mirror of https://github.com/bsnes-emu/bsnes.git
Update to v106r14 release.
byuu says: Changelog: - game/memory/type/battery → game/memory/volatile - (manufacturer.)content.type → (architecture.)content.type - nall: Markup::find() strips spaces from values in comparisons - higan: updated game manifest loading/saving code for all cores - GBA: flash memory ID is internally selected based on the manufacturer and memory size - SFC: ST018 (ARM6) frequency can be modified via game manifest now - WS: EEPROM::name removed (not useful) - icarus, genius: battery→volatile updates I did my best to look over the diff between r13 and r14, but it's 84KiB excluding the game database changes. It's just too much for me. I'd greatly appreciate if someone could look over it and check for any errors in this update. But more than likely, I suppose we'll iron out any issues by determining which games fail to load. Right now, I know the Super Game Boy support doesn't seem to work. But all non-SFC cores should work fully, and all normal + NEC DSP SFC games should work as well. Unsure about the rest. Also, I'm planning to change the Game Boy “MBC1M” mapper to “MBC1#A” to indicate it's an alternate wiring configuration of the stock MBC1, and not a new mapper type.
This commit is contained in:
parent
eaa2c1f6c0
commit
8f61c267c5
|
@ -63,7 +63,6 @@ ListWindow::ListWindow() {
|
|||
reloadList();
|
||||
updateWindow();
|
||||
setCentered();
|
||||
setVisible();
|
||||
}
|
||||
|
||||
auto ListWindow::quit() -> void {
|
||||
|
@ -127,12 +126,12 @@ auto ListWindow::loadDatabase(string location) -> void {
|
|||
if(object.name() == "memory") {
|
||||
component.type = Component::Type::Memory;
|
||||
component.memory.type = object["type"].text();
|
||||
component.memory.battery = (bool)object["type/battery"];
|
||||
component.memory.size = object["size"].text();
|
||||
component.memory.content = object["content"].text();
|
||||
component.memory.manufacturer = object["manufacturer"].text();
|
||||
component.memory.architecture = object["architecture"].text();
|
||||
component.memory.identifier = object["identifier"].text();
|
||||
component.memory.Volatile = (bool)object["volatile"];
|
||||
}
|
||||
if(object.name() == "oscillator") {
|
||||
component.type = Component::Type::Oscillator;
|
||||
|
@ -184,8 +183,6 @@ auto ListWindow::saveDatabase(string location) -> void {
|
|||
if(component.type == Component::Type::Memory) {
|
||||
fp.print(" memory\n");
|
||||
fp.print(" type: ", component.memory.type, "\n");
|
||||
if(component.memory.battery)
|
||||
fp.print(" battery\n");
|
||||
fp.print(" size: ", component.memory.size, "\n");
|
||||
fp.print(" content: ", component.memory.content, "\n");
|
||||
if(component.memory.manufacturer)
|
||||
|
@ -194,6 +191,8 @@ auto ListWindow::saveDatabase(string location) -> void {
|
|||
fp.print(" architecture: ", component.memory.architecture, "\n");
|
||||
if(component.memory.identifier)
|
||||
fp.print(" identifier: ", component.memory.identifier, "\n");
|
||||
if(component.memory.Volatile)
|
||||
fp.print(" volatile\n");
|
||||
}
|
||||
|
||||
if(component.type == Component::Type::Oscillator) {
|
||||
|
@ -367,7 +366,7 @@ auto GameWindow::reloadList() -> void {
|
|||
string index = {"[", counter++, "] "};
|
||||
if(component.type == Component::Type::Memory) {
|
||||
item.setText({index, "Memory"});
|
||||
item.append(TreeViewItem().setText({"Type: ", component.memory.type, component.memory.battery ? " + Battery" : ""}));
|
||||
item.append(TreeViewItem().setText({"Type: ", component.memory.type}));
|
||||
item.append(TreeViewItem().setText({"Size: ", component.memory.size}));
|
||||
item.append(TreeViewItem().setText({"Content: ", component.memory.content}));
|
||||
if(component.memory.manufacturer)
|
||||
|
@ -376,6 +375,8 @@ auto GameWindow::reloadList() -> void {
|
|||
item.append(TreeViewItem().setText({"Architecture: ", component.memory.architecture}));
|
||||
if(component.memory.identifier)
|
||||
item.append(TreeViewItem().setText({"Identifier: ", component.memory.identifier}));
|
||||
if(component.memory.Volatile)
|
||||
item.append(TreeViewItem().setText({"Volatile"}));
|
||||
}
|
||||
|
||||
if(component.type == Component::Type::Oscillator) {
|
||||
|
@ -473,7 +474,7 @@ MemoryWindow::MemoryWindow() {
|
|||
architectureEdit.onChange([&] { modified = true, updateWindow(); });
|
||||
identifierLabel.setText("Identifier:").setAlignment(1.0);
|
||||
identifierEdit.onChange([&] { modified = true, updateWindow(); });
|
||||
batteryOption.setText("Battery").onToggle([&] { modified = true, updateWindow(); });
|
||||
volatileOption.setText("Volatile").onToggle([&] { modified = true, updateWindow(); });
|
||||
acceptButton.setText("Accept").onActivate([&] { accept(); });
|
||||
cancelButton.setText("Cancel").onActivate([&] { cancel(); });
|
||||
|
||||
|
@ -494,7 +495,7 @@ auto MemoryWindow::show(Memory memory) -> void {
|
|||
manufacturerEdit.setText(memory.manufacturer);
|
||||
architectureEdit.setText(memory.architecture);
|
||||
identifierEdit.setText(memory.identifier);
|
||||
batteryOption.setChecked(memory.battery);
|
||||
volatileOption.setChecked(memory.Volatile);
|
||||
|
||||
updateWindow();
|
||||
setCentered(*gameWindow);
|
||||
|
@ -510,7 +511,7 @@ auto MemoryWindow::accept() -> void {
|
|||
memory.manufacturer = manufacturerEdit.text().strip();
|
||||
memory.architecture = architectureEdit.text().strip();
|
||||
memory.identifier = identifierEdit.text().strip();
|
||||
memory.battery = batteryOption.checked() && (memory.type == "RAM" || memory.type == "RTC");
|
||||
memory.Volatile = volatileOption.checked() && (memory.type == "RAM" || memory.type == "RTC");
|
||||
|
||||
Component component{Component::Type::Memory};
|
||||
component.memory = memory;
|
||||
|
@ -543,7 +544,7 @@ auto MemoryWindow::updateWindow() -> void {
|
|||
manufacturerEdit.setBackgroundColor(manufacturerEdit.text().strip() ? Color{} : (Color{255, 255, 240}));
|
||||
architectureEdit.setBackgroundColor(architectureEdit.text().strip() ? Color{} : (Color{255, 255, 240}));
|
||||
identifierEdit.setBackgroundColor(identifierEdit.text().strip() ? Color{} : (Color{255, 255, 240}));
|
||||
batteryOption.setEnabled(typeEdit.text().strip() == "RAM" || typeEdit.text().strip() == "RTC");
|
||||
volatileOption.setEnabled(typeEdit.text().strip() == "RAM" || typeEdit.text().strip() == "RTC");
|
||||
acceptButton.setEnabled(valid);
|
||||
setTitle({modified ? "*" : "", create ? "Add New Memory" : "Modify Memory Details"});
|
||||
}
|
||||
|
@ -615,11 +616,25 @@ auto OscillatorWindow::updateWindow() -> void {
|
|||
//
|
||||
|
||||
#include <nall/main.hpp>
|
||||
auto nall::main(string_vector) -> void {
|
||||
auto nall::main(string_vector args) -> void {
|
||||
Application::setName("genius");
|
||||
new ListWindow;
|
||||
new GameWindow;
|
||||
new MemoryWindow;
|
||||
new OscillatorWindow;
|
||||
|
||||
//internal command used to synchronize all genius databases from an old format to a new format
|
||||
//if enabled, use with extreme caution and make backups first
|
||||
/*if(args.size() == 3 && args[1] == "--sync") {
|
||||
for(auto& filename : directory::contents(args[2], "*.bml")) {
|
||||
if(filename.beginsWith("Boards")) continue;
|
||||
print(filename, "\n");
|
||||
listWindow->loadDatabase({args[2], filename});
|
||||
listWindow->saveDatabase({args[2], filename});
|
||||
}
|
||||
return print("[Done]\n");
|
||||
}*/
|
||||
|
||||
listWindow->setVisible();
|
||||
Application::run();
|
||||
}
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
struct Memory {
|
||||
string type;
|
||||
boolean battery;
|
||||
string size;
|
||||
string content;
|
||||
string manufacturer;
|
||||
string architecture;
|
||||
string identifier;
|
||||
boolean Volatile;
|
||||
};
|
||||
|
||||
struct Oscillator {
|
||||
|
@ -150,7 +150,7 @@ private:
|
|||
LineEdit identifierEdit{&identifierLayout, Size{~0, 0}};
|
||||
HorizontalLayout controlLayout{&layout, Size{~0, 0}};
|
||||
Widget controlSpacer{&controlLayout, Size{~0, 0}};
|
||||
CheckLabel batteryOption{&controlLayout, Size{0, 0}};
|
||||
CheckLabel volatileOption{&controlLayout, Size{0, 0}};
|
||||
Button acceptButton{&controlLayout, Size{80, 0}};
|
||||
Button cancelButton{&controlLayout, Size{80, 0}};
|
||||
};
|
||||
|
|
|
@ -12,7 +12,7 @@ using namespace nall;
|
|||
|
||||
namespace Emulator {
|
||||
static const string Name = "higan";
|
||||
static const string Version = "106.13";
|
||||
static const string Version = "106.14";
|
||||
static const string Author = "byuu";
|
||||
static const string License = "GPLv3";
|
||||
static const string Website = "https://byuu.org/";
|
||||
|
|
|
@ -11,19 +11,23 @@ struct Game {
|
|||
inline auto oscillator(natural = 0) -> maybe<Oscillator>;
|
||||
|
||||
struct Memory {
|
||||
Memory() = default;
|
||||
inline Memory(Markup::Node);
|
||||
explicit operator bool() const { return type; }
|
||||
inline auto name() const -> string;
|
||||
|
||||
string type;
|
||||
boolean battery;
|
||||
natural size;
|
||||
string content;
|
||||
string manufacturer;
|
||||
string architecture;
|
||||
string identifier;
|
||||
boolean nonVolatile;
|
||||
};
|
||||
|
||||
struct Oscillator {
|
||||
Oscillator() = default;
|
||||
inline Oscillator(Markup::Node);
|
||||
explicit operator bool() const { return frequency; }
|
||||
|
||||
natural frequency;
|
||||
|
@ -51,21 +55,11 @@ auto Game::load(string_view text) -> void {
|
|||
board = document["game/board"].text();
|
||||
|
||||
for(auto node : document.find("game/board/memory")) {
|
||||
Memory memory;
|
||||
memory.type = node["type"].text();
|
||||
memory.battery = (bool)node["type/battery"];
|
||||
memory.size = node["size"].natural();
|
||||
memory.content = node["content"].text();
|
||||
memory.manufacturer = node["manufacturer"].text();
|
||||
memory.architecture = node["architecture"].text();
|
||||
memory.identifier = node["identifier"].text();
|
||||
memoryList.append(memory);
|
||||
memoryList.append(Memory{node});
|
||||
}
|
||||
|
||||
for(auto node : document.find("game/board/oscillator")) {
|
||||
Oscillator oscillator;
|
||||
oscillator.frequency = node["frequency"].natural();
|
||||
oscillatorList.append(oscillator);
|
||||
oscillatorList.append(Oscillator{node});
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -94,9 +88,23 @@ auto Game::oscillator(natural index) -> maybe<Oscillator> {
|
|||
return nothing;
|
||||
}
|
||||
|
||||
Game::Memory::Memory(Markup::Node node) {
|
||||
type = node["type"].text();
|
||||
size = node["size"].natural();
|
||||
content = node["content"].text();
|
||||
manufacturer = node["manufacturer"].text();
|
||||
architecture = node["architecture"].text();
|
||||
identifier = node["identifier"].text();
|
||||
nonVolatile = !(bool)node["volatile"];
|
||||
}
|
||||
|
||||
auto Game::Memory::name() const -> string {
|
||||
if(manufacturer) return string{manufacturer, ".", content, ".", type}.downcase();
|
||||
if(architecture) return string{architecture, ".", content, ".", type}.downcase();
|
||||
return string{content, ".", type}.downcase();
|
||||
}
|
||||
|
||||
Game::Oscillator::Oscillator(Markup::Node node) {
|
||||
frequency = node["frequency"].natural();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -21,66 +21,60 @@
|
|||
|
||||
Board::Board(Markup::Node& document) {
|
||||
cartridge.board = this;
|
||||
auto board = document["board"];
|
||||
information.type = document["game/board"].text();
|
||||
|
||||
information.type = board["id"].text();
|
||||
information.battery = (bool)board["prg/ram/name"];
|
||||
|
||||
auto prom = board["prg/rom"];
|
||||
auto pram = board["prg/ram"];
|
||||
auto crom = board["chr/rom"];
|
||||
auto cram = board["chr/ram"];
|
||||
|
||||
prgrom.size = prom["size"].natural();
|
||||
prgram.size = pram["size"].natural();
|
||||
chrrom.size = crom["size"].natural();
|
||||
chrram.size = cram["size"].natural();
|
||||
|
||||
if(prgrom.size) prgrom.data = new uint8_t[prgrom.size]();
|
||||
if(prgram.size) prgram.data = new uint8_t[prgram.size]();
|
||||
if(chrrom.size) chrrom.data = new uint8_t[chrrom.size]();
|
||||
if(chrram.size) chrram.data = new uint8_t[chrram.size]();
|
||||
|
||||
if(prgrom.name = prom["name"].text()) {
|
||||
if(auto fp = platform->open(cartridge.pathID(), prgrom.name, File::Read, File::Required)) {
|
||||
if(auto memory = Emulator::Game::Memory{document["game/board/memory(type=ROM,content=Program)"]}) {
|
||||
if(prgrom.size = memory.size) prgrom.data = new uint8_t[prgrom.size]();
|
||||
if(auto fp = platform->open(cartridge.pathID(), memory.name(), File::Read, File::Required)) {
|
||||
fp->read(prgrom.data, min(prgrom.size, fp->size()));
|
||||
}
|
||||
}
|
||||
if(prgram.name = pram["name"].text()) {
|
||||
if(auto fp = platform->open(cartridge.pathID(), prgram.name, File::Read)) {
|
||||
|
||||
if(auto memory = Emulator::Game::Memory{document["game/board/memory(type=RAM,content=Save)"]}) {
|
||||
if(prgram.size = memory.size) prgram.data = new uint8_t[prgram.size](), prgram.writable = true;
|
||||
if(memory.nonVolatile) {
|
||||
if(auto fp = platform->open(cartridge.pathID(), memory.name(), File::Read)) {
|
||||
fp->read(prgram.data, min(prgram.size, fp->size()));
|
||||
}
|
||||
}
|
||||
if(chrrom.name = crom["name"].text()) {
|
||||
if(auto fp = platform->open(cartridge.pathID(), chrrom.name, File::Read, File::Required)) {
|
||||
}
|
||||
|
||||
if(auto memory = Emulator::Game::Memory{document["game/board/memory(type=ROM,content=Character)"]}) {
|
||||
if(chrrom.size = memory.size) chrrom.data = new uint8_t[chrrom.size]();
|
||||
if(auto fp = platform->open(cartridge.pathID(), memory.name(), File::Read, File::Required)) {
|
||||
fp->read(chrrom.data, min(chrrom.size, fp->size()));
|
||||
}
|
||||
}
|
||||
if(chrram.name = cram["name"].text()) {
|
||||
if(auto fp = platform->open(cartridge.pathID(), chrram.name, File::Read)) {
|
||||
|
||||
if(auto memory = Emulator::Game::Memory{document["game/board/memory(type=RAM,content=Character)"]}) {
|
||||
if(chrram.size = memory.size) chrram.data = new uint8_t[chrram.size](), chrram.writable = true;
|
||||
if(memory.nonVolatile) {
|
||||
if(auto fp = platform->open(cartridge.pathID(), memory.name(), File::Read)) {
|
||||
fp->read(chrram.data, min(chrram.size, fp->size()));
|
||||
}
|
||||
}
|
||||
|
||||
prgram.writable = true;
|
||||
chrram.writable = true;
|
||||
}
|
||||
}
|
||||
|
||||
auto Board::save() -> void {
|
||||
auto document = BML::unserialize(cartridge.manifest());
|
||||
|
||||
if(auto name = document["board/prg/ram/name"].text()) {
|
||||
if(auto fp = platform->open(cartridge.pathID(), name, File::Write)) {
|
||||
if(auto memory = Emulator::Game::Memory{document["game/board/memory(type=RAM,content=Save)"]}) {
|
||||
if(memory.nonVolatile) {
|
||||
if(auto fp = platform->open(cartridge.pathID(), memory.name(), File::Write)) {
|
||||
fp->write(prgram.data, prgram.size);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(auto name = document["board/chr/ram/name"].text()) {
|
||||
if(auto fp = platform->open(cartridge.pathID(), name, File::Write)) {
|
||||
if(auto memory = Emulator::Game::Memory{document["game/board/memory(type=RAM,content=Character)"]}) {
|
||||
if(memory.nonVolatile) {
|
||||
if(auto fp = platform->open(cartridge.pathID(), memory.name(), File::Write)) {
|
||||
fp->write(chrram.data, chrram.size);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
auto Board::Memory::read(uint addr) const -> uint8 {
|
||||
return data[mirror(addr, size)];
|
||||
|
@ -138,9 +132,9 @@ auto Board::serialize(serializer& s) -> void {
|
|||
|
||||
auto Board::load(string manifest) -> Board* {
|
||||
auto document = BML::unserialize(manifest);
|
||||
cartridge.information.title = document["information/title"].text();
|
||||
cartridge.information.title = document["game/label"].text();
|
||||
|
||||
string type = document["board/id"].text();
|
||||
string type = document["game/board"].text();
|
||||
|
||||
if(type == "BANDAI-FCG" ) return new BandaiFCG(document);
|
||||
|
||||
|
|
|
@ -39,7 +39,6 @@ struct Board {
|
|||
|
||||
struct Information {
|
||||
string type;
|
||||
bool battery;
|
||||
} information;
|
||||
|
||||
Memory prgrom;
|
||||
|
|
|
@ -48,8 +48,7 @@ auto Cartridge::load() -> bool {
|
|||
information.manifest = fp->reads();
|
||||
} else return false;
|
||||
|
||||
//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:"));
|
||||
auto document = BML::unserialize(information.manifest);
|
||||
information.title = document["game/label"].text();
|
||||
|
||||
auto mapperID = document["game/board"].text();
|
||||
|
@ -69,31 +68,29 @@ auto Cartridge::load() -> bool {
|
|||
accelerometer = (bool)document["game/board/accelerometer"];
|
||||
rumble = (bool)document["game/board/rumble"];
|
||||
|
||||
if(auto node = document["game/memory(type=ROM)"]) {
|
||||
rom.size = max(0x4000, node["size"].natural());
|
||||
if(auto memory = Emulator::Game::Memory{document["game/board/memory(type=ROM,content=Program)"]}) {
|
||||
rom.size = max(0x4000, (uint)memory.size);
|
||||
rom.data = (uint8*)memory::allocate(rom.size, 0xff);
|
||||
if(auto name = node["name"].text()) {
|
||||
if(auto fp = platform->open(pathID(), name, File::Read, File::Required)) {
|
||||
if(auto fp = platform->open(pathID(), memory.name(), File::Read, File::Required)) {
|
||||
fp->read(rom.data, min(rom.size, fp->size()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(auto node = document["game/memory(type=NVRAM)"]) {
|
||||
ram.size = node["size"].natural();
|
||||
if(auto memory = Emulator::Game::Memory{document["game/board/memory(type=RAM,content=Save)"]}) {
|
||||
ram.size = memory.size;
|
||||
ram.data = (uint8*)memory::allocate(ram.size, 0xff);
|
||||
if(auto name = node["name"].text()) {
|
||||
if(auto fp = platform->open(pathID(), name, File::Read, File::Optional)) {
|
||||
if(memory.nonVolatile) {
|
||||
if(auto fp = platform->open(pathID(), memory.name(), File::Read, File::Optional)) {
|
||||
fp->read(ram.data, min(ram.size, fp->size()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(auto node = document["game/memory(type=RTC)"]) {
|
||||
rtc.size = node["size"].natural();
|
||||
if(auto memory = Emulator::Game::Memory{document["game/board/memory(type=RTC,content=Time)"]}) {
|
||||
rtc.size = memory.size;
|
||||
rtc.data = (uint8*)memory::allocate(rtc.size, 0xff);
|
||||
if(auto name = node["name"].text()) {
|
||||
if(auto fp = platform->open(pathID(), name, File::Read, File::Optional)) {
|
||||
if(memory.nonVolatile) {
|
||||
if(auto fp = platform->open(pathID(), memory.name(), File::Read, File::Optional)) {
|
||||
fp->read(rtc.data, min(rtc.size, fp->size()));
|
||||
}
|
||||
}
|
||||
|
@ -104,19 +101,19 @@ auto Cartridge::load() -> bool {
|
|||
}
|
||||
|
||||
auto Cartridge::save() -> void {
|
||||
auto document = BML::unserialize(string{information.manifest}.replace("type: ", "type:"));
|
||||
auto document = BML::unserialize(information.manifest);
|
||||
|
||||
if(auto node = document["game/memory(type=NVRAM)"]) {
|
||||
if(auto name = node["name"].text()) {
|
||||
if(auto fp = platform->open(pathID(), name, File::Write)) {
|
||||
if(auto memory = Emulator::Game::Memory{document["game/board/memory(type=RAM,content=Save)"]}) {
|
||||
if(memory.nonVolatile) {
|
||||
if(auto fp = platform->open(pathID(), memory.name(), File::Write)) {
|
||||
fp->write(ram.data, ram.size);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(auto node = document["game/memory(type=RTC)"]) {
|
||||
if(auto name = node["name"].text()) {
|
||||
if(auto fp = platform->open(pathID(), name, File::Write)) {
|
||||
if(auto memory = Emulator::Game::Memory{document["game/board/memory(type=RTC,content=Time)"]}) {
|
||||
if(memory.nonVolatile) {
|
||||
if(auto fp = platform->open(pathID(), memory.name(), File::Write)) {
|
||||
fp->write(rtc.data, rtc.size);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -35,61 +35,64 @@ auto Cartridge::load() -> bool {
|
|||
} else return false;
|
||||
|
||||
auto document = BML::unserialize(information.manifest);
|
||||
information.title = document["information/title"].text();
|
||||
information.title = document["game/label"].text();
|
||||
|
||||
hasSRAM = false;
|
||||
hasEEPROM = false;
|
||||
hasFLASH = false;
|
||||
|
||||
if(auto node = document["board/rom"]) {
|
||||
mrom.size = min(32 * 1024 * 1024, node["size"].natural());
|
||||
if(auto fp = platform->open(pathID(), node["name"].text(), File::Read, File::Required)) {
|
||||
if(auto memory = Emulator::Game::Memory{document["game/board/memory(type=ROM,content=Program)"]}) {
|
||||
mrom.size = min(32 * 1024 * 1024, (uint)memory.size);
|
||||
if(auto fp = platform->open(pathID(), memory.name(), File::Read, File::Required)) {
|
||||
fp->read(mrom.data, mrom.size);
|
||||
}
|
||||
}
|
||||
|
||||
if(auto node = document["board/ram"]) {
|
||||
if(node["type"].text() == "sram") {
|
||||
if(auto memory = Emulator::Game::Memory{document["game/board/memory(type=RAM,content=Save)"]}) {
|
||||
hasSRAM = true;
|
||||
sram.size = min(32 * 1024, node["size"].natural());
|
||||
sram.size = min(32 * 1024, (uint)memory.size);
|
||||
sram.mask = sram.size - 1;
|
||||
for(auto n : range(sram.size)) sram.data[n] = 0xff;
|
||||
|
||||
if(auto fp = platform->open(pathID(), node["name"].text(), File::Read)) {
|
||||
if(memory.nonVolatile) {
|
||||
if(auto fp = platform->open(pathID(), memory.name(), File::Read)) {
|
||||
fp->read(sram.data, sram.size);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(node["type"].text() == "eeprom") {
|
||||
if(auto memory = Emulator::Game::Memory{document["game/board/memory(type=EEPROM,content=Save)"]}) {
|
||||
hasEEPROM = true;
|
||||
eeprom.size = min(8 * 1024, node["size"].natural());
|
||||
eeprom.size = min(8 * 1024, (uint)memory.size);
|
||||
eeprom.bits = eeprom.size <= 512 ? 6 : 14;
|
||||
if(eeprom.size == 0) eeprom.size = 8192, eeprom.bits = 0; //auto-detect size
|
||||
eeprom.mask = mrom.size > 16 * 1024 * 1024 ? 0x0fffff00 : 0x0f000000;
|
||||
eeprom.test = mrom.size > 16 * 1024 * 1024 ? 0x0dffff00 : 0x0d000000;
|
||||
for(auto n : range(eeprom.size)) eeprom.data[n] = 0xff;
|
||||
|
||||
if(auto fp = platform->open(pathID(), node["name"].text(), File::Read)) {
|
||||
if(auto fp = platform->open(pathID(), memory.name(), File::Read)) {
|
||||
fp->read(eeprom.data, eeprom.size);
|
||||
}
|
||||
}
|
||||
|
||||
if(node["type"].text() == "flash") {
|
||||
if(auto memory = Emulator::Game::Memory{document["game/board/memory(type=Flash,content=Save)"]}) {
|
||||
hasFLASH = true;
|
||||
flash.id = node["id"].natural();
|
||||
flash.size = min(128 * 1024, node["size"].natural());
|
||||
flash.size = min(128 * 1024, (uint)memory.size);
|
||||
flash.manufacturer = memory.manufacturer;
|
||||
for(auto n : range(flash.size)) flash.data[n] = 0xff;
|
||||
|
||||
//if flash ID not provided; guess that it's a Macronix chip
|
||||
//this will not work for all games; in which case, the ID must be specified manually
|
||||
if(!flash.id && flash.size == 64 * 1024) flash.id = 0x1cc2;
|
||||
if(!flash.id && flash.size == 128 * 1024) flash.id = 0x09c2;
|
||||
flash.id = 0;
|
||||
if(flash.manufacturer == "Atmel" && flash.size == 64 * 1024) flash.id = 0x3d1f;
|
||||
if(flash.manufacturer == "Macronix" && flash.size == 64 * 1024) flash.id = 0x1cc2;
|
||||
if(flash.manufacturer == "Macronix" && flash.size == 128 * 1024) flash.id = 0x09c2;
|
||||
if(flash.manufacturer == "Panasonic" && flash.size == 64 * 1024) flash.id = 0x1b32;
|
||||
if(flash.manufacturer == "Sanyo" && flash.size == 128 * 1024) flash.id = 0x1362;
|
||||
if(flash.manufacturer == "SST" && flash.size == 64 * 1024) flash.id = 0xd4bf;
|
||||
|
||||
if(auto fp = platform->open(pathID(), node["name"].text(), File::Read)) {
|
||||
if(auto fp = platform->open(pathID(), memory.name(), File::Read)) {
|
||||
fp->read(flash.data, flash.size);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
information.sha256 = Hash::SHA256(mrom.data, mrom.size).digest();
|
||||
return true;
|
||||
|
@ -97,11 +100,24 @@ auto Cartridge::load() -> bool {
|
|||
|
||||
auto Cartridge::save() -> void {
|
||||
auto document = BML::unserialize(information.manifest);
|
||||
if(auto node = document["board/ram"]) {
|
||||
if(auto fp = platform->open(pathID(), node["name"].text(), File::Write)) {
|
||||
if(node["type"].text() == "sram") fp->write(sram.data, sram.size);
|
||||
if(node["type"].text() == "eeprom") fp->write(eeprom.data, eeprom.size);
|
||||
if(node["type"].text() == "flash") fp->write(flash.data, flash.size);
|
||||
|
||||
if(auto memory = Emulator::Game::Memory{document["game/board/memory(type=RAM,content=Save)"]}) {
|
||||
if(memory.nonVolatile) {
|
||||
if(auto fp = platform->open(pathID(), memory.name(), File::Write)) {
|
||||
fp->write(sram.data, sram.size);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(auto memory = Emulator::Game::Memory{document["game/board/memory(type=EEPROM,content=Save)"]}) {
|
||||
if(auto fp = platform->open(pathID(), memory.name(), File::Write)) {
|
||||
fp->write(eeprom.data, eeprom.size);
|
||||
}
|
||||
}
|
||||
|
||||
if(auto memory = Emulator::Game::Memory{document["game/board/memory(type=Flash,content=Save)"]}) {
|
||||
if(auto fp = platform->open(pathID(), memory.name(), File::Write)) {
|
||||
fp->write(flash.data, flash.size);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -46,6 +46,8 @@ struct EEPROM {
|
|||
struct FLASH {
|
||||
uint8* data;
|
||||
uint size;
|
||||
string manufacturer;
|
||||
|
||||
uint16 id;
|
||||
|
||||
bool unlockhi;
|
||||
|
|
|
@ -18,41 +18,37 @@ auto Cartridge::load() -> bool {
|
|||
} else return false;
|
||||
|
||||
auto document = BML::unserialize(information.manifest);
|
||||
information.title = document["information/title"].text();
|
||||
information.title = document["game/label"].text();
|
||||
|
||||
if(information.region == "Auto") {
|
||||
if(auto region = document["board/region"].text()) {
|
||||
if(auto region = document["game/region"].text()) {
|
||||
information.region = region.upcase();
|
||||
} else {
|
||||
information.region = "NTSC-J";
|
||||
}
|
||||
}
|
||||
|
||||
if(auto node = document["board/rom"]) {
|
||||
rom.size = node["size"].natural() >> 1;
|
||||
if(auto memory = Emulator::Game::Memory{document["game/board/memory(type=ROM,content=Program)"]}) {
|
||||
rom.size = memory.size >> 1;
|
||||
rom.mask = bit::round(rom.size) - 1;
|
||||
if(rom.size) {
|
||||
rom.data = new uint16[rom.mask + 1]();
|
||||
if(auto name = node["name"].text()) {
|
||||
if(auto fp = platform->open(pathID(), name, File::Read, File::Required)) {
|
||||
if(auto fp = platform->open(pathID(), memory.name(), File::Read, File::Required)) {
|
||||
for(uint n : range(rom.size)) rom.data[n] = fp->readm(2);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(auto node = document["board/ram"]) {
|
||||
if(auto mode = node["mode"].text()) {
|
||||
//todo: handle mode, offset in Emulator::Game::Memory
|
||||
if(auto memory = document["game/board/memory(type=RAM,content=Save)"]) {
|
||||
if(auto mode = memory["mode"].text()) {
|
||||
if(mode == "lo" ) ram.bits = 0x00ff;
|
||||
if(mode == "hi" ) ram.bits = 0xff00;
|
||||
if(mode == "word") ram.bits = 0xffff;
|
||||
}
|
||||
ram.size = node["size"].natural() >> (ram.bits == 0xffff);
|
||||
ram.size = memory["size"].natural() >> (ram.bits == 0xffff);
|
||||
ram.mask = bit::round(ram.size) - 1;
|
||||
if(ram.size) {
|
||||
ram.data = new uint16[ram.mask + 1]();
|
||||
if(auto name = node["name"].text()) {
|
||||
if(auto fp = platform->open(pathID(), name, File::Read)) {
|
||||
if(!(bool)memory["volatile"]) {
|
||||
if(auto fp = platform->open(pathID(), "save.ram", File::Read)) {
|
||||
for(uint n : range(ram.size)) {
|
||||
if(ram.bits != 0xffff) ram.data[n] = fp->readm(1) * 0x0101;
|
||||
if(ram.bits == 0xffff) ram.data[n] = fp->readm(2);
|
||||
|
@ -60,7 +56,6 @@ auto Cartridge::load() -> bool {
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -68,8 +63,9 @@ auto Cartridge::load() -> bool {
|
|||
auto Cartridge::save() -> void {
|
||||
auto document = BML::unserialize(information.manifest);
|
||||
|
||||
if(auto name = document["board/ram/name"].text()) {
|
||||
if(auto fp = platform->open(pathID(), name, File::Write)) {
|
||||
if(auto memory = Emulator::Game::Memory{document["game/board/memory(type=RAM,content=Save)"]}) {
|
||||
if(memory.nonVolatile) {
|
||||
if(auto fp = platform->open(pathID(), memory.name(), File::Write)) {
|
||||
for(uint n : range(ram.size)) {
|
||||
if(ram.bits != 0xffff) fp->writem(ram.data[n], 1);
|
||||
if(ram.bits == 0xffff) fp->writem(ram.data[n], 2);
|
||||
|
@ -77,6 +73,7 @@ auto Cartridge::save() -> void {
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
auto Cartridge::unload() -> void {
|
||||
delete[] rom.data;
|
||||
|
|
|
@ -27,33 +27,27 @@ auto Cartridge::load() -> bool {
|
|||
} else return false;
|
||||
|
||||
auto document = BML::unserialize(information.manifest);
|
||||
information.title = document["information/title"].text();
|
||||
information.title = document["game/label"].text();
|
||||
|
||||
if(auto node = document["board/rom"]) {
|
||||
rom.size = node["size"].natural();
|
||||
if(auto memory = Emulator::Game::Memory{document["game/board/memory(type=ROM,content=Program)"]}) {
|
||||
rom.size = memory.size;
|
||||
rom.mask = bit::round(rom.size) - 1;
|
||||
if(rom.size) {
|
||||
rom.data = new uint8[rom.mask + 1];
|
||||
if(auto name = node["name"].text()) {
|
||||
if(auto fp = platform->open(pathID(), name, File::Read, File::Required)) {
|
||||
if(auto fp = platform->open(pathID(), memory.name(), File::Read, File::Required)) {
|
||||
fp->read(rom.data, rom.size);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(auto node = document["board/ram"]) {
|
||||
ram.size = node["size"].natural();
|
||||
if(auto memory = Emulator::Game::Memory{document["game/board/memory(type=RAM,content=Save)"]}) {
|
||||
ram.size = memory.size;
|
||||
ram.mask = bit::round(ram.size) - 1;
|
||||
if(ram.size) {
|
||||
ram.data = new uint8[ram.mask + 1];
|
||||
if(auto name = node["name"].text()) {
|
||||
if(auto fp = platform->open(pathID(), name, File::Read)) {
|
||||
if(memory.nonVolatile) {
|
||||
if(auto fp = platform->open(pathID(), memory.name(), File::Read)) {
|
||||
fp->read(ram.data, ram.size);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -61,12 +55,14 @@ auto Cartridge::load() -> bool {
|
|||
auto Cartridge::save() -> void {
|
||||
auto document = BML::unserialize(information.manifest);
|
||||
|
||||
if(auto name = document["board/ram/name"].text()) {
|
||||
if(auto fp = platform->open(pathID(), name, File::Write)) {
|
||||
if(auto memory = Emulator::Game::Memory{document["game/board/memory(type=RAM,content=Save)"]}) {
|
||||
if(memory.nonVolatile) {
|
||||
if(auto fp = platform->open(pathID(), memory.name(), File::Write)) {
|
||||
fp->write(ram.data, ram.size);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
auto Cartridge::unload() -> void {
|
||||
delete[] rom.data;
|
||||
|
|
|
@ -24,19 +24,15 @@ auto Cartridge::load() -> bool {
|
|||
} else return false;
|
||||
|
||||
auto document = BML::unserialize(information.manifest);
|
||||
information.title = document["information/title"].text();
|
||||
information.title = document["game/label"].text();
|
||||
|
||||
if(auto node = document["board/rom"]) {
|
||||
rom.size = node["size"].natural();
|
||||
if(rom.size) {
|
||||
if(auto memory = Emulator::Game::Memory{document["game/board/memory(type=ROM,content=Program)"]}) {
|
||||
rom.size = memory.size;
|
||||
rom.data = new uint8[rom.size]();
|
||||
if(auto name = node["name"].text()) {
|
||||
if(auto fp = platform->open(pathID(), name, File::Read, File::Required)) {
|
||||
if(auto fp = platform->open(pathID(), memory.name(), File::Read, File::Required)) {
|
||||
fp->read(rom.data, rom.size);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
information.sha256 = Hash::SHA256(rom.data, rom.size).digest();
|
||||
return true;
|
||||
|
|
|
@ -223,17 +223,23 @@ auto Cartridge::loadSuperFX(Markup::Node node) -> void {
|
|||
auto Cartridge::loadARMDSP(Markup::Node node) -> void {
|
||||
has.ARMDSP = true;
|
||||
|
||||
if(auto memory = game.memory(node["memory(type=ROM,category=Program)"])) {
|
||||
if(auto oscillator = game.oscillator()) {
|
||||
armdsp.Frequency = oscillator->frequency;
|
||||
} else {
|
||||
armdsp.Frequency = 21'440'000;
|
||||
}
|
||||
|
||||
if(auto memory = game.memory(node["memory(type=ROM,content=Program)"])) {
|
||||
if(auto fp = platform->open(ID::SuperFamicom, memory->name(), File::Read, File::Required)) {
|
||||
for(auto n : range(128 * 1024)) armdsp.programROM[n] = fp->read();
|
||||
}
|
||||
}
|
||||
if(auto memory = game.memory(node["memory(type=ROM,category=Data)"])) {
|
||||
if(auto memory = game.memory(node["memory(type=ROM,content=Data)"])) {
|
||||
if(auto fp = platform->open(ID::SuperFamicom, memory->name(), File::Read, File::Required)) {
|
||||
for(auto n : range( 32 * 1024)) armdsp.dataROM[n] = fp->read();
|
||||
}
|
||||
}
|
||||
if(auto memory = game.memory(node["memory(type=RAM,category=Data)"])) {
|
||||
if(auto memory = game.memory(node["memory(type=RAM,content=Data)"])) {
|
||||
if(auto fp = platform->open(ID::SuperFamicom, memory->name(), File::Read)) {
|
||||
for(auto n : range( 16 * 1024)) armdsp.programRAM[n] = fp->read();
|
||||
}
|
||||
|
@ -245,8 +251,11 @@ auto Cartridge::loadARMDSP(Markup::Node node) -> void {
|
|||
auto Cartridge::loadHitachiDSP(Markup::Node node, uint roms) -> void {
|
||||
has.HitachiDSP = true;
|
||||
|
||||
hitachidsp.Frequency = node["frequency"].natural();
|
||||
if(hitachidsp.Frequency == 0) hitachidsp.Frequency = 20'000'000;
|
||||
if(auto oscillator = game.oscillator()) {
|
||||
hitachidsp.Frequency = oscillator->frequency;
|
||||
} else {
|
||||
hitachidsp.Frequency = 20'000'000;
|
||||
}
|
||||
hitachidsp.Roms = roms; //1 or 2
|
||||
|
||||
loadMemory(hitachidsp.rom, node["rom"], File::Required);
|
||||
|
@ -255,12 +264,12 @@ auto Cartridge::loadHitachiDSP(Markup::Node node, uint roms) -> void {
|
|||
for(auto& word : hitachidsp.dataROM) word = 0x000000;
|
||||
for(auto& word : hitachidsp.dataRAM) word = 0x00;
|
||||
|
||||
if(auto memory = game.memory(node["memory(type=ROM,category=Data)"])) {
|
||||
if(auto memory = game.memory(node["memory(type=ROM,content=Data)"])) {
|
||||
if(auto fp = platform->open(ID::SuperFamicom, memory->name(), File::Read, File::Required)) {
|
||||
for(auto n : range(1 * 1024)) hitachidsp.dataROM[n] = fp->readl(3);
|
||||
}
|
||||
}
|
||||
if(auto memory = game.memory(node["memory(type=RAM,category=Data)"])) {
|
||||
if(auto memory = game.memory(node["memory(type=RAM,content=Data)"])) {
|
||||
if(auto fp = platform->open(ID::SuperFamicom, memory->name(), File::Read)) {
|
||||
for(auto n : range(3 * 1024)) hitachidsp.dataRAM[n] = fp->readl(1);
|
||||
}
|
||||
|
@ -275,8 +284,12 @@ auto Cartridge::loadHitachiDSP(Markup::Node node, uint roms) -> void {
|
|||
auto Cartridge::loadNECDSP(Markup::Node node) -> void {
|
||||
has.NECDSP = true;
|
||||
|
||||
necdsp.Frequency = node["frequency"].natural();
|
||||
if(necdsp.Frequency == 0) necdsp.Frequency = 8000000;
|
||||
if(auto oscillator = game.oscillator()) {
|
||||
necdsp.Frequency = oscillator->frequency;
|
||||
} else {
|
||||
necdsp.Frequency = 7'600'000;
|
||||
}
|
||||
|
||||
necdsp.revision
|
||||
= node["model"].text() == "uPD7725" ? NECDSP::Revision::uPD7725
|
||||
: node["model"].text() == "uPD96050" ? NECDSP::Revision::uPD96050
|
||||
|
@ -290,18 +303,18 @@ auto Cartridge::loadNECDSP(Markup::Node node) -> void {
|
|||
if(necdsp.revision == NECDSP::Revision::uPD7725 ) memory::assign(size, 2048, 1024, 256);
|
||||
if(necdsp.revision == NECDSP::Revision::uPD96050) memory::assign(size, 16384, 2048, 2048);
|
||||
|
||||
if(auto memory = game.memory(node["memory(type=ROM,category=Program)"])) {
|
||||
if(auto memory = game.memory(node["memory(type=ROM,content=Program)"])) {
|
||||
if(auto fp = platform->open(ID::SuperFamicom, memory->name(), File::Read, File::Required)) {
|
||||
for(auto n : range(size[0])) necdsp.programROM[n] = fp->readl(3);
|
||||
}
|
||||
}
|
||||
if(auto memory = game.memory(node["memory(type=ROM,category=Data)"])) {
|
||||
if(auto fp = platform->open(ID::SuperFamicom, memory->name(), File::Read, File::Required)) {
|
||||
if(auto memory = Emulator::Game::Memory{node["memory(type=ROM,content=Data)"]}) {
|
||||
if(auto fp = platform->open(ID::SuperFamicom, memory.name(), File::Read, File::Required)) {
|
||||
for(auto n : range(size[1])) necdsp.dataROM[n] = fp->readl(2);
|
||||
}
|
||||
}
|
||||
if(auto memory = game.memory(node["memory(type=RAM,category=Data"])) {
|
||||
if(auto fp = platform->open(ID::SuperFamicom, memory->name(), File::Read)) {
|
||||
if(auto memory = Emulator::Game::Memory{node["memory(type=RAM,content=Data)"]}) {
|
||||
if(auto fp = platform->open(ID::SuperFamicom, memory.name(), File::Read)) {
|
||||
for(auto n : range(size[2])) necdsp.dataRAM[n] = fp->readl(2);
|
||||
}
|
||||
}
|
||||
|
@ -314,7 +327,7 @@ auto Cartridge::loadEpsonRTC(Markup::Node node) -> void {
|
|||
has.EpsonRTC = true;
|
||||
|
||||
epsonrtc.initialize();
|
||||
if(auto memory = game.memory(node["memory(type=RTC)"])) {
|
||||
if(auto memory = game.memory(node["memory(type=RTC,content=Time)"])) {
|
||||
if(auto fp = platform->open(ID::SuperFamicom, memory->name(), File::Read)) {
|
||||
uint8 data[16] = {0};
|
||||
for(auto& byte : data) byte = fp->read();
|
||||
|
@ -329,7 +342,7 @@ auto Cartridge::loadSharpRTC(Markup::Node node) -> void {
|
|||
has.SharpRTC = true;
|
||||
|
||||
sharprtc.initialize();
|
||||
if(auto memory = game.memory(node["memory(type=RTC)"])) {
|
||||
if(auto memory = game.memory(node["memory(type=RTC,content=Time)"])) {
|
||||
if(auto fp = platform->open(ID::SuperFamicom, memory->name(), File::Read)) {
|
||||
uint8 data[16] = {0};
|
||||
for(auto& byte : data) byte = fp->read();
|
||||
|
@ -384,8 +397,8 @@ auto Cartridge::loadMemory(MappedRAM& ram, Markup::Node node, bool required, may
|
|||
if(!id) id = pathID();
|
||||
if(auto memory = game.memory(node)) {
|
||||
ram.allocate(memory->size);
|
||||
if(memory->type == "RAM" && !memory->battery) return;
|
||||
if(memory->type == "RTC" && !memory->battery) return;
|
||||
if(memory->type == "RAM" && !memory->nonVolatile) return;
|
||||
if(memory->type == "RTC" && !memory->nonVolatile) return;
|
||||
if(auto fp = platform->open(id(), memory->name(), File::Read, required)) {
|
||||
fp->read(ram.data(), ram.size());
|
||||
}
|
||||
|
|
|
@ -52,8 +52,8 @@ auto Cartridge::saveSuperFX(Markup::Node node) -> void {
|
|||
}
|
||||
|
||||
auto Cartridge::saveARMDSP(Markup::Node node) -> void {
|
||||
if(auto memory = game.memory(node["memory(type=RAM,category=Data)"])) {
|
||||
if(memory->battery) {
|
||||
if(auto memory = game.memory(node["memory(type=RAM,content=Data)"])) {
|
||||
if(memory->nonVolatile) {
|
||||
if(auto fp = platform->open(ID::SuperFamicom, memory->name(), File::Write)) {
|
||||
for(auto n : range(16 * 1024)) fp->write(armdsp.programRAM[n]);
|
||||
}
|
||||
|
@ -64,8 +64,8 @@ auto Cartridge::saveARMDSP(Markup::Node node) -> void {
|
|||
auto Cartridge::saveHitachiDSP(Markup::Node node) -> void {
|
||||
saveMemory(hitachidsp.ram, node["ram"]);
|
||||
|
||||
if(auto memory = game.memory(node["memory(type=RAM,category=Data)"])) {
|
||||
if(memory->battery) {
|
||||
if(auto memory = game.memory(node["memory(type=RAM,content=Data)"])) {
|
||||
if(memory->nonVolatile) {
|
||||
if(auto fp = platform->open(ID::SuperFamicom, memory->name(), File::Write)) {
|
||||
for(auto n : range(3 * 1024)) fp->write(hitachidsp.dataRAM[n]);
|
||||
}
|
||||
|
@ -75,9 +75,9 @@ auto Cartridge::saveHitachiDSP(Markup::Node node) -> void {
|
|||
|
||||
auto Cartridge::saveNECDSP(Markup::Node node) -> void {
|
||||
uint size = necdsp.revision == NECDSP::Revision::uPD7725 ? 256 : 2048;
|
||||
if(auto memory = game.memory(node["memory(type=RAM,category=Data)"])) {
|
||||
if(memory->battery) {
|
||||
if(auto fp = platform->open(ID::SuperFamicom, memory->name(), File::Write)) {
|
||||
if(auto memory = Emulator::Game::Memory{node["memory(type=RAM,content=Data)"]}) {
|
||||
if(memory.nonVolatile) {
|
||||
if(auto fp = platform->open(ID::SuperFamicom, memory.name(), File::Write)) {
|
||||
for(auto n : range(size)) fp->writel(necdsp.dataRAM[n], 2);
|
||||
}
|
||||
}
|
||||
|
@ -85,8 +85,8 @@ auto Cartridge::saveNECDSP(Markup::Node node) -> void {
|
|||
}
|
||||
|
||||
auto Cartridge::saveEpsonRTC(Markup::Node node) -> void {
|
||||
if(auto memory = game.memory(node["memory(type=RTC)"])) {
|
||||
if(memory->battery) {
|
||||
if(auto memory = game.memory(node["memory(type=RTC,content=Time)"])) {
|
||||
if(memory->nonVolatile) {
|
||||
if(auto fp = platform->open(ID::SuperFamicom, memory->name(), File::Write)) {
|
||||
uint8 data[16] = {0};
|
||||
epsonrtc.save(data);
|
||||
|
@ -97,8 +97,8 @@ auto Cartridge::saveEpsonRTC(Markup::Node node) -> void {
|
|||
}
|
||||
|
||||
auto Cartridge::saveSharpRTC(Markup::Node node) -> void {
|
||||
if(auto memory = game.memory(node["memory(type=RTC)"])) {
|
||||
if(memory->battery) {
|
||||
if(auto memory = game.memory(node["memory(type=RTC,content=Time)"])) {
|
||||
if(memory->nonVolatile) {
|
||||
if(auto fp = platform->open(ID::SuperFamicom, memory->name(), File::Write)) {
|
||||
uint8 data[16] = {0};
|
||||
sharprtc.save(data);
|
||||
|
@ -125,8 +125,8 @@ auto Cartridge::saveOBC1(Markup::Node node) -> void {
|
|||
auto Cartridge::saveMemory(MappedRAM& ram, Markup::Node node, maybe<uint> id) -> void {
|
||||
if(!id) id = pathID();
|
||||
if(auto memory = game.memory(node)) {
|
||||
if(memory->type == "RAM" && !memory->battery) return;
|
||||
if(memory->type == "RTC" && !memory->battery) return;
|
||||
if(memory->type == "RAM" && !memory->nonVolatile) return;
|
||||
if(memory->type == "RTC" && !memory->nonVolatile) return;
|
||||
if(auto fp = platform->open(id(), memory->name(), File::Write)) {
|
||||
fp->write(ram.data(), ram.size());
|
||||
}
|
||||
|
|
|
@ -89,7 +89,7 @@ auto ArmDSP::power() -> void {
|
|||
|
||||
auto ArmDSP::reset() -> void {
|
||||
ARM7TDMI::power();
|
||||
create(ArmDSP::Enter, 21'477'272);
|
||||
create(ArmDSP::Enter, Frequency);
|
||||
|
||||
bridge.ready = false;
|
||||
bridge.signal = false;
|
||||
|
|
|
@ -25,6 +25,8 @@ struct ArmDSP : Processor::ARM7TDMI, Thread {
|
|||
auto firmware() const -> nall::vector<uint8>;
|
||||
auto serialize(serializer&) -> void;
|
||||
|
||||
uint Frequency;
|
||||
|
||||
uint8 programROM[128 * 1024];
|
||||
uint8 dataROM[32 * 1024];
|
||||
uint8 programRAM[16 * 1024];
|
||||
|
|
|
@ -1,490 +1,498 @@
|
|||
database
|
||||
revision: 2018-04-08
|
||||
revision: 2018-04-15
|
||||
|
||||
//Boards (Production)
|
||||
|
||||
database
|
||||
revision: 2018-02-27
|
||||
revision: 2018-04-10
|
||||
|
||||
board: BANDAI-PT-923
|
||||
rom
|
||||
memory type=ROM content=Program
|
||||
map address=00-1f,80-9f:8000-ffff mask=0x8000
|
||||
sufamiturbo
|
||||
slot type=SufamiTurbo
|
||||
rom
|
||||
map address=20-3f,a0-bf:8000-ffff mask=0x8000
|
||||
ram
|
||||
map address=60-6f,e0-ef:0000-ffff
|
||||
sufamiturbo
|
||||
slot type=SufamiTurbo
|
||||
rom
|
||||
map address=40-5f,c0-df:0000-ffff mask=0x8000
|
||||
ram
|
||||
map address=70-7d,f0-ff:0000-ffff
|
||||
|
||||
board: BSC-1A5M-02
|
||||
rom
|
||||
memory type=ROM content=Program
|
||||
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
|
||||
memory type=RAM content=Save
|
||||
map address=70-7d,f0-ff:0000-7fff mask=0x8000
|
||||
bsmemory
|
||||
slot type=BSMemory
|
||||
map address=c0-ef:0000-ffff
|
||||
|
||||
board: BSC-1A7M-01
|
||||
rom
|
||||
memory type=ROM content=Program
|
||||
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
|
||||
memory type=RAM content=Save
|
||||
map address=70-7d,f0-ff:0000-7fff mask=0x8000
|
||||
bsmemory
|
||||
slot type=BSMemory
|
||||
map address=c0-ef:0000-ffff
|
||||
|
||||
board: BSC-1J3M-01
|
||||
rom
|
||||
memory type=ROM content=Program
|
||||
map address=00-1f,80-9f:8000-ffff
|
||||
map address=40-5f,c0-df:0000-ffff
|
||||
ram
|
||||
memory type=RAM content=Save
|
||||
map address=20-3f,a0-bf:6000-7fff mask=0xe000
|
||||
bsmemory
|
||||
slot type=BSMemory
|
||||
map address=20-3f,a0-bf:8000-ffff
|
||||
map address=60-7d,e0-ff:0000-ffff
|
||||
|
||||
board: BSC-1J5M-01
|
||||
rom
|
||||
memory type=ROM content=Program
|
||||
map address=00-1f,80-9f:8000-ffff
|
||||
map address=40-5f,c0-df:0000-ffff
|
||||
ram
|
||||
memory type=RAM content=Save
|
||||
map address=20-3f,a0-bf:6000-7fff mask=0xe000
|
||||
bsmemory
|
||||
slot type=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
|
||||
memory type=ROM content=Program
|
||||
map address=00-3f,80-bf:8000-ffff mask=0x408000
|
||||
map address=c0-ff:0000-ffff
|
||||
bwram
|
||||
memory type=RAM content=Save
|
||||
map address=00-3f,80-bf:6000-7fff size=0x2000
|
||||
map address=40-4f:0000-ffff
|
||||
iram
|
||||
memory type=RAM content=Internal
|
||||
map address=00-3f,80-bf:3000-37ff size=0x800
|
||||
bsmemory
|
||||
slot type=BSMemory
|
||||
|
||||
board: BSC-1L5B-01
|
||||
sa1
|
||||
map address=00-3f,80-bf:2200-23ff
|
||||
rom
|
||||
memory type=ROM content=Program
|
||||
map address=00-3f,80-bf:8000-ffff mask=0x408000
|
||||
map address=c0-ff:0000-ffff
|
||||
bwram
|
||||
memory type=RAM content=Save
|
||||
map address=00-3f,80-bf:6000-7fff size=0x2000
|
||||
map address=40-4f:0000-ffff
|
||||
iram
|
||||
memory type=RAM content=Internal
|
||||
map address=00-3f,80-bf:3000-37ff size=0x800
|
||||
bsmemory
|
||||
slot type=BSMemory
|
||||
|
||||
board: SGB-R-10
|
||||
rom
|
||||
memory type=ROM content=Program
|
||||
map address=00-7d,80-ff:8000-ffff mask=0x8000
|
||||
map address=40-7d,c0-ff:0000-7fff mask=0x8000
|
||||
icd revision=2
|
||||
map address=00-3f,80-bf:6000-67ff,7000-7fff
|
||||
rom
|
||||
gameboy
|
||||
memory type=ROM content=Boot architecture=LR35902
|
||||
slot type=GameBoy
|
||||
|
||||
board: SHVC-1A0N-(01,02,10,20,30)
|
||||
rom
|
||||
memory type=ROM content=Program
|
||||
map address=00-7d,80-ff:8000-ffff mask=0x8000
|
||||
map address=40-7d,c0-ff:0000-7fff mask=0x8000
|
||||
|
||||
board: SHVC-1A1B-(04,05,06)
|
||||
rom
|
||||
memory type=ROM content=Program
|
||||
map address=00-1f,80-9f:8000-ffff mask=0x8000
|
||||
ram
|
||||
memory type=RAM content=Save
|
||||
map address=70-7d,f0-ff:0000-ffff
|
||||
|
||||
board: SHVC-1A1M-(01,10,11,20)
|
||||
rom
|
||||
memory type=ROM content=Program
|
||||
map address=00-7d,80-ff:8000-ffff mask=0x8000
|
||||
ram
|
||||
memory type=RAM content=Save
|
||||
map address=70-7d,f0-ff:0000-7fff mask=0x8000
|
||||
|
||||
board: SHVC-1A3B-(11,12,13)
|
||||
rom
|
||||
memory type=ROM content=Program
|
||||
map address=00-1f,80-9f:8000-ffff mask=0x8000
|
||||
ram
|
||||
memory type=RAM content=Save
|
||||
map address=70-7d,f0-ff:0000-ffff
|
||||
|
||||
board: SHVC-1A3B-20
|
||||
rom
|
||||
memory type=ROM content=Program
|
||||
map address=00-7d,80-ff:8000-ffff mask=0x8000
|
||||
ram
|
||||
memory type=RAM content=Save
|
||||
map address=70-7d,f0-ff:0000-7fff mask=0x8000
|
||||
|
||||
board: SHVC-1A3M-(10,20,21,30)
|
||||
rom
|
||||
memory type=ROM content=Program
|
||||
map address=00-7d,80-ff:8000-ffff mask=0x8000
|
||||
ram
|
||||
memory type=RAM content=Save
|
||||
map address=70-7d,f0-ff:0000-7fff mask=0x8000
|
||||
|
||||
board: SHVC-1A5B-(02,04)
|
||||
rom
|
||||
memory type=ROM content=Program
|
||||
map address=00-1f,80-9f:8000-ffff mask=0x8000
|
||||
ram
|
||||
memory type=RAM content=Save
|
||||
map address=70-7d,f0-ff:0000-ffff
|
||||
|
||||
board: SHVC-1A5M-(01,11,20)
|
||||
rom
|
||||
memory type=ROM content=Program
|
||||
map address=00-7d,80-ff:8000-ffff mask=0x8000
|
||||
ram
|
||||
memory type=RAM content=Save
|
||||
map address=70-7d,f0-ff:0000-7fff mask=0x8000
|
||||
|
||||
board: SHVC-1B0N-(02,03,10)
|
||||
rom
|
||||
memory type=ROM content=Program
|
||||
map address=00-1f,80-9f:8000-ffff mask=0x8000
|
||||
necdsp model=uPD7725 frequency=8000000
|
||||
necdsp model=uPD7725
|
||||
map address=30-3f,b0-bf:8000-ffff mask=0x3fff
|
||||
prom
|
||||
drom
|
||||
dram
|
||||
memory type=ROM content=Program architecture=uPD7725
|
||||
memory type=ROM content=Data architecture=uPD7725
|
||||
memory type=RAM content=Data architecture=uPD7725
|
||||
oscillator
|
||||
|
||||
board: SHVC-1B5B-02
|
||||
rom
|
||||
memory type=ROM content=Program
|
||||
map address=00-1f,80-9f:8000-ffff mask=0x8000
|
||||
ram
|
||||
memory type=RAM content=Save
|
||||
map address=70-7d,f0-ff:0000-ffff
|
||||
necdsp model=uPD7725 frequency=8000000
|
||||
necdsp model=uPD7725
|
||||
map address=20-3f,a0-bf:8000-ffff mask=0x3fff
|
||||
prom
|
||||
drom
|
||||
dram
|
||||
memory type=ROM content=Program architecture=uPD7725
|
||||
memory type=ROM content=Data architecture=uPD7725
|
||||
memory type=RAM content=Data architecture=uPD7725
|
||||
oscillator
|
||||
|
||||
board: SHVC-1C0N
|
||||
superfx
|
||||
map address=00-3f,80-bf:3000-34ff
|
||||
rom
|
||||
memory type=ROM content=Program
|
||||
map address=00-1f,80-9f:8000-ffff mask=0x8000
|
||||
ram
|
||||
memory type=RAM content=Save
|
||||
map address=60-7d,e0-ff:0000-ffff
|
||||
|
||||
board: SHVC-1C0N5S-01
|
||||
superfx
|
||||
map address=00-3f,80-bf:3000-34ff
|
||||
rom
|
||||
memory type=ROM content=Program
|
||||
map address=00-1f,80-9f:8000-ffff mask=0x8000
|
||||
ram
|
||||
memory type=RAM content=Save
|
||||
map address=60-7d,e0-ff:0000-ffff
|
||||
|
||||
board: SHVC-1CA0N5S-01
|
||||
superfx
|
||||
map address=00-3f,80-bf:3000-34ff
|
||||
rom
|
||||
memory type=ROM content=Program
|
||||
map address=00-3f,80-bf:8000-ffff mask=0x8000
|
||||
map address=40-5f,c0-df:0000-ffff
|
||||
ram
|
||||
memory type=RAM content=Save
|
||||
map address=00-3f,80-bf:6000-7fff size=0x2000
|
||||
map address=70-71,f0-f1:0000-ffff
|
||||
|
||||
board: SHVC-1CA0N6S-01
|
||||
superfx
|
||||
map address=00-3f,80-bf:3000-34ff
|
||||
rom
|
||||
memory type=ROM content=Program
|
||||
map address=00-3f,80-bf:8000-ffff mask=0x8000
|
||||
map address=40-5f,c0-df:0000-ffff
|
||||
ram
|
||||
memory type=RAM content=Save
|
||||
map address=00-3f,80-bf:6000-7fff size=0x2000
|
||||
map address=70-71,f0-f1:0000-ffff
|
||||
|
||||
board: SHVC-1CA6B-01
|
||||
superfx
|
||||
map address=00-3f,80-bf:3000-34ff
|
||||
rom
|
||||
memory type=ROM content=Program
|
||||
map address=00-3f,80-bf:8000-ffff mask=0x8000
|
||||
map address=40-5f,c0-df:0000-ffff
|
||||
ram
|
||||
memory type=RAM content=Save
|
||||
map address=00-3f,80-bf:6000-7fff size=0x2000
|
||||
map address=70-71,f0-f1:0000-ffff
|
||||
|
||||
board: SHVC-1CB0N7S-01
|
||||
superfx
|
||||
map address=00-3f,80-bf:3000-34ff
|
||||
rom
|
||||
memory type=ROM content=Program
|
||||
map address=00-3f:8000-ffff mask=0x8000
|
||||
map address=40-5f:0000-ffff
|
||||
ram
|
||||
memory type=RAM content=Save
|
||||
map address=00-3f,80-bf:6000-7fff size=0x2000
|
||||
map address=70-71:0000-ffff
|
||||
|
||||
board: SHVC-1CB5B-20
|
||||
superfx
|
||||
map address=00-3f,80-bf:3000-34ff
|
||||
rom
|
||||
memory type=ROM content=Program
|
||||
map address=00-3f:8000-ffff mask=0x8000
|
||||
map address=40-5f:0000-ffff
|
||||
ram
|
||||
memory type=RAM content=Save
|
||||
map address=00-3f,80-bf:6000-7fff size=0x2000
|
||||
map address=70-71:0000-ffff
|
||||
|
||||
board: SHVC-1CB7B-01
|
||||
superfx
|
||||
map address=00-3f,80-bf:3000-34ff
|
||||
rom
|
||||
memory type=ROM content=Program
|
||||
map address=00-3f:8000-ffff mask=0x8000
|
||||
map address=40-5f:0000-ffff
|
||||
ram
|
||||
memory type=RAM content=Save
|
||||
map address=00-3f,80-bf:6000-7fff size=0x2000
|
||||
map address=70-71:0000-ffff
|
||||
|
||||
board: SHVC-1DC0N-01
|
||||
hitachidsp model=HG51B169 frequency=20000000
|
||||
hitachidsp model=HG51BS169
|
||||
map address=00-3f,80-bf:6c00-6fff,7c00-7fff
|
||||
map address=70-77:0000-7fff
|
||||
rom
|
||||
memory type=ROM content=Program
|
||||
map address=00-3f,80-bf:8000-ffff mask=0x8000
|
||||
drom
|
||||
dram
|
||||
memory type=ROM content=Data architecture=HG51BS169
|
||||
memory type=RAM content=Data architecture=HG51BS169
|
||||
map address=00-3f,80-bf:6000-6bff,7000-7bff mask=0xf000
|
||||
oscillator
|
||||
|
||||
board: SHVC-1DS0B-20
|
||||
rom
|
||||
memory type=ROM content=Program
|
||||
map address=00-7d,80-ff:8000-ffff mask=0x8000
|
||||
necdsp model=uPD96050 frequency=11000000
|
||||
necdsp model=uPD96050
|
||||
map address=60-67,e0-e7:0000-3fff
|
||||
prom
|
||||
drom
|
||||
dram
|
||||
memory type=ROM content=Program architecture=uPD96050
|
||||
memory type=ROM content=Data architecture=uPD96050
|
||||
memory type=RAM content=Data architecture=uPD96050
|
||||
map address=68-6f,e8-ef:0000-7fff mask=0x8000
|
||||
oscillator
|
||||
|
||||
board: SHVC-1J0N-(01,10,20)
|
||||
rom
|
||||
memory type=ROM content=Program
|
||||
map address=00-3f,80-bf:8000-ffff
|
||||
map address=40-7d,c0-ff:0000-ffff
|
||||
|
||||
board: SHVC-1J1M-(11,20)
|
||||
rom
|
||||
memory type=ROM content=Program
|
||||
map address=00-3f,80-bf:8000-ffff
|
||||
map address=40-7d,c0-ff:0000-ffff
|
||||
ram
|
||||
memory type=RAM content=Save
|
||||
map address=20-3f,a0-bf:6000-7fff mask=0xe000
|
||||
|
||||
board: SHVC-1J3B-01
|
||||
rom
|
||||
memory type=ROM content=Program
|
||||
map address=00-3f,80-bf:8000-ffff
|
||||
map address=40-7d,c0-ff:0000-ffff
|
||||
ram
|
||||
memory type=RAM content=Save
|
||||
map address=20-3f,a0-bf:6000-7fff mask=0xe000
|
||||
|
||||
board: SHVC-1J3M-(01,11,20)
|
||||
rom
|
||||
memory type=ROM content=Program
|
||||
map address=00-3f,80-bf:8000-ffff
|
||||
map address=40-7d,c0-ff:0000-ffff
|
||||
ram
|
||||
memory type=RAM content=Save
|
||||
map address=20-3f,a0-bf:6000-7fff mask=0xe000
|
||||
|
||||
board: SHVC-1J5M-(01,11,20)
|
||||
rom
|
||||
memory type=ROM content=Program
|
||||
map address=00-3f,80-bf:8000-ffff
|
||||
map address=40-7d,c0-ff:0000-ffff
|
||||
ram
|
||||
memory type=RAM content=Save
|
||||
map address=20-3f,a0-bf:6000-7fff mask=0xe000
|
||||
|
||||
board: SHVC-1K0N-01
|
||||
rom
|
||||
memory type=ROM content=Program
|
||||
map address=00-3f,80-bf:8000-ffff
|
||||
map address=40-7d,c0-ff:0000-ffff
|
||||
necdsp model=uPD7725 frequency=8000000
|
||||
necdsp model=uPD7725
|
||||
map address=00-1f,80-9f:6000-7fff mask=0xfff
|
||||
prom
|
||||
drom
|
||||
dram
|
||||
memory type=ROM content=Program architecture=uPD7725
|
||||
memory type=ROM content=Data architecture=uPD7725
|
||||
memory type=RAM content=Data architecture=uPD7725
|
||||
oscillator
|
||||
|
||||
board: SHVC-1K1B-01
|
||||
rom
|
||||
memory type=ROM content=Program
|
||||
map address=00-3f,80-bf:8000-ffff
|
||||
map address=40-7d,c0-ff:0000-ffff
|
||||
ram
|
||||
memory type=RAM content=Save
|
||||
map address=20-3f,a0-bf:6000-7fff mask=0xe000
|
||||
necdsp model=uPD7725 frequency=8000000
|
||||
necdsp model=uPD7725
|
||||
map address=00-1f,80-9f:6000-7fff mask=0xfff
|
||||
prom
|
||||
drom
|
||||
dram
|
||||
memory type=ROM content=Program architecture=uPD7725
|
||||
memory type=ROM content=Data architecture=uPD7725
|
||||
memory type=RAM content=Data architecture=uPD7725
|
||||
oscillator
|
||||
|
||||
board: SHVC-1L0N3S-01
|
||||
sa1
|
||||
map address=00-3f,80-bf:2200-23ff
|
||||
rom
|
||||
memory type=ROM content=Program
|
||||
map address=00-3f,80-bf:8000-ffff mask=0x408000
|
||||
map address=c0-ff:0000-ffff
|
||||
bwram
|
||||
memory type=RAM content=Save
|
||||
map address=00-3f,80-bf:6000-7fff size=0x2000
|
||||
map address=40-4f:0000-ffff
|
||||
iram
|
||||
memory type=RAM content=Internal
|
||||
map address=00-3f,80-bf:3000-37ff size=0x800
|
||||
|
||||
board: SHVC-1L3B-(02,11)
|
||||
sa1
|
||||
map address=00-3f,80-bf:2200-23ff
|
||||
rom
|
||||
memory type=ROM content=Program
|
||||
map address=00-3f,80-bf:8000-ffff mask=0x408000
|
||||
map address=c0-ff:0000-ffff
|
||||
bwram
|
||||
memory type=RAM content=Save
|
||||
map address=00-3f,80-bf:6000-7fff size=0x2000
|
||||
map address=40-4f:0000-ffff
|
||||
iram
|
||||
memory type=RAM content=Internal
|
||||
map address=00-3f,80-bf:3000-37ff size=0x800
|
||||
|
||||
board: SHVC-1L5B-(11,20)
|
||||
sa1
|
||||
map address=00-3f,80-bf:2200-23ff
|
||||
rom
|
||||
memory type=ROM content=Program
|
||||
map address=00-3f,80-bf:8000-ffff mask=0x408000
|
||||
map address=c0-ff:0000-ffff
|
||||
bwram
|
||||
memory type=RAM content=Save
|
||||
map address=00-3f,80-bf:6000-7fff size=0x2000
|
||||
map address=40-4f:0000-ffff
|
||||
iram
|
||||
memory type=RAM content=Internal
|
||||
map address=00-3f,80-bf:3000-37ff size=0x800
|
||||
|
||||
board: SHVC-1N0N-(01,10)
|
||||
sdd1
|
||||
map address=00-3f,80-bf:4800-480f
|
||||
rom
|
||||
memory type=ROM content=Program
|
||||
map address=00-3f,80-bf:8000-ffff
|
||||
map address=c0-ff:0000-ffff
|
||||
|
||||
board: SHVC-2A0N-01#R
|
||||
rom
|
||||
board: SHVC-2A0N-01#A
|
||||
memory type=ROM content=Program
|
||||
map address=00-2f,80-af:8000-ffff mask=0x8000
|
||||
map address=40-6f,c0-ef:0000-ffff mask=0x8000
|
||||
|
||||
board: SHVC-2A0N-(01,10,11,20)
|
||||
rom
|
||||
memory type=ROM content=Program
|
||||
map address=00-7d,80-ff:8000-ffff mask=0x8000
|
||||
map address=40-7d,c0-ff:0000-7fff mask=0x8000
|
||||
|
||||
board: SHVC-2A1M-01
|
||||
rom
|
||||
memory type=ROM content=Program
|
||||
map address=00-7d,80-ff:8000-ffff mask=0x8000
|
||||
ram
|
||||
memory type=RAM content=Save
|
||||
map address=70-7d,f0-ff:0000-7fff mask=0x8000
|
||||
|
||||
board: SHVC-2A3B-01
|
||||
rom
|
||||
memory type=ROM content=Program
|
||||
map address=00-3f,80-bf:8000-ffff mask=0x8000
|
||||
ram
|
||||
memory type=RAM content=Save
|
||||
map address=70-7d,f0-ff:0000-7fff mask=0x8000
|
||||
|
||||
board: SHVC-2A3M-01#R
|
||||
rom
|
||||
board: SHVC-2A3M-01#A
|
||||
memory type=ROM content=Program
|
||||
map address=00-3f,80-bf:8000-ffff mask=0x8000
|
||||
ram
|
||||
memory type=RAM content=Save
|
||||
map address=70-7d,f0-ff:0000-7fff mask=0x8000
|
||||
|
||||
board: SHVC-2A3M-(01,11,20)
|
||||
rom
|
||||
memory type=ROM content=Program
|
||||
map address=00-7d,80-ff:8000-ffff mask=0x8000
|
||||
ram
|
||||
memory type=RAM content=Save
|
||||
map address=70-7d,f0-ff:0000-7fff mask=0x8000
|
||||
|
||||
board: SHVC-2A5M-01
|
||||
rom
|
||||
memory type=ROM content=Program
|
||||
map address=00-7d,80-ff:8000-ffff mask=0x8000
|
||||
ram
|
||||
memory type=RAM content=Save
|
||||
map address=70-7d,f0-ff:0000-7fff mask=0x8000
|
||||
|
||||
board: SHVC-2B3B-01
|
||||
rom
|
||||
memory type=ROM content=Program
|
||||
map address=00-3f,80-bf:8000-ffff mask=0x8000
|
||||
ram
|
||||
memory type=RAM content=Save
|
||||
map address=70-7d,f0-ff:0000-7fff mask=0x8000
|
||||
necdsp model=uPD7725 frequency=8000000
|
||||
necdsp model=uPD7725
|
||||
map address=60-6f,e0-ef:0000-7fff mask=0x3fff
|
||||
prom
|
||||
drom
|
||||
dram
|
||||
memory type=ROM content=Program architecture=uPD7725
|
||||
memory type=ROM content=Data architecture=uPD7725
|
||||
memory type=RAM content=Data architecture=uPD7725
|
||||
oscillator
|
||||
|
||||
board: SHVC-2DC0N-01
|
||||
hitachidsp model=HG51B169 frequency=20000000
|
||||
hitachidsp model=HG51BS169
|
||||
map address=00-3f,80-bf:6c00-6fff,7c00-7fff
|
||||
map address=70-77:0000-7fff
|
||||
rom
|
||||
memory type=ROM content=Program
|
||||
map address=00-3f,80-bf:8000-ffff mask=0x8000
|
||||
drom
|
||||
dram
|
||||
memory type=ROM content=Data architecture=HG51BS169
|
||||
memory type=RAM content=Data architecture=HG51BS169
|
||||
map address=00-3f,80-bf:6000-6bff,7000-7bff mask=0xf000
|
||||
oscillator
|
||||
|
||||
board: SHVC-2E3M-01
|
||||
rom
|
||||
memory type=ROM content=Program
|
||||
map address=00-3f,80-bf:8000-ffff mask=0x8000
|
||||
obc1
|
||||
map address=00-3f,80-bf:6000-7fff mask=0xe000
|
||||
map address=70-71,f0-f1:6000-7fff,e000-ffff mask=0xe000
|
||||
ram
|
||||
memory type=RAM content=Save
|
||||
|
||||
board: SHVC-2J0N-(01,10,11,20)
|
||||
rom
|
||||
memory type=ROM content=Program
|
||||
map address=00-3f,80-bf:8000-ffff
|
||||
map address=40-7d,c0-ff:0000-ffff
|
||||
|
||||
board: SHVC-2J3M-(01,11,20)
|
||||
rom
|
||||
memory type=ROM content=Program
|
||||
map address=00-3f,80-bf:8000-ffff
|
||||
map address=40-7d,c0-ff:0000-ffff
|
||||
ram
|
||||
memory type=RAM content=Save
|
||||
map address=10-1f,30-3f,90-9f,b0-bf:6000-7fff mask=0xe000
|
||||
|
||||
board: SHVC-2J5M-01
|
||||
rom
|
||||
memory type=ROM content=Program
|
||||
map address=00-3f,80-bf:8000-ffff
|
||||
map address=40-7d,c0-ff:0000-ffff
|
||||
ram
|
||||
memory type=RAM content=Save
|
||||
map address=10-1f,30-3f,90-9f,b0-bf:6000-7fff mask=0xe000
|
||||
|
||||
board: SHVC-3J0N-01
|
||||
rom
|
||||
memory type=ROM content=Program
|
||||
map address=00-2f,80-af:8000-ffff
|
||||
map address=40-6f,c0-ef:0000-ffff
|
||||
|
||||
board: SHVC-BA0N-(01,10)
|
||||
rom
|
||||
memory type=ROM content=Program
|
||||
map address=00-7d,80-ff:8000-ffff mask=0x8000
|
||||
map address=40-7d,c0-ff:0000-7fff mask=0x8000
|
||||
|
||||
board: SHVC-BA1M-01
|
||||
rom
|
||||
memory type=ROM content=Program
|
||||
map address=00-7d,80-ff:8000-ffff mask=0x8000
|
||||
ram
|
||||
memory type=RAM content=Save
|
||||
map address=70-7d,f0-ff:0000-7fff mask=0x8000
|
||||
|
||||
board: SHVC-BA3M-(01,10)
|
||||
rom
|
||||
memory type=ROM content=Program
|
||||
map address=00-7d,80-ff:8000-ffff mask=0x8000
|
||||
ram
|
||||
memory type=RAM content=Save
|
||||
map address=70-7d,f0-ff:0000-7fff mask=0x8000
|
||||
|
||||
board: SHVC-BJ0N-(01,20)
|
||||
rom
|
||||
memory type=ROM content=Program
|
||||
map address=00-3f,80-bf:8000-ffff
|
||||
map address=40-7d,c0-ff:0000-ffff
|
||||
|
||||
board: SHVC-BJ1M-(10,20)
|
||||
rom
|
||||
memory type=ROM content=Program
|
||||
map address=00-3f,80-bf:8000-ffff
|
||||
map address=40-7d,c0-ff:0000-ffff
|
||||
ram
|
||||
memory type=RAM content=Save
|
||||
map address=20-3f,a0-bf:6000-7fff mask=0xe000
|
||||
|
||||
board: SHVC-BJ3M-10
|
||||
rom
|
||||
memory type=ROM content=Program
|
||||
map address=00-3f,80-bf:8000-ffff
|
||||
map address=40-7d,c0-ff:0000-ffff
|
||||
ram
|
||||
memory type=RAM content=Save
|
||||
map address=20-3f,a0-bf:6000-7fff mask=0xe000
|
||||
|
||||
board: SHVC-LDH3C-01
|
||||
|
@ -493,40 +501,41 @@ board: SHVC-LDH3C-01
|
|||
map address=50,58:0000-ffff
|
||||
map=mcu address=00-3f,80-bf:8000-ffff mask=0x800000
|
||||
map=mcu address=c0-ff:0000-ffff mask=0xc00000
|
||||
prom
|
||||
drom
|
||||
ram
|
||||
memory type=ROM content=Program
|
||||
memory type=ROM content=Data
|
||||
memory type=RAM content=Save
|
||||
map address=00-3f,80-bf:6000-7fff mask=0xe000
|
||||
epsonrtc
|
||||
map address=00-3f,80-bf:4840-4842
|
||||
ram
|
||||
memory type=RTC content=Time manufacturer=Epson
|
||||
|
||||
board: SHVC-LN3B-01
|
||||
sdd1
|
||||
map address=00-3f,80-bf:4800-480f
|
||||
rom
|
||||
memory type=ROM content=Program
|
||||
map address=00-3f,80-bf:8000-ffff
|
||||
map address=c0-ff:0000-ffff
|
||||
ram
|
||||
memory type=RAM content=Save
|
||||
map address=00-3f,80-bf:6000-7fff mask=0xe000
|
||||
map address=70-73:0000-ffff
|
||||
|
||||
board: SHVC-SGB2-01
|
||||
rom
|
||||
memory type=ROM content=Program
|
||||
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
|
||||
icd revision=2
|
||||
map address=00-3f,80-bf:6000-67ff,7000-7fff
|
||||
rom
|
||||
gameboy
|
||||
memory type=ROM content=Boot architecture=LR35902
|
||||
oscillator
|
||||
slot type=GameBoy
|
||||
|
||||
board: SHVC-YA0N-01
|
||||
rom
|
||||
memory type=ROM content=Program
|
||||
map address=00-7d,80-ff:8000-ffff mask=0x8000
|
||||
map address=40-7d,c0-ff:0000-7fff mask=0x8000
|
||||
|
||||
board: SHVC-YJ0N-01
|
||||
rom
|
||||
memory type=ROM content=Program
|
||||
map address=00-3f,80-bf:8000-ffff
|
||||
map address=40-7d,c0-ff:0000-ffff
|
||||
|
||||
|
|
|
@ -62,60 +62,50 @@ auto Cartridge::load() -> bool {
|
|||
|
||||
auto document = BML::unserialize(information.manifest);
|
||||
|
||||
if(auto node = document["board/rom"]) {
|
||||
rom.name = node["name"].text();
|
||||
rom.size = node["size"].natural();
|
||||
if(auto memory = Emulator::Game::Memory{document["game/board/memory(type=ROM,content=Program)"]}) {
|
||||
rom.size = memory.size;
|
||||
rom.mask = bit::round(rom.size) - 1;
|
||||
if(rom.size) {
|
||||
rom.data = new uint8[rom.mask + 1];
|
||||
memory::fill(rom.data, rom.mask + 1, 0xff);
|
||||
if(rom.name) if(auto fp = platform->open(pathID(), rom.name, File::Read, File::Required)) {
|
||||
if(auto fp = platform->open(pathID(), memory.name(), File::Read, File::Required)) {
|
||||
fp->read(rom.data, rom.size);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(auto node = document["board/ram"]) {
|
||||
if(node["type"].text() == "sram") {
|
||||
ram.name = node["name"].text();
|
||||
ram.size = node["size"].natural();
|
||||
if(auto memory = Emulator::Game::Memory{document["game/board/memory(type=RAM,content=Save)"]}) {
|
||||
ram.size = memory.size;
|
||||
ram.mask = bit::round(ram.size) - 1;
|
||||
if(ram.size) {
|
||||
ram.data = new uint8[ram.mask + 1];
|
||||
memory::fill(ram.data, ram.mask + 1, 0xff);
|
||||
if(ram.name) if(auto fp = platform->open(pathID(), ram.name, File::Read)) {
|
||||
if(memory.nonVolatile) {
|
||||
if(auto fp = platform->open(pathID(), memory.name(), File::Read)) {
|
||||
fp->read(ram.data, ram.size);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(node["type"].text() == "eeprom") {
|
||||
eeprom.setName(node["name"].text());
|
||||
eeprom.setSize(node["size"].natural() / sizeof(uint16));
|
||||
if(eeprom.size()) {
|
||||
if(auto memory = Emulator::Game::Memory{document["game/board/memory(type=EEPROM,content=Save)"]}) {
|
||||
eeprom.setSize(memory.size / sizeof(uint16));
|
||||
eeprom.erase();
|
||||
if(eeprom.name()) if(auto fp = platform->open(pathID(), eeprom.name(), File::Read)) {
|
||||
if(auto fp = platform->open(pathID(), memory.name(), File::Read)) {
|
||||
fp->read(eeprom.data(), eeprom.size());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(auto node = document["board/rtc"]) {
|
||||
rtc.name = node["name"].text();
|
||||
rtc.size = node["size"].natural();
|
||||
if(auto memory = Emulator::Game::Memory{document["game/board/memory(type=RTC,content=Time)"]}) {
|
||||
rtc.size = memory.size;
|
||||
rtc.mask = bit::round(rtc.size) - 1;
|
||||
if(rtc.size) {
|
||||
rtc.data = new uint8[rtc.mask + 1];
|
||||
memory::fill(rtc.data, rtc.mask + 1, 0x00);
|
||||
if(rtc.name) if(auto fp = platform->open(pathID(), rtc.name, File::Read)) {
|
||||
if(memory.nonVolatile) {
|
||||
if(auto fp = platform->open(pathID(), memory.name(), File::Read)) {
|
||||
fp->read(rtc.data, rtc.size);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
information.title = document["information/title"].text();
|
||||
information.orientation = document["information/orientation"].text() == "vertical";
|
||||
information.title = document["game/label"].text();
|
||||
information.orientation = document["game/orientation"].text() == "vertical";
|
||||
information.sha256 = Hash::SHA256(rom.data, rom.size).digest();
|
||||
return true;
|
||||
}
|
||||
|
@ -123,43 +113,44 @@ auto Cartridge::load() -> bool {
|
|||
auto Cartridge::save() -> void {
|
||||
auto document = BML::unserialize(information.manifest);
|
||||
|
||||
if(auto name = document["board/ram/name"].text()) {
|
||||
if(auto fp = platform->open(pathID(), name, File::Write)) {
|
||||
if(auto memory = Emulator::Game::Memory{document["game/board/memory(type=RAM,content=Save)"]}) {
|
||||
if(memory.nonVolatile) {
|
||||
if(auto fp = platform->open(pathID(), memory.name(), File::Write)) {
|
||||
fp->write(ram.data, ram.size);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(auto name = document["board/eeprom/name"].text()) {
|
||||
if(auto fp = platform->open(pathID(), name, File::Write)) {
|
||||
if(auto memory = Emulator::Game::Memory{document["game/board/memory(type=EEPROM,content=Save)"]}) {
|
||||
if(auto fp = platform->open(pathID(), memory.name(), File::Write)) {
|
||||
fp->write(eeprom.data(), eeprom.size());
|
||||
}
|
||||
}
|
||||
|
||||
if(auto name = document["board/rtc/name"].text()) {
|
||||
if(auto fp = platform->open(pathID(), name, File::Write)) {
|
||||
if(auto memory = Emulator::Game::Memory{document["game/board/memory(type=RTC,content=Time)"]}) {
|
||||
if(memory.nonVolatile) {
|
||||
if(auto fp = platform->open(pathID(), memory.name(), File::Write)) {
|
||||
fp->write(rtc.data, rtc.size);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
auto Cartridge::unload() -> void {
|
||||
delete[] rom.data;
|
||||
rom.data = nullptr;
|
||||
rom.size = 0;
|
||||
rom.mask = 0;
|
||||
rom.name = "";
|
||||
|
||||
delete[] ram.data;
|
||||
ram.data = nullptr;
|
||||
ram.size = 0;
|
||||
ram.mask = 0;
|
||||
ram.name = "";
|
||||
|
||||
delete[] rtc.data;
|
||||
rtc.data = nullptr;
|
||||
rtc.size = 0;
|
||||
rtc.mask = 0;
|
||||
rtc.name = "";
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -66,7 +66,6 @@ struct Cartridge : Thread, IO {
|
|||
uint8* data = nullptr;
|
||||
uint size = 0;
|
||||
uint mask = 0;
|
||||
string name;
|
||||
};
|
||||
|
||||
struct RTC : Memory {
|
||||
|
|
|
@ -4,14 +4,9 @@ namespace WonderSwan {
|
|||
|
||||
#include "serialization.cpp"
|
||||
|
||||
auto EEPROM::name() const -> string { return _name; }
|
||||
auto EEPROM::data() -> uint16* { return _data; }
|
||||
auto EEPROM::size() const -> uint { return _size; }
|
||||
|
||||
auto EEPROM::setName(string name) -> void {
|
||||
_name = name;
|
||||
}
|
||||
|
||||
auto EEPROM::setSize(uint size) -> void {
|
||||
_size = bit::round(size);
|
||||
}
|
||||
|
|
|
@ -14,7 +14,6 @@ struct EEPROM {
|
|||
Command = Status,
|
||||
};
|
||||
|
||||
auto name() const -> string;
|
||||
auto data() -> uint16*;
|
||||
auto size() const -> uint;
|
||||
|
||||
|
@ -34,7 +33,6 @@ struct EEPROM {
|
|||
private:
|
||||
auto execute() -> void;
|
||||
|
||||
string _name;
|
||||
uint16 _data[1024];
|
||||
uint _size = 0; //in words
|
||||
|
||||
|
|
|
@ -28,12 +28,11 @@ auto System::load(Emulator::Interface* interface, Model model) -> bool {
|
|||
//note: IPLROM is currently undumped; otherwise we'd load it here ...
|
||||
|
||||
if(auto node = document["system/eeprom"]) {
|
||||
eeprom.setName(node["name"].text());
|
||||
eeprom.setSize(node["size"].natural() / sizeof(uint16));
|
||||
eeprom.erase();
|
||||
//initialize user-data section
|
||||
for(uint addr = 0x0030; addr <= 0x003a; addr++) eeprom[addr] = 0x0000;
|
||||
if(auto fp = platform->open(ID::System, eeprom.name(), File::Read)) {
|
||||
if(auto fp = platform->open(ID::System, node["name"].text(), File::Read)) {
|
||||
fp->read(eeprom.data(), eeprom.size());
|
||||
}
|
||||
}
|
||||
|
@ -55,7 +54,6 @@ auto System::save() -> void {
|
|||
auto System::unload() -> void {
|
||||
if(!loaded()) return;
|
||||
|
||||
eeprom.setName("");
|
||||
eeprom.setSize(0);
|
||||
|
||||
cartridge.unload();
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
database
|
||||
revision: 2018-03-13
|
||||
revision: 2018-04-15
|
||||
|
||||
//BS Memory (JPN)
|
||||
|
||||
database
|
||||
revision: 2018-02-12
|
||||
revision: 2018-04-14
|
||||
|
||||
game
|
||||
sha256: 80c34b50817d58820bc8c88d2d9fa462550b4a76372e19c6467cbfbc8cf5d9ef
|
||||
|
@ -16,7 +16,7 @@ game
|
|||
memory
|
||||
type: ROM
|
||||
size: 0x80000
|
||||
category: Program
|
||||
content: Program
|
||||
|
||||
game
|
||||
sha256: 859c7f7b4771d920a5bdb11f1d247ab6b43fb026594d1062f6f72d32cd340a0a
|
||||
|
@ -28,7 +28,7 @@ game
|
|||
memory
|
||||
type: ROM
|
||||
size: 0x80000
|
||||
category: Program
|
||||
content: Program
|
||||
|
||||
game
|
||||
sha256: c92a15fdd9b0133f9ea69105d0230a3acd1cdeef98567462eca86ea02a959e4e
|
||||
|
@ -40,5 +40,5 @@ game
|
|||
memory
|
||||
type: ROM
|
||||
size: 0x80000
|
||||
category: Program
|
||||
content: Program
|
||||
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
database
|
||||
revision: 2018-03-13
|
||||
revision: 2018-04-15
|
||||
|
||||
//Sufami Turbo (JPN)
|
||||
|
||||
database
|
||||
revision: 2018-02-12
|
||||
revision: 2018-04-14
|
||||
|
||||
game
|
||||
sha256: f73bda08743565e0bd101632ebbac2d363d703a3ab39d23f49d95217cab29269
|
||||
|
@ -16,7 +16,7 @@ game
|
|||
memory
|
||||
type: ROM
|
||||
size: 0x100000
|
||||
category: Program
|
||||
content: Program
|
||||
note: Unlinkable
|
||||
|
||||
game
|
||||
|
@ -29,7 +29,7 @@ game
|
|||
memory
|
||||
type: ROM
|
||||
size: 0x80000
|
||||
category: Program
|
||||
content: Program
|
||||
note: Unlinkable
|
||||
|
||||
game
|
||||
|
@ -42,7 +42,7 @@ game
|
|||
memory
|
||||
type: ROM
|
||||
size: 0x80000
|
||||
category: Program
|
||||
content: Program
|
||||
note: Unlinkable
|
||||
|
||||
game
|
||||
|
@ -55,7 +55,7 @@ game
|
|||
memory
|
||||
type: ROM
|
||||
size: 0x80000
|
||||
category: Program
|
||||
content: Program
|
||||
note: Unlinkable
|
||||
|
||||
game
|
||||
|
@ -68,12 +68,11 @@ game
|
|||
memory
|
||||
type: ROM
|
||||
size: 0x80000
|
||||
category: Program
|
||||
content: Program
|
||||
memory
|
||||
type: RAM
|
||||
battery
|
||||
size: 0x800
|
||||
category: Save
|
||||
content: Save
|
||||
note: Linkable: SFT-0103-JPN
|
||||
|
||||
game
|
||||
|
@ -86,12 +85,11 @@ game
|
|||
memory
|
||||
type: ROM
|
||||
size: 0x80000
|
||||
category: Program
|
||||
content: Program
|
||||
memory
|
||||
type: RAM
|
||||
battery
|
||||
size: 0x2000
|
||||
category: Save
|
||||
content: Save
|
||||
note: Linkable: SFT-0104-JPN, SFT-0105-JPN, SFT-0107-JPN, SFT-0108-JPN, SFT-0110-JPN, SFT-0111-JPN
|
||||
|
||||
game
|
||||
|
@ -104,12 +102,11 @@ game
|
|||
memory
|
||||
type: ROM
|
||||
size: 0x80000
|
||||
category: Program
|
||||
content: Program
|
||||
memory
|
||||
type: RAM
|
||||
battery
|
||||
size: 0x2000
|
||||
category: Save
|
||||
content: Save
|
||||
note: Linkable: SFT-0104-JPN, SFT-0105-JPN, SFT-0107-JPN, SFT-0108-JPN, SFT-0110-JPN, SFT-0111-JPN
|
||||
|
||||
game
|
||||
|
@ -122,12 +119,11 @@ game
|
|||
memory
|
||||
type: ROM
|
||||
size: 0x80000
|
||||
category: Program
|
||||
content: Program
|
||||
memory
|
||||
type: RAM
|
||||
battery
|
||||
size: 0x2000
|
||||
category: Save
|
||||
content: Save
|
||||
note: Linkable: SFT-0104-JPN, SFT-0105-JPN, SFT-0107-JPN, SFT-0108-JPN, SFT-0110-JPN, SFT-0111-JPN
|
||||
|
||||
game
|
||||
|
@ -140,12 +136,11 @@ game
|
|||
memory
|
||||
type: ROM
|
||||
size: 0x80000
|
||||
category: Program
|
||||
content: Program
|
||||
memory
|
||||
type: RAM
|
||||
battery
|
||||
size: 0x2000
|
||||
category: Save
|
||||
content: Save
|
||||
note: Linkable: SFT-0104-JPN, SFT-0105-JPN, SFT-0107-JPN, SFT-0108-JPN, SFT-0110-JPN, SFT-0111-JPN
|
||||
|
||||
game
|
||||
|
@ -158,12 +153,11 @@ game
|
|||
memory
|
||||
type: ROM
|
||||
size: 0x80000
|
||||
category: Program
|
||||
content: Program
|
||||
memory
|
||||
type: RAM
|
||||
battery
|
||||
size: 0x2000
|
||||
category: Save
|
||||
content: Save
|
||||
note: Linkable: SFT-0104-JPN, SFT-0105-JPN, SFT-0107-JPN, SFT-0108-JPN, SFT-0110-JPN, SFT-0111-JPN
|
||||
|
||||
game
|
||||
|
@ -176,12 +170,11 @@ game
|
|||
memory
|
||||
type: ROM
|
||||
size: 0x80000
|
||||
category: Program
|
||||
content: Program
|
||||
memory
|
||||
type: RAM
|
||||
battery
|
||||
size: 0x2000
|
||||
category: Save
|
||||
content: Save
|
||||
note: Linkable: SFT-0104-JPN, SFT-0105-JPN, SFT-0107-JPN, SFT-0108-JPN, SFT-0110-JPN, SFT-0111-JPN
|
||||
|
||||
game
|
||||
|
@ -194,12 +187,11 @@ game
|
|||
memory
|
||||
type: ROM
|
||||
size: 0x80000
|
||||
category: Program
|
||||
content: Program
|
||||
memory
|
||||
type: RAM
|
||||
battery
|
||||
size: 0x800
|
||||
category: Save
|
||||
content: Save
|
||||
note: Linkable: SFT-0101-JPN, SFT-0102-JPN
|
||||
|
||||
game
|
||||
|
@ -212,11 +204,10 @@ game
|
|||
memory
|
||||
type: ROM
|
||||
size: 0x80000
|
||||
category: Program
|
||||
content: Program
|
||||
memory
|
||||
type: RAM
|
||||
battery
|
||||
size: 0x800
|
||||
category: Save
|
||||
content: Save
|
||||
note: Linkable: SFT-0101-JPN, SFT-0102-JPN
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -162,10 +162,10 @@ auto Famicom::manifest() const -> string {
|
|||
}
|
||||
|
||||
if(prgrom) output.append(Memory{}.type("ROM").size(prgrom).content("Program").text());
|
||||
if(prgram) output.append(Memory{}.type("RAM").size(prgram).content("Save").battery().text());
|
||||
if(prgram) output.append(Memory{}.type("RAM").size(prgram).content("Save").text());
|
||||
|
||||
if(chrrom) output.append(Memory{}.type("ROM").size(chrrom).content("Character").text());
|
||||
if(chrram) output.append(Memory{}.type("RAM").size(chrram).content("Character").text());
|
||||
if(chrram) output.append(Memory{}.type("RAM").size(chrram).content("Character").isVolatile().text());
|
||||
|
||||
return output;
|
||||
}
|
||||
|
|
|
@ -58,9 +58,9 @@ auto GameBoyAdvance::manifest() const -> string {
|
|||
else if(list.left().beginsWith("SRAM_V" )) output.append(Memory{}.type("RAM" ).size( 0x8000).content("Save").text());
|
||||
else if(list.left().beginsWith("SRAM_F_V" )) output.append(Memory{}.type("RAM" ).size( 0x8000).content("Save").text());
|
||||
else if(list.left().beginsWith("EEPROM_V" )) output.append(Memory{}.type("EEPROM").size( 0x0).content("Save").text());
|
||||
else if(list.left().beginsWith("FLASH_V" )) output.append(Memory{}.type("Flash" ).size(0x10000).content("Save").text());
|
||||
else if(list.left().beginsWith("FLASH512_V")) output.append(Memory{}.type("Flash" ).size(0x10000).content("Save").text());
|
||||
else if(list.left().beginsWith("FLASH1M_V" )) output.append(Memory{}.type("Flash" ).size(0x20000).content("Save").text());
|
||||
else if(list.left().beginsWith("FLASH_V" )) output.append(Memory{}.type("Flash" ).size(0x10000).content("Save").manufacturer("Macronix").text());
|
||||
else if(list.left().beginsWith("FLASH512_V")) output.append(Memory{}.type("Flash" ).size(0x10000).content("Save").manufacturer("Macronix").text());
|
||||
else if(list.left().beginsWith("FLASH1M_V" )) output.append(Memory{}.type("Flash" ).size(0x20000).content("Save").manufacturer("Macronix").text());
|
||||
return output;
|
||||
}
|
||||
|
||||
|
|
|
@ -242,12 +242,14 @@ auto GameBoy::manifest() const -> string {
|
|||
output.append(" name: ", Location::prefix(location), "\n");
|
||||
output.append(" board: ", mapper, "\n");
|
||||
output.append(Memory{}.type("ROM").size(data.size()).content("Program").text());
|
||||
if(ram && ramSize)
|
||||
output.append(Memory{}.type("RAM").size(ramSize).content("Save").battery(battery).text());
|
||||
if(ram && ramSize && battery)
|
||||
output.append(Memory{}.type("RAM").size(ramSize).content("Save").text());
|
||||
if(ram && ramSize && !battery)
|
||||
output.append(Memory{}.type("RAM").size(ramSize).content("Save").isVolatile().text());
|
||||
if(flash && flashSize)
|
||||
output.append(Memory{}.type("Flash").size(flashSize).content("Download").text());
|
||||
if(rtc && rtcSize)
|
||||
output.append(Memory{}.type("RTC").size(rtcSize).content("Time").battery().text());
|
||||
output.append(Memory{}.type("RTC").size(rtcSize).content("Time").text());
|
||||
if(accelerometer)
|
||||
output.append(" accelerometer\n");
|
||||
if(rumble)
|
||||
|
|
|
@ -25,7 +25,7 @@ auto GameGear::manifest() const -> string {
|
|||
output.append(" name: ", Location::prefix(location), "\n");
|
||||
output.append(" board\n");
|
||||
output.append(Memory{}.type("ROM").size(data.size()).content("Program").text());
|
||||
output.append(Memory{}.type("RAM").size(0x8000).content("Save").battery().text());
|
||||
output.append(Memory{}.type("RAM").size(0x8000).content("Save").text());
|
||||
return output;
|
||||
}
|
||||
|
||||
|
|
|
@ -4,8 +4,6 @@ auto Memory::text() const -> string {
|
|||
string output;
|
||||
output.append(" memory\n");
|
||||
output.append(" type: ", _type, "\n");
|
||||
if(_battery)
|
||||
output.append(" battery\n");
|
||||
output.append(" size: 0x", hex(_size), "\n");
|
||||
output.append(" content: ", _content, "\n");
|
||||
if(_manufacturer)
|
||||
|
@ -14,6 +12,8 @@ if(_architecture)
|
|||
output.append(" architecture: ", _architecture, "\n");
|
||||
if(_identifier)
|
||||
output.append(" identifier: ", _identifier, "\n");
|
||||
if(_volatile)
|
||||
output.append(" volatile\n");
|
||||
return output;
|
||||
}
|
||||
|
||||
|
|
|
@ -2,12 +2,12 @@ namespace Heuristics {
|
|||
|
||||
struct Memory {
|
||||
auto& type(string type) { _type = type; return *this; }
|
||||
auto& battery(boolean battery = true) { _battery = battery; return *this; }
|
||||
auto& size(natural size) { _size = size; return *this; }
|
||||
auto& content(string content) { _content = content; return *this; }
|
||||
auto& manufacturer(string manufacturer) { _manufacturer = manufacturer; return *this; }
|
||||
auto& architecture(string architecture) { _architecture = architecture; return *this; }
|
||||
auto& identifier(string identifier) { _identifier = identifier; return *this; }
|
||||
auto& isVolatile() { _volatile = true; return *this; }
|
||||
auto text() const -> string;
|
||||
|
||||
string _type;
|
||||
|
@ -17,6 +17,7 @@ struct Memory {
|
|||
string _manufacturer;
|
||||
string _architecture;
|
||||
string _identifier;
|
||||
boolean _volatile;
|
||||
};
|
||||
|
||||
struct Oscillator {
|
||||
|
|
|
@ -25,7 +25,7 @@ auto MasterSystem::manifest() const -> string {
|
|||
output.append(" name: ", Location::prefix(location), "\n");
|
||||
output.append(" board\n");
|
||||
output.append(Memory{}.type("ROM").size(data.size()).content("Program").text());
|
||||
output.append(Memory{}.type("RAM").size(0x8000).content("Save").battery().text());
|
||||
output.append(Memory{}.type("RAM").size(0x8000).content("Save").text());
|
||||
return output;
|
||||
}
|
||||
|
||||
|
|
|
@ -32,7 +32,7 @@ auto SufamiTurbo::manifest() const -> string {
|
|||
output.append(" board\n");
|
||||
output.append(Memory{}.type("ROM").size(data.size()).content("Program").text());
|
||||
if(ramSize)
|
||||
output.append(Memory{}.type("RAM").size(ramSize).content("Save").battery().text());
|
||||
output.append(Memory{}.type("RAM").size(ramSize).content("Save").text());
|
||||
return output;
|
||||
}
|
||||
|
||||
|
|
|
@ -13,7 +13,7 @@ struct SuperFamicom {
|
|||
auto romSize() const -> uint;
|
||||
auto ramSize() const -> uint;
|
||||
auto expansionRamSize() const -> uint;
|
||||
auto battery() const -> bool;
|
||||
auto nonVolatile() const -> bool;
|
||||
|
||||
private:
|
||||
auto size() const -> uint { return data.size(); }
|
||||
|
@ -72,29 +72,29 @@ auto SuperFamicom::manifest() const -> string {
|
|||
}
|
||||
|
||||
if(auto size = ramSize()) {
|
||||
output.append(Memory{}.type("RAM").size(size).content("Save").battery(battery()).text());
|
||||
output.append(Memory{}.type("RAM").size(size).content("Save").text());
|
||||
}
|
||||
|
||||
if(auto size = expansionRamSize()) {
|
||||
output.append(Memory{}.type("RAM").size(size).content("Save").battery(battery()).text());
|
||||
output.append(Memory{}.type("RAM").size(size).content("Save").text());
|
||||
}
|
||||
|
||||
if(0) {
|
||||
} else if(board(0) == "ARM") {
|
||||
output.append(Memory{}.type("ROM").size(0x20000).content("Program").manufacturer("SETA").architecture("ARM6").identifier(firmwareARM()).text());
|
||||
output.append(Memory{}.type("ROM").size( 0x8000).content("Data" ).manufacturer("SETA").architecture("ARM6").identifier(firmwareARM()).text());
|
||||
output.append(Memory{}.type("RAM").size( 0x4000).content("Data" ).manufacturer("SETA").architecture("ARM6").identifier(firmwareARM()).text());
|
||||
output.append(Memory{}.type("RAM").size( 0x4000).content("Data" ).manufacturer("SETA").architecture("ARM6").identifier(firmwareARM()).isVolatile().text());
|
||||
output.append(Oscillator{}.frequency(21'440'000).text());
|
||||
} else if(board(0) == "BS" && board(1) == "MCC") {
|
||||
output.append(Memory{}.type("RAM").size(0x80000).content("Download").battery().text());
|
||||
output.append(Memory{}.type("RAM").size(0x80000).content("Download").text());
|
||||
} else if(board(0) == "HITACHI") {
|
||||
output.append(Memory{}.type("ROM").size(0xc00).content("Data").manufacturer("Hitachi").architecture("HG51BS169").identifier(firmwareHITACHI()).text());
|
||||
output.append(Memory{}.type("RAM").size(0xc00).content("Data").manufacturer("Hitachi").architecture("HG51BS169").identifier(firmwareHITACHI()).text());
|
||||
output.append(Memory{}.type("RAM").size(0xc00).content("Data").manufacturer("Hitachi").architecture("HG51BS169").identifier(firmwareHITACHI()).isVolatile().text());
|
||||
output.append(Oscillator{}.frequency(20'000'000).text());
|
||||
} else if(board(0) == "NEC") {
|
||||
output.append(Memory{}.type("ROM").size(0x1800).content("Program").manufacturer("NEC").architecture("uPD7725").identifier(firmwareNEC()).text());
|
||||
output.append(Memory{}.type("ROM").size( 0x800).content("Data" ).manufacturer("NEC").architecture("uPD7725").identifier(firmwareNEC()).text());
|
||||
output.append(Memory{}.type("RAM").size( 0x200).content("Data" ).manufacturer("NEC").architecture("uPD7725").identifier(firmwareNEC()).text());
|
||||
output.append(Memory{}.type("RAM").size( 0x200).content("Data" ).manufacturer("NEC").architecture("uPD7725").identifier(firmwareNEC()).isVolatile().text());
|
||||
output.append(Oscillator{}.frequency(7'600'000).text());
|
||||
} else if(board(0) == "NECEX") {
|
||||
output.append(Memory{}.type("ROM").size(0xc000).content("Program").manufacturer("NEC").architecture("uPD96050").identifier(firmwareNECEX()).text());
|
||||
|
@ -102,9 +102,9 @@ auto SuperFamicom::manifest() const -> string {
|
|||
output.append(Memory{}.type("RAM").size(0x1000).content("Data" ).manufacturer("NEC").architecture("uPD96050").identifier(firmwareNECEX()).text());
|
||||
output.append(Oscillator{}.frequency(firmwareNECEX() == "ST010" ? 11'000'000 : 15'000'000).text());
|
||||
} else if(board(0) == "RTC") {
|
||||
output.append(Memory{}.type("RTC").size(0x10).content("Time").battery().text());
|
||||
output.append(Memory{}.type("RTC").size(0x10).content("Time").text());
|
||||
} else if(board(0) == "SA1") {
|
||||
output.append(Memory{}.type("RAM").size(0x800).content("Internal").text());
|
||||
output.append(Memory{}.type("RAM").size(0x800).content("Internal").isVolatile().text());
|
||||
} else if(board(0) == "SGB") {
|
||||
output.append(Memory{}.type("ROM").size(0x100).content("Boot").manufacturer("Nintendo").architecture("LR35902").identifier(firmwareSGB()).text());
|
||||
if(firmwareSGB() == "SGB2")
|
||||
|
@ -112,7 +112,7 @@ auto SuperFamicom::manifest() const -> string {
|
|||
} else if(board(0) == "SPC7110") {
|
||||
output.append(Memory{}.type("ROM").size(romSize() - 0x100000).content("Data").text());
|
||||
if(board(1) == "RTC")
|
||||
output.append(Memory{}.type("RTC").size(0x10).content("Time").battery().text());
|
||||
output.append(Memory{}.type("RTC").size(0x10).content("Time").text());
|
||||
} else if(board(0) == "SUPERFX") {
|
||||
//todo: MARIO CHIP 1 uses CPU oscillator
|
||||
output.append(Oscillator{}.frequency(21'440'000).text());
|
||||
|
@ -411,7 +411,7 @@ auto SuperFamicom::expansionRamSize() const -> uint {
|
|||
return 0;
|
||||
}
|
||||
|
||||
auto SuperFamicom::battery() const -> bool {
|
||||
auto SuperFamicom::nonVolatile() const -> bool {
|
||||
auto cartridgeTypeLo = data[headerAddress + 0x26] & 15;
|
||||
return cartridgeTypeLo == 0x2 || cartridgeTypeLo == 0x5 || cartridgeTypeLo == 0x6;
|
||||
}
|
||||
|
|
|
@ -49,7 +49,7 @@ auto WonderSwan::manifest() const -> string {
|
|||
output.append(" board\n");
|
||||
output.append(Memory{}.type("ROM").size(data.size()).content("Program").text());
|
||||
if(ramType && ramSize)
|
||||
output.append(Memory{}.type(ramType).size(ramSize).content("Save").battery(ramType == "RAM").text());
|
||||
output.append(Memory{}.type(ramType).size(ramSize).content("Save").text());
|
||||
if(hasRTC)
|
||||
output.append(Memory{}.type("RTC").size(0x10).content("Time").text());
|
||||
return output;
|
||||
|
|
|
@ -34,7 +34,7 @@ auto ManagedNode::_evaluate(string query) const -> bool {
|
|||
if(side(0)) {
|
||||
auto result = _find(side(0));
|
||||
if(result.size() == 0) return false;
|
||||
data = result[0].value();
|
||||
data = result[0].text(); //strips whitespace so rules can match without requiring it
|
||||
}
|
||||
|
||||
switch(comparator) {
|
||||
|
|
Loading…
Reference in New Issue