bsnes/higan/ws/cartridge/cartridge.cpp
Tim Allen 3a9c7c6843 Update to v099r09 release.
byuu says:

Changelog:
- Emulator::Interface::Medium::bootable removed
- Emulator::Interface::load(bool required) argument removed
  [File::Required makes no sense on a folder]
- Super Famicom.sys now has user-configurable properties (CPU,PPU1,PPU2
  version; PPU1 VRAM size, Region override)
- old nall/property removed completely
- volatile flags supported on coprocessor RAM files now (still not in
  icarus, though)
- (hopefully) fixed SNES Multitap support (needs testing)
- fixed an OAM tiledata range clipping limit in 128KiB VRAM mode (doesn't
  fix Yoshi's Island, sadly)
- (hopefully, again) fixed the input polling bug hex_usr reported
- re-added dialog box for when File::Required files are missing
  - really cool: if you're missing a boot ROM, BIOS ROM, or IPL ROM,
    it warns you immediately
  - you don't have to select a game before seeing the error message
    anymore
- fixed cheats.bml load/save location
2016-06-25 18:53:11 +10:00

168 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 {
clock += clocks;
if(clock >= 0 && !scheduler.synchronizing()) co_switch(cpu.thread);
}
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);
memory::fill(&r, sizeof(Registers));
r.romBank0 = 0xff;
r.romBank1 = 0xff;
r.romBank2 = 0xff;
r.sramBank = 0xff;
}
auto Cartridge::load() -> bool {
information = Information();
switch(system.model()) {
case Model::WonderSwan:
if(auto pathID = interface->load(ID::WonderSwan, "WonderSwan", "ws")) {
information.pathID = pathID();
} else return false;
break;
case Model::WonderSwanColor:
case Model::SwanCrystal:
if(auto pathID = interface->load(ID::WonderSwanColor, "WonderSwan Color", "wsc")) {
information.pathID = pathID();
} else return false;
break;
}
if(auto fp = interface->open(pathID(), "manifest.bml", File::Read, File::Required)) {
information.manifest = fp->reads();
} else return false;
auto document = BML::unserialize(information.manifest);
if(auto node = document["board/rom"]) {
rom.name = node["name"].text();
rom.size = node["size"].natural();
rom.mask = bit::round(rom.size) - 1;
if(rom.size) {
rom.data = new uint8[rom.mask + 1];
memory::fill(rom.data, rom.mask + 1, 0xff);
if(rom.name) if(auto fp = interface->open(pathID(), rom.name, File::Read, File::Required)) {
fp->read(rom.data, rom.size);
}
}
}
if(auto node = document["board/ram"]) {
if(node["type"].text() == "sram") {
ram.name = node["name"].text();
ram.size = node["size"].natural();
ram.mask = bit::round(ram.size) - 1;
if(ram.size) {
ram.data = new uint8[ram.mask + 1];
memory::fill(ram.data, ram.mask + 1, 0xff);
if(ram.name) if(auto fp = interface->open(pathID(), ram.name, File::Read)) {
fp->read(ram.data, ram.size);
}
}
}
if(node["type"].text() == "eeprom") {
eeprom.setName(node["name"].text());
eeprom.setSize(node["size"].natural() / sizeof(uint16));
if(eeprom.size()) {
eeprom.erase();
if(eeprom.name()) if(auto fp = interface->open(pathID(), eeprom.name(), File::Read)) {
fp->read(eeprom.data(), eeprom.size());
}
}
}
}
if(auto node = document["board/rtc"]) {
rtc.name = node["name"].text();
rtc.size = node["size"].natural();
rtc.mask = bit::round(rtc.size) - 1;
if(rtc.size) {
rtc.data = new uint8[rtc.mask + 1];
memory::fill(rtc.data, rtc.mask + 1, 0x00);
if(rtc.name) if(auto fp = interface->open(pathID(), rtc.name, File::Read)) {
fp->read(rtc.data, rtc.size);
}
}
}
information.title = document["information/title"].text();
information.orientation = document["information/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 name = document["board/ram/name"].text()) {
if(auto fp = interface->open(pathID(), name, File::Write)) {
fp->write(ram.data, ram.size);
}
}
if(auto name = document["board/eeprom/name"].text()) {
if(auto fp = interface->open(pathID(), name, File::Write)) {
fp->write(eeprom.data(), eeprom.size());
}
}
if(auto name = document["board/rtc/name"].text()) {
if(auto fp = interface->open(pathID(), 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;
rom.name = "";
delete[] ram.data;
ram.data = nullptr;
ram.size = 0;
ram.mask = 0;
ram.name = "";
delete[] rtc.data;
rtc.data = nullptr;
rtc.size = 0;
rtc.mask = 0;
rtc.name = "";
}
}