Skip to content

Commit 777c296

Browse files
committed
Implement execute until return
1 parent e2405ac commit 777c296

File tree

10 files changed

+79
-3
lines changed

10 files changed

+79
-3
lines changed

core/cpu.c

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,19 @@ static void cpu_inst_start(void) {
5555
#endif
5656
}
5757

58+
#ifdef DEBUG_SUPPORT
59+
static void debug_break_before_ret(const uint32_t len) {
60+
if (unlikely(debug.untilRet)) {
61+
const uint32_t curSp = cpu_address_mode(cpu.registers.stack[cpu.L].hl, cpu.L);
62+
if (curSp >= debug.untilRetBase) {
63+
const uint32_t start = cpu_mask_mode(cpu.registers.PC - len, cpu.ADL);
64+
cpu.registers.PC = start;
65+
debug_open(DBG_STEP, cpu.registers.PC);
66+
}
67+
}
68+
}
69+
#endif
70+
5871
uint32_t cpu_address_mode(uint32_t address, bool mode) {
5972
if (mode) {
6073
return address & 0xFFFFFF;
@@ -1185,6 +1198,9 @@ void cpu_execute(void) {
11851198
cpu.cycles++;
11861199
if (cpu_read_cc(context.y)) {
11871200
r->R += 2;
1201+
#ifdef DEBUG_SUPPORT
1202+
debug_break_before_ret(1);
1203+
#endif
11881204
cpu_return();
11891205
}
11901206
break;
@@ -1204,6 +1220,9 @@ void cpu_execute(void) {
12041220
}
12051221
switch (context.p) {
12061222
case 0: /* RET */
1223+
#ifdef DEBUG_SUPPORT
1224+
debug_break_before_ret(1);
1225+
#endif
12071226
cpu_return();
12081227
break;
12091228
case 1: /* EXX */
@@ -1485,6 +1504,9 @@ void cpu_execute(void) {
14851504
/* This is actually identical to reti on the z80 */
14861505
case 1: /* RETI */
14871506
cpu.IEF1 = cpu.IEF2;
1507+
#ifdef DEBUG_SUPPORT
1508+
debug_break_before_ret(2);
1509+
#endif
14881510
cpu_return();
14891511
break;
14901512
case 2: /* LEA IY, IX + d */

core/debug/debug.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -312,6 +312,11 @@ void debug_step(int mode, uint32_t addr) {
312312
gui_debug_close();
313313
debug.tempExec = addr;
314314
break;
315+
case DBG_UNTIL_RET:
316+
gui_debug_close();
317+
debug.untilRet = true;
318+
debug.untilRetBase = cpu_address_mode(cpu.registers.stack[cpu.L].hl, cpu.L);
319+
break;
315320
case DBG_BASIC_STEP_IN:
316321
case DBG_BASIC_STEP_NEXT:
317322
gui_debug_close();
@@ -328,6 +333,8 @@ void debug_step(int mode, uint32_t addr) {
328333
void debug_clear_step(void) {
329334
debug.step = debug.stepOver = false;
330335
debug.tempExec = debug.stepOut = ~0u;
336+
debug.untilRet = false;
337+
debug.untilRetBase = 0;
331338
}
332339

333340
void debug_clear_basic_step(void) {

core/debug/debug.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,8 @@ typedef struct {
145145
int64_t flashDelayCycles;
146146
bool step, stepOver;
147147
uint32_t tempExec, stepOut;
148+
bool untilRet;
149+
uint32_t untilRetBase; /* normalized 24bit stack pointer baseline */
148150

149151
uint32_t stackIndex, stackSize;
150152
debug_stack_entry_t *stack;
@@ -179,6 +181,7 @@ enum {
179181
DBG_STEP_OVER,
180182
DBG_STEP_NEXT,
181183
DBG_RUN_UNTIL,
184+
DBG_UNTIL_RET,
182185
DBG_BASIC_STEP_IN,
183186
DBG_BASIC_STEP_NEXT,
184187
};

gui/qt/debugger.cpp

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,9 @@ void MainWindow::debugEnable() {
147147
void MainWindow::debugStep(int mode) {
148148
if (mode == DBG_RUN_UNTIL) {
149149
debug_step(mode, m_runUntilAddr);
150+
} else if (mode == DBG_UNTIL_RET) {
151+
// no address needed, cpu checks for returns internally
152+
debug_step(mode, 0);
150153
} else {
151154
disasm.base = static_cast<int32_t>(cpu.registers.PC);
152155
disasmGet(true);
@@ -679,6 +682,7 @@ void MainWindow::debugGuiState(bool state) const {
679682
ui->buttonStepOver->setEnabled(state);
680683
ui->buttonStepNext->setEnabled(state);
681684
ui->buttonStepOut->setEnabled(state);
685+
ui->buttonUntilRet->setEnabled(state);
682686
ui->buttonCertID->setEnabled(state);
683687
ui->groupCPU->setEnabled(state);
684688
ui->groupFlags->setEnabled(state);
@@ -3003,6 +3007,17 @@ void MainWindow::stepOut() {
30033007
debugStep(DBG_STEP_OUT);
30043008
}
30053009

3010+
void MainWindow::stepUntilRet() {
3011+
if (!guiDebug) {
3012+
return;
3013+
}
3014+
3015+
disconnect(m_shortcutStepUntilRet, &QShortcut::activated, this, &MainWindow::stepUntilRet);
3016+
3017+
debugSync();
3018+
debugStep(DBG_UNTIL_RET);
3019+
}
3020+
30063021
//------------------------------------------------
30073022
// Other Functions
30083023
//------------------------------------------------

gui/qt/mainwindow.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -170,6 +170,7 @@ MainWindow::MainWindow(CEmuOpts &cliOpts, QWidget *p) : QMainWindow(p), ui(new U
170170
connect(ui->buttonStepOver, &QPushButton::clicked, this, &MainWindow::stepOver);
171171
connect(ui->buttonStepNext, &QPushButton::clicked, this, &MainWindow::stepNext);
172172
connect(ui->buttonStepOut, &QPushButton::clicked, this, &MainWindow::stepOut);
173+
connect(ui->buttonUntilRet, &QPushButton::clicked, this, &MainWindow::stepUntilRet);
173174
connect(ui->buttonGoto, &QPushButton::clicked, this, &MainWindow::gotoPressed);
174175
connect(ui->console, &QWidget::customContextMenuRequested, this, &MainWindow::contextConsole);
175176
connect(m_disasm, &QWidget::customContextMenuRequested, this, &MainWindow::contextDisasm);
@@ -521,6 +522,7 @@ MainWindow::MainWindow(CEmuOpts &cliOpts, QWidget *p) : QMainWindow(p), ui(new U
521522
m_shortcutStepOver = new QShortcut(QKeySequence(Qt::Key_F7), this);
522523
m_shortcutStepNext = new QShortcut(QKeySequence(Qt::Key_F8), this);
523524
m_shortcutStepOut = new QShortcut(QKeySequence(Qt::Key_F9), this);
525+
m_shortcutStepUntilRet = new QShortcut(QKeySequence(Qt::SHIFT | Qt::Key_F9), this);
524526
m_shortcutNavBack = new QShortcut(QKeySequence(Qt::ALT | Qt::Key_Left), this);
525527
m_shortcutNavForward = new QShortcut(QKeySequence(Qt::ALT | Qt::Key_Right), this);
526528

@@ -547,6 +549,7 @@ MainWindow::MainWindow(CEmuOpts &cliOpts, QWidget *p) : QMainWindow(p), ui(new U
547549
connect(m_shortcutStepOver, &QShortcut::activated, this, &MainWindow::stepOver);
548550
connect(m_shortcutStepNext, &QShortcut::activated, this, &MainWindow::stepNext);
549551
connect(m_shortcutStepOut, &QShortcut::activated, this, &MainWindow::stepOut);
552+
connect(m_shortcutStepUntilRet, &QShortcut::activated, this, &MainWindow::stepUntilRet);
550553

551554
setCorner(Qt::BottomLeftCorner, Qt::LeftDockWidgetArea);
552555
setCorner(Qt::BottomRightCorner, Qt::RightDockWidgetArea);

gui/qt/mainwindow.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -354,6 +354,7 @@ private slots:
354354
void stepOver();
355355
void stepNext();
356356
void stepOut();
357+
void stepUntilRet();
357358

358359
// os view
359360
void osUpdate();
@@ -710,6 +711,7 @@ private slots:
710711
QShortcut *m_shortcutStepOver;
711712
QShortcut *m_shortcutStepNext;
712713
QShortcut *m_shortcutStepOut;
714+
QShortcut *m_shortcutStepUntilRet;
713715
QShortcut *m_shortcutNavBack;
714716
QShortcut *m_shortcutNavForward;
715717
QShortcut *m_shortcutDebug;

gui/qt/mainwindow.ui

Lines changed: 26 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -532,7 +532,7 @@
532532
</widget>
533533
</item>
534534
<item>
535-
<widget class="QPushButton" name="buttonStepOut">
535+
<widget class="QPushButton" name="buttonStepOut">
536536
<property name="enabled">
537537
<bool>false</bool>
538538
</property>
@@ -552,8 +552,31 @@
552552
<iconset resource="resources.qrc">
553553
<normaloff>:/icons/resources/icons/stepout.png</normaloff>:/icons/resources/icons/stepout.png</iconset>
554554
</property>
555-
</widget>
556-
</item>
555+
</widget>
556+
</item>
557+
<item>
558+
<widget class="QPushButton" name="buttonUntilRet">
559+
<property name="enabled">
560+
<bool>false</bool>
561+
</property>
562+
<property name="sizePolicy">
563+
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Maximum">
564+
<horstretch>0</horstretch>
565+
<verstretch>0</verstretch>
566+
</sizepolicy>
567+
</property>
568+
<property name="focusPolicy">
569+
<enum>Qt::NoFocus</enum>
570+
</property>
571+
<property name="text">
572+
<string>Until RET</string>
573+
</property>
574+
<property name="icon">
575+
<iconset resource="resources.qrc">
576+
<normaloff>:/icons/resources/icons/untilret.png</normaloff>:/icons/resources/icons/untilret.png</iconset>
577+
</property>
578+
</widget>
579+
</item>
557580
<item>
558581
<widget class="QToolButton" name="buttonToggleBreakpoints">
559582
<property name="enabled">

gui/qt/resources.qrc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@
7272
<file>resources/icons/stepout.png</file>
7373
<file>resources/icons/stepover.png</file>
7474
<file>resources/icons/stop.png</file>
75+
<file>resources/icons/untilret.png</file>
7576
<file>resources/icons/timers.png</file>
7677
<file>resources/icons/toggle_console.png</file>
7778
<file>resources/icons/ui_edit.png</file>

gui/qt/resources/icons/stepout.png

2.96 KB
Loading
3.58 KB
Loading

0 commit comments

Comments
 (0)