auto SuperFX::readIO(uint24 addr, uint8) -> uint8 { cpu.synchronize(*this); addr = 0x3000 | addr.bits(0,9); if(addr >= 0x3100 && addr <= 0x32ff) { return readCache(addr - 0x3100); } if(addr >= 0x3000 && addr <= 0x301f) { return regs.r[(addr >> 1) & 15] >> ((addr & 1) << 3); } switch(addr) { case 0x3030: { return regs.sfr >> 0; } case 0x3031: { uint8 r = regs.sfr >> 8; regs.sfr.irq = 0; cpu.r.irq = 0; return r; } case 0x3034: { return regs.pbr; } case 0x3036: { return regs.rombr; } case 0x303b: { return regs.vcr; } case 0x303c: { return regs.rambr; } case 0x303e: { return regs.cbr >> 0; } case 0x303f: { return regs.cbr >> 8; } } return 0x00; } auto SuperFX::writeIO(uint24 addr, uint8 data) -> void { cpu.synchronize(*this); addr = 0x3000 | addr.bits(0,9); if(addr >= 0x3100 && addr <= 0x32ff) { return writeCache(addr - 0x3100, data); } if(addr >= 0x3000 && addr <= 0x301f) { uint n = (addr >> 1) & 15; if((addr & 1) == 0) { regs.r[n] = (regs.r[n] & 0xff00) | data; } else { regs.r[n] = (data << 8) | (regs.r[n] & 0xff); } if(n == 14) updateROMBuffer(); if(addr == 0x301f) regs.sfr.g = 1; return; } switch(addr) { case 0x3030: { bool g = regs.sfr.g; regs.sfr = (regs.sfr & 0xff00) | (data << 0); if(g == 1 && regs.sfr.g == 0) { regs.cbr = 0x0000; flushCache(); } } break; case 0x3031: { regs.sfr = (data << 8) | (regs.sfr & 0x00ff); } break; case 0x3033: { regs.bramr = data & 0x01; } break; case 0x3034: { regs.pbr = data & 0x7f; flushCache(); } break; case 0x3037: { regs.cfgr = data; } break; case 0x3038: { regs.scbr = data; } break; case 0x3039: { regs.clsr = data & 0x01; } break; case 0x303a: { regs.scmr = data; } break; } }