diff options
Diffstat (limited to 'util/vgabios/x86emu/src/x86emu/prim_ops.c')
-rw-r--r-- | util/vgabios/x86emu/src/x86emu/prim_ops.c | 3628 |
1 files changed, 1499 insertions, 2129 deletions
diff --git a/util/vgabios/x86emu/src/x86emu/prim_ops.c b/util/vgabios/x86emu/src/x86emu/prim_ops.c index d1d4be848c..914952bfc8 100644 --- a/util/vgabios/x86emu/src/x86emu/prim_ops.c +++ b/util/vgabios/x86emu/src/x86emu/prim_ops.c @@ -1,10 +1,10 @@ /**************************************************************************** * -* Realmode X86 Emulator Library +* Realmode X86 Emulator Library * -* Copyright (C) 1996-1999 SciTech Software, Inc. -* Copyright (C) David Mosberger-Tang -* Copyright (C) 1999 Egbert Eich +* Copyright (C) 1991-2004 SciTech Software, Inc. +* Copyright (C) David Mosberger-Tang +* Copyright (C) 1999 Egbert Eich * * ======================================================================== * @@ -28,12 +28,12 @@ * * ======================================================================== * -* Language: ANSI C -* Environment: Any +* Language: ANSI C +* Environment: Any * Developer: Kendall Bennett * * Description: This file contains the code to implement the primitive -* machine operations used by the emulation code in ops.c +* machine operations used by the emulation code in ops.c * * Carry Chain Calculation * @@ -97,32 +97,109 @@ * ****************************************************************************/ -#define PRIM_OPS_NO_REDEFINE_ASM +#define PRIM_OPS_NO_REDEFINE_ASM #include "x86emu/x86emui.h" /*------------------------- Global Variables ------------------------------*/ -#ifndef __HAVE_INLINE_ASSEMBLER__ - -static u32 x86emu_parity_tab[8] = { - 0x96696996, - 0x69969669, - 0x69969669, - 0x96696996, - 0x69969669, - 0x96696996, - 0x96696996, - 0x69969669, +static u32 x86emu_parity_tab[8] = +{ + 0x96696996, + 0x69969669, + 0x69969669, + 0x96696996, + 0x69969669, + 0x96696996, + 0x96696996, + 0x69969669, }; -#endif - #define PARITY(x) (((x86emu_parity_tab[(x) / 32] >> ((x) % 32)) & 1) == 0) -#define XOR2(x) (((x) ^ ((x)>>1)) & 0x1) +#define XOR2(x) (((x) ^ ((x)>>1)) & 0x1) /*----------------------------- Implementation ----------------------------*/ -#ifndef __HAVE_INLINE_ASSEMBLER__ + +/*--------- Side effects helper functions -------*/ + +/**************************************************************************** +REMARKS: +implements side efects for byte operations that don't overflow +****************************************************************************/ + +static void set_parity_flag(u32 res) +{ + CONDITIONAL_SET_FLAG(PARITY(res & 0xFF), F_PF); +} + +static void set_szp_flags_8(u8 res) +{ + CONDITIONAL_SET_FLAG(res & 0x80, F_SF); + CONDITIONAL_SET_FLAG(res == 0, F_ZF); + set_parity_flag(res); +} + +static void set_szp_flags_16(u16 res) +{ + CONDITIONAL_SET_FLAG(res & 0x8000, F_SF); + CONDITIONAL_SET_FLAG(res == 0, F_ZF); + set_parity_flag(res); +} + +static void set_szp_flags_32(u32 res) +{ + CONDITIONAL_SET_FLAG(res & 0x80000000, F_SF); + CONDITIONAL_SET_FLAG(res == 0, F_ZF); + set_parity_flag(res); +} + +static void no_carry_byte_side_eff(u8 res) +{ + CLEAR_FLAG(F_OF); + CLEAR_FLAG(F_CF); + CLEAR_FLAG(F_AF); + set_szp_flags_8(res); +} + +static void no_carry_word_side_eff(u16 res) +{ + CLEAR_FLAG(F_OF); + CLEAR_FLAG(F_CF); + CLEAR_FLAG(F_AF); + set_szp_flags_16(res); +} + +static void no_carry_long_side_eff(u32 res) +{ + CLEAR_FLAG(F_OF); + CLEAR_FLAG(F_CF); + CLEAR_FLAG(F_AF); + set_szp_flags_32(res); +} + +static void calc_carry_chain(int bits, u32 d, u32 s, u32 res, int set_carry) +{ + u32 cc; + + cc = (s & d) | ((~res) & (s | d)); + CONDITIONAL_SET_FLAG(XOR2(cc >> (bits - 2)), F_OF); + CONDITIONAL_SET_FLAG(cc & 0x8, F_AF); + if (set_carry) { + CONDITIONAL_SET_FLAG(res & (1 << bits), F_CF); + } +} + +static void calc_borrow_chain(int bits, u32 d, u32 s, u32 res, int set_carry) +{ + u32 bc; + + bc = (res & (~d | s)) | (~d & s); + CONDITIONAL_SET_FLAG(XOR2(bc >> (bits - 2)), F_OF); + CONDITIONAL_SET_FLAG(bc & 0x8, F_AF); + if (set_carry) { + CONDITIONAL_SET_FLAG(bc & (1 << (bits - 1)), F_CF); + } +} /**************************************************************************** REMARKS: @@ -130,21 +207,19 @@ Implements the AAA instruction and side effects. ****************************************************************************/ u16 aaa_word(u16 d) { - u16 res; - if ((d & 0xf) > 0x9 || ACCESS_FLAG(F_AF)) { - d += 0x6; - d += 0x100; - SET_FLAG(F_AF); - SET_FLAG(F_CF); - } else { - CLEAR_FLAG(F_CF); - CLEAR_FLAG(F_AF); - } - res = (u16) (d & 0xFF0F); - CLEAR_FLAG(F_SF); - CONDITIONAL_SET_FLAG(res == 0, F_ZF); - CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF); - return res; + u16 res; + if ((d & 0xf) > 0x9 || ACCESS_FLAG(F_AF)) { + d += 0x6; + d += 0x100; + SET_FLAG(F_AF); + SET_FLAG(F_CF); + } else { + CLEAR_FLAG(F_CF); + CLEAR_FLAG(F_AF); + } + res = (u16)(d & 0xFF0F); + set_szp_flags_16(res); + return res; } /**************************************************************************** @@ -153,21 +228,19 @@ Implements the AAA instruction and side effects. ****************************************************************************/ u16 aas_word(u16 d) { - u16 res; - if ((d & 0xf) > 0x9 || ACCESS_FLAG(F_AF)) { - d -= 0x6; - d -= 0x100; - SET_FLAG(F_AF); - SET_FLAG(F_CF); - } else { - CLEAR_FLAG(F_CF); - CLEAR_FLAG(F_AF); - } - res = (u16) (d & 0xFF0F); - CLEAR_FLAG(F_SF); - CONDITIONAL_SET_FLAG(res == 0, F_ZF); - CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF); - return res; + u16 res; + if ((d & 0xf) > 0x9 || ACCESS_FLAG(F_AF)) { + d -= 0x6; + d -= 0x100; + SET_FLAG(F_AF); + SET_FLAG(F_CF); + } else { + CLEAR_FLAG(F_CF); + CLEAR_FLAG(F_AF); + } + res = (u16)(d & 0xFF0F); + set_szp_flags_16(res); + return res; } /**************************************************************************** @@ -176,20 +249,15 @@ Implements the AAD instruction and side effects. ****************************************************************************/ u16 aad_word(u16 d) { - u16 l; - u8 hb, lb; + u16 l; + u8 hb, lb; - hb = (u8) ((d >> 8) & 0xff); - lb = (u8) ((d & 0xff)); - l = (u16) ((lb + 10 * hb) & 0xFF); + hb = (u8)((d >> 8) & 0xff); + lb = (u8)((d & 0xff)); + l = (u16)((lb + 10 * hb) & 0xFF); - CLEAR_FLAG(F_CF); - CLEAR_FLAG(F_AF); - CLEAR_FLAG(F_OF); - CONDITIONAL_SET_FLAG(l & 0x80, F_SF); - CONDITIONAL_SET_FLAG(l == 0, F_ZF); - CONDITIONAL_SET_FLAG(PARITY(l & 0xff), F_PF); - return l; + no_carry_byte_side_eff(l & 0xFF); + return l; } /**************************************************************************** @@ -198,19 +266,14 @@ Implements the AAM instruction and side effects. ****************************************************************************/ u16 aam_word(u8 d) { - u16 h, l; + u16 h, l; - h = (u16) (d / 10); - l = (u16) (d % 10); - l |= (u16) (h << 8); + h = (u16)(d / 10); + l = (u16)(d % 10); + l |= (u16)(h << 8); - CLEAR_FLAG(F_CF); - CLEAR_FLAG(F_AF); - CLEAR_FLAG(F_OF); - CONDITIONAL_SET_FLAG(l & 0x80, F_SF); - CONDITIONAL_SET_FLAG(l == 0, F_ZF); - CONDITIONAL_SET_FLAG(PARITY(l & 0xff), F_PF); - return l; + no_carry_byte_side_eff(l & 0xFF); + return l; } /**************************************************************************** @@ -219,24 +282,15 @@ Implements the ADC instruction and side effects. ****************************************************************************/ u8 adc_byte(u8 d, u8 s) { - register u32 res; /* all operands in native machine order */ - register u32 cc; + u32 res; /* all operands in native machine order */ - if (ACCESS_FLAG(F_CF)) - res = 1 + d + s; - else - res = d + s; + res = d + s; + if (ACCESS_FLAG(F_CF)) res++; - CONDITIONAL_SET_FLAG(res & 0x100, F_CF); - CONDITIONAL_SET_FLAG((res & 0xff) == 0, F_ZF); - CONDITIONAL_SET_FLAG(res & 0x80, F_SF); - CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF); + set_szp_flags_8(res); + calc_carry_chain(8,s,d,res,1); - /* calculate the carry chain SEE NOTE AT TOP. */ - cc = (s & d) | ((~res) & (s | d)); - CONDITIONAL_SET_FLAG(XOR2(cc >> 6), F_OF); - CONDITIONAL_SET_FLAG(cc & 0x8, F_AF); - return (u8) res; + return (u8)res; } /**************************************************************************** @@ -245,24 +299,16 @@ Implements the ADC instruction and side effects. ****************************************************************************/ u16 adc_word(u16 d, u16 s) { - register u32 res; /* all operands in native machine order */ - register u32 cc; + u32 res; /* all operands in native machine order */ - if (ACCESS_FLAG(F_CF)) - res = 1 + d + s; - else - res = d + s; + res = d + s; + if (ACCESS_FLAG(F_CF)) + res++; - CONDITIONAL_SET_FLAG(res & 0x10000, 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); + set_szp_flags_16((u16)res); + calc_carry_chain(16,s,d,res,1); - /* calculate the carry chain SEE NOTE AT TOP. */ - cc = (s & d) | ((~res) & (s | d)); - CONDITIONAL_SET_FLAG(XOR2(cc >> 14), F_OF); - CONDITIONAL_SET_FLAG(cc & 0x8, F_AF); - return (u16) res; + return (u16)res; } /**************************************************************************** @@ -271,30 +317,26 @@ Implements the ADC instruction and side effects. ****************************************************************************/ u32 adc_long(u32 d, u32 s) { - register u32 lo; /* all operands in native machine order */ - register u32 hi; - register u32 res; - register u32 cc; + u32 lo; /* all operands in native machine order */ + u32 hi; + u32 res; - if (ACCESS_FLAG(F_CF)) { - lo = 1 + (d & 0xFFFF) + (s & 0xFFFF); - res = 1 + d + s; - } else { - lo = (d & 0xFFFF) + (s & 0xFFFF); - res = d + s; - } - hi = (lo >> 16) + (d >> 16) + (s >> 16); + lo = (d & 0xFFFF) + (s & 0xFFFF); + res = d + s; - CONDITIONAL_SET_FLAG(hi & 0x10000, F_CF); - CONDITIONAL_SET_FLAG((res & 0xffffffff) == 0, F_ZF); - CONDITIONAL_SET_FLAG(res & 0x80000000, F_SF); - CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF); + if (ACCESS_FLAG(F_CF)) { + lo++; + res++; + } - /* calculate the carry chain SEE NOTE AT TOP. */ - cc = (s & d) | ((~res) & (s | d)); - CONDITIONAL_SET_FLAG(XOR2(cc >> 30), F_OF); - CONDITIONAL_SET_FLAG(cc & 0x8, F_AF); - return res; + hi = (lo >> 16) + (d >> 16) + (s >> 16); + + set_szp_flags_32(res); + calc_carry_chain(32,s,d,res,0); + + CONDITIONAL_SET_FLAG(hi & 0x10000, F_CF); + + return res; } /**************************************************************************** @@ -303,20 +345,13 @@ Implements the ADD instruction and side effects. ****************************************************************************/ u8 add_byte(u8 d, u8 s) { - register u32 res; /* all operands in native machine order */ - register u32 cc; + u32 res; /* all operands in native machine order */ - res = d + s; - CONDITIONAL_SET_FLAG(res & 0x100, F_CF); - CONDITIONAL_SET_FLAG((res & 0xff) == 0, F_ZF); - CONDITIONAL_SET_FLAG(res & 0x80, F_SF); - CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF); + res = d + s; + set_szp_flags_8((u8)res); + calc_carry_chain(8,s,d,res,1); - /* calculate the carry chain SEE NOTE AT TOP. */ - cc = (s & d) | ((~res) & (s | d)); - CONDITIONAL_SET_FLAG(XOR2(cc >> 6), F_OF); - CONDITIONAL_SET_FLAG(cc & 0x8, F_AF); - return (u8) res; + return (u8)res; } /**************************************************************************** @@ -325,20 +360,13 @@ Implements the ADD instruction and side effects. ****************************************************************************/ u16 add_word(u16 d, u16 s) { - register u32 res; /* all operands in native machine order */ - register u32 cc; + u32 res; /* all operands in native machine order */ - res = d + s; - CONDITIONAL_SET_FLAG(res & 0x10000, 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); + res = d + s; + set_szp_flags_16((u16)res); + calc_carry_chain(16,s,d,res,1); - /* calculate the carry chain SEE NOTE AT TOP. */ - cc = (s & d) | ((~res) & (s | d)); - CONDITIONAL_SET_FLAG(XOR2(cc >> 14), F_OF); - CONDITIONAL_SET_FLAG(cc & 0x8, F_AF); - return (u16) res; + return (u16)res; } /**************************************************************************** @@ -347,26 +375,15 @@ Implements the ADD instruction and side effects. ****************************************************************************/ u32 add_long(u32 d, u32 s) { - register u32 lo; /* all operands in native machine order */ - register u32 hi; - register u32 res; - register u32 cc; + u32 res; - lo = (d & 0xFFFF) + (s & 0xFFFF); - res = d + s; - hi = (lo >> 16) + (d >> 16) + (s >> 16); + res = d + s; + set_szp_flags_32(res); + calc_carry_chain(32,s,d,res,0); - CONDITIONAL_SET_FLAG(hi & 0x10000, F_CF); - CONDITIONAL_SET_FLAG((res & 0xffffffff) == 0, F_ZF); - CONDITIONAL_SET_FLAG(res & 0x80000000, F_SF); - CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF); + CONDITIONAL_SET_FLAG(res < d || res < s, F_CF); - /* calculate the carry chain SEE NOTE AT TOP. */ - cc = (s & d) | ((~res) & (s | d)); - CONDITIONAL_SET_FLAG(XOR2(cc >> 30), F_OF); - CONDITIONAL_SET_FLAG(cc & 0x8, F_AF); - - return res; + return res; } /**************************************************************************** @@ -375,18 +392,12 @@ Implements the AND instruction and side effects. ****************************************************************************/ u8 and_byte(u8 d, u8 s) { - register u8 res; /* all operands in native machine order */ + u8 res; /* all operands in native machine order */ - res = d & s; + res = d & s; - /* set the flags */ - CLEAR_FLAG(F_OF); - CLEAR_FLAG(F_CF); - CLEAR_FLAG(F_AF); - CONDITIONAL_SET_FLAG(res & 0x80, F_SF); - CONDITIONAL_SET_FLAG(res == 0, F_ZF); - CONDITIONAL_SET_FLAG(PARITY(res), F_PF); - return res; + no_carry_byte_side_eff(res); + return res; } /**************************************************************************** @@ -395,18 +406,12 @@ Implements the AND instruction and side effects. ****************************************************************************/ u16 and_word(u16 d, u16 s) { - register u16 res; /* all operands in native machine order */ + u16 res; /* all operands in native machine order */ - res = d & s; + res = d & s; - /* set the flags */ - CLEAR_FLAG(F_OF); - CLEAR_FLAG(F_CF); - CLEAR_FLAG(F_AF); - CONDITIONAL_SET_FLAG(res & 0x8000, F_SF); - CONDITIONAL_SET_FLAG(res == 0, F_ZF); - CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF); - return res; + no_carry_word_side_eff(res); + return res; } /**************************************************************************** @@ -415,18 +420,11 @@ Implements the AND instruction and side effects. ****************************************************************************/ u32 and_long(u32 d, u32 s) { - register u32 res; /* all operands in native machine order */ - - res = d & s; + u32 res; /* all operands in native machine order */ - /* set the flags */ - CLEAR_FLAG(F_OF); - CLEAR_FLAG(F_CF); - CLEAR_FLAG(F_AF); - CONDITIONAL_SET_FLAG(res & 0x80000000, F_SF); - CONDITIONAL_SET_FLAG(res == 0, F_ZF); - CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF); - return res; + res = d & s; + no_carry_long_side_eff(res); + return res; } /**************************************************************************** @@ -435,21 +433,13 @@ Implements the CMP instruction and side effects. ****************************************************************************/ u8 cmp_byte(u8 d, u8 s) { - register u32 res; /* all operands in native machine order */ - register u32 bc; + u32 res; /* all operands in native machine order */ - res = d - s; - CLEAR_FLAG(F_CF); - CONDITIONAL_SET_FLAG(res & 0x80, F_SF); - CONDITIONAL_SET_FLAG((res & 0xff) == 0, F_ZF); - CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF); + res = d - s; + set_szp_flags_8((u8)res); + calc_borrow_chain(8, d, s, res, 1); - /* calculate the borrow chain. See note at top */ - bc = (res & (~d | s)) | (~d & s); - CONDITIONAL_SET_FLAG(bc & 0x80, F_CF); - CONDITIONAL_SET_FLAG(XOR2(bc >> 6), F_OF); - CONDITIONAL_SET_FLAG(bc & 0x8, F_AF); - return d; + return d; } /**************************************************************************** @@ -458,20 +448,13 @@ Implements the CMP instruction and side effects. ****************************************************************************/ u16 cmp_word(u16 d, u16 s) { - register u32 res; /* all operands in native machine order */ - register u32 bc; + u32 res; /* all operands in native machine order */ - res = d - s; - CONDITIONAL_SET_FLAG(res & 0x8000, F_SF); - CONDITIONAL_SET_FLAG((res & 0xffff) == 0, F_ZF); - CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF); + res = d - s; + set_szp_flags_16((u16)res); + calc_borrow_chain(16, d, s, res, 1); - /* calculate the borrow chain. See note at top */ - bc = (res & (~d | s)) | (~d & s); - CONDITIONAL_SET_FLAG(bc & 0x8000, F_CF); - CONDITIONAL_SET_FLAG(XOR2(bc >> 14), F_OF); - CONDITIONAL_SET_FLAG(bc & 0x8, F_AF); - return d; + return d; } /**************************************************************************** @@ -480,20 +463,13 @@ Implements the CMP instruction and side effects. ****************************************************************************/ u32 cmp_long(u32 d, u32 s) { - register u32 res; /* all operands in native machine order */ - register u32 bc; + u32 res; /* all operands in native machine order */ - res = d - s; - CONDITIONAL_SET_FLAG(res & 0x80000000, F_SF); - CONDITIONAL_SET_FLAG((res & 0xffffffff) == 0, F_ZF); - CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF); + res = d - s; + set_szp_flags_32(res); + calc_borrow_chain(32, d, s, res, 1); - /* calculate the borrow chain. See note at top */ - bc = (res & (~d | s)) | (~d & s); - CONDITIONAL_SET_FLAG(bc & 0x80000000, F_CF); - CONDITIONAL_SET_FLAG(XOR2(bc >> 30), F_OF); - CONDITIONAL_SET_FLAG(bc & 0x8, F_AF); - return d; + return d; } /**************************************************************************** @@ -502,19 +478,17 @@ Implements the DAA instruction and side effects. ****************************************************************************/ u8 daa_byte(u8 d) { - u32 res = d; - if ((d & 0xf) > 9 || ACCESS_FLAG(F_AF)) { - res += 6; - SET_FLAG(F_AF); - } - if (res > 0x9F || ACCESS_FLAG(F_CF)) { - res += 0x60; - SET_FLAG(F_CF); - } - CONDITIONAL_SET_FLAG(res & 0x80, F_SF); - CONDITIONAL_SET_FLAG((res & 0xFF) == 0, F_ZF); - CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF); - return (u8) res; + u32 res = d; + if ((d & 0xf) > 9 || ACCESS_FLAG(F_AF)) { + res += 6; + SET_FLAG(F_AF); + } + if (res > 0x9F || ACCESS_FLAG(F_CF)) { + res += 0x60; + SET_FLAG(F_CF); + } + set_szp_flags_8((u8)res); + return (u8)res; } /**************************************************************************** @@ -523,18 +497,16 @@ Implements the DAS instruction and side effects. ****************************************************************************/ u8 das_byte(u8 d) { - if ((d & 0xf) > 9 || ACCESS_FLAG(F_AF)) { - d -= 6; - SET_FLAG(F_AF); - } - if (d > 0x9F || ACCESS_FLAG(F_CF)) { - d -= 0x60; - SET_FLAG(F_CF); - } - CONDITIONAL_SET_FLAG(d & 0x80, F_SF); - CONDITIONAL_SET_FLAG(d == 0, F_ZF); - CONDITIONAL_SET_FLAG(PARITY(d & 0xff), F_PF); - return d; + if ((d & 0xf) > 9 || ACCESS_FLAG(F_AF)) { + d -= 6; + SET_FLAG(F_AF); + } + if (d > 0x9F || ACCESS_FLAG(F_CF)) { + d -= 0x60; + SET_FLAG(F_CF); + } + set_szp_flags_8(d); + return d; } /**************************************************************************** @@ -543,21 +515,13 @@ Implements the DEC instruction and side effects. ****************************************************************************/ u8 dec_byte(u8 d) { - register u32 res; /* all operands in native machine order */ - register u32 bc; + u32 res; /* all operands in native machine order */ - res = d - 1; - CONDITIONAL_SET_FLAG(res & 0x80, F_SF); - CONDITIONAL_SET_FLAG((res & 0xff) == 0, F_ZF); - CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF); + res = d - 1; + set_szp_flags_8((u8)res); + calc_borrow_chain(8, d, 1, res, 0); - /* calculate the borrow chain. See note at top */ - /* based on sub_byte, uses s==1. */ - bc = (res & (~d | 1)) | (~d & 1); - /* carry flag unchanged */ - CONDITIONAL_SET_FLAG(XOR2(bc >> 6), F_OF); - CONDITIONAL_SET_FLAG(bc & 0x8, F_AF); - return (u8) res; + return (u8)res; } /**************************************************************************** @@ -566,21 +530,13 @@ Implements the DEC instruction and side effects. ****************************************************************************/ u16 dec_word(u16 d) { - register u32 res; /* all operands in native machine order */ - register u32 bc; + u32 res; /* all operands in native machine order */ - res = d - 1; - CONDITIONAL_SET_FLAG(res & 0x8000, F_SF); - CONDITIONAL_SET_FLAG((res & 0xffff) == 0, F_ZF); - CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF); + res = d - 1; + set_szp_flags_16((u16)res); + calc_borrow_chain(16, d, 1, res, 0); - /* calculate the borrow chain. See note at top */ - /* based on the sub_byte routine, with s==1 */ - bc = (res & (~d | 1)) | (~d & 1); - /* carry flag unchanged */ - CONDITIONAL_SET_FLAG(XOR2(bc >> 14), F_OF); - CONDITIONAL_SET_FLAG(bc & 0x8, F_AF); - return (u16) res; + return (u16)res; } /**************************************************************************** @@ -589,21 +545,14 @@ Implements the DEC instruction and side effects. ****************************************************************************/ u32 dec_long(u32 d) { - register u32 res; /* all operands in native machine order */ - register u32 bc; + u32 res; /* all operands in native machine order */ - res = d - 1; + res = d - 1; - CONDITIONAL_SET_FLAG(res & 0x80000000, F_SF); - CONDITIONAL_SET_FLAG((res & 0xffffffff) == 0, F_ZF); - CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF); + set_szp_flags_32(res); + calc_borrow_chain(32, d, 1, res, 0); - /* calculate the borrow chain. See note at top */ - bc = (res & (~d | 1)) | (~d & 1); - /* carry flag unchanged */ - CONDITIONAL_SET_FLAG(XOR2(bc >> 30), F_OF); - CONDITIONAL_SET_FLAG(bc & 0x8, F_AF); - return res; + return res; } /**************************************************************************** @@ -612,19 +561,13 @@ Implements the INC instruction and side effects. ****************************************************************************/ u8 inc_byte(u8 d) { - register u32 res; /* all operands in native machine order */ - register u32 cc; + u32 res; /* all operands in native machine order */ - res = d + 1; - CONDITIONAL_SET_FLAG((res & 0xff) == 0, F_ZF); - CONDITIONAL_SET_FLAG(res & 0x80, F_SF); - CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF); + res = d + 1; + set_szp_flags_8((u8)res); + calc_carry_chain(8, d, 1, res, 0); - /* calculate the carry chain SEE NOTE AT TOP. */ - cc = ((1 & d) | (~res)) & (1 | d); - CONDITIONAL_SET_FLAG(XOR2(cc >> 6), F_OF); - CONDITIONAL_SET_FLAG(cc & 0x8, F_AF); - return (u8) res; + return (u8)res; } /**************************************************************************** @@ -633,19 +576,13 @@ Implements the INC instruction and side effects. ****************************************************************************/ u16 inc_word(u16 d) { - register u32 res; /* all operands in native machine order */ - register u32 cc; + u32 res; /* all operands in native machine order */ - res = d + 1; - CONDITIONAL_SET_FLAG((res & 0xffff) == 0, F_ZF); - CONDITIONAL_SET_FLAG(res & 0x8000, F_SF); - CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF); + res = d + 1; + set_szp_flags_16((u16)res); + calc_carry_chain(16, d, 1, res, 0); - /* calculate the carry chain SEE NOTE AT TOP. */ - cc = (1 & d) | ((~res) & (1 | d)); - CONDITIONAL_SET_FLAG(XOR2(cc >> 14), F_OF); - CONDITIONAL_SET_FLAG(cc & 0x8, F_AF); - return (u16) res; + return (u16)res; } /**************************************************************************** @@ -654,19 +591,13 @@ Implements the INC instruction and side effects. ****************************************************************************/ u32 inc_long(u32 d) { - register u32 res; /* all operands in native machine order */ - register u32 cc; + u32 res; /* all operands in native machine order */ - res = d + 1; - CONDITIONAL_SET_FLAG((res & 0xffffffff) == 0, F_ZF); - CONDITIONAL_SET_FLAG(res & 0x80000000, F_SF); - CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF); + res = d + 1; + set_szp_flags_32(res); + calc_carry_chain(32, d, 1, res, 0); - /* calculate the carry chain SEE NOTE AT TOP. */ - cc = (1 & d) | ((~res) & (1 | d)); - CONDITIONAL_SET_FLAG(XOR2(cc >> 30), F_OF); - CONDITIONAL_SET_FLAG(cc & 0x8, F_AF); - return res; + return res; } /**************************************************************************** @@ -675,16 +606,12 @@ Implements the OR instruction and side effects. ****************************************************************************/ u8 or_byte(u8 d, u8 s) { - register u8 res; /* all operands in native machine order */ + u8 res; /* all operands in native machine order */ + + res = d | s; + no_carry_byte_side_eff(res); - res = d | s; - CLEAR_FLAG(F_OF); - CLEAR_FLAG(F_CF); - CLEAR_FLAG(F_AF); - CONDITIONAL_SET_FLAG(res & 0x80, F_SF); - CONDITIONAL_SET_FLAG(res == 0, F_ZF); - CONDITIONAL_SET_FLAG(PARITY(res), F_PF); - return res; + return res; } /**************************************************************************** @@ -693,17 +620,11 @@ Implements the OR instruction and side effects. ****************************************************************************/ u16 or_word(u16 d, u16 s) { - register u16 res; /* all operands in native machine order */ + u16 res; /* all operands in native machine order */ - res = d | s; - /* set the carry flag to be bit 8 */ - CLEAR_FLAG(F_OF); - CLEAR_FLAG(F_CF); - CLEAR_FLAG(F_AF); - CONDITIONAL_SET_FLAG(res & 0x8000, F_SF); - CONDITIONAL_SET_FLAG(res == 0, F_ZF); - CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF); - return res; + res = d | s; + no_carry_word_side_eff(res); + return res; } /**************************************************************************** @@ -712,18 +633,11 @@ Implements the OR instruction and side effects. ****************************************************************************/ u32 or_long(u32 d, u32 s) { - register u32 res; /* all operands in native machine order */ + u32 res; /* all operands in native machine order */ - res = d | s; - - /* set the carry flag to be bit 8 */ - CLEAR_FLAG(F_OF); - CLEAR_FLAG(F_CF); - CLEAR_FLAG(F_AF); - CONDITIONAL_SET_FLAG(res & 0x80000000, F_SF); - CONDITIONAL_SET_FLAG(res == 0, F_ZF); - CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF); - return res; + res = d | s; + no_carry_long_side_eff(res); + return res; } /**************************************************************************** @@ -732,23 +646,14 @@ Implements the OR instruction and side effects. ****************************************************************************/ u8 neg_byte(u8 s) { - register u8 res; - register u8 bc; + u8 res; + + CONDITIONAL_SET_FLAG(s != 0, F_CF); + res = (u8)-s; + set_szp_flags_8(res); + calc_borrow_chain(8, 0, s, res, 0); - CONDITIONAL_SET_FLAG(s != 0, F_CF); - res = (u8) - s; - CONDITIONAL_SET_FLAG((res & 0xff) == 0, F_ZF); - CONDITIONAL_SET_FLAG(res & 0x80, F_SF); - CONDITIONAL_SET_FLAG(PARITY(res), F_PF); - /* calculate the borrow chain --- modified such that d=0. - substitutiing d=0 into bc= res&(~d|s)|(~d&s); - (the one used for sub) and simplifying, since ~d=0xff..., - ~d|s == 0xffff..., and res&0xfff... == res. Similarly - ~d&s == s. So the simplified result is: */ - bc = res | s; - CONDITIONAL_SET_FLAG(XOR2(bc >> 6), F_OF); - CONDITIONAL_SET_FLAG(bc & 0x8, F_AF); - return res; + return res; } /**************************************************************************** @@ -757,24 +662,14 @@ Implements the OR instruction and side effects. ****************************************************************************/ u16 neg_word(u16 s) { - register u16 res; - register u16 bc; + u16 res; - CONDITIONAL_SET_FLAG(s != 0, F_CF); - res = (u16) - s; - CONDITIONAL_SET_FLAG((res & 0xffff) == 0, F_ZF); - CONDITIONAL_SET_FLAG(res & 0x8000, F_SF); - CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF); + CONDITIONAL_SET_FLAG(s != 0, F_CF); + res = (u16)-s; + set_szp_flags_16((u16)res); + calc_borrow_chain(16, 0, s, res, 0); - /* calculate the borrow chain --- modified such that d=0. - substitutiing d=0 into bc= res&(~d|s)|(~d&s); - (the one used for sub) and simplifying, since ~d=0xff..., - ~d|s == 0xffff..., and res&0xfff... == res. Similarly - ~d&s == s. So the simplified result is: */ - bc = res | s; - CONDITIONAL_SET_FLAG(XOR2(bc >> 14), F_OF); - CONDITIONAL_SET_FLAG(bc & 0x8, F_AF); - return res; + return res; } /**************************************************************************** @@ -783,24 +678,14 @@ Implements the OR instruction and side effects. ****************************************************************************/ u32 neg_long(u32 s) { - register u32 res; - register u32 bc; + u32 res; - CONDITIONAL_SET_FLAG(s != 0, F_CF); - res = (u32) - s; - CONDITIONAL_SET_FLAG((res & 0xffffffff) == 0, F_ZF); - CONDITIONAL_SET_FLAG(res & 0x80000000, F_SF); - CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF); + CONDITIONAL_SET_FLAG(s != 0, F_CF); + res = (u32)-s; + set_szp_flags_32(res); + calc_borrow_chain(32, 0, s, res, 0); - /* calculate the borrow chain --- modified such that d=0. - substitutiing d=0 into bc= res&(~d|s)|(~d&s); - (the one used for sub) and simplifying, since ~d=0xff..., - ~d|s == 0xffff..., and res&0xfff... == res. Similarly - ~d&s == s. So the simplified result is: */ - bc = res | s; - CONDITIONAL_SET_FLAG(XOR2(bc >> 30), F_OF); - CONDITIONAL_SET_FLAG(bc & 0x8, F_AF); - return res; + return res; } /**************************************************************************** @@ -809,7 +694,7 @@ Implements the NOT instruction and side effects. ****************************************************************************/ u8 not_byte(u8 s) { - return ~s; + return ~s; } /**************************************************************************** @@ -818,7 +703,7 @@ Implements the NOT instruction and side effects. ****************************************************************************/ u16 not_word(u16 s) { - return ~s; + return ~s; } /**************************************************************************** @@ -827,7 +712,7 @@ Implements the NOT instruction and side effects. ****************************************************************************/ u32 not_long(u32 s) { - return ~s; + return ~s; } /**************************************************************************** @@ -836,70 +721,71 @@ Implements the RCL instruction and side effects. ****************************************************************************/ u8 rcl_byte(u8 d, u8 s) { - register unsigned int res, cnt, mask, cf; - - /* s is the rotate distance. It varies from 0 - 8. */ - /* have - - CF B_7 B_6 B_5 B_4 B_3 B_2 B_1 B_0 - - want to rotate through the carry by "s" bits. We could - loop, but that's inefficient. So the width is 9, - and we split into three parts: - - The new carry flag (was B_n) - the stuff in B_n-1 .. B_0 - the stuff in B_7 .. B_n+1 - - The new rotate is done mod 9, and given this, - for a rotation of n bits (mod 9) the new carry flag is - then located n bits from the MSB. The low part is - then shifted up cnt bits, and the high part is or'd - in. Using CAPS for new values, and lowercase for the - original values, this can be expressed as: - - IF n > 0 - 1) CF <- b_(8-n) - 2) B_(7) .. B_(n) <- b_(8-(n+1)) .. b_0 - 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) */ - cf = (d >> (8 - cnt)) & 0x1; - - /* get the low stuff which rotated - into the range B_7 .. B_cnt */ - /* B_(7) .. B_(n) <- b_(8-(n+1)) .. b_0 */ - /* note that the right hand side done by the mask */ - res = (d << cnt) & 0xff; - - /* now the high stuff which rotated around - into the positions B_cnt-2 .. B_0 */ - /* B_(n-2) .. B_0 <- b_7 .. b_(8-(n-1)) */ - /* shift it downward, 7-(n-2) = 9-n positions. - and mask off the result before or'ing in. - */ - mask = (1 << (cnt - 1)) - 1; - res |= (d >> (9 - cnt)) & mask; - - /* if the carry flag was set, or it in. */ - if (ACCESS_FLAG(F_CF)) { /* carry flag is set */ - /* B_(n-1) <- cf */ - res |= 1 << (cnt - 1); - } - /* set the new carry flag, based on the variable "cf" */ - CONDITIONAL_SET_FLAG(cf, F_CF); - /* OVERFLOW is set *IFF* cnt==1, then it is the - xor of CF and the most significant bit. Blecck. */ - /* parenthesized this expression since it appears to - be causing OF to be misset */ - CONDITIONAL_SET_FLAG(cnt == 1 && XOR2(cf + ((res >> 6) & 0x2)), F_OF); - - } - return (u8) res; + unsigned int res, cnt, mask, cf; + + /* s is the rotate distance. It varies from 0 - 8. */ + /* have + + CF B_7 B_6 B_5 B_4 B_3 B_2 B_1 B_0 + + want to rotate through the carry by "s" bits. We could + loop, but that's inefficient. So the width is 9, + and we split into three parts: + + The new carry flag (was B_n) + the stuff in B_n-1 .. B_0 + the stuff in B_7 .. B_n+1 + + The new rotate is done mod 9, and given this, + for a rotation of n bits (mod 9) the new carry flag is + then located n bits from the MSB. The low part is + then shifted up cnt bits, and the high part is or'd + in. Using CAPS for new values, and lowercase for the + original values, this can be expressed as: + + IF n > 0 + 1) CF <- b_(8-n) + 2) B_(7) .. B_(n) <- b_(8-(n+1)) .. b_0 + 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) */ + cf = (d >> (8 - cnt)) & 0x1; + + /* get the low stuff which rotated + into the range B_7 .. B_cnt */ + /* B_(7) .. B_(n) <- b_(8-(n+1)) .. b_0 */ + /* note that the right hand side done by the mask */ + res = (d << cnt) & 0xff; + + /* now the high stuff which rotated around + into the positions B_cnt-2 .. B_0 */ + /* B_(n-2) .. B_0 <- b_7 .. b_(8-(n-1)) */ + /* shift it downward, 7-(n-2) = 9-n positions. + and mask off the result before or'ing in. + */ + mask = (1 << (cnt - 1)) - 1; + res |= (d >> (9 - cnt)) & mask; + + /* if the carry flag was set, or it in. */ + if (ACCESS_FLAG(F_CF)) { /* carry flag is set */ + /* B_(n-1) <- cf */ + res |= 1 << (cnt - 1); + } + /* set the new carry flag, based on the variable "cf" */ + CONDITIONAL_SET_FLAG(cf, F_CF); + /* OVERFLOW is set *IFF* cnt==1, then it is the + xor of CF and the most significant bit. Blecck. */ + /* parenthesized this expression since it appears to + be causing OF to be misset */ + CONDITIONAL_SET_FLAG(cnt == 1 && XOR2(cf + ((res >> 6) & 0x2)), + F_OF); + + } + return (u8)res; } /**************************************************************************** @@ -908,21 +794,22 @@ Implements the RCL instruction and side effects. ****************************************************************************/ u16 rcl_word(u16 d, u8 s) { - register unsigned int res, cnt, mask, cf; + unsigned int res, cnt, mask, cf; - res = d; - if ((cnt = s % 17) != 0) { - cf = (d >> (16 - cnt)) & 0x1; - res = (d << cnt) & 0xffff; - mask = (1 << (cnt - 1)) - 1; - res |= (d >> (17 - cnt)) & mask; - if (ACCESS_FLAG(F_CF)) { - res |= 1 << (cnt - 1); - } - CONDITIONAL_SET_FLAG(cf, F_CF); - CONDITIONAL_SET_FLAG(cnt == 1 && XOR2(cf + ((res >> 14) & 0x2)), F_OF); - } - return (u16) res; + res = d; + if ((cnt = s % 17) != 0) { + cf = (d >> (16 - cnt)) & 0x1; + res = (d << cnt) & 0xffff; + mask = (1 << (cnt - 1)) - 1; + res |= (d >> (17 - cnt)) & mask; + if (ACCESS_FLAG(F_CF)) { + res |= 1 << (cnt - 1); + } + CONDITIONAL_SET_FLAG(cf, F_CF); + CONDITIONAL_SET_FLAG(cnt == 1 && XOR2(cf + ((res >> 14) & 0x2)), + F_OF); + } + return (u16)res; } /**************************************************************************** @@ -931,21 +818,22 @@ Implements the RCL instruction and side effects. ****************************************************************************/ u32 rcl_long(u32 d, u8 s) { - register u32 res, cnt, mask, cf; + u32 res, cnt, mask, cf; - res = d; - if ((cnt = s % 33) != 0) { - cf = (d >> (32 - cnt)) & 0x1; - res = (d << cnt) & 0xffffffff; - mask = (1 << (cnt - 1)) - 1; - res |= (d >> (33 - cnt)) & mask; - if (ACCESS_FLAG(F_CF)) { /* carry flag is set */ - res |= 1 << (cnt - 1); - } - CONDITIONAL_SET_FLAG(cf, F_CF); - CONDITIONAL_SET_FLAG(cnt == 1 && XOR2(cf + ((res >> 30) & 0x2)), F_OF); - } - return res; + res = d; + if ((cnt = s % 33) != 0) { + cf = (d >> (32 - cnt)) & 0x1; + res = (d << cnt) & 0xffffffff; + mask = (1 << (cnt - 1)) - 1; + res |= (d >> (33 - cnt)) & mask; + if (ACCESS_FLAG(F_CF)) { /* carry flag is set */ + res |= 1 << (cnt - 1); + } + CONDITIONAL_SET_FLAG(cf, F_CF); + CONDITIONAL_SET_FLAG(cnt == 1 && XOR2(cf + ((res >> 30) & 0x2)), + F_OF); + } + return res; } /**************************************************************************** @@ -954,81 +842,82 @@ Implements the RCR instruction and side effects. ****************************************************************************/ u8 rcr_byte(u8 d, u8 s) { - u32 res, cnt; - u32 mask, cf, ocf = 0; - - /* rotate right through carry */ - /* - s is the rotate distance. It varies from 0 - 8. - d is the byte object rotated. - - have - - CF B_7 B_6 B_5 B_4 B_3 B_2 B_1 B_0 - - The new rotate is done mod 9, and given this, - for a rotation of n bits (mod 9) the new carry flag is - then located n bits from the LSB. The low part is - then shifted up cnt bits, and the high part is or'd - in. Using CAPS for new values, and lowercase for the - original values, this can be expressed as: - - IF n > 0 - 1) CF <- b_(n-1) - 2) B_(8-(n+1)) .. B_(0) <- b_(7) .. b_(n) - 3) B_(8-n) <- cf - 4) B_(7) .. B_(8-(n-1)) <- b_(n-2) .. b_(0) - */ - res = d; - if ((cnt = s % 9) != 0) { - /* extract the new CARRY FLAG. */ - /* CF <- b_(n-1) */ - if (cnt == 1) { - cf = d & 0x1; - /* note hackery here. Access_flag(..) evaluates to either - 0 if flag not set - non-zero if flag is set. - doing access_flag(..) != 0 casts that into either - 0..1 in any representation of the flags register - (i.e. packed bit array or unpacked.) - */ - ocf = ACCESS_FLAG(F_CF) != 0; - } else - cf = (d >> (cnt - 1)) & 0x1; - - /* B_(8-(n+1)) .. B_(0) <- b_(7) .. b_n */ - /* note that the right hand side done by the mask - This is effectively done by shifting the - object to the right. The result must be masked, - in case the object came in and was treated - as a negative number. Needed??? */ - - mask = (1 << (8 - cnt)) - 1; - res = (d >> cnt) & mask; - - /* now the high stuff which rotated around - into the positions B_cnt-2 .. B_0 */ - /* B_(7) .. B_(8-(n-1)) <- b_(n-2) .. b_(0) */ - /* shift it downward, 7-(n-2) = 9-n positions. - and mask off the result before or'ing in. - */ - res |= (d << (9 - cnt)); - - /* if the carry flag was set, or it in. */ - if (ACCESS_FLAG(F_CF)) { /* carry flag is set */ - /* B_(8-n) <- cf */ - res |= 1 << (8 - cnt); - } - /* set the new carry flag, based on the variable "cf" */ - CONDITIONAL_SET_FLAG(cf, F_CF); - /* OVERFLOW is set *IFF* cnt==1, then it is the - xor of CF and the most significant bit. Blecck. */ - /* parenthesized... */ - if (cnt == 1) { - CONDITIONAL_SET_FLAG(XOR2(ocf + ((d >> 6) & 0x2)), F_OF); - } - } - return (u8) res; + u32 res, cnt; + u32 mask, cf, ocf = 0; + + /* rotate right through carry */ + /* + s is the rotate distance. It varies from 0 - 8. + d is the byte object rotated. + + have + + CF B_7 B_6 B_5 B_4 B_3 B_2 B_1 B_0 + + The new rotate is done mod 9, and given this, + for a rotation of n bits (mod 9) the new carry flag is + then located n bits from the LSB. The low part is + then shifted up cnt bits, and the high part is or'd + in. Using CAPS for new values, and lowercase for the + original values, this can be expressed as: + + IF n > 0 + 1) CF <- b_(n-1) + 2) B_(8-(n+1)) .. B_(0) <- b_(7) .. b_(n) + 3) B_(8-n) <- cf + 4) B_(7) .. B_(8-(n-1)) <- b_(n-2) .. b_(0) + */ + res = d; + if ((cnt = s % 9) != 0) { + /* extract the new CARRY FLAG. */ + /* CF <- b_(n-1) */ + if (cnt == 1) { + cf = d & 0x1; + /* note hackery here. Access_flag(..) evaluates to either + 0 if flag not set + non-zero if flag is set. + doing access_flag(..) != 0 casts that into either + 0..1 in any representation of the flags register + (i.e. packed bit array or unpacked.) + */ + ocf = ACCESS_FLAG(F_CF) != 0; + } else + cf = (d >> (cnt - 1)) & 0x1; + + /* B_(8-(n+1)) .. B_(0) <- b_(7) .. b_n */ + /* note that the right hand side done by the mask + This is effectively done by shifting the + object to the right. The result must be masked, + in case the object came in and was treated + as a negative number. Needed??? */ + + mask = (1 << (8 - cnt)) - 1; + res = (d >> cnt) & mask; + + /* now the high stuff which rotated around + into the positions B_cnt-2 .. B_0 */ + /* B_(7) .. B_(8-(n-1)) <- b_(n-2) .. b_(0) */ + /* shift it downward, 7-(n-2) = 9-n positions. + and mask off the result before or'ing in. + */ + res |= (d << (9 - cnt)); + + /* if the carry flag was set, or it in. */ + if (ACCESS_FLAG(F_CF)) { /* carry flag is set */ + /* B_(8-n) <- cf */ + res |= 1 << (8 - cnt); + } + /* set the new carry flag, based on the variable "cf" */ + CONDITIONAL_SET_FLAG(cf, F_CF); + /* OVERFLOW is set *IFF* cnt==1, then it is the + xor of CF and the most significant bit. Blecck. */ + /* parenthesized... */ + if (cnt == 1) { + CONDITIONAL_SET_FLAG(XOR2(ocf + ((d >> 6) & 0x2)), + F_OF); + } + } + return (u8)res; } /**************************************************************************** @@ -1037,29 +926,30 @@ Implements the RCR instruction and side effects. ****************************************************************************/ u16 rcr_word(u16 d, u8 s) { - u32 res, cnt; - u32 mask, cf, ocf = 0; - - /* rotate right through carry */ - res = d; - if ((cnt = s % 17) != 0) { - if (cnt == 1) { - cf = d & 0x1; - ocf = ACCESS_FLAG(F_CF) != 0; - } else - cf = (d >> (cnt - 1)) & 0x1; - mask = (1 << (16 - cnt)) - 1; - res = (d >> cnt) & mask; - res |= (d << (17 - cnt)); - if (ACCESS_FLAG(F_CF)) { - res |= 1 << (16 - cnt); - } - CONDITIONAL_SET_FLAG(cf, F_CF); - if (cnt == 1) { - CONDITIONAL_SET_FLAG(XOR2(ocf + ((d >> 14) & 0x2)), F_OF); - } - } - return (u16) res; + u32 res, cnt; + u32 mask, cf, ocf = 0; + + /* rotate right through carry */ + res = d; + if ((cnt = s % 17) != 0) { + if (cnt == 1) { + cf = d & 0x1; + ocf = ACCESS_FLAG(F_CF) != 0; + } else + cf = (d >> (cnt - 1)) & 0x1; + mask = (1 << (16 - cnt)) - 1; + res = (d >> cnt) & mask; + res |= (d << (17 - cnt)); + if (ACCESS_FLAG(F_CF)) { + res |= 1 << (16 - cnt); + } + CONDITIONAL_SET_FLAG(cf, F_CF); + if (cnt == 1) { + CONDITIONAL_SET_FLAG(XOR2(ocf + ((d >> 14) & 0x2)), + F_OF); + } + } + return (u16)res; } /**************************************************************************** @@ -1068,30 +958,31 @@ Implements the RCR instruction and side effects. ****************************************************************************/ u32 rcr_long(u32 d, u8 s) { - u32 res, cnt; - u32 mask, cf, ocf = 0; - - /* rotate right through carry */ - res = d; - if ((cnt = s % 33) != 0) { - if (cnt == 1) { - cf = d & 0x1; - ocf = ACCESS_FLAG(F_CF) != 0; - } else - cf = (d >> (cnt - 1)) & 0x1; - mask = (1 << (32 - cnt)) - 1; - res = (d >> cnt) & mask; - if (cnt != 1) - res |= (d << (33 - cnt)); - if (ACCESS_FLAG(F_CF)) { /* carry flag is set */ - res |= 1 << (32 - cnt); - } - CONDITIONAL_SET_FLAG(cf, F_CF); - if (cnt == 1) { - CONDITIONAL_SET_FLAG(XOR2(ocf + ((d >> 30) & 0x2)), F_OF); - } - } - return res; + u32 res, cnt; + u32 mask, cf, ocf = 0; + + /* rotate right through carry */ + res = d; + if ((cnt = s % 33) != 0) { + if (cnt == 1) { + cf = d & 0x1; + ocf = ACCESS_FLAG(F_CF) != 0; + } else + cf = (d >> (cnt - 1)) & 0x1; + mask = (1 << (32 - cnt)) - 1; + res = (d >> cnt) & mask; + if (cnt != 1) + res |= (d << (33 - cnt)); + if (ACCESS_FLAG(F_CF)) { /* carry flag is set */ + res |= 1 << (32 - cnt); + } + CONDITIONAL_SET_FLAG(cf, F_CF); + if (cnt == 1) { + CONDITIONAL_SET_FLAG(XOR2(ocf + ((d >> 30) & 0x2)), + F_OF); + } + } + return res; } /**************************************************************************** @@ -1100,47 +991,47 @@ Implements the ROL instruction and side effects. ****************************************************************************/ u8 rol_byte(u8 d, u8 s) { - register unsigned int res, cnt, mask; + unsigned int res, cnt, mask; - /* rotate left */ - /* - s is the rotate distance. It varies from 0 - 8. - d is the byte object rotated. + /* rotate left */ + /* + s is the rotate distance. It varies from 0 - 8. + d is the byte object rotated. - have + have - CF B_7 ... B_0 + CF B_7 ... B_0 - The new rotate is done mod 8. - Much simpler than the "rcl" or "rcr" operations. + The new rotate is done mod 8. + Much simpler than the "rcl" or "rcr" operations. - IF n > 0 - 1) B_(7) .. B_(n) <- b_(8-(n+1)) .. b_(0) - 2) B_(n-1) .. B_(0) <- b_(7) .. b_(8-n) - */ - res = d; - if ((cnt = s % 8) != 0) { - /* B_(7) .. B_(n) <- b_(8-(n+1)) .. b_(0) */ - res = (d << cnt); + IF n > 0 + 1) B_(7) .. B_(n) <- b_(8-(n+1)) .. b_(0) + 2) B_(n-1) .. B_(0) <- b_(7) .. b_(8-n) + */ + res = d; + if ((cnt = s % 8) != 0) { + /* B_(7) .. B_(n) <- b_(8-(n+1)) .. b_(0) */ + res = (d << cnt); - /* B_(n-1) .. B_(0) <- b_(7) .. b_(8-n) */ - mask = (1 << cnt) - 1; - res |= (d >> (8 - cnt)) & mask; + /* B_(n-1) .. B_(0) <- b_(7) .. b_(8-n) */ + mask = (1 << cnt) - 1; + res |= (d >> (8 - cnt)) & mask; - /* set the new carry flag, Note that it is the low order - bit of the result!!! */ - CONDITIONAL_SET_FLAG(res & 0x1, F_CF); - /* OVERFLOW is set *IFF* s==1, then it is the - xor of CF and the most significant bit. Blecck. */ - CONDITIONAL_SET_FLAG(s == 1 && - XOR2((res & 0x1) + ((res >> 6) & 0x2)), F_OF); - } - if (s != 0) { - /* set the new carry flag, Note that it is the low order - bit of the result!!! */ - CONDITIONAL_SET_FLAG(res & 0x1, F_CF); - } - return (u8) res; + /* set the new carry flag, Note that it is the low order + bit of the result!!! */ + CONDITIONAL_SET_FLAG(res & 0x1, F_CF); + /* OVERFLOW is set *IFF* s==1, then it is the + xor of CF and the most significant bit. Blecck. */ + CONDITIONAL_SET_FLAG(s == 1 && + XOR2((res & 0x1) + ((res >> 6) & 0x2)), + F_OF); + } if (s != 0) { + /* set the new carry flag, Note that it is the low order + bit of the result!!! */ + CONDITIONAL_SET_FLAG(res & 0x1, F_CF); + } + return (u8)res; } /**************************************************************************** @@ -1149,23 +1040,23 @@ Implements the ROL instruction and side effects. ****************************************************************************/ u16 rol_word(u16 d, u8 s) { - register unsigned int res, cnt, mask; + unsigned int res, cnt, mask; - res = d; - if ((cnt = s % 16) != 0) { - res = (d << cnt); - mask = (1 << cnt) - 1; - res |= (d >> (16 - cnt)) & mask; - CONDITIONAL_SET_FLAG(res & 0x1, F_CF); - CONDITIONAL_SET_FLAG(s == 1 && - XOR2((res & 0x1) + ((res >> 14) & 0x2)), F_OF); - } - if (s != 0) { - /* set the new carry flag, Note that it is the low order - bit of the result!!! */ - CONDITIONAL_SET_FLAG(res & 0x1, F_CF); - } - return (u16) res; + res = d; + if ((cnt = s % 16) != 0) { + res = (d << cnt); + mask = (1 << cnt) - 1; + res |= (d >> (16 - cnt)) & mask; + CONDITIONAL_SET_FLAG(res & 0x1, F_CF); + CONDITIONAL_SET_FLAG(s == 1 && + XOR2((res & 0x1) + ((res >> 14) & 0x2)), + F_OF); + } if (s != 0) { + /* set the new carry flag, Note that it is the low order + bit of the result!!! */ + CONDITIONAL_SET_FLAG(res & 0x1, F_CF); + } + return (u16)res; } /**************************************************************************** @@ -1174,23 +1065,23 @@ Implements the ROL instruction and side effects. ****************************************************************************/ u32 rol_long(u32 d, u8 s) { - register u32 res, cnt, mask; + u32 res, cnt, mask; - res = d; - if ((cnt = s % 32) != 0) { - res = (d << cnt); - mask = (1 << cnt) - 1; - res |= (d >> (32 - cnt)) & mask; - CONDITIONAL_SET_FLAG(res & 0x1, F_CF); - CONDITIONAL_SET_FLAG(s == 1 && - XOR2((res & 0x1) + ((res >> 30) & 0x2)), F_OF); - } - if (s != 0) { - /* set the new carry flag, Note that it is the low order - bit of the result!!! */ - CONDITIONAL_SET_FLAG(res & 0x1, F_CF); - } - return res; + res = d; + if ((cnt = s % 32) != 0) { + res = (d << cnt); + mask = (1 << cnt) - 1; + res |= (d >> (32 - cnt)) & mask; + CONDITIONAL_SET_FLAG(res & 0x1, F_CF); + CONDITIONAL_SET_FLAG(s == 1 && + XOR2((res & 0x1) + ((res >> 30) & 0x2)), + F_OF); + } if (s != 0) { + /* set the new carry flag, Note that it is the low order + bit of the result!!! */ + CONDITIONAL_SET_FLAG(res & 0x1, F_CF); + } + return res; } /**************************************************************************** @@ -1199,44 +1090,44 @@ Implements the ROR instruction and side effects. ****************************************************************************/ u8 ror_byte(u8 d, u8 s) { - register unsigned int res, cnt, mask; + unsigned int res, cnt, mask; - /* rotate right */ - /* - s is the rotate distance. It varies from 0 - 8. - d is the byte object rotated. + /* rotate right */ + /* + s is the rotate distance. It varies from 0 - 8. + d is the byte object rotated. - have + have - B_7 ... B_0 + B_7 ... B_0 - The rotate is done mod 8. + The rotate is done mod 8. - IF n > 0 - 1) B_(8-(n+1)) .. B_(0) <- b_(7) .. b_(n) - 2) B_(7) .. B_(8-n) <- b_(n-1) .. b_(0) - */ - res = d; - if ((cnt = s % 8) != 0) { /* not a typo, do nada if cnt==0 */ - /* B_(7) .. B_(8-n) <- b_(n-1) .. b_(0) */ - res = (d << (8 - cnt)); + IF n > 0 + 1) B_(8-(n+1)) .. B_(0) <- b_(7) .. b_(n) + 2) B_(7) .. B_(8-n) <- b_(n-1) .. b_(0) + */ + res = d; + if ((cnt = s % 8) != 0) { /* not a typo, do nada if cnt==0 */ + /* B_(7) .. B_(8-n) <- b_(n-1) .. b_(0) */ + res = (d << (8 - cnt)); - /* B_(8-(n+1)) .. B_(0) <- b_(7) .. b_(n) */ - mask = (1 << (8 - cnt)) - 1; - res |= (d >> (cnt)) & mask; + /* B_(8-(n+1)) .. B_(0) <- b_(7) .. b_(n) */ + mask = (1 << (8 - cnt)) - 1; + res |= (d >> (cnt)) & mask; - /* set the new carry flag, Note that it is the low order - bit of the result!!! */ - CONDITIONAL_SET_FLAG(res & 0x80, F_CF); - /* OVERFLOW is set *IFF* s==1, then it is the - xor of the two most significant bits. Blecck. */ - CONDITIONAL_SET_FLAG(s == 1 && XOR2(res >> 6), F_OF); - } else if (s != 0) { - /* set the new carry flag, Note that it is the low order - bit of the result!!! */ - CONDITIONAL_SET_FLAG(res & 0x80, F_CF); - } - return (u8) res; + /* set the new carry flag, Note that it is the low order + bit of the result!!! */ + CONDITIONAL_SET_FLAG(res & 0x80, F_CF); + /* OVERFLOW is set *IFF* s==1, then it is the + xor of the two most significant bits. Blecck. */ + CONDITIONAL_SET_FLAG(s == 1 && XOR2(res >> 6), F_OF); + } else if (s != 0) { + /* set the new carry flag, Note that it is the low order + bit of the result!!! */ + CONDITIONAL_SET_FLAG(res & 0x80, F_CF); + } + return (u8)res; } /**************************************************************************** @@ -1245,21 +1136,21 @@ Implements the ROR instruction and side effects. ****************************************************************************/ u16 ror_word(u16 d, u8 s) { - register unsigned int res, cnt, mask; + unsigned int res, cnt, mask; - res = d; - if ((cnt = s % 16) != 0) { - res = (d << (16 - cnt)); - mask = (1 << (16 - cnt)) - 1; - res |= (d >> (cnt)) & mask; - CONDITIONAL_SET_FLAG(res & 0x8000, F_CF); - CONDITIONAL_SET_FLAG(s == 1 && XOR2(res >> 14), F_OF); - } else if (s != 0) { - /* set the new carry flag, Note that it is the low order - bit of the result!!! */ - CONDITIONAL_SET_FLAG(res & 0x8000, F_CF); - } - return (u16) res; + res = d; + if ((cnt = s % 16) != 0) { + res = (d << (16 - cnt)); + mask = (1 << (16 - cnt)) - 1; + res |= (d >> (cnt)) & mask; + CONDITIONAL_SET_FLAG(res & 0x8000, F_CF); + CONDITIONAL_SET_FLAG(s == 1 && XOR2(res >> 14), F_OF); + } else if (s != 0) { + /* set the new carry flag, Note that it is the low order + bit of the result!!! */ + CONDITIONAL_SET_FLAG(res & 0x8000, F_CF); + } + return (u16)res; } /**************************************************************************** @@ -1268,21 +1159,21 @@ Implements the ROR instruction and side effects. ****************************************************************************/ u32 ror_long(u32 d, u8 s) { - register u32 res, cnt, mask; + u32 res, cnt, mask; - res = d; - if ((cnt = s % 32) != 0) { - res = (d << (32 - cnt)); - mask = (1 << (32 - cnt)) - 1; - res |= (d >> (cnt)) & mask; - CONDITIONAL_SET_FLAG(res & 0x80000000, F_CF); - CONDITIONAL_SET_FLAG(s == 1 && XOR2(res >> 30), F_OF); - } else if (s != 0) { - /* set the new carry flag, Note that it is the low order - bit of the result!!! */ - CONDITIONAL_SET_FLAG(res & 0x80000000, F_CF); - } - return res; + res = d; + if ((cnt = s % 32) != 0) { + res = (d << (32 - cnt)); + mask = (1 << (32 - cnt)) - 1; + res |= (d >> (cnt)) & mask; + CONDITIONAL_SET_FLAG(res & 0x80000000, F_CF); + CONDITIONAL_SET_FLAG(s == 1 && XOR2(res >> 30), F_OF); + } else if (s != 0) { + /* set the new carry flag, Note that it is the low order + bit of the result!!! */ + CONDITIONAL_SET_FLAG(res & 0x80000000, F_CF); + } + return res; } /**************************************************************************** @@ -1291,41 +1182,40 @@ Implements the SHL instruction and side effects. ****************************************************************************/ u8 shl_byte(u8 d, u8 s) { - unsigned int cnt, res, cf; - - if (s < 8) { - cnt = s % 8; - - /* last bit shifted out goes into carry flag */ - if (cnt > 0) { - res = d << cnt; - cf = d & (1 << (8 - cnt)); - CONDITIONAL_SET_FLAG(cf, F_CF); - CONDITIONAL_SET_FLAG((res & 0xff) == 0, F_ZF); - CONDITIONAL_SET_FLAG(res & 0x80, F_SF); - CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF); - } else { - res = (u8) d; - } - - if (cnt == 1) { - /* Needs simplification. */ - CONDITIONAL_SET_FLAG((((res & 0x80) == 0x80) ^ - (ACCESS_FLAG(F_CF) != 0)), - /* was (M.x86.R_FLG&F_CF)==F_CF)), */ - F_OF); - } else { - CLEAR_FLAG(F_OF); - } - } else { - res = 0; - CONDITIONAL_SET_FLAG((d << (s - 1)) & 0x80, F_CF); - CLEAR_FLAG(F_OF); - CLEAR_FLAG(F_SF); - SET_FLAG(F_PF); - SET_FLAG(F_ZF); - } - return (u8) res; + unsigned int cnt, res, cf; + + if (s < 8) { + cnt = s % 8; + + /* last bit shifted out goes into carry flag */ + if (cnt > 0) { + res = d << cnt; + cf = d & (1 << (8 - cnt)); + CONDITIONAL_SET_FLAG(cf, F_CF); + set_szp_flags_8((u8)res); + } else { + res = (u8) d; + } + + if (cnt == 1) { + /* Needs simplification. */ + CONDITIONAL_SET_FLAG( + (((res & 0x80) == 0x80) ^ + (ACCESS_FLAG(F_CF) != 0)), + /* was (M.x86.R_FLG&F_CF)==F_CF)), */ + F_OF); + } else { + CLEAR_FLAG(F_OF); + } + } else { + res = 0; + CONDITIONAL_SET_FLAG((d << (s-1)) & 0x80, F_CF); + CLEAR_FLAG(F_OF); + CLEAR_FLAG(F_SF); + SET_FLAG(F_PF); + SET_FLAG(F_ZF); + } + return (u8)res; } /**************************************************************************** @@ -1334,36 +1224,36 @@ Implements the SHL instruction and side effects. ****************************************************************************/ u16 shl_word(u16 d, u8 s) { - unsigned int cnt, res, cf; - - if (s < 16) { - cnt = s % 16; - if (cnt > 0) { - res = d << 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 = (u16) d; - } - - if (cnt == 1) { - CONDITIONAL_SET_FLAG((((res & 0x8000) == 0x8000) ^ - (ACCESS_FLAG(F_CF) != 0)), F_OF); - } else { - CLEAR_FLAG(F_OF); - } - } else { - res = 0; - CONDITIONAL_SET_FLAG((d << (s - 1)) & 0x8000, F_CF); - CLEAR_FLAG(F_OF); - CLEAR_FLAG(F_SF); - SET_FLAG(F_PF); - SET_FLAG(F_ZF); - } - return (u16) res; + unsigned int cnt, res, cf; + + if (s < 16) { + cnt = s % 16; + if (cnt > 0) { + res = d << cnt; + cf = d & (1 << (16 - cnt)); + CONDITIONAL_SET_FLAG(cf, F_CF); + set_szp_flags_16((u16)res); + } else { + res = (u16) d; + } + + if (cnt == 1) { + CONDITIONAL_SET_FLAG( + (((res & 0x8000) == 0x8000) ^ + (ACCESS_FLAG(F_CF) != 0)), + F_OF); + } else { + CLEAR_FLAG(F_OF); + } + } else { + res = 0; + CONDITIONAL_SET_FLAG((d << (s-1)) & 0x8000, F_CF); + CLEAR_FLAG(F_OF); + CLEAR_FLAG(F_SF); + SET_FLAG(F_PF); + SET_FLAG(F_ZF); + } + return (u16)res; } /**************************************************************************** @@ -1372,35 +1262,33 @@ Implements the SHL instruction and side effects. ****************************************************************************/ u32 shl_long(u32 d, u8 s) { - unsigned int cnt, res, cf; - - if (s < 32) { - cnt = s % 32; - if (cnt > 0) { - res = d << cnt; - cf = d & (1 << (32 - cnt)); - CONDITIONAL_SET_FLAG(cf, F_CF); - CONDITIONAL_SET_FLAG((res & 0xffffffff) == 0, F_ZF); - CONDITIONAL_SET_FLAG(res & 0x80000000, F_SF); - CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF); - } else { - res = d; - } - if (cnt == 1) { - CONDITIONAL_SET_FLAG((((res & 0x80000000) == 0x80000000) ^ - (ACCESS_FLAG(F_CF) != 0)), F_OF); - } else { - CLEAR_FLAG(F_OF); - } - } else { - res = 0; - CONDITIONAL_SET_FLAG((d << (s - 1)) & 0x80000000, F_CF); - CLEAR_FLAG(F_OF); - CLEAR_FLAG(F_SF); - SET_FLAG(F_PF); - SET_FLAG(F_ZF); - } - return res; + unsigned int cnt, res, cf; + + if (s < 32) { + cnt = s % 32; + if (cnt > 0) { + res = d << cnt; + cf = d & (1 << (32 - cnt)); + CONDITIONAL_SET_FLAG(cf, F_CF); + set_szp_flags_32((u32)res); + } else { + res = d; + } + if (cnt == 1) { + CONDITIONAL_SET_FLAG((((res & 0x80000000) == 0x80000000) ^ + (ACCESS_FLAG(F_CF) != 0)), F_OF); + } else { + CLEAR_FLAG(F_OF); + } + } else { + res = 0; + CONDITIONAL_SET_FLAG((d << (s-1)) & 0x80000000, F_CF); + CLEAR_FLAG(F_OF); + CLEAR_FLAG(F_SF); + SET_FLAG(F_PF); + SET_FLAG(F_ZF); + } + return res; } /**************************************************************************** @@ -1409,35 +1297,33 @@ Implements the SHR instruction and side effects. ****************************************************************************/ u8 shr_byte(u8 d, u8 s) { - unsigned int cnt, res, cf; - - if (s < 8) { - cnt = s % 8; - if (cnt > 0) { - cf = d & (1 << (cnt - 1)); - res = d >> cnt; - CONDITIONAL_SET_FLAG(cf, F_CF); - CONDITIONAL_SET_FLAG((res & 0xff) == 0, F_ZF); - CONDITIONAL_SET_FLAG(res & 0x80, F_SF); - CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF); - } else { - res = (u8) d; - } - - if (cnt == 1) { - CONDITIONAL_SET_FLAG(XOR2(res >> 6), F_OF); - } else { - CLEAR_FLAG(F_OF); - } - } else { - res = 0; - CONDITIONAL_SET_FLAG((d >> (s - 1)) & 0x1, F_CF); - CLEAR_FLAG(F_OF); - CLEAR_FLAG(F_SF); - SET_FLAG(F_PF); - SET_FLAG(F_ZF); - } - return (u8) res; + unsigned int cnt, res, cf; + + if (s < 8) { + cnt = s % 8; + if (cnt > 0) { + cf = d & (1 << (cnt - 1)); + res = d >> cnt; + CONDITIONAL_SET_FLAG(cf, F_CF); + set_szp_flags_8((u8)res); + } else { + res = (u8) d; + } + + if (cnt == 1) { + CONDITIONAL_SET_FLAG(XOR2(res >> 6), F_OF); + } else { + CLEAR_FLAG(F_OF); + } + } else { + res = 0; + CONDITIONAL_SET_FLAG((d >> (s-1)) & 0x1, F_CF); + CLEAR_FLAG(F_OF); + CLEAR_FLAG(F_SF); + SET_FLAG(F_PF); + SET_FLAG(F_ZF); + } + return (u8)res; } /**************************************************************************** @@ -1446,35 +1332,33 @@ Implements the SHR instruction and side effects. ****************************************************************************/ u16 shr_word(u16 d, u8 s) { - unsigned int cnt, res, cf; - - if (s < 16) { - cnt = s % 16; - if (cnt > 0) { - cf = d & (1 << (cnt - 1)); - res = d >> 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(XOR2(res >> 14), F_OF); - } else { - CLEAR_FLAG(F_OF); - } - } else { - res = 0; - CLEAR_FLAG(F_CF); - CLEAR_FLAG(F_OF); - SET_FLAG(F_ZF); - CLEAR_FLAG(F_SF); - CLEAR_FLAG(F_PF); - } - return (u16) res; + unsigned int cnt, res, cf; + + if (s < 16) { + cnt = s % 16; + if (cnt > 0) { + cf = d & (1 << (cnt - 1)); + res = d >> cnt; + CONDITIONAL_SET_FLAG(cf, F_CF); + set_szp_flags_16((u16)res); + } else { + res = d; + } + + if (cnt == 1) { + CONDITIONAL_SET_FLAG(XOR2(res >> 14), F_OF); + } else { + CLEAR_FLAG(F_OF); + } + } else { + res = 0; + CLEAR_FLAG(F_CF); + CLEAR_FLAG(F_OF); + SET_FLAG(F_ZF); + CLEAR_FLAG(F_SF); + CLEAR_FLAG(F_PF); + } + return (u16)res; } /**************************************************************************** @@ -1483,34 +1367,32 @@ Implements the SHR instruction and side effects. ****************************************************************************/ u32 shr_long(u32 d, u8 s) { - unsigned int cnt, res, cf; - - if (s < 32) { - cnt = s % 32; - if (cnt > 0) { - cf = d & (1 << (cnt - 1)); - res = d >> cnt; - CONDITIONAL_SET_FLAG(cf, F_CF); - CONDITIONAL_SET_FLAG((res & 0xffffffff) == 0, F_ZF); - CONDITIONAL_SET_FLAG(res & 0x80000000, F_SF); - CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF); - } else { - res = d; - } - if (cnt == 1) { - CONDITIONAL_SET_FLAG(XOR2(res >> 30), F_OF); - } else { - CLEAR_FLAG(F_OF); - } - } else { - res = 0; - CLEAR_FLAG(F_CF); - CLEAR_FLAG(F_OF); - SET_FLAG(F_ZF); - CLEAR_FLAG(F_SF); - CLEAR_FLAG(F_PF); - } - return res; + unsigned int cnt, res, cf; + + if (s < 32) { + cnt = s % 32; + if (cnt > 0) { + cf = d & (1 << (cnt - 1)); + res = d >> cnt; + CONDITIONAL_SET_FLAG(cf, F_CF); + set_szp_flags_32((u32)res); + } else { + res = d; + } + if (cnt == 1) { + CONDITIONAL_SET_FLAG(XOR2(res >> 30), F_OF); + } else { + CLEAR_FLAG(F_OF); + } + } else { + res = 0; + CLEAR_FLAG(F_CF); + CLEAR_FLAG(F_OF); + SET_FLAG(F_ZF); + CLEAR_FLAG(F_SF); + CLEAR_FLAG(F_PF); + } + return res; } /**************************************************************************** @@ -1519,38 +1401,36 @@ Implements the SAR instruction and side effects. ****************************************************************************/ u8 sar_byte(u8 d, u8 s) { - unsigned int cnt, res, cf, mask, sf; - - res = d; - sf = d & 0x80; - cnt = s % 8; - if (cnt > 0 && cnt < 8) { - mask = (1 << (8 - cnt)) - 1; - cf = d & (1 << (cnt - 1)); - res = (d >> cnt) & mask; - CONDITIONAL_SET_FLAG(cf, F_CF); - if (sf) { - res |= ~mask; - } - CONDITIONAL_SET_FLAG((res & 0xff) == 0, F_ZF); - CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF); - CONDITIONAL_SET_FLAG(res & 0x80, F_SF); - } else if (cnt >= 8) { - if (sf) { - res = 0xff; - SET_FLAG(F_CF); - CLEAR_FLAG(F_ZF); - SET_FLAG(F_SF); - SET_FLAG(F_PF); - } else { - res = 0; - CLEAR_FLAG(F_CF); - SET_FLAG(F_ZF); - CLEAR_FLAG(F_SF); - CLEAR_FLAG(F_PF); - } - } - return (u8) res; + unsigned int cnt, res, cf, mask, sf; + + res = d; + sf = d & 0x80; + cnt = s % 8; + if (cnt > 0 && cnt < 8) { + mask = (1 << (8 - cnt)) - 1; + cf = d & (1 << (cnt - 1)); + res = (d >> cnt) & mask; + CONDITIONAL_SET_FLAG(cf, F_CF); + if (sf) { + res |= ~mask; + } + set_szp_flags_8((u8)res); + } else if (cnt >= 8) { + if (sf) { + res = 0xff; + SET_FLAG(F_CF); + CLEAR_FLAG(F_ZF); + SET_FLAG(F_SF); + SET_FLAG(F_PF); + } else { + res = 0; + CLEAR_FLAG(F_CF); + SET_FLAG(F_ZF); + CLEAR_FLAG(F_SF); + CLEAR_FLAG(F_PF); + } + } + return (u8)res; } /**************************************************************************** @@ -1559,38 +1439,36 @@ Implements the SAR instruction and side effects. ****************************************************************************/ u16 sar_word(u16 d, u8 s) { - unsigned int cnt, res, cf, mask, sf; - - sf = d & 0x8000; - cnt = s % 16; - res = d; - if (cnt > 0 && cnt < 16) { - mask = (1 << (16 - cnt)) - 1; - cf = d & (1 << (cnt - 1)); - res = (d >> cnt) & mask; - CONDITIONAL_SET_FLAG(cf, F_CF); - if (sf) { - res |= ~mask; - } - CONDITIONAL_SET_FLAG((res & 0xffff) == 0, F_ZF); - CONDITIONAL_SET_FLAG(res & 0x8000, F_SF); - CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF); - } else if (cnt >= 16) { - if (sf) { - res = 0xffff; - SET_FLAG(F_CF); - CLEAR_FLAG(F_ZF); - SET_FLAG(F_SF); - SET_FLAG(F_PF); - } else { - res = 0; - CLEAR_FLAG(F_CF); - SET_FLAG(F_ZF); - CLEAR_FLAG(F_SF); - CLEAR_FLAG(F_PF); - } - } - return (u16) res; + unsigned int cnt, res, cf, mask, sf; + + sf = d & 0x8000; + cnt = s % 16; + res = d; + if (cnt > 0 && cnt < 16) { + mask = (1 << (16 - cnt)) - 1; + cf = d & (1 << (cnt - 1)); + res = (d >> cnt) & mask; + CONDITIONAL_SET_FLAG(cf, F_CF); + if (sf) { + res |= ~mask; + } + set_szp_flags_16((u16)res); + } else if (cnt >= 16) { + if (sf) { + res = 0xffff; + SET_FLAG(F_CF); + CLEAR_FLAG(F_ZF); + SET_FLAG(F_SF); + SET_FLAG(F_PF); + } else { + res = 0; + CLEAR_FLAG(F_CF); + SET_FLAG(F_ZF); + CLEAR_FLAG(F_SF); + CLEAR_FLAG(F_PF); + } + } + return (u16)res; } /**************************************************************************** @@ -1599,185 +1477,175 @@ Implements the SAR instruction and side effects. ****************************************************************************/ u32 sar_long(u32 d, u8 s) { - u32 cnt, res, cf, mask, sf; - - sf = d & 0x80000000; - cnt = s % 32; - res = d; - if (cnt > 0 && cnt < 32) { - mask = (1 << (32 - cnt)) - 1; - cf = d & (1 << (cnt - 1)); - res = (d >> cnt) & mask; - CONDITIONAL_SET_FLAG(cf, F_CF); - if (sf) { - res |= ~mask; - } - CONDITIONAL_SET_FLAG((res & 0xffffffff) == 0, F_ZF); - CONDITIONAL_SET_FLAG(res & 0x80000000, F_SF); - CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF); - } else if (cnt >= 32) { - if (sf) { - res = 0xffffffff; - SET_FLAG(F_CF); - CLEAR_FLAG(F_ZF); - SET_FLAG(F_SF); - SET_FLAG(F_PF); - } else { - res = 0; - CLEAR_FLAG(F_CF); - SET_FLAG(F_ZF); - CLEAR_FLAG(F_SF); - CLEAR_FLAG(F_PF); - } - } - return res; + u32 cnt, res, cf, mask, sf; + + sf = d & 0x80000000; + cnt = s % 32; + res = d; + if (cnt > 0 && cnt < 32) { + mask = (1 << (32 - cnt)) - 1; + cf = d & (1 << (cnt - 1)); + res = (d >> cnt) & mask; + CONDITIONAL_SET_FLAG(cf, F_CF); + if (sf) { + res |= ~mask; + } + set_szp_flags_32(res); + } else if (cnt >= 32) { + if (sf) { + res = 0xffffffff; + SET_FLAG(F_CF); + CLEAR_FLAG(F_ZF); + SET_FLAG(F_SF); + SET_FLAG(F_PF); + } else { + res = 0; + CLEAR_FLAG(F_CF); + SET_FLAG(F_ZF); + CLEAR_FLAG(F_SF); + CLEAR_FLAG(F_PF); + } + } + return res; } /**************************************************************************** REMARKS: Implements the SHLD instruction and side effects. ****************************************************************************/ -u16 shld_word(u16 d, u16 fill, u8 s) -{ - unsigned int cnt, res, cf; - - if (s < 16) { - cnt = 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 & 0x8000) == 0x8000) ^ - (ACCESS_FLAG(F_CF) != 0)), F_OF); - } else { - CLEAR_FLAG(F_OF); - } - } else { - res = 0; - CONDITIONAL_SET_FLAG((d << (s - 1)) & 0x8000, F_CF); - CLEAR_FLAG(F_OF); - CLEAR_FLAG(F_SF); - SET_FLAG(F_PF); - SET_FLAG(F_ZF); - } - return (u16) res; +u16 shld_word (u16 d, u16 fill, u8 s) +{ + unsigned int cnt, res, cf; + + if (s < 16) { + cnt = s % 16; + if (cnt > 0) { + res = (d << cnt) | (fill >> (16-cnt)); + cf = d & (1 << (16 - cnt)); + CONDITIONAL_SET_FLAG(cf, F_CF); + set_szp_flags_16((u16)res); + } else { + res = d; + } + if (cnt == 1) { + CONDITIONAL_SET_FLAG((((res & 0x8000) == 0x8000) ^ + (ACCESS_FLAG(F_CF) != 0)), F_OF); + } else { + CLEAR_FLAG(F_OF); + } + } else { + res = 0; + CONDITIONAL_SET_FLAG((d << (s-1)) & 0x8000, F_CF); + CLEAR_FLAG(F_OF); + CLEAR_FLAG(F_SF); + SET_FLAG(F_PF); + SET_FLAG(F_ZF); + } + return (u16)res; } /**************************************************************************** REMARKS: Implements the SHLD instruction and side effects. ****************************************************************************/ -u32 shld_long(u32 d, u32 fill, u8 s) -{ - unsigned int cnt, res, cf; - - if (s < 32) { - cnt = s % 32; - if (cnt > 0) { - res = (d << cnt) | (fill >> (32 - cnt)); - cf = d & (1 << (32 - cnt)); - CONDITIONAL_SET_FLAG(cf, F_CF); - CONDITIONAL_SET_FLAG((res & 0xffffffff) == 0, F_ZF); - CONDITIONAL_SET_FLAG(res & 0x80000000, F_SF); - CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF); - } else { - res = d; - } - if (cnt == 1) { - CONDITIONAL_SET_FLAG((((res & 0x80000000) == 0x80000000) ^ - (ACCESS_FLAG(F_CF) != 0)), F_OF); - } else { - CLEAR_FLAG(F_OF); - } - } else { - res = 0; - CONDITIONAL_SET_FLAG((d << (s - 1)) & 0x80000000, F_CF); - CLEAR_FLAG(F_OF); - CLEAR_FLAG(F_SF); - SET_FLAG(F_PF); - SET_FLAG(F_ZF); - } - return res; +u32 shld_long (u32 d, u32 fill, u8 s) +{ + unsigned int cnt, res, cf; + + if (s < 32) { + cnt = s % 32; + if (cnt > 0) { + res = (d << cnt) | (fill >> (32-cnt)); + cf = d & (1 << (32 - cnt)); + CONDITIONAL_SET_FLAG(cf, F_CF); + set_szp_flags_32((u32)res); + } else { + res = d; + } + if (cnt == 1) { + CONDITIONAL_SET_FLAG((((res & 0x80000000) == 0x80000000) ^ + (ACCESS_FLAG(F_CF) != 0)), F_OF); + } else { + CLEAR_FLAG(F_OF); + } + } else { + res = 0; + CONDITIONAL_SET_FLAG((d << (s-1)) & 0x80000000, F_CF); + CLEAR_FLAG(F_OF); + CLEAR_FLAG(F_SF); + SET_FLAG(F_PF); + SET_FLAG(F_ZF); + } + return res; } /**************************************************************************** REMARKS: Implements the SHRD instruction and side effects. ****************************************************************************/ -u16 shrd_word(u16 d, u16 fill, u8 s) -{ - unsigned int cnt, res, cf; - - if (s < 16) { - cnt = s % 16; - if (cnt > 0) { - cf = d & (1 << (cnt - 1)); - res = (d >> cnt) | (fill << (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(XOR2(res >> 14), F_OF); - } else { - CLEAR_FLAG(F_OF); - } - } else { - res = 0; - CLEAR_FLAG(F_CF); - CLEAR_FLAG(F_OF); - SET_FLAG(F_ZF); - CLEAR_FLAG(F_SF); - CLEAR_FLAG(F_PF); - } - return (u16) res; +u16 shrd_word (u16 d, u16 fill, u8 s) +{ + unsigned int cnt, res, cf; + + if (s < 16) { + cnt = s % 16; + if (cnt > 0) { + cf = d & (1 << (cnt - 1)); + res = (d >> cnt) | (fill << (16 - cnt)); + CONDITIONAL_SET_FLAG(cf, F_CF); + set_szp_flags_16((u16)res); + } else { + res = d; + } + + if (cnt == 1) { + CONDITIONAL_SET_FLAG(XOR2(res >> 14), F_OF); + } else { + CLEAR_FLAG(F_OF); + } + } else { + res = 0; + CLEAR_FLAG(F_CF); + CLEAR_FLAG(F_OF); + SET_FLAG(F_ZF); + CLEAR_FLAG(F_SF); + CLEAR_FLAG(F_PF); + } + return (u16)res; } /**************************************************************************** REMARKS: Implements the SHRD instruction and side effects. ****************************************************************************/ -u32 shrd_long(u32 d, u32 fill, u8 s) -{ - unsigned int cnt, res, cf; - - if (s < 32) { - cnt = s % 32; - if (cnt > 0) { - cf = d & (1 << (cnt - 1)); - res = (d >> cnt) | (fill << (32 - cnt)); - CONDITIONAL_SET_FLAG(cf, F_CF); - CONDITIONAL_SET_FLAG((res & 0xffffffff) == 0, F_ZF); - CONDITIONAL_SET_FLAG(res & 0x80000000, F_SF); - CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF); - } else { - res = d; - } - if (cnt == 1) { - CONDITIONAL_SET_FLAG(XOR2(res >> 30), F_OF); - } else { - CLEAR_FLAG(F_OF); - } - } else { - res = 0; - CLEAR_FLAG(F_CF); - CLEAR_FLAG(F_OF); - SET_FLAG(F_ZF); - CLEAR_FLAG(F_SF); - CLEAR_FLAG(F_PF); - } - return res; +u32 shrd_long (u32 d, u32 fill, u8 s) +{ + unsigned int cnt, res, cf; + + if (s < 32) { + cnt = s % 32; + if (cnt > 0) { + cf = d & (1 << (cnt - 1)); + res = (d >> cnt) | (fill << (32 - cnt)); + CONDITIONAL_SET_FLAG(cf, F_CF); + set_szp_flags_32((u32)res); + } else { + res = d; + } + if (cnt == 1) { + CONDITIONAL_SET_FLAG(XOR2(res >> 30), F_OF); + } else { + CLEAR_FLAG(F_OF); + } + } else { + res = 0; + CLEAR_FLAG(F_CF); + CLEAR_FLAG(F_OF); + SET_FLAG(F_ZF); + CLEAR_FLAG(F_SF); + CLEAR_FLAG(F_PF); + } + return res; } /**************************************************************************** @@ -1786,23 +1654,21 @@ Implements the SBB instruction and side effects. ****************************************************************************/ u8 sbb_byte(u8 d, u8 s) { - register u32 res; /* all operands in native machine order */ - register u32 bc; + u32 res; /* all operands in native machine order */ + u32 bc; - if (ACCESS_FLAG(F_CF)) - res = d - s - 1; - else - res = d - s; - CONDITIONAL_SET_FLAG(res & 0x80, F_SF); - CONDITIONAL_SET_FLAG((res & 0xff) == 0, F_ZF); - CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF); + if (ACCESS_FLAG(F_CF)) + res = d - s - 1; + else + res = d - s; + set_szp_flags_8((u8)res); - /* calculate the borrow chain. See note at top */ - bc = (res & (~d | s)) | (~d & s); - CONDITIONAL_SET_FLAG(bc & 0x80, F_CF); - CONDITIONAL_SET_FLAG(XOR2(bc >> 6), F_OF); - CONDITIONAL_SET_FLAG(bc & 0x8, F_AF); - return (u8) res; + /* calculate the borrow chain. See note at top */ + bc = (res & (~d | s)) | (~d & s); + CONDITIONAL_SET_FLAG(bc & 0x80, F_CF); + CONDITIONAL_SET_FLAG(XOR2(bc >> 6), F_OF); + CONDITIONAL_SET_FLAG(bc & 0x8, F_AF); + return (u8)res; } /**************************************************************************** @@ -1811,23 +1677,21 @@ Implements the SBB instruction and side effects. ****************************************************************************/ u16 sbb_word(u16 d, u16 s) { - register u32 res; /* all operands in native machine order */ - register u32 bc; + u32 res; /* all operands in native machine order */ + u32 bc; - if (ACCESS_FLAG(F_CF)) - res = d - s - 1; - else - res = d - s; - CONDITIONAL_SET_FLAG(res & 0x8000, F_SF); - CONDITIONAL_SET_FLAG((res & 0xffff) == 0, F_ZF); - CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF); + if (ACCESS_FLAG(F_CF)) + res = d - s - 1; + else + res = d - s; + set_szp_flags_16((u16)res); - /* calculate the borrow chain. See note at top */ - bc = (res & (~d | s)) | (~d & s); - CONDITIONAL_SET_FLAG(bc & 0x8000, F_CF); - CONDITIONAL_SET_FLAG(XOR2(bc >> 14), F_OF); - CONDITIONAL_SET_FLAG(bc & 0x8, F_AF); - return (u16) res; + /* calculate the borrow chain. See note at top */ + bc = (res & (~d | s)) | (~d & s); + CONDITIONAL_SET_FLAG(bc & 0x8000, F_CF); + CONDITIONAL_SET_FLAG(XOR2(bc >> 14), F_OF); + CONDITIONAL_SET_FLAG(bc & 0x8, F_AF); + return (u16)res; } /**************************************************************************** @@ -1836,23 +1700,22 @@ Implements the SBB instruction and side effects. ****************************************************************************/ u32 sbb_long(u32 d, u32 s) { - register u32 res; /* all operands in native machine order */ - register u32 bc; + u32 res; /* all operands in native machine order */ + u32 bc; + + if (ACCESS_FLAG(F_CF)) + res = d - s - 1; + else + res = d - s; - if (ACCESS_FLAG(F_CF)) - res = d - s - 1; - else - res = d - s; - CONDITIONAL_SET_FLAG(res & 0x80000000, F_SF); - CONDITIONAL_SET_FLAG((res & 0xffffffff) == 0, F_ZF); - CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF); + set_szp_flags_32(res); - /* calculate the borrow chain. See note at top */ - bc = (res & (~d | s)) | (~d & s); - CONDITIONAL_SET_FLAG(bc & 0x80000000, F_CF); - CONDITIONAL_SET_FLAG(XOR2(bc >> 30), F_OF); - CONDITIONAL_SET_FLAG(bc & 0x8, F_AF); - return res; + /* calculate the borrow chain. See note at top */ + bc = (res & (~d | s)) | (~d & s); + CONDITIONAL_SET_FLAG(bc & 0x80000000, F_CF); + CONDITIONAL_SET_FLAG(XOR2(bc >> 30), F_OF); + CONDITIONAL_SET_FLAG(bc & 0x8, F_AF); + return res; } /**************************************************************************** @@ -1861,20 +1724,18 @@ Implements the SUB instruction and side effects. ****************************************************************************/ u8 sub_byte(u8 d, u8 s) { - register u32 res; /* all operands in native machine order */ - register u32 bc; + u32 res; /* all operands in native machine order */ + u32 bc; - res = d - s; - CONDITIONAL_SET_FLAG(res & 0x80, F_SF); - CONDITIONAL_SET_FLAG((res & 0xff) == 0, F_ZF); - CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF); + res = d - s; + set_szp_flags_8((u8)res); - /* calculate the borrow chain. See note at top */ - bc = (res & (~d | s)) | (~d & s); - CONDITIONAL_SET_FLAG(bc & 0x80, F_CF); - CONDITIONAL_SET_FLAG(XOR2(bc >> 6), F_OF); - CONDITIONAL_SET_FLAG(bc & 0x8, F_AF); - return (u8) res; + /* calculate the borrow chain. See note at top */ + bc = (res & (~d | s)) | (~d & s); + CONDITIONAL_SET_FLAG(bc & 0x80, F_CF); + CONDITIONAL_SET_FLAG(XOR2(bc >> 6), F_OF); + CONDITIONAL_SET_FLAG(bc & 0x8, F_AF); + return (u8)res; } /**************************************************************************** @@ -1883,20 +1744,18 @@ Implements the SUB instruction and side effects. ****************************************************************************/ u16 sub_word(u16 d, u16 s) { - register u32 res; /* all operands in native machine order */ - register u32 bc; + u32 res; /* all operands in native machine order */ + u32 bc; - res = d - s; - CONDITIONAL_SET_FLAG(res & 0x8000, F_SF); - CONDITIONAL_SET_FLAG((res & 0xffff) == 0, F_ZF); - CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF); + res = d - s; + set_szp_flags_16((u16)res); - /* calculate the borrow chain. See note at top */ - bc = (res & (~d | s)) | (~d & s); - CONDITIONAL_SET_FLAG(bc & 0x8000, F_CF); - CONDITIONAL_SET_FLAG(XOR2(bc >> 14), F_OF); - CONDITIONAL_SET_FLAG(bc & 0x8, F_AF); - return (u16) res; + /* calculate the borrow chain. See note at top */ + bc = (res & (~d | s)) | (~d & s); + CONDITIONAL_SET_FLAG(bc & 0x8000, F_CF); + CONDITIONAL_SET_FLAG(XOR2(bc >> 14), F_OF); + CONDITIONAL_SET_FLAG(bc & 0x8, F_AF); + return (u16)res; } /**************************************************************************** @@ -1905,20 +1764,18 @@ Implements the SUB instruction and side effects. ****************************************************************************/ u32 sub_long(u32 d, u32 s) { - register u32 res; /* all operands in native machine order */ - register u32 bc; + u32 res; /* all operands in native machine order */ + u32 bc; - res = d - s; - CONDITIONAL_SET_FLAG(res & 0x80000000, F_SF); - CONDITIONAL_SET_FLAG((res & 0xffffffff) == 0, F_ZF); - CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF); + res = d - s; + set_szp_flags_32(res); - /* calculate the borrow chain. See note at top */ - bc = (res & (~d | s)) | (~d & s); - CONDITIONAL_SET_FLAG(bc & 0x80000000, F_CF); - CONDITIONAL_SET_FLAG(XOR2(bc >> 30), F_OF); - CONDITIONAL_SET_FLAG(bc & 0x8, F_AF); - return res; + /* calculate the borrow chain. See note at top */ + bc = (res & (~d | s)) | (~d & s); + CONDITIONAL_SET_FLAG(bc & 0x80000000, F_CF); + CONDITIONAL_SET_FLAG(XOR2(bc >> 30), F_OF); + CONDITIONAL_SET_FLAG(bc & 0x8, F_AF); + return res; } /**************************************************************************** @@ -1927,16 +1784,14 @@ Implements the TEST instruction and side effects. ****************************************************************************/ void test_byte(u8 d, u8 s) { - register u32 res; /* all operands in native machine order */ + u32 res; /* all operands in native machine order */ - res = d & s; + res = d & s; - CLEAR_FLAG(F_OF); - CONDITIONAL_SET_FLAG(res & 0x80, F_SF); - CONDITIONAL_SET_FLAG(res == 0, F_ZF); - CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF); - /* AF == dont care */ - CLEAR_FLAG(F_CF); + CLEAR_FLAG(F_OF); + set_szp_flags_8((u8)res); + /* AF == dont care */ + CLEAR_FLAG(F_CF); } /**************************************************************************** @@ -1945,16 +1800,14 @@ Implements the TEST instruction and side effects. ****************************************************************************/ void test_word(u16 d, u16 s) { - register u32 res; /* all operands in native machine order */ + u32 res; /* all operands in native machine order */ - res = d & s; + res = d & s; - CLEAR_FLAG(F_OF); - CONDITIONAL_SET_FLAG(res & 0x8000, F_SF); - CONDITIONAL_SET_FLAG(res == 0, F_ZF); - CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF); - /* AF == dont care */ - CLEAR_FLAG(F_CF); + CLEAR_FLAG(F_OF); + set_szp_flags_16((u16)res); + /* AF == dont care */ + CLEAR_FLAG(F_CF); } /**************************************************************************** @@ -1963,16 +1816,14 @@ Implements the TEST instruction and side effects. ****************************************************************************/ void test_long(u32 d, u32 s) { - register u32 res; /* all operands in native machine order */ + u32 res; /* all operands in native machine order */ - res = d & s; + res = d & s; - CLEAR_FLAG(F_OF); - CONDITIONAL_SET_FLAG(res & 0x80000000, F_SF); - CONDITIONAL_SET_FLAG(res == 0, F_ZF); - CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF); - /* AF == dont care */ - CLEAR_FLAG(F_CF); + CLEAR_FLAG(F_OF); + set_szp_flags_32(res); + /* AF == dont care */ + CLEAR_FLAG(F_CF); } /**************************************************************************** @@ -1981,16 +1832,11 @@ Implements the XOR instruction and side effects. ****************************************************************************/ u8 xor_byte(u8 d, u8 s) { - register u8 res; /* all operands in native machine order */ + u8 res; /* all operands in native machine order */ - res = d ^ s; - CLEAR_FLAG(F_OF); - CONDITIONAL_SET_FLAG(res & 0x80, F_SF); - CONDITIONAL_SET_FLAG(res == 0, F_ZF); - CONDITIONAL_SET_FLAG(PARITY(res), F_PF); - CLEAR_FLAG(F_CF); - CLEAR_FLAG(F_AF); - return res; + res = d ^ s; + no_carry_byte_side_eff(res); + return res; } /**************************************************************************** @@ -1999,16 +1845,11 @@ Implements the XOR instruction and side effects. ****************************************************************************/ u16 xor_word(u16 d, u16 s) { - register u16 res; /* all operands in native machine order */ + u16 res; /* all operands in native machine order */ - res = d ^ s; - CLEAR_FLAG(F_OF); - CONDITIONAL_SET_FLAG(res & 0x8000, F_SF); - CONDITIONAL_SET_FLAG(res == 0, F_ZF); - CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF); - CLEAR_FLAG(F_CF); - CLEAR_FLAG(F_AF); - return res; + res = d ^ s; + no_carry_word_side_eff(res); + return res; } /**************************************************************************** @@ -2017,16 +1858,11 @@ Implements the XOR instruction and side effects. ****************************************************************************/ u32 xor_long(u32 d, u32 s) { - register u32 res; /* all operands in native machine order */ + u32 res; /* all operands in native machine order */ - res = d ^ s; - CLEAR_FLAG(F_OF); - CONDITIONAL_SET_FLAG(res & 0x80000000, F_SF); - CONDITIONAL_SET_FLAG(res == 0, F_ZF); - CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF); - CLEAR_FLAG(F_CF); - CLEAR_FLAG(F_AF); - return res; + res = d ^ s; + no_carry_long_side_eff(res); + return res; } /**************************************************************************** @@ -2035,17 +1871,17 @@ Implements the IMUL instruction and side effects. ****************************************************************************/ void imul_byte(u8 s) { - s16 res = (s16) ((s8) M.x86.R_AL * (s8) s); + s16 res = (s16)((s8)M.x86.R_AL * (s8)s); - M.x86.R_AX = res; - if (((M.x86.R_AL & 0x80) == 0 && M.x86.R_AH == 0x00) || - ((M.x86.R_AL & 0x80) != 0 && M.x86.R_AH == 0xFF)) { - CLEAR_FLAG(F_CF); - CLEAR_FLAG(F_OF); - } else { - SET_FLAG(F_CF); - SET_FLAG(F_OF); - } + M.x86.R_AX = res; + if (((M.x86.R_AL & 0x80) == 0 && M.x86.R_AH == 0x00) || + ((M.x86.R_AL & 0x80) != 0 && M.x86.R_AH == 0xFF)) { + CLEAR_FLAG(F_CF); + CLEAR_FLAG(F_OF); + } else { + SET_FLAG(F_CF); + SET_FLAG(F_OF); + } } /**************************************************************************** @@ -2054,55 +1890,55 @@ Implements the IMUL instruction and side effects. ****************************************************************************/ void imul_word(u16 s) { - s32 res = (s16) M.x86.R_AX * (s16) s; + s32 res = (s16)M.x86.R_AX * (s16)s; - M.x86.R_AX = (u16) res; - M.x86.R_DX = (u16) (res >> 16); - if (((M.x86.R_AX & 0x8000) == 0 && M.x86.R_DX == 0x00) || - ((M.x86.R_AX & 0x8000) != 0 && M.x86.R_DX == 0xFF)) { - CLEAR_FLAG(F_CF); - CLEAR_FLAG(F_OF); - } else { - SET_FLAG(F_CF); - SET_FLAG(F_OF); - } + M.x86.R_AX = (u16)res; + M.x86.R_DX = (u16)(res >> 16); + if (((M.x86.R_AX & 0x8000) == 0 && M.x86.R_DX == 0x0000) || + ((M.x86.R_AX & 0x8000) != 0 && M.x86.R_DX == 0xFFFF)) { + CLEAR_FLAG(F_CF); + CLEAR_FLAG(F_OF); + } else { + SET_FLAG(F_CF); + SET_FLAG(F_OF); + } } /**************************************************************************** REMARKS: Implements the IMUL instruction and side effects. ****************************************************************************/ -void imul_long_direct(u32 * res_lo, u32 * res_hi, u32 d, u32 s) +void imul_long_direct(u32 *res_lo, u32* res_hi,u32 d, u32 s) { -#ifdef __HAS_LONG_LONG__ - s64 res = (s32) d * (s32) s; +#ifdef __HAS_LONG_LONG__ + s64 res = (s32)d * (s32)s; - *res_lo = (u32) res; - *res_hi = (u32) (res >> 32); + *res_lo = (u32)res; + *res_hi = (u32)(res >> 32); #else - u32 d_lo, d_hi, d_sign; - u32 s_lo, s_hi, s_sign; - u32 rlo_lo, rlo_hi, rhi_lo; - - if ((d_sign = d & 0x80000000) != 0) - d = -d; - d_lo = d & 0xFFFF; - d_hi = d >> 16; - if ((s_sign = s & 0x80000000) != 0) - s = -s; - s_lo = s & 0xFFFF; - s_hi = s >> 16; - rlo_lo = d_lo * s_lo; - rlo_hi = (d_hi * s_lo + d_lo * s_hi) + (rlo_lo >> 16); - rhi_lo = d_hi * s_hi + (rlo_hi >> 16); - *res_lo = (rlo_hi << 16) | (rlo_lo & 0xFFFF); - *res_hi = rhi_lo; - if (d_sign != s_sign) { - d = ~*res_lo; - s = (((d & 0xFFFF) + 1) >> 16) + (d >> 16); - *res_lo = ~*res_lo + 1; - *res_hi = ~*res_hi + (s >> 16); - } + u32 d_lo,d_hi,d_sign; + u32 s_lo,s_hi,s_sign; + u32 rlo_lo,rlo_hi,rhi_lo; + + if ((d_sign = d & 0x80000000) != 0) + d = -d; + d_lo = d & 0xFFFF; + d_hi = d >> 16; + if ((s_sign = s & 0x80000000) != 0) + s = -s; + s_lo = s & 0xFFFF; + s_hi = s >> 16; + rlo_lo = d_lo * s_lo; + rlo_hi = (d_hi * s_lo + d_lo * s_hi) + (rlo_lo >> 16); + rhi_lo = d_hi * s_hi + (rlo_hi >> 16); + *res_lo = (rlo_hi << 16) | (rlo_lo & 0xFFFF); + *res_hi = rhi_lo; + if (d_sign != s_sign) { + d = ~*res_lo; + s = (((d & 0xFFFF) + 1) >> 16) + (d >> 16); + *res_lo = ~*res_lo+1; + *res_hi = ~*res_hi+(s >> 16); + } #endif } @@ -2112,15 +1948,15 @@ Implements the IMUL instruction and side effects. ****************************************************************************/ void imul_long(u32 s) { - imul_long_direct(&M.x86.R_EAX, &M.x86.R_EDX, M.x86.R_EAX, s); - if (((M.x86.R_EAX & 0x80000000) == 0 && M.x86.R_EDX == 0x00) || - ((M.x86.R_EAX & 0x80000000) != 0 && M.x86.R_EDX == 0xFF)) { - CLEAR_FLAG(F_CF); - CLEAR_FLAG(F_OF); - } else { - SET_FLAG(F_CF); - SET_FLAG(F_OF); - } + imul_long_direct(&M.x86.R_EAX,&M.x86.R_EDX,M.x86.R_EAX,s); + if (((M.x86.R_EAX & 0x80000000) == 0 && M.x86.R_EDX == 0x00000000) || + ((M.x86.R_EAX & 0x80000000) != 0 && M.x86.R_EDX == 0xFFFFFFFF)) { + CLEAR_FLAG(F_CF); + CLEAR_FLAG(F_OF); + } else { + SET_FLAG(F_CF); + SET_FLAG(F_OF); + } } /**************************************************************************** @@ -2129,16 +1965,16 @@ Implements the MUL instruction and side effects. ****************************************************************************/ void mul_byte(u8 s) { - u16 res = (u16) (M.x86.R_AL * s); + u16 res = (u16)(M.x86.R_AL * s); - M.x86.R_AX = res; - if (M.x86.R_AH == 0) { - CLEAR_FLAG(F_CF); - CLEAR_FLAG(F_OF); - } else { - SET_FLAG(F_CF); - SET_FLAG(F_OF); - } + M.x86.R_AX = res; + if (M.x86.R_AH == 0) { + CLEAR_FLAG(F_CF); + CLEAR_FLAG(F_OF); + } else { + SET_FLAG(F_CF); + SET_FLAG(F_OF); + } } /**************************************************************************** @@ -2147,17 +1983,17 @@ Implements the MUL instruction and side effects. ****************************************************************************/ void mul_word(u16 s) { - u32 res = M.x86.R_AX * s; + u32 res = M.x86.R_AX * s; - M.x86.R_AX = (u16) res; - M.x86.R_DX = (u16) (res >> 16); - if (M.x86.R_DX == 0) { - CLEAR_FLAG(F_CF); - CLEAR_FLAG(F_OF); - } else { - SET_FLAG(F_CF); - SET_FLAG(F_OF); - } + M.x86.R_AX = (u16)res; + M.x86.R_DX = (u16)(res >> 16); + if (M.x86.R_DX == 0) { + CLEAR_FLAG(F_CF); + CLEAR_FLAG(F_OF); + } else { + SET_FLAG(F_CF); + SET_FLAG(F_OF); + } } /**************************************************************************** @@ -2166,35 +2002,34 @@ Implements the MUL instruction and side effects. ****************************************************************************/ void mul_long(u32 s) { -#ifdef __HAS_LONG_LONG__ - u64 res = (u32) M.x86.R_EAX * (u32) s; +#ifdef __HAS_LONG_LONG__ + u64 res = (u32)M.x86.R_EAX * (u32)s; - M.x86.R_EAX = (u32) res; - M.x86.R_EDX = (u32) (res >> 32); + M.x86.R_EAX = (u32)res; + M.x86.R_EDX = (u32)(res >> 32); #else - u32 a, a_lo, a_hi; - u32 s_lo, s_hi; - u32 rlo_lo, rlo_hi, rhi_lo; - - a = M.x86.R_EAX; - a_lo = a & 0xFFFF; - a_hi = a >> 16; - s_lo = s & 0xFFFF; - s_hi = s >> 16; - rlo_lo = a_lo * s_lo; - rlo_hi = (a_hi * s_lo + a_lo * s_hi) + (rlo_lo >> 16); - rhi_lo = a_hi * s_hi + (rlo_hi >> 16); - M.x86.R_EAX = (rlo_hi << 16) | (rlo_lo & 0xFFFF); - M.x86.R_EDX = rhi_lo; + u32 a,a_lo,a_hi; + u32 s_lo,s_hi; + u32 rlo_lo,rlo_hi,rhi_lo; + + a = M.x86.R_EAX; + a_lo = a & 0xFFFF; + a_hi = a >> 16; + s_lo = s & 0xFFFF; + s_hi = s >> 16; + rlo_lo = a_lo * s_lo; + rlo_hi = (a_hi * s_lo + a_lo * s_hi) + (rlo_lo >> 16); + rhi_lo = a_hi * s_hi + (rlo_hi >> 16); + M.x86.R_EAX = (rlo_hi << 16) | (rlo_lo & 0xFFFF); + M.x86.R_EDX = rhi_lo; #endif - - if (M.x86.R_EDX == 0) { - CLEAR_FLAG(F_CF); - CLEAR_FLAG(F_OF); - } else { - SET_FLAG(F_CF); - SET_FLAG(F_OF); - } + if (M.x86.R_EDX == 0) { + CLEAR_FLAG(F_CF); + CLEAR_FLAG(F_OF); + } else { + SET_FLAG(F_CF); + SET_FLAG(F_OF); + } } /**************************************************************************** @@ -2203,21 +2038,21 @@ Implements the IDIV instruction and side effects. ****************************************************************************/ void idiv_byte(u8 s) { - s32 dvd, div, mod; + s32 dvd, div, mod; - dvd = (s16) M.x86.R_AX; - if (s == 0) { - x86emu_intr_raise(0); - return; - } - div = dvd / (s8) s; - mod = dvd % (s8) s; - if (abs(div) > 0x7f) { - x86emu_intr_raise(0); - return; - } - M.x86.R_AL = (s8) div; - M.x86.R_AH = (s8) mod; + dvd = (s16)M.x86.R_AX; + if (s == 0) { + x86emu_intr_raise(0); + return; + } + div = dvd / (s8)s; + mod = dvd % (s8)s; + if (abs(div) > 0x7f) { + x86emu_intr_raise(0); + return; + } + M.x86.R_AL = (s8) div; + M.x86.R_AH = (s8) mod; } /**************************************************************************** @@ -2226,26 +2061,26 @@ Implements the IDIV instruction and side effects. ****************************************************************************/ void idiv_word(u16 s) { - s32 dvd, div, mod; + s32 dvd, div, mod; - dvd = (((s32) M.x86.R_DX) << 16) | M.x86.R_AX; - if (s == 0) { - x86emu_intr_raise(0); - return; - } - div = dvd / (s16) s; - mod = dvd % (s16) s; - if (abs(div) > 0x7fff) { - x86emu_intr_raise(0); - return; - } - CLEAR_FLAG(F_CF); - CLEAR_FLAG(F_SF); - CONDITIONAL_SET_FLAG(div == 0, F_ZF); - CONDITIONAL_SET_FLAG(PARITY(mod & 0xff), F_PF); + dvd = (((s32)M.x86.R_DX) << 16) | M.x86.R_AX; + if (s == 0) { + x86emu_intr_raise(0); + return; + } + div = dvd / (s16)s; + mod = dvd % (s16)s; + if (abs(div) > 0x7fff) { + x86emu_intr_raise(0); + return; + } + CLEAR_FLAG(F_CF); + CLEAR_FLAG(F_SF); + CONDITIONAL_SET_FLAG(div == 0, F_ZF); + set_parity_flag(mod); - M.x86.R_AX = (u16) div; - M.x86.R_DX = (u16) mod; + M.x86.R_AX = (u16)div; + M.x86.R_DX = (u16)mod; } /**************************************************************************** @@ -2254,72 +2089,72 @@ Implements the IDIV instruction and side effects. ****************************************************************************/ void idiv_long(u32 s) { -#ifdef __HAS_LONG_LONG__ - s64 dvd, div, mod; - - dvd = (((s64) M.x86.R_EDX) << 32) | M.x86.R_EAX; - if (s == 0) { - x86emu_intr_raise(0); - return; - } - div = dvd / (s32) s; - mod = dvd % (s32) s; - if (abs(div) > 0x7fffffff) { - x86emu_intr_raise(0); - return; - } +#ifdef __HAS_LONG_LONG__ + s64 dvd, div, mod; + + dvd = (((s64)M.x86.R_EDX) << 32) | M.x86.R_EAX; + if (s == 0) { + x86emu_intr_raise(0); + return; + } + div = dvd / (s32)s; + mod = dvd % (s32)s; + if (abs(div) > 0x7fffffff) { + x86emu_intr_raise(0); + return; + } #else - s32 div = 0, mod; - s32 h_dvd = M.x86.R_EDX; - u32 l_dvd = M.x86.R_EAX; - u32 abs_s = s & 0x7FFFFFFF; - u32 abs_h_dvd = h_dvd & 0x7FFFFFFF; - u32 h_s = abs_s >> 1; - u32 l_s = abs_s << 31; - int counter = 31; - int carry; - - if (s == 0) { - x86emu_intr_raise(0); - return; - } - do { - div <<= 1; - carry = (l_dvd >= l_s) ? 0 : 1; - - if (abs_h_dvd < (h_s + carry)) { - h_s >>= 1; - l_s = abs_s << (--counter); - continue; - } else { - abs_h_dvd -= (h_s + carry); - l_dvd = carry ? ((0xFFFFFFFF - l_s) + l_dvd + 1) - : (l_dvd - l_s); - h_s >>= 1; - l_s = abs_s << (--counter); - div |= 1; - continue; - } - - } while (counter > -1); - /* overflow */ - if (abs_h_dvd || (l_dvd > abs_s)) { - x86emu_intr_raise(0); - return; - } - /* sign */ - div |= ((h_dvd & 0x10000000) ^ (s & 0x10000000)); - mod = l_dvd; + s32 div = 0, mod; + s32 h_dvd = M.x86.R_EDX; + u32 l_dvd = M.x86.R_EAX; + u32 abs_s = s & 0x7FFFFFFF; + u32 abs_h_dvd = h_dvd & 0x7FFFFFFF; + u32 h_s = abs_s >> 1; + u32 l_s = abs_s << 31; + int counter = 31; + int carry; + + if (s == 0) { + x86emu_intr_raise(0); + return; + } + do { + div <<= 1; + carry = (l_dvd >= l_s) ? 0 : 1; + + if (abs_h_dvd < (h_s + carry)) { + h_s >>= 1; + l_s = abs_s << (--counter); + continue; + } else { + abs_h_dvd -= (h_s + carry); + l_dvd = carry ? ((0xFFFFFFFF - l_s) + l_dvd + 1) + : (l_dvd - l_s); + h_s >>= 1; + l_s = abs_s << (--counter); + div |= 1; + continue; + } + + } while (counter > -1); + /* overflow */ + if (abs_h_dvd || (l_dvd > abs_s)) { + x86emu_intr_raise(0); + return; + } + /* sign */ + div |= ((h_dvd & 0x10000000) ^ (s & 0x10000000)); + mod = l_dvd; #endif - CLEAR_FLAG(F_CF); - CLEAR_FLAG(F_AF); - CLEAR_FLAG(F_SF); - SET_FLAG(F_ZF); - CONDITIONAL_SET_FLAG(PARITY(mod & 0xff), F_PF); + CLEAR_FLAG(F_CF); + CLEAR_FLAG(F_AF); + CLEAR_FLAG(F_SF); + SET_FLAG(F_ZF); + set_parity_flag(mod); - M.x86.R_EAX = (u32) div; - M.x86.R_EDX = (u32) mod; + M.x86.R_EAX = (u32)div; + M.x86.R_EDX = (u32)mod; } /**************************************************************************** @@ -2328,21 +2163,21 @@ Implements the DIV instruction and side effects. ****************************************************************************/ void div_byte(u8 s) { - u32 dvd, div, mod; + u32 dvd, div, mod; - dvd = M.x86.R_AX; - if (s == 0) { - x86emu_intr_raise(0); - return; - } - div = dvd / (u8) s; - mod = dvd % (u8) s; - if (abs(div) > 0xff) { - x86emu_intr_raise(0); - return; - } - M.x86.R_AL = (u8) div; - M.x86.R_AH = (u8) mod; + dvd = M.x86.R_AX; + if (s == 0) { + x86emu_intr_raise(0); + return; + } + div = dvd / (u8)s; + mod = dvd % (u8)s; + if (abs(div) > 0xff) { + x86emu_intr_raise(0); + return; + } + M.x86.R_AL = (u8)div; + M.x86.R_AH = (u8)mod; } /**************************************************************************** @@ -2351,26 +2186,26 @@ Implements the DIV instruction and side effects. ****************************************************************************/ void div_word(u16 s) { - u32 dvd, div, mod; + u32 dvd, div, mod; - dvd = (((u32) M.x86.R_DX) << 16) | M.x86.R_AX; - if (s == 0) { - x86emu_intr_raise(0); - return; - } - div = dvd / (u16) s; - mod = dvd % (u16) s; - if (abs(div) > 0xffff) { - x86emu_intr_raise(0); - return; - } - CLEAR_FLAG(F_CF); - CLEAR_FLAG(F_SF); - CONDITIONAL_SET_FLAG(div == 0, F_ZF); - CONDITIONAL_SET_FLAG(PARITY(mod & 0xff), F_PF); + dvd = (((u32)M.x86.R_DX) << 16) | M.x86.R_AX; + if (s == 0) { + x86emu_intr_raise(0); + return; + } + div = dvd / (u16)s; + mod = dvd % (u16)s; + if (abs(div) > 0xffff) { + x86emu_intr_raise(0); + return; + } + CLEAR_FLAG(F_CF); + CLEAR_FLAG(F_SF); + CONDITIONAL_SET_FLAG(div == 0, F_ZF); + set_parity_flag(mod); - M.x86.R_AX = (u16) div; - M.x86.R_DX = (u16) mod; + M.x86.R_AX = (u16)div; + M.x86.R_DX = (u16)mod; } /**************************************************************************** @@ -2379,212 +2214,167 @@ Implements the DIV instruction and side effects. ****************************************************************************/ void div_long(u32 s) { -#ifdef __HAS_LONG_LONG__ - u64 dvd, div, mod; - - dvd = (((u64) M.x86.R_EDX) << 32) | M.x86.R_EAX; - if (s == 0) { - x86emu_intr_raise(0); - return; - } - div = dvd / (u32) s; - mod = dvd % (u32) s; - if (abs(div) > 0xffffffff) { - x86emu_intr_raise(0); - return; - } +#ifdef __HAS_LONG_LONG__ + u64 dvd, div, mod; + + dvd = (((u64)M.x86.R_EDX) << 32) | M.x86.R_EAX; + if (s == 0) { + x86emu_intr_raise(0); + return; + } + div = dvd / (u32)s; + mod = dvd % (u32)s; + if (abs(div) > 0xffffffff) { + x86emu_intr_raise(0); + return; + } #else - s32 div = 0, mod; - s32 h_dvd = M.x86.R_EDX; - u32 l_dvd = M.x86.R_EAX; - - u32 h_s = s; - u32 l_s = 0; - int counter = 32; - int carry; - - if (s == 0) { - x86emu_intr_raise(0); - return; - } - do { - div <<= 1; - carry = (l_dvd >= l_s) ? 0 : 1; - - if (h_dvd < (h_s + carry)) { - h_s >>= 1; - l_s = s << (--counter); - continue; - } else { - h_dvd -= (h_s + carry); - l_dvd = carry ? ((0xFFFFFFFF - l_s) + l_dvd + 1) - : (l_dvd - l_s); - h_s >>= 1; - l_s = s << (--counter); - div |= 1; - continue; - } - - } while (counter > -1); - /* overflow */ - if (h_dvd || (l_dvd > s)) { - x86emu_intr_raise(0); - return; - } - mod = l_dvd; + s32 div = 0, mod; + s32 h_dvd = M.x86.R_EDX; + u32 l_dvd = M.x86.R_EAX; + + u32 h_s = s; + u32 l_s = 0; + int counter = 32; + int carry; + + if (s == 0) { + x86emu_intr_raise(0); + return; + } + do { + div <<= 1; + carry = (l_dvd >= l_s) ? 0 : 1; + + if (h_dvd < (h_s + carry)) { + h_s >>= 1; + l_s = s << (--counter); + continue; + } else { + h_dvd -= (h_s + carry); + l_dvd = carry ? ((0xFFFFFFFF - l_s) + l_dvd + 1) + : (l_dvd - l_s); + h_s >>= 1; + l_s = s << (--counter); + div |= 1; + continue; + } + + } while (counter > -1); + /* overflow */ + if (h_dvd || (l_dvd > s)) { + x86emu_intr_raise(0); + return; + } + mod = l_dvd; #endif - CLEAR_FLAG(F_CF); - CLEAR_FLAG(F_AF); - CLEAR_FLAG(F_SF); - SET_FLAG(F_ZF); - CONDITIONAL_SET_FLAG(PARITY(mod & 0xff), F_PF); + CLEAR_FLAG(F_CF); + CLEAR_FLAG(F_AF); + CLEAR_FLAG(F_SF); + SET_FLAG(F_ZF); + set_parity_flag(mod); - M.x86.R_EAX = (u32) div; - M.x86.R_EDX = (u32) mod; + M.x86.R_EAX = (u32)div; + M.x86.R_EDX = (u32)mod; } -#endif /* __HAVE_INLINE_ASSEMBLER__ */ - /**************************************************************************** REMARKS: Implements the IN string instruction and side effects. ****************************************************************************/ + +static void single_in(int size) +{ + if(size == 1) + store_data_byte_abs(M.x86.R_ES, M.x86.R_DI,(*sys_inb)(M.x86.R_DX)); + else if (size == 2) + store_data_word_abs(M.x86.R_ES, M.x86.R_DI,(*sys_inw)(M.x86.R_DX)); + else + store_data_long_abs(M.x86.R_ES, M.x86.R_DI,(*sys_inl)(M.x86.R_DX)); +} + void ins(int size) { - int inc = size; - - if (ACCESS_FLAG(F_DF)) { - inc = -size; - } - if (M.x86.mode & (SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE)) { - /* dont care whether REPE or REPNE */ - /* in until CX is ZERO. */ - u32 count = ((M.x86.mode & SYSMODE_PREFIX_DATA) ? - M.x86.R_ECX : M.x86.R_CX); - switch (size) { - case 1: - while (count--) { - store_data_byte_abs(M.x86.R_ES, M.x86.R_DI, - (*sys_inb) (M.x86.R_DX)); - M.x86.R_DI += inc; - } - break; - - case 2: - while (count--) { - store_data_word_abs(M.x86.R_ES, M.x86.R_DI, - (*sys_inw) (M.x86.R_DX)); - M.x86.R_DI += inc; - } - break; - case 4: - while (count--) { - store_data_long_abs(M.x86.R_ES, M.x86.R_DI, - (*sys_inl) (M.x86.R_DX)); - M.x86.R_DI += inc; - break; - } - } - M.x86.R_CX = 0; - if (M.x86.mode & SYSMODE_PREFIX_DATA) { - M.x86.R_ECX = 0; - } - M.x86.mode &= ~(SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE); - } else { - switch (size) { - case 1: - store_data_byte_abs(M.x86.R_ES, M.x86.R_DI, - (*sys_inb) (M.x86.R_DX)); - break; - case 2: - store_data_word_abs(M.x86.R_ES, M.x86.R_DI, - (*sys_inw) (M.x86.R_DX)); - break; - case 4: - store_data_long_abs(M.x86.R_ES, M.x86.R_DI, - (*sys_inl) (M.x86.R_DX)); - break; - } - M.x86.R_DI += inc; - } + int inc = size; + + if (ACCESS_FLAG(F_DF)) { + inc = -size; + } + if (M.x86.mode & (SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE)) { + /* dont care whether REPE or REPNE */ + /* in until CX is ZERO. */ + u32 count = ((M.x86.mode & SYSMODE_PREFIX_DATA) ? + M.x86.R_ECX : M.x86.R_CX); + + while (count--) { + single_in(size); + M.x86.R_DI += inc; + } + M.x86.R_CX = 0; + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + M.x86.R_ECX = 0; + } + M.x86.mode &= ~(SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE); + } else { + single_in(size); + M.x86.R_DI += inc; + } } /**************************************************************************** REMARKS: Implements the OUT string instruction and side effects. ****************************************************************************/ + +static void single_out(int size) +{ + if(size == 1) + (*sys_outb)(M.x86.R_DX,fetch_data_byte_abs(M.x86.R_ES, M.x86.R_SI)); + else if (size == 2) + (*sys_outw)(M.x86.R_DX,fetch_data_word_abs(M.x86.R_ES, M.x86.R_SI)); + else + (*sys_outl)(M.x86.R_DX,fetch_data_long_abs(M.x86.R_ES, M.x86.R_SI)); +} + void outs(int size) { - int inc = size; - - if (ACCESS_FLAG(F_DF)) { - inc = -size; - } - if (M.x86.mode & (SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE)) { - /* dont care whether REPE or REPNE */ - /* out until CX is ZERO. */ - u32 count = ((M.x86.mode & SYSMODE_PREFIX_DATA) ? - M.x86.R_ECX : M.x86.R_CX); - switch (size) { - case 1: - while (count--) { - (*sys_outb) (M.x86.R_DX, - fetch_data_byte_abs(M.x86.R_ES, M.x86.R_SI)); - M.x86.R_SI += inc; - } - break; - - case 2: - while (count--) { - (*sys_outw) (M.x86.R_DX, - fetch_data_word_abs(M.x86.R_ES, M.x86.R_SI)); - M.x86.R_SI += inc; - } - break; - case 4: - while (count--) { - (*sys_outl) (M.x86.R_DX, - fetch_data_long_abs(M.x86.R_ES, M.x86.R_SI)); - M.x86.R_SI += inc; - break; - } - } - M.x86.R_CX = 0; - if (M.x86.mode & SYSMODE_PREFIX_DATA) { - M.x86.R_ECX = 0; - } - M.x86.mode &= ~(SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE); - } else { - switch (size) { - case 1: - (*sys_outb) (M.x86.R_DX, - fetch_data_byte_abs(M.x86.R_ES, M.x86.R_SI)); - break; - case 2: - (*sys_outw) (M.x86.R_DX, - fetch_data_word_abs(M.x86.R_ES, M.x86.R_SI)); - break; - case 4: - (*sys_outl) (M.x86.R_DX, - fetch_data_long_abs(M.x86.R_ES, M.x86.R_SI)); - break; - } - M.x86.R_SI += inc; - } + int inc = size; + + if (ACCESS_FLAG(F_DF)) { + inc = -size; + } + if (M.x86.mode & (SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE)) { + /* dont care whether REPE or REPNE */ + /* out until CX is ZERO. */ + u32 count = ((M.x86.mode & SYSMODE_PREFIX_DATA) ? + M.x86.R_ECX : M.x86.R_CX); + while (count--) { + single_out(size); + M.x86.R_SI += inc; + } + M.x86.R_CX = 0; + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + M.x86.R_ECX = 0; + } + M.x86.mode &= ~(SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE); + } else { + single_out(size); + M.x86.R_SI += inc; + } } /**************************************************************************** PARAMETERS: -addr - Address to fetch word from +addr - Address to fetch word from REMARKS: Fetches a word from emulator memory using an absolute address. ****************************************************************************/ u16 mem_access_word(int addr) { - DB(if (CHECK_MEM_ACCESS()) - x86emu_check_mem_access(addr);) - return (*sys_rdw) (addr); +DB( if (CHECK_MEM_ACCESS()) + x86emu_check_mem_access(addr);) + return (*sys_rdw)(addr); } /**************************************************************************** @@ -2595,10 +2385,10 @@ NOTE: Do not inline this, as (*sys_wrX) is already inline! ****************************************************************************/ void push_word(u16 w) { - DB(if (CHECK_SP_ACCESS()) - x86emu_check_sp_access();) - M.x86.R_SP -= 2; - (*sys_wrw) (((u32) M.x86.R_SS << 4) + M.x86.R_SP, w); +DB( if (CHECK_SP_ACCESS()) + x86emu_check_sp_access();) + M.x86.R_SP -= 2; + (*sys_wrw)(((u32)M.x86.R_SS << 4) + M.x86.R_SP, w); } /**************************************************************************** @@ -2609,10 +2399,10 @@ NOTE: Do not inline this, as (*sys_wrX) is already inline! ****************************************************************************/ void push_long(u32 w) { - DB(if (CHECK_SP_ACCESS()) - x86emu_check_sp_access();) - M.x86.R_SP -= 4; - (*sys_wrl) (((u32) M.x86.R_SS << 4) + M.x86.R_SP, w); +DB( if (CHECK_SP_ACCESS()) + x86emu_check_sp_access();) + M.x86.R_SP -= 4; + (*sys_wrl)(((u32)M.x86.R_SS << 4) + M.x86.R_SP, w); } /**************************************************************************** @@ -2623,13 +2413,13 @@ NOTE: Do not inline this, as (*sys_rdX) is already inline! ****************************************************************************/ u16 pop_word(void) { - register u16 res; + u16 res; - DB(if (CHECK_SP_ACCESS()) - x86emu_check_sp_access();) - res = (*sys_rdw) (((u32) M.x86.R_SS << 4) + M.x86.R_SP); - M.x86.R_SP += 2; - return res; +DB( if (CHECK_SP_ACCESS()) + x86emu_check_sp_access();) + res = (*sys_rdw)(((u32)M.x86.R_SS << 4) + M.x86.R_SP); + M.x86.R_SP += 2; + return res; } /**************************************************************************** @@ -2640,432 +2430,12 @@ NOTE: Do not inline this, as (*sys_rdX) is already inline! ****************************************************************************/ u32 pop_long(void) { - register u32 res; - - DB(if (CHECK_SP_ACCESS()) - x86emu_check_sp_access();) - res = (*sys_rdl) (((u32) M.x86.R_SS << 4) + M.x86.R_SP); - M.x86.R_SP += 4; - return res; -} - -#ifdef __HAVE_INLINE_ASSEMBLER__ - -u16 aaa_word(u16 d) -{ - return aaa_word_asm(&M.x86.R_EFLG, d); -} - -u16 aas_word(u16 d) -{ - return aas_word_asm(&M.x86.R_EFLG, d); -} - -u16 aad_word(u16 d) -{ - return aad_word_asm(&M.x86.R_EFLG, d); -} - -u16 aam_word(u8 d) -{ - return aam_word_asm(&M.x86.R_EFLG, d); -} - -u8 adc_byte(u8 d, u8 s) -{ - return adc_byte_asm(&M.x86.R_EFLG, d, s); -} - -u16 adc_word(u16 d, u16 s) -{ - return adc_word_asm(&M.x86.R_EFLG, d, s); -} - -u32 adc_long(u32 d, u32 s) -{ - return adc_long_asm(&M.x86.R_EFLG, d, s); -} - -u8 add_byte(u8 d, u8 s) -{ - return add_byte_asm(&M.x86.R_EFLG, d, s); -} - -u16 add_word(u16 d, u16 s) -{ - return add_word_asm(&M.x86.R_EFLG, d, s); -} - -u32 add_long(u32 d, u32 s) -{ - return add_long_asm(&M.x86.R_EFLG, d, s); -} - -u8 and_byte(u8 d, u8 s) -{ - return and_byte_asm(&M.x86.R_EFLG, d, s); -} - -u16 and_word(u16 d, u16 s) -{ - return and_word_asm(&M.x86.R_EFLG, d, s); -} - -u32 and_long(u32 d, u32 s) -{ - return and_long_asm(&M.x86.R_EFLG, d, s); -} - -u8 cmp_byte(u8 d, u8 s) -{ - return cmp_byte_asm(&M.x86.R_EFLG, d, s); -} - -u16 cmp_word(u16 d, u16 s) -{ - return cmp_word_asm(&M.x86.R_EFLG, d, s); -} - -u32 cmp_long(u32 d, u32 s) -{ - return cmp_long_asm(&M.x86.R_EFLG, d, s); -} - -u8 daa_byte(u8 d) -{ - return daa_byte_asm(&M.x86.R_EFLG, d); -} - -u8 das_byte(u8 d) -{ - return das_byte_asm(&M.x86.R_EFLG, d); -} - -u8 dec_byte(u8 d) -{ - return dec_byte_asm(&M.x86.R_EFLG, d); -} - -u16 dec_word(u16 d) -{ - return dec_word_asm(&M.x86.R_EFLG, d); -} - -u32 dec_long(u32 d) -{ - return dec_long_asm(&M.x86.R_EFLG, d); -} - -u8 inc_byte(u8 d) -{ - return inc_byte_asm(&M.x86.R_EFLG, d); -} - -u16 inc_word(u16 d) -{ - return inc_word_asm(&M.x86.R_EFLG, d); -} - -u32 inc_long(u32 d) -{ - return inc_long_asm(&M.x86.R_EFLG, d); -} - -u8 or_byte(u8 d, u8 s) -{ - return or_byte_asm(&M.x86.R_EFLG, d, s); -} - -u16 or_word(u16 d, u16 s) -{ - return or_word_asm(&M.x86.R_EFLG, d, s); -} - -u32 or_long(u32 d, u32 s) -{ - return or_long_asm(&M.x86.R_EFLG, d, s); -} - -u8 neg_byte(u8 s) -{ - return neg_byte_asm(&M.x86.R_EFLG, s); -} - -u16 neg_word(u16 s) -{ - return neg_word_asm(&M.x86.R_EFLG, s); -} - -u32 neg_long(u32 s) -{ - return neg_long_asm(&M.x86.R_EFLG, s); -} - -u8 not_byte(u8 s) -{ - return not_byte_asm(&M.x86.R_EFLG, s); -} - -u16 not_word(u16 s) -{ - return not_word_asm(&M.x86.R_EFLG, s); -} - -u32 not_long(u32 s) -{ - return not_long_asm(&M.x86.R_EFLG, s); -} - -u8 rcl_byte(u8 d, u8 s) -{ - return rcl_byte_asm(&M.x86.R_EFLG, d, s); -} - -u16 rcl_word(u16 d, u8 s) -{ - return rcl_word_asm(&M.x86.R_EFLG, d, s); -} - -u32 rcl_long(u32 d, u8 s) -{ - return rcl_long_asm(&M.x86.R_EFLG, d, s); -} - -u8 rcr_byte(u8 d, u8 s) -{ - return rcr_byte_asm(&M.x86.R_EFLG, d, s); -} - -u16 rcr_word(u16 d, u8 s) -{ - return rcr_word_asm(&M.x86.R_EFLG, d, s); -} - -u32 rcr_long(u32 d, u8 s) -{ - return rcr_long_asm(&M.x86.R_EFLG, d, s); -} - -u8 rol_byte(u8 d, u8 s) -{ - return rol_byte_asm(&M.x86.R_EFLG, d, s); -} - -u16 rol_word(u16 d, u8 s) -{ - return rol_word_asm(&M.x86.R_EFLG, d, s); -} - -u32 rol_long(u32 d, u8 s) -{ - return rol_long_asm(&M.x86.R_EFLG, d, s); -} - -u8 ror_byte(u8 d, u8 s) -{ - return ror_byte_asm(&M.x86.R_EFLG, d, s); -} - -u16 ror_word(u16 d, u8 s) -{ - return ror_word_asm(&M.x86.R_EFLG, d, s); -} - -u32 ror_long(u32 d, u8 s) -{ - return ror_long_asm(&M.x86.R_EFLG, d, s); -} + u32 res; -u8 shl_byte(u8 d, u8 s) -{ - return shl_byte_asm(&M.x86.R_EFLG, d, s); +DB( if (CHECK_SP_ACCESS()) + x86emu_check_sp_access();) + res = (*sys_rdl)(((u32)M.x86.R_SS << 4) + M.x86.R_SP); + M.x86.R_SP += 4; + return res; } -u16 shl_word(u16 d, u8 s) -{ - return shl_word_asm(&M.x86.R_EFLG, d, s); -} - -u32 shl_long(u32 d, u8 s) -{ - return shl_long_asm(&M.x86.R_EFLG, d, s); -} - -u8 shr_byte(u8 d, u8 s) -{ - return shr_byte_asm(&M.x86.R_EFLG, d, s); -} - -u16 shr_word(u16 d, u8 s) -{ - return shr_word_asm(&M.x86.R_EFLG, d, s); -} - -u32 shr_long(u32 d, u8 s) -{ - return shr_long_asm(&M.x86.R_EFLG, d, s); -} - -u8 sar_byte(u8 d, u8 s) -{ - return sar_byte_asm(&M.x86.R_EFLG, d, s); -} - -u16 sar_word(u16 d, u8 s) -{ - return sar_word_asm(&M.x86.R_EFLG, d, s); -} - -u32 sar_long(u32 d, u8 s) -{ - return sar_long_asm(&M.x86.R_EFLG, d, s); -} - -u16 shld_word(u16 d, u16 fill, u8 s) -{ - return shld_word_asm(&M.x86.R_EFLG, d, fill, s); -} - -u32 shld_long(u32 d, u32 fill, u8 s) -{ - return shld_long_asm(&M.x86.R_EFLG, d, fill, s); -} - -u16 shrd_word(u16 d, u16 fill, u8 s) -{ - return shrd_word_asm(&M.x86.R_EFLG, d, fill, s); -} - -u32 shrd_long(u32 d, u32 fill, u8 s) -{ - return shrd_long_asm(&M.x86.R_EFLG, d, fill, s); -} - -u8 sbb_byte(u8 d, u8 s) -{ - return sbb_byte_asm(&M.x86.R_EFLG, d, s); -} - -u16 sbb_word(u16 d, u16 s) -{ - return sbb_word_asm(&M.x86.R_EFLG, d, s); -} - -u32 sbb_long(u32 d, u32 s) -{ - return sbb_long_asm(&M.x86.R_EFLG, d, s); -} - -u8 sub_byte(u8 d, u8 s) -{ - return sub_byte_asm(&M.x86.R_EFLG, d, s); -} - -u16 sub_word(u16 d, u16 s) -{ - return sub_word_asm(&M.x86.R_EFLG, d, s); -} - -u32 sub_long(u32 d, u32 s) -{ - return sub_long_asm(&M.x86.R_EFLG, d, s); -} - -void test_byte(u8 d, u8 s) -{ - test_byte_asm(&M.x86.R_EFLG, d, s); -} - -void test_word(u16 d, u16 s) -{ - test_word_asm(&M.x86.R_EFLG, d, s); -} - -void test_long(u32 d, u32 s) -{ - test_long_asm(&M.x86.R_EFLG, d, s); -} - -u8 xor_byte(u8 d, u8 s) -{ - return xor_byte_asm(&M.x86.R_EFLG, d, s); -} - -u16 xor_word(u16 d, u16 s) -{ - return xor_word_asm(&M.x86.R_EFLG, d, s); -} - -u32 xor_long(u32 d, u32 s) -{ - return xor_long_asm(&M.x86.R_EFLG, d, s); -} - -void imul_byte(u8 s) -{ - imul_byte_asm(&M.x86.R_EFLG, &M.x86.R_AX, M.x86.R_AL, s); -} - -void imul_word(u16 s) -{ - imul_word_asm(&M.x86.R_EFLG, &M.x86.R_AX, &M.x86.R_DX, M.x86.R_AX, s); -} - -void imul_long(u32 s) -{ - imul_long_asm(&M.x86.R_EFLG, &M.x86.R_EAX, &M.x86.R_EDX, M.x86.R_EAX, s); -} - -void imul_long_direct(u32 * res_lo, u32 * res_hi, u32 d, u32 s) -{ - imul_long_asm(&M.x86.R_EFLG, res_lo, res_hi, d, s); -} - -void mul_byte(u8 s) -{ - mul_byte_asm(&M.x86.R_EFLG, &M.x86.R_AX, M.x86.R_AL, s); -} - -void mul_word(u16 s) -{ - mul_word_asm(&M.x86.R_EFLG, &M.x86.R_AX, &M.x86.R_DX, M.x86.R_AX, s); -} - -void mul_long(u32 s) -{ - mul_long_asm(&M.x86.R_EFLG, &M.x86.R_EAX, &M.x86.R_EDX, M.x86.R_EAX, s); -} - -void idiv_byte(u8 s) -{ - idiv_byte_asm(&M.x86.R_EFLG, &M.x86.R_AL, &M.x86.R_AH, M.x86.R_AX, s); -} - -void idiv_word(u16 s) -{ - idiv_word_asm(&M.x86.R_EFLG, &M.x86.R_AX, &M.x86.R_DX, M.x86.R_AX, M.x86.R_DX, s); -} - -void idiv_long(u32 s) -{ - idiv_long_asm(&M.x86.R_EFLG, &M.x86.R_EAX, &M.x86.R_EDX, M.x86.R_EAX, M.x86.R_EDX, - s); -} - -void div_byte(u8 s) -{ - div_byte_asm(&M.x86.R_EFLG, &M.x86.R_AL, &M.x86.R_AH, M.x86.R_AX, s); -} - -void div_word(u16 s) -{ - div_word_asm(&M.x86.R_EFLG, &M.x86.R_AX, &M.x86.R_DX, M.x86.R_AX, M.x86.R_DX, s); -} - -void div_long(u32 s) -{ - div_long_asm(&M.x86.R_EFLG, &M.x86.R_EAX, &M.x86.R_EDX, M.x86.R_EAX, M.x86.R_EDX, - s); -} - -#endif |