]> git.unchartedbackwaters.co.uk Git - francis/winuae.git/commitdiff
CPU tester 68060 support, 68040/060 address error fixes.
authorToni Wilen <twilen@winuae.net>
Wed, 21 Aug 2019 19:00:02 +0000 (22:00 +0300)
committerToni Wilen <twilen@winuae.net>
Wed, 21 Aug 2019 19:00:02 +0000 (22:00 +0300)
cputest.cpp
cputest/amiga.S
cputest/asm.S
cputest/cputestgen.ini
cputest/main.c
gencpu.cpp
include/cputest.h

index 2e4d28fe309c1fd0a7402c7c6d3cb673c4d0fb8f..ea8e9d40a23e8cb3362020f6479f591f2d007a18 100644 (file)
@@ -63,7 +63,7 @@ static int feature_test_rounds = 2;
 static uae_u32 feature_addressing_modes[2];
 static int ad8r[2], pc8r[2];
 
-#define HIGH_MEMORY_START (0x01000000 - 0x8000)
+#define HIGH_MEMORY_START (addressing_mask == 0xffffffff ? 0xffff8000 : 0x00ff8000)
 
 // large enough for RTD
 #define STACK_SIZE (0x8000 + 8)
@@ -151,7 +151,7 @@ static bool valid_address(uaecptr addr, int size, int w)
                low_memory_accessed = w ? -1 : 1;
                return 1;
        }
-       if (addr >= HIGH_MEMORY_START && addr < HIGH_MEMORY_START + 0x8000) {
+       if (addr >= HIGH_MEMORY_START && addr <= HIGH_MEMORY_START + 0x7fff) {
                if (addr < test_high_memory_start || test_high_memory_start == 0xffffffff)
                        goto oob;
                if (addr + size >= test_high_memory_end)
@@ -178,6 +178,15 @@ oob:
        return 0;
 }
 
+static void validate_addr(uaecptr addr, int size)
+{
+       if (valid_address(addr, size, 0))
+               return;
+       wprintf(_T("Trying to store invalid memory address %08x!?\n"), addr);
+       abort();
+}
+
+
 static uae_u8 *get_addr(uaecptr addr, int size, int w)
 {
        // allow debug output to read memory even if oob condition
@@ -193,7 +202,7 @@ static uae_u8 *get_addr(uaecptr addr, int size, int w)
        size--;
        if (addr + size < low_memory_size) {
                return low_memory + addr;
-       } else if (addr >= HIGH_MEMORY_START && addr < HIGH_MEMORY_START + 0x8000) {
+       } else if (addr >= HIGH_MEMORY_START && addr <= HIGH_MEMORY_START + 0x7fff) {
                return high_memory + (addr - HIGH_MEMORY_START);
        } else if (addr >= test_memory_start && addr + size < test_memory_end + EXTRA_RESERVED_SPACE) {
                return test_memory + (addr - test_memory_start);
@@ -429,6 +438,11 @@ void dfc_nommu_put_long(uaecptr addr, uae_u32 v)
        put_long_test(addr, v);
 }
 
+uae_u16 get_wordi_test(uaecptr addr)
+{
+       return get_word_test(addr);
+}
+
 uae_u32 memory_get_byte(uaecptr addr)
 {
        return get_byte_test(addr);
@@ -483,6 +497,13 @@ uae_u32 next_ilong_test(void)
        return v;
 }
 
+bool mmu_op30(uaecptr pc, uae_u32 opcode, uae_u16 extra, uaecptr extraa)
+{
+       m68k_setpc(pc);
+       op_illg(opcode);
+       return true;
+}
+
 uae_u32(*x_get_long)(uaecptr);
 uae_u32(*x_get_word)(uaecptr);
 void (*x_put_long)(uaecptr, uae_u32);
@@ -699,7 +720,7 @@ static void doexcstack(void)
                } else {
                        Exception_build_stack_frame_common(regs.instruction_pc, regs.pc, 0, test_exception);
                }
-       } else if (cpu_lvl == 2) {
+       } else if (cpu_lvl == 2 || cpu_lvl == 3) {
                if (test_exception == 3) {
                        uae_u16 ssw = (sv ? 4 : 0) | test_exception_3_fc;
                        ssw |= 0x20;
@@ -708,6 +729,14 @@ static void doexcstack(void)
                } else {
                        Exception_build_stack_frame_common(regs.instruction_pc, regs.pc, 0, test_exception);
                }
+       } else {
+               if (test_exception == 3) {
+                       if (currprefs.cpu_model == 68060)
+                               test_exception_addr &= ~1;
+                       Exception_build_stack_frame(test_exception_addr, regs.pc, 0, 3, 0x02);
+               } else {
+                       Exception_build_stack_frame_common(regs.instruction_pc, regs.pc, 0, test_exception);
+               }
        }
        exception_stack_frame_size = test_memory_end + EXTRA_RESERVED_SPACE - m68k_areg(regs, 7);
 
@@ -942,8 +971,6 @@ static void save_memory(const TCHAR *path, const TCHAR *name, uae_u8 *p, int siz
        fclose(f);
 }
 
-
-
 static uae_u8 *store_rel(uae_u8 *dst, uae_u8 mode, uae_u32 s, uae_u32 d, int ordered)
 {
        int diff = (uae_s32)d - (uae_s32)s;
@@ -964,7 +991,7 @@ static uae_u8 *store_rel(uae_u8 *dst, uae_u8 mode, uae_u32 s, uae_u32 d, int ord
                *dst++ = mode | CT_ABSOLUTE_WORD;
                *dst++ = (d >> 8) & 0xff;
                *dst++ = d & 0xff;
-       } else if ((d & ~addressing_mask) == ~addressing_mask && (d & addressing_mask) >= HIGH_MEMORY_START) {
+       } else if ((d & ~addressing_mask) == ~addressing_mask && (d & addressing_mask) >= (HIGH_MEMORY_START & addressing_mask)) {
                *dst++ = mode | CT_ABSOLUTE_WORD;
                *dst++ = (d >> 8) & 0xff;
                *dst++ = d & 0xff;
@@ -1065,6 +1092,7 @@ static uae_u8 *store_mem(uae_u8 *dst, int storealways)
                struct accesshistory *ah = &ahist[i];
                if (ah->oldval == ah->val && !storealways)
                        continue;
+               validate_addr(ah->addr, 1 << ah->size);
                uaecptr addr = ah->addr;
                addr &= addressing_mask;
                if (addr < 0x8000) {
@@ -1172,7 +1200,7 @@ static void save_data(uae_u8 *dst, const TCHAR *dir)
                fwrite(data, 1, 4, f);
                pl(data, opcode_memory_start - test_memory_start);
                fwrite(data, 1, 4, f);
-               pl(data, (cpu_lvl << 16) | sr_undefined_mask);
+               pl(data, (cpu_lvl << 16) | sr_undefined_mask | (addressing_mask == 0xffffffff ? 0x80000000 : 0));
                fwrite(data, 1, 4, f);
                pl(data, currprefs.fpu_model);
                fwrite(data, 1, 4, f);
@@ -1622,9 +1650,9 @@ static void execute_ins(uae_u16 opc, uaecptr endpc, uaecptr targetpc, struct ins
 {
        uae_u16 opw1 = (opcode_memory[2] << 8) | (opcode_memory[3] << 0);
        uae_u16 opw2 = (opcode_memory[4] << 8) | (opcode_memory[5] << 0);
-       if (opc == 0xf601
-//             && opw1 == 0x0000
-//             && opw2 == 0x9908
+       if (opc == 0xf603
+               && opw1 == 0x6884
+               && opw2 == 0x618d
                )
                printf("");
        if (regs.sr & 0x2000)
@@ -1760,6 +1788,18 @@ static int isunsupported(struct instr *dp)
        case i_MOVEC2:
        case i_FSAVE:
        case i_FRESTORE:
+       case i_PFLUSH:
+       case i_PFLUSHA:
+       case i_PFLUSHAN:
+       case i_PFLUSHN:
+       case i_PTESTR:
+       case i_PTESTW:
+       case i_CPUSHA:
+       case i_CPUSHL:
+       case i_CPUSHP:
+       case i_CINVA:
+       case i_CINVL:
+       case i_CINVP:
                return 1;
        case i_RTE:
                if (cpu_lvl > 0)
@@ -2092,7 +2132,7 @@ static void test_mnemo(const TCHAR *path, const TCHAR *mnemo, int opcodesize, in
                                        out_of_test_space = 0;
                                        ahcnt = 0;
 
-                                       if (opc == 0xf620)
+                                       if (opc == 0x0156)
                                                printf("");
                                        if (subtest_count == 1537)
                                                printf("");
@@ -2679,7 +2719,8 @@ 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 && currprefs.cpu_model != 68040) {
+       if (currprefs.cpu_model != 68000 && currprefs.cpu_model != 68010 && currprefs.cpu_model != 68020 &&
+               currprefs.cpu_model != 68030 && currprefs.cpu_model != 68040 && currprefs.cpu_model != 68060) {
                wprintf(_T("Unsupported CPU model.\n"));
                return 0;
        }
@@ -2726,7 +2767,7 @@ int __cdecl main(int argc, char *argv[])
        }
 
        feature_full_extension_format = 0;
-       if (currprefs.cpu_model > 68000) {
+       if (currprefs.cpu_model >= 68020) {
                ini_getval(ini, INISECTION, _T("feature_full_extension_format"), &feature_full_extension_format);
                if (feature_full_extension_format) {
                        ad8r[0] |= 2;
@@ -2908,9 +2949,15 @@ 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) {
+       } else if (currprefs.cpu_model == 68030) {
+               tbl = op_smalltbl_93_test_ff;
+               cpu_lvl = 3;
+       } else if (currprefs.cpu_model == 68040 ) {
                tbl = op_smalltbl_94_test_ff;
                cpu_lvl = 4;
+       } else if (currprefs.cpu_model == 68060) {
+               tbl = op_smalltbl_95_test_ff;
+               cpu_lvl = 5;
        } else {
                wprintf(_T("Unsupported CPU model.\n"));
                abort();
@@ -2929,6 +2976,9 @@ int __cdecl main(int argc, char *argv[])
                cpudatatbl[opcode].branch = tbl[i].branch;
        }
 
+       currprefs.int_no_unimplemented = true;
+       currprefs.fpu_no_unimplemented = true;
+
        for (int opcode = 0; opcode < 65536; opcode++) {
                cpuop_func *f;
                instr *table = &table68k[opcode];
@@ -2936,6 +2986,30 @@ int __cdecl main(int argc, char *argv[])
                if (table->mnemo == i_ILLG)
                        continue;
 
+               /* unimplemented opcode? */
+               if (table->unimpclev > 0 && cpu_lvl >= table->unimpclev) {
+                       if (currprefs.cpu_model == 68060) {
+                               // remove unimplemented integer instructions
+                               // unimpclev == 5: not implemented in 68060,
+                               // generates unimplemented instruction exception.
+                               if (currprefs.int_no_unimplemented && table->unimpclev == 5) {
+                                       cpufunctbl[opcode] = op_unimpl_1;
+                                       continue;
+                               }
+                               // remove unimplemented instruction that were removed in previous models,
+                               // generates normal illegal instruction exception.
+                               // unimplclev < 5: instruction was removed in 68040 or previous model.
+                               // clev=4: implemented in 68040 or later. unimpclev=5: not in 68060
+                               if (table->unimpclev < 5 || (table->clev == 4 && table->unimpclev == 5)) {
+                                       cpufunctbl[opcode] = op_illg_1;
+                                       continue;
+                               }
+                       } else {
+                               cpufunctbl[opcode] = op_illg_1;
+                               continue;
+                       }
+               }
+
                if (table->clev > cpu_lvl) {
                        continue;
                }
index 81cbc205b36724f0a491328e12cd9673d2e1d393..dcd6a41b3274efd4f74b5649a54532de3d1a000e 100644 (file)
@@ -62,6 +62,16 @@ _allocate_absolute:
 _get_cpu_model:
        move.l 4.w,a0
        move.w 0x128(a0),d1
+       cmp.w #15,d1
+       bne.s .cpucheck2
+       | 68040 but could be also 68060
+       movem.l a5/a6,-(sp)
+       move.l a0,a6
+       lea scpucheck(pc),a5
+       jsr -0x1e(a6)
+       movem.l (sp)+,a5/a6
+       bra.s .cpudone2
+.cpucheck2:    
        moveq #5,d0
        tst.b d1
        bmi.s .cpudone2
@@ -75,3 +85,19 @@ _get_cpu_model:
 .cpudone2:
        rts
 
+scpucheck:
+       or.w #0x0700,sr
+       movec vbr,a0
+       move.l 0x10(a0),d1
+       lea illg(pc),a1
+       move.l a1,0x10(a0)
+       move.l sp,a1
+       moveq #4,d0
+.arch 68060
+       movec pcr,d0
+.arch 68020
+       moveq #5,d0
+illg:
+       move.l d1,0x10(a0)
+       move.l a1,sp
+       rte
index 72d07f07a153e5feae08eb279a6a522375eb4eb2..6835dbb8ed6ee076f0462d314fb0eecdfa539931 100644 (file)
@@ -51,12 +51,14 @@ _setcpu:
        moveq #0,d0
        cmp.w #4,d1
        bcc.s .scend1b
+       | 68020-68030 only
        movec caar,d0
 .scend1b:
        move.l d0,(a0)+
        moveq #0,d0
        cmp.w #5,d1
        bcc.s .scend1c
+       | 68020-68040 only
        movec msp,d0
 .scend1c:
        move.l d0,(a0)+
@@ -76,11 +78,13 @@ _setcpu:
        move.l (a1)+,d0
        cmp.w #4,d1
        bcc.s .scend2b
+       | 68020-68030 only
        movec d0,caar
 .scend2b:
        move.l (a1)+,d0
        cmp.w #5,d1
        bcc.s .scend2
+       | 68020-68040 only
        move.c d0,msp
 .scend2:
        rts
@@ -125,12 +129,6 @@ _execute_test000:
        move.l S_AREG+7*4(a0),a1
        move.l a1,USP
        movem.l (a0),d0-d7/a0-a6
-       
-       | cmp.l #0x,0x7a0000
-       | bne.s .not
-       | clr.w 0x100
-|.not:
-       
        rte
 
        | 68010+ test entrypoint
index b0dce4c393e5a351e9926835c2348f21a2774827..21be525a3f335d11d502583a73b8a38ebc0eb8ce 100644 (file)
@@ -1,11 +1,11 @@
 
 [cputest]
 
-; CPU model (68000, 68020 or 68040).
+; CPU model (68000, 68020, 68040 or 68060).
 ; Always select 68020 when testing FPU instructions, even if test hardware CPU is 68040 or 68060.
 cpu=68020
 
-; CPU address space. 24-bit or 32-bit.
+; CPU address space. 24-bit or 32-bit. If 24-bit, tester will assume upper 8-bits of addresses gets ignored.
 cpu_address_space=32
 
 ; FPU model (empty string or 0, 68881, 68882, 68040, 68060)
@@ -22,16 +22,16 @@ path=data/
 test_low_memory_start=0x0000
 test_low_memory_end=0x8000
 
-; High address space limits (0x00ff8000 to 0x01000000 is complete space). Comment out to disable.
+; High address space limits (0x00ff8000 to 0x01000000 is complete space if 24-bit). Comment out to disable.
 ;test_high_memory_start=0x00ff8000
 ;test_high_memory_end=0x01000000
 
-; ROM high address space. High memory is only used for read tests.
+; ROM high address space. High memory is only used for read tests, uses last 32k of ROM image file.
 high_rom=D:\amiga\roms\Kickstart v3.1 rev 40.63 (1993)(Commodore)(A500-A600-A2000)[!].rom
 
 ; 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_start=0x780000
+test_memory_start=0x68800000
 test_memory_size=0x080000
 
 ; number of test rounds (registers are re-randomized after each round)
index cb71ce5c2f16ee07fe9375333f0a5178c587f11b..8b2c3ff5e6cc811b1c003efa32f646eb9501cd78 100644 (file)
@@ -1351,7 +1351,7 @@ static void process_test(uae_u8 *p)
 
                                                if (cpu_lvl == 1) {
                                                        execute_test010(&test_regs);
-                                               } else if (cpu_lvl == 2) {
+                                               } else if (cpu_lvl >= 2) {
                                                        if (fpu_model)
                                                                execute_testfpu(&test_regs);
                                                        else
@@ -1463,7 +1463,8 @@ 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);
-       lvl = gl(data) >> 16;
+       lvl = (gl(data) >> 16) & 15;
+       addressing_mask = (gl(data) & 0x80000000) ? 0xffffffff : 0x00ffffff;
        sr_undefined_mask = gl(data);
        fread(data, 1, 4, f);
        fpu_model = gl(data);
@@ -1516,6 +1517,7 @@ static int test_mnemo(const char *path, const char *opcode)
                exit(0);
        }
 
+       printf("CPUlvl=%d, Mask=%08lx\n", cpu_lvl, addressing_mask);
        printf("%s:\n", inst_name);
 
        testcnt = 0;
@@ -1535,7 +1537,7 @@ static int test_mnemo(const char *path, const char *opcode)
                fread(data, 1, 4, f);
                if (gl(data) != starttimeid) {
                        printf("Test data file header mismatch (old test data file?)\n");
-                       goto next;
+                       break;
                }
                fseek(f, 0, SEEK_END);
                test_data_size = ftell(f);
@@ -1564,7 +1566,6 @@ static int test_mnemo(const char *path, const char *opcode)
                        break;
 
                free(test_data);
-next:
                filecnt++;
        }
 
@@ -1626,10 +1627,9 @@ int main(int argc, char *argv[])
        if (lvl == 3) {
                lvl = 2;
        } else if (lvl == 5) {
-               lvl = 4;
 #ifdef M68K
                // Overwrite MOVEC to/from MSP
-               // with NOP if 68060
+               // with NOPs if 68060
                extern void *msp_address1;
                extern void *msp_address2;
                extern void *msp_address3;
@@ -1651,7 +1651,7 @@ int main(int argc, char *argv[])
                return 0;
        }
 
-       sprintf(path + strlen(path), "%lu/", 68000 + lvl * 10);
+       sprintf(path + strlen(path), "%lu/", 68000 + (lvl == 5 ? 6 : lvl) * 10);
 
        strcpy(opcode, argv[1]);
 
index e7ef2a1d12b22a01aa9dc442c6eb88001b0443d7..810728c313d10f6265adb8bf275f7050a82249b3 100644 (file)
@@ -4328,7 +4328,10 @@ static void gen_opcode (unsigned int opcode)
                        printf ("\tm68k_areg (regs, 7) += offs;\n");
                }
            printf ("\tif (pc & 1) {\n");
-           printf ("\t\texception3i (0x%04X, pc);\n", opcode);
+               if (cpu_level >= 4) {
+                       printf("\t\tm68k_areg(regs, 7) -= 4 + offs;\n");
+               }
+               printf ("\t\texception3i (0x%04X, pc);\n", opcode);
                printf ("\t\tgoto %s;\n", endlabelstr);
                printf ("\t}\n");
                setpc ("pc");
@@ -4338,6 +4341,10 @@ static void gen_opcode (unsigned int opcode)
                fill_prefetch_full ();
            need_endlabel = 1;
                branch_inst = 1;
+               if (cpu_level >= 4) {
+                       if (next_cpu_level < 4)
+                               next_cpu_level = 4 - 1;
+               }
                break;
        case i_LINK:
                // ce confirmed
@@ -4409,6 +4416,9 @@ static void gen_opcode (unsigned int opcode)
            printf ("\tif (%s & 1) {\n", getpc);
                printf ("\t\tuaecptr faultpc = %s;\n", getpc);
                setpc ("pc");
+               if (cpu_level >= 4) {
+                       printf("\t\tm68k_areg(regs, 7) -= 4;\n");
+               }
                printf ("\t\texception3i (0x%04X, faultpc);\n", opcode);
                printf ("\t\tgoto %s;\n", endlabelstr);
                printf ("\t}\n");
@@ -4417,6 +4427,10 @@ static void gen_opcode (unsigned int opcode)
                fill_prefetch_full ();
            need_endlabel = 1;
                branch_inst = 1;
+               if (cpu_level >= 4) {
+                       if (next_cpu_level < 4)
+                               next_cpu_level = 4 - 1;
+               }
                break;
        case i_TRAPV:
                sync_m68k_pc ();
@@ -4432,21 +4446,34 @@ static void gen_opcode (unsigned int opcode)
                printf ("\tMakeSR ();\n");
                genamode (NULL, Aipi, "7", sz_word, "sr", 1, 0, 0);
                genamode (NULL, Aipi, "7", sz_long, "pc", 1, 0, 0);
+               if (cpu_level >= 4) {
+                       printf("\tif (pc & 1) {\n");
+                       printf("\t\tm68k_areg(regs, 7) -= 6;\n");
+                       printf("\t\texception3i (0x%04X, pc);\n", opcode);
+                       printf("\t\tgoto %s;\n", endlabelstr);
+                       printf("\t}\n");
+               }
                printf ("\tregs.sr &= 0xFF00; sr &= 0xFF;\n");
                printf ("\tregs.sr |= sr;\n");
                setpc ("pc");
                makefromsr();
-               printf ("\tif (%s & 1) {\n", getpc);
-               printf ("\t\tuaecptr faultpc = %s;\n", getpc);
-               setpc ("oldpc");
-               printf ("\t\texception3i (0x%04X, faultpc);\n", opcode);
-               printf ("\t\tgoto %s;\n", endlabelstr);
-               printf ("\t}\n");
+               if (cpu_level < 4) {
+                       printf("\tif (%s & 1) {\n", getpc);
+                       printf("\t\tuaecptr faultpc = %s;\n", getpc);
+                       setpc("oldpc");
+                       printf("\t\texception3i (0x%04X, faultpc);\n", opcode);
+                       printf("\t\tgoto %s;\n", endlabelstr);
+                       printf("\t}\n");
+               }
                clear_m68k_offset();
                fill_prefetch_full ();
            need_endlabel = 1;
                branch_inst = 1;
                tail_ce020_done = true;
+               if (cpu_level >= 4) {
+                       if (next_cpu_level < 4)
+                               next_cpu_level = 4 - 1;
+               }
                break;
        case i_JSR:
                // possible idle cycle, prefetch from new address, stack high return addr, stack low, prefetch
@@ -4475,7 +4502,8 @@ static void gen_opcode (unsigned int opcode)
                                if (cpu_level <= 1 && using_prefetch)
                                        printf ("\tnextpc += 2;\n");
                        }
-                       printf("\tm68k_areg (regs, 7) -= 4;\n");
+                       if (cpu_level < 4)
+                               printf("\tm68k_areg (regs, 7) -= 4;\n");
                        if (using_exception_3 && cpu_level <= 1) {
                                printf("\tif (m68k_areg(regs, 7) & 1) {\n");
                                printf("\t\texception3_write(opcode, m68k_areg(regs, 7), 1);\n");
@@ -4491,6 +4519,8 @@ static void gen_opcode (unsigned int opcode)
                                printf("\t}\n");
                                need_endlabel = 1;
                        }
+                       if (cpu_level >= 4)
+                               printf("\tm68k_areg (regs, 7) -= 4;\n");
                        clear_m68k_offset();
                        fill_prefetch_1 (0);
                        if (using_ce || using_prefetch) {
@@ -4508,6 +4538,10 @@ static void gen_opcode (unsigned int opcode)
                fill_prefetch_full_020 ();
                fill_prefetch_next ();
                branch_inst = 1;
+               if (cpu_level >= 4) {
+                       if (next_cpu_level < 4)
+                               next_cpu_level = 4 - 1;
+               }
                break;
        case i_JMP:
                no_prefetch_ce020 = true;
@@ -4563,7 +4597,8 @@ static void gen_opcode (unsigned int opcode)
                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");
+                       if (cpu_level < 4)
+                               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");
@@ -4622,8 +4657,15 @@ static void gen_opcode (unsigned int opcode)
                }
                genamode (curi, curi->smode, "srcreg", curi->size, "src", 1, 0, GF_AA | (cpu_level < 2 ? GF_NOREFILL : 0));
                addcycles000 (2);
+               if (using_exception_3 && cpu_level >= 4) {
+                       printf("\tif (src & 1) {\n");
+                       printf("\t\texception3i (opcode, %s + 2 + (uae_s32)src);\n", getpc);
+                       printf("\t\tgoto %s;\n", endlabelstr);
+                       printf("\t}\n");
+                       need_endlabel = 1;
+               }
                printf ("\tif (!cctrue (%d)) goto didnt_jump;\n", curi->cc);
-               if (using_exception_3) {
+               if (using_exception_3 && cpu_level < 4) {
                        printf ("\tif (src & 1) {\n");
                        printf ("\t\texception3i (opcode, %s + 2 + (uae_s32)src);\n", getpc);
                        printf ("\t\tgoto %s;\n", endlabelstr);
@@ -4664,6 +4706,10 @@ static void gen_opcode (unsigned int opcode)
                insn_n_cycles = curi->size == sz_byte ? 8 : 12;
                branch_inst = 1;
 bccl_not68020:
+               if (cpu_level >= 4) {
+                       if (next_cpu_level < 4)
+                               next_cpu_level = 4 - 1;
+               }
                break;
        case i_LEA:
                if (curi->smode == Ad8r || curi->smode == PC8r)
@@ -4703,12 +4749,19 @@ bccl_not68020:
                //genamode (curi, curi->dmode, "dstreg", curi->size, "offs", 1, 0, GF_AA | GF_NOREFILL);
                printf ("\tuaecptr oldpc = %s;\n", getpc);
                addcycles000 (2);
+               if (using_exception_3 && cpu_level >= 4) {
+                       printf("\tif (offs & 1) {\n");
+                       printf("\t\t\texception3i (opcode, oldpc + (uae_s32)offs + 2);\n");
+                       printf("\t\t\tgoto %s;\n", endlabelstr);
+                       printf("\t\t}\n");
+                       need_endlabel = 1;
+               }
                push_ins_cnt();
                printf ("\tif (!cctrue (%d)) {\n", curi->cc);
                printf("\t");
                incpc ("(uae_s32)offs + 2");
                printf ("\t");
-               if (using_exception_3) {
+               if (using_exception_3 && cpu_level < 4) {
                        printf("\tif (offs & 1) {\n");
                        printf("\t\t\texception3i (opcode, %s);\n", getpc);
                        printf("\t\t\tgoto %s;\n", endlabelstr);
@@ -4740,6 +4793,10 @@ bccl_not68020:
                insn_n_cycles = 12;
                need_endlabel = 1;
                branch_inst = 1;
+               if (cpu_level >= 4) {
+                       if (next_cpu_level < 4)
+                               next_cpu_level = 4 - 1;
+               }
                break;
        case i_Scc:
                // confirmed
@@ -5483,11 +5540,16 @@ bccl_not68020:
                                int old_m68k_pc_total = m68k_pc_total;
                                old_brace_level = n_braces;
                                start_brace ();
+                               if (cpu_level >= 4) {
+                                       printf("\tuae_u32 src = regs.regs[(extra >> 12) & 15];\n");
+                               }
                                genamode (curi, curi->dmode, "dstreg", curi->size, "dst", 2, 0, 0);
                                tail_ce020_done = false;
                                returntail(false);
                                did_prefetch = 0;
-                               printf("\tuae_u32 src = regs.regs[(extra >> 12) & 15];\n");
+                               if (cpu_level < 4) {
+                                       printf("\tuae_u32 src = regs.regs[(extra >> 12) & 15];\n");
+                               }
                                genastore_fc ("src", curi->dmode, "dstreg", curi->size, "dst");
                                sync_m68k_pc();
                                pop_braces(old_brace_level);
@@ -5513,6 +5575,10 @@ bccl_not68020:
                                returntail(false);
                                pop_braces (old_brace_level);
                        }
+                       if (cpu_level >= 4) {
+                               if (next_cpu_level < 4)
+                                       next_cpu_level = 4 - 1;
+                       }
                }
                break;
        case i_BKPT:            /* only needed for hardware emulators */
@@ -6325,10 +6391,18 @@ static void generate_cpu_test(int mode)
                cpu_level = 2;
                using_prefetch = 0;
                using_simple_cycles = 0;
+       } else if (mode == 3) {
+               cpu_level = 3;
+               using_prefetch = 0;
+               using_simple_cycles = 0;
        } else if (mode == 4) {
                cpu_level = 4;
                using_prefetch = 0;
                using_simple_cycles = 0;
+       } else if (mode == 5) {
+               cpu_level = 5;
+               using_prefetch = 0;
+               using_simple_cycles = 0;
        }
 
        read_counts();
@@ -6559,7 +6633,9 @@ int main(int argc, char *argv[])
        generate_cpu_test(0);
        generate_cpu_test(1);
        generate_cpu_test(2);
+       generate_cpu_test(3);
        generate_cpu_test(4);
+       generate_cpu_test(5);
 
 #else
 
index 0fdb5a01fdbd4f7820b520c1b866e4bb67f664ac..954586a3e3d752150ea295a0c1b32a90918597c2 100644 (file)
@@ -28,7 +28,9 @@ 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_93_test_ff[];
 extern const struct cputbl op_smalltbl_94_test_ff[];
+extern const struct cputbl op_smalltbl_95_test_ff[];
 
 extern struct flag_struct regflags;
 
@@ -37,6 +39,7 @@ extern int movem_index2[256];
 extern int movem_next[256];
 
 uae_u16 get_word_test_prefetch(int);
+uae_u16 get_wordi_test(uaecptr);
 
 void put_byte_test(uaecptr, uae_u32);
 void put_word_test(uaecptr, uae_u32);