Jaap's Psion II Page

Psion Series 1 Datapak Format


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

1. Bootable Packs

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.

2. Ordinary Packs

2.1 Pack header

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 or $3FFF for a 16K pack.
3-9 Apparently unused, filled with $FF.

The first data record starts at address $000A of the pack.

Some linearly addressed 32K packs were produced, but I am not sure whether the series 1 could use them, or if they were intended only for the early series II models. The size in the header on such a pack would be $7FFF.

2.2 Records

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:

80A data record.
81A program name record.
82A 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.

2.3 Data 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:

CodeCharCodeCharCodeCharCodeChar
00space10020@30P
01!11121A31Q
02"12222B32R
03#13323C33S
04$14424D34T
05%15525E35U
06&16626F36V
07'17727G37W
08(18828H38X
09)19929I39Y
0A*1A:2AJ3AZ
0B+1B;2BK3B[
0C,1C<2CL3C\
0D-1D=2DM3D]
0E.1E>2EN3E^
0F/1F?2FO3F_

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; C1 C2 D1 D2 D3 D4 D5 D6

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

2.4 Program Name Record

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.

2.5 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 by a single byte. 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.

Byte:Keyword:
80IF
81IN
82OUT
83GOTO
84>=
85<=
86<>
87**
88OR
89AND
8ANOT
8BLN
8CPI
8DP1
8EP2
8FP3
Byte:Keyword:
90P4
90P5
92ABS
93?
94?
95ATN
96COS
97DEG
98ENG
99EXP
9AFAC
9BFIX
9CINT
9DLOG
9EMAX
9FMIN
Byte:Keyword:
A0MOD
A1RAD
A2RND
A3SGN
A4SIN
A5?
A6ALOG
A7?
A8RAND
A9?
AASQRT
AB?
ACMEAN
ADSTDEV
AEROUND
AFSTORE
Byte:Keyword:
B0GETKEY
B1RECALL

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:
04Length of program name record
81Program name record type
54 41 4EProgram name TAN in ascii
0DLength of program body record
82Program body record type
0ALength of first line of program
3D=
A4SIN
28(
8DP1
29)
2F/
96COS
28(
8DP1
29)
01Number 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:
07Length of program name record
81Program name record type
50 4C 41 53 41Program name PLASMA in ascii
2ELength of program body record
82Program body record type
14Length of first line of program
81IN
22"
45 4C 45 43 54 52 4F 4E 20 44 45 4E 53 49 54 59ELECTRON DENSITY
22"
4EN
16Length of second line of program
3D=
AASQRT
28(
4EN
2A*
4B 45KE
2A*
4B 45KE
2F/
28(
4B 4D 45KME
2A*
4B 45 50 53KEPS
29)
29)
02Number of lines in the program