]> git.unchartedbackwaters.co.uk Git - francis/winuae.git/commitdiff
More detailed error output, now also includes source, destination and stack contents...
authorToni Wilen <twilen@winuae.net>
Sat, 28 Sep 2019 07:18:55 +0000 (10:18 +0300)
committerToni Wilen <twilen@winuae.net>
Sat, 28 Sep 2019 07:18:55 +0000 (10:18 +0300)
cputest.cpp
cputest/cputest_defines.h
cputest/main.c
cputest/readme.txt
disasm.cpp

index 5d53b26a086ba457802a3da1a8346b4322a2f794..fd08746b87420aae10200c06d628f07686cc451d 100644 (file)
@@ -1225,7 +1225,7 @@ static void save_data(uae_u8 *dst, const TCHAR *dir)
        }
        if (filecount == 0) {
                uae_u8 data[4];
-               pl(data, 0x00000002);
+               pl(data, DATA_VERSION);
                fwrite(data, 1, 4, f);
                pl(data, (uae_u32)starttime);
                fwrite(data, 1, 4, f);
@@ -1255,7 +1255,7 @@ static void save_data(uae_u8 *dst, const TCHAR *dir)
                save_data(dst, dir);
        } else {
                uae_u8 data[4];
-               pl(data, 0x00000002);
+               pl(data, DATA_VERSION);
                fwrite(data, 1, 4, f);
                pl(data, (uae_u32)starttime);
                fwrite(data, 1, 4, f);
@@ -2315,6 +2315,11 @@ static void test_mnemo(const TCHAR *path, const TCHAR *mnemo, const TCHAR *ovrfi
                }
                regs.sr = feature_min_interrupt_mask << 8;
 
+               uae_u32 srcaddr_old = 0xffffffff;
+               uae_u32 dstaddr_old = 0xffffffff;
+               uae_u32 srcaddr = 0xffffffff;
+               uae_u32 dstaddr = 0xffffffff;
+
                for (int opcode = 0; opcode < 65536; opcode++) {
 
                        struct instr *dp = table68k + opcode;
@@ -2488,7 +2493,6 @@ static void test_mnemo(const TCHAR *path, const TCHAR *mnemo, const TCHAR *ovrfi
 
 
                                        TCHAR out[256];
-                                       uaecptr srcaddr, dstaddr;
                                        memset(out, 0, sizeof(out));
                                        // disassemble and output generated instruction
                                        for (int i = 0; i < MAX_REGISTERS; i++) {
@@ -2498,6 +2502,8 @@ static void test_mnemo(const TCHAR *path, const TCHAR *mnemo, const TCHAR *ovrfi
                                                regs.fp[i].fpx = cur_fpuregisters[i];
                                        }
                                        uaecptr nextpc;
+                                       srcaddr = 0xffffffff;
+                                       dstaddr = 0xffffffff;
                                        m68k_disasm_2(out, sizeof(out) / sizeof(TCHAR), opcode_memory_start, &nextpc, 1, &srcaddr, &dstaddr, 0xffffffff, 0);
                                        if (verbose) {
                                                my_trim(out);
@@ -2556,6 +2562,15 @@ static void test_mnemo(const TCHAR *path, const TCHAR *mnemo, const TCHAR *ovrfi
                                                testing_active = 0;
                                        }
 
+                                       if (srcaddr != srcaddr_old) {
+                                               dst = store_reg(dst, CT_SRCADDR, srcaddr_old, srcaddr, -1);
+                                               srcaddr_old = srcaddr;
+                                       }
+                                       if (dstaddr != dstaddr_old) {
+                                               dst = store_reg(dst, CT_DSTADDR, dstaddr_old, dstaddr, -1);
+                                               dstaddr_old = dstaddr;
+                                       }
+
                                        *dst++ = CT_END_INIT;
 
                                        int exception_array[256] = { 0 };
index 9f332d9034a9c403e618ee60a1c98b62d7a73a99..d1a1d68e84250c585f984312414c16e358a67766 100644 (file)
@@ -1,4 +1,6 @@
 
+#define DATA_VERSION 3
+
 #define CT_FPREG 0
 #define CT_DREG 0
 #define CT_AREG 8
@@ -9,6 +11,8 @@
 #define CT_FPIAR 20
 #define CT_FPSR 21
 #define CT_FPCR 22
+#define CT_SRCADDR 28
+#define CT_DSTADDR 29
 #define CT_MEMWRITE 30
 #define CT_MEMWRITES 31
 #define CT_DATA_MASK 31
index 9b2315bfb856e3ba92f83b9f2d76814e0714e017..e4c80548a2961d6f3674894bcef7f517e18c51a9 100644 (file)
@@ -45,6 +45,7 @@ struct registers
        uae_u32 excframe;
        struct fpureg fpuregs[8];
        uae_u32 fpiar, fpcr, fpsr;
+       uae_u32 srcaddr, dstaddr;
 };
 
 static struct registers test_regs;
@@ -59,7 +60,7 @@ static int high_memory_size;
 static uae_u32 test_low_memory_start, test_low_memory_end;
 static uae_u32 test_high_memory_start, test_high_memory_end;
 static uae_u8 *test_memory;
-static uae_u32 test_memory_addr;
+static uae_u32 test_memory_addr, test_memory_end;
 static uae_u32 test_memory_size;
 static uae_u8 *test_data;
 static int test_data_size;
@@ -106,6 +107,12 @@ static uae_u8 ccr_mask;
 static uae_u32 addressing_mask = 0x00ffffff;
 static uae_u32 interrupt_mask;
 
+#define SIZE_STORED_ADDRESS 20
+static uae_u8 srcaddr[SIZE_STORED_ADDRESS];
+static uae_u8 dstaddr[SIZE_STORED_ADDRESS];
+static uae_u8 stackaddr[SIZE_STORED_ADDRESS];
+static uae_u32 stackaddr_ptr;
+
 #ifndef M68K
 
 #define xmemcpy memcpy
@@ -670,7 +677,13 @@ static uae_u8 *restore_data(uae_u8 *p)
                exit(0);
        }
        int mode = v & CT_DATA_MASK;
-       if (mode < CT_AREG + 8) {
+       if (mode == CT_SRCADDR) {
+               int size;
+               p = restore_value(p, &regs.srcaddr, &size);
+       } else if (mode == CT_DSTADDR) {
+               int size;
+               p = restore_value(p, &regs.dstaddr, &size);
+       } else if (mode < CT_AREG + 8) {
                int size;
                if ((v & CT_SIZE_MASK) == CT_SIZE_FPU) {
                        p = restore_fpvalue(p, &regs.fpuregs[mode]);
@@ -703,9 +716,48 @@ static uae_u8 *restore_data(uae_u8 *p)
        return p;
 }
 
-static uae_u16 test_ccrignoremask;
+static uae_u16 test_sr, test_ccrignoremask;
 static uae_u32 test_fpsr, test_fpcr;
 
+
+static int is_valid_test_addr(uae_u32 a)
+{
+       return (a >= test_low_memory_start && a < test_low_memory_end && test_low_memory_start != 0xffffffff) ||
+               (a >= test_high_memory_start && a < test_high_memory_end && test_high_memory_start != 0xffffffff) ||
+               (a >= test_memory_addr && a < test_memory_end);
+}
+
+static int addr_diff(uae_u8 *ap, uae_u8 *bp, int size)
+{
+       for (int i = 0; i < size; i++) {
+               if (is_valid_test_addr((uae_u32)bp)) {
+                       if (*ap != *bp)
+                               return 1;
+               }
+               ap++;
+               bp++;
+       }
+       return 0;
+}
+
+static void addinfo_bytes(char *name, uae_u8 *src, uae_u32 address, int offset, int len)
+{
+       sprintf(outbp, "%s: %08lx ", name, address);
+       outbp += strlen(outbp);
+       int cnt = 0;
+       while (len-- > 0) {
+               if (offset == 0)
+                       *outbp++ = '*';
+               else if (cnt > 0)
+                       *outbp++ = '.';
+               sprintf(outbp, "%02x", src[cnt]);
+               outbp += 2;
+               offset++;
+               cnt++;
+       }
+       *outbp++ = '\n';
+}
+
 extern uae_u16 disasm_instr(uae_u16 *, char *);
 
 static void addinfo(void)
@@ -732,6 +784,7 @@ static void addinfo(void)
        int offset = 0;
        int lines = 0;
        while (lines++ < 10) {
+               tmpbuffer[0] = 0;
                int v = disasm_instr(code + offset, tmpbuffer);
                for (int i = 0; i < v; i++) {
                        uae_u16 v = (p[i * 2 + 0] << 8) | (p[i * 2 + 1]);
@@ -754,8 +807,27 @@ static void addinfo(void)
                if (v < 0)
                        break;
        }
-       *outbp++ = '\n';
        *outbp = 0;
+       if (code[0] == 0x4e73 || code[0] == 0x4e74 || code[0] == 0x4e75) {
+               addinfo_bytes("SA", stackaddr, stackaddr_ptr, -SIZE_STORED_ADDRESS / 2, SIZE_STORED_ADDRESS);
+               addinfo_bytes("  ", (uae_u8 *)stackaddr_ptr - SIZE_STORED_ADDRESS / 2, stackaddr_ptr, -SIZE_STORED_ADDRESS / 2, SIZE_STORED_ADDRESS);
+       }
+       if (regs.srcaddr != 0xffffffff) {
+               uae_u8 *a = srcaddr;
+               uae_u8 *b = (uae_u8 *)regs.srcaddr - SIZE_STORED_ADDRESS / 2;
+               addinfo_bytes("SA", a, regs.srcaddr, -SIZE_STORED_ADDRESS / 2, SIZE_STORED_ADDRESS);
+               if (addr_diff(a, b, SIZE_STORED_ADDRESS)) {
+                       addinfo_bytes("  ", b, regs.srcaddr, -SIZE_STORED_ADDRESS / 2, SIZE_STORED_ADDRESS);
+               }
+       }
+       if (regs.dstaddr != 0xffffffff) {
+               uae_u8 *a = dstaddr;
+               uae_u8 *b = (uae_u8*)regs.dstaddr - SIZE_STORED_ADDRESS / 2;
+               addinfo_bytes("DA", a, regs.dstaddr, -SIZE_STORED_ADDRESS / 2, SIZE_STORED_ADDRESS);
+               if (addr_diff(a, b, SIZE_STORED_ADDRESS)) {
+                       addinfo_bytes("  ", b, regs.dstaddr, -SIZE_STORED_ADDRESS / 2, SIZE_STORED_ADDRESS);
+               }
+       }
 
 #if 0
 int    Disass68k(long addr, char *labelBuffer, char *opcodeBuffer, char *operandBuffer, char *commentBuffer);
@@ -788,24 +860,56 @@ static const struct srbit srbits[] = {
 
 static void out_regs(struct registers *r, int before)
 {
-       for (int i = 0; i < 16; i++) {
-               if (i > 0 && (i % 4) == 0) {
-                       strcat(outbp, "\n");
-               } else if ((i % 8) != 0) {
-                       strcat(outbp, " ");
+       if (before) {
+               for (int i = 0; i < 16; i++) {
+                       if (i > 0 && (i % 4) == 0) {
+                               strcat(outbp, "\n");
+                       } else if ((i % 8) != 0) {
+                               strcat(outbp, " ");
+                       }
+                       outbp += strlen(outbp);
+                       sprintf(outbp, "%c%d:%c%08lx", i < 8 ? 'D' : 'A', i & 7, test_regs.regs[i] != regs.regs[i] ? '*' : ' ', r->regs[i]);
+                       outbp += strlen(outbp);
+               }
+               *outbp++ = '\n';
+       } else {
+               // output only lines that have at least one modified register to save screen space
+               int outdone = 0;
+               for (int i = 0; i < 4; i++) {
+                       int diff = 0;
+                       for (int j = 0; j < 4; j++) {
+                               int idx = i * 4 + j;
+                               if (test_regs.regs[idx] != regs.regs[idx]) {
+                                       diff = 1;
+                                       outdone = 1;
+                               }
+                       }
+                       if (diff) {
+                               for (int j = 0; j < 4; j++) {
+                                       int idx = i * 4 + j;
+                                       if (j > 0)
+                                               *outbp++ = ' ';
+                                       sprintf(outbp, "%c%d:%c%08lx", idx < 8 ? 'D' : 'A', idx & 7, test_regs.regs[idx] != regs.regs[idx] ? '*' : ' ', r->regs[idx]);
+                                       outbp += strlen(outbp);
+                               }
+                       }
+               }
+               if (outdone) {
+                       *outbp++ = '\n';
                }
-               outbp += strlen(outbp);
-               sprintf(outbp, "%c%d:%c%08lx", i < 8 ? 'D' : 'A', i & 7, test_regs.regs[i] != regs.regs[i] ? '*' : ' ', r->regs[i]);
-               outbp += strlen(outbp);
        }
-       strcat(outbp, "\n");
        outbp += strlen(outbp);
-       sprintf(outbp, "SR:%c%04x   PC: %08lx ISP: %08lx MSP: %08lx\n",
-               test_regs.sr != last_registers.sr ? '*' : ' ', before ? regs.sr : test_regs.sr,
-               r->pc, r->ssp, r->msp);
+       sprintf(outbp, "SR:%c%04x   PC: %08lx ISP: %08lx", test_sr != last_registers.sr ? '*' : ' ', before ? test_sr : test_regs.sr, r->pc, r->ssp);
+       outbp += strlen(outbp);
+       if (cpu_lvl >= 2 && cpu_lvl <= 4) {
+               sprintf(outbp, " MSP: %08lx\n", r->msp);
+               outbp += strlen(outbp);
+       }
+       *outbp++ = '\n';
+
        outbp += strlen(outbp);
        if (before >= 0) {
-               uae_u16 s = before ? regs.sr : test_regs.sr; // current value
+               uae_u16 s = before ? test_sr : test_regs.sr; // current value
                uae_u16 s1 = regs.sr; // original value
                uae_u16 s2 = test_regs.sr; // test result value
                uae_u16 s3 = last_registers.sr; // expected result value
@@ -1111,7 +1215,7 @@ static uae_u8 *validate_test(uae_u8 *p, int ignore_errors, int ignore_sr)
                        if ((val & (sr_undefined_mask & test_ccrignoremask)) != (test_regs.sr & (sr_undefined_mask & test_ccrignoremask)) && !ignore_errors && !ignore_sr) {
                                addinfo();
                                if (dooutput) {
-                                       sprintf(outbp, "SR: expected %04x -> %04x but got %04x (%04x)\n", regs.sr & 0xffff, val & 0xffff, test_regs.sr & 0xffff, test_ccrignoremask);
+                                       sprintf(outbp, "SR: expected %04x -> %04x but got %04x (%04x)\n", test_sr & 0xffff, val & 0xffff, test_regs.sr & 0xffff, test_ccrignoremask);
                                        outbp += strlen(outbp);
                                }
                                errors++;
@@ -1216,7 +1320,7 @@ static uae_u8 *validate_test(uae_u8 *p, int ignore_errors, int ignore_sr)
                        }
                } else {
                        end_test();
-                       printf("Unknown test data %02x\n", v);
+                       printf("Unknown test data %02x mode %d\n", v, mode);
                        exit(0);
                }
        }
@@ -1310,6 +1414,20 @@ static uae_u8 *validate_test(uae_u8 *p, int ignore_errors, int ignore_sr)
        return p;
 }
 
+static void store_addr(uae_u32 s, uae_u8 *d)
+{
+       if (s == 0xffffffff)
+               return;
+       for (int i = -SIZE_STORED_ADDRESS / 2; i < SIZE_STORED_ADDRESS / 2; i++) {
+               uae_u32 ss = s + i;
+               if (is_valid_test_addr(ss)) {
+                       *d++ = *((uae_u8 *)ss);
+               } else {
+                       *d++ = 0;
+               }
+       }
+}
+
 static void process_test(uae_u8 *p)
 {
        outbp = outbuffer;
@@ -1319,6 +1437,8 @@ static void process_test(uae_u8 *p)
 
        memset(&regs, 0, sizeof(struct registers));
        regs.sr = interrupt_mask << 8;
+       regs.srcaddr = 0xffffffff;
+       regs.dstaddr = 0xffffffff;
 
        start_test();
 
@@ -1341,6 +1461,9 @@ static void process_test(uae_u8 *p)
                        break;
                p++;
 
+               store_addr(regs.srcaddr, srcaddr);
+               store_addr(regs.srcaddr, dstaddr);
+
                xmemcpy(&last_registers, &regs, sizeof(struct registers));
 
                int fpumode = fpu_model && (opcode_memory[0] & 0xf0) == 0xf0;
@@ -1354,6 +1477,7 @@ static void process_test(uae_u8 *p)
 
                uae_u32 last_pc = opcode_memory_addr;
                uae_u32 last_fpiar = opcode_memory_addr;
+               int old_super = -1;
 
                for (;;) {
                        uae_u16 sr_mask = 0;
@@ -1389,7 +1513,7 @@ static void process_test(uae_u8 *p)
                                        test_regs.sr = (ccr ? 31 : 0);
                                }
                                test_regs.sr |= sr_mask | (interrupt_mask << 8);
-                               uae_u32 test_sr = test_regs.sr;
+                               test_sr = test_regs.sr;
                                if (fpumode) {
                                        if (flag_mode == 0) {
                                                test_regs.fpsr = (ccr & 15) << 24;
@@ -1401,7 +1525,13 @@ static void process_test(uae_u8 *p)
                                        test_fpsr = test_regs.fpsr;
                                        test_fpcr = test_regs.fpcr;
                                }
+                               int super = (test_regs.sr & 0x2000) != 0;
 
+                               if (super != old_super) {
+                                       stackaddr_ptr = super ? regs.ssp : regs.regs[15];
+                                       store_addr(stackaddr_ptr, stackaddr);
+                                       old_super = super;
+                               }
 
                                if ((*p) == CT_END_SKIP) {
 
@@ -1519,7 +1649,7 @@ static int test_mnemo(const char *path, const char *opcode)
        int header_size = 32;
        fread(data, 1, 4, f);
        v = gl(data);
-       if (v != 0x00000002) {
+       if (v != DATA_VERSION) {
                printf("Invalid test data file (header)\n");
                exit(0);
        }
@@ -1532,6 +1662,7 @@ static int test_mnemo(const char *path, const char *opcode)
        test_memory_addr = gl(data);
        fread(data, 1, 4, f);
        test_memory_size = gl(data);
+       test_memory_end = test_memory_addr + test_memory_size;
        fread(data, 1, 4, f);
        opcode_memory_addr = gl(data) + test_memory_addr;
        fread(data, 1, 4, f);
@@ -1620,7 +1751,7 @@ static int test_mnemo(const char *path, const char *opcode)
                if (!f)
                        break;
                fread(data, 1, 4, f);
-               if (gl(data) != 0x00000002) {
+               if (gl(data) != DATA_VERSION) {
                        printf("Invalid test data file (header)\n");
                        exit(0);
                }
index 0a05ca4432ca5b531dc21e01ca26e27da43176c2..b4404794ceee92ebc6b2125c2ba81f216d6a7ff0 100644 (file)
@@ -55,7 +55,7 @@ Not implemented or only partially implemented:
 
 68010+:
 
-- MOVEC: Only MOVEC to An/Dn is tested and read value is ignored. Basically only verifies if correct and only correct CPU model specific control registers exist.
+- MOVEC: Most control registers tested: Write all ones, write all zeros, read it back, restore original value. 68040+ TC/TT registers enable bit is always zero.
 - RTE: long frames with undefined fields are skipped. Basic frame types 0 and 2 are verified, also unsupported frame types are tested, error is reported if CPU does not generate frame exception.
 - 68020+ undefined addressing mode bit combinations are not tested.
 
index ecf6810c2171f35bce0a56b3e47739017269c7ce..d083f012f927ee9d0bd44474f3331db3c4d2b56e 100644 (file)
@@ -1591,7 +1591,7 @@ void m68k_disasm_2 (TCHAR *buf, int bufsize, uaecptr pc, uaecptr *nextpc, int cn
                int segid, lastsegid;
                TCHAR *symbolpos;
 
-               seaddr2 = deaddr2 = 0;
+               seaddr2 = deaddr2 = 0xffffffff;
                oldpc = pc;
                opcode = get_word_debug (pc);
                extra = get_word_debug (pc + 2);