Qt/Debugger: Auto refresh memory every 100ms
This commit is contained in:
parent
c01e0b8dde
commit
173405be22
|
@ -15,6 +15,8 @@
|
||||||
#include <QtWidgets/QFileDialog>
|
#include <QtWidgets/QFileDialog>
|
||||||
#include <QtWidgets/QMessageBox>
|
#include <QtWidgets/QMessageBox>
|
||||||
|
|
||||||
|
static constexpr int TIMER_REFRESH_INTERVAL_MS = 100;
|
||||||
|
|
||||||
DebuggerWindow::DebuggerWindow(QWidget* parent /* = nullptr */)
|
DebuggerWindow::DebuggerWindow(QWidget* parent /* = nullptr */)
|
||||||
: QMainWindow(parent), m_active_memory_region(Bus::MemoryRegion::Count)
|
: QMainWindow(parent), m_active_memory_region(Bus::MemoryRegion::Count)
|
||||||
{
|
{
|
||||||
|
@ -64,11 +66,16 @@ void DebuggerWindow::onDebuggerMessageReported(const QString& message)
|
||||||
m_ui.statusbar->showMessage(message, 0);
|
m_ui.statusbar->showMessage(message, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void DebuggerWindow::timerRefresh()
|
||||||
|
{
|
||||||
|
m_ui.memoryView->forceRefresh();
|
||||||
|
}
|
||||||
|
|
||||||
void DebuggerWindow::refreshAll()
|
void DebuggerWindow::refreshAll()
|
||||||
{
|
{
|
||||||
m_registers_model->updateValues();
|
m_registers_model->updateValues();
|
||||||
m_stack_model->invalidateView();
|
m_stack_model->invalidateView();
|
||||||
m_ui.memoryView->repaint();
|
m_ui.memoryView->forceRefresh();
|
||||||
|
|
||||||
m_code_model->setPC(CPU::g_state.pc);
|
m_code_model->setPC(CPU::g_state.pc);
|
||||||
scrollToPC();
|
scrollToPC();
|
||||||
|
@ -478,6 +485,9 @@ void DebuggerWindow::connectSignals()
|
||||||
|
|
||||||
connect(m_ui.memorySearch, &QPushButton::clicked, this, &DebuggerWindow::onMemorySearchTriggered);
|
connect(m_ui.memorySearch, &QPushButton::clicked, this, &DebuggerWindow::onMemorySearchTriggered);
|
||||||
connect(m_ui.memorySearchString, &QLineEdit::textChanged, this, &DebuggerWindow::onMemorySearchStringChanged);
|
connect(m_ui.memorySearchString, &QLineEdit::textChanged, this, &DebuggerWindow::onMemorySearchStringChanged);
|
||||||
|
|
||||||
|
connect(&m_refresh_timer, &QTimer::timeout, this, &DebuggerWindow::timerRefresh);
|
||||||
|
m_refresh_timer.setInterval(TIMER_REFRESH_INTERVAL_MS);
|
||||||
}
|
}
|
||||||
|
|
||||||
void DebuggerWindow::disconnectSignals()
|
void DebuggerWindow::disconnectSignals()
|
||||||
|
@ -514,28 +524,35 @@ void DebuggerWindow::createModels()
|
||||||
|
|
||||||
void DebuggerWindow::setUIEnabled(bool enabled, bool allow_pause)
|
void DebuggerWindow::setUIEnabled(bool enabled, bool allow_pause)
|
||||||
{
|
{
|
||||||
|
const bool memory_view_enabled = (enabled || allow_pause);
|
||||||
|
|
||||||
m_ui.actionPause->setEnabled(allow_pause);
|
m_ui.actionPause->setEnabled(allow_pause);
|
||||||
|
|
||||||
// Disable all UI elements that depend on execution state
|
// Disable all UI elements that depend on execution state
|
||||||
m_ui.codeView->setEnabled(enabled);
|
m_ui.codeView->setEnabled(enabled);
|
||||||
m_ui.registerView->setEnabled(enabled);
|
m_ui.registerView->setEnabled(enabled);
|
||||||
m_ui.stackView->setEnabled(enabled);
|
m_ui.stackView->setEnabled(enabled);
|
||||||
m_ui.memoryView->setEnabled(enabled);
|
m_ui.memoryView->setEnabled(memory_view_enabled);
|
||||||
m_ui.actionRunToCursor->setEnabled(enabled);
|
m_ui.actionRunToCursor->setEnabled(enabled);
|
||||||
m_ui.actionAddBreakpoint->setEnabled(enabled);
|
m_ui.actionAddBreakpoint->setEnabled(enabled);
|
||||||
m_ui.actionToggleBreakpoint->setEnabled(enabled);
|
m_ui.actionToggleBreakpoint->setEnabled(enabled);
|
||||||
m_ui.actionClearBreakpoints->setEnabled(enabled);
|
m_ui.actionClearBreakpoints->setEnabled(enabled);
|
||||||
m_ui.actionDumpAddress->setEnabled(enabled);
|
m_ui.actionDumpAddress->setEnabled(memory_view_enabled);
|
||||||
m_ui.actionStepInto->setEnabled(enabled);
|
m_ui.actionStepInto->setEnabled(enabled);
|
||||||
m_ui.actionStepOver->setEnabled(enabled);
|
m_ui.actionStepOver->setEnabled(enabled);
|
||||||
m_ui.actionStepOut->setEnabled(enabled);
|
m_ui.actionStepOut->setEnabled(enabled);
|
||||||
m_ui.actionGoToAddress->setEnabled(enabled);
|
m_ui.actionGoToAddress->setEnabled(enabled);
|
||||||
m_ui.actionGoToPC->setEnabled(enabled);
|
m_ui.actionGoToPC->setEnabled(enabled);
|
||||||
m_ui.actionTrace->setEnabled(enabled);
|
m_ui.actionTrace->setEnabled(enabled);
|
||||||
m_ui.memoryRegionRAM->setEnabled(enabled);
|
m_ui.memoryRegionRAM->setEnabled(memory_view_enabled);
|
||||||
m_ui.memoryRegionEXP1->setEnabled(enabled);
|
m_ui.memoryRegionEXP1->setEnabled(memory_view_enabled);
|
||||||
m_ui.memoryRegionScratchpad->setEnabled(enabled);
|
m_ui.memoryRegionScratchpad->setEnabled(memory_view_enabled);
|
||||||
m_ui.memoryRegionBIOS->setEnabled(enabled);
|
m_ui.memoryRegionBIOS->setEnabled(memory_view_enabled);
|
||||||
|
|
||||||
|
// Partial/timer refreshes only active when not paused.
|
||||||
|
const bool timer_active = (!enabled && allow_pause);
|
||||||
|
if (m_refresh_timer.isActive() != timer_active)
|
||||||
|
timer_active ? m_refresh_timer.start() : m_refresh_timer.stop();
|
||||||
}
|
}
|
||||||
|
|
||||||
void DebuggerWindow::saveCurrentState()
|
void DebuggerWindow::saveCurrentState()
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
#include "core/cpu_core.h"
|
#include "core/cpu_core.h"
|
||||||
#include "core/types.h"
|
#include "core/types.h"
|
||||||
|
|
||||||
|
#include <QtCore/QTimer>
|
||||||
#include <QtWidgets/QMainWindow>
|
#include <QtWidgets/QMainWindow>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <optional>
|
#include <optional>
|
||||||
|
@ -41,6 +42,7 @@ private Q_SLOTS:
|
||||||
void onSystemResumed();
|
void onSystemResumed();
|
||||||
void onDebuggerMessageReported(const QString& message);
|
void onDebuggerMessageReported(const QString& message);
|
||||||
|
|
||||||
|
void timerRefresh();
|
||||||
void refreshAll();
|
void refreshAll();
|
||||||
|
|
||||||
void scrollToPC();
|
void scrollToPC();
|
||||||
|
@ -89,6 +91,8 @@ private:
|
||||||
std::unique_ptr<DebuggerRegistersModel> m_registers_model;
|
std::unique_ptr<DebuggerRegistersModel> m_registers_model;
|
||||||
std::unique_ptr<DebuggerStackModel> m_stack_model;
|
std::unique_ptr<DebuggerStackModel> m_stack_model;
|
||||||
|
|
||||||
|
QTimer m_refresh_timer;
|
||||||
|
|
||||||
Bus::MemoryRegion m_active_memory_region;
|
Bus::MemoryRegion m_active_memory_region;
|
||||||
|
|
||||||
PhysicalMemoryAddress m_next_memory_search_address = 0;
|
PhysicalMemoryAddress m_next_memory_search_address = 0;
|
||||||
|
|
|
@ -125,7 +125,7 @@ void MemoryViewWidget::keyPressEvent(QKeyEvent* event)
|
||||||
{
|
{
|
||||||
m_selected_address--;
|
m_selected_address--;
|
||||||
m_editing_nibble = -1;
|
m_editing_nibble = -1;
|
||||||
viewport()->update();
|
forceRefresh();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -139,7 +139,7 @@ void MemoryViewWidget::keyPressEvent(QKeyEvent* event)
|
||||||
expandCurrentDataToInclude(m_selected_address);
|
expandCurrentDataToInclude(m_selected_address);
|
||||||
std::memcpy(static_cast<unsigned char*>(m_data) + m_selected_address, &ch, sizeof(unsigned char));
|
std::memcpy(static_cast<unsigned char*>(m_data) + m_selected_address, &ch, sizeof(unsigned char));
|
||||||
m_selected_address = std::min(m_selected_address + 1, m_data_size - 1);
|
m_selected_address = std::min(m_selected_address + 1, m_data_size - 1);
|
||||||
viewport()->update();
|
forceRefresh();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -165,7 +165,7 @@ void MemoryViewWidget::keyPressEvent(QKeyEvent* event)
|
||||||
m_selected_address = std::min(m_selected_address + 1, m_data_size - 1);
|
m_selected_address = std::min(m_selected_address + 1, m_data_size - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
viewport()->update();
|
forceRefresh();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -381,7 +381,7 @@ void MemoryViewWidget::updateSelectedByte(const QPoint& pos)
|
||||||
m_selected_address = new_selection;
|
m_selected_address = new_selection;
|
||||||
m_selection_was_ascii = new_ascii;
|
m_selection_was_ascii = new_ascii;
|
||||||
m_editing_nibble = -1;
|
m_editing_nibble = -1;
|
||||||
viewport()->update();
|
forceRefresh();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -419,6 +419,11 @@ void MemoryViewWidget::saveCurrentData()
|
||||||
m_last_data_start_offset = m_start_offset;
|
m_last_data_start_offset = m_start_offset;
|
||||||
m_last_data.resize(size);
|
m_last_data.resize(size);
|
||||||
std::memcpy(m_last_data.data(), static_cast<const u8*>(m_data) + m_start_offset, size);
|
std::memcpy(m_last_data.data(), static_cast<const u8*>(m_data) + m_start_offset, size);
|
||||||
|
forceRefresh();
|
||||||
|
}
|
||||||
|
|
||||||
|
void MemoryViewWidget::forceRefresh()
|
||||||
|
{
|
||||||
viewport()->update();
|
viewport()->update();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -447,5 +452,8 @@ void MemoryViewWidget::adjustContent()
|
||||||
verticalScrollBar()->setRange(0, lineCount - m_rows_visible);
|
verticalScrollBar()->setRange(0, lineCount - m_rows_visible);
|
||||||
verticalScrollBar()->setPageStep(m_rows_visible);
|
verticalScrollBar()->setPageStep(m_rows_visible);
|
||||||
|
|
||||||
viewport()->update();
|
expandCurrentDataToInclude(m_start_offset);
|
||||||
|
expandCurrentDataToInclude(m_end_offset);
|
||||||
|
|
||||||
|
forceRefresh();
|
||||||
}
|
}
|
|
@ -34,6 +34,7 @@ protected:
|
||||||
|
|
||||||
public Q_SLOTS:
|
public Q_SLOTS:
|
||||||
void saveCurrentData();
|
void saveCurrentData();
|
||||||
|
void forceRefresh();
|
||||||
|
|
||||||
private Q_SLOTS:
|
private Q_SLOTS:
|
||||||
void adjustContent();
|
void adjustContent();
|
||||||
|
|
Loading…
Reference in New Issue