/** * Wait for a drive to reach a certain state * * @param stat - The drive stat to wait for. * @return < 0 on error * */ int sceUmdWaitDriveStat(u32 stat) { if (stat == 0) { DEBUG_LOG(HLE, "sceUmdWaitDriveStat(stat = %08x): bad status", stat); return SCE_KERNEL_ERROR_ERRNO_INVALID_ARGUMENT; } if (!__KernelIsDispatchEnabled()) { DEBUG_LOG(HLE, "sceUmdWaitDriveStat(stat = %08x): dispatch disabled", stat); return SCE_KERNEL_ERROR_CAN_NOT_WAIT; } if (__IsInInterrupt()) { DEBUG_LOG(HLE, "sceUmdWaitDriveStat(stat = %08x): inside interrupt", stat); return SCE_KERNEL_ERROR_ILLEGAL_CONTEXT; } if ((stat & __KernelUmdGetState()) == 0) { DEBUG_LOG(HLE, "sceUmdWaitDriveStat(stat = %08x): waiting", stat); umdWaitingThreads.push_back(UmdWaitingThread::Make(__KernelGetCurThread(), stat)); __KernelWaitCurThread(WAITTYPE_UMD, 1, stat, 0, 0, "umd stat waited"); return 0; } DEBUG_LOG(HLE, "0=sceUmdWaitDriveStat(stat = %08x)", stat); return 0; }
int sceUmdWaitDriveStatCB(u32 stat, u32 timeout) { if (stat == 0) { DEBUG_LOG(HLE, "sceUmdWaitDriveStatCB(stat = %08x, timeout = %d): bad status", stat, timeout); return SCE_KERNEL_ERROR_ERRNO_INVALID_ARGUMENT; } if (!__KernelIsDispatchEnabled()) { DEBUG_LOG(HLE, "sceUmdWaitDriveStatCB(stat = %08x, timeout = %d): dispatch disabled", stat, timeout); return SCE_KERNEL_ERROR_CAN_NOT_WAIT; } if (__IsInInterrupt()) { DEBUG_LOG(HLE, "sceUmdWaitDriveStatCB(stat = %08x, timeout = %d): inside interrupt", stat, timeout); return SCE_KERNEL_ERROR_ILLEGAL_CONTEXT; } hleCheckCurrentCallbacks(); if ((stat & __KernelUmdGetState()) == 0) { DEBUG_LOG(HLE, "0=sceUmdWaitDriveStatCB(stat = %08x, timeout = %d): waiting", stat, timeout); if (timeout == 0) { timeout = 8000; } __UmdWaitStat(timeout); umdWaitingThreads.push_back(UmdWaitingThread::Make(__KernelGetCurThread(), stat)); __KernelWaitCurThread(WAITTYPE_UMD, 1, stat, 0, true, "umd stat waited"); } else { hleReSchedule("umd stat waited"); } DEBUG_LOG(HLE, "0=sceUmdWaitDriveStatCB(stat = %08x, timeout = %d)", stat, timeout); return 0; }
void __UmdStatChange(u64 userdata, int cyclesLate) { // TODO: Why not a bool anyway? umdActivated = userdata & 0xFF; // Wake anyone waiting on this. for (size_t i = 0; i < umdWaitingThreads.size(); ++i) { SceUID threadID = umdWaitingThreads[i]; u32 error; SceUID waitID = __KernelGetWaitID(threadID, WAITTYPE_UMD, error); u32 stat = __KernelGetWaitValue(threadID, error); bool keep = false; if (waitID == 1) { if ((stat & __KernelUmdGetState()) != 0) __KernelResumeThreadFromWait(threadID, 0); // Only if they are still waiting do we keep them in the list. else keep = true; } if (!keep) umdWaitingThreads.erase(umdWaitingThreads.begin() + i--); } }
u32 sceUmdGetDriveStat() { //u32 retVal = PSP_UMD_INITED | PSP_UMD_READY | PSP_UMD_PRESENT; u32 retVal = __KernelUmdGetState(); DEBUG_LOG(HLE,"0x%02x=sceUmdGetDriveStat()", retVal); return retVal; }
int sceUmdWaitDriveStatCB(u32 stat, u32 timeout) { if (driveCBId != -1) { DEBUG_LOG(HLE,"0=sceUmdWaitDriveStatCB(stat = %08x, timeout = %d)", stat, timeout); } else { WARN_LOG(HLE, "0=sceUmdWaitDriveStatCB(stat = %08x, timeout = %d) without callback", stat, timeout); } hleCheckCurrentCallbacks(); if ((stat & __KernelUmdGetState()) == 0) { if (timeout == 0) timeout = 8000; __UmdWaitStat(timeout); __KernelWaitCurThread(WAITTYPE_UMD, 1, stat, 0, true); } else hleReSchedule("umd stat waited"); return 0; }
int sceUmdWaitDriveStatWithTimer(u32 stat, u32 timeout) { if (stat == 0) { DEBUG_LOG(SCEIO, "sceUmdWaitDriveStatWithTimer(stat = %08x, timeout = %d): bad status", stat, timeout); return SCE_KERNEL_ERROR_ERRNO_INVALID_ARGUMENT; } if (!__KernelIsDispatchEnabled()) { DEBUG_LOG(SCEIO, "sceUmdWaitDriveStatWithTimer(stat = %08x, timeout = %d): dispatch disabled", stat, timeout); return SCE_KERNEL_ERROR_CAN_NOT_WAIT; } if (__IsInInterrupt()) { DEBUG_LOG(SCEIO, "sceUmdWaitDriveStatWithTimer(stat = %08x, timeout = %d): inside interrupt", stat, timeout); return SCE_KERNEL_ERROR_ILLEGAL_CONTEXT; } if ((stat & __KernelUmdGetState()) == 0) { DEBUG_LOG(SCEIO, "sceUmdWaitDriveStatWithTimer(stat = %08x, timeout = %d): waiting", stat, timeout); __UmdWaitStat(timeout); umdWaitingThreads.push_back(__KernelGetCurThread()); __KernelWaitCurThread(WAITTYPE_UMD, 1, stat, 0, 0, "umd stat waited with timer"); return 0; } else { hleReSchedule("umd stat checked"); } DEBUG_LOG(SCEIO, "0=sceUmdWaitDriveStatWithTimer(stat = %08x, timeout = %d)", stat, timeout); return 0; }
void sceUmdWaitDriveStatCB(u32 stat, u32 timeout) { RETURN(0); if (driveCBId != -1) { DEBUG_LOG(HLE,"0=sceUmdWaitDriveStatCB(stat = %08x, timeout = %d)", stat, timeout); bool callbacksProcessed = __KernelForceCallbacks(); if (callbacksProcessed) __KernelExecutePendingMipsCalls(); } else { 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(); } }
/** * Wait for a drive to reach a certain state * * @param stat - The drive stat to wait for. * @return < 0 on error * */ void sceUmdWaitDriveStat(u32 stat) { DEBUG_LOG(HLE,"0=sceUmdWaitDriveStat(stat = %08x)", stat); RETURN(0); if ((stat & __KernelUmdGetState()) == 0) __KernelWaitCurThread(WAITTYPE_UMD, 1, stat, 0, 0); }
void sceUmdWaitDriveStatWithTimer(u32 stat, u32 timeout) { DEBUG_LOG(HLE,"0=sceUmdWaitDriveStatWithTimer(stat = %08x, timeout = %d)", stat, timeout); RETURN(0); if ((stat & __KernelUmdGetState()) == 0) { __UmdWaitStat(timeout); __KernelWaitCurThread(WAITTYPE_UMD, 1, stat, 0, 0); } }
/** * Wait for a drive to reach a certain state * * @param stat - The drive stat to wait for. * @return < 0 on error * */ int sceUmdWaitDriveStat(u32 stat) { DEBUG_LOG(HLE,"0=sceUmdWaitDriveStat(stat = %08x)", stat); if ((stat & __KernelUmdGetState()) == 0) { umdWaitingThreads.push_back(UmdWaitingThread::Make(__KernelGetCurThread(), stat)); __KernelWaitCurThread(WAITTYPE_UMD, 1, stat, 0, 0, "umd stat waited"); } return 0; }
int sceUmdWaitDriveStatWithTimer(u32 stat, u32 timeout) { DEBUG_LOG(HLE,"0=sceUmdWaitDriveStatWithTimer(stat = %08x, timeout = %d)", stat, timeout); if ((stat & __KernelUmdGetState()) == 0) { __UmdWaitStat(timeout); __KernelWaitCurThread(WAITTYPE_UMD, 1, stat, 0, 0); } else hleReSchedule("umd stat waited with timer"); return 0; }
int sceUmdWaitDriveStatCB(u32 stat, u32 timeout) { DEBUG_LOG(HLE,"0=sceUmdWaitDriveStatCB(stat = %08x, timeout = %d)", stat, timeout); hleCheckCurrentCallbacks(); if ((stat & __KernelUmdGetState()) == 0) { if (timeout == 0) timeout = 8000; __UmdWaitStat(timeout); umdWaitingThreads.push_back(UmdWaitingThread::Make(__KernelGetCurThread(), stat)); __KernelWaitCurThread(WAITTYPE_UMD, 1, stat, 0, true, "umd stat waited"); } else hleReSchedule("umd stat waited"); return 0; }
void __UmdEndCallback(SceUID threadID, SceUID prevCallbackId) { SceUID pauseKey = prevCallbackId == 0 ? threadID : prevCallbackId; u32 error; SceUID waitID = __KernelGetWaitID(threadID, WAITTYPE_UMD, error); u32 stat = __KernelGetWaitValue(threadID, error); if (umdPausedWaitTimeouts.find(pauseKey) == umdPausedWaitTimeouts.end()) { WARN_LOG_REPORT(HLE, "__UmdEndCallback(): UMD paused wait missing"); __KernelResumeThreadFromWait(threadID, 0); return; } u64 waitDeadline = umdPausedWaitTimeouts[pauseKey]; umdPausedWaitTimeouts.erase(pauseKey); // TODO: Don't wake up if __KernelCurHasReadyCallbacks()? if ((stat & __KernelUmdGetState()) != 0) { __KernelResumeThreadFromWait(threadID, 0); return; } s64 cyclesLeft = waitDeadline - CoreTiming::GetTicks(); if (cyclesLeft < 0 && waitDeadline != 0) __KernelResumeThreadFromWait(threadID, SCE_KERNEL_ERROR_WAIT_TIMEOUT); else { _dbg_assert_msg_(HLE, umdStatTimeoutEvent != -1, "Must have a umd timer"); CoreTiming::ScheduleEvent(cyclesLeft, umdStatTimeoutEvent, __KernelGetCurThread()); umdWaitingThreads.push_back(threadID); DEBUG_LOG(HLE, "sceUmdWaitDriveStatCB: Resuming lock wait for callback"); } }