mirror of https://github.com/bsnes-emu/bsnes.git
158 lines
4.3 KiB
C++
158 lines
4.3 KiB
C++
#include <ws/ws.hpp>
|
|
|
|
namespace WonderSwan {
|
|
|
|
Cartridge cartridge;
|
|
#include "memory.cpp"
|
|
#include "rtc.cpp"
|
|
#include "io.cpp"
|
|
#include "serialization.cpp"
|
|
|
|
auto Cartridge::Enter() -> void {
|
|
while(true) scheduler.synchronize(), cartridge.main();
|
|
}
|
|
|
|
auto Cartridge::main() -> void {
|
|
if(rtc.data) {
|
|
rtcTickSecond();
|
|
rtcCheckAlarm();
|
|
}
|
|
step(3'072'000);
|
|
}
|
|
|
|
auto Cartridge::step(uint clocks) -> void {
|
|
Thread::step(clocks);
|
|
synchronize(cpu);
|
|
}
|
|
|
|
auto Cartridge::power() -> void {
|
|
create(Cartridge::Enter, 3'072'000);
|
|
eeprom.power();
|
|
|
|
bus.map(this, 0x00c0, 0x00c8);
|
|
if(rtc.data) bus.map(this, 0x00ca, 0x00cb);
|
|
bus.map(this, 0x00cc, 0x00cd);
|
|
|
|
r = {};
|
|
}
|
|
|
|
auto Cartridge::load() -> bool {
|
|
information = {};
|
|
|
|
if(Model::WonderSwan()) {
|
|
if(auto loaded = platform->load(ID::WonderSwan, "WonderSwan", "ws")) {
|
|
information.pathID = loaded.pathID();
|
|
} else return false;
|
|
}
|
|
|
|
if(Model::WonderSwanColor() || Model::SwanCrystal()) {
|
|
if(auto loaded = platform->load(ID::WonderSwanColor, "WonderSwan Color", "wsc")) {
|
|
information.pathID = loaded.pathID();
|
|
} else return false;
|
|
}
|
|
|
|
if(Model::PocketChallengeV2()) {
|
|
if(auto loaded = platform->load(ID::PocketChallengeV2, "Pocket Challenge V2", "pc2")) {
|
|
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);
|
|
|
|
if(auto memory = Emulator::Game::Memory{document["game/board/memory(type=ROM,content=Program)"]}) {
|
|
rom.size = memory.size;
|
|
rom.mask = bit::round(rom.size) - 1;
|
|
rom.data = new uint8[rom.mask + 1];
|
|
memory::fill<uint8>(rom.data, rom.mask + 1, 0xff);
|
|
if(auto fp = platform->open(pathID(), memory.name(), File::Read, File::Required)) {
|
|
fp->read(rom.data, rom.size);
|
|
}
|
|
}
|
|
|
|
if(auto memory = Emulator::Game::Memory{document["game/board/memory(type=RAM,content=Save)"]}) {
|
|
ram.size = memory.size;
|
|
ram.mask = bit::round(ram.size) - 1;
|
|
ram.data = new uint8[ram.mask + 1];
|
|
memory::fill<uint8>(ram.data, ram.mask + 1, 0xff);
|
|
if(memory.nonVolatile) {
|
|
if(auto fp = platform->open(pathID(), memory.name(), File::Read)) {
|
|
fp->read(ram.data, ram.size);
|
|
}
|
|
}
|
|
}
|
|
|
|
if(auto memory = Emulator::Game::Memory{document["game/board/memory(type=EEPROM,content=Save)"]}) {
|
|
eeprom.setSize(memory.size / sizeof(uint16));
|
|
eeprom.erase();
|
|
if(auto fp = platform->open(pathID(), memory.name(), File::Read)) {
|
|
fp->read(eeprom.data(), eeprom.size());
|
|
}
|
|
}
|
|
|
|
if(auto memory = Emulator::Game::Memory{document["game/board/memory(type=RTC,content=Time)"]}) {
|
|
rtc.size = memory.size;
|
|
rtc.mask = bit::round(rtc.size) - 1;
|
|
rtc.data = new uint8[rtc.mask + 1];
|
|
memory::fill<uint8>(rtc.data, rtc.mask + 1, 0x00);
|
|
if(memory.nonVolatile) {
|
|
if(auto fp = platform->open(pathID(), memory.name(), File::Read)) {
|
|
fp->read(rtc.data, rtc.size);
|
|
}
|
|
}
|
|
}
|
|
|
|
information.title = document["game/label"].text();
|
|
information.orientation = document["game/orientation"].text() == "vertical";
|
|
information.sha256 = Hash::SHA256(rom.data, rom.size).digest();
|
|
return true;
|
|
}
|
|
|
|
auto Cartridge::save() -> void {
|
|
auto document = BML::unserialize(information.manifest);
|
|
|
|
if(auto memory = Emulator::Game::Memory{document["game/board/memory(type=RAM,content=Save)"]}) {
|
|
if(memory.nonVolatile) {
|
|
if(auto fp = platform->open(pathID(), memory.name(), File::Write)) {
|
|
fp->write(ram.data, ram.size);
|
|
}
|
|
}
|
|
}
|
|
|
|
if(auto memory = Emulator::Game::Memory{document["game/board/memory(type=EEPROM,content=Save)"]}) {
|
|
if(auto fp = platform->open(pathID(), memory.name(), File::Write)) {
|
|
fp->write(eeprom.data(), eeprom.size());
|
|
}
|
|
}
|
|
|
|
if(auto memory = Emulator::Game::Memory{document["game/board/memory(type=RTC,content=Time)"]}) {
|
|
if(memory.nonVolatile) {
|
|
if(auto fp = platform->open(pathID(), memory.name(), File::Write)) {
|
|
fp->write(rtc.data, rtc.size);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
auto Cartridge::unload() -> void {
|
|
delete[] rom.data;
|
|
rom.data = nullptr;
|
|
rom.size = 0;
|
|
rom.mask = 0;
|
|
|
|
delete[] ram.data;
|
|
ram.data = nullptr;
|
|
ram.size = 0;
|
|
ram.mask = 0;
|
|
|
|
delete[] rtc.data;
|
|
rtc.data = nullptr;
|
|
rtc.size = 0;
|
|
rtc.mask = 0;
|
|
}
|
|
|
|
}
|