mirror of
https://github.com/libretro/bsnes-libretro.git
synced 2024-11-24 01:19:50 +00:00
Update to v089r17 release.
byuu says: This implements the spec from the XML part 3 thread: http://board.byuu.org/viewtopic.php?f=16&t=2998 It's also propagated the changes to nall and purify, so you can test this one. This is basically it, after years of effort I feel I finally have a fully consistent and logical XML board format. The only things left to change will be: modifications if emulation turns out to be incorrect (eg we missed some MMIO mirrors, or mirrored too much), and new additions. And of course, I'm giving it a bit of time for good arguments against the format. Other than that, this release removes linear_vector and pointer_vector, as vector is better than linear_vector and I've never used pointer_vector. vector also gets move(), which is a way to use move-semantics across types. It lets you steal the underlying memory pool, effectively destroying the vector without a copy. This works really nicely with the move for read() functions to return vector<uint8> instead of taking (uint8_t*&, unsigned&) parameters.
This commit is contained in:
parent
c1318961d8
commit
87cb164f7c
@ -3,7 +3,7 @@
|
||||
|
||||
namespace Emulator {
|
||||
static const char Name[] = "bsnes";
|
||||
static const char Version[] = "089.16";
|
||||
static const char Version[] = "089.17";
|
||||
static const char Author[] = "byuu";
|
||||
static const char License[] = "GPLv3";
|
||||
}
|
||||
|
@ -4,7 +4,7 @@ struct CheatCode {
|
||||
unsigned comp;
|
||||
};
|
||||
|
||||
struct Cheat : public linear_vector<CheatCode> {
|
||||
struct Cheat : public vector<CheatCode> {
|
||||
static bool decode(const string &code, unsigned &addr, unsigned &data, unsigned &comp);
|
||||
|
||||
void synchronize();
|
||||
|
@ -4,7 +4,7 @@ struct CheatCode {
|
||||
unsigned comp;
|
||||
};
|
||||
|
||||
struct Cheat : public linear_vector<CheatCode> {
|
||||
struct Cheat : public vector<CheatCode> {
|
||||
static bool decode(const string &code, unsigned &addr, unsigned &data, unsigned &comp);
|
||||
|
||||
void synchronize();
|
||||
|
@ -1,6 +1,8 @@
|
||||
#ifndef NALL_ATOI_HPP
|
||||
#define NALL_ATOI_HPP
|
||||
|
||||
#include <nall/stdint.hpp>
|
||||
|
||||
namespace nall {
|
||||
|
||||
//note: this header is intended to form the base for user-defined literals;
|
||||
|
@ -122,419 +122,348 @@ SuperFamicomCartridge::SuperFamicomCartridge(const uint8_t *data, unsigned size)
|
||||
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 mode='linear' address='00-7f:8000-ffff'/>\n"
|
||||
" <map mode='linear' address='80-ff:8000-ffff'/>\n"
|
||||
" </rom>\n"
|
||||
" <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"
|
||||
" <map address='00-3f:6000-7fff'/>\n"
|
||||
" <map address='80-bf:6000-7fff'/>\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"
|
||||
);
|
||||
|
||||
else if(has_cx4) markup.append(
|
||||
" <rom name='program.rom' size='0x", hex(rom_size), "'/>\n"
|
||||
" <hitachidsp model='HG51B169' frequency='20000000' firmware='cx4.rom' sha256='ae8d4d1961b93421ff00b3caa1d0f0ce7783e749772a3369c36b3dbf0d37ef18'>\n"
|
||||
" <rom>\n"
|
||||
" <map mode='linear' address='00-7f:8000-ffff'/>\n"
|
||||
" <map mode='linear' address='80-ff:8000-ffff'/>\n"
|
||||
" </rom>\n"
|
||||
" <mmio>\n"
|
||||
" <map address='00-3f:6000-7fff'/>\n"
|
||||
" <map address='80-bf:6000-7fff'/>\n"
|
||||
" </mmio>\n"
|
||||
" <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"
|
||||
);
|
||||
|
||||
else if(has_spc7110) {
|
||||
markup.append(
|
||||
" <rom name='program.rom' size='0x", hex(rom_size), "'/>\n"
|
||||
" <ram name='save.ram' size='", hex(ram_size), "'/>\n"
|
||||
" <spc7110>\n"
|
||||
" <mmio>\n"
|
||||
" <map address='00-3f:4800-483f'/>\n"
|
||||
" <map address='80-bf:4800-483f'/>\n"
|
||||
" </mmio>\n"
|
||||
" <dcu>\n"
|
||||
" <map address='50:0000-ffff'/>\n"
|
||||
" </dcu>\n"
|
||||
" <mcu>\n"
|
||||
" <rom>\n"
|
||||
" <program offset='0x000000' size='0x100000'/>\n"
|
||||
" <data offset='0x100000' size='", hex(rom_size - 0x100000), "'/>\n"
|
||||
" <map address='00-0f:8000-ffff'/>\n"
|
||||
" <map address='80-bf:8000-ffff'/>\n"
|
||||
" <map address='c0-cf:0000-ffff'/>\n"
|
||||
" </rom>\n"
|
||||
" <ram>\n"
|
||||
" <map address='00-3f:6000-7fff'/>\n"
|
||||
" <map address='80-bf:6000-7fff'/>\n"
|
||||
" </ram>\n"
|
||||
" </mcu>\n"
|
||||
" </spc7110>\n"
|
||||
);
|
||||
if(has_spc7110rtc) markup.append(
|
||||
" <epsonrtc name='rtc.ram' size='0x10'>\n"
|
||||
" <map address='00-3f:4840-4842'/>\n"
|
||||
" <map address='80-bf:4840-4842'/>\n"
|
||||
" </epsonrtc>\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"
|
||||
);
|
||||
|
||||
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(mapper == LoROM) {
|
||||
markup.append(
|
||||
" <rom name='program.rom' size='0x", hex(rom_size), "'>\n"
|
||||
" <map mode='linear' address='00-7f:8000-ffff'/>\n"
|
||||
" <map mode='linear' address='80-ff:8000-ffff'/>\n"
|
||||
" </rom>\n"
|
||||
" <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"
|
||||
);
|
||||
if(ram_size > 0) markup.append(
|
||||
" <ram name='save.ram' size='0x", hex(ram_size), "'>\n"
|
||||
" <map mode='linear' address='20-3f:6000-7fff'/>\n"
|
||||
" <map mode='linear' address='a0-bf:6000-7fff'/>\n"
|
||||
" <map mode='linear' address='70-7f:", range, "'/>\n"
|
||||
" <map mode='linear' address='f0-ff:", range, "'/>\n"
|
||||
" </ram>\n"
|
||||
" <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"
|
||||
);
|
||||
}
|
||||
|
||||
else if(mapper == HiROM) {
|
||||
markup.append(
|
||||
" <rom name='program.rom' size='0x", hex(rom_size), "'>\n"
|
||||
" <map mode='shadow' address='00-3f:8000-ffff'/>\n"
|
||||
" <map mode='linear' address='40-7f:0000-ffff'/>\n"
|
||||
" <map mode='shadow' address='80-bf:8000-ffff'/>\n"
|
||||
" <map mode='linear' address='c0-ff:0000-ffff'/>\n"
|
||||
" </rom>\n"
|
||||
" <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"
|
||||
);
|
||||
if(ram_size > 0) markup.append(
|
||||
" <ram name='save.ram' size='0x", hex(ram_size), "'>\n"
|
||||
" <map mode='linear' address='20-3f:6000-7fff'/>\n"
|
||||
" <map mode='linear' address='a0-bf:6000-7fff'/>\n"
|
||||
" <map mode='linear' address='70-7f:", range, "'/>\n"
|
||||
" </ram>\n"
|
||||
" <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"
|
||||
);
|
||||
}
|
||||
|
||||
else if(mapper == ExLoROM) {
|
||||
markup.append(
|
||||
" <rom name='program.rom' size='0x", hex(rom_size), "'>\n"
|
||||
" <map mode='linear' address='00-3f:8000-ffff'/>\n"
|
||||
" <map mode='linear' address='40-7f:0000-ffff'/>\n"
|
||||
" <map mode='linear' address='80-bf:8000-ffff'/>\n"
|
||||
" </rom>\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-7f:0000-ffff' id='rom' mode='linear'/>\n"
|
||||
);
|
||||
if(ram_size > 0) markup.append(
|
||||
" <ram name='save.ram' size='0x", hex(ram_size), "'>\n"
|
||||
" <map mode='linear' address='20-3f:6000-7fff'/>\n"
|
||||
" <map mode='linear' address='a0-bf:6000-7fff'/>\n"
|
||||
" <map mode='linear' address='70-7f:0000-7fff'/>\n"
|
||||
" </ram>\n"
|
||||
" <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"
|
||||
);
|
||||
}
|
||||
|
||||
else if(mapper == ExHiROM) {
|
||||
markup.append(
|
||||
" <rom name='program.rom' size='0x", hex(rom_size), "'>\n"
|
||||
" <map mode='shadow' address='00-3f:8000-ffff' offset='0x400000'/>\n"
|
||||
" <map mode='linear' address='40-7f:0000-ffff' offset='0x400000'/>\n"
|
||||
" <map mode='shadow' address='80-bf:8000-ffff' offset='0x000000'/>\n"
|
||||
" <map mode='linear' address='c0-ff:0000-ffff' offset='0x000000'/>\n"
|
||||
" </rom>\n"
|
||||
" <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"
|
||||
);
|
||||
if(ram_size > 0) markup.append(
|
||||
" <ram name='save.ram' size='0x", hex(ram_size), "'>\n"
|
||||
" <map mode='linear' address='20-3f:6000-7fff'/>\n"
|
||||
" <map mode='linear' address='a0-bf:6000-7fff'/>\n"
|
||||
" <map mode='linear' address='70-7f:", range, "'/>\n"
|
||||
" </ram>\n"
|
||||
" <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"
|
||||
);
|
||||
}
|
||||
|
||||
else if(mapper == SuperFXROM) {
|
||||
markup.append(" <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(
|
||||
" <superfx revision='2'>\n"
|
||||
" <rom>\n"
|
||||
" <map mode='linear' address='00-3f:8000-ffff'/>\n"
|
||||
" <map mode='linear' address='40-5f:0000-ffff'/>\n"
|
||||
" <map mode='linear' address='80-bf:8000-ffff'/>\n"
|
||||
" <map mode='linear' address='c0-df:0000-ffff'/>\n"
|
||||
" </rom>\n"
|
||||
" <ram>\n"
|
||||
" <map mode='linear' address='00-3f:6000-7fff' size='0x2000'/>\n"
|
||||
" <map mode='linear' address='60-7f:0000-ffff'/>\n"
|
||||
" <map mode='linear' address='80-bf:6000-7fff' size='0x2000'/>\n"
|
||||
" <map mode='linear' address='e0-ff:0000-ffff'/>\n"
|
||||
" </ram>\n"
|
||||
" <mmio>\n"
|
||||
" <map address='00-3f:3000-32ff'/>\n"
|
||||
" <map address='80-bf:3000-32ff'/>\n"
|
||||
" </mmio>\n"
|
||||
" <map address='00-3f:3000-32ff' id='io'/>\n"
|
||||
" <map address='80-bf:3000-32ff' id='io'/>\n"
|
||||
" <rom name='program.rom' size='", 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"
|
||||
);
|
||||
if(ram_size > 0) markup.append(
|
||||
" <ram name='save.rwm' size='", 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"
|
||||
);
|
||||
markup.append(
|
||||
" </superfx>\n"
|
||||
);
|
||||
}
|
||||
|
||||
else if(mapper == SA1ROM) {
|
||||
markup.append(" <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(
|
||||
" <sa1>\n"
|
||||
" <mcu>\n"
|
||||
" <rom>\n"
|
||||
" <map mode='direct' address='00-3f:8000-ffff'/>\n"
|
||||
" <map mode='direct' address='80-bf:8000-ffff'/>\n"
|
||||
" <map mode='direct' address='c0-ff:0000-ffff'/>\n"
|
||||
" </rom>\n"
|
||||
" <ram>\n"
|
||||
" <map mode='direct' address='00-3f:6000-7fff'/>\n"
|
||||
" <map mode='direct' address='80-bf:6000-7fff'/>\n"
|
||||
" </ram>\n"
|
||||
" </mcu>\n"
|
||||
" <iram>\n"
|
||||
" <map mode='linear' address='00-3f:3000-37ff'/>\n"
|
||||
" <map mode='linear' address='80-bf:3000-37ff'/>\n"
|
||||
" </iram>\n"
|
||||
" <bwram>\n"
|
||||
" <map mode='linear' address='40-4f:0000-ffff'/>\n"
|
||||
" </bwram>\n"
|
||||
" <mmio>\n"
|
||||
" <map address='00-3f:2200-23ff'/>\n"
|
||||
" <map address='80-bf:2200-23ff'/>\n"
|
||||
" </mmio>\n"
|
||||
" <map address='00-3f:2200-23ff' id='io'/>\n"
|
||||
" <map address='80-bf:2200-23ff' id='io'/>\n"
|
||||
" <rom name='program.rom' size='", 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"
|
||||
);
|
||||
if(ram_size > 0) markup.append(
|
||||
" <bwram name='save.rwm' size='", 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"
|
||||
);
|
||||
markup.append(
|
||||
" </sa1>\n"
|
||||
);
|
||||
}
|
||||
|
||||
else if(mapper == BSCLoROM) markup.append(
|
||||
" <rom name='program.rom' size='0x", hex(rom_size), "'>\n"
|
||||
" <map mode='linear' address='00-1f:8000-ffff' offset='0x000000'/>\n"
|
||||
" <map mode='linear' address='20-3f:8000-ffff' offset='0x100000'/>\n"
|
||||
" <map mode='linear' address='80-9f:8000-ffff' offset='0x200000'/>\n"
|
||||
" <map mode='linear' address='a0-bf:8000-ffff' offset='0x100000'/>\n"
|
||||
" </rom>\n"
|
||||
" <ram name='save.ram' size='0x", hex(ram_size), "'>\n"
|
||||
" <map mode='linear' address='70-7f:0000-7fff'/>\n"
|
||||
" <map mode='linear' address='f0-ff:0000-7fff'/>\n"
|
||||
" </ram>\n"
|
||||
" <bsx>\n"
|
||||
" <slot>\n"
|
||||
" <map mode='linear' address='c0-ef:0000-ffff'/>\n"
|
||||
" </slot>\n"
|
||||
" </bsx>\n"
|
||||
" <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"
|
||||
);
|
||||
|
||||
else if(mapper == BSCHiROM) markup.append(
|
||||
" <rom name='program.rom' size='0x", hex(rom_size), "'>\n"
|
||||
" <map mode='shadow' address='00-1f:8000-ffff'/>\n"
|
||||
" <map mode='linear' address='40-5f:0000-ffff'/>\n"
|
||||
" <map mode='shadow' address='80-9f:8000-ffff'/>\n"
|
||||
" <map mode='linear' address='c0-df:0000-ffff'/>\n"
|
||||
" </rom>\n"
|
||||
" <ram name='save.ram' size='0x", hex(ram_size), "'>\n"
|
||||
" <map mode='linear' address='20-3f:6000-7fff'/>\n"
|
||||
" <map mode='linear' address='a0-bf:6000-7fff'/>\n"
|
||||
" </ram>\n"
|
||||
" <bsx>\n"
|
||||
" <slot>\n"
|
||||
" <map mode='shadow' address='20-3f:8000-ffff'/>\n"
|
||||
" <map mode='linear' address='60-7f:0000-ffff'/>\n"
|
||||
" <map mode='shadow' address='a0-bf:8000-ffff'/>\n"
|
||||
" <map mode='linear' address='e0-ff:0000-ffff'/>\n"
|
||||
" </slot>\n"
|
||||
" </bsx>\n"
|
||||
" <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"
|
||||
);
|
||||
|
||||
else if(mapper == BSXROM) markup.append(
|
||||
" <rom name='program.rom' size='0x", hex(rom_size), "'/>\n"
|
||||
" <ram name='save.ram' size='0x", hex(ram_size), "'/>\n"
|
||||
" <psram name='bsx.ram' size='0x40000'/>\n"
|
||||
" <bsx>\n"
|
||||
" <mcu>\n"
|
||||
" <map address='00-3f:8000-ffff'/>\n"
|
||||
" <map address='80-bf:8000-ffff'/>\n"
|
||||
" <map address='40-7f:0000-ffff'/>\n"
|
||||
" <map address='c0-ff:0000-ffff'/>\n"
|
||||
" <map address='20-3f:6000-7fff'/>\n"
|
||||
" </mcu>\n"
|
||||
" <mmio>\n"
|
||||
" <map address='00-3f:5000-5fff'/>\n"
|
||||
" <map address='80-bf:5000-5fff'/>\n"
|
||||
" </mmio>\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"
|
||||
);
|
||||
|
||||
else if(mapper == STROM) markup.append(
|
||||
" <rom name='program.rom' size='0x", hex(rom_size), "'>\n"
|
||||
" <map mode='linear' address='00-1f:8000-ffff'/>\n"
|
||||
" <map mode='linear' address='80-9f:8000-ffff'/>\n"
|
||||
" </rom>\n"
|
||||
" <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"
|
||||
" <rom>\n"
|
||||
" <map mode='linear' address='20-3f:8000-ffff'/>\n"
|
||||
" <map mode='linear' address='a0-bf:8000-ffff'/>\n"
|
||||
" </rom>\n"
|
||||
" <ram>\n"
|
||||
" <map mode='linear' address='60-63:8000-ffff'/>\n"
|
||||
" <map mode='linear' address='e0-e3:8000-ffff'/>\n"
|
||||
" </ram>\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"
|
||||
" <rom>\n"
|
||||
" <map mode='linear' address='40-5f:8000-ffff'/>\n"
|
||||
" <map mode='linear' address='c0-df:8000-ffff'/>\n"
|
||||
" </rom>\n"
|
||||
" <ram>\n"
|
||||
" <map mode='linear' address='70-73:8000-ffff'/>\n"
|
||||
" <map mode='linear' address='f0-f3:8000-ffff'/>\n"
|
||||
" </ram>\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"
|
||||
);
|
||||
|
||||
if(has_srtc) markup.append(
|
||||
" <sharprtc name='rtc.ram' size='0x10'>\n"
|
||||
" <map address='00-3f:2800-2801'/>\n"
|
||||
" <map address='80-bf:2800-2801'/>\n"
|
||||
" </sharprtc>\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"
|
||||
);
|
||||
|
||||
if(has_sdd1) markup.append(
|
||||
" <sdd1>\n"
|
||||
" <mcu>\n"
|
||||
" <map address='c0-ff:0000-ffff'/>\n"
|
||||
" </mcu>\n"
|
||||
" <mmio>\n"
|
||||
" <map address='00-3f:4800-4807'/>\n"
|
||||
" <map address='80-bf:4800-4807'/>\n"
|
||||
" </mmio>\n"
|
||||
" </sdd1>\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"
|
||||
);
|
||||
|
||||
if(has_obc1) markup.append(
|
||||
" <obc1>\n"
|
||||
" <map address='00-3f:6000-7fff'/>\n"
|
||||
" <map address='80-bf:6000-7fff'/>\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"
|
||||
);
|
||||
|
||||
if(has_dsp1) {
|
||||
//91e87d11e1c30d172556bed2211cce2efa94ba595f58c5d264809ef4d363a97b dsp1.rom
|
||||
markup.append(" <necdsp model='uPD7725' frequency='8000000' firmware='dsp1b.rom' sha256='d789cb3c36b05c0b23b6c6f23be7aa37c6e78b6ee9ceac8d2d2aa9d8c4d35fa9'>\n");
|
||||
markup.append(
|
||||
" <necdsp model='uPD7725' frequency='8000000'>\n"
|
||||
" <firmware name='dsp1b.rom' size='8192' sha256='d789cb3c36b05c0b23b6c6f23be7aa37c6e78b6ee9ceac8d2d2aa9d8c4d35fa9'/>\n"
|
||||
);
|
||||
if(dsp1_mapper == DSP1LoROM1MB) markup.append(
|
||||
" <dr>\n"
|
||||
" <map address='20-3f:8000-bfff'/>\n"
|
||||
" <map address='a0-bf:8000-bfff'/>\n"
|
||||
" </dr>\n"
|
||||
" <sr>\n"
|
||||
" <map address='20-3f:c000-ffff'/>\n"
|
||||
" <map address='a0-bf:c000-ffff'/>\n"
|
||||
" </sr>\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"
|
||||
);
|
||||
if(dsp1_mapper == DSP1LoROM2MB) markup.append(
|
||||
" <dr>\n"
|
||||
" <map address='60-6f:0000-3fff'/>\n"
|
||||
" <map address='e0-ef:0000-3fff'/>\n"
|
||||
" </dr>\n"
|
||||
" <sr>\n"
|
||||
" <map address='60-6f:4000-7fff'/>\n"
|
||||
" <map address='e0-ef:4000-7fff'/>\n"
|
||||
" </sr>\n"
|
||||
" <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"
|
||||
);
|
||||
if(dsp1_mapper == DSP1HiROM) markup.append(
|
||||
" <dr>\n"
|
||||
" <map address='00-1f:6000-6fff'/>\n"
|
||||
" <map address='80-9f:6000-6fff'/>\n"
|
||||
" </dr>\n"
|
||||
" <sr>\n"
|
||||
" <map address='00-1f:7000-7fff'/>\n"
|
||||
" <map address='80-9f:7000-7fff'/>\n"
|
||||
" </sr>\n"
|
||||
" <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"
|
||||
);
|
||||
markup.append(" </necdsp>\n");
|
||||
}
|
||||
|
||||
if(has_dsp2) markup.append(
|
||||
" <necdsp model='uPD7725' frequency='8000000' firmware='dsp2.rom' sha256='03ef4ef26c9f701346708cb5d07847b5203cf1b0818bf2930acd34510ffdd717'>\n"
|
||||
" <dr>\n"
|
||||
" <map address='20-3f:8000-bfff'/>\n"
|
||||
" <map address='a0-bf:8000-bfff'/>\n"
|
||||
" </dr>\n"
|
||||
" <sr>\n"
|
||||
" <map address='20-3f:c000-ffff'/>\n"
|
||||
" <map address='a0-bf:c000-ffff'/>\n"
|
||||
" </sr>\n"
|
||||
" <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"
|
||||
);
|
||||
|
||||
if(has_dsp3) markup.append(
|
||||
" <necdsp model='uPD7725' frequency='8000000' firmware='dsp3.rom' sha256='0971b08f396c32e61989d1067dddf8e4b14649d548b2188f7c541b03d7c69e4e'>\n"
|
||||
" <dr>\n"
|
||||
" <map address='20-3f:8000-bfff'/>\n"
|
||||
" <map address='a0-bf:8000-bfff'/>\n"
|
||||
" </dr>\n"
|
||||
" <sr>\n"
|
||||
" <map address='20-3f:c000-ffff'/>\n"
|
||||
" <map address='a0-bf:c000-ffff'/>\n"
|
||||
" </sr>\n"
|
||||
" <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"
|
||||
);
|
||||
|
||||
if(has_dsp4) markup.append(
|
||||
" <necdsp model='uPD7725' frequency='8000000' firmware='dsp4.rom' sha256='752d03b2d74441e430b7f713001fa241f8bbcfc1a0d890ed4143f174dbe031da'>\n"
|
||||
" <dr>\n"
|
||||
" <map address='30-3f:8000-bfff'/>\n"
|
||||
" <map address='b0-bf:8000-bfff'/>\n"
|
||||
" </dr>\n"
|
||||
" <sr>\n"
|
||||
" <map address='30-3f:c000-ffff'/>\n"
|
||||
" <map address='b0-bf:c000-ffff'/>\n"
|
||||
" </sr>\n"
|
||||
" <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"
|
||||
);
|
||||
|
||||
if(has_st010) markup.append(
|
||||
" <necdsp model='uPD96050' frequency='10000000' firmware='st010.rom' sha256='fa9bced838fedea11c6f6ace33d1878024bdd0d02cc9485899d0bdd4015ec24c'>\n"
|
||||
" <dr>\n"
|
||||
" <map address='60:0000'/>\n"
|
||||
" <map address='e0:0000'/>\n"
|
||||
" </dr>\n"
|
||||
" <sr>\n"
|
||||
" <map address='60:0001'/>\n"
|
||||
" <map address='e0:0001'/>\n"
|
||||
" </sr>\n"
|
||||
" <dp>\n"
|
||||
" <map address='68-6f:0000-0fff'/>\n"
|
||||
" <map address='e8-ef:0000-0fff'/>\n"
|
||||
" </dp>\n"
|
||||
" <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"
|
||||
);
|
||||
|
||||
if(has_st011) markup.append(
|
||||
" <necdsp model='uPD96050' frequency='15000000' firmware='st011.rom' sha256='8b2b3f3f3e6e29f4d21d8bc736b400bc988b7d2214ebee15643f01c1fee2f364'>\n"
|
||||
" <dr>\n"
|
||||
" <map address='60:0000'/>\n"
|
||||
" <map address='e0:0000'/>\n"
|
||||
" </dr>\n"
|
||||
" <sr>\n"
|
||||
" <map address='60:0001'/>\n"
|
||||
" <map address='e0:0001'/>\n"
|
||||
" </sr>\n"
|
||||
" <dp>\n"
|
||||
" <map address='68-6f:0000-0fff'/>\n"
|
||||
" <map address='e8-ef:0000-0fff'/>\n"
|
||||
" </dp>\n"
|
||||
" <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"
|
||||
);
|
||||
|
||||
if(has_st018) markup.append(
|
||||
" <armdsp firmware='st018.rom' frequency='21477272' sha256='6df209ab5d2524d1839c038be400ae5eb20dafc14a3771a3239cd9e8acd53806'>\n"
|
||||
" <map address='00-3f:3800-38ff'/>\n"
|
||||
" <map address='80-bf:3800-38ff'/>\n"
|
||||
" <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"
|
||||
);
|
||||
|
||||
|
56
bsnes/nall/nall.hpp
Executable file
56
bsnes/nall/nall.hpp
Executable file
@ -0,0 +1,56 @@
|
||||
#ifndef NALL_HPP
|
||||
#define NALL_HPP
|
||||
|
||||
//include the most common nall headers with one statement
|
||||
//does not include the most obscure components with high cost and low usage
|
||||
|
||||
#include <nall/platform.hpp>
|
||||
|
||||
#include <nall/algorithm.hpp>
|
||||
#include <nall/any.hpp>
|
||||
#include <nall/atoi.hpp>
|
||||
#include <nall/base64.hpp>
|
||||
#include <nall/bit.hpp>
|
||||
#include <nall/bmp.hpp>
|
||||
#include <nall/config.hpp>
|
||||
#include <nall/crc32.hpp>
|
||||
#include <nall/directory.hpp>
|
||||
#include <nall/dl.hpp>
|
||||
#include <nall/endian.hpp>
|
||||
#include <nall/file.hpp>
|
||||
#include <nall/filemap.hpp>
|
||||
#include <nall/function.hpp>
|
||||
#include <nall/gzip.hpp>
|
||||
#include <nall/http.hpp>
|
||||
#include <nall/image.hpp>
|
||||
#include <nall/inflate.hpp>
|
||||
#include <nall/interpolation.hpp>
|
||||
#include <nall/intrinsics.hpp>
|
||||
#include <nall/invoke.hpp>
|
||||
#include <nall/map.hpp>
|
||||
#include <nall/png.hpp>
|
||||
#include <nall/property.hpp>
|
||||
#include <nall/random.hpp>
|
||||
#include <nall/serializer.hpp>
|
||||
#include <nall/set.hpp>
|
||||
#include <nall/sha256.hpp>
|
||||
#include <nall/sort.hpp>
|
||||
#include <nall/stdint.hpp>
|
||||
#include <nall/stream.hpp>
|
||||
#include <nall/string.hpp>
|
||||
#include <nall/traits.hpp>
|
||||
#include <nall/utility.hpp>
|
||||
#include <nall/varint.hpp>
|
||||
#include <nall/vector.hpp>
|
||||
#include <nall/zip.hpp>
|
||||
|
||||
#if defined(PLATFORM_WINDOWS)
|
||||
#include <nall/windows/registry.hpp>
|
||||
#include <nall/windows/utf8.hpp>
|
||||
#endif
|
||||
|
||||
#if defined(PLATFORM_X)
|
||||
#include <nall/serial.hpp>
|
||||
#endif
|
||||
|
||||
#endif
|
@ -20,7 +20,9 @@ struct zipstream : memorystream {
|
||||
|
||||
for(auto &file : archive.file) {
|
||||
if(file.name.wildcard(filter)) {
|
||||
archive.extract(file, pdata, psize);
|
||||
auto buffer = archive.extract(file);
|
||||
psize = buffer.size();
|
||||
pdata = buffer.move();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -24,10 +24,18 @@ namespace nall {
|
||||
operator bool() const { return pool; }
|
||||
T* data() { return pool; }
|
||||
|
||||
bool empty() const { return pool == nullptr; }
|
||||
bool empty() const { return objectsize == 0; }
|
||||
unsigned size() const { return objectsize; }
|
||||
unsigned capacity() const { return poolsize; }
|
||||
|
||||
T* move() {
|
||||
T *result = data;
|
||||
pool = nullptr;
|
||||
poolsize = 0;
|
||||
objectsize = 0;
|
||||
return result;
|
||||
}
|
||||
|
||||
void reset() {
|
||||
if(pool) {
|
||||
for(unsigned n = 0; n < objectsize; n++) pool[n].~T();
|
||||
@ -191,293 +199,6 @@ namespace nall {
|
||||
reset();
|
||||
}
|
||||
};
|
||||
|
||||
//linear_vector
|
||||
//memory: O(capacity * 2)
|
||||
//
|
||||
//linear_vector uses placement new + manual destructor calls to create a
|
||||
//contiguous block of memory for all objects. accessing individual elements
|
||||
//is fast, though resizing the array incurs significant overhead.
|
||||
//reserve() overhead is reduced from quadratic time to amortized constant time
|
||||
//by resizing twice as much as requested.
|
||||
//
|
||||
//if objects hold memory address references to themselves (introspection), a
|
||||
//valid copy constructor will be needed to keep pointers valid.
|
||||
|
||||
#define NALL_DEPRECATED
|
||||
#if defined(NALL_DEPRECATED)
|
||||
template<typename T> struct linear_vector {
|
||||
protected:
|
||||
T *pool;
|
||||
unsigned poolsize, objectsize;
|
||||
|
||||
public:
|
||||
unsigned size() const { return objectsize; }
|
||||
unsigned capacity() const { return poolsize; }
|
||||
|
||||
void reset() {
|
||||
if(pool) {
|
||||
for(unsigned i = 0; i < objectsize; i++) pool[i].~T();
|
||||
free(pool);
|
||||
}
|
||||
pool = nullptr;
|
||||
poolsize = 0;
|
||||
objectsize = 0;
|
||||
}
|
||||
|
||||
void reserve(unsigned newsize) {
|
||||
newsize = bit::round(newsize); //round to nearest power of two (for amortized growth)
|
||||
|
||||
T *poolcopy = (T*)calloc(newsize, sizeof(T));
|
||||
for(unsigned i = 0; i < min(objectsize, newsize); i++) new(poolcopy + i) T(pool[i]);
|
||||
for(unsigned i = 0; i < objectsize; i++) pool[i].~T();
|
||||
free(pool);
|
||||
pool = poolcopy;
|
||||
poolsize = newsize;
|
||||
objectsize = min(objectsize, newsize);
|
||||
}
|
||||
|
||||
void resize(unsigned newsize) {
|
||||
if(newsize > poolsize) reserve(newsize);
|
||||
|
||||
if(newsize < objectsize) {
|
||||
//vector is shrinking; destroy excess objects
|
||||
for(unsigned i = newsize; i < objectsize; i++) pool[i].~T();
|
||||
} else if(newsize > objectsize) {
|
||||
//vector is expanding; allocate new objects
|
||||
for(unsigned i = objectsize; i < newsize; i++) new(pool + i) T;
|
||||
}
|
||||
|
||||
objectsize = newsize;
|
||||
}
|
||||
|
||||
void append(const T data) {
|
||||
if(objectsize + 1 > poolsize) reserve(objectsize + 1);
|
||||
new(pool + objectsize++) T(data);
|
||||
}
|
||||
|
||||
template<typename U> void insert(unsigned index, const U list) {
|
||||
linear_vector<T> merged;
|
||||
for(unsigned i = 0; i < index; i++) merged.append(pool[i]);
|
||||
for(auto &item : list) merged.append(item);
|
||||
for(unsigned i = index; i < objectsize; i++) merged.append(pool[i]);
|
||||
operator=(merged);
|
||||
}
|
||||
|
||||
void insert(unsigned index, const T item) {
|
||||
insert(index, linear_vector<T>{ item });
|
||||
}
|
||||
|
||||
void remove(unsigned index, unsigned count = 1) {
|
||||
for(unsigned i = index; count + i < objectsize; i++) {
|
||||
pool[i] = pool[count + i];
|
||||
}
|
||||
if(count + index >= objectsize) resize(index); //every element >= index was removed
|
||||
else resize(objectsize - count);
|
||||
}
|
||||
|
||||
linear_vector() : pool(nullptr), poolsize(0), objectsize(0) {
|
||||
}
|
||||
|
||||
linear_vector(std::initializer_list<T> list) : pool(nullptr), poolsize(0), objectsize(0) {
|
||||
for(const T *p = list.begin(); p != list.end(); ++p) append(*p);
|
||||
}
|
||||
|
||||
~linear_vector() {
|
||||
reset();
|
||||
}
|
||||
|
||||
//copy
|
||||
inline linear_vector<T>& operator=(const linear_vector<T> &source) {
|
||||
reset();
|
||||
reserve(source.capacity());
|
||||
resize(source.size());
|
||||
for(unsigned i = 0; i < source.size(); i++) operator[](i) = source.operator[](i);
|
||||
return *this;
|
||||
}
|
||||
|
||||
linear_vector(const linear_vector<T> &source) : pool(nullptr), poolsize(0), objectsize(0) {
|
||||
operator=(source);
|
||||
}
|
||||
|
||||
//move
|
||||
inline linear_vector<T>& operator=(linear_vector<T> &&source) {
|
||||
reset();
|
||||
pool = source.pool;
|
||||
poolsize = source.poolsize;
|
||||
objectsize = source.objectsize;
|
||||
source.pool = nullptr;
|
||||
source.reset();
|
||||
return *this;
|
||||
}
|
||||
|
||||
linear_vector(linear_vector<T> &&source) : pool(nullptr), poolsize(0), objectsize(0) {
|
||||
operator=(std::move(source));
|
||||
}
|
||||
|
||||
//index
|
||||
inline T& operator[](unsigned index) {
|
||||
if(index >= objectsize) resize(index + 1);
|
||||
return pool[index];
|
||||
}
|
||||
|
||||
inline const T& operator[](unsigned index) const {
|
||||
if(index >= objectsize) throw "vector[] out of bounds";
|
||||
return pool[index];
|
||||
}
|
||||
|
||||
//iteration
|
||||
T* begin() { return &pool[0]; }
|
||||
T* end() { return &pool[objectsize]; }
|
||||
const T* begin() const { return &pool[0]; }
|
||||
const T* end() const { return &pool[objectsize]; }
|
||||
};
|
||||
|
||||
//pointer_vector
|
||||
//memory: O(1)
|
||||
//
|
||||
//pointer_vector keeps an array of pointers to each vector object. this adds
|
||||
//significant overhead to individual accesses, but allows for optimal memory
|
||||
//utilization.
|
||||
//
|
||||
//by guaranteeing that the base memory address of each objects never changes,
|
||||
//this avoids the need for an object to have a valid copy constructor.
|
||||
|
||||
template<typename T> struct pointer_vector {
|
||||
protected:
|
||||
T **pool;
|
||||
unsigned poolsize, objectsize;
|
||||
|
||||
public:
|
||||
unsigned size() const { return objectsize; }
|
||||
unsigned capacity() const { return poolsize; }
|
||||
|
||||
void reset() {
|
||||
if(pool) {
|
||||
for(unsigned i = 0; i < objectsize; i++) { if(pool[i]) delete pool[i]; }
|
||||
free(pool);
|
||||
}
|
||||
pool = nullptr;
|
||||
poolsize = 0;
|
||||
objectsize = 0;
|
||||
}
|
||||
|
||||
void reserve(unsigned newsize) {
|
||||
newsize = bit::round(newsize); //round to nearest power of two (for amortized growth)
|
||||
|
||||
for(unsigned i = newsize; i < objectsize; i++) {
|
||||
if(pool[i]) { delete pool[i]; pool[i] = 0; }
|
||||
}
|
||||
|
||||
pool = (T**)realloc(pool, newsize * sizeof(T*));
|
||||
for(unsigned i = poolsize; i < newsize; i++) pool[i] = 0;
|
||||
poolsize = newsize;
|
||||
objectsize = min(objectsize, newsize);
|
||||
}
|
||||
|
||||
void resize(unsigned newsize) {
|
||||
if(newsize > poolsize) reserve(newsize);
|
||||
|
||||
for(unsigned i = newsize; i < objectsize; i++) {
|
||||
if(pool[i]) { delete pool[i]; pool[i] = 0; }
|
||||
}
|
||||
|
||||
objectsize = newsize;
|
||||
}
|
||||
|
||||
void append(const T data) {
|
||||
if(objectsize + 1 > poolsize) reserve(objectsize + 1);
|
||||
pool[objectsize++] = new T(data);
|
||||
}
|
||||
|
||||
template<typename U> void insert(unsigned index, const U list) {
|
||||
pointer_vector<T> merged;
|
||||
for(unsigned i = 0; i < index; i++) merged.append(*pool[i]);
|
||||
for(auto &item : list) merged.append(item);
|
||||
for(unsigned i = index; i < objectsize; i++) merged.append(*pool[i]);
|
||||
operator=(merged);
|
||||
}
|
||||
|
||||
void insert(unsigned index, const T item) {
|
||||
insert(index, pointer_vector<T>{ item });
|
||||
}
|
||||
|
||||
void remove(unsigned index, unsigned count = 1) {
|
||||
for(unsigned i = index; count + i < objectsize; i++) {
|
||||
*pool[i] = *pool[count + i];
|
||||
}
|
||||
if(count + index >= objectsize) resize(index); //every element >= index was removed
|
||||
else resize(objectsize - count);
|
||||
}
|
||||
|
||||
pointer_vector() : pool(nullptr), poolsize(0), objectsize(0) {
|
||||
}
|
||||
|
||||
pointer_vector(std::initializer_list<T> list) : pool(nullptr), poolsize(0), objectsize(0) {
|
||||
for(const T *p = list.begin(); p != list.end(); ++p) append(*p);
|
||||
}
|
||||
|
||||
~pointer_vector() {
|
||||
reset();
|
||||
}
|
||||
|
||||
//copy
|
||||
inline pointer_vector<T>& operator=(const pointer_vector<T> &source) {
|
||||
reset();
|
||||
reserve(source.capacity());
|
||||
resize(source.size());
|
||||
for(unsigned i = 0; i < source.size(); i++) operator[](i) = source.operator[](i);
|
||||
return *this;
|
||||
}
|
||||
|
||||
pointer_vector(const pointer_vector<T> &source) : pool(nullptr), poolsize(0), objectsize(0) {
|
||||
operator=(source);
|
||||
}
|
||||
|
||||
//move
|
||||
inline pointer_vector<T>& operator=(pointer_vector<T> &&source) {
|
||||
reset();
|
||||
pool = source.pool;
|
||||
poolsize = source.poolsize;
|
||||
objectsize = source.objectsize;
|
||||
source.pool = nullptr;
|
||||
source.reset();
|
||||
return *this;
|
||||
}
|
||||
|
||||
pointer_vector(pointer_vector<T> &&source) : pool(nullptr), poolsize(0), objectsize(0) {
|
||||
operator=(std::move(source));
|
||||
}
|
||||
|
||||
//index
|
||||
inline T& operator[](unsigned index) {
|
||||
if(index >= objectsize) resize(index + 1);
|
||||
if(!pool[index]) pool[index] = new T;
|
||||
return *pool[index];
|
||||
}
|
||||
|
||||
inline const T& operator[](unsigned index) const {
|
||||
if(index >= objectsize || !pool[index]) throw "vector[] out of bounds";
|
||||
return *pool[index];
|
||||
}
|
||||
|
||||
//iteration
|
||||
struct iterator {
|
||||
bool operator!=(const iterator &source) const { return index != source.index; }
|
||||
T& operator*() { return vector.operator[](index); }
|
||||
iterator& operator++() { index++; return *this; }
|
||||
iterator(const pointer_vector &vector, unsigned index) : vector(vector), index(index) {}
|
||||
private:
|
||||
const pointer_vector &vector;
|
||||
unsigned index;
|
||||
};
|
||||
|
||||
iterator begin() { return iterator(*this, 0); }
|
||||
iterator end() { return iterator(*this, objectsize); }
|
||||
const iterator begin() const { return iterator(*this, 0); }
|
||||
const iterator end() const { return iterator(*this, objectsize); }
|
||||
};
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -3,13 +3,13 @@
|
||||
<bsx>
|
||||
<rom name="program.rom" size="0x100000"/>
|
||||
<ram name="save.rwm" size="0x8000"/>
|
||||
<psram name="flash.rwm" size="0x40000"/>
|
||||
<map address="00-3f:8000-ffff"/>
|
||||
<map address="80-bf:8000-ffff"/>
|
||||
<map address="40-7f:0000-ffff"/>
|
||||
<map address="c0-ff:0000-ffff"/>
|
||||
<map address="20-3f:6000-7fff"/>
|
||||
<map address="00-3f:5000-5fff"/>
|
||||
<map address="80-bf:5000-5fff"/>
|
||||
<psram name="bsx.rwm" size="0x40000"/>
|
||||
<map address="00-3f:8000-ffff" id="rom"/>
|
||||
<map address="80-bf:8000-ffff" id="rom"/>
|
||||
<map address="40-7f:0000-ffff" id="rom"/>
|
||||
<map address="c0-ff:0000-ffff" id="rom"/>
|
||||
<map address="20-3f:6000-7fff" id="ram"/>
|
||||
<map address="00-3f:5000-5fff" id="io"/>
|
||||
<map address="80-bf:5000-5fff" id="io"/>
|
||||
</bsx>
|
||||
</cartridge>
|
||||
|
@ -1,29 +1,20 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<cartridge region="NTSC">
|
||||
<rom name="program.rom" size="0x40000">
|
||||
<map mode="linear" address="00-1f:8000-ffff"/>
|
||||
<map mode="linear" address="80-9f:8000-ffff"/>
|
||||
</rom>
|
||||
<rom name="program.rom" size="0x40000"/>
|
||||
<map address="00-1f:8000-ffff" id="rom" mode="linear"/>
|
||||
<map address="80-9f:8000-ffff" id="rom" mode="linear"/>
|
||||
<sufamiturbo>
|
||||
<slot id="A">
|
||||
<rom>
|
||||
<map mode="linear" address="20-3f:8000-ffff"/>
|
||||
<map mode="linear" address="a0-bf:8000-ffff"/>
|
||||
</rom>
|
||||
<ram>
|
||||
<map mode="linear" address="60-63:8000-ffff"/>
|
||||
<map mode="linear" address="e0-e3:8000-ffff"/>
|
||||
</ram>
|
||||
<map address="20-3f:8000-ffff" id="rom" mode="linear"/>
|
||||
<map address="a0-bf:8000-ffff" id="rom" mode="linear"/>
|
||||
<map address="60-63:8000-ffff" id="ram" mode="linear"/>
|
||||
<map address="e0-e3:8000-ffff" id="ram" mode="linear"/>
|
||||
</slot>
|
||||
<slot id="B">
|
||||
<rom>
|
||||
<map mode="linear" address="40-5f:8000-ffff"/>
|
||||
<map mode="linear" address="c0-df:8000-ffff"/>
|
||||
</rom>
|
||||
<ram>
|
||||
<map mode="linear" address="70-73:8000-ffff"/>
|
||||
<map mode="linear" address="f0-f3:8000-ffff"/>
|
||||
</ram>
|
||||
<map address="40-5f:8000-ffff" id="rom" mode="linear"/>
|
||||
<map address="c0-df:8000-ffff" id="rom" mode="linear"/>
|
||||
<map address="70-73:8000-ffff" id="ram" mode="linear"/>
|
||||
<map address="f0-f3:8000-ffff" id="ram" mode="linear"/>
|
||||
</slot>
|
||||
</sufamiturbo>
|
||||
</cartridge>
|
||||
|
@ -1,12 +1,11 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<cartridge region="NTSC">
|
||||
<rom name="program.rom" size="0x80000">
|
||||
<map mode="linear" address="00-7f:8000-ffff"/>
|
||||
<map mode="linear" address="80-ff:8000-ffff"/>
|
||||
</rom>
|
||||
<rom name="program.rom" size="0x80000"/>
|
||||
<map address="00-7f:8000-ffff" id="rom" mode="linear"/>
|
||||
<map address="80-ff:8000-ffff" id="rom" mode="linear"/>
|
||||
<icd2 revision="1">
|
||||
<firmware name="boot.rom" size="256" sha256="0e4ddff32fc9d1eeaae812a157dd246459b00c9e14f2f61751f661f32361e360"/>
|
||||
<map address="00-3f:6000-7fff"/>
|
||||
<map address="80-bf:6000-7fff"/>
|
||||
<map address="00-3f:6000-7fff" id="io"/>
|
||||
<map address="80-bf:6000-7fff" id="io"/>
|
||||
</icd2>
|
||||
</cartridge>
|
||||
|
File diff suppressed because one or more lines are too long
@ -78,11 +78,10 @@ private:
|
||||
void parse_markup_map(Mapping&, XML::Node&);
|
||||
void parse_markup_memory(MappedRAM&, XML::Node&, unsigned id, bool writable);
|
||||
|
||||
void parse_markup_rom(XML::Node&);
|
||||
void parse_markup_ram(XML::Node&);
|
||||
void parse_markup_psram(XML::Node&);
|
||||
void parse_markup_cartridge(XML::Node&);
|
||||
void parse_markup_icd2(XML::Node&);
|
||||
void parse_markup_bsx(XML::Node&);
|
||||
void parse_markup_bsxslot(XML::Node&);
|
||||
void parse_markup_sufamiturbo(XML::Node&);
|
||||
void parse_markup_nss(XML::Node&);
|
||||
void parse_markup_sa1(XML::Node&);
|
||||
|
@ -7,11 +7,10 @@ void Cartridge::parse_markup(const char *markup) {
|
||||
auto &cartridge = document["cartridge"];
|
||||
region = cartridge["region"].data != "PAL" ? Region::NTSC : Region::PAL;
|
||||
|
||||
parse_markup_rom(cartridge["rom"]);
|
||||
parse_markup_ram(cartridge["ram"]);
|
||||
parse_markup_psram(cartridge["psram"]);
|
||||
parse_markup_cartridge(cartridge);
|
||||
parse_markup_icd2(cartridge["icd2"]);
|
||||
parse_markup_bsx(cartridge["bsx"]);
|
||||
parse_markup_bsxslot(cartridge["bsxslot"]);
|
||||
parse_markup_sufamiturbo(cartridge["sufamiturbo"]);
|
||||
parse_markup_nss(cartridge["nss"]);
|
||||
parse_markup_sa1(cartridge["sa1"]);
|
||||
@ -74,39 +73,35 @@ void Cartridge::parse_markup_memory(MappedRAM &ram, XML::Node &node, unsigned id
|
||||
|
||||
//
|
||||
|
||||
void Cartridge::parse_markup_rom(XML::Node &root) {
|
||||
void Cartridge::parse_markup_cartridge(XML::Node &root) {
|
||||
if(root.exists() == false) return;
|
||||
parse_markup_memory(rom, root, ID::ROM, false);
|
||||
|
||||
parse_markup_memory(rom, root["rom"], ID::ROM, false);
|
||||
parse_markup_memory(ram, root["ram"], ID::RAM, true);
|
||||
|
||||
for(auto &node : root) {
|
||||
if(node.name != "map") continue;
|
||||
Mapping m(rom);
|
||||
parse_markup_map(m, node);
|
||||
if(m.size == 0) m.size = rom.size();
|
||||
mapping.append(m);
|
||||
|
||||
if(node["id"].data == "rom") {
|
||||
Mapping m(rom);
|
||||
parse_markup_map(m, node);
|
||||
if(m.size == 0) m.size = rom.size();
|
||||
mapping.append(m);
|
||||
}
|
||||
|
||||
if(node["id"].data == "ram") {
|
||||
Mapping m(ram);
|
||||
parse_markup_map(m, node);
|
||||
if(m.size == 0) m.size = ram.size();
|
||||
mapping.append(m);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Cartridge::parse_markup_ram(XML::Node &root) {
|
||||
if(root.exists() == false) return;
|
||||
parse_markup_memory(ram, root, ID::RAM, true);
|
||||
|
||||
for(auto &node : root) {
|
||||
Mapping m(ram);
|
||||
parse_markup_map(m, node);
|
||||
if(m.size == 0) m.size = ram.size();
|
||||
mapping.append(m);
|
||||
}
|
||||
}
|
||||
|
||||
void Cartridge::parse_markup_psram(XML::Node &root) {
|
||||
if(root.exists() == false) return;
|
||||
parse_markup_memory(bsxcartridge.psram, root, ID::BsxPSRAM, true);
|
||||
}
|
||||
|
||||
void Cartridge::parse_markup_icd2(XML::Node &root) {
|
||||
if(root.exists() == false) return;
|
||||
has_gb_slot = true;
|
||||
icd2.revision = max(1, numeral(root["revision"].data));
|
||||
|
||||
interface->loadRequest(ID::SuperGameBoy, "Game Boy", "gb");
|
||||
|
||||
@ -116,43 +111,61 @@ void Cartridge::parse_markup_icd2(XML::Node &root) {
|
||||
interface->notify("Error: required firmware ", firmware, " not found.\n");
|
||||
}
|
||||
|
||||
icd2.revision = max(1, numeral(root["revision"].data));
|
||||
|
||||
for(auto &node : root) {
|
||||
if(node.name != "map") continue;
|
||||
Mapping m({&ICD2::read, &icd2}, {&ICD2::write, &icd2});
|
||||
parse_markup_map(m, node);
|
||||
mapping.append(m);
|
||||
|
||||
if(node["id"].data == "io") {
|
||||
Mapping m({&ICD2::read, &icd2}, {&ICD2::write, &icd2});
|
||||
parse_markup_map(m, node);
|
||||
mapping.append(m);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Cartridge::parse_markup_bsx(XML::Node &root) {
|
||||
if(root.exists() == false) return;
|
||||
has_bs_cart = root["map"].exists();
|
||||
has_bs_cart = true;
|
||||
has_bs_slot = true;
|
||||
|
||||
interface->loadRequest(ID::Satellaview, "BS-X Satellaview", "bs");
|
||||
|
||||
if(has_bs_cart) {
|
||||
parse_markup_memory(bsxcartridge.rom, root["rom"], ID::BsxROM, false);
|
||||
parse_markup_memory(bsxcartridge.ram, root["ram"], ID::BsxRAM, true);
|
||||
parse_markup_memory(bsxcartridge.psram, root["psram"], ID::BsxPSRAM, true);
|
||||
}
|
||||
|
||||
for(auto &node : root["slot"]) {
|
||||
if(node.name != "map") continue;
|
||||
if(bsxflash.memory.size() == 0) continue;
|
||||
|
||||
Mapping m(bsxflash.memory);
|
||||
parse_markup_map(m, node);
|
||||
mapping.append(m);
|
||||
}
|
||||
parse_markup_memory(bsxcartridge.rom, root["rom"], ID::BsxROM, false);
|
||||
parse_markup_memory(bsxcartridge.ram, root["ram"], ID::BsxRAM, true);
|
||||
parse_markup_memory(bsxcartridge.psram, root["psram"], ID::BsxPSRAM, true);
|
||||
|
||||
for(auto &node : root) {
|
||||
if(node.name != "map") continue;
|
||||
Mapping m({&BSXCartridge::mcu_read, &bsxcartridge}, {&BSXCartridge::mcu_write, &bsxcartridge});
|
||||
parse_markup_map(m, node);
|
||||
mapping.append(m);
|
||||
|
||||
if(node["id"].data == "rom" || node["id"].data == "ram") {
|
||||
Mapping m({&BSXCartridge::mcu_read, &bsxcartridge}, {&BSXCartridge::mcu_write, &bsxcartridge});
|
||||
parse_markup_map(m, node);
|
||||
mapping.append(m);
|
||||
}
|
||||
|
||||
if(node["id"].data == "io") {
|
||||
Mapping m({&BSXCartridge::mmio_read, &bsxcartridge}, {&BSXCartridge::mmio_write, &bsxcartridge});
|
||||
parse_markup_map(m, node);
|
||||
mapping.append(m);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Cartridge::parse_markup_bsxslot(XML::Node &root) {
|
||||
if(root.exists() == false) return;
|
||||
has_bs_slot = true;
|
||||
|
||||
interface->loadRequest(ID::Satellaview, "BS-X Satellaview", "bs");
|
||||
|
||||
for(auto &node : root) {
|
||||
if(node.name != "map") continue;
|
||||
|
||||
if(node["id"].data == "rom") {
|
||||
if(bsxflash.memory.size() == 0) continue;
|
||||
|
||||
Mapping m(bsxflash.memory);
|
||||
parse_markup_map(m, node);
|
||||
mapping.append(m);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -166,31 +179,28 @@ void Cartridge::parse_markup_sufamiturbo(XML::Node &root) {
|
||||
for(auto &slot : root) {
|
||||
if(slot.name != "slot") continue;
|
||||
bool slotid = slot["id"].data == "A" ? 0 : slot["id"].data == "B" ? 1 : 0;
|
||||
|
||||
for(auto &node : slot) {
|
||||
if(node.name == "rom") {
|
||||
for(auto &leaf : node) {
|
||||
if(leaf.name != "map") continue;
|
||||
SuperFamicom::Memory &memory = slotid == 0 ? sufamiturbo.slotA.rom : sufamiturbo.slotB.rom;
|
||||
if(memory.size() == 0) continue;
|
||||
if(node.name != "map") continue;
|
||||
|
||||
Mapping m(memory);
|
||||
parse_markup_map(m, leaf);
|
||||
if(m.size == 0) m.size = memory.size();
|
||||
if(m.size) mapping.append(m);
|
||||
}
|
||||
if(node["id"].data == "rom") {
|
||||
SuperFamicom::Memory &memory = slotid == 0 ? sufamiturbo.slotA.rom : sufamiturbo.slotB.rom;
|
||||
if(memory.size() == 0) continue;
|
||||
|
||||
Mapping m(memory);
|
||||
parse_markup_map(m, node);
|
||||
if(m.size == 0) m.size = memory.size();
|
||||
if(m.size) mapping.append(m);
|
||||
}
|
||||
if(node.name == "ram") {
|
||||
unsigned ram_size = numeral(node["size"].data);
|
||||
for(auto &leaf : node) {
|
||||
if(leaf.name != "map") continue;
|
||||
SuperFamicom::Memory &memory = slotid == 0 ? sufamiturbo.slotA.ram : sufamiturbo.slotB.ram;
|
||||
if(memory.size() == 0) continue;
|
||||
|
||||
Mapping m(memory);
|
||||
parse_markup_map(m, leaf);
|
||||
if(m.size == 0) m.size = memory.size();
|
||||
if(m.size) mapping.append(m);
|
||||
}
|
||||
if(node["id"].data == "ram") {
|
||||
SuperFamicom::Memory &memory = slotid == 0 ? sufamiturbo.slotA.ram : sufamiturbo.slotB.ram;
|
||||
if(memory.size() == 0) continue;
|
||||
|
||||
Mapping m(memory);
|
||||
parse_markup_map(m, node);
|
||||
if(m.size == 0) m.size = memory.size();
|
||||
if(m.size) mapping.append(m);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -203,9 +213,12 @@ void Cartridge::parse_markup_nss(XML::Node &root) {
|
||||
|
||||
for(auto &node : root) {
|
||||
if(node.name != "map") continue;
|
||||
Mapping m({&NSS::read, &nss}, {&NSS::write, &nss});
|
||||
parse_markup_map(m, node);
|
||||
mapping.append(m);
|
||||
|
||||
if(node["id"].data == "io") {
|
||||
Mapping m({&NSS::read, &nss}, {&NSS::write, &nss});
|
||||
parse_markup_map(m, node);
|
||||
mapping.append(m);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -214,34 +227,36 @@ void Cartridge::parse_markup_sa1(XML::Node &root) {
|
||||
has_sa1 = true;
|
||||
|
||||
parse_markup_memory(sa1.rom, root["rom"], ID::SA1ROM, false);
|
||||
for(auto &node : root["rom"]) {
|
||||
if(node.name != "map") continue;
|
||||
Mapping m({&SA1::mmc_read, &sa1}, {&SA1::mmc_write, &sa1});
|
||||
parse_markup_map(m, node);
|
||||
mapping.append(m);
|
||||
}
|
||||
|
||||
parse_markup_memory(sa1.iram, root["iram"], ID::SA1IRAM, true);
|
||||
for(auto &node : root["iram"]) {
|
||||
if(node.name != "map") continue;
|
||||
Mapping m({&SA1::mmc_read, &sa1}, {&SA1::mmc_write, &sa1});
|
||||
parse_markup_map(m, node);
|
||||
mapping.append(m);
|
||||
}
|
||||
|
||||
parse_markup_memory(sa1.bwram, root["bwram"], ID::SA1BWRAM, true);
|
||||
for(auto &node : root["bwram"]) {
|
||||
if(node.name != "map") continue;
|
||||
Mapping m({&SA1::mmc_read, &sa1}, {&SA1::mmc_write, &sa1});
|
||||
parse_markup_map(m, node);
|
||||
mapping.append(m);
|
||||
}
|
||||
|
||||
for(auto &node : root) {
|
||||
if(node.name != "map") continue;
|
||||
Mapping m({&SA1::mmio_read, &sa1}, {&SA1::mmio_write, &sa1});
|
||||
parse_markup_map(m, node);
|
||||
mapping.append(m);
|
||||
|
||||
if(node["id"].data == "io") {
|
||||
Mapping m({&SA1::mmio_read, &sa1}, {&SA1::mmio_write, &sa1});
|
||||
parse_markup_map(m, node);
|
||||
mapping.append(m);
|
||||
}
|
||||
|
||||
if(node["id"].data == "rom") {
|
||||
Mapping m({&SA1::mmcrom_read, &sa1}, {&SA1::mmcrom_write, &sa1});
|
||||
parse_markup_map(m, node);
|
||||
mapping.append(m);
|
||||
}
|
||||
|
||||
if(node["id"].data == "iram") {
|
||||
Mapping m(sa1.cpuiram);
|
||||
parse_markup_map(m, node);
|
||||
if(m.size == 0) m.size = sa1.cpuiram.size();
|
||||
mapping.append(m);
|
||||
}
|
||||
|
||||
if(node["id"].data == "bwram") {
|
||||
Mapping m({&SA1::mmcbwram_read, &sa1}, {&SA1::mmcbwram_write, &sa1});
|
||||
parse_markup_map(m, node);
|
||||
mapping.append(m);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -250,27 +265,29 @@ void Cartridge::parse_markup_superfx(XML::Node &root) {
|
||||
has_superfx = true;
|
||||
|
||||
parse_markup_memory(superfx.rom, root["rom"], ID::SuperFXROM, false);
|
||||
for(auto &node : root["rom"]) {
|
||||
if(node.name != "map") continue;
|
||||
Mapping m(superfx.cpurom);
|
||||
parse_markup_map(m, node);
|
||||
mapping.append(m);
|
||||
}
|
||||
|
||||
parse_markup_memory(superfx.ram, root["ram"], ID::SuperFXRAM, true);
|
||||
for(auto &node : root["ram"]) {
|
||||
if(node.name != "map") continue;
|
||||
Mapping m(superfx.cpuram);
|
||||
parse_markup_map(m, node);
|
||||
if(m.size == 0) m.size = superfx.ram.size();
|
||||
mapping.append(m);
|
||||
}
|
||||
|
||||
for(auto &node : root) {
|
||||
if(node.name != "map") continue;
|
||||
Mapping m({&SuperFX::mmio_read, &superfx}, {&SuperFX::mmio_write, &superfx});
|
||||
parse_markup_map(m, node);
|
||||
mapping.append(m);
|
||||
|
||||
if(node["id"].data == "io") {
|
||||
Mapping m({&SuperFX::mmio_read, &superfx}, {&SuperFX::mmio_write, &superfx});
|
||||
parse_markup_map(m, node);
|
||||
mapping.append(m);
|
||||
}
|
||||
|
||||
if(node["id"].data == "rom") {
|
||||
Mapping m(superfx.cpurom);
|
||||
parse_markup_map(m, node);
|
||||
mapping.append(m);
|
||||
}
|
||||
|
||||
if(node["id"].data == "ram") {
|
||||
Mapping m(superfx.cpuram);
|
||||
parse_markup_map(m, node);
|
||||
if(m.size == 0) m.size = superfx.ram.size();
|
||||
mapping.append(m);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -285,9 +302,12 @@ void Cartridge::parse_markup_armdsp(XML::Node &root) {
|
||||
|
||||
for(auto &node : root) {
|
||||
if(node.name != "map") continue;
|
||||
Mapping m({&ArmDSP::mmio_read, &armdsp}, {&ArmDSP::mmio_write, &armdsp});
|
||||
parse_markup_map(m, node);
|
||||
mapping.append(m);
|
||||
|
||||
if(node["id"].data == "io") {
|
||||
Mapping m({&ArmDSP::mmio_read, &armdsp}, {&ArmDSP::mmio_write, &armdsp});
|
||||
parse_markup_map(m, node);
|
||||
mapping.append(m);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -305,18 +325,21 @@ void Cartridge::parse_markup_hitachidsp(XML::Node &root) {
|
||||
interface->loadRequest(ID::HitachiDSP, firmware);
|
||||
|
||||
parse_markup_memory(hitachidsp.rom, root["rom"], ID::HitachiDSPROM, false);
|
||||
for(auto &node : root["rom"]) {
|
||||
if(node.name != "map") continue;
|
||||
Mapping m({&HitachiDSP::rom_read, &hitachidsp}, {&HitachiDSP::rom_write, &hitachidsp});
|
||||
parse_markup_map(m, node);
|
||||
mapping.append(m);
|
||||
}
|
||||
|
||||
for(auto &node : root) {
|
||||
if(node.name != "map") continue;
|
||||
Mapping m({&HitachiDSP::dsp_read, &hitachidsp}, {&HitachiDSP::dsp_write, &hitachidsp});
|
||||
parse_markup_map(m, node);
|
||||
mapping.append(m);
|
||||
|
||||
if(node["id"].data == "io") {
|
||||
Mapping m({&HitachiDSP::dsp_read, &hitachidsp}, {&HitachiDSP::dsp_write, &hitachidsp});
|
||||
parse_markup_map(m, node);
|
||||
mapping.append(m);
|
||||
}
|
||||
|
||||
if(node["id"].data == "rom") {
|
||||
Mapping m({&HitachiDSP::rom_read, &hitachidsp}, {&HitachiDSP::rom_write, &hitachidsp});
|
||||
parse_markup_map(m, node);
|
||||
mapping.append(m);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -347,25 +370,26 @@ void Cartridge::parse_markup_necdsp(XML::Node &root) {
|
||||
memory.append({ID::NecDSPRAM, name});
|
||||
}
|
||||
|
||||
for(auto &node : root["ram"]) {
|
||||
for(auto &node : root) {
|
||||
if(node.name != "map") continue;
|
||||
Mapping m({&NECDSP::dp_read, &necdsp}, {&NECDSP::dp_write, &necdsp});
|
||||
parse_markup_map(m, node);
|
||||
mapping.append(m);
|
||||
}
|
||||
|
||||
for(auto &node : root["dr"]) {
|
||||
if(node.name != "map") continue;
|
||||
Mapping m({&NECDSP::dr_read, &necdsp}, {&NECDSP::dr_write, &necdsp});
|
||||
parse_markup_map(m, node);
|
||||
mapping.append(m);
|
||||
}
|
||||
if(node["id"].data == "dr") {
|
||||
Mapping m({&NECDSP::dr_read, &necdsp}, {&NECDSP::dr_write, &necdsp});
|
||||
parse_markup_map(m, node);
|
||||
mapping.append(m);
|
||||
}
|
||||
|
||||
for(auto &node : root["sr"]) {
|
||||
if(node.name != "map") continue;
|
||||
Mapping m({&NECDSP::sr_read, &necdsp}, {&NECDSP::sr_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});
|
||||
parse_markup_map(m, node);
|
||||
mapping.append(m);
|
||||
}
|
||||
|
||||
if(node["id"].data == "ram") {
|
||||
Mapping m({&NECDSP::dp_read, &necdsp}, {&NECDSP::dp_write, &necdsp});
|
||||
parse_markup_map(m, node);
|
||||
mapping.append(m);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -379,9 +403,12 @@ void Cartridge::parse_markup_epsonrtc(XML::Node &root) {
|
||||
|
||||
for(auto &node : root) {
|
||||
if(node.name != "map") continue;
|
||||
Mapping m({&EpsonRTC::read, &epsonrtc}, {&EpsonRTC::write, &epsonrtc});
|
||||
parse_markup_map(m, node);
|
||||
mapping.append(m);
|
||||
|
||||
if(node["id"].data == "io") {
|
||||
Mapping m({&EpsonRTC::read, &epsonrtc}, {&EpsonRTC::write, &epsonrtc});
|
||||
parse_markup_map(m, node);
|
||||
mapping.append(m);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -395,9 +422,12 @@ void Cartridge::parse_markup_sharprtc(XML::Node &root) {
|
||||
|
||||
for(auto &node : root) {
|
||||
if(node.name != "map") continue;
|
||||
Mapping m({&SharpRTC::read, &sharprtc}, {&SharpRTC::write, &sharprtc});
|
||||
parse_markup_map(m, node);
|
||||
mapping.append(m);
|
||||
|
||||
if(node["id"].data == "io") {
|
||||
Mapping m({&SharpRTC::read, &sharprtc}, {&SharpRTC::write, &sharprtc});
|
||||
parse_markup_map(m, node);
|
||||
mapping.append(m);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -405,28 +435,30 @@ void Cartridge::parse_markup_spc7110(XML::Node &root) {
|
||||
if(root.exists() == false) return;
|
||||
has_spc7110 = true;
|
||||
|
||||
parse_markup_memory(spc7110.prom, root["rom"]["program"], ID::SPC7110PROM, false);
|
||||
parse_markup_memory(spc7110.drom, root["rom"]["data"], ID::SPC7110DROM, false);
|
||||
for(auto &node : root["rom"]) {
|
||||
if(node.name != "map") continue;
|
||||
Mapping m({&SPC7110::mcurom_read, &spc7110}, {&SPC7110::mcurom_write, &spc7110});
|
||||
parse_markup_map(m, node);
|
||||
mapping.append(m);
|
||||
}
|
||||
|
||||
parse_markup_memory(spc7110.prom, root["prom"], ID::SPC7110PROM, false);
|
||||
parse_markup_memory(spc7110.drom, root["drom"], ID::SPC7110DROM, false);
|
||||
parse_markup_memory(spc7110.ram, root["ram"], ID::SPC7110RAM, true);
|
||||
for(auto &node : root["ram"]) {
|
||||
if(node.name != "map") continue;
|
||||
Mapping m({&SPC7110::mcuram_read, &spc7110}, {&SPC7110::mcuram_write, &spc7110});
|
||||
parse_markup_map(m, node);
|
||||
mapping.append(m);
|
||||
}
|
||||
|
||||
for(auto &node : root) {
|
||||
if(node.name != "map") continue;
|
||||
Mapping m({&SPC7110::read, &spc7110}, {&SPC7110::write, &spc7110});
|
||||
parse_markup_map(m, node);
|
||||
mapping.append(m);
|
||||
|
||||
if(node["id"].data == "io") {
|
||||
Mapping m({&SPC7110::read, &spc7110}, {&SPC7110::write, &spc7110});
|
||||
parse_markup_map(m, node);
|
||||
mapping.append(m);
|
||||
}
|
||||
|
||||
if(node["id"].data == "rom") {
|
||||
Mapping m({&SPC7110::mcurom_read, &spc7110}, {&SPC7110::mcurom_write, &spc7110});
|
||||
parse_markup_map(m, node);
|
||||
mapping.append(m);
|
||||
}
|
||||
|
||||
if(node["id"].data == "ram") {
|
||||
Mapping m({&SPC7110::mcuram_read, &spc7110}, {&SPC7110::mcuram_write, &spc7110});
|
||||
parse_markup_map(m, node);
|
||||
mapping.append(m);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -435,26 +467,28 @@ void Cartridge::parse_markup_sdd1(XML::Node &root) {
|
||||
has_sdd1 = true;
|
||||
|
||||
parse_markup_memory(sdd1.rom, root["rom"], ID::SDD1ROM, false);
|
||||
for(auto &node : root["rom"]) {
|
||||
if(node.name != "map") continue;
|
||||
Mapping m({&SDD1::mcu_read, &sdd1}, {&SDD1::mcu_write, &sdd1});
|
||||
parse_markup_map(m, node);
|
||||
mapping.append(m);
|
||||
}
|
||||
|
||||
parse_markup_memory(sdd1.ram, root["ram"], ID::SDD1RAM, true);
|
||||
for(auto &node : root["ram"]) {
|
||||
if(node.name != "map") continue;
|
||||
Mapping m({&SDD1::mcu_read, &sdd1}, {&SDD1::mcu_write, &sdd1});
|
||||
parse_markup_map(m, node);
|
||||
mapping.append(m);
|
||||
}
|
||||
|
||||
for(auto &node : root) {
|
||||
if(node.name != "map") continue;
|
||||
Mapping m({&SDD1::read, &sdd1}, {&SDD1::write, &sdd1});
|
||||
parse_markup_map(m, node);
|
||||
mapping.append(m);
|
||||
|
||||
if(node["id"].data == "io") {
|
||||
Mapping m({&SDD1::read, &sdd1}, {&SDD1::write, &sdd1});
|
||||
parse_markup_map(m, node);
|
||||
mapping.append(m);
|
||||
}
|
||||
|
||||
if(node["id"].data == "rom") {
|
||||
Mapping m({&SDD1::mcurom_read, &sdd1}, {&SDD1::mcurom_write, &sdd1});
|
||||
parse_markup_map(m, node);
|
||||
mapping.append(m);
|
||||
}
|
||||
|
||||
if(node["id"].data == "ram") {
|
||||
Mapping m({&SDD1::mcuram_read, &sdd1}, {&SDD1::mcuram_write, &sdd1});
|
||||
parse_markup_map(m, node);
|
||||
mapping.append(m);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -463,11 +497,15 @@ void Cartridge::parse_markup_obc1(XML::Node &root) {
|
||||
has_obc1 = true;
|
||||
|
||||
parse_markup_memory(obc1.ram, root["ram"], ID::OBC1RAM, true);
|
||||
for(auto &node : root["ram"]) {
|
||||
|
||||
for(auto &node : root) {
|
||||
if(node.name != "map") continue;
|
||||
Mapping m({&OBC1::read, &obc1}, {&OBC1::write, &obc1});
|
||||
parse_markup_map(m, node);
|
||||
mapping.append(m);
|
||||
|
||||
if(node["id"].data == "io") {
|
||||
Mapping m({&OBC1::read, &obc1}, {&OBC1::write, &obc1});
|
||||
parse_markup_map(m, node);
|
||||
mapping.append(m);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -477,9 +515,12 @@ void Cartridge::parse_markup_msu1(XML::Node &root) {
|
||||
|
||||
for(auto &node : root) {
|
||||
if(node.name != "map") continue;
|
||||
Mapping m({&MSU1::mmio_read, &msu1}, {&MSU1::mmio_write, &msu1});
|
||||
parse_markup_map(m, node);
|
||||
mapping.append(m);
|
||||
|
||||
if(node["id"].data == "io") {
|
||||
Mapping m({&MSU1::mmio_read, &msu1}, {&MSU1::mmio_write, &msu1});
|
||||
parse_markup_map(m, node);
|
||||
mapping.append(m);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -42,11 +42,6 @@ void BSXCartridge::memory_write(Memory &memory, unsigned addr, uint8 data) {
|
||||
|
||||
//mcu_access() allows mcu_read() and mcu_write() to share decoding logic
|
||||
uint8 BSXCartridge::mcu_access(bool write, unsigned addr, uint8 data) {
|
||||
if((addr & 0x40f000) == 0x005000) { //$00-3f|80-bf:5000-5fff
|
||||
if(write == 0) return mmio_read(addr);
|
||||
if(write == 1) return mmio_write(addr, data), 0;
|
||||
}
|
||||
|
||||
if((addr & 0xe08000) == 0x008000) { //$00-1f:8000-ffff
|
||||
if(r07 == 1) {
|
||||
addr = ((addr & 0x1f0000) >> 1) | (addr & 0x7fff);
|
||||
|
@ -6,11 +6,11 @@ uint8 SA1::bus_read(unsigned addr) {
|
||||
}
|
||||
|
||||
if((addr & 0x408000) == 0x008000) { //$00-3f|80-bf:8000-ffff
|
||||
return mmc_read(addr);
|
||||
return mmcrom_read(addr);
|
||||
}
|
||||
|
||||
if((addr & 0xc00000) == 0xc00000) { //$c0-ff:0000-ffff
|
||||
return mmc_read(addr);
|
||||
return mmcrom_read(addr);
|
||||
}
|
||||
|
||||
if((addr & 0x40e000) == 0x006000) { //$00-3f|80-bf:6000-7fff
|
||||
@ -74,11 +74,11 @@ void SA1::bus_write(unsigned addr, uint8 data) {
|
||||
//these ports.
|
||||
uint8 SA1::vbr_read(unsigned addr) {
|
||||
if((addr & 0x408000) == 0x008000) { //$00-3f|80-bf:8000-ffff
|
||||
return mmc_read(addr);
|
||||
return mmcrom_read(addr);
|
||||
}
|
||||
|
||||
if((addr & 0xc00000) == 0xc00000) { //$c0-ff:0000-ffff
|
||||
return mmc_read(addr);
|
||||
return mmcrom_read(addr);
|
||||
}
|
||||
|
||||
if((addr & 0x40e000) == 0x006000) { //$00-3f|80-bf:6000-7fff
|
||||
@ -119,21 +119,7 @@ void SA1::op_write(unsigned addr, uint8 data) {
|
||||
bus_write(addr, data);
|
||||
}
|
||||
|
||||
uint8 SA1::mmc_read(unsigned addr) {
|
||||
if((addr & 0x40f800) == 0x003000) { //$00-3f|80-bf:3000-37ff
|
||||
return cpuiram.read(addr & 0x07ff);
|
||||
}
|
||||
|
||||
if((addr & 0x40e000) == 0x006000) { //$00-3f|80-bf:6000-7fff
|
||||
cpu.synchronize_coprocessors();
|
||||
addr = bus.mirror(mmio.sbm * 0x2000 + (addr & 0x1fff), cpubwram.size());
|
||||
return cpubwram.read(addr);
|
||||
}
|
||||
|
||||
if((addr & 0xf00000) == 0x400000) { //$40-4f:0000-ffff
|
||||
return cpubwram.read(addr & 0x0fffff);
|
||||
}
|
||||
|
||||
uint8 SA1::mmcrom_read(unsigned addr) {
|
||||
if((addr & 0xffffe0) == 0x00ffe0) {
|
||||
if(addr == 0xffea && sa1.mmio.cpu_nvsw) return sa1.mmio.snv >> 0;
|
||||
if(addr == 0xffeb && sa1.mmio.cpu_nvsw) return sa1.mmio.snv >> 8;
|
||||
@ -188,11 +174,24 @@ uint8 SA1::mmc_read(unsigned addr) {
|
||||
return 0x00;
|
||||
}
|
||||
|
||||
void SA1::mmc_write(unsigned addr, uint8 data) {
|
||||
if((addr & 0x40f800) == 0x003000) { //$00-3f|80-bf:3000-37ff
|
||||
return cpuiram.write(addr & 0x07ff, data);
|
||||
void SA1::mmcrom_write(unsigned addr, uint8 data) {
|
||||
}
|
||||
|
||||
uint8 SA1::mmcbwram_read(unsigned addr) {
|
||||
if((addr & 0x40e000) == 0x006000) { //$00-3f|80-bf:6000-7fff
|
||||
cpu.synchronize_coprocessors();
|
||||
addr = bus.mirror(mmio.sbm * 0x2000 + (addr & 0x1fff), cpubwram.size());
|
||||
return cpubwram.read(addr);
|
||||
}
|
||||
|
||||
if((addr & 0xf00000) == 0x400000) { //$40-4f:0000-ffff
|
||||
return cpubwram.read(addr & 0x0fffff);
|
||||
}
|
||||
|
||||
return cpu.regs.mdr;
|
||||
}
|
||||
|
||||
void SA1::mmcbwram_write(unsigned addr, uint8 data) {
|
||||
if((addr & 0x40e000) == 0x006000) { //$00-3f|80-bf:6000-7fff
|
||||
cpu.synchronize_coprocessors();
|
||||
addr = bus.mirror(mmio.sbm * 0x2000 + (addr & 0x1fff), cpubwram.size());
|
||||
|
@ -6,8 +6,11 @@ alwaysinline void op_io();
|
||||
alwaysinline uint8 op_read(unsigned addr);
|
||||
alwaysinline void op_write(unsigned addr, uint8 data);
|
||||
|
||||
uint8 mmc_read(unsigned addr);
|
||||
void mmc_write(unsigned addr, uint8 data);
|
||||
uint8 mmcrom_read(unsigned addr);
|
||||
void mmcrom_write(unsigned addr, uint8 data);
|
||||
|
||||
uint8 mmcbwram_read(unsigned addr);
|
||||
void mmcbwram_write(unsigned addr, uint8 data);
|
||||
|
||||
uint8 mmc_sa1_read(unsigned addr);
|
||||
void mmc_sa1_write(unsigned addr, uint8 data);
|
||||
|
@ -108,15 +108,7 @@ uint8 SDD1::mmc_read(unsigned addr) {
|
||||
//
|
||||
//the actual S-DD1 transfer can occur on any channel, but it is most likely limited to
|
||||
//one transfer per $420b write (for spooling purposes). however, this is not known for certain.
|
||||
uint8 SDD1::mcu_read(unsigned addr) {
|
||||
if((addr & 0x60e000) == 0x006000) { //$00-3f|80-bf:6000-7fff
|
||||
return ram.read(addr & 0x1fff);
|
||||
}
|
||||
|
||||
if((addr & 0xf08000) == 0x700000) { //$70-7f:0000-7fff
|
||||
return ram.read(addr & 0x1fff);
|
||||
}
|
||||
|
||||
uint8 SDD1::mcurom_read(unsigned addr) {
|
||||
if((addr & 0x408000) == 0x008000) { //$00-3f|80-bf:8000-ffff
|
||||
addr = ((addr & 0x7f0000) >> 1) | (addr & 0x7fff);
|
||||
return rom.read(addr);
|
||||
@ -152,7 +144,22 @@ uint8 SDD1::mcu_read(unsigned addr) {
|
||||
return mmc_read(addr);
|
||||
}
|
||||
|
||||
void SDD1::mcu_write(unsigned addr, uint8 data) {
|
||||
void SDD1::mcurom_write(unsigned addr, uint8 data) {
|
||||
}
|
||||
|
||||
uint8 SDD1::mcuram_read(unsigned addr) {
|
||||
if((addr & 0x60e000) == 0x006000) { //$00-3f|80-bf:6000-7fff
|
||||
return ram.read(addr & 0x1fff);
|
||||
}
|
||||
|
||||
if((addr & 0xf08000) == 0x700000) { //$70-7f:0000-7fff
|
||||
return ram.read(addr & 0x1fff);
|
||||
}
|
||||
|
||||
return cpu.regs.mdr;
|
||||
}
|
||||
|
||||
void SDD1::mcuram_write(unsigned addr, uint8 data) {
|
||||
if((addr & 0x60e000) == 0x006000) { //$00-3f|80-bf:6000-7fff
|
||||
return ram.write(addr & 0x1fff, data);
|
||||
}
|
||||
|
@ -12,8 +12,12 @@ struct SDD1 {
|
||||
void write(unsigned addr, uint8 data);
|
||||
|
||||
uint8 mmc_read(unsigned addr);
|
||||
uint8 mcu_read(unsigned addr);
|
||||
void mcu_write(unsigned addr, uint8 data);
|
||||
|
||||
uint8 mcurom_read(unsigned addr);
|
||||
void mcurom_write(unsigned addr, uint8 data);
|
||||
|
||||
uint8 mcuram_read(unsigned addr);
|
||||
void mcuram_write(unsigned addr, uint8 data);
|
||||
|
||||
void serialize(serializer&);
|
||||
|
||||
|
@ -1,6 +1,8 @@
|
||||
#ifndef NALL_ATOI_HPP
|
||||
#define NALL_ATOI_HPP
|
||||
|
||||
#include <nall/stdint.hpp>
|
||||
|
||||
namespace nall {
|
||||
|
||||
//note: this header is intended to form the base for user-defined literals;
|
||||
|
@ -122,419 +122,348 @@ SuperFamicomCartridge::SuperFamicomCartridge(const uint8_t *data, unsigned size)
|
||||
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 mode='linear' address='00-7f:8000-ffff'/>\n"
|
||||
" <map mode='linear' address='80-ff:8000-ffff'/>\n"
|
||||
" </rom>\n"
|
||||
" <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"
|
||||
" <map address='00-3f:6000-7fff'/>\n"
|
||||
" <map address='80-bf:6000-7fff'/>\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"
|
||||
);
|
||||
|
||||
else if(has_cx4) markup.append(
|
||||
" <rom name='program.rom' size='0x", hex(rom_size), "'/>\n"
|
||||
" <hitachidsp model='HG51B169' frequency='20000000' firmware='cx4.rom' sha256='ae8d4d1961b93421ff00b3caa1d0f0ce7783e749772a3369c36b3dbf0d37ef18'>\n"
|
||||
" <rom>\n"
|
||||
" <map mode='linear' address='00-7f:8000-ffff'/>\n"
|
||||
" <map mode='linear' address='80-ff:8000-ffff'/>\n"
|
||||
" </rom>\n"
|
||||
" <mmio>\n"
|
||||
" <map address='00-3f:6000-7fff'/>\n"
|
||||
" <map address='80-bf:6000-7fff'/>\n"
|
||||
" </mmio>\n"
|
||||
" <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"
|
||||
);
|
||||
|
||||
else if(has_spc7110) {
|
||||
markup.append(
|
||||
" <rom name='program.rom' size='0x", hex(rom_size), "'/>\n"
|
||||
" <ram name='save.ram' size='", hex(ram_size), "'/>\n"
|
||||
" <spc7110>\n"
|
||||
" <mmio>\n"
|
||||
" <map address='00-3f:4800-483f'/>\n"
|
||||
" <map address='80-bf:4800-483f'/>\n"
|
||||
" </mmio>\n"
|
||||
" <dcu>\n"
|
||||
" <map address='50:0000-ffff'/>\n"
|
||||
" </dcu>\n"
|
||||
" <mcu>\n"
|
||||
" <rom>\n"
|
||||
" <program offset='0x000000' size='0x100000'/>\n"
|
||||
" <data offset='0x100000' size='", hex(rom_size - 0x100000), "'/>\n"
|
||||
" <map address='00-0f:8000-ffff'/>\n"
|
||||
" <map address='80-bf:8000-ffff'/>\n"
|
||||
" <map address='c0-cf:0000-ffff'/>\n"
|
||||
" </rom>\n"
|
||||
" <ram>\n"
|
||||
" <map address='00-3f:6000-7fff'/>\n"
|
||||
" <map address='80-bf:6000-7fff'/>\n"
|
||||
" </ram>\n"
|
||||
" </mcu>\n"
|
||||
" </spc7110>\n"
|
||||
);
|
||||
if(has_spc7110rtc) markup.append(
|
||||
" <epsonrtc name='rtc.ram' size='0x10'>\n"
|
||||
" <map address='00-3f:4840-4842'/>\n"
|
||||
" <map address='80-bf:4840-4842'/>\n"
|
||||
" </epsonrtc>\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"
|
||||
);
|
||||
|
||||
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(mapper == LoROM) {
|
||||
markup.append(
|
||||
" <rom name='program.rom' size='0x", hex(rom_size), "'>\n"
|
||||
" <map mode='linear' address='00-7f:8000-ffff'/>\n"
|
||||
" <map mode='linear' address='80-ff:8000-ffff'/>\n"
|
||||
" </rom>\n"
|
||||
" <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"
|
||||
);
|
||||
if(ram_size > 0) markup.append(
|
||||
" <ram name='save.ram' size='0x", hex(ram_size), "'>\n"
|
||||
" <map mode='linear' address='20-3f:6000-7fff'/>\n"
|
||||
" <map mode='linear' address='a0-bf:6000-7fff'/>\n"
|
||||
" <map mode='linear' address='70-7f:", range, "'/>\n"
|
||||
" <map mode='linear' address='f0-ff:", range, "'/>\n"
|
||||
" </ram>\n"
|
||||
" <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"
|
||||
);
|
||||
}
|
||||
|
||||
else if(mapper == HiROM) {
|
||||
markup.append(
|
||||
" <rom name='program.rom' size='0x", hex(rom_size), "'>\n"
|
||||
" <map mode='shadow' address='00-3f:8000-ffff'/>\n"
|
||||
" <map mode='linear' address='40-7f:0000-ffff'/>\n"
|
||||
" <map mode='shadow' address='80-bf:8000-ffff'/>\n"
|
||||
" <map mode='linear' address='c0-ff:0000-ffff'/>\n"
|
||||
" </rom>\n"
|
||||
" <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"
|
||||
);
|
||||
if(ram_size > 0) markup.append(
|
||||
" <ram name='save.ram' size='0x", hex(ram_size), "'>\n"
|
||||
" <map mode='linear' address='20-3f:6000-7fff'/>\n"
|
||||
" <map mode='linear' address='a0-bf:6000-7fff'/>\n"
|
||||
" <map mode='linear' address='70-7f:", range, "'/>\n"
|
||||
" </ram>\n"
|
||||
" <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"
|
||||
);
|
||||
}
|
||||
|
||||
else if(mapper == ExLoROM) {
|
||||
markup.append(
|
||||
" <rom name='program.rom' size='0x", hex(rom_size), "'>\n"
|
||||
" <map mode='linear' address='00-3f:8000-ffff'/>\n"
|
||||
" <map mode='linear' address='40-7f:0000-ffff'/>\n"
|
||||
" <map mode='linear' address='80-bf:8000-ffff'/>\n"
|
||||
" </rom>\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-7f:0000-ffff' id='rom' mode='linear'/>\n"
|
||||
);
|
||||
if(ram_size > 0) markup.append(
|
||||
" <ram name='save.ram' size='0x", hex(ram_size), "'>\n"
|
||||
" <map mode='linear' address='20-3f:6000-7fff'/>\n"
|
||||
" <map mode='linear' address='a0-bf:6000-7fff'/>\n"
|
||||
" <map mode='linear' address='70-7f:0000-7fff'/>\n"
|
||||
" </ram>\n"
|
||||
" <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"
|
||||
);
|
||||
}
|
||||
|
||||
else if(mapper == ExHiROM) {
|
||||
markup.append(
|
||||
" <rom name='program.rom' size='0x", hex(rom_size), "'>\n"
|
||||
" <map mode='shadow' address='00-3f:8000-ffff' offset='0x400000'/>\n"
|
||||
" <map mode='linear' address='40-7f:0000-ffff' offset='0x400000'/>\n"
|
||||
" <map mode='shadow' address='80-bf:8000-ffff' offset='0x000000'/>\n"
|
||||
" <map mode='linear' address='c0-ff:0000-ffff' offset='0x000000'/>\n"
|
||||
" </rom>\n"
|
||||
" <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"
|
||||
);
|
||||
if(ram_size > 0) markup.append(
|
||||
" <ram name='save.ram' size='0x", hex(ram_size), "'>\n"
|
||||
" <map mode='linear' address='20-3f:6000-7fff'/>\n"
|
||||
" <map mode='linear' address='a0-bf:6000-7fff'/>\n"
|
||||
" <map mode='linear' address='70-7f:", range, "'/>\n"
|
||||
" </ram>\n"
|
||||
" <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"
|
||||
);
|
||||
}
|
||||
|
||||
else if(mapper == SuperFXROM) {
|
||||
markup.append(" <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(
|
||||
" <superfx revision='2'>\n"
|
||||
" <rom>\n"
|
||||
" <map mode='linear' address='00-3f:8000-ffff'/>\n"
|
||||
" <map mode='linear' address='40-5f:0000-ffff'/>\n"
|
||||
" <map mode='linear' address='80-bf:8000-ffff'/>\n"
|
||||
" <map mode='linear' address='c0-df:0000-ffff'/>\n"
|
||||
" </rom>\n"
|
||||
" <ram>\n"
|
||||
" <map mode='linear' address='00-3f:6000-7fff' size='0x2000'/>\n"
|
||||
" <map mode='linear' address='60-7f:0000-ffff'/>\n"
|
||||
" <map mode='linear' address='80-bf:6000-7fff' size='0x2000'/>\n"
|
||||
" <map mode='linear' address='e0-ff:0000-ffff'/>\n"
|
||||
" </ram>\n"
|
||||
" <mmio>\n"
|
||||
" <map address='00-3f:3000-32ff'/>\n"
|
||||
" <map address='80-bf:3000-32ff'/>\n"
|
||||
" </mmio>\n"
|
||||
" <map address='00-3f:3000-32ff' id='io'/>\n"
|
||||
" <map address='80-bf:3000-32ff' id='io'/>\n"
|
||||
" <rom name='program.rom' size='", 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"
|
||||
);
|
||||
if(ram_size > 0) markup.append(
|
||||
" <ram name='save.rwm' size='", 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"
|
||||
);
|
||||
markup.append(
|
||||
" </superfx>\n"
|
||||
);
|
||||
}
|
||||
|
||||
else if(mapper == SA1ROM) {
|
||||
markup.append(" <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(
|
||||
" <sa1>\n"
|
||||
" <mcu>\n"
|
||||
" <rom>\n"
|
||||
" <map mode='direct' address='00-3f:8000-ffff'/>\n"
|
||||
" <map mode='direct' address='80-bf:8000-ffff'/>\n"
|
||||
" <map mode='direct' address='c0-ff:0000-ffff'/>\n"
|
||||
" </rom>\n"
|
||||
" <ram>\n"
|
||||
" <map mode='direct' address='00-3f:6000-7fff'/>\n"
|
||||
" <map mode='direct' address='80-bf:6000-7fff'/>\n"
|
||||
" </ram>\n"
|
||||
" </mcu>\n"
|
||||
" <iram >\n"
|
||||
" <map mode='linear' address='00-3f:3000-37ff'/>\n"
|
||||
" <map mode='linear' address='80-bf:3000-37ff'/>\n"
|
||||
" </iram>\n"
|
||||
" <bwram>\n"
|
||||
" <map mode='linear' address='40-4f:0000-ffff'/>\n"
|
||||
" </bwram>\n"
|
||||
" <mmio>\n"
|
||||
" <map address='00-3f:2200-23ff'/>\n"
|
||||
" <map address='80-bf:2200-23ff'/>\n"
|
||||
" </mmio>\n"
|
||||
" <map address='00-3f:2200-23ff' id='io'/>\n"
|
||||
" <map address='80-bf:2200-23ff' id='io'/>\n"
|
||||
" <rom name='program.rom' size='", 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"
|
||||
);
|
||||
if(ram_size > 0) markup.append(
|
||||
" <bwram name='save.rwm' size='", 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"
|
||||
);
|
||||
markup.append(
|
||||
" </sa1>\n"
|
||||
);
|
||||
}
|
||||
|
||||
else if(mapper == BSCLoROM) markup.append(
|
||||
" <rom name='program.rom' size='0x", hex(rom_size), "'>\n"
|
||||
" <map mode='linear' address='00-1f:8000-ffff' offset='0x000000'/>\n"
|
||||
" <map mode='linear' address='20-3f:8000-ffff' offset='0x100000'/>\n"
|
||||
" <map mode='linear' address='80-9f:8000-ffff' offset='0x200000'/>\n"
|
||||
" <map mode='linear' address='a0-bf:8000-ffff' offset='0x100000'/>\n"
|
||||
" </rom>\n"
|
||||
" <ram name='save.ram' size='0x", hex(ram_size), "'>\n"
|
||||
" <map mode='linear' address='70-7f:0000-7fff'/>\n"
|
||||
" <map mode='linear' address='f0-ff:0000-7fff'/>\n"
|
||||
" </ram>\n"
|
||||
" <bsx>\n"
|
||||
" <slot>\n"
|
||||
" <map mode='linear' address='c0-ef:0000-ffff'/>\n"
|
||||
" </slot>\n"
|
||||
" </bsx>\n"
|
||||
" <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"
|
||||
);
|
||||
|
||||
else if(mapper == BSCHiROM) markup.append(
|
||||
" <rom name='program.rom' size='0x", hex(rom_size), "'>\n"
|
||||
" <map mode='shadow' address='00-1f:8000-ffff'/>\n"
|
||||
" <map mode='linear' address='40-5f:0000-ffff'/>\n"
|
||||
" <map mode='shadow' address='80-9f:8000-ffff'/>\n"
|
||||
" <map mode='linear' address='c0-df:0000-ffff'/>\n"
|
||||
" </rom>\n"
|
||||
" <ram name='save.ram' size='0x", hex(ram_size), "'>\n"
|
||||
" <map mode='linear' address='20-3f:6000-7fff'/>\n"
|
||||
" <map mode='linear' address='a0-bf:6000-7fff'/>\n"
|
||||
" </ram>\n"
|
||||
" <bsx>\n"
|
||||
" <slot>\n"
|
||||
" <map mode='shadow' address='20-3f:8000-ffff'/>\n"
|
||||
" <map mode='linear' address='60-7f:0000-ffff'/>\n"
|
||||
" <map mode='shadow' address='a0-bf:8000-ffff'/>\n"
|
||||
" <map mode='linear' address='e0-ff:0000-ffff'/>\n"
|
||||
" </slot>\n"
|
||||
" </bsx>\n"
|
||||
" <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"
|
||||
);
|
||||
|
||||
else if(mapper == BSXROM) markup.append(
|
||||
" <rom name='program.rom' size='0x", hex(rom_size), "'/>\n"
|
||||
" <ram name='save.ram' size='0x", hex(ram_size), "'/>\n"
|
||||
" <psram name='bsx.ram' size='0x40000'/>\n"
|
||||
" <bsx>\n"
|
||||
" <mcu>\n"
|
||||
" <map address='00-3f:8000-ffff'/>\n"
|
||||
" <map address='80-bf:8000-ffff'/>\n"
|
||||
" <map address='40-7f:0000-ffff'/>\n"
|
||||
" <map address='c0-ff:0000-ffff'/>\n"
|
||||
" <map address='20-3f:6000-7fff'/>\n"
|
||||
" </mcu>\n"
|
||||
" <mmio>\n"
|
||||
" <map address='00-3f:5000-5fff'/>\n"
|
||||
" <map address='80-bf:5000-5fff'/>\n"
|
||||
" </mmio>\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"
|
||||
);
|
||||
|
||||
else if(mapper == STROM) markup.append(
|
||||
" <rom name='program.rom' size='0x", hex(rom_size), "'>\n"
|
||||
" <map mode='linear' address='00-1f:8000-ffff'/>\n"
|
||||
" <map mode='linear' address='80-9f:8000-ffff'/>\n"
|
||||
" </rom>\n"
|
||||
" <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"
|
||||
" <rom>\n"
|
||||
" <map mode='linear' address='20-3f:8000-ffff'/>\n"
|
||||
" <map mode='linear' address='a0-bf:8000-ffff'/>\n"
|
||||
" </rom>\n"
|
||||
" <ram>\n"
|
||||
" <map mode='linear' address='60-63:8000-ffff'/>\n"
|
||||
" <map mode='linear' address='e0-e3:8000-ffff'/>\n"
|
||||
" </ram>\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"
|
||||
" <rom>\n"
|
||||
" <map mode='linear' address='40-5f:8000-ffff'/>\n"
|
||||
" <map mode='linear' address='c0-df:8000-ffff'/>\n"
|
||||
" </rom>\n"
|
||||
" <ram>\n"
|
||||
" <map mode='linear' address='70-73:8000-ffff'/>\n"
|
||||
" <map mode='linear' address='f0-f3:8000-ffff'/>\n"
|
||||
" </ram>\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"
|
||||
);
|
||||
|
||||
if(has_srtc) markup.append(
|
||||
" <sharprtc name='rtc.ram' size='0x10'>\n"
|
||||
" <map address='00-3f:2800-2801'/>\n"
|
||||
" <map address='80-bf:2800-2801'/>\n"
|
||||
" </sharprtc>\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"
|
||||
);
|
||||
|
||||
if(has_sdd1) markup.append(
|
||||
" <sdd1>\n"
|
||||
" <mcu>\n"
|
||||
" <map address='c0-ff:0000-ffff'/>\n"
|
||||
" </mcu>\n"
|
||||
" <mmio>\n"
|
||||
" <map address='00-3f:4800-4807'/>\n"
|
||||
" <map address='80-bf:4800-4807'/>\n"
|
||||
" </mmio>\n"
|
||||
" </sdd1>\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"
|
||||
);
|
||||
|
||||
if(has_obc1) markup.append(
|
||||
" <obc1>\n"
|
||||
" <map address='00-3f:6000-7fff'/>\n"
|
||||
" <map address='80-bf:6000-7fff'/>\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"
|
||||
);
|
||||
|
||||
if(has_dsp1) {
|
||||
//91e87d11e1c30d172556bed2211cce2efa94ba595f58c5d264809ef4d363a97b dsp1.rom
|
||||
markup.append(" <necdsp model='uPD7725' frequency='8000000' firmware='dsp1b.rom' sha256='d789cb3c36b05c0b23b6c6f23be7aa37c6e78b6ee9ceac8d2d2aa9d8c4d35fa9'>\n");
|
||||
markup.append(
|
||||
" <necdsp model='uPD7725' frequency='8000000'>\n"
|
||||
" <firmware name='dsp1b.rom' size='8192' sha256='d789cb3c36b05c0b23b6c6f23be7aa37c6e78b6ee9ceac8d2d2aa9d8c4d35fa9'/>\n"
|
||||
);
|
||||
if(dsp1_mapper == DSP1LoROM1MB) markup.append(
|
||||
" <dr>\n"
|
||||
" <map address='20-3f:8000-bfff'/>\n"
|
||||
" <map address='a0-bf:8000-bfff'/>\n"
|
||||
" </dr>\n"
|
||||
" <sr>\n"
|
||||
" <map address='20-3f:c000-ffff'/>\n"
|
||||
" <map address='a0-bf:c000-ffff'/>\n"
|
||||
" </sr>\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"
|
||||
);
|
||||
if(dsp1_mapper == DSP1LoROM2MB) markup.append(
|
||||
" <dr>\n"
|
||||
" <map address='60-6f:0000-3fff'/>\n"
|
||||
" <map address='e0-ef:0000-3fff'/>\n"
|
||||
" </dr>\n"
|
||||
" <sr>\n"
|
||||
" <map address='60-6f:4000-7fff'/>\n"
|
||||
" <map address='e0-ef:4000-7fff'/>\n"
|
||||
" </sr>\n"
|
||||
" <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"
|
||||
);
|
||||
if(dsp1_mapper == DSP1HiROM) markup.append(
|
||||
" <dr>\n"
|
||||
" <map address='00-1f:6000-6fff'/>\n"
|
||||
" <map address='80-9f:6000-6fff'/>\n"
|
||||
" </dr>\n"
|
||||
" <sr>\n"
|
||||
" <map address='00-1f:7000-7fff'/>\n"
|
||||
" <map address='80-9f:7000-7fff'/>\n"
|
||||
" </sr>\n"
|
||||
" <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"
|
||||
);
|
||||
markup.append(" </necdsp>\n");
|
||||
}
|
||||
|
||||
if(has_dsp2) markup.append(
|
||||
" <necdsp model='uPD7725' frequency='8000000' firmware='dsp2.rom' sha256='03ef4ef26c9f701346708cb5d07847b5203cf1b0818bf2930acd34510ffdd717'>\n"
|
||||
" <dr>\n"
|
||||
" <map address='20-3f:8000-bfff'/>\n"
|
||||
" <map address='a0-bf:8000-bfff'/>\n"
|
||||
" </dr>\n"
|
||||
" <sr>\n"
|
||||
" <map address='20-3f:c000-ffff'/>\n"
|
||||
" <map address='a0-bf:c000-ffff'/>\n"
|
||||
" </sr>\n"
|
||||
" <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"
|
||||
);
|
||||
|
||||
if(has_dsp3) markup.append(
|
||||
" <necdsp model='uPD7725' frequency='8000000' firmware='dsp3.rom' sha256='0971b08f396c32e61989d1067dddf8e4b14649d548b2188f7c541b03d7c69e4e'>\n"
|
||||
" <dr>\n"
|
||||
" <map address='20-3f:8000-bfff'/>\n"
|
||||
" <map address='a0-bf:8000-bfff'/>\n"
|
||||
" </dr>\n"
|
||||
" <sr>\n"
|
||||
" <map address='20-3f:c000-ffff'/>\n"
|
||||
" <map address='a0-bf:c000-ffff'/>\n"
|
||||
" </sr>\n"
|
||||
" <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"
|
||||
);
|
||||
|
||||
if(has_dsp4) markup.append(
|
||||
" <necdsp model='uPD7725' frequency='8000000' firmware='dsp4.rom' sha256='752d03b2d74441e430b7f713001fa241f8bbcfc1a0d890ed4143f174dbe031da'>\n"
|
||||
" <dr>\n"
|
||||
" <map address='30-3f:8000-bfff'/>\n"
|
||||
" <map address='b0-bf:8000-bfff'/>\n"
|
||||
" </dr>\n"
|
||||
" <sr>\n"
|
||||
" <map address='30-3f:c000-ffff'/>\n"
|
||||
" <map address='b0-bf:c000-ffff'/>\n"
|
||||
" </sr>\n"
|
||||
" <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"
|
||||
);
|
||||
|
||||
if(has_st010) markup.append(
|
||||
" <necdsp model='uPD96050' frequency='10000000' firmware='st010.rom' sha256='fa9bced838fedea11c6f6ace33d1878024bdd0d02cc9485899d0bdd4015ec24c'>\n"
|
||||
" <dr>\n"
|
||||
" <map address='60:0000'/>\n"
|
||||
" <map address='e0:0000'/>\n"
|
||||
" </dr>\n"
|
||||
" <sr>\n"
|
||||
" <map address='60:0001'/>\n"
|
||||
" <map address='e0:0001'/>\n"
|
||||
" </sr>\n"
|
||||
" <dp>\n"
|
||||
" <map address='68-6f:0000-0fff'/>\n"
|
||||
" <map address='e8-ef:0000-0fff'/>\n"
|
||||
" </dp>\n"
|
||||
" <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"
|
||||
);
|
||||
|
||||
if(has_st011) markup.append(
|
||||
" <necdsp model='uPD96050' frequency='15000000' firmware='st011.rom' sha256='8b2b3f3f3e6e29f4d21d8bc736b400bc988b7d2214ebee15643f01c1fee2f364'>\n"
|
||||
" <dr>\n"
|
||||
" <map address='60:0000'/>\n"
|
||||
" <map address='e0:0000'/>\n"
|
||||
" </dr>\n"
|
||||
" <sr>\n"
|
||||
" <map address='60:0001'/>\n"
|
||||
" <map address='e0:0001'/>\n"
|
||||
" </sr>\n"
|
||||
" <dp>\n"
|
||||
" <map address='68-6f:0000-0fff'/>\n"
|
||||
" <map address='e8-ef:0000-0fff'/>\n"
|
||||
" </dp>\n"
|
||||
" <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"
|
||||
);
|
||||
|
||||
if(has_st018) markup.append(
|
||||
" <armdsp firmware='st018.rom' frequency='21477272' sha256='6df209ab5d2524d1839c038be400ae5eb20dafc14a3771a3239cd9e8acd53806'>\n"
|
||||
" <map address='00-3f:3800-38ff'/>\n"
|
||||
" <map address='80-bf:3800-38ff'/>\n"
|
||||
" <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"
|
||||
);
|
||||
|
||||
|
@ -66,6 +66,14 @@ namespace nall {
|
||||
return memory;
|
||||
}
|
||||
|
||||
static bool read(const string &filename, uint8_t *data, unsigned size) {
|
||||
file fp;
|
||||
if(fp.open(filename, mode::read) == false) return false;
|
||||
fp.read(data, size);
|
||||
fp.close();
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool write(const string &filename, const uint8_t *data, unsigned size) {
|
||||
file fp;
|
||||
if(fp.open(filename, mode::write) == false) return false;
|
||||
|
56
purify/nall/nall.hpp
Executable file
56
purify/nall/nall.hpp
Executable file
@ -0,0 +1,56 @@
|
||||
#ifndef NALL_HPP
|
||||
#define NALL_HPP
|
||||
|
||||
//include the most common nall headers with one statement
|
||||
//does not include the most obscure components with high cost and low usage
|
||||
|
||||
#include <nall/platform.hpp>
|
||||
|
||||
#include <nall/algorithm.hpp>
|
||||
#include <nall/any.hpp>
|
||||
#include <nall/atoi.hpp>
|
||||
#include <nall/base64.hpp>
|
||||
#include <nall/bit.hpp>
|
||||
#include <nall/bmp.hpp>
|
||||
#include <nall/config.hpp>
|
||||
#include <nall/crc32.hpp>
|
||||
#include <nall/directory.hpp>
|
||||
#include <nall/dl.hpp>
|
||||
#include <nall/endian.hpp>
|
||||
#include <nall/file.hpp>
|
||||
#include <nall/filemap.hpp>
|
||||
#include <nall/function.hpp>
|
||||
#include <nall/gzip.hpp>
|
||||
#include <nall/http.hpp>
|
||||
#include <nall/image.hpp>
|
||||
#include <nall/inflate.hpp>
|
||||
#include <nall/interpolation.hpp>
|
||||
#include <nall/intrinsics.hpp>
|
||||
#include <nall/invoke.hpp>
|
||||
#include <nall/map.hpp>
|
||||
#include <nall/png.hpp>
|
||||
#include <nall/property.hpp>
|
||||
#include <nall/random.hpp>
|
||||
#include <nall/serializer.hpp>
|
||||
#include <nall/set.hpp>
|
||||
#include <nall/sha256.hpp>
|
||||
#include <nall/sort.hpp>
|
||||
#include <nall/stdint.hpp>
|
||||
#include <nall/stream.hpp>
|
||||
#include <nall/string.hpp>
|
||||
#include <nall/traits.hpp>
|
||||
#include <nall/utility.hpp>
|
||||
#include <nall/varint.hpp>
|
||||
#include <nall/vector.hpp>
|
||||
#include <nall/zip.hpp>
|
||||
|
||||
#if defined(PLATFORM_WINDOWS)
|
||||
#include <nall/windows/registry.hpp>
|
||||
#include <nall/windows/utf8.hpp>
|
||||
#endif
|
||||
|
||||
#if defined(PLATFORM_X)
|
||||
#include <nall/serial.hpp>
|
||||
#endif
|
||||
|
||||
#endif
|
@ -20,7 +20,9 @@ struct zipstream : memorystream {
|
||||
|
||||
for(auto &file : archive.file) {
|
||||
if(file.name.wildcard(filter)) {
|
||||
archive.extract(file, pdata, psize);
|
||||
auto buffer = archive.extract(file);
|
||||
psize = buffer.size();
|
||||
pdata = buffer.move();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -2,59 +2,71 @@
|
||||
|
||||
namespace nall {
|
||||
|
||||
// "foo/bar.c" -> "foo/"
|
||||
// "foo/" -> "foo/"
|
||||
// "/foo/bar.c" -> "/foo/"
|
||||
// "/foo/" -> "/foo/"
|
||||
// "bar.c" -> "./"
|
||||
inline string dir(char const *name) {
|
||||
string result = name;
|
||||
for(signed i = strlen(result); i >= 0; i--) {
|
||||
if(result[i] == '/' || result[i] == '\\') {
|
||||
result[i + 1] = 0;
|
||||
break;
|
||||
}
|
||||
if(i == 0) result = "./";
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
// "foo/bar.c" -> "bar.c"
|
||||
inline string notdir(char const *name) {
|
||||
for(signed i = strlen(name); i >= 0; i--) {
|
||||
inline string dir(string name) {
|
||||
for(signed i = name.length(); i >= 0; i--) {
|
||||
if(name[i] == '/' || name[i] == '\\') {
|
||||
name += i + 1;
|
||||
name[i + 1] = 0;
|
||||
break;
|
||||
}
|
||||
if(i == 0) name = "./";
|
||||
}
|
||||
string result = name;
|
||||
return result;
|
||||
return name;
|
||||
}
|
||||
|
||||
// "foo/bar.c" -> "foo/bar"
|
||||
inline string basename(char const *name) {
|
||||
string result = name;
|
||||
for(signed i = strlen(result); i >= 0; i--) {
|
||||
if(result[i] == '/' || result[i] == '\\') {
|
||||
//file has no extension
|
||||
break;
|
||||
}
|
||||
if(result[i] == '.') {
|
||||
result[i] = 0;
|
||||
break;
|
||||
// "/foo/bar.c" -> "bar.c"
|
||||
// "/foo/" -> ""
|
||||
// "bar.c" -> "bar.c"
|
||||
inline string notdir(string name) {
|
||||
for(signed i = name.length(); i >= 0; i--) {
|
||||
if(name[i] == '/' || name[i] == '\\') {
|
||||
return (const char*)name + i + 1;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
return name;
|
||||
}
|
||||
|
||||
// "foo/bar.c" -> "c"
|
||||
inline string extension(char const *name) {
|
||||
for(signed i = strlen(name); i >= 0; i--) {
|
||||
// "/foo/bar/baz" -> "/foo/bar/"
|
||||
// "/foo/bar/" -> "/foo/"
|
||||
// "/foo/bar" -> "/foo/"
|
||||
inline string parentdir(string name) {
|
||||
unsigned length = name.length(), paths = 0, prev, last;
|
||||
for(unsigned i = 0; i < length; i++) {
|
||||
if(name[i] == '/' || name[i] == '\\') {
|
||||
paths++;
|
||||
prev = last;
|
||||
last = i;
|
||||
}
|
||||
}
|
||||
if(last + 1 == length) last = prev; //if name ends in slash; use previous slash
|
||||
if(paths > 1) name[last + 1] = 0;
|
||||
return name;
|
||||
}
|
||||
|
||||
// "/foo/bar.c" -> "/foo/bar"
|
||||
inline string basename(string name) {
|
||||
for(signed i = name.length(); i >= 0; i--) {
|
||||
if(name[i] == '/' || name[i] == '\\') break; //file has no extension
|
||||
if(name[i] == '.') {
|
||||
name += i + 1;
|
||||
name[i] = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
string result = name;
|
||||
return result;
|
||||
return name;
|
||||
}
|
||||
|
||||
// "/foo/bar.c" -> "c"
|
||||
// "/foo/bar" -> ""
|
||||
inline string extension(string name) {
|
||||
for(signed i = name.length(); i >= 0; i--) {
|
||||
if(name[i] == '/' || name[i] == '\\') return ""; //file has no extension
|
||||
if(name[i] == '.') {
|
||||
return (const char*)name + i + 1;
|
||||
}
|
||||
}
|
||||
return name;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -24,10 +24,18 @@ namespace nall {
|
||||
operator bool() const { return pool; }
|
||||
T* data() { return pool; }
|
||||
|
||||
bool empty() const { return pool == nullptr; }
|
||||
bool empty() const { return objectsize == 0; }
|
||||
unsigned size() const { return objectsize; }
|
||||
unsigned capacity() const { return poolsize; }
|
||||
|
||||
T* move() {
|
||||
T *result = data;
|
||||
pool = nullptr;
|
||||
poolsize = 0;
|
||||
objectsize = 0;
|
||||
return result;
|
||||
}
|
||||
|
||||
void reset() {
|
||||
if(pool) {
|
||||
for(unsigned n = 0; n < objectsize; n++) pool[n].~T();
|
||||
@ -97,6 +105,13 @@ namespace nall {
|
||||
return item;
|
||||
}
|
||||
|
||||
void reverse() {
|
||||
unsigned pivot = size() / 2;
|
||||
for(unsigned l = 0, r = size() - 1; l < pivot; l++, r--) {
|
||||
std::swap(pool[l], pool[r]);
|
||||
}
|
||||
}
|
||||
|
||||
void sort() {
|
||||
nall::sort(pool, objectsize);
|
||||
}
|
||||
@ -184,293 +199,6 @@ namespace nall {
|
||||
reset();
|
||||
}
|
||||
};
|
||||
|
||||
//linear_vector
|
||||
//memory: O(capacity * 2)
|
||||
//
|
||||
//linear_vector uses placement new + manual destructor calls to create a
|
||||
//contiguous block of memory for all objects. accessing individual elements
|
||||
//is fast, though resizing the array incurs significant overhead.
|
||||
//reserve() overhead is reduced from quadratic time to amortized constant time
|
||||
//by resizing twice as much as requested.
|
||||
//
|
||||
//if objects hold memory address references to themselves (introspection), a
|
||||
//valid copy constructor will be needed to keep pointers valid.
|
||||
|
||||
#define NALL_DEPRECATED
|
||||
#if defined(NALL_DEPRECATED)
|
||||
template<typename T> struct linear_vector {
|
||||
protected:
|
||||
T *pool;
|
||||
unsigned poolsize, objectsize;
|
||||
|
||||
public:
|
||||
unsigned size() const { return objectsize; }
|
||||
unsigned capacity() const { return poolsize; }
|
||||
|
||||
void reset() {
|
||||
if(pool) {
|
||||
for(unsigned i = 0; i < objectsize; i++) pool[i].~T();
|
||||
free(pool);
|
||||
}
|
||||
pool = nullptr;
|
||||
poolsize = 0;
|
||||
objectsize = 0;
|
||||
}
|
||||
|
||||
void reserve(unsigned newsize) {
|
||||
newsize = bit::round(newsize); //round to nearest power of two (for amortized growth)
|
||||
|
||||
T *poolcopy = (T*)calloc(newsize, sizeof(T));
|
||||
for(unsigned i = 0; i < min(objectsize, newsize); i++) new(poolcopy + i) T(pool[i]);
|
||||
for(unsigned i = 0; i < objectsize; i++) pool[i].~T();
|
||||
free(pool);
|
||||
pool = poolcopy;
|
||||
poolsize = newsize;
|
||||
objectsize = min(objectsize, newsize);
|
||||
}
|
||||
|
||||
void resize(unsigned newsize) {
|
||||
if(newsize > poolsize) reserve(newsize);
|
||||
|
||||
if(newsize < objectsize) {
|
||||
//vector is shrinking; destroy excess objects
|
||||
for(unsigned i = newsize; i < objectsize; i++) pool[i].~T();
|
||||
} else if(newsize > objectsize) {
|
||||
//vector is expanding; allocate new objects
|
||||
for(unsigned i = objectsize; i < newsize; i++) new(pool + i) T;
|
||||
}
|
||||
|
||||
objectsize = newsize;
|
||||
}
|
||||
|
||||
void append(const T data) {
|
||||
if(objectsize + 1 > poolsize) reserve(objectsize + 1);
|
||||
new(pool + objectsize++) T(data);
|
||||
}
|
||||
|
||||
template<typename U> void insert(unsigned index, const U list) {
|
||||
linear_vector<T> merged;
|
||||
for(unsigned i = 0; i < index; i++) merged.append(pool[i]);
|
||||
for(auto &item : list) merged.append(item);
|
||||
for(unsigned i = index; i < objectsize; i++) merged.append(pool[i]);
|
||||
operator=(merged);
|
||||
}
|
||||
|
||||
void insert(unsigned index, const T item) {
|
||||
insert(index, linear_vector<T>{ item });
|
||||
}
|
||||
|
||||
void remove(unsigned index, unsigned count = 1) {
|
||||
for(unsigned i = index; count + i < objectsize; i++) {
|
||||
pool[i] = pool[count + i];
|
||||
}
|
||||
if(count + index >= objectsize) resize(index); //every element >= index was removed
|
||||
else resize(objectsize - count);
|
||||
}
|
||||
|
||||
linear_vector() : pool(nullptr), poolsize(0), objectsize(0) {
|
||||
}
|
||||
|
||||
linear_vector(std::initializer_list<T> list) : pool(nullptr), poolsize(0), objectsize(0) {
|
||||
for(const T *p = list.begin(); p != list.end(); ++p) append(*p);
|
||||
}
|
||||
|
||||
~linear_vector() {
|
||||
reset();
|
||||
}
|
||||
|
||||
//copy
|
||||
inline linear_vector<T>& operator=(const linear_vector<T> &source) {
|
||||
reset();
|
||||
reserve(source.capacity());
|
||||
resize(source.size());
|
||||
for(unsigned i = 0; i < source.size(); i++) operator[](i) = source.operator[](i);
|
||||
return *this;
|
||||
}
|
||||
|
||||
linear_vector(const linear_vector<T> &source) : pool(nullptr), poolsize(0), objectsize(0) {
|
||||
operator=(source);
|
||||
}
|
||||
|
||||
//move
|
||||
inline linear_vector<T>& operator=(linear_vector<T> &&source) {
|
||||
reset();
|
||||
pool = source.pool;
|
||||
poolsize = source.poolsize;
|
||||
objectsize = source.objectsize;
|
||||
source.pool = nullptr;
|
||||
source.reset();
|
||||
return *this;
|
||||
}
|
||||
|
||||
linear_vector(linear_vector<T> &&source) : pool(nullptr), poolsize(0), objectsize(0) {
|
||||
operator=(std::move(source));
|
||||
}
|
||||
|
||||
//index
|
||||
inline T& operator[](unsigned index) {
|
||||
if(index >= objectsize) resize(index + 1);
|
||||
return pool[index];
|
||||
}
|
||||
|
||||
inline const T& operator[](unsigned index) const {
|
||||
if(index >= objectsize) throw "vector[] out of bounds";
|
||||
return pool[index];
|
||||
}
|
||||
|
||||
//iteration
|
||||
T* begin() { return &pool[0]; }
|
||||
T* end() { return &pool[objectsize]; }
|
||||
const T* begin() const { return &pool[0]; }
|
||||
const T* end() const { return &pool[objectsize]; }
|
||||
};
|
||||
|
||||
//pointer_vector
|
||||
//memory: O(1)
|
||||
//
|
||||
//pointer_vector keeps an array of pointers to each vector object. this adds
|
||||
//significant overhead to individual accesses, but allows for optimal memory
|
||||
//utilization.
|
||||
//
|
||||
//by guaranteeing that the base memory address of each objects never changes,
|
||||
//this avoids the need for an object to have a valid copy constructor.
|
||||
|
||||
template<typename T> struct pointer_vector {
|
||||
protected:
|
||||
T **pool;
|
||||
unsigned poolsize, objectsize;
|
||||
|
||||
public:
|
||||
unsigned size() const { return objectsize; }
|
||||
unsigned capacity() const { return poolsize; }
|
||||
|
||||
void reset() {
|
||||
if(pool) {
|
||||
for(unsigned i = 0; i < objectsize; i++) { if(pool[i]) delete pool[i]; }
|
||||
free(pool);
|
||||
}
|
||||
pool = nullptr;
|
||||
poolsize = 0;
|
||||
objectsize = 0;
|
||||
}
|
||||
|
||||
void reserve(unsigned newsize) {
|
||||
newsize = bit::round(newsize); //round to nearest power of two (for amortized growth)
|
||||
|
||||
for(unsigned i = newsize; i < objectsize; i++) {
|
||||
if(pool[i]) { delete pool[i]; pool[i] = 0; }
|
||||
}
|
||||
|
||||
pool = (T**)realloc(pool, newsize * sizeof(T*));
|
||||
for(unsigned i = poolsize; i < newsize; i++) pool[i] = 0;
|
||||
poolsize = newsize;
|
||||
objectsize = min(objectsize, newsize);
|
||||
}
|
||||
|
||||
void resize(unsigned newsize) {
|
||||
if(newsize > poolsize) reserve(newsize);
|
||||
|
||||
for(unsigned i = newsize; i < objectsize; i++) {
|
||||
if(pool[i]) { delete pool[i]; pool[i] = 0; }
|
||||
}
|
||||
|
||||
objectsize = newsize;
|
||||
}
|
||||
|
||||
void append(const T data) {
|
||||
if(objectsize + 1 > poolsize) reserve(objectsize + 1);
|
||||
pool[objectsize++] = new T(data);
|
||||
}
|
||||
|
||||
template<typename U> void insert(unsigned index, const U list) {
|
||||
pointer_vector<T> merged;
|
||||
for(unsigned i = 0; i < index; i++) merged.append(*pool[i]);
|
||||
for(auto &item : list) merged.append(item);
|
||||
for(unsigned i = index; i < objectsize; i++) merged.append(*pool[i]);
|
||||
operator=(merged);
|
||||
}
|
||||
|
||||
void insert(unsigned index, const T item) {
|
||||
insert(index, pointer_vector<T>{ item });
|
||||
}
|
||||
|
||||
void remove(unsigned index, unsigned count = 1) {
|
||||
for(unsigned i = index; count + i < objectsize; i++) {
|
||||
*pool[i] = *pool[count + i];
|
||||
}
|
||||
if(count + index >= objectsize) resize(index); //every element >= index was removed
|
||||
else resize(objectsize - count);
|
||||
}
|
||||
|
||||
pointer_vector() : pool(nullptr), poolsize(0), objectsize(0) {
|
||||
}
|
||||
|
||||
pointer_vector(std::initializer_list<T> list) : pool(nullptr), poolsize(0), objectsize(0) {
|
||||
for(const T *p = list.begin(); p != list.end(); ++p) append(*p);
|
||||
}
|
||||
|
||||
~pointer_vector() {
|
||||
reset();
|
||||
}
|
||||
|
||||
//copy
|
||||
inline pointer_vector<T>& operator=(const pointer_vector<T> &source) {
|
||||
reset();
|
||||
reserve(source.capacity());
|
||||
resize(source.size());
|
||||
for(unsigned i = 0; i < source.size(); i++) operator[](i) = source.operator[](i);
|
||||
return *this;
|
||||
}
|
||||
|
||||
pointer_vector(const pointer_vector<T> &source) : pool(nullptr), poolsize(0), objectsize(0) {
|
||||
operator=(source);
|
||||
}
|
||||
|
||||
//move
|
||||
inline pointer_vector<T>& operator=(pointer_vector<T> &&source) {
|
||||
reset();
|
||||
pool = source.pool;
|
||||
poolsize = source.poolsize;
|
||||
objectsize = source.objectsize;
|
||||
source.pool = nullptr;
|
||||
source.reset();
|
||||
return *this;
|
||||
}
|
||||
|
||||
pointer_vector(pointer_vector<T> &&source) : pool(nullptr), poolsize(0), objectsize(0) {
|
||||
operator=(std::move(source));
|
||||
}
|
||||
|
||||
//index
|
||||
inline T& operator[](unsigned index) {
|
||||
if(index >= objectsize) resize(index + 1);
|
||||
if(!pool[index]) pool[index] = new T;
|
||||
return *pool[index];
|
||||
}
|
||||
|
||||
inline const T& operator[](unsigned index) const {
|
||||
if(index >= objectsize || !pool[index]) throw "vector[] out of bounds";
|
||||
return *pool[index];
|
||||
}
|
||||
|
||||
//iteration
|
||||
struct iterator {
|
||||
bool operator!=(const iterator &source) const { return index != source.index; }
|
||||
T& operator*() { return vector.operator[](index); }
|
||||
iterator& operator++() { index++; return *this; }
|
||||
iterator(const pointer_vector &vector, unsigned index) : vector(vector), index(index) {}
|
||||
private:
|
||||
const pointer_vector &vector;
|
||||
unsigned index;
|
||||
};
|
||||
|
||||
iterator begin() { return iterator(*this, 0); }
|
||||
iterator end() { return iterator(*this, objectsize); }
|
||||
const iterator begin() const { return iterator(*this, 0); }
|
||||
const iterator end() const { return iterator(*this, objectsize); }
|
||||
};
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -19,7 +19,8 @@ using namespace phoenix;
|
||||
#include "resource/resource.cpp"
|
||||
|
||||
struct Settings : configuration {
|
||||
bool play;
|
||||
bool ui; //true if in user-interface mode (windows visible); false if in command-line mode
|
||||
bool play; //true if emulator should be launched after game conversion
|
||||
lstring extensions;
|
||||
|
||||
string emulator;
|
||||
@ -27,6 +28,7 @@ struct Settings : configuration {
|
||||
string recent;
|
||||
|
||||
Settings() {
|
||||
ui = false;
|
||||
play = false;
|
||||
extensions = {".fc", ".nes", ".sfc", ".smc", ".swc", ".fig", ".bs", ".st", ".gb", ".gbc", ".sgb", ".gba"};
|
||||
|
||||
@ -71,7 +73,7 @@ void create_famicom(const string &filename, uint8_t *data, unsigned size) {
|
||||
file::write({path, "manifest.xml"}, (const uint8_t*)information.markup(), information.markup.length());
|
||||
if(information.prgrom > 0) file::write({path, "program.rom"}, data, information.prgrom);
|
||||
if(information.chrrom > 0) file::write({path, "character.rom"}, data + information.prgrom, information.chrrom);
|
||||
if(!file::exists({path, "save.ram"})) file::copy({nall::basename(filename), ".sav"}, {path, "save.ram"});
|
||||
if(!file::exists({path, "save.rwm"})) file::copy({nall::basename(filename), ".sav"}, {path, "save.rwm"});
|
||||
if(settings.play) play(path);
|
||||
}
|
||||
|
||||
@ -88,8 +90,13 @@ void create_super_famicom(const string &filename, uint8_t *data, unsigned size)
|
||||
if((size & 0x7fff) == 512) data += 512, size -= 512;
|
||||
|
||||
file::write({path, "manifest.xml"}, (const uint8_t*)information.markup(), information.markup.length());
|
||||
file::write({path, "program.rom"}, data, size);
|
||||
if(!file::exists({path, "save.ram"})) file::copy({nall::basename(filename), ".srm"}, {path, "save.ram"});
|
||||
if(information.markup.position("<spc7110>") && size >= 0x100000) {
|
||||
file::write({path, "program.rom"}, data, 0x100000);
|
||||
file::write({path, "data.rom"}, data + 0x100000, size - 0x100000);
|
||||
} else {
|
||||
file::write({path, "program.rom"}, data, size);
|
||||
}
|
||||
if(!file::exists({path, "save.rwm"})) file::copy({nall::basename(filename), ".srm"}, {path, "save.rwm"});
|
||||
|
||||
//firmware
|
||||
if(auto position = information.markup.position("firmware=")) {
|
||||
@ -130,7 +137,7 @@ void create_sufami_turbo(const string &filename, uint8_t *data, unsigned size) {
|
||||
|
||||
file::write({path, "manifest.xml"}, (const uint8_t*)information.markup(), information.markup.length());
|
||||
file::write({path, "program.rom"}, data, size);
|
||||
if(!file::exists({path, "save.ram"})) file::copy({nall::basename(filename), ".srm"}, {path, "save.ram"});
|
||||
if(!file::exists({path, "save.rwm"})) file::copy({nall::basename(filename), ".srm"}, {path, "save.rwm"});
|
||||
}
|
||||
|
||||
void create_game_boy(const string &filename, uint8_t *data, unsigned size) {
|
||||
@ -146,7 +153,7 @@ void create_game_boy(const string &filename, uint8_t *data, unsigned size) {
|
||||
|
||||
file::write({path, "manifest.xml"}, (const uint8_t*)information.markup(), information.markup.length());
|
||||
file::write({path, "program.rom"}, data, size);
|
||||
if(!file::exists({path, "save.ram"})) file::copy({nall::basename(filename), ".sav"}, {path, "save.ram"});
|
||||
if(!file::exists({path, "save.rwm"})) file::copy({nall::basename(filename), ".sav"}, {path, "save.rwm"});
|
||||
if(settings.play) play(path);
|
||||
}
|
||||
|
||||
@ -161,7 +168,7 @@ void create_game_boy_advance(const string &filename, uint8_t *data, unsigned siz
|
||||
|
||||
file::write({path, "manifest.xml"}, (const uint8_t*)information.markup(), information.markup.length());
|
||||
file::write({path, "program.rom"}, data, size);
|
||||
if(!file::exists({path, "save.ram"})) file::copy({nall::basename(filename), ".sav"}, {path, "save.ram"});
|
||||
if(!file::exists({path, "save.rwm"})) file::copy({nall::basename(filename), ".sav"}, {path, "save.rwm"});
|
||||
if(settings.play) play(path);
|
||||
}
|
||||
|
||||
@ -262,6 +269,14 @@ void create_folder(string pathname) {
|
||||
pathname.transform("\\", "/");
|
||||
if(pathname.endswith("/") == false) pathname.append("/");
|
||||
|
||||
if(pathname == settings.path) {
|
||||
print(
|
||||
"You cannot use the same path for both the source and destination directories.\n"
|
||||
"Please choose a different output path in settings.cfg.\n"
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
lstring files = directory::contents(pathname);
|
||||
for(auto &name : files) {
|
||||
if(directory::exists({pathname, name}) && valid_extension(name)) {
|
||||
@ -368,7 +383,7 @@ struct Application : Window {
|
||||
Label pathValue;
|
||||
|
||||
Application() {
|
||||
setTitle("purify v00.04");
|
||||
setTitle("purify v00.06");
|
||||
setGeometry({128, 128, 440, 180});
|
||||
layout.setMargin(5);
|
||||
title.setFont("Sans, 16, Bold");
|
||||
@ -435,10 +450,18 @@ struct Application : Window {
|
||||
|
||||
void convertAction() {
|
||||
string pathname = DialogWindow::folderSelect(*this, settings.recent);
|
||||
if(!pathname.empty()) {
|
||||
settings.recent = pathname;
|
||||
progress->convert(pathname);
|
||||
if(pathname.empty()) return;
|
||||
|
||||
if(pathname == settings.path) {
|
||||
MessageWindow::critical(*this,
|
||||
"You cannot use the same path for both the source and destination directories.\n\n"
|
||||
"Please choose a different output path."
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
settings.recent = pathname;
|
||||
progress->convert(pathname);
|
||||
}
|
||||
|
||||
void emulatorAction() {
|
||||
@ -492,6 +515,7 @@ int main(int argc, char **argv) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
settings.ui = true;
|
||||
progress = new Progress;
|
||||
application = new Application;
|
||||
OS::main();
|
||||
|
Loading…
Reference in New Issue
Block a user