Internal ROM Header

From Snesdev wiki
Revision as of 15:20, 14 March 2019 by Sour (talk | contribs) (Destination code)
Jump to navigation Jump to search

SOURCE: http://old.smwiki.net/wiki/Internal_ROM_Header

The internal header defines the original cartridge layout of the ROM in addition to miscellaneous information about the developer and ROM. This includes: ROM size, SRAM size, enhancement chips, internal ROM name and so on...

Technical information

The internal header is located in one of two areas in ROM based on the map mode (almost every SNES game can be categroized as pure 'LoROM' or purely 'HiROM'). It appears at 7FB0 in LoROM games and FFB0 in HiROM games when viewing in a hex editor. The emulator uses fairly reliable heuristics to guess the map mode and very rarely gets it wrong. An incorrect guess by the emulator is instantly noticeable with a garbage string in the internal ROM name. This normally indicates a corrupted internal header.

The internal header is located in bank $00 in both LoROM and HiROM images and are seen by the processor in the same area, although the different map modes mean in a hex editor they are located in one of two addresses mentioned above. The below offsets assume LoROM offsets, subtract 0x8000 of these to get the equivalent address in a hex editor. The last 80 bytes of bank $00 is the internal ROM header, where the very last 32 bytes are the Vector Info.


ROM Registration Data

#SNES AddressPC Address (headered)LengthName
1$00:FFB00x0081B02 bytesMaker code
2$00:FFB20x0081B24 bytesGame code
3$00:FFB60x0081B67 bytesFixed Value ($00)
4$00:FFBD0x0081BD1 byteExpansion RAM size
5$00:FFBE0x0081BE1 byteSpecial version
6$00:FFBF0x0081BF1 byteCartridge type


ROM Specifications

#SNES AddressPC Address (headered)LengthName
7$00:FFC00x0081C021 bytesInternal ROM Name
8$00:FFD50x0081D51 byteMap Mode
9$00:FFD60x0081D61 byteROM Type
10$00:FFD70x0081D71 byteROM Size
11$00:FFD80x0081D81 byteSRAM Size
12$00:FFD90x0081D91 byteDestination code
13$00:FFDA0x0081DA1 byteFixed value ($33)
14$00:FFDB0x0081DB1 byteVersion #
15$00:FFDC0x0081DC2 bytesComplement check
16$00:FFDE0x0081DE2 bytesChecksum

Here I won't explain the vectors and their uses. Please refer to the Vector Info instead.

ROM Registration Data

This area contains minor stuff about the ROM, such as maker code, game code, and so on. It does NOT affect emulation.

Maker code

This can be anything, as long as it is 2 bytes long

Game code

Same as above, except it should be 4 bytes long. It could be "SNES", "GAME", "FIRE", "W00T", and so on...

Fixed value

Self-explanatory. It should stay locked at $00

Expansion RAM size

Here, it gets more complicated. It should be the RAM size of the RAM an enhancement chip uses. Otherwise, it should be $00. It has these possible values: $00, $01, $03, $05, $06, $07 Which is... None, 16Kbit, 64Kbit, 256Kbit, 512Kbit, 1Mbit.

Special Version

Used only at certain circumstances, such as a promotional event. Otherwise it should stay $00.

Cartridge type

Used to distinguish the cartridge from cartridges with the same type. Should stay at $00.

ROM Specifications

These settings actually affect emulation, so be careful while editing them.

Game title

This has the internal ROM name in ASCII. It should be 21 characters long. It appears during the loading of the ROM in emulators (often with uppercase letters). If the name does not fill the entire 21 character range, the remaining space is padded with spaces.

Map Mode

This byte determines how the mapping should be in the ROM image. It also determines if the ROM is a FastROM or not. Format of the byte: xxAAxxxB. If both A bits are set, FastROM is set. If B is set, the ROM is HiROM. x = Most likely unused.

ROM type

This determines what the ROM has, such as SRAM, RAM, and enhancement chips. For ROMs without an enhancement chip, these are the possible values: $00, $01, $02 Which is: ROM Only, ROM + RAM, ROM + RAM + SRAM

For ROMs with an enhancement chip: $0*, $1*, $2*, $3*, $E*, $F* Which is: DSP, SuperFX, OBC1, SA-1, other, custom chip

And we have $*3, $*4, $*5, $*6 Which is: ROM + Enhancement Chip, ROM + Enhancement Chip + RAM, ROM + Enhancement Chip + RAM + SRAM, ROM + Enhancement Chip + SRAM. Combining the two numbers will give you different ROM types. If you want SuperFX with only ROM + chip, you need to input value $13.

ROM Size

This determines the internal ROM size, which is essential when you want to access other banks. There are five possible values: $09,$0A,$0B,$0C,$0D Which is: 3~4MBit, 5~8MBit, 9~16Mbit, 17~32MBit, 33~64MBit. Alternatively, to calculate the size: Amount of bytes = 2048^decimal value

SRAM Size

This byte determines the size of the .srm file (SRAM). To calculate the size: Amount of kilobytes = 2048*2^decimal value

Destination code

This determines where the product will be sold.

Region Code Type
Japan $00 NTSC
North America $01 NTSC
Europe $02 PAL
Sweden/Scandinavia $03 PAL
Finland $04 PAL
Denmark $05 PAL
France $06 SECAM (PAL-like, 50 Hz)
Netherlands $07 PAL
Spain $08 PAL
Germany $09 PAL
Italy $0A PAL
China $0B PAL
Indonesia $0C PAL
Korea $0D NTSC
Global (?) $0E ?
Canada $0F NTSC
Brazil $10 PAL-M (NTSC-like, 60 Hz)
Australia $11 PAL
Other (1) $12 ?
Other (2) $13 ?
Other (3) $14 ?

Fixed value

Self-explanatory. Fixed at $33.

Version #

Version number of your ROM image. 1.0 for initial releases, increased as a developer makes changes.

Complement check

The complement (bitwise NOT) value of the checksum of the ROM.

Checksum

The sum of all bytes in the ROM after a bitwise AND with the value 0xFFFF