From d15623b7e66f98bf1d57db529833c321ac4f7b0c Mon Sep 17 00:00:00 2001 From: Matthew Budd Date: Wed, 27 May 2020 06:46:20 -0400 Subject: [PATCH] Added logic to seek the PC on the debug window every time a breakpoint is hit. --- src/drivers/sdl/debugger.cpp | 165 ++++++++++++++++++++++++++++------- 1 file changed, 132 insertions(+), 33 deletions(-) diff --git a/src/drivers/sdl/debugger.cpp b/src/drivers/sdl/debugger.cpp index 931cfd97..45b3d8a9 100644 --- a/src/drivers/sdl/debugger.cpp +++ b/src/drivers/sdl/debugger.cpp @@ -38,6 +38,7 @@ extern Config *g_config; +static int breakpoint_hit = 0; static void updateAllDebugWindows(void); //******************************************************************************************************* // Debugger Window @@ -189,6 +190,8 @@ struct debuggerWin_t int get_bpList_selrow(void); int getAsmLineFromAddr(int addr); int scrollAsmLine(int line); + int seekAsmPC(void); + int seekAsmAddr(int addr); }; static std::list debuggerWinList; @@ -205,22 +208,88 @@ void debuggerWin_t::asmClear(void) int debuggerWin_t::getAsmLineFromAddr(int addr) { int line = -1; + int incr, nextLine; + int run = 1; if ( asmEntry.size() <= 0 ) { return -1; } + incr = asmEntry.size() / 2; - line = 0; - - for (size_t i=0; iaddr ) { - if ( asmEntry[i]->addr >= addr ) + return 0; + } + else if ( addr > asmEntry[ asmEntry.size() - 1 ]->addr ) + { + return asmEntry.size() - 1; + } + + if ( incr < 1 ) incr = 1; + + nextLine = line = incr; + + // algorithm to efficiently find line from address. Starts in middle of list and + // keeps dividing the list in 2 until it arrives at an answer. + while ( run ) + { + //printf("incr:%i line:%i addr:%04X delta:%i\n", incr, line, asmEntry[line]->addr, addr - asmEntry[line]->addr); + + if ( incr == 1 ) { - line = i; break; + if ( asmEntry[line]->addr < addr ) + { + nextLine = line + 1; + if ( asmEntry[line]->addr > nextLine ) + { + break; + } + line = nextLine; + } + else if ( asmEntry[line]->addr > addr ) + { + nextLine = line - 1; + if ( asmEntry[line]->addr < nextLine ) + { + break; + } + line = nextLine; + } + else + { + run = 0; break; + } + } + else + { + incr = incr / 2; + if ( incr < 1 ) incr = 1; + + if ( asmEntry[line]->addr < addr ) + { + nextLine = line + incr; + } + else if ( asmEntry[line]->addr > addr ) + { + nextLine = line - incr; + } + else + { + run = 0; break; + } + line = nextLine; } } + //for (size_t i=0; iaddr >= addr ) + // { + // line = i; break; + // } + //} + return line; } @@ -228,6 +297,10 @@ int debuggerWin_t::scrollAsmLine(int line) { GtkTextIter iter; + if ( line < 0 ) + { + return -1; + } gtk_text_buffer_get_iter_at_line( textbuf, &iter, line ); gtk_text_view_scroll_to_iter ( textview, &iter, 0.0, 1, 0.0, 0.50 ); gtk_text_buffer_place_cursor( textbuf, &iter ); @@ -235,6 +308,35 @@ int debuggerWin_t::scrollAsmLine(int line) return 0; } +int debuggerWin_t::seekAsmPC(void) +{ + int line; + + if ( asmPC == NULL ) + { + line = getAsmLineFromAddr( X.PC ); + } + else + { + line = asmPC->line; + } + + scrollAsmLine( line ); + + return 0; +} + +int debuggerWin_t::seekAsmAddr( int addr ) +{ + int line; + + line = getAsmLineFromAddr( addr ); + + scrollAsmLine( line ); + + return 0; +} + int debuggerWin_t::get_bpList_selrow(void) { int retval = -1, numListRows; @@ -506,9 +608,9 @@ void debuggerWin_t::updateAssemblyView(void) { break; } - if ( starting_address <= 0x8000 ) + if ( starting_address < 0x8000 ) { - //starting_address = 0x8000; + starting_address = start_address_lp; break; } start_address_lp = starting_address; @@ -1151,42 +1253,19 @@ static void debugRunLine128CB (GtkButton * button, debuggerWin_t * dw) static void seekPCCB (GtkButton * button, debuggerWin_t * dw) { - int line; - //const char *txt; - - //txt = gtk_entry_get_text( GTK_ENTRY(dw->seektoEntry) ); - - //addr = strtol( txt, NULL, 16 ); - - if ( dw->asmPC == NULL ) - { - line = dw->getAsmLineFromAddr( X.PC ); - } - else - { - line = dw->asmPC->line; - } - - dw->scrollAsmLine( line ); - - //printf("Seek: 0x%04X Line:%i\n", addr, line); + dw->seekAsmPC(); } static void seekToCB (GtkButton * button, debuggerWin_t * dw) { - int addr, line; + int addr; const char *txt; txt = gtk_entry_get_text( GTK_ENTRY(dw->seektoEntry) ); - //addr = strtol( txt, NULL, 16 ); addr = offsetStringToInt( BT_C, txt ); - line = dw->getAsmLineFromAddr( addr ); - - dw->scrollAsmLine( line ); - - //printf("Seek: 0x%04X Line:%i\n", addr, line); + dw->seekAsmAddr(addr); } static void @@ -1369,6 +1448,16 @@ static void updateAllDebugWindows(void) } } +static void seekPC_AllDebugWindows(void) +{ + std::list < debuggerWin_t * >::iterator it; + + for (it = debuggerWinList.begin (); it != debuggerWinList.end (); it++) + { + (*it)->seekAsmPC(); + } +} + static void winDebuggerLoopStep(void) { FCEUD_UpdateInput(); @@ -1377,6 +1466,12 @@ static void winDebuggerLoopStep(void) { gtk_main_iteration_do(FALSE); } + + if ( breakpoint_hit ) + { + seekPC_AllDebugWindows(); + breakpoint_hit = 0; + } } //this code enters the debugger when a breakpoint was hit @@ -1384,8 +1479,12 @@ void FCEUD_DebugBreakpoint(int bp_num) { //printf("Breakpoint Hit: %i \n", bp_num); + breakpoint_hit = 1; + updateAllDebugWindows(); + winDebuggerLoopStep(); + while(FCEUI_EmulationPaused() && !FCEUI_EmulationFrameStepped()) { usleep(50000);