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
103 #include "x86emu/x86emui.h"
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)
122 /*----------------------------- Implementation ----------------------------*/
125 /*--------- Side effects helper functions -------*/
127 /****************************************************************************
129 implements side efects for byte operations that don't overflow
130 ****************************************************************************/
132 static void set_parity_flag(u32 res)
134 CONDITIONAL_SET_FLAG(PARITY(res & 0xFF), F_PF);
137 static void set_szp_flags_8(u8 res)
139 CONDITIONAL_SET_FLAG(res & 0x80, F_SF);
140 CONDITIONAL_SET_FLAG(res == 0, F_ZF);
141 set_parity_flag(res);
144 static void set_szp_flags_16(u16 res)
146 CONDITIONAL_SET_FLAG(res & 0x8000, F_SF);
147 CONDITIONAL_SET_FLAG(res == 0, F_ZF);
148 set_parity_flag(res);
151 static void set_szp_flags_32(u32 res)
153 CONDITIONAL_SET_FLAG(res & 0x80000000, F_SF);
154 CONDITIONAL_SET_FLAG(res == 0, F_ZF);
155 set_parity_flag(res);
158 static void no_carry_byte_side_eff(u8 res)
163 set_szp_flags_8(res);
166 static void no_carry_word_side_eff(u16 res)
171 set_szp_flags_16(res);
174 static void no_carry_long_side_eff(u32 res)
179 set_szp_flags_32(res);
182 static void calc_carry_chain(int bits, u32 d, u32 s, u32 res, int set_carry)
186 cc = (s & d) | ((~res) & (s | d));
187 CONDITIONAL_SET_FLAG(XOR2(cc >> (bits - 2)), F_OF);
188 CONDITIONAL_SET_FLAG(cc & 0x8, F_AF);
190 CONDITIONAL_SET_FLAG(res & (1 << bits), F_CF);
194 static void calc_borrow_chain(int bits, u32 d, u32 s, u32 res, int set_carry)
198 bc = (res & (~d | s)) | (~d & s);
199 CONDITIONAL_SET_FLAG(XOR2(bc >> (bits - 2)), F_OF);
200 CONDITIONAL_SET_FLAG(bc & 0x8, F_AF);
202 CONDITIONAL_SET_FLAG(bc & (1 << (bits - 1)), F_CF);
206 /****************************************************************************
208 Implements the AAA instruction and side effects.
209 ****************************************************************************/
213 if ((d & 0xf) > 0x9 || ACCESS_FLAG(F_AF)) {
222 res = (u16)(d & 0xFF0F);
223 set_szp_flags_16(res);
227 /****************************************************************************
229 Implements the AAA instruction and side effects.
230 ****************************************************************************/
234 if ((d & 0xf) > 0x9 || ACCESS_FLAG(F_AF)) {
243 res = (u16)(d & 0xFF0F);
244 set_szp_flags_16(res);
248 /****************************************************************************
250 Implements the AAD instruction and side effects.
251 ****************************************************************************/
257 hb = (u8)((d >> 8) & 0xff);
258 lb = (u8)((d & 0xff));
259 l = (u16)((lb + 10 * hb) & 0xFF);
261 no_carry_byte_side_eff(l & 0xFF);
265 /****************************************************************************
267 Implements the AAM instruction and side effects.
268 ****************************************************************************/
277 no_carry_byte_side_eff(l & 0xFF);
281 /****************************************************************************
283 Implements the ADC instruction and side effects.
284 ****************************************************************************/
285 u8 adc_byte(u8 d, u8 s)
287 u32 res; /* all operands in native machine order */
290 if (ACCESS_FLAG(F_CF)) res++;
292 set_szp_flags_8(res);
293 calc_carry_chain(8,s,d,res,1);
298 /****************************************************************************
300 Implements the ADC instruction and side effects.
301 ****************************************************************************/
302 u16 adc_word(u16 d, u16 s)
304 u32 res; /* all operands in native machine order */
307 if (ACCESS_FLAG(F_CF))
310 set_szp_flags_16((u16)res);
311 calc_carry_chain(16,s,d,res,1);
316 /****************************************************************************
318 Implements the ADC instruction and side effects.
319 ****************************************************************************/
320 u32 adc_long(u32 d, u32 s)
322 u32 lo; /* all operands in native machine order */
326 lo = (d & 0xFFFF) + (s & 0xFFFF);
329 if (ACCESS_FLAG(F_CF)) {
334 hi = (lo >> 16) + (d >> 16) + (s >> 16);
336 set_szp_flags_32(res);
337 calc_carry_chain(32,s,d,res,0);
339 CONDITIONAL_SET_FLAG(hi & 0x10000, F_CF);
344 /****************************************************************************
346 Implements the ADD instruction and side effects.
347 ****************************************************************************/
348 u8 add_byte(u8 d, u8 s)
350 u32 res; /* all operands in native machine order */
353 set_szp_flags_8((u8)res);
354 calc_carry_chain(8,s,d,res,1);
359 /****************************************************************************
361 Implements the ADD instruction and side effects.
362 ****************************************************************************/
363 u16 add_word(u16 d, u16 s)
365 u32 res; /* all operands in native machine order */
368 set_szp_flags_16((u16)res);
369 calc_carry_chain(16,s,d,res,1);
374 /****************************************************************************
376 Implements the ADD instruction and side effects.
377 ****************************************************************************/
378 u32 add_long(u32 d, u32 s)
383 set_szp_flags_32(res);
384 calc_carry_chain(32,s,d,res,0);
386 CONDITIONAL_SET_FLAG(res < d || res < s, F_CF);
391 /****************************************************************************
393 Implements the AND instruction and side effects.
394 ****************************************************************************/
395 u8 and_byte(u8 d, u8 s)
397 u8 res; /* all operands in native machine order */
401 no_carry_byte_side_eff(res);
405 /****************************************************************************
407 Implements the AND instruction and side effects.
408 ****************************************************************************/
409 u16 and_word(u16 d, u16 s)
411 u16 res; /* all operands in native machine order */
415 no_carry_word_side_eff(res);
419 /****************************************************************************
421 Implements the AND instruction and side effects.
422 ****************************************************************************/
423 u32 and_long(u32 d, u32 s)
425 u32 res; /* all operands in native machine order */
428 no_carry_long_side_eff(res);
432 /****************************************************************************
434 Implements the CMP instruction and side effects.
435 ****************************************************************************/
436 u8 cmp_byte(u8 d, u8 s)
438 u32 res; /* all operands in native machine order */
441 set_szp_flags_8((u8)res);
442 calc_borrow_chain(8, d, s, res, 1);
447 /****************************************************************************
449 Implements the CMP instruction and side effects.
450 ****************************************************************************/
451 u16 cmp_word(u16 d, u16 s)
453 u32 res; /* all operands in native machine order */
456 set_szp_flags_16((u16)res);
457 calc_borrow_chain(16, d, s, res, 1);
462 /****************************************************************************
464 Implements the CMP instruction and side effects.
465 ****************************************************************************/
466 u32 cmp_long(u32 d, u32 s)
468 u32 res; /* all operands in native machine order */
471 set_szp_flags_32(res);
472 calc_borrow_chain(32, d, s, res, 1);
477 /****************************************************************************
479 Implements the DAA instruction and side effects.
480 ****************************************************************************/
484 if ((d & 0xf) > 9 || ACCESS_FLAG(F_AF)) {
488 if (res > 0x9F || ACCESS_FLAG(F_CF)) {
492 set_szp_flags_8((u8)res);
496 /****************************************************************************
498 Implements the DAS instruction and side effects.
499 ****************************************************************************/
502 if ((d & 0xf) > 9 || ACCESS_FLAG(F_AF)) {
506 if (d > 0x9F || ACCESS_FLAG(F_CF)) {
514 /****************************************************************************
516 Implements the DEC instruction and side effects.
517 ****************************************************************************/
520 u32 res; /* all operands in native machine order */
523 set_szp_flags_8((u8)res);
524 calc_borrow_chain(8, d, 1, res, 0);
529 /****************************************************************************
531 Implements the DEC instruction and side effects.
532 ****************************************************************************/
535 u32 res; /* all operands in native machine order */
538 set_szp_flags_16((u16)res);
539 calc_borrow_chain(16, d, 1, res, 0);
544 /****************************************************************************
546 Implements the DEC instruction and side effects.
547 ****************************************************************************/
550 u32 res; /* all operands in native machine order */
554 set_szp_flags_32(res);
555 calc_borrow_chain(32, d, 1, res, 0);
560 /****************************************************************************
562 Implements the INC instruction and side effects.
563 ****************************************************************************/
566 u32 res; /* all operands in native machine order */
569 set_szp_flags_8((u8)res);
570 calc_carry_chain(8, d, 1, res, 0);
575 /****************************************************************************
577 Implements the INC instruction and side effects.
578 ****************************************************************************/
581 u32 res; /* all operands in native machine order */
584 set_szp_flags_16((u16)res);
585 calc_carry_chain(16, d, 1, res, 0);
590 /****************************************************************************
592 Implements the INC instruction and side effects.
593 ****************************************************************************/
596 u32 res; /* all operands in native machine order */
599 set_szp_flags_32(res);
600 calc_carry_chain(32, d, 1, res, 0);
605 /****************************************************************************
607 Implements the OR instruction and side effects.
608 ****************************************************************************/
609 u8 or_byte(u8 d, u8 s)
611 u8 res; /* all operands in native machine order */
614 no_carry_byte_side_eff(res);
619 /****************************************************************************
621 Implements the OR instruction and side effects.
622 ****************************************************************************/
623 u16 or_word(u16 d, u16 s)
625 u16 res; /* all operands in native machine order */
628 no_carry_word_side_eff(res);
632 /****************************************************************************
634 Implements the OR instruction and side effects.
635 ****************************************************************************/
636 u32 or_long(u32 d, u32 s)
638 u32 res; /* all operands in native machine order */
641 no_carry_long_side_eff(res);
645 /****************************************************************************
647 Implements the OR instruction and side effects.
648 ****************************************************************************/
653 CONDITIONAL_SET_FLAG(s != 0, F_CF);
655 set_szp_flags_8(res);
656 calc_borrow_chain(8, 0, s, res, 0);
661 /****************************************************************************
663 Implements the OR instruction and side effects.
664 ****************************************************************************/
669 CONDITIONAL_SET_FLAG(s != 0, F_CF);
671 set_szp_flags_16((u16)res);
672 calc_borrow_chain(16, 0, s, res, 0);
677 /****************************************************************************
679 Implements the OR instruction and side effects.
680 ****************************************************************************/
685 CONDITIONAL_SET_FLAG(s != 0, F_CF);
687 set_szp_flags_32(res);
688 calc_borrow_chain(32, 0, s, res, 0);
693 /****************************************************************************
695 Implements the NOT instruction and side effects.
696 ****************************************************************************/
702 /****************************************************************************
704 Implements the NOT instruction and side effects.
705 ****************************************************************************/
711 /****************************************************************************
713 Implements the NOT instruction and side effects.
714 ****************************************************************************/
720 /****************************************************************************
722 Implements the RCL instruction and side effects.
723 ****************************************************************************/
724 u8 rcl_byte(u8 d, u8 s)
726 unsigned int res, cnt, mask, cf;
728 /* s is the rotate distance. It varies from 0 - 8. */
731 CF B_7 B_6 B_5 B_4 B_3 B_2 B_1 B_0
733 want to rotate through the carry by "s" bits. We could
734 loop, but that's inefficient. So the width is 9,
735 and we split into three parts:
737 The new carry flag (was B_n)
738 the stuff in B_n-1 .. B_0
739 the stuff in B_7 .. B_n+1
741 The new rotate is done mod 9, and given this,
742 for a rotation of n bits (mod 9) the new carry flag is
743 then located n bits from the MSB. The low part is
744 then shifted up cnt bits, and the high part is or'd
745 in. Using CAPS for new values, and lowercase for the
746 original values, this can be expressed as:
750 2) B_(7) .. B_(n) <- b_(8-(n+1)) .. b_0
752 4) B_(n-2) .. B_0 <- b_7 .. b_(8-(n-1))
755 if ((cnt = s % 9) != 0) {
756 /* extract the new CARRY FLAG. */
758 cf = (d >> (8 - cnt)) & 0x1;
760 /* get the low stuff which rotated
761 into the range B_7 .. B_cnt */
762 /* B_(7) .. B_(n) <- b_(8-(n+1)) .. b_0 */
763 /* note that the right hand side done by the mask */
764 res = (d << cnt) & 0xff;
766 /* now the high stuff which rotated around
767 into the positions B_cnt-2 .. B_0 */
768 /* B_(n-2) .. B_0 <- b_7 .. b_(8-(n-1)) */
769 /* shift it downward, 7-(n-2) = 9-n positions.
770 and mask off the result before or'ing in.
772 mask = (1 << (cnt - 1)) - 1;
773 res |= (d >> (9 - cnt)) & mask;
775 /* if the carry flag was set, or it in. */
776 if (ACCESS_FLAG(F_CF)) { /* carry flag is set */
778 res |= 1 << (cnt - 1);
780 /* set the new carry flag, based on the variable "cf" */
781 CONDITIONAL_SET_FLAG(cf, F_CF);
782 /* OVERFLOW is set *IFF* cnt==1, then it is the
783 xor of CF and the most significant bit. Blecck. */
784 /* parenthesized this expression since it appears to
785 be causing OF to be misset */
786 CONDITIONAL_SET_FLAG(cnt == 1 && XOR2(cf + ((res >> 6) & 0x2)),
793 /****************************************************************************
795 Implements the RCL instruction and side effects.
796 ****************************************************************************/
797 u16 rcl_word(u16 d, u8 s)
799 unsigned int res, cnt, mask, cf;
802 if ((cnt = s % 17) != 0) {
803 cf = (d >> (16 - cnt)) & 0x1;
804 res = (d << cnt) & 0xffff;
805 mask = (1 << (cnt - 1)) - 1;
806 res |= (d >> (17 - cnt)) & mask;
807 if (ACCESS_FLAG(F_CF)) {
808 res |= 1 << (cnt - 1);
810 CONDITIONAL_SET_FLAG(cf, F_CF);
811 CONDITIONAL_SET_FLAG(cnt == 1 && XOR2(cf + ((res >> 14) & 0x2)),
817 /****************************************************************************
819 Implements the RCL instruction and side effects.
820 ****************************************************************************/
821 u32 rcl_long(u32 d, u8 s)
823 u32 res, cnt, mask, cf;
826 if ((cnt = s % 33) != 0) {
827 cf = (d >> (32 - cnt)) & 0x1;
828 res = (d << cnt) & 0xffffffff;
829 mask = (1 << (cnt - 1)) - 1;
830 res |= (d >> (33 - cnt)) & mask;
831 if (ACCESS_FLAG(F_CF)) { /* carry flag is set */
832 res |= 1 << (cnt - 1);
834 CONDITIONAL_SET_FLAG(cf, F_CF);
835 CONDITIONAL_SET_FLAG(cnt == 1 && XOR2(cf + ((res >> 30) & 0x2)),
841 /****************************************************************************
843 Implements the RCR instruction and side effects.
844 ****************************************************************************/
845 u8 rcr_byte(u8 d, u8 s)
848 u32 mask, cf, ocf = 0;
850 /* rotate right through carry */
852 s is the rotate distance. It varies from 0 - 8.
853 d is the byte object rotated.
857 CF B_7 B_6 B_5 B_4 B_3 B_2 B_1 B_0
859 The new rotate is done mod 9, and given this,
860 for a rotation of n bits (mod 9) the new carry flag is
861 then located n bits from the LSB. The low part is
862 then shifted up cnt bits, and the high part is or'd
863 in. Using CAPS for new values, and lowercase for the
864 original values, this can be expressed as:
868 2) B_(8-(n+1)) .. B_(0) <- b_(7) .. b_(n)
870 4) B_(7) .. B_(8-(n-1)) <- b_(n-2) .. b_(0)
873 if ((cnt = s % 9) != 0) {
874 /* extract the new CARRY FLAG. */
878 /* note hackery here. Access_flag(..) evaluates to either
880 non-zero if flag is set.
881 doing access_flag(..) != 0 casts that into either
882 0..1 in any representation of the flags register
883 (i.e. packed bit array or unpacked.)
885 ocf = ACCESS_FLAG(F_CF) != 0;
887 cf = (d >> (cnt - 1)) & 0x1;
889 /* B_(8-(n+1)) .. B_(0) <- b_(7) .. b_n */
890 /* note that the right hand side done by the mask
891 This is effectively done by shifting the
892 object to the right. The result must be masked,
893 in case the object came in and was treated
894 as a negative number. Needed??? */
896 mask = (1 << (8 - cnt)) - 1;
897 res = (d >> cnt) & mask;
899 /* now the high stuff which rotated around
900 into the positions B_cnt-2 .. B_0 */
901 /* B_(7) .. B_(8-(n-1)) <- b_(n-2) .. b_(0) */
902 /* shift it downward, 7-(n-2) = 9-n positions.
903 and mask off the result before or'ing in.
905 res |= (d << (9 - cnt));
907 /* if the carry flag was set, or it in. */
908 if (ACCESS_FLAG(F_CF)) { /* carry flag is set */
910 res |= 1 << (8 - cnt);
912 /* set the new carry flag, based on the variable "cf" */
913 CONDITIONAL_SET_FLAG(cf, F_CF);
914 /* OVERFLOW is set *IFF* cnt==1, then it is the
915 xor of CF and the most significant bit. Blecck. */
916 /* parenthesized... */
918 CONDITIONAL_SET_FLAG(XOR2(ocf + ((d >> 6) & 0x2)),
925 /****************************************************************************
927 Implements the RCR instruction and side effects.
928 ****************************************************************************/
929 u16 rcr_word(u16 d, u8 s)
932 u32 mask, cf, ocf = 0;
934 /* rotate right through carry */
936 if ((cnt = s % 17) != 0) {
939 ocf = ACCESS_FLAG(F_CF) != 0;
941 cf = (d >> (cnt - 1)) & 0x1;
942 mask = (1 << (16 - cnt)) - 1;
943 res = (d >> cnt) & mask;
944 res |= (d << (17 - cnt));
945 if (ACCESS_FLAG(F_CF)) {
946 res |= 1 << (16 - cnt);
948 CONDITIONAL_SET_FLAG(cf, F_CF);
950 CONDITIONAL_SET_FLAG(XOR2(ocf + ((d >> 14) & 0x2)),
957 /****************************************************************************
959 Implements the RCR instruction and side effects.
960 ****************************************************************************/
961 u32 rcr_long(u32 d, u8 s)
964 u32 mask, cf, ocf = 0;
966 /* rotate right through carry */
968 if ((cnt = s % 33) != 0) {
971 ocf = ACCESS_FLAG(F_CF) != 0;
973 cf = (d >> (cnt - 1)) & 0x1;
974 mask = (1 << (32 - cnt)) - 1;
975 res = (d >> cnt) & mask;
977 res |= (d << (33 - cnt));
978 if (ACCESS_FLAG(F_CF)) { /* carry flag is set */
979 res |= 1 << (32 - cnt);
981 CONDITIONAL_SET_FLAG(cf, F_CF);
983 CONDITIONAL_SET_FLAG(XOR2(ocf + ((d >> 30) & 0x2)),
990 /****************************************************************************
992 Implements the ROL instruction and side effects.
993 ****************************************************************************/
994 u8 rol_byte(u8 d, u8 s)
996 unsigned int res, cnt, mask;
1000 s is the rotate distance. It varies from 0 - 8.
1001 d is the byte object rotated.
1007 The new rotate is done mod 8.
1008 Much simpler than the "rcl" or "rcr" operations.
1011 1) B_(7) .. B_(n) <- b_(8-(n+1)) .. b_(0)
1012 2) B_(n-1) .. B_(0) <- b_(7) .. b_(8-n)
1015 if ((cnt = s % 8) != 0) {
1016 /* B_(7) .. B_(n) <- b_(8-(n+1)) .. b_(0) */
1019 /* B_(n-1) .. B_(0) <- b_(7) .. b_(8-n) */
1020 mask = (1 << cnt) - 1;
1021 res |= (d >> (8 - cnt)) & mask;
1023 /* set the new carry flag, Note that it is the low order
1024 bit of the result!!! */
1025 CONDITIONAL_SET_FLAG(res & 0x1, F_CF);
1026 /* OVERFLOW is set *IFF* s==1, then it is the
1027 xor of CF and the most significant bit. Blecck. */
1028 CONDITIONAL_SET_FLAG(s == 1 &&
1029 XOR2((res & 0x1) + ((res >> 6) & 0x2)),
1032 /* set the new carry flag, Note that it is the low order
1033 bit of the result!!! */
1034 CONDITIONAL_SET_FLAG(res & 0x1, F_CF);
1039 /****************************************************************************
1041 Implements the ROL instruction and side effects.
1042 ****************************************************************************/
1043 u16 rol_word(u16 d, u8 s)
1045 unsigned int res, cnt, mask;
1048 if ((cnt = s % 16) != 0) {
1050 mask = (1 << cnt) - 1;
1051 res |= (d >> (16 - cnt)) & mask;
1052 CONDITIONAL_SET_FLAG(res & 0x1, F_CF);
1053 CONDITIONAL_SET_FLAG(s == 1 &&
1054 XOR2((res & 0x1) + ((res >> 14) & 0x2)),
1057 /* set the new carry flag, Note that it is the low order
1058 bit of the result!!! */
1059 CONDITIONAL_SET_FLAG(res & 0x1, F_CF);
1064 /****************************************************************************
1066 Implements the ROL instruction and side effects.
1067 ****************************************************************************/
1068 u32 rol_long(u32 d, u8 s)
1073 if ((cnt = s % 32) != 0) {
1075 mask = (1 << cnt) - 1;
1076 res |= (d >> (32 - cnt)) & mask;
1077 CONDITIONAL_SET_FLAG(res & 0x1, F_CF);
1078 CONDITIONAL_SET_FLAG(s == 1 &&
1079 XOR2((res & 0x1) + ((res >> 30) & 0x2)),
1082 /* set the new carry flag, Note that it is the low order
1083 bit of the result!!! */
1084 CONDITIONAL_SET_FLAG(res & 0x1, F_CF);
1089 /****************************************************************************
1091 Implements the ROR instruction and side effects.
1092 ****************************************************************************/
1093 u8 ror_byte(u8 d, u8 s)
1095 unsigned int res, cnt, mask;
1099 s is the rotate distance. It varies from 0 - 8.
1100 d is the byte object rotated.
1106 The rotate is done mod 8.
1109 1) B_(8-(n+1)) .. B_(0) <- b_(7) .. b_(n)
1110 2) B_(7) .. B_(8-n) <- b_(n-1) .. b_(0)
1113 if ((cnt = s % 8) != 0) { /* not a typo, do nada if cnt==0 */
1114 /* B_(7) .. B_(8-n) <- b_(n-1) .. b_(0) */
1115 res = (d << (8 - cnt));
1117 /* B_(8-(n+1)) .. B_(0) <- b_(7) .. b_(n) */
1118 mask = (1 << (8 - cnt)) - 1;
1119 res |= (d >> (cnt)) & mask;
1121 /* set the new carry flag, Note that it is the low order
1122 bit of the result!!! */
1123 CONDITIONAL_SET_FLAG(res & 0x80, F_CF);
1124 /* OVERFLOW is set *IFF* s==1, then it is the
1125 xor of the two most significant bits. Blecck. */
1126 CONDITIONAL_SET_FLAG(s == 1 && XOR2(res >> 6), F_OF);
1127 } else if (s != 0) {
1128 /* set the new carry flag, Note that it is the low order
1129 bit of the result!!! */
1130 CONDITIONAL_SET_FLAG(res & 0x80, F_CF);
1135 /****************************************************************************
1137 Implements the ROR instruction and side effects.
1138 ****************************************************************************/
1139 u16 ror_word(u16 d, u8 s)
1141 unsigned int res, cnt, mask;
1144 if ((cnt = s % 16) != 0) {
1145 res = (d << (16 - cnt));
1146 mask = (1 << (16 - cnt)) - 1;
1147 res |= (d >> (cnt)) & mask;
1148 CONDITIONAL_SET_FLAG(res & 0x8000, F_CF);
1149 CONDITIONAL_SET_FLAG(s == 1 && XOR2(res >> 14), F_OF);
1150 } else if (s != 0) {
1151 /* set the new carry flag, Note that it is the low order
1152 bit of the result!!! */
1153 CONDITIONAL_SET_FLAG(res & 0x8000, F_CF);
1158 /****************************************************************************
1160 Implements the ROR instruction and side effects.
1161 ****************************************************************************/
1162 u32 ror_long(u32 d, u8 s)
1167 if ((cnt = s % 32) != 0) {
1168 res = (d << (32 - cnt));
1169 mask = (1 << (32 - cnt)) - 1;
1170 res |= (d >> (cnt)) & mask;
1171 CONDITIONAL_SET_FLAG(res & 0x80000000, F_CF);
1172 CONDITIONAL_SET_FLAG(s == 1 && XOR2(res >> 30), F_OF);
1173 } else if (s != 0) {
1174 /* set the new carry flag, Note that it is the low order
1175 bit of the result!!! */
1176 CONDITIONAL_SET_FLAG(res & 0x80000000, F_CF);
1181 /****************************************************************************
1183 Implements the SHL instruction and side effects.
1184 ****************************************************************************/
1185 u8 shl_byte(u8 d, u8 s)
1187 unsigned int cnt, res, cf;
1192 /* last bit shifted out goes into carry flag */
1195 cf = d & (1 << (8 - cnt));
1196 CONDITIONAL_SET_FLAG(cf, F_CF);
1197 set_szp_flags_8((u8)res);
1203 /* Needs simplification. */
1204 CONDITIONAL_SET_FLAG(
1205 (((res & 0x80) == 0x80) ^
1206 (ACCESS_FLAG(F_CF) != 0)),
1207 /* was (M.x86.R_FLG&F_CF)==F_CF)), */
1214 CONDITIONAL_SET_FLAG((d << (s-1)) & 0x80, F_CF);
1223 /****************************************************************************
1225 Implements the SHL instruction and side effects.
1226 ****************************************************************************/
1227 u16 shl_word(u16 d, u8 s)
1229 unsigned int cnt, res, cf;
1235 cf = d & (1 << (16 - cnt));
1236 CONDITIONAL_SET_FLAG(cf, F_CF);
1237 set_szp_flags_16((u16)res);
1243 CONDITIONAL_SET_FLAG(
1244 (((res & 0x8000) == 0x8000) ^
1245 (ACCESS_FLAG(F_CF) != 0)),
1252 CONDITIONAL_SET_FLAG((d << (s-1)) & 0x8000, F_CF);
1261 /****************************************************************************
1263 Implements the SHL instruction and side effects.
1264 ****************************************************************************/
1265 u32 shl_long(u32 d, u8 s)
1267 unsigned int cnt, res, cf;
1273 cf = d & (1 << (32 - cnt));
1274 CONDITIONAL_SET_FLAG(cf, F_CF);
1275 set_szp_flags_32((u32)res);
1280 CONDITIONAL_SET_FLAG((((res & 0x80000000) == 0x80000000) ^
1281 (ACCESS_FLAG(F_CF) != 0)), F_OF);
1287 CONDITIONAL_SET_FLAG((d << (s-1)) & 0x80000000, F_CF);
1296 /****************************************************************************
1298 Implements the SHR instruction and side effects.
1299 ****************************************************************************/
1300 u8 shr_byte(u8 d, u8 s)
1302 unsigned int cnt, res, cf;
1307 cf = d & (1 << (cnt - 1));
1309 CONDITIONAL_SET_FLAG(cf, F_CF);
1310 set_szp_flags_8((u8)res);
1316 CONDITIONAL_SET_FLAG(XOR2(res >> 6), F_OF);
1322 CONDITIONAL_SET_FLAG((d >> (s-1)) & 0x1, F_CF);
1331 /****************************************************************************
1333 Implements the SHR instruction and side effects.
1334 ****************************************************************************/
1335 u16 shr_word(u16 d, u8 s)
1337 unsigned int cnt, res, cf;
1342 cf = d & (1 << (cnt - 1));
1344 CONDITIONAL_SET_FLAG(cf, F_CF);
1345 set_szp_flags_16((u16)res);
1351 CONDITIONAL_SET_FLAG(XOR2(res >> 14), F_OF);
1366 /****************************************************************************
1368 Implements the SHR instruction and side effects.
1369 ****************************************************************************/
1370 u32 shr_long(u32 d, u8 s)
1372 unsigned int cnt, res, cf;
1377 cf = d & (1 << (cnt - 1));
1379 CONDITIONAL_SET_FLAG(cf, F_CF);
1380 set_szp_flags_32((u32)res);
1385 CONDITIONAL_SET_FLAG(XOR2(res >> 30), F_OF);
1400 /****************************************************************************
1402 Implements the SAR instruction and side effects.
1403 ****************************************************************************/
1404 u8 sar_byte(u8 d, u8 s)
1406 unsigned int cnt, res, cf, mask, sf;
1411 if (cnt > 0 && cnt < 8) {
1412 mask = (1 << (8 - cnt)) - 1;
1413 cf = d & (1 << (cnt - 1));
1414 res = (d >> cnt) & mask;
1415 CONDITIONAL_SET_FLAG(cf, F_CF);
1419 set_szp_flags_8((u8)res);
1420 } else if (cnt >= 8) {
1438 /****************************************************************************
1440 Implements the SAR instruction and side effects.
1441 ****************************************************************************/
1442 u16 sar_word(u16 d, u8 s)
1444 unsigned int cnt, res, cf, mask, sf;
1449 if (cnt > 0 && cnt < 16) {
1450 mask = (1 << (16 - cnt)) - 1;
1451 cf = d & (1 << (cnt - 1));
1452 res = (d >> cnt) & mask;
1453 CONDITIONAL_SET_FLAG(cf, F_CF);
1457 set_szp_flags_16((u16)res);
1458 } else if (cnt >= 16) {
1476 /****************************************************************************
1478 Implements the SAR instruction and side effects.
1479 ****************************************************************************/
1480 u32 sar_long(u32 d, u8 s)
1482 u32 cnt, res, cf, mask, sf;
1484 sf = d & 0x80000000;
1487 if (cnt > 0 && cnt < 32) {
1488 mask = (1 << (32 - cnt)) - 1;
1489 cf = d & (1 << (cnt - 1));
1490 res = (d >> cnt) & mask;
1491 CONDITIONAL_SET_FLAG(cf, F_CF);
1495 set_szp_flags_32(res);
1496 } else if (cnt >= 32) {
1514 /****************************************************************************
1516 Implements the SHLD instruction and side effects.
1517 ****************************************************************************/
1518 u16 shld_word (u16 d, u16 fill, u8 s)
1520 unsigned int cnt, res, cf;
1525 res = (d << cnt) | (fill >> (16-cnt));
1526 cf = d & (1 << (16 - cnt));
1527 CONDITIONAL_SET_FLAG(cf, F_CF);
1528 set_szp_flags_16((u16)res);
1533 CONDITIONAL_SET_FLAG((((res & 0x8000) == 0x8000) ^
1534 (ACCESS_FLAG(F_CF) != 0)), F_OF);
1540 CONDITIONAL_SET_FLAG((d << (s-1)) & 0x8000, F_CF);
1549 /****************************************************************************
1551 Implements the SHLD instruction and side effects.
1552 ****************************************************************************/
1553 u32 shld_long (u32 d, u32 fill, u8 s)
1555 unsigned int cnt, res, cf;
1560 res = (d << cnt) | (fill >> (32-cnt));
1561 cf = d & (1 << (32 - cnt));
1562 CONDITIONAL_SET_FLAG(cf, F_CF);
1563 set_szp_flags_32((u32)res);
1568 CONDITIONAL_SET_FLAG((((res & 0x80000000) == 0x80000000) ^
1569 (ACCESS_FLAG(F_CF) != 0)), F_OF);
1575 CONDITIONAL_SET_FLAG((d << (s-1)) & 0x80000000, F_CF);
1584 /****************************************************************************
1586 Implements the SHRD instruction and side effects.
1587 ****************************************************************************/
1588 u16 shrd_word (u16 d, u16 fill, u8 s)
1590 unsigned int cnt, res, cf;
1595 cf = d & (1 << (cnt - 1));
1596 res = (d >> cnt) | (fill << (16 - cnt));
1597 CONDITIONAL_SET_FLAG(cf, F_CF);
1598 set_szp_flags_16((u16)res);
1604 CONDITIONAL_SET_FLAG(XOR2(res >> 14), F_OF);
1619 /****************************************************************************
1621 Implements the SHRD instruction and side effects.
1622 ****************************************************************************/
1623 u32 shrd_long (u32 d, u32 fill, u8 s)
1625 unsigned int cnt, res, cf;
1630 cf = d & (1 << (cnt - 1));
1631 res = (d >> cnt) | (fill << (32 - cnt));
1632 CONDITIONAL_SET_FLAG(cf, F_CF);
1633 set_szp_flags_32((u32)res);
1638 CONDITIONAL_SET_FLAG(XOR2(res >> 30), F_OF);
1653 /****************************************************************************
1655 Implements the SBB instruction and side effects.
1656 ****************************************************************************/
1657 u8 sbb_byte(u8 d, u8 s)
1659 u32 res; /* all operands in native machine order */
1662 if (ACCESS_FLAG(F_CF))
1666 set_szp_flags_8((u8)res);
1668 /* calculate the borrow chain. See note at top */
1669 bc = (res & (~d | s)) | (~d & s);
1670 CONDITIONAL_SET_FLAG(bc & 0x80, F_CF);
1671 CONDITIONAL_SET_FLAG(XOR2(bc >> 6), F_OF);
1672 CONDITIONAL_SET_FLAG(bc & 0x8, F_AF);
1676 /****************************************************************************
1678 Implements the SBB instruction and side effects.
1679 ****************************************************************************/
1680 u16 sbb_word(u16 d, u16 s)
1682 u32 res; /* all operands in native machine order */
1685 if (ACCESS_FLAG(F_CF))
1689 set_szp_flags_16((u16)res);
1691 /* calculate the borrow chain. See note at top */
1692 bc = (res & (~d | s)) | (~d & s);
1693 CONDITIONAL_SET_FLAG(bc & 0x8000, F_CF);
1694 CONDITIONAL_SET_FLAG(XOR2(bc >> 14), F_OF);
1695 CONDITIONAL_SET_FLAG(bc & 0x8, F_AF);
1699 /****************************************************************************
1701 Implements the SBB instruction and side effects.
1702 ****************************************************************************/
1703 u32 sbb_long(u32 d, u32 s)
1705 u32 res; /* all operands in native machine order */
1708 if (ACCESS_FLAG(F_CF))
1713 set_szp_flags_32(res);
1715 /* calculate the borrow chain. See note at top */
1716 bc = (res & (~d | s)) | (~d & s);
1717 CONDITIONAL_SET_FLAG(bc & 0x80000000, F_CF);
1718 CONDITIONAL_SET_FLAG(XOR2(bc >> 30), F_OF);
1719 CONDITIONAL_SET_FLAG(bc & 0x8, F_AF);
1723 /****************************************************************************
1725 Implements the SUB instruction and side effects.
1726 ****************************************************************************/
1727 u8 sub_byte(u8 d, u8 s)
1729 u32 res; /* all operands in native machine order */
1733 set_szp_flags_8((u8)res);
1735 /* calculate the borrow chain. See note at top */
1736 bc = (res & (~d | s)) | (~d & s);
1737 CONDITIONAL_SET_FLAG(bc & 0x80, F_CF);
1738 CONDITIONAL_SET_FLAG(XOR2(bc >> 6), F_OF);
1739 CONDITIONAL_SET_FLAG(bc & 0x8, F_AF);
1743 /****************************************************************************
1745 Implements the SUB instruction and side effects.
1746 ****************************************************************************/
1747 u16 sub_word(u16 d, u16 s)
1749 u32 res; /* all operands in native machine order */
1753 set_szp_flags_16((u16)res);
1755 /* calculate the borrow chain. See note at top */
1756 bc = (res & (~d | s)) | (~d & s);
1757 CONDITIONAL_SET_FLAG(bc & 0x8000, F_CF);
1758 CONDITIONAL_SET_FLAG(XOR2(bc >> 14), F_OF);
1759 CONDITIONAL_SET_FLAG(bc & 0x8, F_AF);
1763 /****************************************************************************
1765 Implements the SUB instruction and side effects.
1766 ****************************************************************************/
1767 u32 sub_long(u32 d, u32 s)
1769 u32 res; /* all operands in native machine order */
1773 set_szp_flags_32(res);
1775 /* calculate the borrow chain. See note at top */
1776 bc = (res & (~d | s)) | (~d & s);
1777 CONDITIONAL_SET_FLAG(bc & 0x80000000, F_CF);
1778 CONDITIONAL_SET_FLAG(XOR2(bc >> 30), F_OF);
1779 CONDITIONAL_SET_FLAG(bc & 0x8, F_AF);
1783 /****************************************************************************
1785 Implements the TEST instruction and side effects.
1786 ****************************************************************************/
1787 void test_byte(u8 d, u8 s)
1789 u32 res; /* all operands in native machine order */
1794 set_szp_flags_8((u8)res);
1795 /* AF == dont care */
1799 /****************************************************************************
1801 Implements the TEST instruction and side effects.
1802 ****************************************************************************/
1803 void test_word(u16 d, u16 s)
1805 u32 res; /* all operands in native machine order */
1810 set_szp_flags_16((u16)res);
1811 /* AF == dont care */
1815 /****************************************************************************
1817 Implements the TEST instruction and side effects.
1818 ****************************************************************************/
1819 void test_long(u32 d, u32 s)
1821 u32 res; /* all operands in native machine order */
1826 set_szp_flags_32(res);
1827 /* AF == dont care */
1831 /****************************************************************************
1833 Implements the XOR instruction and side effects.
1834 ****************************************************************************/
1835 u8 xor_byte(u8 d, u8 s)
1837 u8 res; /* all operands in native machine order */
1840 no_carry_byte_side_eff(res);
1844 /****************************************************************************
1846 Implements the XOR instruction and side effects.
1847 ****************************************************************************/
1848 u16 xor_word(u16 d, u16 s)
1850 u16 res; /* all operands in native machine order */
1853 no_carry_word_side_eff(res);
1857 /****************************************************************************
1859 Implements the XOR instruction and side effects.
1860 ****************************************************************************/
1861 u32 xor_long(u32 d, u32 s)
1863 u32 res; /* all operands in native machine order */
1866 no_carry_long_side_eff(res);
1870 /****************************************************************************
1872 Implements the IMUL instruction and side effects.
1873 ****************************************************************************/
1874 void imul_byte(u8 s)
1876 s16 res = (s16)((s8)M.x86.R_AL * (s8)s);
1879 if (((M.x86.R_AL & 0x80) == 0 && M.x86.R_AH == 0x00) ||
1880 ((M.x86.R_AL & 0x80) != 0 && M.x86.R_AH == 0xFF)) {
1889 /****************************************************************************
1891 Implements the IMUL instruction and side effects.
1892 ****************************************************************************/
1893 void imul_word(u16 s)
1895 s32 res = (s16)M.x86.R_AX * (s16)s;
1897 M.x86.R_AX = (u16)res;
1898 M.x86.R_DX = (u16)(res >> 16);
1899 if (((M.x86.R_AX & 0x8000) == 0 && M.x86.R_DX == 0x0000) ||
1900 ((M.x86.R_AX & 0x8000) != 0 && M.x86.R_DX == 0xFFFF)) {
1909 /****************************************************************************
1911 Implements the IMUL instruction and side effects.
1912 ****************************************************************************/
1913 void imul_long_direct(u32 *res_lo, u32* res_hi,u32 d, u32 s)
1915 #ifdef __HAS_LONG_LONG__
1916 s64 res = (s32)d * (s32)s;
1919 *res_hi = (u32)(res >> 32);
1921 u32 d_lo,d_hi,d_sign;
1922 u32 s_lo,s_hi,s_sign;
1923 u32 rlo_lo,rlo_hi,rhi_lo;
1925 if ((d_sign = d & 0x80000000) != 0)
1929 if ((s_sign = s & 0x80000000) != 0)
1933 rlo_lo = d_lo * s_lo;
1934 rlo_hi = (d_hi * s_lo + d_lo * s_hi) + (rlo_lo >> 16);
1935 rhi_lo = d_hi * s_hi + (rlo_hi >> 16);
1936 *res_lo = (rlo_hi << 16) | (rlo_lo & 0xFFFF);
1938 if (d_sign != s_sign) {
1940 s = (((d & 0xFFFF) + 1) >> 16) + (d >> 16);
1941 *res_lo = ~*res_lo+1;
1942 *res_hi = ~*res_hi+(s >> 16);
1947 /****************************************************************************
1949 Implements the IMUL instruction and side effects.
1950 ****************************************************************************/
1951 void imul_long(u32 s)
1953 imul_long_direct(&M.x86.R_EAX,&M.x86.R_EDX,M.x86.R_EAX,s);
1954 if (((M.x86.R_EAX & 0x80000000) == 0 && M.x86.R_EDX == 0x00000000) ||
1955 ((M.x86.R_EAX & 0x80000000) != 0 && M.x86.R_EDX == 0xFFFFFFFF)) {
1964 /****************************************************************************
1966 Implements the MUL instruction and side effects.
1967 ****************************************************************************/
1970 u16 res = (u16)(M.x86.R_AL * s);
1973 if (M.x86.R_AH == 0) {
1982 /****************************************************************************
1984 Implements the MUL instruction and side effects.
1985 ****************************************************************************/
1986 void mul_word(u16 s)
1988 u32 res = M.x86.R_AX * s;
1990 M.x86.R_AX = (u16)res;
1991 M.x86.R_DX = (u16)(res >> 16);
1992 if (M.x86.R_DX == 0) {
2001 /****************************************************************************
2003 Implements the MUL instruction and side effects.
2004 ****************************************************************************/
2005 void mul_long(u32 s)
2007 #ifdef __HAS_LONG_LONG__
2008 u64 res = (u32)M.x86.R_EAX * (u32)s;
2010 M.x86.R_EAX = (u32)res;
2011 M.x86.R_EDX = (u32)(res >> 32);
2015 u32 rlo_lo,rlo_hi,rhi_lo;
2022 rlo_lo = a_lo * s_lo;
2023 rlo_hi = (a_hi * s_lo + a_lo * s_hi) + (rlo_lo >> 16);
2024 rhi_lo = a_hi * s_hi + (rlo_hi >> 16);
2025 M.x86.R_EAX = (rlo_hi << 16) | (rlo_lo & 0xFFFF);
2026 M.x86.R_EDX = rhi_lo;
2028 if (M.x86.R_EDX == 0) {
2037 /****************************************************************************
2039 Implements the IDIV instruction and side effects.
2040 ****************************************************************************/
2041 void idiv_byte(u8 s)
2045 dvd = (s16)M.x86.R_AX;
2047 x86emu_intr_raise(0);
2052 if (abs(div) > 0x7f) {
2053 x86emu_intr_raise(0);
2056 M.x86.R_AL = (s8) div;
2057 M.x86.R_AH = (s8) mod;
2060 /****************************************************************************
2062 Implements the IDIV instruction and side effects.
2063 ****************************************************************************/
2064 void idiv_word(u16 s)
2068 dvd = (((s32)M.x86.R_DX) << 16) | M.x86.R_AX;
2070 x86emu_intr_raise(0);
2075 if (abs(div) > 0x7fff) {
2076 x86emu_intr_raise(0);
2081 CONDITIONAL_SET_FLAG(div == 0, F_ZF);
2082 set_parity_flag(mod);
2084 M.x86.R_AX = (u16)div;
2085 M.x86.R_DX = (u16)mod;
2088 /****************************************************************************
2090 Implements the IDIV instruction and side effects.
2091 ****************************************************************************/
2092 void idiv_long(u32 s)
2094 #ifdef __HAS_LONG_LONG__
2097 dvd = (((s64)M.x86.R_EDX) << 32) | M.x86.R_EAX;
2099 x86emu_intr_raise(0);
2104 if (abs(div) > 0x7fffffff) {
2105 x86emu_intr_raise(0);
2110 s32 h_dvd = M.x86.R_EDX;
2111 u32 l_dvd = M.x86.R_EAX;
2112 u32 abs_s = s & 0x7FFFFFFF;
2113 u32 abs_h_dvd = h_dvd & 0x7FFFFFFF;
2114 u32 h_s = abs_s >> 1;
2115 u32 l_s = abs_s << 31;
2120 x86emu_intr_raise(0);
2125 carry = (l_dvd >= l_s) ? 0 : 1;
2127 if (abs_h_dvd < (h_s + carry)) {
2129 l_s = abs_s << (--counter);
2132 abs_h_dvd -= (h_s + carry);
2133 l_dvd = carry ? ((0xFFFFFFFF - l_s) + l_dvd + 1)
2136 l_s = abs_s << (--counter);
2141 } while (counter > -1);
2143 if (abs_h_dvd || (l_dvd > abs_s)) {
2144 x86emu_intr_raise(0);
2148 div |= ((h_dvd & 0x10000000) ^ (s & 0x10000000));
2156 set_parity_flag(mod);
2158 M.x86.R_EAX = (u32)div;
2159 M.x86.R_EDX = (u32)mod;
2162 /****************************************************************************
2164 Implements the DIV instruction and side effects.
2165 ****************************************************************************/
2172 x86emu_intr_raise(0);
2177 if (abs(div) > 0xff) {
2178 x86emu_intr_raise(0);
2181 M.x86.R_AL = (u8)div;
2182 M.x86.R_AH = (u8)mod;
2185 /****************************************************************************
2187 Implements the DIV instruction and side effects.
2188 ****************************************************************************/
2189 void div_word(u16 s)
2193 dvd = (((u32)M.x86.R_DX) << 16) | M.x86.R_AX;
2195 x86emu_intr_raise(0);
2200 if (abs(div) > 0xffff) {
2201 x86emu_intr_raise(0);
2206 CONDITIONAL_SET_FLAG(div == 0, F_ZF);
2207 set_parity_flag(mod);
2209 M.x86.R_AX = (u16)div;
2210 M.x86.R_DX = (u16)mod;
2213 /****************************************************************************
2215 Implements the DIV instruction and side effects.
2216 ****************************************************************************/
2217 void div_long(u32 s)
2219 #ifdef __HAS_LONG_LONG__
2222 dvd = (((u64)M.x86.R_EDX) << 32) | M.x86.R_EAX;
2224 x86emu_intr_raise(0);
2229 if (abs(div) > 0xffffffff) {
2230 x86emu_intr_raise(0);
2235 s32 h_dvd = M.x86.R_EDX;
2236 u32 l_dvd = M.x86.R_EAX;
2244 x86emu_intr_raise(0);
2249 carry = (l_dvd >= l_s) ? 0 : 1;
2251 if (h_dvd < (h_s + carry)) {
2253 l_s = s << (--counter);
2256 h_dvd -= (h_s + carry);
2257 l_dvd = carry ? ((0xFFFFFFFF - l_s) + l_dvd + 1)
2260 l_s = s << (--counter);
2265 } while (counter > -1);
2267 if (h_dvd || (l_dvd > s)) {
2268 x86emu_intr_raise(0);
2277 set_parity_flag(mod);
2279 M.x86.R_EAX = (u32)div;
2280 M.x86.R_EDX = (u32)mod;
2283 /****************************************************************************
2285 Implements the IN string instruction and side effects.
2286 ****************************************************************************/
2288 static void single_in(int size)
2291 store_data_byte_abs(M.x86.R_ES, M.x86.R_DI,(*sys_inb)(M.x86.R_DX));
2293 store_data_word_abs(M.x86.R_ES, M.x86.R_DI,(*sys_inw)(M.x86.R_DX));
2295 store_data_long_abs(M.x86.R_ES, M.x86.R_DI,(*sys_inl)(M.x86.R_DX));
2302 if (ACCESS_FLAG(F_DF)) {
2305 if (M.x86.mode & (SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE)) {
2306 /* dont care whether REPE or REPNE */
2307 /* in until CX is ZERO. */
2308 u32 count = ((M.x86.mode & SYSMODE_PREFIX_DATA) ?
2309 M.x86.R_ECX : M.x86.R_CX);
2316 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2319 M.x86.mode &= ~(SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE);
2326 /****************************************************************************
2328 Implements the OUT string instruction and side effects.
2329 ****************************************************************************/
2331 static void single_out(int size)
2334 (*sys_outb)(M.x86.R_DX,fetch_data_byte_abs(M.x86.R_ES, M.x86.R_SI));
2336 (*sys_outw)(M.x86.R_DX,fetch_data_word_abs(M.x86.R_ES, M.x86.R_SI));
2338 (*sys_outl)(M.x86.R_DX,fetch_data_long_abs(M.x86.R_ES, M.x86.R_SI));
2345 if (ACCESS_FLAG(F_DF)) {
2348 if (M.x86.mode & (SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE)) {
2349 /* dont care whether REPE or REPNE */
2350 /* out until CX is ZERO. */
2351 u32 count = ((M.x86.mode & SYSMODE_PREFIX_DATA) ?
2352 M.x86.R_ECX : M.x86.R_CX);
2358 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2361 M.x86.mode &= ~(SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE);
2368 /****************************************************************************
2370 addr - Address to fetch word from
2373 Fetches a word from emulator memory using an absolute address.
2374 ****************************************************************************/
2375 u16 mem_access_word(int addr)
2377 DB( if (CHECK_MEM_ACCESS())
2378 x86emu_check_mem_access(addr);)
2379 return (*sys_rdw)(addr);
2382 /****************************************************************************
2384 Pushes a word onto the stack.
2386 NOTE: Do not inline this, as (*sys_wrX) is already inline!
2387 ****************************************************************************/
2388 void push_word(u16 w)
2390 DB( if (CHECK_SP_ACCESS())
2391 x86emu_check_sp_access();)
2393 (*sys_wrw)(((u32)M.x86.R_SS << 4) + M.x86.R_SP, w);
2396 /****************************************************************************
2398 Pushes a long onto the stack.
2400 NOTE: Do not inline this, as (*sys_wrX) is already inline!
2401 ****************************************************************************/
2402 void push_long(u32 w)
2404 DB( if (CHECK_SP_ACCESS())
2405 x86emu_check_sp_access();)
2407 (*sys_wrl)(((u32)M.x86.R_SS << 4) + M.x86.R_SP, w);
2410 /****************************************************************************
2412 Pops a word from the stack.
2414 NOTE: Do not inline this, as (*sys_rdX) is already inline!
2415 ****************************************************************************/
2420 DB( if (CHECK_SP_ACCESS())
2421 x86emu_check_sp_access();)
2422 res = (*sys_rdw)(((u32)M.x86.R_SS << 4) + M.x86.R_SP);
2427 /****************************************************************************
2429 Pops a long from the stack.
2431 NOTE: Do not inline this, as (*sys_rdX) is already inline!
2432 ****************************************************************************/
2437 DB( if (CHECK_SP_ACCESS())
2438 x86emu_check_sp_access();)
2439 res = (*sys_rdl)(((u32)M.x86.R_SS << 4) + M.x86.R_SP);