GBX v1.0 has now been finalised!
This proposal is now outdated and is retained here for historical purposes only.
The v1.0 spec can be found here.
🦁 by taizou 🦁 (web / email / twitter)
Comments welcome here!
Last updated: 21st February 2018
GBX = Game Boy Xtended (仮)
The current and only standard for Game Boy and Game Boy Color ROM images (.GB/.GBC) is simply a raw binary dump of the cartridge ROM.
Current Game Boy emulation bases cartridge type detection largely on the internal ROM header. In licensed games, this is always populated per Nintendo's specs. But in unlicensed games, it often isn't. Likewise for some licensed special carts, notably multicarts.
Until now, emulators have had to rely on heuristics to work out if they're dealing with something non-standard. This was workable when only a few such cartridges had been dumped and emulated, but now many more have been discovered (numbering in at least the low hundreds), with more unique mappers and copy protection schemes, it's becoming increasingly unwieldy.
Even when a game in actuality uses a standard mapper, when the internal header is incorrect, the only way to make most emulators recognise it is to hack that header, thus destroying the integrity of the original data.
So I'm proposing a fairly simple file format to allow this information to be specified somewhere outside of the ROM data itself.
A GBX ROM image file will consist of the following:
Recommended file extension: .gbx
Reasons for using a footer instead of a header (commonly used by other ROM formats):
Basically my aim is to make this fairly unintrusive and low-overhead, since I know it'll be a niche/low-uptake thing at this late stage in Game Boy emulation, especially given that plain binary dumps are satisfactory for 99.5% of licensed releases and the cases for a new format are relatively obscure.
TBC: Maybe a plain binary could be considered a valid '0.0' GBX file, meaning 'this is a regular licensed game and the internal header is valid, defer to it'
The footer defines any cartridge metadata required for emulation.
|Offset from end of ROM data (hex)||Use||Type/value||More info|
|00-03||Mapper identifier||Any string of up to 4 bytes||No strict limitations on what a mapper identifier can be, but something readable
in ASCII is recommended.
If the identifier is less than 4 bytes, the remaining bytes should be 00.
See section 4 below for an initial set of mapper identifiers.
|04||Battery flag||00 = not present 01 = present|
|05||Rumble flag||00 = not present 01 = present|
|06||Timer flag||00 = not present 01 = present|
|08-0B||ROM size in bytes||32-bit unsigned little-endian integer||Any number may be specified here, but it's reasonable for an emulator to reject a size that is not valid for the specified mapper.|
|0C-0F||RAM size in bytes||32-bit unsigned little-endian integer||As above|
|10-2F||Eight mapper specific variables||8 x 32-bit anything||May be used in any way by a mapper that requires some further information to be specified e.g. if it has some configurable features or component that may or may not be present.|
|30-33||Footer size in bytes||32-bit unsigned little-endian integer.
For this version it should be 40 hex / 64 decimal.
|34-37||Major version number||32-bit unsigned little-endian integer.
For this version it should be 0.
|This number will only be increased if a change introduces a backwards
e.g. if a program supports v1.x and it finds a 2 here, it should probably reject the file.
|38-3B||Minor version number||32-bit unsigned little-endian integer.
For this version it should be 3.
|Minor versions should always be backwards compatible. A size change should not qualify as a backwards incompatibility.|
|3C-3F||Signature||GBX! in ASCII||RIP to the lion who used to live here|
The values at 30-3F in this version shouldange will always be placed at the end of the footer block in future versions, meaning you can always read the last 4 bytes of a file to determine if it's GBX format, and the preceding 12 to determine if it's a supported version and how big the footer is.
Note the footer is not intended to store metadata about the game itself, such as title, release date or publisher, whether it has Super Game Boy or Game Boy Color support, etc.
MMMM FFFF RRRR SSSS MMMM = mapper, FFFF = flags, RRRR = romsize, SSSS = ramsize 1111 2222 3333 4444 mapper-specific variables 5555 6666 7777 8888 mapper-specific variables SSSS MMMM VVVV GBX! SSSS = footer size, MMMM = major version, VVVV = minor version, GBX! = signature
4D 42 43 35 01 01 00 00 00 10 00 00 00 00 20 00 MBC5, ram+rumble, 1M ROM, 8K RAM 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 empty mapper-specific variables 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 empty mapper-specific variables 00 00 00 40 00 00 00 01 00 00 00 00 47 42 58 21 64k footer, minor v1, major v0, signature
Note the term "mapper" here is used in the NES emulation sense, e.g., any circuitry onboard the cartridge controlling mapping of ROM & RAM and potentially other components such as a rumble motor or tilt sensor. Game Boy cartridges usually contain a custom ASIC (commonly known as "MBC" after the five standard Nintendo chips) for this purpose.
|MBC7||Nintendo MBC7 (Tilt sensor cart)|
|MB1M||Nintendo MBC1 multicart|
|CAMR||Nintendo Game Boy Camera (Pocket Camera)|
|NTO1||NT older type 1|
|NTO2||NT older type 2|
|LBMC||"Last Bible" multicart|
- the end -