s32 sceSTimerSetHandler(s32 timerId, s32 arg1, SceSysTimerCb arg2, s32 arg3) { SceSysTimer *timer = &timers[timerId & 3]; if (timer->curTimer != timerId) return 0x80020097; s32 oldIntr = sceKernelCpuSuspendIntr(); s32 mask; if (arg1 <= 0x3FFFFF) mask = arg1; else mask = 0x3FFFFF; if (arg2 == NULL) { timer->cb = NULL; timer->unk24 = 0; timer->unk28 = 0; _sceSTimerStopCount(timer); sceKernelDisableIntr(timer->s32Num); } else { timer->cb = arg2; timer->unk28 = arg3; timer->hw->unk0 = timer->hw->unk256 & 0xFFC00000; timer->hw->unk0 |= mask; timer->hw->unk0 = timer->hw->unk256 | 0x80400000; sceKernelEnableIntr(timer->s32Num); } sceKernelCpuResumeIntr(oldIntr); return 0; }
// Read out the interrupt state and clear it static int intr_handler(void *arg) { u32 stat; stat = _lw(0xBE500040); _sw(stat, 0xBE500044); sceKernelDisableIntr(PSP_HPREMOTE_INT); sceKernelSetEventFlag(g_eventflag, EVENT_SIO); return -1; }
s32 suspendSTimer() { s32 i; for (i = 0; i < 4; i++) { timerSave[i].unk0 = timers[i].hw->unk0; timerSave[i].unk4 = timers[i].hw->unk8; timerSave[i].unk8 = timers[i].hw->unk12; sceKernelDisableIntr(timers[i].s32Num); } return 0; }
s32 sceSTimerFree(s32 timerId) { SceSysTimer *timer = &timers[timerId & 3]; if (sceKernelIsIntrContext() != 0) return 0x80020064; if (timer->curTimer != timerId) return 0x80020097; s32 oldIntr = sceKernelCpuSuspendIntr(); _sceSTimerStopCount(timer); sceKernelDisableIntr(timer->s32Num); timer->hw->unk0 = 0x80000000; timer->hw->unk8 = -1; timer->hw->unk12 = -1; timer->cb = NULL; (void)timer->hw->unk0; timer->unk28 = 0; timer->curTimer = -1; timer->unk12 = 0; timer->unk16 = 0; timer->unk24 = 0; sceKernelCpuResumeIntr(oldIntr); return 0; }