Correct RDRAM masking in RSP

This commit is contained in:
SimoneN64
2024-09-05 21:15:54 +02:00
parent d1dfe16389
commit 575a6697ca
2 changed files with 69 additions and 51 deletions

View File

@@ -11,3 +11,4 @@ This file always reflects the *latest* changes up until a release. Then it gets
- Remove `nativefiledialog-extended` submodule as it is no longer needed
- Update `xbyak` subtree
- Small CMake refactoring
- Correct RDRAM masking in RSP

View File

@@ -1,12 +1,10 @@
#include <core/RSP.hpp>
#include <log.hpp>
#include <core/Mem.hpp>
#include <core/RSP.hpp>
#include <core/registers/Registers.hpp>
#include <log.hpp>
namespace n64 {
RSP::RSP(Mem& mem, Registers& regs) : mem(mem), regs(regs) {
Reset();
}
RSP::RSP(Mem &mem, Registers &regs) : mem(mem), regs(regs) { Reset(); }
void RSP::Reset() {
lastSuccessfulSPAddr.raw = 0;
@@ -69,16 +67,23 @@ FORCE_INLINE void logRSP(const RSP& rsp, const u32 instr) {
auto RSP::Read(u32 addr) -> u32 {
switch (addr) {
case 0x04040000: return lastSuccessfulSPAddr.raw & 0x1FF8;
case 0x04040004: return lastSuccessfulDRAMAddr.raw & 0xFFFFFC;
case 0x04040000:
return lastSuccessfulSPAddr.raw & 0x1FF8;
case 0x04040004:
return lastSuccessfulDRAMAddr.raw & 0xFFFFF8;
case 0x04040008:
case 0x0404000C: return spDMALen.raw;
case 0x04040010: return spStatus.raw;
case 0x04040014: return spStatus.dmaFull;
case 0x04040018: return 0;
case 0x0404000C:
return spDMALen.raw;
case 0x04040010:
return spStatus.raw;
case 0x04040014:
return spStatus.dmaFull;
case 0x04040018:
return 0;
case 0x0404001C:
return AcquireSemaphore();
case 0x04080000: return pc & 0xFFC;
case 0x04080000:
return pc & 0xFFC;
default:
Util::panic("Unimplemented SP register read {:08X}", addr);
}
@@ -94,7 +99,8 @@ void RSP::WriteStatus(u32 value) {
regs.steps = 0;
spStatus.halt = true;
}
if(write.clearBroke) spStatus.broke = false;
if (write.clearBroke)
spStatus.broke = false;
if (write.clearIntr && !write.setIntr)
mi.InterruptLower(MI::Interrupt::SP);
if (write.setIntr && !write.clearIntr)
@@ -111,7 +117,8 @@ void RSP::WriteStatus(u32 value) {
CLEAR_SET(spStatus.signal7, write.clearSignal7, write.setSignal7);
}
template <> void RSP::DMA<true>() {
template <>
void RSP::DMA<true>() {
u32 length = spDMALen.len + 1;
length = (length + 0x7) & ~0x7;
@@ -119,7 +126,7 @@ template <> void RSP::DMA<true>() {
std::array<u8, DMEM_SIZE> &src = spDMASPAddr.bank ? imem : dmem;
u32 mem_address = spDMASPAddr.address & 0xFF8;
u32 dram_address = spDMADRAMAddr.address & 0xFFFFFC;
u32 dram_address = spDMADRAMAddr.address & 0xFFFFF8;
Util::trace("SP DMA from RSP to RDRAM (size: {} B, {:08X} to {:08X})", length, mem_address, dram_address);
for (u32 i = 0; i < spDMALen.count + 1; i++) {
@@ -130,7 +137,7 @@ template <> void RSP::DMA<true>() {
int skip = i == spDMALen.count ? 0 : spDMALen.skip;
dram_address += (length + skip);
dram_address &= 0xFFFFFC;
dram_address &= 0xFFFFF8;
mem_address += length;
mem_address &= 0xFF8;
}
@@ -142,7 +149,8 @@ template <> void RSP::DMA<true>() {
spDMALen.raw = 0xFF8 | (spDMALen.skip << 20);
}
template <> void RSP::DMA<false>() {
template <>
void RSP::DMA<false>() {
u32 length = spDMALen.len + 1;
length = (length + 0x7) & ~0x7;
@@ -150,7 +158,7 @@ template <> void RSP::DMA<false>() {
std::array<u8, DMEM_SIZE> &dst = spDMASPAddr.bank ? imem : dmem;
u32 mem_address = spDMASPAddr.address & 0xFF8;
u32 dram_address = spDMADRAMAddr.address & 0xFFFFFC;
u32 dram_address = spDMADRAMAddr.address & 0xFFFFF8;
Util::trace("SP DMA from RDRAM to RSP (size: {} B, {:08X} to {:08X})", length, dram_address, mem_address);
for (u32 i = 0; i < spDMALen.count + 1; i++) {
@@ -161,7 +169,7 @@ template <> void RSP::DMA<false>() {
int skip = i == spDMALen.count ? 0 : spDMALen.skip;
dram_address += (length + skip);
dram_address &= 0xFFFFFC;
dram_address &= 0xFFFFF8;
mem_address += length;
mem_address &= 0xFF8;
}
@@ -175,8 +183,12 @@ template <> void RSP::DMA<false>() {
void RSP::Write(u32 addr, u32 val) {
switch (addr) {
case 0x04040000: spDMASPAddr.raw = val & 0x1FF8; break;
case 0x04040004: spDMADRAMAddr.raw = val & 0xFFFFFC; break;
case 0x04040000:
spDMASPAddr.raw = val & 0x1FF8;
break;
case 0x04040004:
spDMADRAMAddr.raw = val & 0xFFFFF8;
break;
case 0x04040008:
spDMALen.raw = val;
DMA<false>();
@@ -185,14 +197,19 @@ void RSP::Write(u32 addr, u32 val) {
spDMALen.raw = val;
DMA<true>();
break;
case 0x04040010: WriteStatus(val); break;
case 0x0404001C: ReleaseSemaphore(); break;
case 0x04040010:
WriteStatus(val);
break;
case 0x0404001C:
ReleaseSemaphore();
break;
case 0x04080000:
if (spStatus.halt) {
SetPC(val);
} break;
}
break;
default:
Util::panic("Unimplemented SP register write {:08X}, val: {:08X}", addr, val);
}
}
}
} // namespace n64