mirror of https://github.com/bsnes-emu/bsnes.git
Update to higan and icarus v095r16 release.
byuu says (in the WIP forum): Changelog: - satellaviewcartridge/SatellaviewCartridge is now bsmemory/BSMemory - Emulation/BS-X Satellaview/ is now Emulation/BS Memory/ - masking is in for MCC's mcu (awful hack in the code, but that's temporary) - BS Memory types are now "flash" or "mrom" - fixed loading Same Game - Tengai Hen - icarus fixed up a lot; can load database entries for any supported media type now (only the SFC DB exists currently) mMenu::remove() fix will be in the next WIP. byuu says (in the public beta thread): Changelog: - GBA emulation accuracy improved quite a bit - video shaders are supported once again - icarus shares settings.bml with higan; changing library path in one now affects the other - icarus manifest generation now uses my SNES game dumping database for perfect mapping of US games - major overhaul to manifest file format. As long as you have v095-style folders without manifest.bml, you will be fine - if not, go to higan->settings->configuration->advanced and check "Ignore Manifests" before loading your first game - new "Manifest Viewer" tool (not really meant for regular users; more of a developer tool) - experimental (but disabled in the binary) WASAPI driver. Help stabilizing it would be *greatly* appreciated! - lots of other stuff
This commit is contained in:
parent
bd628de3cf
commit
2a4eb1cfc8
|
@ -7,7 +7,7 @@ using namespace nall;
|
|||
|
||||
namespace Emulator {
|
||||
static const string Name = "higan";
|
||||
static const string Version = "095.15";
|
||||
static const string Version = "095.16";
|
||||
static const string Author = "byuu";
|
||||
static const string License = "GPLv3";
|
||||
static const string Website = "http://byuu.org/";
|
||||
|
@ -27,8 +27,8 @@ namespace Emulator {
|
|||
//no overhead (and no debugger invocation) if not compiled with -DDEBUGGER
|
||||
//wraps testing of function to allow invocation without a defined callback
|
||||
template<typename T> struct hook;
|
||||
template<typename R, typename... P> struct hook<R (P...)> {
|
||||
function<R (P...)> callback;
|
||||
template<typename R, typename... P> struct hook<auto (P...) -> R> {
|
||||
function<auto (P...) -> R> callback;
|
||||
|
||||
auto operator()(P... p) const -> R {
|
||||
#if defined(DEBUGGER)
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,47 @@
|
|||
auto Icarus::bsMemoryManifest(string location) -> string {
|
||||
vector<uint8> buffer;
|
||||
concatenate(buffer, {location, "program.rom"});
|
||||
return bsMemoryManifest(buffer, location);
|
||||
}
|
||||
|
||||
auto Icarus::bsMemoryManifest(vector<uint8>& buffer, string location) -> string {
|
||||
string markup;
|
||||
string digest = Hash::SHA256(buffer.data(), buffer.size()).digest();
|
||||
|
||||
if(settings["icarus/UseDatabase"].boolean() && !markup) {
|
||||
for(auto node : database.bsMemory) {
|
||||
if(node["sha256"].text() == digest) {
|
||||
markup.append(node.text(), "\n sha256: ", digest, "\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(settings["icarus/UseHeuristics"].boolean() && !markup) {
|
||||
BSMemoryCartridge cartridge{buffer.data(), buffer.size()};
|
||||
if(markup = cartridge.markup) {
|
||||
markup.append("\n");
|
||||
markup.append("information\n");
|
||||
markup.append(" title: ", prefixname(location), "\n");
|
||||
markup.append(" sha256: ", digest, "\n");
|
||||
markup.append(" note: ", "heuristically generated by icarus\n");
|
||||
}
|
||||
}
|
||||
|
||||
return markup;
|
||||
}
|
||||
|
||||
auto Icarus::bsMemoryImport(vector<uint8>& buffer, string location) -> bool {
|
||||
auto name = prefixname(location);
|
||||
auto source = pathname(location);
|
||||
string target{settings["Library/Location"].text(), "BS Memory/", name, ".bs/"};
|
||||
//if(directory::exists(target)) return failure("game already exists");
|
||||
|
||||
auto markup = bsMemoryManifest(buffer, location);
|
||||
if(!markup) return failure("failed to parse ROM image");
|
||||
if(!directory::create(target)) return failure("library path unwritable");
|
||||
|
||||
if(settings["icarus/CreateManifests"].boolean()) file::write({target, "manifest.bml"}, markup);
|
||||
file::write({target, "program.rom"}, buffer);
|
||||
return success();
|
||||
}
|
|
@ -1,56 +0,0 @@
|
|||
auto Icarus::bsxSatellaviewManifest(const string& location) -> string {
|
||||
vector<uint8_t> buffer;
|
||||
concatenate(buffer, {location, "program.rom"});
|
||||
return bsxSatellaviewManifest(buffer, location);
|
||||
}
|
||||
|
||||
auto Icarus::bsxSatellaviewManifest(vector<uint8_t>& buffer, const string& location) -> string {
|
||||
BsxSatellaviewCartridge cartridge{buffer.data(), buffer.size()};
|
||||
if(auto markup = cartridge.markup) {
|
||||
markup.append("\n");
|
||||
markup.append("information\n");
|
||||
markup.append(" sha256: ", Hash::SHA256(buffer.data(), buffer.size()).digest(), "\n");
|
||||
markup.append(" title: ", prefixname(location), "\n");
|
||||
markup.append(" note: ", "heuristically generated by icarus\n");
|
||||
return markup;
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
auto Icarus::bsxSatellaviewImport(vector<uint8_t>& buffer, const string& location) -> bool {
|
||||
auto name = prefixname(location);
|
||||
auto source = pathname(location);
|
||||
string target{settings["Library/Location"].text(), "BS-X Satellaview/", name, ".bs/"};
|
||||
//if(directory::exists(target)) return failure("game already exists");
|
||||
|
||||
string markup;
|
||||
|
||||
if(settings["icarus/UseDatabase"].boolean() && !markup) {
|
||||
auto digest = Hash::SHA256(buffer.data(), buffer.size()).digest();
|
||||
for(auto node : database.bsxSatellaview) {
|
||||
if(node.name() != "release") continue;
|
||||
if(node["information/sha256"].text() == digest) {
|
||||
markup.append(BML::serialize(node["cartridge"]), "\n");
|
||||
markup.append(BML::serialize(node["information"]));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(settings["icarus/UseHeuristics"].boolean() && !markup) {
|
||||
BsxSatellaviewCartridge cartridge{buffer.data(), buffer.size()};
|
||||
if(markup = cartridge.markup) {
|
||||
markup.append("\n");
|
||||
markup.append("information\n");
|
||||
markup.append(" title: ", name, "\n");
|
||||
markup.append(" note: heuristically generated by icarus\n");
|
||||
}
|
||||
}
|
||||
|
||||
if(!markup) return failure("failed to parse ROM image");
|
||||
if(!directory::create(target)) return failure("library path unwritable");
|
||||
|
||||
if(settings["icarus/CreateManifests"].boolean()) file::write({target, "manifest.bml"}, markup);
|
||||
file::write({target, "program.rom"}, buffer);
|
||||
return success();
|
||||
}
|
|
@ -1,5 +1,11 @@
|
|||
Icarus::Icarus() {
|
||||
database.famicom = BML::unserialize(string::read(locate({configpath(), "icarus/"}, "Database/Famicom.bml")));
|
||||
database.superFamicom = BML::unserialize(string::read(locate({configpath(), "icarus/"}, "Database/Super Famicom.bml")));
|
||||
database.gameBoy = BML::unserialize(string::read(locate({configpath(), "icarus/"}, "Database/Game Boy.bml")));
|
||||
database.gameBoyColor = BML::unserialize(string::read(locate({configpath(), "icarus/"}, "Database/Game Boy Color.bml")));
|
||||
database.gameBoyAdvance = BML::unserialize(string::read(locate({configpath(), "icarus/"}, "Database/Game Boy Advance.bml")));
|
||||
database.bsMemory = BML::unserialize(string::read(locate({configpath(), "icarus/"}, "Database/BS Memory.bml")));
|
||||
database.sufamiTurbo = BML::unserialize(string::read(locate({configpath(), "icarus/"}, "Database/Sufami Turbo.bml")));
|
||||
}
|
||||
|
||||
auto Icarus::error() const -> string {
|
||||
|
@ -11,7 +17,7 @@ auto Icarus::success() -> bool {
|
|||
return true;
|
||||
}
|
||||
|
||||
auto Icarus::failure(const string& message) -> bool {
|
||||
auto Icarus::failure(string message) -> bool {
|
||||
errorMessage = message;
|
||||
return false;
|
||||
}
|
||||
|
@ -26,7 +32,7 @@ auto Icarus::manifest(string location) -> string {
|
|||
if(type == ".gb") return gameBoyManifest(location);
|
||||
if(type == ".gbc") return gameBoyColorManifest(location);
|
||||
if(type == ".gba") return gameBoyAdvanceManifest(location);
|
||||
if(type == ".bs") return bsxSatellaviewManifest(location);
|
||||
if(type == ".bs") return bsMemoryManifest(location);
|
||||
if(type == ".st") return sufamiTurboManifest(location);
|
||||
|
||||
return "";
|
||||
|
@ -59,13 +65,13 @@ auto Icarus::import(string location) -> bool {
|
|||
if(type == ".gb") return gameBoyImport(buffer, location);
|
||||
if(type == ".gbc") return gameBoyColorImport(buffer, location);
|
||||
if(type == ".gba") return gameBoyAdvanceImport(buffer, location);
|
||||
if(type == ".bs") return bsxSatellaviewImport(buffer, location);
|
||||
if(type == ".bs") return bsMemoryImport(buffer, location);
|
||||
if(type == ".st") return sufamiTurboImport(buffer, location);
|
||||
|
||||
return failure("unrecognized file extension");
|
||||
}
|
||||
|
||||
auto Icarus::concatenate(vector<uint8_t>& output, const string& location) -> void {
|
||||
auto Icarus::concatenate(vector<uint8>& output, string location) -> void {
|
||||
if(auto input = file::read(location)) {
|
||||
auto size = output.size();
|
||||
output.resize(size + input.size());
|
||||
|
|
|
@ -4,55 +4,59 @@ struct Icarus {
|
|||
|
||||
auto error() const -> string;
|
||||
auto success() -> bool;
|
||||
auto failure(const string& message) -> bool;
|
||||
auto failure(string message) -> bool;
|
||||
|
||||
auto manifest(string location) -> string;
|
||||
auto import(string location) -> bool;
|
||||
|
||||
auto concatenate(vector<uint8_t>& output, const string& location) -> void;
|
||||
auto concatenate(vector<uint8>& output, string location) -> void;
|
||||
|
||||
//famicom.cpp
|
||||
auto famicomManifest(const string& location) -> string;
|
||||
auto famicomManifest(vector<uint8_t>& buffer, const string& location) -> string;
|
||||
auto famicomImport(vector<uint8_t>& buffer, const string& location) -> bool;
|
||||
auto famicomManifest(string location) -> string;
|
||||
auto famicomManifest(vector<uint8>& buffer, string location, uint* prgrom = nullptr, uint* chrrom = nullptr) -> string;
|
||||
auto famicomImport(vector<uint8>& buffer, string location) -> bool;
|
||||
|
||||
//super-famicom.cpp
|
||||
auto superFamicomManifest(const string& location) -> string;
|
||||
auto superFamicomManifest(vector<uint8_t>& buffer, const string& location) -> string;
|
||||
auto superFamicomManifest(string location) -> string;
|
||||
auto superFamicomManifest(vector<uint8>& buffer, string location, bool* firmwareAppended = nullptr) -> string;
|
||||
auto superFamicomManifestScan(vector<Markup::Node>& roms, Markup::Node node) -> void;
|
||||
auto superFamicomImport(vector<uint8_t>& buffer, const string& location) -> bool;
|
||||
auto superFamicomImport(vector<uint8>& buffer, string location) -> bool;
|
||||
|
||||
//game-boy.cpp
|
||||
auto gameBoyManifest(const string& location) -> string;
|
||||
auto gameBoyManifest(vector<uint8_t>& buffer, const string& location) -> string;
|
||||
auto gameBoyImport(vector<uint8_t>& buffer, const string& location) -> bool;
|
||||
auto gameBoyManifest(string location) -> string;
|
||||
auto gameBoyManifest(vector<uint8>& buffer, string location) -> string;
|
||||
auto gameBoyImport(vector<uint8>& buffer, string location) -> bool;
|
||||
|
||||
//game-boy-color.cpp
|
||||
auto gameBoyColorManifest(const string& location) -> string;
|
||||
auto gameBoyColorManifest(vector<uint8_t>& buffer, const string& location) -> string;
|
||||
auto gameBoyColorImport(vector<uint8_t>& buffer, const string& location) -> bool;
|
||||
auto gameBoyColorManifest(string location) -> string;
|
||||
auto gameBoyColorManifest(vector<uint8>& buffer, string location) -> string;
|
||||
auto gameBoyColorImport(vector<uint8>& buffer, string location) -> bool;
|
||||
|
||||
//game-boy-advance.cpp
|
||||
auto gameBoyAdvanceManifest(const string& location) -> string;
|
||||
auto gameBoyAdvanceManifest(vector<uint8_t>& buffer, const string& location) -> string;
|
||||
auto gameBoyAdvanceImport(vector<uint8_t>& buffer, const string& location) -> bool;
|
||||
auto gameBoyAdvanceManifest(string location) -> string;
|
||||
auto gameBoyAdvanceManifest(vector<uint8>& buffer, string location) -> string;
|
||||
auto gameBoyAdvanceImport(vector<uint8>& buffer, string location) -> bool;
|
||||
|
||||
//bsx-satellaview.cpp
|
||||
auto bsxSatellaviewManifest(const string& location) -> string;
|
||||
auto bsxSatellaviewManifest(vector<uint8_t>& buffer, const string& location) -> string;
|
||||
auto bsxSatellaviewImport(vector<uint8_t>& buffer, const string& location) -> bool;
|
||||
//bs-memory.cpp
|
||||
auto bsMemoryManifest(string location) -> string;
|
||||
auto bsMemoryManifest(vector<uint8>& buffer, string location) -> string;
|
||||
auto bsMemoryImport(vector<uint8>& buffer, string location) -> bool;
|
||||
|
||||
//sufami-turbo.cpp
|
||||
auto sufamiTurboManifest(const string& location) -> string;
|
||||
auto sufamiTurboManifest(vector<uint8_t>& buffer, const string& location) -> string;
|
||||
auto sufamiTurboImport(vector<uint8_t>& buffer, const string& location) -> bool;
|
||||
auto sufamiTurboManifest(string location) -> string;
|
||||
auto sufamiTurboManifest(vector<uint8>& buffer, string location) -> string;
|
||||
auto sufamiTurboImport(vector<uint8>& buffer, string location) -> bool;
|
||||
|
||||
private:
|
||||
string errorMessage;
|
||||
|
||||
struct {
|
||||
Markup::Node famicom;
|
||||
Markup::Node superFamicom;
|
||||
Markup::Node bsxSatellaview;
|
||||
Markup::Node gameBoy;
|
||||
Markup::Node gameBoyColor;
|
||||
Markup::Node gameBoyAdvance;
|
||||
Markup::Node bsMemory;
|
||||
Markup::Node sufamiTurbo;
|
||||
} database;
|
||||
};
|
||||
|
|
|
@ -1,49 +1,58 @@
|
|||
auto Icarus::famicomManifest(const string& location) -> string {
|
||||
vector<uint8_t> buffer;
|
||||
auto Icarus::famicomManifest(string location) -> string {
|
||||
vector<uint8> buffer;
|
||||
concatenate(buffer, {location, "ines.rom"});
|
||||
concatenate(buffer, {location, "program.rom"});
|
||||
concatenate(buffer, {location, "character.rom"});
|
||||
return famicomManifest(buffer, location);
|
||||
}
|
||||
|
||||
auto Icarus::famicomManifest(vector<uint8_t>& buffer, const string& location) -> string {
|
||||
FamicomCartridge cartridge{buffer.data(), buffer.size()};
|
||||
if(auto markup = cartridge.markup) {
|
||||
markup.append("\n");
|
||||
markup.append("information\n");
|
||||
markup.append(" sha256: ", Hash::SHA256(buffer.data(), buffer.size()).digest(), "\n");
|
||||
markup.append(" title: ", prefixname(location), "\n");
|
||||
markup.append(" note: ", "heuristically generated by icarus\n");
|
||||
return markup;
|
||||
auto Icarus::famicomManifest(vector<uint8>& buffer, string location, uint* prgrom, uint* chrrom) -> string {
|
||||
string markup;
|
||||
string digest = Hash::SHA256(buffer.data(), buffer.size()).digest();
|
||||
|
||||
if(settings["icarus/UseDatabase"].boolean() && !markup) {
|
||||
for(auto node : database.famicom) {
|
||||
if(node["sha256"].text() == digest) {
|
||||
markup.append(node.text(), "\n sha256: ", digest, "\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return "";
|
||||
|
||||
if(settings["icarus/UseHeuristics"].boolean() && !markup) {
|
||||
FamicomCartridge cartridge{buffer.data(), buffer.size()};
|
||||
if(markup = cartridge.markup) {
|
||||
markup.append("\n");
|
||||
markup.append("information\n");
|
||||
markup.append(" title: ", prefixname(location), "\n");
|
||||
markup.append(" sha256: ", digest, "\n");
|
||||
markup.append(" note: ", "heuristically generated by icarus\n");
|
||||
}
|
||||
}
|
||||
|
||||
auto document = BML::unserialize(markup);
|
||||
if(prgrom) *prgrom = document["board/prg/rom/size"].natural(); //0 if node does not exist
|
||||
if(chrrom) *chrrom = document["board/chr/rom/size"].natural(); //0 if node does not exist
|
||||
|
||||
return markup;
|
||||
}
|
||||
|
||||
auto Icarus::famicomImport(vector<uint8_t>& buffer, const string& location) -> bool {
|
||||
auto Icarus::famicomImport(vector<uint8>& buffer, string location) -> bool {
|
||||
auto name = prefixname(location);
|
||||
auto source = pathname(location);
|
||||
string target{settings["Library/Location"].text(), "Famicom/", name, ".fc/"};
|
||||
//if(directory::exists(target)) return failure("game already exists");
|
||||
|
||||
string markup;
|
||||
|
||||
//if(settings["icarus/UseHeuristics"].boolean() && !markup) {
|
||||
FamicomCartridge cartridge{buffer.data(), buffer.size()};
|
||||
if(markup = cartridge.markup) {
|
||||
markup.append("\n");
|
||||
markup.append("information\n");
|
||||
markup.append(" title: ", name, "\n");
|
||||
markup.append(" note: heuristically generated by icarus\n");
|
||||
}
|
||||
//}
|
||||
|
||||
uint prgrom = 0;
|
||||
uint chrrom = 0;
|
||||
auto markup = famicomManifest(buffer, location, &prgrom, &chrrom);
|
||||
if(!markup) return failure("failed to parse ROM image");
|
||||
if(!directory::create(target)) return failure("library path unwritable");
|
||||
|
||||
if(settings["icarus/CreateManifests"].boolean()) file::write({target, "manifest.bml"}, markup);
|
||||
file::write({target, "ines.rom"}, buffer.data(), 16);
|
||||
file::write({target, "program.rom"}, buffer.data() + 16, cartridge.prgrom);
|
||||
if(!cartridge.chrrom) return success();
|
||||
file::write({target, "character.rom"}, buffer.data() + 16 + cartridge.prgrom, cartridge.chrrom);
|
||||
file::write({target, "program.rom"}, buffer.data() + 16, prgrom);
|
||||
if(!chrrom) return success();
|
||||
file::write({target, "character.rom"}, buffer.data() + 16 + prgrom, chrrom);
|
||||
return success();
|
||||
}
|
||||
|
|
|
@ -1,40 +1,43 @@
|
|||
auto Icarus::gameBoyAdvanceManifest(const string& location) -> string {
|
||||
vector<uint8_t> buffer;
|
||||
auto Icarus::gameBoyAdvanceManifest(string location) -> string {
|
||||
vector<uint8> buffer;
|
||||
concatenate(buffer, {location, "program.rom"});
|
||||
return gameBoyAdvanceManifest(buffer, location);
|
||||
}
|
||||
|
||||
auto Icarus::gameBoyAdvanceManifest(vector<uint8_t>& buffer, const string& location) -> string {
|
||||
GameBoyAdvanceCartridge cartridge{buffer.data(), buffer.size()};
|
||||
if(auto markup = cartridge.markup) {
|
||||
markup.append("\n");
|
||||
markup.append("information\n");
|
||||
markup.append(" sha256: ", Hash::SHA256(buffer.data(), buffer.size()).digest(), "\n");
|
||||
markup.append(" title: ", prefixname(location), "\n");
|
||||
markup.append(" note: ", "heuristically generated by icarus\n");
|
||||
return markup;
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
auto Icarus::gameBoyAdvanceImport(vector<uint8_t>& buffer, const string& location) -> bool {
|
||||
auto name = prefixname(location);
|
||||
auto source = pathname(location);
|
||||
string target{settings["Library/Location"].text(), "Game Boy Advance/", name, ".gba/"};
|
||||
//if(directory::exists(target)) return failure("game already exists");
|
||||
|
||||
auto Icarus::gameBoyAdvanceManifest(vector<uint8>& buffer, string location) -> string {
|
||||
string markup;
|
||||
string digest = Hash::SHA256(buffer.data(), buffer.size()).digest();
|
||||
|
||||
if(settings["icarus/UseDatabase"].boolean() && !markup) {
|
||||
for(auto node : database.gameBoyAdvance) {
|
||||
if(node["sha256"].text() == digest) {
|
||||
markup.append(node.text(), "\n sha256: ", digest, "\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(settings["icarus/UseHeuristics"].boolean() && !markup) {
|
||||
GameBoyAdvanceCartridge cartridge{buffer.data(), buffer.size()};
|
||||
if(markup = cartridge.markup) {
|
||||
markup.append("\n");
|
||||
markup.append("information\n");
|
||||
markup.append(" title: ", name, "\n");
|
||||
markup.append(" note: heuristically generated by icarus\n");
|
||||
markup.append(" title: ", prefixname(location), "\n");
|
||||
markup.append(" sha256: ", digest, "\n");
|
||||
markup.append(" note: ", "heuristically generated by icarus\n");
|
||||
}
|
||||
}
|
||||
|
||||
return markup;
|
||||
}
|
||||
|
||||
auto Icarus::gameBoyAdvanceImport(vector<uint8>& buffer, string location) -> bool {
|
||||
auto name = prefixname(location);
|
||||
auto source = pathname(location);
|
||||
string target{settings["Library/Location"].text(), "Game Boy Advance/", name, ".gba/"};
|
||||
//if(directory::exists(target)) return failure("game already exists");
|
||||
|
||||
auto markup = gameBoyAdvanceManifest(buffer, location);
|
||||
if(!markup) return failure("failed to parse ROM image");
|
||||
if(!directory::create(target)) return failure("library path unwritable");
|
||||
|
||||
|
|
|
@ -1,40 +1,43 @@
|
|||
auto Icarus::gameBoyColorManifest(const string& location) -> string {
|
||||
vector<uint8_t> buffer;
|
||||
auto Icarus::gameBoyColorManifest(string location) -> string {
|
||||
vector<uint8> buffer;
|
||||
concatenate(buffer, {location, "program.rom"});
|
||||
return gameBoyColorManifest(buffer, location);
|
||||
}
|
||||
|
||||
auto Icarus::gameBoyColorManifest(vector<uint8_t>& buffer, const string& location) -> string {
|
||||
GameBoyCartridge cartridge{buffer.data(), buffer.size()};
|
||||
if(auto markup = cartridge.markup) {
|
||||
markup.append("\n");
|
||||
markup.append("information\n");
|
||||
markup.append(" sha256: ", Hash::SHA256(buffer.data(), buffer.size()).digest(), "\n");
|
||||
markup.append(" title: ", prefixname(location), "\n");
|
||||
markup.append(" note: ", "heuristically generated by icarus\n");
|
||||
return markup;
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
auto Icarus::gameBoyColorImport(vector<uint8_t>& buffer, const string& location) -> bool {
|
||||
auto name = prefixname(location);
|
||||
auto source = pathname(location);
|
||||
string target{settings["Library/Location"].text(), "Game Boy Color/", name, ".gbc/"};
|
||||
//if(directory::exists(target)) return failure("game already exists");
|
||||
|
||||
auto Icarus::gameBoyColorManifest(vector<uint8>& buffer, string location) -> string {
|
||||
string markup;
|
||||
string digest = Hash::SHA256(buffer.data(), buffer.size()).digest();
|
||||
|
||||
if(settings["icarus/UseDatabase"].boolean() && !markup) {
|
||||
for(auto node : database.gameBoyColor) {
|
||||
if(node["sha256"].text() == digest) {
|
||||
markup.append(node.text(), "\n sha256: ", digest, "\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(settings["icarus/UseHeuristics"].boolean() && !markup) {
|
||||
GameBoyCartridge cartridge{buffer.data(), buffer.size()};
|
||||
if(markup = cartridge.markup) {
|
||||
markup.append("\n");
|
||||
markup.append("information\n");
|
||||
markup.append(" title: ", name, "\n");
|
||||
markup.append(" note: heuristically generated by icarus\n");
|
||||
markup.append(" title: ", prefixname(location), "\n");
|
||||
markup.append(" sha256: ", digest, "\n");
|
||||
markup.append(" note: ", "heuristically generated by icarus\n");
|
||||
}
|
||||
}
|
||||
|
||||
return markup;
|
||||
}
|
||||
|
||||
auto Icarus::gameBoyColorImport(vector<uint8>& buffer, string location) -> bool {
|
||||
auto name = prefixname(location);
|
||||
auto source = pathname(location);
|
||||
string target{settings["Library/Location"].text(), "Game Boy Color/", name, ".gbc/"};
|
||||
//if(directory::exists(target)) return failure("game already exists");
|
||||
|
||||
auto markup = gameBoyColorManifest(buffer, location);
|
||||
if(!markup) return failure("failed to parse ROM image");
|
||||
if(!directory::create(target)) return failure("library path unwritable");
|
||||
|
||||
|
|
|
@ -1,40 +1,43 @@
|
|||
auto Icarus::gameBoyManifest(const string& location) -> string {
|
||||
vector<uint8_t> buffer;
|
||||
auto Icarus::gameBoyManifest(string location) -> string {
|
||||
vector<uint8> buffer;
|
||||
concatenate(buffer, {location, "program.rom"});
|
||||
return gameBoyManifest(buffer, location);
|
||||
}
|
||||
|
||||
auto Icarus::gameBoyManifest(vector<uint8_t>& buffer, const string& location) -> string {
|
||||
GameBoyCartridge cartridge{buffer.data(), buffer.size()};
|
||||
if(auto markup = cartridge.markup) {
|
||||
markup.append("\n");
|
||||
markup.append("information\n");
|
||||
markup.append(" sha256: ", Hash::SHA256(buffer.data(), buffer.size()).digest(), "\n");
|
||||
markup.append(" title: ", prefixname(location), "\n");
|
||||
markup.append(" note: ", "heuristically generated by icarus\n");
|
||||
return markup;
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
auto Icarus::gameBoyImport(vector<uint8_t>& buffer, const string& location) -> bool {
|
||||
auto name = prefixname(location);
|
||||
auto source = pathname(location);
|
||||
string target{settings["Library/Location"].text(), "Game Boy/", name, ".gb/"};
|
||||
//if(directory::exists(target)) return failure("game already exists");
|
||||
|
||||
auto Icarus::gameBoyManifest(vector<uint8>& buffer, string location) -> string {
|
||||
string markup;
|
||||
string digest = Hash::SHA256(buffer.data(), buffer.size()).digest();
|
||||
|
||||
if(settings["icarus/UseDatabase"].boolean() && !markup) {
|
||||
for(auto node : database.gameBoy) {
|
||||
if(node["sha256"].text() == digest) {
|
||||
markup.append(node.text(), "\n sha256: ", digest, "\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(settings["icarus/UseHeuristics"].boolean() && !markup) {
|
||||
GameBoyCartridge cartridge{buffer.data(), buffer.size()};
|
||||
if(markup = cartridge.markup) {
|
||||
markup.append("\n");
|
||||
markup.append("information\n");
|
||||
markup.append(" title: ", name, "\n");
|
||||
markup.append(" note: heuristically generated by icarus\n");
|
||||
markup.append(" title: ", prefixname(location), "\n");
|
||||
markup.append(" sha256: ", digest, "\n");
|
||||
markup.append(" note: ", "heuristically generated by icarus\n");
|
||||
}
|
||||
}
|
||||
|
||||
return markup;
|
||||
}
|
||||
|
||||
auto Icarus::gameBoyImport(vector<uint8>& buffer, string location) -> bool {
|
||||
auto name = prefixname(location);
|
||||
auto source = pathname(location);
|
||||
string target{settings["Library/Location"].text(), "Game Boy/", name, ".gb/"};
|
||||
//if(directory::exists(target)) return failure("game already exists");
|
||||
|
||||
auto markup = gameBoyManifest(buffer, location);
|
||||
if(!markup) return failure("failed to parse ROM image");
|
||||
if(!directory::create(target)) return failure("library path unwritable");
|
||||
|
||||
|
|
|
@ -1,37 +1,17 @@
|
|||
auto Icarus::sufamiTurboManifest(const string& location) -> string {
|
||||
vector<uint8_t> buffer;
|
||||
auto Icarus::sufamiTurboManifest(string location) -> string {
|
||||
vector<uint8> buffer;
|
||||
concatenate(buffer, {location, "program.rom"});
|
||||
return sufamiTurboManifest(buffer, location);
|
||||
}
|
||||
|
||||
auto Icarus::sufamiTurboManifest(vector<uint8_t>& buffer, const string& location) -> string {
|
||||
SufamiTurboCartridge cartridge{buffer.data(), buffer.size()};
|
||||
if(auto markup = cartridge.markup) {
|
||||
markup.append("\n");
|
||||
markup.append("information\n");
|
||||
markup.append(" sha256: ", Hash::SHA256(buffer.data(), buffer.size()).digest(), "\n");
|
||||
markup.append(" title: ", prefixname(location), "\n");
|
||||
markup.append(" note: ", "heuristically generated by icarus\n");
|
||||
return markup;
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
auto Icarus::sufamiTurboImport(vector<uint8_t>& buffer, const string& location) -> bool {
|
||||
auto name = prefixname(location);
|
||||
auto source = pathname(location);
|
||||
string target{settings["Library/Location"].text(), "Sufami Turbo/", name, ".st/"};
|
||||
//if(directory::exists(target)) return failure("game already exists");
|
||||
|
||||
auto Icarus::sufamiTurboManifest(vector<uint8>& buffer, string location) -> string {
|
||||
string markup;
|
||||
string digest = Hash::SHA256(buffer.data(), buffer.size()).digest();
|
||||
|
||||
if(settings["icarus/UseDatabase"].boolean() && !markup) {
|
||||
auto digest = Hash::SHA256(buffer.data(), buffer.size()).digest();
|
||||
for(auto node : database.sufamiTurbo) {
|
||||
if(node.name() != "release") continue;
|
||||
if(node["information/sha256"].text() == digest) {
|
||||
markup.append(BML::serialize(node["cartridge"]), "\n");
|
||||
markup.append(BML::serialize(node["information"]));
|
||||
if(node["sha256"].text() == digest) {
|
||||
markup.append(node.text(), "\n sha256: ", digest, "\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -42,11 +22,22 @@ auto Icarus::sufamiTurboImport(vector<uint8_t>& buffer, const string& location)
|
|||
if(markup = cartridge.markup) {
|
||||
markup.append("\n");
|
||||
markup.append("information\n");
|
||||
markup.append(" title: ", name, "\n");
|
||||
markup.append(" note: heuristically generated by icarus\n");
|
||||
markup.append(" title: ", prefixname(location), "\n");
|
||||
markup.append(" sha256: ", digest, "\n");
|
||||
markup.append(" note: ", "heuristically generated by icarus\n");
|
||||
}
|
||||
}
|
||||
|
||||
return markup;
|
||||
}
|
||||
|
||||
auto Icarus::sufamiTurboImport(vector<uint8>& buffer, string location) -> bool {
|
||||
auto name = prefixname(location);
|
||||
auto source = pathname(location);
|
||||
string target{settings["Library/Location"].text(), "Sufami Turbo/", name, ".st/"};
|
||||
//if(directory::exists(target)) return failure("game already exists");
|
||||
|
||||
auto markup = sufamiTurboManifest(buffer, location);
|
||||
if(!markup) return failure("failed to parse ROM image");
|
||||
if(!directory::create(target)) return failure("library path unwritable");
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
auto Icarus::superFamicomManifest(const string& location) -> string {
|
||||
vector<uint8_t> buffer;
|
||||
auto Icarus::superFamicomManifest(string location) -> string {
|
||||
vector<uint8> buffer;
|
||||
auto files = directory::files(location, "*.rom");
|
||||
concatenate(buffer, {location, "program.rom"});
|
||||
concatenate(buffer, {location, "data.rom" });
|
||||
|
@ -9,11 +9,11 @@ auto Icarus::superFamicomManifest(const string& location) -> string {
|
|||
return superFamicomManifest(buffer, location);
|
||||
}
|
||||
|
||||
auto Icarus::superFamicomManifest(vector<uint8_t>& buffer, const string& location) -> string {
|
||||
auto Icarus::superFamicomManifest(vector<uint8>& buffer, string location, bool* firmwareAppended) -> string {
|
||||
string markup;
|
||||
string digest = Hash::SHA256(buffer.data(), buffer.size()).digest();
|
||||
|
||||
if(settings["icarus/UseDatabase"].boolean() && !markup) {
|
||||
auto digest = Hash::SHA256(buffer.data(), buffer.size()).digest();
|
||||
for(auto node : database.superFamicom) {
|
||||
if(node["sha256"].text() == digest) {
|
||||
markup.append(node.text(), "\n sha256: ", digest, "\n");
|
||||
|
@ -24,12 +24,13 @@ auto Icarus::superFamicomManifest(vector<uint8_t>& buffer, const string& locatio
|
|||
|
||||
if(settings["icarus/UseHeuristics"].boolean() && !markup) {
|
||||
SuperFamicomCartridge cartridge{buffer.data(), buffer.size()};
|
||||
if(auto markup = cartridge.markup) {
|
||||
if(markup = cartridge.markup) {
|
||||
if(firmwareAppended) *firmwareAppended = cartridge.firmware_appended;
|
||||
markup.append("\n");
|
||||
markup.append("information\n");
|
||||
markup.append(" region: ", cartridge.region == SuperFamicomCartridge::Region::NTSC ? "NTSC" : "PAL", "\n");
|
||||
markup.append(" title: ", prefixname(location), "\n");
|
||||
markup.append(" sha256: ", Hash::SHA256(buffer.data(), buffer.size()).digest(), "\n");
|
||||
markup.append(" sha256: ", digest, "\n");
|
||||
markup.append(" note: ", "heuristically generated by icarus\n");
|
||||
}
|
||||
}
|
||||
|
@ -42,37 +43,15 @@ auto Icarus::superFamicomManifestScan(vector<Markup::Node>& roms, Markup::Node n
|
|||
for(auto leaf : node) superFamicomManifestScan(roms, leaf);
|
||||
}
|
||||
|
||||
auto Icarus::superFamicomImport(vector<uint8_t>& buffer, const string& location) -> bool {
|
||||
auto Icarus::superFamicomImport(vector<uint8>& buffer, string location) -> bool {
|
||||
auto name = prefixname(location);
|
||||
auto source = pathname(location);
|
||||
string target{settings["Library/Location"].text(), "Super Famicom/", name, ".sfc/"};
|
||||
//if(directory::exists(target)) return failure("game already exists");
|
||||
|
||||
string markup;
|
||||
bool firmwareAppended = true;
|
||||
|
||||
if(settings["icarus/UseDatabase"].boolean() && !markup) {
|
||||
auto digest = Hash::SHA256(buffer.data(), buffer.size()).digest();
|
||||
for(auto node : database.superFamicom) {
|
||||
if(node["sha256"].text() == digest) {
|
||||
markup.append(node.text(), "\n sha256: ", digest, "\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(settings["icarus/UseHeuristics"].boolean() && !markup) {
|
||||
SuperFamicomCartridge cartridge{buffer.data(), buffer.size()};
|
||||
if(markup = cartridge.markup) {
|
||||
firmwareAppended = cartridge.firmware_appended;
|
||||
markup.append("\n");
|
||||
markup.append("information\n");
|
||||
markup.append(" region: ", cartridge.region == SuperFamicomCartridge::Region::NTSC ? "NTSC" : "PAL", "\n");
|
||||
markup.append(" title: ", name, "\n");
|
||||
markup.append(" sha256: ", Hash::SHA256(buffer.data(), buffer.size()).digest(), "\n");
|
||||
markup.append(" note: ", "heuristically generated by icarus\n");
|
||||
}
|
||||
}
|
||||
auto markup = superFamicomManifest(buffer, location, &firmwareAppended);
|
||||
if(!markup) return failure("failed to parse ROM image");
|
||||
|
||||
auto document = BML::unserialize(markup);
|
||||
vector<Markup::Node> roms;
|
||||
|
@ -84,7 +63,6 @@ auto Icarus::superFamicomImport(vector<uint8_t>& buffer, const string& location)
|
|||
if(file::size({source, name}) != size) return failure({"firmware (", name, ") missing or invalid"});
|
||||
}
|
||||
|
||||
if(!markup) return failure("failed to parse ROM image");
|
||||
if(!directory::create(target)) return failure("library path unwritable");
|
||||
|
||||
if(settings["icarus/CreateManifests"].boolean()) file::write({target, "manifest.bml"}, markup);
|
||||
|
|
|
@ -0,0 +1,10 @@
|
|||
struct BSMemoryCartridge {
|
||||
BSMemoryCartridge(const uint8* data, uint size);
|
||||
|
||||
string markup;
|
||||
};
|
||||
|
||||
BSMemoryCartridge::BSMemoryCartridge(const uint8* data, uint size) {
|
||||
markup.append("board\n");
|
||||
markup.append(" rom type=flash name=program.rom size=0x", hex(size), "\n");
|
||||
}
|
|
@ -1,10 +0,0 @@
|
|||
struct BsxSatellaviewCartridge {
|
||||
BsxSatellaviewCartridge(const uint8_t* data, unsigned size);
|
||||
|
||||
string markup;
|
||||
};
|
||||
|
||||
BsxSatellaviewCartridge::BsxSatellaviewCartridge(const uint8_t* data, unsigned size) {
|
||||
markup.append("board\n");
|
||||
markup.append(" rom type=flash name=program.rom size=0x", hex(size), "\n");
|
||||
}
|
|
@ -22,88 +22,69 @@ struct SuperFamicomCartridge {
|
|||
ResetVector = 0x3c,
|
||||
};
|
||||
|
||||
enum Mode : uint {
|
||||
ModeNormal,
|
||||
ModeBsxSlotted,
|
||||
ModeBsx,
|
||||
ModeSufamiTurbo,
|
||||
ModeSuperGameBoy,
|
||||
};
|
||||
|
||||
enum Type : uint {
|
||||
TypeNormal,
|
||||
TypeBsxSlotted,
|
||||
TypeBsxBios,
|
||||
TypeBsx,
|
||||
TypeSufamiTurboBios,
|
||||
TypeSufamiTurbo,
|
||||
TypeSuperGameBoy1Bios,
|
||||
TypeSuperGameBoy2Bios,
|
||||
TypeGameBoy,
|
||||
TypeUnknown,
|
||||
};
|
||||
|
||||
enum Region : uint {
|
||||
NTSC,
|
||||
PAL,
|
||||
};
|
||||
|
||||
enum MemoryMapper : uint {
|
||||
enum class Type : uint {
|
||||
SatellaviewBIOS,
|
||||
SufamiTurboBIOS,
|
||||
SuperGameBoy1BIOS,
|
||||
SuperGameBoy2BIOS,
|
||||
LoROM,
|
||||
HiROM,
|
||||
ExLoROM,
|
||||
ExHiROM,
|
||||
SuperFXROM,
|
||||
SA1ROM,
|
||||
SPC7110ROM,
|
||||
BSCLoROM,
|
||||
BSCHiROM,
|
||||
BSXROM,
|
||||
STROM,
|
||||
SuperFX,
|
||||
SA1,
|
||||
LoROMSatellaview,
|
||||
HiROMSatellaview,
|
||||
|
||||
//invalid types
|
||||
Unknown,
|
||||
GameBoy,
|
||||
Satellaview,
|
||||
SufamiTurbo,
|
||||
};
|
||||
|
||||
enum DSP1MemoryMapper : uint {
|
||||
DSP1Unmapped,
|
||||
DSP1LoROM1MB,
|
||||
DSP1LoROM2MB,
|
||||
DSP1HiROM,
|
||||
enum class Region : uint {
|
||||
NTSC,
|
||||
PAL,
|
||||
};
|
||||
|
||||
bool loaded; //is a base cartridge inserted?
|
||||
uint crc32; //crc32 of all cartridges (base+slot(s))
|
||||
uint rom_size;
|
||||
uint ram_size;
|
||||
bool firmware_required; //true if firmware is required for emulation
|
||||
bool firmware_appended; //true if firmware is present at end of data
|
||||
enum class DSP1Type : uint {
|
||||
None,
|
||||
LoROM1MB,
|
||||
LoROM2MB,
|
||||
HiROM,
|
||||
};
|
||||
|
||||
Mode mode;
|
||||
Type type;
|
||||
Region region;
|
||||
MemoryMapper mapper;
|
||||
DSP1MemoryMapper dsp1_mapper;
|
||||
bool loaded = false; //is a base cartridge inserted?
|
||||
uint crc32 = 0; //crc32 of all cartridges (base+slot(s))
|
||||
uint rom_size = 0;
|
||||
uint ram_size = 0;
|
||||
bool firmware_required = false; //true if firmware is required for emulation
|
||||
bool firmware_appended = false; //true if firmware is present at end of data
|
||||
|
||||
bool has_bsx_slot;
|
||||
bool has_superfx;
|
||||
bool has_sa1;
|
||||
bool has_sharprtc;
|
||||
bool has_epsonrtc;
|
||||
bool has_sdd1;
|
||||
bool has_spc7110;
|
||||
bool has_cx4;
|
||||
bool has_dsp1;
|
||||
bool has_dsp2;
|
||||
bool has_dsp3;
|
||||
bool has_dsp4;
|
||||
bool has_obc1;
|
||||
bool has_st010;
|
||||
bool has_st011;
|
||||
bool has_st018;
|
||||
Type type = Type::Unknown;
|
||||
Region region = Region::NTSC;
|
||||
DSP1Type dsp1_type = DSP1Type::None;
|
||||
|
||||
bool has_bsx_slot = false;
|
||||
bool has_superfx = false;
|
||||
bool has_sa1 = false;
|
||||
bool has_sharprtc = false;
|
||||
bool has_epsonrtc = false;
|
||||
bool has_sdd1 = false;
|
||||
bool has_spc7110 = false;
|
||||
bool has_cx4 = false;
|
||||
bool has_dsp1 = false;
|
||||
bool has_dsp2 = false;
|
||||
bool has_dsp3 = false;
|
||||
bool has_dsp4 = false;
|
||||
bool has_obc1 = false;
|
||||
bool has_st010 = false;
|
||||
bool has_st011 = false;
|
||||
bool has_st018 = false;
|
||||
};
|
||||
|
||||
SuperFamicomCartridge::SuperFamicomCartridge(const uint8* data, uint size) {
|
||||
firmware_required = false;
|
||||
firmware_appended = false;
|
||||
|
||||
//skip copier header
|
||||
if((size & 0x7fff) == 512) data += 512, size -= 512;
|
||||
|
||||
|
@ -111,12 +92,13 @@ SuperFamicomCartridge::SuperFamicomCartridge(const uint8* data, uint size) {
|
|||
|
||||
readHeader(data, size);
|
||||
|
||||
if(type == TypeGameBoy) return;
|
||||
if(type == TypeBsx) return;
|
||||
if(type == TypeSufamiTurbo) return;
|
||||
if(type == Type::Unknown) return;
|
||||
if(type == Type::GameBoy) return;
|
||||
if(type == Type::Satellaview) return;
|
||||
if(type == Type::SufamiTurbo) return;
|
||||
|
||||
const char* range = (rom_size > 0x200000) || (ram_size > 32 * 1024) ? "0000-7fff" : "0000-ffff";
|
||||
markup.append("board cic=", region == NTSC ? "411" : "413", "\n");
|
||||
markup.append("board cic=", region == Region::NTSC ? "411" : "413", "\n");
|
||||
|
||||
//detect appended firmware
|
||||
|
||||
|
@ -184,7 +166,7 @@ SuperFamicomCartridge::SuperFamicomCartridge(const uint8* data, uint size) {
|
|||
}
|
||||
}
|
||||
|
||||
if(type == TypeSuperGameBoy1Bios || type == TypeSuperGameBoy2Bios) {
|
||||
if(type == Type::SuperGameBoy1BIOS || type == Type::SuperGameBoy2BIOS) {
|
||||
firmware_required = true;
|
||||
if((rom_size & 0x7fff) == 0x100) {
|
||||
firmware_appended = true;
|
||||
|
@ -194,7 +176,40 @@ SuperFamicomCartridge::SuperFamicomCartridge(const uint8* data, uint size) {
|
|||
|
||||
//end firmware detection
|
||||
|
||||
if(type == TypeSuperGameBoy1Bios || type == TypeSuperGameBoy2Bios) {
|
||||
if(type == Type::SatellaviewBIOS) {
|
||||
markup.append(
|
||||
" ram name=save.ram size=0x", hex(ram_size), "\n"
|
||||
" map address=10-1f:5000-5fff mask=0xf000\n"
|
||||
" mcc\n"
|
||||
" map address=00-0f:5000\n"
|
||||
" map=mcu address=00-3f,80-bf:8000-ffff mask=0x408000\n"
|
||||
" map=mcu address=40-7d,c0-ff:0000-ffff\n"
|
||||
" rom name=program.rom size=0x", hex(rom_size), "\n"
|
||||
" ram name=download.ram size=0x80000\n"
|
||||
" map address=00-3f,80-bf:6000-7fff mask=0xe000\n"
|
||||
" bsmemory\n"
|
||||
);
|
||||
}
|
||||
|
||||
else if(type == Type::SufamiTurboBIOS) {
|
||||
markup.append(
|
||||
" rom name=program.rom size=0x", hex(rom_size), "\n"
|
||||
" map address=00-1f,80-9f:8000-ffff mask=0x8000\n"
|
||||
" sufamiturbo\n"
|
||||
" rom\n"
|
||||
" map address=20-3f,a0-bf:8000-ffff mask=0x8000\n"
|
||||
" ram\n"
|
||||
" map address=60-6f,e0-ef:0000-ffff\n"
|
||||
" sufamiturbo\n"
|
||||
" rom\n"
|
||||
" map address=40-5f,c0-df:0000-7fff mask=0x8000\n"
|
||||
" map address=40-5f,c0-df:8000-ffff mask=0x8000\n"
|
||||
" ram\n"
|
||||
" map address=70-7d,f0-ff:0000-ffff\n"
|
||||
);
|
||||
}
|
||||
|
||||
else if(type == Type::SuperGameBoy1BIOS || type == Type::SuperGameBoy2BIOS) {
|
||||
markup.append(
|
||||
" rom name=program.rom size=0x", hex(rom_size), "\n"
|
||||
" map address=00-7d,80-ff:8000-ffff mask=0x8000\n"
|
||||
|
@ -248,11 +263,11 @@ SuperFamicomCartridge::SuperFamicomCartridge(const uint8* data, uint size) {
|
|||
);
|
||||
}
|
||||
|
||||
else if(mapper == LoROM) {
|
||||
else if(type == Type::LoROM) {
|
||||
markup.append(
|
||||
" rom name=program.rom size=0x", hex(rom_size), "\n"
|
||||
" map address=00-7d,80-ff:8000-ffff mask=0x8000\n"
|
||||
" map address=40-6d,c0-ef:0000-7fff mask=0x8000\n"
|
||||
" map address=40-6f,c0-ef:0000-7fff mask=0x8000\n"
|
||||
);
|
||||
if(ram_size > 0) markup.append(
|
||||
" ram name=save.ram size=0x", hex(ram_size), "\n"
|
||||
|
@ -260,7 +275,7 @@ SuperFamicomCartridge::SuperFamicomCartridge(const uint8* data, uint size) {
|
|||
);
|
||||
}
|
||||
|
||||
else if(mapper == HiROM) {
|
||||
else if(type == Type::HiROM) {
|
||||
markup.append(
|
||||
" rom name=program.rom size=0x", hex(rom_size), "\n"
|
||||
" map address=00-3f,80-bf:8000-ffff\n"
|
||||
|
@ -272,7 +287,7 @@ SuperFamicomCartridge::SuperFamicomCartridge(const uint8* data, uint size) {
|
|||
);
|
||||
}
|
||||
|
||||
else if(mapper == ExLoROM) {
|
||||
else if(type == Type::ExLoROM) {
|
||||
markup.append(
|
||||
" rom name=program.rom size=0x", hex(rom_size), "\n"
|
||||
" map address=00-3f,80-bf:8000-ffff mask=0x8000\n"
|
||||
|
@ -285,7 +300,7 @@ SuperFamicomCartridge::SuperFamicomCartridge(const uint8* data, uint size) {
|
|||
);
|
||||
}
|
||||
|
||||
else if(mapper == ExHiROM) {
|
||||
else if(type == Type::ExHiROM) {
|
||||
markup.append(
|
||||
" rom name=program.rom size=0x", hex(rom_size), "\n"
|
||||
" map address=00-3f:8000-ffff base=0x400000\n"
|
||||
|
@ -300,7 +315,7 @@ SuperFamicomCartridge::SuperFamicomCartridge(const uint8* data, uint size) {
|
|||
);
|
||||
}
|
||||
|
||||
else if(mapper == SuperFXROM) {
|
||||
else if(type == Type::SuperFX) {
|
||||
markup.append(
|
||||
" superfx\n"
|
||||
" map address=00-3f,80-bf:3000-34ff\n"
|
||||
|
@ -315,7 +330,7 @@ SuperFamicomCartridge::SuperFamicomCartridge(const uint8* data, uint size) {
|
|||
);
|
||||
}
|
||||
|
||||
else if(mapper == SA1ROM) {
|
||||
else if(type == Type::SA1) {
|
||||
markup.append(
|
||||
" sa1\n"
|
||||
" map address=00-3f,80-bf:2200-23ff\n"
|
||||
|
@ -334,7 +349,7 @@ SuperFamicomCartridge::SuperFamicomCartridge(const uint8* data, uint size) {
|
|||
);
|
||||
}
|
||||
|
||||
else if(mapper == BSCLoROM) {
|
||||
else if(type == Type::LoROMSatellaview) {
|
||||
markup.append(
|
||||
" rom name=program.rom size=0x", hex(rom_size), "\n"
|
||||
" map address=00-1f:8000-ffff base=0x000000 mask=0x8000\n"
|
||||
|
@ -343,56 +358,24 @@ SuperFamicomCartridge::SuperFamicomCartridge(const uint8* data, uint size) {
|
|||
" map address=a0-bf:8000-ffff base=0x100000 mask=0x8000\n"
|
||||
" ram name=save.ram size=0x", hex(ram_size), "\n"
|
||||
" map address=70-7d,f0-ff:0000-7fff mask=0x8000\n"
|
||||
" satellaview\n"
|
||||
" bsmemory\n"
|
||||
" map address=c0-ef:0000-ffff\n"
|
||||
);
|
||||
}
|
||||
|
||||
else if(mapper == BSCHiROM) {
|
||||
else if(type == Type::HiROMSatellaview) {
|
||||
markup.append(
|
||||
" rom name=program.rom size=0x", hex(rom_size), "\n"
|
||||
" map address=00-1f,80-9f:8000-ffff\n"
|
||||
" map address=40-5f,c0-df:0000-ffff\n"
|
||||
" ram name=save.ram size=0x", hex(ram_size), "\n"
|
||||
" map address=20-3f,a0-bf:6000-7fff\n"
|
||||
" satellaview\n"
|
||||
" bsmemory\n"
|
||||
" map address=20-3f,a0-bf:8000-ffff\n"
|
||||
" map address=60-7f,e0-ff:0000-ffff\n"
|
||||
);
|
||||
}
|
||||
|
||||
else if(mapper == BSXROM) {
|
||||
markup.append(
|
||||
" ram name=save.ram size=0x", hex(ram_size), "\n"
|
||||
" map address=10-1f:5000-5fff mask=0xf000\n"
|
||||
" mcc\n"
|
||||
" map address=00-0f:5000\n"
|
||||
" map=mcu address=00-3f,80-bf:8000-ffff\n"
|
||||
" map=mcu address=40-7d,c0-ff:0000-ffff\n"
|
||||
" rom name=program.rom size=0x", hex(rom_size), "\n"
|
||||
" ram name=download.ram size=0x80000\n"
|
||||
" map address=00-3f,80-bf:6000-7fff mask=0xe000\n"
|
||||
);
|
||||
}
|
||||
|
||||
else if(mapper == STROM) {
|
||||
markup.append(
|
||||
" rom name=program.rom size=0x", hex(rom_size), "\n"
|
||||
" map address=00-1f,80-9f:8000-ffff mask=0x8000\n"
|
||||
" sufamiturbo\n"
|
||||
" rom\n"
|
||||
" map address=20-3f,a0-bf:8000-ffff mask=0x8000\n"
|
||||
" ram\n"
|
||||
" map address=60-6f,e0-ef:0000-ffff\n"
|
||||
" sufamiturbo\n"
|
||||
" rom\n"
|
||||
" map address=40-5f,c0-df:0000-7fff mask=0x8000\n"
|
||||
" map address=40-5f,c0-df:8000-ffff mask=0x8000\n"
|
||||
" ram\n"
|
||||
" map address=70-7d,f0-ff:0000-ffff\n"
|
||||
);
|
||||
}
|
||||
|
||||
if(has_sharprtc) {
|
||||
markup.append(
|
||||
" sharprtc\n"
|
||||
|
@ -421,13 +404,13 @@ SuperFamicomCartridge::SuperFamicomCartridge(const uint8* data, uint size) {
|
|||
markup.append(
|
||||
" necdsp model=uPD7725 frequency=8000000\n"
|
||||
);
|
||||
if(dsp1_mapper == DSP1LoROM1MB) markup.append(
|
||||
if(dsp1_type == DSP1Type::LoROM1MB) markup.append(
|
||||
" map address=20-3f,a0-bf:8000-ffff mask=0x3fff\n"
|
||||
);
|
||||
if(dsp1_mapper == DSP1LoROM2MB) markup.append(
|
||||
if(dsp1_type == DSP1Type::LoROM2MB) markup.append(
|
||||
" map address=60-6f,e0-ef:0000-7fff mask=0x3fff\n"
|
||||
);
|
||||
if(dsp1_mapper == DSP1HiROM) markup.append(
|
||||
if(dsp1_type == DSP1Type::HiROM) markup.append(
|
||||
" map address=00-1f,80-9f:6000-7fff mask=0xfff\n"
|
||||
);
|
||||
markup.append(
|
||||
|
@ -501,47 +484,15 @@ SuperFamicomCartridge::SuperFamicomCartridge(const uint8* data, uint size) {
|
|||
}
|
||||
|
||||
auto SuperFamicomCartridge::readHeader(const uint8* data, uint size) -> void {
|
||||
type = TypeUnknown;
|
||||
mapper = LoROM;
|
||||
dsp1_mapper = DSP1Unmapped;
|
||||
region = NTSC;
|
||||
rom_size = size;
|
||||
ram_size = 0;
|
||||
|
||||
has_bsx_slot = false;
|
||||
has_superfx = false;
|
||||
has_sa1 = false;
|
||||
has_sharprtc = false;
|
||||
has_epsonrtc = false;
|
||||
has_sdd1 = false;
|
||||
has_spc7110 = false;
|
||||
has_cx4 = false;
|
||||
has_dsp1 = false;
|
||||
has_dsp2 = false;
|
||||
has_dsp3 = false;
|
||||
has_dsp4 = false;
|
||||
has_obc1 = false;
|
||||
has_st010 = false;
|
||||
has_st011 = false;
|
||||
has_st018 = false;
|
||||
|
||||
//=====================
|
||||
//detect Game Boy carts
|
||||
//=====================
|
||||
|
||||
if(size >= 0x0140) {
|
||||
if(data[0x0104] == 0xce && data[0x0105] == 0xed && data[0x0106] == 0x66 && data[0x0107] == 0x66
|
||||
&& data[0x0108] == 0xcc && data[0x0109] == 0x0d && data[0x010a] == 0x00 && data[0x010b] == 0x0b) {
|
||||
type = TypeGameBoy;
|
||||
type = Type::GameBoy;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if(size < 32768) {
|
||||
type = TypeUnknown;
|
||||
return;
|
||||
}
|
||||
|
||||
const uint index = findHeader(data, size);
|
||||
const uint8 mapperid = data[index + Mapper];
|
||||
const uint8 rom_type = data[index + RomType];
|
||||
|
@ -549,63 +500,51 @@ auto SuperFamicomCartridge::readHeader(const uint8* data, uint size) -> void {
|
|||
const uint8 company = data[index + Company];
|
||||
const uint8 regionid = data[index + CartRegion] & 0x7f;
|
||||
|
||||
this->rom_size = size;
|
||||
ram_size = 1024 << (data[index + RamSize] & 7);
|
||||
if(ram_size == 1024) ram_size = 0; //no RAM present
|
||||
if(rom_size == 0 && ram_size) ram_size = 0; //fix for Bazooka Blitzkrieg's malformed header (swapped ROM and RAM sizes)
|
||||
|
||||
//0, 1, 13 = NTSC; 2 - 12 = PAL
|
||||
region = (regionid <= 1 || regionid >= 13) ? NTSC : PAL;
|
||||
region = (regionid <= 1 || regionid >= 13) ? Region::NTSC : Region::PAL;
|
||||
|
||||
//=======================
|
||||
//detect BS-X flash carts
|
||||
//=======================
|
||||
|
||||
if(data[index + 0x13] == 0x00 || data[index + 0x13] == 0xff) {
|
||||
if(data[index + 0x14] == 0x00) {
|
||||
const uint8 n15 = data[index + 0x15];
|
||||
if(n15 == 0x00 || n15 == 0x80 || n15 == 0x84 || n15 == 0x9c || n15 == 0xbc || n15 == 0xfc) {
|
||||
if(data[index + 0x1a] == 0x33 || data[index + 0x1a] == 0xff) {
|
||||
type = TypeBsx;
|
||||
mapper = BSXROM;
|
||||
region = NTSC; //BS-X only released in Japan
|
||||
type = Type::Satellaview;
|
||||
region = Region::NTSC; //BS-X only released in Japan
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//=========================
|
||||
//detect Sufami Turbo carts
|
||||
//=========================
|
||||
|
||||
if(!memcmp(data, "BANDAI SFC-ADX", 14)) {
|
||||
if(!memcmp(data + 16, "SFC-ADX BACKUP", 14)) {
|
||||
type = TypeSufamiTurboBios;
|
||||
type = Type::SufamiTurboBIOS;
|
||||
} else {
|
||||
type = TypeSufamiTurbo;
|
||||
type = Type::SufamiTurbo;
|
||||
}
|
||||
mapper = STROM;
|
||||
region = NTSC; //Sufami Turbo only released in Japan
|
||||
return; //RAM size handled outside this routine
|
||||
region = Region::NTSC; //Sufami Turbo only released in Japan
|
||||
return; //RAM size handled outside this routine
|
||||
}
|
||||
|
||||
//==========================
|
||||
//detect Super Game Boy BIOS
|
||||
//==========================
|
||||
|
||||
if(!memcmp(data + index, "Super GAMEBOY2", 14)) {
|
||||
type = TypeSuperGameBoy2Bios;
|
||||
type = Type::SuperGameBoy2BIOS;
|
||||
return;
|
||||
}
|
||||
|
||||
if(!memcmp(data + index, "Super GAMEBOY", 13)) {
|
||||
type = TypeSuperGameBoy1Bios;
|
||||
type = Type::SuperGameBoy1BIOS;
|
||||
return;
|
||||
}
|
||||
|
||||
//=====================
|
||||
//detect standard carts
|
||||
//=====================
|
||||
|
||||
//detect presence of BS-X flash cartridge connector (reads extended header information)
|
||||
if(data[index - 14] == 'Z') {
|
||||
|
@ -622,42 +561,38 @@ auto SuperFamicomCartridge::readHeader(const uint8* data, uint size) -> void {
|
|||
if(has_bsx_slot) {
|
||||
if(!memcmp(data + index, "Satellaview BS-X ", 21)) {
|
||||
//BS-X base cart
|
||||
type = TypeBsxBios;
|
||||
mapper = BSXROM;
|
||||
region = NTSC; //BS-X only released in Japan
|
||||
return; //RAM size handled internally by load_cart_bsx() -> BSXCart class
|
||||
type = Type::SatellaviewBIOS;
|
||||
region = Region::NTSC; //BS-X only released in Japan
|
||||
return; //RAM size handled internally by load_cart_bsx() -> BSXCart class
|
||||
} else {
|
||||
type = TypeBsxSlotted;
|
||||
mapper = (index == 0x7fc0 ? BSCLoROM : BSCHiROM);
|
||||
region = NTSC; //BS-X slotted cartridges only released in Japan
|
||||
type = (index == 0x7fc0 ? Type::LoROMSatellaview : Type::HiROMSatellaview);
|
||||
region = Region::NTSC; //BS-X slotted cartridges only released in Japan
|
||||
}
|
||||
} else {
|
||||
//standard cart
|
||||
type = TypeNormal;
|
||||
|
||||
if(index == 0x7fc0 && size >= 0x401000) {
|
||||
mapper = ExLoROM;
|
||||
type = Type::ExLoROM;
|
||||
} else if(index == 0x7fc0 && mapperid == 0x32) {
|
||||
mapper = ExLoROM;
|
||||
type = Type::ExLoROM;
|
||||
} else if(index == 0x7fc0) {
|
||||
mapper = LoROM;
|
||||
type = Type::LoROM;
|
||||
} else if(index == 0xffc0) {
|
||||
mapper = HiROM;
|
||||
type = Type::HiROM;
|
||||
} else { //index == 0x40ffc0
|
||||
mapper = ExHiROM;
|
||||
type = Type::ExHiROM;
|
||||
}
|
||||
}
|
||||
|
||||
if(mapperid == 0x20 && (rom_type == 0x13 || rom_type == 0x14 || rom_type == 0x15 || rom_type == 0x1a)) {
|
||||
has_superfx = true;
|
||||
mapper = SuperFXROM;
|
||||
type = Type::SuperFX;
|
||||
ram_size = 1024 << (data[index - 3] & 7);
|
||||
if(ram_size == 1024) ram_size = 0;
|
||||
}
|
||||
|
||||
if(mapperid == 0x23 && (rom_type == 0x32 || rom_type == 0x34 || rom_type == 0x35)) {
|
||||
has_sa1 = true;
|
||||
mapper = SA1ROM;
|
||||
type = Type::SA1;
|
||||
}
|
||||
|
||||
if(mapperid == 0x35 && rom_type == 0x55) {
|
||||
|
@ -671,7 +606,6 @@ auto SuperFamicomCartridge::readHeader(const uint8* data, uint size) -> void {
|
|||
if(mapperid == 0x3a && (rom_type == 0xf5 || rom_type == 0xf9)) {
|
||||
has_spc7110 = true;
|
||||
has_epsonrtc = (rom_type == 0xf9);
|
||||
mapper = SPC7110ROM;
|
||||
}
|
||||
|
||||
if(mapperid == 0x20 && rom_type == 0xf3) {
|
||||
|
@ -692,11 +626,11 @@ auto SuperFamicomCartridge::readHeader(const uint8* data, uint size) -> void {
|
|||
|
||||
if(has_dsp1 == true) {
|
||||
if((mapperid & 0x2f) == 0x20 && size <= 0x100000) {
|
||||
dsp1_mapper = DSP1LoROM1MB;
|
||||
dsp1_type = DSP1Type::LoROM1MB;
|
||||
} else if((mapperid & 0x2f) == 0x20) {
|
||||
dsp1_mapper = DSP1LoROM2MB;
|
||||
dsp1_type = DSP1Type::LoROM2MB;
|
||||
} else if((mapperid & 0x2f) == 0x21) {
|
||||
dsp1_mapper = DSP1HiROM;
|
||||
dsp1_type = DSP1Type::HiROM;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -19,7 +19,7 @@ Settings settings;
|
|||
#include "heuristics/super-famicom.hpp"
|
||||
#include "heuristics/game-boy.hpp"
|
||||
#include "heuristics/game-boy-advance.hpp"
|
||||
#include "heuristics/bsx-satellaview.hpp"
|
||||
#include "heuristics/bs-memory.hpp"
|
||||
#include "heuristics/sufami-turbo.hpp"
|
||||
|
||||
#include "core/core.hpp"
|
||||
|
@ -29,7 +29,7 @@ Settings settings;
|
|||
#include "core/game-boy.cpp"
|
||||
#include "core/game-boy-color.cpp"
|
||||
#include "core/game-boy-advance.cpp"
|
||||
#include "core/bsx-satellaview.cpp"
|
||||
#include "core/bs-memory.cpp"
|
||||
#include "core/sufami-turbo.cpp"
|
||||
Icarus icarus;
|
||||
|
||||
|
|
|
@ -1,14 +1,14 @@
|
|||
sfc_objects := sfc-interface sfc-system sfc-controller
|
||||
sfc_objects += sfc-cartridge sfc-cheat
|
||||
sfc_objects += sfc-memory sfc-cpu sfc-smp sfc-dsp sfc-ppu
|
||||
sfc_objects += sfc-eboot sfc-satellaviewbase
|
||||
sfc_objects += sfc-satellaview sfc-eboot
|
||||
sfc_objects += sfc-icd2 sfc-mcc sfc-nss sfc-event
|
||||
sfc_objects += sfc-sa1 sfc-superfx
|
||||
sfc_objects += sfc-armdsp sfc-hitachidsp sfc-necdsp
|
||||
sfc_objects += sfc-epsonrtc sfc-sharprtc
|
||||
sfc_objects += sfc-spc7110 sfc-sdd1 sfc-obc1
|
||||
sfc_objects += sfc-msu1
|
||||
sfc_objects += sfc-satellaviewcart sfc-sufamiturbo
|
||||
sfc_objects += sfc-bsmemory sfc-sufamiturbo
|
||||
objects += $(sfc_objects)
|
||||
|
||||
ifeq ($(profile),accuracy)
|
||||
|
@ -33,40 +33,40 @@ else
|
|||
$(error unknown Super Famicom profile)
|
||||
endif
|
||||
|
||||
obj/sfc-interface.o: $(sfc)/interface/interface.cpp $(call rwildcard,$(sfc)/interface)
|
||||
obj/sfc-system.o: $(sfc)/system/system.cpp $(call rwildcard,$(sfc)/system/)
|
||||
obj/sfc-controller.o: $(sfc)/controller/controller.cpp $(call rwildcard,$(sfc)/controller/)
|
||||
obj/sfc-cartridge.o: $(sfc)/cartridge/cartridge.cpp $(call rwildcard,$(sfc)/cartridge/)
|
||||
obj/sfc-cheat.o: $(sfc)/cheat/cheat.cpp $(call rwildcard,$(sfc)/cheat/)
|
||||
obj/sfc-memory.o: $(sfc)/memory/memory.cpp $(call rwildcard,$(sfc)/memory/)
|
||||
obj/sfc-cpu.o: $(sfccpu)/cpu.cpp $(call rwildcard,$(sfccpu)/)
|
||||
obj/sfc-smp.o: $(sfcsmp)/smp.cpp $(call rwildcard,$(sfcsmp)/)
|
||||
obj/sfc-dsp.o: $(sfcdsp)/dsp.cpp $(call rwildcard,$(sfcdsp)/)
|
||||
obj/sfc-ppu.o: $(sfcppu)/ppu.cpp $(call rwildcard,$(sfcppu)/)
|
||||
obj/sfc-interface.o: $(sfc)/interface/interface.cpp $(call rwildcard,$(sfc)/interface)
|
||||
obj/sfc-system.o: $(sfc)/system/system.cpp $(call rwildcard,$(sfc)/system/)
|
||||
obj/sfc-controller.o: $(sfc)/controller/controller.cpp $(call rwildcard,$(sfc)/controller/)
|
||||
obj/sfc-cartridge.o: $(sfc)/cartridge/cartridge.cpp $(call rwildcard,$(sfc)/cartridge/)
|
||||
obj/sfc-cheat.o: $(sfc)/cheat/cheat.cpp $(call rwildcard,$(sfc)/cheat/)
|
||||
obj/sfc-memory.o: $(sfc)/memory/memory.cpp $(call rwildcard,$(sfc)/memory/)
|
||||
obj/sfc-cpu.o: $(sfccpu)/cpu.cpp $(call rwildcard,$(sfccpu)/)
|
||||
obj/sfc-smp.o: $(sfcsmp)/smp.cpp $(call rwildcard,$(sfcsmp)/)
|
||||
obj/sfc-dsp.o: $(sfcdsp)/dsp.cpp $(call rwildcard,$(sfcdsp)/)
|
||||
obj/sfc-ppu.o: $(sfcppu)/ppu.cpp $(call rwildcard,$(sfcppu)/)
|
||||
|
||||
obj/sfc-eboot.o: $(sfc)/expansion/eboot/eboot.cpp $(call rwildcard,$(sfc)/expansion/eboot/)
|
||||
obj/sfc-satellaviewbase.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-eboot.o: $(sfc)/expansion/eboot/eboot.cpp $(call rwildcard,$(sfc)/expansion/eboot/)
|
||||
|
||||
obj/sfc-icd2.o: $(sfc)/coprocessor/icd2/icd2.cpp $(call rwildcard,$(sfc)/coprocessor/icd2/)
|
||||
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-event.o: $(sfc)/coprocessor/event/event.cpp $(call rwildcard,$(sfc)/coprocessor/event/)
|
||||
obj/sfc-icd2.o: $(sfc)/coprocessor/icd2/icd2.cpp $(call rwildcard,$(sfc)/coprocessor/icd2/)
|
||||
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-event.o: $(sfc)/coprocessor/event/event.cpp $(call rwildcard,$(sfc)/coprocessor/event/)
|
||||
|
||||
obj/sfc-sa1.o: $(sfc)/coprocessor/sa1/sa1.cpp $(call rwildcard,$(sfc)/coprocessor/sa1/)
|
||||
obj/sfc-superfx.o: $(sfc)/coprocessor/superfx/superfx.cpp $(call rwildcard,$(sfc)/coprocessor/superfx/)
|
||||
obj/sfc-sa1.o: $(sfc)/coprocessor/sa1/sa1.cpp $(call rwildcard,$(sfc)/coprocessor/sa1/)
|
||||
obj/sfc-superfx.o: $(sfc)/coprocessor/superfx/superfx.cpp $(call rwildcard,$(sfc)/coprocessor/superfx/)
|
||||
|
||||
obj/sfc-armdsp.o: $(sfc)/coprocessor/armdsp/armdsp.cpp $(call rwildcard,$(sfc)/coprocessor/armdsp/)
|
||||
obj/sfc-hitachidsp.o: $(sfc)/coprocessor/hitachidsp/hitachidsp.cpp $(call rwildcard,$(sfc)/coprocessor/hitachidsp/)
|
||||
obj/sfc-necdsp.o: $(sfc)/coprocessor/necdsp/necdsp.cpp $(call rwildcard,$(sfc)/coprocessor/necdsp/)
|
||||
obj/sfc-armdsp.o: $(sfc)/coprocessor/armdsp/armdsp.cpp $(call rwildcard,$(sfc)/coprocessor/armdsp/)
|
||||
obj/sfc-hitachidsp.o: $(sfc)/coprocessor/hitachidsp/hitachidsp.cpp $(call rwildcard,$(sfc)/coprocessor/hitachidsp/)
|
||||
obj/sfc-necdsp.o: $(sfc)/coprocessor/necdsp/necdsp.cpp $(call rwildcard,$(sfc)/coprocessor/necdsp/)
|
||||
|
||||
obj/sfc-epsonrtc.o: $(sfc)/coprocessor/epsonrtc/epsonrtc.cpp $(call rwildcard,$(sfc)/coprocessor/epsonrtc/)
|
||||
obj/sfc-sharprtc.o: $(sfc)/coprocessor/sharprtc/sharprtc.cpp $(call rwildcard,$(sfc)/coprocessor/sharprtc/)
|
||||
obj/sfc-epsonrtc.o: $(sfc)/coprocessor/epsonrtc/epsonrtc.cpp $(call rwildcard,$(sfc)/coprocessor/epsonrtc/)
|
||||
obj/sfc-sharprtc.o: $(sfc)/coprocessor/sharprtc/sharprtc.cpp $(call rwildcard,$(sfc)/coprocessor/sharprtc/)
|
||||
|
||||
obj/sfc-spc7110.o: $(sfc)/coprocessor/spc7110/spc7110.cpp $(call rwildcard,$(sfc)/coprocessor/spc7110/)
|
||||
obj/sfc-sdd1.o: $(sfc)/coprocessor/sdd1/sdd1.cpp $(call rwildcard,$(sfc)/coprocessor/sdd1/)
|
||||
obj/sfc-obc1.o: $(sfc)/coprocessor/obc1/obc1.cpp $(call rwildcard,$(sfc)/coprocessor/obc1/)
|
||||
obj/sfc-spc7110.o: $(sfc)/coprocessor/spc7110/spc7110.cpp $(call rwildcard,$(sfc)/coprocessor/spc7110/)
|
||||
obj/sfc-sdd1.o: $(sfc)/coprocessor/sdd1/sdd1.cpp $(call rwildcard,$(sfc)/coprocessor/sdd1/)
|
||||
obj/sfc-obc1.o: $(sfc)/coprocessor/obc1/obc1.cpp $(call rwildcard,$(sfc)/coprocessor/obc1/)
|
||||
|
||||
obj/sfc-msu1.o: $(sfc)/coprocessor/msu1/msu1.cpp $(call rwildcard,$(sfc)/coprocessor/msu1/)
|
||||
obj/sfc-msu1.o: $(sfc)/coprocessor/msu1/msu1.cpp $(call rwildcard,$(sfc)/coprocessor/msu1/)
|
||||
|
||||
obj/sfc-satellaviewcart.o: $(sfc)/slot/satellaview/satellaview.cpp $(call rwildcard,$(sfc)/slot/satellaview/)
|
||||
obj/sfc-sufamiturbo.o: $(sfc)/slot/sufamiturbo/sufamiturbo.cpp $(call rwildcard,$(sfc)/slot/sufamiturbo/)
|
||||
obj/sfc-bsmemory.o: $(sfc)/slot/bsmemory/bsmemory.cpp $(call rwildcard,$(sfc)/slot/bsmemory/)
|
||||
obj/sfc-sufamiturbo.o: $(sfc)/slot/sufamiturbo/sufamiturbo.cpp $(call rwildcard,$(sfc)/slot/sufamiturbo/)
|
||||
|
|
|
@ -10,22 +10,22 @@ auto Cartridge::manifest() -> string {
|
|||
string manifest = information.markup.cartridge;
|
||||
|
||||
if(information.markup.gameBoy) {
|
||||
manifest.append("\n[Super Game Boy]\n");
|
||||
manifest.append("\n[[Game Boy]]\n\n");
|
||||
manifest.append(information.markup.gameBoy);
|
||||
}
|
||||
|
||||
if(information.markup.satellaview) {
|
||||
manifest.append("\n[BS-X Satellaview]\n");
|
||||
manifest.append(information.markup.satellaview);
|
||||
if(information.markup.bsMemory) {
|
||||
manifest.append("\n[[BS Memory]]\n\n");
|
||||
manifest.append(information.markup.bsMemory);
|
||||
}
|
||||
|
||||
if(information.markup.sufamiTurboA) {
|
||||
manifest.append("\n[Sufami Turbo - Slot A]\n");
|
||||
manifest.append("\n[[Sufami Turbo - Slot A]]\n\n");
|
||||
manifest.append(information.markup.sufamiTurboA);
|
||||
}
|
||||
|
||||
if(information.markup.sufamiTurboB) {
|
||||
manifest.append("\n[Sufami Turbo - Slot B]\n");
|
||||
manifest.append("\n[[Sufami Turbo - Slot B]]\n\n");
|
||||
manifest.append(information.markup.sufamiTurboB);
|
||||
}
|
||||
|
||||
|
@ -39,8 +39,8 @@ auto Cartridge::title() -> string {
|
|||
title.append(" + ", information.title.gameBoy);
|
||||
}
|
||||
|
||||
if(information.title.satellaview) {
|
||||
title.append(" + ", information.title.satellaview);
|
||||
if(information.title.bsMemory) {
|
||||
title.append(" + ", information.title.bsMemory);
|
||||
}
|
||||
|
||||
if(information.title.sufamiTurboA) {
|
||||
|
@ -73,33 +73,33 @@ auto Cartridge::load() -> void {
|
|||
hasOBC1 = false;
|
||||
hasMSU1 = false;
|
||||
|
||||
hasSuperGameBoySlot = false;
|
||||
hasSatellaviewSlot = false;
|
||||
hasGameBoySlot = false;
|
||||
hasBSMemorySlot = false;
|
||||
hasSufamiTurboSlots = false;
|
||||
|
||||
information.markup.cartridge = "";
|
||||
information.markup.gameBoy = "";
|
||||
information.markup.satellaview = "";
|
||||
information.markup.bsMemory = "";
|
||||
information.markup.sufamiTurboA = "";
|
||||
information.markup.sufamiTurboB = "";
|
||||
|
||||
information.title.cartridge = "";
|
||||
information.title.gameBoy = "";
|
||||
information.title.satellaview = "";
|
||||
information.title.bsMemory = "";
|
||||
information.title.sufamiTurboA = "";
|
||||
information.title.sufamiTurboB = "";
|
||||
|
||||
interface->loadRequest(ID::Manifest, "manifest.bml", true);
|
||||
parseMarkup(information.markup.cartridge);
|
||||
|
||||
//Super Game Boy
|
||||
//Game Boy
|
||||
if(cartridge.hasICD2()) {
|
||||
_sha256 = Hash::SHA256(GameBoy::cartridge.romdata, GameBoy::cartridge.romsize).digest();
|
||||
}
|
||||
|
||||
//Broadcast Satellaview
|
||||
else if(cartridge.hasMCC() && cartridge.hasSatellaviewSlot()) {
|
||||
_sha256 = Hash::SHA256(satellaviewcartridge.memory.data(), satellaviewcartridge.memory.size()).digest();
|
||||
//BS Memory
|
||||
else if(cartridge.hasMCC() && cartridge.hasBSMemorySlot()) {
|
||||
_sha256 = Hash::SHA256(bsmemory.memory.data(), bsmemory.memory.size()).digest();
|
||||
}
|
||||
|
||||
//Sufami Turbo
|
||||
|
@ -141,8 +141,8 @@ auto Cartridge::load() -> void {
|
|||
_loaded = true;
|
||||
}
|
||||
|
||||
auto Cartridge::loadSuperGameBoy() -> void {
|
||||
interface->loadRequest(ID::SuperGameBoyManifest, "manifest.bml", true);
|
||||
auto Cartridge::loadGameBoy() -> void {
|
||||
interface->loadRequest(ID::GameBoyManifest, "manifest.bml", true);
|
||||
auto document = BML::unserialize(information.markup.gameBoy);
|
||||
information.title.gameBoy = document["information/title"].text();
|
||||
|
||||
|
@ -152,24 +152,24 @@ auto Cartridge::loadSuperGameBoy() -> void {
|
|||
GameBoy::cartridge.information.markup = information.markup.gameBoy;
|
||||
GameBoy::cartridge.load(GameBoy::System::Revision::SuperGameBoy);
|
||||
|
||||
if(auto name = rom["name"].text()) interface->loadRequest(ID::SuperGameBoyROM, name, true);
|
||||
if(auto name = ram["name"].text()) interface->loadRequest(ID::SuperGameBoyRAM, name, false);
|
||||
if(auto name = ram["name"].text()) memory.append({ID::SuperGameBoyRAM, name});
|
||||
if(auto name = rom["name"].text()) interface->loadRequest(ID::GameBoyROM, name, true);
|
||||
if(auto name = ram["name"].text()) interface->loadRequest(ID::GameBoyRAM, name, false);
|
||||
if(auto name = ram["name"].text()) memory.append({ID::GameBoyRAM, name});
|
||||
}
|
||||
|
||||
auto Cartridge::loadSatellaview() -> void {
|
||||
interface->loadRequest(ID::SatellaviewManifest, "manifest.bml", true);
|
||||
auto document = BML::unserialize(information.markup.satellaview);
|
||||
information.title.satellaview = document["information/title"].text();
|
||||
auto Cartridge::loadBSMemory() -> void {
|
||||
interface->loadRequest(ID::BSMemoryManifest, "manifest.bml", true);
|
||||
auto document = BML::unserialize(information.markup.bsMemory);
|
||||
information.title.bsMemory = document["information/title"].text();
|
||||
|
||||
auto rom = document["board/rom"];
|
||||
|
||||
if(rom["name"]) {
|
||||
unsigned size = rom["size"].natural();
|
||||
satellaviewcartridge.memory.map(allocate<uint8>(size, 0xff), size);
|
||||
interface->loadRequest(ID::SatellaviewROM, rom["name"].text(), true);
|
||||
uint size = rom["size"].natural();
|
||||
bsmemory.memory.map(allocate<uint8>(size, 0xff), size);
|
||||
interface->loadRequest(ID::BSMemoryROM, rom["name"].text(), true);
|
||||
|
||||
satellaviewcartridge.readonly = (rom["type"].text() == "MaskROM");
|
||||
bsmemory.readonly = (rom["type"].text() == "mrom");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -195,7 +195,7 @@ auto Cartridge::loadSufamiTurboA() -> void {
|
|||
}
|
||||
|
||||
if(document["board/linkable"]) {
|
||||
interface->loadRequest(ID::SufamiTurboSlotB, "Sufami Turbo - Slot B", "st", false);
|
||||
interface->loadRequest(ID::SufamiTurboSlotB, "Sufami Turbo", "st", false);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -24,8 +24,8 @@ struct Cartridge : property<Cartridge> {
|
|||
readonly<bool> hasOBC1;
|
||||
readonly<bool> hasMSU1;
|
||||
|
||||
readonly<bool> hasSuperGameBoySlot;
|
||||
readonly<bool> hasSatellaviewSlot;
|
||||
readonly<bool> hasGameBoySlot;
|
||||
readonly<bool> hasBSMemorySlot;
|
||||
readonly<bool> hasSufamiTurboSlots;
|
||||
|
||||
auto manifest() -> string;
|
||||
|
@ -63,7 +63,7 @@ struct Cartridge : property<Cartridge> {
|
|||
struct Markup {
|
||||
string cartridge;
|
||||
string gameBoy;
|
||||
string satellaview;
|
||||
string bsMemory;
|
||||
string sufamiTurboA;
|
||||
string sufamiTurboB;
|
||||
} markup;
|
||||
|
@ -71,15 +71,15 @@ struct Cartridge : property<Cartridge> {
|
|||
struct Title {
|
||||
string cartridge;
|
||||
string gameBoy;
|
||||
string satellaview;
|
||||
string bsMemory;
|
||||
string sufamiTurboA;
|
||||
string sufamiTurboB;
|
||||
} title;
|
||||
} information;
|
||||
|
||||
private:
|
||||
auto loadSuperGameBoy() -> void;
|
||||
auto loadSatellaview() -> void;
|
||||
auto loadGameBoy() -> void;
|
||||
auto loadBSMemory() -> void;
|
||||
auto loadSufamiTurboA() -> void;
|
||||
auto loadSufamiTurboB() -> void;
|
||||
friend class Interface;
|
||||
|
@ -94,7 +94,7 @@ private:
|
|||
auto parseMarkupRAM(Markup::Node) -> void;
|
||||
auto parseMarkupICD2(Markup::Node) -> void;
|
||||
auto parseMarkupMCC(Markup::Node) -> void;
|
||||
auto parseMarkupSatellaview(Markup::Node) -> void;
|
||||
auto parseMarkupBSMemory(Markup::Node) -> void;
|
||||
auto parseMarkupSufamiTurbo(Markup::Node, bool slot) -> void;
|
||||
auto parseMarkupNSS(Markup::Node) -> void;
|
||||
auto parseMarkupEvent(Markup::Node) -> void;
|
||||
|
|
|
@ -21,7 +21,7 @@ auto Cartridge::parseMarkup(const string& markup) -> void {
|
|||
if(auto node = board["ram"]) parseMarkupRAM(node);
|
||||
if(auto node = board["icd2"]) parseMarkupICD2(node);
|
||||
if(auto node = board["mcc"]) parseMarkupMCC(node);
|
||||
if(auto node = board["satellaview"]) parseMarkupSatellaview(node);
|
||||
if(auto node = board["bsmemory"]) parseMarkupBSMemory(node);
|
||||
if(auto node = board.find("sufamiturbo")) if(node(0)) parseMarkupSufamiTurbo(node(0), 0);
|
||||
if(auto node = board.find("sufamiturbo")) if(node(1)) parseMarkupSufamiTurbo(node(1), 1);
|
||||
if(auto node = board["nss"]) parseMarkupNSS(node);
|
||||
|
@ -88,12 +88,12 @@ auto Cartridge::parseMarkupRAM(Markup::Node root) -> void {
|
|||
}
|
||||
|
||||
auto Cartridge::parseMarkupICD2(Markup::Node root) -> void {
|
||||
hasSuperGameBoySlot = true;
|
||||
hasGameBoySlot = true;
|
||||
hasICD2 = true;
|
||||
icd2.revision = max(1, root["revision"].natural());
|
||||
|
||||
GameBoy::cartridge.load_empty(GameBoy::System::Revision::SuperGameBoy);
|
||||
interface->loadRequest(ID::SuperGameBoy, "Game Boy", "gb", false);
|
||||
interface->loadRequest(ID::GameBoy, "Game Boy", "gb", false);
|
||||
|
||||
interface->loadRequest(ID::SuperGameBoyBootROM, root["brom"]["name"].text(), true);
|
||||
|
||||
|
@ -103,10 +103,10 @@ auto Cartridge::parseMarkupICD2(Markup::Node root) -> void {
|
|||
}
|
||||
|
||||
auto Cartridge::parseMarkupMCC(Markup::Node root) -> void {
|
||||
hasSatellaviewSlot = true;
|
||||
hasBSMemorySlot = true;
|
||||
hasMCC = true;
|
||||
|
||||
interface->loadRequest(ID::Satellaview, "BS-X Satellaview", "bs", false);
|
||||
interface->loadRequest(ID::BSMemory, "BS Memory", "bs", false);
|
||||
|
||||
parseMarkupMemory(mcc.rom, root["rom"], ID::MCCROM, false);
|
||||
parseMarkupMemory(mcc.ram, root["ram"], ID::MCCRAM, true);
|
||||
|
@ -124,14 +124,14 @@ auto Cartridge::parseMarkupMCC(Markup::Node root) -> void {
|
|||
}
|
||||
}
|
||||
|
||||
auto Cartridge::parseMarkupSatellaview(Markup::Node root) -> void {
|
||||
hasSatellaviewSlot = true;
|
||||
auto Cartridge::parseMarkupBSMemory(Markup::Node root) -> void {
|
||||
hasBSMemorySlot = true;
|
||||
|
||||
interface->loadRequest(ID::Satellaview, "BS-X Satellaview", "bs", false);
|
||||
interface->loadRequest(ID::BSMemory, "BS Memory", "bs", false);
|
||||
|
||||
for(auto node : root["rom"].find("map")) {
|
||||
if(satellaviewcartridge.memory.size() == 0) continue;
|
||||
parseMarkupMap(node, satellaviewcartridge);
|
||||
for(auto node : root.find("map")) {
|
||||
if(bsmemory.memory.size() == 0) continue;
|
||||
parseMarkupMap(node, bsmemory);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -140,7 +140,7 @@ auto Cartridge::parseMarkupSufamiTurbo(Markup::Node root, bool slot) -> void {
|
|||
|
||||
if(slot == 0) {
|
||||
//load required slot A (will request slot B if slot A cartridge is linkable)
|
||||
interface->loadRequest(ID::SufamiTurboSlotA, "Sufami Turbo - Slot A", "st", false);
|
||||
interface->loadRequest(ID::SufamiTurboSlotA, "Sufami Turbo", "st", false);
|
||||
}
|
||||
|
||||
for(auto node : root["rom"].find("map")) {
|
||||
|
|
|
@ -35,7 +35,18 @@ auto MCC::memory_access(bool write, Memory& memory, uint addr, uint8 data) -> ui
|
|||
}
|
||||
}
|
||||
|
||||
//map address=00-3f,80-bf:8000-ffff mask=0x408000
|
||||
//map address=40-7d,c0-ff:0000-ffff
|
||||
auto MCC::mcu_access(bool write, uint addr, uint8 data) -> uint8 {
|
||||
if(addr < 0x400000) {
|
||||
//note: manifest maps 00-3f,80-bf:8000-ffff mask=0x408000 => 00-3f:0000-ffff
|
||||
//the intention is consistency in pre-decoding as much as possible
|
||||
//however, the MCC code is intended to be rewritten; and is too convoluted
|
||||
//so for right now, I'm simply transforming it back to its original state
|
||||
//this is very wasteful; but will be addressed once things are rewritten
|
||||
addr = ((addr & 0x200000) << 2) | ((addr & 0x1f8000) << 1) | 0x8000 | (addr & 0x7fff);
|
||||
}
|
||||
|
||||
if((addr & 0xe08000) == 0x008000) { //$00-1f:8000-ffff
|
||||
if(r07 == 1) {
|
||||
addr = ((addr & 0x1f0000) >> 1) | (addr & 0x7fff);
|
||||
|
@ -70,7 +81,7 @@ auto MCC::mcu_access(bool write, uint addr, uint8 data) -> uint8 {
|
|||
|| ((addr & 0x400000) == 0x400000) //$40-7f,c0-ff:0000-ffff
|
||||
) {
|
||||
if(r02 == 0) addr = ((addr & 0x7f0000) >> 1) | (addr & 0x7fff);
|
||||
Memory& memory = (r01 == 0 ? (Memory&)satellaviewcartridge : (Memory&)ram);
|
||||
Memory& memory = (r01 == 0 ? (Memory&)bsmemory : (Memory&)ram);
|
||||
return memory_access(write, memory, addr & 0x7fffff, data);
|
||||
}
|
||||
|
||||
|
|
|
@ -17,10 +17,10 @@ Interface::Interface() {
|
|||
information.capability.states = true;
|
||||
information.capability.cheats = true;
|
||||
|
||||
media.append({ID::SuperFamicom, "Super Famicom", "sfc", true });
|
||||
media.append({ID::SuperFamicom, "Game Boy", "gb", false});
|
||||
media.append({ID::SuperFamicom, "BS-X Satellaview", "bs", false});
|
||||
media.append({ID::SuperFamicom, "Sufami Turbo", "st", false});
|
||||
media.append({ID::SuperFamicom, "Super Famicom", "sfc", true });
|
||||
media.append({ID::SuperFamicom, "Game Boy", "gb", false});
|
||||
media.append({ID::SuperFamicom, "BS Memory", "bs", false});
|
||||
media.append({ID::SuperFamicom, "Sufami Turbo", "st", false});
|
||||
|
||||
{ Device device{0, ID::ControllerPort1 | ID::ControllerPort2 | ID::ExpansionPort, "None"};
|
||||
this->device.append(device);
|
||||
|
@ -201,14 +201,14 @@ auto Interface::group(uint id) -> uint {
|
|||
case ID::MCCROM:
|
||||
case ID::MCCRAM:
|
||||
return 1;
|
||||
case ID::SuperGameBoy:
|
||||
case ID::SuperGameBoyManifest:
|
||||
case ID::SuperGameBoyROM:
|
||||
case ID::SuperGameBoyRAM:
|
||||
case ID::GameBoy:
|
||||
case ID::GameBoyManifest:
|
||||
case ID::GameBoyROM:
|
||||
case ID::GameBoyRAM:
|
||||
return 2;
|
||||
case ID::Satellaview:
|
||||
case ID::SatellaviewManifest:
|
||||
case ID::SatellaviewROM:
|
||||
case ID::BSMemory:
|
||||
case ID::BSMemoryManifest:
|
||||
case ID::BSMemoryROM:
|
||||
return 3;
|
||||
case ID::SufamiTurboSlotA:
|
||||
case ID::SufamiTurboSlotAManifest:
|
||||
|
@ -227,8 +227,8 @@ auto Interface::group(uint id) -> uint {
|
|||
|
||||
auto Interface::load(uint id) -> void {
|
||||
if(id == ID::SuperFamicom) cartridge.load();
|
||||
if(id == ID::SuperGameBoy) cartridge.loadSuperGameBoy();
|
||||
if(id == ID::Satellaview) cartridge.loadSatellaview();
|
||||
if(id == ID::GameBoy) cartridge.loadGameBoy();
|
||||
if(id == ID::BSMemory) cartridge.loadBSMemory();
|
||||
if(id == ID::SufamiTurboSlotA) cartridge.loadSufamiTurboA();
|
||||
if(id == ID::SufamiTurboSlotB) cartridge.loadSufamiTurboB();
|
||||
}
|
||||
|
@ -331,18 +331,18 @@ auto Interface::load(uint id, const stream& stream) -> void {
|
|||
if(id == ID::MCCROM) mcc.rom.read(stream);
|
||||
if(id == ID::MCCRAM) mcc.ram.read(stream);
|
||||
|
||||
if(id == ID::SuperGameBoyManifest) cartridge.information.markup.gameBoy = stream.text();
|
||||
if(id == ID::GameBoyManifest) cartridge.information.markup.gameBoy = stream.text();
|
||||
|
||||
if(id == ID::SuperGameBoyROM) {
|
||||
if(id == ID::GameBoyROM) {
|
||||
stream.read(GameBoy::cartridge.romdata, min(GameBoy::cartridge.romsize, stream.size()));
|
||||
}
|
||||
|
||||
if(id == ID::SuperGameBoyRAM) {
|
||||
if(id == ID::GameBoyRAM) {
|
||||
stream.read(GameBoy::cartridge.ramdata, min(GameBoy::cartridge.ramsize, stream.size()));
|
||||
}
|
||||
|
||||
if(id == ID::SatellaviewManifest) cartridge.information.markup.satellaview = stream.text();
|
||||
if(id == ID::SatellaviewROM) satellaviewcartridge.memory.read(stream);
|
||||
if(id == ID::BSMemoryManifest) cartridge.information.markup.bsMemory = stream.text();
|
||||
if(id == ID::BSMemoryROM) bsmemory.memory.read(stream);
|
||||
|
||||
if(id == ID::SufamiTurboSlotAManifest) cartridge.information.markup.sufamiTurboA = stream.text();
|
||||
if(id == ID::SufamiTurboSlotAROM) sufamiturboA.rom.read(stream);
|
||||
|
@ -392,7 +392,7 @@ auto Interface::save(uint id, const stream& stream) -> void {
|
|||
if(id == ID::SDD1RAM) stream.write(sdd1.ram.data(), sdd1.ram.size());
|
||||
if(id == ID::OBC1RAM) stream.write(obc1.ram.data(), obc1.ram.size());
|
||||
|
||||
if(id == ID::SuperGameBoyRAM) stream.write(GameBoy::cartridge.ramdata, GameBoy::cartridge.ramsize);
|
||||
if(id == ID::GameBoyRAM) stream.write(GameBoy::cartridge.ramdata, GameBoy::cartridge.ramsize);
|
||||
|
||||
if(id == ID::MCCRAM) stream.write(mcc.ram.data(), mcc.ram.size());
|
||||
|
||||
|
|
|
@ -7,8 +7,8 @@ struct ID {
|
|||
//cartridges (folders)
|
||||
System,
|
||||
SuperFamicom,
|
||||
SuperGameBoy,
|
||||
Satellaview,
|
||||
GameBoy,
|
||||
BSMemory,
|
||||
SufamiTurboSlotA,
|
||||
SufamiTurboSlotB,
|
||||
|
||||
|
@ -67,12 +67,12 @@ struct ID {
|
|||
MCCROM,
|
||||
MCCRAM,
|
||||
|
||||
SuperGameBoyManifest,
|
||||
SuperGameBoyROM,
|
||||
SuperGameBoyRAM,
|
||||
GameBoyManifest,
|
||||
GameBoyROM,
|
||||
GameBoyRAM,
|
||||
|
||||
SatellaviewManifest,
|
||||
SatellaviewROM,
|
||||
BSMemoryManifest,
|
||||
BSMemoryROM,
|
||||
|
||||
SufamiTurboSlotAManifest,
|
||||
SufamiTurboSlotAROM,
|
||||
|
|
|
@ -2,25 +2,25 @@
|
|||
|
||||
namespace SuperFamicom {
|
||||
|
||||
SatellaviewCartridge satellaviewcartridge;
|
||||
BSMemory bsmemory;
|
||||
|
||||
auto SatellaviewCartridge::init() -> void {
|
||||
auto BSMemory::init() -> void {
|
||||
}
|
||||
|
||||
auto SatellaviewCartridge::load() -> void {
|
||||
auto BSMemory::load() -> void {
|
||||
if(memory.size() == 0) {
|
||||
memory.map(allocate<uint8>(1024 * 1024, 0xff), 1024 * 1024);
|
||||
}
|
||||
}
|
||||
|
||||
auto SatellaviewCartridge::unload() -> void {
|
||||
auto BSMemory::unload() -> void {
|
||||
memory.reset();
|
||||
}
|
||||
|
||||
auto SatellaviewCartridge::power() -> void {
|
||||
auto BSMemory::power() -> void {
|
||||
}
|
||||
|
||||
auto SatellaviewCartridge::reset() -> void {
|
||||
auto BSMemory::reset() -> void {
|
||||
regs.command = 0;
|
||||
regs.write_old = 0x00;
|
||||
regs.write_new = 0x00;
|
||||
|
@ -31,12 +31,14 @@ auto SatellaviewCartridge::reset() -> void {
|
|||
memory.write_protect(!regs.write_enable);
|
||||
}
|
||||
|
||||
auto SatellaviewCartridge::size() const -> uint {
|
||||
auto BSMemory::size() const -> uint {
|
||||
return memory.size();
|
||||
}
|
||||
|
||||
auto SatellaviewCartridge::read(uint addr, uint8 data) -> uint8 {
|
||||
if(readonly) return memory.read(bus.mirror(addr, memory.size()), data);
|
||||
auto BSMemory::read(uint addr, uint8 data) -> uint8 {
|
||||
if(readonly) {
|
||||
return memory.read(bus.mirror(addr, memory.size()), data);
|
||||
}
|
||||
|
||||
if(addr == 0x0002) {
|
||||
if(regs.flash_enable) return 0x80;
|
||||
|
@ -64,8 +66,10 @@ auto SatellaviewCartridge::read(uint addr, uint8 data) -> uint8 {
|
|||
return memory.read(addr, data);
|
||||
}
|
||||
|
||||
auto SatellaviewCartridge::write(uint addr, uint8 data) -> void {
|
||||
if(readonly) return;
|
||||
auto BSMemory::write(uint addr, uint8 data) -> void {
|
||||
if(readonly) {
|
||||
return;
|
||||
}
|
||||
|
||||
if((addr & 0xff0000) == 0) {
|
||||
regs.write_old = regs.write_new;
|
|
@ -1,4 +1,4 @@
|
|||
struct SatellaviewCartridge : Memory {
|
||||
struct BSMemory : Memory {
|
||||
auto init() -> void;
|
||||
auto load() -> void;
|
||||
auto unload() -> void;
|
||||
|
@ -24,4 +24,4 @@ private:
|
|||
} regs;
|
||||
};
|
||||
|
||||
extern SatellaviewCartridge satellaviewcartridge;
|
||||
extern BSMemory bsmemory;
|
|
@ -1,2 +1,2 @@
|
|||
#include <sfc/slot/satellaview/satellaview.hpp>
|
||||
#include <sfc/slot/bsmemory/bsmemory.hpp>
|
||||
#include <sfc/slot/sufamiturbo/sufamiturbo.hpp>
|
||||
|
|
|
@ -68,8 +68,8 @@ auto System::runThreadToSave() -> void {
|
|||
auto System::init() -> void {
|
||||
assert(interface != nullptr);
|
||||
|
||||
eboot.init();
|
||||
satellaview.init();
|
||||
eboot.init();
|
||||
|
||||
icd2.init();
|
||||
mcc.init();
|
||||
|
@ -87,7 +87,7 @@ auto System::init() -> void {
|
|||
obc1.init();
|
||||
msu1.init();
|
||||
|
||||
satellaviewcartridge.init();
|
||||
bsmemory.init();
|
||||
|
||||
video.init();
|
||||
audio.init();
|
||||
|
@ -142,7 +142,7 @@ auto System::load() -> void {
|
|||
if(cartridge.hasOBC1()) obc1.load();
|
||||
if(cartridge.hasMSU1()) msu1.load();
|
||||
|
||||
if(cartridge.hasSatellaviewSlot()) satellaviewcartridge.load();
|
||||
if(cartridge.hasBSMemorySlot()) bsmemory.load();
|
||||
if(cartridge.hasSufamiTurboSlots()) sufamiturboA.load(), sufamiturboB.load();
|
||||
|
||||
serializeInit();
|
||||
|
@ -168,7 +168,7 @@ auto System::unload() -> void {
|
|||
if(cartridge.hasOBC1()) obc1.unload();
|
||||
if(cartridge.hasMSU1()) msu1.unload();
|
||||
|
||||
if(cartridge.hasSatellaviewSlot()) satellaviewcartridge.unload();
|
||||
if(cartridge.hasBSMemorySlot()) bsmemory.unload();
|
||||
if(cartridge.hasSufamiTurboSlots()) sufamiturboA.unload(), sufamiturboB.unload();
|
||||
}
|
||||
|
||||
|
@ -199,7 +199,7 @@ auto System::power() -> void {
|
|||
if(cartridge.hasOBC1()) obc1.power();
|
||||
if(cartridge.hasMSU1()) msu1.power();
|
||||
|
||||
if(cartridge.hasSatellaviewSlot()) satellaviewcartridge.power();
|
||||
if(cartridge.hasBSMemorySlot()) bsmemory.power();
|
||||
|
||||
reset();
|
||||
}
|
||||
|
@ -229,7 +229,7 @@ auto System::reset() -> void {
|
|||
if(cartridge.hasOBC1()) obc1.reset();
|
||||
if(cartridge.hasMSU1()) msu1.reset();
|
||||
|
||||
if(cartridge.hasSatellaviewSlot()) satellaviewcartridge.reset();
|
||||
if(cartridge.hasBSMemorySlot()) bsmemory.reset();
|
||||
|
||||
if(cartridge.hasICD2()) cpu.coprocessors.append(&icd2);
|
||||
if(cartridge.hasEvent()) cpu.coprocessors.append(&event);
|
||||
|
|
|
@ -3,7 +3,7 @@ ManifestViewer::ManifestViewer(TabFrame* parent) : TabFrameItem(parent) {
|
|||
setText("Manifest Viewer");
|
||||
|
||||
layout.setMargin(5);
|
||||
manifestView.setEditable(false).setFont(Font().setFamily(Font::Mono));
|
||||
manifestView.setEditable(false).setWordWrap(false).setFont(Font().setFamily(Font::Mono));
|
||||
}
|
||||
|
||||
auto ManifestViewer::doRefresh() -> void {
|
||||
|
|
Loading…
Reference in New Issue