CPU: Implement memory breakpoints/watchpoints

This commit is contained in:
Stenzek
2024-02-27 23:56:35 +10:00
parent ef4389cea8
commit 71094a0e44
12 changed files with 466 additions and 134 deletions

View File

@ -1,27 +1,32 @@
// SPDX-FileCopyrightText: 2019-2022 Connor McLaughlin <stenzek@gmail.com>
// SPDX-FileCopyrightText: 2019-2024 Connor McLaughlin <stenzek@gmail.com>
// SPDX-License-Identifier: (GPL-3.0 OR CC-BY-NC-ND-4.0)
#pragma once
#include "ui_debuggeraddbreakpointdialog.h"
#include "core/bus.h"
#include "core/cpu_core.h"
#include "core/cpu_types.h"
#include <QtCore/QAbstractListModel>
#include <QtCore/QAbstractTableModel>
#include <QtGui/QPixmap>
#include <QtWidgets/QDialog>
#include <map>
class DebuggerCodeModel : public QAbstractTableModel
class DebuggerCodeModel final : public QAbstractTableModel
{
Q_OBJECT
public:
DebuggerCodeModel(QObject* parent = nullptr);
virtual ~DebuggerCodeModel();
~DebuggerCodeModel() override;
virtual int rowCount(const QModelIndex& parent = QModelIndex()) const override;
virtual int columnCount(const QModelIndex& parent = QModelIndex()) const override;
virtual QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const override;
virtual QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override;
int rowCount(const QModelIndex& parent = QModelIndex()) const override;
int columnCount(const QModelIndex& parent = QModelIndex()) const override;
QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const override;
QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override;
// Returns the row for this instruction pointer
void resetCodeView(VirtualMemoryAddress start_address);
@ -51,39 +56,59 @@ private:
QPixmap m_breakpoint_pixmap;
};
class DebuggerRegistersModel : public QAbstractListModel
class DebuggerRegistersModel final : public QAbstractListModel
{
Q_OBJECT
public:
DebuggerRegistersModel(QObject* parent = nullptr);
virtual ~DebuggerRegistersModel();
~DebuggerRegistersModel() override;
virtual int rowCount(const QModelIndex& parent = QModelIndex()) const override;
virtual int columnCount(const QModelIndex& parent = QModelIndex()) const override;
virtual QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const override;
virtual QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override;
int rowCount(const QModelIndex& parent = QModelIndex()) const override;
int columnCount(const QModelIndex& parent = QModelIndex()) const override;
QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const override;
QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override;
void updateValues();
void saveCurrentValues();
private:
std::array<u32 ,CPU::NUM_DEBUGGER_REGISTER_LIST_ENTRIES> m_reg_values = {};
std::array<u32, CPU::NUM_DEBUGGER_REGISTER_LIST_ENTRIES> m_reg_values = {};
std::array<u32, CPU::NUM_DEBUGGER_REGISTER_LIST_ENTRIES> m_old_reg_values = {};
};
class DebuggerStackModel : public QAbstractListModel
class DebuggerStackModel final : public QAbstractListModel
{
Q_OBJECT
public:
DebuggerStackModel(QObject* parent = nullptr);
virtual ~DebuggerStackModel();
~DebuggerStackModel() override;
virtual int rowCount(const QModelIndex& parent = QModelIndex()) const override;
virtual int columnCount(const QModelIndex& parent = QModelIndex()) const override;
virtual QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const override;
virtual QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override;
int rowCount(const QModelIndex& parent = QModelIndex()) const override;
int columnCount(const QModelIndex& parent = QModelIndex()) const override;
QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const override;
QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override;
void invalidateView();
};
class DebuggerAddBreakpointDialog final : public QDialog
{
Q_OBJECT
public:
DebuggerAddBreakpointDialog(QWidget* parent = nullptr);
~DebuggerAddBreakpointDialog() override;
u32 getAddress() const { return m_address; }
CPU::BreakpointType getType() const { return m_type; }
private Q_SLOTS:
void okClicked();
private:
Ui::DebuggerAddBreakpointDialog m_ui;
u32 m_address = 0;
CPU::BreakpointType m_type = CPU::BreakpointType::Execute;
};