diff --git a/patterns/nes.hexpat b/patterns/nes.hexpat index 797d8ec..6159a9a 100644 --- a/patterns/nes.hexpat +++ b/patterns/nes.hexpat @@ -4,404 +4,478 @@ import std.string; +enum MirroringType : u8 { + Vertical, + Horizontal +}; + +fn mirroring(u8 value) { + MirroringType enumValue = value; + return enumValue; +}; + bitfield Flags { - mirroringIsHorizontal : 1; - ignoreMirroring : 1; - batterybackedPRGRAM : 1; - trainerOf512Bytes : 1; - lowerMapperNybble : 4; + mirroring : 1 [[format("mirroring")]]; + ignoreMirroring : 1; + batterybackedPRGRAM : 1; + trainerOf512Bytes : 1; + lowerMapperNybble : 4; }; enum ConsoleType : u8 { - Regular, - VsSystem, - PlayChoice10, - ExtendedConsoleType + Regular, + VsSystem, + PlayChoice10, + ExtendedConsoleType }; fn consoleType(u8 bits) { - ConsoleType type = bits; - return type; + ConsoleType type = bits; + return type; }; fn nes2Format(u8 bits) { - return std::string::to_string(bits == 2) + " (" + std::string::to_string(bits) + ")"; + return std::string::to_string(bits == 2) + " (" + std::string::to_string(bits) + ")"; }; bitfield iNESFlags7 { - consoleType : 2 [[format("consoleType")]]; - nes2Format : 2 [[format("nes2Format"), name("nes2.0Format")]]; - higherMapperNybble : 4; + consoleType : 2 [[format("consoleType")]]; + nes2Format : 2 [[format("nes2Format"), name("nes2.0Format")]]; + higherMapperNybble : 4; +}; + +enum OldTVSystemByte : u8 { + NTSC, + PAL +}; + +fn formatOldTVSystemByte(u8 value) { + OldTVSystemByte enumValue = value; + return value; }; bitfield iNESFlags9 { - tvSystem : 1 [[comment("0 = NTSC, 1 = PAL")]]; - padding : 7; + tvSystem : 1 [[format("formatOldTVSystemByte")]]; + padding : 7; }; fn formatDualTVSystem(u8 bits) { - match (bits) { - (0): return "NTSC"; - (2): return "PAL"; - (1 || 3): return "Dual Compatible"; - } + match (bits) { + (0): return "NTSC"; + (2): return "PAL"; + (1 || 3): return "Dual Compatible"; + } }; bitfield iNESFlags10 { - dualTVSystem : 2 [[format("formatDualTVSystem")]]; - padding : 2; - prgRAM : 1; - busConflicts : 1; + dualTVSystem : 2 [[format("formatDualTVSystem")]]; + padding : 2; + prgRAM : 1; + busConflicts : 1; }; bitfield MapperExtra { - highestMapperNybble : 4; - submapper : 4; + highestMapperNybble : 4; + submapper : 4; }; bitfield ROMSize { - extraPRGROMSize : 4; - extraCHRROMSize : 4; + extraPRGROMSize : 4; + extraCHRROMSize : 4; }; bitfield PRGRAMSize { - prgRAMShiftCount : 4; - eepromShiftCount : 4 [[comment("EEPROM = Non-volatile PRG RAM")]]; + prgRAMShiftCount : 4; + eepromShiftCount : 4 [[comment("EEPROM = Non-volatile PRG RAM, or NVPRGRAM")]]; }; bitfield CHRRAMSize { - chrRAMSizeShiftCount : 4; - chrNVRAMSizeShiftCount : 4; + chrRAMSizeShiftCount : 4; + chrNVRAMSizeShiftCount : 4; }; enum TimingList : u8 { - NTSC, - PAL, - MultiRegion, - Dendy + NTSC, + PAL, + MultiRegion, + Dendy }; fn Timing(u8 value) { - TimingList type = value; - return type; + TimingList enumValue = value; + return enumValue; }; -bitfield Timing { - processorTiming : 2 [[format("Timing")]]; - padding : 6; +bitfield Timing { + processorTiming : 2 [[format("Timing")]]; + padding : 6; }; bitfield VsSystemType { - vsPPUType : 4; - vsHardwareType: 4; + vsPPUType : 4; + vsHardwareType: 4; }; enum ExtendedConsoleType : ConsoleType { - DecimalModeFamiclone = 3, - PlugThrough, - VT01, - VT02, - VT03, - VT09, - VT32, - VT3xx, - UM6578, - FamicomNetworkSystem + DecimalModeFamiclone = 3, + PlugThrough, + VT01, + VT02, + VT03, + VT09, + VT32, + VT3xx, + UM6578, + FamicomNetworkSystem }; fn formatExtendedConsoleType(u8 nybble) { - ExtendedConsoleType type = nybble; - return type; + ExtendedConsoleType type = nybble; + return type; }; bitfield ExtendedConsoleTypeByte { - type : 4 [[format("formatExtendedConsoleType")]]; - padding : 4; + type : 4 [[format("formatExtendedConsoleType")]]; + padding : 4; }; -bitfield MiscellaneousROMs { - numberOfMiscellaneousROMs : 2; - padding : 6; +bitfield MiscellaneousROMsHeaderByte { + numberOfMiscellaneousROMs : 2; + padding : 6; }; - + bitfield DefaultExpansionDevice { - defaultExpansionDevice : 6; + defaultExpansionDevice : 6; }; struct NES2Attributes { - MapperExtra mapperExtra; - ROMSize romSize; - PRGRAMSize prgRAMSize; - CHRRAMSize chrRAMSize; - Timing timing; - if (parent.inesFlags7.consoleType == ConsoleType::VsSystem) { - VsSystemType vsSystemType; - } - else if (parent.inesFlags7.consoleType == ConsoleType::ExtendedConsoleType) { - ExtendedConsoleTypeByte ExtendedConsoleTypeByte; - } - else { - padding[1]; - } - MiscellaneousROMs miscellaneousROMs; - DefaultExpansionDevice defaultExpansionDevice; + MapperExtra mapperExtra; + ROMSize romSize; + PRGRAMSize prgRAMSize; + CHRRAMSize chrRAMSize; + Timing timing; + if (parent.inesFlags7.consoleType == ConsoleType::VsSystem) { + VsSystemType vsSystemType; + } + else if (parent.inesFlags7.consoleType == ConsoleType::ExtendedConsoleType) { + ExtendedConsoleTypeByte ExtendedConsoleTypeByte; + } + else { + padding[1]; + } + MiscellaneousROMsHeaderByte miscellaneousROMs; + DefaultExpansionDevice defaultExpansionDevice; } [[inline]]; fn renderEOF(str string) { - return "\"NES\""; + return "\"NES\""; }; struct Header { - char identifier[4] [[format("renderEOF")]]; - u8 prgROMSizeBy16KiBs; - u8 chrROMSizeBy8KiBs; - Flags flags; - if ($[0x07] & 12 != 4) { - iNESFlags7 inesFlags7; - if (inesFlags7.nes2Format) - NES2Attributes nes2Attributes; - else if ($[0x07] & 12 == 0 && !std::mem::read_unsigned($, 4)) { - u8 prgRAMSizeBy8KiBs; - iNESFlags9 inesFlags9; - iNESFlags10 inesFlags10; - } - } + char identifier[4] [[format("renderEOF")]]; + u8 prgROMSizeBy16KiBs; + u8 chrROMSizeBy8KiBs; + Flags flags; + if ($[0x07] & 12 != 4) { + iNESFlags7 inesFlags7; + if (inesFlags7.nes2Format) + NES2Attributes nes2Attributes; + else if ($[0x07] & 12 == 0 && !std::mem::read_unsigned(0x0C, 4)) { + u8 prgRAMSizeBy8KiBs; + iNESFlags9 inesFlags9; + iNESFlags10 inesFlags10; + } + } }; Header header @ 0x00; +u8 FILLED_HIGHER_NYBBLE = 0b1111; +u8 FILLED_NES2_FLAGS = 0b1100; +u8 SET_NES2_FLAGS = 0b1000; +u16 mapperValue = (0x0100 * ($[0x08] & FILLED_HIGHER_NYBBLE)) * ($[7] & FILLED_NES2_FLAGS == SET_NES2_FLAGS) ++ (0x10 * ($[0x07] >> 4)) * ($[7] & FILLED_NES2_FLAGS != 0b100) ++ header.flags.lowerMapperNybble; +fn identifyMapper(u16 mapperValue, u8 submapperValue) { + str mapper; + str submapper; + str designation; + match (mapperValue) { + (0): mapper = "No mapper"; + (1): mapper = "MMC1B"; + (2): mapper = "UxROM"; + (3): mapper = "CNROM-32"; + (4): mapper = "MMC3"; + (5): mapper = "MMC5"; + (6): mapper = "Front Fareast Magic Card 1/2M RAM Cartridge"; + (7): mapper = "AxROM"; + (8): mapper = "Front Fareast Magic Card 1/2M RAM Cartridge [Initial latch-based banking mode 4]"; + (9): mapper = "MMC2"; + (10): mapper = "MMC4"; + (11): mapper = "Color Dreams"; + (12): mapper = "[See submapper]"; + (13): mapper = "CPROM"; + (14): mapper = "SL-1632"; + (15): mapper = "K-102xx"; + (16): mapper = "Bandai FCG boards"; + (17): mapper = "Front Fareast Super Magic Card RAM cartridge"; + (18): mapper = "Jaleco SS88006"; + (19): mapper = "Namco 129/163"; + (20): mapper = "Famicom Disk System"; + (21): mapper = "Konami VRC4a/VRC4c"; + (22): mapper = "Konami VRC2a"; + (23): mapper = "Konami VRC4e or VRC2b + VRC4f"; + (24): mapper = "Konami VRC6a"; + (25): mapper = "Konami VRC4d or VRC2c + VRC4b"; + (26): mapper = "Konami VRC6b"; + (27): mapper = "World Hero"; + (28): mapper = "Action 53, homebrew"; + (29): mapper = "RET-CUFROM"; + (30): mapper = "UNROM 512"; + (31): mapper = "NSF"; + (32): mapper = "G-101"; + (33): mapper = "Taito TC0190"; + (34): mapper = "[See submapper]"; + (35): mapper = "J.Y. Company ASIC [8KiB WRAM]"; + (36): mapper = "Micro Genius 01-22000-400"; + (37): mapper = "SMB+Tetris+NWC"; + (38): mapper = "Bit Corp. Crime Busters"; + (39): mapper = "Study & Game 32-in-1 [DEPRECATED]"; + (40): mapper = "NTDEC 27xx"; + (41): mapper = "Caltron 6-in-1"; + (42): mapper = "FDS -> NES Hacks"; + (43): mapper = "TONY-I/YS-612"; + (44): mapper = "Super Big 7-in-1"; + (45): mapper = "GA23C"; + (46): mapper = "Lite Star Rumble Station"; + (47): mapper = "Nintendo Super Spike V'Ball + NWC"; + (48): mapper = "Taito TC0690"; + (49): mapper = "Super HIK 4-in-1"; + (50): mapper = "N-32 [Super Mario Bros. 2 (J)]"; + (51): mapper = "[See submapper]"; + (52): mapper = "Realtec 8213"; + (53): mapper = "Supervision 16-in-1"; + (54): mapper = "Novel Diamond 9999999-in-1 [DEPRECATED]"; + (55): mapper = "QFJxxxx"; + (56): mapper = "KS202"; + (57): mapper = "GK"; + (58): mapper = "WQ"; + (59): mapper = "T3H53"; + (60): mapper = "Reset-based NROM-128 4-in-1"; + (61): mapper = "[See submapper]"; + (62): mapper = "Super 700-in-1"; + (63): mapper = "[See submapper]"; + (64): mapper = "Tengen RAMBO-1"; + (65): mapper = "Irem H3001"; + (66): mapper = "xxROM"; + (67): mapper = "Sunsoft-3"; + (68): mapper = "Sunsoft-4"; + (69): mapper = "Sunsoft FME-7/Sunsoft 5A/Sunsoft 5B"; + (70): mapper = "Family Trainer Mat"; + (71): mapper = "Camerica"; + (72): mapper = "Jaleco JF-17 [16 KiB PRG ROM]"; + (73): mapper = "Konami VRC3"; + (74): mapper = "860908C"; + (75): mapper = "Konami VRC1"; + (76): mapper = "NAMCOT-3446"; + (77): mapper = "Napoleon Senki"; + (78): mapper = "74HC161/32"; + (79): mapper = "Tengen NINA-003/NINA-006"; + (80): mapper = "X1-005"; + (81): mapper = "N715021"; + (82): mapper = "X1-017"; + (83): mapper = "Cony & Yoko chip"; + (84): mapper = "PC-SMB2J [DEPRECATED]"; + (85): mapper = "Konami VRC7"; + (86): mapper = "Jaleco JF-13"; + (87): mapper = "JF87"; + (88): mapper = "Namco chip"; + (89): mapper = "Sunsoft 2.5"; + (90): mapper = "J.Y. Company ASIC [ROM nametables & extended mirroring]"; + (91): mapper = "J.Y. Company clone boards"; + (92): mapper = "Jaleco JF-17 [16 KiB PRG ROM]"; + (187): mapper = "Kǎ Shèng A98402"; + (256): mapper = "V.R. Technology OneBus"; + (355): mapper = "Jùjīng 3D-BLOCK"; + (424): mapper = "Lexibook Retro TV Game Console"; + (426): mapper = "V.R. Technology OneBus [Serial ROM in GPIO]"; + (594): mapper = "Rinco FSG2"; + (595): mapper = "NES-4MROM-512"; + } + match (mapperValue) { + (0): designation = "NROM"; + (1): designation = "SxROM"; + (4): designation = "TxROM"; + } + if (mapperValue == 3) { + match (submapperValue) { + (0): submapper = "Bus conflict"; + (1): submapper = "No bus conflicts"; + (2): submapper = "AND-type bus conflicts"; + } + } + else if (mapperValue == 12) { + match (submapperValue) { + (0): submapper = "Supertone SL-5020B"; + (1): submapper = "Front Fareast Magic Card 4M RAM Cartridge"; + } + } + else if (mapperValue == 16) { + match (submapperValue) { + (0): submapper = "Both Bandai FCG-1/2 and Bandai LZ93D50"; + (4): submapper = "Bandai FCG-1/2"; + (5): submapper = "Bandai LZ93D50"; + } + } + else if (mapperValue == 34) { + match (submapperValue) { + (0): submapper = "Tengen NINA-001/NINA-002"; + (1): submapper = "BNROM"; + } + } + else if (mapperValue == 40) { + match (submapperValue) { + (0): submapper = "NTDEC 2722"; + (1): submapper = "NTDEC 2752"; + } + } + else if (mapperValue == 51) { + if (submapperValue == 1) submapper = "11-in-1 Ball Games"; + } + else if (mapperValue == 61) { + match (submapperValue) { + (0): submapper = "NTDEC 0324"; + (1): submapper = "NTDEC BS-N032"; + (_): submapper = "GS-2017"; + } + } + else if (mapperValue == 63) { + match (submapperValue) { + (0): submapper = "NTDEC TH2xxx-x"; + (1): submapper = "82-in-1"; + } + } + std::print("Mapper: " + mapper + " (" + std::string::to_string(mapperValue) + ")"); + if (submapper) std::print("Submapper: " + submapper + " (" + std::string::to_string(submapperValue) + ")"); + if (designation) std::print("Designation: " + designation); +}; +identifyMapper(mapperValue, $[0x08] >> 4); + u8 trainer[512*header.flags.trainerOf512Bytes] @ 0x10; enum CHRType : u8 { - CHRROM, - CHRRAM + CHRROM, + CHRRAM }; fn chrType(u8 value) { - CHRType enumValue = value; - return enumValue; + CHRType enumValue = value; + return enumValue; }; fn chrSize(u8 value) { - u24 actualSize; - if (value == 4) actualSize = 262144; - else actualSize = 8192 * header.chrROMSizeBy8KiBs; - return std::string::to_string(value) + " (" + std::string::to_string(actualSize) + ")"; + u24 actualSize; + if (value == 4) actualSize = 262144; + else actualSize = 8192 * header.chrROMSizeBy8KiBs; + return std::string::to_string(value) + " (" + std::string::to_string(actualSize) + ")"; }; bitfield MemorySize { - prgROMSizeBy16KiBs : 4; - chrType : 1 [[format("chrType")]]; - chrSize : 3 [[format("chrSize")]]; + prgROMSizeBy16KiBs : 4; + chrType : 1 [[format("chrType")]]; + chrSize : 3 [[format("chrSize")]]; }; enum ArrangementList : u8 { - Horizontal, - Vertical + Horizontal, + Vertical }; fn arrangement(u8 value) { - ArrangementList enumValue = value; - return enumValue; + ArrangementList enumValue = value; + return enumValue; }; enum MapperList : u8 { - NROM, - CNROM, - UNROM, - GNROM, - MMC + NROM, + CNROM, + UNROM, + GNROM, + MMC }; fn mapper(u8 value) { - MapperList enumValue = value; - return enumValue; + MapperList enumValue = value; + return enumValue; }; bitfield CartridgeType { - nametableArrangement : 1 [[format("arrangement")]]; - mapper : 7 [[format("mapper")]]; + nametableArrangement : 1 [[format("arrangement")]]; + mapper : 7 [[format("mapper")]]; }; enum EncodingType : u8 { - None, - ASCII, - JIS + None, + ASCII, + JIS }; fn titleLength(u8 value) { return value+1; }; struct OfficialHeader { - char title[16] [[hex::spec_name("Title Registration Area")]]; - u16 programChecksum; - u16 characterChecksum; - MemorySize memorySize [[hex::spec_name("Cartridge Memory Size")]]; - CartridgeType cartridgeType; - EncodingType encodingType [[hex::spec_name("Registration Characters Type Distinction")]]; - u8 titleLength [[hex::spec_name("Registration Characters Count"), transform("titleLength")]]; - u8 licenseeID [[hex::spec_name("Maker Code")]]; - u8 complementaryChecksum [[hex::spec_name("Checksum for characterChecksum~makerID")]]; + char title[16] [[hex::spec_name("Title Registration Area")]]; + u16 programChecksum; + u16 characterChecksum; + MemorySize memorySize [[hex::spec_name("Cartridge Memory Size")]]; + CartridgeType cartridgeType; + EncodingType encodingType [[hex::spec_name("Registration Characters Type Distinction")]]; + u8 titleLength [[hex::spec_name("Registration Characters Count"), transform("titleLength")]]; + u8 licenseeID [[hex::spec_name("Maker Code")]]; + u8 complementaryChecksum [[hex::spec_name("Checksum for characterChecksum~makerID")]]; }; -u24 calculatedPRGROMSize = 16384 * ((0x0100 * ($[9] & 0x0F)) * ($[7] & 12 == 8) + header.prgROMSizeBy16KiBs); +u16 PRGROM_MINIMUM_SIZE = 16384; +u8 LOWER_TWO_DIGITS = 0b11; +u32 calculatedPRGROMSize = (std::mem::size()-16-(4096*($[0x0E]&LOWER_TWO_DIGITS))) * ($[0x09]&FILLED_HIGHER_NYBBLE==0x0F) ++ (PRGROM_MINIMUM_SIZE * ((0x0100 * ($[0x09] & FILLED_HIGHER_NYBBLE)) * ($[0x07] & FILLED_NES2_FLAGS == SET_NES2_FLAGS) + header.prgROMSizeBy16KiBs)) * ($[0x09]&FILLED_HIGHER_NYBBLE!=0x0F); fn hasOfficialHeader() { - u8 sum; - for (u8 i = 0, i < 8, i += 1) { - sum += $[(calculatedPRGROMSize - 14) + i]; - } - return !sum; + u8 sum; + for (u8 i = 0, i < 8, i += 1) { + sum += $[(calculatedPRGROMSize - 14) + i]; + } + return !sum; }; +u8 OFFICIAL_HEADER_SIZE = 26; +u8 VECTORS_SIZE = 6; + struct PRGROM { - u8 data[calculatedPRGROMSize - 26 * hasOfficialHeader() - 6]; - if (hasOfficialHeader()) - OfficialHeader officialHeader; - u16 nmi; - u16 resetVector [[comment("Entry Point")]]; - u16 externalIRQ; + u8 data[calculatedPRGROMSize - OFFICIAL_HEADER_SIZE * hasOfficialHeader() - VECTORS_SIZE]; + if (hasOfficialHeader()) + OfficialHeader officialHeader; + u16 nmi; + u16 resetVector [[comment("Entry Point")]]; + u16 externalIRQ; }; - PRGROM prgROM @ 0x10 + sizeof(trainer); -u8 chrROM[8192 * ((0x0100 * ($[9] >> 4)) * ($[7] & 12 == 8) + header.chrROMSizeBy8KiBs)] @ addressof(prgROM) + 16384 * header.prgROMSizeBy16KiBs; -fn identifyMapper(u16 mapperValue, u8 submapperValue) { - str mapper; - str submapper; - str designation; - match (mapperValue) { - (0): mapper = "NROM"; - (1): mapper = "MMC1B"; - (2): mapper = "UxROM"; - (3): mapper = "CNROM-32"; - (4): mapper = "MMC3"; - (5): mapper = "MMC5"; - (6): mapper = "Front Fareast Magic Card 1/2M RAM Cartridge"; - (7): mapper = "AxROM"; - (8): mapper = "Front Fareast Magic Card 1/2M RAM Cartridge (Initial latch-based banking mode 4)"; - (9): mapper = "MMC2"; - (10): mapper = "MMC4"; - (11): mapper = "Color Dreams"; - (12): mapper = "(See submapper)"; - (13): mapper = "CPROM"; - (14): mapper = "SL-1632"; - (15): mapper = "K-102xx"; - (16): mapper = "Bandai FCG boards"; - (17): mapper = "Front Fareast Super Magic Card RAM cartridge"; - (18): mapper = "SS88006 (Jaleco)"; - (19): mapper = "Namco 129/163"; - (20): mapper = "Famicom Disk System"; - (21): mapper = "VRC4a/VRC4c"; - (22): mapper = "VRC2a"; - (23): mapper = "VRC4e or VRC2b + VRC4f"; - (24): mapper = "VRC6a"; - (25): mapper = "VRC4d or VRC2c + VRC4b"; - (26): mapper = "VRC6b"; - (27): mapper = "World Hero"; - (28): mapper = "Action 53"; - (29): mapper = "RET-CUFROM"; - (30): mapper = "UNROM 512"; - (31): mapper = "NSF"; - (32): mapper = "G-101"; - (33): mapper = "TC0190"; - (34): mapper = "(See submapper)"; - (35): mapper = "J.Y. Company (8KiB WRAM)"; - (36): mapper = "01-22000-400"; - (37): mapper = "SMB+Tetris+NWC"; - (38): mapper = "Crime Busters"; - (39): mapper = "Study & Game 32-in-1"; - (40): mapper = "NTDEC 27xx"; - (41): mapper = "Caltron 6-in-1"; - (42): mapper = "FDS -> NES Hacks"; - (43): mapper = "TONY-I/YS-612"; - (44): mapper = "Super Big 7-in-1"; - (45): mapper = "GA23C"; - (46): mapper = "Rumble Station"; - (47): mapper = "Super Spike V'Ball + NWC"; - (48): mapper = "TC0690"; - (49): mapper = "Super HIK 4-in-1"; - (50): mapper = "761214"; - (51): mapper = "11-in-1 Ball Games"; - (52): mapper = "Realtec 8213"; - (53): mapper = "Supervision 16-in-1"; - (54): mapper = "Novel Diamond 9999999-in-1"; - (55): mapper = "QFJ"; - (56): mapper = "KS202"; - (57): mapper = "GK"; - (58): mapper = "WQ"; - (59): mapper = "T3H53"; - (60): mapper = "Reset-based NROM-128 4-in-1"; - (61): mapper = "(See submapper)"; - (62): mapper = "Super 700-in-1"; - (63): mapper = "(See submapper)"; - (64): mapper = "RAMBO-1"; - (65): mapper = "H3001"; - (66): mapper = "GxROM"; - (67): mapper = "Sunsoft-3"; - (68): mapper = "Sunsoft-4"; - (69): mapper = "Sunsoft FME-7/Sunsoft 5A/Sunsoft 5B"; - (70): mapper = "Family Trainer Mat"; - (71): mapper = "Camerica"; - (72): mapper = "JF-17"; - (73): mapper = "VRC3"; - (74): mapper = "860908C"; - (75): mapper = "VRC1"; - (76): mapper = "NAMCOT-3446"; - (77): mapper = "Napoleon Senki"; - (78): mapper = "74HC161/32"; - (79): mapper = "NINA-003/NINA-006"; - (80): mapper = "X1-005"; - (81): mapper = "N715021"; - (82): mapper = "X1-017"; - } - if (mapperValue == 3) { - match (submapperValue) { - (0): submapper = "Bus conflict"; - (1): submapper = "No bus conflicts"; - (2): submapper = "AND-type bus conflicts"; - } - } - else if (mapperValue == 4) designation = "TxROM"; - else if (mapperValue == 12) { - match (submapperValue) { - (0): submapper = "SL-5020B (Gouder)"; - (1): submapper = "Front Fareast Magic Card 4M RAM Cartridge"; - } - } - else if (mapperValue == 16) { - match (submapperValue) { - (0): submapper = "FCG-1/2 or LZ93D50"; - (4): submapper = "FCG-1/2"; - (5): submapper = "LZ93D50"; - } - } - else if (mapperValue == 34) { - match (submapperValue) { - (0): submapper = "NINA-001/NINA-002"; - (1): submapper = "BNROM"; - } - } - else if (mapperValue == 40) { - match (submapperValue) { - (0): submapper = "NTDEC 2722"; - (1): submapper = "NTDEC 2752"; - } - } - else if (mapperValue == 61) { - match (submapperValue) { - (0): submapper = "NTDEC 0324"; - (1): submapper = "NTDEC BS-N032"; - (_): submapper = "GS-2017"; - } - } - else if (mapperValue == 63) { - match (submapperValue) { - (0): submapper = "TH2291-3"; - (1): submapper = "82AB"; - } - } - std::print("Mapper: " + mapper + "(" + std::string::to_string(mapperValue) + ")"); - if (submapper) std::print("Submapper: " + submapper + "(" + std::string::to_string(submapperValue) + ")"); - if (designation) std::print("Designation: " + designation); +u16 CHRROM_MINIMUM_SIZE = 8192; +u24 calculatedCHRROMSize = CHRROM_MINIMUM_SIZE * ((0x0100 * ($[0x09] >> 4)) * ($[0x07] & FILLED_NES2_FLAGS == SET_NES2_FLAGS) + header.chrROMSizeBy8KiBs); +u8 chrROM[calculatedCHRROMSize] @ addressof(prgROM) + calculatedPRGROMSize; + +struct MiscellaneousROMs { + if ($[0x07] & LOWER_TWO_DIGITS == ConsoleType::PlayChoice10) { + u8 instructionsROM[8192] [[hex::spec_name("INST-ROM")]]; + u8 decryptionDataPROM[16]; + u8 decryptionCounterOutPROM[16]; + } + else if ($[0x0D] == ExtendedConsoleType::VT3xx) { + u8 embeddedROM[4096]; + } + else if (mapperValue == 355) { + u8 antiCloningROM[1024]; + } }; -identifyMapper(0x0100 * ($[8] & 0x0F) + 0x10 * ($[7] & 0x0F) + header.flags.lowerMapperNybble, $[8] >> 4); + +MiscellaneousROMs miscellaneousROMs[$[0x0E] & LOWER_TWO_DIGITS > 0] @ addressof(prgROM) + calculatedPRGROMSize + calculatedCHRROMSize; diff --git a/patterns/pe.hexpat b/patterns/pe.hexpat index 4958bbf..4c3a558 100644 --- a/patterns/pe.hexpat +++ b/patterns/pe.hexpat @@ -47,10 +47,10 @@ struct DOSHeader { u16 initialCSValue [[hex::spec_name("e_cs")]]; u16 relocationsTablePointer [[hex::spec_name("e_lfarlc")]]; u16 overlayNumber [[hex::spec_name("e_ovno")]]; - u16 reservedWords[4] [[hex::spec_name("e_res")]]; + padding[8]; u16 oemIdentifier [[hex::spec_name("e_oemid")]]; u16 oemInformation [[hex::spec_name("e_oeminfo")]]; - u16 otherReservedWords[10] [[hex::spec_name("e_res2")]]; + padding[20]; u32 coffHeaderPointer [[hex::spec_name("e_lfanew")]]; }; @@ -1115,7 +1115,7 @@ struct Section { } [[name(sectionsTable[currentSectionIndex-1].name)]]; Section sections[coffHeader.numberOfSections] @ coffHeader.optionalHeader.sizeOfHeaders * !sectionsTable[0].sizeOfRawData - + sectionsTable[0].ptrRawData * sectionsTable[0].sizeOfRawData>0; + + sectionsTable[0].ptrRawData * (sectionsTable[0].sizeOfRawData>0); // Symbol & String Tables enum SectionNumberType : s16 {