mirror of
https://github.com/zoriya/ComSquare.git
synced 2026-06-02 18:21:19 +00:00
Adding a next
This commit is contained in:
@@ -38,6 +38,7 @@ namespace ComSquare::Debugger
|
|||||||
|
|
||||||
QMainWindow::connect(this->_ui.actionPause, &QAction::triggered, this, &CPUDebug::pause);
|
QMainWindow::connect(this->_ui.actionPause, &QAction::triggered, this, &CPUDebug::pause);
|
||||||
QMainWindow::connect(this->_ui.actionStep, &QAction::triggered, this, &CPUDebug::step);
|
QMainWindow::connect(this->_ui.actionStep, &QAction::triggered, this, &CPUDebug::step);
|
||||||
|
QMainWindow::connect(this->_ui.actionNext, &QAction::triggered, this, &CPUDebug::next);
|
||||||
QMainWindow::connect(this->_ui.clear, &QPushButton::released, this, &CPUDebug::clearHistory);
|
QMainWindow::connect(this->_ui.clear, &QPushButton::released, this, &CPUDebug::clearHistory);
|
||||||
this->_window->show();
|
this->_window->show();
|
||||||
this->_updateRegistersPanel();
|
this->_updateRegistersPanel();
|
||||||
@@ -56,14 +57,30 @@ namespace ComSquare::Debugger
|
|||||||
unsigned CPUDebug::update()
|
unsigned CPUDebug::update()
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
|
unsigned cycles = 0;
|
||||||
|
|
||||||
if (this->_isPaused)
|
if (this->_isPaused)
|
||||||
return 0xFF;
|
return 0xFF;
|
||||||
if (this->_isStepping) {
|
if (this->_isStepping) {
|
||||||
unsigned ret = this->_executeInstruction(this->readPC());
|
cycles = this->_executeInstruction(this->readPC());
|
||||||
this->_updateDisassembly();
|
this->_updateDisassembly();
|
||||||
return ret;
|
return cycles;
|
||||||
}
|
}
|
||||||
return CPU::update();
|
|
||||||
|
for (int i = 0; i < 0xFF; i++) {
|
||||||
|
auto breakpoint = std::find_if(this->breakpoints.begin(), this->breakpoints.end(), [this](Breakpoint &brk) {
|
||||||
|
return brk.address == this->_registers.pac;
|
||||||
|
});
|
||||||
|
if (i != 0 && breakpoint != this->breakpoints.end()) {
|
||||||
|
if (breakpoint->oneTime)
|
||||||
|
this->breakpoints.erase(breakpoint);
|
||||||
|
this->_isPaused = false;
|
||||||
|
this->pause();
|
||||||
|
return cycles;
|
||||||
|
}
|
||||||
|
cycles += this->_executeInstruction(this->readPC());
|
||||||
|
}
|
||||||
|
return cycles;
|
||||||
} catch (InvalidOpcode &e) {
|
} catch (InvalidOpcode &e) {
|
||||||
if (!this->_isPaused)
|
if (!this->_isPaused)
|
||||||
this->pause();
|
this->pause();
|
||||||
@@ -105,6 +122,15 @@ namespace ComSquare::Debugger
|
|||||||
this->_isPaused = false;
|
this->_isPaused = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CPUDebug::next()
|
||||||
|
{
|
||||||
|
auto next = std::find_if(this->disassembledInstructions.begin(), this->disassembledInstructions.end(), [this](DisassembledInstruction &i) {
|
||||||
|
return i.address > this->_registers.pac;
|
||||||
|
});
|
||||||
|
this->breakpoints.push_back({next->address, true});
|
||||||
|
this->_isPaused = false;
|
||||||
|
}
|
||||||
|
|
||||||
void CPUDebug::_updateRegistersPanel()
|
void CPUDebug::_updateRegistersPanel()
|
||||||
{
|
{
|
||||||
if (!this->_registers.p.m)
|
if (!this->_registers.p.m)
|
||||||
@@ -378,10 +404,18 @@ RowPainter::RowPainter(ComSquare::Debugger::CPUDebug &cpu, QObject *parent) : QS
|
|||||||
void RowPainter::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
|
void RowPainter::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
|
||||||
{
|
{
|
||||||
ComSquare::Debugger::DisassembledInstruction instruction = this->_cpu.disassembledInstructions[index.row()];
|
ComSquare::Debugger::DisassembledInstruction instruction = this->_cpu.disassembledInstructions[index.row()];
|
||||||
|
bool isBreakpoint = false;
|
||||||
|
|
||||||
|
auto breakpoint = std::find_if(this->_cpu.breakpoints.begin(), this->_cpu.breakpoints.end(), [instruction](ComSquare::Debugger::Breakpoint brk) {
|
||||||
|
return brk.address == instruction.address;
|
||||||
|
});
|
||||||
|
if (breakpoint != this->_cpu.breakpoints.end())
|
||||||
|
isBreakpoint = true;
|
||||||
|
|
||||||
if (instruction.address == this->_cpu.getPC())
|
if (instruction.address == this->_cpu.getPC())
|
||||||
painter->fillRect(option.rect,QColor(Qt::darkGreen));
|
painter->fillRect(option.rect,QColor(Qt::darkGreen));
|
||||||
// TODO display breakpoints with the Qt::darkRed color.
|
if (isBreakpoint && !breakpoint->oneTime)
|
||||||
|
painter->fillRect(option.rect,QColor(Qt::darkRed));
|
||||||
QStyledItemDelegate::paint(painter, option, index);
|
QStyledItemDelegate::paint(painter, option, index);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -95,6 +95,14 @@ namespace ComSquare::Debugger
|
|||||||
std::string toString();
|
std::string toString();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
//! @brief Struct representing a breakpoint set by the user or by the app
|
||||||
|
struct Breakpoint {
|
||||||
|
//! @brief The address of the breakpoint
|
||||||
|
uint24_t address;
|
||||||
|
//! @brief If this is true, the breakpoint will be deleted on first hit and won't be shown on the disassembly view.
|
||||||
|
bool oneTime;
|
||||||
|
};
|
||||||
|
|
||||||
//! @brief A custom CPU with a window that show it's registers and the disassembly.
|
//! @brief A custom CPU with a window that show it's registers and the disassembly.
|
||||||
class CPUDebug : public CPU::CPU, public QObject {
|
class CPUDebug : public CPU::CPU, public QObject {
|
||||||
private:
|
private:
|
||||||
@@ -147,12 +155,16 @@ namespace ComSquare::Debugger
|
|||||||
void pause();
|
void pause();
|
||||||
//! @brief Step - Execute a single instruction.
|
//! @brief Step - Execute a single instruction.
|
||||||
void step();
|
void step();
|
||||||
|
//! @brief Next - Continue running instructions until the next line is reached.
|
||||||
|
void next();
|
||||||
//! @brief Clear the history panel.
|
//! @brief Clear the history panel.
|
||||||
void clearHistory();
|
void clearHistory();
|
||||||
//! @brief Called when the window is closed. Turn off the debugger and revert to a basic CPU.
|
//! @brief Called when the window is closed. Turn off the debugger and revert to a basic CPU.
|
||||||
void disableDebugger();
|
void disableDebugger();
|
||||||
//! @brief The list of disassembled instructions to show on the debugger.
|
//! @brief The list of disassembled instructions to show on the debugger.
|
||||||
std::vector<DisassembledInstruction> disassembledInstructions;
|
std::vector<DisassembledInstruction> disassembledInstructions;
|
||||||
|
//! @brief The list of breakpoints the user has set.
|
||||||
|
std::vector<Breakpoint> breakpoints;
|
||||||
//! @brief Return the current program counter of this CPU.
|
//! @brief Return the current program counter of this CPU.
|
||||||
uint24_t getPC();
|
uint24_t getPC();
|
||||||
//! @brief Update the UI when resetting the CPU.
|
//! @brief Update the UI when resetting the CPU.
|
||||||
|
|||||||
Reference in New Issue
Block a user