OSDN Git Service

[VM] ZAP EVIL __assume() MACRO (-_-#
[csp-qt/common_source_project-fm7.git] / source / src / vm / i86.cpp
1 /*\r
2         Skelton for retropc emulator\r
3 \r
4         Origin : MAME 0.142\r
5         Author : Takeda.Toshiya\r
6         Date  : 2011.04.23-\r
7 \r
8         [ i86/v30 ]\r
9 */\r
10 \r
11 // disable warnings C4146 for microsoft visual c++ 2005\r
12 #if defined(_MSC_VER) && (_MSC_VER >= 1400)\r
13 #pragma warning( disable : 4146 )\r
14 #endif\r
15 \r
16 #include "i86.h"\r
17 #ifdef USE_DEBUGGER\r
18 #include "debugger.h"\r
19 #endif\r
20 #include "../fileio.h"\r
21 \r
22 #define DIVIDE_FAULT                    0\r
23 #define NMI_INT_VECTOR                  2\r
24 #define OVERFLOW_TRAP                   4\r
25 #define BOUNDS_CHECK_FAULT              5\r
26 #define ILLEGAL_INSTRUCTION             6\r
27 #define GENERAL_PROTECTION_FAULT        13\r
28 \r
29 #define INT_REQ_BIT                     1\r
30 #define NMI_REQ_BIT                     2\r
31 \r
32 typedef enum { ES, CS, SS, DS } SREGS;\r
33 typedef enum { AX, CX, DX, BX, SP, BP, SI, DI } WREGS;\r
34 \r
35 typedef enum {\r
36 #ifdef _BIG_ENDIAN\r
37          AH,  AL,  CH,  CL,  DH,  DL,  BH,  BL,\r
38         SPH, SPL, BPH, BPL, SIH, SIL, DIH, DIL,\r
39 #else\r
40          AL,  AH,  CL,  CH,  DL,  DH,  BL,  BH,\r
41         SPL, SPH, BPL, BPH, SIL, SIH, DIL, DIH,\r
42 #endif\r
43 } BREGS;\r
44 \r
45 static struct {\r
46         struct {\r
47                 WREGS w[256];\r
48                 BREGS b[256];\r
49         } reg;\r
50         struct {\r
51                 WREGS w[256];\r
52                 BREGS b[256];\r
53         } RM;\r
54 } Mod_RM;\r
55 \r
56 static const uint8 parity_table[256] = {\r
57         1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,\r
58         0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,\r
59         0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,\r
60         1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,\r
61         0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,\r
62         1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,\r
63         1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,\r
64         0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,\r
65         0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,\r
66         1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,\r
67         1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,\r
68         0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,\r
69         1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,\r
70         0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,\r
71         0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,\r
72         1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1\r
73 };\r
74 \r
75 /************************************************************************/\r
76 \r
77 struct i80x86_timing {\r
78         uint8   exception, iret;                                /* exception, IRET */\r
79         uint8   int3, int_imm, into_nt, into_t;                 /* INTs */\r
80         uint8   override;                                       /* segment overrides */\r
81         uint8   flag_ops, lahf, sahf;                           /* flag operations */\r
82         uint8   aaa, aas, aam, aad;                             /* arithmetic adjusts */\r
83         uint8   daa, das;                                       /* decimal adjusts */\r
84         uint8   cbw, cwd;                                       /* sign extension */\r
85         uint8   hlt, load_ptr, lea, nop, wait, xlat;            /* misc */\r
86 \r
87         uint8   jmp_short, jmp_near, jmp_far;                   /* direct JMPs */\r
88         uint8   jmp_r16, jmp_m16, jmp_m32;                      /* indirect JMPs */\r
89         uint8   call_near, call_far;                            /* direct CALLs */\r
90         uint8   call_r16, call_m16, call_m32;                   /* indirect CALLs */\r
91         uint8   ret_near, ret_far, ret_near_imm, ret_far_imm;   /* returns */\r
92         uint8   jcc_nt, jcc_t, jcxz_nt, jcxz_t;                 /* conditional JMPs */\r
93         uint8   loop_nt, loop_t, loope_nt, loope_t;             /* loops */\r
94 \r
95         uint8   in_imm8, in_imm16, in_dx8, in_dx16;             /* port reads */\r
96         uint8   out_imm8, out_imm16, out_dx8, out_dx16;         /* port writes */\r
97 \r
98         uint8   mov_rr8, mov_rm8, mov_mr8;                      /* move, 8-bit */\r
99         uint8   mov_ri8, mov_mi8;                               /* move, 8-bit immediate */\r
100         uint8   mov_rr16, mov_rm16, mov_mr16;                   /* move, 16-bit */\r
101         uint8   mov_ri16, mov_mi16;                             /* move, 16-bit immediate */\r
102         uint8   mov_am8, mov_am16, mov_ma8, mov_ma16;           /* move, AL/AX memory */\r
103         uint8   mov_sr, mov_sm, mov_rs, mov_ms;                 /* move, segment registers */\r
104         uint8   xchg_rr8, xchg_rm8;                             /* exchange, 8-bit */\r
105         uint8   xchg_rr16, xchg_rm16, xchg_ar16;                /* exchange, 16-bit */\r
106 \r
107         uint8   push_r16, push_m16, push_seg, pushf;            /* pushes */\r
108         uint8   pop_r16, pop_m16, pop_seg, popf;                /* pops */\r
109 \r
110         uint8   alu_rr8, alu_rm8, alu_mr8;                      /* ALU ops, 8-bit */\r
111         uint8   alu_ri8, alu_mi8, alu_mi8_ro;                   /* ALU ops, 8-bit immediate */\r
112         uint8   alu_rr16, alu_rm16, alu_mr16;                   /* ALU ops, 16-bit */\r
113         uint8   alu_ri16, alu_mi16, alu_mi16_ro;                /* ALU ops, 16-bit immediate */\r
114         uint8   alu_r16i8, alu_m16i8, alu_m16i8_ro;             /* ALU ops, 16-bit w/8-bit immediate */\r
115         uint8   mul_r8, mul_r16, mul_m8, mul_m16;               /* MUL */\r
116         uint8   imul_r8, imul_r16, imul_m8, imul_m16;           /* IMUL */\r
117         uint8   div_r8, div_r16, div_m8, div_m16;               /* DIV */\r
118         uint8   idiv_r8, idiv_r16, idiv_m8, idiv_m16;           /* IDIV */\r
119         uint8   incdec_r8, incdec_r16, incdec_m8, incdec_m16;   /* INC/DEC */\r
120         uint8   negnot_r8, negnot_r16, negnot_m8, negnot_m16;   /* NEG/NOT */\r
121 \r
122         uint8   rot_reg_1, rot_reg_base, rot_reg_bit;           /* reg shift/rotate */\r
123         uint8   rot_m8_1, rot_m8_base, rot_m8_bit;              /* m8 shift/rotate */\r
124         uint8   rot_m16_1, rot_m16_base, rot_m16_bit;           /* m16 shift/rotate */\r
125 \r
126         uint8   cmps8, rep_cmps8_base, rep_cmps8_count;         /* CMPS 8-bit */\r
127         uint8   cmps16, rep_cmps16_base, rep_cmps16_count;      /* CMPS 16-bit */\r
128         uint8   scas8, rep_scas8_base, rep_scas8_count;         /* SCAS 8-bit */\r
129         uint8   scas16, rep_scas16_base, rep_scas16_count;      /* SCAS 16-bit */\r
130         uint8   lods8, rep_lods8_base, rep_lods8_count;         /* LODS 8-bit */\r
131         uint8   lods16, rep_lods16_base, rep_lods16_count;      /* LODS 16-bit */\r
132         uint8   stos8, rep_stos8_base, rep_stos8_count;         /* STOS 8-bit */\r
133         uint8   stos16, rep_stos16_base, rep_stos16_count;      /* STOS 16-bit */\r
134         uint8   movs8, rep_movs8_base, rep_movs8_count;         /* MOVS 8-bit */\r
135         uint8   movs16, rep_movs16_base, rep_movs16_count;      /* MOVS 16-bit */\r
136 \r
137         uint8   ins8, rep_ins8_base, rep_ins8_count;            /* (80186) INS 8-bit */\r
138         uint8   ins16, rep_ins16_base, rep_ins16_count;         /* (80186) INS 16-bit */\r
139         uint8   outs8, rep_outs8_base, rep_outs8_count;         /* (80186) OUTS 8-bit */\r
140         uint8   outs16, rep_outs16_base, rep_outs16_count;      /* (80186) OUTS 16-bit */\r
141         uint8   push_imm, pusha, popa;                          /* (80186) PUSH immediate, PUSHA/POPA */\r
142         uint8   imul_rri8, imul_rmi8;                           /* (80186) IMUL immediate 8-bit */\r
143         uint8   imul_rri16, imul_rmi16;                         /* (80186) IMUL immediate 16-bit */\r
144         uint8   enter0, enter1, enter_base, enter_count, leave; /* (80186) ENTER/LEAVE */\r
145         uint8   bound;                                          /* (80186) BOUND */\r
146 };\r
147 \r
148 #if defined(HAS_I86)\r
149 /* these come from the 8088 timings in OPCODE.LST, but with the\r
150    penalty for 16-bit memory accesses removed wherever possible */\r
151 static const struct i80x86_timing timing = {\r
152         51, 32,                 /* exception, IRET */\r
153         2, 0, 4, 2,             /* INTs */\r
154         2,                      /* segment overrides */\r
155         2, 4, 4,                /* flag operations */\r
156         4, 4, 83, 60,           /* arithmetic adjusts */\r
157         4, 4,                   /* decimal adjusts */\r
158         2, 5,                   /* sign extension */\r
159         2, 24, 2, 2, 3, 11,     /* misc */\r
160 \r
161         15, 15, 15,             /* direct JMPs */\r
162         11, 18, 24,             /* indirect JMPs */\r
163         19, 28,                 /* direct CALLs */\r
164         16, 21, 37,             /* indirect CALLs */\r
165         20, 32, 24, 31,         /* returns */\r
166         4, 16, 6, 18,           /* conditional JMPs */\r
167         5, 17, 6, 18,           /* loops */\r
168 \r
169         10, 14, 8, 12,          /* port reads */\r
170         10, 14, 8, 12,          /* port writes */\r
171 \r
172         2, 8, 9,                /* move, 8-bit */\r
173         4, 10,                  /* move, 8-bit immediate */\r
174         2, 8, 9,                /* move, 16-bit */\r
175         4, 10,                  /* move, 16-bit immediate */\r
176         10, 10, 10, 10,         /* move, AL/AX memory */\r
177         2, 8, 2, 9,             /* move, segment registers */\r
178         4, 17,                  /* exchange, 8-bit */\r
179         4, 17, 3,               /* exchange, 16-bit */\r
180 \r
181         15, 24, 14, 14,         /* pushes */\r
182         12, 25, 12, 12,         /* pops */\r
183 \r
184         3, 9, 16,               /* ALU ops, 8-bit */\r
185         4, 17, 10,              /* ALU ops, 8-bit immediate */\r
186         3, 9, 16,               /* ALU ops, 16-bit */\r
187         4, 17, 10,              /* ALU ops, 16-bit immediate */\r
188         4, 17, 10,              /* ALU ops, 16-bit w/8-bit immediate */\r
189         70, 118, 76, 128,       /* MUL */\r
190         80, 128, 86, 138,       /* IMUL */\r
191         80, 144, 86, 154,       /* DIV */\r
192         101, 165, 107, 175,     /* IDIV */\r
193         3, 2, 15, 15,           /* INC/DEC */\r
194         3, 3, 16, 16,           /* NEG/NOT */\r
195 \r
196         2, 8, 4,                /* reg shift/rotate */\r
197         15, 20, 4,              /* m8 shift/rotate */\r
198         15, 20, 4,              /* m16 shift/rotate */\r
199 \r
200         22, 9, 21,              /* CMPS 8-bit */\r
201         22, 9, 21,              /* CMPS 16-bit */\r
202         15, 9, 14,              /* SCAS 8-bit */\r
203         15, 9, 14,              /* SCAS 16-bit */\r
204         12, 9, 11,              /* LODS 8-bit */\r
205         12, 9, 11,              /* LODS 16-bit */\r
206         11, 9, 10,              /* STOS 8-bit */\r
207         11, 9, 10,              /* STOS 16-bit */\r
208         18, 9, 17,              /* MOVS 8-bit */\r
209         18, 9, 17,              /* MOVS 16-bit */\r
210 };\r
211 #else\r
212 /* these come from the Intel 80186 datasheet */\r
213 static const struct i80x86_timing timing = {\r
214         45, 28,                 /* exception, IRET */\r
215         0, 2, 4, 3,             /* INTs */\r
216         2,                      /* segment overrides */\r
217         2, 2, 3,                /* flag operations */\r
218         8, 7, 19, 15,           /* arithmetic adjusts */\r
219         4, 4,                   /* decimal adjusts */\r
220         2, 4,                   /* sign extension */\r
221         2, 18, 6, 2, 6, 11,     /* misc */\r
222 \r
223         14, 14, 14,             /* direct JMPs */\r
224         11, 17, 26,             /* indirect JMPs */\r
225         15, 23,                 /* direct CALLs */\r
226         13, 19, 38,             /* indirect CALLs */\r
227         16, 22, 18, 25,         /* returns */\r
228         4, 13, 5, 15,           /* conditional JMPs */\r
229         6, 16, 6, 16,           /* loops */\r
230 \r
231         10, 10, 8, 8,           /* port reads */\r
232         9, 9, 7, 7,             /* port writes */\r
233 \r
234         2, 9, 12,               /* move, 8-bit */\r
235         3, 12,                  /* move, 8-bit immediate */\r
236         2, 9, 12,               /* move, 16-bit */\r
237         4, 13,                  /* move, 16-bit immediate */\r
238         8, 8, 9, 9,             /* move, AL/AX memory */\r
239         2, 11, 2, 11,           /* move, segment registers */\r
240         4, 17,                  /* exchange, 8-bit */\r
241         4, 17, 3,               /* exchange, 16-bit */\r
242 \r
243         10, 16, 9, 9,           /* pushes */\r
244         10, 20, 8, 8,           /* pops */\r
245 \r
246         3, 10, 10,              /* ALU ops, 8-bit */\r
247         4, 16, 10,              /* ALU ops, 8-bit immediate */\r
248         3, 10, 10,              /* ALU ops, 16-bit */\r
249         4, 16, 10,              /* ALU ops, 16-bit immediate */\r
250         4, 16, 10,              /* ALU ops, 16-bit w/8-bit immediate */\r
251         26, 35, 32, 41,         /* MUL */\r
252         25, 34, 31, 40,         /* IMUL */\r
253         29, 38, 35, 44,         /* DIV */\r
254         44, 53, 50, 59,         /* IDIV */\r
255         3, 3, 15, 15,           /* INC/DEC */\r
256         3, 3, 10, 10,           /* NEG/NOT */\r
257 \r
258         2, 5, 1,                /* reg shift/rotate */\r
259         15, 17, 1,              /* m8 shift/rotate */\r
260         15, 17, 1,              /* m16 shift/rotate */\r
261 \r
262         22, 5, 22,              /* CMPS 8-bit */\r
263         22, 5, 22,              /* CMPS 16-bit */\r
264         15, 5, 15,              /* SCAS 8-bit */\r
265         15, 5, 15,              /* SCAS 16-bit */\r
266         12, 6, 11,              /* LODS 8-bit */\r
267         12, 6, 11,              /* LODS 16-bit */\r
268         10, 6, 9,               /* STOS 8-bit */\r
269         10, 6, 9,               /* STOS 16-bit */\r
270         14, 8, 8,               /* MOVS 8-bit */\r
271         14, 8, 8,               /* MOVS 16-bit */\r
272 \r
273         14, 8, 8,               /* (80186) INS 8-bit */\r
274         14, 8, 8,               /* (80186) INS 16-bit */\r
275         14, 8, 8,               /* (80186) OUTS 8-bit */\r
276         14, 8, 8,               /* (80186) OUTS 16-bit */\r
277         14, 68, 83,             /* (80186) PUSH immediate, PUSHA/POPA */\r
278         22, 29,                 /* (80186) IMUL immediate 8-bit */\r
279         25, 32,                 /* (80186) IMUL immediate 16-bit */\r
280         15, 25, 4, 16, 8,       /* (80186) ENTER/LEAVE */\r
281         33,                     /* (80186) BOUND */\r
282 };\r
283 #endif\r
284 \r
285 /************************************************************************/\r
286 \r
287 #define SetTF(x)                (TF = (x))\r
288 #define SetIF(x)                (IF = (x))\r
289 #define SetDF(x)                (DirVal = (x) ? -1 : 1)\r
290 #define SetMD(x)                (MF = (x))\r
291 \r
292 #define SetOFW_Add(x, y, z)     (OverVal = ((x) ^ (y)) & ((x) ^ (z)) & 0x8000)\r
293 #define SetOFB_Add(x, y, z)     (OverVal = ((x) ^ (y)) & ((x) ^ (z)) & 0x80)\r
294 #define SetOFW_Sub(x, y, z)     (OverVal = ((z) ^ (y)) & ((z) ^ (x)) & 0x8000)\r
295 #define SetOFB_Sub(x, y, z)     (OverVal = ((z) ^ (y)) & ((z) ^ (x)) & 0x80)\r
296 \r
297 #define SetCFB(x)               (CarryVal = (x) & 0x100)\r
298 #define SetCFW(x)               (CarryVal = (x) & 0x10000)\r
299 #define SetAF(x, y, z)          (AuxVal = ((x) ^ ((y) ^ (z))) & 0x10)\r
300 #define SetSF(x)                (SignVal = (x))\r
301 #define SetZF(x)                (ZeroVal = (x))\r
302 #define SetPF(x)                (ParityVal = (x))\r
303 \r
304 #define SetSZPF_Byte(x)         (ParityVal = SignVal = ZeroVal = (int8)(x))\r
305 #define SetSZPF_Word(x)         (ParityVal = SignVal = ZeroVal = (int16)(x))\r
306 \r
307 #define ADDB(dst, src)          { unsigned res = (dst) + (src); SetCFB(res); SetOFB_Add(res, src, dst); SetAF(res, src, dst); SetSZPF_Byte(res); dst = (uint8)res; }\r
308 #define ADDW(dst, src)          { unsigned res = (dst) + (src); SetCFW(res); SetOFW_Add(res, src, dst); SetAF(res, src, dst); SetSZPF_Word(res); dst = (uint16)res; }\r
309 \r
310 #define SUBB(dst, src)          { unsigned res = (dst) - (src); SetCFB(res); SetOFB_Sub(res, src, dst); SetAF(res, src, dst); SetSZPF_Byte(res); dst = (uint8)res; }\r
311 #define SUBW(dst, src)          { unsigned res = (dst) - (src); SetCFW(res); SetOFW_Sub(res, src, dst); SetAF(res, src, dst); SetSZPF_Word(res); dst = (uint16)res; }\r
312 \r
313 #define ORB(dst, src)           dst |= (src); CarryVal = OverVal = AuxVal = 0; SetSZPF_Byte(dst)\r
314 #define ORW(dst, src)           dst |= (src); CarryVal = OverVal = AuxVal = 0; SetSZPF_Word(dst)\r
315 \r
316 #define ANDB(dst, src)          dst &= (src); CarryVal = OverVal = AuxVal = 0; SetSZPF_Byte(dst)\r
317 #define ANDW(dst, src)          dst &= (src); CarryVal = OverVal = AuxVal = 0; SetSZPF_Word(dst)\r
318 \r
319 #define XORB(dst, src)          dst ^= (src); CarryVal = OverVal = AuxVal = 0; SetSZPF_Byte(dst)\r
320 #define XORW(dst, src)          dst ^= (src); CarryVal = OverVal = AuxVal = 0; SetSZPF_Word(dst)\r
321 \r
322 #define CF                      (CarryVal != 0)\r
323 #define SF                      (SignVal < 0)\r
324 #define ZF                      (ZeroVal == 0)\r
325 #define PF                      parity_table[ParityVal]\r
326 #define AF                      (AuxVal != 0)\r
327 #define OF                      (OverVal != 0)\r
328 #define DF                      (DirVal < 0)\r
329 #define MD                      (MF != 0)\r
330 \r
331 /************************************************************************/\r
332 \r
333 #define AMASK   0xfffff\r
334 \r
335 #define read_mem_byte(a)        d_mem->read_data8((a) & AMASK)\r
336 #define read_mem_word(a)        d_mem->read_data16((a) & AMASK)\r
337 #define write_mem_byte(a, d)    d_mem->write_data8((a) & AMASK, (d))\r
338 #define write_mem_word(a, d)    d_mem->write_data16((a) & AMASK, (d))\r
339 \r
340 #define read_port_byte(a)       d_io->read_io8(a)\r
341 #define read_port_word(a)       d_io->read_io16(a)\r
342 #define write_port_byte(a, d)   d_io->write_io8((a), (d))\r
343 #define write_port_word(a, d)   d_io->write_io16((a), (d))\r
344 \r
345 /************************************************************************/\r
346 \r
347 #define SegBase(Seg)            (sregs[Seg] << 4)\r
348 \r
349 #define DefaultSeg(Seg)         ((seg_prefix && (Seg == DS || Seg == SS)) ? prefix_seg : Seg)\r
350 #define DefaultBase(Seg)        ((seg_prefix && (Seg == DS || Seg == SS)) ? base[prefix_seg] : base[Seg])\r
351 \r
352 #define GetMemB(Seg, Off)       (read_mem_byte((DefaultBase(Seg) + (Off)) & AMASK))\r
353 #define GetMemW(Seg, Off)       (read_mem_word((DefaultBase(Seg) + (Off)) & AMASK))\r
354 #define PutMemB(Seg, Off, x)    write_mem_byte((DefaultBase(Seg) + (Off)) & AMASK, (x))\r
355 #define PutMemW(Seg, Off, x)    write_mem_word((DefaultBase(Seg) + (Off)) & AMASK, (x))\r
356 \r
357 #define ReadByte(ea)            (read_mem_byte((ea) & AMASK))\r
358 #define ReadWord(ea)            (read_mem_word((ea) & AMASK))\r
359 #define WriteByte(ea, val)      write_mem_byte((ea) & AMASK, val);\r
360 #define WriteWord(ea, val)      write_mem_word((ea) & AMASK, val);\r
361 \r
362 #define FETCH                   read_mem_byte(pc++)\r
363 #define FETCHOP                 read_mem_byte(pc++)\r
364 #define FETCHWORD(var)          { var = read_mem_word(pc); pc += 2; }\r
365 #define PUSH(val)               { regs.w[SP] -= 2; WriteWord(((base[SS] + regs.w[SP]) & AMASK), val); }\r
366 #define POP(var)                { regs.w[SP] += 2; var = ReadWord(((base[SS] + ((regs.w[SP]-2) & 0xffff)) & AMASK)); }\r
367 \r
368 /************************************************************************/\r
369 \r
370 #define CompressFlags() (uint16)(CF | (PF << 2) | (AF << 4) | (ZF << 6) | (SF << 7) | (TF << 8) | (IF << 9) | (DF << 10) | (OF << 11) | (MD << 15))\r
371 \r
372 #define ExpandFlags(f) { \\r
373         CarryVal = (f) & 1; \\r
374         ParityVal = !((f) & 4); \\r
375         AuxVal = (f) & 0x10; \\r
376         ZeroVal = !((f) & 0x40); \\r
377         SignVal = ((f) & 0x80) ? -1 : 0; \\r
378         TF = ((f) & 0x100) >> 8; \\r
379         IF = ((f) & 0x200) >> 9; \\r
380         MF = ((f) & 0x8000) >> 15; \\r
381         DirVal = ((f) & 0x400) ? -1 : 1; \\r
382         OverVal = (f) & 0x800; \\r
383 }\r
384 \r
385 /************************************************************************/\r
386 \r
387 #define RegWord(ModRM) regs.w[Mod_RM.reg.w[ModRM]]\r
388 #define RegByte(ModRM) regs.b[Mod_RM.reg.b[ModRM]]\r
389 \r
390 #define GetRMWord(ModRM) \\r
391         ((ModRM) >= 0xc0 ? regs.w[Mod_RM.RM.w[ModRM]] : (GetEA(ModRM), ReadWord(ea)))\r
392 \r
393 #define PutbackRMWord(ModRM, val) { \\r
394         if (ModRM >= 0xc0) { \\r
395                 regs.w[Mod_RM.RM.w[ModRM]] = val; \\r
396         } else { \\r
397                 WriteWord(ea, val); \\r
398         } \\r
399 }\r
400 \r
401 #define GetNextRMWord ( \\r
402         ReadWord(ea + 2) \\r
403 )\r
404 \r
405 #define GetRMWordOffset(offs) ( \\r
406         ReadWord(ea - eo + (uint16)(eo + offs)) \\r
407 )\r
408 \r
409 #define GetRMByteOffset(offs) ( \\r
410         ReadByte(ea - eo + (uint16)(eo + offs)) \\r
411 )\r
412 \r
413 #define PutRMWord(ModRM, val) { \\r
414         if (ModRM >= 0xc0) { \\r
415                 regs.w[Mod_RM.RM.w[ModRM]] = val; \\r
416         } else { \\r
417                 GetEA(ModRM); \\r
418                 WriteWord(ea, val); \\r
419         } \\r
420 }\r
421 \r
422 #define PutRMWordOffset(offs, val) \\r
423         WriteWord(ea - eo + (uint16)(eo + offs), val)\r
424 \r
425 #define PutRMByteOffset(offs, val) \\r
426         WriteByte(ea - eo + (uint16)(eo + offs), val)\r
427 \r
428 #define PutImmRMWord(ModRM) { \\r
429         uint16 val; \\r
430         if (ModRM >= 0xc0) { \\r
431                 FETCHWORD(regs.w[Mod_RM.RM.w[ModRM]]) \\r
432         } else { \\r
433                 GetEA(ModRM); \\r
434                 FETCHWORD(val) \\r
435                 WriteWord(ea, val); \\r
436         } \\r
437 }\r
438 \r
439 #define GetRMByte(ModRM) \\r
440         ((ModRM) >= 0xc0 ? regs.b[Mod_RM.RM.b[ModRM]] : (GetEA(ModRM), ReadByte(ea)))\r
441 \r
442 #define PutRMByte(ModRM, val) { \\r
443         if (ModRM >= 0xc0) { \\r
444                 regs.b[Mod_RM.RM.b[ModRM]] = val; \\r
445         } else { \\r
446                 GetEA(ModRM); \\r
447                 WriteByte(ea, val); \\r
448         } \\r
449 }\r
450 \r
451 #define PutImmRMByte(ModRM) { \\r
452         if (ModRM >= 0xc0) { \\r
453                 regs.b[Mod_RM.RM.b[ModRM]] = FETCH; \\r
454         } else { \\r
455                 GetEA(ModRM); \\r
456                 WriteByte(ea, FETCH); \\r
457         } \\r
458 }\r
459 \r
460 #define PutbackRMByte(ModRM, val) { \\r
461         if (ModRM >= 0xc0) { \\r
462                 regs.b[Mod_RM.RM.b[ModRM]] = val; \\r
463         } else { \\r
464                 WriteByte(ea, val); \\r
465         } \\r
466 }\r
467 \r
468 #define DEF_br8(dst, src) \\r
469         unsigned ModRM = FETCHOP; \\r
470         unsigned src = RegByte(ModRM); \\r
471         unsigned dst = GetRMByte(ModRM)\r
472 \r
473 #define DEF_wr16(dst, src) \\r
474         unsigned ModRM = FETCHOP; \\r
475         unsigned src = RegWord(ModRM); \\r
476         unsigned dst = GetRMWord(ModRM)\r
477 \r
478 #define DEF_r8b(dst, src) \\r
479         unsigned ModRM = FETCHOP; \\r
480         unsigned dst = RegByte(ModRM); \\r
481         unsigned src = GetRMByte(ModRM)\r
482 \r
483 #define DEF_r16w(dst, src) \\r
484         unsigned ModRM = FETCHOP; \\r
485         unsigned dst = RegWord(ModRM); \\r
486         unsigned src = GetRMWord(ModRM)\r
487 \r
488 #define DEF_ald8(dst, src) \\r
489         unsigned src = FETCHOP; \\r
490         unsigned dst = regs.b[AL]\r
491 \r
492 #define DEF_axd16(dst, src) \\r
493         unsigned src = FETCHOP; \\r
494         unsigned dst = regs.w[AX]; \\r
495         src += (FETCH << 8)\r
496 \r
497 /************************************************************************/\r
498 \r
499 #ifndef INLINE\r
500 #define INLINE inline\r
501 #endif\r
502 \r
503 #define offs_t UINT32\r
504 \r
505 // Disassembler constants\r
506 const UINT32 DASMFLAG_SUPPORTED     = 0x80000000;   // are disassembly flags supported?\r
507 const UINT32 DASMFLAG_STEP_OUT      = 0x40000000;   // this instruction should be the end of a step out sequence\r
508 const UINT32 DASMFLAG_STEP_OVER     = 0x20000000;   // this instruction should be stepped over by setting a breakpoint afterwards\r
509 const UINT32 DASMFLAG_OVERINSTMASK  = 0x18000000;   // number of extra instructions to skip when stepping over\r
510 const UINT32 DASMFLAG_OVERINSTSHIFT = 27;           // bits to shift after masking to get the value\r
511 const UINT32 DASMFLAG_LENGTHMASK    = 0x0000ffff;   // the low 16-bits contain the actual length\r
512 \r
513 /* Highly useful macro for compile-time knowledge of an array size */\r
514 #define ARRAY_LENGTH(x)     (sizeof(x) / sizeof(x[0]))\r
515 \r
516 int necv_dasm_one(char *buffer, UINT32 eip, const UINT8 *oprom);\r
517 \r
518 void I86::initialize()\r
519 {\r
520         static const BREGS reg_name[8] = {AL, CL, DL, BL, AH, CH, DH, BH};\r
521         \r
522         for(int i = 0; i < 256; i++) {\r
523                 Mod_RM.reg.b[i] = reg_name[(i & 0x38) >> 3];\r
524                 Mod_RM.reg.w[i] = (WREGS)((i & 0x38) >> 3);\r
525         }\r
526         for(int i = 0xc0; i < 0x100; i++) {\r
527                 Mod_RM.RM.w[i] = (WREGS)(i & 7);\r
528                 Mod_RM.RM.b[i] = (BREGS)reg_name[i & 7];\r
529         }\r
530 #ifdef USE_DEBUGGER\r
531         d_mem_stored = d_mem;\r
532         d_io_stored = d_io;\r
533         d_debugger->set_context_mem(d_mem);\r
534         d_debugger->set_context_io(d_io);\r
535 #endif\r
536 }\r
537 \r
538 void I86::reset()\r
539 {\r
540         for(int i = 0; i < 8; i++) {\r
541                 regs.w[i] = 0;\r
542         }\r
543         sregs[CS] = 0xf000;\r
544         sregs[SS] = sregs[DS] = sregs[ES] = 0;\r
545         \r
546         base[CS] = SegBase(CS);\r
547         base[SS] = base[DS] = base[ES] = 0;\r
548         \r
549         ea = 0;\r
550         eo = 0;\r
551         AuxVal = OverVal = SignVal = ZeroVal = CarryVal = 0;\r
552         DirVal = 1;\r
553         ParityVal = TF = IF = MF = 0;\r
554         \r
555         icount = extra_icount = 0;\r
556         int_state = 0;\r
557         test_state = false;\r
558         halted = false;\r
559         \r
560         pc = 0xffff0 & AMASK;\r
561         flags = 0;\r
562         ExpandFlags(flags);\r
563 #ifdef HAS_V30\r
564         SetMD(1);\r
565 #endif\r
566         seg_prefix = false;\r
567 }\r
568 \r
569 int I86::run(int clock)\r
570 {\r
571         /* return now if BUSREQ */\r
572         if(busreq) {\r
573 #ifdef SINGLE_MODE_DMA\r
574                 if(d_dma) {\r
575                         d_dma->do_dma();\r
576                 }\r
577 #endif\r
578                 int passed_icount = max(1, extra_icount);\r
579                 icount = extra_icount = 0;\r
580                 return passed_icount;\r
581         }\r
582         \r
583         // run cpu\r
584         if(clock == -1) {\r
585                 // run only one opcode\r
586                 icount = -extra_icount;\r
587                 extra_icount = 0;\r
588 #ifdef USE_DEBUGGER\r
589                 run_one_opecode_debugger();\r
590 #else\r
591                 run_one_opecode();\r
592 #endif\r
593                 return -icount;\r
594         } else {\r
595                 /* run cpu while given clocks */\r
596                 icount += clock;\r
597                 int first_icount = icount;\r
598                 icount -= extra_icount;\r
599                 extra_icount = 0;\r
600                 \r
601                 while(icount > 0 && !busreq) {\r
602 #ifdef USE_DEBUGGER\r
603                         run_one_opecode_debugger();\r
604 #else\r
605                         run_one_opecode();\r
606 #endif\r
607                 }\r
608                 int passed_icount = first_icount - icount;\r
609                 if(busreq && icount > 0) {\r
610                         icount = 0;\r
611                 }\r
612                 return passed_icount;\r
613         }\r
614 }\r
615 \r
616 #ifdef USE_DEBUGGER\r
617 void I86::run_one_opecode_debugger()\r
618 {\r
619         bool now_debugging = d_debugger->now_debugging;\r
620         if(now_debugging) {\r
621                 d_debugger->check_break_points(pc);\r
622                 if(d_debugger->now_suspended) {\r
623                         emu->mute_sound();\r
624                         while(d_debugger->now_debugging && d_debugger->now_suspended) {\r
625                                 Sleep(10);\r
626                         }\r
627                 }\r
628                 if(d_debugger->now_debugging) {\r
629                         d_mem = d_io = d_debugger;\r
630                 } else {\r
631                         now_debugging = false;\r
632                 }\r
633                 \r
634                 run_one_opecode();\r
635                 if(now_debugging) {\r
636                         if(!d_debugger->now_going) {\r
637                                 d_debugger->now_suspended = true;\r
638                         }\r
639                         d_mem = d_mem_stored;\r
640                         d_io = d_io_stored;\r
641                 }\r
642         } else {\r
643                 run_one_opecode();\r
644         }\r
645 }\r
646 #endif\r
647 \r
648 void I86::run_one_opecode()\r
649 {\r
650         seg_prefix = false;\r
651 #ifdef _JX\r
652         // ugly patch for PC/JX hardware diagnostics :-(\r
653 #ifdef TIMER_HACK\r
654         if(pc == 0xff040) pc = 0xff04a;\r
655         if(pc == 0xff17d) pc = 0xff18f;\r
656 #endif\r
657 #ifdef KEYBOARD_HACK\r
658         if(pc == 0xfa909) { regs.b[BH] = read_port_byte(0xa1); pc = 0xfa97c; }\r
659         if(pc == 0xff6e1) { regs.b[AL] = 0x0d; pc += 2; }\r
660 #endif\r
661 #endif\r
662         instruction(FETCHOP);\r
663         if(int_state & NMI_REQ_BIT) {\r
664                 if(halted) {\r
665                         pc++;\r
666                         halted = false;\r
667                 }\r
668                 int_state &= ~NMI_REQ_BIT;\r
669                 interrupt(NMI_INT_VECTOR);\r
670         } else if((int_state & INT_REQ_BIT) && IF) {\r
671                 if(halted) {\r
672                         pc++;\r
673                         halted = false;\r
674                 }\r
675                 interrupt(-1);\r
676         }\r
677 #ifdef SINGLE_MODE_DMA\r
678         if(d_dma) {\r
679                 d_dma->do_dma();\r
680         }\r
681 #endif\r
682         icount -= extra_icount;\r
683         extra_icount = 0;\r
684 }\r
685 \r
686 void I86::write_signal(int id, uint32 data, uint32 mask)\r
687 {\r
688         if(id == SIG_CPU_NMI) {\r
689                 if(data & mask) {\r
690                         int_state |= NMI_REQ_BIT;\r
691                 } else {\r
692                         int_state &= ~NMI_REQ_BIT;\r
693                 }\r
694         } else if(id == SIG_CPU_BUSREQ) {\r
695                 busreq = ((data & mask) != 0);\r
696         } else if(id == SIG_I86_TEST) {\r
697                 test_state = ((data & mask) != 0);\r
698         }\r
699 }\r
700 \r
701 void I86::set_intr_line(bool line, bool pending, uint32 bit)\r
702 {\r
703         if(line) {\r
704                 int_state |= INT_REQ_BIT;\r
705         } else {\r
706                 int_state &= ~INT_REQ_BIT;\r
707         }\r
708 }\r
709 \r
710 #ifdef USE_DEBUGGER\r
711 void I86::debug_write_data8(uint32 addr, uint32 data)\r
712 {\r
713         int wait;\r
714         d_mem_stored->write_data8w(addr, data, &wait);\r
715 }\r
716 \r
717 uint32 I86::debug_read_data8(uint32 addr)\r
718 {\r
719         int wait;\r
720         return d_mem_stored->read_data8w(addr, &wait);\r
721 }\r
722 \r
723 void I86::debug_write_data16(uint32 addr, uint32 data)\r
724 {\r
725         int wait;\r
726         d_mem_stored->write_data16w(addr, data, &wait);\r
727 }\r
728 \r
729 uint32 I86::debug_read_data16(uint32 addr)\r
730 {\r
731         int wait;\r
732         return d_mem_stored->read_data16w(addr, &wait);\r
733 }\r
734 \r
735 void I86::debug_write_io8(uint32 addr, uint32 data)\r
736 {\r
737         int wait;\r
738         d_io_stored->write_io8w(addr, data, &wait);\r
739 }\r
740 \r
741 uint32 I86::debug_read_io8(uint32 addr) {\r
742         int wait;\r
743         return d_io_stored->read_io8w(addr, &wait);\r
744 }\r
745 \r
746 void I86::debug_write_io16(uint32 addr, uint32 data)\r
747 {\r
748         int wait;\r
749         d_io_stored->write_io16w(addr, data, &wait);\r
750 }\r
751 \r
752 uint32 I86::debug_read_io16(uint32 addr) {\r
753         int wait;\r
754         return d_io_stored->read_io16w(addr, &wait);\r
755 }\r
756 \r
757 bool I86::debug_write_reg(_TCHAR *reg, uint32 data)\r
758 {\r
759         if(_tcsicmp(reg, _T("IP")) == 0) {\r
760                 pc = ((data & 0xffff) + base[CS]) & AMASK;\r
761         } else if(_tcsicmp(reg, _T("AX")) == 0) {\r
762                 regs.w[AX] = data;\r
763         } else if(_tcsicmp(reg, _T("BX")) == 0) {\r
764                 regs.w[BX] = data;\r
765         } else if(_tcsicmp(reg, _T("CX")) == 0) {\r
766                 regs.w[CX] = data;\r
767         } else if(_tcsicmp(reg, _T("DX")) == 0) {\r
768                 regs.w[DX] = data;\r
769         } else if(_tcsicmp(reg, _T("SP")) == 0) {\r
770                 regs.w[SP] = data;\r
771         } else if(_tcsicmp(reg, _T("BP")) == 0) {\r
772                 regs.w[BP] = data;\r
773         } else if(_tcsicmp(reg, _T("SI")) == 0) {\r
774                 regs.w[SI] = data;\r
775         } else if(_tcsicmp(reg, _T("DI")) == 0) {\r
776                 regs.w[DI] = data;\r
777         } else if(_tcsicmp(reg, _T("AL")) == 0) {\r
778                 regs.b[AL] = data;\r
779         } else if(_tcsicmp(reg, _T("AH")) == 0) {\r
780                 regs.b[AH] = data;\r
781         } else if(_tcsicmp(reg, _T("BL")) == 0) {\r
782                 regs.b[BL] = data;\r
783         } else if(_tcsicmp(reg, _T("BH")) == 0) {\r
784                 regs.b[BH] = data;\r
785         } else if(_tcsicmp(reg, _T("CL")) == 0) {\r
786                 regs.b[CL] = data;\r
787         } else if(_tcsicmp(reg, _T("CH")) == 0) {\r
788                 regs.b[CH] = data;\r
789         } else if(_tcsicmp(reg, _T("DL")) == 0) {\r
790                 regs.b[DL] = data;\r
791         } else if(_tcsicmp(reg, _T("DH")) == 0) {\r
792                 regs.b[DH] = data;\r
793         } else {\r
794                 return false;\r
795         }\r
796         return true;\r
797 }\r
798 \r
799 void I86::debug_regs_info(_TCHAR *buffer)\r
800 {\r
801         _stprintf(buffer, _T("AX=%04X  BX=%04X CX=%04X DX=%04X SP=%04X  BP=%04X  SI=%04X  DI=%04X\nDS=%04X  ES=%04X SS=%04X CS=%04X IP=%04X  FLAG=[%c%c%c%c%c%c%c%c%c]"),\r
802         regs.w[AX], regs.w[BX], regs.w[CX], regs.w[DX], regs.w[SP], regs.w[BP], regs.w[SI], regs.w[DI], sregs[DS], sregs[ES], sregs[SS], sregs[CS], (uint16)(pc - base[CS]),\r
803         OF ? _T('O') : _T('-'), DF ? _T('D') : _T('-'), IF ? _T('I') : _T('-'), TF ? _T('T') : _T('-'),\r
804         SF ? _T('S') : _T('-'), ZF ? _T('Z') : _T('-'), AF ? _T('A') : _T('-'), PF ? _T('P') : _T('-'), CF ? _T('C') : _T('-'));\r
805 }\r
806 \r
807 int I86::debug_dasm(uint32 pc, _TCHAR *buffer)\r
808 {\r
809         UINT32 eip = (UINT32)(uint16)(pc - base[CS]);\r
810         UINT8 ops[16];\r
811         for(int i = 0; i < 16; i++) {\r
812                 int wait;\r
813                 ops[i] = d_mem->read_data8w(pc + i, &wait);\r
814         }\r
815         return necv_dasm_one(buffer, eip, ops) & DASMFLAG_LENGTHMASK;\r
816 }\r
817 #endif\r
818 \r
819 void I86::interrupt(int int_num)\r
820 {\r
821         unsigned dest_seg, dest_off;\r
822         uint16 ip = pc - base[CS];\r
823         \r
824         if(int_num == -1) {\r
825                 int_num = d_pic->intr_ack() & 0xff;\r
826                 int_state &= ~INT_REQ_BIT;\r
827         }\r
828         dest_off = ReadWord(int_num * 4);\r
829         dest_seg = ReadWord(int_num * 4 + 2);\r
830         \r
831         _pushf();\r
832         TF = IF = 0;\r
833         PUSH(sregs[CS]);\r
834         PUSH(ip);\r
835         sregs[CS] = (uint16)dest_seg;\r
836         base[CS] = SegBase(CS);\r
837         pc = (base[CS] + dest_off) & AMASK;\r
838         icount -= timing.exception;\r
839 }\r
840 \r
841 void I86::trap()\r
842 {\r
843         instruction(FETCHOP);\r
844         interrupt(1);\r
845 }\r
846 \r
847 unsigned I86::GetEA(unsigned ModRM)\r
848 {\r
849         switch(ModRM) {\r
850         case 0x00: case 0x08: case 0x10: case 0x18: case 0x20: case 0x28: case 0x30: case 0x38:\r
851                 icount -= 7; eo = (uint16)(regs.w[BX] + regs.w[SI]); ea_seg = DefaultSeg(DS); ea = DefaultBase(DS) + eo; return ea;\r
852         case 0x01: case 0x09: case 0x11: case 0x19: case 0x21: case 0x29: case 0x31: case 0x39:\r
853                 icount -= 8; eo = (uint16)(regs.w[BX] + regs.w[DI]); ea_seg = DefaultSeg(DS); ea = DefaultBase(DS) + eo; return ea;\r
854         case 0x02: case 0x0a: case 0x12: case 0x1a: case 0x22: case 0x2a: case 0x32: case 0x3a:\r
855                 icount -= 8; eo = (uint16)(regs.w[BP] + regs.w[SI]); ea_seg = DefaultSeg(SS); ea = DefaultBase(SS) + eo; return ea;\r
856         case 0x03: case 0x0b: case 0x13: case 0x1b: case 0x23: case 0x2b: case 0x33: case 0x3b:\r
857                 icount -= 7; eo = (uint16)(regs.w[BP] + regs.w[DI]); ea_seg = DefaultSeg(SS); ea = DefaultBase(SS) + eo; return ea;\r
858         case 0x04: case 0x0c: case 0x14: case 0x1c: case 0x24: case 0x2c: case 0x34: case 0x3c:\r
859                 icount -= 5; eo = regs.w[SI]; ea_seg = DefaultSeg(DS); ea = DefaultBase(DS) + eo; return ea;\r
860         case 0x05: case 0x0d: case 0x15: case 0x1d: case 0x25: case 0x2d: case 0x35: case 0x3d:\r
861                 icount -= 5; eo = regs.w[DI]; ea_seg = DefaultSeg(DS); ea = DefaultBase(DS) + eo; return ea;\r
862         case 0x06: case 0x0e: case 0x16: case 0x1e: case 0x26: case 0x2e: case 0x36: case 0x3e:\r
863                 icount -= 6; eo = FETCHOP; eo += FETCHOP << 8; ea_seg = DefaultSeg(DS); ea = DefaultBase(DS) + eo; return ea;\r
864         case 0x07: case 0x0f: case 0x17: case 0x1f: case 0x27: case 0x2f: case 0x37: case 0x3f:\r
865                 icount -= 5; eo = regs.w[BX]; ea_seg = DefaultSeg(DS); ea = DefaultBase(DS) + eo; return ea;\r
866 \r
867         case 0x40: case 0x48: case 0x50: case 0x58: case 0x60: case 0x68: case 0x70: case 0x78:\r
868                 icount -= 11; eo = (uint16)(regs.w[BX] + regs.w[SI] + (int8)FETCHOP); ea_seg = DefaultSeg(DS); ea = DefaultBase(DS) + eo; return ea;\r
869         case 0x41: case 0x49: case 0x51: case 0x59: case 0x61: case 0x69: case 0x71: case 0x79:\r
870                 icount -= 12; eo = (uint16)(regs.w[BX] + regs.w[DI] + (int8)FETCHOP); ea_seg = DefaultSeg(DS); ea = DefaultBase(DS) + eo; return ea;\r
871         case 0x42: case 0x4a: case 0x52: case 0x5a: case 0x62: case 0x6a: case 0x72: case 0x7a:\r
872                 icount -= 12; eo = (uint16)(regs.w[BP] + regs.w[SI] + (int8)FETCHOP); ea_seg = DefaultSeg(SS); ea = DefaultBase(SS) + eo; return ea;\r
873         case 0x43: case 0x4b: case 0x53: case 0x5b: case 0x63: case 0x6b: case 0x73: case 0x7b:\r
874                 icount -= 11; eo = (uint16)(regs.w[BP] + regs.w[DI] + (int8)FETCHOP); ea_seg = DefaultSeg(SS); ea = DefaultBase(SS) + eo; return ea;\r
875         case 0x44: case 0x4c: case 0x54: case 0x5c: case 0x64: case 0x6c: case 0x74: case 0x7c:\r
876                 icount -= 9; eo = (uint16)(regs.w[SI] + (int8)FETCHOP); ea_seg = DefaultSeg(DS); ea = DefaultBase(DS) + eo; return ea;\r
877         case 0x45: case 0x4d: case 0x55: case 0x5d: case 0x65: case 0x6d: case 0x75: case 0x7d:\r
878                 icount -= 9; eo = (uint16)(regs.w[DI] + (int8)FETCHOP); ea_seg = DefaultSeg(DS); ea = DefaultBase(DS) + eo; return ea;\r
879         case 0x46: case 0x4e: case 0x56: case 0x5e: case 0x66: case 0x6e: case 0x76: case 0x7e:\r
880                 icount -= 9; eo = (uint16)(regs.w[BP] + (int8)FETCHOP); ea_seg = DefaultSeg(SS); ea = DefaultBase(SS) + eo; return ea;\r
881         case 0x47: case 0x4f: case 0x57: case 0x5f: case 0x67: case 0x6f: case 0x77: case 0x7f:\r
882                 icount -= 9; eo = (uint16)(regs.w[BX] + (int8)FETCHOP); ea_seg = DefaultSeg(DS); ea = DefaultBase(DS) + eo; return ea;\r
883 \r
884         case 0x80: case 0x88: case 0x90: case 0x98: case 0xa0: case 0xa8: case 0xb0: case 0xb8:\r
885                 icount -= 11; eo = FETCHOP; eo += FETCHOP << 8; eo += regs.w[BX] + regs.w[SI]; ea_seg = DefaultSeg(DS); ea = DefaultBase(DS) + (uint16)eo; return ea;\r
886         case 0x81: case 0x89: case 0x91: case 0x99: case 0xa1: case 0xa9: case 0xb1: case 0xb9:\r
887                 icount -= 12; eo = FETCHOP; eo += FETCHOP << 8; eo += regs.w[BX] + regs.w[DI]; ea_seg = DefaultSeg(DS); ea = DefaultBase(DS) + (uint16)eo; return ea;\r
888         case 0x82: case 0x8a: case 0x92: case 0x9a: case 0xa2: case 0xaa: case 0xb2: case 0xba:\r
889                 icount -= 12; eo = FETCHOP; eo += FETCHOP << 8; eo += regs.w[BP] + regs.w[SI]; ea_seg = DefaultSeg(SS); ea = DefaultBase(SS) + (uint16)eo; return ea;\r
890         case 0x83: case 0x8b: case 0x93: case 0x9b: case 0xa3: case 0xab: case 0xb3: case 0xbb:\r
891                 icount -= 11; eo = FETCHOP; eo += FETCHOP << 8; eo += regs.w[BP] + regs.w[DI]; ea_seg = DefaultSeg(DS); ea = DefaultBase(SS) + (uint16)eo; return ea;\r
892         case 0x84: case 0x8c: case 0x94: case 0x9c: case 0xa4: case 0xac: case 0xb4: case 0xbc:\r
893                 icount -= 9; eo = FETCHOP; eo += FETCHOP << 8; eo += regs.w[SI]; ea_seg = DefaultSeg(DS); ea = DefaultBase(DS) + (uint16)eo; return ea;\r
894         case 0x85: case 0x8d: case 0x95: case 0x9d: case 0xa5: case 0xad: case 0xb5: case 0xbd:\r
895                 icount -= 9; eo = FETCHOP; eo += FETCHOP << 8; eo += regs.w[DI]; ea_seg = DefaultSeg(DS); ea = DefaultBase(DS) + (uint16)eo; return ea;\r
896         case 0x86: case 0x8e: case 0x96: case 0x9e: case 0xa6: case 0xae: case 0xb6: case 0xbe:\r
897                 icount -= 9; eo = FETCHOP; eo += FETCHOP << 8; eo += regs.w[BP]; ea_seg = DefaultSeg(SS); ea = DefaultBase(SS) + (uint16)eo; return ea;\r
898         case 0x87: case 0x8f: case 0x97: case 0x9f: case 0xa7: case 0xaf: case 0xb7: case 0xbf:\r
899                 icount -= 9; eo = FETCHOP; eo += FETCHOP << 8; eo += regs.w[BX]; ea_seg = DefaultSeg(DS); ea = DefaultBase(DS) + (uint16)eo; return ea;\r
900         }\r
901         return 0;\r
902 }\r
903 \r
904 void I86::rotate_shift_byte(unsigned ModRM, unsigned count)\r
905 {\r
906         unsigned src = (unsigned)GetRMByte(ModRM);\r
907         unsigned dst = src;\r
908         \r
909         if(count == 0) {\r
910                 icount -= (ModRM >= 0xc0) ? timing.rot_reg_base : timing.rot_m8_base;\r
911         } else if(count == 1) {\r
912                 icount -= (ModRM >= 0xc0) ? timing.rot_reg_1 : timing.rot_m8_1;\r
913                 \r
914                 switch((ModRM >> 3) & 7) {\r
915                 case 0: /* ROL eb, 1 */\r
916                         CarryVal = src & 0x80;\r
917                         dst = (src << 1) + CF;\r
918                         PutbackRMByte(ModRM, dst);\r
919                         OverVal = (src ^ dst) & 0x80;\r
920                         break;\r
921                 case 1: /* ROR eb, 1 */\r
922                         CarryVal = src & 0x01;\r
923                         dst = ((CF << 8) + src) >> 1;\r
924                         PutbackRMByte(ModRM, dst);\r
925                         OverVal = (src ^ dst) & 0x80;\r
926                         break;\r
927                 case 2: /* RCL eb, 1 */\r
928                         dst = (src << 1) + CF;\r
929                         PutbackRMByte(ModRM, dst);\r
930                         SetCFB(dst);\r
931                         OverVal = (src ^ dst) & 0x80;\r
932                         break;\r
933                 case 3: /* RCR eb, 1 */\r
934                         dst = ((CF << 8) + src) >> 1;\r
935                         PutbackRMByte(ModRM, dst);\r
936                         CarryVal = src & 0x01;\r
937                         OverVal = (src ^ dst) & 0x80;\r
938                         break;\r
939                 case 4: /* SHL eb, 1 */\r
940                 case 6:\r
941                         dst = src << 1;\r
942                         PutbackRMByte(ModRM, dst);\r
943                         SetCFB(dst);\r
944                         OverVal = (src ^ dst) & 0x80;\r
945                         AuxVal = 1;\r
946                         SetSZPF_Byte(dst);\r
947                         break;\r
948                 case 5: /* SHR eb, 1 */\r
949                         dst = src >> 1;\r
950                         PutbackRMByte(ModRM, dst);\r
951                         CarryVal = src & 0x01;\r
952                         OverVal = src & 0x80;\r
953                         AuxVal = 1;\r
954                         SetSZPF_Byte(dst);\r
955                         break;\r
956                 case 7: /* SAR eb, 1 */\r
957                         dst = ((int8)src) >> 1;\r
958                         PutbackRMByte(ModRM, dst);\r
959                         CarryVal = src & 0x01;\r
960                         OverVal = 0;\r
961                         AuxVal = 1;\r
962                         SetSZPF_Byte(dst);\r
963                         break;\r
964                 default:\r
965                         //__assume(0);\r
966                         break;\r
967                 }\r
968         } else {\r
969                 icount -= (ModRM >= 0xc0) ? timing.rot_reg_base + timing.rot_reg_bit : timing.rot_m8_base + timing.rot_m8_bit;\r
970                 \r
971                 switch((ModRM >> 3) & 7) {\r
972                 case 0: /* ROL eb, count */\r
973                         for(; count > 0; count--) {\r
974                                 CarryVal = dst & 0x80;\r
975                                 dst = (dst << 1) + CF;\r
976                         }\r
977                         PutbackRMByte(ModRM, (uint8)dst);\r
978                         break;\r
979                 case 1: /* ROR eb, count */\r
980                         for(; count > 0; count--) {\r
981                                 CarryVal = dst & 0x01;\r
982                                 dst = (dst >> 1) + (CF << 7);\r
983                         }\r
984                         PutbackRMByte(ModRM, (uint8)dst);\r
985                         break;\r
986                 case 2: /* RCL eb, count */\r
987                         for(; count > 0; count--) {\r
988                                 dst = (dst << 1) + CF;\r
989                                 SetCFB(dst);\r
990                         }\r
991                         PutbackRMByte(ModRM, (uint8)dst);\r
992                         break;\r
993                 case 3: /* RCR eb, count */\r
994                         for(; count > 0; count--) {\r
995                                 dst = (CF << 8) + dst;\r
996                                 CarryVal = dst & 0x01;\r
997                                 dst >>= 1;\r
998                         }\r
999                         PutbackRMByte(ModRM, (uint8)dst);\r
1000                         break;\r
1001                 case 4: /* SHL eb, count */\r
1002                 case 6:\r
1003                         dst <<= count;\r
1004                         SetCFB(dst);\r
1005                         AuxVal = 1;\r
1006                         SetSZPF_Byte(dst);\r
1007                         PutbackRMByte(ModRM, (uint8)dst);\r
1008                         break;\r
1009                 case 5: /* SHR eb, count */\r
1010                         dst >>= count - 1;\r
1011                         CarryVal = dst & 0x01;\r
1012                         dst >>= 1;\r
1013                         SetSZPF_Byte(dst);\r
1014                         AuxVal = 1;\r
1015                         PutbackRMByte(ModRM, (uint8)dst);\r
1016                         break;\r
1017                 case 7: /* SAR eb, count */\r
1018                         dst = ((int8)dst) >> (count - 1);\r
1019                         CarryVal = dst & 0x01;\r
1020                         dst = ((int8)((uint8)dst)) >> 1;\r
1021                         SetSZPF_Byte(dst);\r
1022                         AuxVal = 1;\r
1023                         PutbackRMByte(ModRM, (uint8)dst);\r
1024                         break;\r
1025                 default:\r
1026                         //__assume(0);\r
1027                         break;\r
1028                 }\r
1029         }\r
1030 }\r
1031 \r
1032 void I86::rotate_shift_word(unsigned ModRM, unsigned count)\r
1033 {\r
1034         unsigned src = GetRMWord(ModRM);\r
1035         unsigned dst = src;\r
1036         \r
1037         if(count == 0) {\r
1038                 icount -= (ModRM >= 0xc0) ? timing.rot_reg_base : timing.rot_m16_base;\r
1039         } else if(count == 1) {\r
1040                 icount -= (ModRM >= 0xc0) ? timing.rot_reg_1 : timing.rot_m16_1;\r
1041                 \r
1042                 switch((ModRM >> 3) & 7) {\r
1043                 case 0: /* ROL ew, 1 */\r
1044                         CarryVal = src & 0x8000;\r
1045                         dst = (src << 1) + CF;\r
1046                         PutbackRMWord(ModRM, dst);\r
1047                         OverVal = (src ^ dst) & 0x8000;\r
1048                         break;\r
1049                 case 1: /* ROR ew, 1 */\r
1050                         CarryVal = src & 0x01;\r
1051                         dst = ((CF << 16) + src) >> 1;\r
1052                         PutbackRMWord(ModRM, dst);\r
1053                         OverVal = (src ^ dst) & 0x8000;\r
1054                         break;\r
1055                 case 2: /* RCL ew, 1 */\r
1056                         dst = (src << 1) + CF;\r
1057                         PutbackRMWord(ModRM, dst);\r
1058                         SetCFW(dst);\r
1059                         OverVal = (src ^ dst) & 0x8000;\r
1060                         break;\r
1061                 case 3: /* RCR ew, 1 */\r
1062                         dst = ((CF << 16) + src) >> 1;\r
1063                         PutbackRMWord(ModRM, dst);\r
1064                         CarryVal = src & 0x01;\r
1065                         OverVal = (src ^ dst) & 0x8000;\r
1066                         break;\r
1067                 case 4: /* SHL ew, 1 */\r
1068                 case 6:\r
1069                         dst = src << 1;\r
1070                         PutbackRMWord(ModRM, dst);\r
1071                         SetCFW(dst);\r
1072                         OverVal = (src ^ dst) & 0x8000;\r
1073                         AuxVal = 1;\r
1074                         SetSZPF_Word(dst);\r
1075                         break;\r
1076                 case 5: /* SHR ew, 1 */\r
1077                         dst = src >> 1;\r
1078                         PutbackRMWord(ModRM, dst);\r
1079                         CarryVal = src & 0x01;\r
1080                         OverVal = src & 0x8000;\r
1081                         AuxVal = 1;\r
1082                         SetSZPF_Word(dst);\r
1083                         break;\r
1084                 case 7: /* SAR ew, 1 */\r
1085                         dst = ((int16)src) >> 1;\r
1086                         PutbackRMWord(ModRM, dst);\r
1087                         CarryVal = src & 0x01;\r
1088                         OverVal = 0;\r
1089                         AuxVal = 1;\r
1090                         SetSZPF_Word(dst);\r
1091                         break;\r
1092                 default:\r
1093                         //__assume(0);\r
1094                         break;\r
1095                 }\r
1096         } else {\r
1097                 icount -= (ModRM >= 0xc0) ? timing.rot_reg_base + timing.rot_reg_bit : timing.rot_m8_base + timing.rot_m16_bit;\r
1098                 \r
1099                 switch((ModRM >> 3) & 7) {\r
1100                 case 0: /* ROL ew, count */\r
1101                         for(; count > 0; count--) {\r
1102                                 CarryVal = dst & 0x8000;\r
1103                                 dst = (dst << 1) + CF;\r
1104                         }\r
1105                         PutbackRMWord(ModRM, dst);\r
1106                         break;\r
1107                 case 1: /* ROR ew, count */\r
1108                         for(; count > 0; count--) {\r
1109                                 CarryVal = dst & 0x01;\r
1110                                 dst = (dst >> 1) + (CF << 15);\r
1111                         }\r
1112                         PutbackRMWord(ModRM, dst);\r
1113                         break;\r
1114                 case 2: /* RCL ew, count */\r
1115                         for(; count > 0; count--) {\r
1116                                 dst = (dst << 1) + CF;\r
1117                                 SetCFW(dst);\r
1118                         }\r
1119                         PutbackRMWord(ModRM, dst);\r
1120                         break;\r
1121                 case 3: /* RCR ew, count */\r
1122                         for(; count > 0; count--) {\r
1123                                 dst = dst + (CF << 16);\r
1124                                 CarryVal = dst & 0x01;\r
1125                                 dst >>= 1;\r
1126                         }\r
1127                         PutbackRMWord(ModRM, dst);\r
1128                         break;\r
1129                 case 4: /* SHL ew, count */\r
1130                 case 6:\r
1131                         dst <<= count;\r
1132                         SetCFW(dst);\r
1133                         AuxVal = 1;\r
1134                         SetSZPF_Word(dst);\r
1135                         PutbackRMWord(ModRM, dst);\r
1136                         break;\r
1137                 case 5: /* SHR ew, count */\r
1138                         dst >>= count - 1;\r
1139                         CarryVal = dst & 0x01;\r
1140                         dst >>= 1;\r
1141                         SetSZPF_Word(dst);\r
1142                         AuxVal = 1;\r
1143                         PutbackRMWord(ModRM, dst);\r
1144                         break;\r
1145                 case 7: /* SAR ew, count */\r
1146                         dst = ((int16)dst) >> (count - 1);\r
1147                         CarryVal = dst & 0x01;\r
1148                         dst = ((int16)((uint16)dst)) >> 1;\r
1149                         SetSZPF_Word(dst);\r
1150                         AuxVal = 1;\r
1151                         PutbackRMWord(ModRM, dst);\r
1152                         break;\r
1153                 default:\r
1154                         //__assume(0);\r
1155                         break;\r
1156                 }\r
1157         }\r
1158 }\r
1159 \r
1160 void I86::instruction(uint8 code)\r
1161 {\r
1162         prevpc = pc - 1;\r
1163         \r
1164         switch(code) {\r
1165         case 0x00: _add_br8(); break;\r
1166         case 0x01: _add_wr16(); break;\r
1167         case 0x02: _add_r8b(); break;\r
1168         case 0x03: _add_r16w(); break;\r
1169         case 0x04: _add_ald8(); break;\r
1170         case 0x05: _add_axd16(); break;\r
1171         case 0x06: _push_es(); break;\r
1172         case 0x07: _pop_es(); break;\r
1173         case 0x08: _or_br8(); break;\r
1174         case 0x09: _or_wr16(); break;\r
1175         case 0x0a: _or_r8b(); break;\r
1176         case 0x0b: _or_r16w(); break;\r
1177         case 0x0c: _or_ald8(); break;\r
1178         case 0x0d: _or_axd16(); break;\r
1179         case 0x0e: _push_cs(); break;\r
1180 #if defined(HAS_V30)\r
1181         case 0x0f: _0fpre(); break;\r
1182 #else\r
1183         case 0x0f: _invalid(); break;\r
1184 #endif\r
1185         case 0x10: _adc_br8(); break;\r
1186         case 0x11: _adc_wr16(); break;\r
1187         case 0x12: _adc_r8b(); break;\r
1188         case 0x13: _adc_r16w(); break;\r
1189         case 0x14: _adc_ald8(); break;\r
1190         case 0x15: _adc_axd16(); break;\r
1191         case 0x16: _push_ss(); break;\r
1192         case 0x17: _pop_ss(); break;\r
1193         case 0x18: _sbb_br8(); break;\r
1194         case 0x19: _sbb_wr16(); break;\r
1195         case 0x1a: _sbb_r8b(); break;\r
1196         case 0x1b: _sbb_r16w(); break;\r
1197         case 0x1c: _sbb_ald8(); break;\r
1198         case 0x1d: _sbb_axd16(); break;\r
1199         case 0x1e: _push_ds(); break;\r
1200         case 0x1f: _pop_ds(); break;\r
1201         case 0x20: _and_br8(); break;\r
1202         case 0x21: _and_wr16(); break;\r
1203         case 0x22: _and_r8b(); break;\r
1204         case 0x23: _and_r16w(); break;\r
1205         case 0x24: _and_ald8(); break;\r
1206         case 0x25: _and_axd16(); break;\r
1207         case 0x26: _es(); break;\r
1208         case 0x27: _daa(); break;\r
1209         case 0x28: _sub_br8(); break;\r
1210         case 0x29: _sub_wr16(); break;\r
1211         case 0x2a: _sub_r8b(); break;\r
1212         case 0x2b: _sub_r16w(); break;\r
1213         case 0x2c: _sub_ald8(); break;\r
1214         case 0x2d: _sub_axd16(); break;\r
1215         case 0x2e: _cs(); break;\r
1216         case 0x2f: _das(); break;\r
1217         case 0x30: _xor_br8(); break;\r
1218         case 0x31: _xor_wr16(); break;\r
1219         case 0x32: _xor_r8b(); break;\r
1220         case 0x33: _xor_r16w(); break;\r
1221         case 0x34: _xor_ald8(); break;\r
1222         case 0x35: _xor_axd16(); break;\r
1223         case 0x36: _ss(); break;\r
1224         case 0x37: _aaa(); break;\r
1225         case 0x38: _cmp_br8(); break;\r
1226         case 0x39: _cmp_wr16(); break;\r
1227         case 0x3a: _cmp_r8b(); break;\r
1228         case 0x3b: _cmp_r16w(); break;\r
1229         case 0x3c: _cmp_ald8(); break;\r
1230         case 0x3d: _cmp_axd16(); break;\r
1231         case 0x3e: _ds(); break;\r
1232         case 0x3f: _aas(); break;\r
1233         case 0x40: _inc_ax(); break;\r
1234         case 0x41: _inc_cx(); break;\r
1235         case 0x42: _inc_dx(); break;\r
1236         case 0x43: _inc_bx(); break;\r
1237         case 0x44: _inc_sp(); break;\r
1238         case 0x45: _inc_bp(); break;\r
1239         case 0x46: _inc_si(); break;\r
1240         case 0x47: _inc_di(); break;\r
1241         case 0x48: _dec_ax(); break;\r
1242         case 0x49: _dec_cx(); break;\r
1243         case 0x4a: _dec_dx(); break;\r
1244         case 0x4b: _dec_bx(); break;\r
1245         case 0x4c: _dec_sp(); break;\r
1246         case 0x4d: _dec_bp(); break;\r
1247         case 0x4e: _dec_si(); break;\r
1248         case 0x4f: _dec_di(); break;\r
1249         case 0x50: _push_ax(); break;\r
1250         case 0x51: _push_cx(); break;\r
1251         case 0x52: _push_dx(); break;\r
1252         case 0x53: _push_bx(); break;\r
1253         case 0x54: _push_sp(); break;\r
1254         case 0x55: _push_bp(); break;\r
1255         case 0x56: _push_si(); break;\r
1256         case 0x57: _push_di(); break;\r
1257         case 0x58: _pop_ax(); break;\r
1258         case 0x59: _pop_cx(); break;\r
1259         case 0x5a: _pop_dx(); break;\r
1260         case 0x5b: _pop_bx(); break;\r
1261         case 0x5c: _pop_sp(); break;\r
1262         case 0x5d: _pop_bp(); break;\r
1263         case 0x5e: _pop_si(); break;\r
1264         case 0x5f: _pop_di(); break;\r
1265 #if defined(HAS_V30)\r
1266         case 0x60: _pusha(); break;\r
1267         case 0x61: _popa(); break;\r
1268         case 0x62: _bound(); break;\r
1269 #else\r
1270         case 0x60: _invalid(); break;\r
1271         case 0x61: _invalid(); break;\r
1272         case 0x62: _invalid(); break;\r
1273 #endif\r
1274         case 0x63: _invalid(); break;\r
1275 #if defined(HAS_V30)\r
1276         case 0x64: _repc(0); break;\r
1277         case 0x65: _repc(1); break;\r
1278 #else\r
1279         case 0x64: _invalid(); break;\r
1280         case 0x65: _invalid(); break;\r
1281 #endif\r
1282         case 0x66: _invalid(); break;\r
1283         case 0x67: _invalid(); break;\r
1284 #if defined(HAS_V30)\r
1285         case 0x68: _push_d16(); break;\r
1286         case 0x69: _imul_d16(); break;\r
1287         case 0x6a: _push_d8(); break;\r
1288         case 0x6b: _imul_d8(); break;\r
1289         case 0x6c: _insb(); break;\r
1290         case 0x6d: _insw(); break;\r
1291         case 0x6e: _outsb(); break;\r
1292         case 0x6f: _outsw(); break;\r
1293 #else\r
1294         case 0x68: _invalid(); break;\r
1295         case 0x69: _invalid(); break;\r
1296         case 0x6a: _invalid(); break;\r
1297         case 0x6b: _invalid(); break;\r
1298         case 0x6c: _invalid(); break;\r
1299         case 0x6d: _invalid(); break;\r
1300         case 0x6e: _invalid(); break;\r
1301         case 0x6f: _invalid(); break;\r
1302 #endif\r
1303         case 0x70: _jo(); break;\r
1304         case 0x71: _jno(); break;\r
1305         case 0x72: _jb(); break;\r
1306         case 0x73: _jnb(); break;\r
1307         case 0x74: _jz(); break;\r
1308         case 0x75: _jnz(); break;\r
1309         case 0x76: _jbe(); break;\r
1310         case 0x77: _jnbe(); break;\r
1311         case 0x78: _js(); break;\r
1312         case 0x79: _jns(); break;\r
1313         case 0x7a: _jp(); break;\r
1314         case 0x7b: _jnp(); break;\r
1315         case 0x7c: _jl(); break;\r
1316         case 0x7d: _jnl(); break;\r
1317         case 0x7e: _jle(); break;\r
1318         case 0x7f: _jnle(); break;\r
1319         case 0x80: _80pre(); break;\r
1320         case 0x81: _81pre(); break;\r
1321         case 0x82: _82pre(); break;\r
1322         case 0x83: _83pre(); break;\r
1323         case 0x84: _test_br8(); break;\r
1324         case 0x85: _test_wr16(); break;\r
1325         case 0x86: _xchg_br8(); break;\r
1326         case 0x87: _xchg_wr16(); break;\r
1327         case 0x88: _mov_br8(); break;\r
1328         case 0x89: _mov_wr16(); break;\r
1329         case 0x8a: _mov_r8b(); break;\r
1330         case 0x8b: _mov_r16w(); break;\r
1331         case 0x8c: _mov_wsreg(); break;\r
1332         case 0x8d: _lea(); break;\r
1333         case 0x8e: _mov_sregw(); break;\r
1334         case 0x8f: _popw(); break;\r
1335         case 0x90: _nop(); break;\r
1336         case 0x91: _xchg_axcx(); break;\r
1337         case 0x92: _xchg_axdx(); break;\r
1338         case 0x93: _xchg_axbx(); break;\r
1339         case 0x94: _xchg_axsp(); break;\r
1340         case 0x95: _xchg_axbp(); break;\r
1341         case 0x96: _xchg_axsi(); break;\r
1342         case 0x97: _xchg_axdi(); break;\r
1343         case 0x98: _cbw(); break;\r
1344         case 0x99: _cwd(); break;\r
1345         case 0x9a: _call_far(); break;\r
1346         case 0x9b: _wait(); break;\r
1347         case 0x9c: _pushf(); break;\r
1348         case 0x9d: _popf(); break;\r
1349         case 0x9e: _sahf(); break;\r
1350         case 0x9f: _lahf(); break;\r
1351         case 0xa0: _mov_aldisp(); break;\r
1352         case 0xa1: _mov_axdisp(); break;\r
1353         case 0xa2: _mov_dispal(); break;\r
1354         case 0xa3: _mov_dispax(); break;\r
1355         case 0xa4: _movsb(); break;\r
1356         case 0xa5: _movsw(); break;\r
1357         case 0xa6: _cmpsb(); break;\r
1358         case 0xa7: _cmpsw(); break;\r
1359         case 0xa8: _test_ald8(); break;\r
1360         case 0xa9: _test_axd16(); break;\r
1361         case 0xaa: _stosb(); break;\r
1362         case 0xab: _stosw(); break;\r
1363         case 0xac: _lodsb(); break;\r
1364         case 0xad: _lodsw(); break;\r
1365         case 0xae: _scasb(); break;\r
1366         case 0xaf: _scasw(); break;\r
1367         case 0xb0: _mov_ald8(); break;\r
1368         case 0xb1: _mov_cld8(); break;\r
1369         case 0xb2: _mov_dld8(); break;\r
1370         case 0xb3: _mov_bld8(); break;\r
1371         case 0xb4: _mov_ahd8(); break;\r
1372         case 0xb5: _mov_chd8(); break;\r
1373         case 0xb6: _mov_dhd8(); break;\r
1374         case 0xb7: _mov_bhd8(); break;\r
1375         case 0xb8: _mov_axd16(); break;\r
1376         case 0xb9: _mov_cxd16(); break;\r
1377         case 0xba: _mov_dxd16(); break;\r
1378         case 0xbb: _mov_bxd16(); break;\r
1379         case 0xbc: _mov_spd16(); break;\r
1380         case 0xbd: _mov_bpd16(); break;\r
1381         case 0xbe: _mov_sid16(); break;\r
1382         case 0xbf: _mov_did16(); break;\r
1383 #if defined(HAS_V30)\r
1384         case 0xc0: _rotshft_bd8(); break;\r
1385         case 0xc1: _rotshft_wd8(); break;\r
1386 #else\r
1387         case 0xc0: _invalid(); break;\r
1388         case 0xc1: _invalid(); break;\r
1389 #endif\r
1390         case 0xc2: _ret_d16(); break;\r
1391         case 0xc3: _ret(); break;\r
1392         case 0xc4: _les_dw(); break;\r
1393         case 0xc5: _lds_dw(); break;\r
1394         case 0xc6: _mov_bd8(); break;\r
1395         case 0xc7: _mov_wd16(); break;\r
1396 #if defined(HAS_V30)\r
1397         case 0xc8: _enter(); break;\r
1398         case 0xc9: _leav(); break;      /* _leave() */\r
1399 #else\r
1400         case 0xc8: _invalid(); break;\r
1401         case 0xc9: _invalid(); break;\r
1402 #endif\r
1403         case 0xca: _retf_d16(); break;\r
1404         case 0xcb: _retf(); break;\r
1405         case 0xcc: _int3(); break;\r
1406         case 0xcd: _int(); break;\r
1407         case 0xce: _into(); break;\r
1408         case 0xcf: _iret(); break;\r
1409         case 0xd0: _rotshft_b(); break;\r
1410         case 0xd1: _rotshft_w(); break;\r
1411         case 0xd2: _rotshft_bcl(); break;\r
1412         case 0xd3: _rotshft_wcl(); break;\r
1413         case 0xd4: _aam(); break;\r
1414         case 0xd5: _aad(); break;\r
1415 #if defined(HAS_V30)\r
1416         case 0xd6: _setalc(); break;\r
1417 #else\r
1418         case 0xd6: _invalid(); break;\r
1419 #endif\r
1420         case 0xd7: _xlat(); break;\r
1421         case 0xd8: _escape(); break;\r
1422         case 0xd9: _escape(); break;\r
1423         case 0xda: _escape(); break;\r
1424         case 0xdb: _escape(); break;\r
1425         case 0xdc: _escape(); break;\r
1426         case 0xdd: _escape(); break;\r
1427         case 0xde: _escape(); break;\r
1428         case 0xdf: _escape(); break;\r
1429         case 0xe0: _loopne(); break;\r
1430         case 0xe1: _loope(); break;\r
1431         case 0xe2: _loop(); break;\r
1432         case 0xe3: _jcxz(); break;\r
1433         case 0xe4: _inal(); break;\r
1434         case 0xe5: _inax(); break;\r
1435         case 0xe6: _outal(); break;\r
1436         case 0xe7: _outax(); break;\r
1437         case 0xe8: _call_d16(); break;\r
1438         case 0xe9: _jmp_d16(); break;\r
1439         case 0xea: _jmp_far(); break;\r
1440         case 0xeb: _jmp_d8(); break;\r
1441         case 0xec: _inaldx(); break;\r
1442         case 0xed: _inaxdx(); break;\r
1443         case 0xee: _outdxal(); break;\r
1444         case 0xef: _outdxax(); break;\r
1445         case 0xf0: _lock(); break;\r
1446         case 0xf1: _invalid(); break;\r
1447         case 0xf2: _repne(); break;\r
1448         case 0xf3: _repe(); break;\r
1449         case 0xf4: _hlt(); break;\r
1450         case 0xf5: _cmc(); break;\r
1451         case 0xf6: _f6pre(); break;\r
1452         case 0xf7: _f7pre(); break;\r
1453         case 0xf8: _clc(); break;\r
1454         case 0xf9: _stc(); break;\r
1455         case 0xfa: _cli(); break;\r
1456         case 0xfb: _sti(); break;\r
1457         case 0xfc: _cld(); break;\r
1458         case 0xfd: _std(); break;\r
1459         case 0xfe: _fepre(); break;\r
1460         case 0xff: _ffpre(); break;\r
1461         default: _add_br8(); break;\r
1462         //default: __assume(0);\r
1463         }\r
1464 }\r
1465 \r
1466 inline void I86::_add_br8()    /* Opcode 0x00 */\r
1467 {\r
1468         DEF_br8(dst, src);\r
1469         icount -= (ModRM >= 0xc0) ? timing.alu_rr8 : timing.alu_mr8;\r
1470         ADDB(dst, src);\r
1471         PutbackRMByte(ModRM, dst);\r
1472 }\r
1473 \r
1474 inline void I86::_add_wr16()    /* Opcode 0x01 */\r
1475 {\r
1476         DEF_wr16(dst, src);\r
1477         icount -= (ModRM >= 0xc0) ? timing.alu_rr16 : timing.alu_mr16;\r
1478         ADDW(dst, src);\r
1479         PutbackRMWord(ModRM, dst);\r
1480 }\r
1481 \r
1482 inline void I86::_add_r8b()    /* Opcode 0x02 */\r
1483 {\r
1484         DEF_r8b(dst, src);\r
1485         icount -= (ModRM >= 0xc0) ? timing.alu_rr8 : timing.alu_rm8;\r
1486         ADDB(dst, src);\r
1487         RegByte(ModRM) = dst;\r
1488 }\r
1489 \r
1490 inline void I86::_add_r16w()    /* Opcode 0x03 */\r
1491 {\r
1492         DEF_r16w(dst, src);\r
1493         icount -= (ModRM >= 0xc0) ? timing.alu_rr16 : timing.alu_rm16;\r
1494         ADDW(dst, src);\r
1495         RegWord(ModRM) = dst;\r
1496 }\r
1497 \r
1498 inline void I86::_add_ald8()    /* Opcode 0x04 */\r
1499 {\r
1500         DEF_ald8(dst, src);\r
1501         icount -= timing.alu_ri8;\r
1502         ADDB(dst, src);\r
1503         regs.b[AL] = dst;\r
1504 }\r
1505 \r
1506 inline void I86::_add_axd16()    /* Opcode 0x05 */\r
1507 {\r
1508         DEF_axd16(dst, src);\r
1509         icount -= timing.alu_ri16;\r
1510         ADDW(dst, src);\r
1511         regs.w[AX] = dst;\r
1512 }\r
1513 \r
1514 inline void I86::_push_es()    /* Opcode 0x06 */\r
1515 {\r
1516         icount -= timing.push_seg;\r
1517         PUSH(sregs[ES]);\r
1518 }\r
1519 \r
1520 inline void I86::_pop_es()    /* Opcode 0x07 */\r
1521 {\r
1522         POP(sregs[ES]);\r
1523         base[ES] = SegBase(ES);\r
1524         icount -= timing.pop_seg;\r
1525 }\r
1526 \r
1527 inline void I86::_or_br8()    /* Opcode 0x08 */\r
1528 {\r
1529         DEF_br8(dst, src);\r
1530         icount -= (ModRM >= 0xc0) ? timing.alu_rr8 : timing.alu_mr8;\r
1531         ORB(dst, src);\r
1532         PutbackRMByte(ModRM, dst);\r
1533 }\r
1534 \r
1535 inline void I86::_or_wr16()    /* Opcode 0x09 */\r
1536 {\r
1537         DEF_wr16(dst, src);\r
1538         icount -= (ModRM >= 0xc0) ? timing.alu_rr16 : timing.alu_mr16;\r
1539         ORW(dst, src);\r
1540         PutbackRMWord(ModRM, dst);\r
1541 }\r
1542 \r
1543 inline void I86::_or_r8b()    /* Opcode 0x0a */\r
1544 {\r
1545         DEF_r8b(dst, src);\r
1546         icount -= (ModRM >= 0xc0) ? timing.alu_rr8 : timing.alu_rm8;\r
1547         ORB(dst, src);\r
1548         RegByte(ModRM) = dst;\r
1549 }\r
1550 \r
1551 inline void I86::_or_r16w()    /* Opcode 0x0b */\r
1552 {\r
1553         DEF_r16w(dst, src);\r
1554         icount -= (ModRM >= 0xc0) ? timing.alu_rr16 : timing.alu_rm16;\r
1555         ORW(dst, src);\r
1556         RegWord(ModRM) = dst;\r
1557 }\r
1558 \r
1559 inline void I86::_or_ald8()    /* Opcode 0x0c */\r
1560 {\r
1561         DEF_ald8(dst, src);\r
1562         icount -= timing.alu_ri8;\r
1563         ORB(dst, src);\r
1564         regs.b[AL] = dst;\r
1565 }\r
1566 \r
1567 inline void I86::_or_axd16()    /* Opcode 0x0d */\r
1568 {\r
1569         DEF_axd16(dst, src);\r
1570         icount -= timing.alu_ri16;\r
1571         ORW(dst, src);\r
1572         regs.w[AX] = dst;\r
1573 }\r
1574 \r
1575 inline void I86::_push_cs()    /* Opcode 0x0e */\r
1576 {\r
1577         icount -= timing.push_seg;\r
1578         PUSH(sregs[CS]);\r
1579 }\r
1580 \r
1581 #if defined(HAS_V30)\r
1582 inline void I86::_0fpre()    /* Opcode 0x0f */\r
1583 {\r
1584         static const uint16 bytes[] = {\r
1585                 1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096, 8192, 16384, 32768\r
1586         };\r
1587         unsigned code = FETCH;\r
1588         unsigned ModRM;\r
1589         unsigned tmp;\r
1590         unsigned tmp2;\r
1591         \r
1592         switch(code) {\r
1593         case 0x10:  /* 0F 10 47 30 - TEST1 [bx+30h], cl */\r
1594                 ModRM = FETCH;\r
1595                 if(ModRM >= 0xc0) {\r
1596                         tmp = regs.b[Mod_RM.RM.b[ModRM]];\r
1597                         icount -= 3;\r
1598                 } else {\r
1599                         int old = icount;\r
1600                         GetEA(ModRM);\r
1601                         tmp = ReadByte(ea);\r
1602                         icount = old - 12;\r
1603                 }\r
1604                 tmp2 = regs.b[CL] & 7;\r
1605                 SetZF(tmp & bytes[tmp2]);\r
1606                 break;\r
1607         case 0x11:  /* 0F 11 47 30 - TEST1 [bx+30h], cl */\r
1608                 ModRM = FETCH;\r
1609                 if(ModRM >= 0xc0) {\r
1610                         tmp = regs.w[Mod_RM.RM.w[ModRM]];\r
1611                         icount -= 3;\r
1612                 } else {\r
1613                         int old = icount;\r
1614                         GetEA(ModRM);\r
1615                         tmp = ReadWord(ea);\r
1616                         icount = old - 12;\r
1617                 }\r
1618                 tmp2 = regs.b[CL] & 0xf;\r
1619                 SetZF(tmp & bytes[tmp2]);\r
1620                 break;\r
1621         case 0x12:  /* 0F 12 [mod:000:r/m] - CLR1 reg/m8, cl */\r
1622                 ModRM = FETCH;\r
1623                 if(ModRM >= 0xc0) {\r
1624                         tmp = regs.b[Mod_RM.RM.b[ModRM]];\r
1625                         icount -= 5;\r
1626                 } else {\r
1627                         int old = icount;\r
1628                         GetEA(ModRM);\r
1629                         tmp = ReadByte(ea);\r
1630                         icount = old - 14;\r
1631                 }\r
1632                 tmp2 = regs.b[CL] & 7;\r
1633                 tmp &= ~bytes[tmp2];\r
1634                 PutbackRMByte(ModRM, tmp);\r
1635                 break;\r
1636         case 0x13:  /* 0F 13 [mod:000:r/m] - CLR1 reg/m16, cl */\r
1637                 ModRM = FETCH;\r
1638                 if(ModRM >= 0xc0) {\r
1639                         tmp = regs.w[Mod_RM.RM.w[ModRM]];\r
1640                         icount -= 5;\r
1641                 } else {\r
1642                         int old = icount;\r
1643                         GetEA(ModRM);\r
1644                         tmp = ReadWord(ea);\r
1645                         icount = old - 14;\r
1646                 }\r
1647                 tmp2 = regs.b[CL] & 0xf;\r
1648                 tmp &= ~bytes[tmp2];\r
1649                 PutbackRMWord(ModRM, tmp);\r
1650                 break;\r
1651         case 0x14:  /* 0F 14 47 30 - SET1 [bx+30h], cl */\r
1652                 ModRM = FETCH;\r
1653                 if(ModRM >= 0xc0) {\r
1654                         tmp = regs.b[Mod_RM.RM.b[ModRM]];\r
1655                         icount -= 4;\r
1656                 } else {\r
1657                         int old = icount;\r
1658                         GetEA(ModRM);\r
1659                         tmp = ReadByte(ea);\r
1660                         icount = old - 13;\r
1661                 }\r
1662                 tmp2 = regs.b[CL] & 7;\r
1663                 tmp |= bytes[tmp2];\r
1664                 PutbackRMByte(ModRM, tmp);\r
1665                 break;\r
1666         case 0x15:  /* 0F 15 C6 - SET1 si, cl */\r
1667                 ModRM = FETCH;\r
1668                 if(ModRM >= 0xc0) {\r
1669                         tmp = regs.w[Mod_RM.RM.w[ModRM]];\r
1670                         icount -= 4;\r
1671                 } else {\r
1672                         int old = icount;\r
1673                         GetEA(ModRM);\r
1674                         tmp = ReadWord(ea);\r
1675                         icount = old - 13;\r
1676                 }\r
1677                 tmp2 = regs.b[CL] & 0xf;\r
1678                 tmp |= bytes[tmp2];\r
1679                 PutbackRMWord(ModRM, tmp);\r
1680                 break;\r
1681         case 0x16:  /* 0F 16 C6 - NOT1 si, cl */\r
1682                 ModRM = FETCH;\r
1683                 if(ModRM >= 0xc0) {\r
1684                         tmp = regs.b[Mod_RM.RM.b[ModRM]];\r
1685                         icount -= 4;\r
1686                 } else {\r
1687                         int old = icount;\r
1688                         GetEA(ModRM);\r
1689                         tmp = ReadByte(ea);\r
1690                         icount = old - 18;\r
1691                 }\r
1692                 tmp2 = regs.b[CL] & 7;\r
1693                 if(tmp & bytes[tmp2]) {\r
1694                         tmp &= ~bytes[tmp2];\r
1695                 } else {\r
1696                         tmp |= bytes[tmp2];\r
1697                 }\r
1698                 PutbackRMByte(ModRM, tmp);\r
1699                 break;\r
1700         case 0x17:  /* 0F 17 C6 - NOT1 si, cl */\r
1701                 ModRM = FETCH;\r
1702                 if(ModRM >= 0xc0) {\r
1703                         tmp = regs.w[Mod_RM.RM.w[ModRM]];\r
1704                         icount -= 4;\r
1705                 } else {\r
1706                         int old = icount;\r
1707                         GetEA(ModRM);\r
1708                         tmp = ReadWord(ea);\r
1709                         icount = old - 18;\r
1710                 }\r
1711                 tmp2 = regs.b[CL] & 0xf;\r
1712                 if(tmp & bytes[tmp2]) {\r
1713                         tmp &= ~bytes[tmp2];\r
1714                 } else {\r
1715                         tmp |= bytes[tmp2];\r
1716                 }\r
1717                 PutbackRMWord(ModRM, tmp);\r
1718                 break;\r
1719         case 0x18:  /* 0F 18 XX - TEST1 [bx+30h], 07 */\r
1720                 ModRM = FETCH;\r
1721                 if(ModRM >= 0xc0) {\r
1722                         tmp = regs.b[Mod_RM.RM.b[ModRM]];\r
1723                         icount -= 4;\r
1724                 } else {\r
1725                         int old = icount;\r
1726                         GetEA(ModRM);\r
1727                         tmp = ReadByte(ea);\r
1728                         icount = old - 13;\r
1729                 }\r
1730                 tmp2 = FETCH;\r
1731                 tmp2 &= 0xf;\r
1732                 SetZF(tmp & bytes[tmp2]);\r
1733                 break;\r
1734         case 0x19:  /* 0F 19 XX - TEST1 [bx+30h], 07 */\r
1735                 ModRM = FETCH;\r
1736                 if(ModRM >= 0xc0) {\r
1737                         tmp = regs.w[Mod_RM.RM.w[ModRM]];\r
1738                         icount -= 4;\r
1739                 } else {\r
1740                         int old = icount;\r
1741                         GetEA(ModRM);\r
1742                         tmp = ReadWord(ea);\r
1743                         icount = old - 13;\r
1744                 }\r
1745                 tmp2 = FETCH;\r
1746                 tmp2 &= 0xf;\r
1747                 SetZF(tmp & bytes[tmp2]);\r
1748                 break;\r
1749         case 0x1a:  /* 0F 1A 06 - CLR1 si, cl */\r
1750                 ModRM = FETCH;\r
1751                 if(ModRM >= 0xc0) {\r
1752                         tmp = regs.b[Mod_RM.RM.b[ModRM]];\r
1753                         icount -= 6;\r
1754                 } else {\r
1755                         int old = icount;\r
1756                         GetEA(ModRM);\r
1757                         tmp = ReadByte(ea);\r
1758                         icount = old - 15;\r
1759                 }\r
1760                 tmp2 = FETCH;\r
1761                 tmp2 &= 7;\r
1762                 tmp &= ~bytes[tmp2];\r
1763                 PutbackRMByte(ModRM, tmp);\r
1764                 break;\r
1765         case 0x1B:  /* 0F 1B 06 - CLR1 si, cl */\r
1766                 ModRM = FETCH;\r
1767                 if(ModRM >= 0xc0) {\r
1768                         tmp = regs.w[Mod_RM.RM.w[ModRM]];\r
1769                         icount -= 6;\r
1770                 } else {\r
1771                         int old = icount;\r
1772                         GetEA(ModRM);\r
1773                         tmp = ReadWord(ea);\r
1774                         icount = old - 15;\r
1775                 }\r
1776                 tmp2 = FETCH;\r
1777                 tmp2 &= 0xf;\r
1778                 tmp &= ~bytes[tmp2];\r
1779                 PutbackRMWord(ModRM, tmp);\r
1780                 break;\r
1781         case 0x1C:  /* 0F 1C 47 30 - SET1 [bx+30h], cl */\r
1782                 ModRM = FETCH;\r
1783                 if(ModRM >= 0xc0) {\r
1784                         tmp = regs.b[Mod_RM.RM.b[ModRM]];\r
1785                         icount -= 5;\r
1786                 } else {\r
1787                         int old = icount;\r
1788                         GetEA(ModRM);\r
1789                         tmp = ReadByte(ea);\r
1790                         icount = old - 14;\r
1791                 }\r
1792                 tmp2 = FETCH;\r
1793                 tmp2 &= 7;\r
1794                 tmp |= bytes[tmp2];\r
1795                 PutbackRMByte(ModRM, tmp);\r
1796                 break;\r
1797         case 0x1D:  /* 0F 1D C6 - SET1 si, cl */\r
1798                 ModRM = FETCH;\r
1799                 if(ModRM >= 0xc0) {\r
1800                         tmp = regs.w[Mod_RM.RM.w[ModRM]];\r
1801                         icount -= 5;\r
1802                 } else {\r
1803                         int old = icount;\r
1804                         GetEA(ModRM);\r
1805                         tmp = ReadWord(ea);\r
1806                         icount = old - 14;\r
1807                 }\r
1808                 tmp2 = FETCH;\r
1809                 tmp2 &= 0xf;\r
1810                 tmp |= bytes[tmp2];\r
1811                 PutbackRMWord(ModRM, tmp);\r
1812                 break;\r
1813         case 0x1e:  /* 0F 1e C6 - NOT1 si, 07 */\r
1814                 ModRM = FETCH;\r
1815                 if(ModRM >= 0xc0) {\r
1816                         tmp = regs.b[Mod_RM.RM.b[ModRM]];\r
1817                         icount -= 5;\r
1818                 } else {\r
1819                         int old = icount;\r
1820                         GetEA(ModRM);\r
1821                         tmp = ReadByte(ea);\r
1822                         icount = old - 19;\r
1823                 }\r
1824                 tmp2 = FETCH;\r
1825                 tmp2 &= 7;\r
1826                 if(tmp & bytes[tmp2]) {\r
1827                         tmp &= ~bytes[tmp2];\r
1828                 } else {\r
1829                         tmp |= bytes[tmp2];\r
1830                 }\r
1831                 PutbackRMByte(ModRM, tmp);\r
1832                 break;\r
1833         case 0x1f:  /* 0F 1f C6 - NOT1 si, 07 */\r
1834                 ModRM = FETCH;\r
1835                 if(ModRM >= 0xc0) {\r
1836                         tmp = regs.w[Mod_RM.RM.w[ModRM]];\r
1837                         icount -= 5;\r
1838                 } else {\r
1839                         int old = icount;\r
1840                         GetEA(ModRM);\r
1841                         tmp = ReadWord(ea);\r
1842                         icount = old - 19;\r
1843                 }\r
1844                 tmp2 = FETCH;\r
1845                 tmp2 &= 0xf;\r
1846                 if(tmp & bytes[tmp2]) {\r
1847                         tmp &= ~bytes[tmp2];\r
1848                 } else {\r
1849                         tmp |= bytes[tmp2];\r
1850                 }\r
1851                 PutbackRMWord(ModRM, tmp);\r
1852                 break;\r
1853         case 0x20:  /* 0F 20 59 - add4s */\r
1854                 {\r
1855                         /* length in words ! */\r
1856                         int count = (regs.b[CL] + 1) / 2;\r
1857                         unsigned di = regs.w[DI];\r
1858                         unsigned si = regs.w[SI];\r
1859                         \r
1860                         ZeroVal = 1;\r
1861                         CarryVal = 0;   /* NOT ADC */\r
1862                         for(int i = 0; i < count; i++) {\r
1863                                 tmp = GetMemB(DS, si);\r
1864                                 tmp2 = GetMemB(ES, di);\r
1865                                 int v1 = (tmp >> 4) * 10 + (tmp & 0xf);\r
1866                                 int v2 = (tmp2 >> 4) * 10 + (tmp2 & 0xf);\r
1867                                 int result = v1 + v2 + CarryVal;\r
1868                                 CarryVal = result > 99 ? 1 : 0;\r
1869                                 result = result % 100;\r
1870                                 v1 = ((result / 10) << 4) | (result % 10);\r
1871                                 PutMemB(ES, di, v1);\r
1872                                 if(v1) {\r
1873                                         ZeroVal = 0;\r
1874                                 }\r
1875                                 si++;\r
1876                                 di++;\r
1877                         }\r
1878                         OverVal = CarryVal;\r
1879                         icount -= 7 + 19 * count;\r
1880                 }\r
1881                 break;\r
1882         case 0x22:  /* 0F 22 59 - sub4s */\r
1883                 {\r
1884                         int count = (regs.b[CL] + 1) / 2;\r
1885                         unsigned di = regs.w[DI];\r
1886                         unsigned si = regs.w[SI];\r
1887                         \r
1888                         ZeroVal = 1;\r
1889                         CarryVal = 0;  /* NOT ADC */\r
1890                         for(int i = 0; i < count; i++) {\r
1891                                 tmp = GetMemB(ES, di);\r
1892                                 tmp2 = GetMemB(DS, si);\r
1893                                 int v1 = (tmp >> 4) * 10 + (tmp & 0xf);\r
1894                                 int v2 = (tmp2 >> 4) * 10 + (tmp2 & 0xf), result;\r
1895                                 if(v1 < (v2 + CarryVal)) {\r
1896                                         v1 += 100;\r
1897                                         result = v1 - (v2 + CarryVal);\r
1898                                         CarryVal = 1;\r
1899                                 } else {\r
1900                                         result = v1 - (v2 + CarryVal);\r
1901                                         CarryVal = 0;\r
1902                                 }\r
1903                                 v1 = ((result / 10) << 4) | (result % 10);\r
1904                                 PutMemB(ES, di, v1);\r
1905                                 if(v1) {\r
1906                                         ZeroVal = 0;\r
1907                                 }\r
1908                                 si++;\r
1909                                 di++;\r
1910                         }\r
1911                         OverVal = CarryVal;\r
1912                         icount -= 7 + 19 * count;\r
1913                 }\r
1914                 break;\r
1915         case 0x25:\r
1916                 icount -= 16;\r
1917                 break;\r
1918         case 0x26:  /* 0F 22 59 - cmp4s */\r
1919                 {\r
1920                         int count = (regs.b[CL] + 1) / 2;\r
1921                         unsigned di = regs.w[DI];\r
1922                         unsigned si = regs.w[SI];\r
1923                         \r
1924                         ZeroVal = 1;\r
1925                         CarryVal = 0;   /* NOT ADC */\r
1926                         for(int i = 0; i < count; i++) {\r
1927                                 tmp = GetMemB(ES, di);\r
1928                                 tmp2 = GetMemB(DS, si);\r
1929                                 int v1 = (tmp >> 4) * 10 + (tmp & 0xf);\r
1930                                 int v2 = (tmp2 >> 4) * 10 + (tmp2 & 0xf), result;\r
1931                                 if(v1 < (v2 + CarryVal)) {\r
1932                                         v1 += 100;\r
1933                                         result = v1 - (v2 + CarryVal);\r
1934                                         CarryVal = 1;\r
1935                                 } else {\r
1936                                         result = v1 - (v2 + CarryVal);\r
1937                                         CarryVal = 0;\r
1938                                 }\r
1939                                 v1 = ((result / 10) << 4) | (result % 10);\r
1940                                 /* PutMemB(ES, di, v1); /* no store, only compare */\r
1941                                 if(v1) {\r
1942                                         ZeroVal = 0;\r
1943                                 }\r
1944                                 si++;\r
1945                                 di++;\r
1946                         }\r
1947                         OverVal = CarryVal;\r
1948                         icount -= 7 + 19 * (regs.b[CL] + 1);\r
1949                 }\r
1950                 break;\r
1951         case 0x28:  /* 0F 28 C7 - ROL4 bh */\r
1952                 ModRM = FETCH;\r
1953                 if(ModRM >= 0xc0) {\r
1954                         tmp = regs.b[Mod_RM.RM.b[ModRM]];\r
1955                         icount -= 25;\r
1956                 } else {\r
1957                         int old = icount;\r
1958                         GetEA(ModRM);\r
1959                         tmp = ReadByte(ea);\r
1960                         icount = old - 28;\r
1961                 }\r
1962                 tmp <<= 4;\r
1963                 tmp |= regs.b[AL] & 0xf;\r
1964                 regs.b[AL] = (regs.b[AL] & 0xf0) | ((tmp >> 8) & 0xf);\r
1965                 tmp &= 0xff;\r
1966                 PutbackRMByte(ModRM, tmp);\r
1967                 break;\r
1968         case 0x29:  /* 0F 29 C7 - ROL4 bx */\r
1969                 ModRM = FETCH;\r
1970                 break;\r
1971         case 0x2A:  /* 0F 2a c2 - ROR4 bh */\r
1972                 ModRM = FETCH;\r
1973                 if(ModRM >= 0xc0) {\r
1974                         tmp = regs.b[Mod_RM.RM.b[ModRM]];\r
1975                         icount -= 29;\r
1976                 } else {\r
1977                         int old = icount;\r
1978                         GetEA(ModRM);\r
1979                         tmp = ReadByte(ea);\r
1980                         icount = old - 33;\r
1981                 }\r
1982                 tmp2 = (regs.b[AL] & 0xf) << 4;\r
1983                 regs.b[AL] = (regs.b[AL] & 0xf0) | (tmp & 0xf);\r
1984                 tmp = tmp2 | (tmp >> 4);\r
1985                 PutbackRMByte(ModRM, tmp);\r
1986                 break;\r
1987         case 0x2B:  /* 0F 2b c2 - ROR4 bx */\r
1988                 ModRM = FETCH;\r
1989                 break;\r
1990         case 0x2D:  /* 0Fh 2Dh < 1111 1RRR> */\r
1991                 ModRM = FETCH;\r
1992                 icount -= 15;\r
1993                 break;\r
1994         case 0x31:  /* 0F 31 [mod:reg:r/m] - INS reg8, reg8 or INS reg8, imm4 */\r
1995                 ModRM = FETCH;\r
1996                 if(ModRM >= 0xc0) {\r
1997                         tmp = regs.b[Mod_RM.RM.b[ModRM]];\r
1998                         icount -= 29;\r
1999                 } else {\r
2000                         int old = icount;\r
2001                         GetEA(ModRM);\r
2002                         tmp = ReadByte(ea);\r
2003                         icount = old - 33;\r
2004                 }\r
2005                 break;\r
2006         case 0x33:  /* 0F 33 [mod:reg:r/m] - EXT reg8, reg8 or EXT reg8, imm4 */\r
2007                 ModRM = FETCH;\r
2008                 if(ModRM >= 0xc0) {\r
2009                         tmp = regs.b[Mod_RM.RM.b[ModRM]];\r
2010                         icount -= 29;\r
2011                 } else {\r
2012                         int old = icount;\r
2013                         GetEA(ModRM);\r
2014                         tmp = ReadByte(ea);\r
2015                         icount = old - 33;\r
2016                 }\r
2017                 break;\r
2018         case 0x91:\r
2019                 icount -= 12;\r
2020                 break;\r
2021         case 0x94:\r
2022                 ModRM = FETCH;\r
2023                 icount -= 11;\r
2024                 break;\r
2025         case 0x95:\r
2026                 ModRM = FETCH;\r
2027                 icount -= 11;\r
2028                 break;\r
2029         case 0xbe:\r
2030                 icount -= 2;\r
2031                 break;\r
2032         case 0xe0:\r
2033                 ModRM = FETCH;\r
2034                 icount -= 12;\r
2035                 break;\r
2036         case 0xf0:\r
2037                 ModRM = FETCH;\r
2038                 icount -= 12;\r
2039                 break;\r
2040         case 0xff:  /* 0F ff imm8 - BRKEM */\r
2041                 ModRM = FETCH;\r
2042                 icount -= 38;\r
2043                 interrupt(ModRM);\r
2044                 break;\r
2045         }\r
2046 }\r
2047 #endif\r
2048 \r
2049 inline void I86::_adc_br8()    /* Opcode 0x10 */\r
2050 {\r
2051         DEF_br8(dst, src);\r
2052         icount -= (ModRM >= 0xc0) ? timing.alu_rr8 : timing.alu_mr8;\r
2053         src += CF;\r
2054         ADDB(dst, src);\r
2055         PutbackRMByte(ModRM, dst);\r
2056 }\r
2057 \r
2058 inline void I86::_adc_wr16()    /* Opcode 0x11 */\r
2059 {\r
2060         DEF_wr16(dst, src);\r
2061         icount -= (ModRM >= 0xc0) ? timing.alu_rr16 : timing.alu_mr16;\r
2062         src += CF;\r
2063         ADDW(dst, src);\r
2064         PutbackRMWord(ModRM, dst);\r
2065 }\r
2066 \r
2067 inline void I86::_adc_r8b()    /* Opcode 0x12 */\r
2068 {\r
2069         DEF_r8b(dst, src);\r
2070         icount -= (ModRM >= 0xc0) ? timing.alu_rr8 : timing.alu_rm8;\r
2071         src += CF;\r
2072         ADDB(dst, src);\r
2073         RegByte(ModRM) = dst;\r
2074 }\r
2075 \r
2076 inline void I86::_adc_r16w()    /* Opcode 0x13 */\r
2077 {\r
2078         DEF_r16w(dst, src);\r
2079         icount -= (ModRM >= 0xc0) ? timing.alu_rr16 : timing.alu_rm16;\r
2080         src += CF;\r
2081         ADDW(dst, src);\r
2082         RegWord(ModRM) = dst;\r
2083 }\r
2084 \r
2085 inline void I86::_adc_ald8()    /* Opcode 0x14 */\r
2086 {\r
2087         DEF_ald8(dst, src);\r
2088         icount -= timing.alu_ri8;\r
2089         src += CF;\r
2090         ADDB(dst, src);\r
2091         regs.b[AL] = dst;\r
2092 }\r
2093 \r
2094 inline void I86::_adc_axd16()    /* Opcode 0x15 */\r
2095 {\r
2096         DEF_axd16(dst, src);\r
2097         icount -= timing.alu_ri16;\r
2098         src += CF;\r
2099         ADDW(dst, src);\r
2100         regs.w[AX] = dst;\r
2101 }\r
2102 \r
2103 inline void I86::_push_ss()    /* Opcode 0x16 */\r
2104 {\r
2105         PUSH(sregs[SS]);\r
2106         icount -= timing.push_seg;\r
2107 }\r
2108 \r
2109 inline void I86::_pop_ss()    /* Opcode 0x17 */\r
2110 {\r
2111         POP(sregs[SS]);\r
2112         base[SS] = SegBase(SS);\r
2113         icount -= timing.pop_seg;\r
2114         instruction(FETCHOP); /* no interrupt before next instruction */\r
2115 }\r
2116 \r
2117 inline void I86::_sbb_br8()    /* Opcode 0x18 */\r
2118 {\r
2119         DEF_br8(dst, src);\r
2120         icount -= (ModRM >= 0xc0) ? timing.alu_rr8 : timing.alu_mr8;\r
2121         src += CF;\r
2122         SUBB(dst, src);\r
2123         PutbackRMByte(ModRM, dst);\r
2124 }\r
2125 \r
2126 inline void I86::_sbb_wr16()    /* Opcode 0x19 */\r
2127 {\r
2128         DEF_wr16(dst, src);\r
2129         icount -= (ModRM >= 0xc0) ? timing.alu_rr16 : timing.alu_mr16;\r
2130         src += CF;\r
2131         SUBW(dst, src);\r
2132         PutbackRMWord(ModRM, dst);\r
2133 }\r
2134 \r
2135 inline void I86::_sbb_r8b()    /* Opcode 0x1a */\r
2136 {\r
2137         DEF_r8b(dst, src);\r
2138         icount -= (ModRM >= 0xc0) ? timing.alu_rr8 : timing.alu_rm8;\r
2139         src += CF;\r
2140         SUBB(dst, src);\r
2141         RegByte(ModRM) = dst;\r
2142 }\r
2143 \r
2144 inline void I86::_sbb_r16w()    /* Opcode 0x1b */\r
2145 {\r
2146         DEF_r16w(dst, src);\r
2147         icount -= (ModRM >= 0xc0) ? timing.alu_rr16 : timing.alu_rm16;\r
2148         src += CF;\r
2149         SUBW(dst, src);\r
2150         RegWord(ModRM) = dst;\r
2151 }\r
2152 \r
2153 inline void I86::_sbb_ald8()    /* Opcode 0x1c */\r
2154 {\r
2155         DEF_ald8(dst, src);\r
2156         icount -= timing.alu_ri8;\r
2157         src += CF;\r
2158         SUBB(dst, src);\r
2159         regs.b[AL] = dst;\r
2160 }\r
2161 \r
2162 inline void I86::_sbb_axd16()    /* Opcode 0x1d */\r
2163 {\r
2164         DEF_axd16(dst, src);\r
2165         icount -= timing.alu_ri16;\r
2166         src += CF;\r
2167         SUBW(dst, src);\r
2168         regs.w[AX] = dst;\r
2169 }\r
2170 \r
2171 inline void I86::_push_ds()    /* Opcode 0x1e */\r
2172 {\r
2173         PUSH(sregs[DS]);\r
2174         icount -= timing.push_seg;\r
2175 }\r
2176 \r
2177 inline void I86::_pop_ds()    /* Opcode 0x1f */\r
2178 {\r
2179         POP(sregs[DS]);\r
2180         base[DS] = SegBase(DS);\r
2181         icount -= timing.push_seg;\r
2182 }\r
2183 \r
2184 inline void I86::_and_br8()    /* Opcode 0x20 */\r
2185 {\r
2186         DEF_br8(dst, src);\r
2187         icount -= (ModRM >= 0xc0) ? timing.alu_rr8 : timing.alu_mr8;\r
2188         ANDB(dst, src);\r
2189         PutbackRMByte(ModRM, dst);\r
2190 }\r
2191 \r
2192 inline void I86::_and_wr16()    /* Opcode 0x21 */\r
2193 {\r
2194         DEF_wr16(dst, src);\r
2195         icount -= (ModRM >= 0xc0) ? timing.alu_rr16 : timing.alu_mr16;\r
2196         ANDW(dst, src);\r
2197         PutbackRMWord(ModRM, dst);\r
2198 }\r
2199 \r
2200 inline void I86::_and_r8b()    /* Opcode 0x22 */\r
2201 {\r
2202         DEF_r8b(dst, src);\r
2203         icount -= (ModRM >= 0xc0) ? timing.alu_rr8 : timing.alu_rm8;\r
2204         ANDB(dst, src);\r
2205         RegByte(ModRM) = dst;\r
2206 }\r
2207 \r
2208 inline void I86::_and_r16w()    /* Opcode 0x23 */\r
2209 {\r
2210         DEF_r16w(dst, src);\r
2211         icount -= (ModRM >= 0xc0) ? timing.alu_rr16 : timing.alu_rm16;\r
2212         ANDW(dst, src);\r
2213         RegWord(ModRM) = dst;\r
2214 }\r
2215 \r
2216 inline void I86::_and_ald8()    /* Opcode 0x24 */\r
2217 {\r
2218         DEF_ald8(dst, src);\r
2219         icount -= timing.alu_ri8;\r
2220         ANDB(dst, src);\r
2221         regs.b[AL] = dst;\r
2222 }\r
2223 \r
2224 inline void I86::_and_axd16()    /* Opcode 0x25 */\r
2225 {\r
2226         DEF_axd16(dst, src);\r
2227         icount -= timing.alu_ri16;\r
2228         ANDW(dst, src);\r
2229         regs.w[AX] = dst;\r
2230 }\r
2231 \r
2232 inline void I86::_es()    /* Opcode 0x26 */\r
2233 {\r
2234         seg_prefix = true;\r
2235         prefix_seg = ES;\r
2236         icount -= timing.override;\r
2237         instruction(FETCHOP);\r
2238 }\r
2239 \r
2240 inline void I86::_daa()    /* Opcode 0x27 */\r
2241 {\r
2242         if(AF || ((regs.b[AL] & 0xf) > 9)) {\r
2243                 int tmp;\r
2244                 regs.b[AL] = tmp = regs.b[AL] + 6;\r
2245                 AuxVal = 1;\r
2246                 CarryVal |= tmp & 0x100;\r
2247         }\r
2248         \r
2249         if(CF || (regs.b[AL] > 0x9f)) {\r
2250                 regs.b[AL] += 0x60;\r
2251                 CarryVal = 1;\r
2252         }\r
2253         \r
2254         SetSZPF_Byte(regs.b[AL]);\r
2255         icount -= timing.daa;\r
2256 }\r
2257 \r
2258 inline void I86::_sub_br8()    /* Opcode 0x28 */\r
2259 {\r
2260         DEF_br8(dst, src);\r
2261         icount -= (ModRM >= 0xc0) ? timing.alu_rr8 : timing.alu_mr8;\r
2262         SUBB(dst, src);\r
2263         PutbackRMByte(ModRM, dst);\r
2264 }\r
2265 \r
2266 inline void I86::_sub_wr16()    /* Opcode 0x29 */\r
2267 {\r
2268         DEF_wr16(dst, src);\r
2269         icount -= (ModRM >= 0xc0) ? timing.alu_rr16 : timing.alu_mr16;\r
2270         SUBW(dst, src);\r
2271         PutbackRMWord(ModRM, dst);\r
2272 }\r
2273 \r
2274 inline void I86::_sub_r8b()    /* Opcode 0x2a */\r
2275 {\r
2276         DEF_r8b(dst, src);\r
2277         icount -= (ModRM >= 0xc0) ? timing.alu_rr8 : timing.alu_rm8;\r
2278         SUBB(dst, src);\r
2279         RegByte(ModRM) = dst;\r
2280 }\r
2281 \r
2282 inline void I86::_sub_r16w()    /* Opcode 0x2b */\r
2283 {\r
2284         DEF_r16w(dst, src);\r
2285         icount -= (ModRM >= 0xc0) ? timing.alu_rr16 : timing.alu_rm16;\r
2286         SUBW(dst, src);\r
2287         RegWord(ModRM) = dst;\r
2288 }\r
2289 \r
2290 inline void I86::_sub_ald8()    /* Opcode 0x2c */\r
2291 {\r
2292         DEF_ald8(dst, src);\r
2293         icount -= timing.alu_ri8;\r
2294         SUBB(dst, src);\r
2295         regs.b[AL] = dst;\r
2296 }\r
2297 \r
2298 inline void I86::_sub_axd16()    /* Opcode 0x2d */\r
2299 {\r
2300         DEF_axd16(dst, src);\r
2301         icount -= timing.alu_ri16;\r
2302         SUBW(dst, src);\r
2303         regs.w[AX] = dst;\r
2304 }\r
2305 \r
2306 inline void I86::_cs()    /* Opcode 0x2e */\r
2307 {\r
2308         seg_prefix = true;\r
2309         prefix_seg = CS;\r
2310         icount -= timing.override;\r
2311         instruction(FETCHOP);\r
2312 }\r
2313 \r
2314 inline void I86::_das()    /* Opcode 0x2f */\r
2315 {\r
2316         uint8 tmpAL = regs.b[AL];\r
2317         if(AF || ((regs.b[AL] & 0xf) > 9)) {\r
2318                 int tmp;\r
2319                 regs.b[AL] = tmp = regs.b[AL] - 6;\r
2320                 AuxVal = 1;\r
2321                 CarryVal |= tmp & 0x100;\r
2322         }\r
2323         \r
2324         if(CF || (tmpAL > 0x9f)) {\r
2325                 regs.b[AL] -= 0x60;\r
2326                 CarryVal = 1;\r
2327         }\r
2328         \r
2329         SetSZPF_Byte(regs.b[AL]);\r
2330         icount -= timing.das;\r
2331 }\r
2332 \r
2333 inline void I86::_xor_br8()    /* Opcode 0x30 */\r
2334 {\r
2335         DEF_br8(dst, src);\r
2336         icount -= (ModRM >= 0xc0) ? timing.alu_rr8 : timing.alu_mr8;\r
2337         XORB(dst, src);\r
2338         PutbackRMByte(ModRM, dst);\r
2339 }\r
2340 \r
2341 inline void I86::_xor_wr16()    /* Opcode 0x31 */\r
2342 {\r
2343         DEF_wr16(dst, src);\r
2344         icount -= (ModRM >= 0xc0) ? timing.alu_rr16 : timing.alu_mr16;\r
2345         XORW(dst, src);\r
2346         PutbackRMWord(ModRM, dst);\r
2347 }\r
2348 \r
2349 inline void I86::_xor_r8b()    /* Opcode 0x32 */\r
2350 {\r
2351         DEF_r8b(dst, src);\r
2352         icount -= (ModRM >= 0xc0) ? timing.alu_rr8 : timing.alu_rm8;\r
2353         XORB(dst, src);\r
2354         RegByte(ModRM) = dst;\r
2355 }\r
2356 \r
2357 inline void I86::_xor_r16w()    /* Opcode 0x33 */\r
2358 {\r
2359         DEF_r16w(dst, src);\r
2360         icount -= (ModRM >= 0xc0) ? timing.alu_rr16 : timing.alu_rm16;\r
2361         XORW(dst, src);\r
2362         RegWord(ModRM) = dst;\r
2363 }\r
2364 \r
2365 inline void I86::_xor_ald8()    /* Opcode 0x34 */\r
2366 {\r
2367         DEF_ald8(dst, src);\r
2368         icount -= timing.alu_ri8;\r
2369         XORB(dst, src);\r
2370         regs.b[AL] = dst;\r
2371 }\r
2372 \r
2373 inline void I86::_xor_axd16()    /* Opcode 0x35 */\r
2374 {\r
2375         DEF_axd16(dst, src);\r
2376         icount -= timing.alu_ri16;\r
2377         XORW(dst, src);\r
2378         regs.w[AX] = dst;\r
2379 }\r
2380 \r
2381 inline void I86::_ss()    /* Opcode 0x36 */\r
2382 {\r
2383         seg_prefix = true;\r
2384         prefix_seg = SS;\r
2385         icount -= timing.override;\r
2386         instruction(FETCHOP);\r
2387 }\r
2388 \r
2389 inline void I86::_aaa()    /* Opcode 0x37 */\r
2390 {\r
2391         uint8 ALcarry = 1;\r
2392         if(regs.b[AL]>0xf9) {\r
2393                 ALcarry = 2;\r
2394         }\r
2395         if(AF || ((regs.b[AL] & 0xf) > 9)) {\r
2396                 regs.b[AL] += 6;\r
2397                 regs.b[AH] += ALcarry;\r
2398                 AuxVal = 1;\r
2399                 CarryVal = 1;\r
2400         } else {\r
2401                 AuxVal = 0;\r
2402                 CarryVal = 0;\r
2403         }\r
2404         regs.b[AL] &= 0x0F;\r
2405         icount -= timing.aaa;\r
2406 }\r
2407 \r
2408 inline void I86::_cmp_br8()    /* Opcode 0x38 */\r
2409 {\r
2410         DEF_br8(dst, src);\r
2411         icount -= (ModRM >= 0xc0) ? timing.alu_rr8 : timing.alu_rm8;\r
2412         SUBB(dst, src);\r
2413 }\r
2414 \r
2415 inline void I86::_cmp_wr16()    /* Opcode 0x39 */\r
2416 {\r
2417         DEF_wr16(dst, src);\r
2418         icount -= (ModRM >= 0xc0) ? timing.alu_rr16 : timing.alu_rm16;\r
2419         SUBW(dst, src);\r
2420 }\r
2421 \r
2422 inline void I86::_cmp_r8b()    /* Opcode 0x3a */\r
2423 {\r
2424         DEF_r8b(dst, src);\r
2425         icount -= (ModRM >= 0xc0) ? timing.alu_rr8 : timing.alu_rm8;\r
2426         SUBB(dst, src);\r
2427 }\r
2428 \r
2429 inline void I86::_cmp_r16w()    /* Opcode 0x3b */\r
2430 {\r
2431         DEF_r16w(dst, src);\r
2432         icount -= (ModRM >= 0xc0) ? timing.alu_rr16 : timing.alu_rm16;\r
2433         SUBW(dst, src);\r
2434 }\r
2435 \r
2436 inline void I86::_cmp_ald8()    /* Opcode 0x3c */\r
2437 {\r
2438         DEF_ald8(dst, src);\r
2439         icount -= timing.alu_ri8;\r
2440         SUBB(dst, src);\r
2441 }\r
2442 \r
2443 inline void I86::_cmp_axd16()    /* Opcode 0x3d */\r
2444 {\r
2445         DEF_axd16(dst, src);\r
2446         icount -= timing.alu_ri16;\r
2447         SUBW(dst, src);\r
2448 }\r
2449 \r
2450 inline void I86::_ds()    /* Opcode 0x3e */\r
2451 {\r
2452         seg_prefix = true;\r
2453         prefix_seg = DS;\r
2454         icount -= timing.override;\r
2455         instruction(FETCHOP);\r
2456 }\r
2457 \r
2458 inline void I86::_aas()    /* Opcode 0x3f */\r
2459 {\r
2460         uint8 ALcarry = 1;\r
2461         if(regs.b[AL] > 0xf9) {\r
2462                 ALcarry = 2;\r
2463         }\r
2464         if(AF || ((regs.b[AL] & 0xf) > 9)) {\r
2465                 regs.b[AL] -= 6;\r
2466                 regs.b[AH] -= 1;\r
2467                 AuxVal = 1;\r
2468                 CarryVal = 1;\r
2469         } else {\r
2470                 AuxVal = 0;\r
2471                 CarryVal = 0;\r
2472         }\r
2473         regs.b[AL] &= 0x0F;\r
2474         icount -= timing.aas;\r
2475 }\r
2476 \r
2477 #define IncWordReg(Reg) { \\r
2478         unsigned tmp = (unsigned)regs.w[Reg]; \\r
2479         unsigned tmp1 = tmp + 1; \\r
2480         SetOFW_Add(tmp1, tmp, 1); \\r
2481         SetAF(tmp1, tmp, 1); \\r
2482         SetSZPF_Word(tmp1); \\r
2483         regs.w[Reg] = tmp1; \\r
2484         icount -= timing.incdec_r16; \\r
2485 }\r
2486 \r
2487 inline void I86::_inc_ax()    /* Opcode 0x40 */\r
2488 {\r
2489         IncWordReg(AX);\r
2490 }\r
2491 \r
2492 inline void I86::_inc_cx()    /* Opcode 0x41 */\r
2493 {\r
2494         IncWordReg(CX);\r
2495 }\r
2496 \r
2497 inline void I86::_inc_dx()    /* Opcode 0x42 */\r
2498 {\r
2499         IncWordReg(DX);\r
2500 }\r
2501 \r
2502 inline void I86::_inc_bx()    /* Opcode 0x43 */\r
2503 {\r
2504         IncWordReg(BX);\r
2505 }\r
2506 \r
2507 inline void I86::_inc_sp()    /* Opcode 0x44 */\r
2508 {\r
2509         IncWordReg(SP);\r
2510 }\r
2511 \r
2512 inline void I86::_inc_bp()    /* Opcode 0x45 */\r
2513 {\r
2514         IncWordReg(BP);\r
2515 }\r
2516 \r
2517 inline void I86::_inc_si()    /* Opcode 0x46 */\r
2518 {\r
2519         IncWordReg(SI);\r
2520 }\r
2521 \r
2522 inline void I86::_inc_di()    /* Opcode 0x47 */\r
2523 {\r
2524         IncWordReg(DI);\r
2525 }\r
2526 \r
2527 #define DecWordReg(Reg) { \\r
2528         unsigned tmp = (unsigned)regs.w[Reg]; \\r
2529         unsigned tmp1 = tmp - 1; \\r
2530         SetOFW_Sub(tmp1, 1, tmp); \\r
2531         SetAF(tmp1, tmp, 1); \\r
2532         SetSZPF_Word(tmp1); \\r
2533         regs.w[Reg] = tmp1; \\r
2534         icount -= timing.incdec_r16; \\r
2535 }\r
2536 \r
2537 inline void I86::_dec_ax()    /* Opcode 0x48 */\r
2538 {\r
2539         DecWordReg(AX);\r
2540 }\r
2541 \r
2542 inline void I86::_dec_cx()    /* Opcode 0x49 */\r
2543 {\r
2544         DecWordReg(CX);\r
2545 }\r
2546 \r
2547 inline void I86::_dec_dx()    /* Opcode 0x4a */\r
2548 {\r
2549         DecWordReg(DX);\r
2550 }\r
2551 \r
2552 inline void I86::_dec_bx()    /* Opcode 0x4b */\r
2553 {\r
2554         DecWordReg(BX);\r
2555 }\r
2556 \r
2557 inline void I86::_dec_sp()    /* Opcode 0x4c */\r
2558 {\r
2559         DecWordReg(SP);\r
2560 }\r
2561 \r
2562 inline void I86::_dec_bp()    /* Opcode 0x4d */\r
2563 {\r
2564         DecWordReg(BP);\r
2565 }\r
2566 \r
2567 inline void I86::_dec_si()    /* Opcode 0x4e */\r
2568 {\r
2569         DecWordReg(SI);\r
2570 }\r
2571 \r
2572 inline void I86::_dec_di()    /* Opcode 0x4f */\r
2573 {\r
2574         DecWordReg(DI);\r
2575 }\r
2576 \r
2577 inline void I86::_push_ax()    /* Opcode 0x50 */\r
2578 {\r
2579         icount -= timing.push_r16;\r
2580         PUSH(regs.w[AX]);\r
2581 }\r
2582 \r
2583 inline void I86::_push_cx()    /* Opcode 0x51 */\r
2584 {\r
2585         icount -= timing.push_r16;\r
2586         PUSH(regs.w[CX]);\r
2587 }\r
2588 \r
2589 inline void I86::_push_dx()    /* Opcode 0x52 */\r
2590 {\r
2591         icount -= timing.push_r16;\r
2592         PUSH(regs.w[DX]);\r
2593 }\r
2594 \r
2595 inline void I86::_push_bx()    /* Opcode 0x53 */\r
2596 {\r
2597         icount -= timing.push_r16;\r
2598         PUSH(regs.w[BX]);\r
2599 }\r
2600 \r
2601 inline void I86::_push_sp()    /* Opcode 0x54 */\r
2602 {\r
2603         unsigned tmp = regs.w[SP];\r
2604         \r
2605         icount -= timing.push_r16;\r
2606         PUSH(tmp - 2);\r
2607 }\r
2608 \r
2609 inline void I86::_push_bp()    /* Opcode 0x55 */\r
2610 {\r
2611         icount -= timing.push_r16;\r
2612         PUSH(regs.w[BP]);\r
2613 }\r
2614 \r
2615 inline void I86::_push_si()    /* Opcode 0x56 */\r
2616 {\r
2617         icount -= timing.push_r16;\r
2618         PUSH(regs.w[SI]);\r
2619 }\r
2620 \r
2621 inline void I86::_push_di()    /* Opcode 0x57 */\r
2622 {\r
2623         icount -= timing.push_r16;\r
2624         PUSH(regs.w[DI]);\r
2625 }\r
2626 \r
2627 inline void I86::_pop_ax()    /* Opcode 0x58 */\r
2628 {\r
2629         icount -= timing.pop_r16;\r
2630         POP(regs.w[AX]);\r
2631 }\r
2632 \r
2633 inline void I86::_pop_cx()    /* Opcode 0x59 */\r
2634 {\r
2635         icount -= timing.pop_r16;\r
2636         POP(regs.w[CX]);\r
2637 }\r
2638 \r
2639 inline void I86::_pop_dx()    /* Opcode 0x5a */\r
2640 {\r
2641         icount -= timing.pop_r16;\r
2642         POP(regs.w[DX]);\r
2643 }\r
2644 \r
2645 inline void I86::_pop_bx()    /* Opcode 0x5b */\r
2646 {\r
2647         icount -= timing.pop_r16;\r
2648         POP(regs.w[BX]);\r
2649 }\r
2650 \r
2651 inline void I86::_pop_sp()    /* Opcode 0x5c */\r
2652 {\r
2653         unsigned tmp;\r
2654         \r
2655         icount -= timing.pop_r16;\r
2656         POP(tmp);\r
2657         regs.w[SP] = tmp;\r
2658 }\r
2659 \r
2660 inline void I86::_pop_bp()    /* Opcode 0x5d */\r
2661 {\r
2662         icount -= timing.pop_r16;\r
2663         POP(regs.w[BP]);\r
2664 }\r
2665 \r
2666 inline void I86::_pop_si()    /* Opcode 0x5e */\r
2667 {\r
2668         icount -= timing.pop_r16;\r
2669         POP(regs.w[SI]);\r
2670 }\r
2671 \r
2672 inline void I86::_pop_di()    /* Opcode 0x5f */\r
2673 {\r
2674         icount -= timing.pop_r16;\r
2675         POP(regs.w[DI]);\r
2676 }\r
2677 \r
2678 inline void I86::_pusha()    /* Opcode 0x60 */\r
2679 {\r
2680         unsigned tmp = regs.w[SP];\r
2681         \r
2682         icount -= timing.pusha;\r
2683         PUSH(regs.w[AX]);\r
2684         PUSH(regs.w[CX]);\r
2685         PUSH(regs.w[DX]);\r
2686         PUSH(regs.w[BX]);\r
2687         PUSH(tmp);\r
2688         PUSH(regs.w[BP]);\r
2689         PUSH(regs.w[SI]);\r
2690         PUSH(regs.w[DI]);\r
2691 }\r
2692 \r
2693 inline void I86::_popa()    /* Opcode 0x61 */\r
2694 {\r
2695         unsigned tmp;\r
2696         \r
2697         icount -= timing.popa;\r
2698         POP(regs.w[DI]);\r
2699         POP(regs.w[SI]);\r
2700         POP(regs.w[BP]);\r
2701         POP(tmp);\r
2702         POP(regs.w[BX]);\r
2703         POP(regs.w[DX]);\r
2704         POP(regs.w[CX]);\r
2705         POP(regs.w[AX]);\r
2706 }\r
2707 \r
2708 inline void I86::_bound()    /* Opcode 0x62 */\r
2709 {\r
2710         unsigned ModRM = FETCHOP;\r
2711         int low = (int16)GetRMWord(ModRM);\r
2712         int high = (int16)GetNextRMWord;\r
2713         int tmp = (int16)RegWord(ModRM);\r
2714         if(tmp < low || tmp>high) {\r
2715                 pc -= (seg_prefix ? 3 : 2);\r
2716                 interrupt(BOUNDS_CHECK_FAULT);\r
2717         }\r
2718         icount -= timing.bound;\r
2719 }\r
2720 \r
2721 inline void I86::_repc(int flagval)\r
2722 {\r
2723 #ifdef HAS_V30\r
2724         unsigned next = FETCHOP;\r
2725         unsigned count = regs.w[CX];\r
2726         \r
2727         switch(next) {\r
2728         case 0x26:      /* ES: */\r
2729                 seg_prefix = true;\r
2730                 prefix_seg = ES;\r
2731                 icount -= 2;\r
2732                 _repc(flagval);\r
2733                 break;\r
2734         case 0x2e:      /* CS: */\r
2735                 seg_prefix = true;\r
2736                 prefix_seg = CS;\r
2737                 icount -= 2;\r
2738                 _repc(flagval);\r
2739                 break;\r
2740         case 0x36:      /* SS: */\r
2741                 seg_prefix = true;\r
2742                 prefix_seg = SS;\r
2743                 icount -= 2;\r
2744                 _repc(flagval);\r
2745                 break;\r
2746         case 0x3e:      /* DS: */\r
2747                 seg_prefix = true;\r
2748                 prefix_seg = DS;\r
2749                 icount -= 2;\r
2750                 _repc(flagval);\r
2751                 break;\r
2752         case 0x6c:      /* REP INSB */\r
2753                 icount -= 9 - count;\r
2754                 for(; (CF == flagval) && (count > 0); count--) {\r
2755                         _insb();\r
2756                 }\r
2757                 regs.w[CX] = count;\r
2758                 break;\r
2759         case 0x6d:      /* REP INSW */\r
2760                 icount -= 9 - count;\r
2761                 for(; (CF == flagval) && (count > 0); count--) {\r
2762                         _insw();\r
2763                 }\r
2764                 regs.w[CX] = count;\r
2765                 break;\r
2766         case 0x6e:      /* REP OUTSB */\r
2767                 icount -= 9 - count;\r
2768                 for(; (CF == flagval) && (count > 0); count--) {\r
2769                         _outsb();\r
2770                 }\r
2771                 regs.w[CX] = count;\r
2772                 break;\r
2773         case 0x6f:      /* REP OUTSW */\r
2774                 icount -= 9 - count;\r
2775                 for(; (CF == flagval) && (count > 0); count--) {\r
2776                         _outsw();\r
2777                 }\r
2778                 regs.w[CX] = count;\r
2779                 break;\r
2780         case 0xa4:      /* REP MOVSB */\r
2781                 icount -= 9 - count;\r
2782                 for(; (CF == flagval) && (count > 0); count--) {\r
2783                         _movsb();\r
2784                 }\r
2785                 regs.w[CX] = count;\r
2786                 break;\r
2787         case 0xa5:      /* REP MOVSW */\r
2788                 icount -= 9 - count;\r
2789                 for(; (CF == flagval) && (count > 0); count--) {\r
2790                         _movsw();\r
2791                 }\r
2792                 regs.w[CX] = count;\r
2793                 break;\r
2794         case 0xa6:      /* REP(N)E CMPSB */\r
2795                 icount -= 9;\r
2796                 for(ZeroVal = !flagval; (ZF == flagval) && (CF == flagval) && (count > 0); count--) {\r
2797                         _cmpsb();\r
2798                 }\r
2799                 regs.w[CX] = count;\r
2800                 break;\r
2801         case 0xa7:      /* REP(N)E CMPSW */\r
2802                 icount -= 9;\r
2803                 for(ZeroVal = !flagval; (ZF == flagval) && (CF == flagval) && (count > 0); count--) {\r
2804                         _cmpsw();\r
2805                 }\r
2806                 regs.w[CX] = count;\r
2807                 break;\r
2808         case 0xaa:      /* REP STOSB */\r
2809                 icount -= 9 - count;\r
2810                 for(; (CF == flagval) && (count > 0); count--) {\r
2811                         _stosb();\r
2812                 }\r
2813                 regs.w[CX] = count;\r
2814                 break;\r
2815         case 0xab:      /* REP STOSW */\r
2816                 icount -= 9 - count;\r
2817                 for(; (CF == flagval) && (count > 0); count--) {\r
2818                         _stosw();\r
2819                 }\r
2820                 regs.w[CX] = count;\r
2821                 break;\r
2822         case 0xac:      /* REP LODSB */\r
2823                 icount -= 9;\r
2824                 for(; (CF == flagval) && (count > 0); count--) {\r
2825                         _lodsb();\r
2826                 }\r
2827                 regs.w[CX] = count;\r
2828                 break;\r
2829         case 0xad:      /* REP LODSW */\r
2830                 icount -= 9;\r
2831                 for(; (CF == flagval) && (count > 0); count--) {\r
2832                         _lodsw();\r
2833                 }\r
2834                 regs.w[CX] = count;\r
2835                 break;\r
2836         case 0xae:      /* REP(N)E SCASB */\r
2837                 icount -= 9;\r
2838                 for(ZeroVal = !flagval; (ZF == flagval) && (CF == flagval) && (count > 0); count--) {\r
2839                         _scasb();\r
2840                 }\r
2841                 regs.w[CX] = count;\r
2842                 break;\r
2843         case 0xaf:      /* REP(N)E SCASW */\r
2844                 icount -= 9;\r
2845                 for(ZeroVal = !flagval; (ZF == flagval) && (CF == flagval) && (count > 0); count--) {\r
2846                         _scasw();\r
2847                 }\r
2848                 regs.w[CX] = count;\r
2849                 break;\r
2850         default:\r
2851                 instruction(next);\r
2852         }\r
2853 #endif\r
2854 }\r
2855 \r
2856 inline void I86::_push_d16()    /* Opcode 0x68 */\r
2857 {\r
2858         unsigned tmp = FETCH;\r
2859         icount -= timing.push_imm;\r
2860         tmp += FETCH << 8;\r
2861         PUSH(tmp);\r
2862 }\r
2863 \r
2864 inline void I86::_imul_d16()    /* Opcode 0x69 */\r
2865 {\r
2866         DEF_r16w(dst, src);\r
2867         unsigned src2 = FETCH;\r
2868         src += (FETCH << 8);\r
2869         icount -= (ModRM >= 0xc0) ? timing.imul_rri16 : timing.imul_rmi16;\r
2870         dst = (int32)((int16)src) * (int32)((int16)src2);\r
2871         CarryVal = OverVal = (((int32)dst) >> 15 != 0) && (((int32)dst) >> 15 != -1);\r
2872         RegWord(ModRM) = (uint16)dst;\r
2873 }\r
2874 \r
2875 inline void I86::_push_d8()    /* Opcode 0x6a */\r
2876 {\r
2877         unsigned tmp = (uint16)((int16)((int8)FETCH));\r
2878         icount -= timing.push_imm;\r
2879         PUSH(tmp);\r
2880 }\r
2881 \r
2882 inline void I86::_imul_d8()    /* Opcode 0x6b */\r
2883 {\r
2884         DEF_r16w(dst, src);\r
2885         unsigned src2 = (uint16)((int16)((int8)FETCH));\r
2886         icount -= (ModRM >= 0xc0) ? timing.imul_rri8 : timing.imul_rmi8;\r
2887         dst = (int32)((int16)src) * (int32)((int16)src2);\r
2888         CarryVal = OverVal = (((int32)dst) >> 15 != 0) && (((int32)dst) >> 15 != -1);\r
2889         RegWord(ModRM) = (uint16)dst;\r
2890 }\r
2891 \r
2892 inline void I86::_insb()    /* Opcode 0x6c */\r
2893 {\r
2894         icount -= timing.ins8;\r
2895         PutMemB(ES, regs.w[DI], read_port_byte(regs.w[DX]));\r
2896         regs.w[DI] += DirVal;\r
2897 }\r
2898 \r
2899 inline void I86::_insw()    /* Opcode 0x6d */\r
2900 {\r
2901         icount -= timing.ins16;\r
2902         PutMemW(ES, regs.w[DI], read_port_word(regs.w[DX]));\r
2903         regs.w[DI] += 2 * DirVal;\r
2904 }\r
2905 \r
2906 inline void I86::_outsb()    /* Opcode 0x6e */\r
2907 {\r
2908         icount -= timing.outs8;\r
2909         write_port_byte(regs.w[DX], GetMemB(DS, regs.w[SI]));\r
2910         regs.w[SI] += DirVal; /* GOL 11/27/01 */\r
2911 }\r
2912 \r
2913 inline void I86::_outsw()    /* Opcode 0x6f */\r
2914 {\r
2915         icount -= timing.outs16;\r
2916         write_port_word(regs.w[DX], GetMemW(DS, regs.w[SI]));\r
2917         regs.w[SI] += 2 * DirVal; /* GOL 11/27/01 */\r
2918 }\r
2919 \r
2920 inline void I86::_jo()    /* Opcode 0x70 */\r
2921 {\r
2922         int tmp = (int)((int8)FETCH);\r
2923         if(OF) {\r
2924                 pc += tmp;\r
2925                 icount -= timing.jcc_t;\r
2926         } else {\r
2927                 icount -= timing.jcc_nt;\r
2928         }\r
2929 }\r
2930 \r
2931 inline void I86::_jno()    /* Opcode 0x71 */\r
2932 {\r
2933         int tmp = (int)((int8)FETCH);\r
2934         if(!OF) {\r
2935                 pc += tmp;\r
2936                 icount -= timing.jcc_t;\r
2937         } else {\r
2938                 icount -= timing.jcc_nt;\r
2939         }\r
2940 }\r
2941 \r
2942 inline void I86::_jb()    /* Opcode 0x72 */\r
2943 {\r
2944         int tmp = (int)((int8)FETCH);\r
2945         if(CF) {\r
2946                 pc += tmp;\r
2947                 icount -= timing.jcc_t;\r
2948         } else {\r
2949                 icount -= timing.jcc_nt;\r
2950         }\r
2951 }\r
2952 \r
2953 inline void I86::_jnb()    /* Opcode 0x73 */\r
2954 {\r
2955         int tmp = (int)((int8)FETCH);\r
2956         if(!CF) {\r
2957                 pc += tmp;\r
2958                 icount -= timing.jcc_t;\r
2959         } else {\r
2960                 icount -= timing.jcc_nt;\r
2961         }\r
2962 }\r
2963 \r
2964 inline void I86::_jz()    /* Opcode 0x74 */\r
2965 {\r
2966         int tmp = (int)((int8)FETCH);\r
2967         if(ZF) {\r
2968                 pc += tmp;\r
2969                 icount -= timing.jcc_t;\r
2970         } else {\r
2971                 icount -= timing.jcc_nt;\r
2972         }\r
2973 }\r
2974 \r
2975 inline void I86::_jnz()    /* Opcode 0x75 */\r
2976 {\r
2977         int tmp = (int)((int8)FETCH);\r
2978         if(!ZF) {\r
2979                 pc += tmp;\r
2980                 icount -= timing.jcc_t;\r
2981         } else {\r
2982                 icount -= timing.jcc_nt;\r
2983         }\r
2984 }\r
2985 \r
2986 inline void I86::_jbe()    /* Opcode 0x76 */\r
2987 {\r
2988         int tmp = (int)((int8)FETCH);\r
2989         if(CF || ZF) {\r
2990                 pc += tmp;\r
2991                 icount -= timing.jcc_t;\r
2992         } else {\r
2993                 icount -= timing.jcc_nt;\r
2994         }\r
2995 }\r
2996 \r
2997 inline void I86::_jnbe()    /* Opcode 0x77 */\r
2998 {\r
2999         int tmp = (int)((int8)FETCH);\r
3000         if(!(CF || ZF)) {\r
3001                 pc += tmp;\r
3002                 icount -= timing.jcc_t;\r
3003         } else {\r
3004                 icount -= timing.jcc_nt;\r
3005         }\r
3006 }\r
3007 \r
3008 inline void I86::_js()    /* Opcode 0x78 */\r
3009 {\r
3010         int tmp = (int)((int8)FETCH);\r
3011         if(SF) {\r
3012                 pc += tmp;\r
3013                 icount -= timing.jcc_t;\r
3014         } else {\r
3015                 icount -= timing.jcc_nt;\r
3016         }\r
3017 }\r
3018 \r
3019 inline void I86::_jns()    /* Opcode 0x79 */\r
3020 {\r
3021         int tmp = (int)((int8)FETCH);\r
3022         if(!SF) {\r
3023                 pc += tmp;\r
3024                 icount -= timing.jcc_t;\r
3025         } else {\r
3026                 icount -= timing.jcc_nt;\r
3027         }\r
3028 }\r
3029 \r
3030 inline void I86::_jp()    /* Opcode 0x7a */\r
3031 {\r
3032         int tmp = (int)((int8)FETCH);\r
3033         if(PF) {\r
3034                 pc += tmp;\r
3035                 icount -= timing.jcc_t;\r
3036         } else {\r
3037                 icount -= timing.jcc_nt;\r
3038         }\r
3039 }\r
3040 \r
3041 inline void I86::_jnp()    /* Opcode 0x7b */\r
3042 {\r
3043         int tmp = (int)((int8)FETCH);\r
3044         if(!PF) {\r
3045                 pc += tmp;\r
3046                 icount -= timing.jcc_t;\r
3047         } else {\r
3048                 icount -= timing.jcc_nt;\r
3049         }\r
3050 }\r
3051 \r
3052 inline void I86::_jl()    /* Opcode 0x7c */\r
3053 {\r
3054         int tmp = (int)((int8)FETCH);\r
3055         if((SF!= OF) && !ZF) {\r
3056                 pc += tmp;\r
3057                 icount -= timing.jcc_t;\r
3058         } else {\r
3059                 icount -= timing.jcc_nt;\r
3060         }\r
3061 }\r
3062 \r
3063 inline void I86::_jnl()    /* Opcode 0x7d */\r
3064 {\r
3065         int tmp = (int)((int8)FETCH);\r
3066         if(ZF || (SF == OF)) {\r
3067                 pc += tmp;\r
3068                 icount -= timing.jcc_t;\r
3069         } else {\r
3070                 icount -= timing.jcc_nt;\r
3071         }\r
3072 }\r
3073 \r
3074 inline void I86::_jle()    /* Opcode 0x7e */\r
3075 {\r
3076         int tmp = (int)((int8)FETCH);\r
3077         if(ZF || (SF!= OF)) {\r
3078                 pc += tmp;\r
3079                 icount -= timing.jcc_t;\r
3080         } else {\r
3081                 icount -= timing.jcc_nt;\r
3082         }\r
3083 }\r
3084 \r
3085 inline void I86::_jnle()    /* Opcode 0x7f */\r
3086 {\r
3087         int tmp = (int)((int8)FETCH);\r
3088         if((SF == OF) && !ZF) {\r
3089                 pc += tmp;\r
3090                 icount -= timing.jcc_t;\r
3091         } else {\r
3092                 icount -= timing.jcc_nt;\r
3093         }\r
3094 }\r
3095 \r
3096 inline void I86::_80pre()    /* Opcode 0x80 */\r
3097 {\r
3098         unsigned ModRM = FETCHOP;\r
3099         unsigned dst = GetRMByte(ModRM);\r
3100         unsigned src = FETCH;\r
3101         \r
3102         switch((ModRM >> 3) & 7) {\r
3103         case 0: /* ADD eb, d8 */\r
3104                 ADDB(dst, src);\r
3105                 PutbackRMByte(ModRM, dst);\r
3106                 icount -= (ModRM >= 0xc0) ? timing.alu_ri8 : timing.alu_mi8;\r
3107                 break;\r
3108         case 1: /* OR eb, d8 */\r
3109                 ORB(dst, src);\r
3110                 PutbackRMByte(ModRM, dst);\r
3111                 icount -= (ModRM >= 0xc0) ? timing.alu_ri8 : timing.alu_mi8;\r
3112                 break;\r
3113         case 2: /* ADC eb, d8 */\r
3114                 src += CF;\r
3115                 ADDB(dst, src);\r
3116                 PutbackRMByte(ModRM, dst);\r
3117                 icount -= (ModRM >= 0xc0) ? timing.alu_ri8 : timing.alu_mi8;\r
3118                 break;\r
3119         case 3: /* SBB eb, b8 */\r
3120                 src += CF;\r
3121                 SUBB(dst, src);\r
3122                 PutbackRMByte(ModRM, dst);\r
3123                 icount -= (ModRM >= 0xc0) ? timing.alu_ri8 : timing.alu_mi8;\r
3124                 break;\r
3125         case 4: /* AND eb, d8 */\r
3126                 ANDB(dst, src);\r
3127                 PutbackRMByte(ModRM, dst);\r
3128                 icount -= (ModRM >= 0xc0) ? timing.alu_ri8 : timing.alu_mi8;\r
3129                 break;\r
3130         case 5: /* SUB eb, d8 */\r
3131                 SUBB(dst, src);\r
3132                 PutbackRMByte(ModRM, dst);\r
3133                 icount -= (ModRM >= 0xc0) ? timing.alu_ri8 : timing.alu_mi8;\r
3134                 break;\r
3135         case 6: /* XOR eb, d8 */\r
3136                 XORB(dst, src);\r
3137                 PutbackRMByte(ModRM, dst);\r
3138                 icount -= (ModRM >= 0xc0) ? timing.alu_ri8 : timing.alu_mi8;\r
3139                 break;\r
3140         case 7: /* CMP eb, d8 */\r
3141                 SUBB(dst, src);\r
3142                 icount -= (ModRM >= 0xc0) ? timing.alu_ri8 : timing.alu_mi8_ro;\r
3143                 break;\r
3144         default:\r
3145                 //__assume(0);\r
3146                 break;\r
3147         }\r
3148 }\r
3149 \r
3150 inline void I86::_81pre()    /* Opcode 0x81 */\r
3151 {\r
3152         unsigned ModRM = FETCH;\r
3153         unsigned dst = GetRMWord(ModRM);\r
3154         unsigned src = FETCH;\r
3155         src += (FETCH << 8);\r
3156         \r
3157         switch((ModRM >> 3) & 7) {\r
3158         case 0: /* ADD ew, d16 */\r
3159                 ADDW(dst, src);\r
3160                 PutbackRMWord(ModRM, dst);\r
3161                 icount -= (ModRM >= 0xc0) ? timing.alu_ri16 : timing.alu_mi16;\r
3162                 break;\r
3163         case 1: /* OR ew, d16 */\r
3164                 ORW(dst, src);\r
3165                 PutbackRMWord(ModRM, dst);\r
3166                 icount -= (ModRM >= 0xc0) ? timing.alu_ri16 : timing.alu_mi16;\r
3167                 break;\r
3168         case 2: /* ADC ew, d16 */\r
3169                 src += CF;\r
3170                 ADDW(dst, src);\r
3171                 PutbackRMWord(ModRM, dst);\r
3172                 icount -= (ModRM >= 0xc0) ? timing.alu_ri16 : timing.alu_mi16;\r
3173                 break;\r
3174         case 3: /* SBB ew, d16 */\r
3175                 src += CF;\r
3176                 SUBW(dst, src);\r
3177                 PutbackRMWord(ModRM, dst);\r
3178                 icount -= (ModRM >= 0xc0) ? timing.alu_ri16 : timing.alu_mi16;\r
3179                 break;\r
3180         case 4: /* AND ew, d16 */\r
3181                 ANDW(dst, src);\r
3182                 PutbackRMWord(ModRM, dst);\r
3183                 icount -= (ModRM >= 0xc0) ? timing.alu_ri16 : timing.alu_mi16;\r
3184                 break;\r
3185         case 5: /* SUB ew, d16 */\r
3186                 SUBW(dst, src);\r
3187                 PutbackRMWord(ModRM, dst);\r
3188                 icount -= (ModRM >= 0xc0) ? timing.alu_ri16 : timing.alu_mi16;\r
3189                 break;\r
3190         case 6: /* XOR ew, d16 */\r
3191                 XORW(dst, src);\r
3192                 PutbackRMWord(ModRM, dst);\r
3193                 icount -= (ModRM >= 0xc0) ? timing.alu_ri16 : timing.alu_mi16;\r
3194                 break;\r
3195         case 7: /* CMP ew, d16 */\r
3196                 SUBW(dst, src);\r
3197                 icount -= (ModRM >= 0xc0) ? timing.alu_ri16 : timing.alu_mi16_ro;\r
3198                 break;\r
3199         default:\r
3200                 //__assume(0);\r
3201                break;\r
3202         }\r
3203 }\r
3204 \r
3205 inline void I86::_82pre()    /* Opcode 0x82 */\r
3206 {\r
3207         unsigned ModRM = FETCH;\r
3208         unsigned dst = GetRMByte(ModRM);\r
3209         unsigned src = FETCH;\r
3210         \r
3211         switch((ModRM >> 3) & 7) {\r
3212         case 0: /* ADD eb, d8 */\r
3213                 ADDB(dst, src);\r
3214                 PutbackRMByte(ModRM, dst);\r
3215                 icount -= (ModRM >= 0xc0) ? timing.alu_ri8 : timing.alu_mi8;\r
3216                 break;\r
3217         case 1: /* OR eb, d8 */\r
3218                 ORB(dst, src);\r
3219                 PutbackRMByte(ModRM, dst);\r
3220                 icount -= (ModRM >= 0xc0) ? timing.alu_ri8 : timing.alu_mi8;\r
3221                 break;\r
3222         case 2: /* ADC eb, d8 */\r
3223                 src += CF;\r
3224                 ADDB(dst, src);\r
3225                 PutbackRMByte(ModRM, dst);\r
3226                 icount -= (ModRM >= 0xc0) ? timing.alu_ri8 : timing.alu_mi8;\r
3227                 break;\r
3228         case 3: /* SBB eb, d8 */\r
3229                 src += CF;\r
3230                 SUBB(dst, src);\r
3231                 PutbackRMByte(ModRM, dst);\r
3232                 icount -= (ModRM >= 0xc0) ? timing.alu_ri8 : timing.alu_mi8;\r
3233                 break;\r
3234         case 4: /* AND eb, d8 */\r
3235                 ANDB(dst, src);\r
3236                 PutbackRMByte(ModRM, dst);\r
3237                 icount -= (ModRM >= 0xc0) ? timing.alu_ri8 : timing.alu_mi8;\r
3238                 break;\r
3239         case 5: /* SUB eb, d8 */\r
3240                 SUBB(dst, src);\r
3241                 PutbackRMByte(ModRM, dst);\r
3242                 icount -= (ModRM >= 0xc0) ? timing.alu_ri8 : timing.alu_mi8;\r
3243                 break;\r
3244         case 6: /* XOR eb, d8 */\r
3245                 XORB(dst, src);\r
3246                 PutbackRMByte(ModRM, dst);\r
3247                 icount -= (ModRM >= 0xc0) ? timing.alu_ri8 : timing.alu_mi8;\r
3248                 break;\r
3249         case 7: /* CMP eb, d8 */\r
3250                 SUBB(dst, src);\r
3251                 icount -= (ModRM >= 0xc0) ? timing.alu_ri8 : timing.alu_mi8_ro;\r
3252                 break;\r
3253         default:\r
3254                 //__assume(0);\r
3255                 break;\r
3256         }\r
3257 }\r
3258 \r
3259 inline void I86::_83pre()    /* Opcode 0x83 */\r
3260 {\r
3261         unsigned ModRM = FETCH;\r
3262         unsigned dst = GetRMWord(ModRM);\r
3263         unsigned src = (uint16)((int16)((int8)FETCH));\r
3264         \r
3265         switch((ModRM >> 3) & 7) {\r
3266         case 0: /* ADD ew, d16 */\r
3267                 ADDW(dst, src);\r
3268                 PutbackRMWord(ModRM, dst);\r
3269                 icount -= (ModRM >= 0xc0) ? timing.alu_r16i8 : timing.alu_m16i8;\r
3270                 break;\r
3271         case 1: /* OR ew, d16 */\r
3272                 ORW(dst, src);\r
3273                 PutbackRMWord(ModRM, dst);\r
3274                 icount -= (ModRM >= 0xc0) ? timing.alu_r16i8 : timing.alu_m16i8;\r
3275                 break;\r
3276         case 2: /* ADC ew, d16 */\r
3277                 src += CF;\r
3278                 ADDW(dst, src);\r
3279                 PutbackRMWord(ModRM, dst);\r
3280                 icount -= (ModRM >= 0xc0) ? timing.alu_r16i8 : timing.alu_m16i8;\r
3281                 break;\r
3282         case 3: /* SBB ew, d16 */\r
3283                 src += CF;\r
3284                 SUBW(dst, src);\r
3285                 PutbackRMWord(ModRM, dst);\r
3286                 icount -= (ModRM >= 0xc0) ? timing.alu_r16i8 : timing.alu_m16i8;\r
3287                 break;\r
3288         case 4: /* AND ew, d16 */\r
3289                 ANDW(dst, src);\r
3290                 PutbackRMWord(ModRM, dst);\r
3291                 icount -= (ModRM >= 0xc0) ? timing.alu_r16i8 : timing.alu_m16i8;\r
3292                 break;\r
3293         case 5: /* SUB ew, d16 */\r
3294                 SUBW(dst, src);\r
3295                 PutbackRMWord(ModRM, dst);\r
3296                 icount -= (ModRM >= 0xc0) ? timing.alu_r16i8 : timing.alu_m16i8;\r
3297                 break;\r
3298         case 6: /* XOR ew, d16 */\r
3299                 XORW(dst, src);\r
3300                 PutbackRMWord(ModRM, dst);\r
3301                 icount -= (ModRM >= 0xc0) ? timing.alu_r16i8 : timing.alu_m16i8;\r
3302                 break;\r
3303         case 7: /* CMP ew, d16 */\r
3304                 SUBW(dst, src);\r
3305                 icount -= (ModRM >= 0xc0) ? timing.alu_r16i8 : timing.alu_m16i8_ro;\r
3306                 break;\r
3307         default:\r
3308                 //__assume(0);\r
3309                 break;\r
3310         }\r
3311 }\r
3312 \r
3313 inline void I86::_test_br8()    /* Opcode 0x84 */\r
3314 {\r
3315         DEF_br8(dst, src);\r
3316         icount -= (ModRM >= 0xc0) ? timing.alu_rr8 : timing.alu_rm8;\r
3317         ANDB(dst, src);\r
3318 }\r
3319 \r
3320 inline void I86::_test_wr16()    /* Opcode 0x85 */\r
3321 {\r
3322         DEF_wr16(dst, src);\r
3323         icount -= (ModRM >= 0xc0) ? timing.alu_rr16 : timing.alu_rm16;\r
3324         ANDW(dst, src);\r
3325 }\r
3326 \r
3327 inline void I86::_xchg_br8()    /* Opcode 0x86 */\r
3328 {\r
3329         DEF_br8(dst, src);\r
3330         icount -= (ModRM >= 0xc0) ? timing.xchg_rr8 : timing.xchg_rm8;\r
3331         RegByte(ModRM) = dst;\r
3332         PutbackRMByte(ModRM, src);\r
3333 }\r
3334 \r
3335 inline void I86::_xchg_wr16()    /* Opcode 0x87 */\r
3336 {\r
3337         DEF_wr16(dst, src);\r
3338         icount -= (ModRM >= 0xc0) ? timing.xchg_rr16 : timing.xchg_rm16;\r
3339         RegWord(ModRM) = dst;\r
3340         PutbackRMWord(ModRM, src);\r
3341 }\r
3342 \r
3343 inline void I86::_mov_br8()    /* Opcode 0x88 */\r
3344 {\r
3345         unsigned ModRM = FETCH;\r
3346         uint8 src = RegByte(ModRM);\r
3347         icount -= (ModRM >= 0xc0) ? timing.mov_rr8 : timing.mov_mr8;\r
3348         PutRMByte(ModRM, src);\r
3349 }\r
3350 \r
3351 inline void I86::_mov_wr16()    /* Opcode 0x89 */\r
3352 {\r
3353         unsigned ModRM = FETCH;\r
3354         uint16 src = RegWord(ModRM);\r
3355         icount -= (ModRM >= 0xc0) ? timing.mov_rr16 : timing.mov_mr16;\r
3356         PutRMWord(ModRM, src);\r
3357 }\r
3358 \r
3359 inline void I86::_mov_r8b()    /* Opcode 0x8a */\r
3360 {\r
3361         unsigned ModRM = FETCH;\r
3362         uint8 src = GetRMByte(ModRM);\r
3363         icount -= (ModRM >= 0xc0) ? timing.mov_rr8 : timing.mov_rm8;\r
3364         RegByte(ModRM) = src;\r
3365 }\r
3366 \r
3367 inline void I86::_mov_r16w()    /* Opcode 0x8b */\r
3368 {\r
3369         unsigned ModRM = FETCH;\r
3370         uint16 src = GetRMWord(ModRM);\r
3371         icount -= (ModRM >= 0xc0) ? timing.mov_rr8 : timing.mov_rm16;\r
3372         RegWord(ModRM) = src;\r
3373 }\r
3374 \r
3375 inline void I86::_mov_wsreg()    /* Opcode 0x8c */\r
3376 {\r
3377         unsigned ModRM = FETCH;\r
3378         icount -= (ModRM >= 0xc0) ? timing.mov_rs : timing.mov_ms;\r
3379         if(ModRM & 0x20) {\r
3380                 return; /* 1xx is invalid */\r
3381         }\r
3382         PutRMWord(ModRM, sregs[(ModRM & 0x38) >> 3]);\r
3383 }\r
3384 \r
3385 inline void I86::_lea()    /* Opcode 0x8d */\r
3386 {\r
3387         unsigned ModRM = FETCH;\r
3388         icount -= timing.lea;\r
3389         GetEA(ModRM);\r
3390         RegWord(ModRM) = eo;    /* effective offset (no segment part) */\r
3391 }\r
3392 \r
3393 inline void I86::_mov_sregw()    /* Opcode 0x8e */\r
3394 {\r
3395         unsigned ModRM = FETCH;\r
3396         uint16 src = GetRMWord(ModRM);\r
3397         \r
3398         icount -= (ModRM >= 0xc0) ? timing.mov_sr : timing.mov_sm;\r
3399         switch((ModRM >> 3) & 7) {\r
3400         case 0:  /* mov es, ew */\r
3401                 sregs[ES] = src;\r
3402                 base[ES] = SegBase(ES);\r
3403                 break;\r
3404         case 1:  /* mov cs, ew */\r
3405                 break;  /* doesn't do a jump far */\r
3406         case 2:  /* mov ss, ew */\r
3407                 sregs[SS] = src;\r
3408                 base[SS] = SegBase(SS); /* no interrupt allowed before next instr */\r
3409                 instruction(FETCHOP);\r
3410                 break;\r
3411         case 3:  /* mov ds, ew */\r
3412                 sregs[DS] = src;\r
3413                 base[DS] = SegBase(DS);\r
3414                 break;\r
3415         case 4:\r
3416         case 5:\r
3417         case 6:\r
3418         case 7:\r
3419                 break;\r
3420         default:\r
3421                 //__assume(0);\r
3422                 break;\r
3423         }\r
3424 }\r
3425 \r
3426 inline void I86::_popw()    /* Opcode 0x8f */\r
3427 {\r
3428         unsigned ModRM = FETCH;\r
3429         uint16 tmp;\r
3430         POP(tmp);\r
3431         icount -= (ModRM >= 0xc0) ? timing.pop_r16 : timing.pop_m16;\r
3432         PutRMWord(ModRM, tmp);\r
3433 }\r
3434 \r
3435 #define XchgAXReg(Reg) { \\r
3436         uint16 tmp; \\r
3437         tmp = regs.w[Reg]; \\r
3438         regs.w[Reg] = regs.w[AX]; \\r
3439         regs.w[AX] = tmp; \\r
3440         icount -= timing.xchg_ar16; \\r
3441 }\r
3442 \r
3443 inline void I86::_nop()    /* Opcode 0x90 */\r
3444 {\r
3445         /* this is XchgAXReg(AX); */\r
3446         icount -= timing.nop;\r
3447 }\r
3448 \r
3449 inline void I86::_xchg_axcx()    /* Opcode 0x91 */\r
3450 {\r
3451         XchgAXReg(CX);\r
3452 }\r
3453 \r
3454 inline void I86::_xchg_axdx()    /* Opcode 0x92 */\r
3455 {\r
3456         XchgAXReg(DX);\r
3457 }\r
3458 \r
3459 inline void I86::_xchg_axbx()    /* Opcode 0x93 */\r
3460 {\r
3461         XchgAXReg(BX);\r
3462 }\r
3463 \r
3464 inline void I86::_xchg_axsp()    /* Opcode 0x94 */\r
3465 {\r
3466         XchgAXReg(SP);\r
3467 }\r
3468 \r
3469 inline void I86::_xchg_axbp()    /* Opcode 0x95 */\r
3470 {\r
3471         XchgAXReg(BP);\r
3472 }\r
3473 \r
3474 inline void I86::_xchg_axsi()    /* Opcode 0x96 */\r
3475 {\r
3476         XchgAXReg(SI);\r
3477 }\r
3478 \r
3479 inline void I86::_xchg_axdi()    /* Opcode 0x97 */\r
3480 {\r
3481         XchgAXReg(DI);\r
3482 }\r
3483 \r
3484 inline void I86::_cbw()    /* Opcode 0x98 */\r
3485 {\r
3486         icount -= timing.cbw;\r
3487         regs.b[AH] = (regs.b[AL] & 0x80) ? 0xff : 0;\r
3488 }\r
3489 \r
3490 inline void I86::_cwd()    /* Opcode 0x99 */\r
3491 {\r
3492         icount -= timing.cwd;\r
3493         regs.w[DX] = (regs.b[AH] & 0x80) ? 0xffff : 0;\r
3494 }\r
3495 \r
3496 inline void I86::_call_far()    /* Opcode 0x9a */\r
3497 {\r
3498         unsigned tmp, tmp2;\r
3499         uint16 ip;\r
3500         \r
3501         tmp = FETCH;\r
3502         tmp += FETCH << 8;\r
3503         \r
3504         tmp2 = FETCH;\r
3505         tmp2 += FETCH << 8;\r
3506         \r
3507         ip = pc - base[CS];\r
3508         PUSH(sregs[CS]);\r
3509         PUSH(ip);\r
3510         sregs[CS] = (uint16)tmp2;\r
3511         base[CS] = SegBase(CS);\r
3512         pc = (base[CS] + (uint16)tmp) & AMASK;\r
3513 #ifdef I86_BIOS_CALL\r
3514         if(d_bios && d_bios->bios_call(pc, regs.w, sregs, &ZeroVal, &CarryVal)) {\r
3515                 /* bios call */\r
3516                 _retf();\r
3517         }\r
3518 #endif\r
3519         icount -= timing.call_far;\r
3520 }\r
3521 \r
3522 inline void I86::_wait()    /* Opcode 0x9b */\r
3523 {\r
3524         if(test_state) {\r
3525                 pc--;\r
3526         }\r
3527         icount -= timing.wait;\r
3528 }\r
3529 \r
3530 inline void I86::_pushf()    /* Opcode 0x9c */\r
3531 {\r
3532         unsigned tmp;\r
3533         icount -= timing.pushf;\r
3534         \r
3535         tmp = CompressFlags();\r
3536         PUSH(tmp | 0xf000);\r
3537 }\r
3538 \r
3539 inline void I86::_popf()    /* Opcode 0x9d */\r
3540 {\r
3541         unsigned tmp;\r
3542         POP(tmp);\r
3543         icount -= timing.popf;\r
3544         ExpandFlags(tmp);\r
3545         \r
3546         if(TF) {\r
3547                 trap();\r
3548         }\r
3549         \r
3550         /* if the IF is set, and an interrupt is pending, signal an interrupt */\r
3551         if(IF && (int_state & INT_REQ_BIT)) {\r
3552                 interrupt(-1);\r
3553         }\r
3554 }\r
3555 \r
3556 inline void I86::_sahf()    /* Opcode 0x9e */\r
3557 {\r
3558         unsigned tmp = (CompressFlags() & 0xff00) | (regs.b[AH] & 0xd5);\r
3559         icount -= timing.sahf;\r
3560         ExpandFlags(tmp);\r
3561 }\r
3562 \r
3563 inline void I86::_lahf()    /* Opcode 0x9f */\r
3564 {\r
3565         regs.b[AH] = CompressFlags() & 0xff;\r
3566         icount -= timing.lahf;\r
3567 }\r
3568 \r
3569 inline void I86::_mov_aldisp()    /* Opcode 0xa0 */\r
3570 {\r
3571         unsigned addr;\r
3572         \r
3573         addr = FETCH;\r
3574         addr += FETCH << 8;\r
3575         \r
3576         icount -= timing.mov_am8;\r
3577         regs.b[AL] = GetMemB(DS, addr);\r
3578 }\r
3579 \r
3580 inline void I86::_mov_axdisp()    /* Opcode 0xa1 */\r
3581 {\r
3582         unsigned addr;\r
3583         \r
3584         addr = FETCH;\r
3585         addr += FETCH << 8;\r
3586         \r
3587         icount -= timing.mov_am16;\r
3588         regs.w[AX] = GetMemW(DS, addr);\r
3589 }\r
3590 \r
3591 inline void I86::_mov_dispal()    /* Opcode 0xa2 */\r
3592 {\r
3593         unsigned addr;\r
3594         \r
3595         addr = FETCH;\r
3596         addr += FETCH << 8;\r
3597         \r
3598         icount -= timing.mov_ma8;\r
3599         PutMemB(DS, addr, regs.b[AL]);\r
3600 }\r
3601 \r
3602 inline void I86::_mov_dispax()    /* Opcode 0xa3 */\r
3603 {\r
3604         unsigned addr;\r
3605         \r
3606         addr = FETCH;\r
3607         addr += FETCH << 8;\r
3608         \r
3609         icount -= timing.mov_ma16;\r
3610         PutMemW(DS, addr, regs.w[AX]);\r
3611 }\r
3612 \r
3613 inline void I86::_movsb()    /* Opcode 0xa4 */\r
3614 {\r
3615         uint8 tmp = GetMemB(DS, regs.w[SI]);\r
3616         PutMemB(ES, regs.w[DI], tmp);\r
3617         regs.w[DI] += DirVal;\r
3618         regs.w[SI] += DirVal;\r
3619         icount -= timing.movs8;\r
3620 }\r
3621 \r
3622 inline void I86::_movsw()    /* Opcode 0xa5 */\r
3623 {\r
3624         uint16 tmp = GetMemW(DS, regs.w[SI]);\r
3625         PutMemW(ES, regs.w[DI], tmp);\r
3626         regs.w[DI] += 2 * DirVal;\r
3627         regs.w[SI] += 2 * DirVal;\r
3628         icount -= timing.movs16;\r
3629 }\r
3630 \r
3631 inline void I86::_cmpsb()    /* Opcode 0xa6 */\r
3632 {\r
3633         unsigned dst = GetMemB(ES, regs.w[DI]);\r
3634         unsigned src = GetMemB(DS, regs.w[SI]);\r
3635         SUBB(src, dst); /* opposite of the usual convention */\r
3636         regs.w[DI] += DirVal;\r
3637         regs.w[SI] += DirVal;\r
3638         icount -= timing.cmps8;\r
3639 }\r
3640 \r
3641 inline void I86::_cmpsw()    /* Opcode 0xa7 */\r
3642 {\r
3643         unsigned dst = GetMemW(ES, regs.w[DI]);\r
3644         unsigned src = GetMemW(DS, regs.w[SI]);\r
3645         SUBW(src, dst); /* opposite of the usual convention */\r
3646         regs.w[DI] += 2 * DirVal;\r
3647         regs.w[SI] += 2 * DirVal;\r
3648         icount -= timing.cmps16;\r
3649 }\r
3650 \r
3651 inline void I86::_test_ald8()    /* Opcode 0xa8 */\r
3652 {\r
3653         DEF_ald8(dst, src);\r
3654         icount -= timing.alu_ri8;\r
3655         ANDB(dst, src);\r
3656 }\r
3657 \r
3658 inline void I86::_test_axd16()    /* Opcode 0xa9 */\r
3659 {\r
3660         DEF_axd16(dst, src);\r
3661         icount -= timing.alu_ri16;\r
3662         ANDW(dst, src);\r
3663 }\r
3664 \r
3665 inline void I86::_stosb()    /* Opcode 0xaa */\r
3666 {\r
3667         PutMemB(ES, regs.w[DI], regs.b[AL]);\r
3668         regs.w[DI] += DirVal;\r
3669         icount -= timing.stos8;\r
3670 }\r
3671 \r
3672 inline void I86::_stosw()    /* Opcode 0xab */\r
3673 {\r
3674         PutMemW(ES, regs.w[DI], regs.w[AX]);\r
3675         regs.w[DI] += 2 * DirVal;\r
3676         icount -= timing.stos16;\r
3677 }\r
3678 \r
3679 inline void I86::_lodsb()    /* Opcode 0xac */\r
3680 {\r
3681         regs.b[AL] = GetMemB(DS, regs.w[SI]);\r
3682         regs.w[SI] += DirVal;\r
3683         icount -= timing.lods8;\r
3684 }\r
3685 \r
3686 inline void I86::_lodsw()    /* Opcode 0xad */\r
3687 {\r
3688         regs.w[AX] = GetMemW(DS, regs.w[SI]);\r
3689         regs.w[SI] += 2 * DirVal;\r
3690         icount -= timing.lods16;\r
3691 }\r
3692 \r
3693 inline void I86::_scasb()    /* Opcode 0xae */\r
3694 {\r
3695         unsigned src = GetMemB(ES, regs.w[DI]);\r
3696         unsigned dst = regs.b[AL];\r
3697         SUBB(dst, src);\r
3698         regs.w[DI] += DirVal;\r
3699         icount -= timing.scas8;\r
3700 }\r
3701 \r
3702 inline void I86::_scasw()    /* Opcode 0xaf */\r
3703 {\r
3704         unsigned src = GetMemW(ES, regs.w[DI]);\r
3705         unsigned dst = regs.w[AX];\r
3706         SUBW(dst, src);\r
3707         regs.w[DI] += 2 * DirVal;\r
3708         icount -= timing.scas16;\r
3709 }\r
3710 \r
3711 inline void I86::_mov_ald8()    /* Opcode 0xb0 */\r
3712 {\r
3713         regs.b[AL] = FETCH;\r
3714         icount -= timing.mov_ri8;\r
3715 }\r
3716 \r
3717 inline void I86::_mov_cld8()    /* Opcode 0xb1 */\r
3718 {\r
3719         regs.b[CL] = FETCH;\r
3720         icount -= timing.mov_ri8;\r
3721 }\r
3722 \r
3723 inline void I86::_mov_dld8()    /* Opcode 0xb2 */\r
3724 {\r
3725         regs.b[DL] = FETCH;\r
3726         icount -= timing.mov_ri8;\r
3727 }\r
3728 \r
3729 inline void I86::_mov_bld8()    /* Opcode 0xb3 */\r
3730 {\r
3731         regs.b[BL] = FETCH;\r
3732         icount -= timing.mov_ri8;\r
3733 }\r
3734 \r
3735 inline void I86::_mov_ahd8()    /* Opcode 0xb4 */\r
3736 {\r
3737         regs.b[AH] = FETCH;\r
3738         icount -= timing.mov_ri8;\r
3739 }\r
3740 \r
3741 inline void I86::_mov_chd8()    /* Opcode 0xb5 */\r
3742 {\r
3743         regs.b[CH] = FETCH;\r
3744         icount -= timing.mov_ri8;\r
3745 }\r
3746 \r
3747 inline void I86::_mov_dhd8()    /* Opcode 0xb6 */\r
3748 {\r
3749         regs.b[DH] = FETCH;\r
3750         icount -= timing.mov_ri8;\r
3751 }\r
3752 \r
3753 inline void I86::_mov_bhd8()    /* Opcode 0xb7 */\r
3754 {\r
3755         regs.b[BH] = FETCH;\r
3756         icount -= timing.mov_ri8;\r
3757 }\r
3758 \r
3759 inline void I86::_mov_axd16()    /* Opcode 0xb8 */\r
3760 {\r
3761         regs.b[AL] = FETCH;\r
3762         regs.b[AH] = FETCH;\r
3763         icount -= timing.mov_ri16;\r
3764 }\r
3765 \r
3766 inline void I86::_mov_cxd16()    /* Opcode 0xb9 */\r
3767 {\r
3768         regs.b[CL] = FETCH;\r
3769         regs.b[CH] = FETCH;\r
3770         icount -= timing.mov_ri16;\r
3771 }\r
3772 \r
3773 inline void I86::_mov_dxd16()    /* Opcode 0xba */\r
3774 {\r
3775         regs.b[DL] = FETCH;\r
3776         regs.b[DH] = FETCH;\r
3777         icount -= timing.mov_ri16;\r
3778 }\r
3779 \r
3780 inline void I86::_mov_bxd16()    /* Opcode 0xbb */\r
3781 {\r
3782         regs.b[BL] = FETCH;\r
3783         regs.b[BH] = FETCH;\r
3784         icount -= timing.mov_ri16;\r
3785 }\r
3786 \r
3787 inline void I86::_mov_spd16()    /* Opcode 0xbc */\r
3788 {\r
3789         regs.b[SPL] = FETCH;\r
3790         regs.b[SPH] = FETCH;\r
3791         icount -= timing.mov_ri16;\r
3792 }\r
3793 \r
3794 inline void I86::_mov_bpd16()    /* Opcode 0xbd */\r
3795 {\r
3796         regs.b[BPL] = FETCH;\r
3797         regs.b[BPH] = FETCH;\r
3798         icount -= timing.mov_ri16;\r
3799 }\r
3800 \r
3801 inline void I86::_mov_sid16()    /* Opcode 0xbe */\r
3802 {\r
3803         regs.b[SIL] = FETCH;\r
3804         regs.b[SIH] = FETCH;\r
3805         icount -= timing.mov_ri16;\r
3806 }\r
3807 \r
3808 inline void I86::_mov_did16()    /* Opcode 0xbf */\r
3809 {\r
3810         regs.b[DIL] = FETCH;\r
3811         regs.b[DIH] = FETCH;\r
3812         icount -= timing.mov_ri16;\r
3813 }\r
3814 \r
3815 inline void I86::_rotshft_bd8()    /* Opcode 0xc0 */\r
3816 {\r
3817         unsigned ModRM = FETCH;\r
3818         unsigned count = FETCH;\r
3819         \r
3820         rotate_shift_byte(ModRM, count);\r
3821 }\r
3822 \r
3823 inline void I86::_rotshft_wd8()    /* Opcode 0xc1 */\r
3824 {\r
3825         unsigned ModRM = FETCH;\r
3826         unsigned count = FETCH;\r
3827         \r
3828         rotate_shift_word(ModRM, count);\r
3829 }\r
3830 \r
3831 inline void I86::_ret_d16()    /* Opcode 0xc2 */\r
3832 {\r
3833         unsigned count = FETCH;\r
3834         count += FETCH << 8;\r
3835         POP(pc);\r
3836         pc = (pc + base[CS]) & AMASK;\r
3837         regs.w[SP] += count;\r
3838         icount -= timing.ret_near_imm;\r
3839 }\r
3840 \r
3841 inline void I86::_ret()    /* Opcode 0xc3 */\r
3842 {\r
3843         POP(pc);\r
3844         pc = (pc + base[CS]) & AMASK;\r
3845         icount -= timing.ret_near;\r
3846 }\r
3847 \r
3848 inline void I86::_les_dw()    /* Opcode 0xc4 */\r
3849 {\r
3850         unsigned ModRM = FETCH;\r
3851         uint16 tmp = GetRMWord(ModRM);\r
3852         RegWord(ModRM) = tmp;\r
3853         sregs[ES] = GetNextRMWord;\r
3854         base[ES] = SegBase(ES);\r
3855         icount -= timing.load_ptr;\r
3856 }\r
3857 \r
3858 inline void I86::_lds_dw()    /* Opcode 0xc5 */\r
3859 {\r
3860         unsigned ModRM = FETCH;\r
3861         uint16 tmp = GetRMWord(ModRM);\r
3862         RegWord(ModRM) = tmp;\r
3863         sregs[DS] = GetNextRMWord;\r
3864         base[DS] = SegBase(DS);\r
3865         icount -= timing.load_ptr;\r
3866 }\r
3867 \r
3868 inline void I86::_mov_bd8()    /* Opcode 0xc6 */\r
3869 {\r
3870         unsigned ModRM = FETCH;\r
3871         icount -= (ModRM >= 0xc0) ? timing.mov_ri8 : timing.mov_mi8;\r
3872         PutImmRMByte(ModRM);\r
3873 }\r
3874 \r
3875 inline void I86::_mov_wd16()    /* Opcode 0xc7 */\r
3876 {\r
3877         unsigned ModRM = FETCH;\r
3878         icount -= (ModRM >= 0xc0) ? timing.mov_ri16 : timing.mov_mi16;\r
3879         PutImmRMWord(ModRM);\r
3880 }\r
3881 \r
3882 inline void I86::_enter()    /* Opcode 0xc8 */\r
3883 {\r
3884         unsigned nb = FETCH;\r
3885         unsigned i, level;\r
3886         \r
3887         nb += FETCH << 8;\r
3888         level = FETCH;\r
3889         icount -= (level == 0) ? timing.enter0 : (level == 1) ? timing.enter1 : timing.enter_base + level * timing.enter_count;\r
3890         PUSH(regs.w[BP]);\r
3891         regs.w[BP] = regs.w[SP];\r
3892         regs.w[SP] -= nb;\r
3893         for(i = 1; i < level; i++) {\r
3894                 PUSH(GetMemW(SS, regs.w[BP] - i * 2));\r
3895         }\r
3896         if(level) {\r
3897                 PUSH(regs.w[BP]);\r
3898         }\r
3899 }\r
3900 \r
3901 inline void I86::_leav()    /* Opcode 0xc9 */\r
3902 {\r
3903         icount -= timing.leave;\r
3904         regs.w[SP] = regs.w[BP];\r
3905         POP(regs.w[BP]);\r
3906 }\r
3907 \r
3908 inline void I86::_retf_d16()    /* Opcode 0xca */\r
3909 {\r
3910         unsigned count = FETCH;\r
3911         count += FETCH << 8;\r
3912         POP(pc);\r
3913         POP(sregs[CS]);\r
3914         base[CS] = SegBase(CS);\r
3915         pc = (pc + base[CS]) & AMASK;\r
3916         regs.w[SP] += count;\r
3917         icount -= timing.ret_far_imm;\r
3918 }\r
3919 \r
3920 inline void I86::_retf()    /* Opcode 0xcb */\r
3921 {\r
3922         POP(pc);\r
3923         POP(sregs[CS]);\r
3924         base[CS] = SegBase(CS);\r
3925         pc = (pc + base[CS]) & AMASK;\r
3926         icount -= timing.ret_far;\r
3927 }\r
3928 \r
3929 inline void I86::_int3()    /* Opcode 0xcc */\r
3930 {\r
3931         icount -= timing.int3;\r
3932         interrupt(3);\r
3933 }\r
3934 \r
3935 inline void I86::_int()    /* Opcode 0xcd */\r
3936 {\r
3937         unsigned int_num = FETCH;\r
3938         icount -= timing.int_imm;\r
3939 #ifdef I86_BIOS_CALL\r
3940         if(d_bios && d_bios->bios_int(int_num, regs.w, sregs, &ZeroVal, &CarryVal)) {\r
3941                 /* bios call */\r
3942                 return;\r
3943         }\r
3944 #endif\r
3945         interrupt(int_num);\r
3946 }\r
3947 \r
3948 inline void I86::_into()    /* Opcode 0xce */\r
3949 {\r
3950         if(OF) {\r
3951                 icount -= timing.into_t;\r
3952                 interrupt(OVERFLOW_TRAP);\r
3953         } else {\r
3954                 icount -= timing.into_nt;\r
3955         }\r
3956 }\r
3957 \r
3958 inline void I86::_iret()    /* Opcode 0xcf */\r
3959 {\r
3960         icount -= timing.iret;\r
3961         POP(pc);\r
3962         POP(sregs[CS]);\r
3963         base[CS] = SegBase(CS);\r
3964         pc = (pc + base[CS]) & AMASK;\r
3965         _popf();\r
3966         \r
3967         /* if the IF is set, and an interrupt is pending, signal an interrupt */\r
3968         if(IF && (int_state & INT_REQ_BIT)) {\r
3969                 interrupt(-1);\r
3970         }\r
3971 }\r
3972 \r
3973 inline void I86::_rotshft_b()    /* Opcode 0xd0 */\r
3974 {\r
3975         rotate_shift_byte(FETCHOP, 1);\r
3976 }\r
3977 \r
3978 inline void I86::_rotshft_w()    /* Opcode 0xd1 */\r
3979 {\r
3980         rotate_shift_word(FETCHOP, 1);\r
3981 }\r
3982 \r
3983 inline void I86::_rotshft_bcl()    /* Opcode 0xd2 */\r
3984 {\r
3985         rotate_shift_byte(FETCHOP, regs.b[CL]);\r
3986 }\r
3987 \r
3988 inline void I86::_rotshft_wcl()    /* Opcode 0xd3 */\r
3989 {\r
3990         rotate_shift_word(FETCHOP, regs.b[CL]);\r
3991 }\r
3992 \r
3993 /* OB: Opcode works on NEC V-Series but not the Variants        */\r
3994 /*     one could specify any byte value as operand but the NECs */\r
3995 /*     always substitute 0x0a.                                  */\r
3996 inline void I86::_aam()    /* Opcode 0xd4 */\r
3997 {\r
3998         unsigned mult = FETCH;\r
3999         icount -= timing.aam;\r
4000         if(mult == 0) {\r
4001                 interrupt(DIVIDE_FAULT);\r
4002         } else {\r
4003                 regs.b[AH] = regs.b[AL] / mult;\r
4004                 regs.b[AL] %= mult;\r
4005                 SetSZPF_Word(regs.w[AX]);\r
4006         }\r
4007 }\r
4008 \r
4009 inline void I86::_aad()    /* Opcode 0xd5 */\r
4010 {\r
4011         unsigned mult = FETCH;\r
4012         icount -= timing.aad;\r
4013         regs.b[AL] = regs.b[AH] * mult + regs.b[AL];\r
4014         regs.b[AH] = 0;\r
4015         SetZF(regs.b[AL]);\r
4016         SetPF(regs.b[AL]);\r
4017         SignVal = 0;\r
4018 }\r
4019 \r
4020 inline void I86::_setalc()    /* Opcode 0xd6 */\r
4021 {\r
4022         regs.b[AL] = (CF) ? 0xff : 0x00;\r
4023         icount -= 3;\r
4024 }\r
4025 \r
4026 inline void I86::_xlat()    /* Opcode 0xd7 */\r
4027 {\r
4028         unsigned dest = regs.w[BX] + regs.b[AL];\r
4029         icount -= timing.xlat;\r
4030         regs.b[AL] = GetMemB(DS, dest);\r
4031 }\r
4032 \r
4033 inline void I86::_escape()    /* Opcodes 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde and 0xdf */\r
4034 {\r
4035         unsigned ModRM = FETCH;\r
4036         icount -= timing.nop;\r
4037         GetRMByte(ModRM);\r
4038 }\r
4039 \r
4040 inline void I86::_loopne()    /* Opcode 0xe0 */\r
4041 {\r
4042         int disp = (int)((int8)FETCH);\r
4043         unsigned tmp = regs.w[CX] - 1;\r
4044         regs.w[CX] = tmp;\r
4045         if(!ZF && tmp) {\r
4046                 icount -= timing.loop_t;\r
4047                 pc += disp;\r
4048         } else {\r
4049                 icount -= timing.loop_nt;\r
4050         }\r
4051 }\r
4052 \r
4053 inline void I86::_loope()    /* Opcode 0xe1 */\r
4054 {\r
4055         int disp = (int)((int8)FETCH);\r
4056         unsigned tmp = regs.w[CX] - 1;\r
4057         regs.w[CX] = tmp;\r
4058         if(ZF && tmp) {\r
4059                 icount -= timing.loope_t;\r
4060                 pc += disp;\r
4061         } else {\r
4062                 icount -= timing.loope_nt;\r
4063         }\r
4064 }\r
4065 \r
4066 inline void I86::_loop()    /* Opcode 0xe2 */\r
4067 {\r
4068         int disp = (int)((int8)FETCH);\r
4069         unsigned tmp = regs.w[CX] - 1;\r
4070         regs.w[CX] = tmp;\r
4071         if(tmp) {\r
4072                 icount -= timing.loop_t;\r
4073                 pc += disp;\r
4074         } else {\r
4075                 icount -= timing.loop_nt;\r
4076         }\r
4077 }\r
4078 \r
4079 inline void I86::_jcxz()    /* Opcode 0xe3 */\r
4080 {\r
4081         int disp = (int)((int8)FETCH);\r
4082         if(regs.w[CX] == 0) {\r
4083                 icount -= timing.jcxz_t;\r
4084                 pc += disp;\r
4085         } else {\r
4086                 icount -= timing.jcxz_nt;\r
4087         }\r
4088 }\r
4089 \r
4090 inline void I86::_inal()    /* Opcode 0xe4 */\r
4091 {\r
4092         unsigned port = FETCH;\r
4093         icount -= timing.in_imm8;\r
4094         regs.b[AL] = read_port_byte(port);\r
4095 }\r
4096 \r
4097 inline void I86::_inax()    /* Opcode 0xe5 */\r
4098 {\r
4099         unsigned port = FETCH;\r
4100         icount -= timing.in_imm16;\r
4101         regs.w[AX] = read_port_word(port);\r
4102 }\r
4103 \r
4104 inline void I86::_outal()    /* Opcode 0xe6 */\r
4105 {\r
4106         unsigned port = FETCH;\r
4107         icount -= timing.out_imm8;\r
4108         write_port_byte(port, regs.b[AL]);\r
4109 }\r
4110 \r
4111 inline void I86::_outax()    /* Opcode 0xe7 */\r
4112 {\r
4113         unsigned port = FETCH;\r
4114         icount -= timing.out_imm16;\r
4115         write_port_word(port, regs.w[AX]);\r
4116 }\r
4117 \r
4118 inline void I86::_call_d16()    /* Opcode 0xe8 */\r
4119 {\r
4120         uint16 ip, tmp;\r
4121         \r
4122         FETCHWORD(tmp);\r
4123         ip = pc - base[CS];\r
4124         PUSH(ip);\r
4125         ip += tmp;\r
4126         pc = (ip + base[CS]) & AMASK;\r
4127 #ifdef I86_BIOS_CALL\r
4128         if(d_bios && d_bios->bios_call(pc, regs.w, sregs, &ZeroVal, &CarryVal)) {\r
4129                 /* bios call */\r
4130                 _ret();\r
4131         }\r
4132 #endif\r
4133         icount -= timing.call_near;\r
4134 }\r
4135 \r
4136 inline void I86::_jmp_d16()    /* Opcode 0xe9 */\r
4137 {\r
4138         uint16 ip, tmp;\r
4139         \r
4140         FETCHWORD(tmp);\r
4141         ip = pc - base[CS] + tmp;\r
4142         pc = (ip + base[CS]) & AMASK;\r
4143         icount -= timing.jmp_near;\r
4144 }\r
4145 \r
4146 inline void I86::_jmp_far()    /* Opcode 0xea */\r
4147 {\r
4148         unsigned tmp, tmp1;\r
4149         \r
4150         tmp = FETCH;\r
4151         tmp += FETCH << 8;\r
4152         \r
4153         tmp1 = FETCH;\r
4154         tmp1 += FETCH << 8;\r
4155         \r
4156         sregs[CS] = (uint16)tmp1;\r
4157         base[CS] = SegBase(CS);\r
4158         pc = (base[CS] + tmp) & AMASK;\r
4159         icount -= timing.jmp_far;\r
4160 }\r
4161 \r
4162 inline void I86::_jmp_d8()    /* Opcode 0xeb */\r
4163 {\r
4164         int tmp = (int)((int8)FETCH);\r
4165         pc += tmp;\r
4166         icount -= timing.jmp_short;\r
4167 }\r
4168 \r
4169 inline void I86::_inaldx()    /* Opcode 0xec */\r
4170 {\r
4171         icount -= timing.in_dx8;\r
4172         regs.b[AL] = read_port_byte(regs.w[DX]);\r
4173 }\r
4174 \r
4175 inline void I86::_inaxdx()    /* Opcode 0xed */\r
4176 {\r
4177         unsigned port = regs.w[DX];\r
4178         icount -= timing.in_dx16;\r
4179         regs.w[AX] = read_port_word(port);\r
4180 }\r
4181 \r
4182 inline void I86::_outdxal()    /* Opcode 0xee */\r
4183 {\r
4184         icount -= timing.out_dx8;\r
4185         write_port_byte(regs.w[DX], regs.b[AL]);\r
4186 }\r
4187 \r
4188 inline void I86::_outdxax()    /* Opcode 0xef */\r
4189 {\r
4190         unsigned port = regs.w[DX];\r
4191         icount -= timing.out_dx16;\r
4192         write_port_word(port, regs.w[AX]);\r
4193 }\r
4194 \r
4195 /* I think thats not a V20 instruction...*/\r
4196 inline void I86::_lock()    /* Opcode 0xf0 */\r
4197 {\r
4198         icount -= timing.nop;\r
4199         instruction(FETCHOP);  /* un-interruptible */\r
4200 }\r
4201 \r
4202 inline void I86::_rep(int flagval)\r
4203 {\r
4204         /* Handles rep- and repnz- prefixes. flagval is the value of ZF for the\r
4205            loop  to continue for CMPS and SCAS instructions. */\r
4206         \r
4207         unsigned next = FETCHOP;\r
4208         unsigned count = regs.w[CX];\r
4209         \r
4210         switch(next) {\r
4211         case 0x26:  /* ES: */\r
4212                 seg_prefix = true;\r
4213                 prefix_seg = ES;\r
4214                 icount -= timing.override;\r
4215                 _rep(flagval);\r
4216                 break;\r
4217         case 0x2e:  /* CS: */\r
4218                 seg_prefix = true;\r
4219                 prefix_seg = CS;\r
4220                 icount -= timing.override;\r
4221                 _rep(flagval);\r
4222                 break;\r
4223         case 0x36:  /* SS: */\r
4224                 seg_prefix = true;\r
4225                 prefix_seg = SS;\r
4226                 icount -= timing.override;\r
4227                 _rep(flagval);\r
4228                 break;\r
4229         case 0x3e:  /* DS: */\r
4230                 seg_prefix = true;\r
4231                 prefix_seg = DS;\r
4232                 icount -= timing.override;\r
4233                 _rep(flagval);\r
4234                 break;\r
4235 #ifndef HAS_I86\r
4236         case 0x6c:  /* REP INSB */\r
4237                 icount -= timing.rep_ins8_base;\r
4238                 for(; count > 0; count--) {\r
4239                         PutMemB(ES, regs.w[DI], read_port_byte(regs.w[DX]));\r
4240                         regs.w[DI] += DirVal;\r
4241                         icount -= timing.rep_ins8_count;\r
4242                 }\r
4243                 regs.w[CX] = count;\r
4244                 break;\r
4245         case 0x6d:  /* REP INSW */\r
4246                 icount -= timing.rep_ins16_base;\r
4247                 for(; count > 0; count--) {\r
4248                         PutMemW(ES, regs.w[DI], read_port_word(regs.w[DX]));\r
4249                         regs.w[DI] += 2 * DirVal;\r
4250                         icount -= timing.rep_ins16_count;\r
4251                 }\r
4252                 regs.w[CX] = count;\r
4253                 break;\r
4254         case 0x6e:  /* REP OUTSB */\r
4255                 icount -= timing.rep_outs8_base;\r
4256                 for(; count > 0; count--) {\r
4257                         write_port_byte(regs.w[DX], GetMemB(DS, regs.w[SI]));\r
4258                         regs.w[SI] += DirVal; /* GOL 11/27/01 */\r
4259                         icount -= timing.rep_outs8_count;\r
4260                 }\r
4261                 regs.w[CX] = count;\r
4262                 break;\r
4263         case 0x6f:  /* REP OUTSW */\r
4264                 icount -= timing.rep_outs16_base;\r
4265                 for(; count > 0; count--) {\r
4266                         write_port_word(regs.w[DX], GetMemW(DS, regs.w[SI]));\r
4267                         regs.w[SI] += 2 * DirVal; /* GOL 11/27/01 */\r
4268                         icount -= timing.rep_outs16_count;\r
4269                 }\r
4270                 regs.w[CX] = count;\r
4271                 break;\r
4272 #endif\r
4273         case 0xa4:      /* REP MOVSB */\r
4274                 icount -= timing.rep_movs8_base;\r
4275                 for(; count > 0; count--) {\r
4276                         uint8 tmp;\r
4277                         tmp = GetMemB(DS, regs.w[SI]);\r
4278                         PutMemB(ES, regs.w[DI], tmp);\r
4279                         regs.w[DI] += DirVal;\r
4280                         regs.w[SI] += DirVal;\r
4281                         icount -= timing.rep_movs8_count;\r
4282                 }\r
4283                 regs.w[CX] = count;\r
4284                 break;\r
4285         case 0xa5:  /* REP MOVSW */\r
4286                 icount -= timing.rep_movs16_base;\r
4287                 for(; count > 0; count--) {\r
4288                         uint16 tmp;\r
4289                         tmp = GetMemW(DS, regs.w[SI]);\r
4290                         PutMemW(ES, regs.w[DI], tmp);\r
4291                         regs.w[DI] += 2 * DirVal;\r
4292                         regs.w[SI] += 2 * DirVal;\r
4293                         icount -= timing.rep_movs16_count;\r
4294                 }\r
4295                 regs.w[CX] = count;\r
4296                 break;\r
4297         case 0xa6:  /* REP(N)E CMPSB */\r
4298                 icount -= timing.rep_cmps8_base;\r
4299                 for(ZeroVal = !flagval; (ZF == flagval) && (count > 0); count--) {\r
4300                         unsigned dst, src;\r
4301                         dst = GetMemB(ES, regs.w[DI]);\r
4302                         src = GetMemB(DS, regs.w[SI]);\r
4303                         SUBB(src, dst); /* opposite of the usual convention */\r
4304                         regs.w[DI] += DirVal;\r
4305                         regs.w[SI] += DirVal;\r
4306                         icount -= timing.rep_cmps8_count;\r
4307                 }\r
4308                 regs.w[CX] = count;\r
4309                 break;\r
4310         case 0xa7:  /* REP(N)E CMPSW */\r
4311                 icount -= timing.rep_cmps16_base;\r
4312                 for(ZeroVal = !flagval; (ZF == flagval) && (count > 0); count--) {\r
4313                         unsigned dst, src;\r
4314                         dst = GetMemW(ES, regs.w[DI]);\r
4315                         src = GetMemW(DS, regs.w[SI]);\r
4316                         SUBW(src, dst); /* opposite of the usual convention */\r
4317                         regs.w[DI] += 2 * DirVal;\r
4318                         regs.w[SI] += 2 * DirVal;\r
4319                         icount -= timing.rep_cmps16_count;\r
4320                 }\r
4321                 regs.w[CX] = count;\r
4322                 break;\r
4323         case 0xaa:  /* REP STOSB */\r
4324                 icount -= timing.rep_stos8_base;\r
4325                 for(; count > 0; count--) {\r
4326                         PutMemB(ES, regs.w[DI], regs.b[AL]);\r
4327                         regs.w[DI] += DirVal;\r
4328                         icount -= timing.rep_stos8_count;\r
4329                 }\r
4330                 regs.w[CX] = count;\r
4331                 break;\r
4332         case 0xab:  /* REP STOSW */\r
4333                 icount -= timing.rep_stos16_base;\r
4334                 for(; count > 0; count--) {\r
4335                         PutMemW(ES, regs.w[DI], regs.w[AX]);\r
4336                         regs.w[DI] += 2 * DirVal;\r
4337                         icount -= timing.rep_stos16_count;\r
4338                 }\r
4339                 regs.w[CX] = count;\r
4340                 break;\r
4341         case 0xac:  /* REP LODSB */\r
4342                 icount -= timing.rep_lods8_base;\r
4343                 for(; count > 0; count--) {\r
4344                         regs.b[AL] = GetMemB(DS, regs.w[SI]);\r
4345                         regs.w[SI] += DirVal;\r
4346                         icount -= timing.rep_lods8_count;\r
4347                 }\r
4348                 regs.w[CX] = count;\r
4349                 break;\r
4350         case 0xad:  /* REP LODSW */\r
4351                 icount -= timing.rep_lods16_base;\r
4352                 for(; count > 0; count--) {\r
4353                         regs.w[AX] = GetMemW(DS, regs.w[SI]);\r
4354                         regs.w[SI] += 2 * DirVal;\r
4355                         icount -= timing.rep_lods16_count;\r
4356                 }\r
4357                 regs.w[CX] = count;\r
4358                 break;\r
4359         case 0xae:  /* REP(N)E SCASB */\r
4360                 icount -= timing.rep_scas8_base;\r
4361                 for(ZeroVal = !flagval; (ZF == flagval) && (count > 0); count--) {\r
4362                         unsigned src, dst;\r
4363                         src = GetMemB(ES, regs.w[DI]);\r
4364                         dst = regs.b[AL];\r
4365                         SUBB(dst, src);\r
4366                         regs.w[DI] += DirVal;\r
4367                         icount -= timing.rep_scas8_count;\r
4368                 }\r
4369                 regs.w[CX] = count;\r
4370                 break;\r
4371         case 0xaf:  /* REP(N)E SCASW */\r
4372                 icount -= timing.rep_scas16_base;\r
4373                 for(ZeroVal = !flagval; (ZF == flagval) && (count > 0); count--) {\r
4374                         unsigned src, dst;\r
4375                         src = GetMemW(ES, regs.w[DI]);\r
4376                         dst = regs.w[AX];\r
4377                         SUBW(dst, src);\r
4378                         regs.w[DI] += 2 * DirVal;\r
4379                         icount -= timing.rep_scas16_count;\r
4380                 }\r
4381                 regs.w[CX] = count;\r
4382                 break;\r
4383         default:\r
4384                 instruction(next);\r
4385         }\r
4386 }\r
4387 \r
4388 inline void I86::_repne()    /* Opcode 0xf2 */\r
4389 {\r
4390         _rep(0);\r
4391 }\r
4392 \r
4393 inline void I86::_repe()    /* Opcode 0xf3 */\r
4394 {\r
4395         _rep(1);\r
4396 }\r
4397 \r
4398 inline void I86::_hlt()    /* Opcode 0xf4 */\r
4399 {\r
4400         pc--;\r
4401         halted = true;\r
4402         icount -= 2;\r
4403 }\r
4404 \r
4405 inline void I86::_cmc()    /* Opcode 0xf5 */\r
4406 {\r
4407         icount -= timing.flag_ops;\r
4408         CarryVal = !CF;\r
4409 }\r
4410 \r
4411 inline void I86::_f6pre()    /* Opcode 0xf6 */\r
4412 {\r
4413         unsigned ModRM = FETCH;\r
4414         unsigned tmp = (unsigned)GetRMByte(ModRM);\r
4415         unsigned tmp2;\r
4416         \r
4417         switch((ModRM >> 3) & 7) {\r
4418         case 0:  /* TEST Eb, data8 */\r
4419         case 1:  /* ??? */\r
4420                 icount -= (ModRM >= 0xc0) ? timing.alu_ri8 : timing.alu_mi8_ro;\r
4421                 tmp &= FETCH;\r
4422                 \r
4423                 CarryVal = OverVal = AuxVal = 0;\r
4424                 SetSZPF_Byte(tmp);\r
4425                 break;\r
4426                 \r
4427         case 2:  /* NOT Eb */\r
4428                 icount -= (ModRM >= 0xc0) ? timing.negnot_r8 : timing.negnot_m8;\r
4429                 PutbackRMByte(ModRM, ~tmp);\r
4430                 break;\r
4431                 \r
4432         case 3:  /* NEG Eb */\r
4433                 icount -= (ModRM >= 0xc0) ? timing.negnot_r8 : timing.negnot_m8;\r
4434                 tmp2 = 0;\r
4435                 SUBB(tmp2, tmp);\r
4436                 PutbackRMByte(ModRM, tmp2);\r
4437                 break;\r
4438                 \r
4439         case 4:  /* MUL AL, Eb */\r
4440                 icount -= (ModRM >= 0xc0) ? timing.mul_r8 : timing.mul_m8;\r
4441                 {\r
4442                         uint16 result;\r
4443                         \r
4444                         tmp2 = regs.b[AL];\r
4445                         \r
4446                         SetSF((int8)tmp2);\r
4447                         SetPF(tmp2);\r
4448                         \r
4449                         result = (uint16)tmp2 * tmp;\r
4450                         regs.w[AX] = (uint16)result;\r
4451                         \r
4452                         SetZF(regs.w[AX]);\r
4453                         CarryVal = OverVal = (regs.b[AH] != 0);\r
4454                 }\r
4455                 break;\r
4456                 \r
4457         case 5:  /* IMUL AL, Eb */\r
4458                 icount -= (ModRM >= 0xc0) ? timing.imul_r8 : timing.imul_m8;\r
4459                 {\r
4460                         int16 result;\r
4461                         \r
4462                         tmp2 = (unsigned)regs.b[AL];\r
4463                         \r
4464                         SetSF((int8)tmp2);\r
4465                         SetPF(tmp2);\r
4466                         \r
4467                         result = (int16)((int8)tmp2) * (int16)((int8)tmp);\r
4468                         regs.w[AX] = (uint16)result;\r
4469                         \r
4470                         SetZF(regs.w[AX]);\r
4471                         CarryVal = OverVal = (result >> 7 != 0) && (result >> 7 != -1);\r
4472                 }\r
4473                 break;\r
4474                 \r
4475         case 6:  /* DIV AL, Ew */\r
4476                 icount -= (ModRM >= 0xc0) ? timing.div_r8 : timing.div_m8;\r
4477                 {\r
4478                         uint16 result;\r
4479                         \r
4480                         result = regs.w[AX];\r
4481                         \r
4482                         if(tmp) {\r
4483                                 if((result / tmp) > 0xff) {\r
4484                                         interrupt(DIVIDE_FAULT);\r
4485                                         break;\r
4486                                 } else {\r
4487                                         regs.b[AH] = result % tmp;\r
4488                                         regs.b[AL] = result / tmp;\r
4489                                 }\r
4490                         } else {\r
4491                                 interrupt(DIVIDE_FAULT);\r
4492                                 break;\r
4493                         }\r
4494                 }\r
4495                 break;\r
4496                 \r
4497         case 7:  /* IDIV AL, Ew */\r
4498                 icount -= (ModRM >= 0xc0) ? timing.idiv_r8 : timing.idiv_m8;\r
4499                 {\r
4500                         int16 result;\r
4501                         \r
4502                         result = regs.w[AX];\r
4503                         \r
4504                         if(tmp) {\r
4505                                 tmp2 = result % (int16)((int8)tmp);\r
4506                                 \r
4507                                 if((result /= (int16)((int8)tmp)) > 0xff) {\r
4508                                         interrupt(DIVIDE_FAULT);\r
4509                                         break;\r
4510                                 } else {\r
4511                                         regs.b[AL] = (uint8)result;\r
4512                                         regs.b[AH] = tmp2;\r
4513                                 }\r
4514                         } else {\r
4515                                 interrupt(DIVIDE_FAULT);\r
4516                                 break;\r
4517                         }\r
4518                 }\r
4519                 break;\r
4520                 \r
4521         default:\r
4522                 //__assume(0);\r
4523                 break;\r
4524         }\r
4525 }\r
4526 \r
4527 inline void I86::_f7pre()    /* Opcode 0xf7 */\r
4528 {\r
4529         unsigned ModRM = FETCH;\r
4530         unsigned tmp = GetRMWord(ModRM);\r
4531         unsigned tmp2;\r
4532         \r
4533         switch((ModRM >> 3) & 7) {\r
4534         case 0:  /* TEST Ew, data16 */\r
4535         case 1:  /* ??? */\r
4536                 icount -= (ModRM >= 0xc0) ? timing.alu_ri16 : timing.alu_mi16_ro;\r
4537                 tmp2 = FETCH;\r
4538                 tmp2 += FETCH << 8;\r
4539                 \r
4540                 tmp &= tmp2;\r
4541                 \r
4542                 CarryVal = OverVal = AuxVal = 0;\r
4543                 SetSZPF_Word(tmp);\r
4544                 break;\r
4545                 \r
4546         case 2:  /* NOT Ew */\r
4547                 icount -= (ModRM >= 0xc0) ? timing.negnot_r16 : timing.negnot_m16;\r
4548                 tmp = ~tmp;\r
4549                 PutbackRMWord(ModRM, tmp);\r
4550                 break;\r
4551                 \r
4552         case 3:  /* NEG Ew */\r
4553                 icount -= (ModRM >= 0xc0) ? timing.negnot_r16 : timing.negnot_m16;\r
4554                 tmp2 = 0;\r
4555                 SUBW(tmp2, tmp);\r
4556                 PutbackRMWord(ModRM, tmp2);\r
4557                 break;\r
4558                 \r
4559         case 4:  /* MUL AX, Ew */\r
4560                 icount -= (ModRM >= 0xc0) ? timing.mul_r16 : timing.mul_m16;\r
4561                 {\r
4562                         uint32 result;\r
4563                         tmp2 = regs.w[AX];\r
4564                         \r
4565                         SetSF((int16)tmp2);\r
4566                         SetPF(tmp2);\r
4567                         \r
4568                         result = (uint32)tmp2 * tmp;\r
4569                         regs.w[AX] = (uint16)result;\r
4570                         result >>= 16;\r
4571                         regs.w[DX] = result;\r
4572                         \r
4573                         SetZF(regs.w[AX] | regs.w[DX]);\r
4574                         CarryVal = OverVal = (regs.w[DX] != 0);\r
4575                 }\r
4576                 break;\r
4577                 \r
4578         case 5:  /* IMUL AX, Ew */\r
4579                 icount -= (ModRM >= 0xc0) ? timing.imul_r16 : timing.imul_m16;\r
4580                 {\r
4581                         int32 result;\r
4582                         \r
4583                         tmp2 = regs.w[AX];\r
4584                         \r
4585                         SetSF((int16)tmp2);\r
4586                         SetPF(tmp2);\r
4587                         \r
4588                         result = (int32)((int16)tmp2) * (int32)((int16)tmp);\r
4589                         CarryVal = OverVal = (result >> 15 != 0) && (result >> 15 != -1);\r
4590                         \r
4591                         regs.w[AX] = (uint16)result;\r
4592                         result = (uint16)(result >> 16);\r
4593                         regs.w[DX] = result;\r
4594                         \r
4595                         SetZF(regs.w[AX] | regs.w[DX]);\r
4596                 }\r
4597                 break;\r
4598                 \r
4599         case 6:  /* DIV AX, Ew */\r
4600                 icount -= (ModRM >= 0xc0) ? timing.div_r16 : timing.div_m16;\r
4601                 {\r
4602                         uint32 result;\r
4603                         \r
4604                         result = (regs.w[DX] << 16) + regs.w[AX];\r
4605                         \r
4606                         if(tmp) {\r
4607                                 tmp2 = result % tmp;\r
4608                                 if((result / tmp) > 0xffff) {\r
4609                                         interrupt(DIVIDE_FAULT);\r
4610                                         break;\r
4611                                 } else {\r
4612                                         regs.w[DX] = tmp2;\r
4613                                         result /= tmp;\r
4614                                         regs.w[AX] = result;\r
4615                                 }\r
4616                         } else {\r
4617                                 interrupt(DIVIDE_FAULT);\r
4618                                 break;\r
4619                         }\r
4620                 }\r
4621                 break;\r
4622                 \r
4623         case 7:  /* IDIV AX, Ew */\r
4624                 icount -= (ModRM >= 0xc0) ? timing.idiv_r16 : timing.idiv_m16;\r
4625                 {\r
4626                         int32 result;\r
4627                         \r
4628                         result = (regs.w[DX] << 16) + regs.w[AX];\r
4629                         \r
4630                         if(tmp) {\r
4631                                 tmp2 = result % (int32)((int16)tmp);\r
4632                                 if((result /= (int32)((int16)tmp)) > 0xffff) {\r
4633                                         interrupt(DIVIDE_FAULT);\r
4634                                         break;\r
4635                                 } else {\r
4636                                         regs.w[AX] = result;\r
4637                                         regs.w[DX] = tmp2;\r
4638                                 }\r
4639                         } else {\r
4640                                 interrupt(DIVIDE_FAULT);\r
4641                                 break;\r
4642                         }\r
4643                 }\r
4644                 break;\r
4645                 \r
4646         default:\r
4647                 //__assume(0);\r
4648                 break;\r
4649         }\r
4650 }\r
4651 \r
4652 inline void I86::_clc()    /* Opcode 0xf8 */\r
4653 {\r
4654         icount -= timing.flag_ops;\r
4655         CarryVal = 0;\r
4656 }\r
4657 \r
4658 inline void I86::_stc()    /* Opcode 0xf9 */\r
4659 {\r
4660         icount -= timing.flag_ops;\r
4661         CarryVal = 1;\r
4662 }\r
4663 \r
4664 inline void I86::_cli()    /* Opcode 0xfa */\r
4665 {\r
4666         icount -= timing.flag_ops;\r
4667         SetIF(0);\r
4668 }\r
4669 \r
4670 inline void I86::_sti()    /* Opcode 0xfb */\r
4671 {\r
4672         icount -= timing.flag_ops;\r
4673         SetIF(1);\r
4674         instruction(FETCHOP); /* no interrupt before next instruction */\r
4675 \r
4676         /* if an interrupt is pending, signal an interrupt */\r
4677         if(IF && (int_state & INT_REQ_BIT)) {\r
4678                 interrupt(-1);\r
4679         }\r
4680 }\r
4681 \r
4682 inline void I86::_cld()    /* Opcode 0xfc */\r
4683 {\r
4684         icount -= timing.flag_ops;\r
4685         SetDF(0);\r
4686 }\r
4687 \r
4688 inline void I86::_std()    /* Opcode 0xfd */\r
4689 {\r
4690         icount -= timing.flag_ops;\r
4691         SetDF(1);\r
4692 }\r
4693 \r
4694 inline void I86::_fepre()    /* Opcode 0xfe */\r
4695 {\r
4696         unsigned ModRM = FETCH;\r
4697         unsigned tmp = GetRMByte(ModRM);\r
4698         unsigned tmp1;\r
4699         \r
4700         icount -= (ModRM >= 0xc0) ? timing.incdec_r8 : timing.incdec_m8;\r
4701         if((ModRM & 0x38) == 0) {\r
4702                 /* INC eb */\r
4703                 tmp1 = tmp + 1;\r
4704                 SetOFB_Add(tmp1, tmp, 1);\r
4705         } else {\r
4706                 /* DEC eb */\r
4707                 tmp1 = tmp - 1;\r
4708                 SetOFB_Sub(tmp1, 1, tmp);\r
4709         }\r
4710         SetAF(tmp1, tmp, 1);\r
4711         SetSZPF_Byte(tmp1);\r
4712         PutbackRMByte(ModRM, (uint8)tmp1);\r
4713 }\r
4714 \r
4715 inline void I86::_ffpre()    /* Opcode 0xff */\r
4716 {\r
4717         unsigned ModRM = FETCHOP;\r
4718         unsigned tmp;\r
4719         unsigned tmp1;\r
4720         uint16 ip;\r
4721         \r
4722         switch((ModRM >> 3) & 7) {\r
4723         case 0:  /* INC ew */\r
4724                 icount -= (ModRM >= 0xc0) ? timing.incdec_r16 : timing.incdec_m16;\r
4725                 tmp = GetRMWord(ModRM);\r
4726                 tmp1 = tmp + 1;\r
4727                 SetOFW_Add(tmp1, tmp, 1);\r
4728                 SetAF(tmp1, tmp, 1);\r
4729                 SetSZPF_Word(tmp1);\r
4730                 PutbackRMWord(ModRM, (uint16)tmp1);\r
4731                 break;\r
4732         case 1:  /* DEC ew */\r
4733                 icount -= (ModRM >= 0xc0) ? timing.incdec_r16 : timing.incdec_m16;\r
4734                 tmp = GetRMWord(ModRM);\r
4735                 tmp1 = tmp - 1;\r
4736                 SetOFW_Sub(tmp1, 1, tmp);\r
4737                 SetAF(tmp1, tmp, 1);\r
4738                 SetSZPF_Word(tmp1);\r
4739                 PutbackRMWord(ModRM, (uint16)tmp1);\r
4740                 break;\r
4741         case 2:  /* CALL ew */\r
4742                 icount -= (ModRM >= 0xc0) ? timing.call_r16 : timing.call_m16;\r
4743                 tmp = GetRMWord(ModRM);\r
4744                 ip = pc - base[CS];\r
4745                 PUSH(ip);\r
4746                 pc = (base[CS] + (uint16)tmp) & AMASK;\r
4747 #ifdef I86_BIOS_CALL\r
4748                 if(d_bios && d_bios->bios_call(pc, regs.w, sregs, &ZeroVal, &CarryVal)) {\r
4749                         /* bios call */\r
4750                         _ret();\r
4751                 }\r
4752 #endif\r
4753                 break;\r
4754         case 3:  /* CALL FAR ea */\r
4755                 icount -= timing.call_m32;\r
4756                 tmp = sregs[CS];        /* need to skip displacements of ea */\r
4757                 tmp1 = GetRMWord(ModRM);\r
4758                 ip = pc - base[CS];\r
4759                 PUSH(tmp);\r
4760                 PUSH(ip);\r
4761                 sregs[CS] = GetNextRMWord;\r
4762                 base[CS] = SegBase(CS);\r
4763                 pc = (base[CS] + tmp1) & AMASK;\r
4764 #ifdef I86_BIOS_CALL\r
4765                 if(d_bios && d_bios->bios_call(pc, regs.w, sregs, &ZeroVal, &CarryVal)) {\r
4766                         /* bios call */\r
4767                         _ret();\r
4768                 }\r
4769 #endif\r
4770                 break;\r
4771         case 4:  /* JMP ea */\r
4772                 icount -= (ModRM >= 0xc0) ? timing.jmp_r16 : timing.jmp_m16;\r
4773                 ip = GetRMWord(ModRM);\r
4774                 pc = (base[CS] + ip) & AMASK;\r
4775                 break;\r
4776         case 5:  /* JMP FAR ea */\r
4777                 icount -= timing.jmp_m32;\r
4778                 pc = GetRMWord(ModRM);\r
4779                 sregs[CS] = GetNextRMWord;\r
4780                 base[CS] = SegBase(CS);\r
4781                 pc = (pc + base[CS]) & AMASK;\r
4782                 break;\r
4783         case 6:  /* PUSH ea */\r
4784                 icount -= (ModRM >= 0xc0) ? timing.push_r16 : timing.push_m16;\r
4785                 tmp = GetRMWord(ModRM);\r
4786                 PUSH(tmp);\r
4787                 break;\r
4788         case 7:  /* invalid ??? */\r
4789                 icount -= 10;\r
4790                 break;\r
4791         default:\r
4792                 //__assume(0);\r
4793                 break;\r
4794         }\r
4795 }\r
4796 \r
4797 inline void I86::_invalid()\r
4798 {\r
4799         /* i8086/i8088 ignore an invalid opcode. */\r
4800         /* i80186/i80188 probably also ignore an invalid opcode. */\r
4801         icount -= 10;\r
4802 }\r
4803 \r
4804 /*\r
4805    NEC V-series Disassembler\r
4806 \r
4807    Originally Written for i386 by Ville Linde\r
4808    Converted to NEC-V by Aaron Giles\r
4809 */\r
4810 \r
4811 enum\r
4812 {\r
4813         PARAM_REG8 = 1,         /* 8-bit register */\r
4814         PARAM_REG16,            /* 16-bit register */\r
4815         PARAM_REG2_8,           /* 8-bit register */\r
4816         PARAM_REG2_16,          /* 16-bit register */\r
4817         PARAM_RM8,                      /* 8-bit memory or register */\r
4818         PARAM_RM16,                     /* 16-bit memory or register */\r
4819         PARAM_RMPTR8,           /* 8-bit memory or register */\r
4820         PARAM_RMPTR16,          /* 16-bit memory or register */\r
4821         PARAM_I3,                       /* 3-bit immediate */\r
4822         PARAM_I4,                       /* 4-bit immediate */\r
4823         PARAM_I8,                       /* 8-bit signed immediate */\r
4824         PARAM_I16,                      /* 16-bit signed immediate */\r
4825         PARAM_UI8,                      /* 8-bit unsigned immediate */\r
4826         PARAM_IMM,                      /* 16-bit immediate */\r
4827         PARAM_ADDR,                     /* 16:16 address */\r
4828         PARAM_REL8,                     /* 8-bit PC-relative displacement */\r
4829         PARAM_REL16,            /* 16-bit PC-relative displacement */\r
4830         PARAM_MEM_OFFS,         /* 16-bit mem offset */\r
4831         PARAM_SREG,                     /* segment register */\r
4832         PARAM_SFREG,            /* V25/V35 special function register */\r
4833         PARAM_1,                        /* used by shift/rotate instructions */\r
4834         PARAM_AL,\r
4835         PARAM_CL,\r
4836         PARAM_DL,\r
4837         PARAM_BL,\r
4838         PARAM_AH,\r
4839         PARAM_CH,\r
4840         PARAM_DH,\r
4841         PARAM_BH,\r
4842         PARAM_AW,\r
4843         PARAM_CW,\r
4844         PARAM_DW,\r
4845         PARAM_BW,\r
4846         PARAM_SP,\r
4847         PARAM_BP,\r
4848         PARAM_IX,\r
4849         PARAM_IY\r
4850 };\r
4851 \r
4852 enum\r
4853 {\r
4854         MODRM = 1,\r
4855         GROUP,\r
4856         FPU,\r
4857         TWO_BYTE,\r
4858         PREFIX,\r
4859         SEG_PS,\r
4860         SEG_DS0,\r
4861         SEG_DS1,\r
4862         SEG_SS\r
4863 };\r
4864 \r
4865 struct I386_OPCODE {\r
4866         char mnemonic[32];\r
4867         UINT32 flags;\r
4868         UINT32 param1;\r
4869         UINT32 param2;\r
4870         UINT32 param3;\r
4871         offs_t dasm_flags;\r
4872 };\r
4873 \r
4874 struct GROUP_OP {\r
4875         char mnemonic[32];\r
4876         const I386_OPCODE *opcode;\r
4877 };\r
4878 \r
4879 static const UINT8 *opcode_ptr;\r
4880 static const UINT8 *opcode_ptr_base;\r
4881 \r
4882 static const I386_OPCODE necv_opcode_table1[256] =\r
4883 {\r
4884         // 0x00\r
4885         {"add",                         MODRM,                  PARAM_RM8,                      PARAM_REG8,                     0                               },\r
4886         {"add",                         MODRM,                  PARAM_RM16,                     PARAM_REG16,            0                               },\r
4887         {"add",                         MODRM,                  PARAM_REG8,                     PARAM_RM8,                      0                               },\r
4888         {"add",                         MODRM,                  PARAM_REG16,            PARAM_RM16,                     0                               },\r
4889         {"add",                         0,                              PARAM_AL,                       PARAM_UI8,                      0                               },\r
4890         {"add",                         0,                              PARAM_AW,                       PARAM_IMM,                      0                               },\r
4891         {"push    ds1",         0,                              0,                                      0,                                      0                               },\r
4892         {"pop     ds1",         0,                              0,                                      0,                                      0                               },\r
4893         {"or",                          MODRM,                  PARAM_RM8,                      PARAM_REG8,                     0                               },\r
4894         {"or",                          MODRM,                  PARAM_RM16,                     PARAM_REG16,            0                               },\r
4895         {"or",                          MODRM,                  PARAM_REG8,                     PARAM_RM8,                      0                               },\r
4896         {"or",                          MODRM,                  PARAM_REG16,            PARAM_RM16,                     0                               },\r
4897         {"or",                          0,                              PARAM_AL,                       PARAM_UI8,                      0                               },\r
4898         {"or",                          0,                              PARAM_AW,                       PARAM_IMM,                      0                               },\r
4899         {"push    ps",          0,                              0,                                      0,                                      0                               },\r
4900         {"two_byte",            TWO_BYTE,               0,                                      0,                                      0                               },\r
4901         // 0x10\r
4902         {"addc",                        MODRM,                  PARAM_RM8,                      PARAM_REG8,                     0                               },\r
4903         {"addc",                        MODRM,                  PARAM_RM16,                     PARAM_REG16,            0                               },\r
4904         {"addc",                        MODRM,                  PARAM_REG8,                     PARAM_RM8,                      0                               },\r
4905         {"addc",                        MODRM,                  PARAM_REG16,            PARAM_RM16,                     0                               },\r
4906         {"addc",                        0,                              PARAM_AL,                       PARAM_UI8,                      0                               },\r
4907         {"addc",                        0,                              PARAM_AW,                       PARAM_IMM,                      0                               },\r
4908         {"push    ss",          0,                              0,                                      0,                                      0                               },\r
4909         {"pop     ss",          0,                              0,                                      0,                                      0                               },\r
4910         {"subc",                        MODRM,                  PARAM_RM8,                      PARAM_REG8,                     0                               },\r
4911         {"subc",                        MODRM,                  PARAM_RM16,                     PARAM_REG16,            0                               },\r
4912         {"subc",                        MODRM,                  PARAM_REG8,                     PARAM_RM8,                      0                               },\r
4913         {"subc",                        MODRM,                  PARAM_REG16,            PARAM_RM16,                     0                               },\r
4914         {"subc",                        0,                              PARAM_AL,                       PARAM_UI8,                      0                               },\r
4915         {"subc",                        0,                              PARAM_AW,                       PARAM_IMM,                      0                               },\r
4916         {"push    ds0",         0,                              0,                                      0,                                      0                               },\r
4917         {"pop     ds0",         0,                              0,                                      0,                                      0                               },\r
4918         // 0x20\r
4919         {"and",                         MODRM,                  PARAM_RM8,                      PARAM_REG8,                     0                               },\r
4920         {"and",                         MODRM,                  PARAM_RM16,                     PARAM_REG16,            0                               },\r
4921         {"and",                         MODRM,                  PARAM_REG8,                     PARAM_RM8,                      0                               },\r
4922         {"and",                         MODRM,                  PARAM_REG16,            PARAM_RM16,                     0                               },\r
4923         {"and",                         0,                              PARAM_AL,                       PARAM_UI8,                      0                               },\r
4924         {"and",                         0,                              PARAM_AW,                       PARAM_IMM,                      0                               },\r
4925         {"ds1:",                        SEG_DS1,                0,                                      0,                                      0                               },\r
4926         {"adj4a",                       0,                              0,                                      0,                                      0                               },\r
4927         {"sub",                         MODRM,                  PARAM_RM8,                      PARAM_REG8,                     0                               },\r
4928         {"sub",                         MODRM,                  PARAM_RM16,                     PARAM_REG16,            0                               },\r
4929         {"sub",                         MODRM,                  PARAM_REG8,                     PARAM_RM8,                      0                               },\r
4930         {"sub",                         MODRM,                  PARAM_REG16,            PARAM_RM16,                     0                               },\r
4931         {"sub",                         0,                              PARAM_AL,                       PARAM_UI8,                      0                               },\r
4932         {"sub",                         0,                              PARAM_AW,                       PARAM_IMM,                      0                               },\r
4933         {"ps:",                         SEG_PS,                 0,                                      0,                                      0                               },\r
4934         {"adj4s",                       0,                              0,                                      0,                                      0                               },\r
4935         // 0x30\r
4936         {"xor",                         MODRM,                  PARAM_RM8,                      PARAM_REG8,                     0                               },\r
4937         {"xor",                         MODRM,                  PARAM_RM16,                     PARAM_REG16,            0                               },\r
4938         {"xor",                         MODRM,                  PARAM_REG8,                     PARAM_RM8,                      0                               },\r
4939         {"xor",                         MODRM,                  PARAM_REG16,            PARAM_RM16,                     0                               },\r
4940         {"xor",                         0,                              PARAM_AL,                       PARAM_UI8,                      0                               },\r
4941         {"xor",                         0,                              PARAM_AW,                       PARAM_IMM,                      0                               },\r
4942         {"ss:",                         SEG_SS,                 0,                                      0,                                      0                               },\r
4943         {"adjba",                       0,                              0,                                      0,                                      0                               },\r
4944         {"cmp",                         MODRM,                  PARAM_RM8,                      PARAM_REG8,                     0                               },\r
4945         {"cmp",                         MODRM,                  PARAM_RM16,                     PARAM_REG16,            0                               },\r
4946         {"cmp",                         MODRM,                  PARAM_REG8,                     PARAM_RM8,                      0                               },\r
4947         {"cmp",                         MODRM,                  PARAM_REG16,            PARAM_RM16,                     0                               },\r
4948         {"cmp",                         0,                              PARAM_AL,                       PARAM_UI8,                      0                               },\r
4949         {"cmp",                         0,                              PARAM_AW,                       PARAM_IMM,                      0                               },\r
4950         {"ds0:",                        SEG_DS0,                0,                                      0,                                      0                               },\r
4951         {"adjbs",                       0,                              0,                                      0,                                      0                               },\r
4952         // 0x40\r
4953         {"inc",                         0,                              PARAM_AW,                       0,                                      0                               },\r
4954         {"inc",                         0,                              PARAM_CW,                       0,                                      0                               },\r
4955         {"inc",                         0,                              PARAM_DW,                       0,                                      0                               },\r
4956         {"inc",                         0,                              PARAM_BW,                       0,                                      0                               },\r
4957         {"inc",                         0,                              PARAM_SP,                       0,                                      0                               },\r
4958         {"inc",                         0,                              PARAM_BP,                       0,                                      0                               },\r
4959         {"inc",                         0,                              PARAM_IX,                       0,                                      0                               },\r
4960         {"inc",                         0,                              PARAM_IY,                       0,                                      0                               },\r
4961         {"dec",                         0,                              PARAM_AW,                       0,                                      0                               },\r
4962         {"dec",                         0,                              PARAM_CW,                       0,                                      0                               },\r
4963         {"dec",                         0,                              PARAM_DW,                       0,                                      0                               },\r
4964         {"dec",                         0,                              PARAM_BW,                       0,                                      0                               },\r
4965         {"dec",                         0,                              PARAM_SP,                       0,                                      0                               },\r
4966         {"dec",                         0,                              PARAM_BP,                       0,                                      0                               },\r
4967         {"dec",                         0,                              PARAM_IX,                       0,                                      0                               },\r
4968         {"dec",                         0,                              PARAM_IY,                       0,                                      0                               },\r
4969         // 0x50\r
4970         {"push",                        0,                              PARAM_AW,                       0,                                      0                               },\r
4971         {"push",                        0,                              PARAM_CW,                       0,                                      0                               },\r
4972         {"push",                        0,                              PARAM_DW,                       0,                                      0                               },\r
4973         {"push",                        0,                              PARAM_BW,                       0,                                      0                               },\r
4974         {"push",                        0,                              PARAM_SP,                       0,                                      0                               },\r
4975         {"push",                        0,                              PARAM_BP,                       0,                                      0                               },\r
4976         {"push",                        0,                              PARAM_IX,                       0,                                      0                               },\r
4977         {"push",                        0,                              PARAM_IY,                       0,                                      0                               },\r
4978         {"pop",                         0,                              PARAM_AW,                       0,                                      0                               },\r
4979         {"pop",                         0,                              PARAM_CW,                       0,                                      0                               },\r
4980         {"pop",                         0,                              PARAM_DW,                       0,                                      0                               },\r
4981         {"pop",                         0,                              PARAM_BW,                       0,                                      0                               },\r
4982         {"pop",                         0,                              PARAM_SP,                       0,                                      0                               },\r
4983         {"pop",                         0,                              PARAM_BP,                       0,                                      0                               },\r
4984         {"pop",                         0,                              PARAM_IX,                       0,                                      0                               },\r
4985         {"pop",                         0,                              PARAM_IY,                       0,                                      0                               },\r
4986         // 0x60\r
4987         {"push    r",           0,                              0,                                      0,                                      0                               },\r
4988         {"pop     r",           0,                              0,                                      0,                                      0                               },\r
4989         {"chkind",                      MODRM,                  PARAM_REG16,            PARAM_RM16,                     0                               },\r
4990         {"brkn",                        0,                              PARAM_UI8,                      0,                                      0,                              DASMFLAG_STEP_OVER},    /* V25S/V35S only */\r
4991         {"repnc",                       PREFIX,                 0,                                      0,                                      0                               },\r
4992         {"repc",                        PREFIX,                 0,                                      0,                                      0                               },\r
4993         {"fpo2    0",           0,                              0,                                      0,                                      0                               },      /* for a coprocessor that was never made */\r
4994         {"fpo2    1",           0,                              0,                                      0,                                      0                               },      /* for a coprocessor that was never made */\r
4995         {"push",                        0,                              PARAM_IMM,                      0,                                      0                               },\r
4996         {"mul",                         MODRM,                  PARAM_REG16,            PARAM_RM16,                     PARAM_IMM               },\r
4997         {"push",                        0,                              PARAM_I8,                       0,                                      0                               },\r
4998         {"mul",                         MODRM,                  PARAM_REG16,            PARAM_RM16,                     PARAM_I8                },\r
4999         {"inmb",                        0,                              0,                                      0,                                      0                               },\r
5000         {"inmw",                        0,                              0,                                      0,                                      0                               },\r
5001         {"outmb",                       0,                              0,                                      0,                                      0                               },\r
5002         {"outmw",                       0,                              0,                                      0,                                      0                               },\r
5003         // 0x70\r
5004         {"bv",                          0,                              PARAM_REL8,                     0,                                      0                               },\r
5005         {"bnv",                         0,                              PARAM_REL8,                     0,                                      0                               },\r
5006         {"bc",                          0,                              PARAM_REL8,                     0,                                      0                               },\r
5007         {"bnc",                         0,                              PARAM_REL8,                     0,                                      0                               },\r
5008         {"be",                          0,                              PARAM_REL8,                     0,                                      0                               },\r
5009         {"bne",                         0,                              PARAM_REL8,                     0,                                      0                               },\r
5010         {"bnh",                         0,                              PARAM_REL8,                     0,                                      0                               },\r
5011         {"bh",                          0,                              PARAM_REL8,                     0,                                      0                               },\r
5012         {"bn",                          0,                              PARAM_REL8,                     0,                                      0                               },\r
5013         {"bp",                          0,                              PARAM_REL8,                     0,                                      0                               },\r
5014         {"bpe",                         0,                              PARAM_REL8,                     0,                                      0                               },\r
5015         {"bpo",                         0,                              PARAM_REL8,                     0,                                      0                               },\r
5016         {"blt",                         0,                              PARAM_REL8,                     0,                                      0                               },\r
5017         {"bge",                         0,                              PARAM_REL8,                     0,                                      0                               },\r
5018         {"ble",                         0,                              PARAM_REL8,                     0,                                      0                               },\r
5019         {"bgt",                         0,                              PARAM_REL8,                     0,                                      0                               },\r
5020         // 0x80\r
5021         {"immb",                        GROUP,                  0,                                      0,                                      0                               },\r
5022         {"immw",                        GROUP,                  0,                                      0,                                      0                               },\r
5023         {"immb",                        GROUP,                  0,                                      0,                                      0                               },\r
5024         {"immws",                       GROUP,                  0,                                      0,                                      0                               },\r
5025         {"test",                        MODRM,                  PARAM_RM8,                      PARAM_REG8,                     0                               },\r
5026         {"test",                        MODRM,                  PARAM_RM16,                     PARAM_REG16,            0                               },\r
5027         {"xch",                         MODRM,                  PARAM_REG8,                     PARAM_RM8,                      0                               },\r
5028         {"xch",                         MODRM,                  PARAM_REG16,            PARAM_RM16,                     0                               },\r
5029         {"mov",                         MODRM,                  PARAM_RM8,                      PARAM_REG8,                     0                               },\r
5030         {"mov",                         MODRM,                  PARAM_RM16,                     PARAM_REG16,            0                               },\r
5031         {"mov",                         MODRM,                  PARAM_REG8,                     PARAM_RM8,                      0                               },\r
5032         {"mov",                         MODRM,                  PARAM_REG16,            PARAM_RM16,                     0                               },\r
5033         {"mov",                         MODRM,                  PARAM_RM16,                     PARAM_SREG,                     0                               },\r
5034         {"ldea",                        MODRM,                  PARAM_REG16,            PARAM_RM16,                     0                               },\r
5035         {"mov",                         MODRM,                  PARAM_SREG,                     PARAM_RM16,                     0                               },\r
5036         {"pop",                         MODRM,                  PARAM_RM16,                     0,                                      0                               },\r
5037         // 0x90\r
5038         {"nop",                         0,                              0,                                      0,                                      0                               },\r
5039         {"xch",                         0,                              PARAM_AW,                       PARAM_CW,                       0                               },\r
5040         {"xch",                         0,                              PARAM_AW,                       PARAM_DW,                       0                               },\r
5041         {"xch",                         0,                              PARAM_AW,                       PARAM_BW,                       0                               },\r
5042         {"xch",                         0,                              PARAM_AW,                       PARAM_SP,                       0                               },\r
5043         {"xch",                         0,                              PARAM_AW,                       PARAM_BP,                       0                               },\r
5044         {"xch",                         0,                              PARAM_AW,                       PARAM_IX,                       0                               },\r
5045         {"xch",                         0,                              PARAM_AW,                       PARAM_IY,                       0                               },\r
5046         {"cvtbw",                       0,                              0,                                      0,                                      0                               },\r
5047         {"cvtwl",                       0,                              0,                                      0,                                      0                               },\r
5048         {"call",                        0,                              PARAM_ADDR,                     0,                                      0,                              DASMFLAG_STEP_OVER},\r
5049         {"poll",                        0,                              0,                                      0,                                      0                               },\r
5050         {"push    psw",         0,                              0,                                      0,                                      0                               },\r
5051         {"pop     psw",         0,                              0,                                      0,                                      0                               },\r
5052         {"mov     psw,ah",      0,                              0,                                      0,                                      0                               },\r
5053         {"mov     ah,psw",      0,                              0,                                      0,                                      0                               },\r
5054         // 0xa0\r
5055         {"mov",                         0,                              PARAM_AL,                       PARAM_MEM_OFFS,         0                               },\r
5056         {"mov",                         0,                              PARAM_AW,                       PARAM_MEM_OFFS,         0                               },\r
5057         {"mov",                         0,                              PARAM_MEM_OFFS,         PARAM_AL,                       0                               },\r
5058         {"mov",                         0,                              PARAM_MEM_OFFS,         PARAM_AW,                       0                               },\r
5059         {"movbkb",                      0,                              0,                                      0,                                      0                               },\r
5060         {"movbkw",                      0,                              0,                                      0,                                      0                               },\r
5061         {"cmpbkb",                      0,                              0,                                      0,                                      0                               },\r
5062         {"cmpbkw",                      0,                              0,                                      0,                                      0                               },\r
5063         {"test",                        0,                              PARAM_AL,                       PARAM_UI8,                      0                               },\r
5064         {"test",                        0,                              PARAM_AW,                       PARAM_IMM,                      0                               },\r
5065         {"stmb",                        0,                              0,                                      0,                                      0                               },\r
5066         {"stmw",                        0,                              0,                                      0,                                      0                               },\r
5067         {"ldmb",                        0,                              0,                                      0,                                      0                               },\r
5068         {"ldmw",                        0,                              0,                                      0,                                      0                               },\r
5069         {"cmpmb",                       0,                              0,                                      0,                                      0                               },\r
5070         {"cmpmw",                       0,                              0,                                      0,                                      0                               },\r
5071         // 0xb0\r
5072         {"mov",                         0,                              PARAM_AL,                       PARAM_UI8,                      0                               },\r
5073         {"mov",                         0,                              PARAM_CL,                       PARAM_UI8,                      0                               },\r
5074         {"mov",                         0,                              PARAM_DL,                       PARAM_UI8,                      0                               },\r
5075         {"mov",                         0,                              PARAM_BL,                       PARAM_UI8,                      0                               },\r
5076         {"mov",                         0,                              PARAM_AH,                       PARAM_UI8,                      0                               },\r
5077         {"mov",                         0,                              PARAM_CH,                       PARAM_UI8,                      0                               },\r
5078         {"mov",                         0,                              PARAM_DH,                       PARAM_UI8,                      0                               },\r
5079         {"mov",                         0,                              PARAM_BH,                       PARAM_UI8,                      0                               },\r
5080         {"mov",                         0,                              PARAM_AW,                       PARAM_IMM,                      0                               },\r
5081         {"mov",                         0,                              PARAM_CW,                       PARAM_IMM,                      0                               },\r
5082         {"mov",                         0,                              PARAM_DW,                       PARAM_IMM,                      0                               },\r
5083         {"mov",                         0,                              PARAM_BW,                       PARAM_IMM,                      0                               },\r
5084         {"mov",                         0,                              PARAM_SP,                       PARAM_IMM,                      0                               },\r
5085         {"mov",                         0,                              PARAM_BP,                       PARAM_IMM,                      0                               },\r
5086         {"mov",                         0,                              PARAM_IX,                       PARAM_IMM,                      0                               },\r
5087         {"mov",                         0,                              PARAM_IY,                       PARAM_IMM,                      0                               },\r
5088         // 0xc0\r
5089         {"shiftbi",                     GROUP,                  0,                                      0,                                      0                               },\r
5090         {"shiftwi",                     GROUP,                  0,                                      0,                                      0                               },\r
5091         {"ret",                         0,                              PARAM_I16,                      0,                                      0,                              DASMFLAG_STEP_OUT},\r
5092         {"ret",                         0,                              0,                                      0,                                      0,                              DASMFLAG_STEP_OUT},\r
5093         {"mov     ds1,",        MODRM,                  PARAM_REG16,            PARAM_RM16,                     0                               },\r
5094         {"mov     ds0,",        MODRM,                  PARAM_REG16,            PARAM_RM16,                     0                               },\r
5095         {"mov",                         MODRM,                  PARAM_RMPTR8,           PARAM_UI8,                      0                               },\r
5096         {"mov",                         MODRM,                  PARAM_RMPTR16,          PARAM_IMM,                      0                               },\r
5097         {"prepare",                     0,                              PARAM_I16,                      PARAM_UI8,                      0                               },\r
5098         {"dispose",                     0,                              0,                                      0,                                      0                               },\r
5099         {"retf",                        0,                              PARAM_I16,                      0,                                      0,                              DASMFLAG_STEP_OUT},\r
5100         {"retf",                        0,                              0,                                      0,                                      0,                              DASMFLAG_STEP_OUT},\r
5101         {"brk     3",           0,                              0,                                      0,                                      0,                              DASMFLAG_STEP_OVER},\r
5102         {"brk",                         0,                              PARAM_UI8,                      0,                                      0,                              DASMFLAG_STEP_OVER},\r
5103         {"brkv",                        0,                              0,                                      0,                                      0                               },\r
5104         {"reti",                        0,                              0,                                      0,                                      0,                              DASMFLAG_STEP_OUT},\r
5105         // 0xd0\r
5106         {"shiftb",                      GROUP,                  0,                                      0,                                      0                               },\r
5107         {"shiftw",                      GROUP,                  0,                                      0,                                      0                               },\r
5108         {"shiftbv",                     GROUP,                  0,                                      0,                                      0                               },\r
5109         {"shiftwv",                     GROUP,                  0,                                      0,                                      0                               },\r
5110         {"cvtbd",                       0,                              PARAM_I8,                       0,                                      0                               },\r
5111         {"cvtdb",                       0,                              PARAM_I8,                       0,                                      0                               },\r
5112         {"???",                         0,                              0,                                      0,                                      0                               },\r
5113         {"trans",                       0,                              0,                                      0,                                      0                               },\r
5114         {"escape",                      FPU,                    0,                                      0,                                      0                               },\r
5115         {"escape",                      FPU,                    0,                                      0,                                      0                               },\r
5116         {"escape",                      FPU,                    0,                                      0,                                      0                               },\r
5117         {"escape",                      FPU,                    0,                                      0,                                      0                               },\r
5118         {"escape",                      FPU,                    0,                                      0,                                      0                               },\r
5119         {"escape",                      FPU,                    0,                                      0,                                      0                               },\r
5120         {"escape",                      FPU,                    0,                                      0,                                      0                               },\r
5121         {"escape",                      FPU,                    0,                                      0,                                      0                               },\r
5122         // 0xe0\r
5123         {"dbnzne",                      0,                              PARAM_REL8,                     0,                                      0,                              DASMFLAG_STEP_OVER},\r
5124         {"dbnze",                       0,                              PARAM_REL8,                     0,                                      0,                              DASMFLAG_STEP_OVER},\r
5125         {"dbnz",                        0,                              PARAM_REL8,                     0,                                      0,                              DASMFLAG_STEP_OVER},\r
5126         {"bcwz",                        0,                              PARAM_REL8,                     0,                                      0                               },\r
5127         {"in",                          0,                              PARAM_AL,                       PARAM_UI8,                      0                               },\r
5128         {"in",                          0,                              PARAM_AW,                       PARAM_UI8,                      0                               },\r
5129         {"out",                         0,                              PARAM_UI8,                      PARAM_AL,                       0                               },\r
5130         {"out",                         0,                              PARAM_UI8,                      PARAM_AW,                       0                               },\r
5131         {"call",                        0,                              PARAM_REL16,            0,                                      0,                              DASMFLAG_STEP_OVER},\r
5132         {"br",                          0,                              PARAM_REL16,            0,                                      0                               },\r
5133         {"br",                          0,                              PARAM_ADDR,                     0,                                      0                               },\r
5134         {"br",                          0,                              PARAM_REL8,                     0,                                      0                               },\r
5135         {"in",                          0,                              PARAM_AL,                       PARAM_DW,                       0                               },\r
5136         {"in",                          0,                              PARAM_AW,                       PARAM_DW,                       0                               },\r
5137         {"out",                         0,                              PARAM_DW,                       PARAM_AL,                       0                               },\r
5138         {"out",                         0,                              PARAM_DW,                       PARAM_AW,                       0                               },\r
5139         // 0xf0\r
5140         {"buslock",                     PREFIX,                 0,                                      0,                                      0                               },\r
5141         {"brks",                        0,                              PARAM_UI8,                      0,                                      0,                              DASMFLAG_STEP_OVER},    /* V25S/V35S only */\r
5142         {"repne",                       PREFIX,                 0,                                      0,                                      0                               },\r
5143         {"rep",                         PREFIX,                 0,                                      0,                                      0                               },\r
5144         {"halt",                        0,                              0,                                      0,                                      0                               },\r
5145         {"not1    cy",          0,                              0,                                      0,                                      0                               },\r
5146         {"group1b",                     GROUP,                  0,                                      0,                                      0                               },\r
5147         {"group1w",                     GROUP,                  0,                                      0,                                      0                               },\r
5148         {"clr1    cy",          0,                              0,                                      0,                                      0                               },\r
5149         {"set1    cy",          0,                              0,                                      0,                                      0                               },\r
5150         {"di",                          0,                              0,                                      0,                                      0                               },\r
5151         {"ei",                          0,                              0,                                      0,                                      0                               },\r
5152         {"clr1    dir",         0,                              0,                                      0,                                      0                               },\r
5153         {"set1    dir",         0,                              0,                                      0,                                      0                               },\r
5154         {"group2b",                     GROUP,                  0,                                      0,                                      0                               },\r
5155         {"group2w",                     GROUP,                  0,                                      0,                                      0                               }\r
5156 };\r
5157 \r
5158 static const I386_OPCODE necv_opcode_table2[256] =\r
5159 {\r
5160         // 0x00\r
5161         {"???",                         0,                              0,                                      0,                                      0                               },\r
5162         {"???",                         0,                              0,                                      0,                                      0                               },\r
5163         {"???",                         0,                              0,                                      0,                                      0                               },\r
5164         {"???",                         0,                              0,                                      0,                                      0                               },\r
5165         {"???",                         0,                              0,                                      0,                                      0                               },\r
5166         {"???",                         0,                              0,                                      0,                                      0                               },\r
5167         {"???",                         0,                              0,                                      0,                                      0                               },\r
5168         {"???",                         0,                              0,                                      0,                                      0                               },\r
5169         {"???",                         0,                              0,                                      0,                                      0                               },\r
5170         {"???",                         0,                              0,                                      0,                                      0                               },\r
5171         {"???",                         0,                              0,                                      0,                                      0                               },\r
5172         {"???",                         0,                              0,                                      0,                                      0                               },\r
5173         {"???",                         0,                              0,                                      0,                                      0                               },\r
5174         {"???",                         0,                              0,                                      0,                                      0                               },\r
5175         {"???",                         0,                              0,                                      0,                                      0                               },\r
5176         {"???",                         0,                              0,                                      0,                                      0                               },\r
5177         // 0x10\r
5178         {"test1",                       MODRM,                  PARAM_RMPTR8,           PARAM_CL,                       0                               },\r
5179         {"test1",                       MODRM,                  PARAM_RMPTR16,          PARAM_CL,                       0                               },\r
5180         {"clr1",                        MODRM,                  PARAM_RMPTR8,           PARAM_CL,                       0                               },\r
5181         {"clr1",                        MODRM,                  PARAM_RMPTR16,          PARAM_CL,                       0                               },\r
5182         {"set1",                        MODRM,                  PARAM_RMPTR8,           PARAM_CL,                       0                               },\r
5183         {"set1",                        MODRM,                  PARAM_RMPTR16,          PARAM_CL,                       0                               },\r
5184         {"not1",                        MODRM,                  PARAM_RMPTR8,           PARAM_CL,                       0                               },\r
5185         {"not1",                        MODRM,                  PARAM_RMPTR16,          PARAM_CL,                       0                               },\r
5186         {"test1",                       MODRM,                  PARAM_RMPTR8,           PARAM_I3,                       0                               },\r
5187         {"test1",                       MODRM,                  PARAM_RMPTR16,          PARAM_I4,                       0                               },\r
5188         {"clr1",                        MODRM,                  PARAM_RMPTR8,           PARAM_I3,                       0                               },\r
5189         {"clr1",                        MODRM,                  PARAM_RMPTR16,          PARAM_I4,                       0                               },\r
5190         {"set1",                        MODRM,                  PARAM_RMPTR8,           PARAM_I3,                       0                               },\r
5191         {"set1",                        MODRM,                  PARAM_RMPTR16,          PARAM_I4,                       0                               },\r
5192         {"not1",                        MODRM,                  PARAM_RMPTR8,           PARAM_I3,                       0                               },\r
5193         {"not1",                        MODRM,                  PARAM_RMPTR16,          PARAM_I4,                       0                               },\r
5194         // 0x20\r
5195         {"add4s",                       0,                              0,                                      0,                                      0                               },\r
5196         {"???",                         0,                              0,                                      0,                                      0                               },\r
5197         {"sub4s",                       0,                              0,                                      0,                                      0                               },\r
5198         {"???",                         0,                              0,                                      0,                                      0                               },\r
5199         {"???",                         0,                              0,                                      0,                                      0                               },\r
5200         {"movspa",                      0,                              0,                                      0,                                      0                               },      /* V25/V35 only */\r
5201         {"cmp4s",                       0,                              0,                                      0,                                      0                               },\r
5202         {"???",                         0,                              0,                                      0,                                      0                               },\r
5203         {"rol4",                        MODRM,                  PARAM_RMPTR8,           0,                                      0                               },\r
5204         {"???",                         0,                              0,                                      0,                                      0                               },\r
5205         {"ror4",                        MODRM,                  PARAM_RMPTR8,           0,                                      0                               },\r
5206         {"???",                         0,                              0,                                      0,                                      0                               },\r
5207         {"???",                         0,                              0,                                      0,                                      0                               },\r
5208         {"brkcs",                       MODRM,                  PARAM_REG2_16,          0,                                      0,                              DASMFLAG_STEP_OVER},    /* V25/V35 only */\r
5209         {"???",                         0,                              0,                                      0,                                      0                               },\r
5210         {"???",                         0,                              0,                                      0,                                      0                               },\r
5211         // 0x30\r
5212         {"???",                         0,                              0,                                      0,                                      0                               },\r
5213         {"ins",                         MODRM,                  PARAM_REG2_8,           PARAM_REG8,                     0                               },\r
5214         {"???",                         0,                              0,                                      0,                                      0                               },\r
5215         {"ext",                         MODRM,                  PARAM_REG2_8,           PARAM_REG8,                     0                               },\r
5216         {"???",                         0,                              0,                                      0,                                      0                               },\r
5217         {"???",                         0,                              0,                                      0,                                      0                               },\r
5218         {"???",                         0,                              0,                                      0,                                      0                               },\r
5219         {"???",                         0,                              0,                                      0,                                      0                               },\r
5220         {"???",                         0,                              0,                                      0,                                      0                               },\r
5221         {"ins",                         MODRM,                  PARAM_REG2_8,           PARAM_I4,                       0                               },\r
5222         {"???",                         0,                              0,                                      0,                                      0                               },\r
5223         {"ext",                         MODRM,                  PARAM_REG2_8,           PARAM_I4,                       0                               },\r
5224         {"???",                         0,                              0,                                      0,                                      0                               },\r
5225         {"???",                         0,                              0,                                      0,                                      0                               },\r
5226         {"???",                         0,                              0,                                      0,                                      0                               },\r
5227         {"???",                         0,                              0,                                      0,                                      0                               },\r
5228         // 0x40\r
5229         {"???",                         0,                              0,                                      0,                                      0                               },\r
5230         {"???",                         0,                              0,                                      0,                                      0                               },\r
5231         {"???",                         0,                              0,                                      0,                                      0                               },\r
5232         {"???",                         0,                              0,                                      0,                                      0                               },\r
5233         {"???",                         0,                              0,                                      0,                                      0                               },\r
5234         {"???",                         0,                              0,                                      0,                                      0                               },\r
5235         {"???",                         0,                              0,                                      0,                                      0                               },\r
5236         {"???",                         0,                              0,                                      0,                                      0                               },\r
5237         {"???",                         0,                              0,                                      0,                                      0                               },\r
5238         {"???",                         0,                              0,                                      0,                                      0                               },\r
5239         {"???",                         0,                              0,                                      0,                                      0                               },\r
5240         {"???",                         0,                              0,                                      0,                                      0                               },\r
5241         {"???",                         0,                              0,                                      0,                                      0                               },\r
5242         {"???",                         0,                              0,                                      0,                                      0                               },\r
5243         {"???",                         0,                              0,                                      0,                                      0                               },\r
5244         {"???",                         0,                              0,                                      0,                                      0                               },\r
5245         // 0x50\r
5246         {"???",                         0,                              0,                                      0,                                      0                               },\r
5247         {"???",                         0,                              0,                                      0,                                      0                               },\r
5248         {"???",                         0,                              0,                                      0,                                      0                               },\r
5249         {"???",                         0,                              0,                                      0,                                      0                               },\r
5250         {"???",                         0,                              0,                                      0,                                      0                               },\r
5251         {"???",                         0,                              0,                                      0,                                      0                               },\r
5252         {"???",                         0,                              0,                                      0,                                      0                               },\r
5253         {"???",                         0,                              0,                                      0,                                      0                               },\r
5254         {"???",                         0,                              0,                                      0,                                      0                               },\r
5255         {"???",                         0,                              0,                                      0,                                      0                               },\r
5256         {"???",                         0,                              0,                                      0,                                      0                               },\r
5257         {"???",                         0,                              0,                                      0,                                      0                               },\r
5258         {"???",                         0,                              0,                                      0,                                      0                               },\r
5259         {"???",                         0,                              0,                                      0,                                      0                               },\r
5260         {"???",                         0,                              0,                                      0,                                      0                               },\r
5261         {"???",                         0,                              0,                                      0,                                      0                               },\r
5262         // 0x60\r
5263         {"???",                         0,                              0,                                      0,                                      0                               },\r
5264         {"???",                         0,                              0,                                      0,                                      0                               },\r
5265         {"???",                         0,                              0,                                      0,                                      0                               },\r
5266         {"???",                         0,                              0,                                      0,                                      0                               },\r
5267         {"???",                         0,                              0,                                      0,                                      0                               },\r
5268         {"???",                         0,                              0,                                      0,                                      0                               },\r
5269         {"???",                         0,                              0,                                      0,                                      0                               },\r
5270         {"???",                         0,                              0,                                      0,                                      0                               },\r
5271         {"???",                         0,                              0,                                      0,                                      0                               },\r
5272         {"???",                         0,                              0,                                      0,                                      0                               },\r
5273         {"???",                         0,                              0,                                      0,                                      0                               },\r
5274         {"???",                         0,                              0,                                      0,                                      0                               },\r
5275         {"???",                         0,                              0,                                      0,                                      0                               },\r
5276         {"???",                         0,                              0,                                      0,                                      0                               },\r
5277         {"???",                         0,                              0,                                      0,                                      0                               },\r
5278         {"???",                         0,                              0,                                      0,                                      0                               },\r
5279         // 0x70\r
5280         {"???",                         0,                              0,                                      0,                                      0                               },\r
5281         {"???",                         0,                              0,                                      0,                                      0                               },\r
5282         {"???",                         0,                              0,                                      0,                                      0                               },\r
5283         {"???",                         0,                              0,                                      0,                                      0                               },\r
5284         {"???",                         0,                              0,                                      0,                                      0                               },\r
5285         {"???",                         0,                              0,                                      0,                                      0                               },\r
5286         {"???",                         0,                              0,                                      0,                                      0                               },\r
5287         {"???",                         0,                              0,                                      0,                                      0                               },\r
5288         {"???",                         0,                              0,                                      0,                                      0                               },\r
5289         {"???",                         0,                              0,                                      0,                                      0                               },\r
5290         {"???",                         0,                              0,                                      0,                                      0                               },\r
5291         {"???",                         0,                              0,                                      0,                                      0                               },\r
5292         {"???",                         0,                              0,                                      0,                                      0                               },\r
5293         {"???",                         0,                              0,                                      0,                                      0                               },\r
5294         {"???",                         0,                              0,                                      0,                                      0                               },\r
5295         {"???",                         0,                              0,                                      0,                                      0                               },\r
5296         // 0x80\r
5297         {"???",                         0,                              0,                                      0,                                      0                               },\r
5298         {"???",                         0,                              0,                                      0,                                      0                               },\r
5299         {"???",                         0,                              0,                                      0,                                      0                               },\r
5300         {"???",                         0,                              0,                                      0,                                      0                               },\r
5301         {"???",                         0,                              0,                                      0,                                      0                               },\r
5302         {"???",                         0,                              0,                                      0,                                      0                               },\r
5303         {"???",                         0,                              0,                                      0,                                      0                               },\r
5304         {"???",                         0,                              0,                                      0,                                      0                               },\r
5305         {"???",                         0,                              0,                                      0,                                      0                               },\r
5306         {"???",                         0,                              0,                                      0,                                      0                               },\r
5307         {"???",                         0,                              0,                                      0,                                      0                               },\r
5308         {"???",                         0,                              0,                                      0,                                      0                               },\r
5309         {"???",                         0,                              0,                                      0,                                      0                               },\r
5310         {"???",                         0,                              0,                                      0,                                      0                               },\r
5311         {"???",                         0,                              0,                                      0,                                      0                               },\r
5312         {"???",                         0,                              0,                                      0,                                      0                               },\r
5313         // 0x90\r
5314         {"???",                         0,                              0,                                      0,                                      0                               },\r
5315         {"retrbi",                      0,                              0,                                      0,                                      0                               },      /* V25/V35 only */\r
5316         {"fint",                        0,                              0,                                      0,                                      0                               },      /* V25/V35 only */\r
5317         {"???",                         0,                              0,                                      0,                                      0                               },\r
5318         {"tsksw",                       MODRM,                  PARAM_REG2_16,          0,                                      0                               },      /* V25/V35 only */\r
5319         {"movspb",                      MODRM,                  PARAM_REG2_16,          0,                                      0                               },      /* V25/V35 only */\r
5320         {"???",                         0,                              0,                                      0,                                      0                               },\r
5321         {"???",                         0,                              0,                                      0,                                      0                               },\r
5322         {"???",                         0,                              0,                                      0,                                      0                               },\r
5323         {"???",                         0,                              0,                                      0,                                      0                               },\r
5324         {"???",                         0,                              0,                                      0,                                      0                               },\r
5325         {"???",                         0,                              0,                                      0,                                      0                               },\r
5326         {"btclr",                       0,                              PARAM_SFREG,            PARAM_I3,                       PARAM_REL8              },      /* V25/V35 only */\r
5327         {"???",                         0,                              0,                                      0,                                      0                               },\r
5328         {"stop",                        0,                              0,                                      0,                                      0                               },      /* V25/V35 only */\r
5329         {"???",                         0,                              0,                                      0,                                      0                               },\r
5330         // 0xa0\r
5331         {"???",                         0,                              0,                                      0,                                      0                               },\r
5332         {"???",                         0,                              0,                                      0,                                      0                               },\r
5333         {"???",                         0,                              0,                                      0,                                      0                               },\r
5334         {"???",                         0,                              0,                                      0,                                      0                               },\r
5335         {"???",                         0,                              0,                                      0,                                      0                               },\r
5336         {"???",                         0,                              0,                                      0,                                      0                               },\r
5337         {"???",                         0,                              0,                                      0,                                      0                               },\r
5338         {"???",                         0,                              0,                                      0,                                      0                               },\r
5339         {"???",                         0,                              0,                                      0,                                      0                               },\r
5340         {"???",                         0,                              0,                                      0,                                      0                               },\r
5341         {"???",                         0,                              0,                                      0,                                      0                               },\r
5342         {"???",                         0,                              0,                                      0,                                      0                               },\r
5343         {"???",                         0,                              0,                                      0,                                      0                               },\r
5344         {"???",                         0,                              0,                                      0,                                      0                               },\r
5345         {"???",                         0,                              0,                                      0,                                      0                               },\r
5346         {"???",                         0,                              0,                                      0,                                      0                               },\r
5347         // 0xb0\r
5348         {"???",                         0,                              0,                                      0,                                      0                               },\r
5349         {"???",                         0,                              0,                                      0,                                      0                               },\r
5350         {"???",                         0,                              0,                                      0,                                      0                               },\r
5351         {"???",                         0,                              0,                                      0,                                      0                               },\r
5352         {"???",                         0,                              0,                                      0,                                      0                               },\r
5353         {"???",                         0,                              0,                                      0,                                      0                               },\r
5354         {"???",                         0,                              0,                                      0,                                      0                               },\r
5355         {"???",                         0,                              0,                                      0,                                      0                               },\r
5356         {"???",                         0,                              0,                                      0,                                      0                               },\r
5357         {"???",                         0,                              0,                                      0,                                      0                               },\r
5358         {"???",                         0,                              0,                                      0,                                      0                               },\r
5359         {"???",                         0,                              0,                                      0,                                      0                               },\r
5360         {"???",                         0,                              0,                                      0,                                      0                               },\r
5361         {"???",                         0,                              0,                                      0,                                      0                               },\r
5362         {"???",                         0,                              0,                                      0,                                      0                               },\r
5363         {"???",                         0,                              0,                                      0,                                      0                               },\r
5364         // 0xc0\r
5365         {"???",                         0,                              0,                                      0,                                      0                               },\r
5366         {"???",                         0,                              0,                                      0,                                      0                               },\r
5367         {"???",                         0,                              0,                                      0,                                      0                               },\r
5368         {"???",                         0,                              0,                                      0,                                      0                               },\r
5369         {"???",                         0,                              0,                                      0,                                      0                               },\r
5370         {"???",                         0,                              0,                                      0,                                      0                               },\r
5371         {"???",                         0,                              0,                                      0,                                      0                               },\r
5372         {"???",                         0,                              0,                                      0,                                      0                               },\r
5373         {"???",                         0,                              0,                                      0,                                      0                               },\r
5374         {"???",                         0,                              0,                                      0,                                      0                               },\r
5375         {"???",                         0,                              0,                                      0,                                      0                               },\r
5376         {"???",                         0,                              0,                                      0,                                      0                               },\r
5377         {"???",                         0,                              0,                                      0,                                      0                               },\r
5378         {"???",                         0,                              0,                                      0,                                      0                               },\r
5379         {"???",                         0,                              0,                                      0,                                      0                               },\r
5380         {"???",                         0,                              0,                                      0,                                      0                               },\r
5381         // 0xd0\r
5382         {"???",                         0,                              0,                                      0,                                      0                               },\r
5383         {"???",                         0,                              0,                                      0,                                      0                               },\r
5384         {"???",                         0,                              0,                                      0,                                      0                               },\r
5385         {"???",                         0,                              0,                                      0,                                      0                               },\r
5386         {"???",                         0,                              0,                                      0,                                      0                               },\r
5387         {"???",                         0,                              0,                                      0,                                      0                               },\r
5388         {"???",                         0,                              0,                                      0,                                      0                               },\r
5389         {"???",                         0,                              0,                                      0,                                      0                               },\r
5390         {"???",                         0,                              0,                                      0,                                      0                               },\r
5391         {"???",                         0,                              0,                                      0,                                      0                               },\r
5392         {"???",                         0,                              0,                                      0,                                      0                               },\r
5393         {"???",                         0,                              0,                                      0,                                      0                               },\r
5394         {"???",                         0,                              0,                                      0,                                      0                               },\r
5395         {"???",                         0,                              0,                                      0,                                      0                               },\r
5396         {"???",                         0,                              0,                                      0,                                      0                               },\r
5397         {"???",                         0,                              0,                                      0,                                      0                               },\r
5398         // 0xe0\r
5399         {"brkxa",                       0,                              PARAM_UI8,                      0,                                      0                               },      /* V33,53 only */\r
5400         {"???",                         0,                              0,                                      0,                                      0                               },\r
5401         {"???",                         0,                              0,                                      0,                                      0                               },\r
5402         {"???",                         0,                              0,                                      0,                                      0                               },\r
5403         {"???",                         0,                              0,                                      0,                                      0                               },\r
5404         {"???",                         0,                              0,                                      0,                                      0                               },\r
5405         {"???",                         0,                              0,                                      0,                                      0                               },\r
5406         {"???",                         0,                              0,                                      0,                                      0                               },\r
5407         {"???",                         0,                              0,                                      0,                                      0                               },\r
5408         {"???",                         0,                              0,                                      0,                                      0                               },\r
5409         {"???",                         0,                              0,                                      0,                                      0                               },\r
5410         {"???",                         0,                              0,                                      0,                                      0                               },\r
5411         {"???",                         0,                              0,                                      0,                                      0                               },\r
5412         {"???",                         0,                              0,                                      0,                                      0                               },\r
5413         {"???",                         0,                              0,                                      0,                                      0                               },\r
5414         {"???",                         0,                              0,                                      0,                                      0                               },\r
5415         // 0xf0\r
5416         {"retxa",                       0,                              PARAM_UI8,                      0,                                      0                               },      /* V33,53 only */\r
5417         {"???",                         0,                              0,                                      0,                                      0                               },\r
5418         {"???",                         0,                              0,                                      0,                                      0                               },\r
5419         {"???",                         0,                              0,                                      0,                                      0                               },\r
5420         {"???",                         0,                              0,                                      0,                                      0                               },\r
5421         {"???",                         0,                              0,                                      0,                                      0                               },\r
5422         {"???",                         0,                              0,                                      0,                                      0                               },\r
5423         {"???",                         0,                              0,                                      0,                                      0                               },\r
5424         {"???",                         0,                              0,                                      0,                                      0                               },\r
5425         {"???",                         0,                              0,                                      0,                                      0                               },\r
5426         {"???",                         0,                              0,                                      0,                                      0                               },\r
5427         {"???",                         0,                              0,                                      0,                                      0                               },\r
5428         {"???",                         0,                              0,                                      0,                                      0                               },\r
5429         {"???",                         0,                              0,                                      0,                                      0                               },\r
5430         {"???",                         0,                              0,                                      0,                                      0                               },\r
5431         {"brkem",                       0,                              PARAM_UI8,                      0,                                      0                               }       /* V20,30,40,50 only */\r
5432 };\r
5433 \r
5434 static const I386_OPCODE immb_table[8] =\r
5435 {\r
5436         {"add",                         0,                              PARAM_RMPTR8,           PARAM_UI8,                      0                               },\r
5437         {"or",                          0,                              PARAM_RMPTR8,           PARAM_UI8,                      0                               },\r
5438         {"addc",                        0,                              PARAM_RMPTR8,           PARAM_UI8,                      0                               },\r
5439         {"subc",                        0,                              PARAM_RMPTR8,           PARAM_UI8,                      0                               },\r
5440         {"and",                         0,                              PARAM_RMPTR8,           PARAM_UI8,                      0                               },\r
5441         {"sub",                         0,                              PARAM_RMPTR8,           PARAM_UI8,                      0                               },\r
5442         {"xor",                         0,                              PARAM_RMPTR8,           PARAM_UI8,                      0                               },\r
5443         {"cmp",                         0,                              PARAM_RMPTR8,           PARAM_UI8,                      0                               }\r
5444 };\r
5445 \r
5446 static const I386_OPCODE immw_table[8] =\r
5447 {\r
5448         {"add",                         0,                              PARAM_RMPTR16,          PARAM_IMM,                      0                               },\r
5449         {"or",                          0,                              PARAM_RMPTR16,          PARAM_IMM,                      0                               },\r
5450         {"addc",                        0,                              PARAM_RMPTR16,          PARAM_IMM,                      0                               },\r
5451         {"subc",                        0,                              PARAM_RMPTR16,          PARAM_IMM,                      0                               },\r
5452         {"and",                         0,                              PARAM_RMPTR16,          PARAM_IMM,                      0                               },\r
5453         {"sub",                         0,                              PARAM_RMPTR16,          PARAM_IMM,                      0                               },\r
5454         {"xor",                         0,                              PARAM_RMPTR16,          PARAM_IMM,                      0                               },\r
5455         {"cmp",                         0,                              PARAM_RMPTR16,          PARAM_IMM,                      0                               }\r
5456 };\r
5457 \r
5458 static const I386_OPCODE immws_table[8] =\r
5459 {\r
5460         {"add",                         0,                              PARAM_RMPTR16,          PARAM_I8,                       0                               },\r
5461         {"or",                          0,                              PARAM_RMPTR16,          PARAM_I8,                       0                               },\r
5462         {"addc",                        0,                              PARAM_RMPTR16,          PARAM_I8,                       0                               },\r
5463         {"subc",                        0,                              PARAM_RMPTR16,          PARAM_I8,                       0                               },\r
5464         {"and",                         0,                              PARAM_RMPTR16,          PARAM_I8,                       0                               },\r
5465         {"sub",                         0,                              PARAM_RMPTR16,          PARAM_I8,                       0                               },\r
5466         {"xor",                         0,                              PARAM_RMPTR16,          PARAM_I8,                       0                               },\r
5467         {"cmp",                         0,                              PARAM_RMPTR16,          PARAM_I8,                       0                               }\r
5468 };\r
5469 \r
5470 static const I386_OPCODE shiftbi_table[8] =\r
5471 {\r
5472         {"rol",                         0,                              PARAM_RMPTR8,           PARAM_I8,                       0                               },\r
5473         {"ror",                         0,                              PARAM_RMPTR8,           PARAM_I8,                       0                               },\r
5474         {"rolc",                        0,                              PARAM_RMPTR8,           PARAM_I8,                       0                               },\r
5475         {"rorc",                        0,                              PARAM_RMPTR8,           PARAM_I8,                       0                               },\r
5476         {"shl",                         0,                              PARAM_RMPTR8,           PARAM_I8,                       0                               },\r
5477         {"shr",                         0,                              PARAM_RMPTR8,           PARAM_I8,                       0                               },\r
5478         {"???",                         0,                              PARAM_RMPTR8,           PARAM_I8,                       0                               },\r
5479         {"shra",                        0,                              PARAM_RMPTR8,           PARAM_I8,                       0                               }\r
5480 };\r
5481 \r
5482 static const I386_OPCODE shiftwi_table[8] =\r
5483 {\r
5484         {"rol",                         0,                              PARAM_RMPTR16,          PARAM_I8,                       0                               },\r
5485         {"ror",                         0,                              PARAM_RMPTR16,          PARAM_I8,                       0                               },\r
5486         {"rolc",                        0,                              PARAM_RMPTR16,          PARAM_I8,                       0                               },\r
5487         {"rorc",                        0,                              PARAM_RMPTR16,          PARAM_I8,                       0                               },\r
5488         {"shl",                         0,                              PARAM_RMPTR16,          PARAM_I8,                       0                               },\r
5489         {"shr",                         0,                              PARAM_RMPTR16,          PARAM_I8,                       0                               },\r
5490         {"???",                         0,                              PARAM_RMPTR16,          PARAM_I8,                       0                               },\r
5491         {"shra",                        0,                              PARAM_RMPTR16,          PARAM_I8,                       0                               }\r
5492 };\r
5493 \r
5494 static const I386_OPCODE shiftb_table[8] =\r
5495 {\r
5496         {"rol",                         0,                              PARAM_RMPTR8,           PARAM_1,                        0                               },\r
5497         {"ror",                         0,                              PARAM_RMPTR8,           PARAM_1,                        0                               },\r
5498         {"rolc",                        0,                              PARAM_RMPTR8,           PARAM_1,                        0                               },\r
5499         {"rorc",                        0,                              PARAM_RMPTR8,           PARAM_1,                        0                               },\r
5500         {"shl",                         0,                              PARAM_RMPTR8,           PARAM_1,                        0                               },\r
5501         {"shr",                         0,                              PARAM_RMPTR8,           PARAM_1,                        0                               },\r
5502         {"???",                         0,                              PARAM_RMPTR8,           PARAM_1,                        0                               },\r
5503         {"shra",                        0,                              PARAM_RMPTR8,           PARAM_1,                        0                               }\r
5504 };\r
5505 \r
5506 static const I386_OPCODE shiftw_table[8] =\r
5507 {\r
5508         {"rol",                         0,                              PARAM_RMPTR16,          PARAM_1,                        0                               },\r
5509         {"ror",                         0,                              PARAM_RMPTR16,          PARAM_1,                        0                               },\r
5510         {"rolc",                        0,                              PARAM_RMPTR16,          PARAM_1,                        0                               },\r
5511         {"rorc",                        0,                              PARAM_RMPTR16,          PARAM_1,                        0                               },\r
5512         {"shl",                         0,                              PARAM_RMPTR16,          PARAM_1,                        0                               },\r
5513         {"shr",                         0,                              PARAM_RMPTR16,          PARAM_1,                        0                               },\r
5514         {"???",                         0,                              PARAM_RMPTR16,          PARAM_1,                        0                               },\r
5515         {"shra",                        0,                              PARAM_RMPTR16,          PARAM_1,                        0                               }\r
5516 };\r
5517 \r
5518 static const I386_OPCODE shiftbv_table[8] =\r
5519 {\r
5520         {"rol",                         0,                              PARAM_RMPTR8,           PARAM_CL,                       0                               },\r
5521         {"ror",                         0,                              PARAM_RMPTR8,           PARAM_CL,                       0                               },\r
5522         {"rolc",                        0,                              PARAM_RMPTR8,           PARAM_CL,                       0                               },\r
5523         {"rorc",                        0,                              PARAM_RMPTR8,           PARAM_CL,                       0                               },\r
5524         {"shl",                         0,                              PARAM_RMPTR8,           PARAM_CL,                       0                               },\r
5525         {"shr",                         0,                              PARAM_RMPTR8,           PARAM_CL,                       0                               },\r
5526         {"???",                         0,                              PARAM_RMPTR8,           PARAM_CL,                       0                               },\r
5527         {"shra",                        0,                              PARAM_RMPTR8,           PARAM_CL,                       0                               }\r
5528 };\r
5529 \r
5530 static const I386_OPCODE shiftwv_table[8] =\r
5531 {\r
5532         {"rol",                         0,                              PARAM_RMPTR16,          PARAM_CL,                       0                               },\r
5533         {"ror",                         0,                              PARAM_RMPTR16,          PARAM_CL,                       0                               },\r
5534         {"rolc",                        0,                              PARAM_RMPTR16,          PARAM_CL,                       0                               },\r
5535         {"rorc",                        0,                              PARAM_RMPTR16,          PARAM_CL,                       0                               },\r
5536         {"shl",                         0,                              PARAM_RMPTR16,          PARAM_CL,                       0                               },\r
5537         {"shr",                         0,                              PARAM_RMPTR16,          PARAM_CL,                       0                               },\r
5538         {"???",                         0,                              PARAM_RMPTR16,          PARAM_CL,                       0                               },\r
5539         {"shra",                        0,                              PARAM_RMPTR16,          PARAM_CL,                       0                               }\r
5540 };\r
5541 \r
5542 static const I386_OPCODE group1b_table[8] =\r
5543 {\r
5544         {"test",                        0,                              PARAM_RMPTR8,           PARAM_UI8,                      0                               },\r
5545         {"???",                         0,                              0,                                      0,                                      0                               },\r
5546         {"not",                         0,                              PARAM_RMPTR8,           0,                                      0                               },\r
5547         {"neg",                         0,                              PARAM_RMPTR8,           0,                                      0                               },\r
5548         {"mulu",                        0,                              PARAM_RMPTR8,           0,                                      0                               },\r
5549         {"mul",                         0,                              PARAM_RMPTR8,           0,                                      0                               },\r
5550         {"divu",                        0,                              PARAM_RMPTR8,           0,                                      0                               },\r
5551         {"div",                         0,                              PARAM_RMPTR8,           0,                                      0                               }\r
5552 };\r
5553 \r
5554 static const I386_OPCODE group1w_table[8] =\r
5555 {\r
5556         {"test",                        0,                              PARAM_RMPTR16,          PARAM_IMM,                      0                               },\r
5557         {"???",                         0,                              0,                                      0,                                      0                               },\r
5558         {"not",                         0,                              PARAM_RMPTR16,          0,                                      0                               },\r
5559         {"neg",                         0,                              PARAM_RMPTR16,          0,                                      0                               },\r
5560         {"mulu",                        0,                              PARAM_RMPTR16,          0,                                      0                               },\r
5561         {"mul",                         0,                              PARAM_RMPTR16,          0,                                      0                               },\r
5562         {"divu",                        0,                              PARAM_RMPTR16,          0,                                      0                               },\r
5563         {"div",                         0,                              PARAM_RMPTR16,          0,                                      0                               }\r
5564 };\r
5565 \r
5566 static const I386_OPCODE group2b_table[8] =\r
5567 {\r
5568         {"inc",                         0,                              PARAM_RMPTR8,           0,                                      0                               },\r
5569         {"dec",                         0,                              PARAM_RMPTR8,           0,                                      0                               },\r
5570         {"???",                         0,                              0,                                      0,                                      0                               },\r
5571         {"???",                         0,                              0,                                      0,                                      0                               },\r
5572         {"???",                         0,                              0,                                      0,                                      0                               },\r
5573         {"???",                         0,                              0,                                      0,                                      0                               },\r
5574         {"???",                         0,                              0,                                      0,                                      0                               },\r
5575         {"???",                         0,                              0,                                      0,                                      0                               }\r
5576 };\r
5577 \r
5578 static const I386_OPCODE group2w_table[8] =\r
5579 {\r
5580         {"inc",                         0,                              PARAM_RMPTR16,          0,                                      0                               },\r
5581         {"dec",                         0,                              PARAM_RMPTR16,          0,                                      0                               },\r
5582         {"call",                        0,                              PARAM_RMPTR16,          0,                                      0,                              DASMFLAG_STEP_OVER},\r
5583         {"call    far ptr ",0,                          PARAM_RM16,                     0,                                      0,                              DASMFLAG_STEP_OVER},\r
5584         {"br",                          0,                              PARAM_RMPTR16,          0,                                      0                               },\r
5585         {"br      far ptr ",0,                          PARAM_RM16,                     0,                                      0                               },\r
5586         {"push",                        0,                              PARAM_RMPTR16,          0,                                      0                               },\r
5587         {"???",                         0,                              0,                                      0,                                      0                               }\r
5588 };\r
5589 \r
5590 static const GROUP_OP group_op_table[] =\r
5591 {\r
5592         { "immb",                               immb_table                              },\r
5593         { "immw",                               immw_table                              },\r
5594         { "immws",                              immws_table                             },\r
5595         { "shiftbi",                    shiftbi_table                   },\r
5596         { "shiftwi",                    shiftwi_table                   },\r
5597         { "shiftb",                             shiftb_table                    },\r
5598         { "shiftw",                             shiftw_table                    },\r
5599         { "shiftbv",                    shiftbv_table                   },\r
5600         { "shiftwv",                    shiftwv_table                   },\r
5601         { "group1b",                    group1b_table                   },\r
5602         { "group1w",                    group1w_table                   },\r
5603         { "group2b",                    group2b_table                   },\r
5604         { "group2w",                    group2w_table                   }\r
5605 };\r
5606 \r
5607 \r
5608 \r
5609 static const char *const nec_reg[8] = { "aw",  "cw",  "dw",  "bw",  "sp",  "bp",  "ix",  "iy" };\r
5610 static const char *const nec_reg8[8] = { "al", "cl", "dl", "bl", "ah", "ch", "dh", "bh" };\r
5611 static const char *const nec_sreg[8] = { "ds1", "ps", "ss", "ds0", "???", "???", "???", "???" };\r
5612 static const char *const nec_sfreg[256] =\r
5613 {\r
5614         /* 0x00 */\r
5615         "p0",   "pm0",  "pmc0", "???",  "???",  "???",  "???",  "???",\r
5616         "p1",   "pm1",  "pmc1", "???",  "???",  "???",  "???",  "???",\r
5617         /* 0x10 */\r
5618         "p2",   "pm2",  "pmc2", "???",  "???",  "???",  "???",  "???",\r
5619         "???",  "???",  "???",  "???",  "???",  "???",  "???",  "???",\r
5620         /* 0x20 */\r
5621         "???",  "???",  "???",  "???",  "???",  "???",  "???",  "???",\r
5622         "???",  "???",  "???",  "???",  "???",  "???",  "???",  "???",\r
5623         /* 0x30 */\r
5624         "???",  "???",  "???",  "???",  "???",  "???",  "???",  "???",\r
5625         "pt",   "???",  "???",  "pmt",  "???",  "???",  "???",  "???",\r
5626         /* 0x40 */\r
5627         "intm", "???",  "???",  "???",  "ems0", "ems1", "ems2", "???",\r
5628         "???",  "???",  "???",  "???",  "exic0","exic1","exic2","???",\r
5629         /* 0x50 */\r
5630         "???",  "???",  "???",  "???",  "???",  "???",  "???",  "???",\r
5631         "???",  "???",  "???",  "???",  "???",  "???",  "???",  "???",\r
5632         /* 0x60 */\r
5633         "rxb0", "???",  "txb0", "???",  "???",  "srms0","stms0","???",\r
5634         "scm0", "scc0", "brg0", "scs0", "seic0","sric0","stic0","???",\r
5635         /* 0x70 */\r
5636         "rxb1", "???",  "txb1", "???",  "???",  "srms1","stms1","???",\r
5637         "scm1", "scc1", "brg1", "scs1", "seic1","sric1","stic1","???",\r
5638         /* 0x80 */\r
5639         "tm0",  "???",  "md0",  "???",  "???",  "???",  "???",  "???",\r
5640         "tm1",  "???",  "md1",  "???",  "???",  "???",  "???",  "???",\r
5641         /* 0x90 */\r
5642         "tmc0", "tmc1", "???",  "???",  "tmms0","tmms1","tmms2","???",\r
5643         "???",  "???",  "???",  "???",  "tmic0","tmic1","tmic2","???",\r
5644         /* 0xa0 */\r
5645         "dmac0","dmam0","dmac1","dmam1","???",  "???",  "???",  "???",\r
5646         "???",  "???",  "???",  "???",  "dic0", "dic1", "???",  "???",\r
5647         /* 0xb0 */\r
5648         "???",  "???",  "???",  "???",  "???",  "???",  "???",  "???",\r
5649         "???",  "???",  "???",  "???",  "???",  "???",  "???",  "???",\r
5650         /* 0xc0 */\r
5651         "sar0l","sar0m","sar0h","???",  "dar0l","dar0m","dar0h","???",\r
5652         "tc0l", "tc0h", "???",  "???",  "???",  "???",  "???",  "???",\r
5653         /* 0xd0 */\r
5654         "sar1l","sar1m","sar1h","???",  "dar1l","dar1m","dar1h","???",\r
5655         "tc1l", "tc1h", "???",  "???",  "???",  "???",  "???",  "???",\r
5656         /* 0xe0 */\r
5657         "stbc", "rfm",  "???",  "???",  "???",  "???",  "???",  "???",\r
5658         "wtc",  "???",  "flag", "prc",  "tbic", "???",  "???",  "irqs",\r
5659         /* 0xf0 */\r
5660         "???",  "???",  "???",  "???",  "???",  "???",  "???",  "???",\r
5661         "???",  "???",  "???",  "???",  "ispr", "???",  "???",  "idb"\r
5662 };\r
5663 \r
5664 static UINT32 pc;\r
5665 static UINT8 modrm;\r
5666 static UINT32 segment;\r
5667 static offs_t dasm_flags;\r
5668 static char modrm_string[256];\r
5669 \r
5670 #define MODRM_REG1      ((modrm >> 3) & 0x7)\r
5671 #define MODRM_REG2      (modrm & 0x7)\r
5672 \r
5673 #define MAX_LENGTH      8\r
5674 \r
5675 INLINE UINT8 FETCHD(void)\r
5676 {\r
5677         if ((opcode_ptr - opcode_ptr_base) + 1 > MAX_LENGTH)\r
5678                 return 0xff;\r
5679         pc++;\r
5680         return *opcode_ptr++;\r
5681 }\r
5682 \r
5683 INLINE UINT16 FETCHD16(void)\r
5684 {\r
5685         UINT16 d;\r
5686         if ((opcode_ptr - opcode_ptr_base) + 2 > MAX_LENGTH)\r
5687                 return 0xffff;\r
5688         d = opcode_ptr[0] | (opcode_ptr[1] << 8);\r
5689         opcode_ptr += 2;\r
5690         pc += 2;\r
5691         return d;\r
5692 }\r
5693 \r
5694 static char *hexstring(UINT32 value, int digits)\r
5695 {\r
5696         static char buffer[20];\r
5697         buffer[0] = '0';\r
5698         if (digits) {\r
5699                 sprintf(&buffer[1], "%0*Xh", digits, value);\r
5700         } else {\r
5701                 sprintf(&buffer[1], "%Xh", value);\r
5702         }\r
5703         return (buffer[1] >= '0' && buffer[1] <= '9') ? &buffer[1] : &buffer[0];\r
5704 }\r
5705 \r
5706 static char *shexstring(UINT32 value, int digits, int always)\r
5707 {\r
5708         static char buffer[20];\r
5709         if (value >= 0x80000000) {\r
5710                 sprintf(buffer, "-%s", hexstring(-value, digits));\r
5711         } else if (always) {\r
5712                 sprintf(buffer, "+%s", hexstring(value, digits));\r
5713         } else {\r
5714                 return hexstring(value, digits);\r
5715         }\r
5716         return buffer;\r
5717 }\r
5718 \r
5719 static void handle_modrm(char* s)\r
5720 {\r
5721         INT8 disp8;\r
5722         INT16 disp16;\r
5723         UINT8 mod, rm;\r
5724 \r
5725         modrm = FETCHD();\r
5726         mod = (modrm >> 6) & 0x3;\r
5727         rm = (modrm & 0x7);\r
5728 \r
5729         if( modrm >= 0xc0 )\r
5730                 return;\r
5731 \r
5732         switch(segment)\r
5733         {\r
5734                 case SEG_PS: s += sprintf( s, "ps:" ); break;\r
5735                 case SEG_DS0: s += sprintf( s, "ds0:" ); break;\r
5736                 case SEG_DS1: s += sprintf( s, "ds1:" ); break;\r
5737                 case SEG_SS: s += sprintf( s, "ss:" ); break;\r
5738         }\r
5739 \r
5740         s += sprintf( s, "[" );\r
5741         switch( rm )\r
5742         {\r
5743                 case 0: s += sprintf( s, "bw+ix" ); break;\r
5744                 case 1: s += sprintf( s, "bw+iy" ); break;\r
5745                 case 2: s += sprintf( s, "bp+ix" ); break;\r
5746                 case 3: s += sprintf( s, "bp+iy" ); break;\r
5747                 case 4: s += sprintf( s, "ix" ); break;\r
5748                 case 5: s += sprintf( s, "iy" ); break;\r
5749                 case 6:\r
5750                         if( mod == 0 ) {\r
5751                                 disp16 = FETCHD16();\r
5752                                 s += sprintf( s, "%s", hexstring((unsigned) (UINT16) disp16, 0) );\r
5753                         } else {\r
5754                                 s += sprintf( s, "bp" );\r
5755                         }\r
5756                         break;\r
5757                 case 7: s += sprintf( s, "bw" ); break;\r
5758         }\r
5759         if( mod == 1 ) {\r
5760                 disp8 = FETCHD();\r
5761                 s += sprintf( s, "%s", shexstring((INT32)disp8, 0, TRUE) );\r
5762         } else if( mod == 2 ) {\r
5763                 disp16 = FETCHD16();\r
5764                 s += sprintf( s, "%s", shexstring((INT32)disp16, 0, TRUE) );\r
5765         }\r
5766         s += sprintf( s, "]" );\r
5767 }\r
5768 \r
5769 static char* handle_param(char* s, UINT32 param)\r
5770 {\r
5771         UINT8 i8;\r
5772         UINT16 i16;\r
5773         UINT16 ptr;\r
5774         UINT32 addr;\r
5775         INT8 d8;\r
5776         INT16 d16;\r
5777 \r
5778         switch(param)\r
5779         {\r
5780                 case PARAM_REG8:\r
5781                         s += sprintf( s, "%s", nec_reg8[MODRM_REG1] );\r
5782                         break;\r
5783 \r
5784                 case PARAM_REG16:\r
5785                         s += sprintf( s, "%s", nec_reg[MODRM_REG1] );\r
5786                         break;\r
5787 \r
5788                 case PARAM_REG2_8:\r
5789                         s += sprintf( s, "%s", nec_reg8[MODRM_REG2] );\r
5790                         break;\r
5791 \r
5792                 case PARAM_REG2_16:\r
5793                         s += sprintf( s, "%s", nec_reg[MODRM_REG2] );\r
5794                         break;\r
5795 \r
5796                 case PARAM_RM8:\r
5797                 case PARAM_RMPTR8:\r
5798                         if( modrm >= 0xc0 ) {\r
5799                                 s += sprintf( s, "%s", nec_reg8[MODRM_REG2] );\r
5800                         } else {\r
5801                                 if (param == PARAM_RMPTR8)\r
5802                                         s += sprintf( s, "byte ptr " );\r
5803                                 s += sprintf( s, "%s", modrm_string );\r
5804                         }\r
5805                         break;\r
5806 \r
5807                 case PARAM_RM16:\r
5808                 case PARAM_RMPTR16:\r
5809                         if( modrm >= 0xc0 ) {\r
5810                                 s += sprintf( s, "%s", nec_reg[MODRM_REG2] );\r
5811                         } else {\r
5812                                 if (param == PARAM_RMPTR16)\r
5813                                         s += sprintf( s, "word ptr " );\r
5814                                 s += sprintf( s, "%s", modrm_string );\r
5815                         }\r
5816                         break;\r
5817 \r
5818                 case PARAM_I3:\r
5819                         i8 = FETCHD();\r
5820                         s += sprintf( s, "%d", i8 & 0x07 );\r
5821                         break;\r
5822 \r
5823                 case PARAM_I4:\r
5824                         i8 = FETCHD();\r
5825                         s += sprintf( s, "%d", i8 & 0x0f );\r
5826                         break;\r
5827 \r
5828                 case PARAM_I8:\r
5829                         i8 = FETCHD();\r
5830                         s += sprintf( s, "%s", shexstring((INT8)i8, 0, FALSE) );\r
5831                         break;\r
5832 \r
5833                 case PARAM_I16:\r
5834                         i16 = FETCHD16();\r
5835                         s += sprintf( s, "%s", shexstring((INT16)i16, 0, FALSE) );\r
5836                         break;\r
5837 \r
5838                 case PARAM_UI8:\r
5839                         i8 = FETCHD();\r
5840                         s += sprintf( s, "%s", shexstring((UINT8)i8, 0, FALSE) );\r
5841                         break;\r
5842 \r
5843                 case PARAM_IMM:\r
5844                         i16 = FETCHD16();\r
5845                         s += sprintf( s, "%s", hexstring(i16, 0) );\r
5846                         break;\r
5847 \r
5848                 case PARAM_ADDR:\r
5849                         addr = FETCHD16();\r
5850                         ptr = FETCHD16();\r
5851                         s += sprintf( s, "%s:", hexstring(ptr, 4) );\r
5852                         s += sprintf( s, "%s", hexstring(addr, 0) );\r
5853                         break;\r
5854 \r
5855                 case PARAM_REL16:\r
5856                         /* make sure to keep the relative offset within the segment */\r
5857                         d16 = FETCHD16();\r
5858                         s += sprintf( s, "%s", hexstring((pc & 0xFFFF0000) | ((pc + d16) & 0x0000FFFF), 0) );\r
5859                         break;\r
5860 \r
5861                 case PARAM_REL8:\r
5862                         d8 = FETCHD();\r
5863                         s += sprintf( s, "%s", hexstring(pc + d8, 0) );\r
5864                         break;\r
5865 \r
5866                 case PARAM_MEM_OFFS:\r
5867                         switch(segment)\r
5868                         {\r
5869                                 case SEG_PS: s += sprintf( s, "ps:" ); break;\r
5870                                 case SEG_DS0: s += sprintf( s, "ds0:" ); break;\r
5871                                 case SEG_DS1: s += sprintf( s, "ds1:" ); break;\r
5872                                 case SEG_SS: s += sprintf( s, "ss:" ); break;\r
5873                         }\r
5874 \r
5875                         i16 = FETCHD16();\r
5876                         s += sprintf( s, "[%s]", hexstring(i16, 0) );\r
5877                         break;\r
5878 \r
5879                 case PARAM_SREG:\r
5880                         s += sprintf( s, "%s", nec_sreg[MODRM_REG1] );\r
5881                         break;\r
5882 \r
5883                 case PARAM_SFREG:\r
5884                         i8 = FETCHD();\r
5885                         s += sprintf( s, "%s", nec_sfreg[i8] );\r
5886                         break;\r
5887 \r
5888                 case PARAM_1:\r
5889                         s += sprintf( s, "1" );\r
5890                         break;\r
5891 \r
5892                 case PARAM_AL: s += sprintf( s, "al" ); break;\r
5893                 case PARAM_CL: s += sprintf( s, "cl" ); break;\r
5894                 case PARAM_DL: s += sprintf( s, "dl" ); break;\r
5895                 case PARAM_BL: s += sprintf( s, "bl" ); break;\r
5896                 case PARAM_AH: s += sprintf( s, "ah" ); break;\r
5897                 case PARAM_CH: s += sprintf( s, "ch" ); break;\r
5898                 case PARAM_DH: s += sprintf( s, "dh" ); break;\r
5899                 case PARAM_BH: s += sprintf( s, "bh" ); break;\r
5900 \r
5901                 case PARAM_AW: s += sprintf( s, "aw" ); break;\r
5902                 case PARAM_CW: s += sprintf( s, "cw" ); break;\r
5903                 case PARAM_DW: s += sprintf( s, "dw" ); break;\r
5904                 case PARAM_BW: s += sprintf( s, "bw" ); break;\r
5905                 case PARAM_SP: s += sprintf( s, "sp" ); break;\r
5906                 case PARAM_BP: s += sprintf( s, "bp" ); break;\r
5907                 case PARAM_IX: s += sprintf( s, "ix" ); break;\r
5908                 case PARAM_IY: s += sprintf( s, "iy" ); break;\r
5909         }\r
5910         return s;\r
5911 }\r
5912 \r
5913 static void handle_fpu(char *s, UINT8 op1, UINT8 op2)\r
5914 {\r
5915         switch (op1 & 0x7)\r
5916         {\r
5917                 case 0:         // Group D8\r
5918                 {\r
5919                         if (op2 < 0xc0)\r
5920                         {\r
5921                                 pc--;           // adjust fetch pointer, so modrm byte read again\r
5922                                 opcode_ptr--;\r
5923                                 handle_modrm( modrm_string );\r
5924                                 switch ((op2 >> 3) & 0x7)\r
5925                                 {\r
5926                                         case 0: sprintf(s, "fadd    dword ptr %s", modrm_string); break;\r
5927                                         case 1: sprintf(s, "fmul    dword ptr %s", modrm_string); break;\r
5928                                         case 2: sprintf(s, "fcom    dword ptr %s", modrm_string); break;\r
5929                                         case 3: sprintf(s, "fcomp   dword ptr %s", modrm_string); break;\r
5930                                         case 4: sprintf(s, "fsub    dword ptr %s", modrm_string); break;\r
5931                                         case 5: sprintf(s, "fsubr   dword ptr %s", modrm_string); break;\r
5932                                         case 6: sprintf(s, "fdiv    dword ptr %s", modrm_string); break;\r
5933                                         case 7: sprintf(s, "fdivr   dword ptr %s", modrm_string); break;\r
5934                                 }\r
5935                         } else {\r
5936                                 switch ((op2 >> 3) & 0x7)\r
5937                                 {\r
5938                                         case 0: sprintf(s, "fadd    st(0),st(%d)", op2 & 0x7); break;\r
5939                                         case 1: sprintf(s, "fcom    st(0),st(%d)", op2 & 0x7); break;\r
5940                                         case 2: sprintf(s, "fsub    st(0),st(%d)", op2 & 0x7); break;\r
5941                                         case 3: sprintf(s, "fdiv    st(0),st(%d)", op2 & 0x7); break;\r
5942                                         case 4: sprintf(s, "fmul    st(0),st(%d)", op2 & 0x7); break;\r
5943                                         case 5: sprintf(s, "fcomp   st(0),st(%d)", op2 & 0x7); break;\r
5944                                         case 6: sprintf(s, "fsubr   st(0),st(%d)", op2 & 0x7); break;\r
5945                                         case 7: sprintf(s, "fdivr   st(0),st(%d)", op2 & 0x7); break;\r
5946                                 }\r
5947                         }\r
5948                         break;\r
5949                 }\r
5950 \r
5951                 case 1:         // Group D9\r
5952                 {\r
5953                         if (op2 < 0xc0)\r
5954                         {\r
5955                                 pc--;           // adjust fetch pointer, so modrm byte read again\r
5956                                 opcode_ptr--;\r
5957                                 handle_modrm( modrm_string );\r
5958                                 switch ((op2 >> 3) & 0x7)\r
5959                                 {\r
5960                                         case 0: sprintf(s, "fld     dword ptr %s", modrm_string); break;\r
5961                                         case 1: sprintf(s, "??? (FPU)"); break;\r
5962                                         case 2: sprintf(s, "fst     dword ptr %s", modrm_string); break;\r
5963                                         case 3: sprintf(s, "fstp    dword ptr %s", modrm_string); break;\r
5964                                         case 4: sprintf(s, "fldenv  word ptr %s", modrm_string); break;\r
5965                                         case 5: sprintf(s, "fldcw   word ptr %s", modrm_string); break;\r
5966                                         case 6: sprintf(s, "fstenv  word ptr %s", modrm_string); break;\r
5967                                         case 7: sprintf(s, "fstcw   word ptr %s", modrm_string); break;\r
5968                                 }\r
5969                         } else {\r
5970                                 switch (op2 & 0x3f)\r
5971                                 {\r
5972                                         case 0x00: case 0x01: case 0x02: case 0x03: case 0x04: case 0x05: case 0x06: case 0x07:\r
5973                                                 sprintf(s, "fld     st(0),st(%d)", op2 & 0x7); break;\r
5974 \r
5975                                         case 0x08: case 0x09: case 0x0a: case 0x0b: case 0x0c: case 0x0d: case 0x0e: case 0x0f:\r
5976                                                 sprintf(s, "fxch    st(0),st(%d)", op2 & 0x7); break;\r
5977 \r
5978                                         case 0x10: sprintf(s, "fnop"); break;\r
5979                                         case 0x20: sprintf(s, "fchs"); break;\r
5980                                         case 0x21: sprintf(s, "fabs"); break;\r
5981                                         case 0x24: sprintf(s, "ftst"); break;\r
5982                                         case 0x25: sprintf(s, "fxam"); break;\r
5983                                         case 0x28: sprintf(s, "fld1"); break;\r
5984                                         case 0x29: sprintf(s, "fldl2t"); break;\r
5985                                         case 0x2a: sprintf(s, "fldl2e"); break;\r
5986                                         case 0x2b: sprintf(s, "fldpi"); break;\r
5987                                         case 0x2c: sprintf(s, "fldlg2"); break;\r
5988                                         case 0x2d: sprintf(s, "fldln2"); break;\r
5989                                         case 0x2e: sprintf(s, "fldz"); break;\r
5990                                         case 0x30: sprintf(s, "f2xm1"); break;\r
5991                                         case 0x31: sprintf(s, "fyl2x"); break;\r
5992                                         case 0x32: sprintf(s, "fptan"); break;\r
5993                                         case 0x33: sprintf(s, "fpatan"); break;\r
5994                                         case 0x34: sprintf(s, "fxtract"); break;\r
5995                                         case 0x35: sprintf(s, "fprem1"); break;\r
5996                                         case 0x36: sprintf(s, "fdecstp"); break;\r
5997                                         case 0x37: sprintf(s, "fincstp"); break;\r
5998                                         case 0x38: sprintf(s, "fprem"); break;\r
5999                                         case 0x39: sprintf(s, "fyl2xp1"); break;\r
6000                                         case 0x3a: sprintf(s, "fsqrt"); break;\r
6001                                         case 0x3b: sprintf(s, "fsincos"); break;\r
6002                                         case 0x3c: sprintf(s, "frndint"); break;\r
6003                                         case 0x3d: sprintf(s, "fscale"); break;\r
6004                                         case 0x3e: sprintf(s, "fsin"); break;\r
6005                                         case 0x3f: sprintf(s, "fcos"); break;\r
6006 \r
6007                                         default: sprintf(s, "??? (FPU)"); break;\r
6008                                 }\r
6009                         }\r
6010                         break;\r
6011                 }\r
6012 \r
6013                 case 2:         // Group DA\r
6014                 {\r
6015                         if (op2 < 0xc0)\r
6016                         {\r
6017                                 pc--;           // adjust fetch pointer, so modrm byte read again\r
6018                                 opcode_ptr--;\r
6019                                 handle_modrm( modrm_string );\r
6020                                 switch ((op2 >> 3) & 0x7)\r
6021                                 {\r
6022                                         case 0: sprintf(s, "fiadd   dword ptr %s", modrm_string); break;\r
6023                                         case 1: sprintf(s, "fimul   dword ptr %s", modrm_string); break;\r
6024                                         case 2: sprintf(s, "ficom   dword ptr %s", modrm_string); break;\r
6025                                         case 3: sprintf(s, "ficomp  dword ptr %s", modrm_string); break;\r
6026                                         case 4: sprintf(s, "fisub   dword ptr %s", modrm_string); break;\r
6027                                         case 5: sprintf(s, "fisubr  dword ptr %s", modrm_string); break;\r
6028                                         case 6: sprintf(s, "fidiv   dword ptr %s", modrm_string); break;\r
6029                                         case 7: sprintf(s, "fidivr  dword ptr %s", modrm_string); break;\r
6030                                 }\r
6031                         } else {\r
6032                                 switch (op2 & 0x3f)\r
6033                                 {\r
6034                                         case 0x00: case 0x01: case 0x02: case 0x03: case 0x04: case 0x05: case 0x06: case 0x07:\r
6035                                                 sprintf(s, "fcmovb  st(0),st(%d)", op2 & 0x7); break;\r
6036 \r
6037                                         case 0x08: case 0x09: case 0x0a: case 0x0b: case 0x0c: case 0x0d: case 0x0e: case 0x0f:\r
6038                                                 sprintf(s, "fcmove  st(0),st(%d)", op2 & 0x7); break;\r
6039 \r
6040                                         case 0x10: case 0x11: case 0x12: case 0x13: case 0x14: case 0x15: case 0x16: case 0x17:\r
6041                                                 sprintf(s, "fcmovbe st(0),st(%d)", op2 & 0x7); break;\r
6042 \r
6043                                         case 0x18: case 0x19: case 0x1a: case 0x1b: case 0x1c: case 0x1d: case 0x1e: case 0x1f:\r
6044                                                 sprintf(s, "fcmovu  st(0),st(%d)", op2 & 0x7); break;\r
6045 \r
6046                                         default: sprintf(s, "??? (FPU)"); break;\r
6047 \r
6048                                 }\r
6049                         }\r
6050                         break;\r
6051                 }\r
6052 \r
6053                 case 3:         // Group DB\r
6054                 {\r
6055                         if (op2 < 0xc0)\r
6056                         {\r
6057                                 pc--;           // adjust fetch pointer, so modrm byte read again\r
6058                                 opcode_ptr--;\r
6059                                 handle_modrm( modrm_string );\r
6060                                 switch ((op2 >> 3) & 0x7)\r
6061                                 {\r
6062                                         case 0: sprintf(s, "fild    dword ptr %s", modrm_string); break;\r
6063                                         case 1: sprintf(s, "??? (FPU)"); break;\r
6064                                         case 2: sprintf(s, "fist    dword ptr %s", modrm_string); break;\r
6065                                         case 3: sprintf(s, "fistp   dword ptr %s", modrm_string); break;\r
6066                                         case 4: sprintf(s, "??? (FPU)"); break;\r
6067                                         case 5: sprintf(s, "fld     tword ptr %s", modrm_string); break;\r
6068                                         case 6: sprintf(s, "??? (FPU)"); break;\r
6069                                         case 7: sprintf(s, "fstp    tword ptr %s", modrm_string); break;\r
6070                                 }\r
6071                         } else {\r
6072                                 switch (op2 & 0x3f)\r
6073                                 {\r
6074                                         case 0x00: case 0x01: case 0x02: case 0x03: case 0x04: case 0x05: case 0x06: case 0x07:\r
6075                                                 sprintf(s, "fcmovnb st(0),st(%d)", op2 & 0x7); break;\r
6076 \r
6077                                         case 0x08: case 0x09: case 0x0a: case 0x0b: case 0x0c: case 0x0d: case 0x0e: case 0x0f:\r
6078                                                 sprintf(s, "fcmovne st(0),st(%d)", op2 & 0x7); break;\r
6079 \r
6080                                         case 0x10: case 0x11: case 0x12: case 0x13: case 0x14: case 0x15: case 0x16: case 0x17:\r
6081                                                 sprintf(s, "fcmovnbe st(0),st(%d)", op2 & 0x7); break;\r
6082 \r
6083                                         case 0x18: case 0x19: case 0x1a: case 0x1b: case 0x1c: case 0x1d: case 0x1e: case 0x1f:\r
6084                                                 sprintf(s, "fcmovnu st(0),st(%d)", op2 & 0x7); break;\r
6085 \r
6086                                         case 0x22: sprintf(s, "fclex"); break;\r
6087                                         case 0x23: sprintf(s, "finit"); break;\r
6088 \r
6089                                         case 0x28: case 0x29: case 0x2a: case 0x2b: case 0x2c: case 0x2d: case 0x2e: case 0x2f:\r
6090                                                 sprintf(s, "fucomi  st(0),st(%d)", op2 & 0x7); break;\r
6091 \r
6092                                         case 0x30: case 0x31: case 0x32: case 0x33: case 0x34: case 0x35: case 0x36: case 0x37:\r
6093                                                 sprintf(s, "fcomi   st(0),st(%d)", op2 & 0x7); break;\r
6094 \r
6095                                         default: sprintf(s, "??? (FPU)"); break;\r
6096                                 }\r
6097                         }\r
6098                         break;\r
6099                 }\r
6100 \r
6101                 case 4:         // Group DC\r
6102                 {\r
6103                         if (op2 < 0xc0)\r
6104                         {\r
6105                                 pc--;           // adjust fetch pointer, so modrm byte read again\r
6106                                 opcode_ptr--;\r
6107                                 handle_modrm( modrm_string );\r
6108                                 switch ((op2 >> 3) & 0x7)\r
6109                                 {\r
6110                                         case 0: sprintf(s, "fadd    qword ptr %s", modrm_string); break;\r
6111                                         case 1: sprintf(s, "fmul    qword ptr %s", modrm_string); break;\r
6112                                         case 2: sprintf(s, "fcom    qword ptr %s", modrm_string); break;\r
6113                                         case 3: sprintf(s, "fcomp   qword ptr %s", modrm_string); break;\r
6114                                         case 4: sprintf(s, "fsub    qword ptr %s", modrm_string); break;\r
6115                                         case 5: sprintf(s, "fsubr   qword ptr %s", modrm_string); break;\r
6116                                         case 6: sprintf(s, "fdiv    qword ptr %s", modrm_string); break;\r
6117                                         case 7: sprintf(s, "fdivr   qword ptr %s", modrm_string); break;\r
6118                                 }\r
6119                         } else {\r
6120                                 switch (op2 & 0x3f)\r
6121                                 {\r
6122                                         case 0x00: case 0x01: case 0x02: case 0x03: case 0x04: case 0x05: case 0x06: case 0x07:\r
6123                                                 sprintf(s, "fadd    st(%d),st(0)", op2 & 0x7); break;\r
6124 \r
6125                                         case 0x08: case 0x09: case 0x0a: case 0x0b: case 0x0c: case 0x0d: case 0x0e: case 0x0f:\r
6126                                                 sprintf(s, "fmul    st(%d),st(0)", op2 & 0x7); break;\r
6127 \r
6128                                         case 0x20: case 0x21: case 0x22: case 0x23: case 0x24: case 0x25: case 0x26: case 0x27:\r
6129                                                 sprintf(s, "fsubr   st(%d),st(0)", op2 & 0x7); break;\r
6130 \r
6131                                         case 0x28: case 0x29: case 0x2a: case 0x2b: case 0x2c: case 0x2d: case 0x2e: case 0x2f:\r
6132                                                 sprintf(s, "fsub    st(%d),st(0)", op2 & 0x7); break;\r
6133 \r
6134                                         case 0x30: case 0x31: case 0x32: case 0x33: case 0x34: case 0x35: case 0x36: case 0x37:\r
6135                                                 sprintf(s, "fdivr   st(%d),st(0)", op2 & 0x7); break;\r
6136 \r
6137                                         case 0x38: case 0x39: case 0x3a: case 0x3b: case 0x3c: case 0x3d: case 0x3e: case 0x3f:\r
6138                                                 sprintf(s, "fdiv    st(%d),st(0)", op2 & 0x7); break;\r
6139 \r
6140                                         default: sprintf(s, "??? (FPU)"); break;\r
6141                                 }\r
6142                         }\r
6143                         break;\r
6144                 }\r
6145 \r
6146                 case 5:         // Group DD\r
6147                 {\r
6148                         if (op2 < 0xc0)\r
6149                         {\r
6150                                 pc--;           // adjust fetch pointer, so modrm byte read again\r
6151                                 opcode_ptr--;\r
6152                                 handle_modrm( modrm_string );\r
6153                                 switch ((op2 >> 3) & 0x7)\r
6154                                 {\r
6155                                         case 0: sprintf(s, "fld     qword ptr %s", modrm_string); break;\r
6156                                         case 1: sprintf(s, "??? (FPU)"); break;\r
6157                                         case 2: sprintf(s, "fst     qword ptr %s", modrm_string); break;\r
6158                                         case 3: sprintf(s, "fstp    qword ptr %s", modrm_string); break;\r
6159                                         case 4: sprintf(s, "frstor  %s", modrm_string); break;\r
6160                                         case 5: sprintf(s, "??? (FPU)"); break;\r
6161                                         case 6: sprintf(s, "fsave   %s", modrm_string); break;\r
6162                                         case 7: sprintf(s, "fstsw   word ptr %s", modrm_string); break;\r
6163                                 }\r
6164                         } else {\r
6165                                 switch (op2 & 0x3f)\r
6166                                 {\r
6167                                         case 0x00: case 0x01: case 0x02: case 0x03: case 0x04: case 0x05: case 0x06: case 0x07:\r
6168                                                 sprintf(s, "ffree   st(%d)", op2 & 0x7); break;\r
6169 \r
6170                                         case 0x10: case 0x11: case 0x12: case 0x13: case 0x14: case 0x15: case 0x16: case 0x17:\r
6171                                                 sprintf(s, "fst     st(%d)", op2 & 0x7); break;\r
6172 \r
6173                                         case 0x18: case 0x19: case 0x1a: case 0x1b: case 0x1c: case 0x1d: case 0x1e: case 0x1f:\r
6174                                                 sprintf(s, "fstp    st(%d)", op2 & 0x7); break;\r
6175 \r
6176                                         case 0x20: case 0x21: case 0x22: case 0x23: case 0x24: case 0x25: case 0x26: case 0x27:\r
6177                                                 sprintf(s, "fucom   st(%d), st(0)", op2 & 0x7); break;\r
6178 \r
6179                                         case 0x28: case 0x29: case 0x2a: case 0x2b: case 0x2c: case 0x2d: case 0x2e: case 0x2f:\r
6180                                                 sprintf(s, "fucomp  st(%d)", op2 & 0x7); break;\r
6181 \r
6182                                         default: sprintf(s, "??? (FPU)"); break;\r
6183                                 }\r
6184                         }\r
6185                         break;\r
6186                 }\r
6187 \r
6188                 case 6:         // Group DE\r
6189                 {\r
6190                         if (op2 < 0xc0)\r
6191                         {\r
6192                                 pc--;           // adjust fetch pointer, so modrm byte read again\r
6193                                 opcode_ptr--;\r
6194                                 handle_modrm( modrm_string );\r
6195                                 switch ((op2 >> 3) & 0x7)\r
6196                                 {\r
6197                                         case 0: sprintf(s, "fiadd   word ptr %s", modrm_string); break;\r
6198                                         case 1: sprintf(s, "fimul   word ptr %s", modrm_string); break;\r
6199                                         case 2: sprintf(s, "ficom   word ptr %s", modrm_string); break;\r
6200                                         case 3: sprintf(s, "ficomp  word ptr %s", modrm_string); break;\r
6201                                         case 4: sprintf(s, "fisub   word ptr %s", modrm_string); break;\r
6202                                         case 5: sprintf(s, "fisubr  word ptr %s", modrm_string); break;\r
6203                                         case 6: sprintf(s, "fidiv   word ptr %s", modrm_string); break;\r
6204                                         case 7: sprintf(s, "fidivr  word ptr %s", modrm_string); break;\r
6205                                 }\r
6206                         } else {\r
6207                                 switch (op2 & 0x3f)\r
6208                                 {\r
6209                                         case 0x00: case 0x01: case 0x02: case 0x03: case 0x04: case 0x05: case 0x06: case 0x07:\r
6210                                                 sprintf(s, "faddp   st(%d)", op2 & 0x7); break;\r
6211 \r
6212                                         case 0x08: case 0x09: case 0x0a: case 0x0b: case 0x0c: case 0x0d: case 0x0e: case 0x0f:\r
6213                                                 sprintf(s, "fmulp   st(%d)", op2 & 0x7); break;\r
6214 \r
6215                                         case 0x19: sprintf(s, "fcompp"); break;\r
6216 \r
6217                                         case 0x20: case 0x21: case 0x22: case 0x23: case 0x24: case 0x25: case 0x26: case 0x27:\r
6218                                                 sprintf(s, "fsubrp  st(%d)", op2 & 0x7); break;\r
6219 \r
6220                                         case 0x28: case 0x29: case 0x2a: case 0x2b: case 0x2c: case 0x2d: case 0x2e: case 0x2f:\r
6221                                                 sprintf(s, "fsubp   st(%d)", op2 & 0x7); break;\r
6222 \r
6223                                         case 0x30: case 0x31: case 0x32: case 0x33: case 0x34: case 0x35: case 0x36: case 0x37:\r
6224                                                 sprintf(s, "fdivrp  st(%d), st(0)", op2 & 0x7); break;\r
6225 \r
6226                                         case 0x38: case 0x39: case 0x3a: case 0x3b: case 0x3c: case 0x3d: case 0x3e: case 0x3f:\r
6227                                                 sprintf(s, "fdivp   st(%d)", op2 & 0x7); break;\r
6228 \r
6229                                         default: sprintf(s, "??? (FPU)"); break;\r
6230                                 }\r
6231                         }\r
6232                         break;\r
6233                 }\r
6234 \r
6235                 case 7:         // Group DF\r
6236                 {\r
6237                         if (op2 < 0xc0)\r
6238                         {\r
6239                                 pc--;           // adjust fetch pointer, so modrm byte read again\r
6240                                 opcode_ptr--;\r
6241                                 handle_modrm( modrm_string );\r
6242                                 switch ((op2 >> 3) & 0x7)\r
6243                                 {\r
6244                                         case 0: sprintf(s, "fild    word ptr %s", modrm_string); break;\r
6245                                         case 1: sprintf(s, "??? (FPU)"); break;\r
6246                                         case 2: sprintf(s, "fist    word ptr %s", modrm_string); break;\r
6247                                         case 3: sprintf(s, "fistp   word ptr %s", modrm_string); break;\r
6248                                         case 4: sprintf(s, "fbld    %s", modrm_string); break;\r
6249                                         case 5: sprintf(s, "fild    qword ptr %s", modrm_string); break;\r
6250                                         case 6: sprintf(s, "fbstp   %s", modrm_string); break;\r
6251                                         case 7: sprintf(s, "fistp   qword ptr %s", modrm_string); break;\r
6252                                 }\r
6253                         } else {\r
6254                                 switch (op2 & 0x3f)\r
6255                                 {\r
6256                                         case 0x20: sprintf(s, "fstsw   aw"); break;\r
6257 \r
6258                                         case 0x28: case 0x29: case 0x2a: case 0x2b: case 0x2c: case 0x2d: case 0x2e: case 0x2f:\r
6259                                                 sprintf(s, "fucomip st(%d)", op2 & 0x7); break;\r
6260 \r
6261                                         case 0x30: case 0x31: case 0x32: case 0x33: case 0x34: case 0x35: case 0x36: case 0x37:\r
6262                                                 sprintf(s, "fcomip  st(%d),st(0)", op2 & 0x7); break;\r
6263 \r
6264                                         default: sprintf(s, "??? (FPU)"); break;\r
6265                                 }\r
6266                         }\r
6267                         break;\r
6268                 }\r
6269         }\r
6270 }\r
6271 \r
6272 static void decode_opcode(char *s, const I386_OPCODE *op, UINT8 op1 )\r
6273 {\r
6274         int i;\r
6275         UINT8 op2;\r
6276 \r
6277         switch( op->flags )\r
6278         {\r
6279                 case TWO_BYTE:\r
6280                         op2 = FETCHD();\r
6281                         decode_opcode( s, &necv_opcode_table2[op2], op1 );\r
6282                         return;\r
6283 \r
6284                 case SEG_PS:\r
6285                 case SEG_DS0:\r
6286                 case SEG_DS1:\r
6287                 case SEG_SS:\r
6288                         segment = op->flags;\r
6289                         op2 = FETCHD();\r
6290                         decode_opcode( s, &necv_opcode_table1[op2], op1 );\r
6291                         return;\r
6292 \r
6293                 case PREFIX:\r
6294                         s += sprintf( s, "%-8s", op->mnemonic );\r
6295                         op2 = FETCHD();\r
6296                         decode_opcode( s, &necv_opcode_table1[op2], op1 );\r
6297                         return;\r
6298 \r
6299                 case GROUP:\r
6300                         handle_modrm( modrm_string );\r
6301                         for( i=0; i < ARRAY_LENGTH(group_op_table); i++ ) {\r
6302                                 if( strcmp(op->mnemonic, group_op_table[i].mnemonic) == 0 )\r
6303                                 {\r
6304                                         decode_opcode( s, &group_op_table[i].opcode[MODRM_REG1], op1 );\r
6305                                         return;\r
6306                                 }\r
6307                         }\r
6308                         goto handle_unknown;\r
6309 \r
6310                 case FPU:\r
6311                         op2 = FETCHD();\r
6312                         handle_fpu( s, op1, op2);\r
6313                         return;\r
6314 \r
6315                 case MODRM:\r
6316                         handle_modrm( modrm_string );\r
6317                         break;\r
6318         }\r
6319 \r
6320         s += sprintf( s, "%-8s", op->mnemonic );\r
6321         dasm_flags = op->dasm_flags;\r
6322 \r
6323         if( op->param1 != 0 ) {\r
6324                 s = handle_param( s, op->param1 );\r
6325         }\r
6326 \r
6327         if( op->param2 != 0 ) {\r
6328                 s += sprintf( s, "," );\r
6329                 s = handle_param( s, op->param2 );\r
6330         }\r
6331 \r
6332         if( op->param3 != 0 ) {\r
6333                 s += sprintf( s, "," );\r
6334                 s = handle_param( s, op->param3 );\r
6335         }\r
6336         return;\r
6337 \r
6338 handle_unknown:\r
6339         sprintf(s, "???");\r
6340 }\r
6341 \r
6342 int necv_dasm_one(char *buffer, UINT32 eip, const UINT8 *oprom)\r
6343 {\r
6344         UINT8 op;\r
6345 \r
6346         opcode_ptr = opcode_ptr_base = oprom;\r
6347         pc = eip;\r
6348         dasm_flags = 0;\r
6349         segment = 0;\r
6350 \r
6351         op = FETCHD();\r
6352 \r
6353         decode_opcode( buffer, &necv_opcode_table1[op], op );\r
6354         return (pc-eip) | dasm_flags | DASMFLAG_SUPPORTED;\r
6355 }\r
6356 \r
6357 #define STATE_VERSION   1\r
6358 \r
6359 void I86::save_state(FILEIO* state_fio)\r
6360 {\r
6361         state_fio->FputUint32(STATE_VERSION);\r
6362         state_fio->FputInt32(this_device_id);\r
6363         \r
6364         state_fio->Fwrite(&regs, sizeof(regs), 1);\r
6365         state_fio->FputUint32(pc);\r
6366         state_fio->FputUint32(prevpc);\r
6367         state_fio->Fwrite(base, sizeof(base), 1);\r
6368         state_fio->Fwrite(sregs, sizeof(sregs), 1);\r
6369         state_fio->FputUint16(flags);\r
6370         state_fio->FputInt32(AuxVal);\r
6371         state_fio->FputInt32(OverVal);\r
6372         state_fio->FputInt32(SignVal);\r
6373         state_fio->FputInt32(ZeroVal);\r
6374         state_fio->FputInt32(CarryVal);\r
6375         state_fio->FputInt32(DirVal);\r
6376         state_fio->FputUint8(ParityVal);\r
6377         state_fio->FputUint8(TF);\r
6378         state_fio->FputUint8(IF);\r
6379         state_fio->FputUint8(MF);\r
6380         state_fio->FputInt32(int_state);\r
6381         state_fio->FputBool(test_state);\r
6382         state_fio->FputBool(busreq);\r
6383         state_fio->FputBool(halted);\r
6384         state_fio->FputInt32(icount);\r
6385         state_fio->FputInt32(extra_icount);\r
6386         state_fio->FputBool(seg_prefix);\r
6387         state_fio->FputUint8(prefix_seg);\r
6388         state_fio->FputUint32(ea);\r
6389         state_fio->FputUint16(eo);\r
6390         state_fio->FputUint8(ea_seg);\r
6391 }\r
6392 \r
6393 bool I86::load_state(FILEIO* state_fio)\r
6394 {\r
6395         if(state_fio->FgetUint32() != STATE_VERSION) {\r
6396                 return false;\r
6397         }\r
6398         if(state_fio->FgetInt32() != this_device_id) {\r
6399                 return false;\r
6400         }\r
6401         state_fio->Fread(&regs, sizeof(regs), 1);\r
6402         pc = state_fio->FgetUint32();\r
6403         prevpc = state_fio->FgetUint32();\r
6404         state_fio->Fread(base, sizeof(base), 1);\r
6405         state_fio->Fread(sregs, sizeof(sregs), 1);\r
6406         flags = state_fio->FgetUint16();\r
6407         AuxVal = state_fio->FgetInt32();\r
6408         OverVal = state_fio->FgetInt32();\r
6409         SignVal = state_fio->FgetInt32();\r
6410         ZeroVal = state_fio->FgetInt32();\r
6411         CarryVal = state_fio->FgetInt32();\r
6412         DirVal = state_fio->FgetInt32();\r
6413         ParityVal = state_fio->FgetUint8();\r
6414         TF = state_fio->FgetUint8();\r
6415         IF = state_fio->FgetUint8();\r
6416         MF = state_fio->FgetUint8();\r
6417         int_state = state_fio->FgetInt32();\r
6418         test_state = state_fio->FgetBool();\r
6419         busreq = state_fio->FgetBool();\r
6420         halted = state_fio->FgetBool();\r
6421         icount = state_fio->FgetInt32();\r
6422         extra_icount = state_fio->FgetInt32();\r
6423         seg_prefix = state_fio->FgetBool();\r
6424         prefix_seg = state_fio->FgetUint8();\r
6425         ea = state_fio->FgetUint32();\r
6426         eo = state_fio->FgetUint16();\r
6427         ea_seg = state_fio->FgetUint8();\r
6428         return true;\r
6429 }\r
6430 \r