int stackCheckFunc(SceSize argc, void *argv) { if ((int)argv & 0xf) { schedf(" %s: ERROR: arg pointer not aligned.\n", stackCheckName); } u32 *stack = (u32 *) stackCheckInfo.stack; u32 *stackEnd = stack + stackCheckInfo.stackSize / 4; if (stack[0] != sceKernelGetThreadId()) { schedf(" %s: ERROR: stack should start with thread ID.\n", stackCheckName); } if (stackEnd[-1] != 0xFFFFFFFF || stackEnd[-2] != 0xFFFFFFFF) { schedf(" %s: WARNING: k0 laid out differently?\n", stackCheckName); } if (stackEnd[-14] != (u32)stack) { schedf(" %s: WARNING: stack pointer not correct in k0.\n", stackCheckName); } if (stackEnd[-16] != sceKernelGetThreadId()) { schedf(" %s: WARNING: thread id not correct in k0.\n", stackCheckName); } SceUID uid = sceKernelAllocPartitionMemory(2, "TEST", PSP_SMEM_Low, 0x100, NULL); if (stack < (u32 *)sceKernelGetBlockHeadAddr(uid)) { schedf(" %s: WARNING: stack allocated low.\n", stackCheckName); } sceKernelFreePartitionMemory(uid); if (stack[1] != 0xFFFFFFFF) { schedf(" %s: WARNING: stack not set to FF, instead: %08x.\n", stackCheckName, stack[1]); } return 0; }
int nkThreadResume(SceUID thId){ int i, j; SceUID myThread, *Thread_Now; if(bufNow.pThread == 0) return 1; Thread_Now = (SceUID*)sceKernelGetBlockHeadAddr(bufNow.pThread); myThread = sceKernelGetThreadId(); for(i = 0; i < bufNow.count; i++){ unsigned char match = 0; SceUID tmp_thid = Thread_Now[i]; for(j = 0; j < count_Start; j++){ if((tmp_thid == Thread_Start[j]) || (tmp_thid == thId) || (tmp_thid == myThread)){ match = 1; j = count_Start; } } if(match == 0){ sceKernelResumeThread(tmp_thid); } } sceKernelFreePartitionMemory(bufNow.pThread); bufNow.count = 0; bufNow.pThread = 0; return 0; }
int hook_sceKernelExitDeleteThread(int res) { SceKernelSemaInfo info; globals_t *globals; SceUID uid; int i; globals = getGlobals(); uid = sceKernelGetThreadId(); DEBUG_PRINTF("Exiting thread 0x%08X (res: 0x%08X)", uid, res); sceKernelLockMutex(globals->threadmgrMutex, 1, NULL); info.size = sizeof(info); i = sceKernelGetSemaInfo(globals->threadmgrSema, &info); if (i == 0) { for (i = info.currentCount; i < info.maxCount; i++) { if (globals->threadmgrTable[info.currentCount].uid == uid) { if (i != info.currentCount) memcpy(globals->threadmgrTable + i, globals->threadmgrTable + info.currentCount, sizeof(thInfo_t)); sceKernelSignalSema(globals->threadmgrSema, 1); break; } } } sceKernelUnlockMutex(globals->threadmgrMutex, 1); sceKernelDelayThread(16384); return sceKernelExitDeleteThread(res); }
int nkThreadSuspend(SceUID thId){ int i, j; SceUID myThread, *Thread_Now; if(bufNow.pThread != 0) return 1; bufNow.pThread = sceKernelAllocPartitionMemory(1, "th", 0, MAX_THREAD*sizeof(SceUID), NULL); if(bufNow.pThread < 0){ bufNow.count = 0; bufNow.pThread = 0; return 1; } Thread_Now = (SceUID*)sceKernelGetBlockHeadAddr(bufNow.pThread); sceKernelGetThreadmanIdList(SCE_KERNEL_TMID_Thread, Thread_Now, MAX_THREAD, &(bufNow.count)); myThread = sceKernelGetThreadId(); for(i = 0; i < bufNow.count; i++){ unsigned char match = 0; SceUID tmp_thid = Thread_Now[i]; for(j = 0; j < count_Start; j++){ if((tmp_thid == Thread_Start[j]) || (tmp_thid == thId) || (tmp_thid == myThread)){ match = 1; j = count_Start; } } if(match == 0){ sceKernelSuspendThread(tmp_thid); } } return 0; }
void psp_init(void) { SceUID thid; char buff[128], *r; /* fw 1.5 sometimes returns 8002032c, although getcwd works */ r = getcwd(buff, sizeof(buff)); if (r) sceIoChdir(buff); main_thread_id = sceKernelGetThreadId(); lprintf("running on %08x kernel\n", sceKernelDevkitVersion()), lprintf("entered psp_init, threadId %08x, priority %i\n", main_thread_id, sceKernelGetThreadCurrentPriority()); thid = sceKernelCreateThread("update_thread", callback_thread, 0x11, 0xFA0, 0, NULL); if (thid >= 0) { sceKernelStartThread(thid, 0, 0); } /* video */ sceDisplaySetMode(0, 480, 272); sceDisplaySetFrameBuf(VRAM_FB1, 512, PSP_DISPLAY_PIXEL_FORMAT_565, PSP_DISPLAY_SETBUF_NEXTFRAME); current_screen = 1; psp_screen = VRAM_FB0; /* gu */ sceGuInit(); sceGuStart(GU_DIRECT, guCmdList); sceGuDrawBuffer(GU_PSM_5650, (void *)VRAMOFFS_FB0, 512); sceGuDispBuffer(480, 272, (void *)VRAMOFFS_FB1, 512); // don't care sceGuClear(GU_COLOR_BUFFER_BIT | GU_DEPTH_BUFFER_BIT); sceGuDepthBuffer((void *)VRAMOFFS_DEPTH, 512); sceGuOffset(2048 - (480 / 2), 2048 - (272 / 2)); sceGuViewport(2048, 2048, 480, 272); sceGuDepthRange(0xc350, 0x2710); sceGuScissor(0, 0, 480, 272); sceGuEnable(GU_SCISSOR_TEST); sceGuDepthMask(0xffff); sceGuDisable(GU_DEPTH_TEST); sceGuFrontFace(GU_CW); sceGuEnable(GU_TEXTURE_2D); sceGuTexFunc(GU_TFX_REPLACE, GU_TCC_RGB); sceGuAmbientColor(0xffffffff); sceGuColor(0xffffffff); sceGuFinish(); sceGuSync(0, 0); sceDisplayWaitVblankStart(); sceGuDisplay(GU_TRUE); /* input */ sceCtrlSetSamplingCycle(0); sceCtrlSetSamplingMode(PSP_CTRL_MODE_ANALOG); }
int PspSpeedTests::threadFunc(SceSize args, void *argp) { PSP_INFO_PRINT("thread %x created.\n", sceKernelGetThreadId()); _sem.take(); PSP_INFO_PRINT("grabbed semaphore. Quitting thread\n"); return 0; }
// 222: 5-7us int PspSpeedTests::getThreadIdSpeed() { uint32 time1 = PspRtc::instance().getMicros(); int threadId = sceKernelGetThreadId(); uint32 time2 = PspRtc::instance().getMicros(); PSP_INFO_PRINT("Getting thread ID %d took %dus\n", threadId, time2-time1); return threadId; }
static void PSPAUDIO_ThreadInit(_THIS) { /* Increase the priority of this audio thread by 1 to put it ahead of other SDL threads. */ SceUID thid; SceKernelThreadInfo status; thid = sceKernelGetThreadId(); status.size = sizeof(SceKernelThreadInfo); if (sceKernelReferThreadStatus(thid, &status) == 0) { sceKernelChangeThreadPriority(thid, status.currentPriority - 1); } }
void vblankCallback(int no, void *value) { //sceKernelSignalSema(sema, 1); /* if (!vblankCalled) { vblankCalled = 1; } */ vblankCalledThread = sceKernelGetThreadId(); called = 1; *(uint *)value = 3; sceKernelSignalSema(sema, 1); }
int threadCtrlSuspend() { if (threadCtrlState() == THREAD_CTRL_STATE_SUSPEND) { return 1; } int i, n; SceUID this_thid; SceKernelThreadInfo thinfo; this_thid = sceKernelGetThreadId(); sceKernelGetThreadmanIdList(SCE_KERNEL_TMID_Thread, current_thid, MAX_THREAD, ¤t_count); for (i = 0;i < current_count;i++) { memset(&thinfo, 0, sizeof(SceKernelThreadInfo)); thinfo.size = sizeof(SceKernelThreadInfo); sceKernelReferThreadStatus(current_thid[i], &thinfo); if (thinfo.status & PSP_THREAD_SUSPEND || current_thid[i] == this_thid) { current_thid[i] = -1; continue; } for (n = 0;n < first_count;n++) { if (current_thid[i] == first_thid[n]) { current_thid[i] = -1; break; } } } /* - - - - - - - - - - - - - - - - - - - - - - - - - - - */ /* I got a hint from taba's JPCheat, thanks! */ /* - - - - - - - - - - - - - - - - - - - - - - - - - - - */ if (use_safely_suspend) { int count; for (count = 0;count < 1000;count++) { if ((IO_MEM_STICK_STATUS & 0x2000) == 0) { count = 0; } sceKernelDelayThread(1); } } /* - - - - - - - - - - - - - - - - - - - - - - - - - - - */ for (i = 0;i < current_count;i++) { if (current_thid[i] >= 0) { sceKernelSuspendThread(current_thid[i]); } } return 0; }
static void VITAAUD_ThreadInit(_THIS) { /* Increase the priority of this audio thread by 1 to put it ahead of other SDL threads. */ SceUID thid; SceKernelThreadInfo info; thid = sceKernelGetThreadId(); info.size = sizeof(SceKernelThreadInfo); if (sceKernelGetThreadInfo(thid, &info) == 0) { sceKernelChangeThreadPriority(thid, info.currentPriority - 1); } }
int SDL_SYS_SetThreadPriority(SDL_ThreadPriority priority) { int value; if (priority == SDL_THREAD_PRIORITY_LOW) { value = 19; } else if (priority == SDL_THREAD_PRIORITY_HIGH) { value = -20; } else { value = 0; } return sceKernelChangeThreadPriority(sceKernelGetThreadId(),value); }
/* Callback thread */ static int callback_thread(SceSize args, void *argp) { int cbid; lprintf("callback_thread started with id %08x, priority %i\n", sceKernelGetThreadId(), sceKernelGetThreadCurrentPriority()); cbid = sceKernelCreateCallback("Exit Callback", exit_callback, NULL); sceKernelRegisterExitCallback(cbid); cbid = sceKernelCreateCallback("Power Callback", power_callback, NULL); scePowerRegisterCallback(0, cbid); sceKernelSleepThreadCB(); return 0; }
void pspAudioSetChannelCallback(int channel, pspAudioCallback_t callback, void *pdata) { volatile psp_audio_channelinfo *pci = &AudioStatus[channel]; if (callback == 0) { deletingthread = sceKernelGetThreadId();; pci->callback = 0; sceKernelSleepThread(); } else { pci->callback=callback; sceKernelWakeupThread(pci->threadhandle); } }
static void LockAlloc() { if( g_Mutex < 0 ) InitAlloc(); SceUID thid = sceKernelGetThreadId(); if( thid != g_MutexOwner ) { sceKernelWaitSema( g_Mutex, 1, NULL ); g_MutexOwner = thid; } else { g_MutexCount++; } }
int dxpMutexLock(DXPMUTEX *pHnd, int tryFlag) { int ret; const SceUID thid = sceKernelGetThreadId(); if(thid != pHnd->ownerThid) { SceUInt timeout = 0; ret = sceKernelWaitSema(pHnd->semaid, 1, tryFlag ? &timeout : NULL); pHnd->ownerThid = thid; } else { pHnd->count++; ret = 0; } return ret; }
int SDL_SYS_CreateThread(SDL_Thread *thread, void *args) { SceKernelThreadInfo status; int priority = 32; /* Set priority of new thread to the same as the current thread */ status.size = sizeof(SceKernelThreadInfo); if (sceKernelReferThreadStatus(sceKernelGetThreadId(), &status) == 0) { priority = status.currentPriority; } thread->handle = sceKernelCreateThread(thread->name, ThreadEntry, priority, thread->stacksize ? ((int) thread->stacksize) : 0x8000, PSP_THREAD_ATTR_VFPU, NULL); if (thread->handle < 0) { return SDL_SetError("sceKernelCreateThread() failed"); } sceKernelStartThread(thread->handle, 4, &args); return 0; }
int SDL_SYS_CreateThread(SDL_Thread *thread, void *args) { SceKernelThreadInfo info; int priority = 32; /* Set priority of new thread to the same as the current thread */ info.size = sizeof(SceKernelThreadInfo); if (sceKernelGetThreadInfo(sceKernelGetThreadId(), &info) == 0) { priority = info.currentPriority; } thread->handle = sceKernelCreateThread("SDL thread", ThreadEntry, priority, 0x10000, 0, 0, NULL); if (thread->handle < 0) { return SDL_SetError("sceKernelCreateThread() failed"); } sceKernelStartThread(thread->handle, 4, &args); return 0; }
void basicUsage() { int value = 7; sema = sceKernelCreateSema("semaphore", 0, 0, 255, NULL); mainThreadId = sceKernelGetThreadId(); //int cb = sceKernelCreateCallback("vblankCallback", vblankCallback, NULL); sceKernelRegisterSubIntrHandler(PSP_DISPLAY_SUBINT, 0, vblankCallback, &value); printf("beforeEnableVblankCallback\n"); sceKernelEnableSubIntr(PSP_DISPLAY_SUBINT, 0); printf("afterEnableVblankCallback\n"); sceKernelWaitSemaCB(sema, 1, NULL); //while (!vblankCalled) { sceKernelDelayThread(1000); } if (called) { printf("vblankCallback(%d):%d\n", *(int *)&value, (vblankCalledThread == mainThreadId)); } sceKernelReleaseSubIntrHandler(PSP_DISPLAY_SUBINT, 0); //sceDisplayWaitVblank(); printf("ended\n"); }
/* Dump the current thread's status */ void dump_threadstatus(void) { int thid; SceKernelThreadInfo status; int ret; thid = sceKernelGetThreadId(); memset(&status, 0, sizeof(SceKernelThreadInfo)); printf("Thread ID: %08X\n", thid); status.size = sizeof(SceKernelThreadInfo); ret = sceKernelReferThreadStatus(thid, &status); printf("Get Thread Status: %08X\n", ret); if(ret == 0) { printf("Name: %s\n", status.name); printf("Thread Addr: %p\n", status.entry); printf("Stack Addr: %p\n", status.stack); printf("Stack Size: %08X\n", status.stackSize); printf("gp: %p\n", status.gpReg); printf("Initial Pri: %x\n", status.initPriority); printf("Current Pri: %x\n", status.currentPriority); } }
static int hookEntry(SceSize args, void *argp) { SceKernelSemaInfo info; globals_t *globals; SceUID uid; int res; uid = sceKernelGetThreadId(); globals = getGlobals(); sceKernelLockMutexCB(globals->threadmgrMutex, 1, NULL); info.size = sizeof(info); res = sceKernelGetSemaInfo(globals->threadmgrSema, &info); if (res) goto fail; while (globals->threadmgrTable[info.currentCount].uid != uid) { if (info.currentCount >= info.maxCount) { res = SCE_KERNEL_ERROR_ERROR; goto fail; } info.currentCount++; } globals->threadmgrTable[info.currentCount].exitDeleteCb = sceKernelCreateCallback("vhlUserExitDeleteCb", 0, exitDeleteCb, NULL); sceKernelUnlockMutex(globals->threadmgrMutex, 1); return globals->threadmgrTable[info.currentCount].entry(args, argp); fail: sceKernelUnlockMutex(globals->threadmgrMutex, 1); return res; }
void runReferTests() { SceKernelThreadInfo2 info; int i; SceUID delayThread = sceKernelCreateThread("delay", &delayFunc, sceKernelGetThreadCurrentPriority(), 0x1000, PSP_THREAD_ATTR_VFPU, NULL); SceUID deletedThread = sceKernelCreateThread("deleted", &delayFunc, sceKernelGetThreadCurrentPriority(), 0x1000, 0, NULL); sceKernelDeleteThread(deletedThread); info.size = sizeof(info); checkpointNext("Thread IDs:"); checkpoint(" NULL: %08x", sceKernelReferThreadStatus(0, &info)); checkpoint(" Current: %08x", sceKernelReferThreadStatus(sceKernelGetThreadId(), &info)); checkpoint(" Deleted: %08x", sceKernelReferThreadStatus(deletedThread, &info)); checkpoint(" Invalid: %08x", sceKernelReferThreadStatus(0xDEADBEEF, &info)); // Crashes. //checkpointNext("sceKernelReferThreadStatus info ptr:"); //checkpoint(" NULL info: %08x", sceKernelReferThreadStatus(0, NULL)); checkpointNext("Sizes:"); int sizes[] = {-1, 0, 1, 2, 3, 4, 5, 8, 16, 32, 64, 80, 82, 108, 128, 1024}; for (i = 0; i < ARRAY_SIZE(sizes); ++i) { memset(&info, 0xff, sizeof(info)); info.size = sizes[i]; int result = sceKernelReferThreadStatus(0, &info); checkpoint(" %d: %08x => %d (exit: %x)", sizes[i], result, info.size, info.exitStatus); } info.size = sizeof(info); sceKernelStartThread(delayThread, 0, NULL); sceKernelReferThreadStatus(delayThread, &info); checkpointNext("Values:"); schedfThreadInfo(&info, &delayFunc); SceUID slumberThread = sceKernelCreateThread("slumber", &slumberFunc, sceKernelGetThreadCurrentPriority() - 1, 0x1000, 0, NULL); checkpoint(" slumber before start:"); sceKernelReferThreadStatus(slumberThread, &info); schedfThreadInfo(&info, &slumberFunc); sceKernelStartThread(slumberThread, 0, NULL); checkpoint(" started slumber"); checkpoint(" slumber after start:"); sceKernelReferThreadStatus(slumberThread, &info); schedfThreadInfo(&info, &slumberFunc); sceKernelTerminateThread(slumberThread); checkpoint(" terminated slumber"); checkpoint(" slumber after terminate:"); sceKernelReferThreadStatus(slumberThread, &info); schedfThreadInfo(&info, &slumberFunc); sceKernelStartThread(slumberThread, 0, NULL); checkpoint(" started slumber"); checkpoint(" slumber after start:"); sceKernelReferThreadStatus(slumberThread, &info); schedfThreadInfo(&info, &slumberFunc); checkpoint(" woke slumber: %08x", sceKernelWakeupThread(slumberThread)); checkpoint(" slumber after wake:"); sceKernelReferThreadStatus(slumberThread, &info); schedfThreadInfo(&info, &slumberFunc); sceKernelTerminateDeleteThread(slumberThread); checkpoint(" terminated and deleted slumber"); // TODO: Test more cases. flushschedf(); }
static inline void init_context_switch(void) { main_thread = sceKernelGetThreadId(); cpu_thread = sceKernelCreateThread ("CPU thread", cpu_thread_entry, 0x12, 0x20000, 0, NULL); sceKernelStartThread(cpu_thread, 0, NULL); }
SDL_threadID SDL_ThreadID(void) { return (SDL_threadID) sceKernelGetThreadId(); }
static int MainThread( SceSize args, void *argp ) { hookDisplay(); sceKernelDcacheWritebackInvalidateAll(); sceKernelIcacheInvalidateAll(); //scePowerTick( 0 ); unsigned int paddata_old = 0; char file[64], flag = 0, size = 0; int x, y, fd, count = 0, thread_count_start, thread_count_now; SceUID thread_buf_start[MAX_THREAD], thread_buf_now[MAX_THREAD], myThread = sceKernelGetThreadId(); SceCtrlData paddata; sceKernelDelayThread(10000); sceKernelGetThreadmanIdList(SCE_KERNEL_TMID_Thread, thread_buf_start, MAX_THREAD, &thread_count_start); while(1) { sceCtrlPeekBufferPositive(&paddata, 1); if(paddata.Buttons != paddata_old) { //press "note" button and magick begin if(paddata.Buttons & PSP_CTRL_NOTE) { // IdList Now sceKernelGetThreadmanIdList(SCE_KERNEL_TMID_Thread, thread_buf_now, MAX_THREAD, &thread_count_now); //hold all threads for a moment for(x = 0; x < thread_count_now; x++) { // thread id match 0 or 1 unsigned char match = 0; SceUID tmp_thid = thread_buf_now[x]; for(y = 0; y < thread_count_start; y++) { if((tmp_thid == thread_buf_start[y]) || (tmp_thid == myThread)) { match = 1; y = thread_count_start; } } if(thread_count_start == 0) match = 1; if(match == 0) { sceKernelSuspendThread(tmp_thid); } } //can parse command list can_parse = 1; //resume all threads for(x = 0; x < thread_count_now; x++) { // thread id match 0 or 1 unsigned char match = 0; SceUID tmp_thid = thread_buf_now[x]; for(y = 0; y < thread_count_start; y++) { if((tmp_thid == thread_buf_start[y]) || (tmp_thid == myThread)) { match = 1; y = thread_count_start; } } if(thread_count_start == 0) match = 1; if(match == 0) { sceKernelResumeThread(tmp_thid); } } } } paddata_old = paddata.Buttons; sceKernelDelayThread(10000); } return( 0 ); }
static int music_thread(SceSize arg, void *argp) { u32 key = 0; u32 oldkey = 0; u64 start, end; double interval = 0; g_thread_actived = 1; g_thread_exited = 0; sceRtcGetCurrentTick(&start); sceRtcGetCurrentTick(&end); while (g_thread_actived) { music_lock(); if (g_list.is_list_playing) { if (musicdrv_has_stop()) { if (g_list.first_time) { int ret; ret = music_play(g_list.curr_pos); if (ret == 0) g_list.first_time = false; } else { get_next_music(); if (!g_list.is_list_playing) { music_unlock(); music_load(g_list.curr_pos); music_stop(); continue; } music_play(g_list.curr_pos); } } music_unlock(); sceKernelDelayThread(100000); } else { music_unlock(); sceKernelDelayThread(500000); } if (g_music_hprm_enable) { key = ctrl_hprm_raw(); sceRtcGetCurrentTick(&end); interval = pspDiffTime(&end, &start); if (key == PSP_HPRM_FORWARD || key == PSP_HPRM_BACK || key == PSP_HPRM_PLAYPAUSE) { if (key != oldkey) { sceRtcGetCurrentTick(&start); sceRtcGetCurrentTick(&end); interval = pspDiffTime(&end, &start); } if (interval >= 0.5) { if (key == PSP_HPRM_FORWARD) { musicdrv_fforward(5); sceKernelDelayThread(200000); } else if (key == PSP_HPRM_BACK) { musicdrv_fbackward(5); sceKernelDelayThread(200000); } } oldkey = key; if (key == PSP_HPRM_PLAYPAUSE && interval >= 4.0) { power_down(); scePowerRequestSuspend(); } } else { if ((oldkey == PSP_HPRM_FORWARD || oldkey == PSP_HPRM_BACK || oldkey == PSP_HPRM_PLAYPAUSE)) { if (interval < 0.5) { if (oldkey == PSP_HPRM_FORWARD) music_next(); else if (oldkey == PSP_HPRM_BACK) music_prev(); } if (interval < 4.0) { if (oldkey == PSP_HPRM_PLAYPAUSE) music_list_playorpause(); } } oldkey = key; sceRtcGetCurrentTick(&start); } } { int thid = sceKernelGetThreadId(); int oldpri = sceKernelGetThreadCurrentPriority(); sceKernelChangeThreadPriority(thid, 90); cache_routine(); sceKernelChangeThreadPriority(thid, oldpri); } } g_thread_actived = 0; g_thread_exited = 1; return 0; }
int main(int argc, char *argv[]) { SceCtrlData pad; int result; int oldButtons = 0; int cbid = -1; int waitStatThid = -1; pspDebugScreenInit(); if (argc > 0) { printf("Bootpath: %s\n", argv[0]); } printf("Triangle - Exit\n"); printf("Left - sceUmdActivate\n"); printf("Right - sceUmdDeactivate\n"); printf("Cross - Delay CB\n"); printf("Circle - Display umd info\n"); printf("Square - Refer umd callback\n"); printf("L-Trigger - IO test\n"); printf("R-Trigger - Start/Stop wait stat test\n"); SetupCallbacks(); sceCtrlSetSamplingCycle(0); sceCtrlSetSamplingMode(PSP_CTRL_MODE_ANALOG); { printUmdInfo(); // result: // callback events are generated if we launch from iso or immediately after psplink has reset cbid = sceKernelCreateCallback("UMD Callback (not active)", umd_callback, (void*)0x34343434); result = sceUmdRegisterUMDCallBack(cbid); printf("sceUmdRegisterUMDCallBack result %08X\n", result); // Register a second UMD callback: it will overwrite the first one. cbid = sceKernelCreateCallback("UMD Callback", umd_callback, (void*)0x11111111); result = sceUmdRegisterUMDCallBack(cbid); printf("sceUmdRegisterUMDCallBack result %08X\n", result); } while (!done) { sceCtrlReadBufferPositive(&pad, 1); // context switch in here //sceCtrlPeekBufferPositive(&pad, 1); // no context switch version int buttonDown = (oldButtons ^ pad.Buttons) & pad.Buttons; if (buttonDown & PSP_CTRL_LEFT) { result = sceUmdActivate(1, "disc0:"); printf("sceUmdActivate result %08x\n", result); } if (buttonDown & PSP_CTRL_RIGHT) { result = sceUmdDeactivate(1, "disc0:"); printf("sceUmdDeactivate result %08x\n", result); } if (buttonDown & PSP_CTRL_CROSS) { printf("sceKernelDelayThreadCB ...\n"); sceKernelDelayThreadCB(10000); } if (buttonDown & PSP_CTRL_CIRCLE) { printUmdInfo(); } if (buttonDown & PSP_CTRL_SQUARE) { SceKernelCallbackInfo info; memset(&info, 0xee, sizeof(info)); info.size = sizeof(info); result = sceKernelReferCallbackStatus(cbid, &info); printf("sceKernelReferCallbackStatus result %08x\n", result); printf(" size %d (%d)\n", info.size, sizeof(info)); printf(" name '%s'\n", info.name); printf(" threadId %08x (%08x)\n", info.threadId, sceKernelGetThreadId()); printf(" callback %p common %p\n", info.callback, info.common); printf(" notifyCount %08x\n", info.notifyCount); printf(" notifyArg %08x\n", info.notifyArg); } if (buttonDown & PSP_CTRL_LTRIGGER) { test_io(); } if (buttonDown & PSP_CTRL_RTRIGGER) { if (waitStatThid >= 0) { printf("Cleaning up wait stat test ...\n"); referThread(waitStatThid); result = sceUmdCancelWaitDriveStat(); printf("sceUmdCancelWaitDriveStat result %08x\n", result); referThread(waitStatThid); result = sceKernelDeleteThread(waitStatThid); printf("sceKernelDeleteThread result %08x\n", result); //result = sceKernelTerminateDeleteThread(waitStatThid); //printf("sceKernelTerminateDeleteThread result %08x\n", result); waitStatThid = -1; } else { printf("Starting wait stat test ...\n"); // test timeout: // Press Right (deactivate UMD) // Press R-Trigger: // - Press R-Trigger again before 3 seconds: // 0x800201a9 wait cancelled // - Or wait 3 seconds: // 0x800201a8 wait timeout struct WaitStatParams params = { 0x20, 3000000 }; // test internal workings: // - (wantStat & curStat) == wantStat // - (wantStat & curStat) != 0 <-- looks like this is the correct one //struct WaitStatParams params = { 0xFF, 3000000 }; waitStatThid = sceKernelCreateThread("WaitUMDStat", waitstat_thread, 0x20, 0x4000, 0, 0); printf("sceKernelCreateThread result %08x\n", waitStatThid); if (waitStatThid >= 0) { result = sceKernelStartThread(waitStatThid, sizeof(params), ¶ms); printf("sceKernelStartThread result %08x\n", result); } } } if (buttonDown & PSP_CTRL_TRIANGLE) done = 1; oldButtons = pad.Buttons; sceDisplayWaitVblank(); // only catch callback when we press Cross (sceKernelDelayThreadCB) //sceDisplayWaitVblankCB(); // catch all callback events } sceKernelExitGame(); return 0; }
int main(int argc, char *argv[]) { int i, result; SceKernelThreadInfo info; SceUID testThread = sceKernelCreateThread("test", &testFunc, sceKernelGetThreadCurrentPriority(), 0x1000, 0, NULL); SceUID deletedThread = sceKernelCreateThread("deleted", &testFunc, sceKernelGetThreadCurrentPriority(), 0x1000, 0, NULL); sceKernelDeleteThread(deletedThread); checkpointNext("Thread IDs:"); checkpoint(" Normal: %08x", sceKernelStartThread(testThread, 0, NULL)); checkpoint(" Twice: %08x", sceKernelStartThread(testThread, 0, NULL)); checkpoint(" NULL: %08x", sceKernelStartThread(0, 0, NULL)); checkpoint(" Current: %08x", sceKernelStartThread(sceKernelGetThreadId(), 0, NULL)); checkpoint(" Deleted: %08x", sceKernelStartThread(deletedThread, 0, NULL)); checkpoint(" Invalid: %08x", sceKernelStartThread(0xDEADBEEF, 0, NULL)); checkpointNext("Argument length:"); SceUID argLengthThread = sceKernelCreateThread("argLength", &argLengthFunc, sceKernelGetThreadCurrentPriority() - 1, 0x800, 0, NULL); char argLengthTemp[0x1000]; void *argLengthStack; info.size = sizeof(info); sceKernelReferThreadStatus(argLengthThread, &info); argLengthStack = info.stack; result = sceKernelStartThread(argLengthThread, 8, NULL); sceKernelWaitThreadEnd(argLengthThread, NULL); char temp[256]; if (argLengthArgv == 0) sprintf(temp, "NULL"); else if (argLengthArgv == argLengthTemp) sprintf(temp, "original"); else sprintf(temp, "stack+0x%x", (char *)argLengthArgv - (char *)argLengthStack); checkpoint(" With NULL ptr: %08x (%d, %s)", result, argLengthArgc, temp); // Note: larger than stack seems to crash the PSP... static int lengths[] = {-1, 0x80000000, 0, 1, 2, 3, 4, 5, 6, 7, 8, 80, 90, 0x600}; for (i = 0; i < ARRAY_SIZE(lengths); ++i) { argLengthArgc = -1; argLengthArgv = NULL; result = sceKernelStartThread(argLengthThread, lengths[i], argLengthTemp); sceKernelWaitThreadEnd(argLengthThread, NULL); if (argLengthArgv == 0) sprintf(temp, "NULL"); else if (argLengthArgv == argLengthTemp) sprintf(temp, "original"); else sprintf(temp, "stack+0x%x", (char *)argLengthArgv - (char *)argLengthStack); checkpoint(" %d arg length: %08x (%d, %s)", lengths[i], result, argLengthArgc, temp); } // NULL crashes it, though... checkpointNext("Argument pointers:"); void *argptrs[] = {argLengthTemp, (void *)0xDEADBEEF, (void *)0x80000000}; for (i = 0; i < ARRAY_SIZE(argptrs); ++i) { argLengthArgc = -1; argLengthArgv = NULL; result = sceKernelStartThread(argLengthThread, 4, argptrs[i]); sceKernelWaitThreadEnd(argLengthThread, NULL); if (argLengthArgv == 0) sprintf(temp, "NULL"); else if (argLengthArgv == argLengthTemp) sprintf(temp, "original"); else sprintf(temp, "stack+0x%x", (char *)argLengthArgv - (char *)argLengthStack); checkpoint(" arg ptr #%d: %08x (%d, %s)", i, result, argLengthArgc, temp); } checkpointNext("Priorities:"); static int priorities[] = {0x8, 0x1F, 0x20, 0x21, 0x40}; for (i = 0; i < ARRAY_SIZE(priorities); ++i) { argLengthArgc = -1; sceKernelDeleteThread(argLengthThread); argLengthThread = sceKernelCreateThread("argLength", &argLengthFunc, priorities[i], 0x800, 0, NULL); result = sceKernelStartThread(argLengthThread, priorities[i], argLengthTemp); int afterStart = argLengthArgc; sceKernelWaitThreadEnd(argLengthThread, NULL); int priorityDiff = priorities[i] - sceKernelGetThreadCurrentPriority(); checkpoint(" priority 0x%02x: %08x (current%s0x%02x, %s)", priorities[i], result, priorityDiff < 0 ? "-" : "+", priorityDiff < 0 ? -priorityDiff : priorityDiff, afterStart == priorities[i] ? "resched" : (argLengthArgc == priorities[i] ? "deferred" : "never")); } checkpointNext("Stack:"); testCheckStackLayout(" No arg", 0, 0); testCheckStackLayout(" Odd arg", 1, 0); testCheckStackLayout(" Large arg", 0x600, 0); testCheckStackLayout(" Low stack", 0, 0x00400000); testCheckStackLayout(" Without fill", 0, 0x00100000); testCheckStackLayout(" Clear stack", 0, 0x00200000); return 0; }
void lprintf(const char *fmt, ...) { va_list vl; #ifdef LPRINTF_STDIO va_start(vl, fmt); vprintf(fmt, vl); va_end(vl); #else static SceUID logfd = -1; static int msg_count = 0; char buff[256]; log_entry *le, *le1; if (logfd == -2) return; // disabled va_start(vl, fmt); vsnprintf(buff, sizeof(buff), fmt, vl); va_end(vl); // note: this is still unsafe code if (main_thread_id != sceKernelGetThreadId()) { le = malloc(sizeof(*le)); if (le == NULL) return; le->next = NULL; strcpy(le->buff, buff); if (le_root == NULL) le_root = le; else { for (le1 = le_root; le1->next != NULL; le1 = le1->next); le1->next = le; } return; } logfd = sceIoOpen(LOG_FILE, PSP_O_WRONLY|PSP_O_APPEND, 0777); if (logfd < 0) { if (msg_count == 0) logfd = -2; return; } if (le_root != NULL) { le1 = le_root; le_root = NULL; sceKernelDelayThread(1000); while (le1 != NULL) { le = le1; le1 = le->next; sceIoWrite(logfd, le->buff, strlen(le->buff)); free(le); msg_count++; } } sceIoWrite(logfd, buff, strlen(buff)); msg_count++; // make sure it gets flushed sceIoClose(logfd); logfd = -1; #endif }