From: Toni Wilen Date: Sat, 16 Feb 2019 11:10:23 +0000 (+0200) Subject: 68030 MMU short bus error stack frame preparations. X-Git-Tag: 4200~56 X-Git-Url: https://git.unchartedbackwaters.co.uk/w/?a=commitdiff_plain;h=75a81a573941aa58430ac19e545eebcaa2ff06cc;p=francis%2Fwinuae.git 68030 MMU short bus error stack frame preparations. --- diff --git a/cpummu30.cpp b/cpummu30.cpp index 111f0192..e8a7f505 100644 --- a/cpummu30.cpp +++ b/cpummu30.cpp @@ -2742,35 +2742,58 @@ void m68k_do_rte_mmu030 (uaecptr a7) else get_word_mmu030(a7 + 32 - 2); - // Internal register, our opcode storage area - uae_u32 oc = get_long_mmu030(a7 + 0x14); - // Data output buffer - uae_u32 mmu030_data_buffer_out_v = get_long_mmu030(a7 + 0x18); - // get_disp_ea_020 - uae_u32 mmu030_disp_store_0 = get_long_mmu030(a7 + 0x1c); - uae_u32 mmu030_disp_store_1 = get_long_mmu030(a7 + 0x1c + 4); - // Internal register, misc flags - uae_u32 ps = get_long_mmu030(a7 + 0x28); - // Data buffer - uae_u32 mmu030_data_buffer_in_v = get_long_mmu030(a7 + 0x2c);; + // Rerun "mmu030_opcode" using restored state. + mmu030_retry = true; - uae_u32 mmu030_opcode_v = (ps & 0x80000000) ? -1U : (oc & 0xffff); - // Misc state data - uae_u32 mmu030_state_0 = get_word_mmu030(a7 + 0x30); - uae_u32 mmu030_state_1 = get_word_mmu030(a7 + 0x32); - uae_u32 mmu030_state_2 = get_word_mmu030(a7 + 0x34); + if (frame == 0xa) { - uae_u32 mmu030_fmovem_store_0 = 0; - uae_u32 mmu030_fmovem_store_1 = 0; - if (mmu030_state[1] & MMU030_STATEFLAG1_FMOVEM) { - mmu030_fmovem_store_0 = get_long_mmu030(a7 + 0x5c - (7 + 1) * 4); - mmu030_fmovem_store_1 = get_long_mmu030(a7 + 0x5c - (8 + 1) * 4); - } + // A-frame only in non-prefetch mode and only when + // instruction's first word fetch caused access fault. + // mmu030_opcode_v is always -1 here. + if ((ssw & MMU030_SSW_FB) && !(ssw & MMU030_SSW_RB)) { + uae_u16 stageb = get_word_mmu030(a7 + 0x0e); + mmu030_opcode_stageb = stageb; + write_log(_T("Software fixed stage B! opcode = %04x\n"), stageb); + } + mmu030_opcode = -1; - // Rerun "mmu030_opcode" using restored state. - mmu030_retry = true; + m68k_areg(regs, 7) += 32; + regs.sr = sr; + MakeFromSR_T0(); + if (pc & 1) { + exception3i(0x4E73, pc); + return; + } + m68k_setpci(pc); - if (frame == 0xb) { + + } else if (frame == 0xb) { + + // get_disp_ea_020 + uae_u32 mmu030_disp_store_0 = get_long_mmu030(a7 + 0x1c); + uae_u32 mmu030_disp_store_1 = get_long_mmu030(a7 + 0x1c + 4); + // Internal register, misc flags + uae_u32 ps = get_long_mmu030(a7 + 0x28); + // Data buffer + uae_u32 mmu030_data_buffer_in_v = get_long_mmu030(a7 + 0x2c);; + // Misc state data + uae_u32 mmu030_state_0 = get_word_mmu030(a7 + 0x30); + uae_u32 mmu030_state_1 = get_word_mmu030(a7 + 0x32); + uae_u32 mmu030_state_2 = get_word_mmu030(a7 + 0x34); + + // Internal register, our opcode storage area + uae_u32 oc = get_long_mmu030(a7 + 0x14); + // Data output buffer + uae_u32 mmu030_data_buffer_out_v = get_long_mmu030(a7 + 0x18); + + uae_u32 mmu030_opcode_v = (ps & 0x80000000) ? -1U : (oc & 0xffff); + + uae_u32 mmu030_fmovem_store_0 = 0; + uae_u32 mmu030_fmovem_store_1 = 0; + if (mmu030_state[1] & MMU030_STATEFLAG1_FMOVEM) { + mmu030_fmovem_store_0 = get_long_mmu030(a7 + 0x5c - (7 + 1) * 4); + mmu030_fmovem_store_1 = get_long_mmu030(a7 + 0x5c - (8 + 1) * 4); + } uae_u16 idxsize = get_word_mmu030 (a7 + 0x36); for (int i = 0; i < idxsize + 1; i++) { @@ -2928,8 +2951,6 @@ void m68k_do_rte_mmu030 (uaecptr a7) } #endif - } else { - m68k_areg (regs, 7) += 32; } } @@ -3331,6 +3352,16 @@ void m68k_do_rte_mmu030c (uaecptr a7) } } else { + m68k_areg (regs, 7) += 32; + + regs.sr = sr; + MakeFromSR_T0(); + if (pc & 1) { + exception3i(0x4E73, pc); + return; + } + m68k_setpci(pc); + } } diff --git a/gencpu.cpp b/gencpu.cpp index 84831131..3cb38b42 100644 --- a/gencpu.cpp +++ b/gencpu.cpp @@ -4025,10 +4025,10 @@ static void gen_opcode (unsigned int opcode) printf ("\t\telse if (frame == 0x9) { m68k_areg (regs, 7) += offset + 12; break; }\n"); if (using_mmu == 68030) { if (using_prefetch_020) { - printf ("\t\telse if (frame == 0xa) { m68k_do_rte_mmu030c (a); break; }\n"); + printf ("\t\telse if (frame == 0xa) { m68k_do_rte_mmu030c (a); goto %s; }\n", endlabelstr); printf ("\t\telse if (frame == 0xb) { m68k_do_rte_mmu030c (a); goto %s; }\n", endlabelstr); } else { - printf ("\t\telse if (frame == 0xa) { m68k_do_rte_mmu030 (a); break; }\n"); + printf ("\t\telse if (frame == 0xa) { m68k_do_rte_mmu030 (a); goto %s; }\n", endlabelstr); printf ("\t\telse if (frame == 0xb) { m68k_do_rte_mmu030 (a); goto %s; }\n", endlabelstr); } } else { diff --git a/newcpu.cpp b/newcpu.cpp index 870b441f..ff94ed94 100644 --- a/newcpu.cpp +++ b/newcpu.cpp @@ -3362,7 +3362,12 @@ static void Exception_mmu030 (int nr, uaecptr oldpc) m68k_areg (regs, 7) = regs.isp; Exception_build_stack_frame (oldpc, currpc, regs.mmu_ssw, nr, 0x1); } else if (nr == 2) { - Exception_build_stack_frame (oldpc, currpc, regs.mmu_ssw, nr, 0xB); + if (0) { + // not that simple + Exception_build_stack_frame(oldpc, currpc, regs.mmu_ssw, nr, 0xA); + } else { + Exception_build_stack_frame(oldpc, currpc, regs.mmu_ssw, nr, 0xB); + } } else if (nr == 3) { regs.mmu_fault_addr = last_fault_for_exception_3; mmu030_state[0] = mmu030_state[1] = 0; @@ -5996,7 +6001,7 @@ insretry: } CATCH (prb) { - if (mmu030_opcode == -1 && currprefs.cpu_compatible) { + if (mmu030_opcode == -1) { // full prefetch fill access fault // TODO: this should create shorter A-frame mmufixup[0].reg = -1;