]> git.unchartedbackwaters.co.uk Git - francis/winuae.git/commitdiff
Accurate DIV overflow undocumented flags.
authorToni Wilen <twilen@winuae.net>
Mon, 4 Dec 2017 13:52:21 +0000 (15:52 +0200)
committerToni Wilen <twilen@winuae.net>
Mon, 4 Dec 2017 13:52:21 +0000 (15:52 +0200)
gencpu.cpp
include/newcpu.h
newcpu_common.cpp

index 4d869e218a6c3ec886e68fcf5c8808c70c8bf328..5b2673620e3c0a9a4f8b39ae508ef4f2766d105d 100644 (file)
@@ -4371,13 +4371,7 @@ bccl_not68020:
                /* The N flag appears to be set each time there is an overflow.
                 * Weird. but 68020 only sets N when dst is negative.. */
                printf ("\t\tif (newv > 0xffff) {\n");
-               printf ("\t\t\tSET_VFLG (1);\n");
-#ifdef UNDEF68020
-               if (cpu_level >= 2)
-                       printf ("\t\t\tif (currprefs.cpu_level == 0 || dst < 0) SET_NFLG (&regs, 1);\n");
-               else /* ??? some 68000 revisions may not set NFLG when overflow happens.. */
-#endif
-                       printf ("\t\t\tSET_NFLG (1);\n");
+               printf ("\t\t\tsetdivuoverflowflags((uae_u32)dst, (uae_u16)src);\n");
                printf ("\t\t} else {\n");
                printf ("\t\t"); genflags (flag_logical, sz_word, "newv", "", "");
                printf ("\t\t\tnewv = (newv & 0xffff) | ((uae_u32)rem << 16);\n");
@@ -4412,19 +4406,12 @@ bccl_not68020:
                addcycles000_nonces("\t\t", "(getDivs68kCycles((uae_s32)dst, (uae_s16)src)) - 4");
                fill_prefetch_next ();
                printf ("\tif (dst == 0x80000000 && src == -1) {\n");
-               printf ("\t\tSET_VFLG (1);\n");
-               printf ("\t\tSET_NFLG (1);\n");
+               printf ("\t\tsetdivsoverflowflags((uae_s32)dst, (uae_s16)src);\n");
                printf ("\t} else {\n");
                printf ("\t\tuae_s32 newv = (uae_s32)dst / (uae_s32)(uae_s16)src;\n");
                printf ("\t\tuae_u16 rem = (uae_s32)dst %% (uae_s32)(uae_s16)src;\n");
                printf ("\t\tif ((newv & 0xffff8000) != 0 && (newv & 0xffff8000) != 0xffff8000) {\n");
-               printf ("\t\t\tSET_VFLG (1);\n");
-#ifdef UNDEF68020
-               if (cpu_level > 0)
-                       printf ("\t\t\tif (currprefs.cpu_level == 0) SET_NFLG (&regs, 1);\n");
-               else
-#endif
-                       printf ("\t\t\tSET_NFLG (1);\n");
+               printf ("\t\t\tsetdivsoverflowflags((uae_s32)dst, (uae_s16)src);\n");
                printf ("\t\t} else {\n");
                printf ("\t\t\tif (((uae_s16)rem < 0) != ((uae_s32)dst < 0)) rem = -rem;\n");
                genflags (flag_logical, sz_word, "newv", "", "");
index e37901555fadde658b013a283e1eeb94839d70b9..700e3d9ccb19a0e98e0ce3dfd9217ed241175dc7 100644 (file)
@@ -633,7 +633,9 @@ extern void m68k_dumpstate (uaecptr, uaecptr *);
 extern void m68k_dumpcache (bool);
 extern int getDivu68kCycles (uae_u32 dividend, uae_u16 divisor);
 extern int getDivs68kCycles (uae_s32 dividend, uae_s16 divisor);
-extern void divbyzero_special (bool issigned, uae_s32 dst);
+extern void divbyzero_special(bool issigned, uae_s32 dst);
+extern void setdivuoverflowflags(uae_u32 dividend, uae_u16 divisor);
+extern void setdivsoverflowflags(uae_s32 dividend, uae_u16 divisor);
 extern void protect_roms (bool);
 extern void unprotect_maprom (void);
 extern bool is_hardreset(void);
index 1f82073e5259a20f34c5764c752e7fcb9deb2fdc..919c98dda9cf7ff018fea39edc2f5ac40f69b43c 100644 (file)
@@ -771,6 +771,64 @@ void divbyzero_special (bool issigned, uae_s32 dst)
        }
 }
 
+/* DIVU overflow
+ *
+ * 68000: V=1 N=1
+ * 68020: V=1 N=X
+ * 68040: V=1
+ * 68060: V=1
+ *
+ * X) N is set if original 32-bit destination value is negative.
+ *
+ */
+
+void setdivuoverflowflags(uae_u32 dividend, uae_u16 divisor)
+{
+       if (currprefs.cpu_model >= 68040) {
+               SET_VFLG(1);
+       } else if (currprefs.cpu_model >= 68020) {
+               SET_VFLG(1);
+               if ((uae_s32)dividend < 0)
+                       SET_NFLG(1);
+       } else {
+               SET_VFLG(1);
+               SET_NFLG(1);
+       }
+}
+
+/*
+ * DIVS overflow
+ *
+ * 68000: V = 1 N = 1
+ * 68020: V = 1 ZN = X
+ * 68040: V = 1
+ * 68060: V = 1
+ *
+ * X) if absolute overflow(Check getDivs68kCycles for details) : Z = 0, N = 0
+ * if not absolute overflow : N is set if internal result BYTE is negative, Z is set if it is zero!
+ *
+ */
+
+void setdivsoverflowflags(uae_s32 dividend, uae_u16 divisor)
+{
+       if (currprefs.cpu_model >= 68040) {
+               SET_VFLG(1);
+       } else if (currprefs.cpu_model >= 68020) {
+               SET_VFLG(1);
+               // absolute overflow?
+               if (((uae_u32)abs(dividend) >> 16) >= (uae_u16)abs(divisor))
+                       return;
+               uae_u32 aquot = (uae_u32)abs(dividend) / (uae_u16)abs(divisor);
+               if ((uae_s8)aquot == 0)
+                       SET_ZFLG(1);
+               if ((uae_s8)aquot < 0)
+                       SET_NFLG(1);
+       } else {
+               SET_VFLG(1);
+               SET_NFLG(1);
+       }
+}
+
 #ifndef CPUEMU_68000_ONLY
 
 #if !defined (uae_s64)