#include <snes/snes.hpp>
#define SDD1_CPP
namespace SNES {
SDD1 sdd1;
#include "decomp.cpp"
#include "serialization.cpp"
void SDD1::init() {
}
void SDD1::load() {
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() {
}
void SDD1::power() {
}
void SDD1::reset() {
sdd1_enable = 0x00;
xfer_enable = 0x00;
dma_ready = false;
mmc[0] = 0 << 20;
mmc[1] = 1 << 20;
mmc[2] = 2 << 20;
mmc[3] = 3 << 20;
for(unsigned i = 0; i < 8; i++) {
dma[i].addr = 0;
dma[i].size = 0;
}
}
uint8 SDD1::mmio_read(unsigned addr) {
addr &= 0xffff;
if((addr & 0x4380) == 0x4300) {
return cpu.mmio_read(addr);
}
switch(addr) {
case 0x4804: return mmc[0] >> 20;
case 0x4805: return mmc[1] >> 20;
case 0x4806: return mmc[2] >> 20;
case 0x4807: return mmc[3] >> 20;
}
return cpu.regs.mdr;
}
void SDD1::mmio_write(unsigned addr, uint8 data) {
addr &= 0xffff;
if((addr & 0x4380) == 0x4300) {
unsigned channel = (addr >> 4) & 7;
switch(addr & 15) {
case 2: dma[channel].addr = (dma[channel].addr & 0xffff00) + (data << 0); break;
case 3: dma[channel].addr = (dma[channel].addr & 0xff00ff) + (data << 8); break;
case 4: dma[channel].addr = (dma[channel].addr & 0x00ffff) + (data << 16); break;
case 5: dma[channel].size = (dma[channel].size & 0xff00) + (data << 0); break;
case 6: dma[channel].size = (dma[channel].size & 0x00ff) + (data << 8); break;
}
return cpu.mmio_write(addr, data);
}
switch(addr) {
case 0x4800: sdd1_enable = data; break;
case 0x4801: xfer_enable = data; break;
case 0x4804: mmc[0] = data << 20; break;
case 0x4805: mmc[1] = data << 20; break;
case 0x4806: mmc[2] = data << 20; break;
case 0x4807: mmc[3] = data << 20; break;
}
}
uint8 SDD1::rom_read(unsigned addr) {
return cartridge.rom.read(mmc[(addr >> 20) & 3] + (addr & 0x0fffff));
}
uint8 SDD1::mcu_read(unsigned addr) {
if(sdd1_enable & xfer_enable) {
for(unsigned i = 0; i < 8; i++) {
if(sdd1_enable & xfer_enable & (1 << i)) {
if(addr == dma[i].addr) {
if(!dma_ready) {
decomp.init(addr);
dma_ready = true;
}
uint8 data = decomp.read();
if(--dma[i].size == 0) {
dma_ready = false;
xfer_enable &= ~(1 << i);
}
return data;
}
}
}
}
return cartridge.rom.read(mmc[(addr >> 20) & 3] + (addr & 0x0fffff));
}
void SDD1::mcu_write(unsigned addr, uint8 data) {
}
SDD1::SDD1() {
}
SDD1::~SDD1() {
}
}