145e35f0ff55ed55fec18674c176d7bdebf97b3a
3 * Copyright (C) 1991 Jim Hudgens
6 * The file is part of GDE.
8 * GDE is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 1, or (at your option)
13 * GDE is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with GDE; see the file COPYING. If not, write to
20 * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
24 #include "altairz80_defs.h"
27 extern void out(const uint32 Port
, const uint32 Value
);
28 extern uint32
in(const uint32 Port
);
30 /* $Log: i86_ops.c,v $
31 * Revision 0.11 1991/07/30 02:02:04 hudgens
34 * Revision 0.10 1991/07/21 18:22:08 hudgens
35 * Fixed problem with scans, which was the result of the loop break
36 * condition being incorrect when used in conjunction with the repe
37 * or repne prefixes. Eureka. pkzip/pkunzip now compress/decompress
40 * Revision 0.9 1991/07/21 03:33:18 hudgens
41 * fixed popf so that it appears to be the same as an 8088 popf, and always
42 * sets the high 4 bits of the flags.
44 * Revision 0.8 1991/07/21 01:44:11 hudgens
45 * fixed aad and aam instructions.
47 * Revision 0.7 1991/07/21 00:31:24 hudgens
48 * Fixed iret so that it works correctly.
50 * Revision 0.6 1991/07/20 16:54:50 hudgens
51 * removed the 8087 coprocessor operations. Moved to i87_ops.c
53 * Revision 0.5 1991/07/17 03:50:10 hudgens
54 * Minor modifications.
56 * Revision 0.4 1991/06/18 02:48:41 hudgens
57 * Fixed a problem with scasb and scasw.
59 * Revision 0.3 1991/06/03 01:01:10 hudgens
60 * fixed minor problems due to unsigned to signed short integer
63 * Revision 0.2 1991/03/31 01:32:10 hudgens
64 * fixed segment handling. Added calls to DECODE_CLEAR_SEGOVR in
65 * many places in the code. Should work much better now.
67 * Revision 0.1 1991/03/30 21:15:48 hudgens
68 * Initial checkin to RCS.
73 /* 2/23/91 fixed decode for operand x87. */
75 /* partially mechanically generated file....(based on the optable) */
77 There are approximately 250 subroutines in here, which correspond
78 to the 256 byte-"opcodes" found on the 8086. The table which
79 dispatches this is found in the files optab.[ch].
81 Each opcode proc has a comment preceeding it which gives it's table
82 address. Several opcodes are missing (undefined) in the table.
84 Each proc includes information for decoding (DECODE_PRINTF and
86 Many of the procedures are *VERY* similar in coding. This has
87 allowed for a very large amount of code to be generated in a fairly
88 short amount of time (i.e. cut, paste, and modify).
89 The result is that much of the code below could
90 have been folded into subroutines for a large reduction in size of
91 this file. The downside would be that there would be a penalty in
92 execution speed. The file could also have been *MUCH* larger by
93 inlining certain functions which were called. This could have
94 resulted even faster execution. The prime directive I used to decide
95 whether to inline the code or to modularize it, was basically: 1) no
96 unnecessary subroutine calls, 2) no routines more than about 200 lines
97 in size, and 3) modularize any code that I might not get right the first
98 time. The fetch_* subroutines fall into the latter category. The
99 The decode_* fall into the second category. The coding of the
100 "switch(mod){ .... }" in many of the subroutines below falls into the
101 first category. Especially, the coding of {add,and,or,sub,...}_{byte,word}
102 subroutines are an especially glaring case of the third guideline.
103 Since so much of the code is cloned from other modules (compare
104 opcode #00 to opcode #01), making the basic operations subroutine calls
105 is especially important; otherwise mistakes in coding an "add"
106 would represent a nightmare in maintenance.
108 So, without further ado, ...
111 extern char parity_tab
[];
113 static void i86op_illegal_op(PC_ENV
*m
)
115 intr
|= INTR_ILLEGAL_OPCODE
;
119 static void i86op_add_byte_RM_R(PC_ENV
*m
)
122 uint8
*destreg
,*srcreg
;
125 FETCH_DECODE_MODRM(m
,mod
,rh
,rl
);
129 destoffset
=decode_rm00_address(m
,rl
);
130 destval
= fetch_data_byte(m
,destoffset
);
131 srcreg
= DECODE_RM_BYTE_REGISTER(m
,rh
);
132 destval
= add_byte(m
, destval
, *srcreg
);
133 store_data_byte(m
,destoffset
,destval
);
136 destoffset
=decode_rm01_address(m
,rl
);
137 destval
= fetch_data_byte(m
,destoffset
);
138 srcreg
= DECODE_RM_BYTE_REGISTER(m
,rh
);
139 destval
= add_byte(m
, destval
, *srcreg
);
140 store_data_byte(m
,destoffset
,destval
);
143 destoffset
=decode_rm10_address(m
,rl
);
144 destval
= fetch_data_byte(m
,destoffset
);
145 srcreg
= DECODE_RM_BYTE_REGISTER(m
,rh
);
146 destval
= add_byte(m
, destval
, *srcreg
);
147 store_data_byte(m
,destoffset
,destval
);
149 case 3: /* register to register */
150 destreg
= DECODE_RM_BYTE_REGISTER(m
,rl
);
151 srcreg
= DECODE_RM_BYTE_REGISTER(m
,rh
);
152 *destreg
= add_byte(m
, *destreg
, *srcreg
);
155 DECODE_CLEAR_SEGOVR(m
);
159 static void i86op_add_word_RM_R(PC_ENV
*m
)
162 uint16
*destreg
,*srcreg
;
165 FETCH_DECODE_MODRM(m
,mod
,rh
,rl
);
169 destoffset
=decode_rm00_address(m
,rl
);
170 destval
= fetch_data_word(m
,destoffset
);
171 srcreg
= DECODE_RM_WORD_REGISTER(m
,rh
);
172 destval
= add_word(m
, destval
, *srcreg
);
173 store_data_word(m
,destoffset
,destval
);
176 destoffset
=decode_rm01_address(m
,rl
);
177 destval
= fetch_data_word(m
,destoffset
);
178 srcreg
= DECODE_RM_WORD_REGISTER(m
,rh
);
179 destval
= add_word(m
, destval
, *srcreg
);
180 store_data_word(m
,destoffset
,destval
);
183 destoffset
=decode_rm10_address(m
,rl
);
184 destval
= fetch_data_word(m
,destoffset
);
185 srcreg
= DECODE_RM_WORD_REGISTER(m
,rh
);
186 destval
= add_word(m
, destval
, *srcreg
);
187 store_data_word(m
,destoffset
,destval
);
189 case 3: /* register to register */
190 destreg
= DECODE_RM_WORD_REGISTER(m
,rl
);
191 srcreg
= DECODE_RM_WORD_REGISTER(m
,rh
);
192 *destreg
= add_word(m
, *destreg
, *srcreg
);
195 DECODE_CLEAR_SEGOVR(m
);
199 static void i86op_add_byte_R_RM(PC_ENV
*m
)
202 uint8
*destreg
,*srcreg
;
205 FETCH_DECODE_MODRM(m
,mod
,rh
,rl
);
209 destreg
= DECODE_RM_BYTE_REGISTER(m
,rh
);
210 srcoffset
=decode_rm00_address(m
,rl
);
211 srcval
= fetch_data_byte(m
,srcoffset
);
212 *destreg
= add_byte(m
, *destreg
, srcval
);
215 destreg
= DECODE_RM_BYTE_REGISTER(m
,rh
);
216 srcoffset
=decode_rm01_address(m
,rl
);
217 srcval
= fetch_data_byte(m
,srcoffset
);
218 *destreg
= add_byte(m
, *destreg
, srcval
);
221 destreg
= DECODE_RM_BYTE_REGISTER(m
,rh
);
222 srcoffset
=decode_rm10_address(m
,rl
);
223 srcval
= fetch_data_byte(m
,srcoffset
);
224 *destreg
= add_byte(m
, * destreg
, srcval
);
226 case 3: /* register to register */
227 destreg
= DECODE_RM_BYTE_REGISTER(m
,rh
);
228 srcreg
= DECODE_RM_BYTE_REGISTER(m
,rl
);
229 *destreg
= add_byte(m
, *destreg
, *srcreg
);
232 DECODE_CLEAR_SEGOVR(m
);
236 static void i86op_add_word_R_RM(PC_ENV
*m
)
239 uint16
*destreg
,*srcreg
;
242 FETCH_DECODE_MODRM(m
,mod
,rh
,rl
);
246 destreg
= DECODE_RM_WORD_REGISTER(m
,rh
);
247 srcoffset
=decode_rm00_address(m
,rl
);
248 srcval
= fetch_data_word(m
,srcoffset
);
249 *destreg
= add_word(m
, *destreg
, srcval
);
252 destreg
= DECODE_RM_WORD_REGISTER(m
,rh
);
253 srcoffset
=decode_rm01_address(m
,rl
);
254 srcval
= fetch_data_word(m
,srcoffset
);
255 *destreg
= add_word(m
, *destreg
, srcval
);
258 destreg
= DECODE_RM_WORD_REGISTER(m
,rh
);
259 srcoffset
=decode_rm10_address(m
,rl
);
260 srcval
= fetch_data_word(m
,srcoffset
);
261 *destreg
= add_word(m
, *destreg
, srcval
);
263 case 3: /* register to register */
264 destreg
= DECODE_RM_WORD_REGISTER(m
,rh
);
265 srcreg
= DECODE_RM_WORD_REGISTER(m
,rl
);
266 *destreg
= add_word(m
, *destreg
, *srcreg
);
269 DECODE_CLEAR_SEGOVR(m
);
273 static void i86op_add_byte_AL_IMM(PC_ENV
*m
)
276 srcval
= fetch_byte_imm(m
);
277 m
->R_AL
= add_byte(m
, m
->R_AL
, srcval
);
278 DECODE_CLEAR_SEGOVR(m
);
282 static void i86op_add_word_AX_IMM(PC_ENV
*m
)
285 srcval
= fetch_word_imm(m
);
286 m
->R_AX
= add_word(m
, m
->R_AX
, srcval
);
287 DECODE_CLEAR_SEGOVR(m
);
291 static void i86op_push_ES(PC_ENV
*m
)
293 push_word(m
,m
->R_ES
);
294 DECODE_CLEAR_SEGOVR(m
);
298 static void i86op_pop_ES(PC_ENV
*m
)
300 m
->R_ES
= pop_word(m
);
301 DECODE_CLEAR_SEGOVR(m
);
305 static void i86op_or_byte_RM_R(PC_ENV
*m
)
308 uint8
*destreg
,*srcreg
;
311 FETCH_DECODE_MODRM(m
,mod
,rh
,rl
);
315 destoffset
=decode_rm00_address(m
,rl
);
316 destval
= fetch_data_byte(m
,destoffset
);
317 srcreg
= DECODE_RM_BYTE_REGISTER(m
,rh
);
318 destval
= or_byte(m
, destval
, *srcreg
);
319 store_data_byte(m
,destoffset
,destval
);
322 destoffset
=decode_rm01_address(m
,rl
);
323 destval
= fetch_data_byte(m
,destoffset
);
324 srcreg
= DECODE_RM_BYTE_REGISTER(m
,rh
);
325 destval
= or_byte(m
, destval
, *srcreg
);
326 store_data_byte(m
,destoffset
,destval
);
329 destoffset
=decode_rm10_address(m
,rl
);
330 destval
= fetch_data_byte(m
,destoffset
);
331 srcreg
= DECODE_RM_BYTE_REGISTER(m
,rh
);
332 destval
= or_byte(m
, destval
, *srcreg
);
333 store_data_byte(m
,destoffset
,destval
);
335 case 3: /* register to register */
336 destreg
= DECODE_RM_BYTE_REGISTER(m
,rl
);
337 srcreg
= DECODE_RM_BYTE_REGISTER(m
,rh
);
338 *destreg
= or_byte(m
, *destreg
, *srcreg
);
341 DECODE_CLEAR_SEGOVR(m
);
345 static void i86op_or_word_RM_R(PC_ENV
*m
)
348 uint16
*destreg
,*srcreg
;
351 FETCH_DECODE_MODRM(m
,mod
,rh
,rl
);
355 destoffset
=decode_rm00_address(m
,rl
);
356 destval
= fetch_data_word(m
,destoffset
);
357 srcreg
= DECODE_RM_WORD_REGISTER(m
,rh
);
358 destval
= or_word(m
, destval
, *srcreg
);
359 store_data_word(m
,destoffset
,destval
);
362 destoffset
=decode_rm01_address(m
,rl
);
363 destval
= fetch_data_word(m
,destoffset
);
364 srcreg
= DECODE_RM_WORD_REGISTER(m
,rh
);
365 destval
= or_word(m
, destval
, *srcreg
);
366 store_data_word(m
,destoffset
,destval
);
369 destoffset
=decode_rm10_address(m
,rl
);
370 destval
= fetch_data_word(m
,destoffset
);
371 srcreg
= DECODE_RM_WORD_REGISTER(m
,rh
);
372 destval
= or_word(m
, destval
, *srcreg
);
373 store_data_word(m
,destoffset
,destval
);
375 case 3: /* register to register */
376 destreg
= DECODE_RM_WORD_REGISTER(m
,rl
);
377 srcreg
= DECODE_RM_WORD_REGISTER(m
,rh
);
378 *destreg
= or_word(m
, *destreg
, *srcreg
);
381 DECODE_CLEAR_SEGOVR(m
);
385 static void i86op_or_byte_R_RM(PC_ENV
*m
)
388 uint8
*destreg
,*srcreg
;
391 FETCH_DECODE_MODRM(m
,mod
,rh
,rl
);
395 destreg
= DECODE_RM_BYTE_REGISTER(m
,rh
);
396 srcoffset
=decode_rm00_address(m
,rl
);
397 srcval
= fetch_data_byte(m
,srcoffset
);
398 *destreg
= or_byte(m
, *destreg
, srcval
);
401 destreg
= DECODE_RM_BYTE_REGISTER(m
,rh
);
402 srcoffset
=decode_rm01_address(m
,rl
);
403 srcval
= fetch_data_byte(m
,srcoffset
);
404 *destreg
= or_byte(m
, *destreg
, srcval
);
407 destreg
= DECODE_RM_BYTE_REGISTER(m
,rh
);
408 srcoffset
=decode_rm10_address(m
,rl
);
409 srcval
= fetch_data_byte(m
,srcoffset
);
410 *destreg
= or_byte(m
, * destreg
, srcval
);
412 case 3: /* register to register */
413 destreg
= DECODE_RM_BYTE_REGISTER(m
,rh
);
414 srcreg
= DECODE_RM_BYTE_REGISTER(m
,rl
);
415 *destreg
= or_byte(m
, *destreg
, *srcreg
);
418 DECODE_CLEAR_SEGOVR(m
);
422 static void i86op_or_word_R_RM(PC_ENV
*m
)
425 uint16
*destreg
,*srcreg
;
428 FETCH_DECODE_MODRM(m
,mod
,rh
,rl
);
432 destreg
= DECODE_RM_WORD_REGISTER(m
,rh
);
433 srcoffset
=decode_rm00_address(m
,rl
);
434 srcval
= fetch_data_word(m
,srcoffset
);
435 *destreg
= or_word(m
, *destreg
, srcval
);
438 destreg
= DECODE_RM_WORD_REGISTER(m
,rh
);
439 srcoffset
=decode_rm01_address(m
,rl
);
440 srcval
= fetch_data_word(m
,srcoffset
);
441 *destreg
= or_word(m
, *destreg
, srcval
);
444 destreg
= DECODE_RM_WORD_REGISTER(m
,rh
);
445 srcoffset
=decode_rm10_address(m
,rl
);
446 srcval
= fetch_data_word(m
,srcoffset
);
447 *destreg
= or_word(m
, *destreg
, srcval
);
449 case 3: /* register to register */
450 destreg
= DECODE_RM_WORD_REGISTER(m
,rh
);
451 srcreg
= DECODE_RM_WORD_REGISTER(m
,rl
);
452 *destreg
= or_word(m
, *destreg
, *srcreg
);
455 DECODE_CLEAR_SEGOVR(m
);
459 static void i86op_or_byte_AL_IMM(PC_ENV
*m
)
462 srcval
= fetch_byte_imm(m
);
463 m
->R_AL
= or_byte(m
, m
->R_AL
, srcval
);
464 DECODE_CLEAR_SEGOVR(m
);
468 static void i86op_or_word_AX_IMM(PC_ENV
*m
)
471 srcval
= fetch_word_imm(m
);
472 m
->R_AX
= or_word(m
, m
->R_AX
, srcval
);
473 DECODE_CLEAR_SEGOVR(m
);
477 static void i86op_push_CS(PC_ENV
*m
)
479 push_word(m
,m
->R_CS
);
480 DECODE_CLEAR_SEGOVR(m
);
483 /*opcode=0x0f === ILLEGAL OP*/
486 static void i86op_adc_byte_RM_R(PC_ENV
*m
)
489 uint8
*destreg
,*srcreg
;
492 FETCH_DECODE_MODRM(m
,mod
,rh
,rl
);
496 destoffset
=decode_rm00_address(m
,rl
);
497 destval
= fetch_data_byte(m
,destoffset
);
498 srcreg
= DECODE_RM_BYTE_REGISTER(m
,rh
);
499 destval
= adc_byte(m
, destval
, *srcreg
);
500 store_data_byte(m
,destoffset
,destval
);
503 destoffset
=decode_rm01_address(m
,rl
);
504 destval
= fetch_data_byte(m
,destoffset
);
505 srcreg
= DECODE_RM_BYTE_REGISTER(m
,rh
);
506 destval
= adc_byte(m
, destval
, *srcreg
);
507 store_data_byte(m
,destoffset
,destval
);
510 destoffset
=decode_rm10_address(m
,rl
);
511 destval
= fetch_data_byte(m
,destoffset
);
512 srcreg
= DECODE_RM_BYTE_REGISTER(m
,rh
);
513 destval
= adc_byte(m
, destval
, *srcreg
);
514 store_data_byte(m
,destoffset
,destval
);
516 case 3: /* register to register */
517 destreg
= DECODE_RM_BYTE_REGISTER(m
,rl
);
518 srcreg
= DECODE_RM_BYTE_REGISTER(m
,rh
);
519 *destreg
= adc_byte(m
, *destreg
, *srcreg
);
522 DECODE_CLEAR_SEGOVR(m
);
526 static void i86op_adc_word_RM_R(PC_ENV
*m
)
529 uint16
*destreg
,*srcreg
;
532 FETCH_DECODE_MODRM(m
,mod
,rh
,rl
);
536 destoffset
=decode_rm00_address(m
,rl
);
537 destval
= fetch_data_word(m
,destoffset
);
538 srcreg
= DECODE_RM_WORD_REGISTER(m
,rh
);
539 destval
= adc_word(m
, destval
, *srcreg
);
540 store_data_word(m
,destoffset
,destval
);
543 destoffset
=decode_rm01_address(m
,rl
);
544 destval
= fetch_data_word(m
,destoffset
);
545 srcreg
= DECODE_RM_WORD_REGISTER(m
,rh
);
546 destval
= adc_word(m
, destval
, *srcreg
);
547 store_data_word(m
,destoffset
,destval
);
550 destoffset
=decode_rm10_address(m
,rl
);
551 destval
= fetch_data_word(m
,destoffset
);
552 srcreg
= DECODE_RM_WORD_REGISTER(m
,rh
);
553 destval
= adc_word(m
, destval
, *srcreg
);
554 store_data_word(m
,destoffset
,destval
);
556 case 3: /* register to register */
557 destreg
= DECODE_RM_WORD_REGISTER(m
,rl
);
558 srcreg
= DECODE_RM_WORD_REGISTER(m
,rh
);
559 *destreg
= adc_word(m
, *destreg
, *srcreg
);
562 DECODE_CLEAR_SEGOVR(m
);
566 static void i86op_adc_byte_R_RM(PC_ENV
*m
)
569 uint8
*destreg
,*srcreg
;
572 FETCH_DECODE_MODRM(m
,mod
,rh
,rl
);
576 destreg
= DECODE_RM_BYTE_REGISTER(m
,rh
);
577 srcoffset
=decode_rm00_address(m
,rl
);
578 srcval
= fetch_data_byte(m
,srcoffset
);
579 *destreg
= adc_byte(m
, *destreg
, srcval
);
582 destreg
= DECODE_RM_BYTE_REGISTER(m
,rh
);
583 srcoffset
=decode_rm01_address(m
,rl
);
584 srcval
= fetch_data_byte(m
,srcoffset
);
585 *destreg
= adc_byte(m
, *destreg
, srcval
);
588 destreg
= DECODE_RM_BYTE_REGISTER(m
,rh
);
589 srcoffset
=decode_rm10_address(m
,rl
);
590 srcval
= fetch_data_byte(m
,srcoffset
);
591 *destreg
= adc_byte(m
, * destreg
, srcval
);
593 case 3: /* register to register */
594 destreg
= DECODE_RM_BYTE_REGISTER(m
,rh
);
595 srcreg
= DECODE_RM_BYTE_REGISTER(m
,rl
);
596 *destreg
= adc_byte(m
, *destreg
, *srcreg
);
599 DECODE_CLEAR_SEGOVR(m
);
603 static void i86op_adc_word_R_RM(PC_ENV
*m
)
606 uint16
*destreg
,*srcreg
;
609 FETCH_DECODE_MODRM(m
,mod
,rh
,rl
);
613 destreg
= DECODE_RM_WORD_REGISTER(m
,rh
);
614 srcoffset
=decode_rm00_address(m
,rl
);
615 srcval
= fetch_data_word(m
,srcoffset
);
616 *destreg
= adc_word(m
, *destreg
, srcval
);
619 destreg
= DECODE_RM_WORD_REGISTER(m
,rh
);
620 srcoffset
=decode_rm01_address(m
,rl
);
621 srcval
= fetch_data_word(m
,srcoffset
);
622 *destreg
= adc_word(m
, *destreg
, srcval
);
625 destreg
= DECODE_RM_WORD_REGISTER(m
,rh
);
626 srcoffset
=decode_rm10_address(m
,rl
);
627 srcval
= fetch_data_word(m
,srcoffset
);
628 *destreg
= adc_word(m
, *destreg
, srcval
);
630 case 3: /* register to register */
631 destreg
= DECODE_RM_WORD_REGISTER(m
,rh
);
632 srcreg
= DECODE_RM_WORD_REGISTER(m
,rl
);
633 *destreg
= adc_word(m
, *destreg
, *srcreg
);
636 DECODE_CLEAR_SEGOVR(m
);
640 static void i86op_adc_byte_AL_IMM(PC_ENV
*m
)
643 srcval
= fetch_byte_imm(m
);
644 m
->R_AL
= adc_byte(m
, m
->R_AL
, srcval
);
645 DECODE_CLEAR_SEGOVR(m
);
649 static void i86op_adc_word_AX_IMM(PC_ENV
*m
)
652 srcval
= fetch_word_imm(m
);
653 m
->R_AX
= adc_word(m
, m
->R_AX
, srcval
);
654 DECODE_CLEAR_SEGOVR(m
);
658 static void i86op_push_SS(PC_ENV
*m
)
660 push_word(m
,m
->R_SS
);
661 DECODE_CLEAR_SEGOVR(m
);
665 static void i86op_pop_SS(PC_ENV
*m
)
667 m
->R_SS
= pop_word(m
);
668 DECODE_CLEAR_SEGOVR(m
);
672 static void i86op_sbb_byte_RM_R(PC_ENV
*m
)
675 uint8
*destreg
,*srcreg
;
678 FETCH_DECODE_MODRM(m
,mod
,rh
,rl
);
682 destoffset
=decode_rm00_address(m
,rl
);
683 destval
= fetch_data_byte(m
,destoffset
);
684 srcreg
= DECODE_RM_BYTE_REGISTER(m
,rh
);
685 destval
= sbb_byte(m
, destval
, *srcreg
);
686 store_data_byte(m
,destoffset
,destval
);
689 destoffset
=decode_rm01_address(m
,rl
);
690 destval
= fetch_data_byte(m
,destoffset
);
691 srcreg
= DECODE_RM_BYTE_REGISTER(m
,rh
);
692 destval
= sbb_byte(m
, destval
, *srcreg
);
693 store_data_byte(m
,destoffset
,destval
);
696 destoffset
=decode_rm10_address(m
,rl
);
697 destval
= fetch_data_byte(m
,destoffset
);
698 srcreg
= DECODE_RM_BYTE_REGISTER(m
,rh
);
699 destval
= sbb_byte(m
, destval
, *srcreg
);
700 store_data_byte(m
,destoffset
,destval
);
702 case 3: /* register to register */
703 destreg
= DECODE_RM_BYTE_REGISTER(m
,rl
);
704 srcreg
= DECODE_RM_BYTE_REGISTER(m
,rh
);
705 *destreg
= sbb_byte(m
, *destreg
, *srcreg
);
708 DECODE_CLEAR_SEGOVR(m
);
712 static void i86op_sbb_word_RM_R(PC_ENV
*m
)
715 uint16
*destreg
,*srcreg
;
718 FETCH_DECODE_MODRM(m
,mod
,rh
,rl
);
722 destoffset
=decode_rm00_address(m
,rl
);
723 destval
= fetch_data_word(m
,destoffset
);
724 srcreg
= DECODE_RM_WORD_REGISTER(m
,rh
);
725 destval
= sbb_word(m
, destval
, *srcreg
);
726 store_data_word(m
,destoffset
,destval
);
729 destoffset
=decode_rm01_address(m
,rl
);
730 destval
= fetch_data_word(m
,destoffset
);
731 srcreg
= DECODE_RM_WORD_REGISTER(m
,rh
);
732 destval
= sbb_word(m
, destval
, *srcreg
);
733 store_data_word(m
,destoffset
,destval
);
736 destoffset
=decode_rm10_address(m
,rl
);
737 destval
= fetch_data_word(m
,destoffset
);
738 srcreg
= DECODE_RM_WORD_REGISTER(m
,rh
);
739 destval
= sbb_word(m
, destval
, *srcreg
);
740 store_data_word(m
,destoffset
,destval
);
742 case 3: /* register to register */
743 destreg
= DECODE_RM_WORD_REGISTER(m
,rl
);
744 srcreg
= DECODE_RM_WORD_REGISTER(m
,rh
);
745 *destreg
= sbb_word(m
, *destreg
, *srcreg
);
748 DECODE_CLEAR_SEGOVR(m
);
752 static void i86op_sbb_byte_R_RM(PC_ENV
*m
)
755 uint8
*destreg
,*srcreg
;
758 FETCH_DECODE_MODRM(m
,mod
,rh
,rl
);
762 destreg
= DECODE_RM_BYTE_REGISTER(m
,rh
);
763 srcoffset
=decode_rm00_address(m
,rl
);
764 srcval
= fetch_data_byte(m
,srcoffset
);
765 *destreg
= sbb_byte(m
, *destreg
, srcval
);
768 destreg
= DECODE_RM_BYTE_REGISTER(m
,rh
);
769 srcoffset
=decode_rm01_address(m
,rl
);
770 srcval
= fetch_data_byte(m
,srcoffset
);
771 *destreg
= sbb_byte(m
, *destreg
, srcval
);
774 destreg
= DECODE_RM_BYTE_REGISTER(m
,rh
);
775 srcoffset
=decode_rm10_address(m
,rl
);
776 srcval
= fetch_data_byte(m
,srcoffset
);
777 *destreg
= sbb_byte(m
, * destreg
, srcval
);
779 case 3: /* register to register */
780 destreg
= DECODE_RM_BYTE_REGISTER(m
,rh
);
781 srcreg
= DECODE_RM_BYTE_REGISTER(m
,rl
);
782 *destreg
= sbb_byte(m
, *destreg
, *srcreg
);
785 DECODE_CLEAR_SEGOVR(m
);
789 static void i86op_sbb_word_R_RM(PC_ENV
*m
)
792 uint16
*destreg
,*srcreg
;
795 FETCH_DECODE_MODRM(m
,mod
,rh
,rl
);
799 destreg
= DECODE_RM_WORD_REGISTER(m
,rh
);
800 srcoffset
=decode_rm00_address(m
,rl
);
801 srcval
= fetch_data_word(m
,srcoffset
);
802 *destreg
= sbb_word(m
, *destreg
, srcval
);
805 destreg
= DECODE_RM_WORD_REGISTER(m
,rh
);
806 srcoffset
=decode_rm01_address(m
,rl
);
807 srcval
= fetch_data_word(m
,srcoffset
);
808 *destreg
= sbb_word(m
, *destreg
, srcval
);
811 destreg
= DECODE_RM_WORD_REGISTER(m
,rh
);
812 srcoffset
=decode_rm10_address(m
,rl
);
813 srcval
= fetch_data_word(m
,srcoffset
);
814 *destreg
= sbb_word(m
, *destreg
, srcval
);
816 case 3: /* register to register */
817 destreg
= DECODE_RM_WORD_REGISTER(m
,rh
);
818 srcreg
= DECODE_RM_WORD_REGISTER(m
,rl
);
819 *destreg
= sbb_word(m
, *destreg
, *srcreg
);
822 DECODE_CLEAR_SEGOVR(m
);
826 static void i86op_sbb_byte_AL_IMM(PC_ENV
*m
)
829 srcval
= fetch_byte_imm(m
);
830 m
->R_AL
= sbb_byte(m
, m
->R_AL
, srcval
);
831 DECODE_CLEAR_SEGOVR(m
);
835 static void i86op_sbb_word_AX_IMM(PC_ENV
*m
)
838 srcval
= fetch_word_imm(m
);
839 m
->R_AX
= sbb_word(m
, m
->R_AX
, srcval
);
840 DECODE_CLEAR_SEGOVR(m
);
844 static void i86op_push_DS(PC_ENV
*m
)
846 push_word(m
,m
->R_DS
);
847 DECODE_CLEAR_SEGOVR(m
);
851 static void i86op_pop_DS(PC_ENV
*m
)
853 m
->R_DS
= pop_word(m
);
854 DECODE_CLEAR_SEGOVR(m
);
858 static void i86op_and_byte_RM_R(PC_ENV
*m
)
861 uint8
*destreg
,*srcreg
;
864 FETCH_DECODE_MODRM(m
,mod
,rh
,rl
);
868 destoffset
=decode_rm00_address(m
,rl
);
869 destval
= fetch_data_byte(m
,destoffset
);
870 srcreg
= DECODE_RM_BYTE_REGISTER(m
,rh
);
871 destval
= and_byte(m
, destval
, *srcreg
);
872 store_data_byte(m
,destoffset
,destval
);
875 destoffset
=decode_rm01_address(m
,rl
);
876 destval
= fetch_data_byte(m
,destoffset
);
877 srcreg
= DECODE_RM_BYTE_REGISTER(m
,rh
);
878 destval
= and_byte(m
, destval
, *srcreg
);
879 store_data_byte(m
,destoffset
,destval
);
882 destoffset
=decode_rm10_address(m
,rl
);
883 destval
= fetch_data_byte(m
,destoffset
);
884 srcreg
= DECODE_RM_BYTE_REGISTER(m
,rh
);
885 destval
= and_byte(m
, destval
, *srcreg
);
886 store_data_byte(m
,destoffset
,destval
);
888 case 3: /* register to register */
889 destreg
= DECODE_RM_BYTE_REGISTER(m
,rl
);
890 srcreg
= DECODE_RM_BYTE_REGISTER(m
,rh
);
891 *destreg
= and_byte(m
, *destreg
, *srcreg
);
894 DECODE_CLEAR_SEGOVR(m
);
898 static void i86op_and_word_RM_R(PC_ENV
*m
)
901 uint16
*destreg
,*srcreg
;
904 FETCH_DECODE_MODRM(m
,mod
,rh
,rl
);
908 destoffset
=decode_rm00_address(m
,rl
);
909 destval
= fetch_data_word(m
,destoffset
);
910 srcreg
= DECODE_RM_WORD_REGISTER(m
,rh
);
911 destval
= and_word(m
, destval
, *srcreg
);
912 store_data_word(m
,destoffset
,destval
);
915 destoffset
=decode_rm01_address(m
,rl
);
916 destval
= fetch_data_word(m
,destoffset
);
917 srcreg
= DECODE_RM_WORD_REGISTER(m
,rh
);
918 destval
= and_word(m
, destval
, *srcreg
);
919 store_data_word(m
,destoffset
,destval
);
922 destoffset
=decode_rm10_address(m
,rl
);
923 destval
= fetch_data_word(m
,destoffset
);
924 srcreg
= DECODE_RM_WORD_REGISTER(m
,rh
);
925 destval
= and_word(m
, destval
, *srcreg
);
926 store_data_word(m
,destoffset
,destval
);
928 case 3: /* register to register */
929 destreg
= DECODE_RM_WORD_REGISTER(m
,rl
);
930 srcreg
= DECODE_RM_WORD_REGISTER(m
,rh
);
931 *destreg
= and_word(m
, *destreg
, *srcreg
);
934 DECODE_CLEAR_SEGOVR(m
);
938 static void i86op_and_byte_R_RM(PC_ENV
*m
)
941 uint8
*destreg
,*srcreg
;
944 FETCH_DECODE_MODRM(m
,mod
,rh
,rl
);
948 destreg
= DECODE_RM_BYTE_REGISTER(m
,rh
);
949 srcoffset
=decode_rm00_address(m
,rl
);
950 srcval
= fetch_data_byte(m
,srcoffset
);
951 *destreg
= and_byte(m
, *destreg
, srcval
);
954 destreg
= DECODE_RM_BYTE_REGISTER(m
,rh
);
955 srcoffset
=decode_rm01_address(m
,rl
);
956 srcval
= fetch_data_byte(m
,srcoffset
);
957 *destreg
= and_byte(m
, *destreg
, srcval
);
960 destreg
= DECODE_RM_BYTE_REGISTER(m
,rh
);
961 srcoffset
=decode_rm10_address(m
,rl
);
962 srcval
= fetch_data_byte(m
,srcoffset
);
963 *destreg
= and_byte(m
, * destreg
, srcval
);
965 case 3: /* register to register */
966 destreg
= DECODE_RM_BYTE_REGISTER(m
,rh
);
967 srcreg
= DECODE_RM_BYTE_REGISTER(m
,rl
);
968 *destreg
= and_byte(m
, *destreg
, *srcreg
);
971 DECODE_CLEAR_SEGOVR(m
);
975 static void i86op_and_word_R_RM(PC_ENV
*m
)
978 uint16
*destreg
,*srcreg
;
981 FETCH_DECODE_MODRM(m
,mod
,rh
,rl
);
985 destreg
= DECODE_RM_WORD_REGISTER(m
,rh
);
986 srcoffset
=decode_rm00_address(m
,rl
);
987 srcval
= fetch_data_word(m
,srcoffset
);
988 *destreg
= and_word(m
, *destreg
, srcval
);
991 destreg
= DECODE_RM_WORD_REGISTER(m
,rh
);
992 srcoffset
=decode_rm01_address(m
,rl
);
993 srcval
= fetch_data_word(m
,srcoffset
);
994 *destreg
= and_word(m
, *destreg
, srcval
);
997 destreg
= DECODE_RM_WORD_REGISTER(m
,rh
);
998 srcoffset
=decode_rm10_address(m
,rl
);
999 srcval
= fetch_data_word(m
,srcoffset
);
1000 *destreg
= and_word(m
, *destreg
, srcval
);
1002 case 3: /* register to register */
1003 destreg
= DECODE_RM_WORD_REGISTER(m
,rh
);
1004 srcreg
= DECODE_RM_WORD_REGISTER(m
,rl
);
1005 *destreg
= and_word(m
, *destreg
, *srcreg
);
1008 DECODE_CLEAR_SEGOVR(m
);
1012 static void i86op_and_byte_AL_IMM(PC_ENV
*m
)
1015 srcval
= fetch_byte_imm(m
);
1016 m
->R_AL
= and_byte(m
, m
->R_AL
, srcval
);
1017 DECODE_CLEAR_SEGOVR(m
);
1021 static void i86op_and_word_AX_IMM(PC_ENV
*m
)
1024 srcval
= fetch_word_imm(m
);
1025 m
->R_AX
= and_word(m
, m
->R_AX
, srcval
);
1026 DECODE_CLEAR_SEGOVR(m
);
1030 static void i86op_segovr_ES(PC_ENV
*m
)
1032 m
->sysmode
|= SYSMODE_SEGOVR_ES
;
1033 /* note the lack of DECODE_CLEAR_SEGOVR(r)
1034 since, here is one of 4 opcode subroutines we do not
1040 static void i86op_daa(PC_ENV
*m
)
1044 if (ACCESS_FLAG(m
,F_AF
)|| (dbyte
&0xf) > 9)
1052 CLEAR_FLAG(m
, F_AF
);
1053 if (ACCESS_FLAG(m
,F_CF
) || (dbyte
&0xf0) > 0x90)
1059 CLEAR_FLAG(m
, F_CF
);
1060 m
->R_AL
= (uint8
) dbyte
;
1061 CONDITIONAL_SET_FLAG((m
->R_AL
& 0x80),m
,F_SF
);
1062 CONDITIONAL_SET_FLAG((m
->R_AL
== 0), m
,F_ZF
);
1063 CONDITIONAL_SET_FLAG((parity_tab
[m
->R_AL
]),m
,F_PF
);
1064 DECODE_CLEAR_SEGOVR(m
);
1068 static void i86op_sub_byte_RM_R(PC_ENV
*m
)
1071 uint8
*destreg
,*srcreg
;
1074 FETCH_DECODE_MODRM(m
,mod
,rh
,rl
);
1078 destoffset
=decode_rm00_address(m
,rl
);
1079 destval
= fetch_data_byte(m
,destoffset
);
1080 srcreg
= DECODE_RM_BYTE_REGISTER(m
,rh
);
1081 destval
= sub_byte(m
, destval
, *srcreg
);
1082 store_data_byte(m
,destoffset
,destval
);
1085 destoffset
=decode_rm01_address(m
,rl
);
1086 destval
= fetch_data_byte(m
,destoffset
);
1087 srcreg
= DECODE_RM_BYTE_REGISTER(m
,rh
);
1088 destval
= sub_byte(m
, destval
, *srcreg
);
1089 store_data_byte(m
,destoffset
,destval
);
1092 destoffset
=decode_rm10_address(m
,rl
);
1093 destval
= fetch_data_byte(m
,destoffset
);
1094 srcreg
= DECODE_RM_BYTE_REGISTER(m
,rh
);
1095 destval
= sub_byte(m
, destval
, *srcreg
);
1096 store_data_byte(m
,destoffset
,destval
);
1098 case 3: /* register to register */
1099 destreg
= DECODE_RM_BYTE_REGISTER(m
,rl
);
1100 srcreg
= DECODE_RM_BYTE_REGISTER(m
,rh
);
1101 *destreg
= sub_byte(m
, *destreg
, *srcreg
);
1104 DECODE_CLEAR_SEGOVR(m
);
1108 static void i86op_sub_word_RM_R(PC_ENV
*m
)
1111 uint16
*destreg
,*srcreg
;
1114 FETCH_DECODE_MODRM(m
,mod
,rh
,rl
);
1118 destoffset
=decode_rm00_address(m
,rl
);
1119 destval
= fetch_data_word(m
,destoffset
);
1120 srcreg
= DECODE_RM_WORD_REGISTER(m
,rh
);
1121 destval
= sub_word(m
, destval
, *srcreg
);
1122 store_data_word(m
,destoffset
,destval
);
1125 destoffset
=decode_rm01_address(m
,rl
);
1126 destval
= fetch_data_word(m
,destoffset
);
1127 srcreg
= DECODE_RM_WORD_REGISTER(m
,rh
);
1128 destval
= sub_word(m
, destval
, *srcreg
);
1129 store_data_word(m
,destoffset
,destval
);
1132 destoffset
=decode_rm10_address(m
,rl
);
1133 destval
= fetch_data_word(m
,destoffset
);
1134 srcreg
= DECODE_RM_WORD_REGISTER(m
,rh
);
1135 destval
= sub_word(m
, destval
, *srcreg
);
1136 store_data_word(m
,destoffset
,destval
);
1138 case 3: /* register to register */
1139 destreg
= DECODE_RM_WORD_REGISTER(m
,rl
);
1140 srcreg
= DECODE_RM_WORD_REGISTER(m
,rh
);
1141 *destreg
= sub_word(m
, *destreg
, *srcreg
);
1144 DECODE_CLEAR_SEGOVR(m
);
1148 static void i86op_sub_byte_R_RM(PC_ENV
*m
)
1151 uint8
*destreg
,*srcreg
;
1154 FETCH_DECODE_MODRM(m
,mod
,rh
,rl
);
1158 destreg
= DECODE_RM_BYTE_REGISTER(m
,rh
);
1159 srcoffset
=decode_rm00_address(m
,rl
);
1160 srcval
= fetch_data_byte(m
,srcoffset
);
1161 *destreg
= sub_byte(m
, *destreg
, srcval
);
1164 destreg
= DECODE_RM_BYTE_REGISTER(m
,rh
);
1165 srcoffset
=decode_rm01_address(m
,rl
);
1166 srcval
= fetch_data_byte(m
,srcoffset
);
1167 *destreg
= sub_byte(m
, *destreg
, srcval
);
1170 destreg
= DECODE_RM_BYTE_REGISTER(m
,rh
);
1171 srcoffset
=decode_rm10_address(m
,rl
);
1172 srcval
= fetch_data_byte(m
,srcoffset
);
1173 *destreg
= sub_byte(m
, * destreg
, srcval
);
1175 case 3: /* register to register */
1176 destreg
= DECODE_RM_BYTE_REGISTER(m
,rh
);
1177 srcreg
= DECODE_RM_BYTE_REGISTER(m
,rl
);
1178 *destreg
= sub_byte(m
, *destreg
, *srcreg
);
1181 DECODE_CLEAR_SEGOVR(m
);
1185 static void i86op_sub_word_R_RM(PC_ENV
*m
)
1188 uint16
*destreg
,*srcreg
;
1191 FETCH_DECODE_MODRM(m
,mod
,rh
,rl
);
1195 destreg
= DECODE_RM_WORD_REGISTER(m
,rh
);
1196 srcoffset
=decode_rm00_address(m
,rl
);
1197 srcval
= fetch_data_word(m
,srcoffset
);
1198 *destreg
= sub_word(m
, *destreg
, srcval
);
1201 destreg
= DECODE_RM_WORD_REGISTER(m
,rh
);
1202 srcoffset
=decode_rm01_address(m
,rl
);
1203 srcval
= fetch_data_word(m
,srcoffset
);
1204 *destreg
= sub_word(m
, *destreg
, srcval
);
1207 destreg
= DECODE_RM_WORD_REGISTER(m
,rh
);
1208 srcoffset
=decode_rm10_address(m
,rl
);
1209 srcval
= fetch_data_word(m
,srcoffset
);
1210 *destreg
= sub_word(m
, *destreg
, srcval
);
1212 case 3: /* register to register */
1213 destreg
= DECODE_RM_WORD_REGISTER(m
,rh
);
1214 srcreg
= DECODE_RM_WORD_REGISTER(m
,rl
);
1215 *destreg
= sub_word(m
, *destreg
, *srcreg
);
1218 DECODE_CLEAR_SEGOVR(m
);
1222 static void i86op_sub_byte_AL_IMM(PC_ENV
*m
)
1225 srcval
= fetch_byte_imm(m
);
1226 m
->R_AL
= sub_byte(m
, m
->R_AL
, srcval
);
1227 DECODE_CLEAR_SEGOVR(m
);
1231 static void i86op_sub_word_AX_IMM(PC_ENV
*m
)
1234 srcval
= fetch_word_imm(m
);
1235 m
->R_AX
= sub_word(m
, m
->R_AX
, srcval
);
1236 DECODE_CLEAR_SEGOVR(m
);
1240 static void i86op_segovr_CS(PC_ENV
*m
)
1242 m
->sysmode
|= SYSMODE_SEGOVR_CS
;
1243 /* note no DECODE_CLEAR_SEGOVER here. */
1247 static void i86op_das(PC_ENV
*m
)
1251 if ( ACCESS_FLAG(m
,F_AF
) || (dbyte
&0xf) > 9)
1254 if (dbyte
&0x100) /* XXXXX --- this is WRONG */
1259 CLEAR_FLAG(m
, F_AF
);
1260 if (ACCESS_FLAG(m
,F_CF
) || (dbyte
&0xf0) > 0x90)
1266 CLEAR_FLAG(m
, F_CF
);
1267 m
->R_AL
= (uint8
) dbyte
;
1268 CONDITIONAL_SET_FLAG(m
->R_AL
& 0x80,m
,F_SF
);
1269 CONDITIONAL_SET_FLAG(m
->R_AL
== 0,m
,F_ZF
);
1270 CONDITIONAL_SET_FLAG(parity_tab
[m
->R_AL
],m
,F_PF
);
1271 DECODE_CLEAR_SEGOVR(m
);
1275 static void i86op_xor_byte_RM_R(PC_ENV
*m
)
1278 uint8
*destreg
,*srcreg
;
1281 FETCH_DECODE_MODRM(m
,mod
,rh
,rl
);
1285 destoffset
=decode_rm00_address(m
,rl
);
1286 destval
= fetch_data_byte(m
,destoffset
);
1287 srcreg
= DECODE_RM_BYTE_REGISTER(m
,rh
);
1288 destval
= xor_byte(m
, destval
, *srcreg
);
1289 store_data_byte(m
,destoffset
,destval
);
1292 destoffset
=decode_rm01_address(m
,rl
);
1293 destval
= fetch_data_byte(m
,destoffset
);
1294 srcreg
= DECODE_RM_BYTE_REGISTER(m
,rh
);
1295 destval
= xor_byte(m
, destval
, *srcreg
);
1296 store_data_byte(m
,destoffset
,destval
);
1299 destoffset
=decode_rm10_address(m
,rl
);
1300 destval
= fetch_data_byte(m
,destoffset
);
1301 srcreg
= DECODE_RM_BYTE_REGISTER(m
,rh
);
1302 destval
= xor_byte(m
, destval
, *srcreg
);
1303 store_data_byte(m
,destoffset
,destval
);
1305 case 3: /* register to register */
1306 destreg
= DECODE_RM_BYTE_REGISTER(m
,rl
);
1307 srcreg
= DECODE_RM_BYTE_REGISTER(m
,rh
);
1308 *destreg
= xor_byte(m
, *destreg
, *srcreg
);
1311 DECODE_CLEAR_SEGOVR(m
);
1315 static void i86op_xor_word_RM_R(PC_ENV
*m
)
1318 uint16
*destreg
,*srcreg
;
1321 FETCH_DECODE_MODRM(m
,mod
,rh
,rl
);
1325 destoffset
=decode_rm00_address(m
,rl
);
1326 destval
= fetch_data_word(m
,destoffset
);
1327 srcreg
= DECODE_RM_WORD_REGISTER(m
,rh
);
1328 destval
= xor_word(m
, destval
, *srcreg
);
1329 store_data_word(m
,destoffset
,destval
);
1332 destoffset
=decode_rm01_address(m
,rl
);
1333 destval
= fetch_data_word(m
,destoffset
);
1334 srcreg
= DECODE_RM_WORD_REGISTER(m
,rh
);
1335 destval
= xor_word(m
, destval
, *srcreg
);
1336 store_data_word(m
,destoffset
,destval
);
1339 destoffset
=decode_rm10_address(m
,rl
);
1340 destval
= fetch_data_word(m
,destoffset
);
1341 srcreg
= DECODE_RM_WORD_REGISTER(m
,rh
);
1342 destval
= xor_word(m
, destval
, *srcreg
);
1343 store_data_word(m
,destoffset
,destval
);
1345 case 3: /* register to register */
1346 destreg
= DECODE_RM_WORD_REGISTER(m
,rl
);
1347 srcreg
= DECODE_RM_WORD_REGISTER(m
,rh
);
1348 *destreg
= xor_word(m
, *destreg
, *srcreg
);
1351 DECODE_CLEAR_SEGOVR(m
);
1355 static void i86op_xor_byte_R_RM(PC_ENV
*m
)
1358 uint8
*destreg
,*srcreg
;
1361 FETCH_DECODE_MODRM(m
,mod
,rh
,rl
);
1365 destreg
= DECODE_RM_BYTE_REGISTER(m
,rh
);
1366 srcoffset
=decode_rm00_address(m
,rl
);
1367 srcval
= fetch_data_byte(m
,srcoffset
);
1368 *destreg
= xor_byte(m
, *destreg
, srcval
);
1371 destreg
= DECODE_RM_BYTE_REGISTER(m
,rh
);
1372 srcoffset
=decode_rm01_address(m
,rl
);
1373 srcval
= fetch_data_byte(m
,srcoffset
);
1374 *destreg
= xor_byte(m
, *destreg
, srcval
);
1377 destreg
= DECODE_RM_BYTE_REGISTER(m
,rh
);
1378 srcoffset
=decode_rm10_address(m
,rl
);
1379 srcval
= fetch_data_byte(m
,srcoffset
);
1380 *destreg
= xor_byte(m
, *destreg
, srcval
);
1382 case 3: /* register to register */
1383 destreg
= DECODE_RM_BYTE_REGISTER(m
,rh
);
1384 srcreg
= DECODE_RM_BYTE_REGISTER(m
,rl
);
1385 *destreg
= xor_byte(m
, *destreg
, *srcreg
);
1388 DECODE_CLEAR_SEGOVR(m
);
1392 static void i86op_xor_word_R_RM(PC_ENV
*m
)
1395 uint16
*destreg
,*srcreg
;
1398 FETCH_DECODE_MODRM(m
,mod
,rh
,rl
);
1402 destreg
= DECODE_RM_WORD_REGISTER(m
,rh
);
1403 srcoffset
=decode_rm00_address(m
,rl
);
1404 srcval
= fetch_data_word(m
,srcoffset
);
1405 *destreg
= xor_word(m
, *destreg
, srcval
);
1408 destreg
= DECODE_RM_WORD_REGISTER(m
,rh
);
1409 srcoffset
=decode_rm01_address(m
,rl
);
1410 srcval
= fetch_data_word(m
,srcoffset
);
1411 *destreg
= xor_word(m
, *destreg
, srcval
);
1414 destreg
= DECODE_RM_WORD_REGISTER(m
,rh
);
1415 srcoffset
=decode_rm10_address(m
,rl
);
1416 srcval
= fetch_data_word(m
,srcoffset
);
1417 *destreg
= xor_word(m
, *destreg
, srcval
);
1419 case 3: /* register to register */
1420 destreg
= DECODE_RM_WORD_REGISTER(m
,rh
);
1421 srcreg
= DECODE_RM_WORD_REGISTER(m
,rl
);
1422 *destreg
= xor_word(m
, *destreg
, *srcreg
);
1425 DECODE_CLEAR_SEGOVR(m
);
1429 static void i86op_xor_byte_AL_IMM(PC_ENV
*m
)
1432 srcval
= fetch_byte_imm(m
);
1433 m
->R_AL
= xor_byte(m
, m
->R_AL
, srcval
);
1434 DECODE_CLEAR_SEGOVR(m
);
1438 static void i86op_xor_word_AX_IMM(PC_ENV
*m
)
1441 srcval
= fetch_word_imm(m
);
1442 m
->R_AX
= xor_word(m
, m
->R_AX
, srcval
);
1443 DECODE_CLEAR_SEGOVR(m
);
1447 static void i86op_segovr_SS(PC_ENV
*m
)
1449 m
->sysmode
|= SYSMODE_SEGOVR_SS
;
1450 /* no DECODE_CLEAR_SEGOVER ! */
1454 static void i86op_aaa(PC_ENV
*m
)
1456 if ( (m
->R_AL
& 0xf) > 0x9 || ACCESS_FLAG(m
,F_AF
))
1465 CLEAR_FLAG(m
, F_CF
);
1466 CLEAR_FLAG(m
, F_AF
);
1469 DECODE_CLEAR_SEGOVR(m
);
1473 static void i86op_cmp_byte_RM_R(PC_ENV
*m
)
1476 uint8
*destreg
,*srcreg
;
1479 FETCH_DECODE_MODRM(m
,mod
,rh
,rl
);
1483 destoffset
=decode_rm00_address(m
,rl
);
1484 destval
= fetch_data_byte(m
,destoffset
);
1485 srcreg
= DECODE_RM_BYTE_REGISTER(m
,rh
);
1486 cmp_byte(m
, destval
, *srcreg
);
1489 destoffset
=decode_rm01_address(m
,rl
);
1490 destval
= fetch_data_byte(m
,destoffset
);
1491 srcreg
= DECODE_RM_BYTE_REGISTER(m
,rh
);
1492 cmp_byte(m
, destval
, *srcreg
);
1495 destoffset
=decode_rm10_address(m
,rl
);
1496 destval
= fetch_data_byte(m
,destoffset
);
1497 srcreg
= DECODE_RM_BYTE_REGISTER(m
,rh
);
1498 cmp_byte(m
, destval
, *srcreg
);
1500 case 3: /* register to register */
1501 destreg
= DECODE_RM_BYTE_REGISTER(m
,rl
);
1502 srcreg
= DECODE_RM_BYTE_REGISTER(m
,rh
);
1503 cmp_byte(m
, *destreg
, *srcreg
);
1506 DECODE_CLEAR_SEGOVR(m
);
1510 static void i86op_cmp_word_RM_R(PC_ENV
*m
)
1513 uint16
*destreg
,*srcreg
;
1516 FETCH_DECODE_MODRM(m
,mod
,rh
,rl
);
1520 destoffset
=decode_rm00_address(m
,rl
);
1521 destval
= fetch_data_word(m
,destoffset
);
1522 srcreg
= DECODE_RM_WORD_REGISTER(m
,rh
);
1523 cmp_word(m
, destval
, *srcreg
);
1526 destoffset
=decode_rm01_address(m
,rl
);
1527 destval
= fetch_data_word(m
,destoffset
);
1528 srcreg
= DECODE_RM_WORD_REGISTER(m
,rh
);
1529 cmp_word(m
, destval
, *srcreg
);
1532 destoffset
=decode_rm10_address(m
,rl
);
1533 destval
= fetch_data_word(m
,destoffset
);
1534 srcreg
= DECODE_RM_WORD_REGISTER(m
,rh
);
1535 cmp_word(m
, destval
, *srcreg
);
1537 case 3: /* register to register */
1538 destreg
= DECODE_RM_WORD_REGISTER(m
,rl
);
1539 srcreg
= DECODE_RM_WORD_REGISTER(m
,rh
);
1540 cmp_word(m
, *destreg
, *srcreg
);
1543 DECODE_CLEAR_SEGOVR(m
);
1547 static void i86op_cmp_byte_R_RM(PC_ENV
*m
)
1550 uint8
*destreg
,*srcreg
;
1553 FETCH_DECODE_MODRM(m
,mod
,rh
,rl
);
1557 destreg
= DECODE_RM_BYTE_REGISTER(m
,rh
);
1558 srcoffset
=decode_rm00_address(m
,rl
);
1559 srcval
= fetch_data_byte(m
,srcoffset
);
1560 cmp_byte(m
, *destreg
, srcval
);
1563 destreg
= DECODE_RM_BYTE_REGISTER(m
,rh
);
1564 srcoffset
=decode_rm01_address(m
,rl
);
1565 srcval
= fetch_data_byte(m
,srcoffset
);
1566 cmp_byte(m
, *destreg
, srcval
);
1569 destreg
= DECODE_RM_BYTE_REGISTER(m
,rh
);
1570 srcoffset
=decode_rm10_address(m
,rl
);
1571 srcval
= fetch_data_byte(m
,srcoffset
);
1572 cmp_byte(m
, * destreg
, srcval
);
1574 case 3: /* register to register */
1575 destreg
= DECODE_RM_BYTE_REGISTER(m
,rh
);
1576 srcreg
= DECODE_RM_BYTE_REGISTER(m
,rl
);
1577 cmp_byte(m
, *destreg
, *srcreg
);
1580 DECODE_CLEAR_SEGOVR(m
);
1584 static void i86op_cmp_word_R_RM(PC_ENV
*m
)
1587 uint16
*destreg
,*srcreg
;
1590 FETCH_DECODE_MODRM(m
,mod
,rh
,rl
);
1594 destreg
= DECODE_RM_WORD_REGISTER(m
,rh
);
1595 srcoffset
=decode_rm00_address(m
,rl
);
1596 srcval
= fetch_data_word(m
,srcoffset
);
1597 cmp_word(m
, *destreg
, srcval
);
1600 destreg
= DECODE_RM_WORD_REGISTER(m
,rh
);
1601 srcoffset
=decode_rm01_address(m
,rl
);
1602 srcval
= fetch_data_word(m
,srcoffset
);
1603 cmp_word(m
, *destreg
, srcval
);
1606 destreg
= DECODE_RM_WORD_REGISTER(m
,rh
);
1607 srcoffset
=decode_rm10_address(m
,rl
);
1608 srcval
= fetch_data_word(m
,srcoffset
);
1609 cmp_word(m
, *destreg
, srcval
);
1611 case 3: /* register to register */
1612 destreg
= DECODE_RM_WORD_REGISTER(m
,rh
);
1613 srcreg
= DECODE_RM_WORD_REGISTER(m
,rl
);
1614 cmp_word(m
, *destreg
, *srcreg
);
1617 DECODE_CLEAR_SEGOVR(m
);
1621 static void i86op_cmp_byte_AL_IMM(PC_ENV
*m
)
1624 srcval
= fetch_byte_imm(m
);
1625 cmp_byte(m
, m
->R_AL
, srcval
);
1626 DECODE_CLEAR_SEGOVR(m
);
1630 static void i86op_cmp_word_AX_IMM(PC_ENV
*m
)
1633 srcval
= fetch_word_imm(m
);
1634 cmp_word(m
, m
->R_AX
, srcval
);
1635 DECODE_CLEAR_SEGOVR(m
);
1639 static void i86op_segovr_DS(PC_ENV
*m
)
1641 m
->sysmode
|= SYSMODE_SEGOVR_DS
;
1642 /* NO DECODE_CLEAR_SEGOVR! */
1646 static void i86op_aas(PC_ENV
*m
)
1648 /* ???? Check out the subtraction here. Will this ?ever? cause
1649 the contents of R_AL or R_AH to be affected incorrectly since
1650 they are being subtracted from *and* are unsigned.
1651 Should put an assertion in here.
1653 if ( (m
->R_AL
& 0xf) > 0x9 || ACCESS_FLAG(m
,F_AF
))
1662 CLEAR_FLAG(m
, F_CF
);
1663 CLEAR_FLAG(m
, F_AF
);
1666 DECODE_CLEAR_SEGOVR(m
);
1670 static void i86op_inc_AX(PC_ENV
*m
)
1672 m
->R_AX
= inc_word(m
,m
->R_AX
);
1673 DECODE_CLEAR_SEGOVR(m
);
1677 static void i86op_inc_CX(PC_ENV
*m
)
1679 m
->R_CX
= inc_word(m
,m
->R_CX
);
1680 DECODE_CLEAR_SEGOVR(m
);
1684 static void i86op_inc_DX(PC_ENV
*m
)
1686 m
->R_DX
= inc_word(m
,m
->R_DX
);
1687 DECODE_CLEAR_SEGOVR(m
);
1691 static void i86op_inc_BX(PC_ENV
*m
)
1693 m
->R_BX
= inc_word(m
,m
->R_BX
);
1694 DECODE_CLEAR_SEGOVR(m
);
1698 static void i86op_inc_SP(PC_ENV
*m
)
1700 m
->R_SP
= inc_word(m
,m
->R_SP
);
1701 DECODE_CLEAR_SEGOVR(m
);
1705 static void i86op_inc_BP(PC_ENV
*m
)
1707 m
->R_BP
= inc_word(m
,m
->R_BP
);
1708 DECODE_CLEAR_SEGOVR(m
);
1712 static void i86op_inc_SI(PC_ENV
*m
)
1714 m
->R_SI
= inc_word(m
,m
->R_SI
);
1715 DECODE_CLEAR_SEGOVR(m
);
1719 static void i86op_inc_DI(PC_ENV
*m
)
1721 m
->R_DI
= inc_word(m
,m
->R_DI
);
1722 DECODE_CLEAR_SEGOVR(m
);
1726 static void i86op_dec_AX(PC_ENV
*m
)
1728 m
->R_AX
= dec_word(m
,m
->R_AX
);
1729 DECODE_CLEAR_SEGOVR(m
);
1733 static void i86op_dec_CX(PC_ENV
*m
)
1735 m
->R_CX
= dec_word(m
,m
->R_CX
);
1736 DECODE_CLEAR_SEGOVR(m
);
1740 static void i86op_dec_DX(PC_ENV
*m
)
1742 m
->R_DX
= dec_word(m
,m
->R_DX
);
1743 DECODE_CLEAR_SEGOVR(m
);
1747 static void i86op_dec_BX(PC_ENV
*m
)
1749 m
->R_BX
= dec_word(m
,m
->R_BX
);
1750 DECODE_CLEAR_SEGOVR(m
);
1754 static void i86op_dec_SP(PC_ENV
*m
)
1756 m
->R_SP
= dec_word(m
,m
->R_SP
);
1757 DECODE_CLEAR_SEGOVR(m
);
1761 static void i86op_dec_BP(PC_ENV
*m
)
1763 m
->R_BP
= dec_word(m
,m
->R_BP
);
1764 DECODE_CLEAR_SEGOVR(m
);
1768 static void i86op_dec_SI(PC_ENV
*m
)
1770 m
->R_SI
= dec_word(m
,m
->R_SI
);
1771 DECODE_CLEAR_SEGOVR(m
);
1775 static void i86op_dec_DI(PC_ENV
*m
)
1777 m
->R_DI
= dec_word(m
,m
->R_DI
);
1778 DECODE_CLEAR_SEGOVR(m
);
1782 static void i86op_push_AX(PC_ENV
*m
)
1784 push_word(m
,m
->R_AX
);
1785 DECODE_CLEAR_SEGOVR(m
);
1789 static void i86op_push_CX(PC_ENV
*m
)
1791 push_word(m
,m
->R_CX
);
1792 DECODE_CLEAR_SEGOVR(m
);
1796 static void i86op_push_DX(PC_ENV
*m
)
1798 push_word(m
,m
->R_DX
);
1799 DECODE_CLEAR_SEGOVR(m
);
1803 static void i86op_push_BX(PC_ENV
*m
)
1805 push_word(m
,m
->R_BX
);
1806 DECODE_CLEAR_SEGOVR(m
);
1810 static void i86op_push_SP(PC_ENV
*m
)
1812 /* .... Note this weirdness: One book I have access to
1813 claims that the value pushed here is actually sp-2. I.e.
1814 it decrements the stackpointer, and then pushes it. The 286
1815 I have does it this way. Changing this causes many problems.*/
1816 /* changed to push SP-2, since this *IS* how a 8088 does this */
1817 push_word(m
,m
->R_SP
-2);
1818 DECODE_CLEAR_SEGOVR(m
);
1822 static void i86op_push_BP(PC_ENV
*m
)
1824 push_word(m
,m
->R_BP
);
1825 DECODE_CLEAR_SEGOVR(m
);
1829 static void i86op_push_SI(PC_ENV
*m
)
1831 push_word(m
,m
->R_SI
);
1832 DECODE_CLEAR_SEGOVR(m
);
1836 static void i86op_push_DI(PC_ENV
*m
)
1838 push_word(m
,m
->R_DI
);
1839 DECODE_CLEAR_SEGOVR(m
);
1843 static void i86op_pop_AX(PC_ENV
*m
)
1845 m
->R_AX
= pop_word(m
);
1846 DECODE_CLEAR_SEGOVR(m
);
1850 static void i86op_pop_CX(PC_ENV
*m
)
1852 m
->R_CX
= pop_word(m
);
1853 DECODE_CLEAR_SEGOVR(m
);
1857 static void i86op_pop_DX(PC_ENV
*m
)
1859 m
->R_DX
= pop_word(m
);
1860 DECODE_CLEAR_SEGOVR(m
);
1864 static void i86op_pop_BX(PC_ENV
*m
)
1866 m
->R_BX
= pop_word(m
);
1867 DECODE_CLEAR_SEGOVR(m
);
1871 static void i86op_pop_SP(PC_ENV
*m
)
1873 m
->R_SP
= pop_word(m
);
1874 DECODE_CLEAR_SEGOVR(m
);
1878 static void i86op_pop_BP(PC_ENV
*m
)
1880 m
->R_BP
= pop_word(m
);
1881 DECODE_CLEAR_SEGOVR(m
);
1885 static void i86op_pop_SI(PC_ENV
*m
)
1887 m
->R_SI
= pop_word(m
);
1888 DECODE_CLEAR_SEGOVR(m
);
1892 static void i86op_pop_DI(PC_ENV
*m
)
1894 m
->R_DI
= pop_word(m
);
1895 DECODE_CLEAR_SEGOVR(m
);
1898 /*opcode=0x60 ILLEGAL OP, calls i86op_illegal_op() */
1899 /*opcode=0x61 ILLEGAL OP, calls i86op_illegal_op() */
1900 /*opcode=0x62 ILLEGAL OP, calls i86op_illegal_op() */
1901 /*opcode=0x63 ILLEGAL OP, calls i86op_illegal_op() */
1902 /*opcode=0x64 ILLEGAL OP, calls i86op_illegal_op() */
1903 /*opcode=0x65 ILLEGAL OP, calls i86op_illegal_op() */
1904 /*opcode=0x66 ILLEGAL OP, calls i86op_illegal_op() */
1905 /*opcode=0x67 ILLEGAL OP, calls i86op_illegal_op() */
1906 /*opcode=0x68 ILLEGAL OP, calls i86op_illegal_op() */
1907 /*opcode=0x69 ILLEGAL OP, calls i86op_illegal_op() */
1908 /*opcode=0x6a ILLEGAL OP, calls i86op_illegal_op() */
1909 /*opcode=0x6b ILLEGAL OP, calls i86op_illegal_op() */
1910 /*opcode=0x6c ILLEGAL OP, calls i86op_illegal_op() */
1911 /*opcode=0x6d ILLEGAL OP, calls i86op_illegal_op() */
1912 /*opcode=0x6e ILLEGAL OP, calls i86op_illegal_op() */
1913 /*opcode=0x6f ILLEGAL OP, calls i86op_illegal_op() */
1916 static void i86op_jump_near_O(PC_ENV
*m
)
1920 /* jump to byte offset if overflow flag is set */
1921 offset
= (int8
) fetch_byte_imm(m
);
1922 target
= (int16
)(m
->R_IP
) + offset
;
1923 if (ACCESS_FLAG(m
,F_OF
))
1925 DECODE_CLEAR_SEGOVR(m
);
1929 static void i86op_jump_near_NO(PC_ENV
*m
)
1933 /* jump to byte offset if overflow is not set */
1934 offset
= (int8
) fetch_byte_imm(m
);
1935 target
= (int16
)(m
->R_IP
) + offset
;
1936 if (!ACCESS_FLAG(m
,F_OF
))
1938 DECODE_CLEAR_SEGOVR(m
);
1942 static void i86op_jump_near_B(PC_ENV
*m
)
1946 /* jump to byte offset if carry flag is set. */
1947 offset
= (int8
)fetch_byte_imm(m
); /* sign extended ??? */
1948 target
= (int16
)(m
->R_IP
) + offset
;
1949 if (ACCESS_FLAG(m
, F_CF
))
1951 DECODE_CLEAR_SEGOVR(m
);
1955 static void i86op_jump_near_NB(PC_ENV
*m
)
1959 /* jump to byte offset if carry flag is clear. */
1960 offset
= (int8
)fetch_byte_imm(m
); /* sign extended ??? */
1961 target
= (int16
)(m
->R_IP
) + offset
;
1962 if (!ACCESS_FLAG(m
,F_CF
))
1964 DECODE_CLEAR_SEGOVR(m
);
1968 static void i86op_jump_near_Z(PC_ENV
*m
)
1972 /* jump to byte offset if zero flag is set. */
1973 offset
= (int8
)fetch_byte_imm(m
);
1974 target
= (int16
)(m
->R_IP
) + offset
;
1975 if (ACCESS_FLAG(m
, F_ZF
))
1977 DECODE_CLEAR_SEGOVR(m
);
1981 static void i86op_jump_near_NZ(PC_ENV
*m
)
1985 /* jump to byte offset if zero flag is clear. */
1986 offset
= (int8
)fetch_byte_imm(m
);
1987 target
= (int16
)(m
->R_IP
) + offset
;
1988 if (!ACCESS_FLAG(m
, F_ZF
))
1990 DECODE_CLEAR_SEGOVR(m
);
1994 static void i86op_jump_near_BE(PC_ENV
*m
)
1998 /* jump to byte offset if carry flag is set or if the zero
2000 offset
= (int8
)fetch_byte_imm(m
);
2001 target
= (int16
)(m
->R_IP
) + offset
;
2002 if (ACCESS_FLAG(m
,F_CF
) || ACCESS_FLAG(m
,F_ZF
))
2004 DECODE_CLEAR_SEGOVR(m
);
2008 static void i86op_jump_near_NBE(PC_ENV
*m
)
2012 /* jump to byte offset if carry flag is clear and if the zero
2014 offset
= (int8
)fetch_byte_imm(m
);
2015 target
= (int16
)(m
->R_IP
) + offset
;
2016 if (!(ACCESS_FLAG(m
,F_CF
)||ACCESS_FLAG(m
,F_ZF
)))
2018 DECODE_CLEAR_SEGOVR(m
);
2022 static void i86op_jump_near_S(PC_ENV
*m
)
2026 /* jump to byte offset if sign flag is set */
2027 offset
= (int8
)fetch_byte_imm(m
);
2028 target
= (int16
)(m
->R_IP
) + offset
;
2029 if (ACCESS_FLAG(m
,F_SF
))
2031 DECODE_CLEAR_SEGOVR(m
);
2035 static void i86op_jump_near_NS(PC_ENV
*m
)
2039 /* jump to byte offset if sign flag is clear */
2040 offset
= (int8
)fetch_byte_imm(m
);
2041 target
= (int16
)(m
->R_IP
) + offset
;
2042 if (!ACCESS_FLAG(m
,F_SF
))
2044 DECODE_CLEAR_SEGOVR(m
);
2048 static void i86op_jump_near_P(PC_ENV
*m
)
2052 /* jump to byte offset if parity flag is set (even parity) */
2053 offset
= (int8
)fetch_byte_imm(m
);
2054 target
= (int16
)(m
->R_IP
) + offset
;
2055 if (ACCESS_FLAG(m
, F_PF
))
2057 DECODE_CLEAR_SEGOVR(m
);
2061 static void i86op_jump_near_NP(PC_ENV
*m
)
2065 /* jump to byte offset if parity flag is clear (odd parity) */
2066 offset
= (int8
)fetch_byte_imm(m
);
2067 target
= (int16
)(m
->R_IP
) + offset
;
2068 if (!ACCESS_FLAG(m
, F_PF
))
2070 DECODE_CLEAR_SEGOVR(m
);
2073 /* JHH fixed till here... */
2076 static void i86op_jump_near_L(PC_ENV
*m
)
2081 /* jump to byte offset if sign flag not equal to overflow flag. */
2082 offset
= (int8
)fetch_byte_imm(m
);
2083 target
= (int16
)(m
->R_IP
) + offset
;
2085 * this is the simplest expression i could think of which
2086 * expresses SF != OF. m->R_FLG&F_SF either equals x80 or x00.
2087 * Similarly m->R_FLG&F_OF either equals x800 or x000.
2088 * The former shifted right by 7 puts a 1 or 0 in bit 0.
2089 * The latter shifter right by 11 puts a 1 or 0 in bit 0.
2090 * if the two expressions are the same, i.e. equal, then
2091 * a zero results from the xor. If they are not equal,
2092 * then a 1 results, and the jump is taken.
2094 sf
= ACCESS_FLAG(m
,F_SF
) != 0;
2095 of
= ACCESS_FLAG(m
,F_OF
) != 0;
2096 /* was: if ( ((m->R_FLG & F_SF)>>7) ^ ((m->R_FLG & F_OF) >> 11))*/
2099 DECODE_CLEAR_SEGOVR(m
);
2103 static void i86op_jump_near_NL(PC_ENV
*m
)
2108 /* jump to byte offset if sign flag not equal to overflow flag. */
2109 offset
= (int8
)fetch_byte_imm(m
);
2110 target
= (int16
)(m
->R_IP
) + offset
;
2111 sf
= ACCESS_FLAG(m
,F_SF
) != 0;
2112 of
= ACCESS_FLAG(m
,F_OF
) != 0;
2113 /* note: inverse of above, but using == instead of xor. */
2114 /* was: if (((m->R_FLG & F_SF)>>7) == ((m->R_FLG & F_OF) >> 11))*/
2117 DECODE_CLEAR_SEGOVR(m
);
2121 static void i86op_jump_near_LE(PC_ENV
*m
)
2126 /* jump to byte offset if sign flag not equal to overflow flag
2127 or the zero flag is set */
2128 offset
= (int8
)fetch_byte_imm(m
);
2129 target
= (int16
)(m
->R_IP
) + offset
;
2130 sf
= ACCESS_FLAG(m
,F_SF
) != 0;
2131 of
= ACCESS_FLAG(m
,F_OF
) != 0;
2132 /* note: modification of JL */
2134 /* was: if ((((m->R_FLG & F_SF)>>7) ^ ((m->R_FLG & F_OF) >> 11))
2135 || (m->R_FLG & F_ZF) ) */
2136 if ( (sf
^ of
) || ACCESS_FLAG(m
,F_ZF
))
2138 DECODE_CLEAR_SEGOVR(m
);
2142 static void i86op_jump_near_NLE(PC_ENV
*m
)
2147 /* jump to byte offset if sign flag equal to overflow flag.
2148 and the zero flag is clear*/
2149 offset
= (int8
)fetch_byte_imm(m
);
2150 target
= (int16
)(m
->R_IP
) + offset
;
2151 sf
= ACCESS_FLAG(m
,F_SF
) != 0;
2152 of
= ACCESS_FLAG(m
,F_OF
) != 0;
2154 /* if (((m->R_FLG & F_SF)>>7) == ((m->R_FLG & F_OF) >> 11)
2155 && (!(m->R_FLG & F_ZF))) */
2156 if ( ( sf
== of
) && !ACCESS_FLAG(m
,F_ZF
))
2158 DECODE_CLEAR_SEGOVR(m
);
2161 static uint8 (*opc80_byte_operation
[])(PC_ENV
*m
,uint8 d
,uint8 s
) =
2174 static void i86op_opc80_byte_RM_IMM(PC_ENV
*m
)
2181 /* weirdo special case instruction format. Part of the
2182 opcode held below in "RH". Doubly nested case would
2183 result, except that the decoded instruction
2185 FETCH_DECODE_MODRM(m
,mod
,rh
,rl
);
2186 /* know operation, decode the mod byte to find the addressing
2191 destoffset
=decode_rm00_address(m
,rl
);
2192 destval
= fetch_data_byte(m
,destoffset
);
2193 imm
= fetch_byte_imm(m
);
2194 destval
= (*opc80_byte_operation
[rh
])(m
, destval
, imm
);
2195 if (rh
!= 7) store_data_byte(m
,destoffset
,destval
);
2198 destoffset
=decode_rm01_address(m
,rl
);
2199 destval
= fetch_data_byte(m
,destoffset
);
2200 imm
= fetch_byte_imm(m
);
2201 destval
= (*opc80_byte_operation
[rh
])(m
, destval
, imm
);
2202 if (rh
!= 7) store_data_byte(m
,destoffset
,destval
);
2205 destoffset
=decode_rm10_address(m
,rl
);
2206 destval
= fetch_data_byte(m
,destoffset
);
2207 imm
= fetch_byte_imm(m
);
2208 destval
= (*opc80_byte_operation
[rh
])(m
, destval
, imm
);
2209 if (rh
!= 7) store_data_byte(m
,destoffset
,destval
);
2211 case 3: /* register to register */
2212 destreg
= DECODE_RM_BYTE_REGISTER(m
,rl
);
2213 imm
= fetch_byte_imm(m
);
2214 destval
= (*opc80_byte_operation
[rh
])(m
, *destreg
, imm
);
2215 if (rh
!= 7) *destreg
= destval
;
2218 DECODE_CLEAR_SEGOVR(m
);
2221 static uint16 (*opc81_word_operation
[])(PC_ENV
*m
,uint16 d
,uint16 s
) =
2233 static void i86op_opc81_word_RM_IMM(PC_ENV
*m
)
2240 /* weirdo special case instruction format. Part of the
2241 opcode held below in "RH". Doubly nested case would
2242 result, except that the decoded instruction
2244 FETCH_DECODE_MODRM(m
,mod
,rh
,rl
);
2245 /* know operation, decode the mod byte to find the addressing
2250 destoffset
=decode_rm00_address(m
,rl
);
2251 destval
= fetch_data_word(m
,destoffset
);
2252 imm
= fetch_word_imm(m
);
2253 destval
= (*opc81_word_operation
[rh
])(m
, destval
, imm
);
2254 if (rh
!= 7) store_data_word(m
,destoffset
,destval
);
2257 destoffset
=decode_rm01_address(m
,rl
);
2258 destval
= fetch_data_word(m
,destoffset
);
2259 imm
= fetch_word_imm(m
);
2260 destval
= (*opc81_word_operation
[rh
])(m
, destval
, imm
);
2261 if (rh
!= 7) store_data_word(m
,destoffset
,destval
);
2264 destoffset
=decode_rm10_address(m
,rl
);
2265 destval
= fetch_data_word(m
,destoffset
);
2266 imm
= fetch_word_imm(m
);
2267 destval
= (*opc81_word_operation
[rh
])(m
, destval
, imm
);
2268 if (rh
!= 7) store_data_word(m
,destoffset
,destval
);
2270 case 3: /* register to register */
2271 destreg
= DECODE_RM_WORD_REGISTER(m
,rl
);
2272 imm
= fetch_word_imm(m
);
2273 destval
= (*opc81_word_operation
[rh
])(m
, *destreg
, imm
);
2274 if (rh
!= 7) *destreg
= destval
;
2277 DECODE_CLEAR_SEGOVR(m
);
2280 static uint8 (*opc82_byte_operation
[])(PC_ENV
*m
,uint8 s
,uint8 d
) =
2283 or_byte
, /*01*/ /*YYY UNUSED ????*/
2286 and_byte
,/*04*/ /*YYY UNUSED ????*/
2288 xor_byte
,/*06*/ /*YYY UNUSED ????*/
2293 static void i86op_opc82_byte_RM_IMM(PC_ENV
*m
)
2300 /* weirdo special case instruction format. Part of the
2301 opcode held below in "RH". Doubly nested case would
2302 result, except that the decoded instruction
2303 Similar to opcode 81, except that the immediate byte
2304 is sign extended to a word length.
2306 FETCH_DECODE_MODRM(m
,mod
,rh
,rl
);
2307 /* know operation, decode the mod byte to find the addressing
2312 destoffset
=decode_rm00_address(m
,rl
);
2313 destval
= fetch_data_byte(m
,destoffset
);
2314 imm
= fetch_byte_imm(m
);
2315 destval
= (*opc82_byte_operation
[rh
])(m
, destval
, imm
);
2316 if (rh
!= 7) store_data_byte(m
,destoffset
,destval
);
2319 destoffset
=decode_rm01_address(m
,rl
);
2320 destval
= fetch_data_byte(m
,destoffset
);
2321 imm
= fetch_byte_imm(m
);
2322 destval
= (*opc82_byte_operation
[rh
])(m
, destval
, imm
);
2323 if (rh
!= 7) store_data_byte(m
,destoffset
,destval
);
2326 destoffset
=decode_rm10_address(m
,rl
);
2327 destval
= fetch_data_byte(m
,destoffset
);
2328 imm
= fetch_byte_imm(m
);
2329 destval
= (*opc82_byte_operation
[rh
])(m
, destval
, imm
);
2330 if (rh
!= 7) store_data_byte(m
,destoffset
,destval
);
2332 case 3: /* register to register */
2333 destreg
= DECODE_RM_BYTE_REGISTER(m
,rl
);
2334 imm
= fetch_byte_imm(m
);
2335 destval
= (*opc82_byte_operation
[rh
])(m
, *destreg
, imm
);
2336 if (rh
!= 7) *destreg
= destval
;
2339 DECODE_CLEAR_SEGOVR(m
);
2342 static uint16 (*opc83_word_operation
[])(PC_ENV
*m
,uint16 s
,uint16 d
) =
2345 or_word
, /*01*/ /*YYY UNUSED ????*/
2348 and_word
,/*04*/ /*YYY UNUSED ????*/
2350 xor_word
,/*06*/ /*YYY UNUSED ????*/
2355 static void i86op_opc83_word_RM_IMM(PC_ENV
*m
)
2362 /* weirdo special case instruction format. Part of the
2363 opcode held below in "RH". Doubly nested case would
2364 result, except that the decoded instruction
2365 Similar to opcode 81, except that the immediate byte
2366 is sign extended to a word length.
2368 FETCH_DECODE_MODRM(m
,mod
,rh
,rl
);
2369 /* know operation, decode the mod byte to find the addressing
2374 destoffset
=decode_rm00_address(m
,rl
);
2375 destval
= fetch_data_word(m
,destoffset
);
2376 imm
= (int8
)fetch_byte_imm(m
);
2377 destval
= (*opc83_word_operation
[rh
])(m
, destval
, imm
);
2378 if (rh
!= 7) store_data_word(m
,destoffset
,destval
);
2381 destoffset
=decode_rm01_address(m
,rl
);
2382 destval
= fetch_data_word(m
,destoffset
);
2383 imm
= (int8
)fetch_byte_imm(m
);
2384 destval
= (*opc83_word_operation
[rh
])(m
, destval
, imm
);
2385 if (rh
!= 7) store_data_word(m
,destoffset
,destval
);
2388 destoffset
=decode_rm10_address(m
,rl
);
2389 destval
= fetch_data_word(m
,destoffset
);
2390 imm
= (int8
) fetch_byte_imm(m
);
2391 destval
= (*opc83_word_operation
[rh
])(m
, destval
, imm
);
2392 if (rh
!= 7) store_data_word(m
,destoffset
,destval
);
2394 case 3: /* register to register */
2395 destreg
= DECODE_RM_WORD_REGISTER(m
,rl
);
2396 imm
= (int8
) fetch_byte_imm(m
);
2397 destval
= (*opc83_word_operation
[rh
])(m
, *destreg
, imm
);
2398 if (rh
!= 7) *destreg
= destval
;
2401 DECODE_CLEAR_SEGOVR(m
);
2405 static void i86op_test_byte_RM_R(PC_ENV
*m
)
2408 uint8
*destreg
,*srcreg
;
2411 FETCH_DECODE_MODRM(m
,mod
,rh
,rl
);
2415 destoffset
=decode_rm00_address(m
,rl
);
2416 destval
= fetch_data_byte(m
,destoffset
);
2417 srcreg
= DECODE_RM_BYTE_REGISTER(m
,rh
);
2418 test_byte(m
, destval
, *srcreg
);
2421 destoffset
=decode_rm01_address(m
,rl
);
2422 destval
= fetch_data_byte(m
,destoffset
);
2423 srcreg
= DECODE_RM_BYTE_REGISTER(m
,rh
);
2424 test_byte(m
, destval
, *srcreg
);
2427 destoffset
=decode_rm10_address(m
,rl
);
2428 destval
= fetch_data_byte(m
,destoffset
);
2429 srcreg
= DECODE_RM_BYTE_REGISTER(m
,rh
);
2430 test_byte(m
, destval
, *srcreg
);
2432 case 3: /* register to register */
2433 destreg
= DECODE_RM_BYTE_REGISTER(m
,rl
);
2434 srcreg
= DECODE_RM_BYTE_REGISTER(m
,rh
);
2435 test_byte(m
, *destreg
, *srcreg
);
2438 DECODE_CLEAR_SEGOVR(m
);
2442 static void i86op_test_word_RM_R(PC_ENV
*m
)
2445 uint16
*destreg
,*srcreg
;
2448 FETCH_DECODE_MODRM(m
,mod
,rh
,rl
);
2452 destoffset
=decode_rm00_address(m
,rl
);
2453 destval
= fetch_data_word(m
,destoffset
);
2454 srcreg
= DECODE_RM_WORD_REGISTER(m
,rh
);
2455 test_word(m
, destval
, *srcreg
);
2458 destoffset
=decode_rm01_address(m
,rl
);
2459 destval
= fetch_data_word(m
,destoffset
);
2460 srcreg
= DECODE_RM_WORD_REGISTER(m
,rh
);
2461 test_word(m
, destval
, *srcreg
);
2464 destoffset
=decode_rm10_address(m
,rl
);
2465 destval
= fetch_data_word(m
,destoffset
);
2466 srcreg
= DECODE_RM_WORD_REGISTER(m
,rh
);
2467 test_word(m
, destval
, *srcreg
);
2469 case 3: /* register to register */
2470 destreg
= DECODE_RM_WORD_REGISTER(m
,rl
);
2471 srcreg
= DECODE_RM_WORD_REGISTER(m
,rh
);
2472 test_word(m
, *destreg
, *srcreg
);
2475 DECODE_CLEAR_SEGOVR(m
);
2479 static void i86op_xchg_byte_RM_R(PC_ENV
*m
)
2482 uint8
*destreg
,*srcreg
;
2486 FETCH_DECODE_MODRM(m
,mod
,rh
,rl
);
2490 destoffset
=decode_rm00_address(m
,rl
);
2491 destval
= fetch_data_byte(m
,destoffset
);
2492 srcreg
= DECODE_RM_BYTE_REGISTER(m
,rh
);
2496 store_data_byte(m
,destoffset
,destval
);
2499 destoffset
=decode_rm01_address(m
,rl
);
2500 destval
= fetch_data_byte(m
,destoffset
);
2501 srcreg
= DECODE_RM_BYTE_REGISTER(m
,rh
);
2505 store_data_byte(m
,destoffset
,destval
);
2508 destoffset
=decode_rm10_address(m
,rl
);
2509 destval
= fetch_data_byte(m
,destoffset
);
2510 srcreg
= DECODE_RM_BYTE_REGISTER(m
,rh
);
2514 store_data_byte(m
,destoffset
,destval
);
2516 case 3: /* register to register */
2517 destreg
= DECODE_RM_BYTE_REGISTER(m
,rl
);
2518 srcreg
= DECODE_RM_BYTE_REGISTER(m
,rh
);
2524 DECODE_CLEAR_SEGOVR(m
);
2528 static void i86op_xchg_word_RM_R(PC_ENV
*m
)
2531 uint16
*destreg
,*srcreg
;
2535 FETCH_DECODE_MODRM(m
,mod
,rh
,rl
);
2539 destoffset
=decode_rm00_address(m
,rl
);
2540 destval
= fetch_data_word(m
,destoffset
);
2541 srcreg
= DECODE_RM_WORD_REGISTER(m
,rh
);
2545 store_data_word(m
,destoffset
,destval
);
2548 destoffset
=decode_rm01_address(m
,rl
);
2549 destval
= fetch_data_word(m
,destoffset
);
2550 srcreg
= DECODE_RM_WORD_REGISTER(m
,rh
);
2554 store_data_word(m
,destoffset
,destval
);
2557 destoffset
=decode_rm10_address(m
,rl
);
2558 destval
= fetch_data_word(m
,destoffset
);
2559 srcreg
= DECODE_RM_WORD_REGISTER(m
,rh
);
2563 store_data_word(m
,destoffset
,destval
);
2565 case 3: /* register to register */
2566 destreg
= DECODE_RM_WORD_REGISTER(m
,rl
);
2567 srcreg
= DECODE_RM_WORD_REGISTER(m
,rh
);
2573 DECODE_CLEAR_SEGOVR(m
);
2577 static void i86op_mov_byte_RM_R(PC_ENV
*m
)
2580 uint8
*destreg
,*srcreg
;
2582 FETCH_DECODE_MODRM(m
,mod
,rh
,rl
);
2586 destoffset
=decode_rm00_address(m
,rl
);
2587 srcreg
= DECODE_RM_BYTE_REGISTER(m
,rh
);
2588 store_data_byte(m
,destoffset
,*srcreg
);
2591 destoffset
=decode_rm01_address(m
,rl
);
2592 srcreg
= DECODE_RM_BYTE_REGISTER(m
,rh
);
2593 store_data_byte(m
,destoffset
,*srcreg
);
2596 destoffset
=decode_rm10_address(m
,rl
);
2597 srcreg
= DECODE_RM_BYTE_REGISTER(m
,rh
);
2598 store_data_byte(m
,destoffset
,*srcreg
);
2600 case 3: /* register to register */
2601 destreg
= DECODE_RM_BYTE_REGISTER(m
,rl
);
2602 srcreg
= DECODE_RM_BYTE_REGISTER(m
,rh
);
2606 DECODE_CLEAR_SEGOVR(m
);
2610 static void i86op_mov_word_RM_R(PC_ENV
*m
)
2613 uint16
*destreg
,*srcreg
;
2615 FETCH_DECODE_MODRM(m
,mod
,rh
,rl
);
2619 destoffset
=decode_rm00_address(m
,rl
);
2620 srcreg
= DECODE_RM_WORD_REGISTER(m
,rh
);
2621 store_data_word(m
,destoffset
,*srcreg
);
2624 destoffset
=decode_rm01_address(m
,rl
);
2625 srcreg
= DECODE_RM_WORD_REGISTER(m
,rh
);
2626 store_data_word(m
,destoffset
,*srcreg
);
2629 destoffset
=decode_rm10_address(m
,rl
);
2630 srcreg
= DECODE_RM_WORD_REGISTER(m
,rh
);
2631 store_data_word(m
,destoffset
,*srcreg
);
2633 case 3: /* register to register */
2634 destreg
= DECODE_RM_WORD_REGISTER(m
,rl
);
2635 srcreg
= DECODE_RM_WORD_REGISTER(m
,rh
);
2639 DECODE_CLEAR_SEGOVR(m
);
2643 static void i86op_mov_byte_R_RM(PC_ENV
*m
)
2646 uint8
*destreg
,*srcreg
;
2649 FETCH_DECODE_MODRM(m
,mod
,rh
,rl
);
2653 destreg
= DECODE_RM_BYTE_REGISTER(m
,rh
);
2654 srcoffset
=decode_rm00_address(m
,rl
);
2655 srcval
= fetch_data_byte(m
,srcoffset
);
2659 destreg
= DECODE_RM_BYTE_REGISTER(m
,rh
);
2660 srcoffset
=decode_rm01_address(m
,rl
);
2661 srcval
= fetch_data_byte(m
,srcoffset
);
2665 destreg
= DECODE_RM_BYTE_REGISTER(m
,rh
);
2666 srcoffset
=decode_rm10_address(m
,rl
);
2667 srcval
= fetch_data_byte(m
,srcoffset
);
2670 case 3: /* register to register */
2671 destreg
= DECODE_RM_BYTE_REGISTER(m
,rh
);
2672 srcreg
= DECODE_RM_BYTE_REGISTER(m
,rl
);
2676 DECODE_CLEAR_SEGOVR(m
);
2680 static void i86op_mov_word_R_RM(PC_ENV
*m
)
2683 uint16
*destreg
,*srcreg
;
2686 FETCH_DECODE_MODRM(m
,mod
,rh
,rl
);
2690 destreg
= DECODE_RM_WORD_REGISTER(m
,rh
);
2691 srcoffset
=decode_rm00_address(m
,rl
);
2692 srcval
= fetch_data_word(m
,srcoffset
);
2696 destreg
= DECODE_RM_WORD_REGISTER(m
,rh
);
2697 srcoffset
=decode_rm01_address(m
,rl
);
2698 srcval
= fetch_data_word(m
,srcoffset
);
2702 destreg
= DECODE_RM_WORD_REGISTER(m
,rh
);
2703 srcoffset
=decode_rm10_address(m
,rl
);
2704 srcval
= fetch_data_word(m
,srcoffset
);
2707 case 3: /* register to register */
2708 destreg
= DECODE_RM_WORD_REGISTER(m
,rh
);
2709 srcreg
= DECODE_RM_WORD_REGISTER(m
,rl
);
2713 DECODE_CLEAR_SEGOVR(m
);
2717 static void i86op_mov_word_RM_SR(PC_ENV
*m
)
2720 uint16
*destreg
,*srcreg
;
2723 FETCH_DECODE_MODRM(m
,mod
,rh
,rl
);
2727 destoffset
=decode_rm00_address(m
,rl
);
2728 srcreg
= decode_rm_seg_register(m
,rh
);
2730 store_data_word(m
,destoffset
,destval
);
2733 destoffset
=decode_rm01_address(m
,rl
);
2734 srcreg
= decode_rm_seg_register(m
,rh
);
2736 store_data_word(m
,destoffset
,destval
);
2739 destoffset
=decode_rm10_address(m
,rl
);
2740 srcreg
= decode_rm_seg_register(m
,rh
);
2742 store_data_word(m
,destoffset
,destval
);
2744 case 3: /* register to register */
2745 destreg
= DECODE_RM_WORD_REGISTER(m
,rl
);
2746 srcreg
= decode_rm_seg_register(m
,rh
);
2750 DECODE_CLEAR_SEGOVR(m
);
2754 static void i86op_lea_word_R_M(PC_ENV
*m
)
2759 FETCH_DECODE_MODRM(m
,mod
,rh
,rl
);
2763 srcreg
= DECODE_RM_WORD_REGISTER(m
,rh
);
2764 destoffset
=decode_rm00_address(m
,rl
);
2765 *srcreg
= destoffset
;
2768 srcreg
= DECODE_RM_WORD_REGISTER(m
,rh
);
2769 destoffset
=decode_rm01_address(m
,rl
);
2770 *srcreg
= destoffset
;
2773 srcreg
= DECODE_RM_WORD_REGISTER(m
,rh
);
2774 destoffset
=decode_rm10_address(m
,rl
);
2775 *srcreg
= destoffset
;
2777 case 3: /* register to register */
2778 /* undefined. Do nothing. */
2781 DECODE_CLEAR_SEGOVR(m
);
2785 static void i86op_mov_word_SR_RM(PC_ENV
*m
)
2788 uint16
*destreg
,*srcreg
;
2791 FETCH_DECODE_MODRM(m
,mod
,rh
,rl
);
2795 destreg
= decode_rm_seg_register(m
,rh
);
2796 srcoffset
=decode_rm00_address(m
,rl
);
2797 srcval
= fetch_data_word(m
,srcoffset
);
2801 destreg
= decode_rm_seg_register(m
,rh
);
2802 srcoffset
=decode_rm01_address(m
,rl
);
2803 srcval
= fetch_data_word(m
,srcoffset
);
2807 destreg
= decode_rm_seg_register(m
,rh
);
2808 srcoffset
= decode_rm10_address(m
,rl
);
2809 srcval
= fetch_data_word(m
,srcoffset
);
2812 case 3: /* register to register */
2813 destreg
= decode_rm_seg_register(m
,rh
);
2814 srcreg
= DECODE_RM_WORD_REGISTER(m
,rl
);
2819 * clean up, and reset all the R_xSP pointers to the correct
2820 * locations. This is about 3x too much overhead (doing all the
2821 * segreg ptrs when only one is needed, but this instruction
2822 * *cannot* be that common, and this isn't too much work anyway.
2824 DECODE_CLEAR_SEGOVR(m
);
2828 static void i86op_pop_RM(PC_ENV
*m
)
2834 FETCH_DECODE_MODRM(m
,mod
,rh
,rl
);
2842 destoffset
=decode_rm00_address(m
,rl
);
2843 destval
= pop_word( m
);
2844 store_data_word(m
,destoffset
,destval
);
2847 destoffset
=decode_rm01_address(m
,rl
);
2848 destval
= pop_word(m
);
2849 store_data_word(m
,destoffset
,destval
);
2852 destoffset
=decode_rm10_address(m
,rl
);
2853 destval
= pop_word(m
);
2854 store_data_word(m
,destoffset
,destval
);
2856 case 3: /* register to register */
2857 destreg
= DECODE_RM_WORD_REGISTER(m
,rl
);
2858 *destreg
= pop_word(m
);
2861 DECODE_CLEAR_SEGOVR(m
);
2865 static void i86op_nop(PC_ENV
*m
)
2867 DECODE_CLEAR_SEGOVR(m
);
2871 static void i86op_xchg_word_AX_CX(PC_ENV
*m
)
2877 DECODE_CLEAR_SEGOVR(m
);
2881 static void i86op_xchg_word_AX_DX(PC_ENV
*m
)
2887 DECODE_CLEAR_SEGOVR(m
);
2891 static void i86op_xchg_word_AX_BX(PC_ENV
*m
)
2897 DECODE_CLEAR_SEGOVR(m
);
2901 static void i86op_xchg_word_AX_SP(PC_ENV
*m
)
2907 DECODE_CLEAR_SEGOVR(m
);
2911 static void i86op_xchg_word_AX_BP(PC_ENV
*m
)
2917 DECODE_CLEAR_SEGOVR(m
);
2921 static void i86op_xchg_word_AX_SI(PC_ENV
*m
)
2927 DECODE_CLEAR_SEGOVR(m
);
2931 static void i86op_xchg_word_AX_DI(PC_ENV
*m
)
2937 DECODE_CLEAR_SEGOVR(m
);
2941 static void i86op_cbw(PC_ENV
*m
)
2951 DECODE_CLEAR_SEGOVR(m
);
2955 static void i86op_cwd(PC_ENV
*m
)
2957 if (m
->R_AX
& 0x8000)
2965 DECODE_CLEAR_SEGOVR(m
);
2969 static void i86op_call_far_IMM(PC_ENV
*m
)
2971 uint16 farseg
,faroff
;
2972 faroff
= fetch_word_imm(m
);
2973 farseg
= fetch_word_imm(m
);
2975 HOOKED INTERRUPT VECTORS CALLING INTO OUR "BIOS"
2976 WILL CAUSE PROBLEMS UNLESS ALL INTERSEGMENT STUFF IS
2977 CHECKED FOR BIOS ACCESS. CHECK NEEDED HERE.
2978 FOR MOMENT, LET IT ALONE.
2980 push_word(m
,m
->R_CS
);
2982 push_word(m
,m
->R_IP
);
2984 DECODE_CLEAR_SEGOVR(m
);
2988 static void i86op_wait(PC_ENV
*m
)
2991 DECODE_CLEAR_SEGOVR(m
);
2995 static void i86op_pushf_word(PC_ENV
*m
)
2999 /* clear out *all* bits not representing flags */
3001 /* TURN ON CHARACTERISTIC BITS OF FLAG FOR 8088 */
3002 flags
|= F_ALWAYS_ON
;
3004 DECODE_CLEAR_SEGOVR(m
);
3008 static void i86op_popf_word(PC_ENV
*m
)
3010 m
->R_FLG
= pop_word(m
);
3011 DECODE_CLEAR_SEGOVR(m
);
3015 static void i86op_sahf(PC_ENV
*m
)
3017 /* clear the lower bits of the flag register */
3018 m
->R_FLG
&= 0xffffff00;
3019 /* or in the AH register into the flags register */
3020 m
->R_FLG
|= m
->R_AH
;
3021 DECODE_CLEAR_SEGOVR(m
);
3025 static void i86op_lahf(PC_ENV
*m
)
3027 m
->R_AH
= m
->R_FLG
& 0xff;
3028 /*undocumented TC++ behavior??? Nope. It's documented, but
3029 you have too look real hard to notice it. */
3031 DECODE_CLEAR_SEGOVR(m
);
3035 static void i86op_mov_AL_M_IMM(PC_ENV
*m
)
3039 offset
= fetch_word_imm(m
);
3040 destval
= fetch_data_byte(m
,offset
);
3042 DECODE_CLEAR_SEGOVR(m
);
3046 static void i86op_mov_AX_M_IMM(PC_ENV
*m
)
3050 offset
= fetch_word_imm(m
);
3051 destval
= fetch_data_word(m
,offset
);
3053 DECODE_CLEAR_SEGOVR(m
);
3057 static void i86op_mov_M_AL_IMM(PC_ENV
*m
)
3060 offset
= fetch_word_imm(m
);
3061 store_data_byte(m
,offset
,m
->R_AL
);
3062 DECODE_CLEAR_SEGOVR(m
);
3066 static void i86op_mov_M_AX_IMM(PC_ENV
*m
)
3069 offset
= fetch_word_imm(m
);
3070 store_data_word(m
,offset
,m
->R_AX
);
3071 DECODE_CLEAR_SEGOVR(m
);
3077 static void i86op_movs_byte(PC_ENV
*m
)
3081 if (ACCESS_FLAG(m
,F_DF
)) /* down */
3085 if (m
->sysmode
& (SYSMODE_PREFIX_REPE
| SYSMODE_PREFIX_REPNE
))
3087 /* dont care whether REPE or REPNE */
3088 /* move them until CX is ZERO. */
3089 while (m
->R_CX
!= 0)
3091 val
= fetch_data_byte(m
,m
->R_SI
);
3092 store_data_byte_abs(m
,m
->R_ES
,m
->R_DI
,val
);
3097 m
->sysmode
&= ~(SYSMODE_PREFIX_REPE
| SYSMODE_PREFIX_REPNE
);
3101 val
= fetch_data_byte(m
,m
->R_SI
);
3102 store_data_byte_abs(m
,m
->R_ES
,m
->R_DI
,val
);
3106 DECODE_CLEAR_SEGOVR(m
);
3110 static void i86op_movs_word(PC_ENV
*m
)
3114 if (ACCESS_FLAG(m
, F_DF
)) /* down */
3118 if (m
->sysmode
& (SYSMODE_PREFIX_REPE
| SYSMODE_PREFIX_REPNE
))
3120 /* dont care whether REPE or REPNE */
3121 /* move them until CX is ZERO. */
3122 while (m
->R_CX
!= 0)
3124 val
= fetch_data_word(m
,m
->R_SI
);
3125 store_data_word_abs(m
,m
->R_ES
,m
->R_DI
,val
);
3130 m
->sysmode
&= ~(SYSMODE_PREFIX_REPE
| SYSMODE_PREFIX_REPNE
);
3134 val
= fetch_data_word(m
,m
->R_SI
);
3135 store_data_word_abs(m
,m
->R_ES
,m
->R_DI
,val
);
3139 DECODE_CLEAR_SEGOVR(m
);
3143 static void i86op_cmps_byte(PC_ENV
*m
)
3147 if (ACCESS_FLAG(m
,F_DF
)) /* down */
3151 if (m
->sysmode
& SYSMODE_PREFIX_REPE
)
3154 /* move them until CX is ZERO. */
3155 while (m
->R_CX
!= 0)
3157 val1
= fetch_data_byte(m
,m
->R_SI
);
3158 val2
= fetch_data_byte_abs(m
,m
->R_ES
,m
->R_DI
);
3159 cmp_byte(m
, val1
,val2
);
3163 if (ACCESS_FLAG(m
,F_ZF
)==0) break;
3165 m
->sysmode
&= ~SYSMODE_PREFIX_REPE
;
3167 else if (m
->sysmode
& SYSMODE_PREFIX_REPNE
)
3170 /* move them until CX is ZERO. */
3171 while (m
->R_CX
!= 0)
3173 val1
= fetch_data_byte(m
,m
->R_SI
);
3174 val2
= fetch_data_byte_abs(m
,m
->R_ES
,m
->R_DI
);
3175 cmp_byte(m
, val1
,val2
);
3179 if (ACCESS_FLAG(m
,F_ZF
)) break; /* zero flag set means equal */
3181 m
->sysmode
&= ~SYSMODE_PREFIX_REPNE
;
3185 val1
= fetch_data_byte(m
,m
->R_SI
);
3186 val2
= fetch_data_byte_abs(m
,m
->R_ES
,m
->R_DI
);
3187 cmp_byte(m
, val1
,val2
);
3191 DECODE_CLEAR_SEGOVR(m
);
3195 static void i86op_cmps_word(PC_ENV
*m
)
3199 if (ACCESS_FLAG(m
,F_DF
)) /* down */
3203 if (m
->sysmode
& SYSMODE_PREFIX_REPE
)
3206 /* move them until CX is ZERO. */
3207 while (m
->R_CX
!= 0)
3209 val1
= fetch_data_word(m
,m
->R_SI
);
3210 val2
= fetch_data_word_abs(m
,m
->R_ES
,m
->R_DI
);
3211 cmp_word(m
, val1
,val2
);
3215 if (ACCESS_FLAG(m
,F_ZF
)==0) break;
3217 m
->sysmode
&= ~SYSMODE_PREFIX_REPE
;
3219 else if (m
->sysmode
& SYSMODE_PREFIX_REPNE
)
3222 /* move them until CX is ZERO. */
3223 while (m
->R_CX
!= 0)
3225 val1
= fetch_data_word(m
,m
->R_SI
);
3226 val2
= fetch_data_word_abs(m
,m
->R_ES
,m
->R_DI
);
3227 cmp_word(m
, val1
,val2
);
3231 if (ACCESS_FLAG(m
,F_ZF
)) break; /* zero flag set means equal */
3233 m
->sysmode
&= ~SYSMODE_PREFIX_REPNE
;
3237 val1
= fetch_data_word(m
,m
->R_SI
);
3238 val2
= fetch_data_word_abs(m
,m
->R_ES
,m
->R_DI
);
3239 cmp_word(m
, val1
,val2
);
3243 DECODE_CLEAR_SEGOVR(m
);
3247 static void i86op_test_AL_IMM(PC_ENV
*m
)
3250 imm
= fetch_byte_imm(m
);
3251 test_byte(m
, m
->R_AL
, imm
);
3252 DECODE_CLEAR_SEGOVR(m
);
3256 static void i86op_test_AX_IMM(PC_ENV
*m
)
3259 imm
= fetch_word_imm(m
);
3260 test_word(m
, m
->R_AX
, imm
);
3261 DECODE_CLEAR_SEGOVR(m
);
3265 static void i86op_stos_byte(PC_ENV
*m
)
3268 if (ACCESS_FLAG(m
, F_DF
)) /* down */
3272 if (m
->sysmode
& (SYSMODE_PREFIX_REPE
| SYSMODE_PREFIX_REPNE
))
3274 /* dont care whether REPE or REPNE */
3275 /* move them until CX is ZERO. */
3276 while (m
->R_CX
!= 0)
3278 store_data_byte_abs(m
,m
->R_ES
,m
->R_DI
,m
->R_AL
);
3282 m
->sysmode
&= ~(SYSMODE_PREFIX_REPE
| SYSMODE_PREFIX_REPNE
);
3286 store_data_byte_abs(m
,m
->R_ES
,m
->R_DI
,m
->R_AL
);
3289 DECODE_CLEAR_SEGOVR(m
);
3293 static void i86op_stos_word(PC_ENV
*m
)
3296 if (ACCESS_FLAG(m
, F_DF
)) /* down */
3300 if (m
->sysmode
& (SYSMODE_PREFIX_REPE
| SYSMODE_PREFIX_REPNE
))
3302 /* dont care whether REPE or REPNE */
3303 /* move them until CX is ZERO. */
3304 while (m
->R_CX
!= 0)
3306 store_data_word_abs(m
,m
->R_ES
,m
->R_DI
,m
->R_AX
);
3310 m
->sysmode
&= ~(SYSMODE_PREFIX_REPE
| SYSMODE_PREFIX_REPNE
);
3314 store_data_word_abs(m
,m
->R_ES
,m
->R_DI
,m
->R_AX
);
3317 DECODE_CLEAR_SEGOVR(m
);
3321 static void i86op_lods_byte(PC_ENV
*m
)
3324 if (ACCESS_FLAG(m
,F_DF
)) /* down */
3328 if (m
->sysmode
& (SYSMODE_PREFIX_REPE
| SYSMODE_PREFIX_REPNE
))
3330 /* dont care whether REPE or REPNE */
3331 /* move them until CX is ZERO. */
3332 while (m
->R_CX
!= 0)
3334 m
->R_AL
= fetch_data_byte(m
,m
->R_SI
);
3338 m
->sysmode
&= ~(SYSMODE_PREFIX_REPE
| SYSMODE_PREFIX_REPNE
);
3342 m
->R_AL
= fetch_data_byte(m
,m
->R_SI
);
3345 DECODE_CLEAR_SEGOVR(m
);
3349 static void i86op_lods_word(PC_ENV
*m
)
3352 if (ACCESS_FLAG(m
,F_DF
)) /* down */
3356 if (m
->sysmode
& (SYSMODE_PREFIX_REPE
| SYSMODE_PREFIX_REPNE
))
3358 /* dont care whether REPE or REPNE */
3359 /* move them until CX is ZERO. */
3360 while (m
->R_CX
!= 0)
3362 m
->R_AX
= fetch_data_word(m
,m
->R_SI
);
3366 m
->sysmode
&= ~(SYSMODE_PREFIX_REPE
| SYSMODE_PREFIX_REPNE
);
3370 m
->R_AX
= fetch_data_word(m
,m
->R_SI
);
3373 DECODE_CLEAR_SEGOVR(m
);
3377 static void i86op_scas_byte(PC_ENV
*m
)
3381 if (ACCESS_FLAG(m
,F_DF
)) /* down */
3385 if (m
->sysmode
& SYSMODE_PREFIX_REPE
)
3388 /* move them until CX is ZERO. */
3389 while (m
->R_CX
!= 0)
3391 val2
= fetch_data_byte_abs(m
,m
->R_ES
,m
->R_DI
);
3392 cmp_byte(m
, m
->R_AL
,val2
);
3395 if (ACCESS_FLAG(m
,F_ZF
)==0) break;
3397 m
->sysmode
&= ~SYSMODE_PREFIX_REPE
;
3399 else if (m
->sysmode
& SYSMODE_PREFIX_REPNE
)
3402 /* move them until CX is ZERO. */
3403 while (m
->R_CX
!= 0)
3405 val2
= fetch_data_byte_abs(m
,m
->R_ES
,m
->R_DI
);
3406 cmp_byte(m
, m
->R_AL
,val2
);
3409 if (ACCESS_FLAG(m
,F_ZF
)) break; /* zero flag set means equal */
3411 m
->sysmode
&= ~SYSMODE_PREFIX_REPNE
;
3415 val2
= fetch_data_byte_abs(m
,m
->R_ES
,m
->R_DI
);
3416 cmp_byte(m
, m
->R_AL
,val2
);
3419 DECODE_CLEAR_SEGOVR(m
);
3423 static void i86op_scas_word(PC_ENV
*m
)
3427 if (ACCESS_FLAG(m
, F_DF
)) /* down */
3431 if (m
->sysmode
& SYSMODE_PREFIX_REPE
)
3434 /* move them until CX is ZERO. */
3435 while (m
->R_CX
!= 0)
3437 val2
= fetch_data_word_abs(m
,m
->R_ES
,m
->R_DI
);
3438 cmp_word(m
,m
->R_AX
,val2
);
3441 if (ACCESS_FLAG(m
,F_ZF
)==0) break;
3443 m
->sysmode
&= ~SYSMODE_PREFIX_REPE
;
3445 else if (m
->sysmode
& SYSMODE_PREFIX_REPNE
)
3448 /* move them until CX is ZERO. */
3449 while (m
->R_CX
!= 0)
3451 val2
= fetch_data_word_abs(m
,m
->R_ES
,m
->R_DI
);
3452 cmp_word(m
, m
->R_AX
,val2
);
3455 if (ACCESS_FLAG(m
,F_ZF
)) break; /* zero flag set means equal */
3457 m
->sysmode
&= ~SYSMODE_PREFIX_REPNE
;
3461 val2
= fetch_data_word_abs(m
,m
->R_ES
,m
->R_DI
);
3462 cmp_word(m
, m
->R_AX
,val2
);
3465 DECODE_CLEAR_SEGOVR(m
);
3469 static void i86op_mov_byte_AL_IMM(PC_ENV
*m
)
3472 imm
= fetch_byte_imm(m
);
3474 DECODE_CLEAR_SEGOVR(m
);
3478 static void i86op_mov_byte_CL_IMM(PC_ENV
*m
)
3481 imm
= fetch_byte_imm(m
);
3483 DECODE_CLEAR_SEGOVR(m
);
3487 static void i86op_mov_byte_DL_IMM(PC_ENV
*m
)
3490 imm
= fetch_byte_imm(m
);
3492 DECODE_CLEAR_SEGOVR(m
);
3496 static void i86op_mov_byte_BL_IMM(PC_ENV
*m
)
3499 imm
= fetch_byte_imm(m
);
3501 DECODE_CLEAR_SEGOVR(m
);
3505 static void i86op_mov_byte_AH_IMM(PC_ENV
*m
)
3508 imm
= fetch_byte_imm(m
);
3510 DECODE_CLEAR_SEGOVR(m
);
3514 static void i86op_mov_byte_CH_IMM(PC_ENV
*m
)
3517 imm
= fetch_byte_imm(m
);
3519 DECODE_CLEAR_SEGOVR(m
);
3523 static void i86op_mov_byte_DH_IMM(PC_ENV
*m
)
3526 imm
= fetch_byte_imm(m
);
3528 DECODE_CLEAR_SEGOVR(m
);
3532 static void i86op_mov_byte_BH_IMM(PC_ENV
*m
)
3535 imm
= fetch_byte_imm(m
);
3537 DECODE_CLEAR_SEGOVR(m
);
3541 static void i86op_mov_word_AX_IMM(PC_ENV
*m
)
3544 imm
= fetch_word_imm(m
);
3546 DECODE_CLEAR_SEGOVR(m
);
3550 static void i86op_mov_word_CX_IMM(PC_ENV
*m
)
3553 imm
= fetch_word_imm(m
);
3555 DECODE_CLEAR_SEGOVR(m
);
3559 static void i86op_mov_word_DX_IMM(PC_ENV
*m
)
3562 imm
= fetch_word_imm(m
);
3564 DECODE_CLEAR_SEGOVR(m
);
3568 static void i86op_mov_word_BX_IMM(PC_ENV
*m
)
3571 imm
= fetch_word_imm(m
);
3573 DECODE_CLEAR_SEGOVR(m
);
3577 static void i86op_mov_word_SP_IMM(PC_ENV
*m
)
3580 imm
= fetch_word_imm(m
);
3582 DECODE_CLEAR_SEGOVR(m
);
3586 static void i86op_mov_word_BP_IMM(PC_ENV
*m
)
3589 imm
= fetch_word_imm(m
);
3591 DECODE_CLEAR_SEGOVR(m
);
3595 static void i86op_mov_word_SI_IMM(PC_ENV
*m
)
3598 imm
= fetch_word_imm(m
);
3600 DECODE_CLEAR_SEGOVR(m
);
3604 static void i86op_mov_word_DI_IMM(PC_ENV
*m
)
3607 imm
= fetch_word_imm(m
);
3609 DECODE_CLEAR_SEGOVR(m
);
3612 /* c0 === ILLEGAL OPERAND */
3613 /* c1 === ILLEGAL OPERAND */
3616 static void i86op_ret_near_IMM(PC_ENV
*m
)
3619 imm
= fetch_word_imm(m
);
3620 m
->R_IP
= pop_word(m
);
3622 DECODE_CLEAR_SEGOVR(m
);
3626 static void i86op_ret_near(PC_ENV
*m
)
3628 m
->R_IP
= pop_word(m
);
3629 DECODE_CLEAR_SEGOVR(m
);
3633 static void i86op_les_R_IMM(PC_ENV
*m
)
3638 FETCH_DECODE_MODRM(m
,mod
,rh
,rl
);
3642 dstreg
= DECODE_RM_WORD_REGISTER(m
,rh
);
3643 srcoffset
=decode_rm00_address(m
,rl
);
3644 *dstreg
= fetch_data_word(m
,srcoffset
);
3645 m
->R_ES
= fetch_data_word(m
,srcoffset
+2);
3648 dstreg
= DECODE_RM_WORD_REGISTER(m
,rh
);
3649 srcoffset
=decode_rm01_address(m
,rl
);
3650 *dstreg
= fetch_data_word(m
,srcoffset
);
3651 m
->R_ES
= fetch_data_word(m
,srcoffset
+2);
3654 dstreg
= DECODE_RM_WORD_REGISTER(m
,rh
);
3655 srcoffset
=decode_rm10_address(m
,rl
);
3656 *dstreg
= fetch_data_word(m
,srcoffset
);
3657 m
->R_ES
= fetch_data_word(m
,srcoffset
+2);
3659 case 3: /* register to register */
3663 DECODE_CLEAR_SEGOVR(m
);
3667 static void i86op_lds_R_IMM(PC_ENV
*m
)
3672 FETCH_DECODE_MODRM(m
,mod
,rh
,rl
);
3676 dstreg
= DECODE_RM_WORD_REGISTER(m
,rh
);
3677 srcoffset
=decode_rm00_address(m
,rl
);
3678 *dstreg
= fetch_data_word(m
,srcoffset
);
3679 m
->R_DS
= fetch_data_word(m
,srcoffset
+2);
3682 dstreg
= DECODE_RM_WORD_REGISTER(m
,rh
);
3683 srcoffset
=decode_rm01_address(m
,rl
);
3684 *dstreg
= fetch_data_word(m
,srcoffset
);
3685 m
->R_DS
= fetch_data_word(m
,srcoffset
+2);
3688 dstreg
= DECODE_RM_WORD_REGISTER(m
,rh
);
3689 srcoffset
=decode_rm10_address(m
,rl
);
3690 *dstreg
= fetch_data_word(m
,srcoffset
);
3691 m
->R_DS
= fetch_data_word(m
,srcoffset
+2);
3693 case 3: /* register to register */
3697 DECODE_CLEAR_SEGOVR(m
);
3701 static void i86op_mov_byte_RM_IMM(PC_ENV
*m
)
3707 FETCH_DECODE_MODRM(m
,mod
,rh
,rl
);
3715 destoffset
=decode_rm00_address(m
,rl
);
3716 imm
= fetch_byte_imm(m
);
3717 store_data_byte(m
,destoffset
,imm
);
3720 destoffset
=decode_rm01_address(m
,rl
);
3721 imm
= fetch_byte_imm(m
);
3722 store_data_byte(m
,destoffset
,imm
);
3725 destoffset
=decode_rm10_address(m
,rl
);
3726 imm
= fetch_byte_imm(m
);
3727 store_data_byte(m
,destoffset
,imm
);
3729 case 3: /* register to register */
3730 destreg
= DECODE_RM_BYTE_REGISTER(m
,rl
);
3731 imm
= fetch_byte_imm(m
);
3735 DECODE_CLEAR_SEGOVR(m
);
3739 static void i86op_mov_word_RM_IMM(PC_ENV
*m
)
3745 FETCH_DECODE_MODRM(m
,mod
,rh
,rl
);
3753 destoffset
=decode_rm00_address(m
,rl
);
3754 imm
= fetch_word_imm(m
);
3755 store_data_word(m
,destoffset
,imm
);
3758 destoffset
=decode_rm01_address(m
,rl
);
3759 imm
= fetch_word_imm(m
);
3760 store_data_word(m
,destoffset
,imm
);
3763 destoffset
=decode_rm10_address(m
,rl
);
3764 imm
= fetch_word_imm(m
);
3765 store_data_word(m
,destoffset
,imm
);
3767 case 3: /* register to register */
3768 destreg
= DECODE_RM_WORD_REGISTER(m
,rl
);
3769 imm
= fetch_word_imm(m
);
3773 DECODE_CLEAR_SEGOVR(m
);
3776 /*opcode=0xc8 ILLEGAL OP*/
3777 /*opcode=0xc9 ILLEGAL OP*/
3780 static void i86op_ret_far_IMM(PC_ENV
*m
)
3783 imm
= fetch_word_imm(m
);
3784 m
->R_IP
= pop_word(m
);
3785 m
->R_CS
= pop_word(m
);
3787 DECODE_CLEAR_SEGOVR(m
);
3791 static void i86op_ret_far(PC_ENV
*m
)
3793 m
->R_IP
= pop_word(m
);
3794 m
->R_CS
= pop_word(m
);
3795 DECODE_CLEAR_SEGOVR(m
);
3799 static void i86op_int3(PC_ENV
*m
)
3802 tmp
= (uint16
) mem_access_word(m
, 3 * 4);
3803 /* access the segment register */
3807 CLEAR_FLAG(m
, F_IF
);
3808 CLEAR_FLAG(m
, F_TF
);
3809 /* [JCE] If we're interrupting between a segment override (or REP override)
3810 * and the following instruction, decrease IP to get back to the prefix */
3811 if (m
->sysmode
& (SYSMODE_SEGMASK
|
3812 SYSMODE_PREFIX_REPE
|
3813 SYSMODE_PREFIX_REPNE
))
3817 push_word(m
, m
->R_CS
);
3818 push_word(m
, m
->R_IP
);
3819 /* [JCE] CS and IP were the wrong way round... */
3820 tmp
= mem_access_word(m
, 3 * 4);
3822 tmp
= mem_access_word(m
, 3 * 4 + 2);
3825 DECODE_CLEAR_SEGOVR(m
);
3829 static void i86op_int_IMM(PC_ENV
*m
)
3833 intnum
= fetch_byte_imm(m
);
3834 tmp
= mem_access_word(m
, intnum
* 4);
3838 CLEAR_FLAG(m
, F_IF
);
3839 CLEAR_FLAG(m
, F_TF
);
3840 /* [JCE] If we're interrupting between a segment override (or REP override)
3841 * and the following instruction, decrease IP to get back to the prefix */
3842 if (m
->sysmode
& (SYSMODE_SEGMASK
|
3843 SYSMODE_PREFIX_REPE
|
3844 SYSMODE_PREFIX_REPNE
))
3848 push_word(m
, m
->R_CS
);
3849 push_word(m
, m
->R_IP
);
3850 /* [JCE] CS and IP were the wrong way round... */
3851 tmp
= mem_access_word(m
, intnum
* 4);
3853 tmp
= mem_access_word(m
, intnum
* 4 + 2);
3856 DECODE_CLEAR_SEGOVR(m
);
3860 static void i86op_into(PC_ENV
*m
)
3863 if (ACCESS_FLAG(m
,F_OF
))
3865 tmp
= mem_access_word(m
, 4 * 4);
3869 CLEAR_FLAG(m
, F_IF
);
3870 CLEAR_FLAG(m
, F_TF
);
3871 /* [JCE] If we're interrupting between a segment override (or REP override)
3872 * and the following instruction, decrease IP to get back to the prefix */
3873 if (m
->sysmode
& (SYSMODE_SEGMASK
|
3874 SYSMODE_PREFIX_REPE
|
3875 SYSMODE_PREFIX_REPNE
))
3879 push_word(m
, m
->R_CS
);
3880 push_word(m
, m
->R_IP
);
3881 /* [JCE] CS and IP were the wrong way round... */
3882 tmp
= mem_access_word(m
, 4 * 4);
3884 tmp
= mem_access_word(m
, 4 * 4 + 2);
3888 DECODE_CLEAR_SEGOVR(m
);
3892 static void i86op_iret(PC_ENV
*m
)
3894 m
->R_IP
= pop_word(m
);
3895 m
->R_CS
= pop_word(m
);
3896 m
->R_FLG
= pop_word(m
);
3897 DECODE_CLEAR_SEGOVR(m
);
3900 static uint8 (*opcD0_byte_operation
[])(PC_ENV
*m
,uint8 d
, uint8 s
) =
3901 /* used by opcodes d0 and d2. */
3909 shl_byte
, /* sal_byte === shl_byte by definition */
3914 static void i86op_opcD0_byte_RM_1(PC_ENV
*m
)
3920 /* Yet another weirdo special case instruction format. Part of the
3921 opcode held below in "RH". Doubly nested case would
3922 result, except that the decoded instruction
3924 FETCH_DECODE_MODRM(m
,mod
,rh
,rl
);
3925 /* know operation, decode the mod byte to find the addressing
3930 destoffset
=decode_rm00_address(m
,rl
);
3931 destval
= fetch_data_byte(m
,destoffset
);
3932 destval
= (*opcD0_byte_operation
[rh
])(m
, destval
,1);
3933 store_data_byte(m
,destoffset
,destval
);
3936 destoffset
=decode_rm01_address(m
,rl
);
3937 destval
= fetch_data_byte(m
,destoffset
);
3938 destval
= (*opcD0_byte_operation
[rh
])(m
, destval
, 1);
3939 store_data_byte(m
,destoffset
,destval
);
3942 destoffset
=decode_rm10_address(m
,rl
);
3943 destval
= fetch_data_byte(m
,destoffset
);
3944 destval
= (*opcD0_byte_operation
[rh
])(m
, destval
, 1);
3945 store_data_byte(m
,destoffset
,destval
);
3947 case 3: /* register to register */
3948 destreg
= DECODE_RM_BYTE_REGISTER(m
,rl
);
3949 destval
= (*opcD0_byte_operation
[rh
])(m
, *destreg
, 1);
3953 DECODE_CLEAR_SEGOVR(m
);
3956 static uint16 (*opcD1_word_operation
[])(PC_ENV
*m
,uint16 s
,uint16 d
) =
3957 /* used by opcodes d1 and d3. */
3964 shl_word
, /* sal_byte === shl_byte by definition */
3969 static void i86op_opcD1_word_RM_1(PC_ENV
*m
)
3975 /* Yet another weirdo special case instruction format. Part of the
3976 opcode held below in "RH". Doubly nested case would
3977 result, except that the decoded instruction
3979 FETCH_DECODE_MODRM(m
,mod
,rh
,rl
);
3980 /* know operation, decode the mod byte to find the addressing
3985 destoffset
=decode_rm00_address(m
,rl
);
3986 destval
= fetch_data_word(m
,destoffset
);
3987 destval
= (*opcD1_word_operation
[rh
])(m
, destval
,1);
3988 store_data_word(m
,destoffset
,destval
);
3991 destoffset
=decode_rm01_address(m
,rl
);
3992 destval
= fetch_data_word(m
,destoffset
);
3993 destval
= (*opcD1_word_operation
[rh
])(m
, destval
, 1);
3994 store_data_word(m
,destoffset
,destval
);
3997 destoffset
=decode_rm10_address(m
,rl
);
3998 destval
= fetch_data_word(m
,destoffset
);
3999 destval
= (*opcD1_word_operation
[rh
])(m
, destval
, 1);
4000 store_data_word(m
,destoffset
,destval
);
4002 case 3: /* register to register */
4003 destreg
= DECODE_RM_WORD_REGISTER(m
,rl
);
4004 destval
= (*opcD1_word_operation
[rh
])(m
, *destreg
, 1);
4008 DECODE_CLEAR_SEGOVR(m
);
4012 static void i86op_opcD2_byte_RM_CL(PC_ENV
*m
)
4019 /* Yet another weirdo special case instruction format. Part of the
4020 opcode held below in "RH". Doubly nested case would
4021 result, except that the decoded instruction
4023 FETCH_DECODE_MODRM(m
,mod
,rh
,rl
);
4025 /* know operation, decode the mod byte to find the addressing
4030 destoffset
=decode_rm00_address(m
,rl
);
4031 destval
= fetch_data_byte(m
,destoffset
);
4032 destval
= (*opcD0_byte_operation
[rh
])(m
, destval
,amt
);
4033 store_data_byte(m
,destoffset
,destval
);
4036 destoffset
=decode_rm01_address(m
,rl
);
4037 destval
= fetch_data_byte(m
,destoffset
);
4038 destval
= (*opcD0_byte_operation
[rh
])(m
, destval
, amt
);
4039 store_data_byte(m
,destoffset
,destval
);
4042 destoffset
=decode_rm10_address(m
,rl
);
4043 destval
= fetch_data_byte(m
,destoffset
);
4044 destval
= (*opcD0_byte_operation
[rh
])(m
, destval
, amt
);
4045 store_data_byte(m
,destoffset
,destval
);
4047 case 3: /* register to register */
4048 destreg
= DECODE_RM_BYTE_REGISTER(m
,rl
);
4049 destval
= (*opcD0_byte_operation
[rh
])(m
, *destreg
, amt
);
4053 DECODE_CLEAR_SEGOVR(m
);
4057 static void i86op_opcD3_word_RM_CL(PC_ENV
*m
)
4064 /* Yet another weirdo special case instruction format. Part of the
4065 opcode held below in "RH". Doubly nested case would
4066 result, except that the decoded instruction
4068 FETCH_DECODE_MODRM(m
,mod
,rh
,rl
);
4070 /* know operation, decode the mod byte to find the addressing
4075 destoffset
=decode_rm00_address(m
,rl
);
4076 destval
= fetch_data_word(m
,destoffset
);
4077 destval
= (*opcD1_word_operation
[rh
])(m
, destval
, amt
);
4078 store_data_word(m
,destoffset
,destval
);
4081 destoffset
=decode_rm01_address(m
,rl
);
4082 destval
= fetch_data_word(m
,destoffset
);
4083 destval
= (*opcD1_word_operation
[rh
])(m
, destval
, amt
);
4084 store_data_word(m
,destoffset
,destval
);
4087 destoffset
=decode_rm10_address(m
,rl
);
4088 destval
= fetch_data_word(m
,destoffset
);
4089 destval
= (*opcD1_word_operation
[rh
])(m
, destval
, amt
);
4090 store_data_word(m
,destoffset
,destval
);
4092 case 3: /* register to register */
4093 destreg
= DECODE_RM_WORD_REGISTER(m
,rl
);
4094 *destreg
= (*opcD1_word_operation
[rh
])(m
, *destreg
, amt
);
4097 DECODE_CLEAR_SEGOVR(m
);
4100 static void sys_fatal(int error
, char *fmt
, ...)
4104 fprintf(stderr
, "Fatal error: ");
4107 fprintf(stderr
, "<%d>",error
);
4108 fprintf(stderr
,"%s",strerror(error
));
4110 vfprintf(stderr
, fmt
, p
);
4112 fprintf(stderr
, NLP
"Exiting..." NLP
);
4117 static void i86op_aam(PC_ENV
*m
)
4119 a
= fetch_byte_imm(m
); /* this is a stupid encoding. */
4120 if (a
!= 10) sys_fatal(0,"error decoding aam" NLP
);
4121 /* note the type change here --- returning AL and AH in AX. */
4122 m
->R_AX
= aam_word(m
,m
->R_AL
);
4123 DECODE_CLEAR_SEGOVR(m
);
4127 static void i86op_aad(PC_ENV
*m
)
4129 a
= fetch_byte_imm(m
);
4130 m
->R_AX
= aad_word(m
,m
->R_AX
);
4131 DECODE_CLEAR_SEGOVR(m
);
4134 /* opcode=0xd6 ILLEGAL OPCODE */
4137 static void i86op_xlat(PC_ENV
*m
)
4140 addr
= m
->R_BX
+ (uint8
)m
->R_AL
;
4141 m
->R_AL
= fetch_data_byte(m
,addr
);
4142 DECODE_CLEAR_SEGOVR(m
);
4146 static void i86op_loopne(PC_ENV
*m
)
4149 ip
= (int8
)fetch_byte_imm(m
);
4150 ip
+= (int16
)m
->R_IP
;
4152 if (m
->R_CX
!= 0 && !ACCESS_FLAG(m
,F_ZF
)) /* CX != 0 and !ZF */
4154 DECODE_CLEAR_SEGOVR(m
);
4158 static void i86op_loope(PC_ENV
*m
)
4161 ip
= (int8
)fetch_byte_imm(m
);
4162 ip
+= (int16
)m
->R_IP
;
4164 if (m
->R_CX
!= 0 && ACCESS_FLAG(m
,F_ZF
)) /* CX != 0 and ZF */
4166 DECODE_CLEAR_SEGOVR(m
);
4170 static void i86op_loop(PC_ENV
*m
)
4173 ip
= (int8
)fetch_byte_imm(m
);
4174 ip
+= (int16
)m
->R_IP
;
4178 DECODE_CLEAR_SEGOVR(m
);
4182 static void i86op_jcxz(PC_ENV
*m
)
4184 int16 offset
,target
;
4185 /* jump to byte offset if overflow flag is set */
4186 offset
= (int8
)fetch_byte_imm(m
); /* sign extended ??? */
4187 target
= (int16
)m
->R_IP
+ offset
;
4190 DECODE_CLEAR_SEGOVR(m
);
4194 static void i86op_in_byte_AL_IMM(PC_ENV
*m
)
4197 port
= (uint8
)fetch_byte_imm(m
);
4199 DECODE_CLEAR_SEGOVR(m
);
4203 static void i86op_in_word_AX_IMM(PC_ENV
*m
)
4206 port
= (uint8
)fetch_byte_imm(m
);
4208 DECODE_CLEAR_SEGOVR(m
);
4212 static void i86op_out_byte_IMM_AL(PC_ENV
*m
)
4215 port
= (uint8
)fetch_byte_imm(m
);
4217 DECODE_CLEAR_SEGOVR(m
);
4221 static void i86op_out_word_IMM_AX(PC_ENV
*m
)
4224 port
= (uint8
)fetch_byte_imm(m
);
4226 DECODE_CLEAR_SEGOVR(m
);
4230 static void i86op_call_near_IMM(PC_ENV
*m
)
4233 /* weird. Thought this was a signed disp! */
4234 ip
= (int16
)fetch_word_imm(m
);
4235 ip
+= (int16
)m
->R_IP
; /* CHECK SIGN */
4236 push_word(m
,m
->R_IP
);
4238 DECODE_CLEAR_SEGOVR(m
);
4242 static void i86op_jump_near_IMM(PC_ENV
*m
)
4245 /* weird. Thought this was a signed disp too! */
4246 ip
= (int16
)fetch_word_imm(m
);
4247 ip
+= (int16
)m
->R_IP
; /* CHECK SIGN */
4249 DECODE_CLEAR_SEGOVR(m
);
4253 static void i86op_jump_far_IMM(PC_ENV
*m
)
4256 ip
= fetch_word_imm(m
);
4257 cs
= fetch_word_imm(m
);
4260 DECODE_CLEAR_SEGOVR(m
);
4264 static void i86op_jump_byte_IMM(PC_ENV
*m
)
4268 offset
= (int8
) fetch_byte_imm(m
); /* CHECK */
4269 /* printf("jump byte imm offset=%d\n",offset);*/
4270 target
= (int16
) m
->R_IP
+ offset
;
4272 DECODE_CLEAR_SEGOVR(m
);
4276 static void i86op_in_byte_AL_DX(PC_ENV
*m
)
4278 m
->R_AL
= in(m
->R_DX
);
4279 DECODE_CLEAR_SEGOVR(m
);
4283 static void i86op_in_word_AX_DX(PC_ENV
*m
)
4285 m
->R_AX
= in(m
->R_DX
);
4286 DECODE_CLEAR_SEGOVR(m
);
4290 static void i86op_out_byte_DX_AL(PC_ENV
*m
)
4292 out(m
->R_DX
, m
->R_AL
);
4293 DECODE_CLEAR_SEGOVR(m
);
4297 static void i86op_out_word_DX_AX(PC_ENV
*m
)
4299 out(m
->R_DX
, m
->R_AX
);
4300 DECODE_CLEAR_SEGOVR(m
);
4304 static void i86op_lock(PC_ENV
*m
)
4306 DECODE_CLEAR_SEGOVR(m
);
4309 /*opcode=0xf1 ILLEGAL OPERATION*/
4312 static void i86op_repne(PC_ENV
*m
)
4314 m
->sysmode
|= SYSMODE_PREFIX_REPNE
;
4315 DECODE_CLEAR_SEGOVR(m
);
4319 static void i86op_repe(PC_ENV
*m
)
4321 m
->sysmode
|= SYSMODE_PREFIX_REPE
;
4322 DECODE_CLEAR_SEGOVR(m
);
4326 static void i86op_halt(PC_ENV
*m
)
4329 DECODE_CLEAR_SEGOVR(m
);
4333 static void i86op_cmc(PC_ENV
*m
)
4335 /* complement the carry flag. */
4336 TOGGLE_FLAG(m
,F_CF
);
4337 DECODE_CLEAR_SEGOVR(m
);
4341 static void i86op_opcF6_byte_RM(PC_ENV
*m
)
4346 uint8 destval
,srcval
;
4347 /* long, drawn out code follows. Double switch for a total
4349 FETCH_DECODE_MODRM(m
,mod
,rh
,rl
);
4352 case 0: /* mod=00 */
4355 case 0: /* test byte imm */
4356 destoffset
=decode_rm00_address(m
,rl
);
4357 srcval
= fetch_byte_imm(m
);
4358 destval
= fetch_data_byte(m
,destoffset
);
4359 test_byte(m
, destval
, srcval
);
4365 destoffset
=decode_rm00_address(m
,rl
);
4366 destval
= fetch_data_byte(m
,destoffset
);
4367 destval
= not_byte(m
, destval
);
4368 store_data_byte(m
,destoffset
,destval
);
4371 destoffset
=decode_rm00_address(m
,rl
);
4372 destval
= fetch_data_byte(m
,destoffset
);
4373 destval
= neg_byte(m
, destval
);
4374 store_data_byte(m
,destoffset
,destval
);
4377 destoffset
=decode_rm00_address(m
,rl
);
4378 destval
= fetch_data_byte(m
,destoffset
);
4379 mul_byte(m
, destval
);
4382 destoffset
=decode_rm00_address(m
,rl
);
4383 destval
= fetch_data_byte(m
,destoffset
);
4384 imul_byte(m
, destval
);
4387 destoffset
=decode_rm00_address(m
,rl
);
4388 destval
= fetch_data_byte(m
,destoffset
);
4389 div_byte(m
, destval
);
4392 destoffset
=decode_rm00_address(m
,rl
);
4393 destval
= fetch_data_byte(m
,destoffset
);
4394 idiv_byte(m
, destval
);
4397 break; /* end mod==00 */
4398 case 1: /* mod=01 */
4401 case 0: /* test byte imm */
4402 destoffset
=decode_rm01_address(m
,rl
);
4403 srcval
= fetch_byte_imm(m
);
4404 destval
= fetch_data_byte(m
,destoffset
);
4405 test_byte(m
, destval
, srcval
);
4411 destoffset
=decode_rm01_address(m
,rl
);
4412 destval
= fetch_data_byte(m
,destoffset
);
4413 destval
= not_byte(m
, destval
);
4414 store_data_byte(m
,destoffset
,destval
);
4417 destoffset
=decode_rm01_address(m
,rl
);
4418 destval
= fetch_data_byte(m
,destoffset
);
4419 destval
= neg_byte(m
, destval
);
4420 store_data_byte(m
,destoffset
,destval
);
4423 destoffset
=decode_rm01_address(m
,rl
);
4424 destval
= fetch_data_byte(m
,destoffset
);
4425 mul_byte(m
, destval
);
4428 destoffset
=decode_rm01_address(m
,rl
);
4429 destval
= fetch_data_byte(m
,destoffset
);
4430 imul_byte(m
, destval
);
4433 destoffset
=decode_rm01_address(m
,rl
);
4434 destval
= fetch_data_byte(m
,destoffset
);
4435 div_byte(m
, destval
);
4438 destoffset
=decode_rm01_address(m
,rl
);
4439 destval
= fetch_data_byte(m
,destoffset
);
4440 idiv_byte(m
, destval
);
4443 break; /* end mod==01 */
4444 case 2: /* mod=10 */
4447 case 0: /* test byte imm */
4448 destoffset
=decode_rm10_address(m
,rl
);
4449 srcval
= fetch_byte_imm(m
);
4450 destval
= fetch_data_byte(m
,destoffset
);
4451 test_byte(m
, destval
, srcval
);
4457 destoffset
=decode_rm10_address(m
,rl
);
4458 destval
= fetch_data_byte(m
,destoffset
);
4459 destval
= not_byte(m
, destval
);
4460 store_data_byte(m
,destoffset
,destval
);
4463 destoffset
=decode_rm10_address(m
,rl
);
4464 destval
= fetch_data_byte(m
,destoffset
);
4465 destval
= neg_byte(m
, destval
);
4466 store_data_byte(m
,destoffset
,destval
);
4469 destoffset
=decode_rm10_address(m
,rl
);
4470 destval
= fetch_data_byte(m
,destoffset
);
4471 mul_byte(m
, destval
);
4474 destoffset
=decode_rm10_address(m
,rl
);
4475 destval
= fetch_data_byte(m
,destoffset
);
4476 imul_byte(m
, destval
);
4479 destoffset
=decode_rm10_address(m
,rl
);
4480 destval
= fetch_data_byte(m
,destoffset
);
4481 div_byte(m
, destval
);
4484 destoffset
=decode_rm10_address(m
,rl
);
4485 destval
= fetch_data_byte(m
,destoffset
);
4486 idiv_byte(m
, destval
);
4489 break; /* end mod==10 */
4490 case 3: /* mod=11 */
4493 case 0: /* test byte imm */
4494 destreg
=DECODE_RM_BYTE_REGISTER(m
,rl
);
4495 srcval
= fetch_byte_imm(m
);
4496 test_byte(m
, *destreg
, srcval
);
4502 destreg
=DECODE_RM_BYTE_REGISTER(m
,rl
);
4503 *destreg
= not_byte(m
, *destreg
);
4506 destreg
=DECODE_RM_BYTE_REGISTER(m
,rl
);
4507 *destreg
= neg_byte(m
, *destreg
);
4510 destreg
=DECODE_RM_BYTE_REGISTER(m
,rl
);
4511 mul_byte(m
, *destreg
); /*!!! */
4514 destreg
=DECODE_RM_BYTE_REGISTER(m
,rl
);
4515 imul_byte(m
, *destreg
);
4518 destreg
=DECODE_RM_BYTE_REGISTER(m
,rl
);
4519 div_byte(m
, *destreg
);
4522 destreg
=DECODE_RM_BYTE_REGISTER(m
,rl
);
4523 idiv_byte(m
, *destreg
);
4526 break; /* end mod==11 */
4528 DECODE_CLEAR_SEGOVR(m
);
4532 static void i86op_opcF7_word_RM(PC_ENV
*m
)
4537 uint16 destval
,srcval
;
4538 /* long, drawn out code follows. Double switch for a total
4540 FETCH_DECODE_MODRM(m
,mod
,rh
,rl
);
4543 case 0: /* mod=00 */
4546 case 0: /* test word imm */
4547 destoffset
=decode_rm00_address(m
,rl
);
4548 srcval
= fetch_word_imm(m
);
4549 destval
= fetch_data_word(m
,destoffset
);
4550 test_word(m
, destval
, srcval
);
4556 destoffset
=decode_rm00_address(m
,rl
);
4557 destval
= fetch_data_word(m
,destoffset
);
4558 destval
= not_word(m
, destval
);
4559 store_data_word(m
,destoffset
,destval
);
4562 destoffset
=decode_rm00_address(m
,rl
);
4563 destval
= fetch_data_word(m
,destoffset
);
4564 destval
= neg_word(m
, destval
);
4565 store_data_word(m
,destoffset
,destval
);
4568 destoffset
=decode_rm00_address(m
,rl
);
4569 destval
= fetch_data_word(m
,destoffset
);
4570 mul_word(m
, destval
);
4573 destoffset
=decode_rm00_address(m
,rl
);
4574 destval
= fetch_data_word(m
,destoffset
);
4575 imul_word(m
, destval
);
4578 destoffset
=decode_rm00_address(m
,rl
);
4579 destval
= fetch_data_word(m
,destoffset
);
4580 div_word(m
, destval
);
4583 destoffset
=decode_rm00_address(m
,rl
);
4584 destval
= fetch_data_word(m
,destoffset
);
4585 idiv_word(m
, destval
);
4588 break; /* end mod==00 */
4589 case 1: /* mod=01 */
4592 case 0: /* test word imm */
4593 destoffset
=decode_rm01_address(m
,rl
);
4594 srcval
= fetch_word_imm(m
);
4595 destval
= fetch_data_word(m
,destoffset
);
4596 test_word(m
, destval
, srcval
);
4602 destoffset
=decode_rm01_address(m
,rl
);
4603 destval
= fetch_data_word(m
,destoffset
);
4604 destval
= not_word(m
, destval
);
4605 store_data_word(m
,destoffset
,destval
);
4608 destoffset
=decode_rm01_address(m
,rl
);
4609 destval
= fetch_data_word(m
,destoffset
);
4610 destval
= neg_word(m
, destval
);
4611 store_data_word(m
,destoffset
,destval
);
4614 destoffset
=decode_rm01_address(m
,rl
);
4615 destval
= fetch_data_word(m
,destoffset
);
4616 mul_word(m
, destval
);
4619 destoffset
=decode_rm01_address(m
,rl
);
4620 destval
= fetch_data_word(m
,destoffset
);
4621 imul_word(m
, destval
);
4624 destoffset
=decode_rm01_address(m
,rl
);
4625 destval
= fetch_data_word(m
,destoffset
);
4626 div_word(m
, destval
);
4629 destoffset
=decode_rm01_address(m
,rl
);
4630 destval
= fetch_data_word(m
,destoffset
);
4631 idiv_word(m
, destval
);
4634 break; /* end mod==01 */
4635 case 2: /* mod=10 */
4638 case 0: /* test word imm */
4639 destoffset
=decode_rm10_address(m
,rl
);
4640 srcval
= fetch_word_imm(m
);
4641 destval
= fetch_data_word(m
,destoffset
);
4642 test_word(m
, destval
, srcval
);
4648 destoffset
=decode_rm10_address(m
,rl
);
4649 destval
= fetch_data_word(m
,destoffset
);
4650 destval
= not_word(m
, destval
);
4651 store_data_word(m
,destoffset
,destval
);
4654 destoffset
=decode_rm10_address(m
,rl
);
4655 destval
= fetch_data_word(m
,destoffset
);
4656 destval
= neg_word(m
, destval
);
4657 store_data_word(m
,destoffset
,destval
);
4660 destoffset
=decode_rm10_address(m
,rl
);
4661 destval
= fetch_data_word(m
,destoffset
);
4662 mul_word(m
, destval
);
4665 destoffset
=decode_rm10_address(m
,rl
);
4666 destval
= fetch_data_word(m
,destoffset
);
4667 imul_word(m
, destval
);
4670 destoffset
=decode_rm10_address(m
,rl
);
4671 destval
= fetch_data_word(m
,destoffset
);
4672 div_word(m
, destval
);
4675 destoffset
=decode_rm10_address(m
,rl
);
4676 destval
= fetch_data_word(m
,destoffset
);
4677 idiv_word(m
, destval
);
4680 break; /* end mod==10 */
4681 case 3: /* mod=11 */
4684 case 0: /* test word imm */
4685 destreg
=DECODE_RM_WORD_REGISTER(m
,rl
);
4686 srcval
= fetch_word_imm(m
);
4687 test_word(m
, *destreg
, srcval
);
4693 destreg
=DECODE_RM_WORD_REGISTER(m
,rl
);
4694 *destreg
= not_word(m
, *destreg
);
4697 destreg
=DECODE_RM_WORD_REGISTER(m
,rl
);
4698 *destreg
= neg_word(m
, *destreg
);
4701 destreg
=DECODE_RM_WORD_REGISTER(m
,rl
);
4702 mul_word(m
, *destreg
); /*!!! */
4705 destreg
=DECODE_RM_WORD_REGISTER(m
,rl
);
4706 imul_word(m
, *destreg
);
4709 destreg
=DECODE_RM_WORD_REGISTER(m
,rl
);
4710 div_word(m
, *destreg
);
4713 destreg
=DECODE_RM_WORD_REGISTER(m
,rl
);
4714 idiv_word(m
, *destreg
);
4717 break; /* end mod==11 */
4719 DECODE_CLEAR_SEGOVR(m
);
4723 static void i86op_clc(PC_ENV
*m
)
4725 /* clear the carry flag. */
4726 CLEAR_FLAG(m
, F_CF
);
4727 DECODE_CLEAR_SEGOVR(m
);
4731 static void i86op_stc(PC_ENV
*m
)
4733 /* set the carry flag. */
4735 DECODE_CLEAR_SEGOVR(m
);
4739 static void i86op_cli(PC_ENV
*m
)
4741 /* clear interrupts. */
4742 CLEAR_FLAG(m
, F_IF
);
4743 DECODE_CLEAR_SEGOVR(m
);
4747 static void i86op_sti(PC_ENV
*m
)
4749 /* enable interrupts. */
4751 DECODE_CLEAR_SEGOVR(m
);
4755 static void i86op_cld(PC_ENV
*m
)
4757 /* clear interrupts. */
4758 CLEAR_FLAG(m
, F_DF
);
4759 DECODE_CLEAR_SEGOVR(m
);
4763 static void i86op_std(PC_ENV
*m
)
4765 /* clear interrupts. */
4767 DECODE_CLEAR_SEGOVR(m
);
4771 static void i86op_opcFE_byte_RM(PC_ENV
*m
)
4773 /* Yet another damned special case instruction. */
4778 /* ARRGH, ANOTHER GODDAMN SPECIAL CASE INSTRUCTION!!! */
4779 FETCH_DECODE_MODRM(m
,mod
,rh
,rl
);
4783 destoffset
=decode_rm00_address(m
,rl
);
4786 case 0: /* inc word ptr ... */
4787 destval
= fetch_data_byte(m
,destoffset
);
4788 destval
= inc_byte(m
,destval
);
4789 store_data_byte(m
,destoffset
,destval
);
4791 case 1: /* dec word ptr ... */
4792 destval
= fetch_data_byte(m
,destoffset
);
4793 destval
= dec_byte(m
,destval
);
4794 store_data_byte(m
,destoffset
,destval
);
4799 destoffset
=decode_rm01_address(m
,rl
);
4803 destval
= fetch_data_byte(m
,destoffset
);
4804 destval
= inc_byte(m
,destval
);
4805 store_data_byte(m
,destoffset
,destval
);
4808 destval
= fetch_data_byte(m
,destoffset
);
4809 destval
= dec_byte(m
,destval
);
4810 store_data_byte(m
,destoffset
,destval
);
4815 destoffset
=decode_rm10_address(m
,rl
);
4819 destval
= fetch_data_byte(m
,destoffset
);
4820 destval
= inc_byte(m
,destval
);
4821 store_data_byte(m
,destoffset
,destval
);
4824 destval
= fetch_data_byte(m
,destoffset
);
4825 destval
= dec_byte(m
,destval
);
4826 store_data_byte(m
,destoffset
,destval
);
4831 destreg
= DECODE_RM_BYTE_REGISTER(m
,rl
);
4835 *destreg
= inc_byte(m
,*destreg
);
4838 *destreg
= dec_byte(m
,*destreg
);
4843 DECODE_CLEAR_SEGOVR(m
);
4847 static void i86op_opcFF_word_RM(PC_ENV
*m
)
4850 uint16 destval
,destval2
;
4853 /* ANOTHER DAMN SPECIAL CASE INSTRUCTION!!! */
4854 FETCH_DECODE_MODRM(m
,mod
,rh
,rl
);
4858 destoffset
=decode_rm00_address(m
,rl
);
4861 case 0: /* inc word ptr ... */
4862 destval
= fetch_data_word(m
,destoffset
);
4863 destval
= inc_word(m
,destval
);
4864 store_data_word(m
,destoffset
,destval
);
4866 case 1: /* dec word ptr ... */
4867 destval
= fetch_data_word(m
,destoffset
);
4868 destval
= dec_word(m
,destval
);
4869 store_data_word(m
,destoffset
,destval
);
4871 case 2: /* call word ptr ... */
4872 destval
= fetch_data_word(m
,destoffset
);
4873 push_word(m
,m
->R_IP
);
4876 case 3: /* call far ptr ... */
4877 destval
= fetch_data_word(m
,destoffset
);
4878 destval2
= fetch_data_word(m
,destoffset
+2);
4879 push_word(m
,m
->R_CS
);
4881 push_word(m
,m
->R_IP
);
4884 case 4: /* jmp word ptr ... */
4885 destval
= fetch_data_word(m
,destoffset
);
4888 case 5: /* jmp far ptr ... */
4889 destval
= fetch_data_word(m
,destoffset
);
4890 destval2
= fetch_data_word(m
,destoffset
+2);
4894 case 6: /* push word ptr ... */
4895 destval
= fetch_data_word(m
,destoffset
);
4896 push_word(m
,destval
);
4901 destoffset
=decode_rm01_address(m
,rl
);
4905 destval
= fetch_data_word(m
,destoffset
);
4906 destval
= inc_word(m
,destval
);
4907 store_data_word(m
,destoffset
,destval
);
4910 destval
= fetch_data_word(m
,destoffset
);
4911 destval
= dec_word(m
,destval
);
4912 store_data_word(m
,destoffset
,destval
);
4914 case 2: /* call word ptr ... */
4915 destval
= fetch_data_word(m
,destoffset
);
4916 push_word(m
,m
->R_IP
);
4919 case 3: /* call far ptr ... */
4920 destval
= fetch_data_word(m
,destoffset
);
4921 destval2
= fetch_data_word(m
,destoffset
+2);
4922 push_word(m
,m
->R_CS
);
4924 push_word(m
,m
->R_IP
);
4927 case 4: /* jmp word ptr ... */
4928 destval
= fetch_data_word(m
,destoffset
);
4931 case 5: /* jmp far ptr ... */
4932 destval
= fetch_data_word(m
,destoffset
);
4933 destval2
= fetch_data_word(m
,destoffset
+2);
4937 case 6: /* push word ptr ... */
4938 destval
= fetch_data_word(m
,destoffset
);
4939 push_word(m
,destval
);
4944 destoffset
=decode_rm10_address(m
,rl
);
4948 destval
= fetch_data_word(m
,destoffset
);
4949 destval
= inc_word(m
,destval
);
4950 store_data_word(m
,destoffset
,destval
);
4953 destval
= fetch_data_word(m
,destoffset
);
4954 destval
= dec_word(m
,destval
);
4955 store_data_word(m
,destoffset
,destval
);
4957 case 2: /* call word ptr ... */
4958 destval
= fetch_data_word(m
,destoffset
);
4959 push_word(m
,m
->R_IP
);
4962 case 3: /* call far ptr ... */
4963 destval
= fetch_data_word(m
,destoffset
);
4964 destval2
= fetch_data_word(m
,destoffset
+2);
4965 push_word(m
,m
->R_CS
);
4967 push_word(m
,m
->R_IP
);
4970 case 4: /* jmp word ptr ... */
4971 destval
= fetch_data_word(m
,destoffset
);
4974 case 5: /* jmp far ptr ... */
4975 destval
= fetch_data_word(m
,destoffset
);
4976 destval2
= fetch_data_word(m
,destoffset
+2);
4980 case 6: /* push word ptr ... */
4981 destval
= fetch_data_word(m
,destoffset
);
4982 push_word(m
,destval
);
4987 destreg
= DECODE_RM_WORD_REGISTER(m
,rl
);
4991 *destreg
= inc_word(m
,*destreg
);
4994 *destreg
= dec_word(m
,*destreg
);
4996 case 2: /* call word ptr ... */
4997 push_word(m
,m
->R_IP
);
5000 case 3: /* jmp far ptr ... */
5003 case 4: /* jmp ... */
5004 m
->R_IP
= (uint16
)(*destreg
);
5006 case 5: /* jmp far ptr ... */
5010 push_word(m
,*destreg
);
5015 DECODE_CLEAR_SEGOVR(m
);
5019 static void i86op_esc_coprocess_d8(PC_ENV
*m
)
5021 DECODE_CLEAR_SEGOVR(m
);
5025 static void i86op_esc_coprocess_d9(PC_ENV
*m
)
5030 FETCH_DECODE_MODRM(m
,mod
,rh
,rl
);
5034 destoffset
=decode_rm00_address(m
,rl
);
5037 destoffset
=decode_rm01_address(m
,rl
);
5040 destoffset
=decode_rm10_address(m
,rl
);
5042 case 3: /* register to register */
5043 stkelem
= (uint8
) rl
;
5046 DECODE_CLEAR_SEGOVR(m
);
5050 static void i86op_esc_coprocess_da(PC_ENV
*m
)
5055 FETCH_DECODE_MODRM(m
,mod
,rh
,rl
);
5059 destoffset
=decode_rm00_address(m
,rl
);
5062 destoffset
=decode_rm01_address(m
,rl
);
5065 destoffset
=decode_rm10_address(m
,rl
);
5067 case 3: /* register to register */
5068 stkelem
= (uint8
) rl
;
5071 DECODE_CLEAR_SEGOVR(m
);
5075 static void i86op_esc_coprocess_db(PC_ENV
*m
)
5080 FETCH_DECODE_MODRM(m
,mod
,rh
,rl
);
5084 destoffset
=decode_rm00_address(m
,rl
);
5087 destoffset
=decode_rm01_address(m
,rl
);
5090 destoffset
=decode_rm10_address(m
,rl
);
5092 case 3: /* register to register */
5095 DECODE_CLEAR_SEGOVR(m
);
5099 static void i86op_esc_coprocess_dc(PC_ENV
*m
)
5104 FETCH_DECODE_MODRM(m
,mod
,rh
,rl
);
5108 destoffset
=decode_rm00_address(m
,rl
);
5111 destoffset
=decode_rm01_address(m
,rl
);
5114 destoffset
=decode_rm10_address(m
,rl
);
5116 case 3: /* register to register */
5117 stkelem
= (uint8
) rl
;
5120 DECODE_CLEAR_SEGOVR(m
);
5124 static void i86op_esc_coprocess_dd(PC_ENV
*m
)
5129 FETCH_DECODE_MODRM(m
,mod
,rh
,rl
);
5133 destoffset
=decode_rm00_address(m
,rl
);
5136 destoffset
=decode_rm01_address(m
,rl
);
5139 destoffset
=decode_rm10_address(m
,rl
);
5141 case 3: /* register to register */
5142 stkelem
= (uint8
) rl
;
5145 DECODE_CLEAR_SEGOVR(m
);
5149 static void i86op_esc_coprocess_de(PC_ENV
*m
)
5154 FETCH_DECODE_MODRM(m
,mod
,rh
,rl
);
5158 destoffset
=decode_rm00_address(m
,rl
);
5161 destoffset
=decode_rm01_address(m
,rl
);
5164 destoffset
=decode_rm10_address(m
,rl
);
5166 case 3: /* register to register */
5167 stkelem
= (uint8
) rl
;
5170 DECODE_CLEAR_SEGOVR(m
);
5174 static void i86op_esc_coprocess_df(PC_ENV
*m
)
5179 FETCH_DECODE_MODRM(m
,mod
,rh
,rl
);
5183 destoffset
=decode_rm00_address(m
,rl
);
5186 destoffset
=decode_rm01_address(m
,rl
);
5189 destoffset
=decode_rm10_address(m
,rl
);
5191 case 3: /* register to register */
5192 stkelem
= (uint8
) rl
;
5195 DECODE_CLEAR_SEGOVR(m
);
5200 OP i86_optab
[256] = {
5202 /* 0x00 */ i86op_add_byte_RM_R
,
5203 /* 0x01 */ i86op_add_word_RM_R
,
5204 /* 0x02 */ i86op_add_byte_R_RM
,
5205 /* 0x03 */ i86op_add_word_R_RM
,
5206 /* 0x04 */ i86op_add_byte_AL_IMM
,
5207 /* 0x05 */ i86op_add_word_AX_IMM
,
5208 /* 0x06 */ i86op_push_ES
,
5209 /* 0x07 */ i86op_pop_ES
,
5211 /* 0x08 */ i86op_or_byte_RM_R
,
5212 /* 0x09 */ i86op_or_word_RM_R
,
5213 /* 0x0a */ i86op_or_byte_R_RM
,
5214 /* 0x0b */ i86op_or_word_R_RM
,
5215 /* 0x0c */ i86op_or_byte_AL_IMM
,
5216 /* 0x0d */ i86op_or_word_AX_IMM
,
5217 /* 0x0e */ i86op_push_CS
,
5218 /* 0x0f */ i86op_illegal_op
,
5220 /* 0x10 */ i86op_adc_byte_RM_R
,
5221 /* 0x11 */ i86op_adc_word_RM_R
,
5222 /* 0x12 */ i86op_adc_byte_R_RM
,
5223 /* 0x13 */ i86op_adc_word_R_RM
,
5224 /* 0x14 */ i86op_adc_byte_AL_IMM
,
5225 /* 0x15 */ i86op_adc_word_AX_IMM
,
5226 /* 0x16 */ i86op_push_SS
,
5227 /* 0x17 */ i86op_pop_SS
,
5229 /* 0x18 */ i86op_sbb_byte_RM_R
,
5230 /* 0x19 */ i86op_sbb_word_RM_R
,
5231 /* 0x1a */ i86op_sbb_byte_R_RM
,
5232 /* 0x1b */ i86op_sbb_word_R_RM
,
5233 /* 0x1c */ i86op_sbb_byte_AL_IMM
,
5234 /* 0x1d */ i86op_sbb_word_AX_IMM
,
5235 /* 0x1e */ i86op_push_DS
,
5236 /* 0x1f */ i86op_pop_DS
,
5238 /* 0x20 */ i86op_and_byte_RM_R
,
5239 /* 0x21 */ i86op_and_word_RM_R
,
5240 /* 0x22 */ i86op_and_byte_R_RM
,
5241 /* 0x23 */ i86op_and_word_R_RM
,
5242 /* 0x24 */ i86op_and_byte_AL_IMM
,
5243 /* 0x25 */ i86op_and_word_AX_IMM
,
5244 /* 0x26 */ i86op_segovr_ES
,
5245 /* 0x27 */ i86op_daa
,
5247 /* 0x28 */ i86op_sub_byte_RM_R
,
5248 /* 0x29 */ i86op_sub_word_RM_R
,
5249 /* 0x2a */ i86op_sub_byte_R_RM
,
5250 /* 0x2b */ i86op_sub_word_R_RM
,
5251 /* 0x2c */ i86op_sub_byte_AL_IMM
,
5252 /* 0x2d */ i86op_sub_word_AX_IMM
,
5253 /* 0x2e */ i86op_segovr_CS
,
5254 /* 0x2f */ i86op_das
,
5256 /* 0x30 */ i86op_xor_byte_RM_R
,
5257 /* 0x31 */ i86op_xor_word_RM_R
,
5258 /* 0x32 */ i86op_xor_byte_R_RM
,
5259 /* 0x33 */ i86op_xor_word_R_RM
,
5260 /* 0x34 */ i86op_xor_byte_AL_IMM
,
5261 /* 0x35 */ i86op_xor_word_AX_IMM
,
5262 /* 0x36 */ i86op_segovr_SS
,
5263 /* 0x37 */ i86op_aaa
,
5265 /* 0x38 */ i86op_cmp_byte_RM_R
,
5266 /* 0x39 */ i86op_cmp_word_RM_R
,
5267 /* 0x3a */ i86op_cmp_byte_R_RM
,
5268 /* 0x3b */ i86op_cmp_word_R_RM
,
5269 /* 0x3c */ i86op_cmp_byte_AL_IMM
,
5270 /* 0x3d */ i86op_cmp_word_AX_IMM
,
5271 /* 0x3e */ i86op_segovr_DS
,
5272 /* 0x3f */ i86op_aas
,
5274 /* 0x40 */ i86op_inc_AX
,
5275 /* 0x41 */ i86op_inc_CX
,
5276 /* 0x42 */ i86op_inc_DX
,
5277 /* 0x43 */ i86op_inc_BX
,
5278 /* 0x44 */ i86op_inc_SP
,
5279 /* 0x45 */ i86op_inc_BP
,
5280 /* 0x46 */ i86op_inc_SI
,
5281 /* 0x47 */ i86op_inc_DI
,
5283 /* 0x48 */ i86op_dec_AX
,
5284 /* 0x49 */ i86op_dec_CX
,
5285 /* 0x4a */ i86op_dec_DX
,
5286 /* 0x4b */ i86op_dec_BX
,
5287 /* 0x4c */ i86op_dec_SP
,
5288 /* 0x4d */ i86op_dec_BP
,
5289 /* 0x4e */ i86op_dec_SI
,
5290 /* 0x4f */ i86op_dec_DI
,
5292 /* 0x50 */ i86op_push_AX
,
5293 /* 0x51 */ i86op_push_CX
,
5294 /* 0x52 */ i86op_push_DX
,
5295 /* 0x53 */ i86op_push_BX
,
5296 /* 0x54 */ i86op_push_SP
,
5297 /* 0x55 */ i86op_push_BP
,
5298 /* 0x56 */ i86op_push_SI
,
5299 /* 0x57 */ i86op_push_DI
,
5301 /* 0x58 */ i86op_pop_AX
,
5302 /* 0x59 */ i86op_pop_CX
,
5303 /* 0x5a */ i86op_pop_DX
,
5304 /* 0x5b */ i86op_pop_BX
,
5305 /* 0x5c */ i86op_pop_SP
,
5306 /* 0x5d */ i86op_pop_BP
,
5307 /* 0x5e */ i86op_pop_SI
,
5308 /* 0x5f */ i86op_pop_DI
,
5310 /* 0x60 */ i86op_illegal_op
,
5311 /* 0x61 */ i86op_illegal_op
,
5312 /* 0x62 */ i86op_illegal_op
,
5313 /* 0x63 */ i86op_illegal_op
,
5314 /* 0x64 */ i86op_illegal_op
,
5315 /* 0x65 */ i86op_illegal_op
,
5316 /* 0x66 */ i86op_illegal_op
,
5317 /* 0x67 */ i86op_illegal_op
,
5319 /* 0x68 */ i86op_illegal_op
,
5320 /* 0x69 */ i86op_illegal_op
,
5321 /* 0x6a */ i86op_illegal_op
,
5322 /* 0x6b */ i86op_illegal_op
,
5323 /* 0x6c */ i86op_illegal_op
,
5324 /* 0x6d */ i86op_illegal_op
,
5325 /* 0x6e */ i86op_illegal_op
,
5326 /* 0x6f */ i86op_illegal_op
,
5328 /* 0x70 */ i86op_jump_near_O
,
5329 /* 0x71 */ i86op_jump_near_NO
,
5330 /* 0x72 */ i86op_jump_near_B
,
5331 /* 0x73 */ i86op_jump_near_NB
,
5332 /* 0x74 */ i86op_jump_near_Z
,
5333 /* 0x75 */ i86op_jump_near_NZ
,
5334 /* 0x76 */ i86op_jump_near_BE
,
5335 /* 0x77 */ i86op_jump_near_NBE
,
5337 /* 0x78 */ i86op_jump_near_S
,
5338 /* 0x79 */ i86op_jump_near_NS
,
5339 /* 0x7a */ i86op_jump_near_P
,
5340 /* 0x7b */ i86op_jump_near_NP
,
5341 /* 0x7c */ i86op_jump_near_L
,
5342 /* 0x7d */ i86op_jump_near_NL
,
5343 /* 0x7e */ i86op_jump_near_LE
,
5344 /* 0x7f */ i86op_jump_near_NLE
,
5346 /* 0x80 */ i86op_opc80_byte_RM_IMM
,
5347 /* 0x81 */ i86op_opc81_word_RM_IMM
,
5348 /* 0x82 */ i86op_opc82_byte_RM_IMM
,
5349 /* 0x83 */ i86op_opc83_word_RM_IMM
,
5350 /* 0x84 */ i86op_test_byte_RM_R
,
5351 /* 0x85 */ i86op_test_word_RM_R
,
5352 /* 0x86 */ i86op_xchg_byte_RM_R
,
5353 /* 0x87 */ i86op_xchg_word_RM_R
,
5355 /* 0x88 */ i86op_mov_byte_RM_R
,
5356 /* 0x89 */ i86op_mov_word_RM_R
,
5357 /* 0x8a */ i86op_mov_byte_R_RM
,
5358 /* 0x8b */ i86op_mov_word_R_RM
,
5359 /* 0x8c */ i86op_mov_word_RM_SR
,
5360 /* 0x8d */ i86op_lea_word_R_M
,
5361 /* 0x8e */ i86op_mov_word_SR_RM
,
5362 /* 0x8f */ i86op_pop_RM
,
5364 /* 0x90 */ i86op_nop
,
5365 /* 0x91 */ i86op_xchg_word_AX_CX
,
5366 /* 0x92 */ i86op_xchg_word_AX_DX
,
5367 /* 0x93 */ i86op_xchg_word_AX_BX
,
5368 /* 0x94 */ i86op_xchg_word_AX_SP
,
5369 /* 0x95 */ i86op_xchg_word_AX_BP
,
5370 /* 0x96 */ i86op_xchg_word_AX_SI
,
5371 /* 0x97 */ i86op_xchg_word_AX_DI
,
5373 /* 0x98 */ i86op_cbw
,
5374 /* 0x99 */ i86op_cwd
,
5375 /* 0x9a */ i86op_call_far_IMM
,
5376 /* 0x9b */ i86op_wait
,
5377 /* 0x9c */ i86op_pushf_word
,
5378 /* 0x9d */ i86op_popf_word
,
5379 /* 0x9e */ i86op_sahf
,
5380 /* 0x9f */ i86op_lahf
,
5382 /* 0xa0 */ i86op_mov_AL_M_IMM
,
5383 /* 0xa1 */ i86op_mov_AX_M_IMM
,
5384 /* 0xa2 */ i86op_mov_M_AL_IMM
,
5385 /* 0xa3 */ i86op_mov_M_AX_IMM
,
5386 /* 0xa4 */ i86op_movs_byte
,
5387 /* 0xa5 */ i86op_movs_word
,
5388 /* 0xa6 */ i86op_cmps_byte
,
5389 /* 0xa7 */ i86op_cmps_word
,
5390 /* 0xa8 */ i86op_test_AL_IMM
,
5391 /* 0xa9 */ i86op_test_AX_IMM
,
5392 /* 0xaa */ i86op_stos_byte
,
5393 /* 0xab */ i86op_stos_word
,
5394 /* 0xac */ i86op_lods_byte
,
5395 /* 0xad */ i86op_lods_word
,
5396 /* 0xac */ i86op_scas_byte
,
5397 /* 0xad */ i86op_scas_word
,
5399 /* 0xb0 */ i86op_mov_byte_AL_IMM
,
5400 /* 0xb1 */ i86op_mov_byte_CL_IMM
,
5401 /* 0xb2 */ i86op_mov_byte_DL_IMM
,
5402 /* 0xb3 */ i86op_mov_byte_BL_IMM
,
5403 /* 0xb4 */ i86op_mov_byte_AH_IMM
,
5404 /* 0xb5 */ i86op_mov_byte_CH_IMM
,
5405 /* 0xb6 */ i86op_mov_byte_DH_IMM
,
5406 /* 0xb7 */ i86op_mov_byte_BH_IMM
,
5408 /* 0xb8 */ i86op_mov_word_AX_IMM
,
5409 /* 0xb9 */ i86op_mov_word_CX_IMM
,
5410 /* 0xba */ i86op_mov_word_DX_IMM
,
5411 /* 0xbb */ i86op_mov_word_BX_IMM
,
5412 /* 0xbc */ i86op_mov_word_SP_IMM
,
5413 /* 0xbd */ i86op_mov_word_BP_IMM
,
5414 /* 0xbe */ i86op_mov_word_SI_IMM
,
5415 /* 0xbf */ i86op_mov_word_DI_IMM
,
5417 /* 0xc0 */ i86op_illegal_op
,
5418 /* 0xc1 */ i86op_illegal_op
,
5419 /* 0xc2 */ i86op_ret_near_IMM
,
5420 /* 0xc3 */ i86op_ret_near
,
5421 /* 0xc4 */ i86op_les_R_IMM
,
5422 /* 0xc5 */ i86op_lds_R_IMM
,
5423 /* 0xc6 */ i86op_mov_byte_RM_IMM
,
5424 /* 0xc7 */ i86op_mov_word_RM_IMM
,
5425 /* 0xc8 */ i86op_illegal_op
,
5426 /* 0xc9 */ i86op_illegal_op
,
5427 /* 0xca */ i86op_ret_far_IMM
,
5428 /* 0xcb */ i86op_ret_far
,
5429 /* 0xcc */ i86op_int3
,
5430 /* 0xcd */ i86op_int_IMM
,
5431 /* 0xce */ i86op_into
,
5432 /* 0xcf */ i86op_iret
,
5434 /* 0xd0 */ i86op_opcD0_byte_RM_1
,
5435 /* 0xd1 */ i86op_opcD1_word_RM_1
,
5436 /* 0xd2 */ i86op_opcD2_byte_RM_CL
,
5437 /* 0xd3 */ i86op_opcD3_word_RM_CL
,
5438 /* 0xd4 */ i86op_aam
,
5439 /* 0xd5 */ i86op_aad
,
5440 /* 0xd6 */ i86op_illegal_op
,
5441 /* 0xd7 */ i86op_xlat
,
5442 /* 0xd8 */ i86op_esc_coprocess_d8
,
5443 /* 0xd9 */ i86op_esc_coprocess_d9
,
5444 /* 0xda */ i86op_esc_coprocess_da
,
5445 /* 0xdb */ i86op_esc_coprocess_db
,
5446 /* 0xdc */ i86op_esc_coprocess_dc
,
5447 /* 0xdd */ i86op_esc_coprocess_dd
,
5448 /* 0xde */ i86op_esc_coprocess_de
,
5449 /* 0xdf */ i86op_esc_coprocess_df
,
5451 /* 0xe0 */ i86op_loopne
,
5452 /* 0xe1 */ i86op_loope
,
5453 /* 0xe2 */ i86op_loop
,
5454 /* 0xe3 */ i86op_jcxz
,
5455 /* 0xe4 */ i86op_in_byte_AL_IMM
,
5456 /* 0xe5 */ i86op_in_word_AX_IMM
,
5457 /* 0xe6 */ i86op_out_byte_IMM_AL
,
5458 /* 0xe7 */ i86op_out_word_IMM_AX
,
5460 /* 0xe8 */ i86op_call_near_IMM
,
5461 /* 0xe9 */ i86op_jump_near_IMM
,
5462 /* 0xea */ i86op_jump_far_IMM
,
5463 /* 0xeb */ i86op_jump_byte_IMM
,
5464 /* 0xec */ i86op_in_byte_AL_DX
,
5465 /* 0xed */ i86op_in_word_AX_DX
,
5466 /* 0xee */ i86op_out_byte_DX_AL
,
5467 /* 0xef */ i86op_out_word_DX_AX
,
5469 /* 0xf0 */ i86op_lock
,
5470 /* 0xf1 */ i86op_illegal_op
,
5471 /* 0xf2 */ i86op_repne
,
5472 /* 0xf3 */ i86op_repe
,
5473 /* 0xf4 */ i86op_halt
,
5474 /* 0xf5 */ i86op_cmc
,
5475 /* 0xf6 */ i86op_opcF6_byte_RM
,
5476 /* 0xf7 */ i86op_opcF7_word_RM
,
5478 /* 0xf8 */ i86op_clc
,
5479 /* 0xf9 */ i86op_stc
,
5480 /* 0xfa */ i86op_cli
,
5481 /* 0xfb */ i86op_sti
,
5482 /* 0xfc */ i86op_cld
,
5483 /* 0xfd */ i86op_std
,
5484 /* 0xfe */ i86op_opcFE_byte_RM
,
5485 /* 0xff */ i86op_opcFF_word_RM
,