Path: blob/master/libsnes/bsnes/nall/gameboy/cartridge.hpp
2 views
#ifndef NALL_GAMEBOY_CARTRIDGE_HPP1#define NALL_GAMEBOY_CARTRIDGE_HPP23namespace nall {45class GameBoyCartridge {6public:7string markup;8inline GameBoyCartridge(uint8_t *data, unsigned size);910//private:11struct Information {12string mapper;13bool ram;14bool battery;15bool rtc;16bool rumble;1718unsigned romsize;19unsigned ramsize;20} info;21};2223GameBoyCartridge::GameBoyCartridge(uint8_t *romdata, unsigned romsize) {24markup = "";25if(romsize < 0x4000) return;2627info.mapper = "unknown";28info.ram = false;29info.battery = false;30info.rtc = false;31info.rumble = false;3233info.romsize = 0;34info.ramsize = 0;3536unsigned base = romsize - 0x8000;37if(romdata[base + 0x0104] == 0xce && romdata[base + 0x0105] == 0xed38&& romdata[base + 0x0106] == 0x66 && romdata[base + 0x0107] == 0x6639&& romdata[base + 0x0108] == 0xcc && romdata[base + 0x0109] == 0x0d40&& romdata[base + 0x0147] >= 0x0b && romdata[base + 0x0147] <= 0x0d41) {42//MMM01 stores header at bottom of image43//flip this around for consistency with all other mappers44uint8_t header[0x8000];45memcpy(header, romdata + base, 0x8000);46memmove(romdata + 0x8000, romdata, romsize - 0x8000);47memcpy(romdata, header, 0x8000);48}4950switch(romdata[0x0147]) {51case 0x00: info.mapper = "none"; break;52case 0x01: info.mapper = "MBC1"; break;53case 0x02: info.mapper = "MBC1"; info.ram = true; break;54case 0x03: info.mapper = "MBC1"; info.ram = true; info.battery = true; break;55case 0x05: info.mapper = "MBC2"; info.ram = true; break;56case 0x06: info.mapper = "MBC2"; info.ram = true; info.battery = true; break;57case 0x08: info.mapper = "none"; info.ram = true; break;58case 0x09: info.mapper = "MBC0"; info.ram = true; info.battery = true; break;59case 0x0b: info.mapper = "MMM01"; break;60case 0x0c: info.mapper = "MMM01"; info.ram = true; break;61case 0x0d: info.mapper = "MMM01"; info.ram = true; info.battery = true; break;62case 0x0f: info.mapper = "MBC3"; info.rtc = true; info.battery = true; break;63case 0x10: info.mapper = "MBC3"; info.rtc = true; info.ram = true; info.battery = true; break;64case 0x11: info.mapper = "MBC3"; break;65case 0x12: info.mapper = "MBC3"; info.ram = true; break;66case 0x13: info.mapper = "MBC3"; info.ram = true; info.battery = true; break;67case 0x19: info.mapper = "MBC5"; break;68case 0x1a: info.mapper = "MBC5"; info.ram = true; break;69case 0x1b: info.mapper = "MBC5"; info.ram = true; info.battery = true; break;70case 0x1c: info.mapper = "MBC5"; info.rumble = true; break;71case 0x1d: info.mapper = "MBC5"; info.rumble = true; info.ram = true; break;72case 0x1e: info.mapper = "MBC5"; info.rumble = true; info.ram = true; info.battery = true; break;73case 0xfc: break; //Pocket Camera74case 0xfd: break; //Bandai TAMA575case 0xfe: info.mapper = "HuC3"; break;76case 0xff: info.mapper = "HuC1"; info.ram = true; info.battery = true; break;77}7879switch(romdata[0x0148]) { default:80case 0x00: info.romsize = 2 * 16 * 1024; break;81case 0x01: info.romsize = 4 * 16 * 1024; break;82case 0x02: info.romsize = 8 * 16 * 1024; break;83case 0x03: info.romsize = 16 * 16 * 1024; break;84case 0x04: info.romsize = 32 * 16 * 1024; break;85case 0x05: info.romsize = 64 * 16 * 1024; break;86case 0x06: info.romsize = 128 * 16 * 1024; break;87case 0x07: info.romsize = 256 * 16 * 1024; break;88case 0x52: info.romsize = 72 * 16 * 1024; break;89case 0x53: info.romsize = 80 * 16 * 1024; break;90case 0x54: info.romsize = 96 * 16 * 1024; break;91}9293switch(romdata[0x0149]) { default:94case 0x00: info.ramsize = 0 * 1024; break;95case 0x01: info.ramsize = 2 * 1024; break;96case 0x02: info.ramsize = 8 * 1024; break;97case 0x03: info.ramsize = 32 * 1024; break;98}99100if(info.mapper == "MBC2") info.ramsize = 512; //512 x 4-bit101102markup.append(103"<?xml version='1.0' encoding='UTF-8'?>\n",104"<cartridge mapper='", info.mapper, "' rtc='", info.rtc, "' rumble='", info.rumble, "'>\n",105" <rom size='0x", hex(romsize), "'/>\n");106if(info.ramsize > 0) markup.append(107" <ram size='0x", hex(info.ramsize), "' battery='", info.battery, "'/>\n");108markup.append(109"</cartridge>\n");110111/*112markup.append("cartridge mapper=", info.mapper);113if(info.rtc) markup.append(" rtc");114if(info.rumble) markup.append(" rumble");115markup.append("\n");116117markup.append("\t" "rom size=", hex(romsize), "\n"); //TODO: trust/check info.romsize?118119if(info.ramsize > 0)120markup.append("\t" "ram size=", hex(info.ramsize), info.battery ? " non-volatile\n" : "\n");121*/122}123124}125126#endif127128129