Apart from the header section, all the data in the PPU file is separated into data blocks, which permit easily adding additional data blocks, without compromising backward compatibility. This is similar to both Electronic Arts IFF chunk format and Microsoft’s RIFF chunk format.
Each ’chunk’ (tppuentry) has the following format, and can be nested:
offset | size (bytes) | description |
00h | 1 | Block type (nested (2) or main (1)) |
01h | 1 | Block identifier |
02h | 4 | Size of this data block |
06h+ | ¡variable¿ | Data for this block |
Each main section chunk must end with an end chunk. Nested chunks are used for record, class or object fields.
To read an entry you can simply call ppufile.readentry:byte, it returns the tppuentry.nr field, which holds the type of the entry. A common way how this works is (example is for the symbols):
repeat b:=ppufile.readentry; case b of ib<etc> : begin end; ibendsyms : break; end; until false;
The possible entry types are found in ppu.pas, but a short description of the most common ones are shown in table (A.5).
Symbolic name | Location | Description |
ibmodulename | General | Name of this unit. |
ibsourcefiles | General | Name of source files. |
ibusedmacros | General | Name and state of macros used. |
ibloadunit | General | Modules used by this units. |
inlinkunitofiles | General | Object files associated with this unit. |
iblinkunitstaticlibs | General | Static libraries associated with this unit. |
iblinkunitsharedlibs | General | Shared libraries associated with this unit. |
ibendinterface | General | End of General information section. |
ibstartdefs | Interface | Start of definitions. |
ibenddefs | Interface | End of definitions. |
ibstartsyms | Interface | Start of symbol data. |
ibendsyms | Interface | End of symbol data. |
ibendimplementation | Implementation | End of implementation data. |
ibendbrowser | Browser | End of browser section. |
ibend | General | End of Unit file. |
Then you can parse each entry type yourself. ppufile.readentry will take care of skipping unread bytes in the entry and reads the next entry correctly! A special function is skipuntilentry(untilb:byte):boolean; which will read the ppufile until it finds entry untilb in the main entries.
Parsing an entry can be done with ppufile.getxxx functions. The available functions are:
procedure ppufile.getdata(var b;len:longint); function getbyte:byte; function getword:word; function getlongint:longint; function getreal:ppureal; function getstring:string;
To check if you’re at the end of an entry you can use the following function:
function EndOfEntry:boolean;
notes:
ppureal is the best real that exists for the cpu where the unit is created for. Currently it is extended for i386 and single for m68k.
the ibobjectdef and ibrecorddef have stored a definition and symbol section for themselves. So you’ll need a recursive call. See ppudump.pp for a correct implementation.
A complete list of entries and what their fields contain can be found in ppudump.pp.