An AmigaDOS hunk file's absolute constants are hunk offsets that LoadSeg
relocates. The same numbers read as file offsets point somewhere else. Every
address in this repository is stated as one of the two and labelled, and the
mapping is this:
FirePAL 410,184 bytes
hunk 0 CODE any 92,236 bytes body at file offset 0x000024
hunk 1 DATA chip 309,252 bytes body at file offset 0x018A40
2,155 relocations: hunk0 -> hunk0 2,106
hunk0 -> hunk1 49
FireNTSC 409,820 bytes
hunk 0 CODE any 91,872 bytes body at file offset 0x000024
hunk 1 DATA chip 309,252 bytes body at file offset 0x0188D4
2,155 relocations, same split
So for FirePAL:
file offset = 0x000024 + hunk 0 offset (code)
file offset = 0x018A40 + hunk 1 offset (chip data)
python3 tools/relocs.py FirePAL --at 0x1101C answers the question in the
other direction and, importantly, says when a constant is not covered by a
relocation, in which case it is a literal and reading it as an address is the
mistake. That check is not decorative here: chasing the copper pointer in
07-graphics.md ran into exactly that case.
Two hunks, 2,155 relocations, no BSS. These are ordinary LoadSeg-able
executables — not the self-decrunching, self-relocating stubs that
HeroQuest II and Banshee ship. There is no hunk file on this disc with zero
HUNK_RELOC32 blocks and more than one hunk.
The absence of a BSS hunk matters for reading the code: the program's
variables live at the tail of the CODE hunk as zero-filled longwords. A
pointer read out of the file there will be 00000000 and is filled in at run
time; it is not a null in the sense of a bug.
Timestamps 2 minutes 8 seconds apart (02-filesystem.md), identical hunk structure, identical relocation counts and identical chip DATA hunk length. The code hunks agree for their first 154 bytes and then diverge, because every absolute address after that point has shifted by 364 bytes. A byte diff is therefore useless and the comparison has to be made on content.
Made on content, the two agree everywhere that matters and differ in exactly two places:
| FirePAL | FireNTSC | |
|---|---|---|
| Code hunk | 92,236 B | 91,872 B (−364) |
| Copper list template | 5,496 B, 1,374 instructions | 5,168 B, 1,292 instructions |
WAIT lines in the list |
240 | 217 |
First WAIT line |
43 | 35 |
Last WAIT line |
26 (after wrapping past 255) | 251 |
| 8-plane region | 193 lines | 193 lines |
| 4-plane region below it | 47 lines | 24 lines |
System: in the options panel |
PAL |
NTSC |
Version: in the options panel |
AGA 1.04 |
AGA 1.04 |
| Chip DATA hunk SHA-1 | b5ef6cbe… |
8bdbfea5… |
The playfield is the same height in both — 193 scanlines — and the whole
difference is the 23 extra lines PAL has underneath it, plus the string. The
PAL list uses the copper's 8-bit vertical counter past line 255 and continues
with small vp values, which is why its last WAIT reads 26; NTSC never
needs to.
Building the second executable rather than branching at run time costs 410 KB of a disc that had 232 spare sectors at the end and a third of the CD unused, so nothing was being economised. It is the shape you get when the display code was written with PAL constants in it and the cheapest way to ship NTSC was to rebuild.
FirePAL's 92 KB code hunk holds the whole game: loader, replayer, blitter
routines, the copper builder, and the menu. The 302 KB chip DATA hunk holds the
copper list template, the font, the sprites for the front end and one
PowerPacker stream (04-compression.md).
Everything the player sees during a level comes from Cores, Graphics and
Sets (09-resources.md); the executable holds no level
data.
Counted from PC-relative lea sites resolving to the name strings at file
0x0DC4..0x0E4C, in address order in the code:
hunk0+0x000010 lea freeanim.library , a1
hunk0+0x000020 lea lowlevel.library , a1
hunk0+0x00005A lea nonvolatile.library , a1
hunk0+0x00006E lea dos.library , a1
hunk0+0x000082 lea graphics.library , a1
hunk0+0x0001AC lea input.device , a0
hunk0+0x000444 lea cd.device , a0
hunk0+0x0004A4 lea cd.device , a0
Five libraries, all through OpenLibrary (−552, five calls), in that order;
three device opens through OpenDevice (−444), of which cd.device is opened
twice, each with its own CreateMsgPort (−666) and CreateIORequest
(−654). An audio.device name string is present at 0x0E0C and is not
reached by any lea in the code hunk.
freeanim.library is opened first and is not on the disc. It is a CD32
ROM library, and there is no wrapper command for it as there is on six other
discs in this set. Combined with the missing /Libs that the Workbench script
tries to assign (03-boot-chain.md), this executable cannot
run from this disc on an A1200. That is the second disc in the set with that
property; Banshee was the first.
Supervisor (−30) is called seven times and Alert (−84) three times. A
program that enters supervisor mode seven times is not asking the OS for much,
which is confirmed by the register scans in 10-hardware.md.