Update to v106r09 release.

byuu says:

Changelog:

  - higan, icarus, genius: new manifest syntax (work in progress)

Pretty much only LoROM and HiROM SNES games will load right now, and RAM
will only work right if the save.ram file already exists to pull its
file size from (a temporary cheap hack was used.)

Basically, I'm just getting this out there for evaluation.

One minor errata is that I switched icarus to using “memory/battery” to
indicate battery-backed RAM, whereas genius still uses “memory/volatile”
to indicate non-battery-backed RAM.

I intend to make it “memory/battery” in genius, and have the field
auto-enable when RAM or RTC is selected for type (obviously allowing it
to be unchecked for volatile memory.)

I need to update all 64 production boards, and 25 of 29 generic boards,
to use the new slot syntax; and I also need to update every single core
in higan to use the new manifest game syntax. I want to build out a
generic manifest game parser that all emulation cores will use.

Once I finish this, I'll also need to write a database converter to
update all of my licensed game dumps to the new database syntax.

I also need to write up something for doc.byuu.org explaining the new
manifest game syntax. The manifest board syntax will still be “internal”
and subject to revisions, but once v107 is out, the gamepak manifest
format will be set in stone sans extensions.
This commit is contained in:
Tim Allen 2018-03-05 15:34:07 +11:00
parent a4a3d611a6
commit e216912ca3
27 changed files with 1925 additions and 752 deletions

View File

@ -8,6 +8,7 @@ using namespace hiro;
unique_pointer<ListWindow> listWindow; unique_pointer<ListWindow> listWindow;
unique_pointer<GameWindow> gameWindow; unique_pointer<GameWindow> gameWindow;
unique_pointer<MemoryWindow> memoryWindow; unique_pointer<MemoryWindow> memoryWindow;
unique_pointer<OscillatorWindow> oscillatorWindow;
// //
@ -35,7 +36,7 @@ ListWindow::ListWindow() {
helpMenu.setText("Help"); helpMenu.setText("Help");
aboutAction.setText("About ...").onActivate([&] { aboutAction.setText("About ...").onActivate([&] {
MessageDialog().setParent(*this).setTitle("About").setText({ MessageDialog().setParent(*this).setTitle("About").setText({
"genius v01\n", "genius\n",
"Author: byuu\n", "Author: byuu\n",
"Website: https://byuu.org/" "Website: https://byuu.org/"
}).information(); }).information();
@ -58,7 +59,7 @@ ListWindow::ListWindow() {
onClose([&] { quit(); }); onClose([&] { quit(); });
setSize({960, 600}); setSize({820, 600});
reloadList(); reloadList();
updateWindow(); updateWindow();
setCentered(); setCentered();
@ -116,19 +117,31 @@ auto ListWindow::loadDatabase(string location) -> void {
for(auto node : document.find("game")) { for(auto node : document.find("game")) {
Game game; Game game;
game.sha256 = node["sha256"].text(); game.sha256 = node["sha256"].text();
game.label = node["label"].text();
game.name = node["name"].text();
game.region = node["region"].text(); game.region = node["region"].text();
game.revision = node["revision"].text(); game.revision = node["revision"].text();
game.board = node["board"].text(); game.board = node["board"].text();
game.name = node["name"].text(); for(auto object : node["board"]) {
game.label = node["label"].text(); Component component;
game.note = node["note"].text(); if(object.name() == "memory") {
for(auto leaf : node.find("memory")) { component.type = Component::Type::Memory;
Memory memory; component.memory.type = object["type"].text();
memory.type = leaf["type"].text(); component.memory.size = object["size"].text();
memory.size = leaf["size"].text(); component.memory.category = object["category"].text();
memory.name = leaf["name"].text(); component.memory.manufacturer = object["manufacturer"].text();
game.memories.append(memory); component.memory.part = object["part"].text();
component.memory.note = object["note"].text();
component.memory.isVolatile = (bool)object["volatile"];
} }
if(object.name() == "oscillator") {
component.type = Component::Type::Oscillator;
component.oscillator.frequency = object["frequency"].text();
component.oscillator.note = object["note"].text();
}
game.components.append(component);
}
game.note = node["note"].text();
games.append(game); games.append(game);
} }
@ -147,7 +160,10 @@ auto ListWindow::saveDatabase(string location) -> void {
auto copy = games; auto copy = games;
copy.sort([](auto x, auto y) { copy.sort([](auto x, auto y) {
return string::icompare(x.name, y.name) < 0; return string::icompare(
{x.name, " ", x.region, " ", x.revision},
{y.name, " ", y.region, " ", y.revision}
) < 0;
}); });
fp.print("database\n"); fp.print("database\n");
@ -156,21 +172,40 @@ auto ListWindow::saveDatabase(string location) -> void {
for(auto& game : copy) { for(auto& game : copy) {
fp.print("game\n"); fp.print("game\n");
fp.print(" sha256: ", game.sha256, "\n"); fp.print(" sha256: ", game.sha256, "\n");
if(game.label)
fp.print(" label: ", game.label, "\n");
fp.print(" name: ", game.name, "\n");
fp.print(" region: ", game.region, "\n"); fp.print(" region: ", game.region, "\n");
fp.print(" revision: ", game.revision, "\n"); fp.print(" revision: ", game.revision, "\n");
if(game.board) if(game.board)
fp.print(" board: ", game.board, "\n"); fp.print(" board: ", game.board, "\n");
fp.print(" name: ", game.name, "\n"); else if(game.components)
if(game.label) fp.print(" board\n");
fp.print(" label: ", game.label, "\n"); for(auto& component : game.components) {
if(component.type == Component::Type::Memory) {
fp.print(" memory\n");
fp.print(" type: ", component.memory.type, "\n");
fp.print(" size: ", component.memory.size, "\n");
fp.print(" category: ", component.memory.category, "\n");
if(component.memory.manufacturer)
fp.print(" manufacturer: ", component.memory.manufacturer, "\n");
if(component.memory.part)
fp.print(" part: ", component.memory.part, "\n");
if(component.memory.note)
fp.print(" note: ", component.memory.note, "\n");
if(component.memory.isVolatile)
fp.print(" volatile\n");
}
if(component.type == Component::Type::Oscillator) {
fp.print(" oscillator\n");
fp.print(" frequency: ", component.oscillator.frequency, "\n");
if(component.oscillator.note)
fp.print(" note: ", component.oscillator.note, "\n");
}
}
if(game.note) if(game.note)
fp.print(" note: ", game.note, "\n"); fp.print(" note: ", game.note, "\n");
for(auto& memory : game.memories) {
fp.print(" memory\n");
fp.print(" type: ", memory.type, "\n");
fp.print(" size: ", memory.size, "\n");
fp.print(" name: ", memory.name, "\n");
}
fp.print("\n"); fp.print("\n");
} }
@ -219,39 +254,52 @@ GameWindow::GameWindow() {
gameWindow = this; gameWindow = this;
layout.setMargin(5); layout.setMargin(5);
hashLabel.setText("SHA256:"); hashLabel.setText("SHA256:").setAlignment(1.0);
hashEdit.setFont(Font().setFamily(Font::Mono)).onChange([&] { modified = true, updateWindow(); }); hashEdit.setFont(Font().setFamily(Font::Mono)).onChange([&] { modified = true, updateWindow(); });
regionLabel.setText("Region:"); regionLabel.setText("Region:").setAlignment(1.0);
regionEdit.setFont(Font().setFamily(Font::Mono)).onChange([&] { modified = true, updateWindow(); }); regionEdit.setFont(Font().setFamily(Font::Mono)).onChange([&] { modified = true, updateWindow(); });
revisionLabel.setText("Revision:"); revisionLabel.setText("Revision:");
revisionEdit.setFont(Font().setFamily(Font::Mono)).onChange([&] { modified = true, updateWindow(); }); revisionEdit.setFont(Font().setFamily(Font::Mono)).onChange([&] { modified = true, updateWindow(); });
boardLabel.setText("Board:"); boardLabel.setText("Board:");
boardEdit.setFont(Font().setFamily(Font::Mono)).onChange([&] { modified = true, updateWindow(); }); boardEdit.setFont(Font().setFamily(Font::Mono)).onChange([&] { modified = true, updateWindow(); });
nameLabel.setText("Name:"); nameLabel.setText("Name:").setAlignment(1.0);
nameEdit.onChange([&] { modified = true, updateWindow(); }); nameEdit.onChange([&] { modified = true, updateWindow(); });
labelLabel.setText("Label:"); labelLabel.setText("Label:").setAlignment(1.0);
labelEdit.onChange([&] { modified = true, updateWindow(); }); labelEdit.onChange([&] { modified = true, updateWindow(); });
noteLabel.setText("Note:"); noteLabel.setText("Note:").setAlignment(1.0);
noteEdit.onChange([&] { modified = true, updateWindow(); }); noteEdit.onChange([&] { modified = true, updateWindow(); });
memoryList.onActivate([&] { modifyButton.doActivate(); }); componentLabel.setText("Tree:").setAlignment({1.0, 0.0});
memoryList.onChange([&] { updateWindow(); }); componentTree.onActivate([&] { modifyComponentButton.doActivate(); });
appendButton.setText("Append").onActivate([&] { componentTree.onChange([&] { updateWindow(); });
appendMemoryButton.setText("Memory").onActivate([&] {
setEnabled(false); setEnabled(false);
memoryWindow->show(); memoryWindow->show();
}); });
modifyButton.setText("Modify").onActivate([&] { appendOscillatorButton.setText("Oscillator").onActivate([&] {
if(auto item = memoryList.selected()) {
setEnabled(false); setEnabled(false);
memoryWindow->show(game.memories[item.offset()]); oscillatorWindow->show();
});
modifyComponentButton.setText("Modify").onActivate([&] {
if(auto item = componentTree.selected()) {
setEnabled(false);
auto path = item.path().split("/");
auto offset = path(0).natural();
Component component = game.components[offset];
if(component.type == Component::Type::Memory) {
memoryWindow->show(component.memory);
}
if(component.type == Component::Type::Oscillator) {
oscillatorWindow->show(component.oscillator);
}
} }
}); });
removeButton.setText("Remove").onActivate([&] { removeMemory(); }); removeComponentButton.setText("Remove").onActivate([&] { removeComponent(); });
acceptButton.setText("Accept").onActivate([&] { accept(); }); acceptButton.setText("Accept").onActivate([&] { accept(); });
cancelButton.setText("Cancel").onActivate([&] { cancel(); }); cancelButton.setText("Cancel").onActivate([&] { cancel(); });
onClose([&] { cancel(); }); onClose([&] { cancel(); });
setSize({800, 480}); setSize({640, 480});
setDismissable(); setDismissable();
} }
@ -260,14 +308,14 @@ auto GameWindow::show(Game game) -> void {
modified = false; modified = false;
create = !game.sha256; create = !game.sha256;
hashEdit.setText(game.sha256).setEditable(create); hashEdit.setText(game.sha256);
regionEdit.setText(game.region); regionEdit.setText(game.region);
revisionEdit.setText(game.revision); revisionEdit.setText(game.revision);
boardEdit.setText(game.board); boardEdit.setText(game.board);
nameEdit.setText(game.name); nameEdit.setText(game.name);
labelEdit.setText(game.label); labelEdit.setText(game.label);
noteEdit.setText(game.note); noteEdit.setText(game.note);
acceptButton.setText(create ? "Create" : "Modify"); acceptButton.setText(create ? "Create" : "Apply");
reloadList(); reloadList();
updateWindow(); updateWindow();
@ -314,70 +362,90 @@ auto GameWindow::cancel() -> void {
} }
auto GameWindow::reloadList() -> void { auto GameWindow::reloadList() -> void {
memoryList.reset(); componentTree.reset();
memoryList.append(TableViewHeader() uint counter = 1;
.append(TableViewColumn().setText("Type")) for(auto& component : game.components) {
.append(TableViewColumn().setText("Size")) TreeViewItem item;
.append(TableViewColumn().setText("Name").setExpandable())
); string index = {"[", counter++, "] "};
for(auto& memory : game.memories) { if(component.type == Component::Type::Memory) {
memoryList.append(TableViewItem() item.setText({index, "Memory"});
.append(TableViewCell().setText(memory.type)) item.append(TreeViewItem().setText({"Type: ", component.memory.type}));
.append(TableViewCell().setText(memory.size)) item.append(TreeViewItem().setText({"Size: ", component.memory.size}));
.append(TableViewCell().setText(memory.name)) item.append(TreeViewItem().setText({"Category: ", component.memory.category}));
); if(component.memory.manufacturer)
item.append(TreeViewItem().setText({"Manufacturer: ", component.memory.manufacturer}));
if(component.memory.part)
item.append(TreeViewItem().setText({"Part: ", component.memory.part}));
if(component.memory.note)
item.append(TreeViewItem().setText({"Note: ", component.memory.note}));
if(component.memory.isVolatile)
item.append(TreeViewItem().setText({"Volatile"}));
} }
if(component.type == Component::Type::Oscillator) {
item.setText({index, "Oscillator"});
item.append(TreeViewItem().setText({"Frequency: ", component.oscillator.frequency}));
if(component.oscillator.note)
item.append(TreeViewItem().setText({"Note: ", component.oscillator.note}));
}
componentTree.append(item);
}
Application::processEvents(); Application::processEvents();
memoryList.resizeColumns(); for(auto& item : componentTree.items()) item.setExpanded();
} }
auto GameWindow::updateWindow() -> void { auto GameWindow::updateWindow() -> void {
bool valid = true; bool valid = true;
hashEdit.setBackgroundColor( bool hashValid = hashEdit.text().strip().size() == 64;
!create ? Color{192, 255, 192} hashEdit.setEditable(!hashValid).setBackgroundColor(
: hashEdit.text().strip().size() == 64 ? Color{} !create || hashValid ? Color{192, 255, 192}
: (valid = false, Color{255, 224, 224}) : (valid = false, Color{255, 224, 224}));
);
regionEdit.setBackgroundColor(regionEdit.text().strip() ? Color{} : (valid = false, Color{255, 224, 224})); regionEdit.setBackgroundColor(regionEdit.text().strip() ? Color{} : (valid = false, Color{255, 224, 224}));
revisionEdit.setBackgroundColor(revisionEdit.text().strip() ? Color{} : (valid = false, Color{255, 224, 224})); revisionEdit.setBackgroundColor(revisionEdit.text().strip() ? Color{} : (valid = false, Color{255, 224, 224}));
boardEdit.setBackgroundColor(boardEdit.text().strip() ? Color{} : (Color{255, 255, 240})); boardEdit.setBackgroundColor(boardEdit.text().strip() ? Color{} : (Color{255, 255, 240}));
nameEdit.setBackgroundColor(nameEdit.text().strip() ? Color{} : (valid = false, Color{255, 224, 224})); nameEdit.setBackgroundColor(nameEdit.text().strip() ? Color{} : (valid = false, Color{255, 224, 224}));
labelEdit.setBackgroundColor(labelEdit.text().strip() ? Color{} : (Color{255, 255, 240})); labelEdit.setBackgroundColor(labelEdit.text().strip() ? Color{} : (Color{255, 255, 240}));
noteEdit.setBackgroundColor(noteEdit.text().strip() ? Color{} : (Color{255, 255, 240})); noteEdit.setBackgroundColor(noteEdit.text().strip() ? Color{} : (Color{255, 255, 240}));
modifyButton.setEnabled((bool)memoryList.selected()); modifyComponentButton.setEnabled((bool)componentTree.selected());
removeButton.setEnabled((bool)memoryList.selected()); removeComponentButton.setEnabled((bool)componentTree.selected());
acceptButton.setEnabled(valid); acceptButton.setEnabled(valid);
setTitle({modified ? "*" : "", create ? "Add New Game" : "Modify Game Details"}); setTitle({modified ? "*" : "", create ? "Add New Game" : "Modify Game Details"});
if(create && hashValid && hashEdit.focused()) regionEdit.setFocused();
} }
auto GameWindow::appendMemory(Memory memory) -> void { auto GameWindow::appendComponent(Component component) -> void {
modified = true; modified = true;
auto offset = game.memories.size(); auto offset = game.components.size();
game.memories.append(memory); game.components.append(component);
reloadList(); reloadList();
memoryList.item(offset).setSelected().setFocused(); componentTree.item(offset).setSelected().setFocused();
updateWindow(); updateWindow();
} }
auto GameWindow::modifyMemory(Memory memory) -> void { auto GameWindow::modifyComponent(Component component) -> void {
if(auto item = memoryList.selected()) { if(auto item = componentTree.selected()) {
modified = true; modified = true;
auto offset = item.offset(); auto path = item.path().split("/");
game.memories[offset] = memory; auto offset = path(0).natural();
game.components[offset] = component;
reloadList(); reloadList();
memoryList.item(offset).setSelected().setFocused(); componentTree.item(offset).setSelected().setFocused();
updateWindow(); updateWindow();
} }
} }
auto GameWindow::removeMemory() -> void { auto GameWindow::removeComponent() -> void {
if(auto item = memoryList.selected()) { if(auto item = componentTree.selected()) {
if(MessageDialog().setParent(*this).setText({ if(MessageDialog().setParent(*this).setText({
"Are you sure you want to permanently remove this memory?\n\n", "Are you sure you want to permanently remove this component?"
"Name: ", item.cell(2).text()
}).question() == "Yes") { }).question() == "Yes") {
modified = true; modified = true;
game.memories.remove(item.offset()); auto path = item.path().split("/");
auto offset = path(0).natural();
game.components.remove(offset);
reloadList(); reloadList();
updateWindow(); updateWindow();
} }
@ -390,25 +458,35 @@ MemoryWindow::MemoryWindow() {
memoryWindow = this; memoryWindow = this;
layout.setMargin(5); layout.setMargin(5);
typeLabel.setText("Type:"); typeLabel.setText("Type:").setAlignment(1.0);
typeEdit.append(ComboEditItem().setText("ROM")); typeEdit.append(ComboEditItem().setText("ROM"));
typeEdit.append(ComboEditItem().setText("EPROM"));
typeEdit.append(ComboEditItem().setText("EEPROM")); typeEdit.append(ComboEditItem().setText("EEPROM"));
typeEdit.append(ComboEditItem().setText("NOR")); typeEdit.append(ComboEditItem().setText("Flash"));
typeEdit.append(ComboEditItem().setText("PSRAM"));
typeEdit.append(ComboEditItem().setText("NVRAM"));
typeEdit.append(ComboEditItem().setText("RAM")); typeEdit.append(ComboEditItem().setText("RAM"));
typeEdit.append(ComboEditItem().setText("RTC"));
typeEdit.onChange([&] { modified = true, updateWindow(); }); typeEdit.onChange([&] { modified = true, updateWindow(); });
sizeLabel.setText("Size:"); sizeLabel.setText("Size:").setAlignment(1.0);
sizeEdit.setFont(Font().setFamily(Font::Mono)).onChange([&] { modified = true, updateWindow(); }); sizeEdit.onChange([&] { modified = true, updateWindow(); });
nameLabel.setText("Name:"); categoryLabel.setText("Category:").setAlignment(1.0);
nameEdit.onChange([&] { modified = true, updateWindow(); }); categoryEdit.append(ComboEditItem().setText("Program"));
categoryEdit.append(ComboEditItem().setText("Data"));
categoryEdit.append(ComboEditItem().setText("Character"));
categoryEdit.append(ComboEditItem().setText("Save"));
categoryEdit.append(ComboEditItem().setText("Time"));
categoryEdit.onChange([&] { modified = true, updateWindow(); });
manufacturerLabel.setText("Manufacturer:").setAlignment(1.0);
manufacturerEdit.onChange([&] { modified = true, updateWindow(); });
partLabel.setText("Part:").setAlignment(1.0);
partEdit.onChange([&] { modified = true, updateWindow(); });
noteLabel.setText("Note:").setAlignment(1.0);
noteEdit.onChange([&] { modified = true, updateWindow(); });
volatileOption.setText("Volatile").onToggle([&] { modified = true, updateWindow(); });
acceptButton.setText("Accept").onActivate([&] { accept(); }); acceptButton.setText("Accept").onActivate([&] { accept(); });
cancelButton.setText("Cancel").onActivate([&] { cancel(); }); cancelButton.setText("Cancel").onActivate([&] { cancel(); });
onClose([&] { cancel(); }); onClose([&] { cancel(); });
setSize({280, layout.minimumSize().height()}); setSize({320, layout.minimumSize().height()});
setDismissable(); setDismissable();
} }
@ -419,7 +497,11 @@ auto MemoryWindow::show(Memory memory) -> void {
typeEdit.setText(memory.type); typeEdit.setText(memory.type);
sizeEdit.setText(memory.size); sizeEdit.setText(memory.size);
nameEdit.setText(memory.name); categoryEdit.setText(memory.category);
manufacturerEdit.setText(memory.manufacturer);
partEdit.setText(memory.part);
noteEdit.setText(memory.note);
volatileOption.setChecked(memory.isVolatile);
updateWindow(); updateWindow();
setCentered(*gameWindow); setCentered(*gameWindow);
@ -431,12 +513,18 @@ auto MemoryWindow::show(Memory memory) -> void {
auto MemoryWindow::accept() -> void { auto MemoryWindow::accept() -> void {
memory.type = typeEdit.text().strip(); memory.type = typeEdit.text().strip();
memory.size = sizeEdit.text().strip(); memory.size = sizeEdit.text().strip();
memory.name = nameEdit.text().strip(); memory.category = categoryEdit.text().strip();
memory.manufacturer = manufacturerEdit.text().strip();
memory.part = partEdit.text().strip();
memory.note = noteEdit.text().strip();
memory.isVolatile = volatileOption.checked();
Component component{Component::Type::Memory};
component.memory = memory;
if(create) { if(create) {
gameWindow->appendMemory(memory); gameWindow->appendComponent(component);
} else { } else {
gameWindow->modifyMemory(memory); gameWindow->modifyComponent(component);
} }
setVisible(false); setVisible(false);
@ -458,18 +546,91 @@ auto MemoryWindow::updateWindow() -> void {
bool valid = true; bool valid = true;
typeEdit.setBackgroundColor(typeEdit.text().strip() ? Color{} : (valid = false, Color{255, 224, 224})); typeEdit.setBackgroundColor(typeEdit.text().strip() ? Color{} : (valid = false, Color{255, 224, 224}));
sizeEdit.setBackgroundColor(sizeEdit.text().strip() ? Color{} : (valid = false, Color{255, 224, 224})); sizeEdit.setBackgroundColor(sizeEdit.text().strip() ? Color{} : (valid = false, Color{255, 224, 224}));
nameEdit.setBackgroundColor(nameEdit.text().strip() ? Color{} : (valid = false, Color{255, 224, 224})); categoryEdit.setBackgroundColor(categoryEdit.text().strip() ? Color{} : (valid = false, Color{255, 224, 224}));
manufacturerEdit.setBackgroundColor(manufacturerEdit.text().strip() ? Color{} : (Color{255, 255, 240}));
partEdit.setBackgroundColor(partEdit.text().strip() ? Color{} : (Color{255, 255, 240}));
noteEdit.setBackgroundColor(noteEdit.text().strip() ? Color{} : (Color{255, 255, 240}));
acceptButton.setEnabled(valid); acceptButton.setEnabled(valid);
setTitle({modified ? "*" : "", create ? "Add New Memory" : "Modify Memory Details"}); setTitle({modified ? "*" : "", create ? "Add New Memory" : "Modify Memory Details"});
} }
// //
OscillatorWindow::OscillatorWindow() {
oscillatorWindow = this;
layout.setMargin(5);
frequencyLabel.setText("Frequency:").setAlignment(1.0);
frequencyEdit.onChange([&] { modified = true, updateWindow(); });
noteLabel.setText("Note:").setAlignment(1.0);
noteEdit.onChange([&] { modified = true, updateWindow(); });
acceptButton.setText("Accept").onActivate([&] { accept(); });
cancelButton.setText("Cancel").onActivate([&] { cancel(); });
onClose([&] { cancel(); });
setSize({320, layout.minimumSize().height()});
setDismissable();
}
auto OscillatorWindow::show(Oscillator oscillator) -> void {
this->oscillator = oscillator;
modified = false;
create = !oscillator.frequency;
frequencyEdit.setText(oscillator.frequency);
noteEdit.setText(oscillator.note);
updateWindow();
setCentered(*gameWindow);
setVisible();
frequencyEdit.setFocused();
}
auto OscillatorWindow::accept() -> void {
oscillator.frequency = frequencyEdit.text().strip();
oscillator.note = noteEdit.text().strip();
Component component{Component::Type::Oscillator};
component.oscillator = oscillator;
if(create) {
gameWindow->appendComponent(component);
} else {
gameWindow->modifyComponent(component);
}
setVisible(false);
gameWindow->setEnabled();
gameWindow->setFocused();
}
auto OscillatorWindow::cancel() -> void {
if(!modified || MessageDialog().setParent(*this).setText({
"Are you sure you want to discard your changes to this property?"
}).question() == "Yes") {
setVisible(false);
gameWindow->setEnabled();
gameWindow->setFocused();
}
}
auto OscillatorWindow::updateWindow() -> void {
bool valid = true;
frequencyEdit.setBackgroundColor(frequencyEdit.text().strip() ? Color{} : (valid = false, Color{255, 224, 224}));
noteEdit.setBackgroundColor(noteEdit.text().strip() ? Color{} : (Color{255, 255, 240}));
acceptButton.setEnabled(valid);
setTitle({modified ? "*" : "", create ? "Add New Property" : "Modify Property Details"});
}
//
#include <nall/main.hpp> #include <nall/main.hpp>
auto nall::main(string_vector) -> void { auto nall::main(string_vector) -> void {
Application::setName("genius"); Application::setName("genius");
new ListWindow; new ListWindow;
new GameWindow; new GameWindow;
new MemoryWindow; new MemoryWindow;
new OscillatorWindow;
Application::run(); Application::run();
} }

View File

@ -1,7 +1,26 @@
struct Memory { struct Memory {
string type; string type;
string size; string size;
string name; string category;
string manufacturer;
string part;
string note;
bool isVolatile = false;
};
struct Oscillator {
string frequency;
string note;
};
//variant meta-class
struct Component {
enum class Type : uint {
Memory,
Oscillator,
} type;
Memory memory;
Oscillator oscillator;
}; };
struct Game { struct Game {
@ -12,7 +31,7 @@ struct Game {
string name; string name;
string label; string label;
string note; string note;
vector<Memory> memories; vector<Component> components;
}; };
struct ListWindow : Window { struct ListWindow : Window {
@ -58,9 +77,9 @@ struct GameWindow : Window {
auto cancel() -> void; auto cancel() -> void;
auto reloadList() -> void; auto reloadList() -> void;
auto updateWindow() -> void; auto updateWindow() -> void;
auto appendMemory(Memory) -> void; auto appendComponent(Component) -> void;
auto modifyMemory(Memory) -> void; auto modifyComponent(Component) -> void;
auto removeMemory() -> void; auto removeComponent() -> void;
private: private:
bool modified = false; bool modified = false;
@ -77,7 +96,7 @@ private:
Label revisionLabel{&infoLayout, Size{0, 0}}; Label revisionLabel{&infoLayout, Size{0, 0}};
LineEdit revisionEdit{&infoLayout, Size{~0, 0}}; LineEdit revisionEdit{&infoLayout, Size{~0, 0}};
Label boardLabel{&infoLayout, Size{0, 0}}; Label boardLabel{&infoLayout, Size{0, 0}};
LineEdit boardEdit{&infoLayout, Size{~0, 0}}; LineEdit boardEdit{&infoLayout, Size{~0, 0}, 0};
HorizontalLayout nameLayout{&layout, Size{~0, 0}}; HorizontalLayout nameLayout{&layout, Size{~0, 0}};
Label nameLabel{&nameLayout, Size{50, 0}}; Label nameLabel{&nameLayout, Size{50, 0}};
LineEdit nameEdit{&nameLayout, Size{~0, 0}}; LineEdit nameEdit{&nameLayout, Size{~0, 0}};
@ -87,12 +106,15 @@ private:
HorizontalLayout noteLayout{&layout, Size{~0, 0}}; HorizontalLayout noteLayout{&layout, Size{~0, 0}};
Label noteLabel{&noteLayout, Size{50, 0}}; Label noteLabel{&noteLayout, Size{50, 0}};
LineEdit noteEdit{&noteLayout, Size{~0, 0}}; LineEdit noteEdit{&noteLayout, Size{~0, 0}};
TableView memoryList{&layout, Size{~0, ~0}}; HorizontalLayout lowerLayout{&layout, Size{~0, ~0}};
HorizontalLayout controlLayout{&layout, Size{~0, 0}}; Label componentLabel{&lowerLayout, Size{50, ~0}};
Button appendButton{&controlLayout, Size{80, 0}}; TreeView componentTree{&lowerLayout, Size{~0, ~0}};
Button modifyButton{&controlLayout, Size{80, 0}}; VerticalLayout controlLayout{&lowerLayout, Size{0, ~0}};
Button removeButton{&controlLayout, Size{80, 0}}; Button appendMemoryButton{&controlLayout, Size{80, 0}};
Widget spacer{&controlLayout, Size{~0, 0}}; Button appendOscillatorButton{&controlLayout, Size{80, 0}};
Button modifyComponentButton{&controlLayout, Size{80, 0}};
Button removeComponentButton{&controlLayout, Size{80, 0}};
Widget controlSpacer{&controlLayout, Size{0, ~0}};
Button acceptButton{&controlLayout, Size{80, 0}}; Button acceptButton{&controlLayout, Size{80, 0}};
Button cancelButton{&controlLayout, Size{80, 0}}; Button cancelButton{&controlLayout, Size{80, 0}};
}; };
@ -111,15 +133,50 @@ private:
VerticalLayout layout{this}; VerticalLayout layout{this};
HorizontalLayout infoLayout{&layout, Size{~0, 0}}; HorizontalLayout infoLayout{&layout, Size{~0, 0}};
Label typeLabel{&infoLayout, Size{40, 0}}; Label typeLabel{&infoLayout, Size{80, 0}};
ComboEdit typeEdit{&infoLayout, Size{~0, 0}}; ComboEdit typeEdit{&infoLayout, Size{~0, 0}};
Label sizeLabel{&infoLayout, Size{0, 0}}; Label sizeLabel{&infoLayout, Size{0, 0}};
LineEdit sizeEdit{&infoLayout, Size{~0, 0}}; LineEdit sizeEdit{&infoLayout, Size{~0, 0}};
HorizontalLayout nameLayout{&layout, Size{~0, 0}}; HorizontalLayout categoryLayout{&layout, Size{~0, 0}};
Label nameLabel{&nameLayout, Size{40, 0}}; Label categoryLabel{&categoryLayout, Size{80, 0}};
LineEdit nameEdit{&nameLayout, Size{~0, 0}}; ComboEdit categoryEdit{&categoryLayout, Size{~0, 0}};
HorizontalLayout manufacturerLayout{&layout, Size{~0, 0}};
Label manufacturerLabel{&manufacturerLayout, Size{80, 0}};
LineEdit manufacturerEdit{&manufacturerLayout, Size{~0, 0}};
HorizontalLayout partLayout{&layout, Size{~0, 0}};
Label partLabel{&partLayout, Size{80, 0}};
LineEdit partEdit{&partLayout, Size{~0, 0}};
HorizontalLayout noteLayout{&layout, Size{~0, 0}};
Label noteLabel{&noteLayout, Size{80, 0}};
LineEdit noteEdit{&noteLayout, Size{~0, 0}};
HorizontalLayout controlLayout{&layout, Size{~0, 0}}; HorizontalLayout controlLayout{&layout, Size{~0, 0}};
Widget spacer{&controlLayout, Size{~0, 0}}; Widget controlSpacer{&controlLayout, Size{~0, 0}};
CheckLabel volatileOption{&controlLayout, Size{0, 0}};
Button acceptButton{&controlLayout, Size{80, 0}};
Button cancelButton{&controlLayout, Size{80, 0}};
};
struct OscillatorWindow : Window {
OscillatorWindow();
auto show(Oscillator = {}) -> void;
auto accept() -> void;
auto cancel() -> void;
auto updateWindow() -> void;
private:
bool modified = false;
bool create = true;
Oscillator oscillator;
VerticalLayout layout{this};
HorizontalLayout frequencyLayout{&layout, Size{~0, 0}};
Label frequencyLabel{&frequencyLayout, Size{60, 0}};
LineEdit frequencyEdit{&frequencyLayout, Size{~0, 0}};
HorizontalLayout noteLayout{&layout, Size{~0, 0}};
Label noteLabel{&noteLayout, Size{60, 0}};
LineEdit noteEdit{&noteLayout, Size{~0, 0}};
HorizontalLayout controlLayout{&layout, Size{~0, 0}};
Widget controlSpacer{&controlLayout, Size{~0, 0}};
Button acceptButton{&controlLayout, Size{80, 0}}; Button acceptButton{&controlLayout, Size{80, 0}};
Button cancelButton{&controlLayout, Size{80, 0}}; Button cancelButton{&controlLayout, Size{80, 0}};
}; };

View File

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

View File

@ -1,13 +1,11 @@
auto Cartridge::loadBoard(Markup::Node node) -> Markup::Node { auto Cartridge::loadBoard(Markup::Node node) -> Markup::Node {
string output; string output;
auto region = node["game/region"].text();
auto board = node["game/board"].text(); auto board = node["game/board"].text();
if(board != "SHVC-SGB2-01") board.trimLeft("SHVC-", 1L); if(board.beginsWith("SNSP-")) board.replace("SNSP-", "SHVC-", 1L);
board.trimLeft("SNSP-", 1L); if(board.beginsWith("MAXI-")) board.replace("MAXI-", "SHVC-", 1L);
board.trimLeft("MAXI-", 1L); if(board.beginsWith("MJSC-")) board.replace("MJSC-", "SHVC-", 1L);
board.trimLeft("MJSC-", 1L); if(board.beginsWith("EA-" )) board.replace("EA-", "SHVC-", 1L);
board.trimLeft("EA-", 1L);
if(auto fp = platform->open(ID::System, "boards.bml", File::Read, File::Required)) { if(auto fp = platform->open(ID::System, "boards.bml", File::Read, File::Required)) {
auto document = BML::unserialize(fp->reads()); auto document = BML::unserialize(fp->reads());
@ -20,8 +18,18 @@ auto Cartridge::loadBoard(Markup::Node node) -> Markup::Node {
if(string{part(0), revision, part(2)} == board) matched = true; if(string{part(0), revision, part(2)} == board) matched = true;
} }
} }
if(!matched) continue; if(matched) return leaf;
}
}
return {};
}
auto Cartridge::loadCartridge(Markup::Node node) -> void {
information.title.cartridge = node["game/label"].text();
if(region() == "Auto") {
auto region = node["game/region"].text();
if(region.endsWith("BRA") if(region.endsWith("BRA")
|| region.endsWith("CAN") || region.endsWith("CAN")
|| region.endsWith("HKG") || region.endsWith("HKG")
@ -32,53 +40,14 @@ auto Cartridge::loadBoard(Markup::Node node) -> Markup::Node {
|| region.endsWith("USA") || region.endsWith("USA")
|| region.beginsWith("SHVC-") || region.beginsWith("SHVC-")
|| region == "NTSC") { || region == "NTSC") {
output.append("region=ntsc\n"); information.region = "NTSC";
} else { } else {
output.append("region=pal\n"); information.region = "PAL";
}
vector<Markup::Node> rom;
vector<Markup::Node> ram;
for(auto memory : node.find("game/memory")) {
if(memory["type"].text() == "ROM" || memory["type"].text() == "EPROM") {
rom.append(memory);
}
if(memory["type"].text() == "RAM" || memory["type"].text() == "NVRAM") {
ram.append(memory);
} }
} }
for(auto& line : BML::serialize(leaf).split("\n")) {
line.trimLeft(" ", 1L);
if(line.endsWith("rom") && rom) {
line.append(" name=", rom.left()["name"].text());
line.append(" size=", rom.left()["size"].text());
rom.removeLeft();
}
if(line.endsWith("ram") && ram) {
line.append(" name=", ram.left()["name"].text());
line.append(" size=", ram.left()["size"].text());
if(ram.left()["type"].text() == "RAM") line.append(" volatile");
ram.removeLeft();
}
output.append(line, "\n");
}
break;
}
}
return BML::unserialize(output);
}
auto Cartridge::loadCartridge(Markup::Node node) -> void {
information.title.cartridge = node["game/label"].text();
auto board = node["board"]; auto board = node["board"];
if(!board) board = loadBoard(node); if(!board) board = loadBoard(node);
if(region() == "Auto") {
if(board["region"].text() == "ntsc") information.region = "NTSC";
if(board["region"].text() == "pal") information.region = "PAL";
}
if(board["bsmemory"] || board["mcc/bsmemory"] || board["sa1/bsmemory"]) { if(board["bsmemory"] || board["mcc/bsmemory"] || board["sa1/bsmemory"]) {
if(auto loaded = platform->load(ID::BSMemory, "BS Memory", "bs")) { if(auto loaded = platform->load(ID::BSMemory, "BS Memory", "bs")) {
@ -401,6 +370,7 @@ auto Cartridge::loadMemory(MappedRAM& ram, Markup::Node node, bool required, may
auto size = node["size"].natural(); auto size = node["size"].natural();
ram.allocate(size); ram.allocate(size);
if(auto fp = platform->open(id(), name, File::Read, required)) { if(auto fp = platform->open(id(), name, File::Read, required)) {
ram.allocate(fp->size()); //TODO: temporary hack
fp->read(ram.data(), ram.size()); fp->read(ram.data(), ram.size());
} }
} }

View File

@ -1,376 +1,10 @@
database database
revision: 2018-02-21 revision: 2018-03-04
//Boards (Production) //Boards (Production)
database database
revision: 2018-02-21 revision: 2018-02-27
board: 1A0N-(01,02,10,20,30)
rom
map address=00-7d,80-ff:8000-ffff mask=0x8000
map address=40-7d,c0-ff:0000-7fff mask=0x8000
board: 1A1B-(04,05,06)
rom
map address=00-1f,80-9f:8000-ffff mask=0x8000
ram
map address=70-7d,f0-ff:0000-ffff
board: 1A1M-(01,10,11,20)
rom
map address=00-7d,80-ff:8000-ffff mask=0x8000
ram
map address=70-7d,f0-ff:0000-7fff mask=0x8000
board: 1A3B-(11,12,13)
rom
map address=00-1f,80-9f:8000-ffff mask=0x8000
ram
map address=70-7d,f0-ff:0000-ffff
board: 1A3B-20
rom
map address=00-7d,80-ff:8000-ffff mask=0x8000
ram
map address=70-7d,f0-ff:0000-7fff mask=0x8000
board: 1A3M-(10,20,21,30)
rom
map address=00-7d,80-ff:8000-ffff mask=0x8000
ram
map address=70-7d,f0-ff:0000-7fff mask=0x8000
board: 1A5B-(02,04)
rom
map address=00-1f,80-9f:8000-ffff mask=0x8000
ram
map address=70-7d,f0-ff:0000-ffff
board: 1A5M-(01,11,20)
rom
map address=00-7d,80-ff:8000-ffff mask=0x8000
ram
map address=70-7d,f0-ff:0000-7fff mask=0x8000
board: 1B0N-(02,03,10)
rom
map address=00-1f,80-9f:8000-ffff mask=0x8000
necdsp model=uPD7725 frequency=8000000
map address=30-3f,b0-bf:8000-ffff mask=0x3fff
prom
drom
dram
board: 1B5B-02
rom
map address=00-1f,80-9f:8000-ffff mask=0x8000
ram
map address=70-7d,f0-ff:0000-ffff
necdsp model=uPD7725 frequency=8000000
map address=20-3f,a0-bf:8000-ffff mask=0x3fff
prom
drom
dram
board: 1C0N
superfx
map address=00-3f,80-bf:3000-34ff
rom
map address=00-1f,80-9f:8000-ffff mask=0x8000
ram
map address=60-7d,e0-ff:0000-ffff
board: 1C0N5S-01
superfx
map address=00-3f,80-bf:3000-34ff
rom
map address=00-1f,80-9f:8000-ffff mask=0x8000
ram
map address=60-7d,e0-ff:0000-ffff
board: 1CA0N5S-01
superfx
map address=00-3f,80-bf:3000-34ff
rom
map address=00-3f,80-bf:8000-ffff mask=0x8000
map address=40-5f,c0-df:0000-ffff
ram
map address=00-3f,80-bf:6000-7fff size=0x2000
map address=70-71,f0-f1:0000-ffff
board: 1CA0N6S-01
superfx
map address=00-3f,80-bf:3000-34ff
rom
map address=00-3f,80-bf:8000-ffff mask=0x8000
map address=40-5f,c0-df:0000-ffff
ram
map address=00-3f,80-bf:6000-7fff size=0x2000
map address=70-71,f0-f1:0000-ffff
board: 1CA6B-01
superfx
map address=00-3f,80-bf:3000-34ff
rom
map address=00-3f,80-bf:8000-ffff mask=0x8000
map address=40-5f,c0-df:0000-ffff
ram
map address=00-3f,80-bf:6000-7fff size=0x2000
map address=70-71,f0-f1:0000-ffff
board: 1CB0N7S-01
superfx
map address=00-3f,80-bf:3000-34ff
rom
map address=00-3f:8000-ffff mask=0x8000
map address=40-5f:0000-ffff
ram
map address=00-3f,80-bf:6000-7fff size=0x2000
map address=70-71:0000-ffff
board: 1CB5B-20
superfx
map address=00-3f,80-bf:3000-34ff
rom
map address=00-3f:8000-ffff mask=0x8000
map address=40-5f:0000-ffff
ram
map address=00-3f,80-bf:6000-7fff size=0x2000
map address=70-71:0000-ffff
board: 1CB7B-01
superfx
map address=00-3f,80-bf:3000-34ff
rom
map address=00-3f:8000-ffff mask=0x8000
map address=40-5f:0000-ffff
ram
map address=00-3f,80-bf:6000-7fff size=0x2000
map address=70-71:0000-ffff
board: 1DC0N-01
hitachidsp model=HG51B169 frequency=20000000
map address=00-3f,80-bf:6c00-6fff,7c00-7fff
map address=70-77:0000-7fff
rom
map address=00-3f,80-bf:8000-ffff mask=0x8000
drom
dram
map address=00-3f,80-bf:6000-6bff,7000-7bff mask=0xf000
board: 1DS0B-20
rom
map address=00-7d,80-ff:8000-ffff mask=0x8000
necdsp model=uPD96050 frequency=11000000
map address=60-67,e0-e7:0000-3fff
prom
drom
dram
map address=68-6f,e8-ef:0000-7fff mask=0x8000
board: 1J0N-(01,10,20)
rom
map address=00-3f,80-bf:8000-ffff
map address=40-7d,c0-ff:0000-ffff
board: 1J1M-(11,20)
rom
map address=00-3f,80-bf:8000-ffff
map address=40-7d,c0-ff:0000-ffff
ram
map address=20-3f,a0-bf:6000-7fff mask=0xe000
board: 1J3B-01
rom
map address=00-3f,80-bf:8000-ffff
map address=40-7d,c0-ff:0000-ffff
ram
map address=20-3f,a0-bf:6000-7fff mask=0xe000
board: 1J3M-(01,11,20)
rom
map address=00-3f,80-bf:8000-ffff
map address=40-7d,c0-ff:0000-ffff
ram
map address=20-3f,a0-bf:6000-7fff mask=0xe000
board: 1J5M-(01,11,20)
rom
map address=00-3f,80-bf:8000-ffff
map address=40-7d,c0-ff:0000-ffff
ram
map address=20-3f,a0-bf:6000-7fff mask=0xe000
board: 1K0N-01
rom
map address=00-3f,80-bf:8000-ffff
map address=40-7d,c0-ff:0000-ffff
necdsp model=uPD7725 frequency=8000000
map address=00-1f,80-9f:6000-7fff mask=0xfff
prom
drom
dram
board: 1K1B-01
rom
map address=00-3f,80-bf:8000-ffff
map address=40-7d,c0-ff:0000-ffff
ram
map address=20-3f,a0-bf:6000-7fff mask=0xe000
necdsp model=uPD7725 frequency=8000000
map address=00-1f,80-9f:6000-7fff mask=0xfff
prom
drom
dram
board: 1L0N3S-01
sa1
map address=00-3f,80-bf:2200-23ff
rom
map address=00-3f,80-bf:8000-ffff mask=0x408000
map address=c0-ff:0000-ffff
bwram
map address=00-3f,80-bf:6000-7fff size=0x2000
map address=40-4f:0000-ffff
iram
map address=00-3f,80-bf:3000-37ff size=0x800
board: 1L3B-(02,11)
sa1
map address=00-3f,80-bf:2200-23ff
rom
map address=00-3f,80-bf:8000-ffff mask=0x408000
map address=c0-ff:0000-ffff
bwram
map address=00-3f,80-bf:6000-7fff size=0x2000
map address=40-4f:0000-ffff
iram
map address=00-3f,80-bf:3000-37ff size=0x800
board: 1L5B-(11,20)
sa1
map address=00-3f,80-bf:2200-23ff
rom
map address=00-3f,80-bf:8000-ffff mask=0x408000
map address=c0-ff:0000-ffff
bwram
map address=00-3f,80-bf:6000-7fff size=0x2000
map address=40-4f:0000-ffff
iram
map address=00-3f,80-bf:3000-37ff size=0x800
board: 1N0N-01
sdd1
map address=00-3f,80-bf:4800-480f
rom
map address=00-3f,80-bf:8000-ffff
map address=c0-ff:0000-ffff
board: 2A0N-(01,10,11,20)
rom
map address=00-7d,80-ff:8000-ffff mask=0x8000
map address=40-7d,c0-ff:0000-7fff mask=0x8000
board: 2A1M-01
rom
map address=00-7d,80-ff:8000-ffff mask=0x8000
ram
map address=70-7d,f0-ff:0000-7fff mask=0x8000
board: 2A3B-01
rom
map address=00-3f,80-bf:8000-ffff mask=0x8000
ram
map address=70-7d,f0-ff:0000-7fff mask=0x8000
board: 2A3M-01#R
rom
map address=00-3f,80-bf:8000-ffff mask=0x8000
ram
map address=70-7d,f0-ff:0000-7fff mask=0x8000
board: 2A3M-(01,11,20)
rom
map address=00-7d,80-ff:8000-ffff mask=0x8000
ram
map address=70-7d,f0-ff:0000-7fff mask=0x8000
board: 2A5M-01
rom
map address=00-7d,80-ff:8000-ffff mask=0x8000
ram
map address=70-7d,f0-ff:0000-7fff mask=0x8000
board: 2B3B-01
rom
map address=00-3f,80-bf:8000-ffff mask=0x8000
ram
map address=70-7d,f0-ff:0000-7fff mask=0x8000
necdsp model=uPD7725 frequency=8000000
map address=60-6f,e0-ef:0000-7fff mask=0x3fff
prom
drom
dram
board: 2DC0N-01
hitachidsp model=HG51B169 frequency=20000000
map address=00-3f,80-bf:6c00-6fff,7c00-7fff
map address=70-77:0000-7fff
rom
map address=00-3f,80-bf:8000-ffff mask=0x8000
drom
dram
map address=00-3f,80-bf:6000-6bff,7000-7bff mask=0xf000
board: 2E3M-01
rom
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
board: 2J0N-(01,10,11,20)
rom
map address=00-3f,80-bf:8000-ffff
map address=40-7d,c0-ff:0000-ffff
board: 2J3M-(01,11,20)
rom
map address=00-3f,80-bf:8000-ffff
map address=40-7d,c0-ff:0000-ffff
ram
map address=10-1f,30-3f,90-9f,b0-bf:6000-7fff mask=0xe000
board: 2J5M-01
rom
map address=00-3f,80-bf:8000-ffff
map address=40-7d,c0-ff:0000-ffff
ram
map address=10-1f,30-3f,90-9f,b0-bf:6000-7fff mask=0xe000
board: 3J0N-01
rom
map address=00-2f,80-af:8000-ffff
map address=40-6f,c0-ef:0000-ffff
board: BA0N-(01,10)
rom
map address=00-7d,80-ff:8000-ffff mask=0x8000
map address=40-7d,c0-ff:0000-7fff mask=0x8000
board: BA1M-01
rom
map address=00-7d,80-ff:8000-ffff mask=0x8000
ram
map address=70-7d,f0-ff:0000-7fff mask=0x8000
board: BA3M-(01,10)
rom
map address=00-7d,80-ff:8000-ffff mask=0x8000
ram
map address=70-7d,f0-ff:0000-7fff mask=0x8000
board: BANDAI-PT-923 board: BANDAI-PT-923
rom rom
@ -386,25 +20,6 @@ board: BANDAI-PT-923
ram ram
map address=70-7d,f0-ff:0000-ffff map address=70-7d,f0-ff:0000-ffff
board: BJ0N-(01,20)
rom
map address=00-3f,80-bf:8000-ffff
map address=40-7d,c0-ff:0000-ffff
board: BJ1M-(10,20)
rom
map address=00-3f,80-bf:8000-ffff
map address=40-7d,c0-ff:0000-ffff
ram
map address=20-3f,a0-bf:6000-7fff mask=0xe000
board: BJ3M-10
rom
map address=00-3f,80-bf:8000-ffff
map address=40-7d,c0-ff:0000-ffff
ram
map address=20-3f,a0-bf:6000-7fff mask=0xe000
board: BSC-1A5M-02 board: BSC-1A5M-02
rom rom
map address=00-1f:8000-ffff mask=0x8000 base=0x000000 map address=00-1f:8000-ffff mask=0x8000 base=0x000000
@ -482,6 +97,420 @@ board: SGB-R-10
rom rom
gameboy gameboy
board: SHVC-1A0N-(01,02,10,20,30)
rom
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
map address=00-1f,80-9f:8000-ffff mask=0x8000
ram
map address=70-7d,f0-ff:0000-ffff
board: SHVC-1A1M-(01,10,11,20)
rom
map address=00-7d,80-ff:8000-ffff mask=0x8000
ram
map address=70-7d,f0-ff:0000-7fff mask=0x8000
board: SHVC-1A3B-(11,12,13)
rom
map address=00-1f,80-9f:8000-ffff mask=0x8000
ram
map address=70-7d,f0-ff:0000-ffff
board: SHVC-1A3B-20
rom
map address=00-7d,80-ff:8000-ffff mask=0x8000
ram
map address=70-7d,f0-ff:0000-7fff mask=0x8000
board: SHVC-1A3M-(10,20,21,30)
rom
map address=00-7d,80-ff:8000-ffff mask=0x8000
ram
map address=70-7d,f0-ff:0000-7fff mask=0x8000
board: SHVC-1A5B-(02,04)
rom
map address=00-1f,80-9f:8000-ffff mask=0x8000
ram
map address=70-7d,f0-ff:0000-ffff
board: SHVC-1A5M-(01,11,20)
rom
map address=00-7d,80-ff:8000-ffff mask=0x8000
ram
map address=70-7d,f0-ff:0000-7fff mask=0x8000
board: SHVC-1B0N-(02,03,10)
rom
map address=00-1f,80-9f:8000-ffff mask=0x8000
necdsp model=uPD7725 frequency=8000000
map address=30-3f,b0-bf:8000-ffff mask=0x3fff
prom
drom
dram
board: SHVC-1B5B-02
rom
map address=00-1f,80-9f:8000-ffff mask=0x8000
ram
map address=70-7d,f0-ff:0000-ffff
necdsp model=uPD7725 frequency=8000000
map address=20-3f,a0-bf:8000-ffff mask=0x3fff
prom
drom
dram
board: SHVC-1C0N
superfx
map address=00-3f,80-bf:3000-34ff
rom
map address=00-1f,80-9f:8000-ffff mask=0x8000
ram
map address=60-7d,e0-ff:0000-ffff
board: SHVC-1C0N5S-01
superfx
map address=00-3f,80-bf:3000-34ff
rom
map address=00-1f,80-9f:8000-ffff mask=0x8000
ram
map address=60-7d,e0-ff:0000-ffff
board: SHVC-1CA0N5S-01
superfx
map address=00-3f,80-bf:3000-34ff
rom
map address=00-3f,80-bf:8000-ffff mask=0x8000
map address=40-5f,c0-df:0000-ffff
ram
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
map address=00-3f,80-bf:8000-ffff mask=0x8000
map address=40-5f,c0-df:0000-ffff
ram
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
map address=00-3f,80-bf:8000-ffff mask=0x8000
map address=40-5f,c0-df:0000-ffff
ram
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
map address=00-3f:8000-ffff mask=0x8000
map address=40-5f:0000-ffff
ram
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
map address=00-3f:8000-ffff mask=0x8000
map address=40-5f:0000-ffff
ram
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
map address=00-3f:8000-ffff mask=0x8000
map address=40-5f:0000-ffff
ram
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
map address=00-3f,80-bf:6c00-6fff,7c00-7fff
map address=70-77:0000-7fff
rom
map address=00-3f,80-bf:8000-ffff mask=0x8000
drom
dram
map address=00-3f,80-bf:6000-6bff,7000-7bff mask=0xf000
board: SHVC-1DS0B-20
rom
map address=00-7d,80-ff:8000-ffff mask=0x8000
necdsp model=uPD96050 frequency=11000000
map address=60-67,e0-e7:0000-3fff
prom
drom
dram
map address=68-6f,e8-ef:0000-7fff mask=0x8000
board: SHVC-1J0N-(01,10,20)
rom
map address=00-3f,80-bf:8000-ffff
map address=40-7d,c0-ff:0000-ffff
board: SHVC-1J1M-(11,20)
rom
map address=00-3f,80-bf:8000-ffff
map address=40-7d,c0-ff:0000-ffff
ram
map address=20-3f,a0-bf:6000-7fff mask=0xe000
board: SHVC-1J3B-01
rom
map address=00-3f,80-bf:8000-ffff
map address=40-7d,c0-ff:0000-ffff
ram
map address=20-3f,a0-bf:6000-7fff mask=0xe000
board: SHVC-1J3M-(01,11,20)
rom
map address=00-3f,80-bf:8000-ffff
map address=40-7d,c0-ff:0000-ffff
ram
map address=20-3f,a0-bf:6000-7fff mask=0xe000
board: SHVC-1J5M-(01,11,20)
rom
map address=00-3f,80-bf:8000-ffff
map address=40-7d,c0-ff:0000-ffff
ram
map address=20-3f,a0-bf:6000-7fff mask=0xe000
board: SHVC-1K0N-01
rom
map address=00-3f,80-bf:8000-ffff
map address=40-7d,c0-ff:0000-ffff
necdsp model=uPD7725 frequency=8000000
map address=00-1f,80-9f:6000-7fff mask=0xfff
prom
drom
dram
board: SHVC-1K1B-01
rom
map address=00-3f,80-bf:8000-ffff
map address=40-7d,c0-ff:0000-ffff
ram
map address=20-3f,a0-bf:6000-7fff mask=0xe000
necdsp model=uPD7725 frequency=8000000
map address=00-1f,80-9f:6000-7fff mask=0xfff
prom
drom
dram
board: SHVC-1L0N3S-01
sa1
map address=00-3f,80-bf:2200-23ff
rom
map address=00-3f,80-bf:8000-ffff mask=0x408000
map address=c0-ff:0000-ffff
bwram
map address=00-3f,80-bf:6000-7fff size=0x2000
map address=40-4f:0000-ffff
iram
map address=00-3f,80-bf:3000-37ff size=0x800
board: SHVC-1L3B-(02,11)
sa1
map address=00-3f,80-bf:2200-23ff
rom
map address=00-3f,80-bf:8000-ffff mask=0x408000
map address=c0-ff:0000-ffff
bwram
map address=00-3f,80-bf:6000-7fff size=0x2000
map address=40-4f:0000-ffff
iram
map address=00-3f,80-bf:3000-37ff size=0x800
board: SHVC-1L5B-(11,20)
sa1
map address=00-3f,80-bf:2200-23ff
rom
map address=00-3f,80-bf:8000-ffff mask=0x408000
map address=c0-ff:0000-ffff
bwram
map address=00-3f,80-bf:6000-7fff size=0x2000
map address=40-4f:0000-ffff
iram
map address=00-3f,80-bf:3000-37ff size=0x800
board: SHVC-1N0N-(01,10)
sdd1
map address=00-3f,80-bf:4800-480f
rom
map address=00-3f,80-bf:8000-ffff
map address=c0-ff:0000-ffff
board: SHVC-2A0N-01#R
rom
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
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
map address=00-7d,80-ff:8000-ffff mask=0x8000
ram
map address=70-7d,f0-ff:0000-7fff mask=0x8000
board: SHVC-2A3B-01
rom
map address=00-3f,80-bf:8000-ffff mask=0x8000
ram
map address=70-7d,f0-ff:0000-7fff mask=0x8000
board: SHVC-2A3M-01#R
rom
map address=00-3f,80-bf:8000-ffff mask=0x8000
ram
map address=70-7d,f0-ff:0000-7fff mask=0x8000
board: SHVC-2A3M-(01,11,20)
rom
map address=00-7d,80-ff:8000-ffff mask=0x8000
ram
map address=70-7d,f0-ff:0000-7fff mask=0x8000
board: SHVC-2A5M-01
rom
map address=00-7d,80-ff:8000-ffff mask=0x8000
ram
map address=70-7d,f0-ff:0000-7fff mask=0x8000
board: SHVC-2B3B-01
rom
map address=00-3f,80-bf:8000-ffff mask=0x8000
ram
map address=70-7d,f0-ff:0000-7fff mask=0x8000
necdsp model=uPD7725 frequency=8000000
map address=60-6f,e0-ef:0000-7fff mask=0x3fff
prom
drom
dram
board: SHVC-2DC0N-01
hitachidsp model=HG51B169 frequency=20000000
map address=00-3f,80-bf:6c00-6fff,7c00-7fff
map address=70-77:0000-7fff
rom
map address=00-3f,80-bf:8000-ffff mask=0x8000
drom
dram
map address=00-3f,80-bf:6000-6bff,7000-7bff mask=0xf000
board: SHVC-2E3M-01
rom
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
board: SHVC-2J0N-(01,10,11,20)
rom
map address=00-3f,80-bf:8000-ffff
map address=40-7d,c0-ff:0000-ffff
board: SHVC-2J3M-(01,11,20)
rom
map address=00-3f,80-bf:8000-ffff
map address=40-7d,c0-ff:0000-ffff
ram
map address=10-1f,30-3f,90-9f,b0-bf:6000-7fff mask=0xe000
board: SHVC-2J5M-01
rom
map address=00-3f,80-bf:8000-ffff
map address=40-7d,c0-ff:0000-ffff
ram
map address=10-1f,30-3f,90-9f,b0-bf:6000-7fff mask=0xe000
board: SHVC-3J0N-01
rom
map address=00-2f,80-af:8000-ffff
map address=40-6f,c0-ef:0000-ffff
board: SHVC-BA0N-(01,10)
rom
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
map address=00-7d,80-ff:8000-ffff mask=0x8000
ram
map address=70-7d,f0-ff:0000-7fff mask=0x8000
board: SHVC-BA3M-(01,10)
rom
map address=00-7d,80-ff:8000-ffff mask=0x8000
ram
map address=70-7d,f0-ff:0000-7fff mask=0x8000
board: SHVC-BJ0N-(01,20)
rom
map address=00-3f,80-bf:8000-ffff
map address=40-7d,c0-ff:0000-ffff
board: SHVC-BJ1M-(10,20)
rom
map address=00-3f,80-bf:8000-ffff
map address=40-7d,c0-ff:0000-ffff
ram
map address=20-3f,a0-bf:6000-7fff mask=0xe000
board: SHVC-BJ3M-10
rom
map address=00-3f,80-bf:8000-ffff
map address=40-7d,c0-ff:0000-ffff
ram
map address=20-3f,a0-bf:6000-7fff mask=0xe000
board: SHVC-LDH3C-01
spc7110
map address=00-3f,80-bf:4800-483f
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
map address=00-3f,80-bf:6000-7fff mask=0xe000
epsonrtc
map address=00-3f,80-bf:4840-4842
ram
board: SHVC-LN3B-01
sdd1
map address=00-3f,80-bf:4800-480f
rom
map address=00-3f,80-bf:8000-ffff
map address=c0-ff:0000-ffff
ram
map address=00-3f,80-bf:6000-7fff mask=0xe000
map address=70-73:0000-ffff
board: SHVC-SGB2-01 board: SHVC-SGB2-01
rom rom
map address=00-7d,80-ff:8000-ffff mask=0x8000 map address=00-7d,80-ff:8000-ffff mask=0x8000
@ -491,12 +520,12 @@ board: SHVC-SGB2-01
rom rom
gameboy gameboy
board: YA0N-01 board: SHVC-YA0N-01
rom rom
map address=00-7d,80-ff:8000-ffff mask=0x8000 map address=00-7d,80-ff:8000-ffff mask=0x8000
map address=40-7d,c0-ff:0000-7fff mask=0x8000 map address=40-7d,c0-ff:0000-7fff mask=0x8000
board: YJ0N-01 board: SHVC-YJ0N-01
rom rom
map address=00-3f,80-bf:8000-ffff map address=00-3f,80-bf:8000-ffff
map address=40-7d,c0-ff:0000-ffff map address=40-7d,c0-ff:0000-ffff
@ -504,7 +533,7 @@ board: YJ0N-01
//Boards (Generic) //Boards (Generic)
database database
revision: 2018-02-21 revision: 2018-03-04
board: ARM-LOROM-RAM board: ARM-LOROM-RAM
rom rom
@ -565,15 +594,15 @@ board: BS-SA1-RAM
bsmemory bsmemory
board: HIROM board: HIROM
rom rom name=program.rom
map address=00-3f,80-bf:8000-ffff map address=00-3f,80-bf:8000-ffff
map address=40-7d,c0-ff:0000-ffff map address=40-7d,c0-ff:0000-ffff
board: HIROM-RAM board: HIROM-RAM
rom rom name=program.rom
map address=00-3f,80-bf:8000-ffff map address=00-3f,80-bf:8000-ffff
map address=40-7d,c0-ff:0000-ffff map address=40-7d,c0-ff:0000-ffff
ram ram name=save.ram
map address=20-3f,a0-bf:6000-7fff mask=0xe000 map address=20-3f,a0-bf:6000-7fff mask=0xe000
board: HIROMEX-RAM board: HIROMEX-RAM
@ -597,13 +626,13 @@ board: HITACHI-LOROM
map address=00-3f,80-bf:6000-6bff,7000-7bff mask=0xf000 map address=00-3f,80-bf:6000-6bff,7000-7bff mask=0xf000
board: LOROM board: LOROM
rom rom name=program.rom
map address=00-7d,80-ff:8000-ffff mask=0x8000 map address=00-7d,80-ff:8000-ffff mask=0x8000
board: LOROM-RAM board: LOROM-RAM
rom rom name=program.rom
map address=00-3f,80-bf:8000-ffff mask=0x8000 map address=00-3f,80-bf:8000-ffff mask=0x8000
ram ram name=save.ram
map address=70-7d,f0-ff:0000-ffff mask=0x8000 map address=70-7d,f0-ff:0000-ffff mask=0x8000
board: LOROMEX-RAM board: LOROMEX-RAM

Binary file not shown.

After

Width:  |  Height:  |  Size: 629 B

View File

@ -84,6 +84,7 @@ namespace name=Icon
binary name=Desktop file=icon/place/desktop.png binary name=Desktop file=icon/place/desktop.png
binary name=Home file=icon/place/home.png binary name=Home file=icon/place/home.png
binary name=Server file=icon/place/server.png binary name=Server file=icon/place/server.png
binary name=Settings file=icon/place/settings.png
binary name=Share file=icon/place/share.png binary name=Share file=icon/place/share.png
namespace name=Prompt namespace name=Prompt
binary name=Error file=icon/prompt/error.png binary name=Error file=icon/prompt/error.png

View File

@ -1756,6 +1756,28 @@ const nall::vector<uint8_t> Server = { //size: 642
162,75,129,231,151,151,151,31,252,63,158,1,254,0,124,80,17,254,250,115,5,147,0,0,0,0,73,69,78,68,174,66, 162,75,129,231,151,151,151,31,252,63,158,1,254,0,124,80,17,254,250,115,5,147,0,0,0,0,73,69,78,68,174,66,
96,130, 96,130,
}; };
const nall::vector<uint8_t> Settings = { //size: 629
137,80,78,71,13,10,26,10,0,0,0,13,73,72,68,82,0,0,0,16,0,0,0,16,8,6,0,0,0,31,243,255,
97,0,0,0,6,98,75,71,68,0,255,0,255,0,255,160,189,167,147,0,0,0,9,112,72,89,115,0,0,11,19,0,
0,11,19,1,0,154,156,24,0,0,0,7,116,73,77,69,7,213,11,4,11,55,32,209,169,238,103,0,0,0,29,116,
69,88,116,67,111,109,109,101,110,116,0,67,114,101,97,116,101,100,32,119,105,116,104,32,84,104,101,32,71,73,77,80,
239,100,37,110,0,0,1,217,73,68,65,84,56,203,197,147,77,107,19,97,20,133,159,105,107,131,52,157,52,35,161,38,
67,55,129,198,221,132,100,66,72,138,88,117,37,53,89,137,8,21,4,33,100,254,65,17,92,117,33,136,43,17,55,45,
253,3,165,45,8,67,178,81,12,88,65,145,188,249,152,162,130,219,36,148,137,52,37,89,180,136,31,113,97,103,72,219,
116,213,133,119,117,121,207,229,112,239,57,231,133,115,150,116,22,240,244,217,147,190,211,63,90,122,124,230,220,152,211,220,
189,119,39,163,235,113,19,64,136,74,22,32,159,51,88,93,91,57,134,157,36,115,9,116,61,110,230,115,6,150,101,1,
152,161,160,74,203,110,16,10,170,160,99,166,146,105,52,77,3,232,15,146,140,13,178,89,150,197,165,105,63,183,179,11,
238,91,44,17,37,70,212,197,79,214,168,211,248,21,191,248,211,255,189,24,185,50,75,171,209,98,251,221,118,175,109,183,
61,59,214,78,111,202,55,229,153,240,78,80,42,149,16,162,146,253,242,249,235,183,99,27,56,130,133,130,42,0,181,90,
173,103,219,223,95,9,81,221,84,20,229,170,36,141,62,92,200,220,10,56,231,232,122,220,213,98,196,97,202,231,12,98,
137,127,171,250,124,62,185,217,108,110,110,172,111,153,157,78,231,189,44,123,3,206,57,249,156,49,220,133,213,181,21,66,
65,149,88,34,202,193,193,225,225,220,92,122,9,32,28,14,27,221,110,183,7,200,213,114,157,194,110,241,180,6,111,94,
191,93,246,43,126,49,57,233,93,188,113,237,38,63,127,253,184,208,110,183,3,145,200,236,3,73,226,242,252,245,121,121,
220,51,78,69,84,16,162,146,125,241,252,229,253,161,54,166,146,105,90,118,3,117,70,69,157,81,47,30,65,178,51,147,
74,166,1,204,141,245,45,215,198,145,193,117,52,77,99,207,222,167,96,22,169,150,235,0,84,203,117,10,102,145,61,123,
223,201,193,112,13,142,84,237,187,73,212,49,51,211,25,10,187,69,39,153,230,199,79,31,78,37,241,220,127,225,255,215,
95,179,89,175,43,2,12,187,45,0,0,0,0,73,69,78,68,174,66,96,130,
};
const nall::vector<uint8_t> Share = { //size: 697 const nall::vector<uint8_t> Share = { //size: 697
137,80,78,71,13,10,26,10,0,0,0,13,73,72,68,82,0,0,0,16,0,0,0,16,8,6,0,0,0,31,243,255, 137,80,78,71,13,10,26,10,0,0,0,13,73,72,68,82,0,0,0,16,0,0,0,16,8,6,0,0,0,31,243,255,
97,0,0,0,4,115,66,73,84,8,8,8,8,124,8,100,136,0,0,0,9,112,72,89,115,0,0,13,215,0,0,13, 97,0,0,0,4,115,66,73,84,8,8,8,8,124,8,100,136,0,0,0,9,112,72,89,115,0,0,13,215,0,0,13,

View File

@ -91,6 +91,7 @@ extern const nall::vector<uint8_t> Bookmarks;
extern const nall::vector<uint8_t> Desktop; extern const nall::vector<uint8_t> Desktop;
extern const nall::vector<uint8_t> Home; extern const nall::vector<uint8_t> Home;
extern const nall::vector<uint8_t> Server; extern const nall::vector<uint8_t> Server;
extern const nall::vector<uint8_t> Settings;
extern const nall::vector<uint8_t> Share; extern const nall::vector<uint8_t> Share;
} }
namespace Prompt { namespace Prompt {

View File

@ -1,5 +1,5 @@
database database
revision: 2018-02-16 revision: 2018-03-01
//BS Memory (JPN) //BS Memory (JPN)

View File

@ -1,5 +1,5 @@
database database
revision: 2018-02-16 revision: 2018-03-01
//Sufami Turbo (JPN) //Sufami Turbo (JPN)

File diff suppressed because it is too large Load Diff

View File

@ -3,9 +3,9 @@ auto Icarus::superFamicomManifest(string location) -> string {
auto files = directory::files(location, "*.rom"); auto files = directory::files(location, "*.rom");
concatenate(buffer, {location, "program.rom"}); concatenate(buffer, {location, "program.rom"});
concatenate(buffer, {location, "data.rom" }); concatenate(buffer, {location, "data.rom" });
for(auto& file : files.match("*.boot.rom" )) concatenate(buffer, {location, file});
for(auto& file : files.match("*.program.rom")) concatenate(buffer, {location, file}); for(auto& file : files.match("*.program.rom")) concatenate(buffer, {location, file});
for(auto& file : files.match("*.data.rom" )) concatenate(buffer, {location, file}); for(auto& file : files.match("*.data.rom" )) concatenate(buffer, {location, file});
for(auto& file : files.match("*.boot.rom" )) concatenate(buffer, {location, file});
return superFamicomManifest(buffer, location); return superFamicomManifest(buffer, location);
} }
@ -19,10 +19,7 @@ auto Icarus::superFamicomManifest(vector<uint8_t>& buffer, string location) -> s
if(settings["icarus/UseHeuristics"].boolean()) { if(settings["icarus/UseHeuristics"].boolean()) {
Heuristics::SuperFamicom game{buffer, location}; Heuristics::SuperFamicom game{buffer, location};
if(auto manifest = game.manifest()) { if(auto manifest = game.manifest()) return manifest;
if(exists({location, "msu1.rom"})) manifest.append(" msu1\n");
return manifest;
}
} }
return {}; return {};
@ -44,11 +41,12 @@ auto Icarus::superFamicomImport(vector<uint8_t>& buffer, string location) -> str
if(settings["icarus/CreateManifests"].boolean()) write({target, "manifest.bml"}, manifest); if(settings["icarus/CreateManifests"].boolean()) write({target, "manifest.bml"}, manifest);
uint offset = 0; uint offset = 0;
auto document = BML::unserialize(manifest); auto document = BML::unserialize(manifest);
for(auto rom : document.find("game/memory")) { for(auto rom : document.find("game/board/memory")) {
if(rom["type"].text() != "ROM") continue; if(rom["type"].text() != "ROM") continue;
auto name = rom["name"].text(); auto name = string{rom["part"].text(), ".", rom["category"].text(), ".rom"}.trimLeft(".", 1L).downcase();
auto size = rom["size"].natural(); auto size = rom["size"].natural();
if(size > buffer.size() - offset) { if(size > buffer.size() - offset) {
auto name = string{rom["note"].text(), ".", rom["category"].text(), ".rom"}.trimLeft(".", 1L).downcase();
auto location = locate({"Firmware/", name}); auto location = locate({"Firmware/", name});
if(location && file::size(location) == size) { if(location && file::size(location) == size) {
write({target, name}, file::read(location)); write({target, name}, file::read(location));

View File

@ -23,9 +23,10 @@ auto BSMemory::manifest() const -> string {
string output; string output;
output.append("game\n"); output.append("game\n");
output.append(" sha256: ", Hash::SHA256(data).digest(), "\n"); output.append(" sha256: ", Hash::SHA256(data).digest(), "\n");
output.append(" name: ", Location::prefix(location), "\n");
output.append(" label: ", Location::prefix(location), "\n"); output.append(" label: ", Location::prefix(location), "\n");
output.append(memory("NAND", data.size(), "program.rom")); output.append(" name: ", Location::prefix(location), "\n");
output.append(" board\n");
output.append(Memory{}.type("Flash").size(data.size()).category("Program").text());
return output; return output;
} }

View File

@ -35,8 +35,8 @@ auto Famicom::manifest() const -> string {
string output; string output;
output.append("game\n"); output.append("game\n");
output.append(" sha256: ", Hash::SHA256(&data[16], data.size() - 16).digest(), "\n"); output.append(" sha256: ", Hash::SHA256(&data[16], data.size() - 16).digest(), "\n");
output.append(" name: ", Location::prefix(location), "\n");
output.append(" label: ", Location::prefix(location), "\n"); output.append(" label: ", Location::prefix(location), "\n");
output.append(" name: ", Location::prefix(location), "\n");
switch(mapper) { switch(mapper) {
default: default:
@ -161,11 +161,11 @@ auto Famicom::manifest() const -> string {
break; break;
} }
if(prgrom) output.append(memory("ROM", prgrom, "program.rom")); if(prgrom) output.append(Memory{}.type("ROM").size(prgrom).category("Program").text());
if(prgram) output.append(memory("NVRAM", prgram, "save.ram")); if(prgram) output.append(Memory{}.type("RAM").size(prgram).category("Save").battery().text());
if(chrrom) output.append(memory("ROM", chrrom, "character.rom")); if(chrrom) output.append(Memory{}.type("ROM").size(chrrom).category("Character").text());
if(chrram) output.append(memory("RAM", chrram, "character.ram")); if(chrram) output.append(Memory{}.type("RAM").size(chrram).category("Character").text());
return output; return output;
} }

View File

@ -50,16 +50,17 @@ auto GameBoyAdvance::manifest() const -> string {
string output; string output;
output.append("game\n"); output.append("game\n");
output.append(" sha256: ", Hash::SHA256(data).digest(), "\n"); output.append(" sha256: ", Hash::SHA256(data).digest(), "\n");
output.append(" name: ", Location::prefix(location), "\n");
output.append(" label: ", Location::prefix(location), "\n"); output.append(" label: ", Location::prefix(location), "\n");
output.append(memory("ROM", data.size(), "program.rom")); output.append(" name: ", Location::prefix(location), "\n");
output.append(" board\n");
output.append(Memory{}.type("ROM").size(data.size()).category("Program").text());
if(!list); if(!list);
else if(list.left().beginsWith("SRAM_V" )) output.append(memory("NVRAM", 0x8000, "save.ram")); else if(list.left().beginsWith("SRAM_V" )) output.append(Memory{}.type("RAM" ).size( 0x8000).category("Save").text());
else if(list.left().beginsWith("SRAM_F_V" )) output.append(memory("NVRAM", 0x8000, "save.ram")); else if(list.left().beginsWith("SRAM_F_V" )) output.append(Memory{}.type("RAM" ).size( 0x8000).category("Save").text());
else if(list.left().beginsWith("EEPROM_V" )) output.append(memory("EEPROM", 0x0, "save.ram")); else if(list.left().beginsWith("EEPROM_V" )) output.append(Memory{}.type("EEPROM").size( 0x0).category("Save").text());
else if(list.left().beginsWith("FLASH_V" )) output.append(memory("NAND", 0x10000, "save.ram")); else if(list.left().beginsWith("FLASH_V" )) output.append(Memory{}.type("Flash" ).size(0x10000).category("Save").text());
else if(list.left().beginsWith("FLASH512_V")) output.append(memory("NAND", 0x10000, "save.ram")); else if(list.left().beginsWith("FLASH512_V")) output.append(Memory{}.type("Flash" ).size(0x10000).category("Save").text());
else if(list.left().beginsWith("FLASH1M_V" )) output.append(memory("NAND", 0x20000, "save.ram")); else if(list.left().beginsWith("FLASH1M_V" )) output.append(Memory{}.type("Flash" ).size(0x20000).category("Save").text());
return output; return output;
} }

View File

@ -40,9 +40,9 @@ auto GameBoy::manifest() const -> string {
bool accelerometer = false; bool accelerometer = false;
bool rumble = false; bool rumble = false;
uint flashSize = 0;
uint romSize = 0; uint romSize = 0;
uint ramSize = 0; uint ramSize = 0;
uint flashSize = 0;
uint rtcSize = 0; uint rtcSize = 0;
string mapper = "MBC0"; string mapper = "MBC0";
@ -218,8 +218,6 @@ auto GameBoy::manifest() const -> string {
case 0x54: romSize = 96 * 16 * 1024; break; case 0x54: romSize = 96 * 16 * 1024; break;
} }
if(mapper == "MBC6" && flash) flashSize = 1024 * 1024;
switch(read(0x0149)) { default: switch(read(0x0149)) { default:
case 0x00: ramSize = 0 * 1024; break; case 0x00: ramSize = 0 * 1024; break;
case 0x01: ramSize = 2 * 1024; break; case 0x01: ramSize = 2 * 1024; break;
@ -232,21 +230,28 @@ auto GameBoy::manifest() const -> string {
if(mapper == "MBC7" && ram) ramSize = 256; if(mapper == "MBC7" && ram) ramSize = 256;
if(mapper == "TAMA" && ram) ramSize = 32; if(mapper == "TAMA" && ram) ramSize = 32;
if(mapper == "MBC6" && flash) flashSize = 1024 * 1024;
if(mapper == "MBC3" && rtc) rtcSize = 13; if(mapper == "MBC3" && rtc) rtcSize = 13;
if(mapper == "TAMA" && rtc) rtcSize = 21; if(mapper == "TAMA" && rtc) rtcSize = 21;
string output; string output;
output.append("game\n"); output.append("game\n");
output.append(" sha256: ", Hash::SHA256(data).digest(), "\n"); output.append(" sha256: ", Hash::SHA256(data).digest(), "\n");
output.append(" board: ", mapper, "\n");
if(accelerometer) output.append(" accelerometer\n");
if(rumble) output.append(" rumble\n");
output.append(" name: ", Location::prefix(location), "\n");
output.append(" label: ", Location::prefix(location), "\n"); output.append(" label: ", Location::prefix(location), "\n");
output.append(memory("ROM", data.size(), "program.rom")); output.append(" name: ", Location::prefix(location), "\n");
if(flash && flashSize) output.append(memory("NAND", flashSize, "download.rom")); output.append(" board: ", mapper, "\n");
if(ram && ramSize) output.append(memory(battery ? "NVRAM" : "RAM", ramSize, "save.ram")); output.append(Memory{}.type("ROM").size(data.size()).category("Program").text());
if(rtc && rtcSize) output.append(memory("RTC", rtcSize, "rtc.ram")); if(ram && ramSize)
output.append(Memory{}.type("RAM").size(ramSize).category("Save").battery(battery).text());
if(flash && flashSize)
output.append(Memory{}.type("Flash").size(flashSize).category("Download").text());
if(rtc && rtcSize)
output.append(Memory{}.type("RTC").size(rtcSize).category("Time").battery().text());
if(accelerometer)
output.append(" accelerometer\n");
if(rumble)
output.append(" rumble\n");
return output; return output;
} }

View File

@ -21,9 +21,11 @@ auto GameGear::manifest() const -> string {
string output; string output;
output.append("game\n"); output.append("game\n");
output.append(" sha256: ", Hash::SHA256(data).digest(), "\n"); output.append(" sha256: ", Hash::SHA256(data).digest(), "\n");
output.append(" name: ", Location::prefix(location), "\n");
output.append(" label: ", Location::prefix(location), "\n"); output.append(" label: ", Location::prefix(location), "\n");
output.append(memory("ROM", data.size(), "program.rom")); output.append(" name: ", Location::prefix(location), "\n");
output.append(" board\n");
output.append(Memory{}.type("ROM").size(data.size()).category("Program").text());
output.append(Memory{}.type("RAM").size(0x8000).category("Save").battery().text());
return output; return output;
} }

View File

@ -1,11 +1,40 @@
namespace Heuristics { namespace Heuristics {
auto Heuristics::memory(string type, uint size, string name) const -> string { auto Memory::text() const -> string {
string output;
output.append(" memory\n");
output.append(" type: ", _type, "\n");
output.append(" size: 0x", hex(_size), "\n");
output.append(" category: ", _category, "\n");
if(_manufacturer)
output.append(" manufacturer: ", _manufacturer, "\n");
if(_part)
output.append(" part: ", _part, "\n");
if(_note)
output.append(" note: ", _note, "\n");
if(_battery)
output.append(" battery\n");
return output;
}
auto Oscillator::text() const -> string {
string output;
output.append(" oscillator\n");
output.append(" frequency: ", _frequency, "\n");
if(_note)
output.append(" note: ", _note, "\n");
return output;
}
//deprecated
auto Heuristics::memory(string type, uint size, string name, string metadata) const -> string {
string output; string output;
output.append(" memory\n"); output.append(" memory\n");
output.append(" type: ", type, "\n"); output.append(" type: ", type, "\n");
output.append(" size: 0x", hex(size), "\n"); output.append(" size: 0x", hex(size), "\n");
output.append(" name: ", name, "\n"); output.append(" name: ", name, "\n");
if(metadata)
output.append(" metadata: ", metadata, "\n");
return output; return output;
} }

View File

@ -1,7 +1,35 @@
namespace Heuristics { namespace Heuristics {
struct Memory {
auto& type(string type) { _type = type; return *this; }
auto& size(natural size) { _size = size; return *this; }
auto& category(string category) { _category = category; return *this; }
auto& manufacturer(string manufacturer) { _manufacturer = manufacturer; return *this; }
auto& part(string part) { _part = part; return *this; }
auto& battery(boolean battery = true) { _battery = battery; return *this; }
auto& note(string note) { _note = note; return *this; }
auto text() const -> string;
string _type;
natural _size;
string _category;
string _manufacturer;
string _part;
boolean _battery;
string _note;
};
struct Oscillator {
auto& frequency(natural frequency) { _frequency = frequency; return *this; }
auto& note(string note) { _note = note; return *this; }
auto text() const -> string;
natural _frequency;
string _note;
};
struct Heuristics { struct Heuristics {
auto memory(string type, uint size, string name) const -> string; auto memory(string type, uint size, string name, string metadata = {}) const -> string;
}; };
} }

View File

@ -21,10 +21,11 @@ auto MasterSystem::manifest() const -> string {
string output; string output;
output.append("game\n"); output.append("game\n");
output.append(" sha256: ", Hash::SHA256(data).digest(), "\n"); output.append(" sha256: ", Hash::SHA256(data).digest(), "\n");
output.append(" name: ", Location::prefix(location), "\n");
output.append(" label: ", Location::prefix(location), "\n"); output.append(" label: ", Location::prefix(location), "\n");
output.append(memory("ROM", data.size(), "program.rom")); output.append(" name: ", Location::prefix(location), "\n");
output.append(memory("NVRAM", 0x8000, "save.ram")); output.append(" board\n");
output.append(Memory{}.type("ROM").size(data.size()).category("Program").text());
output.append(Memory{}.type("RAM").size(0x8000).category("Save").battery().text());
return output; return output;
} }

View File

@ -71,12 +71,13 @@ auto MegaDrive::manifest() const -> string {
string output; string output;
output.append("game\n"); output.append("game\n");
output.append(" sha256: ", Hash::SHA256(data).digest(), "\n"); output.append(" sha256: ", Hash::SHA256(data).digest(), "\n");
output.append(" name: ", Location::prefix(location), "\n");
output.append(" label: ", Location::prefix(location), "\n"); output.append(" label: ", Location::prefix(location), "\n");
output.append(" name: ", Location::prefix(location), "\n");
output.append(" region: ", regions.left(), "\n"); output.append(" region: ", regions.left(), "\n");
output.append(memory("ROM", data.size(), "program.rom")); output.append(" board\n");
output.append(Memory{}.type("ROM").size(data.size()).category("Program").text());
if(ramSize && ramMode != "none") { if(ramSize && ramMode != "none") {
output.append(memory("NVRAM", ramSize, "save.ram")); output.append(Memory{}.type("RAM").size(ramSize).category("Save").text());
output.append(" mode: ", ramMode, "\n"); output.append(" mode: ", ramMode, "\n");
output.append(" offset: 0x", hex(ramFrom), "\n"); output.append(" offset: 0x", hex(ramFrom), "\n");
} }

View File

@ -26,9 +26,10 @@ auto PCEngine::manifest() const -> string {
string output; string output;
output.append("game\n"); output.append("game\n");
output.append(" sha256: ", Hash::SHA256(data).digest(), "\n"); output.append(" sha256: ", Hash::SHA256(data).digest(), "\n");
output.append(" name: ", Location::prefix(location), "\n");
output.append(" label:", Location::prefix(location), "\n"); output.append(" label:", Location::prefix(location), "\n");
output.append(memory("ROM", data.size(), "program.rom")); output.append(" name: ", Location::prefix(location), "\n");
output.append(" board\n");
output.append(Memory{}.type("ROM").size(data.size()).category("Program").text());
return output; return output;
} }

View File

@ -27,10 +27,12 @@ auto SufamiTurbo::manifest() const -> string {
string output; string output;
output.append("game\n"); output.append("game\n");
output.append(" sha256: ", Hash::SHA256(data).digest(), "\n"); output.append(" sha256: ", Hash::SHA256(data).digest(), "\n");
output.append(" name: ", Location::prefix(location), "\n");
output.append(" label: ", Location::prefix(location), "\n"); output.append(" label: ", Location::prefix(location), "\n");
output.append(memory("ROM", data.size(), "program.rom")); output.append(" name: ", Location::prefix(location), "\n");
if(ramSize) output.append(memory("NVRAM", ramSize, "save.ram")); output.append(" board\n");
output.append(Memory{}.type("ROM").size(data.size()).category("Program").text());
if(ramSize)
output.append(Memory{}.type("RAM").size(ramSize).category("Save").battery().text());
return output; return output;
} }

View File

@ -58,65 +58,65 @@ auto SuperFamicom::manifest() const -> string {
string output; string output;
output.append("game\n"); output.append("game\n");
output.append(" sha256: ", Hash::SHA256(data).digest(), "\n"); output.append(" sha256: ", Hash::SHA256(data).digest(), "\n");
output.append(" label: ", label(), "\n");
output.append(" name: ", Location::prefix(location), "\n");
output.append(" region: ", region(), "\n"); output.append(" region: ", region(), "\n");
output.append(" revision: ", revision(), "\n"); output.append(" revision: ", revision(), "\n");
output.append(" board: ", board(), "\n"); output.append(" board: ", board(), "\n");
output.append(" name: ", Location::prefix(location), "\n");
output.append(" label: ", label(), "\n");
auto board = this->board().split("-"); auto board = this->board().split("-");
if(board.left() == "ARM") { if(auto size = romSize()) {
output.append(memory("ROM", size() - 0x28000, "program.rom")); if(board(0) == "SPC7110") size = 0x100000;
output.append(memory("ROM", 0x20000, {firmwareARM(), ".program.rom"})); output.append(Memory{}.type("ROM").size(size).category("Program").text());
output.append(memory("ROM", 0x8000, {firmwareARM(), ".data.rom"}));
} else if(board.left() == "HITACHI") {
output.append(memory("ROM", size() - 0xc00, "program.rom"));
output.append(memory("ROM", 0xc00, {firmwareHITACHI(), ".data.rom"}));
} else if(board.left() == "NEC") {
output.append(memory("ROM", size() - 0x2000, "program.rom"));
output.append(memory("ROM", 0x1800, {firmwareNEC(), ".program.rom"}));
output.append(memory("ROM", 0x800, {firmwareNEC(), ".data.rom"}));
} else if(board.left() == "NECEX") {
output.append(memory("ROM", size() - 0xd000, "program.rom"));
output.append(memory("ROM", 0xc000, {firmwareNECEX(), ".program.rom"}));
output.append(memory("ROM", 0x1000, {firmwareNECEX(), ".data.rom"}));
} else if(board.left() == "SGB") {
output.append(memory("ROM", size() - 0x100, "program.rom"));
output.append(memory("ROM", 0x100, {firmwareSGB(), ".boot.rom"}));
} else if(board.left() == "SPC7110") {
output.append(memory("ROM", 0x100000, "program.rom"));
output.append(memory("ROM", size() - 0x100000, "data.rom"));
} else {
output.append(memory("ROM", size(), "program.rom"));
} }
if(auto size = ramSize()) { if(auto size = ramSize()) {
auto type = battery() ? "NVRAM" : "RAM"; output.append(Memory{}.type("RAM").size(size).category("Save").battery(battery()).text());
output.append(memory(type, size, "save.ram"));
} }
if(auto size = expansionRamSize()) { if(auto size = expansionRamSize()) {
auto type = battery() ? "NVRAM" : "RAM"; output.append(Memory{}.type("RAM").size(size).category("Expansion").battery(battery()).text());
output.append(memory(type, size, "expansion.ram"));
} }
if(board.left() == "ARM") { if(0) {
output.append(memory("NVRAM", 0x4000, {firmwareARM(), ".data.ram"})); } else if(board(0) == "ARM") {
} else if(board.left() == "BS" && board(1) == "MCC") { output.append(Memory{}.type("ROM").size(0x20000).manufacturer("SETA").part("ARM").category("Program").text());
output.append(memory("PSRAM", 0x80000, "download.ram")); output.append(Memory{}.type("ROM").size( 0x8000).manufacturer("SETA").part("ARM").category("Data").text());
} else if(board.left() == "HITACHI") { output.append(Memory{}.type("RAM").size( 0x4000).manufacturer("SETA").part("ARM").category("Data").text());
output.append(memory("RAM", 0xc00, {firmwareHITACHI(), ".data.ram"})); output.append(Oscillator{}.frequency(21'440'000).text());
} else if(board.left() == "NEC") { } else if(board(0) == "BS" && board(1) == "MCC") {
output.append(memory("RAM", 0x200, {firmwareNEC(), ".data.ram"})); output.append(Memory{}.type("RAM").size(0x80000).category("Download").battery().text());
} else if(board.left() == "NECEX") { output.append(Memory{}.type("RTC").size(0x10).category("Time").text());
output.append(memory("NVRAM", 0x1000, {firmwareNEC(), ".data.ram"})); } else if(board(0) == "HITACHI") {
} else if(board.left() == "RTC") { output.append(Memory{}.type("ROM").size(0xc00).manufacturer("Hitachi").part("HG51BS169").category("Data").note(firmwareHITACHI()).text());
output.append(memory("NVRAM", 0x10, "sharp.rtc.ram")); output.append(Memory{}.type("RAM").size(0xc00).manufacturer("Hitachi").part("HG51BS169").category("Data").note(firmwareHITACHI()).text());
} else if(board.left() == "SA1") { output.append(Oscillator{}.frequency(20'000'000).text());
output.append(memory("RAM", 0x800, "internal.ram")); } else if(board(0) == "NEC") {
} else if(board.left() == "SPC7110" && board(1) == "RTC") { output.append(Memory{}.type("ROM").size(0x1800).manufacturer("NEC").part("uPD7725").category("Program").note(firmwareNEC()).text());
output.append(memory("NVRAM", 0x10, "epson.rtc.ram")); output.append(Memory{}.type("ROM").size( 0x800).manufacturer("NEC").part("uPD7725").category("Data").note(firmwareNEC()).text());
output.append(Memory{}.type("RAM").size( 0x200).manufacturer("NEC").part("uPD7725").category("Data").note(firmwareNEC()).text());
output.append(Oscillator{}.frequency(7'600'000).text());
} else if(board(0) == "NECEX") {
output.append(Memory{}.type("ROM").size(0xc000).manufacturer("NEC").part("uPD96050").category("Program").note(firmwareNECEX()).text());
output.append(Memory{}.type("ROM").size(0x1000).manufacturer("NEC").part("uPD96050").category("Data").note(firmwareNECEX()).text());
output.append(Memory{}.type("RAM").size(0x1000).manufacturer("NEC").part("uPD96050").category("Data").note(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).category("Time").battery().text());
} else if(board(0) == "SA1") {
output.append(Memory{}.type("RAM").size(0x800).category("Internal").text());
} else if(board(0) == "SGB") {
output.append(Memory{}.type("ROM").size(0x100).manufacturer("Nintendo").part("SGB").category("Boot").note(firmwareSGB()).text());
if(firmwareSGB() == "SGB2")
output.append(Oscillator{}.frequency(20'971'520).text());
} else if(board(0) == "SPC7110") {
output.append(Memory{}.type("ROM").size(romSize() - 0x100000).category("Data").text());
if(board(1) == "RTC")
output.append(Memory{}.type("RTC").size(0x10).category("Time").battery().text());
} else if(board(0) == "SUPERFX") {
//todo: MARIO CHIP 1 uses CPU oscillator
output.append(Oscillator{}.frequency(21'440'000).text());
} }
return output; return output;
@ -151,20 +151,20 @@ auto SuperFamicom::region() const -> string {
} }
if(!region) { if(!region) {
if(E == 0x00) region = {"SHVC-JPN"}; if(E == 0x00) region = {"JPN"};
if(E == 0x01) region = { "SNS-USA"}; if(E == 0x01) region = {"USA"};
if(E == 0x02) region = {"SNSP-EUR"}; if(E == 0x02) region = {"EUR"};
if(E == 0x03) region = {"SNSP-SCN"}; if(E == 0x03) region = {"SCN"};
if(E == 0x06) region = {"SNSP-FRA"}; if(E == 0x06) region = {"FRA"};
if(E == 0x07) region = {"SNSP-HOL"}; if(E == 0x07) region = {"HOL"};
if(E == 0x08) region = {"SNSP-ESP"}; if(E == 0x08) region = {"ESP"};
if(E == 0x09) region = {"SNSP-NOE"}; if(E == 0x09) region = {"NOE"};
if(E == 0x0a) region = {"SNSP-ITA"}; if(E == 0x0a) region = {"ITA"};
if(E == 0x0b) region = {"SNSP-ROC"}; if(E == 0x0b) region = {"ROC"};
if(E == 0x0d) region = {"SNSP-KOR"}; if(E == 0x0d) region = {"KOR"};
if(E == 0x0f) region = { "SNS-CAN"}; if(E == 0x0f) region = {"CAN"};
if(E == 0x10) region = { "SNS-BRA"}; if(E == 0x10) region = {"BRA"};
if(E == 0x11) region = {"SNSP-AUS"}; if(E == 0x11) region = {"AUS"};
} }
return region ? region : "NTSC"; return region ? region : "NTSC";
@ -200,20 +200,7 @@ auto SuperFamicom::revision() const -> string {
} }
if(!revision) { if(!revision) {
if(E == 0x00) revision = {"SHVC-", F}; revision = {"1.", F};
if(E == 0x01) revision = { "SNS-", F};
if(E == 0x02) revision = {"SNSP-", F};
if(E == 0x03) revision = {"SSWE-", F};
if(E == 0x06) revision = {"SFRA-", F};
if(E == 0x07) revision = {"SHOL-", F};
if(E == 0x08) revision = {"SESP-", F};
if(E == 0x09) revision = {"SFRG-", F};
if(E == 0x0a) revision = {"SITA-", F};
if(E == 0x0b) revision = {"SSCN-", F};
if(E == 0x0d) revision = {"SKOR-", F};
if(E == 0x0f) revision = { "SNS-", F};
if(E == 0x10) revision = {"SBRA-", F};
if(E == 0x11) revision = {"SNSP-", F};
} }
return revision ? revision : string{"1.", F}; return revision ? revision : string{"1.", F};
@ -410,9 +397,6 @@ auto SuperFamicom::romSize() const -> uint {
if((size() & 0xffff) == 0xd000) return size() - 0xd000; if((size() & 0xffff) == 0xd000) return size() - 0xd000;
if((size() & 0x3ffff) == 0x28000) return size() - 0x28000; if((size() & 0x3ffff) == 0x28000) return size() - 0x28000;
return size(); return size();
//auto romSize = data[headerAddress + 0x27] & 15;
//return 1024 << romSize;
} }
auto SuperFamicom::ramSize() const -> uint { auto SuperFamicom::ramSize() const -> uint {
@ -494,33 +478,33 @@ auto SuperFamicom::scoreHeader(uint address) -> uint {
} }
auto SuperFamicom::firmwareARM() const -> string { auto SuperFamicom::firmwareARM() const -> string {
return "st018"; return "ST018";
} }
auto SuperFamicom::firmwareHITACHI() const -> string { auto SuperFamicom::firmwareHITACHI() const -> string {
return "cx4"; return "Cx4";
} }
auto SuperFamicom::firmwareNEC() const -> string { auto SuperFamicom::firmwareNEC() const -> string {
if(label() == "PILOTWINGS") return "dsp1"; if(label() == "PILOTWINGS") return "DSP1";
if(label() == "DUNGEON MASTER") return "dsp2"; if(label() == "DUNGEON MASTER") return "DSP2";
if(label() == "SDガンダムGX") return "dsp3"; if(label() == "SDガンダムGX") return "DSP3";
if(label() == "PLANETS CHAMP TG3000") return "dsp4"; if(label() == "PLANETS CHAMP TG3000") return "DSP4";
if(label() == "TOP GEAR 3000") return "dsp4"; if(label() == "TOP GEAR 3000") return "DSP4";
return "dsp1b"; return "DSP1B";
} }
auto SuperFamicom::firmwareNECEX() const -> string { auto SuperFamicom::firmwareNECEX() const -> string {
if(label() == "EXHAUST HEAT2") return "st010"; if(label() == "EXHAUST HEAT2") return "ST010";
if(label() == "F1 ROC II") return "st010"; if(label() == "F1 ROC II") return "ST010";
if(label() == "2DAN MORITA SHOUGI") return "st011"; if(label() == "2DAN MORITA SHOUGI") return "ST011";
return "st010"; return "ST010";
} }
auto SuperFamicom::firmwareSGB() const -> string { auto SuperFamicom::firmwareSGB() const -> string {
if(label() == "Super GAMEBOY") return "sgb1"; if(label() == "Super GAMEBOY") return "SGB1";
if(label() == "Super GAMEBOY2") return "sgb2"; if(label() == "Super GAMEBOY2") return "SGB2";
return "sgb1"; return "SGB1";
} }
} }

View File

@ -21,9 +21,10 @@ auto SuperGrafx::manifest() const -> string {
string output; string output;
output.append("game\n"); output.append("game\n");
output.append(" sha256: ", Hash::SHA256(data).digest(), "\n"); output.append(" sha256: ", Hash::SHA256(data).digest(), "\n");
output.append(" name: ", Location::prefix(location), "\n");
output.append(" label: ", Location::prefix(location), "\n"); output.append(" label: ", Location::prefix(location), "\n");
output.append(memory("ROM", data.size(), "program.rom")); output.append(" name: ", Location::prefix(location), "\n");
output.append(" board\n");
output.append(Memory{}.type("ROM").size(data.size()).category("Program").text());
return output; return output;
} }

View File

@ -27,11 +27,11 @@ auto WonderSwan::manifest() const -> string {
string ramType; string ramType;
uint ramSize = 0; uint ramSize = 0;
switch(metadata[11]) { switch(metadata[11]) {
case 0x01: ramType = "NVRAM"; ramSize = 8 * 1024; break; case 0x01: ramType = "RAM"; ramSize = 8 * 1024; break;
case 0x02: ramType = "NVRAM"; ramSize = 32 * 1024; break; case 0x02: ramType = "RAM"; ramSize = 32 * 1024; break;
case 0x03: ramType = "NVRAM"; ramSize = 128 * 1024; break; case 0x03: ramType = "RAM"; ramSize = 128 * 1024; break;
case 0x04: ramType = "NVRAM"; ramSize = 256 * 1024; break; case 0x04: ramType = "RAM"; ramSize = 256 * 1024; break;
case 0x05: ramType = "NVRAM"; ramSize = 512 * 1024; break; case 0x05: ramType = "RAM"; ramSize = 512 * 1024; break;
case 0x10: ramType = "EEPROM"; ramSize = 128; break; case 0x10: ramType = "EEPROM"; ramSize = 128; break;
case 0x20: ramType = "EEPROM"; ramSize = 2048; break; case 0x20: ramType = "EEPROM"; ramSize = 2048; break;
case 0x50: ramType = "EEPROM"; ramSize = 1024; break; case 0x50: ramType = "EEPROM"; ramSize = 1024; break;
@ -43,12 +43,15 @@ auto WonderSwan::manifest() const -> string {
string output; string output;
output.append("game\n"); output.append("game\n");
output.append(" sha256: ", Hash::SHA256(data).digest(), "\n"); output.append(" sha256: ", Hash::SHA256(data).digest(), "\n");
output.append(" name: ", Location::prefix(location), "\n");
output.append(" label: ", Location::prefix(location), "\n"); output.append(" label: ", Location::prefix(location), "\n");
output.append(" name: ", Location::prefix(location), "\n");
output.append(" orientation: ", !orientation ? "horizontal" : "vertical", "\n"); output.append(" orientation: ", !orientation ? "horizontal" : "vertical", "\n");
output.append(memory("ROM", data.size(), "program.rom")); output.append(" board\n");
if(ramType && ramSize) output.append(memory(ramType, ramSize, "save.ram")); output.append(Memory{}.type("ROM").size(data.size()).category("Program").text());
if(hasRTC) output.append(memory("NVRAM", 16, "rtc.ram")); if(ramType && ramSize)
output.append(Memory{}.type(ramType).size(ramSize).category("Save").battery(ramType == "RAM").text());
if(hasRTC)
output.append(Memory{}.type("RTC").size(0x10).category("Time").text());
return output; return output;
} }