Update to v106r19 release.

byuu says:

Changelog:

  - Super Famicom: everything outside of Nintendo Super System, Campus
    Challenge '92 and Powerfest '94 should play
  - Super Famicom: removed RAM from coprocessor/event (should use global
    RAM)
  - Super Famicom: removed RAM from SDD1 (should use global RAM)
  - icarus: fixed Super Famicom game importing [hex_usr]

Also worth reminding that you'll need to disable database lookup in
order to run the BS-X Town cartridge right now. Plus, Star Ocean's
database entry still has the RAM in the wrong spot. The MSU1 code is not
looking at the right locations for data, so it's not going to work in
this release either.

I need to figure out what to call coprocessor/event and coprocessor/nss,
as neither are slots or processors like everything else.

Outside of those issues, all games for all systems should be playable,
at least to the extent they were in v106.
This commit is contained in:
Tim Allen 2018-05-13 23:00:48 +10:00
parent b7dca2f317
commit 6847058210
12 changed files with 285 additions and 176 deletions

View File

@ -12,7 +12,7 @@ using namespace nall;
namespace Emulator {
static const string Name = "higan";
static const string Version = "106.18";
static const string Version = "106.19";
static const string Author = "byuu";
static const string License = "GPLv3";
static const string Website = "https://byuu.org/";

View File

@ -68,7 +68,6 @@ private:
auto loadRAM(Markup::Node) -> void;
auto loadICD(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;
@ -76,7 +75,8 @@ private:
auto loadSuperFX(Markup::Node) -> void;
auto loadARMDSP(Markup::Node) -> void;
auto loadHitachiDSP(Markup::Node, uint roms) -> void;
auto loadNECDSP(Markup::Node) -> void;
auto loaduPD7725(Markup::Node) -> void;
auto loaduPD96050(Markup::Node) -> void;
auto loadEpsonRTC(Markup::Node) -> void;
auto loadSharpRTC(Markup::Node) -> void;
auto loadSPC7110(Markup::Node) -> void;
@ -97,16 +97,15 @@ private:
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 saveuPD7725(Markup::Node) -> void;
auto saveuPD96050(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, maybe<uint> = nothing) -> void;

View File

@ -45,14 +45,17 @@ auto Cartridge::loadCartridge(Markup::Node node) -> void {
}
}
if(board["bsmemory"] || board["mcc/bsmemory"] || board["sa1/bsmemory"]) {
if(board["slot(type=BSMemory)"]
|| board["processor(identifier=MCC)/mcu/slot(type=BSMemory)"]
|| board["processor(architecture=W65C816S)/mcu/slot(type=BSMemory)"]
) {
if(auto loaded = platform->load(ID::BSMemory, "BS Memory", "bs")) {
bsmemory.pathID = loaded.pathID();
loadBSMemory();
}
}
if(board["sufamiturbo"]) {
if(board["slot(type=SufamiTurbo)"]) {
if(auto loaded = platform->load(ID::SufamiTurboA, "Sufami Turbo", "st")) {
sufamiturboA.pathID = loaded.pathID();
loadSufamiTurboA();
@ -61,42 +64,55 @@ auto Cartridge::loadCartridge(Markup::Node node) -> void {
if(auto node = board["memory(type=ROM,content=Program)"]) loadROM(node);
if(auto node = board["memory(type=RAM,content=Save)"]) loadRAM(node);
if(auto node = board["icd"]) loadICD(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["processor(identifier=ICD)"]) loadICD(node);
if(auto node = board["processor(identifier=MCC)"]) loadMCC(node);
if(auto node = board.find("slot(type=SufamiTurbo)")) if(node(0)) loadSufamiTurbo(node(0), 0);
if(auto node = board.find("slot(type=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["processor(architecture=W65C816S)"]) loadSA1(node);
if(auto node = board["processor(architecture=GSU)"]) loadSuperFX(node);
if(auto node = board["armdsp"]) loadARMDSP(node);
if(auto node = board["processor(architecture=ARM6)"]) loadARMDSP(node);
if(auto node = board["processor(architecture=HG51BS169)"]) loadHitachiDSP(node, game.board.match("2DC*") ? 2 : 1);
if(auto node = board["necdsp"]) loadNECDSP(node);
if(auto node = board["processor(architecture=uPD7725)"]) loaduPD7725(node);
if(auto node = board["processor(architecture=uPD96050)"]) loaduPD96050(node);
if(auto node = board["rtc(manufacturer=Epson)"]) loadEpsonRTC(node);
if(auto node = board["rtc(manufacturer=Sharp)"]) loadSharpRTC(node);
if(auto node = board["processor(identifier=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(auto node = board["processor(identifier=SDD1)"]) loadSDD1(node);
if(auto node = board["processor(identifier=OBC1)"]) loadOBC1(node);
if(auto node = board["processor(identifier=MSU1)"]) loadMSU1(node);
}
auto Cartridge::loadGameBoy(Markup::Node node) -> void {
}
auto Cartridge::loadBSMemory(Markup::Node node) -> void {
if(node["game/board/memory/type"].text() == "ROM") {
has.BSMemorySlot = true;
if(auto memory = node["game/board/memory(type=ROM)"]) {
bsmemory.readonly = true;
loadMemory(bsmemory.memory, node["game/board/memory(type=ROM)"], File::Required, bsmemory.pathID);
} else {
loadMemory(bsmemory.memory, memory, File::Required, bsmemory.pathID);
} else if(auto memory = node["game/board/memory(type=Flash)"]) {
bsmemory.readonly = false;
loadMemory(bsmemory.memory, node["game/board/memory(type=Flash)"], File::Required, bsmemory.pathID);
loadMemory(bsmemory.memory, memory, File::Required, bsmemory.pathID);
}
for(auto map : node.find("map")) {
if(bsmemory.memory.size()) {
loadMap(map, bsmemory);
}
}
}
auto Cartridge::loadSufamiTurboA(Markup::Node node) -> void {
loadMemory(sufamiturboA.rom, node["game/board/memory(type=ROM)"], File::Required, sufamiturboA.pathID);
loadMemory(sufamiturboA.ram, node["game/board/memory(type=RAM)"], File::Optional, sufamiturboA.pathID);
if(auto memory = node["game/board/memory(type=ROM)"]) {
loadMemory(sufamiturboA.rom, memory, File::Required, sufamiturboA.pathID);
}
if(auto memory = node["game/board/memory(type=RAM)"]) {
loadMemory(sufamiturboA.ram, memory, File::Optional, sufamiturboA.pathID);
}
if(auto loaded = platform->load(ID::SufamiTurboB, "Sufami Turbo", "st")) {
sufamiturboB.pathID = loaded.pathID();
@ -105,67 +121,86 @@ auto Cartridge::loadSufamiTurboA(Markup::Node node) -> void {
}
auto Cartridge::loadSufamiTurboB(Markup::Node node) -> void {
loadMemory(sufamiturboB.rom, node["game/board/memory(type=ROM)"], File::Required, sufamiturboB.pathID);
loadMemory(sufamiturboB.ram, node["game/board/memory(type=RAM)"], File::Optional, sufamiturboB.pathID);
if(auto memory = node["game/board/memory(type=ROM)"]) {
loadMemory(sufamiturboB.rom, memory, File::Required, sufamiturboB.pathID);
}
if(auto memory = node["game/board/memory(type=RAM)"]) {
loadMemory(sufamiturboB.ram, memory, File::Optional, sufamiturboB.pathID);
}
}
//
//memory(type=ROM,content=Program)
auto Cartridge::loadROM(Markup::Node node) -> void {
loadMemory(rom, node, File::Required);
for(auto leaf : node.find("map")) loadMap(leaf, rom);
}
//memory(type=RAM,content=Save)
auto Cartridge::loadRAM(Markup::Node node) -> void {
loadMemory(ram, node, File::Optional);
for(auto leaf : node.find("map")) loadMap(leaf, ram);
}
//processor(identifier=ICD)
auto Cartridge::loadICD(Markup::Node node) -> void {
has.GameBoySlot = true;
has.ICD = true;
icd.Revision = node["revision"].natural();
icd.Frequency = node["frequency"].natural();
if(auto oscillator = game.oscillator()) {
icd.Frequency = oscillator->frequency;
} else {
icd.Frequency = 0;
}
//Game Boy core loads data through ICD interface
for(auto leaf : node.find("map")) loadMap(leaf, {&ICD::readIO, &icd}, {&ICD::writeIO, &icd});
}
auto Cartridge::loadMCC(Markup::Node node) -> void {
has.BSMemorySlot = true;
has.MCC = true;
loadMemory(mcc.rom, node["rom"], File::Required);
loadMemory(mcc.ram, node["ram"], File::Optional);
for(auto leaf : node.find("map")) leaf.text() == "mcu"
? loadMap(leaf, {&MCC::mcuRead, &mcc}, {&MCC::mcuWrite, &mcc})
: loadMap(leaf, {&MCC::read, &mcc}, {&MCC::write, &mcc});
for(auto leaf : node["ram"].find("map")) loadMap(leaf, mcc.ram);
}
auto Cartridge::loadBSMemoryPack(Markup::Node node) -> void {
has.BSMemorySlot = true;
for(auto leaf : node.find("map")) {
if(bsmemory.memory.size() == 0) continue;
loadMap(leaf, bsmemory);
for(auto map : node.find("map")) {
loadMap(map, {&ICD::readIO, &icd}, {&ICD::writeIO, &icd});
}
}
//processor(identifier=MCC)
auto Cartridge::loadMCC(Markup::Node node) -> void {
has.MCC = true;
for(auto map : node.find("map")) {
loadMap(map, {&MCC::read, &mcc}, {&MCC::write, &mcc});
}
if(auto mcu = node["mcu"]) {
for(auto map : mcu.find("map")) {
loadMap(map, {&MCC::mcuRead, &mcc}, {&MCC::mcuWrite, &mcc});
}
if(auto memory = mcu["memory(type=ROM,content=Program)"]) {
loadMemory(mcc.rom, memory, File::Required);
}
}
if(auto memory = node["memory(type=RAM,content=Download)"]) {
loadMemory(mcc.ram, memory, File::Optional);
for(auto map : memory.find("map")) {
loadMap(map, mcc.ram);
}
}
}
//slot(type=SufamiTurbo)[0,1]
auto Cartridge::loadSufamiTurbo(Markup::Node node, bool slot) -> void {
has.SufamiTurboSlots = true;
for(auto leaf : node["rom"].find("map")) {
auto& cart = (slot == 0 ? sufamiturboA : sufamiturboB);
if(cart.rom.size() == 0) continue;
loadMap(leaf, cart.rom);
for(auto map : node.find("rom/map")) {
auto& cartridge = slot == 0 ? sufamiturboA : sufamiturboB;
if(cartridge.rom.size() == 0) continue;
loadMap(map, cartridge.rom);
}
for(auto leaf : node["ram"].find("map")) {
auto& cart = (slot == 0 ? sufamiturboA : sufamiturboB);
if(cart.ram.size() == 0) continue;
loadMap(leaf, cart.ram);
for(auto map : node.find("ram/map")) {
auto& cartridge = slot == 0 ? sufamiturboA : sufamiturboB;
if(cartridge.ram.size() == 0) continue;
loadMap(map, cartridge.ram);
}
}
@ -183,7 +218,6 @@ auto Cartridge::loadEvent(Markup::Node node) -> void {
has.Event = true;
for(uint n : range(4)) loadMemory(event.rom[n], roms[n], File::Required);
loadMemory(event.ram, node["ram"], File::Optional);
event.board = Event::Board::CampusChallenge92;
if(node.text() == "CC92") event.board = Event::Board::CampusChallenge92;
@ -193,7 +227,6 @@ auto Cartridge::loadEvent(Markup::Node node) -> void {
for(auto leaf : node.find("map")) leaf.text() == "mcu"
? loadMap(leaf, {&Event::mcuRead, &event}, {&Event::mcuWrite, &event})
: loadMap(leaf, {&Event::read, &event}, {&Event::write, &event});
for(auto leaf : node["ram"].find("map")) loadMap(leaf, event.ram);
}
//processor(architecture=W65C816S)
@ -251,32 +284,47 @@ auto Cartridge::loadSuperFX(Markup::Node node) -> void {
}
}
//processor(architecture=ARM6)
auto Cartridge::loadARMDSP(Markup::Node node) -> void {
has.ARMDSP = true;
for(auto& word : armdsp.programROM) word = 0x00;
for(auto& word : armdsp.dataROM) word = 0x00;
for(auto& word : armdsp.programRAM) word = 0x00;
if(auto oscillator = game.oscillator()) {
armdsp.Frequency = oscillator->frequency;
} else {
armdsp.Frequency = 21'440'000;
}
if(auto memory = game.memory(node["memory(type=ROM,content=Program)"])) {
if(auto fp = platform->open(ID::SuperFamicom, memory->name(), File::Read, File::Required)) {
for(auto n : range(128 * 1024)) armdsp.programROM[n] = fp->read();
}
for(auto map : node.find("map")) {
loadMap(map, {&ArmDSP::read, &armdsp}, {&ArmDSP::write, &armdsp});
}
if(auto memory = game.memory(node["memory(type=ROM,content=Data)"])) {
if(auto fp = platform->open(ID::SuperFamicom, memory->name(), File::Read, File::Required)) {
for(auto n : range( 32 * 1024)) armdsp.dataROM[n] = fp->read();
}
}
if(auto memory = game.memory(node["memory(type=RAM,content=Data)"])) {
if(auto fp = platform->open(ID::SuperFamicom, memory->name(), File::Read)) {
for(auto n : range( 16 * 1024)) armdsp.programRAM[n] = fp->read();
if(auto memory = node["memory(type=ROM,content=Program,architecture=ARM6)"]) {
if(auto file = game.memory(memory)) {
if(auto fp = platform->open(ID::SuperFamicom, file->name(), File::Read, File::Required)) {
for(auto n : range(128 * 1024)) armdsp.programROM[n] = fp->read();
}
}
}
for(auto leaf : node.find("map")) loadMap(leaf, {&ArmDSP::read, &armdsp}, {&ArmDSP::write, &armdsp});
if(auto memory = node["memory(type=ROM,content=Data,architecture=ARM6)"]) {
if(auto file = game.memory(memory)) {
if(auto fp = platform->open(ID::SuperFamicom, file->name(), File::Read, File::Required)) {
for(auto n : range(32 * 1024)) armdsp.dataROM[n] = fp->read();
}
}
}
if(auto memory = node["memory(type=RAM,content=Data,architecture=ARM6)"]) {
if(auto file = game.memory(memory)) {
if(auto fp = platform->open(ID::SuperFamicom, file->name(), File::Read)) {
for(auto n : range(16 * 1024)) armdsp.programRAM[n] = fp->read();
}
}
}
}
//processor(architecture=HG51BS169)
@ -331,8 +379,14 @@ auto Cartridge::loadHitachiDSP(Markup::Node node, uint roms) -> void {
}
}
auto Cartridge::loadNECDSP(Markup::Node node) -> void {
//processor(architecture=uPD7725)
auto Cartridge::loaduPD7725(Markup::Node node) -> void {
has.NECDSP = true;
necdsp.revision = 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(auto oscillator = game.oscillator()) {
necdsp.Frequency = oscillator->frequency;
@ -340,37 +394,83 @@ auto Cartridge::loadNECDSP(Markup::Node node) -> void {
necdsp.Frequency = 7'600'000;
}
necdsp.revision
= node["model"].text() == "uPD7725" ? NECDSP::Revision::uPD7725
: node["model"].text() == "uPD96050" ? NECDSP::Revision::uPD96050
: NECDSP::Revision::uPD7725;
for(auto map : node.find("map")) {
loadMap(map, {&NECDSP::read, &necdsp}, {&NECDSP::write, &necdsp});
}
if(auto memory = node["memory(type=ROM,content=Program,architecture=uPD7725)"]) {
if(auto file = game.memory(memory)) {
if(auto fp = platform->open(ID::SuperFamicom, file->name(), File::Read, File::Required)) {
for(auto n : range(2048)) necdsp.programROM[n] = fp->readl(3);
}
}
}
if(auto memory = node["memory(type=ROM,content=Data,architecture=uPD7725)"]) {
if(auto file = game.memory(memory)) {
if(auto fp = platform->open(ID::SuperFamicom, file->name(), File::Read, File::Required)) {
for(auto n : range(1024)) necdsp.dataROM[n] = fp->readl(2);
}
}
}
if(auto memory = node["memory(type=RAM,content=Data,architecture=uPD7725)"]) {
if(auto file = game.memory(memory)) {
if(auto fp = platform->open(ID::SuperFamicom, file->name(), File::Read)) {
for(auto n : range(256)) necdsp.dataRAM[n] = fp->readl(2);
}
}
for(auto map : memory.find("map")) {
loadMap(map, {&NECDSP::readRAM, &necdsp}, {&NECDSP::writeRAM, &necdsp});
}
}
}
//processor(architecture=uPD96050)
auto Cartridge::loaduPD96050(Markup::Node node) -> void {
has.NECDSP = true;
necdsp.revision = NECDSP::Revision::uPD96050;
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 oscillator = game.oscillator()) {
necdsp.Frequency = oscillator->frequency;
} else {
necdsp.Frequency = 11'000'000;
}
if(auto memory = game.memory(node["memory(type=ROM,content=Program)"])) {
if(auto fp = platform->open(ID::SuperFamicom, memory->name(), File::Read, File::Required)) {
for(auto n : range(size[0])) necdsp.programROM[n] = fp->readl(3);
}
for(auto map : node.find("map")) {
loadMap(map, {&NECDSP::read, &necdsp}, {&NECDSP::write, &necdsp});
}
if(auto memory = Emulator::Game::Memory{node["memory(type=ROM,content=Data)"]}) {
if(auto fp = platform->open(ID::SuperFamicom, memory.name(), File::Read, File::Required)) {
for(auto n : range(size[1])) necdsp.dataROM[n] = fp->readl(2);
}
}
if(auto memory = Emulator::Game::Memory{node["memory(type=RAM,content=Data)"]}) {
if(auto fp = platform->open(ID::SuperFamicom, memory.name(), File::Read)) {
for(auto n : range(size[2])) necdsp.dataRAM[n] = fp->readl(2);
if(auto memory = node["memory(type=ROM,content=Program,architecture=uPD96050)"]) {
if(auto file = game.memory(memory)) {
if(auto fp = platform->open(ID::SuperFamicom, file->name(), File::Read, File::Required)) {
for(auto n : range(16384)) necdsp.programROM[n] = fp->readl(3);
}
}
}
for(auto leaf : node.find("map")) loadMap(leaf, {&NECDSP::read, &necdsp}, {&NECDSP::write, &necdsp});
for(auto leaf : node["dram"].find("map")) loadMap(leaf, {&NECDSP::readRAM, &necdsp}, {&NECDSP::writeRAM, &necdsp});
if(auto memory = node["memory(type=ROM,content=Data,architecture=uPD96050)"]) {
if(auto file = game.memory(memory)) {
if(auto fp = platform->open(ID::SuperFamicom, file->name(), File::Read, File::Required)) {
for(auto n : range(2048)) necdsp.dataROM[n] = fp->readl(2);
}
}
}
if(auto memory = node["memory(type=RAM,content=Data,architecture=uPD96050)"]) {
if(auto file = game.memory(memory)) {
if(auto fp = platform->open(ID::SuperFamicom, file->name(), File::Read)) {
for(auto n : range(2048)) necdsp.dataRAM[n] = fp->readl(2);
}
}
for(auto map : memory.find("map")) {
loadMap(map, {&NECDSP::readRAM, &necdsp}, {&NECDSP::writeRAM, &necdsp});
}
}
}
//rtc(manufacturer=Epson)
@ -443,29 +543,44 @@ auto Cartridge::loadSPC7110(Markup::Node node) -> void {
}
}
//processor(identifier=SDD1)
auto Cartridge::loadSDD1(Markup::Node node) -> void {
has.SDD1 = true;
loadMemory(sdd1.rom, node["rom"], File::Required);
loadMemory(sdd1.ram, node["ram"], File::Optional);
for(auto map : node.find("map")) {
loadMap(map, {&SDD1::ioRead, &sdd1}, {&SDD1::ioWrite, &sdd1});
}
for(auto leaf : node.find("map")) loadMap(leaf, {&SDD1::read, &sdd1}, {&SDD1::write, &sdd1});
for(auto leaf : node["rom"].find("map")) loadMap(leaf, {&SDD1::mcuromRead, &sdd1}, {&SDD1::mcuromWrite, &sdd1});
for(auto leaf : node["ram"].find("map")) loadMap(leaf, {&SDD1::mcuramRead, &sdd1}, {&SDD1::mcuramWrite, &sdd1});
if(auto mcu = node["mcu"]) {
for(auto map : mcu.find("map")) {
loadMap(map, {&SDD1::mcuRead, &sdd1}, {&SDD1::mcuWrite, &sdd1});
}
if(auto memory = mcu["memory(type=ROM,content=Program)"]) {
loadMemory(sdd1.rom, memory, File::Required);
}
}
}
//processor(identifier=OBC1)
auto Cartridge::loadOBC1(Markup::Node node) -> void {
has.OBC1 = true;
loadMemory(obc1.ram, node["ram"], File::Optional);
for(auto map : node.find("map")) {
loadMap(map, {&OBC1::read, &obc1}, {&OBC1::write, &obc1});
}
for(auto leaf : node.find("map")) loadMap(leaf, {&OBC1::read, &obc1}, {&OBC1::write, &obc1});
if(auto memory = node["memory(type=RAM,content=Save)"]) {
loadMemory(obc1.ram, memory, File::Optional);
}
}
//processor(identifier=MSU1)
auto Cartridge::loadMSU1(Markup::Node node) -> void {
has.MSU1 = true;
for(auto leaf : node.find("map")) loadMap(leaf, {&MSU1::readIO, &msu1}, {&MSU1::writeIO, &msu1});
for(auto map : node.find("map")) {
loadMap(map, {&MSU1::readIO, &msu1}, {&MSU1::writeIO, &msu1});
}
}
//

View File

@ -1,17 +1,16 @@
auto Cartridge::saveCartridge(Markup::Node node) -> void {
if(auto node = board["memory(type=RAM,content=Save)"]) saveRAM(node);
if(auto node = board["mcc"]) saveMCC(node);
if(auto node = board["event"]) saveEvent(node);
if(auto node = board["processor(identifier=MCC)"]) saveMCC(node);
if(auto node = board["processor(architecture=W65C816S)"]) saveSA1(node);
if(auto node = board["processor(architecture=GSU)"]) saveSuperFX(node);
if(auto node = board["armdsp"]) saveARMDSP(node);
if(auto node = board["processor(architecture=ARM6)"]) saveARMDSP(node);
if(auto node = board["processor(architecture=HG51BS169)"]) saveHitachiDSP(node);
if(auto node = board["necdsp"]) saveNECDSP(node);
if(auto node = board["processor(architecture=uPD7725)"]) saveuPD7725(node);
if(auto node = board["processor(architecture=uPD96050)"]) saveuPD96050(node);
if(auto node = board["rtc(manufacturer=Epson)"]) saveEpsonRTC(node);
if(auto node = board["rtc(manufacturer=Sharp)"]) saveSharpRTC(node);
if(auto node = board["processor(identifier=SPC7110)"]) saveSPC7110(node);
if(auto node = board["sdd1"]) saveSDD1(node);
if(auto node = board["obc1"]) saveOBC1(node);
if(auto node = board["processor(identifier=OBC1)"]) saveOBC1(node);
}
auto Cartridge::saveGameBoy(Markup::Node node) -> void {
@ -30,16 +29,16 @@ auto Cartridge::saveSufamiTurboB(Markup::Node node) -> void {
//
//memory(type=RAM,content=Save)
auto Cartridge::saveRAM(Markup::Node node) -> void {
saveMemory(ram, node);
}
//processor(identifier=MCC)
auto Cartridge::saveMCC(Markup::Node node) -> void {
saveMemory(mcc.ram, node["ram"]);
}
auto Cartridge::saveEvent(Markup::Node node) -> void {
saveMemory(event.ram, node["ram"]);
if(auto memory = node["memory(type=RAM,content=Download)"]) {
saveMemory(mcc.ram, memory);
}
}
//processor(architecture=W65C816S)
@ -60,11 +59,14 @@ auto Cartridge::saveSuperFX(Markup::Node node) -> void {
}
}
//processor(architecture=ARM6)
auto Cartridge::saveARMDSP(Markup::Node node) -> void {
if(auto memory = game.memory(node["memory(type=RAM,content=Data)"])) {
if(memory->nonVolatile) {
if(auto fp = platform->open(ID::SuperFamicom, memory->name(), File::Write)) {
for(auto n : range(16 * 1024)) fp->write(armdsp.programRAM[n]);
if(auto memory = node["memory(type=RAM,content=Data,architecture=ARM6)"]) {
if(auto file = game.memory(memory)) {
if(file->nonVolatile) {
if(auto fp = platform->open(ID::SuperFamicom, file->name(), File::Write)) {
for(auto n : range(16 * 1024)) fp->write(armdsp.programRAM[n]);
}
}
}
}
@ -89,12 +91,27 @@ auto Cartridge::saveHitachiDSP(Markup::Node node) -> void {
}
}
auto Cartridge::saveNECDSP(Markup::Node node) -> void {
uint size = necdsp.revision == NECDSP::Revision::uPD7725 ? 256 : 2048;
if(auto memory = Emulator::Game::Memory{node["memory(type=RAM,content=Data)"]}) {
if(memory.nonVolatile) {
if(auto fp = platform->open(ID::SuperFamicom, memory.name(), File::Write)) {
for(auto n : range(size)) fp->writel(necdsp.dataRAM[n], 2);
//processor(architecture=uPD7725)
auto Cartridge::saveuPD7725(Markup::Node node) -> void {
if(auto memory = node["memory(type=RAM,content=Data,architecture=uPD7725)"]) {
if(auto file = game.memory(memory)) {
if(file->nonVolatile) {
if(auto fp = platform->open(ID::SuperFamicom, file->name(), File::Write)) {
for(auto n : range(256)) fp->writel(necdsp.dataRAM[n], 2);
}
}
}
}
}
//processor(architecture=uPD96050)
auto Cartridge::saveuPD96050(Markup::Node node) -> void {
if(auto memory = node["memory(type=RAM,content=Data,architecture=uPD96050)"]) {
if(auto file = game.memory(memory)) {
if(file->nonVolatile) {
if(auto fp = platform->open(ID::SuperFamicom, file->name(), File::Write)) {
for(auto n : range(2 * 1024)) fp->writel(necdsp.dataRAM[n], 2);
}
}
}
}
@ -137,12 +154,11 @@ auto Cartridge::saveSPC7110(Markup::Node node) -> void {
}
}
auto Cartridge::saveSDD1(Markup::Node node) -> void {
saveMemory(sdd1.ram, node["ram"]);
}
//processor(identifier=OBC1)
auto Cartridge::saveOBC1(Markup::Node node) -> void {
saveMemory(obc1.ram, node["ram"]);
if(auto memory = node["memory(type=RAM,content=Save)"]) {
saveMemory(obc1.ram, memory);
}
}
//

View File

@ -2,6 +2,7 @@
namespace SuperFamicom {
#include "serialization.cpp"
Event event;
auto Event::Enter() -> void {
@ -33,7 +34,6 @@ auto Event::unload() -> void {
rom[1].reset();
rom[2].reset();
rom[3].reset();
ram.reset();
}
auto Event::power() -> void {
@ -43,9 +43,7 @@ auto Event::power() -> void {
rom[1].writeProtect(true);
rom[2].writeProtect(true);
rom[3].writeProtect(true);
ram.writeProtect(false);
for(auto n : range(ram.size())) ram.write(n, 0x00);
status = 0x00;
select = 0x00;
timerActive = false;
@ -110,15 +108,4 @@ auto Event::write(uint24 addr, uint8 data) -> void {
}
}
auto Event::serialize(serializer& s) -> void {
Thread::serialize(s);
s.array(ram.data(), ram.size());
s.integer(status);
s.integer(select);
s.integer(timerActive);
s.integer(scoreActive);
s.integer(timerSecondsRemaining);
s.integer(scoreSecondsRemaining);
}
}

View File

@ -3,6 +3,7 @@
//* Powerfest '94
struct Event : Thread {
//event.cpp
static auto Enter() -> void;
auto main() -> void;
auto unload() -> void;
@ -14,10 +15,10 @@ struct Event : Thread {
auto read(uint24 addr, uint8 data) -> uint8;
auto write(uint24 addr, uint8 data) -> void;
//serialization.cpp
auto serialize(serializer&) -> void;
MappedRAM rom[4];
MappedRAM ram;
enum class Board : uint { CampusChallenge92, Powerfest94 } board;
uint timer;

View File

@ -0,0 +1,9 @@
auto Event::serialize(serializer& s) -> void {
Thread::serialize(s);
s.integer(status);
s.integer(select);
s.integer(timerActive);
s.integer(scoreActive);
s.integer(timerSecondsRemaining);
s.integer(scoreSecondsRemaining);
}

View File

@ -9,12 +9,10 @@ SDD1 sdd1;
auto SDD1::unload() -> void {
rom.reset();
ram.reset();
}
auto SDD1::power() -> void {
rom.writeProtect(true);
ram.writeProtect(false);
//hook S-CPU DMA MMIO registers to gather information for struct dma[];
//buffer address and transfer size information for use in SDD1::mcu_read()
@ -34,7 +32,7 @@ auto SDD1::power() -> void {
dmaReady = false;
}
auto SDD1::read(uint24 addr, uint8 data) -> uint8 {
auto SDD1::ioRead(uint24 addr, uint8 data) -> uint8 {
addr = 0x4800 | addr.bits(0,3);
switch(addr) {
@ -50,7 +48,7 @@ auto SDD1::read(uint24 addr, uint8 data) -> uint8 {
return rom.read(addr);
}
auto SDD1::write(uint24 addr, uint8 data) -> void {
auto SDD1::ioWrite(uint24 addr, uint8 data) -> void {
addr = 0x4800 | addr.bits(0,3);
switch(addr) {
@ -91,7 +89,7 @@ auto SDD1::mmcRead(uint24 addr) -> uint8 {
//map address=00-3f,80-bf:8000-ffff
//map address=c0-ff:0000-ffff
auto SDD1::mcuromRead(uint24 addr, uint8 data) -> uint8 {
auto SDD1::mcuRead(uint24 addr, uint8 data) -> uint8 {
//map address=00-3f,80-bf:8000-ffff
if(!addr.bit(22)) {
if(!addr.bit(23) && addr.bit(21) && r4805.bit(7)) addr.bit(21) = 0; //20-3f:8000-ffff
@ -130,17 +128,7 @@ auto SDD1::mcuromRead(uint24 addr, uint8 data) -> uint8 {
return mmcRead(addr);
}
auto SDD1::mcuromWrite(uint24 addr, uint8 data) -> void {
}
//map address=00-3f,80-bf:6000-7fff mask=0xe000
//map address=70-73:0000-ffff mask=0x8000
auto SDD1::mcuramRead(uint24 addr, uint8 data) -> uint8 {
return ram.read(addr.bits(0,12), data);
}
auto SDD1::mcuramWrite(uint24 addr, uint8 data) -> void {
return ram.write(addr.bits(0,12), data);
auto SDD1::mcuWrite(uint24 addr, uint8 data) -> void {
}
}

View File

@ -2,24 +2,20 @@ struct SDD1 {
auto unload() -> void;
auto power() -> void;
auto read(uint24 addr, uint8 data) -> uint8;
auto write(uint24 addr, uint8 data) -> void;
auto ioRead(uint24 addr, uint8 data) -> uint8;
auto ioWrite(uint24 addr, uint8 data) -> void;
auto dmaRead(uint24 addr, uint8 data) -> uint8;
auto dmaWrite(uint24 addr, uint8 data) -> void;
auto mmcRead(uint24 addr) -> uint8;
auto mcuromRead(uint24 addr, uint8 data) -> uint8;
auto mcuromWrite(uint24 addr, uint8 data) -> void;
auto mcuramRead(uint24 addr, uint8 data) -> uint8;
auto mcuramWrite(uint24 addr, uint8 data) -> void;
auto mcuRead(uint24 addr, uint8 data) -> uint8;
auto mcuWrite(uint24 addr, uint8 data) -> void;
auto serialize(serializer&) -> void;
MappedRAM rom;
MappedRAM ram;
private:
uint8 r4800; //hard enable

View File

@ -1,6 +1,4 @@
auto SDD1::serialize(serializer& s) -> void {
s.array(ram.data(), ram.size());
s.integer(r4800);
s.integer(r4801);
s.integer(r4804);

View File

@ -1,5 +1,5 @@
database
revision: 2018-05-08
revision: 2018-05-12
//Boards (Production)
@ -552,7 +552,7 @@ board: SHVC-YJ0N-01
//Boards (Generic)
database
revision: 2018-05-08
revision: 2018-05-12
board: ARM-LOROM-RAM
memory type=ROM content=Program
@ -797,15 +797,15 @@ board: SDD1
memory type=ROM content=Program
board: SDD1-RAM
memory type=RAM content=Save
map address=00-3f,80-bf:6000-7fff mask=0xe000
map address=70-73:0000-ffff mask=0x8000
processor identifier=SDD1
map address=00-3f,80-bf:4800-480f
mcu
map address=00-3f,80-bf:8000-ffff
map address=c0-ff:0000-ffff
memory type=ROM content=Program
memory type=RAM content=Save
map address=00-3f,80-bf:6000-7fff mask=0xe000
map address=70-73:0000-ffff mask=0x8000
board: SPC7110-RAM
processor identifier=SPC7110

View File

@ -43,10 +43,10 @@ auto Icarus::superFamicomImport(vector<uint8_t>& buffer, string location) -> str
auto document = BML::unserialize(manifest);
for(auto rom : document.find("game/board/memory")) {
if(rom["type"].text() != "ROM") continue;
auto name = string{rom["part"].text(), ".", rom["category"].text(), ".rom"}.trimLeft(".", 1L).downcase();
auto name = string{rom["architecture"].text(), ".", rom["content"].text(), ".rom"}.trimLeft(".", 1L).downcase();
auto size = rom["size"].natural();
if(size > buffer.size() - offset) {
auto name = string{rom["note"].text(), ".", rom["category"].text(), ".rom"}.trimLeft(".", 1L).downcase();
auto name = string{rom["identifier"].text(), ".", rom["content"].text(), ".rom"}.trimLeft(".", 1L).downcase();
auto location = locate({"firmware/", name});
if(location && file::size(location) == size) {
write({target, name}, file::read(location));