Files
ImHex-Patterns/patterns/gb.hexpat
Mrmaxmeier c533017d0b git: Various style fixes everywhere, removing whitespaces (#321)
* repo-wide: trim trailing spaces

Note: This doesn't touch the .tbl files in encodings/ since they include
meaningful trailing spaces (`20= `)

* patterns: clean up duplicate semicolons

* ELF: add header magic check

* glTF: use type::Magic for magic value

* glTF: check that the file size in the header matches

* xgstexture: fix generics syntax for magic value

* JPEG: define hex enum with 0x00 instead of 0X00

* CI: update deprecated actions

---------

Co-authored-by: Nik <werwolv98@gmail.com>
2024-11-24 11:41:26 +01:00

384 lines
11 KiB
Rust
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#pragma author WerWolv
#pragma description Gameboy ROM
#pragma MIME application/x-gameboy-rom
import type.size;
import std.string;
import std.mem;
const u16 ROMBANKSIZE_16K = 0x4000;
const u16 ROMBANKSIZE_32K = 0x8000;
bool uppercaseROMFeatures in;
bool brandedROMFeatures in;
bitfield CGB {
padding : 2;
PGB_MODE : 2;
padding : 2;
CGB_ONLY : 1 [[comment("gbcOnly")]];
CGB_SUPPORT : 1 [[comment("supportsGBC")]];
} [[comment("GBCFlags")]];
namespace format {
fn cart_size(u8 cartSizeType) {
u32 romSize = 32768 * (1 << cartSizeType);
u16 romBanks = 2 * (1 << cartSizeType);
if (cartSizeType == 0x52) {
romSize = 1153434;
romBanks = 72;
}
if (cartSizeType == 0x53) {
romSize = 1258291;
romBanks = 80;
}
if (cartSizeType == 0x54) {
romSize = 1572864;
romBanks = 96;
}
return std::format("size: {}, banks: {}", type::impl::size_formatter(romSize), romBanks);
};
fn ram_type(u8 ramType) {
u16 ramSize;
u16 ramBanks;
if(ramType == 2) {
ramSize = 8192;
ramBanks = 1;
}
if(ramType == 3) {
ramSize = 32768;
ramBanks = 4;
}
if(ramType == 4) {
ramSize = 131072;
ramBanks = 16;
}
if(ramType == 5) {
ramSize = 65536;
ramBanks = 8;
}
return std::format("size: {}, banks: {}", type::impl::size_formatter(ramSize), ramBanks);
};
fn rom_features(u8 type) {
str result = "( ";
if (brandedROMFeatures) match(type) {
(0xFC): result += "pocket ";
(0xFD): result += "bandai ";
}
match(type) {
(0x00): result += "no_mbc";
(0x01): result += "mbc1";
(0x02): result += "mbc1 | ram";
(0x03): result += "mbc1 | ram | battery";
(0x05): result += "mbc2";
(0x06): result += "mbc2 | battery";
(0x08): result += "no_mbc | ram";
(0x09): result += "no_mbc | ram | battery";
(0x0B): result += "mmm01";
(0x0C): result += "mmm01 | ram";
(0x0D): result += "mmm01 | ram | battery";
(0x0F): result += "mbc3 | timer | battery";
(0x10): result += "mbc3 | timer | ram | battery";
(0x11): result += "mbc3";
(0x12): result += "mbc3 | ram";
(0x13): result += "mbc3 | ram | battery";
(0x19): result += "mbc5";
(0x1A): result += "mbc5 | ram";
(0x1B): result += "mbc5 | ram | battery";
(0x1C): result += "mbc5 | rumble";
(0x1D): result += "mbc5 | rumble | ram";
(0x1E): result += "mbc5 | rumble | ram | battery";
(0x20): result += "mbc6";
(0x22): result += "mbc7 | sensor | rumble";
(0xFC): result += "camera";
(0xFD): result += "tama5";
(0xFE): result += "huc3";
(0xFF): result += "huc1 | ram | battery";
}
if (uppercaseROMFeatures) result = std::string::to_upper(result);
return result + " )";
};
fn licensee_code(u8 code) {
match(code) {
(0x00): return "None";
(0x01 | 0x31): return "Nintendo";
(0x08 | 0x38): return "Capcom";
(0x09): return "Hot-B";
(0x0A | 0xE0): return "Jaleco";
(0x0B): return "Coconuts Japan";
(0x0C | 0x6E): return "Elite Systems";
(0x13 | 0x69): return "EA (Electronic Arts)";
(0x18): return "Hudsonsoft";
(0x19): return "ITC Entertainment";
(0x1A): return "Yanoman";
(0x1D): return "Japan Clary";
(0x1F | 0x4A | 0x61): return "Virgin Interactive";
(0x24): return "PCM Complete";
(0x25): return "San-X";
(0x28): return "Kotobuki Systems";
(0x29): return "Seta";
(0x30 | 0x70): return "Infogrames";
(0x32 | 0xA2 | 0xB2 | 0xC4): return "Bandai";
(0x33): return "See new licensee code";
(0x34 | 0xA4): return "Konami";
(0x35): return "HectorSoft";
(0x39 | 0x9D): return "Banpresto";
(0x3C): return ".Entertainment i";
(0x3E): return "Gremlin";
(0x41): return "Ubisoft";
(0x42 | 0xEB): return "Atlus";
(0x44 | 0x4D): return "Malibu";
(0x46 | 0xCF): return "Angel";
(0x47): return "Spectrum Holoby";
(0x49): return "Irem";
(0x4F): return "U.S. Gold";
(0x50): return "Absolute";
(0x51 | 0xB0): return "Acclaim";
(0x52): return "Activision";
(0x53): return "American Sammy";
(0x54): return "GameTek";
(0x55): return "Park Place";
(0x56 | 0xDB | 0xFF): return "LJN";
(0x57): return "Matchbox";
(0x59): return "Milton Bradley";
(0x5A): return "Mindscape";
(0x5B): return "Romstar";
(0x5C | 0xD6): return "Naxat Soft";
(0x5D): return "Tradewest";
(0x60): return "Titus";
(0x67): return "Ocean Interactive";
(0x6F): return "Electro Brain";
(0x71): return "Interplay";
(0x72 | 0xAA): return "Broderbund";
(0x73): return "Sculptered Soft";
(0x75): return "The Sales Curve";
(0x78): return "t.hq";
(0x79): return "Accolade";
(0x7A): return "Triffix Entertainment";
(0x7C): return "Microprose";
(0x7F | 0xC2): return "Kemco";
(0x80): return "Misawa Entertainment";
(0x83): return "Lozc";
(0x86 | 0xC4): return "Tokuma Shoten Intermedia";
(0x8B): return "Bullet-Proof Software";
(0x8C): return "Vic Tokai";
(0x8E): return "Ape";
(0x8F): return "I'Max";
(0x91): return "Chunksoft Co.";
(0x92): return "Video System";
(0x93): return "Tsubaraya Productions Co.";
(0x95): return "Varie Corporation";
(0x96): return "Yonezawa/SPal";
(0x97): return "Kaneko";
(0x99): return "Arc";
(0x9A): return "Nihon Bussan";
(0x9B): return "Tecmo";
(0x9C): return "Imagineer";
(0x9F): return "Nova";
(0xA1): return "Hori Electric";
(0xA6): return "Kawada";
(0xA7): return "Takara";
(0xA9): return "Technos Japan";
(0xAC): return "Toei Animation";
(0xAD): return "Toho";
(0xAF): return "Namco";
(0xB1): return "ASCII or Nexsoft";
(0xB4): return "Square Enix";
(0xB6): return "HAL Laboratory";
(0xB7): return "SNK";
(0xB9 | 0xCE): return "Pony Canyon";
(0xBA): return "Culture Brain";
(0xBB): return "Sunsoft";
(0xBD): return "Sony Imagesoft";
(0xBF): return "Sammy";
(0xC0 | 0xD0): return "Taito";
(0xC3): return "Squaresoft";
(0xC5): return "Data East";
(0xC6): return "Tonkinhouse";
(0xC8): return "Koei";
(0xC9): return "UFL";
(0xCA): return "Ultra";
(0xCB): return "Vap";
(0xCC): return "Use Corporation";
(0xCD): return "Meldac";
(0xD1): return "Sofel";
(0xD2): return "Quest";
(0xD3): return "Sigma Enterprises";
(0xD4): return "ASK Kodansha Co.";
(0xD7): return "Copya System";
(0xDA): return "Tomy";
(0xDD): return "NCS";
(0xDE): return "Human";
(0xDF): return "Altron";
(0xE1): return "Towa Chiki";
(0xE2): return "Yutaka";
(0xE3): return "Varie";
(0xE5): return "Epoch";
(0xE7): return "Athena";
(0xE8): return "Asmik";
(0xE9): return "Natsume";
(0xEA): return "King Records";
(0xEC): return "Epic/Sony Records";
(0xEE): return "IGS";
(0xF0): return "A Wave";
(0xF3): return "Extreme Entertainment";
}
return "Unknown Licensee";
};
fn new_licensee_code(str a) {
if (std::mem::read_unsigned(0x14B, 1) != 0x33) return "See old licensee code";
match(a) {
("00"): return "None";
("01"): return "Nintendo R&D1";
("08"): return "Capcom";
("13"): return "Electronic Arts";
("18"): return "Hudson Soft";
("19"): return "b-ai";
("20"): return "KSS";
("22"): return "pow";
("24"): return "PCM Complete";
("25"): return "san-x";
("28"): return "Kemco Japan";
("29"): return "seta";
("30"): return "Viacom";
("31"): return "Nintendo";
("32"): return "Bandai";
("33"): return "Ocean/Acclaim";
("34"): return "Konami";
("35"): return "Hector";
("37"): return "Taito";
("38"): return "Hudson";
("39"): return "Banpresto";
("41"): return "Ubi Soft";
("42"): return "Atlus";
("44"): return "Malibu";
("46"): return "Angel";
("47"): return "Bullet-Proof Software";
("49"): return "irem";
("50"): return "Absolute";
("51"): return "Acclaim";
("52"): return "Activision";
("53"): return "American Sammy";
("54"): return "Konami";
("55"): return "Hi tech entertainment";
("56"): return "LJN";
("57"): return "Matchbox";
("58"): return "Mattel";
("59"): return "Milton Bradley";
("60"): return "Titus";
("61"): return "Virgin";
("64"): return "LucasArts";
("67"): return "Ocean";
("69"): return "Electronic Arts";
("70"): return "Infogrames";
("71"): return "Interplay";
("72"): return "Broderbund";
("73"): return "sculptured";
("75"): return "sci";
("78"): return "THQ";
("79"): return "Accolade";
("80"): return "misawa";
("83"): return "lozc";
("86"): return "Tokuma Shoten Intermedia";
("87"): return "Tsukuda Original";
("91"): return "Chunksoft";
("92"): return "Video system";
("93"): return "Ocean/Acclaim";
("95"): return "Varie";
("96"): return "Yonezawa/spal";
("97"): return "Kaneko";
("99"): return "Pack in soft";
("9H"): return "Bottom Up";
("A4"): return "Konami (Yu-Gi-Oh!)";
("BL"): return "MTO";
("DK"): return "Kodansha";
}
return "Unknown";
};
using CGB;
fn null_cgb_flags(CGB flags) {
return "NO_CGB";
};
}
enum DestinationType : u8 {
Japanese,
NonJapanese
};
enum SGBFlagType : u8 {
NoSGBFunctionality,
SGBFunctionality = 0x03
};
struct Header {
char title[16-(std::mem::read_unsigned(addressof(this)+15, 1) >= 0x80)];
if (std::mem::read_unsigned(addressof(this)+15, 1) == 0)
CGB gbcFlags @ $-1 [[format("format::null_cgb_flags")]];
else if (std::mem::read_unsigned(addressof(this)+15, 1) >= 0x80)
CGB gbcFlags;
char newLicenseeCode[2] [[format("format::new_licensee_code")]];
SGBFlagType sgbFlag;
u8 romType [[format("format::rom_features")]];
u8 cartSize [[format("format::cart_size")]];
u8 ramType [[format("format::ram_type")]];
DestinationType destination;
u8 licenseeCode [[format("format::licensee_code")]];
u8 maskROMVersionNumber;
u8 headerChecksum [[comment("Checksum for: $134-$14C")]];
u16 globalChecksum [[comment("Checksum for entire range")]];
};
bitfield pixel_packed {
p1 : 1;
p2 : 1;
p3 : 1;
p4 : 1;
p5 : 1;
p6 : 1;
p7 : 1;
p8 : 1;
};
struct CartridgeStart {
u8 entryCode[4];
pixel_packed logo[0x30];
Header header;
};
struct JumpVectors {
u8 rst1[8] [[comment("rst $1")]];
u8 rst2[8] [[comment("rst $2")]];
u8 rst3[8] [[comment("rst $3")]];
u8 rst4[8] [[comment("rst $4")]];
u8 rst5[8] [[comment("rst $5")]];
u8 rst6[8] [[comment("rst $6")]];
u8 rst7[8] [[comment("rst $7")]];
u8 rst8[8] [[comment("rst $8")]];
u8 int1[8] [[comment("vblank")]];
u8 int2[8] [[comment("lcd stat")]];
u8 int3[8] [[comment("timer")]];
u8 int4[8] [[comment("serial")]];
u8 int5[8] [[comment("joypad")]];
};
struct romBank16K {
u8 Bank[ROMBANKSIZE_16K];
};
struct romBank32K {
u8 Bank[ROMBANKSIZE_32K];
};
romBank16K romBanks16K[std::mem::size() / ROMBANKSIZE_16K] @ 0x00;
romBank32K romBanks32K[std::mem::size() / ROMBANKSIZE_32K] @ 0x00;
JumpVectors jumpVectors @ 0x00 [[comment("Instructions called on interrupts or RST instructions")]];
CartridgeStart cartridgeStart @ 0x100;