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)
{
}
}
-static char *parse_custom(char *p, char *d)
+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) {
- uae_u32 c = (get_cycles() - debugsprintf_cycles) / CYCLE_UNIT;
- sprintf(d, "%u", c);
+ 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 {
- strcpy(d, "-");
+ v = get_byte_debug(ptr);
+ ptr++;
}
- d += strlen(d);
+ *ptrp = ptr;
+ *sizep = size;
+ return v;
+ } else {
+ struct dsprintfstack *stack = *stackp;
+ uae_u32 v = stack->val;
+ *sizep = stack->size;
+ stack++;
+ *stackp = stack;
+ return v;
}
- return d;
}
static void debug_sprintf_do(uae_u32 s)
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++;
- char cn = *p;
if (c == 0)
break;
- if (c == '%' && cn == '%') {
- *d++ = '%';
- p++;
- } else if (c == '%') {
- if (stack >= &debugsprintf_stack[DEBUGSPRINTF_SIZE]) {
- *d++ = '[';
- *d++ = '?';
- *d++ = ']';
- } else {
- if (cn == 'b') {
- char tmp[MAX_DPATH];
- read_bstring(tmp, MAX_DPATH - 1, stack->val);
- strcpy(d, tmp);
- } else if (cn == 's') {
- char tmp[MAX_DPATH];
- read_string(tmp, MAX_DPATH - 1, stack->val);
- strcpy(d, tmp);
- } else if (cn == 'p') {
- sprintf(d, "%08x", stack->val);
- } else if (cn == 'x') {
- sprintf(d, stack->size == sz_long ? "%08x" : (stack->size == sz_word ? "%04x" : "%02x"), stack->val);
- } else if (cn == 'd') {
- sprintf(d, "%d", stack->val);
- } else if (cn == 'u') {
- sprintf(d, "%u", stack->val);
- } else if (cn == '[') {
- char *next = strchr(p, ']');
- if (next) {
- *next = 0;
- d = parse_custom(p + 1, d);
- p = next;
+ 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 {
- d[0] = '?';
- d[1] = 0;
+ gotm = false;
}
- p++;
+ } else {
+ if (fstrp - fstr < sizeof(fstr) - 1) {
+ *fstrp++ = c;
+ *fstrp = 0;
+ }
+ }
+ if (got) {
d += strlen(d);
- stack++;
+ gotm = false;
}
+ } else if (c == '%') {
+ l = false;
+ fstrp = fstr;
+ *fstrp++ = c;
+ *fstrp = 0;
+ gotm = true;
} else {
*d++ = c;
}
if (size != sz_word) {
debugsprintf_latched = 0;
}
- if (addr & 4) {
+ if ((addr & (8 | 4)) == 4) {
if (size != sz_long)
return true;
debug_sprintf_do(v);
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;
}