This text will explain the various format of the data stored on a Datapak by the Series 1 Psion Organiser.
1. Bootable Packs 2. Ordinary Packs 2.1 Pack Header 2.2 Records 2.3 Data Record 2.4 Program Name Record 2.5 Program Body Record
A bootable pack has a very simple format. The first byte on the pack is $03, to indicate that it is bootable. When the organiser reads this, it will then copy the next $C7 (=199) bytes of code to the RAM address $4006, where it is then immediately executed. This code should do all the necessary initialisation, such as adding menu items. It is likely that this cannot possibly all be done in 199 bytes, so the code will probably copy a larger block of program code from the pack and run that.
It is interesting to note that most of the bootable packs that Psion produced are essentially the same. They contain a runtime environment, which allows the organiser to interpret programs stored on the pack. For example, the Maths Pack, the Finance Pack, and the Science Pack have identical boot code, and differ only in their additional program records.
An ordinary pack is used for data storage. Like a series II pack, it begins with a 10 byte header:
Byte: | Meaning: |
---|---|
0 | $FC, which marks it as an organiser 1 data pack. |
1/2 | Size in bytes minus 1, so $1FFF for an 8K pack, $3FFF for a 16K pack, or $7FFF for a 32K pack. |
3-9 | Apparently unused, filled with $FF. |
The first data record starts at address $000A of the pack.
Note that the Series 1 could only use packs with linear addressing. Some linear 32K packs were produced for the Series 1, but most 32K packs for the Series II use paged addressing and will therefore not work on the series 1.
Each item on the pack is a record with the following format:
Byte: | Meaning: |
---|---|
0 | Length of the data that follows, including the type byte. |
1 | Type byte. See below. |
2+ | Contents, i.e. the stored data. |
The type byte is one of the following:
80 | A data record. |
81 | A program name record. |
82 | A program body record. |
These are explained further in the sections below. When the organiser deletes a record, the high bit of the type byte is cleared, so a type byte of 00, 01, or 02 means it is a deleted data record, program name record, or program body record.
A data record contains text in a packed form. Each letter of the text is stored into 6 bits, and four of those can be stored in 3 bytes, which gives a saving of up to 25%.
Firstly, the letters and symbols are encoded into a number in the range 0 ($00) to 63 ($3F). This is simply the ASCII code minus 32 ($20), as shown in the following table:
Code | Char | Code | Char | Code | Char | Code | Char | |||
---|---|---|---|---|---|---|---|---|---|---|
00 | space | 10 | 0 | 20 | @ | 30 | P | |||
01 | ! | 11 | 1 | 21 | A | 31 | Q | |||
02 | " | 12 | 2 | 22 | B | 32 | R | |||
03 | # | 13 | 3 | 23 | C | 33 | S | |||
04 | $ | 14 | 4 | 24 | D | 34 | T | |||
05 | % | 15 | 5 | 25 | E | 35 | U | |||
06 | & | 16 | 6 | 26 | F | 36 | V | |||
07 | ' | 17 | 7 | 27 | G | 37 | W | |||
08 | ( | 18 | 8 | 28 | H | 38 | X | |||
09 | ) | 19 | 9 | 29 | I | 39 | Y | |||
0A | * | 1A | : | 2A | J | 3A | Z | |||
0B | + | 1B | ; | 2B | K | 3B | [ | |||
0C | , | 1C | < | 2C | L | 3C | \ | |||
0D | - | 1D | = | 2D | M | 3D | ] | |||
0E | . | 1E | > | 2E | N | 3E | ^ | |||
0F | / | 1F | ? | 2F | O | 3F | _ |
The bits of four consecutive data characters are distributed over three bytes like this:
Character bits: | A1 A2 A3 A4 A5 A6 ; B1 B2 B3 B4 B5 B6 ; C1 C2 C3 C4 C5 C6 ; D1 D2 D3 D4 D5 D6 |
---|---|
Bytes: | B5 B6 A1 A2 A3 A4 A5 A6 ; C3 C4 C5 C6 B1 B2 B3 B4 ; D1 D2 D3 D4 D5 D6 C1 C2 |
So the first character is formed by the rightmost six bits of the first byte. The other two bits are left over. When the next byte is read, it is pasted onto the left of the previously read left-over bits, and then the 6 rightmost bits form the second character. Now we have four bits left over. The next byte is pasted onto the left of that, and so on.
When a string is stored, it is always padded at the end by an extra _ ($3F) character. Any unused bits in the last byte are simply ignored.
Let's take for example, the string "ABCDE". The 6-bit codes to store are $21, $22, $23, $24, $25, and a terminating $3F. The first four characters are interwoven to become the bytes $A1, $38, $92, and the next two characters interweave to become $E5, $0F. The complete data record that is stored will therefore be 06 80 A1 38 92 E5 0F.
The earlier CM or XP Series II organisers (rom version 3.3 and earlier) can read the data records of an organiser 1 pack, allowing the data to be copied. They cannot write to such a pack, unless it is reformatted first. This compatibility was removed in later versions (some time between rom versions 3.3 and 3.6).
A program name record simply contains as its data the program name in normal ASCII. A program name record is immediately followed by a program body record.
A program body contains a condensed version of the source code of the program. Every line of the program begins with a length byte, followed by the line of source code in ASCII, except that each multi-character keyword is represented by a one-byte code. After the last line of the program there is a single byte containing the number of lines the program has.
The bytes for all the keywords are shown here.
|
|
|
|
Here are two short examples from the Science Pack. The TAN program contains =SIN(P1)/COS(P1). This is stored on the pack as follows:
Bytes: | Meaning: |
---|---|
04 | Length of program name record |
81 | Program name record type |
54 41 4E | Program name TAN in ascii |
0D | Length of program body record |
82 | Program body record type |
0A | Length of first line of program |
3D | = |
A4 | SIN |
28 | ( |
8D | P1 |
29 | ) |
2F | / |
96 | COS |
28 | ( |
8D | P1 |
29 | ) |
01 | Number of lines in the program |
The PLASMA program contains:
IN "ELECTRON DENSITY"N
=SQRT(N*KE*KE/(KME*KEPS))
This is stored on the pack as follows:
Bytes: | Meaning: |
---|---|
07 | Length of program name record |
81 | Program name record type |
50 4C 41 53 41 | Program name PLASMA in ascii |
2E | Length of program body record |
82 | Program body record type |
14 | Length of first line of program |
81 | IN |
22 | " |
45 4C 45 43 54 52 4F 4E 20 44 45 4E 53 49 54 59 | ELECTRON DENSITY |
22 | " |
4E | N |
16 | Length of second line of program |
3D | = |
AA | SQRT |
28 | ( |
4E | N |
2A | * |
4B 45 | KE |
2A | * |
4B 45 | KE |
2F | / |
28 | ( |
4B 4D 45 | KME |
2A | * |
4B 45 50 53 | KEPS |
29 | ) |
29 | ) |
02 | Number of lines in the program |