Skip to content
Rune Tynan edited this page Apr 10, 2019 · 5 revisions

This is a currently in-progress understanding of how NDS files are formatted to help guide me along the process of making this program functional. A lot of information regarding the header and the basics of the NitroROM File System where thanks to this guide.

Overview

This is an overview of how the NDS format looks on a very basic level. Values that are stored in the header will be noted as Header (offset). They are 4 byte little endian integers unless otherwise noted.

Name Purpose Start Size
Header Stores information about the file 0h 200h
Padding Zero padding until 4000h 200h 3E00h
ARM9 ROM ARM9 boot code (?) Header 20h Header 2Ch
ARM9 Overlay ARM9 overlay table Header 50h Header 54h
Overlay Files (?) Overlay entries placed here (?) ? ?
ARM7 ROM ARM7 boot code (?) Header 30h Header 3Ch
ARM7 Overlay ARM7 overlay table Header 58h Header 5Ch
File Name Table Directory and file name information Header 40h Header 44h
File Allocation Table File offset information Header 48h Header 4Ch

Notes

ARM code and padding

After the header is zero padding up to the 4000h byte mark. This is because ARM9 code must start at at least 4000h into the file and must be on a 1000h byte mark. ARM7 code should be at least at 8000h and also be on a 1000h byte mark, although there are working examples where it is on a 100h byte mark instead.

Padding after the header is usually filled with zeroes, but in many other places in the file FFh is used for padding instead. For example, when padding the file to the nearest power of two size FFh is used instead of 00h.

Overlays

Overlay files can be found in a ROM by finding the starting file id in the root node of the FNT. Any entry in the FAT that falls under the starting file id is an overlay file. These files vary in size and as of now their purpose is unknown. From my testing it seems it is best to put the overlay files exactly where they used to be in the file by reading the old FAT.

Here is a pseudo code example:

int start_file_id = FNT.root().file_id();

for (int i = 0; i < start_file_id; i++)
{
  //  Get FAT entry at index i and use it to read the overlay from the ROM
}

Header

Address Bytes Explanation
000h 12h Game Title
00Ch 4h Gamecode
010h 2h Makercode
012h 1h Unitcode
013h 1h Encryption Seed Select
014h 1h Devicecapacity
015h 9h Reserved
01Eh 1h ROM Version
01Fh 1h Autostart
020h 4h ARM9 rom_offset
024h 4h ARM9 entry_address
028h 4h ARM9 ram_address
02Ch 4h ARM9 size
030h 4h ARM7 rom_offset
034h 4h ARM7 entry_address
038h 4h ARM7 ram_address
03Ch 4h ARM7 size
040h 4h File Name Table
044h 4h File Name Table
048h 4h File Allocation Table
04Ch 4h File Allocation Table
050h 4h File ARM9 overlay_offset
054h 4h File ARM9 overlay_size
058h 4h File ARM7 overlay_offset
05Ch 4h File ARM7 overlay_size
060h 4h Port 40001A4h setting for normal commands
064h 4h Port 40001A4h setting for KEY1 commands
068h 4h Icon_title_offset
06Ch 2h Secure Area Checksum, CRC-16 of [ [20h]..7FFFh]
06Eh 2h Secure Area Loading Timeout
070h 4h ARM9 Auto Load List RAM Address
074h 4h ARM7 Auto Load List RAM Address
078h 8h Secure Area Disable
080h 4h Total Used ROM size
084h 4h ROM Header Size
088h 38h Reserved
0C0h 9Ch Nintendo Logo
15Ch 2h Nintendo Logo Checksum (CF56h)
15Eh 2h Header Checksum, CRC-16 of [000h-15Dh]
160h 4h Debug rom_offset
164h 4h Debug size
168h 4h Debug ram_address
16Ch 4h Reserved
170h 90h Reserved
Clone this wiki locally