NdsForge.NET 1.0.1
Read, validate, edit, compare, and build Nintendo DS and DSi images from .NET
Loading...
Searching...
No Matches
NdsHeader.cs
1namespace NdsForge;
2
4public sealed class NdsHeader
5{
8 internal NdsHeader(ReadOnlyMemory<byte> rawData)
9 {
10 RawData = rawData;
11 ReadOnlySpan<byte> data = rawData.Span;
12 Title = NdsBinary.ReadAscii(data, 0x00, 12);
13 GameCode = NdsBinary.ReadAscii(data, 0x0C, 4);
14 MakerCode = NdsBinary.ReadAscii(data, 0x10, 2);
15 Kind = ParseKind(data[0x12]);
16 EncryptionSeedSelect = data[0x13];
17 DeviceCapacityExponent = data[0x14];
18 DsiFlags = data[0x1C];
19 RegionCode = data[0x1D];
20 Version = data[0x1E];
21 AutoStart = data[0x1F];
22 Arm9 = ReadProgram(data, NdsProcessor.Arm9, 0x20);
23 Arm7 = ReadProgram(data, NdsProcessor.Arm7, 0x30);
24 FileNameTable = ReadRegion(data, 0x40);
25 FileAllocationTable = ReadRegion(data, 0x48);
26 Arm9OverlayTable = ReadRegion(data, 0x50);
27 Arm7OverlayTable = ReadRegion(data, 0x58);
28 NormalCardControl = NdsBinary.ReadUInt32(data, 0x60);
29 SecureCardControl = NdsBinary.ReadUInt32(data, 0x64);
30 BannerOffset = NdsBinary.ReadUInt32(data, 0x68);
31 SecureAreaCrc = NdsBinary.ReadUInt16(data, 0x6C);
32 SecureTransferTimeout = NdsBinary.ReadUInt16(data, 0x6E);
33 Arm9AutoLoad = NdsBinary.ReadUInt32(data, 0x70);
34 Arm7AutoLoad = NdsBinary.ReadUInt32(data, 0x74);
35 SecureDisable = ((ulong)NdsBinary.ReadUInt32(data, 0x7C) << 32) | NdsBinary.ReadUInt32(data, 0x78);
36 UsedImageSize = NdsBinary.ReadUInt32(data, 0x80);
37 HeaderSize = NdsBinary.ReadUInt32(data, 0x84);
38 NintendoLogoCrc = NdsBinary.ReadUInt16(data, 0x15C);
39 HeaderCrc = NdsBinary.ReadUInt16(data, 0x15E);
40
41 if (data.Length >= 0x1E0 && Kind != NdsImageKind.NintendoDs)
42 {
43 Arm9i = ReadDsiProgram(data, NdsProcessor.Arm9i, 0x1C0);
44 Arm7i = ReadDsiProgram(data, NdsProcessor.Arm7i, 0x1D0);
45 Dsi = new(rawData);
46 }
47 }
48
50 public ReadOnlyMemory<byte> RawData { get; }
51
53 public string Title { get; }
54
56 public string GameCode { get; }
57
59 public string MakerCode { get; }
60
62 public NdsImageKind Kind { get; }
63
65 public byte EncryptionSeedSelect { get; }
66
68 public byte DeviceCapacityExponent { get; }
69
71 public long DeviceCapacityBytes => 128L * 1024L << DeviceCapacityExponent;
72
74 public byte DsiFlags { get; }
75
77 public byte RegionCode { get; }
78
80 public byte Version { get; }
81
83 public byte AutoStart { get; }
84
86 public NdsProgram Arm9 { get; }
87
89 public NdsProgram Arm7 { get; }
90
92 public NdsProgram? Arm9i { get; }
93
95 public NdsProgram? Arm7i { get; }
96
98 public NdsDsiHeader? Dsi { get; }
99
101 public NdsRegion FileNameTable { get; }
102
105
108
111
113 public uint NormalCardControl { get; }
114
116 public uint SecureCardControl { get; }
117
119 public uint BannerOffset { get; }
120
122 public ushort SecureAreaCrc { get; }
123
125 public ushort SecureTransferTimeout { get; }
126
128 public uint Arm9AutoLoad { get; }
129
131 public uint Arm7AutoLoad { get; }
132
134 public ulong SecureDisable { get; }
135
137 public uint UsedImageSize { get; }
138
140 public uint HeaderSize { get; }
141
143 public ushort NintendoLogoCrc { get; }
144
146 public ushort HeaderCrc { get; }
147
151 private static NdsImageKind ParseKind(byte value) => value switch
152 {
153 0 => NdsImageKind.NintendoDs,
154 2 => NdsImageKind.NintendoDsiEnhanced,
155 3 => NdsImageKind.NintendoDsiExclusive,
156 _ => throw new InvalidDataException($"Unsupported Nintendo DS unit code 0x{value:X2}."),
157 };
158
164 private static NdsProgram ReadProgram(ReadOnlySpan<byte> data, NdsProcessor processor, int offset) =>
165 new(
166 processor,
167 NdsRegion.FromUInt32(NdsBinary.ReadUInt32(data, offset), NdsBinary.ReadUInt32(data, offset + 12)),
168 NdsBinary.ReadUInt32(data, offset + 4),
169 NdsBinary.ReadUInt32(data, offset + 8));
170
176 private static NdsProgram ReadDsiProgram(ReadOnlySpan<byte> data, NdsProcessor processor, int offset)
177 {
178 uint loadAddress = NdsBinary.ReadUInt32(data, offset + 8);
179 return new(
180 processor,
181 NdsRegion.FromUInt32(NdsBinary.ReadUInt32(data, offset), NdsBinary.ReadUInt32(data, offset + 12)),
182 loadAddress,
183 loadAddress);
184 }
185
190 private static NdsRegion ReadRegion(ReadOnlySpan<byte> data, int offset) =>
191 NdsRegion.FromUInt32(NdsBinary.ReadUInt32(data, offset), NdsBinary.ReadUInt32(data, offset + 4));
192}
Projects DSi security, digest, memory, title, and save metadata while preserving the complete extensi...
ushort SecureTransferTimeout
Preserves the cartridge-transfer timeout value used while accessing the secure area.
Definition NdsHeader.cs:125
ushort NintendoLogoCrc
Contains the CRC16 protecting the 156-byte Nintendo logo at header offset 0xC0.
Definition NdsHeader.cs:143
uint UsedImageSize
Reports the builder-declared meaningful end of image, excluding optional capacity padding.
Definition NdsHeader.cs:137
NdsImageKind Kind
Interprets unit code 0, 2, or 3 as DS, DSi-enhanced, or DSi-exclusive.
Definition NdsHeader.cs:62
uint HeaderSize
Reports the header byte count claimed on cartridge, commonly 0x4000 despite a smaller parsed prefix.
Definition NdsHeader.cs:140
NdsProgram? Arm9i
Locates the DSi-mode ARM9i payload when the unit code selects an extended header.
Definition NdsHeader.cs:92
NdsProgram Arm7
Locates the secondary processor payload and its entry/load addresses from header offsets 0x30-0x3F.
Definition NdsHeader.cs:89
byte DeviceCapacityExponent
Stores the power-of-two exponent that scales the 128 KiB base cartridge capacity.
Definition NdsHeader.cs:68
ulong SecureDisable
Combines the two header words forming the raw 64-bit secure-area disable token.
Definition NdsHeader.cs:134
byte DsiFlags
Preserves the DSi flags at offset 0x1C; DS-only software normally leaves them zero.
Definition NdsHeader.cs:74
uint NormalCardControl
Preserves the raw ROM-control timing word used for ordinary cartridge transfers.
Definition NdsHeader.cs:113
byte AutoStart
Preserves the boot-control byte at offset 0x1F, including reserved bits for lossless rewriting.
Definition NdsHeader.cs:83
byte RegionCode
Preserves the header's region byte, whose defined interpretation depends on DS versus DSi mode.
Definition NdsHeader.cs:77
string Title
Decodes the padded 12-byte ASCII label shown by low-level cartridge inspection tools.
Definition NdsHeader.cs:53
NdsProgram Arm9
Locates the primary processor payload and its entry/load addresses from header offsets 0x20-0x2F.
Definition NdsHeader.cs:86
ReadOnlyMemory< byte > RawData
Preserves reserved and currently unmodeled fields for byte-exact extraction and copy-on-write editing...
Definition NdsHeader.cs:50
byte Version
Exposes the publisher-controlled one-byte software revision rather than the banner or format version.
Definition NdsHeader.cs:80
NdsRegion FileNameTable
Locates the FNT main records and name subtables that give FAT identifiers a hierarchy and names.
Definition NdsHeader.cs:101
ushort HeaderCrc
Contains the CRC16 over bytes 0x000-0x15D, excluding this field itself.
Definition NdsHeader.cs:146
NdsRegion FileAllocationTable
Locates the flat array of eight-byte start/end records used by NitroFS files and overlays.
Definition NdsHeader.cs:104
uint SecureCardControl
Preserves the raw ROM-control timing word used during secure-area cartridge transfers.
Definition NdsHeader.cs:116
string GameCode
Decodes the four-byte product code used for title identity, region suffixes, and encryption derivatio...
Definition NdsHeader.cs:56
NdsDsiHeader? Dsi
Gets the extended DSi header, or null for DS-only images.
Definition NdsHeader.cs:98
string MakerCode
Decodes the two-byte publisher identifier; Nintendo-authored retail images commonly use 01.
Definition NdsHeader.cs:59
NdsRegion Arm9OverlayTable
Locates fixed 32-byte records describing dynamically loaded ARM9 code and their FAT payload IDs.
Definition NdsHeader.cs:107
ushort SecureAreaCrc
Contains the header's CRC16 for the secure area; interpretation requires secure-area encryption state...
Definition NdsHeader.cs:122
byte EncryptionSeedSelect
Preserves the raw seed-selection byte consumed by cartridge secure-area protocols.
Definition NdsHeader.cs:65
NdsProgram? Arm7i
Locates the DSi-mode ARM7i payload when the unit code selects an extended header.
Definition NdsHeader.cs:95
NdsRegion Arm7OverlayTable
Locates fixed 32-byte records describing dynamically loaded ARM7 code and their FAT payload IDs.
Definition NdsHeader.cs:110
uint BannerOffset
Gets the banner offset, or zero when no banner is present.
Definition NdsHeader.cs:119
uint Arm9AutoLoad
Identifies the ARM9 SDK autoload-list address used by the runtime initialization process.
Definition NdsHeader.cs:128
uint Arm7AutoLoad
Identifies the ARM7 SDK autoload-list address used by the runtime initialization process.
Definition NdsHeader.cs:131
long DeviceCapacityBytes
Computes the nominal power-of-two cartridge capacity independently from physical or used image length...
Definition NdsHeader.cs:71
Describes an executable program region and its runtime addresses.
Definition NdsProgram.cs:13
Identifies a bounded range of bytes in an image.
Definition NdsRegion.cs:11
NdsProcessor
Identifies a processor and execution mode.
NdsImageKind
Identifies the hardware family targeted by an image.