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