]> git.unchartedbackwaters.co.uk Git - francis/winuae.git/commitdiff
68030 MMU short bus error stack frame preparations.
authorToni Wilen <twilen@winuae.net>
Sat, 16 Feb 2019 11:10:23 +0000 (13:10 +0200)
committerToni Wilen <twilen@winuae.net>
Sat, 16 Feb 2019 11:10:23 +0000 (13:10 +0200)
cpummu30.cpp
gencpu.cpp
newcpu.cpp

index 111f0192852da47d80a9bf8a21f2219f5d8b56ad..e8a7f5055a8e167128096529930f4580cc867756 100644 (file)
@@ -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);
+
        }
 }
index 8483113106a1027ad208acc1622b8d355aac38c6..3cb38b42583c0457b4fb8d42dc49ce8e757fc01e 100644 (file)
@@ -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 {
index 870b441f1123ae4a6df3cc6f79fcbf75a5402aca..ff94ed94d5986c12879dee01063d92baf81bef9a 100644 (file)
@@ -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;