#include <time.h>
-//#define INCLUDE_BANK1
+#define INCLUDE_BANK1
Emu::Emu() {
}
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)
}
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)
}
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)
}
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
// 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
// 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
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;
}
}
}
#pragma once
#include "arm.h"
#include "wind_hw.h"
+#include <unordered_set>
class Emu {
uint8_t ROM[0x1000000];
UART uart1, uart2;
bool asleep = false;
+ std::unordered_set<uint32_t> _breakpoints;
+
struct ARMCore cpu;
inline bool isMMU() {
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<uint32_t> &breakpoints() { return _breakpoints; }
};
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)
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));
+ }
+}
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;
<item row="4" column="0" colspan="5">
<widget class="QTabWidget" name="tabWidget">
<property name="currentIndex">
- <number>1</number>
+ <number>2</number>
</property>
<widget class="QWidget" name="tab">
<attribute name="title">
</item>
</layout>
</widget>
+ <widget class="QWidget" name="tab_3">
+ <attribute name="title">
+ <string>Breakpoints</string>
+ </attribute>
+ <layout class="QGridLayout" name="gridLayout_2">
+ <item row="0" column="1">
+ <widget class="QGroupBox" name="groupBox">
+ <property name="title">
+ <string>Edit</string>
+ </property>
+ <layout class="QGridLayout" name="gridLayout_3">
+ <item row="1" column="0">
+ <widget class="QPushButton" name="addBreakButton">
+ <property name="text">
+ <string>Add</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="1">
+ <widget class="QPushButton" name="removeBreakButton">
+ <property name="text">
+ <string>Remove</string>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="0" colspan="2">
+ <widget class="QLineEdit" name="breakpointAddress">
+ <property name="placeholderText">
+ <string>hex address, no prefix</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item row="1" column="1">
+ <spacer name="verticalSpacer">
+ <property name="orientation">
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>20</width>
+ <height>40</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item row="0" column="0" rowspan="2">
+ <widget class="QListWidget" name="breakpointsList"/>
+ </item>
+ </layout>
+ </widget>
</widget>
</item>
<item row="0" column="0" colspan="6">
<widget class="QLabel" name="screen">
+ <property name="focusPolicy">
+ <enum>Qt::ClickFocus</enum>
+ </property>
<property name="text">
<string/>
</property>