void checkVblankInterruptHandler() { int counter = 0, last_counter = 0; int results[3], n; //pspDebugScreenInit(); pspDebugScreenPrintf("Starting...\n"); printf("Starting...\n"); sceKernelRegisterSubIntrHandler(PSP_VBLANK_INT, 0, vblank_handler_counter, &counter); sceKernelDelayThread(80000); results[0] = counter; printf("NotEnabled: Counter:%s\n", (counter == 0) ? "zero" : "non-zero"); // 0. Not enabled yet. sceKernelEnableSubIntr(PSP_VBLANK_INT, 0); sceKernelDelayThread(160000); results[1] = counter; printf("Enabled (GreaterThan2): Counter:%s\n", (counter >= 2) ? "greater" : "no greater"); // n. Already enabled. sceKernelReleaseSubIntrHandler(PSP_VBLANK_INT, 0); last_counter = counter; sceKernelDelayThread(80000); results[2] = counter; printf("Disabled (NotChangedAfterDisabled): %s\n", (last_counter != counter) ? "changed" : "not changed"); // n. Disabled. for (n = 0; n < 3; n++) { //printf("Output %d:%d\n", n, results[n]); pspDebugScreenPrintf("%d\n", results[n]); } }
/*------------------------------------------------------------------------------*/ void TranceAsyncOn( void ) { if ( IndexUseNow != -1 ){ return; } if ( sceKernelRegisterSubIntrHandler_Func == NULL ){ return; } IndexUseNow = FindUnuseIndex(); if ( IndexUseNow == -1 ){ return; } sceKernelRegisterSubIntrHandler_Func( 30, IndexUseNow, SendDispEvent, 0 ); sceKernelEnableSubIntr( 30, IndexUseNow ); }
u32 sceGeSetCallback(u32 structAddr) { DEBUG_LOG(HLE,"sceGeSetCallback(struct=%08x)", structAddr); PspGeCallbackData ge_callback_data; Memory::ReadStruct(structAddr, &ge_callback_data); if (ge_callback_data.finish_func) { sceKernelRegisterSubIntrHandler(PSP_GE_INTR, PSP_GE_SUBINTR_FINISH, ge_callback_data.finish_func, ge_callback_data.finish_arg); sceKernelEnableSubIntr(PSP_GE_INTR, PSP_GE_SUBINTR_FINISH); } if (ge_callback_data.signal_func) { sceKernelRegisterSubIntrHandler(PSP_GE_INTR, PSP_GE_SUBINTR_SIGNAL, ge_callback_data.signal_func, ge_callback_data.signal_arg); sceKernelEnableSubIntr(PSP_GE_INTR, PSP_GE_SUBINTR_SIGNAL); } // TODO: This should return a callback ID return 0; }
void suspendUsage() { int counter; sceKernelRegisterSubIntrHandler(PSP_VBLANK_INT, 0, vblank_counter, &counter); counter = 0; sceKernelEnableSubIntr(PSP_VBLANK_INT, 0); int flag = sceKernelCpuSuspendIntr(); sceKernelDelayThread(300000); sceKernelCpuResumeIntr(flag); sceKernelDisableSubIntr(PSP_VBLANK_INT, 0); printf("Interrupts suspended: %d\n", counter); counter = 0; sceKernelRegisterSubIntrHandler(PSP_VBLANK_INT, 0, vblank_counter, &counter); sceKernelEnableSubIntr(PSP_VBLANK_INT, 0); sceKernelDelayThread(300000); sceKernelDisableSubIntr(PSP_VBLANK_INT, 0); sceKernelReleaseSubIntrHandler(PSP_VBLANK_INT, 0); printf("Interrupts resumed: %d\n", counter); }
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"); }
void checkDispatchInterrupt() { dispatchCheckpoint("Interrupts while dispatch disabled:"); sceKernelRegisterSubIntrHandler(PSP_VBLANK_INT, 0, &vblankCallback, NULL); sceKernelEnableSubIntr(PSP_VBLANK_INT, 0); ++ignoreResched; int state = sceKernelSuspendDispatchThread(); int base = sceDisplayGetVcount(); int i, j; for (i = 0; i < 1000; ++i) { if (sceDisplayGetVcount() > base + 3) { break; } for (j = 0; j < 10000; ++j) continue; } dispatchCheckpoint("vblanks=%d", sceDisplayGetVcount() - base); sceKernelResumeDispatchThread(state); --ignoreResched; base = sceDisplayGetVcount(); for (i = 0; i < 1000; ++i) { if (sceDisplayGetVcount() > base + 3) { break; } for (j = 0; j < 10000; ++j) continue; } dispatchCheckpoint("vblanks=%d", sceDisplayGetVcount() - base); sceKernelDisableSubIntr(PSP_VBLANK_INT, 0); sceKernelReleaseSubIntrHandler(PSP_VBLANK_INT, 0); flushschedf(); }
static void *psp_init(const video_info_t *video, const input_driver_t **input, void **input_data) { /* to-do : add ASSERT() checks or use main RAM if * VRAM is too low for desired video->input_scale. */ void *pspinput; int pixel_format, lut_pixel_format, lut_block_count; unsigned int red_shift, color_mask; void *displayBuffer, *LUT_r, *LUT_b; psp1_video_t *psp = (psp1_video_t*)calloc(1, sizeof(psp1_video_t)); if (!psp) return NULL; sceGuInit(); psp->vp.x = 0; psp->vp.y = 0; psp->vp.width = SCEGU_SCR_WIDTH; psp->vp.height = SCEGU_SCR_HEIGHT; psp->vp.full_width = SCEGU_SCR_WIDTH; psp->vp.full_height = SCEGU_SCR_HEIGHT; /* Make sure anything using uncached pointers reserves * whole cachelines (memory address and size need to be a multiple of 64) * so it isn't overwritten by an unlucky cache writeback. * * This includes display lists since the Gu library uses * uncached pointers to write to them. */ /* Allocate more space if bigger display lists are needed. */ psp->main_dList = memalign(64, 256); psp->frame_dList = memalign(64, 256); psp->menu.dList = memalign(64, 256); psp->menu.frame = memalign(16, 2 * 480 * 272); psp->frame_coords = memalign(64, (((PSP_FRAME_SLICE_COUNT * sizeof(psp1_sprite_t)) + 63) & ~63)); psp->menu.frame_coords = memalign(64, (((PSP_FRAME_SLICE_COUNT * sizeof(psp1_sprite_t)) + 63) & ~63)); memset(psp->frame_coords, 0, PSP_FRAME_SLICE_COUNT * sizeof(psp1_sprite_t)); memset(psp->menu.frame_coords, 0, PSP_FRAME_SLICE_COUNT * sizeof(psp1_sprite_t)); sceKernelDcacheWritebackInvalidateAll(); psp->frame_coords = TO_UNCACHED_PTR(psp->frame_coords); psp->menu.frame_coords = TO_UNCACHED_PTR(psp->menu.frame_coords); psp->frame_coords->v0.x = 60; psp->frame_coords->v0.y = 0; psp->frame_coords->v0.u = 0; psp->frame_coords->v0.v = 0; psp->frame_coords->v1.x = 420; psp->frame_coords->v1.y = SCEGU_SCR_HEIGHT; psp->frame_coords->v1.u = 256; psp->frame_coords->v1.v = 240; psp->vsync = video->vsync; psp->rgb32 = video->rgb32; if(psp->rgb32) { uint32_t* LUT_r_local = (uint32_t*)(SCEGU_VRAM_BP32_2); uint32_t* LUT_b_local = (uint32_t*)(SCEGU_VRAM_BP32_2) + (1 << 8); red_shift = 8 + 8; color_mask = 0xFF; lut_block_count = (1 << 8) / 8; psp->texture = (void*)(LUT_b_local + (1 << 8)); psp->draw_buffer = SCEGU_VRAM_BP32_0; psp->bpp_log2 = 2; pixel_format = GU_PSM_8888; lut_pixel_format = GU_PSM_T32; displayBuffer = SCEGU_VRAM_BP32_1; for (u32 i=0; i < (1 << 8); i++){ LUT_r_local[i]= i; LUT_b_local[i]= i << (8 + 8); } LUT_r = (void*)LUT_r_local; LUT_b = (void*)LUT_b_local; } else { uint16_t* LUT_r_local = (uint16_t*)(SCEGU_VRAM_BP_2); uint16_t* LUT_b_local = (uint16_t*)(SCEGU_VRAM_BP_2) + (1 << 5); red_shift = 6 + 5; color_mask = 0x1F; lut_block_count = (1 << 5) / 8; psp->texture = (void*)(LUT_b_local + (1 << 5)); psp->draw_buffer = SCEGU_VRAM_BP_0; psp->bpp_log2 = 1; pixel_format = (g_extern.system.pix_fmt == RETRO_PIXEL_FORMAT_0RGB1555) ? GU_PSM_5551 : GU_PSM_5650 ; lut_pixel_format = GU_PSM_T16; displayBuffer = SCEGU_VRAM_BP_1; for (u16 i = 0; i < (1 << 5); i++) { LUT_r_local[i]= i; LUT_b_local[i]= i << (5 + 6); } LUT_r = (void*)LUT_r_local; LUT_b = (void*)LUT_b_local; } psp->tex_filter = video->smooth? GU_LINEAR : GU_NEAREST; /* TODO: check if necessary. */ sceDisplayWaitVblankStart(); sceGuDisplay(GU_FALSE); sceGuStart(GU_DIRECT, psp->main_dList); sceGuDrawBuffer(pixel_format, TO_GU_POINTER(psp->draw_buffer), SCEGU_VRAM_WIDTH); sceGuDispBuffer(SCEGU_SCR_WIDTH, SCEGU_SCR_HEIGHT, TO_GU_POINTER(displayBuffer), SCEGU_VRAM_WIDTH); sceGuClearColor(0); sceGuScissor(0, 0, SCEGU_SCR_WIDTH, SCEGU_SCR_HEIGHT); sceGuEnable(GU_SCISSOR_TEST); sceGuTexFilter(psp->tex_filter, psp->tex_filter); sceGuTexWrap (GU_CLAMP, GU_CLAMP); sceGuEnable(GU_TEXTURE_2D); sceGuDisable(GU_DEPTH_TEST); sceGuCallMode(GU_FALSE); sceGuFinish(); sceGuSync(0, 0); /* TODO : check if necessary */ sceDisplayWaitVblankStart(); sceGuDisplay(GU_TRUE); pspDebugScreenSetColorMode(pixel_format); pspDebugScreenSetBase(psp->draw_buffer); /* fill frame_dList : */ sceGuStart(GU_CALL, psp->frame_dList); sceGuTexMode(pixel_format, 0, 0, GU_FALSE); sceGuTexFunc(GU_TFX_REPLACE, GU_TCC_RGB); sceGuEnable(GU_BLEND); /* green only */ sceGuBlendFunc(GU_ADD, GU_FIX, GU_FIX, 0x0000FF00, 0xFFFFFFFF); sceGuDrawArray(GU_SPRITES, GU_TEXTURE_32BITF | GU_VERTEX_32BITF | GU_TRANSFORM_2D, PSP_FRAME_VERTEX_COUNT, NULL, (void*)(psp->frame_coords)); /* restore */ sceGuBlendFunc(GU_ADD, GU_FIX, GU_FIX, 0xFFFFFFFF, 0xFFFFFFFF); sceGuTexMode(lut_pixel_format, 0, 0, GU_FALSE); sceGuClutMode(pixel_format, red_shift, color_mask, 0); sceGuClutLoad(lut_block_count, LUT_r); sceGuDrawArray(GU_SPRITES, GU_TEXTURE_32BITF | GU_VERTEX_32BITF | GU_TRANSFORM_2D, PSP_FRAME_VERTEX_COUNT, NULL, (void*)(psp->frame_coords)); sceGuClutMode(pixel_format, 0, color_mask, 0); sceGuClutLoad(lut_block_count, LUT_b); sceGuDrawArray(GU_SPRITES, GU_TEXTURE_32BITF | GU_VERTEX_32BITF | GU_TRANSFORM_2D, PSP_FRAME_VERTEX_COUNT, NULL, (void*)(psp->frame_coords)); sceGuFinish(); if (input && input_data) { pspinput = input_psp.init(); *input = pspinput ? &input_psp : NULL; *input_data = pspinput; } psp->vblank_not_reached = true; sceKernelRegisterSubIntrHandler(PSP_VBLANK_INT, 0, psp_on_vblank, psp); sceKernelEnableSubIntr(PSP_VBLANK_INT, 0); psp->keep_aspect = true; psp->should_resize = true; psp->hw_render = false; return psp; error: RARCH_ERR("PSP1 video could not be initialized.\n"); return (void*)-1; }
extern "C" int main(int argc, char *argv[]) { int result; sceKernelRegisterSubIntrHandler(30, 1, (void *)&handler, (void *)0xDEADBEEF); checkpointNext("sceKernelEnableSubIntr:"); result = sceKernelEnableSubIntr(70, 1); checkpoint(" Invalid intr: %08x", result); result = sceKernelEnableSubIntr(30, 70); checkpoint(" Invalid subintr: %08x", result); result = sceKernelEnableSubIntr(30, 1); checkpoint(" Registered: %08x", result); result = sceKernelEnableSubIntr(30, 1); checkpoint(" Twice: %08x", result); result = sceKernelEnableSubIntr(30, 3); checkpoint(" Unregistered: %08x", result); sceKernelDisableSubIntr(30, 2); sceKernelDisableSubIntr(30, 1); checkpointNext("Interrupts run when enabled:"); checkpoint(" With handler first:"); result = sceKernelEnableSubIntr(30, 1); sceKernelDelayThread(17000); sceKernelDisableSubIntr(30, 1); checkpoint(" With handler after:"); result = sceKernelEnableSubIntr(30, 2); sceKernelRegisterSubIntrHandler(30, 2, (void *)&handler, (void *)0xDEADBEEF); sceKernelDelayThread(17000); sceKernelDisableSubIntr(30, 2); sceKernelReleaseSubIntrHandler(30, 2); checkpoint(" Without handler:"); result = sceKernelEnableSubIntr(30, 3); sceKernelDelayThread(17000); sceKernelDisableSubIntr(30, 3); checkpoint(" Released while enabled:"); sceKernelRegisterSubIntrHandler(30, 4, (void *)&handler, (void *)0xDEADBEEF); result = sceKernelEnableSubIntr(30, 4); sceKernelReleaseSubIntrHandler(30, 4); sceKernelRegisterSubIntrHandler(30, 4, (void *)&handler, (void *)0xDEADBEEF); sceKernelDelayThread(17000); sceKernelDisableSubIntr(30, 4); sceKernelReleaseSubIntrHandler(30, 4); checkpointNext("sceKernelDisableSubIntr:"); result = sceKernelDisableSubIntr(70, 1); checkpoint(" Invalid intr: %08x", result); result = sceKernelDisableSubIntr(30, 70); checkpoint(" Invalid subintr: %08x", result); sceKernelEnableSubIntr(30, 1); result = sceKernelDisableSubIntr(30, 1); checkpoint(" Registered: %08x", result); result = sceKernelDisableSubIntr(30, 1); checkpoint(" Twice: %08x", result); result = sceKernelDisableSubIntr(30, 3); checkpoint(" Unregistered: %08x", result); sceKernelReleaseSubIntrHandler(30, 1); return 0; }