Qt debugger dynamically updates menu items controlling disassembly views

This commit is contained in:
Vas Crabb 2015-02-22 01:06:37 +11:00
parent b5afc9dfea
commit a581728a27
6 changed files with 195 additions and 60 deletions

View File

@ -37,9 +37,8 @@ DasmWindow::DasmWindow(running_machine* machine, QWidget* parent) :
connect(m_cpuComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(cpuChanged(int)));
// The main disasm window
m_dasmView = new DebuggerView(DVT_DISASSEMBLY,
m_machine,
this);
m_dasmView = new DebuggerView(DVT_DISASSEMBLY, m_machine, this);
connect(m_dasmView, SIGNAL(updated()), this, SLOT(dasmViewUpdated()));
// Force a recompute of the disassembly region
downcast<debug_view_disasm*>(m_dasmView->view())->set_expression("curpc");
@ -69,13 +68,16 @@ DasmWindow::DasmWindow(running_machine* machine, QWidget* parent) :
//
// Menu bars
//
// Create two commands
QAction* breakpointSetAct = new QAction("Toggle Breakpoint At Cursor", this);
QAction* runToCursorAct = new QAction("Run To Cursor", this);
breakpointSetAct->setShortcut(Qt::Key_F9);
runToCursorAct->setShortcut(Qt::Key_F4);
connect(breakpointSetAct, SIGNAL(triggered(bool)), this, SLOT(toggleBreakpointAtCursor(bool)));
connect(runToCursorAct, SIGNAL(triggered(bool)), this, SLOT(runToCursor(bool)));
// Create three commands
m_breakpointToggleAct = new QAction("Toggle Breakpoint at Cursor", this);
m_breakpointEnableAct = new QAction("Disable Breakpoint at Cursor", this);
m_runToCursorAct = new QAction("Run to Cursor", this);
m_breakpointToggleAct->setShortcut(Qt::Key_F9);
m_breakpointEnableAct->setShortcut(Qt::SHIFT + Qt::Key_F9);
m_runToCursorAct->setShortcut(Qt::Key_F4);
connect(m_breakpointToggleAct, SIGNAL(triggered(bool)), this, SLOT(toggleBreakpointAtCursor(bool)));
connect(m_breakpointEnableAct, SIGNAL(triggered(bool)), this, SLOT(enableBreakpointAtCursor(bool)));
connect(m_runToCursorAct, SIGNAL(triggered(bool)), this, SLOT(runToCursor(bool)));
// Right bar options
QActionGroup* rightBarGroup = new QActionGroup(this);
@ -97,8 +99,9 @@ DasmWindow::DasmWindow(running_machine* machine, QWidget* parent) :
// Assemble the options menu
QMenu* optionsMenu = menuBar()->addMenu("&Options");
optionsMenu->addAction(breakpointSetAct);
optionsMenu->addAction(runToCursorAct);
optionsMenu->addAction(m_breakpointToggleAct);
optionsMenu->addAction(m_breakpointEnableAct);
optionsMenu->addAction(m_runToCursorAct);
optionsMenu->addSeparator();
optionsMenu->addActions(rightBarGroup->actions());
}
@ -164,6 +167,32 @@ void DasmWindow::toggleBreakpointAtCursor(bool changedTo)
}
void DasmWindow::enableBreakpointAtCursor(bool changedTo)
{
if (m_dasmView->view()->cursor_visible())
{
offs_t const address = downcast<debug_view_disasm *>(m_dasmView->view())->selected_address();
device_t *const device = m_dasmView->view()->source()->device();
device_debug *const cpuinfo = device->debug();
// Find an existing breakpoint at this address
device_debug::breakpoint* bp = cpuinfo->breakpoint_first();
while ((bp != NULL) && (bp->address() != address))
bp = bp->next();
if (bp != NULL)
{
cpuinfo->breakpoint_enable(bp->index(), !bp->enabled());
debug_console_printf(*m_machine, "Breakpoint %X %s\n", (UINT32)bp->index(), bp->enabled() ? "enabled" : "disabled");
m_machine->debug_view().update_all();
debugger_refresh_display(*m_machine);
}
}
refreshAll();
}
void DasmWindow::runToCursor(bool changedTo)
{
if (m_dasmView->view()->cursor_visible())
@ -193,6 +222,37 @@ void DasmWindow::rightBarChanged(QAction* changedTo)
}
void DasmWindow::dasmViewUpdated()
{
bool const haveCursor = m_dasmView->view()->cursor_visible();
bool haveBreakpoint = false;
bool breakpointEnabled = false;
if (haveCursor)
{
offs_t const address = downcast<debug_view_disasm *>(m_dasmView->view())->selected_address();
device_t *const device = m_dasmView->view()->source()->device();
device_debug *const cpuinfo = device->debug();
// Find an existing breakpoint at this address
device_debug::breakpoint* bp = cpuinfo->breakpoint_first();
while ((bp != NULL) && (bp->address() != address))
bp = bp->next();
if (bp != NULL)
{
haveBreakpoint = true;
breakpointEnabled = bp->enabled();
}
}
m_breakpointToggleAct->setText(haveBreakpoint ? "Clear Breakpoint at Cursor" : haveCursor ? "Set Breakpoint at Cursor" : "Toggle Breakpoint at Cursor");
m_breakpointEnableAct->setText((!haveBreakpoint || breakpointEnabled) ? "Disable Breakpoint at Cursor" : "Enable Breakpoint at Cursor");
m_breakpointToggleAct->setEnabled(haveCursor);
m_breakpointEnableAct->setEnabled(haveBreakpoint);
m_runToCursorAct->setEnabled(haveCursor);
}
void DasmWindow::populateComboBox()
{
if (m_dasmView == NULL)

View File

@ -24,19 +24,26 @@ private slots:
void expressionSubmitted();
void toggleBreakpointAtCursor(bool changedTo);
void enableBreakpointAtCursor(bool changedTo);
void runToCursor(bool changedTo);
void rightBarChanged(QAction* changedTo);
void dasmViewUpdated();
private:
void populateComboBox();
private:
// Widgets
QLineEdit* m_inputEdit;
QComboBox* m_cpuComboBox;
DebuggerView* m_dasmView;
// Menu items
QAction* m_breakpointToggleAct;
QAction* m_breakpointEnableAct;
QAction* m_runToCursorAct;
};

View File

@ -379,4 +379,5 @@ void DebuggerView::debuggerViewUpdate(debug_view& debugView, void* osdPrivate)
dView->horizontalScrollBar()->setValue(dView->view()->visible_position().x);
dView->viewport()->update();
dView->update();
emit dView->updated();
}

View File

@ -18,13 +18,12 @@ public:
void paintEvent(QPaintEvent* event);
// Callback to allow MAME to refresh the view
static void debuggerViewUpdate(debug_view& debugView, void* osdPrivate);
// Setters and accessors
void setPreferBottom(bool pb) { m_preferBottom = pb; }
debug_view* view() { return m_view; }
signals:
void updated();
protected:
void keyPressEvent(QKeyEvent* event);
@ -36,6 +35,9 @@ private slots:
private:
// Callback to allow MAME to refresh the view
static void debuggerViewUpdate(debug_view& debugView, void* osdPrivate);
bool m_preferBottom;
debug_view* m_view;

View File

@ -43,13 +43,16 @@ MainWindow::MainWindow(running_machine* machine, QWidget* parent) :
//
// Options Menu
//
// Create two commands
QAction* breakpointSetAct = new QAction("Toggle Breakpoint At Cursor", this);
QAction* runToCursorAct = new QAction("Run To Cursor", this);
breakpointSetAct->setShortcut(Qt::Key_F9);
runToCursorAct->setShortcut(Qt::Key_F4);
connect(breakpointSetAct, SIGNAL(triggered(bool)), this, SLOT(toggleBreakpointAtCursor(bool)));
connect(runToCursorAct, SIGNAL(triggered(bool)), this, SLOT(runToCursor(bool)));
// Create three commands
m_breakpointToggleAct = new QAction("Toggle Breakpoint at Cursor", this);
m_breakpointEnableAct = new QAction("Disable Breakpoint at Cursor", this);
m_runToCursorAct = new QAction("Run to Cursor", this);
m_breakpointToggleAct->setShortcut(Qt::Key_F9);
m_breakpointEnableAct->setShortcut(Qt::SHIFT + Qt::Key_F9);
m_runToCursorAct->setShortcut(Qt::Key_F4);
connect(m_breakpointToggleAct, SIGNAL(triggered(bool)), this, SLOT(toggleBreakpointAtCursor(bool)));
connect(m_breakpointEnableAct, SIGNAL(triggered(bool)), this, SLOT(enableBreakpointAtCursor(bool)));
connect(m_runToCursorAct, SIGNAL(triggered(bool)), this, SLOT(runToCursor(bool)));
// Right bar options
QActionGroup* rightBarGroup = new QActionGroup(this);
@ -71,8 +74,9 @@ MainWindow::MainWindow(running_machine* machine, QWidget* parent) :
// Assemble the options menu
QMenu* optionsMenu = menuBar()->addMenu("&Options");
optionsMenu->addAction(breakpointSetAct);
optionsMenu->addAction(runToCursorAct);
optionsMenu->addAction(m_breakpointToggleAct);
optionsMenu->addAction(m_breakpointEnableAct);
optionsMenu->addAction(m_runToCursorAct);
optionsMenu->addSeparator();
optionsMenu->addActions(rightBarGroup->actions());
@ -109,6 +113,7 @@ MainWindow::MainWindow(running_machine* machine, QWidget* parent) :
dasmDock->setAllowedAreas(Qt::TopDockWidgetArea);
m_dasmFrame = new DasmDockWidget(m_machine, dasmDock);
dasmDock->setWidget(m_dasmFrame);
connect(m_dasmFrame->view(), SIGNAL(updated()), this, SLOT(dasmViewUpdated()));
addDockWidget(Qt::TopDockWidgetArea, dasmDock);
dockMenu->addAction(dasmDock->toggleViewAction());
@ -200,13 +205,11 @@ bool MainWindow::eventFilter(QObject* obj, QEvent* event)
void MainWindow::toggleBreakpointAtCursor(bool changedTo)
{
debug_view_disasm* dasmView = downcast<debug_view_disasm*>(m_dasmFrame->view()->view());
if (dasmView->cursor_visible())
debug_view_disasm *const dasmView = downcast<debug_view_disasm*>(m_dasmFrame->view()->view());
if (dasmView->cursor_visible() && (debug_cpu_get_visible_cpu(*m_machine) == dasmView->source()->device()))
{
if (debug_cpu_get_visible_cpu(*m_machine) == dasmView->source()->device())
{
offs_t address = downcast<debug_view_disasm *>(dasmView)->selected_address();
device_debug *cpuinfo = dasmView->source()->device()->debug();
offs_t const address = downcast<debug_view_disasm *>(dasmView)->selected_address();
device_debug *const cpuinfo = dasmView->source()->device()->debug();
// Find an existing breakpoint at this address
INT32 bpindex = -1;
@ -233,6 +236,31 @@ void MainWindow::toggleBreakpointAtCursor(bool changedTo)
}
debug_console_execute_command(*m_machine, command, 1);
}
refreshAll();
}
void MainWindow::enableBreakpointAtCursor(bool changedTo)
{
debug_view_disasm *const dasmView = downcast<debug_view_disasm*>(m_dasmFrame->view()->view());
if (dasmView->cursor_visible() && (debug_cpu_get_visible_cpu(*m_machine) == dasmView->source()->device()))
{
offs_t const address = dasmView->selected_address();
device_debug *const cpuinfo = dasmView->source()->device()->debug();
// Find an existing breakpoint at this address
device_debug::breakpoint* bp = cpuinfo->breakpoint_first();
while ((bp != NULL) && (bp->address() != address))
bp = bp->next();
if (bp != NULL)
{
INT32 const bpindex = bp->index();
astring command;
command.printf(bp->enabled() ? "bpdisable 0x%X" : "bpenable 0x%X", bpindex);
debug_console_execute_command(*m_machine, command, 1);
}
}
refreshAll();
@ -242,9 +270,7 @@ void MainWindow::toggleBreakpointAtCursor(bool changedTo)
void MainWindow::runToCursor(bool changedTo)
{
debug_view_disasm* dasmView = downcast<debug_view_disasm*>(m_dasmFrame->view()->view());
if (dasmView->cursor_visible())
{
if (debug_cpu_get_visible_cpu(*m_machine) == dasmView->source()->device())
if (dasmView->cursor_visible() && (debug_cpu_get_visible_cpu(*m_machine) == dasmView->source()->device()))
{
offs_t address = downcast<debug_view_disasm*>(dasmView)->selected_address();
astring command;
@ -252,7 +278,6 @@ void MainWindow::runToCursor(bool changedTo)
debug_console_execute_command(*m_machine, command, 1);
}
}
}
void MainWindow::rightBarChanged(QAction* changedTo)
@ -372,6 +397,38 @@ void MainWindow::unmountImage(bool changedTo)
}
void MainWindow::dasmViewUpdated()
{
debug_view_disasm *const dasmView = downcast<debug_view_disasm*>(m_dasmFrame->view()->view());
bool const haveCursor = dasmView->cursor_visible() && (debug_cpu_get_visible_cpu(*m_machine) == dasmView->source()->device());
bool haveBreakpoint = false;
bool breakpointEnabled = false;
if (haveCursor)
{
offs_t const address = dasmView->selected_address();
device_t *const device = dasmView->source()->device();
device_debug *const cpuinfo = device->debug();
// Find an existing breakpoint at this address
device_debug::breakpoint* bp = cpuinfo->breakpoint_first();
while ((bp != NULL) && (bp->address() != address))
bp = bp->next();
if (bp != NULL)
{
haveBreakpoint = true;
breakpointEnabled = bp->enabled();
}
}
m_breakpointToggleAct->setText(haveBreakpoint ? "Clear Breakpoint at Cursor" : haveCursor ? "Set Breakpoint at Cursor" : "Toggle Breakpoint at Cursor");
m_breakpointEnableAct->setText((!haveBreakpoint || breakpointEnabled) ? "Disable Breakpoint at Cursor" : "Enable Breakpoint at Cursor");
m_breakpointToggleAct->setEnabled(haveCursor);
m_breakpointEnableAct->setEnabled(haveBreakpoint);
m_runToCursorAct->setEnabled(haveCursor);
}
void MainWindow::debugActClose()
{
m_machine->schedule_exit();

View File

@ -37,6 +37,7 @@ protected:
private slots:
void toggleBreakpointAtCursor(bool changedTo);
void enableBreakpointAtCursor(bool changedTo);
void runToCursor(bool changedTo);
void rightBarChanged(QAction* changedTo);
@ -45,23 +46,30 @@ private slots:
void mountImage(bool changedTo);
void unmountImage(bool changedTo);
void dasmViewUpdated();
// Closing the main window actually exits the program
void debugActClose();
private:
void createImagesMenu();
// Widgets and docks
QLineEdit* m_inputEdit;
DebuggerView* m_consoleView;
ProcessorDockWidget* m_procFrame;
DasmDockWidget* m_dasmFrame;
// Menu items
QAction* m_breakpointToggleAct;
QAction* m_breakpointEnableAct;
QAction* m_runToCursorAct;
// Terminal history
int m_historyIndex;
std::vector<QString> m_inputHistory;
void addToHistory(const QString& command);
void createImagesMenu();
};