]> git.unchartedbackwaters.co.uk Git - francis/winuae.git/commitdiff
CPU tester updates
authorToni Wilen <twilen@winuae.net>
Sun, 31 May 2020 17:04:56 +0000 (20:04 +0300)
committerToni Wilen <twilen@winuae.net>
Sun, 31 May 2020 17:04:56 +0000 (20:04 +0300)
cputest.cpp
cputest/cputest_defines.h
cputest/cputestgen.ini
cputest/main.c
cputest/readme.txt

index 1d9261f4247d9c5467cd6ef2522bbcaa1dbf7dba..ee10647690616c5ccfcebe588cf1344a171fe873 100644 (file)
@@ -132,6 +132,7 @@ static int test_exception_3_w;
 static int test_exception_3_fc;
 static int test_exception_3_size;
 static int test_exception_3_di;
+static uae_u16 test_exception_3_sr;
 static int test_exception_opcode;
 static uae_u32 trace_store_pc;
 static uae_u16 trace_store_sr;
@@ -225,8 +226,12 @@ static bool valid_address(uaecptr addr, int size, int rwp)
                if (addr < test_low_memory_start || test_low_memory_start == 0xffffffff)
                        goto oob;
                // exception vectors needed during tests
-               if ((addr + size >= 0x08 && addr < 0x30 || (addr + size >= 0x80 && addr < 0xc0)) && currprefs.cpu_model == 68000)
-                       goto oob;
+               if (currprefs.cpu_model == 68000) {
+                       if ((addr + size >= 0x08 && addr < 0x30 || (addr + size >= 0x80 && addr < 0xc0)))
+                               goto oob;
+                       if (feature_interrupts && (addr + size >= 0x64 && addr < 0x7c))
+                               goto oob;
+               }
                if (addr + size >= test_low_memory_end)
                        goto oob;
                if (w && lmem_rom)
@@ -445,24 +450,32 @@ uae_u16 get_word_test_prefetch(int o)
        return get_iword_test(m68k_getpci() + o);
 }
 
-static void previoussame(uaecptr addr, int size)
+static void previoussame(uaecptr addr, int size, uae_u32 *old)
 {
        if (!ahcnt_current || ahcnt_current == ahcnt_written)
                return;
        // Move from SR does two writes to same address.
        // Loop mode can write different values to same address.
        // Mark old values as do not save.
+       // Also loop mode test can do multi writes and it needs original value.
+       bool gotold = false;
        for (int i = ahcnt_written; i < ahcnt_current; i++) {
                struct accesshistory  *ah = &ahist[i];
                if (ah->size == size && ah->addr == addr) {
                        ah->donotsave = true;
-               }
-               if (size == sz_long) {
-                       if (ah->size == sz_word && ah->addr == addr) {
-                               ah->donotsave = true;
+                       if (!gotold) {
+                               *old = ah->oldval;
+                               gotold = true;
                        }
-                       if (ah->size == sz_word && ah->addr == addr + 2) {
-                               ah->donotsave = true;
+               }
+               if (cpu_lvl < 2) {
+                       if (size == sz_long) {
+                               if (ah->size == sz_word && ah->addr == addr) {
+                                       ah->donotsave = true;
+                               }
+                               if (ah->size == sz_word && ah->addr == addr + 2) {
+                                       ah->donotsave = true;
+                               }
                        }
                }
        }
@@ -475,7 +488,8 @@ void put_byte_test(uaecptr addr, uae_u32 v)
        check_bus_error(addr, 1, regs.s ? 5 : 1);
        uae_u8 *p = get_addr(addr, 1, 2);
        if (!out_of_test_space && !noaccesshistory && !hardware_bus_error_fake) {
-               previoussame(addr, sz_byte);
+               uae_u32 old = p[0];
+               previoussame(addr, sz_byte, &old);
                if (ahcnt_current >= MAX_ACCESSHIST) {
                        wprintf(_T(" ahist overflow!"));
                        abort();
@@ -483,7 +497,7 @@ void put_byte_test(uaecptr addr, uae_u32 v)
                struct accesshistory *ah = &ahist[ahcnt_current++];
                ah->addr = addr;
                ah->val = v & 0xff;
-               ah->oldval = *p;
+               ah->oldval = old & 0xff;
                ah->size = sz_byte;
                ah->donotsave = false;
        }
@@ -503,7 +517,8 @@ void put_word_test(uaecptr addr, uae_u32 v)
        } else {
                uae_u8 *p = get_addr(addr, 2, 2);
                if (!out_of_test_space && !noaccesshistory && !hardware_bus_error_fake) {
-                       previoussame(addr, sz_word);
+                       uae_u32 old = (p[0] << 8) | p[1];
+                       previoussame(addr, sz_word, &old);
                        if (ahcnt_current >= MAX_ACCESSHIST) {
                                wprintf(_T(" ahist overflow!"));
                                abort();
@@ -511,7 +526,7 @@ void put_word_test(uaecptr addr, uae_u32 v)
                        struct accesshistory *ah = &ahist[ahcnt_current++];
                        ah->addr = addr;
                        ah->val = v & 0xffff;
-                       ah->oldval = (p[0] << 8) | p[1];
+                       ah->oldval = old & 0xffff;
                        ah->size = sz_word;
                        ah->donotsave = false;
                }
@@ -536,7 +551,8 @@ void put_long_test(uaecptr addr, uae_u32 v)
        } else {
                uae_u8 *p = get_addr(addr, 4, 2);
                if (!out_of_test_space && !noaccesshistory && !hardware_bus_error_fake) {
-                       previoussame(addr, sz_long);
+                       uae_u32 old = (p[0] << 24) | (p[1] << 16) | (p[2] << 8) | p[3];
+                       previoussame(addr, sz_long, &old);
                        if (ahcnt_current >= MAX_ACCESSHIST) {
                                wprintf(_T(" ahist overflow!"));
                                abort();
@@ -544,7 +560,7 @@ void put_long_test(uaecptr addr, uae_u32 v)
                        struct accesshistory *ah = &ahist[ahcnt_current++];
                        ah->addr = addr;
                        ah->val = v;
-                       ah->oldval = (p[0] << 24) | (p[1] << 16) | (p[2] << 8) | p[3];
+                       ah->oldval = old;
                        ah->size = sz_long;
                        ah->donotsave = false;
                }
@@ -935,7 +951,6 @@ void MakeFromSR_x(int t0trace)
                // Always trace if Tx bits were already set, even if this SR modification cleared them.
                activate_trace();
        }
-
 }
 
 void REGPARAM2 MakeFromSR_T0(void)
@@ -1074,7 +1089,7 @@ static void doexcstack(void)
 
        MakeSR();
        regs.sr |= 0x2000;
-       regs.sr &= ~0x8000;
+       regs.sr &= ~(0x8000 | 0x4000);
        MakeFromSR();
 
        regs.pc = original_exception * 4;
@@ -1100,6 +1115,9 @@ static void doexcstack(void)
                } else {
                        flags |= 0x20000;
                }
+               if (cpu_lvl < 5) {
+                       regs.m = 0;
+               }
        }
 
        // set I/N if original exception was group 1 exception.
@@ -1142,10 +1160,11 @@ void REGPARAM2 op_unimpl(uae_u32 opcode)
 }
 uae_u32 REGPARAM2 op_unimpl_1(uae_u32 opcode)
 {
-       if ((opcode & 0xf000) == 0xf000 || currprefs.cpu_model < 68060)
+       if ((opcode & 0xf000) == 0xf000 || currprefs.cpu_model < 68060) {
                op_illg(opcode);
-       else
+       } else {
                op_unimpl(opcode);
+       }
        return 0;
 }
 uae_u32 REGPARAM2 op_illg(uae_u32 opcode)
@@ -1206,7 +1225,7 @@ void exception2_read(uae_u32 opcode, uaecptr addr, int size, int fc)
        test_exception_addr = addr;
        test_exception_opcode = opcode;
        test_exception_3_fc = fc;
-       test_exception_3_size = size;
+       test_exception_3_size = size & 15;
        test_exception_3_di = 1;
 
        if (currprefs.cpu_model == 68000) {
@@ -1229,12 +1248,16 @@ void exception2_write(uae_u32 opcode, uaecptr addr, int size, uae_u32 val, int f
        test_exception_addr = addr;
        test_exception_opcode = opcode;
        test_exception_3_fc = fc;
-       test_exception_3_size = size;
-       if (size == sz_byte) {
-               regs.write_buffer &= 0xff00;
-               regs.write_buffer |= val & 0xff;
-       } else {
+       test_exception_3_size = size & 15;
+       if (size & 0x100) {
                regs.write_buffer = val;
+       } else {
+               if (size == sz_byte) {
+                       regs.write_buffer &= 0xff00;
+                       regs.write_buffer |= val & 0xff;
+               } else {
+                       regs.write_buffer = val;
+               }
        }
        test_exception_3_di = 1;
 
@@ -1258,7 +1281,7 @@ void exception3_read(uae_u32 opcode, uae_u32 addr, int size, int fc)
        test_exception_addr = addr;
        test_exception_opcode = opcode;
        test_exception_3_fc = fc;
-       test_exception_3_size = size;
+       test_exception_3_size = size & 15;
        test_exception_3_di = 1;
 
        if (currprefs.cpu_model == 68000) {
@@ -1284,7 +1307,7 @@ void exception3_write(uae_u32 opcode, uae_u32 addr, int size, uae_u32 val, int f
        test_exception_addr = addr;
        test_exception_opcode = opcode;
        test_exception_3_fc = fc;
-       test_exception_3_size = size;
+       test_exception_3_size = size & 15;
        regs.write_buffer = val;
        test_exception_3_di = 1;
 
@@ -1342,6 +1365,28 @@ void exception3_read_prefetch(uae_u32 opcode, uae_u32 addr)
        doexcstack();
 }
 
+void exception3_read_prefetch_68040bug(uae_u32 opcode, uae_u32 addr, uae_u16 secondarysr)
+{
+       if (cpu_lvl == 1) {
+               get_word_test(addr & ~1);
+       } else {
+               add_memory_cycles(1);
+       }
+       exception3_pc_inc();
+
+       test_exception = 3;
+       test_exception_3_w = 0;
+       test_exception_addr = addr;
+       test_exception_opcode = opcode | 0x10000;
+       test_exception_3_fc = 2;
+       test_exception_3_size = sz_word;
+       test_exception_3_di = 0;
+       test_exception_3_sr = secondarysr;
+
+       doexcstack();
+}
+
+
 void exception3_read_access2(uae_u32 opcode, uae_u32 addr, int size, int fc)
 {
        get_word_test(addr & ~1);
@@ -1385,9 +1430,11 @@ void REGPARAM2 Exception_cpu(int n)
        test_exception_opcode = -1;
 
        bool t0 = currprefs.cpu_model >= 68020 && regs.t0 && !regs.t1;
-       // check T0 trace
-       if (t0) {
-               activate_trace();
+       if (n != 14) {
+               // check T0 trace
+               if (t0) {
+                       activate_trace();
+               }
        }
        doexcstack();
 }
@@ -1629,6 +1676,8 @@ static bool regchange(int reg, uae_u32 *regs)
 
        if (generate_address_mode && reg >= 8)
                return false;
+       if (feature_loop_mode_register == reg)
+               return false;
 
        // don't unnecessarily modify static forced register
        for (int i = 0; i < regdatacnt; i++) {
@@ -1703,6 +1752,9 @@ static bool regchange(int reg, uae_u32 *regs)
                }
                break;
        case 11:
+               if (feature_loop_mode && !feature_loop_mode_68010) {
+                       return false;
+               }
                v ^= 0x8000;
                break;
        case 12:
@@ -2007,7 +2059,7 @@ static uae_u8 *store_mem_bytes(uae_u8 *dst, uaecptr start, int len, uae_u8 *old,
 {
        if (!len)
                return dst;
-       if (len > 32) {
+       if (len > 256) {
                wprintf(_T(" too long byte count!\n"));
                abort();
        }
@@ -2048,7 +2100,12 @@ static uae_u8 *store_mem_bytes(uae_u8 *dst, uaecptr start, int len, uae_u8 *old,
        if (header) {
                *dst++ = CT_MEMWRITES | CT_PC_BYTES;
        }
-       *dst++ = (offset << 5) | (uae_u8)(len == 32 ? 0 : len);
+       if (len > 32) {
+               *dst++ = (offset << 5) | 31;
+               *dst++ = len;
+       } else {
+               *dst++ = (offset << 5) | (uae_u8)(len == 32 ? 0 : len);
+       }
        for (int i = 0; i < len; i++) {
                *dst++ = get_byte_test(start);
                start++;
@@ -2145,7 +2202,7 @@ static void markfile(const TCHAR *dir)
        }
 }
 
-static void save_data(uae_u8 *dst, const TCHAR *dir)
+static void save_data(uae_u8 *dst, const TCHAR *dir, int size)
 {
        TCHAR path[1000];
 
@@ -2213,15 +2270,16 @@ static void save_data(uae_u8 *dst, const TCHAR *dir)
                fwrite(data, 1, 2, f);
                fclose(f);
                filecount++;
-               save_data(dst, dir);
+               save_data(dst, dir, size);
        } else {
                uae_u8 data[4];
                pl(data, DATA_VERSION);
                fwrite(data, 1, 4, f);
                pl(data, (uae_u32)starttime);
                fwrite(data, 1, 4, f);
-               pl(data, 0);
+               pl(data, (size & 3));
                fwrite(data, 1, 4, f);
+               pl(data, 0);
                fwrite(data, 1, 4, f);
                *dst++ = CT_END_FINISH;
                *dst++ = filecount;
@@ -2762,7 +2820,6 @@ static int create_ea_random(uae_u16 *opcodep, uaecptr pc, int mode, int reg, str
                } else {
                        if (opcodecnt == 1) {
                                // STOP #xxxx: test all combinations
-                               // (also includes RTD)
                                if (dp->mnemo == i_LPSTOP) {
                                        uae_u16 lp = 0x01c0;
                                        if (imm16_cnt & (0x40 | 0x80)) {
@@ -2818,7 +2875,8 @@ static int create_ea_random(uae_u16 *opcodep, uaecptr pc, int mode, int reg, str
                                        else
                                                *isconstant = -1;
                                } else if (dp->mnemo == i_BSR || dp->mnemo == i_DBcc || dp->mnemo == i_Bcc ||
-                                       dp->mnemo == i_ORSR || dp->mnemo == i_ANDSR || dp->mnemo == i_EORSR) {
+                                       dp->mnemo == i_ORSR || dp->mnemo == i_ANDSR || dp->mnemo == i_EORSR ||
+                                       dp->mnemo == i_RTD) {
                                        // don't try to test all 65536 possibilies..
                                        uae_u16 i16 = imm16_cnt;
                                        put_word_test(pc, imm16_cnt);
@@ -3539,16 +3597,29 @@ static int handle_specials_stack(uae_u16 opcode, uaecptr pc, struct instr *dp, i
 
 static const int interrupt_levels[] =
 {
-       1, 1, 1, 2, 3, 3, 3, 4, 4, 4, 4, 5, 5, 6, 6, 0
+       0, 1, 1, 1, 2, 3, 3, 3, 4, 4, 4, 4, 5, 5, 6, 6
 };
 
+static bool check_interrupts(void)
+{
+       if (feature_interrupts) {
+               int ic = interrupt_count & 15;
+               int lvl = interrupt_levels[ic];
+               if (lvl > 0 && lvl > feature_min_interrupt_mask) {
+                       Exception(lvl + 24);
+                       return true;
+               }
+       }
+       return false;
+}
+
 static void execute_ins(uaecptr endpc, uaecptr targetpc, struct instr *dp)
 {
        uae_u16 opc = regs.ir;
        uae_u16 opw1 = (opcode_memory[2] << 8) | (opcode_memory[3] << 0);
        uae_u16 opw2 = (opcode_memory[4] << 8) | (opcode_memory[5] << 0);
-       if (opc == 0xf202
-               && opw1 == 0x5225
+       if (opc == 0x4ed6
+               //&& opw1 == 0x5225
                //&& opw2 == 0x4afc
                )
                printf("");
@@ -3584,7 +3655,12 @@ static void execute_ins(uaecptr endpc, uaecptr targetpc, struct instr *dp)
        cpu_cycles = 0;
        regs.loop_mode = 0;
 
-       int cnt = (feature_loop_mode + 1) * 2;
+       int cnt = 2;
+       if (feature_loop_mode_68010) {
+               cnt = (feature_loop_mode + 1) * 2;
+       } else if (feature_loop_mode) {
+               cnt = (feature_loop_mode + 1) * 20;
+       }
        if (multi_mode)
                cnt = 100;
 
@@ -3605,15 +3681,9 @@ static void execute_ins(uaecptr endpc, uaecptr targetpc, struct instr *dp)
                        do_trace();
                }
 
-               if (feature_interrupts) {
-                       int ic = interrupt_count;
-                       interrupt_count++;
-                       interrupt_count &= 15;
-                       int lvl = interrupt_levels[ic];
-                       if (lvl > 0 && lvl > feature_min_interrupt_mask) {
-                               Exception(lvl + 24);
+               if (cpu_lvl <= 1) {
+                       if (check_interrupts())
                                break;
-                       }
                }
 
                regs.instruction_pc = regs.pc;
@@ -3659,10 +3729,15 @@ static void execute_ins(uaecptr endpc, uaecptr targetpc, struct instr *dp)
                        break;
                }
 
+               if (cpu_lvl >= 2) {
+                       if (check_interrupts())
+                               break;
+               }
+
                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) {
+                       if (SPCFLAG_DOTRACE && !test_exception && trace_store_pc == 0xffffffffff) {
                                Exception(9);
                        }
                        break;
@@ -3700,7 +3775,7 @@ static void execute_ins(uaecptr endpc, uaecptr targetpc, struct instr *dp)
 
                cnt--;
 
-               if (!feature_loop_mode && !multi_mode && opc != 0x4e71) {
+               if (!feature_loop_mode && !multi_mode && opc != NOP_OPCODE) {
                        wprintf(_T(" Test instruction didn't finish in single step in non-loop mode!?\n"));
                        abort();
                }
@@ -4105,6 +4180,10 @@ static void test_mnemo(const TCHAR *path, const TCHAR *mnemo, const TCHAR *ovrfi
 
        int count = 0;
 
+       if (feature_loop_mode && !feature_loop_mode_68010) {
+               registers[8 + 3] = 0;
+       }
+
        registers[8 + 6] = opcode_memory_start - 0x100;
        registers[15] = user_stack_memory_use;
 
@@ -4169,10 +4248,10 @@ static void test_mnemo(const TCHAR *path, const TCHAR *mnemo, const TCHAR *ovrfi
 
        dst = storage_buffer;
 
-       if (low_memory) {
+       if (low_memory && low_memory_size != 0xffffffff) {
                memcpy(low_memory, low_memory_temp, low_memory_size);
        }
-       if (high_memory) {
+       if (high_memory && high_memory_size != 0xffffffff) {
                memcpy(high_memory, high_memory_temp, high_memory_size);
        }
        memcpy(test_memory, test_memory_temp, test_memory_size);
@@ -4188,6 +4267,7 @@ static void test_mnemo(const TCHAR *path, const TCHAR *mnemo, const TCHAR *ovrfi
        uae_u32 target_ea_bak[3], target_address_bak, target_opcode_address_bak;
 
        for (;;) {
+               int got_something = 0;
 
                target_ea_bak[0] = target_ea[0];
                target_ea_bak[1] = target_ea[1];
@@ -4216,7 +4296,14 @@ static void test_mnemo(const TCHAR *path, const TCHAR *mnemo, const TCHAR *ovrfi
 
                if (feature_loop_mode) {
                        cur_regs.regs[feature_loop_mode_register] &= 0xffff0000;
-                       cur_regs.regs[feature_loop_mode_register] |= feature_loop_mode - 1;
+                       if (feature_loop_mode_68010) {
+                               cur_regs.regs[feature_loop_mode_register] |= feature_loop_mode - 1;
+                       } else {
+                               // loop register is used as index in some addressing modes but
+                               // we don't handle situation where multiple memory writes access same
+                               // memory location using different access sizes.
+                               cur_regs.regs[feature_loop_mode_register] |= feature_loop_mode * 64 - 1;
+                       }
                }
 
                for (int i = 0; i < MAX_REGISTERS; i++) {
@@ -4273,6 +4360,8 @@ static void test_mnemo(const TCHAR *path, const TCHAR *mnemo, const TCHAR *ovrfi
                                        continue;
                        }
 
+                       got_something = 1;
+
                        target_ea[0] = target_ea_bak[0];
                        target_ea[1] = target_ea_bak[1];
                        target_ea[2] = target_ea_bak[2];
@@ -4344,7 +4433,7 @@ static void test_mnemo(const TCHAR *path, const TCHAR *mnemo, const TCHAR *ovrfi
 
                                        uae_u32 branch_target_swap_address = 0;
                                        int branch_target_swap_mode = 0;
-                                       uae_u32 branch_target_data_original = 0x4afc4e71;
+                                       uae_u32 branch_target_data_original = (ILLG_OPCODE << 16) | NOP_OPCODE;
                                        uae_u32 branch_target_data = branch_target_data_original;
 
                                        int srcregused = -1;
@@ -4389,7 +4478,7 @@ static void test_mnemo(const TCHAR *path, const TCHAR *mnemo, const TCHAR *ovrfi
                                                pc -= 2;
                                                int cnt = 0;
                                                while (pc - 2 != opcode_memory_address) {
-                                                       put_word_test(pc, 0x4e71);
+                                                       put_word_test(pc, NOP_OPCODE);
                                                        pc += 2;
                                                        cnt++;
                                                        if (cnt >= 16) {
@@ -4502,9 +4591,9 @@ static void test_mnemo(const TCHAR *path, const TCHAR *mnemo, const TCHAR *ovrfi
                                                uae_u8 *bo = opcode_memory_ptr + 2;
                                                uae_u16 bopw1 = (bo[0] << 8) | (bo[1] << 0);
                                                uae_u16 bopw2 = (bo[2] << 8) | (bo[3] << 0);
-                                               if (opc == 0x4e96
-                                                       //&& bopw1 == 0x3dec
-                                                       //&& bopw2 == 0x2770
+                                               if (opc == 0x0ab3
+                                                       && bopw1 == 0x5aa9
+                                                       && bopw2 == 0xe5cc
                                                        )
                                                        printf("");
 
@@ -4550,6 +4639,23 @@ static void test_mnemo(const TCHAR *path, const TCHAR *mnemo, const TCHAR *ovrfi
                                        // loop mode
                                        if (feature_loop_mode) {
                                                // dbf dn, opcode_memory_start
+                                               if (!feature_loop_mode_68010) {
+                                                       for (int i = 0; i < 4; i++) {
+                                                               // bcc, bne, bvc, bpl
+                                                               put_word(pc, 0x6400 + (i * 0x0200) + 4);
+                                                               pc += 2;
+                                                               // adda.w #x,a3
+                                                               put_long(pc, 0xd6fc0000 | (1 << (i * 3)));
+                                                               pc += 4;
+                                                       }
+                                                       // negx.b d0 ; add.w d0,d0
+                                                       put_long(pc, 0x4000d040);
+                                                       pc += 4;
+                                                       // sub.w #63,dn
+                                                       put_long(pc, ((0x0440 | feature_loop_mode_register) << 16) | 63);
+                                                       pc += 4;
+                                               }
+                                               // dbf dn,label
                                                put_long_test(pc, ((0x51c8 | feature_loop_mode_register) << 16) | ((opcode_memory_address - pc - 2) & 0xffff));
                                                pc += 4;
                                        }
@@ -4561,7 +4667,7 @@ static void test_mnemo(const TCHAR *path, const TCHAR *mnemo, const TCHAR *ovrfi
 
                                        // end word, needed to detect if instruction finished normally when
                                        // running on real hardware.
-                                       uae_u32 originalendopcode = 0x4afc4e71;
+                                       uae_u32 originalendopcode = (ILLG_OPCODE << 16) | NOP_OPCODE;
                                        uae_u32 endopcode = originalendopcode;
                                        uae_u32 actualendpc = pc;
                                        
@@ -4621,6 +4727,17 @@ static void test_mnemo(const TCHAR *path, const TCHAR *mnemo, const TCHAR *ovrfi
                                                if (dstaddr != 0xffffffff && srcaddr != dstaddr) {
                                                        outbytes(_T("D"), dstaddr);
                                                }
+                                               if (feature_loop_mode) {
+                                                       wprintf(_T("\n"));
+                                                       for (int i = 0; i < 20; i++) {
+                                                               out_of_test_space = false;
+                                                               if (get_word_test(nextpc) == ILLG_OPCODE)
+                                                                       break;
+                                                               m68k_disasm_2(out, sizeof(out) / sizeof(TCHAR), nextpc, &nextpc, 1, NULL, NULL, 0xffffffff, 0);
+                                                               my_trim(out);
+                                                               wprintf(_T("%08u %s\n"), subtest_count, out);
+                                                       }
+                                               }
                                        }
                                        
                                        // disassembler may set this
@@ -4745,6 +4862,7 @@ static void test_mnemo(const TCHAR *path, const TCHAR *mnemo, const TCHAR *ovrfi
                                        uae_u32 branchtarget_old_prev = branchtarget_old;
                                        uae_u32 srcaddr_old_prev = srcaddr_old;
                                        uae_u32 dstaddr_old_prev = dstaddr_old;
+                                       int interrupt_count_old_prev = interrupt_count;
 
                                        if (startpc != startpc_old) {
                                                dst = store_reg(dst, CT_PC, startpc_old, startpc, -1);
@@ -4848,16 +4966,22 @@ static void test_mnemo(const TCHAR *path, const TCHAR *mnemo, const TCHAR *ovrfi
                                                        ahcnt_current = ahcnt_written;
                                                        int ahcnt_start = ahcnt_current;
 
+                                                       if (feature_interrupts) {
+                                                               *dst++ = (uae_u8)interrupt_count;
+                                                               interrupt_count++;
+                                                               interrupt_count &= 15;
+                                                       }
+
                                                        memset(&regs, 0, sizeof(regs));
 
                                                        // swap end opcode illegal/nop
                                                        noaccesshistory++;
                                                        endopcode = (endopcode >> 16) | (endopcode << 16);
-                                                       int extraopcodeendsize = ((endopcode >> 16) == 0x4e71) ? 2 : 0;
+                                                       int extraopcodeendsize = ((endopcode >> 16) == NOP_OPCODE) ? 2 : 0;
                                                        int endopcodesize = 0;
                                                        if (!is_nowrite_address(pc - 4, 4)) {
                                                                put_long_test(pc - 4, endopcode);
-                                                               endopcodesize = (endopcode >> 16) == 0x4e71 ? 2 : 4;
+                                                               endopcodesize = (endopcode >> 16) == NOP_OPCODE ? 2 : 4;
                                                        } else if (!is_nowrite_address(pc - 4, 2)) {
                                                                put_word_test(pc - 4, endopcode >> 16);
                                                                endopcodesize = 2;
@@ -4872,7 +4996,7 @@ static void test_mnemo(const TCHAR *path, const TCHAR *mnemo, const TCHAR *ovrfi
                                                                        if (!(branch_target_swap_address & 1)) {
                                                                                branch_target_data = (branch_target_data >> 16) | (branch_target_data << 16);
                                                                                put_long_test(branch_target_swap_address, branch_target_data);
-                                                                               if ((branch_target_data >> 16) == 0x4e71)
+                                                                               if ((branch_target_data >> 16) == NOP_OPCODE)
                                                                                        branch_target_pc = branch_target + 2;
                                                                                else
                                                                                        branch_target_pc = branch_target;
@@ -4894,7 +5018,7 @@ static void test_mnemo(const TCHAR *path, const TCHAR *mnemo, const TCHAR *ovrfi
                                                        regs.ir = get_word_test(regs.pc + 0);
                                                        regs.irc = get_word_test(regs.pc + 2);
 
-                                                       if (regs.ir == 0x4afc && dp->mnemo != i_ILLG) {
+                                                       if (regs.ir == ILLG_OPCODE && dp->mnemo != i_ILLG) {
                                                                wprintf(_T(" Illegal as starting opcode!?\n"));
                                                                abort();
                                                        }
@@ -5132,10 +5256,13 @@ static void test_mnemo(const TCHAR *path, const TCHAR *mnemo, const TCHAR *ovrfi
 
                                                        // did we have trace also active?
                                                        if (SPCFLAG_DOTRACE) {
-                                                               if ((regs.t1 || regs.t0) && (test_exception == 5 || test_exception == 6 || test_exception == 7 || (test_exception >= 32 && test_exception <= 47) || (cpu_lvl == 1 && test_exception == 14))) {
-                                                                       test_exception_extra = 9;
-                                                               } else {
-                                                                       test_exception_extra = 0;
+                                                               test_exception_extra = 0;
+                                                               if (regs.t1 || regs.t0) {
+                                                                       if ((cpu_lvl < 4 && (test_exception == 5 || test_exception == 6 || test_exception == 7 || (test_exception >= 32 && test_exception <= 47)))
+                                                                               ||
+                                                                               (cpu_lvl == 1 && test_exception == 14)) {
+                                                                                       test_exception_extra = 9;
+                                                                       }
                                                                }
                                                        }
                                                        if (trace_store_pc != 0xffffffff) {
@@ -5249,6 +5376,7 @@ static void test_mnemo(const TCHAR *path, const TCHAR *mnemo, const TCHAR *ovrfi
                                                branchtarget_old = branchtarget_old_prev;
                                                instructionendpc_old = instructionendpc_old_prev;
                                                startpc_old = startpc_old_prev;
+                                               interrupt_count = interrupt_count_old_prev;
                                        } else {
                                                full_format_cnt++;
                                                data_saved = 1;
@@ -5290,7 +5418,7 @@ static void test_mnemo(const TCHAR *path, const TCHAR *mnemo, const TCHAR *ovrfi
                                        // save to file and create new file if watermark reached
                                        if (dst - storage_buffer >= storage_buffer_watermark) {
                                                if (subtest_count > 0) {
-                                                       save_data(dst, dir);
+                                                       save_data(dst, dir, size);
 
                                                        branchtarget_old = 0xffffffff;
                                                        srcaddr_old = 0xffffffff;
@@ -5331,7 +5459,7 @@ static void test_mnemo(const TCHAR *path, const TCHAR *mnemo, const TCHAR *ovrfi
                }
 
                if (data_saved) {
-                       save_data(dst, dir);
+                       save_data(dst, dir, size);
                        data_saved = 0;
                }
                dst = storage_buffer;
@@ -5392,7 +5520,7 @@ static void test_mnemo(const TCHAR *path, const TCHAR *mnemo, const TCHAR *ovrfi
                if (nextround) {
                        rounds--;
                        if (rounds < 0) {
-                               if (subtest_count >= feature_test_rounds_opcode)
+                               if (subtest_count >= feature_test_rounds_opcode || !got_something)
                                        break;
                                rounds = 1;
                        }
@@ -5799,7 +5927,7 @@ static int test(struct ini_data *ini, const TCHAR *sections, const TCHAR *testna
                if (currprefs.fpu_model < 0) {
                        currprefs.fpu_model = currprefs.cpu_model;
                        if (currprefs.fpu_model == 68020 || currprefs.fpu_model == 68030) {
-                               currprefs.fpu_model == 68882;
+                               currprefs.fpu_model = 68882;
                        }
                } else if (currprefs.cpu_model >= 68040) {
                        currprefs.fpu_model = currprefs.cpu_model;
index 4c073f929e5dfaddd8af110dd47d63699411fe0e..e8c649b38e48e7d0970f84c5576d764b287c3a76 100644 (file)
@@ -1,5 +1,5 @@
 
-#define DATA_VERSION 18
+#define DATA_VERSION 20
 
 #define CT_FPREG 0
 #define CT_DREG 0
 #define CT_OVERRIDE_REG (0x80 | 0x40 | 0x10)
 #define CT_BRANCHED 0x40
 
-#define OPCODE_AREA 32
+#define OPCODE_AREA 48
 #define BRANCHTARGET_AREA 4
+
+// MOVEA.L A0,A0
+// not NOP because on 68040 NOP generates T0 trace.
+#define NOP_OPCODE 0x2048
+#define ILLG_OPCODE 0x4afc
index 73c6d553e91734ab41cad6c9cdccc7b19429fbd4..f42b0232c7124412a7f5569e0bd9aaaa18397fe1 100644 (file)
@@ -43,9 +43,9 @@ high_rom=D:\amiga\roms\Kickstart v3.1 rev 40.63 (1993)(Commodore)(A500-A600-A200
 ; main test memory start and size (real hardware must have RAM in this address space)
 test_memory_start=0x860000
 ;test_memory_start=0x68800000
+;test_memory_start=0x43800000
 ;test_memory_start=0x07800000
-;test_memory_start=0x340000
-test_memory_size=0x40000
+test_memory_size=0xa0000
 
 ; address where test instructions are located
 ; if not defined: mid point of test memory
@@ -61,7 +61,7 @@ min_opcode_test_rounds=0
 ; test word or long odd data access address errors (68000/010 only)
 ; 0 = do not generate address errors
 ; 1 = include address errors
-; 2 = only generate test instructions that generate address errors
+; 2 = only generate test instructions that generate address errors (trace is allowed)
 feature_exception3_data=0
 
 ; test branches to odd addresses
@@ -149,10 +149,12 @@ feature_sr_mask=0x0000
 
 ; generate loop test: label: <test instruction> dbf dn,label
 ; value: 0 = disabled, >0 = number of loops
-feature_loop_mode=0
-feature_loop_mode_register=7
+feature_loop_mode=0
+feature_loop_mode_register=7
 ; only generate 68010 loop mode compatible instructions
-feature_loop_mode_68010=0
+: feature_loop_mode_68010=0
+; reload changed address register(s) (-(an) or (an)+) after each round
+; feature_loop_mode_reload=1
 
 ; 68020+ addressing modes (this makes test files much larger if other addressing modes are also enabled)
 ; currently does not generate any reserved mode bit combinations.
@@ -204,8 +206,10 @@ mode=all
 [test=IRQ]
 enabled=0
 cpu=68000-68010
-mode=nop,ext,swap
+feature_sr_mask=0x8000
 feature_interrupts=1
+mode=jsr,jmp,bsr,bcc,dbcc,nop,exg,swap,stop,mvsr2,mv2sr,andsr,eorsr,orsr
+min_opcode_test_rounds=100
 
 ; source EA address error
 [test=AE_SRC]
@@ -255,6 +259,8 @@ feature_safe_memory_mode=P
 feature_target_opcode_offset=2,4,6,8,10,12,14,16
 opcode_memory_start=0x87ffee
 test_memory_size=0xa0000
+test_memory_size=0x100000
+opcode_memory_start=0x87ffa0
 mode=all
 
 ; source EA read bus error (requires extra hardware)
@@ -266,7 +272,9 @@ feature_safe_memory_size=0x80000
 feature_safe_memory_mode=R
 feature_target_src_ea=0x87fffc,0x87fffd,0x87fffe,0x87ffff,0x880000,0x880001,0x880002,0x880003,0x880004
 feature_target_dst_ea=
-test_memory_size=0xa0000
+test_memory_start=0x860000
+test_memory_size=0x100000
+opcode_memory_start=0x87ffa0
 mode=all
 
 ; destination EA read bus error (requires extra hardware)
@@ -278,7 +286,9 @@ feature_safe_memory_size=0x80000
 feature_safe_memory_mode=R
 feature_target_src_ea=
 feature_target_dst_ea=0x87fffc,0x87fffd,0x87fffe,0x87ffff,0x880000,0x880001,0x880002,0x880003,0x880004
-test_memory_size=0xa0000
+test_memory_start=0x860000
+test_memory_size=0x100000
+opcode_memory_start=0x87ffa0
 mode=all
 
 ; source EA (=RMW instructions like NOT have only source EA) write bus error (requires extra hardware)
@@ -293,7 +303,8 @@ feature_target_dst_ea=
 opcode_memory_start=0x8fffa0
 test_memory_start=0x880000
 test_memory_size=0x100000
-mode=all
+mode=moves
+;mode=all
 
 ; destination EA write bus error (requires extra hardware)
 [test=BE_DSTW]
@@ -309,11 +320,15 @@ test_memory_start=0x880000
 test_memory_size=0x100000
 mode=all
 
+
 ; 68010 loop mode compatible instructions
-[test=loopmode]
+[test=LM]
 enabled=0
 cpu=68010
 feature_loop_mode_68010=1
+feature_loop_mode=3
+feature_loop_mode_register=7
+min_opcode_test_rounds=100
 mode=all
 
 ; **************
@@ -325,9 +340,17 @@ mode=all
 [test=Basic]
 enabled=0
 cpu=68020-68060
-feature_sr_mask=0xd000
+feature_sr_mask=0xf000
 mode=all
 
+; interrupt exception
+[test=IRQ]
+enabled=0
+cpu=68020-68060
+mode=jsr,jmp,bsr,bcc,dbcc,nop,exg,swap,stop,mvsr2,mv2sr,andsr,eorsr,orsr
+min_opcode_test_rounds=100
+feature_interrupts=1
+
 ; 68020+ addressing mode tests
 [test=FFEXT_SRC]
 enabled=0
@@ -349,6 +372,7 @@ mode=add,move
 [test=AE]
 enabled=0
 cpu=68020-68060
+feature_sr_mask=0xd000
 feature_exception3_instruction=2
 mode=all
 
@@ -356,6 +380,7 @@ mode=all
 [test=ODD_STK]
 enabled=0
 cpu=68020-68060
+feature_sr_mask=0xd000
 feature_usp=2
 mode=rts,rtd,rtr,jsr,bsr,link,unlk,pea
 
@@ -363,6 +388,7 @@ mode=rts,rtd,rtr,jsr,bsr,link,unlk,pea
 [test=ODD_EXC]
 enabled=0
 cpu=68020-68060
+feature_sr_mask=0xd000
 feature_exception_vectors=0x000123
 mode=mv2sr.w,mvsr2.w,mvusp2r,mvr2usp,illegal,chk,trap,trapv,orsr.w,eorsr.w,andsr.w,divu,divs,divul,divsl
 
@@ -370,7 +396,8 @@ mode=mv2sr.w,mvsr2.w,mvusp2r,mvr2usp,illegal,chk,trap,trapv,orsr.w,eorsr.w,andsr
 [test=ODD_IRQ]
 enabled=0
 cpu=68020-68060
-mode=nop,ext,swap
+feature_sr_mask=0xd000
+mode=ext,swap
 feature_interrupts=1
 feature_exception_vectors=0x000123
 
@@ -431,3 +458,18 @@ fpu=68882
 exceptions=11,55,60,61
 feature_flags_mode=2
 mode=fillegal
+
+; ******************
+; JIT loop mode test
+; ******************
+
+[test=JITLM]
+enabled=0
+cpu=68020-68060
+cpu_address_space=68020
+feature_loop_mode=10
+feature_loop_mode_reload=1
+feature_loop_mode_register=7
+mode=eor
+feature_instruction_size=W
+verbose=0
index 665be6148d9bd65cbd1ade9d82b39919cb336bd7..26c80632a76d71ea0a66f593fe5f9e3c553bf447 100644 (file)
@@ -133,6 +133,7 @@ static short quit;
 static uae_u8 ccr_mask;
 static uae_u32 addressing_mask = 0x00ffffff;
 static uae_u32 interrupt_mask;
+static short instructionsize;
 static short disasm;
 static short basicexcept;
 static short excskipccr;
@@ -161,6 +162,7 @@ static uae_u8 dstaddr[SIZE_STORED_ADDRESS];
 static uae_u8 branchtarget[SIZE_STORED_ADDRESS];
 static uae_u8 stackaddr[SIZE_STORED_ADDRESS];
 static uae_u32 stackaddr_ptr;
+static uae_u8 *opcode_memory_end;
 
 static char opcode[32], group[32], cpustr[10];
 
@@ -304,7 +306,7 @@ static void endinfo(void)
                        break;
                uae_u16 v = (p[i] << 8) | (p[i + 1]);
                printf("%08x %04x\n", (uae_u32)&p[i], v);
-               if (v == 0x4afc && i > 0)
+               if (v == ILLG_OPCODE && i > 0)
                        break;
        }
        printf("\n");
@@ -1057,11 +1059,17 @@ static void restoreahist(void)
 static uae_u8 *restore_bytes(uae_u8 *mem, uae_u8 *p)
 {
        uae_u8 *addr = mem;
-       uae_u8 v = *p++;
+       uae_u16 v = *p++;
        addr += v >> 5;
        v &= 31;
-       if (v == 0)
+       if (v == 31) {
+               v = *p++;
+               if (v == 0) {
+                       v = 256;
+               }
+       } else if (v == 0) {
                v = 32;
+       }
 #ifndef _MSC_VER
        xmemcpy(addr, p, v);
 #endif
@@ -1266,7 +1274,7 @@ static void out_disasm(uae_u8 *mem)
        uae_u8 *p = mem;
        int offset = 0;
        int lines = 0;
-       while (lines++ < 7) {
+       while (lines++ < 15) {
                int v = 0;
                if (!is_valid_word(p)) {
                        sprintf(outbp, "%08x -- INACCESSIBLE --\n", (uae_u32)p);
@@ -1286,14 +1294,14 @@ static void out_disasm(uae_u8 *mem)
                                }
                                sprintf(outbp, "%04x ", v);
                                outbp += strlen(outbp);
-                               if (v == 0x4e71)
+                               if (v == NOP_OPCODE)
                                        lines--;
                        }
                        sprintf(outbp, " %s\n", tmpbuffer);
                        outbp += strlen(outbp);
                        if (!is_valid_word((uae_u8*)(code + offset)))
                                break;
-                       if (v <= 0 || code[offset] == 0x4afc)
+                       if (v <= 0 || code[offset] == ILLG_OPCODE)
                                break;
                        while (v > 0) {
                                offset++;
@@ -1391,19 +1399,22 @@ static void out_regs(struct registers *r, struct registers *r1, struct registers
                        } else if ((i % 8) != 0) {
                                strcat(outbp, " ");
                        }
+                       uae_u32 v1 = r1->regs[i];
+                       uae_u32 v2 = r2->regs[i];
+                       uae_u32 sv = sreg->regs[i];
                        outbp += strlen(outbp);
-                       sprintf(outbp, "%c%d:%c%08x", i < 8 ? 'D' : 'A', i & 7, r1->regs[i] != r2->regs[i] ? '*' : ' ', r->regs[i]);
+                       sprintf(outbp, "%c%d:%c%08x", i < 8 ? 'D' : 'A', i & 7, v1 == v2 && v1 != sv ? '*' : (v1 != v2 ? '!' : ' '), r->regs[i]);
                        outbp += strlen(outbp);
                }
                *outbp++ = '\n';
-               sprintf(outbp, "SR:%c%04x      PC: %08x ISP: %08x B: %d", r1->sr != r2->sr ? '*' : ' ', r->sr, r->pc, r->ssp, branched);
+               sprintf(outbp, "SR:%c%04x      PC: %08x ISP: %08x", r1->sr == r2->sr && r1->sr != sreg->sr ? '*' : (r1->sr != r2->sr ? '!' : ' '), r->sr, r->pc, r->ssp);
        } else {
                // output only lines that have at least one modified register to save screen space
                for (int i = 0; i < 4; i++) {
                        int diff = 0;
                        for (int j = 0; j < 4; j++) {
                                int idx = i * 4 + j;
-                               if (r1->regs[idx] != r2->regs[idx]) {
+                               if (r1->regs[idx] != sreg->regs[idx]) {
                                        diff = 1;
                                }
                        }
@@ -1412,19 +1423,26 @@ static void out_regs(struct registers *r, struct registers *r1, struct registers
                                        int idx = i * 4 + j;
                                        if (j > 0)
                                                *outbp++ = ' ';
-                                       sprintf(outbp, "%c%d:%c%08x", idx < 8 ? 'D' : 'A', idx & 7, r->regs[idx] != r2->regs[idx] ? '*' : ' ', r->regs[idx]);
+                                       uae_u32 v1 = r1->regs[idx];
+                                       uae_u32 v2 = r2->regs[idx];
+                                       uae_u32 sv = sreg->regs[idx];
+                                       sprintf(outbp, "%c%d:%c%08x", idx < 8 ? 'D' : 'A', idx & 7, v1 == v2 && v1 != sv ? '*' : ((v1 != v2) ? '!' : ' '), r->regs[idx]);
                                        outbp += strlen(outbp);
                                }
                                *outbp++ = '\n';
                        }
                }
-               sprintf(outbp, "SR:%c%04x/%04x PC: %08x ISP: %08x B: %d", r->sr != r2->sr ? '*' : ' ', r->sr, r->expsr, r->pc, r->ssp, branched);
+               sprintf(outbp, "SR:%c%04x/%04x PC: %08x ISP: %08x", r1->sr == r2->sr && r1->sr != sreg->sr ? '*' : (r1->sr != r2->sr ? '!' : ' '), r->sr, r->expsr, r->pc, r->ssp);
        }
        outbp += strlen(outbp);
        if (cpu_lvl >= 2 && cpu_lvl <= 4) {
                sprintf(outbp, " MSP: %08x", r->msp);
                outbp += strlen(outbp);
        }
+       if (branched) {
+               sprintf(outbp, " B: %d", branched);
+               outbp += strlen(outbp);
+       }
        *outbp++ = '\n';
        *outbp = 0;
 
@@ -1563,6 +1581,7 @@ static uae_u8 *validate_exception(struct registers *regs, uae_u8 *p, short excnu
                last_exception_extra = *p++;
                if (last_exception_extra & 0x40) {
                        *group2with1 = *p++;
+                       exceptioncount[0][*group2with1]++;
                        last_exception_extra &= ~0x40;
                }
                if ((last_exception_extra & 0x3f) == 9) {
@@ -1570,7 +1589,14 @@ static uae_u8 *validate_exception(struct registers *regs, uae_u8 *p, short excnu
                        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");
+                               uae_u32 pc;
+                               if (!(last_exception_extra & 0x80)) {
+                                       pc = exceptiontableinuse + (excnum - 2) * 2;
+                               } else {
+                                       pc = opcode_memory_addr;
+                                       p = restore_rel_ordered(p + 2, &pc);
+                               }
+                               sprintf(outbp, "Expected trace exception (PC=%08x) but got none.\n", pc);
                                outbp += strlen(outbp);
                                *experr = 1;
                        } else if (!(last_exception_extra & 0x80)) {
@@ -1804,6 +1830,12 @@ static uae_u8 *validate_exception(struct registers *regs, uae_u8 *p, short excnu
                                                }
                                                alts = 3;
                                        }
+                                       if (instructionsize == 0) {
+                                               // if byte wide bus error, ignore high byte of input and output buffer
+                                               // contents of high byte depends on used alu operation and instruction type and more..
+                                               masked_exception[16] = 0;
+                                               masked_exception[20] = 0;
+                                       }
                                        p += 2;
                                }
                                break;
@@ -1969,6 +2001,30 @@ static int get_cycles_amiga(void)
        int gotcycles = (endcycle - startcycle) * 2;
        return gotcycles;
 }
+
+static uae_u16 test_intena, test_intreq;
+
+static void set_interrupt(void)
+{
+       if (interrupt_count < 15) {
+               volatile uae_u16 *intena = (uae_u16 *)0xdff09a;
+               volatile uae_u16 *intreq = (uae_u16 *)0xdff09c;
+               uae_u16 mask = 1 << interrupt_count;
+               test_intena = mask | 0x8000 | 0x4000;
+               test_intreq = mask | 0x8000;
+               *intena = test_intena;
+               *intreq = test_intreq;
+       }
+}
+
+static void clear_interrupt(void)
+{
+       volatile uae_u16 *intena = (uae_u16 *)0xdff09a;
+       volatile uae_u16 *intreq = (uae_u16 *)0xdff09c;
+       *intena = 0x7fff;
+       *intreq = 0x7fff;
+}
+
 #endif
 
 static int check_cycles(int exc, short extratrace, short extrag2w1, struct registers *lregs)
@@ -2056,7 +2112,6 @@ static int check_cycles(int exc, short extratrace, short extrag2w1, struct regis
                        // interrupt
                        expectedcycles += 2 + 4 + 4;
                }
-               exceptioncount[0][extrag2w1]++;
        }
 
        if (0 || abs(gotcycles - expectedcycles) > cycles_range) {
@@ -2411,14 +2466,14 @@ static uae_u8 *validate_test(uae_u8 *p, short ignore_errors, short ignore_sr, st
                                errflag |= 1 << 16;
                        }
                        if ((tregs->expsr & 0xff) != (tregs->sr & 0xff)) {
-                               sprintf(outbp, "Exception stacked CCR != CCR at start of exception handler!\n");
+                               sprintf(outbp, "Exception stacked CCR (%04x) != CCR (%04x) at start of exception handler!\n", tregs->sr, tregs->expsr);
                                outbp += strlen(outbp);
                                errflag |= 1 << 16;
                        }
                        lregs->sr = val;
                } else if (mode == CT_PC) {
                        uae_u32 val = lregs->pc;
-                       p = restore_rel(p, &val, 0);
+                       p = restore_rel(p, &val, 1);
                        pc_changed = 0;
                        lregs->pc = val;
                } else if (mode == CT_CYCLES) {
@@ -2635,6 +2690,12 @@ static uae_u8 *validate_test(uae_u8 *p, short ignore_errors, short ignore_sr, st
                strcat(outbp, "Registers after:\n");
                outbp += strlen(outbp);
                out_regs(tregs, tregs, lregs, sregs, 0, branched2);
+#ifdef AMIGA
+               if (interrupttest) {
+                       sprintf(outbp, "INTREQ: %04x INTENA: %04x\n", test_intreq, test_intena);
+                       outbp += strlen(outbp);
+               }
+#endif
                if (exc > 1) {
                        if (!experr) {
                                sprintf(outbp, "OK: exception %d ", exc);
@@ -2708,34 +2769,6 @@ static void store_addr(uae_u32 s, uae_u8 *d)
        }
 }
 
-#ifdef AMIGA
-static const int interrupt_levels[] =
-{
-       0, 1, 1, 1, 2, 3, 3, 3, 4, 4, 4, 4, 5, 5, 6, 6, -1
-};
-
-static void set_interrupt(void)
-{
-       if (interrupt_count < 15) {
-               volatile uae_u16 *intena = (uae_u16*)0xdff09a;
-               volatile uae_u16 *intreq = (uae_u16*)0xdff09c;
-               uae_u16 mask = 1 << interrupt_count;
-               *intena = mask | 0x8000 | 0x4000;
-               *intreq = mask | 0x8000;
-       }
-       interrupt_count++;
-       interrupt_count &= 15;
-}
-
-static void clear_interrupt(void)
-{
-       volatile uae_u16 *intena = (uae_u16*)0xdff09a;
-       volatile uae_u16 *intreq = (uae_u16*)0xdff09c;
-       *intena = 0x7fff;
-       *intreq = 0x7fff;
-}
-#endif
-
 static uae_u32 xorshiftstate;
 static uae_u32 xorshift32(void)
 {
@@ -2812,13 +2845,13 @@ static void process_test(uae_u8 *p)
                store_addr(cur_regs.branchtarget, branchtarget);
                startpc = cur_regs.pc;
                endpc = cur_regs.endpc;
-               uae_u8 *opcode_memory_end = (uae_u8*)endpc;
+               opcode_memory_end = (uae_u8*)endpc;
 
                int fpumode = fpu_model && (opcode_memory[0] & 0xf0) == 0xf0;
 
                copyregs(&last_regs, &cur_regs, fpumode);
 
-               uae_u32 originalopcodeend = 0x4afc4e71;
+               uae_u32 originalopcodeend = (ILLG_OPCODE << 16) | NOP_OPCODE;
                short opcodeendsizeextra = 0;
                uae_u32 opcodeend = originalopcodeend;
                int extraccr = 0;
@@ -2849,7 +2882,6 @@ static void process_test(uae_u8 *p)
                        testcntsub = 0;
                        for (short ccr = 0;  ccr < maxccr; ccr++, testcntsub++) {
 
-                               copyregs(&test_regs, &cur_regs, fpumode);
                                fpu_approx = 0;
 
                                opcodeend = (opcodeend >> 16) | (opcodeend << 16);
@@ -2868,16 +2900,19 @@ static void process_test(uae_u8 *p)
                                                pl((uae_u8*)cur_regs.branchtarget, bv);
                                        } else if (cur_regs.branchtarget_mode == 2) {
                                                uae_u16 bv = gw((uae_u8 *)cur_regs.branchtarget);
-                                               if (bv == 0x4e71)
-                                                       bv = 0x4afc;
+                                               if (bv == NOP_OPCODE)
+                                                       bv = ILLG_OPCODE;
                                                else
-                                                       bv = 0x4e71;
+                                                       bv = NOP_OPCODE;
                                                pw((uae_u8 *)cur_regs.branchtarget, bv);
                                        }
                                }
 
-                               test_regs.ssp = super_stack_memory - 0x80;
-                               test_regs.msp = super_stack_memory;
+                               cur_regs.ssp = super_stack_memory - 0x80;
+                               cur_regs.msp = super_stack_memory;
+
+                               copyregs(&test_regs, &cur_regs, fpumode);
+
                                test_regs.pc = startpc;
                                test_regs.fpiar = startpc;
                                test_regs.cyclest = 0xffffffff;
@@ -2911,6 +2946,12 @@ static void process_test(uae_u8 *p)
                                        }
                                }
 
+#ifdef AMIGA
+                               if (interrupttest) {
+                                       interrupt_count = *p++;
+                               }
+#endif
+
                                while ((*p) == CT_OVERRIDE_REG) {
                                        p++;
                                        uae_u8 v = *p++;
@@ -3179,7 +3220,7 @@ static int test_mnemo(const char *opcode)
        int headoffset = 0;
        v = read_u32(headerfile, &headoffset);
        if (v != DATA_VERSION) {
-               printf("Invalid test data file (header)\n");
+               printf("Invalid test data file (header %08x<>%08x)\n", v, DATA_VERSION);
                exit(0);
        }
 
@@ -3317,7 +3358,7 @@ static int test_mnemo(const char *opcode)
                        break;
                }
                if (gl(test_data) != DATA_VERSION) {
-                       printf("Invalid test data file (header)\n");
+                       printf("Invalid test data file (header, %08x<>%08x)\n", gl(test_data), DATA_VERSION);
                        exit(0);
                }
                if (gl(test_data + 4) != starttimeid) {
@@ -3329,6 +3370,8 @@ static int test_mnemo(const char *opcode)
                        free(test_data);
                        exit(0);
                }
+               uae_u32 flags = gl(test_data + 8);
+               instructionsize = flags & 3;
 
                // last file?
                int last = test_data[test_data_size - 1] == CT_END_FINISH;
index 0de203a52539c086492700b22810da7c6f0ed898..33d9391d7775171616f7ef63e3e2bab2e9282a4f 100644 (file)
@@ -131,6 +131,13 @@ If mismatch is detected, opcode word(s), instruction disassembly, registers befo
 
 Change log:
 
+31.05.2020
+
+- 68010 bus error and byte size memory access: ignore bus error stack frame high byte of input and output buffers. Their contents depends on type of ALU operation, instruction type and probably more..
+- If trace exception was generated after some other exception ("+EXC 9" in stack frame info line), it was not counted in final exception totals (Exx=1234)
+- Replaced NOP with MOVEA.L A0,A0 in test code because 68040 NOP is considered branching instruction and triggers T0 trace.
+- Interrupt test improved.
+
 17.05.2020
 
 - Rewritten disassembler to use indirect and validated opword reads, now it is safe to use when testing bus errors.