Here I try to describe the structure of a kickstart ROM, what the data looks like and how the code is laid out kickstarts come in different physical and digital formats, but if you strip past all that and just look at the raw kickstart data, this is what I discuss here, these are the bits a ROM is made up from.
ROMHEADER
Because of these various chunks and the way that the Amiga maps kickstart addresses on startup various ROMs may try and execute at different times, to keep this under control, it uses a 16 byte ROMHEADER, the original 256k ROM starts at $FC0000
When you build a 1Mb ROM, you’re not really building a 1Mb ROM, you’re building a 512k ROM at $F80000 and a 512k ROM at $E00000, so you need to give the $E00000 ROM a ROMHEADER too.
When the 680×0 starts, it maps the rom to address 0x0000000 (this is called “overlay” or OVL), then starts executing at address 0x000002 (the first two bytes of the Kickstart identify the size of the first bank used) when execution starts at the proper ROM address it can turn overlay off which means the address 0x000000 then is mapped properly to the first bank of available chip ram, in the examples below, I give the addresses as they would appear after OVL is switched off.
Kickstart 1.3 (A500) 256k ROMHEADER
0xFC0000 1111 ChipID 256k
0xFC0002 4EF9 00FC00D2 JMP $FC00D2
0xFC0008 0000 FFFF Unknown purpose, doesn't seem to vary
0xFC000C 0022 0005 r34.5
Kickstart 2.05 (A600) 512k ROMHEADER
0xF80000 1114 ChipID 512k
0xF80002 4EF9 00F800D2 JMP $F800D2
0xF80008 0000 FFFF Unknown purpose, doesn't seem to vary
0xF8000C 0025 015E r37.350
Kickstart 3.1 (CD32) 512k Extended ROMHEADER
0xE00000 1114 ChipID 512k
0xE00002 4EF9 00F80002 JMP $F80002
0xE00008 0000 FFFF Unknown purpose, doesn't seem to vary
0xE0000C 0028 003C r40.60
Kickstart 3.1 (A600) 512k ReCode ROMHEADER
0x200000 1116 ChipID 512k / Softload
0x200002 4EF9 002000D2 JMP $2000D2
0x200008 0000 FFFF Unknown purpose, doesn't seem to vary
0x20000C 0028 0048 r40.68
You may even see this in the form of a shorter, partial eight byte ROMHEADER 256k through some early 512k ROMs, colloquially known as “Kickity-Split”, this was just a backward-compatible “hack” in case programmers assumed the reset code was at $FC0002.
Kickstart 2.05 (A600) 512k Kickety-Split
0xFC0000 1111 ChipID 256k
0xFC0002 4EF9 00F8 0002 JMP $F80002
Scantable
The way that the Amiga knows what Kickstart banks are present is by using a “scantable”. The scantable is stored in exec, so it’s not in a fixed location and technically part of the ROM structure per-se, but it is fundamental to how the Amiga loads libraries and from which areas of memory.
It’s a list of areas in the memory to search in pairs of long words, it’s actual make up will vary depending on the version of exec/kickstart (and target machine), you may need to manipulate the scantable if you want to load libraries from multiple ROM banks (e.g. you want to build a custom 1Mb ROM).
Kickstart 1.2 exec - 1.3 is the same, just in a different place
0xFC04E4 00FC0000 01000000 0xFC0000 - 0x01000000
0xFC04EC 00FC0000 01000000 0xFC0000 - 0x01000000
0xFC04F4 00F00000 00F80000 0xF00000 - 0xF80000 "Extended ROM" e.g. CDTV
0xFC04FC FFFFFFFF End of scantable
Kickstart 2.05 exec (37.299) there are two identical SCANTABLEs in 2.x Kickstart 1.4 and 3.1 only have one.
0xF80346 00F80000 01000000 0xF80000 - 0x01000000
0xF8034E 00F00000 00F80000 00F00000 - 0xF80000 "Extended ROM"
0xF80356 FFFFFFFF End of scantable
...
0xF8044C 00F80000 01000000 0xF80000 - 0x01000000
0xF80454 00F00000 00F80000 00F00000 - 0xF80000 "Extended ROM"
0xF8045C FFFFFFFF End of scantable
Kickstart 3.1 exec (CD32 - 1Mb kickstart)
0xF8036A 00F80000 01000000 0xF80000 - 0x01000000 "Normal kickstart"
0xF80372 00E00000 00E80000 0xE00000 - 0xE80000 "Extended ROM" (extra 512k)
0xF8037A 00A80000 00B80000 0xA80000 - 0xB80000 "FMV ROM" - Although, the ROM I have has a ROMBASE of $200000
0xF80382 00F00000 00F80000 0xF00000 - 0xF80000 "Extended/Flash ROM"
0xF8038A FFFFFFFF End of scantable
Kickstart 3.1 exec (CD1200 - 1Mb kickstart) - I suspect this is just a modified CD32 kickstart
0xF8036A 00F00000 00F80000 0xF00000 - 0xF80000 "Normal kickstart"
0xF80372 00E00000 00E80000 0xE00000 - 0xE80000 "Extended ROM" - Curiously not used in a CD1200
0xF8037A 00A80000 00B80000 0xA80000 - 0xB80000 "Extended ROM" - This is the CD1200 extended ROM address
0xF80382 00F00000 00F80000 0xF00000 - 0xF80000 "Extended/Flash ROM" - This would imply a second pass
0xF8038A FFFFFFFF End of scantable
In 3.1.4/3.2 there is also an additional scan of the space occupied by exec.
Kickstart 3.2
0xF80410 00F80000 00F840C0 0xF80000 - 0xF840C0 "Scan exec" - this value is different in 3.1.4 as exec is different
0xF80418 00F80000 01000000 0xF80000 - 0x01000000 "Normal kickstart"
0xF80420 00F00000 00F80000 00F00000 - 0xF80000 "Extended ROM"
0xF80428 FFFFFFFF End of scantable
Although the Hyperion ROMs do not come with a CD32 ROM prebuilt, there is a ModulesCD32.adf with a specific exec.library for it, this is more interesting because it’s configured as an exec for 2Mb ROMs, it appears usable for A600/A1200 too.
Kickstart 3.2 CD32
0xF8040E 00F80000 00F840AC 0xF80000 - 0xF840AC "Exclude from scan" - this is different in 3.1.4 as exec is different
0xF80416 00F80000 01000000 0xF80000 - 0x01000000 "Normal kickstart"
0xF8041E 00E00000 00E80000 0xE00000 - 0xE80000 "Extended ROM" (extra 512k)
0xF80426 00A80000 00B80000 0xA80000 - 0xB80000 "Extended ROM" (extra 1mb, possibly FMV ROM overlap in some docs)
0xF8042E 00F00000 00F80000 0xF00000 - 0xF80000 "Expansion ROM"
0xF80436 FFFFFFFF End of scantable
These are “standard” scantables – if you want to build a custom size ROM you may have to update these.
Libraries and Devices
The whole point of the ROM is to hold the libraries and devices, these are stored using library header which has a ROMTAG magic word, this is basically an illegal 680000 opcode (RTC_MATCHWORD) followed by a ROM address which should match the address of the magic number
For example $4AFC00FC00B6, $4AFC is the magic word, and the next 4 bytes $00FC00B6 should be the address of the magic word (if it’s valid)
The ROMTAG structure allows exec to find the devices and libraries in ROM (using the scantable ranges) and initialise/load them.
Markus Wandel dissassembled the 1.2 exec back in 1989, here’s the exec ROMTAG structure from his page
FC00B6 4AFC RTC_MATCHWORD (start of ROMTAG marker)
FC00B8 00FC00B6 RT_MATCHTAG (pointer RTC_MATCHWORD)
FC00BC 00FC323A RT_ENDSKIP (pointer to end of code)
FC00C0 00 RT_FLAGS (no flags)
FC00C1 21 RT_VERSION (version number)
FC00C2 09 RT_TYPE (NT_LIBRARY)
FC00C3 78 RT_PRI (priority = 126)
FC00C4 00FC00A8 RT_NAME (pointer to name)
FC00C8 00FC0018 RT_IDSTRING (pointer to ID string)
FC00CC 00FC00D2 RT_INIT (execution address)
Superkick Size
In some ROMs, 28 bytes from the end of the ROM there’s an indicator of where the last library module ends, you won’t see this in many ROMs, typically only ones designed for the A3000, and typically only ones used for Superkickstart booting, I’m assuming it’s so space can be used efficiently and unused space can be clawed back when softbooting.
This isn’t really a required part of the kickstart ROM definition, so you won’t always find it, but included here for completeness.
00FFF7001 - 00F80000 (ROMBASE) = 0x7F701 (521984 is the first free byte)
Checksum
The kickstart checksum is held 24 bytes from the end of the ROM and is a very simple algorithm, if this is not valid, your Amiga might not boot, and instead may throw a red screen.
CHECKSUM=0
Starting at the beginning of the ROM, read in 4 byte chunks (treat each as an unsigned long word)
Add the unsigned word to CHECKSUM
If CHECKSUM overflows (wraps round past 0xFFFFFFFF)
increment CHECKSUM by 1
The CHECKSUM must end up as 0xFFFFFFFF
To calculate the correct checksum and ensure that the (total ROM) checksum ends up as 0xFFFFFFFF, you add all the four byte chunks (as above) except the four bytes 24 bytes from the end, take this result away from 0xFFFFFFFF and you'll know what you need to store in this reserved location.
Size
The size of the ROM is stored at 20 bytes from the end of the ROM and is the size in bytes, note, for hard drive superkick files the ROM is still a 256k/512k ROM of a fixed size and the extra data appended is like a mini ROM and called “Bonus” code, so the Size indicator will still be 256k or 512k and be 20 bytes offset from that absolute position.
0x.00040000 = 262144 = 256k
0x.00080000 = 524288 = 512k
Vectors
The final 16 bytes are “hardware interrupt vectors” (eight short, two byte integers), and don’t vary much between the versions of the kickstart ROMs.
00000019001A001B001C001D001E001F - Early kickstarts 1.x
00180019001A001B001C001D001E001F - later kickstarts >=2.x