Skip to content

Instantly share code, notes, and snippets.

@johngirvin
Created November 9, 2022 08:36
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save johngirvin/569d8393be6f81329a4caed91daf7b7f to your computer and use it in GitHub Desktop.
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]
From adfa4ea9cfbca3d1a024803613fa72ac438af9e6 Mon Sep 17 00:00:00 2001
From: John Girvin <john@sixecho.com>
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