2 Skelton for retropc emulator
\r
5 Author : Takeda.Toshiya
\r
11 // disable warnings C4146 for microsoft visual c++ 2005
\r
12 #if defined(_MSC_VER) && (_MSC_VER >= 1400)
\r
13 #pragma warning( disable : 4146 )
\r
18 #include "debugger.h"
\r
20 #include "../fileio.h"
\r
22 #define DIVIDE_FAULT 0
\r
23 #define NMI_INT_VECTOR 2
\r
24 #define OVERFLOW_TRAP 4
\r
25 #define BOUNDS_CHECK_FAULT 5
\r
26 #define ILLEGAL_INSTRUCTION 6
\r
27 #define GENERAL_PROTECTION_FAULT 13
\r
29 #define INT_REQ_BIT 1
\r
30 #define NMI_REQ_BIT 2
\r
32 typedef enum { ES, CS, SS, DS } SREGS;
\r
33 typedef enum { AX, CX, DX, BX, SP, BP, SI, DI } WREGS;
\r
37 AH, AL, CH, CL, DH, DL, BH, BL,
\r
38 SPH, SPL, BPH, BPL, SIH, SIL, DIH, DIL,
\r
40 AL, AH, CL, CH, DL, DH, BL, BH,
\r
41 SPL, SPH, BPL, BPH, SIL, SIH, DIL, DIH,
\r
56 static const uint8 parity_table[256] = {
\r
57 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
\r
58 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
\r
59 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
\r
60 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
\r
61 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
\r
62 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
\r
63 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
\r
64 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
\r
65 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
\r
66 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
\r
67 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
\r
68 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
\r
69 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
\r
70 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
\r
71 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
\r
72 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1
\r
75 /************************************************************************/
\r
77 struct i80x86_timing {
\r
78 uint8 exception, iret; /* exception, IRET */
\r
79 uint8 int3, int_imm, into_nt, into_t; /* INTs */
\r
80 uint8 override; /* segment overrides */
\r
81 uint8 flag_ops, lahf, sahf; /* flag operations */
\r
82 uint8 aaa, aas, aam, aad; /* arithmetic adjusts */
\r
83 uint8 daa, das; /* decimal adjusts */
\r
84 uint8 cbw, cwd; /* sign extension */
\r
85 uint8 hlt, load_ptr, lea, nop, wait, xlat; /* misc */
\r
87 uint8 jmp_short, jmp_near, jmp_far; /* direct JMPs */
\r
88 uint8 jmp_r16, jmp_m16, jmp_m32; /* indirect JMPs */
\r
89 uint8 call_near, call_far; /* direct CALLs */
\r
90 uint8 call_r16, call_m16, call_m32; /* indirect CALLs */
\r
91 uint8 ret_near, ret_far, ret_near_imm, ret_far_imm; /* returns */
\r
92 uint8 jcc_nt, jcc_t, jcxz_nt, jcxz_t; /* conditional JMPs */
\r
93 uint8 loop_nt, loop_t, loope_nt, loope_t; /* loops */
\r
95 uint8 in_imm8, in_imm16, in_dx8, in_dx16; /* port reads */
\r
96 uint8 out_imm8, out_imm16, out_dx8, out_dx16; /* port writes */
\r
98 uint8 mov_rr8, mov_rm8, mov_mr8; /* move, 8-bit */
\r
99 uint8 mov_ri8, mov_mi8; /* move, 8-bit immediate */
\r
100 uint8 mov_rr16, mov_rm16, mov_mr16; /* move, 16-bit */
\r
101 uint8 mov_ri16, mov_mi16; /* move, 16-bit immediate */
\r
102 uint8 mov_am8, mov_am16, mov_ma8, mov_ma16; /* move, AL/AX memory */
\r
103 uint8 mov_sr, mov_sm, mov_rs, mov_ms; /* move, segment registers */
\r
104 uint8 xchg_rr8, xchg_rm8; /* exchange, 8-bit */
\r
105 uint8 xchg_rr16, xchg_rm16, xchg_ar16; /* exchange, 16-bit */
\r
107 uint8 push_r16, push_m16, push_seg, pushf; /* pushes */
\r
108 uint8 pop_r16, pop_m16, pop_seg, popf; /* pops */
\r
110 uint8 alu_rr8, alu_rm8, alu_mr8; /* ALU ops, 8-bit */
\r
111 uint8 alu_ri8, alu_mi8, alu_mi8_ro; /* ALU ops, 8-bit immediate */
\r
112 uint8 alu_rr16, alu_rm16, alu_mr16; /* ALU ops, 16-bit */
\r
113 uint8 alu_ri16, alu_mi16, alu_mi16_ro; /* ALU ops, 16-bit immediate */
\r
114 uint8 alu_r16i8, alu_m16i8, alu_m16i8_ro; /* ALU ops, 16-bit w/8-bit immediate */
\r
115 uint8 mul_r8, mul_r16, mul_m8, mul_m16; /* MUL */
\r
116 uint8 imul_r8, imul_r16, imul_m8, imul_m16; /* IMUL */
\r
117 uint8 div_r8, div_r16, div_m8, div_m16; /* DIV */
\r
118 uint8 idiv_r8, idiv_r16, idiv_m8, idiv_m16; /* IDIV */
\r
119 uint8 incdec_r8, incdec_r16, incdec_m8, incdec_m16; /* INC/DEC */
\r
120 uint8 negnot_r8, negnot_r16, negnot_m8, negnot_m16; /* NEG/NOT */
\r
122 uint8 rot_reg_1, rot_reg_base, rot_reg_bit; /* reg shift/rotate */
\r
123 uint8 rot_m8_1, rot_m8_base, rot_m8_bit; /* m8 shift/rotate */
\r
124 uint8 rot_m16_1, rot_m16_base, rot_m16_bit; /* m16 shift/rotate */
\r
126 uint8 cmps8, rep_cmps8_base, rep_cmps8_count; /* CMPS 8-bit */
\r
127 uint8 cmps16, rep_cmps16_base, rep_cmps16_count; /* CMPS 16-bit */
\r
128 uint8 scas8, rep_scas8_base, rep_scas8_count; /* SCAS 8-bit */
\r
129 uint8 scas16, rep_scas16_base, rep_scas16_count; /* SCAS 16-bit */
\r
130 uint8 lods8, rep_lods8_base, rep_lods8_count; /* LODS 8-bit */
\r
131 uint8 lods16, rep_lods16_base, rep_lods16_count; /* LODS 16-bit */
\r
132 uint8 stos8, rep_stos8_base, rep_stos8_count; /* STOS 8-bit */
\r
133 uint8 stos16, rep_stos16_base, rep_stos16_count; /* STOS 16-bit */
\r
134 uint8 movs8, rep_movs8_base, rep_movs8_count; /* MOVS 8-bit */
\r
135 uint8 movs16, rep_movs16_base, rep_movs16_count; /* MOVS 16-bit */
\r
137 uint8 ins8, rep_ins8_base, rep_ins8_count; /* (80186) INS 8-bit */
\r
138 uint8 ins16, rep_ins16_base, rep_ins16_count; /* (80186) INS 16-bit */
\r
139 uint8 outs8, rep_outs8_base, rep_outs8_count; /* (80186) OUTS 8-bit */
\r
140 uint8 outs16, rep_outs16_base, rep_outs16_count; /* (80186) OUTS 16-bit */
\r
141 uint8 push_imm, pusha, popa; /* (80186) PUSH immediate, PUSHA/POPA */
\r
142 uint8 imul_rri8, imul_rmi8; /* (80186) IMUL immediate 8-bit */
\r
143 uint8 imul_rri16, imul_rmi16; /* (80186) IMUL immediate 16-bit */
\r
144 uint8 enter0, enter1, enter_base, enter_count, leave; /* (80186) ENTER/LEAVE */
\r
145 uint8 bound; /* (80186) BOUND */
\r
148 #if defined(HAS_I86)
\r
149 /* these come from the 8088 timings in OPCODE.LST, but with the
\r
150 penalty for 16-bit memory accesses removed wherever possible */
\r
151 static const struct i80x86_timing timing = {
\r
152 51, 32, /* exception, IRET */
\r
153 2, 0, 4, 2, /* INTs */
\r
154 2, /* segment overrides */
\r
155 2, 4, 4, /* flag operations */
\r
156 4, 4, 83, 60, /* arithmetic adjusts */
\r
157 4, 4, /* decimal adjusts */
\r
158 2, 5, /* sign extension */
\r
159 2, 24, 2, 2, 3, 11, /* misc */
\r
161 15, 15, 15, /* direct JMPs */
\r
162 11, 18, 24, /* indirect JMPs */
\r
163 19, 28, /* direct CALLs */
\r
164 16, 21, 37, /* indirect CALLs */
\r
165 20, 32, 24, 31, /* returns */
\r
166 4, 16, 6, 18, /* conditional JMPs */
\r
167 5, 17, 6, 18, /* loops */
\r
169 10, 14, 8, 12, /* port reads */
\r
170 10, 14, 8, 12, /* port writes */
\r
172 2, 8, 9, /* move, 8-bit */
\r
173 4, 10, /* move, 8-bit immediate */
\r
174 2, 8, 9, /* move, 16-bit */
\r
175 4, 10, /* move, 16-bit immediate */
\r
176 10, 10, 10, 10, /* move, AL/AX memory */
\r
177 2, 8, 2, 9, /* move, segment registers */
\r
178 4, 17, /* exchange, 8-bit */
\r
179 4, 17, 3, /* exchange, 16-bit */
\r
181 15, 24, 14, 14, /* pushes */
\r
182 12, 25, 12, 12, /* pops */
\r
184 3, 9, 16, /* ALU ops, 8-bit */
\r
185 4, 17, 10, /* ALU ops, 8-bit immediate */
\r
186 3, 9, 16, /* ALU ops, 16-bit */
\r
187 4, 17, 10, /* ALU ops, 16-bit immediate */
\r
188 4, 17, 10, /* ALU ops, 16-bit w/8-bit immediate */
\r
189 70, 118, 76, 128, /* MUL */
\r
190 80, 128, 86, 138, /* IMUL */
\r
191 80, 144, 86, 154, /* DIV */
\r
192 101, 165, 107, 175, /* IDIV */
\r
193 3, 2, 15, 15, /* INC/DEC */
\r
194 3, 3, 16, 16, /* NEG/NOT */
\r
196 2, 8, 4, /* reg shift/rotate */
\r
197 15, 20, 4, /* m8 shift/rotate */
\r
198 15, 20, 4, /* m16 shift/rotate */
\r
200 22, 9, 21, /* CMPS 8-bit */
\r
201 22, 9, 21, /* CMPS 16-bit */
\r
202 15, 9, 14, /* SCAS 8-bit */
\r
203 15, 9, 14, /* SCAS 16-bit */
\r
204 12, 9, 11, /* LODS 8-bit */
\r
205 12, 9, 11, /* LODS 16-bit */
\r
206 11, 9, 10, /* STOS 8-bit */
\r
207 11, 9, 10, /* STOS 16-bit */
\r
208 18, 9, 17, /* MOVS 8-bit */
\r
209 18, 9, 17, /* MOVS 16-bit */
\r
212 /* these come from the Intel 80186 datasheet */
\r
213 static const struct i80x86_timing timing = {
\r
214 45, 28, /* exception, IRET */
\r
215 0, 2, 4, 3, /* INTs */
\r
216 2, /* segment overrides */
\r
217 2, 2, 3, /* flag operations */
\r
218 8, 7, 19, 15, /* arithmetic adjusts */
\r
219 4, 4, /* decimal adjusts */
\r
220 2, 4, /* sign extension */
\r
221 2, 18, 6, 2, 6, 11, /* misc */
\r
223 14, 14, 14, /* direct JMPs */
\r
224 11, 17, 26, /* indirect JMPs */
\r
225 15, 23, /* direct CALLs */
\r
226 13, 19, 38, /* indirect CALLs */
\r
227 16, 22, 18, 25, /* returns */
\r
228 4, 13, 5, 15, /* conditional JMPs */
\r
229 6, 16, 6, 16, /* loops */
\r
231 10, 10, 8, 8, /* port reads */
\r
232 9, 9, 7, 7, /* port writes */
\r
234 2, 9, 12, /* move, 8-bit */
\r
235 3, 12, /* move, 8-bit immediate */
\r
236 2, 9, 12, /* move, 16-bit */
\r
237 4, 13, /* move, 16-bit immediate */
\r
238 8, 8, 9, 9, /* move, AL/AX memory */
\r
239 2, 11, 2, 11, /* move, segment registers */
\r
240 4, 17, /* exchange, 8-bit */
\r
241 4, 17, 3, /* exchange, 16-bit */
\r
243 10, 16, 9, 9, /* pushes */
\r
244 10, 20, 8, 8, /* pops */
\r
246 3, 10, 10, /* ALU ops, 8-bit */
\r
247 4, 16, 10, /* ALU ops, 8-bit immediate */
\r
248 3, 10, 10, /* ALU ops, 16-bit */
\r
249 4, 16, 10, /* ALU ops, 16-bit immediate */
\r
250 4, 16, 10, /* ALU ops, 16-bit w/8-bit immediate */
\r
251 26, 35, 32, 41, /* MUL */
\r
252 25, 34, 31, 40, /* IMUL */
\r
253 29, 38, 35, 44, /* DIV */
\r
254 44, 53, 50, 59, /* IDIV */
\r
255 3, 3, 15, 15, /* INC/DEC */
\r
256 3, 3, 10, 10, /* NEG/NOT */
\r
258 2, 5, 1, /* reg shift/rotate */
\r
259 15, 17, 1, /* m8 shift/rotate */
\r
260 15, 17, 1, /* m16 shift/rotate */
\r
262 22, 5, 22, /* CMPS 8-bit */
\r
263 22, 5, 22, /* CMPS 16-bit */
\r
264 15, 5, 15, /* SCAS 8-bit */
\r
265 15, 5, 15, /* SCAS 16-bit */
\r
266 12, 6, 11, /* LODS 8-bit */
\r
267 12, 6, 11, /* LODS 16-bit */
\r
268 10, 6, 9, /* STOS 8-bit */
\r
269 10, 6, 9, /* STOS 16-bit */
\r
270 14, 8, 8, /* MOVS 8-bit */
\r
271 14, 8, 8, /* MOVS 16-bit */
\r
273 14, 8, 8, /* (80186) INS 8-bit */
\r
274 14, 8, 8, /* (80186) INS 16-bit */
\r
275 14, 8, 8, /* (80186) OUTS 8-bit */
\r
276 14, 8, 8, /* (80186) OUTS 16-bit */
\r
277 14, 68, 83, /* (80186) PUSH immediate, PUSHA/POPA */
\r
278 22, 29, /* (80186) IMUL immediate 8-bit */
\r
279 25, 32, /* (80186) IMUL immediate 16-bit */
\r
280 15, 25, 4, 16, 8, /* (80186) ENTER/LEAVE */
\r
281 33, /* (80186) BOUND */
\r
285 /************************************************************************/
\r
287 #define SetTF(x) (TF = (x))
\r
288 #define SetIF(x) (IF = (x))
\r
289 #define SetDF(x) (DirVal = (x) ? -1 : 1)
\r
290 #define SetMD(x) (MF = (x))
\r
292 #define SetOFW_Add(x, y, z) (OverVal = ((x) ^ (y)) & ((x) ^ (z)) & 0x8000)
\r
293 #define SetOFB_Add(x, y, z) (OverVal = ((x) ^ (y)) & ((x) ^ (z)) & 0x80)
\r
294 #define SetOFW_Sub(x, y, z) (OverVal = ((z) ^ (y)) & ((z) ^ (x)) & 0x8000)
\r
295 #define SetOFB_Sub(x, y, z) (OverVal = ((z) ^ (y)) & ((z) ^ (x)) & 0x80)
\r
297 #define SetCFB(x) (CarryVal = (x) & 0x100)
\r
298 #define SetCFW(x) (CarryVal = (x) & 0x10000)
\r
299 #define SetAF(x, y, z) (AuxVal = ((x) ^ ((y) ^ (z))) & 0x10)
\r
300 #define SetSF(x) (SignVal = (x))
\r
301 #define SetZF(x) (ZeroVal = (x))
\r
302 #define SetPF(x) (ParityVal = (x))
\r
304 #define SetSZPF_Byte(x) (ParityVal = SignVal = ZeroVal = (int8)(x))
\r
305 #define SetSZPF_Word(x) (ParityVal = SignVal = ZeroVal = (int16)(x))
\r
307 #define ADDB(dst, src) { unsigned res = (dst) + (src); SetCFB(res); SetOFB_Add(res, src, dst); SetAF(res, src, dst); SetSZPF_Byte(res); dst = (uint8)res; }
\r
308 #define ADDW(dst, src) { unsigned res = (dst) + (src); SetCFW(res); SetOFW_Add(res, src, dst); SetAF(res, src, dst); SetSZPF_Word(res); dst = (uint16)res; }
\r
310 #define SUBB(dst, src) { unsigned res = (dst) - (src); SetCFB(res); SetOFB_Sub(res, src, dst); SetAF(res, src, dst); SetSZPF_Byte(res); dst = (uint8)res; }
\r
311 #define SUBW(dst, src) { unsigned res = (dst) - (src); SetCFW(res); SetOFW_Sub(res, src, dst); SetAF(res, src, dst); SetSZPF_Word(res); dst = (uint16)res; }
\r
313 #define ORB(dst, src) dst |= (src); CarryVal = OverVal = AuxVal = 0; SetSZPF_Byte(dst)
\r
314 #define ORW(dst, src) dst |= (src); CarryVal = OverVal = AuxVal = 0; SetSZPF_Word(dst)
\r
316 #define ANDB(dst, src) dst &= (src); CarryVal = OverVal = AuxVal = 0; SetSZPF_Byte(dst)
\r
317 #define ANDW(dst, src) dst &= (src); CarryVal = OverVal = AuxVal = 0; SetSZPF_Word(dst)
\r
319 #define XORB(dst, src) dst ^= (src); CarryVal = OverVal = AuxVal = 0; SetSZPF_Byte(dst)
\r
320 #define XORW(dst, src) dst ^= (src); CarryVal = OverVal = AuxVal = 0; SetSZPF_Word(dst)
\r
322 #define CF (CarryVal != 0)
\r
323 #define SF (SignVal < 0)
\r
324 #define ZF (ZeroVal == 0)
\r
325 #define PF parity_table[ParityVal]
\r
326 #define AF (AuxVal != 0)
\r
327 #define OF (OverVal != 0)
\r
328 #define DF (DirVal < 0)
\r
329 #define MD (MF != 0)
\r
331 /************************************************************************/
\r
333 #define AMASK 0xfffff
\r
335 #define read_mem_byte(a) d_mem->read_data8((a) & AMASK)
\r
336 #define read_mem_word(a) d_mem->read_data16((a) & AMASK)
\r
337 #define write_mem_byte(a, d) d_mem->write_data8((a) & AMASK, (d))
\r
338 #define write_mem_word(a, d) d_mem->write_data16((a) & AMASK, (d))
\r
340 #define read_port_byte(a) d_io->read_io8(a)
\r
341 #define read_port_word(a) d_io->read_io16(a)
\r
342 #define write_port_byte(a, d) d_io->write_io8((a), (d))
\r
343 #define write_port_word(a, d) d_io->write_io16((a), (d))
\r
345 /************************************************************************/
\r
347 #define SegBase(Seg) (sregs[Seg] << 4)
\r
349 #define DefaultSeg(Seg) ((seg_prefix && (Seg == DS || Seg == SS)) ? prefix_seg : Seg)
\r
350 #define DefaultBase(Seg) ((seg_prefix && (Seg == DS || Seg == SS)) ? base[prefix_seg] : base[Seg])
\r
352 #define GetMemB(Seg, Off) (read_mem_byte((DefaultBase(Seg) + (Off)) & AMASK))
\r
353 #define GetMemW(Seg, Off) (read_mem_word((DefaultBase(Seg) + (Off)) & AMASK))
\r
354 #define PutMemB(Seg, Off, x) write_mem_byte((DefaultBase(Seg) + (Off)) & AMASK, (x))
\r
355 #define PutMemW(Seg, Off, x) write_mem_word((DefaultBase(Seg) + (Off)) & AMASK, (x))
\r
357 #define ReadByte(ea) (read_mem_byte((ea) & AMASK))
\r
358 #define ReadWord(ea) (read_mem_word((ea) & AMASK))
\r
359 #define WriteByte(ea, val) write_mem_byte((ea) & AMASK, val);
\r
360 #define WriteWord(ea, val) write_mem_word((ea) & AMASK, val);
\r
362 #define FETCH read_mem_byte(pc++)
\r
363 #define FETCHOP read_mem_byte(pc++)
\r
364 #define FETCHWORD(var) { var = read_mem_word(pc); pc += 2; }
\r
365 #define PUSH(val) { regs.w[SP] -= 2; WriteWord(((base[SS] + regs.w[SP]) & AMASK), val); }
\r
366 #define POP(var) { regs.w[SP] += 2; var = ReadWord(((base[SS] + ((regs.w[SP]-2) & 0xffff)) & AMASK)); }
\r
368 /************************************************************************/
\r
370 #define CompressFlags() (uint16)(CF | (PF << 2) | (AF << 4) | (ZF << 6) | (SF << 7) | (TF << 8) | (IF << 9) | (DF << 10) | (OF << 11) | (MD << 15))
\r
372 #define ExpandFlags(f) { \
\r
373 CarryVal = (f) & 1; \
\r
374 ParityVal = !((f) & 4); \
\r
375 AuxVal = (f) & 0x10; \
\r
376 ZeroVal = !((f) & 0x40); \
\r
377 SignVal = ((f) & 0x80) ? -1 : 0; \
\r
378 TF = ((f) & 0x100) >> 8; \
\r
379 IF = ((f) & 0x200) >> 9; \
\r
380 MF = ((f) & 0x8000) >> 15; \
\r
381 DirVal = ((f) & 0x400) ? -1 : 1; \
\r
382 OverVal = (f) & 0x800; \
\r
385 /************************************************************************/
\r
387 #define RegWord(ModRM) regs.w[Mod_RM.reg.w[ModRM]]
\r
388 #define RegByte(ModRM) regs.b[Mod_RM.reg.b[ModRM]]
\r
390 #define GetRMWord(ModRM) \
\r
391 ((ModRM) >= 0xc0 ? regs.w[Mod_RM.RM.w[ModRM]] : (GetEA(ModRM), ReadWord(ea)))
\r
393 #define PutbackRMWord(ModRM, val) { \
\r
394 if (ModRM >= 0xc0) { \
\r
395 regs.w[Mod_RM.RM.w[ModRM]] = val; \
\r
397 WriteWord(ea, val); \
\r
401 #define GetNextRMWord ( \
\r
405 #define GetRMWordOffset(offs) ( \
\r
406 ReadWord(ea - eo + (uint16)(eo + offs)) \
\r
409 #define GetRMByteOffset(offs) ( \
\r
410 ReadByte(ea - eo + (uint16)(eo + offs)) \
\r
413 #define PutRMWord(ModRM, val) { \
\r
414 if (ModRM >= 0xc0) { \
\r
415 regs.w[Mod_RM.RM.w[ModRM]] = val; \
\r
418 WriteWord(ea, val); \
\r
422 #define PutRMWordOffset(offs, val) \
\r
423 WriteWord(ea - eo + (uint16)(eo + offs), val)
\r
425 #define PutRMByteOffset(offs, val) \
\r
426 WriteByte(ea - eo + (uint16)(eo + offs), val)
\r
428 #define PutImmRMWord(ModRM) { \
\r
430 if (ModRM >= 0xc0) { \
\r
431 FETCHWORD(regs.w[Mod_RM.RM.w[ModRM]]) \
\r
435 WriteWord(ea, val); \
\r
439 #define GetRMByte(ModRM) \
\r
440 ((ModRM) >= 0xc0 ? regs.b[Mod_RM.RM.b[ModRM]] : (GetEA(ModRM), ReadByte(ea)))
\r
442 #define PutRMByte(ModRM, val) { \
\r
443 if (ModRM >= 0xc0) { \
\r
444 regs.b[Mod_RM.RM.b[ModRM]] = val; \
\r
447 WriteByte(ea, val); \
\r
451 #define PutImmRMByte(ModRM) { \
\r
452 if (ModRM >= 0xc0) { \
\r
453 regs.b[Mod_RM.RM.b[ModRM]] = FETCH; \
\r
456 WriteByte(ea, FETCH); \
\r
460 #define PutbackRMByte(ModRM, val) { \
\r
461 if (ModRM >= 0xc0) { \
\r
462 regs.b[Mod_RM.RM.b[ModRM]] = val; \
\r
464 WriteByte(ea, val); \
\r
468 #define DEF_br8(dst, src) \
\r
469 unsigned ModRM = FETCHOP; \
\r
470 unsigned src = RegByte(ModRM); \
\r
471 unsigned dst = GetRMByte(ModRM)
\r
473 #define DEF_wr16(dst, src) \
\r
474 unsigned ModRM = FETCHOP; \
\r
475 unsigned src = RegWord(ModRM); \
\r
476 unsigned dst = GetRMWord(ModRM)
\r
478 #define DEF_r8b(dst, src) \
\r
479 unsigned ModRM = FETCHOP; \
\r
480 unsigned dst = RegByte(ModRM); \
\r
481 unsigned src = GetRMByte(ModRM)
\r
483 #define DEF_r16w(dst, src) \
\r
484 unsigned ModRM = FETCHOP; \
\r
485 unsigned dst = RegWord(ModRM); \
\r
486 unsigned src = GetRMWord(ModRM)
\r
488 #define DEF_ald8(dst, src) \
\r
489 unsigned src = FETCHOP; \
\r
490 unsigned dst = regs.b[AL]
\r
492 #define DEF_axd16(dst, src) \
\r
493 unsigned src = FETCHOP; \
\r
494 unsigned dst = regs.w[AX]; \
\r
495 src += (FETCH << 8)
\r
497 /************************************************************************/
\r
500 #define INLINE inline
\r
503 #define offs_t UINT32
\r
505 // Disassembler constants
\r
506 const UINT32 DASMFLAG_SUPPORTED = 0x80000000; // are disassembly flags supported?
\r
507 const UINT32 DASMFLAG_STEP_OUT = 0x40000000; // this instruction should be the end of a step out sequence
\r
508 const UINT32 DASMFLAG_STEP_OVER = 0x20000000; // this instruction should be stepped over by setting a breakpoint afterwards
\r
509 const UINT32 DASMFLAG_OVERINSTMASK = 0x18000000; // number of extra instructions to skip when stepping over
\r
510 const UINT32 DASMFLAG_OVERINSTSHIFT = 27; // bits to shift after masking to get the value
\r
511 const UINT32 DASMFLAG_LENGTHMASK = 0x0000ffff; // the low 16-bits contain the actual length
\r
513 /* Highly useful macro for compile-time knowledge of an array size */
\r
514 #define ARRAY_LENGTH(x) (sizeof(x) / sizeof(x[0]))
\r
516 int necv_dasm_one(char *buffer, UINT32 eip, const UINT8 *oprom);
\r
518 void I86::initialize()
\r
520 static const BREGS reg_name[8] = {AL, CL, DL, BL, AH, CH, DH, BH};
\r
522 for(int i = 0; i < 256; i++) {
\r
523 Mod_RM.reg.b[i] = reg_name[(i & 0x38) >> 3];
\r
524 Mod_RM.reg.w[i] = (WREGS)((i & 0x38) >> 3);
\r
526 for(int i = 0xc0; i < 0x100; i++) {
\r
527 Mod_RM.RM.w[i] = (WREGS)(i & 7);
\r
528 Mod_RM.RM.b[i] = (BREGS)reg_name[i & 7];
\r
530 #ifdef USE_DEBUGGER
\r
531 d_mem_stored = d_mem;
\r
532 d_io_stored = d_io;
\r
533 d_debugger->set_context_mem(d_mem);
\r
534 d_debugger->set_context_io(d_io);
\r
540 for(int i = 0; i < 8; i++) {
\r
543 sregs[CS] = 0xf000;
\r
544 sregs[SS] = sregs[DS] = sregs[ES] = 0;
\r
546 base[CS] = SegBase(CS);
\r
547 base[SS] = base[DS] = base[ES] = 0;
\r
551 AuxVal = OverVal = SignVal = ZeroVal = CarryVal = 0;
\r
553 ParityVal = TF = IF = MF = 0;
\r
555 icount = extra_icount = 0;
\r
557 test_state = false;
\r
560 pc = 0xffff0 & AMASK;
\r
562 ExpandFlags(flags);
\r
566 seg_prefix = false;
\r
569 int I86::run(int clock)
\r
571 /* return now if BUSREQ */
\r
573 #ifdef SINGLE_MODE_DMA
\r
578 int passed_icount = max(1, extra_icount);
\r
579 icount = extra_icount = 0;
\r
580 return passed_icount;
\r
585 // run only one opcode
\r
586 icount = -extra_icount;
\r
588 #ifdef USE_DEBUGGER
\r
589 run_one_opecode_debugger();
\r
595 /* run cpu while given clocks */
\r
597 int first_icount = icount;
\r
598 icount -= extra_icount;
\r
601 while(icount > 0 && !busreq) {
\r
602 #ifdef USE_DEBUGGER
\r
603 run_one_opecode_debugger();
\r
608 int passed_icount = first_icount - icount;
\r
609 if(busreq && icount > 0) {
\r
612 return passed_icount;
\r
616 #ifdef USE_DEBUGGER
\r
617 void I86::run_one_opecode_debugger()
\r
619 bool now_debugging = d_debugger->now_debugging;
\r
620 if(now_debugging) {
\r
621 d_debugger->check_break_points(pc);
\r
622 if(d_debugger->now_suspended) {
\r
624 while(d_debugger->now_debugging && d_debugger->now_suspended) {
\r
628 if(d_debugger->now_debugging) {
\r
629 d_mem = d_io = d_debugger;
\r
631 now_debugging = false;
\r
635 if(now_debugging) {
\r
636 if(!d_debugger->now_going) {
\r
637 d_debugger->now_suspended = true;
\r
639 d_mem = d_mem_stored;
\r
640 d_io = d_io_stored;
\r
648 void I86::run_one_opecode()
\r
650 seg_prefix = false;
\r
652 // ugly patch for PC/JX hardware diagnostics :-(
\r
654 if(pc == 0xff040) pc = 0xff04a;
\r
655 if(pc == 0xff17d) pc = 0xff18f;
\r
657 #ifdef KEYBOARD_HACK
\r
658 if(pc == 0xfa909) { regs.b[BH] = read_port_byte(0xa1); pc = 0xfa97c; }
\r
659 if(pc == 0xff6e1) { regs.b[AL] = 0x0d; pc += 2; }
\r
662 instruction(FETCHOP);
\r
663 if(int_state & NMI_REQ_BIT) {
\r
668 int_state &= ~NMI_REQ_BIT;
\r
669 interrupt(NMI_INT_VECTOR);
\r
670 } else if((int_state & INT_REQ_BIT) && IF) {
\r
677 #ifdef SINGLE_MODE_DMA
\r
682 icount -= extra_icount;
\r
686 void I86::write_signal(int id, uint32 data, uint32 mask)
\r
688 if(id == SIG_CPU_NMI) {
\r
690 int_state |= NMI_REQ_BIT;
\r
692 int_state &= ~NMI_REQ_BIT;
\r
694 } else if(id == SIG_CPU_BUSREQ) {
\r
695 busreq = ((data & mask) != 0);
\r
696 } else if(id == SIG_I86_TEST) {
\r
697 test_state = ((data & mask) != 0);
\r
701 void I86::set_intr_line(bool line, bool pending, uint32 bit)
\r
704 int_state |= INT_REQ_BIT;
\r
706 int_state &= ~INT_REQ_BIT;
\r
710 #ifdef USE_DEBUGGER
\r
711 void I86::debug_write_data8(uint32 addr, uint32 data)
\r
714 d_mem_stored->write_data8w(addr, data, &wait);
\r
717 uint32 I86::debug_read_data8(uint32 addr)
\r
720 return d_mem_stored->read_data8w(addr, &wait);
\r
723 void I86::debug_write_data16(uint32 addr, uint32 data)
\r
726 d_mem_stored->write_data16w(addr, data, &wait);
\r
729 uint32 I86::debug_read_data16(uint32 addr)
\r
732 return d_mem_stored->read_data16w(addr, &wait);
\r
735 void I86::debug_write_io8(uint32 addr, uint32 data)
\r
738 d_io_stored->write_io8w(addr, data, &wait);
\r
741 uint32 I86::debug_read_io8(uint32 addr) {
\r
743 return d_io_stored->read_io8w(addr, &wait);
\r
746 void I86::debug_write_io16(uint32 addr, uint32 data)
\r
749 d_io_stored->write_io16w(addr, data, &wait);
\r
752 uint32 I86::debug_read_io16(uint32 addr) {
\r
754 return d_io_stored->read_io16w(addr, &wait);
\r
757 bool I86::debug_write_reg(_TCHAR *reg, uint32 data)
\r
759 if(_tcsicmp(reg, _T("IP")) == 0) {
\r
760 pc = ((data & 0xffff) + base[CS]) & AMASK;
\r
761 } else if(_tcsicmp(reg, _T("AX")) == 0) {
\r
763 } else if(_tcsicmp(reg, _T("BX")) == 0) {
\r
765 } else if(_tcsicmp(reg, _T("CX")) == 0) {
\r
767 } else if(_tcsicmp(reg, _T("DX")) == 0) {
\r
769 } else if(_tcsicmp(reg, _T("SP")) == 0) {
\r
771 } else if(_tcsicmp(reg, _T("BP")) == 0) {
\r
773 } else if(_tcsicmp(reg, _T("SI")) == 0) {
\r
775 } else if(_tcsicmp(reg, _T("DI")) == 0) {
\r
777 } else if(_tcsicmp(reg, _T("AL")) == 0) {
\r
779 } else if(_tcsicmp(reg, _T("AH")) == 0) {
\r
781 } else if(_tcsicmp(reg, _T("BL")) == 0) {
\r
783 } else if(_tcsicmp(reg, _T("BH")) == 0) {
\r
785 } else if(_tcsicmp(reg, _T("CL")) == 0) {
\r
787 } else if(_tcsicmp(reg, _T("CH")) == 0) {
\r
789 } else if(_tcsicmp(reg, _T("DL")) == 0) {
\r
791 } else if(_tcsicmp(reg, _T("DH")) == 0) {
\r
799 void I86::debug_regs_info(_TCHAR *buffer)
\r
801 _stprintf(buffer, _T("AX=%04X BX=%04X CX=%04X DX=%04X SP=%04X BP=%04X SI=%04X DI=%04X\nDS=%04X ES=%04X SS=%04X CS=%04X IP=%04X FLAG=[%c%c%c%c%c%c%c%c%c]"),
\r
802 regs.w[AX], regs.w[BX], regs.w[CX], regs.w[DX], regs.w[SP], regs.w[BP], regs.w[SI], regs.w[DI], sregs[DS], sregs[ES], sregs[SS], sregs[CS], (uint16)(pc - base[CS]),
\r
803 OF ? _T('O') : _T('-'), DF ? _T('D') : _T('-'), IF ? _T('I') : _T('-'), TF ? _T('T') : _T('-'),
\r
804 SF ? _T('S') : _T('-'), ZF ? _T('Z') : _T('-'), AF ? _T('A') : _T('-'), PF ? _T('P') : _T('-'), CF ? _T('C') : _T('-'));
\r
807 int I86::debug_dasm(uint32 pc, _TCHAR *buffer)
\r
809 UINT32 eip = (UINT32)(uint16)(pc - base[CS]);
\r
811 for(int i = 0; i < 16; i++) {
\r
813 ops[i] = d_mem->read_data8w(pc + i, &wait);
\r
815 return necv_dasm_one(buffer, eip, ops) & DASMFLAG_LENGTHMASK;
\r
819 void I86::interrupt(int int_num)
\r
821 unsigned dest_seg, dest_off;
\r
822 uint16 ip = pc - base[CS];
\r
824 if(int_num == -1) {
\r
825 int_num = d_pic->intr_ack() & 0xff;
\r
826 int_state &= ~INT_REQ_BIT;
\r
828 dest_off = ReadWord(int_num * 4);
\r
829 dest_seg = ReadWord(int_num * 4 + 2);
\r
835 sregs[CS] = (uint16)dest_seg;
\r
836 base[CS] = SegBase(CS);
\r
837 pc = (base[CS] + dest_off) & AMASK;
\r
838 icount -= timing.exception;
\r
843 instruction(FETCHOP);
\r
847 unsigned I86::GetEA(unsigned ModRM)
\r
850 case 0x00: case 0x08: case 0x10: case 0x18: case 0x20: case 0x28: case 0x30: case 0x38:
\r
851 icount -= 7; eo = (uint16)(regs.w[BX] + regs.w[SI]); ea_seg = DefaultSeg(DS); ea = DefaultBase(DS) + eo; return ea;
\r
852 case 0x01: case 0x09: case 0x11: case 0x19: case 0x21: case 0x29: case 0x31: case 0x39:
\r
853 icount -= 8; eo = (uint16)(regs.w[BX] + regs.w[DI]); ea_seg = DefaultSeg(DS); ea = DefaultBase(DS) + eo; return ea;
\r
854 case 0x02: case 0x0a: case 0x12: case 0x1a: case 0x22: case 0x2a: case 0x32: case 0x3a:
\r
855 icount -= 8; eo = (uint16)(regs.w[BP] + regs.w[SI]); ea_seg = DefaultSeg(SS); ea = DefaultBase(SS) + eo; return ea;
\r
856 case 0x03: case 0x0b: case 0x13: case 0x1b: case 0x23: case 0x2b: case 0x33: case 0x3b:
\r
857 icount -= 7; eo = (uint16)(regs.w[BP] + regs.w[DI]); ea_seg = DefaultSeg(SS); ea = DefaultBase(SS) + eo; return ea;
\r
858 case 0x04: case 0x0c: case 0x14: case 0x1c: case 0x24: case 0x2c: case 0x34: case 0x3c:
\r
859 icount -= 5; eo = regs.w[SI]; ea_seg = DefaultSeg(DS); ea = DefaultBase(DS) + eo; return ea;
\r
860 case 0x05: case 0x0d: case 0x15: case 0x1d: case 0x25: case 0x2d: case 0x35: case 0x3d:
\r
861 icount -= 5; eo = regs.w[DI]; ea_seg = DefaultSeg(DS); ea = DefaultBase(DS) + eo; return ea;
\r
862 case 0x06: case 0x0e: case 0x16: case 0x1e: case 0x26: case 0x2e: case 0x36: case 0x3e:
\r
863 icount -= 6; eo = FETCHOP; eo += FETCHOP << 8; ea_seg = DefaultSeg(DS); ea = DefaultBase(DS) + eo; return ea;
\r
864 case 0x07: case 0x0f: case 0x17: case 0x1f: case 0x27: case 0x2f: case 0x37: case 0x3f:
\r
865 icount -= 5; eo = regs.w[BX]; ea_seg = DefaultSeg(DS); ea = DefaultBase(DS) + eo; return ea;
\r
867 case 0x40: case 0x48: case 0x50: case 0x58: case 0x60: case 0x68: case 0x70: case 0x78:
\r
868 icount -= 11; eo = (uint16)(regs.w[BX] + regs.w[SI] + (int8)FETCHOP); ea_seg = DefaultSeg(DS); ea = DefaultBase(DS) + eo; return ea;
\r
869 case 0x41: case 0x49: case 0x51: case 0x59: case 0x61: case 0x69: case 0x71: case 0x79:
\r
870 icount -= 12; eo = (uint16)(regs.w[BX] + regs.w[DI] + (int8)FETCHOP); ea_seg = DefaultSeg(DS); ea = DefaultBase(DS) + eo; return ea;
\r
871 case 0x42: case 0x4a: case 0x52: case 0x5a: case 0x62: case 0x6a: case 0x72: case 0x7a:
\r
872 icount -= 12; eo = (uint16)(regs.w[BP] + regs.w[SI] + (int8)FETCHOP); ea_seg = DefaultSeg(SS); ea = DefaultBase(SS) + eo; return ea;
\r
873 case 0x43: case 0x4b: case 0x53: case 0x5b: case 0x63: case 0x6b: case 0x73: case 0x7b:
\r
874 icount -= 11; eo = (uint16)(regs.w[BP] + regs.w[DI] + (int8)FETCHOP); ea_seg = DefaultSeg(SS); ea = DefaultBase(SS) + eo; return ea;
\r
875 case 0x44: case 0x4c: case 0x54: case 0x5c: case 0x64: case 0x6c: case 0x74: case 0x7c:
\r
876 icount -= 9; eo = (uint16)(regs.w[SI] + (int8)FETCHOP); ea_seg = DefaultSeg(DS); ea = DefaultBase(DS) + eo; return ea;
\r
877 case 0x45: case 0x4d: case 0x55: case 0x5d: case 0x65: case 0x6d: case 0x75: case 0x7d:
\r
878 icount -= 9; eo = (uint16)(regs.w[DI] + (int8)FETCHOP); ea_seg = DefaultSeg(DS); ea = DefaultBase(DS) + eo; return ea;
\r
879 case 0x46: case 0x4e: case 0x56: case 0x5e: case 0x66: case 0x6e: case 0x76: case 0x7e:
\r
880 icount -= 9; eo = (uint16)(regs.w[BP] + (int8)FETCHOP); ea_seg = DefaultSeg(SS); ea = DefaultBase(SS) + eo; return ea;
\r
881 case 0x47: case 0x4f: case 0x57: case 0x5f: case 0x67: case 0x6f: case 0x77: case 0x7f:
\r
882 icount -= 9; eo = (uint16)(regs.w[BX] + (int8)FETCHOP); ea_seg = DefaultSeg(DS); ea = DefaultBase(DS) + eo; return ea;
\r
884 case 0x80: case 0x88: case 0x90: case 0x98: case 0xa0: case 0xa8: case 0xb0: case 0xb8:
\r
885 icount -= 11; eo = FETCHOP; eo += FETCHOP << 8; eo += regs.w[BX] + regs.w[SI]; ea_seg = DefaultSeg(DS); ea = DefaultBase(DS) + (uint16)eo; return ea;
\r
886 case 0x81: case 0x89: case 0x91: case 0x99: case 0xa1: case 0xa9: case 0xb1: case 0xb9:
\r
887 icount -= 12; eo = FETCHOP; eo += FETCHOP << 8; eo += regs.w[BX] + regs.w[DI]; ea_seg = DefaultSeg(DS); ea = DefaultBase(DS) + (uint16)eo; return ea;
\r
888 case 0x82: case 0x8a: case 0x92: case 0x9a: case 0xa2: case 0xaa: case 0xb2: case 0xba:
\r
889 icount -= 12; eo = FETCHOP; eo += FETCHOP << 8; eo += regs.w[BP] + regs.w[SI]; ea_seg = DefaultSeg(SS); ea = DefaultBase(SS) + (uint16)eo; return ea;
\r
890 case 0x83: case 0x8b: case 0x93: case 0x9b: case 0xa3: case 0xab: case 0xb3: case 0xbb:
\r
891 icount -= 11; eo = FETCHOP; eo += FETCHOP << 8; eo += regs.w[BP] + regs.w[DI]; ea_seg = DefaultSeg(DS); ea = DefaultBase(SS) + (uint16)eo; return ea;
\r
892 case 0x84: case 0x8c: case 0x94: case 0x9c: case 0xa4: case 0xac: case 0xb4: case 0xbc:
\r
893 icount -= 9; eo = FETCHOP; eo += FETCHOP << 8; eo += regs.w[SI]; ea_seg = DefaultSeg(DS); ea = DefaultBase(DS) + (uint16)eo; return ea;
\r
894 case 0x85: case 0x8d: case 0x95: case 0x9d: case 0xa5: case 0xad: case 0xb5: case 0xbd:
\r
895 icount -= 9; eo = FETCHOP; eo += FETCHOP << 8; eo += regs.w[DI]; ea_seg = DefaultSeg(DS); ea = DefaultBase(DS) + (uint16)eo; return ea;
\r
896 case 0x86: case 0x8e: case 0x96: case 0x9e: case 0xa6: case 0xae: case 0xb6: case 0xbe:
\r
897 icount -= 9; eo = FETCHOP; eo += FETCHOP << 8; eo += regs.w[BP]; ea_seg = DefaultSeg(SS); ea = DefaultBase(SS) + (uint16)eo; return ea;
\r
898 case 0x87: case 0x8f: case 0x97: case 0x9f: case 0xa7: case 0xaf: case 0xb7: case 0xbf:
\r
899 icount -= 9; eo = FETCHOP; eo += FETCHOP << 8; eo += regs.w[BX]; ea_seg = DefaultSeg(DS); ea = DefaultBase(DS) + (uint16)eo; return ea;
\r
904 void I86::rotate_shift_byte(unsigned ModRM, unsigned count)
\r
906 unsigned src = (unsigned)GetRMByte(ModRM);
\r
907 unsigned dst = src;
\r
910 icount -= (ModRM >= 0xc0) ? timing.rot_reg_base : timing.rot_m8_base;
\r
911 } else if(count == 1) {
\r
912 icount -= (ModRM >= 0xc0) ? timing.rot_reg_1 : timing.rot_m8_1;
\r
914 switch((ModRM >> 3) & 7) {
\r
915 case 0: /* ROL eb, 1 */
\r
916 CarryVal = src & 0x80;
\r
917 dst = (src << 1) + CF;
\r
918 PutbackRMByte(ModRM, dst);
\r
919 OverVal = (src ^ dst) & 0x80;
\r
921 case 1: /* ROR eb, 1 */
\r
922 CarryVal = src & 0x01;
\r
923 dst = ((CF << 8) + src) >> 1;
\r
924 PutbackRMByte(ModRM, dst);
\r
925 OverVal = (src ^ dst) & 0x80;
\r
927 case 2: /* RCL eb, 1 */
\r
928 dst = (src << 1) + CF;
\r
929 PutbackRMByte(ModRM, dst);
\r
931 OverVal = (src ^ dst) & 0x80;
\r
933 case 3: /* RCR eb, 1 */
\r
934 dst = ((CF << 8) + src) >> 1;
\r
935 PutbackRMByte(ModRM, dst);
\r
936 CarryVal = src & 0x01;
\r
937 OverVal = (src ^ dst) & 0x80;
\r
939 case 4: /* SHL eb, 1 */
\r
942 PutbackRMByte(ModRM, dst);
\r
944 OverVal = (src ^ dst) & 0x80;
\r
948 case 5: /* SHR eb, 1 */
\r
950 PutbackRMByte(ModRM, dst);
\r
951 CarryVal = src & 0x01;
\r
952 OverVal = src & 0x80;
\r
956 case 7: /* SAR eb, 1 */
\r
957 dst = ((int8)src) >> 1;
\r
958 PutbackRMByte(ModRM, dst);
\r
959 CarryVal = src & 0x01;
\r
969 icount -= (ModRM >= 0xc0) ? timing.rot_reg_base + timing.rot_reg_bit : timing.rot_m8_base + timing.rot_m8_bit;
\r
971 switch((ModRM >> 3) & 7) {
\r
972 case 0: /* ROL eb, count */
\r
973 for(; count > 0; count--) {
\r
974 CarryVal = dst & 0x80;
\r
975 dst = (dst << 1) + CF;
\r
977 PutbackRMByte(ModRM, (uint8)dst);
\r
979 case 1: /* ROR eb, count */
\r
980 for(; count > 0; count--) {
\r
981 CarryVal = dst & 0x01;
\r
982 dst = (dst >> 1) + (CF << 7);
\r
984 PutbackRMByte(ModRM, (uint8)dst);
\r
986 case 2: /* RCL eb, count */
\r
987 for(; count > 0; count--) {
\r
988 dst = (dst << 1) + CF;
\r
991 PutbackRMByte(ModRM, (uint8)dst);
\r
993 case 3: /* RCR eb, count */
\r
994 for(; count > 0; count--) {
\r
995 dst = (CF << 8) + dst;
\r
996 CarryVal = dst & 0x01;
\r
999 PutbackRMByte(ModRM, (uint8)dst);
\r
1001 case 4: /* SHL eb, count */
\r
1006 SetSZPF_Byte(dst);
\r
1007 PutbackRMByte(ModRM, (uint8)dst);
\r
1009 case 5: /* SHR eb, count */
\r
1010 dst >>= count - 1;
\r
1011 CarryVal = dst & 0x01;
\r
1013 SetSZPF_Byte(dst);
\r
1015 PutbackRMByte(ModRM, (uint8)dst);
\r
1017 case 7: /* SAR eb, count */
\r
1018 dst = ((int8)dst) >> (count - 1);
\r
1019 CarryVal = dst & 0x01;
\r
1020 dst = ((int8)((uint8)dst)) >> 1;
\r
1021 SetSZPF_Byte(dst);
\r
1023 PutbackRMByte(ModRM, (uint8)dst);
\r
1032 void I86::rotate_shift_word(unsigned ModRM, unsigned count)
\r
1034 unsigned src = GetRMWord(ModRM);
\r
1035 unsigned dst = src;
\r
1038 icount -= (ModRM >= 0xc0) ? timing.rot_reg_base : timing.rot_m16_base;
\r
1039 } else if(count == 1) {
\r
1040 icount -= (ModRM >= 0xc0) ? timing.rot_reg_1 : timing.rot_m16_1;
\r
1042 switch((ModRM >> 3) & 7) {
\r
1043 case 0: /* ROL ew, 1 */
\r
1044 CarryVal = src & 0x8000;
\r
1045 dst = (src << 1) + CF;
\r
1046 PutbackRMWord(ModRM, dst);
\r
1047 OverVal = (src ^ dst) & 0x8000;
\r
1049 case 1: /* ROR ew, 1 */
\r
1050 CarryVal = src & 0x01;
\r
1051 dst = ((CF << 16) + src) >> 1;
\r
1052 PutbackRMWord(ModRM, dst);
\r
1053 OverVal = (src ^ dst) & 0x8000;
\r
1055 case 2: /* RCL ew, 1 */
\r
1056 dst = (src << 1) + CF;
\r
1057 PutbackRMWord(ModRM, dst);
\r
1059 OverVal = (src ^ dst) & 0x8000;
\r
1061 case 3: /* RCR ew, 1 */
\r
1062 dst = ((CF << 16) + src) >> 1;
\r
1063 PutbackRMWord(ModRM, dst);
\r
1064 CarryVal = src & 0x01;
\r
1065 OverVal = (src ^ dst) & 0x8000;
\r
1067 case 4: /* SHL ew, 1 */
\r
1070 PutbackRMWord(ModRM, dst);
\r
1072 OverVal = (src ^ dst) & 0x8000;
\r
1074 SetSZPF_Word(dst);
\r
1076 case 5: /* SHR ew, 1 */
\r
1078 PutbackRMWord(ModRM, dst);
\r
1079 CarryVal = src & 0x01;
\r
1080 OverVal = src & 0x8000;
\r
1082 SetSZPF_Word(dst);
\r
1084 case 7: /* SAR ew, 1 */
\r
1085 dst = ((int16)src) >> 1;
\r
1086 PutbackRMWord(ModRM, dst);
\r
1087 CarryVal = src & 0x01;
\r
1090 SetSZPF_Word(dst);
\r
1097 icount -= (ModRM >= 0xc0) ? timing.rot_reg_base + timing.rot_reg_bit : timing.rot_m8_base + timing.rot_m16_bit;
\r
1099 switch((ModRM >> 3) & 7) {
\r
1100 case 0: /* ROL ew, count */
\r
1101 for(; count > 0; count--) {
\r
1102 CarryVal = dst & 0x8000;
\r
1103 dst = (dst << 1) + CF;
\r
1105 PutbackRMWord(ModRM, dst);
\r
1107 case 1: /* ROR ew, count */
\r
1108 for(; count > 0; count--) {
\r
1109 CarryVal = dst & 0x01;
\r
1110 dst = (dst >> 1) + (CF << 15);
\r
1112 PutbackRMWord(ModRM, dst);
\r
1114 case 2: /* RCL ew, count */
\r
1115 for(; count > 0; count--) {
\r
1116 dst = (dst << 1) + CF;
\r
1119 PutbackRMWord(ModRM, dst);
\r
1121 case 3: /* RCR ew, count */
\r
1122 for(; count > 0; count--) {
\r
1123 dst = dst + (CF << 16);
\r
1124 CarryVal = dst & 0x01;
\r
1127 PutbackRMWord(ModRM, dst);
\r
1129 case 4: /* SHL ew, count */
\r
1134 SetSZPF_Word(dst);
\r
1135 PutbackRMWord(ModRM, dst);
\r
1137 case 5: /* SHR ew, count */
\r
1138 dst >>= count - 1;
\r
1139 CarryVal = dst & 0x01;
\r
1141 SetSZPF_Word(dst);
\r
1143 PutbackRMWord(ModRM, dst);
\r
1145 case 7: /* SAR ew, count */
\r
1146 dst = ((int16)dst) >> (count - 1);
\r
1147 CarryVal = dst & 0x01;
\r
1148 dst = ((int16)((uint16)dst)) >> 1;
\r
1149 SetSZPF_Word(dst);
\r
1151 PutbackRMWord(ModRM, dst);
\r
1160 void I86::instruction(uint8 code)
\r
1165 case 0x00: _add_br8(); break;
\r
1166 case 0x01: _add_wr16(); break;
\r
1167 case 0x02: _add_r8b(); break;
\r
1168 case 0x03: _add_r16w(); break;
\r
1169 case 0x04: _add_ald8(); break;
\r
1170 case 0x05: _add_axd16(); break;
\r
1171 case 0x06: _push_es(); break;
\r
1172 case 0x07: _pop_es(); break;
\r
1173 case 0x08: _or_br8(); break;
\r
1174 case 0x09: _or_wr16(); break;
\r
1175 case 0x0a: _or_r8b(); break;
\r
1176 case 0x0b: _or_r16w(); break;
\r
1177 case 0x0c: _or_ald8(); break;
\r
1178 case 0x0d: _or_axd16(); break;
\r
1179 case 0x0e: _push_cs(); break;
\r
1180 #if defined(HAS_V30)
\r
1181 case 0x0f: _0fpre(); break;
\r
1183 case 0x0f: _invalid(); break;
\r
1185 case 0x10: _adc_br8(); break;
\r
1186 case 0x11: _adc_wr16(); break;
\r
1187 case 0x12: _adc_r8b(); break;
\r
1188 case 0x13: _adc_r16w(); break;
\r
1189 case 0x14: _adc_ald8(); break;
\r
1190 case 0x15: _adc_axd16(); break;
\r
1191 case 0x16: _push_ss(); break;
\r
1192 case 0x17: _pop_ss(); break;
\r
1193 case 0x18: _sbb_br8(); break;
\r
1194 case 0x19: _sbb_wr16(); break;
\r
1195 case 0x1a: _sbb_r8b(); break;
\r
1196 case 0x1b: _sbb_r16w(); break;
\r
1197 case 0x1c: _sbb_ald8(); break;
\r
1198 case 0x1d: _sbb_axd16(); break;
\r
1199 case 0x1e: _push_ds(); break;
\r
1200 case 0x1f: _pop_ds(); break;
\r
1201 case 0x20: _and_br8(); break;
\r
1202 case 0x21: _and_wr16(); break;
\r
1203 case 0x22: _and_r8b(); break;
\r
1204 case 0x23: _and_r16w(); break;
\r
1205 case 0x24: _and_ald8(); break;
\r
1206 case 0x25: _and_axd16(); break;
\r
1207 case 0x26: _es(); break;
\r
1208 case 0x27: _daa(); break;
\r
1209 case 0x28: _sub_br8(); break;
\r
1210 case 0x29: _sub_wr16(); break;
\r
1211 case 0x2a: _sub_r8b(); break;
\r
1212 case 0x2b: _sub_r16w(); break;
\r
1213 case 0x2c: _sub_ald8(); break;
\r
1214 case 0x2d: _sub_axd16(); break;
\r
1215 case 0x2e: _cs(); break;
\r
1216 case 0x2f: _das(); break;
\r
1217 case 0x30: _xor_br8(); break;
\r
1218 case 0x31: _xor_wr16(); break;
\r
1219 case 0x32: _xor_r8b(); break;
\r
1220 case 0x33: _xor_r16w(); break;
\r
1221 case 0x34: _xor_ald8(); break;
\r
1222 case 0x35: _xor_axd16(); break;
\r
1223 case 0x36: _ss(); break;
\r
1224 case 0x37: _aaa(); break;
\r
1225 case 0x38: _cmp_br8(); break;
\r
1226 case 0x39: _cmp_wr16(); break;
\r
1227 case 0x3a: _cmp_r8b(); break;
\r
1228 case 0x3b: _cmp_r16w(); break;
\r
1229 case 0x3c: _cmp_ald8(); break;
\r
1230 case 0x3d: _cmp_axd16(); break;
\r
1231 case 0x3e: _ds(); break;
\r
1232 case 0x3f: _aas(); break;
\r
1233 case 0x40: _inc_ax(); break;
\r
1234 case 0x41: _inc_cx(); break;
\r
1235 case 0x42: _inc_dx(); break;
\r
1236 case 0x43: _inc_bx(); break;
\r
1237 case 0x44: _inc_sp(); break;
\r
1238 case 0x45: _inc_bp(); break;
\r
1239 case 0x46: _inc_si(); break;
\r
1240 case 0x47: _inc_di(); break;
\r
1241 case 0x48: _dec_ax(); break;
\r
1242 case 0x49: _dec_cx(); break;
\r
1243 case 0x4a: _dec_dx(); break;
\r
1244 case 0x4b: _dec_bx(); break;
\r
1245 case 0x4c: _dec_sp(); break;
\r
1246 case 0x4d: _dec_bp(); break;
\r
1247 case 0x4e: _dec_si(); break;
\r
1248 case 0x4f: _dec_di(); break;
\r
1249 case 0x50: _push_ax(); break;
\r
1250 case 0x51: _push_cx(); break;
\r
1251 case 0x52: _push_dx(); break;
\r
1252 case 0x53: _push_bx(); break;
\r
1253 case 0x54: _push_sp(); break;
\r
1254 case 0x55: _push_bp(); break;
\r
1255 case 0x56: _push_si(); break;
\r
1256 case 0x57: _push_di(); break;
\r
1257 case 0x58: _pop_ax(); break;
\r
1258 case 0x59: _pop_cx(); break;
\r
1259 case 0x5a: _pop_dx(); break;
\r
1260 case 0x5b: _pop_bx(); break;
\r
1261 case 0x5c: _pop_sp(); break;
\r
1262 case 0x5d: _pop_bp(); break;
\r
1263 case 0x5e: _pop_si(); break;
\r
1264 case 0x5f: _pop_di(); break;
\r
1265 #if defined(HAS_V30)
\r
1266 case 0x60: _pusha(); break;
\r
1267 case 0x61: _popa(); break;
\r
1268 case 0x62: _bound(); break;
\r
1270 case 0x60: _invalid(); break;
\r
1271 case 0x61: _invalid(); break;
\r
1272 case 0x62: _invalid(); break;
\r
1274 case 0x63: _invalid(); break;
\r
1275 #if defined(HAS_V30)
\r
1276 case 0x64: _repc(0); break;
\r
1277 case 0x65: _repc(1); break;
\r
1279 case 0x64: _invalid(); break;
\r
1280 case 0x65: _invalid(); break;
\r
1282 case 0x66: _invalid(); break;
\r
1283 case 0x67: _invalid(); break;
\r
1284 #if defined(HAS_V30)
\r
1285 case 0x68: _push_d16(); break;
\r
1286 case 0x69: _imul_d16(); break;
\r
1287 case 0x6a: _push_d8(); break;
\r
1288 case 0x6b: _imul_d8(); break;
\r
1289 case 0x6c: _insb(); break;
\r
1290 case 0x6d: _insw(); break;
\r
1291 case 0x6e: _outsb(); break;
\r
1292 case 0x6f: _outsw(); break;
\r
1294 case 0x68: _invalid(); break;
\r
1295 case 0x69: _invalid(); break;
\r
1296 case 0x6a: _invalid(); break;
\r
1297 case 0x6b: _invalid(); break;
\r
1298 case 0x6c: _invalid(); break;
\r
1299 case 0x6d: _invalid(); break;
\r
1300 case 0x6e: _invalid(); break;
\r
1301 case 0x6f: _invalid(); break;
\r
1303 case 0x70: _jo(); break;
\r
1304 case 0x71: _jno(); break;
\r
1305 case 0x72: _jb(); break;
\r
1306 case 0x73: _jnb(); break;
\r
1307 case 0x74: _jz(); break;
\r
1308 case 0x75: _jnz(); break;
\r
1309 case 0x76: _jbe(); break;
\r
1310 case 0x77: _jnbe(); break;
\r
1311 case 0x78: _js(); break;
\r
1312 case 0x79: _jns(); break;
\r
1313 case 0x7a: _jp(); break;
\r
1314 case 0x7b: _jnp(); break;
\r
1315 case 0x7c: _jl(); break;
\r
1316 case 0x7d: _jnl(); break;
\r
1317 case 0x7e: _jle(); break;
\r
1318 case 0x7f: _jnle(); break;
\r
1319 case 0x80: _80pre(); break;
\r
1320 case 0x81: _81pre(); break;
\r
1321 case 0x82: _82pre(); break;
\r
1322 case 0x83: _83pre(); break;
\r
1323 case 0x84: _test_br8(); break;
\r
1324 case 0x85: _test_wr16(); break;
\r
1325 case 0x86: _xchg_br8(); break;
\r
1326 case 0x87: _xchg_wr16(); break;
\r
1327 case 0x88: _mov_br8(); break;
\r
1328 case 0x89: _mov_wr16(); break;
\r
1329 case 0x8a: _mov_r8b(); break;
\r
1330 case 0x8b: _mov_r16w(); break;
\r
1331 case 0x8c: _mov_wsreg(); break;
\r
1332 case 0x8d: _lea(); break;
\r
1333 case 0x8e: _mov_sregw(); break;
\r
1334 case 0x8f: _popw(); break;
\r
1335 case 0x90: _nop(); break;
\r
1336 case 0x91: _xchg_axcx(); break;
\r
1337 case 0x92: _xchg_axdx(); break;
\r
1338 case 0x93: _xchg_axbx(); break;
\r
1339 case 0x94: _xchg_axsp(); break;
\r
1340 case 0x95: _xchg_axbp(); break;
\r
1341 case 0x96: _xchg_axsi(); break;
\r
1342 case 0x97: _xchg_axdi(); break;
\r
1343 case 0x98: _cbw(); break;
\r
1344 case 0x99: _cwd(); break;
\r
1345 case 0x9a: _call_far(); break;
\r
1346 case 0x9b: _wait(); break;
\r
1347 case 0x9c: _pushf(); break;
\r
1348 case 0x9d: _popf(); break;
\r
1349 case 0x9e: _sahf(); break;
\r
1350 case 0x9f: _lahf(); break;
\r
1351 case 0xa0: _mov_aldisp(); break;
\r
1352 case 0xa1: _mov_axdisp(); break;
\r
1353 case 0xa2: _mov_dispal(); break;
\r
1354 case 0xa3: _mov_dispax(); break;
\r
1355 case 0xa4: _movsb(); break;
\r
1356 case 0xa5: _movsw(); break;
\r
1357 case 0xa6: _cmpsb(); break;
\r
1358 case 0xa7: _cmpsw(); break;
\r
1359 case 0xa8: _test_ald8(); break;
\r
1360 case 0xa9: _test_axd16(); break;
\r
1361 case 0xaa: _stosb(); break;
\r
1362 case 0xab: _stosw(); break;
\r
1363 case 0xac: _lodsb(); break;
\r
1364 case 0xad: _lodsw(); break;
\r
1365 case 0xae: _scasb(); break;
\r
1366 case 0xaf: _scasw(); break;
\r
1367 case 0xb0: _mov_ald8(); break;
\r
1368 case 0xb1: _mov_cld8(); break;
\r
1369 case 0xb2: _mov_dld8(); break;
\r
1370 case 0xb3: _mov_bld8(); break;
\r
1371 case 0xb4: _mov_ahd8(); break;
\r
1372 case 0xb5: _mov_chd8(); break;
\r
1373 case 0xb6: _mov_dhd8(); break;
\r
1374 case 0xb7: _mov_bhd8(); break;
\r
1375 case 0xb8: _mov_axd16(); break;
\r
1376 case 0xb9: _mov_cxd16(); break;
\r
1377 case 0xba: _mov_dxd16(); break;
\r
1378 case 0xbb: _mov_bxd16(); break;
\r
1379 case 0xbc: _mov_spd16(); break;
\r
1380 case 0xbd: _mov_bpd16(); break;
\r
1381 case 0xbe: _mov_sid16(); break;
\r
1382 case 0xbf: _mov_did16(); break;
\r
1383 #if defined(HAS_V30)
\r
1384 case 0xc0: _rotshft_bd8(); break;
\r
1385 case 0xc1: _rotshft_wd8(); break;
\r
1387 case 0xc0: _invalid(); break;
\r
1388 case 0xc1: _invalid(); break;
\r
1390 case 0xc2: _ret_d16(); break;
\r
1391 case 0xc3: _ret(); break;
\r
1392 case 0xc4: _les_dw(); break;
\r
1393 case 0xc5: _lds_dw(); break;
\r
1394 case 0xc6: _mov_bd8(); break;
\r
1395 case 0xc7: _mov_wd16(); break;
\r
1396 #if defined(HAS_V30)
\r
1397 case 0xc8: _enter(); break;
\r
1398 case 0xc9: _leav(); break; /* _leave() */
\r
1400 case 0xc8: _invalid(); break;
\r
1401 case 0xc9: _invalid(); break;
\r
1403 case 0xca: _retf_d16(); break;
\r
1404 case 0xcb: _retf(); break;
\r
1405 case 0xcc: _int3(); break;
\r
1406 case 0xcd: _int(); break;
\r
1407 case 0xce: _into(); break;
\r
1408 case 0xcf: _iret(); break;
\r
1409 case 0xd0: _rotshft_b(); break;
\r
1410 case 0xd1: _rotshft_w(); break;
\r
1411 case 0xd2: _rotshft_bcl(); break;
\r
1412 case 0xd3: _rotshft_wcl(); break;
\r
1413 case 0xd4: _aam(); break;
\r
1414 case 0xd5: _aad(); break;
\r
1415 #if defined(HAS_V30)
\r
1416 case 0xd6: _setalc(); break;
\r
1418 case 0xd6: _invalid(); break;
\r
1420 case 0xd7: _xlat(); break;
\r
1421 case 0xd8: _escape(); break;
\r
1422 case 0xd9: _escape(); break;
\r
1423 case 0xda: _escape(); break;
\r
1424 case 0xdb: _escape(); break;
\r
1425 case 0xdc: _escape(); break;
\r
1426 case 0xdd: _escape(); break;
\r
1427 case 0xde: _escape(); break;
\r
1428 case 0xdf: _escape(); break;
\r
1429 case 0xe0: _loopne(); break;
\r
1430 case 0xe1: _loope(); break;
\r
1431 case 0xe2: _loop(); break;
\r
1432 case 0xe3: _jcxz(); break;
\r
1433 case 0xe4: _inal(); break;
\r
1434 case 0xe5: _inax(); break;
\r
1435 case 0xe6: _outal(); break;
\r
1436 case 0xe7: _outax(); break;
\r
1437 case 0xe8: _call_d16(); break;
\r
1438 case 0xe9: _jmp_d16(); break;
\r
1439 case 0xea: _jmp_far(); break;
\r
1440 case 0xeb: _jmp_d8(); break;
\r
1441 case 0xec: _inaldx(); break;
\r
1442 case 0xed: _inaxdx(); break;
\r
1443 case 0xee: _outdxal(); break;
\r
1444 case 0xef: _outdxax(); break;
\r
1445 case 0xf0: _lock(); break;
\r
1446 case 0xf1: _invalid(); break;
\r
1447 case 0xf2: _repne(); break;
\r
1448 case 0xf3: _repe(); break;
\r
1449 case 0xf4: _hlt(); break;
\r
1450 case 0xf5: _cmc(); break;
\r
1451 case 0xf6: _f6pre(); break;
\r
1452 case 0xf7: _f7pre(); break;
\r
1453 case 0xf8: _clc(); break;
\r
1454 case 0xf9: _stc(); break;
\r
1455 case 0xfa: _cli(); break;
\r
1456 case 0xfb: _sti(); break;
\r
1457 case 0xfc: _cld(); break;
\r
1458 case 0xfd: _std(); break;
\r
1459 case 0xfe: _fepre(); break;
\r
1460 case 0xff: _ffpre(); break;
\r
1461 default: _add_br8(); break;
\r
1462 //default: __assume(0);
\r
1466 inline void I86::_add_br8() /* Opcode 0x00 */
\r
1468 DEF_br8(dst, src);
\r
1469 icount -= (ModRM >= 0xc0) ? timing.alu_rr8 : timing.alu_mr8;
\r
1471 PutbackRMByte(ModRM, dst);
\r
1474 inline void I86::_add_wr16() /* Opcode 0x01 */
\r
1476 DEF_wr16(dst, src);
\r
1477 icount -= (ModRM >= 0xc0) ? timing.alu_rr16 : timing.alu_mr16;
\r
1479 PutbackRMWord(ModRM, dst);
\r
1482 inline void I86::_add_r8b() /* Opcode 0x02 */
\r
1484 DEF_r8b(dst, src);
\r
1485 icount -= (ModRM >= 0xc0) ? timing.alu_rr8 : timing.alu_rm8;
\r
1487 RegByte(ModRM) = dst;
\r
1490 inline void I86::_add_r16w() /* Opcode 0x03 */
\r
1492 DEF_r16w(dst, src);
\r
1493 icount -= (ModRM >= 0xc0) ? timing.alu_rr16 : timing.alu_rm16;
\r
1495 RegWord(ModRM) = dst;
\r
1498 inline void I86::_add_ald8() /* Opcode 0x04 */
\r
1500 DEF_ald8(dst, src);
\r
1501 icount -= timing.alu_ri8;
\r
1506 inline void I86::_add_axd16() /* Opcode 0x05 */
\r
1508 DEF_axd16(dst, src);
\r
1509 icount -= timing.alu_ri16;
\r
1514 inline void I86::_push_es() /* Opcode 0x06 */
\r
1516 icount -= timing.push_seg;
\r
1520 inline void I86::_pop_es() /* Opcode 0x07 */
\r
1523 base[ES] = SegBase(ES);
\r
1524 icount -= timing.pop_seg;
\r
1527 inline void I86::_or_br8() /* Opcode 0x08 */
\r
1529 DEF_br8(dst, src);
\r
1530 icount -= (ModRM >= 0xc0) ? timing.alu_rr8 : timing.alu_mr8;
\r
1532 PutbackRMByte(ModRM, dst);
\r
1535 inline void I86::_or_wr16() /* Opcode 0x09 */
\r
1537 DEF_wr16(dst, src);
\r
1538 icount -= (ModRM >= 0xc0) ? timing.alu_rr16 : timing.alu_mr16;
\r
1540 PutbackRMWord(ModRM, dst);
\r
1543 inline void I86::_or_r8b() /* Opcode 0x0a */
\r
1545 DEF_r8b(dst, src);
\r
1546 icount -= (ModRM >= 0xc0) ? timing.alu_rr8 : timing.alu_rm8;
\r
1548 RegByte(ModRM) = dst;
\r
1551 inline void I86::_or_r16w() /* Opcode 0x0b */
\r
1553 DEF_r16w(dst, src);
\r
1554 icount -= (ModRM >= 0xc0) ? timing.alu_rr16 : timing.alu_rm16;
\r
1556 RegWord(ModRM) = dst;
\r
1559 inline void I86::_or_ald8() /* Opcode 0x0c */
\r
1561 DEF_ald8(dst, src);
\r
1562 icount -= timing.alu_ri8;
\r
1567 inline void I86::_or_axd16() /* Opcode 0x0d */
\r
1569 DEF_axd16(dst, src);
\r
1570 icount -= timing.alu_ri16;
\r
1575 inline void I86::_push_cs() /* Opcode 0x0e */
\r
1577 icount -= timing.push_seg;
\r
1581 #if defined(HAS_V30)
\r
1582 inline void I86::_0fpre() /* Opcode 0x0f */
\r
1584 static const uint16 bytes[] = {
\r
1585 1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096, 8192, 16384, 32768
\r
1587 unsigned code = FETCH;
\r
1593 case 0x10: /* 0F 10 47 30 - TEST1 [bx+30h], cl */
\r
1595 if(ModRM >= 0xc0) {
\r
1596 tmp = regs.b[Mod_RM.RM.b[ModRM]];
\r
1601 tmp = ReadByte(ea);
\r
1602 icount = old - 12;
\r
1604 tmp2 = regs.b[CL] & 7;
\r
1605 SetZF(tmp & bytes[tmp2]);
\r
1607 case 0x11: /* 0F 11 47 30 - TEST1 [bx+30h], cl */
\r
1609 if(ModRM >= 0xc0) {
\r
1610 tmp = regs.w[Mod_RM.RM.w[ModRM]];
\r
1615 tmp = ReadWord(ea);
\r
1616 icount = old - 12;
\r
1618 tmp2 = regs.b[CL] & 0xf;
\r
1619 SetZF(tmp & bytes[tmp2]);
\r
1621 case 0x12: /* 0F 12 [mod:000:r/m] - CLR1 reg/m8, cl */
\r
1623 if(ModRM >= 0xc0) {
\r
1624 tmp = regs.b[Mod_RM.RM.b[ModRM]];
\r
1629 tmp = ReadByte(ea);
\r
1630 icount = old - 14;
\r
1632 tmp2 = regs.b[CL] & 7;
\r
1633 tmp &= ~bytes[tmp2];
\r
1634 PutbackRMByte(ModRM, tmp);
\r
1636 case 0x13: /* 0F 13 [mod:000:r/m] - CLR1 reg/m16, cl */
\r
1638 if(ModRM >= 0xc0) {
\r
1639 tmp = regs.w[Mod_RM.RM.w[ModRM]];
\r
1644 tmp = ReadWord(ea);
\r
1645 icount = old - 14;
\r
1647 tmp2 = regs.b[CL] & 0xf;
\r
1648 tmp &= ~bytes[tmp2];
\r
1649 PutbackRMWord(ModRM, tmp);
\r
1651 case 0x14: /* 0F 14 47 30 - SET1 [bx+30h], cl */
\r
1653 if(ModRM >= 0xc0) {
\r
1654 tmp = regs.b[Mod_RM.RM.b[ModRM]];
\r
1659 tmp = ReadByte(ea);
\r
1660 icount = old - 13;
\r
1662 tmp2 = regs.b[CL] & 7;
\r
1663 tmp |= bytes[tmp2];
\r
1664 PutbackRMByte(ModRM, tmp);
\r
1666 case 0x15: /* 0F 15 C6 - SET1 si, cl */
\r
1668 if(ModRM >= 0xc0) {
\r
1669 tmp = regs.w[Mod_RM.RM.w[ModRM]];
\r
1674 tmp = ReadWord(ea);
\r
1675 icount = old - 13;
\r
1677 tmp2 = regs.b[CL] & 0xf;
\r
1678 tmp |= bytes[tmp2];
\r
1679 PutbackRMWord(ModRM, tmp);
\r
1681 case 0x16: /* 0F 16 C6 - NOT1 si, cl */
\r
1683 if(ModRM >= 0xc0) {
\r
1684 tmp = regs.b[Mod_RM.RM.b[ModRM]];
\r
1689 tmp = ReadByte(ea);
\r
1690 icount = old - 18;
\r
1692 tmp2 = regs.b[CL] & 7;
\r
1693 if(tmp & bytes[tmp2]) {
\r
1694 tmp &= ~bytes[tmp2];
\r
1696 tmp |= bytes[tmp2];
\r
1698 PutbackRMByte(ModRM, tmp);
\r
1700 case 0x17: /* 0F 17 C6 - NOT1 si, cl */
\r
1702 if(ModRM >= 0xc0) {
\r
1703 tmp = regs.w[Mod_RM.RM.w[ModRM]];
\r
1708 tmp = ReadWord(ea);
\r
1709 icount = old - 18;
\r
1711 tmp2 = regs.b[CL] & 0xf;
\r
1712 if(tmp & bytes[tmp2]) {
\r
1713 tmp &= ~bytes[tmp2];
\r
1715 tmp |= bytes[tmp2];
\r
1717 PutbackRMWord(ModRM, tmp);
\r
1719 case 0x18: /* 0F 18 XX - TEST1 [bx+30h], 07 */
\r
1721 if(ModRM >= 0xc0) {
\r
1722 tmp = regs.b[Mod_RM.RM.b[ModRM]];
\r
1727 tmp = ReadByte(ea);
\r
1728 icount = old - 13;
\r
1732 SetZF(tmp & bytes[tmp2]);
\r
1734 case 0x19: /* 0F 19 XX - TEST1 [bx+30h], 07 */
\r
1736 if(ModRM >= 0xc0) {
\r
1737 tmp = regs.w[Mod_RM.RM.w[ModRM]];
\r
1742 tmp = ReadWord(ea);
\r
1743 icount = old - 13;
\r
1747 SetZF(tmp & bytes[tmp2]);
\r
1749 case 0x1a: /* 0F 1A 06 - CLR1 si, cl */
\r
1751 if(ModRM >= 0xc0) {
\r
1752 tmp = regs.b[Mod_RM.RM.b[ModRM]];
\r
1757 tmp = ReadByte(ea);
\r
1758 icount = old - 15;
\r
1762 tmp &= ~bytes[tmp2];
\r
1763 PutbackRMByte(ModRM, tmp);
\r
1765 case 0x1B: /* 0F 1B 06 - CLR1 si, cl */
\r
1767 if(ModRM >= 0xc0) {
\r
1768 tmp = regs.w[Mod_RM.RM.w[ModRM]];
\r
1773 tmp = ReadWord(ea);
\r
1774 icount = old - 15;
\r
1778 tmp &= ~bytes[tmp2];
\r
1779 PutbackRMWord(ModRM, tmp);
\r
1781 case 0x1C: /* 0F 1C 47 30 - SET1 [bx+30h], cl */
\r
1783 if(ModRM >= 0xc0) {
\r
1784 tmp = regs.b[Mod_RM.RM.b[ModRM]];
\r
1789 tmp = ReadByte(ea);
\r
1790 icount = old - 14;
\r
1794 tmp |= bytes[tmp2];
\r
1795 PutbackRMByte(ModRM, tmp);
\r
1797 case 0x1D: /* 0F 1D C6 - SET1 si, cl */
\r
1799 if(ModRM >= 0xc0) {
\r
1800 tmp = regs.w[Mod_RM.RM.w[ModRM]];
\r
1805 tmp = ReadWord(ea);
\r
1806 icount = old - 14;
\r
1810 tmp |= bytes[tmp2];
\r
1811 PutbackRMWord(ModRM, tmp);
\r
1813 case 0x1e: /* 0F 1e C6 - NOT1 si, 07 */
\r
1815 if(ModRM >= 0xc0) {
\r
1816 tmp = regs.b[Mod_RM.RM.b[ModRM]];
\r
1821 tmp = ReadByte(ea);
\r
1822 icount = old - 19;
\r
1826 if(tmp & bytes[tmp2]) {
\r
1827 tmp &= ~bytes[tmp2];
\r
1829 tmp |= bytes[tmp2];
\r
1831 PutbackRMByte(ModRM, tmp);
\r
1833 case 0x1f: /* 0F 1f C6 - NOT1 si, 07 */
\r
1835 if(ModRM >= 0xc0) {
\r
1836 tmp = regs.w[Mod_RM.RM.w[ModRM]];
\r
1841 tmp = ReadWord(ea);
\r
1842 icount = old - 19;
\r
1846 if(tmp & bytes[tmp2]) {
\r
1847 tmp &= ~bytes[tmp2];
\r
1849 tmp |= bytes[tmp2];
\r
1851 PutbackRMWord(ModRM, tmp);
\r
1853 case 0x20: /* 0F 20 59 - add4s */
\r
1855 /* length in words ! */
\r
1856 int count = (regs.b[CL] + 1) / 2;
\r
1857 unsigned di = regs.w[DI];
\r
1858 unsigned si = regs.w[SI];
\r
1861 CarryVal = 0; /* NOT ADC */
\r
1862 for(int i = 0; i < count; i++) {
\r
1863 tmp = GetMemB(DS, si);
\r
1864 tmp2 = GetMemB(ES, di);
\r
1865 int v1 = (tmp >> 4) * 10 + (tmp & 0xf);
\r
1866 int v2 = (tmp2 >> 4) * 10 + (tmp2 & 0xf);
\r
1867 int result = v1 + v2 + CarryVal;
\r
1868 CarryVal = result > 99 ? 1 : 0;
\r
1869 result = result % 100;
\r
1870 v1 = ((result / 10) << 4) | (result % 10);
\r
1871 PutMemB(ES, di, v1);
\r
1878 OverVal = CarryVal;
\r
1879 icount -= 7 + 19 * count;
\r
1882 case 0x22: /* 0F 22 59 - sub4s */
\r
1884 int count = (regs.b[CL] + 1) / 2;
\r
1885 unsigned di = regs.w[DI];
\r
1886 unsigned si = regs.w[SI];
\r
1889 CarryVal = 0; /* NOT ADC */
\r
1890 for(int i = 0; i < count; i++) {
\r
1891 tmp = GetMemB(ES, di);
\r
1892 tmp2 = GetMemB(DS, si);
\r
1893 int v1 = (tmp >> 4) * 10 + (tmp & 0xf);
\r
1894 int v2 = (tmp2 >> 4) * 10 + (tmp2 & 0xf), result;
\r
1895 if(v1 < (v2 + CarryVal)) {
\r
1897 result = v1 - (v2 + CarryVal);
\r
1900 result = v1 - (v2 + CarryVal);
\r
1903 v1 = ((result / 10) << 4) | (result % 10);
\r
1904 PutMemB(ES, di, v1);
\r
1911 OverVal = CarryVal;
\r
1912 icount -= 7 + 19 * count;
\r
1918 case 0x26: /* 0F 22 59 - cmp4s */
\r
1920 int count = (regs.b[CL] + 1) / 2;
\r
1921 unsigned di = regs.w[DI];
\r
1922 unsigned si = regs.w[SI];
\r
1925 CarryVal = 0; /* NOT ADC */
\r
1926 for(int i = 0; i < count; i++) {
\r
1927 tmp = GetMemB(ES, di);
\r
1928 tmp2 = GetMemB(DS, si);
\r
1929 int v1 = (tmp >> 4) * 10 + (tmp & 0xf);
\r
1930 int v2 = (tmp2 >> 4) * 10 + (tmp2 & 0xf), result;
\r
1931 if(v1 < (v2 + CarryVal)) {
\r
1933 result = v1 - (v2 + CarryVal);
\r
1936 result = v1 - (v2 + CarryVal);
\r
1939 v1 = ((result / 10) << 4) | (result % 10);
\r
1940 /* PutMemB(ES, di, v1); /* no store, only compare */
\r
1947 OverVal = CarryVal;
\r
1948 icount -= 7 + 19 * (regs.b[CL] + 1);
\r
1951 case 0x28: /* 0F 28 C7 - ROL4 bh */
\r
1953 if(ModRM >= 0xc0) {
\r
1954 tmp = regs.b[Mod_RM.RM.b[ModRM]];
\r
1959 tmp = ReadByte(ea);
\r
1960 icount = old - 28;
\r
1963 tmp |= regs.b[AL] & 0xf;
\r
1964 regs.b[AL] = (regs.b[AL] & 0xf0) | ((tmp >> 8) & 0xf);
\r
1966 PutbackRMByte(ModRM, tmp);
\r
1968 case 0x29: /* 0F 29 C7 - ROL4 bx */
\r
1971 case 0x2A: /* 0F 2a c2 - ROR4 bh */
\r
1973 if(ModRM >= 0xc0) {
\r
1974 tmp = regs.b[Mod_RM.RM.b[ModRM]];
\r
1979 tmp = ReadByte(ea);
\r
1980 icount = old - 33;
\r
1982 tmp2 = (regs.b[AL] & 0xf) << 4;
\r
1983 regs.b[AL] = (regs.b[AL] & 0xf0) | (tmp & 0xf);
\r
1984 tmp = tmp2 | (tmp >> 4);
\r
1985 PutbackRMByte(ModRM, tmp);
\r
1987 case 0x2B: /* 0F 2b c2 - ROR4 bx */
\r
1990 case 0x2D: /* 0Fh 2Dh < 1111 1RRR> */
\r
1994 case 0x31: /* 0F 31 [mod:reg:r/m] - INS reg8, reg8 or INS reg8, imm4 */
\r
1996 if(ModRM >= 0xc0) {
\r
1997 tmp = regs.b[Mod_RM.RM.b[ModRM]];
\r
2002 tmp = ReadByte(ea);
\r
2003 icount = old - 33;
\r
2006 case 0x33: /* 0F 33 [mod:reg:r/m] - EXT reg8, reg8 or EXT reg8, imm4 */
\r
2008 if(ModRM >= 0xc0) {
\r
2009 tmp = regs.b[Mod_RM.RM.b[ModRM]];
\r
2014 tmp = ReadByte(ea);
\r
2015 icount = old - 33;
\r
2040 case 0xff: /* 0F ff imm8 - BRKEM */
\r
2049 inline void I86::_adc_br8() /* Opcode 0x10 */
\r
2051 DEF_br8(dst, src);
\r
2052 icount -= (ModRM >= 0xc0) ? timing.alu_rr8 : timing.alu_mr8;
\r
2055 PutbackRMByte(ModRM, dst);
\r
2058 inline void I86::_adc_wr16() /* Opcode 0x11 */
\r
2060 DEF_wr16(dst, src);
\r
2061 icount -= (ModRM >= 0xc0) ? timing.alu_rr16 : timing.alu_mr16;
\r
2064 PutbackRMWord(ModRM, dst);
\r
2067 inline void I86::_adc_r8b() /* Opcode 0x12 */
\r
2069 DEF_r8b(dst, src);
\r
2070 icount -= (ModRM >= 0xc0) ? timing.alu_rr8 : timing.alu_rm8;
\r
2073 RegByte(ModRM) = dst;
\r
2076 inline void I86::_adc_r16w() /* Opcode 0x13 */
\r
2078 DEF_r16w(dst, src);
\r
2079 icount -= (ModRM >= 0xc0) ? timing.alu_rr16 : timing.alu_rm16;
\r
2082 RegWord(ModRM) = dst;
\r
2085 inline void I86::_adc_ald8() /* Opcode 0x14 */
\r
2087 DEF_ald8(dst, src);
\r
2088 icount -= timing.alu_ri8;
\r
2094 inline void I86::_adc_axd16() /* Opcode 0x15 */
\r
2096 DEF_axd16(dst, src);
\r
2097 icount -= timing.alu_ri16;
\r
2103 inline void I86::_push_ss() /* Opcode 0x16 */
\r
2106 icount -= timing.push_seg;
\r
2109 inline void I86::_pop_ss() /* Opcode 0x17 */
\r
2112 base[SS] = SegBase(SS);
\r
2113 icount -= timing.pop_seg;
\r
2114 instruction(FETCHOP); /* no interrupt before next instruction */
\r
2117 inline void I86::_sbb_br8() /* Opcode 0x18 */
\r
2119 DEF_br8(dst, src);
\r
2120 icount -= (ModRM >= 0xc0) ? timing.alu_rr8 : timing.alu_mr8;
\r
2123 PutbackRMByte(ModRM, dst);
\r
2126 inline void I86::_sbb_wr16() /* Opcode 0x19 */
\r
2128 DEF_wr16(dst, src);
\r
2129 icount -= (ModRM >= 0xc0) ? timing.alu_rr16 : timing.alu_mr16;
\r
2132 PutbackRMWord(ModRM, dst);
\r
2135 inline void I86::_sbb_r8b() /* Opcode 0x1a */
\r
2137 DEF_r8b(dst, src);
\r
2138 icount -= (ModRM >= 0xc0) ? timing.alu_rr8 : timing.alu_rm8;
\r
2141 RegByte(ModRM) = dst;
\r
2144 inline void I86::_sbb_r16w() /* Opcode 0x1b */
\r
2146 DEF_r16w(dst, src);
\r
2147 icount -= (ModRM >= 0xc0) ? timing.alu_rr16 : timing.alu_rm16;
\r
2150 RegWord(ModRM) = dst;
\r
2153 inline void I86::_sbb_ald8() /* Opcode 0x1c */
\r
2155 DEF_ald8(dst, src);
\r
2156 icount -= timing.alu_ri8;
\r
2162 inline void I86::_sbb_axd16() /* Opcode 0x1d */
\r
2164 DEF_axd16(dst, src);
\r
2165 icount -= timing.alu_ri16;
\r
2171 inline void I86::_push_ds() /* Opcode 0x1e */
\r
2174 icount -= timing.push_seg;
\r
2177 inline void I86::_pop_ds() /* Opcode 0x1f */
\r
2180 base[DS] = SegBase(DS);
\r
2181 icount -= timing.push_seg;
\r
2184 inline void I86::_and_br8() /* Opcode 0x20 */
\r
2186 DEF_br8(dst, src);
\r
2187 icount -= (ModRM >= 0xc0) ? timing.alu_rr8 : timing.alu_mr8;
\r
2189 PutbackRMByte(ModRM, dst);
\r
2192 inline void I86::_and_wr16() /* Opcode 0x21 */
\r
2194 DEF_wr16(dst, src);
\r
2195 icount -= (ModRM >= 0xc0) ? timing.alu_rr16 : timing.alu_mr16;
\r
2197 PutbackRMWord(ModRM, dst);
\r
2200 inline void I86::_and_r8b() /* Opcode 0x22 */
\r
2202 DEF_r8b(dst, src);
\r
2203 icount -= (ModRM >= 0xc0) ? timing.alu_rr8 : timing.alu_rm8;
\r
2205 RegByte(ModRM) = dst;
\r
2208 inline void I86::_and_r16w() /* Opcode 0x23 */
\r
2210 DEF_r16w(dst, src);
\r
2211 icount -= (ModRM >= 0xc0) ? timing.alu_rr16 : timing.alu_rm16;
\r
2213 RegWord(ModRM) = dst;
\r
2216 inline void I86::_and_ald8() /* Opcode 0x24 */
\r
2218 DEF_ald8(dst, src);
\r
2219 icount -= timing.alu_ri8;
\r
2224 inline void I86::_and_axd16() /* Opcode 0x25 */
\r
2226 DEF_axd16(dst, src);
\r
2227 icount -= timing.alu_ri16;
\r
2232 inline void I86::_es() /* Opcode 0x26 */
\r
2234 seg_prefix = true;
\r
2236 icount -= timing.override;
\r
2237 instruction(FETCHOP);
\r
2240 inline void I86::_daa() /* Opcode 0x27 */
\r
2242 if(AF || ((regs.b[AL] & 0xf) > 9)) {
\r
2244 regs.b[AL] = tmp = regs.b[AL] + 6;
\r
2246 CarryVal |= tmp & 0x100;
\r
2249 if(CF || (regs.b[AL] > 0x9f)) {
\r
2250 regs.b[AL] += 0x60;
\r
2254 SetSZPF_Byte(regs.b[AL]);
\r
2255 icount -= timing.daa;
\r
2258 inline void I86::_sub_br8() /* Opcode 0x28 */
\r
2260 DEF_br8(dst, src);
\r
2261 icount -= (ModRM >= 0xc0) ? timing.alu_rr8 : timing.alu_mr8;
\r
2263 PutbackRMByte(ModRM, dst);
\r
2266 inline void I86::_sub_wr16() /* Opcode 0x29 */
\r
2268 DEF_wr16(dst, src);
\r
2269 icount -= (ModRM >= 0xc0) ? timing.alu_rr16 : timing.alu_mr16;
\r
2271 PutbackRMWord(ModRM, dst);
\r
2274 inline void I86::_sub_r8b() /* Opcode 0x2a */
\r
2276 DEF_r8b(dst, src);
\r
2277 icount -= (ModRM >= 0xc0) ? timing.alu_rr8 : timing.alu_rm8;
\r
2279 RegByte(ModRM) = dst;
\r
2282 inline void I86::_sub_r16w() /* Opcode 0x2b */
\r
2284 DEF_r16w(dst, src);
\r
2285 icount -= (ModRM >= 0xc0) ? timing.alu_rr16 : timing.alu_rm16;
\r
2287 RegWord(ModRM) = dst;
\r
2290 inline void I86::_sub_ald8() /* Opcode 0x2c */
\r
2292 DEF_ald8(dst, src);
\r
2293 icount -= timing.alu_ri8;
\r
2298 inline void I86::_sub_axd16() /* Opcode 0x2d */
\r
2300 DEF_axd16(dst, src);
\r
2301 icount -= timing.alu_ri16;
\r
2306 inline void I86::_cs() /* Opcode 0x2e */
\r
2308 seg_prefix = true;
\r
2310 icount -= timing.override;
\r
2311 instruction(FETCHOP);
\r
2314 inline void I86::_das() /* Opcode 0x2f */
\r
2316 uint8 tmpAL = regs.b[AL];
\r
2317 if(AF || ((regs.b[AL] & 0xf) > 9)) {
\r
2319 regs.b[AL] = tmp = regs.b[AL] - 6;
\r
2321 CarryVal |= tmp & 0x100;
\r
2324 if(CF || (tmpAL > 0x9f)) {
\r
2325 regs.b[AL] -= 0x60;
\r
2329 SetSZPF_Byte(regs.b[AL]);
\r
2330 icount -= timing.das;
\r
2333 inline void I86::_xor_br8() /* Opcode 0x30 */
\r
2335 DEF_br8(dst, src);
\r
2336 icount -= (ModRM >= 0xc0) ? timing.alu_rr8 : timing.alu_mr8;
\r
2338 PutbackRMByte(ModRM, dst);
\r
2341 inline void I86::_xor_wr16() /* Opcode 0x31 */
\r
2343 DEF_wr16(dst, src);
\r
2344 icount -= (ModRM >= 0xc0) ? timing.alu_rr16 : timing.alu_mr16;
\r
2346 PutbackRMWord(ModRM, dst);
\r
2349 inline void I86::_xor_r8b() /* Opcode 0x32 */
\r
2351 DEF_r8b(dst, src);
\r
2352 icount -= (ModRM >= 0xc0) ? timing.alu_rr8 : timing.alu_rm8;
\r
2354 RegByte(ModRM) = dst;
\r
2357 inline void I86::_xor_r16w() /* Opcode 0x33 */
\r
2359 DEF_r16w(dst, src);
\r
2360 icount -= (ModRM >= 0xc0) ? timing.alu_rr16 : timing.alu_rm16;
\r
2362 RegWord(ModRM) = dst;
\r
2365 inline void I86::_xor_ald8() /* Opcode 0x34 */
\r
2367 DEF_ald8(dst, src);
\r
2368 icount -= timing.alu_ri8;
\r
2373 inline void I86::_xor_axd16() /* Opcode 0x35 */
\r
2375 DEF_axd16(dst, src);
\r
2376 icount -= timing.alu_ri16;
\r
2381 inline void I86::_ss() /* Opcode 0x36 */
\r
2383 seg_prefix = true;
\r
2385 icount -= timing.override;
\r
2386 instruction(FETCHOP);
\r
2389 inline void I86::_aaa() /* Opcode 0x37 */
\r
2391 uint8 ALcarry = 1;
\r
2392 if(regs.b[AL]>0xf9) {
\r
2395 if(AF || ((regs.b[AL] & 0xf) > 9)) {
\r
2397 regs.b[AH] += ALcarry;
\r
2404 regs.b[AL] &= 0x0F;
\r
2405 icount -= timing.aaa;
\r
2408 inline void I86::_cmp_br8() /* Opcode 0x38 */
\r
2410 DEF_br8(dst, src);
\r
2411 icount -= (ModRM >= 0xc0) ? timing.alu_rr8 : timing.alu_rm8;
\r
2415 inline void I86::_cmp_wr16() /* Opcode 0x39 */
\r
2417 DEF_wr16(dst, src);
\r
2418 icount -= (ModRM >= 0xc0) ? timing.alu_rr16 : timing.alu_rm16;
\r
2422 inline void I86::_cmp_r8b() /* Opcode 0x3a */
\r
2424 DEF_r8b(dst, src);
\r
2425 icount -= (ModRM >= 0xc0) ? timing.alu_rr8 : timing.alu_rm8;
\r
2429 inline void I86::_cmp_r16w() /* Opcode 0x3b */
\r
2431 DEF_r16w(dst, src);
\r
2432 icount -= (ModRM >= 0xc0) ? timing.alu_rr16 : timing.alu_rm16;
\r
2436 inline void I86::_cmp_ald8() /* Opcode 0x3c */
\r
2438 DEF_ald8(dst, src);
\r
2439 icount -= timing.alu_ri8;
\r
2443 inline void I86::_cmp_axd16() /* Opcode 0x3d */
\r
2445 DEF_axd16(dst, src);
\r
2446 icount -= timing.alu_ri16;
\r
2450 inline void I86::_ds() /* Opcode 0x3e */
\r
2452 seg_prefix = true;
\r
2454 icount -= timing.override;
\r
2455 instruction(FETCHOP);
\r
2458 inline void I86::_aas() /* Opcode 0x3f */
\r
2460 uint8 ALcarry = 1;
\r
2461 if(regs.b[AL] > 0xf9) {
\r
2464 if(AF || ((regs.b[AL] & 0xf) > 9)) {
\r
2473 regs.b[AL] &= 0x0F;
\r
2474 icount -= timing.aas;
\r
2477 #define IncWordReg(Reg) { \
\r
2478 unsigned tmp = (unsigned)regs.w[Reg]; \
\r
2479 unsigned tmp1 = tmp + 1; \
\r
2480 SetOFW_Add(tmp1, tmp, 1); \
\r
2481 SetAF(tmp1, tmp, 1); \
\r
2482 SetSZPF_Word(tmp1); \
\r
2483 regs.w[Reg] = tmp1; \
\r
2484 icount -= timing.incdec_r16; \
\r
2487 inline void I86::_inc_ax() /* Opcode 0x40 */
\r
2492 inline void I86::_inc_cx() /* Opcode 0x41 */
\r
2497 inline void I86::_inc_dx() /* Opcode 0x42 */
\r
2502 inline void I86::_inc_bx() /* Opcode 0x43 */
\r
2507 inline void I86::_inc_sp() /* Opcode 0x44 */
\r
2512 inline void I86::_inc_bp() /* Opcode 0x45 */
\r
2517 inline void I86::_inc_si() /* Opcode 0x46 */
\r
2522 inline void I86::_inc_di() /* Opcode 0x47 */
\r
2527 #define DecWordReg(Reg) { \
\r
2528 unsigned tmp = (unsigned)regs.w[Reg]; \
\r
2529 unsigned tmp1 = tmp - 1; \
\r
2530 SetOFW_Sub(tmp1, 1, tmp); \
\r
2531 SetAF(tmp1, tmp, 1); \
\r
2532 SetSZPF_Word(tmp1); \
\r
2533 regs.w[Reg] = tmp1; \
\r
2534 icount -= timing.incdec_r16; \
\r
2537 inline void I86::_dec_ax() /* Opcode 0x48 */
\r
2542 inline void I86::_dec_cx() /* Opcode 0x49 */
\r
2547 inline void I86::_dec_dx() /* Opcode 0x4a */
\r
2552 inline void I86::_dec_bx() /* Opcode 0x4b */
\r
2557 inline void I86::_dec_sp() /* Opcode 0x4c */
\r
2562 inline void I86::_dec_bp() /* Opcode 0x4d */
\r
2567 inline void I86::_dec_si() /* Opcode 0x4e */
\r
2572 inline void I86::_dec_di() /* Opcode 0x4f */
\r
2577 inline void I86::_push_ax() /* Opcode 0x50 */
\r
2579 icount -= timing.push_r16;
\r
2583 inline void I86::_push_cx() /* Opcode 0x51 */
\r
2585 icount -= timing.push_r16;
\r
2589 inline void I86::_push_dx() /* Opcode 0x52 */
\r
2591 icount -= timing.push_r16;
\r
2595 inline void I86::_push_bx() /* Opcode 0x53 */
\r
2597 icount -= timing.push_r16;
\r
2601 inline void I86::_push_sp() /* Opcode 0x54 */
\r
2603 unsigned tmp = regs.w[SP];
\r
2605 icount -= timing.push_r16;
\r
2609 inline void I86::_push_bp() /* Opcode 0x55 */
\r
2611 icount -= timing.push_r16;
\r
2615 inline void I86::_push_si() /* Opcode 0x56 */
\r
2617 icount -= timing.push_r16;
\r
2621 inline void I86::_push_di() /* Opcode 0x57 */
\r
2623 icount -= timing.push_r16;
\r
2627 inline void I86::_pop_ax() /* Opcode 0x58 */
\r
2629 icount -= timing.pop_r16;
\r
2633 inline void I86::_pop_cx() /* Opcode 0x59 */
\r
2635 icount -= timing.pop_r16;
\r
2639 inline void I86::_pop_dx() /* Opcode 0x5a */
\r
2641 icount -= timing.pop_r16;
\r
2645 inline void I86::_pop_bx() /* Opcode 0x5b */
\r
2647 icount -= timing.pop_r16;
\r
2651 inline void I86::_pop_sp() /* Opcode 0x5c */
\r
2655 icount -= timing.pop_r16;
\r
2660 inline void I86::_pop_bp() /* Opcode 0x5d */
\r
2662 icount -= timing.pop_r16;
\r
2666 inline void I86::_pop_si() /* Opcode 0x5e */
\r
2668 icount -= timing.pop_r16;
\r
2672 inline void I86::_pop_di() /* Opcode 0x5f */
\r
2674 icount -= timing.pop_r16;
\r
2678 inline void I86::_pusha() /* Opcode 0x60 */
\r
2680 unsigned tmp = regs.w[SP];
\r
2682 icount -= timing.pusha;
\r
2693 inline void I86::_popa() /* Opcode 0x61 */
\r
2697 icount -= timing.popa;
\r
2708 inline void I86::_bound() /* Opcode 0x62 */
\r
2710 unsigned ModRM = FETCHOP;
\r
2711 int low = (int16)GetRMWord(ModRM);
\r
2712 int high = (int16)GetNextRMWord;
\r
2713 int tmp = (int16)RegWord(ModRM);
\r
2714 if(tmp < low || tmp>high) {
\r
2715 pc -= (seg_prefix ? 3 : 2);
\r
2716 interrupt(BOUNDS_CHECK_FAULT);
\r
2718 icount -= timing.bound;
\r
2721 inline void I86::_repc(int flagval)
\r
2724 unsigned next = FETCHOP;
\r
2725 unsigned count = regs.w[CX];
\r
2728 case 0x26: /* ES: */
\r
2729 seg_prefix = true;
\r
2734 case 0x2e: /* CS: */
\r
2735 seg_prefix = true;
\r
2740 case 0x36: /* SS: */
\r
2741 seg_prefix = true;
\r
2746 case 0x3e: /* DS: */
\r
2747 seg_prefix = true;
\r
2752 case 0x6c: /* REP INSB */
\r
2753 icount -= 9 - count;
\r
2754 for(; (CF == flagval) && (count > 0); count--) {
\r
2757 regs.w[CX] = count;
\r
2759 case 0x6d: /* REP INSW */
\r
2760 icount -= 9 - count;
\r
2761 for(; (CF == flagval) && (count > 0); count--) {
\r
2764 regs.w[CX] = count;
\r
2766 case 0x6e: /* REP OUTSB */
\r
2767 icount -= 9 - count;
\r
2768 for(; (CF == flagval) && (count > 0); count--) {
\r
2771 regs.w[CX] = count;
\r
2773 case 0x6f: /* REP OUTSW */
\r
2774 icount -= 9 - count;
\r
2775 for(; (CF == flagval) && (count > 0); count--) {
\r
2778 regs.w[CX] = count;
\r
2780 case 0xa4: /* REP MOVSB */
\r
2781 icount -= 9 - count;
\r
2782 for(; (CF == flagval) && (count > 0); count--) {
\r
2785 regs.w[CX] = count;
\r
2787 case 0xa5: /* REP MOVSW */
\r
2788 icount -= 9 - count;
\r
2789 for(; (CF == flagval) && (count > 0); count--) {
\r
2792 regs.w[CX] = count;
\r
2794 case 0xa6: /* REP(N)E CMPSB */
\r
2796 for(ZeroVal = !flagval; (ZF == flagval) && (CF == flagval) && (count > 0); count--) {
\r
2799 regs.w[CX] = count;
\r
2801 case 0xa7: /* REP(N)E CMPSW */
\r
2803 for(ZeroVal = !flagval; (ZF == flagval) && (CF == flagval) && (count > 0); count--) {
\r
2806 regs.w[CX] = count;
\r
2808 case 0xaa: /* REP STOSB */
\r
2809 icount -= 9 - count;
\r
2810 for(; (CF == flagval) && (count > 0); count--) {
\r
2813 regs.w[CX] = count;
\r
2815 case 0xab: /* REP STOSW */
\r
2816 icount -= 9 - count;
\r
2817 for(; (CF == flagval) && (count > 0); count--) {
\r
2820 regs.w[CX] = count;
\r
2822 case 0xac: /* REP LODSB */
\r
2824 for(; (CF == flagval) && (count > 0); count--) {
\r
2827 regs.w[CX] = count;
\r
2829 case 0xad: /* REP LODSW */
\r
2831 for(; (CF == flagval) && (count > 0); count--) {
\r
2834 regs.w[CX] = count;
\r
2836 case 0xae: /* REP(N)E SCASB */
\r
2838 for(ZeroVal = !flagval; (ZF == flagval) && (CF == flagval) && (count > 0); count--) {
\r
2841 regs.w[CX] = count;
\r
2843 case 0xaf: /* REP(N)E SCASW */
\r
2845 for(ZeroVal = !flagval; (ZF == flagval) && (CF == flagval) && (count > 0); count--) {
\r
2848 regs.w[CX] = count;
\r
2851 instruction(next);
\r
2856 inline void I86::_push_d16() /* Opcode 0x68 */
\r
2858 unsigned tmp = FETCH;
\r
2859 icount -= timing.push_imm;
\r
2860 tmp += FETCH << 8;
\r
2864 inline void I86::_imul_d16() /* Opcode 0x69 */
\r
2866 DEF_r16w(dst, src);
\r
2867 unsigned src2 = FETCH;
\r
2868 src += (FETCH << 8);
\r
2869 icount -= (ModRM >= 0xc0) ? timing.imul_rri16 : timing.imul_rmi16;
\r
2870 dst = (int32)((int16)src) * (int32)((int16)src2);
\r
2871 CarryVal = OverVal = (((int32)dst) >> 15 != 0) && (((int32)dst) >> 15 != -1);
\r
2872 RegWord(ModRM) = (uint16)dst;
\r
2875 inline void I86::_push_d8() /* Opcode 0x6a */
\r
2877 unsigned tmp = (uint16)((int16)((int8)FETCH));
\r
2878 icount -= timing.push_imm;
\r
2882 inline void I86::_imul_d8() /* Opcode 0x6b */
\r
2884 DEF_r16w(dst, src);
\r
2885 unsigned src2 = (uint16)((int16)((int8)FETCH));
\r
2886 icount -= (ModRM >= 0xc0) ? timing.imul_rri8 : timing.imul_rmi8;
\r
2887 dst = (int32)((int16)src) * (int32)((int16)src2);
\r
2888 CarryVal = OverVal = (((int32)dst) >> 15 != 0) && (((int32)dst) >> 15 != -1);
\r
2889 RegWord(ModRM) = (uint16)dst;
\r
2892 inline void I86::_insb() /* Opcode 0x6c */
\r
2894 icount -= timing.ins8;
\r
2895 PutMemB(ES, regs.w[DI], read_port_byte(regs.w[DX]));
\r
2896 regs.w[DI] += DirVal;
\r
2899 inline void I86::_insw() /* Opcode 0x6d */
\r
2901 icount -= timing.ins16;
\r
2902 PutMemW(ES, regs.w[DI], read_port_word(regs.w[DX]));
\r
2903 regs.w[DI] += 2 * DirVal;
\r
2906 inline void I86::_outsb() /* Opcode 0x6e */
\r
2908 icount -= timing.outs8;
\r
2909 write_port_byte(regs.w[DX], GetMemB(DS, regs.w[SI]));
\r
2910 regs.w[SI] += DirVal; /* GOL 11/27/01 */
\r
2913 inline void I86::_outsw() /* Opcode 0x6f */
\r
2915 icount -= timing.outs16;
\r
2916 write_port_word(regs.w[DX], GetMemW(DS, regs.w[SI]));
\r
2917 regs.w[SI] += 2 * DirVal; /* GOL 11/27/01 */
\r
2920 inline void I86::_jo() /* Opcode 0x70 */
\r
2922 int tmp = (int)((int8)FETCH);
\r
2925 icount -= timing.jcc_t;
\r
2927 icount -= timing.jcc_nt;
\r
2931 inline void I86::_jno() /* Opcode 0x71 */
\r
2933 int tmp = (int)((int8)FETCH);
\r
2936 icount -= timing.jcc_t;
\r
2938 icount -= timing.jcc_nt;
\r
2942 inline void I86::_jb() /* Opcode 0x72 */
\r
2944 int tmp = (int)((int8)FETCH);
\r
2947 icount -= timing.jcc_t;
\r
2949 icount -= timing.jcc_nt;
\r
2953 inline void I86::_jnb() /* Opcode 0x73 */
\r
2955 int tmp = (int)((int8)FETCH);
\r
2958 icount -= timing.jcc_t;
\r
2960 icount -= timing.jcc_nt;
\r
2964 inline void I86::_jz() /* Opcode 0x74 */
\r
2966 int tmp = (int)((int8)FETCH);
\r
2969 icount -= timing.jcc_t;
\r
2971 icount -= timing.jcc_nt;
\r
2975 inline void I86::_jnz() /* Opcode 0x75 */
\r
2977 int tmp = (int)((int8)FETCH);
\r
2980 icount -= timing.jcc_t;
\r
2982 icount -= timing.jcc_nt;
\r
2986 inline void I86::_jbe() /* Opcode 0x76 */
\r
2988 int tmp = (int)((int8)FETCH);
\r
2991 icount -= timing.jcc_t;
\r
2993 icount -= timing.jcc_nt;
\r
2997 inline void I86::_jnbe() /* Opcode 0x77 */
\r
2999 int tmp = (int)((int8)FETCH);
\r
3002 icount -= timing.jcc_t;
\r
3004 icount -= timing.jcc_nt;
\r
3008 inline void I86::_js() /* Opcode 0x78 */
\r
3010 int tmp = (int)((int8)FETCH);
\r
3013 icount -= timing.jcc_t;
\r
3015 icount -= timing.jcc_nt;
\r
3019 inline void I86::_jns() /* Opcode 0x79 */
\r
3021 int tmp = (int)((int8)FETCH);
\r
3024 icount -= timing.jcc_t;
\r
3026 icount -= timing.jcc_nt;
\r
3030 inline void I86::_jp() /* Opcode 0x7a */
\r
3032 int tmp = (int)((int8)FETCH);
\r
3035 icount -= timing.jcc_t;
\r
3037 icount -= timing.jcc_nt;
\r
3041 inline void I86::_jnp() /* Opcode 0x7b */
\r
3043 int tmp = (int)((int8)FETCH);
\r
3046 icount -= timing.jcc_t;
\r
3048 icount -= timing.jcc_nt;
\r
3052 inline void I86::_jl() /* Opcode 0x7c */
\r
3054 int tmp = (int)((int8)FETCH);
\r
3055 if((SF!= OF) && !ZF) {
\r
3057 icount -= timing.jcc_t;
\r
3059 icount -= timing.jcc_nt;
\r
3063 inline void I86::_jnl() /* Opcode 0x7d */
\r
3065 int tmp = (int)((int8)FETCH);
\r
3066 if(ZF || (SF == OF)) {
\r
3068 icount -= timing.jcc_t;
\r
3070 icount -= timing.jcc_nt;
\r
3074 inline void I86::_jle() /* Opcode 0x7e */
\r
3076 int tmp = (int)((int8)FETCH);
\r
3077 if(ZF || (SF!= OF)) {
\r
3079 icount -= timing.jcc_t;
\r
3081 icount -= timing.jcc_nt;
\r
3085 inline void I86::_jnle() /* Opcode 0x7f */
\r
3087 int tmp = (int)((int8)FETCH);
\r
3088 if((SF == OF) && !ZF) {
\r
3090 icount -= timing.jcc_t;
\r
3092 icount -= timing.jcc_nt;
\r
3096 inline void I86::_80pre() /* Opcode 0x80 */
\r
3098 unsigned ModRM = FETCHOP;
\r
3099 unsigned dst = GetRMByte(ModRM);
\r
3100 unsigned src = FETCH;
\r
3102 switch((ModRM >> 3) & 7) {
\r
3103 case 0: /* ADD eb, d8 */
\r
3105 PutbackRMByte(ModRM, dst);
\r
3106 icount -= (ModRM >= 0xc0) ? timing.alu_ri8 : timing.alu_mi8;
\r
3108 case 1: /* OR eb, d8 */
\r
3110 PutbackRMByte(ModRM, dst);
\r
3111 icount -= (ModRM >= 0xc0) ? timing.alu_ri8 : timing.alu_mi8;
\r
3113 case 2: /* ADC eb, d8 */
\r
3116 PutbackRMByte(ModRM, dst);
\r
3117 icount -= (ModRM >= 0xc0) ? timing.alu_ri8 : timing.alu_mi8;
\r
3119 case 3: /* SBB eb, b8 */
\r
3122 PutbackRMByte(ModRM, dst);
\r
3123 icount -= (ModRM >= 0xc0) ? timing.alu_ri8 : timing.alu_mi8;
\r
3125 case 4: /* AND eb, d8 */
\r
3127 PutbackRMByte(ModRM, dst);
\r
3128 icount -= (ModRM >= 0xc0) ? timing.alu_ri8 : timing.alu_mi8;
\r
3130 case 5: /* SUB eb, d8 */
\r
3132 PutbackRMByte(ModRM, dst);
\r
3133 icount -= (ModRM >= 0xc0) ? timing.alu_ri8 : timing.alu_mi8;
\r
3135 case 6: /* XOR eb, d8 */
\r
3137 PutbackRMByte(ModRM, dst);
\r
3138 icount -= (ModRM >= 0xc0) ? timing.alu_ri8 : timing.alu_mi8;
\r
3140 case 7: /* CMP eb, d8 */
\r
3142 icount -= (ModRM >= 0xc0) ? timing.alu_ri8 : timing.alu_mi8_ro;
\r
3150 inline void I86::_81pre() /* Opcode 0x81 */
\r
3152 unsigned ModRM = FETCH;
\r
3153 unsigned dst = GetRMWord(ModRM);
\r
3154 unsigned src = FETCH;
\r
3155 src += (FETCH << 8);
\r
3157 switch((ModRM >> 3) & 7) {
\r
3158 case 0: /* ADD ew, d16 */
\r
3160 PutbackRMWord(ModRM, dst);
\r
3161 icount -= (ModRM >= 0xc0) ? timing.alu_ri16 : timing.alu_mi16;
\r
3163 case 1: /* OR ew, d16 */
\r
3165 PutbackRMWord(ModRM, dst);
\r
3166 icount -= (ModRM >= 0xc0) ? timing.alu_ri16 : timing.alu_mi16;
\r
3168 case 2: /* ADC ew, d16 */
\r
3171 PutbackRMWord(ModRM, dst);
\r
3172 icount -= (ModRM >= 0xc0) ? timing.alu_ri16 : timing.alu_mi16;
\r
3174 case 3: /* SBB ew, d16 */
\r
3177 PutbackRMWord(ModRM, dst);
\r
3178 icount -= (ModRM >= 0xc0) ? timing.alu_ri16 : timing.alu_mi16;
\r
3180 case 4: /* AND ew, d16 */
\r
3182 PutbackRMWord(ModRM, dst);
\r
3183 icount -= (ModRM >= 0xc0) ? timing.alu_ri16 : timing.alu_mi16;
\r
3185 case 5: /* SUB ew, d16 */
\r
3187 PutbackRMWord(ModRM, dst);
\r
3188 icount -= (ModRM >= 0xc0) ? timing.alu_ri16 : timing.alu_mi16;
\r
3190 case 6: /* XOR ew, d16 */
\r
3192 PutbackRMWord(ModRM, dst);
\r
3193 icount -= (ModRM >= 0xc0) ? timing.alu_ri16 : timing.alu_mi16;
\r
3195 case 7: /* CMP ew, d16 */
\r
3197 icount -= (ModRM >= 0xc0) ? timing.alu_ri16 : timing.alu_mi16_ro;
\r
3205 inline void I86::_82pre() /* Opcode 0x82 */
\r
3207 unsigned ModRM = FETCH;
\r
3208 unsigned dst = GetRMByte(ModRM);
\r
3209 unsigned src = FETCH;
\r
3211 switch((ModRM >> 3) & 7) {
\r
3212 case 0: /* ADD eb, d8 */
\r
3214 PutbackRMByte(ModRM, dst);
\r
3215 icount -= (ModRM >= 0xc0) ? timing.alu_ri8 : timing.alu_mi8;
\r
3217 case 1: /* OR eb, d8 */
\r
3219 PutbackRMByte(ModRM, dst);
\r
3220 icount -= (ModRM >= 0xc0) ? timing.alu_ri8 : timing.alu_mi8;
\r
3222 case 2: /* ADC eb, d8 */
\r
3225 PutbackRMByte(ModRM, dst);
\r
3226 icount -= (ModRM >= 0xc0) ? timing.alu_ri8 : timing.alu_mi8;
\r
3228 case 3: /* SBB eb, d8 */
\r
3231 PutbackRMByte(ModRM, dst);
\r
3232 icount -= (ModRM >= 0xc0) ? timing.alu_ri8 : timing.alu_mi8;
\r
3234 case 4: /* AND eb, d8 */
\r
3236 PutbackRMByte(ModRM, dst);
\r
3237 icount -= (ModRM >= 0xc0) ? timing.alu_ri8 : timing.alu_mi8;
\r
3239 case 5: /* SUB eb, d8 */
\r
3241 PutbackRMByte(ModRM, dst);
\r
3242 icount -= (ModRM >= 0xc0) ? timing.alu_ri8 : timing.alu_mi8;
\r
3244 case 6: /* XOR eb, d8 */
\r
3246 PutbackRMByte(ModRM, dst);
\r
3247 icount -= (ModRM >= 0xc0) ? timing.alu_ri8 : timing.alu_mi8;
\r
3249 case 7: /* CMP eb, d8 */
\r
3251 icount -= (ModRM >= 0xc0) ? timing.alu_ri8 : timing.alu_mi8_ro;
\r
3259 inline void I86::_83pre() /* Opcode 0x83 */
\r
3261 unsigned ModRM = FETCH;
\r
3262 unsigned dst = GetRMWord(ModRM);
\r
3263 unsigned src = (uint16)((int16)((int8)FETCH));
\r
3265 switch((ModRM >> 3) & 7) {
\r
3266 case 0: /* ADD ew, d16 */
\r
3268 PutbackRMWord(ModRM, dst);
\r
3269 icount -= (ModRM >= 0xc0) ? timing.alu_r16i8 : timing.alu_m16i8;
\r
3271 case 1: /* OR ew, d16 */
\r
3273 PutbackRMWord(ModRM, dst);
\r
3274 icount -= (ModRM >= 0xc0) ? timing.alu_r16i8 : timing.alu_m16i8;
\r
3276 case 2: /* ADC ew, d16 */
\r
3279 PutbackRMWord(ModRM, dst);
\r
3280 icount -= (ModRM >= 0xc0) ? timing.alu_r16i8 : timing.alu_m16i8;
\r
3282 case 3: /* SBB ew, d16 */
\r
3285 PutbackRMWord(ModRM, dst);
\r
3286 icount -= (ModRM >= 0xc0) ? timing.alu_r16i8 : timing.alu_m16i8;
\r
3288 case 4: /* AND ew, d16 */
\r
3290 PutbackRMWord(ModRM, dst);
\r
3291 icount -= (ModRM >= 0xc0) ? timing.alu_r16i8 : timing.alu_m16i8;
\r
3293 case 5: /* SUB ew, d16 */
\r
3295 PutbackRMWord(ModRM, dst);
\r
3296 icount -= (ModRM >= 0xc0) ? timing.alu_r16i8 : timing.alu_m16i8;
\r
3298 case 6: /* XOR ew, d16 */
\r
3300 PutbackRMWord(ModRM, dst);
\r
3301 icount -= (ModRM >= 0xc0) ? timing.alu_r16i8 : timing.alu_m16i8;
\r
3303 case 7: /* CMP ew, d16 */
\r
3305 icount -= (ModRM >= 0xc0) ? timing.alu_r16i8 : timing.alu_m16i8_ro;
\r
3313 inline void I86::_test_br8() /* Opcode 0x84 */
\r
3315 DEF_br8(dst, src);
\r
3316 icount -= (ModRM >= 0xc0) ? timing.alu_rr8 : timing.alu_rm8;
\r
3320 inline void I86::_test_wr16() /* Opcode 0x85 */
\r
3322 DEF_wr16(dst, src);
\r
3323 icount -= (ModRM >= 0xc0) ? timing.alu_rr16 : timing.alu_rm16;
\r
3327 inline void I86::_xchg_br8() /* Opcode 0x86 */
\r
3329 DEF_br8(dst, src);
\r
3330 icount -= (ModRM >= 0xc0) ? timing.xchg_rr8 : timing.xchg_rm8;
\r
3331 RegByte(ModRM) = dst;
\r
3332 PutbackRMByte(ModRM, src);
\r
3335 inline void I86::_xchg_wr16() /* Opcode 0x87 */
\r
3337 DEF_wr16(dst, src);
\r
3338 icount -= (ModRM >= 0xc0) ? timing.xchg_rr16 : timing.xchg_rm16;
\r
3339 RegWord(ModRM) = dst;
\r
3340 PutbackRMWord(ModRM, src);
\r
3343 inline void I86::_mov_br8() /* Opcode 0x88 */
\r
3345 unsigned ModRM = FETCH;
\r
3346 uint8 src = RegByte(ModRM);
\r
3347 icount -= (ModRM >= 0xc0) ? timing.mov_rr8 : timing.mov_mr8;
\r
3348 PutRMByte(ModRM, src);
\r
3351 inline void I86::_mov_wr16() /* Opcode 0x89 */
\r
3353 unsigned ModRM = FETCH;
\r
3354 uint16 src = RegWord(ModRM);
\r
3355 icount -= (ModRM >= 0xc0) ? timing.mov_rr16 : timing.mov_mr16;
\r
3356 PutRMWord(ModRM, src);
\r
3359 inline void I86::_mov_r8b() /* Opcode 0x8a */
\r
3361 unsigned ModRM = FETCH;
\r
3362 uint8 src = GetRMByte(ModRM);
\r
3363 icount -= (ModRM >= 0xc0) ? timing.mov_rr8 : timing.mov_rm8;
\r
3364 RegByte(ModRM) = src;
\r
3367 inline void I86::_mov_r16w() /* Opcode 0x8b */
\r
3369 unsigned ModRM = FETCH;
\r
3370 uint16 src = GetRMWord(ModRM);
\r
3371 icount -= (ModRM >= 0xc0) ? timing.mov_rr8 : timing.mov_rm16;
\r
3372 RegWord(ModRM) = src;
\r
3375 inline void I86::_mov_wsreg() /* Opcode 0x8c */
\r
3377 unsigned ModRM = FETCH;
\r
3378 icount -= (ModRM >= 0xc0) ? timing.mov_rs : timing.mov_ms;
\r
3379 if(ModRM & 0x20) {
\r
3380 return; /* 1xx is invalid */
\r
3382 PutRMWord(ModRM, sregs[(ModRM & 0x38) >> 3]);
\r
3385 inline void I86::_lea() /* Opcode 0x8d */
\r
3387 unsigned ModRM = FETCH;
\r
3388 icount -= timing.lea;
\r
3390 RegWord(ModRM) = eo; /* effective offset (no segment part) */
\r
3393 inline void I86::_mov_sregw() /* Opcode 0x8e */
\r
3395 unsigned ModRM = FETCH;
\r
3396 uint16 src = GetRMWord(ModRM);
\r
3398 icount -= (ModRM >= 0xc0) ? timing.mov_sr : timing.mov_sm;
\r
3399 switch((ModRM >> 3) & 7) {
\r
3400 case 0: /* mov es, ew */
\r
3402 base[ES] = SegBase(ES);
\r
3404 case 1: /* mov cs, ew */
\r
3405 break; /* doesn't do a jump far */
\r
3406 case 2: /* mov ss, ew */
\r
3408 base[SS] = SegBase(SS); /* no interrupt allowed before next instr */
\r
3409 instruction(FETCHOP);
\r
3411 case 3: /* mov ds, ew */
\r
3413 base[DS] = SegBase(DS);
\r
3426 inline void I86::_popw() /* Opcode 0x8f */
\r
3428 unsigned ModRM = FETCH;
\r
3431 icount -= (ModRM >= 0xc0) ? timing.pop_r16 : timing.pop_m16;
\r
3432 PutRMWord(ModRM, tmp);
\r
3435 #define XchgAXReg(Reg) { \
\r
3437 tmp = regs.w[Reg]; \
\r
3438 regs.w[Reg] = regs.w[AX]; \
\r
3439 regs.w[AX] = tmp; \
\r
3440 icount -= timing.xchg_ar16; \
\r
3443 inline void I86::_nop() /* Opcode 0x90 */
\r
3445 /* this is XchgAXReg(AX); */
\r
3446 icount -= timing.nop;
\r
3449 inline void I86::_xchg_axcx() /* Opcode 0x91 */
\r
3454 inline void I86::_xchg_axdx() /* Opcode 0x92 */
\r
3459 inline void I86::_xchg_axbx() /* Opcode 0x93 */
\r
3464 inline void I86::_xchg_axsp() /* Opcode 0x94 */
\r
3469 inline void I86::_xchg_axbp() /* Opcode 0x95 */
\r
3474 inline void I86::_xchg_axsi() /* Opcode 0x96 */
\r
3479 inline void I86::_xchg_axdi() /* Opcode 0x97 */
\r
3484 inline void I86::_cbw() /* Opcode 0x98 */
\r
3486 icount -= timing.cbw;
\r
3487 regs.b[AH] = (regs.b[AL] & 0x80) ? 0xff : 0;
\r
3490 inline void I86::_cwd() /* Opcode 0x99 */
\r
3492 icount -= timing.cwd;
\r
3493 regs.w[DX] = (regs.b[AH] & 0x80) ? 0xffff : 0;
\r
3496 inline void I86::_call_far() /* Opcode 0x9a */
\r
3498 unsigned tmp, tmp2;
\r
3502 tmp += FETCH << 8;
\r
3505 tmp2 += FETCH << 8;
\r
3507 ip = pc - base[CS];
\r
3510 sregs[CS] = (uint16)tmp2;
\r
3511 base[CS] = SegBase(CS);
\r
3512 pc = (base[CS] + (uint16)tmp) & AMASK;
\r
3513 #ifdef I86_BIOS_CALL
\r
3514 if(d_bios && d_bios->bios_call(pc, regs.w, sregs, &ZeroVal, &CarryVal)) {
\r
3519 icount -= timing.call_far;
\r
3522 inline void I86::_wait() /* Opcode 0x9b */
\r
3527 icount -= timing.wait;
\r
3530 inline void I86::_pushf() /* Opcode 0x9c */
\r
3533 icount -= timing.pushf;
\r
3535 tmp = CompressFlags();
\r
3536 PUSH(tmp | 0xf000);
\r
3539 inline void I86::_popf() /* Opcode 0x9d */
\r
3543 icount -= timing.popf;
\r
3550 /* if the IF is set, and an interrupt is pending, signal an interrupt */
\r
3551 if(IF && (int_state & INT_REQ_BIT)) {
\r
3556 inline void I86::_sahf() /* Opcode 0x9e */
\r
3558 unsigned tmp = (CompressFlags() & 0xff00) | (regs.b[AH] & 0xd5);
\r
3559 icount -= timing.sahf;
\r
3563 inline void I86::_lahf() /* Opcode 0x9f */
\r
3565 regs.b[AH] = CompressFlags() & 0xff;
\r
3566 icount -= timing.lahf;
\r
3569 inline void I86::_mov_aldisp() /* Opcode 0xa0 */
\r
3574 addr += FETCH << 8;
\r
3576 icount -= timing.mov_am8;
\r
3577 regs.b[AL] = GetMemB(DS, addr);
\r
3580 inline void I86::_mov_axdisp() /* Opcode 0xa1 */
\r
3585 addr += FETCH << 8;
\r
3587 icount -= timing.mov_am16;
\r
3588 regs.w[AX] = GetMemW(DS, addr);
\r
3591 inline void I86::_mov_dispal() /* Opcode 0xa2 */
\r
3596 addr += FETCH << 8;
\r
3598 icount -= timing.mov_ma8;
\r
3599 PutMemB(DS, addr, regs.b[AL]);
\r
3602 inline void I86::_mov_dispax() /* Opcode 0xa3 */
\r
3607 addr += FETCH << 8;
\r
3609 icount -= timing.mov_ma16;
\r
3610 PutMemW(DS, addr, regs.w[AX]);
\r
3613 inline void I86::_movsb() /* Opcode 0xa4 */
\r
3615 uint8 tmp = GetMemB(DS, regs.w[SI]);
\r
3616 PutMemB(ES, regs.w[DI], tmp);
\r
3617 regs.w[DI] += DirVal;
\r
3618 regs.w[SI] += DirVal;
\r
3619 icount -= timing.movs8;
\r
3622 inline void I86::_movsw() /* Opcode 0xa5 */
\r
3624 uint16 tmp = GetMemW(DS, regs.w[SI]);
\r
3625 PutMemW(ES, regs.w[DI], tmp);
\r
3626 regs.w[DI] += 2 * DirVal;
\r
3627 regs.w[SI] += 2 * DirVal;
\r
3628 icount -= timing.movs16;
\r
3631 inline void I86::_cmpsb() /* Opcode 0xa6 */
\r
3633 unsigned dst = GetMemB(ES, regs.w[DI]);
\r
3634 unsigned src = GetMemB(DS, regs.w[SI]);
\r
3635 SUBB(src, dst); /* opposite of the usual convention */
\r
3636 regs.w[DI] += DirVal;
\r
3637 regs.w[SI] += DirVal;
\r
3638 icount -= timing.cmps8;
\r
3641 inline void I86::_cmpsw() /* Opcode 0xa7 */
\r
3643 unsigned dst = GetMemW(ES, regs.w[DI]);
\r
3644 unsigned src = GetMemW(DS, regs.w[SI]);
\r
3645 SUBW(src, dst); /* opposite of the usual convention */
\r
3646 regs.w[DI] += 2 * DirVal;
\r
3647 regs.w[SI] += 2 * DirVal;
\r
3648 icount -= timing.cmps16;
\r
3651 inline void I86::_test_ald8() /* Opcode 0xa8 */
\r
3653 DEF_ald8(dst, src);
\r
3654 icount -= timing.alu_ri8;
\r
3658 inline void I86::_test_axd16() /* Opcode 0xa9 */
\r
3660 DEF_axd16(dst, src);
\r
3661 icount -= timing.alu_ri16;
\r
3665 inline void I86::_stosb() /* Opcode 0xaa */
\r
3667 PutMemB(ES, regs.w[DI], regs.b[AL]);
\r
3668 regs.w[DI] += DirVal;
\r
3669 icount -= timing.stos8;
\r
3672 inline void I86::_stosw() /* Opcode 0xab */
\r
3674 PutMemW(ES, regs.w[DI], regs.w[AX]);
\r
3675 regs.w[DI] += 2 * DirVal;
\r
3676 icount -= timing.stos16;
\r
3679 inline void I86::_lodsb() /* Opcode 0xac */
\r
3681 regs.b[AL] = GetMemB(DS, regs.w[SI]);
\r
3682 regs.w[SI] += DirVal;
\r
3683 icount -= timing.lods8;
\r
3686 inline void I86::_lodsw() /* Opcode 0xad */
\r
3688 regs.w[AX] = GetMemW(DS, regs.w[SI]);
\r
3689 regs.w[SI] += 2 * DirVal;
\r
3690 icount -= timing.lods16;
\r
3693 inline void I86::_scasb() /* Opcode 0xae */
\r
3695 unsigned src = GetMemB(ES, regs.w[DI]);
\r
3696 unsigned dst = regs.b[AL];
\r
3698 regs.w[DI] += DirVal;
\r
3699 icount -= timing.scas8;
\r
3702 inline void I86::_scasw() /* Opcode 0xaf */
\r
3704 unsigned src = GetMemW(ES, regs.w[DI]);
\r
3705 unsigned dst = regs.w[AX];
\r
3707 regs.w[DI] += 2 * DirVal;
\r
3708 icount -= timing.scas16;
\r
3711 inline void I86::_mov_ald8() /* Opcode 0xb0 */
\r
3713 regs.b[AL] = FETCH;
\r
3714 icount -= timing.mov_ri8;
\r
3717 inline void I86::_mov_cld8() /* Opcode 0xb1 */
\r
3719 regs.b[CL] = FETCH;
\r
3720 icount -= timing.mov_ri8;
\r
3723 inline void I86::_mov_dld8() /* Opcode 0xb2 */
\r
3725 regs.b[DL] = FETCH;
\r
3726 icount -= timing.mov_ri8;
\r
3729 inline void I86::_mov_bld8() /* Opcode 0xb3 */
\r
3731 regs.b[BL] = FETCH;
\r
3732 icount -= timing.mov_ri8;
\r
3735 inline void I86::_mov_ahd8() /* Opcode 0xb4 */
\r
3737 regs.b[AH] = FETCH;
\r
3738 icount -= timing.mov_ri8;
\r
3741 inline void I86::_mov_chd8() /* Opcode 0xb5 */
\r
3743 regs.b[CH] = FETCH;
\r
3744 icount -= timing.mov_ri8;
\r
3747 inline void I86::_mov_dhd8() /* Opcode 0xb6 */
\r
3749 regs.b[DH] = FETCH;
\r
3750 icount -= timing.mov_ri8;
\r
3753 inline void I86::_mov_bhd8() /* Opcode 0xb7 */
\r
3755 regs.b[BH] = FETCH;
\r
3756 icount -= timing.mov_ri8;
\r
3759 inline void I86::_mov_axd16() /* Opcode 0xb8 */
\r
3761 regs.b[AL] = FETCH;
\r
3762 regs.b[AH] = FETCH;
\r
3763 icount -= timing.mov_ri16;
\r
3766 inline void I86::_mov_cxd16() /* Opcode 0xb9 */
\r
3768 regs.b[CL] = FETCH;
\r
3769 regs.b[CH] = FETCH;
\r
3770 icount -= timing.mov_ri16;
\r
3773 inline void I86::_mov_dxd16() /* Opcode 0xba */
\r
3775 regs.b[DL] = FETCH;
\r
3776 regs.b[DH] = FETCH;
\r
3777 icount -= timing.mov_ri16;
\r
3780 inline void I86::_mov_bxd16() /* Opcode 0xbb */
\r
3782 regs.b[BL] = FETCH;
\r
3783 regs.b[BH] = FETCH;
\r
3784 icount -= timing.mov_ri16;
\r
3787 inline void I86::_mov_spd16() /* Opcode 0xbc */
\r
3789 regs.b[SPL] = FETCH;
\r
3790 regs.b[SPH] = FETCH;
\r
3791 icount -= timing.mov_ri16;
\r
3794 inline void I86::_mov_bpd16() /* Opcode 0xbd */
\r
3796 regs.b[BPL] = FETCH;
\r
3797 regs.b[BPH] = FETCH;
\r
3798 icount -= timing.mov_ri16;
\r
3801 inline void I86::_mov_sid16() /* Opcode 0xbe */
\r
3803 regs.b[SIL] = FETCH;
\r
3804 regs.b[SIH] = FETCH;
\r
3805 icount -= timing.mov_ri16;
\r
3808 inline void I86::_mov_did16() /* Opcode 0xbf */
\r
3810 regs.b[DIL] = FETCH;
\r
3811 regs.b[DIH] = FETCH;
\r
3812 icount -= timing.mov_ri16;
\r
3815 inline void I86::_rotshft_bd8() /* Opcode 0xc0 */
\r
3817 unsigned ModRM = FETCH;
\r
3818 unsigned count = FETCH;
\r
3820 rotate_shift_byte(ModRM, count);
\r
3823 inline void I86::_rotshft_wd8() /* Opcode 0xc1 */
\r
3825 unsigned ModRM = FETCH;
\r
3826 unsigned count = FETCH;
\r
3828 rotate_shift_word(ModRM, count);
\r
3831 inline void I86::_ret_d16() /* Opcode 0xc2 */
\r
3833 unsigned count = FETCH;
\r
3834 count += FETCH << 8;
\r
3836 pc = (pc + base[CS]) & AMASK;
\r
3837 regs.w[SP] += count;
\r
3838 icount -= timing.ret_near_imm;
\r
3841 inline void I86::_ret() /* Opcode 0xc3 */
\r
3844 pc = (pc + base[CS]) & AMASK;
\r
3845 icount -= timing.ret_near;
\r
3848 inline void I86::_les_dw() /* Opcode 0xc4 */
\r
3850 unsigned ModRM = FETCH;
\r
3851 uint16 tmp = GetRMWord(ModRM);
\r
3852 RegWord(ModRM) = tmp;
\r
3853 sregs[ES] = GetNextRMWord;
\r
3854 base[ES] = SegBase(ES);
\r
3855 icount -= timing.load_ptr;
\r
3858 inline void I86::_lds_dw() /* Opcode 0xc5 */
\r
3860 unsigned ModRM = FETCH;
\r
3861 uint16 tmp = GetRMWord(ModRM);
\r
3862 RegWord(ModRM) = tmp;
\r
3863 sregs[DS] = GetNextRMWord;
\r
3864 base[DS] = SegBase(DS);
\r
3865 icount -= timing.load_ptr;
\r
3868 inline void I86::_mov_bd8() /* Opcode 0xc6 */
\r
3870 unsigned ModRM = FETCH;
\r
3871 icount -= (ModRM >= 0xc0) ? timing.mov_ri8 : timing.mov_mi8;
\r
3872 PutImmRMByte(ModRM);
\r
3875 inline void I86::_mov_wd16() /* Opcode 0xc7 */
\r
3877 unsigned ModRM = FETCH;
\r
3878 icount -= (ModRM >= 0xc0) ? timing.mov_ri16 : timing.mov_mi16;
\r
3879 PutImmRMWord(ModRM);
\r
3882 inline void I86::_enter() /* Opcode 0xc8 */
\r
3884 unsigned nb = FETCH;
\r
3885 unsigned i, level;
\r
3889 icount -= (level == 0) ? timing.enter0 : (level == 1) ? timing.enter1 : timing.enter_base + level * timing.enter_count;
\r
3891 regs.w[BP] = regs.w[SP];
\r
3893 for(i = 1; i < level; i++) {
\r
3894 PUSH(GetMemW(SS, regs.w[BP] - i * 2));
\r
3901 inline void I86::_leav() /* Opcode 0xc9 */
\r
3903 icount -= timing.leave;
\r
3904 regs.w[SP] = regs.w[BP];
\r
3908 inline void I86::_retf_d16() /* Opcode 0xca */
\r
3910 unsigned count = FETCH;
\r
3911 count += FETCH << 8;
\r
3914 base[CS] = SegBase(CS);
\r
3915 pc = (pc + base[CS]) & AMASK;
\r
3916 regs.w[SP] += count;
\r
3917 icount -= timing.ret_far_imm;
\r
3920 inline void I86::_retf() /* Opcode 0xcb */
\r
3924 base[CS] = SegBase(CS);
\r
3925 pc = (pc + base[CS]) & AMASK;
\r
3926 icount -= timing.ret_far;
\r
3929 inline void I86::_int3() /* Opcode 0xcc */
\r
3931 icount -= timing.int3;
\r
3935 inline void I86::_int() /* Opcode 0xcd */
\r
3937 unsigned int_num = FETCH;
\r
3938 icount -= timing.int_imm;
\r
3939 #ifdef I86_BIOS_CALL
\r
3940 if(d_bios && d_bios->bios_int(int_num, regs.w, sregs, &ZeroVal, &CarryVal)) {
\r
3945 interrupt(int_num);
\r
3948 inline void I86::_into() /* Opcode 0xce */
\r
3951 icount -= timing.into_t;
\r
3952 interrupt(OVERFLOW_TRAP);
\r
3954 icount -= timing.into_nt;
\r
3958 inline void I86::_iret() /* Opcode 0xcf */
\r
3960 icount -= timing.iret;
\r
3963 base[CS] = SegBase(CS);
\r
3964 pc = (pc + base[CS]) & AMASK;
\r
3967 /* if the IF is set, and an interrupt is pending, signal an interrupt */
\r
3968 if(IF && (int_state & INT_REQ_BIT)) {
\r
3973 inline void I86::_rotshft_b() /* Opcode 0xd0 */
\r
3975 rotate_shift_byte(FETCHOP, 1);
\r
3978 inline void I86::_rotshft_w() /* Opcode 0xd1 */
\r
3980 rotate_shift_word(FETCHOP, 1);
\r
3983 inline void I86::_rotshft_bcl() /* Opcode 0xd2 */
\r
3985 rotate_shift_byte(FETCHOP, regs.b[CL]);
\r
3988 inline void I86::_rotshft_wcl() /* Opcode 0xd3 */
\r
3990 rotate_shift_word(FETCHOP, regs.b[CL]);
\r
3993 /* OB: Opcode works on NEC V-Series but not the Variants */
\r
3994 /* one could specify any byte value as operand but the NECs */
\r
3995 /* always substitute 0x0a. */
\r
3996 inline void I86::_aam() /* Opcode 0xd4 */
\r
3998 unsigned mult = FETCH;
\r
3999 icount -= timing.aam;
\r
4001 interrupt(DIVIDE_FAULT);
\r
4003 regs.b[AH] = regs.b[AL] / mult;
\r
4004 regs.b[AL] %= mult;
\r
4005 SetSZPF_Word(regs.w[AX]);
\r
4009 inline void I86::_aad() /* Opcode 0xd5 */
\r
4011 unsigned mult = FETCH;
\r
4012 icount -= timing.aad;
\r
4013 regs.b[AL] = regs.b[AH] * mult + regs.b[AL];
\r
4015 SetZF(regs.b[AL]);
\r
4016 SetPF(regs.b[AL]);
\r
4020 inline void I86::_setalc() /* Opcode 0xd6 */
\r
4022 regs.b[AL] = (CF) ? 0xff : 0x00;
\r
4026 inline void I86::_xlat() /* Opcode 0xd7 */
\r
4028 unsigned dest = regs.w[BX] + regs.b[AL];
\r
4029 icount -= timing.xlat;
\r
4030 regs.b[AL] = GetMemB(DS, dest);
\r
4033 inline void I86::_escape() /* Opcodes 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde and 0xdf */
\r
4035 unsigned ModRM = FETCH;
\r
4036 icount -= timing.nop;
\r
4040 inline void I86::_loopne() /* Opcode 0xe0 */
\r
4042 int disp = (int)((int8)FETCH);
\r
4043 unsigned tmp = regs.w[CX] - 1;
\r
4046 icount -= timing.loop_t;
\r
4049 icount -= timing.loop_nt;
\r
4053 inline void I86::_loope() /* Opcode 0xe1 */
\r
4055 int disp = (int)((int8)FETCH);
\r
4056 unsigned tmp = regs.w[CX] - 1;
\r
4059 icount -= timing.loope_t;
\r
4062 icount -= timing.loope_nt;
\r
4066 inline void I86::_loop() /* Opcode 0xe2 */
\r
4068 int disp = (int)((int8)FETCH);
\r
4069 unsigned tmp = regs.w[CX] - 1;
\r
4072 icount -= timing.loop_t;
\r
4075 icount -= timing.loop_nt;
\r
4079 inline void I86::_jcxz() /* Opcode 0xe3 */
\r
4081 int disp = (int)((int8)FETCH);
\r
4082 if(regs.w[CX] == 0) {
\r
4083 icount -= timing.jcxz_t;
\r
4086 icount -= timing.jcxz_nt;
\r
4090 inline void I86::_inal() /* Opcode 0xe4 */
\r
4092 unsigned port = FETCH;
\r
4093 icount -= timing.in_imm8;
\r
4094 regs.b[AL] = read_port_byte(port);
\r
4097 inline void I86::_inax() /* Opcode 0xe5 */
\r
4099 unsigned port = FETCH;
\r
4100 icount -= timing.in_imm16;
\r
4101 regs.w[AX] = read_port_word(port);
\r
4104 inline void I86::_outal() /* Opcode 0xe6 */
\r
4106 unsigned port = FETCH;
\r
4107 icount -= timing.out_imm8;
\r
4108 write_port_byte(port, regs.b[AL]);
\r
4111 inline void I86::_outax() /* Opcode 0xe7 */
\r
4113 unsigned port = FETCH;
\r
4114 icount -= timing.out_imm16;
\r
4115 write_port_word(port, regs.w[AX]);
\r
4118 inline void I86::_call_d16() /* Opcode 0xe8 */
\r
4123 ip = pc - base[CS];
\r
4126 pc = (ip + base[CS]) & AMASK;
\r
4127 #ifdef I86_BIOS_CALL
\r
4128 if(d_bios && d_bios->bios_call(pc, regs.w, sregs, &ZeroVal, &CarryVal)) {
\r
4133 icount -= timing.call_near;
\r
4136 inline void I86::_jmp_d16() /* Opcode 0xe9 */
\r
4141 ip = pc - base[CS] + tmp;
\r
4142 pc = (ip + base[CS]) & AMASK;
\r
4143 icount -= timing.jmp_near;
\r
4146 inline void I86::_jmp_far() /* Opcode 0xea */
\r
4148 unsigned tmp, tmp1;
\r
4151 tmp += FETCH << 8;
\r
4154 tmp1 += FETCH << 8;
\r
4156 sregs[CS] = (uint16)tmp1;
\r
4157 base[CS] = SegBase(CS);
\r
4158 pc = (base[CS] + tmp) & AMASK;
\r
4159 icount -= timing.jmp_far;
\r
4162 inline void I86::_jmp_d8() /* Opcode 0xeb */
\r
4164 int tmp = (int)((int8)FETCH);
\r
4166 icount -= timing.jmp_short;
\r
4169 inline void I86::_inaldx() /* Opcode 0xec */
\r
4171 icount -= timing.in_dx8;
\r
4172 regs.b[AL] = read_port_byte(regs.w[DX]);
\r
4175 inline void I86::_inaxdx() /* Opcode 0xed */
\r
4177 unsigned port = regs.w[DX];
\r
4178 icount -= timing.in_dx16;
\r
4179 regs.w[AX] = read_port_word(port);
\r
4182 inline void I86::_outdxal() /* Opcode 0xee */
\r
4184 icount -= timing.out_dx8;
\r
4185 write_port_byte(regs.w[DX], regs.b[AL]);
\r
4188 inline void I86::_outdxax() /* Opcode 0xef */
\r
4190 unsigned port = regs.w[DX];
\r
4191 icount -= timing.out_dx16;
\r
4192 write_port_word(port, regs.w[AX]);
\r
4195 /* I think thats not a V20 instruction...*/
\r
4196 inline void I86::_lock() /* Opcode 0xf0 */
\r
4198 icount -= timing.nop;
\r
4199 instruction(FETCHOP); /* un-interruptible */
\r
4202 inline void I86::_rep(int flagval)
\r
4204 /* Handles rep- and repnz- prefixes. flagval is the value of ZF for the
\r
4205 loop to continue for CMPS and SCAS instructions. */
\r
4207 unsigned next = FETCHOP;
\r
4208 unsigned count = regs.w[CX];
\r
4211 case 0x26: /* ES: */
\r
4212 seg_prefix = true;
\r
4214 icount -= timing.override;
\r
4217 case 0x2e: /* CS: */
\r
4218 seg_prefix = true;
\r
4220 icount -= timing.override;
\r
4223 case 0x36: /* SS: */
\r
4224 seg_prefix = true;
\r
4226 icount -= timing.override;
\r
4229 case 0x3e: /* DS: */
\r
4230 seg_prefix = true;
\r
4232 icount -= timing.override;
\r
4236 case 0x6c: /* REP INSB */
\r
4237 icount -= timing.rep_ins8_base;
\r
4238 for(; count > 0; count--) {
\r
4239 PutMemB(ES, regs.w[DI], read_port_byte(regs.w[DX]));
\r
4240 regs.w[DI] += DirVal;
\r
4241 icount -= timing.rep_ins8_count;
\r
4243 regs.w[CX] = count;
\r
4245 case 0x6d: /* REP INSW */
\r
4246 icount -= timing.rep_ins16_base;
\r
4247 for(; count > 0; count--) {
\r
4248 PutMemW(ES, regs.w[DI], read_port_word(regs.w[DX]));
\r
4249 regs.w[DI] += 2 * DirVal;
\r
4250 icount -= timing.rep_ins16_count;
\r
4252 regs.w[CX] = count;
\r
4254 case 0x6e: /* REP OUTSB */
\r
4255 icount -= timing.rep_outs8_base;
\r
4256 for(; count > 0; count--) {
\r
4257 write_port_byte(regs.w[DX], GetMemB(DS, regs.w[SI]));
\r
4258 regs.w[SI] += DirVal; /* GOL 11/27/01 */
\r
4259 icount -= timing.rep_outs8_count;
\r
4261 regs.w[CX] = count;
\r
4263 case 0x6f: /* REP OUTSW */
\r
4264 icount -= timing.rep_outs16_base;
\r
4265 for(; count > 0; count--) {
\r
4266 write_port_word(regs.w[DX], GetMemW(DS, regs.w[SI]));
\r
4267 regs.w[SI] += 2 * DirVal; /* GOL 11/27/01 */
\r
4268 icount -= timing.rep_outs16_count;
\r
4270 regs.w[CX] = count;
\r
4273 case 0xa4: /* REP MOVSB */
\r
4274 icount -= timing.rep_movs8_base;
\r
4275 for(; count > 0; count--) {
\r
4277 tmp = GetMemB(DS, regs.w[SI]);
\r
4278 PutMemB(ES, regs.w[DI], tmp);
\r
4279 regs.w[DI] += DirVal;
\r
4280 regs.w[SI] += DirVal;
\r
4281 icount -= timing.rep_movs8_count;
\r
4283 regs.w[CX] = count;
\r
4285 case 0xa5: /* REP MOVSW */
\r
4286 icount -= timing.rep_movs16_base;
\r
4287 for(; count > 0; count--) {
\r
4289 tmp = GetMemW(DS, regs.w[SI]);
\r
4290 PutMemW(ES, regs.w[DI], tmp);
\r
4291 regs.w[DI] += 2 * DirVal;
\r
4292 regs.w[SI] += 2 * DirVal;
\r
4293 icount -= timing.rep_movs16_count;
\r
4295 regs.w[CX] = count;
\r
4297 case 0xa6: /* REP(N)E CMPSB */
\r
4298 icount -= timing.rep_cmps8_base;
\r
4299 for(ZeroVal = !flagval; (ZF == flagval) && (count > 0); count--) {
\r
4300 unsigned dst, src;
\r
4301 dst = GetMemB(ES, regs.w[DI]);
\r
4302 src = GetMemB(DS, regs.w[SI]);
\r
4303 SUBB(src, dst); /* opposite of the usual convention */
\r
4304 regs.w[DI] += DirVal;
\r
4305 regs.w[SI] += DirVal;
\r
4306 icount -= timing.rep_cmps8_count;
\r
4308 regs.w[CX] = count;
\r
4310 case 0xa7: /* REP(N)E CMPSW */
\r
4311 icount -= timing.rep_cmps16_base;
\r
4312 for(ZeroVal = !flagval; (ZF == flagval) && (count > 0); count--) {
\r
4313 unsigned dst, src;
\r
4314 dst = GetMemW(ES, regs.w[DI]);
\r
4315 src = GetMemW(DS, regs.w[SI]);
\r
4316 SUBW(src, dst); /* opposite of the usual convention */
\r
4317 regs.w[DI] += 2 * DirVal;
\r
4318 regs.w[SI] += 2 * DirVal;
\r
4319 icount -= timing.rep_cmps16_count;
\r
4321 regs.w[CX] = count;
\r
4323 case 0xaa: /* REP STOSB */
\r
4324 icount -= timing.rep_stos8_base;
\r
4325 for(; count > 0; count--) {
\r
4326 PutMemB(ES, regs.w[DI], regs.b[AL]);
\r
4327 regs.w[DI] += DirVal;
\r
4328 icount -= timing.rep_stos8_count;
\r
4330 regs.w[CX] = count;
\r
4332 case 0xab: /* REP STOSW */
\r
4333 icount -= timing.rep_stos16_base;
\r
4334 for(; count > 0; count--) {
\r
4335 PutMemW(ES, regs.w[DI], regs.w[AX]);
\r
4336 regs.w[DI] += 2 * DirVal;
\r
4337 icount -= timing.rep_stos16_count;
\r
4339 regs.w[CX] = count;
\r
4341 case 0xac: /* REP LODSB */
\r
4342 icount -= timing.rep_lods8_base;
\r
4343 for(; count > 0; count--) {
\r
4344 regs.b[AL] = GetMemB(DS, regs.w[SI]);
\r
4345 regs.w[SI] += DirVal;
\r
4346 icount -= timing.rep_lods8_count;
\r
4348 regs.w[CX] = count;
\r
4350 case 0xad: /* REP LODSW */
\r
4351 icount -= timing.rep_lods16_base;
\r
4352 for(; count > 0; count--) {
\r
4353 regs.w[AX] = GetMemW(DS, regs.w[SI]);
\r
4354 regs.w[SI] += 2 * DirVal;
\r
4355 icount -= timing.rep_lods16_count;
\r
4357 regs.w[CX] = count;
\r
4359 case 0xae: /* REP(N)E SCASB */
\r
4360 icount -= timing.rep_scas8_base;
\r
4361 for(ZeroVal = !flagval; (ZF == flagval) && (count > 0); count--) {
\r
4362 unsigned src, dst;
\r
4363 src = GetMemB(ES, regs.w[DI]);
\r
4366 regs.w[DI] += DirVal;
\r
4367 icount -= timing.rep_scas8_count;
\r
4369 regs.w[CX] = count;
\r
4371 case 0xaf: /* REP(N)E SCASW */
\r
4372 icount -= timing.rep_scas16_base;
\r
4373 for(ZeroVal = !flagval; (ZF == flagval) && (count > 0); count--) {
\r
4374 unsigned src, dst;
\r
4375 src = GetMemW(ES, regs.w[DI]);
\r
4378 regs.w[DI] += 2 * DirVal;
\r
4379 icount -= timing.rep_scas16_count;
\r
4381 regs.w[CX] = count;
\r
4384 instruction(next);
\r
4388 inline void I86::_repne() /* Opcode 0xf2 */
\r
4393 inline void I86::_repe() /* Opcode 0xf3 */
\r
4398 inline void I86::_hlt() /* Opcode 0xf4 */
\r
4405 inline void I86::_cmc() /* Opcode 0xf5 */
\r
4407 icount -= timing.flag_ops;
\r
4411 inline void I86::_f6pre() /* Opcode 0xf6 */
\r
4413 unsigned ModRM = FETCH;
\r
4414 unsigned tmp = (unsigned)GetRMByte(ModRM);
\r
4417 switch((ModRM >> 3) & 7) {
\r
4418 case 0: /* TEST Eb, data8 */
\r
4420 icount -= (ModRM >= 0xc0) ? timing.alu_ri8 : timing.alu_mi8_ro;
\r
4423 CarryVal = OverVal = AuxVal = 0;
\r
4424 SetSZPF_Byte(tmp);
\r
4427 case 2: /* NOT Eb */
\r
4428 icount -= (ModRM >= 0xc0) ? timing.negnot_r8 : timing.negnot_m8;
\r
4429 PutbackRMByte(ModRM, ~tmp);
\r
4432 case 3: /* NEG Eb */
\r
4433 icount -= (ModRM >= 0xc0) ? timing.negnot_r8 : timing.negnot_m8;
\r
4436 PutbackRMByte(ModRM, tmp2);
\r
4439 case 4: /* MUL AL, Eb */
\r
4440 icount -= (ModRM >= 0xc0) ? timing.mul_r8 : timing.mul_m8;
\r
4444 tmp2 = regs.b[AL];
\r
4446 SetSF((int8)tmp2);
\r
4449 result = (uint16)tmp2 * tmp;
\r
4450 regs.w[AX] = (uint16)result;
\r
4452 SetZF(regs.w[AX]);
\r
4453 CarryVal = OverVal = (regs.b[AH] != 0);
\r
4457 case 5: /* IMUL AL, Eb */
\r
4458 icount -= (ModRM >= 0xc0) ? timing.imul_r8 : timing.imul_m8;
\r
4462 tmp2 = (unsigned)regs.b[AL];
\r
4464 SetSF((int8)tmp2);
\r
4467 result = (int16)((int8)tmp2) * (int16)((int8)tmp);
\r
4468 regs.w[AX] = (uint16)result;
\r
4470 SetZF(regs.w[AX]);
\r
4471 CarryVal = OverVal = (result >> 7 != 0) && (result >> 7 != -1);
\r
4475 case 6: /* DIV AL, Ew */
\r
4476 icount -= (ModRM >= 0xc0) ? timing.div_r8 : timing.div_m8;
\r
4480 result = regs.w[AX];
\r
4483 if((result / tmp) > 0xff) {
\r
4484 interrupt(DIVIDE_FAULT);
\r
4487 regs.b[AH] = result % tmp;
\r
4488 regs.b[AL] = result / tmp;
\r
4491 interrupt(DIVIDE_FAULT);
\r
4497 case 7: /* IDIV AL, Ew */
\r
4498 icount -= (ModRM >= 0xc0) ? timing.idiv_r8 : timing.idiv_m8;
\r
4502 result = regs.w[AX];
\r
4505 tmp2 = result % (int16)((int8)tmp);
\r
4507 if((result /= (int16)((int8)tmp)) > 0xff) {
\r
4508 interrupt(DIVIDE_FAULT);
\r
4511 regs.b[AL] = (uint8)result;
\r
4512 regs.b[AH] = tmp2;
\r
4515 interrupt(DIVIDE_FAULT);
\r
4527 inline void I86::_f7pre() /* Opcode 0xf7 */
\r
4529 unsigned ModRM = FETCH;
\r
4530 unsigned tmp = GetRMWord(ModRM);
\r
4533 switch((ModRM >> 3) & 7) {
\r
4534 case 0: /* TEST Ew, data16 */
\r
4536 icount -= (ModRM >= 0xc0) ? timing.alu_ri16 : timing.alu_mi16_ro;
\r
4538 tmp2 += FETCH << 8;
\r
4542 CarryVal = OverVal = AuxVal = 0;
\r
4543 SetSZPF_Word(tmp);
\r
4546 case 2: /* NOT Ew */
\r
4547 icount -= (ModRM >= 0xc0) ? timing.negnot_r16 : timing.negnot_m16;
\r
4549 PutbackRMWord(ModRM, tmp);
\r
4552 case 3: /* NEG Ew */
\r
4553 icount -= (ModRM >= 0xc0) ? timing.negnot_r16 : timing.negnot_m16;
\r
4556 PutbackRMWord(ModRM, tmp2);
\r
4559 case 4: /* MUL AX, Ew */
\r
4560 icount -= (ModRM >= 0xc0) ? timing.mul_r16 : timing.mul_m16;
\r
4563 tmp2 = regs.w[AX];
\r
4565 SetSF((int16)tmp2);
\r
4568 result = (uint32)tmp2 * tmp;
\r
4569 regs.w[AX] = (uint16)result;
\r
4571 regs.w[DX] = result;
\r
4573 SetZF(regs.w[AX] | regs.w[DX]);
\r
4574 CarryVal = OverVal = (regs.w[DX] != 0);
\r
4578 case 5: /* IMUL AX, Ew */
\r
4579 icount -= (ModRM >= 0xc0) ? timing.imul_r16 : timing.imul_m16;
\r
4583 tmp2 = regs.w[AX];
\r
4585 SetSF((int16)tmp2);
\r
4588 result = (int32)((int16)tmp2) * (int32)((int16)tmp);
\r
4589 CarryVal = OverVal = (result >> 15 != 0) && (result >> 15 != -1);
\r
4591 regs.w[AX] = (uint16)result;
\r
4592 result = (uint16)(result >> 16);
\r
4593 regs.w[DX] = result;
\r
4595 SetZF(regs.w[AX] | regs.w[DX]);
\r
4599 case 6: /* DIV AX, Ew */
\r
4600 icount -= (ModRM >= 0xc0) ? timing.div_r16 : timing.div_m16;
\r
4604 result = (regs.w[DX] << 16) + regs.w[AX];
\r
4607 tmp2 = result % tmp;
\r
4608 if((result / tmp) > 0xffff) {
\r
4609 interrupt(DIVIDE_FAULT);
\r
4612 regs.w[DX] = tmp2;
\r
4614 regs.w[AX] = result;
\r
4617 interrupt(DIVIDE_FAULT);
\r
4623 case 7: /* IDIV AX, Ew */
\r
4624 icount -= (ModRM >= 0xc0) ? timing.idiv_r16 : timing.idiv_m16;
\r
4628 result = (regs.w[DX] << 16) + regs.w[AX];
\r
4631 tmp2 = result % (int32)((int16)tmp);
\r
4632 if((result /= (int32)((int16)tmp)) > 0xffff) {
\r
4633 interrupt(DIVIDE_FAULT);
\r
4636 regs.w[AX] = result;
\r
4637 regs.w[DX] = tmp2;
\r
4640 interrupt(DIVIDE_FAULT);
\r
4652 inline void I86::_clc() /* Opcode 0xf8 */
\r
4654 icount -= timing.flag_ops;
\r
4658 inline void I86::_stc() /* Opcode 0xf9 */
\r
4660 icount -= timing.flag_ops;
\r
4664 inline void I86::_cli() /* Opcode 0xfa */
\r
4666 icount -= timing.flag_ops;
\r
4670 inline void I86::_sti() /* Opcode 0xfb */
\r
4672 icount -= timing.flag_ops;
\r
4674 instruction(FETCHOP); /* no interrupt before next instruction */
\r
4676 /* if an interrupt is pending, signal an interrupt */
\r
4677 if(IF && (int_state & INT_REQ_BIT)) {
\r
4682 inline void I86::_cld() /* Opcode 0xfc */
\r
4684 icount -= timing.flag_ops;
\r
4688 inline void I86::_std() /* Opcode 0xfd */
\r
4690 icount -= timing.flag_ops;
\r
4694 inline void I86::_fepre() /* Opcode 0xfe */
\r
4696 unsigned ModRM = FETCH;
\r
4697 unsigned tmp = GetRMByte(ModRM);
\r
4700 icount -= (ModRM >= 0xc0) ? timing.incdec_r8 : timing.incdec_m8;
\r
4701 if((ModRM & 0x38) == 0) {
\r
4704 SetOFB_Add(tmp1, tmp, 1);
\r
4708 SetOFB_Sub(tmp1, 1, tmp);
\r
4710 SetAF(tmp1, tmp, 1);
\r
4711 SetSZPF_Byte(tmp1);
\r
4712 PutbackRMByte(ModRM, (uint8)tmp1);
\r
4715 inline void I86::_ffpre() /* Opcode 0xff */
\r
4717 unsigned ModRM = FETCHOP;
\r
4722 switch((ModRM >> 3) & 7) {
\r
4723 case 0: /* INC ew */
\r
4724 icount -= (ModRM >= 0xc0) ? timing.incdec_r16 : timing.incdec_m16;
\r
4725 tmp = GetRMWord(ModRM);
\r
4727 SetOFW_Add(tmp1, tmp, 1);
\r
4728 SetAF(tmp1, tmp, 1);
\r
4729 SetSZPF_Word(tmp1);
\r
4730 PutbackRMWord(ModRM, (uint16)tmp1);
\r
4732 case 1: /* DEC ew */
\r
4733 icount -= (ModRM >= 0xc0) ? timing.incdec_r16 : timing.incdec_m16;
\r
4734 tmp = GetRMWord(ModRM);
\r
4736 SetOFW_Sub(tmp1, 1, tmp);
\r
4737 SetAF(tmp1, tmp, 1);
\r
4738 SetSZPF_Word(tmp1);
\r
4739 PutbackRMWord(ModRM, (uint16)tmp1);
\r
4741 case 2: /* CALL ew */
\r
4742 icount -= (ModRM >= 0xc0) ? timing.call_r16 : timing.call_m16;
\r
4743 tmp = GetRMWord(ModRM);
\r
4744 ip = pc - base[CS];
\r
4746 pc = (base[CS] + (uint16)tmp) & AMASK;
\r
4747 #ifdef I86_BIOS_CALL
\r
4748 if(d_bios && d_bios->bios_call(pc, regs.w, sregs, &ZeroVal, &CarryVal)) {
\r
4754 case 3: /* CALL FAR ea */
\r
4755 icount -= timing.call_m32;
\r
4756 tmp = sregs[CS]; /* need to skip displacements of ea */
\r
4757 tmp1 = GetRMWord(ModRM);
\r
4758 ip = pc - base[CS];
\r
4761 sregs[CS] = GetNextRMWord;
\r
4762 base[CS] = SegBase(CS);
\r
4763 pc = (base[CS] + tmp1) & AMASK;
\r
4764 #ifdef I86_BIOS_CALL
\r
4765 if(d_bios && d_bios->bios_call(pc, regs.w, sregs, &ZeroVal, &CarryVal)) {
\r
4771 case 4: /* JMP ea */
\r
4772 icount -= (ModRM >= 0xc0) ? timing.jmp_r16 : timing.jmp_m16;
\r
4773 ip = GetRMWord(ModRM);
\r
4774 pc = (base[CS] + ip) & AMASK;
\r
4776 case 5: /* JMP FAR ea */
\r
4777 icount -= timing.jmp_m32;
\r
4778 pc = GetRMWord(ModRM);
\r
4779 sregs[CS] = GetNextRMWord;
\r
4780 base[CS] = SegBase(CS);
\r
4781 pc = (pc + base[CS]) & AMASK;
\r
4783 case 6: /* PUSH ea */
\r
4784 icount -= (ModRM >= 0xc0) ? timing.push_r16 : timing.push_m16;
\r
4785 tmp = GetRMWord(ModRM);
\r
4788 case 7: /* invalid ??? */
\r
4797 inline void I86::_invalid()
\r
4799 /* i8086/i8088 ignore an invalid opcode. */
\r
4800 /* i80186/i80188 probably also ignore an invalid opcode. */
\r
4805 NEC V-series Disassembler
\r
4807 Originally Written for i386 by Ville Linde
\r
4808 Converted to NEC-V by Aaron Giles
\r
4813 PARAM_REG8 = 1, /* 8-bit register */
\r
4814 PARAM_REG16, /* 16-bit register */
\r
4815 PARAM_REG2_8, /* 8-bit register */
\r
4816 PARAM_REG2_16, /* 16-bit register */
\r
4817 PARAM_RM8, /* 8-bit memory or register */
\r
4818 PARAM_RM16, /* 16-bit memory or register */
\r
4819 PARAM_RMPTR8, /* 8-bit memory or register */
\r
4820 PARAM_RMPTR16, /* 16-bit memory or register */
\r
4821 PARAM_I3, /* 3-bit immediate */
\r
4822 PARAM_I4, /* 4-bit immediate */
\r
4823 PARAM_I8, /* 8-bit signed immediate */
\r
4824 PARAM_I16, /* 16-bit signed immediate */
\r
4825 PARAM_UI8, /* 8-bit unsigned immediate */
\r
4826 PARAM_IMM, /* 16-bit immediate */
\r
4827 PARAM_ADDR, /* 16:16 address */
\r
4828 PARAM_REL8, /* 8-bit PC-relative displacement */
\r
4829 PARAM_REL16, /* 16-bit PC-relative displacement */
\r
4830 PARAM_MEM_OFFS, /* 16-bit mem offset */
\r
4831 PARAM_SREG, /* segment register */
\r
4832 PARAM_SFREG, /* V25/V35 special function register */
\r
4833 PARAM_1, /* used by shift/rotate instructions */
\r
4865 struct I386_OPCODE {
\r
4866 char mnemonic[32];
\r
4871 offs_t dasm_flags;
\r
4875 char mnemonic[32];
\r
4876 const I386_OPCODE *opcode;
\r
4879 static const UINT8 *opcode_ptr;
\r
4880 static const UINT8 *opcode_ptr_base;
\r
4882 static const I386_OPCODE necv_opcode_table1[256] =
\r
4885 {"add", MODRM, PARAM_RM8, PARAM_REG8, 0 },
\r
4886 {"add", MODRM, PARAM_RM16, PARAM_REG16, 0 },
\r
4887 {"add", MODRM, PARAM_REG8, PARAM_RM8, 0 },
\r
4888 {"add", MODRM, PARAM_REG16, PARAM_RM16, 0 },
\r
4889 {"add", 0, PARAM_AL, PARAM_UI8, 0 },
\r
4890 {"add", 0, PARAM_AW, PARAM_IMM, 0 },
\r
4891 {"push ds1", 0, 0, 0, 0 },
\r
4892 {"pop ds1", 0, 0, 0, 0 },
\r
4893 {"or", MODRM, PARAM_RM8, PARAM_REG8, 0 },
\r
4894 {"or", MODRM, PARAM_RM16, PARAM_REG16, 0 },
\r
4895 {"or", MODRM, PARAM_REG8, PARAM_RM8, 0 },
\r
4896 {"or", MODRM, PARAM_REG16, PARAM_RM16, 0 },
\r
4897 {"or", 0, PARAM_AL, PARAM_UI8, 0 },
\r
4898 {"or", 0, PARAM_AW, PARAM_IMM, 0 },
\r
4899 {"push ps", 0, 0, 0, 0 },
\r
4900 {"two_byte", TWO_BYTE, 0, 0, 0 },
\r
4902 {"addc", MODRM, PARAM_RM8, PARAM_REG8, 0 },
\r
4903 {"addc", MODRM, PARAM_RM16, PARAM_REG16, 0 },
\r
4904 {"addc", MODRM, PARAM_REG8, PARAM_RM8, 0 },
\r
4905 {"addc", MODRM, PARAM_REG16, PARAM_RM16, 0 },
\r
4906 {"addc", 0, PARAM_AL, PARAM_UI8, 0 },
\r
4907 {"addc", 0, PARAM_AW, PARAM_IMM, 0 },
\r
4908 {"push ss", 0, 0, 0, 0 },
\r
4909 {"pop ss", 0, 0, 0, 0 },
\r
4910 {"subc", MODRM, PARAM_RM8, PARAM_REG8, 0 },
\r
4911 {"subc", MODRM, PARAM_RM16, PARAM_REG16, 0 },
\r
4912 {"subc", MODRM, PARAM_REG8, PARAM_RM8, 0 },
\r
4913 {"subc", MODRM, PARAM_REG16, PARAM_RM16, 0 },
\r
4914 {"subc", 0, PARAM_AL, PARAM_UI8, 0 },
\r
4915 {"subc", 0, PARAM_AW, PARAM_IMM, 0 },
\r
4916 {"push ds0", 0, 0, 0, 0 },
\r
4917 {"pop ds0", 0, 0, 0, 0 },
\r
4919 {"and", MODRM, PARAM_RM8, PARAM_REG8, 0 },
\r
4920 {"and", MODRM, PARAM_RM16, PARAM_REG16, 0 },
\r
4921 {"and", MODRM, PARAM_REG8, PARAM_RM8, 0 },
\r
4922 {"and", MODRM, PARAM_REG16, PARAM_RM16, 0 },
\r
4923 {"and", 0, PARAM_AL, PARAM_UI8, 0 },
\r
4924 {"and", 0, PARAM_AW, PARAM_IMM, 0 },
\r
4925 {"ds1:", SEG_DS1, 0, 0, 0 },
\r
4926 {"adj4a", 0, 0, 0, 0 },
\r
4927 {"sub", MODRM, PARAM_RM8, PARAM_REG8, 0 },
\r
4928 {"sub", MODRM, PARAM_RM16, PARAM_REG16, 0 },
\r
4929 {"sub", MODRM, PARAM_REG8, PARAM_RM8, 0 },
\r
4930 {"sub", MODRM, PARAM_REG16, PARAM_RM16, 0 },
\r
4931 {"sub", 0, PARAM_AL, PARAM_UI8, 0 },
\r
4932 {"sub", 0, PARAM_AW, PARAM_IMM, 0 },
\r
4933 {"ps:", SEG_PS, 0, 0, 0 },
\r
4934 {"adj4s", 0, 0, 0, 0 },
\r
4936 {"xor", MODRM, PARAM_RM8, PARAM_REG8, 0 },
\r
4937 {"xor", MODRM, PARAM_RM16, PARAM_REG16, 0 },
\r
4938 {"xor", MODRM, PARAM_REG8, PARAM_RM8, 0 },
\r
4939 {"xor", MODRM, PARAM_REG16, PARAM_RM16, 0 },
\r
4940 {"xor", 0, PARAM_AL, PARAM_UI8, 0 },
\r
4941 {"xor", 0, PARAM_AW, PARAM_IMM, 0 },
\r
4942 {"ss:", SEG_SS, 0, 0, 0 },
\r
4943 {"adjba", 0, 0, 0, 0 },
\r
4944 {"cmp", MODRM, PARAM_RM8, PARAM_REG8, 0 },
\r
4945 {"cmp", MODRM, PARAM_RM16, PARAM_REG16, 0 },
\r
4946 {"cmp", MODRM, PARAM_REG8, PARAM_RM8, 0 },
\r
4947 {"cmp", MODRM, PARAM_REG16, PARAM_RM16, 0 },
\r
4948 {"cmp", 0, PARAM_AL, PARAM_UI8, 0 },
\r
4949 {"cmp", 0, PARAM_AW, PARAM_IMM, 0 },
\r
4950 {"ds0:", SEG_DS0, 0, 0, 0 },
\r
4951 {"adjbs", 0, 0, 0, 0 },
\r
4953 {"inc", 0, PARAM_AW, 0, 0 },
\r
4954 {"inc", 0, PARAM_CW, 0, 0 },
\r
4955 {"inc", 0, PARAM_DW, 0, 0 },
\r
4956 {"inc", 0, PARAM_BW, 0, 0 },
\r
4957 {"inc", 0, PARAM_SP, 0, 0 },
\r
4958 {"inc", 0, PARAM_BP, 0, 0 },
\r
4959 {"inc", 0, PARAM_IX, 0, 0 },
\r
4960 {"inc", 0, PARAM_IY, 0, 0 },
\r
4961 {"dec", 0, PARAM_AW, 0, 0 },
\r
4962 {"dec", 0, PARAM_CW, 0, 0 },
\r
4963 {"dec", 0, PARAM_DW, 0, 0 },
\r
4964 {"dec", 0, PARAM_BW, 0, 0 },
\r
4965 {"dec", 0, PARAM_SP, 0, 0 },
\r
4966 {"dec", 0, PARAM_BP, 0, 0 },
\r
4967 {"dec", 0, PARAM_IX, 0, 0 },
\r
4968 {"dec", 0, PARAM_IY, 0, 0 },
\r
4970 {"push", 0, PARAM_AW, 0, 0 },
\r
4971 {"push", 0, PARAM_CW, 0, 0 },
\r
4972 {"push", 0, PARAM_DW, 0, 0 },
\r
4973 {"push", 0, PARAM_BW, 0, 0 },
\r
4974 {"push", 0, PARAM_SP, 0, 0 },
\r
4975 {"push", 0, PARAM_BP, 0, 0 },
\r
4976 {"push", 0, PARAM_IX, 0, 0 },
\r
4977 {"push", 0, PARAM_IY, 0, 0 },
\r
4978 {"pop", 0, PARAM_AW, 0, 0 },
\r
4979 {"pop", 0, PARAM_CW, 0, 0 },
\r
4980 {"pop", 0, PARAM_DW, 0, 0 },
\r
4981 {"pop", 0, PARAM_BW, 0, 0 },
\r
4982 {"pop", 0, PARAM_SP, 0, 0 },
\r
4983 {"pop", 0, PARAM_BP, 0, 0 },
\r
4984 {"pop", 0, PARAM_IX, 0, 0 },
\r
4985 {"pop", 0, PARAM_IY, 0, 0 },
\r
4987 {"push r", 0, 0, 0, 0 },
\r
4988 {"pop r", 0, 0, 0, 0 },
\r
4989 {"chkind", MODRM, PARAM_REG16, PARAM_RM16, 0 },
\r
4990 {"brkn", 0, PARAM_UI8, 0, 0, DASMFLAG_STEP_OVER}, /* V25S/V35S only */
\r
4991 {"repnc", PREFIX, 0, 0, 0 },
\r
4992 {"repc", PREFIX, 0, 0, 0 },
\r
4993 {"fpo2 0", 0, 0, 0, 0 }, /* for a coprocessor that was never made */
\r
4994 {"fpo2 1", 0, 0, 0, 0 }, /* for a coprocessor that was never made */
\r
4995 {"push", 0, PARAM_IMM, 0, 0 },
\r
4996 {"mul", MODRM, PARAM_REG16, PARAM_RM16, PARAM_IMM },
\r
4997 {"push", 0, PARAM_I8, 0, 0 },
\r
4998 {"mul", MODRM, PARAM_REG16, PARAM_RM16, PARAM_I8 },
\r
4999 {"inmb", 0, 0, 0, 0 },
\r
5000 {"inmw", 0, 0, 0, 0 },
\r
5001 {"outmb", 0, 0, 0, 0 },
\r
5002 {"outmw", 0, 0, 0, 0 },
\r
5004 {"bv", 0, PARAM_REL8, 0, 0 },
\r
5005 {"bnv", 0, PARAM_REL8, 0, 0 },
\r
5006 {"bc", 0, PARAM_REL8, 0, 0 },
\r
5007 {"bnc", 0, PARAM_REL8, 0, 0 },
\r
5008 {"be", 0, PARAM_REL8, 0, 0 },
\r
5009 {"bne", 0, PARAM_REL8, 0, 0 },
\r
5010 {"bnh", 0, PARAM_REL8, 0, 0 },
\r
5011 {"bh", 0, PARAM_REL8, 0, 0 },
\r
5012 {"bn", 0, PARAM_REL8, 0, 0 },
\r
5013 {"bp", 0, PARAM_REL8, 0, 0 },
\r
5014 {"bpe", 0, PARAM_REL8, 0, 0 },
\r
5015 {"bpo", 0, PARAM_REL8, 0, 0 },
\r
5016 {"blt", 0, PARAM_REL8, 0, 0 },
\r
5017 {"bge", 0, PARAM_REL8, 0, 0 },
\r
5018 {"ble", 0, PARAM_REL8, 0, 0 },
\r
5019 {"bgt", 0, PARAM_REL8, 0, 0 },
\r
5021 {"immb", GROUP, 0, 0, 0 },
\r
5022 {"immw", GROUP, 0, 0, 0 },
\r
5023 {"immb", GROUP, 0, 0, 0 },
\r
5024 {"immws", GROUP, 0, 0, 0 },
\r
5025 {"test", MODRM, PARAM_RM8, PARAM_REG8, 0 },
\r
5026 {"test", MODRM, PARAM_RM16, PARAM_REG16, 0 },
\r
5027 {"xch", MODRM, PARAM_REG8, PARAM_RM8, 0 },
\r
5028 {"xch", MODRM, PARAM_REG16, PARAM_RM16, 0 },
\r
5029 {"mov", MODRM, PARAM_RM8, PARAM_REG8, 0 },
\r
5030 {"mov", MODRM, PARAM_RM16, PARAM_REG16, 0 },
\r
5031 {"mov", MODRM, PARAM_REG8, PARAM_RM8, 0 },
\r
5032 {"mov", MODRM, PARAM_REG16, PARAM_RM16, 0 },
\r
5033 {"mov", MODRM, PARAM_RM16, PARAM_SREG, 0 },
\r
5034 {"ldea", MODRM, PARAM_REG16, PARAM_RM16, 0 },
\r
5035 {"mov", MODRM, PARAM_SREG, PARAM_RM16, 0 },
\r
5036 {"pop", MODRM, PARAM_RM16, 0, 0 },
\r
5038 {"nop", 0, 0, 0, 0 },
\r
5039 {"xch", 0, PARAM_AW, PARAM_CW, 0 },
\r
5040 {"xch", 0, PARAM_AW, PARAM_DW, 0 },
\r
5041 {"xch", 0, PARAM_AW, PARAM_BW, 0 },
\r
5042 {"xch", 0, PARAM_AW, PARAM_SP, 0 },
\r
5043 {"xch", 0, PARAM_AW, PARAM_BP, 0 },
\r
5044 {"xch", 0, PARAM_AW, PARAM_IX, 0 },
\r
5045 {"xch", 0, PARAM_AW, PARAM_IY, 0 },
\r
5046 {"cvtbw", 0, 0, 0, 0 },
\r
5047 {"cvtwl", 0, 0, 0, 0 },
\r
5048 {"call", 0, PARAM_ADDR, 0, 0, DASMFLAG_STEP_OVER},
\r
5049 {"poll", 0, 0, 0, 0 },
\r
5050 {"push psw", 0, 0, 0, 0 },
\r
5051 {"pop psw", 0, 0, 0, 0 },
\r
5052 {"mov psw,ah", 0, 0, 0, 0 },
\r
5053 {"mov ah,psw", 0, 0, 0, 0 },
\r
5055 {"mov", 0, PARAM_AL, PARAM_MEM_OFFS, 0 },
\r
5056 {"mov", 0, PARAM_AW, PARAM_MEM_OFFS, 0 },
\r
5057 {"mov", 0, PARAM_MEM_OFFS, PARAM_AL, 0 },
\r
5058 {"mov", 0, PARAM_MEM_OFFS, PARAM_AW, 0 },
\r
5059 {"movbkb", 0, 0, 0, 0 },
\r
5060 {"movbkw", 0, 0, 0, 0 },
\r
5061 {"cmpbkb", 0, 0, 0, 0 },
\r
5062 {"cmpbkw", 0, 0, 0, 0 },
\r
5063 {"test", 0, PARAM_AL, PARAM_UI8, 0 },
\r
5064 {"test", 0, PARAM_AW, PARAM_IMM, 0 },
\r
5065 {"stmb", 0, 0, 0, 0 },
\r
5066 {"stmw", 0, 0, 0, 0 },
\r
5067 {"ldmb", 0, 0, 0, 0 },
\r
5068 {"ldmw", 0, 0, 0, 0 },
\r
5069 {"cmpmb", 0, 0, 0, 0 },
\r
5070 {"cmpmw", 0, 0, 0, 0 },
\r
5072 {"mov", 0, PARAM_AL, PARAM_UI8, 0 },
\r
5073 {"mov", 0, PARAM_CL, PARAM_UI8, 0 },
\r
5074 {"mov", 0, PARAM_DL, PARAM_UI8, 0 },
\r
5075 {"mov", 0, PARAM_BL, PARAM_UI8, 0 },
\r
5076 {"mov", 0, PARAM_AH, PARAM_UI8, 0 },
\r
5077 {"mov", 0, PARAM_CH, PARAM_UI8, 0 },
\r
5078 {"mov", 0, PARAM_DH, PARAM_UI8, 0 },
\r
5079 {"mov", 0, PARAM_BH, PARAM_UI8, 0 },
\r
5080 {"mov", 0, PARAM_AW, PARAM_IMM, 0 },
\r
5081 {"mov", 0, PARAM_CW, PARAM_IMM, 0 },
\r
5082 {"mov", 0, PARAM_DW, PARAM_IMM, 0 },
\r
5083 {"mov", 0, PARAM_BW, PARAM_IMM, 0 },
\r
5084 {"mov", 0, PARAM_SP, PARAM_IMM, 0 },
\r
5085 {"mov", 0, PARAM_BP, PARAM_IMM, 0 },
\r
5086 {"mov", 0, PARAM_IX, PARAM_IMM, 0 },
\r
5087 {"mov", 0, PARAM_IY, PARAM_IMM, 0 },
\r
5089 {"shiftbi", GROUP, 0, 0, 0 },
\r
5090 {"shiftwi", GROUP, 0, 0, 0 },
\r
5091 {"ret", 0, PARAM_I16, 0, 0, DASMFLAG_STEP_OUT},
\r
5092 {"ret", 0, 0, 0, 0, DASMFLAG_STEP_OUT},
\r
5093 {"mov ds1,", MODRM, PARAM_REG16, PARAM_RM16, 0 },
\r
5094 {"mov ds0,", MODRM, PARAM_REG16, PARAM_RM16, 0 },
\r
5095 {"mov", MODRM, PARAM_RMPTR8, PARAM_UI8, 0 },
\r
5096 {"mov", MODRM, PARAM_RMPTR16, PARAM_IMM, 0 },
\r
5097 {"prepare", 0, PARAM_I16, PARAM_UI8, 0 },
\r
5098 {"dispose", 0, 0, 0, 0 },
\r
5099 {"retf", 0, PARAM_I16, 0, 0, DASMFLAG_STEP_OUT},
\r
5100 {"retf", 0, 0, 0, 0, DASMFLAG_STEP_OUT},
\r
5101 {"brk 3", 0, 0, 0, 0, DASMFLAG_STEP_OVER},
\r
5102 {"brk", 0, PARAM_UI8, 0, 0, DASMFLAG_STEP_OVER},
\r
5103 {"brkv", 0, 0, 0, 0 },
\r
5104 {"reti", 0, 0, 0, 0, DASMFLAG_STEP_OUT},
\r
5106 {"shiftb", GROUP, 0, 0, 0 },
\r
5107 {"shiftw", GROUP, 0, 0, 0 },
\r
5108 {"shiftbv", GROUP, 0, 0, 0 },
\r
5109 {"shiftwv", GROUP, 0, 0, 0 },
\r
5110 {"cvtbd", 0, PARAM_I8, 0, 0 },
\r
5111 {"cvtdb", 0, PARAM_I8, 0, 0 },
\r
5112 {"???", 0, 0, 0, 0 },
\r
5113 {"trans", 0, 0, 0, 0 },
\r
5114 {"escape", FPU, 0, 0, 0 },
\r
5115 {"escape", FPU, 0, 0, 0 },
\r
5116 {"escape", FPU, 0, 0, 0 },
\r
5117 {"escape", FPU, 0, 0, 0 },
\r
5118 {"escape", FPU, 0, 0, 0 },
\r
5119 {"escape", FPU, 0, 0, 0 },
\r
5120 {"escape", FPU, 0, 0, 0 },
\r
5121 {"escape", FPU, 0, 0, 0 },
\r
5123 {"dbnzne", 0, PARAM_REL8, 0, 0, DASMFLAG_STEP_OVER},
\r
5124 {"dbnze", 0, PARAM_REL8, 0, 0, DASMFLAG_STEP_OVER},
\r
5125 {"dbnz", 0, PARAM_REL8, 0, 0, DASMFLAG_STEP_OVER},
\r
5126 {"bcwz", 0, PARAM_REL8, 0, 0 },
\r
5127 {"in", 0, PARAM_AL, PARAM_UI8, 0 },
\r
5128 {"in", 0, PARAM_AW, PARAM_UI8, 0 },
\r
5129 {"out", 0, PARAM_UI8, PARAM_AL, 0 },
\r
5130 {"out", 0, PARAM_UI8, PARAM_AW, 0 },
\r
5131 {"call", 0, PARAM_REL16, 0, 0, DASMFLAG_STEP_OVER},
\r
5132 {"br", 0, PARAM_REL16, 0, 0 },
\r
5133 {"br", 0, PARAM_ADDR, 0, 0 },
\r
5134 {"br", 0, PARAM_REL8, 0, 0 },
\r
5135 {"in", 0, PARAM_AL, PARAM_DW, 0 },
\r
5136 {"in", 0, PARAM_AW, PARAM_DW, 0 },
\r
5137 {"out", 0, PARAM_DW, PARAM_AL, 0 },
\r
5138 {"out", 0, PARAM_DW, PARAM_AW, 0 },
\r
5140 {"buslock", PREFIX, 0, 0, 0 },
\r
5141 {"brks", 0, PARAM_UI8, 0, 0, DASMFLAG_STEP_OVER}, /* V25S/V35S only */
\r
5142 {"repne", PREFIX, 0, 0, 0 },
\r
5143 {"rep", PREFIX, 0, 0, 0 },
\r
5144 {"halt", 0, 0, 0, 0 },
\r
5145 {"not1 cy", 0, 0, 0, 0 },
\r
5146 {"group1b", GROUP, 0, 0, 0 },
\r
5147 {"group1w", GROUP, 0, 0, 0 },
\r
5148 {"clr1 cy", 0, 0, 0, 0 },
\r
5149 {"set1 cy", 0, 0, 0, 0 },
\r
5150 {"di", 0, 0, 0, 0 },
\r
5151 {"ei", 0, 0, 0, 0 },
\r
5152 {"clr1 dir", 0, 0, 0, 0 },
\r
5153 {"set1 dir", 0, 0, 0, 0 },
\r
5154 {"group2b", GROUP, 0, 0, 0 },
\r
5155 {"group2w", GROUP, 0, 0, 0 }
\r
5158 static const I386_OPCODE necv_opcode_table2[256] =
\r
5161 {"???", 0, 0, 0, 0 },
\r
5162 {"???", 0, 0, 0, 0 },
\r
5163 {"???", 0, 0, 0, 0 },
\r
5164 {"???", 0, 0, 0, 0 },
\r
5165 {"???", 0, 0, 0, 0 },
\r
5166 {"???", 0, 0, 0, 0 },
\r
5167 {"???", 0, 0, 0, 0 },
\r
5168 {"???", 0, 0, 0, 0 },
\r
5169 {"???", 0, 0, 0, 0 },
\r
5170 {"???", 0, 0, 0, 0 },
\r
5171 {"???", 0, 0, 0, 0 },
\r
5172 {"???", 0, 0, 0, 0 },
\r
5173 {"???", 0, 0, 0, 0 },
\r
5174 {"???", 0, 0, 0, 0 },
\r
5175 {"???", 0, 0, 0, 0 },
\r
5176 {"???", 0, 0, 0, 0 },
\r
5178 {"test1", MODRM, PARAM_RMPTR8, PARAM_CL, 0 },
\r
5179 {"test1", MODRM, PARAM_RMPTR16, PARAM_CL, 0 },
\r
5180 {"clr1", MODRM, PARAM_RMPTR8, PARAM_CL, 0 },
\r
5181 {"clr1", MODRM, PARAM_RMPTR16, PARAM_CL, 0 },
\r
5182 {"set1", MODRM, PARAM_RMPTR8, PARAM_CL, 0 },
\r
5183 {"set1", MODRM, PARAM_RMPTR16, PARAM_CL, 0 },
\r
5184 {"not1", MODRM, PARAM_RMPTR8, PARAM_CL, 0 },
\r
5185 {"not1", MODRM, PARAM_RMPTR16, PARAM_CL, 0 },
\r
5186 {"test1", MODRM, PARAM_RMPTR8, PARAM_I3, 0 },
\r
5187 {"test1", MODRM, PARAM_RMPTR16, PARAM_I4, 0 },
\r
5188 {"clr1", MODRM, PARAM_RMPTR8, PARAM_I3, 0 },
\r
5189 {"clr1", MODRM, PARAM_RMPTR16, PARAM_I4, 0 },
\r
5190 {"set1", MODRM, PARAM_RMPTR8, PARAM_I3, 0 },
\r
5191 {"set1", MODRM, PARAM_RMPTR16, PARAM_I4, 0 },
\r
5192 {"not1", MODRM, PARAM_RMPTR8, PARAM_I3, 0 },
\r
5193 {"not1", MODRM, PARAM_RMPTR16, PARAM_I4, 0 },
\r
5195 {"add4s", 0, 0, 0, 0 },
\r
5196 {"???", 0, 0, 0, 0 },
\r
5197 {"sub4s", 0, 0, 0, 0 },
\r
5198 {"???", 0, 0, 0, 0 },
\r
5199 {"???", 0, 0, 0, 0 },
\r
5200 {"movspa", 0, 0, 0, 0 }, /* V25/V35 only */
\r
5201 {"cmp4s", 0, 0, 0, 0 },
\r
5202 {"???", 0, 0, 0, 0 },
\r
5203 {"rol4", MODRM, PARAM_RMPTR8, 0, 0 },
\r
5204 {"???", 0, 0, 0, 0 },
\r
5205 {"ror4", MODRM, PARAM_RMPTR8, 0, 0 },
\r
5206 {"???", 0, 0, 0, 0 },
\r
5207 {"???", 0, 0, 0, 0 },
\r
5208 {"brkcs", MODRM, PARAM_REG2_16, 0, 0, DASMFLAG_STEP_OVER}, /* V25/V35 only */
\r
5209 {"???", 0, 0, 0, 0 },
\r
5210 {"???", 0, 0, 0, 0 },
\r
5212 {"???", 0, 0, 0, 0 },
\r
5213 {"ins", MODRM, PARAM_REG2_8, PARAM_REG8, 0 },
\r
5214 {"???", 0, 0, 0, 0 },
\r
5215 {"ext", MODRM, PARAM_REG2_8, PARAM_REG8, 0 },
\r
5216 {"???", 0, 0, 0, 0 },
\r
5217 {"???", 0, 0, 0, 0 },
\r
5218 {"???", 0, 0, 0, 0 },
\r
5219 {"???", 0, 0, 0, 0 },
\r
5220 {"???", 0, 0, 0, 0 },
\r
5221 {"ins", MODRM, PARAM_REG2_8, PARAM_I4, 0 },
\r
5222 {"???", 0, 0, 0, 0 },
\r
5223 {"ext", MODRM, PARAM_REG2_8, PARAM_I4, 0 },
\r
5224 {"???", 0, 0, 0, 0 },
\r
5225 {"???", 0, 0, 0, 0 },
\r
5226 {"???", 0, 0, 0, 0 },
\r
5227 {"???", 0, 0, 0, 0 },
\r
5229 {"???", 0, 0, 0, 0 },
\r
5230 {"???", 0, 0, 0, 0 },
\r
5231 {"???", 0, 0, 0, 0 },
\r
5232 {"???", 0, 0, 0, 0 },
\r
5233 {"???", 0, 0, 0, 0 },
\r
5234 {"???", 0, 0, 0, 0 },
\r
5235 {"???", 0, 0, 0, 0 },
\r
5236 {"???", 0, 0, 0, 0 },
\r
5237 {"???", 0, 0, 0, 0 },
\r
5238 {"???", 0, 0, 0, 0 },
\r
5239 {"???", 0, 0, 0, 0 },
\r
5240 {"???", 0, 0, 0, 0 },
\r
5241 {"???", 0, 0, 0, 0 },
\r
5242 {"???", 0, 0, 0, 0 },
\r
5243 {"???", 0, 0, 0, 0 },
\r
5244 {"???", 0, 0, 0, 0 },
\r
5246 {"???", 0, 0, 0, 0 },
\r
5247 {"???", 0, 0, 0, 0 },
\r
5248 {"???", 0, 0, 0, 0 },
\r
5249 {"???", 0, 0, 0, 0 },
\r
5250 {"???", 0, 0, 0, 0 },
\r
5251 {"???", 0, 0, 0, 0 },
\r
5252 {"???", 0, 0, 0, 0 },
\r
5253 {"???", 0, 0, 0, 0 },
\r
5254 {"???", 0, 0, 0, 0 },
\r
5255 {"???", 0, 0, 0, 0 },
\r
5256 {"???", 0, 0, 0, 0 },
\r
5257 {"???", 0, 0, 0, 0 },
\r
5258 {"???", 0, 0, 0, 0 },
\r
5259 {"???", 0, 0, 0, 0 },
\r
5260 {"???", 0, 0, 0, 0 },
\r
5261 {"???", 0, 0, 0, 0 },
\r
5263 {"???", 0, 0, 0, 0 },
\r
5264 {"???", 0, 0, 0, 0 },
\r
5265 {"???", 0, 0, 0, 0 },
\r
5266 {"???", 0, 0, 0, 0 },
\r
5267 {"???", 0, 0, 0, 0 },
\r
5268 {"???", 0, 0, 0, 0 },
\r
5269 {"???", 0, 0, 0, 0 },
\r
5270 {"???", 0, 0, 0, 0 },
\r
5271 {"???", 0, 0, 0, 0 },
\r
5272 {"???", 0, 0, 0, 0 },
\r
5273 {"???", 0, 0, 0, 0 },
\r
5274 {"???", 0, 0, 0, 0 },
\r
5275 {"???", 0, 0, 0, 0 },
\r
5276 {"???", 0, 0, 0, 0 },
\r
5277 {"???", 0, 0, 0, 0 },
\r
5278 {"???", 0, 0, 0, 0 },
\r
5280 {"???", 0, 0, 0, 0 },
\r
5281 {"???", 0, 0, 0, 0 },
\r
5282 {"???", 0, 0, 0, 0 },
\r
5283 {"???", 0, 0, 0, 0 },
\r
5284 {"???", 0, 0, 0, 0 },
\r
5285 {"???", 0, 0, 0, 0 },
\r
5286 {"???", 0, 0, 0, 0 },
\r
5287 {"???", 0, 0, 0, 0 },
\r
5288 {"???", 0, 0, 0, 0 },
\r
5289 {"???", 0, 0, 0, 0 },
\r
5290 {"???", 0, 0, 0, 0 },
\r
5291 {"???", 0, 0, 0, 0 },
\r
5292 {"???", 0, 0, 0, 0 },
\r
5293 {"???", 0, 0, 0, 0 },
\r
5294 {"???", 0, 0, 0, 0 },
\r
5295 {"???", 0, 0, 0, 0 },
\r
5297 {"???", 0, 0, 0, 0 },
\r
5298 {"???", 0, 0, 0, 0 },
\r
5299 {"???", 0, 0, 0, 0 },
\r
5300 {"???", 0, 0, 0, 0 },
\r
5301 {"???", 0, 0, 0, 0 },
\r
5302 {"???", 0, 0, 0, 0 },
\r
5303 {"???", 0, 0, 0, 0 },
\r
5304 {"???", 0, 0, 0, 0 },
\r
5305 {"???", 0, 0, 0, 0 },
\r
5306 {"???", 0, 0, 0, 0 },
\r
5307 {"???", 0, 0, 0, 0 },
\r
5308 {"???", 0, 0, 0, 0 },
\r
5309 {"???", 0, 0, 0, 0 },
\r
5310 {"???", 0, 0, 0, 0 },
\r
5311 {"???", 0, 0, 0, 0 },
\r
5312 {"???", 0, 0, 0, 0 },
\r
5314 {"???", 0, 0, 0, 0 },
\r
5315 {"retrbi", 0, 0, 0, 0 }, /* V25/V35 only */
\r
5316 {"fint", 0, 0, 0, 0 }, /* V25/V35 only */
\r
5317 {"???", 0, 0, 0, 0 },
\r
5318 {"tsksw", MODRM, PARAM_REG2_16, 0, 0 }, /* V25/V35 only */
\r
5319 {"movspb", MODRM, PARAM_REG2_16, 0, 0 }, /* V25/V35 only */
\r
5320 {"???", 0, 0, 0, 0 },
\r
5321 {"???", 0, 0, 0, 0 },
\r
5322 {"???", 0, 0, 0, 0 },
\r
5323 {"???", 0, 0, 0, 0 },
\r
5324 {"???", 0, 0, 0, 0 },
\r
5325 {"???", 0, 0, 0, 0 },
\r
5326 {"btclr", 0, PARAM_SFREG, PARAM_I3, PARAM_REL8 }, /* V25/V35 only */
\r
5327 {"???", 0, 0, 0, 0 },
\r
5328 {"stop", 0, 0, 0, 0 }, /* V25/V35 only */
\r
5329 {"???", 0, 0, 0, 0 },
\r
5331 {"???", 0, 0, 0, 0 },
\r
5332 {"???", 0, 0, 0, 0 },
\r
5333 {"???", 0, 0, 0, 0 },
\r
5334 {"???", 0, 0, 0, 0 },
\r
5335 {"???", 0, 0, 0, 0 },
\r
5336 {"???", 0, 0, 0, 0 },
\r
5337 {"???", 0, 0, 0, 0 },
\r
5338 {"???", 0, 0, 0, 0 },
\r
5339 {"???", 0, 0, 0, 0 },
\r
5340 {"???", 0, 0, 0, 0 },
\r
5341 {"???", 0, 0, 0, 0 },
\r
5342 {"???", 0, 0, 0, 0 },
\r
5343 {"???", 0, 0, 0, 0 },
\r
5344 {"???", 0, 0, 0, 0 },
\r
5345 {"???", 0, 0, 0, 0 },
\r
5346 {"???", 0, 0, 0, 0 },
\r
5348 {"???", 0, 0, 0, 0 },
\r
5349 {"???", 0, 0, 0, 0 },
\r
5350 {"???", 0, 0, 0, 0 },
\r
5351 {"???", 0, 0, 0, 0 },
\r
5352 {"???", 0, 0, 0, 0 },
\r
5353 {"???", 0, 0, 0, 0 },
\r
5354 {"???", 0, 0, 0, 0 },
\r
5355 {"???", 0, 0, 0, 0 },
\r
5356 {"???", 0, 0, 0, 0 },
\r
5357 {"???", 0, 0, 0, 0 },
\r
5358 {"???", 0, 0, 0, 0 },
\r
5359 {"???", 0, 0, 0, 0 },
\r
5360 {"???", 0, 0, 0, 0 },
\r
5361 {"???", 0, 0, 0, 0 },
\r
5362 {"???", 0, 0, 0, 0 },
\r
5363 {"???", 0, 0, 0, 0 },
\r
5365 {"???", 0, 0, 0, 0 },
\r
5366 {"???", 0, 0, 0, 0 },
\r
5367 {"???", 0, 0, 0, 0 },
\r
5368 {"???", 0, 0, 0, 0 },
\r
5369 {"???", 0, 0, 0, 0 },
\r
5370 {"???", 0, 0, 0, 0 },
\r
5371 {"???", 0, 0, 0, 0 },
\r
5372 {"???", 0, 0, 0, 0 },
\r
5373 {"???", 0, 0, 0, 0 },
\r
5374 {"???", 0, 0, 0, 0 },
\r
5375 {"???", 0, 0, 0, 0 },
\r
5376 {"???", 0, 0, 0, 0 },
\r
5377 {"???", 0, 0, 0, 0 },
\r
5378 {"???", 0, 0, 0, 0 },
\r
5379 {"???", 0, 0, 0, 0 },
\r
5380 {"???", 0, 0, 0, 0 },
\r
5382 {"???", 0, 0, 0, 0 },
\r
5383 {"???", 0, 0, 0, 0 },
\r
5384 {"???", 0, 0, 0, 0 },
\r
5385 {"???", 0, 0, 0, 0 },
\r
5386 {"???", 0, 0, 0, 0 },
\r
5387 {"???", 0, 0, 0, 0 },
\r
5388 {"???", 0, 0, 0, 0 },
\r
5389 {"???", 0, 0, 0, 0 },
\r
5390 {"???", 0, 0, 0, 0 },
\r
5391 {"???", 0, 0, 0, 0 },
\r
5392 {"???", 0, 0, 0, 0 },
\r
5393 {"???", 0, 0, 0, 0 },
\r
5394 {"???", 0, 0, 0, 0 },
\r
5395 {"???", 0, 0, 0, 0 },
\r
5396 {"???", 0, 0, 0, 0 },
\r
5397 {"???", 0, 0, 0, 0 },
\r
5399 {"brkxa", 0, PARAM_UI8, 0, 0 }, /* V33,53 only */
\r
5400 {"???", 0, 0, 0, 0 },
\r
5401 {"???", 0, 0, 0, 0 },
\r
5402 {"???", 0, 0, 0, 0 },
\r
5403 {"???", 0, 0, 0, 0 },
\r
5404 {"???", 0, 0, 0, 0 },
\r
5405 {"???", 0, 0, 0, 0 },
\r
5406 {"???", 0, 0, 0, 0 },
\r
5407 {"???", 0, 0, 0, 0 },
\r
5408 {"???", 0, 0, 0, 0 },
\r
5409 {"???", 0, 0, 0, 0 },
\r
5410 {"???", 0, 0, 0, 0 },
\r
5411 {"???", 0, 0, 0, 0 },
\r
5412 {"???", 0, 0, 0, 0 },
\r
5413 {"???", 0, 0, 0, 0 },
\r
5414 {"???", 0, 0, 0, 0 },
\r
5416 {"retxa", 0, PARAM_UI8, 0, 0 }, /* V33,53 only */
\r
5417 {"???", 0, 0, 0, 0 },
\r
5418 {"???", 0, 0, 0, 0 },
\r
5419 {"???", 0, 0, 0, 0 },
\r
5420 {"???", 0, 0, 0, 0 },
\r
5421 {"???", 0, 0, 0, 0 },
\r
5422 {"???", 0, 0, 0, 0 },
\r
5423 {"???", 0, 0, 0, 0 },
\r
5424 {"???", 0, 0, 0, 0 },
\r
5425 {"???", 0, 0, 0, 0 },
\r
5426 {"???", 0, 0, 0, 0 },
\r
5427 {"???", 0, 0, 0, 0 },
\r
5428 {"???", 0, 0, 0, 0 },
\r
5429 {"???", 0, 0, 0, 0 },
\r
5430 {"???", 0, 0, 0, 0 },
\r
5431 {"brkem", 0, PARAM_UI8, 0, 0 } /* V20,30,40,50 only */
\r
5434 static const I386_OPCODE immb_table[8] =
\r
5436 {"add", 0, PARAM_RMPTR8, PARAM_UI8, 0 },
\r
5437 {"or", 0, PARAM_RMPTR8, PARAM_UI8, 0 },
\r
5438 {"addc", 0, PARAM_RMPTR8, PARAM_UI8, 0 },
\r
5439 {"subc", 0, PARAM_RMPTR8, PARAM_UI8, 0 },
\r
5440 {"and", 0, PARAM_RMPTR8, PARAM_UI8, 0 },
\r
5441 {"sub", 0, PARAM_RMPTR8, PARAM_UI8, 0 },
\r
5442 {"xor", 0, PARAM_RMPTR8, PARAM_UI8, 0 },
\r
5443 {"cmp", 0, PARAM_RMPTR8, PARAM_UI8, 0 }
\r
5446 static const I386_OPCODE immw_table[8] =
\r
5448 {"add", 0, PARAM_RMPTR16, PARAM_IMM, 0 },
\r
5449 {"or", 0, PARAM_RMPTR16, PARAM_IMM, 0 },
\r
5450 {"addc", 0, PARAM_RMPTR16, PARAM_IMM, 0 },
\r
5451 {"subc", 0, PARAM_RMPTR16, PARAM_IMM, 0 },
\r
5452 {"and", 0, PARAM_RMPTR16, PARAM_IMM, 0 },
\r
5453 {"sub", 0, PARAM_RMPTR16, PARAM_IMM, 0 },
\r
5454 {"xor", 0, PARAM_RMPTR16, PARAM_IMM, 0 },
\r
5455 {"cmp", 0, PARAM_RMPTR16, PARAM_IMM, 0 }
\r
5458 static const I386_OPCODE immws_table[8] =
\r
5460 {"add", 0, PARAM_RMPTR16, PARAM_I8, 0 },
\r
5461 {"or", 0, PARAM_RMPTR16, PARAM_I8, 0 },
\r
5462 {"addc", 0, PARAM_RMPTR16, PARAM_I8, 0 },
\r
5463 {"subc", 0, PARAM_RMPTR16, PARAM_I8, 0 },
\r
5464 {"and", 0, PARAM_RMPTR16, PARAM_I8, 0 },
\r
5465 {"sub", 0, PARAM_RMPTR16, PARAM_I8, 0 },
\r
5466 {"xor", 0, PARAM_RMPTR16, PARAM_I8, 0 },
\r
5467 {"cmp", 0, PARAM_RMPTR16, PARAM_I8, 0 }
\r
5470 static const I386_OPCODE shiftbi_table[8] =
\r
5472 {"rol", 0, PARAM_RMPTR8, PARAM_I8, 0 },
\r
5473 {"ror", 0, PARAM_RMPTR8, PARAM_I8, 0 },
\r
5474 {"rolc", 0, PARAM_RMPTR8, PARAM_I8, 0 },
\r
5475 {"rorc", 0, PARAM_RMPTR8, PARAM_I8, 0 },
\r
5476 {"shl", 0, PARAM_RMPTR8, PARAM_I8, 0 },
\r
5477 {"shr", 0, PARAM_RMPTR8, PARAM_I8, 0 },
\r
5478 {"???", 0, PARAM_RMPTR8, PARAM_I8, 0 },
\r
5479 {"shra", 0, PARAM_RMPTR8, PARAM_I8, 0 }
\r
5482 static const I386_OPCODE shiftwi_table[8] =
\r
5484 {"rol", 0, PARAM_RMPTR16, PARAM_I8, 0 },
\r
5485 {"ror", 0, PARAM_RMPTR16, PARAM_I8, 0 },
\r
5486 {"rolc", 0, PARAM_RMPTR16, PARAM_I8, 0 },
\r
5487 {"rorc", 0, PARAM_RMPTR16, PARAM_I8, 0 },
\r
5488 {"shl", 0, PARAM_RMPTR16, PARAM_I8, 0 },
\r
5489 {"shr", 0, PARAM_RMPTR16, PARAM_I8, 0 },
\r
5490 {"???", 0, PARAM_RMPTR16, PARAM_I8, 0 },
\r
5491 {"shra", 0, PARAM_RMPTR16, PARAM_I8, 0 }
\r
5494 static const I386_OPCODE shiftb_table[8] =
\r
5496 {"rol", 0, PARAM_RMPTR8, PARAM_1, 0 },
\r
5497 {"ror", 0, PARAM_RMPTR8, PARAM_1, 0 },
\r
5498 {"rolc", 0, PARAM_RMPTR8, PARAM_1, 0 },
\r
5499 {"rorc", 0, PARAM_RMPTR8, PARAM_1, 0 },
\r
5500 {"shl", 0, PARAM_RMPTR8, PARAM_1, 0 },
\r
5501 {"shr", 0, PARAM_RMPTR8, PARAM_1, 0 },
\r
5502 {"???", 0, PARAM_RMPTR8, PARAM_1, 0 },
\r
5503 {"shra", 0, PARAM_RMPTR8, PARAM_1, 0 }
\r
5506 static const I386_OPCODE shiftw_table[8] =
\r
5508 {"rol", 0, PARAM_RMPTR16, PARAM_1, 0 },
\r
5509 {"ror", 0, PARAM_RMPTR16, PARAM_1, 0 },
\r
5510 {"rolc", 0, PARAM_RMPTR16, PARAM_1, 0 },
\r
5511 {"rorc", 0, PARAM_RMPTR16, PARAM_1, 0 },
\r
5512 {"shl", 0, PARAM_RMPTR16, PARAM_1, 0 },
\r
5513 {"shr", 0, PARAM_RMPTR16, PARAM_1, 0 },
\r
5514 {"???", 0, PARAM_RMPTR16, PARAM_1, 0 },
\r
5515 {"shra", 0, PARAM_RMPTR16, PARAM_1, 0 }
\r
5518 static const I386_OPCODE shiftbv_table[8] =
\r
5520 {"rol", 0, PARAM_RMPTR8, PARAM_CL, 0 },
\r
5521 {"ror", 0, PARAM_RMPTR8, PARAM_CL, 0 },
\r
5522 {"rolc", 0, PARAM_RMPTR8, PARAM_CL, 0 },
\r
5523 {"rorc", 0, PARAM_RMPTR8, PARAM_CL, 0 },
\r
5524 {"shl", 0, PARAM_RMPTR8, PARAM_CL, 0 },
\r
5525 {"shr", 0, PARAM_RMPTR8, PARAM_CL, 0 },
\r
5526 {"???", 0, PARAM_RMPTR8, PARAM_CL, 0 },
\r
5527 {"shra", 0, PARAM_RMPTR8, PARAM_CL, 0 }
\r
5530 static const I386_OPCODE shiftwv_table[8] =
\r
5532 {"rol", 0, PARAM_RMPTR16, PARAM_CL, 0 },
\r
5533 {"ror", 0, PARAM_RMPTR16, PARAM_CL, 0 },
\r
5534 {"rolc", 0, PARAM_RMPTR16, PARAM_CL, 0 },
\r
5535 {"rorc", 0, PARAM_RMPTR16, PARAM_CL, 0 },
\r
5536 {"shl", 0, PARAM_RMPTR16, PARAM_CL, 0 },
\r
5537 {"shr", 0, PARAM_RMPTR16, PARAM_CL, 0 },
\r
5538 {"???", 0, PARAM_RMPTR16, PARAM_CL, 0 },
\r
5539 {"shra", 0, PARAM_RMPTR16, PARAM_CL, 0 }
\r
5542 static const I386_OPCODE group1b_table[8] =
\r
5544 {"test", 0, PARAM_RMPTR8, PARAM_UI8, 0 },
\r
5545 {"???", 0, 0, 0, 0 },
\r
5546 {"not", 0, PARAM_RMPTR8, 0, 0 },
\r
5547 {"neg", 0, PARAM_RMPTR8, 0, 0 },
\r
5548 {"mulu", 0, PARAM_RMPTR8, 0, 0 },
\r
5549 {"mul", 0, PARAM_RMPTR8, 0, 0 },
\r
5550 {"divu", 0, PARAM_RMPTR8, 0, 0 },
\r
5551 {"div", 0, PARAM_RMPTR8, 0, 0 }
\r
5554 static const I386_OPCODE group1w_table[8] =
\r
5556 {"test", 0, PARAM_RMPTR16, PARAM_IMM, 0 },
\r
5557 {"???", 0, 0, 0, 0 },
\r
5558 {"not", 0, PARAM_RMPTR16, 0, 0 },
\r
5559 {"neg", 0, PARAM_RMPTR16, 0, 0 },
\r
5560 {"mulu", 0, PARAM_RMPTR16, 0, 0 },
\r
5561 {"mul", 0, PARAM_RMPTR16, 0, 0 },
\r
5562 {"divu", 0, PARAM_RMPTR16, 0, 0 },
\r
5563 {"div", 0, PARAM_RMPTR16, 0, 0 }
\r
5566 static const I386_OPCODE group2b_table[8] =
\r
5568 {"inc", 0, PARAM_RMPTR8, 0, 0 },
\r
5569 {"dec", 0, PARAM_RMPTR8, 0, 0 },
\r
5570 {"???", 0, 0, 0, 0 },
\r
5571 {"???", 0, 0, 0, 0 },
\r
5572 {"???", 0, 0, 0, 0 },
\r
5573 {"???", 0, 0, 0, 0 },
\r
5574 {"???", 0, 0, 0, 0 },
\r
5575 {"???", 0, 0, 0, 0 }
\r
5578 static const I386_OPCODE group2w_table[8] =
\r
5580 {"inc", 0, PARAM_RMPTR16, 0, 0 },
\r
5581 {"dec", 0, PARAM_RMPTR16, 0, 0 },
\r
5582 {"call", 0, PARAM_RMPTR16, 0, 0, DASMFLAG_STEP_OVER},
\r
5583 {"call far ptr ",0, PARAM_RM16, 0, 0, DASMFLAG_STEP_OVER},
\r
5584 {"br", 0, PARAM_RMPTR16, 0, 0 },
\r
5585 {"br far ptr ",0, PARAM_RM16, 0, 0 },
\r
5586 {"push", 0, PARAM_RMPTR16, 0, 0 },
\r
5587 {"???", 0, 0, 0, 0 }
\r
5590 static const GROUP_OP group_op_table[] =
\r
5592 { "immb", immb_table },
\r
5593 { "immw", immw_table },
\r
5594 { "immws", immws_table },
\r
5595 { "shiftbi", shiftbi_table },
\r
5596 { "shiftwi", shiftwi_table },
\r
5597 { "shiftb", shiftb_table },
\r
5598 { "shiftw", shiftw_table },
\r
5599 { "shiftbv", shiftbv_table },
\r
5600 { "shiftwv", shiftwv_table },
\r
5601 { "group1b", group1b_table },
\r
5602 { "group1w", group1w_table },
\r
5603 { "group2b", group2b_table },
\r
5604 { "group2w", group2w_table }
\r
5609 static const char *const nec_reg[8] = { "aw", "cw", "dw", "bw", "sp", "bp", "ix", "iy" };
\r
5610 static const char *const nec_reg8[8] = { "al", "cl", "dl", "bl", "ah", "ch", "dh", "bh" };
\r
5611 static const char *const nec_sreg[8] = { "ds1", "ps", "ss", "ds0", "???", "???", "???", "???" };
\r
5612 static const char *const nec_sfreg[256] =
\r
5615 "p0", "pm0", "pmc0", "???", "???", "???", "???", "???",
\r
5616 "p1", "pm1", "pmc1", "???", "???", "???", "???", "???",
\r
5618 "p2", "pm2", "pmc2", "???", "???", "???", "???", "???",
\r
5619 "???", "???", "???", "???", "???", "???", "???", "???",
\r
5621 "???", "???", "???", "???", "???", "???", "???", "???",
\r
5622 "???", "???", "???", "???", "???", "???", "???", "???",
\r
5624 "???", "???", "???", "???", "???", "???", "???", "???",
\r
5625 "pt", "???", "???", "pmt", "???", "???", "???", "???",
\r
5627 "intm", "???", "???", "???", "ems0", "ems1", "ems2", "???",
\r
5628 "???", "???", "???", "???", "exic0","exic1","exic2","???",
\r
5630 "???", "???", "???", "???", "???", "???", "???", "???",
\r
5631 "???", "???", "???", "???", "???", "???", "???", "???",
\r
5633 "rxb0", "???", "txb0", "???", "???", "srms0","stms0","???",
\r
5634 "scm0", "scc0", "brg0", "scs0", "seic0","sric0","stic0","???",
\r
5636 "rxb1", "???", "txb1", "???", "???", "srms1","stms1","???",
\r
5637 "scm1", "scc1", "brg1", "scs1", "seic1","sric1","stic1","???",
\r
5639 "tm0", "???", "md0", "???", "???", "???", "???", "???",
\r
5640 "tm1", "???", "md1", "???", "???", "???", "???", "???",
\r
5642 "tmc0", "tmc1", "???", "???", "tmms0","tmms1","tmms2","???",
\r
5643 "???", "???", "???", "???", "tmic0","tmic1","tmic2","???",
\r
5645 "dmac0","dmam0","dmac1","dmam1","???", "???", "???", "???",
\r
5646 "???", "???", "???", "???", "dic0", "dic1", "???", "???",
\r
5648 "???", "???", "???", "???", "???", "???", "???", "???",
\r
5649 "???", "???", "???", "???", "???", "???", "???", "???",
\r
5651 "sar0l","sar0m","sar0h","???", "dar0l","dar0m","dar0h","???",
\r
5652 "tc0l", "tc0h", "???", "???", "???", "???", "???", "???",
\r
5654 "sar1l","sar1m","sar1h","???", "dar1l","dar1m","dar1h","???",
\r
5655 "tc1l", "tc1h", "???", "???", "???", "???", "???", "???",
\r
5657 "stbc", "rfm", "???", "???", "???", "???", "???", "???",
\r
5658 "wtc", "???", "flag", "prc", "tbic", "???", "???", "irqs",
\r
5660 "???", "???", "???", "???", "???", "???", "???", "???",
\r
5661 "???", "???", "???", "???", "ispr", "???", "???", "idb"
\r
5665 static UINT8 modrm;
\r
5666 static UINT32 segment;
\r
5667 static offs_t dasm_flags;
\r
5668 static char modrm_string[256];
\r
5670 #define MODRM_REG1 ((modrm >> 3) & 0x7)
\r
5671 #define MODRM_REG2 (modrm & 0x7)
\r
5673 #define MAX_LENGTH 8
\r
5675 INLINE UINT8 FETCHD(void)
\r
5677 if ((opcode_ptr - opcode_ptr_base) + 1 > MAX_LENGTH)
\r
5680 return *opcode_ptr++;
\r
5683 INLINE UINT16 FETCHD16(void)
\r
5686 if ((opcode_ptr - opcode_ptr_base) + 2 > MAX_LENGTH)
\r
5688 d = opcode_ptr[0] | (opcode_ptr[1] << 8);
\r
5694 static char *hexstring(UINT32 value, int digits)
\r
5696 static char buffer[20];
\r
5699 sprintf(&buffer[1], "%0*Xh", digits, value);
\r
5701 sprintf(&buffer[1], "%Xh", value);
\r
5703 return (buffer[1] >= '0' && buffer[1] <= '9') ? &buffer[1] : &buffer[0];
\r
5706 static char *shexstring(UINT32 value, int digits, int always)
\r
5708 static char buffer[20];
\r
5709 if (value >= 0x80000000) {
\r
5710 sprintf(buffer, "-%s", hexstring(-value, digits));
\r
5711 } else if (always) {
\r
5712 sprintf(buffer, "+%s", hexstring(value, digits));
\r
5714 return hexstring(value, digits);
\r
5719 static void handle_modrm(char* s)
\r
5726 mod = (modrm >> 6) & 0x3;
\r
5727 rm = (modrm & 0x7);
\r
5729 if( modrm >= 0xc0 )
\r
5734 case SEG_PS: s += sprintf( s, "ps:" ); break;
\r
5735 case SEG_DS0: s += sprintf( s, "ds0:" ); break;
\r
5736 case SEG_DS1: s += sprintf( s, "ds1:" ); break;
\r
5737 case SEG_SS: s += sprintf( s, "ss:" ); break;
\r
5740 s += sprintf( s, "[" );
\r
5743 case 0: s += sprintf( s, "bw+ix" ); break;
\r
5744 case 1: s += sprintf( s, "bw+iy" ); break;
\r
5745 case 2: s += sprintf( s, "bp+ix" ); break;
\r
5746 case 3: s += sprintf( s, "bp+iy" ); break;
\r
5747 case 4: s += sprintf( s, "ix" ); break;
\r
5748 case 5: s += sprintf( s, "iy" ); break;
\r
5751 disp16 = FETCHD16();
\r
5752 s += sprintf( s, "%s", hexstring((unsigned) (UINT16) disp16, 0) );
\r
5754 s += sprintf( s, "bp" );
\r
5757 case 7: s += sprintf( s, "bw" ); break;
\r
5761 s += sprintf( s, "%s", shexstring((INT32)disp8, 0, TRUE) );
\r
5762 } else if( mod == 2 ) {
\r
5763 disp16 = FETCHD16();
\r
5764 s += sprintf( s, "%s", shexstring((INT32)disp16, 0, TRUE) );
\r
5766 s += sprintf( s, "]" );
\r
5769 static char* handle_param(char* s, UINT32 param)
\r
5781 s += sprintf( s, "%s", nec_reg8[MODRM_REG1] );
\r
5785 s += sprintf( s, "%s", nec_reg[MODRM_REG1] );
\r
5788 case PARAM_REG2_8:
\r
5789 s += sprintf( s, "%s", nec_reg8[MODRM_REG2] );
\r
5792 case PARAM_REG2_16:
\r
5793 s += sprintf( s, "%s", nec_reg[MODRM_REG2] );
\r
5797 case PARAM_RMPTR8:
\r
5798 if( modrm >= 0xc0 ) {
\r
5799 s += sprintf( s, "%s", nec_reg8[MODRM_REG2] );
\r
5801 if (param == PARAM_RMPTR8)
\r
5802 s += sprintf( s, "byte ptr " );
\r
5803 s += sprintf( s, "%s", modrm_string );
\r
5808 case PARAM_RMPTR16:
\r
5809 if( modrm >= 0xc0 ) {
\r
5810 s += sprintf( s, "%s", nec_reg[MODRM_REG2] );
\r
5812 if (param == PARAM_RMPTR16)
\r
5813 s += sprintf( s, "word ptr " );
\r
5814 s += sprintf( s, "%s", modrm_string );
\r
5820 s += sprintf( s, "%d", i8 & 0x07 );
\r
5825 s += sprintf( s, "%d", i8 & 0x0f );
\r
5830 s += sprintf( s, "%s", shexstring((INT8)i8, 0, FALSE) );
\r
5835 s += sprintf( s, "%s", shexstring((INT16)i16, 0, FALSE) );
\r
5840 s += sprintf( s, "%s", shexstring((UINT8)i8, 0, FALSE) );
\r
5845 s += sprintf( s, "%s", hexstring(i16, 0) );
\r
5849 addr = FETCHD16();
\r
5851 s += sprintf( s, "%s:", hexstring(ptr, 4) );
\r
5852 s += sprintf( s, "%s", hexstring(addr, 0) );
\r
5856 /* make sure to keep the relative offset within the segment */
\r
5858 s += sprintf( s, "%s", hexstring((pc & 0xFFFF0000) | ((pc + d16) & 0x0000FFFF), 0) );
\r
5863 s += sprintf( s, "%s", hexstring(pc + d8, 0) );
\r
5866 case PARAM_MEM_OFFS:
\r
5869 case SEG_PS: s += sprintf( s, "ps:" ); break;
\r
5870 case SEG_DS0: s += sprintf( s, "ds0:" ); break;
\r
5871 case SEG_DS1: s += sprintf( s, "ds1:" ); break;
\r
5872 case SEG_SS: s += sprintf( s, "ss:" ); break;
\r
5876 s += sprintf( s, "[%s]", hexstring(i16, 0) );
\r
5880 s += sprintf( s, "%s", nec_sreg[MODRM_REG1] );
\r
5885 s += sprintf( s, "%s", nec_sfreg[i8] );
\r
5889 s += sprintf( s, "1" );
\r
5892 case PARAM_AL: s += sprintf( s, "al" ); break;
\r
5893 case PARAM_CL: s += sprintf( s, "cl" ); break;
\r
5894 case PARAM_DL: s += sprintf( s, "dl" ); break;
\r
5895 case PARAM_BL: s += sprintf( s, "bl" ); break;
\r
5896 case PARAM_AH: s += sprintf( s, "ah" ); break;
\r
5897 case PARAM_CH: s += sprintf( s, "ch" ); break;
\r
5898 case PARAM_DH: s += sprintf( s, "dh" ); break;
\r
5899 case PARAM_BH: s += sprintf( s, "bh" ); break;
\r
5901 case PARAM_AW: s += sprintf( s, "aw" ); break;
\r
5902 case PARAM_CW: s += sprintf( s, "cw" ); break;
\r
5903 case PARAM_DW: s += sprintf( s, "dw" ); break;
\r
5904 case PARAM_BW: s += sprintf( s, "bw" ); break;
\r
5905 case PARAM_SP: s += sprintf( s, "sp" ); break;
\r
5906 case PARAM_BP: s += sprintf( s, "bp" ); break;
\r
5907 case PARAM_IX: s += sprintf( s, "ix" ); break;
\r
5908 case PARAM_IY: s += sprintf( s, "iy" ); break;
\r
5913 static void handle_fpu(char *s, UINT8 op1, UINT8 op2)
\r
5915 switch (op1 & 0x7)
\r
5917 case 0: // Group D8
\r
5921 pc--; // adjust fetch pointer, so modrm byte read again
\r
5923 handle_modrm( modrm_string );
\r
5924 switch ((op2 >> 3) & 0x7)
\r
5926 case 0: sprintf(s, "fadd dword ptr %s", modrm_string); break;
\r
5927 case 1: sprintf(s, "fmul dword ptr %s", modrm_string); break;
\r
5928 case 2: sprintf(s, "fcom dword ptr %s", modrm_string); break;
\r
5929 case 3: sprintf(s, "fcomp dword ptr %s", modrm_string); break;
\r
5930 case 4: sprintf(s, "fsub dword ptr %s", modrm_string); break;
\r
5931 case 5: sprintf(s, "fsubr dword ptr %s", modrm_string); break;
\r
5932 case 6: sprintf(s, "fdiv dword ptr %s", modrm_string); break;
\r
5933 case 7: sprintf(s, "fdivr dword ptr %s", modrm_string); break;
\r
5936 switch ((op2 >> 3) & 0x7)
\r
5938 case 0: sprintf(s, "fadd st(0),st(%d)", op2 & 0x7); break;
\r
5939 case 1: sprintf(s, "fcom st(0),st(%d)", op2 & 0x7); break;
\r
5940 case 2: sprintf(s, "fsub st(0),st(%d)", op2 & 0x7); break;
\r
5941 case 3: sprintf(s, "fdiv st(0),st(%d)", op2 & 0x7); break;
\r
5942 case 4: sprintf(s, "fmul st(0),st(%d)", op2 & 0x7); break;
\r
5943 case 5: sprintf(s, "fcomp st(0),st(%d)", op2 & 0x7); break;
\r
5944 case 6: sprintf(s, "fsubr st(0),st(%d)", op2 & 0x7); break;
\r
5945 case 7: sprintf(s, "fdivr st(0),st(%d)", op2 & 0x7); break;
\r
5951 case 1: // Group D9
\r
5955 pc--; // adjust fetch pointer, so modrm byte read again
\r
5957 handle_modrm( modrm_string );
\r
5958 switch ((op2 >> 3) & 0x7)
\r
5960 case 0: sprintf(s, "fld dword ptr %s", modrm_string); break;
\r
5961 case 1: sprintf(s, "??? (FPU)"); break;
\r
5962 case 2: sprintf(s, "fst dword ptr %s", modrm_string); break;
\r
5963 case 3: sprintf(s, "fstp dword ptr %s", modrm_string); break;
\r
5964 case 4: sprintf(s, "fldenv word ptr %s", modrm_string); break;
\r
5965 case 5: sprintf(s, "fldcw word ptr %s", modrm_string); break;
\r
5966 case 6: sprintf(s, "fstenv word ptr %s", modrm_string); break;
\r
5967 case 7: sprintf(s, "fstcw word ptr %s", modrm_string); break;
\r
5970 switch (op2 & 0x3f)
\r
5972 case 0x00: case 0x01: case 0x02: case 0x03: case 0x04: case 0x05: case 0x06: case 0x07:
\r
5973 sprintf(s, "fld st(0),st(%d)", op2 & 0x7); break;
\r
5975 case 0x08: case 0x09: case 0x0a: case 0x0b: case 0x0c: case 0x0d: case 0x0e: case 0x0f:
\r
5976 sprintf(s, "fxch st(0),st(%d)", op2 & 0x7); break;
\r
5978 case 0x10: sprintf(s, "fnop"); break;
\r
5979 case 0x20: sprintf(s, "fchs"); break;
\r
5980 case 0x21: sprintf(s, "fabs"); break;
\r
5981 case 0x24: sprintf(s, "ftst"); break;
\r
5982 case 0x25: sprintf(s, "fxam"); break;
\r
5983 case 0x28: sprintf(s, "fld1"); break;
\r
5984 case 0x29: sprintf(s, "fldl2t"); break;
\r
5985 case 0x2a: sprintf(s, "fldl2e"); break;
\r
5986 case 0x2b: sprintf(s, "fldpi"); break;
\r
5987 case 0x2c: sprintf(s, "fldlg2"); break;
\r
5988 case 0x2d: sprintf(s, "fldln2"); break;
\r
5989 case 0x2e: sprintf(s, "fldz"); break;
\r
5990 case 0x30: sprintf(s, "f2xm1"); break;
\r
5991 case 0x31: sprintf(s, "fyl2x"); break;
\r
5992 case 0x32: sprintf(s, "fptan"); break;
\r
5993 case 0x33: sprintf(s, "fpatan"); break;
\r
5994 case 0x34: sprintf(s, "fxtract"); break;
\r
5995 case 0x35: sprintf(s, "fprem1"); break;
\r
5996 case 0x36: sprintf(s, "fdecstp"); break;
\r
5997 case 0x37: sprintf(s, "fincstp"); break;
\r
5998 case 0x38: sprintf(s, "fprem"); break;
\r
5999 case 0x39: sprintf(s, "fyl2xp1"); break;
\r
6000 case 0x3a: sprintf(s, "fsqrt"); break;
\r
6001 case 0x3b: sprintf(s, "fsincos"); break;
\r
6002 case 0x3c: sprintf(s, "frndint"); break;
\r
6003 case 0x3d: sprintf(s, "fscale"); break;
\r
6004 case 0x3e: sprintf(s, "fsin"); break;
\r
6005 case 0x3f: sprintf(s, "fcos"); break;
\r
6007 default: sprintf(s, "??? (FPU)"); break;
\r
6013 case 2: // Group DA
\r
6017 pc--; // adjust fetch pointer, so modrm byte read again
\r
6019 handle_modrm( modrm_string );
\r
6020 switch ((op2 >> 3) & 0x7)
\r
6022 case 0: sprintf(s, "fiadd dword ptr %s", modrm_string); break;
\r
6023 case 1: sprintf(s, "fimul dword ptr %s", modrm_string); break;
\r
6024 case 2: sprintf(s, "ficom dword ptr %s", modrm_string); break;
\r
6025 case 3: sprintf(s, "ficomp dword ptr %s", modrm_string); break;
\r
6026 case 4: sprintf(s, "fisub dword ptr %s", modrm_string); break;
\r
6027 case 5: sprintf(s, "fisubr dword ptr %s", modrm_string); break;
\r
6028 case 6: sprintf(s, "fidiv dword ptr %s", modrm_string); break;
\r
6029 case 7: sprintf(s, "fidivr dword ptr %s", modrm_string); break;
\r
6032 switch (op2 & 0x3f)
\r
6034 case 0x00: case 0x01: case 0x02: case 0x03: case 0x04: case 0x05: case 0x06: case 0x07:
\r
6035 sprintf(s, "fcmovb st(0),st(%d)", op2 & 0x7); break;
\r
6037 case 0x08: case 0x09: case 0x0a: case 0x0b: case 0x0c: case 0x0d: case 0x0e: case 0x0f:
\r
6038 sprintf(s, "fcmove st(0),st(%d)", op2 & 0x7); break;
\r
6040 case 0x10: case 0x11: case 0x12: case 0x13: case 0x14: case 0x15: case 0x16: case 0x17:
\r
6041 sprintf(s, "fcmovbe st(0),st(%d)", op2 & 0x7); break;
\r
6043 case 0x18: case 0x19: case 0x1a: case 0x1b: case 0x1c: case 0x1d: case 0x1e: case 0x1f:
\r
6044 sprintf(s, "fcmovu st(0),st(%d)", op2 & 0x7); break;
\r
6046 default: sprintf(s, "??? (FPU)"); break;
\r
6053 case 3: // Group DB
\r
6057 pc--; // adjust fetch pointer, so modrm byte read again
\r
6059 handle_modrm( modrm_string );
\r
6060 switch ((op2 >> 3) & 0x7)
\r
6062 case 0: sprintf(s, "fild dword ptr %s", modrm_string); break;
\r
6063 case 1: sprintf(s, "??? (FPU)"); break;
\r
6064 case 2: sprintf(s, "fist dword ptr %s", modrm_string); break;
\r
6065 case 3: sprintf(s, "fistp dword ptr %s", modrm_string); break;
\r
6066 case 4: sprintf(s, "??? (FPU)"); break;
\r
6067 case 5: sprintf(s, "fld tword ptr %s", modrm_string); break;
\r
6068 case 6: sprintf(s, "??? (FPU)"); break;
\r
6069 case 7: sprintf(s, "fstp tword ptr %s", modrm_string); break;
\r
6072 switch (op2 & 0x3f)
\r
6074 case 0x00: case 0x01: case 0x02: case 0x03: case 0x04: case 0x05: case 0x06: case 0x07:
\r
6075 sprintf(s, "fcmovnb st(0),st(%d)", op2 & 0x7); break;
\r
6077 case 0x08: case 0x09: case 0x0a: case 0x0b: case 0x0c: case 0x0d: case 0x0e: case 0x0f:
\r
6078 sprintf(s, "fcmovne st(0),st(%d)", op2 & 0x7); break;
\r
6080 case 0x10: case 0x11: case 0x12: case 0x13: case 0x14: case 0x15: case 0x16: case 0x17:
\r
6081 sprintf(s, "fcmovnbe st(0),st(%d)", op2 & 0x7); break;
\r
6083 case 0x18: case 0x19: case 0x1a: case 0x1b: case 0x1c: case 0x1d: case 0x1e: case 0x1f:
\r
6084 sprintf(s, "fcmovnu st(0),st(%d)", op2 & 0x7); break;
\r
6086 case 0x22: sprintf(s, "fclex"); break;
\r
6087 case 0x23: sprintf(s, "finit"); break;
\r
6089 case 0x28: case 0x29: case 0x2a: case 0x2b: case 0x2c: case 0x2d: case 0x2e: case 0x2f:
\r
6090 sprintf(s, "fucomi st(0),st(%d)", op2 & 0x7); break;
\r
6092 case 0x30: case 0x31: case 0x32: case 0x33: case 0x34: case 0x35: case 0x36: case 0x37:
\r
6093 sprintf(s, "fcomi st(0),st(%d)", op2 & 0x7); break;
\r
6095 default: sprintf(s, "??? (FPU)"); break;
\r
6101 case 4: // Group DC
\r
6105 pc--; // adjust fetch pointer, so modrm byte read again
\r
6107 handle_modrm( modrm_string );
\r
6108 switch ((op2 >> 3) & 0x7)
\r
6110 case 0: sprintf(s, "fadd qword ptr %s", modrm_string); break;
\r
6111 case 1: sprintf(s, "fmul qword ptr %s", modrm_string); break;
\r
6112 case 2: sprintf(s, "fcom qword ptr %s", modrm_string); break;
\r
6113 case 3: sprintf(s, "fcomp qword ptr %s", modrm_string); break;
\r
6114 case 4: sprintf(s, "fsub qword ptr %s", modrm_string); break;
\r
6115 case 5: sprintf(s, "fsubr qword ptr %s", modrm_string); break;
\r
6116 case 6: sprintf(s, "fdiv qword ptr %s", modrm_string); break;
\r
6117 case 7: sprintf(s, "fdivr qword ptr %s", modrm_string); break;
\r
6120 switch (op2 & 0x3f)
\r
6122 case 0x00: case 0x01: case 0x02: case 0x03: case 0x04: case 0x05: case 0x06: case 0x07:
\r
6123 sprintf(s, "fadd st(%d),st(0)", op2 & 0x7); break;
\r
6125 case 0x08: case 0x09: case 0x0a: case 0x0b: case 0x0c: case 0x0d: case 0x0e: case 0x0f:
\r
6126 sprintf(s, "fmul st(%d),st(0)", op2 & 0x7); break;
\r
6128 case 0x20: case 0x21: case 0x22: case 0x23: case 0x24: case 0x25: case 0x26: case 0x27:
\r
6129 sprintf(s, "fsubr st(%d),st(0)", op2 & 0x7); break;
\r
6131 case 0x28: case 0x29: case 0x2a: case 0x2b: case 0x2c: case 0x2d: case 0x2e: case 0x2f:
\r
6132 sprintf(s, "fsub st(%d),st(0)", op2 & 0x7); break;
\r
6134 case 0x30: case 0x31: case 0x32: case 0x33: case 0x34: case 0x35: case 0x36: case 0x37:
\r
6135 sprintf(s, "fdivr st(%d),st(0)", op2 & 0x7); break;
\r
6137 case 0x38: case 0x39: case 0x3a: case 0x3b: case 0x3c: case 0x3d: case 0x3e: case 0x3f:
\r
6138 sprintf(s, "fdiv st(%d),st(0)", op2 & 0x7); break;
\r
6140 default: sprintf(s, "??? (FPU)"); break;
\r
6146 case 5: // Group DD
\r
6150 pc--; // adjust fetch pointer, so modrm byte read again
\r
6152 handle_modrm( modrm_string );
\r
6153 switch ((op2 >> 3) & 0x7)
\r
6155 case 0: sprintf(s, "fld qword ptr %s", modrm_string); break;
\r
6156 case 1: sprintf(s, "??? (FPU)"); break;
\r
6157 case 2: sprintf(s, "fst qword ptr %s", modrm_string); break;
\r
6158 case 3: sprintf(s, "fstp qword ptr %s", modrm_string); break;
\r
6159 case 4: sprintf(s, "frstor %s", modrm_string); break;
\r
6160 case 5: sprintf(s, "??? (FPU)"); break;
\r
6161 case 6: sprintf(s, "fsave %s", modrm_string); break;
\r
6162 case 7: sprintf(s, "fstsw word ptr %s", modrm_string); break;
\r
6165 switch (op2 & 0x3f)
\r
6167 case 0x00: case 0x01: case 0x02: case 0x03: case 0x04: case 0x05: case 0x06: case 0x07:
\r
6168 sprintf(s, "ffree st(%d)", op2 & 0x7); break;
\r
6170 case 0x10: case 0x11: case 0x12: case 0x13: case 0x14: case 0x15: case 0x16: case 0x17:
\r
6171 sprintf(s, "fst st(%d)", op2 & 0x7); break;
\r
6173 case 0x18: case 0x19: case 0x1a: case 0x1b: case 0x1c: case 0x1d: case 0x1e: case 0x1f:
\r
6174 sprintf(s, "fstp st(%d)", op2 & 0x7); break;
\r
6176 case 0x20: case 0x21: case 0x22: case 0x23: case 0x24: case 0x25: case 0x26: case 0x27:
\r
6177 sprintf(s, "fucom st(%d), st(0)", op2 & 0x7); break;
\r
6179 case 0x28: case 0x29: case 0x2a: case 0x2b: case 0x2c: case 0x2d: case 0x2e: case 0x2f:
\r
6180 sprintf(s, "fucomp st(%d)", op2 & 0x7); break;
\r
6182 default: sprintf(s, "??? (FPU)"); break;
\r
6188 case 6: // Group DE
\r
6192 pc--; // adjust fetch pointer, so modrm byte read again
\r
6194 handle_modrm( modrm_string );
\r
6195 switch ((op2 >> 3) & 0x7)
\r
6197 case 0: sprintf(s, "fiadd word ptr %s", modrm_string); break;
\r
6198 case 1: sprintf(s, "fimul word ptr %s", modrm_string); break;
\r
6199 case 2: sprintf(s, "ficom word ptr %s", modrm_string); break;
\r
6200 case 3: sprintf(s, "ficomp word ptr %s", modrm_string); break;
\r
6201 case 4: sprintf(s, "fisub word ptr %s", modrm_string); break;
\r
6202 case 5: sprintf(s, "fisubr word ptr %s", modrm_string); break;
\r
6203 case 6: sprintf(s, "fidiv word ptr %s", modrm_string); break;
\r
6204 case 7: sprintf(s, "fidivr word ptr %s", modrm_string); break;
\r
6207 switch (op2 & 0x3f)
\r
6209 case 0x00: case 0x01: case 0x02: case 0x03: case 0x04: case 0x05: case 0x06: case 0x07:
\r
6210 sprintf(s, "faddp st(%d)", op2 & 0x7); break;
\r
6212 case 0x08: case 0x09: case 0x0a: case 0x0b: case 0x0c: case 0x0d: case 0x0e: case 0x0f:
\r
6213 sprintf(s, "fmulp st(%d)", op2 & 0x7); break;
\r
6215 case 0x19: sprintf(s, "fcompp"); break;
\r
6217 case 0x20: case 0x21: case 0x22: case 0x23: case 0x24: case 0x25: case 0x26: case 0x27:
\r
6218 sprintf(s, "fsubrp st(%d)", op2 & 0x7); break;
\r
6220 case 0x28: case 0x29: case 0x2a: case 0x2b: case 0x2c: case 0x2d: case 0x2e: case 0x2f:
\r
6221 sprintf(s, "fsubp st(%d)", op2 & 0x7); break;
\r
6223 case 0x30: case 0x31: case 0x32: case 0x33: case 0x34: case 0x35: case 0x36: case 0x37:
\r
6224 sprintf(s, "fdivrp st(%d), st(0)", op2 & 0x7); break;
\r
6226 case 0x38: case 0x39: case 0x3a: case 0x3b: case 0x3c: case 0x3d: case 0x3e: case 0x3f:
\r
6227 sprintf(s, "fdivp st(%d)", op2 & 0x7); break;
\r
6229 default: sprintf(s, "??? (FPU)"); break;
\r
6235 case 7: // Group DF
\r
6239 pc--; // adjust fetch pointer, so modrm byte read again
\r
6241 handle_modrm( modrm_string );
\r
6242 switch ((op2 >> 3) & 0x7)
\r
6244 case 0: sprintf(s, "fild word ptr %s", modrm_string); break;
\r
6245 case 1: sprintf(s, "??? (FPU)"); break;
\r
6246 case 2: sprintf(s, "fist word ptr %s", modrm_string); break;
\r
6247 case 3: sprintf(s, "fistp word ptr %s", modrm_string); break;
\r
6248 case 4: sprintf(s, "fbld %s", modrm_string); break;
\r
6249 case 5: sprintf(s, "fild qword ptr %s", modrm_string); break;
\r
6250 case 6: sprintf(s, "fbstp %s", modrm_string); break;
\r
6251 case 7: sprintf(s, "fistp qword ptr %s", modrm_string); break;
\r
6254 switch (op2 & 0x3f)
\r
6256 case 0x20: sprintf(s, "fstsw aw"); break;
\r
6258 case 0x28: case 0x29: case 0x2a: case 0x2b: case 0x2c: case 0x2d: case 0x2e: case 0x2f:
\r
6259 sprintf(s, "fucomip st(%d)", op2 & 0x7); break;
\r
6261 case 0x30: case 0x31: case 0x32: case 0x33: case 0x34: case 0x35: case 0x36: case 0x37:
\r
6262 sprintf(s, "fcomip st(%d),st(0)", op2 & 0x7); break;
\r
6264 default: sprintf(s, "??? (FPU)"); break;
\r
6272 static void decode_opcode(char *s, const I386_OPCODE *op, UINT8 op1 )
\r
6277 switch( op->flags )
\r
6281 decode_opcode( s, &necv_opcode_table2[op2], op1 );
\r
6288 segment = op->flags;
\r
6290 decode_opcode( s, &necv_opcode_table1[op2], op1 );
\r
6294 s += sprintf( s, "%-8s", op->mnemonic );
\r
6296 decode_opcode( s, &necv_opcode_table1[op2], op1 );
\r
6300 handle_modrm( modrm_string );
\r
6301 for( i=0; i < ARRAY_LENGTH(group_op_table); i++ ) {
\r
6302 if( strcmp(op->mnemonic, group_op_table[i].mnemonic) == 0 )
\r
6304 decode_opcode( s, &group_op_table[i].opcode[MODRM_REG1], op1 );
\r
6308 goto handle_unknown;
\r
6312 handle_fpu( s, op1, op2);
\r
6316 handle_modrm( modrm_string );
\r
6320 s += sprintf( s, "%-8s", op->mnemonic );
\r
6321 dasm_flags = op->dasm_flags;
\r
6323 if( op->param1 != 0 ) {
\r
6324 s = handle_param( s, op->param1 );
\r
6327 if( op->param2 != 0 ) {
\r
6328 s += sprintf( s, "," );
\r
6329 s = handle_param( s, op->param2 );
\r
6332 if( op->param3 != 0 ) {
\r
6333 s += sprintf( s, "," );
\r
6334 s = handle_param( s, op->param3 );
\r
6339 sprintf(s, "???");
\r
6342 int necv_dasm_one(char *buffer, UINT32 eip, const UINT8 *oprom)
\r
6346 opcode_ptr = opcode_ptr_base = oprom;
\r
6353 decode_opcode( buffer, &necv_opcode_table1[op], op );
\r
6354 return (pc-eip) | dasm_flags | DASMFLAG_SUPPORTED;
\r
6357 #define STATE_VERSION 1
\r
6359 void I86::save_state(FILEIO* state_fio)
\r
6361 state_fio->FputUint32(STATE_VERSION);
\r
6362 state_fio->FputInt32(this_device_id);
\r
6364 state_fio->Fwrite(®s, sizeof(regs), 1);
\r
6365 state_fio->FputUint32(pc);
\r
6366 state_fio->FputUint32(prevpc);
\r
6367 state_fio->Fwrite(base, sizeof(base), 1);
\r
6368 state_fio->Fwrite(sregs, sizeof(sregs), 1);
\r
6369 state_fio->FputUint16(flags);
\r
6370 state_fio->FputInt32(AuxVal);
\r
6371 state_fio->FputInt32(OverVal);
\r
6372 state_fio->FputInt32(SignVal);
\r
6373 state_fio->FputInt32(ZeroVal);
\r
6374 state_fio->FputInt32(CarryVal);
\r
6375 state_fio->FputInt32(DirVal);
\r
6376 state_fio->FputUint8(ParityVal);
\r
6377 state_fio->FputUint8(TF);
\r
6378 state_fio->FputUint8(IF);
\r
6379 state_fio->FputUint8(MF);
\r
6380 state_fio->FputInt32(int_state);
\r
6381 state_fio->FputBool(test_state);
\r
6382 state_fio->FputBool(busreq);
\r
6383 state_fio->FputBool(halted);
\r
6384 state_fio->FputInt32(icount);
\r
6385 state_fio->FputInt32(extra_icount);
\r
6386 state_fio->FputBool(seg_prefix);
\r
6387 state_fio->FputUint8(prefix_seg);
\r
6388 state_fio->FputUint32(ea);
\r
6389 state_fio->FputUint16(eo);
\r
6390 state_fio->FputUint8(ea_seg);
\r
6393 bool I86::load_state(FILEIO* state_fio)
\r
6395 if(state_fio->FgetUint32() != STATE_VERSION) {
\r
6398 if(state_fio->FgetInt32() != this_device_id) {
\r
6401 state_fio->Fread(®s, sizeof(regs), 1);
\r
6402 pc = state_fio->FgetUint32();
\r
6403 prevpc = state_fio->FgetUint32();
\r
6404 state_fio->Fread(base, sizeof(base), 1);
\r
6405 state_fio->Fread(sregs, sizeof(sregs), 1);
\r
6406 flags = state_fio->FgetUint16();
\r
6407 AuxVal = state_fio->FgetInt32();
\r
6408 OverVal = state_fio->FgetInt32();
\r
6409 SignVal = state_fio->FgetInt32();
\r
6410 ZeroVal = state_fio->FgetInt32();
\r
6411 CarryVal = state_fio->FgetInt32();
\r
6412 DirVal = state_fio->FgetInt32();
\r
6413 ParityVal = state_fio->FgetUint8();
\r
6414 TF = state_fio->FgetUint8();
\r
6415 IF = state_fio->FgetUint8();
\r
6416 MF = state_fio->FgetUint8();
\r
6417 int_state = state_fio->FgetInt32();
\r
6418 test_state = state_fio->FgetBool();
\r
6419 busreq = state_fio->FgetBool();
\r
6420 halted = state_fio->FgetBool();
\r
6421 icount = state_fio->FgetInt32();
\r
6422 extra_icount = state_fio->FgetInt32();
\r
6423 seg_prefix = state_fio->FgetBool();
\r
6424 prefix_seg = state_fio->FgetUint8();
\r
6425 ea = state_fio->FgetUint32();
\r
6426 eo = state_fio->FgetUint16();
\r
6427 ea_seg = state_fio->FgetUint8();
\r