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 ****************************************************************************/
100 #define PRIM_OPS_NO_REDEFINE_ASM
101 #include "x86emu/x86emui.h"
103 #if defined(CONFIG_BIOSEMU)
105 /*------------------------- Global Variables ------------------------------*/
107 static u32 x86emu_parity_tab[8] =
119 #define PARITY(x) (((x86emu_parity_tab[(x) / 32] >> ((x) % 32)) & 1) == 0)
120 #define XOR2(x) (((x) ^ ((x)>>1)) & 0x1)
121 /*----------------------------- Implementation ----------------------------*/
127 /*----------------------------- Implementation ----------------------------*/
130 /*--------- Side effects helper functions -------*/
132 /****************************************************************************
134 implements side efects for byte operations that don't overflow
135 ****************************************************************************/
137 static void set_parity_flag(u32 res)
139 CONDITIONAL_SET_FLAG(PARITY(res & 0xFF), F_PF);
142 static void set_szp_flags_8(u8 res)
144 CONDITIONAL_SET_FLAG(res & 0x80, F_SF);
145 CONDITIONAL_SET_FLAG(res == 0, F_ZF);
146 set_parity_flag(res);
149 static void set_szp_flags_16(u16 res)
151 CONDITIONAL_SET_FLAG(res & 0x8000, F_SF);
152 CONDITIONAL_SET_FLAG(res == 0, F_ZF);
153 set_parity_flag(res);
156 static void set_szp_flags_32(u32 res)
158 CONDITIONAL_SET_FLAG(res & 0x80000000, F_SF);
159 CONDITIONAL_SET_FLAG(res == 0, F_ZF);
160 set_parity_flag(res);
163 static void no_carry_byte_side_eff(u8 res)
168 set_szp_flags_8(res);
171 static void no_carry_word_side_eff(u16 res)
176 set_szp_flags_16(res);
179 static void no_carry_long_side_eff(u32 res)
184 set_szp_flags_32(res);
187 static void calc_carry_chain(int bits, u32 d, u32 s, u32 res, int set_carry)
191 cc = (s & d) | ((~res) & (s | d));
192 CONDITIONAL_SET_FLAG(XOR2(cc >> (bits - 2)), F_OF);
193 CONDITIONAL_SET_FLAG(cc & 0x8, F_AF);
195 CONDITIONAL_SET_FLAG(res & (1 << bits), F_CF);
199 static void calc_borrow_chain(int bits, u32 d, u32 s, u32 res, int set_carry)
203 bc = (res & (~d | s)) | (~d & s);
204 CONDITIONAL_SET_FLAG(XOR2(bc >> (bits - 2)), F_OF);
205 CONDITIONAL_SET_FLAG(bc & 0x8, F_AF);
207 CONDITIONAL_SET_FLAG(bc & (1 << (bits - 1)), F_CF);
211 /****************************************************************************
213 Implements the AAA instruction and side effects.
214 ****************************************************************************/
218 if ((d & 0xf) > 0x9 || ACCESS_FLAG(F_AF)) {
227 res = (u16)(d & 0xFF0F);
228 set_szp_flags_16(res);
232 /****************************************************************************
234 Implements the AAA instruction and side effects.
235 ****************************************************************************/
239 if ((d & 0xf) > 0x9 || ACCESS_FLAG(F_AF)) {
248 res = (u16)(d & 0xFF0F);
249 set_szp_flags_16(res);
253 /****************************************************************************
255 Implements the AAD instruction and side effects.
256 ****************************************************************************/
262 hb = (u8)((d >> 8) & 0xff);
263 lb = (u8)((d & 0xff));
264 l = (u16)((lb + 10 * hb) & 0xFF);
266 no_carry_byte_side_eff(l & 0xFF);
270 /****************************************************************************
272 Implements the AAM instruction and side effects.
273 ****************************************************************************/
282 no_carry_byte_side_eff(l & 0xFF);
286 /****************************************************************************
288 Implements the ADC instruction and side effects.
289 ****************************************************************************/
290 u8 adc_byte(u8 d, u8 s)
292 u32 res; /* all operands in native machine order */
295 if (ACCESS_FLAG(F_CF)) res++;
297 set_szp_flags_8(res);
298 calc_carry_chain(8,s,d,res,1);
303 /****************************************************************************
305 Implements the ADC instruction and side effects.
306 ****************************************************************************/
307 u16 adc_word(u16 d, u16 s)
309 u32 res; /* all operands in native machine order */
312 if (ACCESS_FLAG(F_CF))
315 set_szp_flags_16((u16)res);
316 calc_carry_chain(16,s,d,res,1);
321 /****************************************************************************
323 Implements the ADC instruction and side effects.
324 ****************************************************************************/
325 u32 adc_long(u32 d, u32 s)
327 u32 lo; /* all operands in native machine order */
331 lo = (d & 0xFFFF) + (s & 0xFFFF);
334 if (ACCESS_FLAG(F_CF)) {
339 hi = (lo >> 16) + (d >> 16) + (s >> 16);
341 set_szp_flags_32(res);
342 calc_carry_chain(32,s,d,res,0);
344 CONDITIONAL_SET_FLAG(hi & 0x10000, F_CF);
349 /****************************************************************************
351 Implements the ADD instruction and side effects.
352 ****************************************************************************/
353 u8 add_byte(u8 d, u8 s)
355 u32 res; /* all operands in native machine order */
358 set_szp_flags_8((u8)res);
359 calc_carry_chain(8,s,d,res,1);
364 /****************************************************************************
366 Implements the ADD instruction and side effects.
367 ****************************************************************************/
368 u16 add_word(u16 d, u16 s)
370 u32 res; /* all operands in native machine order */
373 set_szp_flags_16((u16)res);
374 calc_carry_chain(16,s,d,res,1);
379 /****************************************************************************
381 Implements the ADD instruction and side effects.
382 ****************************************************************************/
383 u32 add_long(u32 d, u32 s)
388 set_szp_flags_32(res);
389 calc_carry_chain(32,s,d,res,0);
391 CONDITIONAL_SET_FLAG(res < d || res < s, F_CF);
396 /****************************************************************************
398 Implements the AND instruction and side effects.
399 ****************************************************************************/
400 u8 and_byte(u8 d, u8 s)
402 u8 res; /* all operands in native machine order */
406 no_carry_byte_side_eff(res);
410 /****************************************************************************
412 Implements the AND instruction and side effects.
413 ****************************************************************************/
414 u16 and_word(u16 d, u16 s)
416 u16 res; /* all operands in native machine order */
420 no_carry_word_side_eff(res);
424 /****************************************************************************
426 Implements the AND instruction and side effects.
427 ****************************************************************************/
428 u32 and_long(u32 d, u32 s)
430 u32 res; /* all operands in native machine order */
433 no_carry_long_side_eff(res);
437 /****************************************************************************
439 Implements the CMP instruction and side effects.
440 ****************************************************************************/
441 u8 cmp_byte(u8 d, u8 s)
443 u32 res; /* all operands in native machine order */
446 set_szp_flags_8((u8)res);
447 calc_borrow_chain(8, d, s, res, 1);
452 /****************************************************************************
454 Implements the CMP instruction and side effects.
455 ****************************************************************************/
456 u16 cmp_word(u16 d, u16 s)
458 u32 res; /* all operands in native machine order */
461 set_szp_flags_16((u16)res);
462 calc_borrow_chain(16, d, s, res, 1);
467 /****************************************************************************
469 Implements the CMP instruction and side effects.
470 ****************************************************************************/
471 u32 cmp_long(u32 d, u32 s)
473 u32 res; /* all operands in native machine order */
476 set_szp_flags_32(res);
477 calc_borrow_chain(32, d, s, res, 1);
482 /****************************************************************************
484 Implements the DAA instruction and side effects.
485 ****************************************************************************/
489 if ((d & 0xf) > 9 || ACCESS_FLAG(F_AF)) {
493 if (res > 0x9F || ACCESS_FLAG(F_CF)) {
497 set_szp_flags_8((u8)res);
501 /****************************************************************************
503 Implements the DAS instruction and side effects.
504 ****************************************************************************/
507 if ((d & 0xf) > 9 || ACCESS_FLAG(F_AF)) {
511 if (d > 0x9F || ACCESS_FLAG(F_CF)) {
519 /****************************************************************************
521 Implements the DEC instruction and side effects.
522 ****************************************************************************/
525 u32 res; /* all operands in native machine order */
528 set_szp_flags_8((u8)res);
529 calc_borrow_chain(8, d, 1, res, 0);
534 /****************************************************************************
536 Implements the DEC instruction and side effects.
537 ****************************************************************************/
540 u32 res; /* all operands in native machine order */
543 set_szp_flags_16((u16)res);
544 calc_borrow_chain(16, d, 1, res, 0);
549 /****************************************************************************
551 Implements the DEC instruction and side effects.
552 ****************************************************************************/
555 u32 res; /* all operands in native machine order */
559 set_szp_flags_32(res);
560 calc_borrow_chain(32, d, 1, res, 0);
565 /****************************************************************************
567 Implements the INC instruction and side effects.
568 ****************************************************************************/
571 u32 res; /* all operands in native machine order */
574 set_szp_flags_8((u8)res);
575 calc_carry_chain(8, d, 1, res, 0);
580 /****************************************************************************
582 Implements the INC instruction and side effects.
583 ****************************************************************************/
586 u32 res; /* all operands in native machine order */
589 set_szp_flags_16((u16)res);
590 calc_carry_chain(16, d, 1, res, 0);
595 /****************************************************************************
597 Implements the INC instruction and side effects.
598 ****************************************************************************/
601 u32 res; /* all operands in native machine order */
604 set_szp_flags_32(res);
605 calc_carry_chain(32, d, 1, res, 0);
610 /****************************************************************************
612 Implements the OR instruction and side effects.
613 ****************************************************************************/
614 u8 or_byte(u8 d, u8 s)
616 u8 res; /* all operands in native machine order */
619 no_carry_byte_side_eff(res);
624 /****************************************************************************
626 Implements the OR instruction and side effects.
627 ****************************************************************************/
628 u16 or_word(u16 d, u16 s)
630 u16 res; /* all operands in native machine order */
633 no_carry_word_side_eff(res);
637 /****************************************************************************
639 Implements the OR instruction and side effects.
640 ****************************************************************************/
641 u32 or_long(u32 d, u32 s)
643 u32 res; /* all operands in native machine order */
646 no_carry_long_side_eff(res);
650 /****************************************************************************
652 Implements the OR instruction and side effects.
653 ****************************************************************************/
658 CONDITIONAL_SET_FLAG(s != 0, F_CF);
660 set_szp_flags_8(res);
661 calc_borrow_chain(8, 0, s, res, 0);
666 /****************************************************************************
668 Implements the OR instruction and side effects.
669 ****************************************************************************/
674 CONDITIONAL_SET_FLAG(s != 0, F_CF);
676 set_szp_flags_16((u16)res);
677 calc_borrow_chain(16, 0, s, res, 0);
682 /****************************************************************************
684 Implements the OR instruction and side effects.
685 ****************************************************************************/
690 CONDITIONAL_SET_FLAG(s != 0, F_CF);
692 set_szp_flags_32(res);
693 calc_borrow_chain(32, 0, s, res, 0);
698 /****************************************************************************
700 Implements the NOT instruction and side effects.
701 ****************************************************************************/
707 /****************************************************************************
709 Implements the NOT instruction and side effects.
710 ****************************************************************************/
716 /****************************************************************************
718 Implements the NOT instruction and side effects.
719 ****************************************************************************/
725 /****************************************************************************
727 Implements the RCL instruction and side effects.
728 ****************************************************************************/
729 u8 rcl_byte(u8 d, u8 s)
731 unsigned int res, cnt, mask, cf;
733 /* s is the rotate distance. It varies from 0 - 8. */
736 CF B_7 B_6 B_5 B_4 B_3 B_2 B_1 B_0
738 want to rotate through the carry by "s" bits. We could
739 loop, but that's inefficient. So the width is 9,
740 and we split into three parts:
742 The new carry flag (was B_n)
743 the stuff in B_n-1 .. B_0
744 the stuff in B_7 .. B_n+1
746 The new rotate is done mod 9, and given this,
747 for a rotation of n bits (mod 9) the new carry flag is
748 then located n bits from the MSB. The low part is
749 then shifted up cnt bits, and the high part is or'd
750 in. Using CAPS for new values, and lowercase for the
751 original values, this can be expressed as:
755 2) B_(7) .. B_(n) <- b_(8-(n+1)) .. b_0
757 4) B_(n-2) .. B_0 <- b_7 .. b_(8-(n-1))
760 if ((cnt = s % 9) != 0) {
761 /* extract the new CARRY FLAG. */
763 cf = (d >> (8 - cnt)) & 0x1;
765 /* get the low stuff which rotated
766 into the range B_7 .. B_cnt */
767 /* B_(7) .. B_(n) <- b_(8-(n+1)) .. b_0 */
768 /* note that the right hand side done by the mask */
769 res = (d << cnt) & 0xff;
771 /* now the high stuff which rotated around
772 into the positions B_cnt-2 .. B_0 */
773 /* B_(n-2) .. B_0 <- b_7 .. b_(8-(n-1)) */
774 /* shift it downward, 7-(n-2) = 9-n positions.
775 and mask off the result before or'ing in.
777 mask = (1 << (cnt - 1)) - 1;
778 res |= (d >> (9 - cnt)) & mask;
780 /* if the carry flag was set, or it in. */
781 if (ACCESS_FLAG(F_CF)) { /* carry flag is set */
783 res |= 1 << (cnt - 1);
785 /* set the new carry flag, based on the variable "cf" */
786 CONDITIONAL_SET_FLAG(cf, F_CF);
787 /* OVERFLOW is set *IFF* cnt==1, then it is the
788 xor of CF and the most significant bit. Blecck. */
789 /* parenthesized this expression since it appears to
790 be causing OF to be misset */
791 CONDITIONAL_SET_FLAG(cnt == 1 && XOR2(cf + ((res >> 6) & 0x2)),
798 /****************************************************************************
800 Implements the RCL instruction and side effects.
801 ****************************************************************************/
802 u16 rcl_word(u16 d, u8 s)
804 unsigned int res, cnt, mask, cf;
807 if ((cnt = s % 17) != 0) {
808 cf = (d >> (16 - cnt)) & 0x1;
809 res = (d << cnt) & 0xffff;
810 mask = (1 << (cnt - 1)) - 1;
811 res |= (d >> (17 - cnt)) & mask;
812 if (ACCESS_FLAG(F_CF)) {
813 res |= 1 << (cnt - 1);
815 CONDITIONAL_SET_FLAG(cf, F_CF);
816 CONDITIONAL_SET_FLAG(cnt == 1 && XOR2(cf + ((res >> 14) & 0x2)),
822 /****************************************************************************
824 Implements the RCL instruction and side effects.
825 ****************************************************************************/
826 u32 rcl_long(u32 d, u8 s)
828 u32 res, cnt, mask, cf;
831 if ((cnt = s % 33) != 0) {
832 cf = (d >> (32 - cnt)) & 0x1;
833 res = (d << cnt) & 0xffffffff;
834 mask = (1 << (cnt - 1)) - 1;
835 res |= (d >> (33 - cnt)) & mask;
836 if (ACCESS_FLAG(F_CF)) { /* carry flag is set */
837 res |= 1 << (cnt - 1);
839 CONDITIONAL_SET_FLAG(cf, F_CF);
840 CONDITIONAL_SET_FLAG(cnt == 1 && XOR2(cf + ((res >> 30) & 0x2)),
846 /****************************************************************************
848 Implements the RCR instruction and side effects.
849 ****************************************************************************/
850 u8 rcr_byte(u8 d, u8 s)
853 u32 mask, cf, ocf = 0;
855 /* rotate right through carry */
857 s is the rotate distance. It varies from 0 - 8.
858 d is the byte object rotated.
862 CF B_7 B_6 B_5 B_4 B_3 B_2 B_1 B_0
864 The new rotate is done mod 9, and given this,
865 for a rotation of n bits (mod 9) the new carry flag is
866 then located n bits from the LSB. The low part is
867 then shifted up cnt bits, and the high part is or'd
868 in. Using CAPS for new values, and lowercase for the
869 original values, this can be expressed as:
873 2) B_(8-(n+1)) .. B_(0) <- b_(7) .. b_(n)
875 4) B_(7) .. B_(8-(n-1)) <- b_(n-2) .. b_(0)
878 if ((cnt = s % 9) != 0) {
879 /* extract the new CARRY FLAG. */
883 /* note hackery here. Access_flag(..) evaluates to either
885 non-zero if flag is set.
886 doing access_flag(..) != 0 casts that into either
887 0..1 in any representation of the flags register
888 (i.e. packed bit array or unpacked.)
890 ocf = ACCESS_FLAG(F_CF) != 0;
892 cf = (d >> (cnt - 1)) & 0x1;
894 /* B_(8-(n+1)) .. B_(0) <- b_(7) .. b_n */
895 /* note that the right hand side done by the mask
896 This is effectively done by shifting the
897 object to the right. The result must be masked,
898 in case the object came in and was treated
899 as a negative number. Needed??? */
901 mask = (1 << (8 - cnt)) - 1;
902 res = (d >> cnt) & mask;
904 /* now the high stuff which rotated around
905 into the positions B_cnt-2 .. B_0 */
906 /* B_(7) .. B_(8-(n-1)) <- b_(n-2) .. b_(0) */
907 /* shift it downward, 7-(n-2) = 9-n positions.
908 and mask off the result before or'ing in.
910 res |= (d << (9 - cnt));
912 /* if the carry flag was set, or it in. */
913 if (ACCESS_FLAG(F_CF)) { /* carry flag is set */
915 res |= 1 << (8 - cnt);
917 /* set the new carry flag, based on the variable "cf" */
918 CONDITIONAL_SET_FLAG(cf, F_CF);
919 /* OVERFLOW is set *IFF* cnt==1, then it is the
920 xor of CF and the most significant bit. Blecck. */
921 /* parenthesized... */
923 CONDITIONAL_SET_FLAG(XOR2(ocf + ((d >> 6) & 0x2)),
930 /****************************************************************************
932 Implements the RCR instruction and side effects.
933 ****************************************************************************/
934 u16 rcr_word(u16 d, u8 s)
937 u32 mask, cf, ocf = 0;
939 /* rotate right through carry */
941 if ((cnt = s % 17) != 0) {
944 ocf = ACCESS_FLAG(F_CF) != 0;
946 cf = (d >> (cnt - 1)) & 0x1;
947 mask = (1 << (16 - cnt)) - 1;
948 res = (d >> cnt) & mask;
949 res |= (d << (17 - cnt));
950 if (ACCESS_FLAG(F_CF)) {
951 res |= 1 << (16 - cnt);
953 CONDITIONAL_SET_FLAG(cf, F_CF);
955 CONDITIONAL_SET_FLAG(XOR2(ocf + ((d >> 14) & 0x2)),
962 /****************************************************************************
964 Implements the RCR instruction and side effects.
965 ****************************************************************************/
966 u32 rcr_long(u32 d, u8 s)
969 u32 mask, cf, ocf = 0;
971 /* rotate right through carry */
973 if ((cnt = s % 33) != 0) {
976 ocf = ACCESS_FLAG(F_CF) != 0;
978 cf = (d >> (cnt - 1)) & 0x1;
979 mask = (1 << (32 - cnt)) - 1;
980 res = (d >> cnt) & mask;
982 res |= (d << (33 - cnt));
983 if (ACCESS_FLAG(F_CF)) { /* carry flag is set */
984 res |= 1 << (32 - cnt);
986 CONDITIONAL_SET_FLAG(cf, F_CF);
988 CONDITIONAL_SET_FLAG(XOR2(ocf + ((d >> 30) & 0x2)),
995 /****************************************************************************
997 Implements the ROL instruction and side effects.
998 ****************************************************************************/
999 u8 rol_byte(u8 d, u8 s)
1001 unsigned int res, cnt, mask;
1005 s is the rotate distance. It varies from 0 - 8.
1006 d is the byte object rotated.
1012 The new rotate is done mod 8.
1013 Much simpler than the "rcl" or "rcr" operations.
1016 1) B_(7) .. B_(n) <- b_(8-(n+1)) .. b_(0)
1017 2) B_(n-1) .. B_(0) <- b_(7) .. b_(8-n)
1020 if ((cnt = s % 8) != 0) {
1021 /* B_(7) .. B_(n) <- b_(8-(n+1)) .. b_(0) */
1024 /* B_(n-1) .. B_(0) <- b_(7) .. b_(8-n) */
1025 mask = (1 << cnt) - 1;
1026 res |= (d >> (8 - cnt)) & mask;
1028 /* set the new carry flag, Note that it is the low order
1029 bit of the result!!! */
1030 CONDITIONAL_SET_FLAG(res & 0x1, F_CF);
1031 /* OVERFLOW is set *IFF* s==1, then it is the
1032 xor of CF and the most significant bit. Blecck. */
1033 CONDITIONAL_SET_FLAG(s == 1 &&
1034 XOR2((res & 0x1) + ((res >> 6) & 0x2)),
1037 /* set the new carry flag, Note that it is the low order
1038 bit of the result!!! */
1039 CONDITIONAL_SET_FLAG(res & 0x1, F_CF);
1044 /****************************************************************************
1046 Implements the ROL instruction and side effects.
1047 ****************************************************************************/
1048 u16 rol_word(u16 d, u8 s)
1050 unsigned int res, cnt, mask;
1053 if ((cnt = s % 16) != 0) {
1055 mask = (1 << cnt) - 1;
1056 res |= (d >> (16 - cnt)) & mask;
1057 CONDITIONAL_SET_FLAG(res & 0x1, F_CF);
1058 CONDITIONAL_SET_FLAG(s == 1 &&
1059 XOR2((res & 0x1) + ((res >> 14) & 0x2)),
1062 /* set the new carry flag, Note that it is the low order
1063 bit of the result!!! */
1064 CONDITIONAL_SET_FLAG(res & 0x1, F_CF);
1069 /****************************************************************************
1071 Implements the ROL instruction and side effects.
1072 ****************************************************************************/
1073 u32 rol_long(u32 d, u8 s)
1078 if ((cnt = s % 32) != 0) {
1080 mask = (1 << cnt) - 1;
1081 res |= (d >> (32 - cnt)) & mask;
1082 CONDITIONAL_SET_FLAG(res & 0x1, F_CF);
1083 CONDITIONAL_SET_FLAG(s == 1 &&
1084 XOR2((res & 0x1) + ((res >> 30) & 0x2)),
1087 /* set the new carry flag, Note that it is the low order
1088 bit of the result!!! */
1089 CONDITIONAL_SET_FLAG(res & 0x1, F_CF);
1094 /****************************************************************************
1096 Implements the ROR instruction and side effects.
1097 ****************************************************************************/
1098 u8 ror_byte(u8 d, u8 s)
1100 unsigned int res, cnt, mask;
1104 s is the rotate distance. It varies from 0 - 8.
1105 d is the byte object rotated.
1111 The rotate is done mod 8.
1114 1) B_(8-(n+1)) .. B_(0) <- b_(7) .. b_(n)
1115 2) B_(7) .. B_(8-n) <- b_(n-1) .. b_(0)
1118 if ((cnt = s % 8) != 0) { /* not a typo, do nada if cnt==0 */
1119 /* B_(7) .. B_(8-n) <- b_(n-1) .. b_(0) */
1120 res = (d << (8 - cnt));
1122 /* B_(8-(n+1)) .. B_(0) <- b_(7) .. b_(n) */
1123 mask = (1 << (8 - cnt)) - 1;
1124 res |= (d >> (cnt)) & mask;
1126 /* set the new carry flag, Note that it is the low order
1127 bit of the result!!! */
1128 CONDITIONAL_SET_FLAG(res & 0x80, F_CF);
1129 /* OVERFLOW is set *IFF* s==1, then it is the
1130 xor of the two most significant bits. Blecck. */
1131 CONDITIONAL_SET_FLAG(s == 1 && XOR2(res >> 6), F_OF);
1132 } else if (s != 0) {
1133 /* set the new carry flag, Note that it is the low order
1134 bit of the result!!! */
1135 CONDITIONAL_SET_FLAG(res & 0x80, F_CF);
1140 /****************************************************************************
1142 Implements the ROR instruction and side effects.
1143 ****************************************************************************/
1144 u16 ror_word(u16 d, u8 s)
1146 unsigned int res, cnt, mask;
1149 if ((cnt = s % 16) != 0) {
1150 res = (d << (16 - cnt));
1151 mask = (1 << (16 - cnt)) - 1;
1152 res |= (d >> (cnt)) & mask;
1153 CONDITIONAL_SET_FLAG(res & 0x8000, F_CF);
1154 CONDITIONAL_SET_FLAG(s == 1 && XOR2(res >> 14), F_OF);
1155 } else if (s != 0) {
1156 /* set the new carry flag, Note that it is the low order
1157 bit of the result!!! */
1158 CONDITIONAL_SET_FLAG(res & 0x8000, F_CF);
1163 /****************************************************************************
1165 Implements the ROR instruction and side effects.
1166 ****************************************************************************/
1167 u32 ror_long(u32 d, u8 s)
1172 if ((cnt = s % 32) != 0) {
1173 res = (d << (32 - cnt));
1174 mask = (1 << (32 - cnt)) - 1;
1175 res |= (d >> (cnt)) & mask;
1176 CONDITIONAL_SET_FLAG(res & 0x80000000, F_CF);
1177 CONDITIONAL_SET_FLAG(s == 1 && XOR2(res >> 30), F_OF);
1178 } else if (s != 0) {
1179 /* set the new carry flag, Note that it is the low order
1180 bit of the result!!! */
1181 CONDITIONAL_SET_FLAG(res & 0x80000000, F_CF);
1186 /****************************************************************************
1188 Implements the SHL instruction and side effects.
1189 ****************************************************************************/
1190 u8 shl_byte(u8 d, u8 s)
1192 unsigned int cnt, res, cf;
1197 /* last bit shifted out goes into carry flag */
1200 cf = d & (1 << (8 - cnt));
1201 CONDITIONAL_SET_FLAG(cf, F_CF);
1202 set_szp_flags_8((u8)res);
1208 /* Needs simplification. */
1209 CONDITIONAL_SET_FLAG(
1210 (((res & 0x80) == 0x80) ^
1211 (ACCESS_FLAG(F_CF) != 0)),
1212 /* was (M.x86.R_FLG&F_CF)==F_CF)), */
1219 CONDITIONAL_SET_FLAG((d << (s-1)) & 0x80, F_CF);
1228 /****************************************************************************
1230 Implements the SHL instruction and side effects.
1231 ****************************************************************************/
1232 u16 shl_word(u16 d, u8 s)
1234 unsigned int cnt, res, cf;
1240 cf = d & (1 << (16 - cnt));
1241 CONDITIONAL_SET_FLAG(cf, F_CF);
1242 set_szp_flags_16((u16)res);
1248 CONDITIONAL_SET_FLAG(
1249 (((res & 0x8000) == 0x8000) ^
1250 (ACCESS_FLAG(F_CF) != 0)),
1257 CONDITIONAL_SET_FLAG((d << (s-1)) & 0x8000, F_CF);
1266 /****************************************************************************
1268 Implements the SHL instruction and side effects.
1269 ****************************************************************************/
1270 u32 shl_long(u32 d, u8 s)
1272 unsigned int cnt, res, cf;
1278 cf = d & (1 << (32 - cnt));
1279 CONDITIONAL_SET_FLAG(cf, F_CF);
1280 set_szp_flags_32((u32)res);
1285 CONDITIONAL_SET_FLAG((((res & 0x80000000) == 0x80000000) ^
1286 (ACCESS_FLAG(F_CF) != 0)), F_OF);
1292 CONDITIONAL_SET_FLAG((d << (s-1)) & 0x80000000, F_CF);
1301 /****************************************************************************
1303 Implements the SHR instruction and side effects.
1304 ****************************************************************************/
1305 u8 shr_byte(u8 d, u8 s)
1307 unsigned int cnt, res, cf;
1312 cf = d & (1 << (cnt - 1));
1314 CONDITIONAL_SET_FLAG(cf, F_CF);
1315 set_szp_flags_8((u8)res);
1321 CONDITIONAL_SET_FLAG(XOR2(res >> 6), F_OF);
1327 CONDITIONAL_SET_FLAG((d >> (s-1)) & 0x1, F_CF);
1336 /****************************************************************************
1338 Implements the SHR instruction and side effects.
1339 ****************************************************************************/
1340 u16 shr_word(u16 d, u8 s)
1342 unsigned int cnt, res, cf;
1347 cf = d & (1 << (cnt - 1));
1349 CONDITIONAL_SET_FLAG(cf, F_CF);
1350 set_szp_flags_16((u16)res);
1356 CONDITIONAL_SET_FLAG(XOR2(res >> 14), F_OF);
1371 /****************************************************************************
1373 Implements the SHR instruction and side effects.
1374 ****************************************************************************/
1375 u32 shr_long(u32 d, u8 s)
1377 unsigned int cnt, res, cf;
1382 cf = d & (1 << (cnt - 1));
1384 CONDITIONAL_SET_FLAG(cf, F_CF);
1385 set_szp_flags_32((u32)res);
1390 CONDITIONAL_SET_FLAG(XOR2(res >> 30), F_OF);
1405 /****************************************************************************
1407 Implements the SAR instruction and side effects.
1408 ****************************************************************************/
1409 u8 sar_byte(u8 d, u8 s)
1411 unsigned int cnt, res, cf, mask, sf;
1416 if (cnt > 0 && cnt < 8) {
1417 mask = (1 << (8 - cnt)) - 1;
1418 cf = d & (1 << (cnt - 1));
1419 res = (d >> cnt) & mask;
1420 CONDITIONAL_SET_FLAG(cf, F_CF);
1424 set_szp_flags_8((u8)res);
1425 } else if (cnt >= 8) {
1443 /****************************************************************************
1445 Implements the SAR instruction and side effects.
1446 ****************************************************************************/
1447 u16 sar_word(u16 d, u8 s)
1449 unsigned int cnt, res, cf, mask, sf;
1454 if (cnt > 0 && cnt < 16) {
1455 mask = (1 << (16 - cnt)) - 1;
1456 cf = d & (1 << (cnt - 1));
1457 res = (d >> cnt) & mask;
1458 CONDITIONAL_SET_FLAG(cf, F_CF);
1462 set_szp_flags_16((u16)res);
1463 } else if (cnt >= 16) {
1481 /****************************************************************************
1483 Implements the SAR instruction and side effects.
1484 ****************************************************************************/
1485 u32 sar_long(u32 d, u8 s)
1487 u32 cnt, res, cf, mask, sf;
1489 sf = d & 0x80000000;
1492 if (cnt > 0 && cnt < 32) {
1493 mask = (1 << (32 - cnt)) - 1;
1494 cf = d & (1 << (cnt - 1));
1495 res = (d >> cnt) & mask;
1496 CONDITIONAL_SET_FLAG(cf, F_CF);
1500 set_szp_flags_32(res);
1501 } else if (cnt >= 32) {
1519 /****************************************************************************
1521 Implements the SHLD instruction and side effects.
1522 ****************************************************************************/
1523 u16 shld_word (u16 d, u16 fill, u8 s)
1525 unsigned int cnt, res, cf;
1530 res = (d << cnt) | (fill >> (16-cnt));
1531 cf = d & (1 << (16 - cnt));
1532 CONDITIONAL_SET_FLAG(cf, F_CF);
1533 set_szp_flags_16((u16)res);
1538 CONDITIONAL_SET_FLAG((((res & 0x8000) == 0x8000) ^
1539 (ACCESS_FLAG(F_CF) != 0)), F_OF);
1545 CONDITIONAL_SET_FLAG((d << (s-1)) & 0x8000, F_CF);
1554 /****************************************************************************
1556 Implements the SHLD instruction and side effects.
1557 ****************************************************************************/
1558 u32 shld_long (u32 d, u32 fill, u8 s)
1560 unsigned int cnt, res, cf;
1565 res = (d << cnt) | (fill >> (32-cnt));
1566 cf = d & (1 << (32 - cnt));
1567 CONDITIONAL_SET_FLAG(cf, F_CF);
1568 set_szp_flags_32((u32)res);
1573 CONDITIONAL_SET_FLAG((((res & 0x80000000) == 0x80000000) ^
1574 (ACCESS_FLAG(F_CF) != 0)), F_OF);
1580 CONDITIONAL_SET_FLAG((d << (s-1)) & 0x80000000, F_CF);
1589 /****************************************************************************
1591 Implements the SHRD instruction and side effects.
1592 ****************************************************************************/
1593 u16 shrd_word (u16 d, u16 fill, u8 s)
1595 unsigned int cnt, res, cf;
1600 cf = d & (1 << (cnt - 1));
1601 res = (d >> cnt) | (fill << (16 - cnt));
1602 CONDITIONAL_SET_FLAG(cf, F_CF);
1603 set_szp_flags_16((u16)res);
1609 CONDITIONAL_SET_FLAG(XOR2(res >> 14), F_OF);
1624 /****************************************************************************
1626 Implements the SHRD instruction and side effects.
1627 ****************************************************************************/
1628 u32 shrd_long (u32 d, u32 fill, u8 s)
1630 unsigned int cnt, res, cf;
1635 cf = d & (1 << (cnt - 1));
1636 res = (d >> cnt) | (fill << (32 - cnt));
1637 CONDITIONAL_SET_FLAG(cf, F_CF);
1638 set_szp_flags_32((u32)res);
1643 CONDITIONAL_SET_FLAG(XOR2(res >> 30), F_OF);
1658 /****************************************************************************
1660 Implements the SBB instruction and side effects.
1661 ****************************************************************************/
1662 u8 sbb_byte(u8 d, u8 s)
1664 u32 res; /* all operands in native machine order */
1667 if (ACCESS_FLAG(F_CF))
1671 set_szp_flags_8((u8)res);
1673 /* calculate the borrow chain. See note at top */
1674 bc = (res & (~d | s)) | (~d & s);
1675 CONDITIONAL_SET_FLAG(bc & 0x80, F_CF);
1676 CONDITIONAL_SET_FLAG(XOR2(bc >> 6), F_OF);
1677 CONDITIONAL_SET_FLAG(bc & 0x8, F_AF);
1681 /****************************************************************************
1683 Implements the SBB instruction and side effects.
1684 ****************************************************************************/
1685 u16 sbb_word(u16 d, u16 s)
1687 u32 res; /* all operands in native machine order */
1690 if (ACCESS_FLAG(F_CF))
1694 set_szp_flags_16((u16)res);
1696 /* calculate the borrow chain. See note at top */
1697 bc = (res & (~d | s)) | (~d & s);
1698 CONDITIONAL_SET_FLAG(bc & 0x8000, F_CF);
1699 CONDITIONAL_SET_FLAG(XOR2(bc >> 14), F_OF);
1700 CONDITIONAL_SET_FLAG(bc & 0x8, F_AF);
1704 /****************************************************************************
1706 Implements the SBB instruction and side effects.
1707 ****************************************************************************/
1708 u32 sbb_long(u32 d, u32 s)
1710 u32 res; /* all operands in native machine order */
1713 if (ACCESS_FLAG(F_CF))
1718 set_szp_flags_32(res);
1720 /* calculate the borrow chain. See note at top */
1721 bc = (res & (~d | s)) | (~d & s);
1722 CONDITIONAL_SET_FLAG(bc & 0x80000000, F_CF);
1723 CONDITIONAL_SET_FLAG(XOR2(bc >> 30), F_OF);
1724 CONDITIONAL_SET_FLAG(bc & 0x8, F_AF);
1728 /****************************************************************************
1730 Implements the SUB instruction and side effects.
1731 ****************************************************************************/
1732 u8 sub_byte(u8 d, u8 s)
1734 u32 res; /* all operands in native machine order */
1738 set_szp_flags_8((u8)res);
1740 /* calculate the borrow chain. See note at top */
1741 bc = (res & (~d | s)) | (~d & s);
1742 CONDITIONAL_SET_FLAG(bc & 0x80, F_CF);
1743 CONDITIONAL_SET_FLAG(XOR2(bc >> 6), F_OF);
1744 CONDITIONAL_SET_FLAG(bc & 0x8, F_AF);
1748 /****************************************************************************
1750 Implements the SUB instruction and side effects.
1751 ****************************************************************************/
1752 u16 sub_word(u16 d, u16 s)
1754 u32 res; /* all operands in native machine order */
1758 set_szp_flags_16((u16)res);
1760 /* calculate the borrow chain. See note at top */
1761 bc = (res & (~d | s)) | (~d & s);
1762 CONDITIONAL_SET_FLAG(bc & 0x8000, F_CF);
1763 CONDITIONAL_SET_FLAG(XOR2(bc >> 14), F_OF);
1764 CONDITIONAL_SET_FLAG(bc & 0x8, F_AF);
1768 /****************************************************************************
1770 Implements the SUB instruction and side effects.
1771 ****************************************************************************/
1772 u32 sub_long(u32 d, u32 s)
1774 u32 res; /* all operands in native machine order */
1778 set_szp_flags_32(res);
1780 /* calculate the borrow chain. See note at top */
1781 bc = (res & (~d | s)) | (~d & s);
1782 CONDITIONAL_SET_FLAG(bc & 0x80000000, F_CF);
1783 CONDITIONAL_SET_FLAG(XOR2(bc >> 30), F_OF);
1784 CONDITIONAL_SET_FLAG(bc & 0x8, F_AF);
1788 /****************************************************************************
1790 Implements the TEST instruction and side effects.
1791 ****************************************************************************/
1792 void test_byte(u8 d, u8 s)
1794 u32 res; /* all operands in native machine order */
1799 set_szp_flags_8((u8)res);
1800 /* AF == dont care */
1804 /****************************************************************************
1806 Implements the TEST instruction and side effects.
1807 ****************************************************************************/
1808 void test_word(u16 d, u16 s)
1810 u32 res; /* all operands in native machine order */
1815 set_szp_flags_16((u16)res);
1816 /* AF == dont care */
1820 /****************************************************************************
1822 Implements the TEST instruction and side effects.
1823 ****************************************************************************/
1824 void test_long(u32 d, u32 s)
1826 u32 res; /* all operands in native machine order */
1831 set_szp_flags_32(res);
1832 /* AF == dont care */
1836 /****************************************************************************
1838 Implements the XOR instruction and side effects.
1839 ****************************************************************************/
1840 u8 xor_byte(u8 d, u8 s)
1842 u8 res; /* all operands in native machine order */
1845 no_carry_byte_side_eff(res);
1849 /****************************************************************************
1851 Implements the XOR instruction and side effects.
1852 ****************************************************************************/
1853 u16 xor_word(u16 d, u16 s)
1855 u16 res; /* all operands in native machine order */
1858 no_carry_word_side_eff(res);
1862 /****************************************************************************
1864 Implements the XOR instruction and side effects.
1865 ****************************************************************************/
1866 u32 xor_long(u32 d, u32 s)
1868 u32 res; /* all operands in native machine order */
1871 no_carry_long_side_eff(res);
1875 /****************************************************************************
1877 Implements the IMUL instruction and side effects.
1878 ****************************************************************************/
1879 void imul_byte(u8 s)
1881 s16 res = (s16)((s8)M.x86.R_AL * (s8)s);
1884 if (((M.x86.R_AL & 0x80) == 0 && M.x86.R_AH == 0x00) ||
1885 ((M.x86.R_AL & 0x80) != 0 && M.x86.R_AH == 0xFF)) {
1894 /****************************************************************************
1896 Implements the IMUL instruction and side effects.
1897 ****************************************************************************/
1898 void imul_word(u16 s)
1900 s32 res = (s16)M.x86.R_AX * (s16)s;
1902 M.x86.R_AX = (u16)res;
1903 M.x86.R_DX = (u16)(res >> 16);
1904 if (((M.x86.R_AX & 0x8000) == 0 && M.x86.R_DX == 0x0000) ||
1905 ((M.x86.R_AX & 0x8000) != 0 && M.x86.R_DX == 0xFFFF)) {
1914 /****************************************************************************
1916 Implements the IMUL instruction and side effects.
1917 ****************************************************************************/
1918 void imul_long_direct(u32 *res_lo, u32* res_hi,u32 d, u32 s)
1920 #ifdef __HAS_LONG_LONG__
1921 s64 res = (s32)d * (s32)s;
1924 *res_hi = (u32)(res >> 32);
1926 u32 d_lo,d_hi,d_sign;
1927 u32 s_lo,s_hi,s_sign;
1928 u32 rlo_lo,rlo_hi,rhi_lo;
1930 if ((d_sign = d & 0x80000000) != 0)
1934 if ((s_sign = s & 0x80000000) != 0)
1938 rlo_lo = d_lo * s_lo;
1939 rlo_hi = (d_hi * s_lo + d_lo * s_hi) + (rlo_lo >> 16);
1940 rhi_lo = d_hi * s_hi + (rlo_hi >> 16);
1941 *res_lo = (rlo_hi << 16) | (rlo_lo & 0xFFFF);
1943 if (d_sign != s_sign) {
1945 s = (((d & 0xFFFF) + 1) >> 16) + (d >> 16);
1946 *res_lo = ~*res_lo+1;
1947 *res_hi = ~*res_hi+(s >> 16);
1952 /****************************************************************************
1954 Implements the IMUL instruction and side effects.
1955 ****************************************************************************/
1956 void imul_long(u32 s)
1958 imul_long_direct(&M.x86.R_EAX,&M.x86.R_EDX,M.x86.R_EAX,s);
1959 if (((M.x86.R_EAX & 0x80000000) == 0 && M.x86.R_EDX == 0x00000000) ||
1960 ((M.x86.R_EAX & 0x80000000) != 0 && M.x86.R_EDX == 0xFFFFFFFF)) {
1969 /****************************************************************************
1971 Implements the MUL instruction and side effects.
1972 ****************************************************************************/
1975 u16 res = (u16)(M.x86.R_AL * s);
1978 if (M.x86.R_AH == 0) {
1987 /****************************************************************************
1989 Implements the MUL instruction and side effects.
1990 ****************************************************************************/
1991 void mul_word(u16 s)
1993 u32 res = M.x86.R_AX * s;
1995 M.x86.R_AX = (u16)res;
1996 M.x86.R_DX = (u16)(res >> 16);
1997 if (M.x86.R_DX == 0) {
2006 /****************************************************************************
2008 Implements the MUL instruction and side effects.
2009 ****************************************************************************/
2010 void mul_long(u32 s)
2012 #ifdef __HAS_LONG_LONG__
2013 u64 res = (u32)M.x86.R_EAX * (u32)s;
2015 M.x86.R_EAX = (u32)res;
2016 M.x86.R_EDX = (u32)(res >> 32);
2020 u32 rlo_lo,rlo_hi,rhi_lo;
2027 rlo_lo = a_lo * s_lo;
2028 rlo_hi = (a_hi * s_lo + a_lo * s_hi) + (rlo_lo >> 16);
2029 rhi_lo = a_hi * s_hi + (rlo_hi >> 16);
2030 M.x86.R_EAX = (rlo_hi << 16) | (rlo_lo & 0xFFFF);
2031 M.x86.R_EDX = rhi_lo;
2033 if (M.x86.R_EDX == 0) {
2042 /****************************************************************************
2044 Implements the IDIV instruction and side effects.
2045 ****************************************************************************/
2046 void idiv_byte(u8 s)
2050 dvd = (s16)M.x86.R_AX;
2052 x86emu_intr_raise(0);
2057 if (abs(div) > 0x7f) {
2058 x86emu_intr_raise(0);
2061 M.x86.R_AL = (s8) div;
2062 M.x86.R_AH = (s8) mod;
2065 /****************************************************************************
2067 Implements the IDIV instruction and side effects.
2068 ****************************************************************************/
2069 void idiv_word(u16 s)
2073 dvd = (((s32)M.x86.R_DX) << 16) | M.x86.R_AX;
2075 x86emu_intr_raise(0);
2080 if (abs(div) > 0x7fff) {
2081 x86emu_intr_raise(0);
2086 CONDITIONAL_SET_FLAG(div == 0, F_ZF);
2087 set_parity_flag(mod);
2089 M.x86.R_AX = (u16)div;
2090 M.x86.R_DX = (u16)mod;
2093 /****************************************************************************
2095 Implements the IDIV instruction and side effects.
2096 ****************************************************************************/
2097 void idiv_long(u32 s)
2099 #ifdef __HAS_LONG_LONG__
2102 dvd = (((s64)M.x86.R_EDX) << 32) | M.x86.R_EAX;
2104 x86emu_intr_raise(0);
2109 if (abs(div) > 0x7fffffff) {
2110 x86emu_intr_raise(0);
2115 s32 h_dvd = M.x86.R_EDX;
2116 u32 l_dvd = M.x86.R_EAX;
2117 u32 abs_s = s & 0x7FFFFFFF;
2118 u32 abs_h_dvd = h_dvd & 0x7FFFFFFF;
2119 u32 h_s = abs_s >> 1;
2120 u32 l_s = abs_s << 31;
2125 x86emu_intr_raise(0);
2130 carry = (l_dvd >= l_s) ? 0 : 1;
2132 if (abs_h_dvd < (h_s + carry)) {
2134 l_s = abs_s << (--counter);
2137 abs_h_dvd -= (h_s + carry);
2138 l_dvd = carry ? ((0xFFFFFFFF - l_s) + l_dvd + 1)
2141 l_s = abs_s << (--counter);
2146 } while (counter > -1);
2148 if (abs_h_dvd || (l_dvd > abs_s)) {
2149 x86emu_intr_raise(0);
2153 div |= ((h_dvd & 0x10000000) ^ (s & 0x10000000));
2161 set_parity_flag(mod);
2163 M.x86.R_EAX = (u32)div;
2164 M.x86.R_EDX = (u32)mod;
2167 /****************************************************************************
2169 Implements the DIV instruction and side effects.
2170 ****************************************************************************/
2177 x86emu_intr_raise(0);
2182 if (abs(div) > 0xff) {
2183 x86emu_intr_raise(0);
2186 M.x86.R_AL = (u8)div;
2187 M.x86.R_AH = (u8)mod;
2190 /****************************************************************************
2192 Implements the DIV instruction and side effects.
2193 ****************************************************************************/
2194 void div_word(u16 s)
2198 dvd = (((u32)M.x86.R_DX) << 16) | M.x86.R_AX;
2200 x86emu_intr_raise(0);
2205 if (abs(div) > 0xffff) {
2206 x86emu_intr_raise(0);
2211 CONDITIONAL_SET_FLAG(div == 0, F_ZF);
2212 set_parity_flag(mod);
2214 M.x86.R_AX = (u16)div;
2215 M.x86.R_DX = (u16)mod;
2218 /****************************************************************************
2220 Implements the DIV instruction and side effects.
2221 ****************************************************************************/
2222 void div_long(u32 s)
2224 #ifdef __HAS_LONG_LONG__
2227 dvd = (((u64)M.x86.R_EDX) << 32) | M.x86.R_EAX;
2229 x86emu_intr_raise(0);
2234 if (abs(div) > 0xffffffff) {
2235 x86emu_intr_raise(0);
2240 s32 h_dvd = M.x86.R_EDX;
2241 u32 l_dvd = M.x86.R_EAX;
2249 x86emu_intr_raise(0);
2254 carry = (l_dvd >= l_s) ? 0 : 1;
2256 if (h_dvd < (h_s + carry)) {
2258 l_s = s << (--counter);
2261 h_dvd -= (h_s + carry);
2262 l_dvd = carry ? ((0xFFFFFFFF - l_s) + l_dvd + 1)
2265 l_s = s << (--counter);
2270 } while (counter > -1);
2272 if (h_dvd || (l_dvd > s)) {
2273 x86emu_intr_raise(0);
2282 set_parity_flag(mod);
2284 M.x86.R_EAX = (u32)div;
2285 M.x86.R_EDX = (u32)mod;
2288 /****************************************************************************
2290 Implements the IN string instruction and side effects.
2291 ****************************************************************************/
2293 static void single_in(int size)
2296 store_data_byte_abs(M.x86.R_ES, M.x86.R_DI,(*sys_inb)(M.x86.R_DX));
2298 store_data_word_abs(M.x86.R_ES, M.x86.R_DI,(*sys_inw)(M.x86.R_DX));
2300 store_data_long_abs(M.x86.R_ES, M.x86.R_DI,(*sys_inl)(M.x86.R_DX));
2307 if (ACCESS_FLAG(F_DF)) {
2310 if (M.x86.mode & (SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE)) {
2311 /* dont care whether REPE or REPNE */
2312 /* in until CX is ZERO. */
2313 u32 count = ((M.x86.mode & SYSMODE_PREFIX_DATA) ?
2314 M.x86.R_ECX : M.x86.R_CX);
2321 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2324 M.x86.mode &= ~(SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE);
2331 /****************************************************************************
2333 Implements the OUT string instruction and side effects.
2334 ****************************************************************************/
2336 static void single_out(int size)
2339 (*sys_outb)(M.x86.R_DX,fetch_data_byte_abs(M.x86.R_ES, M.x86.R_SI));
2341 (*sys_outw)(M.x86.R_DX,fetch_data_word_abs(M.x86.R_ES, M.x86.R_SI));
2343 (*sys_outl)(M.x86.R_DX,fetch_data_long_abs(M.x86.R_ES, M.x86.R_SI));
2350 if (ACCESS_FLAG(F_DF)) {
2353 if (M.x86.mode & (SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE)) {
2354 /* dont care whether REPE or REPNE */
2355 /* out until CX is ZERO. */
2356 u32 count = ((M.x86.mode & SYSMODE_PREFIX_DATA) ?
2357 M.x86.R_ECX : M.x86.R_CX);
2363 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2366 M.x86.mode &= ~(SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE);
2373 /****************************************************************************
2375 addr - Address to fetch word from
2378 Fetches a word from emulator memory using an absolute address.
2379 ****************************************************************************/
2380 u16 mem_access_word(int addr)
2382 DB( if (CHECK_MEM_ACCESS())
2383 x86emu_check_mem_access(addr);)
2384 return (*sys_rdw)(addr);
2387 /****************************************************************************
2389 Pushes a word onto the stack.
2391 NOTE: Do not inline this, as (*sys_wrX) is already inline!
2392 ****************************************************************************/
2393 void push_word(u16 w)
2395 DB( if (CHECK_SP_ACCESS())
2396 x86emu_check_sp_access();)
2398 (*sys_wrw)(((u32)M.x86.R_SS << 4) + M.x86.R_SP, w);
2401 /****************************************************************************
2403 Pushes a long onto the stack.
2405 NOTE: Do not inline this, as (*sys_wrX) is already inline!
2406 ****************************************************************************/
2407 void push_long(u32 w)
2409 DB( if (CHECK_SP_ACCESS())
2410 x86emu_check_sp_access();)
2412 (*sys_wrl)(((u32)M.x86.R_SS << 4) + M.x86.R_SP, w);
2415 /****************************************************************************
2417 Pops a word from the stack.
2419 NOTE: Do not inline this, as (*sys_rdX) is already inline!
2420 ****************************************************************************/
2425 DB( if (CHECK_SP_ACCESS())
2426 x86emu_check_sp_access();)
2427 res = (*sys_rdw)(((u32)M.x86.R_SS << 4) + M.x86.R_SP);
2432 /****************************************************************************
2434 Pops a long from the stack.
2436 NOTE: Do not inline this, as (*sys_rdX) is already inline!
2437 ****************************************************************************/
2442 DB( if (CHECK_SP_ACCESS())
2443 x86emu_check_sp_access();)
2444 res = (*sys_rdl)(((u32)M.x86.R_SS << 4) + M.x86.R_SP);