Added logic to seek the PC on the debug window every time a breakpoint is hit.

This commit is contained in:
Matthew Budd 2020-05-27 06:46:20 -04:00
parent 27e326ce90
commit d15623b7e6
1 changed files with 132 additions and 33 deletions

View File

@ -38,6 +38,7 @@
extern Config *g_config; extern Config *g_config;
static int breakpoint_hit = 0;
static void updateAllDebugWindows(void); static void updateAllDebugWindows(void);
//******************************************************************************************************* //*******************************************************************************************************
// Debugger Window // Debugger Window
@ -189,6 +190,8 @@ struct debuggerWin_t
int get_bpList_selrow(void); int get_bpList_selrow(void);
int getAsmLineFromAddr(int addr); int getAsmLineFromAddr(int addr);
int scrollAsmLine(int line); int scrollAsmLine(int line);
int seekAsmPC(void);
int seekAsmAddr(int addr);
}; };
static std::list <debuggerWin_t*> debuggerWinList; static std::list <debuggerWin_t*> debuggerWinList;
@ -205,22 +208,88 @@ void debuggerWin_t::asmClear(void)
int debuggerWin_t::getAsmLineFromAddr(int addr) int debuggerWin_t::getAsmLineFromAddr(int addr)
{ {
int line = -1; int line = -1;
int incr, nextLine;
int run = 1;
if ( asmEntry.size() <= 0 ) if ( asmEntry.size() <= 0 )
{ {
return -1; return -1;
} }
incr = asmEntry.size() / 2;
line = 0; if ( addr < asmEntry[0]->addr )
for (size_t i=0; i<asmEntry.size(); i++)
{ {
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; i<asmEntry.size(); i++)
//{
// if ( asmEntry[i]->addr >= addr )
// {
// line = i; break;
// }
//}
return line; return line;
} }
@ -228,6 +297,10 @@ int debuggerWin_t::scrollAsmLine(int line)
{ {
GtkTextIter iter; GtkTextIter iter;
if ( line < 0 )
{
return -1;
}
gtk_text_buffer_get_iter_at_line( textbuf, &iter, line ); 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_view_scroll_to_iter ( textview, &iter, 0.0, 1, 0.0, 0.50 );
gtk_text_buffer_place_cursor( textbuf, &iter ); gtk_text_buffer_place_cursor( textbuf, &iter );
@ -235,6 +308,35 @@ int debuggerWin_t::scrollAsmLine(int line)
return 0; 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 debuggerWin_t::get_bpList_selrow(void)
{ {
int retval = -1, numListRows; int retval = -1, numListRows;
@ -506,9 +608,9 @@ void debuggerWin_t::updateAssemblyView(void)
{ {
break; break;
} }
if ( starting_address <= 0x8000 ) if ( starting_address < 0x8000 )
{ {
//starting_address = 0x8000; starting_address = start_address_lp;
break; break;
} }
start_address_lp = starting_address; 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) static void seekPCCB (GtkButton * button, debuggerWin_t * dw)
{ {
int line; dw->seekAsmPC();
//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);
} }
static void seekToCB (GtkButton * button, debuggerWin_t * dw) static void seekToCB (GtkButton * button, debuggerWin_t * dw)
{ {
int addr, line; int addr;
const char *txt; const char *txt;
txt = gtk_entry_get_text( GTK_ENTRY(dw->seektoEntry) ); txt = gtk_entry_get_text( GTK_ENTRY(dw->seektoEntry) );
//addr = strtol( txt, NULL, 16 );
addr = offsetStringToInt( BT_C, txt ); addr = offsetStringToInt( BT_C, txt );
line = dw->getAsmLineFromAddr( addr ); dw->seekAsmAddr(addr);
dw->scrollAsmLine( line );
//printf("Seek: 0x%04X Line:%i\n", addr, line);
} }
static void 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) static void winDebuggerLoopStep(void)
{ {
FCEUD_UpdateInput(); FCEUD_UpdateInput();
@ -1377,6 +1466,12 @@ static void winDebuggerLoopStep(void)
{ {
gtk_main_iteration_do(FALSE); gtk_main_iteration_do(FALSE);
} }
if ( breakpoint_hit )
{
seekPC_AllDebugWindows();
breakpoint_hit = 0;
}
} }
//this code enters the debugger when a breakpoint was hit //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); //printf("Breakpoint Hit: %i \n", bp_num);
breakpoint_hit = 1;
updateAllDebugWindows(); updateAllDebugWindows();
winDebuggerLoopStep();
while(FCEUI_EmulationPaused() && !FCEUI_EmulationFrameStepped()) while(FCEUI_EmulationPaused() && !FCEUI_EmulationFrameStepped())
{ {
usleep(50000); usleep(50000);