[Mem] New handlers using if-range checks instead of switch

This commit is contained in:
irisz64
2025-07-24 15:49:13 +02:00
parent 3b5ed1a160
commit 741b9adfbf
3 changed files with 202 additions and 218 deletions

View File

@@ -36,10 +36,25 @@
#define CART_REGION_END_1_2 0x1FBFFFFF
#define CART_REGION_END_2_1 0x05FFFFFF
#define CART_REGION_END_2_2 0x0FFFFFFF
#define RSP_MEM_REGION_END 0x0403FFFF
#define AI_REGION_START 0x04500000
#define AI_REGION_END 0x045FFFFF
#define MMIO_REGION_START_1 0x04040000
#define MMIO_REGION_START_2 0x04300000
#define MMIO_REGION_END_1 0x041FFFFF
#define MMIO_REGION_END_2 0x048FFFFF
#define UNUSED_START_1 0x00800000
#define UNUSED_END_1 0x03EFFFFF
#define UNUSED_START_2 0x04200000
#define UNUSED_END_2 0x042FFFFF
#define UNUSED_START_3 0x04900000
#define UNUSED_END_3 0x04FFFFFF
#define UNUSED_START_4 0x1FC00800
#define UNUSED_END_4 0xFFFFFFFF
#define RDRAM_REGION RDRAM_REGION_START ... RDRAM_REGION_END
#define RSP_MEM_REGION DMEM_REGION_START ... 0x0403FFFF
#define MMIO_REGION 0x04040000 ... 0x041FFFFF : case 0x04300000 ... 0x048FFFFF
#define RSP_MEM_REGION DMEM_REGION_START ... RSP_MEM_REGION_END
#define MMIO_REGION MMIO_REGION_START_1 ... MMIO_REGION_END_1 : case MMIO_REGION_START_2 ... MMIO_REGION_END_2
#define SP_REGION 0x04040000 ... 0x040FFFFF
#define DP_CMD_REGION 0x04100000 ... 0x041FFFFF
#define RSP_REGION 0x04040000 ... 0x040FFFFF

View File

@@ -189,174 +189,144 @@ template <>
u8 Mem::Read(Registers &regs, const u32 paddr) {
const SI &si = mmio.si;
switch (paddr) {
case RDRAM_REGION:
return mmio.rdp.ReadRDRAM<u8>(paddr);
case RSP_MEM_REGION:
{
const auto &src = paddr & 0x1000 ? mmio.rsp.imem : mmio.rsp.dmem;
return src[BYTE_ADDRESS(paddr & 0xfff)];
}
case REGION_CART:
return mmio.pi.BusRead<u8, false>(paddr);
case 0x04040000 ... 0x040FFFFF:
case 0x04100000 ... 0x041FFFFF:
case 0x04600000 ... 0x048FFFFF:
case 0x04300000 ... 0x044FFFFF:
panic("MMIO Read<u8>!\n");
case AI_REGION:
{
const u32 w = mmio.ai.Read(paddr & ~3);
const int offs = 3 - (paddr & 3);
return w >> offs * 8 & 0xff;
}
case PIF_ROM_REGION:
return si.pif.bootrom[BYTE_ADDRESS(paddr) - PIF_ROM_REGION_START];
case PIF_RAM_REGION:
return si.pif.ram[paddr - PIF_RAM_REGION_START];
case 0x00800000 ... 0x03EFFFFF: // unused
case 0x04200000 ... 0x042FFFFF: // unused
case 0x04900000 ... 0x04FFFFFF: // unused
case 0x1FC00800 ... 0xFFFFFFFF: // unused
return 0;
default:
panic("Unimplemented 8-bit read at address {:08X} (PC = {:016X})", paddr, (u64)regs.pc);
return 0;
if(Util::IsInsideRange(paddr, RDRAM_REGION_START, RDRAM_REGION_END)) return mmio.rdp.ReadRDRAM<u8>(paddr);
if(Util::IsInsideRange(paddr, DMEM_REGION_START, RSP_MEM_REGION_END)) {
const auto &src = paddr & 0x1000 ? mmio.rsp.imem : mmio.rsp.dmem;
return src[BYTE_ADDRESS(paddr & 0xfff)];
}
if(Util::IsInsideRange(paddr, CART_REGION_START_2_1, CART_REGION_END_1_2)) return mmio.pi.BusRead<u8, false>(paddr);
if(Util::IsInsideRange(paddr, AI_REGION_START, AI_REGION_END)) {
const u32 w = mmio.ai.Read(paddr & ~3);
const int offs = 3 - (paddr & 3);
return w >> offs * 8 & 0xff;
}
if(Util::IsInsideRange(paddr, MMIO_REGION_START_1, MMIO_REGION_END_1) ||
Util::IsInsideRange(paddr, MMIO_REGION_START_2, MMIO_REGION_END_2)) panic("MMIO Read<u8>!");
if(Util::IsInsideRange(paddr, PIF_ROM_REGION_START, PIF_ROM_REGION_END)) return si.pif.bootrom[BYTE_ADDRESS(paddr) - PIF_ROM_REGION_START];
if(Util::IsInsideRange(paddr, PIF_RAM_REGION_START, PIF_RAM_REGION_END)) return si.pif.ram[paddr - PIF_RAM_REGION_START];
if(Util::IsInsideRange(paddr, UNUSED_START_1, UNUSED_END_1) || // unused
Util::IsInsideRange(paddr, UNUSED_START_2, UNUSED_END_2) ||
Util::IsInsideRange(paddr, UNUSED_START_3, UNUSED_END_3) ||
Util::IsInsideRange(paddr, UNUSED_START_4, UNUSED_END_4)) return 0;
panic("Unimplemented 8-bit read at address {:08X} (PC = {:016X})", paddr, (u64)regs.pc);
return 0;
}
template <>
u16 Mem::Read(Registers &regs, const u32 paddr) {
const SI &si = mmio.si;
switch (paddr) {
case RDRAM_REGION:
return mmio.rdp.ReadRDRAM<u16>(paddr);
case RSP_MEM_REGION:
{
const auto &src = paddr & 0x1000 ? mmio.rsp.imem : mmio.rsp.dmem;
return Util::ReadAccess<u16>(src, HALF_ADDRESS(paddr & 0xfff));
}
case MMIO_REGION:
return mmio.Read(paddr);
case REGION_CART:
return mmio.pi.BusRead<u16, false>(paddr);
case PIF_ROM_REGION:
return Util::ReadAccess<u16>(si.pif.bootrom, HALF_ADDRESS(paddr) - PIF_ROM_REGION_START);
case PIF_RAM_REGION:
return std::byteswap(Util::ReadAccess<u16>(si.pif.ram, paddr - PIF_RAM_REGION_START));
case 0x00800000 ... 0x03EFFFFF:
case 0x04200000 ... 0x042FFFFF:
case 0x04900000 ... 0x04FFFFFF:
case 0x1FC00800 ... 0xFFFFFFFF:
return 0;
default:
panic("Unimplemented 16-bit read at address {:08X} (PC = {:016X})", paddr, (u64)regs.pc);
return 0;
if(Util::IsInsideRange(paddr, RDRAM_REGION_START, RDRAM_REGION_END)) return mmio.rdp.ReadRDRAM<u16>(paddr);
if(Util::IsInsideRange(paddr, DMEM_REGION_START, RSP_MEM_REGION_END)) {
const auto &src = paddr & 0x1000 ? mmio.rsp.imem : mmio.rsp.dmem;
return Util::ReadAccess<u16>(src, HALF_ADDRESS(paddr & 0xfff));
}
if(Util::IsInsideRange(paddr, CART_REGION_START_2_1, CART_REGION_END_1_2)) return mmio.pi.BusRead<u16, false>(paddr);
if(Util::IsInsideRange(paddr, MMIO_REGION_START_1, MMIO_REGION_END_1) ||
Util::IsInsideRange(paddr, MMIO_REGION_START_2, MMIO_REGION_END_2)) return mmio.Read(paddr);
if(Util::IsInsideRange(paddr, PIF_ROM_REGION_START, PIF_ROM_REGION_END)) return Util::ReadAccess<u16>(si.pif.bootrom, HALF_ADDRESS(paddr) - PIF_ROM_REGION_START);
if(Util::IsInsideRange(paddr, PIF_RAM_REGION_START, PIF_RAM_REGION_END)) return std::byteswap(Util::ReadAccess<u16>(si.pif.ram, paddr - PIF_RAM_REGION_START));
if(Util::IsInsideRange(paddr, UNUSED_START_1, UNUSED_END_1) || // unused
Util::IsInsideRange(paddr, UNUSED_START_2, UNUSED_END_2) ||
Util::IsInsideRange(paddr, UNUSED_START_3, UNUSED_END_3) ||
Util::IsInsideRange(paddr, UNUSED_START_4, UNUSED_END_4)) return 0;
panic("Unimplemented 16-bit read at address {:08X} (PC = {:016X})", paddr, (u64)regs.pc);
return 0;
}
template <>
u32 Mem::Read(Registers &regs, const u32 paddr) {
const SI &si = mmio.si;
switch (paddr) {
case RDRAM_REGION:
return mmio.rdp.ReadRDRAM<u32>(paddr);
case RSP_MEM_REGION:
{
const auto &src = paddr & 0x1000 ? mmio.rsp.imem : mmio.rsp.dmem;
return Util::ReadAccess<u32>(src, paddr & 0xfff);
}
case MMIO_REGION:
return mmio.Read(paddr);
case REGION_CART:
return mmio.pi.BusRead<u32, false>(paddr);
case PIF_ROM_REGION:
return Util::ReadAccess<u32>(si.pif.bootrom, paddr - PIF_ROM_REGION_START);
case PIF_RAM_REGION:
return std::byteswap(Util::ReadAccess<u32>(si.pif.ram, paddr - PIF_RAM_REGION_START));
case 0x00800000 ... 0x03FFFFFF:
case 0x04200000 ... 0x042FFFFF:
case 0x04900000 ... 0x04FFFFFF:
case 0x1FC00800 ... 0xFFFFFFFF:
return 0;
default:
panic("Unimplemented 32-bit read at address {:08X} (PC = {:016X})", paddr, (u64)regs.pc);
return 0;
if(Util::IsInsideRange(paddr, RDRAM_REGION_START, RDRAM_REGION_END)) return mmio.rdp.ReadRDRAM<u32>(paddr);
if(Util::IsInsideRange(paddr, DMEM_REGION_START, RSP_MEM_REGION_END)) {
const auto &src = paddr & 0x1000 ? mmio.rsp.imem : mmio.rsp.dmem;
return Util::ReadAccess<u32>(src, paddr & 0xfff);
}
if(Util::IsInsideRange(paddr, CART_REGION_START_2_1, CART_REGION_END_1_2)) return mmio.pi.BusRead<u32, false>(paddr);
if(Util::IsInsideRange(paddr, MMIO_REGION_START_1, MMIO_REGION_END_1) ||
Util::IsInsideRange(paddr, MMIO_REGION_START_2, MMIO_REGION_END_2)) return mmio.Read(paddr);
if(Util::IsInsideRange(paddr, PIF_ROM_REGION_START, PIF_ROM_REGION_END)) return Util::ReadAccess<u32>(si.pif.bootrom, paddr - PIF_ROM_REGION_START);
if(Util::IsInsideRange(paddr, PIF_RAM_REGION_START, PIF_RAM_REGION_END)) return std::byteswap(Util::ReadAccess<u32>(si.pif.ram, paddr - PIF_RAM_REGION_START));
if(Util::IsInsideRange(paddr, UNUSED_START_1, UNUSED_END_1) || // unused
Util::IsInsideRange(paddr, UNUSED_START_2, UNUSED_END_2) ||
Util::IsInsideRange(paddr, UNUSED_START_3, UNUSED_END_3) ||
Util::IsInsideRange(paddr, UNUSED_START_4, UNUSED_END_4)) return 0;
panic("Unimplemented 32-bit read at address {:08X} (PC = {:016X})", paddr, (u64)regs.pc);
return 0;
}
template <>
u64 Mem::Read(Registers &regs, const u32 paddr) {
const SI &si = mmio.si;
switch (paddr) {
case RDRAM_REGION:
return mmio.rdp.ReadRDRAM<u64>(paddr);
case RSP_MEM_REGION:
{
const auto &src = paddr & 0x1000 ? mmio.rsp.imem : mmio.rsp.dmem;
return Util::ReadAccess<u64>(src, paddr & 0xfff);
}
case MMIO_REGION:
return mmio.Read(paddr);
case REGION_CART:
return mmio.pi.BusRead<u64, false>(paddr);
case PIF_ROM_REGION:
return Util::ReadAccess<u64>(si.pif.bootrom, paddr - PIF_ROM_REGION_START);
case PIF_RAM_REGION:
return std::byteswap(Util::ReadAccess<u64>(si.pif.ram, paddr - PIF_RAM_REGION_START));
case 0x00800000 ... 0x03EFFFFF:
case 0x04200000 ... 0x042FFFFF:
case 0x04900000 ... 0x04FFFFFF:
case 0x1FC00800 ... 0xFFFFFFFF:
return 0;
default:
panic("Unimplemented 32-bit read at address {:08X} (PC = {:016X})", paddr, (u64)regs.pc);
return 0;
if(Util::IsInsideRange(paddr, RDRAM_REGION_START, RDRAM_REGION_END)) return mmio.rdp.ReadRDRAM<u64>(paddr);
if(Util::IsInsideRange(paddr, DMEM_REGION_START, RSP_MEM_REGION_END)) {
const auto &src = paddr & 0x1000 ? mmio.rsp.imem : mmio.rsp.dmem;
return Util::ReadAccess<u64>(src, paddr & 0xfff);
}
if(Util::IsInsideRange(paddr, CART_REGION_START_2_1, CART_REGION_END_1_2)) return mmio.pi.BusRead<u64, false>(paddr);
if(Util::IsInsideRange(paddr, MMIO_REGION_START_1, MMIO_REGION_END_1) ||
Util::IsInsideRange(paddr, MMIO_REGION_START_2, MMIO_REGION_END_2)) return mmio.Read(paddr);
if(Util::IsInsideRange(paddr, PIF_ROM_REGION_START, PIF_ROM_REGION_END)) return Util::ReadAccess<u64>(si.pif.bootrom, paddr - PIF_ROM_REGION_START);
if(Util::IsInsideRange(paddr, PIF_RAM_REGION_START, PIF_RAM_REGION_END)) return std::byteswap(Util::ReadAccess<u64>(si.pif.ram, paddr - PIF_RAM_REGION_START));
if(Util::IsInsideRange(paddr, UNUSED_START_1, UNUSED_END_1) || // unused
Util::IsInsideRange(paddr, UNUSED_START_2, UNUSED_END_2) ||
Util::IsInsideRange(paddr, UNUSED_START_3, UNUSED_END_3) ||
Util::IsInsideRange(paddr, UNUSED_START_4, UNUSED_END_4)) return 0;
panic("Unimplemented 64-bit read at address {:08X} (PC = {:016X})", paddr, (u64)regs.pc);
return 0;
}
template <>
void Mem::WriteInterpreter<u8>(Registers &regs, u32 paddr, u32 val) {
SI &si = mmio.si;
switch (paddr) {
case RDRAM_REGION:
mmio.rdp.WriteRDRAM<u8>(paddr, val);
break;
case RSP_MEM_REGION:
{
val = val << (8 * (3 - (paddr & 3)));
auto &dest = paddr & 0x1000 ? mmio.rsp.imem : mmio.rsp.dmem;
paddr = (paddr & 0xFFF) & ~3;
Util::WriteAccess<u32>(dest, paddr, val);
}
break;
case REGION_CART:
if(Util::IsInsideRange(paddr, RDRAM_REGION_START, RDRAM_REGION_END)) { mmio.rdp.WriteRDRAM<u8>(paddr, val); return; }
if(Util::IsInsideRange(paddr, DMEM_REGION_START, RSP_MEM_REGION_END)) {
val = val << (8 * (3 - (paddr & 3)));
auto &dest = paddr & 0x1000 ? mmio.rsp.imem : mmio.rsp.dmem;
paddr = (paddr & 0xFFF) & ~3;
Util::WriteAccess<u32>(dest, paddr, val);
return;
}
if(Util::IsInsideRange(paddr, CART_REGION_START_2_1, CART_REGION_END_1_2)) {
trace("BusWrite<u8> @ {:08X} = {:02X}", paddr, val);
mmio.pi.BusWrite<u8, false>(paddr, val);
break;
case MMIO_REGION:
panic("MMIO Write<u8>!");
case PIF_RAM_REGION:
return;
}
if(Util::IsInsideRange(paddr, MMIO_REGION_START_1, MMIO_REGION_END_1) ||
Util::IsInsideRange(paddr, MMIO_REGION_START_2, MMIO_REGION_END_2)) panic("MMIO Write<u8>!");
if(Util::IsInsideRange(paddr, PIF_RAM_REGION_START, PIF_RAM_REGION_END)) {
val = val << (8 * (3 - (paddr & 3)));
paddr = (paddr - PIF_RAM_REGION_START) & ~3;
Util::WriteAccess<u32>(si.pif.ram, paddr, std::byteswap(val));
si.pif.ProcessCommands(*this);
break;
case 0x00800000 ... 0x03EFFFFF:
case 0x04200000 ... 0x042FFFFF:
case 0x04900000 ... 0x04FFFFFF:
case PIF_ROM_REGION:
case 0x1FC00800 ... 0x7FFFFFFF:
case 0x80000000 ... 0xFFFFFFFF:
break;
default:
panic("Unimplemented 8-bit write at address {:08X} with value {:02X} (PC = {:016X})", paddr, val,
(u64)regs.pc);
return;
}
if(Util::IsInsideRange(paddr, UNUSED_START_1, UNUSED_END_1) || // unused
Util::IsInsideRange(paddr, UNUSED_START_2, UNUSED_END_2) ||
Util::IsInsideRange(paddr, UNUSED_START_3, UNUSED_END_3) ||
Util::IsInsideRange(paddr, PIF_ROM_REGION_START, PIF_ROM_REGION_END) ||
Util::IsInsideRange(paddr, UNUSED_START_4, UNUSED_END_4)) return;
panic("Unimplemented 8-bit write at address {:08X} with value {:02X} (PC = {:016X})", paddr, val, (u64)regs.pc);
}
#ifndef __aarch64__
@@ -377,41 +347,39 @@ template <>
void Mem::WriteInterpreter<u16>(Registers &regs, u32 paddr, u32 val) {
SI &si = mmio.si;
switch (paddr) {
case RDRAM_REGION:
mmio.rdp.WriteRDRAM<u16>(paddr, val);
break;
case RSP_MEM_REGION:
{
val = val << (16 * !(paddr & 2));
auto &dest = paddr & 0x1000 ? mmio.rsp.imem : mmio.rsp.dmem;
paddr = (paddr & 0xFFF) & ~3;
Util::WriteAccess<u32>(dest, paddr, val);
}
break;
case REGION_CART:
if(Util::IsInsideRange(paddr, RDRAM_REGION_START, RDRAM_REGION_END)) { mmio.rdp.WriteRDRAM<u16>(paddr, val); return; }
if(Util::IsInsideRange(paddr, DMEM_REGION_START, RSP_MEM_REGION_END)) {
val = val << (16 * !(paddr & 2));
auto &dest = paddr & 0x1000 ? mmio.rsp.imem : mmio.rsp.dmem;
paddr = (paddr & 0xFFF) & ~3;
Util::WriteAccess<u32>(dest, paddr, val);
return;
}
if(Util::IsInsideRange(paddr, CART_REGION_START_2_1, CART_REGION_END_1_2)) {
trace("BusWrite<u8> @ {:08X} = {:04X}", paddr, val);
mmio.pi.BusWrite<u16, false>(paddr, val);
break;
case MMIO_REGION:
panic("MMIO Write<u16>!");
case PIF_RAM_REGION:
return;
}
if(Util::IsInsideRange(paddr, MMIO_REGION_START_1, MMIO_REGION_END_1) ||
Util::IsInsideRange(paddr, MMIO_REGION_START_2, MMIO_REGION_END_2)) panic("MMIO Write<u16>!");
if(Util::IsInsideRange(paddr, PIF_RAM_REGION_START, PIF_RAM_REGION_END)) {
val = val << (16 * !(paddr & 2));
paddr &= ~3;
Util::WriteAccess<u32>(si.pif.ram, paddr - PIF_RAM_REGION_START, std::byteswap(val));
si.pif.ProcessCommands(*this);
break;
case 0x00800000 ... 0x03EFFFFF:
case 0x04200000 ... 0x042FFFFF:
case 0x04900000 ... 0x04FFFFFF:
case PIF_ROM_REGION:
case 0x1FC00800 ... 0x7FFFFFFF:
case 0x80000000 ... 0xFFFFFFFF:
break;
default:
panic("Unimplemented 16-bit write at address {:08X} with value {:04X} (PC = {:016X})", paddr, val,
(u64)regs.pc);
return;
}
if(Util::IsInsideRange(paddr, UNUSED_START_1, UNUSED_END_1) || // unused
Util::IsInsideRange(paddr, UNUSED_START_2, UNUSED_END_2) ||
Util::IsInsideRange(paddr, UNUSED_START_3, UNUSED_END_3) ||
Util::IsInsideRange(paddr, PIF_ROM_REGION_START, PIF_ROM_REGION_END) ||
Util::IsInsideRange(paddr, UNUSED_START_4, UNUSED_END_4)) return;
panic("Unimplemented 16-bit write at address {:08X} with value {:04X} (PC = {:016X})", paddr, val, (u64)regs.pc);
}
#ifndef __aarch64__
@@ -432,38 +400,35 @@ template <>
void Mem::WriteInterpreter<u32>(Registers &regs, const u32 paddr, const u32 val) {
SI &si = mmio.si;
switch (paddr) {
case RDRAM_REGION:
mmio.rdp.WriteRDRAM<u32>(paddr, val);
break;
case RSP_MEM_REGION:
{
auto &dest = paddr & 0x1000 ? mmio.rsp.imem : mmio.rsp.dmem;
Util::WriteAccess<u32>(dest, paddr & 0xfff, val);
}
break;
case REGION_CART:
if(Util::IsInsideRange(paddr, RDRAM_REGION_START, RDRAM_REGION_END)) { mmio.rdp.WriteRDRAM<u32>(paddr, val); return; }
if(Util::IsInsideRange(paddr, DMEM_REGION_START, RSP_MEM_REGION_END)) {
auto &dest = paddr & 0x1000 ? mmio.rsp.imem : mmio.rsp.dmem;
Util::WriteAccess<u32>(dest, paddr & 0xfff, val);
return;
}
if(Util::IsInsideRange(paddr, CART_REGION_START_2_1, CART_REGION_END_1_2)) {
trace("BusWrite<u8> @ {:08X} = {:08X}", paddr, val);
mmio.pi.BusWrite<u32, false>(paddr, val);
break;
case MMIO_REGION:
mmio.Write(paddr, val);
break;
case PIF_RAM_REGION:
return;
}
if(Util::IsInsideRange(paddr, MMIO_REGION_START_1, MMIO_REGION_END_1) ||
Util::IsInsideRange(paddr, MMIO_REGION_START_2, MMIO_REGION_END_2)) { mmio.Write(paddr, val); return; }
if(Util::IsInsideRange(paddr, PIF_RAM_REGION_START, PIF_RAM_REGION_END)) {
Util::WriteAccess<u32>(si.pif.ram, paddr - PIF_RAM_REGION_START, std::byteswap(val));
si.pif.ProcessCommands(*this);
break;
case 0x00800000 ... 0x03EFFFFF:
case 0x04200000 ... 0x042FFFFF:
case 0x04900000 ... 0x04FFFFFF:
case PIF_ROM_REGION:
case 0x1FC00800 ... 0x7FFFFFFF:
case 0x80000000 ... 0xFFFFFFFF:
break;
default:
panic("Unimplemented 32-bit write at address {:08X} with value {:0X} (PC = {:016X})", paddr, val,
(u64)regs.pc);
return;
}
if(Util::IsInsideRange(paddr, UNUSED_START_1, UNUSED_END_1) || // unused
Util::IsInsideRange(paddr, UNUSED_START_2, UNUSED_END_2) ||
Util::IsInsideRange(paddr, UNUSED_START_3, UNUSED_END_3) ||
Util::IsInsideRange(paddr, PIF_ROM_REGION_START, PIF_ROM_REGION_END) ||
Util::IsInsideRange(paddr, UNUSED_START_4, UNUSED_END_4)) return;
panic("Unimplemented 32-bit write at address {:08X} with value {:08X} (PC = {:016X})", paddr, val, (u64)regs.pc);
}
#ifndef __aarch64__
@@ -493,38 +458,36 @@ void Mem::Write(const Registers &regs, const u32 paddr, const u64 val) { WriteIn
void Mem::WriteInterpreter(const Registers &regs, const u32 paddr, u64 val) {
SI &si = mmio.si;
switch (paddr) {
case RDRAM_REGION:
mmio.rdp.WriteRDRAM<u64>(paddr, val);
break;
case RSP_MEM_REGION:
{
auto &dest = paddr & 0x1000 ? mmio.rsp.imem : mmio.rsp.dmem;
val >>= 32;
Util::WriteAccess<u32>(dest, paddr & 0xfff, val);
}
break;
case REGION_CART:
trace("BusWrite<u8> @ {:08X} = {:016X}", paddr, val);
if(Util::IsInsideRange(paddr, RDRAM_REGION_START, RDRAM_REGION_END)) { mmio.rdp.WriteRDRAM<u64>(paddr, val); return; }
if(Util::IsInsideRange(paddr, DMEM_REGION_START, RSP_MEM_REGION_END)) {
auto &dest = paddr & 0x1000 ? mmio.rsp.imem : mmio.rsp.dmem;
val >>= 32;
Util::WriteAccess<u32>(dest, paddr & 0xfff, val);
return;
}
if(Util::IsInsideRange(paddr, CART_REGION_START_2_1, CART_REGION_END_1_2)) {
trace("BusWrite<u64> @ {:08X} = {:016X}", paddr, val);
mmio.pi.BusWrite<false>(paddr, val);
break;
case MMIO_REGION:
panic("MMIO Write!");
case PIF_RAM_REGION:
return;
}
if(Util::IsInsideRange(paddr, MMIO_REGION_START_1, MMIO_REGION_END_1) ||
Util::IsInsideRange(paddr, MMIO_REGION_START_2, MMIO_REGION_END_2)) panic("MMIO Write<u64>!");
if(Util::IsInsideRange(paddr, PIF_RAM_REGION_START, PIF_RAM_REGION_END)) {
Util::WriteAccess<u64>(si.pif.ram, paddr - PIF_RAM_REGION_START, std::byteswap(val));
si.pif.ProcessCommands(*this);
break;
case 0x00800000 ... 0x03EFFFFF:
case 0x04200000 ... 0x042FFFFF:
case 0x04900000 ... 0x04FFFFFF:
case 0x1FC00000 ... 0x1FC007BF:
case 0x1FC00800 ... 0x7FFFFFFF:
case 0x80000000 ... 0xFFFFFFFF:
break;
default:
panic("Unimplemented 64-bit write at address {:08X} with value {:0X} (PC = {:016X})", paddr, val,
(u64)regs.pc);
return;
}
if(Util::IsInsideRange(paddr, UNUSED_START_1, UNUSED_END_1) || // unused
Util::IsInsideRange(paddr, UNUSED_START_2, UNUSED_END_2) ||
Util::IsInsideRange(paddr, UNUSED_START_3, UNUSED_END_3) ||
Util::IsInsideRange(paddr, PIF_ROM_REGION_START, PIF_ROM_REGION_END) ||
Util::IsInsideRange(paddr, UNUSED_START_4, UNUSED_END_4)) return;
panic("Unimplemented 64-bit write at address {:08X} with value {:016X} (PC = {:016X})", paddr, val, (u64)regs.pc);
}
template <>