diff --git a/src/backend/core/mmio/PI.cpp b/src/backend/core/mmio/PI.cpp index bf2b83a3..8139c7e0 100644 --- a/src/backend/core/mmio/PI.cpp +++ b/src/backend/core/mmio/PI.cpp @@ -9,7 +9,6 @@ PI::PI(Mem& mem, Registers& regs) : mem(mem), regs(regs) { } void PI::Reset() { - toCart = false; dmaBusy = false; ioBusy = false; latch = 0; @@ -424,6 +423,52 @@ u32 PI::AccessTiming(u8 domain, u32 length) const { return cycles * 1.5; // Converting RCP clock speed to CPU clock speed } +// 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); + + if(mem.saveType == SAVE_FLASH_1m && cartAddr >= SREGION_PI_SRAM && cartAddr < 0x08010000) { + cartAddr = SREGION_PI_SRAM | ((cartAddr & 0xFFFFF) << 1); + } + + for (int i = 0; i < len; i++) { + BusWrite(cartAddr + i, mem.mmio.rdp.ReadRDRAM(dramAddr + i)); + } + dramAddr += len; + dramAddr = (dramAddr + 7) & ~7; + 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); +} + +// 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); + + if(mem.saveType == SAVE_FLASH_1m && cartAddr >= SREGION_PI_SRAM && cartAddr < 0x08010000) { + cartAddr = SREGION_PI_SRAM | ((cartAddr & 0xFFFFF) << 1); + } + + for(u32 i = 0; i < len; i++) { + mem.mmio.rdp.WriteRDRAM(dramAddr + i, BusRead(cartAddr + i)); + } + dramAddr += len; + dramAddr = (dramAddr + 7) & ~7; + 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); +} + void PI::Write(u32 addr, u32 val) { MI& mi = mem.mmio.mi; switch(addr) { @@ -431,39 +476,11 @@ void PI::Write(u32 addr, u32 val) { case 0x04600004: cartAddr = val & 0xFFFFFFFE; break; case 0x04600008: { rdLen = val & 0x00FFFFFF; - s32 len = val + 1; - - for (int i = 0; i < len; i++) { - BusWrite(cartAddr + i, mem.mmio.rdp.ReadRDRAM(dramAddr + i)); - } - dramAddr += len; - dramAddr = (dramAddr + 7) & ~7; - cartAddr += len; - if(cartAddr & 1) cartAddr += 1; - Util::trace("PI DMA from RDRAM to CARTRIDGE (size: {} B, {:08X} to {:08X})", len, dramAddr, cartAddr); - dmaBusy = true; - toCart = true; - scheduler.EnqueueRelative(AccessTiming(GetDomain(cartAddr), len), PI_DMA_COMPLETE); + DMA(); } break; case 0x0460000C: { wrLen = val & 0x00FFFFFF; - s32 len = val + 1; - - if(mem.saveType == SAVE_FLASH_1m && cartAddr >= SREGION_PI_SRAM && cartAddr < 0x08010000) { - cartAddr = SREGION_PI_SRAM | ((cartAddr & 0xFFFFF) << 1); - } - - for(u32 i = 0; i < len; i++) { - mem.mmio.rdp.WriteRDRAM(dramAddr + i, BusRead(cartAddr + i)); - } - dramAddr += len; - dramAddr = (dramAddr + 7) & ~7; - cartAddr += len; - if(cartAddr & 1) cartAddr += 1; - dmaBusy = true; - Util::trace("PI DMA from CARTRIDGE to RDRAM (size: {} B, {:08X} to {:08X})", len, cartAddr, dramAddr); - toCart = false; - scheduler.EnqueueRelative(AccessTiming(GetDomain(cartAddr), len), PI_DMA_COMPLETE); + DMA(); } break; case 0x04600010: if(val & 2) { diff --git a/src/backend/core/mmio/PI.hpp b/src/backend/core/mmio/PI.hpp index 8e0a6e07..d39b9b2e 100644 --- a/src/backend/core/mmio/PI.hpp +++ b/src/backend/core/mmio/PI.hpp @@ -25,7 +25,7 @@ struct PI { static u8 GetDomain(u32 address); [[nodiscard]] u32 AccessTiming(u8 domain, u32 length) const; - bool dmaBusy{}, ioBusy{}, toCart{}; + bool dmaBusy{}, ioBusy{}; u32 latch{}; u32 dramAddr{}, cartAddr{}; u32 rdLen{}, wrLen{}; @@ -34,6 +34,9 @@ struct PI { u32 piBsdDom1Pgs{}, piBsdDom2Pgs{}; u32 piBsdDom1Rls{}, piBsdDom2Rls{}; private: + template + void DMA(); + Mem& mem; Registers& regs; }; diff --git a/src/backend/core/mmio/SI.cpp b/src/backend/core/mmio/SI.cpp index 6105861c..8ad33b9b 100644 --- a/src/backend/core/mmio/SI.cpp +++ b/src/backend/core/mmio/SI.cpp @@ -33,21 +33,27 @@ auto SI::Read(u32 addr) const -> u32 { } } +// pif -> rdram +template <> void SI::DMA() { + pif.ProcessCommands(mem); + for(int i = 0; i < 64; i++) { + mem.mmio.rdp.WriteRDRAM(dramAddr + i, pif.Read(pifAddr + i)); + } + Util::trace("SI DMA from PIF RAM to RDRAM ({:08X} to {:08X})", pifAddr, dramAddr); +} + +// rdram -> pif +template <> void SI::DMA() { + for(int i = 0; i < 64; i++) { + pif.Write(pifAddr + i, mem.mmio.rdp.ReadRDRAM(dramAddr + i)); + } + Util::trace("SI DMA from RDRAM to PIF RAM ({:08X} to {:08X})", dramAddr, pifAddr); +} + void SI::DMA() { status.dmaBusy = false; - if (toDram) { - pif.ProcessCommands(mem); - for(int i = 0; i < 64; i++) { - mem.mmio.rdp.WriteRDRAM(dramAddr + i, pif.Read(pifAddr + i)); - } - Util::trace("SI DMA from PIF RAM to RDRAM ({:08X} to {:08X})", pifAddr, dramAddr); - } else { - for(int i = 0; i < 64; i++) { - pif.Write(pifAddr + i, mem.mmio.rdp.ReadRDRAM(dramAddr + i)); - } - Util::trace("SI DMA from RDRAM to PIF RAM ({:08X} to {:08X})", dramAddr, pifAddr); - pif.ProcessCommands(mem); - } + if (toDram) DMA(); + else DMA(); mem.mmio.mi.InterruptRaise(MI::Interrupt::SI); } diff --git a/src/backend/core/mmio/SI.hpp b/src/backend/core/mmio/SI.hpp index f6c2acde..d0d82a23 100644 --- a/src/backend/core/mmio/SI.hpp +++ b/src/backend/core/mmio/SI.hpp @@ -29,6 +29,8 @@ struct SI { auto Read(u32) const -> u32; void Write(u32, u32); + template + void DMA(); void DMA(); PIF pif; private: