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
102 #if defined(CONFIG_BIOSEMU)
104 #include "x86emu/x86emui.h"
106 /*------------------------- Global Variables ------------------------------*/
108 static u32 x86emu_parity_tab[8] =
120 #define PARITY(x) (((x86emu_parity_tab[(x) / 32] >> ((x) % 32)) & 1) == 0)
121 #define XOR2(x) (((x) ^ ((x)>>1)) & 0x1)
122 /*----------------------------- Implementation ----------------------------*/
128 /*----------------------------- Implementation ----------------------------*/
131 /*--------- Side effects helper functions -------*/
133 /****************************************************************************
135 implements side efects for byte operations that don't overflow
136 ****************************************************************************/
138 static void set_parity_flag(u32 res)
140 CONDITIONAL_SET_FLAG(PARITY(res & 0xFF), F_PF);
143 static void set_szp_flags_8(u8 res)
145 CONDITIONAL_SET_FLAG(res & 0x80, F_SF);
146 CONDITIONAL_SET_FLAG(res == 0, F_ZF);
147 set_parity_flag(res);
150 static void set_szp_flags_16(u16 res)
152 CONDITIONAL_SET_FLAG(res & 0x8000, F_SF);
153 CONDITIONAL_SET_FLAG(res == 0, F_ZF);
154 set_parity_flag(res);
157 static void set_szp_flags_32(u32 res)
159 CONDITIONAL_SET_FLAG(res & 0x80000000, F_SF);
160 CONDITIONAL_SET_FLAG(res == 0, F_ZF);
161 set_parity_flag(res);
164 static void no_carry_byte_side_eff(u8 res)
169 set_szp_flags_8(res);
172 static void no_carry_word_side_eff(u16 res)
177 set_szp_flags_16(res);
180 static void no_carry_long_side_eff(u32 res)
185 set_szp_flags_32(res);
188 static void calc_carry_chain(int bits, u32 d, u32 s, u32 res, int set_carry)
192 cc = (s & d) | ((~res) & (s | d));
193 CONDITIONAL_SET_FLAG(XOR2(cc >> (bits - 2)), F_OF);
194 CONDITIONAL_SET_FLAG(cc & 0x8, F_AF);
196 CONDITIONAL_SET_FLAG(res & (1 << bits), F_CF);
200 static void calc_borrow_chain(int bits, u32 d, u32 s, u32 res, int set_carry)
204 bc = (res & (~d | s)) | (~d & s);
205 CONDITIONAL_SET_FLAG(XOR2(bc >> (bits - 2)), F_OF);
206 CONDITIONAL_SET_FLAG(bc & 0x8, F_AF);
208 CONDITIONAL_SET_FLAG(bc & (1 << (bits - 1)), F_CF);
212 /****************************************************************************
214 Implements the AAA instruction and side effects.
215 ****************************************************************************/
219 if ((d & 0xf) > 0x9 || ACCESS_FLAG(F_AF)) {
228 res = (u16)(d & 0xFF0F);
229 set_szp_flags_16(res);
233 /****************************************************************************
235 Implements the AAA instruction and side effects.
236 ****************************************************************************/
240 if ((d & 0xf) > 0x9 || ACCESS_FLAG(F_AF)) {
249 res = (u16)(d & 0xFF0F);
250 set_szp_flags_16(res);
254 /****************************************************************************
256 Implements the AAD instruction and side effects.
257 ****************************************************************************/
263 hb = (u8)((d >> 8) & 0xff);
264 lb = (u8)((d & 0xff));
265 l = (u16)((lb + 10 * hb) & 0xFF);
267 no_carry_byte_side_eff(l & 0xFF);
271 /****************************************************************************
273 Implements the AAM instruction and side effects.
274 ****************************************************************************/
283 no_carry_byte_side_eff(l & 0xFF);
287 /****************************************************************************
289 Implements the ADC instruction and side effects.
290 ****************************************************************************/
291 u8 adc_byte(u8 d, u8 s)
293 u32 res; /* all operands in native machine order */
296 if (ACCESS_FLAG(F_CF)) res++;
298 set_szp_flags_8(res);
299 calc_carry_chain(8,s,d,res,1);
304 /****************************************************************************
306 Implements the ADC instruction and side effects.
307 ****************************************************************************/
308 u16 adc_word(u16 d, u16 s)
310 u32 res; /* all operands in native machine order */
313 if (ACCESS_FLAG(F_CF))
316 set_szp_flags_16((u16)res);
317 calc_carry_chain(16,s,d,res,1);
322 /****************************************************************************
324 Implements the ADC instruction and side effects.
325 ****************************************************************************/
326 u32 adc_long(u32 d, u32 s)
328 u32 lo; /* all operands in native machine order */
332 lo = (d & 0xFFFF) + (s & 0xFFFF);
335 if (ACCESS_FLAG(F_CF)) {
340 hi = (lo >> 16) + (d >> 16) + (s >> 16);
342 set_szp_flags_32(res);
343 calc_carry_chain(32,s,d,res,0);
345 CONDITIONAL_SET_FLAG(hi & 0x10000, F_CF);
350 /****************************************************************************
352 Implements the ADD instruction and side effects.
353 ****************************************************************************/
354 u8 add_byte(u8 d, u8 s)
356 u32 res; /* all operands in native machine order */
359 set_szp_flags_8((u8)res);
360 calc_carry_chain(8,s,d,res,1);
365 /****************************************************************************
367 Implements the ADD instruction and side effects.
368 ****************************************************************************/
369 u16 add_word(u16 d, u16 s)
371 u32 res; /* all operands in native machine order */
374 set_szp_flags_16((u16)res);
375 calc_carry_chain(16,s,d,res,1);
380 /****************************************************************************
382 Implements the ADD instruction and side effects.
383 ****************************************************************************/
384 u32 add_long(u32 d, u32 s)
389 set_szp_flags_32(res);
390 calc_carry_chain(32,s,d,res,0);
392 CONDITIONAL_SET_FLAG(res < d || res < s, F_CF);
397 /****************************************************************************
399 Implements the AND instruction and side effects.
400 ****************************************************************************/
401 u8 and_byte(u8 d, u8 s)
403 u8 res; /* all operands in native machine order */
407 no_carry_byte_side_eff(res);
411 /****************************************************************************
413 Implements the AND instruction and side effects.
414 ****************************************************************************/
415 u16 and_word(u16 d, u16 s)
417 u16 res; /* all operands in native machine order */
421 no_carry_word_side_eff(res);
425 /****************************************************************************
427 Implements the AND instruction and side effects.
428 ****************************************************************************/
429 u32 and_long(u32 d, u32 s)
431 u32 res; /* all operands in native machine order */
434 no_carry_long_side_eff(res);
438 /****************************************************************************
440 Implements the CMP instruction and side effects.
441 ****************************************************************************/
442 u8 cmp_byte(u8 d, u8 s)
444 u32 res; /* all operands in native machine order */
447 set_szp_flags_8((u8)res);
448 calc_borrow_chain(8, d, s, res, 1);
453 /****************************************************************************
455 Implements the CMP instruction and side effects.
456 ****************************************************************************/
457 u16 cmp_word(u16 d, u16 s)
459 u32 res; /* all operands in native machine order */
462 set_szp_flags_16((u16)res);
463 calc_borrow_chain(16, d, s, res, 1);
468 /****************************************************************************
470 Implements the CMP instruction and side effects.
471 ****************************************************************************/
472 u32 cmp_long(u32 d, u32 s)
474 u32 res; /* all operands in native machine order */
477 set_szp_flags_32(res);
478 calc_borrow_chain(32, d, s, res, 1);
483 /****************************************************************************
485 Implements the DAA instruction and side effects.
486 ****************************************************************************/
490 if ((d & 0xf) > 9 || ACCESS_FLAG(F_AF)) {
494 if (res > 0x9F || ACCESS_FLAG(F_CF)) {
498 set_szp_flags_8((u8)res);
502 /****************************************************************************
504 Implements the DAS instruction and side effects.
505 ****************************************************************************/
508 if ((d & 0xf) > 9 || ACCESS_FLAG(F_AF)) {
512 if (d > 0x9F || ACCESS_FLAG(F_CF)) {
520 /****************************************************************************
522 Implements the DEC instruction and side effects.
523 ****************************************************************************/
526 u32 res; /* all operands in native machine order */
529 set_szp_flags_8((u8)res);
530 calc_borrow_chain(8, d, 1, res, 0);
535 /****************************************************************************
537 Implements the DEC instruction and side effects.
538 ****************************************************************************/
541 u32 res; /* all operands in native machine order */
544 set_szp_flags_16((u16)res);
545 calc_borrow_chain(16, d, 1, res, 0);
550 /****************************************************************************
552 Implements the DEC instruction and side effects.
553 ****************************************************************************/
556 u32 res; /* all operands in native machine order */
560 set_szp_flags_32(res);
561 calc_borrow_chain(32, d, 1, res, 0);
566 /****************************************************************************
568 Implements the INC instruction and side effects.
569 ****************************************************************************/
572 u32 res; /* all operands in native machine order */
575 set_szp_flags_8((u8)res);
576 calc_carry_chain(8, d, 1, res, 0);
581 /****************************************************************************
583 Implements the INC instruction and side effects.
584 ****************************************************************************/
587 u32 res; /* all operands in native machine order */
590 set_szp_flags_16((u16)res);
591 calc_carry_chain(16, d, 1, res, 0);
596 /****************************************************************************
598 Implements the INC instruction and side effects.
599 ****************************************************************************/
602 u32 res; /* all operands in native machine order */
605 set_szp_flags_32(res);
606 calc_carry_chain(32, d, 1, res, 0);
611 /****************************************************************************
613 Implements the OR instruction and side effects.
614 ****************************************************************************/
615 u8 or_byte(u8 d, u8 s)
617 u8 res; /* all operands in native machine order */
620 no_carry_byte_side_eff(res);
625 /****************************************************************************
627 Implements the OR instruction and side effects.
628 ****************************************************************************/
629 u16 or_word(u16 d, u16 s)
631 u16 res; /* all operands in native machine order */
634 no_carry_word_side_eff(res);
638 /****************************************************************************
640 Implements the OR instruction and side effects.
641 ****************************************************************************/
642 u32 or_long(u32 d, u32 s)
644 u32 res; /* all operands in native machine order */
647 no_carry_long_side_eff(res);
651 /****************************************************************************
653 Implements the OR instruction and side effects.
654 ****************************************************************************/
659 CONDITIONAL_SET_FLAG(s != 0, F_CF);
661 set_szp_flags_8(res);
662 calc_borrow_chain(8, 0, s, res, 0);
667 /****************************************************************************
669 Implements the OR instruction and side effects.
670 ****************************************************************************/
675 CONDITIONAL_SET_FLAG(s != 0, F_CF);
677 set_szp_flags_16((u16)res);
678 calc_borrow_chain(16, 0, s, res, 0);
683 /****************************************************************************
685 Implements the OR instruction and side effects.
686 ****************************************************************************/
691 CONDITIONAL_SET_FLAG(s != 0, F_CF);
693 set_szp_flags_32(res);
694 calc_borrow_chain(32, 0, s, res, 0);
699 /****************************************************************************
701 Implements the NOT instruction and side effects.
702 ****************************************************************************/
708 /****************************************************************************
710 Implements the NOT instruction and side effects.
711 ****************************************************************************/
717 /****************************************************************************
719 Implements the NOT instruction and side effects.
720 ****************************************************************************/
726 /****************************************************************************
728 Implements the RCL instruction and side effects.
729 ****************************************************************************/
730 u8 rcl_byte(u8 d, u8 s)
732 unsigned int res, cnt, mask, cf;
734 /* s is the rotate distance. It varies from 0 - 8. */
737 CF B_7 B_6 B_5 B_4 B_3 B_2 B_1 B_0
739 want to rotate through the carry by "s" bits. We could
740 loop, but that's inefficient. So the width is 9,
741 and we split into three parts:
743 The new carry flag (was B_n)
744 the stuff in B_n-1 .. B_0
745 the stuff in B_7 .. B_n+1
747 The new rotate is done mod 9, and given this,
748 for a rotation of n bits (mod 9) the new carry flag is
749 then located n bits from the MSB. The low part is
750 then shifted up cnt bits, and the high part is or'd
751 in. Using CAPS for new values, and lowercase for the
752 original values, this can be expressed as:
756 2) B_(7) .. B_(n) <- b_(8-(n+1)) .. b_0
758 4) B_(n-2) .. B_0 <- b_7 .. b_(8-(n-1))
761 if ((cnt = s % 9) != 0) {
762 /* extract the new CARRY FLAG. */
764 cf = (d >> (8 - cnt)) & 0x1;
766 /* get the low stuff which rotated
767 into the range B_7 .. B_cnt */
768 /* B_(7) .. B_(n) <- b_(8-(n+1)) .. b_0 */
769 /* note that the right hand side done by the mask */
770 res = (d << cnt) & 0xff;
772 /* now the high stuff which rotated around
773 into the positions B_cnt-2 .. B_0 */
774 /* B_(n-2) .. B_0 <- b_7 .. b_(8-(n-1)) */
775 /* shift it downward, 7-(n-2) = 9-n positions.
776 and mask off the result before or'ing in.
778 mask = (1 << (cnt - 1)) - 1;
779 res |= (d >> (9 - cnt)) & mask;
781 /* if the carry flag was set, or it in. */
782 if (ACCESS_FLAG(F_CF)) { /* carry flag is set */
784 res |= 1 << (cnt - 1);
786 /* set the new carry flag, based on the variable "cf" */
787 CONDITIONAL_SET_FLAG(cf, F_CF);
788 /* OVERFLOW is set *IFF* cnt==1, then it is the
789 xor of CF and the most significant bit. Blecck. */
790 /* parenthesized this expression since it appears to
791 be causing OF to be misset */
792 CONDITIONAL_SET_FLAG(cnt == 1 && XOR2(cf + ((res >> 6) & 0x2)),
799 /****************************************************************************
801 Implements the RCL instruction and side effects.
802 ****************************************************************************/
803 u16 rcl_word(u16 d, u8 s)
805 unsigned int res, cnt, mask, cf;
808 if ((cnt = s % 17) != 0) {
809 cf = (d >> (16 - cnt)) & 0x1;
810 res = (d << cnt) & 0xffff;
811 mask = (1 << (cnt - 1)) - 1;
812 res |= (d >> (17 - cnt)) & mask;
813 if (ACCESS_FLAG(F_CF)) {
814 res |= 1 << (cnt - 1);
816 CONDITIONAL_SET_FLAG(cf, F_CF);
817 CONDITIONAL_SET_FLAG(cnt == 1 && XOR2(cf + ((res >> 14) & 0x2)),
823 /****************************************************************************
825 Implements the RCL instruction and side effects.
826 ****************************************************************************/
827 u32 rcl_long(u32 d, u8 s)
829 u32 res, cnt, mask, cf;
832 if ((cnt = s % 33) != 0) {
833 cf = (d >> (32 - cnt)) & 0x1;
834 res = (d << cnt) & 0xffffffff;
835 mask = (1 << (cnt - 1)) - 1;
836 res |= (d >> (33 - cnt)) & mask;
837 if (ACCESS_FLAG(F_CF)) { /* carry flag is set */
838 res |= 1 << (cnt - 1);
840 CONDITIONAL_SET_FLAG(cf, F_CF);
841 CONDITIONAL_SET_FLAG(cnt == 1 && XOR2(cf + ((res >> 30) & 0x2)),
847 /****************************************************************************
849 Implements the RCR instruction and side effects.
850 ****************************************************************************/
851 u8 rcr_byte(u8 d, u8 s)
854 u32 mask, cf, ocf = 0;
856 /* rotate right through carry */
858 s is the rotate distance. It varies from 0 - 8.
859 d is the byte object rotated.
863 CF B_7 B_6 B_5 B_4 B_3 B_2 B_1 B_0
865 The new rotate is done mod 9, and given this,
866 for a rotation of n bits (mod 9) the new carry flag is
867 then located n bits from the LSB. The low part is
868 then shifted up cnt bits, and the high part is or'd
869 in. Using CAPS for new values, and lowercase for the
870 original values, this can be expressed as:
874 2) B_(8-(n+1)) .. B_(0) <- b_(7) .. b_(n)
876 4) B_(7) .. B_(8-(n-1)) <- b_(n-2) .. b_(0)
879 if ((cnt = s % 9) != 0) {
880 /* extract the new CARRY FLAG. */
884 /* note hackery here. Access_flag(..) evaluates to either
886 non-zero if flag is set.
887 doing access_flag(..) != 0 casts that into either
888 0..1 in any representation of the flags register
889 (i.e. packed bit array or unpacked.)
891 ocf = ACCESS_FLAG(F_CF) != 0;
893 cf = (d >> (cnt - 1)) & 0x1;
895 /* B_(8-(n+1)) .. B_(0) <- b_(7) .. b_n */
896 /* note that the right hand side done by the mask
897 This is effectively done by shifting the
898 object to the right. The result must be masked,
899 in case the object came in and was treated
900 as a negative number. Needed??? */
902 mask = (1 << (8 - cnt)) - 1;
903 res = (d >> cnt) & mask;
905 /* now the high stuff which rotated around
906 into the positions B_cnt-2 .. B_0 */
907 /* B_(7) .. B_(8-(n-1)) <- b_(n-2) .. b_(0) */
908 /* shift it downward, 7-(n-2) = 9-n positions.
909 and mask off the result before or'ing in.
911 res |= (d << (9 - cnt));
913 /* if the carry flag was set, or it in. */
914 if (ACCESS_FLAG(F_CF)) { /* carry flag is set */
916 res |= 1 << (8 - cnt);
918 /* set the new carry flag, based on the variable "cf" */
919 CONDITIONAL_SET_FLAG(cf, F_CF);
920 /* OVERFLOW is set *IFF* cnt==1, then it is the
921 xor of CF and the most significant bit. Blecck. */
922 /* parenthesized... */
924 CONDITIONAL_SET_FLAG(XOR2(ocf + ((d >> 6) & 0x2)),
931 /****************************************************************************
933 Implements the RCR instruction and side effects.
934 ****************************************************************************/
935 u16 rcr_word(u16 d, u8 s)
938 u32 mask, cf, ocf = 0;
940 /* rotate right through carry */
942 if ((cnt = s % 17) != 0) {
945 ocf = ACCESS_FLAG(F_CF) != 0;
947 cf = (d >> (cnt - 1)) & 0x1;
948 mask = (1 << (16 - cnt)) - 1;
949 res = (d >> cnt) & mask;
950 res |= (d << (17 - cnt));
951 if (ACCESS_FLAG(F_CF)) {
952 res |= 1 << (16 - cnt);
954 CONDITIONAL_SET_FLAG(cf, F_CF);
956 CONDITIONAL_SET_FLAG(XOR2(ocf + ((d >> 14) & 0x2)),
963 /****************************************************************************
965 Implements the RCR instruction and side effects.
966 ****************************************************************************/
967 u32 rcr_long(u32 d, u8 s)
970 u32 mask, cf, ocf = 0;
972 /* rotate right through carry */
974 if ((cnt = s % 33) != 0) {
977 ocf = ACCESS_FLAG(F_CF) != 0;
979 cf = (d >> (cnt - 1)) & 0x1;
980 mask = (1 << (32 - cnt)) - 1;
981 res = (d >> cnt) & mask;
983 res |= (d << (33 - cnt));
984 if (ACCESS_FLAG(F_CF)) { /* carry flag is set */
985 res |= 1 << (32 - cnt);
987 CONDITIONAL_SET_FLAG(cf, F_CF);
989 CONDITIONAL_SET_FLAG(XOR2(ocf + ((d >> 30) & 0x2)),
996 /****************************************************************************
998 Implements the ROL instruction and side effects.
999 ****************************************************************************/
1000 u8 rol_byte(u8 d, u8 s)
1002 unsigned int res, cnt, mask;
1006 s is the rotate distance. It varies from 0 - 8.
1007 d is the byte object rotated.
1013 The new rotate is done mod 8.
1014 Much simpler than the "rcl" or "rcr" operations.
1017 1) B_(7) .. B_(n) <- b_(8-(n+1)) .. b_(0)
1018 2) B_(n-1) .. B_(0) <- b_(7) .. b_(8-n)
1021 if ((cnt = s % 8) != 0) {
1022 /* B_(7) .. B_(n) <- b_(8-(n+1)) .. b_(0) */
1025 /* B_(n-1) .. B_(0) <- b_(7) .. b_(8-n) */
1026 mask = (1 << cnt) - 1;
1027 res |= (d >> (8 - cnt)) & mask;
1029 /* set the new carry flag, Note that it is the low order
1030 bit of the result!!! */
1031 CONDITIONAL_SET_FLAG(res & 0x1, F_CF);
1032 /* OVERFLOW is set *IFF* s==1, then it is the
1033 xor of CF and the most significant bit. Blecck. */
1034 CONDITIONAL_SET_FLAG(s == 1 &&
1035 XOR2((res & 0x1) + ((res >> 6) & 0x2)),
1038 /* set the new carry flag, Note that it is the low order
1039 bit of the result!!! */
1040 CONDITIONAL_SET_FLAG(res & 0x1, F_CF);
1045 /****************************************************************************
1047 Implements the ROL instruction and side effects.
1048 ****************************************************************************/
1049 u16 rol_word(u16 d, u8 s)
1051 unsigned int res, cnt, mask;
1054 if ((cnt = s % 16) != 0) {
1056 mask = (1 << cnt) - 1;
1057 res |= (d >> (16 - cnt)) & mask;
1058 CONDITIONAL_SET_FLAG(res & 0x1, F_CF);
1059 CONDITIONAL_SET_FLAG(s == 1 &&
1060 XOR2((res & 0x1) + ((res >> 14) & 0x2)),
1063 /* set the new carry flag, Note that it is the low order
1064 bit of the result!!! */
1065 CONDITIONAL_SET_FLAG(res & 0x1, F_CF);
1070 /****************************************************************************
1072 Implements the ROL instruction and side effects.
1073 ****************************************************************************/
1074 u32 rol_long(u32 d, u8 s)
1079 if ((cnt = s % 32) != 0) {
1081 mask = (1 << cnt) - 1;
1082 res |= (d >> (32 - cnt)) & mask;
1083 CONDITIONAL_SET_FLAG(res & 0x1, F_CF);
1084 CONDITIONAL_SET_FLAG(s == 1 &&
1085 XOR2((res & 0x1) + ((res >> 30) & 0x2)),
1088 /* set the new carry flag, Note that it is the low order
1089 bit of the result!!! */
1090 CONDITIONAL_SET_FLAG(res & 0x1, F_CF);
1095 /****************************************************************************
1097 Implements the ROR instruction and side effects.
1098 ****************************************************************************/
1099 u8 ror_byte(u8 d, u8 s)
1101 unsigned int res, cnt, mask;
1105 s is the rotate distance. It varies from 0 - 8.
1106 d is the byte object rotated.
1112 The rotate is done mod 8.
1115 1) B_(8-(n+1)) .. B_(0) <- b_(7) .. b_(n)
1116 2) B_(7) .. B_(8-n) <- b_(n-1) .. b_(0)
1119 if ((cnt = s % 8) != 0) { /* not a typo, do nada if cnt==0 */
1120 /* B_(7) .. B_(8-n) <- b_(n-1) .. b_(0) */
1121 res = (d << (8 - cnt));
1123 /* B_(8-(n+1)) .. B_(0) <- b_(7) .. b_(n) */
1124 mask = (1 << (8 - cnt)) - 1;
1125 res |= (d >> (cnt)) & mask;
1127 /* set the new carry flag, Note that it is the low order
1128 bit of the result!!! */
1129 CONDITIONAL_SET_FLAG(res & 0x80, F_CF);
1130 /* OVERFLOW is set *IFF* s==1, then it is the
1131 xor of the two most significant bits. Blecck. */
1132 CONDITIONAL_SET_FLAG(s == 1 && XOR2(res >> 6), F_OF);
1133 } else if (s != 0) {
1134 /* set the new carry flag, Note that it is the low order
1135 bit of the result!!! */
1136 CONDITIONAL_SET_FLAG(res & 0x80, F_CF);
1141 /****************************************************************************
1143 Implements the ROR instruction and side effects.
1144 ****************************************************************************/
1145 u16 ror_word(u16 d, u8 s)
1147 unsigned int res, cnt, mask;
1150 if ((cnt = s % 16) != 0) {
1151 res = (d << (16 - cnt));
1152 mask = (1 << (16 - cnt)) - 1;
1153 res |= (d >> (cnt)) & mask;
1154 CONDITIONAL_SET_FLAG(res & 0x8000, F_CF);
1155 CONDITIONAL_SET_FLAG(s == 1 && XOR2(res >> 14), F_OF);
1156 } else if (s != 0) {
1157 /* set the new carry flag, Note that it is the low order
1158 bit of the result!!! */
1159 CONDITIONAL_SET_FLAG(res & 0x8000, F_CF);
1164 /****************************************************************************
1166 Implements the ROR instruction and side effects.
1167 ****************************************************************************/
1168 u32 ror_long(u32 d, u8 s)
1173 if ((cnt = s % 32) != 0) {
1174 res = (d << (32 - cnt));
1175 mask = (1 << (32 - cnt)) - 1;
1176 res |= (d >> (cnt)) & mask;
1177 CONDITIONAL_SET_FLAG(res & 0x80000000, F_CF);
1178 CONDITIONAL_SET_FLAG(s == 1 && XOR2(res >> 30), F_OF);
1179 } else if (s != 0) {
1180 /* set the new carry flag, Note that it is the low order
1181 bit of the result!!! */
1182 CONDITIONAL_SET_FLAG(res & 0x80000000, F_CF);
1187 /****************************************************************************
1189 Implements the SHL instruction and side effects.
1190 ****************************************************************************/
1191 u8 shl_byte(u8 d, u8 s)
1193 unsigned int cnt, res, cf;
1198 /* last bit shifted out goes into carry flag */
1201 cf = d & (1 << (8 - cnt));
1202 CONDITIONAL_SET_FLAG(cf, F_CF);
1203 set_szp_flags_8((u8)res);
1209 /* Needs simplification. */
1210 CONDITIONAL_SET_FLAG(
1211 (((res & 0x80) == 0x80) ^
1212 (ACCESS_FLAG(F_CF) != 0)),
1213 /* was (M.x86.R_FLG&F_CF)==F_CF)), */
1220 CONDITIONAL_SET_FLAG((d << (s-1)) & 0x80, F_CF);
1229 /****************************************************************************
1231 Implements the SHL instruction and side effects.
1232 ****************************************************************************/
1233 u16 shl_word(u16 d, u8 s)
1235 unsigned int cnt, res, cf;
1241 cf = d & (1 << (16 - cnt));
1242 CONDITIONAL_SET_FLAG(cf, F_CF);
1243 set_szp_flags_16((u16)res);
1249 CONDITIONAL_SET_FLAG(
1250 (((res & 0x8000) == 0x8000) ^
1251 (ACCESS_FLAG(F_CF) != 0)),
1258 CONDITIONAL_SET_FLAG((d << (s-1)) & 0x8000, F_CF);
1267 /****************************************************************************
1269 Implements the SHL instruction and side effects.
1270 ****************************************************************************/
1271 u32 shl_long(u32 d, u8 s)
1273 unsigned int cnt, res, cf;
1279 cf = d & (1 << (32 - cnt));
1280 CONDITIONAL_SET_FLAG(cf, F_CF);
1281 set_szp_flags_32((u32)res);
1286 CONDITIONAL_SET_FLAG((((res & 0x80000000) == 0x80000000) ^
1287 (ACCESS_FLAG(F_CF) != 0)), F_OF);
1293 CONDITIONAL_SET_FLAG((d << (s-1)) & 0x80000000, F_CF);
1302 /****************************************************************************
1304 Implements the SHR instruction and side effects.
1305 ****************************************************************************/
1306 u8 shr_byte(u8 d, u8 s)
1308 unsigned int cnt, res, cf;
1313 cf = d & (1 << (cnt - 1));
1315 CONDITIONAL_SET_FLAG(cf, F_CF);
1316 set_szp_flags_8((u8)res);
1322 CONDITIONAL_SET_FLAG(XOR2(res >> 6), F_OF);
1328 CONDITIONAL_SET_FLAG((d >> (s-1)) & 0x1, F_CF);
1337 /****************************************************************************
1339 Implements the SHR instruction and side effects.
1340 ****************************************************************************/
1341 u16 shr_word(u16 d, u8 s)
1343 unsigned int cnt, res, cf;
1348 cf = d & (1 << (cnt - 1));
1350 CONDITIONAL_SET_FLAG(cf, F_CF);
1351 set_szp_flags_16((u16)res);
1357 CONDITIONAL_SET_FLAG(XOR2(res >> 14), F_OF);
1372 /****************************************************************************
1374 Implements the SHR instruction and side effects.
1375 ****************************************************************************/
1376 u32 shr_long(u32 d, u8 s)
1378 unsigned int cnt, res, cf;
1383 cf = d & (1 << (cnt - 1));
1385 CONDITIONAL_SET_FLAG(cf, F_CF);
1386 set_szp_flags_32((u32)res);
1391 CONDITIONAL_SET_FLAG(XOR2(res >> 30), F_OF);
1406 /****************************************************************************
1408 Implements the SAR instruction and side effects.
1409 ****************************************************************************/
1410 u8 sar_byte(u8 d, u8 s)
1412 unsigned int cnt, res, cf, mask, sf;
1417 if (cnt > 0 && cnt < 8) {
1418 mask = (1 << (8 - cnt)) - 1;
1419 cf = d & (1 << (cnt - 1));
1420 res = (d >> cnt) & mask;
1421 CONDITIONAL_SET_FLAG(cf, F_CF);
1425 set_szp_flags_8((u8)res);
1426 } else if (cnt >= 8) {
1444 /****************************************************************************
1446 Implements the SAR instruction and side effects.
1447 ****************************************************************************/
1448 u16 sar_word(u16 d, u8 s)
1450 unsigned int cnt, res, cf, mask, sf;
1455 if (cnt > 0 && cnt < 16) {
1456 mask = (1 << (16 - cnt)) - 1;
1457 cf = d & (1 << (cnt - 1));
1458 res = (d >> cnt) & mask;
1459 CONDITIONAL_SET_FLAG(cf, F_CF);
1463 set_szp_flags_16((u16)res);
1464 } else if (cnt >= 16) {
1482 /****************************************************************************
1484 Implements the SAR instruction and side effects.
1485 ****************************************************************************/
1486 u32 sar_long(u32 d, u8 s)
1488 u32 cnt, res, cf, mask, sf;
1490 sf = d & 0x80000000;
1493 if (cnt > 0 && cnt < 32) {
1494 mask = (1 << (32 - cnt)) - 1;
1495 cf = d & (1 << (cnt - 1));
1496 res = (d >> cnt) & mask;
1497 CONDITIONAL_SET_FLAG(cf, F_CF);
1501 set_szp_flags_32(res);
1502 } else if (cnt >= 32) {
1520 /****************************************************************************
1522 Implements the SHLD instruction and side effects.
1523 ****************************************************************************/
1524 u16 shld_word (u16 d, u16 fill, u8 s)
1526 unsigned int cnt, res, cf;
1531 res = (d << cnt) | (fill >> (16-cnt));
1532 cf = d & (1 << (16 - cnt));
1533 CONDITIONAL_SET_FLAG(cf, F_CF);
1534 set_szp_flags_16((u16)res);
1539 CONDITIONAL_SET_FLAG((((res & 0x8000) == 0x8000) ^
1540 (ACCESS_FLAG(F_CF) != 0)), F_OF);
1546 CONDITIONAL_SET_FLAG((d << (s-1)) & 0x8000, F_CF);
1555 /****************************************************************************
1557 Implements the SHLD instruction and side effects.
1558 ****************************************************************************/
1559 u32 shld_long (u32 d, u32 fill, u8 s)
1561 unsigned int cnt, res, cf;
1566 res = (d << cnt) | (fill >> (32-cnt));
1567 cf = d & (1 << (32 - cnt));
1568 CONDITIONAL_SET_FLAG(cf, F_CF);
1569 set_szp_flags_32((u32)res);
1574 CONDITIONAL_SET_FLAG((((res & 0x80000000) == 0x80000000) ^
1575 (ACCESS_FLAG(F_CF) != 0)), F_OF);
1581 CONDITIONAL_SET_FLAG((d << (s-1)) & 0x80000000, F_CF);
1590 /****************************************************************************
1592 Implements the SHRD instruction and side effects.
1593 ****************************************************************************/
1594 u16 shrd_word (u16 d, u16 fill, u8 s)
1596 unsigned int cnt, res, cf;
1601 cf = d & (1 << (cnt - 1));
1602 res = (d >> cnt) | (fill << (16 - cnt));
1603 CONDITIONAL_SET_FLAG(cf, F_CF);
1604 set_szp_flags_16((u16)res);
1610 CONDITIONAL_SET_FLAG(XOR2(res >> 14), F_OF);
1625 /****************************************************************************
1627 Implements the SHRD instruction and side effects.
1628 ****************************************************************************/
1629 u32 shrd_long (u32 d, u32 fill, u8 s)
1631 unsigned int cnt, res, cf;
1636 cf = d & (1 << (cnt - 1));
1637 res = (d >> cnt) | (fill << (32 - cnt));
1638 CONDITIONAL_SET_FLAG(cf, F_CF);
1639 set_szp_flags_32((u32)res);
1644 CONDITIONAL_SET_FLAG(XOR2(res >> 30), F_OF);
1659 /****************************************************************************
1661 Implements the SBB instruction and side effects.
1662 ****************************************************************************/
1663 u8 sbb_byte(u8 d, u8 s)
1665 u32 res; /* all operands in native machine order */
1668 if (ACCESS_FLAG(F_CF))
1672 set_szp_flags_8((u8)res);
1674 /* calculate the borrow chain. See note at top */
1675 bc = (res & (~d | s)) | (~d & s);
1676 CONDITIONAL_SET_FLAG(bc & 0x80, F_CF);
1677 CONDITIONAL_SET_FLAG(XOR2(bc >> 6), F_OF);
1678 CONDITIONAL_SET_FLAG(bc & 0x8, F_AF);
1682 /****************************************************************************
1684 Implements the SBB instruction and side effects.
1685 ****************************************************************************/
1686 u16 sbb_word(u16 d, u16 s)
1688 u32 res; /* all operands in native machine order */
1691 if (ACCESS_FLAG(F_CF))
1695 set_szp_flags_16((u16)res);
1697 /* calculate the borrow chain. See note at top */
1698 bc = (res & (~d | s)) | (~d & s);
1699 CONDITIONAL_SET_FLAG(bc & 0x8000, F_CF);
1700 CONDITIONAL_SET_FLAG(XOR2(bc >> 14), F_OF);
1701 CONDITIONAL_SET_FLAG(bc & 0x8, F_AF);
1705 /****************************************************************************
1707 Implements the SBB instruction and side effects.
1708 ****************************************************************************/
1709 u32 sbb_long(u32 d, u32 s)
1711 u32 res; /* all operands in native machine order */
1714 if (ACCESS_FLAG(F_CF))
1719 set_szp_flags_32(res);
1721 /* calculate the borrow chain. See note at top */
1722 bc = (res & (~d | s)) | (~d & s);
1723 CONDITIONAL_SET_FLAG(bc & 0x80000000, F_CF);
1724 CONDITIONAL_SET_FLAG(XOR2(bc >> 30), F_OF);
1725 CONDITIONAL_SET_FLAG(bc & 0x8, F_AF);
1729 /****************************************************************************
1731 Implements the SUB instruction and side effects.
1732 ****************************************************************************/
1733 u8 sub_byte(u8 d, u8 s)
1735 u32 res; /* all operands in native machine order */
1739 set_szp_flags_8((u8)res);
1741 /* calculate the borrow chain. See note at top */
1742 bc = (res & (~d | s)) | (~d & s);
1743 CONDITIONAL_SET_FLAG(bc & 0x80, F_CF);
1744 CONDITIONAL_SET_FLAG(XOR2(bc >> 6), F_OF);
1745 CONDITIONAL_SET_FLAG(bc & 0x8, F_AF);
1749 /****************************************************************************
1751 Implements the SUB instruction and side effects.
1752 ****************************************************************************/
1753 u16 sub_word(u16 d, u16 s)
1755 u32 res; /* all operands in native machine order */
1759 set_szp_flags_16((u16)res);
1761 /* calculate the borrow chain. See note at top */
1762 bc = (res & (~d | s)) | (~d & s);
1763 CONDITIONAL_SET_FLAG(bc & 0x8000, F_CF);
1764 CONDITIONAL_SET_FLAG(XOR2(bc >> 14), F_OF);
1765 CONDITIONAL_SET_FLAG(bc & 0x8, F_AF);
1769 /****************************************************************************
1771 Implements the SUB instruction and side effects.
1772 ****************************************************************************/
1773 u32 sub_long(u32 d, u32 s)
1775 u32 res; /* all operands in native machine order */
1779 set_szp_flags_32(res);
1781 /* calculate the borrow chain. See note at top */
1782 bc = (res & (~d | s)) | (~d & s);
1783 CONDITIONAL_SET_FLAG(bc & 0x80000000, F_CF);
1784 CONDITIONAL_SET_FLAG(XOR2(bc >> 30), F_OF);
1785 CONDITIONAL_SET_FLAG(bc & 0x8, F_AF);
1789 /****************************************************************************
1791 Implements the TEST instruction and side effects.
1792 ****************************************************************************/
1793 void test_byte(u8 d, u8 s)
1795 u32 res; /* all operands in native machine order */
1800 set_szp_flags_8((u8)res);
1801 /* AF == dont care */
1805 /****************************************************************************
1807 Implements the TEST instruction and side effects.
1808 ****************************************************************************/
1809 void test_word(u16 d, u16 s)
1811 u32 res; /* all operands in native machine order */
1816 set_szp_flags_16((u16)res);
1817 /* AF == dont care */
1821 /****************************************************************************
1823 Implements the TEST instruction and side effects.
1824 ****************************************************************************/
1825 void test_long(u32 d, u32 s)
1827 u32 res; /* all operands in native machine order */
1832 set_szp_flags_32(res);
1833 /* AF == dont care */
1837 /****************************************************************************
1839 Implements the XOR instruction and side effects.
1840 ****************************************************************************/
1841 u8 xor_byte(u8 d, u8 s)
1843 u8 res; /* all operands in native machine order */
1846 no_carry_byte_side_eff(res);
1850 /****************************************************************************
1852 Implements the XOR instruction and side effects.
1853 ****************************************************************************/
1854 u16 xor_word(u16 d, u16 s)
1856 u16 res; /* all operands in native machine order */
1859 no_carry_word_side_eff(res);
1863 /****************************************************************************
1865 Implements the XOR instruction and side effects.
1866 ****************************************************************************/
1867 u32 xor_long(u32 d, u32 s)
1869 u32 res; /* all operands in native machine order */
1872 no_carry_long_side_eff(res);
1876 /****************************************************************************
1878 Implements the IMUL instruction and side effects.
1879 ****************************************************************************/
1880 void imul_byte(u8 s)
1882 s16 res = (s16)((s8)M.x86.R_AL * (s8)s);
1885 if (((M.x86.R_AL & 0x80) == 0 && M.x86.R_AH == 0x00) ||
1886 ((M.x86.R_AL & 0x80) != 0 && M.x86.R_AH == 0xFF)) {
1895 /****************************************************************************
1897 Implements the IMUL instruction and side effects.
1898 ****************************************************************************/
1899 void imul_word(u16 s)
1901 s32 res = (s16)M.x86.R_AX * (s16)s;
1903 M.x86.R_AX = (u16)res;
1904 M.x86.R_DX = (u16)(res >> 16);
1905 if (((M.x86.R_AX & 0x8000) == 0 && M.x86.R_DX == 0x0000) ||
1906 ((M.x86.R_AX & 0x8000) != 0 && M.x86.R_DX == 0xFFFF)) {
1915 /****************************************************************************
1917 Implements the IMUL instruction and side effects.
1918 ****************************************************************************/
1919 void imul_long_direct(u32 *res_lo, u32* res_hi,u32 d, u32 s)
1921 #ifdef __HAS_LONG_LONG__
1922 s64 res = (s32)d * (s32)s;
1925 *res_hi = (u32)(res >> 32);
1927 u32 d_lo,d_hi,d_sign;
1928 u32 s_lo,s_hi,s_sign;
1929 u32 rlo_lo,rlo_hi,rhi_lo;
1931 if ((d_sign = d & 0x80000000) != 0)
1935 if ((s_sign = s & 0x80000000) != 0)
1939 rlo_lo = d_lo * s_lo;
1940 rlo_hi = (d_hi * s_lo + d_lo * s_hi) + (rlo_lo >> 16);
1941 rhi_lo = d_hi * s_hi + (rlo_hi >> 16);
1942 *res_lo = (rlo_hi << 16) | (rlo_lo & 0xFFFF);
1944 if (d_sign != s_sign) {
1946 s = (((d & 0xFFFF) + 1) >> 16) + (d >> 16);
1947 *res_lo = ~*res_lo+1;
1948 *res_hi = ~*res_hi+(s >> 16);
1953 /****************************************************************************
1955 Implements the IMUL instruction and side effects.
1956 ****************************************************************************/
1957 void imul_long(u32 s)
1959 imul_long_direct(&M.x86.R_EAX,&M.x86.R_EDX,M.x86.R_EAX,s);
1960 if (((M.x86.R_EAX & 0x80000000) == 0 && M.x86.R_EDX == 0x00000000) ||
1961 ((M.x86.R_EAX & 0x80000000) != 0 && M.x86.R_EDX == 0xFFFFFFFF)) {
1970 /****************************************************************************
1972 Implements the MUL instruction and side effects.
1973 ****************************************************************************/
1976 u16 res = (u16)(M.x86.R_AL * s);
1979 if (M.x86.R_AH == 0) {
1988 /****************************************************************************
1990 Implements the MUL instruction and side effects.
1991 ****************************************************************************/
1992 void mul_word(u16 s)
1994 u32 res = M.x86.R_AX * s;
1996 M.x86.R_AX = (u16)res;
1997 M.x86.R_DX = (u16)(res >> 16);
1998 if (M.x86.R_DX == 0) {
2007 /****************************************************************************
2009 Implements the MUL instruction and side effects.
2010 ****************************************************************************/
2011 void mul_long(u32 s)
2013 #ifdef __HAS_LONG_LONG__
2014 u64 res = (u32)M.x86.R_EAX * (u32)s;
2016 M.x86.R_EAX = (u32)res;
2017 M.x86.R_EDX = (u32)(res >> 32);
2021 u32 rlo_lo,rlo_hi,rhi_lo;
2028 rlo_lo = a_lo * s_lo;
2029 rlo_hi = (a_hi * s_lo + a_lo * s_hi) + (rlo_lo >> 16);
2030 rhi_lo = a_hi * s_hi + (rlo_hi >> 16);
2031 M.x86.R_EAX = (rlo_hi << 16) | (rlo_lo & 0xFFFF);
2032 M.x86.R_EDX = rhi_lo;
2034 if (M.x86.R_EDX == 0) {
2043 /****************************************************************************
2045 Implements the IDIV instruction and side effects.
2046 ****************************************************************************/
2047 void idiv_byte(u8 s)
2051 dvd = (s16)M.x86.R_AX;
2053 x86emu_intr_raise(0);
2058 if (abs(div) > 0x7f) {
2059 x86emu_intr_raise(0);
2062 M.x86.R_AL = (s8) div;
2063 M.x86.R_AH = (s8) mod;
2066 /****************************************************************************
2068 Implements the IDIV instruction and side effects.
2069 ****************************************************************************/
2070 void idiv_word(u16 s)
2074 dvd = (((s32)M.x86.R_DX) << 16) | M.x86.R_AX;
2076 x86emu_intr_raise(0);
2081 if (abs(div) > 0x7fff) {
2082 x86emu_intr_raise(0);
2087 CONDITIONAL_SET_FLAG(div == 0, F_ZF);
2088 set_parity_flag(mod);
2090 M.x86.R_AX = (u16)div;
2091 M.x86.R_DX = (u16)mod;
2094 /****************************************************************************
2096 Implements the IDIV instruction and side effects.
2097 ****************************************************************************/
2098 void idiv_long(u32 s)
2100 #ifdef __HAS_LONG_LONG__
2103 dvd = (((s64)M.x86.R_EDX) << 32) | M.x86.R_EAX;
2105 x86emu_intr_raise(0);
2110 if (abs(div) > 0x7fffffff) {
2111 x86emu_intr_raise(0);
2116 s32 h_dvd = M.x86.R_EDX;
2117 u32 l_dvd = M.x86.R_EAX;
2118 u32 abs_s = s & 0x7FFFFFFF;
2119 u32 abs_h_dvd = h_dvd & 0x7FFFFFFF;
2120 u32 h_s = abs_s >> 1;
2121 u32 l_s = abs_s << 31;
2126 x86emu_intr_raise(0);
2131 carry = (l_dvd >= l_s) ? 0 : 1;
2133 if (abs_h_dvd < (h_s + carry)) {
2135 l_s = abs_s << (--counter);
2138 abs_h_dvd -= (h_s + carry);
2139 l_dvd = carry ? ((0xFFFFFFFF - l_s) + l_dvd + 1)
2142 l_s = abs_s << (--counter);
2147 } while (counter > -1);
2149 if (abs_h_dvd || (l_dvd > abs_s)) {
2150 x86emu_intr_raise(0);
2154 div |= ((h_dvd & 0x10000000) ^ (s & 0x10000000));
2162 set_parity_flag(mod);
2164 M.x86.R_EAX = (u32)div;
2165 M.x86.R_EDX = (u32)mod;
2168 /****************************************************************************
2170 Implements the DIV instruction and side effects.
2171 ****************************************************************************/
2178 x86emu_intr_raise(0);
2183 if (abs(div) > 0xff) {
2184 x86emu_intr_raise(0);
2187 M.x86.R_AL = (u8)div;
2188 M.x86.R_AH = (u8)mod;
2191 /****************************************************************************
2193 Implements the DIV instruction and side effects.
2194 ****************************************************************************/
2195 void div_word(u16 s)
2199 dvd = (((u32)M.x86.R_DX) << 16) | M.x86.R_AX;
2201 x86emu_intr_raise(0);
2206 if (abs(div) > 0xffff) {
2207 x86emu_intr_raise(0);
2212 CONDITIONAL_SET_FLAG(div == 0, F_ZF);
2213 set_parity_flag(mod);
2215 M.x86.R_AX = (u16)div;
2216 M.x86.R_DX = (u16)mod;
2219 /****************************************************************************
2221 Implements the DIV instruction and side effects.
2222 ****************************************************************************/
2223 void div_long(u32 s)
2225 #ifdef __HAS_LONG_LONG__
2228 dvd = (((u64)M.x86.R_EDX) << 32) | M.x86.R_EAX;
2230 x86emu_intr_raise(0);
2235 if (abs(div) > 0xffffffff) {
2236 x86emu_intr_raise(0);
2241 s32 h_dvd = M.x86.R_EDX;
2242 u32 l_dvd = M.x86.R_EAX;
2250 x86emu_intr_raise(0);
2255 carry = (l_dvd >= l_s) ? 0 : 1;
2257 if (h_dvd < (h_s + carry)) {
2259 l_s = s << (--counter);
2262 h_dvd -= (h_s + carry);
2263 l_dvd = carry ? ((0xFFFFFFFF - l_s) + l_dvd + 1)
2266 l_s = s << (--counter);
2271 } while (counter > -1);
2273 if (h_dvd || (l_dvd > s)) {
2274 x86emu_intr_raise(0);
2283 set_parity_flag(mod);
2285 M.x86.R_EAX = (u32)div;
2286 M.x86.R_EDX = (u32)mod;
2289 /****************************************************************************
2291 Implements the IN string instruction and side effects.
2292 ****************************************************************************/
2294 static void single_in(int size)
2297 store_data_byte_abs(M.x86.R_ES, M.x86.R_DI,(*sys_inb)(M.x86.R_DX));
2299 store_data_word_abs(M.x86.R_ES, M.x86.R_DI,(*sys_inw)(M.x86.R_DX));
2301 store_data_long_abs(M.x86.R_ES, M.x86.R_DI,(*sys_inl)(M.x86.R_DX));
2308 if (ACCESS_FLAG(F_DF)) {
2311 if (M.x86.mode & (SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE)) {
2312 /* dont care whether REPE or REPNE */
2313 /* in until CX is ZERO. */
2314 u32 count = ((M.x86.mode & SYSMODE_PREFIX_DATA) ?
2315 M.x86.R_ECX : M.x86.R_CX);
2322 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2325 M.x86.mode &= ~(SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE);
2332 /****************************************************************************
2334 Implements the OUT string instruction and side effects.
2335 ****************************************************************************/
2337 static void single_out(int size)
2340 (*sys_outb)(M.x86.R_DX,fetch_data_byte_abs(M.x86.R_ES, M.x86.R_SI));
2342 (*sys_outw)(M.x86.R_DX,fetch_data_word_abs(M.x86.R_ES, M.x86.R_SI));
2344 (*sys_outl)(M.x86.R_DX,fetch_data_long_abs(M.x86.R_ES, M.x86.R_SI));
2351 if (ACCESS_FLAG(F_DF)) {
2354 if (M.x86.mode & (SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE)) {
2355 /* dont care whether REPE or REPNE */
2356 /* out until CX is ZERO. */
2357 u32 count = ((M.x86.mode & SYSMODE_PREFIX_DATA) ?
2358 M.x86.R_ECX : M.x86.R_CX);
2364 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2367 M.x86.mode &= ~(SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE);
2374 /****************************************************************************
2376 addr - Address to fetch word from
2379 Fetches a word from emulator memory using an absolute address.
2380 ****************************************************************************/
2381 u16 mem_access_word(int addr)
2383 DB( if (CHECK_MEM_ACCESS())
2384 x86emu_check_mem_access(addr);)
2385 return (*sys_rdw)(addr);
2388 /****************************************************************************
2390 Pushes a word onto the stack.
2392 NOTE: Do not inline this, as (*sys_wrX) is already inline!
2393 ****************************************************************************/
2394 void push_word(u16 w)
2396 DB( if (CHECK_SP_ACCESS())
2397 x86emu_check_sp_access();)
2399 (*sys_wrw)(((u32)M.x86.R_SS << 4) + M.x86.R_SP, w);
2402 /****************************************************************************
2404 Pushes a long onto the stack.
2406 NOTE: Do not inline this, as (*sys_wrX) is already inline!
2407 ****************************************************************************/
2408 void push_long(u32 w)
2410 DB( if (CHECK_SP_ACCESS())
2411 x86emu_check_sp_access();)
2413 (*sys_wrl)(((u32)M.x86.R_SS << 4) + M.x86.R_SP, w);
2416 /****************************************************************************
2418 Pops a word from the stack.
2420 NOTE: Do not inline this, as (*sys_rdX) is already inline!
2421 ****************************************************************************/
2426 DB( if (CHECK_SP_ACCESS())
2427 x86emu_check_sp_access();)
2428 res = (*sys_rdw)(((u32)M.x86.R_SS << 4) + M.x86.R_SP);
2433 /****************************************************************************
2435 Pops a long from the stack.
2437 NOTE: Do not inline this, as (*sys_rdX) is already inline!
2438 ****************************************************************************/
2443 DB( if (CHECK_SP_ACCESS())
2444 x86emu_check_sp_access();)
2445 res = (*sys_rdl)(((u32)M.x86.R_SS << 4) + M.x86.R_SP);