Update to v106r08 release.

byuu says:

Changelog:

  - Game Boy: fixed RAM/RTC saving¹
  - Super Famicom: ICD2 renamed to ICD (there exists an SGB prototype
    with a functionally identical ICD1)
  - Sufami Turbo: removed short-circuiting when loading an unlinkable
    cartridge into slot A²
  - Super Game Boy: the 20971520hz clock of the SGB2 is now emulated
  - Super Famicom: BSC-1Lxx (SA1) boards now prompt for BS memory
    cartridges; and can make use of them³
  - Super Famicom: fixed a potential for out-of-bounds reads with BS
    Memory flash carts

¹: I'm using a gross hack of replacing `type: ` with `type:` so that
`memory(type=...)` will match without the extra spaces. I need to
think about whether I want the BPath query syntax to strip whitespace or
not. But longer term, I want to finalize game/memory's design, and build
a higan/emulation/manifest parser that produces a nicer interface to
reading manifests for all cores, which will make this irrelevant for
higan anyway.

²: I don't think it's appropriate for higan to enforce this. Nothing
stops you from inserting games that can't be linked into a real Sufami
Turbo. I do short-circuit if you cancel the first load, but I may allow
loading an empty slot A with a populated slot B. I think the BIOS does
something when you do that. Probably just yells at you.

³: I know it's emulated correctly now, but I still don't know what
the heck changes when you load the SD Gundam G Next - Unit & Map
Collection BS Memory cartridge with SD Gundam G Next to actually test
it.
This commit is contained in:
Tim Allen 2018-02-21 20:53:49 +11:00
parent c49d3b2006
commit 5c55cc2c94
20 changed files with 179 additions and 86 deletions

View File

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

View File

@ -48,7 +48,8 @@ auto Cartridge::load() -> bool {
information.manifest = fp->reads(); information.manifest = fp->reads();
} else return false; } else return false;
auto document = BML::unserialize(information.manifest); //todo: temporary hack so (type=) node lookup works; replace with a proper game/memory parser
auto document = BML::unserialize(string{information.manifest}.replace("type: ", "type:"));
information.title = document["game/label"].text(); information.title = document["game/label"].text();
auto mapperID = document["game/board"].text(); auto mapperID = document["game/board"].text();
@ -68,7 +69,7 @@ auto Cartridge::load() -> bool {
accelerometer = (bool)document["game/board/accelerometer"]; accelerometer = (bool)document["game/board/accelerometer"];
rumble = (bool)document["game/board/rumble"]; rumble = (bool)document["game/board/rumble"];
if(auto node = document["game/memory[type=ROM]"]) { if(auto node = document["game/memory(type=ROM)"]) {
rom.size = max(0x4000, node["size"].natural()); rom.size = max(0x4000, node["size"].natural());
rom.data = (uint8*)memory::allocate(rom.size, 0xff); rom.data = (uint8*)memory::allocate(rom.size, 0xff);
if(auto name = node["name"].text()) { if(auto name = node["name"].text()) {
@ -78,7 +79,7 @@ auto Cartridge::load() -> bool {
} }
} }
if(auto node = document["game/memory[type=NVRAM]"]) { if(auto node = document["game/memory(type=NVRAM)"]) {
ram.size = node["size"].natural(); ram.size = node["size"].natural();
ram.data = (uint8*)memory::allocate(ram.size, 0xff); ram.data = (uint8*)memory::allocate(ram.size, 0xff);
if(auto name = node["name"].text()) { if(auto name = node["name"].text()) {
@ -88,7 +89,7 @@ auto Cartridge::load() -> bool {
} }
} }
if(auto node = document["game/memory[type=RTC]"]) { if(auto node = document["game/memory(type=RTC)"]) {
rtc.size = node["size"].natural(); rtc.size = node["size"].natural();
rtc.data = (uint8*)memory::allocate(rtc.size, 0xff); rtc.data = (uint8*)memory::allocate(rtc.size, 0xff);
if(auto name = node["name"].text()) { if(auto name = node["name"].text()) {
@ -103,9 +104,9 @@ auto Cartridge::load() -> bool {
} }
auto Cartridge::save() -> void { auto Cartridge::save() -> void {
auto document = BML::unserialize(information.manifest); auto document = BML::unserialize(string{information.manifest}.replace("type: ", "type:"));
if(auto node = document["game/memory[type=NVRAM]"]) { if(auto node = document["game/memory(type=NVRAM)"]) {
if(auto name = node["name"].text()) { if(auto name = node["name"].text()) {
if(auto fp = platform->open(pathID(), name, File::Write)) { if(auto fp = platform->open(pathID(), name, File::Write)) {
fp->write(ram.data, ram.size); fp->write(ram.data, ram.size);
@ -113,7 +114,7 @@ auto Cartridge::save() -> void {
} }
} }
if(auto node = document["game/memory[type=RTC]"]) { if(auto node = document["game/memory(type=RTC)"]) {
if(auto name = node["name"].text()) { if(auto name = node["name"].text()) {
if(auto fp = platform->open(pathID(), name, File::Write)) { if(auto fp = platform->open(pathID(), name, File::Write)) {
fp->write(rtc.data, rtc.size); fp->write(rtc.data, rtc.size);

View File

@ -4,7 +4,7 @@ objects += sfc-interface sfc-system sfc-controller
objects += sfc-cartridge sfc-memory objects += sfc-cartridge sfc-memory
objects += sfc-cpu sfc-smp sfc-dsp sfc-ppu objects += sfc-cpu sfc-smp sfc-dsp sfc-ppu
objects += sfc-expansion sfc-satellaview sfc-21fx objects += sfc-expansion sfc-satellaview sfc-21fx
objects += sfc-icd2 sfc-mcc sfc-nss sfc-event objects += sfc-icd sfc-mcc sfc-nss sfc-event
objects += sfc-sa1 sfc-superfx objects += sfc-sa1 sfc-superfx
objects += sfc-armdsp sfc-hitachidsp sfc-necdsp objects += sfc-armdsp sfc-hitachidsp sfc-necdsp
objects += sfc-epsonrtc sfc-sharprtc objects += sfc-epsonrtc sfc-sharprtc
@ -27,7 +27,7 @@ obj/sfc-expansion.o: sfc/expansion/expansion.cpp $(call rwildcard,sfc/expansio
obj/sfc-satellaview.o: sfc/expansion/satellaview/satellaview.cpp $(call rwildcard,sfc/expansion/satellaview/) obj/sfc-satellaview.o: sfc/expansion/satellaview/satellaview.cpp $(call rwildcard,sfc/expansion/satellaview/)
obj/sfc-21fx.o: sfc/expansion/21fx/21fx.cpp $(call rwildcard,sfc/expansion/21fx/) obj/sfc-21fx.o: sfc/expansion/21fx/21fx.cpp $(call rwildcard,sfc/expansion/21fx/)
obj/sfc-icd2.o: sfc/coprocessor/icd2/icd2.cpp $(call rwildcard,sfc/coprocessor/icd2/) obj/sfc-icd.o: sfc/coprocessor/icd/icd.cpp $(call rwildcard,sfc/coprocessor/icd/)
obj/sfc-mcc.o: sfc/coprocessor/mcc/mcc.cpp $(call rwildcard,sfc/coprocessor/mcc/) obj/sfc-mcc.o: sfc/coprocessor/mcc/mcc.cpp $(call rwildcard,sfc/coprocessor/mcc/)
obj/sfc-nss.o: sfc/coprocessor/nss/nss.cpp $(call rwildcard,sfc/coprocessor/nss/) obj/sfc-nss.o: sfc/coprocessor/nss/nss.cpp $(call rwildcard,sfc/coprocessor/nss/)
obj/sfc-event.o: sfc/coprocessor/event/event.cpp $(call rwildcard,sfc/coprocessor/event/) obj/sfc-event.o: sfc/coprocessor/event/event.cpp $(call rwildcard,sfc/coprocessor/event/)

View File

@ -41,7 +41,7 @@ auto Cartridge::load() -> bool {
loadCartridge(document); loadCartridge(document);
//Game Boy //Game Boy
if(cartridge.has.ICD2) { if(cartridge.has.ICD) {
information.sha256 = ""; //Game Boy cartridge not loaded yet: set later via loadGameBoy() information.sha256 = ""; //Game Boy cartridge not loaded yet: set later via loadGameBoy()
} }
@ -89,7 +89,7 @@ auto Cartridge::load() -> bool {
auto Cartridge::loadGameBoy() -> bool { auto Cartridge::loadGameBoy() -> bool {
#if defined(SFC_SUPERGAMEBOY) #if defined(SFC_SUPERGAMEBOY)
//invoked from ICD2::load() //invoked from ICD::load()
information.sha256 = GameBoy::cartridge.sha256(); information.sha256 = GameBoy::cartridge.sha256();
information.manifest.gameBoy = GameBoy::cartridge.manifest(); information.manifest.gameBoy = GameBoy::cartridge.manifest();
information.title.gameBoy = GameBoy::cartridge.title(); information.title.gameBoy = GameBoy::cartridge.title();
@ -103,7 +103,7 @@ auto Cartridge::loadBSMemory() -> bool {
if(auto fp = platform->open(bsmemory.pathID, "manifest.bml", File::Read, File::Required)) { if(auto fp = platform->open(bsmemory.pathID, "manifest.bml", File::Read, File::Required)) {
information.manifest.bsMemory = fp->reads(); information.manifest.bsMemory = fp->reads();
} else return false; } else return false;
loadBSMemory(BML::unserialize(information.manifest.bsMemory)); loadBSMemory(BML::unserialize(string{information.manifest.bsMemory}.replace("type: ", "type:")));
return true; return true;
} }
@ -111,7 +111,7 @@ auto Cartridge::loadSufamiTurboA() -> bool {
if(auto fp = platform->open(sufamiturboA.pathID, "manifest.bml", File::Read, File::Required)) { if(auto fp = platform->open(sufamiturboA.pathID, "manifest.bml", File::Read, File::Required)) {
information.manifest.sufamiTurboA = fp->reads(); information.manifest.sufamiTurboA = fp->reads();
} else return false; } else return false;
loadSufamiTurboA(BML::unserialize(information.manifest.sufamiTurboA)); loadSufamiTurboA(BML::unserialize(string{information.manifest.sufamiTurboA}.replace("type: ", "type:")));
return true; return true;
} }
@ -119,7 +119,7 @@ auto Cartridge::loadSufamiTurboB() -> bool {
if(auto fp = platform->open(sufamiturboB.pathID, "manifest.bml", File::Read, File::Required)) { if(auto fp = platform->open(sufamiturboB.pathID, "manifest.bml", File::Read, File::Required)) {
information.manifest.sufamiTurboB = fp->reads(); information.manifest.sufamiTurboB = fp->reads();
} else return false; } else return false;
loadSufamiTurboB(BML::unserialize(information.manifest.sufamiTurboB)); loadSufamiTurboB(BML::unserialize(string{information.manifest.sufamiTurboB}.replace("type: ", "type:")));
return true; return true;
} }
@ -127,8 +127,8 @@ auto Cartridge::save() -> void {
saveCartridge(BML::unserialize(information.manifest.cartridge)); saveCartridge(BML::unserialize(information.manifest.cartridge));
saveGameBoy(BML::unserialize(information.manifest.gameBoy)); saveGameBoy(BML::unserialize(information.manifest.gameBoy));
saveBSMemory(BML::unserialize(information.manifest.bsMemory)); saveBSMemory(BML::unserialize(information.manifest.bsMemory));
saveSufamiTurboA(BML::unserialize(information.manifest.sufamiTurboA)); saveSufamiTurboA(BML::unserialize(string{information.manifest.sufamiTurboA}.replace("type: ", "type:")));
saveSufamiTurboB(BML::unserialize(information.manifest.sufamiTurboB)); saveSufamiTurboB(BML::unserialize(string{information.manifest.sufamiTurboB}.replace("type: ", "type:")));
} }
auto Cartridge::unload() -> void { auto Cartridge::unload() -> void {

View File

@ -37,7 +37,7 @@ struct Cartridge {
} information; } information;
struct Has { struct Has {
boolean ICD2; boolean ICD;
boolean MCC; boolean MCC;
boolean NSSDIP; boolean NSSDIP;
boolean Event; boolean Event;
@ -75,7 +75,7 @@ private:
auto loadROM(Markup::Node) -> void; auto loadROM(Markup::Node) -> void;
auto loadRAM(Markup::Node) -> void; auto loadRAM(Markup::Node) -> void;
auto loadICD2(Markup::Node) -> void; auto loadICD(Markup::Node) -> void;
auto loadMCC(Markup::Node) -> void; auto loadMCC(Markup::Node) -> void;
auto loadBSMemoryPack(Markup::Node) -> void; auto loadBSMemoryPack(Markup::Node) -> void;
auto loadSufamiTurbo(Markup::Node, bool slot) -> void; auto loadSufamiTurbo(Markup::Node, bool slot) -> void;
@ -121,7 +121,7 @@ private:
auto saveMemory(MappedRAM&, Markup::Node, maybe<uint> = nothing) -> void; auto saveMemory(MappedRAM&, Markup::Node, maybe<uint> = nothing) -> void;
friend class Interface; friend class Interface;
friend class ICD2; friend class ICD;
}; };
extern Cartridge cartridge; extern Cartridge cartridge;

View File

@ -3,7 +3,7 @@ auto Cartridge::loadBoard(Markup::Node node) -> Markup::Node {
auto region = node["game/region"].text(); auto region = node["game/region"].text();
auto board = node["game/board"].text(); auto board = node["game/board"].text();
board.trimLeft("SHVC-", 1L); if(board != "SHVC-SGB2-01") board.trimLeft("SHVC-", 1L);
board.trimLeft("SNSP-", 1L); board.trimLeft("SNSP-", 1L);
board.trimLeft("MAXI-", 1L); board.trimLeft("MAXI-", 1L);
board.trimLeft("MJSC-", 1L); board.trimLeft("MJSC-", 1L);
@ -80,7 +80,7 @@ auto Cartridge::loadCartridge(Markup::Node node) -> void {
if(board["region"].text() == "pal") information.region = "PAL"; if(board["region"].text() == "pal") information.region = "PAL";
} }
if(board["mcc"] || board["bsmemory"]) { if(board["bsmemory"] || board["mcc/bsmemory"] || board["sa1/bsmemory"]) {
if(auto loaded = platform->load(ID::BSMemory, "BS Memory", "bs")) { if(auto loaded = platform->load(ID::BSMemory, "BS Memory", "bs")) {
bsmemory.pathID = loaded.pathID(); bsmemory.pathID = loaded.pathID();
loadBSMemory(); loadBSMemory();
@ -95,7 +95,7 @@ auto Cartridge::loadCartridge(Markup::Node node) -> void {
if(auto node = board["rom"]) loadROM(node); if(auto node = board["rom"]) loadROM(node);
if(auto node = board["ram"]) loadRAM(node); if(auto node = board["ram"]) loadRAM(node);
if(auto node = board["icd2"]) loadICD2(node); if(auto node = board["icd"]) loadICD(node);
if(auto node = board["mcc"]) loadMCC(node); if(auto node = board["mcc"]) loadMCC(node);
if(auto node = board["bsmemory"]) loadBSMemoryPack(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(0)) loadSufamiTurbo(node(0), 0);
@ -120,30 +120,28 @@ auto Cartridge::loadGameBoy(Markup::Node node) -> void {
auto Cartridge::loadBSMemory(Markup::Node node) -> void { auto Cartridge::loadBSMemory(Markup::Node node) -> void {
information.title.bsMemory = node["game/label"].text(); information.title.bsMemory = node["game/label"].text();
bsmemory.readonly = (node["board/rom/type"].text() == "mrom"); bsmemory.readonly = node["game/memory/type"].text() == "ROM";
loadMemory(bsmemory.memory, node["board/rom"], File::Required, bsmemory.pathID); loadMemory(bsmemory.memory, node["game/memory"], File::Required, bsmemory.pathID);
} }
auto Cartridge::loadSufamiTurboA(Markup::Node node) -> void { auto Cartridge::loadSufamiTurboA(Markup::Node node) -> void {
information.title.sufamiTurboA = node["game/label"].text(); information.title.sufamiTurboA = node["game/label"].text();
loadMemory(sufamiturboA.rom, node["board/rom"], File::Required, sufamiturboA.pathID); loadMemory(sufamiturboA.rom, node["game/memory(type=ROM)" ], File::Required, sufamiturboA.pathID);
loadMemory(sufamiturboA.ram, node["board/ram"], File::Optional, sufamiturboA.pathID); loadMemory(sufamiturboA.ram, node["game/memory(type=NVRAM)"], File::Optional, sufamiturboA.pathID);
if(node["board/linkable"]) { if(auto loaded = platform->load(ID::SufamiTurboB, "Sufami Turbo", "st")) {
if(auto loaded = platform->load(ID::SufamiTurboB, "Sufami Turbo", "st")) { sufamiturboB.pathID = loaded.pathID();
sufamiturboB.pathID = loaded.pathID(); loadSufamiTurboB();
loadSufamiTurboB();
}
} }
} }
auto Cartridge::loadSufamiTurboB(Markup::Node node) -> void { auto Cartridge::loadSufamiTurboB(Markup::Node node) -> void {
information.title.sufamiTurboB = node["game/label"].text(); information.title.sufamiTurboB = node["game/label"].text();
loadMemory(sufamiturboB.rom, node["board/rom"], File::Required, sufamiturboB.pathID); loadMemory(sufamiturboB.rom, node["game/memory(type=ROM)" ], File::Required, sufamiturboB.pathID);
loadMemory(sufamiturboB.ram, node["board/ram"], File::Optional, sufamiturboB.pathID); loadMemory(sufamiturboB.ram, node["game/memory(type=NVRAM)"], File::Optional, sufamiturboB.pathID);
} }
// //
@ -158,13 +156,14 @@ auto Cartridge::loadRAM(Markup::Node node) -> void {
for(auto leaf : node.find("map")) loadMap(leaf, ram); for(auto leaf : node.find("map")) loadMap(leaf, ram);
} }
auto Cartridge::loadICD2(Markup::Node node) -> void { auto Cartridge::loadICD(Markup::Node node) -> void {
has.GameBoySlot = true; has.GameBoySlot = true;
has.ICD2 = true; has.ICD = true;
icd2.revision = max(1, node["revision"].natural()); icd.Revision = node["revision"].natural();
icd.Frequency = node["frequency"].natural();
//Game Boy core loads data through ICD2 interface //Game Boy core loads data through ICD interface
for(auto leaf : node.find("map")) loadMap(leaf, {&ICD2::readIO, &icd2}, {&ICD2::writeIO, &icd2}); for(auto leaf : node.find("map")) loadMap(leaf, {&ICD::readIO, &icd}, {&ICD::writeIO, &icd});
} }
auto Cartridge::loadMCC(Markup::Node node) -> void { auto Cartridge::loadMCC(Markup::Node node) -> void {

View File

@ -23,11 +23,11 @@ auto Cartridge::saveBSMemory(Markup::Node node) -> void {
} }
auto Cartridge::saveSufamiTurboA(Markup::Node node) -> void { auto Cartridge::saveSufamiTurboA(Markup::Node node) -> void {
saveMemory(sufamiturboA.ram, node["board/ram"], sufamiturboA.pathID); saveMemory(sufamiturboA.ram, node["game/memory(type=NVRAM)"], sufamiturboA.pathID);
} }
auto Cartridge::saveSufamiTurboB(Markup::Node node) -> void { auto Cartridge::saveSufamiTurboB(Markup::Node node) -> void {
saveMemory(sufamiturboB.ram, node["board/ram"], sufamiturboB.pathID); saveMemory(sufamiturboB.ram, node["game/memory(type=NVRAM)"], sufamiturboB.pathID);
} }
// //

View File

@ -1,4 +1,4 @@
#include <sfc/coprocessor/icd2/icd2.hpp> #include <sfc/coprocessor/icd/icd.hpp>
#include <sfc/coprocessor/mcc/mcc.hpp> #include <sfc/coprocessor/mcc/mcc.hpp>
#include <sfc/coprocessor/nss/nss.hpp> #include <sfc/coprocessor/nss/nss.hpp>
#include <sfc/coprocessor/event/event.hpp> #include <sfc/coprocessor/event/event.hpp>

View File

@ -2,7 +2,7 @@
namespace SuperFamicom { namespace SuperFamicom {
ICD2 icd2; ICD icd;
#if defined(SFC_SUPERGAMEBOY) #if defined(SFC_SUPERGAMEBOY)
@ -11,15 +11,15 @@ ICD2 icd2;
#include "io.cpp" #include "io.cpp"
#include "serialization.cpp" #include "serialization.cpp"
auto ICD2::Enter() -> void { auto ICD::Enter() -> void {
while(true) { while(true) {
if(scheduler.synchronizing()) GameBoy::system.runToSave(); if(scheduler.synchronizing()) GameBoy::system.runToSave();
scheduler.synchronize(); scheduler.synchronize();
icd2.main(); icd.main();
} }
} }
auto ICD2::main() -> void { auto ICD::main() -> void {
if(r6003 & 0x80) { if(r6003 & 0x80) {
GameBoy::system.run(); GameBoy::system.run();
step(GameBoy::system._clocksExecuted); step(GameBoy::system._clocksExecuted);
@ -31,19 +31,20 @@ auto ICD2::main() -> void {
synchronize(cpu); synchronize(cpu);
} }
auto ICD2::load() -> bool { auto ICD::load() -> bool {
GameBoy::superGameBoy = this; GameBoy::superGameBoy = this;
GameBoy::system.load(&gameBoyInterface, GameBoy::System::Model::SuperGameBoy, cartridge.pathID()); GameBoy::system.load(&gameBoyInterface, GameBoy::System::Model::SuperGameBoy, cartridge.pathID());
return cartridge.loadGameBoy(); return cartridge.loadGameBoy();
} }
auto ICD2::unload() -> void { auto ICD::unload() -> void {
GameBoy::system.save(); GameBoy::system.save();
GameBoy::system.unload(); GameBoy::system.unload();
} }
auto ICD2::power() -> void { auto ICD::power() -> void {
create(ICD2::Enter, system.cpuFrequency() / 5.0); //SGB1 uses CPU oscillator; SGB2 uses dedicated oscillator
create(ICD::Enter, (Frequency ? Frequency : system.cpuFrequency()) / 5.0);
stream = Emulator::audio.createStream(2, frequency() / 2.0); stream = Emulator::audio.createStream(2, frequency() / 2.0);
stream->addFilter(Emulator::Filter::Order::First, Emulator::Filter::Type::HighPass, 20.0); stream->addFilter(Emulator::Filter::Order::First, Emulator::Filter::Type::HighPass, 20.0);
stream->addFilter(Emulator::Filter::Order::Second, Emulator::Filter::Type::LowPass, 20000.0, 3); stream->addFilter(Emulator::Filter::Order::Second, Emulator::Filter::Type::LowPass, 20000.0, 3);
@ -72,8 +73,8 @@ auto ICD2::power() -> void {
GameBoy::system.power(); GameBoy::system.power();
} }
auto ICD2::reset() -> void { auto ICD::reset() -> void {
create(ICD2::Enter, system.cpuFrequency() / 5.0); create(ICD::Enter, (Frequency ? Frequency : system.cpuFrequency()) / 5.0);
r6003 = 0x00; r6003 = 0x00;
r6004 = 0xff; r6004 = 0xff;

View File

@ -1,6 +1,6 @@
#if defined(SFC_SUPERGAMEBOY) #if defined(SFC_SUPERGAMEBOY)
struct ICD2 : Emulator::Platform, GameBoy::SuperGameBoyInterface, Thread { struct ICD : Emulator::Platform, GameBoy::SuperGameBoyInterface, Thread {
shared_pointer<Emulator::Stream> stream; shared_pointer<Emulator::Stream> stream;
static auto Enter() -> void; static auto Enter() -> void;
@ -27,7 +27,8 @@ struct ICD2 : Emulator::Platform, GameBoy::SuperGameBoyInterface, Thread {
//serialization.cpp //serialization.cpp
auto serialize(serializer&) -> void; auto serialize(serializer&) -> void;
uint revision; uint Revision = 0;
uint Frequency = 0;
private: private:
struct Packet { struct Packet {
@ -66,7 +67,7 @@ private:
#else #else
struct ICD2 : Thread { struct ICD : Thread {
auto init() -> void {} auto init() -> void {}
auto load() -> void {} auto load() -> void {}
auto unload() -> void {} auto unload() -> void {}
@ -78,9 +79,10 @@ struct ICD2 : Thread {
auto serialize(serializer&) -> void {} auto serialize(serializer&) -> void {}
uint revision; uint Revision = 0;
uint Frequency = 0;
}; };
#endif #endif
extern ICD2 icd2; extern ICD icd;

View File

@ -1,4 +1,4 @@
auto ICD2::lcdScanline() -> void { auto ICD::lcdScanline() -> void {
if(GameBoy::ppu.status.ly > 143) return; //Vblank if(GameBoy::ppu.status.ly > 143) return; //Vblank
if((GameBoy::ppu.status.ly & 7) == 0) { if((GameBoy::ppu.status.ly & 7) == 0) {
writeBank = (writeBank + 1) & 3; writeBank = (writeBank + 1) & 3;
@ -6,7 +6,7 @@ auto ICD2::lcdScanline() -> void {
} }
} }
auto ICD2::lcdOutput(uint2 color) -> void { auto ICD::lcdOutput(uint2 color) -> void {
uint y = writeAddress / 160; uint y = writeAddress / 160;
uint x = writeAddress % 160; uint x = writeAddress % 160;
uint addr = writeBank * 512 + y * 2 + x / 8 * 16; uint addr = writeBank * 512 + y * 2 + x / 8 * 16;
@ -15,7 +15,7 @@ auto ICD2::lcdOutput(uint2 color) -> void {
writeAddress = (writeAddress + 1) % 1280; writeAddress = (writeAddress + 1) % 1280;
} }
auto ICD2::joypWrite(bool p15, bool p14) -> void { auto ICD::joypWrite(bool p15, bool p14) -> void {
//joypad handling //joypad handling
if(p15 == 1 && p14 == 1) { if(p15 == 1 && p14 == 1) {
if(joyp15Lock == 0 && joyp14Lock == 0) { if(joyp15Lock == 0 && joyp14Lock == 0) {

View File

@ -1,4 +1,4 @@
auto ICD2::readIO(uint24 addr, uint8 data) -> uint8 { auto ICD::readIO(uint24 addr, uint8 data) -> uint8 {
addr &= 0x40ffff; addr &= 0x40ffff;
//LY counter //LY counter
@ -38,7 +38,7 @@ auto ICD2::readIO(uint24 addr, uint8 data) -> uint8 {
return 0x00; return 0x00;
} }
auto ICD2::writeIO(uint24 addr, uint8 data) -> void { auto ICD::writeIO(uint24 addr, uint8 data) -> void {
addr &= 0xffff; addr &= 0xffff;
//VRAM port //VRAM port

View File

@ -1,8 +1,8 @@
auto ICD2::audioSample(const double* samples, uint channels) -> void { auto ICD::audioSample(const double* samples, uint channels) -> void {
stream->write(samples); stream->write(samples);
} }
auto ICD2::inputPoll(uint port, uint device, uint id) -> int16 { auto ICD::inputPoll(uint port, uint device, uint id) -> int16 {
GameBoy::cpu.status.mltReq = joypID & mltReq; GameBoy::cpu.status.mltReq = joypID & mltReq;
uint data = 0x00; uint data = 0x00;

View File

@ -1,4 +1,4 @@
auto ICD2::serialize(serializer& s) -> void { auto ICD::serialize(serializer& s) -> void {
Thread::serialize(s); Thread::serialize(s);
GameBoy::system.serializeAll(s); GameBoy::system.serializeAll(s);

View File

@ -137,6 +137,7 @@ auto SA1::mmcromRead(uint24 addr, uint8) -> uint8 {
} }
static auto read = [](uint addr) { static auto read = [](uint addr) {
if((addr & 0x400000) && bsmemory.size()) return bsmemory.read(addr, 0x00);
return sa1.rom.read(bus.mirror(addr, sa1.rom.size())); return sa1.rom.read(bus.mirror(addr, sa1.rom.size()));
}; };

View File

@ -227,7 +227,7 @@ auto Interface::unserialize(serializer& s) -> bool {
auto Interface::cheatSet(const string_vector& list) -> void { auto Interface::cheatSet(const string_vector& list) -> void {
cheat.reset(); cheat.reset();
#if defined(SFC_SUPERGAMEBOY) #if defined(SFC_SUPERGAMEBOY)
if(cartridge.has.ICD2) return GameBoy::cheat.assign(list); if(cartridge.has.ICD) return GameBoy::cheat.assign(list);
#endif #endif
cheat.assign(list); cheat.assign(list);
} }

View File

@ -55,7 +55,7 @@ auto BSMemory::read(uint24 addr, uint8 data) -> uint8 {
} }
} }
return memory.read(addr, data); return memory.read(bus.mirror(addr, memory.size()), data);
} }
auto BSMemory::write(uint24 addr, uint8 data) -> void { auto BSMemory::write(uint24 addr, uint8 data) -> void {

View File

@ -50,7 +50,7 @@ auto System::serializeAll(serializer& s) -> void {
ppu.serialize(s); ppu.serialize(s);
dsp.serialize(s); dsp.serialize(s);
if(cartridge.has.ICD2) icd2.serialize(s); if(cartridge.has.ICD) icd.serialize(s);
if(cartridge.has.MCC) mcc.serialize(s); if(cartridge.has.MCC) mcc.serialize(s);
if(cartridge.has.Event) event.serialize(s); if(cartridge.has.Event) event.serialize(s);
if(cartridge.has.SA1) sa1.serialize(s); if(cartridge.has.SA1) sa1.serialize(s);

View File

@ -48,7 +48,7 @@ auto System::load(Emulator::Interface* interface) -> bool {
information.cpuFrequency = Emulator::Constants::Colorburst::PAL * 4.8; information.cpuFrequency = Emulator::Constants::Colorburst::PAL * 4.8;
} }
if(cartridge.has.ICD2) icd2.load(); if(cartridge.has.ICD) icd.load();
if(cartridge.has.BSMemorySlot) bsmemory.load(); if(cartridge.has.BSMemorySlot) bsmemory.load();
serializeInit(); serializeInit();
@ -70,7 +70,7 @@ auto System::unload() -> void {
controllerPort2.unload(); controllerPort2.unload();
expansionPort.unload(); expansionPort.unload();
if(cartridge.has.ICD2) icd2.unload(); if(cartridge.has.ICD) icd.unload();
if(cartridge.has.MCC) mcc.unload(); if(cartridge.has.MCC) mcc.unload();
if(cartridge.has.Event) event.unload(); if(cartridge.has.Event) event.unload();
if(cartridge.has.SA1) sa1.unload(); if(cartridge.has.SA1) sa1.unload();
@ -104,7 +104,7 @@ auto System::power(bool reset) -> void {
dsp.power(reset); dsp.power(reset);
ppu.power(reset); ppu.power(reset);
if(cartridge.has.ICD2) icd2.power(); if(cartridge.has.ICD) icd.power();
if(cartridge.has.MCC) mcc.power(); if(cartridge.has.MCC) mcc.power();
if(cartridge.has.NSSDIP) nss.power(); if(cartridge.has.NSSDIP) nss.power();
if(cartridge.has.Event) event.power(); if(cartridge.has.Event) event.power();
@ -122,7 +122,7 @@ auto System::power(bool reset) -> void {
if(cartridge.has.BSMemorySlot) bsmemory.power(); if(cartridge.has.BSMemorySlot) bsmemory.power();
if(cartridge.has.SufamiTurboSlots) sufamiturboA.power(), sufamiturboB.power(); if(cartridge.has.SufamiTurboSlots) sufamiturboA.power(), sufamiturboB.power();
if(cartridge.has.ICD2) cpu.coprocessors.append(&icd2); if(cartridge.has.ICD) cpu.coprocessors.append(&icd);
if(cartridge.has.Event) cpu.coprocessors.append(&event); if(cartridge.has.Event) cpu.coprocessors.append(&event);
if(cartridge.has.SA1) cpu.coprocessors.append(&sa1); if(cartridge.has.SA1) cpu.coprocessors.append(&sa1);
if(cartridge.has.SuperFX) cpu.coprocessors.append(&superfx); if(cartridge.has.SuperFX) cpu.coprocessors.append(&superfx);

View File

@ -1,10 +1,10 @@
database database
revision: 2018-02-15 revision: 2018-02-21
//Boards (Production) //Boards (Production)
database database
revision: 2018-02-11 revision: 2018-02-21
board: 1A0N-(01,02,10,20,30) board: 1A0N-(01,02,10,20,30)
rom rom
@ -152,10 +152,9 @@ board: 1CB7B-01
board: 1DC0N-01 board: 1DC0N-01
hitachidsp model=HG51B169 frequency=20000000 hitachidsp model=HG51B169 frequency=20000000
map address=00-3f,80-bf:6c00-6fff,7c00-7fff map address=00-3f,80-bf:6c00-6fff,7c00-7fff
map address=70-77:0000-7fff
rom rom
map address=00-3f,80-bf:8000-ffff mask=0x8000 map address=00-3f,80-bf:8000-ffff mask=0x8000
ram
map address=70-77:0000-7fff mask=0x8000
drom drom
dram dram
map address=00-3f,80-bf:6000-6bff,7000-7bff mask=0xf000 map address=00-3f,80-bf:6000-6bff,7000-7bff mask=0xf000
@ -196,7 +195,7 @@ board: 1J3M-(01,11,20)
ram ram
map address=20-3f,a0-bf:6000-7fff mask=0xe000 map address=20-3f,a0-bf:6000-7fff mask=0xe000
board: 1J5M-(11,20) board: 1J5M-(01,11,20)
rom rom
map address=00-3f,80-bf:8000-ffff map address=00-3f,80-bf:8000-ffff
map address=40-7d,c0-ff:0000-ffff map address=40-7d,c0-ff:0000-ffff
@ -317,10 +316,9 @@ board: 2B3B-01
board: 2DC0N-01 board: 2DC0N-01
hitachidsp model=HG51B169 frequency=20000000 hitachidsp model=HG51B169 frequency=20000000
map address=00-3f,80-bf:6c00-6fff,7c00-7fff map address=00-3f,80-bf:6c00-6fff,7c00-7fff
map address=70-77:0000-7fff
rom rom
map address=00-3f,80-bf:8000-ffff mask=0x8000 map address=00-3f,80-bf:8000-ffff mask=0x8000
ram
map address=70-77:0000-7fff mask=0x8000
drom drom
dram dram
map address=00-3f,80-bf:6000-6bff,7000-7bff mask=0xf000 map address=00-3f,80-bf:6000-6bff,7000-7bff mask=0xf000
@ -374,6 +372,20 @@ board: BA3M-(01,10)
ram ram
map address=70-7d,f0-ff:0000-7fff mask=0x8000 map address=70-7d,f0-ff:0000-7fff mask=0x8000
board: BANDAI-PT-923
rom
map address=00-1f,80-9f:8000-ffff mask=0x8000
sufamiturbo
rom
map address=20-3f,a0-bf:8000-ffff mask=0x8000
ram
map address=60-6f,e0-ef:0000-ffff
sufamiturbo
rom
map address=40-5f,c0-df:0000-ffff mask=0x8000
ram
map address=70-7d,f0-ff:0000-ffff
board: BJ0N-(01,20) board: BJ0N-(01,20)
rom rom
map address=00-3f,80-bf:8000-ffff map address=00-3f,80-bf:8000-ffff
@ -393,13 +405,91 @@ board: BJ3M-10
ram ram
map address=20-3f,a0-bf:6000-7fff mask=0xe000 map address=20-3f,a0-bf:6000-7fff mask=0xe000
board: BSC-1A5M-02
rom
map address=00-1f:8000-ffff mask=0x8000 base=0x000000
map address=20-3f:8000-ffff mask=0x8000 base=0x100000
map address=80-9f:8000-ffff mask=0x8000 base=0x200000
map address=a0-bf:8000-ffff mask=0x8000 base=0x100000
ram
map address=70-7d,f0-ff:0000-7fff mask=0x8000
bsmemory
map address=c0-ef:0000-ffff
board: BSC-1A7M-01
rom
map address=00-1f:8000-ffff mask=0x8000 base=0x000000
map address=20-3f:8000-ffff mask=0x8000 base=0x100000
map address=80-9f:8000-ffff mask=0x8000 base=0x200000
map address=a0-bf:8000-ffff mask=0x8000 base=0x100000
ram
map address=70-7d,f0-ff:0000-7fff mask=0x8000
bsmemory
map address=c0-ef:0000-ffff
board: BSC-1J3M-01
rom
map address=00-1f,80-9f:8000-ffff
map address=40-5f,c0-df:0000-ffff
ram
map address=20-3f,a0-bf:6000-7fff mask=0xe000
bsmemory
map address=20-3f,a0-bf:8000-ffff
map address=60-7d,e0-ff:0000-ffff
board: BSC-1J5M-01
rom
map address=00-1f,80-9f:8000-ffff
map address=40-5f,c0-df:0000-ffff
ram
map address=20-3f,a0-bf:6000-7fff mask=0xe000
bsmemory
map address=20-3f,a0-bf:8000-ffff
map address=60-7d,e0-ff:0000-ffff
board: BSC-1L3B-01
sa1
map address=00-3f,80-bf:2200-23ff
rom
map address=00-3f,80-bf:8000-ffff mask=0x408000
map address=c0-ff:0000-ffff
bwram
map address=00-3f,80-bf:6000-7fff size=0x2000
map address=40-4f:0000-ffff
iram
map address=00-3f,80-bf:3000-37ff size=0x800
bsmemory
board: BSC-1L5B-01
sa1
map address=00-3f,80-bf:2200-23ff
rom
map address=00-3f,80-bf:8000-ffff mask=0x408000
map address=c0-ff:0000-ffff
bwram
map address=00-3f,80-bf:6000-7fff size=0x2000
map address=40-4f:0000-ffff
iram
map address=00-3f,80-bf:3000-37ff size=0x800
bsmemory
board: SGB-R-10 board: SGB-R-10
rom rom
map address=00-7d,80-ff:8000-ffff mask=0x8000 map address=00-7d,80-ff:8000-ffff mask=0x8000
map address=40-7d,c0-ff:0000-7fff mask=0x8000 map address=40-7d,c0-ff:0000-7fff mask=0x8000
icd2 revision=1 icd revision=2
map address=00-3f,80-bf:6000-67ff,7000-7fff map address=00-3f,80-bf:6000-67ff,7000-7fff
rom rom
gameboy
board: SHVC-SGB2-01
rom
map address=00-7d,80-ff:8000-ffff mask=0x8000
map address=40-7d,c0-ff:0000-7fff mask=0x8000
icd revision=2 frequency=20971520
map address=00-3f,80-bf:6000-67ff,7000-7fff
rom
gameboy
board: YA0N-01 board: YA0N-01
rom rom
@ -414,7 +504,7 @@ board: YJ0N-01
//Boards (Generic) //Boards (Generic)
database database
revision: 2018-02-15 revision: 2018-02-21
board: ARM-LOROM-RAM board: ARM-LOROM-RAM
rom rom
@ -472,8 +562,7 @@ board: BS-SA1-RAM
map address=40-4f:0000-ffff map address=40-4f:0000-ffff
iram iram
map address=00-3f,80-bf:3000-37ff size=0x800 map address=00-3f,80-bf:3000-37ff size=0x800
bsmemory bsmemory
map
board: HIROM board: HIROM
rom rom
@ -650,9 +739,10 @@ board: SGB-LOROM
rom rom
map address=00-7d,80-ff:8000-ffff mask=0x8000 map address=00-7d,80-ff:8000-ffff mask=0x8000
map address=40-7d,c0-ff:0000-7fff mask=0x8000 map address=40-7d,c0-ff:0000-7fff mask=0x8000
icd2 revision=1 icd revision=2
map address=00-3f,80-bf:6000-67ff,7000-7fff map address=00-3f,80-bf:6000-67ff,7000-7fff
rom rom
gameboy
board: SPC7110-RAM board: SPC7110-RAM
spc7110 spc7110
@ -689,8 +779,7 @@ board: ST-LOROM
map address=60-6f,e0-ef:0000-ffff map address=60-6f,e0-ef:0000-ffff
sufamiturbo sufamiturbo
rom rom
map address=40-5f,c0-df:0000-7fff mask=0x8000 map address=40-5f,c0-df:0000-ffff mask=0x8000
map address=40-5f,c0-df:8000-ffff mask=0x8000
ram ram
map address=70-7d,f0-ff:0000-ffff map address=70-7d,f0-ff:0000-ffff