OSDN Git Service

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