From 80cc9d8c0ee20a5c98ae59b0be4c62cf97ad45ef Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Tue, 6 May 2014 00:41:49 -0700 Subject: [PATCH] Mirror memory for VRAM mirrors. For a long time we've done this with GetPointer() only, but it's better if it's the same for all methods of memory access. Technically, we should do the swizzling (and also swizzle the depth data in softgpu), but there's no indication games depend on this, and GetPointer would need changes anyway. --- Core/MemMap.cpp | 29 ++++++++++++------- Core/MemMap.h | 14 ++------- Core/MemMapFunctions.cpp | 61 +++++++++++++++++++--------------------- 3 files changed, 51 insertions(+), 53 deletions(-) diff --git a/Core/MemMap.cpp b/Core/MemMap.cpp index cced19089d..e88e775fb3 100644 --- a/Core/MemMap.cpp +++ b/Core/MemMap.cpp @@ -65,14 +65,21 @@ u8 *m_pPhysicalRAM3; u8 *m_pUncachedRAM3; u8 *m_pKernelRAM3; -u8 *m_pPhysicalVRAM; -u8 *m_pUncachedVRAM; +// VRAM is mirrored 4 times. The second and fourth mirrors are swizzled. +// In practice, a game accessing the mirrors most likely is deswizzling the depth buffer. +u8 *m_pPhysicalVRAM1; +u8 *m_pPhysicalVRAM2; +u8 *m_pPhysicalVRAM3; +u8 *m_pPhysicalVRAM4; +u8 *m_pUncachedVRAM1; +u8 *m_pUncachedVRAM2; +u8 *m_pUncachedVRAM3; +u8 *m_pUncachedVRAM4; // Holds the ending address of the PSP's user space. // Required for HD Remasters to work properly. -// These replace RAM_NORMAL_SIZE and RAM_NORMAL_MASK, respectively. +// This replaces RAM_NORMAL_SIZE at runtime. u32 g_MemorySize; -u32 g_MemoryMask; // Used to store the PSP model on game startup. u32 g_PSPModel; @@ -81,8 +88,14 @@ static MemoryView views[] = { {&m_pScratchPad, &m_pPhysicalScratchPad, 0x00010000, SCRATCHPAD_SIZE, 0}, {NULL, &m_pUncachedScratchPad, 0x40010000, SCRATCHPAD_SIZE, MV_MIRROR_PREVIOUS}, - {&m_pVRAM, &m_pPhysicalVRAM, 0x04000000, 0x00800000, 0}, - {NULL, &m_pUncachedVRAM, 0x44000000, 0x00800000, MV_MIRROR_PREVIOUS}, + {&m_pVRAM, &m_pPhysicalVRAM1, 0x04000000, 0x00200000, 0}, + {NULL, &m_pPhysicalVRAM2, 0x04200000, 0x00200000, MV_MIRROR_PREVIOUS}, + {NULL, &m_pPhysicalVRAM3, 0x04400000, 0x00200000, MV_MIRROR_PREVIOUS}, + {NULL, &m_pPhysicalVRAM4, 0x04600000, 0x00200000, MV_MIRROR_PREVIOUS}, + {NULL, &m_pUncachedVRAM1, 0x44000000, 0x00200000, MV_MIRROR_PREVIOUS}, + {NULL, &m_pUncachedVRAM2, 0x44200000, 0x00200000, MV_MIRROR_PREVIOUS}, + {NULL, &m_pUncachedVRAM3, 0x44400000, 0x00200000, MV_MIRROR_PREVIOUS}, + {NULL, &m_pUncachedVRAM4, 0x44600000, 0x00200000, MV_MIRROR_PREVIOUS}, {&m_pRAM, &m_pPhysicalRAM, 0x08000000, g_MemorySize, MV_IS_PRIMARY_RAM}, // only from 0x08800000 is it usable (last 24 megs) {NULL, &m_pUncachedRAM, 0x48000000, g_MemorySize, MV_MIRROR_PREVIOUS | MV_IS_PRIMARY_RAM}, {NULL, &m_pKernelRAM, 0x88000000, g_MemorySize, MV_MIRROR_PREVIOUS | MV_IS_PRIMARY_RAM}, @@ -104,10 +117,6 @@ static const int num_views = sizeof(views) / sizeof(MemoryView); void Init() { int flags = 0; - // This mask is used ONLY after validating the address is in the correct range. - // So let's just use a fixed mask to remove the uncached/user memory bits. - // Using (Memory::g_MemorySize - 1) won't work for e.g. 0x04C00000. - Memory::g_MemoryMask = 0x07FFFFFF; // On some 32 bit platforms, you can only map < 32 megs at a time. const static int MAX_MMAP_SIZE = 31 * 1024 * 1024; diff --git a/Core/MemMap.h b/Core/MemMap.h index ee10a545f0..e632aa6182 100644 --- a/Core/MemMap.h +++ b/Core/MemMap.h @@ -72,28 +72,20 @@ extern u8 *m_pVRAM; extern u8 *m_pPhysicalRAM; extern u8 *m_pUncachedRAM; -extern u8 *m_pPhysicalVRAM; -extern u8 *m_pUncachedVRAM; - -// These replace RAM_NORMAL_SIZE and RAM_NORMAL_MASK, respectively. +// This replaces RAM_NORMAL_SIZE at runtime. extern u32 g_MemorySize; -extern u32 g_MemoryMask; extern u32 g_PSPModel; enum { // This may be adjusted by remaster games. RAM_NORMAL_SIZE = 0x02000000, - RAM_NORMAL_MASK = RAM_NORMAL_SIZE - 1, - // Used if the PSP model is PSP-2000 (Slim). RAM_DOUBLE_SIZE = RAM_NORMAL_SIZE * 2, - VRAM_SIZE = 0x200000, - VRAM_MASK = VRAM_SIZE - 1, + VRAM_SIZE = 0x00200000, - SCRATCHPAD_SIZE = 0x4000, - SCRATCHPAD_MASK = SCRATCHPAD_SIZE - 1, + SCRATCHPAD_SIZE = 0x00004000, #if defined(_M_IX86) || defined(_M_ARM32) || defined(_XBOX) // This wraparound should work for PSP too. diff --git a/Core/MemMapFunctions.cpp b/Core/MemMapFunctions.cpp index 172d761b1e..285ae2a5df 100644 --- a/Core/MemMapFunctions.cpp +++ b/Core/MemMapFunctions.cpp @@ -41,18 +41,18 @@ namespace Memory u8 *GetPointer(const u32 address) { if ((address & 0x3E000000) == 0x08000000) { + // RAM return GetPointerUnchecked(address); - } - else if ((address & 0x3F800000) == 0x04000000) { - return m_pVRAM + (address & VRAM_MASK); - } - else if ((address & 0xBFFF0000) == 0x00010000) { - return m_pScratchPad + (address & SCRATCHPAD_MASK); - } - else if ((address & 0x3F000000) >= 0x08000000 && (address & 0x3F000000) < 0x08000000 + g_MemorySize) { + } else if ((address & 0x3F800000) == 0x04000000) { + // VRAM return GetPointerUnchecked(address); - } - else { + } else if ((address & 0xBFFF0000) == 0x00010000) { + // Scratchpad + return GetPointerUnchecked(address); + } else if ((address & 0x3F000000) >= 0x08000000 && (address & 0x3F000000) < 0x08000000 + g_MemorySize) { + // More RAM (remasters, etc.) + return GetPointerUnchecked(address); + } else { ERROR_LOG(MEMMAP, "Unknown GetPointer %08x PC %08x LR %08x", address, currentMIPS->pc, currentMIPS->r[MIPS_REG_RA]); static bool reported = false; if (!reported) { @@ -76,20 +76,18 @@ inline void ReadFromHardware(T &var, const u32 address) // Could just do a base-relative read, too.... TODO if ((address & 0x3E000000) == 0x08000000) { + // RAM var = *((const T*)GetPointerUnchecked(address)); - } - else if ((address & 0x3F800000) == 0x04000000) { - var = *((const T*)&m_pVRAM[address & VRAM_MASK]); - } - else if ((address & 0xBFFF0000) == 0x00010000) { + } else if ((address & 0x3F800000) == 0x04000000) { + // VRAM + var = *((const T*)GetPointerUnchecked(address)); + } else if ((address & 0xBFFF0000) == 0x00010000) { // Scratchpad - var = *((const T*)&m_pScratchPad[address & SCRATCHPAD_MASK]); - } - else if ((address & 0x3F000000) >= 0x08000000 && (address & 0x3F000000) < 0x08000000 + g_MemorySize) { var = *((const T*)GetPointerUnchecked(address)); - } - else - { + } else if ((address & 0x3F000000) >= 0x08000000 && (address & 0x3F000000) < 0x08000000 + g_MemorySize) { + // More RAM (remasters, etc.) + var = *((const T*)GetPointerUnchecked(address)); + } else { if (g_Config.bJit) { WARN_LOG(MEMMAP, "ReadFromHardware: Invalid address %08x", address); } else { @@ -114,19 +112,18 @@ inline void WriteToHardware(u32 address, const T data) // Could just do a base-relative write, too.... TODO if ((address & 0x3E000000) == 0x08000000) { + // RAM *(T*)GetPointerUnchecked(address) = data; - } - else if ((address & 0x3F800000) == 0x04000000) { - *(T*)&m_pVRAM[address & VRAM_MASK] = data; - } - else if ((address & 0xBFFF0000) == 0x00010000) { - *(T*)&m_pScratchPad[address & SCRATCHPAD_MASK] = data; - } - else if ((address & 0x3F000000) >= 0x08000000 && (address & 0x3F000000) < 0x08000000 + g_MemorySize) { + } else if ((address & 0x3F800000) == 0x04000000) { + // VRAM *(T*)GetPointerUnchecked(address) = data; - } - else - { + } else if ((address & 0xBFFF0000) == 0x00010000) { + // Scratchpad + *(T*)GetPointerUnchecked(address) = data; + } else if ((address & 0x3F000000) >= 0x08000000 && (address & 0x3F000000) < 0x08000000 + g_MemorySize) { + // More RAM (remasters, etc.) + *(T*)GetPointerUnchecked(address) = data; + } else { if (g_Config.bJit) { WARN_LOG(MEMMAP, "WriteToHardware: Invalid address %08x", address); } else {