about summary refs log tree commit diff stats
path: root/src
diff options
context:
space:
mode:
authorptitSeb <sebastien.chev@gmail.com>2025-02-21 11:40:08 +0100
committerptitSeb <sebastien.chev@gmail.com>2025-02-21 11:40:15 +0100
commite868c8923386b5f184458e84df4c1352b96a3221 (patch)
treeb9917b78dbfdd707df74796685c76892b2417bc7 /src
parentc517d7196d270c164b642e3ec9f043b5e66c259d (diff)
downloadbox64-e868c8923386b5f184458e84df4c1352b96a3221.tar.gz
box64-e868c8923386b5f184458e84df4c1352b96a3221.zip
[INTERP] Work on UD flags
Diffstat (limited to 'src')
-rw-r--r--src/emu/x64primop.c294
-rw-r--r--src/emu/x64primop.h11
-rw-r--r--src/emu/x64run0f.c36
-rw-r--r--src/emu/x64run_private.c282
4 files changed, 308 insertions, 315 deletions
diff --git a/src/emu/x64primop.c b/src/emu/x64primop.c
index 8a17da5a..b201900f 100644
--- a/src/emu/x64primop.c
+++ b/src/emu/x64primop.c
@@ -491,7 +491,6 @@ uint8_t rcl8(x64emu_t *emu, uint8_t d, uint8_t s)
        3) B_(n-1) <- cf
        4) B_(n-2) .. B_0 <-  b_7 .. b_(8-(n-1))
 	 */
-	res = d;
 	if ((cnt = s % 9) != 0) {
         /* extract the new CARRY FLAG. */
         /* CF <-  b_(8-n)             */
@@ -525,8 +524,11 @@ uint8_t rcl8(x64emu_t *emu, uint8_t d, uint8_t s)
 		   CONDITIONAL_SET_FLAG((cf ^ (res >> 7)) & 0x1, F_OF);
 	   else
 		   CONDITIONAL_SET_FLAG((XOR2(d >> 6)), F_OF);
-    } else if(s && BOX64ENV(cputype))
-		CONDITIONAL_SET_FLAG((ACCESS_FLAG(F_CF) ^ (res >> 7)) & 0x1, F_OF);
+    } else if(s) {
+		res = d;
+		if(BOX64ENV(cputype))
+			CONDITIONAL_SET_FLAG((ACCESS_FLAG(F_CF) ^ (res >> 7)) & 0x1, F_OF);
+	}
 	return (uint8_t)res;
 }
 
@@ -536,7 +538,6 @@ uint16_t rcl16(x64emu_t *emu, uint16_t d, uint8_t s)
 	CHECK_FLAGS(emu);
 	s = s&0x1f;
 
-	res = d;
 	if ((cnt = s % 17) != 0) {
 		cf = (d >> (16 - cnt)) & 0x1;
 		res = (d << cnt) & 0xffff;
@@ -550,8 +551,11 @@ uint16_t rcl16(x64emu_t *emu, uint16_t d, uint8_t s)
 			CONDITIONAL_SET_FLAG((cf ^ (res >> 15)) & 0x1, F_OF);
 		else
 			CONDITIONAL_SET_FLAG((XOR2(d >> 14)), F_OF);
-	} else if(s && BOX64ENV(cputype))
-		CONDITIONAL_SET_FLAG((ACCESS_FLAG(F_CF) ^ (res >> 15)) & 0x1, F_OF);
+	} else if(s) {
+		res = d;
+		if(BOX64ENV(cputype))
+			CONDITIONAL_SET_FLAG((ACCESS_FLAG(F_CF) ^ (res >> 15)) & 0x1, F_OF);
+	}
 	return (uint16_t)res;
 }
 
@@ -792,18 +796,16 @@ uint8_t rol8(x64emu_t *emu, uint8_t d, uint8_t s)
 
 	s = s&0x1f;
 	if(!s) return d;
+	/* OF flag is set if s == 1; OF = CF _XOR_ MSB of result */
+	
+	if(!BOX64ENV(cputype)) CONDITIONAL_SET_FLAG(XOR2(d>>6), F_OF);
 
 	if((cnt = s % 8) != 0) {
 	d = (d << cnt) + ((d >> (8 - cnt)) & ((1 << cnt) - 1));
 	}
 	CHECK_FLAGS(emu);
 
-	/* OF flag is set if s == 1; OF = CF _XOR_ MSB of result */
-	if(s == 1) {
-	CONDITIONAL_SET_FLAG((d + (d >> 7)) & 1, F_OF);
-	} else if(BOX64ENV(dynarec_test)) {
-		CLEAR_FLAG(F_OF);
-	}
+	if(BOX64ENV(cputype)) CONDITIONAL_SET_FLAG((d + (d >> 7)) & 1, F_OF);
 
 	/* set new CF; note that it is the LSB of the result */
 	CONDITIONAL_SET_FLAG(d & 0x1, F_CF);
@@ -818,19 +820,14 @@ uint16_t rol16(x64emu_t *emu, uint16_t d, uint8_t s)
 	s = s&0x1f;
 	if(!s) return d;
 
+	if(!BOX64ENV(cputype)) CONDITIONAL_SET_FLAG(XOR2(d>>14), F_OF);
 	if((cnt = s % 16) != 0) {
 	d = (d << cnt) + ((d >> (16 - cnt)) & ((1 << cnt) - 1));
 	}
 	CHECK_FLAGS(emu);
 
-	/* OF flag is set if s == 1; OF = CF _XOR_ MSB of result */
-	if(s == 1) {
-	CONDITIONAL_SET_FLAG((d + (d >> 15)) & 1, F_OF);
-	} else if(BOX64ENV(dynarec_test)) {
-		CLEAR_FLAG(F_OF);
-	}
+	if(BOX64ENV(cputype)) CONDITIONAL_SET_FLAG((d + (d >> 15)) & 1, F_OF);
 
-	/* set new CF; note that it is the LSB of the result */
 	CONDITIONAL_SET_FLAG(d & 0x1, F_CF);
 
 	return d;
@@ -843,19 +840,14 @@ uint32_t rol32(x64emu_t *emu, uint32_t d, uint8_t s)
 	s = s&0x1f;
 	if(!s) return d;
 
+	if(!BOX64ENV(cputype)) CONDITIONAL_SET_FLAG(XOR2(d>>30), F_OF);
 	if((cnt = s % 32) != 0) {
 	d = (d << cnt) + ((d >> (32 - cnt)) & ((1 << cnt) - 1));
 	}
 	CHECK_FLAGS(emu);
 
-	/* OF flag is set if s == 1; OF = CF _XOR_ MSB of result */
-	if(s == 1) {
-	CONDITIONAL_SET_FLAG((d + (d >> 31)) & 1, F_OF);
-	} else if(BOX64ENV(dynarec_test)) {
-		CLEAR_FLAG(F_OF);
-	}
+	if(BOX64ENV(cputype)) CONDITIONAL_SET_FLAG((d + (d >> 31)) & 1, F_OF);
 
-	/* set new CF; note that it is the LSB of the result */
 	CONDITIONAL_SET_FLAG(d & 0x1, F_CF);
 
 	return d;
@@ -868,19 +860,14 @@ uint64_t rol64(x64emu_t *emu, uint64_t d, uint8_t s)
 	s = s&0x3f;
 	if(!s) return d;
 
+	if(!BOX64ENV(cputype)) CONDITIONAL_SET_FLAG(XOR2(d>>62), F_OF);
 	if((cnt = s % 64) != 0) {
 	d = (d << cnt) + ((d >> (64 - cnt)) & ((1L << cnt) - 1));
 	}
 	CHECK_FLAGS(emu);
 
-	/* OF flag is set if s == 1; OF = CF _XOR_ MSB of result */
-	if(s == 1) {
-	CONDITIONAL_SET_FLAG((d + (d >> 63)) & 1, F_OF);
-	} else if(BOX64ENV(dynarec_test)) {
-		CLEAR_FLAG(F_OF);
-	}
+	if(BOX64ENV(cputype)) CONDITIONAL_SET_FLAG((d + (d >> 63)) & 1, F_OF);
 
-	/* set new CF; note that it is the LSB of the result */
 	CONDITIONAL_SET_FLAG(d & 0x1, F_CF);
 
 	return d;
@@ -897,17 +884,14 @@ uint8_t ror8(x64emu_t *emu, uint8_t d, uint8_t s)
 	s = s&0x1f;
 	if(!s) return d;
 
+	if(!BOX64ENV(cputype)) CONDITIONAL_SET_FLAG(((d >> 7)^d)&1, F_OF);
+
 	if((cnt = s % 8) != 0) {
-	d = (d << (8 - cnt)) + ((d >> (cnt)) & ((1 << (8 - cnt)) - 1));
+		d = (d << (8 - cnt)) + ((d >> (cnt)) & ((1 << (8 - cnt)) - 1));
 	}
 	CHECK_FLAGS(emu);
 
-	/* OF flag is set if s == 1; OF = MSB _XOR_ (M-1)SB of result */
-	if(s == 1) {
-	CONDITIONAL_SET_FLAG(XOR2(d >> 6), F_OF);
-	} else if(BOX64ENV(dynarec_test)) {
-		CLEAR_FLAG(F_OF);
-	}
+	if(BOX64ENV(cputype)) CONDITIONAL_SET_FLAG(XOR2(d >> 6), F_OF);
 
 	/* set new CF; note that it is the MSB of the result */
 	CONDITIONAL_SET_FLAG(d & (1 << 7), F_CF);
@@ -922,17 +906,14 @@ uint16_t ror16(x64emu_t *emu, uint16_t d, uint8_t s)
 	s = s&0x1f;
 	if(!s) return d;
 
+	if(!BOX64ENV(cputype)) CONDITIONAL_SET_FLAG(((d >> 15)^d)&1, F_OF);
+
 	if((cnt = s % 16) != 0) {
-	d = (d << (16 - cnt)) + ((d >> (cnt)) & ((1 << (16 - cnt)) - 1));
+		d = (d << (16 - cnt)) + ((d >> (cnt)) & ((1 << (16 - cnt)) - 1));
 	}
 	CHECK_FLAGS(emu);
 
-	/* OF flag is set if s == 1; OF = MSB _XOR_ (M-1)SB of result */
-	if(s == 1) {
-	CONDITIONAL_SET_FLAG(XOR2(d >> 14), F_OF);
-	} else if(BOX64ENV(dynarec_test)) {
-		CLEAR_FLAG(F_OF);
-	}
+	if(BOX64ENV(cputype)) CONDITIONAL_SET_FLAG(XOR2(d >> 14), F_OF);
 
 	/* set new CF; note that it is the MSB of the result */
 	CONDITIONAL_SET_FLAG(d & (1 << 15), F_CF);
@@ -947,17 +928,14 @@ uint32_t ror32(x64emu_t *emu, uint32_t d, uint8_t s)
 	s = s&0x1f;
 	if(!s) return d;
 
+	if(!BOX64ENV(cputype)) CONDITIONAL_SET_FLAG(((d >> 31)^d)&1, F_OF);
+
 	if((cnt = s % 32) != 0) {
-	d = (d << (32 - cnt)) + ((d >> (cnt)) & ((1 << (32 - cnt)) - 1));
+		d = (d << (32 - cnt)) + ((d >> (cnt)) & ((1 << (32 - cnt)) - 1));
 	}
 	CHECK_FLAGS(emu);
 
-	/* OF flag is set if s == 1; OF = MSB _XOR_ (M-1)SB of result */
-	if(s == 1) {
-	CONDITIONAL_SET_FLAG(XOR2(d >> 30), F_OF);
-	} else if(BOX64ENV(dynarec_test)) {
-		CLEAR_FLAG(F_OF);
-	}
+	if(BOX64ENV(cputype)) CONDITIONAL_SET_FLAG(XOR2(d >> 30), F_OF);
 
 	/* set new CF; note that it is the MSB of the result */
 	CONDITIONAL_SET_FLAG(d & (1 << 31), F_CF);
@@ -972,17 +950,14 @@ uint64_t ror64(x64emu_t *emu, uint64_t d, uint8_t s)
 	s = s&0x3f;
 	if(!s) return d;
 
+	if(!BOX64ENV(cputype)) CONDITIONAL_SET_FLAG(((d >> 63)^d)&1, F_OF);
+
 	if((cnt = s % 64) != 0) {
-	d = (d << (64 - cnt)) + ((d >> (cnt)) & ((1L << (64 - cnt)) - 1L));
+		d = (d << (64 - cnt)) + ((d >> (cnt)) & ((1L << (64 - cnt)) - 1L));
 	}
 	CHECK_FLAGS(emu);
 
-	/* OF flag is set if s == 1; OF = MSB _XOR_ (M-1)SB of result */
-	if(s == 1) {
-	CONDITIONAL_SET_FLAG(XOR2(d >> 62), F_OF);
-	} else if(BOX64ENV(dynarec_test)) {
-		CLEAR_FLAG(F_OF);
-	}
+	if(BOX64ENV(cputype)) CONDITIONAL_SET_FLAG(XOR2(d >> 62), F_OF);
 
 	/* set new CF; note that it is the MSB of the result */
 	CONDITIONAL_SET_FLAG(d & (1L << 63), F_CF);
@@ -1003,34 +978,38 @@ uint16_t shld16 (x64emu_t *emu, uint16_t d, uint16_t fill, uint8_t s)
 		return d;
 	RESET_FLAGS(emu);
 	if (s < 16) {
-		if (cnt > 0) {
-			res = (d << cnt) | (fill >> (16-cnt));
-			cf = d & (1 << (16 - cnt));
-			CONDITIONAL_SET_FLAG(cf, F_CF);
-			CONDITIONAL_SET_FLAG((res & 0xffff) == 0, F_ZF);
-			CONDITIONAL_SET_FLAG(res & 0x8000, F_SF);
-			CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
-		} else {
-			res = d;
-		}
-		if (cnt == 1) {
-			CONDITIONAL_SET_FLAG(((res ^ d) >> 15)&1, F_OF);
-		} else {
-			CLEAR_FLAG(F_OF);
-		}
+		res = (d << cnt) | (fill >> (16-cnt));
+		cf = d & (1 << (16 - cnt));
+		CONDITIONAL_SET_FLAG(cf, F_CF);
+		CONDITIONAL_SET_FLAG((res & 0xffff) == 0, F_ZF);
+		CONDITIONAL_SET_FLAG(res & 0x8000, F_SF);
+		CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
 	} else {
 		res = (fill << (cnt)) | (d >> (16 - cnt));
 		if(s==16)
 			cf = d & 1;
 		else
 			cf = fill & (1 << (16 - cnt));
-		CONDITIONAL_SET_FLAG(cf, F_CF);
+		if(BOX64ENV(cputype) && (s>16)) {
+			CLEAR_FLAG(F_CF);
+		} else {
+			CONDITIONAL_SET_FLAG(cf, F_CF);
+		}
 		CONDITIONAL_SET_FLAG((res & 0xffff) == 0, F_ZF);
 		CONDITIONAL_SET_FLAG(res & 0x8000, F_SF);
 		CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
-		CLEAR_FLAG(F_OF);
 	}
-	if(BOX64ENV(dynarec_test))
+	if (BOX64ENV(cputype)) {
+		if(s>15)
+			CONDITIONAL_SET_FLAG(ACCESS_FLAG(F_CF), F_OF);
+		else
+			CONDITIONAL_SET_FLAG((ACCESS_FLAG(F_CF) ^ (res>>15))&1, F_OF);
+	} else {
+		CONDITIONAL_SET_FLAG(XOR2(d>>14), F_OF);
+	}
+	if (BOX64ENV(cputype))
+		SET_FLAG(F_AF);
+	else
 		CLEAR_FLAG(F_AF);
 	return (uint16_t)res;
 }
@@ -1054,12 +1033,14 @@ uint32_t shld32 (x64emu_t *emu, uint32_t d, uint32_t fill, uint8_t s)
 	} else {
 		res = d;
 	}
-	if (cnt == 1) {
-		CONDITIONAL_SET_FLAG(((res ^ d) >> 31)&1, F_OF);
+	if (BOX64ENV(cputype)) {
+		CONDITIONAL_SET_FLAG((ACCESS_FLAG(F_CF) ^ (res>>31))&1, F_OF);
 	} else {
-		CLEAR_FLAG(F_OF);
+		CONDITIONAL_SET_FLAG(XOR2(d>>30), F_OF);
 	}
-	if(BOX64ENV(dynarec_test))
+	if (BOX64ENV(cputype))
+		SET_FLAG(F_AF);
+	else
 		CLEAR_FLAG(F_AF);
 	return res;
 }
@@ -1083,12 +1064,14 @@ uint64_t shld64 (x64emu_t *emu, uint64_t d, uint64_t fill, uint8_t s)
 	} else {
 		res = d;
 	}
-	if (cnt == 1) {
-		CONDITIONAL_SET_FLAG(((res ^ d) >> 63)&1, F_OF);
+	if (BOX64ENV(cputype)) {
+		CONDITIONAL_SET_FLAG((ACCESS_FLAG(F_CF) ^ (res>>63))&1, F_OF);
 	} else {
-		CLEAR_FLAG(F_OF);
+		CONDITIONAL_SET_FLAG(XOR2(d>>62), F_OF);
 	}
-	if(BOX64ENV(dynarec_test))
+	if (BOX64ENV(cputype))
+		SET_FLAG(F_AF);
+	else
 		CLEAR_FLAG(F_AF);
 	return res;
 }
@@ -1118,22 +1101,20 @@ uint16_t shrd16 (x64emu_t *emu, uint16_t d, uint16_t fill, uint8_t s)
 			res = d;
 		}
 
-		if (cnt == 1) {
-			CONDITIONAL_SET_FLAG(((res ^ d) >> 15)&1, F_OF);
-        } else {
-			CLEAR_FLAG(F_OF);
-        }
 	} else {
 		if(s==16)
 			cf = d & (1 << 15);
 		else
 			cf = fill & (1 << (cnt - 1));
 		res = (fill >> cnt) | (d << (16 - cnt));
-		CONDITIONAL_SET_FLAG(cf, F_CF);
+		if(BOX64ENV(cputype) && (s>16)) {
+			CLEAR_FLAG(F_CF);
+		} else {
+			CONDITIONAL_SET_FLAG(cf, F_CF);
+		}
 		CONDITIONAL_SET_FLAG((res & 0xffff) == 0, F_ZF);
 		CONDITIONAL_SET_FLAG(res & 0x8000, F_SF);
 		CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
-		CLEAR_FLAG(F_OF);
 	#if 0
 		res = 0;
 		CLEAR_FLAG(F_CF);
@@ -1143,7 +1124,14 @@ uint16_t shrd16 (x64emu_t *emu, uint16_t d, uint16_t fill, uint8_t s)
 		CLEAR_FLAG(F_PF);
 	#endif
     }
-	if(BOX64ENV(dynarec_test))
+	if (BOX64ENV(cputype)) {
+		CONDITIONAL_SET_FLAG(XOR2(res>>14), F_OF);
+	} else {
+		CONDITIONAL_SET_FLAG((fill^(d>>15))&1, F_OF);
+	}
+	if (BOX64ENV(cputype))
+		SET_FLAG(F_AF);
+	else
 		CLEAR_FLAG(F_AF);
 	return (uint16_t)res;
 }
@@ -1167,12 +1155,14 @@ uint32_t shrd32 (x64emu_t *emu, uint32_t d, uint32_t fill, uint8_t s)
 	} else {
 		res = d;
 	}
-	if (cnt == 1) {
-		CONDITIONAL_SET_FLAG(((res ^ d) >> 31)&1, F_OF);
+	if (BOX64ENV(cputype)) {
+		CONDITIONAL_SET_FLAG(XOR2(res>>30), F_OF);
 	} else {
-		CLEAR_FLAG(F_OF);
+		CONDITIONAL_SET_FLAG((fill^(d>>31))&1, F_OF);
 	}
-	if(BOX64ENV(dynarec_test))
+	if (BOX64ENV(cputype))
+		SET_FLAG(F_AF);
+	else
 		CLEAR_FLAG(F_AF);
 	return res;
 }
@@ -1197,12 +1187,14 @@ uint64_t shrd64 (x64emu_t *emu, uint64_t d, uint64_t fill, uint8_t s)
 	} else {
 		res = d;
 	}
-	if (cnt == 1) {
-		CONDITIONAL_SET_FLAG(((res ^ d) >> 63)&1, F_OF);
+	if (BOX64ENV(cputype)) {
+		CONDITIONAL_SET_FLAG(XOR2(res>>62), F_OF);
 	} else {
-		CLEAR_FLAG(F_OF);
+		CONDITIONAL_SET_FLAG((fill^(d>>63))&1, F_OF);
 	}
-	if(BOX64ENV(dynarec_test))
+	if (BOX64ENV(cputype))
+		SET_FLAG(F_AF);
+	else
 		CLEAR_FLAG(F_AF);
 	return res;
 }
@@ -1370,14 +1362,12 @@ Implements the IDIV instruction and side effects.
 void idiv8(x64emu_t *emu, uint8_t s)
 {
     int32_t dvd, quot, mod;
-	RESET_FLAGS(emu);
-	if(BOX64ENV(dynarec_test)) {
-		CLEAR_FLAG(F_CF);
-		CLEAR_FLAG(F_AF);
+	if(BOX64ENV(cputype)) {
+		CHECK_FLAGS(emu);
+		SET_FLAG(F_AF);
 		CLEAR_FLAG(F_PF);
 		CLEAR_FLAG(F_ZF);
 		CLEAR_FLAG(F_SF);
-		CLEAR_FLAG(F_OF);
 	}
 
 	dvd = (int16_t)R_AX;
@@ -1399,14 +1389,12 @@ void idiv8(x64emu_t *emu, uint8_t s)
 void idiv16(x64emu_t *emu, uint16_t s)
 {
 	int32_t dvd, quot, mod;
-	RESET_FLAGS(emu);
-	if(BOX64ENV(dynarec_test)) {
-		CLEAR_FLAG(F_CF);
-		CLEAR_FLAG(F_AF);
+	if(BOX64ENV(cputype)) {
+		CHECK_FLAGS(emu);
+		SET_FLAG(F_AF);
 		CLEAR_FLAG(F_PF);
 		CLEAR_FLAG(F_ZF);
 		CLEAR_FLAG(F_SF);
-		CLEAR_FLAG(F_OF);
 	}
 
 	dvd = (((int32_t)R_DX) << 16) | R_AX;
@@ -1429,14 +1417,12 @@ void idiv16(x64emu_t *emu, uint16_t s)
 void idiv32(x64emu_t *emu, uint32_t s)
 {
 	int64_t dvd, quot, mod;
-	RESET_FLAGS(emu);
-	if(BOX64ENV(dynarec_test)) {
-		CLEAR_FLAG(F_CF);
-		CLEAR_FLAG(F_AF);
+	if(BOX64ENV(cputype)) {
+		CHECK_FLAGS(emu);
+		SET_FLAG(F_AF);
 		CLEAR_FLAG(F_PF);
 		CLEAR_FLAG(F_ZF);
 		CLEAR_FLAG(F_SF);
-		CLEAR_FLAG(F_OF);
 	}
 
 	dvd = (((int64_t)R_EDX) << 32) | R_EAX;
@@ -1459,14 +1445,12 @@ void idiv32(x64emu_t *emu, uint32_t s)
 void idiv64(x64emu_t *emu, uint64_t s)
 {
 	__int128 dvd, quot, mod;
-	RESET_FLAGS(emu);
-	if(BOX64ENV(dynarec_test)) {
-		CLEAR_FLAG(F_CF);
-		CLEAR_FLAG(F_AF);
+	if(BOX64ENV(cputype)) {
+		CHECK_FLAGS(emu);
+		SET_FLAG(F_AF);
 		CLEAR_FLAG(F_PF);
 		CLEAR_FLAG(F_ZF);
 		CLEAR_FLAG(F_SF);
-		CLEAR_FLAG(F_OF);
 	}
 
 	dvd = (((__int128)R_RDX) << 64) | R_RAX;
@@ -1493,13 +1477,17 @@ void div8(x64emu_t *emu, uint8_t s)
 {
 	uint32_t dvd, div, mod;
 	RESET_FLAGS(emu);
-	if(BOX64ENV(dynarec_test)) {
-		CLEAR_FLAG(F_CF);
-		CLEAR_FLAG(F_AF);
-		CLEAR_FLAG(F_PF);
+	CLEAR_FLAG(F_CF);
+	CLEAR_FLAG(F_SF);
+	CLEAR_FLAG(F_OF);
+	if(BOX64ENV(cputype)) {
+		SET_FLAG(F_AF);
 		CLEAR_FLAG(F_ZF);
-		CLEAR_FLAG(F_SF);
-		CLEAR_FLAG(F_OF);
+		CLEAR_FLAG(F_PF);
+	} else {
+		CLEAR_FLAG(F_AF);
+		SET_FLAG(F_ZF);
+		SET_FLAG(F_PF);
 	}
 
 	dvd = R_AX;
@@ -1521,13 +1509,17 @@ void div16(x64emu_t *emu, uint16_t s)
 {
 	uint32_t dvd, div, mod;
 	RESET_FLAGS(emu);
-	if(BOX64ENV(dynarec_test)) {
-		CLEAR_FLAG(F_CF);
-		CLEAR_FLAG(F_AF);
-		CLEAR_FLAG(F_PF);
+	CLEAR_FLAG(F_CF);
+	CLEAR_FLAG(F_SF);
+	CLEAR_FLAG(F_OF);
+	if(BOX64ENV(cputype)) {
+		SET_FLAG(F_AF);
 		CLEAR_FLAG(F_ZF);
-		CLEAR_FLAG(F_SF);
-		CLEAR_FLAG(F_OF);
+		CLEAR_FLAG(F_PF);
+	} else {
+		CLEAR_FLAG(F_AF);
+		SET_FLAG(F_ZF);
+		SET_FLAG(F_PF);
 	}
 
 	dvd = (((uint32_t)R_DX) << 16) | R_AX;
@@ -1550,13 +1542,17 @@ void div32(x64emu_t *emu, uint32_t s)
 {
 	uint64_t dvd, div, mod;
 	RESET_FLAGS(emu);
-	if(BOX64ENV(dynarec_test)) {
-		CLEAR_FLAG(F_CF);
-		CLEAR_FLAG(F_AF);
-		CLEAR_FLAG(F_PF);
+	CLEAR_FLAG(F_CF);
+	CLEAR_FLAG(F_SF);
+	CLEAR_FLAG(F_OF);
+	if(BOX64ENV(cputype)) {
+		SET_FLAG(F_AF);
 		CLEAR_FLAG(F_ZF);
-		CLEAR_FLAG(F_SF);
-		CLEAR_FLAG(F_OF);
+		CLEAR_FLAG(F_PF);
+	} else {
+		CLEAR_FLAG(F_AF);
+		SET_FLAG(F_ZF);
+		SET_FLAG(F_PF);
 	}
 
 	dvd = (((uint64_t)R_EDX) << 32) | R_EAX;
@@ -1579,13 +1575,17 @@ void div64(x64emu_t *emu, uint64_t s)
 {
 	__int128 dvd, div, mod;
 	RESET_FLAGS(emu);
-	if(BOX64ENV(dynarec_test)) {
-		CLEAR_FLAG(F_CF);
-		CLEAR_FLAG(F_AF);
-		CLEAR_FLAG(F_PF);
+	CLEAR_FLAG(F_CF);
+	CLEAR_FLAG(F_SF);
+	CLEAR_FLAG(F_OF);
+	if(BOX64ENV(cputype)) {
+		SET_FLAG(F_AF);
 		CLEAR_FLAG(F_ZF);
-		CLEAR_FLAG(F_SF);
-		CLEAR_FLAG(F_OF);
+		CLEAR_FLAG(F_PF);
+	} else {
+		CLEAR_FLAG(F_AF);
+		SET_FLAG(F_ZF);
+		SET_FLAG(F_PF);
 	}
 
 	dvd = (((__int128)R_RDX) << 64) | R_RAX;
diff --git a/src/emu/x64primop.h b/src/emu/x64primop.h
index e02fd9e7..2ad7d294 100644
--- a/src/emu/x64primop.h
+++ b/src/emu/x64primop.h
@@ -533,12 +533,14 @@ static inline uint64_t xor64(x64emu_t *emu, uint64_t d, uint64_t s)
 
 static inline void imul8(x64emu_t *emu, uint8_t s)
 {
+	if (BOX64ENV(cputype)) CHECK_FLAGS(emu);
 	emu->df = d_imul8;
 	R_AX = emu->res.u16 = ((int16_t)(int8_t)R_AL) * (int8_t)s;
 }
 
 static inline void imul16_eax(x64emu_t *emu, uint16_t s)
 {
+	if (BOX64ENV(cputype)) CHECK_FLAGS(emu);
 	emu->df = d_imul16;
 	emu->res.u32 = ((int32_t)(int16_t)R_AX) * (int16_t)s;
 	R_AX = (uint16_t)emu->res.u32;
@@ -547,6 +549,7 @@ static inline void imul16_eax(x64emu_t *emu, uint16_t s)
 
 static inline uint16_t imul16(x64emu_t *emu, uint16_t op1, uint16_t op2)
 {
+	if (BOX64ENV(cputype)) CHECK_FLAGS(emu);
 	emu->df = d_imul16;
 	emu->res.u32 = ((int32_t)(int16_t)op1) * (int16_t)op2;
 	return emu->res.u16;
@@ -562,6 +565,7 @@ static inline void imul32_direct(uint32_t *res_lo, uint32_t* res_hi,uint32_t d,
 
 static inline uint32_t imul32(x64emu_t *emu, uint32_t op1, uint32_t op2)
 {
+	if (BOX64ENV(cputype)) CHECK_FLAGS(emu);
 	emu->df = d_imul32;
 	uint32_t _res, _op1;
 	imul32_direct(&_res,&_op1,op1,op2);
@@ -572,6 +576,7 @@ static inline uint32_t imul32(x64emu_t *emu, uint32_t op1, uint32_t op2)
 
 static inline void imul32_eax(x64emu_t *emu, uint32_t s)
 {
+	if (BOX64ENV(cputype)) CHECK_FLAGS(emu);
 	emu->df = d_imul32;
 	imul32_direct(&emu->res.u32,&emu->op1.u32,R_EAX,s);
 	R_EAX = emu->res.u32;
@@ -588,6 +593,7 @@ static inline void imul64_direct(uint64_t *res_lo, uint64_t* res_hi,uint64_t d,
 
 static inline uint64_t imul64(x64emu_t *emu, uint64_t op1, uint64_t op2)
 {
+	if (BOX64ENV(cputype)) CHECK_FLAGS(emu);
 	emu->df = d_imul64;
 	imul64_direct(&emu->res.u64,&emu->op1.u64,op1,op2);
 	return emu->res.u64;
@@ -595,6 +601,7 @@ static inline uint64_t imul64(x64emu_t *emu, uint64_t op1, uint64_t op2)
 
 static inline void imul64_rax(x64emu_t *emu, uint64_t s)
 {
+	if (BOX64ENV(cputype)) CHECK_FLAGS(emu);
 	emu->df = d_imul64;
 	imul64_direct(&emu->res.u64,&emu->op1.u64,R_RAX,s);
 	R_RAX = emu->res.u64;
@@ -603,12 +610,14 @@ static inline void imul64_rax(x64emu_t *emu, uint64_t s)
 
 static inline void mul8(x64emu_t *emu, uint8_t s)
 {
+	if (BOX64ENV(cputype)) CHECK_FLAGS(emu);
 	emu->df = d_mul8;
 	R_AX = emu->res.u16 = (uint16_t)(R_AL) * s;
 }
 
 static inline void mul16(x64emu_t *emu, uint16_t s)
 {
+	if (BOX64ENV(cputype)) CHECK_FLAGS(emu);
 	emu->df = d_mul16;
 	emu->res.u32 = (uint32_t)R_AX * s;
 	R_AX = (uint16_t)emu->res.u32;
@@ -617,6 +626,7 @@ static inline void mul16(x64emu_t *emu, uint16_t s)
 
 static inline void mul32_eax(x64emu_t *emu, uint32_t s)
 {
+	if (BOX64ENV(cputype)) CHECK_FLAGS(emu);
 	emu->df = d_mul32;
 	uint64_t res = (uint64_t)R_EAX * s;
 	emu->res.u32 = R_EAX = (uint32_t)res;
@@ -625,6 +635,7 @@ static inline void mul32_eax(x64emu_t *emu, uint32_t s)
 
 static inline void mul64_rax(x64emu_t *emu, uint64_t s)
 {
+	if (BOX64ENV(cputype)) CHECK_FLAGS(emu);
 	emu->df = d_mul64;
 	unsigned __int128 res = (unsigned __int128)R_RAX * s;
 	emu->res.u64 = R_RAX = (uint64_t)res;
diff --git a/src/emu/x64run0f.c b/src/emu/x64run0f.c
index 6f600a67..556ad1f8 100644
--- a/src/emu/x64run0f.c
+++ b/src/emu/x64run0f.c
@@ -1182,12 +1182,6 @@ uintptr_t Run0F(x64emu_t *emu, rex_t rex, uintptr_t addr, int *step)
                 else

                     CLEAR_FLAG(F_CF);

             }

-            if (BOX64ENV(dynarec_test)) {

-                CLEAR_FLAG(F_OF);

-                CLEAR_FLAG(F_SF);

-                CLEAR_FLAG(F_AF);

-                CLEAR_FLAG(F_PF);

-            }

             break;

         case 0xA4:                      /* SHLD Ed,Gd,Ib */

             nextop = F8;

@@ -1479,12 +1473,6 @@ uintptr_t Run0F(x64emu_t *emu, rex_t rex, uintptr_t addr, int *step)
                         else

                             CLEAR_FLAG(F_CF);

                     }

-                    if (BOX64ENV(dynarec_test)) {

-                        CLEAR_FLAG(F_OF);

-                        CLEAR_FLAG(F_SF);

-                        CLEAR_FLAG(F_AF);

-                        CLEAR_FLAG(F_PF);

-                    }

                     break;

                 case 5:             /* BTS Ed, Ib */

                     CHECK_FLAGS(emu);

@@ -1509,12 +1497,6 @@ uintptr_t Run0F(x64emu_t *emu, rex_t rex, uintptr_t addr, int *step)
                         if(MODREG)

                             ED->dword[1] = 0;

                     }

-                    if (BOX64ENV(dynarec_test)) {

-                        CLEAR_FLAG(F_OF);

-                        CLEAR_FLAG(F_SF);

-                        CLEAR_FLAG(F_AF);

-                        CLEAR_FLAG(F_PF);

-                    }

                     break;

                 case 6:             /* BTR Ed, Ib */

                     CHECK_FLAGS(emu);

@@ -1537,12 +1519,6 @@ uintptr_t Run0F(x64emu_t *emu, rex_t rex, uintptr_t addr, int *step)
                         if(MODREG)

                             ED->dword[1] = 0;

                     }

-                    if (BOX64ENV(dynarec_test)) {

-                        CLEAR_FLAG(F_OF);

-                        CLEAR_FLAG(F_SF);

-                        CLEAR_FLAG(F_AF);

-                        CLEAR_FLAG(F_PF);

-                    }

                     break;

                 case 7:             /* BTC Ed, Ib */

                     CHECK_FLAGS(emu);

@@ -1565,12 +1541,6 @@ uintptr_t Run0F(x64emu_t *emu, rex_t rex, uintptr_t addr, int *step)
                         if(MODREG)

                             ED->dword[1] = 0;

                     }

-                    if (BOX64ENV(dynarec_test)) {

-                        CLEAR_FLAG(F_OF);

-                        CLEAR_FLAG(F_SF);

-                        CLEAR_FLAG(F_AF);

-                        CLEAR_FLAG(F_PF);

-                    }

                     break;

 

                 default:

@@ -1612,12 +1582,6 @@ uintptr_t Run0F(x64emu_t *emu, rex_t rex, uintptr_t addr, int *step)
                 if(MODREG)

                     ED->dword[1] = 0;

             }

-            if (BOX64ENV(dynarec_test)) {

-                CLEAR_FLAG(F_OF);

-                CLEAR_FLAG(F_SF);

-                CLEAR_FLAG(F_AF);

-                CLEAR_FLAG(F_PF);

-            }

             break;

         case 0xBC:                      /* BSF Ed,Gd */

             RESET_FLAGS(emu);

diff --git a/src/emu/x64run_private.c b/src/emu/x64run_private.c
index f462361e..4f3d5b4c 100644
--- a/src/emu/x64run_private.c
+++ b/src/emu/x64run_private.c
@@ -381,12 +381,11 @@ void UpdateFlags(x64emu_t *emu)
                 SET_FLAG(F_CF);
                 SET_FLAG(F_OF);
             }
-            if (BOX64ENV(dynarec_test)) {
-                // to avoid noise in tests
-                CLEAR_FLAG(F_SF);
+            if (!BOX64ENV(cputype)) {
+                CONDITIONAL_SET_FLAG((emu->res.u8>>7)&1, F_SF);
                 CLEAR_FLAG(F_ZF);
                 CLEAR_FLAG(F_AF);
-                CLEAR_FLAG(F_PF);
+                CONDITIONAL_SET_FLAG(PARITY(emu->res.u8), F_PF);
             }
             break;
         case d_imul16:
@@ -400,12 +399,11 @@ void UpdateFlags(x64emu_t *emu)
                 SET_FLAG(F_CF);
                 SET_FLAG(F_OF);
             }
-            if (BOX64ENV(dynarec_test)) {
-                // to avoid noise in tests
-                CLEAR_FLAG(F_SF);
+            if (!BOX64ENV(cputype)) {
+                CONDITIONAL_SET_FLAG((emu->res.u16>>15)&1, F_SF);
                 CLEAR_FLAG(F_ZF);
                 CLEAR_FLAG(F_AF);
-                CLEAR_FLAG(F_PF);
+                CONDITIONAL_SET_FLAG(PARITY(emu->res.u8), F_PF);
             }
             break;
         case d_imul32:
@@ -417,12 +415,11 @@ void UpdateFlags(x64emu_t *emu)
                 SET_FLAG(F_CF);
                 SET_FLAG(F_OF); 
             }
-            if (BOX64ENV(dynarec_test)) {
-                // to avoid noise in tests
-                CLEAR_FLAG(F_SF);
+            if (!BOX64ENV(cputype)) {
+                CONDITIONAL_SET_FLAG((emu->res.u32>>31)&1, F_SF);
                 CLEAR_FLAG(F_ZF);
                 CLEAR_FLAG(F_AF);
-                CLEAR_FLAG(F_PF);
+                CONDITIONAL_SET_FLAG(PARITY(emu->res.u8), F_PF);
             }
             break;
         case d_imul64:
@@ -434,12 +431,11 @@ void UpdateFlags(x64emu_t *emu)
                 SET_FLAG(F_CF);
                 SET_FLAG(F_OF);
             }
-            if (BOX64ENV(dynarec_test)) {
-                // to avoid noise in tests
-                CLEAR_FLAG(F_SF);
+            if (!BOX64ENV(cputype)) {
+                CONDITIONAL_SET_FLAG((emu->res.u64>>63)&1, F_SF);
                 CLEAR_FLAG(F_ZF);
                 CLEAR_FLAG(F_AF);
-                CLEAR_FLAG(F_PF);
+                CONDITIONAL_SET_FLAG(PARITY(emu->res.u8), F_PF);
             }
             break;
         case d_mul8:
@@ -451,12 +447,11 @@ void UpdateFlags(x64emu_t *emu)
                 SET_FLAG(F_CF);
                 SET_FLAG(F_OF);
             }
-            if (BOX64ENV(dynarec_test)) {
-                // to avoid noise in tests
-                CLEAR_FLAG(F_SF);
+            if (!BOX64ENV(cputype)) {
+                CONDITIONAL_SET_FLAG((emu->res.u8>>7)&1, F_SF);
                 CLEAR_FLAG(F_ZF);
                 CLEAR_FLAG(F_AF);
-                CLEAR_FLAG(F_PF);
+                CONDITIONAL_SET_FLAG(PARITY(emu->res.u8), F_PF);
             }
             break;
         case d_mul16:
@@ -468,12 +463,11 @@ void UpdateFlags(x64emu_t *emu)
                 SET_FLAG(F_CF);
                 SET_FLAG(F_OF);
             }
-            if (BOX64ENV(dynarec_test)) {
-                // to avoid noise in tests
-                CLEAR_FLAG(F_SF);
+            if (!BOX64ENV(cputype)) {
+                CONDITIONAL_SET_FLAG((emu->res.u16>>15)&1, F_SF);
                 CLEAR_FLAG(F_ZF);
                 CLEAR_FLAG(F_AF);
-                CLEAR_FLAG(F_PF);
+                CONDITIONAL_SET_FLAG(PARITY(emu->res.u8), F_PF);
             }
             break;
         case d_mul32:
@@ -484,12 +478,11 @@ void UpdateFlags(x64emu_t *emu)
                 SET_FLAG(F_CF);
                 SET_FLAG(F_OF);
             }
-            if (BOX64ENV(dynarec_test)) {
-                // to avoid noise in tests
-                CLEAR_FLAG(F_SF);
+            if (!BOX64ENV(cputype)) {
+                CONDITIONAL_SET_FLAG((emu->res.u32>>31)&1, F_SF);
                 CLEAR_FLAG(F_ZF);
                 CLEAR_FLAG(F_AF);
-                CLEAR_FLAG(F_PF);
+                CONDITIONAL_SET_FLAG(PARITY(emu->res.u8), F_PF);
             }
             break;
         case d_mul64:
@@ -500,12 +493,11 @@ void UpdateFlags(x64emu_t *emu)
                 SET_FLAG(F_CF);
                 SET_FLAG(F_OF);
             }
-            if (BOX64ENV(dynarec_test)) {
-                // to avoid noise in tests
-                CLEAR_FLAG(F_SF);
+            if (!BOX64ENV(cputype)) {
+                CONDITIONAL_SET_FLAG((emu->res.u64>>63)&1, F_SF);
                 CLEAR_FLAG(F_ZF);
                 CLEAR_FLAG(F_AF);
-                CLEAR_FLAG(F_PF);
+                CONDITIONAL_SET_FLAG(PARITY(emu->res.u8), F_PF);
             }
             break;
         case d_or8:
@@ -584,12 +576,11 @@ void UpdateFlags(x64emu_t *emu)
                 CONDITIONAL_SET_FLAG(!emu->res.u8, F_ZF);
                 CONDITIONAL_SET_FLAG(emu->res.u8 & 0x80, F_SF);
                 CONDITIONAL_SET_FLAG(PARITY(emu->res.u8), F_PF);
-                if (cnt == 1) {
-                    CONDITIONAL_SET_FLAG((((emu->res.u8 & 0x80) == 0x80) ^(ACCESS_FLAG(F_CF) != 0)), F_OF);
+                if (BOX64ENV(cputype)) {
+                    CONDITIONAL_SET_FLAG(((emu->res.u8>>7) ^ ACCESS_FLAG(F_CF))&0x01, F_OF);
+                    SET_FLAG(F_AF);
                 } else {
-                    CLEAR_FLAG(F_OF);
-                }
-                if (BOX64ENV(dynarec_test)) {
+                    CONDITIONAL_SET_FLAG(XOR2(emu->op1.u8>>6), F_OF);
                     CLEAR_FLAG(F_AF);
                 }
             }
@@ -602,12 +593,11 @@ void UpdateFlags(x64emu_t *emu)
                 CONDITIONAL_SET_FLAG(!emu->res.u16, F_ZF);
                 CONDITIONAL_SET_FLAG(emu->res.u16 & 0x8000, F_SF);
                 CONDITIONAL_SET_FLAG(PARITY(emu->res.u8), F_PF);
-                if (cnt == 1) {
-                    CONDITIONAL_SET_FLAG(((!!(emu->res.u16 & 0x8000)) ^(ACCESS_FLAG(F_CF) != 0)), F_OF);
+                if (BOX64ENV(cputype)) {
+                    CONDITIONAL_SET_FLAG(((emu->res.u16>>15) ^ ACCESS_FLAG(F_CF))&0x01, F_OF);
+                    SET_FLAG(F_AF);
                 } else {
-                    CLEAR_FLAG(F_OF);
-                }
-                if (BOX64ENV(dynarec_test)) {
+                    CONDITIONAL_SET_FLAG(XOR2(emu->op1.u16>>14), F_OF);
                     CLEAR_FLAG(F_AF);
                 }
             }
@@ -620,13 +610,11 @@ void UpdateFlags(x64emu_t *emu)
                 CONDITIONAL_SET_FLAG(!emu->res.u32, F_ZF);
                 CONDITIONAL_SET_FLAG(emu->res.u32 & 0x80000000, F_SF);
                 CONDITIONAL_SET_FLAG(PARITY(emu->res.u8), F_PF);
-                if (cnt == 1) {
-                    CONDITIONAL_SET_FLAG(((!!(emu->res.u32 & 0x80000000)) ^
-                                            (ACCESS_FLAG(F_CF) != 0)), F_OF);
+                if (BOX64ENV(cputype)) {
+                    CONDITIONAL_SET_FLAG(((emu->res.u32>>31) ^ ACCESS_FLAG(F_CF))&0x01, F_OF);
+                    SET_FLAG(F_AF);
                 } else {
-                    CLEAR_FLAG(F_OF);
-                }
-                if (BOX64ENV(dynarec_test)) {
+                    CONDITIONAL_SET_FLAG(XOR2(emu->op1.u32>>30), F_OF);
                     CLEAR_FLAG(F_AF);
                 }
             }
@@ -638,13 +626,11 @@ void UpdateFlags(x64emu_t *emu)
                 CONDITIONAL_SET_FLAG(!emu->res.u64, F_ZF);
                 CONDITIONAL_SET_FLAG(emu->res.u64 & 0x8000000000000000LL, F_SF);
                 CONDITIONAL_SET_FLAG(PARITY(emu->res.u8), F_PF);
-                if (emu->op2.u64 == 1) {
-                    CONDITIONAL_SET_FLAG(((!!(emu->res.u64 & 0x8000000000000000LL)) ^
-                                            (ACCESS_FLAG(F_CF) != 0)), F_OF);
+                if (BOX64ENV(cputype)) {
+                    CONDITIONAL_SET_FLAG(((emu->res.u64>>63) ^ ACCESS_FLAG(F_CF))&0x01, F_OF);
+                    SET_FLAG(F_AF);
                 } else {
-                    CLEAR_FLAG(F_OF);
-                }
-                if (BOX64ENV(dynarec_test)) {
+                    CONDITIONAL_SET_FLAG(XOR2(emu->op1.u64>>62), F_OF);
                     CLEAR_FLAG(F_AF);
                 }
             }
@@ -656,11 +642,11 @@ void UpdateFlags(x64emu_t *emu)
                 CONDITIONAL_SET_FLAG(!emu->res.u8, F_ZF);
                 CONDITIONAL_SET_FLAG(PARITY(emu->res.u8), F_PF);
                 CONDITIONAL_SET_FLAG(emu->res.u8 & 0x80, F_SF);
-                if (emu->op2.u8 == 1 || BOX64ENV(dynarec_test))
-                    CLEAR_FLAG(F_OF);
-                if (BOX64ENV(dynarec_test)) {
+                CLEAR_FLAG(F_OF);
+                if (BOX64ENV(cputype))
+                    SET_FLAG(F_AF);
+                else
                     CLEAR_FLAG(F_AF);
-                }
             }
             break;
         case d_sar16:
@@ -670,11 +656,11 @@ void UpdateFlags(x64emu_t *emu)
                 CONDITIONAL_SET_FLAG(!emu->res.u16, F_ZF);
                 CONDITIONAL_SET_FLAG(emu->res.u16 & 0x8000, F_SF);
                 CONDITIONAL_SET_FLAG(PARITY(emu->res.u8), F_PF);
-                if (emu->op2.u16 == 1 || BOX64ENV(dynarec_test))
-                    CLEAR_FLAG(F_OF);
-                if (BOX64ENV(dynarec_test)) {
+                CLEAR_FLAG(F_OF);
+                if (BOX64ENV(cputype))
+                    SET_FLAG(F_AF);
+                else
                     CLEAR_FLAG(F_AF);
-                }
             }
             break;
         case d_sar32:
@@ -684,11 +670,11 @@ void UpdateFlags(x64emu_t *emu)
                 CONDITIONAL_SET_FLAG(!emu->res.u32, F_ZF);
                 CONDITIONAL_SET_FLAG(emu->res.u32 & 0x80000000, F_SF);
                 CONDITIONAL_SET_FLAG(PARITY(emu->res.u8), F_PF);
-                if (emu->op2.u32 == 1 || BOX64ENV(dynarec_test))
-                    CLEAR_FLAG(F_OF);
-                if (BOX64ENV(dynarec_test)) {
+                CLEAR_FLAG(F_OF);
+                if (BOX64ENV(cputype))
+                    SET_FLAG(F_AF);
+                else
                     CLEAR_FLAG(F_AF);
-                }
             }
             break;
         case d_sar64:
@@ -698,11 +684,11 @@ void UpdateFlags(x64emu_t *emu)
                 CONDITIONAL_SET_FLAG(!emu->res.u64, F_ZF);
                 CONDITIONAL_SET_FLAG(emu->res.u64 & 0x8000000000000000LL, F_SF);
                 CONDITIONAL_SET_FLAG(PARITY(emu->res.u8), F_PF);
-                if (emu->op2.u64 == 1 || BOX64ENV(dynarec_test))
-                    CLEAR_FLAG(F_OF);
-                if (BOX64ENV(dynarec_test)) {
+                CLEAR_FLAG(F_OF);
+                if (BOX64ENV(cputype))
+                    SET_FLAG(F_AF);
+                else
                     CLEAR_FLAG(F_AF);
-                }
             }
             break;
         case d_shr8:
@@ -713,16 +699,14 @@ void UpdateFlags(x64emu_t *emu)
                 CONDITIONAL_SET_FLAG(!emu->res.u8, F_ZF);
                 CONDITIONAL_SET_FLAG(emu->res.u8 & 0x80, F_SF);
                 CONDITIONAL_SET_FLAG(PARITY(emu->res.u8), F_PF);
-                if (BOX64ENV(dynarec_test)) {
+                if (BOX64ENV(cputype)) {
+                    CONDITIONAL_SET_FLAG((emu->res.u8>>6)&0x1, F_OF);
+                    SET_FLAG(F_AF);
+                } else {
+                    CONDITIONAL_SET_FLAG((emu->op1.u8>>7)&0x1, F_OF);
                     CLEAR_FLAG(F_AF);
-                    if(cnt>1) {
-                        CLEAR_FLAG(F_OF);
-                    }
                 }
             }
-            if (cnt == 1) {
-                CONDITIONAL_SET_FLAG(emu->op1.u8 & 0x80, F_OF);
-            }
             break;
         case d_shr16:
             cnt = emu->op2.u16 & 0x1f;
@@ -732,11 +716,12 @@ void UpdateFlags(x64emu_t *emu)
                 CONDITIONAL_SET_FLAG(!emu->res.u16, F_ZF);
                 CONDITIONAL_SET_FLAG(emu->res.u16 & 0x8000, F_SF);
                 CONDITIONAL_SET_FLAG(PARITY(emu->res.u8), F_PF);
-                if (BOX64ENV(dynarec_test)) {
+                if (BOX64ENV(cputype)) {
+                    CONDITIONAL_SET_FLAG((emu->res.u16>>14)&0x1, F_OF);
+                    SET_FLAG(F_AF);
+                } else {
+                    CONDITIONAL_SET_FLAG((emu->op1.u16>>15)&0x1, F_OF);
                     CLEAR_FLAG(F_AF);
-                    if(cnt>1) {
-                        CLEAR_FLAG(F_OF);
-                    }
                 }
             }
             if (cnt == 1) {
@@ -751,16 +736,14 @@ void UpdateFlags(x64emu_t *emu)
                 CONDITIONAL_SET_FLAG(!emu->res.u32, F_ZF);
                 CONDITIONAL_SET_FLAG(emu->res.u32 & 0x80000000, F_SF);
                 CONDITIONAL_SET_FLAG(PARITY(emu->res.u8), F_PF);
-                if (BOX64ENV(dynarec_test)) {
+                if (BOX64ENV(cputype)) {
+                    CONDITIONAL_SET_FLAG((emu->res.u32>>30)&0x1, F_OF);
+                    SET_FLAG(F_AF);
+                } else {
+                    CONDITIONAL_SET_FLAG((emu->op1.u32>>31)&0x1, F_OF);
                     CLEAR_FLAG(F_AF);
-                    if(cnt>1) {
-                        CLEAR_FLAG(F_OF);
-                    }
                 }
             }
-            if (cnt == 1) {
-                CONDITIONAL_SET_FLAG(emu->op1.u32 & 0x80000000, F_OF);
-            }
             break;
         case d_shr64:
             cnt = emu->op2.u64;
@@ -770,14 +753,12 @@ void UpdateFlags(x64emu_t *emu)
                 CONDITIONAL_SET_FLAG(!emu->res.u64, F_ZF);
                 CONDITIONAL_SET_FLAG(emu->res.u64 & 0x8000000000000000LL, F_SF);
                 CONDITIONAL_SET_FLAG(PARITY(emu->res.u8), F_PF);
-                if (cnt == 1) {
-                    CONDITIONAL_SET_FLAG(emu->op1.u64 & 0x8000000000000000LL, F_OF);
-                }
-                if (BOX64ENV(dynarec_test)) {
+                if (BOX64ENV(cputype)) {
+                    CONDITIONAL_SET_FLAG((emu->res.u64>>62)&0x1, F_OF);
+                    SET_FLAG(F_AF);
+                } else {
+                    CONDITIONAL_SET_FLAG((emu->op1.u64>>63)&0x1, F_OF);
                     CLEAR_FLAG(F_AF);
-                    if(cnt>1) {
-                        CLEAR_FLAG(F_OF);
-                    }
                 }
             }
             break;
@@ -785,16 +766,22 @@ void UpdateFlags(x64emu_t *emu)
             cnt = emu->op2.u16;
             if (cnt > 0) {
                 cc = emu->op1.u16 & (1 << (cnt - 1));
+                if(cnt>15 && BOX64ENV(cputype))
+                    cc = 0;
                 CONDITIONAL_SET_FLAG(cc, F_CF);
                 CONDITIONAL_SET_FLAG(!emu->res.u16, F_ZF);
                 CONDITIONAL_SET_FLAG(emu->res.u16 & 0x8000, F_SF);
                 CONDITIONAL_SET_FLAG(PARITY(emu->res.u8), F_PF);
-                if (cnt == 1) {
-                    CONDITIONAL_SET_FLAG((emu->op1.u16 ^ emu->res.u16) & 0x8000, F_OF);
-                } else {
-                    CLEAR_FLAG(F_OF);
-               }
             }
+            if BOX64ENV(cputype) {
+                CONDITIONAL_SET_FLAG(XOR2(emu->res.u16>>14), F_OF);
+            } else {
+                CONDITIONAL_SET_FLAG(((emu->res.u16>>(16-(cnt&15))) ^ (emu->op1.u16>>15))&1, F_OF);
+            }
+            if (BOX64ENV(cputype))
+                    SET_FLAG(F_AF);
+                else
+                    CLEAR_FLAG(F_AF);
             break;
         case d_shrd32:
             cnt = emu->op2.u32;
@@ -804,11 +791,15 @@ void UpdateFlags(x64emu_t *emu)
                 CONDITIONAL_SET_FLAG(!emu->res.u32, F_ZF);
                 CONDITIONAL_SET_FLAG(emu->res.u32 & 0x80000000, F_SF);
                 CONDITIONAL_SET_FLAG(PARITY(emu->res.u8), F_PF);
-                if (cnt == 1) {
-                    CONDITIONAL_SET_FLAG((emu->op1.u32 ^ emu->res.u32) & 0x80000000, F_OF);
+                if BOX64ENV(cputype) {
+                    CONDITIONAL_SET_FLAG(XOR2(emu->res.u32>>30), F_OF);
                 } else {
-                    CLEAR_FLAG(F_OF);
+                    CONDITIONAL_SET_FLAG(((emu->res.u32>>(32-cnt)) ^ (emu->op1.u32>>31))&1, F_OF);
                 }
+                if (BOX64ENV(cputype))
+                    SET_FLAG(F_AF);
+                else
+                    CLEAR_FLAG(F_AF);
             }
             break;
         case d_shrd64:
@@ -819,11 +810,15 @@ void UpdateFlags(x64emu_t *emu)
                 CONDITIONAL_SET_FLAG(!emu->res.u64, F_ZF);
                 CONDITIONAL_SET_FLAG(emu->res.u64 & 0x8000000000000000LL, F_SF);
                 CONDITIONAL_SET_FLAG(PARITY(emu->res.u8), F_PF);
-                if (cnt == 1) {
-                    CONDITIONAL_SET_FLAG((emu->op1.u64 ^ emu->res.u64) & 0x8000000000000000LL, F_OF);
+                if BOX64ENV(cputype) {
+                    CONDITIONAL_SET_FLAG(XOR2(emu->res.u64>>62), F_OF);
                 } else {
-                    CLEAR_FLAG(F_OF);
+                    CONDITIONAL_SET_FLAG(((emu->res.u64>>(64-cnt)) ^ (emu->op1.u64>>63))&1, F_OF);
                 }
+                if (BOX64ENV(cputype))
+                    SET_FLAG(F_AF);
+                else
+                    CLEAR_FLAG(F_AF);
             }
             break;
         case d_shld16:
@@ -834,11 +829,18 @@ void UpdateFlags(x64emu_t *emu)
                 CONDITIONAL_SET_FLAG(!emu->res.u16, F_ZF);
                 CONDITIONAL_SET_FLAG(emu->res.u16 & 0x8000, F_SF);
                 CONDITIONAL_SET_FLAG(PARITY(emu->res.u8), F_PF);
-                if (cnt == 1) {
-                    CONDITIONAL_SET_FLAG((emu->op1.u16 ^ emu->res.u16) & 0x8000, F_OF);
+                if BOX64ENV(cputype) {
+                    if(cnt>15)
+                        CONDITIONAL_SET_FLAG(ACCESS_FLAG(F_CF), F_OF);
+                    else
+                        CONDITIONAL_SET_FLAG((ACCESS_FLAG(F_CF) ^ (emu->res.u16>>15))&1, F_OF);
                 } else {
-                    CLEAR_FLAG(F_OF);
+                    CONDITIONAL_SET_FLAG(XOR2(emu->op1.u16>>14), F_OF);
                 }
+                if (BOX64ENV(cputype))
+                    SET_FLAG(F_AF);
+                else
+                    CLEAR_FLAG(F_AF);
             }
             break;
         case d_shld32:
@@ -849,11 +851,15 @@ void UpdateFlags(x64emu_t *emu)
                 CONDITIONAL_SET_FLAG(!emu->res.u32, F_ZF);
                 CONDITIONAL_SET_FLAG(emu->res.u32 & 0x80000000, F_SF);
                 CONDITIONAL_SET_FLAG(PARITY(emu->res.u8), F_PF);
-                if (cnt == 1) {
-                    CONDITIONAL_SET_FLAG((emu->op1.u32 ^ emu->res.u32) & 0x80000000, F_OF);
+                if BOX64ENV(cputype) {
+                    CONDITIONAL_SET_FLAG((ACCESS_FLAG(F_CF) ^ (emu->res.u32>>31))&1, F_OF);
                 } else {
-                    CLEAR_FLAG(F_OF);
+                    CONDITIONAL_SET_FLAG(XOR2(emu->op1.u32>>30), F_OF);
                 }
+                if (BOX64ENV(cputype))
+                    SET_FLAG(F_AF);
+                else
+                    CLEAR_FLAG(F_AF);
             }
             break;
         case d_shld64:
@@ -864,11 +870,15 @@ void UpdateFlags(x64emu_t *emu)
                 CONDITIONAL_SET_FLAG(!emu->res.u64, F_ZF);
                 CONDITIONAL_SET_FLAG(emu->res.u64 & 0x8000000000000000LL, F_SF);
                 CONDITIONAL_SET_FLAG(PARITY(emu->res.u8), F_PF);
-                if (cnt == 1) {
-                    CONDITIONAL_SET_FLAG((emu->op1.u64 ^ emu->res.u64) & 0x8000000000000000LL, F_OF);
+                if BOX64ENV(cputype) {
+                    CONDITIONAL_SET_FLAG((ACCESS_FLAG(F_CF) ^ (emu->res.u64>>63))&1, F_OF);
                 } else {
-                    CLEAR_FLAG(F_OF);
+                    CONDITIONAL_SET_FLAG(XOR2(emu->op1.u64>>62), F_OF);
                 }
+                if (BOX64ENV(cputype))
+                    SET_FLAG(F_AF);
+                else
+                    CLEAR_FLAG(F_AF);
             }
             break;
         case d_sub8:
@@ -1097,51 +1107,59 @@ void UpdateFlags(x64emu_t *emu)
             CONDITIONAL_SET_FLAG(bc & 0x8, F_AF);
             break;
         case d_rol8:
-            if(emu->op2.u8 == 1) {
+            if(BOX64ENV(cputype))
                 CONDITIONAL_SET_FLAG((emu->res.u8 + (emu->res.u8 >> 7)) & 1, F_OF);
-            }
+            else
+                CONDITIONAL_SET_FLAG(XOR2(emu->op1.u8>>6), F_OF);
             CONDITIONAL_SET_FLAG(emu->res.u8 & 0x1, F_CF);
-            break;
+                break;
         case d_rol16:
-            if(emu->op2.u16 == 1) {
+            if(BOX64ENV(cputype))
                 CONDITIONAL_SET_FLAG((emu->res.u16 + (emu->res.u16 >> 15)) & 1, F_OF);
-            }
+            else
+                CONDITIONAL_SET_FLAG(XOR2(emu->op1.u16>>14), F_OF);
             CONDITIONAL_SET_FLAG(emu->res.u16 & 0x1, F_CF);
             break;
         case d_rol32:
-            if(emu->op2.u32 == 1) {
+            if(BOX64ENV(cputype))
                 CONDITIONAL_SET_FLAG((emu->res.u32 + (emu->res.u32 >> 31)) & 1, F_OF);
-            }
+            else
+                CONDITIONAL_SET_FLAG(XOR2(emu->op1.u32>>30), F_OF);
             CONDITIONAL_SET_FLAG(emu->res.u32 & 0x1, F_CF);
             break;
         case d_rol64:
-            if(emu->op2.u64 == 1) {
+            if(BOX64ENV(cputype))
                 CONDITIONAL_SET_FLAG((emu->res.u64 + (emu->res.u64 >> 63)) & 1, F_OF);
-            }
+            else
+                CONDITIONAL_SET_FLAG(XOR2(emu->op1.u64>>62), F_OF);
             CONDITIONAL_SET_FLAG(emu->res.u64 & 0x1, F_CF);
             break;
         case d_ror8:
-            if(emu->op2.u8 == 1) {
+            if(BOX64ENV(cputype))
                 CONDITIONAL_SET_FLAG(XOR2(emu->res.u8 >> 6), F_OF);
-            }
+            else
+                CONDITIONAL_SET_FLAG(((emu->op1.u8 >> 7)^emu->op1.u8)&1, F_OF);
             CONDITIONAL_SET_FLAG(emu->res.u8 & (1 << 7), F_CF);
             break;
         case d_ror16:
-            if(emu->op2.u16 == 1) {
+            if(BOX64ENV(cputype))
                 CONDITIONAL_SET_FLAG(XOR2(emu->res.u16 >> 14), F_OF);
-            }
+            else
+                CONDITIONAL_SET_FLAG(((emu->op1.u16 >> 15)^emu->op1.u16)&1, F_OF);
             CONDITIONAL_SET_FLAG(emu->res.u16 & (1 << 15), F_CF);
             break;
         case d_ror32:
-            if(emu->op2.u32 == 1) {
+            if(BOX64ENV(cputype))
                 CONDITIONAL_SET_FLAG(XOR2(emu->res.u32 >> 30), F_OF);
-            }
+            else
+                CONDITIONAL_SET_FLAG(((emu->op1.u32 >> 31)^emu->op1.u32)&1, F_OF);
             CONDITIONAL_SET_FLAG(emu->res.u32 & (1 << 31), F_CF);
             break;
         case d_ror64:
-            if(emu->op2.u64 == 1) {
+            if(BOX64ENV(cputype))
                 CONDITIONAL_SET_FLAG(XOR2(emu->res.u64 >> 62), F_OF);
-            }
+            else
+                CONDITIONAL_SET_FLAG(((emu->op1.u64 >> 63)^emu->op1.u64)&1, F_OF);
             CONDITIONAL_SET_FLAG(emu->res.u64 & (1L << 63), F_CF);
             break;