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);
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;
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);
}
}
-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