Debugger window functionality in work.

This commit is contained in:
Matthew Budd 2020-09-04 06:37:22 -04:00
parent e688ebe23b
commit abf863a6a2
3 changed files with 332 additions and 16 deletions

View File

@ -99,29 +99,36 @@ ConsoleDebugger::ConsoleDebugger(QWidget *parent)
button = new QPushButton( tr("Run") );
grid->addWidget( button, 0, 0, Qt::AlignLeft );
connect( button, SIGNAL(clicked(void)), this, SLOT(debugRunCB(void)) );
button = new QPushButton( tr("Step Into") );
grid->addWidget( button, 0, 1, Qt::AlignLeft );
connect( button, SIGNAL(clicked(void)), this, SLOT(debugStepIntoCB(void)) );
button = new QPushButton( tr("Step Out") );
grid->addWidget( button, 1, 0, Qt::AlignLeft );
connect( button, SIGNAL(clicked(void)), this, SLOT(debugStepOutCB(void)) );
button = new QPushButton( tr("Step Over") );
grid->addWidget( button, 1, 1, Qt::AlignLeft );
connect( button, SIGNAL(clicked(void)), this, SLOT(debugStepOverCB(void)) );
button = new QPushButton( tr("Run Line") );
grid->addWidget( button, 2, 0, Qt::AlignLeft );
connect( button, SIGNAL(clicked(void)), this, SLOT(debugRunLineCB(void)) );
button = new QPushButton( tr("128 Lines") );
grid->addWidget( button, 2, 1, Qt::AlignLeft );
connect( button, SIGNAL(clicked(void)), this, SLOT(debugRunLine128CB(void)) );
button = new QPushButton( tr("Seek To:") );
grid->addWidget( button, 3, 0, Qt::AlignLeft );
//connect( button, SIGNAL(clicked(void)), this, SLOT(seekPCCB(void)) );
seekEntry = new QLineEdit();
seekEntry->setFont( font );
seekEntry->setMaxLength( 4 );
seekEntry->setInputMask( ">HHHH;0" );
seekEntry->setInputMask( ">HHHH;" );
seekEntry->setAlignment(Qt::AlignCenter);
seekEntry->setMaximumWidth( 6 * fontCharWidth );
grid->addWidget( seekEntry, 3, 1, Qt::AlignLeft );
@ -131,7 +138,7 @@ ConsoleDebugger::ConsoleDebugger(QWidget *parent)
pcEntry = new QLineEdit();
pcEntry->setFont( font );
pcEntry->setMaxLength( 4 );
pcEntry->setInputMask( ">HHHH;0" );
pcEntry->setInputMask( ">HHHH;" );
pcEntry->setAlignment(Qt::AlignCenter);
pcEntry->setMaximumWidth( 6 * fontCharWidth );
hbox->addWidget( lbl );
@ -140,13 +147,14 @@ ConsoleDebugger::ConsoleDebugger(QWidget *parent)
button = new QPushButton( tr("Seek PC") );
grid->addWidget( button, 4, 1, Qt::AlignLeft );
connect( button, SIGNAL(clicked(void)), this, SLOT(seekPCCB(void)) );
hbox = new QHBoxLayout();
lbl = new QLabel( tr("A:") );
regAEntry = new QLineEdit();
regAEntry->setFont( font );
regAEntry->setMaxLength( 2 );
regAEntry->setInputMask( ">HH;0" );
regAEntry->setInputMask( ">HH;" );
regAEntry->setAlignment(Qt::AlignCenter);
regAEntry->setMaximumWidth( 4 * fontCharWidth );
hbox->addWidget( lbl );
@ -155,7 +163,7 @@ ConsoleDebugger::ConsoleDebugger(QWidget *parent)
regXEntry = new QLineEdit();
regXEntry->setFont( font );
regXEntry->setMaxLength( 2 );
regXEntry->setInputMask( ">HH;0" );
regXEntry->setInputMask( ">HH;" );
regXEntry->setAlignment(Qt::AlignCenter);
regXEntry->setMaximumWidth( 4 * fontCharWidth );
hbox->addWidget( lbl );
@ -164,7 +172,7 @@ ConsoleDebugger::ConsoleDebugger(QWidget *parent)
regYEntry = new QLineEdit();
regYEntry->setFont( font );
regYEntry->setMaxLength( 2 );
regYEntry->setInputMask( ">HH;0" );
regYEntry->setInputMask( ">HH;" );
regYEntry->setAlignment(Qt::AlignCenter);
regYEntry->setMaximumWidth( 4 * fontCharWidth );
hbox->addWidget( lbl );
@ -250,21 +258,29 @@ ConsoleDebugger::ConsoleDebugger(QWidget *parent)
frame->setLayout( vbox );
frame->setFrameShape( QFrame::Box );
vbox = new QVBoxLayout();
vbox = new QVBoxLayout();
cpuCyclesLbl1 = new QLabel( tr("CPU Cycles:") );
cpuCyclesLbl2 = new QLabel( tr("(+0):") );
cpuInstrsLbl1 = new QLabel( tr("Instructions:") );
cpuInstrsLbl2 = new QLabel( tr("(+0):") );
brkCpuCycExd = new QCheckBox( tr("Break when Exceed") );
brkInstrsExd = new QCheckBox( tr("Break when Exceed") );
cpuCycExdVal = new QLineEdit( tr("0") );
instrExdVal = new QLineEdit( tr("0") );
hbox = new QHBoxLayout();
vbox->addLayout( hbox );
hbox->addWidget( cpuCyclesLbl1 );
hbox->addWidget( cpuCyclesLbl2 );
hbox = new QHBoxLayout();
cpuCyclesLbl = new QLabel( tr("CPU Cycles:") );
cpuInstrsLbl = new QLabel( tr("Instructions:") );
brkCpuCycExd = new QCheckBox( tr("Break when Exceed") );
brkInstrsExd = new QCheckBox( tr("Break when Exceed") );
cpuCycExdVal = new QLineEdit( tr("0") );
instrExdVal = new QLineEdit( tr("0") );
vbox->addWidget( cpuCyclesLbl );
vbox->addLayout( hbox );
hbox->addWidget( brkCpuCycExd );
hbox->addWidget( cpuCycExdVal, 1, Qt::AlignLeft );
hbox = new QHBoxLayout();
vbox->addWidget( cpuInstrsLbl );
vbox->addLayout( hbox );
hbox->addWidget( cpuInstrsLbl1 );
hbox->addWidget( cpuInstrsLbl2 );
hbox = new QHBoxLayout();
vbox->addLayout( hbox );
hbox->addWidget( brkInstrsExd );
hbox->addWidget( instrExdVal, 1, Qt::AlignLeft );
@ -318,6 +334,129 @@ void ConsoleDebugger::closeWindow(void)
deleteLater();
}
//----------------------------------------------------------------------------
void ConsoleDebugger::debugRunCB(void)
{
if (FCEUI_EmulationPaused())
{
setRegsFromEntry();
FCEUI_ToggleEmulationPause();
//DebuggerWasUpdated = false done in above function;
}
}
//----------------------------------------------------------------------------
void ConsoleDebugger::debugStepIntoCB(void)
{
if (FCEUI_EmulationPaused())
{
setRegsFromEntry();
}
FCEUI_Debugger().step = true;
FCEUI_SetEmulationPaused(0);
}
//----------------------------------------------------------------------------
void ConsoleDebugger::debugStepOutCB(void)
{
if (FCEUI_EmulationPaused() > 0)
{
DebuggerState &dbgstate = FCEUI_Debugger();
setRegsFromEntry();
if (dbgstate.stepout)
{
printf("Step Out is currently in process.\n");
return;
}
if (GetMem(X.PC) == 0x20)
{
dbgstate.jsrcount = 1;
}
else
{
dbgstate.jsrcount = 0;
}
dbgstate.stepout = 1;
FCEUI_SetEmulationPaused(0);
}
}
//----------------------------------------------------------------------------
void ConsoleDebugger::debugStepOverCB(void)
{
if (FCEUI_EmulationPaused())
{
setRegsFromEntry();
int tmp=X.PC;
uint8 opcode = GetMem(X.PC);
bool jsr = opcode==0x20;
bool call = jsr;
#ifdef BRK_3BYTE_HACK
//with this hack, treat BRK similar to JSR
if(opcode == 0x00)
{
call = true;
}
#endif
if (call)
{
if (watchpoint[64].flags)
{
printf("Step Over is currently in process.\n");
return;
}
watchpoint[64].address = (tmp+3);
watchpoint[64].flags = WP_E|WP_X;
}
else
{
FCEUI_Debugger().step = true;
}
FCEUI_SetEmulationPaused(0);
}
}
//----------------------------------------------------------------------------
void ConsoleDebugger::debugRunLineCB(void)
{
if (FCEUI_EmulationPaused())
{
setRegsFromEntry();
}
uint64 ts=timestampbase;
ts+=timestamp;
ts+=341/3;
//if (scanline == 240) vblankScanLines++;
//else vblankScanLines = 0;
FCEUI_Debugger().runline = true;
FCEUI_Debugger().runline_end_time=ts;
FCEUI_SetEmulationPaused(0);
}
//----------------------------------------------------------------------------
void ConsoleDebugger::debugRunLine128CB(void)
{
if (FCEUI_EmulationPaused())
{
setRegsFromEntry();
}
FCEUI_Debugger().runline = true;
{
uint64 ts=timestampbase;
ts+=timestamp;
ts+=128*341/3;
FCEUI_Debugger().runline_end_time=ts;
//if (scanline+128 >= 240 && scanline+128 <= 257) vblankScanLines = (scanline+128)-240;
//else vblankScanLines = 0;
}
FCEUI_SetEmulationPaused(0);
}
//----------------------------------------------------------------------------
void ConsoleDebugger::seekPCCB (void)
{
if (FCEUI_EmulationPaused())
{
setRegsFromEntry();
//updateAllDebugWindows();
}
windowUpdateReq = true;
//asmView->scrollToPC();
}
//----------------------------------------------------------------------------
int QAsmView::getAsmLineFromAddr(int addr)
{
int line = -1;
@ -607,10 +746,159 @@ void QAsmView::updateAssemblyView(void)
vbar->setMaximum( asmEntry.size() );
}
//----------------------------------------------------------------------------
void ConsoleDebugger::setRegsFromEntry(void)
{
std::string s;
long int i;
s = pcEntry->text().toStdString();
if ( s.size() > 0 )
{
i = strtol( s.c_str(), NULL, 16 );
}
else
{
i = 0;
}
X.PC = i;
//printf("Set PC: '%s' %04X\n", s.c_str(), X.PC );
s = regAEntry->text().toStdString();
if ( s.size() > 0 )
{
i = strtol( s.c_str(), NULL, 16 );
}
else
{
i = 0;
}
X.A = i;
//printf("Set A: '%s' %02X\n", s.c_str(), X.A );
s = regXEntry->text().toStdString();
if ( s.size() > 0 )
{
i = strtol( s.c_str(), NULL, 16 );
}
else
{
i = 0;
}
X.X = i;
//printf("Set X: '%s' %02X\n", s.c_str(), X.X );
s = regYEntry->text().toStdString();
if ( s.size() > 0 )
{
i = strtol( s.c_str(), NULL, 16 );
}
else
{
i = 0;
}
X.Y = i;
//printf("Set Y: '%s' %02X\n", s.c_str(), X.Y );
}
//----------------------------------------------------------------------------
void ConsoleDebugger::updateRegisterView(void)
{
int stackPtr;
char stmp[64];
char str[32], str2[32];
std::string stackLine;
sprintf( stmp, "%04X", X.PC );
pcEntry->setText( tr(stmp) );
sprintf( stmp, "%02X", X.A );
regAEntry->setText( tr(stmp) );
sprintf( stmp, "%02X", X.X );
regXEntry->setText( tr(stmp) );
sprintf( stmp, "%02X", X.Y );
regYEntry->setText( tr(stmp) );
N_chkbox->setChecked( (X.P & N_FLAG) ? true : false );
V_chkbox->setChecked( (X.P & V_FLAG) ? true : false );
U_chkbox->setChecked( (X.P & U_FLAG) ? true : false );
B_chkbox->setChecked( (X.P & B_FLAG) ? true : false );
D_chkbox->setChecked( (X.P & D_FLAG) ? true : false );
I_chkbox->setChecked( (X.P & I_FLAG) ? true : false );
Z_chkbox->setChecked( (X.P & Z_FLAG) ? true : false );
C_chkbox->setChecked( (X.P & C_FLAG) ? true : false );
stackPtr = X.S | 0x0100;
sprintf( stmp, "Stack: $%04X", stackPtr );
stackFrame->setTitle( tr(stmp) );
stackPtr++;
if ( stackPtr <= 0x01FF )
{
sprintf( stmp, "%02X", GetMem(stackPtr) );
stackLine.assign( stmp );
for (int i = 1; i < 128; i++)
{
//tmp = ((tmp+1)|0x0100)&0x01FF; //increment and fix pointer to $0100-$01FF range
stackPtr++;
if (stackPtr > 0x1FF)
break;
if ((i & 7) == 0)
sprintf( stmp, ",\r\n%02X", GetMem(stackPtr) );
else
sprintf( stmp, ",%02X", GetMem(stackPtr) );
stackLine.append( stmp );
}
}
stackText->setPlainText( tr(stackLine.c_str()) );
// update counters
int64 counter_value = timestampbase + (uint64)timestamp - total_cycles_base;
if (counter_value < 0) // sanity check
{
ResetDebugStatisticsCounters();
counter_value = 0;
}
sprintf( stmp, "CPU Cycles: %llu", counter_value);
cpuCyclesLbl1->setText( tr(stmp) );
counter_value = timestampbase + (uint64)timestamp - delta_cycles_base;
if (counter_value < 0) // sanity check
{
ResetDebugStatisticsCounters();
counter_value = 0;
}
sprintf(stmp, "(+%llu)", counter_value);
cpuCyclesLbl2->setText( tr(stmp) );
sprintf(stmp, "Instructions: %llu", total_instructions);
cpuInstrsLbl1->setText( tr(stmp) );
sprintf(stmp, "(+%llu)", delta_instructions);
cpuInstrsLbl2->setText( tr(stmp) );
}
//----------------------------------------------------------------------------
void ConsoleDebugger::updateWindowData(void)
{
asmView->updateAssemblyView();
asmView->scrollToPC();
updateRegisterView();
windowUpdateReq = false;
}
//----------------------------------------------------------------------------
@ -704,6 +992,14 @@ void QAsmView::setLine(int lineNum)
lineOffset = lineNum;
}
//----------------------------------------------------------------------------
void QAsmView::scrollToPC(void)
{
if ( asmPC != NULL )
{
lineOffset = asmPC->line;
}
}
//----------------------------------------------------------------------------
void QAsmView::calcFontData(void)
{
this->setFont(font);
@ -797,6 +1093,10 @@ void QAsmView::paintEvent(QPaintEvent *event)
maxLineOffset = 0;
}
if ( lineOffset < 0 )
{
lineOffset = 0;
}
if ( lineOffset > maxLineOffset )
{
lineOffset = maxLineOffset;

View File

@ -61,6 +61,7 @@ class QAsmView : public QWidget
void asmClear(void);
int getAsmLineFromAddr(int addr);
void setLine(int lineNum);
void scrollToPC(void);
protected:
void paintEvent(QPaintEvent *event);
void keyPressEvent(QKeyEvent *event);
@ -105,6 +106,7 @@ class ConsoleDebugger : public QDialog
~ConsoleDebugger(void);
void updateWindowData(void);
void updateRegisterView(void);
void breakPointNotify(int addr);
protected:
@ -143,19 +145,29 @@ class ConsoleDebugger : public QDialog
QLabel *spriteLbl;
QLabel *scanLineLbl;
QLabel *pixLbl;
QLabel *cpuCyclesLbl;
QLabel *cpuInstrsLbl;
QLabel *cpuCyclesLbl1;
QLabel *cpuCyclesLbl2;
QLabel *cpuInstrsLbl1;
QLabel *cpuInstrsLbl2;
QTimer *periodicTimer;
QFont font;
bool windowUpdateReq;
private:
void setRegsFromEntry(void);
public slots:
void closeWindow(void);
private slots:
void updatePeriodic(void);
void vbarChanged(int value);
void debugRunCB(void);
void debugStepIntoCB(void);
void debugStepOutCB(void);
void debugStepOverCB(void);
void debugRunLineCB(void);
void debugRunLine128CB(void);
void seekPCCB(void);
};

View File

@ -1769,6 +1769,10 @@ void QHexEdit::paintEvent(QPaintEvent *event)
maxLineOffset = 0;
}
if ( lineOffset < 0 )
{
lineOffset = 0;
}
if ( lineOffset > maxLineOffset )
{
lineOffset = maxLineOffset;