Skip to content

Commit a350046

Browse files
gmestanleyWerWolv
andauthored
patterns: Credit to NE and improvements on NES (#445)
* Add credit to ne.hexpat * Add many changes to nes.hexpat * Fixing dependance on variables declared in if statement --------- Co-authored-by: Nik <[email protected]>
1 parent 4fc11f1 commit a350046

File tree

2 files changed

+244
-65
lines changed

2 files changed

+244
-65
lines changed

patterns/ne.hexpat

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
#pragma author gmestanley
12
#pragma description Microsoft DOS NE executable
23
#pragma MIME application/x-ms-ne-executable
34

patterns/nes.hexpat

Lines changed: 243 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -2,87 +2,265 @@
22
#pragma description Nintendo Entertainment System ROM (.nes)
33
#pragma MIME application/x-nes-rom
44

5-
import std.mem;
65
import std.string;
76

8-
bitfield iNES07Flags {
9-
mirroringIsVertical : 1;
10-
batterybackedPRGRAM : 1;
11-
trainerOf512Bytes : 1;
12-
ignoreMirroring : 1;
13-
mapperLowerNybble : 4;
14-
vsUnisystem : 1;
15-
playchoice10 : 1;
16-
nes2Format : 2 [[name("nes2.0Format")]];
17-
mapperHigherNybble : 4;
18-
} [[name("iNES0.7Flags")]];
19-
20-
bitfield Flags9 {
21-
isPAL : 1;
22-
padding : 7;
23-
};
24-
25-
bitfield Flags10 {
26-
tvSystem : 2;
27-
padding : 2;
28-
prgRAM : 1;
29-
busConflicts : 1;
30-
padding : 2;
31-
};
32-
33-
struct iNESFlags {
34-
iNES07Flags ines07Flags [[name("ines0.7Flags")]];
35-
if (!ines07Flags.nes2Format) {
36-
u8 prgRAM8KBMultiplier;
37-
Flags9 flags9;
38-
Flags10 flags10;
39-
restLength = 5;
40-
}
41-
else {
42-
restLength = 9;
43-
}
44-
};
45-
46-
u8 restLength;
7+
bitfield Flags {
8+
mirroringIsHorizontal : 1;
9+
ignoreMirroring : 1;
10+
batterybackedPRGRAM : 1;
11+
trainerOf512Bytes : 1;
12+
lowerMapperNybble : 4;
13+
};
14+
15+
enum ConsoleType : u8 {
16+
Regular,
17+
VsSystem,
18+
PlayChoice10,
19+
ExtendedConsoleType
20+
};
21+
22+
fn consoleType(u8 bits) {
23+
ConsoleType type = bits;
24+
return type;
25+
};
26+
27+
fn nes2Format(u8 bits) {
28+
return std::string::to_string(bits == 2) + " (" + std::string::to_string(bits) + ")";
29+
};
30+
31+
bitfield iNESFlags7 {
32+
consoleType : 2 [[format("consoleType")]];
33+
nes2Format : 2 [[format("nes2Format"), name("nes2.0Format")]];
34+
higherMapperNybble : 4;
35+
};
36+
37+
bitfield iNESFlags9 {
38+
tvSystem : 1 [[comment("0 = NTSC, 1 = PAL")]];
39+
padding : 7;
40+
};
41+
42+
fn formatDualTVSystem(u8 bits) {
43+
match (bits) {
44+
(0): return "NTSC";
45+
(2): return "PAL";
46+
(1 || 3): return "Dual Compatible";
47+
}
48+
};
49+
50+
bitfield iNESFlags10 {
51+
dualTVSystem : 2 [[format("formatDualTVSystem")]];
52+
padding : 2;
53+
prgRAM : 1;
54+
busConflicts : 1;
55+
};
56+
57+
bitfield MapperExtra {
58+
highestMapperNybble : 4;
59+
submapper : 4;
60+
};
61+
62+
bitfield ROMSize {
63+
extraPRGROMSize : 4;
64+
extraCHRROMSize : 4;
65+
};
66+
67+
bitfield PRGRAMSize {
68+
prgRAMShiftCount : 4;
69+
eepromShiftCount : 4 [[comment("EEPROM = Non-volatile PRG RAM")]];
70+
};
71+
72+
bitfield CHRRAMSize {
73+
chrRAMSizeShiftCount : 4;
74+
chrNVRAMSizeShiftCount : 4;
75+
};
76+
77+
enum TimingList : u8 {
78+
NTSC,
79+
PAL,
80+
MultiRegion,
81+
Dendy
82+
};
83+
84+
fn Timing(u8 value) {
85+
TimingList type = value;
86+
return type;
87+
};
88+
89+
bitfield Timing {
90+
processorTiming : 2 [[format("Timing")]];
91+
padding : 6;
92+
};
93+
94+
bitfield VsSystemType {
95+
vsPPUType : 4;
96+
vsHardwareType: 4;
97+
};
98+
99+
enum ExtendedConsoleType : ConsoleType {
100+
DecimalModeFamiclone = 3,
101+
PlugThrough,
102+
VT01,
103+
VT02,
104+
VT03,
105+
VT09,
106+
VT32,
107+
VT3xx,
108+
UM6578,
109+
FamicomNetworkSystem
110+
};
111+
112+
fn formatExtendedConsoleType(u8 nybble) {
113+
ExtendedConsoleType type = nybble;
114+
return type;
115+
};
116+
117+
bitfield ExtendedConsoleTypeByte {
118+
type : 4 [[format("formatExtendedConsoleType")]];
119+
padding : 4;
120+
};
121+
122+
bitfield MiscellaneousROMs {
123+
numberOfMiscellaneousROMs : 2;
124+
padding : 6;
125+
};
126+
127+
bitfield DefaultExpansionDevice {
128+
defaultExpansionDevice : 6;
129+
};
130+
131+
struct NES2Attributes {
132+
MapperExtra mapperExtra;
133+
ROMSize romSize;
134+
PRGRAMSize prgRAMSize;
135+
CHRRAMSize chrRAMSize;
136+
Timing timing;
137+
if (parent.inesFlags7.consoleType == ConsoleType::VsSystem) {
138+
VsSystemType vsSystemType;
139+
}
140+
else if (parent.inesFlags7.consoleType == ConsoleType::ExtendedConsoleType) {
141+
ExtendedConsoleTypeByte ExtendedConsoleTypeByte;
142+
}
143+
else {
144+
padding[1];
145+
}
146+
MiscellaneousROMs miscellaneousROMs;
147+
DefaultExpansionDevice defaultExpansionDevice;
148+
};
149+
150+
fn renderEOF(str string) {
151+
return "\"NES<EOF>\"";
152+
};
47153

48154
struct Header {
49-
char identifier[4];
50-
u8 prgROM16KBMultiplier;
51-
u8 chrROM8KBMultiplier;
52-
iNESFlags inesFlags;
53-
char rest[restLength];
155+
char identifier[4] [[format("renderEOF")]];
156+
u8 prgROMSizeBy16KiBs;
157+
u8 chrROMSizeBy8KiBs;
158+
Flags flags;
159+
if ($[0x07] & 12 != 4) {
160+
iNESFlags7 inesFlags7;
161+
if (inesFlags7.nes2Format)
162+
NES2Attributes nes2Attributes;
163+
else if ($[0x07] & 12 == 0 && !std::mem::read_unsigned($, 4)) {
164+
u8 prgRAMSizeBy8KiBs;
165+
iNESFlags9 inesFlags9;
166+
iNESFlags10 inesFlags10;
167+
}
168+
}
54169
};
55170

56171
Header header @ 0x00;
57172

173+
u8 trainer[512*header.flags.trainerOf512Bytes] @ 0x10;
174+
175+
enum CHRType : u8 {
176+
CHRROM,
177+
CHRRAM
178+
};
179+
180+
fn chrType(u8 value) {
181+
CHRType enumValue = value;
182+
return enumValue;
183+
};
184+
185+
fn chrSize(u8 value) {
186+
u24 actualSize;
187+
if (value == 4) actualSize = 262144;
188+
else actualSize = 8192 * header.chrROMSizeBy8KiBs;
189+
return std::string::to_string(value) + " (" + std::string::to_string(actualSize) + ")";
190+
};
191+
192+
bitfield MemorySize {
193+
prgROMSizeBy16KiBs : 4;
194+
chrType : 1 [[format("chrType")]];
195+
chrSize : 3 [[format("chrSize")]];
196+
};
197+
198+
enum ArrangementList : u8 {
199+
Horizontal,
200+
Vertical
201+
};
202+
203+
fn arrangement(u8 value) {
204+
ArrangementList enumValue = value;
205+
return enumValue;
206+
};
207+
208+
enum MapperList : u8 {
209+
NROM,
210+
CNROM,
211+
UNROM,
212+
GNROM,
213+
MMC
214+
};
215+
216+
fn mapper(u8 value) {
217+
MapperList enumValue = value;
218+
return enumValue;
219+
};
220+
221+
bitfield CartridgeType {
222+
nametableArrangement : 1 [[format("arrangement")]];
223+
mapper : 7 [[format("mapper")]];
224+
};
225+
58226
enum EncodingType : u8 {
59-
ASCII = 1
227+
None,
228+
ASCII,
229+
JIS
60230
};
61231

232+
fn titleLength(u8 value) { return value+1; };
233+
62234
struct OfficialHeader {
63-
char title[16] [[hex::spec_name("Title Registration Area")]];
64-
u16 programChecksum;
65-
u16 characterChecksum;
66-
u8 memorySize [[hex::spec_name("Cartridge Memory Size")]];
67-
u8 cartridgeType;
68-
EncodingType encodingType [[hex::spec_name("Registration Character Type Distinction")]];
69-
u8 titleLength [[hex::spec_name("Registration Characters Count")]];
70-
u8 makerID [[hex::spec_name("Maker Code")]];
71-
u8 complementaryChecksum;
235+
char title[16] [[hex::spec_name("Title Registration Area")]];
236+
u16 programChecksum;
237+
u16 characterChecksum;
238+
MemorySize memorySize [[hex::spec_name("Cartridge Memory Size")]];
239+
CartridgeType cartridgeType;
240+
EncodingType encodingType [[hex::spec_name("Registration Characters Type Distinction")]];
241+
u8 titleLength [[hex::spec_name("Registration Characters Count"), transform("titleLength")]];
242+
u8 licenseeID [[hex::spec_name("Maker Code")]];
243+
u8 complementaryChecksum [[hex::spec_name("Checksum for characterChecksum~makerID")]];
72244
};
73245

74-
union OfficialHeaderUnion {
75-
u8 miscellaneousData[26];
76-
OfficialHeader officialHeader;
246+
u24 calculatedPRGROMSize = 16384 * ((0x0100 * $[9] & 0x0F) * ($[7] & 12 == 8) + header.prgROMSizeBy16KiBs);
247+
248+
fn hasOfficialHeader() {
249+
u8 sum;
250+
for (u8 i = 0, i < 8, i += 1) {
251+
sum += $[(calculatedPRGROMSize - 14) + i];
252+
}
253+
return !sum;
77254
};
78255

79256
struct PRGROM {
80-
u8 data[16384*header.prgROM16KBMultiplier-32];
81-
OfficialHeaderUnion officialHeaderUnion;
82-
u16 nmi;
83-
u16 entryPoint;
84-
u16 externalIRQ;
257+
u8 data[calculatedPRGROMSize - 26 * hasOfficialHeader() - 6];
258+
if (hasOfficialHeader())
259+
OfficialHeader officialHeader;
260+
u16 nmi;
261+
u16 resetVector [[comment("Entry Point")]];
262+
u16 externalIRQ;
85263
};
86264

87-
PRGROM prgROM @ sizeof(header);
88-
u8 chrROM[8192*header.chrROM8KBMultiplier] @ sizeof(header)+sizeof(prgROM);
265+
PRGROM prgROM @ 0x10 + sizeof(trainer);
266+
u8 chrROM[8192 * ((0x0100 * $[9] >> 4) * ($[7] & 12 == 8) + header.chrROMSizeBy8KiBs)] @ addressof(prgROM) + 16384 * header.prgROMSizeBy16KiBs;

0 commit comments

Comments
 (0)