Adding a next

This commit is contained in:
Anonymus Raccoon
2020-03-28 17:20:52 +01:00
parent 4a8a4a98f3
commit a6556b3ab7
2 changed files with 50 additions and 4 deletions
+38 -4
View File
@@ -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);
} }
+12
View File
@@ -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.