ROM header reference

The ROM header comes after the 68000 vectors and spans the $100-$1FF range. The header includes some information such as the name of the game, or when it was released, or whether it can save, etc. Sometimes emulators may also read parts of the header looking for some information (e.g. what to put on the titlebar or what peripherals to emulate by default).

ROM header format
$10016 bytesSystem type
$11016 bytesCopyright and release date
$12048 bytesGame title (domestic)
$15048 bytesGame title (overseas)
$18014 bytesSerial number
$18E2 bytesROM checksum
$19016 bytesDevice support
$1A08 bytesROM address range
$1A88 bytesRAM address range
$1B012 bytesExtra memory
$1BC12 bytesModem support
$1C840 bytes(reserved, fill with spaces)
$1F03 bytesRegion support
$1F313 bytes(reserved, fill with spaces)

System type

What system the game is running on, padded with spaces. For the Mega Drive, it usually would be "SEGA MEGA DRIVE" or "SEGA GENESIS". Some flashcarts enable extra functionality if a specific text is found here.

This is the only part of the header a console pays attention to. If it doesn't find the initial "SEGA" text in this field, systems with TMSS will refuse to boot the game.

All known system types so far:

List of system types
"SEGA 32X"Mega Drive + 32X
"SEGA EVERDRIVE"Mega Drive (Everdrive extensions)
"SEGA SSF"Mega Drive (Mega Everdrive extensions)
"SEGA MEGAWIFI"Mega Drive (Mega Wifi extensions)
"SEGA TERA68K"Tera Drive (boot from 68000 side)
"SEGA TERA286"Tera Drive (boot from x86 side)

A field with the format "(C)XXXX YYYY.ZZZ", where:

Parts of the copyright field
"YYYY"Release year
"ZZZ"Release month

The "XXXX" part is a four-character abbreviation that identifies the publisher. Sega used to assign these codes (leading to the T-series numbers) but of course they don't anymore, so pick a four letter abbreviation that identifies you and is unlikely to clash.

The release date is the four-digit year and a three-letter month abbreviation (just take the first three letters of the month's name and make them uppercase).

    dc.b  '(C)SEGA 1992.NOV'  ; Sonic 2's copyright!

Game title

What it says. Usually in all uppercase, pad the field with spaces.

There are two title fields (to account for the fact that games may change name during localization), if you just keep the name the same everywhere then use it in both fields.

    dc.b  'CHAMPION FINGER WRESTLING'  ; Domestic title
    dcb.b $150-*, ' '                  ; (padding)
    dc.b  'CHAMPION FINGER WRESTLING'  ; Overseas title
    dcb.b $180-*, ' '                  ; (padding)

This is the only field where text is not required to be ASCII: you're allowed to use Shift-JIS characters as well.

Serial number

A field with the format "XX YYYYYYYY-ZZ", where:

Parts of the serial number field
"XX"Software type
"YYYYYYYY"Serial number

The software type indicates what kind of software is in the cartridge (usually "GM", for game). The full list of known types so far is:

List of software types
"BR"Boot ROM (Sega CD)

The serial number is an identifier unique to the game that used to be assigned by Sega. Try to pick something that's unlikely to clash (maybe something using the publisher code from the copyright field to make it even more unlikely) and stick to it.

The revision is a two-digit number indicating which release of the game is this. The initial release is "00", the first patch is "01", next one is "02", etc.

    dc.b  'GM 00001051-00'  ; Serial number

ROM checksum

A 16-bit value that holds a checksum. Some games check the ROM to see if the checksum matches, and some emulators may also do it and complain if the checksum is bad, but otherwise it does nothing.

You can compute the checksum by adding up every 16-bit word from address $000200 up to the end of the ROM (keep only the lower bits).

Device support

A list of devices or other features the game supports. One letter per device, the unused space is filled in with spaces. It's usually "J" (3 button controller) or "J6" (3 and 6 button controllers).

Note that 6-button controllers only need to be added to the list if the game actually makes uses of the extra buttons. Do not add it to simply indicate that the game will work with those controllers.

    dc.b  'J6'         ; Device support
    dcb.b $1A0-*, ' '  ; (padding)

The full list is this:

List of devices
"J"3-button controller
"6"6-button controller
"0"Master System controller
"A"Analog joystick
"K"Keyboard or keypad
"C"CD-ROM (Sega CD)
"F"Floppy drive

ROM address range

Two 32-bit values, indicating the address range covered by the cartridge. The first value is always $000000, while the last value is usually the ROM size minus one (unless you're using a mapper, then use the last address the console will see).

    dc.l  $000000    ; ROM start address
    dc.l  RomSize-1  ; ROM end address

Some common ROM sizes you may see:

Last address for common ROM sizes
Last addressROM size

RAM address range

Two 32-bit values, indicating where RAM starts and ends. In the case of the Mega Drive, they should be always $FF0000 and $FFFFFF.

    dc.l  $FF0000  ; RAM start address
    dc.l  $FFFFFF  ; RAM end address

Extra memory

This field indicates if there's extra memory (e.g. for saving progress, or simply extra RAM to toy with). The contents of this field depends on what's in the cartridge.

If there's no extra memory

If the game doesn't have extra memory, fill it with spaces.

If it has SRAM or FRAM

If the game does have extra RAM, the field is as follows:

SRAM field format
2 bytesAlways "RA"
1 byteRAM type
1 byteAlways $20
4 bytesStart address
4 bytesEnd address

The RAM type is used to indicate whether the data is saved when turning off the console and what kind of accesses (byte or word) are allowed:

List of SRAM types
$B0No8-bit (even addresses)
$B8No8-bit (odd addresses)
$F0Yes8-bit (even addresses)
$F8Yes8-bit (odd addresses)

The start and end addresses specify the first and last addresses where SRAM shows up.

    dc.b 'RA',$F8,$20    ; SRAM type
    dc.l $200001         ; SRAM start address
    dc.l $20FFFF         ; SRAM end address

If it has EEPROM

If the game has EEPROM instead, the field should look like this (not much room to change aside from the addresses, which should indicate on which range EEPROM is accessible):

    dc.b 'RA',$E8,$40    ; EEPROM type
    dc.l $200001         ; EEPROM start address
    dc.l $200001         ; EEPROM end address

Sadly, this doesn't include information about the way the EEPROM is wired, and different publishers opted for different ways to wire it.

Modem support

If the modem is not supported, pad with spaces.

If the modem is supported, it's a field with the format "MOxxxxyy,zww" (yes, comma), where:

Parts of the modem field
"yy"Game number
"ww"Region and microphone

The publisher is the same one as in the copyright field.

The "yy,z" make a game number and version. Games with the same "number" are compatible i.e. can talk to each other, even if they come from completely different publishers. The "version" is used to distinguish between them ("0" for the original, then "1", "2", etc.). This value was assigned by Sega of Japan back then.

The "ww" part indicates region support and whether the game supports the microphone (yes, voice chat in the early '90s). The possible values are:

Possible support values in the modem field
00Yes (no mic.)No
10Yes (with mic.)No
20NoYes (no mic.)
30NoYes (with mic.)
40Yes (no mic.)Yes (no mic.)
50Yes (with mic.)Yes (with mic.)
60Yes (no mic.)Yes (with mic.)
70Yes (with mic.)Yes (no mic.)

"80" and "90" are also mentioned as possible values, but they aren't described so they may have been reserved.

Iwis says

Some games seemed to use a point instead of a comma (i.e. "MOxxxxyy.zww") so it's possible both were valid.

Region support

A list of all the regions the game supports (one letter per region). This field had two formats over the Mega Drive's lifespan: the original format (we'll call it "old style") is the most well known and is one letter per region. The later format (we'll call it "new style") uses a single character to store information about all regions.

We recommend sticking to the original "old style" format in homebrew.

Old style

The most well known format, it stores one letter per region. If not all the regions are used then pad the field with spaces. The regions can come in any order. To support all three regions just use "JUE".

    dc.b  "JUE"  ; All regions

If e.g. only Japanese systems are supported (note the spaces):

    dc.b  "J  "  ; Japan-only

The regions are these:

List of regions

If you're writing code to check a game's region, bear in mind that in a few cases the spaces are in the middle or beginning, not just at the end! Always check all three bytes.

New style

At some point Sega switched to a different region format. This format uses a single character (padding the rest with spaces). The character in question is a hexadecimal digit… in ASCII (yeah, really).

The digit in question is a 4-bit value where every bit represents a supported region:

Format of region bitfield (new style format)
Bit 0+1Domestic, 60HzJapan, South Korea, Taiwan
Bit 1+2Domestic, 50Hz—
Bit 2+4Overseas, 60HzNorth America, Brazil
Bit 3+8Overseas, 50HzEurope, Hong Kong

All possible combinations are as follows:

List of region combinations (new style format)

Iwis says

Yes, this means that "E" is ambiguous, since in the old style it means Europe only, but in the new style it means everywhere but Japan. In practice you're unlikely to find it in the new style (since it includes the "invalid" region for no real reason), so you can assume it really means Europe.