# HG changeset patch # User nkeynes # Date 1200564697 0 # Node ID 7b9612fd2395696ee699fb641acbdd18094c7145 # Parent 4db6a084ca3cef4fcde2a92aa992ab338227fd49 Add flag to skip breakpoints when it's the very first instruction of a run (ie, so executing dreamcast_run() when the current pc is a breakpoint doesn't just return immediately) --- a/src/sh4/sh4.c Wed Jan 16 09:39:16 2008 +0000 +++ b/src/sh4/sh4.c Thu Jan 17 10:11:37 2008 +0000 @@ -42,13 +42,14 @@ uint32_t sh4_xlat_run_slice( uint32_t ); struct dreamcast_module sh4_module = { "SH4", sh4_init, sh4_reset, - NULL, sh4_run_slice, sh4_stop, + sh4_start, sh4_run_slice, sh4_stop, sh4_save_state, sh4_load_state }; struct sh4_registers sh4r; struct breakpoint_struct sh4_breakpoints[MAX_BREAKPOINTS]; int sh4_breakpoint_count = 0; sh4ptr_t sh4_main_ram; +gboolean sh4_starting = FALSE; static gboolean sh4_use_translator = FALSE; struct sh4_icache_struct sh4_icache = { NULL, -1, -1, 0 }; @@ -80,6 +81,11 @@ sh4_reset(); } +void sh4_start(void) +{ + sh4_starting = TRUE; +} + void sh4_reset(void) { if( sh4_use_translator ) { --- a/src/sh4/sh4core.h Wed Jan 16 09:39:16 2008 +0000 +++ b/src/sh4/sh4core.h Thu Jan 17 10:11:37 2008 +0000 @@ -34,6 +34,7 @@ extern struct breakpoint_struct sh4_breakpoints[MAX_BREAKPOINTS]; extern int sh4_breakpoint_count; extern sh4ptr_t sh4_main_ram; +extern gboolean sh4_starting; /** * Cached direct pointer to the current instruction page. If AT is on, this --- a/src/sh4/sh4trans.c Wed Jan 16 09:39:16 2008 +0000 +++ b/src/sh4/sh4trans.c Thu Jan 17 10:11:37 2008 +0000 @@ -36,7 +36,6 @@ /** * Execute a timeslice using translated code only (ie translate/execute loop) - * Note this version does not support breakpoints */ uint32_t sh4_xlat_run_slice( uint32_t nanosecs ) { @@ -95,6 +94,7 @@ } xlat_running = FALSE; + sh4_starting = FALSE; if( sh4r.sh4_state != SH4_STATE_STANDBY ) { TMU_run_slice( nanosecs ); @@ -222,6 +222,14 @@ longjmp(xlat_jmp_buf, exit_code); } +void sh4_translate_breakpoint_hit(uint32_t pc) +{ + if( sh4_starting && sh4r.slice_cycle == 0 && pc == sh4r.pc ) { + return; + } + sh4_translate_exit( XLAT_EXIT_BREAKPOINT ); +} + /** * Exit the current block at the end of the current instruction, flush the * translation cache (completely) and return control to sh4_xlat_run_slice. --- a/src/sh4/sh4trans.h Wed Jan 16 09:39:16 2008 +0000 +++ b/src/sh4/sh4trans.h Thu Jan 17 10:11:37 2008 +0000 @@ -112,3 +112,10 @@ * the specified exit code (one of the XLAT_EXIT_* values). */ void sh4_translate_exit( int exit_code ); + +/** + * Support function called from the translator when a breakpoint is hit. + * Either returns immediately (to skip the breakpoint), or aborts the current + * cycle and never returns. + */ +void sh4_translate_breakpoint_hit( sh4vma_t pc ); --- a/src/sh4/sh4x86.c Wed Jan 16 09:39:16 2008 +0000 +++ b/src/sh4/sh4x86.c Thu Jan 17 10:11:37 2008 +0000 @@ -364,8 +364,8 @@ */ void sh4_translate_emit_breakpoint( sh4vma_t pc ) { - load_imm32( R_EAX, XLAT_EXIT_BREAKPOINT ); - call_func1( sh4_translate_exit, R_EAX ); + load_imm32( R_EAX, pc ); + call_func1( sh4_translate_breakpoint_hit, R_EAX ); } /** --- a/src/sh4/sh4x86.in Wed Jan 16 09:39:16 2008 +0000 +++ b/src/sh4/sh4x86.in Thu Jan 17 10:11:37 2008 +0000 @@ -364,8 +364,8 @@ */ void sh4_translate_emit_breakpoint( sh4vma_t pc ) { - load_imm32( R_EAX, XLAT_EXIT_BREAKPOINT ); - call_func1( sh4_translate_exit, R_EAX ); + load_imm32( R_EAX, pc ); + call_func1( sh4_translate_breakpoint_hit, R_EAX ); } /**