]> git.unchartedbackwaters.co.uk Git - francis/winuae.git/commitdiff
Cputest JMP and JSR bus error special case supported. "Stand-alone" trace exception...
authorToni Wilen <twilen@winuae.net>
Mon, 2 Dec 2019 16:24:53 +0000 (18:24 +0200)
committerToni Wilen <twilen@winuae.net>
Mon, 2 Dec 2019 16:24:53 +0000 (18:24 +0200)
cputest.cpp
cputest/main.c
gencpu.cpp
newcpu.cpp

index b5e9fb0c83988c67466730431e8f80252bdd29eb..54c96c56bc80a7bda0694fbd0061c29d71703e8c 100644 (file)
@@ -121,6 +121,8 @@ static int test_exception_3_fc;
 static int test_exception_3_size;
 static int test_exception_3_di;
 static int test_exception_opcode;
+static uae_u32 trace_store_pc;
+static uae_u16 trace_store_sr;
 
 static uae_u8 imm8_cnt;
 static uae_u16 imm16_cnt;
@@ -924,6 +926,8 @@ void exception2_fetch(uae_u32 opcode, uaecptr addr)
                if (generates_group1_exception(regs.ir)) {
                        test_exception_3_fc |= 8;  // set N/I
                }
+               if (opcode & 0x10000)
+                       test_exception_3_fc |= 8;
        }
 
        doexcstack();
@@ -943,6 +947,8 @@ void exception2_read(uae_u32 opcode, uaecptr addr, int size, int fc)
                if (generates_group1_exception(regs.ir)) {
                        test_exception_3_fc |= 8;  // set N/I
                }
+               if (opcode & 0x10000)
+                       test_exception_3_fc |= 8;
                test_exception_opcode = regs.ir;
        }
 
@@ -964,6 +970,8 @@ void exception2_write(uae_u32 opcode, uaecptr addr, int size, uae_u32 val, int f
                if (generates_group1_exception(regs.ir)) {
                        test_exception_3_fc |= 8;  // set N/I
                }
+               if (opcode & 0x10000)
+                       test_exception_3_fc |= 8;
                test_exception_opcode = regs.ir;
        }
 
@@ -2426,6 +2434,7 @@ static void execute_ins(uae_u16 opc, uaecptr endpc, uaecptr targetpc, struct ins
        // execute instruction
        SPCFLAG_TRACE = 0;
        SPCFLAG_DOTRACE = 0;
+       trace_store_pc = 0xffffffff;
        mmufixup[0].reg = -1;
        mmufixup[1].reg = -1;
 
@@ -2489,32 +2498,44 @@ static void execute_ins(uae_u16 opc, uaecptr endpc, uaecptr targetpc, struct ins
                        Exception(8);
                }
 
-               // Trace is only added as an exception if there was no other exceptions
-               // Trace stacked with other exception is handled later
-               if (SPCFLAG_DOTRACE && !test_exception) {
-                       Exception(9);
-               }
-
                // Amiga Chip ram does not support TAS or MOVE16
                if ((dp->mnemo == i_TAS || dp->mnemo == i_MOVE16) && low_memory_accessed) {
                        test_exception = -1;
                        break;
                }
 
-               if (regs.pc == endpc || regs.pc == targetpc)
+               if (regs.pc == endpc || regs.pc == targetpc) {
+                       // Trace is only added as an exception if there was no other exceptions
+                       // Trace stacked with other exception is handled later
+                       if (SPCFLAG_DOTRACE && !test_exception) {
+                               Exception(9);
+                       }
                        break;
+               }
 
-               if (test_exception || SPCFLAG_DOTRACE)
+               if (test_exception)
                        break;
 
                if (!valid_address(regs.pc, 2, 0))
                        break;
 
-               if (regs.pc + 2 == targetpc) {
+               if (targetpc != 0xffffffff && regs.pc + 2 == targetpc) {
+                       // trace after jumping to branch target
+                       // and opcode was NOP
+                       if (SPCFLAG_DOTRACE) {
+                               trace_store_pc = regs.pc;
+                               trace_store_sr = regs.sr;
+                               SPCFLAG_DOTRACE = 0;
+                       }
                        opc = regs.ir;
                        continue;
                }
 
+               if (SPCFLAG_DOTRACE) {
+                       wprintf(_T("Trace not supported in loop mode\n"));
+                       abort();
+               }
+
                if (cpu_lvl < 2) {
                        opc = get_word_test_prefetch(2);
                } else {
@@ -2617,6 +2638,12 @@ static uae_u8 *save_exception(uae_u8 *p, struct instr *dp)
        uae_u8 *op = p;
        p++;
        *p++ = test_exception_extra;
+       // Separate, non-stacked Trace
+       if (test_exception_extra & 0x80) {
+               *p++ = trace_store_sr >> 8;
+               *p++ = trace_store_sr;
+               p = store_rel(p, 0, opcode_memory_start, trace_store_pc, 1);
+       }
        uae_u8 *sf = test_memory + test_memory_size + EXTRA_RESERVED_SPACE - exception_stack_frame_size;
        // parse exception and store fields that are unique
        // SR and PC was already saved with non-exception data
@@ -3518,6 +3545,11 @@ static void test_mnemo(const TCHAR *path, const TCHAR *mnemo, const TCHAR *ovrfi
 
                                                        MakeSR();
 
+                                                       if (SPCFLAG_DOTRACE && trace_store_pc != 0xffffffff) {
+                                                               wprintf(_T("Trace and stored trace at the same time!\n"));
+                                                               abort();
+                                                       }
+
                                                        // did we have trace also active?
                                                        if (SPCFLAG_DOTRACE) {
                                                                if (regs.t1 && (test_exception == 5 || test_exception == 6 || test_exception == 7 || (test_exception >= 32 && test_exception <= 47))) {
@@ -3529,6 +3561,9 @@ static void test_mnemo(const TCHAR *path, const TCHAR *mnemo, const TCHAR *ovrfi
                                                                regs.t0 = 0;
                                                                regs.t1 = 0;
                                                        }
+                                                       if (trace_store_pc != 0xffffffff) {
+                                                               test_exception_extra = 9 | 0x80;
+                                                       }
 
                                                        if (!skipped) {
                                                                bool storeregs = true;
index b5a0211d4d59c739f919850603e5cf8f41a35a77..a8d1f52c3c8c832416469085b6d7e10b8885c4d3 100644 (file)
@@ -93,7 +93,7 @@ static int low_memory_offset;
 static int high_memory_offset;
 
 static uae_u32 vbr[256];
-static int exceptioncount[256];
+static int exceptioncount[128];
 static int supercnt;
 
 static char inst_name[16+1];
@@ -1110,26 +1110,44 @@ static uae_u8 *validate_exception(struct registers *regs, uae_u8 *p, int excnum,
        if (excdatalen != 0xff) {
                // check possible extra trace
                last_exception_extra = *p++;
-               // some other exception + trace
-               if (last_exception_extra == 9) {
-                       exceptioncount[last_exception_extra]++;
+               if ((last_exception_extra & 0x7f) == 9) {
+                       exceptioncount[last_exception_extra & 0x7f]++;
+                       uae_u32 ret = (regs->tracedata[1] << 16) | regs->tracedata[2];
+                       uae_u16 sr = regs->tracedata[0];
                        if (regs->tracecnt == 0) {
-                               sprintf(outbp, "Expected trace exception but got none\n", regs->tracecnt);
+                               sprintf(outbp, "Expected trace exception but got none\n");
                                outbp += strlen(outbp);
                                errors = 1;
                                *experr = 1;
-                       } else {
-                               uae_u16 sr = regs->tracedata[0];
+                       } else if (!(last_exception_extra & 0x80)) {
+                               // Trace stacked with group 2 exception
                                if (!(sr & 0x2000) || (sr | 0x2000 | 0xc000) != (regs->sr | 0x2000 | 0xc000)) {
-                                       sprintf(outbp, "Trace exception stack frame SR mismatch: %04x != %04x\n", sr, regs->sr);
+                                       sprintf(outbp, "Trace (%d stacked) SR mismatch: %04x != %04x\n", excnum, sr, regs->sr);
                                        outbp += strlen(outbp);
                                        errors = 1;
                                        *experr = 1;
                                }
-                               uae_u32 ret = (regs->tracedata[1] << 16) | regs->tracedata[2];
                                uae_u32 retv = exceptiontableinuse + (excnum - 2) * 2;
                                if (ret != retv) {
-                                       sprintf(outbp, "Trace exception stacked PC mismatch: %08lx != %08lx (%ld)\n", ret, retv, excnum);
+                                       sprintf(outbp, "Trace (%d stacked) PC mismatch: %08lx != %08lx (%ld)\n", excnum, ret, retv);
+                                       outbp += strlen(outbp);
+                                       errors = 1;
+                                       *experr = 1;
+                               }
+                       } else {
+                               // Standalone Trace
+                               uae_u16 vsr = (p[0] << 8) | (p[1]);
+                               p += 2;
+                               v = opcode_memory_addr;
+                               p = restore_rel_ordered(p, &v);
+                               if (vsr != sr) {
+                                       sprintf(outbp, "Trace (non-stacked) SR mismatch: %04x != %04x\n", sr, vsr);
+                                       outbp += strlen(outbp);
+                                       errors = 1;
+                                       *experr = 1;
+                               }
+                               if (v != ret) {
+                                       sprintf(outbp, "Trace (non-stacked) PC mismatch: %08lx != %08lx\n", ret, v);
                                        outbp += strlen(outbp);
                                        errors = 1;
                                        *experr = 1;
@@ -1827,7 +1845,8 @@ static void process_test(uae_u8 *p)
                                        }
 
                                        p = validate_test(p, ignore_errors, ignore_sr);
-                                       if (regs.sr & 0x2000)
+
+                                       if (super)
                                                supercnt++;
 
                                        last_pc = last_registers.pc;
@@ -2059,7 +2078,7 @@ static int test_mnemo(const char *path, const char *opcode)
        }
 
        printf("S=%ld", supercnt);
-       for (int i = 0; i < 256; i++) {
+       for (int i = 0; i < 128; i++) {
                if (exceptioncount[i]) {
                        printf(" E%02d=%ld", i, exceptioncount[i]);
                }
index e301630f953b5dec2f5e72d2d214fdff3eda3665..d9614805e623acbfd56b6173f6de04fd0814b6a8 100644 (file)
@@ -5185,6 +5185,8 @@ static void gen_opcode (unsigned int opcode)
                                int sp = (curi->smode == Ad16 || curi->smode == absw || curi->smode == absl || curi->smode == PC16 || curi->smode == Ad8r || curi->smode == PC8r) ? -1 : 0;
                                irc2ir();
                                printf("\topcode = regs.ir;\n");
+                               if (sp < 0)
+                                       printf("\tif(regs.t1) opcode |= 0x10000;\n");
                                printf("\t%s (%d);\n", prefetch_word, 2);
                                check_prefetch_bus_error(-2, sp);
                                did_prefetch = 1;
@@ -5221,6 +5223,8 @@ static void gen_opcode (unsigned int opcode)
                        printf("\t%s (%d);\n", prefetch_word, 2);
                        int sp = (curi->smode == Ad16 || curi->smode == absw || curi->smode == absl || curi->smode == PC16 || curi->smode == Ad8r || curi->smode == PC8r) ? -1 : 0;
                        printf("\topcode = regs.ir;\n");
+                       if (sp < 0)
+                               printf("\tif(regs.t1) opcode |= 0x10000;\n");
                        check_prefetch_bus_error(-2, sp);
                        did_prefetch = 1;
                        ir2irc = 0;
index 65e486a22f8172980c06dacf1eb40cb4738d44a3..5f9a32cc0f7c60fed53b6d2c3095b19b66800854 100644 (file)
@@ -6874,7 +6874,7 @@ void exception3_read(uae_u32 opcode, uaecptr addr, int size, int fc)
                        ni = true;
                        fc = -1;
                }
-               if (opcode & 0x100000)
+               if (opcode & 0x10000)
                        ni = true;
                opcode = regs.ir;
        }
@@ -6888,7 +6888,7 @@ void exception3_write(uae_u32 opcode, uaecptr addr, int size, uae_u32 val, int f
                        ni = true;
                        fc = -1;
                }
-               if (opcode & 0x100000)
+               if (opcode & 0x10000)
                        ni = true;
                opcode = regs.ir;
        }
@@ -6944,6 +6944,8 @@ void exception2_read(uae_u32 opcode, uaecptr addr, int size, int fc)
 {
        exception2_setup(addr, true, size, fc);
        last_op_for_exception_3 = opcode;
+       if (opcode & 0x10000)
+               last_notinstruction_for_exception_3 = true;
        Exception(2);
 }
 
@@ -6951,6 +6953,8 @@ void exception2_write(uae_u32 opcode, uaecptr addr, int size, uae_u32 val, int f
 {
        exception2_setup(addr, false, size, fc);
        last_op_for_exception_3 = opcode;
+       if (opcode & 0x10000)
+               last_notinstruction_for_exception_3 = true;
        regs.write_buffer = val;
        Exception(2);
 }
@@ -6960,6 +6964,8 @@ void exception2_fetch(uae_u32 opcode, uaecptr addr)
        exception2_setup(addr, true, 1, 2);
        last_op_for_exception_3 = opcode;
        last_di_for_exception_3 = 0;
+       if (opcode & 0x10000)
+               last_notinstruction_for_exception_3 = true;
        Exception(2);
 }