From: Toni Wilen Date: Thu, 15 Aug 2019 19:49:49 +0000 (+0300) Subject: Added FC field to exception3_read/write. CPU tester DBcc and BSR address error fixes. X-Git-Tag: 4300~149 X-Git-Url: https://git.unchartedbackwaters.co.uk/w/?a=commitdiff_plain;h=6187b19a2d940eddce9a57765037f49108340545;p=francis%2Fwinuae.git Added FC field to exception3_read/write. CPU tester DBcc and BSR address error fixes. --- diff --git a/cputest.cpp b/cputest.cpp index 2f8eb85c..c63ede85 100644 --- a/cputest.cpp +++ b/cputest.cpp @@ -59,6 +59,7 @@ static int feature_sr_mask = 0; static int feature_loop_mode = 0; static int feature_loop_mode_register = -1; static int feature_full_extension_format = 0; +static int feature_test_rounds = 2; static uae_u32 feature_addressing_modes[2]; static int ad8r[2], pc8r[2]; @@ -95,8 +96,8 @@ static int forced_immediate_mode; static int test_exception; static int exception_stack_frame_size; static uaecptr test_exception_addr; -static int test_exception_3_inst; static int test_exception_3_w; +static int test_exception_3_fc; static int test_exception_opcode; static uae_u8 imm8_cnt; static uae_u16 imm16_cnt; @@ -669,28 +670,23 @@ static void doexcstack(void) testing_active = -1; int opcode = (opcode_memory[0] << 8) | (opcode_memory[1]); - int statusormask = 0, statusandmask = 0; - if (test_exception_opcode >= 0) { + if (test_exception_opcode >= 0) opcode = test_exception_opcode; - statusormask = (test_exception_opcode >> 16) & 0xff; - statusandmask = (test_exception_opcode >> 24) & 0xff; - } int sv = regs.s; uaecptr tmp = m68k_areg(regs, 7); m68k_areg(regs, 7) = test_memory_end + EXTRA_RESERVED_SPACE; if (cpu_lvl == 0) { if (test_exception == 3) { - uae_u16 mode = (sv ? 4 : 0) | (test_exception_3_inst ? 2 : 1) | statusormask; - mode &= ~statusandmask; + uae_u16 mode = (sv ? 4 : 0) | test_exception_3_fc; mode |= test_exception_3_w ? 0 : 16; Exception_build_68000_address_error_stack_frame(mode, opcode, test_exception_addr, regs.pc); } } else if (cpu_lvl == 1) { if (test_exception == 3) { - uae_u16 ssw = (sv ? 4 : 0) | (test_exception_3_inst ? 2 : 1); + uae_u16 ssw = (sv ? 4 : 0) | test_exception_3_fc; ssw |= test_exception_3_w ? 0 : 0x100; - ssw |= test_exception_3_inst ? 0 : 0x2000; + ssw |= (test_exception_3_fc & 2) ? 0 : 0x2000; regs.mmu_fault_addr = test_exception_addr; Exception_build_stack_frame(regs.instruction_pc, regs.pc, ssw, 3, 0x08); } else { @@ -698,7 +694,7 @@ static void doexcstack(void) } } else if (cpu_lvl == 2) { if (test_exception == 3) { - uae_u16 ssw = (sv ? 4 : 0) | (test_exception_3_inst ? 2 : 1); + 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; @@ -743,28 +739,27 @@ uae_u32 REGPARAM2 op_illg(uae_u32 opcode) return op_illg_1(opcode); } -void exception3_read(uae_u32 opcode, uae_u32 addr) +void exception3_read(uae_u32 opcode, uae_u32 addr, int fc) { test_exception = 3; - test_exception_3_inst = 0; test_exception_3_w = 0; test_exception_addr = addr; test_exception_opcode = opcode; + test_exception_3_fc = fc; doexcstack(); } -void exception3_write(uae_u32 opcode, uae_u32 addr) +void exception3_write(uae_u32 opcode, uae_u32 addr, int fc) { test_exception = 3; - test_exception_3_inst = 0; test_exception_3_w = 1; test_exception_addr = addr; test_exception_opcode = opcode; + test_exception_3_fc = fc; doexcstack(); } void REGPARAM2 Exception(int n) { test_exception = n; - test_exception_3_inst = 0; test_exception_addr = m68k_getpci(); test_exception_opcode = -1; doexcstack(); @@ -772,7 +767,6 @@ void REGPARAM2 Exception(int n) void REGPARAM2 Exception_cpu(int n) { test_exception = n; - test_exception_3_inst = 0; test_exception_addr = m68k_getpci(); test_exception_opcode = -1; @@ -786,7 +780,7 @@ void REGPARAM2 Exception_cpu(int n) void exception3i(uae_u32 opcode, uaecptr addr) { test_exception = 3; - test_exception_3_inst = 1; + test_exception_3_fc = 2; test_exception_3_w = 0; test_exception_addr = addr; test_exception_opcode = opcode; @@ -795,7 +789,7 @@ void exception3i(uae_u32 opcode, uaecptr addr) void exception3b(uae_u32 opcode, uaecptr addr, bool w, bool i, uaecptr pc) { test_exception = 3; - test_exception_3_inst = i; + test_exception_3_fc = i ? 2 : 1; test_exception_3_w = w; test_exception_addr = addr; test_exception_opcode = opcode; @@ -1802,7 +1796,7 @@ static uae_u8 *save_exception(uae_u8 *p, struct instr *dp) abort(); } } - if (last_exception_len == exception_stack_frame_size && !memcmp(sf, last_exception, exception_stack_frame_size)) { + if (last_exception_len > 0 && last_exception_len == exception_stack_frame_size && !memcmp(sf, last_exception, exception_stack_frame_size)) { // stack frame was identical to previous p = op; *p++ = 0xff; @@ -1922,7 +1916,7 @@ static void test_mnemo(const TCHAR *path, const TCHAR *mnemo, int opcodesize, in wprintf(_T("%s\n"), dir); int quick = 0; - int rounds = 4; + int rounds = feature_test_rounds; int subtest_count = 0; int count = 0; @@ -2322,7 +2316,7 @@ static void test_mnemo(const TCHAR *path, const TCHAR *mnemo, int opcodesize, in if (regs.sr & 0x2000) prev_s_cnt++; - if (subtest_count == 1536) + if (subtest_count == 353) printf(""); execute_ins(opc, pc - 2, branch_target); @@ -2358,10 +2352,10 @@ static void test_mnemo(const TCHAR *path, const TCHAR *mnemo, int opcodesize, in } } if (test_exception == 3) { - if (!feature_exception3_data && !test_exception_3_inst) { + if (!feature_exception3_data && !(test_exception_3_fc & 2)) { skipped = 1; } - if (!feature_exception3_instruction && test_exception_3_inst) { + if (!feature_exception3_instruction && (test_exception_3_fc & 2)) { skipped = 1; } } else { diff --git a/gencpu.cpp b/gencpu.cpp index 7ba83445..e3b37726 100644 --- a/gencpu.cpp +++ b/gencpu.cpp @@ -1339,7 +1339,7 @@ static void maybeaddop_ce020 (int flags) // Handle special MOVE.W/.L condition codes when destination write causes address error. -static void move_68000_address_error(amodes mode, int size, int *setapdi) +static void move_68000_address_error(amodes mode, int size, int *setapdi, int *fcmodeflags) { int smode = g_instr->smode; int dmode = g_instr->dmode; @@ -1368,8 +1368,10 @@ static void move_68000_address_error(amodes mode, int size, int *setapdi) break; } if (dmode == Apdi) { - // this is buggy, address error stack frame opcode field contains next instruction opcode! - printf("\t\topcode = regs.irc | 0x00080000;\n"); + // this is buggy, address error stack frame opcode field contains next + // instruction opcode and Instruction/Not field is one! + printf("\t\topcode = regs.irc;\n"); + *fcmodeflags |= 0x08; // "Not instruction" = 1 } if (set_ccr) { printf("\t\tccr_68000_word_move_ae_normal((uae_s16)(src));\n"); @@ -1783,6 +1785,7 @@ static void genamode2x (amodes mode, const char *reg, wordsizes size, const char // check possible address error (if 68000/010 and enabled) if ((using_prefetch || using_ce) && using_exception_3 && getv != 0 && size != sz_byte && !movem) { int setapdiback = 0; + int fcmodeflags = 0; printf("\tif (%sa & 1) {\n", name); @@ -1801,7 +1804,7 @@ static void genamode2x (amodes mode, const char *reg, wordsizes size, const char if (g_instr->mnemo == i_MOVE) { if (getv == 2) { - move_68000_address_error(mode, size, &setapdiback); + move_68000_address_error(mode, size, &setapdiback, &fcmodeflags); } } @@ -1809,16 +1812,14 @@ static void genamode2x (amodes mode, const char *reg, wordsizes size, const char printf("\t\tm68k_areg (regs, %s) = %sa;\n", reg, name); } - // PC-relative: FC=2 - if (getv == 1 && (g_instr->smode == PC16 || g_instr->smode == PC8r)) { - printf("\t\topcode |= 0x01020000;\n"); - } - // MOVE.L EA,-(An) causing address error: stacked value is original An - 2, not An - 4. if ((flags & (GF_REVERSE | GF_REVERSE2)) && size == sz_long && mode == Apdi) printf("\t\t%sa += %d;\n", name, flags & GF_REVERSE2 ? -2 : 2); - printf("\t\texception3_%s(opcode, %sa);\n", getv == 2 ? "write" : "read", name); + printf("\t\texception3_%s(opcode, %sa, %d);\n", + getv == 2 ? "write" : "read", name, + // PC-relative: FC=2 + (getv == 1 && (g_instr->smode == PC16 || g_instr->smode == PC8r) ? 2 : 1) | fcmodeflags); printf ("\t\tgoto %s;\n", endlabelstr); printf ("\t}\n"); @@ -2453,7 +2454,8 @@ static void movem_ex3(int write) printf("\t\topcode |= 0x01020000;\n"); } } - printf("\t\texception3_%s(opcode, srca);\n", write ? "write" : "read"); + printf("\t\texception3_%s(opcode, srca, %d);\n", + write ? "write" : "read", (g_instr->dmode == PC16 || g_instr->dmode == PC8r) ? 2 : 1); printf("\t\tgoto %s;\n", endlabelstr); printf("\t}\n"); need_endlabel = 1; @@ -4374,7 +4376,7 @@ static void gen_opcode (unsigned int opcode) printf ("\tuaecptr pc = %s;\n", getpc); if (cpu_level <= 1 && using_exception_3) { printf("\tif (m68k_areg(regs, 7) & 1) {\n"); - printf("\t\texception3_read(opcode, m68k_areg(regs, 7));\n"); + printf("\t\texception3_read(opcode, m68k_areg(regs, 7), 1);\n"); printf("\t\tgoto %s;\n", endlabelstr); printf("\t}\n"); } @@ -4471,7 +4473,7 @@ static void gen_opcode (unsigned int opcode) 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));\n"); + printf("\t\texception3_write(opcode, m68k_areg(regs, 7), 1);\n"); printf("\t\tgoto %s;\n", endlabelstr); printf("\t}\n"); } @@ -4529,16 +4531,17 @@ static void gen_opcode (unsigned int opcode) } printf ("\ts = (uae_s32)src + 2;\n"); if (using_exception_3) { - printf("\tif (src & 1) {\n"); - printf("\t\texception3b(opcode, %s + s, 0, 1, %s + s);\n", getpc, getpc); - printf("\t\tgoto %s;\n", endlabelstr); - printf("\t}\n"); if (cpu_level <= 1) { printf("\tif (m68k_areg(regs, 7) & 1) {\n"); printf("\t\tm68k_areg(regs, 7) -= 4;\n"); printf("\t\texception3b(opcode, m68k_areg(regs, 7), true, false, %s + 2);\n", getpc); printf("\t\tgoto %s;\n", endlabelstr); printf("\t}\n"); + } else { + printf("\tif (src & 1) {\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; } @@ -4560,6 +4563,12 @@ static void gen_opcode (unsigned int opcode) } else { printf ("\tm68k_do_bsr (nextpc, s);\n"); } + if (using_exception_3 && cpu_level <= 1) { + printf("\tif (%s & 1) {\n", getpc); + printf("\t\texception3b(opcode, %s, 0, 1, %s);\n", getpc, getpc); + printf("\t\tgoto %s;\n", endlabelstr); + printf("\t}\n"); + } if (using_debugmem) { printf("\tif (debugmem_trace)\n"); printf("\t\tbranch_stack_push(oldpc, nextpc);\n"); @@ -4674,20 +4683,21 @@ bccl_not68020: addcycles000 (2); push_ins_cnt(); printf ("\tif (!cctrue (%d)) {\n", curi->cc); + printf("\t"); incpc ("(uae_s32)offs + 2"); printf ("\t"); - fill_prefetch_1 (0); - printf ("\t"); - genastore ("(src - 1)", curi->smode, "srcreg", curi->size, "src"); - - printf ("\t\tif (src) {\n"); if (using_exception_3) { - printf ("\t\t\tif (offs & 1) {\n"); - printf ("\t\t\t\texception3i (opcode, %s + 2 + (uae_s32)offs + 2);\n", getpc); - printf ("\t\t\t\tgoto %s;\n", endlabelstr); - printf ("\t\t\t}\n"); + printf("\tif (offs & 1) {\n"); + printf("\t\t\texception3i (opcode, %s);\n", getpc); + printf("\t\t\tgoto %s;\n", endlabelstr); + printf("\t\t}\n"); need_endlabel = 1; } + printf("\t"); + fill_prefetch_1(0); + printf("\t"); + genastore ("(src - 1)", curi->smode, "srcreg", curi->size, "src"); + printf ("\t\tif (src) {\n"); irc2ir (); add_head_cycs (6); fill_prefetch_1 (2); diff --git a/include/newcpu.h b/include/newcpu.h index b6cd5ff4..d737f4d5 100644 --- a/include/newcpu.h +++ b/include/newcpu.h @@ -714,8 +714,8 @@ extern void fpux_restore (int*); extern bool fpu_get_constant(fpdata *fp, int cr); extern int fpp_cond(int condition); -extern void exception3_read(uae_u32 opcode, uaecptr addr); -extern void exception3_write(uae_u32 opcode, uaecptr addr); +extern void exception3_read(uae_u32 opcode, uaecptr addr, int fc); +extern void exception3_write(uae_u32 opcode, uaecptr addr, int fc); extern void exception3_notinstruction(uae_u32 opcode, uaecptr addr); extern void exception3i (uae_u32 opcode, uaecptr addr); extern void exception3b (uae_u32 opcode, uaecptr addr, bool w, bool i, uaecptr pc); diff --git a/newcpu.cpp b/newcpu.cpp index e1c2938f..a116f0ae 100644 --- a/newcpu.cpp +++ b/newcpu.cpp @@ -69,8 +69,8 @@ static uaecptr last_addr_for_exception_3; static uaecptr last_fault_for_exception_3; /* read (0) or write (1) access */ static bool last_writeaccess_for_exception_3; -/* instruction (1) or data (0) access */ -static bool last_instructionaccess_for_exception_3; +/* FC */ +static int last_fc_for_exception_3; /* not instruction */ static bool last_notinstruction_for_exception_3; /* set when writing exception stack frame */ @@ -2491,15 +2491,11 @@ static void Exception_ce000 (int nr) write_log(_T("Exception %d (%08x %x) at %x -> %x!\n"), nr, last_op_for_exception_3, last_addr_for_exception_3, currpc, get_long_debug(4 * nr)); if (currprefs.cpu_model == 68000) { - uae_u16 mode = (sv ? 4 : 0) | (last_instructionaccess_for_exception_3 ? 2 : 1); + uae_u16 mode = (sv ? 4 : 0) | last_fc_for_exception_3; mode |= last_writeaccess_for_exception_3 ? 0 : 16; mode |= last_notinstruction_for_exception_3 ? 8 : 0; // undocumented bits seem to contain opcode mode |= last_op_for_exception_3 & ~31; - uae_u16 statusormask = (last_op_for_exception_3 >> 16) & 0xff; - uae_u16 statusandmask = (last_op_for_exception_3 >> 24) & 0xff; - mode |= statusormask; - mode &= ~statusandmask; m68k_areg(regs, 7) -= 14; exception_in_exception = -1; x_put_word(m68k_areg(regs, 7) + 12, last_addr_for_exception_3); @@ -2513,9 +2509,9 @@ static void Exception_ce000 (int nr) goto kludge_me_do; } else { // 68010 address error (partially implemented only) - uae_u16 ssw = (sv ? 4 : 0) | (last_instructionaccess_for_exception_3 ? 2 : 1); + uae_u16 ssw = (sv ? 4 : 0) | last_fc_for_exception_3; ssw |= last_writeaccess_for_exception_3 ? 0 : 0x100; - ssw |= last_instructionaccess_for_exception_3 ? 0 : 0x2000; + ssw |= (last_fc_for_exception_3 & 2) ? 0 : 0x2000; m68k_areg(regs, 7) -= 50; exception_in_exception = -1; frame_id = 8; @@ -2644,7 +2640,7 @@ static void Exception_mmu030 (int nr, uaecptr oldpc) if (nr == 2 || nr == 3) cpu_halt (CPU_HALT_DOUBLE_FAULT); else - exception3_read(regs.ir, newpc); + exception3_read(regs.ir, newpc, 1); return; } if (interrupt) @@ -2710,7 +2706,7 @@ static void Exception_mmu (int nr, uaecptr oldpc) if (nr == 2 || nr == 3) cpu_halt (CPU_HALT_DOUBLE_FAULT); else - exception3_read(regs.ir, newpc); + exception3_read(regs.ir, newpc, 1); return; } @@ -2854,7 +2850,7 @@ static void Exception_normal (int nr) if (nr == 2 || nr == 3) cpu_halt (CPU_HALT_DOUBLE_FAULT); else - exception3_read(regs.ir, newpc); + exception3_read(regs.ir, newpc, 1); return; } m68k_setpc (newpc); @@ -2900,7 +2896,7 @@ static void Exception_normal (int nr) } } else if (currprefs.cpu_model >= 68020) { // 68020/030 odd PC address error (partially implemented only) - uae_u16 ssw = (sv ? 4 : 0) | (last_instructionaccess_for_exception_3 ? 2 : 1); + uae_u16 ssw = (sv ? 4 : 0) | last_fc_for_exception_3; ssw |= last_writeaccess_for_exception_3 ? 0 : 0x40; ssw |= 0x20; regs.mmu_fault_addr = last_fault_for_exception_3; @@ -2908,9 +2904,9 @@ static void Exception_normal (int nr) used_exception_build_stack_frame = true; } else { // 68010 address error (partially implemented only) - uae_u16 ssw = (sv ? 4 : 0) | (last_instructionaccess_for_exception_3 ? 2 : 1); + uae_u16 ssw = (sv ? 4 : 0) | last_fc_for_exception_3; ssw |= last_writeaccess_for_exception_3 ? 0 : 0x100; - ssw |= last_instructionaccess_for_exception_3 ? 0 : 0x2000; + ssw |= (last_fc_for_exception_3 & 2) ? 0 : 0x2000; regs.mmu_fault_addr = last_addr_for_exception_3; Exception_build_stack_frame(oldpc, currpc, ssw, nr, 0x08); used_exception_build_stack_frame = true; @@ -2940,13 +2936,9 @@ static void Exception_normal (int nr) nextpc = m68k_getpc (); if (nr == 2 || nr == 3) { // 68000 bus error/address error - uae_u16 mode = (sv ? 4 : 0) | (last_instructionaccess_for_exception_3 ? 2 : 1); + uae_u16 mode = (sv ? 4 : 0) | last_fc_for_exception_3; mode |= last_writeaccess_for_exception_3 ? 0 : 16; mode |= last_notinstruction_for_exception_3 ? 8 : 0; - uae_u16 statusormask = (last_op_for_exception_3 >> 16) & 0xff; - uae_u16 statusandmask = (last_op_for_exception_3 >> 24) & 0xff; - mode |= statusormask; - mode &= ~statusandmask; exception_in_exception = -1; Exception_build_68000_address_error_stack_frame(mode, last_op_for_exception_3, last_fault_for_exception_3, last_addr_for_exception_3); write_log (_T("Exception %d (%x) at %x -> %x!\n"), nr, last_fault_for_exception_3, currpc, get_long_debug (regs.vbr + 4 * vector_nr)); @@ -5788,7 +5780,7 @@ static void exception2_handle (uaecptr addr, uaecptr fault) last_addr_for_exception_3 = addr; last_fault_for_exception_3 = fault; last_writeaccess_for_exception_3 = 0; - last_instructionaccess_for_exception_3 = 0; + last_fc_for_exception_3 = 0; Exception (2); } #endif @@ -6825,7 +6817,7 @@ uae_u8 *restore_mmu (uae_u8 *src) #endif /* SAVESTATE */ -static void exception3f (uae_u32 opcode, uaecptr addr, bool writeaccess, bool instructionaccess, bool notinstruction, uaecptr pc, bool plus2) +static void exception3f (uae_u32 opcode, uaecptr addr, bool writeaccess, bool instructionaccess, bool notinstruction, uaecptr pc, bool plus2, int fc) { if (currprefs.cpu_model >= 68040) addr &= ~1; @@ -6844,7 +6836,7 @@ static void exception3f (uae_u32 opcode, uaecptr addr, bool writeaccess, bool in last_fault_for_exception_3 = addr; last_op_for_exception_3 = opcode; last_writeaccess_for_exception_3 = writeaccess; - last_instructionaccess_for_exception_3 = instructionaccess; + last_fc_for_exception_3 = fc >= 0 ? fc : (instructionaccess ? 2 : 1); last_notinstruction_for_exception_3 = notinstruction; Exception (3); #if EXCEPTION3_DEBUGGER @@ -6854,23 +6846,23 @@ static void exception3f (uae_u32 opcode, uaecptr addr, bool writeaccess, bool in void exception3_notinstruction(uae_u32 opcode, uaecptr addr) { - exception3f (opcode, addr, true, false, true, 0xffffffff, false); + exception3f (opcode, addr, true, false, true, 0xffffffff, false, -1); } -void exception3_read(uae_u32 opcode, uaecptr addr) +void exception3_read(uae_u32 opcode, uaecptr addr, int fc) { - exception3f (opcode, addr, false, 0, false, 0xffffffff, false); + exception3f (opcode, addr, false, 0, false, 0xffffffff, false, fc); } -void exception3_write(uae_u32 opcode, uaecptr addr) +void exception3_write(uae_u32 opcode, uaecptr addr, int fc) { - exception3f (opcode, addr, true, 0, false, 0xffffffff, false); + exception3f (opcode, addr, true, 0, false, 0xffffffff, false, fc); } void exception3i (uae_u32 opcode, uaecptr addr) { - exception3f (opcode, addr, 0, 1, false, 0xffffffff, true); + exception3f (opcode, addr, 0, 1, false, 0xffffffff, true, -1); } void exception3b (uae_u32 opcode, uaecptr addr, bool w, bool i, uaecptr pc) { - exception3f (opcode, addr, w, i, false, pc, true); + exception3f (opcode, addr, w, i, false, pc, true, -1); } void exception2_setup(uaecptr addr, bool read, int size, uae_u32 fc) @@ -6878,7 +6870,7 @@ void exception2_setup(uaecptr addr, bool read, int size, uae_u32 fc) last_addr_for_exception_3 = m68k_getpc() + bus_error_offset; last_fault_for_exception_3 = addr; last_writeaccess_for_exception_3 = read == 0; - last_instructionaccess_for_exception_3 = (fc & 1) == 0; + last_fc_for_exception_3 = fc; last_op_for_exception_3 = regs.opcode; last_notinstruction_for_exception_3 = exception_in_exception != 0; }