OSDN Git Service

[NEWDEV][VM][I286] Add Ix86 classes from MAME 0.185.
[csp-qt/common_source_project-fm7.git] / source / src / vm / libcpu_newdev / libcpu_i286 / i86.cpp
1 // license:BSD-3-Clause
2 // copyright-holders:Carl
3 /****************************************************************************
4
5     NEC V20/V30/V33 emulator modified back to a 8086/80186 emulator
6
7     (Re)Written June-September 2000 by Bryan McPhail (mish@tendril.co.uk) based
8     on code by Oliver Bergmann (Raul_Bloodworth@hotmail.com) who based code
9     on the i286 emulator by Fabrice Frances which had initial work based on
10     David Hedley's pcemu(!).
11
12 ****************************************************************************/
13
14 #include "emu.h"
15 #include "debugger.h"
16 #include "i86.h"
17 #include "i86inline.h"
18
19 #define I8086_NMI_INT_VECTOR 2
20
21 const uint8_t i8086_cpu_device::m_i8086_timing[] =
22 {
23         51,32,          /* exception, IRET */
24                 2, 0, 4, 2, /* INTs */
25                 2,              /* segment overrides */
26                 2, 4, 4,        /* flag operations */
27                 4, 4,83,60, /* arithmetic adjusts */
28                 4, 4,           /* decimal adjusts */
29                 2, 5,           /* sign extension */
30                 2,24, 2, 2, 3,11,   /* misc */
31
32         15,15,15,       /* direct JMPs */
33         11,18,24,       /* indirect JMPs */
34         19,28,          /* direct CALLs */
35         16,21,37,       /* indirect CALLs */
36         20,32,24,31,    /* returns */
37                 4,16, 6,18, /* conditional JMPs */
38                 5,17, 6,18, /* loops */
39
40         10,14, 8,12,    /* port reads */
41         10,14, 8,12,    /* port writes */
42
43                 2, 8, 9,        /* move, 8-bit */
44                 4,10,           /* move, 8-bit immediate */
45                 2, 8, 9,        /* move, 16-bit */
46                 4,10,           /* move, 16-bit immediate */
47         10,10,10,10,    /* move, AL/AX memory */
48                 2, 8, 2, 9, /* move, segment registers */
49                 4,17,           /* exchange, 8-bit */
50                 4,17, 3,        /* exchange, 16-bit */
51
52         15,24,14,14,    /* pushes */
53         12,25,12,12,    /* pops */
54
55                 3, 9,16,        /* ALU ops, 8-bit */
56                 4,17,10,        /* ALU ops, 8-bit immediate */
57                 3, 9,16,        /* ALU ops, 16-bit */
58                 4,17,10,        /* ALU ops, 16-bit immediate */
59                 4,17,10,        /* ALU ops, 16-bit w/8-bit immediate */
60         70,118,76,128,  /* MUL */
61         80,128,86,138,  /* IMUL */
62         80,144,86,154,  /* DIV */
63         101,165,107,175,/* IDIV */
64                 3, 2,15,15, /* INC/DEC */
65                 3, 3,16,16, /* NEG/NOT */
66
67                 2, 8, 4,        /* reg shift/rotate */
68         15,20, 4,       /* m8 shift/rotate */
69         15,20, 4,       /* m16 shift/rotate */
70
71         22, 9,21,       /* CMPS 8-bit */
72         22, 9,21,       /* CMPS 16-bit */
73         15, 9,14,       /* SCAS 8-bit */
74         15, 9,14,       /* SCAS 16-bit */
75         12, 9,11,       /* LODS 8-bit */
76         12, 9,11,       /* LODS 16-bit */
77         11, 9,10,       /* STOS 8-bit */
78         11, 9,10,       /* STOS 16-bit */
79         18, 9,17,       /* MOVS 8-bit */
80         18, 9,17,       /* MOVS 16-bit */
81 };
82
83 /***************************************************************************/
84 /* cpu state                                                               */
85 /***************************************************************************/
86
87
88 /***************************************************************************/
89
90 const device_type I8086 = device_creator<i8086_cpu_device>;
91 const device_type I8088 = device_creator<i8088_cpu_device>;
92
93 i8088_cpu_device::i8088_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
94         : i8086_cpu_device(mconfig, I8088, "I8088", tag, owner, clock, "i8088", __FILE__, 8)
95 {
96         memcpy(m_timing, m_i8086_timing, sizeof(m_i8086_timing));
97         m_fetch_xor = 0;
98 }
99
100 i8086_cpu_device::i8086_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
101         : i8086_common_cpu_device(mconfig, I8086, "I8086", tag, owner, clock, "i8086", __FILE__)
102         , m_program_config("program", ENDIANNESS_LITTLE, 16, 20, 0)
103         , m_opcodes_config("opcodes", ENDIANNESS_LITTLE, 16, 20, 0)
104         , m_io_config("io", ENDIANNESS_LITTLE, 16, 16, 0)
105 {
106         memcpy(m_timing, m_i8086_timing, sizeof(m_i8086_timing));
107         m_fetch_xor = BYTE_XOR_LE(0);
108 }
109
110 i8086_cpu_device::i8086_cpu_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, uint32_t clock, const char *shortname, const char *source, int data_bus_size)
111         : i8086_common_cpu_device(mconfig, type, name, tag, owner, clock, shortname, source)
112         , m_program_config("program", ENDIANNESS_LITTLE, data_bus_size, 20, 0)
113         , m_opcodes_config("opcodes", ENDIANNESS_LITTLE, data_bus_size, 20, 0)
114         , m_io_config("io", ENDIANNESS_LITTLE, data_bus_size, 16, 0)
115 {
116 }
117
118 const address_space_config *i8086_cpu_device::memory_space_config(address_spacenum spacenum) const
119 {
120         switch(spacenum)
121         {
122         case AS_PROGRAM:           return &m_program_config;
123         case AS_IO:                return &m_io_config;
124         case AS_DECRYPTED_OPCODES: return has_configured_map(AS_DECRYPTED_OPCODES) ? &m_opcodes_config : nullptr;
125         default:                   return nullptr;
126         }
127 }
128
129 uint8_t i8086_cpu_device::fetch_op()
130 {
131         uint8_t data;
132         data = m_direct_opcodes->read_byte(pc(), m_fetch_xor);
133         m_ip++;
134         return data;
135 }
136
137 uint8_t i8086_cpu_device::fetch()
138 {
139         uint8_t data;
140         data = m_direct_opcodes->read_byte(pc(), m_fetch_xor);
141         m_ip++;
142         return data;
143 }
144
145 void i8086_cpu_device::execute_run()
146 {
147         while(m_icount > 0 )
148         {
149                 if ( m_seg_prefix_next )
150                 {
151                         m_seg_prefix = true;
152                         m_seg_prefix_next = false;
153                 }
154                 else
155                 {
156                         m_prev_ip = m_ip;
157                         m_seg_prefix = false;
158
159                                 /* Dispatch IRQ */
160                         if ( m_pending_irq && (m_no_interrupt == 0) )
161                         {
162                                 if ( m_pending_irq & NMI_IRQ )
163                                 {
164                                         interrupt(I8086_NMI_INT_VECTOR);
165                                         m_pending_irq &= ~NMI_IRQ;
166                                 }
167                                 else if ( m_IF )
168                                 {
169                                         /* the actual vector is retrieved after pushing flags */
170                                         /* and clearing the IF */
171                                         interrupt(-1);
172                                 }
173                         }
174
175                         /* Trap should allow one instruction to be executed.
176                            CPUID.ASM (by Bob Smith, 1985) suggests that in situations where m_no_interrupt is 1,
177                            (directly after POP SS / MOV_SREG), single step IRQs don't fire.
178                         */
179                         if (m_fire_trap )
180                         {
181                                 if ( (m_fire_trap >= 2) && (m_no_interrupt == 0) )
182                                 {
183                                         m_fire_trap = 0; // reset trap flag upon entry
184                                         interrupt(1);
185                                 }
186                                 else
187                                 {
188                                         m_fire_trap++;
189                                 }
190                         }
191
192                         /* No interrupt allowed between last instruction and this one */
193                         if ( m_no_interrupt )
194                         {
195                                 m_no_interrupt--;
196                         }
197
198                 }
199
200                 if (!m_seg_prefix)
201                 {
202                         debugger_instruction_hook( this, pc() );
203                 }
204
205                 uint8_t op = fetch_op();
206
207                 switch(op)
208                 {
209                         case 0x0f:
210                                 m_sregs[CS] = POP();
211                                 CLK(POP_SEG);
212                                 break;
213
214                         case 0xd2: // i_rotshft_bcl
215                                 {
216                                         uint8_t c;
217
218                                         m_modrm = fetch();
219                                         m_src = GetRMByte();
220                                         m_dst = m_src;
221                                         c = m_regs.b[CL];
222                                         CLKM(ROT_REG_BASE,ROT_M8_BASE);
223                                         m_icount -= m_timing[ROT_REG_BIT] * c;
224                                         if (c)
225                                         {
226                                                 switch ( m_modrm & 0x38 )
227                                                 {
228                                                 case 0x00: do { ROL_BYTE();  c--; } while (c>0); PutbackRMByte(m_dst); break;
229                                                 case 0x08: do { ROR_BYTE();  c--; } while (c>0); PutbackRMByte(m_dst); break;
230                                                 case 0x10: do { ROLC_BYTE(); c--; } while (c>0); PutbackRMByte(m_dst); break;
231                                                 case 0x18: do { RORC_BYTE(); c--; } while (c>0); PutbackRMByte(m_dst); break;
232                                                 case 0x30:
233                                                 case 0x20: SHL_BYTE(c); break;
234                                                 case 0x28: SHR_BYTE(c); break;
235                                                 case 0x38: SHRA_BYTE(c); break;
236                                                 }
237                                         }
238                                 }
239                                 break;
240
241                         case 0xd3: // i_rotshft_wcl
242                                 {
243                                         uint8_t c;
244
245                                         m_modrm = fetch();
246                                         m_src = GetRMWord();
247                                         m_dst = m_src;
248                                         c = m_regs.b[CL];
249                                         CLKM(ROT_REG_BASE,ROT_M16_BASE);
250                                         m_icount -= m_timing[ROT_REG_BIT] * c;
251                                         if (c)
252                                         {
253                                                 switch ( m_modrm & 0x38 )
254                                                 {
255                                                         case 0x00: do { ROL_WORD();  c--; } while (c>0); PutbackRMWord(m_dst); break;
256                                                         case 0x08: do { ROR_WORD();  c--; } while (c>0); PutbackRMWord(m_dst); break;
257                                                         case 0x10: do { ROLC_WORD(); c--; } while (c>0); PutbackRMWord(m_dst); break;
258                                                         case 0x18: do { RORC_WORD(); c--; } while (c>0); PutbackRMWord(m_dst); break;
259                                                         case 0x30:
260                                                         case 0x20: SHL_WORD(c); break;
261                                                         case 0x28: SHR_WORD(c); break;
262                                                         case 0x38: SHRA_WORD(c); break;
263                                                 }
264                                         }
265                                 }
266                                 break;
267
268                         default:
269                                 if(!common_op(op))
270                                 {
271                                         m_icount -= 10;
272                                         logerror("%06x: Invalid Opcode %02x\n", pc(), op);
273                                         break;
274                                 }
275                                 break;
276                 }
277         }
278 }
279
280 void i8086_cpu_device::device_start()
281 {
282         i8086_common_cpu_device::device_start();
283         state_add( I8086_ES, "ES", m_sregs[ES] ).formatstr("%04X");
284         state_add( I8086_CS, "CS", m_sregs[CS] ).callimport().formatstr("%04X");
285         state_add( I8086_SS, "SS", m_sregs[SS] ).formatstr("%04X");
286         state_add( I8086_DS, "DS", m_sregs[DS] ).formatstr("%04X");
287         state_add( I8086_VECTOR, "V", m_int_vector).formatstr("%02X");
288
289         state_add( I8086_PC, "PC", m_pc ).callimport().formatstr("%05X");
290         state_add( STATE_GENPCBASE, "CURPC", m_pc ).callimport().formatstr("%05X").noshow();
291         state_add( I8086_HALT, "HALT", m_halt ).mask(1);
292 }
293
294 i8086_common_cpu_device::i8086_common_cpu_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, uint32_t clock, const char *shortname, const char *source)
295         : cpu_device(mconfig, type, name, tag, owner, clock, shortname, source)
296         , m_ip(0)
297         , m_TF(0)
298         , m_int_vector(0)
299         , m_pending_irq(0)
300         , m_nmi_state(0)
301         , m_irq_state(0)
302         , m_test_state(1)
303         , m_pc(0)
304         , m_lock(false)
305         , m_lock_handler(*this)
306 {
307         static const BREGS reg_name[8]={ AL, CL, DL, BL, AH, CH, DH, BH };
308
309         /* Set up parity lookup table. */
310         for (uint16_t i = 0;i < 256; i++)
311         {
312                 uint16_t c = 0;
313                 for (uint16_t j = i; j > 0; j >>= 1)
314                 {
315                         if (j & 1) c++;
316                 }
317                 m_parity_table[i] = !(c & 1);
318         }
319
320         for (uint16_t i = 0; i < 256; i++)
321         {
322                 m_Mod_RM.reg.b[i] = reg_name[(i & 0x38) >> 3];
323                 m_Mod_RM.reg.w[i] = (WREGS) ( (i & 0x38) >> 3) ;
324         }
325
326         for (uint16_t i = 0xc0; i < 0x100; i++)
327         {
328                 m_Mod_RM.RM.w[i] = (WREGS)( i & 7 );
329                 m_Mod_RM.RM.b[i] = (BREGS)reg_name[i & 7];
330         }
331
332         memset(&m_regs, 0x00, sizeof(m_regs));
333         memset(m_sregs, 0x00, sizeof(m_sregs));
334 }
335
336
337 //-------------------------------------------------
338 //  state_import - import state into the device,
339 //  after it has been set
340 //-------------------------------------------------
341
342 void i8086_common_cpu_device::state_import(const device_state_entry &entry)
343 {
344         switch (entry.index())
345         {
346         case I8086_IP:
347         case I8086_CS:
348                 m_pc = (m_sregs[CS] << 4) + m_ip;
349                 break;
350
351         case STATE_GENPC:
352         case STATE_GENPCBASE:
353                 if (m_pc - (m_sregs[CS] << 4) > 0xffff)
354                         m_sregs[CS] = m_pc >> 4;
355                 m_ip = m_pc - (m_sregs[CS] << 4);
356                 break;
357         }
358 }
359
360
361 //-------------------------------------------------
362 //  state_string_export - export state as a string
363 //  for the debugger
364 //-------------------------------------------------
365
366 void i8086_common_cpu_device::state_string_export(const device_state_entry &entry, std::string &str) const
367 {
368         switch (entry.index())
369         {
370                 case STATE_GENFLAGS:
371                         {
372                                 uint16_t flags = CompressFlags();
373                                 str = string_format("%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c",
374                                         flags & 0x8000 ? '1':'.',
375                                         flags & 0x4000 ? '1':'.',
376                                         flags & 0x2000 ? '1':'.',
377                                         flags & 0x1000 ? '1':'.',
378                                         flags & 0x0800 ? 'O':'.',
379                                         flags & 0x0400 ? 'D':'.',
380                                         flags & 0x0200 ? 'I':'.',
381                                         flags & 0x0100 ? 'T':'.',
382                                         flags & 0x0080 ? 'S':'.',
383                                         flags & 0x0040 ? 'Z':'.',
384                                         flags & 0x0020 ? '0':'.',
385                                         flags & 0x0010 ? 'A':'.',
386                                         flags & 0x0008 ? '0':'.',
387                                         flags & 0x0004 ? 'P':'.',
388                                         flags & 0x0002 ? '1':'.',
389                                         flags & 0x0001 ? 'C':'.');
390                         }
391                         break;
392         }
393 }
394
395 void i8086_common_cpu_device::device_start()
396 {
397         m_program = &space(AS_PROGRAM);
398         m_opcodes = has_space(AS_DECRYPTED_OPCODES) ? &space(AS_DECRYPTED_OPCODES) : m_program;
399         m_direct = &m_program->direct();
400         m_direct_opcodes = &m_opcodes->direct();
401         m_io = &space(AS_IO);
402
403         save_item(NAME(m_regs.w));
404         save_item(NAME(m_sregs));
405         save_item(NAME(m_ip));
406         save_item(NAME(m_prev_ip));
407         save_item(NAME(m_TF));
408         save_item(NAME(m_IF));
409         save_item(NAME(m_DF));
410         save_item(NAME(m_MF));
411         save_item(NAME(m_NT));
412         save_item(NAME(m_IOPL));
413         save_item(NAME(m_SignVal));
414         save_item(NAME(m_int_vector));
415         save_item(NAME(m_pending_irq));
416         save_item(NAME(m_nmi_state));
417         save_item(NAME(m_irq_state));
418         save_item(NAME(m_AuxVal));
419         save_item(NAME(m_OverVal));
420         save_item(NAME(m_ZeroVal));
421         save_item(NAME(m_CarryVal));
422         save_item(NAME(m_ParityVal));
423         save_item(NAME(m_seg_prefix));
424         save_item(NAME(m_seg_prefix_next));
425         save_item(NAME(m_prefix_seg));
426         save_item(NAME(m_halt));
427
428         // Register state for debugger
429         state_add( I8086_IP, "IP", m_ip         ).callimport().formatstr("%04X");
430         state_add( I8086_AX, "AX", m_regs.w[AX] ).formatstr("%04X");
431         state_add( I8086_CX, "CX", m_regs.w[CS] ).formatstr("%04X");
432         state_add( I8086_DX, "DX", m_regs.w[DX] ).formatstr("%04X");
433         state_add( I8086_BX, "BX", m_regs.w[BX] ).formatstr("%04X");
434         state_add( I8086_SP, "SP", m_regs.w[SP] ).formatstr("%04X");
435         state_add( I8086_BP, "BP", m_regs.w[BP] ).formatstr("%04X");
436         state_add( I8086_SI, "SI", m_regs.w[SI] ).formatstr("%04X");
437         state_add( I8086_DI, "DI", m_regs.w[DI] ).formatstr("%04X");
438
439         state_add(STATE_GENFLAGS, "GENFLAGS", m_TF).formatstr("%16s").noshow();
440
441         m_icountptr = &m_icount;
442
443         m_lock_handler.resolve_safe();
444 }
445
446
447 void i8086_common_cpu_device::device_reset()
448 {
449         m_ZeroVal = 1;
450         m_ParityVal = 1;
451         m_regs.w[AX] = 0;
452         m_regs.w[CX] = 0;
453         m_regs.w[DX] = 0;
454         m_regs.w[BX] = 0;
455         m_regs.w[SP] = 0;
456         m_regs.w[BP] = 0;
457         m_regs.w[SI] = 0;
458         m_regs.w[DI] = 0;
459         m_sregs[ES] = 0;
460         m_sregs[CS] = 0xffff;
461         m_sregs[SS] = 0;
462         m_sregs[DS] = 0;
463         m_ip = 0;
464         m_prev_ip = 0;
465         m_SignVal = 0;
466         m_AuxVal = 0;
467         m_OverVal = 0;
468         m_CarryVal = 0;
469         m_TF = 0;
470         m_IF = 0;
471         m_DF = 0;
472         m_IOPL = 3; // 8086 IOPL always 3
473         m_NT = 1; // 8086 NT always 1
474         m_MF = 1; // 8086 MF always 1, 80286 always 0
475         m_int_vector = 0;
476         m_pending_irq = 0;
477         m_nmi_state = 0;
478         m_irq_state = 0;
479         m_no_interrupt = 0;
480         m_fire_trap = 0;
481         m_prefix_seg = 0;
482         m_seg_prefix = false;
483         m_seg_prefix_next = false;
484         m_ea = 0;
485         m_eo = 0;
486         m_e16 = 0;
487         m_modrm = 0;
488         m_dst = 0;
489         m_src = 0;
490         m_halt = false;
491         m_lock = false;
492 }
493
494
495
496 void i8086_common_cpu_device::interrupt(int int_num, int trap)
497 {
498         PUSH( CompressFlags() );
499         m_TF = m_IF = 0;
500
501         if (int_num == -1)
502         {
503                 int_num = standard_irq_callback(0);
504
505                 m_irq_state = CLEAR_LINE;
506                 m_pending_irq &= ~INT_IRQ;
507         }
508
509         uint16_t dest_off = read_word( int_num * 4 + 0 );
510         uint16_t dest_seg = read_word( int_num * 4 + 2 );
511
512         PUSH(m_sregs[CS]);
513         PUSH(m_ip);
514         m_ip = dest_off;
515         m_sregs[CS] = dest_seg;
516 }
517
518
519 void i8086_common_cpu_device::execute_set_input( int inptnum, int state )
520 {
521         if (inptnum == INPUT_LINE_NMI)
522         {
523                 if ( m_nmi_state == state )
524                 {
525                         return;
526                 }
527                 m_nmi_state = state;
528                 if (state != CLEAR_LINE)
529                 {
530                         m_pending_irq |= NMI_IRQ;
531                 }
532         }
533         else if (inptnum == INPUT_LINE_TEST)
534         {
535                 m_test_state = state;
536         }
537         else
538         {
539                 m_irq_state = state;
540                 if (state == CLEAR_LINE)
541                 {
542                         m_pending_irq &= ~INT_IRQ;
543                 }
544                 else
545                 {
546                         m_pending_irq |= INT_IRQ;
547                 }
548         }
549 }
550
551 offs_t i8086_common_cpu_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options)
552 {
553         extern int i386_dasm_one(std::ostream &stream, offs_t eip, const uint8_t *oprom, int mode);
554         return i386_dasm_one(stream, pc, oprom, 1);
555 }
556
557 uint8_t i8086_common_cpu_device::read_port_byte(uint16_t port)
558 {
559         return m_io->read_byte(port);
560 }
561
562 uint16_t i8086_common_cpu_device::read_port_word(uint16_t port)
563 {
564         return m_io->read_word_unaligned(port);
565 }
566
567 void i8086_common_cpu_device::write_port_byte(uint16_t port, uint8_t data)
568 {
569         m_io->write_byte(port, data);
570 }
571
572 void i8086_common_cpu_device::write_port_word(uint16_t port, uint16_t data)
573 {
574         m_io->write_word_unaligned(port, data);
575 }
576
577 uint32_t i8086_common_cpu_device::calc_addr(int seg, uint16_t offset, int size, int op, bool override)
578 {
579         if ( m_seg_prefix && (seg==DS || seg==SS) && override )
580         {
581                 return (m_sregs[m_prefix_seg] << 4) + offset;
582         }
583         else
584         {
585                 return (m_sregs[seg] << 4) + offset;
586         }
587 }
588
589 bool i8086_common_cpu_device::common_op(uint8_t op)
590 {
591         switch(op)
592         {
593                 case 0x00: // i_add_br8
594                         DEF_br8();
595                         set_CFB(ADDB());
596                         PutbackRMByte(m_dst);
597                         CLKM(ALU_RR8,ALU_MR8);
598                         break;
599
600                 case 0x01: // i_add_wr16
601                         DEF_wr16();
602                         set_CFW(ADDX());
603                         PutbackRMWord(m_dst);
604                         CLKM(ALU_RR16,ALU_MR16);
605                         break;
606
607                 case 0x02: // i_add_r8b
608                         DEF_r8b();
609                         set_CFB(ADDB());
610                         RegByte(m_dst);
611                         CLKM(ALU_RR8,ALU_RM8);
612                         break;
613
614                 case 0x03: // i_add_r16w
615                         DEF_r16w();
616                         set_CFW(ADDX());
617                         RegWord(m_dst);
618                         CLKM(ALU_RR16,ALU_RM16);
619                         break;
620
621                 case 0x04: // i_add_ald8
622                         DEF_ald8();
623                         set_CFB(ADDB());
624                         m_regs.b[AL] = m_dst;
625                         CLK(ALU_RI8);
626                         break;
627
628                 case 0x05: // i_add_axd16
629                         DEF_axd16();
630                         set_CFW(ADDX());
631                         m_regs.w[AX] = m_dst;
632                         CLK(ALU_RI16);
633                         break;
634
635                 case 0x06: // i_push_es
636                         PUSH(m_sregs[ES]);
637                         CLK(PUSH_SEG);
638                         break;
639
640                 case 0x07: // i_pop_es
641                         m_sregs[ES] = POP();
642                         CLK(POP_SEG);
643                         break;
644
645                 case 0x08: // i_or_br8
646                         DEF_br8();
647                         ORB();
648                         PutbackRMByte(m_dst);
649                         CLKM(ALU_RR8,ALU_MR8);
650                         break;
651
652                 case 0x09: // i_or_wr16
653                         DEF_wr16();
654                         ORW();
655                         PutbackRMWord(m_dst);
656                         CLKM(ALU_RR16,ALU_MR16);
657                         break;
658
659                 case 0x0a: // i_or_r8b
660                         DEF_r8b();
661                         ORB();
662                         RegByte(m_dst);
663                         CLKM(ALU_RR8,ALU_RM8);
664                         break;
665
666                 case 0x0b: // i_or_r16w
667                         DEF_r16w();
668                         ORW();
669                         RegWord(m_dst);
670                         CLKM(ALU_RR16,ALU_RM16);
671                         break;
672
673                 case 0x0c: // i_or_ald8
674                         DEF_ald8();
675                         ORB();
676                         m_regs.b[AL] = m_dst;
677                         CLK(ALU_RI8);
678                         break;
679
680                 case 0x0d: // i_or_axd16
681                         DEF_axd16();
682                         ORW();
683                         m_regs.w[AX] = m_dst;
684                         CLK(ALU_RI16);
685                         break;
686
687                 case 0x0e: // i_push_cs
688                         PUSH(m_sregs[CS]);
689                         CLK(PUSH_SEG);
690                         break;
691
692                 case 0x10: // i_adc_br8
693                 {
694                         DEF_br8();
695                         m_src += CF ? 1 : 0;
696                         uint32_t tmpcf = ADDB();
697                         PutbackRMByte(m_dst);
698                         set_CFB(tmpcf);
699                         CLKM(ALU_RR8,ALU_MR8);
700                         break;
701                 }
702                 case 0x11: // i_adc_wr16
703                 {
704                         DEF_wr16();
705                         m_src += CF ? 1 : 0;
706                         uint32_t tmpcf = ADDX();
707                         PutbackRMWord(m_dst);
708                         set_CFW(tmpcf);
709                         CLKM(ALU_RR16,ALU_MR16);
710                         break;
711                 }
712
713                 case 0x12: // i_adc_r8b
714                         DEF_r8b();
715                         m_src += CF ? 1 : 0;
716                         set_CFB(ADDB());
717                         RegByte(m_dst);
718                         CLKM(ALU_RR8,ALU_RM8);
719                         break;
720
721                 case 0x13: // i_adc_r16w
722                         DEF_r16w();
723                         m_src += CF ? 1 : 0;
724                         set_CFW(ADDX());
725                         RegWord(m_dst);
726                         CLKM(ALU_RR16,ALU_RM16);
727                         break;
728
729                 case 0x14: // i_adc_ald8
730                         DEF_ald8();
731                         m_src += CF ? 1 : 0;
732                         set_CFB(ADDB());
733                         m_regs.b[AL] = m_dst;
734                         CLK(ALU_RI8);
735                         break;
736
737                 case 0x15: // i_adc_axd16
738                         DEF_axd16();
739                         m_src += CF ? 1 : 0;
740                         set_CFW(ADDX());
741                         m_regs.w[AX] = m_dst;
742                         CLK(ALU_RI16);
743                         break;
744
745                 case 0x16: // i_push_ss
746                         PUSH(m_sregs[SS]);
747                         CLK(PUSH_SEG);
748                         break;
749
750                 case 0x17: // i_pop_ss
751                         m_sregs[SS] = POP();
752                         CLK(POP_SEG);
753                         m_no_interrupt = 1;
754                         break;
755
756                 case 0x18: // i_sbb_br8
757                 {
758                         uint32_t tmpcf;
759                         DEF_br8();
760                         m_src += CF ? 1 : 0;
761                         tmpcf = SUBB();
762                         PutbackRMByte(m_dst);
763                         set_CFB(tmpcf);
764                         CLKM(ALU_RR8,ALU_MR8);
765                         break;
766                 }
767
768                 case 0x19: // i_sbb_wr16
769                 {
770                         uint32_t tmpcf;
771                         DEF_wr16();
772                         m_src += CF ? 1 : 0;
773                         tmpcf = SUBX();
774                         PutbackRMWord(m_dst);
775                         set_CFW(tmpcf);
776                         CLKM(ALU_RR16,ALU_MR16);
777                         break;
778                 }
779
780                 case 0x1a: // i_sbb_r8b
781                         DEF_r8b();
782                         m_src += CF ? 1 : 0;
783                         set_CFB(SUBB());
784                         RegByte(m_dst);
785                         CLKM(ALU_RR8,ALU_RM8);
786                         break;
787
788                 case 0x1b: // i_sbb_r16w
789                         DEF_r16w();
790                         m_src += CF ? 1 : 0;
791                         set_CFW(SUBX());
792                         RegWord(m_dst);
793                         CLKM(ALU_RR16,ALU_RM16);
794                         break;
795
796                 case 0x1c: // i_sbb_ald8
797                         DEF_ald8();
798                         m_src += CF ? 1 : 0;
799                         set_CFB(SUBB());
800                         m_regs.b[AL] = m_dst;
801                         CLK(ALU_RI8);
802                         break;
803
804                 case 0x1d: // i_sbb_axd16
805                         DEF_axd16();
806                         m_src += CF ? 1 : 0;
807                         set_CFW(SUBX());
808                         m_regs.w[AX] = m_dst;
809                         CLK(ALU_RI16);
810                         break;
811
812                 case 0x1e: // i_push_ds
813                         PUSH(m_sregs[DS]);
814                         CLK(PUSH_SEG);
815                         break;
816
817                 case 0x1f: // i_pop_ds
818                         m_sregs[DS] = POP();
819                         CLK(POP_SEG);
820                         break;
821
822
823                 case 0x20: // i_and_br8
824                         DEF_br8();
825                         ANDB();
826                         PutbackRMByte(m_dst);
827                         CLKM(ALU_RR8,ALU_MR8);
828                         break;
829
830                 case 0x21: // i_and_wr16
831                         DEF_wr16();
832                         ANDX();
833                         PutbackRMWord(m_dst);
834                         CLKM(ALU_RR16,ALU_MR16);
835                         break;
836
837                 case 0x22: // i_and_r8b
838                         DEF_r8b();
839                         ANDB();
840                         RegByte(m_dst);
841                         CLKM(ALU_RR8,ALU_RM8);
842                         break;
843
844                 case 0x23: // i_and_r16w
845                         DEF_r16w();
846                         ANDX();
847                         RegWord(m_dst);
848                         CLKM(ALU_RR16,ALU_RM16);
849                         break;
850
851                 case 0x24: // i_and_ald8
852                         DEF_ald8();
853                         ANDB();
854                         m_regs.b[AL] = m_dst;
855                         CLK(ALU_RI8);
856                         break;
857
858                 case 0x25: // i_and_axd16
859                         DEF_axd16();
860                         ANDX();
861                         m_regs.w[AX] = m_dst;
862                         CLK(ALU_RI16);
863                         break;
864
865                 case 0x26: // i_es
866                         m_seg_prefix_next = true;
867                         m_prefix_seg = ES;
868                         CLK(OVERRIDE);
869                         break;
870
871                 case 0x27: // i_daa
872                         ADJ4(6,0x60);
873                         CLK(DAA);
874                         break;
875
876
877                 case 0x28: // i_sub_br8
878                         DEF_br8();
879                         set_CFB(SUBB());
880                         PutbackRMByte(m_dst);
881                         CLKM(ALU_RR8,ALU_MR8);
882                         break;
883
884                 case 0x29: // i_sub_wr16
885                         DEF_wr16();
886                         set_CFW(SUBX());
887                         PutbackRMWord(m_dst);
888                         CLKM(ALU_RR16,ALU_MR16);
889                         break;
890
891                 case 0x2a: // i_sub_r8b
892                         DEF_r8b();
893                         set_CFB(SUBB());
894                         RegByte(m_dst);
895                         CLKM(ALU_RR8,ALU_RM8);
896                         break;
897
898                 case 0x2b: // i_sub_r16w
899                         DEF_r16w();
900                         set_CFW(SUBX());
901                         RegWord(m_dst);
902                         CLKM(ALU_RR16,ALU_RM16);
903                         break;
904
905                 case 0x2c: // i_sub_ald8
906                         DEF_ald8();
907                         set_CFB(SUBB());
908                         m_regs.b[AL] = m_dst;
909                         CLK(ALU_RI8);
910                         break;
911
912                 case 0x2d: // i_sub_axd16
913                         DEF_axd16();
914                         set_CFW(SUBX());
915                         m_regs.w[AX] = m_dst;
916                         CLK(ALU_RI16);
917                         break;
918
919                 case 0x2e: // i_cs
920                         m_seg_prefix_next = true;
921                         m_prefix_seg = CS;
922                         CLK(OVERRIDE);
923                         break;
924
925                 case 0x2f: // i_das
926                         ADJ4(-6,-0x60);
927                         CLK(DAS);
928                         break;
929
930
931                 case 0x30: // i_xor_br8
932                         DEF_br8();
933                         XORB();
934                         PutbackRMByte(m_dst);
935                         CLKM(ALU_RR8,ALU_MR8);
936                         break;
937
938                 case 0x31: // i_xor_wr16
939                         DEF_wr16();
940                         XORW();
941                         PutbackRMWord(m_dst);
942                         CLKM(ALU_RR16,ALU_RM16);
943                         break;
944
945                 case 0x32: // i_xor_r8b
946                         DEF_r8b();
947                         XORB();
948                         RegByte(m_dst);
949                         CLKM(ALU_RR8,ALU_RM8);
950                         break;
951
952                 case 0x33: // i_xor_r16w
953                         DEF_r16w();
954                         XORW();
955                         RegWord(m_dst);
956                         CLKM(ALU_RR16,ALU_RM16);
957                         break;
958
959                 case 0x34: // i_xor_ald8
960                         DEF_ald8();
961                         XORB();
962                         m_regs.b[AL] = m_dst;
963                         CLK(ALU_RI8);
964                         break;
965
966                 case 0x35: // i_xor_axd16
967                         DEF_axd16();
968                         XORW();
969                         m_regs.w[AX] = m_dst;
970                         CLK(ALU_RI16);
971                         break;
972
973                 case 0x36: // i_ss
974                         m_seg_prefix_next = true;
975                         m_prefix_seg = SS;
976                         CLK(OVERRIDE);
977                         break;
978
979                 case 0x37: // i_aaa
980                         ADJB(6, (m_regs.b[AL] > 0xf9) ? 2 : 1);
981                         CLK(AAA);
982                         break;
983
984
985                 case 0x38: // i_cmp_br8
986                         DEF_br8();
987                         set_CFB(SUBB());
988                         CLKM(ALU_RR8,ALU_RM8);
989                         break;
990
991                 case 0x39: // i_cmp_wr16
992                         DEF_wr16();
993                         set_CFW(SUBX());
994                         CLKM(ALU_RR16,ALU_RM16);
995                         break;
996
997                 case 0x3a: // i_cmp_r8b
998                         DEF_r8b();
999                         set_CFB(SUBB());
1000                         CLKM(ALU_RR8,ALU_RM8);
1001                         break;
1002
1003                 case 0x3b: // i_cmp_r16w
1004                         DEF_r16w();
1005                         set_CFW(SUBX());
1006                         CLKM(ALU_RR16,ALU_RM16);
1007                         break;
1008
1009                 case 0x3c: // i_cmp_ald8
1010                         DEF_ald8();
1011                         set_CFB(SUBB());
1012                         CLK(ALU_RI8);
1013                         break;
1014
1015                 case 0x3d: // i_cmp_axd16
1016                         DEF_axd16();
1017                         set_CFW(SUBX());
1018                         CLK(ALU_RI16);
1019                         break;
1020
1021                 case 0x3e: // i_ds
1022                         m_seg_prefix_next = true;
1023                         m_prefix_seg = DS;
1024                         CLK(OVERRIDE);
1025                         break;
1026
1027                 case 0x3f: // i_aas
1028                         ADJB(-6, (m_regs.b[AL] < 6) ? -2 : -1);
1029                         CLK(AAS);
1030                         break;
1031
1032
1033                 case 0x40: // i_inc_ax
1034                         IncWordReg(AX);
1035                         CLK(INCDEC_R16);
1036                         break;
1037
1038                 case 0x41: // i_inc_cx
1039                         IncWordReg(CX);
1040                         CLK(INCDEC_R16);
1041                         break;
1042
1043                 case 0x42: // i_inc_dx
1044                         IncWordReg(DX);
1045                         CLK(INCDEC_R16);
1046                         break;
1047
1048                 case 0x43: // i_inc_bx
1049                         IncWordReg(BX);
1050                         CLK(INCDEC_R16);
1051                         break;
1052
1053                 case 0x44: // i_inc_sp
1054                         IncWordReg(SP);
1055                         CLK(INCDEC_R16);
1056                         break;
1057
1058                 case 0x45: // i_inc_bp
1059                         IncWordReg(BP);
1060                         CLK(INCDEC_R16);
1061                         break;
1062
1063                 case 0x46: // i_inc_si
1064                         IncWordReg(SI);
1065                         CLK(INCDEC_R16);
1066                         break;
1067
1068                 case 0x47: // i_inc_di
1069                         IncWordReg(DI);
1070                         CLK(INCDEC_R16);
1071                         break;
1072
1073
1074                 case 0x48: // i_dec_ax
1075                         DecWordReg(AX);
1076                         CLK(INCDEC_R16);
1077                         break;
1078
1079                 case 0x49: // i_dec_cx
1080                         DecWordReg(CX);
1081                         CLK(INCDEC_R16);
1082                         break;
1083
1084                 case 0x4a: // i_dec_dx
1085                         DecWordReg(DX);
1086                         CLK(INCDEC_R16);
1087                         break;
1088
1089                 case 0x4b: // i_dec_bx
1090                         DecWordReg(BX);
1091                         CLK(INCDEC_R16);
1092                         break;
1093
1094                 case 0x4c: // i_dec_sp
1095                         DecWordReg(SP);
1096                         CLK(INCDEC_R16);
1097                         break;
1098
1099                 case 0x4d: // i_dec_bp
1100                         DecWordReg(BP);
1101                         CLK(INCDEC_R16);
1102                         break;
1103
1104                 case 0x4e: // i_dec_si
1105                         DecWordReg(SI);
1106                         CLK(INCDEC_R16);
1107                         break;
1108
1109                 case 0x4f: // i_dec_di
1110                         DecWordReg(DI);
1111                         CLK(INCDEC_R16);
1112                         break;
1113
1114
1115                 case 0x50: // i_push_ax
1116                         PUSH(m_regs.w[AX]);
1117                         CLK(PUSH_R16);
1118                         break;
1119
1120                 case 0x51: // i_push_cx
1121                         PUSH(m_regs.w[CX]);
1122                         CLK(PUSH_R16);
1123                         break;
1124
1125                 case 0x52: // i_push_dx
1126                         PUSH(m_regs.w[DX]);
1127                         CLK(PUSH_R16);
1128                         break;
1129
1130                 case 0x53: // i_push_bx
1131                         PUSH(m_regs.w[BX]);
1132                         CLK(PUSH_R16);
1133                         break;
1134
1135                 case 0x54: // i_push_sp
1136                         PUSH(m_regs.w[SP]-2);
1137                         CLK(PUSH_R16);
1138                         break;
1139
1140                 case 0x55: // i_push_bp
1141                         PUSH(m_regs.w[BP]);
1142                         CLK(PUSH_R16);
1143                         break;
1144
1145                 case 0x56: // i_push_si
1146                         PUSH(m_regs.w[SI]);
1147                         CLK(PUSH_R16);
1148                         break;
1149
1150                 case 0x57: // i_push_di
1151                         PUSH(m_regs.w[DI]);
1152                         CLK(PUSH_R16);
1153                         break;
1154
1155
1156                 case 0x58: // i_pop_ax
1157                         m_regs.w[AX] = POP();
1158                         CLK(POP_R16);
1159                         break;
1160
1161                 case 0x59: // i_pop_cx
1162                         m_regs.w[CX] = POP();
1163                         CLK(POP_R16);
1164                         break;
1165
1166                 case 0x5a: // i_pop_dx
1167                         m_regs.w[DX] = POP();
1168                         CLK(POP_R16);
1169                         break;
1170
1171                 case 0x5b: // i_pop_bx
1172                         m_regs.w[BX] = POP();
1173                         CLK(POP_R16);
1174                         break;
1175
1176                 case 0x5c: // i_pop_sp
1177                         m_regs.w[SP] = POP();
1178                         CLK(POP_R16);
1179                         break;
1180
1181                 case 0x5d: // i_pop_bp
1182                         m_regs.w[BP] = POP();
1183                         CLK(POP_R16);
1184                         break;
1185
1186                 case 0x5e: // i_pop_si
1187                         m_regs.w[SI] = POP();
1188                         CLK(POP_R16);
1189                         break;
1190
1191                 case 0x5f: // i_pop_di
1192                         m_regs.w[DI] = POP();
1193                         CLK(POP_R16);
1194                         break;
1195
1196 // 8086 'invalid opcodes', as documented at http://www.os2museum.com/wp/?p=2147 and tested on real hardware
1197 // - 0x60 - 0x6f are aliases to 0x70 - 0x7f.
1198 // - 0xc0, 0xc1, 0xc8, 0xc9 are also aliases where the CPU ignores BIT 1 (*).
1199 // - 0xf1 is an alias to 0xf0.
1200 //
1201 //      Instructions are used in the boot sector for some versions of
1202 //      MS-DOS  (e.g. the DEC Rainbow-100 version of DOS 2.x)
1203                 case 0x60:
1204                 case 0x70: // i_jo
1205                         JMP( OF);
1206                         break;
1207
1208                 case 0x61:
1209                 case 0x71: // i_jno
1210                         JMP(!OF);
1211                         break;
1212
1213                 case 0x62:
1214                 case 0x72: // i_jc
1215                         JMP( CF);
1216                         break;
1217
1218                 case 0x63:
1219                 case 0x73: // i_jnc
1220                         JMP(!CF);
1221                         break;
1222
1223                 case 0x64:
1224                 case 0x74: // i_jz
1225                         JMP( ZF);
1226                         break;
1227
1228                 case 0x65:
1229                 case 0x75: // i_jnz
1230                         JMP(!ZF);
1231                         break;
1232
1233                 case 0x66:
1234                 case 0x76: // i_jce
1235                         JMP(CF || ZF);
1236                         break;
1237
1238                 case 0x67:
1239                 case 0x77: // i_jnce
1240                         JMP(!(CF || ZF));
1241                         break;
1242
1243                 case 0x68:
1244                 case 0x78: // i_js
1245                         JMP( SF);
1246                         break;
1247
1248                 case 0x69:
1249                 case 0x79: // i_jns
1250                         JMP(!SF);
1251                         break;
1252
1253                 case 0x6a:
1254                 case 0x7a: // i_jp
1255                         JMP( PF);
1256                         break;
1257
1258                 case 0x6b:
1259                 case 0x7b: // i_jnp
1260                         JMP(!PF);
1261                         break;
1262
1263                 case 0x6c:
1264                 case 0x7c: // i_jl
1265                         JMP((SF!=OF)&&(!ZF));
1266                         break;
1267
1268                 case 0x6d:
1269                 case 0x7d: // i_jnl
1270                         JMP(SF==OF);
1271                         break;
1272
1273                 case 0x6e:
1274                 case 0x7e: // i_jle
1275                         JMP((ZF)||(SF!=OF));
1276                         break;
1277
1278                 case 0x6f:
1279                 case 0x7f: // i_jnle
1280                         JMP((SF==OF)&&(!ZF));
1281                         break;
1282
1283
1284                 case 0x80: // i_80pre
1285                 {
1286                         uint32_t tmpcf;
1287                         m_modrm = fetch();
1288                         m_dst = GetRMByte();
1289                         m_src = fetch();
1290                         if (m_modrm >=0xc0 )             { CLK(ALU_RI8); }
1291                         else if ((m_modrm & 0x38)==0x38) { CLK(ALU_MI8_RO); }
1292                         else                             { CLK(ALU_MI8); }
1293                         switch (m_modrm & 0x38)
1294                         {
1295                         case 0x00:                      set_CFB(ADDB()); PutbackRMByte(m_dst);   break;
1296                         case 0x08:                      ORB();  PutbackRMByte(m_dst);   break;
1297                         case 0x10: m_src += CF ? 1 : 0; tmpcf = ADDB(); PutbackRMByte(m_dst); set_CFB(tmpcf); break;
1298                         case 0x18: m_src += CF ? 1 : 0; tmpcf = SUBB(); PutbackRMByte(m_dst); set_CFB(tmpcf); break;
1299                         case 0x20:                      ANDB(); PutbackRMByte(m_dst);   break;
1300                         case 0x28:                      set_CFB(SUBB()); PutbackRMByte(m_dst);   break;
1301                         case 0x30:                      XORB(); PutbackRMByte(m_dst);   break;
1302                         case 0x38:                      set_CFB(SUBB());                         break;  /* CMP */
1303                         }
1304                         break;
1305                 }
1306
1307
1308                 case 0x81: // i_81pre
1309                 {
1310                         uint32_t tmpcf;
1311                         m_modrm = fetch();
1312                         m_dst = GetRMWord();
1313                         m_src = fetch_word();
1314                         if (m_modrm >=0xc0 )             { CLK(ALU_RI16); }
1315                         else if ((m_modrm & 0x38)==0x38) { CLK(ALU_MI16_RO); }
1316                         else                             { CLK(ALU_MI16); }
1317                         switch (m_modrm & 0x38)
1318                         {
1319                         case 0x00:                      set_CFW(ADDX()); PutbackRMWord(m_dst);   break;
1320                         case 0x08:                      ORW();  PutbackRMWord(m_dst);   break;
1321                         case 0x10: m_src += CF ? 1 : 0; tmpcf = ADDX(); PutbackRMWord(m_dst); set_CFW(tmpcf); break;
1322                         case 0x18: m_src += CF ? 1 : 0; tmpcf = SUBX(); PutbackRMWord(m_dst); set_CFW(tmpcf); break;
1323                         case 0x20:                      ANDX(); PutbackRMWord(m_dst);   break;
1324                         case 0x28:                      set_CFW(SUBX()); PutbackRMWord(m_dst);   break;
1325                         case 0x30:                      XORW(); PutbackRMWord(m_dst);   break;
1326                         case 0x38:                      set_CFW(SUBX());                         break;  /* CMP */
1327                         }
1328                         break;
1329                 }
1330
1331
1332                 case 0x82: // i_82pre
1333                 {
1334                         uint32_t tmpcf;
1335                         m_modrm = fetch();
1336                         m_dst = GetRMByte();
1337                         m_src = (int8_t)fetch();
1338                         if (m_modrm >=0xc0 )             { CLK(ALU_RI8); }
1339                         else if ((m_modrm & 0x38)==0x38) { CLK(ALU_MI8_RO); }
1340                         else                             { CLK(ALU_MI8); }
1341                         switch (m_modrm & 0x38)
1342                         {
1343                         case 0x00:                      set_CFB(ADDB()); PutbackRMByte(m_dst);   break;
1344                         case 0x08:                      ORB();  PutbackRMByte(m_dst);   break;
1345                         case 0x10: m_src += CF ? 1 : 0; tmpcf = ADDB(); PutbackRMByte(m_dst); set_CFB(tmpcf); break;
1346                         case 0x18: m_src += CF ? 1 : 0; tmpcf = SUBB(); PutbackRMByte(m_dst); set_CFB(tmpcf); break;
1347                         case 0x20:                      ANDB(); PutbackRMByte(m_dst);   break;
1348                         case 0x28:                      set_CFB(SUBB()); PutbackRMByte(m_dst);   break;
1349                         case 0x30:                      XORB(); PutbackRMByte(m_dst);   break;
1350                         case 0x38:                      set_CFB(SUBB());                         break; /* CMP */
1351                         }
1352                         break;
1353                 }
1354
1355
1356                 case 0x83: // i_83pre
1357                 {
1358                         uint32_t tmpcf;
1359                         m_modrm = fetch();
1360                         m_dst = GetRMWord();
1361                         m_src = (uint16_t)((int16_t)((int8_t)fetch()));
1362                         if (m_modrm >=0xc0 )             { CLK(ALU_R16I8); }
1363                         else if ((m_modrm & 0x38)==0x38) { CLK(ALU_M16I8_RO); }
1364                         else                             { CLK(ALU_M16I8); }
1365                         switch (m_modrm & 0x38)
1366                         {
1367                         case 0x00:                      set_CFW(ADDX()); PutbackRMWord(m_dst); break;
1368                         case 0x08:                      ORW();  PutbackRMWord(m_dst); break;
1369                         case 0x10: m_src += CF ? 1 : 0; tmpcf = ADDX(); PutbackRMWord(m_dst); set_CFW(tmpcf); break;
1370                         case 0x18: m_src += CF ? 1 : 0; tmpcf = SUBX(); PutbackRMWord(m_dst); set_CFW(tmpcf); break;
1371                         case 0x20:                      ANDX(); PutbackRMWord(m_dst); break;
1372                         case 0x28:                      set_CFW(SUBX()); PutbackRMWord(m_dst); break;
1373                         case 0x30:                      XORW(); PutbackRMWord(m_dst); break;
1374                         case 0x38:                      set_CFW(SUBX());                       break; /* CMP */
1375                         }
1376                         break;
1377                 }
1378
1379
1380                 case 0x84: // i_test_br8
1381                         DEF_br8();
1382                         ANDB();
1383                         CLKM(ALU_RR8,ALU_RM8);
1384                         break;
1385
1386                 case 0x85: // i_test_wr16
1387                         DEF_wr16();
1388                         ANDX();
1389                         CLKM(ALU_RR16,ALU_RM16);
1390                         break;
1391
1392                 case 0x86: // i_xchg_br8
1393                         DEF_br8();
1394                         RegByte(m_dst);
1395                         PutbackRMByte(m_src);
1396                         CLKM(XCHG_RR8,XCHG_RM8);
1397                         break;
1398
1399                 case 0x87: // i_xchg_wr16
1400                         DEF_wr16();
1401                         RegWord(m_dst);
1402                         PutbackRMWord(m_src);
1403                         CLKM(XCHG_RR16,XCHG_RM16);
1404                         break;
1405
1406
1407                 case 0x88: // i_mov_br8
1408                         m_modrm = fetch();
1409                         m_src = RegByte();
1410                         PutRMByte(m_src);
1411                         CLKM(ALU_RR8,ALU_MR8);
1412                         break;
1413
1414                 case 0x89: // i_mov_wr16
1415                         m_modrm = fetch();
1416                         m_src = RegWord();
1417                         PutRMWord(m_src);
1418                         CLKM(ALU_RR16,ALU_MR16);
1419                         break;
1420
1421                 case 0x8a: // i_mov_r8b
1422                         m_modrm = fetch();
1423                         m_src = GetRMByte();
1424                         RegByte(m_src);
1425                         CLKM(ALU_RR8,ALU_RM8);
1426                         break;
1427
1428                 case 0x8b: // i_mov_r16w
1429                         m_modrm = fetch();
1430                         m_src = GetRMWord();
1431                         RegWord(m_src);
1432                         CLKM(ALU_RR16,ALU_RM16);
1433                         break;
1434
1435                 case 0x8c: // i_mov_wsreg
1436                         m_modrm = fetch();
1437                         PutRMWord(m_sregs[(m_modrm & 0x18) >> 3]); // confirmed on hw: modrm bit 5 ignored
1438                         CLKM(MOV_RS,MOV_MS);
1439                         break;
1440
1441                 case 0x8d: // i_lea
1442                         m_modrm = fetch();
1443                         get_ea(0, I8086_NONE);
1444                         RegWord(m_eo);
1445                         CLK(LEA);
1446                         break;
1447
1448                 case 0x8e: // i_mov_sregw
1449                         m_modrm = fetch();
1450                         m_src = GetRMWord();
1451                         m_sregs[(m_modrm & 0x18) >> 3] = m_src; // confirmed on hw: modrm bit 5 ignored
1452                         CLKM(MOV_SR,MOV_SM);
1453                         m_no_interrupt = 1; // Disable IRQ after load segment register.
1454                         break;
1455
1456                 case 0x8f: // i_popw
1457                         m_modrm = fetch();
1458                         PutRMWord( POP() );
1459                         CLKM(POP_R16,POP_M16);
1460                         break;
1461
1462                 case 0x90: // i_nop
1463                         CLK(NOP);
1464                         break;
1465
1466                 case 0x91: // i_xchg_axcx
1467                         XchgAXReg(CX);
1468                         CLK(XCHG_AR16);
1469                         break;
1470
1471                 case 0x92: // i_xchg_axdx
1472                         XchgAXReg(DX);
1473                         CLK(XCHG_AR16);
1474                         break;
1475
1476                 case 0x93: // i_xchg_axbx
1477                         XchgAXReg(BX);
1478                         CLK(XCHG_AR16);
1479                         break;
1480
1481                 case 0x94: // i_xchg_axsp
1482                         XchgAXReg(SP);
1483                         CLK(XCHG_AR16);
1484                         break;
1485
1486                 case 0x95: // i_xchg_axbp
1487                         XchgAXReg(BP);
1488                         CLK(XCHG_AR16);
1489                         break;
1490
1491                 case 0x96: // i_xchg_axsi
1492                         XchgAXReg(SI);
1493                         CLK(XCHG_AR16);
1494                         break;
1495
1496                 case 0x97: // i_xchg_axdi
1497                         XchgAXReg(DI);
1498                         CLK(XCHG_AR16);
1499                         break;
1500
1501
1502                 case 0x98: // i_cbw
1503                         m_regs.b[AH] = (m_regs.b[AL] & 0x80) ? 0xff : 0;
1504                         CLK(CBW);
1505                         break;
1506
1507                 case 0x99: // i_cwd
1508                         m_regs.w[DX] = (m_regs.b[AH] & 0x80) ? 0xffff : 0;
1509                         CLK(CWD);
1510                         break;
1511
1512                 case 0x9a: // i_call_far
1513                         {
1514                                 uint16_t tmp = fetch_word();
1515                                 uint16_t tmp2 = fetch_word();
1516                                 PUSH(m_sregs[CS]);
1517                                 PUSH(m_ip);
1518                                 m_ip = tmp;
1519                                 m_sregs[CS] = tmp2;
1520                                 CLK(CALL_FAR);
1521                         }
1522                         break;
1523
1524                 case 0x9b: // i_wait
1525                         // Wait for assertion of /TEST
1526                         if (m_test_state == 0)
1527                         {
1528                                 m_icount = 0;
1529                                 m_ip--;
1530                         }
1531                         else
1532                                 CLK(WAIT);
1533                         break;
1534
1535                 case 0x9c: // i_pushf
1536                         PUSH( CompressFlags() );
1537                         CLK(PUSHF);
1538                         break;
1539
1540                 case 0x9d: // i_popf
1541                         i_popf();
1542                         break;
1543
1544                 case 0x9e: // i_sahf
1545                         {
1546                                 uint32_t tmp = (CompressFlags() & 0xff00) | (m_regs.b[AH] & 0xd5);
1547                                 ExpandFlags(tmp);
1548                                 CLK(SAHF);
1549                         }
1550                         break;
1551
1552                 case 0x9f: // i_lahf
1553                         m_regs.b[AH] = CompressFlags();
1554                         CLK(LAHF);
1555                         break;
1556
1557
1558                 case 0xa0: // i_mov_aldisp
1559                         {
1560                                 uint32_t addr = fetch_word();
1561                                 m_regs.b[AL] = GetMemB(DS, addr);
1562                                 CLK(MOV_AM8);
1563                         }
1564                         break;
1565
1566                 case 0xa1: // i_mov_axdisp
1567                         {
1568                                 uint32_t addr = fetch_word();
1569                                 m_regs.w[AX] = GetMemW(DS, addr);
1570                                 CLK(MOV_AM16);
1571                         }
1572                         break;
1573
1574                 case 0xa2: // i_mov_dispal
1575                         {
1576                                 uint32_t addr = fetch_word();
1577                                 PutMemB(DS, addr, m_regs.b[AL]);
1578                                 CLK(MOV_MA8);
1579                         }
1580                         break;
1581
1582                 case 0xa3: // i_mov_dispax
1583                         {
1584                                 uint32_t addr = fetch_word();
1585                                 PutMemW(DS, addr, m_regs.w[AX]);
1586                                 CLK(MOV_MA16);
1587                         }
1588                         break;
1589
1590                 case 0xa4: // i_movsb
1591                         i_movsb();
1592                         break;
1593
1594                 case 0xa5: // i_movsw
1595                         i_movsw();
1596                         break;
1597
1598                 case 0xa6: // i_cmpsb
1599                         i_cmpsb();
1600                         break;
1601
1602                 case 0xa7: // i_cmpsw
1603                         i_cmpsw();
1604                         break;
1605
1606
1607                 case 0xa8: // i_test_ald8
1608                         DEF_ald8();
1609                         ANDB();
1610                         CLK(ALU_RI8);
1611                         break;
1612
1613                 case 0xa9: // i_test_axd16
1614                         DEF_axd16();
1615                         ANDX();
1616                         CLK(ALU_RI16);
1617                         break;
1618
1619                 case 0xaa: // i_stosb
1620                         i_stosb();
1621                         break;
1622
1623                 case 0xab: // i_stosw
1624                         i_stosw();
1625                         break;
1626
1627                 case 0xac: // i_lodsb
1628                         i_lodsb();
1629                         break;
1630
1631                 case 0xad: // i_lodsw
1632                         i_lodsw();
1633                         break;
1634
1635                 case 0xae: // i_scasb
1636                         i_scasb();
1637                         break;
1638
1639                 case 0xaf: // i_scasw
1640                         i_scasw();
1641                         break;
1642
1643
1644                 case 0xb0: // i_mov_ald8
1645                         m_regs.b[AL] = fetch();
1646                         CLK(MOV_RI8);
1647                         break;
1648
1649                 case 0xb1: // i_mov_cld8
1650                         m_regs.b[CL] = fetch();
1651                         CLK(MOV_RI8);
1652                         break;
1653
1654                 case 0xb2: // i_mov_dld8
1655                         m_regs.b[DL] = fetch();
1656                         CLK(MOV_RI8);
1657                         break;
1658
1659                 case 0xb3: // i_mov_bld8
1660                         m_regs.b[BL] = fetch();
1661                         CLK(MOV_RI8);
1662                         break;
1663
1664                 case 0xb4: // i_mov_ahd8
1665                         m_regs.b[AH] = fetch();
1666                         CLK(MOV_RI8);
1667                         break;
1668
1669                 case 0xb5: // i_mov_chd8
1670                         m_regs.b[CH] = fetch();
1671                         CLK(MOV_RI8);
1672                         break;
1673
1674                 case 0xb6: // i_mov_dhd8
1675                         m_regs.b[DH] = fetch();
1676                         CLK(MOV_RI8);
1677                         break;
1678
1679                 case 0xb7: // i_mov_bhd8
1680                         m_regs.b[BH] = fetch();
1681                         CLK(MOV_RI8);
1682                         break;
1683
1684
1685                 case 0xb8: // i_mov_axd16
1686                         m_regs.b[AL] = fetch();
1687                         m_regs.b[AH] = fetch();
1688                         CLK(MOV_RI16);
1689                         break;
1690
1691                 case 0xb9: // i_mov_cxd16
1692                         m_regs.b[CL] = fetch();
1693                         m_regs.b[CH] = fetch();
1694                         CLK(MOV_RI16);
1695                         break;
1696
1697                 case 0xba: // i_mov_dxd16
1698                         m_regs.b[DL] = fetch();
1699                         m_regs.b[DH] = fetch();
1700                         CLK(MOV_RI16);
1701                         break;
1702
1703                 case 0xbb: // i_mov_bxd16
1704                         m_regs.b[BL] = fetch();
1705                         m_regs.b[BH] = fetch();
1706                         CLK(MOV_RI16);
1707                         break;
1708
1709                 case 0xbc: // i_mov_spd16
1710                         m_regs.b[SPL] = fetch();
1711                         m_regs.b[SPH] = fetch();
1712                         CLK(MOV_RI16);
1713                         break;
1714
1715                 case 0xbd: // i_mov_bpd16
1716                         m_regs.b[BPL] = fetch();
1717                         m_regs.b[BPH] = fetch();
1718                         CLK(MOV_RI16);
1719                         break;
1720
1721                 case 0xbe: // i_mov_sid16
1722                         m_regs.b[SIL] = fetch();
1723                         m_regs.b[SIH] = fetch();
1724                         CLK(MOV_RI16);
1725                         break;
1726
1727                 case 0xbf: // i_mov_did16
1728                         m_regs.b[DIL] = fetch();
1729                         m_regs.b[DIH] = fetch();
1730                         CLK(MOV_RI16);
1731                         break;
1732
1733                 case 0xc0: // 0xc0 is 0xc2 - see (*)
1734                 case 0xc2: // i_ret_d16
1735                         {
1736                                 uint32_t count = fetch_word();
1737                                 m_ip = POP();
1738                                 m_regs.w[SP] += count;
1739                                 CLK(RET_NEAR_IMM);
1740                         }
1741                         break;
1742
1743                 case 0xc1: // 0xc1 is 0xc3 - see (*)
1744                 case 0xc3: // i_ret
1745                         m_ip = POP();
1746                         CLK(RET_NEAR);
1747                         break;
1748
1749                 case 0xc4: // i_les_dw
1750                         m_modrm = fetch();
1751                         RegWord( GetRMWord() );
1752                         m_sregs[ES] = GetnextRMWord();
1753                         CLK(LOAD_PTR);
1754                         break;
1755
1756                 case 0xc5: // i_lds_dw
1757                         m_modrm = fetch();
1758                         RegWord( GetRMWord() );
1759                         m_sregs[DS] = GetnextRMWord();
1760                         CLK(LOAD_PTR);
1761                         break;
1762
1763                 case 0xc6: // i_mov_bd8
1764                         m_modrm = fetch();
1765                         PutImmRMByte();
1766                         CLKM(MOV_RI8,MOV_MI8);
1767                         break;
1768
1769                 case 0xc7: // i_mov_wd16
1770                         m_modrm = fetch();
1771                         PutImmRMWord();
1772                         CLKM(MOV_RI16,MOV_MI16);
1773                         break;
1774
1775                 case 0xc8: // 0xc8 = 0xca - see (*)
1776                 case 0xca: // i_retf_d16
1777                         {
1778                                 uint32_t count = fetch_word();
1779                                 m_ip = POP();
1780                                 m_sregs[CS] = POP();
1781                                 m_regs.w[SP] += count;
1782                                 CLK(RET_FAR_IMM);
1783                         }
1784                         break;
1785
1786                 case 0xc9: // 0xc9 = 0xcb  - see (*)
1787                 case 0xcb: // i_retf
1788                         m_ip = POP();
1789                         m_sregs[CS] = POP();
1790                         CLK(RET_FAR);
1791                         break;
1792
1793                 case 0xcc: // i_int3
1794                         interrupt(3, 0);
1795                         CLK(INT3);
1796                         break;
1797
1798                 case 0xcd: // i_int
1799                         interrupt(fetch(), 0);
1800                         CLK(INT_IMM);
1801                         break;
1802
1803                 case 0xce: // i_into
1804                         if (OF)
1805                         {
1806                                 interrupt(4, 0);
1807                                 CLK(INTO_T);
1808                         }
1809                         else
1810                                 CLK(INTO_NT);
1811                         break;
1812
1813                 case 0xcf: // i_iret
1814                         m_ip = POP();
1815                         m_sregs[CS] = POP();
1816                         i_popf();
1817                         CLK(IRET);
1818                         break;
1819
1820                 case 0xd0: // i_rotshft_b
1821                         m_modrm = fetch();
1822                         m_src = GetRMByte();
1823                         m_dst = m_src;
1824                         CLKM(ROT_REG_1,ROT_M8_1);
1825                         switch ( m_modrm & 0x38 )
1826                         {
1827                         case 0x00: ROL_BYTE();  PutbackRMByte(m_dst); m_OverVal = (m_src ^ m_dst) & 0x80; break;
1828                         case 0x08: ROR_BYTE();  PutbackRMByte(m_dst); m_OverVal = (m_src ^ m_dst) & 0x80; break;
1829                         case 0x10: ROLC_BYTE(); PutbackRMByte(m_dst); m_OverVal = (m_src ^ m_dst) & 0x80; break;
1830                         case 0x18: RORC_BYTE(); PutbackRMByte(m_dst); m_OverVal = (m_src ^ m_dst) & 0x80; break;
1831                         case 0x30:
1832                         case 0x20: SHL_BYTE(1); m_OverVal = (m_src ^ m_dst) & 0x80; break;
1833                         case 0x28: SHR_BYTE(1); m_OverVal = (m_src ^ m_dst) & 0x80; break;
1834                         case 0x38: SHRA_BYTE(1); m_OverVal = 0; break;
1835                         }
1836                         break;
1837
1838                 case 0xd1: // i_rotshft_w
1839                         m_modrm = fetch();
1840                         m_src = GetRMWord();
1841                         m_dst = m_src;
1842                         CLKM(ROT_REG_1,ROT_M8_1);
1843                         switch ( m_modrm & 0x38 )
1844                         {
1845                         case 0x00: ROL_WORD();  PutbackRMWord(m_dst); m_OverVal = (m_src ^ m_dst) & 0x8000; break;
1846                         case 0x08: ROR_WORD();  PutbackRMWord(m_dst); m_OverVal = (m_src ^ m_dst) & 0x8000; break;
1847                         case 0x10: ROLC_WORD(); PutbackRMWord(m_dst); m_OverVal = (m_src ^ m_dst) & 0x8000; break;
1848                         case 0x18: RORC_WORD(); PutbackRMWord(m_dst); m_OverVal = (m_src ^ m_dst) & 0x8000; break;
1849                         case 0x30:
1850                         case 0x20: SHL_WORD(1); m_OverVal = (m_src ^ m_dst) & 0x8000;  break;
1851                         case 0x28: SHR_WORD(1); m_OverVal = (m_src ^ m_dst) & 0x8000;  break;
1852                         case 0x38: SHRA_WORD(1); m_OverVal = 0; break;
1853                         }
1854                         break;
1855
1856                 case 0xd4: // i_aam
1857                 {
1858                         uint8_t base = fetch();
1859                         if(!base)
1860                         {
1861                                 interrupt(0);
1862                                 break;
1863                         }
1864                         m_regs.b[AH] = m_regs.b[AL] / base;
1865                         m_regs.b[AL] %= base;
1866                         set_SZPF_Word(m_regs.w[AX]);
1867                         CLK(AAM);
1868                         break;
1869                 }
1870
1871                 case 0xd5: // i_aad
1872                 {
1873                         uint8_t base = fetch();
1874                         m_regs.b[AL] = m_regs.b[AH] * base + m_regs.b[AL];
1875                         m_regs.b[AH] = 0;
1876                         set_SZPF_Byte(m_regs.b[AL]);
1877                         CLK(AAD);
1878                         break;
1879                 }
1880
1881                 case 0xd6: // i_salc
1882                         m_regs.b[AL] = (CF ? 0xff : 0);
1883                         CLK(ALU_RR8);  // is sbb al,al
1884                         break;
1885
1886                 case 0xd7: // i_trans
1887                         m_regs.b[AL] = GetMemB( DS, m_regs.w[BX] + m_regs.b[AL] );
1888                         CLK(XLAT);
1889                         break;
1890
1891                 case 0xd8: // i_esc
1892                 case 0xd9:
1893                 case 0xda:
1894                 case 0xdb:
1895                 case 0xdc:
1896                 case 0xdd:
1897                 case 0xde:
1898                 case 0xdf:
1899                         m_modrm = fetch();
1900                         GetRMByte();
1901                         CLK(NOP);
1902                         logerror("%06x: Unimplemented floating point escape %02x%02x\n", pc(), op, m_modrm);
1903                         break;
1904
1905
1906                 case 0xe0: // i_loopne
1907                         {
1908                                 int8_t disp = (int8_t)fetch();
1909
1910                                 m_regs.w[CX]--;
1911                                 if (!ZF && m_regs.w[CX])
1912                                 {
1913                                         m_ip = m_ip + disp;
1914                                         CLK(LOOP_T);
1915                                 }
1916                                 else
1917                                         CLK(LOOP_NT);
1918                         }
1919                         break;
1920
1921                 case 0xe1: // i_loope
1922                         {
1923                                 int8_t disp = (int8_t)fetch();
1924
1925                                 m_regs.w[CX]--;
1926                                 if (ZF && m_regs.w[CX])
1927                                 {
1928                                         m_ip = m_ip + disp;
1929                                         CLK(LOOPE_T);
1930                                 }
1931                                 else
1932                                         CLK(LOOPE_NT);
1933                         }
1934                         break;
1935
1936                 case 0xe2: // i_loop
1937                         {
1938                                 int8_t disp = (int8_t)fetch();
1939
1940                                 m_regs.w[CX]--;
1941                                 if (m_regs.w[CX])
1942                                 {
1943                                         m_ip = m_ip + disp;
1944                                         CLK(LOOP_T);
1945                                 }
1946                                 else
1947                                         CLK(LOOP_NT);
1948                         }
1949                         break;
1950
1951                 case 0xe3: // i_jcxz
1952                         {
1953                                 int8_t disp = (int8_t)fetch();
1954
1955                                 if (m_regs.w[CX] == 0)
1956                                 {
1957                                         m_ip = m_ip + disp;
1958                                         CLK(JCXZ_T);
1959                                 }
1960                                 else
1961                                         CLK(JCXZ_NT);
1962                         }
1963                         break;
1964
1965                 case 0xe4: // i_inal
1966                         if (m_lock) m_lock_handler(1);
1967                         m_regs.b[AL] = read_port_byte( fetch() );
1968                         if (m_lock) { m_lock_handler(0); m_lock = false; }
1969                         CLK(IN_IMM8);
1970                         break;
1971
1972                 case 0xe5: // i_inax
1973                         {
1974                                 uint8_t port = fetch();
1975
1976                                 m_regs.w[AX] = read_port_word(port);
1977                                 CLK(IN_IMM16);
1978                         }
1979                         break;
1980
1981                 case 0xe6: // i_outal
1982                         write_port_byte( fetch(), m_regs.b[AL]);
1983                         CLK(OUT_IMM8);
1984                         break;
1985
1986                 case 0xe7: // i_outax
1987                         {
1988                                 uint8_t port = fetch();
1989
1990                                 write_port_word(port, m_regs.w[AX]);
1991                                 CLK(OUT_IMM16);
1992                         }
1993                         break;
1994
1995
1996                 case 0xe8: // i_call_d16
1997                         {
1998                                 int16_t tmp = (int16_t)fetch_word();
1999
2000                                 PUSH(m_ip);
2001                                 m_ip = m_ip + tmp;
2002                                 CLK(CALL_NEAR);
2003                         }
2004                         break;
2005
2006                 case 0xe9: // i_jmp_d16
2007                         {
2008                                 int16_t offset = (int16_t)fetch_word();
2009                                 m_ip += offset;
2010                                 CLK(JMP_NEAR);
2011                         }
2012                         break;
2013
2014                 case 0xea: // i_jmp_far
2015                         {
2016                                 uint16_t tmp = fetch_word();
2017                                 uint16_t tmp1 = fetch_word();
2018
2019                                 m_sregs[CS] = tmp1;
2020                                 m_ip = tmp;
2021                                 CLK(JMP_FAR);
2022                         }
2023                         break;
2024
2025                 case 0xeb: // i_jmp_d8
2026                         {
2027                                 int tmp = (int)((int8_t)fetch());
2028
2029                                 CLK(JMP_SHORT);
2030                                 if (tmp==-2 && m_no_interrupt==0 && (m_pending_irq==0) && m_icount>0)
2031                                 {
2032                                         m_icount%=12; /* cycle skip */
2033                                 }
2034                                 m_ip = (uint16_t)(m_ip+tmp);
2035                         }
2036                         break;
2037
2038                 case 0xec: // i_inaldx
2039                         m_regs.b[AL] = read_port_byte(m_regs.w[DX]);
2040                         CLK(IN_DX8);
2041                         break;
2042
2043                 case 0xed: // i_inaxdx
2044                         {
2045                                 uint32_t port = m_regs.w[DX];
2046
2047                                 m_regs.w[AX] = read_port_word(port);
2048                                 CLK(IN_DX16);
2049                         }
2050                         break;
2051
2052                 case 0xee: // i_outdxal
2053                         write_port_byte(m_regs.w[DX], m_regs.b[AL]);
2054                         CLK(OUT_DX8);
2055                         break;
2056
2057                 case 0xef: // i_outdxax
2058                         {
2059                                 uint32_t port = m_regs.w[DX];
2060
2061                                 write_port_word(port, m_regs.w[AX]);
2062                                 CLK(OUT_DX16);
2063                         }
2064                         break;
2065
2066
2067                 case 0xf0: // i_lock
2068                 case 0xf1: // 0xf1 is 0xf0; verified on real CPU
2069                         logerror("%06x: Warning - BUSLOCK\n", pc());
2070                         m_lock = true;
2071                         m_no_interrupt = 1;
2072                         CLK(NOP);
2073                         break;
2074
2075                 case 0xf2: // i_repne
2076                         {
2077                                 bool invalid = false;
2078                                 uint8_t next = repx_op();
2079                                 uint16_t c = m_regs.w[CX];
2080
2081                                 switch (next)
2082                                 {
2083                                 case 0xa4:  CLK(OVERRIDE); if (c) do { i_movsb(); c--; } while (c>0 && m_icount>0);          m_regs.w[CX]=c; m_seg_prefix = false; m_seg_prefix_next = false; break;
2084                                 case 0xa5:  CLK(OVERRIDE); if (c) do { i_movsw(); c--; } while (c>0 && m_icount>0);          m_regs.w[CX]=c; m_seg_prefix = false; m_seg_prefix_next = false; break;
2085                                 case 0xa6:  CLK(OVERRIDE); if (c) do { i_cmpsb(); c--; } while (c>0 && !ZF && m_icount>0);   m_regs.w[CX]=c; m_seg_prefix = false; m_seg_prefix_next = false; break;
2086                                 case 0xa7:  CLK(OVERRIDE); if (c) do { i_cmpsw(); c--; } while (c>0 && !ZF && m_icount>0);   m_regs.w[CX]=c; m_seg_prefix = false; m_seg_prefix_next = false; break;
2087                                 case 0xaa:  CLK(OVERRIDE); if (c) do { i_stosb(); c--; } while (c>0 && m_icount>0);          m_regs.w[CX]=c; m_seg_prefix = false; m_seg_prefix_next = false; break;
2088                                 case 0xab:  CLK(OVERRIDE); if (c) do { i_stosw(); c--; } while (c>0 && m_icount>0);          m_regs.w[CX]=c; m_seg_prefix = false; m_seg_prefix_next = false; break;
2089                                 case 0xac:  CLK(OVERRIDE); if (c) do { i_lodsb(); c--; } while (c>0 && m_icount>0);          m_regs.w[CX]=c; m_seg_prefix = false; m_seg_prefix_next = false; break;
2090                                 case 0xad:  CLK(OVERRIDE); if (c) do { i_lodsw(); c--; } while (c>0 && m_icount>0);          m_regs.w[CX]=c; m_seg_prefix = false; m_seg_prefix_next = false; break;
2091                                 case 0xae:  CLK(OVERRIDE); if (c) do { i_scasb(); c--; } while (c>0 && !ZF && m_icount>0);   m_regs.w[CX]=c; m_seg_prefix = false; m_seg_prefix_next = false; break;
2092                                 case 0xaf:  CLK(OVERRIDE); if (c) do { i_scasw(); c--; } while (c>0 && !ZF && m_icount>0);   m_regs.w[CX]=c; m_seg_prefix = false; m_seg_prefix_next = false; break;
2093                                 default:
2094                                         logerror("%06x: REPNE invalid\n", pc());
2095                                         // Decrement IP so the normal instruction will be executed next
2096                                         m_ip--;
2097                                         invalid = true;
2098                                         break;
2099                                 }
2100                                 if(c && !invalid)
2101                                 {
2102                                         if(!(ZF && ((next & 6) == 6)))
2103                                                 m_ip = m_prev_ip;
2104                                 }
2105                         }
2106                         break;
2107
2108                 case 0xf3: // i_repe
2109                         {
2110                                 bool invalid = false;
2111                                 uint8_t next = repx_op();
2112                                 uint16_t c = m_regs.w[CX];
2113
2114                                 switch (next)
2115                                 {
2116                                 case 0xa4:  CLK(OVERRIDE); if (c) do { i_movsb(); c--; } while (c>0 && m_icount>0);          m_regs.w[CX]=c; m_seg_prefix = false; m_seg_prefix_next = false; break;
2117                                 case 0xa5:  CLK(OVERRIDE); if (c) do { i_movsw(); c--; } while (c>0 && m_icount>0);          m_regs.w[CX]=c; m_seg_prefix = false; m_seg_prefix_next = false; break;
2118                                 case 0xa6:  CLK(OVERRIDE); if (c) do { i_cmpsb(); c--; } while (c>0 && ZF && m_icount>0);    m_regs.w[CX]=c; m_seg_prefix = false; m_seg_prefix_next = false; break;
2119                                 case 0xa7:  CLK(OVERRIDE); if (c) do { i_cmpsw(); c--; } while (c>0 && ZF && m_icount>0);    m_regs.w[CX]=c; m_seg_prefix = false; m_seg_prefix_next = false; break;
2120                                 case 0xaa:  CLK(OVERRIDE); if (c) do { i_stosb(); c--; } while (c>0 && m_icount>0);          m_regs.w[CX]=c; m_seg_prefix = false; m_seg_prefix_next = false; break;
2121                                 case 0xab:  CLK(OVERRIDE); if (c) do { i_stosw(); c--; } while (c>0 && m_icount>0);          m_regs.w[CX]=c; m_seg_prefix = false; m_seg_prefix_next = false; break;
2122                                 case 0xac:  CLK(OVERRIDE); if (c) do { i_lodsb(); c--; } while (c>0 && m_icount>0);          m_regs.w[CX]=c; m_seg_prefix = false; m_seg_prefix_next = false; break;
2123                                 case 0xad:  CLK(OVERRIDE); if (c) do { i_lodsw(); c--; } while (c>0 && m_icount>0);          m_regs.w[CX]=c; m_seg_prefix = false; m_seg_prefix_next = false; break;
2124                                 case 0xae:  CLK(OVERRIDE); if (c) do { i_scasb(); c--; } while (c>0 && ZF && m_icount>0);    m_regs.w[CX]=c; m_seg_prefix = false; m_seg_prefix_next = false; break;
2125                                 case 0xaf:  CLK(OVERRIDE); if (c) do { i_scasw(); c--; } while (c>0 && ZF && m_icount>0);    m_regs.w[CX]=c; m_seg_prefix = false; m_seg_prefix_next = false; break;
2126                                 default:
2127                                         logerror("%06x: REPE invalid\n", pc());
2128                                         // Decrement IP so the normal instruction will be executed next
2129                                         m_ip--;
2130                                         invalid = true;
2131                                         break;
2132                                 }
2133                                 if(c && !invalid)
2134                                 {
2135                                         if(!(!ZF && ((next & 6) == 6)))
2136                                                 m_ip = m_prev_ip;
2137                                 }
2138                         }
2139                         break;
2140
2141                 case 0xf4: // i_hlt
2142                         //logerror("%s: %06x: HALT\n", tag(), pc());
2143                         m_icount = 0;
2144                         m_halt = true;
2145                         break;
2146
2147                 case 0xf5: // i_cmc
2148                         m_CarryVal = !m_CarryVal;
2149                         CLK(FLAG_OPS);
2150                         break;
2151
2152                 case 0xf6: // i_f6pre
2153                         {
2154                                 uint32_t tmp;
2155                                 uint32_t uresult,uresult2;
2156                                 int32_t result,result2;
2157
2158                                 m_modrm = fetch();
2159                                 tmp = GetRMByte();
2160                                 switch ( m_modrm & 0x38 )
2161                                 {
2162                                 case 0x00:  /* TEST */
2163                                 case 0x08:  /* TEST (alias) */
2164                                         tmp &= fetch();
2165                                         m_CarryVal = m_OverVal = 0;
2166                                         set_SZPF_Byte(tmp);
2167                                         CLKM(ALU_RI8,ALU_MI8_RO);
2168                                         break;
2169                                 case 0x10:  /* NOT */
2170                                         PutbackRMByte(~tmp);
2171                                         CLKM(NEGNOT_R8,NEGNOT_M8);
2172                                         break;
2173                                 case 0x18:  /* NEG */
2174                                         m_CarryVal = (tmp!=0) ? 1 : 0;
2175                                         tmp = (~tmp)+1;
2176                                         set_SZPF_Byte(tmp);
2177                                         PutbackRMByte(tmp&0xff);
2178                                         CLKM(NEGNOT_R8,NEGNOT_M8);
2179                                         break;
2180                                 case 0x20:  /* MUL */
2181                                         uresult = m_regs.b[AL] * tmp;
2182                                         m_regs.w[AX] = (uint16_t)uresult;
2183                                         m_CarryVal = m_OverVal = (m_regs.b[AH]!=0) ? 1 : 0;
2184                                         set_ZF(m_regs.w[AX]);
2185                                         CLKM(MUL_R8,MUL_M8);
2186                                         break;
2187                                 case 0x28:  /* IMUL */
2188                                         result = (int16_t)((int8_t)m_regs.b[AL])*(int16_t)((int8_t)tmp);
2189                                         m_regs.w[AX] = (uint16_t)result;
2190                                         m_CarryVal = m_OverVal = (m_regs.b[AH]!=0) ? 1 : 0;
2191                                         set_ZF(m_regs.w[AX]);
2192                                         CLKM(IMUL_R8,IMUL_M8);
2193                                         break;
2194                                 case 0x30:  /* DIV */
2195                                         if (tmp)
2196                                         {
2197                                                 uresult = m_regs.w[AX];
2198                                                 uresult2 = uresult % tmp;
2199                                                 if ((uresult /= tmp) > 0xff)
2200                                                 {
2201                                                         interrupt(0);
2202                                                 }
2203                                                 else
2204                                                 {
2205                                                         m_regs.b[AL] = uresult;
2206                                                         m_regs.b[AH] = uresult2;
2207                                                 }
2208                                         }
2209                                         else
2210                                         {
2211                                                 interrupt(0);
2212                                         }
2213                                         CLKM(DIV_R8,DIV_M8);
2214                                         break;
2215                                 case 0x38:  /* IDIV */
2216                                         if (tmp)
2217                                         {
2218                                                 result = (int16_t)m_regs.w[AX];
2219                                                 result2 = result % (int16_t)((int8_t)tmp);
2220                                                 if ((result /= (int16_t)((int8_t)tmp)) > 0xff)
2221                                                 {
2222                                                         interrupt(0);
2223                                                 }
2224                                                 else
2225                                                 {
2226                                                         m_regs.b[AL] = result;
2227                                                         m_regs.b[AH] = result2;
2228                                                 }
2229                                         }
2230                                         else
2231                                         {
2232                                                 interrupt(0);
2233                                         }
2234                                         CLKM(IDIV_R8,IDIV_M8);
2235                                         break;
2236                                 }
2237                         }
2238                         break;
2239
2240
2241                 case 0xf7: // i_f7pre
2242                         {
2243                                 uint32_t tmp,tmp2;
2244                                 uint32_t uresult,uresult2;
2245                                 int32_t result,result2;
2246
2247                                 m_modrm = fetch();
2248                                 tmp = GetRMWord();
2249                                 switch ( m_modrm & 0x38 )
2250                                 {
2251                                 case 0x00:  /* TEST */
2252                                 case 0x08:  /* TEST (alias) */
2253                                         tmp2 = fetch_word();
2254                                         tmp &= tmp2;
2255                                         m_CarryVal = m_OverVal = 0;
2256                                         set_SZPF_Word(tmp);
2257                                         CLKM(ALU_RI16,ALU_MI16_RO);
2258                                         break;
2259                                 case 0x10:  /* NOT */
2260                                         PutbackRMWord(~tmp);
2261                                         CLKM(NEGNOT_R16,NEGNOT_M16);
2262                                         break;
2263                                 case 0x18:  /* NEG */
2264                                         m_CarryVal = (tmp!=0) ? 1 : 0;
2265                                         tmp = (~tmp) + 1;
2266                                         set_SZPF_Word(tmp);
2267                                         PutbackRMWord(tmp);
2268                                         CLKM(NEGNOT_R16,NEGNOT_M16);
2269                                         break;
2270                                 case 0x20:  /* MUL */
2271                                         uresult = m_regs.w[AX]*tmp;
2272                                         m_regs.w[AX] = uresult & 0xffff;
2273                                         m_regs.w[DX] = ((uint32_t)uresult)>>16;
2274                                         m_CarryVal = m_OverVal = (m_regs.w[DX] != 0) ? 1 : 0;
2275                                         set_ZF(m_regs.w[AX] | m_regs.w[DX]);
2276                                         CLKM(MUL_R16,MUL_M16);
2277                                         break;
2278                                 case 0x28:  /* IMUL */
2279                                         result = (int32_t)((int16_t)m_regs.w[AX]) * (int32_t)((int16_t)tmp);
2280                                         m_regs.w[AX] = result & 0xffff;
2281                                         m_regs.w[DX] = result >> 16;
2282                                         m_CarryVal = m_OverVal = (m_regs.w[DX] != 0) ? 1 : 0;
2283                                         set_ZF(m_regs.w[AX] | m_regs.w[DX]);
2284                                         CLKM(IMUL_R16,IMUL_M16);
2285                                         break;
2286                                 case 0x30:  /* DIV */
2287                                         if (tmp)
2288                                         {
2289                                                 uresult = (((uint32_t)m_regs.w[DX]) << 16) | m_regs.w[AX];
2290                                                 uresult2 = uresult % tmp;
2291                                                 if ((uresult /= tmp) > 0xffff)
2292                                                 {
2293                                                         interrupt(0);
2294                                                 }
2295                                                 else
2296                                                 {
2297                                                         m_regs.w[AX] = uresult;
2298                                                         m_regs.w[DX] = uresult2;
2299                                                 }
2300                                         }
2301                                         else
2302                                         {
2303                                                 interrupt(0);
2304                                         }
2305                                         CLKM(DIV_R16,DIV_M16);
2306                                         break;
2307                                 case 0x38:  /* IDIV */
2308                                         if (tmp)
2309                                         {
2310                                                 result = ((uint32_t)m_regs.w[DX] << 16) + m_regs.w[AX];
2311                                                 result2 = result % (int32_t)((int16_t)tmp);
2312                                                 if ((result /= (int32_t)((int16_t)tmp)) > 0xffff)
2313                                                 {
2314                                                         interrupt(0);
2315                                                 }
2316                                                 else
2317                                                 {
2318                                                         m_regs.w[AX] = result;
2319                                                         m_regs.w[DX] = result2;
2320                                                 }
2321                                         }
2322                                         else
2323                                         {
2324                                                 interrupt(0);
2325                                         }
2326                                         CLKM(IDIV_R16,IDIV_M16);
2327                                         break;
2328                                 }
2329                         }
2330                         break;
2331
2332
2333                 case 0xf8: // i_clc
2334                         m_CarryVal = 0;
2335                         CLK(FLAG_OPS);
2336                         break;
2337
2338                 case 0xf9: // i_stc
2339                         m_CarryVal = 1;
2340                         CLK(FLAG_OPS);
2341                         break;
2342
2343                 case 0xfa: // i_cli
2344                         m_IF = 0;
2345                         CLK(FLAG_OPS);
2346                         break;
2347
2348                 case 0xfb: // i_sti
2349                         m_IF = 1;
2350                         CLK(FLAG_OPS);
2351                         break;
2352
2353                 case 0xfc: // i_cld
2354                         m_DF = 0;
2355                         CLK(FLAG_OPS);
2356                         break;
2357
2358                 case 0xfd: // i_std
2359                         m_DF = 1;
2360                         CLK(FLAG_OPS);
2361                         break;
2362
2363                 case 0xfe: // i_fepre
2364                         {
2365                                 uint32_t tmp, tmp1;
2366                                 m_modrm = fetch();
2367                                 tmp = GetRMByte();
2368                                 switch ( m_modrm & 0x38 )
2369                                 {
2370                                 case 0x00:  /* INC */
2371                                         tmp1 = tmp+1;
2372                                         m_OverVal = (tmp==0x7f);
2373                                         set_AF(tmp1,tmp,1);
2374                                         set_SZPF_Byte(tmp1);
2375                                         PutbackRMByte(tmp1);
2376                                         CLKM(INCDEC_R8,INCDEC_M8);
2377                                         break;
2378                                 case 0x08:  /* DEC */
2379                                         tmp1 = tmp-1;
2380                                         m_OverVal = (tmp==0x80);
2381                                         set_AF(tmp1,tmp,1);
2382                                         set_SZPF_Byte(tmp1);
2383                                         PutbackRMByte(tmp1);
2384                                         CLKM(INCDEC_R8,INCDEC_M8);
2385                                         break;
2386                                 default:
2387                                         logerror("%06x: FE Pre with unimplemented mod\n", pc());
2388                                         break;
2389                                 }
2390                         }
2391                         break;
2392
2393                 case 0xff: // i_ffpre
2394                         {
2395                                 uint32_t tmp, tmp1;
2396                                 m_modrm = fetch();
2397                                 tmp = GetRMWord();
2398                                 switch ( m_modrm & 0x38 )
2399                                 {
2400                                 case 0x00:  /* INC */
2401                                         tmp1 = tmp+1;
2402                                         m_OverVal = (tmp==0x7fff);
2403                                         set_AF(tmp1,tmp,1);
2404                                         set_SZPF_Word(tmp1);
2405                                         PutbackRMWord(tmp1);
2406                                         CLKM(INCDEC_R16,INCDEC_M16);
2407                                         break;
2408                                 case 0x08:  /* DEC */
2409                                         tmp1 = tmp-1;
2410                                         m_OverVal = (tmp==0x8000);
2411                                         set_AF(tmp1,tmp,1);
2412                                         set_SZPF_Word(tmp1);
2413                                         PutbackRMWord(tmp1);
2414                                         CLKM(INCDEC_R16,INCDEC_M16);
2415                                         break;
2416                                 case 0x10:  /* CALL */
2417                                         PUSH(m_ip);
2418                                         m_ip = tmp;
2419                                         CLKM(CALL_R16,CALL_M16);
2420                                         break;
2421                                 case 0x18:  /* CALL FAR */
2422                                         tmp1 = m_sregs[CS];
2423                                         m_sregs[CS] = GetnextRMWord();
2424                                         PUSH(tmp1);
2425                                         PUSH(m_ip);
2426                                         m_ip = tmp;
2427                                         CLK(CALL_M32);
2428                                         break;
2429                                 case 0x20:  /* JMP */
2430                                         m_ip = tmp;
2431                                         CLKM(JMP_R16,JMP_M16);
2432                                         break;
2433                                 case 0x28:  /* JMP FAR */
2434                                         m_ip = tmp;
2435                                         m_sregs[CS] = GetnextRMWord();
2436                                         CLK(JMP_M32);
2437                                         break;
2438                                 case 0x30:
2439                                         PUSH(tmp);
2440                                         CLKM(PUSH_R16,PUSH_M16);
2441                                         break;
2442                                 default:
2443                                         logerror("%06x: FF Pre with unimplemented mod\n", pc());
2444                                         break;
2445                                 }
2446                         }
2447                         break;
2448                 default:
2449                         return false;
2450         }
2451         return true;
2452 }