heckmeck!

Nerd content and
cringe since 1999

Alexander Grupe
Losso/ATW

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.2Kickstart 1.3Kickstart 2.04Kickstart 3.1
d000000000000000000000000000000809
d18000ffff8000ffff0000ffff00000808
d200000001000000010000000100000001
d300000000000000000000d6880000ad48
d400000000000000000000146800001520
d500000000000000000000000000000000
d6ffffffffffffffffffffffffffffffff
d700000000000000000000000000000000
a000001958000019580000dfb80000ed38
a100c014e600c014e20000d54c0000e2c4
a200c0185cffffffff0000d5300000e2a8
a300fe8b3a00fe86ee0000d54c0000e2c4
a4000015580000155800003e4c00002708
a500c014ba00c014b600000a4400000a74
a600c0027600c002760000146800001520
a700c014b600c014b200003e10000026cc
pc00001564000015640000dfc40000ed44

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:

RegisterContents
d2Constant value 00000001
d5Constant value 00000000
d6Constant value ffffffff – see warning above!
d7Constant value 00000000 – see warning above!
a1IORequest, as specified by the OS
a6exec.library, as specified by the OS
pc12 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
previous next close