From f88fcf657e60f8f7f77d05bc0d9409d4ae66791c Mon Sep 17 00:00:00 2001 From: CocoSimone Date: Mon, 19 Sep 2022 20:07:28 +0200 Subject: [PATCH] Implement RSP MEM mirroring --- src/frontend/imgui/Window.cpp | 2 - src/n64/core/Mem.cpp | 45 ++++++---------- src/n64/core/RSP.hpp | 96 +++++++++++++++++++++++++++++++---- 3 files changed, 100 insertions(+), 43 deletions(-) diff --git a/src/frontend/imgui/Window.cpp b/src/frontend/imgui/Window.cpp index d2bf76e1..bd81f9dd 100644 --- a/src/frontend/imgui/Window.cpp +++ b/src/frontend/imgui/Window.cpp @@ -223,11 +223,9 @@ void Window::Render(n64::Core& core) { if (!lockVolume) { ImGui::SliderFloat("Volume R", &volumeR, 0, 1, "%.2f", ImGuiSliderFlags_NoInput); } else { - ImGui::PushStyleColor(ImGuiCol_SliderGrabActive, 0x11111111); ImGui::BeginDisabled(); ImGui::SliderFloat("Volume R", &volumeR, 0, 1, "%.2f", ImGuiSliderFlags_NoInput); ImGui::EndDisabled(); - ImGui::PopStyleColor(); volumeR = volumeL; } ImGui::EndPopup(); diff --git a/src/n64/core/Mem.cpp b/src/n64/core/Mem.cpp index 23cebb23..cc158c65 100644 --- a/src/n64/core/Mem.cpp +++ b/src/n64/core/Mem.cpp @@ -80,21 +80,15 @@ T Mem::Read(Registers& regs, u32 vaddr, s64 pc) { } else { return util::ReadAccess(mmio.rdp.dram.data(), paddr & RDRAM_DSIZE); } - case 0x04000000 ... 0x04000FFF: + case 0x04000000 ... 0x0403FFFF: if constexpr (sizeof(T) == 1) { - return util::ReadAccess(mmio.rsp.dmem, BYTE_ADDRESS(paddr) & DMEM_DSIZE); + return mmio.rsp.ReadByte(paddr, paddr & 0x1000); } else if constexpr (sizeof(T) == 2) { - return util::ReadAccess(mmio.rsp.dmem, HALF_ADDRESS(paddr) & DMEM_DSIZE); + return mmio.rsp.ReadHalf(paddr, paddr & 0x1000); + } else if constexpr (sizeof(T) == 4) { + return mmio.rsp.ReadWord(paddr, paddr & 0x1000); } else { - return util::ReadAccess(mmio.rsp.dmem, paddr & DMEM_DSIZE); - } - case 0x04001000 ... 0x04001FFF: - if constexpr (sizeof(T) == 1) { - return util::ReadAccess(mmio.rsp.imem, BYTE_ADDRESS(paddr) & IMEM_DSIZE); - } else if constexpr (sizeof(T) == 2) { - return util::ReadAccess(mmio.rsp.imem, HALF_ADDRESS(paddr) & IMEM_DSIZE); - } else { - return util::ReadAccess(mmio.rsp.imem, paddr & IMEM_DSIZE); + return mmio.rsp.ReadDword(paddr, paddr & 0x1000); } case 0x04040000 ... 0x040FFFFF: case 0x04100000 ... 0x041FFFFF: case 0x04300000 ... 0x044FFFFF: case 0x04500000 ... 0x048FFFFF: return mmio.Read(paddr); @@ -122,8 +116,7 @@ T Mem::Read(Registers& regs, u32 vaddr, s64 pc) { } else { return util::ReadAccess(pifRam, paddr & PIF_RAM_DSIZE); } - case 0x00800000 ... 0x03FFFFFF: case 0x04002000 ... 0x0403FFFF: - case 0x04200000 ... 0x042FFFFF: + case 0x00800000 ... 0x03FFFFFF: case 0x04200000 ... 0x042FFFFF: case 0x04900000 ... 0x07FFFFFF: case 0x08000000 ... 0x0FFFFFFF: case 0x80000000 ... 0xFFFFFFFF: case 0x1FC00800 ... 0x7FFFFFFF: return 0; default: util::panic("Unimplemented {}-bit read at address {:08X} (PC = {:016X})\n", sizeof(T) * 8, paddr, (u64)regs.pc); @@ -166,22 +159,15 @@ void Mem::Write(Registers& regs, u32 vaddr, T val, s64 pc) { util::WriteAccess(mmio.rdp.dram.data(), paddr & RDRAM_DSIZE, val); } break; - case 0x04000000 ... 0x04000FFF: + case 0x04000000 ... 0x0403FFFF: if constexpr (sizeof(T) == 1) { - util::WriteAccess(mmio.rsp.dmem, BYTE_ADDRESS(paddr) & DMEM_DSIZE, val); + mmio.rsp.WriteByte(paddr, val, paddr & 0x1000); } else if constexpr (sizeof(T) == 2) { - util::WriteAccess(mmio.rsp.dmem, HALF_ADDRESS(paddr) & DMEM_DSIZE, val); + mmio.rsp.WriteHalf(paddr, val, paddr & 0x1000); + } else if constexpr (sizeof(T) == 4) { + mmio.rsp.WriteWord(paddr, val, paddr & 0x1000); } else { - util::WriteAccess(mmio.rsp.dmem, paddr & DMEM_DSIZE, val); - } - break; - case 0x04001000 ... 0x04001FFF: - if constexpr (sizeof(T) == 1) { - util::WriteAccess(mmio.rsp.imem, BYTE_ADDRESS(paddr) & IMEM_DSIZE, val); - } else if constexpr (sizeof(T) == 2) { - util::WriteAccess(mmio.rsp.imem, HALF_ADDRESS(paddr) & IMEM_DSIZE, val); - } else { - util::WriteAccess(mmio.rsp.imem, paddr & IMEM_DSIZE, val); + mmio.rsp.WriteDword(paddr, val, paddr & 0x1000); } break; case 0x04040000 ... 0x040FFFFF: case 0x04100000 ... 0x041FFFFF: @@ -208,9 +194,8 @@ void Mem::Write(Registers& regs, u32 vaddr, T val, s64 pc) { } ProcessPIFCommands(pifRam, mmio.si.controller, *this); break; - case 0x00800000 ... 0x03FFFFFF: case 0x04002000 ... 0x0403FFFF: - case 0x04200000 ... 0x042FFFFF: case 0x04900000 ... 0x07FFFFFF: - case 0x08000000 ... 0x0FFFFFFF: + case 0x00800000 ... 0x03FFFFFF: case 0x04200000 ... 0x042FFFFF: + case 0x08000000 ... 0x0FFFFFFF: case 0x04900000 ... 0x07FFFFFF: case 0x1FC00800 ... 0x7FFFFFFF: case 0x80000000 ... 0xFFFFFFFF: break; default: util::panic("Unimplemented {}-bit write at address {:08X} with value {:0X} (PC = {:016X})\n", sizeof(T) * 8, paddr, val, (u64)regs.pc); } diff --git a/src/n64/core/RSP.hpp b/src/n64/core/RSP.hpp index 48dfff99..19873c67 100644 --- a/src/n64/core/RSP.hpp +++ b/src/n64/core/RSP.hpp @@ -3,11 +3,13 @@ #include #include -#define RSP_BYTE(addr) (dmem[BYTE_ADDRESS(addr) & 0xFFF]) -#define GET_RSP_HALF(addr) ((RSP_BYTE(addr) << 8) | RSP_BYTE((addr) + 1)) -#define SET_RSP_HALF(addr, value) do { RSP_BYTE(addr) = ((value) >> 8) & 0xFF; RSP_BYTE((addr) + 1) = (value) & 0xFF;} while(0) -#define GET_RSP_WORD(addr) ((GET_RSP_HALF(addr) << 16) | GET_RSP_HALF((addr) + 2)) -#define SET_RSP_WORD(addr, value) do { SET_RSP_HALF(addr, ((value) >> 16) & 0xFFFF); SET_RSP_HALF((addr) + 2, (value) & 0xFFFF);} while(0) +#define RSP_BYTE(addr, buf) (buf[BYTE_ADDRESS(addr) & 0xFFF]) +#define GET_RSP_HALF(addr, buf) ((RSP_BYTE(addr, buf) << 8) | RSP_BYTE((addr) + 1, buf)) +#define SET_RSP_HALF(addr, buf, value) do { RSP_BYTE(addr, buf) = ((value) >> 8) & 0xFF; RSP_BYTE((addr) + 1, buf) = (value) & 0xFF;} while(0) +#define GET_RSP_WORD(addr, buf) ((GET_RSP_HALF(addr, buf) << 16) | GET_RSP_HALF((addr) + 2, buf)) +#define SET_RSP_WORD(addr, buf, value) do { SET_RSP_HALF(addr, buf, ((value) >> 16) & 0xFFFF); SET_RSP_HALF((addr) + 2, buf, (value) & 0xFFFF);} while(0) +#define GET_RSP_DWORD(addr, buf) (((u64)GET_RSP_WORD(addr, buf) << 32) | (u64)GET_RSP_WORD((addr) + 4, buf)) +#define SET_RSP_DWORD(addr, buf, value) do { SET_RSP_WORD(addr, buf, ((value) >> 32) & 0xFFFFFFFF); SET_RSP_WORD((addr) + 4, buf, (value) & 0xFFFFFFFF);} while(0) namespace n64 { union SPStatus { @@ -160,28 +162,100 @@ struct RSP { return val; } + inline u64 ReadDword(u32 addr, bool i) { + if (i) { + return GET_RSP_DWORD(addr, imem); + } else { + return GET_RSP_DWORD(addr, dmem); + } + } + + inline void WriteDword(u32 addr, u64 val, bool i) { + if (i) { + SET_RSP_DWORD(addr, imem, val); + } else { + SET_RSP_DWORD(addr, dmem, val); + } + } + + inline u32 ReadWord(u32 addr, bool i) { + if (i) { + return GET_RSP_WORD(addr, imem); + } else { + return GET_RSP_WORD(addr, dmem); + } + } + + inline void WriteWord(u32 addr, u32 val, bool i) { + if (i) { + SET_RSP_WORD(addr, imem, val); + } else { + SET_RSP_WORD(addr, dmem, val); + } + } + + inline u16 ReadHalf(u32 addr, bool i) { + if (i) { + return GET_RSP_HALF(addr, imem); + } else { + return GET_RSP_HALF(addr, dmem); + } + } + + inline void WriteHalf(u32 addr, u16 val, bool i) { + if (i) { + SET_RSP_HALF(addr, imem, val); + } else { + SET_RSP_HALF(addr, dmem, val); + } + } + + inline u8 ReadByte(u32 addr, bool i) { + if (i) { + return RSP_BYTE(addr, imem); + } else { + return RSP_BYTE(addr, dmem); + } + } + + inline void WriteByte(u32 addr, u8 val, bool i) { + if (i) { + RSP_BYTE(addr, imem) = val; + } else { + RSP_BYTE(addr, dmem) = val; + } + } + + inline u64 ReadDword(u32 addr) { + return GET_RSP_DWORD(addr, dmem); + } + + inline void WriteDword(u32 addr, u64 val) { + SET_RSP_DWORD(addr, dmem, val); + } + inline u32 ReadWord(u32 addr) { - return GET_RSP_WORD(addr); + return GET_RSP_WORD(addr, dmem); } inline void WriteWord(u32 addr, u32 val) { - SET_RSP_WORD(addr, val); + SET_RSP_WORD(addr, dmem, val); } inline u16 ReadHalf(u32 addr) { - return GET_RSP_HALF(addr); + return GET_RSP_HALF(addr, dmem); } inline void WriteHalf(u32 addr, u16 val) { - SET_RSP_HALF(addr, val); + SET_RSP_HALF(addr, dmem, val); } inline u8 ReadByte(u32 addr) { - return RSP_BYTE(addr); + return RSP_BYTE(addr, dmem); } inline void WriteByte(u32 addr, u8 val) { - RSP_BYTE(addr) = val; + RSP_BYTE(addr, dmem) = val; } inline bool AcquireSemaphore() {