OSDN Git Service

[VM][EVENT][DEVICE] Add new APIs for recording sound.
[csp-qt/common_source_project-fm7.git] / source / src / vm / libcpu_newdev / i86_base.cpp
1 /*
2         Skelton for retropc emulator
3
4         Origin : MAME 0.142
5         Author : Takeda.Toshiya
6         Date  : 2011.04.23-
7
8         [ i86/v30 ]
9 */
10
11 #if defined(_MSC_VER) && (_MSC_VER >= 1400)
12 #pragma warning( disable : 4146 )
13 #pragma warning( disable : 4996 )
14 #endif
15
16 #include "./i86_base.h"
17 #include "./i86_macros.h"
18 int necv_dasm_one(_TCHAR *buffer, UINT32 eip, const UINT8 *oprom);
19
20 void I86_BASE::initialize()
21 {
22         static const BREGS reg_name[8] = {AL, CL, DL, BL, AH, CH, DH, BH};
23         
24         DEVICE::initialize();
25         for(int i = 0; i < 256; i++) {
26                 Mod_RM.reg.b[i] = reg_name[(i & 0x38) >> 3];
27                 Mod_RM.reg.w[i] = (WREGS)((i & 0x38) >> 3);
28         }
29         for(int i = 0xc0; i < 0x100; i++) {
30                 Mod_RM.RM.w[i] = (WREGS)(i & 7);
31                 Mod_RM.RM.b[i] = (BREGS)reg_name[i & 7];
32         }
33         //memcpy(parity_table, _i80x86_parity_table, sizeof(uint8_t) * 256);
34         timing = _i80x86_timing_tbl_i8086;
35
36         d_mem_stored = d_mem;
37         d_io_stored = d_io;
38 }
39
40 void I86_BASE::reset()
41 {
42         for(int i = 0; i < 8; i++) {
43                 regs.w[i] = 0;
44         }
45         sregs[CS] = 0xf000;
46         sregs[SS] = sregs[DS] = sregs[ES] = 0;
47         
48         base[CS] = SegBase(CS);
49         base[SS] = base[DS] = base[ES] = 0;
50         
51         ea = 0;
52         eo = 0;
53         AuxVal = OverVal = SignVal = ZeroVal = CarryVal = 0;
54         DirVal = 1;
55         ParityVal = TF = IF = MF = 0;
56         
57         icount = extra_icount = 0;
58         int_state = 0;
59         test_state = false;
60         halted = false;
61         
62         pc = 0xffff0 & AMASK;
63         flags = 0;
64         ExpandFlags(flags);
65         seg_prefix = false;
66 }
67
68 int I86_BASE::run(int clock)
69 {
70         /* return now if BUSREQ */
71         if(busreq) {
72                 if(clock == -1) {
73                         int passed_icount = max(1, extra_icount);
74                         // this is main cpu, icount is not used
75                         /*icount = */extra_icount = 0;
76                         return passed_icount;
77                 } else {
78                         icount += clock;
79                         int first_icount = icount;
80                         
81                         /* adjust for any interrupts that came in */
82                         icount -= extra_icount;
83                         extra_icount = 0;
84                         
85                         /* if busreq is raised, spin cpu while remained clock */
86                         if(icount > 0) {
87                                 icount = 0;
88                         }
89                         return first_icount - icount;
90                 }
91         }
92         
93         if(clock == -1) {
94                 /* run only one opcode */
95                 icount = -extra_icount;
96                 extra_icount = 0;
97                 run_one_opecode();
98                 return -icount;
99         } else {
100                 icount += clock;
101                 int first_icount = icount;
102                 
103                 /* adjust for any interrupts that came in */
104                 icount -= extra_icount;
105                 extra_icount = 0;
106                 
107                 /* run cpu while given clocks */
108                 while(icount > 0 && !busreq) {
109                         run_one_opecode();
110                 }
111                 /* if busreq is raised, spin cpu while remained clock */
112                 if(icount > 0 && busreq) {
113                         icount = 0;
114                 }
115                 return first_icount - icount;
116         }
117 }
118
119
120 void I86_BASE::run_one_opecode_debugger()
121 {
122 }
123
124
125 void I86_BASE::run_one_opecode()
126 {
127         seg_prefix = false;
128         instruction(FETCHOP);
129         if(int_state & NMI_REQ_BIT) {
130                 if(halted) {
131                         pc++;
132                         halted = false;
133                 }
134                 int_state &= ~NMI_REQ_BIT;
135                 interrupt(NMI_INT_VECTOR);
136         } else if((int_state & INT_REQ_BIT) && IF) {
137                 if(halted) {
138                         pc++;
139                         halted = false;
140                 }
141                 interrupt(-1);
142         }
143         icount -= extra_icount;
144         extra_icount = 0;
145 }
146
147 void I86_BASE::write_signal(int id, uint32_t data, uint32_t mask)
148 {
149         if(id == SIG_CPU_NMI) {
150                 if(data & mask) {
151                         int_state |= NMI_REQ_BIT;
152                 } else {
153                         int_state &= ~NMI_REQ_BIT;
154                 }
155         } else if(id == SIG_CPU_BUSREQ) {
156                 busreq = ((data & mask) != 0);
157         } else if(id == SIG_I86_TEST) {
158                 test_state = ((data & mask) != 0);
159         }
160 }
161
162 void I86_BASE::set_intr_line(bool line, bool pending, uint32_t bit)
163 {
164         if(line) {
165                 int_state |= INT_REQ_BIT;
166         } else {
167                 int_state &= ~INT_REQ_BIT;
168         }
169 }
170
171 //#ifdef USE_DEBUGGER
172 void I86_BASE::write_debug_data8(uint32_t addr, uint32_t data)
173 {
174         int wait;
175         d_mem_stored->write_data8w(addr, data, &wait);
176 }
177
178 uint32_t I86_BASE::read_debug_data8(uint32_t addr)
179 {
180         int wait;
181         return d_mem_stored->read_data8w(addr, &wait);
182 }
183
184 void I86_BASE::write_debug_data16(uint32_t addr, uint32_t data)
185 {
186         int wait;
187         d_mem_stored->write_data16w(addr, data, &wait);
188 }
189
190 uint32_t I86_BASE::read_debug_data16(uint32_t addr)
191 {
192         int wait;
193         return d_mem_stored->read_data16w(addr, &wait);
194 }
195
196 void I86_BASE::write_debug_io8(uint32_t addr, uint32_t data)
197 {
198         int wait;
199         d_io_stored->write_io8w(addr, data, &wait);
200 }
201
202 uint32_t I86_BASE::read_debug_io8(uint32_t addr) {
203         int wait;
204         return d_io_stored->read_io8w(addr, &wait);
205 }
206
207 void I86_BASE::write_debug_io16(uint32_t addr, uint32_t data)
208 {
209         int wait;
210         d_io_stored->write_io16w(addr, data, &wait);
211 }
212
213 uint32_t I86_BASE::read_debug_io16(uint32_t addr) {
214         int wait;
215         return d_io_stored->read_io16w(addr, &wait);
216 }
217
218 bool I86_BASE::write_debug_reg(const _TCHAR *reg, uint32_t data)
219 {
220         if(_tcsicmp(reg, _T("IP")) == 0) {
221                 pc = ((data & 0xffff) + base[CS]) & AMASK;
222         } else if(_tcsicmp(reg, _T("AX")) == 0) {
223                 regs.w[AX] = data;
224         } else if(_tcsicmp(reg, _T("BX")) == 0) {
225                 regs.w[BX] = data;
226         } else if(_tcsicmp(reg, _T("CX")) == 0) {
227                 regs.w[CX] = data;
228         } else if(_tcsicmp(reg, _T("DX")) == 0) {
229                 regs.w[DX] = data;
230         } else if(_tcsicmp(reg, _T("SP")) == 0) {
231                 regs.w[SP] = data;
232         } else if(_tcsicmp(reg, _T("BP")) == 0) {
233                 regs.w[BP] = data;
234         } else if(_tcsicmp(reg, _T("SI")) == 0) {
235                 regs.w[SI] = data;
236         } else if(_tcsicmp(reg, _T("DI")) == 0) {
237                 regs.w[DI] = data;
238         } else if(_tcsicmp(reg, _T("AL")) == 0) {
239                 regs.b[AL] = data;
240         } else if(_tcsicmp(reg, _T("AH")) == 0) {
241                 regs.b[AH] = data;
242         } else if(_tcsicmp(reg, _T("BL")) == 0) {
243                 regs.b[BL] = data;
244         } else if(_tcsicmp(reg, _T("BH")) == 0) {
245                 regs.b[BH] = data;
246         } else if(_tcsicmp(reg, _T("CL")) == 0) {
247                 regs.b[CL] = data;
248         } else if(_tcsicmp(reg, _T("CH")) == 0) {
249                 regs.b[CH] = data;
250         } else if(_tcsicmp(reg, _T("DL")) == 0) {
251                 regs.b[DL] = data;
252         } else if(_tcsicmp(reg, _T("DH")) == 0) {
253                 regs.b[DH] = data;
254         } else {
255                 return false;
256         }
257         return true;
258 }
259
260 void I86_BASE::get_debug_regs_info(_TCHAR *buffer, size_t buffer_len)
261 {
262         my_stprintf_s(buffer, buffer_len,
263         _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]"),
264         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_t)(pc - base[CS]),
265         OF ? _T('O') : _T('-'), DF ? _T('D') : _T('-'), IF ? _T('I') : _T('-'), TF ? _T('T') : _T('-'),
266         SF ? _T('S') : _T('-'), ZF ? _T('Z') : _T('-'), AF ? _T('A') : _T('-'), PF ? _T('P') : _T('-'), CF ? _T('C') : _T('-'));
267 }
268
269 int I86_BASE::debug_dasm(uint32_t pc, _TCHAR *buffer, size_t buffer_len)
270 {
271         UINT32 eip = (UINT32)(uint16_t)(pc - base[CS]);
272         UINT8 ops[16];
273         for(int i = 0; i < 16; i++) {
274                 int wait;
275                 ops[i] = d_mem->read_data8w(pc + i, &wait);
276         }
277         return necv_dasm_one(buffer, eip, ops) & DASMFLAG_LENGTHMASK;
278 }
279 //#endif
280
281 void I86_BASE::interrupt(int int_num)
282 {
283         unsigned dest_seg, dest_off;
284         uint16_t ip = pc - base[CS];
285         
286         if(int_num == -1) {
287                 int_num = d_pic->get_intr_ack() & 0xff;
288                 int_state &= ~INT_REQ_BIT;
289         }
290         dest_off = ReadWord(int_num * 4);
291         dest_seg = ReadWord(int_num * 4 + 2);
292         
293         _pushf();
294         TF = IF = 0;
295         PUSH(sregs[CS]);
296         PUSH(ip);
297         sregs[CS] = (uint16_t)dest_seg;
298         base[CS] = SegBase(CS);
299         pc = (base[CS] + dest_off) & AMASK;
300         icount -= timing.exception;
301 }
302
303 void I86_BASE::trap()
304 {
305         instruction(FETCHOP);
306         interrupt(1);
307 }
308
309 unsigned I86_BASE::GetEA(unsigned ModRM)
310 {
311         switch(ModRM) {
312         case 0x00: case 0x08: case 0x10: case 0x18: case 0x20: case 0x28: case 0x30: case 0x38:
313                 icount -= 7; eo = (uint16_t)(regs.w[BX] + regs.w[SI]); ea_seg = DefaultSeg(DS); ea = DefaultBase(DS) + eo; return ea;
314         case 0x01: case 0x09: case 0x11: case 0x19: case 0x21: case 0x29: case 0x31: case 0x39:
315                 icount -= 8; eo = (uint16_t)(regs.w[BX] + regs.w[DI]); ea_seg = DefaultSeg(DS); ea = DefaultBase(DS) + eo; return ea;
316         case 0x02: case 0x0a: case 0x12: case 0x1a: case 0x22: case 0x2a: case 0x32: case 0x3a:
317                 icount -= 8; eo = (uint16_t)(regs.w[BP] + regs.w[SI]); ea_seg = DefaultSeg(SS); ea = DefaultBase(SS) + eo; return ea;
318         case 0x03: case 0x0b: case 0x13: case 0x1b: case 0x23: case 0x2b: case 0x33: case 0x3b:
319                 icount -= 7; eo = (uint16_t)(regs.w[BP] + regs.w[DI]); ea_seg = DefaultSeg(SS); ea = DefaultBase(SS) + eo; return ea;
320         case 0x04: case 0x0c: case 0x14: case 0x1c: case 0x24: case 0x2c: case 0x34: case 0x3c:
321                 icount -= 5; eo = regs.w[SI]; ea_seg = DefaultSeg(DS); ea = DefaultBase(DS) + eo; return ea;
322         case 0x05: case 0x0d: case 0x15: case 0x1d: case 0x25: case 0x2d: case 0x35: case 0x3d:
323                 icount -= 5; eo = regs.w[DI]; ea_seg = DefaultSeg(DS); ea = DefaultBase(DS) + eo; return ea;
324         case 0x06: case 0x0e: case 0x16: case 0x1e: case 0x26: case 0x2e: case 0x36: case 0x3e:
325                 icount -= 6; eo = FETCHOP; eo += FETCHOP << 8; ea_seg = DefaultSeg(DS); ea = DefaultBase(DS) + eo; return ea;
326         case 0x07: case 0x0f: case 0x17: case 0x1f: case 0x27: case 0x2f: case 0x37: case 0x3f:
327                 icount -= 5; eo = regs.w[BX]; ea_seg = DefaultSeg(DS); ea = DefaultBase(DS) + eo; return ea;
328
329         case 0x40: case 0x48: case 0x50: case 0x58: case 0x60: case 0x68: case 0x70: case 0x78:
330                 icount -= 11; eo = (uint16_t)(regs.w[BX] + regs.w[SI] + (int8_t)FETCHOP); ea_seg = DefaultSeg(DS); ea = DefaultBase(DS) + eo; return ea;
331         case 0x41: case 0x49: case 0x51: case 0x59: case 0x61: case 0x69: case 0x71: case 0x79:
332                 icount -= 12; eo = (uint16_t)(regs.w[BX] + regs.w[DI] + (int8_t)FETCHOP); ea_seg = DefaultSeg(DS); ea = DefaultBase(DS) + eo; return ea;
333         case 0x42: case 0x4a: case 0x52: case 0x5a: case 0x62: case 0x6a: case 0x72: case 0x7a:
334                 icount -= 12; eo = (uint16_t)(regs.w[BP] + regs.w[SI] + (int8_t)FETCHOP); ea_seg = DefaultSeg(SS); ea = DefaultBase(SS) + eo; return ea;
335         case 0x43: case 0x4b: case 0x53: case 0x5b: case 0x63: case 0x6b: case 0x73: case 0x7b:
336                 icount -= 11; eo = (uint16_t)(regs.w[BP] + regs.w[DI] + (int8_t)FETCHOP); ea_seg = DefaultSeg(SS); ea = DefaultBase(SS) + eo; return ea;
337         case 0x44: case 0x4c: case 0x54: case 0x5c: case 0x64: case 0x6c: case 0x74: case 0x7c:
338                 icount -= 9; eo = (uint16_t)(regs.w[SI] + (int8_t)FETCHOP); ea_seg = DefaultSeg(DS); ea = DefaultBase(DS) + eo; return ea;
339         case 0x45: case 0x4d: case 0x55: case 0x5d: case 0x65: case 0x6d: case 0x75: case 0x7d:
340                 icount -= 9; eo = (uint16_t)(regs.w[DI] + (int8_t)FETCHOP); ea_seg = DefaultSeg(DS); ea = DefaultBase(DS) + eo; return ea;
341         case 0x46: case 0x4e: case 0x56: case 0x5e: case 0x66: case 0x6e: case 0x76: case 0x7e:
342                 icount -= 9; eo = (uint16_t)(regs.w[BP] + (int8_t)FETCHOP); ea_seg = DefaultSeg(SS); ea = DefaultBase(SS) + eo; return ea;
343         case 0x47: case 0x4f: case 0x57: case 0x5f: case 0x67: case 0x6f: case 0x77: case 0x7f:
344                 icount -= 9; eo = (uint16_t)(regs.w[BX] + (int8_t)FETCHOP); ea_seg = DefaultSeg(DS); ea = DefaultBase(DS) + eo; return ea;
345
346         case 0x80: case 0x88: case 0x90: case 0x98: case 0xa0: case 0xa8: case 0xb0: case 0xb8:
347                 icount -= 11; eo = FETCHOP; eo += FETCHOP << 8; eo += regs.w[BX] + regs.w[SI]; ea_seg = DefaultSeg(DS); ea = DefaultBase(DS) + (uint16_t)eo; return ea;
348         case 0x81: case 0x89: case 0x91: case 0x99: case 0xa1: case 0xa9: case 0xb1: case 0xb9:
349                 icount -= 12; eo = FETCHOP; eo += FETCHOP << 8; eo += regs.w[BX] + regs.w[DI]; ea_seg = DefaultSeg(DS); ea = DefaultBase(DS) + (uint16_t)eo; return ea;
350         case 0x82: case 0x8a: case 0x92: case 0x9a: case 0xa2: case 0xaa: case 0xb2: case 0xba:
351                 icount -= 12; eo = FETCHOP; eo += FETCHOP << 8; eo += regs.w[BP] + regs.w[SI]; ea_seg = DefaultSeg(SS); ea = DefaultBase(SS) + (uint16_t)eo; return ea;
352         case 0x83: case 0x8b: case 0x93: case 0x9b: case 0xa3: case 0xab: case 0xb3: case 0xbb:
353                 icount -= 11; eo = FETCHOP; eo += FETCHOP << 8; eo += regs.w[BP] + regs.w[DI]; ea_seg = DefaultSeg(DS); ea = DefaultBase(SS) + (uint16_t)eo; return ea;
354         case 0x84: case 0x8c: case 0x94: case 0x9c: case 0xa4: case 0xac: case 0xb4: case 0xbc:
355                 icount -= 9; eo = FETCHOP; eo += FETCHOP << 8; eo += regs.w[SI]; ea_seg = DefaultSeg(DS); ea = DefaultBase(DS) + (uint16_t)eo; return ea;
356         case 0x85: case 0x8d: case 0x95: case 0x9d: case 0xa5: case 0xad: case 0xb5: case 0xbd:
357                 icount -= 9; eo = FETCHOP; eo += FETCHOP << 8; eo += regs.w[DI]; ea_seg = DefaultSeg(DS); ea = DefaultBase(DS) + (uint16_t)eo; return ea;
358         case 0x86: case 0x8e: case 0x96: case 0x9e: case 0xa6: case 0xae: case 0xb6: case 0xbe:
359                 icount -= 9; eo = FETCHOP; eo += FETCHOP << 8; eo += regs.w[BP]; ea_seg = DefaultSeg(SS); ea = DefaultBase(SS) + (uint16_t)eo; return ea;
360         case 0x87: case 0x8f: case 0x97: case 0x9f: case 0xa7: case 0xaf: case 0xb7: case 0xbf:
361                 icount -= 9; eo = FETCHOP; eo += FETCHOP << 8; eo += regs.w[BX]; ea_seg = DefaultSeg(DS); ea = DefaultBase(DS) + (uint16_t)eo; return ea;
362         }
363         return 0;
364 }
365
366 void I86_BASE::rotate_shift_byte(unsigned ModRM, unsigned count)
367 {
368         unsigned src = (unsigned)GetRMByte(ModRM);
369         unsigned dst = src;
370         
371         if(count == 0) {
372                 icount -= (ModRM >= 0xc0) ? timing.rot_reg_base : timing.rot_m8_base;
373         } else if(count == 1) {
374                 icount -= (ModRM >= 0xc0) ? timing.rot_reg_1 : timing.rot_m8_1;
375                 
376                 switch((ModRM >> 3) & 7) {
377                 case 0: /* ROL eb, 1 */
378                         CarryVal = src & 0x80;
379                         dst = (src << 1) + CF;
380                         PutbackRMByte(ModRM, dst);
381                         OverVal = (src ^ dst) & 0x80;
382                         break;
383                 case 1: /* ROR eb, 1 */
384                         CarryVal = src & 0x01;
385                         dst = ((CF << 8) + src) >> 1;
386                         PutbackRMByte(ModRM, dst);
387                         OverVal = (src ^ dst) & 0x80;
388                         break;
389                 case 2: /* RCL eb, 1 */
390                         dst = (src << 1) + CF;
391                         PutbackRMByte(ModRM, dst);
392                         SetCFB(dst);
393                         OverVal = (src ^ dst) & 0x80;
394                         break;
395                 case 3: /* RCR eb, 1 */
396                         dst = ((CF << 8) + src) >> 1;
397                         PutbackRMByte(ModRM, dst);
398                         CarryVal = src & 0x01;
399                         OverVal = (src ^ dst) & 0x80;
400                         break;
401                 case 4: /* SHL eb, 1 */
402                 case 6:
403                         dst = src << 1;
404                         PutbackRMByte(ModRM, dst);
405                         SetCFB(dst);
406                         OverVal = (src ^ dst) & 0x80;
407                         AuxVal = 1;
408                         SetSZPF_Byte(dst);
409                         break;
410                 case 5: /* SHR eb, 1 */
411                         dst = src >> 1;
412                         PutbackRMByte(ModRM, dst);
413                         CarryVal = src & 0x01;
414                         OverVal = src & 0x80;
415                         AuxVal = 1;
416                         SetSZPF_Byte(dst);
417                         break;
418                 case 7: /* SAR eb, 1 */
419                         dst = ((int8_t)src) >> 1;
420                         PutbackRMByte(ModRM, dst);
421                         CarryVal = src & 0x01;
422                         OverVal = 0;
423                         AuxVal = 1;
424                         SetSZPF_Byte(dst);
425                         break;
426 #if defined(_MSC_VER) && (_MSC_VER >= 1200)
427                 default:
428                         __assume(0);
429 #endif
430                 }
431         } else {
432                 icount -= (ModRM >= 0xc0) ? timing.rot_reg_base + timing.rot_reg_bit : timing.rot_m8_base + timing.rot_m8_bit;
433                 
434                 switch((ModRM >> 3) & 7) {
435                 case 0: /* ROL eb, count */
436                         for(; count > 0; count--) {
437                                 CarryVal = dst & 0x80;
438                                 dst = (dst << 1) + CF;
439                         }
440                         PutbackRMByte(ModRM, (uint8_t)dst);
441                         break;
442                 case 1: /* ROR eb, count */
443                         for(; count > 0; count--) {
444                                 CarryVal = dst & 0x01;
445                                 dst = (dst >> 1) + (CF << 7);
446                         }
447                         PutbackRMByte(ModRM, (uint8_t)dst);
448                         break;
449                 case 2: /* RCL eb, count */
450                         for(; count > 0; count--) {
451                                 dst = (dst << 1) + CF;
452                                 SetCFB(dst);
453                         }
454                         PutbackRMByte(ModRM, (uint8_t)dst);
455                         break;
456                 case 3: /* RCR eb, count */
457                         for(; count > 0; count--) {
458                                 dst = (CF << 8) + dst;
459                                 CarryVal = dst & 0x01;
460                                 dst >>= 1;
461                         }
462                         PutbackRMByte(ModRM, (uint8_t)dst);
463                         break;
464                 case 4: /* SHL eb, count */
465                 case 6:
466                         dst <<= count;
467                         SetCFB(dst);
468                         AuxVal = 1;
469                         SetSZPF_Byte(dst);
470                         PutbackRMByte(ModRM, (uint8_t)dst);
471                         break;
472                 case 5: /* SHR eb, count */
473                         dst >>= count - 1;
474                         CarryVal = dst & 0x01;
475                         dst >>= 1;
476                         SetSZPF_Byte(dst);
477                         AuxVal = 1;
478                         PutbackRMByte(ModRM, (uint8_t)dst);
479                         break;
480                 case 7: /* SAR eb, count */
481                         dst = ((int8_t)dst) >> (count - 1);
482                         CarryVal = dst & 0x01;
483                         dst = ((int8_t)((uint8_t)dst)) >> 1;
484                         SetSZPF_Byte(dst);
485                         AuxVal = 1;
486                         PutbackRMByte(ModRM, (uint8_t)dst);
487                         break;
488 #if defined(_MSC_VER) && (_MSC_VER >= 1200)
489                 default:
490                         __assume(0);
491 #endif
492                 }
493         }
494 }
495
496 void I86_BASE::rotate_shift_word(unsigned ModRM, unsigned count)
497 {
498         unsigned src = GetRMWord(ModRM);
499         unsigned dst = src;
500         
501         if(count == 0) {
502                 icount -= (ModRM >= 0xc0) ? timing.rot_reg_base : timing.rot_m16_base;
503         } else if(count == 1) {
504                 icount -= (ModRM >= 0xc0) ? timing.rot_reg_1 : timing.rot_m16_1;
505                 
506                 switch((ModRM >> 3) & 7) {
507                 case 0: /* ROL ew, 1 */
508                         CarryVal = src & 0x8000;
509                         dst = (src << 1) + CF;
510                         PutbackRMWord(ModRM, dst);
511                         OverVal = (src ^ dst) & 0x8000;
512                         break;
513                 case 1: /* ROR ew, 1 */
514                         CarryVal = src & 0x01;
515                         dst = ((CF << 16) + src) >> 1;
516                         PutbackRMWord(ModRM, dst);
517                         OverVal = (src ^ dst) & 0x8000;
518                         break;
519                 case 2: /* RCL ew, 1 */
520                         dst = (src << 1) + CF;
521                         PutbackRMWord(ModRM, dst);
522                         SetCFW(dst);
523                         OverVal = (src ^ dst) & 0x8000;
524                         break;
525                 case 3: /* RCR ew, 1 */
526                         dst = ((CF << 16) + src) >> 1;
527                         PutbackRMWord(ModRM, dst);
528                         CarryVal = src & 0x01;
529                         OverVal = (src ^ dst) & 0x8000;
530                         break;
531                 case 4: /* SHL ew, 1 */
532                 case 6:
533                         dst = src << 1;
534                         PutbackRMWord(ModRM, dst);
535                         SetCFW(dst);
536                         OverVal = (src ^ dst) & 0x8000;
537                         AuxVal = 1;
538                         SetSZPF_Word(dst);
539                         break;
540                 case 5: /* SHR ew, 1 */
541                         dst = src >> 1;
542                         PutbackRMWord(ModRM, dst);
543                         CarryVal = src & 0x01;
544                         OverVal = src & 0x8000;
545                         AuxVal = 1;
546                         SetSZPF_Word(dst);
547                         break;
548                 case 7: /* SAR ew, 1 */
549                         dst = ((int16_t)src) >> 1;
550                         PutbackRMWord(ModRM, dst);
551                         CarryVal = src & 0x01;
552                         OverVal = 0;
553                         AuxVal = 1;
554                         SetSZPF_Word(dst);
555                         break;
556 #if defined(_MSC_VER) && (_MSC_VER >= 1200)
557                 default:
558                         __assume(0);
559 #endif
560                 }
561         } else {
562                 icount -= (ModRM >= 0xc0) ? timing.rot_reg_base + timing.rot_reg_bit : timing.rot_m8_base + timing.rot_m16_bit;
563                 
564                 switch((ModRM >> 3) & 7) {
565                 case 0: /* ROL ew, count */
566                         for(; count > 0; count--) {
567                                 CarryVal = dst & 0x8000;
568                                 dst = (dst << 1) + CF;
569                         }
570                         PutbackRMWord(ModRM, dst);
571                         break;
572                 case 1: /* ROR ew, count */
573                         for(; count > 0; count--) {
574                                 CarryVal = dst & 0x01;
575                                 dst = (dst >> 1) + (CF << 15);
576                         }
577                         PutbackRMWord(ModRM, dst);
578                         break;
579                 case 2: /* RCL ew, count */
580                         for(; count > 0; count--) {
581                                 dst = (dst << 1) + CF;
582                                 SetCFW(dst);
583                         }
584                         PutbackRMWord(ModRM, dst);
585                         break;
586                 case 3: /* RCR ew, count */
587                         for(; count > 0; count--) {
588                                 dst = dst + (CF << 16);
589                                 CarryVal = dst & 0x01;
590                                 dst >>= 1;
591                         }
592                         PutbackRMWord(ModRM, dst);
593                         break;
594                 case 4: /* SHL ew, count */
595                 case 6:
596                         dst <<= count;
597                         SetCFW(dst);
598                         AuxVal = 1;
599                         SetSZPF_Word(dst);
600                         PutbackRMWord(ModRM, dst);
601                         break;
602                 case 5: /* SHR ew, count */
603                         dst >>= count - 1;
604                         CarryVal = dst & 0x01;
605                         dst >>= 1;
606                         SetSZPF_Word(dst);
607                         AuxVal = 1;
608                         PutbackRMWord(ModRM, dst);
609                         break;
610                 case 7: /* SAR ew, count */
611                         dst = ((int16_t)dst) >> (count - 1);
612                         CarryVal = dst & 0x01;
613                         dst = ((int16_t)((uint16_t)dst)) >> 1;
614                         SetSZPF_Word(dst);
615                         AuxVal = 1;
616                         PutbackRMWord(ModRM, dst);
617                         break;
618 #if defined(_MSC_VER) && (_MSC_VER >= 1200)
619                 default:
620                         __assume(0);
621 #endif
622                 }
623         }
624 }
625
626 void I86_BASE::instruction(uint8_t code)
627 {
628         prevpc = pc - 1;
629         
630         switch(code) {
631         case 0x00: _add_br8(); break;
632         case 0x01: _add_wr16(); break;
633         case 0x02: _add_r8b(); break;
634         case 0x03: _add_r16w(); break;
635         case 0x04: _add_ald8(); break;
636         case 0x05: _add_axd16(); break;
637         case 0x06: _push_es(); break;
638         case 0x07: _pop_es(); break;
639         case 0x08: _or_br8(); break;
640         case 0x09: _or_wr16(); break;
641         case 0x0a: _or_r8b(); break;
642         case 0x0b: _or_r16w(); break;
643         case 0x0c: _or_ald8(); break;
644         case 0x0d: _or_axd16(); break;
645         case 0x0e: _push_cs(); break;
646         case 0x0f: _invalid(); break;
647         case 0x10: _adc_br8(); break;
648         case 0x11: _adc_wr16(); break;
649         case 0x12: _adc_r8b(); break;
650         case 0x13: _adc_r16w(); break;
651         case 0x14: _adc_ald8(); break;
652         case 0x15: _adc_axd16(); break;
653         case 0x16: _push_ss(); break;
654         case 0x17: _pop_ss(); break;
655         case 0x18: _sbb_br8(); break;
656         case 0x19: _sbb_wr16(); break;
657         case 0x1a: _sbb_r8b(); break;
658         case 0x1b: _sbb_r16w(); break;
659         case 0x1c: _sbb_ald8(); break;
660         case 0x1d: _sbb_axd16(); break;
661         case 0x1e: _push_ds(); break;
662         case 0x1f: _pop_ds(); break;
663         case 0x20: _and_br8(); break;
664         case 0x21: _and_wr16(); break;
665         case 0x22: _and_r8b(); break;
666         case 0x23: _and_r16w(); break;
667         case 0x24: _and_ald8(); break;
668         case 0x25: _and_axd16(); break;
669         case 0x26: _es(); break;
670         case 0x27: _daa(); break;
671         case 0x28: _sub_br8(); break;
672         case 0x29: _sub_wr16(); break;
673         case 0x2a: _sub_r8b(); break;
674         case 0x2b: _sub_r16w(); break;
675         case 0x2c: _sub_ald8(); break;
676         case 0x2d: _sub_axd16(); break;
677         case 0x2e: _cs(); break;
678         case 0x2f: _das(); break;
679         case 0x30: _xor_br8(); break;
680         case 0x31: _xor_wr16(); break;
681         case 0x32: _xor_r8b(); break;
682         case 0x33: _xor_r16w(); break;
683         case 0x34: _xor_ald8(); break;
684         case 0x35: _xor_axd16(); break;
685         case 0x36: _ss(); break;
686         case 0x37: _aaa(); break;
687         case 0x38: _cmp_br8(); break;
688         case 0x39: _cmp_wr16(); break;
689         case 0x3a: _cmp_r8b(); break;
690         case 0x3b: _cmp_r16w(); break;
691         case 0x3c: _cmp_ald8(); break;
692         case 0x3d: _cmp_axd16(); break;
693         case 0x3e: _ds(); break;
694         case 0x3f: _aas(); break;
695         case 0x40: _inc_ax(); break;
696         case 0x41: _inc_cx(); break;
697         case 0x42: _inc_dx(); break;
698         case 0x43: _inc_bx(); break;
699         case 0x44: _inc_sp(); break;
700         case 0x45: _inc_bp(); break;
701         case 0x46: _inc_si(); break;
702         case 0x47: _inc_di(); break;
703         case 0x48: _dec_ax(); break;
704         case 0x49: _dec_cx(); break;
705         case 0x4a: _dec_dx(); break;
706         case 0x4b: _dec_bx(); break;
707         case 0x4c: _dec_sp(); break;
708         case 0x4d: _dec_bp(); break;
709         case 0x4e: _dec_si(); break;
710         case 0x4f: _dec_di(); break;
711         case 0x50: _push_ax(); break;
712         case 0x51: _push_cx(); break;
713         case 0x52: _push_dx(); break;
714         case 0x53: _push_bx(); break;
715         case 0x54: _push_sp(); break;
716         case 0x55: _push_bp(); break;
717         case 0x56: _push_si(); break;
718         case 0x57: _push_di(); break;
719         case 0x58: _pop_ax(); break;
720         case 0x59: _pop_cx(); break;
721         case 0x5a: _pop_dx(); break;
722         case 0x5b: _pop_bx(); break;
723         case 0x5c: _pop_sp(); break;
724         case 0x5d: _pop_bp(); break;
725         case 0x5e: _pop_si(); break;
726         case 0x5f: _pop_di(); break;
727         case 0x60: _invalid(); break;
728         case 0x61: _invalid(); break;
729         case 0x62: _invalid(); break;
730
731         case 0x63: _invalid(); break;
732         case 0x64: _invalid(); break;
733         case 0x65: _invalid(); break;
734         case 0x66: _invalid(); break;
735         case 0x67: _invalid(); break;
736         case 0x68: _invalid(); break;
737         case 0x69: _invalid(); break;
738         case 0x6a: _invalid(); break;
739         case 0x6b: _invalid(); break;
740         case 0x6c: _invalid(); break;
741         case 0x6d: _invalid(); break;
742         case 0x6e: _invalid(); break;
743         case 0x6f: _invalid(); break;
744         case 0x70: _jo(); break;
745         case 0x71: _jno(); break;
746         case 0x72: _jb(); break;
747         case 0x73: _jnb(); break;
748         case 0x74: _jz(); break;
749         case 0x75: _jnz(); break;
750         case 0x76: _jbe(); break;
751         case 0x77: _jnbe(); break;
752         case 0x78: _js(); break;
753         case 0x79: _jns(); break;
754         case 0x7a: _jp(); break;
755         case 0x7b: _jnp(); break;
756         case 0x7c: _jl(); break;
757         case 0x7d: _jnl(); break;
758         case 0x7e: _jle(); break;
759         case 0x7f: _jnle(); break;
760         case 0x80: _80pre(); break;
761         case 0x81: _81pre(); break;
762         case 0x82: _82pre(); break;
763         case 0x83: _83pre(); break;
764         case 0x84: _test_br8(); break;
765         case 0x85: _test_wr16(); break;
766         case 0x86: _xchg_br8(); break;
767         case 0x87: _xchg_wr16(); break;
768         case 0x88: _mov_br8(); break;
769         case 0x89: _mov_wr16(); break;
770         case 0x8a: _mov_r8b(); break;
771         case 0x8b: _mov_r16w(); break;
772         case 0x8c: _mov_wsreg(); break;
773         case 0x8d: _lea(); break;
774         case 0x8e: _mov_sregw(); break;
775         case 0x8f: _popw(); break;
776         case 0x90: _nop(); break;
777         case 0x91: _xchg_axcx(); break;
778         case 0x92: _xchg_axdx(); break;
779         case 0x93: _xchg_axbx(); break;
780         case 0x94: _xchg_axsp(); break;
781         case 0x95: _xchg_axbp(); break;
782         case 0x96: _xchg_axsi(); break;
783         case 0x97: _xchg_axdi(); break;
784         case 0x98: _cbw(); break;
785         case 0x99: _cwd(); break;
786         case 0x9a: _call_far(); break;
787         case 0x9b: _wait(); break;
788         case 0x9c: _pushf(); break;
789         case 0x9d: _popf(); break;
790         case 0x9e: _sahf(); break;
791         case 0x9f: _lahf(); break;
792         case 0xa0: _mov_aldisp(); break;
793         case 0xa1: _mov_axdisp(); break;
794         case 0xa2: _mov_dispal(); break;
795         case 0xa3: _mov_dispax(); break;
796         case 0xa4: _movsb(); break;
797         case 0xa5: _movsw(); break;
798         case 0xa6: _cmpsb(); break;
799         case 0xa7: _cmpsw(); break;
800         case 0xa8: _test_ald8(); break;
801         case 0xa9: _test_axd16(); break;
802         case 0xaa: _stosb(); break;
803         case 0xab: _stosw(); break;
804         case 0xac: _lodsb(); break;
805         case 0xad: _lodsw(); break;
806         case 0xae: _scasb(); break;
807         case 0xaf: _scasw(); break;
808         case 0xb0: _mov_ald8(); break;
809         case 0xb1: _mov_cld8(); break;
810         case 0xb2: _mov_dld8(); break;
811         case 0xb3: _mov_bld8(); break;
812         case 0xb4: _mov_ahd8(); break;
813         case 0xb5: _mov_chd8(); break;
814         case 0xb6: _mov_dhd8(); break;
815         case 0xb7: _mov_bhd8(); break;
816         case 0xb8: _mov_axd16(); break;
817         case 0xb9: _mov_cxd16(); break;
818         case 0xba: _mov_dxd16(); break;
819         case 0xbb: _mov_bxd16(); break;
820         case 0xbc: _mov_spd16(); break;
821         case 0xbd: _mov_bpd16(); break;
822         case 0xbe: _mov_sid16(); break;
823         case 0xbf: _mov_did16(); break;
824         case 0xc0: _invalid(); break;
825         case 0xc1: _invalid(); break;
826         case 0xc2: _ret_d16(); break;
827         case 0xc3: _ret(); break;
828         case 0xc4: _les_dw(); break;
829         case 0xc5: _lds_dw(); break;
830         case 0xc6: _mov_bd8(); break;
831         case 0xc7: _mov_wd16(); break;
832         case 0xc8: _invalid(); break;
833         case 0xc9: _invalid(); break;
834         case 0xca: _retf_d16(); break;
835         case 0xcb: _retf(); break;
836         case 0xcc: _int3(); break;
837         case 0xcd: _int(); break;
838         case 0xce: _into(); break;
839         case 0xcf: _iret(); break;
840         case 0xd0: _rotshft_b(); break;
841         case 0xd1: _rotshft_w(); break;
842         case 0xd2: _rotshft_bcl(); break;
843         case 0xd3: _rotshft_wcl(); break;
844         case 0xd4: _aam(); break;
845         case 0xd5: _aad(); break;
846         case 0xd6: _invalid(); break;
847         case 0xd7: _xlat(); break;
848         case 0xd8: _escape(); break;
849         case 0xd9: _escape(); break;
850         case 0xda: _escape(); break;
851         case 0xdb: _escape(); break;
852         case 0xdc: _escape(); break;
853         case 0xdd: _escape(); break;
854         case 0xde: _escape(); break;
855         case 0xdf: _escape(); break;
856         case 0xe0: _loopne(); break;
857         case 0xe1: _loope(); break;
858         case 0xe2: _loop(); break;
859         case 0xe3: _jcxz(); break;
860         case 0xe4: _inal(); break;
861         case 0xe5: _inax(); break;
862         case 0xe6: _outal(); break;
863         case 0xe7: _outax(); break;
864         case 0xe8: _call_d16(); break;
865         case 0xe9: _jmp_d16(); break;
866         case 0xea: _jmp_far(); break;
867         case 0xeb: _jmp_d8(); break;
868         case 0xec: _inaldx(); break;
869         case 0xed: _inaxdx(); break;
870         case 0xee: _outdxal(); break;
871         case 0xef: _outdxax(); break;
872         case 0xf0: _lock(); break;
873         case 0xf1: _invalid(); break;
874         case 0xf2: _repne(); break;
875         case 0xf3: _repe(); break;
876         case 0xf4: _hlt(); break;
877         case 0xf5: _cmc(); break;
878         case 0xf6: _f6pre(); break;
879         case 0xf7: _f7pre(); break;
880         case 0xf8: _clc(); break;
881         case 0xf9: _stc(); break;
882         case 0xfa: _cli(); break;
883         case 0xfb: _sti(); break;
884         case 0xfc: _cld(); break;
885         case 0xfd: _std(); break;
886         case 0xfe: _fepre(); break;
887         case 0xff: _ffpre(); break;
888 #if defined(_MSC_VER) && (_MSC_VER >= 1200)
889         default: __assume(0);
890 #endif
891         }
892 }
893
894 void I86_BASE::_repc(int flagval)
895 {
896 }
897
898 //!!
899 void I86_BASE::_call_far()    /* Opcode 0x9a */
900 {
901         unsigned tmp, tmp2;
902         uint16_t ip;
903         
904         tmp = FETCH;
905         tmp += FETCH << 8;
906         
907         tmp2 = FETCH;
908         tmp2 += FETCH << 8;
909         
910         ip = pc - base[CS];
911         PUSH(sregs[CS]);
912         PUSH(ip);
913         sregs[CS] = (uint16_t)tmp2;
914         base[CS] = SegBase(CS);
915         pc = (base[CS] + (uint16_t)tmp) & AMASK;
916         icount -= timing.call_far;
917 }
918
919 void I86_BASE::_int()    /* Opcode 0xcd */
920 {
921         unsigned int_num = FETCH;
922         icount -= timing.int_imm;
923         interrupt(int_num);
924 }
925 void I86_BASE::_aad()    /* Opcode 0xd5 */
926 {
927         unsigned mult = FETCH;
928         icount -= timing.aad;
929         regs.b[AL] = regs.b[AH] * mult + regs.b[AL];
930         regs.b[AH] = 0;
931         SetZF(regs.b[AL]);
932         SetPF(regs.b[AL]);
933         SignVal = 0;
934 }
935 void I86_BASE::_call_d16()    /* Opcode 0xe8 */
936 {
937         uint16_t ip, tmp;
938         
939         FETCHWORD(tmp);
940         ip = pc - base[CS];
941         PUSH(ip);
942         ip += tmp;
943         pc = (ip + base[CS]) & AMASK;
944         icount -= timing.call_near;
945 }
946
947 void I86_BASE::_rep(int flagval)
948 {
949         /* Handles rep- and repnz- prefixes. flagval is the value of ZF for the
950            loop  to continue for CMPS and SCAS instructions. */
951         
952         unsigned next = FETCHOP;
953         unsigned count = regs.w[CX];
954         
955         switch(next) {
956         case 0x26:  /* ES: */
957                 seg_prefix = true;
958                 prefix_seg = ES;
959                 icount -= timing.override;
960                 _rep(flagval);
961                 break;
962         case 0x2e:  /* CS: */
963                 seg_prefix = true;
964                 prefix_seg = CS;
965                 icount -= timing.override;
966                 _rep(flagval);
967                 break;
968         case 0x36:  /* SS: */
969                 seg_prefix = true;
970                 prefix_seg = SS;
971                 icount -= timing.override;
972                 _rep(flagval);
973                 break;
974         case 0x3e:  /* DS: */
975                 seg_prefix = true;
976                 prefix_seg = DS;
977                 icount -= timing.override;
978                 _rep(flagval);
979                 break;
980         case 0xa4:      /* REP MOVSB */
981                 icount -= timing.rep_movs8_base;
982                 for(; count > 0; count--) {
983                         uint8_t tmp;
984                         tmp = GetMemB(DS, regs.w[SI]);
985                         PutMemB(ES, regs.w[DI], tmp);
986                         regs.w[DI] += DirVal;
987                         regs.w[SI] += DirVal;
988                         icount -= timing.rep_movs8_count;
989                 }
990                 regs.w[CX] = count;
991                 break;
992         case 0xa5:  /* REP MOVSW */
993                 icount -= timing.rep_movs16_base;
994                 for(; count > 0; count--) {
995                         uint16_t tmp;
996                         tmp = GetMemW(DS, regs.w[SI]);
997                         PutMemW(ES, regs.w[DI], tmp);
998                         regs.w[DI] += 2 * DirVal;
999                         regs.w[SI] += 2 * DirVal;
1000                         icount -= timing.rep_movs16_count;
1001                 }
1002                 regs.w[CX] = count;
1003                 break;
1004         case 0xa6:  /* REP(N)E CMPSB */
1005                 icount -= timing.rep_cmps8_base;
1006                 for(ZeroVal = !flagval; (ZF == flagval) && (count > 0); count--) {
1007                         unsigned dst, src;
1008                         dst = GetMemB(ES, regs.w[DI]);
1009                         src = GetMemB(DS, regs.w[SI]);
1010                         SUBB(src, dst); /* opposite of the usual convention */
1011                         regs.w[DI] += DirVal;
1012                         regs.w[SI] += DirVal;
1013                         icount -= timing.rep_cmps8_count;
1014                 }
1015                 regs.w[CX] = count;
1016                 break;
1017         case 0xa7:  /* REP(N)E CMPSW */
1018                 icount -= timing.rep_cmps16_base;
1019                 for(ZeroVal = !flagval; (ZF == flagval) && (count > 0); count--) {
1020                         unsigned dst, src;
1021                         dst = GetMemW(ES, regs.w[DI]);
1022                         src = GetMemW(DS, regs.w[SI]);
1023                         SUBW(src, dst); /* opposite of the usual convention */
1024                         regs.w[DI] += 2 * DirVal;
1025                         regs.w[SI] += 2 * DirVal;
1026                         icount -= timing.rep_cmps16_count;
1027                 }
1028                 regs.w[CX] = count;
1029                 break;
1030         case 0xaa:  /* REP STOSB */
1031                 icount -= timing.rep_stos8_base;
1032                 for(; count > 0; count--) {
1033                         PutMemB(ES, regs.w[DI], regs.b[AL]);
1034                         regs.w[DI] += DirVal;
1035                         icount -= timing.rep_stos8_count;
1036                 }
1037                 regs.w[CX] = count;
1038                 break;
1039         case 0xab:  /* REP STOSW */
1040                 icount -= timing.rep_stos16_base;
1041                 for(; count > 0; count--) {
1042                         PutMemW(ES, regs.w[DI], regs.w[AX]);
1043                         regs.w[DI] += 2 * DirVal;
1044                         icount -= timing.rep_stos16_count;
1045                 }
1046                 regs.w[CX] = count;
1047                 break;
1048         case 0xac:  /* REP LODSB */
1049                 icount -= timing.rep_lods8_base;
1050                 for(; count > 0; count--) {
1051                         regs.b[AL] = GetMemB(DS, regs.w[SI]);
1052                         regs.w[SI] += DirVal;
1053                         icount -= timing.rep_lods8_count;
1054                 }
1055                 regs.w[CX] = count;
1056                 break;
1057         case 0xad:  /* REP LODSW */
1058                 icount -= timing.rep_lods16_base;
1059                 for(; count > 0; count--) {
1060                         regs.w[AX] = GetMemW(DS, regs.w[SI]);
1061                         regs.w[SI] += 2 * DirVal;
1062                         icount -= timing.rep_lods16_count;
1063                 }
1064                 regs.w[CX] = count;
1065                 break;
1066         case 0xae:  /* REP(N)E SCASB */
1067                 icount -= timing.rep_scas8_base;
1068                 for(ZeroVal = !flagval; (ZF == flagval) && (count > 0); count--) {
1069                         unsigned src, dst;
1070                         src = GetMemB(ES, regs.w[DI]);
1071                         dst = regs.b[AL];
1072                         SUBB(dst, src);
1073                         regs.w[DI] += DirVal;
1074                         icount -= timing.rep_scas8_count;
1075                 }
1076                 regs.w[CX] = count;
1077                 break;
1078         case 0xaf:  /* REP(N)E SCASW */
1079                 icount -= timing.rep_scas16_base;
1080                 for(ZeroVal = !flagval; (ZF == flagval) && (count > 0); count--) {
1081                         unsigned src, dst;
1082                         src = GetMemW(ES, regs.w[DI]);
1083                         dst = regs.w[AX];
1084                         SUBW(dst, src);
1085                         regs.w[DI] += 2 * DirVal;
1086                         icount -= timing.rep_scas16_count;
1087                 }
1088                 regs.w[CX] = count;
1089                 break;
1090         default:
1091                 instruction(next);
1092         }
1093 }
1094 void I86_BASE::_ffpre()    /* Opcode 0xff */
1095 {
1096         unsigned ModRM = FETCHOP;
1097         unsigned tmp;
1098         unsigned tmp1;
1099         uint16_t ip;
1100         
1101         switch((ModRM >> 3) & 7) {
1102         case 0:  /* INC ew */
1103                 icount -= (ModRM >= 0xc0) ? timing.incdec_r16 : timing.incdec_m16;
1104                 tmp = GetRMWord(ModRM);
1105                 tmp1 = tmp + 1;
1106                 SetOFW_Add(tmp1, tmp, 1);
1107                 SetAF(tmp1, tmp, 1);
1108                 SetSZPF_Word(tmp1);
1109                 PutbackRMWord(ModRM, (uint16_t)tmp1);
1110                 break;
1111         case 1:  /* DEC ew */
1112                 icount -= (ModRM >= 0xc0) ? timing.incdec_r16 : timing.incdec_m16;
1113                 tmp = GetRMWord(ModRM);
1114                 tmp1 = tmp - 1;
1115                 SetOFW_Sub(tmp1, 1, tmp);
1116                 SetAF(tmp1, tmp, 1);
1117                 SetSZPF_Word(tmp1);
1118                 PutbackRMWord(ModRM, (uint16_t)tmp1);
1119                 break;
1120         case 2:  /* CALL ew */
1121                 icount -= (ModRM >= 0xc0) ? timing.call_r16 : timing.call_m16;
1122                 tmp = GetRMWord(ModRM);
1123                 ip = pc - base[CS];
1124                 PUSH(ip);
1125                 pc = (base[CS] + (uint16_t)tmp) & AMASK;
1126                 break;
1127         case 3:  /* CALL FAR ea */
1128                 icount -= timing.call_m32;
1129                 tmp = sregs[CS];        /* need to skip displacements of ea */
1130                 tmp1 = GetRMWord(ModRM);
1131                 ip = pc - base[CS];
1132                 PUSH(tmp);
1133                 PUSH(ip);
1134                 sregs[CS] = GetNextRMWord;
1135                 base[CS] = SegBase(CS);
1136                 pc = (base[CS] + tmp1) & AMASK;
1137                 break;
1138         case 4:  /* JMP ea */
1139                 icount -= (ModRM >= 0xc0) ? timing.jmp_r16 : timing.jmp_m16;
1140                 ip = GetRMWord(ModRM);
1141                 pc = (base[CS] + ip) & AMASK;
1142                 break;
1143         case 5:  /* JMP FAR ea */
1144                 icount -= timing.jmp_m32;
1145                 pc = GetRMWord(ModRM);
1146                 sregs[CS] = GetNextRMWord;
1147                 base[CS] = SegBase(CS);
1148                 pc = (pc + base[CS]) & AMASK;
1149                 break;
1150         case 6:  /* PUSH ea */
1151                 icount -= (ModRM >= 0xc0) ? timing.push_r16 : timing.push_m16;
1152                 tmp = GetRMWord(ModRM);
1153                 PUSH(tmp);
1154                 break;
1155         case 7:  /* invalid ??? */
1156                 icount -= 10;
1157                 break;
1158 #if defined(_MSC_VER) && (_MSC_VER >= 1200)
1159         default:
1160                 __assume(0);
1161 #endif
1162         }
1163 }
1164
1165
1166 /*
1167    NEC V-series Disassembler
1168
1169    Originally Written for i386 by Ville Linde
1170    Converted to NEC-V by Aaron Giles
1171 */
1172
1173 enum
1174 {
1175         PARAM_REG8 = 1,         /* 8-bit register */
1176         PARAM_REG16,            /* 16-bit register */
1177         PARAM_REG2_8,           /* 8-bit register */
1178         PARAM_REG2_16,          /* 16-bit register */
1179         PARAM_RM8,                      /* 8-bit memory or register */
1180         PARAM_RM16,                     /* 16-bit memory or register */
1181         PARAM_RMPTR8,           /* 8-bit memory or register */
1182         PARAM_RMPTR16,          /* 16-bit memory or register */
1183         PARAM_I3,                       /* 3-bit immediate */
1184         PARAM_I4,                       /* 4-bit immediate */
1185         PARAM_I8,                       /* 8-bit signed immediate */
1186         PARAM_I16,                      /* 16-bit signed immediate */
1187         PARAM_UI8,                      /* 8-bit unsigned immediate */
1188         PARAM_IMM,                      /* 16-bit immediate */
1189         PARAM_ADDR,                     /* 16:16 address */
1190         PARAM_REL8,                     /* 8-bit PC-relative displacement */
1191         PARAM_REL16,            /* 16-bit PC-relative displacement */
1192         PARAM_MEM_OFFS,         /* 16-bit mem offset */
1193         PARAM_SREG,                     /* segment register */
1194         PARAM_SFREG,            /* V25/V35 special function register */
1195         PARAM_1,                        /* used by shift/rotate instructions */
1196         PARAM_AL,
1197         PARAM_CL,
1198         PARAM_DL,
1199         PARAM_BL,
1200         PARAM_AH,
1201         PARAM_CH,
1202         PARAM_DH,
1203         PARAM_BH,
1204         PARAM_AW,
1205         PARAM_CW,
1206         PARAM_DW,
1207         PARAM_BW,
1208         PARAM_SP,
1209         PARAM_BP,
1210         PARAM_IX,
1211         PARAM_IY
1212 };
1213
1214 enum
1215 {
1216         MODRM = 1,
1217         GROUP,
1218         FPU,
1219         TWO_BYTE,
1220         PREFIX,
1221         SEG_PS,
1222         SEG_DS0,
1223         SEG_DS1,
1224         SEG_SS
1225 };
1226
1227 struct I386_OPCODE {
1228         _TCHAR mnemonic[32];
1229         UINT32 flags;
1230         UINT32 param1;
1231         UINT32 param2;
1232         UINT32 param3;
1233         offs_t dasm_flags;
1234 };
1235
1236 struct GROUP_OP {
1237         _TCHAR mnemonic[32];
1238         const I386_OPCODE *opcode;
1239 };
1240
1241 static const UINT8 *opcode_ptr;
1242 static const UINT8 *opcode_ptr_base;
1243
1244 static const I386_OPCODE necv_opcode_table1[256] =
1245 {
1246         // 0x00
1247         {_T("add"),                             MODRM,                  PARAM_RM8,                      PARAM_REG8,                     0                               },
1248         {_T("add"),                             MODRM,                  PARAM_RM16,                     PARAM_REG16,            0                               },
1249         {_T("add"),                             MODRM,                  PARAM_REG8,                     PARAM_RM8,                      0                               },
1250         {_T("add"),                             MODRM,                  PARAM_REG16,            PARAM_RM16,                     0                               },
1251         {_T("add"),                             0,                              PARAM_AL,                       PARAM_UI8,                      0                               },
1252         {_T("add"),                             0,                              PARAM_AW,                       PARAM_IMM,                      0                               },
1253         {_T("push    ds1"),             0,                              0,                                      0,                                      0                               },
1254         {_T("pop     ds1"),             0,                              0,                                      0,                                      0                               },
1255         {_T("or"),                              MODRM,                  PARAM_RM8,                      PARAM_REG8,                     0                               },
1256         {_T("or"),                              MODRM,                  PARAM_RM16,                     PARAM_REG16,            0                               },
1257         {_T("or"),                              MODRM,                  PARAM_REG8,                     PARAM_RM8,                      0                               },
1258         {_T("or"),                              MODRM,                  PARAM_REG16,            PARAM_RM16,                     0                               },
1259         {_T("or"),                              0,                              PARAM_AL,                       PARAM_UI8,                      0                               },
1260         {_T("or"),                              0,                              PARAM_AW,                       PARAM_IMM,                      0                               },
1261         {_T("push    ps"),              0,                              0,                                      0,                                      0                               },
1262         {_T("two_byte"),                TWO_BYTE,               0,                                      0,                                      0                               },
1263         // 0x10
1264         {_T("addc"),                    MODRM,                  PARAM_RM8,                      PARAM_REG8,                     0                               },
1265         {_T("addc"),                    MODRM,                  PARAM_RM16,                     PARAM_REG16,            0                               },
1266         {_T("addc"),                    MODRM,                  PARAM_REG8,                     PARAM_RM8,                      0                               },
1267         {_T("addc"),                    MODRM,                  PARAM_REG16,            PARAM_RM16,                     0                               },
1268         {_T("addc"),                    0,                              PARAM_AL,                       PARAM_UI8,                      0                               },
1269         {_T("addc"),                    0,                              PARAM_AW,                       PARAM_IMM,                      0                               },
1270         {_T("push    ss"),              0,                              0,                                      0,                                      0                               },
1271         {_T("pop     ss"),              0,                              0,                                      0,                                      0                               },
1272         {_T("subc"),                    MODRM,                  PARAM_RM8,                      PARAM_REG8,                     0                               },
1273         {_T("subc"),                    MODRM,                  PARAM_RM16,                     PARAM_REG16,            0                               },
1274         {_T("subc"),                    MODRM,                  PARAM_REG8,                     PARAM_RM8,                      0                               },
1275         {_T("subc"),                    MODRM,                  PARAM_REG16,            PARAM_RM16,                     0                               },
1276         {_T("subc"),                    0,                              PARAM_AL,                       PARAM_UI8,                      0                               },
1277         {_T("subc"),                    0,                              PARAM_AW,                       PARAM_IMM,                      0                               },
1278         {_T("push    ds0"),             0,                              0,                                      0,                                      0                               },
1279         {_T("pop     ds0"),             0,                              0,                                      0,                                      0                               },
1280         // 0x20
1281         {_T("and"),                             MODRM,                  PARAM_RM8,                      PARAM_REG8,                     0                               },
1282         {_T("and"),                             MODRM,                  PARAM_RM16,                     PARAM_REG16,            0                               },
1283         {_T("and"),                             MODRM,                  PARAM_REG8,                     PARAM_RM8,                      0                               },
1284         {_T("and"),                             MODRM,                  PARAM_REG16,            PARAM_RM16,                     0                               },
1285         {_T("and"),                             0,                              PARAM_AL,                       PARAM_UI8,                      0                               },
1286         {_T("and"),                             0,                              PARAM_AW,                       PARAM_IMM,                      0                               },
1287         {_T("ds1:"),                    SEG_DS1,                0,                                      0,                                      0                               },
1288         {_T("adj4a"),                   0,                              0,                                      0,                                      0                               },
1289         {_T("sub"),                             MODRM,                  PARAM_RM8,                      PARAM_REG8,                     0                               },
1290         {_T("sub"),                             MODRM,                  PARAM_RM16,                     PARAM_REG16,            0                               },
1291         {_T("sub"),                             MODRM,                  PARAM_REG8,                     PARAM_RM8,                      0                               },
1292         {_T("sub"),                             MODRM,                  PARAM_REG16,            PARAM_RM16,                     0                               },
1293         {_T("sub"),                             0,                              PARAM_AL,                       PARAM_UI8,                      0                               },
1294         {_T("sub"),                             0,                              PARAM_AW,                       PARAM_IMM,                      0                               },
1295         {_T("ps:"),                             SEG_PS,                 0,                                      0,                                      0                               },
1296         {_T("adj4s"),                   0,                              0,                                      0,                                      0                               },
1297         // 0x30
1298         {_T("xor"),                             MODRM,                  PARAM_RM8,                      PARAM_REG8,                     0                               },
1299         {_T("xor"),                             MODRM,                  PARAM_RM16,                     PARAM_REG16,            0                               },
1300         {_T("xor"),                             MODRM,                  PARAM_REG8,                     PARAM_RM8,                      0                               },
1301         {_T("xor"),                             MODRM,                  PARAM_REG16,            PARAM_RM16,                     0                               },
1302         {_T("xor"),                             0,                              PARAM_AL,                       PARAM_UI8,                      0                               },
1303         {_T("xor"),                             0,                              PARAM_AW,                       PARAM_IMM,                      0                               },
1304         {_T("ss:"),                             SEG_SS,                 0,                                      0,                                      0                               },
1305         {_T("adjba"),                   0,                              0,                                      0,                                      0                               },
1306         {_T("cmp"),                             MODRM,                  PARAM_RM8,                      PARAM_REG8,                     0                               },
1307         {_T("cmp"),                             MODRM,                  PARAM_RM16,                     PARAM_REG16,            0                               },
1308         {_T("cmp"),                             MODRM,                  PARAM_REG8,                     PARAM_RM8,                      0                               },
1309         {_T("cmp"),                             MODRM,                  PARAM_REG16,            PARAM_RM16,                     0                               },
1310         {_T("cmp"),                             0,                              PARAM_AL,                       PARAM_UI8,                      0                               },
1311         {_T("cmp"),                             0,                              PARAM_AW,                       PARAM_IMM,                      0                               },
1312         {_T("ds0:"),                    SEG_DS0,                0,                                      0,                                      0                               },
1313         {_T("adjbs"),                   0,                              0,                                      0,                                      0                               },
1314         // 0x40
1315         {_T("inc"),                             0,                              PARAM_AW,                       0,                                      0                               },
1316         {_T("inc"),                             0,                              PARAM_CW,                       0,                                      0                               },
1317         {_T("inc"),                             0,                              PARAM_DW,                       0,                                      0                               },
1318         {_T("inc"),                             0,                              PARAM_BW,                       0,                                      0                               },
1319         {_T("inc"),                             0,                              PARAM_SP,                       0,                                      0                               },
1320         {_T("inc"),                             0,                              PARAM_BP,                       0,                                      0                               },
1321         {_T("inc"),                             0,                              PARAM_IX,                       0,                                      0                               },
1322         {_T("inc"),                             0,                              PARAM_IY,                       0,                                      0                               },
1323         {_T("dec"),                             0,                              PARAM_AW,                       0,                                      0                               },
1324         {_T("dec"),                             0,                              PARAM_CW,                       0,                                      0                               },
1325         {_T("dec"),                             0,                              PARAM_DW,                       0,                                      0                               },
1326         {_T("dec"),                             0,                              PARAM_BW,                       0,                                      0                               },
1327         {_T("dec"),                             0,                              PARAM_SP,                       0,                                      0                               },
1328         {_T("dec"),                             0,                              PARAM_BP,                       0,                                      0                               },
1329         {_T("dec"),                             0,                              PARAM_IX,                       0,                                      0                               },
1330         {_T("dec"),                             0,                              PARAM_IY,                       0,                                      0                               },
1331         // 0x50
1332         {_T("push"),                    0,                              PARAM_AW,                       0,                                      0                               },
1333         {_T("push"),                    0,                              PARAM_CW,                       0,                                      0                               },
1334         {_T("push"),                    0,                              PARAM_DW,                       0,                                      0                               },
1335         {_T("push"),                    0,                              PARAM_BW,                       0,                                      0                               },
1336         {_T("push"),                    0,                              PARAM_SP,                       0,                                      0                               },
1337         {_T("push"),                    0,                              PARAM_BP,                       0,                                      0                               },
1338         {_T("push"),                    0,                              PARAM_IX,                       0,                                      0                               },
1339         {_T("push"),                    0,                              PARAM_IY,                       0,                                      0                               },
1340         {_T("pop"),                             0,                              PARAM_AW,                       0,                                      0                               },
1341         {_T("pop"),                             0,                              PARAM_CW,                       0,                                      0                               },
1342         {_T("pop"),                             0,                              PARAM_DW,                       0,                                      0                               },
1343         {_T("pop"),                             0,                              PARAM_BW,                       0,                                      0                               },
1344         {_T("pop"),                             0,                              PARAM_SP,                       0,                                      0                               },
1345         {_T("pop"),                             0,                              PARAM_BP,                       0,                                      0                               },
1346         {_T("pop"),                             0,                              PARAM_IX,                       0,                                      0                               },
1347         {_T("pop"),                             0,                              PARAM_IY,                       0,                                      0                               },
1348         // 0x60
1349         {_T("push    r"),               0,                              0,                                      0,                                      0                               },
1350         {_T("pop     r"),               0,                              0,                                      0,                                      0                               },
1351         {_T("chkind"),                  MODRM,                  PARAM_REG16,            PARAM_RM16,                     0                               },
1352         {_T("brkn"),                    0,                              PARAM_UI8,                      0,                                      0,                              DASMFLAG_STEP_OVER},    /* V25S/V35S only */
1353         {_T("repnc"),                   PREFIX,                 0,                                      0,                                      0                               },
1354         {_T("repc"),                    PREFIX,                 0,                                      0,                                      0                               },
1355         {_T("fpo2    0"),               0,                              0,                                      0,                                      0                               },      /* for a coprocessor that was never made */
1356         {_T("fpo2    1"),               0,                              0,                                      0,                                      0                               },      /* for a coprocessor that was never made */
1357         {_T("push"),                    0,                              PARAM_IMM,                      0,                                      0                               },
1358         {_T("mul"),                             MODRM,                  PARAM_REG16,            PARAM_RM16,                     PARAM_IMM               },
1359         {_T("push"),                    0,                              PARAM_I8,                       0,                                      0                               },
1360         {_T("mul"),                             MODRM,                  PARAM_REG16,            PARAM_RM16,                     PARAM_I8                },
1361         {_T("inmb"),                    0,                              0,                                      0,                                      0                               },
1362         {_T("inmw"),                    0,                              0,                                      0,                                      0                               },
1363         {_T("outmb"),                   0,                              0,                                      0,                                      0                               },
1364         {_T("outmw"),                   0,                              0,                                      0,                                      0                               },
1365         // 0x70
1366         {_T("bv"),                              0,                              PARAM_REL8,                     0,                                      0                               },
1367         {_T("bnv"),                             0,                              PARAM_REL8,                     0,                                      0                               },
1368         {_T("bc"),                              0,                              PARAM_REL8,                     0,                                      0                               },
1369         {_T("bnc"),                             0,                              PARAM_REL8,                     0,                                      0                               },
1370         {_T("be"),                              0,                              PARAM_REL8,                     0,                                      0                               },
1371         {_T("bne"),                             0,                              PARAM_REL8,                     0,                                      0                               },
1372         {_T("bnh"),                             0,                              PARAM_REL8,                     0,                                      0                               },
1373         {_T("bh"),                              0,                              PARAM_REL8,                     0,                                      0                               },
1374         {_T("bn"),                              0,                              PARAM_REL8,                     0,                                      0                               },
1375         {_T("bp"),                              0,                              PARAM_REL8,                     0,                                      0                               },
1376         {_T("bpe"),                             0,                              PARAM_REL8,                     0,                                      0                               },
1377         {_T("bpo"),                             0,                              PARAM_REL8,                     0,                                      0                               },
1378         {_T("blt"),                             0,                              PARAM_REL8,                     0,                                      0                               },
1379         {_T("bge"),                             0,                              PARAM_REL8,                     0,                                      0                               },
1380         {_T("ble"),                             0,                              PARAM_REL8,                     0,                                      0                               },
1381         {_T("bgt"),                             0,                              PARAM_REL8,                     0,                                      0                               },
1382         // 0x80
1383         {_T("immb"),                    GROUP,                  0,                                      0,                                      0                               },
1384         {_T("immw"),                    GROUP,                  0,                                      0,                                      0                               },
1385         {_T("immb"),                    GROUP,                  0,                                      0,                                      0                               },
1386         {_T("immws"),                   GROUP,                  0,                                      0,                                      0                               },
1387         {_T("test"),                    MODRM,                  PARAM_RM8,                      PARAM_REG8,                     0                               },
1388         {_T("test"),                    MODRM,                  PARAM_RM16,                     PARAM_REG16,            0                               },
1389         {_T("xch"),                             MODRM,                  PARAM_REG8,                     PARAM_RM8,                      0                               },
1390         {_T("xch"),                             MODRM,                  PARAM_REG16,            PARAM_RM16,                     0                               },
1391         {_T("mov"),                             MODRM,                  PARAM_RM8,                      PARAM_REG8,                     0                               },
1392         {_T("mov"),                             MODRM,                  PARAM_RM16,                     PARAM_REG16,            0                               },
1393         {_T("mov"),                             MODRM,                  PARAM_REG8,                     PARAM_RM8,                      0                               },
1394         {_T("mov"),                             MODRM,                  PARAM_REG16,            PARAM_RM16,                     0                               },
1395         {_T("mov"),                             MODRM,                  PARAM_RM16,                     PARAM_SREG,                     0                               },
1396         {_T("ldea"),                    MODRM,                  PARAM_REG16,            PARAM_RM16,                     0                               },
1397         {_T("mov"),                             MODRM,                  PARAM_SREG,                     PARAM_RM16,                     0                               },
1398         {_T("pop"),                             MODRM,                  PARAM_RM16,                     0,                                      0                               },
1399         // 0x90
1400         {_T("nop"),                             0,                              0,                                      0,                                      0                               },
1401         {_T("xch"),                             0,                              PARAM_AW,                       PARAM_CW,                       0                               },
1402         {_T("xch"),                             0,                              PARAM_AW,                       PARAM_DW,                       0                               },
1403         {_T("xch"),                             0,                              PARAM_AW,                       PARAM_BW,                       0                               },
1404         {_T("xch"),                             0,                              PARAM_AW,                       PARAM_SP,                       0                               },
1405         {_T("xch"),                             0,                              PARAM_AW,                       PARAM_BP,                       0                               },
1406         {_T("xch"),                             0,                              PARAM_AW,                       PARAM_IX,                       0                               },
1407         {_T("xch"),                             0,                              PARAM_AW,                       PARAM_IY,                       0                               },
1408         {_T("cvtbw"),                   0,                              0,                                      0,                                      0                               },
1409         {_T("cvtwl"),                   0,                              0,                                      0,                                      0                               },
1410         {_T("call"),                    0,                              PARAM_ADDR,                     0,                                      0,                              DASMFLAG_STEP_OVER},
1411         {_T("poll"),                    0,                              0,                                      0,                                      0                               },
1412         {_T("push    psw"),             0,                              0,                                      0,                                      0                               },
1413         {_T("pop     psw"),             0,                              0,                                      0,                                      0                               },
1414         {_T("mov     psw,ah"),  0,                              0,                                      0,                                      0                               },
1415         {_T("mov     ah,psw"),  0,                              0,                                      0,                                      0                               },
1416         // 0xa0
1417         {_T("mov"),                             0,                              PARAM_AL,                       PARAM_MEM_OFFS,         0                               },
1418         {_T("mov"),                             0,                              PARAM_AW,                       PARAM_MEM_OFFS,         0                               },
1419         {_T("mov"),                             0,                              PARAM_MEM_OFFS,         PARAM_AL,                       0                               },
1420         {_T("mov"),                             0,                              PARAM_MEM_OFFS,         PARAM_AW,                       0                               },
1421         {_T("movbkb"),                  0,                              0,                                      0,                                      0                               },
1422         {_T("movbkw"),                  0,                              0,                                      0,                                      0                               },
1423         {_T("cmpbkb"),                  0,                              0,                                      0,                                      0                               },
1424         {_T("cmpbkw"),                  0,                              0,                                      0,                                      0                               },
1425         {_T("test"),                    0,                              PARAM_AL,                       PARAM_UI8,                      0                               },
1426         {_T("test"),                    0,                              PARAM_AW,                       PARAM_IMM,                      0                               },
1427         {_T("stmb"),                    0,                              0,                                      0,                                      0                               },
1428         {_T("stmw"),                    0,                              0,                                      0,                                      0                               },
1429         {_T("ldmb"),                    0,                              0,                                      0,                                      0                               },
1430         {_T("ldmw"),                    0,                              0,                                      0,                                      0                               },
1431         {_T("cmpmb"),                   0,                              0,                                      0,                                      0                               },
1432         {_T("cmpmw"),                   0,                              0,                                      0,                                      0                               },
1433         // 0xb0
1434         {_T("mov"),                             0,                              PARAM_AL,                       PARAM_UI8,                      0                               },
1435         {_T("mov"),                             0,                              PARAM_CL,                       PARAM_UI8,                      0                               },
1436         {_T("mov"),                             0,                              PARAM_DL,                       PARAM_UI8,                      0                               },
1437         {_T("mov"),                             0,                              PARAM_BL,                       PARAM_UI8,                      0                               },
1438         {_T("mov"),                             0,                              PARAM_AH,                       PARAM_UI8,                      0                               },
1439         {_T("mov"),                             0,                              PARAM_CH,                       PARAM_UI8,                      0                               },
1440         {_T("mov"),                             0,                              PARAM_DH,                       PARAM_UI8,                      0                               },
1441         {_T("mov"),                             0,                              PARAM_BH,                       PARAM_UI8,                      0                               },
1442         {_T("mov"),                             0,                              PARAM_AW,                       PARAM_IMM,                      0                               },
1443         {_T("mov"),                             0,                              PARAM_CW,                       PARAM_IMM,                      0                               },
1444         {_T("mov"),                             0,                              PARAM_DW,                       PARAM_IMM,                      0                               },
1445         {_T("mov"),                             0,                              PARAM_BW,                       PARAM_IMM,                      0                               },
1446         {_T("mov"),                             0,                              PARAM_SP,                       PARAM_IMM,                      0                               },
1447         {_T("mov"),                             0,                              PARAM_BP,                       PARAM_IMM,                      0                               },
1448         {_T("mov"),                             0,                              PARAM_IX,                       PARAM_IMM,                      0                               },
1449         {_T("mov"),                             0,                              PARAM_IY,                       PARAM_IMM,                      0                               },
1450         // 0xc0
1451         {_T("shiftbi"),                 GROUP,                  0,                                      0,                                      0                               },
1452         {_T("shiftwi"),                 GROUP,                  0,                                      0,                                      0                               },
1453         {_T("ret"),                             0,                              PARAM_I16,                      0,                                      0,                              DASMFLAG_STEP_OUT},
1454         {_T("ret"),                             0,                              0,                                      0,                                      0,                              DASMFLAG_STEP_OUT},
1455         {_T("mov     ds1,"),    MODRM,                  PARAM_REG16,            PARAM_RM16,                     0                               },
1456         {_T("mov     ds0,"),    MODRM,                  PARAM_REG16,            PARAM_RM16,                     0                               },
1457         {_T("mov"),                             MODRM,                  PARAM_RMPTR8,           PARAM_UI8,                      0                               },
1458         {_T("mov"),                             MODRM,                  PARAM_RMPTR16,          PARAM_IMM,                      0                               },
1459         {_T("prepare"),                 0,                              PARAM_I16,                      PARAM_UI8,                      0                               },
1460         {_T("dispose"),                 0,                              0,                                      0,                                      0                               },
1461         {_T("retf"),                    0,                              PARAM_I16,                      0,                                      0,                              DASMFLAG_STEP_OUT},
1462         {_T("retf"),                    0,                              0,                                      0,                                      0,                              DASMFLAG_STEP_OUT},
1463         {_T("brk     3"),               0,                              0,                                      0,                                      0,                              DASMFLAG_STEP_OVER},
1464         {_T("brk"),                             0,                              PARAM_UI8,                      0,                                      0,                              DASMFLAG_STEP_OVER},
1465         {_T("brkv"),                    0,                              0,                                      0,                                      0                               },
1466         {_T("reti"),                    0,                              0,                                      0,                                      0,                              DASMFLAG_STEP_OUT},
1467         // 0xd0
1468         {_T("shiftb"),                  GROUP,                  0,                                      0,                                      0                               },
1469         {_T("shiftw"),                  GROUP,                  0,                                      0,                                      0                               },
1470         {_T("shiftbv"),                 GROUP,                  0,                                      0,                                      0                               },
1471         {_T("shiftwv"),                 GROUP,                  0,                                      0,                                      0                               },
1472         {_T("cvtbd"),                   0,                              PARAM_I8,                       0,                                      0                               },
1473         {_T("cvtdb"),                   0,                              PARAM_I8,                       0,                                      0                               },
1474         {_T("???"),                             0,                              0,                                      0,                                      0                               },
1475         {_T("trans"),                   0,                              0,                                      0,                                      0                               },
1476         {_T("escape"),                  FPU,                    0,                                      0,                                      0                               },
1477         {_T("escape"),                  FPU,                    0,                                      0,                                      0                               },
1478         {_T("escape"),                  FPU,                    0,                                      0,                                      0                               },
1479         {_T("escape"),                  FPU,                    0,                                      0,                                      0                               },
1480         {_T("escape"),                  FPU,                    0,                                      0,                                      0                               },
1481         {_T("escape"),                  FPU,                    0,                                      0,                                      0                               },
1482         {_T("escape"),                  FPU,                    0,                                      0,                                      0                               },
1483         {_T("escape"),                  FPU,                    0,                                      0,                                      0                               },
1484         // 0xe0
1485         {_T("dbnzne"),                  0,                              PARAM_REL8,                     0,                                      0,                              DASMFLAG_STEP_OVER},
1486         {_T("dbnze"),                   0,                              PARAM_REL8,                     0,                                      0,                              DASMFLAG_STEP_OVER},
1487         {_T("dbnz"),                    0,                              PARAM_REL8,                     0,                                      0,                              DASMFLAG_STEP_OVER},
1488         {_T("bcwz"),                    0,                              PARAM_REL8,                     0,                                      0                               },
1489         {_T("in"),                              0,                              PARAM_AL,                       PARAM_UI8,                      0                               },
1490         {_T("in"),                              0,                              PARAM_AW,                       PARAM_UI8,                      0                               },
1491         {_T("out"),                             0,                              PARAM_UI8,                      PARAM_AL,                       0                               },
1492         {_T("out"),                             0,                              PARAM_UI8,                      PARAM_AW,                       0                               },
1493         {_T("call"),                    0,                              PARAM_REL16,            0,                                      0,                              DASMFLAG_STEP_OVER},
1494         {_T("br"),                              0,                              PARAM_REL16,            0,                                      0                               },
1495         {_T("br"),                              0,                              PARAM_ADDR,                     0,                                      0                               },
1496         {_T("br"),                              0,                              PARAM_REL8,                     0,                                      0                               },
1497         {_T("in"),                              0,                              PARAM_AL,                       PARAM_DW,                       0                               },
1498         {_T("in"),                              0,                              PARAM_AW,                       PARAM_DW,                       0                               },
1499         {_T("out"),                             0,                              PARAM_DW,                       PARAM_AL,                       0                               },
1500         {_T("out"),                             0,                              PARAM_DW,                       PARAM_AW,                       0                               },
1501         // 0xf0
1502         {_T("buslock"),                 PREFIX,                 0,                                      0,                                      0                               },
1503         {_T("brks"),                    0,                              PARAM_UI8,                      0,                                      0,                              DASMFLAG_STEP_OVER},    /* V25S/V35S only */
1504         {_T("repne"),                   PREFIX,                 0,                                      0,                                      0                               },
1505         {_T("rep"),                             PREFIX,                 0,                                      0,                                      0                               },
1506         {_T("halt"),                    0,                              0,                                      0,                                      0                               },
1507         {_T("not1    cy"),              0,                              0,                                      0,                                      0                               },
1508         {_T("group1b"),                 GROUP,                  0,                                      0,                                      0                               },
1509         {_T("group1w"),                 GROUP,                  0,                                      0,                                      0                               },
1510         {_T("clr1    cy"),              0,                              0,                                      0,                                      0                               },
1511         {_T("set1    cy"),              0,                              0,                                      0,                                      0                               },
1512         {_T("di"),                              0,                              0,                                      0,                                      0                               },
1513         {_T("ei"),                              0,                              0,                                      0,                                      0                               },
1514         {_T("clr1    dir"),             0,                              0,                                      0,                                      0                               },
1515         {_T("set1    dir"),             0,                              0,                                      0,                                      0                               },
1516         {_T("group2b"),                 GROUP,                  0,                                      0,                                      0                               },
1517         {_T("group2w"),                 GROUP,                  0,                                      0,                                      0                               }
1518 };
1519
1520 static const I386_OPCODE necv_opcode_table2[256] =
1521 {
1522         // 0x00
1523         {_T("???"),                             0,                              0,                                      0,                                      0                               },
1524         {_T("???"),                             0,                              0,                                      0,                                      0                               },
1525         {_T("???"),                             0,                              0,                                      0,                                      0                               },
1526         {_T("???"),                             0,                              0,                                      0,                                      0                               },
1527         {_T("???"),                             0,                              0,                                      0,                                      0                               },
1528         {_T("???"),                             0,                              0,                                      0,                                      0                               },
1529         {_T("???"),                             0,                              0,                                      0,                                      0                               },
1530         {_T("???"),                             0,                              0,                                      0,                                      0                               },
1531         {_T("???"),                             0,                              0,                                      0,                                      0                               },
1532         {_T("???"),                             0,                              0,                                      0,                                      0                               },
1533         {_T("???"),                             0,                              0,                                      0,                                      0                               },
1534         {_T("???"),                             0,                              0,                                      0,                                      0                               },
1535         {_T("???"),                             0,                              0,                                      0,                                      0                               },
1536         {_T("???"),                             0,                              0,                                      0,                                      0                               },
1537         {_T("???"),                             0,                              0,                                      0,                                      0                               },
1538         {_T("???"),                             0,                              0,                                      0,                                      0                               },
1539         // 0x10
1540         {_T("test1"),                   MODRM,                  PARAM_RMPTR8,           PARAM_CL,                       0                               },
1541         {_T("test1"),                   MODRM,                  PARAM_RMPTR16,          PARAM_CL,                       0                               },
1542         {_T("clr1"),                    MODRM,                  PARAM_RMPTR8,           PARAM_CL,                       0                               },
1543         {_T("clr1"),                    MODRM,                  PARAM_RMPTR16,          PARAM_CL,                       0                               },
1544         {_T("set1"),                    MODRM,                  PARAM_RMPTR8,           PARAM_CL,                       0                               },
1545         {_T("set1"),                    MODRM,                  PARAM_RMPTR16,          PARAM_CL,                       0                               },
1546         {_T("not1"),                    MODRM,                  PARAM_RMPTR8,           PARAM_CL,                       0                               },
1547         {_T("not1"),                    MODRM,                  PARAM_RMPTR16,          PARAM_CL,                       0                               },
1548         {_T("test1"),                   MODRM,                  PARAM_RMPTR8,           PARAM_I3,                       0                               },
1549         {_T("test1"),                   MODRM,                  PARAM_RMPTR16,          PARAM_I4,                       0                               },
1550         {_T("clr1"),                    MODRM,                  PARAM_RMPTR8,           PARAM_I3,                       0                               },
1551         {_T("clr1"),                    MODRM,                  PARAM_RMPTR16,          PARAM_I4,                       0                               },
1552         {_T("set1"),                    MODRM,                  PARAM_RMPTR8,           PARAM_I3,                       0                               },
1553         {_T("set1"),                    MODRM,                  PARAM_RMPTR16,          PARAM_I4,                       0                               },
1554         {_T("not1"),                    MODRM,                  PARAM_RMPTR8,           PARAM_I3,                       0                               },
1555         {_T("not1"),                    MODRM,                  PARAM_RMPTR16,          PARAM_I4,                       0                               },
1556         // 0x20
1557         {_T("add4s"),                   0,                              0,                                      0,                                      0                               },
1558         {_T("???"),                             0,                              0,                                      0,                                      0                               },
1559         {_T("sub4s"),                   0,                              0,                                      0,                                      0                               },
1560         {_T("???"),                             0,                              0,                                      0,                                      0                               },
1561         {_T("???"),                             0,                              0,                                      0,                                      0                               },
1562         {_T("movspa"),                  0,                              0,                                      0,                                      0                               },      /* V25/V35 only */
1563         {_T("cmp4s"),                   0,                              0,                                      0,                                      0                               },
1564         {_T("???"),                             0,                              0,                                      0,                                      0                               },
1565         {_T("rol4"),                    MODRM,                  PARAM_RMPTR8,           0,                                      0                               },
1566         {_T("???"),                             0,                              0,                                      0,                                      0                               },
1567         {_T("ror4"),                    MODRM,                  PARAM_RMPTR8,           0,                                      0                               },
1568         {_T("???"),                             0,                              0,                                      0,                                      0                               },
1569         {_T("???"),                             0,                              0,                                      0,                                      0                               },
1570         {_T("brkcs"),                   MODRM,                  PARAM_REG2_16,          0,                                      0,                              DASMFLAG_STEP_OVER},    /* V25/V35 only */
1571         {_T("???"),                             0,                              0,                                      0,                                      0                               },
1572         {_T("???"),                             0,                              0,                                      0,                                      0                               },
1573         // 0x30
1574         {_T("???"),                             0,                              0,                                      0,                                      0                               },
1575         {_T("ins"),                             MODRM,                  PARAM_REG2_8,           PARAM_REG8,                     0                               },
1576         {_T("???"),                             0,                              0,                                      0,                                      0                               },
1577         {_T("ext"),                             MODRM,                  PARAM_REG2_8,           PARAM_REG8,                     0                               },
1578         {_T("???"),                             0,                              0,                                      0,                                      0                               },
1579         {_T("???"),                             0,                              0,                                      0,                                      0                               },
1580         {_T("???"),                             0,                              0,                                      0,                                      0                               },
1581         {_T("???"),                             0,                              0,                                      0,                                      0                               },
1582         {_T("???"),                             0,                              0,                                      0,                                      0                               },
1583         {_T("ins"),                             MODRM,                  PARAM_REG2_8,           PARAM_I4,                       0                               },
1584         {_T("???"),                             0,                              0,                                      0,                                      0                               },
1585         {_T("ext"),                             MODRM,                  PARAM_REG2_8,           PARAM_I4,                       0                               },
1586         {_T("???"),                             0,                              0,                                      0,                                      0                               },
1587         {_T("???"),                             0,                              0,                                      0,                                      0                               },
1588         {_T("???"),                             0,                              0,                                      0,                                      0                               },
1589         {_T("???"),                             0,                              0,                                      0,                                      0                               },
1590         // 0x40
1591         {_T("???"),                             0,                              0,                                      0,                                      0                               },
1592         {_T("???"),                             0,                              0,                                      0,                                      0                               },
1593         {_T("???"),                             0,                              0,                                      0,                                      0                               },
1594         {_T("???"),                             0,                              0,                                      0,                                      0                               },
1595         {_T("???"),                             0,                              0,                                      0,                                      0                               },
1596         {_T("???"),                             0,                              0,                                      0,                                      0                               },
1597         {_T("???"),                             0,                              0,                                      0,                                      0                               },
1598         {_T("???"),                             0,                              0,                                      0,                                      0                               },
1599         {_T("???"),                             0,                              0,                                      0,                                      0                               },
1600         {_T("???"),                             0,                              0,                                      0,                                      0                               },
1601         {_T("???"),                             0,                              0,                                      0,                                      0                               },
1602         {_T("???"),                             0,                              0,                                      0,                                      0                               },
1603         {_T("???"),                             0,                              0,                                      0,                                      0                               },
1604         {_T("???"),                             0,                              0,                                      0,                                      0                               },
1605         {_T("???"),                             0,                              0,                                      0,                                      0                               },
1606         {_T("???"),                             0,                              0,                                      0,                                      0                               },
1607         // 0x50
1608         {_T("???"),                             0,                              0,                                      0,                                      0                               },
1609         {_T("???"),                             0,                              0,                                      0,                                      0                               },
1610         {_T("???"),                             0,                              0,                                      0,                                      0                               },
1611         {_T("???"),                             0,                              0,                                      0,                                      0                               },
1612         {_T("???"),                             0,                              0,                                      0,                                      0                               },
1613         {_T("???"),                             0,                              0,                                      0,                                      0                               },
1614         {_T("???"),                             0,                              0,                                      0,                                      0                               },
1615         {_T("???"),                             0,                              0,                                      0,                                      0                               },
1616         {_T("???"),                             0,                              0,                                      0,                                      0                               },
1617         {_T("???"),                             0,                              0,                                      0,                                      0                               },
1618         {_T("???"),                             0,                              0,                                      0,                                      0                               },
1619         {_T("???"),                             0,                              0,                                      0,                                      0                               },
1620         {_T("???"),                             0,                              0,                                      0,                                      0                               },
1621         {_T("???"),                             0,                              0,                                      0,                                      0                               },
1622         {_T("???"),                             0,                              0,                                      0,                                      0                               },
1623         {_T("???"),                             0,                              0,                                      0,                                      0                               },
1624         // 0x60
1625         {_T("???"),                             0,                              0,                                      0,                                      0                               },
1626         {_T("???"),                             0,                              0,                                      0,                                      0                               },
1627         {_T("???"),                             0,                              0,                                      0,                                      0                               },
1628         {_T("???"),                             0,                              0,                                      0,                                      0                               },
1629         {_T("???"),                             0,                              0,                                      0,                                      0                               },
1630         {_T("???"),                             0,                              0,                                      0,                                      0                               },
1631         {_T("???"),                             0,                              0,                                      0,                                      0                               },
1632         {_T("???"),                             0,                              0,                                      0,                                      0                               },
1633         {_T("???"),                             0,                              0,                                      0,                                      0                               },
1634         {_T("???"),                             0,                              0,                                      0,                                      0                               },
1635         {_T("???"),                             0,                              0,                                      0,                                      0                               },
1636         {_T("???"),                             0,                              0,                                      0,                                      0                               },
1637         {_T("???"),                             0,                              0,                                      0,                                      0                               },
1638         {_T("???"),                             0,                              0,                                      0,                                      0                               },
1639         {_T("???"),                             0,                              0,                                      0,                                      0                               },
1640         {_T("???"),                             0,                              0,                                      0,                                      0                               },
1641         // 0x70
1642         {_T("???"),                             0,                              0,                                      0,                                      0                               },
1643         {_T("???"),                             0,                              0,                                      0,                                      0                               },
1644         {_T("???"),                             0,                              0,                                      0,                                      0                               },
1645         {_T("???"),                             0,                              0,                                      0,                                      0                               },
1646         {_T("???"),                             0,                              0,                                      0,                                      0                               },
1647         {_T("???"),                             0,                              0,                                      0,                                      0                               },
1648         {_T("???"),                             0,                              0,                                      0,                                      0                               },
1649         {_T("???"),                             0,                              0,                                      0,                                      0                               },
1650         {_T("???"),                             0,                              0,                                      0,                                      0                               },
1651         {_T("???"),                             0,                              0,                                      0,                                      0                               },
1652         {_T("???"),                             0,                              0,                                      0,                                      0                               },
1653         {_T("???"),                             0,                              0,                                      0,                                      0                               },
1654         {_T("???"),                             0,                              0,                                      0,                                      0                               },
1655         {_T("???"),                             0,                              0,                                      0,                                      0                               },
1656         {_T("???"),                             0,                              0,                                      0,                                      0                               },
1657         {_T("???"),                             0,                              0,                                      0,                                      0                               },
1658         // 0x80
1659         {_T("???"),                             0,                              0,                                      0,                                      0                               },
1660         {_T("???"),                             0,                              0,                                      0,                                      0                               },
1661         {_T("???"),                             0,                              0,                                      0,                                      0                               },
1662         {_T("???"),                             0,                              0,                                      0,                                      0                               },
1663         {_T("???"),                             0,                              0,                                      0,                                      0                               },
1664         {_T("???"),                             0,                              0,                                      0,                                      0                               },
1665         {_T("???"),                             0,                              0,                                      0,                                      0                               },
1666         {_T("???"),                             0,                              0,                                      0,                                      0                               },
1667         {_T("???"),                             0,                              0,                                      0,                                      0                               },
1668         {_T("???"),                             0,                              0,                                      0,                                      0                               },
1669         {_T("???"),                             0,                              0,                                      0,                                      0                               },
1670         {_T("???"),                             0,                              0,                                      0,                                      0                               },
1671         {_T("???"),                             0,                              0,                                      0,                                      0                               },
1672         {_T("???"),                             0,                              0,                                      0,                                      0                               },
1673         {_T("???"),                             0,                              0,                                      0,                                      0                               },
1674         {_T("???"),                             0,                              0,                                      0,                                      0                               },
1675         // 0x90
1676         {_T("???"),                             0,                              0,                                      0,                                      0                               },
1677         {_T("retrbi"),                  0,                              0,                                      0,                                      0                               },      /* V25/V35 only */
1678         {_T("fint"),                    0,                              0,                                      0,                                      0                               },      /* V25/V35 only */
1679         {_T("???"),                             0,                              0,                                      0,                                      0                               },
1680         {_T("tsksw"),                   MODRM,                  PARAM_REG2_16,          0,                                      0                               },      /* V25/V35 only */
1681         {_T("movspb"),                  MODRM,                  PARAM_REG2_16,          0,                                      0                               },      /* V25/V35 only */
1682         {_T("???"),                             0,                              0,                                      0,                                      0                               },
1683         {_T("???"),                             0,                              0,                                      0,                                      0                               },
1684         {_T("???"),                             0,                              0,                                      0,                                      0                               },
1685         {_T("???"),                             0,                              0,                                      0,                                      0                               },
1686         {_T("???"),                             0,                              0,                                      0,                                      0                               },
1687         {_T("???"),                             0,                              0,                                      0,                                      0                               },
1688         {_T("btclr"),                   0,                              PARAM_SFREG,            PARAM_I3,                       PARAM_REL8              },      /* V25/V35 only */
1689         {_T("???"),                             0,                              0,                                      0,                                      0                               },
1690         {_T("stop"),                    0,                              0,                                      0,                                      0                               },      /* V25/V35 only */
1691         {_T("???"),                             0,                              0,                                      0,                                      0                               },
1692         // 0xa0
1693         {_T("???"),                             0,                              0,                                      0,                                      0                               },
1694         {_T("???"),                             0,                              0,                                      0,                                      0                               },
1695         {_T("???"),                             0,                              0,                                      0,                                      0                               },
1696         {_T("???"),                             0,                              0,                                      0,                                      0                               },
1697         {_T("???"),                             0,                              0,                                      0,                                      0                               },
1698         {_T("???"),                             0,                              0,                                      0,                                      0                               },
1699         {_T("???"),                             0,                              0,                                      0,                                      0                               },
1700         {_T("???"),                             0,                              0,                                      0,                                      0                               },
1701         {_T("???"),                             0,                              0,                                      0,                                      0                               },
1702         {_T("???"),                             0,                              0,                                      0,                                      0                               },
1703         {_T("???"),                             0,                              0,                                      0,                                      0                               },
1704         {_T("???"),                             0,                              0,                                      0,                                      0                               },
1705         {_T("???"),                             0,                              0,                                      0,                                      0                               },
1706         {_T("???"),                             0,                              0,                                      0,                                      0                               },
1707         {_T("???"),                             0,                              0,                                      0,                                      0                               },
1708         {_T("???"),                             0,                              0,                                      0,                                      0                               },
1709         // 0xb0
1710         {_T("???"),                             0,                              0,                                      0,                                      0                               },
1711         {_T("???"),                             0,                              0,                                      0,                                      0                               },
1712         {_T("???"),                             0,                              0,                                      0,                                      0                               },
1713         {_T("???"),                             0,                              0,                                      0,                                      0                               },
1714         {_T("???"),                             0,                              0,                                      0,                                      0                               },
1715         {_T("???"),                             0,                              0,                                      0,                                      0                               },
1716         {_T("???"),                             0,                              0,                                      0,                                      0                               },
1717         {_T("???"),                             0,                              0,                                      0,                                      0                               },
1718         {_T("???"),                             0,                              0,                                      0,                                      0                               },
1719         {_T("???"),                             0,                              0,                                      0,                                      0                               },
1720         {_T("???"),                             0,                              0,                                      0,                                      0                               },
1721         {_T("???"),                             0,                              0,                                      0,                                      0                               },
1722         {_T("???"),                             0,                              0,                                      0,                                      0                               },
1723         {_T("???"),                             0,                              0,                                      0,                                      0                               },
1724         {_T("???"),                             0,                              0,                                      0,                                      0                               },
1725         {_T("???"),                             0,                              0,                                      0,                                      0                               },
1726         // 0xc0
1727         {_T("???"),                             0,                              0,                                      0,                                      0                               },
1728         {_T("???"),                             0,                              0,                                      0,                                      0                               },
1729         {_T("???"),                             0,                              0,                                      0,                                      0                               },
1730         {_T("???"),                             0,                              0,                                      0,                                      0                               },
1731         {_T("???"),                             0,                              0,                                      0,                                      0                               },
1732         {_T("???"),                             0,                              0,                                      0,                                      0                               },
1733         {_T("???"),                             0,                              0,                                      0,                                      0                               },
1734         {_T("???"),                             0,                              0,                                      0,                                      0                               },
1735         {_T("???"),                             0,                              0,                                      0,                                      0                               },
1736         {_T("???"),                             0,                              0,                                      0,                                      0                               },
1737         {_T("???"),                             0,                              0,                                      0,                                      0                               },
1738         {_T("???"),                             0,                              0,                                      0,                                      0                               },
1739         {_T("???"),                             0,                              0,                                      0,                                      0                               },
1740         {_T("???"),                             0,                              0,                                      0,                                      0                               },
1741         {_T("???"),                             0,                              0,                                      0,                                      0                               },
1742         {_T("???"),                             0,                              0,                                      0,                                      0                               },
1743         // 0xd0
1744         {_T("???"),                             0,                              0,                                      0,                                      0                               },
1745         {_T("???"),                             0,                              0,                                      0,                                      0                               },
1746         {_T("???"),                             0,                              0,                                      0,                                      0                               },
1747         {_T("???"),                             0,                              0,                                      0,                                      0                               },
1748         {_T("???"),                             0,                              0,                                      0,                                      0                               },
1749         {_T("???"),                             0,                              0,                                      0,                                      0                               },
1750         {_T("???"),                             0,                              0,                                      0,                                      0                               },
1751         {_T("???"),                             0,                              0,                                      0,                                      0                               },
1752         {_T("???"),                             0,                              0,                                      0,                                      0                               },
1753         {_T("???"),                             0,                              0,                                      0,                                      0                               },
1754         {_T("???"),                             0,                              0,                                      0,                                      0                               },
1755         {_T("???"),                             0,                              0,                                      0,                                      0                               },
1756         {_T("???"),                             0,                              0,                                      0,                                      0                               },
1757         {_T("???"),                             0,                              0,                                      0,                                      0                               },
1758         {_T("???"),                             0,                              0,                                      0,                                      0                               },
1759         {_T("???"),                             0,                              0,                                      0,                                      0                               },
1760         // 0xe0
1761         {_T("brkxa"),                   0,                              PARAM_UI8,                      0,                                      0                               },      /* V33,53 only */
1762         {_T("???"),                             0,                              0,                                      0,                                      0                               },
1763         {_T("???"),                             0,                              0,                                      0,                                      0                               },
1764         {_T("???"),                             0,                              0,                                      0,                                      0                               },
1765         {_T("???"),                             0,                              0,                                      0,                                      0                               },
1766         {_T("???"),                             0,                              0,                                      0,                                      0                               },
1767         {_T("???"),                             0,                              0,                                      0,                                      0                               },
1768         {_T("???"),                             0,                              0,                                      0,                                      0                               },
1769         {_T("???"),                             0,                              0,                                      0,                                      0                               },
1770         {_T("???"),                             0,                              0,                                      0,                                      0                               },
1771         {_T("???"),                             0,                              0,                                      0,                                      0                               },
1772         {_T("???"),                             0,                              0,                                      0,                                      0                               },
1773         {_T("???"),                             0,                              0,                                      0,                                      0                               },
1774         {_T("???"),                             0,                              0,                                      0,                                      0                               },
1775         {_T("???"),                             0,                              0,                                      0,                                      0                               },
1776         {_T("???"),                             0,                              0,                                      0,                                      0                               },
1777         // 0xf0
1778         {_T("retxa"),                   0,                              PARAM_UI8,                      0,                                      0                               },      /* V33,53 only */
1779         {_T("???"),                             0,                              0,                                      0,                                      0                               },
1780         {_T("???"),                             0,                              0,                                      0,                                      0                               },
1781         {_T("???"),                             0,                              0,                                      0,                                      0                               },
1782         {_T("???"),                             0,                              0,                                      0,                                      0                               },
1783         {_T("???"),                             0,                              0,                                      0,                                      0                               },
1784         {_T("???"),                             0,                              0,                                      0,                                      0                               },
1785         {_T("???"),                             0,                              0,                                      0,                                      0                               },
1786         {_T("???"),                             0,                              0,                                      0,                                      0                               },
1787         {_T("???"),                             0,                              0,                                      0,                                      0                               },
1788         {_T("???"),                             0,                              0,                                      0,                                      0                               },
1789         {_T("???"),                             0,                              0,                                      0,                                      0                               },
1790         {_T("???"),                             0,                              0,                                      0,                                      0                               },
1791         {_T("???"),                             0,                              0,                                      0,                                      0                               },
1792         {_T("???"),                             0,                              0,                                      0,                                      0                               },
1793         {_T("brkem"),                   0,                              PARAM_UI8,                      0,                                      0                               }       /* V20,30,40,50 only */
1794 };
1795
1796 static const I386_OPCODE immb_table[8] =
1797 {
1798         {_T("add"),                             0,                              PARAM_RMPTR8,           PARAM_UI8,                      0                               },
1799         {_T("or"),                              0,                              PARAM_RMPTR8,           PARAM_UI8,                      0                               },
1800         {_T("addc"),                    0,                              PARAM_RMPTR8,           PARAM_UI8,                      0                               },
1801         {_T("subc"),                    0,                              PARAM_RMPTR8,           PARAM_UI8,                      0                               },
1802         {_T("and"),                             0,                              PARAM_RMPTR8,           PARAM_UI8,                      0                               },
1803         {_T("sub"),                             0,                              PARAM_RMPTR8,           PARAM_UI8,                      0                               },
1804         {_T("xor"),                             0,                              PARAM_RMPTR8,           PARAM_UI8,                      0                               },
1805         {_T("cmp"),                             0,                              PARAM_RMPTR8,           PARAM_UI8,                      0                               }
1806 };
1807
1808 static const I386_OPCODE immw_table[8] =
1809 {
1810         {_T("add"),                             0,                              PARAM_RMPTR16,          PARAM_IMM,                      0                               },
1811         {_T("or"),                              0,                              PARAM_RMPTR16,          PARAM_IMM,                      0                               },
1812         {_T("addc"),                    0,                              PARAM_RMPTR16,          PARAM_IMM,                      0                               },
1813         {_T("subc"),                    0,                              PARAM_RMPTR16,          PARAM_IMM,                      0                               },
1814         {_T("and"),                             0,                              PARAM_RMPTR16,          PARAM_IMM,                      0                               },
1815         {_T("sub"),                             0,                              PARAM_RMPTR16,          PARAM_IMM,                      0                               },
1816         {_T("xor"),                             0,                              PARAM_RMPTR16,          PARAM_IMM,                      0                               },
1817         {_T("cmp"),                             0,                              PARAM_RMPTR16,          PARAM_IMM,                      0                               }
1818 };
1819
1820 static const I386_OPCODE immws_table[8] =
1821 {
1822         {_T("add"),                             0,                              PARAM_RMPTR16,          PARAM_I8,                       0                               },
1823         {_T("or"),                              0,                              PARAM_RMPTR16,          PARAM_I8,                       0                               },
1824         {_T("addc"),                    0,                              PARAM_RMPTR16,          PARAM_I8,                       0                               },
1825         {_T("subc"),                    0,                              PARAM_RMPTR16,          PARAM_I8,                       0                               },
1826         {_T("and"),                             0,                              PARAM_RMPTR16,          PARAM_I8,                       0                               },
1827         {_T("sub"),                             0,                              PARAM_RMPTR16,          PARAM_I8,                       0                               },
1828         {_T("xor"),                             0,                              PARAM_RMPTR16,          PARAM_I8,                       0                               },
1829         {_T("cmp"),                             0,                              PARAM_RMPTR16,          PARAM_I8,                       0                               }
1830 };
1831
1832 static const I386_OPCODE shiftbi_table[8] =
1833 {
1834         {_T("rol"),                             0,                              PARAM_RMPTR8,           PARAM_I8,                       0                               },
1835         {_T("ror"),                             0,                              PARAM_RMPTR8,           PARAM_I8,                       0                               },
1836         {_T("rolc"),                    0,                              PARAM_RMPTR8,           PARAM_I8,                       0                               },
1837         {_T("rorc"),                    0,                              PARAM_RMPTR8,           PARAM_I8,                       0                               },
1838         {_T("shl"),                             0,                              PARAM_RMPTR8,           PARAM_I8,                       0                               },
1839         {_T("shr"),                             0,                              PARAM_RMPTR8,           PARAM_I8,                       0                               },
1840         {_T("???"),                             0,                              PARAM_RMPTR8,           PARAM_I8,                       0                               },
1841         {_T("shra"),                    0,                              PARAM_RMPTR8,           PARAM_I8,                       0                               }
1842 };
1843
1844 static const I386_OPCODE shiftwi_table[8] =
1845 {
1846         {_T("rol"),                             0,                              PARAM_RMPTR16,          PARAM_I8,                       0                               },
1847         {_T("ror"),                             0,                              PARAM_RMPTR16,          PARAM_I8,                       0                               },
1848         {_T("rolc"),                    0,                              PARAM_RMPTR16,          PARAM_I8,                       0                               },
1849         {_T("rorc"),                    0,                              PARAM_RMPTR16,          PARAM_I8,                       0                               },
1850         {_T("shl"),                             0,                              PARAM_RMPTR16,          PARAM_I8,                       0                               },
1851         {_T("shr"),                             0,                              PARAM_RMPTR16,          PARAM_I8,                       0                               },
1852         {_T("???"),                             0,                              PARAM_RMPTR16,          PARAM_I8,                       0                               },
1853         {_T("shra"),                    0,                              PARAM_RMPTR16,          PARAM_I8,                       0                               }
1854 };
1855
1856 static const I386_OPCODE shiftb_table[8] =
1857 {
1858         {_T("rol"),                             0,                              PARAM_RMPTR8,           PARAM_1,                        0                               },
1859         {_T("ror"),                             0,                              PARAM_RMPTR8,           PARAM_1,                        0                               },
1860         {_T("rolc"),                    0,                              PARAM_RMPTR8,           PARAM_1,                        0                               },
1861         {_T("rorc"),                    0,                              PARAM_RMPTR8,           PARAM_1,                        0                               },
1862         {_T("shl"),                             0,                              PARAM_RMPTR8,           PARAM_1,                        0                               },
1863         {_T("shr"),                             0,                              PARAM_RMPTR8,           PARAM_1,                        0                               },
1864         {_T("???"),                             0,                              PARAM_RMPTR8,           PARAM_1,                        0                               },
1865         {_T("shra"),                    0,                              PARAM_RMPTR8,           PARAM_1,                        0                               }
1866 };
1867
1868 static const I386_OPCODE shiftw_table[8] =
1869 {
1870         {_T("rol"),                             0,                              PARAM_RMPTR16,          PARAM_1,                        0                               },
1871         {_T("ror"),                             0,                              PARAM_RMPTR16,          PARAM_1,                        0                               },
1872         {_T("rolc"),                    0,                              PARAM_RMPTR16,          PARAM_1,                        0                               },
1873         {_T("rorc"),                    0,                              PARAM_RMPTR16,          PARAM_1,                        0                               },
1874         {_T("shl"),                             0,                              PARAM_RMPTR16,          PARAM_1,                        0                               },
1875         {_T("shr"),                             0,                              PARAM_RMPTR16,          PARAM_1,                        0                               },
1876         {_T("???"),                             0,                              PARAM_RMPTR16,          PARAM_1,                        0                               },
1877         {_T("shra"),                    0,                              PARAM_RMPTR16,          PARAM_1,                        0                               }
1878 };
1879
1880 static const I386_OPCODE shiftbv_table[8] =
1881 {
1882         {_T("rol"),                             0,                              PARAM_RMPTR8,           PARAM_CL,                       0                               },
1883         {_T("ror"),                             0,                              PARAM_RMPTR8,           PARAM_CL,                       0                               },
1884         {_T("rolc"),                    0,                              PARAM_RMPTR8,           PARAM_CL,                       0                               },
1885         {_T("rorc"),                    0,                              PARAM_RMPTR8,           PARAM_CL,                       0                               },
1886         {_T("shl"),                             0,                              PARAM_RMPTR8,           PARAM_CL,                       0                               },
1887         {_T("shr"),                             0,                              PARAM_RMPTR8,           PARAM_CL,                       0                               },
1888         {_T("???"),                             0,                              PARAM_RMPTR8,           PARAM_CL,                       0                               },
1889         {_T("shra"),                    0,                              PARAM_RMPTR8,           PARAM_CL,                       0                               }
1890 };
1891
1892 static const I386_OPCODE shiftwv_table[8] =
1893 {
1894         {_T("rol"),                             0,                              PARAM_RMPTR16,          PARAM_CL,                       0                               },
1895         {_T("ror"),                             0,                              PARAM_RMPTR16,          PARAM_CL,                       0                               },
1896         {_T("rolc"),                    0,                              PARAM_RMPTR16,          PARAM_CL,                       0                               },
1897         {_T("rorc"),                    0,                              PARAM_RMPTR16,          PARAM_CL,                       0                               },
1898         {_T("shl"),                             0,                              PARAM_RMPTR16,          PARAM_CL,                       0                               },
1899         {_T("shr"),                             0,                              PARAM_RMPTR16,          PARAM_CL,                       0                               },
1900         {_T("???"),                             0,                              PARAM_RMPTR16,          PARAM_CL,                       0                               },
1901         {_T("shra"),                    0,                              PARAM_RMPTR16,          PARAM_CL,                       0                               }
1902 };
1903
1904 static const I386_OPCODE group1b_table[8] =
1905 {
1906         {_T("test"),                    0,                              PARAM_RMPTR8,           PARAM_UI8,                      0                               },
1907         {_T("???"),                             0,                              0,                                      0,                                      0                               },
1908         {_T("not"),                             0,                              PARAM_RMPTR8,           0,                                      0                               },
1909         {_T("neg"),                             0,                              PARAM_RMPTR8,           0,                                      0                               },
1910         {_T("mulu"),                    0,                              PARAM_RMPTR8,           0,                                      0                               },
1911         {_T("mul"),                             0,                              PARAM_RMPTR8,           0,                                      0                               },
1912         {_T("divu"),                    0,                              PARAM_RMPTR8,           0,                                      0                               },
1913         {_T("div"),                             0,                              PARAM_RMPTR8,           0,                                      0                               }
1914 };
1915
1916 static const I386_OPCODE group1w_table[8] =
1917 {
1918         {_T("test"),                    0,                              PARAM_RMPTR16,          PARAM_IMM,                      0                               },
1919         {_T("???"),                             0,                              0,                                      0,                                      0                               },
1920         {_T("not"),                             0,                              PARAM_RMPTR16,          0,                                      0                               },
1921         {_T("neg"),                             0,                              PARAM_RMPTR16,          0,                                      0                               },
1922         {_T("mulu"),                    0,                              PARAM_RMPTR16,          0,                                      0                               },
1923         {_T("mul"),                             0,                              PARAM_RMPTR16,          0,                                      0                               },
1924         {_T("divu"),                    0,                              PARAM_RMPTR16,          0,                                      0                               },
1925         {_T("div"),                             0,                              PARAM_RMPTR16,          0,                                      0                               }
1926 };
1927
1928 static const I386_OPCODE group2b_table[8] =
1929 {
1930         {_T("inc"),                             0,                              PARAM_RMPTR8,           0,                                      0                               },
1931         {_T("dec"),                             0,                              PARAM_RMPTR8,           0,                                      0                               },
1932         {_T("???"),                             0,                              0,                                      0,                                      0                               },
1933         {_T("???"),                             0,                              0,                                      0,                                      0                               },
1934         {_T("???"),                             0,                              0,                                      0,                                      0                               },
1935         {_T("???"),                             0,                              0,                                      0,                                      0                               },
1936         {_T("???"),                             0,                              0,                                      0,                                      0                               },
1937         {_T("???"),                             0,                              0,                                      0,                                      0                               }
1938 };
1939
1940 static const I386_OPCODE group2w_table[8] =
1941 {
1942         {_T("inc"),                             0,                              PARAM_RMPTR16,          0,                                      0                               },
1943         {_T("dec"),                             0,                              PARAM_RMPTR16,          0,                                      0                               },
1944         {_T("call"),                    0,                              PARAM_RMPTR16,          0,                                      0,                              DASMFLAG_STEP_OVER},
1945         {_T("call    far ptr "),0,                              PARAM_RM16,                     0,                                      0,                              DASMFLAG_STEP_OVER},
1946         {_T("br"),                              0,                              PARAM_RMPTR16,          0,                                      0                               },
1947         {_T("br      far ptr "),0,                              PARAM_RM16,                     0,                                      0                               },
1948         {_T("push"),                    0,                              PARAM_RMPTR16,          0,                                      0                               },
1949         {_T("???"),                             0,                              0,                                      0,                                      0                               }
1950 };
1951
1952 static const GROUP_OP group_op_table[] =
1953 {
1954         {_T("immb"),                            immb_table                              },
1955         {_T("immw"),                            immw_table                              },
1956         {_T("immws"),                           immws_table                             },
1957         {_T("shiftbi"),                 shiftbi_table                   },
1958         {_T("shiftwi"),                 shiftwi_table                   },
1959         {_T("shiftb"),                          shiftb_table                    },
1960         {_T("shiftw"),                          shiftw_table                    },
1961         {_T("shiftbv"),                 shiftbv_table                   },
1962         {_T("shiftwv"),                 shiftwv_table                   },
1963         {_T("group1b"),                 group1b_table                   },
1964         {_T("group1w"),                 group1w_table                   },
1965         {_T("group2b"),                 group2b_table                   },
1966         {_T("group2w"),                 group2w_table                   }
1967 };
1968
1969
1970
1971 static const _TCHAR *const nec_reg[8] = { _T("aw"), _T("cw"), _T("dw"), _T("bw"), _T("sp"), _T("bp"), _T("ix"), _T("iy") };
1972 static const _TCHAR *const nec_reg8[8] = { _T("al"), _T("cl"), _T("dl"), _T("bl"), _T("ah"), _T("ch"), _T("dh"), _T("bh") };
1973 static const _TCHAR *const nec_sreg[8] = { _T("ds1"), _T("ps"), _T("ss"), _T("ds0"), _T("???"), _T("???"), _T("???"), _T("???") };
1974 static const _TCHAR *const nec_sfreg[256] =
1975 {
1976         /* 0x00 */
1977         _T("p0"),       _T("pm0"),      _T("pmc0"),     _T("???"),      _T("???"),      _T("???"),      _T("???"),      _T("???"),
1978         _T("p1"),       _T("pm1"),      _T("pmc1"),     _T("???"),      _T("???"),      _T("???"),      _T("???"),      _T("???"),
1979         /* 0x10 */
1980         _T("p2"),       _T("pm2"),      _T("pmc2"),     _T("???"),      _T("???"),      _T("???"),      _T("???"),      _T("???"),
1981         _T("???"),      _T("???"),      _T("???"),      _T("???"),      _T("???"),      _T("???"),      _T("???"),      _T("???"),
1982         /* 0x20 */
1983         _T("???"),      _T("???"),      _T("???"),      _T("???"),      _T("???"),      _T("???"),      _T("???"),      _T("???"),
1984         _T("???"),      _T("???"),      _T("???"),      _T("???"),      _T("???"),      _T("???"),      _T("???"),      _T("???"),
1985         /* 0x30 */
1986         _T("???"),      _T("???"),      _T("???"),      _T("???"),      _T("???"),      _T("???"),      _T("???"),      _T("???"),
1987         _T("pt"),       _T("???"),      _T("???"),      _T("pmt"),      _T("???"),      _T("???"),      _T("???"),      _T("???"),
1988         /* 0x40 */
1989         _T("intm"),     _T("???"),      _T("???"),      _T("???"),      _T("ems0"),     _T("ems1"),     _T("ems2"),     _T("???"),
1990         _T("???"),      _T("???"),      _T("???"),      _T("???"),      _T("exic0"),    _T("exic1"),    _T("exic2"),    _T("???"),
1991         /* 0x50 */
1992         _T("???"),      _T("???"),      _T("???"),      _T("???"),      _T("???"),      _T("???"),      _T("???"),      _T("???"),
1993         _T("???"),      _T("???"),      _T("???"),      _T("???"),      _T("???"),      _T("???"),      _T("???"),      _T("???"),
1994         /* 0x60 */
1995         _T("rxb0"),     _T("???"),      _T("txb0"),     _T("???"),      _T("???"),      _T("srms0"),    _T("stms0"),    _T("???"),
1996         _T("scm0"),     _T("scc0"),     _T("brg0"),     _T("scs0"),     _T("seic0"),    _T("sric0"),    _T("stic0"),    _T("???"),
1997         /* 0x70 */
1998         _T("rxb1"),     _T("???"),      _T("txb1"),     _T("???"),      _T("???"),      _T("srms1"),    _T("stms1"),    _T("???"),
1999         _T("scm1"),     _T("scc1"),     _T("brg1"),     _T("scs1"),     _T("seic1"),    _T("sric1"),    _T("stic1"),    _T("???"),
2000         /* 0x80 */
2001         _T("tm0"),      _T("???"),      _T("md0"),      _T("???"),      _T("???"),      _T("???"),      _T("???"),      _T("???"),
2002         _T("tm1"),      _T("???"),      _T("md1"),      _T("???"),      _T("???"),      _T("???"),      _T("???"),      _T("???"),
2003         /* 0x90 */
2004         _T("tmc0"),     _T("tmc1"),     _T("???"),      _T("???"),      _T("tmms0"),    _T("tmms1"),    _T("tmms2"),    _T("???"),
2005         _T("???"),      _T("???"),      _T("???"),      _T("???"),      _T("tmic0"),    _T("tmic1"),    _T("tmic2"),    _T("???"),
2006         /* 0xa0 */
2007         _T("dmac0"),    _T("dmam0"),    _T("dmac1"),    _T("dmam1"),    _T("???"),      _T("???"),      _T("???"),      _T("???"),
2008         _T("???"),      _T("???"),      _T("???"),      _T("???"),      _T("dic0"),     _T("dic1"),     _T("???"),      _T("???"),
2009         /* 0xb0 */
2010         _T("???"),      _T("???"),      _T("???"),      _T("???"),      _T("???"),      _T("???"),      _T("???"),      _T("???"),
2011         _T("???"),      _T("???"),      _T("???"),      _T("???"),      _T("???"),      _T("???"),      _T("???"),      _T("???"),
2012         /* 0xc0 */
2013         _T("sar0l"),    _T("sar0m"),    _T("sar0h"),    _T("???"),      _T("dar0l"),    _T("dar0m"),    _T("dar0h"),    _T("???"),
2014         _T("tc0l"),     _T("tc0h"),     _T("???"),      _T("???"),      _T("???"),      _T("???"),      _T("???"),      _T("???"),
2015         /* 0xd0 */
2016         _T("sar1l"),    _T("sar1m"),    _T("sar1h"),    _T("???"),      _T("dar1l"),    _T("dar1m"),    _T("dar1h"),    _T("???"),
2017         _T("tc1l"),     _T("tc1h"),     _T("???"),      _T("???"),      _T("???"),      _T("???"),      _T("???"),      _T("???"),
2018         /* 0xe0 */
2019         _T("stbc"),     _T("rfm"),      _T("???"),      _T("???"),      _T("???"),      _T("???"),      _T("???"),      _T("???"),
2020         _T("wtc"),      _T("???"),      _T("flag"),     _T("prc"),      _T("tbic"),     _T("???"),      _T("???"),      _T("irqs"),
2021         /* 0xf0 */
2022         _T("???"),      _T("???"),      _T("???"),      _T("???"),      _T("???"),      _T("???"),      _T("???"),      _T("???"),
2023         _T("???"),      _T("???"),      _T("???"),      _T("???"),      _T("ispr"),     _T("???"),      _T("???"),      _T("idb")
2024 };
2025
2026 static UINT32 pc;
2027 static UINT8 modrm;
2028 static UINT32 segment;
2029 static offs_t dasm_flags;
2030 static _TCHAR modrm_string[256];
2031
2032 #define MODRM_REG1      ((modrm >> 3) & 0x7)
2033 #define MODRM_REG2      (modrm & 0x7)
2034
2035 #define MAX_LENGTH      8
2036
2037 INLINE UINT8 FETCHD(void)
2038 {
2039         if ((opcode_ptr - opcode_ptr_base) + 1 > MAX_LENGTH)
2040                 return 0xff;
2041         pc++;
2042         return *opcode_ptr++;
2043 }
2044
2045 INLINE UINT16 FETCHD16(void)
2046 {
2047         UINT16 d;
2048         if ((opcode_ptr - opcode_ptr_base) + 2 > MAX_LENGTH)
2049                 return 0xffff;
2050         d = opcode_ptr[0] | (opcode_ptr[1] << 8);
2051         opcode_ptr += 2;
2052         pc += 2;
2053         return d;
2054 }
2055
2056 static _TCHAR *hexstring(UINT32 value, int digits)
2057 {
2058         static _TCHAR buffer[20];
2059         buffer[0] = _T('0');
2060         if (digits) {
2061                 _stprintf(&buffer[1], _T("%0*Xh"), digits, value);
2062         } else {
2063                 _stprintf(&buffer[1], _T("%Xh"), value);
2064         }
2065         return (buffer[1] >= _T('0') && buffer[1] <= _T('9')) ? &buffer[1] : &buffer[0];
2066 }
2067
2068 static _TCHAR *shexstring(UINT32 value, int digits, int always)
2069 {
2070         static _TCHAR buffer[20];
2071         if (value >= 0x80000000) {
2072                 _stprintf(buffer, _T("-%s"), hexstring(-value, digits));
2073         } else if (always) {
2074                 _stprintf(buffer, _T("+%s"), hexstring(value, digits));
2075         } else {
2076                 return hexstring(value, digits);
2077         }
2078         return buffer;
2079 }
2080
2081 static void handle_modrm(_TCHAR* s)
2082 {
2083         INT8 disp8;
2084         INT16 disp16;
2085         UINT8 mod, rm;
2086
2087         modrm = FETCHD();
2088         mod = (modrm >> 6) & 0x3;
2089         rm = (modrm & 0x7);
2090
2091         if( modrm >= 0xc0 )
2092                 return;
2093
2094         switch(segment)
2095         {
2096                 case SEG_PS: s += _stprintf( s, _T("ps:") ); break;
2097                 case SEG_DS0: s += _stprintf( s, _T("ds0:") ); break;
2098                 case SEG_DS1: s += _stprintf( s, _T("ds1:") ); break;
2099                 case SEG_SS: s += _stprintf( s, _T("ss:") ); break;
2100         }
2101
2102         s += _stprintf( s, _T("[") );
2103         switch( rm )
2104         {
2105                 case 0: s += _stprintf( s, _T("bw+ix") ); break;
2106                 case 1: s += _stprintf( s, _T("bw+iy") ); break;
2107                 case 2: s += _stprintf( s, _T("bp+ix") ); break;
2108                 case 3: s += _stprintf( s, _T("bp+iy") ); break;
2109                 case 4: s += _stprintf( s, _T("ix") ); break;
2110                 case 5: s += _stprintf( s, _T("iy") ); break;
2111                 case 6:
2112                         if( mod == 0 ) {
2113                                 disp16 = FETCHD16();
2114                                 s += _stprintf( s, _T("%s"), hexstring((unsigned) (UINT16) disp16, 0) );
2115                         } else {
2116                                 s += _stprintf( s, _T("bp") );
2117                         }
2118                         break;
2119                 case 7: s += _stprintf( s, _T("bw") ); break;
2120         }
2121         if( mod == 1 ) {
2122                 disp8 = FETCHD();
2123                 s += _stprintf( s, _T("%s"), shexstring((INT32)disp8, 0, TRUE) );
2124         } else if( mod == 2 ) {
2125                 disp16 = FETCHD16();
2126                 s += _stprintf( s, _T("%s"), shexstring((INT32)disp16, 0, TRUE) );
2127         }
2128         s += _stprintf( s, _T("]") );
2129 }
2130
2131 static _TCHAR* handle_param(_TCHAR* s, UINT32 param)
2132 {
2133         UINT8 i8;
2134         UINT16 i16;
2135         UINT16 ptr;
2136         UINT32 addr;
2137         INT8 d8;
2138         INT16 d16;
2139
2140         switch(param)
2141         {
2142                 case PARAM_REG8:
2143                         s += _stprintf( s, _T("%s"), nec_reg8[MODRM_REG1] );
2144                         break;
2145
2146                 case PARAM_REG16:
2147                         s += _stprintf( s, _T("%s"), nec_reg[MODRM_REG1] );
2148                         break;
2149
2150                 case PARAM_REG2_8:
2151                         s += _stprintf( s, _T("%s"), nec_reg8[MODRM_REG2] );
2152                         break;
2153
2154                 case PARAM_REG2_16:
2155                         s += _stprintf( s, _T("%s"), nec_reg[MODRM_REG2] );
2156                         break;
2157
2158                 case PARAM_RM8:
2159                 case PARAM_RMPTR8:
2160                         if( modrm >= 0xc0 ) {
2161                                 s += _stprintf( s, _T("%s"), nec_reg8[MODRM_REG2] );
2162                         } else {
2163                                 if (param == PARAM_RMPTR8)
2164                                         s += _stprintf( s, _T("byte ptr ") );
2165                                 s += _stprintf( s, _T("%s"), modrm_string );
2166                         }
2167                         break;
2168
2169                 case PARAM_RM16:
2170                 case PARAM_RMPTR16:
2171                         if( modrm >= 0xc0 ) {
2172                                 s += _stprintf( s, _T("%s"), nec_reg[MODRM_REG2] );
2173                         } else {
2174                                 if (param == PARAM_RMPTR16)
2175                                         s += _stprintf( s, _T("word ptr ") );
2176                                 s += _stprintf( s, _T("%s"), modrm_string );
2177                         }
2178                         break;
2179
2180                 case PARAM_I3:
2181                         i8 = FETCHD();
2182                         s += _stprintf( s, _T("%d"), i8 & 0x07 );
2183                         break;
2184
2185                 case PARAM_I4:
2186                         i8 = FETCHD();
2187                         s += _stprintf( s, _T("%d"), i8 & 0x0f );
2188                         break;
2189
2190                 case PARAM_I8:
2191                         i8 = FETCHD();
2192                         s += _stprintf( s, _T("%s"), shexstring((INT8)i8, 0, FALSE) );
2193                         break;
2194
2195                 case PARAM_I16:
2196                         i16 = FETCHD16();
2197                         s += _stprintf( s, _T("%s"), shexstring((INT16)i16, 0, FALSE) );
2198                         break;
2199
2200                 case PARAM_UI8:
2201                         i8 = FETCHD();
2202                         s += _stprintf( s, _T("%s"), shexstring((UINT8)i8, 0, FALSE) );
2203                         break;
2204
2205                 case PARAM_IMM:
2206                         i16 = FETCHD16();
2207                         s += _stprintf( s, _T("%s"), hexstring(i16, 0) );
2208                         break;
2209
2210                 case PARAM_ADDR:
2211                         addr = FETCHD16();
2212                         ptr = FETCHD16();
2213                         s += _stprintf( s, _T("%s:"), hexstring(ptr, 4) );
2214                         s += _stprintf( s, _T("%s"), hexstring(addr, 0) );
2215                         break;
2216
2217                 case PARAM_REL16:
2218                         /* make sure to keep the relative offset within the segment */
2219                         d16 = FETCHD16();
2220                         s += _stprintf( s, _T("%s"), hexstring((pc & 0xFFFF0000) | ((pc + d16) & 0x0000FFFF), 0) );
2221                         break;
2222
2223                 case PARAM_REL8:
2224                         d8 = FETCHD();
2225                         s += _stprintf( s, _T("%s"), hexstring(pc + d8, 0) );
2226                         break;
2227
2228                 case PARAM_MEM_OFFS:
2229                         switch(segment)
2230                         {
2231                                 case SEG_PS: s += _stprintf( s, _T("ps:") ); break;
2232                                 case SEG_DS0: s += _stprintf( s, _T("ds0:") ); break;
2233                                 case SEG_DS1: s += _stprintf( s, _T("ds1:") ); break;
2234                                 case SEG_SS: s += _stprintf( s, _T("ss:") ); break;
2235                         }
2236
2237                         i16 = FETCHD16();
2238                         s += _stprintf( s, _T("[%s]"), hexstring(i16, 0) );
2239                         break;
2240
2241                 case PARAM_SREG:
2242                         s += _stprintf( s, _T("%s"), nec_sreg[MODRM_REG1] );
2243                         break;
2244
2245                 case PARAM_SFREG:
2246                         i8 = FETCHD();
2247                         s += _stprintf( s, _T("%s"), nec_sfreg[i8] );
2248                         break;
2249
2250                 case PARAM_1:
2251                         s += _stprintf( s, _T("1") );
2252                         break;
2253
2254                 case PARAM_AL: s += _stprintf( s, _T("al") ); break;
2255                 case PARAM_CL: s += _stprintf( s, _T("cl") ); break;
2256                 case PARAM_DL: s += _stprintf( s, _T("dl") ); break;
2257                 case PARAM_BL: s += _stprintf( s, _T("bl") ); break;
2258                 case PARAM_AH: s += _stprintf( s, _T("ah") ); break;
2259                 case PARAM_CH: s += _stprintf( s, _T("ch") ); break;
2260                 case PARAM_DH: s += _stprintf( s, _T("dh") ); break;
2261                 case PARAM_BH: s += _stprintf( s, _T("bh") ); break;
2262
2263                 case PARAM_AW: s += _stprintf( s, _T("aw") ); break;
2264                 case PARAM_CW: s += _stprintf( s, _T("cw") ); break;
2265                 case PARAM_DW: s += _stprintf( s, _T("dw") ); break;
2266                 case PARAM_BW: s += _stprintf( s, _T("bw") ); break;
2267                 case PARAM_SP: s += _stprintf( s, _T("sp") ); break;
2268                 case PARAM_BP: s += _stprintf( s, _T("bp") ); break;
2269                 case PARAM_IX: s += _stprintf( s, _T("ix") ); break;
2270                 case PARAM_IY: s += _stprintf( s, _T("iy") ); break;
2271         }
2272         return s;
2273 }
2274
2275 static void handle_fpu(_TCHAR *s, UINT8 op1, UINT8 op2)
2276 {
2277         switch (op1 & 0x7)
2278         {
2279                 case 0:         // Group D8
2280                 {
2281                         if (op2 < 0xc0)
2282                         {
2283                                 pc--;           // adjust fetch pointer, so modrm byte read again
2284                                 opcode_ptr--;
2285                                 handle_modrm( modrm_string );
2286                                 switch ((op2 >> 3) & 0x7)
2287                                 {
2288                                         case 0: _stprintf(s, _T("fadd    dword ptr %s"), modrm_string); break;
2289                                         case 1: _stprintf(s, _T("fmul    dword ptr %s"), modrm_string); break;
2290                                         case 2: _stprintf(s, _T("fcom    dword ptr %s"), modrm_string); break;
2291                                         case 3: _stprintf(s, _T("fcomp   dword ptr %s"), modrm_string); break;
2292                                         case 4: _stprintf(s, _T("fsub    dword ptr %s"), modrm_string); break;
2293                                         case 5: _stprintf(s, _T("fsubr   dword ptr %s"), modrm_string); break;
2294                                         case 6: _stprintf(s, _T("fdiv    dword ptr %s"), modrm_string); break;
2295                                         case 7: _stprintf(s, _T("fdivr   dword ptr %s"), modrm_string); break;
2296                                 }
2297                         } else {
2298                                 switch ((op2 >> 3) & 0x7)
2299                                 {
2300                                         case 0: _stprintf(s, _T("fadd    st(0),st(%d)"), op2 & 0x7); break;
2301                                         case 1: _stprintf(s, _T("fcom    st(0),st(%d)"), op2 & 0x7); break;
2302                                         case 2: _stprintf(s, _T("fsub    st(0),st(%d)"), op2 & 0x7); break;
2303                                         case 3: _stprintf(s, _T("fdiv    st(0),st(%d)"), op2 & 0x7); break;
2304                                         case 4: _stprintf(s, _T("fmul    st(0),st(%d)"), op2 & 0x7); break;
2305                                         case 5: _stprintf(s, _T("fcomp   st(0),st(%d)"), op2 & 0x7); break;
2306                                         case 6: _stprintf(s, _T("fsubr   st(0),st(%d)"), op2 & 0x7); break;
2307                                         case 7: _stprintf(s, _T("fdivr   st(0),st(%d)"), op2 & 0x7); break;
2308                                 }
2309                         }
2310                         break;
2311                 }
2312
2313                 case 1:         // Group D9
2314                 {
2315                         if (op2 < 0xc0)
2316                         {
2317                                 pc--;           // adjust fetch pointer, so modrm byte read again
2318                                 opcode_ptr--;
2319                                 handle_modrm( modrm_string );
2320                                 switch ((op2 >> 3) & 0x7)
2321                                 {
2322                                         case 0: _stprintf(s, _T("fld     dword ptr %s"), modrm_string); break;
2323                                         case 1: _stprintf(s, _T("??? (FPU)")); break;
2324                                         case 2: _stprintf(s, _T("fst     dword ptr %s"), modrm_string); break;
2325                                         case 3: _stprintf(s, _T("fstp    dword ptr %s"), modrm_string); break;
2326                                         case 4: _stprintf(s, _T("fldenv  word ptr %s"), modrm_string); break;
2327                                         case 5: _stprintf(s, _T("fldcw   word ptr %s"), modrm_string); break;
2328                                         case 6: _stprintf(s, _T("fstenv  word ptr %s"), modrm_string); break;
2329                                         case 7: _stprintf(s, _T("fstcw   word ptr %s"), modrm_string); break;
2330                                 }
2331                         } else {
2332                                 switch (op2 & 0x3f)
2333                                 {
2334                                         case 0x00: case 0x01: case 0x02: case 0x03: case 0x04: case 0x05: case 0x06: case 0x07:
2335                                                 _stprintf(s, _T("fld     st(0),st(%d)"), op2 & 0x7); break;
2336
2337                                         case 0x08: case 0x09: case 0x0a: case 0x0b: case 0x0c: case 0x0d: case 0x0e: case 0x0f:
2338                                                 _stprintf(s, _T("fxch    st(0),st(%d)"), op2 & 0x7); break;
2339
2340                                         case 0x10: _stprintf(s, _T("fnop")); break;
2341                                         case 0x20: _stprintf(s, _T("fchs")); break;
2342                                         case 0x21: _stprintf(s, _T("fabs")); break;
2343                                         case 0x24: _stprintf(s, _T("ftst")); break;
2344                                         case 0x25: _stprintf(s, _T("fxam")); break;
2345                                         case 0x28: _stprintf(s, _T("fld1")); break;
2346                                         case 0x29: _stprintf(s, _T("fldl2t")); break;
2347                                         case 0x2a: _stprintf(s, _T("fldl2e")); break;
2348                                         case 0x2b: _stprintf(s, _T("fldpi")); break;
2349                                         case 0x2c: _stprintf(s, _T("fldlg2")); break;
2350                                         case 0x2d: _stprintf(s, _T("fldln2")); break;
2351                                         case 0x2e: _stprintf(s, _T("fldz")); break;
2352                                         case 0x30: _stprintf(s, _T("f2xm1")); break;
2353                                         case 0x31: _stprintf(s, _T("fyl2x")); break;
2354                                         case 0x32: _stprintf(s, _T("fptan")); break;
2355                                         case 0x33: _stprintf(s, _T("fpatan")); break;
2356                                         case 0x34: _stprintf(s, _T("fxtract")); break;
2357                                         case 0x35: _stprintf(s, _T("fprem1")); break;
2358                                         case 0x36: _stprintf(s, _T("fdecstp")); break;
2359                                         case 0x37: _stprintf(s, _T("fincstp")); break;
2360                                         case 0x38: _stprintf(s, _T("fprem")); break;
2361                                         case 0x39: _stprintf(s, _T("fyl2xp1")); break;
2362                                         case 0x3a: _stprintf(s, _T("fsqrt")); break;
2363                                         case 0x3b: _stprintf(s, _T("fsincos")); break;
2364                                         case 0x3c: _stprintf(s, _T("frndint")); break;
2365                                         case 0x3d: _stprintf(s, _T("fscale")); break;
2366                                         case 0x3e: _stprintf(s, _T("fsin")); break;
2367                                         case 0x3f: _stprintf(s, _T("fcos")); break;
2368
2369                                         default: _stprintf(s, _T("??? (FPU)")); break;
2370                                 }
2371                         }
2372                         break;
2373                 }
2374
2375                 case 2:         // Group DA
2376                 {
2377                         if (op2 < 0xc0)
2378                         {
2379                                 pc--;           // adjust fetch pointer, so modrm byte read again
2380                                 opcode_ptr--;
2381                                 handle_modrm( modrm_string );
2382                                 switch ((op2 >> 3) & 0x7)
2383                                 {
2384                                         case 0: _stprintf(s, _T("fiadd   dword ptr %s"), modrm_string); break;
2385                                         case 1: _stprintf(s, _T("fimul   dword ptr %s"), modrm_string); break;
2386                                         case 2: _stprintf(s, _T("ficom   dword ptr %s"), modrm_string); break;
2387                                         case 3: _stprintf(s, _T("ficomp  dword ptr %s"), modrm_string); break;
2388                                         case 4: _stprintf(s, _T("fisub   dword ptr %s"), modrm_string); break;
2389                                         case 5: _stprintf(s, _T("fisubr  dword ptr %s"), modrm_string); break;
2390                                         case 6: _stprintf(s, _T("fidiv   dword ptr %s"), modrm_string); break;
2391                                         case 7: _stprintf(s, _T("fidivr  dword ptr %s"), modrm_string); break;
2392                                 }
2393                         } else {
2394                                 switch (op2 & 0x3f)
2395                                 {
2396                                         case 0x00: case 0x01: case 0x02: case 0x03: case 0x04: case 0x05: case 0x06: case 0x07:
2397                                                 _stprintf(s, _T("fcmovb  st(0),st(%d)"), op2 & 0x7); break;
2398
2399                                         case 0x08: case 0x09: case 0x0a: case 0x0b: case 0x0c: case 0x0d: case 0x0e: case 0x0f:
2400                                                 _stprintf(s, _T("fcmove  st(0),st(%d)"), op2 & 0x7); break;
2401
2402                                         case 0x10: case 0x11: case 0x12: case 0x13: case 0x14: case 0x15: case 0x16: case 0x17:
2403                                                 _stprintf(s, _T("fcmovbe st(0),st(%d)"), op2 & 0x7); break;
2404
2405                                         case 0x18: case 0x19: case 0x1a: case 0x1b: case 0x1c: case 0x1d: case 0x1e: case 0x1f:
2406                                                 _stprintf(s, _T("fcmovu  st(0),st(%d)"), op2 & 0x7); break;
2407
2408                                         default: _stprintf(s, _T("??? (FPU)")); break;
2409
2410                                 }
2411                         }
2412                         break;
2413                 }
2414
2415                 case 3:         // Group DB
2416                 {
2417                         if (op2 < 0xc0)
2418                         {
2419                                 pc--;           // adjust fetch pointer, so modrm byte read again
2420                                 opcode_ptr--;
2421                                 handle_modrm( modrm_string );
2422                                 switch ((op2 >> 3) & 0x7)
2423                                 {
2424                                         case 0: _stprintf(s, _T("fild    dword ptr %s"), modrm_string); break;
2425                                         case 1: _stprintf(s, _T("??? (FPU)")); break;
2426                                         case 2: _stprintf(s, _T("fist    dword ptr %s"), modrm_string); break;
2427                                         case 3: _stprintf(s, _T("fistp   dword ptr %s"), modrm_string); break;
2428                                         case 4: _stprintf(s, _T("??? (FPU)")); break;
2429                                         case 5: _stprintf(s, _T("fld     tword ptr %s"), modrm_string); break;
2430                                         case 6: _stprintf(s, _T("??? (FPU)")); break;
2431                                         case 7: _stprintf(s, _T("fstp    tword ptr %s"), modrm_string); break;
2432                                 }
2433                         } else {
2434                                 switch (op2 & 0x3f)
2435                                 {
2436                                         case 0x00: case 0x01: case 0x02: case 0x03: case 0x04: case 0x05: case 0x06: case 0x07:
2437                                                 _stprintf(s, _T("fcmovnb st(0),st(%d)"), op2 & 0x7); break;
2438
2439                                         case 0x08: case 0x09: case 0x0a: case 0x0b: case 0x0c: case 0x0d: case 0x0e: case 0x0f:
2440                                                 _stprintf(s, _T("fcmovne st(0),st(%d)"), op2 & 0x7); break;
2441
2442                                         case 0x10: case 0x11: case 0x12: case 0x13: case 0x14: case 0x15: case 0x16: case 0x17:
2443                                                 _stprintf(s, _T("fcmovnbe st(0),st(%d)"), op2 & 0x7); break;
2444
2445                                         case 0x18: case 0x19: case 0x1a: case 0x1b: case 0x1c: case 0x1d: case 0x1e: case 0x1f:
2446                                                 _stprintf(s, _T("fcmovnu st(0),st(%d)"), op2 & 0x7); break;
2447
2448                                         case 0x22: _stprintf(s, _T("fclex")); break;
2449                                         case 0x23: _stprintf(s, _T("finit")); break;
2450
2451                                         case 0x28: case 0x29: case 0x2a: case 0x2b: case 0x2c: case 0x2d: case 0x2e: case 0x2f:
2452                                                 _stprintf(s, _T("fucomi  st(0),st(%d)"), op2 & 0x7); break;
2453
2454                                         case 0x30: case 0x31: case 0x32: case 0x33: case 0x34: case 0x35: case 0x36: case 0x37:
2455                                                 _stprintf(s, _T("fcomi   st(0),st(%d)"), op2 & 0x7); break;
2456
2457                                         default: _stprintf(s, _T("??? (FPU)")); break;
2458                                 }
2459                         }
2460                         break;
2461                 }
2462
2463                 case 4:         // Group DC
2464                 {
2465                         if (op2 < 0xc0)
2466                         {
2467                                 pc--;           // adjust fetch pointer, so modrm byte read again
2468                                 opcode_ptr--;
2469                                 handle_modrm( modrm_string );
2470                                 switch ((op2 >> 3) & 0x7)
2471                                 {
2472                                         case 0: _stprintf(s, _T("fadd    qword ptr %s"), modrm_string); break;
2473                                         case 1: _stprintf(s, _T("fmul    qword ptr %s"), modrm_string); break;
2474                                         case 2: _stprintf(s, _T("fcom    qword ptr %s"), modrm_string); break;
2475                                         case 3: _stprintf(s, _T("fcomp   qword ptr %s"), modrm_string); break;
2476                                         case 4: _stprintf(s, _T("fsub    qword ptr %s"), modrm_string); break;
2477                                         case 5: _stprintf(s, _T("fsubr   qword ptr %s"), modrm_string); break;
2478                                         case 6: _stprintf(s, _T("fdiv    qword ptr %s"), modrm_string); break;
2479                                         case 7: _stprintf(s, _T("fdivr   qword ptr %s"), modrm_string); break;
2480                                 }
2481                         } else {
2482                                 switch (op2 & 0x3f)
2483                                 {
2484                                         case 0x00: case 0x01: case 0x02: case 0x03: case 0x04: case 0x05: case 0x06: case 0x07:
2485                                                 _stprintf(s, _T("fadd    st(%d),st(0)"), op2 & 0x7); break;
2486
2487                                         case 0x08: case 0x09: case 0x0a: case 0x0b: case 0x0c: case 0x0d: case 0x0e: case 0x0f:
2488                                                 _stprintf(s, _T("fmul    st(%d),st(0)"), op2 & 0x7); break;
2489
2490                                         case 0x20: case 0x21: case 0x22: case 0x23: case 0x24: case 0x25: case 0x26: case 0x27:
2491                                                 _stprintf(s, _T("fsubr   st(%d),st(0)"), op2 & 0x7); break;
2492
2493                                         case 0x28: case 0x29: case 0x2a: case 0x2b: case 0x2c: case 0x2d: case 0x2e: case 0x2f:
2494                                                 _stprintf(s, _T("fsub    st(%d),st(0)"), op2 & 0x7); break;
2495
2496                                         case 0x30: case 0x31: case 0x32: case 0x33: case 0x34: case 0x35: case 0x36: case 0x37:
2497                                                 _stprintf(s, _T("fdivr   st(%d),st(0)"), op2 & 0x7); break;
2498
2499                                         case 0x38: case 0x39: case 0x3a: case 0x3b: case 0x3c: case 0x3d: case 0x3e: case 0x3f:
2500                                                 _stprintf(s, _T("fdiv    st(%d),st(0)"), op2 & 0x7); break;
2501
2502                                         default: _stprintf(s, _T("??? (FPU)")); break;
2503                                 }
2504                         }
2505                         break;
2506                 }
2507
2508                 case 5:         // Group DD
2509                 {
2510                         if (op2 < 0xc0)
2511                         {
2512                                 pc--;           // adjust fetch pointer, so modrm byte read again
2513                                 opcode_ptr--;
2514                                 handle_modrm( modrm_string );
2515                                 switch ((op2 >> 3) & 0x7)
2516                                 {
2517                                         case 0: _stprintf(s, _T("fld     qword ptr %s"), modrm_string); break;
2518                                         case 1: _stprintf(s, _T("??? (FPU)")); break;
2519                                         case 2: _stprintf(s, _T("fst     qword ptr %s"), modrm_string); break;
2520                                         case 3: _stprintf(s, _T("fstp    qword ptr %s"), modrm_string); break;
2521                                         case 4: _stprintf(s, _T("frstor  %s"), modrm_string); break;
2522                                         case 5: _stprintf(s, _T("??? (FPU)")); break;
2523                                         case 6: _stprintf(s, _T("fsave   %s"), modrm_string); break;
2524                                         case 7: _stprintf(s, _T("fstsw   word ptr %s"), modrm_string); break;
2525                                 }
2526                         } else {
2527                                 switch (op2 & 0x3f)
2528                                 {
2529                                         case 0x00: case 0x01: case 0x02: case 0x03: case 0x04: case 0x05: case 0x06: case 0x07:
2530                                                 _stprintf(s, _T("ffree   st(%d)"), op2 & 0x7); break;
2531
2532                                         case 0x10: case 0x11: case 0x12: case 0x13: case 0x14: case 0x15: case 0x16: case 0x17:
2533                                                 _stprintf(s, _T("fst     st(%d)"), op2 & 0x7); break;
2534
2535                                         case 0x18: case 0x19: case 0x1a: case 0x1b: case 0x1c: case 0x1d: case 0x1e: case 0x1f:
2536                                                 _stprintf(s, _T("fstp    st(%d)"), op2 & 0x7); break;
2537
2538                                         case 0x20: case 0x21: case 0x22: case 0x23: case 0x24: case 0x25: case 0x26: case 0x27:
2539                                                 _stprintf(s, _T("fucom   st(%d), st(0)"), op2 & 0x7); break;
2540
2541                                         case 0x28: case 0x29: case 0x2a: case 0x2b: case 0x2c: case 0x2d: case 0x2e: case 0x2f:
2542                                                 _stprintf(s, _T("fucomp  st(%d)"), op2 & 0x7); break;
2543
2544                                         default: _stprintf(s, _T("??? (FPU)")); break;
2545                                 }
2546                         }
2547                         break;
2548                 }
2549
2550                 case 6:         // Group DE
2551                 {
2552                         if (op2 < 0xc0)
2553                         {
2554                                 pc--;           // adjust fetch pointer, so modrm byte read again
2555                                 opcode_ptr--;
2556                                 handle_modrm( modrm_string );
2557                                 switch ((op2 >> 3) & 0x7)
2558                                 {
2559                                         case 0: _stprintf(s, _T("fiadd   word ptr %s"), modrm_string); break;
2560                                         case 1: _stprintf(s, _T("fimul   word ptr %s"), modrm_string); break;
2561                                         case 2: _stprintf(s, _T("ficom   word ptr %s"), modrm_string); break;
2562                                         case 3: _stprintf(s, _T("ficomp  word ptr %s"), modrm_string); break;
2563                                         case 4: _stprintf(s, _T("fisub   word ptr %s"), modrm_string); break;
2564                                         case 5: _stprintf(s, _T("fisubr  word ptr %s"), modrm_string); break;
2565                                         case 6: _stprintf(s, _T("fidiv   word ptr %s"), modrm_string); break;
2566                                         case 7: _stprintf(s, _T("fidivr  word ptr %s"), modrm_string); break;
2567                                 }
2568                         } else {
2569                                 switch (op2 & 0x3f)
2570                                 {
2571                                         case 0x00: case 0x01: case 0x02: case 0x03: case 0x04: case 0x05: case 0x06: case 0x07:
2572                                                 _stprintf(s, _T("faddp   st(%d)"), op2 & 0x7); break;
2573
2574                                         case 0x08: case 0x09: case 0x0a: case 0x0b: case 0x0c: case 0x0d: case 0x0e: case 0x0f:
2575                                                 _stprintf(s, _T("fmulp   st(%d)"), op2 & 0x7); break;
2576
2577                                         case 0x19: _stprintf(s, _T("fcompp")); break;
2578
2579                                         case 0x20: case 0x21: case 0x22: case 0x23: case 0x24: case 0x25: case 0x26: case 0x27:
2580                                                 _stprintf(s, _T("fsubrp  st(%d)"), op2 & 0x7); break;
2581
2582                                         case 0x28: case 0x29: case 0x2a: case 0x2b: case 0x2c: case 0x2d: case 0x2e: case 0x2f:
2583                                                 _stprintf(s, _T("fsubp   st(%d)"), op2 & 0x7); break;
2584
2585                                         case 0x30: case 0x31: case 0x32: case 0x33: case 0x34: case 0x35: case 0x36: case 0x37:
2586                                                 _stprintf(s, _T("fdivrp  st(%d), st(0)"), op2 & 0x7); break;
2587
2588                                         case 0x38: case 0x39: case 0x3a: case 0x3b: case 0x3c: case 0x3d: case 0x3e: case 0x3f:
2589                                                 _stprintf(s, _T("fdivp   st(%d)"), op2 & 0x7); break;
2590
2591                                         default: _stprintf(s, _T("??? (FPU)")); break;
2592                                 }
2593                         }
2594                         break;
2595                 }
2596
2597                 case 7:         // Group DF
2598                 {
2599                         if (op2 < 0xc0)
2600                         {
2601                                 pc--;           // adjust fetch pointer, so modrm byte read again
2602                                 opcode_ptr--;
2603                                 handle_modrm( modrm_string );
2604                                 switch ((op2 >> 3) & 0x7)
2605                                 {
2606                                         case 0: _stprintf(s, _T("fild    word ptr %s"), modrm_string); break;
2607                                         case 1: _stprintf(s, _T("??? (FPU)")); break;
2608                                         case 2: _stprintf(s, _T("fist    word ptr %s"), modrm_string); break;
2609                                         case 3: _stprintf(s, _T("fistp   word ptr %s"), modrm_string); break;
2610                                         case 4: _stprintf(s, _T("fbld    %s"), modrm_string); break;
2611                                         case 5: _stprintf(s, _T("fild    qword ptr %s"), modrm_string); break;
2612                                         case 6: _stprintf(s, _T("fbstp   %s"), modrm_string); break;
2613                                         case 7: _stprintf(s, _T("fistp   qword ptr %s"), modrm_string); break;
2614                                 }
2615                         } else {
2616                                 switch (op2 & 0x3f)
2617                                 {
2618                                         case 0x20: _stprintf(s, _T("fstsw   aw")); break;
2619
2620                                         case 0x28: case 0x29: case 0x2a: case 0x2b: case 0x2c: case 0x2d: case 0x2e: case 0x2f:
2621                                                 _stprintf(s, _T("fucomip st(%d)"), op2 & 0x7); break;
2622
2623                                         case 0x30: case 0x31: case 0x32: case 0x33: case 0x34: case 0x35: case 0x36: case 0x37:
2624                                                 _stprintf(s, _T("fcomip  st(%d),st(0)"), op2 & 0x7); break;
2625
2626                                         default: _stprintf(s, _T("??? (FPU)")); break;
2627                                 }
2628                         }
2629                         break;
2630                 }
2631         }
2632 }
2633
2634 static void decode_opcode(_TCHAR *s, const I386_OPCODE *op, UINT8 op1 )
2635 {
2636         int i;
2637         UINT8 op2;
2638
2639         switch( op->flags )
2640         {
2641                 case TWO_BYTE:
2642                         op2 = FETCHD();
2643                         decode_opcode( s, &necv_opcode_table2[op2], op1 );
2644                         return;
2645
2646                 case SEG_PS:
2647                 case SEG_DS0:
2648                 case SEG_DS1:
2649                 case SEG_SS:
2650                         segment = op->flags;
2651                         op2 = FETCHD();
2652                         decode_opcode( s, &necv_opcode_table1[op2], op1 );
2653                         return;
2654
2655                 case PREFIX:
2656                         s += _stprintf( s, _T("%-8s"), op->mnemonic );
2657                         op2 = FETCHD();
2658                         decode_opcode( s, &necv_opcode_table1[op2], op1 );
2659                         return;
2660
2661                 case GROUP:
2662                         handle_modrm( modrm_string );
2663                         for( i=0; i < ARRAY_LENGTH(group_op_table); i++ ) {
2664                                 if( _tcscmp(op->mnemonic, group_op_table[i].mnemonic) == 0 )
2665                                 {
2666                                         decode_opcode( s, &group_op_table[i].opcode[MODRM_REG1], op1 );
2667                                         return;
2668                                 }
2669                         }
2670                         goto handle_unknown;
2671
2672                 case FPU:
2673                         op2 = FETCHD();
2674                         handle_fpu( s, op1, op2);
2675                         return;
2676
2677                 case MODRM:
2678                         handle_modrm( modrm_string );
2679                         break;
2680         }
2681
2682         s += _stprintf( s, _T("%-8s"), op->mnemonic );
2683         dasm_flags = op->dasm_flags;
2684
2685         if( op->param1 != 0 ) {
2686                 s = handle_param( s, op->param1 );
2687         }
2688
2689         if( op->param2 != 0 ) {
2690                 s += _stprintf( s, _T(",") );
2691                 s = handle_param( s, op->param2 );
2692         }
2693
2694         if( op->param3 != 0 ) {
2695                 s += _stprintf( s, _T(",") );
2696                 s = handle_param( s, op->param3 );
2697         }
2698         return;
2699
2700 handle_unknown:
2701         _stprintf(s, _T("???"));
2702 }
2703
2704 int necv_dasm_one(_TCHAR *buffer, UINT32 eip, const UINT8 *oprom)
2705 {
2706         UINT8 op;
2707
2708         opcode_ptr = opcode_ptr_base = oprom;
2709         pc = eip;
2710         dasm_flags = 0;
2711         segment = 0;
2712
2713         op = FETCHD();
2714
2715         decode_opcode( buffer, &necv_opcode_table1[op], op );
2716         return (pc-eip) | dasm_flags | DASMFLAG_SUPPORTED;
2717 }
2718
2719 #define STATE_VERSION   1
2720
2721 void I86_BASE::save_state(FILEIO* state_fio)
2722 {
2723         state_fio->FputUint32(STATE_VERSION);
2724         state_fio->FputInt32(this_device_id);
2725         
2726         state_fio->Fwrite(&regs, sizeof(regs), 1);
2727         state_fio->FputUint32(pc);
2728         state_fio->FputUint32(prevpc);
2729         state_fio->Fwrite(base, sizeof(base), 1);
2730         state_fio->Fwrite(sregs, sizeof(sregs), 1);
2731         state_fio->FputUint16(flags);
2732         state_fio->FputInt32(AuxVal);
2733         state_fio->FputInt32(OverVal);
2734         state_fio->FputInt32(SignVal);
2735         state_fio->FputInt32(ZeroVal);
2736         state_fio->FputInt32(CarryVal);
2737         state_fio->FputInt32(DirVal);
2738         state_fio->FputUint8(ParityVal);
2739         state_fio->FputUint8(TF);
2740         state_fio->FputUint8(IF);
2741         state_fio->FputUint8(MF);
2742         state_fio->FputInt32(int_state);
2743         state_fio->FputBool(test_state);
2744         state_fio->FputBool(busreq);
2745         state_fio->FputBool(halted);
2746         state_fio->FputInt32(icount);
2747         state_fio->FputInt32(extra_icount);
2748         state_fio->FputBool(seg_prefix);
2749         state_fio->FputUint8(prefix_seg);
2750         state_fio->FputUint32(ea);
2751         state_fio->FputUint16(eo);
2752         state_fio->FputUint8(ea_seg);
2753 }
2754
2755 bool I86_BASE::load_state(FILEIO* state_fio)
2756 {
2757         if(state_fio->FgetUint32() != STATE_VERSION) {
2758                 return false;
2759         }
2760         if(state_fio->FgetInt32() != this_device_id) {
2761                 return false;
2762         }
2763         state_fio->Fread(&regs, sizeof(regs), 1);
2764         pc = state_fio->FgetUint32();
2765         prevpc = state_fio->FgetUint32();
2766         state_fio->Fread(base, sizeof(base), 1);
2767         state_fio->Fread(sregs, sizeof(sregs), 1);
2768         flags = state_fio->FgetUint16();
2769         AuxVal = state_fio->FgetInt32();
2770         OverVal = state_fio->FgetInt32();
2771         SignVal = state_fio->FgetInt32();
2772         ZeroVal = state_fio->FgetInt32();
2773         CarryVal = state_fio->FgetInt32();
2774         DirVal = state_fio->FgetInt32();
2775         ParityVal = state_fio->FgetUint8();
2776         TF = state_fio->FgetUint8();
2777         IF = state_fio->FgetUint8();
2778         MF = state_fio->FgetUint8();
2779         int_state = state_fio->FgetInt32();
2780         test_state = state_fio->FgetBool();
2781         busreq = state_fio->FgetBool();
2782         halted = state_fio->FgetBool();
2783         icount = state_fio->FgetInt32();
2784         extra_icount = state_fio->FgetInt32();
2785         seg_prefix = state_fio->FgetBool();
2786         prefix_seg = state_fio->FgetUint8();
2787         ea = state_fio->FgetUint32();
2788         eo = state_fio->FgetUint16();
2789         ea_seg = state_fio->FgetUint8();
2790         return true;
2791 }
2792