Technical Reference
Memory Usage
Filing System
System Timing
System Board
Power Supply Board
Interface Slots
Low Level
Comms Link
Psion Link
Utility System
LZ Passwords
System Services

Technical Reference Manual


The system services are explained in detail at the system services page.
They are included here only for completeness!














Copies one buffer to another buffer. The two buffers can overlap in any way required.


Case independent buffer compare.

UT$CMPB (LZ only)

A case dependent buffer compare. Works in exactly the same way as UT$ICPB but is case dependent.


Fills a buffer of the given length with the specified byte, filling two bytes at a time for efficiency.


Finds the occurrence of the minor buffer within a major buffer.

UT$WILD (LZ only)

Works in the same way as UT$ISBF except that the wild characters '*' and '+' apply.


Finds the address and length of a field in a buffer where the fields are separated by the character specified.


Converts an unsigned binary number to ')"; onMouseout="hideddrivetip()"> ASCII decimal.


Converts an unsigned binary number to ')"; onMouseout="hideddrivetip()"> ASCII hexadecimal in the buffer at X.


These services provide complex display handling, displaying any required parameters according to the format control string parameter. The LCD display is not cleared and the text is displayed from the current cursor position and vertical scrolling will begin after the text fills the whole LCD display.


Displays literal text and variables according to the format control string which is inserted in-line directly after the operating system call to UT$DISP.


Displays literal text and variables according to a given format control string.

This is identical to UT$DISP except that the format control string is not inserted in-line.

UT$CDSP (OS Version 2.5 and later only)

Like UT$DISP but screen is cleared first.


Format descriptors interspersed between literal text in the format control string, allow the display of variables formatted in the specified way.

Optionally, the programmer can justify the text within a field of chosen width, where the field is filled with a specified character.

All display is done through the service routine DP$EMIT, so that control characters (such as 16 for beep) can be used in the format control string.


Variable parameters must be pushed onto the machine stack in reverse order to that in which they will be displayed. For a buffer parameter, the length byte must be pushed before the address.


The variable parameters must correspond in number and in type to the specification of the format control string.


There are two distinct editors in the operating system. The operating system itself uses the LANGUAGE EDITOR is for editing OPL programs, and the LINE EDITOR is used in all other editing situations; the editors can however each be used in a wide range of circumstances. Both can be called by the programmer, so a basic outline of some of the differences is given here. For a detailed description please refer to the system services page.

The line-editor is used for editing a maximum of 255 characters in the editor buffer, RTT_BF. Any text on the display prior to calling the editor will be treated as a prompt, with the text that is editable displayed directly after it. If required, a string can be set up for editing by copying it into the editor buffer before calling the editor.

The language editor can be used for editing any text files. The amount of text that can be edited is limited only by memory availability. Free RAM is allocated to the editor as required. An existing file can be loaded for editing in this memory. A file can be saved with a block file type between $81 and $8F inclusive, as specified by the programmer.

When exiting the editor, the user has the choice of

  1. translating an OPL program,
  2. saving the file,
  3. quitting, in which case everything typed in the editing session is lost.

Since any type of text file can be edited (not only OPL procedures), the programmer can choose to prevent the option to translate the edited file.

LZ machines provide an extended language editor.



This is the standard input line-editor.

A maximum characters may be specified. There are two modes of operation, multi-line and single-line editing. With multi-line editing the down arrow key starts a new line of text, while with single-line editing the up and down arrow keys send the cursor to the beginning and end of the editable text respectively. A new line is represented in the editor buffer by a TAB character ( ')"; onMouseout="hideddrivetip()"> ASCII value 9).

The editor is exited when the EXE key is pressed, or when the ON/CLEAR key is pressed with an empty editor buffer. When the editor buffer is not empty, the ON/CLEAR key clears it and does not cause an exit. The programmer can also choose whether to allow exit from the editor when the user presses the MODE key.


Calls the line-editor service routine ED$EPOS with the cursor initially positioned on the first editable character.


Typically used to edit a filename, with the MODE key being used to select a PACK as in "FIND A:".

TL$XXMD clears the screen, prints a string followed by a space, a device letter 'A' to 'C' and a colon. The system service ED$EDIT is then called to edit a line of text, typically a file name. If the MODE key is pressed, the device letter displays the next available pack. TL$XXMD returns when either EXE or ON/CLEAR is pressed.

TL$ZZMD (LZ only)

Works like TL$XXMD except that the screen is not cleared.



Handles RUN, LIST, EDIT and DELETE commands in the top level PROG menu. LIST, EDIT and DELETE can operate on any text file, while RUN operates on OPL procedures only. The system variable TLB_MODE must be set by the programmer to control which of the top level commands is performed.

The standard input language editor can be used for editing any text files (with size limited only by memory availability). The file is loaded into RAM specially allocated to the language editor. An edited file can be saved with a block file type between $82 and $8F inclusive.

When exiting the editor, the user has the choice of

  1. translating an OPL program,
  2. saving the file,
  3. quitting, in which case everything typed in the editing session is lost.

Since any type of text file can be edited (not only OPL files), the programmer can choose to prevent the option to translate the edited file. Attempting to translate a non-OPL file will simply produce an error message.

The language editor differs from the line-editor (ED$EPOS) in the use of cursor and control keys.

  1. The ON/CLEAR key deletes only the current line (not the whole record).
  2. The down arrow key moves the cursor one line down the file. (It does not create a new line).
  3. The EXE key creates a new line. (It does not exit the editor).
  4. A line can be split in two using the EXE key.

Note that on the LZ the PROG menu utilities may also be accessed by LG$ENTR.


Calls the language editor to create a new file.

This is identical to LG$RLED when it is operating in editing mode except that the file to be edited is created.



Allows the user to view the string that is in the run-time buffer.

New lines are specified by TABs, and the up and down arrow keys control the line being scrolled. Two spaces are displayed between the end and beginning of any scrolling text. The left and right arrow keys are used to stop, start and change direction of scrolling. Any other key pressed ends the service.


A menu consists of a list of item names (with leading byte-count), each followed by the address of an associated subroutine, or by 0. The maximum name length is 16. The items are displayed (and numbered) in the same order as in the menu-list. The first item is displayed at the top left-hand corner (HOME position) of the LCD display. The display is filled from left to right until an item is too long to fit, in which case a new line is started

On the LZ all menus (except 1 line menus) are aligned in 3 columns. However if there is any item greater than 6 characters long, 2 columns will be used. Aligning in columns uses more space in RTT_BF where the menu is constructed, so to maintain compatibility, if an aligned menu will not fit, the menu reverts back to a single spaced menu automatically. All menu items appear on the screen capitalized (but not in 2-line mode - for compatibility) but this can be overridden by writing 1 to MNB_CPTZ ($209C). Note that any spaces within menu items are converted to character 254 to save confusion.



Displays a menu according to the specified menu-list, allowing the user to scroll through the menu using the arrow keys or by pressing the first letter of the item to be selected.

MN$DISP exits when the user either

  1. presses any of the special keys specified, or
  2. selects an item with a unique first letter by pressing its first letter.
MN$XDSP (LZ only)

Exactly the same as MN$DISP except that text already on the screen is treated as a title with the menu underneath (starting on the next clear line). If more the 3 lines of text are on the screen, the text will be truncated, and the last line used for the menu.

MN$1DSP (LZ only)

Exactly the same as MN$DISP except that the menu is displayed in one line only and scrolls horizontally. The remaining 3 lines of the screen are left intact. The menu is displayed in the line containing the cursor.

MN$TITL (LZ only)

Exactly the same as MN$DISP except that the top line is used to display an icon on the left and a running digital clock on the right just like the top-level menu.

UDG 0 is always displayed in the top left hand corner of the display.


The top level menu is held in RAM in the second allocator cell. Either OPL procedures or machine code programs may be called from the top-level menu.

On the LZ the top level menu has been extended to allow the names of notes and files to be inserted as well as the names of OPL procedures. This is done by using 0001 and 0002 as the execution addresses for Notes and Files respectively (0000 is still for OPL).


Inserts a given menu item into the top-level menu at given position.


Deletes an item from the top level menu.

TL$RSTR (OS versions 2.7 and above only)

Restores several top-level functions to their initial state. This service first boots all devices, asks which language is to be set (on multi-lingual machines), initialises World and Notes (on LZ machines), and resets the top- level menu. The system time, the alarms, the diary and all files are left unaffected.




2-byte by 2-byte signed integer division routine.

WARNING: Does not check for division by zero, which will cause an infinite loop.


2-byte by 2-byte signed integer multiply routine.


2-byte by 2-byte unsigned integer division routine.

WARNING: Does not check for division by zero, which will cause an infinite loop.


2-byte by 2-byte unsigned integer multiply routine.


These consist of a 12-digit precision BCD-packed mantissa with one byte for the sign and a one byte signed binary exponent. They are structured as follows: (low memory -> high memory)

mantissa_1 low-order byte
mantissa_2 .
mantissa_3 .
mantissa_4 .
mantissa_5 .
mantissa_6 high-order byte
exponent 1 byte
sign 1 byte

Each byte of the mantissa contains two decimal digits, the high-order digit in the top 4 bits and the low-order digit in the bottom 4 bits. The sign byte has the normal sign convention i.e. negative if bit 7 set, positive otherwise. Standard practice in the Organiser operating system is $80 for negative and zero for positive. An exponent of zero (with a non-zero mantissa) implies that the value of the number lies between 1 and 9.99999999999 inclusive.

The mathematical routines operate on two floating-point registers, which are identical in structure to the floating-point numbers described above except for the addition of a guard byte to the mantissa. These bytes are used for rounding purposes.

The registers are arranged in zero-page memory as follows:
Address Variable name Function
$C5 MTT_AMAN accumulator: guard byte
$C6 - start of accumulator mantissa
$CC MTB_AEXP accumulator exponent
$CD MTB_ASGN accumulator sign
$CE MTT_OMAN operand: guard byte
$CF - start of operand mantissa
$D5 MTB_OEXP operand exponent
$D6 MTB_OSGN operand sign

Thus the floating-point number -12345.0006789 can be declared as follows:

         .BYTE   $89,$67,$00,$50,$34,$12         ;mantissa
         .BYTE   4                               ;exponent
         .BYTE   $80                             ;negative sign

and copied into the accumulator by the following code:

        LDD     #MTT_AMAN+1 
        LDX     #8 
        STX     UTW_S0: 
        LDX     #FP_CONST 
        OS      UT$CPYB


The four binary operators add, subtract, multiply and divide operate directly on the floating-point registers in the order

accumulator (operator) operand = accumulator

e.g. to do the operation 6/3 = 2, 6 is placed in the accumulator, 3 in the operand and the result after calling mt_fdiv will be in the accumulator.

Any number used as an argument to these routines must be normalised, i.e. the most significant digit of the mantissa must be non-zero for all non-zero numbers. Any number having zero in the most significant byte is treated as zero.

For example declaring the number 0.00009999 as follows

        .BYTE   0,0,$99,$99,0,0         ;most significant digit is zero 
        .BYTE   -1
        .BYTE   0

is incorrect. It should read:

        .BYTE   0,0,0,0,$99,$99         ;non-zero digits shifted to 
                                        ;most significant position 
        .BYTE   -5                      ;and exponent adjusted accordingly 
        .BYTE   0

These routines also require the exponent to be in the range -99 to 99. The result is always returned as a normalised floating-point number in the accumulator, the operand remains unchanged, and both guard digits are cleared to zero. No validation is made of the contents of the registers on input, and the arithmetic routines will attempt to operate on invalid floating-point numbers with unpredictable results.

A description of the system services to handle floating-point arithmetic follows.


Does a floating-point add on the accumulator and operand registers.


Subtracts the floating-point operand from the accumulator.


Toggles the sign of the register pointed to by X.


Performs a floating-point multiply on the BCD registers.


Performs a floating-point divide on the BCD registers.



Converts a numeric ')"; onMouseout="hideddrivetip()"> ASCII string to a floating-point number. The string may be terminated by any character which is not numeric (and not by ".", "E" or "e" unless these have previously occurred in the input string).

An Error is returned if:

  • The exponent is greater than 99 or less than -99 (irrespective of the value of the mantissa)
  • The input string contains more than 12 significant digits (not including leading or trailing zeros)
  • The total of significant digits + trailing zeros exceeds 44
  • There are no valid numeric digits in the mantissa (e.g. .E5)
  • There are no valid numeric digits in the exponent (e.g. 6E)



Converts floating-point accumulator to numeric ')"; onMouseout="hideddrivetip()"> ASCII text in decimal format. This is the format nnnn.nnn, i.e. a decimal number with no exponent. If the number of significant digits after the decimal point is greater than the decimal places specified, the number is rounded, otherwise it is zero-filled on the right to make up the necessary decimal places.


Converts floating-point accumulator to numeric ')"; onMouseout="hideddrivetip()"> ASCII text in exponential (scientific) format. This is in the form n.nnnnnE+nn, a decimal mantissa with one digit before the decimal point followed by the exponent. The exponent is always expressed as a + or - sign followed by 2 numeric digits.


Converts floating-point accumulator to numeric ')"; onMouseout="hideddrivetip()"> ASCII text in integer format. If the value in the floating-point accumulator is not an integer, then the string output is the accumulator value rounded to the nearest integer.


Converts floating-point accumulator to numeric ')"; onMouseout="hideddrivetip()"> ASCII text in general format, i.e. in whichever of the above three formats is the most suitable for the given number and field width.

The output string will be in integer format if the number is a floating-point integer, otherwise decimal format. If the field width is not sufficient for the above, the number is output in scientific format rounded to as many decimal places as can be accommodated. A field width of 7 is sufficient to convert any floating-point number without returning an error, though severe truncation of the mantissa may result.


With a few exceptions, the system services for these functions require a single floating-point number on the run-time stack (described in the chapter on the language pointers) as input. On exit this number is replaced by the floating-point result, with the stack pointer unchanged. The result is also left in the floating-point accumulator.


Returns the arctangent in radians of a floating-point number.


Returns the cosine of a floating-point number (assumed to be in radians).


Returns the result of the arithmetic constant e (2.71828...) to the power of a floating-point number.


Returns the logarithm to the base e of a floating-point number.


Returns the logarithm to the base 10 of a floating-point number.


Returns the result of X to the power of Y where X and Y are both floating-point numbers.


Pushes a random floating-point number onto the run-time stack. The number will always lie between 0 and 0.999999999999 inclusive.

The seed for the random number generator is held in the 7 bytes at FNT_SEED. If these bytes are set to a particular value then the sequence of random numbers following this will always be the same.


Returns the sine of a floating-point number (assumed to be radians).


Returns the square root of a floating-point number.


Returns the tangent of a floating-point number. The argument is assumed to be in radians.

FN$ASIN (LZ only)

Returns the arcsine in radians of a floating-point number.

FN$ACOS (LZ only)

Returns the arccosine in radians of the floating-point number.


XF$SORT (LZ only)

Sorts a file. An optional subroutine may be specified to be called during the sort (usually used to print to the screen). The method used is a Quick Sort algorithm with passes as follows:

  1. Generate the tag list
  2. Sort the tag list
  3. Reconstruct the file from the sorted tag list

The total number of bytes in RAM required to sort a file of size S bytes and containing N records is approximately given by the following formula:

Space required = 2 * ( S + N )

If there is insufficient memory for the sort, the file will left alone and an error will be returned.

UT$SORT (LZ only)

Provides the core utility for a Quick Sort. The routine assigns space for a Tag for each of the items to be sorted. Then a caller supplied routine is called in three different ways:

  1. to obtain a tag for each item
  2. to compare any two items
  3. to receive the ordered tags


FN$SUM (LZ only)

Returns the sum of a list floating-point numbers.

FN$MEAN (LZ only)

Returns the arithmetic mean of a list of floating-point.

FN$VAR (LZ only)

Returns the sample variance of a list of floating-point.

The sample variance differs from the population variance in assuming that the data set provided constitutes a sample of the data