Part 1:
Allocator cells and their system services.
AL$FREE
AL$GRAB
AL$GROW
AL$REPL
AL$SHNK
AL$SIZE
AL$ZERO
Hardware services
BT$NMDN
BT$NMEN
BT$NOF
BT$NON
BT$PPRG
BT$SWOF
Sound services
BZ$ALRM
BZ$BELL
BZ$TONE
Display services
DP$EMIT
DP$PRNT
DP$REST
DP$SAVE
DP$STAT
DP$VIEW
DP$WRDY
Device services
DV$BOOT
DV$CLER
DV$LKUP
DV$LOAD
DV$VECT
Editor services
ED$EDIT
ED$EPOS
ED$VIEW
Error services
ER$LKUP
ER$MESS
File services
FL$BACK
FL$BCAT
FL$BDEL
FL$BOPN
FL$BSAV
FL$CATL
FL$COPY
FL$CRET
FL$DELN
FL$ERAS
FL$FFND
FL$FIND
FL$FREC
FL$NEXT
FL$OPEN
FL$PARS
FL$READ
FL$RECT
FL$RENM
FL$RSET
FL$SETP
FL$SIZE
FL$WRIT
Complex Floating point services
FN$ATAN
FN$COS
FN$EXP
FN$LN
FN$LOG
FN$POWR
FN$RND
FN$SIN
FN$SQRT
FN$TAN
Part 2:
Table interpreter services.
IT$GVAL
IT$RADD
IT$STRT
IT$TADD
Keyboard services.
KB$INIT
KB$TEST
KB$GETK
KB$BREK
KB$FLSH
KB$UGET
KB$STAT
Language services.
LG$RLED
LG$NEWP
LN$STRT
Menu services.
MN$DISP
Floating point arithmetic services.
MT$BTOF
MT$FADD
MT$FBDC
MT$FBEX
MT$FBGN
MT$FBIN
MT$FDIV
MT$FMUL
MT$FNGT
MT$FSUB
Pack services.
PK$PKOF
PK$QADD
PK$RBYT
PK$READ
PK$RWRD
PK$SADD
PK$SAVE
PK$SETP
PK$SKIP
Run services.
RM$RUNP
Top level services.
TL$ADDI
TL$CPYX
TL$DELI
TL$XXMD
TL$RSTR
TL$LSET
Timing services.
TM$DAYV
TM$TGET
TM$UPDT
TM$WAIT
Utility display services.
UT$DDSP
UT$DISP
UT$CDSP
Utility services.
UT$CPYB
UT$ENTR
UT$FILL
UT$ICPB
UT$ISBF
UT$LEAV
UT$SDIV
UT$SMUL
UT$SPLT
UT$UDIV
UT$UMUL
UT$UTOB
UT$XCAT
UT$XTOB
UT$YSNO
LZ Services
Hardware services
BT$TOFF
Display services
DP$CPRN
DP$CSET
DP$MSET
DP$PVEW
DP$UDG
XT$BAR
Editor services
TL$ZZMD
Error services
ER$PRNT
File services
FL$FDEL
FL$GETX
FL$NCAT
FL$VALX
FL$WCAT
FL$WCPY
FL$WDEL
FL$WFND
FL$WPAR
XF$SORT
XT$DIRM
Complex Floating point services
FN$ASIN
FN$ACOS
FN$MAX
FN$MEAN
FN$MIN
FN$STD
FN$SUM
FN$VAR
Keyboard services.
KB$CONK
Language services.
LG$EDIT
LG$ENTR
LN$XSTT
Menu services.
MN$1DSP
MN$TITL
MN$XDSP
Timing services.
TM$DNAM
TM$MNAM
TM$NDYS
TM$TSET
TM$WEEK
Top level services.
AM$ENTR
CA$ENTR
DI$ENTR
NT$ENTR
TI$ENTR
WL$ENTR
XF$ENTR
XT$ENTR
Utility services.
UT$CMPB
UT$SORT
UT$WILD
The following 4 services are used for table programs. A table consists of a list of bytes, which is interpreted by the IT$STRT service like a program. The advantage of this is that the user can supply a machine code subroutine to run for most table bytes, thus making the code more compact. Table programs are used in the ROM mainly for complex floating point system services (and for password codes on the LZ).
In a table program, the bytes $00-$14 have predetermined actions and the bytes $15-$FF are available for user defined actions. The first word of a table contains an offset to the list of addresses of the machine code subroutines that define the user actions. This list starts with the address that is to be called when action $15 is encountered, and ends with the address belonging to the highest defined action byte. The table program itself starts from the third byte of the table, i.e. immediately after the list offset.
The table program has 32 bytes of variable space assigned to it at ITT_REGS ($234D-$236C) and also its own independent stack area at ITT_STAK ($236D-$23AC).
Many actions need parameters and these of course usually follow immediately after the action byte. The predefined actions often use a single byte in the range $E0-$FF to denote the 32 byte variables, and numbers in the range $00-$DF as ordinary numbers. If an address in the table is given as a parameter then the address is given as an offset from the start of the table. Note that the start of the table is the word pointing to the user action address list, not the start of the table program.
The following functions are predefined:
00 RETURN: Return from a table subroutine, i.e. pulls a table address from the
table stack and continues the table program there.
01 CALL: Calls a table subroutine also passing the given parameters. The
action byte is followed by:
- a byte denoting the number of bytes passed to the subroutine.
- the subroutine address (as offset from table start)
- the list of bytes to pass to the subroutine.
The parameters to be passed are put in the table variables before
calling the subroutine, so at most 32 bytes can be passed along, and
the previous values of the variables $E0-$?? are overwritten. See also
action 10.
02 BRANCH FALSE: Branches if the result of a previous comparison was false,
see the actions 08 and 09. The relative jump following the action byte
is different from the relative jumps in ordinary machine code, in that
the branch is calculated from the current action byte. Thus a branch of
2 will do nothing. Negative branches are allowed.
03 BRANCH TRUE: Like action 02, except that it branches if the result of a
previous comparison was true.
04 CASE: Jumps to one of a list table addresses depending on a variable.
The action byte is followed by a variable ($E0-$FF) and a table
address. The address points to a case-list which is in the following
format: byte, table address; byte, table address; .... etc. If the
variable matches one of the bytes on the list, CASE will cause a jump
to the associated address. A byte of $FF can be used in the last list
entry to denote the ELSE case, which will be called whenever the
variable doesn't match any of the earlier entries.
05 VECTOR: Jumps to one of a list table addresses depending on a variable,
like the BASIC instruction ON x GOTO. The action byte is followed by a
variable, and a table address. The table address points to a list of
table addresses. If the variable contains 0 the interpreter takes the
first table address on the list and jumps to it, 1 uses the second
address etc.
06 JUMP: Jumps to the given table address.
07 BRANCH: Branches a given distance. See action 02.
08 EQUAL: The action byte is followed by two bytes, which can be numbers or
variables. This action tests whether the two values are equal.
09 UNEQUAL: The action byte is followed by two bytes, which can be numbers
or variables. This action tests whether the two values are different.
0A ASSIGN: The action byte is followed by a variable, and a byte value that
may be either a number or a variable. This action assigns the value to
the given variable.
0B ADD: The action byte is followed by a variable, and a byte value that may
be either a number or a variable. This action adds the value to the
given variable.
0C SUB: The action byte is followed by a variable, and a byte value that may
be either a number or a variable. This action subtracts the value from
the given variable.
0D PUSH: Pushes the given address on the table stack. This first subtracts
two from the stack pointer ITA_SPTR and then stores the given word at
this new value of ITA_SPTR. See also action 0F.
0E CALLMC: Calls the machine code routine at the given address. Note that
the address is an absolute address, not a table offset. The variable
$E0 is passed in the B register when the routine is called.
0F POP: Pops a word off the table stack, by adding two to the stack pointer
ITA_SPTR. Note that the value that was on the top of the stack is lost.
For this reason, the table stack is not used for temporarily storing
data, just for storing return addresses when table subroutines are
called. User defined actions can use the stack for other purposes.
10 JSR: Calls the table subroutine at the given address, without passing any
parameters. See also action 01. The subroutine is exited by the action
00.
11 RANGE: The action byte is followed by three bytes, which can be numbers
or variables. This action tests whether the first value lies between
the other two, i.e. whether v2<=v1<=v3.
12 PEEK: The action byte is followed by a variable and a table address. This
action stores the contents of the table address in the variable.
13 POKE: The action byte is followed by a byte (variable or number) and a
table address. This action stores the given value at the table address.
14 END: Ends the table program normally, returning to next instruction after
the IT$STRT call with register B=0 and the zero flag set. This can also
be called in a table subroutine.
The system variable ITA_PCNT ($D7) is used as a table program counter. At
the start of a user action routine, ITA_PCNT still points to the action byte.
The user routine must end with B containing the number to add to ITA_PCNT for
it to point to the next table instruction (i.e. 1 if no parameters were used).
To quit the table program during a user action, pull one return address from
the machine stack, load B with an error code and perform a RTS instruction.
The system variable ITA_SPTR ($DB) contains the table stack pointer, which
contains the address of the last word pushed on the stack.
The system variable ITA_UVC ($234B) points to the absolute address of the
list of user action addresses.
The system variable ITA_BAS ($D9) points to the absolute address of the
table, i.e. the address given when IT$STRT was called.
The system variable ITA_TEST ($DD) contains the result of comparisons, i.e.
the result from actions 08, 09 and 11. Actions 02 and 03 test whether this
value is zero (false) or non-zero (true). User actions may of course use this
byte in other ways.
066 42 | IT$GVAL |
INPUT: | B=Offset to parameter (1=first byte after action byte) |
OUTPUT: | B=Contents of variable (if byte is $E0-$FF) or else parameter value
A,X=preserved |
Used in user defined actions to get the value of a byte parameter. |
067 43 | IT$RADD |
INPUT: | B=Offset to parameter (1=first byte after action byte) |
OUTPUT: | X=Address of table variable
A,B=preserved |
Used in user defined actions to get the memory address of a table variable that is passed as a parameter. |
068 44 | IT$STRT |
INPUT: | D=Address of table program |
OUTPUT: | B=error code or zero |
This is the table interpreter. When called, it will start interpreting the given table program. The table program-counter ITA_PCNT always points to the current byte being interpreted, initially pointing to the third byte of the table. The table is interpreted until the END action (with value 20) is fetched, upon which IT$STRT returns with the B register cleared and the Z-flag set. User defined actions may quit the table program by pulling one return address from the machine stack, loading B with an error code and performing a RTS instruction. In this case IT$STRT will return with B containing the error code, and the zero flag set only if B=0. Note that this cannot be called recursively, i.e. from within a user defined action. |
069 45 | IT$TADD |
INPUT: | B=Offset to parameter (1=first byte after action byte) |
OUTPUT: | D=Parameter value
X=preserved |
Used in user defined actions to get the value of a word parameter. Note that if the word is a table offset, then adding ITA_BAS will give the absolute address. |
The keyboard is checked by the OCI interrupt routine, which normally occurs 20 times a second. The routine first calls the keyboard poll routine (its address is held in bta_poll, $205A), which scans the keyboard. If it reports that there are keys being pressed, then the keyboard translation routine (its address is held in bta_tran, $205C) is called which returns which character that corresponds to, taking into account the state of the Caps/Num locks, auto-repeat delays etc. The ascii value of the key is then saved in the keyboard buffer.
The keyboard buffer holds any keys that have been pressed until the organiser's software is ready to use them. It can contain up to 16 keys, and is found at kbt_buff, $20B0-F. It is a wraparound buffer, so it can be considered to be a loop without a fixed beginning. The offset to the oldest key is held in kbb_back ($73), the number of keys is kbb_nkys ($74).
073 49 | KB$INIT |
INPUT: | None. |
OUTPUT: | None. |
Initialises the keyboard interrupts. This is performed when the machine is
cold booted. It does all the following things:
1. The keyboard buffer is cleared. 2. The keyboard interrupt rate KBW_TDEL is set to $B3DD (=50ms) 3. The auto-repeat variables KBB_DLAY, KBB_REPT are set to 14 and 0. 4. The keyboard status flags, in KBB_STAT are set to 0. 5. The length of the key click, KBB_CLIK, is set to 1. 6. The interrupts are enabled: FREE RUNNING COUNTER (i.e. Timer1) is cleared, TIMER 1 OUTPUT COMPARE REGISTER 1 is set to $B3DD (so that the first Output Compare Interrupt is in 50ms) bit 3 of TIMER 1 CONTROL STATUS REGISTER 1 is set, to enable the OCI interrupt, the I flag is cleared to enable all interrupts. |
075 4B | KB$TEST |
INPUT: | None. |
OUTPUT: | B=key, or 0 if no key found
A,X=preserved |
Tests the keyboard buffer and returns the ASCII value of the key found, just like the OPL function KEY. This service is surprisingly complex: First it tries to find a key in the unget buffer, KBB_WAIT ($76). If a key is found there, the service returns it but does NOT clear the unget buffer. If the unget buffer is empty, it will then test the ordinary keyboard buffer. If a key is found there, the service returns it after removing it from the buffer and putting it in the unget buffer. If still no key has been found, then it does the following: 1. The packs are switched off using PK$PKOF, provided this option hasn't been disabled by clearing the variable KBB_PKOF ($20C1). 2. Auto switchoff is tested: If TMB_SWOF is non-zero (i.e. auto- switchoff is enabled) and TMW_TOUT is zero (i.e. the auto- switchoff time has elapsed) then BT$SWOF is called, switching off the Psion. 3. The battery is tested and if it is too low, the BATTERY TOO LOW error 194 is raised and the Psion switches off after 4 seconds. Normally the keyboard is polled during an OCI interrupt, but if the interrupts are disabled, this service will poll the keyboard itself before doing all the actions described above. |
072 48 | KB$GETK |
INPUT: | None. |
OUTPUT: | B=Key
A,X=preserved |
Waits for a key to be pressed, and returns its ASCII value. This service performs the same list of tasks as KB$TEST, except that instead of returning zero when no key is pressed, it performs a SLP instruction to conserve power and again tests for a keypress. This is repeated until a keypress has been detected. Unlike KB$TEST, the key is removed from the unget buffer KBB_WAIT. This service also initialises the auto-switchoff timeout counter TMW_TOUT to the value of TMW_TCNT, so that it waits for the maximum possible time before switching off. |
070 46 | KB$BREK |
INPUT: | None. |
OUTPUT: | None. |
Tests whether the ON/CLEAR key is pressed, and returns with the carry flag set if this is so. It tests this by testing the keyboard directly, and by testing the keyboard buffer. If ON has been pressed, it will wait until it is released, and flush the keyboard buffer. |
071 47 | KB$FLSH |
INPUT: | None. |
OUTPUT: | None. |
Flushes the keyboard buffer. The variables KBB_BACK, KBB_NKYS, KBB_PREV and KBB_WAIT are all set to zero. |
076 4C | KB$UGET |
INPUT: | B=key to unget |
OUTPUT: | D,X=preserved |
The ASCII value in the B register is put in the unget buffer, KBB_WAIT provided that buffer is empty. All registers are preserved. |
074 4A | KB$STAT |
INPUT: | B=new keyboard status |
OUTPUT: | None.
B=preserved |
Sets the keyboard state. The value of B is put in KBB_STAT ($7B), and the display is updated to reflect this. To use this service, read the value of KBB_STAT, change the necessary bits, and call the service. The bits of KBB_STAT have the following meanings: Bit 0: Clear when Caps lock. Bit 1: Set when Caps, Num or Special lock is being pressed. Bit 2: Set when Special lock on. (i.e. shift-rightarrow, used for special symbols in foreign languages) Bit 3-5: Not Used Bit 6: Set when Num lock. Bit 7: Set when shift is pressed. Note that bits 0,2 and 6 can be safely changed. The other bits are best left unchanged. The shape of the cursor will be updated by this service if necessary. |
078 4E | LG$RLED |
INPUT: | TT_FF=Name of file
TLB_MODE=command to be performed on file (3=EDIT, 4=LIST, 7=RUN, 8=DELETE) LGB_LANT=file type ($82-$8F) |
OUTPUT: | None. |
Performs one of the program menu commands RUN/LIST/EDIT/DELETE on an existing block file. Note that the RUN command can only be used on a procedure file (type $83) while the other commands can be applied to any text block file. The name of the file to use must be in the find buffer RTT_FF ($22C9). If the file does not exist, the error will be displayed immediately using the ER$MESS service. If a new file needs to be created, the LG$NEWP service should be used instead. The command to be performed on the file should be set in the system variable TLB_MODE ($A3). The following values are allowed: 3 to EDIT, 4 to LIST, 7 to RUN, and 8 to DELETE. The file type must be supplied in the system variable LGB_LANT ($23E0) and must me in the range $82-$8F. When the edit option is chosen then the file editor is used, so that pressing MODE will call up the editing menu which has the options TRAN,SAVE,QUIT (and Find,Home,End,Zap,Xtran on the LZ). To suppress the TRAN (and Xtran) options when non-OPL text files are edited, make the system variable LGB_MENU ($23E1) non-zero. When the editor is exited using the Save option, the edited file is saved, and if Quit is chosen the original file is preserved and any changes made are lost. |
077 4D | LG$NEWP |
INPUT: | As LG$RLED above |
OUTPUT: | None. |
Makes a new text block file. Identical to LG$RLED except that a new file is created instead of an existing one being edited. Note that if Quit is chosen when exiting the editor, no new file is created. |
079 4F | LN$STRT |
INPUT: | B=function (0=tran proc, 1=tran calc, 2=locate error in calc, 3=loc err in proc)
X=offset in Q-code where error occurred (error-locating only, else ignored. Must be in range) |
OUTPUT: | B=error code if there is one.
X=offset in textcell where error occurred if there is one. Qcode-cell=translated output if translating |
Runs the translator. There are four functions available, values 0 and 1 mean the service will translate procedures or calculator expressions respectively. Values 2 and 3 mean that the service locates errors in calculator expressions or procedures respectively. When translating, the result is put in the QCode output cell, the allocator cell with tag $200C. If an error occurs, B is the error number and X is the offset to the error in the textcell (the alloc cell with tag $2006). On the LZ machines, the current display mode DPB_MODE determines whether the translation is for 2 or 4-line machines. LZ users, see also LN$XSTT. |
080 50 | MN$DISP |
INPUT: | X=Address of menu string.
D=Bit mask of keys that exit the menu (bit n set if char n+1 exits). |
OUTPUT: | B=keypress used to exit menu (gives Exe if a letter key was used)
UTW_S0=number of the chosen item (0=first item) A=non-zero X=Address of menu item in the menu string. A=zero X=Associated address of menu item |
Displays a menu and allows a choice to be made, like the OPL function MENU.
The menu string consists of a list of menu items, each with a leading
byte-count and followed by an associated word. This word is usually the
address of the relevant subroutine or zero. The top level menu uses zero for
items associated with OPL procedures (the LZ also uses 1 for Notepad files,
2 for ordinary files). The menu list is terminated by a zero byte.
The D register contains the terminating bit mask, which determines which
keypresses exit the menu. If the nth bit is set then the key with code n+1
will exit the menu, so bit 0 corresponds to the ON/CLEAR key, bit 12 to the
EXE key etc. Never call this service with D=0 or it can never be exited.
On exit, there are two possibilities. If register A is non-zero (generally 1) then the chosen menu item had a zero word associated with it. If register A is zero on exit, then the chosen menu item had a non-zero word associated with it. If a letter has been pressed to choose the only item in the menu starting with that letter then the service acts as if EXE has been pressed (so that the service will exit with B=13 if bit 12 in the mask was set). Note that the keyboard is put into alpha shift. On the LZ, the system variable MNB_CPTZ ($209C) is used to decide whether the menu should be capitalized or not when in 4-line mode. The default is 0, meaning that all menu's are capitalized. If it is 1, then all menu's are displayed exactly as they were stored. An undocumented feature is that the menu routine uses dpb_vsiz ($65) to hold the number of items in the menu and dpb_vlin ($64) to hold the currently selected one (0=first item etc). |
081 51 | MT$BTOF |
INPUT: | X=Address of start of string to convert
D=Address to store floating point number |
OUTPUT: | X=Address of first unused character in string
D=trashed |
Converts an ASCII string to a floating point number, like the OPL function VAL. Note that the first character in the string that cannot be incorporated in the number signifies the end of the number, so no length need to passed to the service. Error 252 'string to number error' may be returned. |
082 52 | MT$FADD |
INPUT: | Acc=First floating point number
Oper=Second floating point number |
OUTPUT: | Acc=Sum of the two floating point numbers |
Adds two floating point numbers. The numbers are in the fp operator and the fp accumulator, and the result is left in the fp accumulator. Error 253 'exponent overflow' may be returned. |
083 53 | MT$FBDC |
INPUT: | A=Maximum length of output string
B=Number of decimal places needed X=Address to store the resulting string |
OUTPUT: | B=Length of string |
Converts the floating point accumulator into an ASCII string in decimal format, i.e. without an exponent and rounded off to a fixed number of decimal places, somewhat like the OPL function FIX$. Error 250 'Number to string error' may be returned. |
084 54 | MT$FBEX |
INPUT: | A=Maximum length of output string
B=Number of decimal places needed X=Address to store the resulting string |
OUTPUT: | B=Length of string |
Converts the floating point accumulator into an ASCII string in exponential format, i.e. with an exponent and rounded off to a fixed number of decimal places, somewhat like the OPL function SCI$. Error 250 'Number to string error' may be returned. |
085 55 | MT$FBGN |
INPUT: | A=Maximum length of output string
B=Number of decimal places needed, negative if no fixed point. X=Address to store the resulting string |
OUTPUT: | B=Length of string |
Converts the floating point accumulator into an ASCII string in general format, i.e. whichever of the three standard formats is most suitable, somewhat like the OPL function GEN$. Error 250 'Number to string error' may be returned. |
086 56 | MT$FBIN |
INPUT: | A=Maximum length of output string
X=Address to store the resulting string |
OUTPUT: | B=Length of string |
Converts the floating point accumulator into an ASCII string in integer format, i.e. without an exponent and rounded off to an integer, somewhat like the OPL function NUM$. Error 250 'Number to string error' may be returned. |
087 57 | MT$FDIV |
INPUT: | Acc=First floating point number
Oper=Second floating point number |
OUTPUT: | Acc=Result of the division of operator by accumulator. |
Divides two floating point numbers. Errors 253 'exponent overflow' and 251 (divide by zero) may be returned. |
088 58 | MT$FMUL |
INPUT: | Acc=First floating point number
Oper=Second floating point number |
OUTPUT: | Acc=Product of operator and accumulator.
Oper=preserved |
Multiplies two floating point numbers. Error 253 'exponent overflow' may be returned. |
089 59 | MT$FNGT |
INPUT: | X=Address of floating point number to negate (has 7 byte mantissa) |
OUTPUT: | None.
B,X=preserved |
Negates a floating point number. Note that the number is assumed to have a mantissa of seven bytes, so for numbers with a 6 byte mantissa X must point to the address one byte below the number. |
090 5A | MT$FSUB |
INPUT: | Acc=First floating point number
Oper=Second floating point number |
OUTPUT: | Acc=Result of the subtraction of operator from accumulator. |
Subtracts two floating point numbers. Note that this routine simply calls MT$FADD after negating the operator. Error 253 'exponent overflow' may be returned. |
091 5B | PK$PKOF |
INPUT: | None |
OUTPUT: | None. |
Turns off all packs. PK$SETP or PK$SADD must be called before using the packs again. |
092 5C | PK$QADD |
INPUT: | None |
OUTPUT: | B=Highest byte of pack address (will always be 0 on CM organiser)
X=Lowest bytes of pack address |
Returns the current pack address. |
093 5D | PK$RBYT |
INPUT: | None |
OUTPUT: | B=Byte read from pack
A,X=preserved |
Reads a single byte from the current position in the current pack. The current pack position is incremented by one. Care must be taken not to read past the end of the pack. |
094 5E | PK$READ |
INPUT: | D=Number of byte to read from pack
X=Address to copy the bytes to. |
OUTPUT: | None. |
Copies a number of consecutive bytes from the current position on the current pack to memory. The current pack position is updated to point the next available byte. Note that if the slot has not been previously selected by PK$SETP then garbage will be returned. |
095 5F | PK$RWRD |
INPUT: | None |
OUTPUT: | D=Word read from pack
X=preserved |
Reads a word from the current position in the current pack. The current pack position is incremented by two. Care must be taken not to read past the end of the pack. |
096 60 | PK$SADD |
INPUT: | B=High byte of address to set pack to (ignored on CM)
X=Lowest bytes of address to set pack to |
OUTPUT: | None. |
Sets the current pack address. If necessary the PK$SETP will be called first
to power up the packs. If the address is past the end of the pack then a Bad
Read Error is generated and the pack address is indeterminate.
The following errors can be generated:
|
097 61 | PK$SAVE |
INPUT: | D=Number of bytes to save
X=Memory address of bytes to save |
OUTPUT: | None. |
Copy a block of consecutive bytes from memory to the current position on the
current pack. The current pack position is updated to point to the next
available byte, or if there was an error it points to the offending byte.
The following errors can be generated:
|
098 62 | PK$SETP |
INPUT: | A=Non-zero if pack change is to be an error, zero otherwise.
B=Pack to select (0-3) |
OUTPUT: | A=Pack type
X=Size of pack in 8K units (not for pack A:) |
Sets the current pack, and configures the operating system to access it. This
routine must be run before using any other pack routines if the packs have
been turned off.
In preparing the system to use a pack, the variable PKA_PKID is set to point
to the pack correct ID string in PKT_ID, the packs are powered up if
necessary (PKB_CPAK is $FF when packs are off) and the pack address is set to
0 (PKW_CMAD for pack A, or PKB_HPAD and PKW_CPAD for a datapak). If a datapak
is chosen then a battery check is also performed.
The following errors can be generated:
|
099 63 | PK$SKIP |
INPUT: | D=Skips a number of bytes on the pack (0-$7FFF) |
OUTPUT: | None. |
Adds D to the current pack address, thus skipping D bytes.
The following errors can be generated:
|
100 64 | RM$RUNP |
INPUT: | B=zero for procedure, non-zero for calculator
X=Address of lbc string containing procedure name |
OUTPUT: | None. |
Loads and runs an OPL procedure or runs the calculator. If running a procedure, it cannot have any parameters. Note that the run-time stack is cleared, and all files closed and the language is re-initialised before running. This service should therefore not be called from within a procedure. Note also that the procedure should be known to exist before this service is called. On the LZ the display mode is set to 2-line mode to run OPL which was written for 2 line displays. |
101 65 | TL$ADDI |
INPUT: | B=Position at which to insert item (0=first item, 1=second, etc.
If past end, e.g. $FF, then item inserted before OFF)
RTT_BUF=Menu item to insert (followed by associated word) |
OUTPUT: | None. |
Inserts a new item in the top level menu. The word that is associated with
the menu item should be 0 for an OPL procedure (or 1 for a notepad and 2 for
a file on the LZ) or the address of the machine code subroutine to be called
when the item is chosen. Note that this service does not recognize the
standard items FIND, SAVE etc. so this service can be used to replace
standard system menu items.
The following errors can be generated:
|
102 66 | TL$CPYX |
INPUT: | None. |
OUTPUT: | None. |
Performs the COPY option which is in the top level menu (or in the Utils menu on the LZ), complete with "FROM" and "TO" prompts. Any errors are handled directly by displaying them using ER$MESS. |
103 67 | TL$DELI |
INPUT: | X=Address of name of menu item to find and remove (lbc string) |
OUTPUT: | None. |
Deletes a top level menu item. |
104 68 | TL$XXMD |
INPUT: | A=Flags:
Bit 0 set for multi-line editing, clear for single-line. Bit 1 set for up/down to exit editor in single-line editing. LZ only. Bit 7 clear for MODE to exit editor, set if MODE to be ignored. B=Maximum input length (possibly 0) X=Address of prompt to display (lbc string, e.g. 'FIND' shows 'FIND A:') TLB_CPAK=Initial pack RTT_BUF=String to be edited |
OUTPUT: |
TLB_CPAK=Chosen pack Carry=set if ON/Clear used to exit. |
Clears the screen, displays a prompt, a pack name and a colon, then allows the editing of a string (usually considered to be a filename). The MODE key changes the chosen pack. The system variable TLB_CPAK ($A2) can be set to the default pack beforehand, and read afterwards to see which pack is chosen. This service calls the editor ED$EDIT, see there for more information. LZ users, see also TL$ZZMD. |
127 7F | TL$RSTR |
INPUT: | None. |
OUTPUT: | None. |
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. Only available on versions 2.7 and above. |
128 80 | TL$LSET |
INPUT: | B=Language to set:
0=English 1=French 2=German 3=Spanish 4=Italian 5=Portuguese 6=Swedish 7=Danish 8=Norwegian 9=Dutch 10=Turkish |
OUTPUT: | None. |
Sets the language. On the LZ only English and two other languages are available. If the language requested is not available, then English is used instead. Note that the top-level menu is reset so any inserted items are removed. If there is not enough memory for the new menu, then error 254 'out of memory' is returned and the language remains unchanged. Only available on multi-lingual machines. |
105 69 | TM$DAYV |
INPUT: | X=Address of three byte date (year 0-99/0-255, month 0-11, day 0-30) |
OUTPUT: | B=Weekday number (0-6, 0=Monday)
X=Address of three byte string containing day name (e.g. 'MON') |
Calculates the day of the week from a given date. |
106 6A | TM$TGET |
INPUT: | X=Address of six byte buffer to copy time to. |
OUTPUT: | None.
X=preserved |
Copies the system time to an address in memory. This service makes sure that the system time is not being updated by an NMI at the time of copying. |
107 6B | TM$UPDT |
INPUT: | A=Number of minutes to add
B=Number of seconds to add X=Address of 6 byte buffer containing date/time to adjust. |
OUTPUT: | None. |
Adds a number of minutes and seconds to a date/time. This should not be used directly on the system variables containing the system time when an NMI is imminent. |
108 6C | TM$WAIT |
INPUT: | D=Number of clock ticks to wait |
OUTPUT: | None. |
Waits for a given length of time. If the keyboard interrupts are enabled, it will simply wait count these until D of them have occurred. These interrupts occur every 50 ms unless KBW_TDEL has been changed. If the interrupts are disabled this service uses its own 50 ms pause so that it will still work. |
The following two system services can be used to display information on the screen at the current cursor position. They use a format control string which controls the way the information is displayed.
In the simplest case, the format control string is simply a string of characters to be displayed. The characters '%', '+', '-' and '}' are reserved for special purposes as described below. Control characters can be used, except for 0 which signals the end of the format control string. The LZ has an extra control character available, viz. 31 which will centralize the next string on the current line, clearing the left and right sides of the line.
The character '%' can be followed by a letter to indicate what kind of
information is to be displayed and in what way. Here is the list of letters
and what they do:
%a display ASCII character
%i display signed integer word in decimal
%j display signed integer byte in decimal
%u display unsigned integer word in decimal
%v display unsigned integer byte in decimal
%x display unsigned integer word in hex
%y display unsigned integer byte in hex
%s display a lbc string
%b display text buffer (address and length byte given)
%f fill field (for this type a field width must be included; see below)
These combinations need further information on what is to be displayed. Both the following system services assume that this information has been pushed onto the machine stack. Thus if the byte $F0 were pushed on the stack and one of the following services were called with the format string '%v' then '240' would be printed on the screen.
These combinations can also be used for left justifying the data to be displayed. This is done by inserting the length of the field to be used between the '%' character and the control letter in ASCII decimal format. Thus if '%10v' were used to display the byte $F0 then '240 ' would be printed, which is ten characters long. Note that with the '%' character the data is always left justified, so if a field width is included spaces are added to the right.
The control character '+' can also be used for left justifying. This time however the character to be used to fill out the field must be given as well as the field width. Thus using '+X10v' to print $F0 will show the string '240XXXXXXX'.
The control character '-' can be used for right justifying. This is used in the same way as '+' so the character to be used to fill out the field must be given as must the field width. Thus using '-010v' to print $F0 will show the string '0000000240'. Note how the first '0' is the fill character and not part of the field width.
The field width can be up to 99 characters wide, and if the string does not fit on the screen it will scroll vertically upwards. If the data to be displayed does not fit inside the given field width then only some of the characters can be displayed. With '%' and '+' the data is left justified so the leftmost characters are displayed, and similarly with '-' the rightmost. For example '-02v' shows $F0 as '40', while '+02v' or '%2v' shows it as '24'.
The character '}' is used as shorthand for '-02v'. This shows the last two digits of a single unsigned byte, including a leading 0 if necessary.
To display the characters '%', '+', '-' and '}' themselves simply precede them by '%'. Thus '%+' displays '+' and '%%' displays '%'.
The control letter 'f' is used when a sequence of characters is needed. For example, '%16f' displays 16 spaces. A field width must be given in this case. To display a sequence of another character you must use '+', for example '+*16f' shows 16 asterisks.
All the control letters (except for 'f') need to know what number or string is to be displayed, and this information is taken from the stack. For example, to display a time ' 7:45' when A contains the hours and B the minutes, then you must use PSHB, PSHA followed by one of the following system services with the control string '- 2v:}'. Note that the hours are pushed last so that they are popped from the stack first and hence displayed first.
When the control letter 'b' is used a text buffer is displayed. To use this option, you must push the length (1 byte) of the text first, followed by the address of the buffer. For control letter 's' only the address needs to be pushed as the string stored there has a lbc.
It goes without saying that you must be sure that the correct amount of data is pushed or else the stack is corrupted. Care must also be taken that the data is pushed in the correct order, that the control letters in the format control string are in lower case, and that the format control string ends with a zero byte.
LZ users (and probably users of other multi-lingual machines) should note that if format control strings from the ROM are used (i.e. strings at an address with bit 15 set) then the characters $60 to $FF are used to denote various system messages, which will then be displayed in the current language.
110 6E | UT$DDSP |
INPUT: | D=Address of format control string to display. |
OUTPUT: | None. |
The format control string at given address in memory is displayed. Any data that the string needs is taken from the machine stack. The string is printed from the current cursor position. |
111 6F | UT$DISP |
INPUT: | None. |
OUTPUT: | None. |
The format control string which follows immediately after the UT$DISP call is displayed. The program then continues at the instruction following the string. Any data that the string needs is taken from the machine stack. The string is printed from the current cursor position. |
126 7E | UT$CDSP |
INPUT: | None. |
OUTPUT: | None. |
Exactly the same as UT$DISP except that the screen is cleared first. Thus the format control string which follows immediately after the UT$CDSP call is displayed. The program then continues at the instruction following the string. Any data that the string needs is taken from the machine stack. The string is printed from the current cursor position. Only available on versions 2.5 and above. |
109 6D | UT$CPYB |
INPUT: | D=Target address to copy to.
X=Source address to copy from. UTW_S0=Number of bytes to copy. |
OUTPUT: | None. |
Copies UTW_S0 bytes from X to D. The two areas can overlap as this service can cope with this. Note that if UTW_S0=0 or if X=D, the routine does nothing. The copying rate is about 81K per second. |
112 70 | UT$ENTR |
INPUT: | X=Address of routine to enter.
D=parameters UTW_S1-5=parameters |
OUTPUT: | B=Error code returned from routine
Carry=set if B is non-zero. |
Calls a routine at address X. This routine can end in an RTS instruction, but it can also be ended by calling UT$LEAV. If any of this main routine's subroutines calls UT$LEAV then the main routine is exited too and the program continues with the instruction immediately after the UT$ENTR call. This means that something akin to error handling occurs. If a program is called by UT$ENTR then it can be exited at any point, and in any subroutine simply by calling UT$LEAV. Normally B is set to hold an error code before calling UT$LEAV, or 0 if no error is to occur. Before control is returned to the instruction after the UT$ENTR call, the carry flag is set whenever B is non-zero. Note that UT$ENTR calls can be nested and in that case a call to UT$LEAV returns to the instruction after the most recent UT$ENTR call. Parameters to the routine can be passed in register D, or in the scratch variables UTW_S1 to UTW_S5. Note that UTW_S0 is trashed by UT$ENTR, though the routine itself can use it. |
113 71 | UT$FILL |
INPUT: | A=Value to fill bytes with
B=Number of bytes to fill X=Address of block to fill |
OUTPUT: | None.
A=preserved UTW_Sx=preserved B=0 X=first unfilled byte |
Fills a block of B bytes starting from address X with value A. If B is zero then nothing is done. This service is very fast, though for B up to 13 bytes the following is a little faster: STAA 0,X / INX / DECB / BNE FA. |
114 72 | UT$ICPB |
INPUT: | A=Length of first string
B=Length of second string X=Address of first string UTW_S0=Address of second string |
OUTPUT: | B=0 if equal, negative if <, positive if >.
N,Z flags=set according to B. X=preserved |
Two ASCII strings are compared, but the upper/lower case is ignored. On exit, the N and Z flags are also set according to the B register, so they are set as if a CMP [String at X],[String at UTW_S0] has been executed. For example "ABCD" < "bcd", "abcd" < "BCD", "A" < "AA", and "ABCD" = "abcd" = "AbcD" |
115 73 | UT$ISBF |
INPUT: | A=Length of major string
B=Length of minor string X=Address of major string UTW_S0=Address of minor string |
OUTPUT: | B=Offset within major string where minor string is found (0 if at start), length of major string if not found. |
Finds the location of one string inside another, much like the OPL function LOC. |
116 74 | UT$LEAV |
INPUT: | B=Error to return, 0 if no error. |
OUTPUT: | B=Error to return, 0 if no error.
Carry=set if B non-zero. X=preserved UTW-Sx=preserved A=trashed |
Jumps to the instruction immediately after the most recent UT$ENTR call and adjusts the stack pointer to the value it was when UT$ENTR was called. Register B contains the error code that should be returned, and UT$LEAV sets the carry flag if this is non-zero. See UT$ENTR for more details. |
117 75 | UT$SDIV |
INPUT: | X=First signed integer
D=Second signed integer (Must be non-zero, else infinite loop!) |
OUTPUT: | X=Quotient, first integer divided by second. |
Divides two signed integers. |
118 76 | UT$SMUL |
INPUT: | D=Signed integer
X=Signed integer |
OUTPUT: | D=High bytes of 4-byte signed product.
X=Low bytes of 4-byte signed product. |
Multiplies two signed integers. |
119 77 | UT$SPLT |
INPUT: | A=Separator character
B=Number of field to extract (0=first field) X=Address of list of fields UTW_S0=Length of list of fields |
OUTPUT: | carry=clear
X=address of field found D=length of field found carry=set UTW_S0=amount the field number exceeded the number of fields available. |
Finds the address and length of a particular field in a string. Note that the last field need not have a separator character at the end. |
120 78 | UT$UDIV |
INPUT: | X=First unsigned integer
D=Second unsigned integer (Must be non-zero, else infinite loop!) |
OUTPUT: | X=Quotient, first integer divided by second.
UTW_S2=same as X |
Divides two unsigned integers. |
121 79 | UT$UMUL |
INPUT: | D=A unsigned integer
X=A unsigned integer |
OUTPUT: | D=High bytes of 4-byte unsigned product.
X=Low bytes of 4-byte unsigned product. UTW_S1=same as D UTW_S2=same as X |
Multiplies two unsigned integers. |
122 7A | UT$UTOB |
INPUT: | D=Unsigned integer to convert to string
X=Address to store string |
OUTPUT: | B=Length of string
X=preserved |
Converts the unsigned integer into an ASCII string in decimal notation. |
123 7B | UT$XCAT |
INPUT: | UTW_S0l=File type to search ($81-8F, 0 for all file types) |
OUTPUT: | None. |
Displays all filenames of the given type on the current pack. The screen is cleared first, then the filenames are displayed one by one. The service waits for EXE to be pressed before displaying the next filename. If there are no more files of the requested type then END OF PACK (or on the LZ 'NO MORE ENTRIES') will be displayed. Pressing ON at any time exits this service. Note that the service does not wait for the ON key to be released. Note that if an error occurs, it will handled immediately by calling ER$MESS after which the service is exited. |
124 7C | UT$XTOB |
INPUT: | D=Unsigned integer to convert to hex string
X=Address to store string |
OUTPUT: | B=Length of string
X=preserved |
Converts the unsigned integer into an ASCII string in hexadecimal notation. |
125 7D | UT$YSNO |
INPUT: | None. |
OUTPUT: | B=key pressed
carry=set if 'y' or 'Y' pressed, clear otherwise |
Waits for one of 'y' 'Y' 'n' 'N' or ON/CLEAR to be pressed, and returns that key. Note that the service uses KB$STAT to put the keyboard in alpha shift (i.e. releases NumLock), and that the previous keyboard state will be lost. |