mirror of https://github.com/bsnes-emu/bsnes.git
Update to v099r06 release.
byuu says: Changelog: - Super Famicom core converted to use nall/vfs - excludes Super Game Boy; since that's invoked from inside the GB core This was definitely the major obstacle to test nall/vfs' applicability. Things worked out pretty great in the end. We went from 22.0KiB (cartridge) + 18.6KiB (interface) to 24.5KiB (cartridge) + 11.4KiB (interface). Or 40.7KiB to 36.0KiB. This removes a very large source of indirection. Before it was: "coprocessor <=> cartridge <=> interface" for loading and saving data, and now it's just "coprocessor <=> cartridge". And it may make sense to eventually turn this into just "cartridge -> coprocessor" by making each coprocessor class handle its own markup parsing. It's nice to have all the manifest parsing in one location (well, sans MSU1); but it's also nice for loading/unloading to be handled by each coprocessor itself. So I'll have to think longer about that one. I've also started handling Interface::save() differently. Instead of keeping track of memory IDs and filenames, and iterating through that vector of objects ... instead I now have a system that mirrors the markup parsing on loading, but handles saving instead. This was actually the reason the code size savings weren't more significant, but I like this style more. As before, it removes an extra level of indirection. So ... next up, I need to port over the GB, then GBA, then WS cores. These shouldn't take too long since they're all very simple with just ROM+RAM(+RTC) right now. Then get the SGB callbacks using vfs. Then after that, gut all the old stream stuff from nall and higan. Kill the (load,save)Request stuff, rename the load(Gamepak)Request to something simpler, and then we should be good. Anyway ... these are some huge changes.
This commit is contained in:
parent
f04d9d58f5
commit
875f031182
|
@ -10,7 +10,7 @@ using namespace nall;
|
|||
|
||||
namespace Emulator {
|
||||
static const string Name = "higan";
|
||||
static const string Version = "099.05";
|
||||
static const string Version = "099.06";
|
||||
static const string Author = "byuu";
|
||||
static const string License = "GPLv3";
|
||||
static const string Website = "http://byuu.org/";
|
||||
|
|
|
@ -79,8 +79,8 @@ struct Interface {
|
|||
|
||||
//video information
|
||||
virtual auto videoFrequency() -> double = 0;
|
||||
virtual auto videoColors() -> uint32 { return 1 << 19; }
|
||||
virtual auto videoColor(uint32 color) -> uint64 { return 0; }
|
||||
virtual auto videoColors() -> uint32 = 0;
|
||||
virtual auto videoColor(uint32 color) -> uint64 = 0;
|
||||
|
||||
//audio information
|
||||
virtual auto audioFrequency() -> double = 0;
|
||||
|
|
|
@ -28,7 +28,7 @@ auto Cartridge::main() -> void {
|
|||
|
||||
auto Cartridge::load() -> bool {
|
||||
if(auto fp = interface->open(ID::Famicom, "manifest.bml", vfs::file::mode::read, true)) {
|
||||
fp->reads(information.markup);
|
||||
information.markup = fp->reads();
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -23,7 +23,7 @@ auto System::runToSave() -> void {
|
|||
|
||||
auto System::load() -> bool {
|
||||
if(auto fp = interface->open(ID::System, "manifest.bml", vfs::file::mode::read, true)) {
|
||||
fp->reads(information.manifest);
|
||||
information.manifest = fp->reads();
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -2,108 +2,53 @@
|
|||
|
||||
namespace SuperFamicom {
|
||||
|
||||
#include "markup.cpp"
|
||||
#include "load.cpp"
|
||||
#include "save.cpp"
|
||||
#include "serialization.cpp"
|
||||
Cartridge cartridge;
|
||||
|
||||
auto Cartridge::manifest() -> string {
|
||||
string manifest = information.markup.cartridge;
|
||||
|
||||
if(information.markup.gameBoy) {
|
||||
manifest.append("\n[[Game Boy]]\n\n");
|
||||
manifest.append(information.markup.gameBoy);
|
||||
}
|
||||
|
||||
if(information.markup.bsMemory) {
|
||||
manifest.append("\n[[BS Memory]]\n\n");
|
||||
manifest.append(information.markup.bsMemory);
|
||||
}
|
||||
|
||||
if(information.markup.sufamiTurboA) {
|
||||
manifest.append("\n[[Sufami Turbo - Slot A]]\n\n");
|
||||
manifest.append(information.markup.sufamiTurboA);
|
||||
}
|
||||
|
||||
if(information.markup.sufamiTurboB) {
|
||||
manifest.append("\n[[Sufami Turbo - Slot B]]\n\n");
|
||||
manifest.append(information.markup.sufamiTurboB);
|
||||
}
|
||||
|
||||
auto Cartridge::manifest() const -> string {
|
||||
string manifest = information.manifest.cartridge;
|
||||
if(information.manifest.gameBoy) manifest.append("\n[[Game Boy]]\n\n", information.manifest.gameBoy);
|
||||
if(information.manifest.bsMemory) manifest.append("\n[[BS Memory]]\n\n", information.manifest.bsMemory);
|
||||
if(information.manifest.sufamiTurboA) manifest.append("\n[[Sufami Turbo - Slot A]]\n\n", information.manifest.sufamiTurboA);
|
||||
if(information.manifest.sufamiTurboB) manifest.append("\n[[Sufami Turbo - Slot B]]\n\n", information.manifest.sufamiTurboB);
|
||||
return manifest;
|
||||
}
|
||||
|
||||
auto Cartridge::title() -> string {
|
||||
auto Cartridge::title() const -> string {
|
||||
string title = information.title.cartridge;
|
||||
|
||||
if(information.title.gameBoy) {
|
||||
title.append(" + ", information.title.gameBoy);
|
||||
}
|
||||
|
||||
if(information.title.bsMemory) {
|
||||
title.append(" + ", information.title.bsMemory);
|
||||
}
|
||||
|
||||
if(information.title.sufamiTurboA) {
|
||||
title.append(" + ", information.title.sufamiTurboA);
|
||||
}
|
||||
|
||||
if(information.title.sufamiTurboB) {
|
||||
title.append(" + ", information.title.sufamiTurboB);
|
||||
}
|
||||
|
||||
if(information.title.gameBoy) title.append(" + ", information.title.gameBoy);
|
||||
if(information.title.bsMemory) title.append(" + ", information.title.bsMemory);
|
||||
if(information.title.sufamiTurboA) title.append(" + ", information.title.sufamiTurboA);
|
||||
if(information.title.sufamiTurboB) title.append(" + ", information.title.sufamiTurboB);
|
||||
return title;
|
||||
}
|
||||
|
||||
auto Cartridge::load() -> void {
|
||||
auto Cartridge::load() -> bool {
|
||||
information = Information();
|
||||
has = Has();
|
||||
_sha256 = "";
|
||||
_region = Region::NTSC;
|
||||
|
||||
hasICD2 = false;
|
||||
hasMCC = false;
|
||||
hasNSSDIP = false;
|
||||
hasEvent = false;
|
||||
hasSA1 = false;
|
||||
hasSuperFX = false;
|
||||
hasARMDSP = false;
|
||||
hasHitachiDSP = false;
|
||||
hasNECDSP = false;
|
||||
hasEpsonRTC = false;
|
||||
hasSharpRTC = false;
|
||||
hasSPC7110 = false;
|
||||
hasSDD1 = false;
|
||||
hasOBC1 = false;
|
||||
hasMSU1 = false;
|
||||
|
||||
hasGameBoySlot = false;
|
||||
hasBSMemorySlot = false;
|
||||
hasSufamiTurboSlots = false;
|
||||
|
||||
information.markup.cartridge = "";
|
||||
information.markup.gameBoy = "";
|
||||
information.markup.bsMemory = "";
|
||||
information.markup.sufamiTurboA = "";
|
||||
information.markup.sufamiTurboB = "";
|
||||
|
||||
information.title.cartridge = "";
|
||||
information.title.gameBoy = "";
|
||||
information.title.bsMemory = "";
|
||||
information.title.sufamiTurboA = "";
|
||||
information.title.sufamiTurboB = "";
|
||||
|
||||
interface->loadRequest(ID::Manifest, "manifest.bml", true);
|
||||
parseMarkup(information.markup.cartridge);
|
||||
if(auto fp = interface->open(ID::SuperFamicom, "manifest.bml", File::Read, File::Required)) {
|
||||
information.manifest.cartridge = fp->reads();
|
||||
} else return false;
|
||||
auto document = BML::unserialize(information.manifest.cartridge);
|
||||
loadCartridge(document);
|
||||
|
||||
//Game Boy
|
||||
if(cartridge.hasICD2) {
|
||||
if(cartridge.has.ICD2) {
|
||||
_sha256 = ""; //Game Boy cartridge not loaded yet: set later via loadGameBoy()
|
||||
}
|
||||
|
||||
//BS Memory
|
||||
else if(cartridge.hasMCC && cartridge.hasBSMemorySlot) {
|
||||
else if(cartridge.has.MCC && cartridge.has.BSMemorySlot) {
|
||||
_sha256 = Hash::SHA256(bsmemory.memory.data(), bsmemory.memory.size()).digest();
|
||||
}
|
||||
|
||||
//Sufami Turbo
|
||||
else if(cartridge.hasSufamiTurboSlots) {
|
||||
else if(cartridge.has.SufamiTurboSlots) {
|
||||
Hash::SHA256 sha;
|
||||
sha.data(sufamiturboA.rom.data(), sufamiturboA.rom.size());
|
||||
sha.data(sufamiturboB.rom.data(), sufamiturboB.rom.size());
|
||||
|
@ -136,85 +81,51 @@ auto Cartridge::load() -> void {
|
|||
|
||||
rom.writeProtect(true);
|
||||
ram.writeProtect(false);
|
||||
return true;
|
||||
}
|
||||
|
||||
auto Cartridge::loadGameBoy() -> void {
|
||||
#if defined(SFC_SUPERGAMEBOY)
|
||||
//invoked from ICD2::load()
|
||||
_sha256 = GameBoy::interface->sha256();
|
||||
information.markup.gameBoy = GameBoy::interface->manifest();
|
||||
information.manifest.gameBoy = GameBoy::interface->manifest();
|
||||
information.title.gameBoy = GameBoy::interface->title();
|
||||
#endif
|
||||
loadGameBoy(BML::unserialize(information.manifest.gameBoy));
|
||||
}
|
||||
|
||||
auto Cartridge::loadBSMemory() -> void {
|
||||
interface->loadRequest(ID::BSMemoryManifest, "manifest.bml", true);
|
||||
auto document = BML::unserialize(information.markup.bsMemory);
|
||||
information.title.bsMemory = document["information/title"].text();
|
||||
|
||||
auto rom = document["board/rom"];
|
||||
|
||||
if(rom["name"]) {
|
||||
uint size = rom["size"].natural();
|
||||
bsmemory.memory.map(allocate<uint8>(size, 0xff), size);
|
||||
interface->loadRequest(ID::BSMemoryROM, rom["name"].text(), true);
|
||||
|
||||
bsmemory.readonly = (rom["type"].text() == "mrom");
|
||||
}
|
||||
if(auto fp = interface->open(ID::BSMemory, "manifest.bml", File::Read, File::Required)) {
|
||||
information.manifest.bsMemory = fp->reads();
|
||||
} else return;
|
||||
loadBSMemory(BML::unserialize(information.manifest.bsMemory));
|
||||
}
|
||||
|
||||
auto Cartridge::loadSufamiTurboA() -> void {
|
||||
interface->loadRequest(ID::SufamiTurboSlotAManifest, "manifest.bml", true);
|
||||
auto document = BML::unserialize(information.markup.sufamiTurboA);
|
||||
information.title.sufamiTurboA = document["information/title"].text();
|
||||
|
||||
auto rom = document["board/rom"];
|
||||
auto ram = document["board/ram"];
|
||||
|
||||
if(rom["name"]) {
|
||||
uint size = rom["size"].natural();
|
||||
sufamiturboA.rom.map(allocate<uint8>(size, 0xff), size);
|
||||
interface->loadRequest(ID::SufamiTurboSlotAROM, rom["name"].text(), true);
|
||||
}
|
||||
|
||||
if(ram["name"]) {
|
||||
uint size = ram["size"].natural();
|
||||
sufamiturboA.ram.map(allocate<uint8>(size, 0xff), size);
|
||||
interface->loadRequest(ID::SufamiTurboSlotARAM, ram["name"].text(), false);
|
||||
memory.append({ID::SufamiTurboSlotARAM, ram["name"].text()});
|
||||
}
|
||||
|
||||
if(document["board/linkable"]) {
|
||||
interface->loadRequest(ID::SufamiTurboSlotB, "Sufami Turbo", "st", false);
|
||||
}
|
||||
if(auto fp = interface->open(ID::SufamiTurboA, "manifest.bml", File::Read, File::Required)) {
|
||||
information.manifest.sufamiTurboA = fp->reads();
|
||||
} else return;
|
||||
loadSufamiTurboA(BML::unserialize(information.manifest.sufamiTurboA));
|
||||
}
|
||||
|
||||
auto Cartridge::loadSufamiTurboB() -> void {
|
||||
interface->loadRequest(ID::SufamiTurboSlotBManifest, "manifest.bml", true);
|
||||
auto document = BML::unserialize(information.markup.sufamiTurboB);
|
||||
information.title.sufamiTurboB = document["information/title"].text();
|
||||
if(auto fp = interface->open(ID::SufamiTurboB, "manifest.bml", File::Read, File::Required)) {
|
||||
information.manifest.sufamiTurboB = fp->reads();
|
||||
} else return;
|
||||
loadSufamiTurboB(BML::unserialize(information.manifest.sufamiTurboB));
|
||||
}
|
||||
|
||||
auto rom = document["board/rom"];
|
||||
auto ram = document["board/ram"];
|
||||
|
||||
if(rom["name"]) {
|
||||
uint size = rom["size"].natural();
|
||||
sufamiturboB.rom.map(allocate<uint8>(size, 0xff), size);
|
||||
interface->loadRequest(ID::SufamiTurboSlotBROM, rom["name"].text(), true);
|
||||
}
|
||||
|
||||
if(ram["name"]) {
|
||||
uint size = ram["size"].natural();
|
||||
sufamiturboB.ram.map(allocate<uint8>(size, 0xff), size);
|
||||
interface->loadRequest(ID::SufamiTurboSlotBRAM, ram["name"].text(), false);
|
||||
memory.append({ID::SufamiTurboSlotBRAM, ram["name"].text()});
|
||||
}
|
||||
auto Cartridge::save() -> void {
|
||||
saveCartridge(BML::unserialize(information.manifest.cartridge));
|
||||
saveGameBoy(BML::unserialize(information.manifest.gameBoy));
|
||||
saveBSMemory(BML::unserialize(information.manifest.bsMemory));
|
||||
saveSufamiTurboA(BML::unserialize(information.manifest.sufamiTurboA));
|
||||
saveSufamiTurboB(BML::unserialize(information.manifest.sufamiTurboB));
|
||||
}
|
||||
|
||||
auto Cartridge::unload() -> void {
|
||||
rom.reset();
|
||||
ram.reset();
|
||||
memory.reset();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -3,11 +3,11 @@ struct Cartridge {
|
|||
|
||||
auto sha256() const -> string { return _sha256; }
|
||||
auto region() const -> Region { return _region; }
|
||||
auto manifest() const -> string;
|
||||
auto title() const -> string;
|
||||
|
||||
auto manifest() -> string;
|
||||
auto title() -> string;
|
||||
|
||||
auto load() -> void;
|
||||
auto load() -> bool;
|
||||
auto save() -> void;
|
||||
auto unload() -> void;
|
||||
|
||||
auto serialize(serializer&) -> void;
|
||||
|
@ -15,20 +15,14 @@ struct Cartridge {
|
|||
MappedRAM rom;
|
||||
MappedRAM ram;
|
||||
|
||||
struct Memory {
|
||||
unsigned id;
|
||||
string name;
|
||||
};
|
||||
vector<Memory> memory;
|
||||
|
||||
struct Information {
|
||||
struct Markup {
|
||||
struct Manifest {
|
||||
string cartridge;
|
||||
string gameBoy;
|
||||
string bsMemory;
|
||||
string sufamiTurboA;
|
||||
string sufamiTurboB;
|
||||
} markup;
|
||||
} manifest;
|
||||
|
||||
struct Title {
|
||||
string cartridge;
|
||||
|
@ -39,62 +33,94 @@ struct Cartridge {
|
|||
} title;
|
||||
} information;
|
||||
|
||||
bool hasICD2;
|
||||
bool hasMCC;
|
||||
bool hasNSSDIP;
|
||||
bool hasEvent;
|
||||
bool hasSA1;
|
||||
bool hasSuperFX;
|
||||
bool hasARMDSP;
|
||||
bool hasHitachiDSP;
|
||||
bool hasNECDSP;
|
||||
bool hasEpsonRTC;
|
||||
bool hasSharpRTC;
|
||||
bool hasSPC7110;
|
||||
bool hasSDD1;
|
||||
bool hasOBC1;
|
||||
bool hasMSU1;
|
||||
struct Has {
|
||||
boolean ICD2;
|
||||
boolean MCC;
|
||||
boolean NSSDIP;
|
||||
boolean Event;
|
||||
boolean SA1;
|
||||
boolean SuperFX;
|
||||
boolean ARMDSP;
|
||||
boolean HitachiDSP;
|
||||
boolean NECDSP;
|
||||
boolean EpsonRTC;
|
||||
boolean SharpRTC;
|
||||
boolean SPC7110;
|
||||
boolean SDD1;
|
||||
boolean OBC1;
|
||||
boolean MSU1;
|
||||
|
||||
bool hasGameBoySlot;
|
||||
bool hasBSMemorySlot;
|
||||
bool hasSufamiTurboSlots;
|
||||
boolean GameBoySlot;
|
||||
boolean BSMemorySlot;
|
||||
boolean SufamiTurboSlots;
|
||||
} has;
|
||||
|
||||
private:
|
||||
//cartridge.cpp
|
||||
auto loadGameBoy() -> void;
|
||||
auto loadBSMemory() -> void;
|
||||
auto loadSufamiTurboA() -> void;
|
||||
auto loadSufamiTurboB() -> void;
|
||||
friend class Interface;
|
||||
friend class ICD2;
|
||||
|
||||
//markup.cpp
|
||||
auto parseMarkup(const string&) -> void;
|
||||
auto parseMarkupMap(Markup::Node, SuperFamicom::Memory&) -> void;
|
||||
auto parseMarkupMap(Markup::Node, const function<uint8 (uint24, uint8)>&, const function<void (uint24, uint8)>&) -> void;
|
||||
auto parseMarkupMemory(MappedRAM&, Markup::Node, uint id, bool writable) -> void;
|
||||
//load.cpp
|
||||
auto loadCartridge(Markup::Node) -> void;
|
||||
auto loadGameBoy(Markup::Node) -> void;
|
||||
auto loadBSMemory(Markup::Node) -> void;
|
||||
auto loadSufamiTurboA(Markup::Node) -> void;
|
||||
auto loadSufamiTurboB(Markup::Node) -> void;
|
||||
|
||||
auto parseMarkupROM(Markup::Node) -> void;
|
||||
auto parseMarkupRAM(Markup::Node) -> void;
|
||||
auto parseMarkupICD2(Markup::Node) -> void;
|
||||
auto parseMarkupMCC(Markup::Node) -> void;
|
||||
auto parseMarkupBSMemory(Markup::Node) -> void;
|
||||
auto parseMarkupSufamiTurbo(Markup::Node, bool slot) -> void;
|
||||
auto parseMarkupNSS(Markup::Node) -> void;
|
||||
auto parseMarkupEvent(Markup::Node) -> void;
|
||||
auto parseMarkupSA1(Markup::Node) -> void;
|
||||
auto parseMarkupSuperFX(Markup::Node) -> void;
|
||||
auto parseMarkupARMDSP(Markup::Node) -> void;
|
||||
auto parseMarkupHitachiDSP(Markup::Node, unsigned roms) -> void;
|
||||
auto parseMarkupNECDSP(Markup::Node) -> void;
|
||||
auto parseMarkupEpsonRTC(Markup::Node) -> void;
|
||||
auto parseMarkupSharpRTC(Markup::Node) -> void;
|
||||
auto parseMarkupSPC7110(Markup::Node) -> void;
|
||||
auto parseMarkupSDD1(Markup::Node) -> void;
|
||||
auto parseMarkupOBC1(Markup::Node) -> void;
|
||||
auto parseMarkupMSU1(Markup::Node) -> void;
|
||||
auto loadROM(Markup::Node) -> void;
|
||||
auto loadRAM(Markup::Node) -> void;
|
||||
auto loadICD2(Markup::Node) -> void;
|
||||
auto loadMCC(Markup::Node) -> void;
|
||||
auto loadBSMemoryPack(Markup::Node) -> void;
|
||||
auto loadSufamiTurbo(Markup::Node, bool slot) -> void;
|
||||
auto loadNSS(Markup::Node) -> void;
|
||||
auto loadEvent(Markup::Node) -> void;
|
||||
auto loadSA1(Markup::Node) -> void;
|
||||
auto loadSuperFX(Markup::Node) -> void;
|
||||
auto loadARMDSP(Markup::Node) -> void;
|
||||
auto loadHitachiDSP(Markup::Node, uint roms) -> void;
|
||||
auto loadNECDSP(Markup::Node) -> void;
|
||||
auto loadEpsonRTC(Markup::Node) -> void;
|
||||
auto loadSharpRTC(Markup::Node) -> void;
|
||||
auto loadSPC7110(Markup::Node) -> void;
|
||||
auto loadSDD1(Markup::Node) -> void;
|
||||
auto loadOBC1(Markup::Node) -> void;
|
||||
auto loadMSU1(Markup::Node) -> void;
|
||||
|
||||
auto loadMemory(MappedRAM&, Markup::Node, bool writable, uint id = 1) -> void;
|
||||
auto loadMap(Markup::Node, SuperFamicom::Memory&) -> void;
|
||||
auto loadMap(Markup::Node, const function<uint8 (uint24, uint8)>&, const function<void (uint24, uint8)>&) -> void;
|
||||
|
||||
//save.cpp
|
||||
auto saveCartridge(Markup::Node) -> void;
|
||||
auto saveGameBoy(Markup::Node) -> void;
|
||||
auto saveBSMemory(Markup::Node) -> void;
|
||||
auto saveSufamiTurboA(Markup::Node) -> void;
|
||||
auto saveSufamiTurboB(Markup::Node) -> void;
|
||||
|
||||
auto saveRAM(Markup::Node) -> void;
|
||||
auto saveMCC(Markup::Node) -> void;
|
||||
auto saveEvent(Markup::Node) -> void;
|
||||
auto saveSA1(Markup::Node) -> void;
|
||||
auto saveSuperFX(Markup::Node) -> void;
|
||||
auto saveARMDSP(Markup::Node) -> void;
|
||||
auto saveHitachiDSP(Markup::Node) -> void;
|
||||
auto saveNECDSP(Markup::Node) -> void;
|
||||
auto saveEpsonRTC(Markup::Node) -> void;
|
||||
auto saveSharpRTC(Markup::Node) -> void;
|
||||
auto saveSPC7110(Markup::Node) -> void;
|
||||
auto saveSDD1(Markup::Node) -> void;
|
||||
auto saveOBC1(Markup::Node) -> void;
|
||||
|
||||
auto saveMemory(MappedRAM&, Markup::Node, uint = 1) -> void;
|
||||
|
||||
string _sha256;
|
||||
Region _region = Region::NTSC;
|
||||
|
||||
friend class Interface;
|
||||
friend class ICD2;
|
||||
};
|
||||
|
||||
extern Cartridge cartridge;
|
||||
|
|
|
@ -0,0 +1,334 @@
|
|||
auto Cartridge::loadCartridge(Markup::Node node) -> void {
|
||||
information.title.cartridge = node["information/title"].text();
|
||||
auto board = node["board"];
|
||||
_region = board["region"].text() == "pal" ? Region::PAL : Region::NTSC;
|
||||
|
||||
if(auto node = board["rom"]) loadROM(node);
|
||||
if(auto node = board["ram"]) loadRAM(node);
|
||||
if(auto node = board["icd2"]) loadICD2(node);
|
||||
if(auto node = board["mcc"]) loadMCC(node);
|
||||
if(auto node = board["bsmemory"]) loadBSMemoryPack(node);
|
||||
if(auto node = board.find("sufamiturbo")) if(node(0)) loadSufamiTurbo(node(0), 0);
|
||||
if(auto node = board.find("sufamiturbo")) if(node(1)) loadSufamiTurbo(node(1), 1);
|
||||
if(auto node = board["nss"]) loadNSS(node);
|
||||
if(auto node = board["event"]) loadEvent(node);
|
||||
if(auto node = board["sa1"]) loadSA1(node);
|
||||
if(auto node = board["superfx"]) loadSuperFX(node);
|
||||
if(auto node = board["armdsp"]) loadARMDSP(node);
|
||||
if(auto node = board["hitachidsp"]) loadHitachiDSP(node, node["information/board"].text().match("2DC*") ? 2 : 1);
|
||||
if(auto node = board["necdsp"]) loadNECDSP(node);
|
||||
if(auto node = board["epsonrtc"]) loadEpsonRTC(node);
|
||||
if(auto node = board["sharprtc"]) loadSharpRTC(node);
|
||||
if(auto node = board["spc7110"]) loadSPC7110(node);
|
||||
if(auto node = board["sdd1"]) loadSDD1(node);
|
||||
if(auto node = board["obc1"]) loadOBC1(node);
|
||||
if(auto node = board["msu1"]) loadMSU1(node);
|
||||
|
||||
if(board["mcc"] || board["bsmemory"]) interface->loadRequest(ID::BSMemory, "BS Memory", "bs", false);
|
||||
if(board["sufamiturbo"]) interface->loadRequest(ID::SufamiTurboA, "Sufami Turbo", "st", false);
|
||||
}
|
||||
|
||||
auto Cartridge::loadGameBoy(Markup::Node node) -> void {
|
||||
}
|
||||
|
||||
auto Cartridge::loadBSMemory(Markup::Node node) -> void {
|
||||
information.title.bsMemory = node["information/title"].text();
|
||||
bsmemory.readonly = (node["board/rom/type"].text() == "mrom");
|
||||
|
||||
loadMemory(bsmemory.memory, node["board/rom"], false);
|
||||
}
|
||||
|
||||
auto Cartridge::loadSufamiTurboA(Markup::Node node) -> void {
|
||||
information.title.sufamiTurboA = node["information/title"].text();
|
||||
|
||||
loadMemory(sufamiturboA.rom, node["rom"], ID::SufamiTurboA);
|
||||
loadMemory(sufamiturboA.ram, node["ram"], ID::SufamiTurboA);
|
||||
|
||||
if(node["board/linkable"]) interface->loadRequest(ID::SufamiTurboB, "Sufami Turbo", "st", false);
|
||||
}
|
||||
|
||||
auto Cartridge::loadSufamiTurboB(Markup::Node node) -> void {
|
||||
information.title.sufamiTurboB = node["information/title"].text();
|
||||
|
||||
loadMemory(sufamiturboB.rom, node["rom"], ID::SufamiTurboB);
|
||||
loadMemory(sufamiturboB.ram, node["ram"], ID::SufamiTurboB);
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
auto Cartridge::loadROM(Markup::Node root) -> void {
|
||||
loadMemory(rom, root, false);
|
||||
for(auto node : root.find("map")) loadMap(node, rom);
|
||||
}
|
||||
|
||||
auto Cartridge::loadRAM(Markup::Node root) -> void {
|
||||
loadMemory(ram, root, true);
|
||||
for(auto node : root.find("map")) loadMap(node, ram);
|
||||
}
|
||||
|
||||
auto Cartridge::loadICD2(Markup::Node root) -> void {
|
||||
has.GameBoySlot = true;
|
||||
has.ICD2 = true;
|
||||
icd2.revision = max(1, root["revision"].natural());
|
||||
|
||||
//Game Boy core loads data through ICD2 interface
|
||||
for(auto node : root.find("map")) loadMap(node, {&ICD2::read, &icd2}, {&ICD2::write, &icd2});
|
||||
}
|
||||
|
||||
auto Cartridge::loadMCC(Markup::Node root) -> void {
|
||||
has.BSMemorySlot = true;
|
||||
has.MCC = true;
|
||||
|
||||
loadMemory(mcc.rom, root["rom"], false);
|
||||
loadMemory(mcc.ram, root["ram"], true);
|
||||
|
||||
for(auto node : root.find("map")) node.text() == "mcu"
|
||||
? loadMap(node, {&MCC::mcuRead, &mcc}, {&MCC::mcuWrite, &mcc})
|
||||
: loadMap(node, {&MCC::read, &mcc}, {&MCC::write, &mcc});
|
||||
for(auto node : root["ram"].find("map")) loadMap(node, mcc.ram);
|
||||
}
|
||||
|
||||
auto Cartridge::loadBSMemoryPack(Markup::Node root) -> void {
|
||||
has.BSMemorySlot = true;
|
||||
|
||||
for(auto node : root.find("map")) {
|
||||
if(bsmemory.memory.size() == 0) continue;
|
||||
loadMap(node, bsmemory);
|
||||
}
|
||||
}
|
||||
|
||||
auto Cartridge::loadSufamiTurbo(Markup::Node root, bool slot) -> void {
|
||||
has.SufamiTurboSlots = true;
|
||||
|
||||
for(auto node : root["rom"].find("map")) {
|
||||
auto& cart = (slot == 0 ? sufamiturboA : sufamiturboB);
|
||||
if(cart.rom.size() == 0) continue;
|
||||
loadMap(node, cart.rom);
|
||||
}
|
||||
|
||||
for(auto node : root["ram"].find("map")) {
|
||||
auto& cart = (slot == 0 ? sufamiturboA : sufamiturboB);
|
||||
if(cart.ram.size() == 0) continue;
|
||||
loadMap(node, cart.ram);
|
||||
}
|
||||
}
|
||||
|
||||
auto Cartridge::loadNSS(Markup::Node root) -> void {
|
||||
has.NSSDIP = true;
|
||||
nss.dip = interface->dipSettings(root);
|
||||
|
||||
for(auto node : root.find("map")) loadMap(node, {&NSS::read, &nss}, {&NSS::write, &nss});
|
||||
}
|
||||
|
||||
auto Cartridge::loadEvent(Markup::Node root) -> void {
|
||||
auto roms = root.find("rom");
|
||||
if(roms.size() != 4) return;
|
||||
|
||||
has.Event = true;
|
||||
|
||||
for(uint n : range(4)) loadMemory(event.rom[n], roms[n], false);
|
||||
loadMemory(event.ram, root["ram"], true);
|
||||
|
||||
event.board = Event::Board::CampusChallenge92;
|
||||
if(root.text() == "CC92") event.board = Event::Board::CampusChallenge92;
|
||||
if(root.text() == "PF94") event.board = Event::Board::Powerfest94;
|
||||
event.timer = root["timer"].natural();
|
||||
|
||||
for(auto node : root.find("map")) node.text() == "mcu"
|
||||
? loadMap(node, {&Event::mcuRead, &event}, {&Event::mcuWrite, &event})
|
||||
: loadMap(node, {&Event::read, &event}, {&Event::write, &event});
|
||||
for(auto node : root["ram"].find("map")) loadMap(node, event.ram);
|
||||
}
|
||||
|
||||
auto Cartridge::loadSA1(Markup::Node root) -> void {
|
||||
has.SA1 = true;
|
||||
|
||||
loadMemory(sa1.rom, root["rom"], false);
|
||||
loadMemory(sa1.bwram, root["bwram"], true);
|
||||
loadMemory(sa1.iram, root["iram"], true);
|
||||
|
||||
for(auto node : root.find("map")) loadMap(node, {&SA1::readIO, &sa1}, {&SA1::writeIO, &sa1});
|
||||
for(auto node : root["rom"].find("map")) loadMap(node, {&SA1::mmcromRead, &sa1}, {&SA1::mmcromWrite, &sa1});
|
||||
for(auto node : root["bwram"].find("map")) loadMap(node, {&SA1::mmcbwramRead, &sa1}, {&SA1::mmcbwramWrite, &sa1});
|
||||
for(auto node : root["iram"].find("map")) loadMap(node, sa1.cpuiram);
|
||||
}
|
||||
|
||||
auto Cartridge::loadSuperFX(Markup::Node root) -> void {
|
||||
has.SuperFX = true;
|
||||
|
||||
loadMemory(superfx.rom, root["rom"], false);
|
||||
loadMemory(superfx.ram, root["ram"], true);
|
||||
|
||||
for(auto node : root.find("map")) loadMap(node, {&SuperFX::readIO, &superfx}, {&SuperFX::writeIO, &superfx});
|
||||
for(auto node : root["rom"].find("map")) loadMap(node, superfx.cpurom);
|
||||
for(auto node : root["ram"].find("map")) loadMap(node, superfx.cpuram);
|
||||
}
|
||||
|
||||
auto Cartridge::loadARMDSP(Markup::Node root) -> void {
|
||||
has.ARMDSP = true;
|
||||
|
||||
if(auto fp = interface->open(ID::SuperFamicom, root["prom"]["name"].text(), File::Read, File::Required)) {
|
||||
for(auto n : range(128 * 1024)) armdsp.programROM[n] = fp->read();
|
||||
}
|
||||
if(auto fp = interface->open(ID::SuperFamicom, root["drom"]["name"].text(), File::Read, File::Required)) {
|
||||
for(auto n : range( 32 * 1024)) armdsp.dataROM[n] = fp->read();
|
||||
}
|
||||
if(auto fp = interface->open(ID::SuperFamicom, root["ram"]["name"].text(), File::Read)) {
|
||||
for(auto n : range( 16 * 1024)) armdsp.programRAM[n] = fp->read();
|
||||
}
|
||||
|
||||
for(auto node : root.find("map")) loadMap(node, {&ArmDSP::read, &armdsp}, {&ArmDSP::write, &armdsp});
|
||||
}
|
||||
|
||||
auto Cartridge::loadHitachiDSP(Markup::Node root, uint roms) -> void {
|
||||
has.HitachiDSP = true;
|
||||
|
||||
hitachidsp.Frequency = root["frequency"].natural();
|
||||
if(hitachidsp.Frequency == 0) hitachidsp.frequency = 20000000;
|
||||
hitachidsp.Roms = roms; //1 or 2
|
||||
|
||||
loadMemory(hitachidsp.rom, root["rom"], false);
|
||||
loadMemory(hitachidsp.ram, root["ram"], true);
|
||||
|
||||
for(auto& word : hitachidsp.dataROM) word = 0x000000;
|
||||
for(auto& word : hitachidsp.dataRAM) word = 0x00;
|
||||
|
||||
if(auto fp = interface->open(ID::SuperFamicom, root["drom"]["name"].text(), File::Read, File::Required)) {
|
||||
for(auto n : range(1 * 1024)) hitachidsp.dataROM[n] = fp->readl(3);
|
||||
}
|
||||
if(auto fp = interface->open(ID::SuperFamicom, root["dram"]["name"].text(), File::Read)) {
|
||||
for(auto n : range(3 * 1024)) hitachidsp.dataRAM[n] = fp->readl(1);
|
||||
}
|
||||
|
||||
for(auto node : root.find("map")) loadMap(node, {&HitachiDSP::dspRead, &hitachidsp}, {&HitachiDSP::dspWrite, &hitachidsp});
|
||||
for(auto node : root["rom"].find("map")) loadMap(node, {&HitachiDSP::romRead, &hitachidsp}, {&HitachiDSP::romWrite, &hitachidsp});
|
||||
for(auto node : root["ram"].find("map")) loadMap(node, {&HitachiDSP::ramRead, &hitachidsp}, {&HitachiDSP::ramWrite, &hitachidsp});
|
||||
for(auto node : root["dram"].find("map")) loadMap(node, {&HitachiDSP::dramRead, &hitachidsp}, {&HitachiDSP::dramWrite, &hitachidsp});
|
||||
}
|
||||
|
||||
auto Cartridge::loadNECDSP(Markup::Node root) -> void {
|
||||
has.NECDSP = true;
|
||||
|
||||
necdsp.frequency = root["frequency"].natural();
|
||||
if(necdsp.frequency == 0) necdsp.frequency = 8000000;
|
||||
necdsp.revision
|
||||
= root["model"].text() == "uPD7725" ? NECDSP::Revision::uPD7725
|
||||
: root["model"].text() == "uPD96050" ? NECDSP::Revision::uPD96050
|
||||
: NECDSP::Revision::uPD7725;
|
||||
|
||||
for(auto& word : necdsp.programROM) word = 0x000000;
|
||||
for(auto& word : necdsp.dataROM) word = 0x0000;
|
||||
for(auto& word : necdsp.dataRAM) word = 0x0000;
|
||||
|
||||
uint size[3] = {0};
|
||||
if(necdsp.revision == NECDSP::Revision::uPD7725 ) memory::assign(size, 2048, 1024, 256);
|
||||
if(necdsp.revision == NECDSP::Revision::uPD96050) memory::assign(size, 16384, 2048, 2048);
|
||||
|
||||
if(auto fp = interface->open(ID::SuperFamicom, root["prom"]["name"].text(), File::Read, File::Required)) {
|
||||
for(auto n : range(size[0])) necdsp.programROM[n] = fp->readl(3);
|
||||
}
|
||||
if(auto fp = interface->open(ID::SuperFamicom, root["drom"]["name"].text(), File::Read, File::Required)) {
|
||||
for(auto n : range(size[1])) necdsp.dataROM[n] = fp->readl(2);
|
||||
}
|
||||
if(auto fp = interface->open(ID::SuperFamicom, root["dram"]["name"].text(), File::Read)) {
|
||||
for(auto n : range(size[2])) necdsp.dataRAM[n] = fp->readl(2);
|
||||
}
|
||||
|
||||
for(auto node : root.find("map")) loadMap(node, {&NECDSP::read, &necdsp}, {&NECDSP::write, &necdsp});
|
||||
for(auto node : root["dram"].find("map")) loadMap(node, {&NECDSP::readRAM, &necdsp}, {&NECDSP::writeRAM, &necdsp});
|
||||
}
|
||||
|
||||
auto Cartridge::loadEpsonRTC(Markup::Node root) -> void {
|
||||
has.EpsonRTC = true;
|
||||
|
||||
if(auto fp = interface->open(ID::SuperFamicom, root["ram"]["name"].text(), File::Read)) {
|
||||
uint8 data[16] = {0};
|
||||
for(auto& byte : data) fp->read();
|
||||
epsonrtc.load(data);
|
||||
}
|
||||
|
||||
for(auto node : root.find("map")) loadMap(node, {&EpsonRTC::read, &epsonrtc}, {&EpsonRTC::write, &epsonrtc});
|
||||
}
|
||||
|
||||
auto Cartridge::loadSharpRTC(Markup::Node root) -> void {
|
||||
has.SharpRTC = true;
|
||||
|
||||
if(auto fp = interface->open(ID::SuperFamicom, root["ram"]["name"].text(), File::Read)) {
|
||||
uint8 data[16] = {0};
|
||||
for(auto& byte : data) fp->read();
|
||||
sharprtc.load(data);
|
||||
}
|
||||
|
||||
for(auto node : root.find("map")) loadMap(node, {&SharpRTC::read, &sharprtc}, {&SharpRTC::write, &sharprtc});
|
||||
}
|
||||
|
||||
auto Cartridge::loadSPC7110(Markup::Node root) -> void {
|
||||
has.SPC7110 = true;
|
||||
|
||||
loadMemory(spc7110.prom, root["prom"], false);
|
||||
loadMemory(spc7110.drom, root["drom"], false);
|
||||
loadMemory(spc7110.ram, root["ram"], true);
|
||||
|
||||
for(auto node : root.find("map")) node.text() == "mcu"
|
||||
? loadMap(node, {&SPC7110::mcuromRead, &spc7110}, {&SPC7110::mcuromWrite, &spc7110})
|
||||
: loadMap(node, {&SPC7110::read, &spc7110}, {&SPC7110::write, &spc7110});
|
||||
for(auto node : root["ram"].find("map")) loadMap(node, {&SPC7110::mcuramRead, &spc7110}, {&SPC7110::mcuramWrite, &spc7110});
|
||||
}
|
||||
|
||||
auto Cartridge::loadSDD1(Markup::Node root) -> void {
|
||||
has.SDD1 = true;
|
||||
|
||||
loadMemory(sdd1.rom, root["rom"], false);
|
||||
loadMemory(sdd1.ram, root["ram"], true);
|
||||
|
||||
for(auto node : root.find("map")) loadMap(node, {&SDD1::read, &sdd1}, {&SDD1::write, &sdd1});
|
||||
for(auto node : root["rom"].find("map")) loadMap(node, {&SDD1::mcuromRead, &sdd1}, {&SDD1::mcuromWrite, &sdd1});
|
||||
for(auto node : root["ram"].find("map")) loadMap(node, {&SDD1::mcuramRead, &sdd1}, {&SDD1::mcuramWrite, &sdd1});
|
||||
}
|
||||
|
||||
auto Cartridge::loadOBC1(Markup::Node root) -> void {
|
||||
has.OBC1 = true;
|
||||
|
||||
loadMemory(obc1.ram, root["ram"], true);
|
||||
|
||||
for(auto node : root.find("map")) loadMap(node, {&OBC1::read, &obc1}, {&OBC1::write, &obc1});
|
||||
}
|
||||
|
||||
auto Cartridge::loadMSU1(Markup::Node root) -> void {
|
||||
has.MSU1 = true;
|
||||
|
||||
for(auto node : root.find("map")) loadMap(node, {&MSU1::read, &msu1}, {&MSU1::write, &msu1});
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
auto Cartridge::loadMemory(MappedRAM& ram, Markup::Node node, bool writable, uint id) -> void {
|
||||
auto name = node["name"].text();
|
||||
auto size = node["size"].natural();
|
||||
ram.allocate(size);
|
||||
if(auto fp = interface->open(id, name, File::Read, !writable)) { //treat ROM as required; RAM as optional
|
||||
fp->read(ram.data(), ram.size());
|
||||
}
|
||||
}
|
||||
|
||||
auto Cartridge::loadMap(Markup::Node map, SuperFamicom::Memory& memory) -> void {
|
||||
auto addr = map["address"].text();
|
||||
auto size = map["size"].natural();
|
||||
auto base = map["base"].natural();
|
||||
auto mask = map["mask"].natural();
|
||||
if(size == 0) size = memory.size();
|
||||
if(size == 0) return;
|
||||
bus.map({&SuperFamicom::Memory::read, &memory}, {&SuperFamicom::Memory::write, &memory}, addr, size, base, mask);
|
||||
}
|
||||
|
||||
auto Cartridge::loadMap(
|
||||
Markup::Node map,
|
||||
const function<uint8 (uint24, uint8)>& reader,
|
||||
const function<void (uint24, uint8)>& writer
|
||||
) -> void {
|
||||
auto addr = map["address"].text();
|
||||
auto size = map["size"].natural();
|
||||
auto base = map["base"].natural();
|
||||
auto mask = map["mask"].natural();
|
||||
bus.map(reader, writer, addr, size, base, mask);
|
||||
}
|
|
@ -1,385 +0,0 @@
|
|||
auto Cartridge::parseMarkup(const string& markup) -> void {
|
||||
auto document = BML::unserialize(markup);
|
||||
auto information = document["information"];
|
||||
auto board = document["board"];
|
||||
|
||||
this->information.title.cartridge = information["title"].text();
|
||||
_region = board["region"].text() == "pal" ? Region::PAL : Region::NTSC;
|
||||
|
||||
if(auto node = board["rom"]) parseMarkupROM(node);
|
||||
if(auto node = board["ram"]) parseMarkupRAM(node);
|
||||
if(auto node = board["icd2"]) parseMarkupICD2(node);
|
||||
if(auto node = board["mcc"]) parseMarkupMCC(node);
|
||||
if(auto node = board["bsmemory"]) parseMarkupBSMemory(node);
|
||||
if(auto node = board.find("sufamiturbo")) if(node(0)) parseMarkupSufamiTurbo(node(0), 0);
|
||||
if(auto node = board.find("sufamiturbo")) if(node(1)) parseMarkupSufamiTurbo(node(1), 1);
|
||||
if(auto node = board["nss"]) parseMarkupNSS(node);
|
||||
if(auto node = board["event"]) parseMarkupEvent(node);
|
||||
if(auto node = board["sa1"]) parseMarkupSA1(node);
|
||||
if(auto node = board["superfx"]) parseMarkupSuperFX(node);
|
||||
if(auto node = board["armdsp"]) parseMarkupARMDSP(node);
|
||||
if(auto node = board["hitachidsp"]) parseMarkupHitachiDSP(node, document["information/board"].text().match("2DC*") ? 2 : 1);
|
||||
if(auto node = board["necdsp"]) parseMarkupNECDSP(node);
|
||||
if(auto node = board["epsonrtc"]) parseMarkupEpsonRTC(node);
|
||||
if(auto node = board["sharprtc"]) parseMarkupSharpRTC(node);
|
||||
if(auto node = board["spc7110"]) parseMarkupSPC7110(node);
|
||||
if(auto node = board["sdd1"]) parseMarkupSDD1(node);
|
||||
if(auto node = board["obc1"]) parseMarkupOBC1(node);
|
||||
if(auto node = board["msu1"]) parseMarkupMSU1(node);
|
||||
}
|
||||
|
||||
auto Cartridge::parseMarkupMap(Markup::Node map, SuperFamicom::Memory& memory) -> void {
|
||||
auto addr = map["address"].text();
|
||||
auto size = map["size"].natural();
|
||||
auto base = map["base"].natural();
|
||||
auto mask = map["mask"].natural();
|
||||
if(size == 0) size = memory.size();
|
||||
if(size == 0) return;
|
||||
bus.map({&SuperFamicom::Memory::read, &memory}, {&SuperFamicom::Memory::write, &memory}, addr, size, base, mask);
|
||||
}
|
||||
|
||||
auto Cartridge::parseMarkupMap(
|
||||
Markup::Node map,
|
||||
const function<uint8 (uint24, uint8)>& reader,
|
||||
const function<void (uint24, uint8)>& writer
|
||||
) -> void {
|
||||
auto addr = map["address"].text();
|
||||
auto size = map["size"].natural();
|
||||
auto base = map["base"].natural();
|
||||
auto mask = map["mask"].natural();
|
||||
bus.map(reader, writer, addr, size, base, mask);
|
||||
}
|
||||
|
||||
auto Cartridge::parseMarkupMemory(MappedRAM& ram, Markup::Node node, uint id, bool writable) -> void {
|
||||
string name = node["name"].text();
|
||||
uint size = node["size"].natural();
|
||||
bool save = !(bool)node["volatile"];
|
||||
ram.map(allocate<uint8>(size, 0xff), size);
|
||||
if(name) {
|
||||
interface->loadRequest(id, name, !writable); //treat ROM as required; RAM as optional
|
||||
if(writable && save) memory.append({id, name});
|
||||
}
|
||||
}
|
||||
|
||||
auto Cartridge::parseMarkupROM(Markup::Node root) -> void {
|
||||
parseMarkupMemory(rom, root, ID::ROM, false);
|
||||
for(auto node : root.find("map")) {
|
||||
parseMarkupMap(node, rom);
|
||||
}
|
||||
}
|
||||
|
||||
auto Cartridge::parseMarkupRAM(Markup::Node root) -> void {
|
||||
parseMarkupMemory(ram, root, ID::RAM, true);
|
||||
for(auto node : root.find("map")) {
|
||||
parseMarkupMap(node, ram);
|
||||
}
|
||||
}
|
||||
|
||||
auto Cartridge::parseMarkupICD2(Markup::Node root) -> void {
|
||||
hasGameBoySlot = true;
|
||||
hasICD2 = true;
|
||||
icd2.revision = max(1, root["revision"].natural());
|
||||
|
||||
//Game Boy core loads data through ICD2 interface
|
||||
|
||||
for(auto node : root.find("map")) {
|
||||
parseMarkupMap(node, {&ICD2::read, &icd2}, {&ICD2::write, &icd2});
|
||||
}
|
||||
}
|
||||
|
||||
auto Cartridge::parseMarkupMCC(Markup::Node root) -> void {
|
||||
hasBSMemorySlot = true;
|
||||
hasMCC = true;
|
||||
|
||||
interface->loadRequest(ID::BSMemory, "BS Memory", "bs", false);
|
||||
|
||||
parseMarkupMemory(mcc.rom, root["rom"], ID::MCCROM, false);
|
||||
parseMarkupMemory(mcc.ram, root["ram"], ID::MCCRAM, true);
|
||||
|
||||
for(auto node : root.find("map")) {
|
||||
if(node.text() == "mcu") {
|
||||
parseMarkupMap(node, {&MCC::mcuRead, &mcc}, {&MCC::mcuWrite, &mcc});
|
||||
} else {
|
||||
parseMarkupMap(node, {&MCC::read, &mcc}, {&MCC::write, &mcc});
|
||||
}
|
||||
}
|
||||
|
||||
for(auto node : root["ram"].find("map")) {
|
||||
parseMarkupMap(node, mcc.ram);
|
||||
}
|
||||
}
|
||||
|
||||
auto Cartridge::parseMarkupBSMemory(Markup::Node root) -> void {
|
||||
hasBSMemorySlot = true;
|
||||
|
||||
interface->loadRequest(ID::BSMemory, "BS Memory", "bs", false);
|
||||
|
||||
for(auto node : root.find("map")) {
|
||||
if(bsmemory.memory.size() == 0) continue;
|
||||
parseMarkupMap(node, bsmemory);
|
||||
}
|
||||
}
|
||||
|
||||
auto Cartridge::parseMarkupSufamiTurbo(Markup::Node root, bool slot) -> void {
|
||||
hasSufamiTurboSlots = true;
|
||||
|
||||
if(slot == 0) {
|
||||
//load required slot A (will request slot B if slot A cartridge is linkable)
|
||||
interface->loadRequest(ID::SufamiTurboSlotA, "Sufami Turbo", "st", false);
|
||||
}
|
||||
|
||||
for(auto node : root["rom"].find("map")) {
|
||||
SufamiTurboCartridge& cart = (slot == 0 ? sufamiturboA : sufamiturboB);
|
||||
if(cart.rom.size() == 0) continue;
|
||||
parseMarkupMap(node, cart.rom);
|
||||
}
|
||||
|
||||
for(auto node : root["ram"].find("map")) {
|
||||
SufamiTurboCartridge& cart = (slot == 0 ? sufamiturboA : sufamiturboB);
|
||||
if(cart.ram.size() == 0) continue;
|
||||
parseMarkupMap(node, cart.ram);
|
||||
}
|
||||
}
|
||||
|
||||
auto Cartridge::parseMarkupNSS(Markup::Node root) -> void {
|
||||
hasNSSDIP = true;
|
||||
nss.dip = interface->dipSettings(root);
|
||||
|
||||
for(auto node : root.find("map")) {
|
||||
parseMarkupMap(node, {&NSS::read, &nss}, {&NSS::write, &nss});
|
||||
}
|
||||
}
|
||||
|
||||
auto Cartridge::parseMarkupEvent(Markup::Node root) -> void {
|
||||
auto roms = root.find("rom");
|
||||
if(roms.size() != 4) return;
|
||||
|
||||
hasEvent = true;
|
||||
|
||||
for(uint n : range(4)) {
|
||||
parseMarkupMemory(event.rom[n], roms[n], ID::EventROM0 + n, false);
|
||||
}
|
||||
parseMarkupMemory(event.ram, root["ram"], ID::EventRAM, true);
|
||||
|
||||
event.board = Event::Board::CampusChallenge92;
|
||||
if(root.text() == "CC92") event.board = Event::Board::CampusChallenge92;
|
||||
if(root.text() == "PF94") event.board = Event::Board::Powerfest94;
|
||||
event.timer = root["timer"].natural();
|
||||
|
||||
for(auto node : root.find("map")) {
|
||||
if(node.text() == "mcu") {
|
||||
parseMarkupMap(node, {&Event::mcuRead, &event}, {&Event::mcuWrite, &event});
|
||||
} else {
|
||||
parseMarkupMap(node, {&Event::read, &event}, {&Event::write, &event});
|
||||
}
|
||||
}
|
||||
|
||||
for(auto node : root["ram"].find("map")) {
|
||||
parseMarkupMap(node, event.ram);
|
||||
}
|
||||
}
|
||||
|
||||
auto Cartridge::parseMarkupSA1(Markup::Node root) -> void {
|
||||
hasSA1 = true;
|
||||
|
||||
parseMarkupMemory(sa1.rom, root["rom"], ID::SA1ROM, false);
|
||||
parseMarkupMemory(sa1.bwram, root["bwram"], ID::SA1BWRAM, true);
|
||||
parseMarkupMemory(sa1.iram, root["iram"], ID::SA1IRAM, true);
|
||||
|
||||
for(auto node : root.find("map")) {
|
||||
parseMarkupMap(node, {&SA1::readIO, &sa1}, {&SA1::writeIO, &sa1});
|
||||
}
|
||||
|
||||
for(auto node : root["rom"].find("map")) {
|
||||
parseMarkupMap(node, {&SA1::mmcromRead, &sa1}, {&SA1::mmcromWrite, &sa1});
|
||||
}
|
||||
|
||||
for(auto node : root["bwram"].find("map")) {
|
||||
parseMarkupMap(node, {&SA1::mmcbwramRead, &sa1}, {&SA1::mmcbwramWrite, &sa1});
|
||||
}
|
||||
|
||||
for(auto node : root["iram"].find("map")) {
|
||||
parseMarkupMap(node, sa1.cpuiram);
|
||||
}
|
||||
}
|
||||
|
||||
auto Cartridge::parseMarkupSuperFX(Markup::Node root) -> void {
|
||||
hasSuperFX = true;
|
||||
|
||||
parseMarkupMemory(superfx.rom, root["rom"], ID::SuperFXROM, false);
|
||||
parseMarkupMemory(superfx.ram, root["ram"], ID::SuperFXRAM, true);
|
||||
|
||||
for(auto node : root.find("map")) {
|
||||
parseMarkupMap(node, {&SuperFX::readIO, &superfx}, {&SuperFX::writeIO, &superfx});
|
||||
}
|
||||
|
||||
for(auto node : root["rom"].find("map")) {
|
||||
parseMarkupMap(node, superfx.cpurom);
|
||||
}
|
||||
|
||||
for(auto node : root["ram"].find("map")) {
|
||||
parseMarkupMap(node, superfx.cpuram);
|
||||
}
|
||||
}
|
||||
|
||||
auto Cartridge::parseMarkupARMDSP(Markup::Node root) -> void {
|
||||
hasARMDSP = true;
|
||||
|
||||
interface->loadRequest(ID::ArmDSPPROM, root["prom"]["name"].text(), true);
|
||||
interface->loadRequest(ID::ArmDSPDROM, root["drom"]["name"].text(), true);
|
||||
interface->loadRequest(ID::ArmDSPRAM, root["dram"]["name"].text(), false);
|
||||
memory.append({ID::ArmDSPRAM, root["dram"]["name"].text()});
|
||||
|
||||
for(auto node : root.find("map")) {
|
||||
parseMarkupMap(node, {&ArmDSP::read, &armdsp}, {&ArmDSP::write, &armdsp});
|
||||
}
|
||||
}
|
||||
|
||||
auto Cartridge::parseMarkupHitachiDSP(Markup::Node root, uint roms) -> void {
|
||||
hasHitachiDSP = true;
|
||||
|
||||
hitachidsp.Frequency = root["frequency"].natural();
|
||||
if(hitachidsp.Frequency == 0) hitachidsp.frequency = 20000000;
|
||||
hitachidsp.Roms = roms; //1 or 2
|
||||
|
||||
for(auto& word : hitachidsp.dataROM) word = 0x000000;
|
||||
for(auto& word : hitachidsp.dataRAM) word = 0x00;
|
||||
|
||||
interface->loadRequest(ID::HitachiDSPDROM, root["drom"]["name"].text(), true);
|
||||
interface->loadRequest(ID::HitachiDSPDRAM, root["dram"]["name"].text(), false);
|
||||
|
||||
parseMarkupMemory(hitachidsp.rom, root["rom"], ID::HitachiDSPROM, false);
|
||||
parseMarkupMemory(hitachidsp.ram, root["ram"], ID::HitachiDSPRAM, true);
|
||||
|
||||
for(auto node : root.find("map")) {
|
||||
parseMarkupMap(node, {&HitachiDSP::dspRead, &hitachidsp}, {&HitachiDSP::dspWrite, &hitachidsp});
|
||||
}
|
||||
|
||||
for(auto node : root["rom"].find("map")) {
|
||||
parseMarkupMap(node, {&HitachiDSP::romRead, &hitachidsp}, {&HitachiDSP::romWrite, &hitachidsp});
|
||||
}
|
||||
|
||||
for(auto node : root["ram"].find("map")) {
|
||||
parseMarkupMap(node, {&HitachiDSP::ramRead, &hitachidsp}, {&HitachiDSP::ramWrite, &hitachidsp});
|
||||
}
|
||||
|
||||
for(auto node : root["dram"].find("map")) {
|
||||
parseMarkupMap(node, {&HitachiDSP::dramRead, &hitachidsp}, {&HitachiDSP::dramWrite, &hitachidsp});
|
||||
}
|
||||
}
|
||||
|
||||
auto Cartridge::parseMarkupNECDSP(Markup::Node root) -> void {
|
||||
hasNECDSP = true;
|
||||
|
||||
necdsp.frequency = root["frequency"].natural();
|
||||
if(necdsp.frequency == 0) necdsp.frequency = 8000000;
|
||||
necdsp.revision
|
||||
= root["model"].text() == "uPD7725" ? NECDSP::Revision::uPD7725
|
||||
: root["model"].text() == "uPD96050" ? NECDSP::Revision::uPD96050
|
||||
: NECDSP::Revision::uPD7725;
|
||||
|
||||
for(auto& word : necdsp.programROM) word = 0x000000;
|
||||
for(auto& word : necdsp.dataROM) word = 0x0000;
|
||||
for(auto& word : necdsp.dataRAM) word = 0x0000;
|
||||
|
||||
if(necdsp.revision == NECDSP::Revision::uPD7725) {
|
||||
interface->loadRequest(ID::Nec7725DSPPROM, root["prom"]["name"].text(), true);
|
||||
interface->loadRequest(ID::Nec7725DSPDROM, root["drom"]["name"].text(), true);
|
||||
interface->loadRequest(ID::Nec7725DSPRAM, root["dram"]["name"].text(), false);
|
||||
memory.append({ID::Nec7725DSPRAM, root["dram"]["name"].text()});
|
||||
}
|
||||
|
||||
if(necdsp.revision == NECDSP::Revision::uPD96050) {
|
||||
interface->loadRequest(ID::Nec96050DSPPROM, root["prom"]["name"].text(), true);
|
||||
interface->loadRequest(ID::Nec96050DSPDROM, root["drom"]["name"].text(), true);
|
||||
interface->loadRequest(ID::Nec96050DSPRAM, root["dram"]["name"].text(), false);
|
||||
memory.append({ID::Nec96050DSPRAM, root["dram"]["name"].text()});
|
||||
}
|
||||
|
||||
for(auto node : root.find("map")) {
|
||||
parseMarkupMap(node, {&NECDSP::read, &necdsp}, {&NECDSP::write, &necdsp});
|
||||
}
|
||||
|
||||
for(auto node : root["dram"].find("map")) {
|
||||
parseMarkupMap(node, {&NECDSP::readRAM, &necdsp}, {&NECDSP::writeRAM, &necdsp});
|
||||
}
|
||||
}
|
||||
|
||||
auto Cartridge::parseMarkupEpsonRTC(Markup::Node root) -> void {
|
||||
hasEpsonRTC = true;
|
||||
|
||||
interface->loadRequest(ID::EpsonRTC, root["ram"]["name"].text(), false);
|
||||
memory.append({ID::EpsonRTC, root["ram"]["name"].text()});
|
||||
|
||||
for(auto node : root.find("map")) {
|
||||
parseMarkupMap(node, {&EpsonRTC::read, &epsonrtc}, {&EpsonRTC::write, &epsonrtc});
|
||||
}
|
||||
}
|
||||
|
||||
auto Cartridge::parseMarkupSharpRTC(Markup::Node root) -> void {
|
||||
hasSharpRTC = true;
|
||||
|
||||
interface->loadRequest(ID::SharpRTC, root["ram"]["name"].text(), false);
|
||||
memory.append({ID::SharpRTC, root["ram"]["name"].text()});
|
||||
|
||||
for(auto node : root.find("map")) {
|
||||
parseMarkupMap(node, {&SharpRTC::read, &sharprtc}, {&SharpRTC::write, &sharprtc});
|
||||
}
|
||||
}
|
||||
|
||||
auto Cartridge::parseMarkupSPC7110(Markup::Node root) -> void {
|
||||
hasSPC7110 = true;
|
||||
|
||||
parseMarkupMemory(spc7110.prom, root["prom"], ID::SPC7110PROM, false);
|
||||
parseMarkupMemory(spc7110.drom, root["drom"], ID::SPC7110DROM, false);
|
||||
parseMarkupMemory(spc7110.ram, root["ram"], ID::SPC7110RAM, true);
|
||||
|
||||
for(auto node : root.find("map")) {
|
||||
if(node.text() == "mcu") {
|
||||
parseMarkupMap(node, {&SPC7110::mcuromRead, &spc7110}, {&SPC7110::mcuromWrite, &spc7110});
|
||||
} else {
|
||||
parseMarkupMap(node, {&SPC7110::read, &spc7110}, {&SPC7110::write, &spc7110});
|
||||
}
|
||||
}
|
||||
|
||||
for(auto node : root["ram"].find("map")) {
|
||||
parseMarkupMap(node, {&SPC7110::mcuramRead, &spc7110}, {&SPC7110::mcuramWrite, &spc7110});
|
||||
}
|
||||
}
|
||||
|
||||
auto Cartridge::parseMarkupSDD1(Markup::Node root) -> void {
|
||||
hasSDD1 = true;
|
||||
|
||||
parseMarkupMemory(sdd1.rom, root["rom"], ID::SDD1ROM, false);
|
||||
parseMarkupMemory(sdd1.ram, root["ram"], ID::SDD1RAM, true);
|
||||
|
||||
for(auto node : root.find("map")) {
|
||||
parseMarkupMap(node, {&SDD1::read, &sdd1}, {&SDD1::write, &sdd1});
|
||||
}
|
||||
|
||||
for(auto node : root["rom"].find("map")) {
|
||||
parseMarkupMap(node, {&SDD1::mcuromRead, &sdd1}, {&SDD1::mcuromWrite, &sdd1});
|
||||
}
|
||||
|
||||
for(auto node : root["ram"].find("map")) {
|
||||
parseMarkupMap(node, {&SDD1::mcuramRead, &sdd1}, {&SDD1::mcuramWrite, &sdd1});
|
||||
}
|
||||
}
|
||||
|
||||
auto Cartridge::parseMarkupOBC1(Markup::Node root) -> void {
|
||||
hasOBC1 = true;
|
||||
|
||||
parseMarkupMemory(obc1.ram, root["ram"], ID::OBC1RAM, true);
|
||||
|
||||
for(auto node : root.find("map")) {
|
||||
parseMarkupMap(node, {&OBC1::read, &obc1}, {&OBC1::write, &obc1});
|
||||
}
|
||||
}
|
||||
|
||||
auto Cartridge::parseMarkupMSU1(Markup::Node root) -> void {
|
||||
hasMSU1 = true;
|
||||
|
||||
for(auto node : root.find("map")) {
|
||||
parseMarkupMap(node, {&MSU1::read, &msu1}, {&MSU1::write, &msu1});
|
||||
}
|
||||
}
|
|
@ -0,0 +1,123 @@
|
|||
auto Cartridge::saveCartridge(Markup::Node node) -> void {
|
||||
auto board = node["board"];
|
||||
|
||||
if(auto node = board["ram"]) saveRAM(node);
|
||||
if(auto node = board["mcc"]) saveMCC(node);
|
||||
if(auto node = board["event"]) saveEvent(node);
|
||||
if(auto node = board["sa1"]) saveSA1(node);
|
||||
if(auto node = board["superfx"]) saveSuperFX(node);
|
||||
if(auto node = board["armdsp"]) saveARMDSP(node);
|
||||
if(auto node = board["hitachidsp"]) saveHitachiDSP(node);
|
||||
if(auto node = board["necdsp"]) saveNECDSP(node);
|
||||
if(auto node = board["epsonrtc"]) saveEpsonRTC(node);
|
||||
if(auto node = board["sharprtc"]) saveSharpRTC(node);
|
||||
if(auto node = board["spc7110"]) saveSPC7110(node);
|
||||
if(auto node = board["sdd1"]) saveSDD1(node);
|
||||
if(auto node = board["obc1"]) saveOBC1(node);
|
||||
}
|
||||
|
||||
auto Cartridge::saveGameBoy(Markup::Node node) -> void {
|
||||
}
|
||||
|
||||
auto Cartridge::saveBSMemory(Markup::Node node) -> void {
|
||||
}
|
||||
|
||||
auto Cartridge::saveSufamiTurboA(Markup::Node node) -> void {
|
||||
saveMemory(sufamiturboA.ram, node["board/ram"], ID::SufamiTurboA);
|
||||
}
|
||||
|
||||
auto Cartridge::saveSufamiTurboB(Markup::Node node) -> void {
|
||||
saveMemory(sufamiturboB.ram, node["board/ram"], ID::SufamiTurboB);
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
auto Cartridge::saveRAM(Markup::Node node) -> void {
|
||||
saveMemory(ram, node);
|
||||
}
|
||||
|
||||
auto Cartridge::saveMCC(Markup::Node node) -> void {
|
||||
saveMemory(mcc.ram, node["ram"]);
|
||||
}
|
||||
|
||||
auto Cartridge::saveEvent(Markup::Node node) -> void {
|
||||
saveMemory(event.ram, node["ram"]);
|
||||
}
|
||||
|
||||
auto Cartridge::saveSA1(Markup::Node node) -> void {
|
||||
saveMemory(sa1.bwram, node["bwram"]);
|
||||
saveMemory(sa1.iram, node["iram"]);
|
||||
}
|
||||
|
||||
auto Cartridge::saveSuperFX(Markup::Node node) -> void {
|
||||
saveMemory(superfx.ram, node["ram"]);
|
||||
}
|
||||
|
||||
auto Cartridge::saveARMDSP(Markup::Node node) -> void {
|
||||
if(auto name = node["ram"]["name"].text()) {
|
||||
if(auto fp = interface->open(ID::SuperFamicom, name, File::Write)) {
|
||||
for(auto n : range(16 * 1024)) fp->write(armdsp.programRAM[n]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
auto Cartridge::saveHitachiDSP(Markup::Node node) -> void {
|
||||
saveMemory(hitachidsp.ram, node["ram"]);
|
||||
if(auto name = node["dram"]["name"].text()) {
|
||||
if(auto fp = interface->open(ID::SuperFamicom, name, File::Write)) {
|
||||
for(auto n : range(3 * 1024)) fp->write(hitachidsp.dataRAM[n]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
auto Cartridge::saveNECDSP(Markup::Node node) -> void {
|
||||
uint size = necdsp.revision == NECDSP::Revision::uPD7725 ? 256 : 2048;
|
||||
if(auto name = node["dram"]["name"].text()) {
|
||||
if(auto fp = interface->open(ID::SuperFamicom, name, File::Write)) {
|
||||
for(auto n : range(size)) fp->writel(necdsp.dataRAM[n], 2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
auto Cartridge::saveEpsonRTC(Markup::Node node) -> void {
|
||||
if(auto name = node["ram"]["name"].text()) {
|
||||
if(auto fp = interface->open(ID::SuperFamicom, name, File::Write)) {
|
||||
uint8 data[16] = {0};
|
||||
epsonrtc.save(data);
|
||||
fp->write(data, 16);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
auto Cartridge::saveSharpRTC(Markup::Node node) -> void {
|
||||
if(auto name = node["ram"]["name"].text()) {
|
||||
if(auto fp = interface->open(ID::SuperFamicom, name, File::Write)) {
|
||||
uint8 data[16] = {0};
|
||||
sharprtc.save(data);
|
||||
fp->write(data, 16);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
auto Cartridge::saveSPC7110(Markup::Node node) -> void {
|
||||
saveMemory(spc7110.ram, node["ram"]);
|
||||
}
|
||||
|
||||
auto Cartridge::saveSDD1(Markup::Node node) -> void {
|
||||
saveMemory(sdd1.ram, node["ram"]);
|
||||
}
|
||||
|
||||
auto Cartridge::saveOBC1(Markup::Node node) -> void {
|
||||
saveMemory(obc1.ram, node["ram"]);
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
auto Cartridge::saveMemory(MappedRAM& memory, Markup::Node node, uint id) -> void {
|
||||
if(!node || node["volatile"]) return;
|
||||
auto name = node["name"].text();
|
||||
auto size = node["size"].natural();
|
||||
if(auto fp = interface->open(id, name, File::Write)) {
|
||||
fp->write(memory.data(), memory.size());
|
||||
}
|
||||
}
|
|
@ -1,6 +1,6 @@
|
|||
auto ArmDSP::firmware() const -> nall::vector<uint8> {
|
||||
nall::vector<uint8> buffer;
|
||||
if(!cartridge.hasARMDSP) return buffer;
|
||||
if(!cartridge.has.ARMDSP) return buffer;
|
||||
buffer.reserve(128 * 1024 + 32 * 1024);
|
||||
for(auto n : range(128 * 1024)) buffer.append(programROM[n]);
|
||||
for(auto n : range( 32 * 1024)) buffer.append(dataROM[n]);
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
auto HitachiDSP::firmware() const -> vector<uint8> {
|
||||
vector<uint8> buffer;
|
||||
if(!cartridge.hasHitachiDSP) return buffer;
|
||||
if(!cartridge.has.HitachiDSP) return buffer;
|
||||
buffer.reserve(1024 * 3);
|
||||
for(auto n : range(1024)) {
|
||||
buffer.append(dataROM[n] >> 0);
|
||||
|
|
|
@ -85,7 +85,7 @@ auto MSU1::reset() -> void {
|
|||
|
||||
auto MSU1::dataOpen() -> void {
|
||||
if(dataFile.open()) dataFile.close();
|
||||
auto document = BML::unserialize(cartridge.information.markup.cartridge);
|
||||
auto document = BML::unserialize(cartridge.information.manifest.cartridge);
|
||||
string name = document["board/msu1/rom/name"].text();
|
||||
if(!name) name = "msu1.rom";
|
||||
if(dataFile.open({interface->path(ID::SuperFamicom), name}, file::mode::read)) {
|
||||
|
@ -95,7 +95,7 @@ auto MSU1::dataOpen() -> void {
|
|||
|
||||
auto MSU1::audioOpen() -> void {
|
||||
if(audioFile.open()) audioFile.close();
|
||||
auto document = BML::unserialize(cartridge.information.markup.cartridge);
|
||||
auto document = BML::unserialize(cartridge.information.manifest.cartridge);
|
||||
string name = {"track-", mmio.audioTrack, ".pcm"};
|
||||
for(auto track : document.find("board/msu1/track")) {
|
||||
if(track["number"].natural() != mmio.audioTrack) continue;
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
auto NECDSP::firmware() const -> vector<uint8> {
|
||||
vector<uint8> buffer;
|
||||
if(!cartridge.hasNECDSP) return buffer;
|
||||
if(!cartridge.has.NECDSP) return buffer;
|
||||
uint plength = 2048, dlength = 1024;
|
||||
if(revision == Revision::uPD96050) plength = 16384, dlength = 2048;
|
||||
buffer.reserve(plength * 3 + dlength * 2);
|
||||
|
|
|
@ -183,175 +183,33 @@ auto Interface::sha256() -> string {
|
|||
return cartridge.sha256();
|
||||
}
|
||||
|
||||
//deprecated
|
||||
auto Interface::group(uint id) -> uint {
|
||||
switch(id) {
|
||||
case ID::SystemManifest:
|
||||
case ID::IPLROM:
|
||||
return 0;
|
||||
case ID::Manifest:
|
||||
case ID::ROM:
|
||||
case ID::RAM:
|
||||
case ID::EventROM0:
|
||||
case ID::EventROM1:
|
||||
case ID::EventROM2:
|
||||
case ID::EventROM3:
|
||||
case ID::EventRAM:
|
||||
case ID::SA1ROM:
|
||||
case ID::SA1IRAM:
|
||||
case ID::SA1BWRAM:
|
||||
case ID::SuperFXROM:
|
||||
case ID::SuperFXRAM:
|
||||
case ID::ArmDSPPROM:
|
||||
case ID::ArmDSPDROM:
|
||||
case ID::ArmDSPRAM:
|
||||
case ID::HitachiDSPROM:
|
||||
case ID::HitachiDSPRAM:
|
||||
case ID::HitachiDSPDROM:
|
||||
case ID::HitachiDSPDRAM:
|
||||
case ID::Nec7725DSPPROM:
|
||||
case ID::Nec7725DSPDROM:
|
||||
case ID::Nec7725DSPRAM:
|
||||
case ID::Nec96050DSPPROM:
|
||||
case ID::Nec96050DSPDROM:
|
||||
case ID::Nec96050DSPRAM:
|
||||
case ID::EpsonRTC:
|
||||
case ID::SharpRTC:
|
||||
case ID::SPC7110PROM:
|
||||
case ID::SPC7110DROM:
|
||||
case ID::SPC7110RAM:
|
||||
case ID::SDD1ROM:
|
||||
case ID::SDD1RAM:
|
||||
case ID::OBC1RAM:
|
||||
case ID::SuperGameBoyManifest:
|
||||
case ID::SuperGameBoyBootROM:
|
||||
case ID::MCCROM:
|
||||
case ID::MCCRAM:
|
||||
return 1;
|
||||
case ID::GameBoy:
|
||||
case ID::GameBoyManifest:
|
||||
case ID::GameBoyROM:
|
||||
case ID::GameBoyRAM:
|
||||
return 2;
|
||||
case ID::BSMemory:
|
||||
case ID::BSMemoryManifest:
|
||||
case ID::BSMemoryROM:
|
||||
return 3;
|
||||
case ID::SufamiTurboSlotA:
|
||||
case ID::SufamiTurboSlotAManifest:
|
||||
case ID::SufamiTurboSlotAROM:
|
||||
case ID::SufamiTurboSlotARAM:
|
||||
return 4;
|
||||
case ID::SufamiTurboSlotB:
|
||||
case ID::SufamiTurboSlotBManifest:
|
||||
case ID::SufamiTurboSlotBROM:
|
||||
case ID::SufamiTurboSlotBRAM:
|
||||
return 5;
|
||||
}
|
||||
|
||||
throw;
|
||||
}
|
||||
|
||||
auto Interface::load(uint id) -> void {
|
||||
if(id == ID::SuperFamicom) system.load();
|
||||
if(id == ID::BSMemory) cartridge.loadBSMemory();
|
||||
if(id == ID::SufamiTurboSlotA) cartridge.loadSufamiTurboA();
|
||||
if(id == ID::SufamiTurboSlotB) cartridge.loadSufamiTurboB();
|
||||
if(id == ID::SufamiTurboA) cartridge.loadSufamiTurboA();
|
||||
if(id == ID::SufamiTurboB) cartridge.loadSufamiTurboB();
|
||||
}
|
||||
|
||||
auto Interface::save() -> void {
|
||||
for(auto& memory : cartridge.memory) {
|
||||
saveRequest(memory.id, memory.name);
|
||||
}
|
||||
system.save();
|
||||
}
|
||||
|
||||
//deprecated
|
||||
auto Interface::load(uint id, const stream& stream) -> void {
|
||||
if(id == ID::SystemManifest) {
|
||||
system.information.manifest = stream.text();
|
||||
}
|
||||
|
||||
if(id == ID::IPLROM) {
|
||||
stream.read((uint8_t*)smp.iplrom, min(64u, stream.size()));
|
||||
}
|
||||
|
||||
if(id == ID::Manifest) cartridge.information.markup.cartridge = stream.text();
|
||||
if(id == ID::ROM) cartridge.rom.read(stream);
|
||||
if(id == ID::RAM) cartridge.ram.read(stream);
|
||||
|
||||
if(id == ID::EventROM0) event.rom[0].read(stream);
|
||||
if(id == ID::EventROM1) event.rom[1].read(stream);
|
||||
if(id == ID::EventROM2) event.rom[2].read(stream);
|
||||
if(id == ID::EventROM3) event.rom[3].read(stream);
|
||||
if(id == ID::EventRAM) event.ram.read(stream);
|
||||
|
||||
if(id == ID::SA1ROM) sa1.rom.read(stream);
|
||||
if(id == ID::SA1IRAM) sa1.iram.read(stream);
|
||||
if(id == ID::SA1BWRAM) sa1.bwram.read(stream);
|
||||
|
||||
if(id == ID::SuperFXROM) superfx.rom.read(stream);
|
||||
if(id == ID::SuperFXRAM) superfx.ram.read(stream);
|
||||
|
||||
if(id == ID::ArmDSPPROM) {
|
||||
for(auto n : range(128 * 1024)) armdsp.programROM[n] = stream.read();
|
||||
}
|
||||
if(id == ID::ArmDSPDROM) {
|
||||
for(auto n : range( 32 * 1024)) armdsp.dataROM[n] = stream.read();
|
||||
}
|
||||
if(id == ID::ArmDSPRAM) {
|
||||
for(auto n : range( 16 * 1024)) armdsp.programRAM[n] = stream.read();
|
||||
}
|
||||
|
||||
if(id == ID::HitachiDSPROM) hitachidsp.rom.read(stream);
|
||||
if(id == ID::HitachiDSPRAM) hitachidsp.ram.read(stream);
|
||||
if(id == ID::HitachiDSPDROM) {
|
||||
for(auto n : range(1024)) hitachidsp.dataROM[n] = stream.readl(3);
|
||||
}
|
||||
if(id == ID::HitachiDSPDRAM) {
|
||||
for(auto n : range(3072)) hitachidsp.dataRAM[n] = stream.readl(1);
|
||||
}
|
||||
|
||||
if(id == ID::Nec7725DSPPROM) {
|
||||
for(auto n : range( 2048)) necdsp.programROM[n] = stream.readl(3);
|
||||
}
|
||||
if(id == ID::Nec7725DSPDROM) {
|
||||
for(auto n : range( 1024)) necdsp.dataROM[n] = stream.readl(2);
|
||||
}
|
||||
if(id == ID::Nec7725DSPRAM) {
|
||||
for(auto n : range( 256)) necdsp.dataRAM[n] = stream.readl(2);
|
||||
}
|
||||
if(id == ID::Nec96050DSPPROM) {
|
||||
for(auto n : range(16384)) necdsp.programROM[n] = stream.readl(3);
|
||||
}
|
||||
if(id == ID::Nec96050DSPDROM) {
|
||||
for(auto n : range( 2048)) necdsp.dataROM[n] = stream.readl(2);
|
||||
}
|
||||
if(id == ID::Nec96050DSPRAM) {
|
||||
for(auto n : range( 2048)) necdsp.dataRAM[n] = stream.readl(2);
|
||||
}
|
||||
|
||||
if(id == ID::EpsonRTC) {
|
||||
uint8 data[16] = {0};
|
||||
stream.read((uint8_t*)data, min(stream.size(), sizeof data));
|
||||
epsonrtc.load(data);
|
||||
}
|
||||
|
||||
if(id == ID::SharpRTC) {
|
||||
uint8 data[16] = {0};
|
||||
stream.read((uint8_t*)data, min(stream.size(), sizeof data));
|
||||
sharprtc.load(data);
|
||||
}
|
||||
|
||||
if(id == ID::SPC7110PROM) spc7110.prom.read(stream);
|
||||
if(id == ID::SPC7110DROM) spc7110.drom.read(stream);
|
||||
if(id == ID::SPC7110RAM) spc7110.ram.read(stream);
|
||||
|
||||
if(id == ID::SDD1ROM) sdd1.rom.read(stream);
|
||||
if(id == ID::SDD1RAM) sdd1.ram.read(stream);
|
||||
|
||||
if(id == ID::OBC1RAM) obc1.ram.read(stream);
|
||||
|
||||
if(id == ID::MCCROM) mcc.rom.read(stream);
|
||||
if(id == ID::MCCRAM) mcc.ram.read(stream);
|
||||
|
||||
#if defined(SFC_SUPERGAMEBOY)
|
||||
if(id == ID::SuperGameBoyManifest) {
|
||||
GameBoy::interface->load(GameBoy::ID::SystemManifest, stream);
|
||||
|
@ -373,68 +231,15 @@ auto Interface::load(uint id, const stream& stream) -> void {
|
|||
GameBoy::interface->load(GameBoy::ID::RAM, stream);
|
||||
}
|
||||
#endif
|
||||
|
||||
if(id == ID::BSMemoryManifest) cartridge.information.markup.bsMemory = stream.text();
|
||||
if(id == ID::BSMemoryROM) bsmemory.memory.read(stream);
|
||||
|
||||
if(id == ID::SufamiTurboSlotAManifest) cartridge.information.markup.sufamiTurboA = stream.text();
|
||||
if(id == ID::SufamiTurboSlotAROM) sufamiturboA.rom.read(stream);
|
||||
if(id == ID::SufamiTurboSlotBROM) sufamiturboB.rom.read(stream);
|
||||
|
||||
if(id == ID::SufamiTurboSlotBManifest) cartridge.information.markup.sufamiTurboB = stream.text();
|
||||
if(id == ID::SufamiTurboSlotARAM) sufamiturboA.ram.read(stream);
|
||||
if(id == ID::SufamiTurboSlotBRAM) sufamiturboB.ram.read(stream);
|
||||
}
|
||||
|
||||
//deprecated
|
||||
auto Interface::save(uint id, const stream& stream) -> void {
|
||||
if(id == ID::RAM) stream.write((uint8_t*)cartridge.ram.data(), cartridge.ram.size());
|
||||
if(id == ID::EventRAM) stream.write((uint8_t*)event.ram.data(), event.ram.size());
|
||||
if(id == ID::SA1IRAM) stream.write((uint8_t*)sa1.iram.data(), sa1.iram.size());
|
||||
if(id == ID::SA1BWRAM) stream.write((uint8_t*)sa1.bwram.data(), sa1.bwram.size());
|
||||
if(id == ID::SuperFXRAM) stream.write((uint8_t*)superfx.ram.data(), superfx.ram.size());
|
||||
|
||||
if(id == ID::ArmDSPRAM) {
|
||||
for(auto n : range(16 * 1024)) stream.write(armdsp.programRAM[n]);
|
||||
}
|
||||
|
||||
if(id == ID::HitachiDSPRAM) stream.write((uint8_t*)hitachidsp.ram.data(), hitachidsp.ram.size());
|
||||
if(id == ID::HitachiDSPDRAM) {
|
||||
for(auto n : range(3072)) stream.writel(hitachidsp.dataRAM[n], 1);
|
||||
}
|
||||
|
||||
if(id == ID::Nec7725DSPRAM) {
|
||||
for(auto n : range( 256)) stream.writel(necdsp.dataRAM[n], 2);
|
||||
}
|
||||
if(id == ID::Nec96050DSPRAM) {
|
||||
for(auto n : range(2048)) stream.writel(necdsp.dataRAM[n], 2);
|
||||
}
|
||||
|
||||
if(id == ID::EpsonRTC) {
|
||||
uint8 data[16] = {0};
|
||||
epsonrtc.save(data);
|
||||
stream.write((uint8_t*)data, sizeof data);
|
||||
}
|
||||
|
||||
if(id == ID::SharpRTC) {
|
||||
uint8 data[16] = {0};
|
||||
sharprtc.save(data);
|
||||
stream.write((uint8_t*)data, sizeof data);
|
||||
}
|
||||
|
||||
if(id == ID::SPC7110RAM) stream.write((uint8_t*)spc7110.ram.data(), spc7110.ram.size());
|
||||
if(id == ID::SDD1RAM) stream.write((uint8_t*)sdd1.ram.data(), sdd1.ram.size());
|
||||
if(id == ID::OBC1RAM) stream.write((uint8_t*)obc1.ram.data(), obc1.ram.size());
|
||||
|
||||
#if defined(SFC_SUPERGAMEBOY)
|
||||
if(id == ID::GameBoyRAM) {
|
||||
GameBoy::interface->save(GameBoy::ID::RAM, stream);
|
||||
}
|
||||
#endif
|
||||
|
||||
if(id == ID::MCCRAM) stream.write((uint8_t*)mcc.ram.data(), mcc.ram.size());
|
||||
|
||||
if(id == ID::SufamiTurboSlotARAM) stream.write((uint8_t*)sufamiturboA.ram.data(), sufamiturboA.ram.size());
|
||||
if(id == ID::SufamiTurboSlotBRAM) stream.write((uint8_t*)sufamiturboB.ram.data(), sufamiturboB.ram.size());
|
||||
}
|
||||
|
||||
auto Interface::unload() -> void {
|
||||
|
@ -459,14 +264,14 @@ auto Interface::run() -> void {
|
|||
}
|
||||
|
||||
auto Interface::rtc() -> bool {
|
||||
if(cartridge.hasEpsonRTC) return true;
|
||||
if(cartridge.hasSharpRTC) return true;
|
||||
if(cartridge.has.EpsonRTC) return true;
|
||||
if(cartridge.has.SharpRTC) return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
auto Interface::rtcsync() -> void {
|
||||
if(cartridge.hasEpsonRTC) epsonrtc.sync();
|
||||
if(cartridge.hasSharpRTC) sharprtc.sync();
|
||||
if(cartridge.has.EpsonRTC) epsonrtc.sync();
|
||||
if(cartridge.has.SharpRTC) sharprtc.sync();
|
||||
}
|
||||
|
||||
auto Interface::serialize() -> serializer {
|
||||
|
@ -482,7 +287,7 @@ auto Interface::cheatSet(const lstring& list) -> void {
|
|||
cheat.reset();
|
||||
|
||||
#if defined(SFC_SUPERGAMEBOY)
|
||||
if(cartridge.hasICD2) {
|
||||
if(cartridge.has.ICD2) {
|
||||
GameBoy::cheat.reset();
|
||||
for(auto& codeset : list) {
|
||||
lstring codes = codeset.split("+");
|
||||
|
|
|
@ -2,85 +2,23 @@ namespace SuperFamicom {
|
|||
|
||||
struct ID {
|
||||
enum : uint {
|
||||
//cartridges (folders)
|
||||
System,
|
||||
SuperFamicom,
|
||||
GameBoy,
|
||||
BSMemory,
|
||||
SufamiTurboSlotA,
|
||||
SufamiTurboSlotB,
|
||||
|
||||
//memory (files)
|
||||
SystemManifest,
|
||||
IPLROM,
|
||||
|
||||
Manifest,
|
||||
ROM,
|
||||
RAM,
|
||||
|
||||
EventROM0,
|
||||
EventROM1,
|
||||
EventROM2,
|
||||
EventROM3,
|
||||
EventRAM,
|
||||
|
||||
SA1ROM,
|
||||
SA1IRAM,
|
||||
SA1BWRAM,
|
||||
|
||||
SuperFXROM,
|
||||
SuperFXRAM,
|
||||
|
||||
ArmDSPPROM,
|
||||
ArmDSPDROM,
|
||||
ArmDSPRAM,
|
||||
|
||||
HitachiDSPROM,
|
||||
HitachiDSPRAM,
|
||||
HitachiDSPDROM,
|
||||
HitachiDSPDRAM,
|
||||
|
||||
Nec7725DSPPROM,
|
||||
Nec7725DSPDROM,
|
||||
Nec7725DSPRAM,
|
||||
|
||||
Nec96050DSPPROM,
|
||||
Nec96050DSPDROM,
|
||||
Nec96050DSPRAM,
|
||||
|
||||
EpsonRTC,
|
||||
SharpRTC,
|
||||
|
||||
SPC7110PROM,
|
||||
SPC7110DROM,
|
||||
SPC7110RAM,
|
||||
|
||||
SDD1ROM,
|
||||
SDD1RAM,
|
||||
|
||||
OBC1RAM,
|
||||
|
||||
MCCROM,
|
||||
MCCRAM,
|
||||
SufamiTurboA,
|
||||
SufamiTurboB,
|
||||
|
||||
//deprecated
|
||||
SuperGameBoyManifest,
|
||||
SuperGameBoyBootROM,
|
||||
|
||||
GameBoyManifest,
|
||||
GameBoyROM,
|
||||
GameBoyRAM,
|
||||
};
|
||||
|
||||
BSMemoryManifest,
|
||||
BSMemoryROM,
|
||||
|
||||
SufamiTurboSlotAManifest,
|
||||
SufamiTurboSlotAROM,
|
||||
SufamiTurboSlotARAM,
|
||||
|
||||
SufamiTurboSlotBManifest,
|
||||
SufamiTurboSlotBROM,
|
||||
SufamiTurboSlotBRAM,
|
||||
|
||||
enum : uint {
|
||||
//device ports (bitmask)
|
||||
ControllerPort1 = 1,
|
||||
ControllerPort2 = 2,
|
||||
|
|
|
@ -24,6 +24,12 @@ auto MappedRAM::reset() -> void {
|
|||
_writeProtect = false;
|
||||
}
|
||||
|
||||
auto MappedRAM::allocate(uint size) -> void {
|
||||
reset();
|
||||
_data = new uint8[_size = size];
|
||||
memory::fill(_data, _size, 0xff);
|
||||
}
|
||||
|
||||
auto MappedRAM::map(uint8* source, uint length) -> void {
|
||||
reset();
|
||||
_data = source;
|
||||
|
|
|
@ -23,6 +23,7 @@ private:
|
|||
|
||||
struct MappedRAM : Memory {
|
||||
inline auto reset() -> void;
|
||||
inline auto allocate(uint) -> void;
|
||||
inline auto map(uint8*, uint) -> void;
|
||||
inline auto copy(const stream& memory) -> void;
|
||||
inline auto read(const stream& memory) -> void;
|
||||
|
|
|
@ -24,6 +24,12 @@ namespace SuperFamicom {
|
|||
#endif
|
||||
|
||||
namespace SuperFamicom {
|
||||
struct File {
|
||||
static const vfs::file::mode Read = vfs::file::mode::read;
|
||||
static const vfs::file::mode Write = vfs::file::mode::write;
|
||||
static const bool Required = true;
|
||||
};
|
||||
|
||||
struct Thread {
|
||||
virtual ~Thread() {
|
||||
if(thread) co_delete(thread);
|
||||
|
|
|
@ -50,22 +50,22 @@ auto System::serializeAll(serializer& s) -> void {
|
|||
ppu.serialize(s);
|
||||
dsp.serialize(s);
|
||||
|
||||
if(cartridge.hasICD2) icd2.serialize(s);
|
||||
if(cartridge.hasMCC) mcc.serialize(s);
|
||||
if(cartridge.hasEvent) event.serialize(s);
|
||||
if(cartridge.hasSA1) sa1.serialize(s);
|
||||
if(cartridge.hasSuperFX) superfx.serialize(s);
|
||||
if(cartridge.hasARMDSP) armdsp.serialize(s);
|
||||
if(cartridge.hasHitachiDSP) hitachidsp.serialize(s);
|
||||
if(cartridge.hasNECDSP) necdsp.serialize(s);
|
||||
if(cartridge.hasEpsonRTC) epsonrtc.serialize(s);
|
||||
if(cartridge.hasSharpRTC) sharprtc.serialize(s);
|
||||
if(cartridge.hasSPC7110) spc7110.serialize(s);
|
||||
if(cartridge.hasSDD1) sdd1.serialize(s);
|
||||
if(cartridge.hasOBC1) obc1.serialize(s);
|
||||
if(cartridge.hasMSU1) msu1.serialize(s);
|
||||
if(cartridge.has.ICD2) icd2.serialize(s);
|
||||
if(cartridge.has.MCC) mcc.serialize(s);
|
||||
if(cartridge.has.Event) event.serialize(s);
|
||||
if(cartridge.has.SA1) sa1.serialize(s);
|
||||
if(cartridge.has.SuperFX) superfx.serialize(s);
|
||||
if(cartridge.has.ARMDSP) armdsp.serialize(s);
|
||||
if(cartridge.has.HitachiDSP) hitachidsp.serialize(s);
|
||||
if(cartridge.has.NECDSP) necdsp.serialize(s);
|
||||
if(cartridge.has.EpsonRTC) epsonrtc.serialize(s);
|
||||
if(cartridge.has.SharpRTC) sharprtc.serialize(s);
|
||||
if(cartridge.has.SPC7110) spc7110.serialize(s);
|
||||
if(cartridge.has.SDD1) sdd1.serialize(s);
|
||||
if(cartridge.has.OBC1) obc1.serialize(s);
|
||||
if(cartridge.has.MSU1) msu1.serialize(s);
|
||||
|
||||
if(cartridge.hasSufamiTurboSlots) sufamiturboA.serialize(s), sufamiturboB.serialize(s);
|
||||
if(cartridge.has.SufamiTurboSlots) sufamiturboA.serialize(s), sufamiturboB.serialize(s);
|
||||
}
|
||||
|
||||
//perform dry-run state save:
|
||||
|
|
|
@ -51,14 +51,19 @@ auto System::init() -> void {
|
|||
auto System::term() -> void {
|
||||
}
|
||||
|
||||
auto System::load() -> void {
|
||||
auto System::load() -> bool {
|
||||
bus.reset();
|
||||
|
||||
interface->loadRequest(ID::SystemManifest, "manifest.bml", true);
|
||||
if(auto fp = interface->open(ID::System, "manifest.bml", File::Read, File::Required)) {
|
||||
information.manifest = fp->reads();
|
||||
} else return false;
|
||||
|
||||
auto document = BML::unserialize(information.manifest);
|
||||
|
||||
if(auto iplrom = document["system/smp/rom/name"].text()) {
|
||||
interface->loadRequest(ID::IPLROM, iplrom, true);
|
||||
if(auto fp = interface->open(ID::System, iplrom, File::Read, File::Required)) {
|
||||
fp->read(smp.iplrom, 64);
|
||||
} else return false;
|
||||
}
|
||||
|
||||
cartridge.load();
|
||||
|
@ -66,51 +71,56 @@ auto System::load() -> void {
|
|||
_cpuFrequency = region() == Region::NTSC ? 21'477'272 : 21'281'370;
|
||||
_apuFrequency = 24'606'720;
|
||||
|
||||
if(cartridge.hasICD2) icd2.load();
|
||||
if(cartridge.hasMCC) mcc.load();
|
||||
if(cartridge.hasNSSDIP) nss.load();
|
||||
if(cartridge.hasEvent) event.load();
|
||||
if(cartridge.hasSA1) sa1.load();
|
||||
if(cartridge.hasSuperFX) superfx.load();
|
||||
if(cartridge.hasARMDSP) armdsp.load();
|
||||
if(cartridge.hasHitachiDSP) hitachidsp.load();
|
||||
if(cartridge.hasNECDSP) necdsp.load();
|
||||
if(cartridge.hasEpsonRTC) epsonrtc.load();
|
||||
if(cartridge.hasSharpRTC) sharprtc.load();
|
||||
if(cartridge.hasSPC7110) spc7110.load();
|
||||
if(cartridge.hasSDD1) sdd1.load();
|
||||
if(cartridge.hasOBC1) obc1.load();
|
||||
if(cartridge.hasMSU1) msu1.load();
|
||||
if(cartridge.has.ICD2) icd2.load();
|
||||
if(cartridge.has.MCC) mcc.load();
|
||||
if(cartridge.has.NSSDIP) nss.load();
|
||||
if(cartridge.has.Event) event.load();
|
||||
if(cartridge.has.SA1) sa1.load();
|
||||
if(cartridge.has.SuperFX) superfx.load();
|
||||
if(cartridge.has.ARMDSP) armdsp.load();
|
||||
if(cartridge.has.HitachiDSP) hitachidsp.load();
|
||||
if(cartridge.has.NECDSP) necdsp.load();
|
||||
if(cartridge.has.EpsonRTC) epsonrtc.load();
|
||||
if(cartridge.has.SharpRTC) sharprtc.load();
|
||||
if(cartridge.has.SPC7110) spc7110.load();
|
||||
if(cartridge.has.SDD1) sdd1.load();
|
||||
if(cartridge.has.OBC1) obc1.load();
|
||||
if(cartridge.has.MSU1) msu1.load();
|
||||
|
||||
if(cartridge.hasBSMemorySlot) bsmemory.load();
|
||||
if(cartridge.hasSufamiTurboSlots) sufamiturboA.load(), sufamiturboB.load();
|
||||
if(cartridge.has.BSMemorySlot) bsmemory.load();
|
||||
if(cartridge.has.SufamiTurboSlots) sufamiturboA.load(), sufamiturboB.load();
|
||||
|
||||
serializeInit();
|
||||
_loaded = true;
|
||||
return _loaded = true;
|
||||
}
|
||||
|
||||
auto System::save() -> void {
|
||||
if(!loaded()) return;
|
||||
cartridge.save();
|
||||
}
|
||||
|
||||
auto System::unload() -> void {
|
||||
if(!loaded()) return;
|
||||
peripherals.unload();
|
||||
|
||||
if(cartridge.hasICD2) icd2.unload();
|
||||
if(cartridge.hasMCC) mcc.unload();
|
||||
if(cartridge.hasNSSDIP) nss.unload();
|
||||
if(cartridge.hasEvent) event.unload();
|
||||
if(cartridge.hasSA1) sa1.unload();
|
||||
if(cartridge.hasSuperFX) superfx.unload();
|
||||
if(cartridge.hasARMDSP) armdsp.unload();
|
||||
if(cartridge.hasHitachiDSP) hitachidsp.unload();
|
||||
if(cartridge.hasNECDSP) necdsp.unload();
|
||||
if(cartridge.hasEpsonRTC) epsonrtc.unload();
|
||||
if(cartridge.hasSharpRTC) sharprtc.unload();
|
||||
if(cartridge.hasSPC7110) spc7110.unload();
|
||||
if(cartridge.hasSDD1) sdd1.unload();
|
||||
if(cartridge.hasOBC1) obc1.unload();
|
||||
if(cartridge.hasMSU1) msu1.unload();
|
||||
if(cartridge.has.ICD2) icd2.unload();
|
||||
if(cartridge.has.MCC) mcc.unload();
|
||||
if(cartridge.has.NSSDIP) nss.unload();
|
||||
if(cartridge.has.Event) event.unload();
|
||||
if(cartridge.has.SA1) sa1.unload();
|
||||
if(cartridge.has.SuperFX) superfx.unload();
|
||||
if(cartridge.has.ARMDSP) armdsp.unload();
|
||||
if(cartridge.has.HitachiDSP) hitachidsp.unload();
|
||||
if(cartridge.has.NECDSP) necdsp.unload();
|
||||
if(cartridge.has.EpsonRTC) epsonrtc.unload();
|
||||
if(cartridge.has.SharpRTC) sharprtc.unload();
|
||||
if(cartridge.has.SPC7110) spc7110.unload();
|
||||
if(cartridge.has.SDD1) sdd1.unload();
|
||||
if(cartridge.has.OBC1) obc1.unload();
|
||||
if(cartridge.has.MSU1) msu1.unload();
|
||||
|
||||
if(cartridge.hasBSMemorySlot) bsmemory.unload();
|
||||
if(cartridge.hasSufamiTurboSlots) sufamiturboA.unload(), sufamiturboB.unload();
|
||||
if(cartridge.has.BSMemorySlot) bsmemory.unload();
|
||||
if(cartridge.has.SufamiTurboSlots) sufamiturboA.unload(), sufamiturboB.unload();
|
||||
|
||||
cartridge.unload();
|
||||
_loaded = false;
|
||||
|
@ -124,23 +134,23 @@ auto System::power() -> void {
|
|||
dsp.power();
|
||||
ppu.power();
|
||||
|
||||
if(cartridge.hasICD2) icd2.power();
|
||||
if(cartridge.hasMCC) mcc.power();
|
||||
if(cartridge.hasNSSDIP) nss.power();
|
||||
if(cartridge.hasEvent) event.power();
|
||||
if(cartridge.hasSA1) sa1.power();
|
||||
if(cartridge.hasSuperFX) superfx.power();
|
||||
if(cartridge.hasARMDSP) armdsp.power();
|
||||
if(cartridge.hasHitachiDSP) hitachidsp.power();
|
||||
if(cartridge.hasNECDSP) necdsp.power();
|
||||
if(cartridge.hasEpsonRTC) epsonrtc.power();
|
||||
if(cartridge.hasSharpRTC) sharprtc.power();
|
||||
if(cartridge.hasSPC7110) spc7110.power();
|
||||
if(cartridge.hasSDD1) sdd1.power();
|
||||
if(cartridge.hasOBC1) obc1.power();
|
||||
if(cartridge.hasMSU1) msu1.power();
|
||||
if(cartridge.has.ICD2) icd2.power();
|
||||
if(cartridge.has.MCC) mcc.power();
|
||||
if(cartridge.has.NSSDIP) nss.power();
|
||||
if(cartridge.has.Event) event.power();
|
||||
if(cartridge.has.SA1) sa1.power();
|
||||
if(cartridge.has.SuperFX) superfx.power();
|
||||
if(cartridge.has.ARMDSP) armdsp.power();
|
||||
if(cartridge.has.HitachiDSP) hitachidsp.power();
|
||||
if(cartridge.has.NECDSP) necdsp.power();
|
||||
if(cartridge.has.EpsonRTC) epsonrtc.power();
|
||||
if(cartridge.has.SharpRTC) sharprtc.power();
|
||||
if(cartridge.has.SPC7110) spc7110.power();
|
||||
if(cartridge.has.SDD1) sdd1.power();
|
||||
if(cartridge.has.OBC1) obc1.power();
|
||||
if(cartridge.has.MSU1) msu1.power();
|
||||
|
||||
if(cartridge.hasBSMemorySlot) bsmemory.power();
|
||||
if(cartridge.has.BSMemorySlot) bsmemory.power();
|
||||
|
||||
reset();
|
||||
}
|
||||
|
@ -159,35 +169,35 @@ auto System::reset() -> void {
|
|||
dsp.reset();
|
||||
ppu.reset();
|
||||
|
||||
if(cartridge.hasICD2) icd2.reset();
|
||||
if(cartridge.hasMCC) mcc.reset();
|
||||
if(cartridge.hasNSSDIP) nss.reset();
|
||||
if(cartridge.hasEvent) event.reset();
|
||||
if(cartridge.hasSA1) sa1.reset();
|
||||
if(cartridge.hasSuperFX) superfx.reset();
|
||||
if(cartridge.hasARMDSP) armdsp.reset();
|
||||
if(cartridge.hasHitachiDSP) hitachidsp.reset();
|
||||
if(cartridge.hasNECDSP) necdsp.reset();
|
||||
if(cartridge.hasEpsonRTC) epsonrtc.reset();
|
||||
if(cartridge.hasSharpRTC) sharprtc.reset();
|
||||
if(cartridge.hasSPC7110) spc7110.reset();
|
||||
if(cartridge.hasSDD1) sdd1.reset();
|
||||
if(cartridge.hasOBC1) obc1.reset();
|
||||
if(cartridge.hasMSU1) msu1.reset();
|
||||
if(cartridge.has.ICD2) icd2.reset();
|
||||
if(cartridge.has.MCC) mcc.reset();
|
||||
if(cartridge.has.NSSDIP) nss.reset();
|
||||
if(cartridge.has.Event) event.reset();
|
||||
if(cartridge.has.SA1) sa1.reset();
|
||||
if(cartridge.has.SuperFX) superfx.reset();
|
||||
if(cartridge.has.ARMDSP) armdsp.reset();
|
||||
if(cartridge.has.HitachiDSP) hitachidsp.reset();
|
||||
if(cartridge.has.NECDSP) necdsp.reset();
|
||||
if(cartridge.has.EpsonRTC) epsonrtc.reset();
|
||||
if(cartridge.has.SharpRTC) sharprtc.reset();
|
||||
if(cartridge.has.SPC7110) spc7110.reset();
|
||||
if(cartridge.has.SDD1) sdd1.reset();
|
||||
if(cartridge.has.OBC1) obc1.reset();
|
||||
if(cartridge.has.MSU1) msu1.reset();
|
||||
|
||||
if(cartridge.hasBSMemorySlot) bsmemory.reset();
|
||||
if(cartridge.has.BSMemorySlot) bsmemory.reset();
|
||||
|
||||
if(cartridge.hasICD2) cpu.coprocessors.append(&icd2);
|
||||
if(cartridge.hasEvent) cpu.coprocessors.append(&event);
|
||||
if(cartridge.hasSA1) cpu.coprocessors.append(&sa1);
|
||||
if(cartridge.hasSuperFX) cpu.coprocessors.append(&superfx);
|
||||
if(cartridge.hasARMDSP) cpu.coprocessors.append(&armdsp);
|
||||
if(cartridge.hasHitachiDSP) cpu.coprocessors.append(&hitachidsp);
|
||||
if(cartridge.hasNECDSP) cpu.coprocessors.append(&necdsp);
|
||||
if(cartridge.hasEpsonRTC) cpu.coprocessors.append(&epsonrtc);
|
||||
if(cartridge.hasSharpRTC) cpu.coprocessors.append(&sharprtc);
|
||||
if(cartridge.hasSPC7110) cpu.coprocessors.append(&spc7110);
|
||||
if(cartridge.hasMSU1) cpu.coprocessors.append(&msu1);
|
||||
if(cartridge.has.ICD2) cpu.coprocessors.append(&icd2);
|
||||
if(cartridge.has.Event) cpu.coprocessors.append(&event);
|
||||
if(cartridge.has.SA1) cpu.coprocessors.append(&sa1);
|
||||
if(cartridge.has.SuperFX) cpu.coprocessors.append(&superfx);
|
||||
if(cartridge.has.ARMDSP) cpu.coprocessors.append(&armdsp);
|
||||
if(cartridge.has.HitachiDSP) cpu.coprocessors.append(&hitachidsp);
|
||||
if(cartridge.has.NECDSP) cpu.coprocessors.append(&necdsp);
|
||||
if(cartridge.has.EpsonRTC) cpu.coprocessors.append(&epsonrtc);
|
||||
if(cartridge.has.SharpRTC) cpu.coprocessors.append(&sharprtc);
|
||||
if(cartridge.has.SPC7110) cpu.coprocessors.append(&spc7110);
|
||||
if(cartridge.has.MSU1) cpu.coprocessors.append(&msu1);
|
||||
|
||||
scheduler.reset();
|
||||
peripherals.reset();
|
||||
|
|
|
@ -15,7 +15,8 @@ struct System {
|
|||
|
||||
auto init() -> void;
|
||||
auto term() -> void;
|
||||
auto load() -> void;
|
||||
auto load() -> bool;
|
||||
auto save() -> void;
|
||||
auto unload() -> void;
|
||||
auto power() -> void;
|
||||
auto reset() -> void;
|
||||
|
|
|
@ -23,7 +23,8 @@ struct file {
|
|||
return offset() >= size();
|
||||
}
|
||||
|
||||
auto read(uint8_t* data, uintmax bytes) -> void {
|
||||
auto read(void* vdata, uintmax bytes) -> void {
|
||||
auto data = (uint8_t*)vdata;
|
||||
while(bytes--) *data++ = read();
|
||||
}
|
||||
|
||||
|
@ -39,12 +40,15 @@ struct file {
|
|||
return data;
|
||||
}
|
||||
|
||||
auto reads(string& s) -> void {
|
||||
auto reads() -> string {
|
||||
string s;
|
||||
s.resize(size());
|
||||
read(s.get<uint8_t>(), s.size());
|
||||
return s;
|
||||
}
|
||||
|
||||
auto write(const uint8_t* data, uintmax bytes) -> void {
|
||||
auto write(const void* vdata, uintmax bytes) -> void {
|
||||
auto data = (const uint8_t*)vdata;
|
||||
while(bytes--) write(*data++);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue