Implement RSP MEM mirroring

This commit is contained in:
CocoSimone
2022-09-19 20:07:28 +02:00
parent 708dde5b6c
commit f88fcf657e
3 changed files with 100 additions and 43 deletions

View File

@@ -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();

View File

@@ -80,21 +80,15 @@ T Mem::Read(Registers& regs, u32 vaddr, s64 pc) {
} else {
return util::ReadAccess<T>(mmio.rdp.dram.data(), paddr & RDRAM_DSIZE);
}
case 0x04000000 ... 0x04000FFF:
case 0x04000000 ... 0x0403FFFF:
if constexpr (sizeof(T) == 1) {
return util::ReadAccess<T>(mmio.rsp.dmem, BYTE_ADDRESS(paddr) & DMEM_DSIZE);
return mmio.rsp.ReadByte(paddr, paddr & 0x1000);
} else if constexpr (sizeof(T) == 2) {
return util::ReadAccess<T>(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<T>(mmio.rsp.dmem, paddr & DMEM_DSIZE);
}
case 0x04001000 ... 0x04001FFF:
if constexpr (sizeof(T) == 1) {
return util::ReadAccess<T>(mmio.rsp.imem, BYTE_ADDRESS(paddr) & IMEM_DSIZE);
} else if constexpr (sizeof(T) == 2) {
return util::ReadAccess<T>(mmio.rsp.imem, HALF_ADDRESS(paddr) & IMEM_DSIZE);
} else {
return util::ReadAccess<T>(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<T>(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<T>(mmio.rdp.dram.data(), paddr & RDRAM_DSIZE, val);
}
break;
case 0x04000000 ... 0x04000FFF:
case 0x04000000 ... 0x0403FFFF:
if constexpr (sizeof(T) == 1) {
util::WriteAccess<T>(mmio.rsp.dmem, BYTE_ADDRESS(paddr) & DMEM_DSIZE, val);
mmio.rsp.WriteByte(paddr, val, paddr & 0x1000);
} else if constexpr (sizeof(T) == 2) {
util::WriteAccess<T>(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<T>(mmio.rsp.dmem, paddr & DMEM_DSIZE, val);
}
break;
case 0x04001000 ... 0x04001FFF:
if constexpr (sizeof(T) == 1) {
util::WriteAccess<T>(mmio.rsp.imem, BYTE_ADDRESS(paddr) & IMEM_DSIZE, val);
} else if constexpr (sizeof(T) == 2) {
util::WriteAccess<T>(mmio.rsp.imem, HALF_ADDRESS(paddr) & IMEM_DSIZE, val);
} else {
util::WriteAccess<T>(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);
}

View File

@@ -3,11 +3,13 @@
#include <n64/core/RDP.hpp>
#include <n64/memory_regions.hpp>
#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() {