]> git.unchartedbackwaters.co.uk Git - francis/winuae.git/commitdiff
CPU tester updates (68040/060 support). 68020/030 address error fixes. MOVE16 disasse...
authorToni Wilen <twilen@winuae.net>
Sun, 18 Aug 2019 17:47:41 +0000 (20:47 +0300)
committerToni Wilen <twilen@winuae.net>
Sun, 18 Aug 2019 17:47:41 +0000 (20:47 +0300)
cputest.cpp
cputest/amiga.S
cputest/asm.S
cputest/cputestgen.ini
cputest/main.c
cputest_support.cpp
disasm.cpp
gencpu.cpp
include/cputest.h
newcpu.cpp

index c63ede85fd58731ef1d466d52ee5b2ce669d1a07..2e4d28fe309c1fd0a7402c7c6d3cb673c4d0fb8f 100644 (file)
@@ -102,6 +102,7 @@ static int test_exception_opcode;
 static uae_u8 imm8_cnt;
 static uae_u16 imm16_cnt;
 static uae_u32 imm32_cnt;
+static uae_u32 immabsl_cnt;
 static uae_u32 addressing_mask;
 static int opcodecnt;
 static int cpu_stopped;
@@ -111,6 +112,9 @@ static int testing_active;
 static time_t starttime;
 static int filecount;
 static uae_u16 sr_undefined_mask;
+static int low_memory_accessed;
+static int high_memory_accessed;
+static int test_memory_accessed;
 
 struct uae_prefs currprefs;
 
@@ -144,6 +148,7 @@ static bool valid_address(uaecptr addr, int size, int w)
                        goto oob;
                if (w && lmem_rom)
                        goto oob;
+               low_memory_accessed = w ? -1 : 1;
                return 1;
        }
        if (addr >= HIGH_MEMORY_START && addr < HIGH_MEMORY_START + 0x8000) {
@@ -153,6 +158,7 @@ static bool valid_address(uaecptr addr, int size, int w)
                        goto oob;
                if (w && hmem_rom)
                        goto oob;
+               high_memory_accessed = w ? -1 : 1;
                return 1;
        }
        if (addr >= test_memory_end && addr + size < test_memory_end + EXTRA_RESERVED_SPACE) {
@@ -165,6 +171,7 @@ static bool valid_address(uaecptr addr, int size, int w)
                        if (addr >= opcode_memory_start && addr + size < opcode_memory_start + OPCODE_AREA)
                                goto oob;
                }
+               test_memory_accessed = w ? -1 : 1;
                return 1;
        }
 oob:
@@ -695,10 +702,9 @@ static void doexcstack(void)
        } else if (cpu_lvl == 2) {
                if (test_exception == 3) {
                        uae_u16 ssw = (sv ? 4 : 0) | test_exception_3_fc;
-                       ssw |= test_exception_3_w ? 0 : 0x40;
                        ssw |= 0x20;
                        regs.mmu_fault_addr = test_exception_addr;
-                       Exception_build_stack_frame(regs.instruction_pc, regs.pc, ssw, 3, 0x0a);
+                       Exception_build_stack_frame(regs.instruction_pc, regs.pc, ssw, 3, 0x0b);
                } else {
                        Exception_build_stack_frame_common(regs.instruction_pc, regs.pc, 0, test_exception);
                }
@@ -1194,7 +1200,7 @@ static int full_format_cnt;
 
 static uaecptr putfpuimm(uaecptr pc, int opcodesize, int *isconstant)
 {
-       // TODO: generate FPU immediates
+       // TODO: generate sane FPU immediates
        switch (opcodesize)
        {
        case 0: // L
@@ -1210,24 +1216,24 @@ static uaecptr putfpuimm(uaecptr pc, int opcodesize, int *isconstant)
                pc += 2;
                break;
        case 1: // S
-               put_long(pc, 0);
+               put_long(pc, rand32());
                pc += 4;
                break;
        case 2: // X
-               put_long(pc, 0);
-               put_long(pc + 4, 0);
-               put_long(pc + 8, 0);
+               put_long(pc, rand32());
+               put_long(pc + 4, rand32());
+               put_long(pc + 8, rand32());
                pc += 12;
                break;
        case 3: // P
-               put_long(pc, 0);
-               put_long(pc + 4, 0);
-               put_long(pc + 8, 0);
+               put_long(pc, rand32());
+               put_long(pc + 4, rand32());
+               put_long(pc + 8, rand32());
                pc += 12;
                break;
        case 5: // D
-               put_long(pc, 0);
-               put_long(pc + 4, 0);
+               put_long(pc, rand32());
+               put_long(pc + 4, rand32());
                pc += 8;
                break;
        }
@@ -1325,9 +1331,24 @@ static int create_ea(uae_u16 *opcodep, uaecptr pc, int mode, int reg, struct ins
                pc += 2;
                break;
        case absl:
-               put_long_test(pc, rand32());
-               *isconstant = 32;
-               pc += 4;
+               {
+                       uae_u32 v = rand32();
+                       if ((immabsl_cnt & 7) == 0) {
+                               v &= 0x0000ffff;
+                       } else if ((immabsl_cnt & 7) >= 4) {
+                               int offset = 0;
+                               for (;;) {
+                                       offset = (uae_s16)rand16();
+                                       if (offset < -OPCODE_AREA || offset > OPCODE_AREA)
+                                               break;
+                               }
+                               v = opcode_memory_start + offset;
+                       }
+                       immabsl_cnt++;
+                       put_long_test(pc, v);
+                       *isconstant = 32;
+                       pc += 4;
+               }
                break;
        case imm:
                if (fpuopcode >= 0 && opcodesize < 8) {
@@ -1432,8 +1453,9 @@ static int create_ea(uae_u16 *opcodep, uaecptr pc, int mode, int reg, struct ins
        {
                // long immediate
                uae_u32 v = rand32();
-               if ((imm32_cnt & 7) == 0)
+               if ((imm32_cnt & 7) == 0) {
                        v &= 0x0000ffff;
+               }
                imm32_cnt++;
                put_long_test(pc, v);
                if (imm32_cnt < 256)
@@ -1460,6 +1482,15 @@ static int handle_specials_preea(uae_u16 opcode, uaecptr pc, struct instr *dp)
                imm_special++;
                return 2;
        }
+       if (dp->mnemo == i_MOVE16) {
+               if (opcode & 0x20) {
+                       uae_u16 v = 0;
+                       v |= imm_special << 12;
+                       put_word_test(pc, v);
+                       imm_special++;
+                       return 2;
+               }
+       }
        return 0;
 }
 
@@ -1519,7 +1550,6 @@ static void handle_specials_extra(uae_u16 opcode, uaecptr pc, struct instr *dp)
                if (extra != extra2) {
                        put_word_test(opcode_memory_start + 4, extra);
                }
-
        }
        if (dp->mnemo == i_CHK2) {
                uae_u16 extra = get_word_test(opcode_memory_start + 2);
@@ -1528,7 +1558,6 @@ static void handle_specials_extra(uae_u16 opcode, uaecptr pc, struct instr *dp)
                if (extra != extra2) {
                        put_word_test(opcode_memory_start + 2, extra);
                }
-
        }
 }
 
@@ -1549,13 +1578,6 @@ static int handle_specials_stack(uae_u16 opcode, uaecptr pc, struct instr *dp, i
                        addr += 2;
                        offset += 2;
                        *isconstant = imm_special >= (1 << (0 + 5)) * 4 ? 0 : -1;
-               } else if (dp->mnemo == i_RTD) {
-                       // RTD
-                       v = imm_special >> 2;
-                       uae_u16 sr = v & 31;
-                       sr |= (v >> 5) << 12;
-                       put_word_test(addr + 4, sr);
-                       *isconstant = imm_special >= (1 << (4 + 5)) * 4 ? 0 : -1;
                } else if (dp->mnemo == i_RTE) {
                        // RTE
                        if (currprefs.cpu_model == 68000) {
@@ -1596,13 +1618,13 @@ static int handle_specials_stack(uae_u16 opcode, uaecptr pc, struct instr *dp, i
        return offset;
 }
 
-static void execute_ins(uae_u16 opc, uaecptr endpc, uaecptr targetpc)
+static void execute_ins(uae_u16 opc, uaecptr endpc, uaecptr targetpc, struct instr *dp)
 {
        uae_u16 opw1 = (opcode_memory[2] << 8) | (opcode_memory[3] << 0);
        uae_u16 opw2 = (opcode_memory[4] << 8) | (opcode_memory[5] << 0);
-       if (opc == 0x61ff  
-               && opw1 == 0x0000
-               && opw2 == 0x9908
+       if (opc == 0xf601
+//             && opw1 == 0x0000
+//             && opw2 == 0x9908
                )
                printf("");
        if (regs.sr & 0x2000)
@@ -1614,6 +1636,9 @@ static void execute_ins(uae_u16 opc, uaecptr endpc, uaecptr targetpc)
 
        MakeFromSR();
 
+       low_memory_accessed = 0;
+       high_memory_accessed = 0;
+       test_memory_accessed = 0;
        testing_active = 1;
 
        int cnt = feature_loop_mode * 2;
@@ -1648,6 +1673,11 @@ static void execute_ins(uae_u16 opc, uaecptr endpc, uaecptr targetpc)
                        }
                }
 
+               if (dp->mnemo == i_TAS && low_memory_accessed) {
+                       test_exception = -1;
+                       break;
+               }
+
                if (regs.pc == endpc || regs.pc == targetpc)
                        break;
 
@@ -1784,12 +1814,9 @@ static uae_u8 *save_exception(uae_u8 *p, struct instr *dp)
                        // FSLW or PC of faulted instruction
                        p = store_rel(p, 0, opcode_memory_start, gl(sf + 12), 1);
                        break;
-               case 0x0a: // 68020/030 address error. Only check SSW.
-                       // SSW
-                       p = store_reg(p, 0, 0, gw(sf + 0x0a), sz_word);
-                       exception_stack_frame_size = 0x0c;
-                       sf[8] = sf[9] = 0;
-                       last_exception[8] = last_exception[9] = 0;
+               case 0x0a: // 68020/030 address error.
+               case 0x0b: // Don't save anything extra, too many undefined fields and bits..
+                       exception_stack_frame_size = 0x08;
                        break;
                default:
                        wprintf(_T("Unknown frame %04x!\n"), frame);
@@ -1819,6 +1846,22 @@ static uae_u16 get_ccr_ignore(struct instr *dp)
        return ccrignoremask;
 }
 
+static int isfpp(int mnemo)
+{
+       switch (mnemo)
+       {
+       case i_FPP:
+       case i_FBcc:
+       case i_FDBcc:
+       case i_FTRAPcc:
+       case i_FScc:
+       case i_FRESTORE:
+       case i_FSAVE:
+               return 1;
+       }
+       return 0;
+}
+
 
 static const TCHAR *sizes[] = { _T("B"), _T("W"), _T("L") };
 
@@ -1905,9 +1948,9 @@ static void test_mnemo(const TCHAR *path, const TCHAR *mnemo, int opcodesize, in
                opcodecnt++;
                if (isunsupported(dp))
                        return;
-               if ((opcode & 0xf000) == 0xf000 && !currprefs.fpu_model)
+               if (isfpp(lookup->mnemo) && !currprefs.fpu_model)
                        return;
-               fpumode = currprefs.fpu_model && (opcode & 0xf000) == 0xf000;
+               fpumode = currprefs.fpu_model && isfpp(lookup->mnemo);
        }
 
        if (!opcodecnt)
@@ -2028,6 +2071,7 @@ static void test_mnemo(const TCHAR *path, const TCHAR *mnemo, int opcodesize, in
                                imm8_cnt = 0;
                                imm16_cnt = 0;
                                imm32_cnt = 0;
+                               immabsl_cnt = 0;
                                imm_special = 0;
 
                                // retry few times if out of bounds access
@@ -2048,7 +2092,7 @@ static void test_mnemo(const TCHAR *path, const TCHAR *mnemo, int opcodesize, in
                                        out_of_test_space = 0;
                                        ahcnt = 0;
 
-                                       if (opc == 0xf228)
+                                       if (opc == 0xf620)
                                                printf("");
                                        if (subtest_count == 1537)
                                                printf("");
@@ -2319,7 +2363,7 @@ static void test_mnemo(const TCHAR *path, const TCHAR *mnemo, int opcodesize, in
                                                        if (subtest_count == 353)
                                                                printf("");
 
-                                                       execute_ins(opc, pc - 2, branch_target);
+                                                       execute_ins(opc, pc - 2, branch_target, dp);
 
                                                        if (regs.s)
                                                                s_cnt++;
@@ -2635,7 +2679,7 @@ int __cdecl main(int argc, char *argv[])
 
        currprefs.cpu_model = 68000;
        ini_getval(ini, INISECTION, _T("cpu"), &currprefs.cpu_model);
-       if (currprefs.cpu_model != 68000 && currprefs.cpu_model != 68010 && currprefs.cpu_model != 68020) {
+       if (currprefs.cpu_model != 68000 && currprefs.cpu_model != 68010 && currprefs.cpu_model != 68020 && currprefs.cpu_model != 68040) {
                wprintf(_T("Unsupported CPU model.\n"));
                return 0;
        }
@@ -2644,7 +2688,7 @@ int __cdecl main(int argc, char *argv[])
        addressing_mask = 0x00ffffff;
        v = 24;
        ini_getval(ini, INISECTION, _T("cpu_address_space"), &v);
-       if (v == 32) {
+       if (v == 32 || currprefs.cpu_model >= 68030) {
                currprefs.address_space_24 = 0;
                addressing_mask = 0xffffffff;
        }
@@ -2653,7 +2697,7 @@ int __cdecl main(int argc, char *argv[])
        currprefs.fpu_mode = 1;
        ini_getval(ini, INISECTION, _T("fpu"), &currprefs.fpu_model);
        if (currprefs.fpu_model && currprefs.cpu_model < 68020) {
-               wprintf(_T("FPU requires 68020 CPU.\n"));
+               wprintf(_T("FPU requires 68020 or 68040 CPU.\n"));
                return 0;
        }
        if (currprefs.fpu_model != 0 && currprefs.fpu_model != 68881 && currprefs.fpu_model != 68882 && currprefs.fpu_model != 68040 && currprefs.fpu_model != 68060) {
@@ -2751,6 +2795,9 @@ int __cdecl main(int argc, char *argv[])
 
        xorshiftstate = 1;
 
+       feature_test_rounds = 2;
+       ini_getval(ini, INISECTION, _T("test_rounds"), &feature_test_rounds);
+
        v = 0;
        ini_getval(ini, INISECTION, _T("test_memory_start"), &v);
        if (!v) {
@@ -2861,6 +2908,9 @@ int __cdecl main(int argc, char *argv[])
        } else if (currprefs.cpu_model == 68020) {
                tbl = op_smalltbl_92_test_ff;
                cpu_lvl = 2;
+       } else if (currprefs.cpu_model == 68040) {
+               tbl = op_smalltbl_94_test_ff;
+               cpu_lvl = 4;
        } else {
                wprintf(_T("Unsupported CPU model.\n"));
                abort();
@@ -2890,8 +2940,10 @@ int __cdecl main(int argc, char *argv[])
                        continue;
                }
 
-               if (!currprefs.fpu_model && (opcode & 0xf000) == 0xf000) {
-                       continue;
+               if (!currprefs.fpu_model) {
+                       int fppskip = isfpp(table->mnemo);
+                       if (fppskip)
+                               continue;
                }
 
                if (table->handler != -1) {
index 263662a6dda0a8db2c9575d31ec1c15a8caa23d3..81cbc205b36724f0a491328e12cd9673d2e1d393 100644 (file)
@@ -58,17 +58,20 @@ _allocate_absolute:
        move.l (sp)+,a6
        rts
 
-       | return CPU model (68000=0, 68010=1, 68020=2)
+       | return CPU model (68000=0, 68010=1, 68020=2, 68030=3, 68040=4, 68060=5)
 _get_cpu_model:
        move.l 4.w,a0
-       moveq #0,d0
        move.w 0x128(a0),d1
-       and.w #3,d1
-       beq.s .cpudone
-       moveq #2,d0
-       btst #1,d1
+       moveq #5,d0
+       tst.b d1
+       bmi.s .cpudone2
+       moveq #3,d0
+.cpucheck:
+       btst d0,d1
        bne.s .cpudone
-       moveq #1,d0
+       dbf d0,.cpucheck
 .cpudone:
+       addq.l #1,d0
+.cpudone2:
        rts
 
index 70a59add5a3806469ee16a67605e602f6ff6a530..72d07f07a153e5feae08eb279a6a522375eb4eb2 100644 (file)
        .globl _setvbr
        .globl _setcpu
        .globl _flushcache
+       .globl _msp_address1
+       .globl _msp_address2
+       .globl _msp_address3
+       .globl _msp_address4
 
 | must match main.c
 S_DREG = 0
@@ -44,9 +48,17 @@ _setcpu:
        bcs.s .scend1
        movec cacr,d0
        move.l d0,(a0)+
+       moveq #0,d0
+       cmp.w #4,d1
+       bcc.s .scend1b
        movec caar,d0
+.scend1b:
        move.l d0,(a0)+
+       moveq #0,d0
+       cmp.w #5,d1
+       bcc.s .scend1c
        movec msp,d0
+.scend1c:
        move.l d0,(a0)+
 .scend1:
        move.l a1,d0
@@ -62,17 +74,30 @@ _setcpu:
        move.l (a1)+,d0
        movec d0,cacr
        move.l (a1)+,d0
+       cmp.w #4,d1
+       bcc.s .scend2b
        movec d0,caar
+.scend2b:
        move.l (a1)+,d0
+       cmp.w #5,d1
+       bcc.s .scend2
        move.c d0,msp
 .scend2:
        rts
 
 _flushcache:
+       move.l 4(sp),d1 | cpu_lvl
+       cmp.w #4,d1
+       bcc.s .fc040    
        movec cacr,d0
        bset #3,d0
        movec d0,cacr
        rts
+.fc040:
+       .arch 68040
+       cpusha bc
+       .arch 68020
+       rts
 
        | set and return old VBR
 _setvbr:
@@ -130,7 +155,7 @@ _execute_test010:
        movem.l (a0),d0-d7/a0-a6
        rte
 
-       | 68020 test entrypoint
+       | 68020+ test entrypoint
 _execute_test020:
        movem.l d1-d7/a0-a6,-(sp)
        move.l 14*4+4(sp),a0 | register struct
@@ -149,8 +174,11 @@ _execute_test020:
        move.w S_SR+2(a0),-(sp)
        move.l S_AREG+7*4(a0),a1
        move.l a1,USP
+
        move.l S_MSP(a0),a1
+_msp_address1:
        movec a1,MSP
+
        movem.l (a0),d0-d7/a0-a6
        rte
 
@@ -173,8 +201,11 @@ _execute_testfpu:
        move.w S_SR+2(a0),-(sp)
        move.l S_AREG+7*4(a0),a1
        move.l a1,USP
+
        move.l S_MSP(a0),a1
+_msp_address2:
        movec a1,MSP
+
        fmovem.x S_FPU(a0),fp0-fp7
        lea S_FPIAR(a0),a1
        fmove.l (a1)+,fpiar
@@ -296,8 +327,10 @@ _exception020:
        lsr.w #2,d0
        move.w d0,S_EXC+2(a0)
        
+_msp_address3:
        movec MSP,a1
        move.l a1,S_MSP(a0)
+
        move.l USP,a1
        move.l a1,S_AREG+7*4(a0)
                
@@ -323,8 +356,10 @@ _exceptionfpu:
        lsr.w #2,d0
        move.w d0,S_EXC+2(a0)
        
+_msp_address4:
        movec MSP,a1
        move.l a1,S_MSP(a0)
+
        move.l USP,a1
        move.l a1,S_AREG+7*4(a0)
 
index 8c9b758fdc02bf70f7d7efda553dc8f1790dce08..b0dce4c393e5a351e9926835c2348f21a2774827 100644 (file)
@@ -1,7 +1,7 @@
 
 [cputest]
 
-; CPU model (68000, 68020).
+; CPU model (68000, 68020 or 68040).
 ; Always select 68020 when testing FPU instructions, even if test hardware CPU is 68040 or 68060.
 cpu=68020
 
@@ -31,8 +31,12 @@ 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=0x780000
+;test_memory_start=0x68800000
 test_memory_size=0x080000
 
+; number of test rounds (registers are re-randomized after each round)
+test_rounds=2
+
 ; test word or long odd data access address errors (68000/010 only)
 ; 0 = do not generate address errors
 ; 1 = include address errors
@@ -41,7 +45,7 @@ feature_exception3_data=0
 
 ; test branches to odd addresses
 ; same options as above
-feature_exception3_instruction=0
+feature_exception3_instruction=1
 
 ; SR extra mask.
 ; 0x8000 = T1
@@ -72,4 +76,4 @@ feature_addressing_modes_dst=
 ; mnemonics separated by comma or all/fall.
 ; all = generate all CPU tests. tst = generate tst.b, tst.w and tst.l. tst.l = generate only tst.l
 ; fall = generate all FPU tests.
-mode=chk2.b
+mode=all
index 4a256cf46e626fd9467d60d29053b0a4d8471a02..cb71ce5c2f16ee07fe9375333f0a5178c587f11b 100644 (file)
@@ -145,7 +145,7 @@ static uae_u32 get_cpu_model(void)
 static void setcpu(uae_u32 v, uae_u32 *s, uae_u32 *d)
 {
 }
-static void flushcache(void)
+static void flushcache(uae_u32 v)
 {
 }
 #else
@@ -168,7 +168,7 @@ extern uae_u32 testexit(void);
 extern uae_u32 setvbr(uae_u32);
 extern uae_u32 get_cpu_model(void);
 extern void setcpu(uae_u32, uae_u32*, uae_u32*);
-extern void flushcache(void);
+extern void flushcache(uae_u32);
 
 #endif
 
@@ -900,10 +900,8 @@ static uae_u8 *validate_exception(struct registers *regs, uae_u8 *p, int excnum,
                                exclen = 16;
                                break;
                        case 0x0a:
-                               v = 0;
-                               p = restore_value(p, &v, &size);
-                               pw(exc + 0x0a, v);
-                               exclen = 0x0c;
+                       case 0x0b:
+                               exclen = 8;
                                break;
                        default:
                                end_test();
@@ -1299,7 +1297,7 @@ static void process_test(uae_u8 *p)
                int fpumode = fpu_model && (opcode_memory[0] & 0xf0) == 0xf0;
 
                if (cpu_lvl >= 2)
-                       flushcache();
+                       flushcache(cpu_lvl);
 
                uae_u32 pc = opcode_memory_addr;
 
@@ -1435,6 +1433,7 @@ static int test_mnemo(const char *path, const char *opcode)
        char fname[256], tfname[256];
        int filecnt = 1;
        uae_u32 starttimeid;
+       int lvl;
 
        errors = 0;
        quit = 0;
@@ -1464,13 +1463,22 @@ static int test_mnemo(const char *path, const char *opcode)
        fread(data, 1, 4, f);
        opcode_memory_addr = gl(data) + test_memory_addr;
        fread(data, 1, 4, f);
-       cpu_lvl = gl(data) >> 16;
+       lvl = gl(data) >> 16;
        sr_undefined_mask = gl(data);
        fread(data, 1, 4, f);
        fpu_model = gl(data);
        fread(inst_name, 1, sizeof(inst_name) - 1, f);
        inst_name[sizeof(inst_name) - 1] = 0;
 
+       int lvl2 = cpu_lvl;
+       if (lvl2 == 5 && lvl2 != lvl)
+               lvl2 = 4;
+
+       if (lvl != lvl2) {
+               printf("Mismatched CPU model: %lu <> %lu\n", 68000 + 10 * cpu_lvl, 68000 + lvl * 10);
+               exit(0);
+       }
+
        if (!check_undefined_sr) {
                sr_undefined_mask = ~sr_undefined_mask;
        } else {
@@ -1614,6 +1622,25 @@ int main(int argc, char *argv[])
 
 #endif
 
+       int lvl = cpu_lvl;
+       if (lvl == 3) {
+               lvl = 2;
+       } else if (lvl == 5) {
+               lvl = 4;
+#ifdef M68K
+               // Overwrite MOVEC to/from MSP
+               // with NOP if 68060
+               extern void *msp_address1;
+               extern void *msp_address2;
+               extern void *msp_address3;
+               extern void *msp_address4;
+               *((uae_u32*)&msp_address1) = 0x4e714e71;
+               *((uae_u32*)&msp_address2) = 0x4e714e71;
+               *((uae_u32*)&msp_address3) = 0x4e714e71;
+               *((uae_u32*)&msp_address4) = 0x4e714e71;
+#endif
+       }
+
        if (argc < 2) {
                printf("cputest <all/mnemonic> (<start mnemonic>) (continue)\n");
                printf("mnemonic = test single mnemonic\n");
@@ -1624,7 +1651,7 @@ int main(int argc, char *argv[])
                return 0;
        }
 
-       sprintf(path + strlen(path), "%lu/", 68000 + cpu_lvl * 10);
+       sprintf(path + strlen(path), "%lu/", 68000 + lvl * 10);
 
        strcpy(opcode, argv[1]);
 
index 5b03799c2966829052f03bd0ecef883e618e50a1..b4c653abdf419431a8ca7f0258d673615af62219 100644 (file)
@@ -92,6 +92,10 @@ void flush_icache(int v)
 {
 }
 
+void flush_cpu_caches_040(uae_u16 opcode)
+{
+}
+
 void mmu_tt_modified(void)
 {
 }
@@ -101,6 +105,10 @@ uae_u16 REGPARAM2 mmu_set_tc(uae_u16 tc)
        return 0;
 }
 
+void mmu_op(uae_u32 opcode, uae_u32 extra)
+{
+}
+
 uae_u16 mmu030_state[3];
 int mmu030_opcode;
 int mmu030_idx;
index af73887cecac42a861c711418a0d9fbc573d9c40..b173ced6185dd6a685bd0f5e523ca43122c54109 100644 (file)
@@ -1791,7 +1791,7 @@ void m68k_disasm_2 (TCHAR *buf, int bufsize, uaecptr pc, uaecptr *nextpc, int cn
                                _stprintf(p, _T("(A%d)+,(A%d)+"), opcode & 7, (extra >> 12) & 7);
                                pc += 2;
                        } else {
-                               uae_u32 addr = get_long_debug(pc + 2);
+                               uae_u32 addr = get_long_debug(pc);
                                int ay = opcode & 7;
                                pc += 4;
                                switch ((opcode >> 3) & 3)
index fc9b9bbe53271880e0e92b08833176f9f6996107..e7ef2a1d12b22a01aa9dc442c6eb88001b0443d7 100644 (file)
@@ -1809,7 +1809,7 @@ static void genamode2x (amodes mode, const char *reg, wordsizes size, const char
                        }
                } else if (g_instr->mnemo == i_MVSR2) {
                        // If MOVE from SR generates address error exception,
-                       // RW field is set to Read!
+                       // Change it to read because it does dummy read first.
                        exp3rw = 0;
                }
 
@@ -4023,9 +4023,9 @@ static void gen_opcode (unsigned int opcode)
                        fill_prefetch_next ();
                        addcycles000 (2);
                } else {
-                       // write to memory, dummy write to same address, X-flag seems to be always set
+                       // read first and ignore result
                        if (cpu_level <= 1 && curi->size == sz_word) {
-                               printf ("\t%s (srca, regs.sr | 0x0010);\n", dstw);
+                               printf ("\t%s (srca);\n", srcw);
                                count_write++;
                        }
                        fill_prefetch_next ();
@@ -4455,7 +4455,7 @@ static void gen_opcode (unsigned int opcode)
                start_brace ();
                printf("\tuaecptr oldpc = %s;\n", getpc);
                printf("\tuaecptr nextpc = oldpc + %d;\n", m68k_pc_offset);
-               if (using_exception_3) {
+               if (using_exception_3 && cpu_level <= 1) {
                        printf("\tif (srca & 1) {\n");
                        printf("\t\texception3i (opcode, srca);\n");
                        printf("\t\tgoto %s;\n", endlabelstr);
@@ -4481,8 +4481,16 @@ static void gen_opcode (unsigned int opcode)
                                printf("\t\texception3_write(opcode, m68k_areg(regs, 7), 1);\n");
                                printf("\t\tgoto %s;\n", endlabelstr);
                                printf("\t}\n");
+                               need_endlabel = 1;
                        }
                        setpc ("srca");
+                       if (using_exception_3 && cpu_level >= 2) {
+                               printf("\tif (%s & 1) {\n", getpc);
+                               printf("\t\texception3i (opcode, %s);\n", getpc);
+                               printf("\t\tgoto %s;\n", endlabelstr);
+                               printf("\t}\n");
+                               need_endlabel = 1;
+                       }
                        clear_m68k_offset();
                        fill_prefetch_1 (0);
                        if (using_ce || using_prefetch) {
@@ -4542,7 +4550,7 @@ static void gen_opcode (unsigned int opcode)
                                printf("\t\texception3b(opcode,  m68k_areg(regs, 7), true, false, %s + 2);\n", getpc);
                                printf("\t\tgoto %s;\n", endlabelstr);
                                printf("\t}\n");
-                       } else {
+                       } else if (0) {
                                printf("\tif (src & 1) {\n");
                                printf("\t\texception3b(opcode, %s + s, 0, 1, %s + s);\n", getpc, getpc);
                                printf("\t\tgoto %s;\n", endlabelstr);
@@ -4553,6 +4561,14 @@ static void gen_opcode (unsigned int opcode)
                addcycles000 (2);
                printf("\tuaecptr oldpc = %s;\n", getpc);
                printf("\tuaecptr nextpc = oldpc + %d;\n", m68k_pc_offset);
+               if (using_exception_3 && cpu_level >= 2) {
+                       printf("\tif (s & 1) {\n");
+                       printf("\t\tm68k_areg(regs, 7) -= 4;\n");
+                       printf("\t\texception3b(opcode, %s + s, 0, 1, %s + s);\n", getpc, getpc);
+                       printf("\t\tgoto %s;\n", endlabelstr);
+                       printf("\t}\n");
+                       need_endlabel = 1;
+               }
                if (using_indirect > 0 && !using_ce020 && !using_prefetch_020 && !using_ce && !using_test) {
                        printf("\tm68k_do_bsri_jit (nextpc, s);\n");
                } else if (using_mmu) {
@@ -4573,6 +4589,7 @@ static void gen_opcode (unsigned int opcode)
                        printf("\t\texception3b(opcode, %s, 0, 1, %s);\n", getpc, getpc);
                        printf("\t\tgoto %s;\n", endlabelstr);
                        printf("\t}\n");
+                       need_endlabel = 1;
                }
                if (using_debugmem) {
                        printf("\tif (debugmem_trace)\n");
@@ -5435,8 +5452,8 @@ bccl_not68020:
                        printf ("\t}}\n");
                        pop_braces (old_brace_level);
                        printf ("\tif (! GET_ZFLG ()) {\n");
-                       printf ("\tm68k_dreg (regs, (extra >> 0) & 7) = (m68k_dreg (regs, (extra >> 6) & 7) & ~0xffff) | (dst2 & 0xffff);\n");
-                       printf ("\tm68k_dreg (regs, (extra >> 16) & 7) = (m68k_dreg (regs, (extra >> 22) & 7) & ~0xffff) | (dst1 & 0xffff);\n");
+                       printf ("\tm68k_dreg (regs, (extra >> 0) & 7) = (m68k_dreg (regs, (extra >> 0) & 7) & ~0xffff) | (dst2 & 0xffff);\n");
+                       printf ("\tm68k_dreg (regs, (extra >> 16) & 7) = (m68k_dreg (regs, (extra >> 16) & 7) & ~0xffff) | (dst1 & 0xffff);\n");
                        printf ("\t}\n");
                } else {
                        int old_brace_level = n_braces;
@@ -6308,9 +6325,12 @@ static void generate_cpu_test(int mode)
                cpu_level = 2;
                using_prefetch = 0;
                using_simple_cycles = 0;
+       } else if (mode == 4) {
+               cpu_level = 4;
+               using_prefetch = 0;
+               using_simple_cycles = 0;
        }
 
-
        read_counts();
        for (rp = 0; rp < nr_cpuop_funcs; rp++)
                opcode_next_clev[rp] = cpu_level;
@@ -6539,6 +6559,7 @@ int main(int argc, char *argv[])
        generate_cpu_test(0);
        generate_cpu_test(1);
        generate_cpu_test(2);
+       generate_cpu_test(4);
 
 #else
 
index 29cdcdab0070cd7210bdeba59631b33d6dbb37b8..0fdb5a01fdbd4f7820b520c1b866e4bb67f664ac 100644 (file)
@@ -28,6 +28,7 @@ extern const int imm8_table[];
 extern const struct cputbl op_smalltbl_90_test_ff[];
 extern const struct cputbl op_smalltbl_91_test_ff[];
 extern const struct cputbl op_smalltbl_92_test_ff[];
+extern const struct cputbl op_smalltbl_94_test_ff[];
 
 extern struct flag_struct regflags;
 
index a116f0aeaa3974ae99ca3be9e514462028e6a919..c8015cdfbfe59b0fabef3171d82d5d2bda39e345 100644 (file)
@@ -2631,7 +2631,7 @@ static void Exception_mmu030 (int nr, uaecptr oldpc)
                regs.mmu_fault_addr = last_fault_for_exception_3;
                mmu030_state[0] = mmu030_state[1] = 0;
                mmu030_data_buffer_out = 0;
-        Exception_build_stack_frame (last_fault_for_exception_3, currpc, MMU030_SSW_RW | MMU030_SSW_SIZE_W | (regs.s ? 6 : 2), nr,  0xA);
+        Exception_build_stack_frame (last_fault_for_exception_3, currpc, MMU030_SSW_RW | MMU030_SSW_SIZE_W | (regs.s ? 6 : 2), nr,  0xB);
        } else {
                Exception_build_stack_frame_common(oldpc, currpc, regs.mmu_ssw, nr);
        }
@@ -2896,11 +2896,13 @@ static void Exception_normal (int nr)
                                }
                        } else if (currprefs.cpu_model >= 68020) {
                                // 68020/030 odd PC address error (partially implemented only)
+                               // annoyingly this generates frame B, not A.
                                uae_u16 ssw = (sv ? 4 : 0) | last_fc_for_exception_3;
-                               ssw |= last_writeaccess_for_exception_3 ? 0 : 0x40;
-                               ssw |= 0x20;
+                               ssw |= MMU030_SSW_RW | MMU030_SSW_SIZE_W;
                                regs.mmu_fault_addr = last_fault_for_exception_3;
-                               Exception_build_stack_frame(oldpc, currpc, ssw, nr, 0x0a);
+                               mmu030_state[0] = mmu030_state[1] = 0;
+                               mmu030_data_buffer_out = 0;
+                               Exception_build_stack_frame(last_fault_for_exception_3, currpc, ssw, nr, 0x0b);
                                used_exception_build_stack_frame = true;
                        } else {
                                // 68010 address error (partially implemented only)