/* Throw exceptions */ void exception_throw(register int x, register const char *file, register int line, register const char *function) { /* Let's assure we won't throw zero, shall we? */ if(x) { /* First let's backup our data and get a new handler */ exception_handler handler; handler = exception_add_handler(EXCEPTION_THROWN, (bool *)&handler, file, line, function); /* Are we inside any try block? */ if(exception_last_handler()) { /* Check it's state */ if(handler->status == EXCEPTION_RETURN) { /* If we've returned, act as there were no exception at all, deleting it */ exception_pop_handler(); /* Make sure we're error-free */ exception_clear(); } else { /* We have to set the exception itself */ exception_set(x); /* We can go back to check newer handlers, if any */ exception_save_zombies(); /* And we have to return to the previous handler */ exception_return_home(exception_get_handler(EXCEPTION_LIVING)); }; } else { /* Ooops! Called throw outside try! */ (*exception_panic)(EXCEPTION_UNCAUGHT); }; }; };
void ubc_init (void) { exception_table_entry new_entry; /* STAGE: Clear both UBC channels. */ *UBC_R_BBRA = *UBC_R_BBRB = 0; *UBC_R_BAMRA = *UBC_R_BAMRB = UBC_BAMR_NOASID; /* STAGE: Initialize the global UBC configuration. */ *UBC_R_BRCR = UBC_BRCR_UBDE | UBC_BRCR_PCBA | UBC_BRCR_PCBB; /* STAGE: Ensure interrupts are being directed properly. */ dbr_set (ubc_handler_lowlevel); /* STAGE: Don't allow multiple hooks on the exception. */ if (inited) return; /* STAGE: Install the UBC clearing handler. */ new_entry.type = EXP_TYPE_GEN; new_entry.code = EXP_CODE_UBC; new_entry.handler = ubc_handler; inited = exception_add_handler (&new_entry, &old_ubc_handler); }
/* Handler opener */ void exception_init(register bool *flag) { /* At the beginning of a try block, we clean the exception */ exception_clear(); /* And create a new handler */ exception_add_handler(EXCEPTION_TRYING, flag, NULL, 0, NULL); /* We have here to start the loop flag for the handler */ *flag = true; };