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 allocator cells allow you to reserve any amount memory of memory safely during the execution of a program. These cells each contain a certain amount of memory and can be grown or shrunk of more or less memory is needed. These cells lie adjacent in memory so by changing the size of a cell all cells above it will be moved up or down so that there is no unused memory between them. Thus the address of a cell is not fixed.
The start addresses of the 32 available cells are held in the system variables between $2000 and $203F. These addresses of these system variables are called tags. Thus the cell with tag $2000 has its base address stored at $2000. If a cell is not used, then zero is stored at the tag address.
Many of the cells are already permanently in use by the Psion. These are:
2000 | Permanent cell, used for code/data from booted devices. The base address of this cell never moves so once code is loaded it will not be moved. |
2002 | Top level menu cell |
2004 | Diary cell |
2006 | Language text cell, used for editing/translating OPL/CALC. |
2008 | Symbol table cell, used when translating OPL/CALC. |
200A | Global record cell, used when translating OPL/CALC. |
200C | QCODE output cell, used when translating/running OPL/CALC. |
200E | Field name symbol table 1, contains field names for OPL file A. |
2010 | Field name symbol table 2, contains field names for OPL file B. |
2012 | Field name symbol table 3, contains field names for OPL file C. |
2014 | Field name symbol table 4, contains field names for OPL file D. |
2016 | File buffer 1, buffers for files opened in OPL. |
2018 | File buffer 2 |
201A | File buffer 3 |
201C | File buffer 4 |
201E | Database cell, contains all data held in pack A:. |
2020 | Notepad cell. Used on LZ only. |
2022 | Dummy spreadsheet cell. LZ only. |
2024-203E | 14 free cells for use by applications |
000 00 | AL$FREE |
INPUT: | X=Tag of the cell, must be in the correct range, ($2000-$203E). |
OUTPUT: | None.
UTW_S0-3=trashed |
Frees a cell. A cell is freed by making its entry zero in the allocator table. This is the reverse of AL$GRAB. If the cell is already free, this has no effect. |
001 01 | AL$GRAB |
INPUT: | D=Size of space to allocate |
OUTPUT: | X=Tag of the cell allocated ($2000-$203E).
UTW_S0-3=trashed |
Allocates a new memory cell. It returns 'No Alloc Cells' error 255 if all cells are already in use, and 'Out of Memory' 254 if there is not enough memory to get a cell of the requested size. |
002 02 | AL$GROW |
INPUT: | X=Tag of the cell, must be in the correct range, ($2000-$203E).
D=Number of bytes the cell is to be grown UTW_S0=Offset into cell where to insert the new bytes. Must not be larger than the length of the cell. |
OUTPUT: | None.
UTW_S0-3=trashed |
Increases the size of a cell. Opposite of AL$SHNK. It returns 'Out of Memory' error 254 if there is not enough memory to grow the cell by the requested amount. |
003 03 | AL$REPL |
INPUT: | X=Tag of the cell, must be in the correct range, ($2000-$203E).
UTW_S0=Offset into cell of the part to be replaced. D=Size of part to be replaced. UTW_S0+D must not be larger than the size of the cell. UTW_S1=Size of the new part. |
OUTPUT: | None.
UTW_S0-3=trashed |
Changes the size of a cell by calling AL$GROW or AL$SHNK as appropriate. This is generally used when you wish to replace part of a cell by something which has a different length. It returns 'Out of Memory' error 254 if there is not enough memory to perform the requested action. |
004 04 | AL$SHNK |
INPUT: | X=Tag of the cell, must be in the correct range, ($2000-$203E).
D=Number of bytes the cell is to be shrunk UTW_S0=Offset into cell where to remove the new bytes. UTW_S0+D must not be larger than the length of the cell. |
OUTPUT: | None.
UTW_S0-3=trashed |
Decreases the size of a cell. Opposite of AL$GROW. |
005 05 | AL$SIZE |
INPUT: | X=Tag of the cell, must be in the correct range, ($2000-$203E). |
OUTPUT: | D=Size of the cell.
X=Preserved UTW_S0=trashed |
Returns the size of a cell. |
006 06 | AL$ZERO |
INPUT: | X=Tag of the cell, must be in the correct range, ($2000-$203E). |
OUTPUT: | None.
UTW_S0-3=trashed |
Shrinks a cell to zero size but does not de-allocate it. |
007 07 | BT$NMDN |
INPUT: | None |
OUTPUT: | D,X=Preserved |
Switches off the non-maskable interrupts. To enable them again use the BT$NMEN service. This is a very unusual feature as in most computers the non-maskable interrupts by their very nature cannot be disabled. The NMI's are used to control the system clock, so by using this service the system time will be invalid. To switch off the NMI's without losing the system time you must use BT$NOF instead. |
008 08 | BT$NMEN |
INPUT: | None |
OUTPUT: | D,X=Preserved |
Enables NMI's which have been switched off by BT$NMDN. |
009 09 | BT$NOF |
INPUT: | None |
OUTPUT: | D,X=Preserved |
Switches off the non-maskable interrupts but without losing the system time. To enable them again use the BT$NON service. The system clock will not be updated while the NMI's are off, but the number of NMI's that would have occurred are counted. When the NMI's are enabled the clock is then updated appropriately. The counter used to count the elapsed number of NMI's is the keyboard & clock counter so it is also used when scanning the keyboard. therefore the keyboard interrupts must also be disabled before this service is called and no keyboard system services should be used afterwards. Also, the counter can only count up to a value of 2048 so the NMI's should be enabled before 2048 seconds (about 34 minutes) have elapsed. |
010 0A | BT$NON |
INPUT: | None. |
OUTPUT: | None.
D,X=trashed |
Enables NMI's which have been switched off by BT$NOF. Note that this service waits till the next NMI occurs so there may be a delay of up to one second. |
011 0B | BT$PPRG |
INPUT: | None. |
OUTPUT: | None.
D,X=Preserved |
This system service routine will push or pop the seven system variables UTW_R0
to UTW_R6 ($4D - $5A) on the stack. This makes available some more scratch
variables for you to use. This service needs one data byte which immediately
follows the SWI 0B instruction. This data byte indicates which of the seven
system variables are used and whether they are to be pushed on or pulled off
the stack.
The byte contains this information in the following way: This is best illustrated by an example of its use:
Note that no RTS is used. When saving variables the service call returns to the next instruction after the data byte, but when restoring the variables, it will act as a RTS instruction. |
012 0C | BT$SWOF |
INPUT: | None. |
OUTPUT: | None.
D,X=trashed |
Switches off the Psion, like the main menu OFF option. When switched on again, program execution continues with the instruction immediately following the SWI $0C instruction. |
013 0D | BZ$ALRM |
INPUT: | None. |
OUTPUT: | None.
D,X=trashed UTW_Sx=preserved |
Emits the normal ALARM noise. Note that keyboard interrupts are disabled temporarily. |
014 0E | BZ$BELL |
INPUT: | None. |
OUTPUT: | None.
D,X=trashed UTW_Sx=preserved |
Emits a standard beep, the same as if control character 16 has been printed. This service simply uses the BZ$TONE routine with the values X=$0032 and D=$0038. Note that keyboard interrupts are disabled temporarily. |
015 0F | BZ$TONE |
INPUT: | D=Pitch of note
X=Length of note in milliseconds (0-$7FFF). |
OUTPUT: | None.
D,X=trashed UTW_Sx=preserved |
Emits a note. The frequency in Hertz can be calculated from D by the formula Freq = 921600 / ( 78 + 2 * D register ). Note that keyboard interrupts are disabled temporarily. |
016 10 | DP$EMIT |
INPUT: | A=Ascii code of character to print |
OUTPUT: | None. All registers and scratch variables preserved. |
Prints a single character. The cursor position will be updated, as will the display buffer. Note characters 0 to 7 will display UDG's and that control codes can be used (see introduction). |
017 11 | DP$PRNT |
INPUT: | X=Address of string to print
B=Length of string to print |
OUTPUT: | None.
X=points to byte following the string. |
Prints the string by printing the characters one at a time using DP$EMIT. |
018 12 | DP$REST |
INPUT: | None. |
OUTPUT: | None.
X,D=trashed UTW_S0-3=trashed |
Restores the screen to its previously saved state. DP$SAVE must have been used first to save the screen position before this service is used. See DP$SAVE for further details. |
019 13 | DP$SAVE |
INPUT: | None. |
OUTPUT: | None.
X,D=trashed UTW_S0-3=trashed |
Saves the current screen contents and the cursor position and state. This information is stored at DPT_SAVE ($2090), DPB_SPOS ($67) and DPB_SCUS ($68) respectively. The original contents of these variables is overwritten. The screen can then be restored by the DP$REST service. This service is used during when an alarm is sounded, so you must make sure that no alarms will go off between your own DP$SAVE and DP$REST calls. Note that the LZ uses the 4 line buffer DPT_4SAV ($7F62) instead, even when in two line mode. |
020 14 | DP$STAT |
INPUT: | A=position to move cursor to (0-31 / 0-79 on LZ)
B=status to change cursor to: Bit 7 set for cursor on Bit 0 set if cursor is underline only |
OUTPUT: | None.
D=trashed X=preserved |
Moves the cursor and has changes its status. The values of A and B are stored at DPB_CPOS and DPB_CUST and the display updated by this service. |
021 15 | DP$VIEW |
INPUT: | X=Address of string to view, 0 for previous string.
A=Line to view string on (0-1 / 0-3 on LZ). Set bit 7 to disallow changing the scroll direction. B=Length of string to view. UTW_S0=Initial pause before scrolling (in 20th of a sec) |
OUTPUT: | B=Key pressed |
Displays a string in the same way as the OPL VIEW instruction.
After exiting this service, it can be resumed where it left off by calling the service again with X equal to zero. In this case no other display routines should be used between the subsequent calls of this service. Never attempt to use X=0 on the initial call of this service. Though the cursor is switched off during this service, the cursor status prior to the call is preserved. The cursor position is lost however. |
022 16 | DP$WRDY |
INPUT: | None |
OUTPUT: | None
X=preserved UTW_S0=preserved |
Waits until the system variable DPW_REDY is zero. This variable is decreased on every interrupt, so every 50ms. If the interrupts are disabled, this service will use its own 50ms delay routine instead and will therefore still work. |
A device is any pack or peripheral that contains boot code. When the Psion is cold booted, or when ON is pressed in the main menu, the DV$BOOT service will be performed. This loads in the boot code from that pack or peripheral into memory, trying the low Ram (0400-1FFF) first or else in the permanent allocator cell (with tag $2000).
Device code is split up into several separate routines, also called
vectors. Three vectors have special meanings:
Vector 0 is the install vector. It is called by DV$BOOT as soon as it
has loaded the code into memory. It is used for example to add an item to the
main menu.
Vector 1 is the remove vector. It is called by DV$CLER. After it has
been called, it must be safe for the code to be removed from memory. It is
used for example to remove an item from the main menu.
Vector 2 is the language vector. It is called in OPL whenever a
procedure name has been encountered. The Psion first checks all devices to
see if one of these will accept it, only then does it look for procedures of
that name. This is used to add extra commands to the language. See DV$LKUP.
Further vectors are generally used for the extra commands that vector 2 accepts. See DV$LKUP and DV$VECT for more information.
Device code is stored on a pack in Psion relocatable code format. This
consists of the following:
A word containing length of the code,
the code itself,
a word checksum, the sum of all the bytes of the code
a word containing the number of fix-ups,
a list of fix-ups (0000 specifying the first word of the code block)
a word checksum, the sum of all the fix-ups in the fix-up list
The code block is such that all absolute jumps and other absolute
references are coded as if the block was at address 0. The fix-up list
contains the addresses of those absolute references, again with 0000
specifying the first word of the code. When the code is loaded into memory,
the fix-up list is used to adjust all the absolute references so that the
code will run properly. Relocatable code is loaded by the service DV$LOAD,
and DV$BOOT uses that to load the device code.
Device code is in relocatable format, and its code block consists of the
following:
0/1 Program length. When loaded into memory, the program length is stored
here so that the services can skip through the device code of all the
devices easily.
2 Pack. When loaded into memory, the pack that this device is on is
stored here. The device code can use this to look up data from its
pack without having to load it permanently into memory. This allows
for code to be written using overlays, to minimise the amount of
memory the code uses at any one time.
3 Device number. Same as in the pack header. This number should be
unique amongst the devices connected to the organiser.
4 Version number. Same as in the pack header.
5 Number of vectors. Usually at least 3.
6+ Vector list. List containing the address of each vector. These
addresses must be fixed-up.
? Rest of code.
023 17 | DV$BOOT |
INPUT: | None. |
OUTPUT: | None.
D,X=trashed UTW_S0=trashed |
Boots all devices which are plugged into the Organiser. First DV$CLER is called to deactivate all previous device code, and the code is removed from memory. Then the current devices are checked, and code is loaded into memory using DV$LOAD. The devices are loaded in order of the priority byte in the pack header. Note that if an error occurs it is handled immediately, by saving the screen contents (using DP$SAVE), displaying the error message (using ER$MESS), and restoring the screen contents afterwards (DP$REST). On the LZ 2-line mode is used for printing by the remove or install device vectors unless the device routine itself sets the display to 4-line mode first. |
024 18 | DV$CLER |
INPUT: | None. |
OUTPUT: | None.
D,X=trashed UTW_S0-5=trashed |
The Remove vector (vector 1) is called of all of the devices that are currently in memory. After this has been done, all the device code can be removed from memory because all the device code is no longer active. The code is not removed however. To remove it, zero the permanent cell, and set dva_top ($232B) equal to dva_bot ($2329). Note that on the LZ 2-line mode is used for printing by the remove device vectors unless the device routine itself sets the display to 4-line mode. |
025 19 | DV$LKUP |
INPUT: | X=Address of lbc string of procedure name. |
OUTPUT: | A=Device number
B=Vector number UTW_S0-5=trashed |
The language vector (vector 2) of each of the devices is called, so that it can check if the procedure name it is given should be accepted by the device. If the device accepts the procedure name, its language vector returns its device number and the vector that handles the task of that procedure in registers A and B respectively, so this can then be returned by DV$LKUP. If the device refuses the procedure, then it should return with the carry flag set. If DV$LKUP finds that no device will handle the procedure name, a 'Device Missing' error 230 is returned, and the carry flag is set. Note that if a device is willing to handle the task, then the carry flag is clear and A and B are set correctly for DV$VECT to be called immediately. This is how peripherals like the Comms link adds extra commands to the OPL language. |
026 1A | DV$LOAD |
INPUT: | X=Pack address of relocatable code block.
D=Memory address at which to load the relocatable code block. UTW_S0=Address used to fix up the relocatable code block. |
OUTPUT: | None. |
Loads a relocatable code block from a pack into memory, and fixes up all the
specified absolute addresses in the code. The absolute addresses are fixed up
by adding UTW_S0 to them. Thus UTW_S0 is the intended execution address, i.e.
the address where the code is expected to be when it is finally run. Normally
this is the same as D, the address where this service loads the code. This
service assumes that the correct pack has already been activated with the
PK$SETP service.
The following errors can be generated:
|
027 1B | DV$VECT |
INPUT: | A=Device number
B=Vector number X,UTW_S0=data to be passed to the device routine (UTW_S1-4=trashed on entry to device routine) |
OUTPUT: | Depends on vector routine. |
Finds and calls a vector routine of a device. If the device is not found,
then the 'Device Missing' error 230 is returned. If the device is found but
there are fewer than B vectors supported then 'Bad Device Call' error 231 is
returned. Otherwise the appropriate part of the device code is run. Note that
the X register and UTW_S0 is passed on to the device routine, so that these
can contain parameters for the routine. The device vector routine can return
values in the registers, flags or scratch variables, and these are passed on
unchanged by DV$VECT.
The following errors can be generated:
|
028 1C | ED$EDIT |
INPUT: | See ED$EPOS below. |
OUTPUT: | See ED$EPOS below. |
Calls the line-editor ED$EPOS with the cursor position on the first character of the editing string. See there for full details and entry requirements. |
029 1D | ED$EPOS |
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 allowed length of the edited string. X=ignored. RTT_BF=String to be edited. UTW_S0=Initial cursor position, 0=start of string, any number past end places cursor at end of string. |
OUTPUT: | B=keypress used to exit editor.
RTT_BF=Edited string. A,X=trashed. |
Calls the built in editor. There are two editing modes, single-line and multi-line editing. In multi-line editing, the up and down arrow keys move to another line. The down arrow key will also create a new empty line if necessary when at the bottom of the editing string. In single-line editing, the up and down keys move the cursor to the start and end of the line (unless otherwise specified on the LZ organiser). In multi-line editing, the lines are separated in the buffer by TABs (i.e. character 9). TAB characters should not be used in the initial editing string when single-line editing is requested. The editing will occur on the screen at the current cursor position, and any text to the left (and also above in multi-line editing) is treated as a prompt. Before editing starts, the editing area to the right of the cursor position (and also below in multi-line editing) is cleared. |
030 1E | ED$VIEW |
INPUT: | X=Non-zero for first call, zero to continue display of same string.
RTT_BF=String to display. UTW_S0=Initial pause before scrolling (in 20th of a sec) |
OUTPUT: | B=keypress used to exit editor. |
Clears the screen and then displays a string in the same way as the OPL function DISP. The lines are separated by TABs (character 9). The arrow keys control which line is being scrolled and its direction. If another key is pressed, the service exits. The X register must be non-zero when the service is first called. If called again with X zero, the display will continue at the point it was interrupted. |
031 1F | ER$LKUP |
INPUT: | B=Error code to look up. |
OUTPUT: | X=lbc string of error message.
D=trashed UTW-Sx=preserved. |
Gives the error message belonging to an error code, like the OPL function ERR$. If the error code has no standard error message then the default message '*** ERROR ***' (or 'UNKNOWN ERR x' on an LZ) is returned. |
032 20 | ER$MESS |
INPUT: | B=Error code to look up. |
OUTPUT: | None.
X=preserved D=trashed |
Displays an error message and the string 'press SPACE key' and then waits for the space or ON/CLEAR key to be pressed. Note that with error number 194, the low battery error, the organiser will be switched off after four seconds. The LZ in 4-line mode will use all four lines of the display. |
Programmers should note that calls to the FL$ services are allowed to be interspersed with PK$ calls - which may change currently selected device or change the current pack address - provided that PK$SETP is called to re-select the correct device for the file system before calling any further FL$ services. As always, any programs directly accessing the datapack hardware should notify the OS by calling PK$SETP.
033 21 | FL$BACK |
INPUT: | None |
OUTPUT: | X=new current record number
D=preserved |
Performs like the OPL command BACK, setting the current record number to the previous record. Should not be called when FLW_CREC = 0 or 1 because then there is no previous record. On exit X contains the new current record number, i.e. the new value of FLW_CREC. Register D is preserved. |
034 22 | FL$BCAT |
INPUT: | A=1 on the first call, 0 for subsequent calls.
B=pack (0-3) X=Address to store result (which will be lbc string of filename, in form 'D:NAME') UTW_S0l=File type to look for (81-8F) |
OUTPUT: | None. |
Performs much like the OPL function DIR$ except that it works on all file
types. When called, this service will store the name of the next file it
finds. Register A should contain 1 on the first call to FL$BCAT so that the
search can be initialised, and 0 on subsequent calls so that the search will
be continued from where it left off. If no more files are found then the
service exits with the error 'FILE NOT FOUND', 238. Note that calling this
service to look for files of type $81 is equivalent to using FL$CATL.
The following errors can be generated:
|
035 23 | FL$BDEL |
INPUT: | X=address of filename (lbc string of form 'D:NAME')
B=file type (must be in range $82-$8F) |
OUTPUT: | None. |
Deletes a block file, i.e. a file of type between $82 and $8F. If a file is
removed from a RAM device then the space the file used is freed up. This
service can not be used to delete files of type $81. For ordinary files the
service FL$DELN is used instead. LZ users, see also FL$WDEL.
The following errors can be generated:
|
036 24 | FL$BOPN |
INPUT: | X=address of filename (lbc string of form 'D:NAME')
B=block file type ($82-$8F) |
OUTPUT: | D=length of data block in file |
Opens a block file. On exit, the current pack and pack address are set so
that the data can be read immediately using PK$READ. If the file does not
exist then a 'FILE NOT FOUND' error 234 is returned.
The following errors can be generated:
|
037 25 | FL$BSAV |
INPUT: | X=address of filename (lbc string of form 'D:NAME')
B=block file type ($82-$8F) UTW_S0=length of data block |
OUTPUT: | None. |
Saves the block file name and length in preparation for saving the actual
data block of the file. On exit, the current pack and pack address is all
set for PK$SAVE to save the data block of the file. This service does check
whether the file fits on the device before writing anything.
The following errors can be generated:
|
038 26 | FL$CATL |
INPUT: | A=1 on the first call, 0 for subsequent calls.
B=pack (0-3) X=Address to store result (which will be lbc string of filename, in form 'D:NAME') |
OUTPUT: | None. |
Performs like the OPL function DIR$. When called, this service will store the
name of the next ordinary file found. Register A should contain 1 on the
first call to FL$CATL so that the search can be initialised, and 0 on
subsequent calls so that the search will be continued from where it left off.
If no more files are found then the service exits with error 238, 'FILE NOT
FOUND'. Note that a similar service for other file types is performed by
FL$BCAT.
The following errors can be generated:
|
039 27 | FL$COPY |
INPUT: | D=address of source filename (lbc string of form 'D:NAME' or 'D:')
X=address of target filename (lbc string of form 'D:NAME' or 'D:') UTW_S0h=block file type ($82-$8F) or 0 for ordinary files. UTW_S0l=contains 1 for object only procedure copy, 0 otherwise. |
OUTPUT: | None. |
Copies ordinary files or block files from one device to another, like the OPL
command COPY. If the target filename is different from the source name then
the file is in effect renamed. Note that because this service does not change
the data block in any way, a procedure will still show the old filename when
printed. If the target filename contains only the target device name then the
file will be copied with the same name. If both filenames contain only device
names, then all relevant files will be copied. If an ordinary file is copied,
and the target device already contains a file of the same name then the
records will be appended. If this happens with a block file then it will
overwrite the file on the target device. LZ users, see also FL$WCPY.
The following errors can be generated:
|
040 28 | FL$CRET |
INPUT: | X=address of filename (lbc string of form 'D:NAME') |
OUTPUT: | A=record type of file |
Creates an ordinary file, like the OPL command CREATE. If a file of the given
name already exists then an error 235 'FILE EXISTS' is returned.
The following errors can be generated:
|
041 29 | FL$DELN |
INPUT: | X=address of filename (lbc string of form 'D:NAME') |
OUTPUT: | None. |
Delete an ordinary file like the OPL command DELETE. To delete block files
the service FL$BDEL is used instead. LZ users, see also FL$WDEL.
The following errors can be generated:
|
042 2A | FL$ERAS |
INPUT: | None. |
OUTPUT: | None. |
Erases the current record from the current file, like the OPL command ERASE.
The current file position is not changed, even if the last record has just
been erased. If an attempt is made to erase after the last record of the file
then an 'END OF FILE' error 238 is returned.
The following errors can be generated:
|
043 2B | FL$FFND |
INPUT: | A=length of string to search for
B=file/record type to look through X=address of string to search for |
OUTPUT: | None. |
Tries to find a record of a given type on the current pack which starts with
a given string. The search begins at the start of the pack and stops at the
first match, or when no matches are found at all. If a matching record is
found, the whole record is stored at RTB_BL as a lbc string. If there is no
match an 'END OF FILE' error 238 is returned. This service is normally used to
check whether a particular filename exists on a pack. In this case, B is a
file type between $81 and $8F, and the string is the beginning of a filename.
Note that searching for the string 'ABC' will find the name 'ABCD' too. Since
filenames are stored as 8 byte string padded with spaces if necessary,
searching for 'ABC ' will only find the correctly named file. This
service can also be used for ordinary file records, in which case register B
is the data record type of the file to search through so must be in the range
$90-$FE. The FL$FIND service is more flexible in this respect however.
The following errors can be generated:
|
044 2C | FL$FIND |
INPUT: | D=address of lbc string to search for
X=address to store record found, as lbc string |
OUTPUT: | A=current record type |
Searches the current datapack for the next record of the current type
containing a given string. This therefore works exactly like the OPL command
FIND, in that it find the next occurrence of a string in a particular file.
If a matching record is found, it becomes the current one, and its contents
are stored at address X. If there is no match, the file position is left at
the end of the file and an 'END OF FILE' error 238 is returned.
The following errors can be generated:
|
045 2D | FL$FREC |
INPUT: | D=record number to examine |
OUTPUT: | A=length of the record
B=current record type X=low bytes of pack address of record UTW_S0=high byte of pack address of record |
Returns information about the D'th record of the current record type on the
current datapack. If the record is found then its three byte address and its
length are returned. If no such record exists because there are less than D
records on the pack then an "END OF FILE" error 238 is returned.
The following errors can be generated:
|
046 2E | FL$NEXT |
INPUT: | None. |
OUTPUT: | None. |
Moves to the next record in the current file by incrementing the current record number. This service is like the OPL command NEXT. It does not perform any checks to see is the end of the file has been reached or passed. This will be checked for when the file is next accessed. |
047 2F | FL$OPEN |
INPUT: | X=address of filename (lbc string of form 'D:NAME' or 'NAME') |
OUTPUT: | A=record type of file |
Opens an existing ordinary file. If the device is not named, the file is
assumed to be on the current device. If the file does not exist a "FILE NOT
FOUND" error is returned.
The following errors can be generated:
|
048 30 | FL$PARS |
INPUT: | X=address of filename (lbc string of form 'D:NAME' or 'NAME')
D=address to store standard format filename UTW_S0h=default device if no device given in name. |
OUTPUT: | None. |
Checks whether a file name is legal, and if so it is converted to a standard
format. This format is a 9 byte string; a device byte (0-3) followed by a
filename which has been padded with spaces to make it 8 characters long.
The errors "BAD FILE NAME" 236, or "BAD DEVICE NAME" 243 will be returned
if the filename or the default device is illegal.
The following errors can be generated:
|
049 31 | FL$READ |
INPUT: | X=Address to store the record |
OUTPUT: | B=Record type |
Reads in the current record, storing it in memory. Note that the current
record number is not altered.
The following errors can be generated:
|
050 32 | FL$RECT |
INPUT: | B=Record type (must be $81-$FE) |
OUTPUT: | None. |
Sets the current record type. This is normally set to a value in the range $90-$FE, the record data types of ordinary files. Note that record type $90 is always the MAIN file. However, by choosing a value in the $81-$8F range the filename records will be used by later file services instead. |
051 33 | FL$RENM |
INPUT: | D=new filename (lbc string in form 'D:NAME' or 'NAME')
X=old filename (lbc string in form 'D:NAME' or 'NAME') |
OUTPUT: | None. |
Renames an ordinary file, by deleting the old filename record and saving a
new one. If both filenames include device names, then the device names must
be the same. If the old filename does not include a device name then the
current device is assumed. The new filename cannot consist of a device name
only. If the devices differ or a filename is illegal then a 'BAD FILE NAME'
error is returned.
The following errors can be generated:
|
052 34 | FL$RSET |
INPUT: | D=record number to make current |
OUTPUT: | None. |
Sets the current file position, like the OPL command POSITION. The first record is number 1, and no attempt should be made to set the record number to 0. Like FL$NEXT, this service does not check whether the new current record exists. This will be checked when the non-existent record is accessed. |
053 35 | FL$SETP |
INPUT: | B=pack (must be in range 0-3) |
OUTPUT: | None. |
Selects the pack which future file services are to use. |
054 36 | FL$SIZE |
INPUT: | None |
OUTPUT: | X=number of records of the current record type
UTW_S1h=high byte of amount of free space D=lowest bytes of amount of free space UTW_S1l=high byte of pack address UTW_S0=lowest bytes of pack address |
Returns the amount of free space the current datapack and where the first
free byte is. It also returns the number of records of the current record
type. Thus if the record type is between $81 and $8F the number of files of
that type is returned, and if the record type is $90 to $FE then the number
of data records in the file using that record type is returned. This service
is used by the OPL commands SPACE, LAST, and COUNT.
The following errors can be generated:
|
055 37 | FL$WRIT |
INPUT: | X=Address of lbc string containing data to be saved (max 254 chars, truncated if 255 chars used) |
OUTPUT: | None. |
Appends a new record of the current record type to the current device, much
like the OPL command APPEND. The current record number changed so that the
record just written becomes the current one. The amount of available free
space is checked first to see if the record fits on the pack.
The following errors can be generated:
|
The following services use the run-time stack, also called the language stack. Its stack pointer is rta_sp ($A5/A6). It holds the address of the last byte of the stack. To push a floating point number onto the stack you must decrement the stack pointer by 8 and place the number in those 8 bytes from the pointer upwards. The services remove any numbers they need from the stack and place the result on it instead. The result is also left in the floating point accumulator ($C5-$CD).
Care must be taken to restore the stack to its previous state. If you push some values on the stack and maybe use these services for calculating from them, then afterwards the stack pointer must restored to the previous value. Any data higher up the stack must be preserved.
There are always at least $100 bytes available on the stack. Do not temporarily point the stack pointer to another memory area with floating point values unless there is at least 60 bytes below it for the services to use for intermediate results.
These services use the table interpreter (IT$STRT).
056 38 | FN$ATAN |
INPUT: | None |
OUTPUT: | None |
Replaces the floating point number on the top of the run-time stack with its arctangent. Error 253 'exponent overflow' may be returned. |
057 39 | FN$COS |
INPUT: | None |
OUTPUT: | None |
Replaces the floating point number on the top of the run-time stack with its cosine. Error 247 'Function argument error' may be returned. |
058 3A | FN$EXP |
INPUT: | None |
OUTPUT: | None |
Replaces the floating point number on the top of the run-time stack with the result gained from raising the constant e (2.718281828..) to the power of the given number. Error 247 'Function argument error' may be returned. |
059 3B | FN$LN |
INPUT: | None |
OUTPUT: | None |
Replaces the floating point number on the top of the run-time stack with its natural logarithm (i.e. base e). Error 247 'Function argument error' may be returned. |
060 3C | FN$LOG |
INPUT: | None |
OUTPUT: | None |
Replaces the floating point number on the top of the run-time stack with its logarithm (i.e. base 10). Error 247 'Function argument error' may be returned. |
061 3D | FN$POWR |
INPUT: | None |
OUTPUT: | None |
Replaces two floating point numbers on the top of the run-time stack with the result gained be raising one to the power of the other. If X and Y are on the stack, and Y was pushed last, then this service will replace the two numbers with X**Y. Error 247 'Function argument error' may be returned. |
062 3E | FN$RND |
INPUT: | None |
OUTPUT: | None |
Pushes a random number between 0 and 1 on the stack. |
063 3F | FN$SIN |
INPUT: | None |
OUTPUT: | None |
Replaces the floating point number on the top of the run-time stack with its sine. Error 247 'Function argument error' may be returned. |
064 40 | FN$SQRT |
INPUT: | None |
OUTPUT: | None |
Replaces the floating point number on the top of the run-time stack with its square root. Error 247 'Function argument error' may be returned. |
065 41 | FN$TAN |
INPUT: | None |
OUTPUT: | None |
Replaces the floating point number on the top of the run-time stack with its tangent. Error 247 'Function argument error' may be returned. |