With Revision’s
deadlines looming and the party build-up
starting tomorrow later today, my time budget for
a potential size-coded Amiga release doesn’t look too good anymore…
That’s life!
But at least I had some time to revisit my packer setup between my last work day before Easter and packing my luggage. Behold, the magic of known register contents at boot time across Kickstart versions!
Kickstart 1.2 | Kickstart 1.3 | Kickstart 2.04 | Kickstart 3.1 | |
---|---|---|---|---|
d0 | 00000000 | 00000000 | 00000000 | 00000809 |
d1 | 8000ffff | 8000ffff | 0000ffff | 00000808 |
d2 | 00000001 | 00000001 | 00000001 | 00000001 |
d3 | 00000000 | 00000000 | 0000d688 | 0000ad48 |
d4 | 00000000 | 00000000 | 00001468 | 00001520 |
d5 | 00000000 | 00000000 | 00000000 | 00000000 |
d6 | ffffffff | ffffffff | ffffffff | ffffffff |
d7 | 00000000 | 00000000 | 00000000 | 00000000 |
a0 | 00001958 | 00001958 | 0000dfb8 | 0000ed38 |
a1 | 00c014e6 | 00c014e2 | 0000d54c | 0000e2c4 |
a2 | 00c0185c | ffffffff | 0000d530 | 0000e2a8 |
a3 | 00fe8b3a | 00fe86ee | 0000d54c | 0000e2c4 |
a4 | 00001558 | 00001558 | 00003e4c | 00002708 |
a5 | 00c014ba | 00c014b6 | 00000a44 | 00000a74 |
a6 | 00c00276 | 00c00276 | 00001468 | 00001520 |
a7 | 00c014b6 | 00c014b2 | 00003e10 | 000026cc |
pc | 00001564 | 00001564 | 0000dfc4 | 0000ed44 |
Note: Of course, this is not an exhaustive list; these are merely samples of the most common configuations: Amiga 500 with 512+512K RAM for 1.2 and 1.3, Amiga 500+ for 2.04, vanilla Amiga 1200 for 3.1
Warning: The values for d6 and d7 will differ if the bootblock is run after a guru meditation! For example, after this:

…d6 and d7 will contain 00000004
and 00c01570
instead of -1 and 0.
Thanks to platon42 for the hint!
This gives us:
Register | Contents |
---|---|
d2 | Constant value 00000001 |
d5 | Constant value 00000000 |
d6 | Constant value ffffffff – see warning above! |
d7 | Constant value 00000000 – see warning above! |
a1 | IORequest, as specified by the OS |
a6 | exec.library, as specified by the OS |
pc | 12 bytes after the bootblock content as it was loaded from disk (i. e. 'DOS',0 followed by checksum and rootblock longwords) |
Nifty! Together with some register shuffling, we can then use these values to omit some constant initializations in the depacker code.
Shrinkler (source) – 4 bytes saved:
ShrinklerDecompress: ; Init range decoder state moveq.l #0,d2 ; omit, use d5 instead moveq.l #1,d3 ; omit, use d2 instead ...
ZX0 (source) – 2 bytes saved:
zx0_decompress: moveq.l #-128,d1 ; initialize empty bit queue moveq.l #-1,d2 ; omit, use d6 instead ...
I love that each of the constant values 0, 1, and -1 is useful! :)
For both packers, the bootblock on disk then starts like this:
dc.b 'DOS',0 dc.l 0 ; checksum will be inserted here root: dc.l $20000 ; destinaton; normally 880 = rootblock entry: move.l root(pc),aX ; load destination address lea packed(pc),aY ; load packed data pea (aX) ; rts will jump into unpacked code ... ; decompress code starts here