1 /****************************************************************************
3 * Realmode X86 Emulator Library
5 * Copyright (C) 1991-2004 SciTech Software, Inc.
6 * Copyright (C) David Mosberger-Tang
7 * Copyright (C) 1999 Egbert Eich
9 * ========================================================================
11 * Permission to use, copy, modify, distribute, and sell this software and
12 * its documentation for any purpose is hereby granted without fee,
13 * provided that the above copyright notice appear in all copies and that
14 * both that copyright notice and this permission notice appear in
15 * supporting documentation, and that the name of the authors not be used
16 * in advertising or publicity pertaining to distribution of the software
17 * without specific, written prior permission. The authors makes no
18 * representations about the suitability of this software for any purpose.
19 * It is provided "as is" without express or implied warranty.
21 * THE AUTHORS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
22 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
23 * EVENT SHALL THE AUTHORS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
24 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
25 * USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
26 * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
27 * PERFORMANCE OF THIS SOFTWARE.
29 * ========================================================================
33 * Developer: Kendall Bennett
35 * Description: This file contains the code to implement the primitive
36 * machine operations used by the emulation code in ops.c
38 * Carry Chain Calculation
40 * This represents a somewhat expensive calculation which is
41 * apparently required to emulate the setting of the OF343364 and AF flag.
42 * The latter is not so important, but the former is. The overflow
43 * flag is the XOR of the top two bits of the carry chain for an
44 * addition (similar for subtraction). Since we do not want to
45 * simulate the addition in a bitwise manner, we try to calculate the
46 * carry chain given the two operands and the result.
48 * So, given the following table, which represents the addition of two
49 * bits, we can derive a formula for the carry chain.
61 * Construction of table for cout:
69 * By inspection, one gets: cc = ab + r'(a + b)
71 * That represents alot of operations, but NO CHOICE....
73 * Borrow Chain Calculation.
75 * The following table represents the subtraction of two bits, from
76 * which we can derive a formula for the borrow chain.
88 * Construction of table for cout:
96 * By inspection, one gets: bc = a'b + r(a' + b)
98 ****************************************************************************/
102 #define PRIM_OPS_NO_REDEFINE_ASM
104 #if defined(CONFIG_BIOSEMU)
106 #include "x86emu/x86emui.h"
108 /*------------------------- Global Variables ------------------------------*/
110 static u32 x86emu_parity_tab[8] =
122 #define PARITY(x) (((x86emu_parity_tab[(x) / 32] >> ((x) % 32)) & 1) == 0)
123 #define XOR2(x) (((x) ^ ((x)>>1)) & 0x1)
124 /*----------------------------- Implementation ----------------------------*/
130 /*----------------------------- Implementation ----------------------------*/
133 /*--------- Side effects helper functions -------*/
135 /****************************************************************************
137 implements side efects for byte operations that don't overflow
138 ****************************************************************************/
140 static void set_parity_flag(u32 res)
142 CONDITIONAL_SET_FLAG(PARITY(res & 0xFF), F_PF);
145 static void set_szp_flags_8(u8 res)
147 CONDITIONAL_SET_FLAG(res & 0x80, F_SF);
148 CONDITIONAL_SET_FLAG(res == 0, F_ZF);
149 set_parity_flag(res);
152 static void set_szp_flags_16(u16 res)
154 CONDITIONAL_SET_FLAG(res & 0x8000, F_SF);
155 CONDITIONAL_SET_FLAG(res == 0, F_ZF);
156 set_parity_flag(res);
159 static void set_szp_flags_32(u32 res)
161 CONDITIONAL_SET_FLAG(res & 0x80000000, F_SF);
162 CONDITIONAL_SET_FLAG(res == 0, F_ZF);
163 set_parity_flag(res);
166 static void no_carry_byte_side_eff(u8 res)
171 set_szp_flags_8(res);
174 static void no_carry_word_side_eff(u16 res)
179 set_szp_flags_16(res);
182 static void no_carry_long_side_eff(u32 res)
187 set_szp_flags_32(res);
190 static void calc_carry_chain(int bits, u32 d, u32 s, u32 res, int set_carry)
194 cc = (s & d) | ((~res) & (s | d));
195 CONDITIONAL_SET_FLAG(XOR2(cc >> (bits - 2)), F_OF);
196 CONDITIONAL_SET_FLAG(cc & 0x8, F_AF);
198 CONDITIONAL_SET_FLAG(res & (1 << bits), F_CF);
202 static void calc_borrow_chain(int bits, u32 d, u32 s, u32 res, int set_carry)
206 bc = (res & (~d | s)) | (~d & s);
207 CONDITIONAL_SET_FLAG(XOR2(bc >> (bits - 2)), F_OF);
208 CONDITIONAL_SET_FLAG(bc & 0x8, F_AF);
210 CONDITIONAL_SET_FLAG(bc & (1 << (bits - 1)), F_CF);
214 /****************************************************************************
216 Implements the AAA instruction and side effects.
217 ****************************************************************************/
221 if ((d & 0xf) > 0x9 || ACCESS_FLAG(F_AF)) {
230 res = (u16)(d & 0xFF0F);
231 set_szp_flags_16(res);
235 /****************************************************************************
237 Implements the AAA instruction and side effects.
238 ****************************************************************************/
242 if ((d & 0xf) > 0x9 || ACCESS_FLAG(F_AF)) {
251 res = (u16)(d & 0xFF0F);
252 set_szp_flags_16(res);
256 /****************************************************************************
258 Implements the AAD instruction and side effects.
259 ****************************************************************************/
265 hb = (u8)((d >> 8) & 0xff);
266 lb = (u8)((d & 0xff));
267 l = (u16)((lb + 10 * hb) & 0xFF);
269 no_carry_byte_side_eff(l & 0xFF);
273 /****************************************************************************
275 Implements the AAM instruction and side effects.
276 ****************************************************************************/
285 no_carry_byte_side_eff(l & 0xFF);
289 /****************************************************************************
291 Implements the ADC instruction and side effects.
292 ****************************************************************************/
293 u8 adc_byte(u8 d, u8 s)
295 u32 res; /* all operands in native machine order */
298 if (ACCESS_FLAG(F_CF)) res++;
300 set_szp_flags_8(res);
301 calc_carry_chain(8,s,d,res,1);
306 /****************************************************************************
308 Implements the ADC instruction and side effects.
309 ****************************************************************************/
310 u16 adc_word(u16 d, u16 s)
312 u32 res; /* all operands in native machine order */
315 if (ACCESS_FLAG(F_CF))
318 set_szp_flags_16((u16)res);
319 calc_carry_chain(16,s,d,res,1);
324 /****************************************************************************
326 Implements the ADC instruction and side effects.
327 ****************************************************************************/
328 u32 adc_long(u32 d, u32 s)
330 u32 lo; /* all operands in native machine order */
334 lo = (d & 0xFFFF) + (s & 0xFFFF);
337 if (ACCESS_FLAG(F_CF)) {
342 hi = (lo >> 16) + (d >> 16) + (s >> 16);
344 set_szp_flags_32(res);
345 calc_carry_chain(32,s,d,res,0);
347 CONDITIONAL_SET_FLAG(hi & 0x10000, F_CF);
352 /****************************************************************************
354 Implements the ADD instruction and side effects.
355 ****************************************************************************/
356 u8 add_byte(u8 d, u8 s)
358 u32 res; /* all operands in native machine order */
361 set_szp_flags_8((u8)res);
362 calc_carry_chain(8,s,d,res,1);
367 /****************************************************************************
369 Implements the ADD instruction and side effects.
370 ****************************************************************************/
371 u16 add_word(u16 d, u16 s)
373 u32 res; /* all operands in native machine order */
376 set_szp_flags_16((u16)res);
377 calc_carry_chain(16,s,d,res,1);
382 /****************************************************************************
384 Implements the ADD instruction and side effects.
385 ****************************************************************************/
386 u32 add_long(u32 d, u32 s)
391 set_szp_flags_32(res);
392 calc_carry_chain(32,s,d,res,0);
394 CONDITIONAL_SET_FLAG(res < d || res < s, F_CF);
399 /****************************************************************************
401 Implements the AND instruction and side effects.
402 ****************************************************************************/
403 u8 and_byte(u8 d, u8 s)
405 u8 res; /* all operands in native machine order */
409 no_carry_byte_side_eff(res);
413 /****************************************************************************
415 Implements the AND instruction and side effects.
416 ****************************************************************************/
417 u16 and_word(u16 d, u16 s)
419 u16 res; /* all operands in native machine order */
423 no_carry_word_side_eff(res);
427 /****************************************************************************
429 Implements the AND instruction and side effects.
430 ****************************************************************************/
431 u32 and_long(u32 d, u32 s)
433 u32 res; /* all operands in native machine order */
436 no_carry_long_side_eff(res);
440 /****************************************************************************
442 Implements the CMP instruction and side effects.
443 ****************************************************************************/
444 u8 cmp_byte(u8 d, u8 s)
446 u32 res; /* all operands in native machine order */
449 set_szp_flags_8((u8)res);
450 calc_borrow_chain(8, d, s, res, 1);
455 /****************************************************************************
457 Implements the CMP instruction and side effects.
458 ****************************************************************************/
459 u16 cmp_word(u16 d, u16 s)
461 u32 res; /* all operands in native machine order */
464 set_szp_flags_16((u16)res);
465 calc_borrow_chain(16, d, s, res, 1);
470 /****************************************************************************
472 Implements the CMP instruction and side effects.
473 ****************************************************************************/
474 u32 cmp_long(u32 d, u32 s)
476 u32 res; /* all operands in native machine order */
479 set_szp_flags_32(res);
480 calc_borrow_chain(32, d, s, res, 1);
485 /****************************************************************************
487 Implements the DAA instruction and side effects.
488 ****************************************************************************/
492 if ((d & 0xf) > 9 || ACCESS_FLAG(F_AF)) {
496 if (res > 0x9F || ACCESS_FLAG(F_CF)) {
500 set_szp_flags_8((u8)res);
504 /****************************************************************************
506 Implements the DAS instruction and side effects.
507 ****************************************************************************/
510 if ((d & 0xf) > 9 || ACCESS_FLAG(F_AF)) {
514 if (d > 0x9F || ACCESS_FLAG(F_CF)) {
522 /****************************************************************************
524 Implements the DEC instruction and side effects.
525 ****************************************************************************/
528 u32 res; /* all operands in native machine order */
531 set_szp_flags_8((u8)res);
532 calc_borrow_chain(8, d, 1, res, 0);
537 /****************************************************************************
539 Implements the DEC instruction and side effects.
540 ****************************************************************************/
543 u32 res; /* all operands in native machine order */
546 set_szp_flags_16((u16)res);
547 calc_borrow_chain(16, d, 1, res, 0);
552 /****************************************************************************
554 Implements the DEC instruction and side effects.
555 ****************************************************************************/
558 u32 res; /* all operands in native machine order */
562 set_szp_flags_32(res);
563 calc_borrow_chain(32, d, 1, res, 0);
568 /****************************************************************************
570 Implements the INC instruction and side effects.
571 ****************************************************************************/
574 u32 res; /* all operands in native machine order */
577 set_szp_flags_8((u8)res);
578 calc_carry_chain(8, d, 1, res, 0);
583 /****************************************************************************
585 Implements the INC instruction and side effects.
586 ****************************************************************************/
589 u32 res; /* all operands in native machine order */
592 set_szp_flags_16((u16)res);
593 calc_carry_chain(16, d, 1, res, 0);
598 /****************************************************************************
600 Implements the INC instruction and side effects.
601 ****************************************************************************/
604 u32 res; /* all operands in native machine order */
607 set_szp_flags_32(res);
608 calc_carry_chain(32, d, 1, res, 0);
613 /****************************************************************************
615 Implements the OR instruction and side effects.
616 ****************************************************************************/
617 u8 or_byte(u8 d, u8 s)
619 u8 res; /* all operands in native machine order */
622 no_carry_byte_side_eff(res);
627 /****************************************************************************
629 Implements the OR instruction and side effects.
630 ****************************************************************************/
631 u16 or_word(u16 d, u16 s)
633 u16 res; /* all operands in native machine order */
636 no_carry_word_side_eff(res);
640 /****************************************************************************
642 Implements the OR instruction and side effects.
643 ****************************************************************************/
644 u32 or_long(u32 d, u32 s)
646 u32 res; /* all operands in native machine order */
649 no_carry_long_side_eff(res);
653 /****************************************************************************
655 Implements the OR instruction and side effects.
656 ****************************************************************************/
661 CONDITIONAL_SET_FLAG(s != 0, F_CF);
663 set_szp_flags_8(res);
664 calc_borrow_chain(8, 0, s, res, 0);
669 /****************************************************************************
671 Implements the OR instruction and side effects.
672 ****************************************************************************/
677 CONDITIONAL_SET_FLAG(s != 0, F_CF);
679 set_szp_flags_16((u16)res);
680 calc_borrow_chain(16, 0, s, res, 0);
685 /****************************************************************************
687 Implements the OR instruction and side effects.
688 ****************************************************************************/
693 CONDITIONAL_SET_FLAG(s != 0, F_CF);
695 set_szp_flags_32(res);
696 calc_borrow_chain(32, 0, s, res, 0);
701 /****************************************************************************
703 Implements the NOT instruction and side effects.
704 ****************************************************************************/
710 /****************************************************************************
712 Implements the NOT instruction and side effects.
713 ****************************************************************************/
719 /****************************************************************************
721 Implements the NOT instruction and side effects.
722 ****************************************************************************/
728 /****************************************************************************
730 Implements the RCL instruction and side effects.
731 ****************************************************************************/
732 u8 rcl_byte(u8 d, u8 s)
734 unsigned int res, cnt, mask, cf;
736 /* s is the rotate distance. It varies from 0 - 8. */
739 CF B_7 B_6 B_5 B_4 B_3 B_2 B_1 B_0
741 want to rotate through the carry by "s" bits. We could
742 loop, but that's inefficient. So the width is 9,
743 and we split into three parts:
745 The new carry flag (was B_n)
746 the stuff in B_n-1 .. B_0
747 the stuff in B_7 .. B_n+1
749 The new rotate is done mod 9, and given this,
750 for a rotation of n bits (mod 9) the new carry flag is
751 then located n bits from the MSB. The low part is
752 then shifted up cnt bits, and the high part is or'd
753 in. Using CAPS for new values, and lowercase for the
754 original values, this can be expressed as:
758 2) B_(7) .. B_(n) <- b_(8-(n+1)) .. b_0
760 4) B_(n-2) .. B_0 <- b_7 .. b_(8-(n-1))
763 if ((cnt = s % 9) != 0) {
764 /* extract the new CARRY FLAG. */
766 cf = (d >> (8 - cnt)) & 0x1;
768 /* get the low stuff which rotated
769 into the range B_7 .. B_cnt */
770 /* B_(7) .. B_(n) <- b_(8-(n+1)) .. b_0 */
771 /* note that the right hand side done by the mask */
772 res = (d << cnt) & 0xff;
774 /* now the high stuff which rotated around
775 into the positions B_cnt-2 .. B_0 */
776 /* B_(n-2) .. B_0 <- b_7 .. b_(8-(n-1)) */
777 /* shift it downward, 7-(n-2) = 9-n positions.
778 and mask off the result before or'ing in.
780 mask = (1 << (cnt - 1)) - 1;
781 res |= (d >> (9 - cnt)) & mask;
783 /* if the carry flag was set, or it in. */
784 if (ACCESS_FLAG(F_CF)) { /* carry flag is set */
786 res |= 1 << (cnt - 1);
788 /* set the new carry flag, based on the variable "cf" */
789 CONDITIONAL_SET_FLAG(cf, F_CF);
790 /* OVERFLOW is set *IFF* cnt==1, then it is the
791 xor of CF and the most significant bit. Blecck. */
792 /* parenthesized this expression since it appears to
793 be causing OF to be misset */
794 CONDITIONAL_SET_FLAG(cnt == 1 && XOR2(cf + ((res >> 6) & 0x2)),
801 /****************************************************************************
803 Implements the RCL instruction and side effects.
804 ****************************************************************************/
805 u16 rcl_word(u16 d, u8 s)
807 unsigned int res, cnt, mask, cf;
810 if ((cnt = s % 17) != 0) {
811 cf = (d >> (16 - cnt)) & 0x1;
812 res = (d << cnt) & 0xffff;
813 mask = (1 << (cnt - 1)) - 1;
814 res |= (d >> (17 - cnt)) & mask;
815 if (ACCESS_FLAG(F_CF)) {
816 res |= 1 << (cnt - 1);
818 CONDITIONAL_SET_FLAG(cf, F_CF);
819 CONDITIONAL_SET_FLAG(cnt == 1 && XOR2(cf + ((res >> 14) & 0x2)),
825 /****************************************************************************
827 Implements the RCL instruction and side effects.
828 ****************************************************************************/
829 u32 rcl_long(u32 d, u8 s)
831 u32 res, cnt, mask, cf;
834 if ((cnt = s % 33) != 0) {
835 cf = (d >> (32 - cnt)) & 0x1;
836 res = (d << cnt) & 0xffffffff;
837 mask = (1 << (cnt - 1)) - 1;
838 res |= (d >> (33 - cnt)) & mask;
839 if (ACCESS_FLAG(F_CF)) { /* carry flag is set */
840 res |= 1 << (cnt - 1);
842 CONDITIONAL_SET_FLAG(cf, F_CF);
843 CONDITIONAL_SET_FLAG(cnt == 1 && XOR2(cf + ((res >> 30) & 0x2)),
849 /****************************************************************************
851 Implements the RCR instruction and side effects.
852 ****************************************************************************/
853 u8 rcr_byte(u8 d, u8 s)
856 u32 mask, cf, ocf = 0;
858 /* rotate right through carry */
860 s is the rotate distance. It varies from 0 - 8.
861 d is the byte object rotated.
865 CF B_7 B_6 B_5 B_4 B_3 B_2 B_1 B_0
867 The new rotate is done mod 9, and given this,
868 for a rotation of n bits (mod 9) the new carry flag is
869 then located n bits from the LSB. The low part is
870 then shifted up cnt bits, and the high part is or'd
871 in. Using CAPS for new values, and lowercase for the
872 original values, this can be expressed as:
876 2) B_(8-(n+1)) .. B_(0) <- b_(7) .. b_(n)
878 4) B_(7) .. B_(8-(n-1)) <- b_(n-2) .. b_(0)
881 if ((cnt = s % 9) != 0) {
882 /* extract the new CARRY FLAG. */
886 /* note hackery here. Access_flag(..) evaluates to either
888 non-zero if flag is set.
889 doing access_flag(..) != 0 casts that into either
890 0..1 in any representation of the flags register
891 (i.e. packed bit array or unpacked.)
893 ocf = ACCESS_FLAG(F_CF) != 0;
895 cf = (d >> (cnt - 1)) & 0x1;
897 /* B_(8-(n+1)) .. B_(0) <- b_(7) .. b_n */
898 /* note that the right hand side done by the mask
899 This is effectively done by shifting the
900 object to the right. The result must be masked,
901 in case the object came in and was treated
902 as a negative number. Needed??? */
904 mask = (1 << (8 - cnt)) - 1;
905 res = (d >> cnt) & mask;
907 /* now the high stuff which rotated around
908 into the positions B_cnt-2 .. B_0 */
909 /* B_(7) .. B_(8-(n-1)) <- b_(n-2) .. b_(0) */
910 /* shift it downward, 7-(n-2) = 9-n positions.
911 and mask off the result before or'ing in.
913 res |= (d << (9 - cnt));
915 /* if the carry flag was set, or it in. */
916 if (ACCESS_FLAG(F_CF)) { /* carry flag is set */
918 res |= 1 << (8 - cnt);
920 /* set the new carry flag, based on the variable "cf" */
921 CONDITIONAL_SET_FLAG(cf, F_CF);
922 /* OVERFLOW is set *IFF* cnt==1, then it is the
923 xor of CF and the most significant bit. Blecck. */
924 /* parenthesized... */
926 CONDITIONAL_SET_FLAG(XOR2(ocf + ((d >> 6) & 0x2)),
933 /****************************************************************************
935 Implements the RCR instruction and side effects.
936 ****************************************************************************/
937 u16 rcr_word(u16 d, u8 s)
940 u32 mask, cf, ocf = 0;
942 /* rotate right through carry */
944 if ((cnt = s % 17) != 0) {
947 ocf = ACCESS_FLAG(F_CF) != 0;
949 cf = (d >> (cnt - 1)) & 0x1;
950 mask = (1 << (16 - cnt)) - 1;
951 res = (d >> cnt) & mask;
952 res |= (d << (17 - cnt));
953 if (ACCESS_FLAG(F_CF)) {
954 res |= 1 << (16 - cnt);
956 CONDITIONAL_SET_FLAG(cf, F_CF);
958 CONDITIONAL_SET_FLAG(XOR2(ocf + ((d >> 14) & 0x2)),
965 /****************************************************************************
967 Implements the RCR instruction and side effects.
968 ****************************************************************************/
969 u32 rcr_long(u32 d, u8 s)
972 u32 mask, cf, ocf = 0;
974 /* rotate right through carry */
976 if ((cnt = s % 33) != 0) {
979 ocf = ACCESS_FLAG(F_CF) != 0;
981 cf = (d >> (cnt - 1)) & 0x1;
982 mask = (1 << (32 - cnt)) - 1;
983 res = (d >> cnt) & mask;
985 res |= (d << (33 - cnt));
986 if (ACCESS_FLAG(F_CF)) { /* carry flag is set */
987 res |= 1 << (32 - cnt);
989 CONDITIONAL_SET_FLAG(cf, F_CF);
991 CONDITIONAL_SET_FLAG(XOR2(ocf + ((d >> 30) & 0x2)),
998 /****************************************************************************
1000 Implements the ROL instruction and side effects.
1001 ****************************************************************************/
1002 u8 rol_byte(u8 d, u8 s)
1004 unsigned int res, cnt, mask;
1008 s is the rotate distance. It varies from 0 - 8.
1009 d is the byte object rotated.
1015 The new rotate is done mod 8.
1016 Much simpler than the "rcl" or "rcr" operations.
1019 1) B_(7) .. B_(n) <- b_(8-(n+1)) .. b_(0)
1020 2) B_(n-1) .. B_(0) <- b_(7) .. b_(8-n)
1023 if ((cnt = s % 8) != 0) {
1024 /* B_(7) .. B_(n) <- b_(8-(n+1)) .. b_(0) */
1027 /* B_(n-1) .. B_(0) <- b_(7) .. b_(8-n) */
1028 mask = (1 << cnt) - 1;
1029 res |= (d >> (8 - cnt)) & mask;
1031 /* set the new carry flag, Note that it is the low order
1032 bit of the result!!! */
1033 CONDITIONAL_SET_FLAG(res & 0x1, F_CF);
1034 /* OVERFLOW is set *IFF* s==1, then it is the
1035 xor of CF and the most significant bit. Blecck. */
1036 CONDITIONAL_SET_FLAG(s == 1 &&
1037 XOR2((res & 0x1) + ((res >> 6) & 0x2)),
1040 /* set the new carry flag, Note that it is the low order
1041 bit of the result!!! */
1042 CONDITIONAL_SET_FLAG(res & 0x1, F_CF);
1047 /****************************************************************************
1049 Implements the ROL instruction and side effects.
1050 ****************************************************************************/
1051 u16 rol_word(u16 d, u8 s)
1053 unsigned int res, cnt, mask;
1056 if ((cnt = s % 16) != 0) {
1058 mask = (1 << cnt) - 1;
1059 res |= (d >> (16 - cnt)) & mask;
1060 CONDITIONAL_SET_FLAG(res & 0x1, F_CF);
1061 CONDITIONAL_SET_FLAG(s == 1 &&
1062 XOR2((res & 0x1) + ((res >> 14) & 0x2)),
1065 /* set the new carry flag, Note that it is the low order
1066 bit of the result!!! */
1067 CONDITIONAL_SET_FLAG(res & 0x1, F_CF);
1072 /****************************************************************************
1074 Implements the ROL instruction and side effects.
1075 ****************************************************************************/
1076 u32 rol_long(u32 d, u8 s)
1081 if ((cnt = s % 32) != 0) {
1083 mask = (1 << cnt) - 1;
1084 res |= (d >> (32 - cnt)) & mask;
1085 CONDITIONAL_SET_FLAG(res & 0x1, F_CF);
1086 CONDITIONAL_SET_FLAG(s == 1 &&
1087 XOR2((res & 0x1) + ((res >> 30) & 0x2)),
1090 /* set the new carry flag, Note that it is the low order
1091 bit of the result!!! */
1092 CONDITIONAL_SET_FLAG(res & 0x1, F_CF);
1097 /****************************************************************************
1099 Implements the ROR instruction and side effects.
1100 ****************************************************************************/
1101 u8 ror_byte(u8 d, u8 s)
1103 unsigned int res, cnt, mask;
1107 s is the rotate distance. It varies from 0 - 8.
1108 d is the byte object rotated.
1114 The rotate is done mod 8.
1117 1) B_(8-(n+1)) .. B_(0) <- b_(7) .. b_(n)
1118 2) B_(7) .. B_(8-n) <- b_(n-1) .. b_(0)
1121 if ((cnt = s % 8) != 0) { /* not a typo, do nada if cnt==0 */
1122 /* B_(7) .. B_(8-n) <- b_(n-1) .. b_(0) */
1123 res = (d << (8 - cnt));
1125 /* B_(8-(n+1)) .. B_(0) <- b_(7) .. b_(n) */
1126 mask = (1 << (8 - cnt)) - 1;
1127 res |= (d >> (cnt)) & mask;
1129 /* set the new carry flag, Note that it is the low order
1130 bit of the result!!! */
1131 CONDITIONAL_SET_FLAG(res & 0x80, F_CF);
1132 /* OVERFLOW is set *IFF* s==1, then it is the
1133 xor of the two most significant bits. Blecck. */
1134 CONDITIONAL_SET_FLAG(s == 1 && XOR2(res >> 6), F_OF);
1135 } else if (s != 0) {
1136 /* set the new carry flag, Note that it is the low order
1137 bit of the result!!! */
1138 CONDITIONAL_SET_FLAG(res & 0x80, F_CF);
1143 /****************************************************************************
1145 Implements the ROR instruction and side effects.
1146 ****************************************************************************/
1147 u16 ror_word(u16 d, u8 s)
1149 unsigned int res, cnt, mask;
1152 if ((cnt = s % 16) != 0) {
1153 res = (d << (16 - cnt));
1154 mask = (1 << (16 - cnt)) - 1;
1155 res |= (d >> (cnt)) & mask;
1156 CONDITIONAL_SET_FLAG(res & 0x8000, F_CF);
1157 CONDITIONAL_SET_FLAG(s == 1 && XOR2(res >> 14), F_OF);
1158 } else if (s != 0) {
1159 /* set the new carry flag, Note that it is the low order
1160 bit of the result!!! */
1161 CONDITIONAL_SET_FLAG(res & 0x8000, F_CF);
1166 /****************************************************************************
1168 Implements the ROR instruction and side effects.
1169 ****************************************************************************/
1170 u32 ror_long(u32 d, u8 s)
1175 if ((cnt = s % 32) != 0) {
1176 res = (d << (32 - cnt));
1177 mask = (1 << (32 - cnt)) - 1;
1178 res |= (d >> (cnt)) & mask;
1179 CONDITIONAL_SET_FLAG(res & 0x80000000, F_CF);
1180 CONDITIONAL_SET_FLAG(s == 1 && XOR2(res >> 30), F_OF);
1181 } else if (s != 0) {
1182 /* set the new carry flag, Note that it is the low order
1183 bit of the result!!! */
1184 CONDITIONAL_SET_FLAG(res & 0x80000000, F_CF);
1189 /****************************************************************************
1191 Implements the SHL instruction and side effects.
1192 ****************************************************************************/
1193 u8 shl_byte(u8 d, u8 s)
1195 unsigned int cnt, res, cf;
1200 /* last bit shifted out goes into carry flag */
1203 cf = d & (1 << (8 - cnt));
1204 CONDITIONAL_SET_FLAG(cf, F_CF);
1205 set_szp_flags_8((u8)res);
1211 /* Needs simplification. */
1212 CONDITIONAL_SET_FLAG(
1213 (((res & 0x80) == 0x80) ^
1214 (ACCESS_FLAG(F_CF) != 0)),
1215 /* was (M.x86.R_FLG&F_CF)==F_CF)), */
1222 CONDITIONAL_SET_FLAG((d << (s-1)) & 0x80, F_CF);
1231 /****************************************************************************
1233 Implements the SHL instruction and side effects.
1234 ****************************************************************************/
1235 u16 shl_word(u16 d, u8 s)
1237 unsigned int cnt, res, cf;
1243 cf = d & (1 << (16 - cnt));
1244 CONDITIONAL_SET_FLAG(cf, F_CF);
1245 set_szp_flags_16((u16)res);
1251 CONDITIONAL_SET_FLAG(
1252 (((res & 0x8000) == 0x8000) ^
1253 (ACCESS_FLAG(F_CF) != 0)),
1260 CONDITIONAL_SET_FLAG((d << (s-1)) & 0x8000, F_CF);
1269 /****************************************************************************
1271 Implements the SHL instruction and side effects.
1272 ****************************************************************************/
1273 u32 shl_long(u32 d, u8 s)
1275 unsigned int cnt, res, cf;
1281 cf = d & (1 << (32 - cnt));
1282 CONDITIONAL_SET_FLAG(cf, F_CF);
1283 set_szp_flags_32((u32)res);
1288 CONDITIONAL_SET_FLAG((((res & 0x80000000) == 0x80000000) ^
1289 (ACCESS_FLAG(F_CF) != 0)), F_OF);
1295 CONDITIONAL_SET_FLAG((d << (s-1)) & 0x80000000, F_CF);
1304 /****************************************************************************
1306 Implements the SHR instruction and side effects.
1307 ****************************************************************************/
1308 u8 shr_byte(u8 d, u8 s)
1310 unsigned int cnt, res, cf;
1315 cf = d & (1 << (cnt - 1));
1317 CONDITIONAL_SET_FLAG(cf, F_CF);
1318 set_szp_flags_8((u8)res);
1324 CONDITIONAL_SET_FLAG(XOR2(res >> 6), F_OF);
1330 CONDITIONAL_SET_FLAG((d >> (s-1)) & 0x1, F_CF);
1339 /****************************************************************************
1341 Implements the SHR instruction and side effects.
1342 ****************************************************************************/
1343 u16 shr_word(u16 d, u8 s)
1345 unsigned int cnt, res, cf;
1350 cf = d & (1 << (cnt - 1));
1352 CONDITIONAL_SET_FLAG(cf, F_CF);
1353 set_szp_flags_16((u16)res);
1359 CONDITIONAL_SET_FLAG(XOR2(res >> 14), F_OF);
1374 /****************************************************************************
1376 Implements the SHR instruction and side effects.
1377 ****************************************************************************/
1378 u32 shr_long(u32 d, u8 s)
1380 unsigned int cnt, res, cf;
1385 cf = d & (1 << (cnt - 1));
1387 CONDITIONAL_SET_FLAG(cf, F_CF);
1388 set_szp_flags_32((u32)res);
1393 CONDITIONAL_SET_FLAG(XOR2(res >> 30), F_OF);
1408 /****************************************************************************
1410 Implements the SAR instruction and side effects.
1411 ****************************************************************************/
1412 u8 sar_byte(u8 d, u8 s)
1414 unsigned int cnt, res, cf, mask, sf;
1419 if (cnt > 0 && cnt < 8) {
1420 mask = (1 << (8 - cnt)) - 1;
1421 cf = d & (1 << (cnt - 1));
1422 res = (d >> cnt) & mask;
1423 CONDITIONAL_SET_FLAG(cf, F_CF);
1427 set_szp_flags_8((u8)res);
1428 } else if (cnt >= 8) {
1446 /****************************************************************************
1448 Implements the SAR instruction and side effects.
1449 ****************************************************************************/
1450 u16 sar_word(u16 d, u8 s)
1452 unsigned int cnt, res, cf, mask, sf;
1457 if (cnt > 0 && cnt < 16) {
1458 mask = (1 << (16 - cnt)) - 1;
1459 cf = d & (1 << (cnt - 1));
1460 res = (d >> cnt) & mask;
1461 CONDITIONAL_SET_FLAG(cf, F_CF);
1465 set_szp_flags_16((u16)res);
1466 } else if (cnt >= 16) {
1484 /****************************************************************************
1486 Implements the SAR instruction and side effects.
1487 ****************************************************************************/
1488 u32 sar_long(u32 d, u8 s)
1490 u32 cnt, res, cf, mask, sf;
1492 sf = d & 0x80000000;
1495 if (cnt > 0 && cnt < 32) {
1496 mask = (1 << (32 - cnt)) - 1;
1497 cf = d & (1 << (cnt - 1));
1498 res = (d >> cnt) & mask;
1499 CONDITIONAL_SET_FLAG(cf, F_CF);
1503 set_szp_flags_32(res);
1504 } else if (cnt >= 32) {
1522 /****************************************************************************
1524 Implements the SHLD instruction and side effects.
1525 ****************************************************************************/
1526 u16 shld_word (u16 d, u16 fill, u8 s)
1528 unsigned int cnt, res, cf;
1533 res = (d << cnt) | (fill >> (16-cnt));
1534 cf = d & (1 << (16 - cnt));
1535 CONDITIONAL_SET_FLAG(cf, F_CF);
1536 set_szp_flags_16((u16)res);
1541 CONDITIONAL_SET_FLAG((((res & 0x8000) == 0x8000) ^
1542 (ACCESS_FLAG(F_CF) != 0)), F_OF);
1548 CONDITIONAL_SET_FLAG((d << (s-1)) & 0x8000, F_CF);
1557 /****************************************************************************
1559 Implements the SHLD instruction and side effects.
1560 ****************************************************************************/
1561 u32 shld_long (u32 d, u32 fill, u8 s)
1563 unsigned int cnt, res, cf;
1568 res = (d << cnt) | (fill >> (32-cnt));
1569 cf = d & (1 << (32 - cnt));
1570 CONDITIONAL_SET_FLAG(cf, F_CF);
1571 set_szp_flags_32((u32)res);
1576 CONDITIONAL_SET_FLAG((((res & 0x80000000) == 0x80000000) ^
1577 (ACCESS_FLAG(F_CF) != 0)), F_OF);
1583 CONDITIONAL_SET_FLAG((d << (s-1)) & 0x80000000, F_CF);
1592 /****************************************************************************
1594 Implements the SHRD instruction and side effects.
1595 ****************************************************************************/
1596 u16 shrd_word (u16 d, u16 fill, u8 s)
1598 unsigned int cnt, res, cf;
1603 cf = d & (1 << (cnt - 1));
1604 res = (d >> cnt) | (fill << (16 - cnt));
1605 CONDITIONAL_SET_FLAG(cf, F_CF);
1606 set_szp_flags_16((u16)res);
1612 CONDITIONAL_SET_FLAG(XOR2(res >> 14), F_OF);
1627 /****************************************************************************
1629 Implements the SHRD instruction and side effects.
1630 ****************************************************************************/
1631 u32 shrd_long (u32 d, u32 fill, u8 s)
1633 unsigned int cnt, res, cf;
1638 cf = d & (1 << (cnt - 1));
1639 res = (d >> cnt) | (fill << (32 - cnt));
1640 CONDITIONAL_SET_FLAG(cf, F_CF);
1641 set_szp_flags_32((u32)res);
1646 CONDITIONAL_SET_FLAG(XOR2(res >> 30), F_OF);
1661 /****************************************************************************
1663 Implements the SBB instruction and side effects.
1664 ****************************************************************************/
1665 u8 sbb_byte(u8 d, u8 s)
1667 u32 res; /* all operands in native machine order */
1670 if (ACCESS_FLAG(F_CF))
1674 set_szp_flags_8((u8)res);
1676 /* calculate the borrow chain. See note at top */
1677 bc = (res & (~d | s)) | (~d & s);
1678 CONDITIONAL_SET_FLAG(bc & 0x80, F_CF);
1679 CONDITIONAL_SET_FLAG(XOR2(bc >> 6), F_OF);
1680 CONDITIONAL_SET_FLAG(bc & 0x8, F_AF);
1684 /****************************************************************************
1686 Implements the SBB instruction and side effects.
1687 ****************************************************************************/
1688 u16 sbb_word(u16 d, u16 s)
1690 u32 res; /* all operands in native machine order */
1693 if (ACCESS_FLAG(F_CF))
1697 set_szp_flags_16((u16)res);
1699 /* calculate the borrow chain. See note at top */
1700 bc = (res & (~d | s)) | (~d & s);
1701 CONDITIONAL_SET_FLAG(bc & 0x8000, F_CF);
1702 CONDITIONAL_SET_FLAG(XOR2(bc >> 14), F_OF);
1703 CONDITIONAL_SET_FLAG(bc & 0x8, F_AF);
1707 /****************************************************************************
1709 Implements the SBB instruction and side effects.
1710 ****************************************************************************/
1711 u32 sbb_long(u32 d, u32 s)
1713 u32 res; /* all operands in native machine order */
1716 if (ACCESS_FLAG(F_CF))
1721 set_szp_flags_32(res);
1723 /* calculate the borrow chain. See note at top */
1724 bc = (res & (~d | s)) | (~d & s);
1725 CONDITIONAL_SET_FLAG(bc & 0x80000000, F_CF);
1726 CONDITIONAL_SET_FLAG(XOR2(bc >> 30), F_OF);
1727 CONDITIONAL_SET_FLAG(bc & 0x8, F_AF);
1731 /****************************************************************************
1733 Implements the SUB instruction and side effects.
1734 ****************************************************************************/
1735 u8 sub_byte(u8 d, u8 s)
1737 u32 res; /* all operands in native machine order */
1741 set_szp_flags_8((u8)res);
1743 /* calculate the borrow chain. See note at top */
1744 bc = (res & (~d | s)) | (~d & s);
1745 CONDITIONAL_SET_FLAG(bc & 0x80, F_CF);
1746 CONDITIONAL_SET_FLAG(XOR2(bc >> 6), F_OF);
1747 CONDITIONAL_SET_FLAG(bc & 0x8, F_AF);
1751 /****************************************************************************
1753 Implements the SUB instruction and side effects.
1754 ****************************************************************************/
1755 u16 sub_word(u16 d, u16 s)
1757 u32 res; /* all operands in native machine order */
1761 set_szp_flags_16((u16)res);
1763 /* calculate the borrow chain. See note at top */
1764 bc = (res & (~d | s)) | (~d & s);
1765 CONDITIONAL_SET_FLAG(bc & 0x8000, F_CF);
1766 CONDITIONAL_SET_FLAG(XOR2(bc >> 14), F_OF);
1767 CONDITIONAL_SET_FLAG(bc & 0x8, F_AF);
1771 /****************************************************************************
1773 Implements the SUB instruction and side effects.
1774 ****************************************************************************/
1775 u32 sub_long(u32 d, u32 s)
1777 u32 res; /* all operands in native machine order */
1781 set_szp_flags_32(res);
1783 /* calculate the borrow chain. See note at top */
1784 bc = (res & (~d | s)) | (~d & s);
1785 CONDITIONAL_SET_FLAG(bc & 0x80000000, F_CF);
1786 CONDITIONAL_SET_FLAG(XOR2(bc >> 30), F_OF);
1787 CONDITIONAL_SET_FLAG(bc & 0x8, F_AF);
1791 /****************************************************************************
1793 Implements the TEST instruction and side effects.
1794 ****************************************************************************/
1795 void test_byte(u8 d, u8 s)
1797 u32 res; /* all operands in native machine order */
1802 set_szp_flags_8((u8)res);
1803 /* AF == dont care */
1807 /****************************************************************************
1809 Implements the TEST instruction and side effects.
1810 ****************************************************************************/
1811 void test_word(u16 d, u16 s)
1813 u32 res; /* all operands in native machine order */
1818 set_szp_flags_16((u16)res);
1819 /* AF == dont care */
1823 /****************************************************************************
1825 Implements the TEST instruction and side effects.
1826 ****************************************************************************/
1827 void test_long(u32 d, u32 s)
1829 u32 res; /* all operands in native machine order */
1834 set_szp_flags_32(res);
1835 /* AF == dont care */
1839 /****************************************************************************
1841 Implements the XOR instruction and side effects.
1842 ****************************************************************************/
1843 u8 xor_byte(u8 d, u8 s)
1845 u8 res; /* all operands in native machine order */
1848 no_carry_byte_side_eff(res);
1852 /****************************************************************************
1854 Implements the XOR instruction and side effects.
1855 ****************************************************************************/
1856 u16 xor_word(u16 d, u16 s)
1858 u16 res; /* all operands in native machine order */
1861 no_carry_word_side_eff(res);
1865 /****************************************************************************
1867 Implements the XOR instruction and side effects.
1868 ****************************************************************************/
1869 u32 xor_long(u32 d, u32 s)
1871 u32 res; /* all operands in native machine order */
1874 no_carry_long_side_eff(res);
1878 /****************************************************************************
1880 Implements the IMUL instruction and side effects.
1881 ****************************************************************************/
1882 void imul_byte(u8 s)
1884 s16 res = (s16)((s8)M.x86.R_AL * (s8)s);
1887 if (((M.x86.R_AL & 0x80) == 0 && M.x86.R_AH == 0x00) ||
1888 ((M.x86.R_AL & 0x80) != 0 && M.x86.R_AH == 0xFF)) {
1897 /****************************************************************************
1899 Implements the IMUL instruction and side effects.
1900 ****************************************************************************/
1901 void imul_word(u16 s)
1903 s32 res = (s16)M.x86.R_AX * (s16)s;
1905 M.x86.R_AX = (u16)res;
1906 M.x86.R_DX = (u16)(res >> 16);
1907 if (((M.x86.R_AX & 0x8000) == 0 && M.x86.R_DX == 0x0000) ||
1908 ((M.x86.R_AX & 0x8000) != 0 && M.x86.R_DX == 0xFFFF)) {
1917 /****************************************************************************
1919 Implements the IMUL instruction and side effects.
1920 ****************************************************************************/
1921 void imul_long_direct(u32 *res_lo, u32* res_hi,u32 d, u32 s)
1923 #ifdef __HAS_LONG_LONG__
1924 s64 res = (s32)d * (s32)s;
1927 *res_hi = (u32)(res >> 32);
1929 u32 d_lo,d_hi,d_sign;
1930 u32 s_lo,s_hi,s_sign;
1931 u32 rlo_lo,rlo_hi,rhi_lo;
1933 if ((d_sign = d & 0x80000000) != 0)
1937 if ((s_sign = s & 0x80000000) != 0)
1941 rlo_lo = d_lo * s_lo;
1942 rlo_hi = (d_hi * s_lo + d_lo * s_hi) + (rlo_lo >> 16);
1943 rhi_lo = d_hi * s_hi + (rlo_hi >> 16);
1944 *res_lo = (rlo_hi << 16) | (rlo_lo & 0xFFFF);
1946 if (d_sign != s_sign) {
1948 s = (((d & 0xFFFF) + 1) >> 16) + (d >> 16);
1949 *res_lo = ~*res_lo+1;
1950 *res_hi = ~*res_hi+(s >> 16);
1955 /****************************************************************************
1957 Implements the IMUL instruction and side effects.
1958 ****************************************************************************/
1959 void imul_long(u32 s)
1961 imul_long_direct(&M.x86.R_EAX,&M.x86.R_EDX,M.x86.R_EAX,s);
1962 if (((M.x86.R_EAX & 0x80000000) == 0 && M.x86.R_EDX == 0x00000000) ||
1963 ((M.x86.R_EAX & 0x80000000) != 0 && M.x86.R_EDX == 0xFFFFFFFF)) {
1972 /****************************************************************************
1974 Implements the MUL instruction and side effects.
1975 ****************************************************************************/
1978 u16 res = (u16)(M.x86.R_AL * s);
1981 if (M.x86.R_AH == 0) {
1990 /****************************************************************************
1992 Implements the MUL instruction and side effects.
1993 ****************************************************************************/
1994 void mul_word(u16 s)
1996 u32 res = M.x86.R_AX * s;
1998 M.x86.R_AX = (u16)res;
1999 M.x86.R_DX = (u16)(res >> 16);
2000 if (M.x86.R_DX == 0) {
2009 /****************************************************************************
2011 Implements the MUL instruction and side effects.
2012 ****************************************************************************/
2013 void mul_long(u32 s)
2015 #ifdef __HAS_LONG_LONG__
2016 u64 res = (u32)M.x86.R_EAX * (u32)s;
2018 M.x86.R_EAX = (u32)res;
2019 M.x86.R_EDX = (u32)(res >> 32);
2023 u32 rlo_lo,rlo_hi,rhi_lo;
2030 rlo_lo = a_lo * s_lo;
2031 rlo_hi = (a_hi * s_lo + a_lo * s_hi) + (rlo_lo >> 16);
2032 rhi_lo = a_hi * s_hi + (rlo_hi >> 16);
2033 M.x86.R_EAX = (rlo_hi << 16) | (rlo_lo & 0xFFFF);
2034 M.x86.R_EDX = rhi_lo;
2036 if (M.x86.R_EDX == 0) {
2045 /****************************************************************************
2047 Implements the IDIV instruction and side effects.
2048 ****************************************************************************/
2049 void idiv_byte(u8 s)
2053 dvd = (s16)M.x86.R_AX;
2055 x86emu_intr_raise(0);
2060 if (abs(div) > 0x7f) {
2061 x86emu_intr_raise(0);
2064 M.x86.R_AL = (s8) div;
2065 M.x86.R_AH = (s8) mod;
2068 /****************************************************************************
2070 Implements the IDIV instruction and side effects.
2071 ****************************************************************************/
2072 void idiv_word(u16 s)
2076 dvd = (((s32)M.x86.R_DX) << 16) | M.x86.R_AX;
2078 x86emu_intr_raise(0);
2083 if (abs(div) > 0x7fff) {
2084 x86emu_intr_raise(0);
2089 CONDITIONAL_SET_FLAG(div == 0, F_ZF);
2090 set_parity_flag(mod);
2092 M.x86.R_AX = (u16)div;
2093 M.x86.R_DX = (u16)mod;
2096 /****************************************************************************
2098 Implements the IDIV instruction and side effects.
2099 ****************************************************************************/
2100 void idiv_long(u32 s)
2102 #ifdef __HAS_LONG_LONG__
2105 dvd = (((s64)M.x86.R_EDX) << 32) | M.x86.R_EAX;
2107 x86emu_intr_raise(0);
2112 if (abs(div) > 0x7fffffff) {
2113 x86emu_intr_raise(0);
2118 s32 h_dvd = M.x86.R_EDX;
2119 u32 l_dvd = M.x86.R_EAX;
2120 u32 abs_s = s & 0x7FFFFFFF;
2121 u32 abs_h_dvd = h_dvd & 0x7FFFFFFF;
2122 u32 h_s = abs_s >> 1;
2123 u32 l_s = abs_s << 31;
2128 x86emu_intr_raise(0);
2133 carry = (l_dvd >= l_s) ? 0 : 1;
2135 if (abs_h_dvd < (h_s + carry)) {
2137 l_s = abs_s << (--counter);
2140 abs_h_dvd -= (h_s + carry);
2141 l_dvd = carry ? ((0xFFFFFFFF - l_s) + l_dvd + 1)
2144 l_s = abs_s << (--counter);
2149 } while (counter > -1);
2151 if (abs_h_dvd || (l_dvd > abs_s)) {
2152 x86emu_intr_raise(0);
2156 div |= ((h_dvd & 0x10000000) ^ (s & 0x10000000));
2164 set_parity_flag(mod);
2166 M.x86.R_EAX = (u32)div;
2167 M.x86.R_EDX = (u32)mod;
2170 /****************************************************************************
2172 Implements the DIV instruction and side effects.
2173 ****************************************************************************/
2180 x86emu_intr_raise(0);
2185 if (abs(div) > 0xff) {
2186 x86emu_intr_raise(0);
2189 M.x86.R_AL = (u8)div;
2190 M.x86.R_AH = (u8)mod;
2193 /****************************************************************************
2195 Implements the DIV instruction and side effects.
2196 ****************************************************************************/
2197 void div_word(u16 s)
2201 dvd = (((u32)M.x86.R_DX) << 16) | M.x86.R_AX;
2203 x86emu_intr_raise(0);
2208 if (abs(div) > 0xffff) {
2209 x86emu_intr_raise(0);
2214 CONDITIONAL_SET_FLAG(div == 0, F_ZF);
2215 set_parity_flag(mod);
2217 M.x86.R_AX = (u16)div;
2218 M.x86.R_DX = (u16)mod;
2221 /****************************************************************************
2223 Implements the DIV instruction and side effects.
2224 ****************************************************************************/
2225 void div_long(u32 s)
2227 #ifdef __HAS_LONG_LONG__
2230 dvd = (((u64)M.x86.R_EDX) << 32) | M.x86.R_EAX;
2232 x86emu_intr_raise(0);
2237 if (abs(div) > 0xffffffff) {
2238 x86emu_intr_raise(0);
2243 s32 h_dvd = M.x86.R_EDX;
2244 u32 l_dvd = M.x86.R_EAX;
2252 x86emu_intr_raise(0);
2257 carry = (l_dvd >= l_s) ? 0 : 1;
2259 if (h_dvd < (h_s + carry)) {
2261 l_s = s << (--counter);
2264 h_dvd -= (h_s + carry);
2265 l_dvd = carry ? ((0xFFFFFFFF - l_s) + l_dvd + 1)
2268 l_s = s << (--counter);
2273 } while (counter > -1);
2275 if (h_dvd || (l_dvd > s)) {
2276 x86emu_intr_raise(0);
2285 set_parity_flag(mod);
2287 M.x86.R_EAX = (u32)div;
2288 M.x86.R_EDX = (u32)mod;
2291 /****************************************************************************
2293 Implements the IN string instruction and side effects.
2294 ****************************************************************************/
2296 static void single_in(int size)
2299 store_data_byte_abs(M.x86.R_ES, M.x86.R_DI,(*sys_inb)(M.x86.R_DX));
2301 store_data_word_abs(M.x86.R_ES, M.x86.R_DI,(*sys_inw)(M.x86.R_DX));
2303 store_data_long_abs(M.x86.R_ES, M.x86.R_DI,(*sys_inl)(M.x86.R_DX));
2310 if (ACCESS_FLAG(F_DF)) {
2313 if (M.x86.mode & (SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE)) {
2314 /* dont care whether REPE or REPNE */
2315 /* in until CX is ZERO. */
2316 u32 count = ((M.x86.mode & SYSMODE_PREFIX_DATA) ?
2317 M.x86.R_ECX : M.x86.R_CX);
2324 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2327 M.x86.mode &= ~(SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE);
2334 /****************************************************************************
2336 Implements the OUT string instruction and side effects.
2337 ****************************************************************************/
2339 static void single_out(int size)
2342 (*sys_outb)(M.x86.R_DX,fetch_data_byte_abs(M.x86.R_ES, M.x86.R_SI));
2344 (*sys_outw)(M.x86.R_DX,fetch_data_word_abs(M.x86.R_ES, M.x86.R_SI));
2346 (*sys_outl)(M.x86.R_DX,fetch_data_long_abs(M.x86.R_ES, M.x86.R_SI));
2353 if (ACCESS_FLAG(F_DF)) {
2356 if (M.x86.mode & (SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE)) {
2357 /* dont care whether REPE or REPNE */
2358 /* out until CX is ZERO. */
2359 u32 count = ((M.x86.mode & SYSMODE_PREFIX_DATA) ?
2360 M.x86.R_ECX : M.x86.R_CX);
2366 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2369 M.x86.mode &= ~(SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE);
2376 /****************************************************************************
2378 addr - Address to fetch word from
2381 Fetches a word from emulator memory using an absolute address.
2382 ****************************************************************************/
2383 u16 mem_access_word(int addr)
2385 DB( if (CHECK_MEM_ACCESS())
2386 x86emu_check_mem_access(addr);)
2387 return (*sys_rdw)(addr);
2390 /****************************************************************************
2392 Pushes a word onto the stack.
2394 NOTE: Do not inline this, as (*sys_wrX) is already inline!
2395 ****************************************************************************/
2396 void push_word(u16 w)
2398 DB( if (CHECK_SP_ACCESS())
2399 x86emu_check_sp_access();)
2401 (*sys_wrw)(((u32)M.x86.R_SS << 4) + M.x86.R_SP, w);
2404 /****************************************************************************
2406 Pushes a long onto the stack.
2408 NOTE: Do not inline this, as (*sys_wrX) is already inline!
2409 ****************************************************************************/
2410 void push_long(u32 w)
2412 DB( if (CHECK_SP_ACCESS())
2413 x86emu_check_sp_access();)
2415 (*sys_wrl)(((u32)M.x86.R_SS << 4) + M.x86.R_SP, w);
2418 /****************************************************************************
2420 Pops a word from the stack.
2422 NOTE: Do not inline this, as (*sys_rdX) is already inline!
2423 ****************************************************************************/
2428 DB( if (CHECK_SP_ACCESS())
2429 x86emu_check_sp_access();)
2430 res = (*sys_rdw)(((u32)M.x86.R_SS << 4) + M.x86.R_SP);
2435 /****************************************************************************
2437 Pops a long from the stack.
2439 NOTE: Do not inline this, as (*sys_rdX) is already inline!
2440 ****************************************************************************/
2445 DB( if (CHECK_SP_ACCESS())
2446 x86emu_check_sp_access();)
2447 res = (*sys_rdl)(((u32)M.x86.R_SS << 4) + M.x86.R_SP);