/* 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 (®s, 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");
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 (®s, 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", "", "");
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);
}
}
+/* 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)