The first 512 bytes (0x000–0x1FF) of the ROM. The fields are from GBATEK
(“DS Cartridge Header”), checked against the header structure of the DeSmuME emulator. All numbers
are little-endian.
Fields
| Offset | Size | Field | What it holds |
|---|---|---|---|
0x000 | 12 | Game title | Upper-case ASCII, padded with 0x00. |
0x00C | 4 | Game code | Upper-case ASCII; zero in homebrew. |
0x010 | 2 | Maker code | Upper-case ASCII, for example 01 for Nintendo; zero in homebrew. The viewer shows the characters and does not name the publisher. |
0x012 | 1 | Unit code | 0x00 Nintendo DS, 0x02 Nintendo DS and DSi, 0x03 Nintendo DSi; bit 1 means the DSi. |
0x013 | 1 | Encryption seed select | 0x00 to 0x07, usually 0x00. |
0x014 | 1 | Device capacity | The chip size is 128 KiB shifted left by this number (7 is 16 MiB). |
0x015 | 7 | Reserved | Zero. |
0x01C | 1 | Reserved | Zero, except on the DSi. |
0x01D | 1 | Region | 0x00 normal, 0x80 China, 0x40 Korea; the DSi uses other values. |
0x01E | 1 | ROM version | Usually 0x00. |
0x01F | 1 | Autostart | Bit 2 skips the “Press Button” screen after the Health and Safety screen, and the boot menu. |
The two programs
| Offset | Size | Field | What it holds |
|---|---|---|---|
0x020 | 4 | ARM9 ROM offset | 0x4000 and up, aligned to 0x1000. |
0x024 | 4 | ARM9 entry address | 0x02000000 to 0x023BFE00. |
0x028 | 4 | ARM9 RAM address | 0x02000000 to 0x023BFE00: where the program is copied to. |
0x02C | 4 | ARM9 size | At most 0x3BFE00. |
0x030 | 4 | ARM7 ROM offset | 0x8000 and up. |
0x034 | 4 | ARM7 entry address | 0x02000000 to 0x023BFE00, or 0x037F8000 to 0x03807E00. |
0x038 | 4 | ARM7 RAM address | The same ranges. |
0x03C | 4 | ARM7 size | At most 0x3BFE00, or 0xFE00 in the second range. |
The viewer disassembles each program from the file offset, as if it were loaded at its RAM address. The instruction set of each is chosen in the options bar, because the file cannot say.
File tables, overlays, banner
| Offset | Size | Field | What it holds |
|---|---|---|---|
0x040 | 4+4 | File name table (FNT) offset and size | The names of the directories and files. See NitroFS. |
0x048 | 4+4 | File allocation table (FAT) offset and size | The start and end of every file, 8 bytes a file. |
0x050 | 4+4 | ARM9 overlay table offset and size | 32 bytes an overlay. |
0x058 | 4+4 | ARM7 overlay table offset and size | 32 bytes an overlay. |
0x060 | 4 | Gamecard setting, normal commands | The value for port 0x040001A4, usually 0x00586000. |
0x064 | 4 | Gamecard setting, KEY1 commands | Usually 0x001808F8. |
0x068 | 4 | Banner offset | 0 is none, otherwise 0x8000 and up. See Banner. |
0x06C | 2 | Secure area checksum | CRC-16 of the bytes from the ARM9 ROM offset to 0x7FFF. |
0x06E | 2 | Secure area delay | In 131 kHz units: 0x051E is 10 ms, 0x0D7E is 26 ms. |
0x070 | 4 | ARM9 auto-load hook | RAM address; GBATEK marks its meaning as uncertain. |
0x074 | 4 | ARM7 auto-load hook | As above. |
0x078 | 8 | Secure area disable | The text “NmMdOnly”, encrypted; usually zero. |
0x080 | 4 | Total used ROM size | The rest of the chip is usually filled with 0xFF. |
0x084 | 4 | Header size | 0x4000. |
0x088 | 4 | Unknown | A ROM offset or zero (the DSi differs). DeSmuME reads 0x088 and 0x08C as the ARM9 and ARM7 module parameter addresses. |
0x08C | 8 | Reserved | Zero (0x088–0x093 are used on the DSi). |
0x094 | 2+2 | NAND end of ROM area, start of RW area | For the DSi. |
0x098 | 24 | Reserved | Zero. |
0x0B0 | 16 | Reserved | Zero (or the text “DoNotZeroFillMem”, set by a boot loader). |
Logo and checksums
| Offset | Size | Field | What it holds |
|---|---|---|---|
0x0C0 | 156 | Nintendo logo | The compressed bitmap, the same 156 bytes as in a Game Boy Advance header. |
0x15C | 2 | Logo checksum | CRC-16 of 0x0C0–0x15B; the BIOS requires the value 0xCF56. |
0x15E | 2 | Header checksum | CRC-16 of 0x000–0x15D. |
0x160 | 4+4+4 | Debug ROM offset, size, RAM address | 0 is none. |
0x16C | 4 | Reserved | Zero. |
0x170 | 144 | Reserved | Zero. |
GBATEK says the BIOS checks only that the logo checksum field is 0xCF56, and that the firmware checks the logo bytes.
The CRC-16
The checksums are the CRC-16 of the BIOS function GetCRC16: the initial value is 0xFFFF and the polynomial is
0xA001, used reflected (the same as CRC-16/MODBUS). GBATEK names the function but does not print the parameters. They are
confirmed here three ways: the 156 logo bytes give 0xCF56, the value GBATEK gives; DeSmuME’s own table-driven version of the BIOS
function gives the same result as the bit-by-bit one on random data; and a small homebrew ROM’s builder uses the same parameters.
The secure area
The bytes 0x4000–0x7FFF are the secure area. Its first 8 bytes are an ID. In an unencrypted image they read
“encryObj”; on a card they are stored encrypted. After the BIOS has decrypted the area and found “encryObj” it overwrites the 8 bytes with
0xE7FFDEFF twice, so a memory dump of a running DS shows that value instead. The viewer reports which of three states the file
is in, as a fact: the ID reads “encryObj”, the ID has been overwritten, or neither (encrypted, or not a secure area). It does not decrypt anything.
DSi
A unit code with bit 1 set means a DSi game (or a DS game with DSi features). The DSi adds a second header from 0x200 that the
viewer does not read; it reports that the unit code says so.