Creating 1Mb+ ROMs

As mentioned before, there’s no such thing as a 1Mb Kickstart, yes, there’s physical ROMs which are 1Mb, however, the Amiga will map this to two 512k banks at non-contiguous addresses.

The first released ROMs were 256k, starting at 0xFC0000, during the changeover from KS1.3 to KS2.0 these were superseded by 512k ROMs which load (lower in memory) at 0xF80000, the CD32 uses a 1Mb (physical) ROM which consists of a 512k bank at 0xF80000 and an “extended” bank at 0xE00000.

Booting and loading

When an Amiga boots, it loads the exec library first, exec then will load the other kickstart libraries, or more correctly, it creates the references and function tables to the library, it also loads up any required initial data.

Exec finds the libraries in memory by looking for a “LIBHEADER”, this always starts with couple of bytes (0x4AFC, the “magic number”) and to check this isn’t just random data, this is followed by the address of the magic number, e.g. 0x4AFC00F800B6 where 0xF800B6 is the memory address of the 0x4AFC bytes, using the rest of the fields in the LIBHEADER it loads the library.

Choosing the banks to scan

Exec will scan defined areas of memory, for a standard A600 512k 3.1 ROM which loads at 0xF80000 it will scan 0xF80000 to 0x01000000, for a standard CD32 with a 3.1 kickstart it will scan 0xF80000 to 0x0100000 and the “extended” bank 0xE00000 to 0xE80000.

The list of areas to scan we call a “scantable”, this is an informal name, not documented as such, have a look at Kickstart->Kickstart Structure->Scantable for some examples.

Modifying the SCANTABLE

To get Exec to scan different areas of the ROM, there’s two approaches;

  1. Modify (patch) the SCANTABLE itself, by changing the list of areas you can scan different areas of memory.
  2. Append a new SCANTABLE to the ROM and patch the code to point to the new table

All SCANTABLES include are area 0xF00000-0xF80000 for scanning expansion ROMs so you can replace this (but lose the ability to use expansion ROMs). KS1.3 has 0xFC0000 listed twice so you can modify one of these without changing how it works, in theory, you can modify the 0xF00000-0xF80000 to 0xF00000-0x01000000 which will retain expansion ROM compatibility and still scan 0xF8, freeing up space to add 0xE0, however, this does change the loading order and that might have undesired effects.

Most 1Mb+patches will append a new SCANTABLE that has the new areas included and then change the code that points to the old SCANTABLE to point to the new one, this is a more elegant solution, but isn’t without challenges!

Patching KS1.3

As noted above, there’s duplicate entries in the KS1.3 SCANTABLE, so if you need to change it, you can an an entry easily.

find $exec.library 0x00FC00000100000000FC00000100000000F0000000F80000FFFFFFFF

Patching KS2.x

Patching KS2.x is slightly more complex than patching KS3.1 because, like KS3.1 it has two references to the SCANTABLE, but unlike KS3.1, there are two SCANTABLEs, and each reference refers to a different SCANTABLE.

Patching KS3.1

To patch KS3.1 you need to find the SCANTABLE and then find the code that points to it, finding the SCANTABLE is easy;

find $exec.library 0x00F800000100000000F0000000F80000FFFFFFFF

Finding the code that points to it isn’t as easy, you’ll need to find an opcode which looks something like “LEA $F8036A(PC),A0”, and of course this is a relative address, i.e. you won’t find the string of bytes “00F8036A” in memory, so you’ll need to disassemble the code – luckily Cap has a disassembler built in, note, as this is a relative (four byte) address, the maximum “jump” from the LEA to the new SCANTABLE is ±32k

findopcode $exec.library "LEA $F8036A(PC),A0"

Once you have the address of the opcode, you can patch it with the new address – note, there are two references to the SCANTABLE, both must be patched.

Patching Hyperion KS3.1.4+

You can patch the Hyperion ROMs by either changing the SCANTABLE contents (simple hack for 1Mb ROMs) or you can add a new (larger SCANTABLE) and patch the thing that points to it (needed for 2Mb ROMs), or you can avoid patching the SCANTABLE altogether by using the CD32 exec bundled on the CD32 modules as it comes enabled for 2Mb ROMs.

Patching Hyperion (modify existing SCANTABLE, 1Mb only)

Because the Hyperion SCANTABLE has a (largely) redundant scan of the space occupied by exec at the start, you can overwrite it safely (probably, seems to work).
e.g. we can modify;

00F80000 00F840A0 00F80000 01000000 00F00000 00F80000 FFFFFFFF
to
00F80000 01000000 00E00000 00E80000 00F00000 00F80000 FFFFFFFF

So simply, we need to find the SCANTABLE then patch it, the original SCANTABLE contains a reference to exec’s ENDSKIP (and it varies) so this patch works for any Hyperion ROM and makes it 1Mb enabled.

# The original SCANTABLE has a reference to exec's ENDSKIP value
# Set the ENDSKIP variable to whatever is in the ROM (e.g. 0x00F840A0)
alias ENDSKIP romdata $exec.library.(ROMTAG.ENDSKIP) 4
# Get rid of the 0x (e.g. 00F840A0) 
alias ENDSKIP mid 2

# Find the position of the original SCANTABLE (e.g. FIND=0x00000410)
find $exec.library 0x00F80000$ENDSKIP00F800000100000000F0000000F80000FFFFFFFF 

# Patch the SCANTABLE with the new values
patch $FIND 0x00F800000100000000E0000000E80000

Patching Hyperion (new SCANTABLE, 1Mb/2Mb)

Adding a new SCANTABLE is more complex, as you have to add some data, make it look similar to the original and then re-point any SCANTABLE references, it’s a “more complete” solution (and allows 2Mb ROMs) but it’s a bit more involved.

# The original SCANTABLE has a reference to exec's ENDSKIP value
# Set the ENDSKIP variable to whatever is in the ROM (e.g. 0x00F840A0)
alias ENDSKIP romdata $exec.library.(ROMTAG.ENDSKIP) 4
# Get rid of the 0x (e.g. 00F840A0) 
alias ENDSKIP mid 2

# Lets make the new SCANTABLE look like the old one (except it's bigger)
patch $1Mb_Scantable.3.2.bin.(START) 0x00F80000$ENDSKIP
# Now create the STSTART as a proper ROM reference
alias STSTART $1Mb_Scantable.3.2.bin.(START)
alias STSTART add $ROMBASE

# Find the position of the original SCANTABLE (e.g. FIND=0x00000410)
find $exec.library 0x00F80000$ENDSKIP00F800000100000000F0000000F80000FFFFFFFF 
# Add the ROMBASE to get a proper Amiga address after the ROM is loaded (e.g. FIND=0x00F80410)
alias FIND add $ROMBASE
# Find the reference to the original SCANTABLE (i.e. the thing that points at the original SCANTABLE)
find $exec.library $FIND

# Patch the reference to the original SCANTABLE with the address of the new SCANTABLE
patch $FIND $STSTART
Scroll to Top