#include #define CARTRIDGE_CPP namespace SuperFamicom { #include "markup.cpp" #include "serialization.cpp" Cartridge cartridge; void Cartridge::load(const string &manifest) { region = Region::NTSC; has_gb_slot = false; has_bs_cart = false; has_bs_slot = false; has_st_slots = false; has_nss_dip = false; has_event = false; has_sa1 = false; has_superfx = false; has_armdsp = false; has_hitachidsp = false; has_necdsp = false; has_epsonrtc = false; has_sharprtc = false; has_spc7110 = false; has_sdd1 = false; has_obc1 = false; has_msu1 = false; this->manifest = manifest; parse_markup(manifest); //print(manifest, "\n\n"); //Super Game Boy if(cartridge.has_gb_slot()) { sha256 = nall::sha256(GameBoy::cartridge.romdata, GameBoy::cartridge.romsize); } //Broadcast Satellaview else if(cartridge.has_bs_cart() && cartridge.has_bs_slot()) { sha256 = nall::sha256(bsxflash.memory.data(), bsxflash.memory.size()); } //Sufami Turbo else if(cartridge.has_st_slots()) { sha256 = nall::sha256(sufamiturbo.slotA.rom.data(), sufamiturbo.slotA.rom.size()); } //Super Famicom else { sha256_ctx sha; uint8_t hash[32]; sha256_init(&sha); //hash each ROM image that exists; any with size() == 0 is ignored by sha256_chunk() sha256_chunk(&sha, rom.data(), rom.size()); sha256_chunk(&sha, bsxcartridge.rom.data(), bsxcartridge.rom.size()); sha256_chunk(&sha, sa1.rom.data(), sa1.rom.size()); sha256_chunk(&sha, superfx.rom.data(), superfx.rom.size()); sha256_chunk(&sha, hitachidsp.rom.data(), hitachidsp.rom.size()); sha256_chunk(&sha, spc7110.prom.data(), spc7110.prom.size()); sha256_chunk(&sha, spc7110.drom.data(), spc7110.drom.size()); sha256_chunk(&sha, sdd1.rom.data(), sdd1.rom.size()); sha256_final(&sha); sha256_hash(&sha, hash); string result; for(auto &byte : hash) result.append(hex<2>(byte)); sha256 = result; } rom.write_protect(true); ram.write_protect(false); system.load(); loaded = true; } void Cartridge::load_super_game_boy(const string &manifest) { XML::Document document(manifest); auto &rom = document["cartridge"]["rom"]; auto &ram = document["cartridge"]["ram"]; GameBoy::cartridge.load(GameBoy::System::Revision::SuperGameBoy, manifest); if(rom["name"].exists()) interface->loadRequest(ID::SuperGameBoyROM, rom["name"].data); if(ram["name"].exists()) interface->loadRequest(ID::SuperGameBoyRAM, ram["name"].data); if(ram["name"].exists()) memory.append({ID::SuperGameBoyRAM, ram["name"].data}); } void Cartridge::load_satellaview(const string &manifest) { XML::Document document(manifest); auto &rom = document["cartridge"]["rom"]; if(rom["name"].exists()) { unsigned size = numeral(rom["size"].data); bsxflash.memory.map(allocate(size, 0xff), size); interface->loadRequest(ID::BsxFlashROM, rom["name"].data); } } void Cartridge::load_sufami_turbo_a(const string &manifest) { XML::Document document(manifest); auto &rom = document["cartridge"]["rom"]; auto &ram = document["cartridge"]["ram"]; if(rom["name"].exists()) { unsigned size = numeral(rom["size"].data); sufamiturbo.slotA.rom.map(allocate(size, 0xff), size); interface->loadRequest(ID::SufamiTurboSlotAROM, rom["name"].data); } if(ram["name"].exists()) { unsigned size = numeral(ram["size"].data); sufamiturbo.slotA.ram.map(allocate(size, 0xff), size); interface->loadRequest(ID::SufamiTurboSlotARAM, ram["name"].data); memory.append({ID::SufamiTurboSlotARAM, ram["name"].data}); } if(document["cartridge"]["linkable"].data == "true") { interface->loadRequest(ID::SufamiTurboSlotB, "Sufami Turbo - Slot B", "st"); } } void Cartridge::load_sufami_turbo_b(const string &manifest) { XML::Document document(manifest); auto &rom = document["cartridge"]["rom"]; auto &ram = document["cartridge"]["ram"]; if(rom["name"].exists()) { unsigned size = numeral(rom["size"].data); sufamiturbo.slotB.rom.map(allocate(size, 0xff), size); interface->loadRequest(ID::SufamiTurboSlotBROM, rom["name"].data); } if(ram["name"].exists()) { unsigned size = numeral(ram["size"].data); sufamiturbo.slotB.ram.map(allocate(size, 0xff), size); interface->loadRequest(ID::SufamiTurboSlotBRAM, ram["name"].data); memory.append({ID::SufamiTurboSlotBRAM, ram["name"].data}); } } void Cartridge::unload() { if(loaded == false) return; system.unload(); rom.reset(); ram.reset(); loaded = false; memory.reset(); } Cartridge::Cartridge() { loaded = false; } Cartridge::~Cartridge() { unload(); } }