From 6c6cc910e641e861e7e90ff38bf6734d2690ffd7 Mon Sep 17 00:00:00 2001 From: Stenzek Date: Thu, 19 Jun 2025 21:14:56 +1000 Subject: [PATCH] DMA: Invalidate code pages on CD-ROM DMA write Avoids page faulting by invalidating the pages in advance. Might help with frame time spikes on super low-spec devices. --- src/core/bus.cpp | 5 ----- src/core/bus.h | 7 +++++-- src/core/dma.cpp | 10 ++++++++++ 3 files changed, 15 insertions(+), 7 deletions(-) diff --git a/src/core/bus.cpp b/src/core/bus.cpp index a5f326a61..7b38d011c 100644 --- a/src/core/bus.cpp +++ b/src/core/bus.cpp @@ -699,11 +699,6 @@ bool Bus::CanUseFastmemForAddress(VirtualMemoryAddress address) } } -bool Bus::IsRAMCodePage(u32 index) -{ - return g_ram_code_bits[index]; -} - void Bus::SetRAMCodePage(u32 index) { if (g_ram_code_bits[index]) diff --git a/src/core/bus.h b/src/core/bus.h index 0c0e613e4..917849bbc 100644 --- a/src/core/bus.h +++ b/src/core/bus.h @@ -170,7 +170,10 @@ ALWAYS_INLINE static u32 GetRAMCodePageIndex(PhysicalMemoryAddress address) } /// Returns true if the specified page contains code. -bool IsRAMCodePage(u32 index); +ALWAYS_INLINE static bool IsRAMCodePage(u32 index) +{ + return g_ram_code_bits[index]; +} /// Flags a RAM region as code, so we know when to invalidate blocks. void SetRAMCodePage(u32 index); @@ -188,7 +191,7 @@ bool IsCodePageAddress(PhysicalMemoryAddress address); bool HasCodePagesInRange(PhysicalMemoryAddress start_address, u32 size); /// Returns the number of cycles stolen by DMA RAM access. -ALWAYS_INLINE TickCount GetDMARAMTickCount(u32 word_count) +ALWAYS_INLINE static TickCount GetDMARAMTickCount(u32 word_count) { // DMA is using DRAM Hyper Page mode, allowing it to access DRAM rows at 1 clock cycle per word (effectively around // 17 clks per 16 words, due to required row address loading, probably plus some further minimal overload due to diff --git a/src/core/dma.cpp b/src/core/dma.cpp index 21e71758a..45f1d6b55 100644 --- a/src/core/dma.cpp +++ b/src/core/dma.cpp @@ -4,6 +4,7 @@ #include "dma.h" #include "bus.h" #include "cdrom.h" +#include "cpu_code_cache.h" #include "cpu_core.h" #include "gpu.h" #include "gpu_dump.h" @@ -895,6 +896,15 @@ TickCount DMA::TransferDeviceToMemory(u32 address, u32 increment, u32 word_count s_state.transfer_buffer.resize(word_count); dest_pointer = s_state.transfer_buffer.data(); } + else if constexpr (channel == Channel::CDROM) + { + const u32 end_page = (address + (increment * word_count) - 1) >> HOST_PAGE_SHIFT; + for (u32 page = address >> HOST_PAGE_SHIFT; page <= end_page; page++) + { + if (Bus::IsRAMCodePage(page)) + CPU::CodeCache::InvalidateBlocksWithPageIndex(page); + } + } // Read from device. switch (channel)