diff --git a/bsnes/cc.bat b/bsnes/cc.bat deleted file mode 100755 index f49d74d32..000000000 --- a/bsnes/cc.bat +++ /dev/null @@ -1,2 +0,0 @@ -@mingw32-make -j 8 -@pause diff --git a/bsnes/emulator/emulator.hpp b/bsnes/emulator/emulator.hpp index a8583013c..8c457fcce 100755 --- a/bsnes/emulator/emulator.hpp +++ b/bsnes/emulator/emulator.hpp @@ -3,7 +3,7 @@ namespace Emulator { static const char Name[] = "bsnes"; - static const char Version[] = "089.13"; + static const char Version[] = "089.14"; static const char Author[] = "byuu"; static const char License[] = "GPLv3"; } diff --git a/bsnes/nall/string/filename.hpp b/bsnes/nall/string/filename.hpp index 6dea67fc9..19b5f1174 100755 --- a/bsnes/nall/string/filename.hpp +++ b/bsnes/nall/string/filename.hpp @@ -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; } } diff --git a/bsnes/nall/vector.hpp b/bsnes/nall/vector.hpp index c3a768fb5..ea5fd6976 100755 --- a/bsnes/nall/vector.hpp +++ b/bsnes/nall/vector.hpp @@ -97,6 +97,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); } diff --git a/bsnes/purge.bat b/bsnes/purge.bat deleted file mode 100755 index d4c3d600b..000000000 --- a/bsnes/purge.bat +++ /dev/null @@ -1 +0,0 @@ -@mingw32-make clean diff --git a/bsnes/sfc/cartridge/markup.cpp b/bsnes/sfc/cartridge/markup.cpp index 6b937af55..3cb062810 100755 --- a/bsnes/sfc/cartridge/markup.cpp +++ b/bsnes/sfc/cartridge/markup.cpp @@ -194,47 +194,46 @@ void Cartridge::parse_markup_sufamiturbo(XML::Node &root) { void Cartridge::parse_markup_nss(XML::Node &root) { if(root.exists() == false) return; has_nss_dip = true; - nss.dip = interface->dipSettings(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); + } } void Cartridge::parse_markup_sa1(XML::Node &root) { if(root.exists() == false) return; has_sa1 = true; - auto &mcurom = root["mcu"]["rom"]; - auto &mcuram = root["mcu"]["ram"]; + auto &rom = root["rom"]; auto &iram = root["iram"]; auto &bwram = root["bwram"]; auto &mmio = root["mmio"]; - for(auto &node : mcurom) { + parse_markup_memory(sa1.rom, rom, ID::SA1ROM, false); + for(auto &node : rom) { 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 : mcuram) { - if(node.name != "map") continue; - Mapping m({&SA1::mmc_cpu_read, &sa1}, {&SA1::mmc_cpu_write, &sa1}); - parse_markup_map(m, node); - mapping.append(m); - } - + parse_markup_memory(sa1.iram, iram, ID::SA1IRAM, true); for(auto &node : iram) { if(node.name != "map") continue; - Mapping m(sa1.cpuiram); + Mapping m({&SA1::mmc_read, &sa1}, {&SA1::mmc_write, &sa1}); parse_markup_map(m, node); - if(m.size == 0) m.size = 2048; mapping.append(m); } + parse_markup_memory(sa1.bwram, bwram, ID::SA1BWRAM, true); for(auto &node : bwram) { if(node.name != "map") continue; - Mapping m(sa1.cpubwram); + Mapping m({&SA1::mmc_read, &sa1}, {&SA1::mmc_write, &sa1}); parse_markup_map(m, node); - if(m.size == 0) m.size = ram.size(); mapping.append(m); } @@ -420,16 +419,32 @@ void Cartridge::parse_markup_spc7110(XML::Node &root) { if(root.exists() == false) return; has_spc7110 = true; + auto &rom = root["rom"]; + auto &ram = root["ram"]; auto &mmio = root["mmio"]; auto &dcu = root["dcu"]; - auto &mcurom = root["mcu"]["rom"]; - auto &mcuram = root["mcu"]["ram"]; - spc7110.prom_base = numeral(mcurom["program"]["offset"].data); - spc7110.prom_size = numeral(mcurom["program"]["size"].data); + spc7110.prom_base = numeral(rom["program"]["offset"].data); + spc7110.prom_size = numeral(rom["program"]["size"].data); - spc7110.drom_base = numeral(mcurom["data"]["offset"].data); - spc7110.drom_size = numeral(mcurom["data"]["size"].data); + spc7110.drom_base = numeral(rom["data"]["offset"].data); + spc7110.drom_size = numeral(rom["data"]["size"].data); + + parse_markup_memory(cartridge.rom, rom, ID::ROM, false); + for(auto &node : 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(cartridge.ram, ram, ID::RAM, true); + for(auto &node : 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 : mmio) { if(node.name != "map") continue; @@ -444,39 +459,34 @@ void Cartridge::parse_markup_spc7110(XML::Node &root) { parse_markup_map(m, node); mapping.append(m); } - - for(auto &node : mcurom) { - if(node.name != "map") continue; - Mapping m({&SPC7110::mcurom_read, &spc7110}, {&SPC7110::mcurom_write, &spc7110}); - parse_markup_map(m, node); - mapping.append(m); - } - - for(auto &node : mcuram) { - if(node.name != "map") continue; - Mapping m({&SPC7110::mcuram_read, &spc7110}, {&SPC7110::mcuram_write, &spc7110}); - parse_markup_map(m, node); - mapping.append(m); - } } void Cartridge::parse_markup_sdd1(XML::Node &root) { if(root.exists() == false) return; has_sdd1 = true; - for(auto &node : root["mmio"]) { + parse_markup_memory(sdd1.rom, root["rom"], ID::SDD1ROM, false); + for(auto &node : root["rom"]) { if(node.name != "map") continue; - Mapping m({&SDD1::mmio_read, &sdd1}, {&SDD1::mmio_write, &sdd1}); + Mapping m({&SDD1::mcu_read, &sdd1}, {&SDD1::mcu_write, &sdd1}); parse_markup_map(m, node); mapping.append(m); } - for(auto &node : root["mcu"]) { + 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["mmio"]) { + if(node.name != "map") continue; + Mapping m({&SDD1::mmio_read, &sdd1}, {&SDD1::mmio_write, &sdd1}); + parse_markup_map(m, node); + mapping.append(m); + } } void Cartridge::parse_markup_obc1(XML::Node &root) { diff --git a/bsnes/sfc/chip/nss/nss.cpp b/bsnes/sfc/chip/nss/nss.cpp index 8c935fcfe..7c50d3845 100755 --- a/bsnes/sfc/chip/nss/nss.cpp +++ b/bsnes/sfc/chip/nss/nss.cpp @@ -6,12 +6,10 @@ namespace SuperFamicom { NSS nss; void NSS::init() { - dip = 0x0000; + dip = 0x00; } void NSS::load() { - bus.map(Bus::MapMode::Direct, 0x00, 0x3f, 0x4100, 0x4101, { &NSS::read, this }, { &NSS::write, this }); - bus.map(Bus::MapMode::Direct, 0x80, 0xbf, 0x4100, 0x4101, { &NSS::read, this }, { &NSS::write, this }); } void NSS::unload() { @@ -28,9 +26,7 @@ void NSS::set_dip(uint16 dip) { } uint8 NSS::read(unsigned addr) { - if((addr & 0x40ffff) == 0x004100) return dip >> 0; - if((addr & 0x40ffff) == 0x004101) return dip >> 8; - return cpu.regs.mdr; + return dip; } void NSS::write(unsigned addr, uint8 data) { diff --git a/bsnes/sfc/chip/nss/nss.hpp b/bsnes/sfc/chip/nss/nss.hpp index 52cc5d984..931c9b6ef 100755 --- a/bsnes/sfc/chip/nss/nss.hpp +++ b/bsnes/sfc/chip/nss/nss.hpp @@ -1,5 +1,5 @@ struct NSS { - uint16 dip; + uint8 dip; void init(); void load(); diff --git a/bsnes/sfc/chip/sa1/bus/bus.cpp b/bsnes/sfc/chip/sa1/bus/bus.cpp index a632551a4..4fbc03bf3 100755 --- a/bsnes/sfc/chip/sa1/bus/bus.cpp +++ b/bsnes/sfc/chip/sa1/bus/bus.cpp @@ -8,27 +8,27 @@ unsigned SA1::CPUIRAM::size() const { uint8 SA1::CPUIRAM::read(unsigned addr) { cpu.synchronize_coprocessors(); - return sa1.iram.read(addr); + return sa1.iram.read(addr & 0x07ff); } void SA1::CPUIRAM::write(unsigned addr, uint8 data) { cpu.synchronize_coprocessors(); - sa1.iram.write(addr, data); + sa1.iram.write(addr & 0x07ff, data); } unsigned SA1::CPUBWRAM::size() const { - return cartridge.ram.size(); + return sa1.bwram.size(); } uint8 SA1::CPUBWRAM::read(unsigned addr) { cpu.synchronize_coprocessors(); if(dma) return sa1.dma_cc1_read(addr); - return cartridge.ram.read(addr); + return sa1.bwram.read(addr); } void SA1::CPUBWRAM::write(unsigned addr, uint8 data) { cpu.synchronize_coprocessors(); - cartridge.ram.write(addr, data); + sa1.bwram.write(addr, data); } #endif diff --git a/bsnes/sfc/chip/sa1/bus/bus.hpp b/bsnes/sfc/chip/sa1/bus/bus.hpp index e3b42b972..ed32e4ec8 100755 --- a/bsnes/sfc/chip/sa1/bus/bus.hpp +++ b/bsnes/sfc/chip/sa1/bus/bus.hpp @@ -1,5 +1,3 @@ -StaticRAM iram; - struct CPUIRAM : Memory { unsigned size() const; alwaysinline uint8 read(unsigned); diff --git a/bsnes/sfc/chip/sa1/dma/dma.cpp b/bsnes/sfc/chip/sa1/dma/dma.cpp index 711488656..cc860145d 100755 --- a/bsnes/sfc/chip/sa1/dma/dma.cpp +++ b/bsnes/sfc/chip/sa1/dma/dma.cpp @@ -75,7 +75,7 @@ uint8 SA1::dma_cc1_read(unsigned addr) { //buffer next character to I-RAM unsigned bpp = 2 << (2 - mmio.dmacb); unsigned bpl = (8 << mmio.dmasize) >> mmio.dmacb; - unsigned bwmask = cartridge.ram.size() - 1; + unsigned bwmask = bwram.size() - 1; unsigned tile = ((addr - mmio.dsa) & bwmask) >> (6 - mmio.dmacb); unsigned ty = (tile >> mmio.dmasize); unsigned tx = tile & ((1 << mmio.dmasize) - 1); @@ -84,7 +84,7 @@ uint8 SA1::dma_cc1_read(unsigned addr) { for(unsigned y = 0; y < 8; y++) { uint64 data = 0; for(unsigned byte = 0; byte < bpp; byte++) { - data |= (uint64)cartridge.ram.read((bwaddr + byte) & bwmask) << (byte << 3); + data |= (uint64)bwram.read((bwaddr + byte) & bwmask) << (byte << 3); } bwaddr += bpl; diff --git a/bsnes/sfc/chip/sa1/memory/memory.cpp b/bsnes/sfc/chip/sa1/memory/memory.cpp index d13ac9299..778bab952 100755 --- a/bsnes/sfc/chip/sa1/memory/memory.cpp +++ b/bsnes/sfc/chip/sa1/memory/memory.cpp @@ -29,7 +29,7 @@ uint8 SA1::bus_read(unsigned addr) { if((addr & 0xf00000) == 0x400000) { //$40-4f:0000-ffff synchronize_cpu(); - return cartridge.ram.read(addr & (cartridge.ram.size() - 1)); + return bwram.read(addr & (bwram.size() - 1)); } if((addr & 0xf00000) == 0x600000) { //$60-6f:0000-ffff @@ -59,7 +59,7 @@ void SA1::bus_write(unsigned addr, uint8 data) { if((addr & 0xf00000) == 0x400000) { //$40-4f:0000-ffff synchronize_cpu(); - return cartridge.ram.write(addr & (cartridge.ram.size() - 1), data); + return bwram.write(addr & (bwram.size() - 1), data); } if((addr & 0xf00000) == 0x600000) { //$60-6f:0000-ffff @@ -82,11 +82,11 @@ uint8 SA1::vbr_read(unsigned addr) { } if((addr & 0x40e000) == 0x006000) { //$00-3f|80-bf:6000-7fff - return cartridge.ram.read(addr & (cartridge.ram.size() - 1)); + return bwram.read(addr & (bwram.size() - 1)); } if((addr & 0xf00000) == 0x400000) { //$40-4f:0000-ffff - return cartridge.ram.read(addr & (cartridge.ram.size() - 1)); + return bwram.read(addr & (bwram.size() - 1)); } if((addr & 0x40f800) == 0x000000) { //$00-3f|80-bf:0000-07ff @@ -120,6 +120,20 @@ void SA1::op_write(unsigned addr, uint8 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); + } + 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; @@ -128,7 +142,7 @@ uint8 SA1::mmc_read(unsigned addr) { } static auto read = [](unsigned addr) { - return cartridge.rom.read(bus.mirror(addr, cartridge.rom.size())); + return sa1.rom.read(bus.mirror(addr, sa1.rom.size())); }; if((addr & 0xe08000) == 0x008000) { //$00-1f:8000-ffff @@ -175,26 +189,27 @@ uint8 SA1::mmc_read(unsigned addr) { } void SA1::mmc_write(unsigned addr, uint8 data) { -} + if((addr & 0x40f800) == 0x003000) { //$00-3f|80-bf:3000-37ff + return cpuiram.write(addr & 0x07ff, data); + } -uint8 SA1::mmc_cpu_read(unsigned addr) { - cpu.synchronize_coprocessors(); - addr = bus.mirror(mmio.sbm * 0x2000 + (addr & 0x1fff), cpubwram.size()); - return cpubwram.read(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.write(addr, data); + } -void SA1::mmc_cpu_write(unsigned addr, uint8 data) { - cpu.synchronize_coprocessors(); - addr = bus.mirror(mmio.sbm * 0x2000 + (addr & 0x1fff), cpubwram.size()); - cpubwram.write(addr, data); + if((addr & 0xf00000) == 0x400000) { //$40-4f:0000-ffff + return cpubwram.write(addr & 0x0fffff, data); + } } uint8 SA1::mmc_sa1_read(unsigned addr) { synchronize_cpu(); if(mmio.sw46 == 0) { //$40-43:0000-ffff x 32 projection - addr = bus.mirror((mmio.cbm & 0x1f) * 0x2000 + (addr & 0x1fff), cartridge.ram.size()); - return cartridge.ram.read(addr); + addr = bus.mirror((mmio.cbm & 0x1f) * 0x2000 + (addr & 0x1fff), bwram.size()); + return bwram.read(addr); } else { //$60-6f:0000-ffff x 128 projection addr = bus.mirror(mmio.cbm * 0x2000 + (addr & 0x1fff), 0x100000); @@ -206,8 +221,8 @@ void SA1::mmc_sa1_write(unsigned addr, uint8 data) { synchronize_cpu(); if(mmio.sw46 == 0) { //$40-43:0000-ffff x 32 projection - addr = bus.mirror((mmio.cbm & 0x1f) * 0x2000 + (addr & 0x1fff), cartridge.ram.size()); - cartridge.ram.write(addr, data); + addr = bus.mirror((mmio.cbm & 0x1f) * 0x2000 + (addr & 0x1fff), bwram.size()); + bwram.write(addr, data); } else { //$60-6f:0000-ffff x 128 projection addr = bus.mirror(mmio.cbm * 0x2000 + (addr & 0x1fff), 0x100000); @@ -219,20 +234,20 @@ uint8 SA1::bitmap_read(unsigned addr) { if(mmio.bbf == 0) { //4bpp unsigned shift = addr & 1; - addr = (addr >> 1) & (cartridge.ram.size() - 1); + addr = (addr >> 1) & (bwram.size() - 1); switch(shift) { default: - case 0: return (cartridge.ram.read(addr) >> 0) & 15; - case 1: return (cartridge.ram.read(addr) >> 4) & 15; + case 0: return (bwram.read(addr) >> 0) & 15; + case 1: return (bwram.read(addr) >> 4) & 15; } } else { //2bpp unsigned shift = addr & 3; - addr = (addr >> 2) & (cartridge.ram.size() - 1); + addr = (addr >> 2) & (bwram.size() - 1); switch(shift) { default: - case 0: return (cartridge.ram.read(addr) >> 0) & 3; - case 1: return (cartridge.ram.read(addr) >> 2) & 3; - case 2: return (cartridge.ram.read(addr) >> 4) & 3; - case 3: return (cartridge.ram.read(addr) >> 6) & 3; + case 0: return (bwram.read(addr) >> 0) & 3; + case 1: return (bwram.read(addr) >> 2) & 3; + case 2: return (bwram.read(addr) >> 4) & 3; + case 3: return (bwram.read(addr) >> 6) & 3; } } } @@ -241,24 +256,24 @@ void SA1::bitmap_write(unsigned addr, uint8 data) { if(mmio.bbf == 0) { //4bpp unsigned shift = addr & 1; - addr = (addr >> 1) & (cartridge.ram.size() - 1); + addr = (addr >> 1) & (bwram.size() - 1); switch(shift) { default: - case 0: data = (cartridge.ram.read(addr) & 0xf0) | ((data & 15) << 0); break; - case 1: data = (cartridge.ram.read(addr) & 0x0f) | ((data & 15) << 4); break; + case 0: data = (bwram.read(addr) & 0xf0) | ((data & 15) << 0); break; + case 1: data = (bwram.read(addr) & 0x0f) | ((data & 15) << 4); break; } } else { //2bpp unsigned shift = addr & 3; - addr = (addr >> 2) & (cartridge.ram.size() - 1); + addr = (addr >> 2) & (bwram.size() - 1); switch(shift) { default: - case 0: data = (cartridge.ram.read(addr) & 0xfc) | ((data & 3) << 0); break; - case 1: data = (cartridge.ram.read(addr) & 0xf3) | ((data & 3) << 2); break; - case 2: data = (cartridge.ram.read(addr) & 0xcf) | ((data & 3) << 4); break; - case 3: data = (cartridge.ram.read(addr) & 0x3f) | ((data & 3) << 6); break; + case 0: data = (bwram.read(addr) & 0xfc) | ((data & 3) << 0); break; + case 1: data = (bwram.read(addr) & 0xf3) | ((data & 3) << 2); break; + case 2: data = (bwram.read(addr) & 0xcf) | ((data & 3) << 4); break; + case 3: data = (bwram.read(addr) & 0x3f) | ((data & 3) << 6); break; } } - cartridge.ram.write(addr, data); + bwram.write(addr, data); } #endif diff --git a/bsnes/sfc/chip/sa1/memory/memory.hpp b/bsnes/sfc/chip/sa1/memory/memory.hpp index ffb9e9f6e..c9fd36155 100755 --- a/bsnes/sfc/chip/sa1/memory/memory.hpp +++ b/bsnes/sfc/chip/sa1/memory/memory.hpp @@ -9,9 +9,6 @@ alwaysinline void op_write(unsigned addr, uint8 data); uint8 mmc_read(unsigned addr); void mmc_write(unsigned addr, uint8 data); -uint8 mmc_cpu_read(unsigned addr); -void mmc_cpu_write(unsigned addr, uint8 data); - uint8 mmc_sa1_read(unsigned addr); void mmc_sa1_write(unsigned addr, uint8 data); diff --git a/bsnes/sfc/chip/sa1/sa1.cpp b/bsnes/sfc/chip/sa1/sa1.cpp index d6ca94587..2ce73b1f4 100755 --- a/bsnes/sfc/chip/sa1/sa1.cpp +++ b/bsnes/sfc/chip/sa1/sa1.cpp @@ -123,6 +123,9 @@ void SA1::load() { } void SA1::unload() { + rom.reset(); + iram.reset(); + bwram.reset(); } void SA1::power() { @@ -324,7 +327,4 @@ void SA1::reset() { mmio.overflow = false; } -SA1::SA1() : iram(2048) { -} - } diff --git a/bsnes/sfc/chip/sa1/sa1.hpp b/bsnes/sfc/chip/sa1/sa1.hpp index e6d9d3bc3..667fd47b6 100755 --- a/bsnes/sfc/chip/sa1/sa1.hpp +++ b/bsnes/sfc/chip/sa1/sa1.hpp @@ -1,4 +1,8 @@ struct SA1 : Processor::R65816, public Coprocessor { + MappedRAM rom; + MappedRAM iram; + MappedRAM bwram; + #include "bus/bus.hpp" #include "dma/dma.hpp" #include "memory/memory.hpp" @@ -30,7 +34,6 @@ struct SA1 : Processor::R65816, public Coprocessor { void reset(); void serialize(serializer&); - SA1(); }; extern SA1 sa1; diff --git a/bsnes/sfc/chip/sa1/serialization.cpp b/bsnes/sfc/chip/sa1/serialization.cpp index 04377f7f4..661bb41ff 100755 --- a/bsnes/sfc/chip/sa1/serialization.cpp +++ b/bsnes/sfc/chip/sa1/serialization.cpp @@ -4,6 +4,9 @@ void SA1::serialize(serializer &s) { R65816::serialize(s); Thread::serialize(s); + s.array(iram.data(), iram.size()); + s.array(bwram.data(), bwram.size()); + //sa1.hpp s.integer(status.tick_counter); diff --git a/bsnes/sfc/chip/sdd1/decomp.cpp b/bsnes/sfc/chip/sdd1/decomp.cpp index 9975580fc..d8ef7698c 100755 --- a/bsnes/sfc/chip/sdd1/decomp.cpp +++ b/bsnes/sfc/chip/sdd1/decomp.cpp @@ -17,11 +17,11 @@ uint8 SDD1::Decomp::IM::get_codeword(uint8 code_length) { uint8 codeword; uint8 comp_count; - codeword = self.rom_read(offset) << bit_count; + codeword = sdd1.mmc_read(offset) << bit_count; bit_count++; if(codeword & 0x80) { - codeword |= self.rom_read(offset + 1) >> (9 - bit_count); + codeword |= sdd1.mmc_read(offset + 1) >> (9 - bit_count); bit_count += code_length; } @@ -183,8 +183,8 @@ uint8 SDD1::Decomp::PEM::get_bit(uint8 context) { //context model void SDD1::Decomp::CM::init(unsigned offset) { - bitplanes_info = self.rom_read(offset) & 0xc0; - context_bits_info = self.rom_read(offset) & 0x30; + bitplanes_info = sdd1.mmc_read(offset) & 0xc0; + context_bits_info = sdd1.mmc_read(offset) & 0x30; bit_number = 0; for(unsigned i = 0; i < 8; i++) previous_bitplane_bits[i] = 0; switch(bitplanes_info) { @@ -231,7 +231,7 @@ uint8 SDD1::Decomp::CM::get_bit() { //output logic void SDD1::Decomp::OL::init(unsigned offset) { - bitplanes_info = self.rom_read(offset) & 0xc0; + bitplanes_info = sdd1.mmc_read(offset) & 0xc0; r0 = 0x01; } @@ -276,10 +276,6 @@ uint8 SDD1::Decomp::read() { return ol.decompress(); } -uint8 SDD1::Decomp::rom_read(unsigned offset) { - return sdd1.rom_read(offset); -} - SDD1::Decomp::Decomp() : im(*this), gcd(*this), bg0(*this, 0), bg1(*this, 1), bg2(*this, 2), bg3(*this, 3), bg4(*this, 4), bg5(*this, 5), bg6(*this, 6), bg7(*this, 7), diff --git a/bsnes/sfc/chip/sdd1/decomp.hpp b/bsnes/sfc/chip/sdd1/decomp.hpp index 6c83d1d93..065e64bc6 100755 --- a/bsnes/sfc/chip/sdd1/decomp.hpp +++ b/bsnes/sfc/chip/sdd1/decomp.hpp @@ -70,7 +70,6 @@ struct Decomp { void init(unsigned offset); uint8 read(); - uint8 rom_read(unsigned offset); Decomp(); IM im; diff --git a/bsnes/sfc/chip/sdd1/sdd1.cpp b/bsnes/sfc/chip/sdd1/sdd1.cpp index c778dc84c..ccd330fbf 100755 --- a/bsnes/sfc/chip/sdd1/sdd1.cpp +++ b/bsnes/sfc/chip/sdd1/sdd1.cpp @@ -14,11 +14,13 @@ void SDD1::init() { void SDD1::load() { //hook S-CPU DMA MMIO registers to gather information for struct dma[]; //buffer address and transfer size information for use in SDD1::mcu_read() - bus.map(Bus::MapMode::Direct, 0x00, 0x3f, 0x4300, 0x437f, { &SDD1::mmio_read, &sdd1 }, { &SDD1::mmio_write, &sdd1 }); - bus.map(Bus::MapMode::Direct, 0x80, 0xbf, 0x4300, 0x437f, { &SDD1::mmio_read, &sdd1 }, { &SDD1::mmio_write, &sdd1 }); + bus.map(Bus::MapMode::Direct, 0x00, 0x3f, 0x4300, 0x437f, {&SDD1::mmio_read, &sdd1}, {&SDD1::mmio_write, &sdd1}); + bus.map(Bus::MapMode::Direct, 0x80, 0xbf, 0x4300, 0x437f, {&SDD1::mmio_read, &sdd1}, {&SDD1::mmio_write, &sdd1}); } void SDD1::unload() { + rom.reset(); + ram.reset(); } void SDD1::power() { @@ -84,8 +86,8 @@ void SDD1::mmio_write(unsigned addr, uint8 data) { } } -uint8 SDD1::rom_read(unsigned addr) { - return cartridge.rom.read(mmc[(addr >> 20) & 3] + (addr & 0x0fffff)); +uint8 SDD1::mmc_read(unsigned addr) { + return rom.read(mmc[(addr >> 20) & 3] + (addr & 0x0fffff)); } //SDD1::mcu_read() is mapped to $c0-ff:0000-ffff @@ -107,6 +109,20 @@ uint8 SDD1::rom_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); + } + + if((addr & 0x408000) == 0x008000) { //$00-3f|80-bf:8000-ffff + addr = ((addr & 0x7f0000) >> 1) | (addr & 0x7fff); + return rom.read(addr); + } + + //$40-7f|c0-ff:0000-ffff (MMC) if(sdd1_enable & xfer_enable) { //at least one channel has S-DD1 decompression enabled ... for(unsigned i = 0; i < 8; i++) { @@ -133,16 +149,17 @@ uint8 SDD1::mcu_read(unsigned addr) { } //S-DD1 decompressor enabled //S-DD1 decompression mode inactive; return ROM data - return cartridge.rom.read(mmc[(addr >> 20) & 3] + (addr & 0x0fffff)); + return mmc_read(addr); } void SDD1::mcu_write(unsigned addr, uint8 data) { -} + if((addr & 0x60e000) == 0x006000) { //$00-3f|80-bf:6000-7fff + return ram.write(addr & 0x1fff, data); + } -SDD1::SDD1() { -} - -SDD1::~SDD1() { + if((addr & 0xf08000) == 0x700000) { //$70-7f:0000-7fff + return ram.write(addr & 0x1fff, data); + } } } diff --git a/bsnes/sfc/chip/sdd1/sdd1.hpp b/bsnes/sfc/chip/sdd1/sdd1.hpp index 4cc68939d..d7708b8e4 100755 --- a/bsnes/sfc/chip/sdd1/sdd1.hpp +++ b/bsnes/sfc/chip/sdd1/sdd1.hpp @@ -1,4 +1,7 @@ struct SDD1 { + MappedRAM rom; + MappedRAM ram; + void init(); void load(); void unload(); @@ -8,13 +11,11 @@ struct SDD1 { uint8 mmio_read(unsigned addr); void mmio_write(unsigned addr, uint8 data); - uint8 rom_read(unsigned addr); + uint8 mmc_read(unsigned addr); uint8 mcu_read(unsigned addr); void mcu_write(unsigned addr, uint8 data); void serialize(serializer&); - SDD1(); - ~SDD1(); private: uint8 sdd1_enable; //channel bit-mask diff --git a/bsnes/sfc/chip/sdd1/serialization.cpp b/bsnes/sfc/chip/sdd1/serialization.cpp index 1741e1a4f..c0e947504 100755 --- a/bsnes/sfc/chip/sdd1/serialization.cpp +++ b/bsnes/sfc/chip/sdd1/serialization.cpp @@ -1,6 +1,8 @@ #ifdef SDD1_CPP void SDD1::serialize(serializer &s) { + s.array(ram.data(), ram.size()); + s.integer(sdd1_enable); s.integer(xfer_enable); s.integer(dma_ready); diff --git a/bsnes/sfc/interface/interface.cpp b/bsnes/sfc/interface/interface.cpp index 971a858ac..1902ee314 100755 --- a/bsnes/sfc/interface/interface.cpp +++ b/bsnes/sfc/interface/interface.cpp @@ -27,11 +27,18 @@ unsigned Interface::group(unsigned id) { switch(id) { case ID::ROM: case ID::RAM: + case ID::SA1ROM: + case ID::SA1IRAM: + case ID::SA1BWRAM: case ID::ArmDSP: case ID::HitachiDSP: case ID::Nec7725DSP: case ID::Nec96050DSP: case ID::NecDSPRAM: + case ID::EpsonRTC: + case ID::SharpRTC: + case ID::SDD1ROM: + case ID::SDD1RAM: case ID::BsxPSRAM: return 0; case ID::SuperGameBoy: @@ -72,13 +79,12 @@ void Interface::load(unsigned id, const stream &stream, const string &manifest) stream.read(smp.iplrom, min(64u, stream.size())); } - if(id == ID::ROM) { - stream.read(cartridge.rom.data(), min(cartridge.rom.size(), stream.size())); - } + if(id == ID::ROM) cartridge.rom.read(stream); + if(id == ID::RAM) cartridge.ram.read(stream); - if(id == ID::RAM) { - stream.read(cartridge.ram.data(), min(cartridge.ram.size(), stream.size())); - } + if(id == ID::SA1ROM) sa1.rom.read(stream); + if(id == ID::SA1IRAM) sa1.iram.read(stream); + if(id == ID::SA1BWRAM) sa1.bwram.read(stream); if(id == ID::ArmDSP) { stream.read(armdsp.firmware, stream.size()); @@ -114,6 +120,9 @@ void Interface::load(unsigned id, const stream &stream, const string &manifest) sharprtc.load(data); } + if(id == ID::SDD1ROM) sdd1.rom.read(stream); + if(id == ID::SDD1RAM) sdd1.ram.read(stream); + if(id == ID::SuperGameBoyROM) { stream.read(GameBoy::cartridge.romdata, min(GameBoy::cartridge.romsize, stream.size())); } @@ -123,20 +132,15 @@ void Interface::load(unsigned id, const stream &stream, const string &manifest) } if(id == ID::BsxFlashROM) { - bsxflash.memory.copy(stream); + bsxflash.memory.read(stream); } if(id == ID::BsxPSRAM) { stream.read(bsxcartridge.psram.data(), min(stream.size(), bsxcartridge.psram.size())); } - if(id == ID::SufamiTurboSlotAROM) { - sufamiturbo.slotA.rom.copy(stream); - } - - if(id == ID::SufamiTurboSlotBROM) { - sufamiturbo.slotB.rom.copy(stream); - } + if(id == ID::SufamiTurboSlotAROM) sufamiturbo.slotA.rom.read(stream); + if(id == ID::SufamiTurboSlotBROM) sufamiturbo.slotB.rom.read(stream); if(id == ID::SufamiTurboSlotARAM) { stream.read(sufamiturbo.slotA.ram.data(), min(sufamiturbo.slotA.ram.size(), stream.size())); @@ -148,9 +152,9 @@ void Interface::load(unsigned id, const stream &stream, const string &manifest) } void Interface::save(unsigned id, const stream &stream) { - if(id == ID::RAM) { - stream.write(cartridge.ram.data(), cartridge.ram.size()); - } + if(id == ID::RAM) stream.write(cartridge.ram.data(), cartridge.ram.size()); + if(id == ID::SA1IRAM) stream.write(sa1.iram.data(), sa1.iram.size()); + if(id == ID::SA1BWRAM) stream.write(sa1.bwram.data(), sa1.bwram.size()); if(id == ID::NecDSPRAM) { for(unsigned n = 0; n < 2048; n++) stream.writel(necdsp.dataRAM[n], 2); @@ -168,6 +172,8 @@ void Interface::save(unsigned id, const stream &stream) { stream.write(data, sizeof data); } + if(id == ID::SDD1RAM) stream.write(sdd1.ram.data(), sdd1.ram.size()); + if(id == ID::SuperGameBoyRAM) { stream.write(GameBoy::cartridge.ramdata, GameBoy::cartridge.ramsize); } diff --git a/bsnes/sfc/interface/interface.hpp b/bsnes/sfc/interface/interface.hpp index 2b6bebcb0..ac4a8f258 100755 --- a/bsnes/sfc/interface/interface.hpp +++ b/bsnes/sfc/interface/interface.hpp @@ -17,6 +17,10 @@ struct ID { ROM, RAM, + SA1ROM, + SA1IRAM, + SA1BWRAM, + ArmDSP, HitachiDSP, Nec7725DSP, @@ -26,6 +30,9 @@ struct ID { EpsonRTC, SharpRTC, + SDD1ROM, + SDD1RAM, + SuperGameBoyROM, SuperGameBoyRAM, diff --git a/bsnes/sfc/memory/memory-inline.hpp b/bsnes/sfc/memory/memory-inline.hpp index b3a13c914..22273066e 100755 --- a/bsnes/sfc/memory/memory-inline.hpp +++ b/bsnes/sfc/memory/memory-inline.hpp @@ -40,6 +40,10 @@ void MappedRAM::copy(const stream &memory) { memory.read(data_, memory.size()); } +void MappedRAM::read(const stream &memory) { + memory.read(data_, min(memory.size(), size_)); +} + void MappedRAM::write_protect(bool status) { write_protect_ = status; } uint8* MappedRAM::data() { return data_; } unsigned MappedRAM::size() const { return size_; } diff --git a/bsnes/sfc/memory/memory.hpp b/bsnes/sfc/memory/memory.hpp index c0bc78700..3b4db227e 100755 --- a/bsnes/sfc/memory/memory.hpp +++ b/bsnes/sfc/memory/memory.hpp @@ -25,6 +25,7 @@ struct MappedRAM : Memory { inline void reset(); inline void map(uint8*, unsigned); inline void copy(const stream &memory); + inline void read(const stream &memory); inline void write_protect(bool status); inline uint8* data();