]> git.unchartedbackwaters.co.uk Git - francis/winuae.git/commitdiff
Debugger ?-command 6888x floating point format support
authorToni Wilen <twilen@winuae.net>
Sat, 28 Mar 2026 14:15:17 +0000 (16:15 +0200)
committerToni Wilen <twilen@winuae.net>
Sat, 28 Mar 2026 14:15:17 +0000 (16:15 +0200)
debug.cpp

index e4058c6a4b61f1565a421dc8bd06c09eae8b092a..f7c7b80b534db3bc68610faaf4d1d079f6236a20 100644 (file)
--- 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 [<ratio> <lines>]  \"Heat map\"\n")
        _T("  I <custom event>      Send custom event string\n")
-       _T("  ?<value>              Hex ($ and 0x)/Bin (%)/Dec (!) converter and calculator.\n")
+       _T("  ?<value>              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)