From cdbb251be112fb63a502ecc8923246f4bff0d77f Mon Sep 17 00:00:00 2001 From: SimoneN64 Date: Fri, 5 Jul 2024 23:50:30 +0200 Subject: [PATCH] Better management of RDRAM accesses --- src/backend/core/Mem.cpp | 489 +++++++++++++++-------------------- src/backend/core/Mem.hpp | 1 - src/backend/core/RDP.cpp | 48 ++++ src/backend/core/RDP.hpp | 10 +- src/backend/core/mmio/AI.cpp | 2 +- src/backend/core/mmio/PI.cpp | 15 +- src/backend/core/mmio/SI.cpp | 12 +- 7 files changed, 270 insertions(+), 307 deletions(-) diff --git a/src/backend/core/Mem.cpp b/src/backend/core/Mem.cpp index dfb65dc3..41fe5ae7 100644 --- a/src/backend/core/Mem.cpp +++ b/src/backend/core/Mem.cpp @@ -9,16 +9,6 @@ namespace n64 { Mem::Mem(Registers& regs, ParallelRDP& parallel) : flash(saveData), mmio(*this, regs, parallel) { - memset(readPages, 0, PAGE_COUNT); - memset(writePages, 0, PAGE_COUNT); - - for(u64 i = 0; i < RDRAM_SIZE / PAGE_SIZE; i++) { - const auto addr = (i * PAGE_SIZE) & RDRAM_DSIZE; - const auto pointer = (uintptr_t) &mmio.rdp.rdram[addr]; - readPages[i] = pointer; - writePages[i] = pointer; - } - rom.cart.resize(CART_SIZE); std::fill(rom.cart.begin(), rom.cart.end(), 0); } @@ -33,15 +23,6 @@ void Mem::Reset() { saveData.unmap(); } mmio.Reset(); - memset(readPages, 0, PAGE_COUNT); - memset(writePages, 0, PAGE_COUNT); - - for(u64 i = 0; i < RDRAM_SIZE / PAGE_SIZE; i++) { - const auto addr = (i * PAGE_SIZE) & RDRAM_DSIZE; - const auto pointer = (uintptr_t) &mmio.rdp.rdram[addr]; - readPages[i] = pointer; - writePages[i] = pointer; - } } void Mem::LoadSRAM(SaveType save_type, fs::path path) { @@ -187,317 +168,261 @@ void Mem::LoadROM(bool isArchive, const std::string& filename) { } template<> u8 Mem::Read(n64::Registers ®s, u32 paddr) { - const auto page = paddr >> 12; - const auto offset = paddr & 0xFFF; - const auto pointer = readPages[page]; SI& si = mmio.si; - if(pointer) { - return ((u8*)pointer)[BYTE_ADDRESS(offset)]; - } else { - switch (paddr) { - case RDRAM_REGION: - return mmio.rdp.rdram[BYTE_ADDRESS(paddr)]; - case RSP_MEM_REGION: { - 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: - Util::panic("MMIO Read!\n"); - case AI_REGION: { - u32 w = mmio.ai.Read(paddr & ~3); - 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: - Util::panic("Unimplemented 8-bit read at address {:08X} (PC = {:016X})", paddr, (u64) regs.pc); + switch (paddr) { + case RDRAM_REGION: + return mmio.rdp.ReadRDRAM(paddr); + case RSP_MEM_REGION: { + 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: + Util::panic("MMIO Read!\n"); + case AI_REGION: { + u32 w = mmio.ai.Read(paddr & ~3); + 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: + Util::panic("Unimplemented 8-bit read at address {:08X} (PC = {:016X})", paddr, (u64) regs.pc); } } template<> u16 Mem::Read(n64::Registers ®s, u32 paddr) { - const auto page = paddr >> 12; - const auto offset = paddr & 0xFFF; - const auto pointer = readPages[page]; SI& si = mmio.si; - if(pointer) { - return Util::ReadAccess((u8*)pointer, HALF_ADDRESS(offset)); - } else { - switch (paddr) { - case RDRAM_REGION: - return Util::ReadAccess(mmio.rdp.rdram, HALF_ADDRESS(paddr)); - case RSP_MEM_REGION: { - 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 be16toh(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: - Util::panic("Unimplemented 16-bit read at address {:08X} (PC = {:016X})", paddr, (u64) regs.pc); + switch (paddr) { + case RDRAM_REGION: + return mmio.rdp.ReadRDRAM(paddr); + case RSP_MEM_REGION: { + 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 be16toh(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: + Util::panic("Unimplemented 16-bit read at address {:08X} (PC = {:016X})", paddr, (u64) regs.pc); } } template<> u32 Mem::Read(n64::Registers ®s, u32 paddr) { - const auto page = paddr >> 12; - const auto offset = paddr & 0xFFF; - const auto pointer = readPages[page]; SI& si = mmio.si; - if(pointer) { - return Util::ReadAccess((u8*)pointer, offset); - } else { - switch(paddr) { - case RDRAM_REGION: - return Util::ReadAccess(mmio.rdp.rdram, paddr); - case RSP_MEM_REGION: { - 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 be32toh(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: - Util::panic("Unimplemented 32-bit read at address {:08X} (PC = {:016X})", paddr, (u64) regs.pc); + switch(paddr) { + case RDRAM_REGION: + return mmio.rdp.ReadRDRAM(paddr); + case RSP_MEM_REGION: { + 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 be32toh(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: + Util::panic("Unimplemented 32-bit read at address {:08X} (PC = {:016X})", paddr, (u64) regs.pc); } } template<> u64 Mem::Read(n64::Registers ®s, u32 paddr) { - const auto page = paddr >> 12; - const auto offset = paddr & 0xFFF; - const auto pointer = readPages[page]; SI& si = mmio.si; - if(pointer) { - return Util::ReadAccess((u8*)pointer, offset); - } else { - switch (paddr) { - case RDRAM_REGION: - return Util::ReadAccess(mmio.rdp.rdram, paddr); - case RSP_MEM_REGION: { - 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 be64toh(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: - Util::panic("Unimplemented 32-bit read at address {:08X} (PC = {:016X})", paddr, (u64) regs.pc); + switch (paddr) { + case RDRAM_REGION: + return mmio.rdp.ReadRDRAM(paddr); + case RSP_MEM_REGION: { + 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 be64toh(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: + Util::panic("Unimplemented 32-bit read at address {:08X} (PC = {:016X})", paddr, (u64) regs.pc); } } template<> void Mem::Write(Registers& regs, u32 paddr, u32 val) { - const auto page = paddr >> 12; - const auto offset = paddr & 0xFFF; - const auto pointer = writePages[page]; SI& si = mmio.si; - if(pointer) { - ((u8*)pointer)[BYTE_ADDRESS(offset)] = val; - } else { - switch (paddr) { - case RDRAM_REGION: - mmio.rdp.rdram[BYTE_ADDRESS(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: - Util::trace("BusWrite @ {:08X} = {:02X}", paddr, val); - mmio.pi.BusWrite(paddr, val); - break; - case MMIO_REGION: - Util::panic("MMIO Write!"); - case PIF_RAM_REGION: - val = val << (8 * (3 - (paddr & 3))); - paddr = (paddr - PIF_RAM_REGION_START) & ~3; - Util::WriteAccess(si.pif.ram, paddr, htobe32(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: - Util::panic("Unimplemented 8-bit write at address {:08X} with value {:02X} (PC = {:016X})", paddr, val, - (u64) regs.pc); - } + 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: + Util::trace("BusWrite @ {:08X} = {:02X}", paddr, val); + mmio.pi.BusWrite(paddr, val); + break; + case MMIO_REGION: + Util::panic("MMIO Write!"); + case PIF_RAM_REGION: + val = val << (8 * (3 - (paddr & 3))); + paddr = (paddr - PIF_RAM_REGION_START) & ~3; + Util::WriteAccess(si.pif.ram, paddr, htobe32(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: + Util::panic("Unimplemented 8-bit write at address {:08X} with value {:02X} (PC = {:016X})", paddr, val, + (u64) regs.pc); } } template<> void Mem::Write(Registers& regs, u32 paddr, u32 val) { - const auto page = paddr >> 12; - const auto offset = paddr & 0xFFF; - const auto pointer = writePages[page]; SI& si = mmio.si; - if(pointer) { - Util::WriteAccess((u8*)pointer, HALF_ADDRESS(offset), val); - } else { - switch (paddr) { - case RDRAM_REGION: - Util::WriteAccess(mmio.rdp.rdram, HALF_ADDRESS(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: - Util::trace("BusWrite @ {:08X} = {:04X}", paddr, val); - mmio.pi.BusWrite(paddr, val); - break; - case MMIO_REGION: - Util::panic("MMIO Write!"); - case PIF_RAM_REGION: - val = val << (16 * !(paddr & 2)); - paddr &= ~3; - Util::WriteAccess(si.pif.ram, paddr - PIF_RAM_REGION_START, htobe32(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: - Util::panic("Unimplemented 16-bit write at address {:08X} with value {:04X} (PC = {:016X})", paddr, val, - (u64) regs.pc); - } + 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: + Util::trace("BusWrite @ {:08X} = {:04X}", paddr, val); + mmio.pi.BusWrite(paddr, val); + break; + case MMIO_REGION: + Util::panic("MMIO Write!"); + case PIF_RAM_REGION: + val = val << (16 * !(paddr & 2)); + paddr &= ~3; + Util::WriteAccess(si.pif.ram, paddr - PIF_RAM_REGION_START, htobe32(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: + Util::panic("Unimplemented 16-bit write at address {:08X} with value {:04X} (PC = {:016X})", paddr, val, + (u64) regs.pc); } } template<> void Mem::Write(Registers& regs, u32 paddr, u32 val) { - const auto page = paddr >> 12; - const auto offset = paddr & 0xFFF; - const auto pointer = writePages[page]; SI& si = mmio.si; - if(pointer) { - Util::WriteAccess((u8*)pointer, offset, val); - } else { - switch(paddr) { - case RDRAM_REGION: - Util::WriteAccess(mmio.rdp.rdram, 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: - Util::trace("BusWrite @ {:08X} = {:08X}", paddr, val); - mmio.pi.BusWrite(paddr, val); - break; - case MMIO_REGION: - mmio.Write(paddr, val); - break; - case PIF_RAM_REGION: - Util::WriteAccess(si.pif.ram, paddr - PIF_RAM_REGION_START, htobe32(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: Util::panic("Unimplemented 32-bit write at address {:08X} with value {:0X} (PC = {:016X})", paddr, val, (u64)regs.pc); - } + 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: + Util::trace("BusWrite @ {:08X} = {:08X}", paddr, val); + mmio.pi.BusWrite(paddr, val); + break; + case MMIO_REGION: + mmio.Write(paddr, val); + break; + case PIF_RAM_REGION: + Util::WriteAccess(si.pif.ram, paddr - PIF_RAM_REGION_START, htobe32(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: Util::panic("Unimplemented 32-bit write at address {:08X} with value {:0X} (PC = {:016X})", paddr, val, (u64)regs.pc); } } void Mem::Write(Registers& regs, u32 paddr, u64 val) { - const auto page = paddr >> 12; - const auto offset = paddr & 0xFFF; - const auto pointer = writePages[page]; SI& si = mmio.si; - if(pointer) { - Util::WriteAccess((u8*)pointer, offset, val); - } else { - switch (paddr) { - case RDRAM_REGION: - Util::WriteAccess(mmio.rdp.rdram, 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: - Util::trace("BusWrite @ {:08X} = {:016X}", paddr, val); - mmio.pi.BusWrite(paddr, val); - break; - case MMIO_REGION: - Util::panic("MMIO Write!"); - case PIF_RAM_REGION: - Util::WriteAccess(si.pif.ram, paddr - PIF_RAM_REGION_START, htobe64(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: - Util::panic("Unimplemented 64-bit write at address {:08X} with value {:0X} (PC = {:016X})", paddr, val, - (u64) regs.pc); - } + 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: + Util::trace("BusWrite @ {:08X} = {:016X}", paddr, val); + mmio.pi.BusWrite(paddr, val); + break; + case MMIO_REGION: + Util::panic("MMIO Write!"); + case PIF_RAM_REGION: + Util::WriteAccess(si.pif.ram, paddr - PIF_RAM_REGION_START, htobe64(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: + Util::panic("Unimplemented 64-bit write at address {:08X} with value {:0X} (PC = {:016X})", paddr, val, + (u64) regs.pc); } } diff --git a/src/backend/core/Mem.hpp b/src/backend/core/Mem.hpp index 122c50c3..6acbf691 100644 --- a/src/backend/core/Mem.hpp +++ b/src/backend/core/Mem.hpp @@ -132,7 +132,6 @@ struct Mem { Util::SwapBuffer32(temp); Util::WriteFileBinary(temp, "dmem.bin"); } - uintptr_t writePages[PAGE_COUNT]{}, readPages[PAGE_COUNT]{}; ROM rom; SaveType saveType = SAVE_NONE; Flash flash; diff --git a/src/backend/core/RDP.cpp b/src/backend/core/RDP.cpp index 3aae9573..b3c7406f 100644 --- a/src/backend/core/RDP.cpp +++ b/src/backend/core/RDP.cpp @@ -18,6 +18,54 @@ void RDP::Reset() { memset(cmd_buf, 0, 0x100000); } +template<> void RDP::WriteRDRAM(size_t idx, u8 v) { + size_t real = BYTE_ADDRESS(idx); + if(real < RDRAM_SIZE) { + rdram[real] = v; + } +} + +template<> void RDP::WriteRDRAM(size_t idx, u16 v) { + size_t real = HALF_ADDRESS(idx); + if(real < RDRAM_SIZE) { + Util::WriteAccess(rdram, real, v); + } +} + +template<> void RDP::WriteRDRAM(size_t idx, u32 v) { + if(idx < RDRAM_SIZE) { + Util::WriteAccess(rdram, idx, v); + } +} + +template<> void RDP::WriteRDRAM(size_t idx, u64 v) { + if(idx < RDRAM_SIZE) { + Util::WriteAccess(rdram, idx, v); + } +} + +template<> u8 RDP::ReadRDRAM(size_t idx) { + size_t real = BYTE_ADDRESS(idx); + if(real >= RDRAM_SIZE) return 0; + return rdram[real]; +} + +template<> u16 RDP::ReadRDRAM(size_t idx) { + size_t real = HALF_ADDRESS(idx); + if(real >= RDRAM_SIZE) return 0; + return Util::ReadAccess(rdram, real); +} + +template<> u32 RDP::ReadRDRAM(size_t idx) { + if(idx >= RDRAM_SIZE) return 0; + return Util::ReadAccess(rdram, idx); +} + +template<> u64 RDP::ReadRDRAM(size_t idx) { + if(idx >= RDRAM_SIZE) return 0; + return Util::ReadAccess(rdram, idx); +} + static const int cmd_lens[64] = { 2, 2, 2, 2, 2, 2, 2, 2, 8, 12, 24, 28, 24, 28, 40, 44, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, diff --git a/src/backend/core/RDP.hpp b/src/backend/core/RDP.hpp index 8cafac93..e3f56dd7 100644 --- a/src/backend/core/RDP.hpp +++ b/src/backend/core/RDP.hpp @@ -59,7 +59,6 @@ struct RDP { RDP(Mem&, ParallelRDP&); void Reset(); - std::vector rdram{}; [[nodiscard]] auto Read(u32 addr) const -> u32; void Write(u32 addr, u32 val); void WriteStatus(u32 val); @@ -81,7 +80,16 @@ struct RDP { } RunCommand(); } + + template + void WriteRDRAM(size_t, T); + template + T ReadRDRAM(size_t); private: + friend struct Mem; + friend struct MMIO; + std::vector rdram{}; + Mem& mem; ParallelRDP& parallel; }; diff --git a/src/backend/core/mmio/AI.cpp b/src/backend/core/mmio/AI.cpp index 50e9fbe5..dd977d3b 100644 --- a/src/backend/core/mmio/AI.cpp +++ b/src/backend/core/mmio/AI.cpp @@ -84,7 +84,7 @@ void AI::Step(u32 cpuCycles, float volumeL, float volumeR) { if(dmaLen[0] && dmaEnable) { u32 addrHi = ((dmaAddr[0] >> 13) + dmaAddrCarry) & 0x7FF; dmaAddr[0] = (addrHi << 13) | (dmaAddr[0] & 0x1FFF); - u32 data = Util::ReadAccess(mem.mmio.rdp.rdram, dmaAddr[0] & RDRAM_DSIZE); + u32 data = mem.mmio.rdp.ReadRDRAM(dmaAddr[0]); s16 l = s16(data >> 16); s16 r = s16(data); diff --git a/src/backend/core/mmio/PI.cpp b/src/backend/core/mmio/PI.cpp index a1e81c02..bf2b83a3 100644 --- a/src/backend/core/mmio/PI.cpp +++ b/src/backend/core/mmio/PI.cpp @@ -427,20 +427,14 @@ u32 PI::AccessTiming(u8 domain, u32 length) const { void PI::Write(u32 addr, u32 val) { MI& mi = mem.mmio.mi; switch(addr) { - case 0x04600000: dramAddr = val & 0x00FFFFFE; break; + case 0x04600000: dramAddr = val & 0x00FFFFFC; break; case 0x04600004: cartAddr = val & 0xFFFFFFFE; break; case 0x04600008: { rdLen = val & 0x00FFFFFF; s32 len = val + 1; for (int i = 0; i < len; i++) { - u32 address = BYTE_ADDRESS(dramAddr + i) & RDRAM_DSIZE; - if (address < RDRAM_SIZE) { - BusWrite(cartAddr + i, mem.mmio.rdp.rdram[address]); - } - else { - BusWrite(cartAddr + i, 0); - } + BusWrite(cartAddr + i, mem.mmio.rdp.ReadRDRAM(dramAddr + i)); } dramAddr += len; dramAddr = (dramAddr + 7) & ~7; @@ -460,10 +454,7 @@ void PI::Write(u32 addr, u32 val) { } for(u32 i = 0; i < len; i++) { - u32 address = BYTE_ADDRESS(dramAddr + i) & RDRAM_DSIZE; - if (address < RDRAM_SIZE) { - mem.mmio.rdp.rdram[address] = BusRead(cartAddr + i); - } + mem.mmio.rdp.WriteRDRAM(dramAddr + i, BusRead(cartAddr + i)); } dramAddr += len; dramAddr = (dramAddr + 7) & ~7; diff --git a/src/backend/core/mmio/SI.cpp b/src/backend/core/mmio/SI.cpp index 8d8866ba..6105861c 100644 --- a/src/backend/core/mmio/SI.cpp +++ b/src/backend/core/mmio/SI.cpp @@ -38,20 +38,12 @@ void SI::DMA() { if (toDram) { pif.ProcessCommands(mem); for(int i = 0; i < 64; i++) { - u32 addr = dramAddr + i; - if(addr < RDRAM_SIZE) { - mem.mmio.rdp.rdram[BYTE_ADDRESS(addr)] = pif.Read(pifAddr + i); - } + mem.mmio.rdp.WriteRDRAM(dramAddr + i, pif.Read(pifAddr + i)); } Util::trace("SI DMA from PIF RAM to RDRAM ({:08X} to {:08X})", pifAddr, dramAddr); } else { for(int i = 0; i < 64; i++) { - u32 addr = dramAddr + i; - if(addr < RDRAM_SIZE) { - pif.Write(pifAddr + i, mem.mmio.rdp.rdram[BYTE_ADDRESS(addr)]); - } else { - pif.Write(pifAddr + i, 0); - } + pif.Write(pifAddr + i, mem.mmio.rdp.ReadRDRAM(dramAddr + i)); } Util::trace("SI DMA from RDRAM to PIF RAM ({:08X} to {:08X})", dramAddr, pifAddr); pif.ProcessCommands(mem);