mirror of
https://github.com/WerWolv/ImHex-Patterns.git
synced 2026-03-27 23:37:04 -05:00
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 <werwolv98@gmail.com>
This commit is contained in:
@@ -2,87 +2,265 @@
|
||||
#pragma description Nintendo Entertainment System ROM (.nes)
|
||||
#pragma MIME application/x-nes-rom
|
||||
|
||||
import std.mem;
|
||||
import std.string;
|
||||
|
||||
bitfield iNES07Flags {
|
||||
mirroringIsVertical : 1;
|
||||
batterybackedPRGRAM : 1;
|
||||
trainerOf512Bytes : 1;
|
||||
ignoreMirroring : 1;
|
||||
mapperLowerNybble : 4;
|
||||
vsUnisystem : 1;
|
||||
playchoice10 : 1;
|
||||
nes2Format : 2 [[name("nes2.0Format")]];
|
||||
mapperHigherNybble : 4;
|
||||
} [[name("iNES0.7Flags")]];
|
||||
|
||||
bitfield Flags9 {
|
||||
isPAL : 1;
|
||||
padding : 7;
|
||||
bitfield Flags {
|
||||
mirroringIsHorizontal : 1;
|
||||
ignoreMirroring : 1;
|
||||
batterybackedPRGRAM : 1;
|
||||
trainerOf512Bytes : 1;
|
||||
lowerMapperNybble : 4;
|
||||
};
|
||||
|
||||
bitfield Flags10 {
|
||||
tvSystem : 2;
|
||||
padding : 2;
|
||||
prgRAM : 1;
|
||||
busConflicts : 1;
|
||||
padding : 2;
|
||||
enum ConsoleType : u8 {
|
||||
Regular,
|
||||
VsSystem,
|
||||
PlayChoice10,
|
||||
ExtendedConsoleType
|
||||
};
|
||||
|
||||
struct iNESFlags {
|
||||
iNES07Flags ines07Flags [[name("ines0.7Flags")]];
|
||||
if (!ines07Flags.nes2Format) {
|
||||
u8 prgRAM8KBMultiplier;
|
||||
Flags9 flags9;
|
||||
Flags10 flags10;
|
||||
restLength = 5;
|
||||
}
|
||||
else {
|
||||
restLength = 9;
|
||||
}
|
||||
fn consoleType(u8 bits) {
|
||||
ConsoleType type = bits;
|
||||
return type;
|
||||
};
|
||||
|
||||
u8 restLength;
|
||||
fn nes2Format(u8 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;
|
||||
};
|
||||
|
||||
bitfield iNESFlags9 {
|
||||
tvSystem : 1 [[comment("0 = NTSC, 1 = PAL")]];
|
||||
padding : 7;
|
||||
};
|
||||
|
||||
fn formatDualTVSystem(u8 bits) {
|
||||
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;
|
||||
};
|
||||
|
||||
bitfield MapperExtra {
|
||||
highestMapperNybble : 4;
|
||||
submapper : 4;
|
||||
};
|
||||
|
||||
bitfield ROMSize {
|
||||
extraPRGROMSize : 4;
|
||||
extraCHRROMSize : 4;
|
||||
};
|
||||
|
||||
bitfield PRGRAMSize {
|
||||
prgRAMShiftCount : 4;
|
||||
eepromShiftCount : 4 [[comment("EEPROM = Non-volatile PRG RAM")]];
|
||||
};
|
||||
|
||||
bitfield CHRRAMSize {
|
||||
chrRAMSizeShiftCount : 4;
|
||||
chrNVRAMSizeShiftCount : 4;
|
||||
};
|
||||
|
||||
enum TimingList : u8 {
|
||||
NTSC,
|
||||
PAL,
|
||||
MultiRegion,
|
||||
Dendy
|
||||
};
|
||||
|
||||
fn Timing(u8 value) {
|
||||
TimingList type = value;
|
||||
return type;
|
||||
};
|
||||
|
||||
bitfield Timing {
|
||||
processorTiming : 2 [[format("Timing")]];
|
||||
padding : 6;
|
||||
};
|
||||
|
||||
bitfield VsSystemType {
|
||||
vsPPUType : 4;
|
||||
vsHardwareType: 4;
|
||||
};
|
||||
|
||||
enum ExtendedConsoleType : ConsoleType {
|
||||
DecimalModeFamiclone = 3,
|
||||
PlugThrough,
|
||||
VT01,
|
||||
VT02,
|
||||
VT03,
|
||||
VT09,
|
||||
VT32,
|
||||
VT3xx,
|
||||
UM6578,
|
||||
FamicomNetworkSystem
|
||||
};
|
||||
|
||||
fn formatExtendedConsoleType(u8 nybble) {
|
||||
ExtendedConsoleType type = nybble;
|
||||
return type;
|
||||
};
|
||||
|
||||
bitfield ExtendedConsoleTypeByte {
|
||||
type : 4 [[format("formatExtendedConsoleType")]];
|
||||
padding : 4;
|
||||
};
|
||||
|
||||
bitfield MiscellaneousROMs {
|
||||
numberOfMiscellaneousROMs : 2;
|
||||
padding : 6;
|
||||
};
|
||||
|
||||
bitfield DefaultExpansionDevice {
|
||||
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;
|
||||
};
|
||||
|
||||
fn renderEOF(str string) {
|
||||
return "\"NES<EOF>\"";
|
||||
};
|
||||
|
||||
struct Header {
|
||||
char identifier[4];
|
||||
u8 prgROM16KBMultiplier;
|
||||
u8 chrROM8KBMultiplier;
|
||||
iNESFlags inesFlags;
|
||||
char rest[restLength];
|
||||
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;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
Header header @ 0x00;
|
||||
|
||||
enum EncodingType : u8 {
|
||||
ASCII = 1
|
||||
u8 trainer[512*header.flags.trainerOf512Bytes] @ 0x10;
|
||||
|
||||
enum CHRType : u8 {
|
||||
CHRROM,
|
||||
CHRRAM
|
||||
};
|
||||
|
||||
fn chrType(u8 value) {
|
||||
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) + ")";
|
||||
};
|
||||
|
||||
bitfield MemorySize {
|
||||
prgROMSizeBy16KiBs : 4;
|
||||
chrType : 1 [[format("chrType")]];
|
||||
chrSize : 3 [[format("chrSize")]];
|
||||
};
|
||||
|
||||
enum ArrangementList : u8 {
|
||||
Horizontal,
|
||||
Vertical
|
||||
};
|
||||
|
||||
fn arrangement(u8 value) {
|
||||
ArrangementList enumValue = value;
|
||||
return enumValue;
|
||||
};
|
||||
|
||||
enum MapperList : u8 {
|
||||
NROM,
|
||||
CNROM,
|
||||
UNROM,
|
||||
GNROM,
|
||||
MMC
|
||||
};
|
||||
|
||||
fn mapper(u8 value) {
|
||||
MapperList enumValue = value;
|
||||
return enumValue;
|
||||
};
|
||||
|
||||
bitfield CartridgeType {
|
||||
nametableArrangement : 1 [[format("arrangement")]];
|
||||
mapper : 7 [[format("mapper")]];
|
||||
};
|
||||
|
||||
enum EncodingType : u8 {
|
||||
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;
|
||||
u8 memorySize [[hex::spec_name("Cartridge Memory Size")]];
|
||||
u8 cartridgeType;
|
||||
EncodingType encodingType [[hex::spec_name("Registration Character Type Distinction")]];
|
||||
u8 titleLength [[hex::spec_name("Registration Characters Count")]];
|
||||
u8 makerID [[hex::spec_name("Maker Code")]];
|
||||
u8 complementaryChecksum;
|
||||
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")]];
|
||||
};
|
||||
|
||||
union OfficialHeaderUnion {
|
||||
u8 miscellaneousData[26];
|
||||
OfficialHeader officialHeader;
|
||||
u24 calculatedPRGROMSize = 16384 * ((0x0100 * $[9] & 0x0F) * ($[7] & 12 == 8) + header.prgROMSizeBy16KiBs);
|
||||
|
||||
fn hasOfficialHeader() {
|
||||
u8 sum;
|
||||
for (u8 i = 0, i < 8, i += 1) {
|
||||
sum += $[(calculatedPRGROMSize - 14) + i];
|
||||
}
|
||||
return !sum;
|
||||
};
|
||||
|
||||
struct PRGROM {
|
||||
u8 data[16384*header.prgROM16KBMultiplier-32];
|
||||
OfficialHeaderUnion officialHeaderUnion;
|
||||
u16 nmi;
|
||||
u16 entryPoint;
|
||||
u16 externalIRQ;
|
||||
u8 data[calculatedPRGROMSize - 26 * hasOfficialHeader() - 6];
|
||||
if (hasOfficialHeader())
|
||||
OfficialHeader officialHeader;
|
||||
u16 nmi;
|
||||
u16 resetVector [[comment("Entry Point")]];
|
||||
u16 externalIRQ;
|
||||
};
|
||||
|
||||
PRGROM prgROM @ sizeof(header);
|
||||
u8 chrROM[8192*header.chrROM8KBMultiplier] @ sizeof(header)+sizeof(prgROM);
|
||||
PRGROM prgROM @ 0x10 + sizeof(trainer);
|
||||
u8 chrROM[8192 * ((0x0100 * $[9] >> 4) * ($[7] & 12 == 8) + header.chrROMSizeBy8KiBs)] @ addressof(prgROM) + 16384 * header.prgROMSizeBy16KiBs;
|
||||
|
||||
Reference in New Issue
Block a user