2016-03-26 01:56:15 +00:00
|
|
|
auto SuperFX::bus_read(uint24 addr, uint8 data) -> uint8 {
|
2011-01-16 13:17:45 +00:00
|
|
|
if((addr & 0xc00000) == 0x000000) { //$00-3f:0000-7fff, $00-3f:8000-ffff
|
2016-02-09 11:51:12 +00:00
|
|
|
while(!regs.scmr.ron && !scheduler.synchronizing()) {
|
2012-04-29 06:16:44 +00:00
|
|
|
step(6);
|
2015-12-14 09:41:06 +00:00
|
|
|
synchronizeCPU();
|
2011-01-16 13:17:45 +00:00
|
|
|
}
|
2012-07-09 11:40:23 +00:00
|
|
|
return rom.read((((addr & 0x3f0000) >> 1) | (addr & 0x7fff)) & rom_mask);
|
2011-01-16 13:17:45 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if((addr & 0xe00000) == 0x400000) { //$40-5f:0000-ffff
|
2016-02-09 11:51:12 +00:00
|
|
|
while(!regs.scmr.ron && !scheduler.synchronizing()) {
|
2012-04-29 06:16:44 +00:00
|
|
|
step(6);
|
2015-12-14 09:41:06 +00:00
|
|
|
synchronizeCPU();
|
2011-01-16 13:17:45 +00:00
|
|
|
}
|
2012-07-09 11:40:23 +00:00
|
|
|
return rom.read(addr & rom_mask);
|
2011-01-16 13:17:45 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if((addr & 0xe00000) == 0x600000) { //$60-7f:0000-ffff
|
2016-02-09 11:51:12 +00:00
|
|
|
while(!regs.scmr.ran && !scheduler.synchronizing()) {
|
2012-04-29 06:16:44 +00:00
|
|
|
step(6);
|
2015-12-14 09:41:06 +00:00
|
|
|
synchronizeCPU();
|
2011-01-16 13:17:45 +00:00
|
|
|
}
|
2012-07-09 11:40:23 +00:00
|
|
|
return ram.read(addr & ram_mask);
|
2011-01-16 13:17:45 +00:00
|
|
|
}
|
2016-03-26 01:56:15 +00:00
|
|
|
|
|
|
|
return data;
|
2011-01-16 13:17:45 +00:00
|
|
|
}
|
|
|
|
|
2016-03-26 01:56:15 +00:00
|
|
|
auto SuperFX::bus_write(uint24 addr, uint8 data) -> void {
|
2011-01-16 13:17:45 +00:00
|
|
|
if((addr & 0xe00000) == 0x600000) { //$60-7f:0000-ffff
|
2016-02-09 11:51:12 +00:00
|
|
|
while(!regs.scmr.ran && !scheduler.synchronizing()) {
|
2012-04-29 06:16:44 +00:00
|
|
|
step(6);
|
2015-12-14 09:41:06 +00:00
|
|
|
synchronizeCPU();
|
2011-01-16 13:17:45 +00:00
|
|
|
}
|
2012-07-09 11:40:23 +00:00
|
|
|
return ram.write(addr & ram_mask, data);
|
2011-01-16 13:17:45 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-06-27 02:38:47 +00:00
|
|
|
auto SuperFX::op_read(uint16 addr) -> uint8 {
|
2010-08-09 13:28:56 +00:00
|
|
|
uint16 offset = addr - regs.cbr;
|
|
|
|
if(offset < 512) {
|
|
|
|
if(cache.valid[offset >> 4] == false) {
|
|
|
|
unsigned dp = offset & 0xfff0;
|
|
|
|
unsigned sp = (regs.pbr << 16) + ((regs.cbr + dp) & 0xfff0);
|
|
|
|
for(unsigned n = 0; n < 16; n++) {
|
2015-06-28 08:44:56 +00:00
|
|
|
step(regs.clsr ? 5 : 6);
|
2011-01-16 13:17:45 +00:00
|
|
|
cache.buffer[dp++] = bus_read(sp++);
|
2010-08-09 13:28:56 +00:00
|
|
|
}
|
|
|
|
cache.valid[offset >> 4] = true;
|
|
|
|
} else {
|
2015-06-28 08:44:56 +00:00
|
|
|
step(regs.clsr ? 1 : 2);
|
2010-08-09 13:28:56 +00:00
|
|
|
}
|
|
|
|
return cache.buffer[offset];
|
|
|
|
}
|
|
|
|
|
|
|
|
if(regs.pbr <= 0x5f) {
|
|
|
|
//$[00-5f]:[0000-ffff] ROM
|
|
|
|
rombuffer_sync();
|
2015-06-28 08:44:56 +00:00
|
|
|
step(regs.clsr ? 5 : 6);
|
2011-01-16 13:17:45 +00:00
|
|
|
return bus_read((regs.pbr << 16) + addr);
|
2010-08-09 13:28:56 +00:00
|
|
|
} else {
|
|
|
|
//$[60-7f]:[0000-ffff] RAM
|
|
|
|
rambuffer_sync();
|
2015-06-28 08:44:56 +00:00
|
|
|
step(regs.clsr ? 5 : 6);
|
2011-01-16 13:17:45 +00:00
|
|
|
return bus_read((regs.pbr << 16) + addr);
|
2010-08-09 13:28:56 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-06-27 02:38:47 +00:00
|
|
|
auto SuperFX::peekpipe() -> uint8 {
|
2010-08-09 13:28:56 +00:00
|
|
|
uint8 result = regs.pipeline;
|
|
|
|
regs.pipeline = op_read(regs.r[15]);
|
|
|
|
r15_modified = false;
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
2015-06-27 02:38:47 +00:00
|
|
|
auto SuperFX::pipe() -> uint8 {
|
2010-08-09 13:28:56 +00:00
|
|
|
uint8 result = regs.pipeline;
|
|
|
|
regs.pipeline = op_read(++regs.r[15]);
|
|
|
|
r15_modified = false;
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
2015-06-27 02:38:47 +00:00
|
|
|
auto SuperFX::cache_flush() -> void {
|
2010-08-09 13:28:56 +00:00
|
|
|
for(unsigned n = 0; n < 32; n++) cache.valid[n] = false;
|
|
|
|
}
|
|
|
|
|
2015-06-27 02:38:47 +00:00
|
|
|
auto SuperFX::cache_mmio_read(uint16 addr) -> uint8 {
|
2010-08-09 13:28:56 +00:00
|
|
|
addr = (addr + regs.cbr) & 511;
|
|
|
|
return cache.buffer[addr];
|
|
|
|
}
|
|
|
|
|
2015-06-27 02:38:47 +00:00
|
|
|
auto SuperFX::cache_mmio_write(uint16 addr, uint8 data) -> void {
|
2010-08-09 13:28:56 +00:00
|
|
|
addr = (addr + regs.cbr) & 511;
|
|
|
|
cache.buffer[addr] = data;
|
|
|
|
if((addr & 15) == 15) cache.valid[addr >> 4] = true;
|
|
|
|
}
|
|
|
|
|
2015-06-27 02:38:47 +00:00
|
|
|
auto SuperFX::memory_reset() -> void {
|
2012-07-09 11:40:23 +00:00
|
|
|
rom_mask = rom.size() - 1;
|
|
|
|
ram_mask = ram.size() - 1;
|
2011-01-16 13:17:45 +00:00
|
|
|
|
2010-08-09 13:28:56 +00:00
|
|
|
for(unsigned n = 0; n < 512; n++) cache.buffer[n] = 0x00;
|
|
|
|
for(unsigned n = 0; n < 32; n++) cache.valid[n] = false;
|
|
|
|
for(unsigned n = 0; n < 2; n++) {
|
|
|
|
pixelcache[n].offset = ~0;
|
|
|
|
pixelcache[n].bitpend = 0x00;
|
|
|
|
}
|
|
|
|
}
|