From fa2ad6373ef74fe84e7fef780eaecebc40516bbd Mon Sep 17 00:00:00 2001 From: Toni Wilen Date: Wed, 21 Aug 2019 22:00:02 +0300 Subject: [PATCH] CPU tester 68060 support, 68040/060 address error fixes. --- cputest.cpp | 104 +++++++++++++++++++++++++++++++++++------ cputest/amiga.S | 26 +++++++++++ cputest/asm.S | 10 ++-- cputest/cputestgen.ini | 12 ++--- cputest/main.c | 14 +++--- gencpu.cpp | 100 ++++++++++++++++++++++++++++++++++----- include/cputest.h | 3 ++ 7 files changed, 223 insertions(+), 46 deletions(-) diff --git a/cputest.cpp b/cputest.cpp index 2e4d28fe..ea8e9d40 100644 --- a/cputest.cpp +++ b/cputest.cpp @@ -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; } diff --git a/cputest/amiga.S b/cputest/amiga.S index 81cbc205..dcd6a41b 100644 --- a/cputest/amiga.S +++ b/cputest/amiga.S @@ -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 diff --git a/cputest/asm.S b/cputest/asm.S index 72d07f07..6835dbb8 100644 --- a/cputest/asm.S +++ b/cputest/asm.S @@ -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 diff --git a/cputest/cputestgen.ini b/cputest/cputestgen.ini index b0dce4c3..21be525a 100644 --- a/cputest/cputestgen.ini +++ b/cputest/cputestgen.ini @@ -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) diff --git a/cputest/main.c b/cputest/main.c index cb71ce5c..8b2c3ff5 100644 --- a/cputest/main.c +++ b/cputest/main.c @@ -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]); diff --git a/gencpu.cpp b/gencpu.cpp index e7ef2a1d..810728c3 100644 --- a/gencpu.cpp +++ b/gencpu.cpp @@ -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 diff --git a/include/cputest.h b/include/cputest.h index 0fdb5a01..954586a3 100644 --- a/include/cputest.h +++ b/include/cputest.h @@ -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); -- 2.47.3