The PSION Organiser II Homepage
 
Home
Technical Reference
Introduction
System
Versions
Operating
System
Memory Usage
Filing System
System Timing
System Board
Power Supply Board
Display
Keyboard
Interface Slots
Packs
General
Flashpacks
Low Level
Access
External
Interfacing
Comms Link
Psion Link
Protocol
Utility System
Services
Built-in
Applications
LZ Passwords
Programming
Language
General
Q-Code
Table
Interpreter
System Services
 

Technical Reference Manual

FILING SYSTEM

GENERAL

RECORDS

DATA FILES

BLOCK FILES

 

SUMMARY OF RECORD STRUCTURE

ERROR HANDLING

SUMMARY OF RECORD TYPES

FILE SYSTEM VARIABLES

ORGANISER I COMPATIBILITY

SYSTEM SERVICES

GENERAL

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 low level pack access.

In the following sections "datapack" means (E)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.

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.

SHORT RECORDS

Short records are of the format:

Byte  0 1 2...
  length record type 1 to 254 data bytes...
Range  1 to 254 $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.

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.

Long records have the following format:

Byte  0 1 2 3 4...
  $02 $80 length word  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 below). The $80 is a special record type which identifies a long record.

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

DATA FILES

There are two kinds of files; data 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 file 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. The name and data records of a file can be interspersed by any number of other records and files. Also the name need not come before the first record of a file.

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-9 10
  $09 $81 file name, space filled record type

 

Example: the file MAIN (all records of type $90 will be in MAIN)

$09  $81  $4D  $41  $49  $4E  $20  $20  $20  $20  $90

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.

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.

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-9 10 11 12 13 - 14 15...
  $09 TYPE file name $00 $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.

OPL PROCEDURES

OPL procedures are saved as block files of type $83. The data block has the following format:

Byte  0 1 2... word        
  length of
Q-code
Q-code (if any) length of
source
1st source line $00 2nd source line $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 or was received from PC. 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.

CM/XP DIARY FILES

These are block files of type $82. Its data block consists of a list of entries which is terminated by a zero byte. Each entry has the form:

Byte  0 1 2 3 4 5 6 7...
  length of the text year month day hour minute alarm text...
Range    0-99 0-11 0-30 0-23 0-59 0-60  

 

The alarm flag is 0 for no alarm, otherwise one more than the number of minutes early the alarm has to go off.

LZ DIARY FILES

On LZ machines the diary is no longer saved as a block file of type $82, but instead as an ordinary data file. Each entry is saved as a separate record.

For example

 
Mon 8 May 1989 Wk19
6:00a
5:15p ABCDEF
5:45p 

would be:

         1989050817150216
         ABCDEF 

The first field specifies the date of the entry (1989, 05, 08, for 8th May 1989), the time (17 15, for 5:15pm), the duration (02) and the alarm byte (16, for 15 minutes before - again, 00 would mean "no alarm"). The second field is the text of the entry. The order of things in the first field, and the use of zeroes where necessary to keep things the same length (e.g. "02" for a duration of 2) make the file easy to sort in OPL, or otherwise.

Note, though, that the "Restore" option in the diary will restore entries in any order from a file. The "Xrestore" option can be used to load a CM/XP diary from a pack, in which case each entry is given a duration of 2 (=30 minutes).

COMMSLINK SETUP FILES

These are block files of type $84. Its data block consists of 27 bytes exactly, containing the parameters:

Byte  0 1 2 3 4 5 6
  baud parity data bits stop bits handshake minute echo
Range  0-9 0-4 0-1 0-1 0-7 0-2 0-1

 

Byte  7 8 9-11 12-15 16-19 20-23 24-27
  width timeout REOL REOF RTRN TEOL TTRN
Range  0-254 0-255 string string string string string

 

All string have a maximum length of 2 and a leading length byte.

LZ NOTEPAD FILES

These are block files of type $87. Its data block consists of two parts, the header, and the data, both preceded by a length word.

Header:
Byte  0 2 3 4...
  header length flags $00 title+":"

 

If a password was used:

Byte  0 2 3 4-13 14...
  header length flags $09 password code title+":"


Flags: The bits are set as for the LG$EDIT service, so Bit 7 is set if the notepad is numbered, bit 3 must be set, bits 1 and 2 are clear.

Data:
Byte  0 2 3...    
  data length $00 1st line $00 2nd line...

OTHER BLOCK FILES

Other block file types:

$85 Spreadsheet files
$86 Pager setup files
$8E General use

PSION states that all other types are reserved. These might be used by PSION or third-party software.

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.

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

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 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".

SUMMARY OF RECORD TYPES

Record type

00 invalid long record - ignored
01 deleted data file name
02 - 0F deleted block file name, following long record is regarded as deleted
10 - 7E deleted short records
7F deleted $FF (should not occur)
80 long record - length word follows
81 data file name
82 - 8F block file name, followed by a long record
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
      03 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

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.
$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.
Set by many routines including FL$RSET, FL$NEXT.

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.

SYSTEM SERVICES

This section briefly describes the system services used by OPL to handle files, records and block files. The names of these services are prefixed by FL$. A detailed explanation is given on the system services page.

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.

FL$BACK

Sets the current file position back to the previous record.

FL$BCAT

When called repeatedly, returns each filename of a given record type on a device.

FL$BDEL

Delete a named block file. 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.

FL$BOPN

Finds a named block file of the given block file type. It returns 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.

FL$BSAV

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. 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.

FL$CATL

When called repeatedly, returns each the name of each file on a device.

Calling FL$CATL is equivalent to calling FL$BCAT for file type $81.

FL$COPY

Copies files or block files from one device to another, as in the top level COPY or PROG COPY menu options. 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.

FL$CRET

Creates a file. If the file already exists then FL$CRET returns error "FILE EXISTS", otherwise the file is created and the record type to be used by the data records in the file is returned

FL$DELN

Delete a named file.

FL$ERAS

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.

FL$FFND

Searches through all the records of a particular type on current datapack for a record beginning with a given search string. Also used to find file names.

FL$FIND

Finds the next record of the current record type on the current datapack which contains the given search string. If a match occurs, 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.

FL$FREC

Returns information about the n'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.

FL$NEXT

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.

FL$OPEN

Opens a previously existing file.

FL$PARS

Checks that a file name is legal, and converts it to a standard form (D:Name where D is the device 'A'..'D', and the filename is between one and eight characters long.

FL$READ

Read the record from the current position of the current record type into not memory.

FL$RECT

Sets the 'current record type' to the given value.

FL$RENM

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.

FL$RSET

Sets the 'current record number' to a given value

FL$SETP

Selects a datapack. This datapack will then be used by other file system services.

FL$SIZE

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.

FL$WRIT

Appends a new record of the current record type to the records on the current device. Records of length 255 are truncated to 254 characters. The current record number is set to the number of records of the current type.

FL$WRIT checks that there is sufficient space free first.

TL$CPYX

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

FL$WPAR (LZ only)

Validates wild card filenames. Returns length of body of filename and the file type for the extension.

FL$WCAT (LZ only)

Provides a wild card catalogue of the file names on a device. Works in the same way as FL$BCAT and FL$CATL except that it returns only those files which are consistent with the match string.

FL$NCAT (LZ only)

Same as FL$WCAT but gets the n'th match.

FL$WCPY (LZ only)

Wild file copy, works in a similar way to FL$COPY.

FL$WDEL (LZ only)

Wild file delete, works in a similar way to FL$DELN and FL$BDEL except that wild card characters and file extensions are allowed.

FL$WFND (LZ only)

Wild FIND, works exactly like FL$FIND but the wild card characters *, +, can be used.

FL$FDEL (LZ only)

Fast delete of a given number of records starting from a given record. If the number is -1 this deletes to end of file.

FL$GETX (LZ only)

Get the file extension for a given numeric file type ($81 to $8F)

FL$VALX (LZ only)

Returns the numeric file type for an extension.

 

See also chapter Packs for PK$READ and PK$SAVE.

 
first previous   next top