mirror of
https://github.com/hrydgard/ppsspp.git
synced 2025-04-02 11:01:50 -04:00
Make the UMD wait funcs actually wait.
This commit is contained in:
parent
16c29a52a8
commit
00ca9d8dc7
2 changed files with 59 additions and 12 deletions
|
@ -374,8 +374,15 @@ void __KernelWaitMutex(Mutex *mutex, u32 timeoutPtr)
|
|||
if (timeoutPtr == 0 || mutexWaitTimer == 0)
|
||||
return;
|
||||
|
||||
// This should call __KernelMutexTimeout() later, unless we cancel it.
|
||||
int micro = (int) Memory::Read_U32(timeoutPtr);
|
||||
|
||||
// This happens to be how the hardware seems to time things.
|
||||
if (micro <= 3)
|
||||
micro = 15;
|
||||
else if (micro <= 249)
|
||||
micro = 250;
|
||||
|
||||
// This should call __KernelMutexTimeout() later, unless we cancel it.
|
||||
CoreTiming::ScheduleEvent(usToCycles(micro), mutexWaitTimer, __KernelGetCurThread());
|
||||
}
|
||||
|
||||
|
@ -701,7 +708,7 @@ void __KernelWaitLwMutex(LwMutex *mutex, u32 timeoutPtr)
|
|||
else if (micro <= 249)
|
||||
micro = 250;
|
||||
|
||||
// This should call __KernelMutexTimeout() later, unless we cancel it.
|
||||
// This should call __KernelLwMutexTimeout() later, unless we cancel it.
|
||||
CoreTiming::ScheduleEvent(usToCycles(micro), lwMutexWaitTimer, __KernelGetCurThread());
|
||||
}
|
||||
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
|
||||
#include "HLE.h"
|
||||
#include "../MIPS/MIPS.h"
|
||||
#include "../../Core/CoreTiming.h"
|
||||
#include "sceUmd.h"
|
||||
#include "sceKernelThread.h"
|
||||
|
||||
|
@ -34,6 +35,7 @@ u8 umdActivated = 1;
|
|||
u32 umdStatus = 0;
|
||||
u32 umdErrorStat = 0;
|
||||
static int driveCBId= -1;
|
||||
int umdStatTimer = 0;
|
||||
|
||||
|
||||
#define PSP_UMD_TYPE_GAME 0x10
|
||||
|
@ -171,6 +173,31 @@ u32 sceUmdGetDriveStat()
|
|||
return retVal;
|
||||
}
|
||||
|
||||
void __UmdStatTimeout(u64 userdata, int cyclesLate)
|
||||
{
|
||||
SceUID threadID = (SceUID)userdata;
|
||||
|
||||
u32 error;
|
||||
SceUID waitID = __KernelGetWaitID(threadID, WAITTYPE_UMD, error);
|
||||
// Assuming it's still waiting.
|
||||
if (waitID == 1)
|
||||
__KernelResumeThreadFromWait(threadID, SCE_KERNEL_ERROR_WAIT_TIMEOUT);
|
||||
}
|
||||
|
||||
void __UmdWaitStat(u32 timeout)
|
||||
{
|
||||
if (umdStatTimer == 0)
|
||||
umdStatTimer = CoreTiming::RegisterEvent("MutexTimeout", &__UmdStatTimeout);
|
||||
|
||||
// This happens to be how the hardware seems to time things.
|
||||
if (timeout <= 4)
|
||||
timeout = 15;
|
||||
else if (timeout <= 215)
|
||||
timeout = 250;
|
||||
|
||||
CoreTiming::ScheduleEvent(usToCycles((int) timeout), umdStatTimer, __KernelGetCurThread());
|
||||
}
|
||||
|
||||
/**
|
||||
* Wait for a drive to reach a certain state
|
||||
*
|
||||
|
@ -180,40 +207,51 @@ u32 sceUmdGetDriveStat()
|
|||
*/
|
||||
void sceUmdWaitDriveStat(u32 stat)
|
||||
{
|
||||
ERROR_LOG(HLE,"HACK 0=sceUmdWaitDriveStat(stat = %08x)", stat);
|
||||
DEBUG_LOG(HLE,"0=sceUmdWaitDriveStat(stat = %08x)", stat);
|
||||
RETURN(0);
|
||||
|
||||
if ((stat & __KernelUmdGetState()) == 0)
|
||||
__KernelWaitCurThread(WAITTYPE_UMD, 0, stat, 0, 0); //__KernelWaitCurThread(WAITTYPE_UMD, 0);
|
||||
__KernelWaitCurThread(WAITTYPE_UMD, 1, stat, 0, 0);
|
||||
}
|
||||
|
||||
void sceUmdWaitDriveStatWithTimer(u32 stat, u32 timeout)
|
||||
{
|
||||
ERROR_LOG(HLE,"HACK 0=sceUmdWaitDriveStatWithTimer(stat = %08x, timeout = %08x)", stat, timeout);
|
||||
DEBUG_LOG(HLE,"0=sceUmdWaitDriveStatWithTimer(stat = %08x, timeout = %d)", stat, timeout);
|
||||
RETURN(0);
|
||||
|
||||
// TODO: timeout?
|
||||
if ((stat & __KernelUmdGetState()) == 0)
|
||||
__KernelWaitCurThread(WAITTYPE_UMD, 0, stat, 0, 0); //__KernelWaitCurThread(WAITTYPE_UMD, 0);
|
||||
{
|
||||
__UmdWaitStat(timeout);
|
||||
__KernelWaitCurThread(WAITTYPE_UMD, 1, stat, 0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void sceUmdWaitDriveStatCB(u32 stat, u32 timeout)
|
||||
{
|
||||
ERROR_LOG(HLE,"HACK 0=sceUmdWaitDriveStatCB(stat = %08x, timeout = %08x)", stat, timeout);
|
||||
RETURN(0);
|
||||
|
||||
// TODO: wait and timeout?
|
||||
|
||||
if (driveCBId != -1)
|
||||
{
|
||||
DEBUG_LOG(HLE,"0=sceUmdWaitDriveStatCB(stat = %08x, timeout = %d)", stat, timeout);
|
||||
|
||||
bool callbacksProcessed = __KernelForceCallbacks();
|
||||
if (callbacksProcessed)
|
||||
__KernelExecutePendingMipsCalls();
|
||||
}
|
||||
else
|
||||
{
|
||||
ERROR_LOG(HLE, "HACK 0=sceUmdWaitDriveStatCB(stat = %08x) attempting to call unset callback", stat);
|
||||
WARN_LOG(HLE, "0=sceUmdWaitDriveStatCB(stat = %08x, timeout = %d) without callback", stat, timeout);
|
||||
}
|
||||
|
||||
if ((stat & __KernelUmdGetState()) == 0)
|
||||
{
|
||||
if (timeout == 0)
|
||||
timeout = 8000;
|
||||
|
||||
__UmdWaitStat(timeout);
|
||||
__KernelWaitCurThread(WAITTYPE_UMD, 1, stat, 0, true);
|
||||
__KernelCheckCallbacks();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -222,7 +260,9 @@ void sceUmdCancelWaitDriveStat()
|
|||
DEBUG_LOG(HLE,"0=sceUmdCancelWaitDriveStat()");
|
||||
RETURN(0);
|
||||
|
||||
__KernelTriggerWait(WAITTYPE_UMD, 0, SCE_KERNEL_ERROR_WAIT_CANCEL, false);
|
||||
__KernelTriggerWait(WAITTYPE_UMD, 1, SCE_KERNEL_ERROR_WAIT_CANCEL, false);
|
||||
// TODO: We should call UnscheduleEvent() event here?
|
||||
// But it's not often used anyway, and worst-case it will just do nothing unless it waits again.
|
||||
}
|
||||
|
||||
u32 sceUmdGetErrorStat()
|
||||
|
|
Loading…
Add table
Reference in a new issue