From 741b9adfbf158f341becfffddc4b23a87d4c94b0 Mon Sep 17 00:00:00 2001 From: irisz64 Date: Thu, 24 Jul 2025 15:49:13 +0200 Subject: [PATCH] [Mem] New handlers using if-range checks instead of switch --- src/backend/MemoryRegions.hpp | 19 +- src/backend/core/Mem.cpp | 395 +++++++++++++++------------------- src/utils/MemoryHelpers.hpp | 6 + 3 files changed, 202 insertions(+), 218 deletions(-) diff --git a/src/backend/MemoryRegions.hpp b/src/backend/MemoryRegions.hpp index 6ce3be62..90c43de7 100644 --- a/src/backend/MemoryRegions.hpp +++ b/src/backend/MemoryRegions.hpp @@ -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 diff --git a/src/backend/core/Mem.cpp b/src/backend/core/Mem.cpp index 2d06c1b1..7a8a8ebd 100644 --- a/src/backend/core/Mem.cpp +++ b/src/backend/core/Mem.cpp @@ -189,174 +189,144 @@ template <> u8 Mem::Read(Registers ®s, const u32 paddr) { const SI &si = mmio.si; - switch (paddr) { - case RDRAM_REGION: - return mmio.rdp.ReadRDRAM(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(paddr); - case 0x04040000 ... 0x040FFFFF: - case 0x04100000 ... 0x041FFFFF: - case 0x04600000 ... 0x048FFFFF: - case 0x04300000 ... 0x044FFFFF: - panic("MMIO Read!\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(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(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!"); + + 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 ®s, const u32 paddr) { const SI &si = mmio.si; - switch (paddr) { - case RDRAM_REGION: - return mmio.rdp.ReadRDRAM(paddr); - case RSP_MEM_REGION: - { - const auto &src = paddr & 0x1000 ? mmio.rsp.imem : mmio.rsp.dmem; - return Util::ReadAccess(src, HALF_ADDRESS(paddr & 0xfff)); - } - case MMIO_REGION: - return mmio.Read(paddr); - case REGION_CART: - return mmio.pi.BusRead(paddr); - case PIF_ROM_REGION: - return Util::ReadAccess(si.pif.bootrom, HALF_ADDRESS(paddr) - PIF_ROM_REGION_START); - case PIF_RAM_REGION: - return std::byteswap(Util::ReadAccess(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(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(src, HALF_ADDRESS(paddr & 0xfff)); } + + if(Util::IsInsideRange(paddr, CART_REGION_START_2_1, CART_REGION_END_1_2)) return mmio.pi.BusRead(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(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(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 ®s, const u32 paddr) { const SI &si = mmio.si; - switch (paddr) { - case RDRAM_REGION: - return mmio.rdp.ReadRDRAM(paddr); - case RSP_MEM_REGION: - { - const auto &src = paddr & 0x1000 ? mmio.rsp.imem : mmio.rsp.dmem; - return Util::ReadAccess(src, paddr & 0xfff); - } - case MMIO_REGION: - return mmio.Read(paddr); - case REGION_CART: - return mmio.pi.BusRead(paddr); - case PIF_ROM_REGION: - return Util::ReadAccess(si.pif.bootrom, paddr - PIF_ROM_REGION_START); - case PIF_RAM_REGION: - return std::byteswap(Util::ReadAccess(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(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(src, paddr & 0xfff); } + + if(Util::IsInsideRange(paddr, CART_REGION_START_2_1, CART_REGION_END_1_2)) return mmio.pi.BusRead(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(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(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 ®s, const u32 paddr) { const SI &si = mmio.si; - switch (paddr) { - case RDRAM_REGION: - return mmio.rdp.ReadRDRAM(paddr); - case RSP_MEM_REGION: - { - const auto &src = paddr & 0x1000 ? mmio.rsp.imem : mmio.rsp.dmem; - return Util::ReadAccess(src, paddr & 0xfff); - } - case MMIO_REGION: - return mmio.Read(paddr); - case REGION_CART: - return mmio.pi.BusRead(paddr); - case PIF_ROM_REGION: - return Util::ReadAccess(si.pif.bootrom, paddr - PIF_ROM_REGION_START); - case PIF_RAM_REGION: - return std::byteswap(Util::ReadAccess(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(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(src, paddr & 0xfff); } + + if(Util::IsInsideRange(paddr, CART_REGION_START_2_1, CART_REGION_END_1_2)) return mmio.pi.BusRead(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(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(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(Registers ®s, u32 paddr, u32 val) { SI &si = mmio.si; - switch (paddr) { - case RDRAM_REGION: - mmio.rdp.WriteRDRAM(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(dest, paddr, val); - } - break; - case REGION_CART: + if(Util::IsInsideRange(paddr, RDRAM_REGION_START, RDRAM_REGION_END)) { mmio.rdp.WriteRDRAM(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(dest, paddr, val); + return; + } + + if(Util::IsInsideRange(paddr, CART_REGION_START_2_1, CART_REGION_END_1_2)) { trace("BusWrite @ {:08X} = {:02X}", paddr, val); mmio.pi.BusWrite(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!"); + + 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(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(Registers ®s, u32 paddr, u32 val) { SI &si = mmio.si; - switch (paddr) { - case RDRAM_REGION: - mmio.rdp.WriteRDRAM(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(dest, paddr, val); - } - break; - case REGION_CART: + if(Util::IsInsideRange(paddr, RDRAM_REGION_START, RDRAM_REGION_END)) { mmio.rdp.WriteRDRAM(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(dest, paddr, val); + return; + } + + if(Util::IsInsideRange(paddr, CART_REGION_START_2_1, CART_REGION_END_1_2)) { trace("BusWrite @ {:08X} = {:04X}", paddr, val); mmio.pi.BusWrite(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!"); + + if(Util::IsInsideRange(paddr, PIF_RAM_REGION_START, PIF_RAM_REGION_END)) { val = val << (16 * !(paddr & 2)); paddr &= ~3; Util::WriteAccess(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(Registers ®s, const u32 paddr, const u32 val) { SI &si = mmio.si; - switch (paddr) { - case RDRAM_REGION: - mmio.rdp.WriteRDRAM(paddr, val); - break; - case RSP_MEM_REGION: - { - auto &dest = paddr & 0x1000 ? mmio.rsp.imem : mmio.rsp.dmem; - Util::WriteAccess(dest, paddr & 0xfff, val); - } - break; - case REGION_CART: + if(Util::IsInsideRange(paddr, RDRAM_REGION_START, RDRAM_REGION_END)) { mmio.rdp.WriteRDRAM(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(dest, paddr & 0xfff, val); + return; + } + + if(Util::IsInsideRange(paddr, CART_REGION_START_2_1, CART_REGION_END_1_2)) { trace("BusWrite @ {:08X} = {:08X}", paddr, val); mmio.pi.BusWrite(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(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 ®s, const u32 paddr, const u64 val) { WriteIn void Mem::WriteInterpreter(const Registers ®s, const u32 paddr, u64 val) { SI &si = mmio.si; - switch (paddr) { - case RDRAM_REGION: - mmio.rdp.WriteRDRAM(paddr, val); - break; - case RSP_MEM_REGION: - { - auto &dest = paddr & 0x1000 ? mmio.rsp.imem : mmio.rsp.dmem; - val >>= 32; - Util::WriteAccess(dest, paddr & 0xfff, val); - } - break; - case REGION_CART: - trace("BusWrite @ {:08X} = {:016X}", paddr, val); + if(Util::IsInsideRange(paddr, RDRAM_REGION_START, RDRAM_REGION_END)) { mmio.rdp.WriteRDRAM(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(dest, paddr & 0xfff, val); + return; + } + + if(Util::IsInsideRange(paddr, CART_REGION_START_2_1, CART_REGION_END_1_2)) { + trace("BusWrite @ {:08X} = {:016X}", paddr, val); mmio.pi.BusWrite(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!"); + + if(Util::IsInsideRange(paddr, PIF_RAM_REGION_START, PIF_RAM_REGION_END)) { Util::WriteAccess(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 <> diff --git a/src/utils/MemoryHelpers.hpp b/src/utils/MemoryHelpers.hpp index bf118367..bdb47568 100644 --- a/src/utils/MemoryHelpers.hpp +++ b/src/utils/MemoryHelpers.hpp @@ -17,6 +17,12 @@ static FORCE_INLINE std::vector IntegralToBuffer(const std::integral auto &v 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 static constexpr FORCE_INLINE T ReadAccess(const u8 *data, const u32 index); template