Update to v091r13 release, and ananke v00r01.

byuu says (about higan):

- dropped release/ root node for individual games (still there in
  ananke's database.)
- Memory export uses smarter names (vram.rwm -> video.ram, etc.)
- cheat database moved from XML to BML (3.1MB to 1.9MB file size.)
- cheat codes moved from XML to BML
- resource manifest moved from XML to BML

What can I say, I like consistency. But I'll leave the shaders alone
until I get around to shader folders.

byuu says (about ananke):

Works with higan v091r13. Only does SNES stuff so far.
This commit is contained in:
Tim Allen 2012-11-22 21:28:01 +11:00
parent 84e98833ca
commit 019fc1a2c6
28 changed files with 86622 additions and 107258 deletions

View File

@ -1,79 +1,63 @@
#include <nall/nall.hpp>
#include <nall/beat/patch.hpp>
#include <nall/emulation/super-famicom.hpp>
using namespace nall;
#include <phoenix/phoenix.hpp>
using namespace phoenix;
struct Ananke {
struct Configuration : configuration {
string path;
#include "configuration.cpp"
Configuration() {
append(path = userpath(), "Path");
directory::create({configpath(), "ananke/"});
load({configpath(), "ananke/settings.cfg"});
}
struct Information {
string path; //path to selected file
string name; //name of selected file (inside of archive if .zip)
string archive; //pathname of archive
string manifest; //manifest from successfully applied patch
} information;
~Configuration() {
save({configpath(), "ananke/settings.cfg"});
}
} config;
//archive.cpp
vector<uint8_t> extractROM();
vector<uint8_t> extractFile(const string &filename);
string createSuperFamicomDatabase(const string &filename, Markup::Node &document, const string &manifest) {
string pathname = {
userpath(), "Emulation/Super Famicom/",
document["release/information/name"].text(),
" (", document["release/information/region"].text(), ")",
" (", document["release/information/revision"].text(), ")",
".sfc/"
};
directory::create(pathname);
//patch.cpp
void applyBeatPatch(vector<uint8_t> &buffer);
file::write({pathname, "manifest.bml"}, (const uint8_t*)(const char*)manifest, manifest.length());
auto buffer = file::read(filename);
unsigned offset = 0;
for(auto &node : document["release/information/configuration"]) {
if(node.name != "rom") continue;
string name = node["name"].text();
unsigned size = node["size"].decimal();
if(file::exists({pathname, name}) == false) {
file::write({pathname, name}, buffer.data() + offset, size);
}
offset += size;
}
return pathname;
}
string openSuperFamicom(const string &filename) {
string sha256 = file::sha256(filename);
string databaseText = string::read({configpath(), "ananke/database/Super Famicom.bml"}).rtrim("\n");
lstring databaseItem = databaseText.split("\n\n");
for(auto &item : databaseItem) {
item.append("\n");
auto document = Markup::Document(item);
if(document["release/information/sha256"].text() == sha256) {
return createSuperFamicomDatabase(filename, document, item);
}
}
return "";
}
//super-famicom.cpp
string createSuperFamicomDatabase(vector<uint8_t> &buffer, Markup::Node &document, const string &manifest);
string createSuperFamicomHeuristic(vector<uint8_t> &buffer);
string openSuperFamicom(vector<uint8_t> &buffer);
string open(string filename = "") {
if(filename.empty()) filename = DialogWindow::fileOpen(Window::none(), config.path);
if(filename.empty()) return "";
config.path = dir(filename);
if(filename.endswith(".sfc")) return openSuperFamicom(filename);
information.path = dir(filename);
information.name = notdir(filename);
config.path = information.path; //remember last used directory
vector<uint8_t> buffer;
if(filename.endswith(".zip")) {
information.archive = filename;
buffer = extractROM();
} else {
buffer = file::read(filename);
}
if(buffer.size() == 0) return ""; //failed to read file
applyBeatPatch(buffer);
if(information.name.endswith(".sfc")) return openSuperFamicom(buffer);
return "";
}
};
#include "archive.cpp"
#include "patch.cpp"
#include "super-famicom.cpp"
extern "C" string ananke_browse(const string &filename) {
Ananke ananke;
return ananke.open();

24
ananke/archive.cpp Normal file
View File

@ -0,0 +1,24 @@
vector<uint8_t> Ananke::extractROM() {
unzip archive;
if(archive.open(information.archive)) {
for(auto &file : archive.file) {
if(file.name.endswith(".sfc")) {
information.name = notdir(file.name);
return archive.extract(file);
}
}
}
return vector<uint8_t>();
}
vector<uint8_t> Ananke::extractFile(const string &filename) {
unzip archive;
if(archive.open(information.archive)) {
for(auto &file : archive.file) {
if(notdir(file.name) == filename) {
return archive.extract(file);
}
}
}
return vector<uint8_t>();
}

13
ananke/configuration.cpp Normal file
View File

@ -0,0 +1,13 @@
struct Configuration : configuration {
string path;
Configuration() {
append(path = userpath(), "Path");
directory::create({configpath(), "ananke/"});
load({configpath(), "ananke/settings.cfg"});
}
~Configuration() {
save({configpath(), "ananke/settings.cfg"});
}
} config;

File diff suppressed because it is too large Load Diff

View File

@ -119,359 +119,298 @@ SuperFamicomCartridge::SuperFamicomCartridge(const uint8_t *data, unsigned size)
if(type == TypeBsx) return;
if(type == TypeSufamiTurbo) return;
markup.append("<?xml version='1.0' encoding='UTF-8'?>\n");
const char *range = (rom_size > 0x200000) || (ram_size > 32 * 1024) ? "0000-7fff" : "0000-ffff";
markup.append("<cartridge region='", region == NTSC ? "NTSC" : "PAL", "'>\n");
markup.append("cartridge region=", region == NTSC ? "NTSC" : "PAL", "\n");
if(type == TypeSuperGameBoy1Bios || type == TypeSuperGameBoy2Bios) markup.append(
" <rom name='program.rom' size='0x", hex(rom_size), "'/>\n"
" <map address='00-7f:8000-ffff' id='rom' mode='linear'/>\n"
" <map address='80-ff:8000-ffff' id='rom' mode='linear'/>\n"
" <icd2 revision='1'>\n"
" <firmware name='boot.rom' size='256' sha256='0e4ddff32fc9d1eeaae812a157dd246459b00c9e14f2f61751f661f32361e360'/>\n"
" <map address='00-3f:6000-7fff' id='io'/>\n"
" <map address='80-bf:6000-7fff' id='io'/>\n"
" </icd2>\n"
" rom name=program.rom size=0x", hex(rom_size), "\n"
" map id=rom address=00-7f,80-ff:8000-ffff\n"
" icd2 revision=1\n"
" rom name=boot.rom size=0x100\n"
" map id=io address=00-3f,80-bf:6000-7fff\n"
);
else if(has_cx4) markup.append(
" <hitachidsp model='HG51B169' frequency='20000000'>\n"
" <firmware name='cx4.rom' size='3072' sha256='ae8d4d1961b93421ff00b3caa1d0f0ce7783e749772a3369c36b3dbf0d37ef18'/>\n"
" <rom name='program.rom' size='0x", hex(rom_size), "'/>\n"
" <map address='00-3f:6000-7fff' id='io'/>\n"
" <map address='80-bf:6000-7fff' id='io'/>\n"
" <map address='00-7f:8000-ffff' id='rom' mode='linear'/>\n"
" <map address='80-ff:8000-ffff' id='rom' mode='linear'/>\n"
" </hitachidsp>\n"
" hitachidsp model=HG51B169 frequency=20000000\n"
" rom id=program name=program.rom size=0x", hex(rom_size), "\n"
" rom id=data name=cx4.data.rom size=0xc00\n"
" ram id=data size=0xc00\n"
" map id=io address=00-3f,80-bf:6000-7fff\n"
" map id=rom address=00-7f,80-ff:8000-ffff mask=0x8000\n"
" map id=ram address=70-77:0000-7fff\n"
);
else if(has_spc7110) markup.append(
" <spc7110>\n"
" <prom name='program.rom' size='0x100000'/>\n"
" <drom name='data.rom' size='0x", hex(rom_size - 0x100000), "'/>\n"
" <ram name='save.rwm' size='0x2000'/>\n"
" <map address='00-3f:4800-483f' id='io'/>\n"
" <map address='80-bf:4800-483f' id='io'/>\n"
" <map address='50:0000-ffff' id='io'/>\n"
" <map address='00-3f:8000-ffff' id='rom'/>\n"
" <map address='80-bf:8000-ffff' id='rom'/>\n"
" <map address='c0-ff:0000-ffff' id='rom'/>\n"
" <map address='00-3f:6000-7fff' id='ram'/>\n"
" <map address='80-bf:6000-7fff' id='ram'/>\n"
" </spc7110>\n"
" spc7110\n"
" rom id=program name=program.rom size=0x100000\n"
" rom id=data name=data.rom size=0x", hex(rom_size - 0x100000), "\n"
" ram name=save.ram size=0x", hex(ram_size), "\n"
" map id=io address=00-3f,80-bf:4800-483f\n"
" map id=io address=50:0000-ffff\n"
" map id=rom address=00-3f,80-bf:8000-ffff\n"
" map id=rom address=c0-ff:0000-ffff\n"
" map id=ram address=00-3f,80-bf:6000-7fff mask=0xe000\n"
);
else if(has_sdd1) markup.append(
" <sdd1>\n"
" <rom name='program.rom' size='0x", hex(rom_size), "'/>\n"
" <ram name='save.rwm' size='0x", hex(ram_size), "'/>\n"
" <map address='00-3f:4800-4807' id='io'/>\n"
" <map address='80-bf:4800-4807' id='io'/>\n"
" <map address='00-3f:8000-ffff' id='rom'/>\n"
" <map address='80-bf:8000-ffff' id='rom'/>\n"
" <map address='40-7f:0000-ffff' id='rom'/>\n"
" <map address='c0-ff:0000-ffff' id='rom'/>\n"
" <map address='20-3f:6000-7fff' id='ram'/>\n"
" <map address='a0-bf:6000-7fff' id='ram'/>\n"
" <map address='70-7f:0000-7fff' id='ram'/>\n"
" </sdd1>\n"
);
else if(has_sdd1) {
markup.append(
" sdd1\n"
" rom name=program.rom size=0x", hex(rom_size), "\n"
);
if(ram_size > 0) markup.append(
" ram name=save.ram size=0x", hex(ram_size), "\n"
);
markup.append(
" map id=io address=00-3f,80-bf:4800-4807\n"
" map id=rom address=00-3f,80-bf:8000-ffff mask=0x8000\n"
" map id=rom address=c0-ff:0000-ffff\n"
);
if(ram_size > 0) markup.append(
" map id=ram address=20-3f,a0-bf:6000-7fff mask=0xe000\n"
" map id=ram address=70-7f:0000-7fff\n"
);
}
else if(mapper == LoROM) {
markup.append(
" <rom name='program.rom' size='0x", hex(rom_size), "'/>\n"
" <map address='00-7f:8000-ffff' id='rom' mode='linear'/>\n"
" <map address='80-ff:8000-ffff' id='rom' mode='linear'/>\n"
" rom name=program.rom size=0x", hex(rom_size), "\n"
);
if(ram_size > 0) markup.append(
" <ram name='save.rwm' size='0x", hex(ram_size), "'/>\n"
" <map address='20-3f:6000-7fff' id='ram' mode='linear'/>\n"
" <map address='a0-bf:6000-7fff' id='ram' mode='linear'/>\n"
" <map address='70-7f:", range, "' id='ram' mode='linear'/>\n"
" <map address='f0-ff:", range, "' id='ram' mode='linear'/>\n"
" ram name=save.ram size=0x", hex(ram_size), "\n"
);
markup.append(
" map id=rom address=00-7f,80-ff:8000-ffff mask=0x8000\n"
);
if(ram_size > 0) markup.append(
" map id=ram address=70-7f,f0-ff:", range, "\n"
);
}
else if(mapper == HiROM) {
markup.append(
" <rom name='program.rom' size='0x", hex(rom_size), "'/>\n"
" <map address='00-3f:8000-ffff' id='rom' mode='shadow'/>\n"
" <map address='80-bf:8000-ffff' id='rom' mode='shadow'/>\n"
" <map address='40-7f:0000-ffff' id='rom' mode='linear'/>\n"
" <map address='c0-ff:0000-ffff' id='rom' mode='linear'/>\n"
" rom name=program.rom size=0x", hex(rom_size), "\n"
);
if(ram_size > 0) markup.append(
" <ram name='save.rwm' size='0x", hex(ram_size), "'/>\n"
" <map address='20-3f:6000-7fff' id='ram' mode='linear'/>\n"
" <map address='a0-bf:6000-7fff' id='ram' mode='linear'/>\n"
" <map address='70-7f:", range, "' id='ram' mode='linear'/>\n"
" ram name=save.ram size=0x", hex(ram_size), "\n"
);
markup.append(
" map id=rom address=00-3f,80-bf:8000-ffff\n"
" map id=rom address=40-7f,c0-ff:0000-ffff\n"
);
if(ram_size > 0) markup.append(
" map id=ram address=10-3f,90-bf:6000-7fff mask=0xe000\n"
);
}
else if(mapper == ExLoROM) {
markup.append(
" <rom name='program.rom' size='0x", hex(rom_size), "'/>\n"
" <map address='00-3f:8000-ffff' id='rom' mode='linear'/>\n"
" <map address='80-bf:8000-ffff' id='rom' mode='linear'/>\n"
" <map address='40-7f:0000-ffff' id='rom' mode='linear'/>\n"
" rom name=program.rom size=0x", hex(rom_size), "\n"
);
if(ram_size > 0) markup.append(
" <ram name='save.rwm' size='0x", hex(ram_size), "'/>\n"
" <map address='20-3f:6000-7fff' id='ram' mode='linear'/>\n"
" <map address='a0-bf:6000-7fff' id='ram' mode='linear'/>\n"
" <map address='70-7f:0000-7fff' id='ram' mode='linear'/>\n"
" ram name=save.ram size=0x", hex(ram_size), "\n"
);
markup.append(
" map id=rom address=00-3f,80-bf:8000-ffff mask=0x8000\n"
" map id=rom address=40-7f:0000-ffff\n"
);
if(ram_size > 0) markup.append(
" map id=ram address=20-3f,a0-bf:6000-7fff\n"
" map id=ram address=70-7f:0000-7fff\n"
);
}
else if(mapper == ExHiROM) {
markup.append(
" <rom name='program.rom' size='0x", hex(rom_size), "'/>\n"
" <map address='00-3f:8000-ffff' id='rom' mode='shadow' offset='0x400000'/>\n"
" <map address='80-bf:8000-ffff' id='rom' mode='shadow' offset='0x000000'/>\n"
" <map address='40-7f:0000-ffff' id='rom' mode='linear' offset='0x400000'/>\n"
" <map address='c0-ff:0000-ffff' id='rom' mode='linear' offset='0x000000'/>\n"
" rom name=program.rom size=0x", hex(rom_size), "\n"
);
if(ram_size > 0) markup.append(
" <ram name='save.rwm' size='0x", hex(ram_size), "'/>\n"
" <map address='20-3f:6000-7fff' id='ram' mode='linear'/>\n"
" <map address='a0-bf:6000-7fff' id='ram' mode='linear'/>\n"
" <map address='70-7f:", range, "' id='ram' mode='linear'/>\n"
" ram name=save.ram size=0x", hex(ram_size), "\n"
);
markup.append(
" map id=rom address=00-3f:8000-ffff offset=0x400000\n"
" map id=rom address=40-7f:0000-ffff offset=0x400000\n"
" map id=rom address=80-bf:8000-ffff offset=0x000000\n"
" map id=rom address=c0-ff:0000-ffff offset=0x000000\n"
);
if(ram_size > 0) markup.append(
" map id=ram address=20-3f,a0-bf:6000-7fff mask=0xe000\n"
" map id=ram address=70-7f:", range, "\n"
);
}
else if(mapper == SuperFXROM) {
markup.append(
" <superfx revision='2'>\n"
" <map address='00-3f:3000-32ff' id='io'/>\n"
" <map address='80-bf:3000-32ff' id='io'/>\n"
" <rom name='program.rom' size='0x", hex(rom_size), "'/>\n"
" <map address='00-3f:8000-ffff' id='rom' mode='linear'/>\n"
" <map address='80-bf:8000-ffff' id='rom' mode='linear'/>\n"
" <map address='40-5f:0000-ffff' id='rom' mode='linear'/>\n"
" <map address='c0-df:0000-ffff' id='rom' mode='linear'/>\n"
" superfx revision=3\n"
" rom name=program.rom size=0x", hex(rom_size), "\n"
);
if(ram_size > 0) markup.append(
" <ram name='save.rwm' size='0x", hex(ram_size), "'/>\n"
" <map address='00-3f:6000-7fff' id='ram' mode='linear' size='0x2000'/>\n"
" <map address='80-bf:6000-7fff' id='ram' mode='linear' size='0x2000'/>\n"
" <map address='60-7f:0000-ffff' id='ram' mode='linear'/>\n"
" <map address='e0-ff:0000-ffff' id='ram' mode='linear'/>\n"
" ram name=save.ram size=0x", hex(ram_size), "\n"
);
markup.append(
" </superfx>\n"
" map id=io address=00-3f,80-bf:3000-32ff\n"
" map id=rom address=00-3f,80-bf:8000-ffff mask=0x8000\n"
" map id=rom address=40-5f,c0-df:0000-ffff\n"
);
if(ram_size > 0) markup.append(
" map id=ram address=00-3f,80-bf:6000-7fff size=0x2000\n"
" map id=ram address=70-71,f0-f1:0000-ffff\n"
);
}
else if(mapper == SA1ROM) {
markup.append(
" <sa1>\n"
" <map address='00-3f:2200-23ff' id='io'/>\n"
" <map address='80-bf:2200-23ff' id='io'/>\n"
" <rom name='program.rom' size='0x", hex(rom_size), "'/>\n"
" <map address='00-3f:8000-ffff' id='rom'/>\n"
" <map address='80-bf:8000-ffff' id='rom'/>\n"
" <map address='c0-ff:0000-ffff' id='rom'/>\n"
" <iram size='0x800'/>\n"
" <map address='00-3f:3000-37ff' id='iram'/>\n"
" <map address='80-bf:3000-37ff' id='iram'/>\n"
" sa1\n"
" rom name=program.rom size=0x", hex(rom_size), "\n"
);
if(ram_size > 0) markup.append(
" <bwram name='save.rwm' size='0x", hex(ram_size), "'/>\n"
" <map address='00-3f:6000-7fff' id='bwram'/>\n"
" <map address='80-bf:6000-7fff' id='bwram'/>\n"
" <map address='40-4f:0000-ffff' id='bwram'/>\n"
" ram id=bitmap name=save.ram size=0x", hex(ram_size), "\n"
);
markup.append(
" </sa1>\n"
" ram id=internal size=0x800\n"
" map id=io address=00-3f,80-bf:2200-23ff\n"
" map id=rom address=00-3f,80-bf:8000-ffff\n"
" map id=rom address=c0-ff:0000-ffff\n"
);
if(ram_size > 0) markup.append(
" map id=bwram address=00-3f,80-bf:6000-7fff\n"
" map id=bwram address=40-4f:0000-ffff\n"
);
markup.append(
" map id=iram address=00-3f,80-bf:3000-37ff\n"
);
}
else if(mapper == BSCLoROM) markup.append(
" <rom name='program.rom' size='0x", hex(rom_size), "'/>\n"
" <ram name='save.rwm' size='0x", hex(ram_size), "'/>\n"
" <map address='00-1f:8000-ffff' id='rom' mode='linear' offset='0x000000'/>\n"
" <map address='20-3f:8000-ffff' id='rom' mode='linear' offset='0x100000'/>\n"
" <map address='80-9f:8000-ffff' id='rom' mode='linear' offset='0x200000'/>\n"
" <map address='a0-bf:8000-ffff' id='rom' mode='linear' offset='0x100000'/>\n"
" <map address='70-7f:0000-7fff' id='ram' mode='linear'/>\n"
" <map address='f0-ff:0000-7fff' id='ram' mode='linear'/>\n"
" <bsxslot>\n"
" <map address='c0-ef:0000-ffff' id='rom' mode='linear'/>\n"
" </bsxslot>\n"
" rom name=program.rom size=0x", hex(rom_size), "\n"
" ram name=save.ram size=0x", hex(ram_size), "\n"
" map id=rom address=00-1f:8000-ffff offset=0x000000 mask=0x8000\n"
" map id=rom address=20-3f:8000-ffff offset=0x100000 mask=0x8000\n"
" map id=rom address=80-9f:8000-ffff offset=0x200000 mask=0x8000\n"
" map id=rom address=a0-bf:8000-ffff offset=0x100000 mask=0x8000\n"
" map id=ram address=70-7f,f0-ff:0000-7fff\n"
" bsxslot\n"
" map id=rom address=c0-ef:0000-ffff\n"
);
else if(mapper == BSCHiROM) markup.append(
" <rom name='program.rom' size='0x", hex(rom_size), "'/>\n"
" <ram name='save.rwm' size='0x", hex(ram_size), "'/>\n"
" <map address='00-1f:8000-ffff' id='rom' mode='shadow'/>\n"
" <map address='80-9f:8000-ffff' id='rom' mode='shadow'/>\n"
" <map address='40-5f:0000-ffff' id='rom' mode='linear'/>\n"
" <map address='c0-df:0000-ffff' id='rom' mode='linear'/>\n"
" <map address='20-3f:6000-7fff' id='ram' mode='linear'/>\n"
" <map address='a0-bf:6000-7fff' id='ram' mode='linear'/>\n"
" <bsxslot>\n"
" <map address='20-3f:8000-ffff' id='rom' mode='shadow'/>\n"
" <map address='a0-bf:8000-ffff' id='rom' mode='shadow'/>\n"
" <map address='60-7f:0000-ffff' id='rom' mode='linear'/>\n"
" <map address='e0-ff:0000-ffff' id='rom' mode='linear'/>\n"
" </bsxslot>\n"
" rom name=program.rom size=0x", hex(rom_size), "\n"
" ram name=save.ram size=0x", hex(ram_size), "\n"
" map id=rom address=00-1f,80-9f:8000-ffff\n"
" map id=rom address=40-5f,c0-df:0000-ffff\n"
" map id=ram address=20-3f,a0-bf:6000-7fff\n"
" bsxslot\n"
" map id=rom address=20-3f,a0-bf:8000-ffff\n"
" map id=rom address=60-7f,e0-ff:0000-ffff\n"
);
else if(mapper == BSXROM) markup.append(
" <bsx>\n"
" <rom name='program.rom' size='0x", hex(rom_size), "'/>\n"
" <ram name='save.rwm' size='0x", hex(ram_size), "'/>\n"
" <psram name='bsx.rwm' size='0x40000'/>\n"
" <map address='00-3f:5000-5fff' id='io'/>\n"
" <map address='80-bf:5000-5fff' id='io'/>\n"
" <map address='20-3f:6000-7fff' id='ram'/>\n"
" <map address='00-3f:8000-ffff' id='rom'/>\n"
" <map address='80-bf:8000-ffff' id='rom'/>\n"
" <map address='40-7f:0000-ffff' id='rom'/>\n"
" <map address='c0-ff:0000-ffff' id='rom'/>\n"
" </bsx>\n"
" bsx\n"
" rom name=program.rom size=0x", hex(rom_size), "\n"
" ram id=save name=save.ram size=0x", hex(ram_size), "\n"
" ram id=download name=bsx.ram size=0x40000\n"
" map id=io address=00-3f,80-bf:5000-5fff\n"
" map id=rom address=00-3f,80-bf:8000-ffff\n"
" map id=rom address=40-7f,c0-ff:0000-ffff\n"
" map id=ram address=20-3f:6000-7fff\n"
);
else if(mapper == STROM) markup.append(
" <rom name='program.rom' size='0x", hex(rom_size), "'/>\n"
" <map address='00-1f:8000-ffff' id='rom' mode='linear'/>\n"
" <map address='80-9f:8000-ffff' id='rom' mode='linear'/>\n"
" <sufamiturbo>\n"
" <slot id='A'>\n"
" <map address='20-3f:8000-ffff' id='rom' mode='linear'/>\n"
" <map address='a0-bf:8000-ffff' id='rom' mode='linear'/>\n"
" <map address='60-63:8000-ffff' id='ram' mode='linear'/>\n"
" <map address='e0-e3:8000-ffff' id='ram' mode='linear'/>\n"
" </slot>\n"
" <slot id='B'>\n"
" <map address='40-5f:8000-ffff' id='rom' mode='linear'/>\n"
" <map address='c0-df:8000-ffff' id='rom' mode='linear'/>\n"
" <map address='70-73:8000-ffff' id='ram' mode='linear'/>\n"
" <map address='f0-f3:8000-ffff' id='ram' mode='linear'/>\n"
" </slot>\n"
" </sufamiturbo>\n"
" rom name=program.rom size=0x", hex(rom_size), "\n"
" map id=rom address='00-1f,80-9f:8000-ffff mask=0x8000\n"
" sufamiturbo\n"
" slot id=A\n"
" map id=rom address=20-3f,a0-bf:8000-ffff mask=0x8000\n"
" map id=ram address=60-63,e0-e3:8000-ffff\n"
" slot id=B\n"
" map id=rom address=40-5f,c0-df:8000-ffff mask=0x8000\n"
" map id=ram address=70-73,f0-f3:8000-ffff\n"
);
if(has_spc7110rtc) markup.append(
" <epsonrtc>\n"
" <ram name='rtc.rwm' size='0x10'/>\n"
" <map address='00-3f:4840-4842' id='io'/>\n"
" <map address='80-bf:4840-4842' id='io'/>\n"
" </epsonrtc>\n"
" epsonrtc\n"
" ram name=rtc.ram size=0x10\n"
" map id=io address=00-3f,80-bf:4840-4842\n"
);
if(has_srtc) markup.append(
" <sharprtc>\n"
" <ram name='rtc.rwm' size='0x10'/>\n"
" <map address='00-3f:2800-2801' id='io'/>\n"
" <map address='80-bf:2800-2801' id='io'/>\n"
" </sharprtc>\n"
" sharprtc\n"
" ram name=rtc.ram size=0x10\n"
" map id=io address=00-3f,80-bf:2800-2801\n"
);
if(has_obc1) markup.append(
" <obc1>\n"
" <ram name='save.rwm' size='0x2000'/>\n"
" <map address='00-3f:6000-7fff' id='io'/>\n"
" <map address='80-bf:6000-7fff' id='io'/>\n"
" </obc1>\n"
" obc1\n"
" ram name=save.ram size=0x2000\n"
" map id=io address=00-3f,80-bf:6000-7fff\n"
);
if(has_dsp1) {
//91e87d11e1c30d172556bed2211cce2efa94ba595f58c5d264809ef4d363a97b dsp1.rom
markup.append(
" <necdsp model='uPD7725' frequency='8000000'>\n"
" <firmware name='dsp1b.rom' size='8192' sha256='d789cb3c36b05c0b23b6c6f23be7aa37c6e78b6ee9ceac8d2d2aa9d8c4d35fa9'/>\n"
" necdsp model=uPD7725 frequency=8000000\n"
" rom id=program name=dsp1b.program.rom size=0x1800\n"
" rom id=data name=dsp1b.data.rom size=0x800\n"
" ram id=data size=0x200\n"
);
if(dsp1_mapper == DSP1LoROM1MB) markup.append(
" <map address='20-3f:8000-bfff' id='dr'/>\n"
" <map address='a0-bf:8000-bfff' id='dr'/>\n"
" <map address='20-3f:c000-ffff' id='sr'/>\n"
" <map address='a0-bf:c000-ffff' id='sr'/>\n"
" map id=io address=20-3f,a0-bf:8000-ffff select=0x4000\n"
);
if(dsp1_mapper == DSP1LoROM2MB) markup.append(
" <map address='60-6f:0000-3fff' id='dr'/>\n"
" <map address='e0-ef:0000-3fff' id='dr'/>\n"
" <map address='60-6f:4000-7fff' id='sr'/>\n"
" <map address='e0-ef:4000-7fff' id='sr'/>\n"
" map id=io address=60-6f,e0-ef:0000-7fff select=0x4000\n"
);
if(dsp1_mapper == DSP1HiROM) markup.append(
" <map address='00-1f:6000-6fff' id='dr'/>\n"
" <map address='80-9f:6000-6fff' id='dr'/>\n"
" <map address='00-1f:7000-7fff' id='sr'/>\n"
" <map address='80-9f:7000-7fff' id='sr'/>\n"
);
markup.append(
" </necdsp>\n"
" map id=io address=00-1f,80-9f:6000-7fff select=0x1000\n"
);
}
if(has_dsp2) markup.append(
" <necdsp model='uPD7725' frequency='8000000'>\n"
" <firmware name='dsp2.rom' size='8192' sha256='03ef4ef26c9f701346708cb5d07847b5203cf1b0818bf2930acd34510ffdd717'/>\n"
" <map address='20-3f:8000-bfff' id='dr'/>\n"
" <map address='a0-bf:8000-bfff' id='dr'/>\n"
" <map address='20-3f:c000-ffff' id='sr'/>\n"
" <map address='a0-bf:c000-ffff' id='sr'/>\n"
" </necdsp>\n"
" necdsp model=uPD7725 frequency=8000000\n"
" rom id=program name=dsp2.program.rom size=0x1800\n"
" rom id=data name=dsp2.data.rom size=0x800\n"
" ram id=data size=0x200\n"
" map id=io address=20-3f,a0-bf:8000-ffff select=0x4000\n"
);
if(has_dsp3) markup.append(
" <necdsp model='uPD7725' frequency='8000000'>\n"
" <firmware name='dsp3.rom' size='8192' sha256='0971b08f396c32e61989d1067dddf8e4b14649d548b2188f7c541b03d7c69e4e'/>\n"
" <map address='20-3f:8000-bfff' id='dr'/>\n"
" <map address='a0-bf:8000-bfff' id='dr'/>\n"
" <map address='20-3f:c000-ffff' id='sr'/>\n"
" <map address='a0-bf:c000-ffff' id='sr'/>\n"
" </necdsp>\n"
" necdsp model=uPD7725 frequency=8000000\n"
" rom id=program name=dsp3.program.rom size=0x1800\n"
" rom id=data name=dsp3.data.rom size=0x800\n"
" ram id=data size=0x200\n"
" map id=io address=20-3f,a0-bf:8000-ffff select=0x4000\n"
);
if(has_dsp4) markup.append(
" <necdsp model='uPD7725' frequency='8000000'>\n"
" <firmware name='dsp4.rom' size='8192' sha256='752d03b2d74441e430b7f713001fa241f8bbcfc1a0d890ed4143f174dbe031da'/>\n"
" <map address='30-3f:8000-bfff' id='dr'/>\n"
" <map address='b0-bf:8000-bfff' id='dr'/>\n"
" <map address='30-3f:c000-ffff' id='sr'/>\n"
" <map address='b0-bf:c000-ffff' id='sr'/>\n"
" </necdsp>\n"
" necdsp model=uPD7725 frequency=8000000\n"
" rom id=program name=dsp4.program.rom size=0x1800\n"
" rom id=data name=dsp4.data.rom size=0x800\n"
" ram id=data size=0x200\n"
" map address=30-3f,b0-bf:8000-ffff select=0x4000\n"
);
if(has_st010) markup.append(
" <necdsp model='uPD96050' frequency='10000000'>\n"
" <firmware name='st010.rom' size='53248' sha256='fa9bced838fedea11c6f6ace33d1878024bdd0d02cc9485899d0bdd4015ec24c'/>\n"
" <ram name='save.rwm' size='0x1000'/>\n"
" <map address='60:0000' id='dr'/>\n"
" <map address='e0:0000' id='dr'/>\n"
" <map address='60:0001' id='sr'/>\n"
" <map address='e0:0001' id='sr'/>\n"
" <map address='68-6f:0000-0fff' id='ram'/>\n"
" <map address='e8-ef:0000-0fff' id='ram'/>\n"
" </necdsp>\n"
" necdsp model=uPD96050 frequency=11000000\n"
" rom id=program name=st010.program.rom size=0xc000\n"
" rom id=data name=st010.data.rom size=0x1000\n"
" ram id=data name=save.ram size=0x1000\n"
" map id=io address=60-67,e0-e7:0000-3fff select=0x0001\n"
" map id=ram address=68-6f,e8-ef:0000-7fff\n"
);
if(has_st011) markup.append(
" <necdsp model='uPD96050' frequency='15000000'>\n"
" <firmware name='st011.rom' size='53248' sha256='8b2b3f3f3e6e29f4d21d8bc736b400bc988b7d2214ebee15643f01c1fee2f364'/>\n"
" <ram name='save.rwm' size='0x1000'/>\n"
" <map address='60:0000' id='dr'/>\n"
" <map address='e0:0000' id='dr'/>\n"
" <map address='60:0001' id='sr'/>\n"
" <map address='e0:0001' id='sr'/>\n"
" <map address='68-6f:0000-0fff' id='ram'/>\n"
" <map address='e8-ef:0000-0fff' id='ram'/>\n"
" </necdsp>\n"
" necdsp model=uPD96050 frequency=15000000\n"
" rom id=program name=st011.program.rom size=0xc000\n"
" rom id=data name=st011.data.rom size=0x1000\n"
" ram id=data name=save.ram size=0x1000\n"
" map id=io address=60-67,e0-e7:0000-3fff select=0x0001\n"
" map id=ram address=68-6f,e8-ef:0000-7fff\n"
);
if(has_st018) markup.append(
" <armdsp frequency='21477272'>\n"
" <firmware name='st018.rom' size='163840' sha256='6df209ab5d2524d1839c038be400ae5eb20dafc14a3771a3239cd9e8acd53806'/>\n"
" <map address='00-3f:3800-38ff' id='io'/>\n"
" <map address='80-bf:3800-38ff' id='io'/>\n"
" </armdsp>\n"
" armdsp frequency=21477272\n"
" rom id=program name=st018.program.rom size=0x20000\n"
" rom id=data name=st018.data.rom size=0x8000\n"
" ram name=save.ram size=0x4000\n"
" map id=io address=00-3f,80-bf:3800-38ff\n"
);
markup.append("</cartridge>\n");
markup.transform("'", "\"");
}
void SuperFamicomCartridge::read_header(const uint8_t *data, unsigned size) {

View File

@ -74,6 +74,14 @@ namespace nall {
return true;
}
static bool write(const string &filename, const string &text) {
file fp;
if(fp.open(filename, mode::write) == false) return false;
fp.print(text);
fp.close();
return true;
}
static bool write(const string &filename, const vector<uint8_t> &buffer) {
file fp;
if(fp.open(filename, mode::write) == false) return false;

15
ananke/patch.cpp Normal file
View File

@ -0,0 +1,15 @@
void Ananke::applyBeatPatch(vector<uint8_t> &buffer) {
string name = {nall::basename(information.name), ".bps"};
if(!file::exists(name)) return;
bpspatch patch;
if(patch.modify(name) == false) return;
patch.source(buffer.data(), buffer.size());
vector<uint8_t> output;
output.resize(patch.size());
patch.target(output.data(), output.size());
if(patch.apply() == bpspatch::result::success) {
buffer = output;
information.manifest = patch.metadata();
}
}

99
ananke/super-famicom.cpp Normal file
View File

@ -0,0 +1,99 @@
string Ananke::createSuperFamicomDatabase(vector<uint8_t> &buffer, Markup::Node &document, const string &manifest) {
string pathname = {
userpath(), "Emulation/Super Famicom/",
document["release/information/name"].text(),
" (", document["release/information/region"].text(), ")",
" (", document["release/information/revision"].text(), ")",
".sfc/"
};
directory::create(pathname);
//strip "release" root node from database entry
string markup = manifest;
markup.replace("\n ", "\n");
markup.replace("information", "\ninformation");
markup.ltrim<1>("release\n");
file::write({pathname, "manifest.bml"}, markup);
unsigned offset = 0;
for(auto &node : document["release/information/configuration"]) {
if(node.name != "rom") continue;
string name = node["name"].text();
unsigned size = node["size"].decimal();
file::write({pathname, name}, buffer.data() + offset, size);
offset += size;
}
return pathname;
}
string Ananke::createSuperFamicomHeuristic(vector<uint8_t> &buffer) {
string pathname = {
userpath(), "Emulation/Super Famicom/",
nall::basename(information.name),
" (unverified).sfc/"
};
directory::create(pathname);
if((buffer.size() & 0x7fff) == 512) buffer.remove(0, 512); //strip copier header, if present
SuperFamicomCartridge info(buffer.data(), buffer.size());
string markup = info.markup;
if(!information.manifest.empty()) markup = information.manifest; //override with embedded beat manifest, if one exists
file::write({pathname, "manifest.bml"}, markup);
if(!markup.position("spc7110")) {
file::write({pathname, "program.rom"}, buffer);
} else {
file::write({pathname, "program.rom"}, buffer.data(), 0x100000);
file::write({pathname, "data.rom"}, buffer.data() + 0x100000, buffer.size() - 0x100000);
}
auto copyFirmware = [&](const string &name, unsigned programSize, unsigned dataSize) {
auto buffer = file::read({information.path, name}); //try and read from the containing directory
if(buffer.size() == 0) buffer = extractFile(name); //try and read from the containing archive, if one exists
if(buffer.size() == 0) {
MessageWindow::critical(Window::none(), {
"Error: required firmware ", name, " not found. Game will not be playable!\n\n",
"You must obtain this file, and place it in the same folder as this game."
});
return;
}
string basename = nall::basename(name);
if(programSize) file::write({pathname, basename, ".program.rom"}, buffer.data(), programSize);
if(dataSize) file::write({pathname, basename, ".data.rom"}, buffer.data() + programSize, dataSize);
};
if(markup.position("dsp1.program.rom" )) copyFirmware("dsp1.rom", 0x001800, 0x000800);
if(markup.position("dsp1b.program.rom")) copyFirmware("dsp1b.rom", 0x001800, 0x000800);
if(markup.position("dsp2.program.rom" )) copyFirmware("dsp2.rom", 0x001800, 0x000800);
if(markup.position("dsp3.program.rom" )) copyFirmware("dsp3.rom", 0x001800, 0x000800);
if(markup.position("dsp4.program.rom" )) copyFirmware("dsp4.rom", 0x001800, 0x000800);
if(markup.position("st010.program.rom")) copyFirmware("st010.rom", 0x00c000, 0x001000);
if(markup.position("st011.program.rom")) copyFirmware("st011.rom", 0x00c000, 0x001000);
if(markup.position("st018.program.rom")) copyFirmware("st018.rom", 0x020000, 0x008000);
if(markup.position("cx4.data.rom" )) copyFirmware("cx4.rom", 0x000000, 0x000c00);
return pathname;
}
string Ananke::openSuperFamicom(vector<uint8_t> &buffer) {
string sha256 = nall::sha256(buffer.data(), buffer.size());
string databaseText = string::read({configpath(), "ananke/database/Super Famicom.bml"}).rtrim("\n");
lstring databaseItem = databaseText.split("\n\n");
for(auto &item : databaseItem) {
item.append("\n");
auto document = Markup::Document(item);
if(document["release/information/sha256"].text() == sha256) {
return createSuperFamicomDatabase(buffer, document, item);
}
}
return createSuperFamicomHeuristic(buffer);
}

81209
higan/data/cheats.bml Normal file

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -3,7 +3,7 @@
namespace Emulator {
static const char Name[] = "higan";
static const char Version[] = "091.11";
static const char Version[] = "091.13";
static const char Author[] = "byuu";
static const char License[] = "GPLv3";
}

View File

@ -119,359 +119,298 @@ SuperFamicomCartridge::SuperFamicomCartridge(const uint8_t *data, unsigned size)
if(type == TypeBsx) return;
if(type == TypeSufamiTurbo) return;
markup.append("<?xml version='1.0' encoding='UTF-8'?>\n");
const char *range = (rom_size > 0x200000) || (ram_size > 32 * 1024) ? "0000-7fff" : "0000-ffff";
markup.append("<cartridge region='", region == NTSC ? "NTSC" : "PAL", "'>\n");
markup.append("cartridge region=", region == NTSC ? "NTSC" : "PAL", "\n");
if(type == TypeSuperGameBoy1Bios || type == TypeSuperGameBoy2Bios) markup.append(
" <rom name='program.rom' size='0x", hex(rom_size), "'/>\n"
" <map address='00-7f:8000-ffff' id='rom' mode='linear'/>\n"
" <map address='80-ff:8000-ffff' id='rom' mode='linear'/>\n"
" <icd2 revision='1'>\n"
" <firmware name='boot.rom' size='256' sha256='0e4ddff32fc9d1eeaae812a157dd246459b00c9e14f2f61751f661f32361e360'/>\n"
" <map address='00-3f:6000-7fff' id='io'/>\n"
" <map address='80-bf:6000-7fff' id='io'/>\n"
" </icd2>\n"
" rom name=program.rom size=0x", hex(rom_size), "\n"
" map id=rom address=00-7f,80-ff:8000-ffff\n"
" icd2 revision=1\n"
" rom name=boot.rom size=0x100\n"
" map id=io address=00-3f,80-bf:6000-7fff\n"
);
else if(has_cx4) markup.append(
" <hitachidsp model='HG51B169' frequency='20000000'>\n"
" <firmware name='cx4.rom' size='3072' sha256='ae8d4d1961b93421ff00b3caa1d0f0ce7783e749772a3369c36b3dbf0d37ef18'/>\n"
" <rom name='program.rom' size='0x", hex(rom_size), "'/>\n"
" <map address='00-3f:6000-7fff' id='io'/>\n"
" <map address='80-bf:6000-7fff' id='io'/>\n"
" <map address='00-7f:8000-ffff' id='rom' mode='linear'/>\n"
" <map address='80-ff:8000-ffff' id='rom' mode='linear'/>\n"
" </hitachidsp>\n"
" hitachidsp model=HG51B169 frequency=20000000\n"
" rom id=program name=program.rom size=0x", hex(rom_size), "\n"
" rom id=data name=cx4.data.rom size=0xc00\n"
" ram id=data size=0xc00\n"
" map id=io address=00-3f,80-bf:6000-7fff\n"
" map id=rom address=00-7f,80-ff:8000-ffff mask=0x8000\n"
" map id=ram address=70-77:0000-7fff\n"
);
else if(has_spc7110) markup.append(
" <spc7110>\n"
" <prom name='program.rom' size='0x100000'/>\n"
" <drom name='data.rom' size='0x", hex(rom_size - 0x100000), "'/>\n"
" <ram name='save.rwm' size='0x2000'/>\n"
" <map address='00-3f:4800-483f' id='io'/>\n"
" <map address='80-bf:4800-483f' id='io'/>\n"
" <map address='50:0000-ffff' id='io'/>\n"
" <map address='00-3f:8000-ffff' id='rom'/>\n"
" <map address='80-bf:8000-ffff' id='rom'/>\n"
" <map address='c0-ff:0000-ffff' id='rom'/>\n"
" <map address='00-3f:6000-7fff' id='ram'/>\n"
" <map address='80-bf:6000-7fff' id='ram'/>\n"
" </spc7110>\n"
" spc7110\n"
" rom id=program name=program.rom size=0x100000\n"
" rom id=data name=data.rom size=0x", hex(rom_size - 0x100000), "\n"
" ram name=save.ram size=0x", hex(ram_size), "\n"
" map id=io address=00-3f,80-bf:4800-483f\n"
" map id=io address=50:0000-ffff\n"
" map id=rom address=00-3f,80-bf:8000-ffff\n"
" map id=rom address=c0-ff:0000-ffff\n"
" map id=ram address=00-3f,80-bf:6000-7fff mask=0xe000\n"
);
else if(has_sdd1) markup.append(
" <sdd1>\n"
" <rom name='program.rom' size='0x", hex(rom_size), "'/>\n"
" <ram name='save.rwm' size='0x", hex(ram_size), "'/>\n"
" <map address='00-3f:4800-4807' id='io'/>\n"
" <map address='80-bf:4800-4807' id='io'/>\n"
" <map address='00-3f:8000-ffff' id='rom'/>\n"
" <map address='80-bf:8000-ffff' id='rom'/>\n"
" <map address='40-7f:0000-ffff' id='rom'/>\n"
" <map address='c0-ff:0000-ffff' id='rom'/>\n"
" <map address='20-3f:6000-7fff' id='ram'/>\n"
" <map address='a0-bf:6000-7fff' id='ram'/>\n"
" <map address='70-7f:0000-7fff' id='ram'/>\n"
" </sdd1>\n"
);
else if(has_sdd1) {
markup.append(
" sdd1\n"
" rom name=program.rom size=0x", hex(rom_size), "\n"
);
if(ram_size > 0) markup.append(
" ram name=save.ram size=0x", hex(ram_size), "\n"
);
markup.append(
" map id=io address=00-3f,80-bf:4800-4807\n"
" map id=rom address=00-3f,80-bf:8000-ffff mask=0x8000\n"
" map id=rom address=c0-ff:0000-ffff\n"
);
if(ram_size > 0) markup.append(
" map id=ram address=20-3f,a0-bf:6000-7fff mask=0xe000\n"
" map id=ram address=70-7f:0000-7fff\n"
);
}
else if(mapper == LoROM) {
markup.append(
" <rom name='program.rom' size='0x", hex(rom_size), "'/>\n"
" <map address='00-7f:8000-ffff' id='rom' mode='linear'/>\n"
" <map address='80-ff:8000-ffff' id='rom' mode='linear'/>\n"
" rom name=program.rom size=0x", hex(rom_size), "\n"
);
if(ram_size > 0) markup.append(
" <ram name='save.rwm' size='0x", hex(ram_size), "'/>\n"
" <map address='20-3f:6000-7fff' id='ram' mode='linear'/>\n"
" <map address='a0-bf:6000-7fff' id='ram' mode='linear'/>\n"
" <map address='70-7f:", range, "' id='ram' mode='linear'/>\n"
" <map address='f0-ff:", range, "' id='ram' mode='linear'/>\n"
" ram name=save.ram size=0x", hex(ram_size), "\n"
);
markup.append(
" map id=rom address=00-7f,80-ff:8000-ffff mask=0x8000\n"
);
if(ram_size > 0) markup.append(
" map id=ram address=70-7f,f0-ff:", range, "\n"
);
}
else if(mapper == HiROM) {
markup.append(
" <rom name='program.rom' size='0x", hex(rom_size), "'/>\n"
" <map address='00-3f:8000-ffff' id='rom' mode='shadow'/>\n"
" <map address='80-bf:8000-ffff' id='rom' mode='shadow'/>\n"
" <map address='40-7f:0000-ffff' id='rom' mode='linear'/>\n"
" <map address='c0-ff:0000-ffff' id='rom' mode='linear'/>\n"
" rom name=program.rom size=0x", hex(rom_size), "\n"
);
if(ram_size > 0) markup.append(
" <ram name='save.rwm' size='0x", hex(ram_size), "'/>\n"
" <map address='20-3f:6000-7fff' id='ram' mode='linear'/>\n"
" <map address='a0-bf:6000-7fff' id='ram' mode='linear'/>\n"
" <map address='70-7f:", range, "' id='ram' mode='linear'/>\n"
" ram name=save.ram size=0x", hex(ram_size), "\n"
);
markup.append(
" map id=rom address=00-3f,80-bf:8000-ffff\n"
" map id=rom address=40-7f,c0-ff:0000-ffff\n"
);
if(ram_size > 0) markup.append(
" map id=ram address=10-3f,90-bf:6000-7fff mask=0xe000\n"
);
}
else if(mapper == ExLoROM) {
markup.append(
" <rom name='program.rom' size='0x", hex(rom_size), "'/>\n"
" <map address='00-3f:8000-ffff' id='rom' mode='linear'/>\n"
" <map address='80-bf:8000-ffff' id='rom' mode='linear'/>\n"
" <map address='40-7f:0000-ffff' id='rom' mode='linear'/>\n"
" rom name=program.rom size=0x", hex(rom_size), "\n"
);
if(ram_size > 0) markup.append(
" <ram name='save.rwm' size='0x", hex(ram_size), "'/>\n"
" <map address='20-3f:6000-7fff' id='ram' mode='linear'/>\n"
" <map address='a0-bf:6000-7fff' id='ram' mode='linear'/>\n"
" <map address='70-7f:0000-7fff' id='ram' mode='linear'/>\n"
" ram name=save.ram size=0x", hex(ram_size), "\n"
);
markup.append(
" map id=rom address=00-3f,80-bf:8000-ffff mask=0x8000\n"
" map id=rom address=40-7f:0000-ffff\n"
);
if(ram_size > 0) markup.append(
" map id=ram address=20-3f,a0-bf:6000-7fff\n"
" map id=ram address=70-7f:0000-7fff\n"
);
}
else if(mapper == ExHiROM) {
markup.append(
" <rom name='program.rom' size='0x", hex(rom_size), "'/>\n"
" <map address='00-3f:8000-ffff' id='rom' mode='shadow' offset='0x400000'/>\n"
" <map address='80-bf:8000-ffff' id='rom' mode='shadow' offset='0x000000'/>\n"
" <map address='40-7f:0000-ffff' id='rom' mode='linear' offset='0x400000'/>\n"
" <map address='c0-ff:0000-ffff' id='rom' mode='linear' offset='0x000000'/>\n"
" rom name=program.rom size=0x", hex(rom_size), "\n"
);
if(ram_size > 0) markup.append(
" <ram name='save.rwm' size='0x", hex(ram_size), "'/>\n"
" <map address='20-3f:6000-7fff' id='ram' mode='linear'/>\n"
" <map address='a0-bf:6000-7fff' id='ram' mode='linear'/>\n"
" <map address='70-7f:", range, "' id='ram' mode='linear'/>\n"
" ram name=save.ram size=0x", hex(ram_size), "\n"
);
markup.append(
" map id=rom address=00-3f:8000-ffff offset=0x400000\n"
" map id=rom address=40-7f:0000-ffff offset=0x400000\n"
" map id=rom address=80-bf:8000-ffff offset=0x000000\n"
" map id=rom address=c0-ff:0000-ffff offset=0x000000\n"
);
if(ram_size > 0) markup.append(
" map id=ram address=20-3f,a0-bf:6000-7fff mask=0xe000\n"
" map id=ram address=70-7f:", range, "\n"
);
}
else if(mapper == SuperFXROM) {
markup.append(
" <superfx revision='2'>\n"
" <map address='00-3f:3000-32ff' id='io'/>\n"
" <map address='80-bf:3000-32ff' id='io'/>\n"
" <rom name='program.rom' size='0x", hex(rom_size), "'/>\n"
" <map address='00-3f:8000-ffff' id='rom' mode='linear'/>\n"
" <map address='80-bf:8000-ffff' id='rom' mode='linear'/>\n"
" <map address='40-5f:0000-ffff' id='rom' mode='linear'/>\n"
" <map address='c0-df:0000-ffff' id='rom' mode='linear'/>\n"
" superfx revision=3\n"
" rom name=program.rom size=0x", hex(rom_size), "\n"
);
if(ram_size > 0) markup.append(
" <ram name='save.rwm' size='0x", hex(ram_size), "'/>\n"
" <map address='00-3f:6000-7fff' id='ram' mode='linear' size='0x2000'/>\n"
" <map address='80-bf:6000-7fff' id='ram' mode='linear' size='0x2000'/>\n"
" <map address='60-7f:0000-ffff' id='ram' mode='linear'/>\n"
" <map address='e0-ff:0000-ffff' id='ram' mode='linear'/>\n"
" ram name=save.ram size=0x", hex(ram_size), "\n"
);
markup.append(
" </superfx>\n"
" map id=io address=00-3f,80-bf:3000-32ff\n"
" map id=rom address=00-3f,80-bf:8000-ffff mask=0x8000\n"
" map id=rom address=40-5f,c0-df:0000-ffff\n"
);
if(ram_size > 0) markup.append(
" map id=ram address=00-3f,80-bf:6000-7fff size=0x2000\n"
" map id=ram address=70-71,f0-f1:0000-ffff\n"
);
}
else if(mapper == SA1ROM) {
markup.append(
" <sa1>\n"
" <map address='00-3f:2200-23ff' id='io'/>\n"
" <map address='80-bf:2200-23ff' id='io'/>\n"
" <rom name='program.rom' size='0x", hex(rom_size), "'/>\n"
" <map address='00-3f:8000-ffff' id='rom'/>\n"
" <map address='80-bf:8000-ffff' id='rom'/>\n"
" <map address='c0-ff:0000-ffff' id='rom'/>\n"
" <iram size='0x800'/>\n"
" <map address='00-3f:3000-37ff' id='iram'/>\n"
" <map address='80-bf:3000-37ff' id='iram'/>\n"
" sa1\n"
" rom name=program.rom size=0x", hex(rom_size), "\n"
);
if(ram_size > 0) markup.append(
" <bwram name='save.rwm' size='0x", hex(ram_size), "'/>\n"
" <map address='00-3f:6000-7fff' id='bwram'/>\n"
" <map address='80-bf:6000-7fff' id='bwram'/>\n"
" <map address='40-4f:0000-ffff' id='bwram'/>\n"
" ram id=bitmap name=save.ram size=0x", hex(ram_size), "\n"
);
markup.append(
" </sa1>\n"
" ram id=internal size=0x800\n"
" map id=io address=00-3f,80-bf:2200-23ff\n"
" map id=rom address=00-3f,80-bf:8000-ffff\n"
" map id=rom address=c0-ff:0000-ffff\n"
);
if(ram_size > 0) markup.append(
" map id=bwram address=00-3f,80-bf:6000-7fff\n"
" map id=bwram address=40-4f:0000-ffff\n"
);
markup.append(
" map id=iram address=00-3f,80-bf:3000-37ff\n"
);
}
else if(mapper == BSCLoROM) markup.append(
" <rom name='program.rom' size='0x", hex(rom_size), "'/>\n"
" <ram name='save.rwm' size='0x", hex(ram_size), "'/>\n"
" <map address='00-1f:8000-ffff' id='rom' mode='linear' offset='0x000000'/>\n"
" <map address='20-3f:8000-ffff' id='rom' mode='linear' offset='0x100000'/>\n"
" <map address='80-9f:8000-ffff' id='rom' mode='linear' offset='0x200000'/>\n"
" <map address='a0-bf:8000-ffff' id='rom' mode='linear' offset='0x100000'/>\n"
" <map address='70-7f:0000-7fff' id='ram' mode='linear'/>\n"
" <map address='f0-ff:0000-7fff' id='ram' mode='linear'/>\n"
" <bsxslot>\n"
" <map address='c0-ef:0000-ffff' id='rom' mode='linear'/>\n"
" </bsxslot>\n"
" rom name=program.rom size=0x", hex(rom_size), "\n"
" ram name=save.ram size=0x", hex(ram_size), "\n"
" map id=rom address=00-1f:8000-ffff offset=0x000000 mask=0x8000\n"
" map id=rom address=20-3f:8000-ffff offset=0x100000 mask=0x8000\n"
" map id=rom address=80-9f:8000-ffff offset=0x200000 mask=0x8000\n"
" map id=rom address=a0-bf:8000-ffff offset=0x100000 mask=0x8000\n"
" map id=ram address=70-7f,f0-ff:0000-7fff\n"
" bsxslot\n"
" map id=rom address=c0-ef:0000-ffff\n"
);
else if(mapper == BSCHiROM) markup.append(
" <rom name='program.rom' size='0x", hex(rom_size), "'/>\n"
" <ram name='save.rwm' size='0x", hex(ram_size), "'/>\n"
" <map address='00-1f:8000-ffff' id='rom' mode='shadow'/>\n"
" <map address='80-9f:8000-ffff' id='rom' mode='shadow'/>\n"
" <map address='40-5f:0000-ffff' id='rom' mode='linear'/>\n"
" <map address='c0-df:0000-ffff' id='rom' mode='linear'/>\n"
" <map address='20-3f:6000-7fff' id='ram' mode='linear'/>\n"
" <map address='a0-bf:6000-7fff' id='ram' mode='linear'/>\n"
" <bsxslot>\n"
" <map address='20-3f:8000-ffff' id='rom' mode='shadow'/>\n"
" <map address='a0-bf:8000-ffff' id='rom' mode='shadow'/>\n"
" <map address='60-7f:0000-ffff' id='rom' mode='linear'/>\n"
" <map address='e0-ff:0000-ffff' id='rom' mode='linear'/>\n"
" </bsxslot>\n"
" rom name=program.rom size=0x", hex(rom_size), "\n"
" ram name=save.ram size=0x", hex(ram_size), "\n"
" map id=rom address=00-1f,80-9f:8000-ffff\n"
" map id=rom address=40-5f,c0-df:0000-ffff\n"
" map id=ram address=20-3f,a0-bf:6000-7fff\n"
" bsxslot\n"
" map id=rom address=20-3f,a0-bf:8000-ffff\n"
" map id=rom address=60-7f,e0-ff:0000-ffff\n"
);
else if(mapper == BSXROM) markup.append(
" <bsx>\n"
" <rom name='program.rom' size='0x", hex(rom_size), "'/>\n"
" <ram name='save.rwm' size='0x", hex(ram_size), "'/>\n"
" <psram name='bsx.rwm' size='0x40000'/>\n"
" <map address='00-3f:5000-5fff' id='io'/>\n"
" <map address='80-bf:5000-5fff' id='io'/>\n"
" <map address='20-3f:6000-7fff' id='ram'/>\n"
" <map address='00-3f:8000-ffff' id='rom'/>\n"
" <map address='80-bf:8000-ffff' id='rom'/>\n"
" <map address='40-7f:0000-ffff' id='rom'/>\n"
" <map address='c0-ff:0000-ffff' id='rom'/>\n"
" </bsx>\n"
" bsx\n"
" rom name=program.rom size=0x", hex(rom_size), "\n"
" ram id=save name=save.ram size=0x", hex(ram_size), "\n"
" ram id=download name=bsx.ram size=0x40000\n"
" map id=io address=00-3f,80-bf:5000-5fff\n"
" map id=rom address=00-3f,80-bf:8000-ffff\n"
" map id=rom address=40-7f,c0-ff:0000-ffff\n"
" map id=ram address=20-3f:6000-7fff\n"
);
else if(mapper == STROM) markup.append(
" <rom name='program.rom' size='0x", hex(rom_size), "'/>\n"
" <map address='00-1f:8000-ffff' id='rom' mode='linear'/>\n"
" <map address='80-9f:8000-ffff' id='rom' mode='linear'/>\n"
" <sufamiturbo>\n"
" <slot id='A'>\n"
" <map address='20-3f:8000-ffff' id='rom' mode='linear'/>\n"
" <map address='a0-bf:8000-ffff' id='rom' mode='linear'/>\n"
" <map address='60-63:8000-ffff' id='ram' mode='linear'/>\n"
" <map address='e0-e3:8000-ffff' id='ram' mode='linear'/>\n"
" </slot>\n"
" <slot id='B'>\n"
" <map address='40-5f:8000-ffff' id='rom' mode='linear'/>\n"
" <map address='c0-df:8000-ffff' id='rom' mode='linear'/>\n"
" <map address='70-73:8000-ffff' id='ram' mode='linear'/>\n"
" <map address='f0-f3:8000-ffff' id='ram' mode='linear'/>\n"
" </slot>\n"
" </sufamiturbo>\n"
" rom name=program.rom size=0x", hex(rom_size), "\n"
" map id=rom address='00-1f,80-9f:8000-ffff mask=0x8000\n"
" sufamiturbo\n"
" slot id=A\n"
" map id=rom address=20-3f,a0-bf:8000-ffff mask=0x8000\n"
" map id=ram address=60-63,e0-e3:8000-ffff\n"
" slot id=B\n"
" map id=rom address=40-5f,c0-df:8000-ffff mask=0x8000\n"
" map id=ram address=70-73,f0-f3:8000-ffff\n"
);
if(has_spc7110rtc) markup.append(
" <epsonrtc>\n"
" <ram name='rtc.rwm' size='0x10'/>\n"
" <map address='00-3f:4840-4842' id='io'/>\n"
" <map address='80-bf:4840-4842' id='io'/>\n"
" </epsonrtc>\n"
" epsonrtc\n"
" ram name=rtc.ram size=0x10\n"
" map id=io address=00-3f,80-bf:4840-4842\n"
);
if(has_srtc) markup.append(
" <sharprtc>\n"
" <ram name='rtc.rwm' size='0x10'/>\n"
" <map address='00-3f:2800-2801' id='io'/>\n"
" <map address='80-bf:2800-2801' id='io'/>\n"
" </sharprtc>\n"
" sharprtc\n"
" ram name=rtc.ram size=0x10\n"
" map id=io address=00-3f,80-bf:2800-2801\n"
);
if(has_obc1) markup.append(
" <obc1>\n"
" <ram name='save.rwm' size='0x2000'/>\n"
" <map address='00-3f:6000-7fff' id='io'/>\n"
" <map address='80-bf:6000-7fff' id='io'/>\n"
" </obc1>\n"
" obc1\n"
" ram name=save.ram size=0x2000\n"
" map id=io address=00-3f,80-bf:6000-7fff\n"
);
if(has_dsp1) {
//91e87d11e1c30d172556bed2211cce2efa94ba595f58c5d264809ef4d363a97b dsp1.rom
markup.append(
" <necdsp model='uPD7725' frequency='8000000'>\n"
" <firmware name='dsp1b.rom' size='8192' sha256='d789cb3c36b05c0b23b6c6f23be7aa37c6e78b6ee9ceac8d2d2aa9d8c4d35fa9'/>\n"
" necdsp model=uPD7725 frequency=8000000\n"
" rom id=program name=dsp1b.program.rom size=0x1800\n"
" rom id=data name=dsp1b.data.rom size=0x800\n"
" ram id=data size=0x200\n"
);
if(dsp1_mapper == DSP1LoROM1MB) markup.append(
" <map address='20-3f:8000-bfff' id='dr'/>\n"
" <map address='a0-bf:8000-bfff' id='dr'/>\n"
" <map address='20-3f:c000-ffff' id='sr'/>\n"
" <map address='a0-bf:c000-ffff' id='sr'/>\n"
" map id=io address=20-3f,a0-bf:8000-ffff select=0x4000\n"
);
if(dsp1_mapper == DSP1LoROM2MB) markup.append(
" <map address='60-6f:0000-3fff' id='dr'/>\n"
" <map address='e0-ef:0000-3fff' id='dr'/>\n"
" <map address='60-6f:4000-7fff' id='sr'/>\n"
" <map address='e0-ef:4000-7fff' id='sr'/>\n"
" map id=io address=60-6f,e0-ef:0000-7fff select=0x4000\n"
);
if(dsp1_mapper == DSP1HiROM) markup.append(
" <map address='00-1f:6000-6fff' id='dr'/>\n"
" <map address='80-9f:6000-6fff' id='dr'/>\n"
" <map address='00-1f:7000-7fff' id='sr'/>\n"
" <map address='80-9f:7000-7fff' id='sr'/>\n"
);
markup.append(
" </necdsp>\n"
" map id=io address=00-1f,80-9f:6000-7fff select=0x1000\n"
);
}
if(has_dsp2) markup.append(
" <necdsp model='uPD7725' frequency='8000000'>\n"
" <firmware name='dsp2.rom' size='8192' sha256='03ef4ef26c9f701346708cb5d07847b5203cf1b0818bf2930acd34510ffdd717'/>\n"
" <map address='20-3f:8000-bfff' id='dr'/>\n"
" <map address='a0-bf:8000-bfff' id='dr'/>\n"
" <map address='20-3f:c000-ffff' id='sr'/>\n"
" <map address='a0-bf:c000-ffff' id='sr'/>\n"
" </necdsp>\n"
" necdsp model=uPD7725 frequency=8000000\n"
" rom id=program name=dsp2.program.rom size=0x1800\n"
" rom id=data name=dsp2.data.rom size=0x800\n"
" ram id=data size=0x200\n"
" map id=io address=20-3f,a0-bf:8000-ffff select=0x4000\n"
);
if(has_dsp3) markup.append(
" <necdsp model='uPD7725' frequency='8000000'>\n"
" <firmware name='dsp3.rom' size='8192' sha256='0971b08f396c32e61989d1067dddf8e4b14649d548b2188f7c541b03d7c69e4e'/>\n"
" <map address='20-3f:8000-bfff' id='dr'/>\n"
" <map address='a0-bf:8000-bfff' id='dr'/>\n"
" <map address='20-3f:c000-ffff' id='sr'/>\n"
" <map address='a0-bf:c000-ffff' id='sr'/>\n"
" </necdsp>\n"
" necdsp model=uPD7725 frequency=8000000\n"
" rom id=program name=dsp3.program.rom size=0x1800\n"
" rom id=data name=dsp3.data.rom size=0x800\n"
" ram id=data size=0x200\n"
" map id=io address=20-3f,a0-bf:8000-ffff select=0x4000\n"
);
if(has_dsp4) markup.append(
" <necdsp model='uPD7725' frequency='8000000'>\n"
" <firmware name='dsp4.rom' size='8192' sha256='752d03b2d74441e430b7f713001fa241f8bbcfc1a0d890ed4143f174dbe031da'/>\n"
" <map address='30-3f:8000-bfff' id='dr'/>\n"
" <map address='b0-bf:8000-bfff' id='dr'/>\n"
" <map address='30-3f:c000-ffff' id='sr'/>\n"
" <map address='b0-bf:c000-ffff' id='sr'/>\n"
" </necdsp>\n"
" necdsp model=uPD7725 frequency=8000000\n"
" rom id=program name=dsp4.program.rom size=0x1800\n"
" rom id=data name=dsp4.data.rom size=0x800\n"
" ram id=data size=0x200\n"
" map address=30-3f,b0-bf:8000-ffff select=0x4000\n"
);
if(has_st010) markup.append(
" <necdsp model='uPD96050' frequency='10000000'>\n"
" <firmware name='st010.rom' size='53248' sha256='fa9bced838fedea11c6f6ace33d1878024bdd0d02cc9485899d0bdd4015ec24c'/>\n"
" <ram name='save.rwm' size='0x1000'/>\n"
" <map address='60:0000' id='dr'/>\n"
" <map address='e0:0000' id='dr'/>\n"
" <map address='60:0001' id='sr'/>\n"
" <map address='e0:0001' id='sr'/>\n"
" <map address='68-6f:0000-0fff' id='ram'/>\n"
" <map address='e8-ef:0000-0fff' id='ram'/>\n"
" </necdsp>\n"
" necdsp model=uPD96050 frequency=11000000\n"
" rom id=program name=st010.program.rom size=0xc000\n"
" rom id=data name=st010.data.rom size=0x1000\n"
" ram id=data name=save.ram size=0x1000\n"
" map id=io address=60-67,e0-e7:0000-3fff select=0x0001\n"
" map id=ram address=68-6f,e8-ef:0000-7fff\n"
);
if(has_st011) markup.append(
" <necdsp model='uPD96050' frequency='15000000'>\n"
" <firmware name='st011.rom' size='53248' sha256='8b2b3f3f3e6e29f4d21d8bc736b400bc988b7d2214ebee15643f01c1fee2f364'/>\n"
" <ram name='save.rwm' size='0x1000'/>\n"
" <map address='60:0000' id='dr'/>\n"
" <map address='e0:0000' id='dr'/>\n"
" <map address='60:0001' id='sr'/>\n"
" <map address='e0:0001' id='sr'/>\n"
" <map address='68-6f:0000-0fff' id='ram'/>\n"
" <map address='e8-ef:0000-0fff' id='ram'/>\n"
" </necdsp>\n"
" necdsp model=uPD96050 frequency=15000000\n"
" rom id=program name=st011.program.rom size=0xc000\n"
" rom id=data name=st011.data.rom size=0x1000\n"
" ram id=data name=save.ram size=0x1000\n"
" map id=io address=60-67,e0-e7:0000-3fff select=0x0001\n"
" map id=ram address=68-6f,e8-ef:0000-7fff\n"
);
if(has_st018) markup.append(
" <armdsp frequency='21477272'>\n"
" <firmware name='st018.rom' size='163840' sha256='6df209ab5d2524d1839c038be400ae5eb20dafc14a3771a3239cd9e8acd53806'/>\n"
" <map address='00-3f:3800-38ff' id='io'/>\n"
" <map address='80-bf:3800-38ff' id='io'/>\n"
" </armdsp>\n"
" armdsp frequency=21477272\n"
" rom id=program name=st018.program.rom size=0x20000\n"
" rom id=data name=st018.data.rom size=0x8000\n"
" ram name=save.ram size=0x4000\n"
" map id=io address=00-3f,80-bf:3800-38ff\n"
);
markup.append("</cartridge>\n");
markup.transform("'", "\"");
}
void SuperFamicomCartridge::read_header(const uint8_t *data, unsigned size) {

View File

@ -1,8 +1,8 @@
cartridge region=NTSC
bsx
rom name=program.rom size=0x100000
ram name=save.rwm size=0x8000
psram name=bsx.rwm size=0x40000
ram id=save name=save.ram size=0x8000
ram id=download name=bsx.ram size=0x40000
map id=io address=00-3f,80-bf:5000-5fff
map id=rom address=00-3f,80-bf:8000-ffff
map id=rom address=40-7f,c0-ff:0000-7fff

View File

@ -87,7 +87,7 @@ private:
void parse_markup_sa1(Markup::Node);
void parse_markup_superfx(Markup::Node);
void parse_markup_armdsp(Markup::Node);
void parse_markup_hitachidsp(Markup::Node);
void parse_markup_hitachidsp(Markup::Node, unsigned roms);
void parse_markup_necdsp(Markup::Node);
void parse_markup_epsonrtc(Markup::Node);
void parse_markup_sharprtc(Markup::Node);

View File

@ -1,7 +1,7 @@
#ifdef CARTRIDGE_CPP
void Cartridge::parse_markup(const char *markup) {
auto cartridge = Markup::Document(markup)["release/cartridge"];
auto cartridge = Markup::Document(markup)["cartridge"];
region = cartridge["region"].data != "PAL" ? Region::NTSC : Region::PAL;
mapping.reset();
@ -15,7 +15,7 @@ void Cartridge::parse_markup(const char *markup) {
parse_markup_sa1(cartridge["sa1"]);
parse_markup_superfx(cartridge["superfx"]);
parse_markup_armdsp(cartridge["armdsp"]);
parse_markup_hitachidsp(cartridge["hitachidsp"]);
parse_markup_hitachidsp(cartridge["hitachidsp"], cartridge["board/type"].data.wildcard("2DC*") ? 2 : 1);
parse_markup_necdsp(cartridge["necdsp"]);
parse_markup_epsonrtc(cartridge["epsonrtc"]);
parse_markup_sharprtc(cartridge["sharprtc"]);
@ -320,7 +320,7 @@ void Cartridge::parse_markup_armdsp(Markup::Node root) {
string programROMName = root["rom(id=program)/name"].data;
string dataROMName = root["rom(id=data)/name"].data;
string dataRAMName = root["ram/name"].data;
string dataRAMName = root["ram(id=data)/name"].data;
interface->loadRequest(ID::ArmDSPPROM, programROMName);
interface->loadRequest(ID::ArmDSPDROM, dataROMName);
@ -340,25 +340,27 @@ void Cartridge::parse_markup_armdsp(Markup::Node root) {
}
}
void Cartridge::parse_markup_hitachidsp(Markup::Node root) {
void Cartridge::parse_markup_hitachidsp(Markup::Node root, unsigned roms) {
if(root.exists() == false) return;
has_hitachidsp = true;
for(auto &n : hitachidsp.dataROM) hitachidsp.dataROM[n] = 0x000000;
for(auto &n : hitachidsp.dataRAM) hitachidsp.dataRAM[n] = 0x00;
hitachidsp.frequency = numeral(root["frequency"].data);
if(hitachidsp.frequency == 0) hitachidsp.frequency = 20000000;
hitachidsp.Frequency = numeral(root["frequency"].data);
if(hitachidsp.Frequency == 0) hitachidsp.frequency = 20000000;
hitachidsp.Roms = roms;
string dataROMName = root["rom(id=data)/name"].data;
string dataRAMName = root["ram/name"].data;
string dataRAMName = root["ram(id=data)/name"].data;
interface->loadRequest(ID::HitachiDSPDROM, dataROMName);
if(dataRAMName.empty() == false) {
interface->loadRequest(ID::HitachiDSPRAM, dataRAMName);
interface->loadRequest(ID::HitachiDSPDRAM, dataRAMName);
}
parse_markup_memory(hitachidsp.rom, root["rom(id!=data)"], ID::HitachiDSPROM, false);
parse_markup_memory(hitachidsp.rom, root["rom(id=program)"], ID::HitachiDSPROM, false);
parse_markup_memory(hitachidsp.ram, root["ram(id=program)"], ID::HitachiDSPRAM, true);
for(auto &node : root) {
if(node.name != "map") continue;
@ -375,6 +377,13 @@ void Cartridge::parse_markup_hitachidsp(Markup::Node root) {
if(m.size == 0) m.size = hitachidsp.rom.size();
mapping.append(m);
}
if(node["id"].data == "ram") {
Mapping m({&HitachiDSP::ram_read, &hitachidsp}, {&HitachiDSP::ram_write, &hitachidsp});
parse_markup_map(m, node);
if(m.size == 0) m.size = hitachidsp.ram.size();
mapping.append(m);
}
}
}
@ -395,7 +404,7 @@ void Cartridge::parse_markup_necdsp(Markup::Node root) {
string programROMName = root["rom(id=program)/name"].data;
string dataROMName = root["rom(id=data)/name"].data;
string dataRAMName = root["ram/name"].data;
string dataRAMName = root["ram(id=data)/name"].data;
if(necdsp.revision == NECDSP::Revision::uPD7725) {
interface->loadRequest(ID::Nec7725DSPPROM, programROMName);
@ -418,20 +427,15 @@ void Cartridge::parse_markup_necdsp(Markup::Node root) {
for(auto &node : root) {
if(node.name != "map") continue;
if(node["id"].data == "dr") {
Mapping m({&NECDSP::dr_read, &necdsp}, {&NECDSP::dr_write, &necdsp});
parse_markup_map(m, node);
mapping.append(m);
}
if(node["id"].data == "sr") {
Mapping m({&NECDSP::sr_read, &necdsp}, {&NECDSP::sr_write, &necdsp});
if(node["id"].data == "io") {
Mapping m({&NECDSP::read, &necdsp}, {&NECDSP::write, &necdsp});
parse_markup_map(m, node);
mapping.append(m);
necdsp.Select = numeral(node["select"].data);
}
if(node["id"].data == "ram") {
Mapping m({&NECDSP::dp_read, &necdsp}, {&NECDSP::dp_write, &necdsp});
Mapping m({&NECDSP::ram_read, &necdsp}, {&NECDSP::ram_write, &necdsp});
parse_markup_map(m, node);
mapping.append(m);
}

View File

@ -38,6 +38,7 @@ void HitachiDSP::load() {
void HitachiDSP::unload() {
rom.reset();
ram.reset();
}
void HitachiDSP::power() {
@ -57,7 +58,7 @@ void HitachiDSP::power() {
}
void HitachiDSP::reset() {
create(HitachiDSP::Enter, frequency);
create(HitachiDSP::Enter, Frequency);
HG51B::power();
}

View File

@ -1,7 +1,10 @@
struct HitachiDSP : Processor::HG51B, Coprocessor {
MappedRAM rom;
unsigned Frequency;
unsigned Roms;
MappedRAM rom;
MappedRAM ram;
unsigned frequency;
#include "mmio.hpp"
static void Enter();
@ -21,6 +24,10 @@ struct HitachiDSP : Processor::HG51B, Coprocessor {
uint8 rom_read(unsigned addr);
void rom_write(unsigned addr, uint8 data);
//CPU RAM read/write
uint8 ram_read(unsigned addr);
void ram_write(unsigned addr, uint8 data);
//CPU MMIO read/write
uint8 dsp_read(unsigned addr);
void dsp_write(unsigned addr, uint8 data);

View File

@ -1,29 +1,39 @@
#ifdef HITACHIDSP_CPP
uint8 HitachiDSP::bus_read(uint24 addr) {
if((addr & 0x408000) == 0x008000) return bus.read(addr);
if((addr & 0x408000) == 0x008000) return bus.read(addr); //$00-3f,80-bf:6000-7fff
if((addr & 0xf88000) == 0x700000) return bus.read(addr); //$70-77:0000-7fff
return 0x00;
}
void HitachiDSP::bus_write(uint24 addr, uint8 data) {
if((addr & 0x40e000) == 0x006000) return bus.write(addr, data);
if((addr & 0x40e000) == 0x006000) return bus.write(addr, data); //$00-3f,80-bf:6000-7fff
if((addr & 0xf88000) == 0x700000) return bus.write(addr, data); //$70-77:0000-7fff
}
uint8 HitachiDSP::rom_read(unsigned addr) {
if(co_active() == cpu.thread) {
if(regs.halt) return rom.read(addr);
if((addr & 0x40ffe0) == 0x00ffe0) return mmio.vector[addr & 0x1f];
return cpu.regs.mdr;
}
if(co_active() == hitachidsp.thread) {
if(co_active() == hitachidsp.thread || regs.halt) {
addr = bus.mirror(addr, rom.size());
//if(Roms == 2 && mmio.r1f52 == 1 && addr >= (bit::round(rom.size()) >> 1)) return 0x00;
return rom.read(addr);
}
if((addr & 0x40ffe0) == 0x00ffe0) return mmio.vector[addr & 0x1f];
return cpu.regs.mdr;
}
void HitachiDSP::rom_write(unsigned addr, uint8 data) {
}
uint8 HitachiDSP::ram_read(unsigned addr) {
if(ram.size() == 0) return 0x00; //not open bus
return ram.read(bus.mirror(addr, ram.size()));
}
void HitachiDSP::ram_write(unsigned addr, uint8 data) {
if(ram.size() == 0) return;
return ram.write(bus.mirror(addr, ram.size()), data);
}
uint8 HitachiDSP::dsp_read(unsigned addr) {
addr &= 0x1fff;

View File

@ -20,14 +20,33 @@ void NECDSP::enter() {
}
}
uint8 NECDSP::sr_read(unsigned) { cpu.synchronize_coprocessors(); return uPD96050::sr_read(); }
void NECDSP::sr_write(unsigned, uint8 data) { cpu.synchronize_coprocessors(); return uPD96050::sr_write(data); }
uint8 NECDSP::read(unsigned addr) {
cpu.synchronize_coprocessors();
if(addr & Select) {
return uPD96050::sr_read();
} else {
return uPD96050::dr_read();
}
}
uint8 NECDSP::dr_read(unsigned) { cpu.synchronize_coprocessors(); return uPD96050::dr_read(); }
void NECDSP::dr_write(unsigned, uint8 data) { cpu.synchronize_coprocessors(); return uPD96050::dr_write(data); }
void NECDSP::write(unsigned addr, uint8 data) {
cpu.synchronize_coprocessors();
if(addr & Select) {
return uPD96050::sr_write(data);
} else {
return uPD96050::dr_write(data);
}
}
uint8 NECDSP::dp_read(unsigned addr) { cpu.synchronize_coprocessors(); return uPD96050::dp_read(addr); }
void NECDSP::dp_write(unsigned addr, uint8 data) { cpu.synchronize_coprocessors(); return uPD96050::dp_write(addr, data); }
uint8 NECDSP::ram_read(unsigned addr) {
cpu.synchronize_coprocessors();
return uPD96050::dp_read(addr);
}
void NECDSP::ram_write(unsigned addr, uint8 data) {
cpu.synchronize_coprocessors();
return uPD96050::dp_write(addr, data);
}
void NECDSP::init() {
}

View File

@ -1,15 +1,14 @@
struct NECDSP : Processor::uPD96050, Coprocessor {
unsigned Select;
static void Enter();
void enter();
uint8 sr_read(unsigned);
void sr_write(unsigned, uint8 data);
uint8 read(unsigned addr);
void write(unsigned addr, uint8 data);
uint8 dr_read(unsigned);
void dr_write(unsigned, uint8 data);
uint8 dp_read(unsigned addr);
void dp_write(unsigned addr, uint8 data);
uint8 ram_read(unsigned addr);
void ram_write(unsigned addr, uint8 data);
void init();
void load();

View File

@ -43,8 +43,9 @@ unsigned Interface::group(unsigned id) {
case ID::ArmDSPDROM:
case ID::ArmDSPRAM:
case ID::HitachiDSPROM:
case ID::HitachiDSPDROM:
case ID::HitachiDSPRAM:
case ID::HitachiDSPDROM:
case ID::HitachiDSPDRAM:
case ID::Nec7725DSPPROM:
case ID::Nec7725DSPDROM:
case ID::Nec7725DSPRAM:
@ -130,13 +131,12 @@ void Interface::load(unsigned id, const stream &stream, const string &manifest)
for(unsigned n = 0; n < 16 * 1024; n++) armdsp.programRAM[n] = stream.read();
}
if(id == ID::HitachiDSPROM) {
hitachidsp.rom.read(stream);
}
if(id == ID::HitachiDSPROM) hitachidsp.rom.read(stream);
if(id == ID::HitachiDSPRAM) hitachidsp.ram.read(stream);
if(id == ID::HitachiDSPDROM) {
for(unsigned n = 0; n < 1024; n++) hitachidsp.dataROM[n] = stream.readl(3);
}
if(id == ID::HitachiDSPRAM) {
if(id == ID::HitachiDSPDRAM) {
for(unsigned n = 0; n < 3072; n++) hitachidsp.dataRAM[n] = stream.readl(1);
}
@ -215,11 +215,12 @@ void Interface::save(unsigned id, const stream &stream) {
for(unsigned n = 0; n < 16 * 1024; n++) stream.write(armdsp.programRAM[n]);
}
if(id == ID::HitachiDSPRAM) {
if(id == ID::HitachiDSPRAM) stream.write(hitachidsp.ram.data(), hitachidsp.ram.size());
if(id == ID::HitachiDSPDRAM) {
for(unsigned n = 0; n < 3072; n++) stream.writel(hitachidsp.dataRAM[n], 1);
}
if(id == ID::Nec96050DSPRAM) {
if(id == ID::Nec7725DSPRAM) {
for(unsigned n = 0; n < 256; n++) stream.writel(necdsp.dataRAM[n], 2);
}
if(id == ID::Nec96050DSPRAM) {
@ -351,11 +352,11 @@ void Interface::exportMemory() {
string pathname = {path(group(ID::ROM)), "debug/"};
directory::create(pathname);
file::write({pathname, "wram.rwm"}, cpu.wram, 128 * 1024);
file::write({pathname, "vram.rwm"}, ppu.vram, 64 * 1024);
file::write({pathname, "oam.rwm"}, ppu.oam, 544);
file::write({pathname, "cgram.rwm"}, ppu.cgram, 512);
file::write({pathname, "apuram.rwm"}, smp.apuram, 64 * 1024);
file::write({pathname, "work.ram"}, cpu.wram, 128 * 1024);
file::write({pathname, "video.ram"}, ppu.vram, 64 * 1024);
file::write({pathname, "sprite.ram"}, ppu.oam, 544);
file::write({pathname, "palette.ram"}, ppu.cgram, 512);
file::write({pathname, "apu.ram"}, smp.apuram, 64 * 1024);
}
Interface::Interface() {

View File

@ -36,8 +36,9 @@ struct ID {
ArmDSPRAM,
HitachiDSPROM,
HitachiDSPDROM,
HitachiDSPRAM,
HitachiDSPDROM,
HitachiDSPDRAM,
Nec7725DSPPROM,
Nec7725DSPDROM,

View File

@ -1,3 +1,5 @@
name := higan
processors := arm gsu hg51b lr35902 r6502 r65816 spc700 upd96050
include processor/Makefile
@ -6,7 +8,6 @@ include sfc/Makefile
include gb/Makefile
include gba/Makefile
# include nds/Makefile
name := higan
ui_objects := ui-ethos ui-configuration ui-interface ui-utility
ui_objects += ui-input ui-window ui-general ui-settings ui-tools
@ -73,7 +74,7 @@ else
endif
resource:
sourcery $(ui)/resource/resource.xml $(ui)/resource/resource.cpp $(ui)/resource/resource.hpp
sourcery $(ui)/resource/resource.bml $(ui)/resource/resource.cpp $(ui)/resource/resource.hpp
install:
ifeq ($(USER),root)
@ -86,7 +87,7 @@ else ifeq ($(platform),x)
mkdir -p ~/.config/$(name)
cp -R profile/* ~/.config/$(name)
cp data/cheats.xml ~/.config/$(name)/cheats.xml
cp data/cheats.bml ~/.config/$(name)/cheats.bml
chmod -R 777 ~/.config/$(name)
endif

View File

@ -0,0 +1,6 @@
resource name=resource
binary id=cabinet name=cabinet.png
binary id=folder name=folder.png
binary id=file name=file.png
binary id=home name=home.png
binary id=up name=up.png

View File

@ -1,8 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<resource name="resource">
<binary id="cabinet" name="cabinet.png"/>
<binary id="folder" name="folder.png"/>
<binary id="file" name="file.png"/>
<binary id="home" name="home.png"/>
<binary id="up" name="up.png"/>
</resource>

View File

@ -34,18 +34,16 @@ void CheatDatabase::findCodes() {
cheatList.reset();
cheat.reset();
string data;
data.readfile(application->path("cheats.xml"));
XML::Document document(data);
for(auto &node : document["database"]) {
auto document = Markup::Document(string::read(application->path("cheats.bml")));
for(auto &node : document) {
if(node.name != "cartridge") continue;
if(node["sha256"].data != sha256) continue;
if(node["sha256"].text() != sha256) continue;
setTitle(node["name"].data);
setTitle(node["name"].text());
for(auto &cheat : node) {
if(cheat.name != "cheat") continue;
cheatList.append(cheat["description"].data);
this->cheat.append({cheat["code"].data, cheat["description"].data});
cheatList.append(cheat["description"].text());
this->cheat.append({cheat["code"].text(), cheat["description"].text()});
}
setVisible();

View File

@ -125,16 +125,16 @@ void CheatEditor::updateDesc() {
}
bool CheatEditor::load(const string &filename) {
string data;
if(data.readfile(filename) == false) return false;
string data = string::read(filename);
if(data.empty()) return false;
unsigned n = 0;
XML::Document document(data);
auto document = Markup::Document(data);
for(auto &node : document["cartridge"]) {
if(node.name != "cheat") continue;
cheatList.setChecked(n, node["enable"].data == "true");
cheat[n].code = node["code"].data;
cheat[n].desc = node["description"].data;
cheatList.setChecked(n, node["enabled"].exists());
cheat[n].code = node["code"].text();
cheat[n].desc = node["description"].text();
if(++n >= Codes) break;
}
@ -160,15 +160,12 @@ bool CheatEditor::save(const string &filename) {
file fp;
if(fp.open(filename, file::mode::write) == false) return false;
fp.print("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
fp.print("<cartridge sha256=\"", system().sha256(), "\">\n");
fp.print("cartridge sha256:", system().sha256(), "\n");
for(unsigned n = 0; n <= lastSave; n++) {
fp.print(" <cheat enable=\"", cheatList.checked(n) ? "true" : "false", "\">\n");
fp.print(" <description><![CDATA[", cheat[n].desc, "]]></description>\n");
fp.print(" <code><![CDATA[", cheat[n].code, "]]></code>\n");
fp.print(" </cheat>\n");
fp.print(" cheat", cheatList.checked(n) ? " enabled\n" : "\n");
fp.print(" description:", cheat[n].desc, "\n");
fp.print(" code:", cheat[n].code, "\n");
}
fp.print("</cartridge>\n");
fp.close();
return true;

View File

@ -62,7 +62,7 @@ void Utility::loadMedia(Emulator::Interface *emulator, Emulator::Interface::Medi
if(this->pathname.size() == 0) this->pathname.append(pathname);
presentation->setSystemName(media.name);
load(Markup::Document(manifest)["release/information/title"].text());
load(Markup::Document(manifest)["information/title"].text());
}
//request from emulation core to load non-volatile media folder
@ -118,7 +118,7 @@ void Utility::load(string title) {
}
presentation->setTitle(title);
cheatEditor->load({pathname[0], "cheats.xml"});
cheatEditor->load({pathname[0], "cheats.bml"});
stateManager->load({pathname[0], "bsnes/states.bsa"}, 1);
system().paletteUpdate();
@ -133,7 +133,7 @@ void Utility::unload() {
if(application->active == nullptr) return;
if(tracerEnable) tracerToggle();
cheatEditor->save({pathname[0], "cheats.xml"});
cheatEditor->save({pathname[0], "cheats.bml"});
stateManager->save({pathname[0], "bsnes/states.bsa"}, 1);
system().unload();