Introduction
The 65816 addresses 16 MB as a bank byte and a 16-bit offset. The cartridge answers where its ROM is mapped, and how it is mapped is the “map mode” the internal header names. The ROM file is the ROM chip’s contents from byte 0 (after the copier header, if any); this page gives the rule that turns a CPU address into an offset in it. A disassembly of a ROM needs it to find where the vectors lead.
Everything on this page is for an ordinary cartridge with ROM and perhaps RAM. The co-processor boards (SA-1, Super FX, S-DD1, SPC7110, Cx4) remap ROM with registers of their own, which the explorer does not follow.
What is the same in every cartridge
In banks $00–$3F and their mirror $80–$BF
the console’s own hardware sits in the lower half of the bank, and the cartridge answers only
from $8000:
| Offset | What is there |
|---|---|
$0000–$1FFF | The first 8 KiB of the work RAM, mirrored in every system bank. |
$2100–$213F | The picture processor’s registers. |
$2140–$217F | The four sound processor ports, repeated every four bytes. |
$2180–$2183 | The work RAM access registers. |
$4016–$4017 | The joypad serial ports. |
$4200–$421F | The CPU’s registers: interrupts, multiply and divide, joypad data. |
$4300–$437F | The eight DMA channels, 11 registers each. |
$6000–$7FFF | Expansion: some cartridges put RAM or a chip’s registers here. |
$8000–$FFFF | The cartridge ROM. |
Banks $7E and $7F are the 128 KiB of work RAM. The registers are
listed on hardware registers. Banks
$80–$FF repeat $00–$7F for the ROM; they differ
in speed: $420D (MEMSEL) makes ROM in the upper banks read faster (the header’s
speed bit says whether the ROM is fast enough).
LoROM
The ROM is in 32 KiB pieces, each the upper half of a bank. For $8000–$FFFF
in any bank:
ROM offset = (bank AND $7F) × $8000 + (offset − $8000)
- Banks
$40–$7Dand$C0–$FFshow the same ROM across the whole bank: the lower half mirrors the upper half (when the cartridge has no SRAM there). - SRAM, when there is any, sits at
$70–$7Dand often again at$F0–$FF, offsets$0000–$7FFF. The placement varies; the wiki says there are many variations. - The header is at ROM offset
$7FC0, which is$00:FFC0on the bus, and the vectors at$7FE0–$7FFF.
HiROM
The ROM is in 64 KiB banks and the view in $C0–$FF is linear:
ROM offset = (bank AND $3F) × $10000 + offset
- Banks
$00–$3Fand$80–$BFshow the upper half of each bank,$8000–$FFFF, from the same offset as$C0–$FF:$00:8000reads what$C0:8000does. - Banks
$40–$7Dnormally mirror$C0–$FD. - SRAM, when there is any, is at
$20–$3F(and$A0–$BF), offsets$6000–$7FFF. - The header is at ROM offset
$FFC0, which is$00:FFC0.
ExHiROM
For ROMs larger than 4 MiB. ROM address line A22 is the inverse of CPU address line A23:
ROM offset = (bank AND $80 is 0 ? $400000 : 0) + (bank AND $3F) × $10000 + offset
- Banks
$80–$FFread the first 4 MiB of the file; banks$00–$7Dread the part from$400000, less the RAM banks. - The header is at ROM offset
$40FFC0, which is$00:FFC0on the bus, and the first bytes of the file are at$C0:0000.
ROMs that are not a power of two
The address lines decode a power-of-two size. A ROM that is not one (3 MiB, 1.5 MiB) is made of two power-of-two parts; the cartridge shows the smaller part repeated to fill the space up to the next power of two. The checksum in the header is taken over that repeated ROM (checksum). The explorer pads a ROM to a power of two by copying, for each bit set in the size from the lowest, the bytes just before it (which is the same thing for two parts) and reads the vectors and the code through that padded ROM, so a 3 MiB ROM’s upper banks read the last megabyte again, as the cartridge does.
How this page was checked
The explorer’s mapping was compared with the LakeSnes emulator’s cartridge code, built and run on the same ROM files: for each of 54 files (built test files and the real ROMs on this Mac) the byte its memory map answers at 8 CPU addresses in each of the 256 banks was compared with the explorer’s (about 2000 reads a file), where both map ROM; and the map mode LakeSnes chose was compared with the explorer’s choice. They agree, except for one file whose header is damaged, where LakeSnes does not skip the copier header (see the overview).
Not described
Known, not yet covered
- Reference: the co-processor boards’ own mappings (the SA-1’s bank registers
$2220–$2223, the Super FX’s ROM and RAM windows, S-DD1 and SPC7110 data decompression) and the SRAM placement variations. - Reference: the speed of each region (2.68 MHz or 3.58 MHz) beyond the ROM speed bit.
- Viewer: the disassembly shows each bank at one address (the first mirror); a jump to another mirror of the same bytes does not link.
Links
Reference
- Memory map – SNESdev Wiki: the pin wiring of LoROM, HiROM and ExHiROM, from which the formulas above follow
- ROM header – SNESdev Wiki: where the header is for each map mode