Path: blob/master/libsnes/bsnes/gameboy/cartridge/cartridge.cpp
2 views
#include <gameboy/gameboy.hpp>12#include <nall/crc32.hpp>34#define CARTRIDGE_CPP5namespace GameBoy {67#include "mbc0/mbc0.cpp"8#include "mbc1/mbc1.cpp"9#include "mbc2/mbc2.cpp"10#include "mbc3/mbc3.cpp"11#include "mbc5/mbc5.cpp"12#include "mmm01/mmm01.cpp"13#include "huc1/huc1.cpp"14#include "huc3/huc3.cpp"15#include "serialization.cpp"16Cartridge cartridge;1718void Cartridge::load(System::Revision revision, const string &markup, const uint8_t *data, unsigned size) {19if(size == 0) size = 32768;20romdata = allocate<uint8>(romsize = size, 0xff);21if(data) memcpy(romdata, data, size);2223info.mapper = Mapper::Unknown;24info.ram = false;25info.battery = false;26info.rtc = false;27info.rumble = false;2829info.romsize = 0;30info.ramsize = 0;3132XML::Document document(markup);3334auto &mapperid = document["cartridge"]["mapper"].data;35if(mapperid == "none" ) info.mapper = Mapper::MBC0;36if(mapperid == "MBC1" ) info.mapper = Mapper::MBC1;37if(mapperid == "MBC2" ) info.mapper = Mapper::MBC2;38if(mapperid == "MBC3" ) info.mapper = Mapper::MBC3;39if(mapperid == "MBC5" ) info.mapper = Mapper::MBC5;40if(mapperid == "MMM01") info.mapper = Mapper::MMM01;41if(mapperid == "HuC1" ) info.mapper = Mapper::HuC1;42if(mapperid == "HuC3" ) info.mapper = Mapper::HuC3;4344info.rtc = document["cartridge"]["rtc"].data == "true";45info.rumble = document["cartridge"]["rumble"].data == "true";4647info.romsize = numeral(document["cartridge"]["rom"]["size"].data);48info.ramsize = numeral(document["cartridge"]["ram"]["size"].data);49info.battery = document["cartridge"]["ram"]["battery"].data == "true";5051switch(info.mapper) { default:52case Mapper::MBC0: mapper = &mbc0; break;53case Mapper::MBC1: mapper = &mbc1; break;54case Mapper::MBC2: mapper = &mbc2; break;55case Mapper::MBC3: mapper = &mbc3; break;56case Mapper::MBC5: mapper = &mbc5; break;57case Mapper::MMM01: mapper = &mmm01; break;58case Mapper::HuC1: mapper = &huc1; break;59case Mapper::HuC3: mapper = &huc3; break;60}6162ramdata = (uint8_t*)interface->allocSharedMemory("SGB_CARTRAM",ramsize = info.ramsize);63system.load(revision);6465loaded = true;66sha256 = nall::sha256(romdata, romsize);67}6869void Cartridge::unload() {70if(loaded == false) return;7172if(romdata) { delete[] romdata; romdata = 0; }73if(ramdata) { interface->freeSharedMemory(ramdata); }74loaded = false;75}7677uint8 Cartridge::rom_read(unsigned addr) {78if(addr >= romsize) addr %= romsize;79return romdata[addr];80}8182void Cartridge::rom_write(unsigned addr, uint8 data) {83if(addr >= romsize) addr %= romsize;84romdata[addr] = data;85}8687uint8 Cartridge::ram_read(unsigned addr) {88if(ramsize == 0) return 0x00;89if(addr >= ramsize) addr %= ramsize;90return ramdata[addr];91}9293void Cartridge::ram_write(unsigned addr, uint8 data) {94if(ramsize == 0) return;95if(addr >= ramsize) addr %= ramsize;96ramdata[addr] = data;97}9899uint8 Cartridge::mmio_read(uint16 addr) {100if(addr == 0xff50) return 0x00;101102if(bootrom_enable) {103const uint8 *data = nullptr;104switch(system.revision()) { default:105case System::Revision::GameBoy: data = System::BootROM::dmg; break;106case System::Revision::SuperGameBoy: data = System::BootROM::sgb; break;107case System::Revision::GameBoyColor: data = System::BootROM::cgb; break;108}109if(addr >= 0x0000 && addr <= 0x00ff) return data[addr];110if(addr >= 0x0200 && addr <= 0x08ff && system.cgb()) return data[addr - 256];111}112113return mapper->mmio_read(addr);114}115116void Cartridge::mmio_write(uint16 addr, uint8 data) {117if(bootrom_enable && addr == 0xff50) {118bootrom_enable = false;119return;120}121122mapper->mmio_write(addr, data);123}124125void Cartridge::power() {126bootrom_enable = true;127128mbc0.power();129mbc1.power();130mbc2.power();131mbc3.power();132mbc5.power();133mmm01.power();134huc1.power();135huc3.power();136137for(unsigned n = 0x0000; n <= 0x7fff; n++) bus.mmio[n] = this;138for(unsigned n = 0xa000; n <= 0xbfff; n++) bus.mmio[n] = this;139bus.mmio[0xff50] = this;140}141142Cartridge::Cartridge() {143loaded = false;144romdata = 0;145ramdata = 0;146}147148Cartridge::~Cartridge() {149unload();150}151152}153154155