mirror of https://github.com/bsnes-emu/bsnes.git
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:
parent
b7dca2f317
commit
6847058210
|
@ -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/";
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 map : node.find("map")) {
|
||||
loadMap(map, {&ArmDSP::read, &armdsp}, {&ArmDSP::write, &armdsp});
|
||||
}
|
||||
|
||||
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();
|
||||
}
|
||||
}
|
||||
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 = 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 = 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();
|
||||
}
|
||||
}
|
||||
|
||||
for(auto leaf : node.find("map")) loadMap(leaf, {&ArmDSP::read, &armdsp}, {&ArmDSP::write, &armdsp});
|
||||
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 = 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);
|
||||
}
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
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});
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
|
|
|
@ -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,14 +59,17 @@ 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)) {
|
||||
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]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//processor(architecture=HG51BS169)
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
}
|
|
@ -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 {
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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));
|
||||
|
|
Loading…
Reference in New Issue