]> git.unchartedbackwaters.co.uk Git - francis/winuae.git/commitdiff
Debugger updates (FPU register support, help update and more)
authorToni Wilen <twilen@winuae.net>
Sat, 11 Apr 2026 13:46:05 +0000 (16:46 +0300)
committerToni Wilen <twilen@winuae.net>
Sat, 11 Apr 2026 13:46:05 +0000 (16:46 +0300)
debug.cpp
include/debug.h

index 5f7262b11653b0dbdf7c75768b23e074f2487a6f..95f56882d584a96a90f5b89916df19be93bfefb3 100644 (file)
--- a/debug.cpp
+++ b/debug.cpp
@@ -225,12 +225,12 @@ static const TCHAR help[] = {
        _T("  W <addr> 'string'     Write into Amiga memory.\n")
        _T("  Wf <addr> <endaddr-1> <bytes or string like above>, fill memory.\n")
        _T("  Wc <addr> <endaddr-1> <destaddr>, copy memory.\n")
-       _T("  w <num> <address> <length> <R/W/I> <F/C/L/N> [V<value>[.x]] (read/write/opcode) (freeze/mustchange/logonly/nobreak).\n")
+       _T("  w <num> <address> <length> <R/W/I> <F/C/L/N> [V<value>[.x]] [<channel>] (read/write/opcode) (freeze/mustchange/logonly/nobreak).\n")
        _T("                        Add/remove memory watchpoints.\n")
        _T("  wd [<0-1>]            Enable illegal access logger. 1 = enable break.\n")
        _T("  L <file> <addr> [<n>] Load a block of Amiga memory.\n")
        _T("  S <file> <addr> <n>   Save a block of Amiga memory.\n")
-       _T("  s \"<string>\"/<values> [<addr>] [<endaddr-1>]\n")
+       _T("  s \"<string>\"/<values> [<addr>] [<endaddr-1>] [max results]\n")
        _T("                        Search for string/bytes.\n")
        _T("  T or Tt               Show exec tasks and their PCs.\n")
        _T("  Td,Tl,Tr,Tp,Ts,TS,Ti,TO,TM,Tf Show devs, libs, resources, ports, semaphores,\n")
@@ -517,10 +517,11 @@ static bool iscancel (int counter)
 static bool isoperator(TCHAR **cp)
 {
        TCHAR c = _totupper(**cp);
-       TCHAR c1 = _totupper((*cp)[1]);
+       TCHAR c1 = c ? _totupper((*cp)[1]) : 0;
+       TCHAR c2 = c1 ? _totupper((*cp)[2]) : 0;
        return c == '+' || c == '-' || c == '/' || c == '*' || c == '(' || c == ')' ||
                c == '|' || c == '&' || c == '^' || c == '=' || c == '>' || c == '<' ||
-               (c == 'R' && (c1 == 'L' || c1 == 'W' || c1 == 'B'));
+               (c == 'R' && (c1 == 'L' || c1 == 'W' || c1 == 'B') && c2 == '(');
 }
 
 static void ignore_ws (TCHAR **c)
@@ -626,6 +627,34 @@ static int getoperidx(TCHAR **c, bool *opersigned)
        return -1;
 }
 
+static double f80todouble(floatx80 v)
+{
+       float_status st = { 0 };
+       union {
+               double d;
+               uae_u32 u[2];
+       } fval;
+       float64 v64 = floatx80_to_float64(v, &st);
+       fval.u[1] = v64 >> 32;
+       fval.u[0] = v64 >> 0;
+       return fval.d;
+}
+static floatx80 doubletof80(double d)
+{
+       float_status st = { 0 };
+       union {
+               double d;
+               uae_u32 u[2];
+       } fval;
+       fval.d = d;
+       return float64_to_floatx80(((uae_u64)fval.u[1] << 32) | (fval.u[0]), &st);
+}
+
+#define NUMTYTPE_S 5
+#define NUMTYTPE_D 6
+#define NUMTYTPE_X 7
+#define NUMTYTPE_P 8
+
 static const TCHAR *debugregs[] = {
        _T("D0"),
        _T("D1"),
@@ -664,6 +693,14 @@ static const TCHAR *debugregs[] = {
        _T("FPIAR"),
        _T("FPCR"),
        _T("FPSR"),
+       _T("FP0"),
+       _T("FP1"),
+       _T("FP2"),
+       _T("FP3"),
+       _T("FP4"),
+       _T("FP5"),
+       _T("FP6"),
+       _T("FP7"),
        NULL
 };
 
@@ -751,7 +788,7 @@ uae_u32 returnregx(int regid)
        return 0;
 }
 
-static int readregx(TCHAR **c, uae_u32 *valp)
+static int readregx(TCHAR **c, uae_u32 *valp, floatx80 *valx80p)
 {
        int idx;
        uae_u32 addr;
@@ -766,6 +803,15 @@ static int readregx(TCHAR **c, uae_u32 *valp)
                *c = old;
                return 0;
        }
+       if (idx >= BREAKPOINT_REG_FPx && idx < BREAKPOINT_REG_FPx + 8) {
+               int fpureg = idx - BREAKPOINT_REG_FPx;
+               if (currprefs.fpu_mode > 0) {
+                       *valx80p = regs.fp[fpureg].fpx;
+               } else {
+                       *valx80p = doubletof80(regs.fp[fpureg].fp);
+               }
+               return NUMTYTPE_X;
+       }
        addr = returnregx(idx);
        *valp = addr;
        return 1;
@@ -783,34 +829,6 @@ static bool checkisneg(TCHAR **c)
        return false;
 }
 
-static double f80todouble(floatx80 v)
-{
-       float_status st = { 0 };
-       union {
-               double d;
-               uae_u32 u[2];
-       } fval;
-       float64 v64 = floatx80_to_float64(v, &st);
-       fval.u[1] = v64 >> 32;
-       fval.u[0] = v64 >> 0;
-       return fval.d;
-}
-static floatx80 doubletof80(double d)
-{
-       float_status st = { 0 };
-       union {
-               double d;
-               uae_u32 u[2];
-       } fval;
-       fval.d = d;
-       return float64_to_floatx80(((uae_u64)fval.u[1] << 32) | (fval.u[0]), &st);
-}
-
-#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;
@@ -995,8 +1013,10 @@ static int checkvaltype2(TCHAR **c, uae_u32 *val, floatx80 *valx80, TCHAR def)
                return 2;
        }
        if (nc >= 'A' && nc <= 'Z' && nc != 'A' && nc != 'D') {
-               if (readregx(c, val))
-                       return 1;
+               int ret = readregx(c, val, valx80);
+               if (ret) {
+                       return ret;
+               }
        }
        TCHAR name[256];
        name[0] = 0;
@@ -1296,7 +1316,10 @@ static void converter(TCHAR **c)
                }
        }
        s[j] = 0;
-       if (debug_float) {
+
+       int intval = floatx80_to_int32(xf, &st);
+       floatx80 intx80 = int32_to_floatx80(intval);
+       if (debug_float || (intx80.high != xf.high || intx80.low != xf.low)) {
                uae_u64 df = floatx80_to_float64(xf, &st);
                uae_u32 sf = floatx80_to_float32(xf, &st);
                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,
@@ -4958,17 +4981,22 @@ void memwatch_dump2 (TCHAR *buf, int bufsize, int num)
        }
 }
 
-static void memwatch_dump (int num)
+static bool memwatch_dump(int num)
 {
        TCHAR *buf;
        int multiplier = num < 0 ? MEMWATCH_TOTAL : 1;
+       bool ret = false;
 
        buf = xmalloc (TCHAR, 50 * multiplier);
        if (!buf)
-               return;
-       memwatch_dump2 (buf, 50 * multiplier, num);
-       f_out (stdout, _T("%s"), buf);
+               return false;
+       memwatch_dump2(buf, 50 * multiplier, num);
+       if (buf[0]) {
+               f_out(stdout, _T("%s"), buf);
+               ret = true;
+       }
        xfree (buf);
+       return ret;
 }
 
 static void memwatch (TCHAR **c)
@@ -4977,17 +5005,23 @@ static void memwatch (TCHAR **c)
        struct memwatch_node *mwn;
        TCHAR nc, *cp;
        bool err;
+       bool enabled = false;
 
        if (!memwatch_enabled) {
                initialize_memwatch (0);
                console_out (_T("Memwatch breakpoints enabled\n"));
                memwatch_access_validator = 0;
+               enabled = true;
        }
 
        cp = *c;
        ignore_ws (c);
        if (!more_params (c)) {
-               memwatch_dump (-1);
+               if (!memwatch_dump(-1)) {
+                       if (!enabled) {
+                               console_out(_T("No memwatch breakpoints.\n"));
+                       }
+               }
                return;
        }
        nc = next_char (c);
@@ -5033,13 +5067,19 @@ static void memwatch (TCHAR **c)
        }
        *c = cp;
        num = readint(c, NULL);
-       if (num < 0 || num >= MEMWATCH_TOTAL)
+       if (num < 0 || num >= MEMWATCH_TOTAL) {
                return;
+       }
        mwn = &mwnodes[num];
+       enabled = mwn->size != 0;
        mwn->size = 0;
        ignore_ws (c);
        if (!more_params (c)) {
-               console_out_f (_T("Memwatch %d removed\n"), num);
+               if (enabled) {
+                       console_out_f (_T("Memwatch %d removed\n"), num);
+               } else {
+                       console_out_f (_T("Memwatch %d is not active\n"), num);
+               }
                memwatch_setup ();
                return;
        }
@@ -6201,9 +6241,13 @@ int instruction_breakpoint(TCHAR **c)
                        int got = 0;
                        for (i = 0; i < BREAKPOINT_TOTAL; i++) {
                                bpn = &bpnodes[i];
-                               if (!bpn->enabled)
+                               if (!bpn->enabled) {
                                        continue;
-                               console_out_f (_T("%d: %s %s %08x [%08x %08x]"), i, debugregs[bpn->type], debugoper[bpn->oper], bpn->value1, bpn->mask, bpn->value2);
+                               }
+                               console_out_f(_T("%d: %s %s %08x"), i, debugregs[bpn->type], debugoper[bpn->oper], bpn->value1);
+                               if (bpn->mask || bpn->value2) {
+                                       console_out_f (_T(" [%08x %08x]"), bpn->mask, bpn->value2);
+                               }
                                if (bpn->cnt > 0) {
                                        console_out_f(_T(" N=%d"), bpn->cnt);
                                }
@@ -6410,6 +6454,7 @@ static void searchmem (TCHAR **cc)
        }
        if (sslen == 0)
                return;
+       int max = 100;
        ignore_ws (cc);
        addr = 0xffffffff;
        endaddr = lastaddr(addr);
@@ -6419,18 +6464,22 @@ static void searchmem (TCHAR **cc)
                endaddr = lastaddr(addr);
                if (more_params(cc)) {
                        endaddr = readhex(cc, NULL);
+                       if (more_params(cc)) {
+                               max = readint(cc, NULL);
+                       }
                }
        }
-       console_out_f (_T("Searching from %08X to %08X..\n"), addr + 1, endaddr - 1);
+       console_out_f(_T("Searching from %08X to %08X..\n"), addr + 1, endaddr - 1);
        nextaddr_init(addr);
        bool out = false;
+       int colcnt = 0;
        while ((addr = nextaddr(addr, endaddr, NULL, true, &out)) != 0xffffffff) {
                if (addr == endaddr)
                        break;
                for (i = 0; i < sslen; i++) {
-                       uae_u8 b = get_byte_debug (addr + i);
+                       uae_u8 b = get_byte_debug(addr + i);
                        if (stringmode) {
-                               if (tolower (b) != ss[i])
+                               if (tolower(b) != ss[i])
                                        break;
                        } else {
                                if (b != ss[i])
@@ -6439,21 +6488,27 @@ static void searchmem (TCHAR **cc)
                }
                if (i == sslen) {
                        got++;
-                       console_out_f (_T(" %08X"), addr);
+                       colcnt++;
+                       if (colcnt > 8) {
+                               colcnt = 1;
+                               console_out_f(_T("\n"));
+                       }
+                       console_out_f(_T(" %08X"), addr);
                        out = true;
-                       if (got > 100) {
-                               console_out (_T("\nMore than 100 results, aborting.."));
+                       if (got > max) {
+                               console_out_f(_T("\nMore than %d results, aborting.."), max);
                                break;
                        }
                }
                if  (iscancel (65536)) {
-                       console_out_f (_T("Aborted at %08X\n"), addr);
+                       console_out_f(_T("Aborted at %08X\n"), addr);
                        break;
                }
        }
-       if (!got)
-               console_out (_T("nothing found"));
-       console_out (_T("\n"));
+       if (!got) {
+               console_out(_T("nothing found"));
+       }
+       console_out(_T("\n"));
 }
 
 static int staterecorder (TCHAR **cc)
@@ -6664,9 +6719,9 @@ static void debug_sprite (TCHAR **inptr)
                        console_out_f (_T("%3d %06X %s\n"), y, addr, tmp);
                }
 
-               console_out_f (_T("Sprite address %08X, width = %d\n"), saddr, size * 16);
-               console_out_f (_T("OCS: StartX=%d StartY=%d EndY=%d\n"), xpos, ypos, ypose);
-               console_out_f (_T("ECS: StartX=%d (%d.%d) StartY=%d EndY=%d%s\n"), xpos_ecs, xpos_ecs / 4, xpos_ecs & 3, ypos_ecs, ypose_ecs, ecs ? _T(" (*)") : _T(""));
+               console_out_f (_T("Sprite address %08X, Width=%d\n"), saddr, size * 16);
+               console_out_f (_T("OCS: StartX=%d StartY=%d EndY=%d Height=%d\n"), xpos, ypos, ypose, ypose - ypos + 1);
+               console_out_f (_T("ECS: StartX=%d (%d.%d) StartY=%d EndY=%d Height=%d %s\n"), xpos_ecs, xpos_ecs / 4, xpos_ecs & 3, ypos_ecs, ypose_ecs, ypose_ecs - ypos_ecs + 1, ecs ? _T(" (*)") : _T(""));
                console_out_f (_T("Attach: %d. AGA SSCAN/SH10 bit: %d\n"), attach, sh10);
 
                addr += size * 4;
index d4b172f14b75305095015d190c77be9c65e04ffe..e4614b7efd5d7f8f5515f588ba6c0389648e9672 100644 (file)
@@ -109,7 +109,8 @@ extern void debug_smc_clear(uaecptr addr, int size);
 #define BREAKPOINT_REG_FPIAR 34
 #define BREAKPOINT_REG_FPCR 35
 #define BREAKPOINT_REG_FPSR 36
-#define BREAKPOINT_REG_END 37
+#define BREAKPOINT_REG_FPx 37
+#define BREAKPOINT_REG_END 45
 
 #define BREAKPOINT_CMP_EQUAL 0
 #define BREAKPOINT_CMP_NEQUAL 1