]> git.unchartedbackwaters.co.uk Git - francis/winuae.git/commitdiff
CPU tester IPL timing rewrite. Merged test files (multiple small dat files -> single...
authorToni Wilen <twilen@winuae.net>
Thu, 25 Aug 2022 19:14:31 +0000 (22:14 +0300)
committerToni Wilen <twilen@winuae.net>
Thu, 25 Aug 2022 19:14:31 +0000 (22:14 +0300)
cputest.cpp
cputest/asm.S
cputest/cputest_defines.h
cputest/cputestgen.ini
cputest/main.c

index 7e01e081ad43e04f1eba8eab091002b03bca66e1..3bb42a754c876ea62c0c10f79fd7120efd754218 100644 (file)
@@ -71,7 +71,8 @@ static int feature_exception_vectors = 0;
 static int feature_interrupts = 0;
 static int feature_instruction_size = 0;
 static int fpu_min_exponent, fpu_max_exponent;
-static int rnd_seed;
+static int max_file_size;
+static int rnd_seed, rnd_seed_prev;
 static TCHAR *feature_instruction_size_text = NULL;
 static uae_u32 feature_addressing_modes[2];
 static int feature_gzip = 0;
@@ -87,6 +88,7 @@ static uae_u8 exceptionenabletable[256];
 #define MAX_REGDATAS 32
 static int regdatacnt;
 static struct regdata regdatas[MAX_REGDATAS];
+static uae_u32 ignore_register_mask;
 
 #define HIGH_MEMORY_START (addressing_mask == 0xffffffff ? 0xffff8000 : 0x00ff8000)
 
@@ -143,6 +145,8 @@ static uae_u16 trace_store_sr;
 static int generate_address_mode;
 static int test_memory_access_mask;
 static uae_u32 opcode_memory_address;
+static uaecptr branch_target;
+static uaecptr branch_target_pc;
 
 static uae_u8 imm8_cnt;
 static uae_u16 imm16_cnt;
@@ -522,7 +526,9 @@ void put_byte_test(uaecptr addr, uae_u32 v)
                return;
        if (feature_interrupts >= 2 && addr == IPL_TRIGGER_ADDR) {
                add_memory_cycles(1);
+#if IPL_TRIGGER_ADDR_SIZE == 1
                interrupt_cycle_cnt = INTERRUPT_CYCLES;
+#endif
                return;
        }
        check_bus_error(addr, 1, regs.s ? 5 : 1);
@@ -550,6 +556,13 @@ void put_word_test(uaecptr addr, uae_u32 v)
 {
        if (!testing_active && is_nowrite_address(addr, 1))
                return;
+       if (feature_interrupts >= 2 && addr == IPL_TRIGGER_ADDR) {
+               add_memory_cycles(1);
+#if IPL_TRIGGER_ADDR_SIZE == 2
+               interrupt_cycle_cnt = INTERRUPT_CYCLES;
+#endif
+               return;
+       }
        check_bus_error(addr, 1, regs.s ? 5 : 1);
        if (addr & 1) {
                put_byte_test(addr + 0, v >> 8);
@@ -827,10 +840,19 @@ bool is_cycle_ce(uaecptr addr)
        return 0;
 }
 
-void ipl_fetch(void)
+// ipl check was early enough, interrupt possible after current instruction
+void ipl_fetch_now(void)
 {
-       if (regs.ipl_pin) {
+       if (regs.ipl[0] != regs.ipl_pin) {
                regs.ipl[0] = regs.ipl_pin;
+               regs.ipl[1] = 0;
+       }
+}
+// ipl check was too late, interrupt possible after following instruction
+void ipl_fetch_next(void)
+{
+       if (regs.ipl[1] != regs.ipl_pin) {
+               regs.ipl[1] = regs.ipl_pin;
        }
 }
 
@@ -899,7 +921,7 @@ uae_u32 get_disp_ea_test(uae_u32 base, uae_u32 dp)
        uae_s32 regd = regs.regs[reg];
        if ((dp & 0x800) == 0)
                regd = (uae_s32)(uae_s16)regd;
-       return base + (uae_s8)dp + regd;
+       return base + (uae_s32)((uae_s8)(dp)) + regd;
 }
 
 static void activate_trace(void)
@@ -1014,6 +1036,11 @@ void REGPARAM2 MakeFromSR(void)
        MakeFromSR_x(0);
 }
 
+void REGPARAM2 MakeFromSR_STOP(void)
+{
+       MakeFromSR_x(-1);
+}
+
 void REGPARAM2 MakeFromSR_intmask(uae_u16 oldsr, uae_u16 newsr)
 {
 }
@@ -1022,6 +1049,10 @@ void intlev_load(void)
 {
 }
 
+void checkint(void)
+{
+}
+
 void cpu_halt(int halt)
 {
        cpu_halted = halt;
@@ -1590,7 +1621,7 @@ int cctrue(int cc)
        return 0;
 }
 
-static uae_u32 xorshiftstate;
+static uae_u32 xorshiftstate, xorshiftstate_prev;
 static uae_u32 xorshift32(void)
 {
        uae_u32 x = xorshiftstate;
@@ -1601,7 +1632,7 @@ static uae_u32 xorshift32(void)
        return xorshiftstate;
 }
 
-static int rand16_cnt;
+static int rand16_cnt, rand16_cnt_prev;
 static uae_u16 rand16(void)
 {
        int cnt = rand16_cnt & 15;
@@ -1620,7 +1651,7 @@ static uae_u16 rand16(void)
                v |= 1;
        return v;
 }
-static int rand32_cnt;
+static int rand32_cnt, rand32_cnt_prev;
 static uae_u32 rand32(void)
 {
        int cnt = rand32_cnt & 31;
@@ -1643,7 +1674,7 @@ static uae_u32 rand32(void)
 // first 3 values: positive
 // next 4 values: negative
 // last: zero
-static int rand8_cnt;
+static int rand8_cnt, rand8_cnt_prev;
 static uae_u8 rand8(void)
 {
        int cnt = rand8_cnt & 7;
@@ -1777,6 +1808,8 @@ static bool regchange(int reg, uae_u32 *regs)
                return false;
        if (feature_loop_mode_register == reg)
                return false;
+       if ((1 << reg) & ignore_register_mask)
+               return false;
 
        // don't unnecessarily modify static forced register
        for (int i = 0; i < regdatacnt; i++) {
@@ -1931,13 +1964,84 @@ static void compressfile(TCHAR *path, int flags)
 
 static void compressfiles(const TCHAR *dir)
 {
-       for (int i = 1; i < filecount; i++) {
+       for (int i = 0; i < filecount; i++) {
                TCHAR path[1000];
                _stprintf(path, _T("%s/%04d.dat"), dir, i);
                compressfile(path, 1);
        }
 }
 
+static void mergefiles(const TCHAR *dir)
+{
+       int tsize = 0;
+       FILE *of = NULL;
+       int oi = -1;
+       unsigned char zero[4] = { 0, 0, 0, 0 };
+       unsigned char head[4] = { 0xff, 0xff, 0xff, 0xff };
+       TCHAR opath[1000];
+       for (int i = 0; i < filecount; i++) {
+               TCHAR path[1000];
+               _stprintf(path, _T("%s/%04d.dat"), dir, i);
+               if (feature_gzip & 1) {
+                       if (_tcschr(path, '.')) {
+                               path[_tcslen(path) - 1] = 'z';
+                       } else {
+                               _tcscat(path, _T(".gz"));
+                       }
+               }
+               FILE *f = _tfopen(path, _T("rb"));
+               fseek(f, 0, SEEK_END);
+               int size = ftell(f);
+               fseek(f, 0, SEEK_SET);
+               if (tsize > 0 && max_file_size > 0 && tsize + size >= max_file_size * 1024) {
+                       fwrite(head, 1, 4, of);
+                       fwrite(zero, 1, 4, of);
+                       fclose(of);
+                       of = NULL;
+                       tsize = 0;
+               }
+               uae_u8 *mem = (uae_u8 *)malloc(size);
+               fread(mem, 1, size, f);
+               fclose(f);
+               if (!of) {
+                       oi++;
+                       _stprintf(opath, _T("%s/%04d.dat"), dir, oi);
+                       if (feature_gzip & 1) {
+                               if (_tcschr(opath, '.')) {
+                                       opath[_tcslen(opath) - 1] = 'z';
+                               } else {
+                                       _tcscat(opath, _T(".gz"));
+                               }
+                       }
+                       of = _tfopen(opath, _T("wb"));
+                       if (!of) {
+                               wprintf(_T("Couldn't open '%s'\n"), opath);
+                               abort();
+                       }
+               }
+               if (oi != i) {
+                       _tunlink(path);
+               }
+               unsigned char b;
+               fwrite(head, 1, 4, of);
+               b = size >> 24;
+               fwrite(&b, 1, 1, of);
+               b = size >> 16;
+               fwrite(&b, 1, 1, of);
+               b = size >> 8;
+               fwrite(&b, 1, 1, of);
+               b = size >> 0;
+               fwrite(&b, 1, 1, of);
+               fwrite(mem, 1, size, of);
+               tsize += size;
+               free(mem);
+       }
+       if (of) {
+               fwrite(zero, 1, 4, of);
+               fclose(of);
+       }
+}
+
 static void save_memory(const TCHAR *path, const TCHAR *name, uae_u8 *p, int size)
 {
        TCHAR fname[1000];
@@ -2615,6 +2719,8 @@ static int create_ea_random(uae_u16 *opcodep, uaecptr pc, int mode, int reg, str
                                } else {
                                        break;
                                }
+                       } else if (((1 << reg) & ignore_register_mask)) {
+                               return -1;
                        } else {
                                break;
                        }
@@ -2726,7 +2832,7 @@ static int create_ea_random(uae_u16 *opcodep, uaecptr pc, int mode, int reg, str
                                        if (currprefs.cpu_model >= 68020)
                                                v &= ~0x100;
                                        ereg = v >> 12;
-                                       if (loopmodelimit && (ereg == 0 || ereg == 8 + 3 || ereg == 8 + 7 || ereg == feature_loop_mode_register)) {
+                                       if (loopmodelimit && (ereg == 0 || ereg == 8 + 3 || ereg == 8 + 7 || ((1 << ereg) & ignore_register_mask))) {
                                                continue;
                                        }
                                        break;
@@ -2781,7 +2887,10 @@ static int create_ea_random(uae_u16 *opcodep, uaecptr pc, int mode, int reg, str
                                break;
                        }
                        int ereg = v >> 12;
-                       if (loopmodelimit && (ereg == 0 || ereg == 8 + 3 || ereg == 8 + 7 || ereg == feature_loop_mode_register)) {
+                       if (loopmodelimit && (ereg == 0 || ereg == 8 + 3 || ereg == 8 + 7)) {
+                               return -1;
+                       }
+                       if ((1 << ereg) & ignore_register_mask) {
                                return -1;
                        }
                        *regused = ereg;
@@ -3918,10 +4027,7 @@ static bool check_interrupts(void)
 
 static int get_ipl(void)
 {
-       if (cpu_cycles + 4 > regs.ipl_time) {
-               return regs.ipl[0];
-       }
-       return regs.ipl[1];
+       return regs.ipl[0];
 }
 
 static void execute_ins(uaecptr endpc, uaecptr targetpc, struct instr *dp, bool fpumode)
@@ -3968,7 +4074,6 @@ static void execute_ins(uaecptr endpc, uaecptr targetpc, struct instr *dp, bool
        regs.loop_mode = 0;
        regs.ipl_pin = 0;
        regs.ipl[0] = regs.ipl[1] = 0;
-       regs.ipl_time = 0;
        interrupt_level = 0;
        interrupt_cycle_cnt = 0;
        test_exception_orig = 0;
@@ -4097,10 +4202,16 @@ static void execute_ins(uaecptr endpc, uaecptr targetpc, struct instr *dp, bool
                        break;
                }
 
+               if (test_exception) {
+                       break;
+               }
+
                if (get_ipl() > regs.intmask) {
                        Exception(24 + get_ipl());
                        break;
                }
+               regs.ipl[0] = regs.ipl[1];
+               regs.ipl[1] = 0;
 
                if ((regs.pc == endpc || regs.pc == targetpc) && !cpu_stopped && feature_interrupts < 2) {
                        // Trace is only added as an exception if there was no other exceptions
@@ -4177,8 +4288,8 @@ static void execute_ins(uaecptr endpc, uaecptr targetpc, struct instr *dp, bool
                if (test_exception >= 24 && test_exception <= 24 + 8) {
                        if (test_exception_addr != opcode_memory_address &&
                                test_exception_addr != opcode_memory_address - 2 &&
-                               test_exception_addr != test_instruction_end_pc)
-                       {
+                               test_exception_addr != test_instruction_end_pc &&
+                               test_exception_addr != branch_target) {
                                test_exception = -1;
                        }
                }
@@ -4529,6 +4640,16 @@ static void test_mnemo(const TCHAR *path, const TCHAR *mnemo, const TCHAR *ovrfi
                registers[8 + 3] = test_memory_start; // A3 = start of test memory
        }
 
+       ignore_register_mask = 0;
+       if (feature_loop_mode_register >= 0) {
+               ignore_register_mask |= 1 << feature_loop_mode_register;
+       }
+       if (feature_interrupts >= 2) {
+               // D0 and D7 is modified by delay code
+               ignore_register_mask |= 1 << 0;
+               ignore_register_mask |= 1 << 7;
+       }
+
        registers[8 + 6] = opcode_memory_start - 0x100;
        registers[15] = user_stack_memory_use;
 
@@ -4613,9 +4734,23 @@ 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;
 
+       rnd_seed_prev = rnd_seed;
+       rand8_cnt_prev = rand8_cnt;
+       rand16_cnt_prev = rand16_cnt_prev;
+       rand32_cnt_prev = rand32_cnt_prev;
+       xorshiftstate_prev = xorshiftstate;
+
        for (;;) {
                int got_something = 0;
 
+               if (feature_interrupts >= 2) {
+                       rnd_seed = rnd_seed;
+                       rand8_cnt = rand8_cnt;
+                       rand16_cnt = rand16_cnt_prev;
+                       rand32_cnt = rand32_cnt_prev;
+                       xorshiftstate = xorshiftstate_prev;
+               }
+
                target_ea_bak[0] = target_ea[0];
                target_ea_bak[1] = target_ea[1];
                target_ea_bak[2] = target_ea[2];
@@ -4855,18 +4990,50 @@ static void test_mnemo(const TCHAR *path, const TCHAR *mnemo, const TCHAR *ovrfi
                                                        // move ccr,d7
                                                        put_word_test(pc + 0, 0x42c7); // 4 cycles
                                                }
+                                               pc += 2;
+#if IPL_TRIGGER_ADDR_SIZE == 1
+                                               // move.b #x,xxx.L (4 * 4 + 4)
+                                               put_long_test(pc, (0x13fc << 16) | IPL_TRIGGER_DATA);
+#else
+                                               // move.w #x,xxx.L (4 * 4 + 4)
+                                               put_long_test(pc, (0x33fc << 16) | IPL_TRIGGER_DATA);
+#endif
+                                               pc += 4;
+                                               put_long_test(pc, IPL_TRIGGER_ADDR);
+                                               pc += 4;
                                                // moveq #x,d0 (4 cycles)
-                                               put_word_test(pc + 2, 0x7000 | interrupt_delay_cnt);
-                                               // move.b d0,0xdc0000 (RTCW) (8 + 4 + 4)
-                                               put_word_test(pc + 4, 0x13c0);
-                                               put_long_test(pc + 6, IPL_TRIGGER_ADDR);
+                                               int shift = interrupt_delay_cnt;
+                                               int ashift;
+                                               if (shift > 63) {
+                                                       shift -= 63;
+                                                       ashift = 63;
+                                               } else {
+                                                       ashift = 0;
+                                               }
+                                               if (shift > 63 || ashift > 63) {
+                                                       wprintf(_T("IPL delay count too large!\n"));
+                                                       abort();
+                                               }
+
+                                               put_word_test(pc, 0x7000 | (ashift & 63));
+                                               pc += 2;
                                                // ror.l d0,d0 (4 + 4 + d0 * 2 cycles)
-                                               put_word_test(pc + 10, 0xe0b8);
+                                               put_word_test(pc, 0xe0b8);
+                                               pc += 2;
+                                               // moveq #x,d0 (4 cycles)
+                                               put_word_test(pc, 0x7000 | (shift & 63));
+                                               pc += 2;
+                                               // ror.l d0,d0 (4 + 4 + d0 * 2 cycles)
+                                               put_word_test(pc, 0xe0b8);
+                                               pc += 2;
                                                // restore CCR
                                                // move d7,ccr
-                                               put_word_test(pc + 12, 0x44c7); // 12 cycles
-                                               put_word_test(pc + 14, NOP_OPCODE); // 4 cycles
-                                               pc += 16;
+                                               put_word_test(pc, 0x44c7); // 12 cycles
+                                               pc += 2;
+                                               put_word_test(pc, NOP_OPCODE); // 4 cycles
+                                               pc += 2;
+                                               put_word_test(pc, NOP_OPCODE); // 4 cycles
+                                               pc += 2;
                                                if (feature_interrupts >= 3) {
                                                        // or #$8000,sr
                                                        put_long_test(pc, 0x007c8000);
@@ -5004,7 +5171,7 @@ static void test_mnemo(const TCHAR *path, const TCHAR *mnemo, const TCHAR *ovrfi
                                                pc += handle_specials_misc(opc, pc, dp, &isconstant_src);
 
                                                if (fpumode) {
-                                                       // append fnop so that we detect pending FPU exceptions immediately
+                                                       // append FNOP so that we detect pending FPU exceptions immediately
                                                        put_long_test(pc, 0xf2800000);
                                                        pc += 4;
                                                }
@@ -5180,6 +5347,10 @@ static void test_mnemo(const TCHAR *path, const TCHAR *mnemo, const TCHAR *ovrfi
                                        uaecptr nextpc;
                                        srcaddr = 0xffffffff;
                                        dstaddr = 0xffffffff;
+
+                                       if (opc == 0x4efb && get_word_debug(opcode_memory_address + 2) == 0x06d4)
+                                               printf("");
+
                                        uae_u32 dflags = m68k_disasm_2(out, sizeof(out) / sizeof(TCHAR), opcode_memory_address, NULL, 0, &nextpc, 1, &srcaddr, &dstaddr, 0xffffffff, 0);
                                        if (verbose) {
                                                my_trim(out);
@@ -5203,6 +5374,10 @@ static void test_mnemo(const TCHAR *path, const TCHAR *mnemo, const TCHAR *ovrfi
                                                        }
                                                }
                                        }
+
+
+                                       if (srcaddr == 0x006b022e)
+                                               printf("");
                                        
                                        // disassembler may set this
                                        out_of_test_space = false;
@@ -5247,8 +5422,8 @@ static void test_mnemo(const TCHAR *path, const TCHAR *mnemo, const TCHAR *ovrfi
                                        }
 #endif
 
-                                       uaecptr branch_target = 0xffffffff;
-                                       uaecptr branch_target_pc = 0xffffffff;
+                                       branch_target = 0xffffffff;
+                                       branch_target_pc = 0xffffffff;
                                        int bc = isbranchinst(dp);
                                        if (bc) {
                                                if (bc < 0) {
@@ -5612,7 +5787,7 @@ static void test_mnemo(const TCHAR *path, const TCHAR *mnemo, const TCHAR *ovrfi
                                                        if (regs.sr & 0x2000)
                                                                prev_s_cnt++;
 
-                                                       if (subtest_count == 19)
+                                                       if (subtest_count == 77171)
                                                                printf("");
 
                                                        // execute test instruction(s)
@@ -5693,7 +5868,7 @@ static void test_mnemo(const TCHAR *path, const TCHAR *mnemo, const TCHAR *ovrfi
                                                                }
                                                                if (safe_memory_mode) {
                                                                        skipped = 1;
-                                                               }                                       
+                                                               }                               
                                                        }
 
                                                        // skip exceptions if loop mode and not CC instruction
@@ -5855,7 +6030,7 @@ static void test_mnemo(const TCHAR *path, const TCHAR *mnemo, const TCHAR *ovrfi
                                                                        }
                                                                }
                                                                if (cpu_lvl <= 1 && (last_cpu_cycles != cpu_cycles || first_cycles)) {
-                                                                       dst = store_reg(dst, CT_CYCLES, last_cpu_cycles, cpu_cycles, first_cycles  ? 0 : -1);
+                                                                       dst = store_reg(dst, CT_CYCLES, last_cpu_cycles, cpu_cycles, first_cycles  ? sz_word : -1);
                                                                        last_cpu_cycles = cpu_cycles;
                                                                        first_cycles = 0;
                                                                }
@@ -6007,19 +6182,19 @@ static void test_mnemo(const TCHAR *path, const TCHAR *mnemo, const TCHAR *ovrfi
                if (lookup->mnemo == i_ILLG || fpuopcode == FPUOPP_ILLEGAL)
                        break;
 
-               bool nextround = false;
+               int nextround = 0;
                if (target_address != 0xffffffff) {
                        target_ea_src_cnt++;
                        if (target_ea_src_cnt >= target_ea_src_max) {
                                target_ea_src_cnt = 0;
                                if (target_ea_src_max > 0)
-                                       nextround = true;
+                                       nextround = 1;
                        }
                        target_ea_dst_cnt++;
                        if (target_ea_dst_cnt >= target_ea_dst_max) {
                                target_ea_dst_cnt = 0;
                                if (target_ea_dst_max > 0)
-                                       nextround = true;
+                                       nextround = 1;
                        }
                        target_ea[0] = 0xffffffff;
                        target_ea[1] = 0xffffffff;
@@ -6032,28 +6207,28 @@ static void test_mnemo(const TCHAR *path, const TCHAR *mnemo, const TCHAR *ovrfi
                        }
                        generate_target_registers(target_address, cur_regs.regs);
                } else {
-                       nextround = true;
+                       nextround = 1;
                }
 
                // interrupt delay test
                if (feature_interrupts >= 2) {
                        interrupt_delay_cnt++;
-                       if (interrupt_delay_cnt >= MAX_INTERRUPT_DELAY) {
+                       if (interrupt_delay_cnt > 2 * 63) {
                                break;
                        } else {
-                               nextround = true;
+                               nextround = -1;
                                rounds = 1;
                                quick = 0;
                        }
                }
 
                if (target_opcode_address != 0xffffffff || target_usp_address != 0xffffffff) {
-                       nextround = false;
+                       nextround = 0;
                        target_ea_opcode_cnt++;
                        if (target_ea_opcode_cnt >= target_ea_opcode_max) {
                                target_ea_opcode_cnt = 0;
                                if (target_ea_opcode_max > 0)
-                                       nextround = true;
+                                       nextround = 1;
                        } else {
                                quick = 0;
                        }
@@ -6076,16 +6251,25 @@ static void test_mnemo(const TCHAR *path, const TCHAR *mnemo, const TCHAR *ovrfi
                        }
                }
 
-               cur_regs.regs[0] &= 0xffff;
-               cur_regs.regs[8] &= 0xffff;
-               cur_regs.regs[8 + 6]--;
-               cur_regs.regs[15] -= 2;
+               if (nextround >= 0) {
+                       cur_regs.regs[0] &= 0xffff;
+                       cur_regs.regs[8] &= 0xffff;
+                       cur_regs.regs[8 + 6]--;
+                       cur_regs.regs[15] -= 2;
+                       rnd_seed_prev = rnd_seed;
+                       rand8_cnt_prev = rand8_cnt;
+                       rand16_cnt_prev = rand16_cnt;
+                       rand32_cnt_prev = rand32_cnt;
+                       xorshiftstate_prev = xorshiftstate;
+               }
        }
 
        markfile(dir);
 
        compressfiles(dir);
 
+       mergefiles(dir);
+
        wprintf(_T("- %d tests\n"), subtest_count);
 }
 
@@ -6793,6 +6977,9 @@ static int test(struct ini_data *ini, const TCHAR *sections, const TCHAR *testna
        feature_test_rounds_opcode = 0;
        ini_getvalx(ini, sections, _T("min_opcode_test_rounds"), &feature_test_rounds_opcode);
 
+       max_file_size = 200;
+       ini_getvalx(ini, sections, _T("max_file_size"), &max_file_size);
+
        ini_getstringx(ini, sections, _T("feature_instruction_size"), &feature_instruction_size_text);
        for (int i = 0; i < _tcslen(feature_instruction_size_text); i++) {
                TCHAR c = _totupper(feature_instruction_size_text[i]);
index 40faacaf29a10c26260a985044a4438d43fa3198..0d2616e5f8b862e5804c5faa9e7aee88a2979638 100644 (file)
@@ -357,6 +357,7 @@ exception:
        move.w sr,-(sp)
 _cyclereg_address4:
        move.w CYCLEREG,cycles+2
+       move.w #0x2700,sr
        move.w #0,ACTIVITYREG
        | exception start inside this assembly code?
        cmp.l #asm_start,2+4+2(sp)
@@ -369,7 +370,11 @@ _cyclereg_address4:
        cmp.l #_exceptiontable000+(24+8)*2,2(sp)
        bcc.s .okpc
        | possibly IPL tester spurious interrupt
-       | ignore it
+       | ignore it. Mark cycle count as invalid.
+#ifdef AMIGA
+       move.w #0x0800,0xdff09c
+#endif
+       move.l #0xffffffff,cycles
        addq.l #2+4,sp
        rte
 .okpc:
@@ -398,12 +403,9 @@ _cyclereg_address4:
        bcs.s .nointerrupt
        cmp.w #24+8,d0
        bcc.s .nointerrupt
-       | possible IPL test run, delay a bit
-       | to make sure tester hardware is not pulling
-       | IPL line down anymore
-       moveq #16-1,d1
-.delay1:
-       dbf d1,.delay1
+#ifdef AMIGA
+       move.w #0x0800,0xdff09c
+#endif
 .nointerrupt:
 
        move.w (sp)+,S_SR+2(a0)
index 5aaeb9b10926d9c8dd42c31d2608a57ef6897b98..8c79a2e59e7eac029058cb26accd842ce3fa22a0 100644 (file)
@@ -1,5 +1,5 @@
 
-#define DATA_VERSION 22
+#define DATA_VERSION 23
 
 #define CT_FPREG 0
 #define CT_DREG 0
 #define ILLG_OPCODE 0x4afc
 #define LM_OPCODE 0x42db
 
-#define INTERRUPT_CYCLES 64
-#define MAX_INTERRUPT_DELAY 64
-#define IPL_TRIGGER_ADDR 0xdc0000
-#define IPL_TEST_IPL_LEVEL 4
+#define IPL_TRIGGER_ADDR 0xdff030
+#define IPL_TRIGGER_ADDR_SIZE 2
+#define IPL_TRIGGER_DATA 0x100
+#define IPL_TRIGGER_SERPER 10
+#define INTERRUPT_CYCLES ((((IPL_TRIGGER_SERPER + 1) * 9) + (((IPL_TRIGGER_SERPER + 1) - 1) / 2) + 1 + 3 + 9) * 2)
+#define IPL_TRIGGER_INTMASK 0x0800
+#define IPL_TEST_IPL_LEVEL 5
index 802919bce0eae8380beb1f35016ffc2b76c6ae4a..6d8bcbe62ca3f8a16abccbebeb0ff931360f0237 100644 (file)
@@ -36,7 +36,11 @@ path=data/
 ; 1 = compress only test data files
 ; 2 = compress only main data files
 ; 3 = compress all data files
-feature_gzip=0
+feature_gzip=1
+
+; data file max size in kilobytes (split size)
+; 0 = no split
+max_file_size=0
 
 ; Low address space limits. Real hardware must have RAM in this space. Comment out to disable.
 ; Start should be zero if Amiga, set to 0x0800 if Atari ST.
index 5e14e98b4ba1675646b817736ff6274de8953152..3caf07f535e8d2c87a2e9bf7d98c146f77e126e0 100644 (file)
@@ -173,6 +173,10 @@ static uae_u8 stackaddr[SIZE_STORED_ADDRESS];
 static uae_u32 stackaddr_ptr;
 static uae_u8 *opcode_memory_end;
 
+#define MAX_IPL_PC_VALUES 4
+static uae_u32 ipl_pc[MAX_IPL_PC_VALUES];
+static int ipl_pc_cnt[MAX_IPL_PC_VALUES];
+
 static char opcode[32], group[32], cpustr[10];
 
 #ifndef M68K
@@ -608,25 +612,63 @@ static int set_berr(int mask, int ask)
        return getchar();
 }
 
-static uae_u8 *load_file(const char *path, const char *file, uae_u8 *p, int *sizep, int exiterror, int candirect)
+static int load_file_offset(FILE *f, int *foffsetp)
+{
+       int size = -1;
+       unsigned char buf[4] = { 0 };
+       fseek(f, *foffsetp, SEEK_SET);
+       fread(buf, 1, sizeof(buf), f);
+       if (buf[0] == 0xff && buf[1] == 0xff && buf[2] == 0xff && buf[3] == 0xff) {
+               fread(buf, 1, sizeof(buf), f);
+               size = (buf[0] << 24) | (buf[1] << 16) | (buf[2] << 8) | (buf[3] << 0);
+               if (size == 0) {
+                       *foffsetp = -1;
+                       return 0;
+               }
+               *foffsetp = *foffsetp + size + 8;
+               return size;
+       }
+       *foffsetp = -1;
+       return -1;
+}
+
+static uae_u8 *load_file(const char *path, const char *file, uae_u8 *p, int *sizep, int *foffsetp, int exiterror, int candirect)
 {
        char fname[256];
        uae_u8 *unpack = NULL;
        int unpackoffset = 0;
        int size = 0;
+       int foffset = foffsetp ? *foffsetp : 0;
 
-       strcpy(fname, path);
-       strcat(fname, file);
-       if (strchr(file, '.')) {
-               fname[strlen(fname) - 1] = 'z';
+       if (path) {
+               strcpy(fname, path);
+               strcat(fname, file);
+               if (strchr(file, '.')) {
+                       fname[strlen(fname) - 1] = 'z';
+               } else {
+                       strcat(fname, ".gz");
+               }
        } else {
-               strcat(fname, ".gz");
+               strcpy(fname, file);
        }
        FILE *f = fopen(fname, "rb");
        if (f) {
-               fseek(f, 0, SEEK_END);
-               int gsize = ftell(f);
-               fseek(f, 0, SEEK_SET);
+               int gsize;
+               if (foffsetp) {
+                       gsize = load_file_offset(f, foffsetp);
+                       if (gsize == 0) {
+                               return NULL;
+                       }
+                       if (gsize > 0) {
+                               *sizep = gsize;
+                       }
+               }
+               if (*sizep <= 0) {
+                       fseek(f, 0, SEEK_END);
+                       gsize = ftell(f);
+                       fseek(f, 0, SEEK_SET);
+               }
+
                uae_u8 *gzbuf = NULL;
                if (prealloc) {
                        if (!prealloc_gzip) {
@@ -698,7 +740,11 @@ static uae_u8 *load_file(const char *path, const char *file, uae_u8 *p, int *siz
                }
        }
        if (!unpack) {
-               sprintf(fname, "%s%s", path, file);
+               if (path) {
+                       sprintf(fname, "%s%s", path, file);
+               } else {
+                       strcpy(fname, file);
+               }
                f = fopen(fname, "rb");
                if (!f) {
                        if (exiterror) {
@@ -707,8 +753,17 @@ static uae_u8 *load_file(const char *path, const char *file, uae_u8 *p, int *siz
                        }
                        return NULL;
                }
+               if (foffsetp) {
+                       size = load_file_offset(f, foffsetp);
+                       if (size == 0) {
+                               return NULL;
+                       }
+                       if (size > 0) {
+                               *sizep = size;
+                       }
+               }
                size = *sizep;
-               if (size < 0) {
+               if (size <= 0) {
                        fseek(f, 0, SEEK_END);
                        size = ftell(f);
                        fseek(f, 0, SEEK_SET);
@@ -2147,21 +2202,31 @@ 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;
+       if (interrupttest == 1) {
+               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;
+               }
+       }
+       if (interrupttest == 2) {
+               volatile uae_u16 *intena = (uae_u16*)0xdff09a;
+               volatile uae_u16 *intreq = (uae_u16*)0xdff09c;
+               volatile uae_u16 *serper = (uae_u16*)0xdff032;
+               *serper = IPL_TRIGGER_SERPER;
+               *intena = 0x8000 | 0x4000 | IPL_TRIGGER_INTMASK;
+               *intreq = IPL_TRIGGER_INTMASK;
        }
 }
 
 static void clear_interrupt(void)
 {
-       volatile uae_u16 *intena = (uae_u16 *)0xdff09a;
-       volatile uae_u16 *intreq = (uae_u16 *)0xdff09c;
+       volatile uae_u16 *intena = (uae_u16*)0xdff09a;
+       volatile uae_u16 *intreq = (uae_u16*)0xdff09c;
        *intena = 0x7fff;
        *intreq = 0x7fff;
 }
@@ -2941,7 +3006,7 @@ static void out_endinfo(void)
        outbp += strlen(outbp);
        sprintf(outbp, "S=%d", supercnt);
        outbp += strlen(outbp);
-       for (int i = 0; i < 128; i++) {
+       for (short i = 0; i < 128; i++) {
                if (exceptioncount[0][i] || exceptioncount[1][i] || exceptioncount[2][i]) {
                        if (i == 2 || i == 3) {
                                sprintf(outbp, " E%02d=%d/%d/%d", i, exceptioncount[0][i], exceptioncount[1][i], exceptioncount[2][i]);
@@ -2957,6 +3022,16 @@ static void out_endinfo(void)
        }
        strcat(outbp, "\n");
        outbp += strlen(outbp);
+       if (interrupttest == 2) {
+               for (short i = 0; i < MAX_IPL_PC_VALUES; i++) {
+                       if (ipl_pc[i]) {
+                               sprintf(outbp, "%08x:%d ", ipl_pc[i], ipl_pc_cnt[i]);
+                               outbp += strlen(outbp);
+                       }
+               }
+               strcat(outbp, "\n");
+               outbp += strlen(outbp);
+       }
        if (fpu_approxcnt) {
                sprintf(outbp, "FPU approximate matches: %d\n", fpu_approxcnt);
        }
@@ -3272,10 +3347,11 @@ static void process_test(uae_u8 *p)
 
 
 #ifdef AMIGA
-                                               if (interrupttest == 1) {
+                                               if (interrupttest) {
                                                        set_interrupt();
                                                }
 #endif
+
                                                if (cpu_lvl == 1) {
                                                        execute_test010(&test_regs);
                                                } else if (cpu_lvl >= 2) {
@@ -3322,6 +3398,26 @@ static void process_test(uae_u8 *p)
 
                                        p = validate_test(p, ignore_errors, ignore_sr, &cur_regs, &test_regs, &last_regs, opcodeendsizeextra);
 
+                                       if (interrupttest == 2) {
+                                               short found = 0;
+                                               for (short i = 0; i < MAX_IPL_PC_VALUES; i++) {
+                                                       if (ipl_pc[i] == test_regs.pc) {
+                                                               ipl_pc_cnt[i]++;
+                                                               found = 1;
+
+                                                       }
+                                               }
+                                               if (!found) {
+                                                       for (short i = 0; i < MAX_IPL_PC_VALUES; i++) {
+                                                               if (ipl_pc[i] == 0) {
+                                                                       ipl_pc[i] = test_regs.pc;
+                                                                       ipl_pc_cnt[i] = 1;
+                                                                       break;
+                                                               }
+                                                       }
+                                               }
+                                       }
+
                                        testcnt++;
                                        if (super)
                                                supercnt++;
@@ -3419,7 +3515,7 @@ static int test_mnemo(const char *opcode)
        uae_u8 data[4] = { 0 };
        uae_u32 v;
        char tfname[256];
-       int filecnt = 1;
+       int filecnt = 0;
        uae_u32 starttimeid;
        int lvl;
 
@@ -3429,8 +3525,10 @@ static int test_mnemo(const char *opcode)
 
        sprintf(tfname, "%s/0000.dat", opcode);
        size = -1;
-       uae_u8 *headerfile = load_file(path, tfname, NULL, &size, 1, 1);
+       int foffset = 0;
+       uae_u8 *headerfile = load_file(path, tfname, NULL, &size, &foffset, 1, 1);
        if (!headerfile) {
+               printf("Data file failed to open\n");
                exit(0);
        }
        int headoffset = 0;
@@ -3536,7 +3634,7 @@ static int test_mnemo(const char *opcode)
        }
 
        size = test_memory_size;
-       load_file(path, "tmem.dat", test_memory, &size, 1, 0);
+       load_file(path, "tmem.dat", test_memory, &size, NULL, 1, 0);
        if (size != test_memory_size) {
                printf("tmem.dat size mismatch\n");
                exit(0);
@@ -3569,14 +3667,27 @@ static int test_mnemo(const char *opcode)
                }
        }
 
+       int otestcnt = -1;
+       printf("offset = %d\n", foffset);
        for (;;) {
-               printf("%s (%s). %u...\n", tfname, group, testcnt);
+               if (otestcnt != testcnt) {
+                       printf("%s (%s). %u...\n", tfname, group, testcnt);
+                       otestcnt = testcnt;
+               }
 
                sprintf(tfname, "%s/%04d.dat", opcode, filecnt);
 
-               test_data_size = -1;
-               test_data = load_file(path, tfname, test_data_prealloc, &test_data_size, 0, 1);
+               test_data_size = 0;
+               test_data = load_file(path, tfname, test_data_prealloc, &test_data_size, &foffset, 0, 1);
+
+               printf("%p %d\n", test_data, foffset);
+
                if (!test_data) {
+                       if (foffset < 0) {
+                               filecnt++;
+                               foffset = 0;
+                               continue;
+                       }
                        if (askifmissing) {
                                printf("Couldn't open '%s%s'. Type new path and press enter.\n", path, tfname);
                                path[0] = 0;
@@ -3627,7 +3738,9 @@ static int test_mnemo(const char *opcode)
                        break;
                }
 
-               filecnt++;
+               if (foffset <= 0) {
+                       filecnt++;
+               }
        }
 
        if (errorcnt == 0) {
@@ -3929,9 +4042,9 @@ int main(int argc, char *argv[])
                }
 
                low_memory_size = -1;
-               low_memory_temp = load_file(path, "lmem.dat", NULL, &low_memory_size, 0, 1);
+               low_memory_temp = load_file(path, "lmem.dat", NULL, &low_memory_size, NULL, 0, 1);
                high_memory_size = -1;
-               high_memory_temp = load_file(path, "hmem.dat", NULL, &high_memory_size, 0, 1);
+               high_memory_temp = load_file(path, "hmem.dat", NULL, &high_memory_size, NULL, 0, 1);
 
 #ifndef M68K
                low_memory = calloc(1, 32768);