This text will explain the various file formats the Psion Organiser II uses.
1. Packs 1.1 Pack Header 1.2 Pack header flag byte 1.3 Trap Rampak 1.4 Bootable packs 1.5 Device Identification Number 1.6 Flash datapaks 1.7 Relocatable code block 1.8 Device Code 1.9 Device Vectors 2. General File Formats 2.1 Short Records 2.2 Long Records 2.3 Record types 2.4 Data File 2.5 Block File 2.6 Headerless blocks 2.7 Deleted records and files 2.8 Pack error correction 3. Block File Formats 3.1 CM/XP Diary files 3.2 Procedure files 3.3 Comms link setup files 3.4 Pocket Spreadsheet files 3.5 Pager setup files 3.6 LZ notepad file 4. PC files 4.1 ODB files 4.2 OPL files 4.3 OBx files 4.4 LNO file for the Organiser Developer kit 4.5 OPK file for the Organiser Developer kit 4.6 IPK file for the Organiser Developer kit 4.7 BIN file for the Organiser Developer kit 4.8 BIN file for Comms boot 4.9 ORGBAK.BUF backup file
First, lets examine packs, and how info is stored on them. It is important to realise that a clean datapack has all its bits set, and the organiser can only clear bits to write its data. This has many consequences for the way that data is organised.
Every pack starts with a 10 byte header, containing the info about the pack itself. This header is written by the organiser when it 'Sizes' a pack.
Normal packs have the following header:
Byte: | Meaning: |
---|---|
0 | Flags (see below) |
1 | Size in 8k blocks (so 4 means 32k, 8 means 64k etc.) |
2 | Year, when pack was sized (0-255) |
3 | Month, when pack was sized (0-11) |
4 | Day, when pack was sized (0-30) |
5 | Hour, when pack was sized (0-23) |
6/7 | Frame counter, when pack was sized (see system variable $20CB) |
8/9 | Word 'checksum' of header. This word is the sum of the words at pack address 0, 2, 4, and 6. The organiser never checks this sum, because a pack's copy/write protection is sometimes set after the checksum has already been computed and written. |
Once a pack has been detected or booted by the Organiser, the pack header is copied into memory. The header for slot B: is located at address $20E1 (8417) and the slot C: header is directly after that at $20EB (8427). You can use this for example to find out the size of a pack by evaluating 8*PEEKB(8418) or 8*PEEKB(8428) in the calculator for the pack in slot B: or C: respectively.
The bits of the flag byte all have a different meaning:
Bit: | Meaning: |
---|---|
0 | Clear for a valid pack. |
1 | EPROM: Set for a datapack (or flashpak), clear for a Rampak. |
2 | PGCPK: Set for page counted packs (most packs 32K and larger), clear for linear packs (all 8K and 16K packs, some 32K packs). |
3 | RDWRT: Normally set, clear for write protection. Always clear for flashpaks. |
4 | NOBOOT: Normally set, clear for a bootable pack |
5 | COPYPK: Normally set, clear for copy protection. |
6 | NYIMPL: Normally set, clear for flashpaks, and for trap Rampaks. |
7 | MKIPAK: Normally clear. Set on an organiser 1 pack. |
Note that it is possible to clear the RDWRT and/or COPYPK bits to set the pack protection, but it is not possible to remove it again (except by copying to a new pack).
Here are some common values of the first two bytes of the header:
Flag & size: | Meaning: |
---|---|
$7A 01 | 8K datapak. |
$7A 02 | 16K datapak. |
$7E 04 | 32K datapak (paged). |
$7E 08 | 64K datapak. |
$7E 10 | 128K datapak. |
$52 02 | 16K datapak. Copy and write protected. |
$56 04 | 32K datapak (paged). Copy and write protected. |
$56 08 | 64K datapak. Copy and write protected. |
$42 02 | 16K datapak. Bootable, copy and write protected. |
$46 04 | 32K datapak (paged). Bootable, copy and write protected. |
$46 08 | 64K datapak. Bootable, copy and write protected. |
$7C 04 | 32K rampak. |
$26 10 | 128K flashpak. |
$26 20 | 256K flashpak. |
This is a 32k Rampak which has bit 6 of the flag byte cleared, and hence a flag byte of $3C. When a system crash occurs on a Psion organiser, a Trap interrupt is generated which jumps to a routine in the ROM. This routine prints 'TRAP' on the screen, possibly some extra information, and switches off. In ROM versions 3.6 or above, it checks whether a trap Rampak is in any of the slots and if found it will copy the Ram contents to the corresponding addresses on the pack. Of course the areas $00-$3F and $100-$400 are not copied because they are processor ports and semi-custom chip controls. Therefore those pack addresses are left untouched (so the pack header stays intact too). Note that the LZ64's extra Ram banks are not copied.
A bootable pack is a pack that contains a machine code program that is loaded and run when 'the devices are booted', i.e. when ON is pressed in the main menu. The Comms link for example acts like a bootable pack, and its program inserts/deletes a menu item, and handles the new OPL commands for the link.
Bootable packs have the following header:
Byte: | Meaning: |
---|---|
0 | Flags, as above. |
1 | Size, as above. |
2 | Code byte, 0 for a software device (e.g. normal pack) or 1 for a hardware device (e.g. Comms link). Descriptive only. |
3 | Identification number. Should be unique amongst the devices used on the organiser at the same time. See below. |
4 | Version number. A binary coded decimal number, i.e. the number $25 means version 2.5 etc. Descriptive only. |
5 | Priority. Devices are booted highest priority first. Generally the same as the Identification number. |
6/7 | Code address. Pack address of the relocatable code block containing the device code to run. Usually $0019, where the block immediately follows the pack header and MAIN file header. |
8/9 | Word 'checksum', as above. |
Officially, Identification numbers in the range $80-$C0 are reserved for Psion's hardware devices, and $00-40 for their software devices. However, the convention of using that same number for the boot priority sometimes causes conflict with those ranges. Here is a table of the Identification/Priority numbers that I have found so far.
Id Byte: | Device |
---|---|
02 | SDRP software pack |
09 | Formulator |
0A | Concise Oxford Spelling Checker, OWI interface |
0B | Thesaurus and Spelling Checker |
20 | FlightMaster software pack 1 |
40 | Microtima SigSet software pack |
41 | Dial-Link software pack, AutoScribe Plus |
50 | HB Games Pack |
80 | KDG Mobrey MSP100 software pack |
90 | Bootable packs using Boot.BIN from the Organiser Developer kit. |
BC | Extech Comms Modem |
BE | Magnetic Card Reader |
BF | Barcode Reader, Digitron SF10 software pack |
C0 | RS232 Link, Comms Link, Paralink (later versions) |
C1 | CNF41 Hart Interface, Hand-held Operator's Terminal |
C2 | Psion Printer |
C3 | Sony Lisa-1 EVR packs |
C4 | Extech Comms Printer II |
C6 | Pager |
C8 | Pocket Spreadsheet |
CB | Sony PRM-1 pack |
CD | Dynapen |
CF | Sony Lisa-1 pixel repair pack |
F7 | Flashpak |
F8 | Flashpak |
FF | Paralink (earlier versions) |
A flash datapak (or flashpak) is a datapak that uses an EEPROM instead of an EPROM. This allows it to be electronically formatted. As the Organiser's operating system has no way of formatting or writing to these chips, the flashpak normally contains a driver to allow it to do so. The pack is therefore bootable.
It always has its write-protect bit cleared so that no attempt will be made to write to it as if it were a normal datapak. The flashpak driver instead uses the most significant bit of the 'checksum' word to signify the write protection (normally set, but cleared for write-protection).
Flashpaks have the following bootable header:
Byte: | Meaning: |
---|---|
0 | Flag byte has value $26, or $06 for copy-protected packs. |
1 | Size. Usually $10 (128K) or $20 (256K). |
2 | Code byte is $01 to indicate a hardware device. |
3 | Identification number for flashpaks is $F8. |
4 | Version number. The latest driver is version 1.9, in which case the byte is $19. |
5 | Priority is $F8 for flashpaks. |
6/7 | Code address for the driver, usually $0019. |
8/9 | Checksum word, except that the high bit indicates the real write-protection status. |
Here is a short description of the Psion relocatable object format, as used for device code on bootable packs:
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 (with 0 meaning the first byte of the code block). When the code is loaded in memory (by using the DV$LOAD service in the ROM; SWI $1A), the new address of the code block is added at all the places indicated by the fixup list, so that all the absolute references are correct.
Device code is a program that is run when a pack (or top slot device) is booted. They are booted either when ON/Clear is pressed in the main menu, or when the system service DV$BOOT (SWI $17) is called. See bootable packs. Device code is in a relocatable code format, and its code block has the following format:
Byte: | Meaning: |
---|---|
0/1 | Contains 0000. When loaded into memory, the program length is stored here, allowing the organiser to skip through consecutively loaded device code blocks. |
2 | Contains 00. When loaded into memory, the program pack is stored here, which is 1, 2, or 3 for packs B:, C:, or D: (top slot). |
3 | Device identification number. Same as in the pack header. |
4 | Device Version number. Same as in the pack header. |
5 | Number of vectors. Device code consists of several smaller programs called vectors. Generally, device code must have at least 3 special vectors, which are detailed below. |
6/7+ | List of addresses of the vectors. These addresses are normally fixed up addresses pointing to routines in this code block. |
??+ | This is followed by the device vector routines. |
Device code is generally stored on a pack in a headerless block.
Device code consists of several smaller programs called vectors. By using the system service DV$VECT (SWI $1B) any vector on any booted device can be called (register A should contain the device number, B the vector number).
Generally, a device must have at least 3 special vectors, which are detailed below.
Vector: | Purpose: |
---|---|
0 | Install vector. Performs device initialisation, for example inserts a menu item. If the carry flag is set on return, the device code will be rejected, i.e. not loaded. |
1 | Remove vector. Performs removal, for example deletes a menu item. (On return, carry flag is ignored.) After running this vector, the device code could be safely deleted from memory. |
2 | Language vector. Is called by the organiser to see if the device is willing to accept a particular procedure name as an external command. Peripherals like the Comms link use this vector for all the extra commands. On entry, X points to the string (with leading byte count) and on exit it should have the device identification number in register A and the vector number of the vector that performs the task in register B, ready for a DV$VECT call. Carry should be clear. If the device will not handle that command name, carry should be set. On a device which does not implement any extra commands, this vector generally reads SEC, RTS. |
Pressing ON/Clear in the main menu (or using service DV$BOOT, SWI $17) will first call the remove vector of all devices (using service DV$CLER, SWI $18) and remove all device code from memory. Then all device code is loaded, calling the install vector in the process.
If a procedure call is encountered in a program or in the calculator, (the service DV$LKUP, SWI $19, is called so that) the procedure name is passed to the language vector of all devices in turn. If the carry flag is set, then none of the devices accept it and the packs are searched for a normal OPL procedure of that name. If a device returns with a clear carry flag, then the appropriate vector is immediately called (registers A and B are already prepared for calling service DV$VECT, SWI $1B).
There now follows a description of the various file types that can be stored on a pack. Two types of record are used for storing files.
A short record is used for storing file names, and for records in data files. It has the following format:
Byte: | Meaning: |
---|---|
0 | Length byte. Contains the length of the data in the record, and must be in the range $01-FE (1-254). |
1 | Record type. Explained below. |
2+ | Data, of the given length. |
A long record is used for a large block of data, for example the data of a procedure, and has the following format:
Byte: | Meaning: |
---|---|
0 | Contains $02, for error correcting purposes explained later. |
1 | Contains $80, the record type of a long record. |
2/3 | Length word. Contains the length of the data in the record. |
4+ | Data, of the given length. |
The record type bytes that the organiser uses are as follows:
Type: | Meaning: |
---|---|
80 | A long record. |
81 | A data file. |
82 | A CM/XP diary file. |
83 | A procedure file. |
84 | A Comms link setup file. |
85 | A pocket spreadsheet file. |
86 | A pager setup file. |
87 | An LZ notepad file. |
88-8F | Other types of file not officially used by Psion. |
90-FE | Used to identify records of data files. |
FF | Used for error correcting purposes. |
Note that when a record or file is deleted, the high bit of the record type byte is cleared, so record types 01-7E signify deleted files/records.
A data file, for example the MAIN file, consists of a header, and its separate data records. The header is a short record of record type $81 and length 9, in which the data consists of the file name (padded to 8 characters with spaces) followed by its file identifier byte (range $90-FE). In other words:
Byte: | Meaning: |
---|---|
0 | Contains 9, length byte of the header. |
1 | Contains $81, data file type. |
2-9 | File name, padded with spaces if necessary. |
10 | File identifier byte (range $90-FE), see below. |
Every data file on a pack must have a unique File Identifier byte. The data records of a data file are short records, which use the file identifier byte as their record type, i.e.
0 | Length byte of the record. |
1 | Contains file identifier. |
2+ | Record data, where the fields of the record are separated by ASCII character 9. |
The header and data records of a file can be interspersed by any number of other records and files. When a data file is deleted, all the records and its header are individually marked as deleted, so that the file identifier byte can be reused when a new file is created on a pack.
Also the header need not come before the first record of a file, because when a file is renamed, the header is deleted and rewritten (with the new name but the same file identifier) at the end of the pack. The header of the MAIN file is written on the pack during 'Sizing', so it has file identifier byte $90. The MAIN file should not be renamed or deleted.
Apart from data files explained above, the only other files the organiser uses are block files. These are files in which the data is stored as one block in a long record. A block file consists of a file name header, followed immediately by a long record:
Byte: | Meaning: |
---|---|
0 | Contains 9, length byte of the header. |
1 | The block file type, e.g. $83 for a procedure. |
2-9 | File name, padded with spaces if necessary. |
10 | Unused byte. Generally 00. |
followed by:
0 | Contains $02, for error correcting purposes explained later. |
1 | Contains $80, the record type of a long record. |
2/3 | Length word. Contains the length of the data in the block. |
4+ | Data, of the given length. |
Sometimes a long record is used without preceding it with a header. The most common use for this is for storing device code. Generally it is the first new item on the pack, following directly after the pack header and the MAIN file header. This places the device code at pack address $0019 ($0A bytes in the pack header, $0B bytes in the MAIN header, 4 bytes in the long record header).
Note that when a record or file is deleted, the high bit of the type byte is cleared, so file types 01-7E signify deleted files/records.
When a block file is deleted, the file header is marked deleted, but the long record is not changed (see error correction for the meaning of a 00 type byte). When a data file is deleted, all its data records are marked as deleted as well as its file header, allowing the file identifier to be reused.
The data file header usually precedes the data records of that file, but this is not true if the file has been renamed. When a data file is renamed, the old header is deleted, and a new one is written at the end of the pack, using the same file identifier byte.
The Psion uses a simple but fairly effective system to recover from errors when writing to a pack. When a pack is sized, the organiser checks that all bytes are set to FF (or else a pack not blank error occurs). If the pack header cannot be written, the pack is unusable.
If an error occurs when writing the first byte of a short or long record, then the second byte is left untouched, and the organiser tries again at the next address. Therefore a 'record type' of FF means that the two bytes should be ignored.
This method fails if the incorrect length byte has become 0 or $FF. The byte 0 is taken by the organiser to mean that the pack has been removed. The byte $FF on the other hand signifies (especially when followed by another $FF) that the end of the data is reached, and that new data can be written there.
If an error occurs when writing the length word of a long record, then the type byte is marked deleted, so that it becomes in effect a deleted short record with length 2. The file header is then also deleted, and the organiser tries again at the next address.
There now follows a description of the content format of various types of block files. Unfortunately not all are complete, due to being difficult to reverse-engineer.
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: | Meaning: |
---|---|
0 | Length of the text of this entry. Must be at least 1 to distinguish it from the data block's terminating zero. |
1 | Year (0-99) |
2 | Month (0-11) |
3 | Day (0-30) |
4 | Hour (0-23) |
5 | Minute (0-59) |
6 | Alarm flag (0-60): 0 for no alarm, otherwise one more than the number of minutes early the alarm has to go off. |
7+ | Text of length given above. |
These are block files of type $83. The data block consists of two parts, both preceded by a length word. The first part contains the object code of the procedure (i.e. the translated code), the second the source code (i.e. the typed OPL).
The object code data is too complicated to explain here, for full details see Translated Procedures and QCodes. A procedure which has not been translated will have an object code block of length zero.
The source code data consists of text, with each line terminating in a zero-byte. The first line must contain a title ending in a colon. In an object-only procedure, the source code block is of length zero.
Procedures translated by the emulator in the Organiser Developer are block files of type FE. For details of these files, again see Translated Procedures and QCodes.
These are block files of type $84, containing the saved settings for the Comms Link. Its data block consists of 27 bytes exactly, containing the parameters:
Byte index: | Meaning: |
---|---|
0 | Baud rate (0-9 for 50, 75, 110, 150, 300, 600, 1200, 2400, 4800, 9600 baud respectively) |
1 | Parity (0-4 for NONE, ODD, EVEN, MARK, SPACE respectively) |
2 | Data bits (0-1 for 7 or 8 bits) |
3 | Stop bits (0-1 for 1 or 2 bits) |
4 | Handshake (0-7 for NONE, XON, RTS, XON+RTS, DTR, XON+DTR, RTS+DTR, ALL respectively) |
5 | Protocol (0-2 for NONE, XMODEM, PSION respectively) |
6 | Echo (0-1 for LOCAL, HOST respectively) |
7 | Width (0-250, 0 for none) |
8 | Timeout (0-255 in seconds, 0 for none) |
9-$0B | REOL, string of length at most 2 with leading length byte. Any unused bytes after the string are ignored so may have any value. |
0C-0E | REOF, as above. |
0F-11 | RTRN, as above. |
12-14 | TEOL, as above. |
15-17 | TEOF, as above. |
18-1A | TTRN, as above. |
These are block files of type $85. This is a complicated file type, and I have not yet been able to work out the exact specifications.
These are block files of type $86 containing the saved settings for the Pager. Its data block consists of 119 bytes exactly. There are many bytes that seem to have fixed values and which are not actually used by the Wordcall Pager I have, but it may be that other types of Pager make use of those bytes to store further settings.
Byte index: | Value range | Default Value | Meaning: |
---|---|---|---|
00 | 00 | ||
01 | 00-02 | 02 | Status: 00=Off, 01=On, 02=Auto |
02 | 01 | ||
03 | 00-01 | 01 | Sounder: 00=Off, 01=On |
04 | 02 | ||
05 | 00-03 | 03 | Volume: 00=Quietest, 03=Loudest |
06 | 05 | ||
07 | 3E | ||
08 | 04 | ||
09 | 00-17 | 08 | Hour ON: Hour of the day it switches on in Auto mode |
0A | 04 | ||
0B | 00-17 | 12 | Hour OFF: Hour of the day it switches off in Auto mode |
0C | 03 | ||
0D | 00-FF | 04 | Repeat 1: Initial delay in minutes between unacknowledged message warning beeps. |
0E | 03 | ||
0F | 00-FF | 3c | Period 1: Number of minutes to sound warnings before moving on to Repeat 2. |
10 | 03 | ||
11 | 00-FF | 3c | Repeat 2: Delay in minutes between unacknowledged message warning beeps. |
12 | 01 | ||
13 | 00-01 | 01 | Duplicates: Duplicate filtering, 00=OFF, 01=ON. |
14 | 01 | ||
15 | 00-01 | 01 | Warning: Sound warning beeps when switching on or off, 00=OFF, 01=ON. |
16 | 06 | ||
17 | 00-27 | 07 | Size: The size of message storage is (value+1)*500 bytes. |
18 | 07 | ||
19 | 03 | ||
1A | 08 | ||
1B | 00 | ||
1C | 09 | ||
1D | 00 | ||
1E | 09 | ||
1F | 09 | ||
20 | 09 | ||
21 | 12 | ||
22 | 00 | ||
23 | 0A | Length of storage space reserved for next parameter, including this byte. Must not be changed. | |
24-2C | lbc string | "sMTWTFs" | Days: A string of length 7 (starting with its length byte which is of course 07), one letter for each day of the week. Capital letters are days when Auto is in effect, on lower case days it remains off. Note that the unused byte of storage space after the string is ignored and normally 00. |
2D | 0C | Length of storage space reserved for next parameter, including this byte. Must not be changed. | |
2E-38 | lbc string | "A:MAIN" | Log: Filename (including device letter) of data file. |
39 | 04 | Length of storage space reserved for next parameter, including this byte. Must not be changed. | |
3A-3C | lbc string | "U:" | Semi-Urgt: Two characters that mark a message as urgent in semi-urgent mode. |
3D | 09 | Length of storage space reserved for next parameter, including this byte. Must not be changed. | |
3E-45 | lbc string | "Tone 1" | Text 1: Text to display when alert 1 sounds. |
46 | 09 | Length of storage space reserved for next parameter, including this byte. Must not be changed. | |
47-4E | lbc string | "Tone 2" | Text 2: Text to display when alert 2 sounds. |
4F | 09 | Length of storage space reserved for next parameter, including this byte. Must not be changed. | |
50-57 | lbc string | "Tone 3" | Text 3: Text to display when alert 3 sounds. |
58 | 00 | ||
59 | 00-02 | 01 | Alert 1: Status of the tone-only alert 1, 0=Off, 1=On, 2=Urgent. |
5A | 00-02 | 01 | Alert 2: Status of the tone-only alert 2, 0=Off, 1=On, 2=Urgent. |
5B | 00-02 | 01 | Alert 3: Status of the tone-only alert 3, 0=Off, 1=On, 2=Urgent. |
5C | 00-03 | 01 | Alert 4: Status of the text alert 4, 0=Off, 1=On, 2=Urgent, 3=Semi-Urgent. |
5D | 03 | ||
5E | 65 | ||
5F | 9A | ||
60 | 01 | ||
61-73 | 00 | ||
74 | 59 | ||
75 | 00 | ||
76 | 15 | ||
77 | 00 |
It is clear that in the first part of the file, each numerical setting is preceded by a byte that indicates the range of values the setting has, for instance all settings that only allow On/Off (00/01) are preceded by 01. The bytes at 07-08 and 18-21 therefore probably represent settings that other Pagers could use, such as Pagers that can also send messages. The byte at 07 containing the '>' character could be some kind of prompt.
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. The header has the form:
Byte: | Meaning: |
---|---|
0 | Flag byte. The bits are set as for the LG$EDIT service (SWI $AB), so Bit 7 is set if the notepad is numbered, bit 3 must be set, bits 1 and 2 are clear. |
1 | Password code length, 0 when no password, 9 when there is a password. |
2-$0A | Password code, only included if a password is set. This code is a series of 9 bytes computed from the notepad's password. If the entered password gives the same passcode, then the notepad is decoded. |
The data consists of text with zero-bytes indicating the end of a line (so the data ends in zero). The first line must contain a title ending in a colon. If a password has been set, all the data after the title is encrypted. Note that the title, the colon after the title, and if present the zero-byte immediately following the colon, are all left unencrypted.
For an in-depth description of the password system and the notepad encryption, see The Psion LZ Password System page.
When a file is transferred via a Comms link to another computer, its format is changed somewhat. Here the various PC files are described.
These are data files which have been sent to a PC. The file name extension is ODB. This is an ordinary ASCII text file. Each record is placed on a single line, and tab characters (ASCII code 9) are used to separate the fields. No line may be longer than 254 characters.
These are procedures which have been sent to a PC. The file name extension is OPL. This is an ordinary ASCII text file, containing only the source of the procedure. No line may be longer than 254 characters.
These are block files which have been sent to a PC. The file name extension is OBx where x is the low nibble of the file type, i.e. OB3 for a translated procedure, OB7 for a notepad file etc. The file has the following format:
Byte: | Meaning: |
---|---|
0-2 | 'Magic number', the ASCII characters 'ORG'. Used to check whether a file is a Psion organiser file. |
3/4 | Length word, the length of the data block. |
5 | File type, between $82 and $8F. |
6+ | Data block. |
These are files containing a translated procedure, similar to an OB3 file. It has file type FE instead of 83. For the details of these files, see Translated Procedures and QCodes.
These are pack image files. It contains all the data of a pack, and has the following format:
Byte: | Meaning: |
---|---|
0-2 | 'Magic number', the ASCII characters 'OPK'. Used to check whether a file is a Psion pack image file. |
3-5 | Length, a three byte integer, the length of the pack data block. |
6+ | Pack data block. It is a direct copy of the data on the pack, beginning with the ten byte pack header, and ending with the FFFF word which follows the last data on the pack. |
There is a slight ambiguity with this format. When BLDPACK is used, the length integer includes the final FFFF bytes, so that it is 6 less than the OPK file size. When UNMAKE is used, the length integer does not include the FFFF bytes, so that it is 8 less than the OPK file size. In practice this does not matter, since writing FF bytes to an empty part of a pack changes nothing.
These pack image files are used in the emulator that is part of the Organiser Developer kit, and the format is almost identical to the OPK file format:
Byte: | Meaning: |
---|---|
0-2 | 'Magic number', the ASCII characters 'IPK'. Used to check whether a file is a Psion pack image file. |
3-5 | Length, a three byte integer, the length of the pack data block. |
6+ | Pack data block. It is a direct copy of the data on the pack, beginning with the ten byte pack header, and ending with the FFFF word which follows the last data on the pack. Note however that an .IPK image can only contain data files and LNO procedure files. The latter are procedures translated by the emulator. |
? | Padding, filled with zeroes. This can be any length, but is not included in the length integer. |
The length integer includes the final FFFF bytes at the end of the pack data, but not any of the padding that may follow.
These files are used by the BLDPACK program in the Organiser Developer kit for constructing bootable packs. It has the following format:
Byte: | Meaning: |
---|---|
0-2 | 'Magic number', the ASCII characters 'ORG'. Used to check whether a file is a Psion organiser file. |
3/4 | Length word, the length of the data following the 'file type' byte. |
5 | File type, is set to $FF. |
6-$F | Bootable pack header. Note that the flag byte, size byte, and checksum word are ignored, and are usually set to $FF. The code address is set to $0019. |
10-1A | MAIN file header. |
1B+ | Headerless block, containing the device code. |
The format of bytes 6+ are basically used as the first part of the pack. As such, it could probably be chosen to be different from the standard format outlined above, as long as it generates a valid pack image.
These files are loaded by the Comms link BOOT option. They simply contain the standard device code (i.e. a relocatable code block) without any preceding or subsequent bytes. There are a few differences from standard device code. The device code block is like this:
Byte: | Meaning: |
---|---|
0/1 | The length of the code. The same as the length word of the relocatable code block. |
2 | Contains 00 as normal. |
3 | Device identification number. Generally in the region $C-$18. |
4 | Device Version number. |
5 | Number of vectors is 1. Only the install vector is used. |
6/7 | Address of the install vector. |
8+ | The device vector routine and data. |
This file contains a backup of the RAM of the organiser, including the contents of device A:, diaries, alarms, etc. It is created by running the TRANS.BIN Comms boot code, and loaded back into the organiser by running the RECV.BIN boot code.
This file consists of separate blocks. Each block starts with a length word, which is the length of the block including the length word itself. The third byte is the type of block. This type byte can have the following values:
Byte: | Meaning: |
---|---|
00 | Header. This must be present and is always the first block the file, and has length $0010. The 13 data bytes consist of the Rom version ($FFE9), model bytes 1 and 2 ($FFE8, $FFCB), the selected language byte ($2186), the version byte of TRANS used to create the file, followed by the length of the whole file in 8 byte floating point format. |
01 | Pack block. Contains complete contents of pack A: starting with the title record of the MAIN file, just like a pack image. |
02 | Diary block. Contains contents of diary allocator cell $2004. |
03 | Notepad block. Contains contents of notepad allocator cell $2020. |
04 | Menu block. Contains contents of main menu allocator cell $2002. |
05 | Alarm block. Contains the alarm table $22F9-2328 (all 48 bytes regardless of how many of the alarms are set). |
06 | System variables block. Contains various system variables, and is $0064 bytes long. The variables are: the time ($20C5-A), delays ($69-C,$77), swoff vars ($7C-E), buzzer mute ($A4), keyboard ($20C0,$20C2-4,$7B), calculator mems ($20FF-$214E). |
07 | LZ system variables block. Is always 3 bytes long and contains the 2-line border ($2099), workday ($20A7) and time flags ($20A6). |