mirror of
https://github.com/hrydgard/ppsspp.git
synced 2025-04-02 11:01:50 -04:00
Reschedule in sceIoLseek() etc.
Also make it so we can return u64s easily in places...
This commit is contained in:
parent
feba421566
commit
0b9c248856
5 changed files with 92 additions and 6 deletions
|
@ -65,7 +65,7 @@ void hleDelayResultFinish(u64 userdata, int cycleslate)
|
||||||
u32 error;
|
u32 error;
|
||||||
SceUID threadID = (SceUID) userdata;
|
SceUID threadID = (SceUID) userdata;
|
||||||
SceUID verify = __KernelGetWaitID(threadID, WAITTYPE_DELAY, error);
|
SceUID verify = __KernelGetWaitID(threadID, WAITTYPE_DELAY, error);
|
||||||
SceUID result = __KernelGetWaitValue(threadID, error);
|
u64 result = (userdata ^ threadID) | __KernelGetWaitValue(threadID, error);
|
||||||
|
|
||||||
if (error == 0 && verify == 1)
|
if (error == 0 && verify == 1)
|
||||||
__KernelResumeThreadFromWait(threadID, result);
|
__KernelResumeThreadFromWait(threadID, result);
|
||||||
|
@ -335,6 +335,14 @@ u32 hleDelayResult(u32 result, const char *reason, int usec)
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
u64 hleDelayResult(u64 result, const char *reason, int usec)
|
||||||
|
{
|
||||||
|
u64 param = (result & 0xFFFFFFFF00000000) | __KernelGetCurThread();
|
||||||
|
CoreTiming::ScheduleEvent(usToCycles(usec), delayedResultEvent, param);
|
||||||
|
__KernelWaitCurThread(WAITTYPE_DELAY, 1, (u32) result, 0, false, reason);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
void hleEatMicro(int usec)
|
void hleEatMicro(int usec)
|
||||||
{
|
{
|
||||||
// Maybe this should Idle, at least for larger delays? Could that cause issues?
|
// Maybe this should Idle, at least for larger delays? Could that cause issues?
|
||||||
|
|
|
@ -89,8 +89,19 @@ void hleDebugBreak();
|
||||||
|
|
||||||
// Delays the result for usec microseconds, allowing other threads to run during this time.
|
// Delays the result for usec microseconds, allowing other threads to run during this time.
|
||||||
u32 hleDelayResult(u32 result, const char *reason, int usec);
|
u32 hleDelayResult(u32 result, const char *reason, int usec);
|
||||||
|
u64 hleDelayResult(u64 result, const char *reason, int usec);
|
||||||
void hleEatMicro(int usec);
|
void hleEatMicro(int usec);
|
||||||
|
|
||||||
|
inline int hleDelayResult(int result, const char *reason, int usec)
|
||||||
|
{
|
||||||
|
return hleDelayResult((u32) result, reason, usec);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline s64 hleDelayResult(s64 result, const char *reason, int usec)
|
||||||
|
{
|
||||||
|
return hleDelayResult((u64) result, reason, usec);
|
||||||
|
}
|
||||||
|
|
||||||
void HLEInit();
|
void HLEInit();
|
||||||
void HLEDoState(PointerWrap &p);
|
void HLEDoState(PointerWrap &p);
|
||||||
void HLEShutdown();
|
void HLEShutdown();
|
||||||
|
|
|
@ -627,7 +627,8 @@ s64 sceIoLseek(int id, s64 offset, int whence) {
|
||||||
s64 result = __IoLseek(id, offset, whence);
|
s64 result = __IoLseek(id, offset, whence);
|
||||||
if (result >= 0) {
|
if (result >= 0) {
|
||||||
DEBUG_LOG(HLE, "%lli = sceIoLseek(%d, %llx, %i)", result, id, offset, whence);
|
DEBUG_LOG(HLE, "%lli = sceIoLseek(%d, %llx, %i)", result, id, offset, whence);
|
||||||
return result;
|
// Educated guess at timing.
|
||||||
|
return hleDelayResult(result, "io seek", 100);
|
||||||
} else {
|
} else {
|
||||||
ERROR_LOG(HLE, "sceIoLseek(%d, %llx, %i) - ERROR: invalid file", id, offset, whence);
|
ERROR_LOG(HLE, "sceIoLseek(%d, %llx, %i) - ERROR: invalid file", id, offset, whence);
|
||||||
return result;
|
return result;
|
||||||
|
@ -638,7 +639,8 @@ u32 sceIoLseek32(int id, int offset, int whence) {
|
||||||
s32 result = (s32) __IoLseek(id, offset, whence);
|
s32 result = (s32) __IoLseek(id, offset, whence);
|
||||||
if (result >= 0) {
|
if (result >= 0) {
|
||||||
DEBUG_LOG(HLE, "%lli = sceIoLseek(%d, %x, %i)", result, id, offset, whence);
|
DEBUG_LOG(HLE, "%lli = sceIoLseek(%d, %x, %i)", result, id, offset, whence);
|
||||||
return result;
|
// Educated guess at timing.
|
||||||
|
return hleDelayResult(result, "io seek", 100);
|
||||||
} else {
|
} else {
|
||||||
ERROR_LOG(HLE, "sceIoLseek(%d, %x, %i) - ERROR: invalid file", id, offset, whence);
|
ERROR_LOG(HLE, "sceIoLseek(%d, %x, %i) - ERROR: invalid file", id, offset, whence);
|
||||||
return result;
|
return result;
|
||||||
|
|
|
@ -372,6 +372,7 @@ public:
|
||||||
|
|
||||||
ActionAfterMipsCall *getRunningCallbackAction();
|
ActionAfterMipsCall *getRunningCallbackAction();
|
||||||
void setReturnValue(u32 retval);
|
void setReturnValue(u32 retval);
|
||||||
|
void setReturnValue(u64 retval);
|
||||||
void resumeFromWait();
|
void resumeFromWait();
|
||||||
bool isWaitingFor(WaitType type, int id);
|
bool isWaitingFor(WaitType type, int id);
|
||||||
int getWaitID(WaitType type);
|
int getWaitID(WaitType type);
|
||||||
|
@ -588,6 +589,12 @@ void MipsCall::setReturnValue(u32 value)
|
||||||
savedV0 = value;
|
savedV0 = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MipsCall::setReturnValue(u64 value)
|
||||||
|
{
|
||||||
|
savedV0 = value & 0xFFFFFFFF;
|
||||||
|
savedV1 = (value >> 32) & 0xFFFFFFFF;
|
||||||
|
}
|
||||||
|
|
||||||
// TODO: Should move to this wrapper so we can keep the current thread as a SceUID instead
|
// TODO: Should move to this wrapper so we can keep the current thread as a SceUID instead
|
||||||
// of a dangerous raw pointer.
|
// of a dangerous raw pointer.
|
||||||
Thread *__GetCurrentThread() {
|
Thread *__GetCurrentThread() {
|
||||||
|
@ -1058,7 +1065,24 @@ u32 __KernelResumeThreadFromWait(SceUID threadID)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
u32 __KernelResumeThreadFromWait(SceUID threadID, int retval)
|
u32 __KernelResumeThreadFromWait(SceUID threadID, u32 retval)
|
||||||
|
{
|
||||||
|
u32 error;
|
||||||
|
Thread *t = kernelObjects.Get<Thread>(threadID, error);
|
||||||
|
if (t)
|
||||||
|
{
|
||||||
|
t->resumeFromWait();
|
||||||
|
t->setReturnValue(retval);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ERROR_LOG(HLE, "__KernelResumeThreadFromWait(%d): bad thread: %08x", threadID, error);
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
u32 __KernelResumeThreadFromWait(SceUID threadID, u64 retval)
|
||||||
{
|
{
|
||||||
u32 error;
|
u32 error;
|
||||||
Thread *t = kernelObjects.Get<Thread>(threadID, error);
|
Thread *t = kernelObjects.Get<Thread>(threadID, error);
|
||||||
|
@ -1091,7 +1115,7 @@ bool __KernelTriggerWait(WaitType type, int id, bool useRetVal, int retVal, cons
|
||||||
// This thread was waiting for the triggered object.
|
// This thread was waiting for the triggered object.
|
||||||
t->resumeFromWait();
|
t->resumeFromWait();
|
||||||
if (useRetVal)
|
if (useRetVal)
|
||||||
t->setReturnValue(retVal);
|
t->setReturnValue((u32)retVal);
|
||||||
doneAnything = true;
|
doneAnything = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2279,6 +2303,27 @@ void Thread::setReturnValue(u32 retval)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Thread::setReturnValue(u64 retval)
|
||||||
|
{
|
||||||
|
if (this->GetUID() == currentThread) {
|
||||||
|
if (g_inCbCount) {
|
||||||
|
u32 callId = this->currentCallbackId;
|
||||||
|
MipsCall *call = mipsCalls.get(callId);
|
||||||
|
if (call) {
|
||||||
|
call->setReturnValue(retval);
|
||||||
|
} else {
|
||||||
|
ERROR_LOG(HLE, "Failed to inject return value %08llx in thread", retval);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
currentMIPS->r[2] = retval & 0xFFFFFFFF;
|
||||||
|
currentMIPS->r[3] = (retval >> 32) & 0xFFFFFFFF;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
context.r[2] = retval & 0xFFFFFFFF;
|
||||||
|
context.r[3] = (retval >> 32) & 0xFFFFFFFF;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void Thread::resumeFromWait()
|
void Thread::resumeFromWait()
|
||||||
{
|
{
|
||||||
// Do we need to "inject" it?
|
// Do we need to "inject" it?
|
||||||
|
|
|
@ -127,7 +127,18 @@ void __KernelLoadContext(ThreadContext *ctx);
|
||||||
bool __KernelTriggerWait(WaitType type, int id, const char *reason, bool dontSwitch = false);
|
bool __KernelTriggerWait(WaitType type, int id, const char *reason, bool dontSwitch = false);
|
||||||
bool __KernelTriggerWait(WaitType type, int id, int retVal, const char *reason, bool dontSwitch);
|
bool __KernelTriggerWait(WaitType type, int id, int retVal, const char *reason, bool dontSwitch);
|
||||||
u32 __KernelResumeThreadFromWait(SceUID threadID); // can return an error value
|
u32 __KernelResumeThreadFromWait(SceUID threadID); // can return an error value
|
||||||
u32 __KernelResumeThreadFromWait(SceUID threadID, int retval);
|
u32 __KernelResumeThreadFromWait(SceUID threadID, u32 retval);
|
||||||
|
u32 __KernelResumeThreadFromWait(SceUID threadID, u64 retval);
|
||||||
|
|
||||||
|
inline u32 __KernelResumeThreadFromWait(SceUID threadID, int retval)
|
||||||
|
{
|
||||||
|
return __KernelResumeThreadFromWait(threadID, (u32)retval);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline u32 __KernelResumeThreadFromWait(SceUID threadID, s64 retval)
|
||||||
|
{
|
||||||
|
return __KernelResumeThreadFromWait(threadID, (u64)retval);
|
||||||
|
}
|
||||||
|
|
||||||
u32 __KernelGetWaitValue(SceUID threadID, u32 &error);
|
u32 __KernelGetWaitValue(SceUID threadID, u32 &error);
|
||||||
u32 __KernelGetWaitTimeoutPtr(SceUID threadID, u32 &error);
|
u32 __KernelGetWaitTimeoutPtr(SceUID threadID, u32 &error);
|
||||||
|
@ -231,6 +242,15 @@ struct MipsCall {
|
||||||
|
|
||||||
void DoState(PointerWrap &p);
|
void DoState(PointerWrap &p);
|
||||||
void setReturnValue(u32 value);
|
void setReturnValue(u32 value);
|
||||||
|
void setReturnValue(u64 value);
|
||||||
|
inline void setReturnValue(int value)
|
||||||
|
{
|
||||||
|
setReturnValue((u32)value);
|
||||||
|
}
|
||||||
|
inline void setReturnValue(s64 value)
|
||||||
|
{
|
||||||
|
setReturnValue((u64)value);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
class Action
|
class Action
|
||||||
|
|
Loading…
Add table
Reference in a new issue