From 5148a836a192265bf655f746b715e2175aa0af11 Mon Sep 17 00:00:00 2001 From: SimoneN64 Date: Mon, 13 May 2024 20:32:07 +0200 Subject: [PATCH] Refactor RSP --- src/backend/Core.cpp | 2 +- src/backend/core/MMIO.cpp | 2 +- src/backend/core/MMIO.hpp | 2 +- src/backend/core/RSP.cpp | 74 ++++++++++++++++++++++--- src/backend/core/RSP.hpp | 78 ++++----------------------- src/backend/core/rsp/decode.cpp | 4 +- src/backend/core/rsp/instructions.cpp | 8 +-- 7 files changed, 87 insertions(+), 83 deletions(-) diff --git a/src/backend/Core.cpp b/src/backend/Core.cpp index 349f73e4..9df946cc 100644 --- a/src/backend/Core.cpp +++ b/src/backend/Core.cpp @@ -85,7 +85,7 @@ void Core::Run(float volumeL, float volumeR) { while(mmio.rsp.steps > 0) { mmio.rsp.steps--; - mmio.rsp.Step(regs, mem); + mmio.rsp.Step(); } } diff --git a/src/backend/core/MMIO.cpp b/src/backend/core/MMIO.cpp index 1f0ede02..aacf8974 100644 --- a/src/backend/core/MMIO.cpp +++ b/src/backend/core/MMIO.cpp @@ -32,7 +32,7 @@ u32 MMIO::Read(u32 addr) { void MMIO::Write(Mem& mem, Registers& regs, u32 addr, u32 val) { switch (addr) { - case RSP_REGION: rsp.Write(mem, regs, addr, val); break; + case RSP_REGION: rsp.Write(addr, val); break; case RDP_REGION: rdp.Write(mi, regs, rsp, addr, val); break; case MI_REGION: mi.Write(regs, addr, val); break; case VI_REGION: vi.Write(mi, regs, addr, val); break; diff --git a/src/backend/core/MMIO.hpp b/src/backend/core/MMIO.hpp index 6b1433e9..f9ce0c94 100644 --- a/src/backend/core/MMIO.hpp +++ b/src/backend/core/MMIO.hpp @@ -13,7 +13,7 @@ struct Mem; struct Registers; struct MMIO { - MMIO(Mem& mem, Registers& regs) : mi(regs), si(mem, regs) {} + MMIO(Mem& mem, Registers& regs) : mi(regs), si(mem, regs), rsp(mem, regs) {} void Reset(); VI vi; diff --git a/src/backend/core/RSP.cpp b/src/backend/core/RSP.cpp index 9844e922..55015874 100644 --- a/src/backend/core/RSP.cpp +++ b/src/backend/core/RSP.cpp @@ -4,7 +4,7 @@ #include namespace n64 { -RSP::RSP() { +RSP::RSP(Mem& mem, Registers& regs) : mem(mem), regs(regs) { Reset(); } @@ -83,7 +83,8 @@ auto RSP::Read(u32 addr) -> u32{ } } -void RSP::WriteStatus(MI& mi, Registers& regs, u32 value) { +void RSP::WriteStatus(u32 value) { + MI& mi = mem.mmio.mi; auto write = SPStatusWrite{.raw = value}; if(write.clearHalt && !write.setHalt) { spStatus.halt = false; @@ -109,20 +110,19 @@ void RSP::WriteStatus(MI& mi, Registers& regs, u32 value) { CLEAR_SET(spStatus.signal7, write.clearSignal7, write.setSignal7); } -void RSP::Write(Mem& mem, Registers& regs, u32 addr, u32 value) { - MI& mi = mem.mmio.mi; +void RSP::Write(u32 addr, u32 value) { switch (addr) { case 0x04040000: spDMASPAddr.raw = value & 0x1FF8; break; case 0x04040004: spDMADRAMAddr.raw = value & 0xFFFFF8; break; case 0x04040008: { spDMALen.raw = value; - DMAtoRSP(spDMALen, mem.GetRDRAM(), *this, spDMASPAddr.bank); + DMAtoRSP(mem.GetRDRAM()); } break; case 0x0404000C: { spDMALen.raw = value; - DMAtoRDRAM(spDMALen, mem.GetRDRAM(), *this, spDMASPAddr.bank); + DMAtoRDRAM(mem.GetRDRAM()); } break; - case 0x04040010: WriteStatus(mi, regs, value); break; + case 0x04040010: WriteStatus(value); break; case 0x0404001C: ReleaseSemaphore(); break; case 0x04080000: if(spStatus.halt) { @@ -132,4 +132,64 @@ void RSP::Write(Mem& mem, Registers& regs, u32 addr, u32 value) { Util::panic("Unimplemented SP register write {:08X}, val: {:08X}", addr, value); } } + +void RSP::DMAtoRDRAM(std::vector& rdram) { + u32 length = spDMALen.len + 1; + + length = (length + 0x7) & ~0x7; + + std::vector& dst = rdram; + std::array& src = spDMASPAddr.bank ? imem : dmem; + + u32 mem_address = spDMASPAddr.address & 0xFF8; + u32 dram_address = spDMADRAMAddr.address & 0xFFFFF8; + + for (u32 i = 0; i < spDMALen.count + 1; i++) { + for(u32 j = 0; j < length; j++) { + dst[dram_address + j] = src[(mem_address + j) & 0xFFF]; + } + + int skip = i == spDMALen.count ? 0 : spDMALen.skip; + + dram_address += (length + skip); + dram_address &= 0xFFFFF8; + mem_address += length; + mem_address &= 0xFF8; + } + + lastSuccessfulSPAddr.address = mem_address; + lastSuccessfulSPAddr.bank = spDMASPAddr.bank; + lastSuccessfulDRAMAddr.address = dram_address; + spDMALen.raw = 0xFF8 | (spDMALen.skip << 20); +} + +void RSP::DMAtoRSP(std::vector& rdram) { + u32 length = spDMALen.len + 1; + + length = (length + 0x7) & ~0x7; + + std::vector& src = rdram; + std::array& dst = spDMASPAddr.bank ? imem : dmem; + + u32 mem_address = spDMASPAddr.address & 0xFF8; + u32 dram_address = spDMADRAMAddr.address & 0xFFFFF8; + + for (u32 i = 0; i < spDMALen.count + 1; i++) { + for(u32 j = 0; j < length; j++) { + dst[(mem_address + j) & 0xFFF] = src[dram_address + j]; + } + + int skip = i == spDMALen.count ? 0 : spDMALen.skip; + + dram_address += (length + skip); + dram_address &= 0xFFFFF8; + mem_address += length; + mem_address &= 0xFF8; + } + + lastSuccessfulSPAddr.address = mem_address; + lastSuccessfulSPAddr.bank = spDMASPAddr.bank; + lastSuccessfulDRAMAddr.address = dram_address; + spDMALen.raw = 0xFF8 | (spDMALen.skip << 20); +} } diff --git a/src/backend/core/RSP.hpp b/src/backend/core/RSP.hpp index 5ec1cb40..223737cf 100644 --- a/src/backend/core/RSP.hpp +++ b/src/backend/core/RSP.hpp @@ -113,21 +113,21 @@ struct Registers; } while(0) struct RSP { - RSP(); + RSP(Mem&, Registers&); void Reset(); - FORCE_INLINE void Step(Registers& regs, Mem& mem) { + FORCE_INLINE void Step() { gpr[0] = 0; u32 instr = Util::ReadAccess(imem, pc & IMEM_DSIZE); oldPC = pc & 0xFFC; pc = nextPC & 0xFFC; nextPC += 4; - Exec(regs, mem, instr); + Exec(instr); } auto Read(u32 addr) -> u32; - void Write(Mem& mem, Registers& regs, u32 addr, u32 value); - void Exec(Registers& regs, Mem& mem, u32 instr); + void Write(u32 addr, u32 value); + void Exec(u32 instr); SPStatus spStatus{}; u16 oldPC{}, pc{}, nextPC{}; SPDMASPAddr spDMASPAddr{}; @@ -354,72 +354,16 @@ struct RSP { void vnor(u32 instr); void vzero(u32 instr); void mfc0(RDP& rdp, u32 instr); - void mtc0(Registers& regs, Mem& mem, u32 instr); + void mtc0(u32 instr); void mfc2(u32 instr); void mtc2(u32 instr); - FORCE_INLINE void DMAtoRDRAM(SPDMALen len, std::vector& rdram, RSP& rsp, bool bank) { - u32 length = len.len + 1; - - length = (length + 0x7) & ~0x7; - - std::vector& dst = rdram; - std::array& src = bank ? rsp.imem : rsp.dmem; - - u32 mem_address = rsp.spDMASPAddr.address & 0xFF8; - u32 dram_address = rsp.spDMADRAMAddr.address & 0xFFFFF8; - - for (u32 i = 0; i < len.count + 1; i++) { - for(u32 j = 0; j < length; j++) { - dst[dram_address + j] = src[(mem_address + j) & 0xFFF]; - } - - int skip = i == len.count ? 0 : len.skip; - - dram_address += (length + skip); - dram_address &= 0xFFFFF8; - mem_address += length; - mem_address &= 0xFF8; - } - - rsp.lastSuccessfulSPAddr.address = mem_address; - rsp.lastSuccessfulSPAddr.bank = bank; - rsp.lastSuccessfulDRAMAddr.address = dram_address; - rsp.spDMALen.raw = 0xFF8 | (rsp.spDMALen.skip << 20); - } - - FORCE_INLINE void DMAtoRSP(SPDMALen len, std::vector& rdram, RSP& rsp, bool bank) { - u32 length = len.len + 1; - - length = (length + 0x7) & ~0x7; - - std::vector& src = rdram; - std::array& dst = bank ? rsp.imem : rsp.dmem; - - u32 mem_address = rsp.spDMASPAddr.address & 0xFF8; - u32 dram_address = rsp.spDMADRAMAddr.address & 0xFFFFF8; - - for (u32 i = 0; i < len.count + 1; i++) { - for(u32 j = 0; j < length; j++) { - dst[(mem_address + j) & 0xFFF] = src[dram_address + j]; - } - - int skip = i == len.count ? 0 : len.skip; - - dram_address += (length + skip); - dram_address &= 0xFFFFF8; - mem_address += length; - mem_address &= 0xFF8; - } - - rsp.lastSuccessfulSPAddr.address = mem_address; - rsp.lastSuccessfulSPAddr.bank = bank; - rsp.lastSuccessfulDRAMAddr.address = dram_address; - rsp.spDMALen.raw = 0xFF8 | (rsp.spDMALen.skip << 20); - } - - void WriteStatus(MI& mi, Registers& regs, u32 value); + void DMAtoRDRAM(std::vector& rdram); + void DMAtoRSP(std::vector& rdram); + void WriteStatus(u32 value); private: + Registers& regs; + Mem& mem; FORCE_INLINE void branch(u16 address, bool cond) { if(cond) { nextPC = address & 0xFFC; diff --git a/src/backend/core/rsp/decode.cpp b/src/backend/core/rsp/decode.cpp index 5c6a6253..224e6d17 100644 --- a/src/backend/core/rsp/decode.cpp +++ b/src/backend/core/rsp/decode.cpp @@ -177,7 +177,7 @@ FORCE_INLINE void cop0(Registers& regs, Mem& mem, u32 instr) { if((instr & 0x7FF) == 0) { switch (mask) { case 0x00: rsp.mfc0(rdp, instr); break; - case 0x04: rsp.mtc0(regs, mem, instr); break; + case 0x04: rsp.mtc0(instr); break; default: Util::panic("Unhandled RSP COP0 ({:05b})", mask); } } else { @@ -185,7 +185,7 @@ FORCE_INLINE void cop0(Registers& regs, Mem& mem, u32 instr) { } } -void RSP::Exec(Registers ®s, Mem& mem, u32 instr) { +void RSP::Exec(u32 instr) { u8 mask = (instr >> 26) & 0x3F; MMIO& mmio = mem.mmio; MI& mi = mmio.mi; diff --git a/src/backend/core/rsp/instructions.cpp b/src/backend/core/rsp/instructions.cpp index f34ae878..69a06559 100644 --- a/src/backend/core/rsp/instructions.cpp +++ b/src/backend/core/rsp/instructions.cpp @@ -60,13 +60,13 @@ FORCE_INLINE void SetCop0Reg(Registers& regs, Mem& mem, u8 index, u32 val) { case 1: rsp.spDMADRAMAddr.raw = val; break; case 2: rsp.spDMALen.raw = val; - rsp.DMAtoRSP(rsp.spDMALen, mem.GetRDRAM(), rsp, rsp.spDMASPAddr.bank); + rsp.DMAtoRSP(mem.GetRDRAM()); break; case 3: rsp.spDMALen.raw = val; - rsp.DMAtoRDRAM(rsp.spDMALen, mem.GetRDRAM(), rsp, rsp.spDMASPAddr.bank); + rsp.DMAtoRDRAM(mem.GetRDRAM()); break; - case 4: rsp.WriteStatus(mi, regs, val); break; + case 4: rsp.WriteStatus(val); break; case 7: if(val == 0) { ReleaseSemaphore(rsp); @@ -1776,7 +1776,7 @@ void RSP::mfc0(RDP& rdp, u32 instr) { gpr[RT(instr)] = GetCop0Reg(*this, rdp, RD(instr)); } -void RSP::mtc0(Registers& regs, Mem& mem, u32 instr) { +void RSP::mtc0(u32 instr) { SetCop0Reg(regs, mem, RD(instr), gpr[RT(instr)]); }