#pragma once #include #include #define rom_offset(member) (0x100 + offsetof(struct rom_header, member)) #define rom_offset_end(member) (0x100 + offsetof(struct rom_header, member) + sizeof(((struct rom_header *)0)->member)) enum rom_cgb { ROM_CGB_SUPPORTED = 0x80, ROM_CGB_ONLY = 0xC0 }; enum rom_sgb { ROM_SGB_NO = 0x00, ROM_SGB_SUPPORTED = 0x03 }; enum rom_type { ROM_TYPE_ROM_ONLY = 0x00, ROM_TYPE_MBC1 = 0x01, ROM_TYPE_MBC1_RAM = 0x2, ROM_TYPE_MBC1_RAM_BATTERY = 0x03, // UNUSED = 0x04 ROM_TYPE_MBC2 = 0x05, ROM_TYPE_MBC2_BATTERY = 0x06, // UNUSED = 0x07 ROM_TYPE_ROM_RAM = 0x08, ROM_TYPE_ROM_RAM_BATTERY = 0x09, // UNUSED = 0x0A ROM_TYPE_MMM01 = 0x0B, ROM_TYPE_MMM01_RAM = 0x0C, ROM_TYPE_MMM01_RAM_BATTERY = 0x0D, // UNUSED = 0x0E ROM_TYPE_MBC3_TIMER_BATTERY = 0x0F, ROM_TYPE_MBC3_TIMER_RAM_BATTERY = 0x10, ROM_TYPE_MBC3 = 0x11, ROM_TYPE_MBC3_RAM = 0x12, ROM_TYPE_MBC3_RAM_BATTERY = 0x13, // UNUSED = 0x14 // Doesn't exist, but included for "completeness". ROM_TYPE_MBC4 = 0x15, ROM_TYPE_MBC4_RAM = 0x16, ROM_TYPE_MBC4_RAM_BATTERY = 0x17, // UNUSED = 0x18 ROM_TYPE_MBC5 = 0x19, ROM_TYPE_MBC5_RAM = 0x1A, ROM_TYPE_MBC5_RAM_BATTERY = 0x1B, ROM_TYPE_MBC5_RUMBLE = 0x1C, ROM_TYPE_MBC5_RUMBLE_RAM = 0x1D, ROM_TYPE_MBC5_RUMBLE_RAM_BATTERY = 0x1E, // UNUSED = 0x1F ROM_TYPE_MBC6_RAM_BATTERY = 0x20, // UNUSED = 0x21 ROM_TYPE_MBC7_ACCEL_RAM_BATTERY = 0x22, // UNUSED ... ROM_TYPE_POCKET_CAMERA = 0xFC, ROM_TYPE_BANDAI_TAMA5 = 0xFD, ROM_TYPE_HUC3 = 0xFE, ROM_TYPE_HUC1_RAM_BATTERY = 0xFF }; enum rom_region { ROM_REGION_JAPANESE = 0x00, ROM_REGION_INTERNATIONAL = 0x01 }; // http://gbdev.gg8.se/files/docs/mirrors/pandocs.html#thecartridgeheader // https://raw.githubusercontent.com/AntonioND/giibiiadvance/master/docs/TCAGBD.pdf (page 51) struct rom_header { uint8_t entry[4]; uint8_t logo[0x30]; uint8_t title[0xB]; uint8_t manufacturer[4]; uint8_t cgb_flag; uint8_t licensee[2]; uint8_t sgb_flag; uint8_t type; uint8_t rom_size; // 0x8000 << x uint8_t ram_size; // MBC2 uses 0, but has a size of 512 * 4 bytes uint8_t region; uint8_t old_licensee; // If 0x33, use the new licensee uint8_t version; uint8_t header_checksum; uint8_t global_checksum[2]; // Big endian } __attribute__((packed)); extern uint8_t rom_logo[];