From 6a41ed1d7646f3dea3ddf02d3c34cad09643d1dc Mon Sep 17 00:00:00 2001 From: Ash Wolf Date: Thu, 19 Dec 2019 14:11:31 +0000 Subject: [PATCH] add a very basic debugger UI --- WindCore/emu.cpp | 6 ++- WindCore/emu.h | 1 + WindQt/mainwindow.cpp | 104 ++++++++++++++++++++++++++++++++++++------ WindQt/mainwindow.h | 6 ++- WindQt/mainwindow.ui | 89 +++++++++++++++++++++++++++++++----- 5 files changed, 177 insertions(+), 29 deletions(-) diff --git a/WindCore/emu.cpp b/WindCore/emu.cpp index b8fa8de..d3418db 100644 --- a/WindCore/emu.cpp +++ b/WindCore/emu.cpp @@ -6,7 +6,6 @@ Emu::Emu() { - configure(); } @@ -464,7 +463,10 @@ void Emu::loadROM(const char *path) { } void Emu::executeUntil(int64_t cycles) { - while (!asleep && cpu.cycles <= cycles) { + if (!configured) + configure(); + + while (!asleep && cpu.cycles < cycles) { if (cpu.cycles >= nextTickAt) { // increment RTCDIV if ((pwrsr & 0x3F) == 0x3F) { diff --git a/WindCore/emu.h b/WindCore/emu.h index e743987..35ac805 100644 --- a/WindCore/emu.h +++ b/WindCore/emu.h @@ -82,4 +82,5 @@ public: void dumpRAM(const char *path); void executeUntil(int64_t cycles); int64_t currentCycles() const { return cpu.cycles; } + uint32_t getGPR(int index) const { return cpu.gprs[index]; } }; diff --git a/WindQt/mainwindow.cpp b/WindQt/mainwindow.cpp index 0dd9d20..2c9da90 100644 --- a/WindQt/mainwindow.cpp +++ b/WindQt/mainwindow.cpp @@ -3,6 +3,7 @@ #include "../WindCore/wind.h" #include #include +#include "../WindCore/decoder.h" MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), @@ -14,8 +15,10 @@ MainWindow::MainWindow(QWidget *parent) : emu->loadROM("/Users/ash/src/psion/Sys$rom.bin"); timer = new QTimer(this); - timer->start(1000/64); + timer->setInterval(1000/64); connect(timer, SIGNAL(timeout()), SLOT(execTimer())); + + updateScreen(); } MainWindow::~MainWindow() @@ -23,22 +26,54 @@ MainWindow::~MainWindow() delete ui; } -void MainWindow::execTimer() -{ - emu->executeUntil(emu->currentCycles() + (CLOCK_SPEED / 64)); - ui->cycleCounter->setText(QString("Cycles: %1").arg(emu->currentCycles())); - updateScreen(); -} - -void MainWindow::on_stepButton_clicked() -{ - emu->executeUntil(emu->currentCycles() + (CLOCK_SPEED * 2)); - ui->cycleCounter->setText(QString("Cycles: %1").arg(emu->currentCycles())); - updateScreen(); -} - void MainWindow::updateScreen() { + ui->cycleCounter->setText(QString("Cycles: %1").arg(emu->currentCycles())); + + ui->regsLabel->setText( + QString("R0: %1 / R1: %2 / R2: %3 / R3: %4 / R4: %5 / R5: %6 / R6: %7 / R7: %8 / R8: %9\nR9: %10 / R10:%11 / R11:%12 / R12:%13 / SP: %14 / LR: %15 / PC: %16") + .arg(emu->getGPR(0), 8, 16) + .arg(emu->getGPR(1), 8, 16) + .arg(emu->getGPR(2), 8, 16) + .arg(emu->getGPR(3), 8, 16) + .arg(emu->getGPR(4), 8, 16) + .arg(emu->getGPR(5), 8, 16) + .arg(emu->getGPR(6), 8, 16) + .arg(emu->getGPR(7), 8, 16) + .arg(emu->getGPR(8), 8, 16) + .arg(emu->getGPR(9), 8, 16) + .arg(emu->getGPR(10), 8, 16) + .arg(emu->getGPR(11), 8, 16) + .arg(emu->getGPR(12), 8, 16) + .arg(emu->getGPR(13), 8, 16) + .arg(emu->getGPR(14), 8, 16) + .arg(emu->getGPR(15), 8, 16) + ); + + // show a crude disassembly + const int context = 8 * 4; + uint32_t pc = emu->getGPR(15) - 4; + uint32_t minCode = pc - context; + if (minCode >= (UINT32_MAX - context)) + minCode = 0; + uint32_t maxCode = pc + context; + if (maxCode < context) + maxCode = UINT32_MAX; + + QStringList codeLines; + for (uint32_t addr = minCode; addr >= minCode && addr <= maxCode; addr += 4) { + const char *prefix = (addr == pc) ? "==>" : " "; + struct ARMInstructionInfo info; + char buffer[512]; + + uint32_t opcode = emu->readVirt32(addr); + ARMDecodeARM(opcode, &info); + ARMDisassemble(&info, addr, buffer, sizeof(buffer)); + codeLines.append(QString("%1 %2 | %3 | %4").arg(prefix).arg(addr, 8, 16).arg(opcode, 8, 16).arg(buffer)); + } + ui->codeLabel->setText(codeLines.join('\n')); + + // now, the actual screen const uint8_t *lcdBuf = emu->getLCDBuffer(); if (lcdBuf) { QImage img(640, 240, QImage::Format_Grayscale8); @@ -169,3 +204,42 @@ void MainWindow::keyReleaseEvent(QKeyEvent *event) if (k >= 0) emu->keyboardKeys[k] = false; } + + + + +void MainWindow::on_startButton_clicked() +{ + timer->start(); + ui->startButton->setEnabled(false); + ui->stopButton->setEnabled(true); + ui->stepInsnButton->setEnabled(false); + ui->stepTickButton->setEnabled(false); +} + +void MainWindow::on_stopButton_clicked() +{ + timer->stop(); + ui->startButton->setEnabled(true); + ui->stopButton->setEnabled(false); + ui->stepInsnButton->setEnabled(true); + ui->stepTickButton->setEnabled(true); +} + +void MainWindow::on_stepTickButton_clicked() +{ + emu->executeUntil(emu->currentCycles() + (CLOCK_SPEED * 2)); + updateScreen(); +} + +void MainWindow::on_stepInsnButton_clicked() +{ + emu->executeUntil(emu->currentCycles() + 1); + updateScreen(); +} + +void MainWindow::execTimer() +{ + emu->executeUntil(emu->currentCycles() + (CLOCK_SPEED / 64)); + updateScreen(); +} diff --git a/WindQt/mainwindow.h b/WindQt/mainwindow.h index 6059f6d..b2cb200 100644 --- a/WindQt/mainwindow.h +++ b/WindQt/mainwindow.h @@ -17,9 +17,13 @@ public: ~MainWindow() override; private slots: - void on_stepButton_clicked(); void execTimer(); + void on_startButton_clicked(); + void on_stopButton_clicked(); + void on_stepInsnButton_clicked(); + void on_stepTickButton_clicked(); + private: Ui::MainWindow *ui; Emu *emu; diff --git a/WindQt/mainwindow.ui b/WindQt/mainwindow.ui index 43a46e0..6d4db52 100644 --- a/WindQt/mainwindow.ui +++ b/WindQt/mainwindow.ui @@ -15,6 +15,75 @@ + + + + false + + + Stop + + + + + + + Step (Insn) + + + + + + + 1 + + + + Memory + + + + + Code + + + + + + + Courier New + + + + TextLabel + + + + + + + + + + + + + + + + + + Start + + + + + + + Cycles + + + @@ -28,22 +97,20 @@ - - + + - Step + Step (Tick) - - - - Cycles + + + + + Courier New + - - - -