diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 593ec405..52df2ba9 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -41,8 +41,8 @@ include_directories( add_compile_definitions(SIMD_SUPPORT) add_compile_options(-mssse3 -msse4.1) if(${CMAKE_BUILD_TYPE} MATCHES Debug) - add_compile_options(-fsanitize=address -fsanitize=undefined) - add_link_options(-fsanitize=address -fsanitize=undefined) + #add_compile_options(-fsanitize=address -fsanitize=undefined) + #add_link_options(-fsanitize=address -fsanitize=undefined) endif() add_subdirectory(frontend) diff --git a/src/backend/core/Mem.hpp b/src/backend/core/Mem.hpp index 47ee3f24..c255fc4d 100644 --- a/src/backend/core/Mem.hpp +++ b/src/backend/core/Mem.hpp @@ -95,7 +95,7 @@ struct Mem { free(temp); fclose(fp); } - uintptr_t writePages[PAGE_COUNT], readPages[PAGE_COUNT]; + uintptr_t writePages[PAGE_COUNT]{}, readPages[PAGE_COUNT]{}; ROM rom; SaveType saveType; private: diff --git a/src/backend/core/mmio/PI.cpp b/src/backend/core/mmio/PI.cpp index 380342d0..e71ac64c 100644 --- a/src/backend/core/mmio/PI.cpp +++ b/src/backend/core/mmio/PI.cpp @@ -24,8 +24,8 @@ auto PI::Read(MI& mi, u32 addr) const -> u32 { case 0x0460000C: return wrLen; case 0x04600010: { u32 value = 0; - value |= (0 << 0); // Is PI DMA active? No, because it's instant - value |= (0 << 1); // Is PI IO busy? No, because it's instant + value |= (0 << dmaBusy); // Is PI DMA active? No, because it's instant + value |= (0 << ioBusy); // Is PI IO busy? No, because it's instant value |= (0 << 2); // PI IO error? value |= (mi.miIntr.pi << 3); // PI interrupt? return value; @@ -89,6 +89,23 @@ FORCE_INLINE u32 PIAccessTiming(PI& pi, u8 domain, u32 length) { return cycles * 1.5; // Converting RCP clock speed to CPU clock speed } +template +FORCE_INLINE void OnDMAComplete(Mem& mem, Registers& regs) { + PI& pi = mem.mmio.pi; + u32 len; + if constexpr (toCart) { + len = pi.rdLen; + } else { + len = pi.wrLen; + } + + pi.dramAddr = pi.dramAddrInternal + len; + pi.cartAddr = pi.cartAddrInternal + len; + pi.dmaBusy = false; + pi.ioBusy = false; + InterruptRaise(mem.mmio.mi, regs, Interrupt::PI); +} + void PI::Write(Mem& mem, Registers& regs, u32 addr, u32 val) { MI& mi = mem.mmio.mi; switch(addr) { @@ -96,37 +113,35 @@ void PI::Write(Mem& mem, Registers& regs, u32 addr, u32 val) { case 0x04600004: cartAddr = val; break; case 0x04600008: { u32 len = (val & 0x00FFFFFF) + 1; - u32 cart_addr = cartAddr & 0xFFFFFFFE; - u32 dram_addr = dramAddr & 0x007FFFFE; - if (dram_addr & 0x7) { - len -= dram_addr & 0x7; + cartAddrInternal = cartAddr & 0xFFFFFFFE; + dramAddrInternal = dramAddr & 0x007FFFFE; + if (dramAddrInternal & 0x7) { + len -= dramAddrInternal & 0x7; } rdLen = len; - for(int i = 0; i < len; i++) { - mem.rom.cart[BYTE_ADDRESS(cart_addr + i) & mem.rom.mask] = mem.mmio.rdp.rdram[BYTE_ADDRESS(dram_addr + i) & RDRAM_DSIZE]; + for (int i = 0; i < rdLen; i++) { + mem.rom.cart[BYTE_ADDRESS(cartAddrInternal + i) & mem.rom.mask] = mem.mmio.rdp.rdram[BYTE_ADDRESS(dramAddrInternal + i) & RDRAM_DSIZE]; } - - dramAddr = dram_addr + len; - cartAddr = cart_addr + len; - InterruptRaise(mi, regs, Interrupt::PI); Util::debug("PI DMA from RDRAM to CARTRIDGE (size: {} B, {:08X} to {:08X})", len, dramAddr, cartAddr); + dmaBusy = true; + ioBusy = true; + scheduler.enqueueRelative(Event{PIAccessTiming(*this, PIGetDomain(cartAddr), len), OnDMAComplete}); } break; case 0x0460000C: { u32 len = (val & 0x00FFFFFF) + 1; - u32 cart_addr = cartAddr & 0xFFFFFFFE; - u32 dram_addr = dramAddr & 0x007FFFFE; - if (dram_addr & 0x7) { - len -= (dram_addr & 0x7); + cartAddrInternal = cartAddr & 0xFFFFFFFE; + dramAddrInternal = dramAddr & 0x007FFFFE; + if (dramAddrInternal & 0x7) { + len -= (dramAddrInternal & 0x7); } wrLen = len; - for(int i = 0; i < len; i++) { - mem.mmio.rdp.rdram[BYTE_ADDRESS(dram_addr + i) & RDRAM_DSIZE] = mem.rom.cart[BYTE_ADDRESS(cart_addr + i) & mem.rom.mask]; + for(int i = 0; i < wrLen; i++) { + mem.mmio.rdp.rdram[BYTE_ADDRESS(dramAddrInternal + i) & RDRAM_DSIZE] = mem.rom.cart[BYTE_ADDRESS(cartAddrInternal + i) & mem.rom.mask]; } - - dramAddr = dram_addr + len; - cartAddr = cart_addr + len; - InterruptRaise(mi, regs, Interrupt::PI); + dmaBusy = true; + ioBusy = true; Util::debug("PI DMA from CARTRIDGE to RDRAM (size: {} B, {:08X} to {:08X})", len, cartAddr, dramAddr); + scheduler.enqueueRelative(Event{PIAccessTiming(*this, PIGetDomain(cartAddr), len), OnDMAComplete}); } break; case 0x04600010: if(val & 2) { diff --git a/src/backend/core/mmio/PI.hpp b/src/backend/core/mmio/PI.hpp index 070b81ce..69f66830 100644 --- a/src/backend/core/mmio/PI.hpp +++ b/src/backend/core/mmio/PI.hpp @@ -12,7 +12,8 @@ struct PI { void Reset(); auto Read(MI&, u32) const -> u32; void Write(Mem&, Registers&, u32, u32); - u32 dramAddr{}, cartAddr{}; + bool dmaBusy{}, ioBusy{}; + u32 dramAddr{}, cartAddr{}, dramAddrInternal{}, cartAddrInternal{}; u32 rdLen{}, wrLen{}; u32 pi_bsd_dom1_lat{}, pi_bsd_dom2_lat{}; u32 pi_bsd_dom1_pwd{}, pi_bsd_dom2_pwd{};