mirror of https://github.com/bsnes-emu/bsnes.git
Update to v089r14 release.
byuu says: Changelog: - NSS emulation improvement (DIP is 8-bits, not 16-bits; can be remapped via XML now like all the other chips) - SA-1 memory map improvements (IRAM and BWRAM can be saved; ROM, IRAM and BWRAM are separate from Cartridge::ROM, RAM; no MCU) - S-DD1 memory map improvements (ROM, RAM inside mapping; no MCU) - SPC7110 memory map improvements (ROM, RAM inside mapping; no MCU; not finished yet [have to handle 8mbit expansion somehow now) I have tried multiple times now to get the SuperFX core to use internal ROM and RAM (separate from Cartridge::ROM, RAM) to no avail. Not sure what the hell is going on there. Trace logs of 430MB are not enticing ... So right now: SuperFX, SPC7110 and BS-X cheat by mapping stuff to Cartridge::ROM, RAM still. They need to not do that.
This commit is contained in:
parent
fbd52c7e5f
commit
27af50099f
|
@ -1,2 +0,0 @@
|
|||
@mingw32-make -j 8
|
||||
@pause
|
|
@ -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";
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -1 +0,0 @@
|
|||
@mingw32-make clean
|
|
@ -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) {
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
struct NSS {
|
||||
uint16 dip;
|
||||
uint8 dip;
|
||||
|
||||
void init();
|
||||
void load();
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -1,5 +1,3 @@
|
|||
StaticRAM iram;
|
||||
|
||||
struct CPUIRAM : Memory {
|
||||
unsigned size() const;
|
||||
alwaysinline uint8 read(unsigned);
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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) {
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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),
|
||||
|
|
|
@ -70,7 +70,6 @@ struct Decomp {
|
|||
|
||||
void init(unsigned offset);
|
||||
uint8 read();
|
||||
uint8 rom_read(unsigned offset);
|
||||
Decomp();
|
||||
|
||||
IM im;
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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,
|
||||
|
||||
|
|
|
@ -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_; }
|
||||
|
|
|
@ -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();
|
||||
|
|
Loading…
Reference in New Issue