diff --git a/libogc/exception.c b/libogc/exception.c index 8773e417..d9b04643 100644 --- a/libogc/exception.c +++ b/libogc/exception.c @@ -61,6 +61,7 @@ typedef struct _framerec { } frame_rec, *frame_rec_t; static void *exception_xfb = (void*)0xC1700000; //we use a static address above ArenaHi. +static void *lookup_xfb = NULL; static int reload_timer = -1; void __exception_sethandler(u32 nExcept, void (*pHndl)(frame_context*)); @@ -198,40 +199,71 @@ void __exception_setreload(int t) reload_timer = t*50; } +static void __toggleframebuffer() { + if(VIDEO_GetCurrentFramebuffer() == exception_xfb) { + VIDEO_SetFramebuffer(lookup_xfb); + } else { + VIDEO_SetFramebuffer(exception_xfb); + } + VIDEO_Flush(); +} + static void waitForReload(void) { u32 level; - + PAD_Init(); - kprintf("\n\n\tPress RESET, or Z on a GameCube Controller, to reload\n\n"); + VIDEO_WaitVSync(); // For VI/PAD_Interface Timing + + kprintf("\n\tRESET / A: Reset, B: Reload"); + if (lookup_xfb) { + kprintf(", START: Show the previous XFB\n"); + } else { + kprintf("\n"); + } while ( 1 ) { if(reload_timer > 0) { kprintf("\x1b[2K\r\tReloading in %d seconds", reload_timer/50); } + PAD_ScanPads(); + + // Checks all controller ports because why not + int buttonsDown = PAD_ButtonsDown(0) | PAD_ButtonsDown(1) | PAD_ButtonsDown(2) | PAD_ButtonsDown(3); - int buttonsDown = PAD_ButtonsDown(0); - - if( (buttonsDown & PAD_TRIGGER_Z) || SYS_ResetButtonDown() || reload_timer == 0 ) + if( (buttonsDown & PAD_BUTTON_B) || reload_timer == 0 ) { - kprintf("\n\tReload\n\n\n"); + // Clears the screen because the added text + // could interfere with the ability of showing the full stack + consoleClear(); + kprintf("\tReloading..."); _CPU_ISR_Disable(level); __reload (); } - if ( buttonsDown & PAD_BUTTON_A ) + if ( (buttonsDown & PAD_BUTTON_START) && lookup_xfb ) { + reload_timer--; + __toggleframebuffer(); + VIDEO_WaitVSync(); + udelay(20000); + } + + if ( buttonsDown & PAD_BUTTON_A || SYS_ResetButtonDown() ) { - kprintf("\n\tReset\n\n\n"); + // Clears the screen because the added text + // could interfere with the ability of showing the full stack + consoleClear(); + kprintf("\tResetting..."); #if defined(HW_DOL) SYS_ResetSystem(SYS_HOTRESET,0,FALSE); #else - __reload (); + SYS_ResetSystem(SYS_RETURNTOMENU, 0, 0); #endif } - + VIDEO_WaitVSync(); udelay(20000); if(reload_timer > 0) reload_timer--; @@ -240,17 +272,20 @@ static void waitForReload(void) //just implement core for unrecoverable exceptions. void c_default_exceptionhandler(frame_context *pCtx) -{ +{ const u16 console_height = 680; const u16 console_width = 574; + lookup_xfb = VIDEO_GetNextFramebuffer(); + VIDEO_WaitVSync(); GX_AbortFrame(); VIDEO_SetFramebuffer(exception_xfb); + VIDEO_Flush(); __VIClearFramebuffer(exception_xfb, console_height * console_width * VI_DISPLAY_PIX_SZ, COLOR_BLACK); - __console_init(exception_xfb, 20, 20, console_height-40, console_width-40, 1280); + __console_init(exception_xfb, 16, 32, console_height-16, console_width-32, 1280); CON_EnableGecko(1, true); - kprintf("\n\n\n\tException (%s) occurred!\n", exception_name[pCtx->EXCPT_Number]); + kprintf("\tException (%s) occurred!\n", exception_name[pCtx->EXCPT_Number]); kprintf("\tGPR00 %08X GPR08 %08X GPR16 %08X GPR24 %08X\n",pCtx->GPR[0], pCtx->GPR[8], pCtx->GPR[16], pCtx->GPR[24]); kprintf("\tGPR01 %08X GPR09 %08X GPR17 %08X GPR25 %08X\n",pCtx->GPR[1], pCtx->GPR[9], pCtx->GPR[17], pCtx->GPR[25]); @@ -265,15 +300,16 @@ void c_default_exceptionhandler(frame_context *pCtx) _cpu_print_stack((void*)pCtx->SRR0,(void*)pCtx->LR,(void*)pCtx->GPR[1]); + kprintf("\n"); + if((pCtx->EXCPT_Number==EX_DSI) || (pCtx->EXCPT_Number==EX_FP)) { u32 i; u32 *pAdd = (u32*)pCtx->SRR0; - kprintf("\n\n\tCODE DUMP:\n"); + kprintf("\n\tCODE DUMP:\n"); for (i=0; i<12; i+=4) kprintf("\t%p: %08X %08X %08X %08X\n", &(pAdd[i]),pAdd[i], pAdd[i+1], pAdd[i+2], pAdd[i+3]); } waitForReload(); -} - +} \ No newline at end of file