OSDN Git Service

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