From e96c438003bdf061519a9caab70480ecd41da0de Mon Sep 17 00:00:00 2001 From: Ash Wolf Date: Thu, 19 Dec 2019 17:40:49 +0000 Subject: [PATCH] add basic breakpoint support --- WindCore/emu.cpp | 18 ++++++++------ WindCore/emu.h | 4 +++ WindQt/mainwindow.cpp | 24 +++++++++++++++++- WindQt/mainwindow.h | 6 ++++- WindQt/mainwindow.ui | 58 ++++++++++++++++++++++++++++++++++++++++++- 5 files changed, 100 insertions(+), 10 deletions(-) diff --git a/WindCore/emu.cpp b/WindCore/emu.cpp index 71b09a5..848f08a 100644 --- a/WindCore/emu.cpp +++ b/WindCore/emu.cpp @@ -4,7 +4,7 @@ #include -//#define INCLUDE_BANK1 +#define INCLUDE_BANK1 Emu::Emu() { } @@ -184,7 +184,7 @@ void Emu::writeReg32(uint32_t reg, uint32_t value) { uint32_t Emu::readPhys8(uint32_t physAddress) { uint32_t result = 0xFF; - uint8_t region = (physAddress >> 24) & 0xF8; + uint8_t region = (physAddress >> 24) & 0xF1; if (region == 0) result = ROM[physAddress & 0xFFFFFF]; else if (region == 0x80 && physAddress <= 0x80000FFF) @@ -207,7 +207,7 @@ uint32_t Emu::readPhys8(uint32_t physAddress) { } uint32_t Emu::readPhys16(uint32_t physAddress) { uint32_t result = 0xFFFFFFFF; - uint8_t region = (physAddress >> 24) & 0xF8; + uint8_t region = (physAddress >> 24) & 0xF1; if (region == 0) LOAD_16LE(result, physAddress & 0xFFFFFF, ROM); else if (region == 0xC0) @@ -228,7 +228,7 @@ uint32_t Emu::readPhys16(uint32_t physAddress) { } uint32_t Emu::readPhys32(uint32_t physAddress) { uint32_t result = 0xFFFFFFFF; - uint8_t region = (physAddress >> 24) & 0xF8; + uint8_t region = (physAddress >> 24) & 0xF1; if (region == 0) LOAD_32LE(result, physAddress & 0xFFFFFF, ROM); else if (region == 0x80 && physAddress <= 0x80000FFF) @@ -251,7 +251,7 @@ uint32_t Emu::readPhys32(uint32_t physAddress) { } void Emu::writePhys8(uint32_t physAddress, uint8_t value) { - uint8_t region = (physAddress >> 24) & 0xF8; + uint8_t region = (physAddress >> 24) & 0xF1; if (region == 0xC0) MemoryBlockC0[physAddress & MemoryBlockMask] = (uint8_t)value; #ifdef INCLUDE_BANK1 @@ -270,7 +270,7 @@ void Emu::writePhys8(uint32_t physAddress, uint8_t value) { // printf("<%08x> unmapped write8 addr p:%08x :: %02x\n", cpu.gprs[ARM_PC] - 4, physAddress, value); } void Emu::writePhys16(uint32_t physAddress, uint16_t value) { - uint8_t region = (physAddress >> 24) & 0xF8; + uint8_t region = (physAddress >> 24) & 0xF1; if (region == 0xC0) STORE_16LE(value, physAddress & MemoryBlockMask, MemoryBlockC0); #ifdef INCLUDE_BANK1 @@ -287,7 +287,7 @@ void Emu::writePhys16(uint32_t physAddress, uint16_t value) { // printf("<%08x> unmapped write16 addr p:%08x :: %04x\n", cpu.gprs[ARM_PC] - 4, physAddress, value); } void Emu::writePhys32(uint32_t physAddress, uint32_t value) { - uint8_t region = (physAddress >> 24) & 0xF8; + uint8_t region = (physAddress >> 24) & 0xF1; if (region == 0xC0) STORE_32LE(value, physAddress & MemoryBlockMask, MemoryBlockC0); #ifdef INCLUDE_BANK1 @@ -556,6 +556,10 @@ void Emu::executeUntil(int64_t cycles) { uint32_t phys_pc = virtToPhys(pc); debugPC(phys_pc); ARMRun(&cpu); + + uint32_t new_pc = cpu.gprs[ARM_PC] - 4; + if (_breakpoints.find(new_pc) != _breakpoints.end()) + return; } } } diff --git a/WindCore/emu.h b/WindCore/emu.h index c814af6..05ae799 100644 --- a/WindCore/emu.h +++ b/WindCore/emu.h @@ -1,6 +1,7 @@ #pragma once #include "arm.h" #include "wind_hw.h" +#include class Emu { uint8_t ROM[0x1000000]; @@ -28,6 +29,8 @@ class Emu { UART uart1, uart2; bool asleep = false; + std::unordered_set _breakpoints; + struct ARMCore cpu; inline bool isMMU() { @@ -84,4 +87,5 @@ public: void executeUntil(int64_t cycles); int64_t currentCycles() const { return cpu.cycles; } uint32_t getGPR(int index) const { return cpu.gprs[index]; } + std::unordered_set &breakpoints() { return _breakpoints; } }; diff --git a/WindQt/mainwindow.cpp b/WindQt/mainwindow.cpp index 2c9da90..4491613 100644 --- a/WindQt/mainwindow.cpp +++ b/WindQt/mainwindow.cpp @@ -31,7 +31,7 @@ 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") + QString("R0: %1 / R1: %2 / R2: %3 / R3: %4 / R4: %5 / R5: %6 / R6: %7 / R7: %8\nR8: %9 / R9: %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) @@ -243,3 +243,25 @@ void MainWindow::execTimer() emu->executeUntil(emu->currentCycles() + (CLOCK_SPEED / 64)); updateScreen(); } + +void MainWindow::on_addBreakButton_clicked() +{ + uint32_t addr = ui->breakpointAddress->text().toUInt(nullptr, 16); + emu->breakpoints().insert(addr); + updateBreakpointsList(); +} + +void MainWindow::on_removeBreakButton_clicked() +{ + uint32_t addr = ui->breakpointAddress->text().toUInt(nullptr, 16); + emu->breakpoints().erase(addr); + updateBreakpointsList(); +} + +void MainWindow::updateBreakpointsList() +{ + ui->breakpointsList->clear(); + for (uint32_t addr : emu->breakpoints()) { + ui->breakpointsList->addItem(QString::number(addr, 16)); + } +} diff --git a/WindQt/mainwindow.h b/WindQt/mainwindow.h index b2cb200..e7ea7a8 100644 --- a/WindQt/mainwindow.h +++ b/WindQt/mainwindow.h @@ -24,12 +24,16 @@ private slots: void on_stepInsnButton_clicked(); void on_stepTickButton_clicked(); + void on_addBreakButton_clicked(); + + void on_removeBreakButton_clicked(); + private: Ui::MainWindow *ui; Emu *emu; QTimer *timer; void updateScreen(); - + void updateBreakpointsList(); protected: void keyPressEvent(QKeyEvent *event) override; diff --git a/WindQt/mainwindow.ui b/WindQt/mainwindow.ui index 6d4db52..337d05c 100644 --- a/WindQt/mainwindow.ui +++ b/WindQt/mainwindow.ui @@ -35,7 +35,7 @@ - 1 + 2 @@ -61,10 +61,66 @@ + + + Breakpoints + + + + + + Edit + + + + + + Add + + + + + + + Remove + + + + + + + hex address, no prefix + + + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + + + Qt::ClickFocus +