Implement RSP MEM mirroring
This commit is contained in:
@@ -223,11 +223,9 @@ void Window::Render(n64::Core& core) {
|
|||||||
if (!lockVolume) {
|
if (!lockVolume) {
|
||||||
ImGui::SliderFloat("Volume R", &volumeR, 0, 1, "%.2f", ImGuiSliderFlags_NoInput);
|
ImGui::SliderFloat("Volume R", &volumeR, 0, 1, "%.2f", ImGuiSliderFlags_NoInput);
|
||||||
} else {
|
} else {
|
||||||
ImGui::PushStyleColor(ImGuiCol_SliderGrabActive, 0x11111111);
|
|
||||||
ImGui::BeginDisabled();
|
ImGui::BeginDisabled();
|
||||||
ImGui::SliderFloat("Volume R", &volumeR, 0, 1, "%.2f", ImGuiSliderFlags_NoInput);
|
ImGui::SliderFloat("Volume R", &volumeR, 0, 1, "%.2f", ImGuiSliderFlags_NoInput);
|
||||||
ImGui::EndDisabled();
|
ImGui::EndDisabled();
|
||||||
ImGui::PopStyleColor();
|
|
||||||
volumeR = volumeL;
|
volumeR = volumeL;
|
||||||
}
|
}
|
||||||
ImGui::EndPopup();
|
ImGui::EndPopup();
|
||||||
|
|||||||
@@ -80,21 +80,15 @@ T Mem::Read(Registers& regs, u32 vaddr, s64 pc) {
|
|||||||
} else {
|
} else {
|
||||||
return util::ReadAccess<T>(mmio.rdp.dram.data(), paddr & RDRAM_DSIZE);
|
return util::ReadAccess<T>(mmio.rdp.dram.data(), paddr & RDRAM_DSIZE);
|
||||||
}
|
}
|
||||||
case 0x04000000 ... 0x04000FFF:
|
case 0x04000000 ... 0x0403FFFF:
|
||||||
if constexpr (sizeof(T) == 1) {
|
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) {
|
} 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 {
|
} else {
|
||||||
return util::ReadAccess<T>(mmio.rsp.dmem, paddr & DMEM_DSIZE);
|
return mmio.rsp.ReadDword(paddr, paddr & 0x1000);
|
||||||
}
|
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
case 0x04040000 ... 0x040FFFFF: case 0x04100000 ... 0x041FFFFF:
|
case 0x04040000 ... 0x040FFFFF: case 0x04100000 ... 0x041FFFFF:
|
||||||
case 0x04300000 ... 0x044FFFFF: case 0x04500000 ... 0x048FFFFF: return mmio.Read(paddr);
|
case 0x04300000 ... 0x044FFFFF: case 0x04500000 ... 0x048FFFFF: return mmio.Read(paddr);
|
||||||
@@ -122,8 +116,7 @@ T Mem::Read(Registers& regs, u32 vaddr, s64 pc) {
|
|||||||
} else {
|
} else {
|
||||||
return util::ReadAccess<T>(pifRam, paddr & PIF_RAM_DSIZE);
|
return util::ReadAccess<T>(pifRam, paddr & PIF_RAM_DSIZE);
|
||||||
}
|
}
|
||||||
case 0x00800000 ... 0x03FFFFFF: case 0x04002000 ... 0x0403FFFF:
|
case 0x00800000 ... 0x03FFFFFF: case 0x04200000 ... 0x042FFFFF:
|
||||||
case 0x04200000 ... 0x042FFFFF:
|
|
||||||
case 0x04900000 ... 0x07FFFFFF: case 0x08000000 ... 0x0FFFFFFF:
|
case 0x04900000 ... 0x07FFFFFF: case 0x08000000 ... 0x0FFFFFFF:
|
||||||
case 0x80000000 ... 0xFFFFFFFF: case 0x1FC00800 ... 0x7FFFFFFF: return 0;
|
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);
|
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);
|
util::WriteAccess<T>(mmio.rdp.dram.data(), paddr & RDRAM_DSIZE, val);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 0x04000000 ... 0x04000FFF:
|
case 0x04000000 ... 0x0403FFFF:
|
||||||
if constexpr (sizeof(T) == 1) {
|
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) {
|
} 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 {
|
} else {
|
||||||
util::WriteAccess<T>(mmio.rsp.dmem, paddr & DMEM_DSIZE, val);
|
mmio.rsp.WriteDword(paddr, val, paddr & 0x1000);
|
||||||
}
|
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 0x04040000 ... 0x040FFFFF: case 0x04100000 ... 0x041FFFFF:
|
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);
|
ProcessPIFCommands(pifRam, mmio.si.controller, *this);
|
||||||
break;
|
break;
|
||||||
case 0x00800000 ... 0x03FFFFFF: case 0x04002000 ... 0x0403FFFF:
|
case 0x00800000 ... 0x03FFFFFF: case 0x04200000 ... 0x042FFFFF:
|
||||||
case 0x04200000 ... 0x042FFFFF: case 0x04900000 ... 0x07FFFFFF:
|
case 0x08000000 ... 0x0FFFFFFF: case 0x04900000 ... 0x07FFFFFF:
|
||||||
case 0x08000000 ... 0x0FFFFFFF:
|
|
||||||
case 0x1FC00800 ... 0x7FFFFFFF: case 0x80000000 ... 0xFFFFFFFF: break;
|
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);
|
default: util::panic("Unimplemented {}-bit write at address {:08X} with value {:0X} (PC = {:016X})\n", sizeof(T) * 8, paddr, val, (u64)regs.pc);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,11 +3,13 @@
|
|||||||
#include <n64/core/RDP.hpp>
|
#include <n64/core/RDP.hpp>
|
||||||
#include <n64/memory_regions.hpp>
|
#include <n64/memory_regions.hpp>
|
||||||
|
|
||||||
#define RSP_BYTE(addr) (dmem[BYTE_ADDRESS(addr) & 0xFFF])
|
#define RSP_BYTE(addr, buf) (buf[BYTE_ADDRESS(addr) & 0xFFF])
|
||||||
#define GET_RSP_HALF(addr) ((RSP_BYTE(addr) << 8) | RSP_BYTE((addr) + 1))
|
#define GET_RSP_HALF(addr, buf) ((RSP_BYTE(addr, buf) << 8) | RSP_BYTE((addr) + 1, buf))
|
||||||
#define SET_RSP_HALF(addr, value) do { RSP_BYTE(addr) = ((value) >> 8) & 0xFF; RSP_BYTE((addr) + 1) = (value) & 0xFF;} while(0)
|
#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) ((GET_RSP_HALF(addr) << 16) | GET_RSP_HALF((addr) + 2))
|
#define GET_RSP_WORD(addr, buf) ((GET_RSP_HALF(addr, buf) << 16) | GET_RSP_HALF((addr) + 2, buf))
|
||||||
#define SET_RSP_WORD(addr, value) do { SET_RSP_HALF(addr, ((value) >> 16) & 0xFFFF); SET_RSP_HALF((addr) + 2, (value) & 0xFFFF);} while(0)
|
#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 {
|
namespace n64 {
|
||||||
union SPStatus {
|
union SPStatus {
|
||||||
@@ -160,28 +162,100 @@ struct RSP {
|
|||||||
return val;
|
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) {
|
inline u32 ReadWord(u32 addr) {
|
||||||
return GET_RSP_WORD(addr);
|
return GET_RSP_WORD(addr, dmem);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void WriteWord(u32 addr, u32 val) {
|
inline void WriteWord(u32 addr, u32 val) {
|
||||||
SET_RSP_WORD(addr, val);
|
SET_RSP_WORD(addr, dmem, val);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline u16 ReadHalf(u32 addr) {
|
inline u16 ReadHalf(u32 addr) {
|
||||||
return GET_RSP_HALF(addr);
|
return GET_RSP_HALF(addr, dmem);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void WriteHalf(u32 addr, u16 val) {
|
inline void WriteHalf(u32 addr, u16 val) {
|
||||||
SET_RSP_HALF(addr, val);
|
SET_RSP_HALF(addr, dmem, val);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline u8 ReadByte(u32 addr) {
|
inline u8 ReadByte(u32 addr) {
|
||||||
return RSP_BYTE(addr);
|
return RSP_BYTE(addr, dmem);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void WriteByte(u32 addr, u8 val) {
|
inline void WriteByte(u32 addr, u8 val) {
|
||||||
RSP_BYTE(addr) = val;
|
RSP_BYTE(addr, dmem) = val;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool AcquireSemaphore() {
|
inline bool AcquireSemaphore() {
|
||||||
|
|||||||
Reference in New Issue
Block a user