(back to project list)

Metroid Disassembly

Metroid is a hugely popular side-scrolling action adventure game developed and published by Nintendo for the NES.

This disassembly project is a quick experiment to see how the Metroid cartridge would work with SourceGen. This is not a finished disassembly. The original disassembly project upon which this is based came from metroid-database.com/source-code and nicholasmikstas.com/games, but neither of those sites work anymore. The nmikstas/metroid-disassembly github repo appears to be the current home.

Metroid is copyright 1986 Nintendo, Inc.

Notes

Metroid presents an interesting challenge for a disassembler. In memory, the ROM has two 16KB segments, from $8000-bfff and $c000-ffff. However, the cartridge actually has 8 16KB segments, 7 of which are mapped to the same place:

# Addr Name
0$8000Title
1$8000Brinstar
2$8000Norfair
3$8000Tourian
4$8000Kraid
5$8000Ridley
6$8000Graphics
7$C000Game Engine

While SourceGen is designed to handle multi-segment files, Metroid presents an awkward situation. Segments 1-5 have code that is called directly from the game engine, at a specific address that isn't part of a jump table. For example, the instruction at $f503 is JSR $80b0, where $80b0 is a small subroutine in segments 1-5. Unfortunately, in segment 0 $80b0 is actually the middle of an instruction, and without guidance that's where SourceGen tries to map it. Marking segment 0 as "no inbound references" avoids most of the issues, though it's necessary to fix an actual bank 0 reference from the game engine at +01c1fa by providing an operand label.

Another issue is the fact that a 128KB file is a bit large to display as a single document. The approach used in the original disassembly -- splitting each segment into a separate source listing -- works better. (Plus, most of the cross-assemblers choked on the generated sources because they exceeded the 64KB bank limit... dividing it into separate source files and linking the output together would solve that.)


Copyright 2021 by Andy McFadden