]> git.unchartedbackwaters.co.uk Git - francis/winuae.git/commitdiff
68030 MMU: FC 11xxx field is invalid and generates f-line exception. Add invalid...
authorToni Wilen <twilen@winuae.net>
Sun, 10 Mar 2019 08:28:36 +0000 (10:28 +0200)
committerToni Wilen <twilen@winuae.net>
Sun, 10 Mar 2019 08:28:36 +0000 (10:28 +0200)
cpummu30.cpp
newcpu.cpp

index 2317dc9a0faf67ebd2bed13d43a4246b9bd414f9..3eef9a26a589ca305611b5448103ea51e81f7946 100644 (file)
@@ -290,21 +290,24 @@ void mmu030_flush_atc_all(void) {
 }
 
 /* -- Helper function for MMU instructions -- */
-static uae_u32 mmu_op30_helper_get_fc(uae_u16 next) {
+static bool mmu_op30_helper_get_fc(uae_u16 next, uae_u32 *fc) {
        switch (next & 0x0018) {
        case 0x0010:
-       return (next & 0x7);
+       *fc = next & 0x7;
+       return true;
        case 0x0008:
-       return (m68k_dreg(regs, next & 0x7) & 0x7);
+       *fc = m68k_dreg(regs, next & 0x7) & 0x7;
+       return true;
        case 0x0000:
        if (next & 1) {
-               return (regs.dfc);
+               *fc = regs.dfc;
        } else {
-               return (regs.sfc);
+               *fc = regs.sfc;
        }
+       return true;
        default:
        write_log(_T("MMU_OP30 ERROR: bad fc source! (%04X)\n"), next & 0x0018);
-       return 0;
+       return false;
        }
 }
 
@@ -452,13 +455,15 @@ bool mmu_op30_ptest (uaecptr pc, uae_u32 opcode, uae_u16 next, uaecptr extra)
     int rw = (next >> 9) & 1;
     int a = (next >> 8) & 1;
     int areg = (next&0xE0)>>5;
-    uae_u32 fc = mmu_op30_helper_get_fc(next);
-    bool write = rw ? false : true;
+       uae_u32 fc;
+       bool write = rw ? false : true;
     uae_u32 ret = 0;
 
        if (mmu_op30_invea(opcode))
                return true;
-    if (!level && a) {
+       if (!mmu_op30_helper_get_fc(next, &fc))
+               return true;
+       if (!level && a) {
         write_log(_T("PTEST: Bad instruction causing F-line unimplemented instruction exception!\n"));
         return true;
     }
@@ -497,13 +502,15 @@ static bool mmu_op30_pload (uaecptr pc, uae_u32 opcode, uae_u16 next, uaecptr ex
 {
     int rw = (next >> 9) & 1;
        int unused = (next & (0x100 | 0x80 | 0x40 | 0x20));
-       uae_u32 fc = mmu_op30_helper_get_fc(next);
+       uae_u32 fc;
     bool write = rw ? false : true;
 
        if (mmu_op30_invea(opcode))
                return true;
        if (unused)
                return true;
+       if (!mmu_op30_helper_get_fc(next, &fc))
+               return true;
 
 #if 0
     write_log (_T("PLOAD%c: Create ATC entry for %08X, FC = %i\n"), write?'W':'R', extra, fc);
@@ -517,8 +524,8 @@ static bool mmu_op30_pload (uaecptr pc, uae_u32 opcode, uae_u16 next, uaecptr ex
 bool mmu_op30_pflush (uaecptr pc, uae_u32 opcode, uae_u16 next, uaecptr extra)
 {
        uae_u16 mode = (next >> 8) & 31;
-    uae_u32 fc_mask = (uae_u32)(next & 0x00E0) >> 5;
-    uae_u32 fc_base = mmu_op30_helper_get_fc(next);
+    uae_u32 fc_mask = (next & 0x00E0) >> 5;
+       uae_u32 fc_base;
        uae_u32 fc_bits = next & 0x7f;
     
 #if 0
@@ -550,12 +557,16 @@ bool mmu_op30_pflush (uaecptr pc, uae_u32 opcode, uae_u16 next, uaecptr extra)
             mmu030_flush_atc_all();
             break;
         case 0x10:
+                       if (!mmu_op30_helper_get_fc(next, &fc_base))
+                               return true;
             mmu030_flush_atc_fc(fc_base, fc_mask);
             break;
         case 0x18:
                        if (mmu_op30_invea(opcode))
                                return true;
-            mmu030_flush_atc_page_fc(extra, fc_base, fc_mask);
+                       if (!mmu_op30_helper_get_fc(next, &fc_base))
+                               return true;
+                       mmu030_flush_atc_page_fc(extra, fc_base, fc_mask);
             break;
         default:
             write_log(_T("PFLUSH %04x-%04x ERROR: bad mode! (%i)\n"), opcode, next, mode);
index 744be7ad1331973d82d8402f353d4fd3055abcc1..8b781e1ea6ac0fabe288ad5277742661fe929547 100644 (file)
@@ -7659,25 +7659,24 @@ static void resolve_if_jmp(TCHAR *s, uae_u32 addr)
        }
 }
 
-static void mmu_op30_helper_get_fc(uae_u16 extra, TCHAR *out)
+static bool mmu_op30_helper_get_fc(uae_u16 extra, TCHAR *out)
 {
        switch (extra & 0x0018) {
        case 0x0010:
                _stprintf(out, _T("#%d"), extra & 7);
-               return;
+               return true;
        case 0x0008:
                _stprintf(out, _T("D%d"), extra & 7);
-               return;
+               return true;
        case 0x0000:
                if (extra & 1) {
                        _tcscpy(out, _T("DFC"));
                } else {
                        _tcscpy(out, _T("SFC"));
                }
-               return;
+               return true;
        default:
-               _tcscpy(out, _T("??"));
-               return;
+               return false;
        }
 }
 
@@ -7685,7 +7684,9 @@ static uaecptr disasm_mmu030(uaecptr pc, uae_u16 opcode, uae_u16 extra, struct i
 {
        int type = extra >> 13;
 
+       _tcscpy(instrname, _T("F-LINE (MMU 68030)"));
        pc += 2;
+
        switch (type)
        {
        case 0:
@@ -7699,15 +7700,12 @@ static uaecptr disasm_mmu030(uaecptr pc, uae_u16 opcode, uae_u16 extra, struct i
                int unused = (extra & 0xff);
                TCHAR *r = NULL;
 
-               _tcscpy(instrname, _T("PMOVE"));
-               if (fd)
-                       _tcscat(instrname, _T("FD"));
-               _tcscat(instrname, _T(" "));
-
-               if (!rw) {
-                       pc = ShowEA(NULL, pc, opcode, dp->sreg, dp->smode, dp->size, instrname, seaddr2, safemode);
-                       _tcscat(instrname, _T(","));
-               }
+               if (mmu_op30_invea(opcode))
+                       break;
+               if (unused)
+                       break;
+               if (rw && fd)
+                       break;
                switch (preg)
                {
                case 0x10:
@@ -7728,9 +7726,18 @@ static uaecptr disasm_mmu030(uaecptr pc, uae_u16 opcode, uae_u16 extra, struct i
                case 0x03:
                        r = _T("TT1");
                        break;
-               default:
-                       r = _T("??");
+               }
+               if (!r)
                        break;
+
+               _tcscpy(instrname, _T("PMOVE"));
+               if (fd)
+                       _tcscat(instrname, _T("FD"));
+               _tcscat(instrname, _T(" "));
+
+               if (!rw) {
+                       pc = ShowEA(NULL, pc, opcode, dp->sreg, dp->smode, dp->size, instrname, seaddr2, safemode);
+                       _tcscat(instrname, _T(","));
                }
                _tcscat(instrname, r);
                if (rw) {
@@ -7743,30 +7750,40 @@ static uaecptr disasm_mmu030(uaecptr pc, uae_u16 opcode, uae_u16 extra, struct i
        {
                // PLOAD/PFLUSH
                uae_u16 mode = (extra >> 8) & 31;
+               int unused = (extra & (0x100 | 0x80 | 0x40 | 0x20));
                uae_u16 fc_mask = (extra & 0x00E0) >> 5;
                uae_u16 fc_bits = extra & 0x7f;
                TCHAR fc[10];
 
-               mmu_op30_helper_get_fc(extra, fc);
+               if (unused)
+                       break;
+
                switch (mode) {
                case 0x00: // PLOAD W
                case 0x02: // PLOAD R
+                       if (mmu_op30_invea(opcode))
+                               break;
                        _stprintf(instrname, _T("PLOAD%c %s,"), mode == 0 ? 'W' : 'R', fc);
                        pc = ShowEA(NULL, pc, opcode, dp->sreg, dp->smode, dp->size, instrname, seaddr2, safemode);
                        break;
                case 0x04: // PFLUSHA
+                       if (fc_bits)
+                               break;
                        _tcscpy(instrname, _T("PFLUSHA"));
                        break;
                case 0x10: // FC
-               case 0x18: // FC + EA
+                       if (!mmu_op30_helper_get_fc(extra, fc))
+                               break;
                        _stprintf(instrname, _T("PFLUSH %s,%d"), fc, fc_mask);
-                       if (mode == 0x18) {
-                               _tcscat(instrname, _T(","));
-                               pc = ShowEA(NULL, pc, opcode, dp->sreg, dp->smode, dp->size, instrname, seaddr2, safemode);
-                       }
                        break;
-               default:
-                       _tcscpy(instrname, _T("PFLUSH??"));
+               case 0x18: // FC + EA
+                       if (mmu_op30_invea(opcode))
+                               break;
+                       if (!mmu_op30_helper_get_fc(extra, fc))
+                               break;
+                       _stprintf(instrname, _T("PFLUSH %s,%d"), fc, fc_mask);
+                       _tcscat(instrname, _T(","));
+                       pc = ShowEA(NULL, pc, opcode, dp->sreg, dp->smode, dp->size, instrname, seaddr2, safemode);
                        break;
                }
                break;
@@ -7780,7 +7797,12 @@ static uaecptr disasm_mmu030(uaecptr pc, uae_u16 opcode, uae_u16 extra, struct i
                int areg = (extra & 0xE0) >> 5;
                TCHAR fc[10];
 
-               mmu_op30_helper_get_fc(extra, fc);
+               if (mmu_op30_invea(opcode))
+                       break;
+               if (!mmu_op30_helper_get_fc(extra, fc))
+                       break;
+               if (!level && a)
+                       break;
                _stprintf(instrname, _T("PTEST%c %s,"), rw ? 'R' : 'W', fc);
                pc = ShowEA(NULL, pc, opcode, dp->sreg, dp->smode, dp->size, instrname, seaddr2, safemode);
                _stprintf(instrname + _tcslen(instrname), _T(",#%d"), level);
@@ -7788,9 +7810,6 @@ static uaecptr disasm_mmu030(uaecptr pc, uae_u16 opcode, uae_u16 extra, struct i
                        _stprintf(instrname + _tcslen(instrname), _T(",A%d"), areg);
                break;
        }
-       default:
-               _tcscpy(instrname, _T("F-LINE"));
-               break;
        }
        return pc;
 }