From 48ec7fc0e059e069ef17e0f69291ea52503c4946 Mon Sep 17 00:00:00 2001 From: Toni Wilen Date: Mon, 2 Sep 2019 20:04:15 +0300 Subject: [PATCH] CHK2/CMP2 undefined N and V flags emulated. --- gencpu.cpp | 18 ++++---- include/newcpu.h | 2 +- newcpu_common.cpp | 105 +++++++++++++++++++++++++++++++++++++++------- 3 files changed, 101 insertions(+), 24 deletions(-) diff --git a/gencpu.cpp b/gencpu.cpp index 4b68b632..d1770636 100644 --- a/gencpu.cpp +++ b/gencpu.cpp @@ -5017,7 +5017,7 @@ bccl_not68020: genamode (curi, curi->smode, "srcreg", curi->size, "extra", 1, 0, 0); genamode (curi, curi->dmode, "dstreg", curi->size, "dst", 2, 0, 0); fill_prefetch_0 (); - printf ("\t{uae_u32 upper,lower,reg = regs.regs[(extra >> 12) & 15];\n"); + printf ("\t{uae_s32 upper,lower,reg = regs.regs[(extra >> 12) & 15];\n"); switch (curi->size) { case sz_byte: printf ("\tlower = (uae_s32)(uae_s8)%s (dsta); upper = (uae_s32)(uae_s8)%s (dsta + 1);\n", srcb, srcb); @@ -5033,12 +5033,16 @@ bccl_not68020: default: term (); } - printf("\tsetchk2undefinedflags(lower, upper, reg, (extra & 0x8000) ? %d : 2);\n", curi->size); - printf("\tupper -= lower;\n"); - printf("\treg -= lower;\n"); - printf("\tSET_ZFLG (upper == reg || 0 == reg);\n"); - printf("\tSET_CFLG_ALWAYS (reg > upper);\n"); - printf("\tif ((extra & 0x800) && GET_CFLG ()) { Exception_cpu(6); goto %s; }\n}\n", endlabelstr); + printf("\tSET_CFLG(0);\n"); + printf("\tSET_ZFLG(0);\n"); + printf("\tsetchk2undefinedflags(lower, upper, reg, (extra & 0x8000) ? 2 : %d);\n", curi->size); + printf("\tif(upper == reg || lower == reg) {\n"); + printf("\t\tSET_ZFLG(1);\n"); + printf("\t}else{\n"); + printf("\t\tif (lower <= upper && (reg < lower || reg > upper)) SET_CFLG(1);\n"); + printf("\t\tif (lower > upper && reg > upper && reg < lower) SET_CFLG(1);\n"); + printf("\t}\n"); + printf("\tif ((extra & 0x800) && GET_CFLG()) { Exception_cpu(6); goto %s; }\n}\n", endlabelstr); need_endlabel = 1; break; diff --git a/include/newcpu.h b/include/newcpu.h index 83d823c5..b672e3c1 100644 --- a/include/newcpu.h +++ b/include/newcpu.h @@ -682,7 +682,7 @@ extern void divbyzero_special(bool issigned, uae_s32 dst); extern void setdivuflags(bool overflow, uae_u32 dividend, uae_u16 divisor); extern void setdivsflags(bool overflow, uae_s32 dividend, uae_s16 divisor); extern void setchkundefinedflags(uae_s32 src, uae_s32 dst, int size); -extern void setchk2undefinedflags(uae_u32 lower, uae_u32 upper, uae_u32 val, int size); +extern void setchk2undefinedflags(uae_s32 lower, uae_s32 upper, uae_s32 val, int size); extern void protect_roms (bool); extern void unprotect_maprom (void); extern bool is_hardreset(void); diff --git a/newcpu_common.cpp b/newcpu_common.cpp index 02753998..7561d5f1 100644 --- a/newcpu_common.cpp +++ b/newcpu_common.cpp @@ -924,25 +924,98 @@ void setchkundefinedflags(uae_s32 src, uae_s32 dst, int size) } } -void setchk2undefinedflags(uae_u32 lower, uae_u32 upper, uae_u32 val, int size) -{ - uae_u32 nmask; - if (size == sz_byte) - nmask = 0x80; - else if (size == sz_word) - nmask = 0x8000; - else - nmask = 0x80000000; +/* + * CHK2/CMP2 undefined flags + * + * 68020-68030: See below.. + * 68040: N: val<0 V=0 + * + */ +// This is the complex one. +// Someone else can attempt to simplify this.. +void setchk2undefinedflags(uae_s32 lower, uae_s32 upper, uae_s32 val, int size) +{ SET_NFLG(0); - if ((upper & nmask) && val > upper) { - SET_NFLG(1); - } else if (!(upper & nmask) && val > upper && val < nmask) { - SET_NFLG(1); - } else if (val < lower) { - SET_NFLG(1); - } SET_VFLG(0); + + if (currprefs.cpu_model >= 68040) { + SET_NFLG(val < 0); + return; + } + + if (val == lower || val == upper) + return; + + if (lower < 0 && upper >= 0) { + if (val < lower) { + SET_NFLG(1); + } + if (val >= 0 && val < upper) { + SET_NFLG(1); + } + if (val >= 0 && lower - val >= 0) { + SET_VFLG(1); + SET_NFLG(0); + if (val > upper) { + SET_NFLG(1); + } + } + } else if (lower >= 0 && upper < 0) { + if (val >= 0) { + SET_NFLG(1); + } + if (val > upper) { + SET_NFLG(1); + } + if (val > lower && upper - val >= 0) { + SET_VFLG(1); + SET_NFLG(0); + } + } else if (lower >= 0 && upper >= 0 && lower > upper) { + if (val > upper && val < lower) { + SET_NFLG(1); + } + if (val < 0 && lower - val < 0) { + SET_VFLG(1); + } + if (val < 0 && lower - val >= 0) { + SET_NFLG(1); + } + } else if (lower >= 0 && upper >= 0 && lower <= upper) { + if (val >= 0 && val < lower) { + SET_NFLG(1); + } + if (val > upper) { + SET_NFLG(1); + } + if (val < 0 && upper - val < 0) { + SET_VFLG(1); + SET_NFLG(1); + } + } else if (lower < 0 && upper < 0 && lower > upper) { + if (val >= 0) { + SET_NFLG(1); + } + if (val > upper && val < lower) { + SET_NFLG(1); + } + if (val >= 0 && val - lower < 0) { + SET_NFLG(0); + SET_VFLG(1); + } + } else if (lower < 0 && upper < 0 && lower <= upper) { + if (val < lower) { + SET_NFLG(1); + } + if (val < 0 && val > upper) { + SET_NFLG(1); + } + if (val >= 0 && val - lower < 0) { + SET_NFLG(1); + SET_VFLG(1); + } + } } #ifndef CPUEMU_68000_ONLY -- 2.47.3