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:
Tim Allen 2012-07-08 12:57:34 +10:00
parent fbd52c7e5f
commit 27af50099f
25 changed files with 250 additions and 179 deletions

View File

@ -1,2 +0,0 @@
@mingw32-make -j 8
@pause

View File

@ -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";
}

View File

@ -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;
}
}

View File

@ -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);
}

View File

@ -1 +0,0 @@
@mingw32-make clean

View File

@ -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) {

View File

@ -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) {

View File

@ -1,5 +1,5 @@
struct NSS {
uint16 dip;
uint8 dip;
void init();
void load();

View File

@ -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

View File

@ -1,5 +1,3 @@
StaticRAM iram;
struct CPUIRAM : Memory {
unsigned size() const;
alwaysinline uint8 read(unsigned);

View File

@ -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;

View File

@ -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

View File

@ -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);

View File

@ -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) {
}
}

View File

@ -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;

View File

@ -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);

View File

@ -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),

View File

@ -70,7 +70,6 @@ struct Decomp {
void init(unsigned offset);
uint8 read();
uint8 rom_read(unsigned offset);
Decomp();
IM im;

View File

@ -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);
}
}
}

View File

@ -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

View File

@ -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);

View File

@ -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);
}

View File

@ -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,

View File

@ -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_; }

View File

@ -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();