--- a/src/sh4/sh4trans.c Thu Jan 10 08:28:37 2008 +0000 +++ b/src/sh4/sh4trans.c Mon Jan 14 10:23:49 2008 +0000 @@ -42,7 +42,19 @@ } } - int jmp = setjmp(xlat_jmp_buf); + switch( setjmp(xlat_jmp_buf) ) { + case XLAT_EXIT_BREAKPOINT: + sh4_clear_breakpoint( sh4r.pc, BREAK_ONESHOT ); + /* fallthrough */ + case XLAT_EXIT_HALT: + if( sh4r.sh4_state != SH4_STATE_STANDBY ) { + TMU_run_slice( sh4r.slice_cycle ); + SCIF_run_slice( sh4r.slice_cycle ); + dreamcast_stop(); + return sh4r.slice_cycle; + } + break; + } void * (*code)() = NULL; while( sh4r.slice_cycle < nanosecs ) { @@ -94,7 +106,7 @@ { sh4addr_t pc = start; sh4addr_t lastpc = (pc&0xFFFFF000)+0x1000; - int done; + int done, i; xlat_cache_block_t block = xlat_start_block( start ); xlat_output = (uint8_t *)block->code; xlat_recovery_posn = 0; @@ -102,6 +114,13 @@ sh4_translate_begin_block(pc); do { + /* check for breakpoints at this pc */ + for( i=0; icode; block = xlat_extend_block( xlat_output - oldstart + MAX_INSTRUCTION_SIZE ); @@ -139,32 +158,6 @@ } /** - * Translate a linear basic block to a temporary buffer, execute it, and return - * the result of the execution. The translation is discarded. - */ -void *sh4_translate_and_run( sh4addr_t start ) -{ - unsigned char buf[65536]; - - sh4addr_t pc = start; - int done; - xlat_output = buf; - uint8_t *eob = xlat_output + sizeof(buf); - - sh4_translate_begin_block(pc); - - while( (done = sh4_translate_instruction( pc )) == 0 ) { - assert( (eob - xlat_output) >= MAX_INSTRUCTION_SIZE ); - pc += 2; - } - pc+=2; - sh4_translate_end_block(pc); - - void * (*code)() = (void *)buf; - return code(); -} - -/** * "Execute" the supplied recovery record. Currently this only updates * sh4r.pc and sh4r.slice_cycle according to the currently executing * instruction. In future this may be more sophisticated (ie will @@ -179,10 +172,8 @@ void sh4_translate_unwind_stack( gboolean abort_after, unwind_thunk_t thunk ) { void *pc = xlat_get_native_pc(); - if( pc == NULL ) { - // This should never happen - indicative of a bug somewhere. - FATAL("Attempted to unwind stack, but translator is not running or stack is corrupt"); - } + + assert( pc != NULL ); void *code = xlat_get_code( sh4r.pc ); xlat_recovery_record_t recover = xlat_get_recovery(code, pc, TRUE); if( recover != NULL ) { @@ -193,9 +184,24 @@ thunk(); } // finally longjmp back into sh4_xlat_run_slice - longjmp(xlat_jmp_buf, 1); + longjmp(xlat_jmp_buf, XLAT_EXIT_CONTINUE); } +void sh4_translate_exit( int exit_code ) +{ + void *pc = xlat_get_native_pc(); + assert(pc != NULL); + + void *code = xlat_get_code( sh4r.pc ); + xlat_recovery_record_t recover = xlat_get_recovery(code, pc, TRUE); + if( recover != NULL ) { + // Can be null if there is no recovery necessary + sh4_translate_run_recovery(recover); + } + // finally longjmp back into sh4_xlat_run_slice + longjmp(xlat_jmp_buf, exit_code); +} + /** * Exit the current block at the end of the current instruction, flush the * translation cache (completely) and return control to sh4_xlat_run_slice. @@ -210,17 +216,15 @@ void sh4_translate_flush_cache() { void *pc = xlat_get_native_pc(); - if( pc == NULL ) { - // This should never happen - indicative of a bug somewhere. - FATAL("Attempted to unwind stack, but translator is not running or stack is corrupt"); - } + assert( pc != NULL ); + void *code = xlat_get_code( sh4r.pc ); xlat_recovery_record_t recover = xlat_get_recovery(code, pc, TRUE); if( recover != NULL ) { // Can be null if there is no recovery necessary sh4_translate_run_recovery(recover); xlat_flush_cache(); - longjmp(xlat_jmp_buf, 1); + longjmp(xlat_jmp_buf, XLAT_EXIT_CONTINUE); } else { xlat_flush_cache(); return; @@ -232,6 +236,10 @@ void *result = NULL; if( !IS_IN_ICACHE(vma) ) { + if( vma > 0xFFFFFF00 ) { + // lxdream hook + return NULL; + } if( !mmu_update_icache(sh4r.pc) ) { // fault - off to the fault handler if( !mmu_update_icache(sh4r.pc) ) {