From e42dac2fb40e7ebd06297437d47822c7dcd0f6eb Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Mon, 18 Jan 2021 11:07:21 -0800 Subject: [PATCH] Dialog: Simulate volatile memory lock behavior. Also simply clear to zero, which isn't exactly correct but should be fairly close. See #8288 (NBA Live 08 hang.) --- Core/Dialog/PSPDialog.cpp | 57 ++++++++++++++++++++++++++++++++------- Core/Dialog/PSPDialog.h | 3 +++ Core/MemMap.h | 3 +++ 3 files changed, 54 insertions(+), 9 deletions(-) diff --git a/Core/Dialog/PSPDialog.cpp b/Core/Dialog/PSPDialog.cpp index 469d8ae7e8..32ddb45699 100644 --- a/Core/Dialog/PSPDialog.cpp +++ b/Core/Dialog/PSPDialog.cpp @@ -21,9 +21,11 @@ #include "Common/Serialize/SerializeFuncs.h" #include "Common/StringUtils.h" #include "Core/CoreTiming.h" -#include "Core/HLE/sceCtrl.h" -#include "Core/Util/PPGeDraw.h" #include "Core/Dialog/PSPDialog.h" +#include "Core/HLE/sceCtrl.h" +#include "Core/HLE/scePower.h" +#include "Core/MemMapHelpers.h" +#include "Core/Util/PPGeDraw.h" #define FADE_TIME 1.0 const float FONT_SCALE = 0.55f; @@ -34,11 +36,24 @@ PSPDialog::PSPDialog() { PSPDialog::~PSPDialog() { } -PSPDialog::DialogStatus PSPDialog::GetStatus() -{ +PSPDialog::DialogStatus PSPDialog::GetStatus() { if (pendingStatusTicks != 0 && CoreTiming::GetTicks() >= pendingStatusTicks) { - status = pendingStatus; - pendingStatusTicks = 0; + bool changeAllowed = true; + if (pendingStatus == SCE_UTILITY_STATUS_NONE && status == SCE_UTILITY_STATUS_SHUTDOWN) { + if (volatileLocked_) { + KernelVolatileMemUnlock(0); + volatileLocked_ = false; + } + } else if (pendingStatus == SCE_UTILITY_STATUS_RUNNING && status == SCE_UTILITY_STATUS_INITIALIZE) { + if (!volatileLocked_) { + volatileLocked_ = KernelVolatileMemLock(0, 0, 0) == 0; + changeAllowed = volatileLocked_; + } + } + if (changeAllowed) { + status = pendingStatus; + pendingStatusTicks = 0; + } } PSPDialog::DialogStatus retval = status; @@ -53,6 +68,17 @@ PSPDialog::DialogStatus PSPDialog::GetStatus() void PSPDialog::ChangeStatus(DialogStatus newStatus, int delayUs) { if (delayUs <= 0) { + if (newStatus == SCE_UTILITY_STATUS_NONE && status == SCE_UTILITY_STATUS_SHUTDOWN) { + if (volatileLocked_) { + KernelVolatileMemUnlock(0); + volatileLocked_ = false; + } + } else if (newStatus == SCE_UTILITY_STATUS_RUNNING && status == SCE_UTILITY_STATUS_INITIALIZE) { + if (!volatileLocked_) { + // TODO: Should probably make the status pending instead? + volatileLocked_ = KernelVolatileMemLock(0, 0, 0) == 0; + } + } status = newStatus; pendingStatusTicks = 0; } else { @@ -61,6 +87,14 @@ void PSPDialog::ChangeStatus(DialogStatus newStatus, int delayUs) { } } +void PSPDialog::FinishVolatile() { + if (KernelVolatileMemUnlock(0) == 0) { + volatileLocked_ = false; + // Simulate modifications to volatile memory. + Memory::Memset(PSP_GetVolatileMemoryStart(), 0, PSP_GetVolatileMemoryEnd() - PSP_GetVolatileMemoryStart()); + } +} + void PSPDialog::ChangeStatusInit(int delayUs) { status = SCE_UTILITY_STATUS_INITIALIZE; ChangeStatus(SCE_UTILITY_STATUS_RUNNING, delayUs); @@ -128,9 +162,8 @@ u32 PSPDialog::CalcFadedColor(u32 inColor) return (inColor & 0x00FFFFFF) | (alpha << 24); } -void PSPDialog::DoState(PointerWrap &p) -{ - auto s = p.Section("PSPDialog", 1, 2); +void PSPDialog::DoState(PointerWrap &p) { + auto s = p.Section("PSPDialog", 1, 3); if (!s) return; @@ -157,6 +190,12 @@ void PSPDialog::DoState(PointerWrap &p) } else { pendingStatusTicks = 0; } + + if (s >= 3) { + Do(p, volatileLocked_); + } else { + volatileLocked_ = false; + } } pspUtilityDialogCommon *PSPDialog::GetCommonParam() diff --git a/Core/Dialog/PSPDialog.h b/Core/Dialog/PSPDialog.h index 934b79168c..0804f36240 100644 --- a/Core/Dialog/PSPDialog.h +++ b/Core/Dialog/PSPDialog.h @@ -123,5 +123,8 @@ protected: int cancelButtonFlag; private: + void FinishVolatile(); + DialogStatus status = SCE_UTILITY_STATUS_NONE; + bool volatileLocked_ = false; }; diff --git a/Core/MemMap.h b/Core/MemMap.h index 1bd6027c22..66238f72ea 100644 --- a/Core/MemMap.h +++ b/Core/MemMap.h @@ -465,8 +465,11 @@ inline u32 PSP_GetScratchpadMemoryEnd() { return 0x00014000;} inline u32 PSP_GetKernelMemoryBase() { return 0x08000000;} inline u32 PSP_GetUserMemoryEnd() { return PSP_GetKernelMemoryBase() + Memory::g_MemorySize;} inline u32 PSP_GetKernelMemoryEnd() { return 0x08400000;} + // "Volatile" RAM is between 0x08400000 and 0x08800000, can be requested by the // game through sceKernelVolatileMemTryLock. +inline u32 PSP_GetVolatileMemoryStart() { return 0x08400000; } +inline u32 PSP_GetVolatileMemoryEnd() { return 0x08800000; } inline u32 PSP_GetUserMemoryBase() { return 0x08800000;} inline u32 PSP_GetDefaultLoadAddress() { return 0;}