mirror of https://github.com/bsnes-emu/bsnes.git
111 lines
2.6 KiB
C++
111 lines
2.6 KiB
C++
#include <ms/ms.hpp>
|
|
|
|
namespace MasterSystem {
|
|
|
|
Cartridge cartridge;
|
|
#include "mapper.cpp"
|
|
#include "serialization.cpp"
|
|
|
|
auto Cartridge::load() -> bool {
|
|
information = {};
|
|
|
|
if(Model::MasterSystem()) {
|
|
if(auto loaded = platform->load(ID::MasterSystem, "Master System", "ms", {"NTSC", "PAL"})) {
|
|
information.pathID = loaded.pathID();
|
|
information.region = loaded.option();
|
|
} else return false;
|
|
}
|
|
|
|
if(Model::GameGear()) {
|
|
if(auto loaded = platform->load(ID::GameGear, "Game Gear", "gg")) {
|
|
information.pathID = loaded.pathID();
|
|
} else return false;
|
|
}
|
|
|
|
if(auto fp = platform->open(pathID(), "manifest.bml", File::Read, File::Required)) {
|
|
information.manifest = fp->reads();
|
|
} else return false;
|
|
|
|
auto document = BML::unserialize(information.manifest);
|
|
information.title = document["information/title"].text();
|
|
|
|
if(auto node = document["board/rom"]) {
|
|
rom.size = node["size"].natural();
|
|
rom.mask = bit::round(rom.size) - 1;
|
|
if(rom.size) {
|
|
rom.data = new uint8[rom.mask + 1];
|
|
if(auto name = node["name"].text()) {
|
|
if(auto fp = platform->open(pathID(), name, File::Read, File::Required)) {
|
|
fp->read(rom.data, rom.size);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if(auto node = document["board/ram"]) {
|
|
ram.size = node["size"].natural();
|
|
ram.mask = bit::round(ram.size) - 1;
|
|
if(ram.size) {
|
|
ram.data = new uint8[ram.mask + 1];
|
|
if(auto name = node["name"].text()) {
|
|
if(auto fp = platform->open(pathID(), name, File::Read)) {
|
|
fp->read(ram.data, ram.size);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
auto Cartridge::save() -> void {
|
|
auto document = BML::unserialize(information.manifest);
|
|
|
|
if(auto name = document["board/ram/name"].text()) {
|
|
if(auto fp = platform->open(pathID(), name, File::Write)) {
|
|
fp->write(ram.data, ram.size);
|
|
}
|
|
}
|
|
}
|
|
|
|
auto Cartridge::unload() -> void {
|
|
delete[] rom.data;
|
|
delete[] ram.data;
|
|
rom = {};
|
|
ram = {};
|
|
}
|
|
|
|
auto Cartridge::power() -> void {
|
|
memory::fill(&mapper, sizeof(Mapper));
|
|
mapper.romPage0 = 0;
|
|
mapper.romPage1 = 1;
|
|
mapper.romPage2 = 2;
|
|
}
|
|
|
|
auto Cartridge::Memory::mirror(uint addr, uint size) -> uint {
|
|
uint base = 0;
|
|
uint mask = 1 << 21;
|
|
while(addr >= size) {
|
|
while(!(addr & mask)) mask >>= 1;
|
|
addr -= mask;
|
|
if(size > mask) {
|
|
size -= mask;
|
|
base += mask;
|
|
}
|
|
mask >>= 1;
|
|
}
|
|
return base + addr;
|
|
}
|
|
|
|
auto Cartridge::Memory::read(uint addr) -> uint8 {
|
|
if(!size) return 0x00;
|
|
return this->data[mirror(addr, size)];
|
|
}
|
|
|
|
auto Cartridge::Memory::write(uint addr, uint8 data) -> void {
|
|
if(!size) return;
|
|
this->data[mirror(addr, size)] = data;
|
|
}
|
|
|
|
}
|