1 /****************************************************************************
2 * *
3 * Third Year Project *
4 * *
5 * An IBM PC Emulator *
6 * For Unix and X Windows *
7 * *
8 * By David Hedley *
9 * *
10 * *
11 * This program is Copyrighted. Consult the file COPYRIGHT for more details *
12 * *
13 ****************************************************************************/
14
15 /* This is CPU.C It emulates the 8086 processor */
16
17 #include "global.h"
18
19 #include <stdio.h>
20
21 #include "mytypes.h"
22 #include "cpu.h"
23 #include "instr.h"
24 #include "hardware.h"
25
26 #ifdef DEBUGGER
27 # include "debugger.h"
28 #endif
29
30 #ifdef DEBUG
31 # include <stdlib.h>
32 #endif
33
34 WORD wregs[8]; /* Always little-endian */
35 BYTE *bregs[16]; /* Points to bytes within wregs[] */
36 unsigned sregs[4]; /* Always native machine word order */
37
38 unsigned ip; /* Always native machine word order */
39
40
41 /* All the byte flags will either be 1 or 0 */
42
43 BYTE CF, PF, ZF, TF, IF, DF;
44
45 /* All the word flags may be either none-zero (true) or zero (false) */
46
47 unsigned AF, OF, SF;
48
49
50 static UINT8 parity_table[256];
51 static BYTE *ModRMRegB[256];
52 static WORD *ModRMRegW[256];
53
54 /* 'Shadows' of the segment registers. Point directly into the start of the
55 segment within memory[] */
56 BYTE *c_cs,*c_ds,*c_es,*c_ss,*c_stack;
57
58 volatile int int_pending; /* Interrupt pending */
59 volatile int int_blocked; /* Blocked pending */
60
61 static struct
62 {
63 BYTE **segment;
64 WORD *reg1;
65 WORD *reg2;
66 int offset;
67 int offset16;
68 int pad[3]; /* Make structure power of 2 bytes wide for speed */
69 } ModRMRM[256];
70
71 static WORD zero_word = 0;
72
73 static WORD *ModRMRMWRegs[256];
74 static BYTE *ModRMRMBRegs[256];
75
76 void trap(void);
77
78 #define PushSeg(Seg) \
79 { \
80 register unsigned tmp = (WORD)(ReadWord(&wregs[SP])-2); \
81 WriteWord(&wregs[SP],tmp); \
82 PutMemW(c_stack,tmp,sregs[Seg]); \
83 }
84
85
86 #define PopSeg(seg, Seg) \
87 { \
88 register unsigned tmp = ReadWord(&wregs[SP]); \
89 sregs[Seg] = GetMemW(c_stack,tmp); \
90 seg = SegToMemPtr(Seg); \
91 tmp += 2; \
92 WriteWord(&wregs[SP],tmp); \
93 }
94
95
96 #define PushWordReg(Reg) \
97 { \
98 register unsigned tmp1 = (WORD)(ReadWord(&wregs[SP])-2); \
99 WORD tmp2; \
100 WriteWord(&wregs[SP],tmp1); \
101 tmp2 = ReadWord(&wregs[Reg]); \
102 PutMemW(c_stack,tmp1,tmp2); \
103 }
104
105
106 #define PopWordReg(Reg) \
107 { \
108 register unsigned tmp = ReadWord(&wregs[SP]); \
109 WORD tmp2 = GetMemW(c_stack,tmp); \
110 tmp += 2; \
111 WriteWord(&wregs[SP],tmp); \
112 WriteWord(&wregs[Reg],tmp2); \
113 }
114
115
116 #define XchgAXReg(Reg) \
117 { \
118 register unsigned tmp; \
119 tmp = wregs[Reg]; \
120 wregs[Reg] = wregs[AX]; \
121 wregs[AX] = tmp; \
122 }
123
124
125 #define IncWordReg(Reg) \
126 { \
127 register unsigned tmp = (unsigned)ReadWord(&wregs[Reg]); \
128 register unsigned tmp1 = tmp+1; \
129 SetOFW_Add(tmp1,tmp,1); \
130 SetAF(tmp1,tmp,1); \
131 SetZFW(tmp1); \
132 SetSFW(tmp1); \
133 SetPF(tmp1); \
134 WriteWord(&wregs[Reg],tmp1); \
135 }
136
137
138 #define DecWordReg(Reg) \
139 { \
140 register unsigned tmp = (unsigned)ReadWord(&wregs[Reg]); \
141 register unsigned tmp1 = tmp-1; \
142 SetOFW_Sub(tmp1,1,tmp); \
143 SetAF(tmp1,tmp,1); \
144 SetZFW(tmp1); \
145 SetSFW(tmp1); \
146 SetPF(tmp1); \
147 WriteWord(&wregs[Reg],tmp1); \
148 }
149
150
151 #define Logical_br8(op) \
152 { \
153 unsigned ModRM = (unsigned)GetMemInc(c_cs,ip); \
154 register unsigned src = (unsigned)*GetModRMRegB(ModRM); \
155 BYTE *dest = GetModRMRMB(ModRM); \
156 register unsigned tmp = (unsigned) *dest; \
157 tmp op ## = src; \
158 CF = OF = AF = 0; \
159 SetZFB(tmp); \
160 SetSFB(tmp); \
161 SetPF(tmp); \
162 *dest = (BYTE)tmp; \
163 }
164
165
166 #define Logical_r8b(op) \
167 { \
168 unsigned ModRM = (unsigned)GetMemInc(c_cs,ip); \
169 register unsigned src = (unsigned)*GetModRMRMB(ModRM); \
170 BYTE *dest = GetModRMRegB(ModRM); \
171 register unsigned tmp = (unsigned) *dest; \
172 tmp op ## = src; \
173 CF = OF = AF = 0; \
174 SetZFB(tmp); \
175 SetSFB(tmp); \
176 SetPF(tmp); \
177 *dest = (BYTE)tmp; \
178 }
179
180
181 #define Logical_wr16(op) \
182 { \
183 unsigned ModRM = GetMemInc(c_cs,ip); \
184 WORD *src = GetModRMRegW(ModRM); \
185 WORD *dest = GetModRMRMW(ModRM); \
186 register unsigned tmp1 = (unsigned)ReadWord(src); \
187 register unsigned tmp2 = (unsigned)ReadWord(dest); \
188 register unsigned tmp3 = tmp1 op tmp2; \
189 CF = OF = AF = 0; \
190 SetZFW(tmp3); \
191 SetSFW(tmp3); \
192 SetPF(tmp3); \
193 WriteWord(dest,tmp3); \
194 }
195
196
197 #define Logical_r16w(op) \
198 { \
199 unsigned ModRM = GetMemInc(c_cs,ip); \
200 WORD *dest = GetModRMRegW(ModRM); \
201 WORD *src = GetModRMRMW(ModRM); \
202 register unsigned tmp1 = (unsigned)ReadWord(src); \
203 register unsigned tmp2 = (unsigned)ReadWord(dest); \
204 register unsigned tmp3 = tmp1 op tmp2; \
205 CF = OF = AF = 0; \
206 SetZFW(tmp3); \
207 SetSFW(tmp3); \
208 SetPF(tmp3); \
209 WriteWord(dest,tmp3); \
210 }
211
212
213 #define Logical_ald8(op) \
214 { \
215 register unsigned tmp = *bregs[AL]; \
216 tmp op ## = (unsigned)GetMemInc(c_cs,ip); \
217 CF = OF = AF = 0; \
218 SetZFB(tmp); \
219 SetSFB(tmp); \
220 SetPF(tmp); \
221 *bregs[AL] = (BYTE)tmp; \
222 }
223
224
225 #define Logical_axd16(op) \
226 { \
227 register unsigned src; \
228 register unsigned tmp = ReadWord(&wregs[AX]); \
229 src = GetMemInc(c_cs,ip); \
230 src += GetMemInc(c_cs,ip) << 8; \
231 tmp op ## = src; \
232 CF = OF = AF = 0; \
233 SetZFW(tmp); \
234 SetSFW(tmp); \
235 SetPF(tmp); \
236 WriteWord(&wregs[AX],tmp); \
237 }
238
239
240 #define LogicalOp(name,symbol) \
241 static INLINE2 void i_ ## name ## _br8(void) \
242 { Logical_br8(symbol); } \
243 static INLINE2 void i_ ## name ## _wr16(void) \
244 { Logical_wr16(symbol); } \
245 static INLINE2 void i_ ## name ## _r8b(void) \
246 { Logical_r8b(symbol); } \
247 static INLINE2 void i_ ## name ## _r16w(void) \
248 { Logical_r16w(symbol); } \
249 static INLINE2 void i_ ## name ## _ald8(void) \
250 { Logical_ald8(symbol); } \
251 static INLINE2 void i_ ## name ## _axd16(void) \
252 { Logical_axd16(symbol); }
253
254
255 #define JumpCond(name, cond) \
256 static INLINE2 void i_j ## name ## (void) \
257 { \
258 register int tmp = (int)((INT8)GetMemInc(c_cs,ip)); \
259 if (cond) ip = (WORD)(ip+tmp); \
260 }
261
262
init_cpu(void)263 void init_cpu(void)
264 {
265 unsigned int i,j,c;
266
267 for (i = 0; i < 4; i++)
268 {
269 wregs[i] = 0;
270 sregs[i] = 0x70;
271 }
272 for (; i < 8; i++)
273 wregs[i] = 0;
274
275 wregs[SP] = 0;
276 ip = 0x100;
277
278 for (i = 0;i < 256; i++)
279 {
280 for (j = i, c = 0; j > 0; j >>= 1)
281 if (j & 1) c++;
282
283 parity_table[i] = !(c & 1);
284 }
285
286 CF = PF = AF = ZF = SF = TF = IF = DF = OF = 0;
287
288 bregs[AL] = (BYTE *)&wregs[AX];
289 bregs[AH] = (BYTE *)&wregs[AX]+1;
290 bregs[CL] = (BYTE *)&wregs[CX];
291 bregs[CH] = (BYTE *)&wregs[CX]+1;
292 bregs[DL] = (BYTE *)&wregs[DX];
293 bregs[DH] = (BYTE *)&wregs[DX]+1;
294 bregs[BL] = (BYTE *)&wregs[BX];
295 bregs[BH] = (BYTE *)&wregs[BX]+1;
296
297 bregs[SPL] = (BYTE *)&wregs[SP];
298 bregs[SPH] = (BYTE *)&wregs[SP]+1;
299 bregs[BPL] = (BYTE *)&wregs[BP];
300 bregs[BPH] = (BYTE *)&wregs[BP]+1;
301 bregs[SIL] = (BYTE *)&wregs[SI];
302 bregs[SIH] = (BYTE *)&wregs[SI]+1;
303 bregs[DIL] = (BYTE *)&wregs[DI];
304 bregs[DIH] = (BYTE *)&wregs[DI]+1;
305
306 for (i = 0; i < 256; i++)
307 {
308 ModRMRegB[i] = bregs[(i & 0x38) >> 3];
309 ModRMRegW[i] = &wregs[(i & 0x38) >> 3];
310 }
311
312 for (i = 0; i < 0x40; i++)
313 {
314 switch (i & 7)
315 {
316 case 0:
317 ModRMRM[i].segment = &c_ds;
318 ModRMRM[i].reg1 = &wregs[BX];
319 ModRMRM[i].reg2 = &wregs[SI];
320 ModRMRM[i].offset = ModRMRM[i].offset16 = 0;
321 break;
322 case 1:
323 ModRMRM[i].segment = &c_ds;
324 ModRMRM[i].reg1 = &wregs[BX];
325 ModRMRM[i].reg2 = &wregs[DI];
326 ModRMRM[i].offset = ModRMRM[i].offset16 = 0;
327 break;
328 case 2:
329 ModRMRM[i].segment = &c_ss;
330 ModRMRM[i].reg1 = &wregs[BP];
331 ModRMRM[i].reg2 = &wregs[SI];
332 ModRMRM[i].offset = ModRMRM[i].offset16 = 0;
333 break;
334 case 3:
335 ModRMRM[i].segment = &c_ss;
336 ModRMRM[i].reg1 = &wregs[BP];
337 ModRMRM[i].reg2 = &wregs[DI];
338 ModRMRM[i].offset = ModRMRM[i].offset16 = 0;
339 break;
340 case 4:
341 ModRMRM[i].segment = &c_ds;
342 ModRMRM[i].reg1 = &zero_word;
343 ModRMRM[i].reg2 = &wregs[SI];
344 ModRMRM[i].offset = ModRMRM[i].offset16 = 0;
345 break;
346 case 5:
347 ModRMRM[i].segment = &c_ds;
348 ModRMRM[i].reg1 = &zero_word;
349 ModRMRM[i].reg2 = &wregs[DI];
350 ModRMRM[i].offset = ModRMRM[i].offset16 = 0;
351 break;
352 case 6:
353 ModRMRM[i].segment = &c_ds;
354 ModRMRM[i].reg1 = &zero_word;
355 ModRMRM[i].reg2 = &zero_word;
356 ModRMRM[i].offset = 1;
357 ModRMRM[i].offset16 = 1;
358 break;
359 default:
360 ModRMRM[i].segment = &c_ds;
361 ModRMRM[i].reg1 = &wregs[BX];
362 ModRMRM[i].reg2 = &zero_word;
363 ModRMRM[i].offset = ModRMRM[i].offset16 = 0;
364 break;
365 }
366 }
367
368 for (i = 0x40; i < 0x80; i++)
369 {
370 switch (i & 7)
371 {
372 case 0:
373 ModRMRM[i].segment = &c_ds;
374 ModRMRM[i].reg1 = &wregs[BX];
375 ModRMRM[i].reg2 = &wregs[SI];
376 ModRMRM[i].offset = 1;
377 ModRMRM[i].offset16 = 0;
378 break;
379 case 1:
380 ModRMRM[i].segment = &c_ds;
381 ModRMRM[i].reg1 = &wregs[BX];
382 ModRMRM[i].reg2 = &wregs[DI];
383 ModRMRM[i].offset = 1;
384 ModRMRM[i].offset16 = 0;
385 break;
386 case 2:
387 ModRMRM[i].segment = &c_ss;
388 ModRMRM[i].reg1 = &wregs[BP];
389 ModRMRM[i].reg2 = &wregs[SI];
390 ModRMRM[i].offset = 1;
391 ModRMRM[i].offset16 = 0;
392 break;
393 case 3:
394 ModRMRM[i].segment = &c_ss;
395 ModRMRM[i].reg1 = &wregs[BP];
396 ModRMRM[i].reg2 = &wregs[DI];
397 ModRMRM[i].offset = 1;
398 ModRMRM[i].offset16 = 0;
399 break;
400 case 4:
401 ModRMRM[i].segment = &c_ds;
402 ModRMRM[i].reg1 = &zero_word;
403 ModRMRM[i].reg2 = &wregs[SI];
404 ModRMRM[i].offset = 1;
405 ModRMRM[i].offset16 = 0;
406 break;
407 case 5:
408 ModRMRM[i].segment = &c_ds;
409 ModRMRM[i].reg1 = &zero_word;
410 ModRMRM[i].reg2 = &wregs[DI];
411 ModRMRM[i].offset = 1;
412 ModRMRM[i].offset16 = 0;
413 break;
414 case 6:
415 ModRMRM[i].segment = &c_ss;
416 ModRMRM[i].reg1 = &wregs[BP];
417 ModRMRM[i].reg2 = &zero_word;
418 ModRMRM[i].offset = 1;
419 ModRMRM[i].offset16 = 0;
420 break;
421 default:
422 ModRMRM[i].segment = &c_ds;
423 ModRMRM[i].reg1 = &wregs[BX];
424 ModRMRM[i].reg2 = &zero_word;
425 ModRMRM[i].offset = 1;
426 ModRMRM[i].offset16 = 0;
427 break;
428 }
429 }
430
431 for (i = 0x80; i < 0xc0; i++)
432 {
433 switch (i & 7)
434 {
435 case 0:
436 ModRMRM[i].segment = &c_ds;
437 ModRMRM[i].reg1 = &wregs[BX];
438 ModRMRM[i].reg2 = &wregs[SI];
439 ModRMRM[i].offset = 1;
440 ModRMRM[i].offset16 = 1;
441 break;
442 case 1:
443 ModRMRM[i].segment = &c_ds;
444 ModRMRM[i].reg1 = &wregs[BX];
445 ModRMRM[i].reg2 = &wregs[DI];
446 ModRMRM[i].offset = 1;
447 ModRMRM[i].offset16 = 1;
448 break;
449 case 2:
450 ModRMRM[i].segment = &c_ss;
451 ModRMRM[i].reg1 = &wregs[BP];
452 ModRMRM[i].reg2 = &wregs[SI];
453 ModRMRM[i].offset = 1;
454 ModRMRM[i].offset16 = 1;
455 break;
456 case 3:
457 ModRMRM[i].segment = &c_ss;
458 ModRMRM[i].reg1 = &wregs[BP];
459 ModRMRM[i].reg2 = &wregs[DI];
460 ModRMRM[i].offset = 1;
461 ModRMRM[i].offset16 = 1;
462 break;
463 case 4:
464 ModRMRM[i].segment = &c_ds;
465 ModRMRM[i].reg1 = &zero_word;
466 ModRMRM[i].reg2 = &wregs[SI];
467 ModRMRM[i].offset = 1;
468 ModRMRM[i].offset16 = 1;
469 break;
470 case 5:
471 ModRMRM[i].segment = &c_ds;
472 ModRMRM[i].reg1 = &zero_word;
473 ModRMRM[i].reg2 = &wregs[DI];
474 ModRMRM[i].offset = 1;
475 ModRMRM[i].offset16 = 1;
476 break;
477 case 6:
478 ModRMRM[i].segment = &c_ss;
479 ModRMRM[i].reg1 = &wregs[BP];
480 ModRMRM[i].reg2 = &zero_word;
481 ModRMRM[i].offset = 1;
482 ModRMRM[i].offset16 = 1;
483 break;
484 default:
485 ModRMRM[i].segment = &c_ds;
486 ModRMRM[i].reg1 = &wregs[BX];
487 ModRMRM[i].reg2 = &zero_word;
488 ModRMRM[i].offset = 1;
489 ModRMRM[i].offset16 = 1;
490 break;
491 }
492 }
493
494 for (i = 0xc0; i < 0x100; i++)
495 {
496 ModRMRMWRegs[i] = &wregs[i & 7];
497 ModRMRMBRegs[i] = bregs[i & 7];
498 }
499 }
500
501
502 #ifdef DEBUG2
loc(void)503 void loc(void)
504 {
505 printf("%04X:%04X ", sregs[CS], ip);
506 }
507 #endif
508
interrupt(unsigned int_num)509 static void interrupt(unsigned int_num)
510 {
511 unsigned dest_seg, dest_off,tmp1;
512
513 i_pushf();
514 dest_off = GetMemW(memory,int_num*4);
515 dest_seg = GetMemW(memory,int_num*4+2);
516
517 tmp1 = (WORD)(ReadWord(&wregs[SP])-2);
518
519 PutMemW(c_stack,tmp1,sregs[CS]);
520 tmp1 = (WORD)(tmp1-2);
521 PutMemW(c_stack,tmp1,ip);
522 WriteWord(&wregs[SP],tmp1);
523
524 ip = (WORD)dest_off;
525 sregs[CS] = (WORD)dest_seg;
526 c_cs = SegToMemPtr(CS);
527
528 TF = IF = 0; /* Turn of trap and interrupts... */
529
530 }
531
532
external_int(void)533 static void external_int(void)
534 {
535 disable();
536
537 #ifdef DEBUGGER
538 call_debugger(D_INT);
539 #endif
540 D2(printf("Interrupt 0x%02X\n", int_pending););
541 interrupt(int_pending);
542 int_pending = 0;
543
544 enable();
545 }
546
547
548 #define GetModRMRegW(ModRM) (ModRMRegW[ModRM])
549 #define GetModRMRegB(ModRM) (ModRMRegB[ModRM])
550
GetModRMRMW(unsigned ModRM)551 static INLINE WORD *GetModRMRMW(unsigned ModRM)
552 {
553 register unsigned dest;
554
555 if (ModRM >= 0xc0)
556 return ModRMRMWRegs[ModRM];
557
558 dest = 0;
559
560 if (ModRMRM[ModRM].offset)
561 {
562 dest = (WORD)((INT16)((INT8)GetMemInc(c_cs,ip)));
563 if (ModRMRM[ModRM].offset16)
564 dest = (GetMemInc(c_cs,ip) << 8) + (BYTE)dest;
565 }
566
567 return (WORD *)(*ModRMRM[ModRM].segment +
568 (WORD)(ReadWord(ModRMRM[ModRM].reg1) +
569 ReadWord(ModRMRM[ModRM].reg2) + dest));
570 }
571
572
GetModRMRMB(unsigned ModRM)573 static INLINE BYTE *GetModRMRMB(unsigned ModRM)
574 {
575 register unsigned dest;
576
577 if (ModRM >= 0xc0)
578 return ModRMRMBRegs[ModRM];
579
580 dest = 0;
581
582 if (ModRMRM[ModRM].offset)
583 {
584 dest = (WORD)((INT16)((INT8)GetMemInc(c_cs,ip)));
585 if (ModRMRM[ModRM].offset16)
586 dest = (GetMemInc(c_cs,ip) << 8) + (BYTE)dest;
587 }
588
589 return (*ModRMRM[ModRM].segment +
590 (WORD)(ReadWord(ModRMRM[ModRM].reg1) +
591 ReadWord(ModRMRM[ModRM].reg2) + dest));
592 }
593
594
i_add_br8(void)595 static INLINE2 void i_add_br8(void)
596 {
597 /* Opcode 0x00 */
598
599 unsigned ModRM = (unsigned)GetMemInc(c_cs,ip);
600 register unsigned src = (unsigned)*GetModRMRegB(ModRM);
601 BYTE *dest = GetModRMRMB(ModRM);
602 register unsigned tmp = (unsigned) *dest;
603 register unsigned tmp2 = tmp;
604
605 tmp += src;
606
607 SetCFB_Add(tmp,tmp2);
608 SetOFB_Add(tmp,src,tmp2);
609 SetAF(tmp,src,tmp2);
610 SetZFB(tmp);
611 SetSFB(tmp);
612 SetPF(tmp);
613
614 *dest = (BYTE)tmp;
615 }
616
617
i_add_wr16(void)618 static INLINE2 void i_add_wr16(void)
619 {
620 /* Opcode 0x01 */
621
622 unsigned ModRM = GetMemInc(c_cs,ip);
623 WORD *src = GetModRMRegW(ModRM);
624 WORD *dest = GetModRMRMW(ModRM);
625 register unsigned tmp1 = (unsigned)ReadWord(dest);
626 register unsigned tmp2 = (unsigned)ReadWord(src);
627 register unsigned tmp3;
628
629 tmp3 = tmp1+tmp2;
630
631 SetCFW_Add(tmp3,tmp1);
632 SetOFW_Add(tmp3,tmp2,tmp1);
633 SetAF(tmp3,tmp2,tmp1);
634 SetZFW(tmp3);
635 SetSFW(tmp3);
636 SetPF(tmp3);
637
638 WriteWord(dest, tmp3);
639 }
640
641
i_add_r8b(void)642 static INLINE2 void i_add_r8b(void)
643 {
644 /* Opcode 0x02 */
645
646 unsigned ModRM = (unsigned)GetMemInc(c_cs,ip);
647 register unsigned src = (unsigned)*GetModRMRMB(ModRM);
648 BYTE *dest = GetModRMRegB(ModRM);
649 register unsigned tmp = (unsigned) *dest;
650 register unsigned tmp2 = tmp;
651
652 tmp += src;
653
654 SetCFB_Add(tmp,tmp2);
655 SetOFB_Add(tmp,src,tmp2);
656 SetAF(tmp,src,tmp2);
657 SetZFB(tmp);
658 SetSFB(tmp);
659 SetPF(tmp);
660
661 *dest = (BYTE)tmp;
662
663 }
664
665
i_add_r16w(void)666 static INLINE2 void i_add_r16w(void)
667 {
668 /* Opcode 0x03 */
669
670 unsigned ModRM = GetMemInc(c_cs,ip);
671 WORD *dest = GetModRMRegW(ModRM);
672 WORD *src = GetModRMRMW(ModRM);
673 register unsigned tmp1 = (unsigned)ReadWord(dest);
674 register unsigned tmp2 = (unsigned)ReadWord(src);
675 register unsigned tmp3;
676
677 tmp3 = tmp1 + tmp2;
678
679 SetCFW_Add(tmp3,tmp1);
680 SetOFW_Add(tmp3,tmp2,tmp1);
681 SetAF(tmp3,tmp2,tmp1);
682 SetZFW(tmp3);
683 SetSFW(tmp3);
684 SetPF(tmp3);
685
686 WriteWord(dest, tmp3);
687 }
688
689
i_add_ald8(void)690 static INLINE2 void i_add_ald8(void)
691 {
692 /* Opcode 0x04 */
693
694 register unsigned src = (unsigned)GetMemInc(c_cs,ip);
695 register unsigned tmp = (unsigned)*bregs[AL];
696 register unsigned tmp2 = tmp;
697
698 tmp2 += src;
699
700 SetCFB_Add(tmp2,tmp);
701 SetOFB_Add(tmp2,src,tmp);
702 SetAF(tmp2,src,tmp);
703 SetZFB(tmp2);
704 SetSFB(tmp2);
705 SetPF(tmp2);
706
707 *bregs[AL] = (BYTE)tmp2;
708 }
709
710
i_add_axd16(void)711 static INLINE2 void i_add_axd16(void)
712 {
713 /* Opcode 0x05 */
714
715 register unsigned src;
716 register unsigned tmp = ReadWord(&wregs[AX]);
717 register unsigned tmp2 = tmp;
718
719 src = GetMemInc(c_cs,ip);
720 src += GetMemInc(c_cs,ip) << 8;
721
722 tmp2 += src;
723
724 SetCFW_Add(tmp2,tmp);
725 SetOFW_Add(tmp2,tmp,src);
726 SetAF(tmp2,tmp,src);
727 SetZFW(tmp2);
728 SetSFW(tmp2);
729 SetPF(tmp2);
730
731 WriteWord(&wregs[AX],tmp2);
732 }
733
734
i_push_es(void)735 static INLINE2 void i_push_es(void)
736 {
737 /* Opcode 0x06 */
738
739 PushSeg(ES);
740 }
741
742
i_pop_es(void)743 static INLINE2 void i_pop_es(void)
744 {
745 /* Opcode 0x07 */
746 PopSeg(c_es,ES);
747 }
748
749 /* most OR instructions go here... */
750
751 LogicalOp(or,|)
752
753
i_push_cs(void)754 static INLINE2 void i_push_cs(void)
755 {
756 /* Opcode 0x0e */
757
758 PushSeg(CS);
759 }
760
761
i_adc_br8(void)762 static INLINE2 void i_adc_br8(void)
763 {
764 /* Opcode 0x10 */
765
766 unsigned ModRM = (unsigned)GetMemInc(c_cs,ip);
767 register unsigned src = (unsigned)*GetModRMRegB(ModRM)+CF;
768 BYTE *dest = GetModRMRMB(ModRM);
769 register unsigned tmp = (unsigned) *dest;
770 register unsigned tmp2 = tmp;
771
772 tmp += src;
773
774 CF = tmp >> 8;
775
776 /* SetCFB_Add(tmp,tmp2); */
777 SetOFB_Add(tmp,src,tmp2);
778 SetAF(tmp,src,tmp2);
779 SetZFB(tmp);
780 SetSFB(tmp);
781 SetPF(tmp);
782
783 *dest = (BYTE)tmp;
784 }
785
786
i_adc_wr16(void)787 static INLINE2 void i_adc_wr16(void)
788 {
789 /* Opcode 0x11 */
790
791 unsigned ModRM = GetMemInc(c_cs,ip);
792 WORD *src = GetModRMRegW(ModRM);
793 WORD *dest = GetModRMRMW(ModRM);
794 register unsigned tmp1 = (unsigned)ReadWord(dest);
795 register unsigned tmp2 = (unsigned)ReadWord(src)+CF;
796 register unsigned tmp3;
797
798 tmp3 = tmp1+tmp2;
799
800 CF = tmp3 >> 16;
801 /* SetCFW_Add(tmp3,tmp1); */
802 SetOFW_Add(tmp3,tmp2,tmp1);
803 SetAF(tmp3,tmp2,tmp1);
804 SetZFW(tmp3);
805 SetSFW(tmp3);
806 SetPF(tmp3);
807
808 WriteWord(dest, tmp3);
809
810 }
811
812
i_adc_r8b(void)813 static INLINE2 void i_adc_r8b(void)
814 {
815 /* Opcode 0x12 */
816
817 unsigned ModRM = (unsigned)GetMemInc(c_cs,ip);
818 register unsigned src = (unsigned)*GetModRMRMB(ModRM)+CF;
819 BYTE *dest = GetModRMRegB(ModRM);
820 register unsigned tmp = (unsigned) *dest;
821 register unsigned tmp2 = tmp;
822
823 tmp += src;
824
825 CF = tmp >> 8;
826
827 /* SetCFB_Add(tmp,tmp2); */
828 SetOFB_Add(tmp,src,tmp2);
829 SetAF(tmp,src,tmp2);
830 SetZFB(tmp);
831 SetSFB(tmp);
832 SetPF(tmp);
833
834 *dest = (BYTE)tmp;
835 }
836
837
i_adc_r16w(void)838 static INLINE2 void i_adc_r16w(void)
839 {
840 /* Opcode 0x13 */
841
842 unsigned ModRM = GetMemInc(c_cs,ip);
843 WORD *dest = GetModRMRegW(ModRM);
844 WORD *src = GetModRMRMW(ModRM);
845 register unsigned tmp1 = (unsigned)ReadWord(dest);
846 register unsigned tmp2 = (unsigned)ReadWord(src)+CF;
847 register unsigned tmp3;
848
849 tmp3 = tmp1+tmp2;
850
851 CF = tmp3 >> 16;
852
853 /* SetCFW_Add(tmp3,tmp1); */
854 SetOFW_Add(tmp3,tmp2,tmp1);
855 SetAF(tmp3,tmp2,tmp1);
856 SetZFW(tmp3);
857 SetSFW(tmp3);
858 SetPF(tmp3);
859
860 WriteWord(dest, tmp3);
861
862 }
863
864
i_adc_ald8(void)865 static INLINE2 void i_adc_ald8(void)
866 {
867 /* Opcode 0x14 */
868
869 register unsigned src = (unsigned)GetMemInc(c_cs,ip)+CF;
870 register unsigned tmp = (unsigned)*bregs[AL];
871 register unsigned tmp2 = tmp;
872
873 tmp2 += src;
874
875 CF = tmp2 >> 8;
876
877 /* SetCFB_Add(tmp2,tmp); */
878 SetOFB_Add(tmp2,src,tmp);
879 SetAF(tmp2,src,tmp);
880 SetZFB(tmp2);
881 SetSFB(tmp2);
882 SetPF(tmp2);
883
884 *bregs[AL] = (BYTE)tmp2;
885 }
886
887
i_adc_axd16(void)888 static INLINE2 void i_adc_axd16(void)
889 {
890 /* Opcode 0x15 */
891
892 register unsigned src;
893 register unsigned tmp = ReadWord(&wregs[AX]);
894 register unsigned tmp2 = tmp;
895
896 src = GetMemInc(c_cs,ip);
897 src += (GetMemInc(c_cs,ip) << 8)+CF;
898
899 tmp2 += src;
900
901 CF = tmp2 >> 16;
902
903 /* SetCFW_Add(tmp2,tmp); */
904 SetOFW_Add(tmp2,tmp,src);
905 SetAF(tmp2,tmp,src);
906 SetZFW(tmp2);
907 SetSFW(tmp2);
908 SetPF(tmp2);
909
910 WriteWord(&wregs[AX],tmp2);
911 }
912
913
i_push_ss(void)914 static INLINE2 void i_push_ss(void)
915 {
916 /* Opcode 0x16 */
917
918 PushSeg(SS);
919 }
920
921
i_pop_ss(void)922 static INLINE2 void i_pop_ss(void)
923 {
924 /* Opcode 0x17 */
925
926 static int multiple = 0;
927
928 PopSeg(c_ss,SS);
929 c_stack = c_ss;
930
931 if (multiple == 0) /* prevent unlimited recursion */
932 {
933 multiple = 1;
934 /*
935 #ifdef DEBUGGER
936 call_debugger(D_TRACE);
937 #endif
938 */
939 instruction[GetMemInc(c_cs,ip)]();
940 multiple = 0;
941 }
942 }
943
944
i_sbb_br8(void)945 static INLINE2 void i_sbb_br8(void)
946 {
947 /* Opcode 0x18 */
948
949 unsigned ModRM = (unsigned)GetMemInc(c_cs,ip);
950 register unsigned src = (unsigned)*GetModRMRegB(ModRM)+CF;
951 BYTE *dest = GetModRMRMB(ModRM);
952 register unsigned tmp = (unsigned) *dest;
953 register unsigned tmp2 = tmp;
954
955 tmp -= src;
956
957 CF = (tmp & 0x100) == 0x100;
958
959 /* SetCFB_Sub(tmp,tmp2); */
960 SetOFB_Sub(tmp,src,tmp2);
961 SetAF(tmp,src,tmp2);
962 SetZFB(tmp);
963 SetSFB(tmp);
964 SetPF(tmp);
965
966 *dest = (BYTE)tmp;
967 }
968
969
i_sbb_wr16(void)970 static INLINE2 void i_sbb_wr16(void)
971 {
972 /* Opcode 0x19 */
973
974 unsigned ModRM = GetMemInc(c_cs,ip);
975 WORD *src = GetModRMRegW(ModRM);
976 WORD *dest = GetModRMRMW(ModRM);
977 register unsigned tmp1 = ReadWord(dest);
978 register unsigned tmp2 = ReadWord(src)+CF;
979 register unsigned tmp3;
980
981 tmp3 = tmp1-tmp2;
982
983 CF = (tmp3 & 0x10000) == 0x10000;
984
985 /* SetCFW_Sub(tmp2,tmp1); */
986 SetOFW_Sub(tmp3,tmp2,tmp1);
987 SetAF(tmp3,tmp2,tmp1);
988 SetZFW(tmp3);
989 SetSFW(tmp3);
990 SetPF(tmp3);
991
992 WriteWord(dest, tmp3);
993 }
994
995
i_sbb_r8b(void)996 static INLINE2 void i_sbb_r8b(void)
997 {
998 /* Opcode 0x1a */
999
1000 unsigned ModRM = (unsigned)GetMemInc(c_cs,ip);
1001 register unsigned src = (unsigned)*GetModRMRMB(ModRM)+CF;
1002 BYTE *dest = GetModRMRegB(ModRM);
1003 register unsigned tmp = (unsigned) *dest;
1004 register unsigned tmp2 = tmp;
1005
1006 tmp -= src;
1007
1008 CF = (tmp & 0x100) == 0x100;
1009
1010 /* SetCFB_Sub(tmp,tmp2); */
1011 SetOFB_Sub(tmp,src,tmp2);
1012 SetAF(tmp,src,tmp2);
1013 SetZFB(tmp);
1014 SetSFB(tmp);
1015 SetPF(tmp);
1016
1017 *dest = (BYTE)tmp;
1018
1019 }
1020
1021
i_sbb_r16w(void)1022 static INLINE2 void i_sbb_r16w(void)
1023 {
1024 /* Opcode 0x1b */
1025
1026 unsigned ModRM = GetMemInc(c_cs,ip);
1027 WORD *dest = GetModRMRegW(ModRM);
1028 WORD *src = GetModRMRMW(ModRM);
1029 register unsigned tmp1 = ReadWord(dest);
1030 register unsigned tmp2 = ReadWord(src)+CF;
1031 register unsigned tmp3;
1032
1033 tmp3 = tmp1-tmp2;
1034
1035 CF = (tmp3 & 0x10000) == 0x10000;
1036
1037 /* SetCFW_Sub(tmp2,tmp1); */
1038 SetOFW_Sub(tmp3,tmp2,tmp1);
1039 SetAF(tmp3,tmp2,tmp1);
1040 SetZFW(tmp3);
1041 SetSFW(tmp3);
1042 SetPF(tmp3);
1043
1044 WriteWord(dest, tmp3);
1045 }
1046
1047
i_sbb_ald8(void)1048 static INLINE2 void i_sbb_ald8(void)
1049 {
1050 /* Opcode 0x1c */
1051
1052 register unsigned src = GetMemInc(c_cs,ip)+CF;
1053 register unsigned tmp = *bregs[AL];
1054 register unsigned tmp1 = tmp;
1055
1056 tmp1 -= src;
1057
1058 CF = (tmp1 & 0x100) == 0x100;
1059
1060 /* SetCFB_Sub(src,tmp); */
1061 SetOFB_Sub(tmp1,src,tmp);
1062 SetAF(tmp1,src,tmp);
1063 SetZFB(tmp1);
1064 SetSFB(tmp1);
1065 SetPF(tmp1);
1066
1067 *bregs[AL] = (BYTE)tmp1;
1068 }
1069
1070
i_sbb_axd16(void)1071 static INLINE2 void i_sbb_axd16(void)
1072 {
1073 /* Opcode 0x1d */
1074
1075 register unsigned src;
1076 register unsigned tmp = ReadWord(&wregs[AX]);
1077 register unsigned tmp2 = tmp;
1078
1079 src = GetMemInc(c_cs,ip);
1080 src += (GetMemInc(c_cs,ip) << 8)+CF;
1081
1082 tmp2 -= src;
1083
1084 CF = (tmp2 & 0x10000) == 0x10000;
1085
1086 /* SetCFW_Sub(src,tmp); */
1087 SetOFW_Sub(tmp2,src,tmp);
1088 SetAF(tmp2,tmp,src);
1089 SetZFW(tmp2);
1090 SetSFW(tmp2);
1091 SetPF(tmp2);
1092
1093 WriteWord(&wregs[AX],tmp2);
1094 }
1095
1096
i_push_ds(void)1097 static INLINE2 void i_push_ds(void)
1098 {
1099 /* Opcode 0x1e */
1100
1101 PushSeg(DS);
1102 }
1103
1104
i_pop_ds(void)1105 static INLINE2 void i_pop_ds(void)
1106 {
1107 /* Opcode 0x1f */
1108 PopSeg(c_ds,DS);
1109 }
1110
1111 /* most AND instructions go here... */
1112
1113 LogicalOp(and,&)
1114
1115
i_es(void)1116 static INLINE2 void i_es(void)
1117 {
1118 /* Opcode 0x26 */
1119
1120 c_ds = c_ss = c_es;
1121
1122 instruction[GetMemInc(c_cs,ip)]();
1123
1124 c_ds = SegToMemPtr(DS);
1125 c_ss = SegToMemPtr(SS);
1126 }
1127
i_daa(void)1128 static INLINE2 void i_daa(void)
1129 {
1130 if (AF || ((*bregs[AL] & 0xf) > 9))
1131 {
1132 *bregs[AL] += 6;
1133 AF = 1;
1134 }
1135 else
1136 AF = 0;
1137
1138 if (CF || (*bregs[AL] > 0x9f))
1139 {
1140 *bregs[AL] += 0x60;
1141 CF = 1;
1142 }
1143 else
1144 CF = 0;
1145
1146 SetPF(*bregs[AL]);
1147 SetSFB(*bregs[AL]);
1148 SetZFB(*bregs[AL]);
1149 }
1150
i_sub_br8(void)1151 static INLINE2 void i_sub_br8(void)
1152 {
1153 /* Opcode 0x28 */
1154
1155 unsigned ModRM = (unsigned)GetMemInc(c_cs,ip);
1156 register unsigned src = (unsigned)*GetModRMRegB(ModRM);
1157 BYTE *dest = GetModRMRMB(ModRM);
1158 register unsigned tmp = (unsigned) *dest;
1159 register unsigned tmp2 = tmp;
1160
1161 tmp -= src;
1162
1163 SetCFB_Sub(tmp,tmp2);
1164 SetOFB_Sub(tmp,src,tmp2);
1165 SetAF(tmp,src,tmp2);
1166 SetZFB(tmp);
1167 SetSFB(tmp);
1168 SetPF(tmp);
1169
1170 *dest = (BYTE)tmp;
1171
1172 }
1173
1174
i_sub_wr16(void)1175 static INLINE2 void i_sub_wr16(void)
1176 {
1177 /* Opcode 0x29 */
1178
1179 unsigned ModRM = GetMemInc(c_cs,ip);
1180 WORD *src = GetModRMRegW(ModRM);
1181 WORD *dest = GetModRMRMW(ModRM);
1182 register unsigned tmp1 = ReadWord(dest);
1183 register unsigned tmp2 = ReadWord(src);
1184 register unsigned tmp3;
1185
1186 tmp3 = tmp1-tmp2;
1187
1188 SetCFW_Sub(tmp2,tmp1);
1189 SetOFW_Sub(tmp3,tmp2,tmp1);
1190 SetAF(tmp3,tmp2,tmp1);
1191 SetZFW(tmp3);
1192 SetSFW(tmp3);
1193 SetPF(tmp3);
1194
1195 WriteWord(dest, tmp3);
1196 }
1197
1198
i_sub_r8b(void)1199 static INLINE2 void i_sub_r8b(void)
1200 {
1201 /* Opcode 0x2a */
1202
1203 unsigned ModRM = (unsigned)GetMemInc(c_cs,ip);
1204 BYTE *dest = GetModRMRegB(ModRM);
1205 register unsigned src = *GetModRMRMB(ModRM);
1206 register unsigned tmp = *dest;
1207 register unsigned tmp2 = tmp;
1208
1209 tmp -= src;
1210
1211 SetCFB_Sub(tmp,tmp2);
1212 SetOFB_Sub(tmp,src,tmp2);
1213 SetAF(tmp,src,tmp2);
1214 SetZFB(tmp);
1215 SetSFB(tmp);
1216 SetPF(tmp);
1217
1218 *dest = (BYTE)tmp;
1219 }
1220
1221
i_sub_r16w(void)1222 static INLINE2 void i_sub_r16w(void)
1223 {
1224 /* Opcode 0x2b */
1225
1226 unsigned ModRM = GetMemInc(c_cs,ip);
1227 WORD *dest = GetModRMRegW(ModRM);
1228 WORD *src = GetModRMRMW(ModRM);
1229 register unsigned tmp1 = ReadWord(dest);
1230 register unsigned tmp2 = ReadWord(src);
1231 register unsigned tmp3;
1232
1233 tmp3 = tmp1-tmp2;
1234
1235 SetCFW_Sub(tmp2,tmp1);
1236 SetOFW_Sub(tmp3,tmp2,tmp1);
1237 SetAF(tmp3,tmp2,tmp1);
1238 SetZFW(tmp3);
1239 SetSFW(tmp3);
1240 SetPF(tmp3);
1241
1242 WriteWord(dest, tmp3);
1243 }
1244
1245
i_sub_ald8(void)1246 static INLINE2 void i_sub_ald8(void)
1247 {
1248 /* Opcode 0x2c */
1249
1250 register unsigned src = GetMemInc(c_cs,ip);
1251 register unsigned tmp = *bregs[AL];
1252 register unsigned tmp1 = tmp;
1253
1254 tmp1 -= src;
1255
1256 SetCFB_Sub(src,tmp);
1257 SetOFB_Sub(tmp1,src,tmp);
1258 SetAF(tmp1,src,tmp);
1259 SetZFB(tmp1);
1260 SetSFB(tmp1);
1261 SetPF(tmp1);
1262
1263 *bregs[AL] = (unsigned) tmp1;
1264 }
1265
1266
i_sub_axd16(void)1267 static INLINE2 void i_sub_axd16(void)
1268 {
1269 /* Opcode 0x2d */
1270
1271 register unsigned src;
1272 register unsigned tmp = ReadWord(&wregs[AX]);
1273 register unsigned tmp2 = tmp;
1274
1275 src = GetMemInc(c_cs,ip);
1276 src += (GetMemInc(c_cs,ip) << 8);
1277
1278 tmp2 -= src;
1279
1280 SetCFW_Sub(src,tmp);
1281 SetOFW_Sub(tmp2,src,tmp);
1282 SetAF(tmp2,tmp,src);
1283 SetZFW(tmp2);
1284 SetSFW(tmp2);
1285 SetPF(tmp2);
1286
1287 WriteWord(&wregs[AX],tmp2);
1288 }
1289
1290
i_cs(void)1291 static INLINE2 void i_cs(void)
1292 {
1293 /* Opcode 0x2e */
1294
1295 c_ds = c_ss = c_cs;
1296
1297 instruction[GetMemInc(c_cs,ip)]();
1298
1299 c_ds = SegToMemPtr(DS);
1300 c_ss = SegToMemPtr(SS);
1301 }
1302
1303
1304 /* most XOR instructions go here */
1305
1306 LogicalOp(xor,^)
1307
1308
i_ss(void)1309 static INLINE2 void i_ss(void)
1310 {
1311 /* Opcode 0x36 */
1312
1313 c_ds = c_ss;
1314
1315 instruction[GetMemInc(c_cs,ip)]();
1316
1317 c_ds = SegToMemPtr(DS);
1318 }
1319
1320
i_cmp_br8(void)1321 static INLINE2 void i_cmp_br8(void)
1322 {
1323 /* Opcode 0x38 */
1324
1325 unsigned ModRM = (unsigned)GetMemInc(c_cs,ip);
1326 register unsigned src = (unsigned)*GetModRMRegB(ModRM);
1327 register unsigned tmp = *GetModRMRMB(ModRM);
1328 register unsigned tmp2 = tmp;
1329
1330 tmp -= src;
1331
1332 SetCFB_Sub(tmp,tmp2);
1333 SetOFB_Sub(tmp,src,tmp2);
1334 SetAF(tmp,src,tmp2);
1335 SetZFB(tmp);
1336 SetSFB(tmp);
1337 SetPF(tmp);
1338 }
1339
1340
i_cmp_wr16(void)1341 static INLINE2 void i_cmp_wr16(void)
1342 {
1343 /* Opcode 0x39 */
1344
1345 unsigned ModRM = GetMemInc(c_cs,ip);
1346 WORD *src = GetModRMRegW(ModRM);
1347 WORD *dest = GetModRMRMW(ModRM);
1348 register unsigned tmp1 = ReadWord(dest);
1349 register unsigned tmp2 = ReadWord(src);
1350 register unsigned tmp3;
1351
1352 tmp3 = tmp1-tmp2;
1353
1354 SetCFW_Sub(tmp2,tmp1);
1355 SetOFW_Sub(tmp3,tmp2,tmp1);
1356 SetAF(tmp3,tmp2,tmp1);
1357 SetZFW(tmp3);
1358 SetSFW(tmp3);
1359 SetPF(tmp3);
1360 }
1361
1362
i_cmp_r8b(void)1363 static INLINE2 void i_cmp_r8b(void)
1364 {
1365 /* Opcode 0x3a */
1366
1367 unsigned ModRM = (unsigned)GetMemInc(c_cs,ip);
1368 register unsigned tmp = (unsigned)*GetModRMRegB(ModRM);
1369 register unsigned src = *GetModRMRMB(ModRM);
1370 register unsigned tmp2 = tmp;
1371
1372 tmp -= src;
1373
1374 SetCFB_Sub(tmp,tmp2);
1375 SetOFB_Sub(tmp,src,tmp2);
1376 SetAF(tmp,src,tmp2);
1377 SetZFB(tmp);
1378 SetSFB(tmp);
1379 SetPF(tmp);
1380 }
1381
i_cmp_r16w(void)1382 static INLINE2 void i_cmp_r16w(void)
1383 {
1384 /* Opcode 0x3b */
1385
1386 unsigned ModRM = GetMemInc(c_cs,ip);
1387 WORD *dest = GetModRMRegW(ModRM);
1388 WORD *src = GetModRMRMW(ModRM);
1389 register unsigned tmp1 = ReadWord(dest);
1390 register unsigned tmp2 = ReadWord(src);
1391 register unsigned tmp3;
1392
1393 tmp3 = tmp1-tmp2;
1394
1395 SetCFW_Sub(tmp2,tmp1);
1396 SetOFW_Sub(tmp3,tmp2,tmp1);
1397 SetAF(tmp3,tmp2,tmp1);
1398 SetZFW(tmp3);
1399 SetSFW(tmp3);
1400 SetPF(tmp3);
1401 }
1402
1403
i_cmp_ald8(void)1404 static INLINE2 void i_cmp_ald8(void)
1405 {
1406 /* Opcode 0x3c */
1407
1408 register unsigned src = GetMemInc(c_cs,ip);
1409 register unsigned tmp = *bregs[AL];
1410 register unsigned tmp1 = tmp;
1411
1412 tmp1 -= src;
1413
1414 SetCFB_Sub(src,tmp);
1415 SetOFB_Sub(tmp1,src,tmp);
1416 SetAF(tmp1,src,tmp);
1417 SetZFB(tmp1);
1418 SetSFB(tmp1);
1419 SetPF(tmp1);
1420 }
1421
1422
i_cmp_axd16(void)1423 static INLINE2 void i_cmp_axd16(void)
1424 {
1425 /* Opcode 0x3d */
1426
1427 register unsigned src;
1428 register unsigned tmp = ReadWord(&wregs[AX]);
1429 register unsigned tmp2 = tmp;
1430
1431 src = GetMemInc(c_cs,ip);
1432 src += (GetMemInc(c_cs,ip) << 8);
1433
1434 tmp2 -= src;
1435
1436 SetCFW_Sub(src,tmp);
1437 SetOFW_Sub(tmp2,src,tmp);
1438 SetAF(tmp2,tmp,src);
1439 SetZFW(tmp2);
1440 SetSFW(tmp2);
1441 SetPF(tmp2);
1442 }
1443
1444
i_ds(void)1445 static INLINE2 void i_ds(void)
1446 {
1447 /* Opcode 0x3e */
1448
1449 c_ss = c_ds;
1450
1451 instruction[GetMemInc(c_cs,ip)]();
1452
1453 c_ss = SegToMemPtr(SS);
1454 }
1455
1456
i_inc_ax(void)1457 static INLINE2 void i_inc_ax(void)
1458 {
1459 /* Opcode 0x40 */
1460 IncWordReg(AX);
1461 }
1462
1463
i_inc_cx(void)1464 static INLINE2 void i_inc_cx(void)
1465 {
1466 /* Opcode 0x41 */
1467 IncWordReg(CX);
1468 }
1469
1470
i_inc_dx(void)1471 static INLINE2 void i_inc_dx(void)
1472 {
1473 /* Opcode 0x42 */
1474 IncWordReg(DX);
1475 }
1476
1477
i_inc_bx(void)1478 static INLINE2 void i_inc_bx(void)
1479 {
1480 /* Opcode 0x43 */
1481 IncWordReg(BX);
1482 }
1483
1484
i_inc_sp(void)1485 static INLINE2 void i_inc_sp(void)
1486 {
1487 /* Opcode 0x44 */
1488 IncWordReg(SP);
1489 }
1490
1491
i_inc_bp(void)1492 static INLINE2 void i_inc_bp(void)
1493 {
1494 /* Opcode 0x45 */
1495 IncWordReg(BP);
1496 }
1497
1498
i_inc_si(void)1499 static INLINE2 void i_inc_si(void)
1500 {
1501 /* Opcode 0x46 */
1502 IncWordReg(SI);
1503 }
1504
1505
i_inc_di(void)1506 static INLINE2 void i_inc_di(void)
1507 {
1508 /* Opcode 0x47 */
1509 IncWordReg(DI);
1510 }
1511
1512
i_dec_ax(void)1513 static INLINE2 void i_dec_ax(void)
1514 {
1515 /* Opcode 0x48 */
1516 DecWordReg(AX);
1517 }
1518
1519
i_dec_cx(void)1520 static INLINE2 void i_dec_cx(void)
1521 {
1522 /* Opcode 0x49 */
1523 DecWordReg(CX);
1524 }
1525
1526
i_dec_dx(void)1527 static INLINE2 void i_dec_dx(void)
1528 {
1529 /* Opcode 0x4a */
1530 DecWordReg(DX);
1531 }
1532
1533
i_dec_bx(void)1534 static INLINE2 void i_dec_bx(void)
1535 {
1536 /* Opcode 0x4b */
1537 DecWordReg(BX);
1538 }
1539
1540
i_dec_sp(void)1541 static INLINE2 void i_dec_sp(void)
1542 {
1543 /* Opcode 0x4c */
1544 DecWordReg(SP);
1545 }
1546
1547
i_dec_bp(void)1548 static INLINE2 void i_dec_bp(void)
1549 {
1550 /* Opcode 0x4d */
1551 DecWordReg(BP);
1552 }
1553
1554
i_dec_si(void)1555 static INLINE2 void i_dec_si(void)
1556 {
1557 /* Opcode 0x4e */
1558 DecWordReg(SI);
1559 }
1560
1561
i_dec_di(void)1562 static INLINE2 void i_dec_di(void)
1563 {
1564 /* Opcode 0x4f */
1565 DecWordReg(DI);
1566 }
1567
1568
i_push_ax(void)1569 static INLINE2 void i_push_ax(void)
1570 {
1571 /* Opcode 0x50 */
1572 PushWordReg(AX);
1573 }
1574
1575
i_push_cx(void)1576 static INLINE2 void i_push_cx(void)
1577 {
1578 /* Opcode 0x51 */
1579 PushWordReg(CX);
1580 }
1581
1582
i_push_dx(void)1583 static INLINE2 void i_push_dx(void)
1584 {
1585 /* Opcode 0x52 */
1586 PushWordReg(DX);
1587 }
1588
1589
i_push_bx(void)1590 static INLINE2 void i_push_bx(void)
1591 {
1592 /* Opcode 0x53 */
1593 PushWordReg(BX);
1594 }
1595
1596
i_push_sp(void)1597 static INLINE2 void i_push_sp(void)
1598 {
1599 /* Opcode 0x54 */
1600 PushWordReg(SP);
1601 }
1602
1603
i_push_bp(void)1604 static INLINE2 void i_push_bp(void)
1605 {
1606 /* Opcode 0x55 */
1607 PushWordReg(BP);
1608 }
1609
1610
1611
i_push_si(void)1612 static INLINE2 void i_push_si(void)
1613 {
1614 /* Opcode 0x56 */
1615 PushWordReg(SI);
1616 }
1617
1618
i_push_di(void)1619 static INLINE2 void i_push_di(void)
1620 {
1621 /* Opcode 0x57 */
1622 PushWordReg(DI);
1623 }
1624
1625
i_pop_ax(void)1626 static INLINE2 void i_pop_ax(void)
1627 {
1628 /* Opcode 0x58 */
1629 PopWordReg(AX);
1630 }
1631
1632
i_pop_cx(void)1633 static INLINE2 void i_pop_cx(void)
1634 {
1635 /* Opcode 0x59 */
1636 PopWordReg(CX);
1637 }
1638
1639
i_pop_dx(void)1640 static INLINE2 void i_pop_dx(void)
1641 {
1642 /* Opcode 0x5a */
1643 PopWordReg(DX);
1644 }
1645
1646
i_pop_bx(void)1647 static INLINE2 void i_pop_bx(void)
1648 {
1649 /* Opcode 0x5b */
1650 PopWordReg(BX);
1651 }
1652
1653
i_pop_sp(void)1654 static INLINE2 void i_pop_sp(void)
1655 {
1656 /* Opcode 0x5c */
1657 PopWordReg(SP);
1658 }
1659
1660
i_pop_bp(void)1661 static INLINE2 void i_pop_bp(void)
1662 {
1663 /* Opcode 0x5d */
1664 PopWordReg(BP);
1665 }
1666
1667
i_pop_si(void)1668 static INLINE2 void i_pop_si(void)
1669 {
1670 /* Opcode 0x5e */
1671 PopWordReg(SI);
1672 }
1673
1674
i_pop_di(void)1675 static INLINE2 void i_pop_di(void)
1676 {
1677 /* Opcode 0x5f */
1678 PopWordReg(DI);
1679 }
1680
1681 /* Conditional jumps from 0x70 to 0x7f */
1682
JumpCond(o,OF)1683 JumpCond(o, OF) /* 0x70 = Jump if overflow */
1684 JumpCond(no, !OF) /* 0x71 = Jump if no overflow */
1685 JumpCond(b, CF) /* 0x72 = Jump if below */
1686 JumpCond(nb, !CF) /* 0x73 = Jump if not below */
1687 JumpCond(z, ZF) /* 0x74 = Jump if zero */
1688 JumpCond(nz, !ZF) /* 0x75 = Jump if not zero */
1689 JumpCond(be, CF || ZF) /* 0x76 = Jump if below or equal */
1690 JumpCond(nbe, !(CF || ZF)) /* 0x77 = Jump if not below or equal */
1691 JumpCond(s, SF) /* 0x78 = Jump if sign */
1692 JumpCond(ns, !SF) /* 0x79 = Jump if no sign */
1693 JumpCond(p, PF) /* 0x7a = Jump if parity */
1694 JumpCond(np, !PF) /* 0x7b = Jump if no parity */
1695 JumpCond(l,(!(!SF)!=!(!OF))&&!ZF) /* 0x7c = Jump if less */
1696 JumpCond(nl, ZF||(!(!SF) == !(!OF))) /* 0x7d = Jump if not less */
1697 JumpCond(le, ZF||(!(!SF) != !(!OF))) /* 0x7e = Jump if less than or equal */
1698 JumpCond(nle,(!(!SF)==!(!OF))&&!ZF) /* 0x7f = Jump if not less than or equal*/
1699
1700
1701 static INLINE2 void i_80pre(void)
1702 {
1703 /* Opcode 0x80 */
1704 unsigned ModRM = GetMemInc(c_cs,ip);
1705 BYTE *dest = GetModRMRMB(ModRM);
1706 register unsigned src = GetMemInc(c_cs,ip);
1707 register unsigned tmp = *dest;
1708 register unsigned tmp2;
1709
1710
1711 switch (ModRM & 0x38)
1712 {
1713 case 0x00: /* ADD eb,d8 */
1714 tmp2 = src + tmp;
1715
1716 SetCFB_Add(tmp2,tmp);
1717 SetOFB_Add(tmp2,src,tmp);
1718 SetAF(tmp2,src,tmp);
1719 SetZFB(tmp2);
1720 SetSFB(tmp2);
1721 SetPF(tmp2);
1722
1723 *dest = (BYTE)tmp2;
1724 break;
1725 case 0x08: /* OR eb,d8 */
1726 tmp |= src;
1727
1728 CF = OF = AF = 0;
1729
1730 SetZFB(tmp);
1731 SetSFB(tmp);
1732 SetPF(tmp);
1733
1734 *dest = (BYTE)tmp;
1735 break;
1736 case 0x10: /* ADC eb,d8 */
1737 src += CF;
1738 tmp2 = src + tmp;
1739
1740 CF = tmp2 >> 8;
1741 /* SetCFB_Add(tmp2,tmp); */
1742 SetOFB_Add(tmp2,src,tmp);
1743 SetAF(tmp2,src,tmp);
1744 SetZFB(tmp2);
1745 SetSFB(tmp2);
1746 SetPF(tmp2);
1747
1748 *dest = (BYTE)tmp2;
1749 break;
1750 case 0x18: /* SBB eb,b8 */
1751 src += CF;
1752 tmp2 = tmp;
1753 tmp -= src;
1754
1755 CF = (tmp & 0x100) == 0x100;
1756
1757 /* SetCFB_Sub(tmp,tmp2); */
1758 SetOFB_Sub(tmp,src,tmp2);
1759 SetAF(tmp,src,tmp2);
1760 SetZFB(tmp);
1761 SetSFB(tmp);
1762 SetPF(tmp);
1763
1764 *dest = (BYTE)tmp;
1765 break;
1766 case 0x20: /* AND eb,d8 */
1767 tmp &= src;
1768
1769 CF = OF = AF = 0;
1770
1771 SetZFB(tmp);
1772 SetSFB(tmp);
1773 SetPF(tmp);
1774
1775 *dest = (BYTE)tmp;
1776 break;
1777 case 0x28: /* SUB eb,d8 */
1778 tmp2 = tmp;
1779 tmp -= src;
1780
1781 SetCFB_Sub(tmp,tmp2);
1782 SetOFB_Sub(tmp,src,tmp2);
1783 SetAF(tmp,src,tmp2);
1784 SetZFB(tmp);
1785 SetSFB(tmp);
1786 SetPF(tmp);
1787
1788 *dest = (BYTE)tmp;
1789 break;
1790 case 0x30: /* XOR eb,d8 */
1791 tmp ^= src;
1792
1793 CF = OF = AF = 0;
1794
1795 SetZFB(tmp);
1796 SetSFB(tmp);
1797 SetPF(tmp);
1798
1799 *dest = (BYTE)tmp;
1800 break;
1801 case 0x38: /* CMP eb,d8 */
1802 tmp2 = tmp;
1803 tmp -= src;
1804
1805 SetCFB_Sub(tmp,tmp2);
1806 SetOFB_Sub(tmp,src,tmp2);
1807 SetAF(tmp,src,tmp2);
1808 SetZFB(tmp);
1809 SetSFB(tmp);
1810 SetPF(tmp);
1811
1812 break;
1813 }
1814 }
1815
1816
i_81pre(void)1817 static INLINE2 void i_81pre(void)
1818 {
1819 /* Opcode 0x81 */
1820
1821 unsigned ModRM = GetMemInc(c_cs,ip);
1822 WORD *dest = GetModRMRMW(ModRM);
1823 register unsigned src = GetMemInc(c_cs,ip);
1824 register unsigned tmp = ReadWord(dest);
1825 register unsigned tmp2;
1826
1827 src += GetMemInc(c_cs,ip) << 8;
1828
1829 switch (ModRM & 0x38)
1830 {
1831 case 0x00: /* ADD ew,d16 */
1832 tmp2 = src + tmp;
1833
1834 SetCFW_Add(tmp2,tmp);
1835 SetOFW_Add(tmp2,src,tmp);
1836 SetAF(tmp2,src,tmp);
1837 SetZFW(tmp2);
1838 SetSFW(tmp2);
1839 SetPF(tmp2);
1840
1841 WriteWord(dest,tmp2);
1842 break;
1843 case 0x08: /* OR ew,d16 */
1844 tmp |= src;
1845
1846 CF = OF = AF = 0;
1847
1848 SetZFW(tmp);
1849 SetSFW(tmp);
1850 SetPF(tmp);
1851
1852 WriteWord(dest,tmp);
1853 break;
1854 case 0x10: /* ADC ew,d16 */
1855 src += CF;
1856 tmp2 = src + tmp;
1857
1858 CF = tmp2 >> 16;
1859 /* SetCFW_Add(tmp2,tmp); */
1860 SetOFW_Add(tmp2,src,tmp);
1861 SetAF(tmp2,src,tmp);
1862 SetZFW(tmp2);
1863 SetSFW(tmp2);
1864 SetPF(tmp2);
1865
1866 WriteWord(dest,tmp2);
1867 break;
1868 case 0x18: /* SBB ew,d16 */
1869 src += CF;
1870 tmp2 = tmp;
1871 tmp -= src;
1872
1873 CF = (tmp & 0x10000) == 0x10000;
1874
1875 /* SetCFW_Sub(tmp,tmp2); */
1876 SetOFW_Sub(tmp,src,tmp2);
1877 SetAF(tmp,src,tmp2);
1878 SetZFW(tmp);
1879 SetSFW(tmp);
1880 SetPF(tmp);
1881
1882 WriteWord(dest,tmp);
1883 break;
1884 case 0x20: /* AND ew,d16 */
1885 tmp &= src;
1886
1887 CF = OF = AF = 0;
1888
1889 SetZFW(tmp);
1890 SetSFW(tmp);
1891 SetPF(tmp);
1892
1893 WriteWord(dest,tmp);
1894 break;
1895 case 0x28: /* SUB ew,d16 */
1896 tmp2 = tmp;
1897 tmp -= src;
1898
1899 SetCFW_Sub(tmp,tmp2);
1900 SetOFW_Sub(tmp,src,tmp2);
1901 SetAF(tmp,src,tmp2);
1902 SetZFW(tmp);
1903 SetSFW(tmp);
1904 SetPF(tmp);
1905
1906 WriteWord(dest,tmp);
1907 break;
1908 case 0x30: /* XOR ew,d16 */
1909 tmp ^= src;
1910
1911 CF = OF = AF = 0;
1912
1913 SetZFW(tmp);
1914 SetSFW(tmp);
1915 SetPF(tmp);
1916
1917 WriteWord(dest,tmp);
1918 break;
1919 case 0x38: /* CMP ew,d16 */
1920 tmp2 = tmp;
1921 tmp -= src;
1922
1923 SetCFW_Sub(tmp,tmp2);
1924 SetOFW_Sub(tmp,src,tmp2);
1925 SetAF(tmp,src,tmp2);
1926 SetZFW(tmp);
1927 SetSFW(tmp);
1928 SetPF(tmp);
1929
1930 break;
1931 }
1932 }
1933
1934
i_83pre(void)1935 static INLINE2 void i_83pre(void)
1936 {
1937 /* Opcode 0x83 */
1938
1939 unsigned ModRM = GetMemInc(c_cs,ip);
1940 WORD *dest = GetModRMRMW(ModRM);
1941 register unsigned src = (WORD)((INT16)((INT8)GetMemInc(c_cs,ip)));
1942 register unsigned tmp = ReadWord(dest);
1943 register unsigned tmp2;
1944
1945 switch (ModRM & 0x38)
1946 {
1947 case 0x00: /* ADD ew,d8 */
1948 tmp2 = src + tmp;
1949
1950 SetCFW_Add(tmp2,tmp);
1951 SetOFW_Add(tmp2,src,tmp);
1952 SetAF(tmp2,src,tmp);
1953 SetZFW(tmp2);
1954 SetSFW(tmp2);
1955 SetPF(tmp2);
1956
1957 WriteWord(dest,tmp2);
1958 break;
1959 case 0x08: /* OR ew,d8 */
1960 tmp |= src;
1961
1962 CF = OF = AF = 0;
1963
1964 SetZFW(tmp);
1965 SetSFW(tmp);
1966 SetPF(tmp);
1967
1968 WriteWord(dest,tmp);
1969 break;
1970 case 0x10: /* ADC ew,d8 */
1971 src += CF;
1972 tmp2 = src + tmp;
1973
1974 CF = tmp2 >> 16;
1975
1976 /* SetCFW_Add(tmp2,tmp); */
1977 SetOFW_Add(tmp2,src,tmp);
1978 SetAF(tmp2,src,tmp);
1979 SetZFW(tmp2);
1980 SetSFW(tmp2);
1981 SetPF(tmp2);
1982
1983 WriteWord(dest,tmp2);
1984 break;
1985 case 0x18: /* SBB ew,d8 */
1986 src += CF;
1987 tmp2 = tmp;
1988 tmp -= src;
1989
1990 CF = (tmp & 0x10000) == 0x10000;
1991
1992 /* SetCFW_Sub(tmp,tmp2); */
1993 SetOFW_Sub(tmp,src,tmp2);
1994 SetAF(tmp,src,tmp2);
1995 SetZFW(tmp);
1996 SetSFW(tmp);
1997 SetPF(tmp);
1998
1999 WriteWord(dest,tmp);
2000 break;
2001 case 0x20: /* AND ew,d8 */
2002 tmp &= src;
2003
2004 CF = OF = AF = 0;
2005
2006 SetZFW(tmp);
2007 SetSFW(tmp);
2008 SetPF(tmp);
2009
2010 WriteWord(dest,tmp);
2011 break;
2012 case 0x28: /* SUB ew,d8 */
2013 tmp2 = tmp;
2014 tmp -= src;
2015
2016 SetCFW_Sub(tmp,tmp2);
2017 SetOFW_Sub(tmp,src,tmp2);
2018 SetAF(tmp,src,tmp2);
2019 SetZFW(tmp);
2020 SetSFW(tmp);
2021 SetPF(tmp);
2022
2023 WriteWord(dest,tmp);
2024 break;
2025 case 0x30: /* XOR ew,d8 */
2026 tmp ^= src;
2027
2028 CF = OF = AF = 0;
2029
2030 SetZFW(tmp);
2031 SetSFW(tmp);
2032 SetPF(tmp);
2033
2034 WriteWord(dest,tmp);
2035 break;
2036
2037 case 0x38: /* CMP ew,d8 */
2038 tmp2 = tmp;
2039 tmp -= src;
2040
2041 SetCFW_Sub(tmp,tmp2);
2042 SetOFW_Sub(tmp,src,tmp2);
2043 SetAF(tmp,src,tmp2);
2044 SetZFW(tmp);
2045 SetSFW(tmp);
2046 SetPF(tmp);
2047
2048 break;
2049 }
2050 }
2051
2052
i_test_br8(void)2053 static INLINE2 void i_test_br8(void)
2054 {
2055 /* Opcode 0x84 */
2056
2057 unsigned ModRM = (unsigned)GetMemInc(c_cs,ip);
2058 register unsigned src = (unsigned)*GetModRMRegB(ModRM);
2059 BYTE *dest = GetModRMRMB(ModRM);
2060 register unsigned tmp = (unsigned) *dest;
2061 tmp &= src;
2062 CF = OF = AF = 0;
2063 SetZFB(tmp);
2064 SetSFB(tmp);
2065 SetPF(tmp);
2066 }
2067
2068
i_test_wr16(void)2069 static INLINE2 void i_test_wr16(void)
2070 {
2071 /* Opcode 0x85 */
2072
2073 unsigned ModRM = GetMemInc(c_cs,ip);
2074 WORD *src = GetModRMRegW(ModRM);
2075 WORD *dest = GetModRMRMW(ModRM);
2076 register unsigned tmp1 = (unsigned)ReadWord(src);
2077 register unsigned tmp2 = (unsigned)ReadWord(dest);
2078 register unsigned tmp3 = tmp1 & tmp2;
2079 CF = OF = AF = 0;
2080 SetZFW(tmp3);
2081 SetSFW(tmp3);
2082 SetPF(tmp3);
2083 }
2084
2085
i_xchg_br8(void)2086 static INLINE2 void i_xchg_br8(void)
2087 {
2088 /* Opcode 0x86 */
2089
2090 unsigned ModRM = (unsigned)GetMemInc(c_cs,ip);
2091 register BYTE *src = GetModRMRegB(ModRM);
2092 register BYTE *dest = GetModRMRMB(ModRM);
2093 BYTE tmp;
2094
2095 tmp = *src;
2096 *src = *dest;
2097 *dest = tmp;
2098 }
2099
2100
i_xchg_wr16(void)2101 static INLINE2 void i_xchg_wr16(void)
2102 {
2103 /* Opcode 0x87 */
2104
2105 unsigned ModRM = GetMemInc(c_cs,ip);
2106 register BYTE *src = (BYTE *)GetModRMRegW(ModRM);
2107 register BYTE *dest = (BYTE *)GetModRMRMW(ModRM);
2108 BYTE tmp1,tmp2;
2109
2110 tmp1 = src[0];
2111 tmp2 = src[1];
2112 src[0] = dest[0];
2113 src[1] = dest[1];
2114 dest[0] = tmp1;
2115 dest[1] = tmp2;
2116
2117 }
2118
2119
i_mov_br8(void)2120 static INLINE2 void i_mov_br8(void)
2121 {
2122 /* Opcode 0x88 */
2123
2124 register unsigned ModRM = GetMemInc(c_cs,ip);
2125 register BYTE src = *GetModRMRegB(ModRM);
2126 register BYTE *dest = GetModRMRMB(ModRM);
2127
2128 *dest = src;
2129 }
2130
2131
i_mov_wr16(void)2132 static INLINE2 void i_mov_wr16(void)
2133 {
2134 /* Opcode 0x89 */
2135
2136 register unsigned ModRM = GetMemInc(c_cs,ip);
2137 register WORD *src = GetModRMRegW(ModRM);
2138 register WORD *dest = GetModRMRMW(ModRM);
2139
2140 CopyWord(dest,src);
2141 }
2142
2143
i_mov_r8b(void)2144 static INLINE2 void i_mov_r8b(void)
2145 {
2146 /* Opcode 0x8a */
2147
2148 register unsigned ModRM = GetMemInc(c_cs,ip);
2149 register BYTE *dest = GetModRMRegB(ModRM);
2150 register BYTE src = *GetModRMRMB(ModRM);
2151
2152 *dest = src;
2153 }
2154
2155
i_mov_r16w(void)2156 static INLINE2 void i_mov_r16w(void)
2157 {
2158 /* Opcode 0x8b */
2159
2160 register unsigned ModRM = GetMemInc(c_cs,ip);
2161 register WORD *dest = GetModRMRegW(ModRM);
2162 register WORD *src = GetModRMRMW(ModRM);
2163
2164 CopyWord(dest,src);
2165 }
2166
2167
i_mov_wsreg(void)2168 static INLINE2 void i_mov_wsreg(void)
2169 {
2170 /* Opcode 0x8c */
2171
2172 register unsigned ModRM = GetMemInc(c_cs,ip);
2173 register WORD *dest = GetModRMRMW(ModRM);
2174
2175 WriteWord(dest,sregs[(ModRM & 0x38) >> 3]);
2176 }
2177
2178
i_lea(void)2179 static INLINE2 void i_lea(void)
2180 {
2181 /* Opcode 0x8d */
2182
2183 register unsigned ModRM = GetMemInc(c_cs,ip);
2184 register unsigned src = 0;
2185 register WORD *dest = GetModRMRegW(ModRM);
2186
2187 if (ModRMRM[ModRM].offset)
2188 {
2189 src = (WORD)((INT16)((INT8)GetMemInc(c_cs,ip)));
2190 if (ModRMRM[ModRM].offset16)
2191 src = (GetMemInc(c_cs,ip) << 8) + (BYTE)(src);
2192 }
2193
2194 src += ReadWord(ModRMRM[ModRM].reg1)+ReadWord(ModRMRM[ModRM].reg2);
2195 WriteWord(dest,src);
2196 }
2197
2198
i_mov_sregw(void)2199 static INLINE2 void i_mov_sregw(void)
2200 {
2201 /* Opcode 0x8e */
2202
2203 static int multiple = 0;
2204 register unsigned ModRM = GetMemInc(c_cs,ip);
2205 register WORD *src = GetModRMRMW(ModRM);
2206
2207 switch (ModRM & 0x38)
2208 {
2209 case 0x00: /* mov es,... */
2210 sregs[ES] = ReadWord(src);
2211 c_es = SegToMemPtr(ES);
2212 break;
2213 case 0x18: /* mov ds,... */
2214 sregs[DS] = ReadWord(src);
2215 c_ds = SegToMemPtr(DS);
2216 break;
2217 case 0x10: /* mov ss,... */
2218 sregs[SS] = ReadWord(src);
2219 c_stack = c_ss = SegToMemPtr(SS);
2220
2221 if (multiple == 0) /* Prevent unlimited recursion.. */
2222 {
2223 multiple = 1;
2224 /*
2225 #ifdef DEBUGGER
2226 call_debugger(D_TRACE);
2227 #endif
2228 */
2229 instruction[GetMemInc(c_cs,ip)]();
2230 multiple = 0;
2231 }
2232
2233 break;
2234 case 0x08: /* mov cs,... (hangs 486, but we'll let it through) */
2235 break;
2236
2237 }
2238 }
2239
2240
i_popw(void)2241 static INLINE2 void i_popw(void)
2242 {
2243 /* Opcode 0x8f */
2244
2245 unsigned ModRM = GetMemInc(c_cs,ip);
2246 register WORD *dest = GetModRMRMW(ModRM);
2247 register unsigned tmp = ReadWord(&wregs[SP]);
2248 WORD tmp2 = GetMemW(c_stack,tmp);
2249 tmp += 2;
2250 WriteWord(&wregs[SP],tmp);
2251 WriteWord(dest,tmp2);
2252 }
2253
2254
i_nop(void)2255 static INLINE2 void i_nop(void)
2256 {
2257 /* Opcode 0x90 */
2258 }
2259
2260
i_xchg_axcx(void)2261 static INLINE2 void i_xchg_axcx(void)
2262 {
2263 /* Opcode 0x91 */
2264 XchgAXReg(CX);
2265 }
2266
2267
i_xchg_axdx(void)2268 static INLINE2 void i_xchg_axdx(void)
2269 {
2270 /* Opcode 0x92 */
2271 XchgAXReg(DX);
2272 }
2273
2274
i_xchg_axbx(void)2275 static INLINE2 void i_xchg_axbx(void)
2276 {
2277 /* Opcode 0x93 */
2278 XchgAXReg(BX);
2279 }
2280
2281
i_xchg_axsp(void)2282 static INLINE2 void i_xchg_axsp(void)
2283 {
2284 /* Opcode 0x94 */
2285 XchgAXReg(SP);
2286 }
2287
2288
i_xchg_axbp(void)2289 static INLINE2 void i_xchg_axbp(void)
2290 {
2291 /* Opcode 0x95 */
2292 XchgAXReg(BP);
2293 }
2294
2295
i_xchg_axsi(void)2296 static INLINE2 void i_xchg_axsi(void)
2297 {
2298 /* Opcode 0x96 */
2299 XchgAXReg(SI);
2300 }
2301
2302
i_xchg_axdi(void)2303 static INLINE2 void i_xchg_axdi(void)
2304 {
2305 /* Opcode 0x97 */
2306 XchgAXReg(DI);
2307 }
2308
i_cbw(void)2309 static INLINE2 void i_cbw(void)
2310 {
2311 /* Opcode 0x98 */
2312
2313 *bregs[AH] = (*bregs[AL] & 0x80) ? 0xff : 0;
2314 }
2315
i_cwd(void)2316 static INLINE2 void i_cwd(void)
2317 {
2318 /* Opcode 0x99 */
2319
2320 wregs[DX] = (*bregs[AH] & 0x80) ? ChangeE(0xffff) : ChangeE(0);
2321 }
2322
2323
i_call_far(void)2324 static INLINE2 void i_call_far(void)
2325 {
2326 register unsigned tmp, tmp1, tmp2;
2327
2328 tmp = GetMemInc(c_cs,ip);
2329 tmp += GetMemInc(c_cs,ip) << 8;
2330
2331 tmp2 = GetMemInc(c_cs,ip);
2332 tmp2 += GetMemInc(c_cs,ip) << 8;
2333
2334 tmp1 = (WORD)(ReadWord(&wregs[SP])-2);
2335
2336 PutMemW(c_stack,tmp1,sregs[CS]);
2337 tmp1 = (WORD)(tmp1-2);
2338 PutMemW(c_stack,tmp1,ip);
2339
2340 WriteWord(&wregs[SP],tmp1);
2341
2342 ip = (WORD)tmp;
2343 sregs[CS] = (WORD)tmp2;
2344 c_cs = SegToMemPtr(CS);
2345 }
2346
2347
i_wait(void)2348 static INLINE2 void i_wait(void)
2349 {
2350 /* Opcode 0x9b */
2351
2352 return;
2353 }
2354
2355
i_pushf(void)2356 static INLINE2 void i_pushf(void)
2357 {
2358 /* Opcode 0x9c */
2359
2360 register unsigned tmp1 = (ReadWord(&wregs[SP])-2);
2361 WORD tmp2 = CompressFlags() | 0xf000;
2362
2363 PutMemW(c_stack,tmp1,tmp2);
2364 WriteWord(&wregs[SP],tmp1);
2365 }
2366
2367
i_popf(void)2368 static INLINE2 void i_popf(void)
2369 {
2370 /* Opcode 0x9d */
2371
2372 register unsigned tmp = ReadWord(&wregs[SP]);
2373 unsigned tmp2 = (unsigned)GetMemW(c_stack,tmp);
2374
2375 ExpandFlags(tmp2);
2376 tmp += 2;
2377 WriteWord(&wregs[SP],tmp);
2378
2379 if (IF && int_blocked)
2380 {
2381 int_pending = int_blocked;
2382 int_blocked = 0;
2383 D2(printf("Unblocking interrupt\n"););
2384 }
2385 if (TF) trap();
2386 }
2387
2388
i_sahf(void)2389 static INLINE2 void i_sahf(void)
2390 {
2391 /* Opcode 0x9e */
2392
2393 unsigned tmp = (CompressFlags() & 0xff00) | (*bregs[AH] & 0xd5);
2394
2395 ExpandFlags(tmp);
2396 }
2397
2398
i_lahf(void)2399 static INLINE2 void i_lahf(void)
2400 {
2401 /* Opcode 0x9f */
2402
2403 *bregs[AH] = CompressFlags() & 0xff;
2404 }
2405
i_mov_aldisp(void)2406 static INLINE2 void i_mov_aldisp(void)
2407 {
2408 /* Opcode 0xa0 */
2409
2410 register unsigned addr;
2411
2412 addr = GetMemInc(c_cs,ip);
2413 addr += GetMemInc(c_cs, ip) << 8;
2414
2415 *bregs[AL] = GetMemB(c_ds, addr);
2416 }
2417
2418
i_mov_axdisp(void)2419 static INLINE2 void i_mov_axdisp(void)
2420 {
2421 /* Opcode 0xa1 */
2422
2423 register unsigned addr;
2424
2425 addr = GetMemInc(c_cs, ip);
2426 addr += GetMemInc(c_cs, ip) << 8;
2427
2428 *bregs[AL] = GetMemB(c_ds, addr);
2429 *bregs[AH] = GetMemB(c_ds, addr+1);
2430 }
2431
2432
i_mov_dispal(void)2433 static INLINE2 void i_mov_dispal(void)
2434 {
2435 /* Opcode 0xa2 */
2436
2437 register unsigned addr;
2438
2439 addr = GetMemInc(c_cs,ip);
2440 addr += GetMemInc(c_cs, ip) << 8;
2441
2442 PutMemB(c_ds, addr, *bregs[AL]);
2443 }
2444
2445
i_mov_dispax(void)2446 static INLINE2 void i_mov_dispax(void)
2447 {
2448 /* Opcode 0xa3 */
2449
2450 register unsigned addr;
2451
2452 addr = GetMemInc(c_cs, ip);
2453 addr += GetMemInc(c_cs, ip) << 8;
2454
2455 PutMemB(c_ds, addr, *bregs[AL]);
2456 PutMemB(c_ds, addr+1, *bregs[AH]);
2457 }
2458
2459
i_movsb(void)2460 static INLINE2 void i_movsb(void)
2461 {
2462 /* Opcode 0xa4 */
2463
2464 register unsigned di = ReadWord(&wregs[DI]);
2465 register unsigned si = ReadWord(&wregs[SI]);
2466
2467 BYTE tmp = GetMemB(c_ds,si);
2468
2469 PutMemB(c_es,di, tmp);
2470
2471 di += -2*DF +1;
2472 si += -2*DF +1;
2473
2474 WriteWord(&wregs[DI],di);
2475 WriteWord(&wregs[SI],si);
2476 }
2477
2478
i_movsw(void)2479 static INLINE2 void i_movsw(void)
2480 {
2481 /* Opcode 0xa5 */
2482
2483 register unsigned di = ReadWord(&wregs[DI]);
2484 register unsigned si = ReadWord(&wregs[SI]);
2485
2486 WORD tmp = GetMemW(c_ds,si);
2487
2488 PutMemW(c_es,di, tmp);
2489
2490 di += -4*DF +2;
2491 si += -4*DF +2;
2492
2493 WriteWord(&wregs[DI],di);
2494 WriteWord(&wregs[SI],si);
2495 }
2496
2497
i_cmpsb(void)2498 static INLINE2 void i_cmpsb(void)
2499 {
2500 /* Opcode 0xa6 */
2501
2502 unsigned di = ReadWord(&wregs[DI]);
2503 unsigned si = ReadWord(&wregs[SI]);
2504 unsigned src = GetMemB(c_es, di);
2505 unsigned tmp = GetMemB(c_ds, si);
2506 unsigned tmp2 = tmp;
2507
2508 tmp -= src;
2509
2510 SetCFB_Sub(tmp,tmp2);
2511 SetOFB_Sub(tmp,src,tmp2);
2512 SetAF(tmp,src,tmp2);
2513 SetZFB(tmp);
2514 SetSFB(tmp);
2515 SetPF(tmp);
2516
2517 di += -2*DF +1;
2518 si += -2*DF +1;
2519
2520 WriteWord(&wregs[DI],di);
2521 WriteWord(&wregs[SI],si);
2522 }
2523
2524
i_cmpsw(void)2525 static INLINE2 void i_cmpsw(void)
2526 {
2527 /* Opcode 0xa7 */
2528
2529 unsigned di = ReadWord(&wregs[DI]);
2530 unsigned si = ReadWord(&wregs[SI]);
2531 unsigned src = GetMemW(c_es, di);
2532 unsigned tmp = GetMemW(c_ds, si);
2533 unsigned tmp2 = tmp;
2534
2535 tmp -= src;
2536
2537 SetCFW_Sub(tmp,tmp2);
2538 SetOFW_Sub(tmp,src,tmp2);
2539 SetAF(tmp,src,tmp2);
2540 SetZFW(tmp);
2541 SetSFW(tmp);
2542 SetPF(tmp);
2543
2544 di += -4*DF +2;
2545 si += -4*DF +2;
2546
2547 WriteWord(&wregs[DI],di);
2548 WriteWord(&wregs[SI],si);
2549 }
2550
2551
i_test_ald8(void)2552 static INLINE2 void i_test_ald8(void)
2553 {
2554 /* Opcode 0xa8 */
2555
2556 register unsigned tmp1 = (unsigned)*bregs[AL];
2557 register unsigned tmp2 = (unsigned) GetMemInc(c_cs,ip);
2558
2559 tmp1 &= tmp2;
2560 CF = OF = AF = 0;
2561 SetZFB(tmp1);
2562 SetSFB(tmp1);
2563 SetPF(tmp1);
2564 }
2565
2566
i_test_axd16(void)2567 static INLINE2 void i_test_axd16(void)
2568 {
2569 /* Opcode 0xa9 */
2570
2571 register unsigned tmp1 = (unsigned)ReadWord(&wregs[AX]);
2572 register unsigned tmp2;
2573
2574 tmp2 = (unsigned) GetMemInc(c_cs,ip);
2575 tmp2 += GetMemInc(c_cs,ip) << 8;
2576
2577 tmp1 &= tmp2;
2578 CF = OF = AF = 0;
2579 SetZFW(tmp1);
2580 SetSFW(tmp1);
2581 SetPF(tmp1);
2582 }
2583
i_stosb(void)2584 static INLINE2 void i_stosb(void)
2585 {
2586 /* Opcode 0xaa */
2587
2588 register unsigned di = ReadWord(&wregs[DI]);
2589
2590 PutMemB(c_es,di,*bregs[AL]);
2591 di += -2*DF +1;
2592 WriteWord(&wregs[DI],di);
2593 }
2594
i_stosw(void)2595 static INLINE2 void i_stosw(void)
2596 {
2597 /* Opcode 0xab */
2598
2599 register unsigned di = ReadWord(&wregs[DI]);
2600
2601 PutMemB(c_es,di,*bregs[AL]);
2602 PutMemB(c_es,di+1,*bregs[AH]);
2603 di += -4*DF +2;;
2604 WriteWord(&wregs[DI],di);
2605 }
2606
i_lodsb(void)2607 static INLINE2 void i_lodsb(void)
2608 {
2609 /* Opcode 0xac */
2610
2611 register unsigned si = ReadWord(&wregs[SI]);
2612
2613 *bregs[AL] = GetMemB(c_ds,si);
2614 si += -2*DF +1;
2615 WriteWord(&wregs[SI],si);
2616 }
2617
i_lodsw(void)2618 static INLINE2 void i_lodsw(void)
2619 {
2620 /* Opcode 0xad */
2621
2622 register unsigned si = ReadWord(&wregs[SI]);
2623 register unsigned tmp = GetMemW(c_ds,si);
2624
2625 si += -4*DF+2;
2626 WriteWord(&wregs[SI],si);
2627 WriteWord(&wregs[AX],tmp);
2628 }
2629
i_scasb(void)2630 static INLINE2 void i_scasb(void)
2631 {
2632 /* Opcode 0xae */
2633
2634 unsigned di = ReadWord(&wregs[DI]);
2635 unsigned src = GetMemB(c_es, di);
2636 unsigned tmp = *bregs[AL];
2637 unsigned tmp2 = tmp;
2638
2639 tmp -= src;
2640
2641 SetCFB_Sub(tmp,tmp2);
2642 SetOFB_Sub(tmp,src,tmp2);
2643 SetAF(tmp,src,tmp2);
2644 SetZFB(tmp);
2645 SetSFB(tmp);
2646 SetPF(tmp);
2647
2648 di += -2*DF +1;
2649
2650 WriteWord(&wregs[DI],di);
2651 }
2652
2653
i_scasw(void)2654 static INLINE2 void i_scasw(void)
2655 {
2656 /* Opcode 0xaf */
2657
2658 unsigned di = ReadWord(&wregs[DI]);
2659 unsigned src = GetMemW(c_es, di);
2660 unsigned tmp = ReadWord(&wregs[AX]);
2661 unsigned tmp2 = tmp;
2662
2663 tmp -= src;
2664
2665 SetCFW_Sub(tmp,tmp2);
2666 SetOFW_Sub(tmp,src,tmp2);
2667 SetAF(tmp,src,tmp2);
2668 SetZFW(tmp);
2669 SetSFW(tmp);
2670 SetPF(tmp);
2671
2672 di += -4*DF +2;
2673
2674 WriteWord(&wregs[DI],di);
2675 }
2676
i_mov_ald8(void)2677 static INLINE2 void i_mov_ald8(void)
2678 {
2679 /* Opcode 0xb0 */
2680
2681 *bregs[AL] = GetMemInc(c_cs,ip);
2682 }
2683
2684
i_mov_cld8(void)2685 static INLINE2 void i_mov_cld8(void)
2686 {
2687 /* Opcode 0xb1 */
2688
2689 *bregs[CL] = GetMemInc(c_cs,ip);
2690 }
2691
2692
i_mov_dld8(void)2693 static INLINE2 void i_mov_dld8(void)
2694 {
2695 /* Opcode 0xb2 */
2696
2697 *bregs[DL] = GetMemInc(c_cs,ip);
2698 }
2699
2700
i_mov_bld8(void)2701 static INLINE2 void i_mov_bld8(void)
2702 {
2703 /* Opcode 0xb3 */
2704
2705 *bregs[BL] = GetMemInc(c_cs,ip);
2706 }
2707
2708
i_mov_ahd8(void)2709 static INLINE2 void i_mov_ahd8(void)
2710 {
2711 /* Opcode 0xb4 */
2712
2713 *bregs[AH] = GetMemInc(c_cs,ip);
2714 }
2715
2716
i_mov_chd8(void)2717 static INLINE2 void i_mov_chd8(void)
2718 {
2719 /* Opcode 0xb5 */
2720
2721 *bregs[CH] = GetMemInc(c_cs,ip);
2722 }
2723
2724
i_mov_dhd8(void)2725 static INLINE2 void i_mov_dhd8(void)
2726 {
2727 /* Opcode 0xb6 */
2728
2729 *bregs[DH] = GetMemInc(c_cs,ip);
2730 }
2731
2732
i_mov_bhd8(void)2733 static INLINE2 void i_mov_bhd8(void)
2734 {
2735 /* Opcode 0xb7 */
2736
2737 *bregs[BH] = GetMemInc(c_cs,ip);
2738 }
2739
2740
i_mov_axd16(void)2741 static INLINE2 void i_mov_axd16(void)
2742 {
2743 /* Opcode 0xb8 */
2744
2745 *bregs[AL] = GetMemInc(c_cs,ip);
2746 *bregs[AH] = GetMemInc(c_cs,ip);
2747 }
2748
2749
i_mov_cxd16(void)2750 static INLINE2 void i_mov_cxd16(void)
2751 {
2752 /* Opcode 0xb9 */
2753
2754 *bregs[CL] = GetMemInc(c_cs,ip);
2755 *bregs[CH] = GetMemInc(c_cs,ip);
2756 }
2757
2758
i_mov_dxd16(void)2759 static INLINE2 void i_mov_dxd16(void)
2760 {
2761 /* Opcode 0xba */
2762
2763 *bregs[DL] = GetMemInc(c_cs,ip);
2764 *bregs[DH] = GetMemInc(c_cs,ip);
2765 }
2766
2767
i_mov_bxd16(void)2768 static INLINE2 void i_mov_bxd16(void)
2769 {
2770 /* Opcode 0xbb */
2771
2772 *bregs[BL] = GetMemInc(c_cs,ip);
2773 *bregs[BH] = GetMemInc(c_cs,ip);
2774 }
2775
2776
i_mov_spd16(void)2777 static INLINE2 void i_mov_spd16(void)
2778 {
2779 /* Opcode 0xbc */
2780
2781 *bregs[SPL] = GetMemInc(c_cs,ip);
2782 *bregs[SPH] = GetMemInc(c_cs,ip);
2783 }
2784
2785
i_mov_bpd16(void)2786 static INLINE2 void i_mov_bpd16(void)
2787 {
2788 /* Opcode 0xbd */
2789
2790 *bregs[BPL] = GetMemInc(c_cs,ip);
2791 *bregs[BPH] = GetMemInc(c_cs,ip);
2792 }
2793
2794
i_mov_sid16(void)2795 static INLINE2 void i_mov_sid16(void)
2796 {
2797 /* Opcode 0xbe */
2798
2799 *bregs[SIL] = GetMemInc(c_cs,ip);
2800 *bregs[SIH] = GetMemInc(c_cs,ip);
2801 }
2802
2803
i_mov_did16(void)2804 static INLINE2 void i_mov_did16(void)
2805 {
2806 /* Opcode 0xbf */
2807
2808 *bregs[DIL] = GetMemInc(c_cs,ip);
2809 *bregs[DIH] = GetMemInc(c_cs,ip);
2810 }
2811
2812
i_ret_d16(void)2813 static INLINE2 void i_ret_d16(void)
2814 {
2815 /* Opcode 0xc2 */
2816
2817 register unsigned tmp = ReadWord(&wregs[SP]);
2818 register unsigned count;
2819
2820 count = GetMemInc(c_cs,ip);
2821 count += GetMemInc(c_cs,ip) << 8;
2822
2823 ip = GetMemW(c_stack,tmp);
2824 tmp += count+2;
2825 WriteWord(&wregs[SP],tmp);
2826 }
2827
2828
i_ret(void)2829 static INLINE2 void i_ret(void)
2830 {
2831 /* Opcode 0xc3 */
2832
2833 register unsigned tmp = ReadWord(&wregs[SP]);
2834 ip = GetMemW(c_stack,tmp);
2835 tmp += 2;
2836 WriteWord(&wregs[SP],tmp);
2837 }
2838
2839
i_les_dw(void)2840 static INLINE2 void i_les_dw(void)
2841 {
2842 /* Opcode 0xc4 */
2843
2844 unsigned ModRM = GetMemInc(c_cs,ip);
2845 register WORD *dest = GetModRMRegW(ModRM);
2846 register WORD *src = GetModRMRMW(ModRM);
2847 WORD tmp = ReadWord(src);
2848
2849 WriteWord(dest, tmp);
2850 src += 1;
2851 sregs[ES] = ReadWord(src);
2852 c_es = SegToMemPtr(ES);
2853 }
2854
2855
i_lds_dw(void)2856 static INLINE2 void i_lds_dw(void)
2857 {
2858 /* Opcode 0xc5 */
2859
2860 unsigned ModRM = GetMemInc(c_cs,ip);
2861 register WORD *dest = GetModRMRegW(ModRM);
2862 register WORD *src = GetModRMRMW(ModRM);
2863 WORD tmp = ReadWord(src);
2864
2865 WriteWord(dest,tmp);
2866 src += 1;
2867 sregs[DS] = ReadWord(src);
2868 c_ds = SegToMemPtr(DS);
2869 }
2870
i_mov_bd8(void)2871 static INLINE2 void i_mov_bd8(void)
2872 {
2873 /* Opcode 0xc6 */
2874
2875 unsigned ModRM = GetMemInc(c_cs,ip);
2876 register BYTE *dest = GetModRMRMB(ModRM);
2877
2878 *dest = GetMemInc(c_cs,ip);
2879 }
2880
2881
i_mov_wd16(void)2882 static INLINE2 void i_mov_wd16(void)
2883 {
2884 /* Opcode 0xc7 */
2885
2886 unsigned ModRM = GetMemInc(c_cs,ip);
2887 register BYTE *dest = (BYTE *)GetModRMRMW(ModRM);
2888
2889 *dest++ = GetMemInc(c_cs,ip);
2890 *dest = GetMemInc(c_cs,ip);
2891 }
2892
2893
i_retf_d16(void)2894 static INLINE2 void i_retf_d16(void)
2895 {
2896 /* Opcode 0xca */
2897
2898 register unsigned tmp = ReadWord(&wregs[SP]);
2899 register unsigned count;
2900
2901 count = GetMemInc(c_cs,ip);
2902 count += GetMemInc(c_cs,ip) << 8;
2903
2904 ip = GetMemW(c_stack,tmp);
2905 tmp = (WORD)(tmp+2);
2906 sregs[CS] = GetMemW(c_stack,tmp);
2907 c_cs = SegToMemPtr(CS);
2908 tmp += count+2;
2909 WriteWord(&wregs[SP],tmp);
2910 }
2911
2912
i_retf(void)2913 static INLINE2 void i_retf(void)
2914 {
2915 /* Opcode 0xcb */
2916
2917 register unsigned tmp = ReadWord(&wregs[SP]);
2918 ip = GetMemW(c_stack,tmp);
2919 tmp = (WORD)(tmp+2);
2920 sregs[CS] = GetMemW(c_stack,tmp);
2921 c_cs = SegToMemPtr(CS);
2922 tmp += 2;
2923 WriteWord(&wregs[SP],tmp);
2924 }
2925
2926
i_int3(void)2927 static INLINE2 void i_int3(void)
2928 {
2929 /* Opcode 0xcc */
2930
2931 interrupt(3);
2932 }
2933
2934
i_int(void)2935 static INLINE2 void i_int(void)
2936 {
2937 /* Opcode 0xcd */
2938
2939 unsigned int_num = GetMemInc(c_cs,ip);
2940
2941 interrupt(int_num);
2942 }
2943
2944
i_into(void)2945 static INLINE2 void i_into(void)
2946 {
2947 /* Opcode 0xce */
2948
2949 if (OF)
2950 interrupt(4);
2951 }
2952
2953
i_iret(void)2954 static INLINE2 void i_iret(void)
2955 {
2956 /* Opcode 0xcf */
2957
2958 register unsigned tmp = ReadWord(&wregs[SP]);
2959 ip = GetMemW(c_stack,tmp);
2960 tmp = (WORD)(tmp+2);
2961 sregs[CS] = GetMemW(c_stack,tmp);
2962 c_cs = SegToMemPtr(CS);
2963 tmp += 2;
2964 WriteWord(&wregs[SP],tmp);
2965
2966 i_popf();
2967 #ifdef DEBUGGER
2968 call_debugger(D_TRACE);
2969 #endif
2970 }
2971
2972
i_d0pre(void)2973 static INLINE2 void i_d0pre(void)
2974 {
2975 /* Opcode 0xd0 */
2976
2977 unsigned ModRM = GetMemInc(c_cs,ip);
2978 register BYTE *dest = GetModRMRMB(ModRM);
2979 register unsigned tmp = *dest;
2980 register unsigned tmp2 = tmp;
2981
2982 switch (ModRM & 0x38)
2983 {
2984 case 0x00: /* ROL eb,1 */
2985 CF = (tmp & 0x80) != 0;
2986 *dest = (tmp << 1) + CF;
2987 OF = !(!(tmp & 0x40)) != CF;
2988 break;
2989 case 0x08: /* ROR eb,1 */
2990 CF = (tmp & 0x01) != 0;
2991 *dest = (tmp >> 1) + (CF << 7);
2992 OF = !(!(tmp & 0x80)) != CF;
2993 break;
2994 case 0x10: /* RCL eb,1 */
2995 OF = (tmp ^ (tmp << 1)) & 0x80;
2996 *dest = (tmp << 1) + CF;
2997 CF = (tmp & 0x80) != 0;
2998 break;
2999 case 0x18: /* RCR eb,1 */
3000 *dest = (tmp >> 1) + (CF << 7);
3001 OF = !(!(tmp & 0x80)) != CF;
3002 CF = (tmp & 0x01) != 0;
3003 break;
3004 case 0x20: /* SHL eb,1 */
3005 case 0x30:
3006 tmp += tmp;
3007
3008 SetCFB_Add(tmp,tmp2);
3009 SetOFB_Add(tmp,tmp2,tmp2);
3010 AF = 1;
3011 SetZFB(tmp);
3012 SetSFB(tmp);
3013 SetPF(tmp);
3014
3015 *dest = (BYTE)tmp;
3016 break;
3017 case 0x28: /* SHR eb,1 */
3018 CF = (tmp & 0x01) != 0;
3019 OF = tmp & 0x80;
3020
3021 tmp2 = tmp >> 1;
3022
3023 SetSFB(tmp2);
3024 SetPF(tmp2);
3025 SetZFB(tmp2);
3026 AF = 1;
3027 *dest = (BYTE)tmp2;
3028 break;
3029 case 0x38: /* SAR eb,1 */
3030 CF = (tmp & 0x01) != 0;
3031 OF = 0;
3032
3033 tmp2 = (tmp >> 1) | (tmp & 0x80);
3034
3035 SetSFB(tmp2);
3036 SetPF(tmp2);
3037 SetZFB(tmp2);
3038 AF = 1;
3039 *dest = (BYTE)tmp2;
3040 break;
3041 }
3042 }
3043
3044
i_d1pre(void)3045 static INLINE2 void i_d1pre(void)
3046 {
3047 /* Opcode 0xd1 */
3048
3049 unsigned ModRM = GetMemInc(c_cs,ip);
3050 register WORD *dest = GetModRMRMW(ModRM);
3051 register unsigned tmp = ReadWord(dest);
3052 register unsigned tmp2 = tmp;
3053
3054 switch (ModRM & 0x38)
3055 {
3056 case 0x00: /* ROL ew,1 */
3057 CF = (tmp & 0x8000) != 0;
3058 tmp2 = (tmp << 1) + CF;
3059 OF = !(!(tmp & 0x4000)) != CF;
3060 WriteWord(dest,tmp2);
3061 break;
3062 case 0x08: /* ROR ew,1 */
3063 CF = (tmp & 0x01) != 0;
3064 tmp2 = (tmp >> 1) + ((unsigned)CF << 15);
3065 OF = !(!(tmp & 0x8000)) != CF;
3066 WriteWord(dest,tmp2);
3067 break;
3068 case 0x10: /* RCL ew,1 */
3069 tmp2 = (tmp << 1) + CF;
3070 OF = (tmp ^ (tmp << 1)) & 0x8000;
3071 CF = (tmp & 0x8000) != 0;
3072 WriteWord(dest,tmp2);
3073 break;
3074 case 0x18: /* RCR ew,1 */
3075 tmp2 = (tmp >> 1) + ((unsigned)CF << 15);
3076 OF = !(!(tmp & 0x8000)) != CF;
3077 CF = (tmp & 0x01) != 0;
3078 WriteWord(dest,tmp2);
3079 break;
3080 case 0x20: /* SHL ew,1 */
3081 case 0x30:
3082 tmp += tmp;
3083
3084 SetCFW_Add(tmp,tmp2);
3085 SetOFW_Add(tmp,tmp2,tmp2);
3086 AF = 1;
3087 SetZFW(tmp);
3088 SetSFW(tmp);
3089 SetPF(tmp);
3090
3091 WriteWord(dest,tmp);
3092 break;
3093 case 0x28: /* SHR ew,1 */
3094 CF = (tmp & 0x01) != 0;
3095 OF = tmp & 0x8000;
3096
3097 tmp2 = tmp >> 1;
3098
3099 SetSFW(tmp2);
3100 SetPF(tmp2);
3101 SetZFW(tmp2);
3102 AF = 1;
3103 WriteWord(dest,tmp2);
3104 break;
3105 case 0x38: /* SAR ew,1 */
3106 CF = (tmp & 0x01) != 0;
3107 OF = 0;
3108
3109 tmp2 = (tmp >> 1) | (tmp & 0x8000);
3110
3111 SetSFW(tmp2);
3112 SetPF(tmp2);
3113 SetZFW(tmp2);
3114 AF = 1;
3115 WriteWord(dest,tmp2);
3116 break;
3117 }
3118 }
3119
3120
i_d2pre(void)3121 static INLINE2 void i_d2pre(void)
3122 {
3123 /* Opcode 0xd2 */
3124
3125 unsigned ModRM;
3126 register BYTE *dest;
3127 register unsigned tmp;
3128 register unsigned tmp2;
3129 unsigned count;
3130
3131 if (*bregs[CL] == 1)
3132 {
3133 i_d0pre();
3134 D(printf("Skipping CL processing\n"););
3135 return;
3136 }
3137
3138 ModRM = GetMemInc(c_cs,ip);
3139 dest = GetModRMRMB(ModRM);
3140 tmp = (unsigned)*dest;
3141 count = (unsigned)*bregs[CL];
3142
3143 switch (ModRM & 0x38)
3144 {
3145 case 0x00: /* ROL eb,CL */
3146 for (; count > 0; count--)
3147 {
3148 CF = (tmp & 0x80) != 0;
3149 tmp = (tmp << 1) + CF;
3150 }
3151 *dest = (BYTE)tmp;
3152 break;
3153 case 0x08: /* ROR eb,CL */
3154 for (; count > 0; count--)
3155 {
3156 CF = (tmp & 0x01) != 0;
3157 tmp = (tmp >> 1) + (CF << 7);
3158 }
3159 *dest = (BYTE)tmp;
3160 break;
3161 case 0x10: /* RCL eb,CL */
3162 for (; count > 0; count--)
3163 {
3164 tmp2 = CF;
3165 CF = (tmp & 0x80) != 0;
3166 tmp = (tmp << 1) + tmp2;
3167 }
3168 *dest = (BYTE)tmp;
3169 break;
3170 case 0x18: /* RCR eb,CL */
3171 for (; count > 0; count--)
3172 {
3173 tmp2 = (tmp >> 1) + (CF << 7);
3174 CF = (tmp & 0x01) != 0;
3175 tmp = tmp2;
3176 }
3177 *dest = (BYTE)tmp;
3178 break;
3179 case 0x20:
3180 case 0x30: /* SHL eb,CL */
3181 if (count >= 9)
3182 {
3183 CF = 0; /* Not sure about this... */
3184 tmp = 0;
3185 }
3186 else
3187 {
3188 CF = ((tmp << (count-1)) & 0x80) != 0;
3189 tmp <<= count;
3190 }
3191
3192 AF = 1;
3193 SetZFB(tmp);
3194 SetSFB(tmp);
3195 SetPF(tmp);
3196
3197 *dest = (BYTE)tmp;
3198 break;
3199 case 0x28: /* SHR eb,CL */
3200 if (count >= 9)
3201 {
3202 CF = 0; /* Not sure about this... */
3203 tmp = 0;
3204 }
3205 else
3206 {
3207 CF = ((tmp >> (count-1)) & 0x1) != 0;
3208 tmp >>= count;
3209 }
3210
3211 SetSFB(tmp);
3212 SetPF(tmp);
3213 SetZFB(tmp);
3214 AF = 1;
3215 *dest = (BYTE)tmp;
3216 break;
3217 case 0x38: /* SAR eb,CL */
3218 tmp2 = tmp & 0x80;
3219 CF = (((INT8)tmp >> (count-1)) & 0x01) != 0;
3220 for (; count > 0; count--)
3221 tmp = (tmp >> 1) | tmp2;
3222
3223 SetSFB(tmp);
3224 SetPF(tmp);
3225 SetZFB(tmp);
3226 AF = 1;
3227 *dest = (BYTE)tmp;
3228 break;
3229 }
3230 }
3231
3232
i_d3pre(void)3233 static INLINE2 void i_d3pre(void)
3234 {
3235 /* Opcode 0xd3 */
3236
3237 unsigned ModRM;
3238 register WORD *dest;
3239 register unsigned tmp;
3240 register unsigned tmp2;
3241 unsigned count;
3242
3243 if (*bregs[CL] == 1)
3244 {
3245 i_d1pre();
3246 return;
3247 }
3248
3249 ModRM = GetMemInc(c_cs,ip);
3250 dest = GetModRMRMW(ModRM);
3251 tmp = ReadWord(dest);
3252 count = (unsigned)*bregs[CL];
3253
3254 switch (ModRM & 0x38)
3255 {
3256 case 0x00: /* ROL ew,CL */
3257 for (; count > 0; count--)
3258 {
3259 CF = (tmp & 0x8000) != 0;
3260 tmp = (tmp << 1) + CF;
3261 }
3262 WriteWord(dest,tmp);
3263 break;
3264 case 0x08: /* ROR ew,CL */
3265 for (; count > 0; count--)
3266 {
3267 CF = (tmp & 0x01) != 0;
3268 tmp = (tmp >> 1) + (CF << 15);
3269 }
3270 WriteWord(dest, tmp);
3271 break;
3272 case 0x10: /* RCL ew,CL */
3273 for (; count > 0; count--)
3274 {
3275 tmp2 = CF;
3276 CF = (tmp & 0x8000) != 0;
3277 tmp = (tmp << 1) + tmp2;
3278 }
3279 WriteWord(dest, tmp);
3280 break;
3281 case 0x18: /* RCR ew,CL */
3282 for (; count > 0; count--)
3283 {
3284 tmp2 = (tmp >> 1) + (CF << 15);
3285 CF = (tmp & 0x01) != 0;
3286 tmp = tmp2;
3287 }
3288 WriteWord(dest, tmp);
3289 break;
3290 case 0x20:
3291 case 0x30: /* SHL ew,CL */
3292 if (count >= 17)
3293 {
3294 CF = 0; /* Not sure about this... */
3295 tmp = 0;
3296 }
3297 else
3298 {
3299 CF = ((tmp << (count-1)) & 0x8000) != 0;
3300 tmp <<= count;
3301 }
3302
3303 AF = 1;
3304 SetZFW(tmp);
3305 SetSFW(tmp);
3306 SetPF(tmp);
3307
3308 WriteWord(dest, tmp);
3309 break;
3310 case 0x28: /* SHR ew,CL */
3311 if (count >= 17)
3312 {
3313 CF = 0; /* Not sure about this... */
3314 tmp = 0;
3315 }
3316 else
3317 {
3318 CF = ((tmp >> (count-1)) & 0x1) != 0;
3319 tmp >>= count;
3320 }
3321
3322 SetSFW(tmp);
3323 SetPF(tmp);
3324 SetZFW(tmp);
3325 AF = 1;
3326 WriteWord(dest, tmp);
3327 break;
3328 case 0x38: /* SAR ew,CL */
3329 tmp2 = tmp & 0x8000;
3330 CF = (((INT16)tmp >> (count-1)) & 0x01) != 0;
3331 for (; count > 0; count--)
3332 tmp = (tmp >> 1) | tmp2;
3333
3334 SetSFW(tmp);
3335 SetPF(tmp);
3336 SetZFW(tmp);
3337 AF = 1;
3338 WriteWord(dest, tmp);
3339 break;
3340 }
3341 }
3342
i_aam(void)3343 static INLINE2 void i_aam(void)
3344 {
3345 /* Opcode 0xd4 */
3346 unsigned mult = GetMemInc(c_cs,ip);
3347
3348 if (mult == 0)
3349 interrupt(0);
3350 else
3351 {
3352 *bregs[AH] = *bregs[AL] / mult;
3353 *bregs[AL] %= mult;
3354
3355 SetPF(*bregs[AL]);
3356 SetZFW(wregs[AX]);
3357 SetSFB(*bregs[AH]);
3358 }
3359 }
3360
3361
i_aad(void)3362 static INLINE2 void i_aad(void)
3363 {
3364 /* Opcode 0xd5 */
3365 unsigned mult = GetMemInc(c_cs,ip);
3366
3367 *bregs[AL] = *bregs[AH] * mult + *bregs[AL];
3368 *bregs[AH] = 0;
3369
3370 SetPF(*bregs[AL]);
3371 SetZFB(*bregs[AL]);
3372 SF = 0;
3373 }
3374
i_xlat(void)3375 static INLINE2 void i_xlat(void)
3376 {
3377 /* Opcode 0xd7 */
3378
3379 unsigned dest = ReadWord(&wregs[BX])+*bregs[AL];
3380
3381 *bregs[AL] = GetMemB(c_ds, dest);
3382 }
3383
i_escape(void)3384 static INLINE2 void i_escape(void)
3385 {
3386 /* Opcodes 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde and 0xdf */
3387
3388 unsigned ModRM = GetMemInc(c_cs,ip);
3389 GetModRMRMB(ModRM);
3390 }
3391
i_loopne(void)3392 static INLINE2 void i_loopne(void)
3393 {
3394 /* Opcode 0xe0 */
3395
3396 register int disp = (int)((INT8)GetMemInc(c_cs,ip));
3397 register unsigned tmp = ReadWord(&wregs[CX])-1;
3398
3399 WriteWord(&wregs[CX],tmp);
3400
3401 if (!ZF && tmp) ip = (WORD)(ip+disp);
3402 }
3403
i_loope(void)3404 static INLINE2 void i_loope(void)
3405 {
3406 /* Opcode 0xe1 */
3407
3408 register int disp = (int)((INT8)GetMemInc(c_cs,ip));
3409 register unsigned tmp = ReadWord(&wregs[CX])-1;
3410
3411 WriteWord(&wregs[CX],tmp);
3412
3413 if (ZF && tmp) ip = (WORD)(ip+disp);
3414 }
3415
i_loop(void)3416 static INLINE2 void i_loop(void)
3417 {
3418 /* Opcode 0xe2 */
3419
3420 register int disp = (int)((INT8)GetMemInc(c_cs,ip));
3421 register unsigned tmp = ReadWord(&wregs[CX])-1;
3422
3423 WriteWord(&wregs[CX],tmp);
3424
3425 if (tmp) ip = (WORD)(ip+disp);
3426 }
3427
i_jcxz(void)3428 static INLINE2 void i_jcxz(void)
3429 {
3430 /* Opcode 0xe3 */
3431
3432 register int disp = (int)((INT8)GetMemInc(c_cs,ip));
3433
3434 if (wregs[CX] == 0)
3435 ip = (WORD)(ip+disp);
3436 }
3437
i_inal(void)3438 static INLINE2 void i_inal(void)
3439 {
3440 /* Opcode 0xe4 */
3441
3442 unsigned port = GetMemInc(c_cs,ip);
3443
3444 *bregs[AL] = read_port(port);
3445 }
3446
i_inax(void)3447 static INLINE2 void i_inax(void)
3448 {
3449 /* Opcode 0xe5 */
3450
3451 unsigned port = GetMemInc(c_cs,ip);
3452
3453 *bregs[AL] = read_port(port);
3454 *bregs[AH] = read_port(port+1);
3455 }
3456
i_outal(void)3457 static INLINE2 void i_outal(void)
3458 {
3459 /* Opcode 0xe6 */
3460
3461 unsigned port = GetMemInc(c_cs,ip);
3462
3463 write_port(port, *bregs[AL]);
3464 }
3465
i_outax(void)3466 static INLINE2 void i_outax(void)
3467 {
3468 /* Opcode 0xe7 */
3469
3470 unsigned port = GetMemInc(c_cs,ip);
3471
3472 write_port(port, *bregs[AL]);
3473 write_port(port+1, *bregs[AH]);
3474 }
3475
i_call_d16(void)3476 static INLINE2 void i_call_d16(void)
3477 {
3478 /* Opcode 0xe8 */
3479
3480 register unsigned tmp;
3481 register unsigned tmp1 = (WORD)(ReadWord(&wregs[SP])-2);
3482
3483 tmp = GetMemInc(c_cs,ip);
3484 tmp += GetMemInc(c_cs,ip) << 8;
3485
3486 PutMemW(c_stack,tmp1,ip);
3487 WriteWord(&wregs[SP],tmp1);
3488
3489 ip = (WORD)(ip+(INT16)tmp);
3490 }
3491
3492
i_jmp_d16(void)3493 static INLINE2 void i_jmp_d16(void)
3494 {
3495 /* Opcode 0xe9 */
3496
3497 register int tmp = GetMemInc(c_cs,ip);
3498 tmp += GetMemInc(c_cs,ip) << 8;
3499
3500 ip = (WORD)(ip+(INT16)tmp);
3501 }
3502
3503
i_jmp_far(void)3504 static INLINE2 void i_jmp_far(void)
3505 {
3506 /* Opcode 0xea */
3507
3508 register unsigned tmp,tmp1;
3509
3510 tmp = GetMemInc(c_cs,ip);
3511 tmp += GetMemInc(c_cs,ip) << 8;
3512
3513 tmp1 = GetMemInc(c_cs,ip);
3514 tmp1 += GetMemInc(c_cs,ip) << 8;
3515
3516 sregs[CS] = (WORD)tmp1;
3517 c_cs = SegToMemPtr(CS);
3518 ip = (WORD)tmp;
3519 }
3520
3521
i_jmp_d8(void)3522 static INLINE2 void i_jmp_d8(void)
3523 {
3524 /* Opcode 0xeb */
3525 register int tmp = (int)((INT8)GetMemInc(c_cs,ip));
3526 ip = (WORD)(ip+tmp);
3527 }
3528
3529
i_inaldx(void)3530 static INLINE2 void i_inaldx(void)
3531 {
3532 /* Opcode 0xec */
3533
3534 *bregs[AL] = read_port(ReadWord(&wregs[DX]));
3535 }
3536
i_inaxdx(void)3537 static INLINE2 void i_inaxdx(void)
3538 {
3539 /* Opcode 0xed */
3540
3541 unsigned port = ReadWord(&wregs[DX]);
3542
3543 *bregs[AL] = read_port(port);
3544 *bregs[AH] = read_port(port+1);
3545 }
3546
i_outdxal(void)3547 static INLINE2 void i_outdxal(void)
3548 {
3549 /* Opcode 0xee */
3550
3551 write_port(ReadWord(&wregs[DX]), *bregs[AL]);
3552 }
3553
i_outdxax(void)3554 static INLINE2 void i_outdxax(void)
3555 {
3556 /* Opcode 0xef */
3557 unsigned port = ReadWord(&wregs[DX]);
3558
3559 write_port(port, *bregs[AL]);
3560 write_port(port+1, *bregs[AH]);
3561 }
3562
i_lock(void)3563 static INLINE2 void i_lock(void)
3564 {
3565 /* Opcode 0xf0 */
3566 }
3567
i_gobios(void)3568 static INLINE2 void i_gobios(void)
3569 {
3570 /* Opcode 0xf1 */
3571
3572 void (*routine)(void);
3573 unsigned dest;
3574
3575 if (GetMemInc(c_cs,ip) != 0xf1)
3576 i_notdone();
3577
3578 dest = GetMemInc(c_cs,ip); /* Must be re-coded sometime.... */
3579 dest += (GetMemInc(c_cs,ip) << 8);
3580 dest += (GetMemInc(c_cs,ip) << 16);
3581 dest += (GetMemInc(c_cs,ip) << 24);
3582
3583 routine = (void (*)(void))dest;
3584
3585 routine();
3586 }
3587
3588
rep(int flagval)3589 static void rep(int flagval)
3590 {
3591 /* Handles rep- and repnz- prefixes. flagval is the value of ZF for the
3592 loop to continue for CMPS and SCAS instructions. */
3593
3594 unsigned next = GetMemInc(c_cs,ip);
3595 unsigned count = ReadWord(&wregs[CX]);
3596
3597 switch(next)
3598 {
3599 case 0x26: /* ES: */
3600 c_ss = c_ds = c_es;
3601 rep(flagval);
3602 c_ds = SegToMemPtr(DS);
3603 c_ss = SegToMemPtr(SS);
3604 break;
3605 case 0x2e: /* CS: */
3606 c_ss = c_ds = c_cs;
3607 rep(flagval);
3608 c_ds = SegToMemPtr(DS);
3609 c_ss = SegToMemPtr(SS);
3610 break;
3611 case 0x36: /* SS: */
3612 c_ds = c_ss;
3613 rep(flagval);
3614 c_ds = SegToMemPtr(DS);
3615 break;
3616 case 0x3e: /* DS: */
3617 c_ss = c_ds;
3618 rep(flagval);
3619 c_ss = SegToMemPtr(SS);
3620 break;
3621 case 0xa4: /* REP MOVSB */
3622 for (; count > 0; count--)
3623 i_movsb();
3624 WriteWord(&wregs[CX],count);
3625 break;
3626 case 0xa5: /* REP MOVSW */
3627 for (; count > 0; count--)
3628 i_movsw();
3629 WriteWord(&wregs[CX],count);
3630 break;
3631 case 0xa6: /* REP(N)E CMPSB */
3632 for (ZF = flagval; (ZF == flagval) && (count > 0); count--)
3633 i_cmpsb();
3634 WriteWord(&wregs[CX],count);
3635 break;
3636 case 0xa7: /* REP(N)E CMPSW */
3637 for (ZF = flagval; (ZF == flagval) && (count > 0); count--)
3638 i_cmpsw();
3639 WriteWord(&wregs[CX],count);
3640 break;
3641 case 0xaa: /* REP STOSB */
3642 for (; count > 0; count--)
3643 i_stosb();
3644 WriteWord(&wregs[CX],count);
3645 break;
3646 case 0xab: /* REP LODSW */
3647 for (; count > 0; count--)
3648 i_stosw();
3649 WriteWord(&wregs[CX],count);
3650 break;
3651 case 0xac: /* REP LODSB */
3652 for (; count > 0; count--)
3653 i_lodsb();
3654 WriteWord(&wregs[CX],count);
3655 break;
3656 case 0xad: /* REP LODSW */
3657 for (; count > 0; count--)
3658 i_lodsw();
3659 WriteWord(&wregs[CX],count);
3660 break;
3661 case 0xae: /* REP(N)E SCASB */
3662 for (ZF = flagval; (ZF == flagval) && (count > 0); count--)
3663 i_scasb();
3664 WriteWord(&wregs[CX],count);
3665 break;
3666 case 0xaf: /* REP(N)E SCASW */
3667 for (ZF = flagval; (ZF == flagval) && (count > 0); count--)
3668 i_scasw();
3669 WriteWord(&wregs[CX],count);
3670 break;
3671 default:
3672 instruction[next]();
3673 }
3674 }
3675
3676
i_repne(void)3677 static INLINE2 void i_repne(void)
3678 {
3679 /* Opcode 0xf2 */
3680
3681 rep(0);
3682 }
3683
3684
i_repe(void)3685 static INLINE2 void i_repe(void)
3686 {
3687 /* Opcode 0xf3 */
3688
3689 rep(1);
3690 }
3691
3692
i_cmc(void)3693 static INLINE2 void i_cmc(void)
3694 {
3695 /* Opcode 0xf5 */
3696
3697 CF = !CF;
3698 }
3699
3700
i_f6pre(void)3701 static INLINE2 void i_f6pre(void)
3702 {
3703 /* Opcode 0xf6 */
3704 unsigned ModRM = GetMemInc(c_cs,ip);
3705 register BYTE *byte = GetModRMRMB(ModRM);
3706 register unsigned tmp = (unsigned)*byte;
3707 register unsigned tmp2;
3708
3709
3710 switch (ModRM & 0x38)
3711 {
3712 case 0x00: /* TEST Eb, data8 */
3713 case 0x08: /* ??? */
3714 tmp &= GetMemInc(c_cs,ip);
3715
3716 CF = OF = AF = 0;
3717 SetZFB(tmp);
3718 SetSFB(tmp);
3719 SetPF(tmp);
3720 break;
3721
3722 case 0x10: /* NOT Eb */
3723 *byte = ~tmp;
3724 break;
3725
3726 case 0x18: /* NEG Eb */
3727 tmp2 = tmp;
3728 tmp = -tmp;
3729
3730 CF = (int)tmp2 > 0;
3731
3732 SetAF(tmp,0,tmp2);
3733 SetZFB(tmp);
3734 SetSFB(tmp);
3735 SetPF(tmp);
3736
3737 *byte = tmp;
3738 break;
3739 case 0x20: /* MUL AL, Eb */
3740 {
3741 UINT16 result;
3742 tmp2 = *bregs[AL];
3743
3744 SetSFB(tmp2);
3745 SetPF(tmp2);
3746
3747 result = (UINT16)tmp2*tmp;
3748 WriteWord(&wregs[AX],(WORD)result);
3749
3750 SetZFW(wregs[AX]);
3751 CF = OF = (*bregs[AH] != 0);
3752 }
3753 break;
3754 case 0x28: /* IMUL AL, Eb */
3755 {
3756 INT16 result;
3757
3758 tmp2 = (unsigned)*bregs[AL];
3759
3760 SetSFB(tmp2);
3761 SetPF(tmp2);
3762
3763 result = (INT16)((INT8)tmp2)*(INT16)((INT8)tmp);
3764 WriteWord(&wregs[AX],(WORD)result);
3765
3766 SetZFW(wregs[AX]);
3767
3768 OF = (result >> 7 != 0) && (result >> 7 != -1);
3769 CF = !(!OF);
3770 }
3771 break;
3772 case 0x30: /* DIV AL, Ew */
3773 {
3774 UINT16 result;
3775
3776 result = ReadWord(&wregs[AX]);
3777
3778 if (tmp)
3779 {
3780 if ((result / tmp) > 0xff)
3781 {
3782 interrupt(0);
3783 break;
3784 }
3785 else
3786 {
3787 *bregs[AH] = result % tmp;
3788 *bregs[AL] = result / tmp;
3789 }
3790
3791 }
3792 else
3793 {
3794 interrupt(0);
3795 break;
3796 }
3797 }
3798 break;
3799 case 0x38: /* IDIV AL, Ew */
3800 {
3801 INT16 result;
3802
3803 result = ReadWord(&wregs[AX]);
3804
3805 if (tmp)
3806 {
3807 tmp2 = result % (INT16)((INT8)tmp);
3808
3809 if ((result /= (INT16)((INT8)tmp)) > 0xff)
3810 {
3811 interrupt(0);
3812 break;
3813 }
3814 else
3815 {
3816 *bregs[AL] = result;
3817 *bregs[AH] = tmp2;
3818 }
3819 }
3820 else
3821 {
3822 interrupt(0);
3823 break;
3824 }
3825 }
3826 break;
3827 }
3828 }
3829
3830
i_f7pre(void)3831 static INLINE2 void i_f7pre(void)
3832 {
3833 /* Opcode 0xf7 */
3834 unsigned ModRM = GetMemInc(c_cs,ip);
3835 WORD *wrd = GetModRMRMW(ModRM);
3836 register unsigned tmp = ReadWord(wrd);
3837 register unsigned tmp2;
3838
3839
3840 switch (ModRM & 0x38)
3841 {
3842 case 0x00: /* TEST Ew, data16 */
3843 case 0x08: /* ??? */
3844 tmp2 = GetMemInc(c_cs,ip);
3845 tmp2 += GetMemInc(c_cs,ip) << 8;
3846
3847 tmp &= tmp2;
3848
3849 CF = OF = AF = 0;
3850 SetZFW(tmp);
3851 SetSFW(tmp);
3852 SetPF(tmp);
3853 break;
3854
3855 case 0x10: /* NOT Ew */
3856 tmp = ~tmp;
3857 WriteWord(wrd,tmp);
3858 break;
3859
3860 case 0x18: /* NEG Ew */
3861 tmp2 = tmp;
3862 tmp = -tmp;
3863
3864 CF = (int)tmp2 > 0;
3865
3866 SetAF(tmp,0,tmp2);
3867 SetZFW(tmp);
3868 SetSFW(tmp);
3869 SetPF(tmp);
3870
3871 WriteWord(wrd,tmp);
3872 break;
3873 case 0x20: /* MUL AX, Ew */
3874 {
3875 UINT32 result;
3876 tmp2 = ReadWord(&wregs[AX]);
3877
3878 SetSFW(tmp2);
3879 SetPF(tmp2);
3880
3881 result = (UINT32)tmp2*tmp;
3882 WriteWord(&wregs[AX],(WORD)result);
3883 result >>= 16;
3884 WriteWord(&wregs[DX],result);
3885
3886 SetZFW(wregs[AX] | wregs[DX]);
3887 CF = OF = (wregs[DX] != ChangeE(0));
3888 }
3889 break;
3890
3891 case 0x28: /* IMUL AX, Ew */
3892 {
3893 INT32 result;
3894
3895 tmp2 = ReadWord(&wregs[AX]);
3896
3897 SetSFW(tmp2);
3898 SetPF(tmp2);
3899
3900 result = (INT32)((INT16)tmp2)*(INT32)((INT16)tmp);
3901 OF = (result >> 15 != 0) && (result >> 15 != -1);
3902
3903 WriteWord(&wregs[AX],(WORD)result);
3904 result = (WORD)(result >> 16);
3905 WriteWord(&wregs[DX],result);
3906
3907 SetZFW(wregs[AX] | wregs[DX]);
3908
3909 CF = !(!OF);
3910 }
3911 break;
3912 case 0x30: /* DIV AX, Ew */
3913 {
3914 UINT32 result;
3915
3916 result = (ReadWord(&wregs[DX]) << 16) + ReadWord(&wregs[AX]);
3917
3918 if (tmp)
3919 {
3920 tmp2 = result % tmp;
3921 if ((result / tmp) > 0xffff)
3922 {
3923 interrupt(0);
3924 break;
3925 }
3926 else
3927 {
3928 WriteWord(&wregs[DX],tmp2);
3929 result /= tmp;
3930 WriteWord(&wregs[AX],result);
3931 }
3932 }
3933 else
3934 {
3935 interrupt(0);
3936 break;
3937 }
3938 }
3939 break;
3940 case 0x38: /* IDIV AX, Ew */
3941 {
3942 INT32 result;
3943
3944 result = (ReadWord(&wregs[DX]) << 16) + ReadWord(&wregs[AX]);
3945
3946 if (tmp)
3947 {
3948 tmp2 = result % (INT32)((INT16)tmp);
3949
3950 if ((result /= (INT32)((INT16)tmp)) > 0xffff)
3951 {
3952 interrupt(0);
3953 break;
3954 }
3955 else
3956 {
3957 WriteWord(&wregs[AX],result);
3958 WriteWord(&wregs[DX],tmp2);
3959 }
3960 }
3961 else
3962 {
3963 interrupt(0);
3964 break;
3965 }
3966 }
3967 break;
3968 }
3969 }
3970
3971
i_clc(void)3972 static INLINE2 void i_clc(void)
3973 {
3974 /* Opcode 0xf8 */
3975
3976 CF = 0;
3977 }
3978
3979
i_stc(void)3980 static INLINE2 void i_stc(void)
3981 {
3982 /* Opcode 0xf9 */
3983
3984 CF = 1;
3985 }
3986
3987
i_cli(void)3988 static INLINE2 void i_cli(void)
3989 {
3990 /* Opcode 0xfa */
3991
3992 IF = 0;
3993 }
3994
3995
i_sti(void)3996 static INLINE2 void i_sti(void)
3997 {
3998 /* Opcode 0xfb */
3999
4000 IF = 1;
4001
4002 if (int_blocked)
4003 {
4004 int_pending = int_blocked;
4005 int_blocked = 0;
4006 D2(printf("Unblocking interrupt\n"););
4007 }
4008 }
4009
4010
i_cld(void)4011 static INLINE2 void i_cld(void)
4012 {
4013 /* Opcode 0xfc */
4014
4015 DF = 0;
4016 }
4017
4018
i_std(void)4019 static INLINE2 void i_std(void)
4020 {
4021 /* Opcode 0xfd */
4022
4023 DF = 1;
4024 }
4025
4026
i_fepre(void)4027 static INLINE2 void i_fepre(void)
4028 {
4029 /* Opcode 0xfe */
4030
4031 unsigned ModRM = GetMemInc(c_cs,ip);
4032 register BYTE *dest = GetModRMRMB(ModRM);
4033 register unsigned tmp = *dest;
4034 register unsigned tmp1;
4035
4036 if ((ModRM & 0x38) == 0)
4037 {
4038 tmp1 = tmp+1;
4039 SetOFB_Add(tmp1,tmp,1);
4040 }
4041 else
4042 {
4043 tmp1 = tmp-1;
4044 SetOFB_Sub(tmp1,1,tmp);
4045 }
4046
4047 SetAF(tmp1,tmp,1);
4048 SetZFB(tmp1);
4049 SetSFB(tmp1);
4050 SetPF(tmp1);
4051
4052 *dest = (BYTE)tmp1;
4053 }
4054
4055
i_ffpre(void)4056 static INLINE2 void i_ffpre(void)
4057 {
4058 /* Opcode 0xff */
4059
4060 unsigned ModRM = GetMemInc(c_cs,ip);
4061 register WORD *dest = GetModRMRMW(ModRM);
4062 register unsigned tmp;
4063 register unsigned tmp1;
4064
4065 switch(ModRM & 0x38)
4066 {
4067 case 0x00: /* INC ew */
4068 tmp = ReadWord(dest);
4069 tmp1 = tmp+1;
4070
4071 SetOFW_Add(tmp1,tmp,1);
4072 SetAF(tmp1,tmp,1);
4073 SetZFW(tmp1);
4074 SetSFW(tmp1);
4075 SetPF(tmp1);
4076
4077 WriteWord(dest,(WORD)tmp1);
4078 break;
4079
4080 case 0x08: /* DEC ew */
4081 tmp = ReadWord(dest);
4082 tmp1 = tmp-1;
4083
4084 SetOFW_Sub(tmp1,1,tmp);
4085 SetAF(tmp1,tmp,1);
4086 SetZFW(tmp1);
4087 SetSFW(tmp1);
4088 SetPF(tmp1);
4089
4090 WriteWord(dest,(WORD)tmp1);
4091 break;
4092
4093 case 0x10: /* CALL ew */
4094 tmp = ReadWord(dest);
4095 tmp1 = (WORD)(ReadWord(&wregs[SP])-2);
4096
4097 PutMemW(c_stack,tmp1,ip);
4098 WriteWord(&wregs[SP],tmp1);
4099
4100 ip = (WORD)tmp;
4101 break;
4102
4103 case 0x18: /* CALL FAR ea */
4104 tmp1 = (WORD)(ReadWord(&wregs[SP])-2);
4105
4106 PutMemW(c_stack,tmp1,sregs[CS]);
4107 tmp1 = (WORD)(tmp1-2);
4108 PutMemW(c_stack,tmp1,ip);
4109 WriteWord(&wregs[SP],tmp1);
4110
4111 ip = ReadWord(dest);
4112 dest++;
4113 sregs[CS] = ReadWord(dest);
4114 c_cs = SegToMemPtr(CS);
4115 break;
4116
4117 case 0x20: /* JMP ea */
4118 ip = ReadWord(dest);
4119 break;
4120
4121 case 0x28: /* JMP FAR ea */
4122 ip = ReadWord(dest);
4123 dest++;
4124 sregs[CS] = ReadWord(dest);
4125 c_cs = SegToMemPtr(CS);
4126 break;
4127
4128 case 0x30: /* PUSH ea */
4129 tmp1 = (WORD)(ReadWord(&wregs[SP])-2);
4130 tmp = ReadWord(dest);
4131
4132 PutMemW(c_stack,tmp1,tmp);
4133 WriteWord(&wregs[SP],tmp1);
4134 break;
4135 }
4136 }
4137
4138
i_notdone(void)4139 static INLINE2 void i_notdone(void)
4140 {
4141 fprintf(stderr,"Error: Unimplemented opcode %02X at cs:ip = %04X:%04X\n",
4142 c_cs[ip-1],sregs[CS],ip-1);
4143 exit(1);
4144 }
4145
4146
trap(void)4147 void trap(void)
4148 {
4149 instruction[GetMemInc(c_cs,ip)]();
4150 interrupt(1);
4151 }
4152
4153
execute(void)4154 void execute(void)
4155 {
4156 c_cs = SegToMemPtr(CS);
4157 c_ds = SegToMemPtr(DS);
4158 c_es = SegToMemPtr(ES);
4159 c_stack = c_ss = SegToMemPtr(SS);
4160
4161 for(;;)
4162 {
4163 if (int_pending)
4164 external_int();
4165
4166 #ifdef DEBUGGER
4167 call_debugger(D_TRACE);
4168 #endif
4169
4170 #if defined(BIGCASE) && !defined(RS6000)
4171 /* Some compilers cannot handle large case statements */
4172 switch(GetMemInc(c_cs,ip))
4173 {
4174 case 0x00: i_add_br8(); break;
4175 case 0x01: i_add_wr16(); break;
4176 case 0x02: i_add_r8b(); break;
4177 case 0x03: i_add_r16w(); break;
4178 case 0x04: i_add_ald8(); break;
4179 case 0x05: i_add_axd16(); break;
4180 case 0x06: i_push_es(); break;
4181 case 0x07: i_pop_es(); break;
4182 case 0x08: i_or_br8(); break;
4183 case 0x09: i_or_wr16(); break;
4184 case 0x0a: i_or_r8b(); break;
4185 case 0x0b: i_or_r16w(); break;
4186 case 0x0c: i_or_ald8(); break;
4187 case 0x0d: i_or_axd16(); break;
4188 case 0x0e: i_push_cs(); break;
4189 case 0x0f: i_notdone(); break;
4190 case 0x10: i_adc_br8(); break;
4191 case 0x11: i_adc_wr16(); break;
4192 case 0x12: i_adc_r8b(); break;
4193 case 0x13: i_adc_r16w(); break;
4194 case 0x14: i_adc_ald8(); break;
4195 case 0x15: i_adc_axd16(); break;
4196 case 0x16: i_push_ss(); break;
4197 case 0x17: i_pop_ss(); break;
4198 case 0x18: i_sbb_br8(); break;
4199 case 0x19: i_sbb_wr16(); break;
4200 case 0x1a: i_sbb_r8b(); break;
4201 case 0x1b: i_sbb_r16w(); break;
4202 case 0x1c: i_sbb_ald8(); break;
4203 case 0x1d: i_sbb_axd16(); break;
4204 case 0x1e: i_push_ds(); break;
4205 case 0x1f: i_pop_ds(); break;
4206 case 0x20: i_and_br8(); break;
4207 case 0x21: i_and_wr16(); break;
4208 case 0x22: i_and_r8b(); break;
4209 case 0x23: i_and_r16w(); break;
4210 case 0x24: i_and_ald8(); break;
4211 case 0x25: i_and_axd16(); break;
4212 case 0x26: i_es(); break;
4213 case 0x27: i_daa(); break;
4214 case 0x28: i_sub_br8(); break;
4215 case 0x29: i_sub_wr16(); break;
4216 case 0x2a: i_sub_r8b(); break;
4217 case 0x2b: i_sub_r16w(); break;
4218 case 0x2c: i_sub_ald8(); break;
4219 case 0x2d: i_sub_axd16(); break;
4220 case 0x2e: i_cs(); break;
4221 case 0x2f: i_notdone(); break;
4222 case 0x30: i_xor_br8(); break;
4223 case 0x31: i_xor_wr16(); break;
4224 case 0x32: i_xor_r8b(); break;
4225 case 0x33: i_xor_r16w(); break;
4226 case 0x34: i_xor_ald8(); break;
4227 case 0x35: i_xor_axd16(); break;
4228 case 0x36: i_ss(); break;
4229 case 0x37: i_notdone(); break;
4230 case 0x38: i_cmp_br8(); break;
4231 case 0x39: i_cmp_wr16(); break;
4232 case 0x3a: i_cmp_r8b(); break;
4233 case 0x3b: i_cmp_r16w(); break;
4234 case 0x3c: i_cmp_ald8(); break;
4235 case 0x3d: i_cmp_axd16(); break;
4236 case 0x3e: i_ds(); break;
4237 case 0x3f: i_notdone(); break;
4238 case 0x40: i_inc_ax(); break;
4239 case 0x41: i_inc_cx(); break;
4240 case 0x42: i_inc_dx(); break;
4241 case 0x43: i_inc_bx(); break;
4242 case 0x44: i_inc_sp(); break;
4243 case 0x45: i_inc_bp(); break;
4244 case 0x46: i_inc_si(); break;
4245 case 0x47: i_inc_di(); break;
4246 case 0x48: i_dec_ax(); break;
4247 case 0x49: i_dec_cx(); break;
4248 case 0x4a: i_dec_dx(); break;
4249 case 0x4b: i_dec_bx(); break;
4250 case 0x4c: i_dec_sp(); break;
4251 case 0x4d: i_dec_bp(); break;
4252 case 0x4e: i_dec_si(); break;
4253 case 0x4f: i_dec_di(); break;
4254 case 0x50: i_push_ax(); break;
4255 case 0x51: i_push_cx(); break;
4256 case 0x52: i_push_dx(); break;
4257 case 0x53: i_push_bx(); break;
4258 case 0x54: i_push_sp(); break;
4259 case 0x55: i_push_bp(); break;
4260 case 0x56: i_push_si(); break;
4261 case 0x57: i_push_di(); break;
4262 case 0x58: i_pop_ax(); break;
4263 case 0x59: i_pop_cx(); break;
4264 case 0x5a: i_pop_dx(); break;
4265 case 0x5b: i_pop_bx(); break;
4266 case 0x5c: i_pop_sp(); break;
4267 case 0x5d: i_pop_bp(); break;
4268 case 0x5e: i_pop_si(); break;
4269 case 0x5f: i_pop_di(); break;
4270 case 0x60: i_notdone(); break;
4271 case 0x61: i_notdone(); break;
4272 case 0x62: i_notdone(); break;
4273 case 0x63: i_notdone(); break;
4274 case 0x64: i_notdone(); break;
4275 case 0x65: i_notdone(); break;
4276 case 0x66: i_notdone(); break;
4277 case 0x67: i_notdone(); break;
4278 case 0x68: i_notdone(); break;
4279 case 0x69: i_notdone(); break;
4280 case 0x6a: i_notdone(); break;
4281 case 0x6b: i_notdone(); break;
4282 case 0x6c: i_notdone(); break;
4283 case 0x6d: i_notdone(); break;
4284 case 0x6e: i_notdone(); break;
4285 case 0x6f: i_notdone(); break;
4286 case 0x70: i_jo(); break;
4287 case 0x71: i_jno(); break;
4288 case 0x72: i_jb(); break;
4289 case 0x73: i_jnb(); break;
4290 case 0x74: i_jz(); break;
4291 case 0x75: i_jnz(); break;
4292 case 0x76: i_jbe(); break;
4293 case 0x77: i_jnbe(); break;
4294 case 0x78: i_js(); break;
4295 case 0x79: i_jns(); break;
4296 case 0x7a: i_jp(); break;
4297 case 0x7b: i_jnp(); break;
4298 case 0x7c: i_jl(); break;
4299 case 0x7d: i_jnl(); break;
4300 case 0x7e: i_jle(); break;
4301 case 0x7f: i_jnle(); break;
4302 case 0x80: i_80pre(); break;
4303 case 0x81: i_81pre(); break;
4304 case 0x82: i_notdone(); break;
4305 case 0x83: i_83pre(); break;
4306 case 0x84: i_test_br8(); break;
4307 case 0x85: i_test_wr16(); break;
4308 case 0x86: i_xchg_br8(); break;
4309 case 0x87: i_xchg_wr16(); break;
4310 case 0x88: i_mov_br8(); break;
4311 case 0x89: i_mov_wr16(); break;
4312 case 0x8a: i_mov_r8b(); break;
4313 case 0x8b: i_mov_r16w(); break;
4314 case 0x8c: i_mov_wsreg(); break;
4315 case 0x8d: i_lea(); break;
4316 case 0x8e: i_mov_sregw(); break;
4317 case 0x8f: i_popw(); break;
4318 case 0x90: i_nop(); break;
4319 case 0x91: i_xchg_axcx(); break;
4320 case 0x92: i_xchg_axdx(); break;
4321 case 0x93: i_xchg_axbx(); break;
4322 case 0x94: i_xchg_axsp(); break;
4323 case 0x95: i_xchg_axbp(); break;
4324 case 0x96: i_xchg_axsi(); break;
4325 case 0x97: i_xchg_axdi(); break;
4326 case 0x98: i_cbw(); break;
4327 case 0x99: i_cwd(); break;
4328 case 0x9a: i_call_far(); break;
4329 case 0x9b: i_wait(); break;
4330 case 0x9c: i_pushf(); break;
4331 case 0x9d: i_popf(); break;
4332 case 0x9e: i_sahf(); break;
4333 case 0x9f: i_lahf(); break;
4334 case 0xa0: i_mov_aldisp(); break;
4335 case 0xa1: i_mov_axdisp(); break;
4336 case 0xa2: i_mov_dispal(); break;
4337 case 0xa3: i_mov_dispax(); break;
4338 case 0xa4: i_movsb(); break;
4339 case 0xa5: i_movsw(); break;
4340 case 0xa6: i_cmpsb(); break;
4341 case 0xa7: i_cmpsw(); break;
4342 case 0xa8: i_test_ald8(); break;
4343 case 0xa9: i_test_axd16(); break;
4344 case 0xaa: i_stosb(); break;
4345 case 0xab: i_stosw(); break;
4346 case 0xac: i_lodsb(); break;
4347 case 0xad: i_lodsw(); break;
4348 case 0xae: i_scasb(); break;
4349 case 0xaf: i_scasw(); break;
4350 case 0xb0: i_mov_ald8(); break;
4351 case 0xb1: i_mov_cld8(); break;
4352 case 0xb2: i_mov_dld8(); break;
4353 case 0xb3: i_mov_bld8(); break;
4354 case 0xb4: i_mov_ahd8(); break;
4355 case 0xb5: i_mov_chd8(); break;
4356 case 0xb6: i_mov_dhd8(); break;
4357 case 0xb7: i_mov_bhd8(); break;
4358 case 0xb8: i_mov_axd16(); break;
4359 case 0xb9: i_mov_cxd16(); break;
4360 case 0xba: i_mov_dxd16(); break;
4361 case 0xbb: i_mov_bxd16(); break;
4362 case 0xbc: i_mov_spd16(); break;
4363 case 0xbd: i_mov_bpd16(); break;
4364 case 0xbe: i_mov_sid16(); break;
4365 case 0xbf: i_mov_did16(); break;
4366 case 0xc0: i_notdone(); break;
4367 case 0xc1: i_notdone(); break;
4368 case 0xc2: i_ret_d16(); break;
4369 case 0xc3: i_ret(); break;
4370 case 0xc4: i_les_dw(); break;
4371 case 0xc5: i_lds_dw(); break;
4372 case 0xc6: i_mov_bd8(); break;
4373 case 0xc7: i_mov_wd16(); break;
4374 case 0xc8: i_notdone(); break;
4375 case 0xc9: i_notdone(); break;
4376 case 0xca: i_retf_d16(); break;
4377 case 0xcb: i_retf(); break;
4378 case 0xcc: i_int3(); break;
4379 case 0xcd: i_int(); break;
4380 case 0xce: i_into(); break;
4381 case 0xcf: i_iret(); break;
4382 case 0xd0: i_d0pre(); break;
4383 case 0xd1: i_d1pre(); break;
4384 case 0xd2: i_d2pre(); break;
4385 case 0xd3: i_d3pre(); break;
4386 case 0xd4: i_aam(); break;
4387 case 0xd5: i_aad(); break;
4388 case 0xd6: i_notdone(); break;
4389 case 0xd7: i_xlat(); break;
4390 case 0xd8: i_escape(); break;
4391 case 0xd9: i_escape(); break;
4392 case 0xda: i_escape(); break;
4393 case 0xdb: i_escape(); break;
4394 case 0xdc: i_escape(); break;
4395 case 0xdd: i_escape(); break;
4396 case 0xde: i_escape(); break;
4397 case 0xdf: i_escape(); break;
4398 case 0xe0: i_loopne(); break;
4399 case 0xe1: i_loope(); break;
4400 case 0xe2: i_loop(); break;
4401 case 0xe3: i_jcxz(); break;
4402 case 0xe4: i_inal(); break;
4403 case 0xe5: i_inax(); break;
4404 case 0xe6: i_outal(); break;
4405 case 0xe7: i_outax(); break;
4406 case 0xe8: i_call_d16(); break;
4407 case 0xe9: i_jmp_d16(); break;
4408 case 0xea: i_jmp_far(); break;
4409 case 0xeb: i_jmp_d8(); break;
4410 case 0xec: i_inaldx(); break;
4411 case 0xed: i_inaxdx(); break;
4412 case 0xee: i_outdxal(); break;
4413 case 0xef: i_outdxax(); break;
4414 case 0xf0: i_lock(); break;
4415 case 0xf1: i_gobios(); break;
4416 case 0xf2: i_repne(); break;
4417 case 0xf3: i_repe(); break;
4418 case 0xf4: i_notdone(); break;
4419 case 0xf5: i_cmc(); break;
4420 case 0xf6: i_f6pre(); break;
4421 case 0xf7: i_f7pre(); break;
4422 case 0xf8: i_clc(); break;
4423 case 0xf9: i_stc(); break;
4424 case 0xfa: i_cli(); break;
4425 case 0xfb: i_sti(); break;
4426 case 0xfc: i_cld(); break;
4427 case 0xfd: i_std(); break;
4428 case 0xfe: i_fepre(); break;
4429 case 0xff: i_ffpre(); break;
4430 };
4431 #else
4432 instruction[GetMemInc(c_cs,ip)]();
4433 #endif
4434 }
4435 }
4436
4437