OSDN Git Service

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