From d3b779a4e3cd5042e3157686a610a74472802e42 Mon Sep 17 00:00:00 2001 From: Matthew Budd Date: Sun, 15 Nov 2020 11:57:43 -0500 Subject: [PATCH 1/4] Added a run to cursor debugger feature to Qt debugger window assembly view context menu. --- src/drivers/Qt/ConsoleDebugger.cpp | 28 +++++++++++++++++++++++++++- src/drivers/Qt/ConsoleDebugger.h | 1 + 2 files changed, 28 insertions(+), 1 deletion(-) diff --git a/src/drivers/Qt/ConsoleDebugger.cpp b/src/drivers/Qt/ConsoleDebugger.cpp index 46175299..83387b4c 100644 --- a/src/drivers/Qt/ConsoleDebugger.cpp +++ b/src/drivers/Qt/ConsoleDebugger.cpp @@ -1663,6 +1663,14 @@ void ConsoleDebugger::resetCountersCB (void) updateRegisterView(); } //---------------------------------------------------------------------------- +void ConsoleDebugger::asmViewCtxMenuRunToCursor(void) +{ + watchpoint[64].address = asmView->getCtxMenuAddr(); + watchpoint[64].flags = WP_E|WP_X; + + FCEUI_SetEmulationPaused(0); +} +//---------------------------------------------------------------------------- void ConsoleDebugger::asmViewCtxMenuAddBP(void) { watchpointinfo wp; @@ -2958,7 +2966,12 @@ void QAsmView::scrollToPC(void) { if ( asmPC != NULL ) { - lineOffset = asmPC->line; + lineOffset = asmPC->line - (viewLines / 2); + + if ( lineOffset < 0 ) + { + lineOffset = 0; + } vbar->setValue( lineOffset ); } } @@ -3579,6 +3592,7 @@ void QAsmView::contextMenuEvent(QContextMenuEvent *event) QAction *act; QMenu menu(this); QPoint c = convPixToCursor( event->pos() ); + bool enableRunToCursor = false; line = lineOffset + c.y(); @@ -3591,10 +3605,22 @@ void QAsmView::contextMenuEvent(QContextMenuEvent *event) if ( selAddrValue < 0 ) { ctxMenuAddr = addr = asmEntry[line]->addr; + + enableRunToCursor = true; } else { ctxMenuAddr = addr = selAddrValue; + + enableRunToCursor = (selAddrValue == asmEntry[line]->addr); + } + + if ( enableRunToCursor ) + { + act = new QAction(tr("Run To Cursor"), &menu); + menu.addAction(act); + act->setShortcut( QKeySequence(tr("Ctrl+F10"))); + connect( act, SIGNAL(triggered(void)), parent, SLOT(asmViewCtxMenuRunToCursor(void)) ); } act = new QAction(tr("Add Breakpoint"), &menu); diff --git a/src/drivers/Qt/ConsoleDebugger.h b/src/drivers/Qt/ConsoleDebugger.h index e35e1c03..6e206159 100644 --- a/src/drivers/Qt/ConsoleDebugger.h +++ b/src/drivers/Qt/ConsoleDebugger.h @@ -291,6 +291,7 @@ class ConsoleDebugger : public QDialog void asmViewCtxMenuAddBM(void); void asmViewCtxMenuAddSym(void); void asmViewCtxMenuOpenHexEdit(void); + void asmViewCtxMenuRunToCursor(void); private slots: void updatePeriodic(void); void hbarChanged(int value); From 8629e1927310ea7417f6279f0eed306796ecbc67 Mon Sep 17 00:00:00 2001 From: Matthew Budd Date: Sun, 15 Nov 2020 14:30:38 -0500 Subject: [PATCH 2/4] Added PC line placement options for Qt debugger assembly viewer. Old behavior was to always to display program counter line at the top of the viewer when a breakpoint is hit. Now that behavior is selectable to be top, upper-mid, center, lower-mid, bottom, or custom line offset. --- src/drivers/Qt/ConsoleDebugger.cpp | 180 ++++++++++++++++++++++++++++- src/drivers/Qt/ConsoleDebugger.h | 10 ++ src/drivers/Qt/config.cpp | 6 +- 3 files changed, 192 insertions(+), 4 deletions(-) diff --git a/src/drivers/Qt/ConsoleDebugger.cpp b/src/drivers/Qt/ConsoleDebugger.cpp index 83387b4c..c5c6f868 100644 --- a/src/drivers/Qt/ConsoleDebugger.cpp +++ b/src/drivers/Qt/ConsoleDebugger.cpp @@ -66,7 +66,8 @@ ConsoleDebugger::ConsoleDebugger(QWidget *parent) QFrame *frame; QLabel *lbl; QMenuBar *menuBar; - QMenu *debugMenu; + QMenu *debugMenu, *optMenu, *subMenu; + QActionGroup *actGroup; QAction *act; float fontCharWidth; QTreeWidgetItem * item; @@ -144,6 +145,71 @@ ConsoleDebugger::ConsoleDebugger(QWidget *parent) debugMenu->addAction(act); + // Options + optMenu = menuBar->addMenu(tr("Options")); + + // Options -> PC Position + subMenu = optMenu->addMenu(tr("PC Line Positioning")); + actGroup = new QActionGroup(this); + + actGroup->setExclusive(true); + + g_config->getOption( "SDL.DebuggerPCPlacement", &opt ); + + // Options -> PC Position -> Top Line + act = new QAction(tr("Top Line"), this); + act->setStatusTip(tr("Top Line")); + act->setCheckable(true); + act->setChecked( opt == 0 ); + connect( act, SIGNAL(triggered()), this, SLOT(pcSetPlaceTop(void)) ); + actGroup->addAction(act); + subMenu->addAction(act); + + // Options -> PC Position -> Upper Mid-Line + act = new QAction(tr("Upper Mid-Line"), this); + act->setStatusTip(tr("Upper Mid-Line")); + act->setCheckable(true); + act->setChecked( opt == 1 ); + connect( act, SIGNAL(triggered()), this, SLOT(pcSetPlaceUpperMid(void)) ); + actGroup->addAction(act); + subMenu->addAction(act); + + // Options -> PC Position -> Center Line + act = new QAction(tr("Center Line"), this); + act->setStatusTip(tr("Center Line")); + act->setCheckable(true); + act->setChecked( opt == 2 ); + connect( act, SIGNAL(triggered()), this, SLOT(pcSetPlaceCenter(void)) ); + actGroup->addAction(act); + subMenu->addAction(act); + + // Options -> PC Position -> Lower Mid-Line + act = new QAction(tr("Lower Mid-Line"), this); + act->setStatusTip(tr("Lower Mid-Line")); + act->setCheckable(true); + act->setChecked( opt == 3 ); + connect( act, SIGNAL(triggered()), this, SLOT(pcSetPlaceLowerMid(void)) ); + actGroup->addAction(act); + subMenu->addAction(act); + + // Options -> PC Position -> Bottom + act = new QAction(tr("Bottom Line"), this); + act->setStatusTip(tr("Bottom Line")); + act->setCheckable(true); + act->setChecked( opt == 4 ); + connect( act, SIGNAL(triggered()), this, SLOT(pcSetPlaceBottom(void)) ); + actGroup->addAction(act); + subMenu->addAction(act); + + // Options -> PC Position -> Custom Line + act = new QAction(tr("Custom Line Offset"), this); + act->setStatusTip(tr("Custom Line Offset")); + act->setChecked( opt == 5 ); + act->setCheckable(true); + connect( act, SIGNAL(triggered()), this, SLOT(pcSetPlaceCustom(void)) ); + actGroup->addAction(act); + subMenu->addAction(act); + //----------------------------------------------------------------------- // Menu End //----------------------------------------------------------------------- @@ -1512,6 +1578,57 @@ void ConsoleDebugger::reloadSymbolsCB(void) fceuWrapperUnLock(); } //---------------------------------------------------------------------------- +void ConsoleDebugger::pcSetPlaceTop(void) +{ + asmView->setPC_placement( 0 ); +} +//---------------------------------------------------------------------------- +void ConsoleDebugger::pcSetPlaceUpperMid(void) +{ + asmView->setPC_placement( 1 ); +} +//---------------------------------------------------------------------------- +void ConsoleDebugger::pcSetPlaceCenter(void) +{ + asmView->setPC_placement( 2 ); +} +//---------------------------------------------------------------------------- +void ConsoleDebugger::pcSetPlaceLowerMid(void) +{ + asmView->setPC_placement( 3 ); +} +//---------------------------------------------------------------------------- +void ConsoleDebugger::pcSetPlaceBottom(void) +{ + asmView->setPC_placement( 4 ); +} +//---------------------------------------------------------------------------- +void ConsoleDebugger::pcSetPlaceCustom(void) +{ + int ret, ofs; + QInputDialog dialog(this); + + g_config->getOption("SDL.DebuggerPCLineOffset" , &ofs ); + + dialog.setWindowTitle( tr("PC Line Offset") ); + dialog.setLabelText( tr("Enter a line offset from 0 to 100.") ); + dialog.setOkButtonText( tr("Ok") ); + dialog.setInputMode( QInputDialog::IntInput ); + dialog.setIntRange( 0, 100 ); + dialog.setIntValue( ofs ); + + dialog.show(); + ret = dialog.exec(); + + if ( QDialog::Accepted == ret ) + { + ofs = dialog.intValue(); + + asmView->setPC_placement( 5, ofs ); + } + +} +//---------------------------------------------------------------------------- void ConsoleDebugger::debugRunCB(void) { if (FCEUI_EmulationPaused()) @@ -1732,6 +1849,20 @@ void ConsoleDebugger::asmViewCtxMenuAddSym(void) openDebugSymbolEditWindow( asmView->getCtxMenuAddr() ); } //---------------------------------------------------------------------------- +void QAsmView::setPC_placement( int mode, int ofs ) +{ + pcLinePlacement = mode; + + if ( mode == 5 ) + { + pcLineOffset = ofs; + } + + g_config->setOption("SDL.DebuggerPCPlacement" , pcLinePlacement); + g_config->setOption("SDL.DebuggerPCLineOffset" , pcLineOffset ); + g_config->save(); +} +//---------------------------------------------------------------------------- int QAsmView::getAsmLineFromAddr(int addr) { int line = -1; @@ -2912,6 +3043,11 @@ QAsmView::QAsmView(QWidget *parent) txtHlgtEndChar = -1; txtHlgtEndLine = -1; + pcLinePlacement = 0; + pcLineOffset = 0; + + g_config->getOption( "SDL.DebuggerPCPlacement" , &pcLinePlacement ); + g_config->getOption( "SDL.DebuggerPCLineOffset", &pcLineOffset ); selAddrLine = -1; selAddrChar = 0; @@ -2966,7 +3102,47 @@ void QAsmView::scrollToPC(void) { if ( asmPC != NULL ) { - lineOffset = asmPC->line - (viewLines / 2); + int ofs = 0; + int maxOfs = (viewLines-3); + + if ( maxOfs < 0 ) + { + maxOfs = 0; + } + + switch ( pcLinePlacement ) + { + default: + case 0: + ofs = 0; + break; + case 1: + ofs = (viewLines / 4); + break; + case 2: + ofs = (viewLines / 2); + break; + case 3: + ofs = (viewLines*3) / 4; + break; + case 4: + ofs = maxOfs; + break; + case 5: + ofs = pcLineOffset; + + if ( ofs < 0 ) + { + ofs = 0; + } + else if ( ofs > maxOfs ) + { + ofs = maxOfs; + } + break; + } + + lineOffset = asmPC->line - ofs; if ( lineOffset < 0 ) { diff --git a/src/drivers/Qt/ConsoleDebugger.h b/src/drivers/Qt/ConsoleDebugger.h index 6e206159..d6b87b3c 100644 --- a/src/drivers/Qt/ConsoleDebugger.h +++ b/src/drivers/Qt/ConsoleDebugger.h @@ -112,6 +112,7 @@ class QAsmView : public QWidget void setSymbolDebugEnable( bool value ); void setRegisterNameEnable( bool value ); int getCtxMenuAddr(void){ return ctxMenuAddr; }; + void setPC_placement( int mode, int ofs = 0 ); protected: void paintEvent(QPaintEvent *event); void keyPressEvent(QKeyEvent *event); @@ -154,6 +155,8 @@ class QAsmView : public QWidget int pxLineXScroll; int cursorPosX; int cursorPosY; + int pcLinePlacement; + int pcLineOffset; int selAddrLine; int selAddrChar; @@ -178,6 +181,7 @@ class QAsmView : public QWidget bool symbolicDebugEnable; bool registerNameEnable; bool mouseLeftBtnDown; + }; class DebuggerStackDisplay : public QPlainTextEdit @@ -326,6 +330,12 @@ class ConsoleDebugger : public QDialog void cpuCycleThresChanged(const QString &txt); void instructionsThresChanged(const QString &txt); void selBmAddrChanged(const QString &txt); + void pcSetPlaceTop(void); + void pcSetPlaceUpperMid(void); + void pcSetPlaceCenter(void); + void pcSetPlaceLowerMid(void); + void pcSetPlaceBottom(void); + void pcSetPlaceCustom(void); }; diff --git a/src/drivers/Qt/config.cpp b/src/drivers/Qt/config.cpp index 3a51678d..e8e3ff80 100644 --- a/src/drivers/Qt/config.cpp +++ b/src/drivers/Qt/config.cpp @@ -260,8 +260,10 @@ InitConfig() config->addOption("hexEditFgColor", "SDL.HexEditFgColor", "#FFFFFF"); // Debugger Options - config->addOption("autoLoadDebugFiles", "SDL.AutoLoadDebugFiles", 1); - config->addOption("autoOpenDebugger" , "SDL.AutoOpenDebugger" , 0); + config->addOption("autoLoadDebugFiles" , "SDL.AutoLoadDebugFiles", 1); + config->addOption("autoOpenDebugger" , "SDL.AutoOpenDebugger" , 0); + config->addOption("debuggerPCPlacementMode", "SDL.DebuggerPCPlacement" , 0); + config->addOption("debuggerPCDLineOffset" , "SDL.DebuggerPCLineOffset" , 0); // Code Data Logger Options config->addOption("autoSaveCDL" , "SDL.AutoSaveCDL", 1); From 386f943140884a00d816d7da622ea3d269913e79 Mon Sep 17 00:00:00 2001 From: Matthew Budd Date: Sun, 15 Nov 2020 14:47:57 -0500 Subject: [PATCH 3/4] For Qt debugger, added a run to cursor menu shortcut key. --- src/drivers/Qt/ConsoleDebugger.cpp | 26 ++++++++++++++++++++++++-- src/drivers/Qt/ConsoleDebugger.h | 3 +++ 2 files changed, 27 insertions(+), 2 deletions(-) diff --git a/src/drivers/Qt/ConsoleDebugger.cpp b/src/drivers/Qt/ConsoleDebugger.cpp index c5c6f868..3ec19f02 100644 --- a/src/drivers/Qt/ConsoleDebugger.cpp +++ b/src/drivers/Qt/ConsoleDebugger.cpp @@ -127,6 +127,14 @@ ConsoleDebugger::ConsoleDebugger(QWidget *parent) act->setStatusTip(tr("Step Over")); connect( act, SIGNAL(triggered()), this, SLOT(debugStepOverCB(void)) ); + debugMenu->addAction(act); + + // Debug -> Run to Cursor + act = new QAction(tr("Run to Cursor"), this); + act->setShortcut(QKeySequence( tr("Ctrl+F10") ) ); + act->setStatusTip(tr("Run to Cursor")); + connect( act, SIGNAL(triggered()), this, SLOT(debugRunToCursorCB(void)) ); + debugMenu->addAction(act); // Debug -> Run Line @@ -1707,6 +1715,19 @@ void ConsoleDebugger::debugStepOverCB(void) } } //---------------------------------------------------------------------------- +void ConsoleDebugger::debugRunToCursorCB(void) +{ + int addr = asmView->getCursorAddr(); + + if ( addr >= 0 ) + { + watchpoint[64].address = addr; + watchpoint[64].flags = WP_E|WP_X; + + FCEUI_SetEmulationPaused(0); + } +} +//---------------------------------------------------------------------------- void ConsoleDebugger::debugRunLineCB(void) { if (FCEUI_EmulationPaused()) @@ -3055,7 +3076,8 @@ QAsmView::QAsmView(QWidget *parent) selAddrValue = -1; memset( selAddrText, 0, sizeof(selAddrText) ); - wheelPixelCounter = 0; + cursorLineAddr = -1; + wheelPixelCounter = 0; //setSizePolicy( QSizePolicy::Preferred, QSizePolicy::Expanding ); setFocusPolicy(Qt::StrongFocus); @@ -3426,7 +3448,7 @@ void QAsmView::mouseMoveEvent(QMouseEvent * event) { int addr; - addr = asmEntry[line]->addr; + cursorLineAddr = addr = asmEntry[line]->addr; if (addr >= 0x8000) { diff --git a/src/drivers/Qt/ConsoleDebugger.h b/src/drivers/Qt/ConsoleDebugger.h index d6b87b3c..6d47059a 100644 --- a/src/drivers/Qt/ConsoleDebugger.h +++ b/src/drivers/Qt/ConsoleDebugger.h @@ -112,6 +112,7 @@ class QAsmView : public QWidget void setSymbolDebugEnable( bool value ); void setRegisterNameEnable( bool value ); int getCtxMenuAddr(void){ return ctxMenuAddr; }; + int getCursorAddr(void){ return cursorLineAddr; }; void setPC_placement( int mode, int ofs = 0 ); protected: void paintEvent(QPaintEvent *event); @@ -155,6 +156,7 @@ class QAsmView : public QWidget int pxLineXScroll; int cursorPosX; int cursorPosY; + int cursorLineAddr; int pcLinePlacement; int pcLineOffset; @@ -304,6 +306,7 @@ class ConsoleDebugger : public QDialog void debugStepIntoCB(void); void debugStepOutCB(void); void debugStepOverCB(void); + void debugRunToCursorCB(void); void debugRunLineCB(void); void debugRunLine128CB(void); void seekToCB(void); From 5e35c181c8aba00c2b872f608b4106d86cd402da Mon Sep 17 00:00:00 2001 From: Matthew Budd Date: Sun, 15 Nov 2020 18:55:03 -0500 Subject: [PATCH 4/4] Qt debugger slight change in main menu entry 'Run to Cursor' is now 'Run to Selected Line'. Run to Cursor option is still present in assembly viewer context menu. --- src/drivers/Qt/ConsoleDebugger.cpp | 45 ++++++++++++++++++++---------- src/drivers/Qt/ConsoleDebugger.h | 1 + 2 files changed, 32 insertions(+), 14 deletions(-) diff --git a/src/drivers/Qt/ConsoleDebugger.cpp b/src/drivers/Qt/ConsoleDebugger.cpp index 3ec19f02..a5a3f5fc 100644 --- a/src/drivers/Qt/ConsoleDebugger.cpp +++ b/src/drivers/Qt/ConsoleDebugger.cpp @@ -129,10 +129,10 @@ ConsoleDebugger::ConsoleDebugger(QWidget *parent) debugMenu->addAction(act); - // Debug -> Run to Cursor - act = new QAction(tr("Run to Cursor"), this); - act->setShortcut(QKeySequence( tr("Ctrl+F10") ) ); - act->setStatusTip(tr("Run to Cursor")); + // Debug -> Run to Selected Line + act = new QAction(tr("Run to Selected Line"), this); + act->setShortcut(QKeySequence( tr("F1") ) ); + act->setStatusTip(tr("Run to Selected Line")); connect( act, SIGNAL(triggered()), this, SLOT(debugRunToCursorCB(void)) ); debugMenu->addAction(act); @@ -1717,15 +1717,7 @@ void ConsoleDebugger::debugStepOverCB(void) //---------------------------------------------------------------------------- void ConsoleDebugger::debugRunToCursorCB(void) { - int addr = asmView->getCursorAddr(); - - if ( addr >= 0 ) - { - watchpoint[64].address = addr; - watchpoint[64].flags = WP_E|WP_X; - - FCEUI_SetEmulationPaused(0); - } + asmView->setBreakpointAtSelectedLine(); } //---------------------------------------------------------------------------- void ConsoleDebugger::debugRunLineCB(void) @@ -1803,10 +1795,12 @@ void ConsoleDebugger::resetCountersCB (void) //---------------------------------------------------------------------------- void ConsoleDebugger::asmViewCtxMenuRunToCursor(void) { + fceuWrapperLock(); watchpoint[64].address = asmView->getCtxMenuAddr(); watchpoint[64].flags = WP_E|WP_X; FCEUI_SetEmulationPaused(0); + fceuWrapperUnLock(); } //---------------------------------------------------------------------------- void ConsoleDebugger::asmViewCtxMenuAddBP(void) @@ -1884,6 +1878,29 @@ void QAsmView::setPC_placement( int mode, int ofs ) g_config->save(); } //---------------------------------------------------------------------------- +void QAsmView::setBreakpointAtSelectedLine(void) +{ + int addr = -1; + + if ( (selAddrLine >= 0) && (selAddrLine < asmEntry.size()) ) + { + if ( selAddrValue == asmEntry[ selAddrLine ]->addr ) + { + addr = selAddrValue; + } + } + + if ( addr >= 0 ) + { + fceuWrapperLock(); + watchpoint[64].address = addr; + watchpoint[64].flags = WP_E|WP_X; + + FCEUI_SetEmulationPaused(0); + fceuWrapperUnLock(); + } +} +//---------------------------------------------------------------------------- int QAsmView::getAsmLineFromAddr(int addr) { int line = -1; @@ -3817,7 +3834,7 @@ void QAsmView::contextMenuEvent(QContextMenuEvent *event) { act = new QAction(tr("Run To Cursor"), &menu); menu.addAction(act); - act->setShortcut( QKeySequence(tr("Ctrl+F10"))); + //act->setShortcut( QKeySequence(tr("Ctrl+F10"))); connect( act, SIGNAL(triggered(void)), parent, SLOT(asmViewCtxMenuRunToCursor(void)) ); } diff --git a/src/drivers/Qt/ConsoleDebugger.h b/src/drivers/Qt/ConsoleDebugger.h index 6d47059a..20f9a1a4 100644 --- a/src/drivers/Qt/ConsoleDebugger.h +++ b/src/drivers/Qt/ConsoleDebugger.h @@ -114,6 +114,7 @@ class QAsmView : public QWidget int getCtxMenuAddr(void){ return ctxMenuAddr; }; int getCursorAddr(void){ return cursorLineAddr; }; void setPC_placement( int mode, int ofs = 0 ); + void setBreakpointAtSelectedLine(void); protected: void paintEvent(QPaintEvent *event); void keyPressEvent(QKeyEvent *event);