Created
November 9, 2022 08:36
-
-
Save johngirvin/569d8393be6f81329a4caed91daf7b7f to your computer and use it in GitHub Desktop.
Patch to add 0xbfff00 debug output from WinUAE to FS-UAE at commit [bfa0c752]
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
From adfa4ea9cfbca3d1a024803613fa72ac438af9e6 Mon Sep 17 00:00:00 2001 | |
From: John Girvin <[email protected]> | |
Date: Wed, 9 Nov 2022 08:32:31 +0000 | |
Subject: [PATCH] port 0xbfff00 debug output from winuae | |
--- | |
src/cia.cpp | 20 ++++ | |
src/debug.cpp | 272 ++++++++++++++++++++++++++++++++++++++++++++ | |
src/include/debug.h | 3 + | |
3 files changed, 295 insertions(+) | |
diff --git a/src/cia.cpp b/src/cia.cpp | |
index 39c2f729..47cc7fcc 100644 | |
--- a/src/cia.cpp | |
+++ b/src/cia.cpp | |
@@ -2123,10 +2123,24 @@ static uae_u32 REGPARAM2 cia_lgeti (uaecptr addr) | |
return cia_lget (addr); | |
} | |
+static bool cia_debug(uaecptr addr, uae_u32 value, int size) | |
+{ | |
+ if (addr == DEBUG_SPRINTF_ADDRESS || addr == DEBUG_SPRINTF_ADDRESS + 4 || addr == DEBUG_SPRINTF_ADDRESS + 8 || | |
+ (addr == DEBUG_SPRINTF_ADDRESS + 2 && currprefs.cpu_model < 68020) || | |
+ (addr == DEBUG_SPRINTF_ADDRESS + 6 && currprefs.cpu_model < 68020) || | |
+ (addr == DEBUG_SPRINTF_ADDRESS + 10 && currprefs.cpu_model < 68020)) { | |
+ return debug_sprintf(addr, value, size); | |
+ } | |
+ return false; | |
+} | |
+ | |
static void REGPARAM2 cia_bput (uaecptr addr, uae_u32 value) | |
{ | |
int r = (addr & 0xf00) >> 8; | |
+ if (cia_debug(addr, value, sz_byte)) | |
+ return; | |
+ | |
if (isgarynocia(addr)) { | |
dummy_put(addr, 1, false); | |
return; | |
@@ -2165,6 +2179,9 @@ static void REGPARAM2 cia_wput (uaecptr addr, uae_u32 value) | |
{ | |
int r = (addr & 0xf00) >> 8; | |
+ if (cia_debug(addr, value, sz_word)) | |
+ return; | |
+ | |
if (isgarynocia(addr)) { | |
dummy_put(addr, 2, false); | |
return; | |
@@ -2201,6 +2218,9 @@ static void REGPARAM2 cia_wput (uaecptr addr, uae_u32 value) | |
static void REGPARAM2 cia_lput (uaecptr addr, uae_u32 value) | |
{ | |
+ if (cia_debug(addr, value, sz_long)) | |
+ return; | |
+ | |
cia_wput (addr, value >> 16); | |
cia_wput (addr + 2, value & 0xffff); | |
} | |
diff --git a/src/debug.cpp b/src/debug.cpp | |
index 03a963ab..143cbb53 100644 | |
--- a/src/debug.cpp | |
+++ b/src/debug.cpp | |
@@ -7458,3 +7458,275 @@ bool debug_trainer_event(int evt, int state) | |
} | |
return false; | |
} | |
+ | |
+#define DEBUGSPRINTF_SIZE 32 | |
+static int debugsprintf_cnt; | |
+struct dsprintfstack | |
+{ | |
+ uae_u32 val; | |
+ int size; | |
+}; | |
+static dsprintfstack debugsprintf_stack[DEBUGSPRINTF_SIZE]; | |
+static uae_u16 debugsprintf_latch, debugsprintf_latched; | |
+static uae_u32 debugsprintf_cycles, debugsprintf_cycles_set; | |
+static uaecptr debugsprintf_va; | |
+static int debugsprintf_mode; | |
+ | |
+static void read_bstring(char *out, int max, uae_u32 addr) | |
+{ | |
+ out[0] = 0; | |
+ if (!valid_address(addr, 1)) | |
+ return; | |
+ uae_u8 l = get_byte(addr); | |
+ if (l > max) | |
+ l = max; | |
+ addr++; | |
+ for (int i = 0; i < l && i < max; i++) { | |
+ uae_u8 c = 0; | |
+ if (valid_address(addr, 1)) { | |
+ c = get_byte(addr); | |
+ } | |
+ if (c == 0) { | |
+ c = '.'; | |
+ } | |
+ addr++; | |
+ out[i] = c; | |
+ out[i + 1] = 0; | |
+ } | |
+} | |
+ | |
+static void read_string(char *out, int max, uae_u32 addr) | |
+{ | |
+ out[0] = 0; | |
+ for (int i = 0; i < max; i++) { | |
+ uae_u8 c = 0; | |
+ if (valid_address(addr, 1)) { | |
+ c = get_byte(addr); | |
+ } | |
+ addr++; | |
+ out[i] = c; | |
+ out[i + 1] = 0; | |
+ if (!c) | |
+ break; | |
+ } | |
+} | |
+ | |
+static void parse_custom(char *out, int buffersize, char *format, char *p, char c) | |
+{ | |
+ bool gotv = false; | |
+ bool gots = false; | |
+ out[0] = 0; | |
+ uae_u32 v = 0; | |
+ char s[256]; | |
+ if (!strcmp(p, "CYCLES")) { | |
+ if (debugsprintf_cycles_set) { | |
+ v = (get_cycles() - debugsprintf_cycles) / CYCLE_UNIT; | |
+ } else { | |
+ v = 0xffffffff; | |
+ } | |
+ gotv = true; | |
+ } | |
+ if (gotv) { | |
+ if (c == 'x' || c == 'X' || c == 'd' || c == 'i' || c == 'u' || c == 'o') { | |
+ char *fs = format + strlen(format); | |
+ *fs++ = c; | |
+ *fs = 0; | |
+ snprintf(out, buffersize, format, v); | |
+ } else { | |
+ strcpy(s, "****"); | |
+ gots = true; | |
+ } | |
+ } | |
+ if (gots) { | |
+ char *fs = format + strlen(format); | |
+ *fs++ = 's'; | |
+ *fs = 0; | |
+ snprintf(out, buffersize, format, s); | |
+ } | |
+} | |
+ | |
+static uae_u32 get_value(struct dsprintfstack **stackp, uae_u32 *sizep, uaecptr *ptrp, uae_u32 size) | |
+{ | |
+ if (debugsprintf_mode) { | |
+ uae_u32 v; | |
+ uaecptr ptr = *ptrp; | |
+ if (size == sz_long) { | |
+ v = get_long_debug(ptr); | |
+ ptr += 4; | |
+ } else if (size == sz_word) { | |
+ v = get_word_debug(ptr); | |
+ ptr += 2; | |
+ } else { | |
+ v = get_byte_debug(ptr); | |
+ ptr++; | |
+ } | |
+ *ptrp = ptr; | |
+ *sizep = size; | |
+ return v; | |
+ } else { | |
+ struct dsprintfstack *stack = *stackp; | |
+ uae_u32 v = stack->val; | |
+ if (stack->size == 0) | |
+ v &= 0xff; | |
+ else if (stack->size == 1) | |
+ v &= 0xffff; | |
+ if (size == 1) | |
+ v &= 0xffff; | |
+ *sizep = size; | |
+ stack++; | |
+ *stackp = stack; | |
+ return v; | |
+ } | |
+} | |
+ | |
+static void debug_sprintf_do(uae_u32 s) | |
+{ | |
+ int cnt = 0; | |
+ char format[MAX_DPATH]; | |
+ char out[MAX_DPATH]; | |
+ read_string(format, MAX_DPATH - 1, s); | |
+ char *p = format; | |
+ char *d = out; | |
+ bool gotm = false; | |
+ bool l = false; | |
+ uaecptr ptr = debugsprintf_va; | |
+ struct dsprintfstack *stack = debugsprintf_stack; | |
+ char fstr[100], *fstrp; | |
+ int buffersize = MAX_DPATH - 1; | |
+ fstrp = fstr; | |
+ *d = 0; | |
+ for (;;) { | |
+ char c = *p++; | |
+ if (c == 0) | |
+ break; | |
+ if (gotm) { | |
+ bool got = false; | |
+ buffersize = MAX_DPATH - strlen(out); | |
+ if (buffersize <= 1) | |
+ break; | |
+ if (c == '%') { | |
+ *d++ = '%'; | |
+ gotm = false; | |
+ } else if (c == 'l') { | |
+ l = true; | |
+ } else if (c == 'c') { | |
+ uae_u32 size; | |
+ uae_u32 val = get_value(&stack, &size, &ptr, l ? sz_long : sz_word); | |
+ *fstrp++ = c; | |
+ *fstrp = 0; | |
+ snprintf(d, buffersize, fstr, val); | |
+ got = true; | |
+ } else if (c == 'b') { | |
+ uae_u32 size; | |
+ uae_u32 val = get_value(&stack, &size, &ptr, sz_long); | |
+ char tmp[MAX_DPATH]; | |
+ read_bstring(tmp, MAX_DPATH - 1, val); | |
+ *fstrp++ = 's'; | |
+ *fstrp = 0; | |
+ snprintf(d, buffersize, fstr, tmp); | |
+ got = true; | |
+ } else if (c == 's') { | |
+ uae_u32 size; | |
+ uae_u32 val = get_value(&stack, &size, &ptr, sz_long); | |
+ char tmp[MAX_DPATH]; | |
+ read_string(tmp, MAX_DPATH - 1, val); | |
+ *fstrp++ = c; | |
+ *fstrp = 0; | |
+ snprintf(d, buffersize, fstr, tmp); | |
+ got = true; | |
+ } else if (c == 'p') { | |
+ uae_u32 size; | |
+ uae_u32 val = get_value(&stack, &size, &ptr, sz_long); | |
+ snprintf(d, buffersize, "$%08x", val); | |
+ got = true; | |
+ } else if (c == 'x' || c == 'X' || c == 'd' || c == 'i' || c == 'u' || c == 'o') { | |
+ uae_u32 size; | |
+ uae_u32 val = get_value(&stack, &size, &ptr, l ? sz_long : sz_word); | |
+ if (c == 'd' || c == 'i') { | |
+ if (size == sz_word && (val & 0x8000)) { | |
+ val = (uae_s32)(uae_s16)val; | |
+ } | |
+ } | |
+ *fstrp++ = c; | |
+ *fstrp = 0; | |
+ snprintf(d, buffersize, fstr, val); | |
+ got = true; | |
+ } else if (c == '[') { | |
+ char *next = strchr(p, ']'); | |
+ if (next && next[1]) { | |
+ char customout[MAX_DPATH]; | |
+ customout[0] = 0; | |
+ *next = 0; | |
+ parse_custom(d, buffersize, fstr, p, next[1]); | |
+ p = next + 2; | |
+ got = true; | |
+ } else { | |
+ gotm = false; | |
+ } | |
+ } else { | |
+ if (fstrp - fstr < sizeof(fstr) - 1) { | |
+ *fstrp++ = c; | |
+ *fstrp = 0; | |
+ } | |
+ } | |
+ if (got) { | |
+ d += strlen(d); | |
+ gotm = false; | |
+ } | |
+ } else if (c == '%') { | |
+ l = false; | |
+ fstrp = fstr; | |
+ *fstrp++ = c; | |
+ *fstrp = 0; | |
+ gotm = true; | |
+ } else { | |
+ *d++ = c; | |
+ } | |
+ *d = 0; | |
+ } | |
+ // write_log("%s", out); | |
+ fprintf(stderr, "%s\n", out); | |
+} | |
+ | |
+bool debug_sprintf(uaecptr addr, uae_u32 val, int size) | |
+{ | |
+ uae_u32 v = val; | |
+ if (size == sz_word && currprefs.cpu_model < 68020) { | |
+ v &= 0xffff; | |
+ if (!(addr & 2)) { | |
+ debugsprintf_latch = v; | |
+ debugsprintf_latched = 1; | |
+ } else if (debugsprintf_latched) { | |
+ v |= debugsprintf_latch << 16; | |
+ size = sz_long; | |
+ if (!(addr & 4) && debugsprintf_cnt > 0) { | |
+ debugsprintf_cnt--; | |
+ } | |
+ } | |
+ } | |
+ if (size != sz_word) { | |
+ debugsprintf_latched = 0; | |
+ } | |
+ if ((addr & (8 | 4)) == 4) { | |
+ if (size != sz_long) | |
+ return true; | |
+ debug_sprintf_do(v); | |
+ debugsprintf_cnt = 0; | |
+ debugsprintf_latched = 0; | |
+ debugsprintf_cycles = get_cycles(); | |
+ debugsprintf_cycles_set = 1; | |
+ } else if ((addr & (8 | 4)) == 8) { | |
+ if (size != sz_long) | |
+ return true; | |
+ debugsprintf_va = val; | |
+ debugsprintf_mode = 1; | |
+ } else { | |
+ if (debugsprintf_cnt < DEBUGSPRINTF_SIZE) { | |
+ debugsprintf_stack[debugsprintf_cnt].val = v; | |
+ debugsprintf_stack[debugsprintf_cnt].size = size; | |
+ debugsprintf_cnt++; | |
+ } | |
+ debugsprintf_mode = 0; | |
+ } | |
+ return true; | |
+} | |
diff --git a/src/include/debug.h b/src/include/debug.h | |
index 0c948603..23d32907 100644 | |
--- a/src/include/debug.h | |
+++ b/src/include/debug.h | |
@@ -70,6 +70,9 @@ extern void debug_trainer_match(void); | |
extern bool debug_opcode_watch; | |
extern bool debug_trainer_event(int evt, int state); | |
+#define DEBUG_SPRINTF_ADDRESS 0xbfff00 | |
+extern bool debug_sprintf(uaecptr, uae_u32, int); | |
+ | |
#define BREAKPOINT_TOTAL 20 | |
#define BREAKPOINT_REG_Dx 0 | |
#define BREAKPOINT_REG_Ax 8 | |
-- | |
2.37.0 | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment