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
968 icount -= (ModRM >= 0xc0) ? timing.rot_reg_base + timing.rot_reg_bit : timing.rot_m8_base + timing.rot_m8_bit;
\r
970 switch((ModRM >> 3) & 7) {
\r
971 case 0: /* ROL eb, count */
\r
972 for(; count > 0; count--) {
\r
973 CarryVal = dst & 0x80;
\r
974 dst = (dst << 1) + CF;
\r
976 PutbackRMByte(ModRM, (uint8)dst);
\r
978 case 1: /* ROR eb, count */
\r
979 for(; count > 0; count--) {
\r
980 CarryVal = dst & 0x01;
\r
981 dst = (dst >> 1) + (CF << 7);
\r
983 PutbackRMByte(ModRM, (uint8)dst);
\r
985 case 2: /* RCL eb, count */
\r
986 for(; count > 0; count--) {
\r
987 dst = (dst << 1) + CF;
\r
990 PutbackRMByte(ModRM, (uint8)dst);
\r
992 case 3: /* RCR eb, count */
\r
993 for(; count > 0; count--) {
\r
994 dst = (CF << 8) + dst;
\r
995 CarryVal = dst & 0x01;
\r
998 PutbackRMByte(ModRM, (uint8)dst);
\r
1000 case 4: /* SHL eb, count */
\r
1005 SetSZPF_Byte(dst);
\r
1006 PutbackRMByte(ModRM, (uint8)dst);
\r
1008 case 5: /* SHR eb, count */
\r
1009 dst >>= count - 1;
\r
1010 CarryVal = dst & 0x01;
\r
1012 SetSZPF_Byte(dst);
\r
1014 PutbackRMByte(ModRM, (uint8)dst);
\r
1016 case 7: /* SAR eb, count */
\r
1017 dst = ((int8)dst) >> (count - 1);
\r
1018 CarryVal = dst & 0x01;
\r
1019 dst = ((int8)((uint8)dst)) >> 1;
\r
1020 SetSZPF_Byte(dst);
\r
1022 PutbackRMByte(ModRM, (uint8)dst);
\r
1030 void I86::rotate_shift_word(unsigned ModRM, unsigned count)
\r
1032 unsigned src = GetRMWord(ModRM);
\r
1033 unsigned dst = src;
\r
1036 icount -= (ModRM >= 0xc0) ? timing.rot_reg_base : timing.rot_m16_base;
\r
1037 } else if(count == 1) {
\r
1038 icount -= (ModRM >= 0xc0) ? timing.rot_reg_1 : timing.rot_m16_1;
\r
1040 switch((ModRM >> 3) & 7) {
\r
1041 case 0: /* ROL ew, 1 */
\r
1042 CarryVal = src & 0x8000;
\r
1043 dst = (src << 1) + CF;
\r
1044 PutbackRMWord(ModRM, dst);
\r
1045 OverVal = (src ^ dst) & 0x8000;
\r
1047 case 1: /* ROR ew, 1 */
\r
1048 CarryVal = src & 0x01;
\r
1049 dst = ((CF << 16) + src) >> 1;
\r
1050 PutbackRMWord(ModRM, dst);
\r
1051 OverVal = (src ^ dst) & 0x8000;
\r
1053 case 2: /* RCL ew, 1 */
\r
1054 dst = (src << 1) + CF;
\r
1055 PutbackRMWord(ModRM, dst);
\r
1057 OverVal = (src ^ dst) & 0x8000;
\r
1059 case 3: /* RCR ew, 1 */
\r
1060 dst = ((CF << 16) + src) >> 1;
\r
1061 PutbackRMWord(ModRM, dst);
\r
1062 CarryVal = src & 0x01;
\r
1063 OverVal = (src ^ dst) & 0x8000;
\r
1065 case 4: /* SHL ew, 1 */
\r
1068 PutbackRMWord(ModRM, dst);
\r
1070 OverVal = (src ^ dst) & 0x8000;
\r
1072 SetSZPF_Word(dst);
\r
1074 case 5: /* SHR ew, 1 */
\r
1076 PutbackRMWord(ModRM, dst);
\r
1077 CarryVal = src & 0x01;
\r
1078 OverVal = src & 0x8000;
\r
1080 SetSZPF_Word(dst);
\r
1082 case 7: /* SAR ew, 1 */
\r
1083 dst = ((int16)src) >> 1;
\r
1084 PutbackRMWord(ModRM, dst);
\r
1085 CarryVal = src & 0x01;
\r
1088 SetSZPF_Word(dst);
\r
1094 icount -= (ModRM >= 0xc0) ? timing.rot_reg_base + timing.rot_reg_bit : timing.rot_m8_base + timing.rot_m16_bit;
\r
1096 switch((ModRM >> 3) & 7) {
\r
1097 case 0: /* ROL ew, count */
\r
1098 for(; count > 0; count--) {
\r
1099 CarryVal = dst & 0x8000;
\r
1100 dst = (dst << 1) + CF;
\r
1102 PutbackRMWord(ModRM, dst);
\r
1104 case 1: /* ROR ew, count */
\r
1105 for(; count > 0; count--) {
\r
1106 CarryVal = dst & 0x01;
\r
1107 dst = (dst >> 1) + (CF << 15);
\r
1109 PutbackRMWord(ModRM, dst);
\r
1111 case 2: /* RCL ew, count */
\r
1112 for(; count > 0; count--) {
\r
1113 dst = (dst << 1) + CF;
\r
1116 PutbackRMWord(ModRM, dst);
\r
1118 case 3: /* RCR ew, count */
\r
1119 for(; count > 0; count--) {
\r
1120 dst = dst + (CF << 16);
\r
1121 CarryVal = dst & 0x01;
\r
1124 PutbackRMWord(ModRM, dst);
\r
1126 case 4: /* SHL ew, count */
\r
1131 SetSZPF_Word(dst);
\r
1132 PutbackRMWord(ModRM, dst);
\r
1134 case 5: /* SHR ew, count */
\r
1135 dst >>= count - 1;
\r
1136 CarryVal = dst & 0x01;
\r
1138 SetSZPF_Word(dst);
\r
1140 PutbackRMWord(ModRM, dst);
\r
1142 case 7: /* SAR ew, count */
\r
1143 dst = ((int16)dst) >> (count - 1);
\r
1144 CarryVal = dst & 0x01;
\r
1145 dst = ((int16)((uint16)dst)) >> 1;
\r
1146 SetSZPF_Word(dst);
\r
1148 PutbackRMWord(ModRM, dst);
\r
1156 void I86::instruction(uint8 code)
\r
1161 case 0x00: _add_br8(); break;
\r
1162 case 0x01: _add_wr16(); break;
\r
1163 case 0x02: _add_r8b(); break;
\r
1164 case 0x03: _add_r16w(); break;
\r
1165 case 0x04: _add_ald8(); break;
\r
1166 case 0x05: _add_axd16(); break;
\r
1167 case 0x06: _push_es(); break;
\r
1168 case 0x07: _pop_es(); break;
\r
1169 case 0x08: _or_br8(); break;
\r
1170 case 0x09: _or_wr16(); break;
\r
1171 case 0x0a: _or_r8b(); break;
\r
1172 case 0x0b: _or_r16w(); break;
\r
1173 case 0x0c: _or_ald8(); break;
\r
1174 case 0x0d: _or_axd16(); break;
\r
1175 case 0x0e: _push_cs(); break;
\r
1176 #if defined(HAS_V30)
\r
1177 case 0x0f: _0fpre(); break;
\r
1179 case 0x0f: _invalid(); break;
\r
1181 case 0x10: _adc_br8(); break;
\r
1182 case 0x11: _adc_wr16(); break;
\r
1183 case 0x12: _adc_r8b(); break;
\r
1184 case 0x13: _adc_r16w(); break;
\r
1185 case 0x14: _adc_ald8(); break;
\r
1186 case 0x15: _adc_axd16(); break;
\r
1187 case 0x16: _push_ss(); break;
\r
1188 case 0x17: _pop_ss(); break;
\r
1189 case 0x18: _sbb_br8(); break;
\r
1190 case 0x19: _sbb_wr16(); break;
\r
1191 case 0x1a: _sbb_r8b(); break;
\r
1192 case 0x1b: _sbb_r16w(); break;
\r
1193 case 0x1c: _sbb_ald8(); break;
\r
1194 case 0x1d: _sbb_axd16(); break;
\r
1195 case 0x1e: _push_ds(); break;
\r
1196 case 0x1f: _pop_ds(); break;
\r
1197 case 0x20: _and_br8(); break;
\r
1198 case 0x21: _and_wr16(); break;
\r
1199 case 0x22: _and_r8b(); break;
\r
1200 case 0x23: _and_r16w(); break;
\r
1201 case 0x24: _and_ald8(); break;
\r
1202 case 0x25: _and_axd16(); break;
\r
1203 case 0x26: _es(); break;
\r
1204 case 0x27: _daa(); break;
\r
1205 case 0x28: _sub_br8(); break;
\r
1206 case 0x29: _sub_wr16(); break;
\r
1207 case 0x2a: _sub_r8b(); break;
\r
1208 case 0x2b: _sub_r16w(); break;
\r
1209 case 0x2c: _sub_ald8(); break;
\r
1210 case 0x2d: _sub_axd16(); break;
\r
1211 case 0x2e: _cs(); break;
\r
1212 case 0x2f: _das(); break;
\r
1213 case 0x30: _xor_br8(); break;
\r
1214 case 0x31: _xor_wr16(); break;
\r
1215 case 0x32: _xor_r8b(); break;
\r
1216 case 0x33: _xor_r16w(); break;
\r
1217 case 0x34: _xor_ald8(); break;
\r
1218 case 0x35: _xor_axd16(); break;
\r
1219 case 0x36: _ss(); break;
\r
1220 case 0x37: _aaa(); break;
\r
1221 case 0x38: _cmp_br8(); break;
\r
1222 case 0x39: _cmp_wr16(); break;
\r
1223 case 0x3a: _cmp_r8b(); break;
\r
1224 case 0x3b: _cmp_r16w(); break;
\r
1225 case 0x3c: _cmp_ald8(); break;
\r
1226 case 0x3d: _cmp_axd16(); break;
\r
1227 case 0x3e: _ds(); break;
\r
1228 case 0x3f: _aas(); break;
\r
1229 case 0x40: _inc_ax(); break;
\r
1230 case 0x41: _inc_cx(); break;
\r
1231 case 0x42: _inc_dx(); break;
\r
1232 case 0x43: _inc_bx(); break;
\r
1233 case 0x44: _inc_sp(); break;
\r
1234 case 0x45: _inc_bp(); break;
\r
1235 case 0x46: _inc_si(); break;
\r
1236 case 0x47: _inc_di(); break;
\r
1237 case 0x48: _dec_ax(); break;
\r
1238 case 0x49: _dec_cx(); break;
\r
1239 case 0x4a: _dec_dx(); break;
\r
1240 case 0x4b: _dec_bx(); break;
\r
1241 case 0x4c: _dec_sp(); break;
\r
1242 case 0x4d: _dec_bp(); break;
\r
1243 case 0x4e: _dec_si(); break;
\r
1244 case 0x4f: _dec_di(); break;
\r
1245 case 0x50: _push_ax(); break;
\r
1246 case 0x51: _push_cx(); break;
\r
1247 case 0x52: _push_dx(); break;
\r
1248 case 0x53: _push_bx(); break;
\r
1249 case 0x54: _push_sp(); break;
\r
1250 case 0x55: _push_bp(); break;
\r
1251 case 0x56: _push_si(); break;
\r
1252 case 0x57: _push_di(); break;
\r
1253 case 0x58: _pop_ax(); break;
\r
1254 case 0x59: _pop_cx(); break;
\r
1255 case 0x5a: _pop_dx(); break;
\r
1256 case 0x5b: _pop_bx(); break;
\r
1257 case 0x5c: _pop_sp(); break;
\r
1258 case 0x5d: _pop_bp(); break;
\r
1259 case 0x5e: _pop_si(); break;
\r
1260 case 0x5f: _pop_di(); break;
\r
1261 #if defined(HAS_V30)
\r
1262 case 0x60: _pusha(); break;
\r
1263 case 0x61: _popa(); break;
\r
1264 case 0x62: _bound(); break;
\r
1266 case 0x60: _invalid(); break;
\r
1267 case 0x61: _invalid(); break;
\r
1268 case 0x62: _invalid(); break;
\r
1270 case 0x63: _invalid(); break;
\r
1271 #if defined(HAS_V30)
\r
1272 case 0x64: _repc(0); break;
\r
1273 case 0x65: _repc(1); break;
\r
1275 case 0x64: _invalid(); break;
\r
1276 case 0x65: _invalid(); break;
\r
1278 case 0x66: _invalid(); break;
\r
1279 case 0x67: _invalid(); break;
\r
1280 #if defined(HAS_V30)
\r
1281 case 0x68: _push_d16(); break;
\r
1282 case 0x69: _imul_d16(); break;
\r
1283 case 0x6a: _push_d8(); break;
\r
1284 case 0x6b: _imul_d8(); break;
\r
1285 case 0x6c: _insb(); break;
\r
1286 case 0x6d: _insw(); break;
\r
1287 case 0x6e: _outsb(); break;
\r
1288 case 0x6f: _outsw(); break;
\r
1290 case 0x68: _invalid(); break;
\r
1291 case 0x69: _invalid(); break;
\r
1292 case 0x6a: _invalid(); break;
\r
1293 case 0x6b: _invalid(); break;
\r
1294 case 0x6c: _invalid(); break;
\r
1295 case 0x6d: _invalid(); break;
\r
1296 case 0x6e: _invalid(); break;
\r
1297 case 0x6f: _invalid(); break;
\r
1299 case 0x70: _jo(); break;
\r
1300 case 0x71: _jno(); break;
\r
1301 case 0x72: _jb(); break;
\r
1302 case 0x73: _jnb(); break;
\r
1303 case 0x74: _jz(); break;
\r
1304 case 0x75: _jnz(); break;
\r
1305 case 0x76: _jbe(); break;
\r
1306 case 0x77: _jnbe(); break;
\r
1307 case 0x78: _js(); break;
\r
1308 case 0x79: _jns(); break;
\r
1309 case 0x7a: _jp(); break;
\r
1310 case 0x7b: _jnp(); break;
\r
1311 case 0x7c: _jl(); break;
\r
1312 case 0x7d: _jnl(); break;
\r
1313 case 0x7e: _jle(); break;
\r
1314 case 0x7f: _jnle(); break;
\r
1315 case 0x80: _80pre(); break;
\r
1316 case 0x81: _81pre(); break;
\r
1317 case 0x82: _82pre(); break;
\r
1318 case 0x83: _83pre(); break;
\r
1319 case 0x84: _test_br8(); break;
\r
1320 case 0x85: _test_wr16(); break;
\r
1321 case 0x86: _xchg_br8(); break;
\r
1322 case 0x87: _xchg_wr16(); break;
\r
1323 case 0x88: _mov_br8(); break;
\r
1324 case 0x89: _mov_wr16(); break;
\r
1325 case 0x8a: _mov_r8b(); break;
\r
1326 case 0x8b: _mov_r16w(); break;
\r
1327 case 0x8c: _mov_wsreg(); break;
\r
1328 case 0x8d: _lea(); break;
\r
1329 case 0x8e: _mov_sregw(); break;
\r
1330 case 0x8f: _popw(); break;
\r
1331 case 0x90: _nop(); break;
\r
1332 case 0x91: _xchg_axcx(); break;
\r
1333 case 0x92: _xchg_axdx(); break;
\r
1334 case 0x93: _xchg_axbx(); break;
\r
1335 case 0x94: _xchg_axsp(); break;
\r
1336 case 0x95: _xchg_axbp(); break;
\r
1337 case 0x96: _xchg_axsi(); break;
\r
1338 case 0x97: _xchg_axdi(); break;
\r
1339 case 0x98: _cbw(); break;
\r
1340 case 0x99: _cwd(); break;
\r
1341 case 0x9a: _call_far(); break;
\r
1342 case 0x9b: _wait(); break;
\r
1343 case 0x9c: _pushf(); break;
\r
1344 case 0x9d: _popf(); break;
\r
1345 case 0x9e: _sahf(); break;
\r
1346 case 0x9f: _lahf(); break;
\r
1347 case 0xa0: _mov_aldisp(); break;
\r
1348 case 0xa1: _mov_axdisp(); break;
\r
1349 case 0xa2: _mov_dispal(); break;
\r
1350 case 0xa3: _mov_dispax(); break;
\r
1351 case 0xa4: _movsb(); break;
\r
1352 case 0xa5: _movsw(); break;
\r
1353 case 0xa6: _cmpsb(); break;
\r
1354 case 0xa7: _cmpsw(); break;
\r
1355 case 0xa8: _test_ald8(); break;
\r
1356 case 0xa9: _test_axd16(); break;
\r
1357 case 0xaa: _stosb(); break;
\r
1358 case 0xab: _stosw(); break;
\r
1359 case 0xac: _lodsb(); break;
\r
1360 case 0xad: _lodsw(); break;
\r
1361 case 0xae: _scasb(); break;
\r
1362 case 0xaf: _scasw(); break;
\r
1363 case 0xb0: _mov_ald8(); break;
\r
1364 case 0xb1: _mov_cld8(); break;
\r
1365 case 0xb2: _mov_dld8(); break;
\r
1366 case 0xb3: _mov_bld8(); break;
\r
1367 case 0xb4: _mov_ahd8(); break;
\r
1368 case 0xb5: _mov_chd8(); break;
\r
1369 case 0xb6: _mov_dhd8(); break;
\r
1370 case 0xb7: _mov_bhd8(); break;
\r
1371 case 0xb8: _mov_axd16(); break;
\r
1372 case 0xb9: _mov_cxd16(); break;
\r
1373 case 0xba: _mov_dxd16(); break;
\r
1374 case 0xbb: _mov_bxd16(); break;
\r
1375 case 0xbc: _mov_spd16(); break;
\r
1376 case 0xbd: _mov_bpd16(); break;
\r
1377 case 0xbe: _mov_sid16(); break;
\r
1378 case 0xbf: _mov_did16(); break;
\r
1379 #if defined(HAS_V30)
\r
1380 case 0xc0: _rotshft_bd8(); break;
\r
1381 case 0xc1: _rotshft_wd8(); break;
\r
1383 case 0xc0: _invalid(); break;
\r
1384 case 0xc1: _invalid(); break;
\r
1386 case 0xc2: _ret_d16(); break;
\r
1387 case 0xc3: _ret(); break;
\r
1388 case 0xc4: _les_dw(); break;
\r
1389 case 0xc5: _lds_dw(); break;
\r
1390 case 0xc6: _mov_bd8(); break;
\r
1391 case 0xc7: _mov_wd16(); break;
\r
1392 #if defined(HAS_V30)
\r
1393 case 0xc8: _enter(); break;
\r
1394 case 0xc9: _leav(); break; /* _leave() */
\r
1396 case 0xc8: _invalid(); break;
\r
1397 case 0xc9: _invalid(); break;
\r
1399 case 0xca: _retf_d16(); break;
\r
1400 case 0xcb: _retf(); break;
\r
1401 case 0xcc: _int3(); break;
\r
1402 case 0xcd: _int(); break;
\r
1403 case 0xce: _into(); break;
\r
1404 case 0xcf: _iret(); break;
\r
1405 case 0xd0: _rotshft_b(); break;
\r
1406 case 0xd1: _rotshft_w(); break;
\r
1407 case 0xd2: _rotshft_bcl(); break;
\r
1408 case 0xd3: _rotshft_wcl(); break;
\r
1409 case 0xd4: _aam(); break;
\r
1410 case 0xd5: _aad(); break;
\r
1411 #if defined(HAS_V30)
\r
1412 case 0xd6: _setalc(); break;
\r
1414 case 0xd6: _invalid(); break;
\r
1416 case 0xd7: _xlat(); break;
\r
1417 case 0xd8: _escape(); break;
\r
1418 case 0xd9: _escape(); break;
\r
1419 case 0xda: _escape(); break;
\r
1420 case 0xdb: _escape(); break;
\r
1421 case 0xdc: _escape(); break;
\r
1422 case 0xdd: _escape(); break;
\r
1423 case 0xde: _escape(); break;
\r
1424 case 0xdf: _escape(); break;
\r
1425 case 0xe0: _loopne(); break;
\r
1426 case 0xe1: _loope(); break;
\r
1427 case 0xe2: _loop(); break;
\r
1428 case 0xe3: _jcxz(); break;
\r
1429 case 0xe4: _inal(); break;
\r
1430 case 0xe5: _inax(); break;
\r
1431 case 0xe6: _outal(); break;
\r
1432 case 0xe7: _outax(); break;
\r
1433 case 0xe8: _call_d16(); break;
\r
1434 case 0xe9: _jmp_d16(); break;
\r
1435 case 0xea: _jmp_far(); break;
\r
1436 case 0xeb: _jmp_d8(); break;
\r
1437 case 0xec: _inaldx(); break;
\r
1438 case 0xed: _inaxdx(); break;
\r
1439 case 0xee: _outdxal(); break;
\r
1440 case 0xef: _outdxax(); break;
\r
1441 case 0xf0: _lock(); break;
\r
1442 case 0xf1: _invalid(); break;
\r
1443 case 0xf2: _repne(); break;
\r
1444 case 0xf3: _repe(); break;
\r
1445 case 0xf4: _hlt(); break;
\r
1446 case 0xf5: _cmc(); break;
\r
1447 case 0xf6: _f6pre(); break;
\r
1448 case 0xf7: _f7pre(); break;
\r
1449 case 0xf8: _clc(); break;
\r
1450 case 0xf9: _stc(); break;
\r
1451 case 0xfa: _cli(); break;
\r
1452 case 0xfb: _sti(); break;
\r
1453 case 0xfc: _cld(); break;
\r
1454 case 0xfd: _std(); break;
\r
1455 case 0xfe: _fepre(); break;
\r
1456 case 0xff: _ffpre(); break;
\r
1457 default: __assume(0);
\r
1461 inline void I86::_add_br8() /* Opcode 0x00 */
\r
1463 DEF_br8(dst, src);
\r
1464 icount -= (ModRM >= 0xc0) ? timing.alu_rr8 : timing.alu_mr8;
\r
1466 PutbackRMByte(ModRM, dst);
\r
1469 inline void I86::_add_wr16() /* Opcode 0x01 */
\r
1471 DEF_wr16(dst, src);
\r
1472 icount -= (ModRM >= 0xc0) ? timing.alu_rr16 : timing.alu_mr16;
\r
1474 PutbackRMWord(ModRM, dst);
\r
1477 inline void I86::_add_r8b() /* Opcode 0x02 */
\r
1479 DEF_r8b(dst, src);
\r
1480 icount -= (ModRM >= 0xc0) ? timing.alu_rr8 : timing.alu_rm8;
\r
1482 RegByte(ModRM) = dst;
\r
1485 inline void I86::_add_r16w() /* Opcode 0x03 */
\r
1487 DEF_r16w(dst, src);
\r
1488 icount -= (ModRM >= 0xc0) ? timing.alu_rr16 : timing.alu_rm16;
\r
1490 RegWord(ModRM) = dst;
\r
1493 inline void I86::_add_ald8() /* Opcode 0x04 */
\r
1495 DEF_ald8(dst, src);
\r
1496 icount -= timing.alu_ri8;
\r
1501 inline void I86::_add_axd16() /* Opcode 0x05 */
\r
1503 DEF_axd16(dst, src);
\r
1504 icount -= timing.alu_ri16;
\r
1509 inline void I86::_push_es() /* Opcode 0x06 */
\r
1511 icount -= timing.push_seg;
\r
1515 inline void I86::_pop_es() /* Opcode 0x07 */
\r
1518 base[ES] = SegBase(ES);
\r
1519 icount -= timing.pop_seg;
\r
1522 inline void I86::_or_br8() /* Opcode 0x08 */
\r
1524 DEF_br8(dst, src);
\r
1525 icount -= (ModRM >= 0xc0) ? timing.alu_rr8 : timing.alu_mr8;
\r
1527 PutbackRMByte(ModRM, dst);
\r
1530 inline void I86::_or_wr16() /* Opcode 0x09 */
\r
1532 DEF_wr16(dst, src);
\r
1533 icount -= (ModRM >= 0xc0) ? timing.alu_rr16 : timing.alu_mr16;
\r
1535 PutbackRMWord(ModRM, dst);
\r
1538 inline void I86::_or_r8b() /* Opcode 0x0a */
\r
1540 DEF_r8b(dst, src);
\r
1541 icount -= (ModRM >= 0xc0) ? timing.alu_rr8 : timing.alu_rm8;
\r
1543 RegByte(ModRM) = dst;
\r
1546 inline void I86::_or_r16w() /* Opcode 0x0b */
\r
1548 DEF_r16w(dst, src);
\r
1549 icount -= (ModRM >= 0xc0) ? timing.alu_rr16 : timing.alu_rm16;
\r
1551 RegWord(ModRM) = dst;
\r
1554 inline void I86::_or_ald8() /* Opcode 0x0c */
\r
1556 DEF_ald8(dst, src);
\r
1557 icount -= timing.alu_ri8;
\r
1562 inline void I86::_or_axd16() /* Opcode 0x0d */
\r
1564 DEF_axd16(dst, src);
\r
1565 icount -= timing.alu_ri16;
\r
1570 inline void I86::_push_cs() /* Opcode 0x0e */
\r
1572 icount -= timing.push_seg;
\r
1576 #if defined(HAS_V30)
\r
1577 inline void I86::_0fpre() /* Opcode 0x0f */
\r
1579 static const uint16 bytes[] = {
\r
1580 1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096, 8192, 16384, 32768
\r
1582 unsigned code = FETCH;
\r
1588 case 0x10: /* 0F 10 47 30 - TEST1 [bx+30h], cl */
\r
1590 if(ModRM >= 0xc0) {
\r
1591 tmp = regs.b[Mod_RM.RM.b[ModRM]];
\r
1596 tmp = ReadByte(ea);
\r
1597 icount = old - 12;
\r
1599 tmp2 = regs.b[CL] & 7;
\r
1600 SetZF(tmp & bytes[tmp2]);
\r
1602 case 0x11: /* 0F 11 47 30 - TEST1 [bx+30h], cl */
\r
1604 if(ModRM >= 0xc0) {
\r
1605 tmp = regs.w[Mod_RM.RM.w[ModRM]];
\r
1610 tmp = ReadWord(ea);
\r
1611 icount = old - 12;
\r
1613 tmp2 = regs.b[CL] & 0xf;
\r
1614 SetZF(tmp & bytes[tmp2]);
\r
1616 case 0x12: /* 0F 12 [mod:000:r/m] - CLR1 reg/m8, cl */
\r
1618 if(ModRM >= 0xc0) {
\r
1619 tmp = regs.b[Mod_RM.RM.b[ModRM]];
\r
1624 tmp = ReadByte(ea);
\r
1625 icount = old - 14;
\r
1627 tmp2 = regs.b[CL] & 7;
\r
1628 tmp &= ~bytes[tmp2];
\r
1629 PutbackRMByte(ModRM, tmp);
\r
1631 case 0x13: /* 0F 13 [mod:000:r/m] - CLR1 reg/m16, cl */
\r
1633 if(ModRM >= 0xc0) {
\r
1634 tmp = regs.w[Mod_RM.RM.w[ModRM]];
\r
1639 tmp = ReadWord(ea);
\r
1640 icount = old - 14;
\r
1642 tmp2 = regs.b[CL] & 0xf;
\r
1643 tmp &= ~bytes[tmp2];
\r
1644 PutbackRMWord(ModRM, tmp);
\r
1646 case 0x14: /* 0F 14 47 30 - SET1 [bx+30h], cl */
\r
1648 if(ModRM >= 0xc0) {
\r
1649 tmp = regs.b[Mod_RM.RM.b[ModRM]];
\r
1654 tmp = ReadByte(ea);
\r
1655 icount = old - 13;
\r
1657 tmp2 = regs.b[CL] & 7;
\r
1658 tmp |= bytes[tmp2];
\r
1659 PutbackRMByte(ModRM, tmp);
\r
1661 case 0x15: /* 0F 15 C6 - SET1 si, cl */
\r
1663 if(ModRM >= 0xc0) {
\r
1664 tmp = regs.w[Mod_RM.RM.w[ModRM]];
\r
1669 tmp = ReadWord(ea);
\r
1670 icount = old - 13;
\r
1672 tmp2 = regs.b[CL] & 0xf;
\r
1673 tmp |= bytes[tmp2];
\r
1674 PutbackRMWord(ModRM, tmp);
\r
1676 case 0x16: /* 0F 16 C6 - NOT1 si, cl */
\r
1678 if(ModRM >= 0xc0) {
\r
1679 tmp = regs.b[Mod_RM.RM.b[ModRM]];
\r
1684 tmp = ReadByte(ea);
\r
1685 icount = old - 18;
\r
1687 tmp2 = regs.b[CL] & 7;
\r
1688 if(tmp & bytes[tmp2]) {
\r
1689 tmp &= ~bytes[tmp2];
\r
1691 tmp |= bytes[tmp2];
\r
1693 PutbackRMByte(ModRM, tmp);
\r
1695 case 0x17: /* 0F 17 C6 - NOT1 si, cl */
\r
1697 if(ModRM >= 0xc0) {
\r
1698 tmp = regs.w[Mod_RM.RM.w[ModRM]];
\r
1703 tmp = ReadWord(ea);
\r
1704 icount = old - 18;
\r
1706 tmp2 = regs.b[CL] & 0xf;
\r
1707 if(tmp & bytes[tmp2]) {
\r
1708 tmp &= ~bytes[tmp2];
\r
1710 tmp |= bytes[tmp2];
\r
1712 PutbackRMWord(ModRM, tmp);
\r
1714 case 0x18: /* 0F 18 XX - TEST1 [bx+30h], 07 */
\r
1716 if(ModRM >= 0xc0) {
\r
1717 tmp = regs.b[Mod_RM.RM.b[ModRM]];
\r
1722 tmp = ReadByte(ea);
\r
1723 icount = old - 13;
\r
1727 SetZF(tmp & bytes[tmp2]);
\r
1729 case 0x19: /* 0F 19 XX - TEST1 [bx+30h], 07 */
\r
1731 if(ModRM >= 0xc0) {
\r
1732 tmp = regs.w[Mod_RM.RM.w[ModRM]];
\r
1737 tmp = ReadWord(ea);
\r
1738 icount = old - 13;
\r
1742 SetZF(tmp & bytes[tmp2]);
\r
1744 case 0x1a: /* 0F 1A 06 - CLR1 si, cl */
\r
1746 if(ModRM >= 0xc0) {
\r
1747 tmp = regs.b[Mod_RM.RM.b[ModRM]];
\r
1752 tmp = ReadByte(ea);
\r
1753 icount = old - 15;
\r
1757 tmp &= ~bytes[tmp2];
\r
1758 PutbackRMByte(ModRM, tmp);
\r
1760 case 0x1B: /* 0F 1B 06 - CLR1 si, cl */
\r
1762 if(ModRM >= 0xc0) {
\r
1763 tmp = regs.w[Mod_RM.RM.w[ModRM]];
\r
1768 tmp = ReadWord(ea);
\r
1769 icount = old - 15;
\r
1773 tmp &= ~bytes[tmp2];
\r
1774 PutbackRMWord(ModRM, tmp);
\r
1776 case 0x1C: /* 0F 1C 47 30 - SET1 [bx+30h], cl */
\r
1778 if(ModRM >= 0xc0) {
\r
1779 tmp = regs.b[Mod_RM.RM.b[ModRM]];
\r
1784 tmp = ReadByte(ea);
\r
1785 icount = old - 14;
\r
1789 tmp |= bytes[tmp2];
\r
1790 PutbackRMByte(ModRM, tmp);
\r
1792 case 0x1D: /* 0F 1D C6 - SET1 si, cl */
\r
1794 if(ModRM >= 0xc0) {
\r
1795 tmp = regs.w[Mod_RM.RM.w[ModRM]];
\r
1800 tmp = ReadWord(ea);
\r
1801 icount = old - 14;
\r
1805 tmp |= bytes[tmp2];
\r
1806 PutbackRMWord(ModRM, tmp);
\r
1808 case 0x1e: /* 0F 1e C6 - NOT1 si, 07 */
\r
1810 if(ModRM >= 0xc0) {
\r
1811 tmp = regs.b[Mod_RM.RM.b[ModRM]];
\r
1816 tmp = ReadByte(ea);
\r
1817 icount = old - 19;
\r
1821 if(tmp & bytes[tmp2]) {
\r
1822 tmp &= ~bytes[tmp2];
\r
1824 tmp |= bytes[tmp2];
\r
1826 PutbackRMByte(ModRM, tmp);
\r
1828 case 0x1f: /* 0F 1f C6 - NOT1 si, 07 */
\r
1830 if(ModRM >= 0xc0) {
\r
1831 tmp = regs.w[Mod_RM.RM.w[ModRM]];
\r
1836 tmp = ReadWord(ea);
\r
1837 icount = old - 19;
\r
1841 if(tmp & bytes[tmp2]) {
\r
1842 tmp &= ~bytes[tmp2];
\r
1844 tmp |= bytes[tmp2];
\r
1846 PutbackRMWord(ModRM, tmp);
\r
1848 case 0x20: /* 0F 20 59 - add4s */
\r
1850 /* length in words ! */
\r
1851 int count = (regs.b[CL] + 1) / 2;
\r
1852 unsigned di = regs.w[DI];
\r
1853 unsigned si = regs.w[SI];
\r
1856 CarryVal = 0; /* NOT ADC */
\r
1857 for(int i = 0; i < count; i++) {
\r
1858 tmp = GetMemB(DS, si);
\r
1859 tmp2 = GetMemB(ES, di);
\r
1860 int v1 = (tmp >> 4) * 10 + (tmp & 0xf);
\r
1861 int v2 = (tmp2 >> 4) * 10 + (tmp2 & 0xf);
\r
1862 int result = v1 + v2 + CarryVal;
\r
1863 CarryVal = result > 99 ? 1 : 0;
\r
1864 result = result % 100;
\r
1865 v1 = ((result / 10) << 4) | (result % 10);
\r
1866 PutMemB(ES, di, v1);
\r
1873 OverVal = CarryVal;
\r
1874 icount -= 7 + 19 * count;
\r
1877 case 0x22: /* 0F 22 59 - sub4s */
\r
1879 int count = (regs.b[CL] + 1) / 2;
\r
1880 unsigned di = regs.w[DI];
\r
1881 unsigned si = regs.w[SI];
\r
1884 CarryVal = 0; /* NOT ADC */
\r
1885 for(int i = 0; i < count; i++) {
\r
1886 tmp = GetMemB(ES, di);
\r
1887 tmp2 = GetMemB(DS, si);
\r
1888 int v1 = (tmp >> 4) * 10 + (tmp & 0xf);
\r
1889 int v2 = (tmp2 >> 4) * 10 + (tmp2 & 0xf), result;
\r
1890 if(v1 < (v2 + CarryVal)) {
\r
1892 result = v1 - (v2 + CarryVal);
\r
1895 result = v1 - (v2 + CarryVal);
\r
1898 v1 = ((result / 10) << 4) | (result % 10);
\r
1899 PutMemB(ES, di, v1);
\r
1906 OverVal = CarryVal;
\r
1907 icount -= 7 + 19 * count;
\r
1913 case 0x26: /* 0F 22 59 - cmp4s */
\r
1915 int count = (regs.b[CL] + 1) / 2;
\r
1916 unsigned di = regs.w[DI];
\r
1917 unsigned si = regs.w[SI];
\r
1920 CarryVal = 0; /* NOT ADC */
\r
1921 for(int i = 0; i < count; i++) {
\r
1922 tmp = GetMemB(ES, di);
\r
1923 tmp2 = GetMemB(DS, si);
\r
1924 int v1 = (tmp >> 4) * 10 + (tmp & 0xf);
\r
1925 int v2 = (tmp2 >> 4) * 10 + (tmp2 & 0xf), result;
\r
1926 if(v1 < (v2 + CarryVal)) {
\r
1928 result = v1 - (v2 + CarryVal);
\r
1931 result = v1 - (v2 + CarryVal);
\r
1934 v1 = ((result / 10) << 4) | (result % 10);
\r
1935 /* PutMemB(ES, di, v1); /* no store, only compare */
\r
1942 OverVal = CarryVal;
\r
1943 icount -= 7 + 19 * (regs.b[CL] + 1);
\r
1946 case 0x28: /* 0F 28 C7 - ROL4 bh */
\r
1948 if(ModRM >= 0xc0) {
\r
1949 tmp = regs.b[Mod_RM.RM.b[ModRM]];
\r
1954 tmp = ReadByte(ea);
\r
1955 icount = old - 28;
\r
1958 tmp |= regs.b[AL] & 0xf;
\r
1959 regs.b[AL] = (regs.b[AL] & 0xf0) | ((tmp >> 8) & 0xf);
\r
1961 PutbackRMByte(ModRM, tmp);
\r
1963 case 0x29: /* 0F 29 C7 - ROL4 bx */
\r
1966 case 0x2A: /* 0F 2a c2 - ROR4 bh */
\r
1968 if(ModRM >= 0xc0) {
\r
1969 tmp = regs.b[Mod_RM.RM.b[ModRM]];
\r
1974 tmp = ReadByte(ea);
\r
1975 icount = old - 33;
\r
1977 tmp2 = (regs.b[AL] & 0xf) << 4;
\r
1978 regs.b[AL] = (regs.b[AL] & 0xf0) | (tmp & 0xf);
\r
1979 tmp = tmp2 | (tmp >> 4);
\r
1980 PutbackRMByte(ModRM, tmp);
\r
1982 case 0x2B: /* 0F 2b c2 - ROR4 bx */
\r
1985 case 0x2D: /* 0Fh 2Dh < 1111 1RRR> */
\r
1989 case 0x31: /* 0F 31 [mod:reg:r/m] - INS reg8, reg8 or INS reg8, imm4 */
\r
1991 if(ModRM >= 0xc0) {
\r
1992 tmp = regs.b[Mod_RM.RM.b[ModRM]];
\r
1997 tmp = ReadByte(ea);
\r
1998 icount = old - 33;
\r
2001 case 0x33: /* 0F 33 [mod:reg:r/m] - EXT reg8, reg8 or EXT reg8, imm4 */
\r
2003 if(ModRM >= 0xc0) {
\r
2004 tmp = regs.b[Mod_RM.RM.b[ModRM]];
\r
2009 tmp = ReadByte(ea);
\r
2010 icount = old - 33;
\r
2035 case 0xff: /* 0F ff imm8 - BRKEM */
\r
2044 inline void I86::_adc_br8() /* Opcode 0x10 */
\r
2046 DEF_br8(dst, src);
\r
2047 icount -= (ModRM >= 0xc0) ? timing.alu_rr8 : timing.alu_mr8;
\r
2050 PutbackRMByte(ModRM, dst);
\r
2053 inline void I86::_adc_wr16() /* Opcode 0x11 */
\r
2055 DEF_wr16(dst, src);
\r
2056 icount -= (ModRM >= 0xc0) ? timing.alu_rr16 : timing.alu_mr16;
\r
2059 PutbackRMWord(ModRM, dst);
\r
2062 inline void I86::_adc_r8b() /* Opcode 0x12 */
\r
2064 DEF_r8b(dst, src);
\r
2065 icount -= (ModRM >= 0xc0) ? timing.alu_rr8 : timing.alu_rm8;
\r
2068 RegByte(ModRM) = dst;
\r
2071 inline void I86::_adc_r16w() /* Opcode 0x13 */
\r
2073 DEF_r16w(dst, src);
\r
2074 icount -= (ModRM >= 0xc0) ? timing.alu_rr16 : timing.alu_rm16;
\r
2077 RegWord(ModRM) = dst;
\r
2080 inline void I86::_adc_ald8() /* Opcode 0x14 */
\r
2082 DEF_ald8(dst, src);
\r
2083 icount -= timing.alu_ri8;
\r
2089 inline void I86::_adc_axd16() /* Opcode 0x15 */
\r
2091 DEF_axd16(dst, src);
\r
2092 icount -= timing.alu_ri16;
\r
2098 inline void I86::_push_ss() /* Opcode 0x16 */
\r
2101 icount -= timing.push_seg;
\r
2104 inline void I86::_pop_ss() /* Opcode 0x17 */
\r
2107 base[SS] = SegBase(SS);
\r
2108 icount -= timing.pop_seg;
\r
2109 instruction(FETCHOP); /* no interrupt before next instruction */
\r
2112 inline void I86::_sbb_br8() /* Opcode 0x18 */
\r
2114 DEF_br8(dst, src);
\r
2115 icount -= (ModRM >= 0xc0) ? timing.alu_rr8 : timing.alu_mr8;
\r
2118 PutbackRMByte(ModRM, dst);
\r
2121 inline void I86::_sbb_wr16() /* Opcode 0x19 */
\r
2123 DEF_wr16(dst, src);
\r
2124 icount -= (ModRM >= 0xc0) ? timing.alu_rr16 : timing.alu_mr16;
\r
2127 PutbackRMWord(ModRM, dst);
\r
2130 inline void I86::_sbb_r8b() /* Opcode 0x1a */
\r
2132 DEF_r8b(dst, src);
\r
2133 icount -= (ModRM >= 0xc0) ? timing.alu_rr8 : timing.alu_rm8;
\r
2136 RegByte(ModRM) = dst;
\r
2139 inline void I86::_sbb_r16w() /* Opcode 0x1b */
\r
2141 DEF_r16w(dst, src);
\r
2142 icount -= (ModRM >= 0xc0) ? timing.alu_rr16 : timing.alu_rm16;
\r
2145 RegWord(ModRM) = dst;
\r
2148 inline void I86::_sbb_ald8() /* Opcode 0x1c */
\r
2150 DEF_ald8(dst, src);
\r
2151 icount -= timing.alu_ri8;
\r
2157 inline void I86::_sbb_axd16() /* Opcode 0x1d */
\r
2159 DEF_axd16(dst, src);
\r
2160 icount -= timing.alu_ri16;
\r
2166 inline void I86::_push_ds() /* Opcode 0x1e */
\r
2169 icount -= timing.push_seg;
\r
2172 inline void I86::_pop_ds() /* Opcode 0x1f */
\r
2175 base[DS] = SegBase(DS);
\r
2176 icount -= timing.push_seg;
\r
2179 inline void I86::_and_br8() /* Opcode 0x20 */
\r
2181 DEF_br8(dst, src);
\r
2182 icount -= (ModRM >= 0xc0) ? timing.alu_rr8 : timing.alu_mr8;
\r
2184 PutbackRMByte(ModRM, dst);
\r
2187 inline void I86::_and_wr16() /* Opcode 0x21 */
\r
2189 DEF_wr16(dst, src);
\r
2190 icount -= (ModRM >= 0xc0) ? timing.alu_rr16 : timing.alu_mr16;
\r
2192 PutbackRMWord(ModRM, dst);
\r
2195 inline void I86::_and_r8b() /* Opcode 0x22 */
\r
2197 DEF_r8b(dst, src);
\r
2198 icount -= (ModRM >= 0xc0) ? timing.alu_rr8 : timing.alu_rm8;
\r
2200 RegByte(ModRM) = dst;
\r
2203 inline void I86::_and_r16w() /* Opcode 0x23 */
\r
2205 DEF_r16w(dst, src);
\r
2206 icount -= (ModRM >= 0xc0) ? timing.alu_rr16 : timing.alu_rm16;
\r
2208 RegWord(ModRM) = dst;
\r
2211 inline void I86::_and_ald8() /* Opcode 0x24 */
\r
2213 DEF_ald8(dst, src);
\r
2214 icount -= timing.alu_ri8;
\r
2219 inline void I86::_and_axd16() /* Opcode 0x25 */
\r
2221 DEF_axd16(dst, src);
\r
2222 icount -= timing.alu_ri16;
\r
2227 inline void I86::_es() /* Opcode 0x26 */
\r
2229 seg_prefix = true;
\r
2231 icount -= timing.override;
\r
2232 instruction(FETCHOP);
\r
2235 inline void I86::_daa() /* Opcode 0x27 */
\r
2237 if(AF || ((regs.b[AL] & 0xf) > 9)) {
\r
2239 regs.b[AL] = tmp = regs.b[AL] + 6;
\r
2241 CarryVal |= tmp & 0x100;
\r
2244 if(CF || (regs.b[AL] > 0x9f)) {
\r
2245 regs.b[AL] += 0x60;
\r
2249 SetSZPF_Byte(regs.b[AL]);
\r
2250 icount -= timing.daa;
\r
2253 inline void I86::_sub_br8() /* Opcode 0x28 */
\r
2255 DEF_br8(dst, src);
\r
2256 icount -= (ModRM >= 0xc0) ? timing.alu_rr8 : timing.alu_mr8;
\r
2258 PutbackRMByte(ModRM, dst);
\r
2261 inline void I86::_sub_wr16() /* Opcode 0x29 */
\r
2263 DEF_wr16(dst, src);
\r
2264 icount -= (ModRM >= 0xc0) ? timing.alu_rr16 : timing.alu_mr16;
\r
2266 PutbackRMWord(ModRM, dst);
\r
2269 inline void I86::_sub_r8b() /* Opcode 0x2a */
\r
2271 DEF_r8b(dst, src);
\r
2272 icount -= (ModRM >= 0xc0) ? timing.alu_rr8 : timing.alu_rm8;
\r
2274 RegByte(ModRM) = dst;
\r
2277 inline void I86::_sub_r16w() /* Opcode 0x2b */
\r
2279 DEF_r16w(dst, src);
\r
2280 icount -= (ModRM >= 0xc0) ? timing.alu_rr16 : timing.alu_rm16;
\r
2282 RegWord(ModRM) = dst;
\r
2285 inline void I86::_sub_ald8() /* Opcode 0x2c */
\r
2287 DEF_ald8(dst, src);
\r
2288 icount -= timing.alu_ri8;
\r
2293 inline void I86::_sub_axd16() /* Opcode 0x2d */
\r
2295 DEF_axd16(dst, src);
\r
2296 icount -= timing.alu_ri16;
\r
2301 inline void I86::_cs() /* Opcode 0x2e */
\r
2303 seg_prefix = true;
\r
2305 icount -= timing.override;
\r
2306 instruction(FETCHOP);
\r
2309 inline void I86::_das() /* Opcode 0x2f */
\r
2311 uint8 tmpAL = regs.b[AL];
\r
2312 if(AF || ((regs.b[AL] & 0xf) > 9)) {
\r
2314 regs.b[AL] = tmp = regs.b[AL] - 6;
\r
2316 CarryVal |= tmp & 0x100;
\r
2319 if(CF || (tmpAL > 0x9f)) {
\r
2320 regs.b[AL] -= 0x60;
\r
2324 SetSZPF_Byte(regs.b[AL]);
\r
2325 icount -= timing.das;
\r
2328 inline void I86::_xor_br8() /* Opcode 0x30 */
\r
2330 DEF_br8(dst, src);
\r
2331 icount -= (ModRM >= 0xc0) ? timing.alu_rr8 : timing.alu_mr8;
\r
2333 PutbackRMByte(ModRM, dst);
\r
2336 inline void I86::_xor_wr16() /* Opcode 0x31 */
\r
2338 DEF_wr16(dst, src);
\r
2339 icount -= (ModRM >= 0xc0) ? timing.alu_rr16 : timing.alu_mr16;
\r
2341 PutbackRMWord(ModRM, dst);
\r
2344 inline void I86::_xor_r8b() /* Opcode 0x32 */
\r
2346 DEF_r8b(dst, src);
\r
2347 icount -= (ModRM >= 0xc0) ? timing.alu_rr8 : timing.alu_rm8;
\r
2349 RegByte(ModRM) = dst;
\r
2352 inline void I86::_xor_r16w() /* Opcode 0x33 */
\r
2354 DEF_r16w(dst, src);
\r
2355 icount -= (ModRM >= 0xc0) ? timing.alu_rr16 : timing.alu_rm16;
\r
2357 RegWord(ModRM) = dst;
\r
2360 inline void I86::_xor_ald8() /* Opcode 0x34 */
\r
2362 DEF_ald8(dst, src);
\r
2363 icount -= timing.alu_ri8;
\r
2368 inline void I86::_xor_axd16() /* Opcode 0x35 */
\r
2370 DEF_axd16(dst, src);
\r
2371 icount -= timing.alu_ri16;
\r
2376 inline void I86::_ss() /* Opcode 0x36 */
\r
2378 seg_prefix = true;
\r
2380 icount -= timing.override;
\r
2381 instruction(FETCHOP);
\r
2384 inline void I86::_aaa() /* Opcode 0x37 */
\r
2386 uint8 ALcarry = 1;
\r
2387 if(regs.b[AL]>0xf9) {
\r
2390 if(AF || ((regs.b[AL] & 0xf) > 9)) {
\r
2392 regs.b[AH] += ALcarry;
\r
2399 regs.b[AL] &= 0x0F;
\r
2400 icount -= timing.aaa;
\r
2403 inline void I86::_cmp_br8() /* Opcode 0x38 */
\r
2405 DEF_br8(dst, src);
\r
2406 icount -= (ModRM >= 0xc0) ? timing.alu_rr8 : timing.alu_rm8;
\r
2410 inline void I86::_cmp_wr16() /* Opcode 0x39 */
\r
2412 DEF_wr16(dst, src);
\r
2413 icount -= (ModRM >= 0xc0) ? timing.alu_rr16 : timing.alu_rm16;
\r
2417 inline void I86::_cmp_r8b() /* Opcode 0x3a */
\r
2419 DEF_r8b(dst, src);
\r
2420 icount -= (ModRM >= 0xc0) ? timing.alu_rr8 : timing.alu_rm8;
\r
2424 inline void I86::_cmp_r16w() /* Opcode 0x3b */
\r
2426 DEF_r16w(dst, src);
\r
2427 icount -= (ModRM >= 0xc0) ? timing.alu_rr16 : timing.alu_rm16;
\r
2431 inline void I86::_cmp_ald8() /* Opcode 0x3c */
\r
2433 DEF_ald8(dst, src);
\r
2434 icount -= timing.alu_ri8;
\r
2438 inline void I86::_cmp_axd16() /* Opcode 0x3d */
\r
2440 DEF_axd16(dst, src);
\r
2441 icount -= timing.alu_ri16;
\r
2445 inline void I86::_ds() /* Opcode 0x3e */
\r
2447 seg_prefix = true;
\r
2449 icount -= timing.override;
\r
2450 instruction(FETCHOP);
\r
2453 inline void I86::_aas() /* Opcode 0x3f */
\r
2455 uint8 ALcarry = 1;
\r
2456 if(regs.b[AL] > 0xf9) {
\r
2459 if(AF || ((regs.b[AL] & 0xf) > 9)) {
\r
2468 regs.b[AL] &= 0x0F;
\r
2469 icount -= timing.aas;
\r
2472 #define IncWordReg(Reg) { \
\r
2473 unsigned tmp = (unsigned)regs.w[Reg]; \
\r
2474 unsigned tmp1 = tmp + 1; \
\r
2475 SetOFW_Add(tmp1, tmp, 1); \
\r
2476 SetAF(tmp1, tmp, 1); \
\r
2477 SetSZPF_Word(tmp1); \
\r
2478 regs.w[Reg] = tmp1; \
\r
2479 icount -= timing.incdec_r16; \
\r
2482 inline void I86::_inc_ax() /* Opcode 0x40 */
\r
2487 inline void I86::_inc_cx() /* Opcode 0x41 */
\r
2492 inline void I86::_inc_dx() /* Opcode 0x42 */
\r
2497 inline void I86::_inc_bx() /* Opcode 0x43 */
\r
2502 inline void I86::_inc_sp() /* Opcode 0x44 */
\r
2507 inline void I86::_inc_bp() /* Opcode 0x45 */
\r
2512 inline void I86::_inc_si() /* Opcode 0x46 */
\r
2517 inline void I86::_inc_di() /* Opcode 0x47 */
\r
2522 #define DecWordReg(Reg) { \
\r
2523 unsigned tmp = (unsigned)regs.w[Reg]; \
\r
2524 unsigned tmp1 = tmp - 1; \
\r
2525 SetOFW_Sub(tmp1, 1, tmp); \
\r
2526 SetAF(tmp1, tmp, 1); \
\r
2527 SetSZPF_Word(tmp1); \
\r
2528 regs.w[Reg] = tmp1; \
\r
2529 icount -= timing.incdec_r16; \
\r
2532 inline void I86::_dec_ax() /* Opcode 0x48 */
\r
2537 inline void I86::_dec_cx() /* Opcode 0x49 */
\r
2542 inline void I86::_dec_dx() /* Opcode 0x4a */
\r
2547 inline void I86::_dec_bx() /* Opcode 0x4b */
\r
2552 inline void I86::_dec_sp() /* Opcode 0x4c */
\r
2557 inline void I86::_dec_bp() /* Opcode 0x4d */
\r
2562 inline void I86::_dec_si() /* Opcode 0x4e */
\r
2567 inline void I86::_dec_di() /* Opcode 0x4f */
\r
2572 inline void I86::_push_ax() /* Opcode 0x50 */
\r
2574 icount -= timing.push_r16;
\r
2578 inline void I86::_push_cx() /* Opcode 0x51 */
\r
2580 icount -= timing.push_r16;
\r
2584 inline void I86::_push_dx() /* Opcode 0x52 */
\r
2586 icount -= timing.push_r16;
\r
2590 inline void I86::_push_bx() /* Opcode 0x53 */
\r
2592 icount -= timing.push_r16;
\r
2596 inline void I86::_push_sp() /* Opcode 0x54 */
\r
2598 unsigned tmp = regs.w[SP];
\r
2600 icount -= timing.push_r16;
\r
2604 inline void I86::_push_bp() /* Opcode 0x55 */
\r
2606 icount -= timing.push_r16;
\r
2610 inline void I86::_push_si() /* Opcode 0x56 */
\r
2612 icount -= timing.push_r16;
\r
2616 inline void I86::_push_di() /* Opcode 0x57 */
\r
2618 icount -= timing.push_r16;
\r
2622 inline void I86::_pop_ax() /* Opcode 0x58 */
\r
2624 icount -= timing.pop_r16;
\r
2628 inline void I86::_pop_cx() /* Opcode 0x59 */
\r
2630 icount -= timing.pop_r16;
\r
2634 inline void I86::_pop_dx() /* Opcode 0x5a */
\r
2636 icount -= timing.pop_r16;
\r
2640 inline void I86::_pop_bx() /* Opcode 0x5b */
\r
2642 icount -= timing.pop_r16;
\r
2646 inline void I86::_pop_sp() /* Opcode 0x5c */
\r
2650 icount -= timing.pop_r16;
\r
2655 inline void I86::_pop_bp() /* Opcode 0x5d */
\r
2657 icount -= timing.pop_r16;
\r
2661 inline void I86::_pop_si() /* Opcode 0x5e */
\r
2663 icount -= timing.pop_r16;
\r
2667 inline void I86::_pop_di() /* Opcode 0x5f */
\r
2669 icount -= timing.pop_r16;
\r
2673 inline void I86::_pusha() /* Opcode 0x60 */
\r
2675 unsigned tmp = regs.w[SP];
\r
2677 icount -= timing.pusha;
\r
2688 inline void I86::_popa() /* Opcode 0x61 */
\r
2692 icount -= timing.popa;
\r
2703 inline void I86::_bound() /* Opcode 0x62 */
\r
2705 unsigned ModRM = FETCHOP;
\r
2706 int low = (int16)GetRMWord(ModRM);
\r
2707 int high = (int16)GetNextRMWord;
\r
2708 int tmp = (int16)RegWord(ModRM);
\r
2709 if(tmp < low || tmp>high) {
\r
2710 pc -= (seg_prefix ? 3 : 2);
\r
2711 interrupt(BOUNDS_CHECK_FAULT);
\r
2713 icount -= timing.bound;
\r
2716 inline void I86::_repc(int flagval)
\r
2719 unsigned next = FETCHOP;
\r
2720 unsigned count = regs.w[CX];
\r
2723 case 0x26: /* ES: */
\r
2724 seg_prefix = true;
\r
2729 case 0x2e: /* CS: */
\r
2730 seg_prefix = true;
\r
2735 case 0x36: /* SS: */
\r
2736 seg_prefix = true;
\r
2741 case 0x3e: /* DS: */
\r
2742 seg_prefix = true;
\r
2747 case 0x6c: /* REP INSB */
\r
2748 icount -= 9 - count;
\r
2749 for(; (CF == flagval) && (count > 0); count--) {
\r
2752 regs.w[CX] = count;
\r
2754 case 0x6d: /* REP INSW */
\r
2755 icount -= 9 - count;
\r
2756 for(; (CF == flagval) && (count > 0); count--) {
\r
2759 regs.w[CX] = count;
\r
2761 case 0x6e: /* REP OUTSB */
\r
2762 icount -= 9 - count;
\r
2763 for(; (CF == flagval) && (count > 0); count--) {
\r
2766 regs.w[CX] = count;
\r
2768 case 0x6f: /* REP OUTSW */
\r
2769 icount -= 9 - count;
\r
2770 for(; (CF == flagval) && (count > 0); count--) {
\r
2773 regs.w[CX] = count;
\r
2775 case 0xa4: /* REP MOVSB */
\r
2776 icount -= 9 - count;
\r
2777 for(; (CF == flagval) && (count > 0); count--) {
\r
2780 regs.w[CX] = count;
\r
2782 case 0xa5: /* REP MOVSW */
\r
2783 icount -= 9 - count;
\r
2784 for(; (CF == flagval) && (count > 0); count--) {
\r
2787 regs.w[CX] = count;
\r
2789 case 0xa6: /* REP(N)E CMPSB */
\r
2791 for(ZeroVal = !flagval; (ZF == flagval) && (CF == flagval) && (count > 0); count--) {
\r
2794 regs.w[CX] = count;
\r
2796 case 0xa7: /* REP(N)E CMPSW */
\r
2798 for(ZeroVal = !flagval; (ZF == flagval) && (CF == flagval) && (count > 0); count--) {
\r
2801 regs.w[CX] = count;
\r
2803 case 0xaa: /* REP STOSB */
\r
2804 icount -= 9 - count;
\r
2805 for(; (CF == flagval) && (count > 0); count--) {
\r
2808 regs.w[CX] = count;
\r
2810 case 0xab: /* REP STOSW */
\r
2811 icount -= 9 - count;
\r
2812 for(; (CF == flagval) && (count > 0); count--) {
\r
2815 regs.w[CX] = count;
\r
2817 case 0xac: /* REP LODSB */
\r
2819 for(; (CF == flagval) && (count > 0); count--) {
\r
2822 regs.w[CX] = count;
\r
2824 case 0xad: /* REP LODSW */
\r
2826 for(; (CF == flagval) && (count > 0); count--) {
\r
2829 regs.w[CX] = count;
\r
2831 case 0xae: /* REP(N)E SCASB */
\r
2833 for(ZeroVal = !flagval; (ZF == flagval) && (CF == flagval) && (count > 0); count--) {
\r
2836 regs.w[CX] = count;
\r
2838 case 0xaf: /* REP(N)E SCASW */
\r
2840 for(ZeroVal = !flagval; (ZF == flagval) && (CF == flagval) && (count > 0); count--) {
\r
2843 regs.w[CX] = count;
\r
2846 instruction(next);
\r
2851 inline void I86::_push_d16() /* Opcode 0x68 */
\r
2853 unsigned tmp = FETCH;
\r
2854 icount -= timing.push_imm;
\r
2855 tmp += FETCH << 8;
\r
2859 inline void I86::_imul_d16() /* Opcode 0x69 */
\r
2861 DEF_r16w(dst, src);
\r
2862 unsigned src2 = FETCH;
\r
2863 src += (FETCH << 8);
\r
2864 icount -= (ModRM >= 0xc0) ? timing.imul_rri16 : timing.imul_rmi16;
\r
2865 dst = (int32)((int16)src) * (int32)((int16)src2);
\r
2866 CarryVal = OverVal = (((int32)dst) >> 15 != 0) && (((int32)dst) >> 15 != -1);
\r
2867 RegWord(ModRM) = (uint16)dst;
\r
2870 inline void I86::_push_d8() /* Opcode 0x6a */
\r
2872 unsigned tmp = (uint16)((int16)((int8)FETCH));
\r
2873 icount -= timing.push_imm;
\r
2877 inline void I86::_imul_d8() /* Opcode 0x6b */
\r
2879 DEF_r16w(dst, src);
\r
2880 unsigned src2 = (uint16)((int16)((int8)FETCH));
\r
2881 icount -= (ModRM >= 0xc0) ? timing.imul_rri8 : timing.imul_rmi8;
\r
2882 dst = (int32)((int16)src) * (int32)((int16)src2);
\r
2883 CarryVal = OverVal = (((int32)dst) >> 15 != 0) && (((int32)dst) >> 15 != -1);
\r
2884 RegWord(ModRM) = (uint16)dst;
\r
2887 inline void I86::_insb() /* Opcode 0x6c */
\r
2889 icount -= timing.ins8;
\r
2890 PutMemB(ES, regs.w[DI], read_port_byte(regs.w[DX]));
\r
2891 regs.w[DI] += DirVal;
\r
2894 inline void I86::_insw() /* Opcode 0x6d */
\r
2896 icount -= timing.ins16;
\r
2897 PutMemW(ES, regs.w[DI], read_port_word(regs.w[DX]));
\r
2898 regs.w[DI] += 2 * DirVal;
\r
2901 inline void I86::_outsb() /* Opcode 0x6e */
\r
2903 icount -= timing.outs8;
\r
2904 write_port_byte(regs.w[DX], GetMemB(DS, regs.w[SI]));
\r
2905 regs.w[SI] += DirVal; /* GOL 11/27/01 */
\r
2908 inline void I86::_outsw() /* Opcode 0x6f */
\r
2910 icount -= timing.outs16;
\r
2911 write_port_word(regs.w[DX], GetMemW(DS, regs.w[SI]));
\r
2912 regs.w[SI] += 2 * DirVal; /* GOL 11/27/01 */
\r
2915 inline void I86::_jo() /* Opcode 0x70 */
\r
2917 int tmp = (int)((int8)FETCH);
\r
2920 icount -= timing.jcc_t;
\r
2922 icount -= timing.jcc_nt;
\r
2926 inline void I86::_jno() /* Opcode 0x71 */
\r
2928 int tmp = (int)((int8)FETCH);
\r
2931 icount -= timing.jcc_t;
\r
2933 icount -= timing.jcc_nt;
\r
2937 inline void I86::_jb() /* Opcode 0x72 */
\r
2939 int tmp = (int)((int8)FETCH);
\r
2942 icount -= timing.jcc_t;
\r
2944 icount -= timing.jcc_nt;
\r
2948 inline void I86::_jnb() /* Opcode 0x73 */
\r
2950 int tmp = (int)((int8)FETCH);
\r
2953 icount -= timing.jcc_t;
\r
2955 icount -= timing.jcc_nt;
\r
2959 inline void I86::_jz() /* Opcode 0x74 */
\r
2961 int tmp = (int)((int8)FETCH);
\r
2964 icount -= timing.jcc_t;
\r
2966 icount -= timing.jcc_nt;
\r
2970 inline void I86::_jnz() /* Opcode 0x75 */
\r
2972 int tmp = (int)((int8)FETCH);
\r
2975 icount -= timing.jcc_t;
\r
2977 icount -= timing.jcc_nt;
\r
2981 inline void I86::_jbe() /* Opcode 0x76 */
\r
2983 int tmp = (int)((int8)FETCH);
\r
2986 icount -= timing.jcc_t;
\r
2988 icount -= timing.jcc_nt;
\r
2992 inline void I86::_jnbe() /* Opcode 0x77 */
\r
2994 int tmp = (int)((int8)FETCH);
\r
2997 icount -= timing.jcc_t;
\r
2999 icount -= timing.jcc_nt;
\r
3003 inline void I86::_js() /* Opcode 0x78 */
\r
3005 int tmp = (int)((int8)FETCH);
\r
3008 icount -= timing.jcc_t;
\r
3010 icount -= timing.jcc_nt;
\r
3014 inline void I86::_jns() /* Opcode 0x79 */
\r
3016 int tmp = (int)((int8)FETCH);
\r
3019 icount -= timing.jcc_t;
\r
3021 icount -= timing.jcc_nt;
\r
3025 inline void I86::_jp() /* Opcode 0x7a */
\r
3027 int tmp = (int)((int8)FETCH);
\r
3030 icount -= timing.jcc_t;
\r
3032 icount -= timing.jcc_nt;
\r
3036 inline void I86::_jnp() /* Opcode 0x7b */
\r
3038 int tmp = (int)((int8)FETCH);
\r
3041 icount -= timing.jcc_t;
\r
3043 icount -= timing.jcc_nt;
\r
3047 inline void I86::_jl() /* Opcode 0x7c */
\r
3049 int tmp = (int)((int8)FETCH);
\r
3050 if((SF!= OF) && !ZF) {
\r
3052 icount -= timing.jcc_t;
\r
3054 icount -= timing.jcc_nt;
\r
3058 inline void I86::_jnl() /* Opcode 0x7d */
\r
3060 int tmp = (int)((int8)FETCH);
\r
3061 if(ZF || (SF == OF)) {
\r
3063 icount -= timing.jcc_t;
\r
3065 icount -= timing.jcc_nt;
\r
3069 inline void I86::_jle() /* Opcode 0x7e */
\r
3071 int tmp = (int)((int8)FETCH);
\r
3072 if(ZF || (SF!= OF)) {
\r
3074 icount -= timing.jcc_t;
\r
3076 icount -= timing.jcc_nt;
\r
3080 inline void I86::_jnle() /* Opcode 0x7f */
\r
3082 int tmp = (int)((int8)FETCH);
\r
3083 if((SF == OF) && !ZF) {
\r
3085 icount -= timing.jcc_t;
\r
3087 icount -= timing.jcc_nt;
\r
3091 inline void I86::_80pre() /* Opcode 0x80 */
\r
3093 unsigned ModRM = FETCHOP;
\r
3094 unsigned dst = GetRMByte(ModRM);
\r
3095 unsigned src = FETCH;
\r
3097 switch((ModRM >> 3) & 7) {
\r
3098 case 0: /* ADD eb, d8 */
\r
3100 PutbackRMByte(ModRM, dst);
\r
3101 icount -= (ModRM >= 0xc0) ? timing.alu_ri8 : timing.alu_mi8;
\r
3103 case 1: /* OR eb, d8 */
\r
3105 PutbackRMByte(ModRM, dst);
\r
3106 icount -= (ModRM >= 0xc0) ? timing.alu_ri8 : timing.alu_mi8;
\r
3108 case 2: /* ADC eb, d8 */
\r
3111 PutbackRMByte(ModRM, dst);
\r
3112 icount -= (ModRM >= 0xc0) ? timing.alu_ri8 : timing.alu_mi8;
\r
3114 case 3: /* SBB eb, b8 */
\r
3117 PutbackRMByte(ModRM, dst);
\r
3118 icount -= (ModRM >= 0xc0) ? timing.alu_ri8 : timing.alu_mi8;
\r
3120 case 4: /* AND eb, d8 */
\r
3122 PutbackRMByte(ModRM, dst);
\r
3123 icount -= (ModRM >= 0xc0) ? timing.alu_ri8 : timing.alu_mi8;
\r
3125 case 5: /* SUB eb, d8 */
\r
3127 PutbackRMByte(ModRM, dst);
\r
3128 icount -= (ModRM >= 0xc0) ? timing.alu_ri8 : timing.alu_mi8;
\r
3130 case 6: /* XOR eb, d8 */
\r
3132 PutbackRMByte(ModRM, dst);
\r
3133 icount -= (ModRM >= 0xc0) ? timing.alu_ri8 : timing.alu_mi8;
\r
3135 case 7: /* CMP eb, d8 */
\r
3137 icount -= (ModRM >= 0xc0) ? timing.alu_ri8 : timing.alu_mi8_ro;
\r
3144 inline void I86::_81pre() /* Opcode 0x81 */
\r
3146 unsigned ModRM = FETCH;
\r
3147 unsigned dst = GetRMWord(ModRM);
\r
3148 unsigned src = FETCH;
\r
3149 src += (FETCH << 8);
\r
3151 switch((ModRM >> 3) & 7) {
\r
3152 case 0: /* ADD ew, d16 */
\r
3154 PutbackRMWord(ModRM, dst);
\r
3155 icount -= (ModRM >= 0xc0) ? timing.alu_ri16 : timing.alu_mi16;
\r
3157 case 1: /* OR ew, d16 */
\r
3159 PutbackRMWord(ModRM, dst);
\r
3160 icount -= (ModRM >= 0xc0) ? timing.alu_ri16 : timing.alu_mi16;
\r
3162 case 2: /* ADC ew, d16 */
\r
3165 PutbackRMWord(ModRM, dst);
\r
3166 icount -= (ModRM >= 0xc0) ? timing.alu_ri16 : timing.alu_mi16;
\r
3168 case 3: /* SBB ew, d16 */
\r
3171 PutbackRMWord(ModRM, dst);
\r
3172 icount -= (ModRM >= 0xc0) ? timing.alu_ri16 : timing.alu_mi16;
\r
3174 case 4: /* AND ew, d16 */
\r
3176 PutbackRMWord(ModRM, dst);
\r
3177 icount -= (ModRM >= 0xc0) ? timing.alu_ri16 : timing.alu_mi16;
\r
3179 case 5: /* SUB ew, d16 */
\r
3181 PutbackRMWord(ModRM, dst);
\r
3182 icount -= (ModRM >= 0xc0) ? timing.alu_ri16 : timing.alu_mi16;
\r
3184 case 6: /* XOR ew, d16 */
\r
3186 PutbackRMWord(ModRM, dst);
\r
3187 icount -= (ModRM >= 0xc0) ? timing.alu_ri16 : timing.alu_mi16;
\r
3189 case 7: /* CMP ew, d16 */
\r
3191 icount -= (ModRM >= 0xc0) ? timing.alu_ri16 : timing.alu_mi16_ro;
\r
3198 inline void I86::_82pre() /* Opcode 0x82 */
\r
3200 unsigned ModRM = FETCH;
\r
3201 unsigned dst = GetRMByte(ModRM);
\r
3202 unsigned src = FETCH;
\r
3204 switch((ModRM >> 3) & 7) {
\r
3205 case 0: /* ADD eb, d8 */
\r
3207 PutbackRMByte(ModRM, dst);
\r
3208 icount -= (ModRM >= 0xc0) ? timing.alu_ri8 : timing.alu_mi8;
\r
3210 case 1: /* OR eb, d8 */
\r
3212 PutbackRMByte(ModRM, dst);
\r
3213 icount -= (ModRM >= 0xc0) ? timing.alu_ri8 : timing.alu_mi8;
\r
3215 case 2: /* ADC eb, d8 */
\r
3218 PutbackRMByte(ModRM, dst);
\r
3219 icount -= (ModRM >= 0xc0) ? timing.alu_ri8 : timing.alu_mi8;
\r
3221 case 3: /* SBB eb, d8 */
\r
3224 PutbackRMByte(ModRM, dst);
\r
3225 icount -= (ModRM >= 0xc0) ? timing.alu_ri8 : timing.alu_mi8;
\r
3227 case 4: /* AND eb, d8 */
\r
3229 PutbackRMByte(ModRM, dst);
\r
3230 icount -= (ModRM >= 0xc0) ? timing.alu_ri8 : timing.alu_mi8;
\r
3232 case 5: /* SUB eb, d8 */
\r
3234 PutbackRMByte(ModRM, dst);
\r
3235 icount -= (ModRM >= 0xc0) ? timing.alu_ri8 : timing.alu_mi8;
\r
3237 case 6: /* XOR eb, d8 */
\r
3239 PutbackRMByte(ModRM, dst);
\r
3240 icount -= (ModRM >= 0xc0) ? timing.alu_ri8 : timing.alu_mi8;
\r
3242 case 7: /* CMP eb, d8 */
\r
3244 icount -= (ModRM >= 0xc0) ? timing.alu_ri8 : timing.alu_mi8_ro;
\r
3251 inline void I86::_83pre() /* Opcode 0x83 */
\r
3253 unsigned ModRM = FETCH;
\r
3254 unsigned dst = GetRMWord(ModRM);
\r
3255 unsigned src = (uint16)((int16)((int8)FETCH));
\r
3257 switch((ModRM >> 3) & 7) {
\r
3258 case 0: /* ADD ew, d16 */
\r
3260 PutbackRMWord(ModRM, dst);
\r
3261 icount -= (ModRM >= 0xc0) ? timing.alu_r16i8 : timing.alu_m16i8;
\r
3263 case 1: /* OR ew, d16 */
\r
3265 PutbackRMWord(ModRM, dst);
\r
3266 icount -= (ModRM >= 0xc0) ? timing.alu_r16i8 : timing.alu_m16i8;
\r
3268 case 2: /* ADC ew, d16 */
\r
3271 PutbackRMWord(ModRM, dst);
\r
3272 icount -= (ModRM >= 0xc0) ? timing.alu_r16i8 : timing.alu_m16i8;
\r
3274 case 3: /* SBB ew, d16 */
\r
3277 PutbackRMWord(ModRM, dst);
\r
3278 icount -= (ModRM >= 0xc0) ? timing.alu_r16i8 : timing.alu_m16i8;
\r
3280 case 4: /* AND ew, d16 */
\r
3282 PutbackRMWord(ModRM, dst);
\r
3283 icount -= (ModRM >= 0xc0) ? timing.alu_r16i8 : timing.alu_m16i8;
\r
3285 case 5: /* SUB ew, d16 */
\r
3287 PutbackRMWord(ModRM, dst);
\r
3288 icount -= (ModRM >= 0xc0) ? timing.alu_r16i8 : timing.alu_m16i8;
\r
3290 case 6: /* XOR ew, d16 */
\r
3292 PutbackRMWord(ModRM, dst);
\r
3293 icount -= (ModRM >= 0xc0) ? timing.alu_r16i8 : timing.alu_m16i8;
\r
3295 case 7: /* CMP ew, d16 */
\r
3297 icount -= (ModRM >= 0xc0) ? timing.alu_r16i8 : timing.alu_m16i8_ro;
\r
3304 inline void I86::_test_br8() /* Opcode 0x84 */
\r
3306 DEF_br8(dst, src);
\r
3307 icount -= (ModRM >= 0xc0) ? timing.alu_rr8 : timing.alu_rm8;
\r
3311 inline void I86::_test_wr16() /* Opcode 0x85 */
\r
3313 DEF_wr16(dst, src);
\r
3314 icount -= (ModRM >= 0xc0) ? timing.alu_rr16 : timing.alu_rm16;
\r
3318 inline void I86::_xchg_br8() /* Opcode 0x86 */
\r
3320 DEF_br8(dst, src);
\r
3321 icount -= (ModRM >= 0xc0) ? timing.xchg_rr8 : timing.xchg_rm8;
\r
3322 RegByte(ModRM) = dst;
\r
3323 PutbackRMByte(ModRM, src);
\r
3326 inline void I86::_xchg_wr16() /* Opcode 0x87 */
\r
3328 DEF_wr16(dst, src);
\r
3329 icount -= (ModRM >= 0xc0) ? timing.xchg_rr16 : timing.xchg_rm16;
\r
3330 RegWord(ModRM) = dst;
\r
3331 PutbackRMWord(ModRM, src);
\r
3334 inline void I86::_mov_br8() /* Opcode 0x88 */
\r
3336 unsigned ModRM = FETCH;
\r
3337 uint8 src = RegByte(ModRM);
\r
3338 icount -= (ModRM >= 0xc0) ? timing.mov_rr8 : timing.mov_mr8;
\r
3339 PutRMByte(ModRM, src);
\r
3342 inline void I86::_mov_wr16() /* Opcode 0x89 */
\r
3344 unsigned ModRM = FETCH;
\r
3345 uint16 src = RegWord(ModRM);
\r
3346 icount -= (ModRM >= 0xc0) ? timing.mov_rr16 : timing.mov_mr16;
\r
3347 PutRMWord(ModRM, src);
\r
3350 inline void I86::_mov_r8b() /* Opcode 0x8a */
\r
3352 unsigned ModRM = FETCH;
\r
3353 uint8 src = GetRMByte(ModRM);
\r
3354 icount -= (ModRM >= 0xc0) ? timing.mov_rr8 : timing.mov_rm8;
\r
3355 RegByte(ModRM) = src;
\r
3358 inline void I86::_mov_r16w() /* Opcode 0x8b */
\r
3360 unsigned ModRM = FETCH;
\r
3361 uint16 src = GetRMWord(ModRM);
\r
3362 icount -= (ModRM >= 0xc0) ? timing.mov_rr8 : timing.mov_rm16;
\r
3363 RegWord(ModRM) = src;
\r
3366 inline void I86::_mov_wsreg() /* Opcode 0x8c */
\r
3368 unsigned ModRM = FETCH;
\r
3369 icount -= (ModRM >= 0xc0) ? timing.mov_rs : timing.mov_ms;
\r
3370 if(ModRM & 0x20) {
\r
3371 return; /* 1xx is invalid */
\r
3373 PutRMWord(ModRM, sregs[(ModRM & 0x38) >> 3]);
\r
3376 inline void I86::_lea() /* Opcode 0x8d */
\r
3378 unsigned ModRM = FETCH;
\r
3379 icount -= timing.lea;
\r
3381 RegWord(ModRM) = eo; /* effective offset (no segment part) */
\r
3384 inline void I86::_mov_sregw() /* Opcode 0x8e */
\r
3386 unsigned ModRM = FETCH;
\r
3387 uint16 src = GetRMWord(ModRM);
\r
3389 icount -= (ModRM >= 0xc0) ? timing.mov_sr : timing.mov_sm;
\r
3390 switch((ModRM >> 3) & 7) {
\r
3391 case 0: /* mov es, ew */
\r
3393 base[ES] = SegBase(ES);
\r
3395 case 1: /* mov cs, ew */
\r
3396 break; /* doesn't do a jump far */
\r
3397 case 2: /* mov ss, ew */
\r
3399 base[SS] = SegBase(SS); /* no interrupt allowed before next instr */
\r
3400 instruction(FETCHOP);
\r
3402 case 3: /* mov ds, ew */
\r
3404 base[DS] = SegBase(DS);
\r
3416 inline void I86::_popw() /* Opcode 0x8f */
\r
3418 unsigned ModRM = FETCH;
\r
3421 icount -= (ModRM >= 0xc0) ? timing.pop_r16 : timing.pop_m16;
\r
3422 PutRMWord(ModRM, tmp);
\r
3425 #define XchgAXReg(Reg) { \
\r
3427 tmp = regs.w[Reg]; \
\r
3428 regs.w[Reg] = regs.w[AX]; \
\r
3429 regs.w[AX] = tmp; \
\r
3430 icount -= timing.xchg_ar16; \
\r
3433 inline void I86::_nop() /* Opcode 0x90 */
\r
3435 /* this is XchgAXReg(AX); */
\r
3436 icount -= timing.nop;
\r
3439 inline void I86::_xchg_axcx() /* Opcode 0x91 */
\r
3444 inline void I86::_xchg_axdx() /* Opcode 0x92 */
\r
3449 inline void I86::_xchg_axbx() /* Opcode 0x93 */
\r
3454 inline void I86::_xchg_axsp() /* Opcode 0x94 */
\r
3459 inline void I86::_xchg_axbp() /* Opcode 0x95 */
\r
3464 inline void I86::_xchg_axsi() /* Opcode 0x96 */
\r
3469 inline void I86::_xchg_axdi() /* Opcode 0x97 */
\r
3474 inline void I86::_cbw() /* Opcode 0x98 */
\r
3476 icount -= timing.cbw;
\r
3477 regs.b[AH] = (regs.b[AL] & 0x80) ? 0xff : 0;
\r
3480 inline void I86::_cwd() /* Opcode 0x99 */
\r
3482 icount -= timing.cwd;
\r
3483 regs.w[DX] = (regs.b[AH] & 0x80) ? 0xffff : 0;
\r
3486 inline void I86::_call_far() /* Opcode 0x9a */
\r
3488 unsigned tmp, tmp2;
\r
3492 tmp += FETCH << 8;
\r
3495 tmp2 += FETCH << 8;
\r
3497 ip = pc - base[CS];
\r
3500 sregs[CS] = (uint16)tmp2;
\r
3501 base[CS] = SegBase(CS);
\r
3502 pc = (base[CS] + (uint16)tmp) & AMASK;
\r
3503 #ifdef I86_BIOS_CALL
\r
3504 if(d_bios && d_bios->bios_call(pc, regs.w, sregs, &ZeroVal, &CarryVal)) {
\r
3509 icount -= timing.call_far;
\r
3512 inline void I86::_wait() /* Opcode 0x9b */
\r
3517 icount -= timing.wait;
\r
3520 inline void I86::_pushf() /* Opcode 0x9c */
\r
3523 icount -= timing.pushf;
\r
3525 tmp = CompressFlags();
\r
3526 PUSH(tmp | 0xf000);
\r
3529 inline void I86::_popf() /* Opcode 0x9d */
\r
3533 icount -= timing.popf;
\r
3540 /* if the IF is set, and an interrupt is pending, signal an interrupt */
\r
3541 if(IF && (int_state & INT_REQ_BIT)) {
\r
3546 inline void I86::_sahf() /* Opcode 0x9e */
\r
3548 unsigned tmp = (CompressFlags() & 0xff00) | (regs.b[AH] & 0xd5);
\r
3549 icount -= timing.sahf;
\r
3553 inline void I86::_lahf() /* Opcode 0x9f */
\r
3555 regs.b[AH] = CompressFlags() & 0xff;
\r
3556 icount -= timing.lahf;
\r
3559 inline void I86::_mov_aldisp() /* Opcode 0xa0 */
\r
3564 addr += FETCH << 8;
\r
3566 icount -= timing.mov_am8;
\r
3567 regs.b[AL] = GetMemB(DS, addr);
\r
3570 inline void I86::_mov_axdisp() /* Opcode 0xa1 */
\r
3575 addr += FETCH << 8;
\r
3577 icount -= timing.mov_am16;
\r
3578 regs.w[AX] = GetMemW(DS, addr);
\r
3581 inline void I86::_mov_dispal() /* Opcode 0xa2 */
\r
3586 addr += FETCH << 8;
\r
3588 icount -= timing.mov_ma8;
\r
3589 PutMemB(DS, addr, regs.b[AL]);
\r
3592 inline void I86::_mov_dispax() /* Opcode 0xa3 */
\r
3597 addr += FETCH << 8;
\r
3599 icount -= timing.mov_ma16;
\r
3600 PutMemW(DS, addr, regs.w[AX]);
\r
3603 inline void I86::_movsb() /* Opcode 0xa4 */
\r
3605 uint8 tmp = GetMemB(DS, regs.w[SI]);
\r
3606 PutMemB(ES, regs.w[DI], tmp);
\r
3607 regs.w[DI] += DirVal;
\r
3608 regs.w[SI] += DirVal;
\r
3609 icount -= timing.movs8;
\r
3612 inline void I86::_movsw() /* Opcode 0xa5 */
\r
3614 uint16 tmp = GetMemW(DS, regs.w[SI]);
\r
3615 PutMemW(ES, regs.w[DI], tmp);
\r
3616 regs.w[DI] += 2 * DirVal;
\r
3617 regs.w[SI] += 2 * DirVal;
\r
3618 icount -= timing.movs16;
\r
3621 inline void I86::_cmpsb() /* Opcode 0xa6 */
\r
3623 unsigned dst = GetMemB(ES, regs.w[DI]);
\r
3624 unsigned src = GetMemB(DS, regs.w[SI]);
\r
3625 SUBB(src, dst); /* opposite of the usual convention */
\r
3626 regs.w[DI] += DirVal;
\r
3627 regs.w[SI] += DirVal;
\r
3628 icount -= timing.cmps8;
\r
3631 inline void I86::_cmpsw() /* Opcode 0xa7 */
\r
3633 unsigned dst = GetMemW(ES, regs.w[DI]);
\r
3634 unsigned src = GetMemW(DS, regs.w[SI]);
\r
3635 SUBW(src, dst); /* opposite of the usual convention */
\r
3636 regs.w[DI] += 2 * DirVal;
\r
3637 regs.w[SI] += 2 * DirVal;
\r
3638 icount -= timing.cmps16;
\r
3641 inline void I86::_test_ald8() /* Opcode 0xa8 */
\r
3643 DEF_ald8(dst, src);
\r
3644 icount -= timing.alu_ri8;
\r
3648 inline void I86::_test_axd16() /* Opcode 0xa9 */
\r
3650 DEF_axd16(dst, src);
\r
3651 icount -= timing.alu_ri16;
\r
3655 inline void I86::_stosb() /* Opcode 0xaa */
\r
3657 PutMemB(ES, regs.w[DI], regs.b[AL]);
\r
3658 regs.w[DI] += DirVal;
\r
3659 icount -= timing.stos8;
\r
3662 inline void I86::_stosw() /* Opcode 0xab */
\r
3664 PutMemW(ES, regs.w[DI], regs.w[AX]);
\r
3665 regs.w[DI] += 2 * DirVal;
\r
3666 icount -= timing.stos16;
\r
3669 inline void I86::_lodsb() /* Opcode 0xac */
\r
3671 regs.b[AL] = GetMemB(DS, regs.w[SI]);
\r
3672 regs.w[SI] += DirVal;
\r
3673 icount -= timing.lods8;
\r
3676 inline void I86::_lodsw() /* Opcode 0xad */
\r
3678 regs.w[AX] = GetMemW(DS, regs.w[SI]);
\r
3679 regs.w[SI] += 2 * DirVal;
\r
3680 icount -= timing.lods16;
\r
3683 inline void I86::_scasb() /* Opcode 0xae */
\r
3685 unsigned src = GetMemB(ES, regs.w[DI]);
\r
3686 unsigned dst = regs.b[AL];
\r
3688 regs.w[DI] += DirVal;
\r
3689 icount -= timing.scas8;
\r
3692 inline void I86::_scasw() /* Opcode 0xaf */
\r
3694 unsigned src = GetMemW(ES, regs.w[DI]);
\r
3695 unsigned dst = regs.w[AX];
\r
3697 regs.w[DI] += 2 * DirVal;
\r
3698 icount -= timing.scas16;
\r
3701 inline void I86::_mov_ald8() /* Opcode 0xb0 */
\r
3703 regs.b[AL] = FETCH;
\r
3704 icount -= timing.mov_ri8;
\r
3707 inline void I86::_mov_cld8() /* Opcode 0xb1 */
\r
3709 regs.b[CL] = FETCH;
\r
3710 icount -= timing.mov_ri8;
\r
3713 inline void I86::_mov_dld8() /* Opcode 0xb2 */
\r
3715 regs.b[DL] = FETCH;
\r
3716 icount -= timing.mov_ri8;
\r
3719 inline void I86::_mov_bld8() /* Opcode 0xb3 */
\r
3721 regs.b[BL] = FETCH;
\r
3722 icount -= timing.mov_ri8;
\r
3725 inline void I86::_mov_ahd8() /* Opcode 0xb4 */
\r
3727 regs.b[AH] = FETCH;
\r
3728 icount -= timing.mov_ri8;
\r
3731 inline void I86::_mov_chd8() /* Opcode 0xb5 */
\r
3733 regs.b[CH] = FETCH;
\r
3734 icount -= timing.mov_ri8;
\r
3737 inline void I86::_mov_dhd8() /* Opcode 0xb6 */
\r
3739 regs.b[DH] = FETCH;
\r
3740 icount -= timing.mov_ri8;
\r
3743 inline void I86::_mov_bhd8() /* Opcode 0xb7 */
\r
3745 regs.b[BH] = FETCH;
\r
3746 icount -= timing.mov_ri8;
\r
3749 inline void I86::_mov_axd16() /* Opcode 0xb8 */
\r
3751 regs.b[AL] = FETCH;
\r
3752 regs.b[AH] = FETCH;
\r
3753 icount -= timing.mov_ri16;
\r
3756 inline void I86::_mov_cxd16() /* Opcode 0xb9 */
\r
3758 regs.b[CL] = FETCH;
\r
3759 regs.b[CH] = FETCH;
\r
3760 icount -= timing.mov_ri16;
\r
3763 inline void I86::_mov_dxd16() /* Opcode 0xba */
\r
3765 regs.b[DL] = FETCH;
\r
3766 regs.b[DH] = FETCH;
\r
3767 icount -= timing.mov_ri16;
\r
3770 inline void I86::_mov_bxd16() /* Opcode 0xbb */
\r
3772 regs.b[BL] = FETCH;
\r
3773 regs.b[BH] = FETCH;
\r
3774 icount -= timing.mov_ri16;
\r
3777 inline void I86::_mov_spd16() /* Opcode 0xbc */
\r
3779 regs.b[SPL] = FETCH;
\r
3780 regs.b[SPH] = FETCH;
\r
3781 icount -= timing.mov_ri16;
\r
3784 inline void I86::_mov_bpd16() /* Opcode 0xbd */
\r
3786 regs.b[BPL] = FETCH;
\r
3787 regs.b[BPH] = FETCH;
\r
3788 icount -= timing.mov_ri16;
\r
3791 inline void I86::_mov_sid16() /* Opcode 0xbe */
\r
3793 regs.b[SIL] = FETCH;
\r
3794 regs.b[SIH] = FETCH;
\r
3795 icount -= timing.mov_ri16;
\r
3798 inline void I86::_mov_did16() /* Opcode 0xbf */
\r
3800 regs.b[DIL] = FETCH;
\r
3801 regs.b[DIH] = FETCH;
\r
3802 icount -= timing.mov_ri16;
\r
3805 inline void I86::_rotshft_bd8() /* Opcode 0xc0 */
\r
3807 unsigned ModRM = FETCH;
\r
3808 unsigned count = FETCH;
\r
3810 rotate_shift_byte(ModRM, count);
\r
3813 inline void I86::_rotshft_wd8() /* Opcode 0xc1 */
\r
3815 unsigned ModRM = FETCH;
\r
3816 unsigned count = FETCH;
\r
3818 rotate_shift_word(ModRM, count);
\r
3821 inline void I86::_ret_d16() /* Opcode 0xc2 */
\r
3823 unsigned count = FETCH;
\r
3824 count += FETCH << 8;
\r
3826 pc = (pc + base[CS]) & AMASK;
\r
3827 regs.w[SP] += count;
\r
3828 icount -= timing.ret_near_imm;
\r
3831 inline void I86::_ret() /* Opcode 0xc3 */
\r
3834 pc = (pc + base[CS]) & AMASK;
\r
3835 icount -= timing.ret_near;
\r
3838 inline void I86::_les_dw() /* Opcode 0xc4 */
\r
3840 unsigned ModRM = FETCH;
\r
3841 uint16 tmp = GetRMWord(ModRM);
\r
3842 RegWord(ModRM) = tmp;
\r
3843 sregs[ES] = GetNextRMWord;
\r
3844 base[ES] = SegBase(ES);
\r
3845 icount -= timing.load_ptr;
\r
3848 inline void I86::_lds_dw() /* Opcode 0xc5 */
\r
3850 unsigned ModRM = FETCH;
\r
3851 uint16 tmp = GetRMWord(ModRM);
\r
3852 RegWord(ModRM) = tmp;
\r
3853 sregs[DS] = GetNextRMWord;
\r
3854 base[DS] = SegBase(DS);
\r
3855 icount -= timing.load_ptr;
\r
3858 inline void I86::_mov_bd8() /* Opcode 0xc6 */
\r
3860 unsigned ModRM = FETCH;
\r
3861 icount -= (ModRM >= 0xc0) ? timing.mov_ri8 : timing.mov_mi8;
\r
3862 PutImmRMByte(ModRM);
\r
3865 inline void I86::_mov_wd16() /* Opcode 0xc7 */
\r
3867 unsigned ModRM = FETCH;
\r
3868 icount -= (ModRM >= 0xc0) ? timing.mov_ri16 : timing.mov_mi16;
\r
3869 PutImmRMWord(ModRM);
\r
3872 inline void I86::_enter() /* Opcode 0xc8 */
\r
3874 unsigned nb = FETCH;
\r
3875 unsigned i, level;
\r
3879 icount -= (level == 0) ? timing.enter0 : (level == 1) ? timing.enter1 : timing.enter_base + level * timing.enter_count;
\r
3881 regs.w[BP] = regs.w[SP];
\r
3883 for(i = 1; i < level; i++) {
\r
3884 PUSH(GetMemW(SS, regs.w[BP] - i * 2));
\r
3891 inline void I86::_leav() /* Opcode 0xc9 */
\r
3893 icount -= timing.leave;
\r
3894 regs.w[SP] = regs.w[BP];
\r
3898 inline void I86::_retf_d16() /* Opcode 0xca */
\r
3900 unsigned count = FETCH;
\r
3901 count += FETCH << 8;
\r
3904 base[CS] = SegBase(CS);
\r
3905 pc = (pc + base[CS]) & AMASK;
\r
3906 regs.w[SP] += count;
\r
3907 icount -= timing.ret_far_imm;
\r
3910 inline void I86::_retf() /* Opcode 0xcb */
\r
3914 base[CS] = SegBase(CS);
\r
3915 pc = (pc + base[CS]) & AMASK;
\r
3916 icount -= timing.ret_far;
\r
3919 inline void I86::_int3() /* Opcode 0xcc */
\r
3921 icount -= timing.int3;
\r
3925 inline void I86::_int() /* Opcode 0xcd */
\r
3927 unsigned int_num = FETCH;
\r
3928 icount -= timing.int_imm;
\r
3929 #ifdef I86_BIOS_CALL
\r
3930 if(d_bios && d_bios->bios_int(int_num, regs.w, sregs, &ZeroVal, &CarryVal)) {
\r
3935 interrupt(int_num);
\r
3938 inline void I86::_into() /* Opcode 0xce */
\r
3941 icount -= timing.into_t;
\r
3942 interrupt(OVERFLOW_TRAP);
\r
3944 icount -= timing.into_nt;
\r
3948 inline void I86::_iret() /* Opcode 0xcf */
\r
3950 icount -= timing.iret;
\r
3953 base[CS] = SegBase(CS);
\r
3954 pc = (pc + base[CS]) & AMASK;
\r
3957 /* if the IF is set, and an interrupt is pending, signal an interrupt */
\r
3958 if(IF && (int_state & INT_REQ_BIT)) {
\r
3963 inline void I86::_rotshft_b() /* Opcode 0xd0 */
\r
3965 rotate_shift_byte(FETCHOP, 1);
\r
3968 inline void I86::_rotshft_w() /* Opcode 0xd1 */
\r
3970 rotate_shift_word(FETCHOP, 1);
\r
3973 inline void I86::_rotshft_bcl() /* Opcode 0xd2 */
\r
3975 rotate_shift_byte(FETCHOP, regs.b[CL]);
\r
3978 inline void I86::_rotshft_wcl() /* Opcode 0xd3 */
\r
3980 rotate_shift_word(FETCHOP, regs.b[CL]);
\r
3983 /* OB: Opcode works on NEC V-Series but not the Variants */
\r
3984 /* one could specify any byte value as operand but the NECs */
\r
3985 /* always substitute 0x0a. */
\r
3986 inline void I86::_aam() /* Opcode 0xd4 */
\r
3988 unsigned mult = FETCH;
\r
3989 icount -= timing.aam;
\r
3991 interrupt(DIVIDE_FAULT);
\r
3993 regs.b[AH] = regs.b[AL] / mult;
\r
3994 regs.b[AL] %= mult;
\r
3995 SetSZPF_Word(regs.w[AX]);
\r
3999 inline void I86::_aad() /* Opcode 0xd5 */
\r
4001 unsigned mult = FETCH;
\r
4002 icount -= timing.aad;
\r
4003 regs.b[AL] = regs.b[AH] * mult + regs.b[AL];
\r
4005 SetZF(regs.b[AL]);
\r
4006 SetPF(regs.b[AL]);
\r
4010 inline void I86::_setalc() /* Opcode 0xd6 */
\r
4012 regs.b[AL] = (CF) ? 0xff : 0x00;
\r
4016 inline void I86::_xlat() /* Opcode 0xd7 */
\r
4018 unsigned dest = regs.w[BX] + regs.b[AL];
\r
4019 icount -= timing.xlat;
\r
4020 regs.b[AL] = GetMemB(DS, dest);
\r
4023 inline void I86::_escape() /* Opcodes 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde and 0xdf */
\r
4025 unsigned ModRM = FETCH;
\r
4026 icount -= timing.nop;
\r
4030 inline void I86::_loopne() /* Opcode 0xe0 */
\r
4032 int disp = (int)((int8)FETCH);
\r
4033 unsigned tmp = regs.w[CX] - 1;
\r
4036 icount -= timing.loop_t;
\r
4039 icount -= timing.loop_nt;
\r
4043 inline void I86::_loope() /* Opcode 0xe1 */
\r
4045 int disp = (int)((int8)FETCH);
\r
4046 unsigned tmp = regs.w[CX] - 1;
\r
4049 icount -= timing.loope_t;
\r
4052 icount -= timing.loope_nt;
\r
4056 inline void I86::_loop() /* Opcode 0xe2 */
\r
4058 int disp = (int)((int8)FETCH);
\r
4059 unsigned tmp = regs.w[CX] - 1;
\r
4062 icount -= timing.loop_t;
\r
4065 icount -= timing.loop_nt;
\r
4069 inline void I86::_jcxz() /* Opcode 0xe3 */
\r
4071 int disp = (int)((int8)FETCH);
\r
4072 if(regs.w[CX] == 0) {
\r
4073 icount -= timing.jcxz_t;
\r
4076 icount -= timing.jcxz_nt;
\r
4080 inline void I86::_inal() /* Opcode 0xe4 */
\r
4082 unsigned port = FETCH;
\r
4083 icount -= timing.in_imm8;
\r
4084 regs.b[AL] = read_port_byte(port);
\r
4087 inline void I86::_inax() /* Opcode 0xe5 */
\r
4089 unsigned port = FETCH;
\r
4090 icount -= timing.in_imm16;
\r
4091 regs.w[AX] = read_port_word(port);
\r
4094 inline void I86::_outal() /* Opcode 0xe6 */
\r
4096 unsigned port = FETCH;
\r
4097 icount -= timing.out_imm8;
\r
4098 write_port_byte(port, regs.b[AL]);
\r
4101 inline void I86::_outax() /* Opcode 0xe7 */
\r
4103 unsigned port = FETCH;
\r
4104 icount -= timing.out_imm16;
\r
4105 write_port_word(port, regs.w[AX]);
\r
4108 inline void I86::_call_d16() /* Opcode 0xe8 */
\r
4113 ip = pc - base[CS];
\r
4116 pc = (ip + base[CS]) & AMASK;
\r
4117 #ifdef I86_BIOS_CALL
\r
4118 if(d_bios && d_bios->bios_call(pc, regs.w, sregs, &ZeroVal, &CarryVal)) {
\r
4123 icount -= timing.call_near;
\r
4126 inline void I86::_jmp_d16() /* Opcode 0xe9 */
\r
4131 ip = pc - base[CS] + tmp;
\r
4132 pc = (ip + base[CS]) & AMASK;
\r
4133 icount -= timing.jmp_near;
\r
4136 inline void I86::_jmp_far() /* Opcode 0xea */
\r
4138 unsigned tmp, tmp1;
\r
4141 tmp += FETCH << 8;
\r
4144 tmp1 += FETCH << 8;
\r
4146 sregs[CS] = (uint16)tmp1;
\r
4147 base[CS] = SegBase(CS);
\r
4148 pc = (base[CS] + tmp) & AMASK;
\r
4149 icount -= timing.jmp_far;
\r
4152 inline void I86::_jmp_d8() /* Opcode 0xeb */
\r
4154 int tmp = (int)((int8)FETCH);
\r
4156 icount -= timing.jmp_short;
\r
4159 inline void I86::_inaldx() /* Opcode 0xec */
\r
4161 icount -= timing.in_dx8;
\r
4162 regs.b[AL] = read_port_byte(regs.w[DX]);
\r
4165 inline void I86::_inaxdx() /* Opcode 0xed */
\r
4167 unsigned port = regs.w[DX];
\r
4168 icount -= timing.in_dx16;
\r
4169 regs.w[AX] = read_port_word(port);
\r
4172 inline void I86::_outdxal() /* Opcode 0xee */
\r
4174 icount -= timing.out_dx8;
\r
4175 write_port_byte(regs.w[DX], regs.b[AL]);
\r
4178 inline void I86::_outdxax() /* Opcode 0xef */
\r
4180 unsigned port = regs.w[DX];
\r
4181 icount -= timing.out_dx16;
\r
4182 write_port_word(port, regs.w[AX]);
\r
4185 /* I think thats not a V20 instruction...*/
\r
4186 inline void I86::_lock() /* Opcode 0xf0 */
\r
4188 icount -= timing.nop;
\r
4189 instruction(FETCHOP); /* un-interruptible */
\r
4192 inline void I86::_rep(int flagval)
\r
4194 /* Handles rep- and repnz- prefixes. flagval is the value of ZF for the
\r
4195 loop to continue for CMPS and SCAS instructions. */
\r
4197 unsigned next = FETCHOP;
\r
4198 unsigned count = regs.w[CX];
\r
4201 case 0x26: /* ES: */
\r
4202 seg_prefix = true;
\r
4204 icount -= timing.override;
\r
4207 case 0x2e: /* CS: */
\r
4208 seg_prefix = true;
\r
4210 icount -= timing.override;
\r
4213 case 0x36: /* SS: */
\r
4214 seg_prefix = true;
\r
4216 icount -= timing.override;
\r
4219 case 0x3e: /* DS: */
\r
4220 seg_prefix = true;
\r
4222 icount -= timing.override;
\r
4226 case 0x6c: /* REP INSB */
\r
4227 icount -= timing.rep_ins8_base;
\r
4228 for(; count > 0; count--) {
\r
4229 PutMemB(ES, regs.w[DI], read_port_byte(regs.w[DX]));
\r
4230 regs.w[DI] += DirVal;
\r
4231 icount -= timing.rep_ins8_count;
\r
4233 regs.w[CX] = count;
\r
4235 case 0x6d: /* REP INSW */
\r
4236 icount -= timing.rep_ins16_base;
\r
4237 for(; count > 0; count--) {
\r
4238 PutMemW(ES, regs.w[DI], read_port_word(regs.w[DX]));
\r
4239 regs.w[DI] += 2 * DirVal;
\r
4240 icount -= timing.rep_ins16_count;
\r
4242 regs.w[CX] = count;
\r
4244 case 0x6e: /* REP OUTSB */
\r
4245 icount -= timing.rep_outs8_base;
\r
4246 for(; count > 0; count--) {
\r
4247 write_port_byte(regs.w[DX], GetMemB(DS, regs.w[SI]));
\r
4248 regs.w[SI] += DirVal; /* GOL 11/27/01 */
\r
4249 icount -= timing.rep_outs8_count;
\r
4251 regs.w[CX] = count;
\r
4253 case 0x6f: /* REP OUTSW */
\r
4254 icount -= timing.rep_outs16_base;
\r
4255 for(; count > 0; count--) {
\r
4256 write_port_word(regs.w[DX], GetMemW(DS, regs.w[SI]));
\r
4257 regs.w[SI] += 2 * DirVal; /* GOL 11/27/01 */
\r
4258 icount -= timing.rep_outs16_count;
\r
4260 regs.w[CX] = count;
\r
4263 case 0xa4: /* REP MOVSB */
\r
4264 icount -= timing.rep_movs8_base;
\r
4265 for(; count > 0; count--) {
\r
4267 tmp = GetMemB(DS, regs.w[SI]);
\r
4268 PutMemB(ES, regs.w[DI], tmp);
\r
4269 regs.w[DI] += DirVal;
\r
4270 regs.w[SI] += DirVal;
\r
4271 icount -= timing.rep_movs8_count;
\r
4273 regs.w[CX] = count;
\r
4275 case 0xa5: /* REP MOVSW */
\r
4276 icount -= timing.rep_movs16_base;
\r
4277 for(; count > 0; count--) {
\r
4279 tmp = GetMemW(DS, regs.w[SI]);
\r
4280 PutMemW(ES, regs.w[DI], tmp);
\r
4281 regs.w[DI] += 2 * DirVal;
\r
4282 regs.w[SI] += 2 * DirVal;
\r
4283 icount -= timing.rep_movs16_count;
\r
4285 regs.w[CX] = count;
\r
4287 case 0xa6: /* REP(N)E CMPSB */
\r
4288 icount -= timing.rep_cmps8_base;
\r
4289 for(ZeroVal = !flagval; (ZF == flagval) && (count > 0); count--) {
\r
4290 unsigned dst, src;
\r
4291 dst = GetMemB(ES, regs.w[DI]);
\r
4292 src = GetMemB(DS, regs.w[SI]);
\r
4293 SUBB(src, dst); /* opposite of the usual convention */
\r
4294 regs.w[DI] += DirVal;
\r
4295 regs.w[SI] += DirVal;
\r
4296 icount -= timing.rep_cmps8_count;
\r
4298 regs.w[CX] = count;
\r
4300 case 0xa7: /* REP(N)E CMPSW */
\r
4301 icount -= timing.rep_cmps16_base;
\r
4302 for(ZeroVal = !flagval; (ZF == flagval) && (count > 0); count--) {
\r
4303 unsigned dst, src;
\r
4304 dst = GetMemW(ES, regs.w[DI]);
\r
4305 src = GetMemW(DS, regs.w[SI]);
\r
4306 SUBW(src, dst); /* opposite of the usual convention */
\r
4307 regs.w[DI] += 2 * DirVal;
\r
4308 regs.w[SI] += 2 * DirVal;
\r
4309 icount -= timing.rep_cmps16_count;
\r
4311 regs.w[CX] = count;
\r
4313 case 0xaa: /* REP STOSB */
\r
4314 icount -= timing.rep_stos8_base;
\r
4315 for(; count > 0; count--) {
\r
4316 PutMemB(ES, regs.w[DI], regs.b[AL]);
\r
4317 regs.w[DI] += DirVal;
\r
4318 icount -= timing.rep_stos8_count;
\r
4320 regs.w[CX] = count;
\r
4322 case 0xab: /* REP STOSW */
\r
4323 icount -= timing.rep_stos16_base;
\r
4324 for(; count > 0; count--) {
\r
4325 PutMemW(ES, regs.w[DI], regs.w[AX]);
\r
4326 regs.w[DI] += 2 * DirVal;
\r
4327 icount -= timing.rep_stos16_count;
\r
4329 regs.w[CX] = count;
\r
4331 case 0xac: /* REP LODSB */
\r
4332 icount -= timing.rep_lods8_base;
\r
4333 for(; count > 0; count--) {
\r
4334 regs.b[AL] = GetMemB(DS, regs.w[SI]);
\r
4335 regs.w[SI] += DirVal;
\r
4336 icount -= timing.rep_lods8_count;
\r
4338 regs.w[CX] = count;
\r
4340 case 0xad: /* REP LODSW */
\r
4341 icount -= timing.rep_lods16_base;
\r
4342 for(; count > 0; count--) {
\r
4343 regs.w[AX] = GetMemW(DS, regs.w[SI]);
\r
4344 regs.w[SI] += 2 * DirVal;
\r
4345 icount -= timing.rep_lods16_count;
\r
4347 regs.w[CX] = count;
\r
4349 case 0xae: /* REP(N)E SCASB */
\r
4350 icount -= timing.rep_scas8_base;
\r
4351 for(ZeroVal = !flagval; (ZF == flagval) && (count > 0); count--) {
\r
4352 unsigned src, dst;
\r
4353 src = GetMemB(ES, regs.w[DI]);
\r
4356 regs.w[DI] += DirVal;
\r
4357 icount -= timing.rep_scas8_count;
\r
4359 regs.w[CX] = count;
\r
4361 case 0xaf: /* REP(N)E SCASW */
\r
4362 icount -= timing.rep_scas16_base;
\r
4363 for(ZeroVal = !flagval; (ZF == flagval) && (count > 0); count--) {
\r
4364 unsigned src, dst;
\r
4365 src = GetMemW(ES, regs.w[DI]);
\r
4368 regs.w[DI] += 2 * DirVal;
\r
4369 icount -= timing.rep_scas16_count;
\r
4371 regs.w[CX] = count;
\r
4374 instruction(next);
\r
4378 inline void I86::_repne() /* Opcode 0xf2 */
\r
4383 inline void I86::_repe() /* Opcode 0xf3 */
\r
4388 inline void I86::_hlt() /* Opcode 0xf4 */
\r
4395 inline void I86::_cmc() /* Opcode 0xf5 */
\r
4397 icount -= timing.flag_ops;
\r
4401 inline void I86::_f6pre() /* Opcode 0xf6 */
\r
4403 unsigned ModRM = FETCH;
\r
4404 unsigned tmp = (unsigned)GetRMByte(ModRM);
\r
4407 switch((ModRM >> 3) & 7) {
\r
4408 case 0: /* TEST Eb, data8 */
\r
4410 icount -= (ModRM >= 0xc0) ? timing.alu_ri8 : timing.alu_mi8_ro;
\r
4413 CarryVal = OverVal = AuxVal = 0;
\r
4414 SetSZPF_Byte(tmp);
\r
4417 case 2: /* NOT Eb */
\r
4418 icount -= (ModRM >= 0xc0) ? timing.negnot_r8 : timing.negnot_m8;
\r
4419 PutbackRMByte(ModRM, ~tmp);
\r
4422 case 3: /* NEG Eb */
\r
4423 icount -= (ModRM >= 0xc0) ? timing.negnot_r8 : timing.negnot_m8;
\r
4426 PutbackRMByte(ModRM, tmp2);
\r
4429 case 4: /* MUL AL, Eb */
\r
4430 icount -= (ModRM >= 0xc0) ? timing.mul_r8 : timing.mul_m8;
\r
4434 tmp2 = regs.b[AL];
\r
4436 SetSF((int8)tmp2);
\r
4439 result = (uint16)tmp2 * tmp;
\r
4440 regs.w[AX] = (uint16)result;
\r
4442 SetZF(regs.w[AX]);
\r
4443 CarryVal = OverVal = (regs.b[AH] != 0);
\r
4447 case 5: /* IMUL AL, Eb */
\r
4448 icount -= (ModRM >= 0xc0) ? timing.imul_r8 : timing.imul_m8;
\r
4452 tmp2 = (unsigned)regs.b[AL];
\r
4454 SetSF((int8)tmp2);
\r
4457 result = (int16)((int8)tmp2) * (int16)((int8)tmp);
\r
4458 regs.w[AX] = (uint16)result;
\r
4460 SetZF(regs.w[AX]);
\r
4461 CarryVal = OverVal = (result >> 7 != 0) && (result >> 7 != -1);
\r
4465 case 6: /* DIV AL, Ew */
\r
4466 icount -= (ModRM >= 0xc0) ? timing.div_r8 : timing.div_m8;
\r
4470 result = regs.w[AX];
\r
4473 if((result / tmp) > 0xff) {
\r
4474 interrupt(DIVIDE_FAULT);
\r
4477 regs.b[AH] = result % tmp;
\r
4478 regs.b[AL] = result / tmp;
\r
4481 interrupt(DIVIDE_FAULT);
\r
4487 case 7: /* IDIV AL, Ew */
\r
4488 icount -= (ModRM >= 0xc0) ? timing.idiv_r8 : timing.idiv_m8;
\r
4492 result = regs.w[AX];
\r
4495 tmp2 = result % (int16)((int8)tmp);
\r
4497 if((result /= (int16)((int8)tmp)) > 0xff) {
\r
4498 interrupt(DIVIDE_FAULT);
\r
4501 regs.b[AL] = (uint8)result;
\r
4502 regs.b[AH] = tmp2;
\r
4505 interrupt(DIVIDE_FAULT);
\r
4516 inline void I86::_f7pre() /* Opcode 0xf7 */
\r
4518 unsigned ModRM = FETCH;
\r
4519 unsigned tmp = GetRMWord(ModRM);
\r
4522 switch((ModRM >> 3) & 7) {
\r
4523 case 0: /* TEST Ew, data16 */
\r
4525 icount -= (ModRM >= 0xc0) ? timing.alu_ri16 : timing.alu_mi16_ro;
\r
4527 tmp2 += FETCH << 8;
\r
4531 CarryVal = OverVal = AuxVal = 0;
\r
4532 SetSZPF_Word(tmp);
\r
4535 case 2: /* NOT Ew */
\r
4536 icount -= (ModRM >= 0xc0) ? timing.negnot_r16 : timing.negnot_m16;
\r
4538 PutbackRMWord(ModRM, tmp);
\r
4541 case 3: /* NEG Ew */
\r
4542 icount -= (ModRM >= 0xc0) ? timing.negnot_r16 : timing.negnot_m16;
\r
4545 PutbackRMWord(ModRM, tmp2);
\r
4548 case 4: /* MUL AX, Ew */
\r
4549 icount -= (ModRM >= 0xc0) ? timing.mul_r16 : timing.mul_m16;
\r
4552 tmp2 = regs.w[AX];
\r
4554 SetSF((int16)tmp2);
\r
4557 result = (uint32)tmp2 * tmp;
\r
4558 regs.w[AX] = (uint16)result;
\r
4560 regs.w[DX] = result;
\r
4562 SetZF(regs.w[AX] | regs.w[DX]);
\r
4563 CarryVal = OverVal = (regs.w[DX] != 0);
\r
4567 case 5: /* IMUL AX, Ew */
\r
4568 icount -= (ModRM >= 0xc0) ? timing.imul_r16 : timing.imul_m16;
\r
4572 tmp2 = regs.w[AX];
\r
4574 SetSF((int16)tmp2);
\r
4577 result = (int32)((int16)tmp2) * (int32)((int16)tmp);
\r
4578 CarryVal = OverVal = (result >> 15 != 0) && (result >> 15 != -1);
\r
4580 regs.w[AX] = (uint16)result;
\r
4581 result = (uint16)(result >> 16);
\r
4582 regs.w[DX] = result;
\r
4584 SetZF(regs.w[AX] | regs.w[DX]);
\r
4588 case 6: /* DIV AX, Ew */
\r
4589 icount -= (ModRM >= 0xc0) ? timing.div_r16 : timing.div_m16;
\r
4593 result = (regs.w[DX] << 16) + regs.w[AX];
\r
4596 tmp2 = result % tmp;
\r
4597 if((result / tmp) > 0xffff) {
\r
4598 interrupt(DIVIDE_FAULT);
\r
4601 regs.w[DX] = tmp2;
\r
4603 regs.w[AX] = result;
\r
4606 interrupt(DIVIDE_FAULT);
\r
4612 case 7: /* IDIV AX, Ew */
\r
4613 icount -= (ModRM >= 0xc0) ? timing.idiv_r16 : timing.idiv_m16;
\r
4617 result = (regs.w[DX] << 16) + regs.w[AX];
\r
4620 tmp2 = result % (int32)((int16)tmp);
\r
4621 if((result /= (int32)((int16)tmp)) > 0xffff) {
\r
4622 interrupt(DIVIDE_FAULT);
\r
4625 regs.w[AX] = result;
\r
4626 regs.w[DX] = tmp2;
\r
4629 interrupt(DIVIDE_FAULT);
\r
4640 inline void I86::_clc() /* Opcode 0xf8 */
\r
4642 icount -= timing.flag_ops;
\r
4646 inline void I86::_stc() /* Opcode 0xf9 */
\r
4648 icount -= timing.flag_ops;
\r
4652 inline void I86::_cli() /* Opcode 0xfa */
\r
4654 icount -= timing.flag_ops;
\r
4658 inline void I86::_sti() /* Opcode 0xfb */
\r
4660 icount -= timing.flag_ops;
\r
4662 instruction(FETCHOP); /* no interrupt before next instruction */
\r
4664 /* if an interrupt is pending, signal an interrupt */
\r
4665 if(IF && (int_state & INT_REQ_BIT)) {
\r
4670 inline void I86::_cld() /* Opcode 0xfc */
\r
4672 icount -= timing.flag_ops;
\r
4676 inline void I86::_std() /* Opcode 0xfd */
\r
4678 icount -= timing.flag_ops;
\r
4682 inline void I86::_fepre() /* Opcode 0xfe */
\r
4684 unsigned ModRM = FETCH;
\r
4685 unsigned tmp = GetRMByte(ModRM);
\r
4688 icount -= (ModRM >= 0xc0) ? timing.incdec_r8 : timing.incdec_m8;
\r
4689 if((ModRM & 0x38) == 0) {
\r
4692 SetOFB_Add(tmp1, tmp, 1);
\r
4696 SetOFB_Sub(tmp1, 1, tmp);
\r
4698 SetAF(tmp1, tmp, 1);
\r
4699 SetSZPF_Byte(tmp1);
\r
4700 PutbackRMByte(ModRM, (uint8)tmp1);
\r
4703 inline void I86::_ffpre() /* Opcode 0xff */
\r
4705 unsigned ModRM = FETCHOP;
\r
4710 switch((ModRM >> 3) & 7) {
\r
4711 case 0: /* INC ew */
\r
4712 icount -= (ModRM >= 0xc0) ? timing.incdec_r16 : timing.incdec_m16;
\r
4713 tmp = GetRMWord(ModRM);
\r
4715 SetOFW_Add(tmp1, tmp, 1);
\r
4716 SetAF(tmp1, tmp, 1);
\r
4717 SetSZPF_Word(tmp1);
\r
4718 PutbackRMWord(ModRM, (uint16)tmp1);
\r
4720 case 1: /* DEC ew */
\r
4721 icount -= (ModRM >= 0xc0) ? timing.incdec_r16 : timing.incdec_m16;
\r
4722 tmp = GetRMWord(ModRM);
\r
4724 SetOFW_Sub(tmp1, 1, tmp);
\r
4725 SetAF(tmp1, tmp, 1);
\r
4726 SetSZPF_Word(tmp1);
\r
4727 PutbackRMWord(ModRM, (uint16)tmp1);
\r
4729 case 2: /* CALL ew */
\r
4730 icount -= (ModRM >= 0xc0) ? timing.call_r16 : timing.call_m16;
\r
4731 tmp = GetRMWord(ModRM);
\r
4732 ip = pc - base[CS];
\r
4734 pc = (base[CS] + (uint16)tmp) & AMASK;
\r
4735 #ifdef I86_BIOS_CALL
\r
4736 if(d_bios && d_bios->bios_call(pc, regs.w, sregs, &ZeroVal, &CarryVal)) {
\r
4742 case 3: /* CALL FAR ea */
\r
4743 icount -= timing.call_m32;
\r
4744 tmp = sregs[CS]; /* need to skip displacements of ea */
\r
4745 tmp1 = GetRMWord(ModRM);
\r
4746 ip = pc - base[CS];
\r
4749 sregs[CS] = GetNextRMWord;
\r
4750 base[CS] = SegBase(CS);
\r
4751 pc = (base[CS] + tmp1) & AMASK;
\r
4752 #ifdef I86_BIOS_CALL
\r
4753 if(d_bios && d_bios->bios_call(pc, regs.w, sregs, &ZeroVal, &CarryVal)) {
\r
4759 case 4: /* JMP ea */
\r
4760 icount -= (ModRM >= 0xc0) ? timing.jmp_r16 : timing.jmp_m16;
\r
4761 ip = GetRMWord(ModRM);
\r
4762 pc = (base[CS] + ip) & AMASK;
\r
4764 case 5: /* JMP FAR ea */
\r
4765 icount -= timing.jmp_m32;
\r
4766 pc = GetRMWord(ModRM);
\r
4767 sregs[CS] = GetNextRMWord;
\r
4768 base[CS] = SegBase(CS);
\r
4769 pc = (pc + base[CS]) & AMASK;
\r
4771 case 6: /* PUSH ea */
\r
4772 icount -= (ModRM >= 0xc0) ? timing.push_r16 : timing.push_m16;
\r
4773 tmp = GetRMWord(ModRM);
\r
4776 case 7: /* invalid ??? */
\r
4784 inline void I86::_invalid()
\r
4786 /* i8086/i8088 ignore an invalid opcode. */
\r
4787 /* i80186/i80188 probably also ignore an invalid opcode. */
\r
4792 NEC V-series Disassembler
\r
4794 Originally Written for i386 by Ville Linde
\r
4795 Converted to NEC-V by Aaron Giles
\r
4800 PARAM_REG8 = 1, /* 8-bit register */
\r
4801 PARAM_REG16, /* 16-bit register */
\r
4802 PARAM_REG2_8, /* 8-bit register */
\r
4803 PARAM_REG2_16, /* 16-bit register */
\r
4804 PARAM_RM8, /* 8-bit memory or register */
\r
4805 PARAM_RM16, /* 16-bit memory or register */
\r
4806 PARAM_RMPTR8, /* 8-bit memory or register */
\r
4807 PARAM_RMPTR16, /* 16-bit memory or register */
\r
4808 PARAM_I3, /* 3-bit immediate */
\r
4809 PARAM_I4, /* 4-bit immediate */
\r
4810 PARAM_I8, /* 8-bit signed immediate */
\r
4811 PARAM_I16, /* 16-bit signed immediate */
\r
4812 PARAM_UI8, /* 8-bit unsigned immediate */
\r
4813 PARAM_IMM, /* 16-bit immediate */
\r
4814 PARAM_ADDR, /* 16:16 address */
\r
4815 PARAM_REL8, /* 8-bit PC-relative displacement */
\r
4816 PARAM_REL16, /* 16-bit PC-relative displacement */
\r
4817 PARAM_MEM_OFFS, /* 16-bit mem offset */
\r
4818 PARAM_SREG, /* segment register */
\r
4819 PARAM_SFREG, /* V25/V35 special function register */
\r
4820 PARAM_1, /* used by shift/rotate instructions */
\r
4852 struct I386_OPCODE {
\r
4853 char mnemonic[32];
\r
4858 offs_t dasm_flags;
\r
4862 char mnemonic[32];
\r
4863 const I386_OPCODE *opcode;
\r
4866 static const UINT8 *opcode_ptr;
\r
4867 static const UINT8 *opcode_ptr_base;
\r
4869 static const I386_OPCODE necv_opcode_table1[256] =
\r
4872 {"add", MODRM, PARAM_RM8, PARAM_REG8, 0 },
\r
4873 {"add", MODRM, PARAM_RM16, PARAM_REG16, 0 },
\r
4874 {"add", MODRM, PARAM_REG8, PARAM_RM8, 0 },
\r
4875 {"add", MODRM, PARAM_REG16, PARAM_RM16, 0 },
\r
4876 {"add", 0, PARAM_AL, PARAM_UI8, 0 },
\r
4877 {"add", 0, PARAM_AW, PARAM_IMM, 0 },
\r
4878 {"push ds1", 0, 0, 0, 0 },
\r
4879 {"pop ds1", 0, 0, 0, 0 },
\r
4880 {"or", MODRM, PARAM_RM8, PARAM_REG8, 0 },
\r
4881 {"or", MODRM, PARAM_RM16, PARAM_REG16, 0 },
\r
4882 {"or", MODRM, PARAM_REG8, PARAM_RM8, 0 },
\r
4883 {"or", MODRM, PARAM_REG16, PARAM_RM16, 0 },
\r
4884 {"or", 0, PARAM_AL, PARAM_UI8, 0 },
\r
4885 {"or", 0, PARAM_AW, PARAM_IMM, 0 },
\r
4886 {"push ps", 0, 0, 0, 0 },
\r
4887 {"two_byte", TWO_BYTE, 0, 0, 0 },
\r
4889 {"addc", MODRM, PARAM_RM8, PARAM_REG8, 0 },
\r
4890 {"addc", MODRM, PARAM_RM16, PARAM_REG16, 0 },
\r
4891 {"addc", MODRM, PARAM_REG8, PARAM_RM8, 0 },
\r
4892 {"addc", MODRM, PARAM_REG16, PARAM_RM16, 0 },
\r
4893 {"addc", 0, PARAM_AL, PARAM_UI8, 0 },
\r
4894 {"addc", 0, PARAM_AW, PARAM_IMM, 0 },
\r
4895 {"push ss", 0, 0, 0, 0 },
\r
4896 {"pop ss", 0, 0, 0, 0 },
\r
4897 {"subc", MODRM, PARAM_RM8, PARAM_REG8, 0 },
\r
4898 {"subc", MODRM, PARAM_RM16, PARAM_REG16, 0 },
\r
4899 {"subc", MODRM, PARAM_REG8, PARAM_RM8, 0 },
\r
4900 {"subc", MODRM, PARAM_REG16, PARAM_RM16, 0 },
\r
4901 {"subc", 0, PARAM_AL, PARAM_UI8, 0 },
\r
4902 {"subc", 0, PARAM_AW, PARAM_IMM, 0 },
\r
4903 {"push ds0", 0, 0, 0, 0 },
\r
4904 {"pop ds0", 0, 0, 0, 0 },
\r
4906 {"and", MODRM, PARAM_RM8, PARAM_REG8, 0 },
\r
4907 {"and", MODRM, PARAM_RM16, PARAM_REG16, 0 },
\r
4908 {"and", MODRM, PARAM_REG8, PARAM_RM8, 0 },
\r
4909 {"and", MODRM, PARAM_REG16, PARAM_RM16, 0 },
\r
4910 {"and", 0, PARAM_AL, PARAM_UI8, 0 },
\r
4911 {"and", 0, PARAM_AW, PARAM_IMM, 0 },
\r
4912 {"ds1:", SEG_DS1, 0, 0, 0 },
\r
4913 {"adj4a", 0, 0, 0, 0 },
\r
4914 {"sub", MODRM, PARAM_RM8, PARAM_REG8, 0 },
\r
4915 {"sub", MODRM, PARAM_RM16, PARAM_REG16, 0 },
\r
4916 {"sub", MODRM, PARAM_REG8, PARAM_RM8, 0 },
\r
4917 {"sub", MODRM, PARAM_REG16, PARAM_RM16, 0 },
\r
4918 {"sub", 0, PARAM_AL, PARAM_UI8, 0 },
\r
4919 {"sub", 0, PARAM_AW, PARAM_IMM, 0 },
\r
4920 {"ps:", SEG_PS, 0, 0, 0 },
\r
4921 {"adj4s", 0, 0, 0, 0 },
\r
4923 {"xor", MODRM, PARAM_RM8, PARAM_REG8, 0 },
\r
4924 {"xor", MODRM, PARAM_RM16, PARAM_REG16, 0 },
\r
4925 {"xor", MODRM, PARAM_REG8, PARAM_RM8, 0 },
\r
4926 {"xor", MODRM, PARAM_REG16, PARAM_RM16, 0 },
\r
4927 {"xor", 0, PARAM_AL, PARAM_UI8, 0 },
\r
4928 {"xor", 0, PARAM_AW, PARAM_IMM, 0 },
\r
4929 {"ss:", SEG_SS, 0, 0, 0 },
\r
4930 {"adjba", 0, 0, 0, 0 },
\r
4931 {"cmp", MODRM, PARAM_RM8, PARAM_REG8, 0 },
\r
4932 {"cmp", MODRM, PARAM_RM16, PARAM_REG16, 0 },
\r
4933 {"cmp", MODRM, PARAM_REG8, PARAM_RM8, 0 },
\r
4934 {"cmp", MODRM, PARAM_REG16, PARAM_RM16, 0 },
\r
4935 {"cmp", 0, PARAM_AL, PARAM_UI8, 0 },
\r
4936 {"cmp", 0, PARAM_AW, PARAM_IMM, 0 },
\r
4937 {"ds0:", SEG_DS0, 0, 0, 0 },
\r
4938 {"adjbs", 0, 0, 0, 0 },
\r
4940 {"inc", 0, PARAM_AW, 0, 0 },
\r
4941 {"inc", 0, PARAM_CW, 0, 0 },
\r
4942 {"inc", 0, PARAM_DW, 0, 0 },
\r
4943 {"inc", 0, PARAM_BW, 0, 0 },
\r
4944 {"inc", 0, PARAM_SP, 0, 0 },
\r
4945 {"inc", 0, PARAM_BP, 0, 0 },
\r
4946 {"inc", 0, PARAM_IX, 0, 0 },
\r
4947 {"inc", 0, PARAM_IY, 0, 0 },
\r
4948 {"dec", 0, PARAM_AW, 0, 0 },
\r
4949 {"dec", 0, PARAM_CW, 0, 0 },
\r
4950 {"dec", 0, PARAM_DW, 0, 0 },
\r
4951 {"dec", 0, PARAM_BW, 0, 0 },
\r
4952 {"dec", 0, PARAM_SP, 0, 0 },
\r
4953 {"dec", 0, PARAM_BP, 0, 0 },
\r
4954 {"dec", 0, PARAM_IX, 0, 0 },
\r
4955 {"dec", 0, PARAM_IY, 0, 0 },
\r
4957 {"push", 0, PARAM_AW, 0, 0 },
\r
4958 {"push", 0, PARAM_CW, 0, 0 },
\r
4959 {"push", 0, PARAM_DW, 0, 0 },
\r
4960 {"push", 0, PARAM_BW, 0, 0 },
\r
4961 {"push", 0, PARAM_SP, 0, 0 },
\r
4962 {"push", 0, PARAM_BP, 0, 0 },
\r
4963 {"push", 0, PARAM_IX, 0, 0 },
\r
4964 {"push", 0, PARAM_IY, 0, 0 },
\r
4965 {"pop", 0, PARAM_AW, 0, 0 },
\r
4966 {"pop", 0, PARAM_CW, 0, 0 },
\r
4967 {"pop", 0, PARAM_DW, 0, 0 },
\r
4968 {"pop", 0, PARAM_BW, 0, 0 },
\r
4969 {"pop", 0, PARAM_SP, 0, 0 },
\r
4970 {"pop", 0, PARAM_BP, 0, 0 },
\r
4971 {"pop", 0, PARAM_IX, 0, 0 },
\r
4972 {"pop", 0, PARAM_IY, 0, 0 },
\r
4974 {"push r", 0, 0, 0, 0 },
\r
4975 {"pop r", 0, 0, 0, 0 },
\r
4976 {"chkind", MODRM, PARAM_REG16, PARAM_RM16, 0 },
\r
4977 {"brkn", 0, PARAM_UI8, 0, 0, DASMFLAG_STEP_OVER}, /* V25S/V35S only */
\r
4978 {"repnc", PREFIX, 0, 0, 0 },
\r
4979 {"repc", PREFIX, 0, 0, 0 },
\r
4980 {"fpo2 0", 0, 0, 0, 0 }, /* for a coprocessor that was never made */
\r
4981 {"fpo2 1", 0, 0, 0, 0 }, /* for a coprocessor that was never made */
\r
4982 {"push", 0, PARAM_IMM, 0, 0 },
\r
4983 {"mul", MODRM, PARAM_REG16, PARAM_RM16, PARAM_IMM },
\r
4984 {"push", 0, PARAM_I8, 0, 0 },
\r
4985 {"mul", MODRM, PARAM_REG16, PARAM_RM16, PARAM_I8 },
\r
4986 {"inmb", 0, 0, 0, 0 },
\r
4987 {"inmw", 0, 0, 0, 0 },
\r
4988 {"outmb", 0, 0, 0, 0 },
\r
4989 {"outmw", 0, 0, 0, 0 },
\r
4991 {"bv", 0, PARAM_REL8, 0, 0 },
\r
4992 {"bnv", 0, PARAM_REL8, 0, 0 },
\r
4993 {"bc", 0, PARAM_REL8, 0, 0 },
\r
4994 {"bnc", 0, PARAM_REL8, 0, 0 },
\r
4995 {"be", 0, PARAM_REL8, 0, 0 },
\r
4996 {"bne", 0, PARAM_REL8, 0, 0 },
\r
4997 {"bnh", 0, PARAM_REL8, 0, 0 },
\r
4998 {"bh", 0, PARAM_REL8, 0, 0 },
\r
4999 {"bn", 0, PARAM_REL8, 0, 0 },
\r
5000 {"bp", 0, PARAM_REL8, 0, 0 },
\r
5001 {"bpe", 0, PARAM_REL8, 0, 0 },
\r
5002 {"bpo", 0, PARAM_REL8, 0, 0 },
\r
5003 {"blt", 0, PARAM_REL8, 0, 0 },
\r
5004 {"bge", 0, PARAM_REL8, 0, 0 },
\r
5005 {"ble", 0, PARAM_REL8, 0, 0 },
\r
5006 {"bgt", 0, PARAM_REL8, 0, 0 },
\r
5008 {"immb", GROUP, 0, 0, 0 },
\r
5009 {"immw", GROUP, 0, 0, 0 },
\r
5010 {"immb", GROUP, 0, 0, 0 },
\r
5011 {"immws", GROUP, 0, 0, 0 },
\r
5012 {"test", MODRM, PARAM_RM8, PARAM_REG8, 0 },
\r
5013 {"test", MODRM, PARAM_RM16, PARAM_REG16, 0 },
\r
5014 {"xch", MODRM, PARAM_REG8, PARAM_RM8, 0 },
\r
5015 {"xch", MODRM, PARAM_REG16, PARAM_RM16, 0 },
\r
5016 {"mov", MODRM, PARAM_RM8, PARAM_REG8, 0 },
\r
5017 {"mov", MODRM, PARAM_RM16, PARAM_REG16, 0 },
\r
5018 {"mov", MODRM, PARAM_REG8, PARAM_RM8, 0 },
\r
5019 {"mov", MODRM, PARAM_REG16, PARAM_RM16, 0 },
\r
5020 {"mov", MODRM, PARAM_RM16, PARAM_SREG, 0 },
\r
5021 {"ldea", MODRM, PARAM_REG16, PARAM_RM16, 0 },
\r
5022 {"mov", MODRM, PARAM_SREG, PARAM_RM16, 0 },
\r
5023 {"pop", MODRM, PARAM_RM16, 0, 0 },
\r
5025 {"nop", 0, 0, 0, 0 },
\r
5026 {"xch", 0, PARAM_AW, PARAM_CW, 0 },
\r
5027 {"xch", 0, PARAM_AW, PARAM_DW, 0 },
\r
5028 {"xch", 0, PARAM_AW, PARAM_BW, 0 },
\r
5029 {"xch", 0, PARAM_AW, PARAM_SP, 0 },
\r
5030 {"xch", 0, PARAM_AW, PARAM_BP, 0 },
\r
5031 {"xch", 0, PARAM_AW, PARAM_IX, 0 },
\r
5032 {"xch", 0, PARAM_AW, PARAM_IY, 0 },
\r
5033 {"cvtbw", 0, 0, 0, 0 },
\r
5034 {"cvtwl", 0, 0, 0, 0 },
\r
5035 {"call", 0, PARAM_ADDR, 0, 0, DASMFLAG_STEP_OVER},
\r
5036 {"poll", 0, 0, 0, 0 },
\r
5037 {"push psw", 0, 0, 0, 0 },
\r
5038 {"pop psw", 0, 0, 0, 0 },
\r
5039 {"mov psw,ah", 0, 0, 0, 0 },
\r
5040 {"mov ah,psw", 0, 0, 0, 0 },
\r
5042 {"mov", 0, PARAM_AL, PARAM_MEM_OFFS, 0 },
\r
5043 {"mov", 0, PARAM_AW, PARAM_MEM_OFFS, 0 },
\r
5044 {"mov", 0, PARAM_MEM_OFFS, PARAM_AL, 0 },
\r
5045 {"mov", 0, PARAM_MEM_OFFS, PARAM_AW, 0 },
\r
5046 {"movbkb", 0, 0, 0, 0 },
\r
5047 {"movbkw", 0, 0, 0, 0 },
\r
5048 {"cmpbkb", 0, 0, 0, 0 },
\r
5049 {"cmpbkw", 0, 0, 0, 0 },
\r
5050 {"test", 0, PARAM_AL, PARAM_UI8, 0 },
\r
5051 {"test", 0, PARAM_AW, PARAM_IMM, 0 },
\r
5052 {"stmb", 0, 0, 0, 0 },
\r
5053 {"stmw", 0, 0, 0, 0 },
\r
5054 {"ldmb", 0, 0, 0, 0 },
\r
5055 {"ldmw", 0, 0, 0, 0 },
\r
5056 {"cmpmb", 0, 0, 0, 0 },
\r
5057 {"cmpmw", 0, 0, 0, 0 },
\r
5059 {"mov", 0, PARAM_AL, PARAM_UI8, 0 },
\r
5060 {"mov", 0, PARAM_CL, PARAM_UI8, 0 },
\r
5061 {"mov", 0, PARAM_DL, PARAM_UI8, 0 },
\r
5062 {"mov", 0, PARAM_BL, PARAM_UI8, 0 },
\r
5063 {"mov", 0, PARAM_AH, PARAM_UI8, 0 },
\r
5064 {"mov", 0, PARAM_CH, PARAM_UI8, 0 },
\r
5065 {"mov", 0, PARAM_DH, PARAM_UI8, 0 },
\r
5066 {"mov", 0, PARAM_BH, PARAM_UI8, 0 },
\r
5067 {"mov", 0, PARAM_AW, PARAM_IMM, 0 },
\r
5068 {"mov", 0, PARAM_CW, PARAM_IMM, 0 },
\r
5069 {"mov", 0, PARAM_DW, PARAM_IMM, 0 },
\r
5070 {"mov", 0, PARAM_BW, PARAM_IMM, 0 },
\r
5071 {"mov", 0, PARAM_SP, PARAM_IMM, 0 },
\r
5072 {"mov", 0, PARAM_BP, PARAM_IMM, 0 },
\r
5073 {"mov", 0, PARAM_IX, PARAM_IMM, 0 },
\r
5074 {"mov", 0, PARAM_IY, PARAM_IMM, 0 },
\r
5076 {"shiftbi", GROUP, 0, 0, 0 },
\r
5077 {"shiftwi", GROUP, 0, 0, 0 },
\r
5078 {"ret", 0, PARAM_I16, 0, 0, DASMFLAG_STEP_OUT},
\r
5079 {"ret", 0, 0, 0, 0, DASMFLAG_STEP_OUT},
\r
5080 {"mov ds1,", MODRM, PARAM_REG16, PARAM_RM16, 0 },
\r
5081 {"mov ds0,", MODRM, PARAM_REG16, PARAM_RM16, 0 },
\r
5082 {"mov", MODRM, PARAM_RMPTR8, PARAM_UI8, 0 },
\r
5083 {"mov", MODRM, PARAM_RMPTR16, PARAM_IMM, 0 },
\r
5084 {"prepare", 0, PARAM_I16, PARAM_UI8, 0 },
\r
5085 {"dispose", 0, 0, 0, 0 },
\r
5086 {"retf", 0, PARAM_I16, 0, 0, DASMFLAG_STEP_OUT},
\r
5087 {"retf", 0, 0, 0, 0, DASMFLAG_STEP_OUT},
\r
5088 {"brk 3", 0, 0, 0, 0, DASMFLAG_STEP_OVER},
\r
5089 {"brk", 0, PARAM_UI8, 0, 0, DASMFLAG_STEP_OVER},
\r
5090 {"brkv", 0, 0, 0, 0 },
\r
5091 {"reti", 0, 0, 0, 0, DASMFLAG_STEP_OUT},
\r
5093 {"shiftb", GROUP, 0, 0, 0 },
\r
5094 {"shiftw", GROUP, 0, 0, 0 },
\r
5095 {"shiftbv", GROUP, 0, 0, 0 },
\r
5096 {"shiftwv", GROUP, 0, 0, 0 },
\r
5097 {"cvtbd", 0, PARAM_I8, 0, 0 },
\r
5098 {"cvtdb", 0, PARAM_I8, 0, 0 },
\r
5099 {"???", 0, 0, 0, 0 },
\r
5100 {"trans", 0, 0, 0, 0 },
\r
5101 {"escape", FPU, 0, 0, 0 },
\r
5102 {"escape", FPU, 0, 0, 0 },
\r
5103 {"escape", FPU, 0, 0, 0 },
\r
5104 {"escape", FPU, 0, 0, 0 },
\r
5105 {"escape", FPU, 0, 0, 0 },
\r
5106 {"escape", FPU, 0, 0, 0 },
\r
5107 {"escape", FPU, 0, 0, 0 },
\r
5108 {"escape", FPU, 0, 0, 0 },
\r
5110 {"dbnzne", 0, PARAM_REL8, 0, 0, DASMFLAG_STEP_OVER},
\r
5111 {"dbnze", 0, PARAM_REL8, 0, 0, DASMFLAG_STEP_OVER},
\r
5112 {"dbnz", 0, PARAM_REL8, 0, 0, DASMFLAG_STEP_OVER},
\r
5113 {"bcwz", 0, PARAM_REL8, 0, 0 },
\r
5114 {"in", 0, PARAM_AL, PARAM_UI8, 0 },
\r
5115 {"in", 0, PARAM_AW, PARAM_UI8, 0 },
\r
5116 {"out", 0, PARAM_UI8, PARAM_AL, 0 },
\r
5117 {"out", 0, PARAM_UI8, PARAM_AW, 0 },
\r
5118 {"call", 0, PARAM_REL16, 0, 0, DASMFLAG_STEP_OVER},
\r
5119 {"br", 0, PARAM_REL16, 0, 0 },
\r
5120 {"br", 0, PARAM_ADDR, 0, 0 },
\r
5121 {"br", 0, PARAM_REL8, 0, 0 },
\r
5122 {"in", 0, PARAM_AL, PARAM_DW, 0 },
\r
5123 {"in", 0, PARAM_AW, PARAM_DW, 0 },
\r
5124 {"out", 0, PARAM_DW, PARAM_AL, 0 },
\r
5125 {"out", 0, PARAM_DW, PARAM_AW, 0 },
\r
5127 {"buslock", PREFIX, 0, 0, 0 },
\r
5128 {"brks", 0, PARAM_UI8, 0, 0, DASMFLAG_STEP_OVER}, /* V25S/V35S only */
\r
5129 {"repne", PREFIX, 0, 0, 0 },
\r
5130 {"rep", PREFIX, 0, 0, 0 },
\r
5131 {"halt", 0, 0, 0, 0 },
\r
5132 {"not1 cy", 0, 0, 0, 0 },
\r
5133 {"group1b", GROUP, 0, 0, 0 },
\r
5134 {"group1w", GROUP, 0, 0, 0 },
\r
5135 {"clr1 cy", 0, 0, 0, 0 },
\r
5136 {"set1 cy", 0, 0, 0, 0 },
\r
5137 {"di", 0, 0, 0, 0 },
\r
5138 {"ei", 0, 0, 0, 0 },
\r
5139 {"clr1 dir", 0, 0, 0, 0 },
\r
5140 {"set1 dir", 0, 0, 0, 0 },
\r
5141 {"group2b", GROUP, 0, 0, 0 },
\r
5142 {"group2w", GROUP, 0, 0, 0 }
\r
5145 static const I386_OPCODE necv_opcode_table2[256] =
\r
5148 {"???", 0, 0, 0, 0 },
\r
5149 {"???", 0, 0, 0, 0 },
\r
5150 {"???", 0, 0, 0, 0 },
\r
5151 {"???", 0, 0, 0, 0 },
\r
5152 {"???", 0, 0, 0, 0 },
\r
5153 {"???", 0, 0, 0, 0 },
\r
5154 {"???", 0, 0, 0, 0 },
\r
5155 {"???", 0, 0, 0, 0 },
\r
5156 {"???", 0, 0, 0, 0 },
\r
5157 {"???", 0, 0, 0, 0 },
\r
5158 {"???", 0, 0, 0, 0 },
\r
5159 {"???", 0, 0, 0, 0 },
\r
5160 {"???", 0, 0, 0, 0 },
\r
5161 {"???", 0, 0, 0, 0 },
\r
5162 {"???", 0, 0, 0, 0 },
\r
5163 {"???", 0, 0, 0, 0 },
\r
5165 {"test1", MODRM, PARAM_RMPTR8, PARAM_CL, 0 },
\r
5166 {"test1", MODRM, PARAM_RMPTR16, PARAM_CL, 0 },
\r
5167 {"clr1", MODRM, PARAM_RMPTR8, PARAM_CL, 0 },
\r
5168 {"clr1", MODRM, PARAM_RMPTR16, PARAM_CL, 0 },
\r
5169 {"set1", MODRM, PARAM_RMPTR8, PARAM_CL, 0 },
\r
5170 {"set1", MODRM, PARAM_RMPTR16, PARAM_CL, 0 },
\r
5171 {"not1", MODRM, PARAM_RMPTR8, PARAM_CL, 0 },
\r
5172 {"not1", MODRM, PARAM_RMPTR16, PARAM_CL, 0 },
\r
5173 {"test1", MODRM, PARAM_RMPTR8, PARAM_I3, 0 },
\r
5174 {"test1", MODRM, PARAM_RMPTR16, PARAM_I4, 0 },
\r
5175 {"clr1", MODRM, PARAM_RMPTR8, PARAM_I3, 0 },
\r
5176 {"clr1", MODRM, PARAM_RMPTR16, PARAM_I4, 0 },
\r
5177 {"set1", MODRM, PARAM_RMPTR8, PARAM_I3, 0 },
\r
5178 {"set1", MODRM, PARAM_RMPTR16, PARAM_I4, 0 },
\r
5179 {"not1", MODRM, PARAM_RMPTR8, PARAM_I3, 0 },
\r
5180 {"not1", MODRM, PARAM_RMPTR16, PARAM_I4, 0 },
\r
5182 {"add4s", 0, 0, 0, 0 },
\r
5183 {"???", 0, 0, 0, 0 },
\r
5184 {"sub4s", 0, 0, 0, 0 },
\r
5185 {"???", 0, 0, 0, 0 },
\r
5186 {"???", 0, 0, 0, 0 },
\r
5187 {"movspa", 0, 0, 0, 0 }, /* V25/V35 only */
\r
5188 {"cmp4s", 0, 0, 0, 0 },
\r
5189 {"???", 0, 0, 0, 0 },
\r
5190 {"rol4", MODRM, PARAM_RMPTR8, 0, 0 },
\r
5191 {"???", 0, 0, 0, 0 },
\r
5192 {"ror4", MODRM, PARAM_RMPTR8, 0, 0 },
\r
5193 {"???", 0, 0, 0, 0 },
\r
5194 {"???", 0, 0, 0, 0 },
\r
5195 {"brkcs", MODRM, PARAM_REG2_16, 0, 0, DASMFLAG_STEP_OVER}, /* V25/V35 only */
\r
5196 {"???", 0, 0, 0, 0 },
\r
5197 {"???", 0, 0, 0, 0 },
\r
5199 {"???", 0, 0, 0, 0 },
\r
5200 {"ins", MODRM, PARAM_REG2_8, PARAM_REG8, 0 },
\r
5201 {"???", 0, 0, 0, 0 },
\r
5202 {"ext", MODRM, PARAM_REG2_8, PARAM_REG8, 0 },
\r
5203 {"???", 0, 0, 0, 0 },
\r
5204 {"???", 0, 0, 0, 0 },
\r
5205 {"???", 0, 0, 0, 0 },
\r
5206 {"???", 0, 0, 0, 0 },
\r
5207 {"???", 0, 0, 0, 0 },
\r
5208 {"ins", MODRM, PARAM_REG2_8, PARAM_I4, 0 },
\r
5209 {"???", 0, 0, 0, 0 },
\r
5210 {"ext", MODRM, PARAM_REG2_8, PARAM_I4, 0 },
\r
5211 {"???", 0, 0, 0, 0 },
\r
5212 {"???", 0, 0, 0, 0 },
\r
5213 {"???", 0, 0, 0, 0 },
\r
5214 {"???", 0, 0, 0, 0 },
\r
5216 {"???", 0, 0, 0, 0 },
\r
5217 {"???", 0, 0, 0, 0 },
\r
5218 {"???", 0, 0, 0, 0 },
\r
5219 {"???", 0, 0, 0, 0 },
\r
5220 {"???", 0, 0, 0, 0 },
\r
5221 {"???", 0, 0, 0, 0 },
\r
5222 {"???", 0, 0, 0, 0 },
\r
5223 {"???", 0, 0, 0, 0 },
\r
5224 {"???", 0, 0, 0, 0 },
\r
5225 {"???", 0, 0, 0, 0 },
\r
5226 {"???", 0, 0, 0, 0 },
\r
5227 {"???", 0, 0, 0, 0 },
\r
5228 {"???", 0, 0, 0, 0 },
\r
5229 {"???", 0, 0, 0, 0 },
\r
5230 {"???", 0, 0, 0, 0 },
\r
5231 {"???", 0, 0, 0, 0 },
\r
5233 {"???", 0, 0, 0, 0 },
\r
5234 {"???", 0, 0, 0, 0 },
\r
5235 {"???", 0, 0, 0, 0 },
\r
5236 {"???", 0, 0, 0, 0 },
\r
5237 {"???", 0, 0, 0, 0 },
\r
5238 {"???", 0, 0, 0, 0 },
\r
5239 {"???", 0, 0, 0, 0 },
\r
5240 {"???", 0, 0, 0, 0 },
\r
5241 {"???", 0, 0, 0, 0 },
\r
5242 {"???", 0, 0, 0, 0 },
\r
5243 {"???", 0, 0, 0, 0 },
\r
5244 {"???", 0, 0, 0, 0 },
\r
5245 {"???", 0, 0, 0, 0 },
\r
5246 {"???", 0, 0, 0, 0 },
\r
5247 {"???", 0, 0, 0, 0 },
\r
5248 {"???", 0, 0, 0, 0 },
\r
5250 {"???", 0, 0, 0, 0 },
\r
5251 {"???", 0, 0, 0, 0 },
\r
5252 {"???", 0, 0, 0, 0 },
\r
5253 {"???", 0, 0, 0, 0 },
\r
5254 {"???", 0, 0, 0, 0 },
\r
5255 {"???", 0, 0, 0, 0 },
\r
5256 {"???", 0, 0, 0, 0 },
\r
5257 {"???", 0, 0, 0, 0 },
\r
5258 {"???", 0, 0, 0, 0 },
\r
5259 {"???", 0, 0, 0, 0 },
\r
5260 {"???", 0, 0, 0, 0 },
\r
5261 {"???", 0, 0, 0, 0 },
\r
5262 {"???", 0, 0, 0, 0 },
\r
5263 {"???", 0, 0, 0, 0 },
\r
5264 {"???", 0, 0, 0, 0 },
\r
5265 {"???", 0, 0, 0, 0 },
\r
5267 {"???", 0, 0, 0, 0 },
\r
5268 {"???", 0, 0, 0, 0 },
\r
5269 {"???", 0, 0, 0, 0 },
\r
5270 {"???", 0, 0, 0, 0 },
\r
5271 {"???", 0, 0, 0, 0 },
\r
5272 {"???", 0, 0, 0, 0 },
\r
5273 {"???", 0, 0, 0, 0 },
\r
5274 {"???", 0, 0, 0, 0 },
\r
5275 {"???", 0, 0, 0, 0 },
\r
5276 {"???", 0, 0, 0, 0 },
\r
5277 {"???", 0, 0, 0, 0 },
\r
5278 {"???", 0, 0, 0, 0 },
\r
5279 {"???", 0, 0, 0, 0 },
\r
5280 {"???", 0, 0, 0, 0 },
\r
5281 {"???", 0, 0, 0, 0 },
\r
5282 {"???", 0, 0, 0, 0 },
\r
5284 {"???", 0, 0, 0, 0 },
\r
5285 {"???", 0, 0, 0, 0 },
\r
5286 {"???", 0, 0, 0, 0 },
\r
5287 {"???", 0, 0, 0, 0 },
\r
5288 {"???", 0, 0, 0, 0 },
\r
5289 {"???", 0, 0, 0, 0 },
\r
5290 {"???", 0, 0, 0, 0 },
\r
5291 {"???", 0, 0, 0, 0 },
\r
5292 {"???", 0, 0, 0, 0 },
\r
5293 {"???", 0, 0, 0, 0 },
\r
5294 {"???", 0, 0, 0, 0 },
\r
5295 {"???", 0, 0, 0, 0 },
\r
5296 {"???", 0, 0, 0, 0 },
\r
5297 {"???", 0, 0, 0, 0 },
\r
5298 {"???", 0, 0, 0, 0 },
\r
5299 {"???", 0, 0, 0, 0 },
\r
5301 {"???", 0, 0, 0, 0 },
\r
5302 {"retrbi", 0, 0, 0, 0 }, /* V25/V35 only */
\r
5303 {"fint", 0, 0, 0, 0 }, /* V25/V35 only */
\r
5304 {"???", 0, 0, 0, 0 },
\r
5305 {"tsksw", MODRM, PARAM_REG2_16, 0, 0 }, /* V25/V35 only */
\r
5306 {"movspb", MODRM, PARAM_REG2_16, 0, 0 }, /* V25/V35 only */
\r
5307 {"???", 0, 0, 0, 0 },
\r
5308 {"???", 0, 0, 0, 0 },
\r
5309 {"???", 0, 0, 0, 0 },
\r
5310 {"???", 0, 0, 0, 0 },
\r
5311 {"???", 0, 0, 0, 0 },
\r
5312 {"???", 0, 0, 0, 0 },
\r
5313 {"btclr", 0, PARAM_SFREG, PARAM_I3, PARAM_REL8 }, /* V25/V35 only */
\r
5314 {"???", 0, 0, 0, 0 },
\r
5315 {"stop", 0, 0, 0, 0 }, /* V25/V35 only */
\r
5316 {"???", 0, 0, 0, 0 },
\r
5318 {"???", 0, 0, 0, 0 },
\r
5319 {"???", 0, 0, 0, 0 },
\r
5320 {"???", 0, 0, 0, 0 },
\r
5321 {"???", 0, 0, 0, 0 },
\r
5322 {"???", 0, 0, 0, 0 },
\r
5323 {"???", 0, 0, 0, 0 },
\r
5324 {"???", 0, 0, 0, 0 },
\r
5325 {"???", 0, 0, 0, 0 },
\r
5326 {"???", 0, 0, 0, 0 },
\r
5327 {"???", 0, 0, 0, 0 },
\r
5328 {"???", 0, 0, 0, 0 },
\r
5329 {"???", 0, 0, 0, 0 },
\r
5330 {"???", 0, 0, 0, 0 },
\r
5331 {"???", 0, 0, 0, 0 },
\r
5332 {"???", 0, 0, 0, 0 },
\r
5333 {"???", 0, 0, 0, 0 },
\r
5335 {"???", 0, 0, 0, 0 },
\r
5336 {"???", 0, 0, 0, 0 },
\r
5337 {"???", 0, 0, 0, 0 },
\r
5338 {"???", 0, 0, 0, 0 },
\r
5339 {"???", 0, 0, 0, 0 },
\r
5340 {"???", 0, 0, 0, 0 },
\r
5341 {"???", 0, 0, 0, 0 },
\r
5342 {"???", 0, 0, 0, 0 },
\r
5343 {"???", 0, 0, 0, 0 },
\r
5344 {"???", 0, 0, 0, 0 },
\r
5345 {"???", 0, 0, 0, 0 },
\r
5346 {"???", 0, 0, 0, 0 },
\r
5347 {"???", 0, 0, 0, 0 },
\r
5348 {"???", 0, 0, 0, 0 },
\r
5349 {"???", 0, 0, 0, 0 },
\r
5350 {"???", 0, 0, 0, 0 },
\r
5352 {"???", 0, 0, 0, 0 },
\r
5353 {"???", 0, 0, 0, 0 },
\r
5354 {"???", 0, 0, 0, 0 },
\r
5355 {"???", 0, 0, 0, 0 },
\r
5356 {"???", 0, 0, 0, 0 },
\r
5357 {"???", 0, 0, 0, 0 },
\r
5358 {"???", 0, 0, 0, 0 },
\r
5359 {"???", 0, 0, 0, 0 },
\r
5360 {"???", 0, 0, 0, 0 },
\r
5361 {"???", 0, 0, 0, 0 },
\r
5362 {"???", 0, 0, 0, 0 },
\r
5363 {"???", 0, 0, 0, 0 },
\r
5364 {"???", 0, 0, 0, 0 },
\r
5365 {"???", 0, 0, 0, 0 },
\r
5366 {"???", 0, 0, 0, 0 },
\r
5367 {"???", 0, 0, 0, 0 },
\r
5369 {"???", 0, 0, 0, 0 },
\r
5370 {"???", 0, 0, 0, 0 },
\r
5371 {"???", 0, 0, 0, 0 },
\r
5372 {"???", 0, 0, 0, 0 },
\r
5373 {"???", 0, 0, 0, 0 },
\r
5374 {"???", 0, 0, 0, 0 },
\r
5375 {"???", 0, 0, 0, 0 },
\r
5376 {"???", 0, 0, 0, 0 },
\r
5377 {"???", 0, 0, 0, 0 },
\r
5378 {"???", 0, 0, 0, 0 },
\r
5379 {"???", 0, 0, 0, 0 },
\r
5380 {"???", 0, 0, 0, 0 },
\r
5381 {"???", 0, 0, 0, 0 },
\r
5382 {"???", 0, 0, 0, 0 },
\r
5383 {"???", 0, 0, 0, 0 },
\r
5384 {"???", 0, 0, 0, 0 },
\r
5386 {"brkxa", 0, PARAM_UI8, 0, 0 }, /* V33,53 only */
\r
5387 {"???", 0, 0, 0, 0 },
\r
5388 {"???", 0, 0, 0, 0 },
\r
5389 {"???", 0, 0, 0, 0 },
\r
5390 {"???", 0, 0, 0, 0 },
\r
5391 {"???", 0, 0, 0, 0 },
\r
5392 {"???", 0, 0, 0, 0 },
\r
5393 {"???", 0, 0, 0, 0 },
\r
5394 {"???", 0, 0, 0, 0 },
\r
5395 {"???", 0, 0, 0, 0 },
\r
5396 {"???", 0, 0, 0, 0 },
\r
5397 {"???", 0, 0, 0, 0 },
\r
5398 {"???", 0, 0, 0, 0 },
\r
5399 {"???", 0, 0, 0, 0 },
\r
5400 {"???", 0, 0, 0, 0 },
\r
5401 {"???", 0, 0, 0, 0 },
\r
5403 {"retxa", 0, PARAM_UI8, 0, 0 }, /* V33,53 only */
\r
5404 {"???", 0, 0, 0, 0 },
\r
5405 {"???", 0, 0, 0, 0 },
\r
5406 {"???", 0, 0, 0, 0 },
\r
5407 {"???", 0, 0, 0, 0 },
\r
5408 {"???", 0, 0, 0, 0 },
\r
5409 {"???", 0, 0, 0, 0 },
\r
5410 {"???", 0, 0, 0, 0 },
\r
5411 {"???", 0, 0, 0, 0 },
\r
5412 {"???", 0, 0, 0, 0 },
\r
5413 {"???", 0, 0, 0, 0 },
\r
5414 {"???", 0, 0, 0, 0 },
\r
5415 {"???", 0, 0, 0, 0 },
\r
5416 {"???", 0, 0, 0, 0 },
\r
5417 {"???", 0, 0, 0, 0 },
\r
5418 {"brkem", 0, PARAM_UI8, 0, 0 } /* V20,30,40,50 only */
\r
5421 static const I386_OPCODE immb_table[8] =
\r
5423 {"add", 0, PARAM_RMPTR8, PARAM_UI8, 0 },
\r
5424 {"or", 0, PARAM_RMPTR8, PARAM_UI8, 0 },
\r
5425 {"addc", 0, PARAM_RMPTR8, PARAM_UI8, 0 },
\r
5426 {"subc", 0, PARAM_RMPTR8, PARAM_UI8, 0 },
\r
5427 {"and", 0, PARAM_RMPTR8, PARAM_UI8, 0 },
\r
5428 {"sub", 0, PARAM_RMPTR8, PARAM_UI8, 0 },
\r
5429 {"xor", 0, PARAM_RMPTR8, PARAM_UI8, 0 },
\r
5430 {"cmp", 0, PARAM_RMPTR8, PARAM_UI8, 0 }
\r
5433 static const I386_OPCODE immw_table[8] =
\r
5435 {"add", 0, PARAM_RMPTR16, PARAM_IMM, 0 },
\r
5436 {"or", 0, PARAM_RMPTR16, PARAM_IMM, 0 },
\r
5437 {"addc", 0, PARAM_RMPTR16, PARAM_IMM, 0 },
\r
5438 {"subc", 0, PARAM_RMPTR16, PARAM_IMM, 0 },
\r
5439 {"and", 0, PARAM_RMPTR16, PARAM_IMM, 0 },
\r
5440 {"sub", 0, PARAM_RMPTR16, PARAM_IMM, 0 },
\r
5441 {"xor", 0, PARAM_RMPTR16, PARAM_IMM, 0 },
\r
5442 {"cmp", 0, PARAM_RMPTR16, PARAM_IMM, 0 }
\r
5445 static const I386_OPCODE immws_table[8] =
\r
5447 {"add", 0, PARAM_RMPTR16, PARAM_I8, 0 },
\r
5448 {"or", 0, PARAM_RMPTR16, PARAM_I8, 0 },
\r
5449 {"addc", 0, PARAM_RMPTR16, PARAM_I8, 0 },
\r
5450 {"subc", 0, PARAM_RMPTR16, PARAM_I8, 0 },
\r
5451 {"and", 0, PARAM_RMPTR16, PARAM_I8, 0 },
\r
5452 {"sub", 0, PARAM_RMPTR16, PARAM_I8, 0 },
\r
5453 {"xor", 0, PARAM_RMPTR16, PARAM_I8, 0 },
\r
5454 {"cmp", 0, PARAM_RMPTR16, PARAM_I8, 0 }
\r
5457 static const I386_OPCODE shiftbi_table[8] =
\r
5459 {"rol", 0, PARAM_RMPTR8, PARAM_I8, 0 },
\r
5460 {"ror", 0, PARAM_RMPTR8, PARAM_I8, 0 },
\r
5461 {"rolc", 0, PARAM_RMPTR8, PARAM_I8, 0 },
\r
5462 {"rorc", 0, PARAM_RMPTR8, PARAM_I8, 0 },
\r
5463 {"shl", 0, PARAM_RMPTR8, PARAM_I8, 0 },
\r
5464 {"shr", 0, PARAM_RMPTR8, PARAM_I8, 0 },
\r
5465 {"???", 0, PARAM_RMPTR8, PARAM_I8, 0 },
\r
5466 {"shra", 0, PARAM_RMPTR8, PARAM_I8, 0 }
\r
5469 static const I386_OPCODE shiftwi_table[8] =
\r
5471 {"rol", 0, PARAM_RMPTR16, PARAM_I8, 0 },
\r
5472 {"ror", 0, PARAM_RMPTR16, PARAM_I8, 0 },
\r
5473 {"rolc", 0, PARAM_RMPTR16, PARAM_I8, 0 },
\r
5474 {"rorc", 0, PARAM_RMPTR16, PARAM_I8, 0 },
\r
5475 {"shl", 0, PARAM_RMPTR16, PARAM_I8, 0 },
\r
5476 {"shr", 0, PARAM_RMPTR16, PARAM_I8, 0 },
\r
5477 {"???", 0, PARAM_RMPTR16, PARAM_I8, 0 },
\r
5478 {"shra", 0, PARAM_RMPTR16, PARAM_I8, 0 }
\r
5481 static const I386_OPCODE shiftb_table[8] =
\r
5483 {"rol", 0, PARAM_RMPTR8, PARAM_1, 0 },
\r
5484 {"ror", 0, PARAM_RMPTR8, PARAM_1, 0 },
\r
5485 {"rolc", 0, PARAM_RMPTR8, PARAM_1, 0 },
\r
5486 {"rorc", 0, PARAM_RMPTR8, PARAM_1, 0 },
\r
5487 {"shl", 0, PARAM_RMPTR8, PARAM_1, 0 },
\r
5488 {"shr", 0, PARAM_RMPTR8, PARAM_1, 0 },
\r
5489 {"???", 0, PARAM_RMPTR8, PARAM_1, 0 },
\r
5490 {"shra", 0, PARAM_RMPTR8, PARAM_1, 0 }
\r
5493 static const I386_OPCODE shiftw_table[8] =
\r
5495 {"rol", 0, PARAM_RMPTR16, PARAM_1, 0 },
\r
5496 {"ror", 0, PARAM_RMPTR16, PARAM_1, 0 },
\r
5497 {"rolc", 0, PARAM_RMPTR16, PARAM_1, 0 },
\r
5498 {"rorc", 0, PARAM_RMPTR16, PARAM_1, 0 },
\r
5499 {"shl", 0, PARAM_RMPTR16, PARAM_1, 0 },
\r
5500 {"shr", 0, PARAM_RMPTR16, PARAM_1, 0 },
\r
5501 {"???", 0, PARAM_RMPTR16, PARAM_1, 0 },
\r
5502 {"shra", 0, PARAM_RMPTR16, PARAM_1, 0 }
\r
5505 static const I386_OPCODE shiftbv_table[8] =
\r
5507 {"rol", 0, PARAM_RMPTR8, PARAM_CL, 0 },
\r
5508 {"ror", 0, PARAM_RMPTR8, PARAM_CL, 0 },
\r
5509 {"rolc", 0, PARAM_RMPTR8, PARAM_CL, 0 },
\r
5510 {"rorc", 0, PARAM_RMPTR8, PARAM_CL, 0 },
\r
5511 {"shl", 0, PARAM_RMPTR8, PARAM_CL, 0 },
\r
5512 {"shr", 0, PARAM_RMPTR8, PARAM_CL, 0 },
\r
5513 {"???", 0, PARAM_RMPTR8, PARAM_CL, 0 },
\r
5514 {"shra", 0, PARAM_RMPTR8, PARAM_CL, 0 }
\r
5517 static const I386_OPCODE shiftwv_table[8] =
\r
5519 {"rol", 0, PARAM_RMPTR16, PARAM_CL, 0 },
\r
5520 {"ror", 0, PARAM_RMPTR16, PARAM_CL, 0 },
\r
5521 {"rolc", 0, PARAM_RMPTR16, PARAM_CL, 0 },
\r
5522 {"rorc", 0, PARAM_RMPTR16, PARAM_CL, 0 },
\r
5523 {"shl", 0, PARAM_RMPTR16, PARAM_CL, 0 },
\r
5524 {"shr", 0, PARAM_RMPTR16, PARAM_CL, 0 },
\r
5525 {"???", 0, PARAM_RMPTR16, PARAM_CL, 0 },
\r
5526 {"shra", 0, PARAM_RMPTR16, PARAM_CL, 0 }
\r
5529 static const I386_OPCODE group1b_table[8] =
\r
5531 {"test", 0, PARAM_RMPTR8, PARAM_UI8, 0 },
\r
5532 {"???", 0, 0, 0, 0 },
\r
5533 {"not", 0, PARAM_RMPTR8, 0, 0 },
\r
5534 {"neg", 0, PARAM_RMPTR8, 0, 0 },
\r
5535 {"mulu", 0, PARAM_RMPTR8, 0, 0 },
\r
5536 {"mul", 0, PARAM_RMPTR8, 0, 0 },
\r
5537 {"divu", 0, PARAM_RMPTR8, 0, 0 },
\r
5538 {"div", 0, PARAM_RMPTR8, 0, 0 }
\r
5541 static const I386_OPCODE group1w_table[8] =
\r
5543 {"test", 0, PARAM_RMPTR16, PARAM_IMM, 0 },
\r
5544 {"???", 0, 0, 0, 0 },
\r
5545 {"not", 0, PARAM_RMPTR16, 0, 0 },
\r
5546 {"neg", 0, PARAM_RMPTR16, 0, 0 },
\r
5547 {"mulu", 0, PARAM_RMPTR16, 0, 0 },
\r
5548 {"mul", 0, PARAM_RMPTR16, 0, 0 },
\r
5549 {"divu", 0, PARAM_RMPTR16, 0, 0 },
\r
5550 {"div", 0, PARAM_RMPTR16, 0, 0 }
\r
5553 static const I386_OPCODE group2b_table[8] =
\r
5555 {"inc", 0, PARAM_RMPTR8, 0, 0 },
\r
5556 {"dec", 0, PARAM_RMPTR8, 0, 0 },
\r
5557 {"???", 0, 0, 0, 0 },
\r
5558 {"???", 0, 0, 0, 0 },
\r
5559 {"???", 0, 0, 0, 0 },
\r
5560 {"???", 0, 0, 0, 0 },
\r
5561 {"???", 0, 0, 0, 0 },
\r
5562 {"???", 0, 0, 0, 0 }
\r
5565 static const I386_OPCODE group2w_table[8] =
\r
5567 {"inc", 0, PARAM_RMPTR16, 0, 0 },
\r
5568 {"dec", 0, PARAM_RMPTR16, 0, 0 },
\r
5569 {"call", 0, PARAM_RMPTR16, 0, 0, DASMFLAG_STEP_OVER},
\r
5570 {"call far ptr ",0, PARAM_RM16, 0, 0, DASMFLAG_STEP_OVER},
\r
5571 {"br", 0, PARAM_RMPTR16, 0, 0 },
\r
5572 {"br far ptr ",0, PARAM_RM16, 0, 0 },
\r
5573 {"push", 0, PARAM_RMPTR16, 0, 0 },
\r
5574 {"???", 0, 0, 0, 0 }
\r
5577 static const GROUP_OP group_op_table[] =
\r
5579 { "immb", immb_table },
\r
5580 { "immw", immw_table },
\r
5581 { "immws", immws_table },
\r
5582 { "shiftbi", shiftbi_table },
\r
5583 { "shiftwi", shiftwi_table },
\r
5584 { "shiftb", shiftb_table },
\r
5585 { "shiftw", shiftw_table },
\r
5586 { "shiftbv", shiftbv_table },
\r
5587 { "shiftwv", shiftwv_table },
\r
5588 { "group1b", group1b_table },
\r
5589 { "group1w", group1w_table },
\r
5590 { "group2b", group2b_table },
\r
5591 { "group2w", group2w_table }
\r
5596 static const char *const nec_reg[8] = { "aw", "cw", "dw", "bw", "sp", "bp", "ix", "iy" };
\r
5597 static const char *const nec_reg8[8] = { "al", "cl", "dl", "bl", "ah", "ch", "dh", "bh" };
\r
5598 static const char *const nec_sreg[8] = { "ds1", "ps", "ss", "ds0", "???", "???", "???", "???" };
\r
5599 static const char *const nec_sfreg[256] =
\r
5602 "p0", "pm0", "pmc0", "???", "???", "???", "???", "???",
\r
5603 "p1", "pm1", "pmc1", "???", "???", "???", "???", "???",
\r
5605 "p2", "pm2", "pmc2", "???", "???", "???", "???", "???",
\r
5606 "???", "???", "???", "???", "???", "???", "???", "???",
\r
5608 "???", "???", "???", "???", "???", "???", "???", "???",
\r
5609 "???", "???", "???", "???", "???", "???", "???", "???",
\r
5611 "???", "???", "???", "???", "???", "???", "???", "???",
\r
5612 "pt", "???", "???", "pmt", "???", "???", "???", "???",
\r
5614 "intm", "???", "???", "???", "ems0", "ems1", "ems2", "???",
\r
5615 "???", "???", "???", "???", "exic0","exic1","exic2","???",
\r
5617 "???", "???", "???", "???", "???", "???", "???", "???",
\r
5618 "???", "???", "???", "???", "???", "???", "???", "???",
\r
5620 "rxb0", "???", "txb0", "???", "???", "srms0","stms0","???",
\r
5621 "scm0", "scc0", "brg0", "scs0", "seic0","sric0","stic0","???",
\r
5623 "rxb1", "???", "txb1", "???", "???", "srms1","stms1","???",
\r
5624 "scm1", "scc1", "brg1", "scs1", "seic1","sric1","stic1","???",
\r
5626 "tm0", "???", "md0", "???", "???", "???", "???", "???",
\r
5627 "tm1", "???", "md1", "???", "???", "???", "???", "???",
\r
5629 "tmc0", "tmc1", "???", "???", "tmms0","tmms1","tmms2","???",
\r
5630 "???", "???", "???", "???", "tmic0","tmic1","tmic2","???",
\r
5632 "dmac0","dmam0","dmac1","dmam1","???", "???", "???", "???",
\r
5633 "???", "???", "???", "???", "dic0", "dic1", "???", "???",
\r
5635 "???", "???", "???", "???", "???", "???", "???", "???",
\r
5636 "???", "???", "???", "???", "???", "???", "???", "???",
\r
5638 "sar0l","sar0m","sar0h","???", "dar0l","dar0m","dar0h","???",
\r
5639 "tc0l", "tc0h", "???", "???", "???", "???", "???", "???",
\r
5641 "sar1l","sar1m","sar1h","???", "dar1l","dar1m","dar1h","???",
\r
5642 "tc1l", "tc1h", "???", "???", "???", "???", "???", "???",
\r
5644 "stbc", "rfm", "???", "???", "???", "???", "???", "???",
\r
5645 "wtc", "???", "flag", "prc", "tbic", "???", "???", "irqs",
\r
5647 "???", "???", "???", "???", "???", "???", "???", "???",
\r
5648 "???", "???", "???", "???", "ispr", "???", "???", "idb"
\r
5652 static UINT8 modrm;
\r
5653 static UINT32 segment;
\r
5654 static offs_t dasm_flags;
\r
5655 static char modrm_string[256];
\r
5657 #define MODRM_REG1 ((modrm >> 3) & 0x7)
\r
5658 #define MODRM_REG2 (modrm & 0x7)
\r
5660 #define MAX_LENGTH 8
\r
5662 INLINE UINT8 FETCHD(void)
\r
5664 if ((opcode_ptr - opcode_ptr_base) + 1 > MAX_LENGTH)
\r
5667 return *opcode_ptr++;
\r
5670 INLINE UINT16 FETCHD16(void)
\r
5673 if ((opcode_ptr - opcode_ptr_base) + 2 > MAX_LENGTH)
\r
5675 d = opcode_ptr[0] | (opcode_ptr[1] << 8);
\r
5681 static char *hexstring(UINT32 value, int digits)
\r
5683 static char buffer[20];
\r
5686 sprintf(&buffer[1], "%0*Xh", digits, value);
\r
5688 sprintf(&buffer[1], "%Xh", value);
\r
5690 return (buffer[1] >= '0' && buffer[1] <= '9') ? &buffer[1] : &buffer[0];
\r
5693 static char *shexstring(UINT32 value, int digits, int always)
\r
5695 static char buffer[20];
\r
5696 if (value >= 0x80000000) {
\r
5697 sprintf(buffer, "-%s", hexstring(-value, digits));
\r
5698 } else if (always) {
\r
5699 sprintf(buffer, "+%s", hexstring(value, digits));
\r
5701 return hexstring(value, digits);
\r
5706 static void handle_modrm(char* s)
\r
5713 mod = (modrm >> 6) & 0x3;
\r
5714 rm = (modrm & 0x7);
\r
5716 if( modrm >= 0xc0 )
\r
5721 case SEG_PS: s += sprintf( s, "ps:" ); break;
\r
5722 case SEG_DS0: s += sprintf( s, "ds0:" ); break;
\r
5723 case SEG_DS1: s += sprintf( s, "ds1:" ); break;
\r
5724 case SEG_SS: s += sprintf( s, "ss:" ); break;
\r
5727 s += sprintf( s, "[" );
\r
5730 case 0: s += sprintf( s, "bw+ix" ); break;
\r
5731 case 1: s += sprintf( s, "bw+iy" ); break;
\r
5732 case 2: s += sprintf( s, "bp+ix" ); break;
\r
5733 case 3: s += sprintf( s, "bp+iy" ); break;
\r
5734 case 4: s += sprintf( s, "ix" ); break;
\r
5735 case 5: s += sprintf( s, "iy" ); break;
\r
5738 disp16 = FETCHD16();
\r
5739 s += sprintf( s, "%s", hexstring((unsigned) (UINT16) disp16, 0) );
\r
5741 s += sprintf( s, "bp" );
\r
5744 case 7: s += sprintf( s, "bw" ); break;
\r
5748 s += sprintf( s, "%s", shexstring((INT32)disp8, 0, TRUE) );
\r
5749 } else if( mod == 2 ) {
\r
5750 disp16 = FETCHD16();
\r
5751 s += sprintf( s, "%s", shexstring((INT32)disp16, 0, TRUE) );
\r
5753 s += sprintf( s, "]" );
\r
5756 static char* handle_param(char* s, UINT32 param)
\r
5768 s += sprintf( s, "%s", nec_reg8[MODRM_REG1] );
\r
5772 s += sprintf( s, "%s", nec_reg[MODRM_REG1] );
\r
5775 case PARAM_REG2_8:
\r
5776 s += sprintf( s, "%s", nec_reg8[MODRM_REG2] );
\r
5779 case PARAM_REG2_16:
\r
5780 s += sprintf( s, "%s", nec_reg[MODRM_REG2] );
\r
5784 case PARAM_RMPTR8:
\r
5785 if( modrm >= 0xc0 ) {
\r
5786 s += sprintf( s, "%s", nec_reg8[MODRM_REG2] );
\r
5788 if (param == PARAM_RMPTR8)
\r
5789 s += sprintf( s, "byte ptr " );
\r
5790 s += sprintf( s, "%s", modrm_string );
\r
5795 case PARAM_RMPTR16:
\r
5796 if( modrm >= 0xc0 ) {
\r
5797 s += sprintf( s, "%s", nec_reg[MODRM_REG2] );
\r
5799 if (param == PARAM_RMPTR16)
\r
5800 s += sprintf( s, "word ptr " );
\r
5801 s += sprintf( s, "%s", modrm_string );
\r
5807 s += sprintf( s, "%d", i8 & 0x07 );
\r
5812 s += sprintf( s, "%d", i8 & 0x0f );
\r
5817 s += sprintf( s, "%s", shexstring((INT8)i8, 0, FALSE) );
\r
5822 s += sprintf( s, "%s", shexstring((INT16)i16, 0, FALSE) );
\r
5827 s += sprintf( s, "%s", shexstring((UINT8)i8, 0, FALSE) );
\r
5832 s += sprintf( s, "%s", hexstring(i16, 0) );
\r
5836 addr = FETCHD16();
\r
5838 s += sprintf( s, "%s:", hexstring(ptr, 4) );
\r
5839 s += sprintf( s, "%s", hexstring(addr, 0) );
\r
5843 /* make sure to keep the relative offset within the segment */
\r
5845 s += sprintf( s, "%s", hexstring((pc & 0xFFFF0000) | ((pc + d16) & 0x0000FFFF), 0) );
\r
5850 s += sprintf( s, "%s", hexstring(pc + d8, 0) );
\r
5853 case PARAM_MEM_OFFS:
\r
5856 case SEG_PS: s += sprintf( s, "ps:" ); break;
\r
5857 case SEG_DS0: s += sprintf( s, "ds0:" ); break;
\r
5858 case SEG_DS1: s += sprintf( s, "ds1:" ); break;
\r
5859 case SEG_SS: s += sprintf( s, "ss:" ); break;
\r
5863 s += sprintf( s, "[%s]", hexstring(i16, 0) );
\r
5867 s += sprintf( s, "%s", nec_sreg[MODRM_REG1] );
\r
5872 s += sprintf( s, "%s", nec_sfreg[i8] );
\r
5876 s += sprintf( s, "1" );
\r
5879 case PARAM_AL: s += sprintf( s, "al" ); break;
\r
5880 case PARAM_CL: s += sprintf( s, "cl" ); break;
\r
5881 case PARAM_DL: s += sprintf( s, "dl" ); break;
\r
5882 case PARAM_BL: s += sprintf( s, "bl" ); break;
\r
5883 case PARAM_AH: s += sprintf( s, "ah" ); break;
\r
5884 case PARAM_CH: s += sprintf( s, "ch" ); break;
\r
5885 case PARAM_DH: s += sprintf( s, "dh" ); break;
\r
5886 case PARAM_BH: s += sprintf( s, "bh" ); break;
\r
5888 case PARAM_AW: s += sprintf( s, "aw" ); break;
\r
5889 case PARAM_CW: s += sprintf( s, "cw" ); break;
\r
5890 case PARAM_DW: s += sprintf( s, "dw" ); break;
\r
5891 case PARAM_BW: s += sprintf( s, "bw" ); break;
\r
5892 case PARAM_SP: s += sprintf( s, "sp" ); break;
\r
5893 case PARAM_BP: s += sprintf( s, "bp" ); break;
\r
5894 case PARAM_IX: s += sprintf( s, "ix" ); break;
\r
5895 case PARAM_IY: s += sprintf( s, "iy" ); break;
\r
5900 static void handle_fpu(char *s, UINT8 op1, UINT8 op2)
\r
5902 switch (op1 & 0x7)
\r
5904 case 0: // Group D8
\r
5908 pc--; // adjust fetch pointer, so modrm byte read again
\r
5910 handle_modrm( modrm_string );
\r
5911 switch ((op2 >> 3) & 0x7)
\r
5913 case 0: sprintf(s, "fadd dword ptr %s", modrm_string); break;
\r
5914 case 1: sprintf(s, "fmul dword ptr %s", modrm_string); break;
\r
5915 case 2: sprintf(s, "fcom dword ptr %s", modrm_string); break;
\r
5916 case 3: sprintf(s, "fcomp dword ptr %s", modrm_string); break;
\r
5917 case 4: sprintf(s, "fsub dword ptr %s", modrm_string); break;
\r
5918 case 5: sprintf(s, "fsubr dword ptr %s", modrm_string); break;
\r
5919 case 6: sprintf(s, "fdiv dword ptr %s", modrm_string); break;
\r
5920 case 7: sprintf(s, "fdivr dword ptr %s", modrm_string); break;
\r
5923 switch ((op2 >> 3) & 0x7)
\r
5925 case 0: sprintf(s, "fadd st(0),st(%d)", op2 & 0x7); break;
\r
5926 case 1: sprintf(s, "fcom st(0),st(%d)", op2 & 0x7); break;
\r
5927 case 2: sprintf(s, "fsub st(0),st(%d)", op2 & 0x7); break;
\r
5928 case 3: sprintf(s, "fdiv st(0),st(%d)", op2 & 0x7); break;
\r
5929 case 4: sprintf(s, "fmul st(0),st(%d)", op2 & 0x7); break;
\r
5930 case 5: sprintf(s, "fcomp st(0),st(%d)", op2 & 0x7); break;
\r
5931 case 6: sprintf(s, "fsubr st(0),st(%d)", op2 & 0x7); break;
\r
5932 case 7: sprintf(s, "fdivr st(0),st(%d)", op2 & 0x7); break;
\r
5938 case 1: // Group D9
\r
5942 pc--; // adjust fetch pointer, so modrm byte read again
\r
5944 handle_modrm( modrm_string );
\r
5945 switch ((op2 >> 3) & 0x7)
\r
5947 case 0: sprintf(s, "fld dword ptr %s", modrm_string); break;
\r
5948 case 1: sprintf(s, "??? (FPU)"); break;
\r
5949 case 2: sprintf(s, "fst dword ptr %s", modrm_string); break;
\r
5950 case 3: sprintf(s, "fstp dword ptr %s", modrm_string); break;
\r
5951 case 4: sprintf(s, "fldenv word ptr %s", modrm_string); break;
\r
5952 case 5: sprintf(s, "fldcw word ptr %s", modrm_string); break;
\r
5953 case 6: sprintf(s, "fstenv word ptr %s", modrm_string); break;
\r
5954 case 7: sprintf(s, "fstcw word ptr %s", modrm_string); break;
\r
5957 switch (op2 & 0x3f)
\r
5959 case 0x00: case 0x01: case 0x02: case 0x03: case 0x04: case 0x05: case 0x06: case 0x07:
\r
5960 sprintf(s, "fld st(0),st(%d)", op2 & 0x7); break;
\r
5962 case 0x08: case 0x09: case 0x0a: case 0x0b: case 0x0c: case 0x0d: case 0x0e: case 0x0f:
\r
5963 sprintf(s, "fxch st(0),st(%d)", op2 & 0x7); break;
\r
5965 case 0x10: sprintf(s, "fnop"); break;
\r
5966 case 0x20: sprintf(s, "fchs"); break;
\r
5967 case 0x21: sprintf(s, "fabs"); break;
\r
5968 case 0x24: sprintf(s, "ftst"); break;
\r
5969 case 0x25: sprintf(s, "fxam"); break;
\r
5970 case 0x28: sprintf(s, "fld1"); break;
\r
5971 case 0x29: sprintf(s, "fldl2t"); break;
\r
5972 case 0x2a: sprintf(s, "fldl2e"); break;
\r
5973 case 0x2b: sprintf(s, "fldpi"); break;
\r
5974 case 0x2c: sprintf(s, "fldlg2"); break;
\r
5975 case 0x2d: sprintf(s, "fldln2"); break;
\r
5976 case 0x2e: sprintf(s, "fldz"); break;
\r
5977 case 0x30: sprintf(s, "f2xm1"); break;
\r
5978 case 0x31: sprintf(s, "fyl2x"); break;
\r
5979 case 0x32: sprintf(s, "fptan"); break;
\r
5980 case 0x33: sprintf(s, "fpatan"); break;
\r
5981 case 0x34: sprintf(s, "fxtract"); break;
\r
5982 case 0x35: sprintf(s, "fprem1"); break;
\r
5983 case 0x36: sprintf(s, "fdecstp"); break;
\r
5984 case 0x37: sprintf(s, "fincstp"); break;
\r
5985 case 0x38: sprintf(s, "fprem"); break;
\r
5986 case 0x39: sprintf(s, "fyl2xp1"); break;
\r
5987 case 0x3a: sprintf(s, "fsqrt"); break;
\r
5988 case 0x3b: sprintf(s, "fsincos"); break;
\r
5989 case 0x3c: sprintf(s, "frndint"); break;
\r
5990 case 0x3d: sprintf(s, "fscale"); break;
\r
5991 case 0x3e: sprintf(s, "fsin"); break;
\r
5992 case 0x3f: sprintf(s, "fcos"); break;
\r
5994 default: sprintf(s, "??? (FPU)"); break;
\r
6000 case 2: // Group DA
\r
6004 pc--; // adjust fetch pointer, so modrm byte read again
\r
6006 handle_modrm( modrm_string );
\r
6007 switch ((op2 >> 3) & 0x7)
\r
6009 case 0: sprintf(s, "fiadd dword ptr %s", modrm_string); break;
\r
6010 case 1: sprintf(s, "fimul dword ptr %s", modrm_string); break;
\r
6011 case 2: sprintf(s, "ficom dword ptr %s", modrm_string); break;
\r
6012 case 3: sprintf(s, "ficomp dword ptr %s", modrm_string); break;
\r
6013 case 4: sprintf(s, "fisub dword ptr %s", modrm_string); break;
\r
6014 case 5: sprintf(s, "fisubr dword ptr %s", modrm_string); break;
\r
6015 case 6: sprintf(s, "fidiv dword ptr %s", modrm_string); break;
\r
6016 case 7: sprintf(s, "fidivr dword ptr %s", modrm_string); break;
\r
6019 switch (op2 & 0x3f)
\r
6021 case 0x00: case 0x01: case 0x02: case 0x03: case 0x04: case 0x05: case 0x06: case 0x07:
\r
6022 sprintf(s, "fcmovb st(0),st(%d)", op2 & 0x7); break;
\r
6024 case 0x08: case 0x09: case 0x0a: case 0x0b: case 0x0c: case 0x0d: case 0x0e: case 0x0f:
\r
6025 sprintf(s, "fcmove st(0),st(%d)", op2 & 0x7); break;
\r
6027 case 0x10: case 0x11: case 0x12: case 0x13: case 0x14: case 0x15: case 0x16: case 0x17:
\r
6028 sprintf(s, "fcmovbe st(0),st(%d)", op2 & 0x7); break;
\r
6030 case 0x18: case 0x19: case 0x1a: case 0x1b: case 0x1c: case 0x1d: case 0x1e: case 0x1f:
\r
6031 sprintf(s, "fcmovu st(0),st(%d)", op2 & 0x7); break;
\r
6033 default: sprintf(s, "??? (FPU)"); break;
\r
6040 case 3: // Group DB
\r
6044 pc--; // adjust fetch pointer, so modrm byte read again
\r
6046 handle_modrm( modrm_string );
\r
6047 switch ((op2 >> 3) & 0x7)
\r
6049 case 0: sprintf(s, "fild dword ptr %s", modrm_string); break;
\r
6050 case 1: sprintf(s, "??? (FPU)"); break;
\r
6051 case 2: sprintf(s, "fist dword ptr %s", modrm_string); break;
\r
6052 case 3: sprintf(s, "fistp dword ptr %s", modrm_string); break;
\r
6053 case 4: sprintf(s, "??? (FPU)"); break;
\r
6054 case 5: sprintf(s, "fld tword ptr %s", modrm_string); break;
\r
6055 case 6: sprintf(s, "??? (FPU)"); break;
\r
6056 case 7: sprintf(s, "fstp tword ptr %s", modrm_string); break;
\r
6059 switch (op2 & 0x3f)
\r
6061 case 0x00: case 0x01: case 0x02: case 0x03: case 0x04: case 0x05: case 0x06: case 0x07:
\r
6062 sprintf(s, "fcmovnb st(0),st(%d)", op2 & 0x7); break;
\r
6064 case 0x08: case 0x09: case 0x0a: case 0x0b: case 0x0c: case 0x0d: case 0x0e: case 0x0f:
\r
6065 sprintf(s, "fcmovne st(0),st(%d)", op2 & 0x7); break;
\r
6067 case 0x10: case 0x11: case 0x12: case 0x13: case 0x14: case 0x15: case 0x16: case 0x17:
\r
6068 sprintf(s, "fcmovnbe st(0),st(%d)", op2 & 0x7); break;
\r
6070 case 0x18: case 0x19: case 0x1a: case 0x1b: case 0x1c: case 0x1d: case 0x1e: case 0x1f:
\r
6071 sprintf(s, "fcmovnu st(0),st(%d)", op2 & 0x7); break;
\r
6073 case 0x22: sprintf(s, "fclex"); break;
\r
6074 case 0x23: sprintf(s, "finit"); break;
\r
6076 case 0x28: case 0x29: case 0x2a: case 0x2b: case 0x2c: case 0x2d: case 0x2e: case 0x2f:
\r
6077 sprintf(s, "fucomi st(0),st(%d)", op2 & 0x7); break;
\r
6079 case 0x30: case 0x31: case 0x32: case 0x33: case 0x34: case 0x35: case 0x36: case 0x37:
\r
6080 sprintf(s, "fcomi st(0),st(%d)", op2 & 0x7); break;
\r
6082 default: sprintf(s, "??? (FPU)"); break;
\r
6088 case 4: // Group DC
\r
6092 pc--; // adjust fetch pointer, so modrm byte read again
\r
6094 handle_modrm( modrm_string );
\r
6095 switch ((op2 >> 3) & 0x7)
\r
6097 case 0: sprintf(s, "fadd qword ptr %s", modrm_string); break;
\r
6098 case 1: sprintf(s, "fmul qword ptr %s", modrm_string); break;
\r
6099 case 2: sprintf(s, "fcom qword ptr %s", modrm_string); break;
\r
6100 case 3: sprintf(s, "fcomp qword ptr %s", modrm_string); break;
\r
6101 case 4: sprintf(s, "fsub qword ptr %s", modrm_string); break;
\r
6102 case 5: sprintf(s, "fsubr qword ptr %s", modrm_string); break;
\r
6103 case 6: sprintf(s, "fdiv qword ptr %s", modrm_string); break;
\r
6104 case 7: sprintf(s, "fdivr qword ptr %s", modrm_string); break;
\r
6107 switch (op2 & 0x3f)
\r
6109 case 0x00: case 0x01: case 0x02: case 0x03: case 0x04: case 0x05: case 0x06: case 0x07:
\r
6110 sprintf(s, "fadd st(%d),st(0)", op2 & 0x7); break;
\r
6112 case 0x08: case 0x09: case 0x0a: case 0x0b: case 0x0c: case 0x0d: case 0x0e: case 0x0f:
\r
6113 sprintf(s, "fmul st(%d),st(0)", op2 & 0x7); break;
\r
6115 case 0x20: case 0x21: case 0x22: case 0x23: case 0x24: case 0x25: case 0x26: case 0x27:
\r
6116 sprintf(s, "fsubr st(%d),st(0)", op2 & 0x7); break;
\r
6118 case 0x28: case 0x29: case 0x2a: case 0x2b: case 0x2c: case 0x2d: case 0x2e: case 0x2f:
\r
6119 sprintf(s, "fsub st(%d),st(0)", op2 & 0x7); break;
\r
6121 case 0x30: case 0x31: case 0x32: case 0x33: case 0x34: case 0x35: case 0x36: case 0x37:
\r
6122 sprintf(s, "fdivr st(%d),st(0)", op2 & 0x7); break;
\r
6124 case 0x38: case 0x39: case 0x3a: case 0x3b: case 0x3c: case 0x3d: case 0x3e: case 0x3f:
\r
6125 sprintf(s, "fdiv st(%d),st(0)", op2 & 0x7); break;
\r
6127 default: sprintf(s, "??? (FPU)"); break;
\r
6133 case 5: // Group DD
\r
6137 pc--; // adjust fetch pointer, so modrm byte read again
\r
6139 handle_modrm( modrm_string );
\r
6140 switch ((op2 >> 3) & 0x7)
\r
6142 case 0: sprintf(s, "fld qword ptr %s", modrm_string); break;
\r
6143 case 1: sprintf(s, "??? (FPU)"); break;
\r
6144 case 2: sprintf(s, "fst qword ptr %s", modrm_string); break;
\r
6145 case 3: sprintf(s, "fstp qword ptr %s", modrm_string); break;
\r
6146 case 4: sprintf(s, "frstor %s", modrm_string); break;
\r
6147 case 5: sprintf(s, "??? (FPU)"); break;
\r
6148 case 6: sprintf(s, "fsave %s", modrm_string); break;
\r
6149 case 7: sprintf(s, "fstsw word ptr %s", modrm_string); break;
\r
6152 switch (op2 & 0x3f)
\r
6154 case 0x00: case 0x01: case 0x02: case 0x03: case 0x04: case 0x05: case 0x06: case 0x07:
\r
6155 sprintf(s, "ffree st(%d)", op2 & 0x7); break;
\r
6157 case 0x10: case 0x11: case 0x12: case 0x13: case 0x14: case 0x15: case 0x16: case 0x17:
\r
6158 sprintf(s, "fst st(%d)", op2 & 0x7); break;
\r
6160 case 0x18: case 0x19: case 0x1a: case 0x1b: case 0x1c: case 0x1d: case 0x1e: case 0x1f:
\r
6161 sprintf(s, "fstp st(%d)", op2 & 0x7); break;
\r
6163 case 0x20: case 0x21: case 0x22: case 0x23: case 0x24: case 0x25: case 0x26: case 0x27:
\r
6164 sprintf(s, "fucom st(%d), st(0)", op2 & 0x7); break;
\r
6166 case 0x28: case 0x29: case 0x2a: case 0x2b: case 0x2c: case 0x2d: case 0x2e: case 0x2f:
\r
6167 sprintf(s, "fucomp st(%d)", op2 & 0x7); break;
\r
6169 default: sprintf(s, "??? (FPU)"); break;
\r
6175 case 6: // Group DE
\r
6179 pc--; // adjust fetch pointer, so modrm byte read again
\r
6181 handle_modrm( modrm_string );
\r
6182 switch ((op2 >> 3) & 0x7)
\r
6184 case 0: sprintf(s, "fiadd word ptr %s", modrm_string); break;
\r
6185 case 1: sprintf(s, "fimul word ptr %s", modrm_string); break;
\r
6186 case 2: sprintf(s, "ficom word ptr %s", modrm_string); break;
\r
6187 case 3: sprintf(s, "ficomp word ptr %s", modrm_string); break;
\r
6188 case 4: sprintf(s, "fisub word ptr %s", modrm_string); break;
\r
6189 case 5: sprintf(s, "fisubr word ptr %s", modrm_string); break;
\r
6190 case 6: sprintf(s, "fidiv word ptr %s", modrm_string); break;
\r
6191 case 7: sprintf(s, "fidivr word ptr %s", modrm_string); break;
\r
6194 switch (op2 & 0x3f)
\r
6196 case 0x00: case 0x01: case 0x02: case 0x03: case 0x04: case 0x05: case 0x06: case 0x07:
\r
6197 sprintf(s, "faddp st(%d)", op2 & 0x7); break;
\r
6199 case 0x08: case 0x09: case 0x0a: case 0x0b: case 0x0c: case 0x0d: case 0x0e: case 0x0f:
\r
6200 sprintf(s, "fmulp st(%d)", op2 & 0x7); break;
\r
6202 case 0x19: sprintf(s, "fcompp"); break;
\r
6204 case 0x20: case 0x21: case 0x22: case 0x23: case 0x24: case 0x25: case 0x26: case 0x27:
\r
6205 sprintf(s, "fsubrp st(%d)", op2 & 0x7); break;
\r
6207 case 0x28: case 0x29: case 0x2a: case 0x2b: case 0x2c: case 0x2d: case 0x2e: case 0x2f:
\r
6208 sprintf(s, "fsubp st(%d)", op2 & 0x7); break;
\r
6210 case 0x30: case 0x31: case 0x32: case 0x33: case 0x34: case 0x35: case 0x36: case 0x37:
\r
6211 sprintf(s, "fdivrp st(%d), st(0)", op2 & 0x7); break;
\r
6213 case 0x38: case 0x39: case 0x3a: case 0x3b: case 0x3c: case 0x3d: case 0x3e: case 0x3f:
\r
6214 sprintf(s, "fdivp st(%d)", op2 & 0x7); break;
\r
6216 default: sprintf(s, "??? (FPU)"); break;
\r
6222 case 7: // Group DF
\r
6226 pc--; // adjust fetch pointer, so modrm byte read again
\r
6228 handle_modrm( modrm_string );
\r
6229 switch ((op2 >> 3) & 0x7)
\r
6231 case 0: sprintf(s, "fild word ptr %s", modrm_string); break;
\r
6232 case 1: sprintf(s, "??? (FPU)"); break;
\r
6233 case 2: sprintf(s, "fist word ptr %s", modrm_string); break;
\r
6234 case 3: sprintf(s, "fistp word ptr %s", modrm_string); break;
\r
6235 case 4: sprintf(s, "fbld %s", modrm_string); break;
\r
6236 case 5: sprintf(s, "fild qword ptr %s", modrm_string); break;
\r
6237 case 6: sprintf(s, "fbstp %s", modrm_string); break;
\r
6238 case 7: sprintf(s, "fistp qword ptr %s", modrm_string); break;
\r
6241 switch (op2 & 0x3f)
\r
6243 case 0x20: sprintf(s, "fstsw aw"); break;
\r
6245 case 0x28: case 0x29: case 0x2a: case 0x2b: case 0x2c: case 0x2d: case 0x2e: case 0x2f:
\r
6246 sprintf(s, "fucomip st(%d)", op2 & 0x7); break;
\r
6248 case 0x30: case 0x31: case 0x32: case 0x33: case 0x34: case 0x35: case 0x36: case 0x37:
\r
6249 sprintf(s, "fcomip st(%d),st(0)", op2 & 0x7); break;
\r
6251 default: sprintf(s, "??? (FPU)"); break;
\r
6259 static void decode_opcode(char *s, const I386_OPCODE *op, UINT8 op1 )
\r
6264 switch( op->flags )
\r
6268 decode_opcode( s, &necv_opcode_table2[op2], op1 );
\r
6275 segment = op->flags;
\r
6277 decode_opcode( s, &necv_opcode_table1[op2], op1 );
\r
6281 s += sprintf( s, "%-8s", op->mnemonic );
\r
6283 decode_opcode( s, &necv_opcode_table1[op2], op1 );
\r
6287 handle_modrm( modrm_string );
\r
6288 for( i=0; i < ARRAY_LENGTH(group_op_table); i++ ) {
\r
6289 if( strcmp(op->mnemonic, group_op_table[i].mnemonic) == 0 )
\r
6291 decode_opcode( s, &group_op_table[i].opcode[MODRM_REG1], op1 );
\r
6295 goto handle_unknown;
\r
6299 handle_fpu( s, op1, op2);
\r
6303 handle_modrm( modrm_string );
\r
6307 s += sprintf( s, "%-8s", op->mnemonic );
\r
6308 dasm_flags = op->dasm_flags;
\r
6310 if( op->param1 != 0 ) {
\r
6311 s = handle_param( s, op->param1 );
\r
6314 if( op->param2 != 0 ) {
\r
6315 s += sprintf( s, "," );
\r
6316 s = handle_param( s, op->param2 );
\r
6319 if( op->param3 != 0 ) {
\r
6320 s += sprintf( s, "," );
\r
6321 s = handle_param( s, op->param3 );
\r
6326 sprintf(s, "???");
\r
6329 int necv_dasm_one(char *buffer, UINT32 eip, const UINT8 *oprom)
\r
6333 opcode_ptr = opcode_ptr_base = oprom;
\r
6340 decode_opcode( buffer, &necv_opcode_table1[op], op );
\r
6341 return (pc-eip) | dasm_flags | DASMFLAG_SUPPORTED;
\r
6344 #define STATE_VERSION 1
\r
6346 void I86::save_state(FILEIO* state_fio)
\r
6348 state_fio->FputUint32(STATE_VERSION);
\r
6349 state_fio->FputInt32(this_device_id);
\r
6351 state_fio->Fwrite(®s, sizeof(regs), 1);
\r
6352 state_fio->FputUint32(pc);
\r
6353 state_fio->FputUint32(prevpc);
\r
6354 state_fio->Fwrite(base, sizeof(base), 1);
\r
6355 state_fio->Fwrite(sregs, sizeof(sregs), 1);
\r
6356 state_fio->FputUint16(flags);
\r
6357 state_fio->FputInt32(AuxVal);
\r
6358 state_fio->FputInt32(OverVal);
\r
6359 state_fio->FputInt32(SignVal);
\r
6360 state_fio->FputInt32(ZeroVal);
\r
6361 state_fio->FputInt32(CarryVal);
\r
6362 state_fio->FputInt32(DirVal);
\r
6363 state_fio->FputUint8(ParityVal);
\r
6364 state_fio->FputUint8(TF);
\r
6365 state_fio->FputUint8(IF);
\r
6366 state_fio->FputUint8(MF);
\r
6367 state_fio->FputInt32(int_state);
\r
6368 state_fio->FputBool(test_state);
\r
6369 state_fio->FputBool(busreq);
\r
6370 state_fio->FputBool(halted);
\r
6371 state_fio->FputInt32(icount);
\r
6372 state_fio->FputInt32(extra_icount);
\r
6373 state_fio->FputBool(seg_prefix);
\r
6374 state_fio->FputUint8(prefix_seg);
\r
6375 state_fio->FputUint32(ea);
\r
6376 state_fio->FputUint16(eo);
\r
6377 state_fio->FputUint8(ea_seg);
\r
6380 bool I86::load_state(FILEIO* state_fio)
\r
6382 if(state_fio->FgetUint32() != STATE_VERSION) {
\r
6385 if(state_fio->FgetInt32() != this_device_id) {
\r
6388 state_fio->Fread(®s, sizeof(regs), 1);
\r
6389 pc = state_fio->FgetUint32();
\r
6390 prevpc = state_fio->FgetUint32();
\r
6391 state_fio->Fread(base, sizeof(base), 1);
\r
6392 state_fio->Fread(sregs, sizeof(sregs), 1);
\r
6393 flags = state_fio->FgetUint16();
\r
6394 AuxVal = state_fio->FgetInt32();
\r
6395 OverVal = state_fio->FgetInt32();
\r
6396 SignVal = state_fio->FgetInt32();
\r
6397 ZeroVal = state_fio->FgetInt32();
\r
6398 CarryVal = state_fio->FgetInt32();
\r
6399 DirVal = state_fio->FgetInt32();
\r
6400 ParityVal = state_fio->FgetUint8();
\r
6401 TF = state_fio->FgetUint8();
\r
6402 IF = state_fio->FgetUint8();
\r
6403 MF = state_fio->FgetUint8();
\r
6404 int_state = state_fio->FgetInt32();
\r
6405 test_state = state_fio->FgetBool();
\r
6406 busreq = state_fio->FgetBool();
\r
6407 halted = state_fio->FgetBool();
\r
6408 icount = state_fio->FgetInt32();
\r
6409 extra_icount = state_fio->FgetInt32();
\r
6410 seg_prefix = state_fio->FgetBool();
\r
6411 prefix_seg = state_fio->FgetUint8();
\r
6412 ea = state_fio->FgetUint32();
\r
6413 eo = state_fio->FgetUint16();
\r
6414 ea_seg = state_fio->FgetUint8();
\r