From e50fda62be3e79c60bd6510d53d869adb058aff5 Mon Sep 17 00:00:00 2001 From: Peter Evans Date: Sun, 25 Feb 2018 15:41:37 -0600 Subject: [PATCH] Add step command --- include/vm_debug.h | 1 + src/apple2.c | 4 ++++ src/apple2.reflect.c | 12 ++++-------- src/mos6502.c | 2 ++ src/vm_debug.c | 11 +++++++++++ tests/vm_debug.c | 21 +++++++++++++++++++++ 6 files changed, 43 insertions(+), 8 deletions(-) diff --git a/include/vm_debug.h b/include/vm_debug.h index fe8212b..776c5a9 100644 --- a/include/vm_debug.h +++ b/include/vm_debug.h @@ -82,6 +82,7 @@ extern DEBUG_CMD(printaddr); extern DEBUG_CMD(printstate); extern DEBUG_CMD(quit); extern DEBUG_CMD(resume); +extern DEBUG_CMD(step); extern DEBUG_CMD(unbreak); extern DEBUG_CMD(writeaddr); extern DEBUG_CMD(writestate); diff --git a/src/apple2.c b/src/apple2.c index b372862..fa7d738 100644 --- a/src/apple2.c +++ b/src/apple2.c @@ -351,6 +351,10 @@ apple2_run_loop(apple2 *mach) vm_reflect_pause(NULL); while (vm_screen_active(mach->screen)) { + if (vm_debug_broke(mach->cpu->PC)) { + mach->paused = true; + } + // If we're paused, then just re-loop until we're not if (mach->paused) { char *input = vm_debug_prompt(); diff --git a/src/apple2.reflect.c b/src/apple2.reflect.c index bdace0b..acbf3d0 100644 --- a/src/apple2.reflect.c +++ b/src/apple2.reflect.c @@ -33,8 +33,7 @@ REFLECT(apple2_reflect_cpu_info) mos6502 *cpu = (mos6502 *)vm_di_get(VM_CPU); FILE *out = (FILE *)vm_di_get(VM_OUTPUT); - fprintf(out, "REGISTERS:\n"); - fprintf(out, " A:%02x X:%02x Y:%02x P:%02x S:%02x PC:%04x\n", + fprintf(out, "CPU: A:%02x X:%02x Y:%02x P:%02x S:%02x PC:%04x\n", cpu->A, cpu->X, cpu->Y, cpu->P, cpu->S, cpu->PC); } @@ -48,12 +47,9 @@ REFLECT(apple2_reflect_machine_info) apple2 *mach = (apple2 *)vm_di_get(VM_MACHINE); FILE *out = (FILE *)vm_di_get(VM_OUTPUT); - fprintf(out, "MACHINE:\n"); - fprintf(out, " display_mode: %02x\n", mach->display_mode); - fprintf(out, " color_mode: %02x\n", mach->color_mode); - fprintf(out, " bank_switch: %02x\n", mach->bank_switch); - fprintf(out, " memory_mode: %02x\n", mach->memory_mode); - fprintf(out, " strobe: %02x\n", mach->strobe); + fprintf(out, "MACH: BS:%02x CM:%02x DM:%02x MM:%02x STROBE:%02x\n", + mach->bank_switch, mach->color_mode, mach->display_mode, + mach->memory_mode, mach->strobe); } /* diff --git a/src/mos6502.c b/src/mos6502.c index 1c0c9e7..2d95fac 100644 --- a/src/mos6502.c +++ b/src/mos6502.c @@ -364,6 +364,8 @@ mos6502_execute(mos6502 *cpu) mos6502_address_resolver resolver; mos6502_instruction_handler handler; + // We shouldn't normally get here, if there was a breakpoint, but we + // will in testing. if (vm_debug_broke(cpu->PC)) { return; } diff --git a/src/vm_debug.c b/src/vm_debug.c index bea7f46..339c9ed 100644 --- a/src/vm_debug.c +++ b/src/vm_debug.c @@ -41,6 +41,8 @@ vm_debug_cmd cmdtable[] = { "Quit the emulator", }, { "resume", "r", vm_debug_cmd_resume, 0, "", "Resume execution", }, + { "step", "s", vm_debug_cmd_step, 0, "", + "Execute the current opcode and break at the next", }, { "unbreak", "u", vm_debug_cmd_unbreak, 1, "", "Remove breakpoint at ", }, { "writeaddr", "wa", vm_debug_cmd_writeaddr, 2, " ", @@ -311,3 +313,12 @@ DEBUG_CMD(unbreak) { vm_debug_unbreak(args->addr1); } + +DEBUG_CMD(step) +{ + mos6502 *cpu = (mos6502 *)vm_di_get(VM_CPU); + + vm_debug_unbreak(cpu->PC); + mos6502_execute(cpu); + vm_debug_break(cpu->PC); +} diff --git a/tests/vm_debug.c b/tests/vm_debug.c index 6d3ec00..8c25b61 100644 --- a/tests/vm_debug.c +++ b/tests/vm_debug.c @@ -212,4 +212,25 @@ Test(vm_debug, unbreak_all) cr_assert_eq(vm_debug_broke(55555), false); } +Test(vm_debug, cmd_step) +{ + // Just setting us up with some NOPs for the testing + mos6502_set(mach->cpu, 0, 0xEA); + mos6502_set(mach->cpu, 1, 0xEA); + mos6502_set(mach->cpu, 2, 0xEA); + mos6502_set(mach->cpu, 3, 0xEA); + + vm_debug_break(1); + mos6502_execute(mach->cpu); + cr_assert_eq(mach->cpu->PC, 1); + + // We should go nowhere here + mos6502_execute(mach->cpu); + cr_assert_eq(mach->cpu->PC, 1); + + // Step should a) unbreak at PC, b) execute at PC + vm_debug_cmd_step(&args); + cr_assert_eq(mach->cpu->PC, 2); +} + /* Test(vm_debug, quit) */