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).
|16 bytes||System type|
|16 bytes||Copyright and release date|
|48 bytes||Game title (domestic)|
|48 bytes||Game title (overseas)|
|14 bytes||Serial number|
|2 bytes||ROM checksum|
|16 bytes||Device support|
|8 bytes||ROM address range|
|8 bytes||RAM address range|
|12 bytes||Extra memory|
|12 bytes||Modem support|
|40 bytes||(reserved, fill with spaces)|
|3 bytes||Region support|
|13 bytes||(reserved, fill with spaces)|
What system the game is running on, padded with spaces. For the Mega
Drive, it usually would be "
SEGA MEGA DRIVE" or "
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:
|"||Mega Drive + 32X|
|"||Mega Drive (Everdrive extensions)|
|"||Mega Drive (Mega Everdrive extensions)|
|"||Mega Drive (Mega Wifi extensions)|
|"||Tera Drive (boot from 68000 side)|
|"||Tera Drive (boot from x86 side)|
Copyright and release date
A field with the format "
(C)XXXX YYYY.ZZZ", where:
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!
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.
A field with the format "
XX YYYYYYYY-ZZ", where:
The software type indicates what kind of software is in the cartridge
GM", for game). The full list of known types so
|"||Boot ROM (TMSS)|
|"||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 "
dc.b 'GM 00001051-00' ; Serial number
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
$000200 up to the end of the ROM (keep only the
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:
|"||Master System controller|
|"||Keyboard or keypad|
|"||CD-ROM (Sega CD)|
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
dc.l $000000 ; ROM start address dc.l RomSize-1 ; ROM end address
Some common ROM sizes you may see:
|Last address||ROM 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
dc.l $FF0000 ; RAM start address dc.l $FFFFFF ; RAM end address
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:
|2 bytes||Always "|
|1 byte||RAM type|
|1 byte||Always |
|4 bytes||Start address|
|4 bytes||End 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:
|No||8-bit (even addresses)|
|No||8-bit (odd addresses)|
|Yes||8-bit (even addresses)|
|Yes||8-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.
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:
|"||Region and microphone|
The publisher is the same one as in the copyright field.
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
2", etc.). This value was assigned by
Sega of Japan back then.
ww" part indicates region support and whether the game
supports the microphone (yes, voice chat in the early '90s). The possible
|Yes (no mic.)||No|
|Yes (with mic.)||No|
|No||Yes (no mic.)|
|No||Yes (with mic.)|
|Yes (no mic.)||Yes (no mic.)|
|Yes (with mic.)||Yes (with mic.)|
|Yes (no mic.)||Yes (with mic.)|
|Yes (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.
Some games seemed to use a point instead of a comma (i.e.
MOxxxxyy.zww") so it's possible both were valid.
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.
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 "
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:
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.
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:
|Bit 0||+1||Domestic, 60Hz||Japan, South Korea, Taiwan|
|Bit 1||+2||Domestic, 50Hz||—|
|Bit 2||+4||Overseas, 60Hz||North America, Brazil|
|Bit 3||+8||Overseas, 50Hz||Europe, Hong Kong|
All possible combinations are as follows:
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.