From 03db602a051f472d01ccea106af8b36e4a0dd38e Mon Sep 17 00:00:00 2001 From: Chris Sotraidis <56282582+chrissotraidis@users.noreply.github.com> Date: Mon, 5 Oct 2026 15:54:41 +0000 Subject: [PATCH] Bulk-copy DVD DMA into non-executable guest RAM Ported from chrissotraidis/wiicompiled (KartPad) ec14a0dddacbd1267de159215ba39d5f19633164. Co-Authored-By: Claude Opus 5.5 (1M context) Claude-Session: https://claude.ai/code/session_019rLZ24cFcqTNBmb4w2dpSq --- runtime/src/hle/storage/dvd.cpp | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/runtime/src/hle/storage/dvd.cpp b/runtime/src/hle/storage/dvd.cpp index bb63144..9c67eff 100644 --- a/runtime/src/hle/storage/dvd.cpp +++ b/runtime/src/hle/storage/dvd.cpp @@ -104,10 +104,15 @@ extern "C" void DVDInit_8015EA1C(); extern "C" uint32_t g_dvdFstReservedBase; extern "C" uint32_t g_dvdFstReservedSize; -// Byte-wise copy into guest RAM plus the DMA notification the GX caches need. +// DVD DMA normally targets ordinary RAM. Keep scalar writes for executable +// ranges so the translated-code write guard still sees every modified byte. static void CopyToGuestAsDma(uint32_t dest, const uint8_t* data, size_t size) { - for (size_t i = 0; i < size; ++i) { - Memory::Write8(dest + static_cast(i), data[i]); + if (size != 0 && !RecompMod::ExecutableWriteGuardMayHit(dest, size)) { + std::memcpy(Memory::GetPointer(dest, size), data, size); + } else { + for (size_t i = 0; i < size; ++i) { + Memory::Write8(dest + static_cast(i), data[i]); + } } GxNotifyGuestRamDmaWrite(dest, static_cast(size)); }