From d7a92f4441ebed18ebeb9fc71205493df20930f2 Mon Sep 17 00:00:00 2001 From: Kelvin Sherlock Date: Mon, 18 Mar 2019 17:06:14 -0400 Subject: [PATCH] cop/brk debugger support... cop=1 brk=1 to enable brk/cop support. cop/brk instructions will be caught *BEFORE* execution and drop into the debugger shell. step/go/next will execute the instruction as normal. %pc++ will skip over the instruction. --- src/debug_shell.re2c | 36 +++++++++++++++++++++++++++++++++++- src/defcomm.h | 4 ++++ src/instable.h | 18 ++++++++++++++---- src/sim65816.c | 4 +++- 4 files changed, 56 insertions(+), 6 deletions(-) diff --git a/src/debug_shell.re2c b/src/debug_shell.re2c index 368528b..5003e08 100644 --- a/src/debug_shell.re2c +++ b/src/debug_shell.re2c @@ -885,6 +885,36 @@ next: return 0; } +static int do_brk_cop(const char *cp, int which) { + /* brk=1 / brk=0 */ + + const char *YYCURSOR = cp; + int value = 0; + + /*!re2c + [01] eol { + value = *cp - '0'; + goto next; + } + * { return -1; } + */ +next: + + switch(which) { + case 0x00: + engine.flags &= ~FLAG_WANT_BRK; + if (value) engine.flags |= FLAG_WANT_BRK; + printf("brk intercept %s\n\n", value ? "on" : "off"); + break; + case 0x02: + engine.flags &= ~FLAG_WANT_COP; + if (value) engine.flags |= FLAG_WANT_COP; + printf("cop intercept %s\n\n", value ? "on" : "off"); + break; + } + return 0; +} + static word32 do_mem_assign(word32 addr, const char *cp) { /* "string" -> pokes ASCII chars */ /* 'string' -> pokes ASCII chars | 0x80 */ @@ -1122,6 +1152,8 @@ static int parse_command(const char *cp) { ("q" | "quit" | "exit" | "bye") eol { return 'q'; } "reset" eol { do_reset(); return 0; } ("help" | "?") eol { do_help(); return 0; } + "brk=" { return do_brk_cop(YYCURSOR, 0x00); } + "cop=" { return do_brk_cop(YYCURSOR, 0x02); } // register stuff @@ -1420,7 +1452,9 @@ int debug_shell(int code) { } printf("%06x: %0*x\n", g_abort_address, g_abort_bytes * 2, g_abort_value); } - if (code == RET_BRK) { + if (code == RET_BRK || code == RET_COP) { + /* todo -- should do this at end, verify pc/memory unchanged */ + engine.flags |= FLAG_IGNORE_BRK; /* hit a BRK op */ } if (code == RET_HALT) { diff --git a/src/defcomm.h b/src/defcomm.h index aaca6c0..849b322 100644 --- a/src/defcomm.h +++ b/src/defcomm.h @@ -100,6 +100,10 @@ #define FLAG_IGNORE_BP 0x02 #define FLAG_STEP 0x04 #define FLAG_WANT_BRK 0x08 +#define FLAG_WANT_COP 0x10 +#define FLAG_WANT_RET 0x20 +#define FLAG_WANT_JSL 0x40 +#define FLAG_IGNORE_BRK 0x80 /* and cop */ #define MODE_BORDER 0 #define MODE_TEXT 1 diff --git a/src/instable.h b/src/instable.h index bb71684..21b3c48 100644 --- a/src/instable.h +++ b/src/instable.h @@ -76,9 +76,11 @@ brk_testing_SYM #else GET_1BYTE_ARG; - if(flags & FLAG_WANT_BRK) { - CYCLES_PLUS_2; - FINISH(RET_BRK, arg); + if (flags & FLAG_WANT_BRK) { + if (~flags & FLAG_IGNORE_BRK) { + CYCLES_PLUS_2; + FINISH(RET_BRK, arg); + } } INC_KPC_2; g_num_brk++; @@ -167,8 +169,16 @@ cop_native_SYM #else - g_num_cop++; + GET_1BYTE_ARG; + + if (flags & FLAG_WANT_COP) { + if (~flags & FLAG_IGNORE_BRK) { + CYCLES_PLUS_2; + FINISH(RET_COP, arg); + } + } INC_KPC_2; + g_num_cop++; psr = psr & (~0x82); psr |= (neg << 7); diff --git a/src/sim65816.c b/src/sim65816.c index 43ba00f..1bfc7a2 100644 --- a/src/sim65816.c +++ b/src/sim65816.c @@ -1607,7 +1607,9 @@ int run_prog() { if (ret == RET_MP) break; if (ret == RET_BP) break; - engine.flags &= ~(FLAG_IGNORE_BP | FLAG_IGNORE_MP); + if (ret == RET_BRK) break; + if (ret == RET_COP) break; + engine.flags &= ~(FLAG_IGNORE_BP | FLAG_IGNORE_MP | FLAG_IGNORE_BRK); if(g_stepping) { ret = 0; break;