PCem
changeset 37:bea391e61690
Fixed lazy V flag on SHL/SHR/SAR - IBM AT & Acer 386 BIOSes work again.
| author | TomW |
|---|---|
| date | Fri Nov 15 19:55:22 2013 +0000 |
| parents | 3150e4f3c1a3 |
| children | 79cd603440f9 |
| files | src/x86_flags.h src/x86_ops_shift.h |
| diffstat | 2 files changed, 351 insertions(+), 276 deletions(-) [+] |
line diff
1.1 --- a/src/x86_flags.h Sun Nov 10 16:40:52 2013 +0000 1.2 +++ b/src/x86_flags.h Fri Nov 15 19:55:22 2013 +0000 1.3 @@ -12,7 +12,19 @@ 1.4 1.5 FLAGS_SUB8, 1.6 FLAGS_SUB16, 1.7 - FLAGS_SUB32 1.8 + FLAGS_SUB32, 1.9 + 1.10 + FLAGS_SHL8, 1.11 + FLAGS_SHL16, 1.12 + FLAGS_SHL32, 1.13 + 1.14 + FLAGS_SHR8, 1.15 + FLAGS_SHR16, 1.16 + FLAGS_SHR32, 1.17 + 1.18 + FLAGS_SAR8, 1.19 + FLAGS_SAR16, 1.20 + FLAGS_SAR32, 1.21 }; 1.22 1.23 static int flags_op; 1.24 @@ -32,6 +44,15 @@ 1.25 case FLAGS_SUB8: 1.26 case FLAGS_SUB16: 1.27 case FLAGS_SUB32: 1.28 + case FLAGS_SHL8: 1.29 + case FLAGS_SHL16: 1.30 + case FLAGS_SHL32: 1.31 + case FLAGS_SHR8: 1.32 + case FLAGS_SHR16: 1.33 + case FLAGS_SHR32: 1.34 + case FLAGS_SAR8: 1.35 + case FLAGS_SAR16: 1.36 + case FLAGS_SAR32: 1.37 return !flags_res; 1.38 1.39 case FLAGS_UNKNOWN: 1.40 @@ -46,16 +67,25 @@ 1.41 case FLAGS_ZN8: 1.42 case FLAGS_ADD8: 1.43 case FLAGS_SUB8: 1.44 + case FLAGS_SHL8: 1.45 + case FLAGS_SHR8: 1.46 + case FLAGS_SAR8: 1.47 return flags_res & 0x80; 1.48 1.49 case FLAGS_ZN16: 1.50 case FLAGS_ADD16: 1.51 case FLAGS_SUB16: 1.52 + case FLAGS_SHL16: 1.53 + case FLAGS_SHR16: 1.54 + case FLAGS_SAR16: 1.55 return flags_res & 0x8000; 1.56 1.57 case FLAGS_ZN32: 1.58 case FLAGS_ADD32: 1.59 case FLAGS_SUB32: 1.60 + case FLAGS_SHL32: 1.61 + case FLAGS_SHR32: 1.62 + case FLAGS_SAR32: 1.63 return flags_res & 0x80000000; 1.64 1.65 case FLAGS_UNKNOWN: 1.66 @@ -76,6 +106,15 @@ 1.67 case FLAGS_SUB8: 1.68 case FLAGS_SUB16: 1.69 case FLAGS_SUB32: 1.70 + case FLAGS_SHL8: 1.71 + case FLAGS_SHL16: 1.72 + case FLAGS_SHL32: 1.73 + case FLAGS_SHR8: 1.74 + case FLAGS_SHR16: 1.75 + case FLAGS_SHR32: 1.76 + case FLAGS_SAR8: 1.77 + case FLAGS_SAR16: 1.78 + case FLAGS_SAR32: 1.79 return znptable8[flags_res & 0xff] & P_FLAG; 1.80 1.81 case FLAGS_UNKNOWN: 1.82 @@ -87,9 +126,12 @@ 1.83 { 1.84 switch (flags_op) 1.85 { 1.86 - case FLAGS_ZN8: 1.87 + case FLAGS_ZN8: 1.88 case FLAGS_ZN16: 1.89 case FLAGS_ZN32: 1.90 + case FLAGS_SAR8: 1.91 + case FLAGS_SAR16: 1.92 + case FLAGS_SAR32: 1.93 return 0; 1.94 1.95 case FLAGS_ADD8: 1.96 @@ -105,7 +147,21 @@ 1.97 return ((flags_op1 ^ flags_op2) & (flags_op1 ^ flags_res) & 0x8000); 1.98 case FLAGS_SUB32: 1.99 return ((flags_op1 ^ flags_op2) & (flags_op1 ^ flags_res) & 0x80000000); 1.100 - 1.101 + 1.102 + case FLAGS_SHL8: 1.103 + return (((flags_op1 << flags_op2) ^ (flags_op1 << (flags_op2 - 1))) & 0x80); 1.104 + case FLAGS_SHL16: 1.105 + return (((flags_op1 << flags_op2) ^ (flags_op1 << (flags_op2 - 1))) & 0x8000); 1.106 + case FLAGS_SHL32: 1.107 + return (((flags_op1 << flags_op2) ^ (flags_op1 << (flags_op2 - 1))) & 0x80000000); 1.108 + 1.109 + case FLAGS_SHR8: 1.110 + return ((flags_op2 == 1) && (flags_op1 & 0x80)); 1.111 + case FLAGS_SHR16: 1.112 + return ((flags_op2 == 1) && (flags_op1 & 0x8000)); 1.113 + case FLAGS_SHR32: 1.114 + return ((flags_op2 == 1) && (flags_op1 & 0x80000000)); 1.115 + 1.116 case FLAGS_UNKNOWN: 1.117 return flags & V_FLAG; 1.118 } 1.119 @@ -118,6 +174,15 @@ 1.120 case FLAGS_ZN8: 1.121 case FLAGS_ZN16: 1.122 case FLAGS_ZN32: 1.123 + case FLAGS_SHL8: 1.124 + case FLAGS_SHL16: 1.125 + case FLAGS_SHL32: 1.126 + case FLAGS_SHR8: 1.127 + case FLAGS_SHR16: 1.128 + case FLAGS_SHR32: 1.129 + case FLAGS_SAR8: 1.130 + case FLAGS_SAR16: 1.131 + case FLAGS_SAR32: 1.132 return 0; 1.133 1.134 case FLAGS_ADD8: 1.135 @@ -214,6 +279,13 @@ 1.136 flags &= ~C_FLAG; 1.137 } 1.138 1.139 +#define set_flags_shift(op, orig, shift, res) \ 1.140 + flags_op = op; \ 1.141 + flags_res = res; \ 1.142 + flags_op1 = orig; \ 1.143 + flags_op2 = shift; \ 1.144 + flags &= ~C_FLAG; 1.145 + 1.146 static inline void setadd8(uint8_t a, uint8_t b) 1.147 { 1.148 flags_op1 = a;
2.1 --- a/src/x86_ops_shift.h Sun Nov 10 16:40:52 2013 +0000 2.2 +++ b/src/x86_ops_shift.h Fri Nov 15 19:55:22 2013 +0000 2.3 @@ -1,280 +1,283 @@ 2.4 -#define OP_SHIFT_b(c) \ 2.5 - if (!c) return 0; \ 2.6 - flags_rebuild(); \ 2.7 - switch (rmdat & 0x38) \ 2.8 - { \ 2.9 - case 0x00: /*ROL b, c*/ \ 2.10 - while (c > 0) \ 2.11 - { \ 2.12 - temp2 = (temp & 0x80) ? 1 : 0; \ 2.13 - temp = (temp << 1) | temp2; \ 2.14 - c--; \ 2.15 - } \ 2.16 - seteab(temp); if (abrt) return 0; \ 2.17 - flags &= ~(C_FLAG | V_FLAG); \ 2.18 - if (temp2) flags |= C_FLAG; \ 2.19 - if ((flags & C_FLAG) ^ (temp >> 7)) flags |= V_FLAG; \ 2.20 - cycles -= ((mod == 3) ? 3 : 7); \ 2.21 - break; \ 2.22 - case 0x08: /*ROR b,CL*/ \ 2.23 - while (c > 0) \ 2.24 - { \ 2.25 - temp2 = temp & 1; \ 2.26 - temp >>= 1; \ 2.27 - if (temp2) temp |= 0x80; \ 2.28 - c--; \ 2.29 - } \ 2.30 - seteab(temp); if (abrt) return 0; \ 2.31 - flags &= ~(C_FLAG | V_FLAG); \ 2.32 - if (temp2) flags |= C_FLAG; \ 2.33 - if ((temp ^ (temp >> 1)) & 0x40) flags |= V_FLAG; \ 2.34 - cycles -= ((mod == 3) ? 3 : 7); \ 2.35 - break; \ 2.36 - case 0x10: /*RCL b,CL*/ \ 2.37 - temp2 = flags & C_FLAG; \ 2.38 - while (c > 0) \ 2.39 - { \ 2.40 - tempc = temp2 ? 1 : 0; \ 2.41 - temp2 = temp & 0x80; \ 2.42 - temp = (temp << 1) | tempc; \ 2.43 - c--; \ 2.44 - if (is486) cycles--; \ 2.45 - } \ 2.46 - seteab(temp); if (abrt) return 0; \ 2.47 - flags &= ~(C_FLAG | V_FLAG); \ 2.48 - if (temp2) flags |= C_FLAG; \ 2.49 - if ((flags & C_FLAG) ^ (temp >> 7)) flags |= V_FLAG; \ 2.50 - cycles -= ((mod == 3) ? 9 : 10); \ 2.51 - break; \ 2.52 - case 0x18: /*RCR b,CL*/ \ 2.53 - temp2 = flags & C_FLAG; \ 2.54 - while (c > 0) \ 2.55 - { \ 2.56 - tempc = temp2 ? 0x80 : 0; \ 2.57 - temp2 = temp & 1; \ 2.58 - temp = (temp >> 1) | tempc; \ 2.59 - c--; \ 2.60 - if (is486) cycles--; \ 2.61 - } \ 2.62 - seteab(temp); if (abrt) return 0; \ 2.63 - flags &= ~(C_FLAG | V_FLAG); \ 2.64 - if (temp2) flags |= C_FLAG; \ 2.65 - if ((temp ^ (temp >> 1)) & 0x40) flags |= V_FLAG; \ 2.66 - cycles -= ((mod == 3) ? 9 : 10); \ 2.67 - break; \ 2.68 - case 0x20: case 0x30: /*SHL b,CL*/ \ 2.69 - seteab(temp << c); if (abrt) return 0; \ 2.70 - setznp8(temp << c); \ 2.71 - if ((temp << (c - 1)) & 0x80) flags |= C_FLAG; \ 2.72 - if (((temp << c) ^ (temp << (c - 1))) & 0x80) flags |= V_FLAG; \ 2.73 - cycles -= ((mod == 3) ? 3 : 7); \ 2.74 - break; \ 2.75 - case 0x28: /*SHR b,CL*/ \ 2.76 - seteab(temp >> c); if (abrt) return 0; \ 2.77 - setznp8(temp >> c); \ 2.78 - if ((temp >> (c - 1)) & 1) flags |= C_FLAG; \ 2.79 - if (c == 1 && temp & 0x80) flags |= V_FLAG; \ 2.80 - cycles -= ((mod == 3) ? 3 : 7); \ 2.81 - break; \ 2.82 - case 0x38: /*SAR b,CL*/ \ 2.83 - tempc = ((temp >> (c - 1)) & 1); \ 2.84 - while (c > 0) \ 2.85 - { \ 2.86 - temp >>= 1; \ 2.87 - if (temp & 0x40) temp |= 0x80; \ 2.88 - c--; \ 2.89 - } \ 2.90 - seteab(temp); if (abrt) return 0; \ 2.91 - setznp8(temp); \ 2.92 - if (tempc) flags |= C_FLAG; \ 2.93 - cycles -= ((mod == 3) ? 3 : 7); \ 2.94 - break; \ 2.95 +#define OP_SHIFT_b(c) \ 2.96 + { \ 2.97 + uint8_t temp_orig = temp; \ 2.98 + if (!c) return 0; \ 2.99 + flags_rebuild(); \ 2.100 + switch (rmdat & 0x38) \ 2.101 + { \ 2.102 + case 0x00: /*ROL b, c*/ \ 2.103 + while (c > 0) \ 2.104 + { \ 2.105 + temp2 = (temp & 0x80) ? 1 : 0; \ 2.106 + temp = (temp << 1) | temp2; \ 2.107 + c--; \ 2.108 + } \ 2.109 + seteab(temp); if (abrt) return 0; \ 2.110 + flags &= ~(C_FLAG | V_FLAG); \ 2.111 + if (temp2) flags |= C_FLAG; \ 2.112 + if ((flags & C_FLAG) ^ (temp >> 7)) flags |= V_FLAG; \ 2.113 + cycles -= ((mod == 3) ? 3 : 7); \ 2.114 + break; \ 2.115 + case 0x08: /*ROR b,CL*/ \ 2.116 + while (c > 0) \ 2.117 + { \ 2.118 + temp2 = temp & 1; \ 2.119 + temp >>= 1; \ 2.120 + if (temp2) temp |= 0x80; \ 2.121 + c--; \ 2.122 + } \ 2.123 + seteab(temp); if (abrt) return 0; \ 2.124 + flags &= ~(C_FLAG | V_FLAG); \ 2.125 + if (temp2) flags |= C_FLAG; \ 2.126 + if ((temp ^ (temp >> 1)) & 0x40) flags |= V_FLAG; \ 2.127 + cycles -= ((mod == 3) ? 3 : 7); \ 2.128 + break; \ 2.129 + case 0x10: /*RCL b,CL*/ \ 2.130 + temp2 = flags & C_FLAG; \ 2.131 + while (c > 0) \ 2.132 + { \ 2.133 + tempc = temp2 ? 1 : 0; \ 2.134 + temp2 = temp & 0x80; \ 2.135 + temp = (temp << 1) | tempc; \ 2.136 + c--; \ 2.137 + if (is486) cycles--; \ 2.138 + } \ 2.139 + seteab(temp); if (abrt) return 0; \ 2.140 + flags &= ~(C_FLAG | V_FLAG); \ 2.141 + if (temp2) flags |= C_FLAG; \ 2.142 + if ((flags & C_FLAG) ^ (temp >> 7)) flags |= V_FLAG; \ 2.143 + cycles -= ((mod == 3) ? 9 : 10); \ 2.144 + break; \ 2.145 + case 0x18: /*RCR b,CL*/ \ 2.146 + temp2 = flags & C_FLAG; \ 2.147 + while (c > 0) \ 2.148 + { \ 2.149 + tempc = temp2 ? 0x80 : 0; \ 2.150 + temp2 = temp & 1; \ 2.151 + temp = (temp >> 1) | tempc; \ 2.152 + c--; \ 2.153 + if (is486) cycles--; \ 2.154 + } \ 2.155 + seteab(temp); if (abrt) return 0; \ 2.156 + flags &= ~(C_FLAG | V_FLAG); \ 2.157 + if (temp2) flags |= C_FLAG; \ 2.158 + if ((temp ^ (temp >> 1)) & 0x40) flags |= V_FLAG; \ 2.159 + cycles -= ((mod == 3) ? 9 : 10); \ 2.160 + break; \ 2.161 + case 0x20: case 0x30: /*SHL b,CL*/ \ 2.162 + seteab(temp << c); if (abrt) return 0; \ 2.163 + set_flags_shift(FLAGS_SHL8, temp_orig, c, temp << c); \ 2.164 + if ((temp << (c - 1)) & 0x80) flags |= C_FLAG; \ 2.165 + cycles -= ((mod == 3) ? 3 : 7); \ 2.166 + break; \ 2.167 + case 0x28: /*SHR b,CL*/ \ 2.168 + seteab(temp >> c); if (abrt) return 0; \ 2.169 + set_flags_shift(FLAGS_SHR8, temp_orig, c, temp >> c); \ 2.170 + if ((temp >> (c - 1)) & 1) flags |= C_FLAG; \ 2.171 + cycles -= ((mod == 3) ? 3 : 7); \ 2.172 + break; \ 2.173 + case 0x38: /*SAR b,CL*/ \ 2.174 + tempc = ((temp >> (c - 1)) & 1); \ 2.175 + while (c > 0) \ 2.176 + { \ 2.177 + temp >>= 1; \ 2.178 + if (temp & 0x40) temp |= 0x80; \ 2.179 + c--; \ 2.180 + } \ 2.181 + seteab(temp); if (abrt) return 0; \ 2.182 + set_flags_shift(FLAGS_SAR8, temp_orig, c, temp); \ 2.183 + if (tempc) flags |= C_FLAG; \ 2.184 + cycles -= ((mod == 3) ? 3 : 7); \ 2.185 + break; \ 2.186 + } \ 2.187 } 2.188 2.189 -#define OP_SHIFT_w(c) \ 2.190 - if (!c) return 0; \ 2.191 - flags_rebuild(); \ 2.192 - switch (rmdat & 0x38) \ 2.193 - { \ 2.194 - case 0x00: /*ROL w, c*/ \ 2.195 - while (c > 0) \ 2.196 - { \ 2.197 - temp2 = (temp & 0x8000) ? 1 : 0; \ 2.198 - temp = (temp << 1) | temp2; \ 2.199 - c--; \ 2.200 - } \ 2.201 - seteaw(temp); if (abrt) return 0; \ 2.202 - flags &= ~(C_FLAG | V_FLAG); \ 2.203 - if (temp2) flags |= C_FLAG; \ 2.204 - if ((flags & C_FLAG) ^ (temp >> 15)) flags |= V_FLAG; \ 2.205 - cycles -= ((mod == 3) ? 3 : 7); \ 2.206 - break; \ 2.207 - case 0x08: /*ROR w, c*/ \ 2.208 - while (c > 0) \ 2.209 - { \ 2.210 - temp2 = temp & 1; \ 2.211 - temp >>= 1; \ 2.212 - if (temp2) temp |= 0x8000; \ 2.213 - c--; \ 2.214 - } \ 2.215 - seteaw(temp); if (abrt) return 0; \ 2.216 - flags &= ~(C_FLAG | V_FLAG); \ 2.217 - if (temp2) flags |= C_FLAG; \ 2.218 - if ((temp ^ (temp >> 1)) & 0x4000) flags |= V_FLAG; \ 2.219 - cycles -= ((mod == 3) ? 3 : 7); \ 2.220 - break; \ 2.221 - case 0x10: /*RCL w, c*/ \ 2.222 - temp2 = flags & C_FLAG; \ 2.223 - while (c > 0) \ 2.224 - { \ 2.225 - tempc = temp2 ? 1 : 0; \ 2.226 - temp2 = temp & 0x8000; \ 2.227 - temp = (temp << 1) | tempc; \ 2.228 - c--; \ 2.229 - if (is486) cycles--; \ 2.230 - } \ 2.231 - seteaw(temp); if (abrt) return 0; \ 2.232 - flags &= ~(C_FLAG | V_FLAG); \ 2.233 - if (temp2) flags |= C_FLAG; \ 2.234 - if ((flags & C_FLAG) ^ (temp >> 15)) flags |= V_FLAG; \ 2.235 - cycles -= ((mod == 3) ? 9 : 10); \ 2.236 - break; \ 2.237 - case 0x18: /*RCR w, c*/ \ 2.238 - temp2 = flags & C_FLAG; \ 2.239 - while (c > 0) \ 2.240 - { \ 2.241 - tempc = temp2 ? 0x8000 : 0; \ 2.242 - temp2 = temp & 1; \ 2.243 - temp = (temp >> 1) | tempc; \ 2.244 - c--; \ 2.245 - if (is486) cycles--; \ 2.246 - } \ 2.247 - seteaw(temp); if (abrt) return 0; \ 2.248 - flags &= ~(C_FLAG | V_FLAG); \ 2.249 - if (temp2) flags |= C_FLAG; \ 2.250 - if ((temp ^ (temp >> 1)) & 0x4000) flags |= V_FLAG; \ 2.251 - cycles -= ((mod == 3) ? 9 : 10); \ 2.252 - break; \ 2.253 - case 0x20: case 0x30: /*SHL w, c*/ \ 2.254 - seteaw(temp << c); if (abrt) return 0; \ 2.255 - setznp16(temp << c); \ 2.256 - if ((temp << (c - 1)) & 0x8000) flags |= C_FLAG; \ 2.257 - if (((temp << c) ^ (temp << (c - 1))) & 0x8000) flags |= V_FLAG;\ 2.258 - cycles -= ((mod == 3) ? 3 : 7); \ 2.259 - break; \ 2.260 - case 0x28: /*SHR w, c*/ \ 2.261 - seteaw(temp >> c); if (abrt) return 0; \ 2.262 - setznp16(temp >> c); \ 2.263 - if ((temp >> (c - 1)) & 1) flags |= C_FLAG; \ 2.264 - if (c == 1 && temp & 0x8000) flags |= V_FLAG; \ 2.265 - cycles -= ((mod == 3) ? 3 : 7); \ 2.266 - break; \ 2.267 - case 0x38: /*SAR w, c*/ \ 2.268 - tempc = ((temp >> (c - 1)) & 1); \ 2.269 - while (c > 0) \ 2.270 - { \ 2.271 - temp >>= 1; \ 2.272 - if (temp & 0x4000) temp |= 0x8000; \ 2.273 - c--; \ 2.274 - } \ 2.275 - seteaw(temp); if (abrt) return 0; \ 2.276 - setznp16(temp); \ 2.277 - if (tempc) flags |= C_FLAG; \ 2.278 - cycles -= ((mod == 3) ? 3 : 7); \ 2.279 - break; \ 2.280 +#define OP_SHIFT_w(c) \ 2.281 + { \ 2.282 + uint16_t temp_orig = temp; \ 2.283 + if (!c) return 0; \ 2.284 + flags_rebuild(); \ 2.285 + switch (rmdat & 0x38) \ 2.286 + { \ 2.287 + case 0x00: /*ROL w, c*/ \ 2.288 + while (c > 0) \ 2.289 + { \ 2.290 + temp2 = (temp & 0x8000) ? 1 : 0; \ 2.291 + temp = (temp << 1) | temp2; \ 2.292 + c--; \ 2.293 + } \ 2.294 + seteaw(temp); if (abrt) return 0; \ 2.295 + flags &= ~(C_FLAG | V_FLAG); \ 2.296 + if (temp2) flags |= C_FLAG; \ 2.297 + if ((flags & C_FLAG) ^ (temp >> 15)) flags |= V_FLAG; \ 2.298 + cycles -= ((mod == 3) ? 3 : 7); \ 2.299 + break; \ 2.300 + case 0x08: /*ROR w, c*/ \ 2.301 + while (c > 0) \ 2.302 + { \ 2.303 + temp2 = temp & 1; \ 2.304 + temp >>= 1; \ 2.305 + if (temp2) temp |= 0x8000; \ 2.306 + c--; \ 2.307 + } \ 2.308 + seteaw(temp); if (abrt) return 0; \ 2.309 + flags &= ~(C_FLAG | V_FLAG); \ 2.310 + if (temp2) flags |= C_FLAG; \ 2.311 + if ((temp ^ (temp >> 1)) & 0x4000) flags |= V_FLAG; \ 2.312 + cycles -= ((mod == 3) ? 3 : 7); \ 2.313 + break; \ 2.314 + case 0x10: /*RCL w, c*/ \ 2.315 + temp2 = flags & C_FLAG; \ 2.316 + while (c > 0) \ 2.317 + { \ 2.318 + tempc = temp2 ? 1 : 0; \ 2.319 + temp2 = temp & 0x8000; \ 2.320 + temp = (temp << 1) | tempc; \ 2.321 + c--; \ 2.322 + if (is486) cycles--; \ 2.323 + } \ 2.324 + seteaw(temp); if (abrt) return 0; \ 2.325 + flags &= ~(C_FLAG | V_FLAG); \ 2.326 + if (temp2) flags |= C_FLAG; \ 2.327 + if ((flags & C_FLAG) ^ (temp >> 15)) flags |= V_FLAG; \ 2.328 + cycles -= ((mod == 3) ? 9 : 10); \ 2.329 + break; \ 2.330 + case 0x18: /*RCR w, c*/ \ 2.331 + temp2 = flags & C_FLAG; \ 2.332 + while (c > 0) \ 2.333 + { \ 2.334 + tempc = temp2 ? 0x8000 : 0; \ 2.335 + temp2 = temp & 1; \ 2.336 + temp = (temp >> 1) | tempc; \ 2.337 + c--; \ 2.338 + if (is486) cycles--; \ 2.339 + } \ 2.340 + seteaw(temp); if (abrt) return 0; \ 2.341 + flags &= ~(C_FLAG | V_FLAG); \ 2.342 + if (temp2) flags |= C_FLAG; \ 2.343 + if ((temp ^ (temp >> 1)) & 0x4000) flags |= V_FLAG; \ 2.344 + cycles -= ((mod == 3) ? 9 : 10); \ 2.345 + break; \ 2.346 + case 0x20: case 0x30: /*SHL w, c*/ \ 2.347 + seteaw(temp << c); if (abrt) return 0; \ 2.348 + set_flags_shift(FLAGS_SHL16, temp_orig, c, temp << c); \ 2.349 + if ((temp << (c - 1)) & 0x8000) flags |= C_FLAG; \ 2.350 + cycles -= ((mod == 3) ? 3 : 7); \ 2.351 + break; \ 2.352 + case 0x28: /*SHR w, c*/ \ 2.353 + seteaw(temp >> c); if (abrt) return 0; \ 2.354 + set_flags_shift(FLAGS_SHR16, temp_orig, c, temp >> c); \ 2.355 + if ((temp >> (c - 1)) & 1) flags |= C_FLAG; \ 2.356 + cycles -= ((mod == 3) ? 3 : 7); \ 2.357 + break; \ 2.358 + case 0x38: /*SAR w, c*/ \ 2.359 + tempc = ((temp >> (c - 1)) & 1); \ 2.360 + while (c > 0) \ 2.361 + { \ 2.362 + temp >>= 1; \ 2.363 + if (temp & 0x4000) temp |= 0x8000; \ 2.364 + c--; \ 2.365 + } \ 2.366 + seteaw(temp); if (abrt) return 0; \ 2.367 + set_flags_shift(FLAGS_SAR16, temp_orig, c, temp); \ 2.368 + if (tempc) flags |= C_FLAG; \ 2.369 + cycles -= ((mod == 3) ? 3 : 7); \ 2.370 + break; \ 2.371 + } \ 2.372 } 2.373 2.374 -#define OP_SHIFT_l(c) \ 2.375 - if (!c) return 0; \ 2.376 - flags_rebuild(); \ 2.377 - switch (rmdat & 0x38) \ 2.378 - { \ 2.379 - case 0x00: /*ROL l, c*/ \ 2.380 - while (c > 0) \ 2.381 - { \ 2.382 - temp2 = (temp & 0x80000000) ? 1 : 0; \ 2.383 - temp = (temp << 1) | temp2; \ 2.384 - c--; \ 2.385 - } \ 2.386 - seteal(temp); if (abrt) return 0; \ 2.387 - flags &= ~(C_FLAG | V_FLAG); \ 2.388 - if (temp2) flags |= C_FLAG; \ 2.389 - if ((flags & C_FLAG) ^ (temp >> 31)) flags |= V_FLAG; \ 2.390 - cycles -= ((mod == 3) ? 3 : 7); \ 2.391 - break; \ 2.392 - case 0x08: /*ROR l, c*/ \ 2.393 - while (c > 0) \ 2.394 - { \ 2.395 - temp2 = temp & 1; \ 2.396 - temp >>= 1; \ 2.397 - if (temp2) temp |= 0x80000000; \ 2.398 - c--; \ 2.399 - } \ 2.400 - seteal(temp); if (abrt) return 0; \ 2.401 - flags &= ~(C_FLAG | V_FLAG); \ 2.402 - if (temp2) flags |= C_FLAG; \ 2.403 - if ((temp ^ (temp >> 1)) & 0x40000000) flags |= V_FLAG; \ 2.404 - cycles -= ((mod == 3) ? 3 : 7); \ 2.405 - break; \ 2.406 - case 0x10: /*RCL l, c*/ \ 2.407 - temp2 = flags & C_FLAG; \ 2.408 - while (c > 0) \ 2.409 - { \ 2.410 - tempc = temp2 ? 1 : 0; \ 2.411 - temp2 = temp & 0x80000000; \ 2.412 - temp = (temp << 1) | tempc; \ 2.413 - c--; \ 2.414 - if (is486) cycles--; \ 2.415 - } \ 2.416 - seteal(temp); if (abrt) return 0; \ 2.417 - flags &= ~(C_FLAG | V_FLAG); \ 2.418 - if (temp2) flags |= C_FLAG; \ 2.419 - if ((flags & C_FLAG) ^ (temp >> 31)) flags |= V_FLAG; \ 2.420 - cycles -= ((mod == 3) ? 9 : 10); \ 2.421 - break; \ 2.422 - case 0x18: /*RCR l, c*/ \ 2.423 - temp2 = flags & C_FLAG; \ 2.424 - while (c > 0) \ 2.425 - { \ 2.426 - tempc = temp2 ? 0x80000000 : 0; \ 2.427 - temp2 = temp & 1; \ 2.428 - temp = (temp >> 1) | tempc; \ 2.429 - c--; \ 2.430 - if (is486) cycles--; \ 2.431 - } \ 2.432 - seteal(temp); if (abrt) return 0; \ 2.433 - flags &= ~(C_FLAG | V_FLAG); \ 2.434 - if (temp2) flags |= C_FLAG; \ 2.435 - if ((temp ^ (temp >> 1)) & 0x40000000) flags |= V_FLAG; \ 2.436 - cycles -= ((mod == 3) ? 9 : 10); \ 2.437 - break; \ 2.438 - case 0x20: case 0x30: /*SHL l, c*/ \ 2.439 - seteal(temp << c); if (abrt) return 0; \ 2.440 - setznp32(temp << c); \ 2.441 - if ((temp << (c - 1)) & 0x80000000) flags |= C_FLAG; \ 2.442 - if (((temp << c) ^ (temp << (c - 1))) & 0x80000000) flags |= V_FLAG;\ 2.443 - cycles -= ((mod == 3) ? 3 : 7); \ 2.444 - break; \ 2.445 - case 0x28: /*SHR l, c*/ \ 2.446 - seteal(temp >> c); if (abrt) return 0; \ 2.447 - setznp32(temp >> c); \ 2.448 - if ((temp >> (c - 1)) & 1) flags |= C_FLAG; \ 2.449 - if (c == 1 && temp & 0x80000000) flags |= V_FLAG; \ 2.450 - cycles -= ((mod == 3) ? 3 : 7); \ 2.451 - break; \ 2.452 - case 0x38: /*SAR l, c*/ \ 2.453 - tempc = ((temp >> (c - 1)) & 1); \ 2.454 - while (c > 0) \ 2.455 - { \ 2.456 - temp >>= 1; \ 2.457 - if (temp & 0x40000000) temp |= 0x80000000; \ 2.458 - c--; \ 2.459 - } \ 2.460 - seteal(temp); if (abrt) return 0; \ 2.461 - setznp32(temp); \ 2.462 - if (tempc) flags |= C_FLAG; \ 2.463 - cycles -= ((mod == 3) ? 3 : 7); \ 2.464 - break; \ 2.465 +#define OP_SHIFT_l(c) \ 2.466 + { \ 2.467 + uint32_t temp_orig = temp; \ 2.468 + if (!c) return 0; \ 2.469 + flags_rebuild(); \ 2.470 + switch (rmdat & 0x38) \ 2.471 + { \ 2.472 + case 0x00: /*ROL l, c*/ \ 2.473 + while (c > 0) \ 2.474 + { \ 2.475 + temp2 = (temp & 0x80000000) ? 1 : 0; \ 2.476 + temp = (temp << 1) | temp2; \ 2.477 + c--; \ 2.478 + } \ 2.479 + seteal(temp); if (abrt) return 0; \ 2.480 + flags &= ~(C_FLAG | V_FLAG); \ 2.481 + if (temp2) flags |= C_FLAG; \ 2.482 + if ((flags & C_FLAG) ^ (temp >> 31)) flags |= V_FLAG; \ 2.483 + cycles -= ((mod == 3) ? 3 : 7); \ 2.484 + break; \ 2.485 + case 0x08: /*ROR l, c*/ \ 2.486 + while (c > 0) \ 2.487 + { \ 2.488 + temp2 = temp & 1; \ 2.489 + temp >>= 1; \ 2.490 + if (temp2) temp |= 0x80000000; \ 2.491 + c--; \ 2.492 + } \ 2.493 + seteal(temp); if (abrt) return 0; \ 2.494 + flags &= ~(C_FLAG | V_FLAG); \ 2.495 + if (temp2) flags |= C_FLAG; \ 2.496 + if ((temp ^ (temp >> 1)) & 0x40000000) flags |= V_FLAG; \ 2.497 + cycles -= ((mod == 3) ? 3 : 7); \ 2.498 + break; \ 2.499 + case 0x10: /*RCL l, c*/ \ 2.500 + temp2 = flags & C_FLAG; \ 2.501 + while (c > 0) \ 2.502 + { \ 2.503 + tempc = temp2 ? 1 : 0; \ 2.504 + temp2 = temp & 0x80000000; \ 2.505 + temp = (temp << 1) | tempc; \ 2.506 + c--; \ 2.507 + if (is486) cycles--; \ 2.508 + } \ 2.509 + seteal(temp); if (abrt) return 0; \ 2.510 + flags &= ~(C_FLAG | V_FLAG); \ 2.511 + if (temp2) flags |= C_FLAG; \ 2.512 + if ((flags & C_FLAG) ^ (temp >> 31)) flags |= V_FLAG; \ 2.513 + cycles -= ((mod == 3) ? 9 : 10); \ 2.514 + break; \ 2.515 + case 0x18: /*RCR l, c*/ \ 2.516 + temp2 = flags & C_FLAG; \ 2.517 + while (c > 0) \ 2.518 + { \ 2.519 + tempc = temp2 ? 0x80000000 : 0; \ 2.520 + temp2 = temp & 1; \ 2.521 + temp = (temp >> 1) | tempc; \ 2.522 + c--; \ 2.523 + if (is486) cycles--; \ 2.524 + } \ 2.525 + seteal(temp); if (abrt) return 0; \ 2.526 + flags &= ~(C_FLAG | V_FLAG); \ 2.527 + if (temp2) flags |= C_FLAG; \ 2.528 + if ((temp ^ (temp >> 1)) & 0x40000000) flags |= V_FLAG; \ 2.529 + cycles -= ((mod == 3) ? 9 : 10); \ 2.530 + break; \ 2.531 + case 0x20: case 0x30: /*SHL l, c*/ \ 2.532 + seteal(temp << c); if (abrt) return 0; \ 2.533 + set_flags_shift(FLAGS_SHL32, temp_orig, c, temp << c); \ 2.534 + if ((temp << (c - 1)) & 0x80000000) flags |= C_FLAG; \ 2.535 + cycles -= ((mod == 3) ? 3 : 7); \ 2.536 + break; \ 2.537 + case 0x28: /*SHR l, c*/ \ 2.538 + seteal(temp >> c); if (abrt) return 0; \ 2.539 + set_flags_shift(FLAGS_SHR32, temp_orig, c, temp >> c); \ 2.540 + if ((temp >> (c - 1)) & 1) flags |= C_FLAG; \ 2.541 + cycles -= ((mod == 3) ? 3 : 7); \ 2.542 + break; \ 2.543 + case 0x38: /*SAR l, c*/ \ 2.544 + tempc = ((temp >> (c - 1)) & 1); \ 2.545 + while (c > 0) \ 2.546 + { \ 2.547 + temp >>= 1; \ 2.548 + if (temp & 0x40000000) temp |= 0x80000000; \ 2.549 + c--; \ 2.550 + } \ 2.551 + seteal(temp); if (abrt) return 0; \ 2.552 + set_flags_shift(FLAGS_SAR32, temp_orig, c, temp); \ 2.553 + if (tempc) flags |= C_FLAG; \ 2.554 + cycles -= ((mod == 3) ? 3 : 7); \ 2.555 + break; \ 2.556 + } \ 2.557 } 2.558 2.559 static int opC0_a16(uint32_t fetchdat)
