diff --git a/src/backend/core/RSP.cpp b/src/backend/core/RSP.cpp index 6a7c77ad..b154e8d0 100644 --- a/src/backend/core/RSP.cpp +++ b/src/backend/core/RSP.cpp @@ -111,17 +111,75 @@ void RSP::WriteStatus(u32 value) { CLEAR_SET(spStatus.signal7, write.clearSignal7, write.setSignal7); } +template <> void RSP::DMA() { + u32 length = spDMALen.len + 1; + + length = (length + 0x7) & ~0x7; + + 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++) { + mem.mmio.rdp.WriteRDRAM(BYTE_ADDRESS(dram_address + j), src[(mem_address + j) & DMEM_DSIZE]); + } + + 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); +} + +template <> void RSP::DMA() { + u32 length = spDMALen.len + 1; + + length = (length + 0x7) & ~0x7; + + 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) & DMEM_DSIZE] = mem.mmio.rdp.ReadRDRAM(BYTE_ADDRESS(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); +} + void RSP::Write(u32 addr, u32 val) { switch (addr) { case 0x04040000: spDMASPAddr.raw = val & 0x1FF8; break; case 0x04040004: spDMADRAMAddr.raw = val & 0xFFFFF8; break; case 0x04040008: { spDMALen.raw = val; - DMAtoRSP(mem.GetRDRAM()); + DMA(); } break; case 0x0404000C: { spDMALen.raw = val; - DMAtoRDRAM(mem.GetRDRAM()); + DMA(); } break; case 0x04040010: WriteStatus(val); break; case 0x0404001C: ReleaseSemaphore(); break; @@ -133,70 +191,4 @@ void RSP::Write(u32 addr, u32 val) { Util::panic("Unimplemented SP register write {:08X}, val: {:08X}", addr, val); } } - -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++) { - if((dram_address + j) < RDRAM_SIZE) { - dst[dram_address + j] = src[(mem_address + j) & DMEM_DSIZE]; - } - } - - 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++) { - if((dram_address + j) < RDRAM_SIZE) { - dst[(mem_address + j) & DMEM_DSIZE] = src[dram_address + j]; - } else { - dst[(mem_address + j) & DMEM_DSIZE] = 0; - } - } - - 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 194a0843..692d8f0f 100644 --- a/src/backend/core/RSP.hpp +++ b/src/backend/core/RSP.hpp @@ -357,8 +357,8 @@ struct RSP { void mfc2(u32 instr); void mtc2(u32 instr); - void DMAtoRDRAM(std::vector& rdram); - void DMAtoRSP(std::vector& rdram); + template + void DMA(); void WriteStatus(u32 value); private: Registers& regs; diff --git a/src/backend/core/mmio/PI.cpp b/src/backend/core/mmio/PI.cpp index 8139c7e0..37a50f6f 100644 --- a/src/backend/core/mmio/PI.cpp +++ b/src/backend/core/mmio/PI.cpp @@ -426,7 +426,7 @@ u32 PI::AccessTiming(u8 domain, u32 length) const { // rdram -> cart template <> void PI::DMA() { s32 len = rdLen + 1; - Util::always("PI DMA from RDRAM to CARTRIDGE (size: {} B, {:08X} to {:08X})", len, dramAddr, cartAddr); + Util::trace("PI DMA from RDRAM to CARTRIDGE (size: {} B, {:08X} to {:08X})", len, dramAddr, cartAddr); if(mem.saveType == SAVE_FLASH_1m && cartAddr >= SREGION_PI_SRAM && cartAddr < 0x08010000) { cartAddr = SREGION_PI_SRAM | ((cartAddr & 0xFFFFF) << 1); @@ -440,7 +440,6 @@ template <> void PI::DMA() { cartAddr += len; if(cartAddr & 1) cartAddr += 1; - Util::always("Addresses after: Cart: 0x{:08X}, Dram: 0x{:08X}", cartAddr, dramAddr); dmaBusy = true; scheduler.EnqueueRelative(AccessTiming(GetDomain(cartAddr), rdLen), PI_DMA_COMPLETE); } @@ -448,7 +447,7 @@ template <> void PI::DMA() { // cart -> rdram template <> void PI::DMA() { s32 len = wrLen + 1; - Util::always("PI DMA from CARTRIDGE to RDRAM (size: {} B, {:08X} to {:08X})", len, cartAddr, dramAddr); + Util::trace("PI DMA from CARTRIDGE to RDRAM (size: {} B, {:08X} to {:08X})", len, cartAddr, dramAddr); if(mem.saveType == SAVE_FLASH_1m && cartAddr >= SREGION_PI_SRAM && cartAddr < 0x08010000) { cartAddr = SREGION_PI_SRAM | ((cartAddr & 0xFFFFF) << 1); @@ -462,9 +461,6 @@ template <> void PI::DMA() { cartAddr += len; if(cartAddr & 1) cartAddr += 1; - mem.DumpRDRAM(); - - Util::always("Addresses after: Cart: 0x{:08X}, Dram: 0x{:08X}", cartAddr, dramAddr); dmaBusy = true; scheduler.EnqueueRelative(AccessTiming(GetDomain(cartAddr), len), PI_DMA_COMPLETE); } diff --git a/src/backend/core/rsp/instructions.cpp b/src/backend/core/rsp/instructions.cpp index 7f95fe85..f69623d7 100644 --- a/src/backend/core/rsp/instructions.cpp +++ b/src/backend/core/rsp/instructions.cpp @@ -60,11 +60,11 @@ 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(mem.GetRDRAM()); + rsp.DMA(); break; case 3: rsp.spDMALen.raw = val; - rsp.DMAtoRDRAM(mem.GetRDRAM()); + rsp.DMA(); break; case 4: rsp.WriteStatus(val); break; case 7: