]> git.unchartedbackwaters.co.uk Git - francis/winuae.git/commitdiff
68040 MMU MOVE16 access fault update.
authorToni Wilen <twilen@winuae.net>
Thu, 13 Mar 2014 17:11:27 +0000 (19:11 +0200)
committerToni Wilen <twilen@winuae.net>
Thu, 13 Mar 2014 17:11:27 +0000 (19:11 +0200)
cpummu.cpp
gencpu.cpp
include/cpummu.h
include/mmu_common.h
include/newcpu.h
newcpu.cpp

index 15bcf3d7b960d23dcd108d502b09c3e5dcb8a6dd..122e28baaaece9e0a129a356e78a92b66f6ac0b9 100644 (file)
@@ -57,6 +57,7 @@ int mmu_atc_ways;
 
 int mmu040_movem;
 uaecptr mmu040_movem_ea;
+uae_u32 mmu040_move16[4];
 
 static void mmu_dump_ttr(const TCHAR * label, uae_u32 ttr)
 {
@@ -276,6 +277,9 @@ void mmu_bus_error(uaecptr addr, int fc, bool write, int size, bool rmw, uae_u32
                }
 
                ssw |= fc & MMU_SSW_TM;                         /* TM = FC */
+               regs.wb3_status = write ? 0x80 | (ssw & 0x7f) : 0;
+               regs.wb2_status = 0;
+
                switch (size) {
                case sz_byte:
                        ssw |= MMU_SSW_SIZE_B;
@@ -287,13 +291,20 @@ void mmu_bus_error(uaecptr addr, int fc, bool write, int size, bool rmw, uae_u32
                        ssw |= MMU_SSW_SIZE_L;
                        break;
                case 16: // MOVE16
-                       ssw |= MMU_SSW_SIZE_L; // ??
+                       ssw |= MMU_SSW_SIZE_L; // ?? maybe MMU_SSW_SIZE_CL?
                        ssw |= MMU_SSW_TT0;
-                       write_log (_T("040 MMU MOVE16 FAULT!\n"));
+                       regs.mmu_effective_addr &= ~15;
+                       if (write) {
+                               // clear normal writeback if MOVE16 write
+                               regs.wb3_status &= ~0x80;
+                               // wb2 = cacheline size writeback
+                               regs.wb2_status = 0x80 | MMU_SSW_SIZE_CL | (ssw & 0x1f);
+                               regs.wb2_address = regs.mmu_effective_addr;
+                               write_log (_T("040 MMU MOVE16 WRITE FAULT!\n"));
+                       }
                        break;
                }
 
-               regs.wb3_status = write ? 0x80 | (ssw & 0x7f) : 0;
                if (!write)
                        ssw |= MMU_SSW_RW;
 
@@ -967,6 +978,39 @@ void REGPARAM2 dfc_put_byte(uaecptr addr, uae_u8 val)
        ismoves = false;
 }
 
+void mmu_get_move16(uaecptr addr, uae_u32 *v, bool data, int size)
+{
+       struct mmu_atc_line *cl;
+       addr &= ~15;
+       for (int i = 0; i < 4; i++) {
+               uaecptr addr2 = addr + i * 4;
+               //                                       addr,super,data
+               if ((!regs.mmu_enabled) || (mmu_match_ttr(addr2,regs.s != 0,data,false)!=TTR_NO_MATCH))
+                       v[i] = phys_get_long(addr2);
+               else if (likely(mmu_lookup(addr2, data, false, &cl)))
+                       v[i] = phys_get_long(mmu_get_real_address(addr2, cl));
+               else
+                       v[i] = mmu_get_long_slow(addr2, regs.s != 0, data, size, false, cl);
+       }
+}
+
+void mmu_put_move16(uaecptr addr, uae_u32 *val, bool data, int size)
+{
+       struct mmu_atc_line *cl;
+       addr &= ~15;
+       for (int i = 0; i < 4; i++) {
+               uaecptr addr2 = addr + i * 4;
+               //                                        addr,super,data
+               if ((!regs.mmu_enabled) || (mmu_match_ttr_write(addr2,regs.s != 0,data,val[i],size,false)==TTR_OK_MATCH))
+                       phys_put_long(addr2,val[i]);
+               else if (likely(mmu_lookup(addr2, data, true, &cl)))
+                       phys_put_long(mmu_get_real_address(addr2, cl), val[i]);
+               else
+                       mmu_put_long_slow(addr2, val[i], regs.s != 0, data, size, false, cl);
+       }
+}
+
+
 void REGPARAM2 mmu_op_real(uae_u32 opcode, uae_u16 extra)
 {
        bool super = (regs.dfc & 4) != 0;
index d4b0fdb9031901235a95146021a0dd9290de6997..84c261bf040347fc73c9eea97399fdb0171ebd42 100644 (file)
@@ -4976,12 +4976,15 @@ static void gen_opcode (unsigned long int opcode)
                                printf ("\tuae_u32 v[4];\n");
                                genamode (curi, curi->smode, "srcreg", curi->size, "mems", 0, 2, 0);
                                genamode (curi, curi->dmode, "dstreg", curi->size, "memd", 0, 2, 0);
-                               printf ("\tmemsa &= ~15;\n");
-                               printf ("\tmemda &= ~15;\n");
-                               if (using_mmu >= 68040) {
+                               if (using_mmu == 68040) {
+                                       printf ("\tget_move16_mmu (memsa, mmu040_move16);\n");
+                                       printf ("\tput_move16_mmu (memda, mmu040_move16);\n");
+                               } else if (using_mmu == 68060) {
                                        printf ("\tget_move16_mmu (memsa, v);\n");
                                        printf ("\tput_move16_mmu (memda, v);\n");
                                } else {
+                                       printf ("\tmemsa &= ~15;\n");
+                                       printf ("\tmemda &= ~15;\n");
                                        printf ("\tv[0] = %s (memsa);\n", srcl);
                                        printf ("\tv[1] = %s (memsa + 4);\n", srcl);
                                        printf ("\tv[2] = %s (memsa + 8);\n", srcl);
index ea1aa1b16707dbf46dff3fa65b591ffaf5debb5a..458b1972a880ce5a982b33516da834ac57848abe 100644 (file)
@@ -47,6 +47,7 @@ extern int mmu060_state;
 
 extern int mmu040_movem;
 extern uaecptr mmu040_movem_ea;
+extern uae_u32 mmu040_move16[4];
 
 extern bool mmu_pagesize_8k;
 extern uae_u16 mmu_opcode;
@@ -384,20 +385,8 @@ static ALWAYS_INLINE uaecptr mmu_get_real_address(uaecptr addr, struct mmu_atc_l
     return cl->phys | (addr & mmu_pagemask);
 }
 
-static ALWAYS_INLINE void mmu_get_move16(uaecptr addr, uae_u32 *v, bool data, int size)
-{
-       struct mmu_atc_line *cl;
-       for (int i = 0; i < 4; i++) {
-               uaecptr addr2 = addr + i * 4;
-               //                                       addr,super,data
-               if ((!regs.mmu_enabled) || (mmu_match_ttr(addr2,regs.s != 0,data,false)!=TTR_NO_MATCH))
-                       v[i] = phys_get_long(addr2);
-               else if (likely(mmu_lookup(addr2, data, false, &cl)))
-                       v[i] = phys_get_long(mmu_get_real_address(addr2, cl));
-               else
-                       v[i] = mmu_get_long_slow(addr2, regs.s != 0, data, size, false, cl);
-       }
-}
+extern void mmu_get_move16(uaecptr addr, uae_u32 *v, bool data, int size);
+extern void mmu_put_move16(uaecptr addr, uae_u32 *val, bool data, int size);
 
 static ALWAYS_INLINE uae_u32 mmu_get_long(uaecptr addr, bool data, int size, bool rmw)
 {
@@ -450,21 +439,6 @@ static ALWAYS_INLINE void mmu_put_long(uaecptr addr, uae_u32 val, bool data, int
                mmu_put_long_slow(addr, val, regs.s != 0, data, size, rmw, cl);
 }
 
-static ALWAYS_INLINE void mmu_put_move16(uaecptr addr, uae_u32 *val, bool data, int size)
-{
-       struct mmu_atc_line *cl;
-       for (int i = 0; i < 4; i++) {
-               uaecptr addr2 = addr + i * 4;
-               //                                        addr,super,data
-               if ((!regs.mmu_enabled) || (mmu_match_ttr_write(addr2,regs.s != 0,data,val[i],size,false)==TTR_OK_MATCH))
-                       phys_put_long(addr2,val[i]);
-               else if (likely(mmu_lookup(addr2, data, true, &cl)))
-                       phys_put_long(mmu_get_real_address(addr2, cl), val[i]);
-               else
-                       mmu_put_long_slow(addr2, val[i], regs.s != 0, data, size, false, cl);
-       }
-}
-
 static ALWAYS_INLINE void mmu_put_word(uaecptr addr, uae_u16 val, bool data, int size, bool rmw)
 {
        struct mmu_atc_line *cl;
index 63cd7ccb164dd5dddbdfef63e30e79510e15504f..50241798dfd0f14fa94cc11b7a3b066798bd888d 100644 (file)
@@ -83,6 +83,7 @@ typedef  int m68k_exception;
 #define MMU_SSW_SIZE_B 0x0020
 #define MMU_SSW_SIZE_W 0x0040
 #define MMU_SSW_SIZE_L 0x0000
+#define MMU_SSW_SIZE_CL        0x0060
 #define MMU_SSW_RW             0x0100
 #define MMU_SSW_LK             0x0200
 #define MMU_SSW_ATC            0x0400
index cf4c0568d98093618eab20e6591ad1c0d3bc45f1..2b7fdcd974bfbd5ae1ad3f254c8e5ac64f4b6ee3 100644 (file)
@@ -167,8 +167,8 @@ struct regstruct
 #ifdef FPUEMU
        fpdata fp[8];
        fpdata fp_result;
+       uae_u32 fp_result_status;
        uae_u32 fpcr, fpsr, fpiar;
-       uae_u32 fpsr_highbyte;
        uae_u32 fpu_state;
        uae_u32 fpu_exp_state;
        fpdata exp_src1, exp_src2;
@@ -183,8 +183,9 @@ struct regstruct
        uae_u32 mmu_fslw;
        uae_u32 mmu_fault_addr, mmu_effective_addr;
        uae_u16 mmu_ssw;
+       uae_u32 wb2_address;
        uae_u32 wb3_data;
-       uae_u16 wb3_status;
+       uae_u8 wb3_status, wb2_status;
        int mmu_enabled;
        int mmu_page_size;
 #endif
index 4831d8abaa9711bf4b14e3ee8f6419de03a9d69c..60bdae08c4e0b11ad6e005d501b719f25f06697c 100644 (file)
@@ -2062,24 +2062,37 @@ static void Exception_build_stack_frame (uae_u32 oldpc, uae_u32 currpc, uae_u32
             x_put_long (m68k_areg (regs, 7), oldpc);
             break;
         case 0x7: // access error stack frame (68040)
-            for (i = 0 ; i < 7 ; i++) {
+
+                       for (i = 3; i >= 0; i--) {
+                               // WB1D/PD0,PD1,PD2,PD3
                 m68k_areg (regs, 7) -= 4;
-                x_put_long (m68k_areg (regs, 7), 0);
-            }
+                x_put_long (m68k_areg (regs, 7), mmu040_move16[i]);
+                       }
+
             m68k_areg (regs, 7) -= 4;
-            x_put_long (m68k_areg (regs, 7), regs.wb3_data);
+            x_put_long (m68k_areg (regs, 7), 0); // WB1A
+                       m68k_areg (regs, 7) -= 4;
+            x_put_long (m68k_areg (regs, 7), 0); // WB2D
             m68k_areg (regs, 7) -= 4;
-            x_put_long (m68k_areg (regs, 7), regs.mmu_fault_addr);
+            x_put_long (m68k_areg (regs, 7), regs.wb2_address); // WB2A
+                       m68k_areg (regs, 7) -= 4;
+            x_put_long (m68k_areg (regs, 7), regs.wb3_data); // WB3D
             m68k_areg (regs, 7) -= 4;
-            x_put_long (m68k_areg (regs, 7), regs.mmu_fault_addr);
-            m68k_areg (regs, 7) -= 2;
+            x_put_long (m68k_areg (regs, 7), regs.mmu_fault_addr); // WB3A
+
+                       m68k_areg (regs, 7) -= 4;
+            x_put_long (m68k_areg (regs, 7), regs.mmu_fault_addr); // FA
+            
+                       m68k_areg (regs, 7) -= 2;
             x_put_word (m68k_areg (regs, 7), 0);
             m68k_areg (regs, 7) -= 2;
-            x_put_word (m68k_areg (regs, 7), 0);
+            x_put_word (m68k_areg (regs, 7), regs.wb2_status);
+            regs.wb2_status = 0;
             m68k_areg (regs, 7) -= 2;
             x_put_word (m68k_areg (regs, 7), regs.wb3_status);
             regs.wb3_status = 0;
-            m68k_areg (regs, 7) -= 2;
+
+                       m68k_areg (regs, 7) -= 2;
                        x_put_word (m68k_areg (regs, 7), ssw);
             m68k_areg (regs, 7) -= 4;
             x_put_long (m68k_areg (regs, 7), regs.mmu_effective_addr);