[Mem] New handlers using if-range checks instead of switch
This commit is contained in:
@@ -36,10 +36,25 @@
|
|||||||
#define CART_REGION_END_1_2 0x1FBFFFFF
|
#define CART_REGION_END_1_2 0x1FBFFFFF
|
||||||
#define CART_REGION_END_2_1 0x05FFFFFF
|
#define CART_REGION_END_2_1 0x05FFFFFF
|
||||||
#define CART_REGION_END_2_2 0x0FFFFFFF
|
#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 RDRAM_REGION RDRAM_REGION_START ... RDRAM_REGION_END
|
||||||
#define RSP_MEM_REGION DMEM_REGION_START ... 0x0403FFFF
|
#define RSP_MEM_REGION DMEM_REGION_START ... RSP_MEM_REGION_END
|
||||||
#define MMIO_REGION 0x04040000 ... 0x041FFFFF : case 0x04300000 ... 0x048FFFFF
|
#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 SP_REGION 0x04040000 ... 0x040FFFFF
|
||||||
#define DP_CMD_REGION 0x04100000 ... 0x041FFFFF
|
#define DP_CMD_REGION 0x04100000 ... 0x041FFFFF
|
||||||
#define RSP_REGION 0x04040000 ... 0x040FFFFF
|
#define RSP_REGION 0x04040000 ... 0x040FFFFF
|
||||||
|
|||||||
@@ -189,174 +189,144 @@ template <>
|
|||||||
u8 Mem::Read(Registers ®s, const u32 paddr) {
|
u8 Mem::Read(Registers ®s, const u32 paddr) {
|
||||||
const SI &si = mmio.si;
|
const SI &si = mmio.si;
|
||||||
|
|
||||||
switch (paddr) {
|
if(Util::IsInsideRange(paddr, RDRAM_REGION_START, RDRAM_REGION_END)) return mmio.rdp.ReadRDRAM<u8>(paddr);
|
||||||
case RDRAM_REGION:
|
if(Util::IsInsideRange(paddr, DMEM_REGION_START, RSP_MEM_REGION_END)) {
|
||||||
return mmio.rdp.ReadRDRAM<u8>(paddr);
|
const auto &src = paddr & 0x1000 ? mmio.rsp.imem : mmio.rsp.dmem;
|
||||||
case RSP_MEM_REGION:
|
return src[BYTE_ADDRESS(paddr & 0xfff)];
|
||||||
{
|
|
||||||
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, 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 <>
|
template <>
|
||||||
u16 Mem::Read(Registers ®s, const u32 paddr) {
|
u16 Mem::Read(Registers ®s, const u32 paddr) {
|
||||||
const SI &si = mmio.si;
|
const SI &si = mmio.si;
|
||||||
|
|
||||||
switch (paddr) {
|
if(Util::IsInsideRange(paddr, RDRAM_REGION_START, RDRAM_REGION_END)) return mmio.rdp.ReadRDRAM<u16>(paddr);
|
||||||
case RDRAM_REGION:
|
if(Util::IsInsideRange(paddr, DMEM_REGION_START, RSP_MEM_REGION_END)) {
|
||||||
return mmio.rdp.ReadRDRAM<u16>(paddr);
|
const auto &src = paddr & 0x1000 ? mmio.rsp.imem : mmio.rsp.dmem;
|
||||||
case RSP_MEM_REGION:
|
return Util::ReadAccess<u16>(src, HALF_ADDRESS(paddr & 0xfff));
|
||||||
{
|
|
||||||
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, 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 <>
|
template <>
|
||||||
u32 Mem::Read(Registers ®s, const u32 paddr) {
|
u32 Mem::Read(Registers ®s, const u32 paddr) {
|
||||||
const SI &si = mmio.si;
|
const SI &si = mmio.si;
|
||||||
|
|
||||||
switch (paddr) {
|
if(Util::IsInsideRange(paddr, RDRAM_REGION_START, RDRAM_REGION_END)) return mmio.rdp.ReadRDRAM<u32>(paddr);
|
||||||
case RDRAM_REGION:
|
if(Util::IsInsideRange(paddr, DMEM_REGION_START, RSP_MEM_REGION_END)) {
|
||||||
return mmio.rdp.ReadRDRAM<u32>(paddr);
|
const auto &src = paddr & 0x1000 ? mmio.rsp.imem : mmio.rsp.dmem;
|
||||||
case RSP_MEM_REGION:
|
return Util::ReadAccess<u32>(src, paddr & 0xfff);
|
||||||
{
|
|
||||||
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, 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 <>
|
template <>
|
||||||
u64 Mem::Read(Registers ®s, const u32 paddr) {
|
u64 Mem::Read(Registers ®s, const u32 paddr) {
|
||||||
const SI &si = mmio.si;
|
const SI &si = mmio.si;
|
||||||
|
|
||||||
switch (paddr) {
|
if(Util::IsInsideRange(paddr, RDRAM_REGION_START, RDRAM_REGION_END)) return mmio.rdp.ReadRDRAM<u64>(paddr);
|
||||||
case RDRAM_REGION:
|
if(Util::IsInsideRange(paddr, DMEM_REGION_START, RSP_MEM_REGION_END)) {
|
||||||
return mmio.rdp.ReadRDRAM<u64>(paddr);
|
const auto &src = paddr & 0x1000 ? mmio.rsp.imem : mmio.rsp.dmem;
|
||||||
case RSP_MEM_REGION:
|
return Util::ReadAccess<u64>(src, paddr & 0xfff);
|
||||||
{
|
|
||||||
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, 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 <>
|
template <>
|
||||||
void Mem::WriteInterpreter<u8>(Registers ®s, u32 paddr, u32 val) {
|
void Mem::WriteInterpreter<u8>(Registers ®s, u32 paddr, u32 val) {
|
||||||
SI &si = mmio.si;
|
SI &si = mmio.si;
|
||||||
|
|
||||||
switch (paddr) {
|
if(Util::IsInsideRange(paddr, RDRAM_REGION_START, RDRAM_REGION_END)) { mmio.rdp.WriteRDRAM<u8>(paddr, val); return; }
|
||||||
case RDRAM_REGION:
|
if(Util::IsInsideRange(paddr, DMEM_REGION_START, RSP_MEM_REGION_END)) {
|
||||||
mmio.rdp.WriteRDRAM<u8>(paddr, val);
|
val = val << (8 * (3 - (paddr & 3)));
|
||||||
break;
|
auto &dest = paddr & 0x1000 ? mmio.rsp.imem : mmio.rsp.dmem;
|
||||||
case RSP_MEM_REGION:
|
paddr = (paddr & 0xFFF) & ~3;
|
||||||
{
|
Util::WriteAccess<u32>(dest, paddr, val);
|
||||||
val = val << (8 * (3 - (paddr & 3)));
|
return;
|
||||||
auto &dest = paddr & 0x1000 ? mmio.rsp.imem : mmio.rsp.dmem;
|
}
|
||||||
paddr = (paddr & 0xFFF) & ~3;
|
|
||||||
Util::WriteAccess<u32>(dest, paddr, val);
|
if(Util::IsInsideRange(paddr, CART_REGION_START_2_1, CART_REGION_END_1_2)) {
|
||||||
}
|
|
||||||
break;
|
|
||||||
case REGION_CART:
|
|
||||||
trace("BusWrite<u8> @ {:08X} = {:02X}", paddr, val);
|
trace("BusWrite<u8> @ {:08X} = {:02X}", paddr, val);
|
||||||
mmio.pi.BusWrite<u8, false>(paddr, val);
|
mmio.pi.BusWrite<u8, false>(paddr, val);
|
||||||
break;
|
return;
|
||||||
case MMIO_REGION:
|
}
|
||||||
panic("MMIO Write<u8>!");
|
|
||||||
case PIF_RAM_REGION:
|
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)));
|
val = val << (8 * (3 - (paddr & 3)));
|
||||||
paddr = (paddr - PIF_RAM_REGION_START) & ~3;
|
paddr = (paddr - PIF_RAM_REGION_START) & ~3;
|
||||||
Util::WriteAccess<u32>(si.pif.ram, paddr, std::byteswap(val));
|
Util::WriteAccess<u32>(si.pif.ram, paddr, std::byteswap(val));
|
||||||
si.pif.ProcessCommands(*this);
|
si.pif.ProcessCommands(*this);
|
||||||
break;
|
return;
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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__
|
#ifndef __aarch64__
|
||||||
@@ -377,41 +347,39 @@ template <>
|
|||||||
void Mem::WriteInterpreter<u16>(Registers ®s, u32 paddr, u32 val) {
|
void Mem::WriteInterpreter<u16>(Registers ®s, u32 paddr, u32 val) {
|
||||||
SI &si = mmio.si;
|
SI &si = mmio.si;
|
||||||
|
|
||||||
switch (paddr) {
|
if(Util::IsInsideRange(paddr, RDRAM_REGION_START, RDRAM_REGION_END)) { mmio.rdp.WriteRDRAM<u16>(paddr, val); return; }
|
||||||
case RDRAM_REGION:
|
if(Util::IsInsideRange(paddr, DMEM_REGION_START, RSP_MEM_REGION_END)) {
|
||||||
mmio.rdp.WriteRDRAM<u16>(paddr, val);
|
val = val << (16 * !(paddr & 2));
|
||||||
break;
|
auto &dest = paddr & 0x1000 ? mmio.rsp.imem : mmio.rsp.dmem;
|
||||||
case RSP_MEM_REGION:
|
paddr = (paddr & 0xFFF) & ~3;
|
||||||
{
|
Util::WriteAccess<u32>(dest, paddr, val);
|
||||||
val = val << (16 * !(paddr & 2));
|
return;
|
||||||
auto &dest = paddr & 0x1000 ? mmio.rsp.imem : mmio.rsp.dmem;
|
}
|
||||||
paddr = (paddr & 0xFFF) & ~3;
|
|
||||||
Util::WriteAccess<u32>(dest, paddr, val);
|
if(Util::IsInsideRange(paddr, CART_REGION_START_2_1, CART_REGION_END_1_2)) {
|
||||||
}
|
|
||||||
break;
|
|
||||||
case REGION_CART:
|
|
||||||
trace("BusWrite<u8> @ {:08X} = {:04X}", paddr, val);
|
trace("BusWrite<u8> @ {:08X} = {:04X}", paddr, val);
|
||||||
mmio.pi.BusWrite<u16, false>(paddr, val);
|
mmio.pi.BusWrite<u16, false>(paddr, val);
|
||||||
break;
|
return;
|
||||||
case MMIO_REGION:
|
}
|
||||||
panic("MMIO Write<u16>!");
|
|
||||||
case PIF_RAM_REGION:
|
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));
|
val = val << (16 * !(paddr & 2));
|
||||||
paddr &= ~3;
|
paddr &= ~3;
|
||||||
Util::WriteAccess<u32>(si.pif.ram, paddr - PIF_RAM_REGION_START, std::byteswap(val));
|
Util::WriteAccess<u32>(si.pif.ram, paddr - PIF_RAM_REGION_START, std::byteswap(val));
|
||||||
si.pif.ProcessCommands(*this);
|
si.pif.ProcessCommands(*this);
|
||||||
break;
|
return;
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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__
|
#ifndef __aarch64__
|
||||||
@@ -432,38 +400,35 @@ template <>
|
|||||||
void Mem::WriteInterpreter<u32>(Registers ®s, const u32 paddr, const u32 val) {
|
void Mem::WriteInterpreter<u32>(Registers ®s, const u32 paddr, const u32 val) {
|
||||||
SI &si = mmio.si;
|
SI &si = mmio.si;
|
||||||
|
|
||||||
switch (paddr) {
|
if(Util::IsInsideRange(paddr, RDRAM_REGION_START, RDRAM_REGION_END)) { mmio.rdp.WriteRDRAM<u32>(paddr, val); return; }
|
||||||
case RDRAM_REGION:
|
if(Util::IsInsideRange(paddr, DMEM_REGION_START, RSP_MEM_REGION_END)) {
|
||||||
mmio.rdp.WriteRDRAM<u32>(paddr, val);
|
auto &dest = paddr & 0x1000 ? mmio.rsp.imem : mmio.rsp.dmem;
|
||||||
break;
|
Util::WriteAccess<u32>(dest, paddr & 0xfff, val);
|
||||||
case RSP_MEM_REGION:
|
return;
|
||||||
{
|
}
|
||||||
auto &dest = paddr & 0x1000 ? mmio.rsp.imem : mmio.rsp.dmem;
|
|
||||||
Util::WriteAccess<u32>(dest, paddr & 0xfff, val);
|
if(Util::IsInsideRange(paddr, CART_REGION_START_2_1, CART_REGION_END_1_2)) {
|
||||||
}
|
|
||||||
break;
|
|
||||||
case REGION_CART:
|
|
||||||
trace("BusWrite<u8> @ {:08X} = {:08X}", paddr, val);
|
trace("BusWrite<u8> @ {:08X} = {:08X}", paddr, val);
|
||||||
mmio.pi.BusWrite<u32, false>(paddr, val);
|
mmio.pi.BusWrite<u32, false>(paddr, val);
|
||||||
break;
|
return;
|
||||||
case MMIO_REGION:
|
}
|
||||||
mmio.Write(paddr, val);
|
|
||||||
break;
|
if(Util::IsInsideRange(paddr, MMIO_REGION_START_1, MMIO_REGION_END_1) ||
|
||||||
case PIF_RAM_REGION:
|
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));
|
Util::WriteAccess<u32>(si.pif.ram, paddr - PIF_RAM_REGION_START, std::byteswap(val));
|
||||||
si.pif.ProcessCommands(*this);
|
si.pif.ProcessCommands(*this);
|
||||||
break;
|
return;
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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__
|
#ifndef __aarch64__
|
||||||
@@ -493,38 +458,36 @@ void Mem::Write(const Registers ®s, const u32 paddr, const u64 val) { WriteIn
|
|||||||
void Mem::WriteInterpreter(const Registers ®s, const u32 paddr, u64 val) {
|
void Mem::WriteInterpreter(const Registers ®s, const u32 paddr, u64 val) {
|
||||||
SI &si = mmio.si;
|
SI &si = mmio.si;
|
||||||
|
|
||||||
switch (paddr) {
|
if(Util::IsInsideRange(paddr, RDRAM_REGION_START, RDRAM_REGION_END)) { mmio.rdp.WriteRDRAM<u64>(paddr, val); return; }
|
||||||
case RDRAM_REGION:
|
if(Util::IsInsideRange(paddr, DMEM_REGION_START, RSP_MEM_REGION_END)) {
|
||||||
mmio.rdp.WriteRDRAM<u64>(paddr, val);
|
auto &dest = paddr & 0x1000 ? mmio.rsp.imem : mmio.rsp.dmem;
|
||||||
break;
|
val >>= 32;
|
||||||
case RSP_MEM_REGION:
|
Util::WriteAccess<u32>(dest, paddr & 0xfff, val);
|
||||||
{
|
return;
|
||||||
auto &dest = paddr & 0x1000 ? mmio.rsp.imem : mmio.rsp.dmem;
|
}
|
||||||
val >>= 32;
|
|
||||||
Util::WriteAccess<u32>(dest, paddr & 0xfff, val);
|
if(Util::IsInsideRange(paddr, CART_REGION_START_2_1, CART_REGION_END_1_2)) {
|
||||||
}
|
trace("BusWrite<u64> @ {:08X} = {:016X}", paddr, val);
|
||||||
break;
|
|
||||||
case REGION_CART:
|
|
||||||
trace("BusWrite<u8> @ {:08X} = {:016X}", paddr, val);
|
|
||||||
mmio.pi.BusWrite<false>(paddr, val);
|
mmio.pi.BusWrite<false>(paddr, val);
|
||||||
break;
|
return;
|
||||||
case MMIO_REGION:
|
}
|
||||||
panic("MMIO Write!");
|
|
||||||
case PIF_RAM_REGION:
|
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));
|
Util::WriteAccess<u64>(si.pif.ram, paddr - PIF_RAM_REGION_START, std::byteswap(val));
|
||||||
si.pif.ProcessCommands(*this);
|
si.pif.ProcessCommands(*this);
|
||||||
break;
|
return;
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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 <>
|
template <>
|
||||||
|
|||||||
@@ -17,6 +17,12 @@ static FORCE_INLINE std::vector<u8> IntegralToBuffer(const std::integral auto &v
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static FORCE_INLINE constexpr bool IsInsideRange(const std::integral auto& addr,
|
||||||
|
const std::integral auto& start,
|
||||||
|
const std::integral auto& end) {
|
||||||
|
return addr >= start && addr <= end;
|
||||||
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
static constexpr FORCE_INLINE T ReadAccess(const u8 *data, const u32 index);
|
static constexpr FORCE_INLINE T ReadAccess(const u8 *data, const u32 index);
|
||||||
template <typename T>
|
template <typename T>
|
||||||
|
|||||||
Reference in New Issue
Block a user