]> git.unchartedbackwaters.co.uk Git - francis/winuae.git/commitdiff
More 68040/060 no fpu updates.
authorToni Wilen <twilen@winuae.net>
Sat, 22 Jul 2017 19:39:02 +0000 (22:39 +0300)
committerToni Wilen <twilen@winuae.net>
Sat, 22 Jul 2017 19:39:02 +0000 (22:39 +0300)
fpp.cpp

diff --git a/fpp.cpp b/fpp.cpp
index 49af46e974bd5cf7d9417a25b47c32fdebc54576..f54f58e7fce5c5c66317130d115a29ad1a48524e 100644 (file)
--- a/fpp.cpp
+++ b/fpp.cpp
@@ -929,9 +929,14 @@ static void fpu_noinst (uae_u16 opcode, uaecptr pc)
        op_illg (opcode);
 }
 
+static bool if_no_fpu(void)
+{
+       return (regs.pcr & 2) || currprefs.fpu_model <= 0;
+}
+
 static bool fault_if_no_fpu (uae_u16 opcode, uae_u16 extra, uaecptr ea, uaecptr oldpc)
 {
-       if ((regs.pcr & 2) || currprefs.fpu_model <= 0) {
+       if (if_no_fpu()) {
 #if EXCEPTION_FPP
                write_log (_T("no FPU: %04X-%04X PC=%08X\n"), opcode, extra, oldpc);
 #endif
@@ -1217,6 +1222,8 @@ static int get_fp_value (uae_u32 opcode, uae_u16 extra, fpdata *src, uaecptr old
 
        switch (mode) {
                case 0:
+                       if ((size == 0 || size == 1 ||size == 4 || size == 6) && fault_if_no_fpu (opcode, extra, 0, oldpc))
+                               return -1;
                        switch (size)
                        {
                                case 6:
@@ -1256,6 +1263,9 @@ static int get_fp_value (uae_u32 opcode, uae_u16 extra, fpdata *src, uaecptr old
                        fpu_mmu_fixup = true;
                        m68k_areg (regs, reg) -= reg == 7 ? sz2[size] : sz1[size];
                        ad = m68k_areg (regs, reg);
+                       // 68060 no fpu -(an): EA points to -4, not -12 if extended precision
+                       if (currprefs.cpu_model == 68060 && if_no_fpu() && sz1[size] == 12)
+                               ad += 8;
                        break;
                case 5:
                        ad = m68k_areg (regs, reg) + (uae_s32) (uae_s16) x_cp_next_iword ();
@@ -1280,8 +1290,6 @@ static int get_fp_value (uae_u32 opcode, uae_u16 extra, fpdata *src, uaecptr old
                                        ad = x_cp_get_disp_ea_020 (m68k_getpc (), 0);
                                        break;
                                case 4: // #imm
-                                       if (fault_if_no_fpu (opcode, extra, 0, oldpc))
-                                               return -1;
                                        doext = 1;
                                        switch (size)
                                        {
@@ -1413,11 +1421,12 @@ static int put_fp_value (fpdata *value, uae_u32 opcode, uae_u16 extra, uaecptr o
        reg = opcode & 7;
        mode = (opcode >> 3) & 7;
        size = (extra >> 10) & 7;
-       ad = -1;
        switch (mode)
        {
                case 0:
 
+                       if ((size == 0 || size == 1 ||size == 4 || size == 6) && fault_if_no_fpu (opcode, extra, 0, oldpc))
+                               return -1;
                        switch (size)
                        {
                                case 6:
@@ -1458,22 +1467,23 @@ static int put_fp_value (fpdata *value, uae_u32 opcode, uae_u16 extra, uaecptr o
                        ad = m68k_areg (regs, reg);
                        break;
                case 3:
-                       if (currprefs.mmu_model) {
-                               mmufixup[0].reg = reg;
-                               mmufixup[0].value = m68k_areg (regs, reg);
-                               fpu_mmu_fixup = true;
-                       }
+                       // Also needed by fault_if_no_fpu 
+                       mmufixup[0].reg = reg;
+                       mmufixup[0].value = m68k_areg (regs, reg);
+                       fpu_mmu_fixup = true;
                        ad = m68k_areg (regs, reg);
                        m68k_areg (regs, reg) += reg == 7 ? sz2[size] : sz1[size];
                        break;
                case 4:
-                       if (currprefs.mmu_model) {
-                               mmufixup[0].reg = reg;
-                               mmufixup[0].value = m68k_areg (regs, reg);
-                               fpu_mmu_fixup = true;
-                       }
+                       // Also needed by fault_if_no_fpu 
+                       mmufixup[0].reg = reg;
+                       mmufixup[0].value = m68k_areg (regs, reg);
+                       fpu_mmu_fixup = true;
                        m68k_areg (regs, reg) -= reg == 7 ? sz2[size] : sz1[size];
                        ad = m68k_areg (regs, reg);
+                       // 68060 no fpu -(an): EA points to -4, not -12 if extended precision
+                       if (currprefs.cpu_model == 68060 && if_no_fpu() && sz1[size] == 12)
+                               ad += 8;
                        break;
                case 5:
                        ad = m68k_areg (regs, reg) + (uae_s32) (uae_s16) x_cp_next_iword ();
@@ -1505,7 +1515,7 @@ static int put_fp_value (fpdata *value, uae_u32 opcode, uae_u16 extra, uaecptr o
        *adp = ad;
 
        if (fault_if_no_fpu (opcode, extra, ad, oldpc))
-               return 1;
+               return -1;
 
        switch (size)
        {
@@ -2677,15 +2687,13 @@ static void fpuop_arithmetic2 (uae_u32 opcode, uae_u16 extra)
        switch ((extra >> 13) & 0x7)
        {
                case 3:
-                       if (fault_if_no_fpu (opcode, extra, 0, pc))
-                               return;
                        if (fp_exception_pending(true))
                                return;
 
                        regs.fpiar = pc;
                        fpsr_clear_status();
                        src = regs.fp[(extra >> 7) & 7];
-                       v = put_fp_value (&src, opcode, extra, pc, & ad);
+                       v = put_fp_value (&src, opcode, extra, pc, &ad);
                        if (v <= 0) {
                                if (v == 0)
                                        fpu_noinst (opcode, pc);
@@ -2735,8 +2743,6 @@ static void fpuop_arithmetic2 (uae_u32 opcode, uae_u16 extra)
                                                regs.fpiar = m68k_areg (regs, opcode & 7);
                                }
                        } else if ((opcode & 0x3f) == 0x3c) {
-                               if (fault_if_no_fpu (opcode, extra, 0, pc))
-                                       return;
                                if ((extra & 0x2000) == 0) {
                                        uae_u32 ext[3];
                                        // 68060 FMOVEM.L #imm,more than 1 control register: unimplemented EA
@@ -2753,12 +2759,18 @@ static void fpuop_arithmetic2 (uae_u32 opcode, uae_u16 extra)
                                                ext[1] = x_cp_next_ilong ();
                                        if (extra & 0x0400)
                                                ext[2] = x_cp_next_ilong ();
+                                       if (fault_if_no_fpu (opcode, extra, 0, pc))
+                                               return;
                                        if (extra & 0x1000)
                                                fpp_set_fpcr(ext[0]);
                                        if (extra & 0x0800)
                                                fpp_set_fpsr(ext[1]);
                                        if (extra & 0x0400)
                                                regs.fpiar = ext[2];
+                               } else {
+                                       // immediate as destination
+                                       fpu_noinst (opcode, pc);
+                                       return;
                                }
                        } else if (extra & 0x2000) {
                                /* FMOVEM FPP->memory */