From 6c7b746bf98bc3c2f11dcf9c11f5dcac4626bb0e Mon Sep 17 00:00:00 2001 From: TomW Date: Fri, 15 Nov 2013 19:55:22 +0000 Subject: [PATCH] Fixed lazy V flag on SHL/SHR/SAR - IBM AT & Acer 386 BIOSes work again. --- src/x86_flags.h | 78 ++++++- src/x86_ops_shift.h | 549 ++++++++++++++++++++++---------------------- 2 files changed, 351 insertions(+), 276 deletions(-) diff --git a/src/x86_flags.h b/src/x86_flags.h index 391c901..61fe0c9 100644 --- a/src/x86_flags.h +++ b/src/x86_flags.h @@ -12,7 +12,19 @@ enum FLAGS_SUB8, FLAGS_SUB16, - FLAGS_SUB32 + FLAGS_SUB32, + + FLAGS_SHL8, + FLAGS_SHL16, + FLAGS_SHL32, + + FLAGS_SHR8, + FLAGS_SHR16, + FLAGS_SHR32, + + FLAGS_SAR8, + FLAGS_SAR16, + FLAGS_SAR32, }; static int flags_op; @@ -32,6 +44,15 @@ static inline int ZF_SET() case FLAGS_SUB8: case FLAGS_SUB16: case FLAGS_SUB32: + case FLAGS_SHL8: + case FLAGS_SHL16: + case FLAGS_SHL32: + case FLAGS_SHR8: + case FLAGS_SHR16: + case FLAGS_SHR32: + case FLAGS_SAR8: + case FLAGS_SAR16: + case FLAGS_SAR32: return !flags_res; case FLAGS_UNKNOWN: @@ -46,16 +67,25 @@ static inline int NF_SET() case FLAGS_ZN8: case FLAGS_ADD8: case FLAGS_SUB8: + case FLAGS_SHL8: + case FLAGS_SHR8: + case FLAGS_SAR8: return flags_res & 0x80; case FLAGS_ZN16: case FLAGS_ADD16: case FLAGS_SUB16: + case FLAGS_SHL16: + case FLAGS_SHR16: + case FLAGS_SAR16: return flags_res & 0x8000; case FLAGS_ZN32: case FLAGS_ADD32: case FLAGS_SUB32: + case FLAGS_SHL32: + case FLAGS_SHR32: + case FLAGS_SAR32: return flags_res & 0x80000000; case FLAGS_UNKNOWN: @@ -76,6 +106,15 @@ static inline int PF_SET() case FLAGS_SUB8: case FLAGS_SUB16: case FLAGS_SUB32: + case FLAGS_SHL8: + case FLAGS_SHL16: + case FLAGS_SHL32: + case FLAGS_SHR8: + case FLAGS_SHR16: + case FLAGS_SHR32: + case FLAGS_SAR8: + case FLAGS_SAR16: + case FLAGS_SAR32: return znptable8[flags_res & 0xff] & P_FLAG; case FLAGS_UNKNOWN: @@ -87,9 +126,12 @@ static inline int VF_SET() { switch (flags_op) { - case FLAGS_ZN8: + case FLAGS_ZN8: case FLAGS_ZN16: case FLAGS_ZN32: + case FLAGS_SAR8: + case FLAGS_SAR16: + case FLAGS_SAR32: return 0; case FLAGS_ADD8: @@ -105,7 +147,21 @@ static inline int VF_SET() return ((flags_op1 ^ flags_op2) & (flags_op1 ^ flags_res) & 0x8000); case FLAGS_SUB32: return ((flags_op1 ^ flags_op2) & (flags_op1 ^ flags_res) & 0x80000000); - + + case FLAGS_SHL8: + return (((flags_op1 << flags_op2) ^ (flags_op1 << (flags_op2 - 1))) & 0x80); + case FLAGS_SHL16: + return (((flags_op1 << flags_op2) ^ (flags_op1 << (flags_op2 - 1))) & 0x8000); + case FLAGS_SHL32: + return (((flags_op1 << flags_op2) ^ (flags_op1 << (flags_op2 - 1))) & 0x80000000); + + case FLAGS_SHR8: + return ((flags_op2 == 1) && (flags_op1 & 0x80)); + case FLAGS_SHR16: + return ((flags_op2 == 1) && (flags_op1 & 0x8000)); + case FLAGS_SHR32: + return ((flags_op2 == 1) && (flags_op1 & 0x80000000)); + case FLAGS_UNKNOWN: return flags & V_FLAG; } @@ -118,6 +174,15 @@ static inline int AF_SET() case FLAGS_ZN8: case FLAGS_ZN16: case FLAGS_ZN32: + case FLAGS_SHL8: + case FLAGS_SHL16: + case FLAGS_SHL32: + case FLAGS_SHR8: + case FLAGS_SHR16: + case FLAGS_SHR32: + case FLAGS_SAR8: + case FLAGS_SAR16: + case FLAGS_SAR32: return 0; case FLAGS_ADD8: @@ -214,6 +279,13 @@ static inline void setznp32(uint32_t val) flags &= ~C_FLAG; } +#define set_flags_shift(op, orig, shift, res) \ + flags_op = op; \ + flags_res = res; \ + flags_op1 = orig; \ + flags_op2 = shift; \ + flags &= ~C_FLAG; + static inline void setadd8(uint8_t a, uint8_t b) { flags_op1 = a; diff --git a/src/x86_ops_shift.h b/src/x86_ops_shift.h index 953550c..6f1eed6 100644 --- a/src/x86_ops_shift.h +++ b/src/x86_ops_shift.h @@ -1,280 +1,283 @@ -#define OP_SHIFT_b(c) \ - if (!c) return 0; \ - flags_rebuild(); \ - switch (rmdat & 0x38) \ - { \ - case 0x00: /*ROL b, c*/ \ - while (c > 0) \ - { \ - temp2 = (temp & 0x80) ? 1 : 0; \ - temp = (temp << 1) | temp2; \ - c--; \ - } \ - seteab(temp); if (abrt) return 0; \ - flags &= ~(C_FLAG | V_FLAG); \ - if (temp2) flags |= C_FLAG; \ - if ((flags & C_FLAG) ^ (temp >> 7)) flags |= V_FLAG; \ - cycles -= ((mod == 3) ? 3 : 7); \ - break; \ - case 0x08: /*ROR b,CL*/ \ - while (c > 0) \ - { \ - temp2 = temp & 1; \ - temp >>= 1; \ - if (temp2) temp |= 0x80; \ - c--; \ - } \ - seteab(temp); if (abrt) return 0; \ - flags &= ~(C_FLAG | V_FLAG); \ - if (temp2) flags |= C_FLAG; \ - if ((temp ^ (temp >> 1)) & 0x40) flags |= V_FLAG; \ - cycles -= ((mod == 3) ? 3 : 7); \ - break; \ - case 0x10: /*RCL b,CL*/ \ - temp2 = flags & C_FLAG; \ - while (c > 0) \ - { \ - tempc = temp2 ? 1 : 0; \ - temp2 = temp & 0x80; \ - temp = (temp << 1) | tempc; \ - c--; \ - if (is486) cycles--; \ - } \ - seteab(temp); if (abrt) return 0; \ - flags &= ~(C_FLAG | V_FLAG); \ - if (temp2) flags |= C_FLAG; \ - if ((flags & C_FLAG) ^ (temp >> 7)) flags |= V_FLAG; \ - cycles -= ((mod == 3) ? 9 : 10); \ - break; \ - case 0x18: /*RCR b,CL*/ \ - temp2 = flags & C_FLAG; \ - while (c > 0) \ - { \ - tempc = temp2 ? 0x80 : 0; \ - temp2 = temp & 1; \ - temp = (temp >> 1) | tempc; \ - c--; \ - if (is486) cycles--; \ - } \ - seteab(temp); if (abrt) return 0; \ - flags &= ~(C_FLAG | V_FLAG); \ - if (temp2) flags |= C_FLAG; \ - if ((temp ^ (temp >> 1)) & 0x40) flags |= V_FLAG; \ - cycles -= ((mod == 3) ? 9 : 10); \ - break; \ - case 0x20: case 0x30: /*SHL b,CL*/ \ - seteab(temp << c); if (abrt) return 0; \ - setznp8(temp << c); \ - if ((temp << (c - 1)) & 0x80) flags |= C_FLAG; \ - if (((temp << c) ^ (temp << (c - 1))) & 0x80) flags |= V_FLAG; \ - cycles -= ((mod == 3) ? 3 : 7); \ - break; \ - case 0x28: /*SHR b,CL*/ \ - seteab(temp >> c); if (abrt) return 0; \ - setznp8(temp >> c); \ - if ((temp >> (c - 1)) & 1) flags |= C_FLAG; \ - if (c == 1 && temp & 0x80) flags |= V_FLAG; \ - cycles -= ((mod == 3) ? 3 : 7); \ - break; \ - case 0x38: /*SAR b,CL*/ \ - tempc = ((temp >> (c - 1)) & 1); \ - while (c > 0) \ - { \ - temp >>= 1; \ - if (temp & 0x40) temp |= 0x80; \ - c--; \ - } \ - seteab(temp); if (abrt) return 0; \ - setznp8(temp); \ - if (tempc) flags |= C_FLAG; \ - cycles -= ((mod == 3) ? 3 : 7); \ - break; \ +#define OP_SHIFT_b(c) \ + { \ + uint8_t temp_orig = temp; \ + if (!c) return 0; \ + flags_rebuild(); \ + switch (rmdat & 0x38) \ + { \ + case 0x00: /*ROL b, c*/ \ + while (c > 0) \ + { \ + temp2 = (temp & 0x80) ? 1 : 0; \ + temp = (temp << 1) | temp2; \ + c--; \ + } \ + seteab(temp); if (abrt) return 0; \ + flags &= ~(C_FLAG | V_FLAG); \ + if (temp2) flags |= C_FLAG; \ + if ((flags & C_FLAG) ^ (temp >> 7)) flags |= V_FLAG; \ + cycles -= ((mod == 3) ? 3 : 7); \ + break; \ + case 0x08: /*ROR b,CL*/ \ + while (c > 0) \ + { \ + temp2 = temp & 1; \ + temp >>= 1; \ + if (temp2) temp |= 0x80; \ + c--; \ + } \ + seteab(temp); if (abrt) return 0; \ + flags &= ~(C_FLAG | V_FLAG); \ + if (temp2) flags |= C_FLAG; \ + if ((temp ^ (temp >> 1)) & 0x40) flags |= V_FLAG; \ + cycles -= ((mod == 3) ? 3 : 7); \ + break; \ + case 0x10: /*RCL b,CL*/ \ + temp2 = flags & C_FLAG; \ + while (c > 0) \ + { \ + tempc = temp2 ? 1 : 0; \ + temp2 = temp & 0x80; \ + temp = (temp << 1) | tempc; \ + c--; \ + if (is486) cycles--; \ + } \ + seteab(temp); if (abrt) return 0; \ + flags &= ~(C_FLAG | V_FLAG); \ + if (temp2) flags |= C_FLAG; \ + if ((flags & C_FLAG) ^ (temp >> 7)) flags |= V_FLAG; \ + cycles -= ((mod == 3) ? 9 : 10); \ + break; \ + case 0x18: /*RCR b,CL*/ \ + temp2 = flags & C_FLAG; \ + while (c > 0) \ + { \ + tempc = temp2 ? 0x80 : 0; \ + temp2 = temp & 1; \ + temp = (temp >> 1) | tempc; \ + c--; \ + if (is486) cycles--; \ + } \ + seteab(temp); if (abrt) return 0; \ + flags &= ~(C_FLAG | V_FLAG); \ + if (temp2) flags |= C_FLAG; \ + if ((temp ^ (temp >> 1)) & 0x40) flags |= V_FLAG; \ + cycles -= ((mod == 3) ? 9 : 10); \ + break; \ + case 0x20: case 0x30: /*SHL b,CL*/ \ + seteab(temp << c); if (abrt) return 0; \ + set_flags_shift(FLAGS_SHL8, temp_orig, c, temp << c); \ + if ((temp << (c - 1)) & 0x80) flags |= C_FLAG; \ + cycles -= ((mod == 3) ? 3 : 7); \ + break; \ + case 0x28: /*SHR b,CL*/ \ + seteab(temp >> c); if (abrt) return 0; \ + set_flags_shift(FLAGS_SHR8, temp_orig, c, temp >> c); \ + if ((temp >> (c - 1)) & 1) flags |= C_FLAG; \ + cycles -= ((mod == 3) ? 3 : 7); \ + break; \ + case 0x38: /*SAR b,CL*/ \ + tempc = ((temp >> (c - 1)) & 1); \ + while (c > 0) \ + { \ + temp >>= 1; \ + if (temp & 0x40) temp |= 0x80; \ + c--; \ + } \ + seteab(temp); if (abrt) return 0; \ + set_flags_shift(FLAGS_SAR8, temp_orig, c, temp); \ + if (tempc) flags |= C_FLAG; \ + cycles -= ((mod == 3) ? 3 : 7); \ + break; \ + } \ } -#define OP_SHIFT_w(c) \ - if (!c) return 0; \ - flags_rebuild(); \ - switch (rmdat & 0x38) \ - { \ - case 0x00: /*ROL w, c*/ \ - while (c > 0) \ - { \ - temp2 = (temp & 0x8000) ? 1 : 0; \ - temp = (temp << 1) | temp2; \ - c--; \ - } \ - seteaw(temp); if (abrt) return 0; \ - flags &= ~(C_FLAG | V_FLAG); \ - if (temp2) flags |= C_FLAG; \ - if ((flags & C_FLAG) ^ (temp >> 15)) flags |= V_FLAG; \ - cycles -= ((mod == 3) ? 3 : 7); \ - break; \ - case 0x08: /*ROR w, c*/ \ - while (c > 0) \ - { \ - temp2 = temp & 1; \ - temp >>= 1; \ - if (temp2) temp |= 0x8000; \ - c--; \ - } \ - seteaw(temp); if (abrt) return 0; \ - flags &= ~(C_FLAG | V_FLAG); \ - if (temp2) flags |= C_FLAG; \ - if ((temp ^ (temp >> 1)) & 0x4000) flags |= V_FLAG; \ - cycles -= ((mod == 3) ? 3 : 7); \ - break; \ - case 0x10: /*RCL w, c*/ \ - temp2 = flags & C_FLAG; \ - while (c > 0) \ - { \ - tempc = temp2 ? 1 : 0; \ - temp2 = temp & 0x8000; \ - temp = (temp << 1) | tempc; \ - c--; \ - if (is486) cycles--; \ - } \ - seteaw(temp); if (abrt) return 0; \ - flags &= ~(C_FLAG | V_FLAG); \ - if (temp2) flags |= C_FLAG; \ - if ((flags & C_FLAG) ^ (temp >> 15)) flags |= V_FLAG; \ - cycles -= ((mod == 3) ? 9 : 10); \ - break; \ - case 0x18: /*RCR w, c*/ \ - temp2 = flags & C_FLAG; \ - while (c > 0) \ - { \ - tempc = temp2 ? 0x8000 : 0; \ - temp2 = temp & 1; \ - temp = (temp >> 1) | tempc; \ - c--; \ - if (is486) cycles--; \ - } \ - seteaw(temp); if (abrt) return 0; \ - flags &= ~(C_FLAG | V_FLAG); \ - if (temp2) flags |= C_FLAG; \ - if ((temp ^ (temp >> 1)) & 0x4000) flags |= V_FLAG; \ - cycles -= ((mod == 3) ? 9 : 10); \ - break; \ - case 0x20: case 0x30: /*SHL w, c*/ \ - seteaw(temp << c); if (abrt) return 0; \ - setznp16(temp << c); \ - if ((temp << (c - 1)) & 0x8000) flags |= C_FLAG; \ - if (((temp << c) ^ (temp << (c - 1))) & 0x8000) flags |= V_FLAG;\ - cycles -= ((mod == 3) ? 3 : 7); \ - break; \ - case 0x28: /*SHR w, c*/ \ - seteaw(temp >> c); if (abrt) return 0; \ - setznp16(temp >> c); \ - if ((temp >> (c - 1)) & 1) flags |= C_FLAG; \ - if (c == 1 && temp & 0x8000) flags |= V_FLAG; \ - cycles -= ((mod == 3) ? 3 : 7); \ - break; \ - case 0x38: /*SAR w, c*/ \ - tempc = ((temp >> (c - 1)) & 1); \ - while (c > 0) \ - { \ - temp >>= 1; \ - if (temp & 0x4000) temp |= 0x8000; \ - c--; \ - } \ - seteaw(temp); if (abrt) return 0; \ - setznp16(temp); \ - if (tempc) flags |= C_FLAG; \ - cycles -= ((mod == 3) ? 3 : 7); \ - break; \ +#define OP_SHIFT_w(c) \ + { \ + uint16_t temp_orig = temp; \ + if (!c) return 0; \ + flags_rebuild(); \ + switch (rmdat & 0x38) \ + { \ + case 0x00: /*ROL w, c*/ \ + while (c > 0) \ + { \ + temp2 = (temp & 0x8000) ? 1 : 0; \ + temp = (temp << 1) | temp2; \ + c--; \ + } \ + seteaw(temp); if (abrt) return 0; \ + flags &= ~(C_FLAG | V_FLAG); \ + if (temp2) flags |= C_FLAG; \ + if ((flags & C_FLAG) ^ (temp >> 15)) flags |= V_FLAG; \ + cycles -= ((mod == 3) ? 3 : 7); \ + break; \ + case 0x08: /*ROR w, c*/ \ + while (c > 0) \ + { \ + temp2 = temp & 1; \ + temp >>= 1; \ + if (temp2) temp |= 0x8000; \ + c--; \ + } \ + seteaw(temp); if (abrt) return 0; \ + flags &= ~(C_FLAG | V_FLAG); \ + if (temp2) flags |= C_FLAG; \ + if ((temp ^ (temp >> 1)) & 0x4000) flags |= V_FLAG; \ + cycles -= ((mod == 3) ? 3 : 7); \ + break; \ + case 0x10: /*RCL w, c*/ \ + temp2 = flags & C_FLAG; \ + while (c > 0) \ + { \ + tempc = temp2 ? 1 : 0; \ + temp2 = temp & 0x8000; \ + temp = (temp << 1) | tempc; \ + c--; \ + if (is486) cycles--; \ + } \ + seteaw(temp); if (abrt) return 0; \ + flags &= ~(C_FLAG | V_FLAG); \ + if (temp2) flags |= C_FLAG; \ + if ((flags & C_FLAG) ^ (temp >> 15)) flags |= V_FLAG; \ + cycles -= ((mod == 3) ? 9 : 10); \ + break; \ + case 0x18: /*RCR w, c*/ \ + temp2 = flags & C_FLAG; \ + while (c > 0) \ + { \ + tempc = temp2 ? 0x8000 : 0; \ + temp2 = temp & 1; \ + temp = (temp >> 1) | tempc; \ + c--; \ + if (is486) cycles--; \ + } \ + seteaw(temp); if (abrt) return 0; \ + flags &= ~(C_FLAG | V_FLAG); \ + if (temp2) flags |= C_FLAG; \ + if ((temp ^ (temp >> 1)) & 0x4000) flags |= V_FLAG; \ + cycles -= ((mod == 3) ? 9 : 10); \ + break; \ + case 0x20: case 0x30: /*SHL w, c*/ \ + seteaw(temp << c); if (abrt) return 0; \ + set_flags_shift(FLAGS_SHL16, temp_orig, c, temp << c); \ + if ((temp << (c - 1)) & 0x8000) flags |= C_FLAG; \ + cycles -= ((mod == 3) ? 3 : 7); \ + break; \ + case 0x28: /*SHR w, c*/ \ + seteaw(temp >> c); if (abrt) return 0; \ + set_flags_shift(FLAGS_SHR16, temp_orig, c, temp >> c); \ + if ((temp >> (c - 1)) & 1) flags |= C_FLAG; \ + cycles -= ((mod == 3) ? 3 : 7); \ + break; \ + case 0x38: /*SAR w, c*/ \ + tempc = ((temp >> (c - 1)) & 1); \ + while (c > 0) \ + { \ + temp >>= 1; \ + if (temp & 0x4000) temp |= 0x8000; \ + c--; \ + } \ + seteaw(temp); if (abrt) return 0; \ + set_flags_shift(FLAGS_SAR16, temp_orig, c, temp); \ + if (tempc) flags |= C_FLAG; \ + cycles -= ((mod == 3) ? 3 : 7); \ + break; \ + } \ } -#define OP_SHIFT_l(c) \ - if (!c) return 0; \ - flags_rebuild(); \ - switch (rmdat & 0x38) \ - { \ - case 0x00: /*ROL l, c*/ \ - while (c > 0) \ - { \ - temp2 = (temp & 0x80000000) ? 1 : 0; \ - temp = (temp << 1) | temp2; \ - c--; \ - } \ - seteal(temp); if (abrt) return 0; \ - flags &= ~(C_FLAG | V_FLAG); \ - if (temp2) flags |= C_FLAG; \ - if ((flags & C_FLAG) ^ (temp >> 31)) flags |= V_FLAG; \ - cycles -= ((mod == 3) ? 3 : 7); \ - break; \ - case 0x08: /*ROR l, c*/ \ - while (c > 0) \ - { \ - temp2 = temp & 1; \ - temp >>= 1; \ - if (temp2) temp |= 0x80000000; \ - c--; \ - } \ - seteal(temp); if (abrt) return 0; \ - flags &= ~(C_FLAG | V_FLAG); \ - if (temp2) flags |= C_FLAG; \ - if ((temp ^ (temp >> 1)) & 0x40000000) flags |= V_FLAG; \ - cycles -= ((mod == 3) ? 3 : 7); \ - break; \ - case 0x10: /*RCL l, c*/ \ - temp2 = flags & C_FLAG; \ - while (c > 0) \ - { \ - tempc = temp2 ? 1 : 0; \ - temp2 = temp & 0x80000000; \ - temp = (temp << 1) | tempc; \ - c--; \ - if (is486) cycles--; \ - } \ - seteal(temp); if (abrt) return 0; \ - flags &= ~(C_FLAG | V_FLAG); \ - if (temp2) flags |= C_FLAG; \ - if ((flags & C_FLAG) ^ (temp >> 31)) flags |= V_FLAG; \ - cycles -= ((mod == 3) ? 9 : 10); \ - break; \ - case 0x18: /*RCR l, c*/ \ - temp2 = flags & C_FLAG; \ - while (c > 0) \ - { \ - tempc = temp2 ? 0x80000000 : 0; \ - temp2 = temp & 1; \ - temp = (temp >> 1) | tempc; \ - c--; \ - if (is486) cycles--; \ - } \ - seteal(temp); if (abrt) return 0; \ - flags &= ~(C_FLAG | V_FLAG); \ - if (temp2) flags |= C_FLAG; \ - if ((temp ^ (temp >> 1)) & 0x40000000) flags |= V_FLAG; \ - cycles -= ((mod == 3) ? 9 : 10); \ - break; \ - case 0x20: case 0x30: /*SHL l, c*/ \ - seteal(temp << c); if (abrt) return 0; \ - setznp32(temp << c); \ - if ((temp << (c - 1)) & 0x80000000) flags |= C_FLAG; \ - if (((temp << c) ^ (temp << (c - 1))) & 0x80000000) flags |= V_FLAG;\ - cycles -= ((mod == 3) ? 3 : 7); \ - break; \ - case 0x28: /*SHR l, c*/ \ - seteal(temp >> c); if (abrt) return 0; \ - setznp32(temp >> c); \ - if ((temp >> (c - 1)) & 1) flags |= C_FLAG; \ - if (c == 1 && temp & 0x80000000) flags |= V_FLAG; \ - cycles -= ((mod == 3) ? 3 : 7); \ - break; \ - case 0x38: /*SAR l, c*/ \ - tempc = ((temp >> (c - 1)) & 1); \ - while (c > 0) \ - { \ - temp >>= 1; \ - if (temp & 0x40000000) temp |= 0x80000000; \ - c--; \ - } \ - seteal(temp); if (abrt) return 0; \ - setznp32(temp); \ - if (tempc) flags |= C_FLAG; \ - cycles -= ((mod == 3) ? 3 : 7); \ - break; \ +#define OP_SHIFT_l(c) \ + { \ + uint32_t temp_orig = temp; \ + if (!c) return 0; \ + flags_rebuild(); \ + switch (rmdat & 0x38) \ + { \ + case 0x00: /*ROL l, c*/ \ + while (c > 0) \ + { \ + temp2 = (temp & 0x80000000) ? 1 : 0; \ + temp = (temp << 1) | temp2; \ + c--; \ + } \ + seteal(temp); if (abrt) return 0; \ + flags &= ~(C_FLAG | V_FLAG); \ + if (temp2) flags |= C_FLAG; \ + if ((flags & C_FLAG) ^ (temp >> 31)) flags |= V_FLAG; \ + cycles -= ((mod == 3) ? 3 : 7); \ + break; \ + case 0x08: /*ROR l, c*/ \ + while (c > 0) \ + { \ + temp2 = temp & 1; \ + temp >>= 1; \ + if (temp2) temp |= 0x80000000; \ + c--; \ + } \ + seteal(temp); if (abrt) return 0; \ + flags &= ~(C_FLAG | V_FLAG); \ + if (temp2) flags |= C_FLAG; \ + if ((temp ^ (temp >> 1)) & 0x40000000) flags |= V_FLAG; \ + cycles -= ((mod == 3) ? 3 : 7); \ + break; \ + case 0x10: /*RCL l, c*/ \ + temp2 = flags & C_FLAG; \ + while (c > 0) \ + { \ + tempc = temp2 ? 1 : 0; \ + temp2 = temp & 0x80000000; \ + temp = (temp << 1) | tempc; \ + c--; \ + if (is486) cycles--; \ + } \ + seteal(temp); if (abrt) return 0; \ + flags &= ~(C_FLAG | V_FLAG); \ + if (temp2) flags |= C_FLAG; \ + if ((flags & C_FLAG) ^ (temp >> 31)) flags |= V_FLAG; \ + cycles -= ((mod == 3) ? 9 : 10); \ + break; \ + case 0x18: /*RCR l, c*/ \ + temp2 = flags & C_FLAG; \ + while (c > 0) \ + { \ + tempc = temp2 ? 0x80000000 : 0; \ + temp2 = temp & 1; \ + temp = (temp >> 1) | tempc; \ + c--; \ + if (is486) cycles--; \ + } \ + seteal(temp); if (abrt) return 0; \ + flags &= ~(C_FLAG | V_FLAG); \ + if (temp2) flags |= C_FLAG; \ + if ((temp ^ (temp >> 1)) & 0x40000000) flags |= V_FLAG; \ + cycles -= ((mod == 3) ? 9 : 10); \ + break; \ + case 0x20: case 0x30: /*SHL l, c*/ \ + seteal(temp << c); if (abrt) return 0; \ + set_flags_shift(FLAGS_SHL32, temp_orig, c, temp << c); \ + if ((temp << (c - 1)) & 0x80000000) flags |= C_FLAG; \ + cycles -= ((mod == 3) ? 3 : 7); \ + break; \ + case 0x28: /*SHR l, c*/ \ + seteal(temp >> c); if (abrt) return 0; \ + set_flags_shift(FLAGS_SHR32, temp_orig, c, temp >> c); \ + if ((temp >> (c - 1)) & 1) flags |= C_FLAG; \ + cycles -= ((mod == 3) ? 3 : 7); \ + break; \ + case 0x38: /*SAR l, c*/ \ + tempc = ((temp >> (c - 1)) & 1); \ + while (c > 0) \ + { \ + temp >>= 1; \ + if (temp & 0x40000000) temp |= 0x80000000; \ + c--; \ + } \ + seteal(temp); if (abrt) return 0; \ + set_flags_shift(FLAGS_SAR32, temp_orig, c, temp); \ + if (tempc) flags |= C_FLAG; \ + cycles -= ((mod == 3) ? 3 : 7); \ + break; \ + } \ } static int opC0_a16(uint32_t fetchdat)