From: Toni Wilen Date: Sat, 28 Mar 2026 14:15:17 +0000 (+0200) Subject: Debugger ?-command 6888x floating point format support X-Git-Url: https://git.unchartedbackwaters.co.uk/w/?a=commitdiff_plain;h=138b0a8770bd990b009426e7a4fdd936c1251026;p=francis%2Fwinuae.git Debugger ?-command 6888x floating point format support --- diff --git a/debug.cpp b/debug.cpp index e4058c6a..f7c7b80b 100644 --- a/debug.cpp +++ b/debug.cpp @@ -249,7 +249,7 @@ static const TCHAR help[] = { _T(" v [-2 to -5] = enable visual DMA debugger.\n") _T(" vh [ ] \"Heat map\"\n") _T(" I Send custom event string\n") - _T(" ? Hex ($ and 0x)/Bin (%)/Dec (!) converter and calculator.\n") + _T(" ? Hex ($, 0x)/Bin (%)/Dec (!) converter and calculator. Prefix floats with f.\n") #ifdef _WIN32 _T(" x Close debugger.\n") _T(" xx Switch between console and GUI debugger.\n") @@ -783,6 +783,11 @@ static bool checkisneg(TCHAR **c) return false; } +#define NUMTYTPE_S 5 +#define NUMTYTPE_D 6 +#define NUMTYTPE_X 7 +#define NUMTYTPE_P 8 + static bool readbinx (TCHAR **c, uae_u32 *valp) { uae_u32 val = 0; @@ -821,7 +826,8 @@ static bool readhexx (TCHAR **c, uae_u32 *valp) negative = checkisneg(c); if (!isxdigit(peekchar(c))) return false; - while (isxdigit (nc = **c)) { + int max = 8; + while (isxdigit (nc = **c) && max-- > 0) { (*c)++; val *= 16; nc = _totupper (nc); @@ -854,35 +860,100 @@ static bool readintx (TCHAR **c, uae_u32 *valp) return true; } -static int checkvaltype2 (TCHAR **c, uae_u32 *val, TCHAR def) +static int checkvaltype2(TCHAR **c, uae_u32 *val, floatx80 *valx80, TCHAR def) { TCHAR nc; - ignore_ws (c); - nc = _totupper (**c); + ignore_ws(c); + + // check for floating point formats + TCHAR *cp = *c; + for (;;) { + nc = *cp++; + TCHAR nc2 = _totupper (*cp); + if (!nc || _istspace(nc)) { + break; + } + if (nc == '.' && (nc2 == 'S' || nc2 == 'D' || nc2 == 'X')) { + float_status st = { 0 }; + nc = _totupper(**c); + if (nc == '$') { + (*c)++; + } + if (nc == '0' && _totupper((*c)[1]) == 'X') { + (*c) += 2; + } + if (nc2 == 'S') { + if (readhexx(c, val)) { + *valx80 = float32_to_floatx80(*val, &st); + return NUMTYTPE_S; + } + } + if (nc2 == 'D') { + uae_u32 val2; + if (readhexx(c, val)) { + if (readhexx(c, &val2)) { + *valx80 = float64_to_floatx80((((uae_u64)(*val)) << 32) | val2, &st); + return NUMTYTPE_D; + } + } + } + if (nc2 == 'X') { + uae_u32 val1; + uae_u32 val2, val3; + if (readhexx(c, &val1)) { + if (peekchar(c) == '.') { + (*c)++; + } + if (readhexx(c, &val2)) { + if (readhexx(c, &val3)) { + valx80->high = val1; + valx80->low = ((uae_u64)val2 << 32) | val3; + return NUMTYTPE_X; + } + } + } + } + return 0; + } + } + + nc = _totupper(**c); if (nc == '!') { (*c)++; - return readintx (c, val) ? 1 : 0; + return readintx(c, val) ? 1 : 0; } if (nc == '$') { (*c)++; - return readhexx (c, val) ? 1 : 0; + return readhexx(c, val) ? 1 : 0; } if (nc == '0' && _totupper ((*c)[1]) == 'X') { (*c)+= 2; - return readhexx (c, val) ? 1 : 0; + return readhexx(c, val) ? 1 : 0; } if (nc == '%') { (*c)++; - return readbinx (c, val) ? 1: 0; + return readbinx(c, val) ? 1: 0; + } + if (nc == 'F') { + union { + double d; + uae_u32 u[2]; + } val; + (*c)++; + float_status st = { 0 }; + double dval = _wtof(*c); + val.d = dval; + *valx80 = float64_to_floatx80(((uae_u64)val.u[1] << 32) | (val.u[0]), &st); + return 2; } if (nc >= 'A' && nc <= 'Z' && nc != 'A' && nc != 'D') { - if (readregx (c, val)) + if (readregx(c, val)) return 1; } TCHAR name[256]; name[0] = 0; - for (int i = 0; i < sizeof name / sizeof(TCHAR) - 1; i++) { + for (int i = 0; i < sizeof(name) / sizeof(TCHAR) - 1; i++) { nc = (*c)[i]; if (nc == 0 || nc == ' ') break; @@ -899,11 +970,11 @@ static int checkvaltype2 (TCHAR **c, uae_u32 *val, TCHAR def) } } if (def == '!') { - return readintx (c, val) ? -1 : 0; + return readintx(c, val) ? -1 : 0; } else if (def == '$') { - return readhexx (c, val) ? -1 : 0; + return readhexx(c, val) ? -1 : 0; } else if (def == '%') { - return readbinx (c, val) ? -1 : 0; + return readbinx(c, val) ? -1 : 0; } return 0; } @@ -919,15 +990,26 @@ static int readsize (int val, TCHAR **c) return 3; if (cc == 'L') return 4; + if (cc == 'S') + return NUMTYTPE_S; + if (cc == 'D') + return NUMTYTPE_D; + if (cc == 'X') + return NUMTYTPE_X; + if (cc == 'P') + return NUMTYTPE_P; return 0; } -static int checkvaltype(TCHAR **cp, uae_u32 *val, int *size, TCHAR def) +static int checkvaltype(TCHAR **cp, uae_u32 *val, floatx80 *valx80, int *size, TCHAR def) { TCHAR form[256], *p; bool gotop = false; bool copyrest = false; double out; + int sizetype = -1; + TCHAR *startp = NULL; + floatx80 vx80 = { 0 }; form[0] = 0; if (size) @@ -935,15 +1017,26 @@ static int checkvaltype(TCHAR **cp, uae_u32 *val, int *size, TCHAR def) p = form; for (;;) { uae_u32 v; - if (!checkvaltype2(cp, &v, def)) { + int ret = checkvaltype2(cp, &v, &vx80, def); + if (!ret) { if (isoperator(cp) || gotop || **cp == '\"' || **cp == '\'') { goto docalc; } return 0; } - *val = v; - // stupid but works! - _stprintf(p, _T("%u"), v); + if (ret == 1 || ret == -1) { + *val = v; + // stupid but works! + _stprintf(p, _T("%u"), v); + } else { + *val = 0; + *valx80 = vx80; + *p = 0; + if (size) { + *size = NUMTYTPE_X; + } + return -1; + } p += _tcslen (p); *p = 0; if (peekchar(cp) == '.') { @@ -1005,44 +1098,80 @@ docalc: return 0; } +struct numdata +{ + bool x80; + uae_u32 val; + floatx80 valx80; +}; -static uae_u32 readnum(TCHAR **c, int *size, TCHAR def, bool *err) +static void readnum(struct numdata *nd, TCHAR **c, int *size, TCHAR def, bool *err) { uae_u32 val; + floatx80 valx80; + nd->val = 0; + nd->valx80.high = 0; + nd->valx80.low = 0; + nd->x80 = false; if (err) { *err = 0; } - if (checkvaltype(c, &val, size, def)) { - return val; + int ret = checkvaltype(c, &val, &valx80, size, def); + if (ret > 0) { + nd->x80 = false; + nd->val = val; + return; + } else if (ret < 0) { + nd->x80 = true; + nd->valx80 = valx80; + return; } if (err) { *err = 1; } - return 0; } +static bool readintx(TCHAR **c, bool *err, uae_u32 *val, floatx80 *valx80) +{ + int size; + struct numdata nd; + readnum(&nd, c, &size, '!', err); + *valx80 = nd.valx80; + *val = nd.val; + return nd.x80; +} static uae_u32 readint(TCHAR **c, bool *err) { int size; - return readnum(c, &size, '!', err); + struct numdata nd; + readnum(&nd, c, &size, '!', err); + return nd.val; } static uae_u32 readhex(TCHAR **c, bool *err) { int size; - return readnum(c, &size, '$', err); + struct numdata nd; + readnum(&nd, c, &size, '$', err); + return nd.val; } static uae_u32 readbin(TCHAR **c, bool *err) { int size; - return readnum(c, &size, '%', err); + struct numdata nd; + readnum(&nd, c, &size, '%', err); + return nd.val; } static uae_u32 readint(TCHAR **c, int *size, bool *err) { - return readnum(c, size, '!', err); + struct numdata nd; + readnum(&nd, c, size, '!', err); + return nd.val; } static uae_u32 readhex(TCHAR **c, int *size, bool *err) { - return readnum(c, size, '$', err); + struct numdata nd; + readnum(&nd, c, size, '$', err); + return nd.val; } static size_t next_string (TCHAR **c, TCHAR *out, int max, int forceupper) @@ -1080,14 +1209,44 @@ static size_t next_string (TCHAR **c, TCHAR *out, int max, int forceupper) static void converter(TCHAR **c) { - bool err; - uae_u32 v = readint(c, &err); TCHAR s[100]; - int i, j; + float_status st = { 0 }; + bool err = false; + uae_u32 v = 0; + floatx80 xf = { 0 }; + + if (_totupper(peekchar(c)) == 'F') { + float_status st = { 0 }; + struct numdata nd; + int size; + readnum(&nd, c, &size, 0, &err); + v = floatx80_to_int32_round_to_zero(nd.valx80, &st); + xf = nd.valx80; + + } else { + if (!readintx(c, &err, &v, &xf)) { + xf = int32_to_floatx80(v); + } else { + v = floatx80_to_int32(xf, &st); + } + } if (err) { return; } + + uae_u64 df = floatx80_to_float64(xf, &st); + uae_u32 sf = floatx80_to_float32(xf, &st); + + // NOTE: output decimal value is currently always double, even if input was extended. + union { + double d; + uae_u32 u[2]; + } val; + val.u[1] = df >> 32; + val.u[0] = df >> 0; + + int i, j; for (i = 0, j = 0; i < 32; i++) { s[j++] = (v & (1 << (31 - i))) ? '1' : '0'; if (i < 31 && (i & 7) == 7) { @@ -1095,7 +1254,9 @@ static void converter(TCHAR **c) } } s[j] = 0; - console_out_f (_T("$%08X = %%%s = %u = %d\n"), v, s, v, (uae_s32)v); + console_out_f(_T("$%08X = %%%s = %u = %d ($%08X.S = $%08X%08X.D = $%04X.%08X%08X.X = %f)\n"), v, s, v, (uae_s32)v, + sf, (uae_u32)(df >> 32), (uae_u32)df, (uae_u32)(xf.high), (uae_u32)(xf.low >> 32), (uae_u32)xf.low, + val.d); } static bool isrom(uaecptr addr)