DOLDVDFormat
From Rare Gaming Dump
Jump to navigationJump to search
GameCube Disc Format aka NROM(Read-only) or NR-Disc(Recordable)
Please Note this is a work in progress doc.
DVD Sector Scrambling(XOR) is done using Disk ID(8 bytes) and a Random Number by the Disk Controller Firmware, it is stored on a 128KB on-chip ROM System Controller firmware uses a ROM 128KB chip.
Panasonic MN103S (32bit), 54MHz is the Disk Controller(ECC, EFM\EFM+, Drive IC Control, Descrambler, XADPCM Decoding) Panasonic MN102H (16bit), 33Mhz is the System Controller(System Manager, Copy protection, Handles Commands)
The development tools used to develop for these Panasonic microcontrollers is called Debug Factory 3, it comes with a toolchain that has compiler, linker, assembler.

In the firmware the text "Nintendo Game Disk" can be found this is the Media ID 19 byte string that is used as meta data in the lead-in area of the DVD. MN102H looks for this string to check if the disc type is a GameCube\Wii Game Disc. It's also does the BCA copy protection check.
Notes
========================================
NROM BOOTABLE PRESSED DISC GUIDE
GameCube / Original Wii (GC Mode)
========================================
1. CONTROL DATA ZONE (CDZ) - Mandatory for boot
------------------------------------------------
Sector size: 2048 bytes
PHYSICAL FORMAT INFORMATION
---------------------------
Bytes (BP) Name Value / Notes
0-5 Reserved Any value (zeros fine)
6 NGC Identifier 0xFF (must)
7 Disc size & min transfer rate 0x12 (fixed)
8 Disc structure 0x01 (fixed)
9 Recorded density 0x00 (fixed)
10-21 Data area allocation Start sector = 0x030000
End sector = 0x0DE0AF
22-2047 Reserved Any value (zeros or filler)
Dummy area Reserved 6 bytes
DISC MANUFACTURING INFORMATION
------------------------------
Bytes (BP) Name Value / Notes
0-5 Reserved Any value
6-11 Secret Optional, any value
12-13 Random number Optional
14-15 Secret Optional
16-21 Random number Optional
22-40 Media ID ASCII: "Nintendo Game Disk" (must match exactly)
41-47 Random number Optional
48 Book type / Part version 0x01 (must)
49 Disc size / min readout 0x12 (must)
50 Disc structure 0x01 (must)
51 Recorded density 0x00 (must)
52-63 Data area allocation Start = 0x030000, End = 0x0DE0AF
64 BCA descriptor 0x80 (must)
65-2047 Reserved Any value
Dummy area Reserved 6 bytes
Notes:
- Only BP6, BP7-BP9, BP48-BP51, BP52-BP63, BP64, and Media ID are critical.
- All "secret" or "random number" fields are optional filler.
2. DISCID - Mandatory
---------------------
- 8 bytes total: game_code[4] + corp_code[2] + disc_number + version
- Example:
game_code = "ABCD"
corp_code = "01"
disc_number = 0x01
version = 0x00
- DiscID is used to select XOR scrambler preset index.
3. USER AREA - Mandatory, XOR Scrambled
----------------------------------------
- Start sector: 0x030000
- End sector: 0x0DE0AF
- Sector size: 2048 bytes
XOR Scrambling (NROM style):
- Preset table (16 numbers):
0: 3, 1: 48, 2: 32512, 3: 28673
4: 6, 5: 69, 6: 32256, 7: 24579
8: 12, 9: 192, 10: 31744, 11: 16391
12: 24, 13: 384, 14: 30720, 15: 15
- Select preset index (0-15) using DiscID:
1) sum = sum of first 8 bytes of DiscID
2) beat_data = ((sum / 0x10) + sum) & 0x0F
3) beat_data selects index in preset table
- Initialize XOR scrambler (LFSR) with chosen preset
- Scramble each sector:
- Bytes D0-D5 = not scrambled
- Bytes D6-D2047 = XOR with pseudo-random stream from LFSR
- Wrap-around ensures continuity across sectors
4. BCA (BURST-CUTTING AREA) - Optional
----------------------------------------
- 188-byte block is enough if included
- Fill with zeros or dummy values
- No real marks or signatures needed
- Drive ignores BCA for boot
5. LEAD-IN / LEAD-OUT
---------------------
- Can follow normal DVD standard
- Ignored by drive for boot
6. SUMMARY - Minimum for bootable disc
--------------------------------------
1) Control Data Zone ? correct fixed bytes + Media ID + BCA descriptor
2) DiscID ? 8 bytes
3) User area ? XOR-scrambled using DiscID/preset index
4) Optional: BCA block (zeros or filler)
Data Frame
u32 id; // PSN(Physical Sector Number) u16 ied; // ID Error Detection Code, CRC16 u8 userdata[2048]; // Sector Data u8 cpr_mai[6]; // Copyright Management Information(Not used) u32 edc; // Error Detection Code, CRC32 // 2064B
Random Number Table
0: 3 1: 48 2: 32512 3: 28673 4: 6 5: 69 6: 32256 7: 24579 8: 12 9: 192 10: 31744 11: 16391 12: 24 13: 384 14: 30720 15: 15
DiskId
char gamecode[4]; char makercode[2]; u8 diskNumber; u8 version; u8 streaming; u8 streamingBufferSize; u8 pad[18]; u32 magic;
Burst Cutting Area
// UserData(unencrypted), 64B
u8 optionalInfo[52];
u8 manufacturer[2];
u8 recorderDevice[2];
u8 bcaSerial;
u8 discDate[2];
u8 discTime[2];
u8 discNumber[3];
// SecureData(unencrypted), 12B
u8 key[8];
u8 id[4];
// AuthenticationData(encrypted), 48B
PsnRegion psn[6]; // 6 sector locations
// 188 Total Bytes
struct_PsnRegion
{
u32 start;
u32 end;
};
Disc Physical Format
// Leadin Area PhysicalFormatInfo pfi; DiscManufacturingInfo dmi;
PhysicalFormatInfo
u8 reversed[6]; u8 discMagic; // value is -1. u8 discSizeMinTransferRate; // The value is fixed on 16. u8 discStructure; // The value is fixed on 1. u8 recordedDensity; // The value is fixed on 1. DataAreaAllocation m_dataAreaAllocation; u8 reversed2[2026]; u8 reversed3[6];
DiscManufacturingInfo
u8 reversed[6]; u8 unknown1[6]; u8 randomNumber2[6]; u8 unknown2[6]; u8 randomNumber3[6]; char mediaId[19]; // "Nintendo Game Disk" u8 randomNumber4[6]; u8 bookTypePartVersion; // value must be 1. u8 discSizeMinReadoutRate; // The value is fixed on 16. u8 discStructure; // The value is fixed on 1. u8 recordedDensity; // The value is fixed on 0. DataAreaAllocation dataAreaAllocation; u8 bcaDescriptor; // The value is fixed on 128. u8 reversed2[1983]; u8 reversed3[6];
DataAreaAllocation
u8 reversed; u16 startSector; u8 reversed2; u16 endSector; u8 reversed3[3]; // 12 Bytes
Disc Image Format
BootHeader m_header; BootHeaderInfo m_bi; AppLoader m_apploader; FileSystemTable m_fst; u8 userdata[0]; // application is stored here, including boot file
BootHeader
u8 game_code[4]; u8 company_code[2]; u8 diskNumber; u8 gameVersion; u8 audioStreaming; u8 streamBufSize; u8 unused_1[18]; u32 magic; // 3258163005 char gameName[64]; u8 unused_2[416]; u32 nkitMagicWord; u32 nkitVersion; u32 dataCRC; u32 headerCRC; u32 dataSize; u32 junkId; u8 unused_3[488]; u32 ApploaderSize; u32 ApploaderInit; u32 ApploaderMain; u32 ApploaderExit; u8 unused_4[16]; u32 bootOffset; u32 fstOffset; u32 fstSize; u32 maxFstSize; u32 fstAddress; // debug fstOffset u32 userPos; // disc data offset u32 userLength; // disc data size u32 unused_5;
BootHeaderInfo
u32 debugMonSize; // debug monitor size u32 simMemSize; // simulator memory size u32 argOffset; u32 debugFlag; u32 debugOffset; u32 debugSize; u32 country; u32 totalDisc; u32 supportLongFileName; u32 padSpec; u32 dolLimit; u8 unused_6[8148]; // 8192 Bytes
AppLoader
char date[16]; // date string u32 entryAddress; u32 size; u32 rebootSize; u8 pad[4]; u8* code;
FileSystemTable
u32 entryCount; FileSystemEntity* m_entity; StringTable* m_string;
FileSystemEntity
u8 flags; u16 filenameOffset; u32 fileOffset; u32 fileSize;
StringTable
char* name; u8 pad;