mirror of
https://github.com/WerWolv/ImHex-Patterns.git
synced 2026-03-27 23:37:04 -05:00
* add support for cartridge size type $54 Added support for cartridge size type $54, corresponding to 1.5 MiB (96 banks). * add missing license * Add GBA Cartridge Header * Update README.md Added GBA information to README.md and corrected a typo.
176 lines
6.8 KiB
Rust
176 lines
6.8 KiB
Rust
#pragma author GekySan
|
||
#pragma description Game Boy Advance ROM Header
|
||
|
||
#pragma MIME application/x-gameboy-advance-rom
|
||
#pragma MIME application/x-agb-rom
|
||
#pragma MIME application/x-gba-rom
|
||
|
||
import std.string;
|
||
import std.mem;
|
||
import std.sys;
|
||
|
||
// In gb.hexpat
|
||
namespace format {
|
||
fn licensee_code(str code) {
|
||
match(code) {
|
||
("00"): return "None";
|
||
("01" | "31"): return "Nintendo";
|
||
("08" | "38"): return "Capcom";
|
||
("09"): return "Hot-B";
|
||
("0A" | "E0"): return "Jaleco";
|
||
("0B"): return "Coconuts Japan";
|
||
("0C" | "6E"): return "Elite Systems";
|
||
("13" | "69"): return "EA (Electronic Arts)";
|
||
("18"): return "Hudsonsoft";
|
||
("19"): return "ITC Entertainment";
|
||
("1A"): return "Yanoman";
|
||
("1D"): return "Japan Clary";
|
||
("1F" | "4A" | "61"): return "Virgin Interactive";
|
||
("24"): return "PCM Complete";
|
||
("25"): return "San-X";
|
||
("28"): return "Kotobuki Systems";
|
||
("29"): return "Seta";
|
||
("30" | "70"): return "Infogrames";
|
||
("32" | "A2" | "B2" | "C4"): return "Bandai";
|
||
("33"): return "See new licensee code";
|
||
("34" | "A4"): return "Konami";
|
||
("35"): return "HectorSoft";
|
||
("39" | "9D"): return "Banpresto";
|
||
("3C"): return ".Entertainment i";
|
||
("3E"): return "Gremlin";
|
||
("41"): return "Ubisoft";
|
||
("42" | "EB"): return "Atlus";
|
||
("44" | "4D"): return "Malibu";
|
||
("46" | "CF"): return "Angel";
|
||
("47"): return "Spectrum Holoby";
|
||
("49"): return "Irem";
|
||
("4F"): return "U.S. Gold";
|
||
("50"): return "Absolute";
|
||
("51" | "B0"): return "Acclaim";
|
||
("52"): return "Activision";
|
||
("53"): return "American Sammy";
|
||
("54"): return "GameTek";
|
||
("55"): return "Park Place";
|
||
("56" | "DB" | "FF"): return "LJN";
|
||
("57"): return "Matchbox";
|
||
("59"): return "Milton Bradley";
|
||
("5A"): return "Mindscape";
|
||
("5B"): return "Romstar";
|
||
("5C" | "D6"): return "Naxat Soft";
|
||
("5D"): return "Tradewest";
|
||
("60"): return "Titus";
|
||
("67"): return "Ocean Interactive";
|
||
("6F"): return "Electro Brain";
|
||
("71"): return "Interplay";
|
||
("72" | "AA"): return "Broderbund";
|
||
("73"): return "Sculptered Soft";
|
||
("75"): return "The Sales Curve";
|
||
("78"): return "t.hq";
|
||
("79"): return "Accolade";
|
||
("7A"): return "Triffix Entertainment";
|
||
("7C"): return "Microprose";
|
||
("7F" | "C2"): return "Kemco";
|
||
("80"): return "Misawa Entertainment";
|
||
("83"): return "Lozc";
|
||
("86" | "C4"): return "Tokuma Shoten Intermedia";
|
||
("8B"): return "Bullet-Proof Software";
|
||
("8C"): return "Vic Tokai";
|
||
("8E"): return "Ape";
|
||
("8F"): return "I'Max";
|
||
("91"): return "Chunksoft Co.";
|
||
("92"): return "Video System";
|
||
("93"): return "Tsubaraya Productions Co.";
|
||
("95"): return "Varie Corporation";
|
||
("96"): return "Yonezawa/S’Pal";
|
||
("97"): return "Kaneko";
|
||
("99"): return "Arc";
|
||
("9A"): return "Nihon Bussan";
|
||
("9B"): return "Tecmo";
|
||
("9C"): return "Imagineer";
|
||
("9F"): return "Nova";
|
||
("A1"): return "Hori Electric";
|
||
("A6"): return "Kawada";
|
||
("A7"): return "Takara";
|
||
("A9"): return "Technos Japan";
|
||
("AC"): return "Toei Animation";
|
||
("AD"): return "Toho";
|
||
("AF"): return "Namco";
|
||
("B1"): return "ASCII or Nexsoft";
|
||
("B4"): return "Square Enix";
|
||
("B6"): return "HAL Laboratory";
|
||
("B7"): return "SNK";
|
||
("B9" | "CE"): return "Pony Canyon";
|
||
("BA"): return "Culture Brain";
|
||
("BB"): return "Sunsoft";
|
||
("BD"): return "Sony Imagesoft";
|
||
("BF"): return "Sammy";
|
||
("C0" | "D0"): return "Taito";
|
||
("C3"): return "Squaresoft";
|
||
("C5"): return "Data East";
|
||
("C6"): return "Tonkinhouse";
|
||
("C8"): return "Koei";
|
||
("C9"): return "UFL";
|
||
("CA"): return "Ultra";
|
||
("CB"): return "Vap";
|
||
("CC"): return "Use Corporation";
|
||
("CD"): return "Meldac";
|
||
("D1"): return "Sofel";
|
||
("D2"): return "Quest";
|
||
("D3"): return "Sigma Enterprises";
|
||
("D4"): return "ASK Kodansha Co.";
|
||
("D7"): return "Copya System";
|
||
("DA"): return "Tomy";
|
||
("DD"): return "NCS";
|
||
("DE"): return "Human";
|
||
("DF"): return "Altron";
|
||
("E1"): return "Towa Chiki";
|
||
("E2"): return "Yutaka";
|
||
("E3"): return "Varie";
|
||
("E5"): return "Epoch";
|
||
("E7"): return "Athena";
|
||
("E8"): return "Asmik";
|
||
("E9"): return "Natsume";
|
||
("EA"): return "King Records";
|
||
("EC"): return "Epic/Sony Records";
|
||
("EE"): return "IGS";
|
||
("F0"): return "A Wave";
|
||
("F3"): return "Extreme Entertainment";
|
||
}
|
||
return "Unknown Licensee";
|
||
};
|
||
}
|
||
|
||
fn calcChecksum() {
|
||
u8 sum = 0;
|
||
u8 offset = 0xA0;
|
||
|
||
while (offset <= 0xBC) {
|
||
sum += std::mem::read_unsigned(offset, 1);
|
||
offset += 1;
|
||
}
|
||
|
||
return ((-((0x19 + sum) & 0xFF)) & 0xFF) == std::mem::read_unsigned(0xBD, 1);
|
||
};
|
||
|
||
struct GBAHeader {
|
||
u8 entryPoint[4] [[comment("ARM entry point code, typically a 'B rom_start' instruction")]];
|
||
u8 nintendoLogo[156] [[comment("Nintendo logo")]];
|
||
char gameTitle[12] [[comment("Game title, uppercase ASCII, max 12 characters")]];
|
||
char gameCode[4] [[comment("Game code, uppercase ASCII, 4 characters")]];
|
||
char makerCode[2] [[format("format::licensee_code"), comment("Maker code, uppercase ASCII, 2 characters")]];
|
||
u8 fixedValue [[comment("Fixed value, must be 0x96")]];
|
||
u8 unitCode [[comment("Main unit code, identifies required hardware (00h for GBA)")]];
|
||
u8 deviceType [[comment("Device type, usually 00h. Bit 7 relates to DACS/debug features")]];
|
||
u8 reserved1[7] [[comment("Reserved area, must be zero-filled")]];
|
||
u8 softwareVersion [[comment("Software version number, usually 00h")]];
|
||
u8 complementCheck [[comment("Header checksum, required for validation")]];
|
||
u8 reserved2[2] [[comment("Reserved area, must be zero-filled")]];
|
||
};
|
||
|
||
|
||
if (!calcChecksum()) {
|
||
std::error("Checksum validation failed: Calculated value does not match the expected checksum in the header.");
|
||
}
|
||
|
||
GBAHeader gbaHeader @ 0x0000;
|