Thanks to Ian Goldberg, the format of the RLE compression in the Data resource is now documented.
Up until now, there really hasn't been a public documentation of the PRC format. I tried looking at the sources for some of the alternative software Pilot development programs, such as Pila and prc-tools. Unfortunately, these programs would often treat header fields as "magic", and often different programs would do completely different things with the same fields.
This document is my attempt to rectify this situation. It is the product of both research into existing implementations, as well as experimentation to clarify some minor points of how the Pilot tools work. Some of my sources include:
An application for the pilot is simply a Pilot resource database with a number of mandatory resources (CODE 0, CODE 1, DATA 0, PREF 0, etc.) The PRC file, then, is simply the flat file representation of a Pilot resource database. When the PRC file is loaded into the Pilot, it is converted into a resource database using the PalmOS routine dmCreateDatabaseFromImage().
The PRC format consists of the following major pieces:
The PRC Header is located at the very beginning of the file, and contains the following information:
offset name type size notes 0x00 name char 32 [1] 0x20 flags int 2 [2] 0x22 version int 2 [3] 0x24 create_time pilot_time_t 4 [4] 0x28 mod_time pilot_time_t 4 [4] 0x2C backup_time pilot_time_t 4 [4] 0x30 mod_num int 4 [5] 0x34 app_info int 4 [5] 0x38 sort_info int 4 [5] 0x3C type int 4 [6] 0x40 id int 4 [7] 0x44 unique_id_seed int 4 [5] 0x48 next_record_list int 4 [5] 0x4C num_records int 2 [8]
[1] The name field is zero terminated and is usually zero padded. The pila assembler sneaks 'Pila' into the last 4 bytes of this field
[2] The 'flags' field is 0x01 for PRC executables. The 0x40 bit is set if the executable is considered non-beamble. (Note that this means it's probably fairly easy to make a non-beamble application to be beamable...)
[3] The 'version' field is 0x01 for PRC executables
[4] Pilot time is defined to be the number of seconds since January 1, 1904 (i.e, Macintosh time).
[5] This field must be zero for PRC executables
[6] The 'type' field must be 'appl' for PRC executables
[7] The 'id' field is a four character "creator code", ala the Macintosh
[8] The 'num_records' field contains the number of resources in the PRC file.
The Resource headers follow immediately after the PRC Header field. The num_records field in the PRC Header indicates the number of resources contained in the PRC file, and there is a 10 byte resource header for each resource.
name | type | size | notes |
---|---|---|---|
name | char | 4 | Name of the resource |
id | int | 2 | ID number of the resource |
offset | int | 4 | Pointer to the resource data |
The actual data for the resources follow after the resource headers. The resource data records are stored in order as they appeared in the resource headers. (Since the resource header does not have a size field, the size is determined by examining the where the offset pointer for the next resource.)
The contents of this resource have been (up until now) somewhat mysterious, with different packages --- Metroworks, Pila, and the obj-res program from the prc-tools package --- generating in some cases very different values.
Pila creates an 8 byte resource, with the first four bytes described as the initialized data size and the next four bytes described as the unitialized data size. Pila stores the size of the data segment in the first field, and the second field is always filled with zeros.
The obj-res program from the prc-tools package does something quite different. It creates a 24 byte resource, which is filled in as follows:
offset value 0 0x00000028 4 [bss+data segments rounded up to 4 bytes] 8 0x00000008 12 0x00000020 16 0x0000 18 0x3F3C 20 0x0001 22 0xA9F0
The obj-res program treated most of the fields in the 24 byte resource as magic values, apparently obtained from looking at the contents of the code 0 resource from PRC files generated by the Metroworks compiler, since applications generated by the Metrowerks compiler have similar code 0 resources.
I believe that the code 0 resource is identical to that which is used by the 68k Macintosh. This explains why pila can use such a different code 0 resource, and yet still produce working appications. To explain this, though, we need to take a detour and look at the Macintosh memory management model.
+-------------------+ /| | / | Jump table | | +-------------------+ A5 world ---> | | Appl. Params | | +-------------------+