SNES ROM Header: Difference between revisions
Vitor Vilela (talk | contribs) |
No edit summary |
||
Line 49: | Line 49: | ||
=== Game Code === | === Game Code === | ||
=== Fixed Value === | === Fixed Value === | ||
Each of these bytes should be #$00. | |||
=== Expansion RAM Size === | === Expansion RAM Size === | ||
Common values: #$00 - none, #$01 - 2KB, #$03 - 8KB, #$05 - 32KB, #$06 - 64KB, #$07 - 128KB | |||
=== Special Version === | === Special Version === | ||
Should be #$00. | |||
=== Game Title Specification === | === Game Title Specification === | ||
The game title is 21 bytes long, encoded with the [https://en.wikipedia.org/wiki/JIS_X_0201 JIS X 0201] character set (which consists of standard ASCII plus katakana). If the title is shorter than 21 bytes, then the remainder should be padded with spaces (0x20). | The game title is 21 bytes long, encoded with the [https://en.wikipedia.org/wiki/JIS_X_0201 JIS X 0201] character set (which consists of standard ASCII plus katakana). If the title is shorter than 21 bytes, then the remainder should be padded with spaces (0x20). | ||
Line 56: | Line 59: | ||
=== Cartridge Configuration === | === Cartridge Configuration === | ||
==== Map Mode ==== | ==== Map Mode ==== | ||
Common values: #$20 - 2.68MHz LoROM, #$21 - 2.68MHz HiROM, #$23 - SA-1; #$25 - 2.68MHz ExHiROM; #$30 - 3.58MHz LoROM, #$31 - 3.58MHz HiROM; #$35 - 3.58MHz ExHiROM | |||
==== Cartridge Type ==== | ==== Cartridge Type ==== | ||
Common values: #$00 - ROM only; #$01 - ROM and RAM; #$02 - ROM, RAM and battery; #$33 - ROM and SA-1; #$34 - ROM, SA-1 and RAM; #$35 - ROM, SA-1, RAM and battery | |||
===== Sub-Number ===== | ===== Sub-Number ===== | ||
==== ROM Size ==== | ==== ROM Size ==== | ||
2^(this value) would be the size of the ROM in kilobytes. | 2^(this value) would be the size of the ROM in kilobytes. For example, for 512KB, this should be #$09. | ||
==== RAM Size ==== | ==== RAM Size ==== | ||
2^(this value) would be the size of the SRAM (if present) in kilobytes. Maximum supported value is $07. | 2^(this value) would be the size of the SRAM (if present) in kilobytes. Maximum supported value is #$07. | ||
=== Destination Code === | === Destination Code === | ||
Where the game is intended to be sold. Common values: #$00 - Japan; #$01 - USA; #$02 - Europe (enables 50fps PAL mode) | |||
=== Mask ROM Version === | === Mask ROM Version === | ||
=== ROM Verification === | === ROM Verification === |
Revision as of 21:07, 17 September 2021
All SNES gamepaks have an internal header that is used to identifying the game, producer, region and technical aspects of the ROM. It's often referred as Internal ROM Header or SNES Software Specification.
Although it's not required to run a game on real hardware, the SNES ROM Header was used during the Nintendo approval process for validation and it's also used by the SNES emulators to identify and determine the memory layout and ROM type.
The data starts at SNES address $00:FFB0 and ends at $00:FFDF. $00:FFE0 though $00:FFFF contains the SNES vector information and it's actually used by the SNES CPU to determine where to execute when an interrupt occurs.
ROM Registration Data
Address | Length | Data Name Type |
---|---|---|
$00:FFB0 | 2 bytes | Maker Code |
$00:FFB2 | 4 bytes | Game Code |
$00:FFB6 | 7 bytes | Fixed Value |
$00:FFBD | 1 byte | Expansion RAM Size |
$00:FFBE | 1 byte | Special Version |
$00:FFBF | 1 byte | Cartridge Type (Sub-number) |
$00:FFC0 | 21 bytes | Game Title Registration |
$00:FFD5 | 1 byte | Map Mode |
$00:FFD6 | 1 byte | Cartridge Type |
$00:FFD7 | 1 byte | ROM Size |
$00:FFD8 | 1 byte | RAM Size |
$00:FFD9 | 1 byte | Destination Code |
$00:FFDA | 1 byte | Fixed Value |
$00:FFDB | 1 byte | Mask ROM Version |
$00:FFDC | 2 bytes | Complement Check |
$00:FFDE | 2 bytes | Check Sum |
Data Name Types
Maker Code
Game Code
Fixed Value
Each of these bytes should be #$00.
Expansion RAM Size
Common values: #$00 - none, #$01 - 2KB, #$03 - 8KB, #$05 - 32KB, #$06 - 64KB, #$07 - 128KB
Special Version
Should be #$00.
Game Title Specification
The game title is 21 bytes long, encoded with the JIS X 0201 character set (which consists of standard ASCII plus katakana). If the title is shorter than 21 bytes, then the remainder should be padded with spaces (0x20).
Cartridge Configuration
Map Mode
Common values: #$20 - 2.68MHz LoROM, #$21 - 2.68MHz HiROM, #$23 - SA-1; #$25 - 2.68MHz ExHiROM; #$30 - 3.58MHz LoROM, #$31 - 3.58MHz HiROM; #$35 - 3.58MHz ExHiROM
Cartridge Type
Common values: #$00 - ROM only; #$01 - ROM and RAM; #$02 - ROM, RAM and battery; #$33 - ROM and SA-1; #$34 - ROM, SA-1 and RAM; #$35 - ROM, SA-1, RAM and battery
Sub-Number
ROM Size
2^(this value) would be the size of the ROM in kilobytes. For example, for 512KB, this should be #$09.
RAM Size
2^(this value) would be the size of the SRAM (if present) in kilobytes. Maximum supported value is #$07.
Destination Code
Where the game is intended to be sold. Common values: #$00 - Japan; #$01 - USA; #$02 - Europe (enables 50fps PAL mode)
Mask ROM Version
ROM Verification
Complement Check
This is the 16-bit complement (bit-inverse) of the checksum. This is used so that the checksum value cancels itself out when calculating the real checksum.
Check Sum
This is simply the 16-bit sum of all bytes in the ROM. For power-of-2-sized ROMs, no mirroring is used, each byte of ROM is counted exactly once.
For non-power-of-2-sized ROMs (e.g. 2.5MB or 6MB), first the checksum for the largest power-of-2 area smaller than the ROM size (so 4MB for 6MB ROMs, 2MB for 2.5MB ROMs) is computed normally. Then the remaining part is repeated until it's the same size as the first part (so the last 2MB of a 6MB ROM is repeated once so both halves are 4MB, and the last 512KB of a 2.5MB ROM is repeated 4 times so both halves are 2MB). Then its checksum is computed and the checksums of the 2 halves are added to get the final checksum.
CPU Exception Vectors
The vectors from $00:FFE0-$00:FFEF are used when the SNES is running in native mode, while the vectors from $00:FFF0-$00:FFFF are used when the SNES is running in emulation mode. Note that ABORT is technically unused, but listed for completion.
Also note that the vectors are only 16 bits wide, so they can only jump to addresses within bank $00. If you want to jump to a different bank, or you need FastROM addressing, point them to a JML instruction. With WRAM being mapped at $0000-$1FFF on bank $00, it's possible to point them on that range, being an interesting option for run-time code modification.
Certain enhancement chips like SA-1 and Super FX can override the CPU vectors on special occasions.
Address | Length | Mode | Vector |
---|---|---|---|
$00:FFE0 | 4 bytes | Native | unused |
$00:FFE4 | 2 bytes | Native | COP |
$00:FFE6 | 2 bytes | Native | BRK |
$00:FFE8 | 2 bytes | Native | ABORT |
$00:FFEA | 2 bytes | Native | NMI |
$00:FFEC | 2 bytes | Native | unused (would be RESET, but the SNES always boots in Emulation mode) |
$00:FFEE | 2 bytes | Native | IRQ |
$00:FFF0 | 4 bytes | Emulation | unused |
$00:FFF4 | 2 bytes | Emulation | COP |
$00:FFF6 | 2 bytes | Emulation | unused (would be BRK, but BRK and IRQ share the same vector in Emulation mode) |
$00:FFF8 | 2 bytes | Emulation | ABORT |
$00:FFFA | 2 bytes | Emulation | NMI |
$00:FFFC | 2 bytes | Emulation | RESET |
$00:FFFE | 2 bytes | Emulation | IRQ/BRK |