The cartridge

RC-742, 128 KB, sixteen banks of 8 KB, with the Konami mapper without SCC (Konami4). tools/reconocimiento.py measures that on the bytes rather than assuming it: there is not one write to 0x5000, 0x7000, 0x9000 or 0xB000, which are the registers of the other Konami mapper, the one with the SCC.

How the banks are mapped

There is no register for 0x4000-0x5FFF: bank 0 is nailed there. The other three windows take the bank number written to 0x6000, 0x8000 and 0xA000, and the cartridge keeps a copy of the current split in 0xF0F1..0xF0F3 so an interrupt can put it back.

windowbanks that go there
0x40000 (fixed)
0x60001, 4
0x80002, 5, 7, 9, 11
0xA0003, 6, 8, 10, 12

Each bank has exactly one address it executes at, which is why the listing can be split into sixteen files with sixteen orgs.

What is in each bank

bankcodewhat it holds
03,158 instr.the loop, the scroll, the sprites, the VDP, the modes
13,231 instr.the enemy engines, the collisions, the boss
22,849 instr.the ship, the bosses, the aiming tables
33,074 instr.the power-up meter, the laser, twenty of the enemy types
4, 5, 6—the stage graphics, compressed
7420 instr.the sound player
8—the music and the effects
9, 10227 instr.the fixed screens, and a small sprite engine of their own
11, 12—the map pieces and the stage scripts
13, 14, 15—0xFF, end to end

Only six of the sixteen banks carry code.

How much of the chip is empty

48,219 bytes — 47.1 KB, 36.8% of the cartridge — are declared as 0xFF filler. Four banks are filler end to end: 6, 13, 14 and 15. The others end with a tail: 7,202 bytes in bank 8, 4,311 in bank 10, 2,487 in bank 12 and 1,052 in bank 5. The odd one out is a hole of 399 bytes inside bank 3, between the last data and the eleven bytes of the hidden Konami mark; the other 47,820 are tails.

Bank 6 is the odd one: the routine that maps 4/5/6 for graphics does put it in 0xA000, so it is mapped for real — there is simply nothing in it to read.

The VRAM map is upside down

The eight bytes at 0x575A go to VDP registers 0 to 7: 0x02, 0xE2, 0x0E, 0x7F, 0x07, 0x76, 0x03, 0xE4. They do not leave anything where the BIOS leaves it.

tablewhere the BIOS puts itwhere this cartridge puts it
patterns0x00000x2000
colours0x20000x0000
names0x18000x3800
sprite attributes0x1B000x3B00
sprite patterns0x38000x1800

The name table ends at 0x3AFF and the sprite attributes start at 0x3B00, right behind it.

How the graphics are stored

Everything the cartridge draws goes through one small decompressor at 0x49B9, and its format is written the other way round from what you would expect: bit 7 marks the literal copy, not the repeat.

commandwhat it does
0x00ends the block
0x01..0x7Fthe next byte, N times
0x80the next two bytes are a new VRAM address
0x81..0xFFN-0x80 bytes copied as they come

With that, the size of a block is not estimated: it is counted. That is what lets every graphics range be declared with a D directive without missing a byte or eating the next one. tools/rle.py measures any of them.

The stage characters are loaded by records of six bytes: which thirds to fill, where the pattern stream is, at which character to start, and where the colour stream is. Then two more lists mirror part of what was just loaded — by bits for a horizontal flip, by bytes for a vertical one — so half the terrain characters are made out of the other half instead of being stored twice.

The hidden mark

At the end of bank 3, at offset 0x07FFF of the dump, sit the cartridge code RC-742 and eight katakana characters that read グラディウス, Gradius. It is the signature Konami hid in its cartridges; the person who found it and documented it is Manuel Pazos. make marca reads it back out of the ROM.