Jaap's Psion II Page

                                CHAPTER 12

                               _____________
                               FILING SYSTEM



           _________________
12.1  FILES AND RECORDS


This section describes the format of file-structured  datapacks,  then  the
system  services available for file and record management.  System services
which access datapacks directly are discussed in chapter 9.  See  also  the
Organiser  II operating manual for details of file handling in OPL.  In the
following sections "datapack"  means  EPROMs,  ROMs  on  external  devices,
external RAM packs, and internal RAM (the device A:).  The operating system
handles the different device types  in  the  same  way  apart  from  delete
operations.   All  device  types  use  the  same  record structure.  Device
dependencies will be pointed out as necessary.



        _______
12.1.1  RECORDS


Datapacks contain two types of records, preceded by either a byte  or  word
length.   This  is to al low long records while minimising the overhead for
text files which typically contain short  records.   The  first  record  is
always  at byte $0A in the datapack.  The record structure is terminated by
a byte $FF.



          _____________
12.1.1.1  SHORT RECORDS


Short records are of the format :


        Byte :  0               1               2
                -----------------------------------------------------
                |    length     |  record type  | 1 to $FE data bytes ...
                -----------------------------------------------------
        Range :     1 to $FE        $81 to $FE

        Example :

        "HELLO" saved using SAVE. Record type is $90.

        $05 $90  $48 $45 $4C $4C $4F


Note that the length byte does not include itself or the record type.   The
record  length can not be zero.  The maximum length is $FE, because a first
byte $FF is used to terminate the record structure.  The record type is  in
the  range  $81  to $FE inclusive.  When writing to more than one file, the
record type is used to identify which file each record  belongs  to,  since
the records may be written in any order.



          ____________
12.1.1.2  LONG RECORDS


     Long records are used primarily for saving blocks of data  which  will
not  be regularly altered, which are intended to be loaded and saved in one
piece.  Long records are also used to contain information which  is  to  be
hidden from the file system (see section 11.1.1 - bootable packs).

Long records have the following format :
        Byte :  0       1       2       3       4       ...
                --------------------------------------------------------
                |  $02  |  $80  |  length word  |  ... data ...         |
                ---------------------------------------------------------

                 byte 0         always $02
                 byte 1         always $80

                 byte 2         high byte of length of data
                 byte 3         low byte        ..      ..
                [byte 4         0 to $FFFF bytes of data]
                [               ...  ]

        Example :

        long record "HELLO"

        $02 $80 $00 $05         $48 $45 $4C $4C $4F

        null long record

        $02 $80 $00 $00


Long records do not have a length byte as such, the $02 is purely for error
handling  (see  section  12.1.5).   The  $80 is a special record type which
identifies a long record.



          _______________
12.1.1.3  DELETED RECORDS


On EPROM datapacks, short records are marked as deleted by clearing the top
bit  of  the  record type.  On EPROMs long records are never deleted - this
will be discussed later.  On a RAM device, the space occupied by  a  record
is  recovered  when  the  record  is deleted, so there will not be any long
records with a record type < $80 on either RAM or EPROM devices.

        Example :

            short record "AAA" of record type $91 on an EPROM

                        $03 $91 $41 $41 $41     when deleted becomes :
                        $03 $11 $41 $41 $41




        _____
12.1.2  FILES


There are two kinds of files ; files accessible to OPL (of which  the  file
"MAIN"  is  an example), and block files such as OPL procedures.  In future
we will refer to the first kind simply as 'files'.

Each files has a name, which is a short record of type $81, and a number of
data  records  which  are  short records all of the same record type in the
range $90 to $FE.  Each file has data records of a unique record  type,  so
there  can be up to 111 files on a device.  An attempt to create more files
will produce the error "DIRECTORY FULL".  A file may contain  up  to  $FFFE
data records, given a sufficiently large pack.

Filenames have the following format :

        Byte :  0   1   2   3   4   5   6   7   8   9   10
                -----------------------------------------------------
                |$09|$81| file name, space filled       |record type|
                -----------------------------------------------------

        Example : the file MAIN
                09 81   4D 41 49 4E 20 20 20 20 90

                all records of type $90 will be in MAIN.


Filenames are always padded with spaces to  make  them  eight  bytes  long.
Byte  10 in the above diagram is the record type which will be used for all
data records in the file.  It can take values  in  the  range  $90  to  $FE
inclusive.

When a file is created, the operating system first searches through all the
filenames  on  the datapack to find the lowest free record type and this is
then allocated to the new file.  The new record type is then stored in  the
new file name record.  Since several files can be open at once, the records
of a file can be mixed with any other type of records.  No  facilities  are
provided  to  allow  reordering  of  records  in  a  file,  or to allow the
insertion of records in the middle of a file.  When a file is deleted,  all
records  of  the appropriate type are deleted one by one, then the filename
is deleted.  On EPROMs the filename is deleted by  overwriting  the  record
byte (i.e.  $81 in the above example) in the filename with 01.

The total overhead for each file is 11 bytes  for  the  filename  plus  two
bytes per record.



          _____________________
12.1.2.1  FIND, SAVE AND "MAIN"


The top level commands FIND and SAVE work with short records  of  type  $90
directly,  not  by  opening  the  file  MAIN.   This  means that if MAIN is
deleted, problems can occur.  SAVE will still save records of type $90, but
these records can not be re-read by OPL.  The record type $90 is 'reserved'
for MAIN, so that no other file can have  this  record  type.   When  blank
packs are sized, the filename MAIN is created.

Note :  User programs should never  delete  MAIN,  since  this  will  cause
problems  with  certain  OS versions.  To create a new MAIN, delete all the
records in a loop.



        ___________
12.1.3  BLOCK FILES


Block files are a special class of files with a name  immediately  followed
by  a  single  long  data record.  No records are allowed between the block
filename and the long record.  They are intended  for  storing  data  which
will  be  re-saved  as a whole each time the data is changed.  Long records
may be used alone without a preceding  block  filename  -  for  example  to
enclose  a  machine  code  program  on  a  datapack.   Long records with no
preceding block filename are ignored by the file system.

Format of a block file :

        byte :  0   1    2   3   4   5   6   7   8   9  10
                ----------------------------------------------
    FILENAME    |$09|TYPE|file name, space filled       | 00 |
                ----------------------------------------------

        byte :  11  12  13  14  15
                ----------------------------------------------
 LONG RECORD    |$02|$80|length | data .....
                ----------------------------------------------

Example :  block file ABCD of block type  $83,  containing  four  bytes  of
data.

                09 83           41 42 43 44 20 20 20 20 00
                02 80 00 04     xx xx xx xx


The record type, byte 1 in the above  diagram,  is  in  the  range  $82-$8F
inclusive.   This  byte  is  used to distinguish different classes of block
files containing different kinds of information, and will be referred to as
the block file type.  Because block files have their data immediately after
the filename they do not need a data record type, so  byte  10,  which  was
used  as  the  data  record type in ordinary filenames is not used in block
files.  This byte is reserved by Psion.  Note also that the number of block
files  on a device is limited only by the space available, and there can be
up to fourteen different kinds of block files with types $82 to $8F.

On EPROMS, a block file is deleted by clearing the top bit  in  the  record
type  byte  of  the name (byte 1, the $83 in the above example).  The total
overhead for each block file is 15 bytes.



          ___ _________________________
12.1.3.1  OPL PROCEDURES, SAVED DIARIES


OPL procedures are saved as block files  of  type  $83,  in  the  following
format:

     +-------------------------------+

     | length of Q-code (word)  |

     +-------------------------------+

     |                          |

     |   Q-code (if any)        |

     |                          |

     +-------------------------------+

     | length of source (word)  |

     +-------------------------------+

     | 1st source line   |00|

     +-------------------------------+

     | 2nd source line   |00|

     +-------------------------------+

     | ...       |00|

     +-------------------------------+

The length of the Q-code may be zero, if the procedure was saved  with  the
SAVE  option  in the TRAN SAVE QUIT sub-menu.  The length of the source may
be zero if the procedure has been copied object-only.   Each  line  of  the
source is terminated by a zero.

The DIR option in the PROG sub-menu works by finding all type $83  records.
Saved  diaries  are  block files of type $82.  The other block file type in
use at the time of writing is $84, which is used by  the  RS232  for  saved
setups.

Users wishing to use any of the remaining  block  file  types  $85  to  $8F
should  first  contact  Psion,  to  avoid  incompatibility  with any future
products.  Block file types are important in  keeping  different  types  of
data  distinct  :   disaster would result if OPL procedures could be loaded
into the diary, for example.  Applications tend to assume that block  files
of their own type are in the correct format, and usually perform no further
checking.



        ___________________________
12.1.4  SUMMARY OF RECORD STRUCTURE


This is the algorithm for  scanning  through  the  record  structure  of  a
datapack :

        SET_PACK_ADDRESS ($0A)
        do
            LENGTH_BYTE = NEXT_BYTE
            RECORD_TYPE = NEXT_BYTE
            if LENGTH_BYTE = 0
                ERROR (246) -- "no pack"
                stop
            endif
            if RECORD_TYPE = $80        -- if long record
                BLOCK_LENGTH = NEXT_WORD
                SKIP_BYTES (BLOCK_LENGTH)
            else
                if RECORD_TYPE <> $FF   -- if valid short record
                    SKIP_BYTES (LENGTH_BYTE)
                endif
            endif
        until LENGTH_BYTE = $FF

        -- found end of pack




        ______________
12.1.5  ERROR HANDLING


If a length byte of zero is seen the pack is assumed to  have  been  pulled
out,  and  a NO PACK error is reported.  Errors can occur in various places
when writing to EPROM devices, which can disrupt the record structure.  The
file system error handling attempts to mark the data as deleted, or creates
special 'invalid' records so that the remainder of the datapack  can  still
be used.  In certain exceptional cases this mechanism can fail, and a "READ
PACK" error will result when invalid record structure  is  detected.   This
error  is  reported  whenever the last record extends beyond the end of the
pack.  An "END OF FILE" error will also be reported when accessing a  block
file if the block file name is not followed immediately by a long record.

When writing a block file, any error will cause  the  operating  system  to
first delete the long record, then the block file name.  This is the reason
for the $02 before the $80 in a long record - if writing  the  length  word
fails,  the $80 is re-written as a zero, which forms a deleted short record
enclosing the bad length word.  When a block file is  opened,  if  a  valid
long  record  beginning  with $02 $80 is not found, the error "END OF FILE"
(238) is reported.

When writing a short record the following errors may occur :

     1.  When writing the length byte fails, no further bytes  are  written
         to  the  record.  The record is left with a second byte $ff, which
         is taken as a special invalid record type.  If this type of record
         is  seen  the  bad  length byte is ignored, and the next record is
         assumed to begin immediately  after  the  $FF.   This  prevents  a
         record  with a bad length byte from going off the end of the pack.
         However, the method is fallible because the length byte  could  be
         $FF,  denoting  the  end  of  the  datapack, or could even be zero
         (although zero is very unlikely).

     2.  When writing the record type or a data byte fails,  the  operating
         system  attempts  to delete the record.  If this fails, a spurious
         record will remain, which may become part of the wrong file  since
         the record type is wrong.


Some of the errors  mentioned  with  the  system  service  descriptions  in
section  12.2,  such  as  "PACK NOT BLANK", and "WRITE PACK ERROR" may only
occur when sizing a blank EPROM device.  Apart from the  obvious,  "END  OF
FILE"  can  mean  :   an  illegal  block file (as discussed above), or more
generally "not found".



        _______________________
12.1.6  SUMMARY OF RECORD TYPES


          Record type

   deleted   00         invalid long record - ignored by file system
   short     01 - 7E
   records   7F         deleted $FF (should not occur)

             80         long record - length word follows
             81         file name
             82         block file  - saved DIARY
             83         block file  - OPL procedure
             84         block file  - saved RS232 setup
             85 - 8F    block files - reserved to PSION
             90         record from MAIN, top level FIND/SAVE record
             91 - FE    data records from files
             FF         invalid record - length byte will be ignored

    Example of record structure :

      09 81 4D 41 49 4E 20 20 20 20 90  filename "MAIN"

      04 90 41 41 41 41                 record "AAAA" in MAIN

      09 81 41 42 43 20 20 20 20 20 91  filename "ABC",
                                        data records are type $91

      02 91 42 42 42                    record "BBB" in ABC

      01 10 41                          deleted record "A" in MAIN

      09 85 42 4C 4F 43 4B 20 20 20 00  block file "BLOCK", type $85
      02 80 00 05 01 02 03 04 05        contains 5 bytes of data

      09 02 4F 4C 44 20 20 20 20 20 00  deleted block file "OLD",
      02 80 00 01 FF                    of type $82 (diary),
                                        contained 1 byte of data

      F7 FF                             invalid short record

      09 03 42 41 44 20 20 20 20 20 00  invalid block file "BAD"
      02 00 00 FF                       of type $83 (OPL proc),
                                        deleted when length word
                                        failed
        FF                              end of datapack



        _____________________
12.1.7  FILE SYSTEM VARIABLES


Some of the file system's variables can be usefully read by the  user,  but
these variables should be treated as read only.  Writing to these variables
may produce unpredictable results,  and  will  cause  incompatibility  with
future OS versions.

$96     FLB_RECT        Current record type in use - set by FL$RECT, and
                        implicitly set by FL$OPEN, FL$CRET etc. Returned
                        by FL$OPEN, FL$CRET and others.

$97     FLB_CPAK        Current device used by file system, set by FL$SETP,
                        and implicitly set by FL$OPEN, FL$CRET etc.

$9B     FLW_CREC        Current record number - 1 is the first record. Counts
                        the records of type FLB_RECT. Set by many routines
                        including FL$RSET, FL$NEXT.



        _________________________
12.1.8  ORGANISER I COMPATIBILITY


Organiser I datapacks are structured differently to Organiser II  datapacks
- the details will not be discussed here.  The main differences are :

     1.  Organiser I datapacks have a first byte $FC - a value not used  by
         the  Organiser  II.   These  packs are treated as read-only by the
         Organiser II.

     2.  Organiser I program packs have a first byte of  $03;  these  packs
         are not supported by the organiser II.

     3.  Records saved on Organiser I datapacks with SAVE are stored  in  a
         packed  six-bit  format,  which  can  be read by the Organiser II.
         These records are treated as part of  an  imaginary  file  "MAIN".
         All  read-only  file  system  operations on "MAIN" will work on an
         Organiser I datapack, including COPY.   Other  types  of  records,
         such as POPL programs are not supported.


The Organiser I datapacks themselves are all compatible with the  Organiser
II, and can be used on the Organiser II after UV-erasure.  Also there is no
reason why a special user program could not read an Organiser  I  datapack,
by  accessing the datapack directly.  If some special data other than SAVEd
records is to be transferred, the easiest method is to use two RS232 leads.



      _______________
12.2  SYSTEM SERVICES


This section describes the system services used by  OPL  to  handle  files,
records and block files.  The names of these services are prefixed by FL$.

Services which handle files and block files :

                                _____           ___________
                                FILES           BLOCK FILES

        Opening old files       FL$OPEN         FL$BOPN (then PK$READ)

        Creating new files      FL$CRET         FL$BSAV (then PK$SAVE)

        Closing files              -

        Deleting files          FL$DELN         FL$BDEL

        Copying files           FL$COPY            -
        Renaming files          FL$RENM            -

        Directory of files      FL$CATL         FL$BCAT

        File statistics         FL$SIZE         (use FL$BOPN)


Services which handle records :

        Reading records                 FL$READ

        Writing (appending) records     FL$WRIT

        Erasing records                 FL$ERAS

        Positioning to a                FL$BACK
        record                          FL$NEXT
                                        FL$RSET

        Finding a record by             FL$FIND
        its content                     FL$FFND

        Getting record info             FL$FREC

        Setting default
        device                          FL$SETP
        record type                     FL$RECT



See section 9.5.3 for PK$READ and section 9.5.2 for PK$SAVE.

It is more efficient to use record types directly to access  several  files
at  once,  rather  than  opening  one  file,  then  the other.  This is the
equivalent of the OPL command  USE.   The  services  FL$OPEN,  and  FL$CRET
return the record type in use by a file.  FL$FREC will provide details of a
record including its address in the pack for any user  wishing  to  perform
direct  pack  accessing,  however  such programs may not be compatible with
future OS versions.

Programmers should note that calls to the FL$ services may 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.



        _______
12.2.1  FL$BACK


VECTOR NUMBER :         033

INPUT PARAMETERS :      NONE
OUTPUT VALUES :         X = updated record number (FLW_CREC)

REGISTERS PRESERVED :   D

DESCRIPTION

Used in the OPL command BACK.  Sets the current file position back  to  the
previous record.

Should not be called with FLW_CREC = 0 or 1.  The first record is  numbered
1.

EXAMPLE

        LDA     B,#10           ; go back ten records

1$:     LDX     FLW_CREC        ; don't go back past start
        CPX     #1
        BCC     2$

        OS      FL$BACK
        DEC     B
        BNE     1$

2$:


ERRORS          NONE



        _______
12.2.2  FL$BCAT


VECTOR NUMBER :         034

INPUT PARAMETERS :      A = 1 for 1st call, 0 subsequently
                        B = device (0 to 3)
                        X = where to put filename (leading count byte)
                        UTW_S0+1
                          = block file type ($81 to $8F inc.)

OUTPUT VALUES :         NONE

DESCRIPTION

When called repeatedly, returns each filename of a given record type  on  a
device as a leading count byte string at the address given in X in the form
D:NAME .  A is set to  1  before  the  first  call  to  FL$BCAT  and  0  on
subsequent  calls.  When there are no more files in the directory the carry
is set and B = ER_FL_EF.  B contains the device number - 0 for A:, 1 for B:
etc.   A  record type of $81 in (UTW_S0+1) will do a directory of files, as
in the OPL function DIR$.  Any other value up to $8F inclusive  will  do  a
directory of block files of the given type.

Calling FL$BCAT with UTW_S0+1 = $81 is equivalent to calling  FL$CATL.   No
error  is  reported  if  the  block file type is outside the range $81-$8F,
unless the block file type is less than $80.

See also section 12.2.6 FL$CATL, section  13.4.3  UT$XCAT,  section  12.1.3
block files.

EXAMPLE

;       Do a directory of saved diaries

        LDA     A,#1            ; A=1 first time FL$BCAT called
        BRA     FIRST
;       For each file in directory :-

LOOP:   LDX     #TEMP           ; print leading count byte string in TEMP
        PSHX                    ; pass address to UT$DISP
        OS      UT$DISP
        .ASCII  "%s"            ; leading count byte string
        .BYTE   13,10           ; CR LF
        .BYTE   0               ; terminator for format string

        CLR     A               ; A=0 on subsequent calls to FL$BCAT
FIRST:  LDA     B,#$82          ; UTW_S0+1 = block file type for diaries
        STA     B,UTW_S0+1:
        LDX     #TEMP           ; filenames be placed in TEMP by FL$BCAT
        LDA     B,#MY_DEVICE    ; which device : 0 - 3 for A: to D:
        OS      FL$BCAT
        BCC     LOOP            ; repeat until error returned
        CMP     B,#ER_FL_EF     ; end-of-file error means normal completion
        BEQ     DONE

ERROR:  ...                     ; otherwise report error

DONE:   ...

ERRORS

    ER_FL_EF    238     FILE NOT FOUND (normal completion)

    ER_GN_BL    194     BATTERY TOO LOW
    ER_PK_BR    200     READ PACK ERR
    ER_FL_BR    237     BAD RECORD TYPE (if record type <$80 only)
    ER_PK_IV    240     UNKNOWN PACK
    ER_PK_NB    241     PACK NOT BLANK
    ER_PK_DV    243     BAD DEVICE NAME
    ER_PK_DE    245     WRITE PACK ERR
    ER_PK_NP    246     NO PACK



        _______
12.2.3  FL$BDEL


VECTOR NUMBER :         035

INPUT PARAMETERS :      X = block file name (leading count byte).
                        B = block file type ($82 to $8F incl.)
OUTPUT VALUES :         NONE

DESCRIPTION

Delete a named block file of the block type B.  The file name is a  leading
count  byte  string at X in the form D:NAME.  On RAM devices the block file
name and the following long record is deleted and the space is  freed.   On
EPROMs the long record is not affected.

No error is reported if the block file type is outside the  range  $81-$8F,
unless the block file type is less than $80.

EXAMPLE

        LDA     B,#$83          ; block file type for OPL procs
        LDX     #NAME           ; address of filename
        OS      FL$BDEL         ; delete it
        BCS     ERROR


NAME:   .ASCIC  "C:MYPROG"

ERRORS

    ER_GN_BL    194     BATTERY TOO LOW
    ER_PK_BR    200     READ PACK ERR
    ER_FL_NX    234     FILE NOT FOUND
    ER_FL_BN    236     BAD FILE NAME
    ER_FL_BR    237     BAD RECORD TYPE (if record type <$80 only)
    ER_PK_IV    240     UNKNOWN PACK
    ER_PK_NB    241     PACK NOT BLANK
    ER_PK_DV    243     BAD DEVICE NAME
    ER_PK_RO    244     READ ONLY PACK
    ER_PK_DE    245     WRITE PACK ERR
    ER_PK_NP    246     NO PACK



        _______
12.2.4  FL$BOPN


VECTOR NUMBER :         036

INPUT PARAMETERS :      X  = block file name (leading count byte).
                        B  = block file type

OUTPUT VALUES           D  = length of data in block file

DESCRIPTION

Finds a named block file of the given block file type data.  On return D is
the  length  of  the  data, and the pack address is set to the start of the
data, ready for PK$READ to load the data into RAM.   The  file  name  is  a
leading count byte string at X in the form "D:NNNNN".

Error "FILE NOT FOUND" will be reported if the file does not exist.

See section 9.5.3 for PK$READ.

EXAMPLE

        LDA     B,#$84          ; block file type for RS232 saved setup
        LDX     #NAME           ; address of filename
        OS      FL$BOPN         ; open the file
        BCS     ERROR

        LDX     #LOAD_ADDRESS
        OS      PK$READ
        ...

NAME:   .ASCIC  "C:IBMPC"

ERRORS

    ER_GN_BL    194     BATTERY TOO LOW
    ER_PK_BR    200     READ PACK ERR
    ER_FL_NX    234     FILE NOT FOUND
    ER_FL_BN    236     BAD FILE NAME
    ER_FL_EF    238     END OF FILE -  see section 12.1.5
    ER_PK_IV    240     UNKNOWN PACK
    ER_PK_NB    241     PACK NOT BLANK
    ER_PK_DV    243     BAD DEVICE NAME
    ER_PK_DE    245     WRITE PACK ERR
    ER_PK_NP    246     NO PACK



        _______
12.2.5  FL$BSAV


VECTOR NUMBER :         037

INPUT PARAMETERS :      B = block file type
                        X = block file name (leading count byte).
                        UTW_S0 = length of code to be saved by PK$SAVE

OUTPUT VALUES :         NONE

DESCRIPTION

Called in preparation for saving  a  block  file,  FL$BSAV  saves  a  block
filename followed by the first four bytes of a long record :  $0280 and the
length word given in UTW_S0.  Then a call to PK$SAVE must be made  to  save
the  data.   FL$BSAV  checks  that there is sufficient room on the pack for
both the filename and the long record before writing to the  datapack.   If
PK$SAVE  fails,  the  user is responsible for any error recovery.  The file
name is a leading count byte string at X in the form D:NAME.

See also sections section 9.5.2 PK$SAVE,  section  12.1.1.2  long  records,
section 12.1.3 block files and section 12.1.5 errors.

EXAMPLE
;       To save an OPL procedure :
        LDX     PROCSIZE        ; UTW_S0 = length of data to be saved
        STX     UTW_S0:
        LDX     #PROCNAME       ; address of procedure name
        LDA     B,#$83          ; block file type for OPL procedures
        OS      FL$BSAV
        BCS     ERROR

        LDD     PROCSIZE        ; length of data to be saved
        LDX     #PROCSTART      ; start of data in OPL procedure
        OS      PK$SAVE         ; save the block data
        BCC     DONE            ; branch if all ok

;       if error in PK$SAVE
        CMP     B,#ER_PK_DE     ; B = error code from PK$SAVE
        BNE     1$

;       if WRITE PACK ERROR :
        PSH     B               ; preserve error code
        LDX     #PROCNAME       ; address of procedure name
        LDA     B,#$83          ; block file type for OPL procedures
        OS      FL$BDEL         ; try to delete the block file
        PUL     B
1$:     SEC                     ; set carry again
ERROR:
        ...                     ; report error

DONE:
        ...


ERRORS

    ER_GN_BL    194     BATTERY TOO LOW
    ER_PK_BR    200     READ PACK ERR
    ER_FL_EX    235     FILE EXISTS
    ER_FL_BN    236     BAD FILE NAME
    ER_FL_PF    239     PACK FULL
    ER_PK_IV    240     UNKNOWN PACK
    ER_PK_NB    241     PACK NOT BLANK
    ER_PK_DV    243     BAD DEVICE NAME
    ER_PK_RO    244     READ ONLY PACK
    ER_PK_DE    245     WRITE PACK ERR
    ER_PK_NP    246     NO PACK



        _______
12.2.6  FL$CATL


VECTOR NUMBER :         038

INPUT PARAMETERS :      A = 1 for 1st call, 0 subsequently
                        B = device (0 to 3)
                        X = where to put filename (leading count byte)

OUTPUT VALUES :         NONE
DESCRIPTION

When called repeatedly, returns each the name of each file on a device as a
leading count byte string at the address given in X in the form D:NAME .  A
is set to 1 before the first call to FL$CATL and  0  on  subsequent  calls.
When  there  are  no  more  files in the directory the carry is set and B =
ER_FL_EF.  B contains the device number - 0 for A:, 1 for B:  etc.  Used in
the OPL function DIR$.

Calling FL$CATL is equivalent to calling FL$BCAT with UTW_S0+1 = $81.

See also section 12.2.2 FL$BCAT, section  13.4.3  UT$XCAT,  section
12.1.3 block files.

EXAMPLE

        LDA     A,#1            ; A=1 first time FL$CATL called
        BRA     FIRST
;       For each file in directory :-

LOOP:   LDX     #TEMP           ; print leading string in temp
        PSHX                    ; pass address to UT$DISP
        OS      UT$DISP
        .ASCII  "%s"            ; leading count byte string
        .BYTE   13,10           ; CR LF
        .BYTE   0               ; terminator for format string

        CLR     A               ; A=0 on subsequent calls to FL$CATL
FIRST:  LDX     #TEMP           ; filenames be placed in TEMP by FL$CATL
        LDA     B,#MY_DEVICE    ; which device : 0 - 3 for A: to D:
        OS      FL$CATL
        BCC     LOOP            ; repeat until error returned

        CMP     B,#ER_FL_EF     ; end-of-file error means normal completion
        BEQ     DONE

ERROR:  ...                     ; otherwise report error

DONE:   ...

ERRORS

    ER_FL_EF    238     FILE NOT FOUND (normal completion)
    ER_GN_BL    194     BATTERY TOO LOW
    ER_PK_BR    200     READ PACK ERR
    ER_PK_IV    240     UNKNOWN PACK
    ER_PK_NB    241     PACK NOT BLANK
    ER_PK_DV    243     BAD DEVICE NAME
    ER_PK_DE    245     WRITE PACK ERR
    ER_PK_NP    246     NO PACK



        _______
12.2.7  FL$COPY


VECTOR NUMBER :         039

INPUT PARAMETERS :      D = addr of 'copy-to' string.
                        X = addr of 'copy-from' string.
                        UTW_S0 = type of copy to perform.

OUTPUT VALUES :         NONE

DESCRIPTION

Copies files or block files from one device to another, as in the top level
COPY or PROG COPY menu options.


     ____________                       ______
     TYPE OF COPY                       UTW_S0

        files                           $0000
        OPL procedures                  $8300
        OPL procedures, object only     $8301
        other block files of type XX    $XX00


The high byte of UTW_S0 must be either zero for files or a legal block file
type  in  the  range $82 to $8F inclusive.  FL$COPY must not be called with
any other values of UTW_S0.

X points to the 'copy from' string, D points to the 'copy to' string.  Both
are leading byte count and the following forms are allowed :

    _________   _______
    Copy-from   Copy-to

        C:NNNNNNNN      B:NNNNNNNN      copy one file
        C:NNNNNNNN      B:              .. target filename same as source
        C:              B:              copy all files

The copy-from device must not be the same as the copy-to  device.   A  file
may  be  copied to a different name on the target device.  If a device only
is specified in the copy-to string, the file is copied with the same name.

If the file already exists on the  TO  device  then  the  records  will  be
appended  to  the file otherwise a new file of the appropriate name will be
created.

Note :  When used to copy an OPL procedure to  a  different  name,  FL$COPY
does not actually change the name on the first line of the procedure.  This
means that if an OPL procedure is copied  to  a  different  name  and  then
listed on a printer, it will be shown with the original name.

See also section 12.2.4, TL$CPYX.

EXAMPLE

        To copy all files from A: to B: :

COPY_FROM:
        .ASCIC  "A:"
COPY_TO:
        .ASCIC  "B:"

        CLR     A
        CLR     B
        STD     UTW_S0:         ; copy files
        LDX     #COPY_FROM
        LDD     #COPY_TO
        OS      FL$COPY
        BCS     ERROR

        ...

        To copy A:MYPROC to B:HISPROC, object only

COPY_FROM:
        .ASCIC  "A:MYPROC"
COPY_TO:
        .ASCIC  "B:HISPROC"

        LDD     #$8201
        STD     UTW_S0:         ; copy OPL, object only
        LDX     #COPY_FROM
        LDD     #COPY_TO
        OS      FL$COPY
        BCS     ERROR

        ...

        To copy all data from A: to B:. B: must be empty.
COPY_ALL:
        CLR     A               ; first call to FL$COPY
        BSR     COPY_TYPE_A     ; to copy files
        BCS     ERROR

        LDA     A,#$82          ; copy all block types from $82 to $8F
1$:     PSH     A
        BSR     COPY_TYPE_A
        PUL     A
        BCS     ERROR

        INC     A
        CMP     A,#$8F
        BLS     1$

COPY_TYPE_A:
        CLR     B
        STD     UTW_S0:         ; set type of copy
        LDX     #COPY_FROM
        LDD     #COPY_TO
        OS      FL$COPY
        RTS

COPY_FROM:
        .ASCIC  "A:"
COPY_TO:
        .ASCIC  "B:"

ERRORS

    ER_GN_BL    194     BATTERY TOO LOW
    ER_PK_BR    200     READ PACK ERR
    ER_FL_CY    232     PAK NOT COPYABLE
    ER_FL_DF    233     DIRECTORY FULL
    ER_FL_NX    234     FILE NOT FOUND
    ER_FL_BN    236     BAD FILE NAME
    ER_FL_EF    238     END OF FILE -  see section 12.1.5
    ER_FL_PF    239     PACK FULL
    ER_PK_IV    240     UNKNOWN PACK
    ER_PK_NB    241     PACK NOT BLANK
    ER_PK_CH    242     PAK CHANGED
    ER_PK_DV    243     BAD DEVICE NAME
    ER_PK_RO    244     READ ONLY PACK
    ER_PK_DE    245     WRITE PACK ERR
    ER_PK_NP    246     NO PACK



        _______
12.2.8  FL$CRET


VECTOR NUMBER :         040

INPUT PARAMETERS :      X = address of filename (leading count byte)

OUTPUT VALUES :         If no error -
                        A = data record type used by file

DESCRIPTION

Creates a file.  The file name at X is a leading count byte string  of  the
form  D:NNNNNNNN where D is 'A', 'B', 'C' or 'D' and the name is 1..8 chars
long.  If the file already exists then FL$CRET returns error "FILE EXISTS",
otherwise  the file is created and A contains the record type to be used by
the data records in the file.

EXAMPLE

        To create the file "WIDGET" on device A:

        LDX     #FILENAME
        OS      FL$CRET
        BCS     ERROR

FILENAME:
        .ASCIC  "A:WIDGET"

ERRORS

    ER_GN_BL    194     BATTERY TOO LOW
    ER_PK_BR    200     READ PACK ERR
    ER_FL_DF    233     DIRECTORY FULL
    ER_FL_EX    235     FILE EXISTS
    ER_FL_BN    236     BAD FILE NAME
    ER_FL_PF    239     PACK FULL
    ER_PK_IV    240     UNKNOWN PACK
    ER_PK_NB    241     PACK NOT BLANK
    ER_PK_CH    242     PAK CHANGED
    ER_PK_DV    243     BAD DEVICE NAME
    ER_PK_RO    244     READ ONLY PACK
    ER_PK_DE    245     WRITE PACK ERR
    ER_PK_NP    246     NO PACK



        _______
12.2.9  FL$DELN


VECTOR NUMBER :         041

INPUT PARAMETERS :      X = address of filename (leading count byte)

OUTPUT VALUES :         NONE

DESCRIPTION

Delete a named file.  The file name at X is a leading count byte string  of
the  form  D:NNNNNNNN  where D is 'A', 'B', 'C' or 'D' and the name is 1..8
chars long.

EXAMPLE

        To delete the file "DATA" on device C:

        LDX     #FILENAME
        OS      FL$DELN
        BCS     ERROR
        ; FILE C:DATA NOW DELETED
FILENAME:
        .ASCIC  "C:DATA"

ERRORS

    ER_GN_BL    194     BATTERY TOO LOW
    ER_PK_BR    200     READ PACK ERR
    ER_FL_NX    234     FILE NOT FOUND
    ER_FL_BN    236     BAD FILE NAME
    ER_PK_IV    240     UNKNOWN PACK
    ER_PK_NB    241     PACK NOT BLANK
    ER_PK_DV    243     BAD DEVICE NAME
    ER_PK_RO    244     READ ONLY PACK
    ER_PK_DE    245     WRITE PACK ERR
    ER_PK_NP    246     NO PACK



         _______
12.2.10  FL$ERAS


VECTOR NUMBER :         042

INPUT PARAMETERS :      NONE

OUTPUT VALUES :         NONE

DESCRIPTION

Erase the current record in the current file.  On EPROMs this  is  done  by
clearing the top bit of the record type.  On RAM devices the space occupied
by the record is recovered.  The current file position is unaltered - but a
new record is now at the current position.  Error "END OF FILE" is reported
if you attempt to erase after the last record in the file.

EXAMPLE

        To erase the first record in the current file

        LDD     #1              ; position to the first record
        OS      FL$RSET
        BCS     ERROR

        OS      FL$ERAS
        BCS     ERROR

ERRORS

    ER_GN_BL    194     BATTERY TOO LOW
    ER_PK_BR    200     READ PACK ERR
    ER_FL_BR    237     BAD RECORD TYPE
    ER_FL_EF    238     END OF FILE
    ER_PK_IV    240     UNKNOWN PACK
    ER_PK_NB    241     PACK NOT BLANK
    ER_PK_DV    243     BAD DEVICE NAME
    ER_PK_RO    244     READ ONLY PACK
    ER_PK_DE    245     WRITE PACK ERR
    ER_PK_NP    246     NO PACK



         _______
12.2.11  FL$FFND


VECTOR NUMBER :         043

INPUT PARAMETERS :      X = address of search string
                        A = length of search string
                        B = record type to be searched
OUTPUT VALUES :         NONE

DESCRIPTION

Searches through all the records of a particular type on  current  datapack
for a record beginning with a given search string.  The search string is at
X of length A.  B is the record type.

To find a file name or a block file name, use a search string padded out to
eight  characters  with  spaces,  otherwise searching for ABC, for example,
will also find ABCD etc.  The search string should  not  include  a  device
name  A:   B:   etc.   The  most  common  use  of FL$FFND is in finding OPL
procedure names, in which case B = $83.  To find a filename, use B  =  $81.
To  find a block file name use the appropriate block file type, between $82
and $8F inclusive.  A should be set to 8 in each case.

FL$FFND will fail unless the records are known to be at least  as  long  as
the search string.

If found, the file name which matches the  search  string  is  returned  at
RTBBL as a leading count byte string, else error "END OF FILE" is reported.

See also  sections  FILENAMESECTION  Files,  section  12.1.3  block  files,
section 12.1.3.1 OPL procs.

EXAMPLE

        To find the OPL procedure "POKEY" on device C:

        LDA     B,#2            ; set current device in use by file system
        OS      FL$SETP         ; to C:  -- 0 for A:, 1 for B: etc.
        BCS     ERROR

        LDX     #SEARCH         ; address of search string
        LDA     A,#8            ; length of search string
        LDA     B,#$83          ; block file type for OPL procedures
        OS      FL$FFND         ; FIND IT
        BCC     FOUND

        CMP     B,#ER_FL_EF
        BNE     ERROR

NOT_FOUND:
        ...
FOUND:
        ...

SEARCH:
        .ASCIC  "POKEY   "      ; 3 spaces
ERRORS

    ER_GN_BL    194     BATTERY TOO LOW
    ER_PK_BR    200     READ PACK ERR
    ER_FL_EF    238     END OF FILE (no match occurred)
    ER_PK_IV    240     UNKNOWN PACK
    ER_PK_NB    241     PACK NOT BLANK
    ER_PK_DV    243     BAD DEVICE NAME
    ER_PK_DE    245     WRITE PACK ERR
    ER_PK_NP    246     NO PACK



         _______
12.2.12  FL$FIND


VECTOR NUMBER :         044

INPUT PARAMETERS :      D = address of search string (leading count byte)
                        X = where to put the record found (leading count byte)

OUTPUT VALUES :         A = the record type of the record found

DESCRIPTION

          next
Finds the next record of the current record type on  the  current  datapack
which contains the given search string at D.  If a match occurs, the record
found is placed at X.  Both the search string  and  the  found  string  are
leading byte count.

FL$FIND leaves the current file position on the found record, if  there  is
no  match,  reports  error "END OF FILE" and leaves the current position at
the end of file.

Used in the OPL function FIND.

EXAMPLE

        To find the first occurrence of the string "SETTLE" in the current
        file :

        LDX     #1
        OS      FL$RSET         ; set to the first record
        BCS     ERROR

        LDD     #SEARCH_STRING
        LDX     #FOUND_STRING   ; where string found will be returned
        OS      FL$FIND
        BCC     FOUND

        CMP     B,#ER_FL_EF
        BNE     ERROR

NOT_FOUND:
        ...
FOUND:
        ...

SEARCH_STRING:
        .ASCIC  "SETTLE"

FOUND_STRING:
        .BLKB   256
ERRORS

    ER_GN_BL    194     BATTERY TOO LOW
    ER_PK_BR    200     READ PACK ERR
    ER_FL_EF    238     END OF FILE (no match occurred)
    ER_PK_IV    240     UNKNOWN PACK
    ER_PK_NB    241     PACK NOT BLANK
    ER_PK_DV    243     BAD DEVICE NAME
    ER_PK_DE    245     WRITE PACK ERR
    ER_PK_NP    246     NO PACK



         _______
12.2.13  FL$FREC


VECTOR NUMBER :         045

INPUT PARAMETERS :      D = record number to be found

OUTPUT VALUES :         A = length of record found
                        B = record type found
                        UTW_S0 (high byte) : X
                          = address in pack of the record found

DESCRIPTION

Returns information about the D'th record of the current record type on the
current datapack.  If the record exists, the three byte pack address of the
start of the record is returned - the first byte of UTW_S0 being  the  most
significant  byte of the address, and X being the least significant word of
the address.  If there are less than D records on the datapack, error  "END
OF FILE" is returned.

EXAMPLE

        To find the tenth record of type $90

        LDA     B,#$90
        OS      FL$RECT
        BCS     ERROR

        LDD     #10
        OS      FL$FREC
        BCC     FOUND

        CMP     B,#ER_FL_EF
        BNE     ERROR

NOT_FOUND:
        ...
FOUND:
        STA     A,LENGTH
        LDA     A,UTW_S0
        STA     A,PAK_ADDRESS
        STX     PAK_ADDRESS+1
        ...

ERRORS

    ER_GN_BL    194     BATTERY TOO LOW
    ER_PK_BR    200     READ PACK ERR
    ER_FL_EF    238     END OF FILE (no match occurred)
    ER_PK_IV    240     UNKNOWN PACK
    ER_PK_NB    241     PACK NOT BLANK
    ER_PK_DV    243     BAD DEVICE NAME
    ER_PK_DE    245     WRITE PACK ERR
    ER_PK_NP    246     NO PACK



         _______
12.2.14  FL$NEXT


VECTOR NUMBER :         046

INPUT PARAMETERS :      NONE

OUTPUT VALUES :         NONE

DESCRIPTION

Adds one to the current record number.  The next file  operation,  such  as
FL$READ  will now read the next record of the current type.  If called when
at or beyond the end of file, any subsequent calls to file system  services
such  as FL$READ will return an "END OF FILE" error.  However, FL$NEXT does
no checking for end of file in itself.

Used in the OPL command NEXT.

EXAMPLE

        OS      FL$NEXT

ERRORS

    NONE



         _______
12.2.15  FL$OPEN


VECTOR NUMBER :         047

INPUT PARAMETERS :      X = address of file name (leading count byte)

OUTPUT VALUES :         A = if file found : record type of data records

DESCRIPTION

Opens a previously existing file whose name is at X.  The filename at X  is
a leading count byte string of the form D:Name where D is the device 'A' to
'D' (optional).  The filename may be between one and  eight  characters  in
length,  excluding  the  D:,  but  including  any final '$' or '%'.  If the
device name is not specified, the current device in  FLB_CPAK  is  assumed.
Filenames  may  contain  any of the characters 'a'..'z', 'A'..'Z', '0'..'9'
and the last character may also be a '$' or '%'.  The first character  must
be  'A'  ..   'Z'  or  'a'  ..   'z'.   Upper and lower case are treated as
equivalent.

If the file does not exist the error "FILE NOT FOUND" is returned

EXAMPLE

        To open the file "A:ALSTON"

        LDX     #FILE_NAME
        OS      FL$OPEN
        BCS     ERROR

        STA     A,RECORD_TYPE
        ...

FILE_NAME:
        .ASCIC  "A:ALSTON"
ERRORS

    ER_GN_BL    194     BATTERY TOO LOW
    ER_PK_BR    200     READ PACK ERR
    ER_FL_NX    234     FILE NOT FOUND
    ER_FL_BN    236     BAD FILE NAME
    ER_PK_IV    240     UNKNOWN PACK
    ER_PK_NB    241     PACK NOT BLANK
    ER_PK_DV    243     BAD DEVICE NAME
    ER_PK_DE    245     WRITE PACK ERR
    ER_PK_NP    246     NO PACK



         _______
12.2.16  FL$PARS


VECTOR NUMBER :         048

INPUT PARAMETERS :      D = Where to put parsed output
                        X = File name to be parsed (leading count byte)
                        UTW_S0 = default device

OUTPUT VALUES :         NONE

DESCRIPTION

Checks that the file name at X is legal, and converts it to a standard form
at  D.   The input filename at X is a leading count byte string of the form
D:Name where D is the device  'A'..'D'  (optional),  and  the  filename  is
between one and eight characters long.

Filenames may contain any of the characters  'a'..'z',  'A'..'Z',  '0'..'9'
and  the last character may also be a '$' or '%'.  The first character must
be 'A' .  'Z' or 'a' ..  'z'.  They may be between one and eight characters
in length, excluding the D:, but including any final '$' or '%'.

A device code - 0 for device A:  to 3 for D:  - is placed before  the  name
in  the  output.  If no device was given in the input filename, the byte at
UTW_S0 which can be 0..3 is taken to be the device code.  The output string
is in upper case and padded with spaces to be eight characters long.

The error "BAD FILE NAME", or "BAD DEVICE NAME" will  be  returned  if  the
file name at X or the high byte of UTW_S0 is illegal.

EXAMPLE

                Input filename                  Output string

        1)      <05>"C:ABC"               <03>"ABC     " taken as C:ABC
        2)      <03>"ABC"       UTW_S0=0  <00>"ABC     " taken as A:ABC
        3)      <03>"ABC"       UTW_S0=1  <01>"ABC     " taken as B:ABC

        Note spaces at the end of each output string.

        Code for example (3) could be :

INPUT_FILENAME:
        .ASCIC  "ABC"
PARSED_OUTPUT:
        .BLKB   9

        LDX     #INPUT_FILENAME
        LDD     #PARSED_OUTPUT
        OS      FL$PARS
        BCS     BAD_NAME

ERRORS

    ER_FL_BN    236     BAD FILE NAME
    ER_PK_DV    243     BAD DEVICE NAME



         _______
12.2.17  FL$READ


VECTOR NUMBER :         049

INPUT PARAMETERS :      X = where to put data read (leading count byte)

OUTPUT VALUES :         B = record type of record

DESCRIPTION

Read the record from the current position of the current record  type  into
memory  at  X  as a leading count byte string.  Does not change the current
record number.

See also section 12.2.20 - FL$RSET, and section 12.2.14 - FL$NEXT.

EXAMPLE

BUFFER:
        .BLKB   255

        LDX     #BUFFER
        OS      FL$READ
        BCS     ERROR


ERRORS

    ER_GN_BL    194     BATTERY TOO LOW
    ER_PK_BR    200     READ PACK ERR
    ER_FL_EF    238     END OF FILE
    ER_PK_IV    240     UNKNOWN PACK
    ER_PK_NB    241     PACK NOT BLANK
    ER_PK_DV    243     BAD DEVICE NAME
    ER_PK_DE    245     WRITE PACK ERR
    ER_PK_NP    246     NO PACK



         _______
12.2.18  FL$RECT


VECTOR NUMBER :         050

INPUT PARAMETERS :      B = record type

OUTPUT VALUES :         NONE
DESCRIPTION

Sets the 'current record type' to the value in B.  This  will  be  used  by
other file system services.

B should be between $80 and $FE inclusive.

EXAMPLE

        To select records of type $90 - that is the file MAIN :

        LDA     B,#$90
        OS      FL$RECT
        BCS     ERROR

        ...

ERRORS

        May be returned in future OS versions



         _______
12.2.19  FL$RENM


VECTOR NUMBER :         051

INPUT PARAMETERS :      X = Old file name (leading count byte )
                        D = New file name (leading count byte )

OUTPUT VALUES :         NONE

DESCRIPTION

Changes the name of a file.  Files  can  only  be  renamed  onto  the  same
device.   The  old  name  is deleted and then the new name is saved.  On an
EPROM device, this means that only  eleven  more  bytes  used  by  the  new
filename are saved.

Both filenames are leading count byte  strings.   If  the  device  name  is
missing  from  the  old  file  name (at X), the device is assumed to be the
currently selected device (see section 12.2.21 FL$SETP).  The  device  name
may be omitted from the new file name (at D).

Note that the new file name may not be a device name only, as  in  FL$COPY.
If  the  two device names differ, or either file name is illegal error "BAD
FILE NAME" is returned.

EXAMPLES

        To rename the file A:HAWES to GAYLE  :

COPY_FROM:
        .ASCIC  "A:HAWES"
COPY_TO:
        .ASCIC  "A:GAYLE"       ; or .ASCIC     "GAYLE"

        LDX     #COPY_FROM
        LDD     #COPY_TO
        OS      FL$RENM
        BCS     ERROR

        ...

ERRORS

    ER_GN_BL    194     BATTERY TOO LOW
    ER_PK_BR    200     READ PACK ERR
    ER_FL_NX    234     FILE NOT FOUND
    ER_FL_EX    235     FILE EXISTS
    ER_FL_BN    236     BAD FILE NAME
    ER_FL_PF    239     PACK FULL
    ER_PK_IV    240     UNKNOWN PACK
    ER_PK_NB    241     PACK NOT BLANK
    ER_PK_DV    243     BAD DEVICE NAME
    ER_PK_RO    244     READ ONLY PACK
    ER_PK_DE    245     WRITE PACK ERR
    ER_PK_NP    246     NO PACK



         _______
12.2.20  FL$RSET


VECTOR NUMBER :         052

INPUT PARAMETERS :      D = record number

OUTPUT VALUES :         NONE

DESCRIPTION

Sets the 'current record number' to the value in D.  This will be  used  by
other file system services.

The first record is number 1.  D should not be set to zero.  If  there  are
less  than  D  records on the datapack, any subsequent calls to file system
services such as FL$READ will return an  "END  OF  FILE"  error.   However,
FL$RSET itself does no checking for end of file.

EXAMPLE

        LDD     #RECORD_NUMBER
        OS      FL$RSET
        BCS     ERROR
        ...
ERRORS

        May be returned in future OS versions



         _______
12.2.21  FL$SETP


VECTOR NUMBER :         053

INPUT PARAMETERS :      B = number of datapack to select (MUST BE 0 to 3)

OUTPUT VALUES :         NONE

DESCRIPTION

Selects the datapack given in B.  This datapack will then be used by  other
file system services.  B should be set to zero for A:, 1 for B:  etc.  This
value is not checked by FL$SETP.

NOTE :  Users calling FL$SETP must always ensure that B is in the  range  0
to 3 to ensure compatibility with all operating system versions.

EXAMPLE

        LDA     B,PACK_TO_SELECT
        CMP     B,#3
        BHI     ERROR                   ; Error if B > 3

        OS      FL$SETP
        BCS     ERROR
        ...

ERRORS

        May be returned in future OS versions



         _______
12.2.22  FL$SIZE


VECTOR NUMBER :         054

INPUT PARAMETERS :      NONE

OUTPUT VALUES :         UTW_S1 (byte) : D
                          = number of bytes free on datapack (3 byte value)
                        X = number of records of current record type
                        UTW_S1+1 (byte) : UTW_S0 (word)
                          = address of first free byte (3-byte address)
DESCRIPTION

Returns statistics about the current datapack, and current file or  current
record  type.   Counts the number of records of the current type, finds the
end of the current datapack and returns the amount of free space.

Used in various OPL commands including SPACE, LAST, COUNT.

See also section 12.2.21 FL$RSET, section 12.2.15 FL$OPEN,  section
12.2.21 FL$SETP, section 12.2.18 FL$RECT.

EXAMPLE
        Get statistics of device B: :

        LDA     B,#1            ; A=0, B=1 etc.
        OS      FL$SETP         ; select device to be used by file system
        BCS     ERROR

        OS      FL$SIZE         ; get device info
        BCS     ERROR
                                ; store 3-byte number of bytes free
        STD     BYTES_FREE+1    ; low word
        LDA     A,UTW_S1        ; high byte
        STA     A,BYTES_FREE

        LDA     A,UTW_S1+1      ; store 3 byte address
        STA     A,FREE_ADDRESS
        LDD     UTW_S0
        STD     FREE_ADDRESS+1

        To count the number of records in A:MAIN :

FILENAME:
        .ASCIC  "A:MAIN"

        LDX     #FILE_NAME
        OS      FL$OPEN         ; open "A:MAIN"
        BCS     ERROR

        OS      FL$SIZE         ; get file info
        BCS     ERROR

        STX     N_RECORDS       ; store number of records in file

ERRORS

    ER_GN_BL    194     BATTERY TOO LOW
    ER_PK_BR    200     READ PACK ERR
    ER_PK_IV    240     UNKNOWN PACK
    ER_PK_NB    241     PACK NOT BLANK
    ER_PK_DV    243     BAD DEVICE NAME
    ER_PK_RO    244     READ ONLY PACK
    ER_PK_DE    245     WRITE PACK ERR
    ER_PK_NP    246     NO PACK



         _______
12.2.23  FL$WRIT


VECTOR NUMBER :         055

INPUT PARAMETERS :      X = address of string to be written
                                (leading count byte)

OUTPUT VALUES :         NONE

DESCRIPTION

Appends a new record of the current record  type  to  the  records  on  the
current  device.  The data to be saved in the new record is a leading count
byte string at X, containing between one and 254  characters.   Records  of
length  255  are truncated to 254 characters.  The current record number is
set to the number of records of the current type.   A  subsequent  call  to
FL$READ will return the record just written.

FL$WRIT checks that there is sufficient space free first.  Usually if there
is a "WRITE PACK ERROR" on an EPROM, the record will have been deleted.

Used in the OPL command APPEND.

EXAMPLE

        To write the record "ILKLEY" to the file C:WYORKS

RECORD:
        .ASCIC  "ILKLEY"
FILE_NAME:
        .ASCIC  "C:WYORKS"

        LDX     #FILE_NAME
        OS      FL$OPEN
        BCS     ERROR

        LDX     #RECORD
        TST     0,X
        BEQ     1$
        OS      FL$WRIT
        BCS     ERROR
1$:     ...


ERRORS

    ER_GN_BL    194     BATTERY TOO LOW
    ER_PK_BR    200     READ PACK ERR
    ER_FL_CY    232     PAK NOT COPYABLE
    ER_FL_DF    233     DIRECTORY FULL
    ER_FL_NX    234     FILE NOT FOUND
    ER_FL_BN    236     BAD FILE NAME
    ER_FL_EF    238     END OF FILE
    ER_FL_PF    239     PACK FULL
    ER_PK_IV    240     UNKNOWN PACK
    ER_PK_NB    241     PACK NOT BLANK
    ER_PK_CH    242     PAK CHANGED
    ER_PK_DV    243     BAD DEVICE NAME
    ER_PK_RO    244     READ ONLY PACK
    ER_PK_DE    245     WRITE PACK ERR
    ER_PK_NP    246     NO PACK



         _______
12.2.24  TL$CPYX


VECTOR NUMBER :         102

INPUT PARAMETERS :      NONE

OUTPUT VALUES :         NONE

DESCRIPTION

Performs the top level COPY, complete with "FROM" and "TO" prompts.

EXAMPLE

        OS      TL$CPYX

ERRORS

        NONE - errors are reported directly on the screen