--- /dev/null
+#ifndef __NEWDEV_LIBX86_EA_H__
+#define __NEWDEV_LIBX86_EA_H__
+unsigned X86_OPS_BASE::EA_000() { cpustate->icount-=7; cpustate->eo=(WORD)(cpustate->regs.w[BX]+cpustate->regs.w[SI]); cpustate->ea_seg=DefaultSeg(DS); cpustate->ea=DefaultBase(DS)+cpustate->eo; return cpustate->ea; }
+unsigned X86_OPS_BASE::EA_001() { cpustate->icount-=8; cpustate->eo=(WORD)(cpustate->regs.w[BX]+cpustate->regs.w[DI]); cpustate->ea_seg=DefaultSeg(DS); cpustate->ea=DefaultBase(DS)+cpustate->eo; return cpustate->ea; }
+unsigned X86_OPS_BASE::EA_002() { cpustate->icount-=8; cpustate->eo=(WORD)(cpustate->regs.w[BP]+cpustate->regs.w[SI]); cpustate->ea_seg=DefaultSeg(SS); cpustate->ea=DefaultBase(SS)+cpustate->eo; return cpustate->ea; }
+unsigned X86_OPS_BASE::EA_003() { cpustate->icount-=7; cpustate->eo=(WORD)(cpustate->regs.w[BP]+cpustate->regs.w[DI]); cpustate->ea_seg=DefaultSeg(SS); cpustate->ea=DefaultBase(SS)+cpustate->eo; return cpustate->ea; }
+unsigned X86_OPS_BASE::EA_004() { cpustate->icount-=5; cpustate->eo=cpustate->regs.w[SI]; cpustate->ea_seg=DefaultSeg(DS); cpustate->ea=DefaultBase(DS)+cpustate->eo; return cpustate->ea; }
+unsigned X86_OPS_BASE::EA_005() { cpustate->icount-=5; cpustate->eo=cpustate->regs.w[DI]; cpustate->ea_seg=DefaultSeg(DS); cpustate->ea=DefaultBase(DS)+cpustate->eo; return cpustate->ea; }
+unsigned X86_OPS_BASE::EA_006() { cpustate->icount-=6; cpustate->eo=FETCHOP; cpustate->eo+=FETCHOP<<8; cpustate->ea_seg=DefaultSeg(DS); cpustate->ea=DefaultBase(DS)+cpustate->eo; return cpustate->ea; }
+unsigned X86_OPS_BASE::EA_007() { cpustate->icount-=5; cpustate->eo=cpustate->regs.w[BX]; cpustate->ea_seg=DefaultSeg(DS); cpustate->ea=DefaultBase(DS)+cpustate->eo; return cpustate->ea; }
+
+unsigned X86_OPS_BASE::EA_100() { cpustate->icount-=11; cpustate->eo=(WORD)(cpustate->regs.w[BX]+cpustate->regs.w[SI]+(INT8)FETCHOP); cpustate->ea_seg=DefaultSeg(DS); cpustate->ea=DefaultBase(DS)+cpustate->eo; return cpustate->ea; }
+unsigned X86_OPS_BASE::EA_101() { cpustate->icount-=12; cpustate->eo=(WORD)(cpustate->regs.w[BX]+cpustate->regs.w[DI]+(INT8)FETCHOP); cpustate->ea_seg=DefaultSeg(DS); cpustate->ea=DefaultBase(DS)+cpustate->eo; return cpustate->ea; }
+unsigned X86_OPS_BASE::EA_102() { cpustate->icount-=12; cpustate->eo=(WORD)(cpustate->regs.w[BP]+cpustate->regs.w[SI]+(INT8)FETCHOP); cpustate->ea_seg=DefaultSeg(SS); cpustate->ea=DefaultBase(SS)+cpustate->eo; return cpustate->ea; }
+unsigned X86_OPS_BASE::EA_103() { cpustate->icount-=11; cpustate->eo=(WORD)(cpustate->regs.w[BP]+cpustate->regs.w[DI]+(INT8)FETCHOP); cpustate->ea_seg=DefaultSeg(SS); cpustate->ea=DefaultBase(SS)+cpustate->eo; return cpustate->ea; }
+unsigned X86_OPS_BASE::EA_104() { cpustate->icount-=9; cpustate->eo=(WORD)(cpustate->regs.w[SI]+(INT8)FETCHOP); cpustate->ea_seg=DefaultSeg(DS); cpustate->ea=DefaultBase(DS)+cpustate->eo; return cpustate->ea; }
+unsigned X86_OPS_BASE::EA_105() { cpustate->icount-=9; cpustate->eo=(WORD)(cpustate->regs.w[DI]+(INT8)FETCHOP); cpustate->ea_seg=DefaultSeg(DS); cpustate->ea=DefaultBase(DS)+cpustate->eo; return cpustate->ea; }
+unsigned X86_OPS_BASE::EA_106() { cpustate->icount-=9; cpustate->eo=(WORD)(cpustate->regs.w[BP]+(INT8)FETCHOP); cpustate->ea_seg=DefaultSeg(SS); cpustate->ea=DefaultBase(SS)+cpustate->eo; return cpustate->ea; }
+unsigned X86_OPS_BASE::EA_107() { cpustate->icount-=9; cpustate->eo=(WORD)(cpustate->regs.w[BX]+(INT8)FETCHOP); cpustate->ea_seg=DefaultSeg(DS); cpustate->ea=DefaultBase(DS)+cpustate->eo; return cpustate->ea; }
+
+unsigned X86_OPS_BASE::EA_200() { cpustate->icount-=11; cpustate->eo=FETCHOP; cpustate->eo+=FETCHOP<<8; cpustate->eo+=cpustate->regs.w[BX]+cpustate->regs.w[SI]; cpustate->ea_seg=DefaultSeg(DS); cpustate->ea=DefaultBase(DS)+(WORD)cpustate->eo; return cpustate->ea; }
+unsigned X86_OPS_BASE::EA_201() { cpustate->icount-=12; cpustate->eo=FETCHOP; cpustate->eo+=FETCHOP<<8; cpustate->eo+=cpustate->regs.w[BX]+cpustate->regs.w[DI]; cpustate->ea_seg=DefaultSeg(DS); cpustate->ea=DefaultBase(DS)+(WORD)cpustate->eo; return cpustate->ea; }
+unsigned X86_OPS_BASE::EA_202() { cpustate->icount-=12; cpustate->eo=FETCHOP; cpustate->eo+=FETCHOP<<8; cpustate->eo+=cpustate->regs.w[BP]+cpustate->regs.w[SI]; cpustate->ea_seg=DefaultSeg(SS); cpustate->ea=DefaultBase(SS)+(WORD)cpustate->eo; return cpustate->ea; }
+unsigned X86_OPS_BASE::EA_203() { cpustate->icount-=11; cpustate->eo=FETCHOP; cpustate->eo+=FETCHOP<<8; cpustate->eo+=cpustate->regs.w[BP]+cpustate->regs.w[DI]; cpustate->ea_seg=DefaultSeg(SS); cpustate->ea=DefaultBase(SS)+(WORD)cpustate->eo; return cpustate->ea; }
+unsigned X86_OPS_BASE::EA_204() { cpustate->icount-=9; cpustate->eo=FETCHOP; cpustate->eo+=FETCHOP<<8; cpustate->eo+=cpustate->regs.w[SI]; cpustate->ea_seg=DefaultSeg(DS); cpustate->ea=DefaultBase(DS)+(WORD)cpustate->eo; return cpustate->ea; }
+unsigned X86_OPS_BASE::EA_205() { cpustate->icount-=9; cpustate->eo=FETCHOP; cpustate->eo+=FETCHOP<<8; cpustate->eo+=cpustate->regs.w[DI]; cpustate->ea_seg=DefaultSeg(DS); cpustate->ea=DefaultBase(DS)+(WORD)cpustate->eo; return cpustate->ea; }
+unsigned X86_OPS_BASE::EA_206() { cpustate->icount-=9; cpustate->eo=FETCHOP; cpustate->eo+=FETCHOP<<8; cpustate->eo+=cpustate->regs.w[BP]; cpustate->ea_seg=DefaultSeg(SS); cpustate->ea=DefaultBase(SS)+(WORD)cpustate->eo; return cpustate->ea; }
+unsigned X86_OPS_BASE::EA_207() { cpustate->icount-=9; cpustate->eo=FETCHOP; cpustate->eo+=FETCHOP<<8; cpustate->eo+=cpustate->regs.w[BX]; cpustate->ea_seg=DefaultSeg(DS); cpustate->ea=DefaultBase(DS)+(WORD)cpustate->eo; return cpustate->ea; }
+
+unsigned (X86_OPS_BASE::*GetEA[192])()={
+ &X86_OPS_BASE::EA_000, &X86_OPS_BASE::EA_001, &X86_OPS_BASE::EA_002, &X86_OPS_BASE::EA_003, &X86_OPS_BASE::EA_004, &X86_OPS_BASE::EA_005, &X86_OPS_BASE::EA_006, &X86_OPS_BASE::EA_007,
+ &X86_OPS_BASE::EA_000, &X86_OPS_BASE::EA_001, &X86_OPS_BASE::EA_002, &X86_OPS_BASE::EA_003, &X86_OPS_BASE::EA_004, &X86_OPS_BASE::EA_005, &X86_OPS_BASE::EA_006, &X86_OPS_BASE::EA_007,
+ &X86_OPS_BASE::EA_000, &X86_OPS_BASE::EA_001, &X86_OPS_BASE::EA_002, &X86_OPS_BASE::EA_003, &X86_OPS_BASE::EA_004, &X86_OPS_BASE::EA_005, &X86_OPS_BASE::EA_006, &X86_OPS_BASE::EA_007,
+ &X86_OPS_BASE::EA_000, &X86_OPS_BASE::EA_001, &X86_OPS_BASE::EA_002, &X86_OPS_BASE::EA_003, &X86_OPS_BASE::EA_004, &X86_OPS_BASE::EA_005, &X86_OPS_BASE::EA_006, &X86_OPS_BASE::EA_007,
+ &X86_OPS_BASE::EA_000, &X86_OPS_BASE::EA_001, &X86_OPS_BASE::EA_002, &X86_OPS_BASE::EA_003, &X86_OPS_BASE::EA_004, &X86_OPS_BASE::EA_005, &X86_OPS_BASE::EA_006, &X86_OPS_BASE::EA_007,
+ &X86_OPS_BASE::EA_000, &X86_OPS_BASE::EA_001, &X86_OPS_BASE::EA_002, &X86_OPS_BASE::EA_003, &X86_OPS_BASE::EA_004, &X86_OPS_BASE::EA_005, &X86_OPS_BASE::EA_006, &X86_OPS_BASE::EA_007,
+ &X86_OPS_BASE::EA_000, &X86_OPS_BASE::EA_001, &X86_OPS_BASE::EA_002, &X86_OPS_BASE::EA_003, &X86_OPS_BASE::EA_004, &X86_OPS_BASE::EA_005, &X86_OPS_BASE::EA_006, &X86_OPS_BASE::EA_007,
+ &X86_OPS_BASE::EA_000, &X86_OPS_BASE::EA_001, &X86_OPS_BASE::EA_002, &X86_OPS_BASE::EA_003, &X86_OPS_BASE::EA_004, &X86_OPS_BASE::EA_005, &X86_OPS_BASE::EA_006, &X86_OPS_BASE::EA_007,
+
+ &X86_OPS_BASE::EA_100, &X86_OPS_BASE::EA_101, &X86_OPS_BASE::EA_102, &X86_OPS_BASE::EA_103, &X86_OPS_BASE::EA_104, &X86_OPS_BASE::EA_105, &X86_OPS_BASE::EA_106, &X86_OPS_BASE::EA_107,
+ &X86_OPS_BASE::EA_100, &X86_OPS_BASE::EA_101, &X86_OPS_BASE::EA_102, &X86_OPS_BASE::EA_103, &X86_OPS_BASE::EA_104, &X86_OPS_BASE::EA_105, &X86_OPS_BASE::EA_106, &X86_OPS_BASE::EA_107,
+ &X86_OPS_BASE::EA_100, &X86_OPS_BASE::EA_101, &X86_OPS_BASE::EA_102, &X86_OPS_BASE::EA_103, &X86_OPS_BASE::EA_104, &X86_OPS_BASE::EA_105, &X86_OPS_BASE::EA_106, &X86_OPS_BASE::EA_107,
+ &X86_OPS_BASE::EA_100, &X86_OPS_BASE::EA_101, &X86_OPS_BASE::EA_102, &X86_OPS_BASE::EA_103, &X86_OPS_BASE::EA_104, &X86_OPS_BASE::EA_105, &X86_OPS_BASE::EA_106, &X86_OPS_BASE::EA_107,
+ &X86_OPS_BASE::EA_100, &X86_OPS_BASE::EA_101, &X86_OPS_BASE::EA_102, &X86_OPS_BASE::EA_103, &X86_OPS_BASE::EA_104, &X86_OPS_BASE::EA_105, &X86_OPS_BASE::EA_106, &X86_OPS_BASE::EA_107,
+ &X86_OPS_BASE::EA_100, &X86_OPS_BASE::EA_101, &X86_OPS_BASE::EA_102, &X86_OPS_BASE::EA_103, &X86_OPS_BASE::EA_104, &X86_OPS_BASE::EA_105, &X86_OPS_BASE::EA_106, &X86_OPS_BASE::EA_107,
+ &X86_OPS_BASE::EA_100, &X86_OPS_BASE::EA_101, &X86_OPS_BASE::EA_102, &X86_OPS_BASE::EA_103, &X86_OPS_BASE::EA_104, &X86_OPS_BASE::EA_105, &X86_OPS_BASE::EA_106, &X86_OPS_BASE::EA_107,
+ &X86_OPS_BASE::EA_100, &X86_OPS_BASE::EA_101, &X86_OPS_BASE::EA_102, &X86_OPS_BASE::EA_103, &X86_OPS_BASE::EA_104, &X86_OPS_BASE::EA_105, &X86_OPS_BASE::EA_106, &X86_OPS_BASE::EA_107,
+
+ &X86_OPS_BASE::EA_200, &X86_OPS_BASE::EA_201, &X86_OPS_BASE::EA_202, &X86_OPS_BASE::EA_203, &X86_OPS_BASE::EA_204, &X86_OPS_BASE::EA_205, &X86_OPS_BASE::EA_206, &X86_OPS_BASE::EA_207,
+ &X86_OPS_BASE::EA_200, &X86_OPS_BASE::EA_201, &X86_OPS_BASE::EA_202, &X86_OPS_BASE::EA_203, &X86_OPS_BASE::EA_204, &X86_OPS_BASE::EA_205, &X86_OPS_BASE::EA_206, &X86_OPS_BASE::EA_207,
+ &X86_OPS_BASE::EA_200, &X86_OPS_BASE::EA_201, &X86_OPS_BASE::EA_202, &X86_OPS_BASE::EA_203, &X86_OPS_BASE::EA_204, &X86_OPS_BASE::EA_205, &X86_OPS_BASE::EA_206, &X86_OPS_BASE::EA_207,
+ &X86_OPS_BASE::EA_200, &X86_OPS_BASE::EA_201, &X86_OPS_BASE::EA_202, &X86_OPS_BASE::EA_203, &X86_OPS_BASE::EA_204, &X86_OPS_BASE::EA_205, &X86_OPS_BASE::EA_206, &X86_OPS_BASE::EA_207,
+ &X86_OPS_BASE::EA_200, &X86_OPS_BASE::EA_201, &X86_OPS_BASE::EA_202, &X86_OPS_BASE::EA_203, &X86_OPS_BASE::EA_204, &X86_OPS_BASE::EA_205, &X86_OPS_BASE::EA_206, &X86_OPS_BASE::EA_207,
+ &X86_OPS_BASE::EA_200, &X86_OPS_BASE::EA_201, &X86_OPS_BASE::EA_202, &X86_OPS_BASE::EA_203, &X86_OPS_BASE::EA_204, &X86_OPS_BASE::EA_205, &X86_OPS_BASE::EA_206, &X86_OPS_BASE::EA_207,
+ &X86_OPS_BASE::EA_200, &X86_OPS_BASE::EA_201, &X86_OPS_BASE::EA_202, &X86_OPS_BASE::EA_203, &X86_OPS_BASE::EA_204, &X86_OPS_BASE::EA_205, &X86_OPS_BASE::EA_206, &X86_OPS_BASE::EA_207,
+ &X86_OPS_BASE::EA_200, &X86_OPS_BASE::EA_201, &X86_OPS_BASE::EA_202, &X86_OPS_BASE::EA_203, &X86_OPS_BASE::EA_204, &X86_OPS_BASE::EA_205, &X86_OPS_BASE::EA_206, &X86_OPS_BASE::EA_207
+};
+#endif
\ No newline at end of file
--- /dev/null
+/*****************************************************************************/
+/* host dependent types */
+
+
+/*#define BIGCASE*/
+
+
+typedef UINT8 BOOLEAN;
+
+typedef UINT8 BYTE;
+typedef UINT16 WORD;
+typedef UINT32 DWORD;
--- /dev/null
+/* ASG 971222 -- rewrote this interface */
+#pragma once
+
+#ifndef __I286INTF_H__
+#define __I286INTF_H__
+
+#include "./i86.h"
+
+#define TRAP(fault, code) (UINT32)(((fault&0xffff)<<16)|(code&0xffff))
+
+#endif /* __I286INTF_H__ */
--- /dev/null
+/****************************************************************************
+* real mode i286 emulator v1.4 by Fabrice Frances *
+* (initial work based on David Hedley's pcemu) *
+****************************************************************************/
+
+//#include "emu.h"
+//#include "debugger.h"
+//#include "host.h"
+
+
+#define VERBOSE 0
+#define LOG(x) do { if (VERBOSE) mame_printf_debug x; } while (0)
+
+/* All post-i286 CPUs have a 16MB address space */
+#define AMASK cpustate->amask
+
+
+#define INPUT_LINE_A20 1
+
+#include "i286.h"
+//#include "i86time.c"
+
+#define INT_IRQ 0x01
+#define NMI_IRQ 0x02
+
+/***************************************************************************/
+
+//#define I80286
+#include "./i86priv.h"
+//#define PREFIX(fname) i80286##fname
+//#define PREFIX86(fname) i80286##fname
+//#define PREFIX186(fname) i80286##fname
+//#define PREFIX286(fname) i80286##fname
+//#define i8086_state i80286_state
+//#include "./ea.h"
+#include "./modrm286.h"
+//#include "./instr86.h"
+//#include "./instr186.h"
+//#include "./instr286.h"
+#include "./table286.h"
+//#include "instr86.c"
+//#include "instr186.c"
+//#include "instr286.c"
+
+void X86_OPS_BASE::i80286_urinit(void)
+{
+ unsigned int i,j,c;
+ static const BREGS reg_name[8]={ AL, CL, DL, BL, AH, CH, DH, BH };
+
+ for (i = 0;i < 256; i++)
+ {
+ for (j = i, c = 0; j > 0; j >>= 1)
+ if (j & 1) c++;
+
+ parity_table[i] = !(c & 1);
+ }
+
+ for (i = 0; i < 256; i++)
+ {
+ Mod_RM.reg.b[i] = reg_name[(i & 0x38) >> 3];
+ Mod_RM.reg.w[i] = (WREGS) ( (i & 0x38) >> 3) ;
+ }
+
+ for (i = 0xc0; i < 0x100; i++)
+ {
+ Mod_RM.RM.w[i] = (WREGS)( i & 7 );
+ Mod_RM.RM.b[i] = (BREGS)reg_name[i & 7];
+ }
+}
+
+void X86_OPS_BASE::i80286_set_a20_line(int state)
+{
+ cpustate->amask = state ? 0x00ffffff : 0x000fffff;
+}
+
+void X86_OPS_BASE::cpu_reset_i80286()
+{
+ memset(&cpustate->regs, 0, sizeof(i80286basicregs));
+ cpustate->sregs[CS] = 0xf000;
+ cpustate->base[CS] = 0xff0000;
+// /* temporary, until I have the right reset vector working */
+// cpustate->base[CS] = cpustate->sregs[CS] << 4;
+// cpustate->pc = 0xffff0;
+ cpustate->pc = 0xfffff0;
+ cpustate->limit[CS]=cpustate->limit[SS]=cpustate->limit[DS]=cpustate->limit[ES]=0xffff;
+ cpustate->sregs[DS]=cpustate->sregs[SS]=cpustate->sregs[ES]=0;
+ cpustate->base[DS]=cpustate->base[SS]=cpustate->base[ES]=0;
+ cpustate->rights[DS]=cpustate->rights[SS]=cpustate->rights[ES]=0x93;
+ cpustate->rights[CS]=0x9a;
+ cpustate->valid[CS]=cpustate->valid[SS]=cpustate->valid[DS]=cpustate->valid[ES]=1;
+ cpustate->msw=0xfff0;
+ cpustate->flags=2;
+ ExpandFlags(cpustate->flags);
+ cpustate->idtr.base=0;cpustate->idtr.limit=0x3ff;
+ cpustate->gdtr.base=cpustate->ldtr.base=cpustate->tr.base=0;
+ cpustate->gdtr.limit=cpustate->ldtr.limit=cpustate->tr.limit=0;
+ cpustate->ldtr.rights=cpustate->tr.rights=0;
+ cpustate->ldtr.sel=cpustate->tr.sel=0;
+ cpustate->rep_in_progress = FALSE;
+ cpustate->seg_prefix = FALSE;
+
+ CHANGE_PC(cpustate->pc);
+
+ cpustate->icount = cpustate->extra_cycles = 0;
+ cpustate->halted = 0;
+}
+
+/****************************************************************************/
+
+/* ASG 971222 -- added these interface functions */
+
+void X86_OPS_BASE::set_irq_line_286(int irqline, int state)
+{
+ if (state != CLEAR_LINE && cpustate->halted)
+ {
+ cpustate->halted = 0;
+ }
+ try
+ {
+ if (irqline == INPUT_LINE_NMI)
+ {
+ if (cpustate->nmi_state == state)
+ return;
+ cpustate->nmi_state = state;
+
+ /* on a rising edge, signal the NMI */
+ if (state != CLEAR_LINE) {
+ i80286_interrupt_descriptor(cpustate, I8086_NMI_INT_VECTOR, 2, -1);
+ cpustate->nmi_state = CLEAR_LINE;
+ }
+ }
+ else
+ {
+ cpustate->irq_state = state;
+
+ /* if the IF is set, signal an interrupt */
+ if (state != CLEAR_LINE && cpustate->IF) {
+ i80286_interrupt_descriptor(cpustate, cpustate->pic->get_intr_ack(), 2, -1);
+ cpustate->irq_state = CLEAR_LINE;
+ }
+ }
+ }
+ catch (UINT32 e)
+ {
+ i80286_trap2(cpustate, e);
+ }
+}
+
+void X86_OPS_BASE::CPU_EXECUTE( i80286 )
+{
+ if (cpustate->halted || cpustate->busreq)
+ {
+ if (icount == -1) {
+ int passed_icount = max(1, cpustate->extra_cycles);
+ // this is main cpu, cpustate->icount is not used
+ /*cpustate->icount = */cpustate->extra_cycles = 0;
+ return passed_icount;
+ } else {
+ cpustate->icount += icount;
+ int base_icount = cpustate->icount;
+
+ /* adjust for any interrupts that came in */
+ cpustate->icount -= cpustate->extra_cycles;
+ cpustate->extra_cycles = 0;
+
+ /* if busreq is raised, spin cpu while remained clock */
+ if (cpustate->icount > 0) {
+ cpustate->icount = 0;
+ }
+ return base_icount - cpustate->icount;
+ }
+ }
+
+ if (icount == -1) {
+ cpustate->icount = 1;
+ } else {
+ cpustate->icount += icount;
+ }
+ int base_icount = cpustate->icount;
+
+ /* copy over the cycle counts if they're not correct */
+ if (timing.id != 80286)
+ timing = i80286_cycles;
+
+ /* adjust for any interrupts that came in */
+ cpustate->icount -= cpustate->extra_cycles;
+ cpustate->extra_cycles = 0;
+
+ /* run until we're out */
+ while(cpustate->icount > 0 && !cpustate->busreq)
+ {
+ cpustate->seg_prefix=FALSE;
+ try
+ {
+ if (PM && ((cpustate->pc-cpustate->base[CS]) > cpustate->limit[CS]))
+ throw TRAP(GENERAL_PROTECTION_FAULT, cpustate->sregs[CS] & ~3);
+ cpustate->prevpc = cpustate->pc;
+
+ TABLE286 // call instruction
+ }
+ catch (UINT32 e)
+ {
+ i80286_trap2(cpustate,e);
+ }
+ /* adjust for any interrupts that came in */
+ cpustate->icount -= cpustate->extra_cycles;
+ cpustate->extra_cycles = 0;
+ }
+
+ /* if busreq is raised, spin cpu while remained clock */
+ if (cpustate->icount > 0 && cpustate->busreq) {
+ cpustate->icount = 0;
+ }
+ return base_icount - cpustate->icount;
+}
+
+i86_state *X86_OPS_BASE::cpu_init_i80286()
+{
+ cpustate = (i80286_state *)calloc(1, sizeof(i80286_state));
+ cpustate->amask = 0xfffff;
+ i80286_urinit();
+ return cpustate;
+}
+
+//#undef I80286
--- /dev/null
+/* ASG 971222 -- rewrote this interface */
+#pragma once
+
+#ifndef __I86INTF_H__
+#define __I86INTF_H__
+
+
+#define INPUT_LINE_INT0 INPUT_LINE_IRQ0
+#define INPUT_LINE_INT1 INPUT_LINE_IRQ1
+#define INPUT_LINE_INT2 INPUT_LINE_IRQ2
+#define INPUT_LINE_INT3 INPUT_LINE_IRQ3
+#define INPUT_LINE_TEST 20 /* PJB 03/05 */
+#define INPUT_LINE_DRQ0 21
+#define INPUT_LINE_DRQ1 22
+#define INPUT_LINE_TMRIN0 23
+#define INPUT_LINE_TMRIN1 24
+
+#endif /* __I86INTF_H__ */
--- /dev/null
+intel 8086 and compatibles
+--------------------------
+
+this info is here,
+to list and give some remarks on all 8086 compatible processors
+
+excellent info in Hamarsoft's 86BUGS list
+(also distributed in ralf browns interrupt list)
+
+8086/8088
+---------
+20 bit address bus, 16 bit data bus and registers
+many 8080 assembler sources should be compilable/reusable
+
+8086
+----
+6 bytes prefetch queue
+
+8088
+----
+8086 with 8 bit data bus,
+prefetch queue only 4 byte, and refilled when 1 byte empty
+
+early 8086/8088 revisions bug
+-----------------------------
+(copyright 1978 on package)
+mov sreg, doesnot disable until next operation is executed
+
+8086/8088
+---------
+"mov cs, " causes unconditional jump!
+
+80C86/80C88
+-----------
+"mov cs, " ignored
+
+80186/80188
+-----------
+integrated pic8259, pit8253, dma8253 (but not at standard pc addresses)
+additional instructions
+"mov cs, " ?
+shift count anded with 0x1f
+
+80188
+-----
+8bit data bus
+
+NEC series
+----------
+80186 instruction set, additional nec instructions
+although it is based on 80186 instruction set, some behaviours follow 8086
+8080 emulation mode
+"mov cs, " ignored
+shift count not anded (acts like 8086)
+
+NEC 70116 (V30)
+---------------
+8086 pin compatible
+
+NEC 70108 (V20)
+---------------
+8088 pinout
+
+NEC V30MX
+---------
+on die ems hardware
+24 bit address but for ems memory!?
+no 8080 emulation mode
+
+NEC V40
+-------
+pinout, integrated peripherals as 80186
+
+NEC V50
+-------
+pinout, integrated peripherals as 80188
+
+NEC V33?
+--------
+speed optimized V30?
+
+NEC V25/V35?
+------------
+
+NEC V25+/V35+?
+--------------
+
+NEC V60/V70
+-----------
+risc (misc/delux) like instruction set
+v30? emulation mode (without 8080 emulation mode)
+
+80286
+-----
+80186 with additional instructions
+24 bit address bus,
+protected mode
+
+80386 and later
+---------------
+not covered here
+
+8087/80287/80387/80387sx
+------------------------
+mathematical coprocessors
+
+weitek, iit variants
+
+in 80486 coprocessor integrated
+(except 80486sx and several clones)
+80487: 80486 with other pinout
--- /dev/null
+/****************************************************************************
+* real mode i286 emulator v1.4 by Fabrice Frances *
+* (initial work based on David Hedley's pcemu) *
+****************************************************************************/
+/* 26.March 2000 PeT changed set_irq_line */
+
+//#include "emu.h"
+//#include "debugger.h"
+
+//#include "host.h"
+#include "i86priv.h"
+#include "i86.h"
+
+//extern int i386_dasm_one(_TCHAR *buffer, UINT32 eip, const UINT8 *oprom, int mode);
+
+#define VERBOSE 0
+#define LOG(x) do { if (VERBOSE) mame_printf_debug x; } while (0)
+
+
+/* All pre-i286 CPUs have a 1MB address space */
+#define AMASK 0xfffff
+
+
+//#include "i86time.c"
+
+/***************************************************************************/
+/* cpu state */
+/***************************************************************************/
+
+/* The interrupt number of a pending external interrupt pending NMI is 2. */
+/* For INTR interrupts, the level is caught on the bus during an INTA cycle */
+
+//#define PREFIX(name) i8086##name
+//#define PREFIX86(name) i8086##name
+
+//#define I8086
+//#include "./instr86.h"
+#include "./ea.h"
+#include "./modrm.h"
+#include "./table86.h"
+
+//#include "instr86.c"
+//#undef I8086
+
+
+/***************************************************************************/
+i8086_state *X86_OPS_BASE::cpu_init_i8086()
+{
+ cpustate = (i8086_state *)calloc(1, sizeof(i8086_state));
+ unsigned int i, j, c;
+ static const BREGS reg_name[8] = {AL, CL, DL, BL, AH, CH, DH, BH};
+ for (i = 0; i < 256; i++)
+ {
+ for (j = i, c = 0; j > 0; j >>= 1)
+ if (j & 1)
+ c++;
+
+ parity_table[i] = !(c & 1);
+ }
+
+ for (i = 0; i < 256; i++)
+ {
+ Mod_RM.reg.b[i] = reg_name[(i & 0x38) >> 3];
+ Mod_RM.reg.w[i] = (WREGS) ((i & 0x38) >> 3);
+ }
+
+ for (i = 0xc0; i < 0x100; i++)
+ {
+ Mod_RM.RM.w[i] = (WREGS) (i & 7);
+ Mod_RM.RM.b[i] = (BREGS) reg_name[i & 7];
+ }
+
+ return cpustate;
+}
+
+i8086_state *X86_OPS_BASE::cpu_init_i8088()
+{
+ return cpu_init_i8086()
+}
+
+i8086_state *X86_OPS_BASE::cpu_init_i80186()
+{
+ return cpu_init_i8086()
+
+}
+
+i8086_state *X86_OPS_BASE::cpu_init_v30()
+{
+ return cpu_init_i8086()
+}
+
+void X86_OPS_BASE::CPU_RESET( i8086 )
+{
+ memset(cpustate, 0, sizeof(*cpustate));
+
+ cpustate->sregs[CS] = 0xffff;
+ cpustate->base[CS] = SegBase(CS);
+ cpustate->pc = 0xffff0 & AMASK;
+ ExpandFlags(cpustate->flags);
+
+ cpustate->halted = 0;
+}
+
+void X86_OPS_BASE::CPU_RESET( i8088 )
+{
+ CPU_RESET_CALL(i8086);
+}
+
+void X86_OPS_BASE::CPU_RESET( i80186 )
+{
+ CPU_RESET_CALL(i8086);
+}
+
+void X86_OPS_BASE::CPU_RESET( v30 )
+{
+ CPU_RESET_CALL(i8086);
+ SetMD(1);
+}
+
+/* ASG 971222 -- added these interface functions */
+
+void X86_OPS_BASE::set_irq_line_86(int irqline, int state)
+{
+ if (state != CLEAR_LINE && cpustate->halted)
+ {
+ cpustate->halted = 0;
+ }
+
+ if (irqline == INPUT_LINE_NMI)
+ {
+ if (cpustate->nmi_state == state)
+ return;
+ cpustate->nmi_state = state;
+
+ /* on a rising edge, signal the NMI */
+ if (state != CLEAR_LINE)
+ {
+ PREFIX86(_interrupt)(cpustate, I8086_NMI_INT_VECTOR);
+ cpustate->nmi_state = CLEAR_LINE;
+ }
+ }
+ else
+ {
+ cpustate->irq_state = state;
+
+ /* if the IF is set, signal an interrupt */
+ if (state != CLEAR_LINE && cpustate->IF) {
+ PREFIXV30(_interrupt)(cpustate, (UINT32)-1);
+ cpustate->irq_state = CLEAR_LINE;
+ }
+ }
+}
+
+void X86_OPS_BASE::set_drq_line_86(int irqline, int state)
+{
+ // TODO implement me
+}
+
+void X86_OPS_BASE::set_tmrin_line_86(i8086_state *cpustate, int irqline, int state)
+{
+ // TODO implement me
+}
+
+/* PJB 03/05 */
+void X86_OPS_BASE::set_test_line_86(i8086_state *cpustate, int state)
+{
+ cpustate->test_state = !state;
+}
+
+void X86_OPS_BASE::CPU_EXECUTE( i8086 )
+{
+ if (cpustate->halted || cpustate->busreq)
+ {
+ if (icount == -1) {
+ int passed_icount = max(1, cpustate->extra_cycles);
+ // this is main cpu, cpustate->icount is not used
+ /*cpustate->icount = */cpustate->extra_cycles = 0;
+ return passed_icount;
+ } else {
+ cpustate->icount += icount;
+ int base_icount = cpustate->icount;
+
+ /* adjust for any interrupts that came in */
+ cpustate->icount -= cpustate->extra_cycles;
+ cpustate->extra_cycles = 0;
+
+ /* if busreq is raised, spin cpu while remained clock */
+ if (cpustate->icount > 0) {
+ cpustate->icount = 0;
+ }
+ return base_icount - cpustate->icount;
+ }
+ }
+
+ if (icount == -1) {
+ cpustate->icount = 1;
+ } else {
+ cpustate->icount += icount;
+ }
+ int base_icount = cpustate->icount;
+
+ /* copy over the cycle counts if they're not correct */
+ if (timing.id != 8086)
+ timing = i8086_cycles;
+
+ /* adjust for any interrupts that came in */
+ cpustate->icount -= cpustate->extra_cycles;
+ cpustate->extra_cycles = 0;
+
+ /* run until we're out */
+ while (cpustate->icount > 0 && !cpustate->busreq)
+ {
+ cpustate->seg_prefix = FALSE;
+ cpustate->prevpc = cpustate->pc;
+ TABLE86;
+ /* adjust for any interrupts that came in */
+ cpustate->icount -= cpustate->extra_cycles;
+ cpustate->extra_cycles = 0;
+ }
+
+ /* if busreq is raised, spin cpu while remained clock */
+ if (cpustate->icount > 0 && cpustate->busreq) {
+ cpustate->icount = 0;
+ }
+ return base_icount - cpustate->icount;
+}
+
+void X86_OPS_BASE::CPU_EXECUTE( i8088 )
+{
+ return CPU_EXECUTE_CALL(i8086);
+}
+
+//#include "i86.h"
+
+//#undef PREFIX
+//#define PREFIX(name) i80186##name
+//#define PREFIX186(name) i80186##name
+
+//#define I80186
+//#include "instr186.h"
+#include "table186.h"
+
+//#include "instr86.c"
+//#include "instr186.c"
+//#undef I80186
+
+void X86_OPS_BASE::CPU_EXECUTE( i80186 )
+{
+ if (cpustate->halted || cpustate->busreq)
+ {
+ if (icount == -1) {
+ int passed_icount = max(1, cpustate->extra_cycles);
+ // this is main cpu, cpustate->icount is not used
+ /*cpustate->icount = */cpustate->extra_cycles = 0;
+ return passed_icount;
+ } else {
+ cpustate->icount += icount;
+ int base_icount = cpustate->icount;
+
+ /* adjust for any interrupts that came in */
+ cpustate->icount -= cpustate->extra_cycles;
+ cpustate->extra_cycles = 0;
+
+ /* if busreq is raised, spin cpu while remained clock */
+ if (cpustate->icount > 0) {
+ cpustate->icount = 0;
+ }
+ return base_icount - cpustate->icount;
+ }
+ }
+
+ if (icount == -1) {
+ cpustate->icount = 1;
+ } else {
+ cpustate->icount += icount;
+ }
+ int base_icount = cpustate->icount;
+
+ /* copy over the cycle counts if they're not correct */
+ if (timing.id != 80186)
+ timing = i80186_cycles;
+
+ /* adjust for any interrupts that came in */
+ cpustate->icount -= cpustate->extra_cycles;
+ cpustate->extra_cycles = 0;
+
+ /* run until we're out */
+ while (cpustate->icount > 0 && !cpustate->busreq)
+ {
+ cpustate->seg_prefix = FALSE;
+ cpustate->prevpc = cpustate->pc;
+ TABLE186;
+ /* adjust for any interrupts that came in */
+ cpustate->icount -= cpustate->extra_cycles;
+ cpustate->extra_cycles = 0;
+ }
+
+ /* if busreq is raised, spin cpu while remained clock */
+ if (cpustate->icount > 0 && cpustate->busreq) {
+ cpustate->icount = 0;
+ }
+ return base_icount - cpustate->icount;
+}
+void X86_OPS_BASE::set_irq_line_186(int irqline, int state)
+{
+ if (state != CLEAR_LINE && cpustate->halted)
+ {
+ cpustate->halted = 0;
+ }
+
+ if (irqline == INPUT_LINE_NMI)
+ {
+ if (cpustate->nmi_state == state)
+ return;
+ cpustate->nmi_state = state;
+
+ /* on a rising edge, signal the NMI */
+ if (state != CLEAR_LINE)
+ {
+ PREFIX186(_interrupt)(cpustate, I8086_NMI_INT_VECTOR);
+ cpustate->nmi_state = CLEAR_LINE;
+ }
+ }
+ else
+ {
+ cpustate->irq_state = state;
+
+ /* if the IF is set, signal an interrupt */
+ if (state != CLEAR_LINE && cpustate->IF) {
+ PREFIX186(_interrupt)(cpustate, (UINT32)-1);
+ cpustate->irq_state = CLEAR_LINE;
+ }
+ }
+}
+
+
+//#include "i86.h"
+
+//#undef PREFIX
+//#define PREFIX(name) v30##name
+//#define PREFIXV30(name) v30##name
+
+//#define I80186
+//#include "instrv30.h"
+#include "tablev30.h"
+
+//#include "instr86.c"
+//#include "instrv30.c"
+//#undef I80186
+
+void X86_OPS_BASE::CPU_EXECUTE( v30 )
+{
+ if (cpustate->halted || cpustate->busreq)
+ {
+ if (icount == -1) {
+ int passed_icount = max(1, cpustate->extra_cycles);
+ // this is main cpu, cpustate->icount is not used
+ /*cpustate->icount = */cpustate->extra_cycles = 0;
+ return passed_icount;
+ } else {
+ cpustate->icount += icount;
+ int base_icount = cpustate->icount;
+
+ /* adjust for any interrupts that came in */
+ cpustate->icount -= cpustate->extra_cycles;
+ cpustate->extra_cycles = 0;
+
+ /* if busreq is raised, spin cpu while remained clock */
+ if (cpustate->icount > 0) {
+ cpustate->icount = 0;
+ }
+ return base_icount - cpustate->icount;
+ }
+ }
+
+ if (icount == -1) {
+ cpustate->icount = 1;
+ } else {
+ cpustate->icount += icount;
+ }
+ int base_icount = cpustate->icount;
+
+ /* copy over the cycle counts if they're not correct */
+ if (timing.id != 80186)
+ timing = i80186_cycles;
+
+ /* adjust for any interrupts that came in */
+ cpustate->icount -= cpustate->extra_cycles;
+ cpustate->extra_cycles = 0;
+
+ /* run until we're out */
+ while (cpustate->icount > 0 && !cpustate->busreq)
+ {
+ cpustate->seg_prefix = FALSE;
+ cpustate->prevpc = cpustate->pc;
+ TABLEV30;
+ /* adjust for any interrupts that came in */
+ cpustate->icount -= cpustate->extra_cycles;
+ cpustate->extra_cycles = 0;
+ }
+
+ /* if busreq is raised, spin cpu while remained clock */
+ if (cpustate->icount > 0 && cpustate->busreq) {
+ cpustate->icount = 0;
+ }
+ return base_icount - cpustate->icount;
+}
+
+void X86_OPS_BASE::set_irq_line_v30(int irqline, int state)
+{
+ if (state != CLEAR_LINE && cpustate->halted)
+ {
+ cpustate->halted = 0;
+ }
+
+ if (irqline == INPUT_LINE_NMI)
+ {
+ if (cpustate->nmi_state == state)
+ return;
+ cpustate->nmi_state = state;
+
+ /* on a rising edge, signal the NMI */
+ if (state != CLEAR_LINE)
+ {
+ PREFIXV30(_interrupt)(cpustate, I8086_NMI_INT_VECTOR);
+ cpustate->nmi_state = CLEAR_LINE;
+ }
+ }
+ else
+ {
+ cpustate->irq_state = state;
+
+ /* if the IF is set, signal an interrupt */
+ if (state != CLEAR_LINE && cpustate->IF) {
+ PREFIXV30(_interrupt)(cpustate, (UINT32)-1);
+ cpustate->irq_state = CLEAR_LINE;
+ }
+ }
+}
+
--- /dev/null
+/****************************************************************************/
+/* real mode i286 emulator by Fabrice Frances */
+/* (initial work based on David Hedley's pcemu) */
+/* */
+/****************************************************************************/
+#pragma once
+
+#ifndef __NEWDEV_I86_PRIV_H__
+#define __NEWDEV_I86_PRIV_H__
+
+#define I8086_NMI_INT_VECTOR 2
+
+enum SREGS { ES, CS, SS, DS };
+enum WREGS { AX, CX, DX, BX, SP, BP, SI, DI };
+
+#ifndef FALSE
+#define FALSE 0
+#define TRUE 1
+#endif
+
+
+enum BREGS {
+ AL = NATIVE_ENDIAN_VALUE_LE_BE(0x0, 0x1),
+ AH = NATIVE_ENDIAN_VALUE_LE_BE(0x1, 0x0),
+ CL = NATIVE_ENDIAN_VALUE_LE_BE(0x2, 0x3),
+ CH = NATIVE_ENDIAN_VALUE_LE_BE(0x3, 0x2),
+ DL = NATIVE_ENDIAN_VALUE_LE_BE(0x4, 0x5),
+ DH = NATIVE_ENDIAN_VALUE_LE_BE(0x5, 0x4),
+ BL = NATIVE_ENDIAN_VALUE_LE_BE(0x6, 0x7),
+ BH = NATIVE_ENDIAN_VALUE_LE_BE(0x7, 0x6),
+ SPL = NATIVE_ENDIAN_VALUE_LE_BE(0x8, 0x9),
+ SPH = NATIVE_ENDIAN_VALUE_LE_BE(0x9, 0x8),
+ BPL = NATIVE_ENDIAN_VALUE_LE_BE(0xa, 0xb),
+ BPH = NATIVE_ENDIAN_VALUE_LE_BE(0xb, 0xa),
+ SIL = NATIVE_ENDIAN_VALUE_LE_BE(0xc, 0xd),
+ SIH = NATIVE_ENDIAN_VALUE_LE_BE(0xd, 0xc),
+ DIL = NATIVE_ENDIAN_VALUE_LE_BE(0xe, 0xf),
+ DIH = NATIVE_ENDIAN_VALUE_LE_BE(0xf, 0xe)
+};
+
+/* parameter x = result, y = source 1, z = source 2 */
+
+#define SetTF(x) (cpustate->TF = (x))
+#define SetIF(x) (cpustate->IF = (x))
+#define SetMD(x) (cpustate->MF = (x))
+#define SetDF(x) (cpustate->DirVal = (x) ? -1 : 1)
+
+#define SetOFW_Add(x,y,z) (cpustate->OverVal = ((x) ^ (y)) & ((x) ^ (z)) & 0x8000)
+#define SetOFB_Add(x,y,z) (cpustate->OverVal = ((x) ^ (y)) & ((x) ^ (z)) & 0x80)
+#define SetOFW_Sub(x,y,z) (cpustate->OverVal = ((z) ^ (y)) & ((z) ^ (x)) & 0x8000)
+#define SetOFB_Sub(x,y,z) (cpustate->OverVal = ((z) ^ (y)) & ((z) ^ (x)) & 0x80)
+
+#define SetCFB(x) (cpustate->CarryVal = (x) & 0x100)
+#define SetCFW(x) (cpustate->CarryVal = (x) & 0x10000)
+#define SetAF(x,y,z) (cpustate->AuxVal = ((x) ^ ((y) ^ (z))) & 0x10)
+#define SetSF(x) (cpustate->SignVal = (x))
+#define SetZF(x) (cpustate->ZeroVal = (x))
+#define SetPF(x) (cpustate->ParityVal = (x))
+
+#define SetSZPF_Byte(x) (cpustate->ParityVal = cpustate->SignVal = cpustate->ZeroVal = (INT8)(x))
+#define SetSZPF_Word(x) (cpustate->ParityVal = cpustate->SignVal = cpustate->ZeroVal = (INT16)(x))
+
+#define ADDB(dst,src) { unsigned res=dst+src; SetCFB(res); SetOFB_Add(res,src,dst); SetAF(res,src,dst); SetSZPF_Byte(res); dst=(BYTE)res; }
+#define ADDW(dst,src) { unsigned res=dst+src; SetCFW(res); SetOFW_Add(res,src,dst); SetAF(res,src,dst); SetSZPF_Word(res); dst=(WORD)res; }
+
+#define SUBB(dst,src) { unsigned res=dst-src; SetCFB(res); SetOFB_Sub(res,src,dst); SetAF(res,src,dst); SetSZPF_Byte(res); dst=(BYTE)res; }
+#define SUBW(dst,src) { unsigned res=dst-src; SetCFW(res); SetOFW_Sub(res,src,dst); SetAF(res,src,dst); SetSZPF_Word(res); dst=(WORD)res; }
+
+// don't modify CF in case fault occurs
+#define ADCB(dst,src,tmpcf) { unsigned res=dst+src; tmpcf = res & 0x100; SetOFB_Add(res,src,dst); SetAF(res,src,dst); SetSZPF_Byte(res); dst=(BYTE)res; }
+#define ADCW(dst,src,tmpcf) { unsigned res=dst+src; tmpcf = res & 0x10000; SetOFW_Add(res,src,dst); SetAF(res,src,dst); SetSZPF_Word(res); dst=(WORD)res; }
+
+#define SBBB(dst,src,tmpcf) { unsigned res=dst-src; tmpcf = res & 0x100; SetOFB_Sub(res,src,dst); SetAF(res,src,dst); SetSZPF_Byte(res); dst=(BYTE)res; }
+#define SBBW(dst,src,tmpcf) { unsigned res=dst-src; tmpcf = res & 0x10000; SetOFW_Sub(res,src,dst); SetAF(res,src,dst); SetSZPF_Word(res); dst=(WORD)res; }
+
+#define ORB(dst,src) dst |= src; cpustate->CarryVal = cpustate->OverVal = cpustate->AuxVal = 0; SetSZPF_Byte(dst)
+#define ORW(dst,src) dst |= src; cpustate->CarryVal = cpustate->OverVal = cpustate->AuxVal = 0; SetSZPF_Word(dst)
+
+#define ANDB(dst,src) dst &= src; cpustate->CarryVal = cpustate->OverVal = cpustate->AuxVal = 0; SetSZPF_Byte(dst)
+#define ANDW(dst,src) dst &= src; cpustate->CarryVal = cpustate->OverVal = cpustate->AuxVal = 0; SetSZPF_Word(dst)
+
+#define XORB(dst,src) dst ^= src; cpustate->CarryVal = cpustate->OverVal = cpustate->AuxVal = 0; SetSZPF_Byte(dst)
+#define XORW(dst,src) dst ^= src; cpustate->CarryVal = cpustate->OverVal = cpustate->AuxVal = 0; SetSZPF_Word(dst)
+
+#define CF (int)(cpustate->CarryVal != 0)
+#define SF (int)(cpustate->SignVal < 0)
+#define ZF (int)(cpustate->ZeroVal == 0)
+#define PF parity_table[cpustate->ParityVal&0xff]
+#define AF (int)(cpustate->AuxVal != 0)
+#define OF (int)(cpustate->OverVal != 0)
+#define DF (int)(cpustate->DirVal < 0)
+
+/************************************************************************/
+
+#define read_mem_byte(a) cpustate->program->read_data8(a)
+#define read_mem_word(a) cpustate->program->read_data16(a)
+#define write_mem_byte(a,d) cpustate->program->write_data8((a),(d))
+#define write_mem_word(a,d) cpustate->program->write_data16((a),(d))
+
+#define read_port_byte(a) cpustate->io->read_io8(a)
+#define read_port_word(a) cpustate->io->read_io16(a)
+#define write_port_byte(a,d) cpustate->io->write_io8((a),(d))
+#define write_port_word(a,d) cpustate->io->write_io16((a),(d))
+
+/************************************************************************/
+
+#define SegBase(Seg) (cpustate->sregs[Seg] << 4)
+
+#define DefaultSeg(Seg) ((cpustate->seg_prefix && (Seg == DS || Seg == SS)) ? cpustate->prefix_seg : Seg)
+#define DefaultBase(Seg) ((cpustate->seg_prefix && (Seg == DS || Seg == SS)) ? cpustate->base[cpustate->prefix_seg] : cpustate->base[Seg])
+
+#define GetMemB(Seg,Off) (read_mem_byte((DefaultBase(Seg) + (Off)) & AMASK))
+#define GetMemW(Seg,Off) (read_mem_word((DefaultBase(Seg) + (Off)) & AMASK))
+#define PutMemB(Seg,Off,x) write_mem_byte((DefaultBase(Seg) + (Off)) & AMASK, (x))
+#define PutMemW(Seg,Off,x) write_mem_word((DefaultBase(Seg) + (Off)) & AMASK, (x))
+
+#define PEEKBYTE(ea) (read_mem_byte((ea) & AMASK))
+#define ReadByte(ea) (read_mem_byte((ea) & AMASK))
+#define ReadWord(ea) (read_mem_word((ea) & AMASK))
+#define WriteByte(ea,val) write_mem_byte((ea) & AMASK, val);
+#define WriteWord(ea,val) write_mem_word((ea) & AMASK, val);
+
+#define FETCH (cpustate->program->read_data8(cpustate->pc++))
+#define FETCHOP (cpustate->program->read_data8(cpustate->pc++))
+#define PEEKOP(addr) (cpustate->program->read_data8(addr))
+#define FETCHWORD(var) { var = cpustate->program->read_data8(cpustate->pc); var += (cpustate->program->read_data8(cpustate->pc + 1) << 8); cpustate->pc += 2; }
+#define CHANGE_PC(addr)
+#define PUSH(val) { cpustate->regs.w[SP] -= 2; WriteWord(((cpustate->base[SS] + cpustate->regs.w[SP]) & AMASK), val); }
+#define POP(var) { cpustate->regs.w[SP] += 2; var = ReadWord(((cpustate->base[SS] + ((cpustate->regs.w[SP]-2) & 0xffff)) & AMASK)); }
+
+/************************************************************************/
+#define IOPL (3)
+#define NT (1)
+#define xF (1)
+
+#define CompressFlags() (WORD)(CF | 2 |(PF << 2) | (AF << 4) | (ZF << 6) \
+ | (SF << 7) | (cpustate->TF << 8) | (cpustate->IF << 9) | (cpustate->MF << 15) \
+ | (DF << 10) | (OF << 11) | (IOPL << 12) | (NT << 14) | (xF << 15))
+
+#define ExpandFlags(f) \
+{ \
+ cpustate->CarryVal = (f) & 1; \
+ cpustate->ParityVal = !((f) & 4); \
+ cpustate->AuxVal = (f) & 16; \
+ cpustate->ZeroVal = !((f) & 64); \
+ cpustate->SignVal = ((f) & 128) ? -1 : 0; \
+ cpustate->TF = ((f) & 256) >> 8; \
+ cpustate->IF = ((f) & 512) >> 9; \
+ cpustate->MF = ((f) & 32768) >> 15; \
+ cpustate->DirVal = ((f) & 1024) ? -1 : 1; \
+ cpustate->OverVal = (f) & 2048; \
+}
+#endif /* __I86_H__ */
--- /dev/null
+/****************************************************************************
+* real mode i286 emulator v1.4 by Fabrice Frances *
+* (initial work based on David Hedley's pcemu) *
+****************************************************************************/
+
+
+#include "./ix86_cpustat.h"
+
+/* these come from the 8088 timings in OPCODE.LST, but with the
+ penalty for 16-bit memory accesses removed wherever possible */
+const struct i80x86_timing i8086_cycles =
+{
+ 8086,
+
+ 51,32, /* exception, IRET */
+ 2, 0, 4, 2, /* INTs */
+ 2, /* segment overrides */
+ 2, 4, 4, /* flag operations */
+ 4, 4,83,60, /* arithmetic adjusts */
+ 4, 4, /* decimal adjusts */
+ 2, 5, /* sign extension */
+ 2,24, 2, 2, 3,11, /* misc */
+
+ 15,15,15, /* direct JMPs */
+ 11,18,24, /* indirect JMPs */
+ 19,28, /* direct CALLs */
+ 16,21,37, /* indirect CALLs */
+ 20,32,24,31, /* returns */
+ 4,16, 6,18, /* conditional JMPs */
+ 5,17, 6,18, /* loops */
+
+ 10,14, 8,12, /* port reads */
+ 10,14, 8,12, /* port writes */
+
+ 2, 8, 9, /* move, 8-bit */
+ 4,10, /* move, 8-bit immediate */
+ 2, 8, 9, /* move, 16-bit */
+ 4,10, /* move, 16-bit immediate */
+ 10,10,10,10, /* move, AL/AX memory */
+ 2, 8, 2, 9, /* move, segment registers */
+ 4,17, /* exchange, 8-bit */
+ 4,17, 3, /* exchange, 16-bit */
+
+ 15,24,14,14, /* pushes */
+ 12,25,12,12, /* pops */
+
+ 3, 9,16, /* ALU ops, 8-bit */
+ 4,17,10, /* ALU ops, 8-bit immediate */
+ 3, 9,16, /* ALU ops, 16-bit */
+ 4,17,10, /* ALU ops, 16-bit immediate */
+ 4,17,10, /* ALU ops, 16-bit w/8-bit immediate */
+ 70,118,76,128, /* MUL */
+ 80,128,86,138, /* IMUL */
+ 80,144,86,154, /* DIV */
+ 101,165,107,175,/* IDIV */
+ 3, 2,15,15, /* INC/DEC */
+ 3, 3,16,16, /* NEG/NOT */
+
+ 2, 8, 4, /* reg shift/rotate */
+ 15,20, 4, /* m8 shift/rotate */
+ 15,20, 4, /* m16 shift/rotate */
+
+ 22, 9,21, /* CMPS 8-bit */
+ 22, 9,21, /* CMPS 16-bit */
+ 15, 9,14, /* SCAS 8-bit */
+ 15, 9,14, /* SCAS 16-bit */
+ 12, 9,11, /* LODS 8-bit */
+ 12, 9,11, /* LODS 16-bit */
+ 11, 9,10, /* STOS 8-bit */
+ 11, 9,10, /* STOS 16-bit */
+ 18, 9,17, /* MOVS 8-bit */
+ 18, 9,17, /* MOVS 16-bit */
+
+ (void *)-1 /* marker to make sure we line up */
+};
+
+/* these come from the Intel 80186 datasheet */
+const struct i80x86_timing i80186_cycles =
+{
+ 80186,
+
+ 45,28, /* exception, IRET */
+ 0, 2, 4, 3, /* INTs */
+ 2, /* segment overrides */
+ 2, 2, 3, /* flag operations */
+ 8, 7,19,15, /* arithmetic adjusts */
+ 4, 4, /* decimal adjusts */
+ 2, 4, /* sign extension */
+ 2,18, 6, 2, 6,11, /* misc */
+
+ 14,14,14, /* direct JMPs */
+ 11,17,26, /* indirect JMPs */
+ 15,23, /* direct CALLs */
+ 13,19,38, /* indirect CALLs */
+ 16,22,18,25, /* returns */
+ 4,13, 5,15, /* conditional JMPs */
+ 6,16, 6,16, /* loops */
+
+ 10,10, 8, 8, /* port reads */
+ 9, 9, 7, 7, /* port writes */
+
+ 2, 9,12, /* move, 8-bit */
+ 3,12, /* move, 8-bit immediate */
+ 2, 9,12, /* move, 16-bit */
+ 4,13, /* move, 16-bit immediate */
+ 8, 8, 9, 9, /* move, AL/AX memory */
+ 2,11, 2,11, /* move, segment registers */
+ 4,17, /* exchange, 8-bit */
+ 4,17, 3, /* exchange, 16-bit */
+
+ 10,16, 9, 9, /* pushes */
+ 10,20, 8, 8, /* pops */
+
+ 3,10,10, /* ALU ops, 8-bit */
+ 4,16,10, /* ALU ops, 8-bit immediate */
+ 3,10,10, /* ALU ops, 16-bit */
+ 4,16,10, /* ALU ops, 16-bit immediate */
+ 4,16,10, /* ALU ops, 16-bit w/8-bit immediate */
+ 26,35,32,41, /* MUL */
+ 25,34,31,40, /* IMUL */
+ 29,38,35,44, /* DIV */
+ 44,53,50,59, /* IDIV */
+ 3, 3,15,15, /* INC/DEC */
+ 3, 3,10,10, /* NEG/NOT */
+
+ 2, 5, 1, /* reg shift/rotate */
+ 15,17, 1, /* m8 shift/rotate */
+ 15,17, 1, /* m16 shift/rotate */
+
+ 22, 5,22, /* CMPS 8-bit */
+ 22, 5,22, /* CMPS 16-bit */
+ 15, 5,15, /* SCAS 8-bit */
+ 15, 5,15, /* SCAS 16-bit */
+ 12, 6,11, /* LODS 8-bit */
+ 12, 6,11, /* LODS 16-bit */
+ 10, 6, 9, /* STOS 8-bit */
+ 10, 6, 9, /* STOS 16-bit */
+ 14, 8, 8, /* MOVS 8-bit */
+ 14, 8, 8, /* MOVS 16-bit */
+
+ (void *)-1, /* marker to make sure we line up */
+
+ 14, 8, 8, /* (80186) INS 8-bit */
+ 14, 8, 8, /* (80186) INS 16-bit */
+ 14, 8, 8, /* (80186) OUTS 8-bit */
+ 14, 8, 8, /* (80186) OUTS 16-bit */
+ 14,68,83, /* (80186) PUSH immediate, PUSHA/POPA */
+ 22,29, /* (80186) IMUL immediate 8-bit */
+ 25,32, /* (80186) IMUL immediate 16-bit */
+ 15,25,4,16, 8, /* (80186) ENTER/LEAVE */
+ 33, /* (80186) BOUND */
+
+ (void *)-1 /* marker to make sure we line up */
+};
+
+/* these come from the 80286 timings in OPCODE.LST */
+/* many of these numbers are suspect */
+const struct i80x86_timing i80286_cycles =
+{
+ 80286,
+
+ 23,17, /* exception, IRET */
+ 0, 2, 3, 1, /* INTs */
+ 2, /* segment overrides */
+ 2, 2, 2, /* flag operations */
+ 3, 3,16,14, /* arithmetic adjusts */
+ 3, 3, /* decimal adjusts */
+ 2, 2, /* sign extension */
+ 2, 7, 3, 3, 3, 5, /* misc */
+
+ 7, 7,11, /* direct JMPs */
+ 7,11,26, /* indirect JMPs */
+ 7,13, /* direct CALLs */
+ 7,11,29, /* indirect CALLs */
+ 11,15,11,15, /* returns */
+ 3, 7, 4, 8, /* conditional JMPs */
+ 4, 8, 4, 8, /* loops */
+
+ 5, 5, 5, 5, /* port reads */
+ 3, 3, 3, 3, /* port writes */
+
+ 2, 3, 3, /* move, 8-bit */
+ 2, 3, /* move, 8-bit immediate */
+ 2, 3, 3, /* move, 16-bit */
+ 2, 3, /* move, 16-bit immediate */
+ 5, 5, 3, 3, /* move, AL/AX memory */
+ 2, 5, 2, 3, /* move, segment registers */
+ 3, 5, /* exchange, 8-bit */
+ 3, 5, 3, /* exchange, 16-bit */
+
+ 5, 5, 3, 3, /* pushes */
+ 5, 5, 5, 5, /* pops */
+
+ 2, 7, 7, /* ALU ops, 8-bit */
+ 3, 7, 7, /* ALU ops, 8-bit immediate */
+ 2, 7, 7, /* ALU ops, 16-bit */
+ 3, 7, 7, /* ALU ops, 16-bit immediate */
+ 3, 7, 7, /* ALU ops, 16-bit w/8-bit immediate */
+ 13,21,16,24, /* MUL */
+ 13,21,16,24, /* IMUL */
+ 14,22,17,25, /* DIV */
+ 17,25,20,28, /* IDIV */
+ 2, 2, 7, 7, /* INC/DEC */
+ 2, 2, 7, 7, /* NEG/NOT */
+
+ 2, 5, 1, /* reg shift/rotate */
+ 7, 8, 1, /* m8 shift/rotate */
+ 7, 8, 1, /* m16 shift/rotate */
+
+ 13, 5,12, /* CMPS 8-bit */
+ 13, 5,12, /* CMPS 16-bit */
+ 9, 5, 8, /* SCAS 8-bit */
+ 9, 5, 8, /* SCAS 16-bit */
+ 5, 5, 4, /* LODS 8-bit */
+ 5, 5, 4, /* LODS 16-bit */
+ 4, 4, 3, /* STOS 8-bit */
+ 4, 4, 3, /* STOS 16-bit */
+ 5, 5, 4, /* MOVS 8-bit */
+ 5, 5, 4, /* MOVS 16-bit */
+
+ (void *)-1, /* marker to make sure we line up */
+
+ 5, 5, 4, /* (80186) INS 8-bit */
+ 5, 5, 4, /* (80186) INS 16-bit */
+ 5, 5, 4, /* (80186) OUTS 8-bit */
+ 5, 5, 4, /* (80186) OUTS 16-bit */
+ 3,17,19, /* (80186) PUSH immediate, PUSHA/POPA */
+ 21,24, /* (80186) IMUL immediate 8-bit */
+ 21,24, /* (80186) IMUL immediate 16-bit */
+ 11,15,12, 4, 5, /* (80186) ENTER/LEAVE */
+ 13, /* (80186) BOUND */
+
+ (void *)-1 /* marker to make sure we line up */
+};
--- /dev/null
+/****************************************************************************
+* real mode i286 emulator v1.4 by Fabrice Frances *
+* (initial work based on David Hedley's pcemu) *
+****************************************************************************/
+#ifndef __NEWDEV_LIBX86_I86TIME_H__
+#define __NEWDEV_LIBX86_I86TIME_H__
+struct i80x86_timing
+{
+ int id;
+
+ UINT8 exception, iret; /* exception, IRET */
+ UINT8 int3, int_imm, into_nt, into_t; /* INTs */
+ UINT8 override; /* segment overrides */
+ UINT8 flag_ops, lahf, sahf; /* flag operations */
+ UINT8 aaa, aas, aam, aad; /* arithmetic adjusts */
+ UINT8 daa, das; /* decimal adjusts */
+ UINT8 cbw, cwd; /* sign extension */
+ UINT8 hlt, load_ptr, lea, nop, wait, xlat; /* misc */
+
+ UINT8 jmp_short, jmp_near, jmp_far; /* direct JMPs */
+ UINT8 jmp_r16, jmp_m16, jmp_m32; /* indirect JMPs */
+ UINT8 call_near, call_far; /* direct CALLs */
+ UINT8 call_r16, call_m16, call_m32; /* indirect CALLs */
+ UINT8 ret_near, ret_far, ret_near_imm, ret_far_imm; /* returns */
+ UINT8 jcc_nt, jcc_t, jcxz_nt, jcxz_t; /* conditional JMPs */
+ UINT8 loop_nt, loop_t, loope_nt, loope_t; /* loops */
+
+ UINT8 in_imm8, in_imm16, in_dx8, in_dx16; /* port reads */
+ UINT8 out_imm8, out_imm16, out_dx8, out_dx16; /* port writes */
+
+ UINT8 mov_rr8, mov_rm8, mov_mr8; /* move, 8-bit */
+ UINT8 mov_ri8, mov_mi8; /* move, 8-bit immediate */
+ UINT8 mov_rr16, mov_rm16, mov_mr16; /* move, 16-bit */
+ UINT8 mov_ri16, mov_mi16; /* move, 16-bit immediate */
+ UINT8 mov_am8, mov_am16, mov_ma8, mov_ma16; /* move, AL/AX memory */
+ UINT8 mov_sr, mov_sm, mov_rs, mov_ms; /* move, segment registers */
+ UINT8 xchg_rr8, xchg_rm8; /* exchange, 8-bit */
+ UINT8 xchg_rr16, xchg_rm16, xchg_ar16; /* exchange, 16-bit */
+
+ UINT8 push_r16, push_m16, push_seg, pushf; /* pushes */
+ UINT8 pop_r16, pop_m16, pop_seg, popf; /* pops */
+
+ UINT8 alu_rr8, alu_rm8, alu_mr8; /* ALU ops, 8-bit */
+ UINT8 alu_ri8, alu_mi8, alu_mi8_ro; /* ALU ops, 8-bit immediate */
+ UINT8 alu_rr16, alu_rm16, alu_mr16; /* ALU ops, 16-bit */
+ UINT8 alu_ri16, alu_mi16, alu_mi16_ro; /* ALU ops, 16-bit immediate */
+ UINT8 alu_r16i8, alu_m16i8, alu_m16i8_ro; /* ALU ops, 16-bit w/8-bit immediate */
+ UINT8 mul_r8, mul_r16, mul_m8, mul_m16; /* MUL */
+ UINT8 imul_r8, imul_r16, imul_m8, imul_m16; /* IMUL */
+ UINT8 div_r8, div_r16, div_m8, div_m16; /* DIV */
+ UINT8 idiv_r8, idiv_r16, idiv_m8, idiv_m16; /* IDIV */
+ UINT8 incdec_r8, incdec_r16, incdec_m8, incdec_m16; /* INC/DEC */
+ UINT8 negnot_r8, negnot_r16, negnot_m8, negnot_m16; /* NEG/NOT */
+
+ UINT8 rot_reg_1, rot_reg_base, rot_reg_bit; /* reg shift/rotate */
+ UINT8 rot_m8_1, rot_m8_base, rot_m8_bit; /* m8 shift/rotate */
+ UINT8 rot_m16_1, rot_m16_base, rot_m16_bit; /* m16 shift/rotate */
+
+ UINT8 cmps8, rep_cmps8_base, rep_cmps8_count; /* CMPS 8-bit */
+ UINT8 cmps16, rep_cmps16_base, rep_cmps16_count; /* CMPS 16-bit */
+ UINT8 scas8, rep_scas8_base, rep_scas8_count; /* SCAS 8-bit */
+ UINT8 scas16, rep_scas16_base, rep_scas16_count; /* SCAS 16-bit */
+ UINT8 lods8, rep_lods8_base, rep_lods8_count; /* LODS 8-bit */
+ UINT8 lods16, rep_lods16_base, rep_lods16_count; /* LODS 16-bit */
+ UINT8 stos8, rep_stos8_base, rep_stos8_count; /* STOS 8-bit */
+ UINT8 stos16, rep_stos16_base, rep_stos16_count; /* STOS 16-bit */
+ UINT8 movs8, rep_movs8_base, rep_movs8_count; /* MOVS 8-bit */
+ UINT8 movs16, rep_movs16_base, rep_movs16_count; /* MOVS 16-bit */
+
+ void * check1; /* marker to make sure we line up */
+
+ UINT8 ins8, rep_ins8_base, rep_ins8_count; /* (80186) INS 8-bit */
+ UINT8 ins16, rep_ins16_base, rep_ins16_count; /* (80186) INS 16-bit */
+ UINT8 outs8, rep_outs8_base, rep_outs8_count; /* (80186) OUTS 8-bit */
+ UINT8 outs16, rep_outs16_base, rep_outs16_count; /* (80186) OUTS 16-bit */
+ UINT8 push_imm, pusha, popa; /* (80186) PUSH immediate, PUSHA/POPA */
+ UINT8 imul_rri8, imul_rmi8; /* (80186) IMUL immediate 8-bit */
+ UINT8 imul_rri16, imul_rmi16; /* (80186) IMUL immediate 16-bit */
+ UINT8 enter0, enter1, enter_base, enter_count, leave; /* (80186) ENTER/LEAVE */
+ UINT8 bound; /* (80186) BOUND */
+
+ void * check2; /* marker to make sure we line up */
+};
+
+#endif
\ No newline at end of file
--- /dev/null
+/****************************************************************************
+* real mode i286 emulator v1.4 by Fabrice Frances *
+* (initial work based on David Hedley's pcemu) *
+****************************************************************************/
+
+// file will be included in all cpu variants
+// function renaming will be added when necessary
+// timing value should move to separate array
+
+#include "./ix86_opdef.h"
+
+#undef ICOUNT
+
+#define ICOUNT cpustate->icount
+#define PREFIX(XXX) PREFIX86(XXXX)
+
+void IX86_OPS_BASE::PREFIX186(_interrupt)(unsigned int_num)
+{
+ unsigned dest_seg, dest_off;
+ WORD ip = cpustate->pc - cpustate->base[CS];
+
+ if (int_num == -1)
+ int_num = cpustate->pic->get_intr_ack();
+
+ dest_off = ReadWord(int_num*4);
+ dest_seg = ReadWord(int_num*4+2);
+
+ PREFIX(_pushf());
+ cpustate->TF = cpustate->IF = 0;
+ PUSH(cpustate->sregs[CS]);
+ PUSH(ip);
+ cpustate->sregs[CS] = (WORD)dest_seg;
+ cpustate->base[CS] = SegBase(CS);
+ cpustate->pc = (cpustate->base[CS] + dest_off) & AMASK;
+ CHANGE_PC(cpustate->pc);
+
+ cpustate->extra_cycles += timing.exception;
+}
+
+void IX86_OPS_BASE::PREFIX186(_pusha)() /* Opcode 0x60 */
+{
+ unsigned tmp=cpustate->regs.w[SP];
+
+ ICOUNT -= timing.pusha;
+ PUSH(cpustate->regs.w[AX]);
+ PUSH(cpustate->regs.w[CX]);
+ PUSH(cpustate->regs.w[DX]);
+ PUSH(cpustate->regs.w[BX]);
+ PUSH(tmp);
+ PUSH(cpustate->regs.w[BP]);
+ PUSH(cpustate->regs.w[SI]);
+ PUSH(cpustate->regs.w[DI]);
+}
+
+static unsigned i186_popa_tmp; // hack around GCC 4.6 error because we need the side effects of POP
+void IX86_OPS_BASE::PREFIX186(_popa)() /* Opcode 0x61 */
+{
+
+ ICOUNT -= timing.popa;
+ POP(cpustate->regs.w[DI]);
+ POP(cpustate->regs.w[SI]);
+ POP(cpustate->regs.w[BP]);
+ POP(i186_popa_tmp);
+ POP(cpustate->regs.w[BX]);
+ POP(cpustate->regs.w[DX]);
+ POP(cpustate->regs.w[CX]);
+ POP(cpustate->regs.w[AX]);
+}
+
+void IX86_OPS_BASE::PREFIX186(_bound)() /* Opcode 0x62 */
+{
+ unsigned ModRM = FETCHOP;
+ int low = (INT16)GetRMWord(ModRM);
+ int high= (INT16)GetnextRMWord;
+ int tmp= (INT16)RegWord(ModRM);
+ if (tmp<low || tmp>high) {
+ cpustate->pc-= (cpustate->seg_prefix ? 3 : 2 );
+ PREFIX(_interrupt)(5);
+ }
+ ICOUNT -= timing.bound;
+}
+
+void IX86_OPS_BASE::PREFIX186(_push_d16)() /* Opcode 0x68 */
+{
+ unsigned tmp = FETCH;
+
+ ICOUNT -= timing.push_imm;
+ tmp += FETCH << 8;
+ PUSH(tmp);
+}
+
+void IX86_OPS_BASE::PREFIX186(_imul_d16)() /* Opcode 0x69 */
+{
+ DEF_r16w(dst,src);
+ unsigned src2=FETCH;
+ src2+=(FETCH<<8);
+
+ ICOUNT -= (ModRM >= 0xc0) ? timing.imul_rri16 : timing.imul_rmi16;
+
+ dst = (INT32)((INT16)src)*(INT32)((INT16)src2);
+ cpustate->CarryVal = cpustate->OverVal = (((INT32)dst) >> 15 != 0) && (((INT32)dst) >> 15 != -1);
+ RegWord(ModRM)=(WORD)dst;
+}
+
+
+void IX86_OPS_BASE::PREFIX186(_push_d8)() /* Opcode 0x6a */
+{
+ unsigned tmp = (WORD)((INT16)((INT8)FETCH));
+
+ ICOUNT -= timing.push_imm;
+ PUSH(tmp);
+}
+
+void IX86_OPS_BASE::PREFIX186(_imul_d8)() /* Opcode 0x6b */
+{
+ DEF_r16w(dst,src);
+ unsigned src2= (WORD)((INT16)((INT8)FETCH));
+
+ ICOUNT -= (ModRM >= 0xc0) ? timing.imul_rri8 : timing.imul_rmi8;
+
+ dst = (INT32)((INT16)src)*(INT32)((INT16)src2);
+ cpustate->CarryVal = cpustate->OverVal = (((INT32)dst) >> 15 != 0) && (((INT32)dst) >> 15 != -1);
+ RegWord(ModRM)=(WORD)dst;
+}
+
+void IX86_OPS_BASE::PREFIX186(_insb)() /* Opcode 0x6c */
+{
+ ICOUNT -= timing.ins8;
+ PutMemB(ES,cpustate->regs.w[DI],read_port_byte(cpustate->regs.w[DX]));
+ cpustate->regs.w[DI] += cpustate->DirVal;
+}
+
+void IX86_OPS_BASE::PREFIX186(_insw)() /* Opcode 0x6d */
+{
+ ICOUNT -= timing.ins16;
+ PutMemW(ES,cpustate->regs.w[DI],read_port_word(cpustate->regs.w[DX]));
+ cpustate->regs.w[DI] += 2 * cpustate->DirVal;
+}
+
+void IX86_OPS_BASE::PREFIX186(_outsb)() /* Opcode 0x6e */
+{
+ ICOUNT -= timing.outs8;
+ write_port_byte(cpustate->regs.w[DX],GetMemB(DS,cpustate->regs.w[SI]));
+ cpustate->regs.w[SI] += cpustate->DirVal; /* GOL 11/27/01 */
+}
+
+void IX86_OPS_BASE::PREFIX186(_outsw)() /* Opcode 0x6f */
+{
+ ICOUNT -= timing.outs16;
+ write_port_word(cpustate->regs.w[DX],GetMemW(DS,cpustate->regs.w[SI]));
+ cpustate->regs.w[SI] += 2 * cpustate->DirVal; /* GOL 11/27/01 */
+}
+
+void IX86_OPS_BASE::PREFIX186(_rotshft_bd8)() /* Opcode 0xc0 */
+{
+ unsigned ModRM = FETCH;
+ unsigned src = GetRMByte(ModRM);
+ unsigned count = FETCH;
+
+ PREFIX86(_rotate_shift_Byte)(cpustate,ModRM,count & 0x1f,src);
+}
+
+void IX86_OPS_BASE::PREFIX186(_rotshft_wd8)() /* Opcode 0xc1 */
+{
+ unsigned ModRM = FETCH;
+ unsigned src = GetRMWord(ModRM);
+ unsigned count = FETCH;
+
+ PREFIX86(_rotate_shift_Word)(cpustate,ModRM,count & 0x1f,src);
+}
+
+void IX86_OPS_BASE::PREFIX186(_enter)() /* Opcode 0xc8 */
+{
+ unsigned nb = FETCH;
+ unsigned i,level;
+ UINT16 fp;
+
+ nb += FETCH << 8;
+ level = FETCH;
+ ICOUNT -= (level == 0) ? timing.enter0 : (level == 1) ? timing.enter1 : timing.enter_base + level * timing.enter_count;
+ PUSH(cpustate->regs.w[BP]);
+ fp = cpustate->regs.w[SP];
+ for (i=1;i<level;i++)
+ PUSH(GetMemW(SS,cpustate->regs.w[BP]-i*2));
+ if (level) PUSH(fp);
+ cpustate->regs.w[BP] = fp;
+ cpustate->regs.w[SP] -= nb;
+}
+
+void IX86_OPS_BASE::PREFIX186(_leave)() /* Opcode 0xc9 */
+{
+ ICOUNT -= timing.leave;
+ cpustate->regs.w[SP]=cpustate->regs.w[BP];
+ POP(cpustate->regs.w[BP]);
+}
+
+void IX86_OPS_BASE::PREFIX186(_rotshft_bcl)() /* Opcode 0xd2 */
+{
+ unsigned ModRM = FETCHOP;
+ PREFIX86(_rotate_shift_Byte)(cpustate,ModRM,cpustate->regs.b[CL] & 0x1f,GetRMByte(ModRM));
+}
+
+void IX86_OPS_BASE::PREFIX186(_rotshft_wcl)() /* Opcode 0xd3 */
+{
+ unsigned ModRM = FETCHOP;
+ PREFIX86(_rotate_shift_Word)(cpustate,ModRM,cpustate->regs.b[CL] & 0x1f,GetRMWord(ModRM));
+}
+
+void IX86_OPS::PREFIX(_pop_ss)() /* Opcode 0x17 */
+{
+ POP(cpustate->sregs[SS]);
+ cpustate->base[SS] = SegBase(SS);
+
+ ICOUNT -= timing.pop_seg;
+ PREFIX(_instruction)[FETCHOP](cpustate); /* no interrupt before next instruction */
+}
+
+void IX86_OPS::PREFIX(_mov_sregw)() /* Opcode 0x8e */
+{
+ unsigned ModRM = FETCH;
+ WORD src = GetRMWord(ModRM);
+
+ ICOUNT -= (ModRM >= 0xc0) ? timing.mov_sr : timing.mov_sm;
+ switch (ModRM & 0x38)
+ {
+ case 0x00: /* mov es,ew */
+ cpustate->sregs[ES] = src;
+ cpustate->base[ES] = SegBase(ES);
+ break;
+ case 0x18: /* mov ds,ew */
+ cpustate->sregs[DS] = src;
+ cpustate->base[DS] = SegBase(DS);
+ break;
+ case 0x10: /* mov ss,ew */
+ cpustate->sregs[SS] = src;
+ cpustate->base[SS] = SegBase(SS); /* no interrupt allowed before next instr */
+ cpustate->seg_prefix = FALSE;
+ PREFIX(_instruction)[FETCHOP](cpustate);
+ break;
+ case 0x08: /* mov cs,ew */
+ break;
+ }
+}
+void IX86_OPS::PREFIX(_sti)() /* Opcode 0xfb */
+{
+ ICOUNT -= timing.flag_ops;
+ SetIF(1);
+ PREFIX(_instruction)[FETCHOP](cpustate); /* no interrupt before next instruction */
+
+ /* if an interrupt is pending, signal an interrupt */
+ if (cpustate->irq_state) {
+ PREFIX86(_interrupt)(cpustate, (UINT32)-1);
+ cpustate->irq_state = 0;
+ }
+}
+
+void IX86_OPS_BASE::PREFIX(_inc_bx)() /* Opcode 0x43 */
+{
+ IncWordReg(BX);
+}
+
+void IX86_OPS_BASE::PREFIX(_pop_ss)() /* Opcode 0x17 */
+{
+ POP(cpustate->sregs[SS]);
+ cpustate->base[SS] = SegBase(SS);
+
+ ICOUNT -= timing.pop_seg;
+ PREFIX(_instruction)[FETCHOP](cpustate); /* no interrupt before next instruction */
+}
+
+void IX86_OPS_BASE::PREFIX(_es)() /* Opcode 0x26 */
+{
+ cpustate->seg_prefix = TRUE;
+ cpustate->prefix_seg = ES;
+ ICOUNT -= timing.override;
+ PREFIX(_instruction)[FETCHOP](cpustate);
+}
+
+void IX86_OPS_BASE::PREFIX(_cs)() /* Opcode 0x2e */
+{
+ cpustate->seg_prefix = TRUE;
+ cpustate->prefix_seg = CS;
+ ICOUNT -= timing.override;
+ PREFIX(_instruction)[FETCHOP](cpustate);
+}
+
+void IX86_OPS_BASE::PREFIX(_ss)() /* Opcode 0x36 */
+{
+ cpustate->seg_prefix = TRUE;
+ cpustate->prefix_seg = SS;
+ ICOUNT -= timing.override;
+ PREFIX(_instruction)[FETCHOP](cpustate);
+}
+
+void IX86_OPS_BASE::PREFIX(_ds)() /* Opcode 0x3e */
+{
+ cpustate->seg_prefix = TRUE;
+ cpustate->prefix_seg = DS;
+ ICOUNT -= timing.override;
+ PREFIX(_instruction)[FETCHOP](cpustate);
+}
+
+void IX86_OPS_BASE::PREFIX(_mov_sregw)() /* Opcode 0x8e */
+{
+ unsigned ModRM = FETCH;
+ WORD src = GetRMWord(ModRM);
+
+ ICOUNT -= (ModRM >= 0xc0) ? timing.mov_sr : timing.mov_sm;
+ switch (ModRM & 0x38)
+ {
+ case 0x00: /* mov es,ew */
+ cpustate->sregs[ES] = src;
+ cpustate->base[ES] = SegBase(ES);
+ break;
+ case 0x18: /* mov ds,ew */
+ cpustate->sregs[DS] = src;
+ cpustate->base[DS] = SegBase(DS);
+ break;
+ case 0x10: /* mov ss,ew */
+ cpustate->sregs[SS] = src;
+ cpustate->base[SS] = SegBase(SS); /* no interrupt allowed before next instr */
+ cpustate->seg_prefix = FALSE;
+ PREFIX(_instruction)[FETCHOP]();
+ break;
+ case 0x08: /* mov cs,ew */
+ break;
+ }
+}
+
+void IX86_OPS_BASE::PREFIX(_repne)() /* Opcode 0xf2 */
+{
+ PREFIX(rep)(0);
+}
+
+void IX86_OPS_BASE::PREFIX(_repe)() /* Opcode 0xf3 */
+{
+ PREFIX(rep)(1);
+}
+
+void IX86_OPS_BASE::PREFIX(_sti)() /* Opcode 0xfb */
+{
+ ICOUNT -= timing.flag_ops;
+ SetIF(1);
+ PREFIX(_instruction)[FETCHOP](cpustate); /* no interrupt before next instruction */
+
+ /* if an interrupt is pending, signal an interrupt */
+ if (cpustate->irq_state) {
+ PREFIX86(_interrupt)(cpustate, (UINT32)-1);
+ cpustate->irq_state = 0;
+ }
+}
--- /dev/null
+/****************************************************************************
+* real mode i286 emulator v1.4 by Fabrice Frances *
+* (initial work based on David Hedley's pcemu) *
+****************************************************************************/
+
+// file will be included in all cpu variants
+// timing value should move to separate array
+
+//void IX86_OPS::PREFIX186(_pusha)();
+//void IX86_OPS::PREFIX186(_popa)();
+//void IX86_OPS::PREFIX186(_bound)();
+//void IX86_OPS::PREFIX186(_push_d16)();
+//void IX86_OPS::PREFIX186(_imul_d16)();
+//void IX86_OPS::PREFIX186(_push_d8)();
+//void IX86_OPS::PREFIX186(_imul_d8)();
+//void IX86_OPS::PREFIX186(_rotshft_bd8)();
+//void IX86_OPS::PREFIX186(_rotshft_wd8)();
+//void IX86_OPS::PREFIX186(_enter)();
+//void IX86_OPS::PREFIX186(_leave)();
+//void IX86_OPS::PREFIX186(_insb)();
+//void IX86_OPS::PREFIX186(_insw)();
+//void IX86_OPS::PREFIX186(_outsb)();
+//void IX86_OPS::PREFIX186(_outsw)();
+
+/* changed instructions */
+//void IX86_OPS::PREFIX(_pop_ss)();
+//void IX86_OPS::PREFIX(_es)();
+//void IX86_OPS::PREFIX(_cs)();
+//void IX86_OPS::PREFIX(_ss)();
+//void IX86_OPS::PREFIX(_ds)();
+//void IX86_OPS::PREFIX(_mov_sregw)();
+//void IX86_OPS::PREFIX186(_repne)();
+//void IX86_OPS::PREFIX186(_repe)();
+//void IX86_OPS::PREFIX186(_sti)();
+//void IX86_OPS::PREFIX186(_rotshft_bcl)();
+//void IX86_OPS::PREFIX186(_rotshft_wcl)();
--- /dev/null
+/* descriptor table format in memory
+ UINT16 limit
+ UINT24 addr
+ 0..3 type
+ system segment
+ 3 execute:
+ 0 data segment: readable,
+ 1: write
+ 2: expand down
+ 1 code segment
+ 1: readable
+ 2: conforming (can be used with higher privilege level)
+ 0: access (set when processor accesses segment)
+
+ 4 dt 0 system segment, 1 application segment (code, data)
+ 5,6 dpl descriptor privileg level
+ 7 p present 0 gives trap when accessed
+ UINT16 reserved (should be zero)
+*/
+#define LIMIT(desc) (desc[0]&0xffff)
+#define BASE(desc) ((desc[1]&0xffff)|((desc[2]&0xff)<<16))
+#define RIGHTS(desc) ((desc[2]>>8)&0xff)
+
+#define ACCESS(r) (r&1)
+#define SET_ACC(desc) (desc[2]|=0x100)
+#define RW(r) ((r>>1)&1)
+#define READ(r) ((r>>1)&1)
+#define CONF(r) ((r>>2)&1)
+#define EXPDOWN(r) ((r>>2)&1)
+#define CODE(r) ((r>>3)&1)
+#define SEGDESC(r) ((r>>4)&1)
+#define DPL(r) ((r>>5)&3)
+#define PRES(r) ((r>>7)&1)
+#define GATE(r) (r&31)
+#define GATESEL(desc) (desc[1])
+#define GATEOFF(desc) (desc[0])
+#define GATECNT(desc) (desc[2]&31)
+
+#define RPL(s) (s&3)
+#define IDX(s) (s&(~7))
+#define IDXTBL(s) (s&(~3))
+#define TBL(s) (s&4)
+
+#define TSSDESCIDLE 1
+#define LDTDESC 2
+#define TSSDESCBUSY 3
+#define CALLGATE 4
+#define TASKGATE 5
+#define INTGATE 6
+#define TRAPGATE 7
+
+#define TSS_BACK 0
+#define TSS_SP0 1
+#define TSS_SS0 2
+#define TSS_SP1 3
+#define TSS_SS1 4
+#define TSS_SP2 5
+#define TSS_SS2 6
+#define TSS_IP 7
+#define TSS_FLAG 8
+#define TSS_AX 9
+#define TSS_CX 10
+#define TSS_DX 11
+#define TSS_BX 12
+#define TSS_SP 13
+#define TSS_BP 14
+#define TSS_SI 15
+#define TSS_DI 16
+#define TSS_ES 17
+#define TSS_CS 18
+#define TSS_SS 19
+#define TSS_DS 20
+#define TSS_LDT 21
+
+#define PMAX(a,b) ((a<b)?b:a)
+
+#define IRET 0
+#define JMP 1
+#define CALL 2
+
+#include "./i86priv.h"
+#undef GetMemB
+#undef GetMemW
+#undef PutMemB
+#undef PutMemW
+#undef PUSH
+#undef POP
+#undef IOPL
+#undef NT
+#undef xF
+#undef CompressFlags
+
+#define GetMemB(Seg,Off) (read_mem_byte(GetMemAddr(cpustate,Seg,Off,1,I80286_READ)))
+#define GetMemW(Seg,Off) (read_mem_word(GetMemAddr(cpustate,Seg,Off,2,I80286_READ)))
+#define PutMemB(Seg,Off,x) write_mem_byte(GetMemAddr(cpustate,Seg,Off,1,I80286_WRITE), (x))
+#define PutMemW(Seg,Off,x) write_mem_word(GetMemAddr(cpustate,Seg,Off,2,I80286_WRITE), (x))
+
+#define PUSH(val) { if(PM) i80286_check_permission(cpustate, SS, cpustate->regs.w[SP]-2, I80286_WORD, I80286_WRITE); cpustate->regs.w[SP] -= 2; WriteWord(((cpustate->base[SS] + cpustate->regs.w[SP]) & AMASK), val); }
+#define POP(var) { if(PM) i80286_check_permission(cpustate, SS, cpustate->regs.w[SP], I80286_WORD, I80286_READ); cpustate->regs.w[SP] += 2; var = ReadWord(((cpustate->base[SS] + ((cpustate->regs.w[SP]-2) & 0xffff)) & AMASK)); }
+
+#define IOPL ((cpustate->flags&0x3000)>>12)
+#define NT ((cpustate->flags&0x4000)>>14)
+#define xF (0)
+
+#define CompressFlags() (WORD)(CF | 2 |(PF << 2) | (AF << 4) | (ZF << 6) \
+ | (SF << 7) | (cpustate->TF << 8) | (cpustate->IF << 9) | (cpustate->MF << 15) \
+ | (DF << 10) | (OF << 11) | (IOPL << 12) | (NT << 14) | (xF << 15))
+
+//IX86_OPS_BASE::CPU_RESET( CPU_MODEL );
+
+// when a cpu reset happens on a AT the bios checks for 9 in byte 0xf
+// of the nvram. if yes, after init, it sets the stack pointer to the value in 0040:0067
+// in the bios data segment then pops es and ds off that stack, does popa then a far ret.
+#include "./ix86_opdef.h"
+
+#define PREFIX(XXX) PREFIX286(XXX)
+
+void IX86_OPS_BASE::PREFIX(_interrupt)(unsigned int_num)
+{
+ unsigned dest_seg, dest_off;
+ WORD ip = cpustate->pc - cpustate->base[CS];
+
+ if (int_num == -1)
+ int_num = cpustate->pic->get_intr_ack();
+
+ if (PM) {
+ i80286_interrupt_descriptor(cpustate, int_num, 0, 0);
+ } else {
+ dest_off = ReadWord(int_num*4);
+ dest_seg = ReadWord(int_num*4+2);
+
+ PREFIX(_pushf());
+ cpustate->TF = cpustate->IF = 0;
+ PUSH(cpustate->sregs[CS]);
+ PUSH(ip);
+ cpustate->sregs[CS] = (WORD)dest_seg;
+ cpustate->base[CS] = SegBase(CS);
+ cpustate->pc = (cpustate->base[CS] + dest_off) & AMASK;
+ CHANGE_PC(cpustate->pc);
+ }
+ cpustate->extra_cycles += timing.exception;
+}
+
+void IX86_OPS_BASE::PREFIX(_trap)()
+{
+ PREFIX(_instruction)[FETCHOP]();
+ PREFIX(_interrupt)(1);
+}
+void IX86_OPS_BASE::PREFIX(_pushf)() /* Opcode 0x9c */
+{
+ unsigned tmp;
+ ICOUNT -= timing.pushf;
+
+ tmp = CompressFlags();
+ if(!PM) ( tmp &= ~0xf000 );
+ PUSH( tmp );
+}
+
+
+void IX86_OPS_BASE::PREFIX(rep)(int flagval)
+{
+ /* Handles rep- and repnz- prefixes. flagval is the value of ZF for the
+ loop to continue for CMPS and SCAS instructions. */
+
+ unsigned next = FETCHOP;
+
+ switch(next)
+ {
+ case 0x26: /* ES: */
+ cpustate->seg_prefix = TRUE;
+ cpustate->prefix_seg = ES;
+ if (!cpustate->rep_in_progress)
+ ICOUNT -= timing.override;
+ PREFIX(rep)(flagval);
+ break;
+ case 0x2e: /* CS: */
+ cpustate->seg_prefix = TRUE;
+ cpustate->prefix_seg = CS;
+ if (!cpustate->rep_in_progress)
+ ICOUNT -= timing.override;
+ PREFIX(rep)(flagval);
+ break;
+ case 0x36: /* SS: */
+ cpustate->seg_prefix = TRUE;
+ cpustate->prefix_seg = SS;
+ if (!cpustate->rep_in_progress)
+ ICOUNT -= timing.override;
+ PREFIX(rep)(cpustate, flagval);
+ break;
+ case 0x3e: /* DS: */
+ cpustate->seg_prefix = TRUE;
+ cpustate->prefix_seg = DS;
+ if (!cpustate->rep_in_progress)
+ ICOUNT -= timing.override;
+ PREFIX(rep)(cpustate, flagval);
+ break;
+ case 0x6c: /* REP INSB */
+ if (PM && (CPL>IOPL)) throw TRAP(GENERAL_PROTECTION_FAULT, 0);
+ if (!cpustate->rep_in_progress)
+ ICOUNT -= timing.rep_ins8_base;
+ cpustate->rep_in_progress = FALSE;
+ while(cpustate->regs.w[CX])
+ {
+// if (ICOUNT <= 0) { cpustate->pc = cpustate->prevpc; cpustate->rep_in_progress = TRUE; break; }
+ PutMemB(ES,cpustate->regs.w[DI],read_port_byte(cpustate->regs.w[DX]));
+ cpustate->regs.w[CX]--;
+ cpustate->regs.w[DI] += cpustate->DirVal;
+ ICOUNT -= timing.rep_ins8_count;
+ }
+ break;
+ case 0x6d: /* REP INSW */
+ if (PM && (CPL>IOPL)) throw TRAP(GENERAL_PROTECTION_FAULT, 0);
+ if (!cpustate->rep_in_progress)
+ ICOUNT -= timing.rep_ins16_base;
+ cpustate->rep_in_progress = FALSE;
+ while(cpustate->regs.w[CX])
+ {
+// if (ICOUNT <= 0) { cpustate->pc = cpustate->prevpc; cpustate->rep_in_progress = TRUE; break; }
+ PutMemW(ES,cpustate->regs.w[DI],read_port_word(cpustate->regs.w[DX]));
+ cpustate->regs.w[CX]--;
+ cpustate->regs.w[DI] += 2 * cpustate->DirVal;
+ ICOUNT -= timing.rep_ins16_count;
+ }
+ break;
+ case 0x6e: /* REP OUTSB */
+ if (PM && (CPL>IOPL)) throw TRAP(GENERAL_PROTECTION_FAULT, 0);
+ if (!cpustate->rep_in_progress)
+ ICOUNT -= timing.rep_outs8_base;
+ cpustate->rep_in_progress = FALSE;
+ while(cpustate->regs.w[CX])
+ {
+// if (ICOUNT <= 0) { cpustate->pc = cpustate->prevpc; cpustate->rep_in_progress = TRUE; break; }
+ write_port_byte(cpustate->regs.w[DX],GetMemB(DS,cpustate->regs.w[SI]));
+ cpustate->regs.w[CX]--;
+ cpustate->regs.w[SI] += cpustate->DirVal; /* GOL 11/27/01 */
+ ICOUNT -= timing.rep_outs8_count;
+ }
+ break;
+ case 0x6f: /* REP OUTSW */
+ if (PM && (CPL>IOPL)) throw TRAP(GENERAL_PROTECTION_FAULT, 0);
+ if (!cpustate->rep_in_progress)
+ ICOUNT -= timing.rep_outs16_base;
+ cpustate->rep_in_progress = FALSE;
+ while(cpustate->regs.w[CX])
+ {
+// if (ICOUNT <= 0) { cpustate->pc = cpustate->prevpc; cpustate->rep_in_progress = TRUE; break; }
+ write_port_word(cpustate->regs.w[DX],GetMemW(DS,cpustate->regs.w[SI]));
+ cpustate->regs.w[CX]--;
+ cpustate->regs.w[SI] += 2 * cpustate->DirVal; /* GOL 11/27/01 */
+ ICOUNT -= timing.rep_outs16_count;
+ }
+ break;
+ case 0xa4: /* REP MOVSB */
+ if (!cpustate->rep_in_progress)
+ ICOUNT -= timing.rep_movs8_base;
+ cpustate->rep_in_progress = FALSE;
+ while(cpustate->regs.w[CX])
+ {
+ BYTE tmp;
+
+// if (ICOUNT <= 0) { cpustate->pc = cpustate->prevpc; cpustate->rep_in_progress = TRUE; break; }
+ tmp = GetMemB(DS,cpustate->regs.w[SI]);
+ PutMemB(ES,cpustate->regs.w[DI], tmp);
+ cpustate->regs.w[CX]--;
+ cpustate->regs.w[DI] += cpustate->DirVal;
+ cpustate->regs.w[SI] += cpustate->DirVal;
+ ICOUNT -= timing.rep_movs8_count;
+ }
+ break;
+ case 0xa5: /* REP MOVSW */
+ if (!cpustate->rep_in_progress)
+ ICOUNT -= timing.rep_movs16_base;
+ cpustate->rep_in_progress = FALSE;
+ while(cpustate->regs.w[CX])
+ {
+ WORD tmp;
+
+// if (ICOUNT <= 0) { cpustate->pc = cpustate->prevpc; cpustate->rep_in_progress = TRUE; break; }
+ tmp = GetMemW(DS,cpustate->regs.w[SI]);
+ PutMemW(ES,cpustate->regs.w[DI], tmp);
+ cpustate->regs.w[CX]--;
+ cpustate->regs.w[DI] += 2 * cpustate->DirVal;
+ cpustate->regs.w[SI] += 2 * cpustate->DirVal;
+ ICOUNT -= timing.rep_movs16_count;
+ }
+ break;
+ case 0xa6: /* REP(N)E CMPSB */
+ if (!cpustate->rep_in_progress)
+ ICOUNT -= timing.rep_cmps8_base;
+ cpustate->rep_in_progress = FALSE;
+ cpustate->ZeroVal = !flagval;
+ while(cpustate->regs.w[CX] && (ZF == flagval))
+ {
+ unsigned dst, src;
+
+// if (ICOUNT <= 0) { cpustate->pc = cpustate->prevpc; cpustate->rep_in_progress = TRUE; break; }
+ dst = GetMemB(ES, cpustate->regs.w[DI]);
+ src = GetMemB(DS, cpustate->regs.w[SI]);
+ SUBB(src,dst); /* opposite of the usual convention */
+ cpustate->regs.w[CX]--;
+ cpustate->regs.w[DI] += cpustate->DirVal;
+ cpustate->regs.w[SI] += cpustate->DirVal;
+ ICOUNT -= timing.rep_cmps8_count;
+ }
+ break;
+ case 0xa7: /* REP(N)E CMPSW */
+ if (!cpustate->rep_in_progress)
+ ICOUNT -= timing.rep_cmps16_base;
+ cpustate->rep_in_progress = FALSE;
+ cpustate->ZeroVal = !flagval;
+ while(cpustate->regs.w[CX] && (ZF == flagval))
+ {
+ unsigned dst, src;
+
+// if (ICOUNT <= 0) { cpustate->pc = cpustate->prevpc; cpustate->rep_in_progress = TRUE; break; }
+ dst = GetMemW(ES, cpustate->regs.w[DI]);
+ src = GetMemW(DS, cpustate->regs.w[SI]);
+ SUBW(src,dst); /* opposite of the usual convention */
+ cpustate->regs.w[CX]--;
+ cpustate->regs.w[DI] += 2 * cpustate->DirVal;
+ cpustate->regs.w[SI] += 2 * cpustate->DirVal;
+ ICOUNT -= timing.rep_cmps16_count;
+ }
+ break;
+ case 0xaa: /* REP STOSB */
+ if (!cpustate->rep_in_progress)
+ ICOUNT -= timing.rep_stos8_base;
+ cpustate->rep_in_progress = FALSE;
+ while(cpustate->regs.w[CX])
+ {
+// if (ICOUNT <= 0) { cpustate->pc = cpustate->prevpc; cpustate->rep_in_progress = TRUE; break; }
+ PutMemB(ES,cpustate->regs.w[DI],cpustate->regs.b[AL]);
+ cpustate->regs.w[CX]--;
+ cpustate->regs.w[DI] += cpustate->DirVal;
+ ICOUNT -= timing.rep_stos8_count;
+ }
+ break;
+ case 0xab: /* REP STOSW */
+ if (!cpustate->rep_in_progress)
+ ICOUNT -= timing.rep_stos16_base;
+ cpustate->rep_in_progress = FALSE;
+ while(cpustate->regs.w[CX])
+ {
+// if (ICOUNT <= 0) { cpustate->pc = cpustate->prevpc; cpustate->rep_in_progress = TRUE; break; }
+ PutMemW(ES,cpustate->regs.w[DI],cpustate->regs.w[AX]);
+ cpustate->regs.w[CX]--;
+ cpustate->regs.w[DI] += 2 * cpustate->DirVal;
+ ICOUNT -= timing.rep_stos16_count;
+ }
+ break;
+ case 0xac: /* REP LODSB */
+ if (!cpustate->rep_in_progress)
+ ICOUNT -= timing.rep_lods8_base;
+ cpustate->rep_in_progress = FALSE;
+ while(cpustate->regs.w[CX])
+ {
+// if (ICOUNT <= 0) { cpustate->pc = cpustate->prevpc; cpustate->rep_in_progress = TRUE; break; }
+ cpustate->regs.b[AL] = GetMemB(DS,cpustate->regs.w[SI]);
+ cpustate->regs.w[CX]--;
+ cpustate->regs.w[SI] += cpustate->DirVal;
+ ICOUNT -= timing.rep_lods8_count;
+ }
+ break;
+ case 0xad: /* REP LODSW */
+ if (!cpustate->rep_in_progress)
+ ICOUNT -= timing.rep_lods16_base;
+ cpustate->rep_in_progress = FALSE;
+ while(cpustate->regs.w[CX])
+ {
+// if (ICOUNT <= 0) { cpustate->pc = cpustate->prevpc; cpustate->rep_in_progress = TRUE; break; }
+ cpustate->regs.w[AX] = GetMemW(DS,cpustate->regs.w[SI]);
+ cpustate->regs.w[CX]--;
+ cpustate->regs.w[SI] += 2 * cpustate->DirVal;
+ ICOUNT -= timing.rep_lods16_count;
+ }
+ break;
+ case 0xae: /* REP(N)E SCASB */
+ if (!cpustate->rep_in_progress)
+ ICOUNT -= timing.rep_scas8_base;
+ cpustate->rep_in_progress = FALSE;
+ cpustate->ZeroVal = !flagval;
+ while(cpustate->regs.w[CX] && (ZF == flagval))
+ {
+ unsigned src, dst;
+
+// if (ICOUNT <= 0) { cpustate->pc = cpustate->prevpc; cpustate->rep_in_progress = TRUE; break; }
+ src = GetMemB(ES, cpustate->regs.w[DI]);
+ dst = cpustate->regs.b[AL];
+ SUBB(dst,src);
+ cpustate->regs.w[CX]--;
+ cpustate->regs.w[DI] += cpustate->DirVal;
+ ICOUNT -= timing.rep_scas8_count;
+ }
+ break;
+ case 0xaf: /* REP(N)E SCASW */
+ if (!cpustate->rep_in_progress)
+ ICOUNT -= timing.rep_scas16_base;
+ cpustate->rep_in_progress = FALSE;
+ cpustate->ZeroVal = !flagval;
+ while(cpustate->regs.w[CX] && (ZF == flagval))
+ {
+ unsigned src, dst;
+
+// if (ICOUNT <= 0) { cpustate->pc = cpustate->prevpc; cpustate->rep_in_progress = TRUE; break; }
+ src = GetMemW(ES, cpustate->regs.w[DI]);
+ dst = cpustate->regs.w[AX];
+ SUBW(dst,src);
+ cpustate->regs.w[CX]--;
+ cpustate->regs.w[DI] += 2 * cpustate->DirVal;
+ ICOUNT -= timing.rep_scas16_count;
+ }
+ break;
+ default:
+ PREFIX(_instruction)[next](cpustate);
+ }
+}
+
+void IX86_OPS_BASE::i80286_trap2(UINT32 error)
+{
+ int error_code = error & 0xffff;
+ UINT16 number = error >> 16;
+ if(error_code == 0xffff) error_code = -1;
+ cpustate->pc = cpustate->prevpc;
+ try {
+ switch(number) {
+ case DIVIDE_BY_ZERO:
+ case INVALID_TSS:
+ case SEG_NOT_PRESENT:
+ case STACK_FAULT:
+ case GENERAL_PROTECTION_FAULT:
+ cpustate->trap_level++;
+ if(cpustate->trap_level == 2) throw TRAP(DOUBLE_FAULT,0);
+ if(cpustate->trap_level == 3) break;
+ i80286_interrupt_descriptor(cpustate,number,1,error_code);
+ break;
+ case DOUBLE_FAULT:
+ i80286_interrupt_descriptor(cpustate,number,1,0);
+ break;
+ default:
+ i80286_interrupt_descriptor(cpustate,number,1,-1);
+ }
+ } catch(UINT32 e) { i80286_trap2(cpustate, e); }
+ if(cpustate->trap_level == 3) {
+ // this is supposed to triggered by support hardware
+ // create a shutdown output line that causes a reset
+ // NMI can wake processor without reset
+ CPU_RESET_CALL(CPU_MODEL);
+ cpustate->shutdown = 1;
+ }
+ cpustate->trap_level = 0;
+}
+
+static UINT32 i80286_selector_address(UINT16 sel)
+{
+ UINT32 base;
+ UINT16 limit;
+ if(TBL(sel)) { base = cpustate->ldtr.base; limit = cpustate->ldtr.limit; }
+ else { base = cpustate->gdtr.base; limit = cpustate->gdtr.limit; }
+ return ((IDX(sel)>=limit)||!IDXTBL(sel)?-1:base+IDX(sel));
+}
+
+static int i80286_verify(UINT16 selector, i80286_operation operation, UINT8 rights, bool valid)
+{
+ if (!IDXTBL(selector) && !valid) return GENERAL_PROTECTION_FAULT;
+ if (!SEGDESC(rights)) return GENERAL_PROTECTION_FAULT;
+
+ switch(operation) {
+ case I80286_READ:
+ if (CODE(rights) && !READ(rights)) return GENERAL_PROTECTION_FAULT;
+ break;
+ case I80286_WRITE:
+ if (CODE(rights) || !RW(rights)) return GENERAL_PROTECTION_FAULT;
+ break;
+ case I80286_EXECUTE:
+ if (!CODE(rights)) return GENERAL_PROTECTION_FAULT;
+ break;
+ }
+ return 0;
+}
+
+void IX86_OPS_BASE::i80286_pop_seg(int reg)
+{
+ UINT16 sel;
+ if(PM) i80286_check_permission(cpustate, SS, cpustate->regs.w[SP], I80286_WORD, I80286_READ);
+ sel = ReadWord(cpustate->base[SS]+cpustate->regs.w[SP]);
+ i80286_data_descriptor(cpustate, reg, sel);
+ cpustate->regs.w[SP] += 2;
+}
+
+void IX86_OPS_BASE::i80286_data_descriptor_full(int reg, UINT16 selector, int cpl, UINT32 trap, UINT16 offset, int size)
+{
+ if (PM) {
+ UINT16 desc[3];
+ UINT8 r;
+ UINT32 addr;
+ /* selector format
+ 15..3 number/address in descriptor table
+ 2: 0 global, 1 local descriptor table
+ 1,0: requested privileg level
+ must be higher or same as current privileg level in code selector */
+ if ((reg != SS) && !IDXTBL(selector)) {
+ cpustate->sregs[reg]=0;
+ cpustate->limit[reg]=0;
+ cpustate->base[reg]=0;
+ cpustate->rights[reg]=0;
+ cpustate->valid[reg]=0;
+ return;
+ }
+
+ if ((addr = i80286_selector_address(cpustate,selector)) == -1) throw trap;
+
+ desc[0] = ReadWord(addr);
+ desc[1] = ReadWord(addr+2);
+ desc[2] = ReadWord(addr+4);
+ r = RIGHTS(desc);
+ if (!SEGDESC(r)) throw trap;
+ if (reg == SS) {
+ if (!IDXTBL(selector)) throw trap;
+ if (DPL(r)!=cpl) throw trap;
+ if (RPL(selector)!=cpl) throw trap;
+ if (!RW(r) || CODE(r)) throw trap;
+ if (!PRES(r)) throw TRAP(STACK_FAULT,(IDXTBL(selector)+(trap&1)));
+ } else {
+ if ((DPL(r) < PMAX(cpl,RPL(selector))) && (!CODE(r) || (CODE(r) && !CONF(r)))) throw trap;
+ if (CODE(r) && !READ(r)) throw trap;
+ if (!PRES(r)) throw TRAP(SEG_NOT_PRESENT,(IDXTBL(selector)+(trap&1)));
+ }
+ if (offset+size) {
+ if ((CODE(r) || !EXPDOWN(r)) && ((offset+size-1) > LIMIT(desc))) throw (reg==SS)?TRAP(STACK_FAULT,(trap&1)):trap;
+ if (!CODE(r) && EXPDOWN(r) && ((offset <= LIMIT(desc)) || ((offset+size-1) > 0xffff))) throw (reg==SS)?TRAP(STACK_FAULT,(trap&1)):trap;
+ }
+
+ SET_ACC(desc);
+ WriteWord(addr+4, desc[2]);
+ cpustate->sregs[reg]=selector;
+ cpustate->limit[reg]=LIMIT(desc);
+ cpustate->base[reg]=BASE(desc);
+ cpustate->rights[reg]=RIGHTS(desc);
+ } else {
+ cpustate->sregs[reg]=selector;
+ cpustate->base[reg]=selector<<4;
+ }
+ cpustate->valid[reg]=1;
+}
+
+void IX86_OPS_BASE::i80286_data_descriptor(int reg, UINT16 selector)
+{
+ i80286_data_descriptor_full(cpustate, reg, selector, CPL, TRAP(GENERAL_PROTECTION_FAULT,IDXTBL(selector)), 0, 0);
+}
+
+void IX86_OPS_BASE::i80286_switch_task(UINT16 ntask, int type)
+{
+ UINT16 ndesc[3], desc[3], ntss[22], otss[22];
+ UINT8 r, lr;
+ UINT32 naddr, oaddr, ldtaddr;
+ int i;
+ logerror("This program uses TSSs, how rare. Please report this to the developers.\n");
+ if (TBL(ntask)) throw TRAP(INVALID_TSS,IDXTBL(ntask));
+ if ((naddr = i80286_selector_address(cpustate,ntask)) == -1) throw TRAP(INVALID_TSS,IDXTBL(ntask));
+ oaddr = i80286_selector_address(cpustate,cpustate->tr.sel);
+ ndesc[0] = ReadWord(naddr);
+ ndesc[1] = ReadWord(naddr+2);
+ ndesc[2] = ReadWord(naddr+4);
+ desc[2] = ReadWord(oaddr+4);
+ r = RIGHTS(ndesc);
+ if (SEGDESC(r) || ((GATE(r) & ~2) != TSSDESCIDLE)) throw TRAP(GENERAL_PROTECTION_FAULT,IDXTBL(ntask));
+ if (!PRES(r)) throw TRAP(SEG_NOT_PRESENT, IDXTBL(ntask));
+ if (LIMIT(ndesc) < 43) throw TRAP(INVALID_TSS,IDXTBL(ntask));
+ for (i = 0; i < 44; i+=2) ntss[i/2] = ReadWord(BASE(ndesc)+i);
+
+ cpustate->flags = CompressFlags();
+ if (type == CALL) WriteWord(BASE(ndesc)+TSS_BACK*2, cpustate->tr.sel);
+ if (type == IRET) cpustate->flags &= ~0x4000;
+
+ otss[TSS_IP] = cpustate->pc-cpustate->base[CS];
+ otss[TSS_FLAG] = cpustate->flags;
+ otss[TSS_AX] = cpustate->regs.w[AX];
+ otss[TSS_CX] = cpustate->regs.w[CX];
+ otss[TSS_DX] = cpustate->regs.w[DX];
+ otss[TSS_BX] = cpustate->regs.w[BX];
+ otss[TSS_SP] = cpustate->regs.w[SP];
+ otss[TSS_BP] = cpustate->regs.w[BP];
+ otss[TSS_SI] = cpustate->regs.w[SI];
+ otss[TSS_DI] = cpustate->regs.w[DI];
+ otss[TSS_ES] = cpustate->sregs[ES];
+ otss[TSS_CS] = cpustate->sregs[CS];
+ otss[TSS_SS] = cpustate->sregs[SS];
+ otss[TSS_DS] = cpustate->sregs[DS];
+ otss[TSS_LDT] = cpustate->ldtr.sel;
+
+ for (i = 14; i < 44; i+=2) WriteWord(cpustate->tr.base+i, otss[i/2]);
+
+ // jmp does both
+ if (type != CALL) {
+ desc[2] &= ~0x200; // mark idle
+ WriteWord(oaddr+4, desc[2]);
+ }
+ if (type != IRET) {
+ ndesc[2] |= 0x200;
+ WriteWord(naddr+4, ndesc[2]);
+ }
+ cpustate->tr.sel=ntask;
+ cpustate->tr.limit=LIMIT(ndesc);
+ cpustate->tr.base=BASE(ndesc);
+ cpustate->tr.rights=RIGHTS(ndesc);
+
+ cpustate->flags = ntss[TSS_FLAG];
+ cpustate->regs.w[AX] = ntss[TSS_AX];
+ cpustate->regs.w[CX] = ntss[TSS_CX];
+ cpustate->regs.w[DX] = ntss[TSS_DX];
+ cpustate->regs.w[BX] = ntss[TSS_BX];
+ cpustate->regs.w[SP] = ntss[TSS_SP];
+ cpustate->regs.w[BP] = ntss[TSS_BP];
+ cpustate->regs.w[SI] = ntss[TSS_SI];
+ cpustate->regs.w[DI] = ntss[TSS_DI];
+
+ if (TBL(ntss[TSS_LDT])) throw TRAP(INVALID_TSS,IDXTBL(ntss[TSS_LDT]));
+ if (IDXTBL(ntss[TSS_LDT])) {
+ if ((ldtaddr = i80286_selector_address(cpustate,ntss[TSS_LDT])) == -1)
+ throw TRAP(INVALID_TSS,IDXTBL(ntss[TSS_LDT]));
+ desc[0] = ReadWord(ldtaddr);
+ desc[1] = ReadWord(ldtaddr+2);
+ desc[2] = ReadWord(ldtaddr+4);
+ lr = RIGHTS(desc);
+ if (SEGDESC(lr) || (GATE(lr) != LDTDESC)) throw TRAP(INVALID_TSS,IDXTBL(ntss[TSS_LDT]));
+ if (!PRES(lr)) throw TRAP(INVALID_TSS,IDXTBL(ntss[TSS_LDT]));
+ cpustate->ldtr.sel=ntss[TSS_LDT];
+ cpustate->ldtr.limit=LIMIT(desc);
+ cpustate->ldtr.base=BASE(desc);
+ cpustate->ldtr.rights=RIGHTS(desc);
+ } else {
+ cpustate->ldtr.sel=0;
+ cpustate->ldtr.limit=0;
+ cpustate->ldtr.base=0;
+ cpustate->ldtr.rights=0;
+ }
+
+ if (type == CALL) cpustate->flags |= 0x4000;
+ cpustate->msw |= 8;
+ i80286_data_descriptor_full(cpustate, SS, ntss[TSS_SS], RPL(ntss[TSS_CS]), TRAP(INVALID_TSS,IDXTBL(ntss[TSS_SS])), 0, 0);
+
+ cpustate->sregs[CS] = IDXTBL(cpustate->sregs[CS]) | RPL(ntss[TSS_CS]); // fixme
+ try {
+ i80286_code_descriptor(cpustate, ntss[TSS_CS], ntss[TSS_IP], 0);
+ } catch(UINT32 e) {
+ int error_code = e & 0xffff;
+ if(error_code == GENERAL_PROTECTION_FAULT) e = TRAP(INVALID_TSS,(e >> 16)); // #NP fault is correct
+ throw e;
+ }
+
+ i80286_data_descriptor_full(cpustate, ES, ntss[TSS_ES], RPL(ntss[TSS_CS]), TRAP(INVALID_TSS,IDXTBL(ntss[TSS_ES])), 0, 0);
+ i80286_data_descriptor_full(cpustate, DS, ntss[TSS_DS], RPL(ntss[TSS_CS]), TRAP(INVALID_TSS,IDXTBL(ntss[TSS_DS])), 0, 0);
+}
+
+void IX86_OPS_BASE::i80286_code_descriptor(UINT16 selector, UINT16 offset, int gate)
+{
+ if (PM) {
+ UINT16 desc[3];
+ UINT8 r;
+ UINT32 addr;
+ /* selector format
+ 15..3 number/address in descriptor table
+ 2: 0 global, 1 local descriptor table
+ 1,0: requested privileg level
+ must be higher or same as current privileg level in code selector */
+ if ((addr = i80286_selector_address(cpustate,selector)) == -1) throw TRAP(GENERAL_PROTECTION_FAULT,IDXTBL(selector));
+ desc[0] = ReadWord(addr);
+ desc[1] = ReadWord(addr+2);
+ desc[2] = ReadWord(addr+4);
+ r = RIGHTS(desc);
+
+ if (SEGDESC(r)) {
+ if (!CODE(r)) throw TRAP(GENERAL_PROTECTION_FAULT,IDXTBL(selector));
+ if (CONF(r)) { if(DPL(r)>CPL) throw TRAP(GENERAL_PROTECTION_FAULT,IDXTBL(selector)); }
+ else if ((RPL(selector)>CPL) || (DPL(r)!=CPL)) throw TRAP(GENERAL_PROTECTION_FAULT,IDXTBL(selector));
+
+ if (!PRES(r)) throw TRAP(SEG_NOT_PRESENT,IDXTBL(selector)); // this order is important
+ if (offset > LIMIT(desc)) throw TRAP(GENERAL_PROTECTION_FAULT, 0);
+ SET_ACC(desc);
+ WriteWord(addr+4, desc[2]);
+ cpustate->sregs[CS]=IDXTBL(selector) | CPL;
+ cpustate->limit[CS]=LIMIT(desc);
+ cpustate->base[CS]=BASE(desc);
+ cpustate->rights[CS]=RIGHTS(desc);
+ cpustate->pc=cpustate->base[CS]+offset;
+ } else { // systemdescriptor
+ UINT16 gatedesc[3]={0,0,0};
+ UINT16 gatesel = GATESEL(desc);
+ if (!gate) throw TRAP(GENERAL_PROTECTION_FAULT,IDXTBL(selector)); // tss cs must be segment
+ if (DPL(r) < PMAX(CPL,RPL(selector))) throw TRAP(GENERAL_PROTECTION_FAULT,IDXTBL(selector));
+ if (!PRES(r)) throw TRAP(SEG_NOT_PRESENT, IDXTBL(selector));
+
+ switch (GATE(r)) {
+ case CALLGATE:
+ if ((addr = i80286_selector_address(cpustate,gatesel)) == -1)
+ throw TRAP(GENERAL_PROTECTION_FAULT,IDXTBL(gatesel));
+ gatedesc[0] = ReadWord(addr);
+ gatedesc[1] = ReadWord(addr+2);
+ gatedesc[2] = ReadWord(addr+4);
+ r = RIGHTS(gatedesc);
+ if (!CODE(r) || !SEGDESC(r)) throw TRAP(GENERAL_PROTECTION_FAULT,IDXTBL(gatesel));
+ if (DPL(r)>CPL) throw TRAP(GENERAL_PROTECTION_FAULT,IDXTBL(gatesel));
+ if (!PRES(r)) throw TRAP(SEG_NOT_PRESENT,IDXTBL(gatesel));
+ if (GATEOFF(desc) > LIMIT(gatedesc)) throw TRAP(GENERAL_PROTECTION_FAULT,0);
+
+ if (!CONF(r)&&(DPL(r)<CPL)) { // inner call
+ UINT16 tss_ss, tss_sp, oldss, oldsp;
+ UINT32 oldstk;
+ int i;
+ if(gate == JMP) throw TRAP(GENERAL_PROTECTION_FAULT,IDXTBL(gatesel)); // can't jmp to inner
+ tss_ss = ReadWord(cpustate->tr.base+TSS_SS0*2+(DPL(r)*4));
+ tss_sp = ReadWord(cpustate->tr.base+TSS_SP0*2+(DPL(r)*4));
+
+ oldss = cpustate->sregs[SS];
+ oldsp = cpustate->regs.w[SP];
+ oldstk = cpustate->base[SS] + oldsp;
+ i80286_data_descriptor_full(cpustate, SS, tss_ss, DPL(r), TRAP(INVALID_TSS,IDXTBL(tss_ss)), tss_sp-8-(GATECNT(desc)*2), 8+(GATECNT(desc)*2));
+ cpustate->regs.w[SP] = tss_sp;
+ PUSH(oldss);
+ PUSH(oldsp);
+ for (i = GATECNT(desc)-1; i >= 0; i--)
+ PUSH(ReadWord(oldstk+(i*2)));
+ } else i80286_check_permission(cpustate, SS, cpustate->regs.w[SP]-4, 4, I80286_READ);
+ SET_ACC(gatedesc);
+ WriteWord(addr+4, gatedesc[2]);
+ cpustate->sregs[CS]=IDXTBL(gatesel) | DPL(r);
+ cpustate->limit[CS]=LIMIT(gatedesc);
+ cpustate->base[CS]=BASE(gatedesc);
+ cpustate->rights[CS]=RIGHTS(gatedesc);
+ cpustate->pc=(cpustate->base[CS]+GATEOFF(desc))&AMASK;
+ break;
+ case TASKGATE:
+ selector = gatesel;
+ if ((addr = i80286_selector_address(cpustate,selector)) == -1)
+ throw TRAP(GENERAL_PROTECTION_FAULT,IDXTBL(selector));
+ desc[2] = ReadWord(addr+4);
+ r = RIGHTS(desc);
+ if (SEGDESC(r) || (GATE(r) != TSSDESCIDLE)) throw TRAP(GENERAL_PROTECTION_FAULT,IDXTBL(selector));
+ case TSSDESCIDLE:
+ i80286_switch_task(cpustate, selector, gate);
+ i80286_load_flags(cpustate, cpustate->flags, CPL);
+ break;
+ default:
+ throw TRAP(GENERAL_PROTECTION_FAULT,IDXTBL(selector));
+ }
+ }
+ } else {
+ cpustate->sregs[CS]=selector;
+ cpustate->base[CS]=selector<<4;
+ cpustate->rights[CS]=0x9a;
+ cpustate->limit[CS]=0xffff;
+ cpustate->pc=(cpustate->base[CS]+offset)&AMASK;
+ }
+}
+
+void IX86_OPS_BASE::i80286_interrupt_descriptor(UINT16 number, int hwint, int error)
+{
+ UINT16 desc[3], gatedesc[3]={0,0,0}, gatesel;
+ UINT8 r;
+ UINT32 addr;
+
+ if(!PM) return PREFIX86(_interrupt)(cpustate, number);
+
+ if ((number<<3)>=cpustate->idtr.limit)
+ throw TRAP(GENERAL_PROTECTION_FAULT,(number*8+2+(hwint&&1)));
+
+ desc[0] = ReadWord(cpustate->idtr.base+(number<<3));
+ desc[1] = ReadWord(cpustate->idtr.base+(number<<3)+2);
+ desc[2] = ReadWord(cpustate->idtr.base+(number<<3)+4);
+ r = RIGHTS(desc);
+ if (!hwint && (DPL(r)<CPL)) throw TRAP(GENERAL_PROTECTION_FAULT,(number*8+2+(hwint&&1)));
+ if (!PRES(r)) throw TRAP(SEG_NOT_PRESENT,(number*8+2+(hwint&&1)));
+ gatesel = GATESEL(desc);
+
+ switch (GATE(r)) {
+ case TASKGATE:
+ i80286_switch_task(cpustate, gatesel, CALL);
+ if((hwint == 1) && (error != -1)) PUSH(error);
+ i80286_load_flags(cpustate, cpustate->flags, CPL);
+ break;
+ case INTGATE:
+ case TRAPGATE:
+ if ((addr = i80286_selector_address(cpustate,gatesel)) == -1)
+ throw TRAP(GENERAL_PROTECTION_FAULT,(IDXTBL(gatesel)+(hwint&&1)));
+ gatedesc[0] = ReadWord(addr);
+ gatedesc[1] = ReadWord(addr+2);
+ gatedesc[2] = ReadWord(addr+4);
+ r = RIGHTS(gatedesc);
+ if (!CODE(r) || !SEGDESC(r)) throw TRAP(GENERAL_PROTECTION_FAULT,(IDXTBL(gatesel)+(hwint&&1)));
+ if (DPL(r)>CPL) throw TRAP(GENERAL_PROTECTION_FAULT,(IDXTBL(gatesel)+(hwint&&1)));
+ if (!PRES(r)) throw TRAP(SEG_NOT_PRESENT,(IDXTBL(gatesel)+(hwint&&1)));
+ if (GATEOFF(desc) > LIMIT(gatedesc)) throw TRAP(GENERAL_PROTECTION_FAULT,(int)(hwint&&1));
+
+ if (!CONF(r)&&(DPL(r)<CPL)) { // inner call
+ UINT16 tss_ss, tss_sp, oldss, oldsp;
+ tss_ss = ReadWord(cpustate->tr.base+TSS_SS0*2+(DPL(r)*4));
+ tss_sp = ReadWord(cpustate->tr.base+TSS_SP0*2+(DPL(r)*4));
+
+ oldss = cpustate->sregs[SS];
+ oldsp = cpustate->regs.w[SP];
+ i80286_data_descriptor_full(cpustate, SS, tss_ss, DPL(r), TRAP(INVALID_TSS,(IDXTBL(tss_ss)+(hwint&&1))), tss_sp-((error != -1)?12:10), (error != -1)?12:10);
+ cpustate->regs.w[SP] = tss_sp;
+ PUSH(oldss);
+ PUSH(oldsp);
+ } else i80286_check_permission(cpustate, SS, cpustate->regs.w[SP]-((error != -1)?8:6), (error != -1)?8:6, I80286_READ);
+ SET_ACC(gatedesc);
+ WriteWord(addr+4, gatedesc[2]);
+ PREFIX(_pushf());
+ PUSH(cpustate->sregs[CS]);
+ PUSH(cpustate->pc-cpustate->base[CS]);
+ if((hwint == 1) && (error != -1)) PUSH(error);
+ cpustate->sregs[CS]=IDXTBL(gatesel) | DPL(r);
+ cpustate->limit[CS]=LIMIT(gatedesc);
+ cpustate->base[CS]=BASE(gatedesc);
+ cpustate->rights[CS]=RIGHTS(gatedesc);
+ cpustate->pc=(cpustate->base[CS]+GATEOFF(desc))&AMASK;
+ cpustate->TF = 0;
+ cpustate->flags &= ~0x4000;
+ if (GATE(RIGHTS(desc)) == INTGATE) cpustate->IF = 0;
+ CHANGE_PC(cpustate->pc);
+ break;
+ default:
+ throw TRAP(GENERAL_PROTECTION_FAULT,(number*8+2+(hwint&&1)));
+ }
+}
+
+void IX86_OPS_BASE::PREFIX286(_0fpre)()
+{
+ unsigned next = FETCHOP;
+ UINT16 ModRM, desc[3];
+ UINT16 tmp, msw, sel;
+ UINT8 r;
+ UINT32 addr;
+
+ switch (next) {
+ case 0:
+ if (!PM) throw TRAP(ILLEGAL_INSTRUCTION,-1);
+ ModRM=FETCHOP;
+ switch (ModRM&0x38) {
+ case 0: /* sldt */
+ PutRMWord(ModRM, cpustate->ldtr.sel);
+ break;
+ case 8: /* str */
+ PutRMWord(ModRM, cpustate->tr.sel);
+ break;
+ case 0x10: /* lldt */
+ if (CPL!=0) throw TRAP(GENERAL_PROTECTION_FAULT,0);
+ sel=GetRMWord(ModRM);
+ if (TBL(sel)) throw TRAP(GENERAL_PROTECTION_FAULT,IDXTBL(sel));
+ if (IDXTBL(sel)) {
+ if (IDX(sel)>=cpustate->gdtr.limit) throw TRAP(GENERAL_PROTECTION_FAULT,IDXTBL(sel));
+ addr = cpustate->gdtr.base + IDX(sel);
+ desc[0] = ReadWord(addr);
+ desc[1] = ReadWord(addr+2);
+ desc[2] = ReadWord(addr+4);
+ r = RIGHTS(desc);
+ if (SEGDESC(r) || (GATE(r) != LDTDESC)) throw TRAP(GENERAL_PROTECTION_FAULT,IDXTBL(sel));
+ if (!PRES(r)) throw TRAP(SEG_NOT_PRESENT,IDXTBL(sel));
+ } else {
+ desc[0] = 0;
+ desc[1] = 0;
+ desc[2] = 0;
+ }
+ cpustate->ldtr.sel=sel;
+ cpustate->ldtr.limit=LIMIT(desc);
+ cpustate->ldtr.base=BASE(desc);
+ cpustate->ldtr.rights=RIGHTS(desc);
+ break;
+ case 0x18: /* ltr */
+ if (CPL!=0) throw TRAP(GENERAL_PROTECTION_FAULT,0);
+ sel=GetRMWord(ModRM);
+ if ((addr = i80286_selector_address(cpustate,sel)) == -1) throw TRAP(GENERAL_PROTECTION_FAULT,IDXTBL(sel));
+ desc[0] = ReadWord(addr);
+ desc[1] = ReadWord(addr+2);
+ desc[2] = ReadWord(addr+4);
+ r = RIGHTS(desc);
+ if (SEGDESC(r) || (GATE(r) != TSSDESCIDLE)) throw TRAP(GENERAL_PROTECTION_FAULT,IDXTBL(sel));
+ if (!PRES(r)) throw TRAP(SEG_NOT_PRESENT,IDXTBL(sel));
+ desc[2] |= 0x200; // mark busy
+ WriteWord(addr+4, desc[2]);
+ cpustate->tr.sel=sel;
+ cpustate->tr.limit=LIMIT(desc);
+ cpustate->tr.base=BASE(desc);
+ cpustate->tr.rights=RIGHTS(desc);
+ break;
+ case 0x20: /* verr */
+ tmp=GetRMWord(ModRM);
+ if ((addr = i80286_selector_address(cpustate,tmp)) == -1) cpustate->ZeroVal = 1;
+ else {
+ desc[2] = ReadWord(addr+4);
+ r = RIGHTS(desc);
+ cpustate->ZeroVal = i80286_verify(cpustate, tmp, I80286_READ, RIGHTS(desc), 0);
+ cpustate->ZeroVal = cpustate->ZeroVal || (CODE(r) && CONF(r) ? 0 : (DPL(r)<PMAX(RPL(tmp),CPL)));
+ }
+ break;
+ case 0x28: /* verw */
+ tmp=GetRMWord(ModRM);
+ if ((addr = i80286_selector_address(cpustate,tmp)) == -1) cpustate->ZeroVal = 1;
+ else {
+ desc[2] = ReadWord(addr+4);
+ r = RIGHTS(desc);
+ cpustate->ZeroVal = i80286_verify(cpustate, tmp, I80286_WRITE, RIGHTS(desc), 0);
+ cpustate->ZeroVal = cpustate->ZeroVal || (DPL(r)<PMAX(RPL(tmp),CPL));
+ }
+ break;
+ default:
+ throw TRAP(ILLEGAL_INSTRUCTION,-1);
+ }
+ break;
+ case 1:
+ /* lgdt, lldt in protected mode privilege level 0 required else common protection
+ failure 0xd */
+ ModRM = FETCHOP;
+ switch (ModRM&0x38) {
+ case 0: /* sgdt */
+ PutRMWord(ModRM,cpustate->gdtr.limit);
+ PutRMWordOffset(2,cpustate->gdtr.base&0xffff);
+ PutRMWordOffset(4,0xff00|cpustate->gdtr.base>>16);
+ break;
+ case 8: /* sidt */
+ PutRMWord(ModRM,cpustate->idtr.limit);
+ PutRMWordOffset(2,cpustate->idtr.base&0xffff);
+ PutRMWordOffset(4,0xff00|cpustate->idtr.base>>16);
+ break;
+ case 0x10: /* lgdt */
+ if (PM&&(CPL!=0)) throw TRAP(GENERAL_PROTECTION_FAULT,0);
+ cpustate->gdtr.limit=GetRMWord(ModRM);
+ cpustate->gdtr.base=GetRMWordOffset(2)|(GetRMByteOffset(4)<<16);
+ break;
+ case 0x18: /* lidt */
+ if (PM&&(CPL!=0)) throw TRAP(GENERAL_PROTECTION_FAULT,0);
+ cpustate->idtr.limit=GetRMWord(ModRM);
+ cpustate->idtr.base=GetRMWordOffset(2)|(GetRMByteOffset(4)<<16);
+ break;
+ case 0x20: /* smsw */
+ PutRMWord(ModRM, cpustate->msw);
+ break;
+ case 0x30: /* lmsw */
+ if (PM&&(CPL!=0)) throw TRAP(GENERAL_PROTECTION_FAULT,0);
+ msw = GetRMWord(ModRM);
+ if (!PM&&(msw&1)) cpustate->sregs[CS] = IDX(cpustate->sregs[CS]); // cheat and set cpl to 0
+ cpustate->msw=(cpustate->msw&1)|msw;
+ break;
+ default:
+ throw TRAP(ILLEGAL_INSTRUCTION,-1);
+ }
+ break;
+ case 2: /* LAR */
+ if (!PM) throw TRAP(ILLEGAL_INSTRUCTION,-1);
+ ModRM = FETCHOP;
+ tmp=GetRMWord(ModRM);
+ if ((addr = i80286_selector_address(cpustate,tmp)) == -1) cpustate->ZeroVal = 1;
+ else {
+ desc[2] = ReadWord(addr+4);
+ r = RIGHTS(desc);
+ if (DPL(r)>=PMAX(RPL(tmp),CPL) || (SEGDESC(r) && CODE(r) && CONF(r))) {
+ cpustate->ZeroVal = 0;
+ // rights are expected to be in upper byte
+ RegWord(ModRM) = r << 8;
+ }
+ else
+ cpustate->ZeroVal = 1;
+ }
+ break;
+ case 3: /* LSL */
+ if (!PM) throw TRAP(ILLEGAL_INSTRUCTION,-1);
+ ModRM = FETCHOP;
+ tmp=GetRMWord(ModRM);
+ if ((addr = i80286_selector_address(cpustate,tmp)) == -1) cpustate->ZeroVal = 1;
+ else {
+ desc[2] = ReadWord(addr+4);
+ r = RIGHTS(desc);
+ if (!SEGDESC(r) && (GATE(r) >= CALLGATE)) cpustate->ZeroVal = 1; // not valid for gates
+ else if (DPL(r)>=PMAX(RPL(tmp),CPL) || (SEGDESC(r) && CODE(r) && CONF(r))) {
+ cpustate->ZeroVal = 0;
+ RegWord(ModRM) = ReadWord(addr);
+ }
+ else
+ cpustate->ZeroVal = 1;
+ }
+ break;
+ case 5: /* loadall */
+ if (PM&&(CPL!=0)) throw TRAP(GENERAL_PROTECTION_FAULT,0);
+ cpustate->msw = (cpustate->msw&1)|ReadWord(0x806);
+ cpustate->tr.sel = ReadWord(0x816);
+ tmp = ReadWord(0x818);
+ ExpandFlags(tmp);
+ cpustate->flags = tmp;
+ cpustate->flags = CompressFlags();
+ cpustate->pc = ReadWord(0x81a);
+ cpustate->ldtr.sel = ReadWord(0x81c);
+ cpustate->sregs[DS] = ReadWord(0x81e);
+ cpustate->sregs[SS] = ReadWord(0x820);
+ cpustate->sregs[CS] = ReadWord(0x822);
+ cpustate->sregs[ES] = ReadWord(0x824);
+ cpustate->regs.w[DI] = ReadWord(0x826);
+ cpustate->regs.w[SI] = ReadWord(0x828);
+ cpustate->regs.w[BP] = ReadWord(0x82a);
+ cpustate->regs.w[SP] = ReadWord(0x82c);
+ cpustate->regs.w[BX] = ReadWord(0x82e);
+ cpustate->regs.w[DX] = ReadWord(0x830);
+ cpustate->regs.w[CX] = ReadWord(0x832);
+ cpustate->regs.w[AX] = ReadWord(0x834);
+// loadall uses base-rights-limit order
+#define LOADDESC(addr, sreg) { desc[1] = ReadWord(addr); desc[2] = ReadWord(addr+2); desc[0] = ReadWord(addr+4); \
+ cpustate->base[sreg] = BASE(desc); cpustate->rights[sreg] = RIGHTS(desc); \
+ cpustate->limit[sreg] = LIMIT(desc); }
+ LOADDESC(0x836, ES);
+ LOADDESC(0x83C, CS);
+ LOADDESC(0x842, SS);
+ LOADDESC(0x848, DS);
+#undef LOADDESC
+// void cast supresses warning
+#define LOADDESC(addr, reg, r) { desc[1] = ReadWord(addr); desc[2] = ReadWord(addr+2); desc[0] = ReadWord(addr+4); \
+ cpustate->reg.base = BASE(desc); (void)(r); cpustate->reg.limit = LIMIT(desc); }
+ LOADDESC(0x84e, gdtr, 1);
+ LOADDESC(0x854, ldtr, cpustate->ldtr.rights = RIGHTS(desc));
+ LOADDESC(0x85a, idtr, 1);
+ LOADDESC(0x860, tr, cpustate->tr.rights = RIGHTS(desc));
+#undef LOADDESC
+ cpustate->pc = (cpustate->pc + cpustate->base[CS]) & AMASK;
+ CHANGE_PC(cpustate->pc);
+ break;
+
+ case 6: /* clts */
+ if (PM&&(CPL!=0)) throw TRAP(GENERAL_PROTECTION_FAULT,0);
+ cpustate->msw&=~8;
+ break;
+ default:
+ throw TRAP(ILLEGAL_INSTRUCTION,-1);
+ }
+}
+
+void IX86_OPS_BASE::PREFIX286(_arpl)() /* 0x63 */
+{
+ UINT16 ModRM, tmp, source;
+ if (!PM) throw TRAP(ILLEGAL_INSTRUCTION,-1);
+
+ ModRM=FETCHOP;
+ tmp=GetRMWord(ModRM);
+ source=RegWord(ModRM);
+
+ if (RPL(tmp)<RPL(source))
+ {
+ cpustate->ZeroVal = 0;
+ PutbackRMWord(ModRM, IDXTBL(tmp)|RPL(source));
+ }
+ else
+ cpustate->ZeroVal = 1;
+}
+
+void IX86_OPS_BASE::i80286_load_flags(UINT16 flags, int cpl)
+{
+ cpustate->flags = CompressFlags();
+ if(PM && cpl) {
+ UINT16 mask = 0x3000;
+ if(cpl>IOPL) mask |= 0x200;
+ flags &= ~mask;
+ flags |= (cpustate->flags & mask);
+ }
+ else if(!PM) (flags &= ~0xf000);
+ ExpandFlags(flags);
+ cpustate->flags = flags;
+
+ if (cpustate->TF) PREFIX(_trap)();
+ /* if the IF is set, and an interrupt is pending, signal an interrupt */
+ if (cpustate->IF && cpustate->irq_state) {
+ i80286_interrupt_descriptor(cpustate, cpustate->pic->get_intr_ack(), 2, -1);
+ cpustate->irq_state = 0;
+ }
+}
+
+void IX86_OPS_BASE::PREFIX286(_popf)()
+{
+ UINT16 flags;
+ POP(flags);
+ ICOUNT -= timing.popf;
+ i80286_load_flags(cpustate, flags, CPL);
+}
+
+static UINT16 i80286_far_return(int iret, int bytes)
+{
+ UINT16 sel, off, flags = 0;
+ int spaddr;
+
+ if (PM && NT && iret) {
+ i80286_switch_task(cpustate, ReadWord(cpustate->tr.base+TSS_BACK*2), IRET);
+ return cpustate->flags;
+ }
+
+ // must be restartable
+ if(PM) i80286_check_permission(cpustate, SS, cpustate->regs.w[SP], (iret?6:4), I80286_READ);
+ spaddr = (cpustate->base[SS] + cpustate->regs.w[SP]) & AMASK;
+ off = ReadWord(spaddr);
+ sel = ReadWord(spaddr+2);
+ if(iret) flags = ReadWord(spaddr+4);
+
+ if(PM) {
+ UINT16 desc[3], newsp, newss;
+ int addr, r;
+
+ if ((addr = i80286_selector_address(cpustate,sel)) == -1)
+ throw TRAP(GENERAL_PROTECTION_FAULT,IDXTBL(sel));
+
+ if (RPL(sel)<CPL) throw TRAP(GENERAL_PROTECTION_FAULT,IDXTBL(sel));
+ desc[0] = ReadWord(addr);
+ desc[1] = ReadWord(addr+2);
+ desc[2] = ReadWord(addr+4);
+ r = RIGHTS(desc);
+
+ if (!CODE(r) || !SEGDESC(r)) throw TRAP(GENERAL_PROTECTION_FAULT,IDXTBL(sel));
+ if (CONF(r)) { if(DPL(r)>RPL(sel)) throw TRAP(GENERAL_PROTECTION_FAULT,IDXTBL(sel)); }
+ else if (DPL(r)!=RPL(sel)) throw TRAP(GENERAL_PROTECTION_FAULT,IDXTBL(sel));
+
+ if (!PRES(r)) throw TRAP(SEG_NOT_PRESENT,IDXTBL(sel));
+ if (off > LIMIT(desc)) throw TRAP(GENERAL_PROTECTION_FAULT,0);
+ if (CPL<RPL(sel)) {
+ i80286_check_permission(cpustate, SS, cpustate->regs.w[SP]+(iret?6:4)+bytes, 4, I80286_READ);
+ newsp = ReadWord(spaddr+((iret?6:4)+bytes));
+ newss = ReadWord(spaddr+((iret?8:6)+bytes));
+ i80286_data_descriptor_full(cpustate, SS, newss, RPL(sel), TRAP(GENERAL_PROTECTION_FAULT,IDXTBL(newss)), 0, 0);
+ cpustate->regs.w[SP] = newsp + bytes;
+ } else cpustate->regs.w[SP] += (iret?6:4) + bytes;
+ SET_ACC(desc);
+ WriteWord(addr+4, desc[2]);
+ cpustate->sregs[CS]=sel;
+ cpustate->limit[CS]=LIMIT(desc);
+ cpustate->base[CS]=BASE(desc);
+ cpustate->rights[CS]=RIGHTS(desc);
+ cpustate->pc=(cpustate->base[CS]+off)&AMASK;
+
+ // docs say check rpl but windows doesn't like it
+ r = cpustate->rights[DS];
+ if (i80286_verify(cpustate, cpustate->sregs[DS], I80286_READ, r, 0) || (CODE(r) && CONF(r) ? 0 : (DPL(r) < CPL)))
+ i80286_data_descriptor(cpustate, DS, 0);
+ r = cpustate->rights[ES];
+ if (i80286_verify(cpustate, cpustate->sregs[ES], I80286_READ, r, 0) || (CODE(r) && CONF(r) ? 0 : (DPL(r) < CPL)))
+ i80286_data_descriptor(cpustate, ES, 0);
+ } else {
+ cpustate->regs.w[SP] += (iret?6:4) + bytes;
+ cpustate->sregs[CS]=sel;
+ cpustate->base[CS]=sel<<4;
+ cpustate->rights[CS]=0x9a;
+ cpustate->limit[CS]=0xffff;
+ cpustate->pc=(cpustate->base[CS]+off)&AMASK;
+ }
+ CHANGE_PC(cpustate->pc);
+
+ return flags;
+}
+
+void IX86_OPS_BASE::PREFIX286(_iret)()
+{
+ int oldcpl = (PM)?CPL:0;
+ UINT16 flags = i80286_far_return(cpustate, 1, 0);
+ ICOUNT -= timing.iret;
+ i80286_load_flags(cpustate, flags, oldcpl);
+}
+
+void IX86_OPS_BASE::PREFIX286(_retf_d16)()
+{
+ unsigned count = FETCH;
+ count += FETCH << 8;
+ i80286_far_return(cpustate, 0, count);
+ ICOUNT -= timing.ret_far_imm;
+}
+
+void IX86_OPS_BASE::PREFIX286(_retf)()
+{
+ i80286_far_return(cpustate, 0, 0);
+ ICOUNT -= timing.ret_far;
+}
+
+void IX86_OPS_BASE::PREFIX286(_escape)() /* Opcodes 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde */
+{
+ if ((cpustate->msw&8) || (cpustate->msw&4)) throw TRAP(FPU_UNAVAILABLE,-1);
+ unsigned ModRM = FETCH;
+ ICOUNT -= timing.nop;
+ GetRMByte(ModRM);
+}
+
+void IX86_OPS_BASE::PREFIX286(_escape_7)() /* Opcode 0xdf */
+{
+ if ((cpustate->msw&8) || (cpustate->msw&4)) throw TRAP(FPU_UNAVAILABLE,-1);
+ unsigned ModRM = FETCH;
+ ICOUNT -= timing.nop;
+ GetRMByte(ModRM);
+ if (ModRM == 0xe0) cpustate->regs.w[AX] = 0xffff; // FPU not present
+}
+
+void IX86_OPS_BASE::i80286_check_permission(UINT8 check_seg, UINT32 offset, UINT16 size, i80286_operation operation)
+{
+ int trap = 0;
+ UINT8 rights;
+ if (PM) {
+ rights = cpustate->rights[check_seg];
+ trap = i80286_verify(cpustate, cpustate->sregs[check_seg], operation, rights, cpustate->valid[check_seg]);
+ if ((CODE(rights) || !EXPDOWN(rights)) && ((offset+size-1) > cpustate->limit[check_seg])) trap = GENERAL_PROTECTION_FAULT;
+ if (!CODE(rights) && EXPDOWN(rights) && ((offset <= cpustate->limit[check_seg]) || ((offset+size-1) > 0xffff))) trap = GENERAL_PROTECTION_FAULT;
+
+ if ((trap == GENERAL_PROTECTION_FAULT) && (check_seg == SS)) trap = STACK_FAULT;
+ if (trap) throw TRAP(trap, 0);
+ }
+}
+
+void IX86_OPS::PREFIX(_pop_ss)() /* Opcode 0x17 */
+{
+//#ifdef I80286
+ i80286_pop_seg(cpustate, SS);
+//#else
+// POP(cpustate->sregs[SS]);
+// cpustate->base[SS] = SegBase(SS);
+//#endif
+ ICOUNT -= timing.pop_seg;
+ PREFIX(_instruction)[FETCHOP](cpustate); /* no interrupt before next instruction */
+}
+
+void IX86_OPS::PREFIX(_mov_sregw)() /* Opcode 0x8e */
+{
+ unsigned ModRM = FETCH;
+ WORD src = GetRMWord(ModRM);
+
+ ICOUNT -= (ModRM >= 0xc0) ? timing.mov_sr : timing.mov_sm;
+
+ switch (ModRM & 0x38)
+ {
+ case 0x00: /* mov es,ew */
+ i80286_data_descriptor(cpustate,ES,src);
+ break;
+ case 0x18: /* mov ds,ew */
+ i80286_data_descriptor(cpustate,DS,src);
+ break;
+ case 0x10: /* mov ss,ew */
+ i80286_data_descriptor(cpustate,SS,src);
+ cpustate->seg_prefix = FALSE;
+ PREFIX(_instruction)[FETCHOP](cpustate);
+ break;
+ case 0x08: /* mov cs,ew */
+ PREFIX(_invalid)(cpustate);
+ break; /* doesn't do a jump far */
+ }
+}
+void IX86_OPS::PREFIX(_sti)() /* Opcode 0xfb */
+{
+//#ifdef I80286
+ if(PM && (CPL>IOPL)) throw TRAP(GENERAL_PROTECTION_FAULT,0);
+//#endif
+ ICOUNT -= timing.flag_ops;
+ SetIF(1);
+ PREFIX(_instruction)[FETCHOP](cpustate); /* no interrupt before next instruction */
+
+ /* if an interrupt is pending, signal an interrupt */
+ if (cpustate->irq_state) {
+//#ifdef I80286
+ i80286_interrupt_descriptor(cpustate, cpustate->pic->get_intr_ack(), 2, -1);
+//#else
+// PREFIX86(_interrupt)(cpustate, (UINT32)-1);
+//#endif
+ cpustate->irq_state = 0;
+ }
+}
+
+void IX86_OPS_BASE::PREFIX(_inc_bx)() /* Opcode 0x43 */
+{
+ IncWordReg(BX);
+}
+
+void IX86_OPS_BASE::PREFIX(_pop_ss)() /* Opcode 0x17 */
+{
+ i80286_pop_seg(cpustate, SS);
+ ICOUNT -= timing.pop_seg;
+ PREFIX(_instruction)[FETCHOP](cpustate); /* no interrupt before next instruction */
+}
+
+void IX86_OPS_BASE::PREFIX(_es)() /* Opcode 0x26 */
+{
+ cpustate->seg_prefix = TRUE;
+ cpustate->prefix_seg = ES;
+ ICOUNT -= timing.override;
+ PREFIX(_instruction)[FETCHOP](cpustate);
+}
+
+void IX86_OPS_BASE::PREFIX(_cs)() /* Opcode 0x2e */
+{
+ cpustate->seg_prefix = TRUE;
+ cpustate->prefix_seg = CS;
+ ICOUNT -= timing.override;
+ PREFIX(_instruction)[FETCHOP](cpustate);
+}
+
+void IX86_OPS_BASE::PREFIX(_ss)() /* Opcode 0x36 */
+{
+ cpustate->seg_prefix = TRUE;
+ cpustate->prefix_seg = SS;
+ ICOUNT -= timing.override;
+ PREFIX(_instruction)[FETCHOP](cpustate);
+}
+
+void IX86_OPS_BASE::PREFIX(_ds)() /* Opcode 0x3e */
+{
+ cpustate->seg_prefix = TRUE;
+ cpustate->prefix_seg = DS;
+ ICOUNT -= timing.override;
+ PREFIX(_instruction)[FETCHOP](cpustate);
+}
+
+void IX86_OPS_BASE::PREFIX(_mov_sregw)() /* Opcode 0x8e */
+{
+ unsigned ModRM = FETCH;
+ WORD src = GetRMWord(ModRM);
+
+ ICOUNT -= (ModRM >= 0xc0) ? timing.mov_sr : timing.mov_sm;
+ switch (ModRM & 0x38)
+ {
+ case 0x00: /* mov es,ew */
+ i80286_data_descriptor(cpustate,ES,src);
+ break;
+ case 0x18: /* mov ds,ew */
+ i80286_data_descriptor(cpustate,DS,src);
+ break;
+ case 0x10: /* mov ss,ew */
+ i80286_data_descriptor(cpustate,SS,src);
+ cpustate->seg_prefix = FALSE;
+ PREFIX(_instruction)[FETCHOP](cpustate);
+ break;
+ case 0x08: /* mov cs,ew */
+ PREFIX(_invalid)(cpustate);
+ break; /* doesn't do a jump far */
+ }
+}
+
+void IX86_OPS_BASE::PREFIX(_repne)() /* Opcode 0xf2 */
+{
+ PREFIX(rep)(0);
+}
+
+void IX86_OPS_BASE::PREFIX(_repe)() /* Opcode 0xf3 */
+{
+ PREFIX(rep)(1);
+}
+
+void IX86_OPS_BASE::PREFIX(_sti)() /* Opcode 0xfb */
+{
+//#ifdef I80286
+ if(PM && (CPL>IOPL)) throw TRAP(GENERAL_PROTECTION_FAULT,0);
+//#endif
+ ICOUNT -= timing.flag_ops;
+ SetIF(1);
+ PREFIX(_instruction)[FETCHOP](cpustate); /* no interrupt before next instruction */
+
+ /* if an interrupt is pending, signal an interrupt */
+ if (cpustate->irq_state) {
+//#ifdef I80286
+ i80286_interrupt_descriptor(cpustate, cpustate->pic->get_intr_ack(), 2, -1);
+//#else
+// PREFIX86(_interrupt)(cpustate, (UINT32)-1);
+//#endif
+ cpustate->irq_state = 0;
+ }
+}
+
+void IX86_OPS_BASE::PREFIX286(_insb)() /* Opcode 0x6c */
+{
+ ICOUNT -= timing.ins8;
+ PutMemB(ES,cpustate->regs.w[DI],read_port_byte(cpustate->regs.w[DX]));
+ cpustate->regs.w[DI] += cpustate->DirVal;
+}
+
+void IX86_OPS_BASE::PREFIX286(_insw)() /* Opcode 0x6d */
+{
+ ICOUNT -= timing.ins16;
+ PutMemW(ES,cpustate->regs.w[DI],read_port_word(cpustate->regs.w[DX]));
+ cpustate->regs.w[DI] += 2 * cpustate->DirVal;
+}
+
+void IX86_OPS_BASE::PREFIX286(_outsb)() /* Opcode 0x6e */
+{
+ ICOUNT -= timing.outs8;
+ write_port_byte(cpustate->regs.w[DX],GetMemB(DS,cpustate->regs.w[SI]));
+ cpustate->regs.w[SI] += cpustate->DirVal; /* GOL 11/27/01 */
+}
+
+void IX86_OPS_BASE::PREFIX286(_outsw)() /* Opcode 0x6f */
+{
+ ICOUNT -= timing.outs16;
+ write_port_word(cpustate->regs.w[DX],GetMemW(DS,cpustate->regs.w[SI]));
+ cpustate->regs.w[SI] += 2 * cpustate->DirVal; /* GOL 11/27/01 */
+}
--- /dev/null
+#define DIVIDE_BY_ZERO 0
+#define SINGLE_STEP 1
+#define NMI 2
+#define BREAK 3
+#define INTO_OVERFLOW 4
+#define BOUND_OVERRUN 5
+#define ILLEGAL_INSTRUCTION 6
+#define FPU_UNAVAILABLE 7
+#define DOUBLE_FAULT 8
+#define FPU_SEG_OVERRUN 9
+#define INVALID_TSS 10
+#define SEG_NOT_PRESENT 11
+#define STACK_FAULT 12
+#define GENERAL_PROTECTION_FAULT 13
+
+#define CPL (cpustate->sregs[CS]&3)
+#define PM (cpustate->msw&1)
+
+//void IX86_BASE::i80286_trap2(UINT32 error);
+//void IX86_BASE::i80286_interrupt_descriptor(UINT16 number, int trap, int error);
+//void IX86_BASE::i80286_code_descriptor(UINT16 selector, UINT16 offset, int gate);
+//void IX86_BASE::i80286_data_descriptor(int reg, UINT16 selector);
+
+//void IX86_BASE::PREFIX286(_0fpre)();
+//void IX86_BASE::PREFIX286(_arpl)();
+//void IX86_BASE::PREFIX286(_escape_7)();
+
+//void IX86_BASE::i80286_pop_seg(int reg);
+//void IX86_BASE::i80286_load_flags(UINT16 flags, int cpl);
+
+enum i80286_size
+{
+ I80286_BYTE = 1,
+ I80286_WORD = 2
+};
+
+enum i80286_operation
+{
+ I80286_READ = 1,
+ I80286_WRITE,
+ I80286_EXECUTE
+};
+
+//void IX86_BASE::i80286_check_permission(i8086_state *cpustate, UINT8 check_seg, UINT32 offset, UINT16 size, i80286_operation operation);
+
+inline UINT32 IX86_OPS_BASE::GetMemAddr(UINT8 seg, UINT32 off, UINT16 size, i80286_operation op) {
+ seg = DefaultSeg(seg);
+ if(PM) i80286_check_permission(cpustate, seg, off, size, op);
+ return (cpustate->base[seg] + off) & AMASK;
+}
--- /dev/null
+/****************************************************************************
+* real mode i286 emulator v1.4 by Fabrice Frances *
+* (initial work based on David Hedley's pcemu) *
+****************************************************************************/
+
+/*
+ * file will be included in all cpu variants
+ * put non i86 instructions in own files (i286, i386, nec)
+ * function renaming will be added when necessary
+ * timing value should move to separate array
+ */
+
+/*
+ PHS - 2010-12-29
+
+ Moved several instruction stubs so that they are compiled separately for
+ the 8086 and 80186. The instructions affected are :
+
+ _pop_ss, _es, _cs, _ss, _ds, _mov_sregw and _sti
+
+ This is because they call the next instruction directly as it cannot be
+ interrupted. If they are not compiled separately when executing on an
+ 80186, the wrong set of instructions are used (the 8086 set). This has
+ the serious effect of ignoring the next instruction, as invalid, *IF*
+ it is an 80186 specific instruction.
+
+*/
+
+#undef ICOUNT
+
+#define ICOUNT cpustate->icount
+
+
+//#if !defined(I80186)
+void IX86_OPS_BASE::PREFIX86(_interrupt)(unsigned int_num)
+{
+ unsigned dest_seg, dest_off;
+ WORD ip = cpustate->pc - cpustate->base[CS];
+
+ if (int_num == -1)
+ int_num = cpustate->pic->get_intr_ack();
+
+ dest_off = ReadWord(int_num*4);
+ dest_seg = ReadWord(int_num*4+2);
+
+ PREFIX(_pushf());
+ cpustate->TF = cpustate->IF = 0;
+ PUSH(cpustate->sregs[CS]);
+ PUSH(ip);
+ cpustate->sregs[CS] = (WORD)dest_seg;
+ cpustate->base[CS] = SegBase(CS);
+ cpustate->pc = (cpustate->base[CS] + dest_off) & AMASK;
+ CHANGE_PC(cpustate->pc);
+ cpustate->extra_cycles += timing.exception;
+}
+
+void IX86_OPS_BASE::PREFIX86(_trap)()
+{
+ PREFIX(_instruction)[FETCHOP]();
+ PREFIX(_interrupt)(1);
+}
+//#endif
+
+//#ifndef I80186
+void IX86_OPS_BASE::PREFIX86(_rotate_shift_Byte)(, unsigned ModRM, unsigned count, unsigned src)
+{
+}
+
+void IX86_OPS_BASE::PREFIX86(_rotate_shift_Word)(, unsigned ModRM, unsigned count, unsigned src)
+{
+}
+//#endif
+
+void IX86_OPS_BASE::PREFIX(rep)(int flagval)
+{
+ /* Handles rep- and repnz- prefixes. flagval is the value of ZF for the
+ loop to continue for CMPS and SCAS instructions. */
+
+ unsigned next = FETCHOP;
+
+ switch(next)
+ {
+ case 0x26: /* ES: */
+ cpustate->seg_prefix = TRUE;
+ cpustate->prefix_seg = ES;
+ if (!cpustate->rep_in_progress)
+ ICOUNT -= timing.override;
+ PREFIX(rep)(flagval);
+ break;
+ case 0x2e: /* CS: */
+ cpustate->seg_prefix = TRUE;
+ cpustate->prefix_seg = CS;
+ if (!cpustate->rep_in_progress)
+ ICOUNT -= timing.override;
+ PREFIX(rep)(flagval);
+ break;
+ case 0x36: /* SS: */
+ cpustate->seg_prefix = TRUE;
+ cpustate->prefix_seg = SS;
+ if (!cpustate->rep_in_progress)
+ ICOUNT -= timing.override;
+ PREFIX(rep)(flagval);
+ break;
+ case 0x3e: /* DS: */
+ cpustate->seg_prefix = TRUE;
+ cpustate->prefix_seg = DS;
+ if (!cpustate->rep_in_progress)
+ ICOUNT -= timing.override;
+ PREFIX(rep)(flagval);
+ break;
+ // !8086 was deleted.
+ case 0xa4: /* REP MOVSB */
+ if (!cpustate->rep_in_progress)
+ ICOUNT -= timing.rep_movs8_base;
+ cpustate->rep_in_progress = FALSE;
+ while(cpustate->regs.w[CX])
+ {
+ BYTE tmp;
+
+// if (ICOUNT <= 0) { cpustate->pc = cpustate->prevpc; cpustate->rep_in_progress = TRUE; break; }
+ tmp = GetMemB(DS,cpustate->regs.w[SI]);
+ PutMemB(ES,cpustate->regs.w[DI], tmp);
+ cpustate->regs.w[CX]--;
+ cpustate->regs.w[DI] += cpustate->DirVal;
+ cpustate->regs.w[SI] += cpustate->DirVal;
+ ICOUNT -= timing.rep_movs8_count;
+ }
+ break;
+ case 0xa5: /* REP MOVSW */
+ if (!cpustate->rep_in_progress)
+ ICOUNT -= timing.rep_movs16_base;
+ cpustate->rep_in_progress = FALSE;
+ while(cpustate->regs.w[CX])
+ {
+ WORD tmp;
+
+// if (ICOUNT <= 0) { cpustate->pc = cpustate->prevpc; cpustate->rep_in_progress = TRUE; break; }
+ tmp = GetMemW(DS,cpustate->regs.w[SI]);
+ PutMemW(ES,cpustate->regs.w[DI], tmp);
+ cpustate->regs.w[CX]--;
+ cpustate->regs.w[DI] += 2 * cpustate->DirVal;
+ cpustate->regs.w[SI] += 2 * cpustate->DirVal;
+ ICOUNT -= timing.rep_movs16_count;
+ }
+ break;
+ case 0xa6: /* REP(N)E CMPSB */
+ if (!cpustate->rep_in_progress)
+ ICOUNT -= timing.rep_cmps8_base;
+ cpustate->rep_in_progress = FALSE;
+ cpustate->ZeroVal = !flagval;
+ while(cpustate->regs.w[CX] && (ZF == flagval))
+ {
+ unsigned dst, src;
+
+// if (ICOUNT <= 0) { cpustate->pc = cpustate->prevpc; cpustate->rep_in_progress = TRUE; break; }
+ dst = GetMemB(ES, cpustate->regs.w[DI]);
+ src = GetMemB(DS, cpustate->regs.w[SI]);
+ SUBB(src,dst); /* opposite of the usual convention */
+ cpustate->regs.w[CX]--;
+ cpustate->regs.w[DI] += cpustate->DirVal;
+ cpustate->regs.w[SI] += cpustate->DirVal;
+ ICOUNT -= timing.rep_cmps8_count;
+ }
+ break;
+ case 0xa7: /* REP(N)E CMPSW */
+ if (!cpustate->rep_in_progress)
+ ICOUNT -= timing.rep_cmps16_base;
+ cpustate->rep_in_progress = FALSE;
+ cpustate->ZeroVal = !flagval;
+ while(cpustate->regs.w[CX] && (ZF == flagval))
+ {
+ unsigned dst, src;
+
+// if (ICOUNT <= 0) { cpustate->pc = cpustate->prevpc; cpustate->rep_in_progress = TRUE; break; }
+ dst = GetMemW(ES, cpustate->regs.w[DI]);
+ src = GetMemW(DS, cpustate->regs.w[SI]);
+ SUBW(src,dst); /* opposite of the usual convention */
+ cpustate->regs.w[CX]--;
+ cpustate->regs.w[DI] += 2 * cpustate->DirVal;
+ cpustate->regs.w[SI] += 2 * cpustate->DirVal;
+ ICOUNT -= timing.rep_cmps16_count;
+ }
+ break;
+ case 0xaa: /* REP STOSB */
+ if (!cpustate->rep_in_progress)
+ ICOUNT -= timing.rep_stos8_base;
+ cpustate->rep_in_progress = FALSE;
+ while(cpustate->regs.w[CX])
+ {
+// if (ICOUNT <= 0) { cpustate->pc = cpustate->prevpc; cpustate->rep_in_progress = TRUE; break; }
+ PutMemB(ES,cpustate->regs.w[DI],cpustate->regs.b[AL]);
+ cpustate->regs.w[CX]--;
+ cpustate->regs.w[DI] += cpustate->DirVal;
+ ICOUNT -= timing.rep_stos8_count;
+ }
+ break;
+ case 0xab: /* REP STOSW */
+ if (!cpustate->rep_in_progress)
+ ICOUNT -= timing.rep_stos16_base;
+ cpustate->rep_in_progress = FALSE;
+ while(cpustate->regs.w[CX])
+ {
+// if (ICOUNT <= 0) { cpustate->pc = cpustate->prevpc; cpustate->rep_in_progress = TRUE; break; }
+ PutMemW(ES,cpustate->regs.w[DI],cpustate->regs.w[AX]);
+ cpustate->regs.w[CX]--;
+ cpustate->regs.w[DI] += 2 * cpustate->DirVal;
+ ICOUNT -= timing.rep_stos16_count;
+ }
+ break;
+ case 0xac: /* REP LODSB */
+ if (!cpustate->rep_in_progress)
+ ICOUNT -= timing.rep_lods8_base;
+ cpustate->rep_in_progress = FALSE;
+ while(cpustate->regs.w[CX])
+ {
+// if (ICOUNT <= 0) { cpustate->pc = cpustate->prevpc; cpustate->rep_in_progress = TRUE; break; }
+ cpustate->regs.b[AL] = GetMemB(DS,cpustate->regs.w[SI]);
+ cpustate->regs.w[CX]--;
+ cpustate->regs.w[SI] += cpustate->DirVal;
+ ICOUNT -= timing.rep_lods8_count;
+ }
+ break;
+ case 0xad: /* REP LODSW */
+ if (!cpustate->rep_in_progress)
+ ICOUNT -= timing.rep_lods16_base;
+ cpustate->rep_in_progress = FALSE;
+ while(cpustate->regs.w[CX])
+ {
+// if (ICOUNT <= 0) { cpustate->pc = cpustate->prevpc; cpustate->rep_in_progress = TRUE; break; }
+ cpustate->regs.w[AX] = GetMemW(DS,cpustate->regs.w[SI]);
+ cpustate->regs.w[CX]--;
+ cpustate->regs.w[SI] += 2 * cpustate->DirVal;
+ ICOUNT -= timing.rep_lods16_count;
+ }
+ break;
+ case 0xae: /* REP(N)E SCASB */
+ if (!cpustate->rep_in_progress)
+ ICOUNT -= timing.rep_scas8_base;
+ cpustate->rep_in_progress = FALSE;
+ cpustate->ZeroVal = !flagval;
+ while(cpustate->regs.w[CX] && (ZF == flagval))
+ {
+ unsigned src, dst;
+
+// if (ICOUNT <= 0) { cpustate->pc = cpustate->prevpc; cpustate->rep_in_progress = TRUE; break; }
+ src = GetMemB(ES, cpustate->regs.w[DI]);
+ dst = cpustate->regs.b[AL];
+ SUBB(dst,src);
+ cpustate->regs.w[CX]--;
+ cpustate->regs.w[DI] += cpustate->DirVal;
+ ICOUNT -= timing.rep_scas8_count;
+ }
+ break;
+ case 0xaf: /* REP(N)E SCASW */
+ if (!cpustate->rep_in_progress)
+ ICOUNT -= timing.rep_scas16_base;
+ cpustate->rep_in_progress = FALSE;
+ cpustate->ZeroVal = !flagval;
+ while(cpustate->regs.w[CX] && (ZF == flagval))
+ {
+ unsigned src, dst;
+
+// if (ICOUNT <= 0) { cpustate->pc = cpustate->prevpc; cpustate->rep_in_progress = TRUE; break; }
+ src = GetMemW(ES, cpustate->regs.w[DI]);
+ dst = cpustate->regs.w[AX];
+ SUBW(dst,src);
+ cpustate->regs.w[CX]--;
+ cpustate->regs.w[DI] += 2 * cpustate->DirVal;
+ ICOUNT -= timing.rep_scas16_count;
+ }
+ break;
+ default:
+ PREFIX(_instruction)[next]();
+ }
+}
+
+//#ifndef I80186
+void IX86_OPS_BASE::PREFIX86(_add_br8)() /* Opcode 0x00 */
+{
+ DEF_br8(dst,src);
+ ICOUNT -= (ModRM >= 0xc0) ? timing.alu_rr8 : timing.alu_mr8;
+ ADDB(dst,src);
+ PutbackRMByte(ModRM,dst);
+}
+
+void IX86_OPS_BASE::PREFIX86(_add_wr16)() /* Opcode 0x01 */
+{
+ DEF_wr16(dst,src);
+ ICOUNT -= (ModRM >= 0xc0) ? timing.alu_rr16 : timing.alu_mr16;
+ ADDW(dst,src);
+ PutbackRMWord(ModRM,dst);
+}
+
+void IX86_OPS_BASE::PREFIX86(_add_r8b)() /* Opcode 0x02 */
+{
+ DEF_r8b(dst,src);
+ ICOUNT -= (ModRM >= 0xc0) ? timing.alu_rr8 : timing.alu_rm8;
+ ADDB(dst,src);
+ RegByte(ModRM)=dst;
+}
+
+void IX86_OPS_BASE::PREFIX86(_add_r16w)() /* Opcode 0x03 */
+{
+ DEF_r16w(dst,src);
+ ICOUNT -= (ModRM >= 0xc0) ? timing.alu_rr16 : timing.alu_rm16;
+ ADDW(dst,src);
+ RegWord(ModRM)=dst;
+}
+
+
+void IX86_OPS_BASE::PREFIX86(_add_ald8)() /* Opcode 0x04 */
+{
+ DEF_ald8(dst,src);
+ ICOUNT -= timing.alu_ri8;
+ ADDB(dst,src);
+ cpustate->regs.b[AL]=dst;
+}
+
+
+void IX86_OPS_BASE::PREFIX86(_add_axd16)() /* Opcode 0x05 */
+{
+ DEF_axd16(dst,src);
+ ICOUNT -= timing.alu_ri16;
+ ADDW(dst,src);
+ cpustate->regs.w[AX]=dst;
+}
+
+
+void IX86_OPS_BASE::PREFIX86(_push_es)() /* Opcode 0x06 */
+{
+ ICOUNT -= timing.push_seg;
+ PUSH(cpustate->sregs[ES]);
+}
+
+
+void IX86_OPS_BASE::PREFIX86(_pop_es)() /* Opcode 0x07 */
+{
+ POP(cpustate->sregs[ES]);
+ cpustate->base[ES] = SegBase(ES);
+
+ ICOUNT -= timing.pop_seg;
+}
+
+void IX86_OPS_BASE::PREFIX86(_or_br8)() /* Opcode 0x08 */
+{
+ DEF_br8(dst,src);
+ ICOUNT -= (ModRM >= 0xc0) ? timing.alu_rr8 : timing.alu_mr8;
+ ORB(dst,src);
+ PutbackRMByte(ModRM,dst);
+}
+
+void IX86_OPS_BASE::PREFIX86(_or_wr16)() /* Opcode 0x09 */
+{
+ DEF_wr16(dst,src);
+ ICOUNT -= (ModRM >= 0xc0) ? timing.alu_rr16 : timing.alu_mr16;
+ ORW(dst,src);
+ PutbackRMWord(ModRM,dst);
+}
+
+void IX86_OPS_BASE::PREFIX86(_or_r8b)() /* Opcode 0x0a */
+{
+ DEF_r8b(dst,src);
+ ICOUNT -= (ModRM >= 0xc0) ? timing.alu_rr8 : timing.alu_rm8;
+ ORB(dst,src);
+ RegByte(ModRM)=dst;
+}
+
+void IX86_OPS_BASE::PREFIX86(_or_r16w)() /* Opcode 0x0b */
+{
+ DEF_r16w(dst,src);
+ ICOUNT -= (ModRM >= 0xc0) ? timing.alu_rr16 : timing.alu_rm16;
+ ORW(dst,src);
+ RegWord(ModRM)=dst;
+}
+
+void IX86_OPS_BASE::PREFIX86(_or_ald8)() /* Opcode 0x0c */
+{
+ DEF_ald8(dst,src);
+ ICOUNT -= timing.alu_ri8;
+ ORB(dst,src);
+ cpustate->regs.b[AL]=dst;
+}
+
+void IX86_OPS_BASE::PREFIX86(_or_axd16)() /* Opcode 0x0d */
+{
+ DEF_axd16(dst,src);
+ ICOUNT -= timing.alu_ri16;
+ ORW(dst,src);
+ cpustate->regs.w[AX]=dst;
+}
+
+void IX86_OPS_BASE::PREFIX86(_push_cs)() /* Opcode 0x0e */
+{
+ ICOUNT -= timing.push_seg;
+ PUSH(cpustate->sregs[CS]);
+}
+
+//#ifndef I80286
+void IX86_OPS_BASE::PREFIX86(_pop_cs)() /* Opcode 0x0f */
+{
+ int ip = cpustate->pc - cpustate->base[CS];
+ ICOUNT -= timing.push_seg;
+ POP(cpustate->sregs[CS]);
+ cpustate->base[CS] = SegBase(CS);
+ cpustate->pc = (ip + cpustate->base[CS]) & AMASK;
+ CHANGE_PC(cpustate->pc);
+}
+//#endif
+
+void IX86_OPS_BASE::PREFIX86(_adc_br8)() /* Opcode 0x10 */
+{
+ int tmpcf;
+ DEF_br8(dst,src);
+ ICOUNT -= (ModRM >= 0xc0) ? timing.alu_rr8 : timing.alu_mr8;
+ src+=CF;
+ ADCB(dst,src,tmpcf);
+ PutbackRMByte(ModRM,dst);
+ cpustate->CarryVal = tmpcf;
+}
+
+void IX86_OPS_BASE::PREFIX86(_adc_wr16)() /* Opcode 0x11 */
+{
+ int tmpcf;
+ DEF_wr16(dst,src);
+ ICOUNT -= (ModRM >= 0xc0) ? timing.alu_rr16 : timing.alu_mr16;
+ src+=CF;
+ ADCW(dst,src,tmpcf);
+ PutbackRMWord(ModRM,dst);
+ cpustate->CarryVal = tmpcf;
+}
+
+void IX86_OPS_BASE::PREFIX86(_adc_r8b)() /* Opcode 0x12 */
+{
+ DEF_r8b(dst,src);
+ ICOUNT -= (ModRM >= 0xc0) ? timing.alu_rr8 : timing.alu_rm8;
+ src+=CF;
+ ADDB(dst,src);
+ RegByte(ModRM)=dst;
+}
+
+void IX86_OPS_BASE::PREFIX86(_adc_r16w)() /* Opcode 0x13 */
+{
+ DEF_r16w(dst,src);
+ ICOUNT -= (ModRM >= 0xc0) ? timing.alu_rr16 : timing.alu_rm16;
+ src+=CF;
+ ADDW(dst,src);
+ RegWord(ModRM)=dst;
+}
+
+void IX86_OPS_BASE::PREFIX86(_adc_ald8)() /* Opcode 0x14 */
+{
+ DEF_ald8(dst,src);
+ ICOUNT -= timing.alu_ri8;
+ src+=CF;
+ ADDB(dst,src);
+ cpustate->regs.b[AL] = dst;
+}
+
+void IX86_OPS_BASE::PREFIX86(_adc_axd16)() /* Opcode 0x15 */
+{
+ DEF_axd16(dst,src);
+ ICOUNT -= timing.alu_ri16;
+ src+=CF;
+ ADDW(dst,src);
+ cpustate->regs.w[AX]=dst;
+}
+
+void IX86_OPS_BASE::PREFIX86(_push_ss)() /* Opcode 0x16 */
+{
+ PUSH(cpustate->sregs[SS]);
+ ICOUNT -= timing.push_seg;
+}
+
+void IX86_OPS_BASE::PREFIX86(_sbb_br8)() /* Opcode 0x18 */
+{
+ int tmpcf;
+ DEF_br8(dst,src);
+ ICOUNT -= (ModRM >= 0xc0) ? timing.alu_rr8 : timing.alu_mr8;
+ src+=CF;
+ SBBB(dst,src,tmpcf);
+ PutbackRMByte(ModRM,dst);
+ cpustate->CarryVal = tmpcf;
+}
+
+void IX86_OPS_BASE::PREFIX86(_sbb_wr16)() /* Opcode 0x19 */
+{
+ int tmpcf;
+ DEF_wr16(dst,src);
+ ICOUNT -= (ModRM >= 0xc0) ? timing.alu_rr16 : timing.alu_mr16;
+ src+=CF;
+ SBBW(dst,src,tmpcf);
+ PutbackRMWord(ModRM,dst);
+ cpustate->CarryVal = tmpcf;
+}
+
+void IX86_OPS_BASE::PREFIX86(_sbb_r8b)() /* Opcode 0x1a */
+{
+ DEF_r8b(dst,src);
+ ICOUNT -= (ModRM >= 0xc0) ? timing.alu_rr8 : timing.alu_rm8;
+ src+=CF;
+ SUBB(dst,src);
+ RegByte(ModRM)=dst;
+}
+
+void IX86_OPS_BASE::PREFIX86(_sbb_r16w)() /* Opcode 0x1b */
+{
+ DEF_r16w(dst,src);
+ ICOUNT -= (ModRM >= 0xc0) ? timing.alu_rr16 : timing.alu_rm16;
+ src+=CF;
+ SUBW(dst,src);
+ RegWord(ModRM)= dst;
+}
+
+void IX86_OPS_BASE::PREFIX86(_sbb_ald8)() /* Opcode 0x1c */
+{
+ DEF_ald8(dst,src);
+ ICOUNT -= timing.alu_ri8;
+ src+=CF;
+ SUBB(dst,src);
+ cpustate->regs.b[AL] = dst;
+}
+
+void IX86_OPS_BASE::PREFIX86(_sbb_axd16)() /* Opcode 0x1d */
+{
+ DEF_axd16(dst,src);
+ ICOUNT -= timing.alu_ri16;
+ src+=CF;
+ SUBW(dst,src);
+ cpustate->regs.w[AX]=dst;
+}
+
+void IX86_OPS_BASE::PREFIX86(_push_ds)() /* Opcode 0x1e */
+{
+ PUSH(cpustate->sregs[DS]);
+ ICOUNT -= timing.push_seg;
+}
+
+void IX86_OPS_BASE::PREFIX86(_pop_ds)() /* Opcode 0x1f */
+{
+ POP(cpustate->sregs[DS]);
+ cpustate->base[DS] = SegBase(DS);
+
+ ICOUNT -= timing.push_seg;
+}
+
+void IX86_OPS_BASE::PREFIX86(_and_br8)() /* Opcode 0x20 */
+{
+ DEF_br8(dst,src);
+ ICOUNT -= (ModRM >= 0xc0) ? timing.alu_rr8 : timing.alu_mr8;
+ ANDB(dst,src);
+ PutbackRMByte(ModRM,dst);
+}
+
+void IX86_OPS_BASE::PREFIX86(_and_wr16)() /* Opcode 0x21 */
+{
+ DEF_wr16(dst,src);
+ ICOUNT -= (ModRM >= 0xc0) ? timing.alu_rr16 : timing.alu_mr16;
+ ANDW(dst,src);
+ PutbackRMWord(ModRM,dst);
+}
+
+void IX86_OPS_BASE::PREFIX86(_and_r8b)() /* Opcode 0x22 */
+{
+ DEF_r8b(dst,src);
+ ICOUNT -= (ModRM >= 0xc0) ? timing.alu_rr8 : timing.alu_rm8;
+ ANDB(dst,src);
+ RegByte(ModRM)=dst;
+}
+
+void IX86_OPS_BASE::PREFIX86(_and_r16w)() /* Opcode 0x23 */
+{
+ DEF_r16w(dst,src);
+ ICOUNT -= (ModRM >= 0xc0) ? timing.alu_rr16 : timing.alu_rm16;
+ ANDW(dst,src);
+ RegWord(ModRM)=dst;
+}
+
+void IX86_OPS_BASE::PREFIX86(_and_ald8)() /* Opcode 0x24 */
+{
+ DEF_ald8(dst,src);
+ ICOUNT -= timing.alu_ri8;
+ ANDB(dst,src);
+ cpustate->regs.b[AL] = dst;
+}
+
+void IX86_OPS_BASE::PREFIX86(_and_axd16)() /* Opcode 0x25 */
+{
+ DEF_axd16(dst,src);
+ ICOUNT -= timing.alu_ri16;
+ ANDW(dst,src);
+ cpustate->regs.w[AX]=dst;
+}
+
+void IX86_OPS_BASE::PREFIX86(_daa)() /* Opcode 0x27 */
+{
+ if (AF || ((cpustate->regs.b[AL] & 0xf) > 9))
+ {
+ int tmp;
+ cpustate->regs.b[AL] = tmp = cpustate->regs.b[AL] + 6;
+ cpustate->AuxVal = 1;
+ cpustate->CarryVal |= tmp & 0x100;
+ }
+
+ if (CF || (cpustate->regs.b[AL] > 0x9f))
+ {
+ cpustate->regs.b[AL] += 0x60;
+ cpustate->CarryVal = 1;
+ }
+
+ SetSZPF_Byte(cpustate->regs.b[AL]);
+ ICOUNT -= timing.daa;
+}
+
+void IX86_OPS_BASE::PREFIX86(_sub_br8)() /* Opcode 0x28 */
+{
+ DEF_br8(dst,src);
+ ICOUNT -= (ModRM >= 0xc0) ? timing.alu_rr8 : timing.alu_mr8;
+ SUBB(dst,src);
+ PutbackRMByte(ModRM,dst);
+}
+
+void IX86_OPS_BASE::PREFIX86(_sub_wr16)() /* Opcode 0x29 */
+{
+ DEF_wr16(dst,src);
+ ICOUNT -= (ModRM >= 0xc0) ? timing.alu_rr16 : timing.alu_mr16;
+ SUBW(dst,src);
+ PutbackRMWord(ModRM,dst);
+}
+
+void IX86_OPS_BASE::PREFIX86(_sub_r8b)() /* Opcode 0x2a */
+{
+ DEF_r8b(dst,src);
+ ICOUNT -= (ModRM >= 0xc0) ? timing.alu_rr8 : timing.alu_rm8;
+ SUBB(dst,src);
+ RegByte(ModRM)=dst;
+}
+
+void IX86_OPS_BASE::PREFIX86(_sub_r16w)() /* Opcode 0x2b */
+{
+ DEF_r16w(dst,src);
+ ICOUNT -= (ModRM >= 0xc0) ? timing.alu_rr16 : timing.alu_rm16;
+ SUBW(dst,src);
+ RegWord(ModRM)=dst;
+}
+
+void IX86_OPS_BASE::PREFIX86(_sub_ald8)() /* Opcode 0x2c */
+{
+ DEF_ald8(dst,src);
+ ICOUNT -= timing.alu_ri8;
+ SUBB(dst,src);
+ cpustate->regs.b[AL] = dst;
+}
+
+void IX86_OPS_BASE::PREFIX86(_sub_axd16)() /* Opcode 0x2d */
+{
+ DEF_axd16(dst,src);
+ ICOUNT -= timing.alu_ri16;
+ SUBW(dst,src);
+ cpustate->regs.w[AX]=dst;
+}
+
+void IX86_OPS_BASE::PREFIX86(_das)() /* Opcode 0x2f */
+{
+ UINT8 tmpAL=cpustate->regs.b[AL];
+ if (AF || ((cpustate->regs.b[AL] & 0xf) > 9))
+ {
+ int tmp;
+ cpustate->regs.b[AL] = tmp = cpustate->regs.b[AL] - 6;
+ cpustate->AuxVal = 1;
+ cpustate->CarryVal |= tmp & 0x100;
+ }
+
+ if (CF || (tmpAL > 0x9f))
+ {
+ cpustate->regs.b[AL] -= 0x60;
+ cpustate->CarryVal = 1;
+ }
+
+ SetSZPF_Byte(cpustate->regs.b[AL]);
+ ICOUNT -= timing.das;
+}
+
+void IX86_OPS_BASE::PREFIX86(_xor_br8)() /* Opcode 0x30 */
+{
+ DEF_br8(dst,src);
+ ICOUNT -= (ModRM >= 0xc0) ? timing.alu_rr8 : timing.alu_mr8;
+ XORB(dst,src);
+ PutbackRMByte(ModRM,dst);
+}
+
+void IX86_OPS_BASE::PREFIX86(_xor_wr16)() /* Opcode 0x31 */
+{
+ DEF_wr16(dst,src);
+ ICOUNT -= (ModRM >= 0xc0) ? timing.alu_rr16 : timing.alu_mr16;
+ XORW(dst,src);
+ PutbackRMWord(ModRM,dst);
+}
+
+void IX86_OPS_BASE::PREFIX86(_xor_r8b)() /* Opcode 0x32 */
+{
+ DEF_r8b(dst,src);
+ ICOUNT -= (ModRM >= 0xc0) ? timing.alu_rr8 : timing.alu_rm8;
+ XORB(dst,src);
+ RegByte(ModRM)=dst;
+}
+
+void IX86_OPS_BASE::PREFIX86(_xor_r16w)() /* Opcode 0x33 */
+{
+ DEF_r16w(dst,src);
+ ICOUNT -= (ModRM >= 0xc0) ? timing.alu_rr16 : timing.alu_rm16;
+ XORW(dst,src);
+ RegWord(ModRM)=dst;
+}
+
+void IX86_OPS_BASE::PREFIX86(_xor_ald8)() /* Opcode 0x34 */
+{
+ DEF_ald8(dst,src);
+ ICOUNT -= timing.alu_ri8;
+ XORB(dst,src);
+ cpustate->regs.b[AL] = dst;
+}
+
+void IX86_OPS_BASE::PREFIX86(_xor_axd16)() /* Opcode 0x35 */
+{
+ DEF_axd16(dst,src);
+ ICOUNT -= timing.alu_ri16;
+ XORW(dst,src);
+ cpustate->regs.w[AX]=dst;
+}
+
+void IX86_OPS_BASE::PREFIX86(_aaa)() /* Opcode 0x37 */
+{
+ UINT8 ALcarry=1;
+ if (cpustate->regs.b[AL]>0xf9) ALcarry=2;
+
+ if (AF || ((cpustate->regs.b[AL] & 0xf) > 9))
+ {
+ cpustate->regs.b[AL] += 6;
+ cpustate->regs.b[AH] += ALcarry;
+ cpustate->AuxVal = 1;
+ cpustate->CarryVal = 1;
+ }
+ else
+ {
+ cpustate->AuxVal = 0;
+ cpustate->CarryVal = 0;
+ }
+ cpustate->regs.b[AL] &= 0x0F;
+ ICOUNT -= timing.aaa;
+}
+
+void IX86_OPS_BASE::PREFIX86(_cmp_br8)() /* Opcode 0x38 */
+{
+ DEF_br8(dst,src);
+ ICOUNT -= (ModRM >= 0xc0) ? timing.alu_rr8 : timing.alu_rm8;
+ SUBB(dst,src);
+}
+
+void IX86_OPS_BASE::PREFIX86(_cmp_wr16)() /* Opcode 0x39 */
+{
+ DEF_wr16(dst,src);
+ ICOUNT -= (ModRM >= 0xc0) ? timing.alu_rr16 : timing.alu_rm16;
+ SUBW(dst,src);
+}
+
+void IX86_OPS_BASE::PREFIX86(_cmp_r8b)() /* Opcode 0x3a */
+{
+ DEF_r8b(dst,src);
+ ICOUNT -= (ModRM >= 0xc0) ? timing.alu_rr8 : timing.alu_rm8;
+ SUBB(dst,src);
+}
+
+void IX86_OPS_BASE::PREFIX86(_cmp_r16w)() /* Opcode 0x3b */
+{
+ DEF_r16w(dst,src);
+ ICOUNT -= (ModRM >= 0xc0) ? timing.alu_rr16 : timing.alu_rm16;
+ SUBW(dst,src);
+}
+
+void IX86_OPS_BASE::PREFIX86(_cmp_ald8)() /* Opcode 0x3c */
+{
+ DEF_ald8(dst,src);
+ ICOUNT -= timing.alu_ri8;
+ SUBB(dst,src);
+}
+
+void IX86_OPS_BASE::PREFIX86(_cmp_axd16)() /* Opcode 0x3d */
+{
+ DEF_axd16(dst,src);
+ ICOUNT -= timing.alu_ri16;
+ SUBW(dst,src);
+}
+
+void IX86_OPS_BASE::PREFIX86(_aas)() /* Opcode 0x3f */
+{
+// UINT8 ALcarry=1;
+// if (cpustate->regs.b[AL]>0xf9) ALcarry=2;
+
+ if (AF || ((cpustate->regs.b[AL] & 0xf) > 9))
+ {
+ cpustate->regs.b[AL] -= 6;
+ cpustate->regs.b[AH] -= 1;
+ cpustate->AuxVal = 1;
+ cpustate->CarryVal = 1;
+ }
+ else
+ {
+ cpustate->AuxVal = 0;
+ cpustate->CarryVal = 0;
+ }
+ cpustate->regs.b[AL] &= 0x0F;
+ ICOUNT -= timing.aas;
+}
+
+#define IncWordReg(Reg) \
+{ \
+ unsigned tmp = (unsigned)cpustate->regs.w[Reg]; \
+ unsigned tmp1 = tmp+1; \
+ SetOFW_Add(tmp1,tmp,1); \
+ SetAF(tmp1,tmp,1); \
+ SetSZPF_Word(tmp1); \
+ cpustate->regs.w[Reg]=tmp1; \
+ ICOUNT -= timing.incdec_r16; \
+}
+
+void IX86_OPS_BASE::PREFIX86(_inc_ax)() /* Opcode 0x40 */
+{
+ IncWordReg(AX);
+}
+
+void IX86_OPS_BASE::PREFIX86(_inc_cx)() /* Opcode 0x41 */
+{
+ IncWordReg(CX);
+}
+
+void IX86_OPS_BASE::PREFIX86(_inc_dx)() /* Opcode 0x42 */
+{
+ IncWordReg(DX);
+}
+
+void IX86_OPS_BASE::PREFIX(_inc_bx)() /* Opcode 0x43 */
+{
+ IncWordReg(BX);
+}
+
+void IX86_OPS_BASE::PREFIX86(_inc_sp)() /* Opcode 0x44 */
+{
+ IncWordReg(SP);
+}
+
+void IX86_OPS_BASE::PREFIX86(_inc_bp)() /* Opcode 0x45 */
+{
+ IncWordReg(BP);
+}
+
+void IX86_OPS_BASE::PREFIX86(_inc_si)() /* Opcode 0x46 */
+{
+ IncWordReg(SI);
+}
+
+void IX86_OPS_BASE::PREFIX86(_inc_di)() /* Opcode 0x47 */
+{
+ IncWordReg(DI);
+}
+
+#define DecWordReg(Reg) \
+{ \
+ unsigned tmp = (unsigned)cpustate->regs.w[Reg]; \
+ unsigned tmp1 = tmp-1; \
+ SetOFW_Sub(tmp1,1,tmp); \
+ SetAF(tmp1,tmp,1); \
+ SetSZPF_Word(tmp1); \
+ cpustate->regs.w[Reg]=tmp1; \
+ ICOUNT -= timing.incdec_r16; \
+}
+
+void IX86_OPS_BASE::PREFIX86(_dec_ax)() /* Opcode 0x48 */
+{
+ DecWordReg(AX);
+}
+
+void IX86_OPS_BASE::PREFIX86(_dec_cx)() /* Opcode 0x49 */
+{
+ DecWordReg(CX);
+}
+
+void IX86_OPS_BASE::PREFIX86(_dec_dx)() /* Opcode 0x4a */
+{
+ DecWordReg(DX);
+}
+
+void IX86_OPS_BASE::PREFIX86(_dec_bx)() /* Opcode 0x4b */
+{
+ DecWordReg(BX);
+}
+
+void IX86_OPS_BASE::PREFIX86(_dec_sp)() /* Opcode 0x4c */
+{
+ DecWordReg(SP);
+}
+
+void IX86_OPS_BASE::PREFIX86(_dec_bp)() /* Opcode 0x4d */
+{
+ DecWordReg(BP);
+}
+
+void IX86_OPS_BASE::PREFIX86(_dec_si)() /* Opcode 0x4e */
+{
+ DecWordReg(SI);
+}
+
+void IX86_OPS_BASE::PREFIX86(_dec_di)() /* Opcode 0x4f */
+{
+ DecWordReg(DI);
+}
+
+void IX86_OPS_BASE::PREFIX86(_push_ax)() /* Opcode 0x50 */
+{
+ ICOUNT -= timing.push_r16;
+ PUSH(cpustate->regs.w[AX]);
+}
+
+void IX86_OPS_BASE::PREFIX86(_push_cx)() /* Opcode 0x51 */
+{
+ ICOUNT -= timing.push_r16;
+ PUSH(cpustate->regs.w[CX]);
+}
+
+void IX86_OPS_BASE::PREFIX86(_push_dx)() /* Opcode 0x52 */
+{
+ ICOUNT -= timing.push_r16;
+ PUSH(cpustate->regs.w[DX]);
+}
+
+void IX86_OPS_BASE::PREFIX86(_push_bx)() /* Opcode 0x53 */
+{
+ ICOUNT -= timing.push_r16;
+ PUSH(cpustate->regs.w[BX]);
+}
+
+void IX86_OPS_BASE::PREFIX86(_push_sp)() /* Opcode 0x54 */
+{
+ ICOUNT -= timing.push_r16;
+ PUSH(cpustate->regs.w[SP]);
+}
+
+void IX86_OPS_BASE::PREFIX86(_push_bp)() /* Opcode 0x55 */
+{
+ ICOUNT -= timing.push_r16;
+ PUSH(cpustate->regs.w[BP]);
+}
+
+
+void IX86_OPS_BASE::PREFIX86(_push_si)() /* Opcode 0x56 */
+{
+ ICOUNT -= timing.push_r16;
+ PUSH(cpustate->regs.w[SI]);
+}
+
+void IX86_OPS_BASE::PREFIX86(_push_di)() /* Opcode 0x57 */
+{
+ ICOUNT -= timing.push_r16;
+ PUSH(cpustate->regs.w[DI]);
+}
+
+void IX86_OPS_BASE::PREFIX86(_pop_ax)() /* Opcode 0x58 */
+{
+ ICOUNT -= timing.pop_r16;
+ POP(cpustate->regs.w[AX]);
+}
+
+void IX86_OPS_BASE::PREFIX86(_pop_cx)() /* Opcode 0x59 */
+{
+ ICOUNT -= timing.pop_r16;
+ POP(cpustate->regs.w[CX]);
+}
+
+void IX86_OPS_BASE::PREFIX86(_pop_dx)() /* Opcode 0x5a */
+{
+ ICOUNT -= timing.pop_r16;
+ POP(cpustate->regs.w[DX]);
+}
+
+void IX86_OPS_BASE::PREFIX86(_pop_bx)() /* Opcode 0x5b */
+{
+ ICOUNT -= timing.pop_r16;
+ POP(cpustate->regs.w[BX]);
+}
+
+void IX86_OPS_BASE::PREFIX86(_pop_sp)() /* Opcode 0x5c */
+{
+ ICOUNT -= timing.pop_r16;
+ POP(cpustate->regs.w[SP]);
+}
+
+void IX86_OPS_BASE::PREFIX86(_pop_bp)() /* Opcode 0x5d */
+{
+ ICOUNT -= timing.pop_r16;
+ POP(cpustate->regs.w[BP]);
+}
+
+void IX86_OPS_BASE::PREFIX86(_pop_si)() /* Opcode 0x5e */
+{
+ ICOUNT -= timing.pop_r16;
+ POP(cpustate->regs.w[SI]);
+}
+
+void IX86_OPS_BASE::PREFIX86(_pop_di)() /* Opcode 0x5f */
+{
+ ICOUNT -= timing.pop_r16;
+ POP(cpustate->regs.w[DI]);
+}
+
+void IX86_OPS_BASE::PREFIX86(_jo)() /* Opcode 0x70 */
+{
+ int tmp = (int)((INT8)FETCH);
+ if (OF)
+ {
+ cpustate->pc += tmp;
+ ICOUNT -= timing.jcc_t;
+/* ASG - can probably assume this is safe
+ CHANGE_PC(cpustate->pc);*/
+ } else ICOUNT -= timing.jcc_nt;
+}
+
+void IX86_OPS_BASE::PREFIX86(_jno)() /* Opcode 0x71 */
+{
+ int tmp = (int)((INT8)FETCH);
+ if (!OF) {
+ cpustate->pc += tmp;
+ ICOUNT -= timing.jcc_t;
+/* ASG - can probably assume this is safe
+ CHANGE_PC(cpustate->pc);*/
+ } else ICOUNT -= timing.jcc_nt;
+}
+
+void IX86_OPS_BASE::PREFIX86(_jb)() /* Opcode 0x72 */
+{
+ int tmp = (int)((INT8)FETCH);
+ if (CF) {
+ cpustate->pc += tmp;
+ ICOUNT -= timing.jcc_t;
+/* ASG - can probably assume this is safe
+ CHANGE_PC(cpustate->pc);*/
+ } else ICOUNT -= timing.jcc_nt;
+}
+
+void IX86_OPS_BASE::PREFIX86(_jnb)() /* Opcode 0x73 */
+{
+ int tmp = (int)((INT8)FETCH);
+ if (!CF) {
+ cpustate->pc += tmp;
+ ICOUNT -= timing.jcc_t;
+/* ASG - can probably assume this is safe
+ CHANGE_PC(cpustate->pc);*/
+ } else ICOUNT -= timing.jcc_nt;
+}
+
+void IX86_OPS_BASE::PREFIX86(_jz)() /* Opcode 0x74 */
+{
+ int tmp = (int)((INT8)FETCH);
+ if (ZF) {
+ cpustate->pc += tmp;
+ ICOUNT -= timing.jcc_t;
+/* ASG - can probably assume this is safe
+ CHANGE_PC(cpustate->pc);*/
+ } else ICOUNT -= timing.jcc_nt;
+}
+
+void IX86_OPS_BASE::PREFIX86(_jnz)() /* Opcode 0x75 */
+{
+ int tmp = (int)((INT8)FETCH);
+ if (!ZF) {
+ cpustate->pc += tmp;
+ ICOUNT -= timing.jcc_t;
+/* ASG - can probably assume this is safe
+ CHANGE_PC(cpustate->pc);*/
+ } else ICOUNT -= timing.jcc_nt;
+}
+
+void IX86_OPS_BASE::PREFIX86(_jbe)() /* Opcode 0x76 */
+{
+ int tmp = (int)((INT8)FETCH);
+ if (CF || ZF) {
+ cpustate->pc += tmp;
+ ICOUNT -= timing.jcc_t;
+/* ASG - can probably assume this is safe
+ CHANGE_PC(cpustate->pc);*/
+ } else ICOUNT -= timing.jcc_nt;
+}
+
+void IX86_OPS_BASE::PREFIX86(_jnbe)() /* Opcode 0x77 */
+{
+ int tmp = (int)((INT8)FETCH);
+ if (!(CF || ZF)) {
+ cpustate->pc += tmp;
+ ICOUNT -= timing.jcc_t;
+/* ASG - can probably assume this is safe
+ CHANGE_PC(cpustate->pc);*/
+ } else ICOUNT -= timing.jcc_nt;
+}
+
+void IX86_OPS_BASE::PREFIX86(_js)() /* Opcode 0x78 */
+{
+ int tmp = (int)((INT8)FETCH);
+ if (SF) {
+ cpustate->pc += tmp;
+ ICOUNT -= timing.jcc_t;
+/* ASG - can probably assume this is safe
+ CHANGE_PC(cpustate->pc);*/
+ } else ICOUNT -= timing.jcc_nt;
+}
+
+void IX86_OPS_BASE::PREFIX86(_jns)() /* Opcode 0x79 */
+{
+ int tmp = (int)((INT8)FETCH);
+ if (!SF) {
+ cpustate->pc += tmp;
+ ICOUNT -= timing.jcc_t;
+/* ASG - can probably assume this is safe
+ CHANGE_PC(cpustate->pc);*/
+ } else ICOUNT -= timing.jcc_nt;
+}
+
+void IX86_OPS_BASE::PREFIX86(_jp)() /* Opcode 0x7a */
+{
+ int tmp = (int)((INT8)FETCH);
+ if (PF) {
+ cpustate->pc += tmp;
+ ICOUNT -= timing.jcc_t;
+/* ASG - can probably assume this is safe
+ CHANGE_PC(cpustate->pc);*/
+ } else ICOUNT -= timing.jcc_nt;
+}
+
+void IX86_OPS_BASE::PREFIX86(_jnp)() /* Opcode 0x7b */
+{
+ int tmp = (int)((INT8)FETCH);
+ if (!PF) {
+ cpustate->pc += tmp;
+ ICOUNT -= timing.jcc_t;
+/* ASG - can probably assume this is safe
+ CHANGE_PC(cpustate->pc);*/
+ } else ICOUNT -= timing.jcc_nt;
+}
+
+void IX86_OPS_BASE::PREFIX86(_jl)() /* Opcode 0x7c */
+{
+ int tmp = (int)((INT8)FETCH);
+ if ((SF!=OF)&&!ZF) {
+ cpustate->pc += tmp;
+ ICOUNT -= timing.jcc_t;
+/* ASG - can probably assume this is safe
+ CHANGE_PC(cpustate->pc);*/
+ } else ICOUNT -= timing.jcc_nt;
+}
+
+void IX86_OPS_BASE::PREFIX86(_jnl)() /* Opcode 0x7d */
+{
+ int tmp = (int)((INT8)FETCH);
+ if (ZF||(SF==OF)) {
+ cpustate->pc += tmp;
+ ICOUNT -= timing.jcc_t;
+/* ASG - can probably assume this is safe
+ CHANGE_PC(cpustate->pc);*/
+ } else ICOUNT -= timing.jcc_nt;
+}
+
+void IX86_OPS_BASE::PREFIX86(_jle)() /* Opcode 0x7e */
+{
+ int tmp = (int)((INT8)FETCH);
+ if (ZF||(SF!=OF)) {
+ cpustate->pc += tmp;
+ ICOUNT -= timing.jcc_t;
+/* ASG - can probably assume this is safe
+ CHANGE_PC(cpustate->pc);*/
+ } else ICOUNT -= timing.jcc_nt;
+}
+
+void IX86_OPS_BASE::PREFIX86(_jnle)() /* Opcode 0x7f */
+{
+ int tmp = (int)((INT8)FETCH);
+ if ((SF==OF)&&!ZF) {
+ cpustate->pc += tmp;
+ ICOUNT -= timing.jcc_t;
+/* ASG - can probably assume this is safe
+ CHANGE_PC(cpustate->pc);*/
+ } else ICOUNT -= timing.jcc_nt;
+}
+
+void IX86_OPS_BASE::PREFIX86(_80pre)() /* Opcode 0x80 */
+{
+ unsigned ModRM = FETCHOP;
+ unsigned dst = GetRMByte(ModRM);
+ unsigned src = FETCH;
+ int tmpcf;
+
+ switch (ModRM & 0x38)
+ {
+ case 0x00: /* ADD eb,d8 */
+ ADDB(dst,src);
+ PutbackRMByte(ModRM,dst);
+ ICOUNT -= (ModRM >= 0xc0) ? timing.alu_ri8 : timing.alu_mi8;
+ break;
+ case 0x08: /* OR eb,d8 */
+ ORB(dst,src);
+ PutbackRMByte(ModRM,dst);
+ ICOUNT -= (ModRM >= 0xc0) ? timing.alu_ri8 : timing.alu_mi8;
+ break;
+ case 0x10: /* ADC eb,d8 */
+ src+=CF;
+ ADCB(dst,src,tmpcf);
+ PutbackRMByte(ModRM,dst);
+ cpustate->CarryVal = tmpcf;
+ ICOUNT -= (ModRM >= 0xc0) ? timing.alu_ri8 : timing.alu_mi8;
+ break;
+ case 0x18: /* SBB eb,b8 */
+ src+=CF;
+ SBBB(dst,src,tmpcf);
+ PutbackRMByte(ModRM,dst);
+ cpustate->CarryVal = tmpcf;
+ ICOUNT -= (ModRM >= 0xc0) ? timing.alu_ri8 : timing.alu_mi8;
+ break;
+ case 0x20: /* AND eb,d8 */
+ ANDB(dst,src);
+ PutbackRMByte(ModRM,dst);
+ ICOUNT -= (ModRM >= 0xc0) ? timing.alu_ri8 : timing.alu_mi8;
+ break;
+ case 0x28: /* SUB eb,d8 */
+ SUBB(dst,src);
+ PutbackRMByte(ModRM,dst);
+ ICOUNT -= (ModRM >= 0xc0) ? timing.alu_ri8 : timing.alu_mi8;
+ break;
+ case 0x30: /* XOR eb,d8 */
+ XORB(dst,src);
+ PutbackRMByte(ModRM,dst);
+ ICOUNT -= (ModRM >= 0xc0) ? timing.alu_ri8 : timing.alu_mi8;
+ break;
+ case 0x38: /* CMP eb,d8 */
+ SUBB(dst,src);
+ ICOUNT -= (ModRM >= 0xc0) ? timing.alu_ri8 : timing.alu_mi8_ro;
+ break;
+ }
+}
+
+
+void IX86_OPS_BASE::PREFIX86(_81pre)() /* Opcode 0x81 */
+{
+ unsigned ModRM = FETCH;
+ unsigned dst = GetRMWord(ModRM);
+ unsigned src = FETCH;
+ int tmpcf;
+ src+= (FETCH << 8);
+
+ switch (ModRM & 0x38)
+ {
+ case 0x00: /* ADD ew,d16 */
+ ADDW(dst,src);
+ PutbackRMWord(ModRM,dst);
+ ICOUNT -= (ModRM >= 0xc0) ? timing.alu_ri16 : timing.alu_mi16;
+ break;
+ case 0x08: /* OR ew,d16 */
+ ORW(dst,src);
+ PutbackRMWord(ModRM,dst);
+ ICOUNT -= (ModRM >= 0xc0) ? timing.alu_ri16 : timing.alu_mi16;
+ break;
+ case 0x10: /* ADC ew,d16 */
+ src+=CF;
+ ADCW(dst,src,tmpcf);
+ PutbackRMWord(ModRM,dst);
+ cpustate->CarryVal = tmpcf;
+ ICOUNT -= (ModRM >= 0xc0) ? timing.alu_ri16 : timing.alu_mi16;
+ break;
+ case 0x18: /* SBB ew,d16 */
+ src+=CF;
+ SBBW(dst,src,tmpcf);
+ PutbackRMWord(ModRM,dst);
+ cpustate->CarryVal = tmpcf;
+ ICOUNT -= (ModRM >= 0xc0) ? timing.alu_ri16 : timing.alu_mi16;
+ break;
+ case 0x20: /* AND ew,d16 */
+ ANDW(dst,src);
+ PutbackRMWord(ModRM,dst);
+ ICOUNT -= (ModRM >= 0xc0) ? timing.alu_ri16 : timing.alu_mi16;
+ break;
+ case 0x28: /* SUB ew,d16 */
+ SUBW(dst,src);
+ PutbackRMWord(ModRM,dst);
+ ICOUNT -= (ModRM >= 0xc0) ? timing.alu_ri16 : timing.alu_mi16;
+ break;
+ case 0x30: /* XOR ew,d16 */
+ XORW(dst,src);
+ PutbackRMWord(ModRM,dst);
+ ICOUNT -= (ModRM >= 0xc0) ? timing.alu_ri16 : timing.alu_mi16;
+ break;
+ case 0x38: /* CMP ew,d16 */
+ SUBW(dst,src);
+ ICOUNT -= (ModRM >= 0xc0) ? timing.alu_ri16 : timing.alu_mi16_ro;
+ break;
+ }
+}
+
+void IX86_OPS_BASE::PREFIX86(_82pre)() /* Opcode 0x82 */
+{
+ unsigned ModRM = FETCH;
+ unsigned dst = GetRMByte(ModRM);
+ unsigned src = FETCH;
+ int tmpcf;
+
+ switch (ModRM & 0x38)
+ {
+ case 0x00: /* ADD eb,d8 */
+ ADDB(dst,src);
+ PutbackRMByte(ModRM,dst);
+ ICOUNT -= (ModRM >= 0xc0) ? timing.alu_ri8 : timing.alu_mi8;
+ break;
+ case 0x08: /* OR eb,d8 */
+ ORB(dst,src);
+ PutbackRMByte(ModRM,dst);
+ ICOUNT -= (ModRM >= 0xc0) ? timing.alu_ri8 : timing.alu_mi8;
+ break;
+ case 0x10: /* ADC eb,d8 */
+ src+=CF;
+ ADCB(dst,src,tmpcf);
+ PutbackRMByte(ModRM,dst);
+ cpustate->CarryVal = tmpcf;
+ ICOUNT -= (ModRM >= 0xc0) ? timing.alu_ri8 : timing.alu_mi8;
+ break;
+ case 0x18: /* SBB eb,d8 */
+ src+=CF;
+ SBBB(dst,src,tmpcf);
+ PutbackRMByte(ModRM,dst);
+ cpustate->CarryVal = tmpcf;
+ ICOUNT -= (ModRM >= 0xc0) ? timing.alu_ri8 : timing.alu_mi8;
+ break;
+ case 0x20: /* AND eb,d8 */
+ ANDB(dst,src);
+ PutbackRMByte(ModRM,dst);
+ ICOUNT -= (ModRM >= 0xc0) ? timing.alu_ri8 : timing.alu_mi8;
+ break;
+ case 0x28: /* SUB eb,d8 */
+ SUBB(dst,src);
+ PutbackRMByte(ModRM,dst);
+ ICOUNT -= (ModRM >= 0xc0) ? timing.alu_ri8 : timing.alu_mi8;
+ break;
+ case 0x30: /* XOR eb,d8 */
+ XORB(dst,src);
+ PutbackRMByte(ModRM,dst);
+ ICOUNT -= (ModRM >= 0xc0) ? timing.alu_ri8 : timing.alu_mi8;
+ break;
+ case 0x38: /* CMP eb,d8 */
+ SUBB(dst,src);
+ ICOUNT -= (ModRM >= 0xc0) ? timing.alu_ri8 : timing.alu_mi8_ro;
+ break;
+ }
+}
+
+void IX86_OPS_BASE::PREFIX86(_83pre)() /* Opcode 0x83 */
+{
+ unsigned ModRM = FETCH;
+ unsigned dst = GetRMWord(ModRM);
+ unsigned src = (WORD)((INT16)((INT8)FETCH));
+ int tmpcf;
+
+ switch (ModRM & 0x38)
+ {
+ case 0x00: /* ADD ew,d16 */
+ ADDW(dst,src);
+ PutbackRMWord(ModRM,dst);
+ ICOUNT -= (ModRM >= 0xc0) ? timing.alu_r16i8 : timing.alu_m16i8;
+ break;
+ case 0x08: /* OR ew,d16 */
+ ORW(dst,src);
+ PutbackRMWord(ModRM,dst);
+ ICOUNT -= (ModRM >= 0xc0) ? timing.alu_r16i8 : timing.alu_m16i8;
+ break;
+ case 0x10: /* ADC ew,d16 */
+ src+=CF;
+ ADCW(dst,src,tmpcf);
+ PutbackRMWord(ModRM,dst);
+ cpustate->CarryVal = tmpcf;
+ ICOUNT -= (ModRM >= 0xc0) ? timing.alu_r16i8 : timing.alu_m16i8;
+ break;
+ case 0x18: /* SBB ew,d16 */
+ src+=CF;
+ SBBW(dst,src,tmpcf);
+ PutbackRMWord(ModRM,dst);
+ cpustate->CarryVal = tmpcf;
+ ICOUNT -= (ModRM >= 0xc0) ? timing.alu_r16i8 : timing.alu_m16i8;
+ break;
+ case 0x20: /* AND ew,d16 */
+ ANDW(dst,src);
+ PutbackRMWord(ModRM,dst);
+ ICOUNT -= (ModRM >= 0xc0) ? timing.alu_r16i8 : timing.alu_m16i8;
+ break;
+ case 0x28: /* SUB ew,d16 */
+ SUBW(dst,src);
+ PutbackRMWord(ModRM,dst);
+ ICOUNT -= (ModRM >= 0xc0) ? timing.alu_r16i8 : timing.alu_m16i8;
+ break;
+ case 0x30: /* XOR ew,d16 */
+ XORW(dst,src);
+ PutbackRMWord(ModRM,dst);
+ ICOUNT -= (ModRM >= 0xc0) ? timing.alu_r16i8 : timing.alu_m16i8;
+ break;
+ case 0x38: /* CMP ew,d16 */
+ SUBW(dst,src);
+ ICOUNT -= (ModRM >= 0xc0) ? timing.alu_r16i8 : timing.alu_m16i8_ro;
+ break;
+ }
+}
+
+void IX86_OPS_BASE::PREFIX86(_test_br8)() /* Opcode 0x84 */
+{
+ DEF_br8(dst,src);
+ ICOUNT -= (ModRM >= 0xc0) ? timing.alu_rr8 : timing.alu_rm8;
+ ANDB(dst,src);
+}
+
+void IX86_OPS_BASE::PREFIX86(_test_wr16)() /* Opcode 0x85 */
+{
+ DEF_wr16(dst,src);
+ ICOUNT -= (ModRM >= 0xc0) ? timing.alu_rr16 : timing.alu_rm16;
+ ANDW(dst,src);
+}
+
+void IX86_OPS_BASE::PREFIX86(_xchg_br8)() /* Opcode 0x86 */
+{
+ DEF_br8(dst,src);
+ ICOUNT -= (ModRM >= 0xc0) ? timing.xchg_rr8 : timing.xchg_rm8;
+ PutbackRMByte(ModRM,src);
+ RegByte(ModRM)=dst;
+}
+
+void IX86_OPS_BASE::PREFIX86(_xchg_wr16)() /* Opcode 0x87 */
+{
+ DEF_wr16(dst,src);
+ ICOUNT -= (ModRM >= 0xc0) ? timing.xchg_rr16 : timing.xchg_rm16;
+ PutbackRMWord(ModRM,src);
+ RegWord(ModRM)=dst;
+}
+
+void IX86_OPS_BASE::PREFIX86(_mov_br8)() /* Opcode 0x88 */
+{
+ unsigned ModRM = FETCH;
+ BYTE src = RegByte(ModRM);
+ ICOUNT -= (ModRM >= 0xc0) ? timing.mov_rr8 : timing.mov_mr8;
+ PutRMByte(ModRM,src);
+}
+
+void IX86_OPS_BASE::PREFIX86(_mov_wr16)() /* Opcode 0x89 */
+{
+ unsigned ModRM = FETCH;
+ WORD src = RegWord(ModRM);
+ ICOUNT -= (ModRM >= 0xc0) ? timing.mov_rr16 : timing.mov_mr16;
+ PutRMWord(ModRM,src);
+}
+
+void IX86_OPS_BASE::PREFIX86(_mov_r8b)() /* Opcode 0x8a */
+{
+ unsigned ModRM = FETCH;
+ BYTE src = GetRMByte(ModRM);
+ ICOUNT -= (ModRM >= 0xc0) ? timing.mov_rr8 : timing.mov_rm8;
+ RegByte(ModRM)=src;
+}
+
+void IX86_OPS_BASE::PREFIX86(_mov_r16w)() /* Opcode 0x8b */
+{
+ unsigned ModRM = FETCH;
+ WORD src = GetRMWord(ModRM);
+ ICOUNT -= (ModRM >= 0xc0) ? timing.mov_rr8 : timing.mov_rm16;
+ RegWord(ModRM)=src;
+}
+
+void IX86_OPS_BASE::PREFIX86(_mov_wsreg)() /* Opcode 0x8c */
+{
+ unsigned ModRM = FETCH;
+ ICOUNT -= (ModRM >= 0xc0) ? timing.mov_rs : timing.mov_ms;
+ if (ModRM & 0x20) { /* HJB 12/13/98 1xx is invalid */
+ cpustate->pc = cpustate->prevpc;
+ return PREFIX86(_invalid)(cpustate);
+ }
+
+ PutRMWord(ModRM,cpustate->sregs[(ModRM & 0x38) >> 3]);
+}
+
+void IX86_OPS_BASE::PREFIX86(_lea)() /* Opcode 0x8d */
+{
+ unsigned ModRM = FETCH;
+ ICOUNT -= timing.lea;
+ (void)(*GetEA[ModRM])(cpustate);
+ RegWord(ModRM)=cpustate->eo; /* HJB 12/13/98 effective offset (no segment part) */
+}
+
+void IX86_OPS_BASE::PREFIX86(_popw)() /* Opcode 0x8f */
+{
+ unsigned ModRM = FETCH;
+ WORD tmp;
+ tmp = ReadWord(cpustate->base[SS] + cpustate->regs.w[SP]);
+ ICOUNT -= (ModRM >= 0xc0) ? timing.pop_r16 : timing.pop_m16;
+ PutRMWord(ModRM,tmp);
+ cpustate->regs.w[SP] += 2;
+}
+
+
+#define XchgAXReg(Reg) \
+{ \
+ WORD tmp; \
+ tmp = cpustate->regs.w[Reg]; \
+ cpustate->regs.w[Reg] = cpustate->regs.w[AX]; \
+ cpustate->regs.w[AX] = tmp; \
+ ICOUNT -= timing.xchg_ar16; \
+}
+
+
+void IX86_OPS_BASE::PREFIX86(_nop)() /* Opcode 0x90 */
+{
+ /* this is XchgAXReg(AX); */
+ ICOUNT -= timing.nop;
+}
+
+void IX86_OPS_BASE::PREFIX86(_xchg_axcx)() /* Opcode 0x91 */
+{
+ XchgAXReg(CX);
+}
+
+void IX86_OPS_BASE::PREFIX86(_xchg_axdx)() /* Opcode 0x92 */
+{
+ XchgAXReg(DX);
+}
+
+void IX86_OPS_BASE::PREFIX86(_xchg_axbx)() /* Opcode 0x93 */
+{
+ XchgAXReg(BX);
+}
+
+void IX86_OPS_BASE::PREFIX86(_xchg_axsp)() /* Opcode 0x94 */
+{
+ XchgAXReg(SP);
+}
+
+void IX86_OPS_BASE::PREFIX86(_xchg_axbp)() /* Opcode 0x95 */
+{
+ XchgAXReg(BP);
+}
+
+void IX86_OPS_BASE::PREFIX86(_xchg_axsi)() /* Opcode 0x96 */
+{
+ XchgAXReg(SI);
+}
+
+void IX86_OPS_BASE::PREFIX86(_xchg_axdi)() /* Opcode 0x97 */
+{
+ XchgAXReg(DI);
+}
+
+void IX86_OPS_BASE::PREFIX86(_cbw)() /* Opcode 0x98 */
+{
+ ICOUNT -= timing.cbw;
+ cpustate->regs.b[AH] = (cpustate->regs.b[AL] & 0x80) ? 0xff : 0;
+}
+
+void IX86_OPS_BASE::PREFIX86(_cwd)() /* Opcode 0x99 */
+{
+ ICOUNT -= timing.cwd;
+ cpustate->regs.w[DX] = (cpustate->regs.b[AH] & 0x80) ? 0xffff : 0;
+}
+
+void IX86_OPS_BASE::PREFIX86(_call_far)()
+{
+ unsigned int tmp, tmp2;
+ WORD cs, ip;
+
+ tmp = FETCH;
+ tmp += FETCH << 8;
+
+ tmp2 = FETCH;
+ tmp2 += FETCH << 8;
+
+//#ifdef I86_PSEUDO_BIOS
+// if(cpustate->bios != NULL && cpustate->bios->bios_call_i86(((tmp2 << 4) + tmp) & AMASK, cpustate->regs.w, cpustate->sregs, &cpustate->ZeroVal, &cpustate->CarryVal)) {
+// ICOUNT -= timing.call_far;
+// return;
+// }
+//#endif
+
+ ip = cpustate->pc - cpustate->base[CS];
+ cs = cpustate->sregs[CS];
+
+//#ifdef I80286
+// i80286_code_descriptor(cpustate, tmp2, tmp, 2);
+//#else
+ cpustate->sregs[CS] = (WORD)tmp2;
+ cpustate->base[CS] = SegBase(CS);
+ cpustate->pc = (cpustate->base[CS] + (WORD)tmp) & AMASK;
+//#endif
+ PUSH(cs);
+ PUSH(ip);
+ ICOUNT -= timing.call_far;
+ CHANGE_PC(cpustate->pc);
+}
+
+void IX86_OPS_BASE::PREFIX86(_wait)() /* Opcode 0x9b */
+{
+ if (cpustate->test_state)
+ {
+ ICOUNT = 0;
+ cpustate->pc--;
+ }
+ else
+ ICOUNT -= timing.wait;
+}
+
+void IX86_OPS_BASE::PREFIX86(_pushf)() /* Opcode 0x9c */
+{
+ unsigned tmp;
+ ICOUNT -= timing.pushf;
+
+ tmp = CompressFlags();
+ PUSH( tmp );
+}
+
+//#ifndef I80286
+void IX86_OPS_BASE::PREFIX86(_popf)() /* Opcode 0x9d */
+{
+ unsigned tmp;
+ POP(tmp);
+ ICOUNT -= timing.popf;
+
+ ExpandFlags(tmp);
+ cpustate->flags = tmp;
+ cpustate->flags = CompressFlags();
+
+ if (cpustate->TF) PREFIX(_trap)(cpustate);
+
+ /* if the IF is set, and an interrupt is pending, signal an interrupt */
+ if (cpustate->IF && cpustate->irq_state) {
+ PREFIX(_interrupt)(cpustate, (UINT32)-1);
+ cpustate->irq_state = 0;
+ }
+}
+//#endif
+
+void IX86_OPS_BASE::PREFIX86(_sahf)() /* Opcode 0x9e */
+{
+ unsigned tmp = (CompressFlags() & 0xff00) | (cpustate->regs.b[AH] & 0xd5);
+ ICOUNT -= timing.sahf;
+ ExpandFlags(tmp);
+}
+
+void IX86_OPS_BASE::PREFIX86(_lahf)() /* Opcode 0x9f */
+{
+ cpustate->regs.b[AH] = CompressFlags() & 0xff;
+ ICOUNT -= timing.lahf;
+}
+
+
+void IX86_OPS_BASE::PREFIX86(_mov_aldisp)() /* Opcode 0xa0 */
+{
+ unsigned addr;
+
+ addr = FETCH;
+ addr += FETCH << 8;
+
+ ICOUNT -= timing.mov_am8;
+ cpustate->regs.b[AL] = GetMemB(DS, addr);
+}
+
+void IX86_OPS_BASE::PREFIX86(_mov_axdisp)() /* Opcode 0xa1 */
+{
+ unsigned addr;
+
+ addr = FETCH;
+ addr += FETCH << 8;
+
+ ICOUNT -= timing.mov_am16;
+ cpustate->regs.w[AX] = GetMemW(DS, addr);
+}
+
+void IX86_OPS_BASE::PREFIX86(_mov_dispal)() /* Opcode 0xa2 */
+{
+ unsigned addr;
+
+ addr = FETCH;
+ addr += FETCH << 8;
+
+ ICOUNT -= timing.mov_ma8;
+ PutMemB(DS, addr, cpustate->regs.b[AL]);
+}
+
+void IX86_OPS_BASE::PREFIX86(_mov_dispax)() /* Opcode 0xa3 */
+{
+ unsigned addr;
+
+ addr = FETCH;
+ addr += FETCH << 8;
+
+ ICOUNT -= timing.mov_ma16;
+ PutMemW(DS, addr, cpustate->regs.w[AX]);
+}
+
+void IX86_OPS_BASE::PREFIX86(_movsb)() /* Opcode 0xa4 */
+{
+ BYTE tmp = GetMemB(DS,cpustate->regs.w[SI]);
+ PutMemB(ES,cpustate->regs.w[DI], tmp);
+ cpustate->regs.w[DI] += cpustate->DirVal;
+ cpustate->regs.w[SI] += cpustate->DirVal;
+ ICOUNT -= timing.movs8;
+}
+
+void IX86_OPS_BASE::PREFIX86(_movsw)() /* Opcode 0xa5 */
+{
+ WORD tmp = GetMemW(DS,cpustate->regs.w[SI]);
+ PutMemW(ES,cpustate->regs.w[DI], tmp);
+ cpustate->regs.w[DI] += 2 * cpustate->DirVal;
+ cpustate->regs.w[SI] += 2 * cpustate->DirVal;
+ ICOUNT -= timing.movs16;
+}
+
+void IX86_OPS_BASE::PREFIX86(_cmpsb)() /* Opcode 0xa6 */
+{
+ unsigned dst = GetMemB(ES, cpustate->regs.w[DI]);
+ unsigned src = GetMemB(DS, cpustate->regs.w[SI]);
+ SUBB(src,dst); /* opposite of the usual convention */
+ cpustate->regs.w[DI] += cpustate->DirVal;
+ cpustate->regs.w[SI] += cpustate->DirVal;
+ ICOUNT -= timing.cmps8;
+}
+
+void IX86_OPS_BASE::PREFIX86(_cmpsw)() /* Opcode 0xa7 */
+{
+ unsigned dst = GetMemW(ES, cpustate->regs.w[DI]);
+ unsigned src = GetMemW(DS, cpustate->regs.w[SI]);
+ SUBW(src,dst); /* opposite of the usual convention */
+ cpustate->regs.w[DI] += 2 * cpustate->DirVal;
+ cpustate->regs.w[SI] += 2 * cpustate->DirVal;
+ ICOUNT -= timing.cmps16;
+}
+
+void IX86_OPS_BASE::PREFIX86(_test_ald8)() /* Opcode 0xa8 */
+{
+ DEF_ald8(dst,src);
+ ICOUNT -= timing.alu_ri8;
+ ANDB(dst,src);
+}
+
+void IX86_OPS_BASE::PREFIX86(_test_axd16)() /* Opcode 0xa9 */
+{
+ DEF_axd16(dst,src);
+ ICOUNT -= timing.alu_ri16;
+ ANDW(dst,src);
+}
+
+void IX86_OPS_BASE::PREFIX86(_stosb)() /* Opcode 0xaa */
+{
+ PutMemB(ES,cpustate->regs.w[DI],cpustate->regs.b[AL]);
+ cpustate->regs.w[DI] += cpustate->DirVal;
+ ICOUNT -= timing.stos8;
+}
+
+void IX86_OPS_BASE::PREFIX86(_stosw)() /* Opcode 0xab */
+{
+ PutMemW(ES,cpustate->regs.w[DI],cpustate->regs.w[AX]);
+ cpustate->regs.w[DI] += 2 * cpustate->DirVal;
+ ICOUNT -= timing.stos16;
+}
+
+void IX86_OPS_BASE::PREFIX86(_lodsb)() /* Opcode 0xac */
+{
+ cpustate->regs.b[AL] = GetMemB(DS,cpustate->regs.w[SI]);
+ cpustate->regs.w[SI] += cpustate->DirVal;
+ ICOUNT -= timing.lods8;
+}
+
+void IX86_OPS_BASE::PREFIX86(_lodsw)() /* Opcode 0xad */
+{
+ cpustate->regs.w[AX] = GetMemW(DS,cpustate->regs.w[SI]);
+ cpustate->regs.w[SI] += 2 * cpustate->DirVal;
+ ICOUNT -= timing.lods16;
+}
+
+void IX86_OPS_BASE::PREFIX86(_scasb)() /* Opcode 0xae */
+{
+ unsigned src = GetMemB(ES, cpustate->regs.w[DI]);
+ unsigned dst = cpustate->regs.b[AL];
+ SUBB(dst,src);
+ cpustate->regs.w[DI] += cpustate->DirVal;
+ ICOUNT -= timing.scas8;
+}
+
+void IX86_OPS_BASE::PREFIX86(_scasw)() /* Opcode 0xaf */
+{
+ unsigned src = GetMemW(ES, cpustate->regs.w[DI]);
+ unsigned dst = cpustate->regs.w[AX];
+ SUBW(dst,src);
+ cpustate->regs.w[DI] += 2 * cpustate->DirVal;
+ ICOUNT -= timing.scas16;
+}
+
+void IX86_OPS_BASE::PREFIX86(_mov_ald8)() /* Opcode 0xb0 */
+{
+ cpustate->regs.b[AL] = FETCH;
+ ICOUNT -= timing.mov_ri8;
+}
+
+void IX86_OPS_BASE::PREFIX86(_mov_cld8)() /* Opcode 0xb1 */
+{
+ cpustate->regs.b[CL] = FETCH;
+ ICOUNT -= timing.mov_ri8;
+}
+
+void IX86_OPS_BASE::PREFIX86(_mov_dld8)() /* Opcode 0xb2 */
+{
+ cpustate->regs.b[DL] = FETCH;
+ ICOUNT -= timing.mov_ri8;
+}
+
+void IX86_OPS_BASE::PREFIX86(_mov_bld8)() /* Opcode 0xb3 */
+{
+ cpustate->regs.b[BL] = FETCH;
+ ICOUNT -= timing.mov_ri8;
+}
+
+void IX86_OPS_BASE::PREFIX86(_mov_ahd8)() /* Opcode 0xb4 */
+{
+ cpustate->regs.b[AH] = FETCH;
+ ICOUNT -= timing.mov_ri8;
+}
+
+void IX86_OPS_BASE::PREFIX86(_mov_chd8)() /* Opcode 0xb5 */
+{
+ cpustate->regs.b[CH] = FETCH;
+ ICOUNT -= timing.mov_ri8;
+}
+
+void IX86_OPS_BASE::PREFIX86(_mov_dhd8)() /* Opcode 0xb6 */
+{
+ cpustate->regs.b[DH] = FETCH;
+ ICOUNT -= timing.mov_ri8;
+}
+
+void IX86_OPS_BASE::PREFIX86(_mov_bhd8)() /* Opcode 0xb7 */
+{
+ cpustate->regs.b[BH] = FETCH;
+ ICOUNT -= timing.mov_ri8;
+}
+
+void IX86_OPS_BASE::PREFIX86(_mov_axd16)() /* Opcode 0xb8 */
+{
+ cpustate->regs.b[AL] = FETCH;
+ cpustate->regs.b[AH] = FETCH;
+ ICOUNT -= timing.mov_ri16;
+}
+
+void IX86_OPS_BASE::PREFIX86(_mov_cxd16)() /* Opcode 0xb9 */
+{
+ cpustate->regs.b[CL] = FETCH;
+ cpustate->regs.b[CH] = FETCH;
+ ICOUNT -= timing.mov_ri16;
+}
+
+void IX86_OPS_BASE::PREFIX86(_mov_dxd16)() /* Opcode 0xba */
+{
+ cpustate->regs.b[DL] = FETCH;
+ cpustate->regs.b[DH] = FETCH;
+ ICOUNT -= timing.mov_ri16;
+}
+
+void IX86_OPS_BASE::PREFIX86(_mov_bxd16)() /* Opcode 0xbb */
+{
+ cpustate->regs.b[BL] = FETCH;
+ cpustate->regs.b[BH] = FETCH;
+ ICOUNT -= timing.mov_ri16;
+}
+
+void IX86_OPS_BASE::PREFIX86(_mov_spd16)() /* Opcode 0xbc */
+{
+ cpustate->regs.b[SPL] = FETCH;
+ cpustate->regs.b[SPH] = FETCH;
+ ICOUNT -= timing.mov_ri16;
+}
+
+void IX86_OPS_BASE::PREFIX86(_mov_bpd16)() /* Opcode 0xbd */
+{
+ cpustate->regs.b[BPL] = FETCH;
+ cpustate->regs.b[BPH] = FETCH;
+ ICOUNT -= timing.mov_ri16;
+}
+
+void IX86_OPS_BASE::PREFIX86(_mov_sid16)() /* Opcode 0xbe */
+{
+ cpustate->regs.b[SIL] = FETCH;
+ cpustate->regs.b[SIH] = FETCH;
+ ICOUNT -= timing.mov_ri16;
+}
+
+void IX86_OPS_BASE::PREFIX86(_mov_did16)() /* Opcode 0xbf */
+{
+ cpustate->regs.b[DIL] = FETCH;
+ cpustate->regs.b[DIH] = FETCH;
+ ICOUNT -= timing.mov_ri16;
+}
+
+void IX86_OPS_BASE::PREFIX86(_ret_d16)() /* Opcode 0xc2 */
+{
+ unsigned count = FETCH;
+ count += FETCH << 8;
+ POP(cpustate->pc);
+ cpustate->pc = (cpustate->pc + cpustate->base[CS]) & AMASK;
+ cpustate->regs.w[SP]+=count;
+ ICOUNT -= timing.ret_near_imm;
+ CHANGE_PC(cpustate->pc);
+}
+
+void IX86_OPS_BASE::PREFIX86(_ret)() /* Opcode 0xc3 */
+{
+ POP(cpustate->pc);
+ cpustate->pc = (cpustate->pc + cpustate->base[CS]) & AMASK;
+ ICOUNT -= timing.ret_near;
+ CHANGE_PC(cpustate->pc);
+}
+
+void IX86_OPS_BASE::PREFIX86(_les_dw)() /* Opcode 0xc4 */
+{
+ unsigned ModRM = FETCH;
+ WORD tmp = GetRMWord(ModRM);
+
+ cpustate->sregs[ES] = GetnextRMWord;
+ cpustate->base[ES] = SegBase(ES);
+ RegWord(ModRM)= tmp;
+ ICOUNT -= timing.load_ptr;
+}
+
+void IX86_OPS_BASE::PREFIX86(_lds_dw)() /* Opcode 0xc5 */
+{
+ unsigned ModRM = FETCH;
+ WORD tmp = GetRMWord(ModRM);
+
+ cpustate->sregs[DS] = GetnextRMWord;
+ cpustate->base[DS] = SegBase(DS);
+ RegWord(ModRM)=tmp;
+ ICOUNT -= timing.load_ptr;
+}
+
+void IX86_OPS_BASE::PREFIX86(_mov_bd8)() /* Opcode 0xc6 */
+{
+ unsigned ModRM = FETCH;
+ ICOUNT -= (ModRM >= 0xc0) ? timing.mov_ri8 : timing.mov_mi8;
+ PutImmRMByte(ModRM);
+}
+
+void IX86_OPS_BASE::PREFIX86(_mov_wd16)() /* Opcode 0xc7 */
+{
+ unsigned ModRM = FETCH;
+ ICOUNT -= (ModRM >= 0xc0) ? timing.mov_ri16 : timing.mov_mi16;
+ PutImmRMWord(ModRM);
+}
+
+//#ifndef I80286
+void IX86_OPS_BASE::PREFIX86(_retf_d16)() /* Opcode 0xca */
+{
+ unsigned count = FETCH;
+ count += FETCH << 8;
+
+ POP(cpustate->pc);
+ POP(cpustate->sregs[CS]);
+ cpustate->base[CS] = SegBase(CS);
+ cpustate->pc = (cpustate->pc + cpustate->base[CS]) & AMASK;
+ cpustate->regs.w[SP]+=count;
+ ICOUNT -= timing.ret_far_imm;
+ CHANGE_PC(cpustate->pc);
+}
+
+void IX86_OPS_BASE::PREFIX86(_retf)() /* Opcode 0xcb */
+{
+ POP(cpustate->pc);
+ POP(cpustate->sregs[CS]);
+ cpustate->base[CS] = SegBase(CS);
+ cpustate->pc = (cpustate->pc + cpustate->base[CS]) & AMASK;
+ ICOUNT -= timing.ret_far;
+ CHANGE_PC(cpustate->pc);
+}
+//#endif
+
+void IX86_OPS_BASE::PREFIX86(_int3)() /* Opcode 0xcc */
+{
+ ICOUNT -= timing.int3;
+ PREFIX(_interrupt)(cpustate, 3);
+}
+
+void IX86_OPS_BASE::PREFIX86(_int)() /* Opcode 0xcd */
+{
+ unsigned int_num = FETCH;
+ ICOUNT -= timing.int_imm;
+//#ifdef I86_PSEUDO_BIOS
+// if(cpustate->bios != NULL && cpustate->bios->bios_int_i86(int_num, cpustate->regs.w, cpustate->sregs, &cpustate->ZeroVal, &cpustate->CarryVal)) {
+// return;
+// }
+//#endif
+ PREFIX(_interrupt)(cpustate, int_num);
+}
+
+void IX86_OPS_BASE::PREFIX86(_into)() /* Opcode 0xce */
+{
+ if (OF) {
+ ICOUNT -= timing.into_t;
+ PREFIX(_interrupt)(cpustate, 4);
+ } else ICOUNT -= timing.into_nt;
+}
+
+
+void IX86_OPS_BASE::PREFIX86(_iret)() /* Opcode 0xcf */
+{
+//#ifndef I80286
+ ICOUNT -= timing.iret;
+ POP(cpustate->pc);
+ POP(cpustate->sregs[CS]);
+ cpustate->base[CS] = SegBase(CS);
+ cpustate->pc = (cpustate->pc + cpustate->base[CS]) & AMASK;
+ PREFIX(_popf)(cpustate);
+ CHANGE_PC(cpustate->pc);
+
+ /* if the IF is set, and an interrupt is pending, signal an interrupt */
+ if (cpustate->IF && cpustate->irq_state) {
+ PREFIX(_interrupt)(cpustate, (UINT32)-1);
+ cpustate->irq_state = 0;
+ }
+//#endif
+}
+
+void IX86_OPS_BASE::PREFIX86(_rotshft_b)() /* Opcode 0xd0 */
+{
+ unsigned ModRM = FETCHOP;
+ PREFIX(_rotate_shift_Byte)(cpustate,ModRM,1,GetRMByte(ModRM));
+}
+
+
+void IX86_OPS_BASE::PREFIX86(_rotshft_w)() /* Opcode 0xd1 */
+{
+ unsigned ModRM = FETCHOP;
+ PREFIX(_rotate_shift_Word)(cpustate,ModRM,1,GetRMWord(ModRM));
+}
+
+
+void IX86_OPS_BASE::PREFIX86(_rotshft_bcl)() /* Opcode 0xd2 */
+{
+ unsigned ModRM = FETCHOP;
+ PREFIX(_rotate_shift_Byte)(cpustate,ModRM,cpustate->regs.b[CL],GetRMByte(ModRM));
+}
+
+void IX86_OPS_BASE::PREFIX86(_rotshft_wcl)() /* Opcode 0xd3 */
+{
+ unsigned ModRM = FETCHOP;
+ PREFIX(_rotate_shift_Word)(cpustate,ModRM,cpustate->regs.b[CL],GetRMWord(ModRM));
+}
+
+/* OB: Opcode works on NEC V-Series but not the Variants */
+/* one could specify any byte value as operand but the NECs */
+/* always substitute 0x0a. */
+void IX86_OPS_BASE::PREFIX86(_aam)() /* Opcode 0xd4 */
+{
+ unsigned mult = FETCH;
+
+ ICOUNT -= timing.aam;
+ if (mult == 0)
+ PREFIX(_interrupt)(cpustate, 0);
+ else
+ {
+ cpustate->regs.b[AH] = cpustate->regs.b[AL] / mult;
+ cpustate->regs.b[AL] %= mult;
+
+ SetSZPF_Word(cpustate->regs.w[AX]);
+ }
+}
+
+void IX86_OPS_BASE::PREFIX86(_aad)() /* Opcode 0xd5 */
+{
+ unsigned mult = FETCH;
+
+ ICOUNT -= timing.aad;
+
+ cpustate->regs.b[AL] = cpustate->regs.b[AH] * mult + cpustate->regs.b[AL];
+ cpustate->regs.b[AH] = 0;
+
+ SetZF(cpustate->regs.b[AL]);
+ SetPF(cpustate->regs.b[AL]);
+ cpustate->SignVal = 0;
+}
+
+
+void IX86_OPS_BASE::PREFIX86(_xlat)() /* Opcode 0xd7 */
+{
+ unsigned dest = cpustate->regs.w[BX]+cpustate->regs.b[AL];
+
+ ICOUNT -= timing.xlat;
+ cpustate->regs.b[AL] = GetMemB(DS, dest);
+}
+
+//#ifndef I80286
+void IX86_OPS_BASE::PREFIX86(_escape)() /* Opcodes 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde and 0xdf */
+{
+ unsigned ModRM = FETCH;
+ ICOUNT -= timing.nop;
+ GetRMByte(ModRM);
+}
+//#endif
+
+void IX86_OPS_BASE::PREFIX86(_loopne)() /* Opcode 0xe0 */
+{
+ int disp = (int)((INT8)FETCH);
+ unsigned tmp = cpustate->regs.w[CX]-1;
+
+ cpustate->regs.w[CX]=tmp;
+
+ if (!ZF && tmp) {
+ ICOUNT -= timing.loop_t;
+ cpustate->pc += disp;
+/* ASG - can probably assume this is safe
+ CHANGE_PC(cpustate->pc);*/
+ } else ICOUNT -= timing.loop_nt;
+}
+
+void IX86_OPS_BASE::PREFIX86(_loope)() /* Opcode 0xe1 */
+{
+ int disp = (int)((INT8)FETCH);
+ unsigned tmp = cpustate->regs.w[CX]-1;
+
+ cpustate->regs.w[CX]=tmp;
+
+ if (ZF && tmp) {
+ ICOUNT -= timing.loope_t;
+ cpustate->pc += disp;
+/* ASG - can probably assume this is safe
+ CHANGE_PC(cpustate->pc);*/
+ } else ICOUNT -= timing.loope_nt;
+}
+
+void IX86_OPS_BASE::PREFIX86(_loop)() /* Opcode 0xe2 */
+{
+ int disp = (int)((INT8)FETCH);
+ unsigned tmp = cpustate->regs.w[CX]-1;
+
+ cpustate->regs.w[CX]=tmp;
+
+ if (tmp) {
+ ICOUNT -= timing.loop_t;
+ cpustate->pc += disp;
+/* ASG - can probably assume this is safe
+ CHANGE_PC(cpustate->pc);*/
+ } else ICOUNT -= timing.loop_nt;
+}
+
+void IX86_OPS_BASE::PREFIX86(_jcxz)() /* Opcode 0xe3 */
+{
+ int disp = (int)((INT8)FETCH);
+
+ if (cpustate->regs.w[CX] == 0) {
+ ICOUNT -= timing.jcxz_t;
+ cpustate->pc += disp;
+/* ASG - can probably assume this is safe
+ CHANGE_PC(cpustate->pc);*/
+ } else
+ ICOUNT -= timing.jcxz_nt;
+}
+
+void IX86_OPS_BASE::PREFIX86(_inal)() /* Opcode 0xe4 */
+{
+ unsigned port;
+ port = FETCH;
+
+ ICOUNT -= timing.in_imm8;
+ cpustate->regs.b[AL] = read_port_byte(port);
+}
+
+void IX86_OPS_BASE::PREFIX86(_inax)() /* Opcode 0xe5 */
+{
+ unsigned port;
+ port = FETCH;
+
+ ICOUNT -= timing.in_imm16;
+ cpustate->regs.w[AX] = read_port_word(port);
+}
+
+void IX86_OPS_BASE::PREFIX86(_outal)() /* Opcode 0xe6 */
+{
+ unsigned port;
+ port = FETCH;
+
+ ICOUNT -= timing.out_imm8;
+ write_port_byte(port, cpustate->regs.b[AL]);
+}
+
+void IX86_OPS_BASE::PREFIX86(_outax)() /* Opcode 0xe7 */
+{
+ unsigned port;
+ port = FETCH;
+
+ ICOUNT -= timing.out_imm16;
+ write_port_word(port, cpustate->regs.w[AX]);
+}
+
+void IX86_OPS_BASE::PREFIX86(_call_d16)() /* Opcode 0xe8 */
+{
+ WORD ip, tmp;
+
+ FETCHWORD(tmp);
+ ip = cpustate->pc - cpustate->base[CS];
+ PUSH(ip);
+ ip += tmp;
+ cpustate->pc = (ip + cpustate->base[CS]) & AMASK;
+ ICOUNT -= timing.call_near;
+ CHANGE_PC(cpustate->pc);
+}
+
+void IX86_OPS_BASE::PREFIX86(_jmp_d16)() /* Opcode 0xe9 */
+{
+ WORD ip, tmp;
+
+ FETCHWORD(tmp);
+ ip = cpustate->pc - cpustate->base[CS] + tmp;
+ cpustate->pc = (ip + cpustate->base[CS]) & AMASK;
+ ICOUNT -= timing.jmp_near;
+ CHANGE_PC(cpustate->pc);
+}
+
+void IX86_OPS_BASE::PREFIX86(_jmp_far)() /* Opcode 0xea */
+{
+ unsigned tmp,tmp1;
+
+ tmp = FETCH;
+ tmp += FETCH << 8;
+
+ tmp1 = FETCH;
+ tmp1 += FETCH << 8;
+
+ cpustate->sregs[CS] = (WORD)tmp1;
+ cpustate->base[CS] = SegBase(CS);
+ cpustate->pc = (cpustate->base[CS] + tmp) & AMASK;
+ ICOUNT -= timing.jmp_far;
+ CHANGE_PC(cpustate->pc);
+}
+
+void IX86_OPS_BASE::PREFIX86(_jmp_d8)() /* Opcode 0xeb */
+{
+ int tmp = (int)((INT8)FETCH);
+ cpustate->pc += tmp;
+/* ASG - can probably assume this is safe
+ CHANGE_PC(cpustate->pc);*/
+ ICOUNT -= timing.jmp_short;
+}
+
+void IX86_OPS_BASE::PREFIX86(_inaldx)() /* Opcode 0xec */
+{
+ ICOUNT -= timing.in_dx8;
+ cpustate->regs.b[AL] = read_port_byte(cpustate->regs.w[DX]);
+}
+
+void IX86_OPS_BASE::PREFIX86(_inaxdx)() /* Opcode 0xed */
+{
+ unsigned port = cpustate->regs.w[DX];
+ ICOUNT -= timing.in_dx16;
+ cpustate->regs.w[AX] = read_port_word(port);
+}
+
+void IX86_OPS_BASE::PREFIX86(_outdxal)() /* Opcode 0xee */
+{
+ ICOUNT -= timing.out_dx8;
+ write_port_byte(cpustate->regs.w[DX], cpustate->regs.b[AL]);
+}
+
+void IX86_OPS_BASE::PREFIX86(_outdxax)() /* Opcode 0xef */
+{
+ unsigned port = cpustate->regs.w[DX];
+ ICOUNT -= timing.out_dx16;
+ write_port_word(port, cpustate->regs.w[AX]);
+}
+
+/* I think thats not a V20 instruction...*/
+void IX86_OPS_BASE::PREFIX86(_lock)() /* Opcode 0xf0 */
+{
+ ICOUNT -= timing.nop;
+ PREFIX(_instruction)[FETCHOP](cpustate); /* un-interruptible */
+}
+#endif
+
+void IX86_OPS_BASE::PREFIX(_pop_ss)() /* Opcode 0x17 */
+{
+ POP(cpustate->sregs[SS]);
+ cpustate->base[SS] = SegBase(SS);
+ ICOUNT -= timing.pop_seg;
+ PREFIX(_instruction)[FETCHOP](cpustate); /* no interrupt before next instruction */
+}
+
+void IX86_OPS_BASE::PREFIX(_es)() /* Opcode 0x26 */
+{
+ cpustate->seg_prefix = TRUE;
+ cpustate->prefix_seg = ES;
+ ICOUNT -= timing.override;
+ PREFIX(_instruction)[FETCHOP](cpustate);
+}
+
+void IX86_OPS_BASE::PREFIX(_cs)() /* Opcode 0x2e */
+{
+ cpustate->seg_prefix = TRUE;
+ cpustate->prefix_seg = CS;
+ ICOUNT -= timing.override;
+ PREFIX(_instruction)[FETCHOP](cpustate);
+}
+
+void IX86_OPS_BASE::PREFIX(_ss)() /* Opcode 0x36 */
+{
+ cpustate->seg_prefix = TRUE;
+ cpustate->prefix_seg = SS;
+ ICOUNT -= timing.override;
+ PREFIX(_instruction)[FETCHOP](cpustate);
+}
+
+void IX86_OPS_BASE::PREFIX(_ds)() /* Opcode 0x3e */
+{
+ cpustate->seg_prefix = TRUE;
+ cpustate->prefix_seg = DS;
+ ICOUNT -= timing.override;
+ PREFIX(_instruction)[FETCHOP](cpustate);
+}
+
+void IX86_OPS_BASE::PREFIX(_mov_sregw)() /* Opcode 0x8e */
+{
+ unsigned ModRM = FETCH;
+ WORD src = GetRMWord(ModRM);
+
+ ICOUNT -= (ModRM >= 0xc0) ? timing.mov_sr : timing.mov_sm;
+ switch (ModRM & 0x38)
+ {
+ case 0x00: /* mov es,ew */
+ cpustate->sregs[ES] = src;
+ cpustate->base[ES] = SegBase(ES);
+ break;
+ case 0x18: /* mov ds,ew */
+ cpustate->sregs[DS] = src;
+ cpustate->base[DS] = SegBase(DS);
+ break;
+ case 0x10: /* mov ss,ew */
+ cpustate->sregs[SS] = src;
+ cpustate->base[SS] = SegBase(SS); /* no interrupt allowed before next instr */
+ cpustate->seg_prefix = FALSE;
+ PREFIX(_instruction)[FETCHOP](cpustate);
+ break;
+ case 0x08: /* mov cs,ew */
+//#ifndef I80186
+ int ip = cpustate->pc - cpustate->base[CS];
+ cpustate->sregs[CS] = src;
+ cpustate->base[CS] = SegBase(CS);
+ cpustate->pc = (ip + cpustate->base[CS]) & AMASK;
+ CHANGE_PC(cpustate->pc);
+//#endif
+ break;
+ }
+}
+
+void IX86_OPS_BASE::PREFIX(_repne)() /* Opcode 0xf2 */
+{
+ PREFIX(rep)(cpustate, 0);
+}
+
+void IX86_OPS_BASE::PREFIX(_repe)() /* Opcode 0xf3 */
+{
+ PREFIX(rep)(cpustate, 1);
+}
+
+void IX86_OPS_BASE::PREFIX(_sti)() /* Opcode 0xfb */
+{
+ ICOUNT -= timing.flag_ops;
+ SetIF(1);
+ PREFIX(_instruction)[FETCHOP](cpustate); /* no interrupt before next instruction */
+
+ /* if an interrupt is pending, signal an interrupt */
+ if (cpustate->irq_state) {
+ PREFIX86(_interrupt)(cpustate, (UINT32)-1);
+ cpustate->irq_state = 0;
+ }
+}
+
+//#ifndef I80186
+void IX86_OPS_BASE::PREFIX86(_hlt)() /* Opcode 0xf4 */
+{
+ cpustate->halted=1;
+ ICOUNT = 0;
+}
+
+void IX86_OPS_BASE::PREFIX86(_cmc)() /* Opcode 0xf5 */
+{
+ ICOUNT -= timing.flag_ops;
+ cpustate->CarryVal = !CF;
+}
+
+void IX86_OPS_BASE::PREFIX86(_f6pre)()
+{
+ /* Opcode 0xf6 */
+ unsigned ModRM = FETCH;
+ unsigned tmp = (unsigned)GetRMByte(ModRM);
+ unsigned tmp2;
+
+
+ switch (ModRM & 0x38)
+ {
+ case 0x00: /* TEST Eb, data8 */
+ case 0x08: /* ??? */
+ ICOUNT -= (ModRM >= 0xc0) ? timing.alu_ri8 : timing.alu_mi8_ro;
+ tmp &= FETCH;
+
+ cpustate->CarryVal = cpustate->OverVal = cpustate->AuxVal = 0;
+ SetSZPF_Byte(tmp);
+ break;
+
+ case 0x10: /* NOT Eb */
+ ICOUNT -= (ModRM >= 0xc0) ? timing.negnot_r8 : timing.negnot_m8;
+ PutbackRMByte(ModRM,~tmp);
+ break;
+
+ case 0x18: /* NEG Eb */
+ ICOUNT -= (ModRM >= 0xc0) ? timing.negnot_r8 : timing.negnot_m8;
+ tmp2=0;
+ SUBB(tmp2,tmp);
+ PutbackRMByte(ModRM,tmp2);
+ break;
+ case 0x20: /* MUL AL, Eb */
+ ICOUNT -= (ModRM >= 0xc0) ? timing.mul_r8 : timing.mul_m8;
+ {
+ UINT16 result;
+ tmp2 = cpustate->regs.b[AL];
+
+ SetSF((INT8)tmp2);
+ SetPF(tmp2);
+
+ result = (UINT16)tmp2*tmp;
+ cpustate->regs.w[AX]=(WORD)result;
+
+ SetZF(cpustate->regs.w[AX]);
+ cpustate->CarryVal = cpustate->OverVal = (cpustate->regs.b[AH] != 0);
+ }
+ break;
+ case 0x28: /* IMUL AL, Eb */
+ ICOUNT -= (ModRM >= 0xc0) ? timing.imul_r8 : timing.imul_m8;
+ {
+ INT16 result;
+
+ tmp2 = (unsigned)cpustate->regs.b[AL];
+
+ SetSF((INT8)tmp2);
+ SetPF(tmp2);
+
+ result = (INT16)((INT8)tmp2)*(INT16)((INT8)tmp);
+ cpustate->regs.w[AX]=(WORD)result;
+
+ SetZF(cpustate->regs.w[AX]);
+
+ cpustate->CarryVal = cpustate->OverVal = (result >> 7 != 0) && (result >> 7 != -1);
+ }
+ break;
+ case 0x30: /* DIV AL, Ew */
+ ICOUNT -= (ModRM >= 0xc0) ? timing.div_r8 : timing.div_m8;
+ {
+ UINT16 result;
+
+ result = cpustate->regs.w[AX];
+
+ if (tmp)
+ {
+ if ((result / tmp) > 0xff)
+ {
+ PREFIX(_interrupt)(cpustate, 0);
+ break;
+ }
+ else
+ {
+ cpustate->regs.b[AH] = result % tmp;
+ cpustate->regs.b[AL] = result / tmp;
+ }
+ }
+ else
+ {
+ PREFIX(_interrupt)(cpustate, 0);
+ break;
+ }
+ }
+ break;
+ case 0x38: /* IDIV AL, Ew */
+ ICOUNT -= (ModRM >= 0xc0) ? timing.idiv_r8 : timing.idiv_m8;
+ {
+
+ INT16 result;
+
+ result = cpustate->regs.w[AX];
+
+ if (tmp)
+ {
+ tmp2 = result % (INT16)((INT8)tmp);
+
+ if ((result /= (INT16)((INT8)tmp)) > 0xff)
+ {
+ PREFIX(_interrupt)(cpustate, 0);
+ break;
+ }
+ else
+ {
+ cpustate->regs.b[AL] = result;
+ cpustate->regs.b[AH] = tmp2;
+ }
+ }
+ else
+ {
+ PREFIX(_interrupt)(cpustate, 0);
+ break;
+ }
+ }
+ break;
+ }
+}
+
+
+void IX86_OPS_BASE::PREFIX86(_f7pre)()
+{
+ /* Opcode 0xf7 */
+ unsigned ModRM = FETCH;
+ unsigned tmp = GetRMWord(ModRM);
+ unsigned tmp2;
+
+
+ switch (ModRM & 0x38)
+ {
+ case 0x00: /* TEST Ew, data16 */
+ case 0x08: /* ??? */
+ ICOUNT -= (ModRM >= 0xc0) ? timing.alu_ri16 : timing.alu_mi16_ro;
+ tmp2 = FETCH;
+ tmp2 += FETCH << 8;
+
+ tmp &= tmp2;
+
+ cpustate->CarryVal = cpustate->OverVal = cpustate->AuxVal = 0;
+ SetSZPF_Word(tmp);
+ break;
+
+ case 0x10: /* NOT Ew */
+ ICOUNT -= (ModRM >= 0xc0) ? timing.negnot_r16 : timing.negnot_m16;
+ tmp = ~tmp;
+ PutbackRMWord(ModRM,tmp);
+ break;
+
+ case 0x18: /* NEG Ew */
+ ICOUNT -= (ModRM >= 0xc0) ? timing.negnot_r16 : timing.negnot_m16;
+ tmp2 = 0;
+ SUBW(tmp2,tmp);
+ PutbackRMWord(ModRM,tmp2);
+ break;
+ case 0x20: /* MUL AX, Ew */
+ ICOUNT -= (ModRM >= 0xc0) ? timing.mul_r16 : timing.mul_m16;
+ {
+ UINT32 result;
+ tmp2 = cpustate->regs.w[AX];
+
+ SetSF((INT16)tmp2);
+ SetPF(tmp2);
+
+ result = (UINT32)tmp2*tmp;
+ cpustate->regs.w[AX]=(WORD)result;
+ result >>= 16;
+ cpustate->regs.w[DX]=result;
+
+ SetZF(cpustate->regs.w[AX] | cpustate->regs.w[DX]);
+ cpustate->CarryVal = cpustate->OverVal = (cpustate->regs.w[DX] != 0);
+ }
+ break;
+
+ case 0x28: /* IMUL AX, Ew */
+ ICOUNT -= (ModRM >= 0xc0) ? timing.imul_r16 : timing.imul_m16;
+ {
+ INT32 result;
+
+ tmp2 = cpustate->regs.w[AX];
+
+ SetSF((INT16)tmp2);
+ SetPF(tmp2);
+
+ result = (INT32)((INT16)tmp2)*(INT32)((INT16)tmp);
+ cpustate->CarryVal = cpustate->OverVal = (result >> 15 != 0) && (result >> 15 != -1);
+
+ cpustate->regs.w[AX]=(WORD)result;
+ result = (WORD)(result >> 16);
+ cpustate->regs.w[DX]=result;
+
+ SetZF(cpustate->regs.w[AX] | cpustate->regs.w[DX]);
+ }
+ break;
+ case 0x30: /* DIV AX, Ew */
+ ICOUNT -= (ModRM >= 0xc0) ? timing.div_r16 : timing.div_m16;
+ {
+ UINT32 result;
+
+ result = (cpustate->regs.w[DX] << 16) + cpustate->regs.w[AX];
+
+ if (tmp)
+ {
+ tmp2 = result % tmp;
+ if ((result / tmp) > 0xffff)
+ {
+ PREFIX(_interrupt)(cpustate, 0);
+ break;
+ }
+ else
+ {
+ cpustate->regs.w[DX]=tmp2;
+ result /= tmp;
+ cpustate->regs.w[AX]=result;
+ }
+ }
+ else
+ {
+ PREFIX(_interrupt)(cpustate, 0);
+ break;
+ }
+ }
+ break;
+ case 0x38: /* IDIV AX, Ew */
+ ICOUNT -= (ModRM >= 0xc0) ? timing.idiv_r16 : timing.idiv_m16;
+ {
+ INT32 result;
+
+ result = (cpustate->regs.w[DX] << 16) + cpustate->regs.w[AX];
+
+ if (tmp)
+ {
+ tmp2 = result % (INT32)((INT16)tmp);
+ if ((result /= (INT32)((INT16)tmp)) > 0xffff)
+ {
+ PREFIX(_interrupt)(cpustate, 0);
+ break;
+ }
+ else
+ {
+ cpustate->regs.w[AX]=result;
+ cpustate->regs.w[DX]=tmp2;
+ }
+ }
+ else
+ {
+ PREFIX(_interrupt)(cpustate, 0);
+ break;
+ }
+ }
+ break;
+ }
+}
+
+
+void IX86_OPS_BASE::PREFIX86(_clc)() /* Opcode 0xf8 */
+{
+ ICOUNT -= timing.flag_ops;
+ cpustate->CarryVal = 0;
+}
+
+void IX86_OPS_BASE::PREFIX86(_stc)() /* Opcode 0xf9 */
+{
+ ICOUNT -= timing.flag_ops;
+ cpustate->CarryVal = 1;
+}
+
+void IX86_OPS_BASE::PREFIX86(_cli)() /* Opcode 0xfa */
+{
+ ICOUNT -= timing.flag_ops;
+ SetIF(0);
+}
+
+void IX86_OPS_BASE::PREFIX86(_cld)() /* Opcode 0xfc */
+{
+ ICOUNT -= timing.flag_ops;
+ SetDF(0);
+}
+
+void IX86_OPS_BASE::PREFIX86(_std)() /* Opcode 0xfd */
+{
+ ICOUNT -= timing.flag_ops;
+ SetDF(1);
+}
+
+void IX86_OPS_BASE::PREFIX86(_fepre)() /* Opcode 0xfe */
+{
+ unsigned ModRM = FETCH;
+ unsigned tmp = GetRMByte(ModRM);
+ unsigned tmp1;
+
+ ICOUNT -= (ModRM >= 0xc0) ? timing.incdec_r8 : timing.incdec_m8;
+ if ((ModRM & 0x38) == 0) /* INC eb */
+ {
+ tmp1 = tmp+1;
+ SetOFB_Add(tmp1,tmp,1);
+ }
+ else /* DEC eb */
+ {
+ tmp1 = tmp-1;
+ SetOFB_Sub(tmp1,1,tmp);
+ }
+
+ SetAF(tmp1,tmp,1);
+ SetSZPF_Byte(tmp1);
+
+ PutbackRMByte(ModRM,(BYTE)tmp1);
+}
+
+
+void IX86_OPS_BASE::PREFIX86(_ffpre)() /* Opcode 0xff */
+{
+ unsigned ModRM = FETCHOP;
+ unsigned tmp;
+ unsigned tmp1, tmp2;
+ WORD ip;
+
+ switch(ModRM & 0x38)
+ {
+ case 0x00: /* INC ew */
+ ICOUNT -= (ModRM >= 0xc0) ? timing.incdec_r16 : timing.incdec_m16;
+ tmp = GetRMWord(ModRM);
+ tmp1 = tmp+1;
+
+ SetOFW_Add(tmp1,tmp,1);
+ SetAF(tmp1,tmp,1);
+ SetSZPF_Word(tmp1);
+
+ PutbackRMWord(ModRM,(WORD)tmp1);
+ break;
+
+ case 0x08: /* DEC ew */
+ ICOUNT -= (ModRM >= 0xc0) ? timing.incdec_r16 : timing.incdec_m16;
+ tmp = GetRMWord(ModRM);
+ tmp1 = tmp-1;
+
+ SetOFW_Sub(tmp1,1,tmp);
+ SetAF(tmp1,tmp,1);
+ SetSZPF_Word(tmp1);
+
+ PutbackRMWord(ModRM,(WORD)tmp1);
+ break;
+
+ case 0x10: /* CALL ew */
+ ICOUNT -= (ModRM >= 0xc0) ? timing.call_r16 : timing.call_m16;
+ tmp = GetRMWord(ModRM);
+
+ ip = cpustate->pc - cpustate->base[CS];
+ PUSH(ip);
+ cpustate->pc = (cpustate->base[CS] + (WORD)tmp) & AMASK;
+ CHANGE_PC(cpustate->pc);
+ break;
+
+ case 0x18: /* CALL FAR ea */
+ ICOUNT -= timing.call_m32;
+ tmp = cpustate->sregs[CS]; /* HJB 12/13/98 need to skip displacements of cpustate->ea */
+ tmp1 = GetRMWord(ModRM);
+ tmp2 = GetnextRMWord;
+ ip = cpustate->pc - cpustate->base[CS];
+ cpustate->sregs[CS] = tmp2;
+ cpustate->base[CS] = SegBase(CS);
+ cpustate->pc = (cpustate->base[CS] + tmp1) & AMASK;
+
+ PUSH(tmp);
+ PUSH(ip);
+ CHANGE_PC(cpustate->pc);
+ break;
+
+ case 0x20: /* JMP ea */
+ ICOUNT -= (ModRM >= 0xc0) ? timing.jmp_r16 : timing.jmp_m16;
+ ip = GetRMWord(ModRM);
+ cpustate->pc = (cpustate->base[CS] + ip) & AMASK;
+ CHANGE_PC(cpustate->pc);
+ break;
+
+ case 0x28: /* JMP FAR ea */
+ ICOUNT -= timing.jmp_m32;
+
+ cpustate->pc = GetRMWord(ModRM);
+ cpustate->sregs[CS] = GetnextRMWord;
+ cpustate->base[CS] = SegBase(CS);
+ cpustate->pc = (cpustate->pc + cpustate->base[CS]) & AMASK;
+
+ CHANGE_PC(cpustate->pc);
+ break;
+
+ case 0x30: /* PUSH ea */
+ ICOUNT -= (ModRM >= 0xc0) ? timing.push_r16 : timing.push_m16;
+ tmp = GetRMWord(ModRM);
+ PUSH(tmp);
+ break;
+ default:
+ tmp = GetRMWord(ModRM); // 286 doesn't matter but 8086?
+ return PREFIX(_invalid)(cpustate);
+ }
+}
+
+
+void IX86_OPS_BASE::PREFIX86(_invalid)()
+{
+ logerror("illegal instruction %.2x at %.5x\n",PEEKBYTE(cpustate->pc-1), cpustate->pc);
+ /* i8086/i8088 ignore an invalid opcode. */
+ /* i80186/i80188 probably also ignore an invalid opcode. */
+ ICOUNT -= 10;
+}
+
+//#ifndef I80286
+void IX86_OPS_BASE::PREFIX86(_invalid_2b)()
+{
+ unsigned ModRM = FETCH;
+ GetRMByte(ModRM);
+ logerror("illegal 2 byte instruction %.2x at %.5x\n",PEEKBYTE(cpustate->pc-2), cpustate->pc-2);
+ ICOUNT -= 10;
+}
+//#endif
+#endif
--- /dev/null
+#pragma once
+
+#ifndef __INSTR86_H__
+#define __INSTR86_H__
+
+/****************************************************************************
+* real mode i286 emulator v1.4 by Fabrice Frances *
+* (initial work based on David Hedley's pcemu) *
+****************************************************************************/
+
+// file will be included in all cpu variants
+// put non i86 instructions in own files (i286, i386, nec)
+// function renaming will be added when necessary
+// timing value should move to separate array
+
+//void IX86_OPS::PREFIX86(_add_br8)();
+//void IX86_OPS::PREFIX86(_add_wr16)();
+//void IX86_OPS::PREFIX86(_add_r8b)();
+//void IX86_OPS::PREFIX86(_add_r16w)();
+//void IX86_OPS::PREFIX86(_add_ald8)();
+//void IX86_OPS::PREFIX86(_add_axd16)();
+//void IX86_OPS::PREFIX86(_push_es)();
+//void IX86_OPS::PREFIX86(_pop_es)();
+//void IX86_OPS::PREFIX86(_or_br8)();
+//void IX86_OPS::PREFIX86(_or_r8b)();
+//void IX86_OPS::PREFIX86(_or_wr16)();
+//void IX86_OPS::PREFIX86(_or_r16w)();
+//void IX86_OPS::PREFIX86(_or_ald8)();
+//void IX86_OPS::PREFIX86(_or_axd16)();
+//void IX86_OPS::PREFIX86(_push_cs)();
+//#ifndef I80286
+//void IX86_OPS::PREFIX86(_pop_cs)();
+//#endif
+//void IX86_OPS::PREFIX86(_adc_br8)();
+//void IX86_OPS::PREFIX86(_adc_wr16)();
+//void IX86_OPS::PREFIX86(_adc_r8b)();
+//void IX86_OPS::PREFIX86(_adc_r16w)();
+//void IX86_OPS::PREFIX86(_adc_ald8)();
+//void IX86_OPS::PREFIX86(_adc_axd16)();
+//void IX86_OPS::PREFIX86(_push_ss)();
+//void IX86_OPS::PREFIX86(_pop_ss)();
+//void IX86_OPS::PREFIX86(_sbb_br8)();
+//void IX86_OPS::PREFIX86(_sbb_wr16)();
+//void IX86_OPS::PREFIX86(_sbb_r8b)();
+//void IX86_OPS::PREFIX86(_sbb_r16w)();
+//void IX86_OPS::PREFIX86(_sbb_ald8)();
+//void IX86_OPS::PREFIX86(_sbb_axd16)();
+//void IX86_OPS::PREFIX86(_push_ds)();
+//void IX86_OPS::PREFIX86(_pop_ds)();
+//void IX86_OPS::PREFIX86(_and_br8)();
+//void IX86_OPS::PREFIX86(_and_r8b)();
+//void IX86_OPS::PREFIX86(_and_wr16)();
+//void IX86_OPS::PREFIX86(_and_r16w)();
+//void IX86_OPS::PREFIX86(_and_ald8)();
+//void IX86_OPS::PREFIX86(_and_axd16)();
+//void IX86_OPS::PREFIX86(_es)();
+//void IX86_OPS::PREFIX86(_daa)();
+//void IX86_OPS::PREFIX86(_sub_br8)();
+//void IX86_OPS::PREFIX86(_sub_wr16)();
+//void IX86_OPS::PREFIX86(_sub_r8b)();
+//void IX86_OPS::PREFIX86(_sub_r16w)();
+//void IX86_OPS::PREFIX86(_sub_ald8)();
+//void IX86_OPS::PREFIX86(_sub_axd16)();
+//void IX86_OPS::PREFIX86(_cs)();
+//void IX86_OPS::PREFIX86(_das)();
+//void IX86_OPS::PREFIX86(_xor_br8)();
+//void IX86_OPS::PREFIX86(_xor_r8b)();
+//void IX86_OPS::PREFIX86(_xor_wr16)();
+//void IX86_OPS::PREFIX86(_xor_r16w)();
+//void IX86_OPS::PREFIX86(_xor_ald8)();
+//void IX86_OPS::PREFIX86(_xor_axd16)();
+//void IX86_OPS::PREFIX86(_ss)();
+//void IX86_OPS::PREFIX86(_aaa)();
+//void IX86_OPS::PREFIX86(_cmp_br8)();
+//void IX86_OPS::PREFIX86(_cmp_wr16)();
+//void IX86_OPS::PREFIX86(_cmp_r8b)();
+//void IX86_OPS::PREFIX86(_cmp_r16w)();
+//void IX86_OPS::PREFIX86(_cmp_ald8)();
+//void IX86_OPS::PREFIX86(_cmp_axd16)();
+//void IX86_OPS::PREFIX86(_ds)();
+//void IX86_OPS::PREFIX86(_aas)();
+//void IX86_OPS::PREFIX86(_inc_ax)();
+//void IX86_OPS::PREFIX86(_inc_cx)();
+//void IX86_OPS::PREFIX86(_inc_dx)();
+//void IX86_OPS::PREFIX86(_inc_bx)();
+//void IX86_OPS::PREFIX86(_inc_sp)();
+//void IX86_OPS::PREFIX86(_inc_bp)();
+//void IX86_OPS::PREFIX86(_inc_si)();
+//void IX86_OPS::PREFIX86(_inc_di)();
+//void IX86_OPS::PREFIX86(_dec_ax)();
+//void IX86_OPS::PREFIX86(_dec_cx)();
+//void IX86_OPS::PREFIX86(_dec_dx)();
+//void IX86_OPS::PREFIX86(_dec_bx)();
+//void IX86_OPS::PREFIX86(_dec_sp)();
+//void IX86_OPS::PREFIX86(_dec_bp)();
+//void IX86_OPS::PREFIX86(_dec_si)();
+//void IX86_OPS::PREFIX86(_dec_di)();
+//void IX86_OPS::PREFIX86(_push_ax)();
+//void IX86_OPS::PREFIX86(_push_cx)();
+//void IX86_OPS::PREFIX86(_push_dx)();
+//void IX86_OPS::PREFIX86(_push_bx)();
+//void IX86_OPS::PREFIX86(_push_sp)();
+//void IX86_OPS::PREFIX86(_push_bp)();
+//void IX86_OPS::PREFIX86(_push_si)();
+//void IX86_OPS::PREFIX86(_push_di)();
+//void IX86_OPS::PREFIX86(_pop_ax)();
+//void IX86_OPS::PREFIX86(_pop_cx)();
+//void IX86_OPS::PREFIX86(_pop_dx)();
+//void IX86_OPS::PREFIX86(_pop_bx)();
+//void IX86_OPS::PREFIX86(_pop_sp)();
+//void IX86_OPS::PREFIX86(_pop_bp)();
+//void IX86_OPS::PREFIX86(_pop_si)();
+//void IX86_OPS::PREFIX86(_pop_di)();
+//void IX86_OPS::PREFIX86(_jo)();
+//void IX86_OPS::PREFIX86(_jno)();
+//void IX86_OPS::PREFIX86(_jb)();
+//void IX86_OPS::PREFIX86(_jnb)();
+//void IX86_OPS::PREFIX86(_jz)();
+//void IX86_OPS::PREFIX86(_jnz)();
+//void IX86_OPS::PREFIX86(_jbe)();
+//void IX86_OPS::PREFIX86(_jnbe)();
+//void IX86_OPS::PREFIX86(_js)();
+//void IX86_OPS::PREFIX86(_jns)();
+//void IX86_OPS::PREFIX86(_jp)();
+//void IX86_OPS::PREFIX86(_jnp)();
+//void IX86_OPS::PREFIX86(_jl)();
+//void IX86_OPS::PREFIX86(_jnl)();
+//void IX86_OPS::PREFIX86(_jle)();
+//void IX86_OPS::PREFIX86(_jnle)();
+//void IX86_OPS::PREFIX86(_80pre)();
+//void IX86_OPS::PREFIX86(_82pre)();
+//void IX86_OPS::PREFIX86(_81pre)();
+//void IX86_OPS::PREFIX86(_83pre)();
+//void IX86_OPS::PREFIX86(_test_br8)();
+//void IX86_OPS::PREFIX86(_test_wr16)();
+//void IX86_OPS::PREFIX86(_xchg_br8)();
+//void IX86_OPS::PREFIX86(_xchg_wr16)();
+//void IX86_OPS::PREFIX86(_mov_br8)();
+//void IX86_OPS::PREFIX86(_mov_r8b)();
+//void IX86_OPS::PREFIX86(_mov_wr16)();
+//void IX86_OPS::PREFIX86(_mov_r16w)();
+//void IX86_OPS::PREFIX86(_mov_wsreg)();
+//void IX86_OPS::PREFIX86(_lea)();
+//void IX86_OPS::PREFIX86(_mov_sregw)();
+//void IX86_OPS::PREFIX86(_invalid)();
+//#ifndef I80286
+//void IX86_OPS::PREFIX86(_invalid_2b)();
+//#endif
+//void IX86_OPS::PREFIX86(_popw)();
+//void IX86_OPS::PREFIX86(_nop)();
+//void IX86_OPS::PREFIX86(_xchg_axcx)();
+//void IX86_OPS::PREFIX86(_xchg_axdx)();
+//void IX86_OPS::PREFIX86(_xchg_axbx)();
+//void IX86_OPS::PREFIX86(_xchg_axsp)();
+//void IX86_OPS::PREFIX86(_xchg_axbp)();
+//void IX86_OPS::PREFIX86(_xchg_axsi)();
+//void IX86_OPS::PREFIX86(_xchg_axdi)();
+//void IX86_OPS::PREFIX86(_cbw)();
+//void IX86_OPS::PREFIX86(_cwd)();
+//void IX86_OPS::PREFIX86(_call_far)();
+//void IX86_OPS::PREFIX86(_pushf)();
+//void IX86_OPS::PREFIX86(_popf)();
+//void IX86_OPS::PREFIX86(_sahf)();
+//void IX86_OPS::PREFIX86(_lahf)();
+//void IX86_OPS::PREFIX86(_mov_aldisp)();
+//void IX86_OPS::PREFIX86(_mov_axdisp)();
+//void IX86_OPS::PREFIX86(_mov_dispal)();
+//void IX86_OPS::PREFIX86(_mov_dispax)();
+//void IX86_OPS::PREFIX86(_movsb)();
+//void IX86_OPS::PREFIX86(_movsw)();
+//void IX86_OPS::PREFIX86(_cmpsb)();
+//void IX86_OPS::PREFIX86(_cmpsw)();
+//void IX86_OPS::PREFIX86(_test_ald8)();
+//void IX86_OPS::PREFIX86(_test_axd16)();
+//void IX86_OPS::PREFIX86(_stosb)();
+//void IX86_OPS::PREFIX86(_stosw)();
+//void IX86_OPS::PREFIX86(_lodsb)();
+//void IX86_OPS::PREFIX86(_lodsw)();
+//void IX86_OPS::PREFIX86(_scasb)();
+//void IX86_OPS::PREFIX86(_scasw)();
+//void IX86_OPS::PREFIX86(_mov_ald8)();
+//void IX86_OPS::PREFIX86(_mov_cld8)();
+//void IX86_OPS::PREFIX86(_mov_dld8)();
+//void IX86_OPS::PREFIX86(_mov_bld8)();
+//void IX86_OPS::PREFIX86(_mov_ahd8)();
+//void IX86_OPS::PREFIX86(_mov_chd8)();
+//void IX86_OPS::PREFIX86(_mov_dhd8)();
+//void IX86_OPS::PREFIX86(_mov_bhd8)();
+//void IX86_OPS::PREFIX86(_mov_axd16)();
+//void IX86_OPS::PREFIX86(_mov_cxd16)();
+//void IX86_OPS::PREFIX86(_mov_dxd16)();
+//void IX86_OPS::PREFIX86(_mov_bxd16)();
+//void IX86_OPS::PREFIX86(_mov_spd16)();
+//void IX86_OPS::PREFIX86(_mov_bpd16)();
+//void IX86_OPS::PREFIX86(_mov_sid16)();
+//void IX86_OPS::PREFIX86(_mov_did16)();
+//void IX86_OPS::PREFIX86(_ret_d16)();
+//void IX86_OPS::PREFIX86(_ret)();
+//void IX86_OPS::PREFIX86(_les_dw)();
+//void IX86_OPS::PREFIX86(_lds_dw)();
+//void IX86_OPS::PREFIX86(_mov_bd8)();
+//void IX86_OPS::PREFIX86(_mov_wd16)();
+//void IX86_OPS::PREFIX86(_retf_d16)();
+//void IX86_OPS::PREFIX86(_retf)();
+//void IX86_OPS::PREFIX86(_int3)();
+//void IX86_OPS::PREFIX86(_int)();
+//void IX86_OPS::PREFIX86(_into)();
+//void IX86_OPS::PREFIX86(_iret)();
+//void IX86_OPS::PREFIX86(_rotshft_b)();
+//void IX86_OPS::PREFIX86(_rotshft_w)();
+//void IX86_OPS::PREFIX86(_rotshft_bcl)();
+//void IX86_OPS::PREFIX86(_rotshft_wcl)();
+//void IX86_OPS::PREFIX86(_aam)();
+//void IX86_OPS::PREFIX86(_aad)();
+//void IX86_OPS::PREFIX86(_xlat)();
+//void IX86_OPS::PREFIX86(_escape)();
+//void IX86_OPS::PREFIX86(_loopne)();
+//void IX86_OPS::PREFIX86(_loope)();
+//void IX86_OPS::PREFIX86(_loop)();
+//void IX86_OPS::PREFIX86(_jcxz)();
+//void IX86_OPS::PREFIX86(_inal)();
+//void IX86_OPS::PREFIX86(_inax)();
+//void IX86_OPS::PREFIX86(_outal)();
+//void IX86_OPS::PREFIX86(_outax)();
+//void IX86_OPS::PREFIX86(_call_d16)();
+//void IX86_OPS::PREFIX86(_jmp_d16)();
+//void IX86_OPS::PREFIX86(_jmp_far)();
+//void IX86_OPS::PREFIX86(_jmp_d8)();
+//void IX86_OPS::PREFIX86(_inaldx)();
+//void IX86_OPS::PREFIX86(_inaxdx)();
+//void IX86_OPS::PREFIX86(_outdxal)();
+//void IX86_OPS::PREFIX86(_outdxax)();
+//void IX86_OPS::PREFIX86(_lock)();
+//void IX86_OPS::PREFIX86(_repne)();
+//void IX86_OPS::PREFIX86(_repe)();
+//void IX86_OPS::PREFIX86(_hlt)();
+//void IX86_OPS::PREFIX86(_cmc)();
+//void IX86_OPS::PREFIX86(_f6pre)();
+//void IX86_OPS::PREFIX86(_f7pre)();
+//void IX86_OPS::PREFIX86(_clc)();
+//void IX86_OPS::PREFIX86(_stc)();
+//void IX86_OPS::PREFIX86(_cli)();
+//void IX86_OPS::PREFIX86(_sti)();
+//void IX86_OPS::PREFIX86(_cld)();
+//void IX86_OPS::PREFIX86(_std)();
+//void IX86_OPS::PREFIX86(_fepre)();
+//void IX86_OPS::PREFIX86(_ffpre)();
+//void IX86_OPS::PREFIX86(_wait)();
+
+#endif /* __INSTR86_H__ */
--- /dev/null
+#include "./i86priv.h"
+
+#ifdef I80286
+#undef GetMemB
+#undef GetMemW
+#undef PutMemB
+#undef PutMemW
+#undef PUSH
+#undef POP
+#undef IOPL
+#undef NT
+#undef xF
+#undef CompressFlags
+
+#define GetMemB(Seg,Off) (read_mem_byte(GetMemAddr(cpustate,Seg,Off,1,I80286_READ)))
+#define GetMemW(Seg,Off) (read_mem_word(GetMemAddr(cpustate,Seg,Off,2,I80286_READ)))
+#define PutMemB(Seg,Off,x) write_mem_byte(GetMemAddr(cpustate,Seg,Off,1,I80286_WRITE), (x))
+#define PutMemW(Seg,Off,x) write_mem_word(GetMemAddr(cpustate,Seg,Off,2,I80286_WRITE), (x))
+
+#define PUSH(val) { if(PM) i80286_check_permission(cpustate, SS, cpustate->regs.w[SP]-2, I80286_WORD, I80286_WRITE); cpustate->regs.w[SP] -= 2; WriteWord(((cpustate->base[SS] + cpustate->regs.w[SP]) & AMASK), val); }
+#define POP(var) { if(PM) i80286_check_permission(cpustate, SS, cpustate->regs.w[SP], I80286_WORD, I80286_READ); cpustate->regs.w[SP] += 2; var = ReadWord(((cpustate->base[SS] + ((cpustate->regs.w[SP]-2) & 0xffff)) & AMASK)); }
+
+#define IOPL ((cpustate->flags&0x3000)>>12)
+#define NT ((cpustate->flags&0x4000)>>14)
+#define xF (0)
+
+#define CompressFlags() (WORD)(CF | 2 |(PF << 2) | (AF << 4) | (ZF << 6) \
+ | (SF << 7) | (cpustate->TF << 8) | (cpustate->IF << 9) | (cpustate->MF << 15) \
+ | (DF << 10) | (OF << 11) | (IOPL << 12) | (NT << 14) | (xF << 15))
+
+#endif
+#include "./ix86_opdef_real.h"
+#ifdef I80286
+#include "./modrm286.h"
+#else
+#include "./modrm.h"
+#endif
+
+// Interrupt
+
+// 80186
+void IX86_OPS::PREFIX186(_pusha)() /* Opcode 0x60 */
+{
+ unsigned tmp=cpustate->regs.w[SP];
+
+#ifdef I80286
+ if(PM) i80286_check_permission(SS, cpustate->regs.w[SP]-16, 16, I80286_WRITE);
+#endif
+ ICOUNT -= timing.pusha;
+ PUSH(cpustate->regs.w[AX]);
+ PUSH(cpustate->regs.w[CX]);
+ PUSH(cpustate->regs.w[DX]);
+ PUSH(cpustate->regs.w[BX]);
+ PUSH(tmp);
+ PUSH(cpustate->regs.w[BP]);
+ PUSH(cpustate->regs.w[SI]);
+ PUSH(cpustate->regs.w[DI]);
+}
+
+static unsigned i186_popa_tmp_r; // hack around GCC 4.6 error because we need the side effects of POP
+void IX86_OPS::PREFIX186(_popa)() /* Opcode 0x61 */
+{
+
+#ifdef I80286
+ if(PM) i80286_check_permission(SS, cpustate->regs.w[SP], 16, I80286_READ);
+#endif
+ ICOUNT -= timing.popa;
+ POP(cpustate->regs.w[DI]);
+ POP(cpustate->regs.w[SI]);
+ POP(cpustate->regs.w[BP]);
+ POP(i186_popa_tmp_r);
+ POP(cpustate->regs.w[BX]);
+ POP(cpustate->regs.w[DX]);
+ POP(cpustate->regs.w[CX]);
+ POP(cpustate->regs.w[AX]);
+}
+
+void IX86_OPS::PREFIX186(_insb)() /* Opcode 0x6c */
+{
+#ifdef I80286
+ if (PM && (CPL>IOPL)) throw TRAP(GENERAL_PROTECTION_FAULT, 0);
+#endif
+ ICOUNT -= timing.ins8;
+ PutMemB(ES,cpustate->regs.w[DI],read_port_byte(cpustate->regs.w[DX]));
+ cpustate->regs.w[DI] += cpustate->DirVal;
+}
+
+void IX86_OPS::PREFIX186(_insw)() /* Opcode 0x6d */
+{
+#ifdef I80286
+ if (PM && (CPL>IOPL)) throw TRAP(GENERAL_PROTECTION_FAULT, 0);
+#endif
+ ICOUNT -= timing.ins16;
+ PutMemW(ES,cpustate->regs.w[DI],read_port_word(cpustate->regs.w[DX]));
+ cpustate->regs.w[DI] += 2 * cpustate->DirVal;
+}
+
+void IX86_OPS::PREFIX186(_outsb)() /* Opcode 0x6e */
+{
+#ifdef I80286
+ if (PM && (CPL>IOPL)) throw TRAP(GENERAL_PROTECTION_FAULT, 0);
+#endif
+ ICOUNT -= timing.outs8;
+ write_port_byte(cpustate->regs.w[DX],GetMemB(DS,cpustate->regs.w[SI]));
+ cpustate->regs.w[SI] += cpustate->DirVal; /* GOL 11/27/01 */
+}
+
+void IX86_OPS::PREFIX186(_outsw)() /* Opcode 0x6f */
+{
+#ifdef I80286
+ if (PM && (CPL>IOPL)) throw TRAP(GENERAL_PROTECTION_FAULT, 0);
+#endif
+ ICOUNT -= timing.outs16;
+ write_port_word(cpustate->regs.w[DX],GetMemW(DS,cpustate->regs.w[SI]));
+ cpustate->regs.w[SI] += 2 * cpustate->DirVal; /* GOL 11/27/01 */
+}
+
+void IX86_OPS::PREFIX186(_enter)() /* Opcode 0xc8 */
+{
+ unsigned nb = FETCH;
+ unsigned i,level;
+ UINT16 fp;
+
+ nb += FETCH << 8;
+#ifdef I80286
+ level = FETCH & 0x1f;
+ if(PM) i80286_check_permission(SS, cpustate->regs.w[SP]-2-(level*2), 2+(level*2), I80286_WRITE);
+#else
+ level = FETCH;
+#endif
+ ICOUNT -= (level == 0) ? timing.enter0 : (level == 1) ? timing.enter1 : timing.enter_base + level * timing.enter_count;
+ PUSH(cpustate->regs.w[BP]);
+ fp = cpustate->regs.w[SP];
+ for (i=1;i<level;i++)
+ PUSH(GetMemW(SS,cpustate->regs.w[BP]-i*2));
+ if (level) PUSH(fp);
+ cpustate->regs.w[BP] = fp;
+ cpustate->regs.w[SP] -= nb;
+}
+
+// 98086
+void IX86_OPS::PREFIX86(_trap)()
+{
+ PREFIX(_instruction)[FETCHOP]();
+ PREFIX(_interrupt)(1);
+}
+
+
+void IX86_OPS::PREFIX86(_rotate_shift_Byte)(unsigned ModRM, unsigned count, unsigned src)
+{
+// unsigned src = (unsigned)GetRMByte(ModRM);
+ unsigned dst=src;
+
+ if (count==0)
+ {
+ ICOUNT -= (ModRM >= 0xc0) ? timing.rot_reg_base : timing.rot_m8_base;
+ }
+ else if (count==1)
+ {
+ ICOUNT -= (ModRM >= 0xc0) ? timing.rot_reg_1 : timing.rot_m8_1;
+
+ switch (ModRM & 0x38)
+ {
+ case 0x00: /* ROL eb,1 */
+ cpustate->CarryVal = src & 0x80;
+ dst=(src<<1)+CF;
+ PutbackRMByte(ModRM,dst);
+ cpustate->OverVal = (src^dst)&0x80;
+ break;
+ case 0x08: /* ROR eb,1 */
+ cpustate->CarryVal = src & 0x01;
+ dst = ((CF<<8)+src) >> 1;
+ PutbackRMByte(ModRM,dst);
+ cpustate->OverVal = (src^dst)&0x80;
+ break;
+ case 0x10: /* RCL eb,1 */
+ dst=(src<<1)+CF;
+ PutbackRMByte(ModRM,dst);
+ SetCFB(dst);
+ cpustate->OverVal = (src^dst)&0x80;
+ break;
+ case 0x18: /* RCR eb,1 */
+ dst = ((CF<<8)+src) >> 1;
+ PutbackRMByte(ModRM,dst);
+ cpustate->CarryVal = src & 0x01;
+ cpustate->OverVal = (src^dst)&0x80;
+ break;
+ case 0x20: /* SHL eb,1 */
+ case 0x30:
+ dst = src << 1;
+ PutbackRMByte(ModRM,dst);
+ SetCFB(dst);
+ cpustate->OverVal = (src^dst)&0x80;
+ cpustate->AuxVal = 1;
+ SetSZPF_Byte(dst);
+ break;
+ case 0x28: /* SHR eb,1 */
+ dst = src >> 1;
+ PutbackRMByte(ModRM,dst);
+ cpustate->CarryVal = src & 0x01;
+ cpustate->OverVal = src & 0x80;
+ cpustate->AuxVal = 1;
+ SetSZPF_Byte(dst);
+ break;
+ case 0x38: /* SAR eb,1 */
+ dst = ((INT8)src) >> 1;
+ PutbackRMByte(ModRM,dst);
+ cpustate->CarryVal = src & 0x01;
+ cpustate->OverVal = 0;
+ cpustate->AuxVal = 1;
+ SetSZPF_Byte(dst);
+ break;
+ }
+ }
+ else
+ {
+ int tmpcf = CF;
+ ICOUNT -= (ModRM >= 0xc0) ? timing.rot_reg_base + (timing.rot_reg_bit * count) : timing.rot_m8_base + (timing.rot_m8_bit * count);
+
+ switch (ModRM & 0x38)
+ {
+ case 0x00: /* ROL eb,count */
+ for (; count > 0; count--)
+ {
+ cpustate->CarryVal = dst & 0x80;
+ dst = (dst << 1) + CF;
+ }
+ PutbackRMByte(ModRM,(BYTE)dst);
+ break;
+ case 0x08: /* ROR eb,count */
+ for (; count > 0; count--)
+ {
+ cpustate->CarryVal = dst & 0x01;
+ dst = (dst >> 1) + (CF << 7);
+ }
+ PutbackRMByte(ModRM,(BYTE)dst);
+ break;
+ case 0x10: /* RCL eb,count */
+ for (; count > 0; count--)
+ {
+ dst = (dst << 1) + tmpcf;
+ tmpcf = (int)((dst & 0x100) != 0);
+ }
+ PutbackRMByte(ModRM,(BYTE)dst);
+ cpustate->CarryVal = tmpcf;
+ break;
+ case 0x18: /* RCR eb,count */
+ for (; count > 0; count--)
+ {
+ dst = (tmpcf<<8)+dst;
+ tmpcf = dst & 0x01;
+ dst >>= 1;
+ }
+ PutbackRMByte(ModRM,(BYTE)dst);
+ cpustate->CarryVal = tmpcf;
+ break;
+ case 0x20:
+ case 0x30: /* SHL eb,count */
+ for(int i=0;i<count;i++) dst<<= 1;
+ SetCFB(dst);
+ cpustate->AuxVal = 1;
+ SetSZPF_Byte(dst);
+ PutbackRMByte(ModRM,(BYTE)dst);
+ break;
+ case 0x28: /* SHR eb,count */
+ for(int i=0;i<count-1;i++) dst>>= 1;
+ cpustate->CarryVal = dst & 0x1;
+ dst >>= 1;
+ SetSZPF_Byte(dst);
+ cpustate->AuxVal = 1;
+ PutbackRMByte(ModRM,(BYTE)dst);
+ break;
+ case 0x38: /* SAR eb,count */
+ for(int i=0;i<count-1;i++) dst = ((INT8)dst) >> 1;
+ cpustate->CarryVal = dst & 0x1;
+ dst = ((INT8)((BYTE)dst)) >> 1;
+ SetSZPF_Byte(dst);
+ cpustate->AuxVal = 1;
+ PutbackRMByte(ModRM,(BYTE)dst);
+ break;
+ }
+ }
+}
+
+void IX86_OPS::PREFIX86(_rotate_shift_Word)(unsigned ModRM, unsigned count, unsigned src)
+{
+// unsigned src = GetRMWord(ModRM);
+ unsigned dst=src;
+
+ if (count==0)
+ {
+ ICOUNT -= (ModRM >= 0xc0) ? timing.rot_reg_base : timing.rot_m16_base;
+ }
+ else if (count==1)
+ {
+ ICOUNT -= (ModRM >= 0xc0) ? timing.rot_reg_1 : timing.rot_m16_1;
+
+ switch (ModRM & 0x38)
+ {
+#if 0
+ case 0x00: /* ROL ew,1 */
+ tmp2 = (tmp << 1) + CF;
+ SetCFW(tmp2);
+ cpustate->OverVal = !(!(tmp & 0x4000)) != CF;
+ PutbackRMWord(ModRM,tmp2);
+ break;
+ case 0x08: /* ROR ew,1 */
+ cpustate->CarryVal = tmp & 0x01;
+ tmp2 = (tmp >> 1) + ((unsigned)CF << 15);
+ cpustate->OverVal = !(!(tmp & 0x8000)) != CF;
+ PutbackRMWord(ModRM,tmp2);
+ break;
+ case 0x10: /* RCL ew,1 */
+ tmp2 = (tmp << 1) + CF;
+ SetCFW(tmp2);
+ cpustate->OverVal = (tmp ^ (tmp << 1)) & 0x8000;
+ PutbackRMWord(ModRM,tmp2);
+ break;
+ case 0x18: /* RCR ew,1 */
+ tmp2 = (tmp >> 1) + ((unsigned)CF << 15);
+ cpustate->OverVal = !(!(tmp & 0x8000)) != CF;
+ cpustate->CarryVal = tmp & 0x01;
+ PutbackRMWord(ModRM,tmp2);
+ break;
+ case 0x20: /* SHL ew,1 */
+ case 0x30:
+ tmp <<= 1;
+
+ SetCFW(tmp);
+ SetOFW_Add(tmp,tmp2,tmp2);
+ cpustate->AuxVal = 1;
+ SetSZPF_Word(tmp);
+
+ PutbackRMWord(ModRM,tmp);
+ break;
+ case 0x28: /* SHR ew,1 */
+ cpustate->CarryVal = tmp & 0x01;
+ cpustate->OverVal = tmp & 0x8000;
+
+ tmp2 = tmp >> 1;
+
+ SetSZPF_Word(tmp2);
+ cpustate->AuxVal = 1;
+ PutbackRMWord(ModRM,tmp2);
+ break;
+ case 0x38: /* SAR ew,1 */
+ cpustate->CarryVal = tmp & 0x01;
+ cpustate->OverVal = 0;
+
+ tmp2 = (tmp >> 1) | (tmp & 0x8000);
+
+ SetSZPF_Word(tmp2);
+ cpustate->AuxVal = 1;
+ PutbackRMWord(ModRM,tmp2);
+ break;
+#else
+ case 0x00: /* ROL ew,1 */
+ cpustate->CarryVal = src & 0x8000;
+ dst=(src<<1)+CF;
+ PutbackRMWord(ModRM,dst);
+ cpustate->OverVal = (src^dst)&0x8000;
+ break;
+ case 0x08: /* ROR ew,1 */
+ cpustate->CarryVal = src & 0x01;
+ dst = ((CF<<16)+src) >> 1;
+ PutbackRMWord(ModRM,dst);
+ cpustate->OverVal = (src^dst)&0x8000;
+ break;
+ case 0x10: /* RCL ew,1 */
+ dst=(src<<1)+CF;
+ PutbackRMWord(ModRM,dst);
+ SetCFW(dst);
+ cpustate->OverVal = (src^dst)&0x8000;
+ break;
+ case 0x18: /* RCR ew,1 */
+ dst = ((CF<<16)+src) >> 1;
+ PutbackRMWord(ModRM,dst);
+ cpustate->CarryVal = src & 0x01;
+ cpustate->OverVal = (src^dst)&0x8000;
+ break;
+ case 0x20: /* SHL ew,1 */
+ case 0x30:
+ dst = src << 1;
+ PutbackRMWord(ModRM,dst);
+ SetCFW(dst);
+ cpustate->OverVal = (src^dst)&0x8000;
+ cpustate->AuxVal = 1;
+ SetSZPF_Word(dst);
+ break;
+ case 0x28: /* SHR ew,1 */
+ dst = src >> 1;
+ PutbackRMWord(ModRM,dst);
+ cpustate->CarryVal = src & 0x01;
+ cpustate->OverVal = src & 0x8000;
+ cpustate->AuxVal = 1;
+ SetSZPF_Word(dst);
+ break;
+ case 0x38: /* SAR ew,1 */
+ dst = ((INT16)src) >> 1;
+ PutbackRMWord(ModRM,dst);
+ cpustate->CarryVal = src & 0x01;
+ cpustate->OverVal = 0;
+ cpustate->AuxVal = 1;
+ SetSZPF_Word(dst);
+ break;
+#endif
+ }
+ }
+ else
+ {
+ int tmpcf = CF;
+ ICOUNT -= (ModRM >= 0xc0) ? timing.rot_reg_base + (timing.rot_reg_bit * count) : timing.rot_m8_base + (timing.rot_m16_bit * count);
+
+ switch (ModRM & 0x38)
+ {
+ case 0x00: /* ROL ew,count */
+ for (; count > 0; count--)
+ {
+ cpustate->CarryVal = dst & 0x8000;
+ dst = (dst << 1) + CF;
+ }
+ PutbackRMWord(ModRM,dst);
+ break;
+ case 0x08: /* ROR ew,count */
+ for (; count > 0; count--)
+ {
+ cpustate->CarryVal = dst & 0x01;
+ dst = (dst >> 1) + (CF << 15);
+ }
+ PutbackRMWord(ModRM,dst);
+ break;
+ case 0x10: /* RCL ew,count */
+ for (; count > 0; count--)
+ {
+ dst = (dst << 1) + tmpcf;
+ tmpcf = (int)((dst & 0x10000) != 0);
+ }
+ PutbackRMWord(ModRM,dst);
+ cpustate->CarryVal = tmpcf;
+ break;
+ case 0x18: /* RCR ew,count */
+ for (; count > 0; count--)
+ {
+ dst = dst + (tmpcf << 16);
+ tmpcf = dst & 0x01;
+ dst >>= 1;
+ }
+ PutbackRMWord(ModRM,dst);
+ cpustate->CarryVal = tmpcf;
+ break;
+ case 0x20:
+ case 0x30: /* SHL ew,count */
+ for(int i=0;i<count;i++) dst<<= 1;
+ SetCFW(dst);
+ cpustate->AuxVal = 1;
+ SetSZPF_Word(dst);
+ PutbackRMWord(ModRM,dst);
+ break;
+ case 0x28: /* SHR ew,count */
+ for(int i=0;i<count-1;i++) dst>>= 1;
+ cpustate->CarryVal = dst & 0x1;
+ dst >>= 1;
+ SetSZPF_Word(dst);
+ cpustate->AuxVal = 1;
+ PutbackRMWord(ModRM,dst);
+ break;
+ case 0x38: /* SAR ew,count */
+ for(int i=0;i<count-1;i++) dst = ((INT16)dst) >> 1;
+ cpustate->CarryVal = dst & 0x01;
+ dst = ((INT16)((WORD)dst)) >> 1;
+ SetSZPF_Word(dst);
+ cpustate->AuxVal = 1;
+ PutbackRMWord(ModRM,dst);
+ break;
+ }
+ }
+}
+
+void IX86_OPS::PREFIX86(_pop_ds)(i8086_state *cpustate) /* Opcode 0x1f */
+{
+#ifdef I80286
+ i80286_pop_seg(cpustate,DS);
+#else
+ POP(cpustate->sregs[DS]);
+ cpustate->base[DS] = SegBase(DS);
+#endif
+ ICOUNT -= timing.push_seg;
+}
+
+
+void IX86_OPS::PREFIX(rep)(int flagval)
+{
+ /* Handles rep- and repnz- prefixes. flagval is the value of ZF for the
+ loop to continue for CMPS and SCAS instructions. */
+
+ unsigned next = FETCHOP;
+
+ switch(next)
+ {
+ case 0x26: /* ES: */
+ cpustate->seg_prefix = TRUE;
+ cpustate->prefix_seg = ES;
+ if (!cpustate->rep_in_progress)
+ ICOUNT -= timing.override;
+ PREFIX(rep)(cpustate, flagval);
+ break;
+ case 0x2e: /* CS: */
+ cpustate->seg_prefix = TRUE;
+ cpustate->prefix_seg = CS;
+ if (!cpustate->rep_in_progress)
+ ICOUNT -= timing.override;
+ PREFIX(rep)(cpustate, flagval);
+ break;
+ case 0x36: /* SS: */
+ cpustate->seg_prefix = TRUE;
+ cpustate->prefix_seg = SS;
+ if (!cpustate->rep_in_progress)
+ ICOUNT -= timing.override;
+ PREFIX(rep)(cpustate, flagval);
+ break;
+ case 0x3e: /* DS: */
+ cpustate->seg_prefix = TRUE;
+ cpustate->prefix_seg = DS;
+ if (!cpustate->rep_in_progress)
+ ICOUNT -= timing.override;
+ PREFIX(rep)(cpustate, flagval);
+ break;
+#ifndef I8086
+ case 0x6c: /* REP INSB */
+#ifdef I80286
+ if (PM && (CPL>IOPL)) throw TRAP(GENERAL_PROTECTION_FAULT, 0);
+#endif
+ if (!cpustate->rep_in_progress)
+ ICOUNT -= timing.rep_ins8_base;
+ cpustate->rep_in_progress = FALSE;
+ while(cpustate->regs.w[CX])
+ {
+// if (ICOUNT <= 0) { cpustate->pc = cpustate->prevpc; cpustate->rep_in_progress = TRUE; break; }
+ PutMemB(ES,cpustate->regs.w[DI],read_port_byte(cpustate->regs.w[DX]));
+ cpustate->regs.w[CX]--;
+ cpustate->regs.w[DI] += cpustate->DirVal;
+ ICOUNT -= timing.rep_ins8_count;
+ }
+ break;
+ case 0x6d: /* REP INSW */
+#ifdef I80286
+ if (PM && (CPL>IOPL)) throw TRAP(GENERAL_PROTECTION_FAULT, 0);
+#endif
+ if (!cpustate->rep_in_progress)
+ ICOUNT -= timing.rep_ins16_base;
+ cpustate->rep_in_progress = FALSE;
+ while(cpustate->regs.w[CX])
+ {
+// if (ICOUNT <= 0) { cpustate->pc = cpustate->prevpc; cpustate->rep_in_progress = TRUE; break; }
+ PutMemW(ES,cpustate->regs.w[DI],read_port_word(cpustate->regs.w[DX]));
+ cpustate->regs.w[CX]--;
+ cpustate->regs.w[DI] += 2 * cpustate->DirVal;
+ ICOUNT -= timing.rep_ins16_count;
+ }
+ break;
+ case 0x6e: /* REP OUTSB */
+#ifdef I80286
+ if (PM && (CPL>IOPL)) throw TRAP(GENERAL_PROTECTION_FAULT, 0);
+#endif
+ if (!cpustate->rep_in_progress)
+ ICOUNT -= timing.rep_outs8_base;
+ cpustate->rep_in_progress = FALSE;
+ while(cpustate->regs.w[CX])
+ {
+// if (ICOUNT <= 0) { cpustate->pc = cpustate->prevpc; cpustate->rep_in_progress = TRUE; break; }
+ write_port_byte(cpustate->regs.w[DX],GetMemB(DS,cpustate->regs.w[SI]));
+ cpustate->regs.w[CX]--;
+ cpustate->regs.w[SI] += cpustate->DirVal; /* GOL 11/27/01 */
+ ICOUNT -= timing.rep_outs8_count;
+ }
+ break;
+ case 0x6f: /* REP OUTSW */
+#ifdef I80286
+ if (PM && (CPL>IOPL)) throw TRAP(GENERAL_PROTECTION_FAULT, 0);
+#endif
+ if (!cpustate->rep_in_progress)
+ ICOUNT -= timing.rep_outs16_base;
+ cpustate->rep_in_progress = FALSE;
+ while(cpustate->regs.w[CX])
+ {
+// if (ICOUNT <= 0) { cpustate->pc = cpustate->prevpc; cpustate->rep_in_progress = TRUE; break; }
+ write_port_word(cpustate->regs.w[DX],GetMemW(DS,cpustate->regs.w[SI]));
+ cpustate->regs.w[CX]--;
+ cpustate->regs.w[SI] += 2 * cpustate->DirVal; /* GOL 11/27/01 */
+ ICOUNT -= timing.rep_outs16_count;
+ }
+ break;
+#endif
+ case 0xa4: /* REP MOVSB */
+ if (!cpustate->rep_in_progress)
+ ICOUNT -= timing.rep_movs8_base;
+ cpustate->rep_in_progress = FALSE;
+ while(cpustate->regs.w[CX])
+ {
+ BYTE tmp;
+
+// if (ICOUNT <= 0) { cpustate->pc = cpustate->prevpc; cpustate->rep_in_progress = TRUE; break; }
+ tmp = GetMemB(DS,cpustate->regs.w[SI]);
+ PutMemB(ES,cpustate->regs.w[DI], tmp);
+ cpustate->regs.w[CX]--;
+ cpustate->regs.w[DI] += cpustate->DirVal;
+ cpustate->regs.w[SI] += cpustate->DirVal;
+ ICOUNT -= timing.rep_movs8_count;
+ }
+ break;
+ case 0xa5: /* REP MOVSW */
+ if (!cpustate->rep_in_progress)
+ ICOUNT -= timing.rep_movs16_base;
+ cpustate->rep_in_progress = FALSE;
+ while(cpustate->regs.w[CX])
+ {
+ WORD tmp;
+
+// if (ICOUNT <= 0) { cpustate->pc = cpustate->prevpc; cpustate->rep_in_progress = TRUE; break; }
+ tmp = GetMemW(DS,cpustate->regs.w[SI]);
+ PutMemW(ES,cpustate->regs.w[DI], tmp);
+ cpustate->regs.w[CX]--;
+ cpustate->regs.w[DI] += 2 * cpustate->DirVal;
+ cpustate->regs.w[SI] += 2 * cpustate->DirVal;
+ ICOUNT -= timing.rep_movs16_count;
+ }
+ break;
+ case 0xa6: /* REP(N)E CMPSB */
+ if (!cpustate->rep_in_progress)
+ ICOUNT -= timing.rep_cmps8_base;
+ cpustate->rep_in_progress = FALSE;
+ cpustate->ZeroVal = !flagval;
+ while(cpustate->regs.w[CX] && (ZF == flagval))
+ {
+ unsigned dst, src;
+
+// if (ICOUNT <= 0) { cpustate->pc = cpustate->prevpc; cpustate->rep_in_progress = TRUE; break; }
+ dst = GetMemB(ES, cpustate->regs.w[DI]);
+ src = GetMemB(DS, cpustate->regs.w[SI]);
+ SUBB(src,dst); /* opposite of the usual convention */
+ cpustate->regs.w[CX]--;
+ cpustate->regs.w[DI] += cpustate->DirVal;
+ cpustate->regs.w[SI] += cpustate->DirVal;
+ ICOUNT -= timing.rep_cmps8_count;
+ }
+ break;
+ case 0xa7: /* REP(N)E CMPSW */
+ if (!cpustate->rep_in_progress)
+ ICOUNT -= timing.rep_cmps16_base;
+ cpustate->rep_in_progress = FALSE;
+ cpustate->ZeroVal = !flagval;
+ while(cpustate->regs.w[CX] && (ZF == flagval))
+ {
+ unsigned dst, src;
+
+// if (ICOUNT <= 0) { cpustate->pc = cpustate->prevpc; cpustate->rep_in_progress = TRUE; break; }
+ dst = GetMemW(ES, cpustate->regs.w[DI]);
+ src = GetMemW(DS, cpustate->regs.w[SI]);
+ SUBW(src,dst); /* opposite of the usual convention */
+ cpustate->regs.w[CX]--;
+ cpustate->regs.w[DI] += 2 * cpustate->DirVal;
+ cpustate->regs.w[SI] += 2 * cpustate->DirVal;
+ ICOUNT -= timing.rep_cmps16_count;
+ }
+ break;
+ case 0xaa: /* REP STOSB */
+ if (!cpustate->rep_in_progress)
+ ICOUNT -= timing.rep_stos8_base;
+ cpustate->rep_in_progress = FALSE;
+ while(cpustate->regs.w[CX])
+ {
+// if (ICOUNT <= 0) { cpustate->pc = cpustate->prevpc; cpustate->rep_in_progress = TRUE; break; }
+ PutMemB(ES,cpustate->regs.w[DI],cpustate->regs.b[AL]);
+ cpustate->regs.w[CX]--;
+ cpustate->regs.w[DI] += cpustate->DirVal;
+ ICOUNT -= timing.rep_stos8_count;
+ }
+ break;
+ case 0xab: /* REP STOSW */
+ if (!cpustate->rep_in_progress)
+ ICOUNT -= timing.rep_stos16_base;
+ cpustate->rep_in_progress = FALSE;
+ while(cpustate->regs.w[CX])
+ {
+// if (ICOUNT <= 0) { cpustate->pc = cpustate->prevpc; cpustate->rep_in_progress = TRUE; break; }
+ PutMemW(ES,cpustate->regs.w[DI],cpustate->regs.w[AX]);
+ cpustate->regs.w[CX]--;
+ cpustate->regs.w[DI] += 2 * cpustate->DirVal;
+ ICOUNT -= timing.rep_stos16_count;
+ }
+ break;
+ case 0xac: /* REP LODSB */
+ if (!cpustate->rep_in_progress)
+ ICOUNT -= timing.rep_lods8_base;
+ cpustate->rep_in_progress = FALSE;
+ while(cpustate->regs.w[CX])
+ {
+// if (ICOUNT <= 0) { cpustate->pc = cpustate->prevpc; cpustate->rep_in_progress = TRUE; break; }
+ cpustate->regs.b[AL] = GetMemB(DS,cpustate->regs.w[SI]);
+ cpustate->regs.w[CX]--;
+ cpustate->regs.w[SI] += cpustate->DirVal;
+ ICOUNT -= timing.rep_lods8_count;
+ }
+ break;
+ case 0xad: /* REP LODSW */
+ if (!cpustate->rep_in_progress)
+ ICOUNT -= timing.rep_lods16_base;
+ cpustate->rep_in_progress = FALSE;
+ while(cpustate->regs.w[CX])
+ {
+// if (ICOUNT <= 0) { cpustate->pc = cpustate->prevpc; cpustate->rep_in_progress = TRUE; break; }
+ cpustate->regs.w[AX] = GetMemW(DS,cpustate->regs.w[SI]);
+ cpustate->regs.w[CX]--;
+ cpustate->regs.w[SI] += 2 * cpustate->DirVal;
+ ICOUNT -= timing.rep_lods16_count;
+ }
+ break;
+ case 0xae: /* REP(N)E SCASB */
+ if (!cpustate->rep_in_progress)
+ ICOUNT -= timing.rep_scas8_base;
+ cpustate->rep_in_progress = FALSE;
+ cpustate->ZeroVal = !flagval;
+ while(cpustate->regs.w[CX] && (ZF == flagval))
+ {
+ unsigned src, dst;
+
+// if (ICOUNT <= 0) { cpustate->pc = cpustate->prevpc; cpustate->rep_in_progress = TRUE; break; }
+ src = GetMemB(ES, cpustate->regs.w[DI]);
+ dst = cpustate->regs.b[AL];
+ SUBB(dst,src);
+ cpustate->regs.w[CX]--;
+ cpustate->regs.w[DI] += cpustate->DirVal;
+ ICOUNT -= timing.rep_scas8_count;
+ }
+ break;
+ case 0xaf: /* REP(N)E SCASW */
+ if (!cpustate->rep_in_progress)
+ ICOUNT -= timing.rep_scas16_base;
+ cpustate->rep_in_progress = FALSE;
+ cpustate->ZeroVal = !flagval;
+ while(cpustate->regs.w[CX] && (ZF == flagval))
+ {
+ unsigned src, dst;
+
+// if (ICOUNT <= 0) { cpustate->pc = cpustate->prevpc; cpustate->rep_in_progress = TRUE; break; }
+ src = GetMemW(ES, cpustate->regs.w[DI]);
+ dst = cpustate->regs.w[AX];
+ SUBW(dst,src);
+ cpustate->regs.w[CX]--;
+ cpustate->regs.w[DI] += 2 * cpustate->DirVal;
+ ICOUNT -= timing.rep_scas16_count;
+ }
+ break;
+ default:
+ PREFIX(_instruction)[next](cpustate);
+ }
+}
+
+
+void IX86_OPS::PREFIX86(_pop_es)() /* Opcode 0x07 */
+{
+#ifdef I80286
+ i80286_pop_seg(cpustate,ES);
+#else
+ POP(cpustate->sregs[ES]);
+ cpustate->base[ES] = SegBase(ES);
+#endif
+ ICOUNT -= timing.pop_seg;
+}
+
+
+void IX86_OPS::PREFIX86(_pop_cs)() /* Opcode 0x0f */
+{
+#ifndef I80286
+ int ip = cpustate->pc - cpustate->base[CS];
+ ICOUNT -= timing.push_seg;
+ POP(cpustate->sregs[CS]);
+ cpustate->base[CS] = SegBase(CS);
+ cpustate->pc = (ip + cpustate->base[CS]) & AMASK;
+ CHANGE_PC(cpustate->pc);
+#endif
+}
+
+void IX86_OPS::PREFIX86(_push_sp)() /* Opcode 0x54 */
+{
+ ICOUNT -= timing.push_r16;
+#ifdef I80286
+ PUSH(cpustate->regs.w[SP]+2);
+#else
+ PUSH(cpustate->regs.w[SP]);
+#endif
+}
+void IX86_OPS_BASE::PREFIX186(_bound)() /* Opcode 0x62 */
+{
+ unsigned ModRM = FETCHOP;
+ int low = (INT16)GetRMWord(ModRM);
+ int high= (INT16)GetnextRMWord;
+ int tmp= (INT16)RegWord(ModRM);
+ if (tmp<low || tmp>high) {
+ cpustate->pc-= (cpustate->seg_prefix ? 3 : 2 );
+ PREFIX(_interrupt)(5);
+ }
+ ICOUNT -= timing.bound;
+}
+
+void IX86_OPS::PREFIX86(_call_far)()
+{
+ unsigned int tmp, tmp2;
+ WORD cs, ip;
+
+ tmp = FETCH;
+ tmp += FETCH << 8;
+
+ tmp2 = FETCH;
+ tmp2 += FETCH << 8;
+
+#ifdef I86_PSEUDO_BIOS
+ if(cpustate->bios != NULL && cpustate->bios->bios_call_i86(((tmp2 << 4) + tmp) & AMASK, cpustate->regs.w, cpustate->sregs, &cpustate->ZeroVal, &cpustate->CarryVal)) {
+ ICOUNT -= timing.call_far;
+ return;
+ }
+#endif
+
+ ip = cpustate->pc - cpustate->base[CS];
+ cs = cpustate->sregs[CS];
+
+#ifdef I80286
+ i80286_code_descriptor(cpustate, tmp2, tmp, 2);
+#else
+ cpustate->sregs[CS] = (WORD)tmp2;
+ cpustate->base[CS] = SegBase(CS);
+ cpustate->pc = (cpustate->base[CS] + (WORD)tmp) & AMASK;
+#endif
+ PUSH(cs);
+ PUSH(ip);
+ ICOUNT -= timing.call_far;
+ CHANGE_PC(cpustate->pc);
+}
+
+void IX86_OPS::PREFIX86(_wait)() /* Opcode 0x9b */
+{
+#ifdef I80286
+ if ((cpustate->msw&0x0a) == 0x0a) throw TRAP(FPU_UNAVAILABLE,-1);
+#endif
+ if (cpustate->test_state)
+ {
+ ICOUNT = 0;
+ cpustate->pc--;
+ }
+ else
+ ICOUNT -= timing.wait;
+}
+
+void IX86_OPS::PREFIX86(_pushf)() /* Opcode 0x9c */
+{
+ unsigned tmp;
+ ICOUNT -= timing.pushf;
+
+ tmp = CompressFlags();
+#ifdef I80286
+ if(!PM) ( tmp &= ~0xf000 );
+#endif
+ PUSH( tmp );
+}
+
+#ifndef I80286
+void IX86_OPS::PREFIX86(_popf)() /* Opcode 0x9d */
+{
+ unsigned tmp;
+ POP(tmp);
+ ICOUNT -= timing.popf;
+
+ ExpandFlags(tmp);
+ cpustate->flags = tmp;
+ cpustate->flags = CompressFlags();
+
+ if (cpustate->TF) PREFIX(_trap)(cpustate);
+
+ /* if the IF is set, and an interrupt is pending, signal an interrupt */
+ if (cpustate->IF && cpustate->irq_state) {
+ PREFIX(_interrupt)(cpustate, (UINT32)-1);
+ cpustate->irq_state = 0;
+ }
+}
+#endif
+
+void IX86_OPS::PREFIX86(_les_dw)() /* Opcode 0xc4 */
+{
+ unsigned ModRM = FETCH;
+ WORD tmp = GetRMWord(ModRM);
+
+#ifdef I80286
+ i80286_data_descriptor(cpustate,ES,GetnextRMWord);
+#else
+ cpustate->sregs[ES] = GetnextRMWord;
+ cpustate->base[ES] = SegBase(ES);
+#endif
+ RegWord(ModRM)= tmp;
+ ICOUNT -= timing.load_ptr;
+}
+
+void IX86_OPS::PREFIX86(_lds_dw)() /* Opcode 0xc5 */
+{
+ unsigned ModRM = FETCH;
+ WORD tmp = GetRMWord(ModRM);
+
+#ifdef I80286
+ i80286_data_descriptor(cpustate,DS,GetnextRMWord);
+#else
+ cpustate->sregs[DS] = GetnextRMWord;
+ cpustate->base[DS] = SegBase(DS);
+#endif
+ RegWord(ModRM)=tmp;
+ ICOUNT -= timing.load_ptr;
+}
+
+#ifndef I80286
+void IX86_OPS::PREFIX86(_retf_d16)() /* Opcode 0xca */
+{
+ unsigned count = FETCH;
+ count += FETCH << 8;
+
+ POP(cpustate->pc);
+ POP(cpustate->sregs[CS]);
+ cpustate->base[CS] = SegBase(CS);
+ cpustate->pc = (cpustate->pc + cpustate->base[CS]) & AMASK;
+ cpustate->regs.w[SP]+=count;
+ ICOUNT -= timing.ret_far_imm;
+ CHANGE_PC(cpustate->pc);
+}
+
+void IX86_OPS::PREFIX86(_retf)() /* Opcode 0xcb */
+{
+ POP(cpustate->pc);
+ POP(cpustate->sregs[CS]);
+ cpustate->base[CS] = SegBase(CS);
+ cpustate->pc = (cpustate->pc + cpustate->base[CS]) & AMASK;
+ ICOUNT -= timing.ret_far;
+ CHANGE_PC(cpustate->pc);
+}
+#endif
+
+void IX86_OPS::PREFIX86(_int)() /* Opcode 0xcd */
+{
+ unsigned int_num = FETCH;
+ ICOUNT -= timing.int_imm;
+#ifdef I86_PSEUDO_BIOS
+ if(cpustate->bios != NULL && cpustate->bios->bios_int_i86(int_num, cpustate->regs.w, cpustate->sregs, &cpustate->ZeroVal, &cpustate->CarryVal)) {
+ return;
+ }
+#endif
+ PREFIX(_interrupt)(cpustate, int_num);
+}
+
+#ifndef I80286
+void IX86_OPS::PREFIX86(_iret)(i8086_state *cpustate) /* Opcode 0xcf */
+{
+ ICOUNT -= timing.iret;
+ POP(cpustate->pc);
+ POP(cpustate->sregs[CS]);
+ cpustate->base[CS] = SegBase(CS);
+ cpustate->pc = (cpustate->pc + cpustate->base[CS]) & AMASK;
+ PREFIX(_popf)(cpustate);
+ CHANGE_PC(cpustate->pc);
+
+ /* if the IF is set, and an interrupt is pending, signal an interrupt */
+ if (cpustate->IF && cpustate->irq_state) {
+ PREFIX(_interrupt)(cpustate, (UINT32)-1);
+ cpustate->irq_state = 0;
+ }
+}
+#endif
+
+void IX86_BASE::PREFIX86(_rotshft_b)() /* Opcode 0xd0 */
+{
+ unsigned ModRM = FETCHOP;
+ PREFIX(_rotate_shift_Byte)(cpustate,ModRM,1,GetRMByte(ModRM));
+}
+
+void IX86_BASE::PREFIX86(_rotshft_w)() /* Opcode 0xd1 */
+{
+ unsigned ModRM = FETCHOP;
+ PREFIX(_rotate_shift_Word)(cpustate,ModRM,1,GetRMWord(ModRM));
+}
+
+#ifdef I8086
+void IX86_OPS::PREFIX86(_rotshft_bcl)() /* Opcode 0xd2 */
+{
+ unsigned ModRM = FETCHOP;
+ PREFIX(_rotate_shift_Byte)(cpustate,ModRM,cpustate->regs.b[CL],GetRMByte(ModRM));
+}
+
+void IX86_OPS::PREFIX86(_rotshft_wcl)() /* Opcode 0xd3 */
+{
+ unsigned ModRM = FETCHOP;
+ PREFIX(_rotate_shift_Word)(cpustate,ModRM,cpustate->regs.b[CL],GetRMWord(ModRM));
+}
+#endif
+/* OB: Opcode works on NEC V-Series but not the Variants */
+/* one could specify any byte value as operand but the NECs */
+/* always substitute 0x0a. */
+void IX86_BASE::PREFIX86(_aam)() /* Opcode 0xd4 */
+{
+ unsigned mult = FETCH;
+
+ ICOUNT -= timing.aam;
+ if (mult == 0)
+ PREFIX(_interrupt)(cpustate, 0);
+ else
+ {
+ cpustate->regs.b[AH] = cpustate->regs.b[AL] / mult;
+ cpustate->regs.b[AL] %= mult;
+
+ SetSZPF_Word(cpustate->regs.w[AX]);
+ }
+}
+
+#ifndef I80286
+void IX86_OPS::PREFIX86(_escape)() /* Opcodes 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde and 0xdf */
+{
+ unsigned ModRM = FETCH;
+ ICOUNT -= timing.nop;
+ GetRMByte(ModRM);
+}
+#endif
+
+void IX86_OPS::PREFIX86(_inal)() /* Opcode 0xe4 */
+{
+ unsigned port;
+#ifdef I80286
+ if (PM && (CPL>IOPL)) throw TRAP(GENERAL_PROTECTION_FAULT, 0);
+#endif
+ port = FETCH;
+
+ ICOUNT -= timing.in_imm8;
+ cpustate->regs.b[AL] = read_port_byte(port);
+}
+
+void IX86_OPS::PREFIX86(_inax)() /* Opcode 0xe5 */
+{
+ unsigned port;
+#ifdef I80286
+ if (PM && (CPL>IOPL)) throw TRAP(GENERAL_PROTECTION_FAULT, 0);
+#endif
+ port = FETCH;
+
+ ICOUNT -= timing.in_imm16;
+ cpustate->regs.w[AX] = read_port_word(port);
+}
+
+void IX86_OPS::PREFIX86(_outal)() /* Opcode 0xe6 */
+{
+ unsigned port;
+#ifdef I80286
+ if (PM && (CPL>IOPL)) throw TRAP(GENERAL_PROTECTION_FAULT, 0);
+#endif
+ port = FETCH;
+
+ ICOUNT -= timing.out_imm8;
+ write_port_byte(port, cpustate->regs.b[AL]);
+}
+
+void IX86_OPS::PREFIX86(_outax)() /* Opcode 0xe7 */
+{
+ unsigned port;
+#ifdef I80286
+ if (PM && (CPL>IOPL)) throw TRAP(GENERAL_PROTECTION_FAULT, 0);
+#endif
+ port = FETCH;
+
+ ICOUNT -= timing.out_imm16;
+ write_port_word(port, cpustate->regs.w[AX]);
+}
+
+void IX86_OPS::PREFIX86(_call_d16)() /* Opcode 0xe8 */
+{
+ WORD ip, tmp;
+
+ FETCHWORD(tmp);
+#ifdef I86_PSEUDO_BIOS
+ if(cpustate->bios != NULL && cpustate->bios->bios_call_i86((cpustate->pc + tmp) & AMASK, cpustate->regs.w, cpustate->sregs, &cpustate->ZeroVal, &cpustate->CarryVal)) {
+ ICOUNT -= timing.call_near;
+ return;
+ }
+#endif
+ ip = cpustate->pc - cpustate->base[CS];
+ PUSH(ip);
+ ip += tmp;
+ cpustate->pc = (ip + cpustate->base[CS]) & AMASK;
+ ICOUNT -= timing.call_near;
+ CHANGE_PC(cpustate->pc);
+}
+
+void IX86_OPS::PREFIX86(_jmp_d16)() /* Opcode 0xe9 */
+{
+ WORD ip, tmp;
+
+ FETCHWORD(tmp);
+ ip = cpustate->pc - cpustate->base[CS] + tmp;
+ cpustate->pc = (ip + cpustate->base[CS]) & AMASK;
+ ICOUNT -= timing.jmp_near;
+ CHANGE_PC(cpustate->pc);
+}
+
+void IX86_OPS::PREFIX86(_jmp_far)() /* Opcode 0xea */
+{
+ unsigned tmp,tmp1;
+
+ tmp = FETCH;
+ tmp += FETCH << 8;
+
+ tmp1 = FETCH;
+ tmp1 += FETCH << 8;
+
+#ifdef I80286
+ i80286_code_descriptor(cpustate, tmp1,tmp, 1);
+#else
+ cpustate->sregs[CS] = (WORD)tmp1;
+ cpustate->base[CS] = SegBase(CS);
+ cpustate->pc = (cpustate->base[CS] + tmp) & AMASK;
+#endif
+ ICOUNT -= timing.jmp_far;
+ CHANGE_PC(cpustate->pc);
+}
+
+void IX86_OPS::PREFIX86(_jmp_d8)() /* Opcode 0xeb */
+{
+ int tmp = (int)((INT8)FETCH);
+ cpustate->pc += tmp;
+/* ASG - can probably assume this is safe
+ CHANGE_PC(cpustate->pc);*/
+ ICOUNT -= timing.jmp_short;
+}
+void IX86_OPS::PREFIX86(_inaldx)() /* Opcode 0xec */
+{
+#ifdef I80286
+ if (PM && (CPL>IOPL)) throw TRAP(GENERAL_PROTECTION_FAULT, 0);
+#endif
+ ICOUNT -= timing.in_dx8;
+ cpustate->regs.b[AL] = read_port_byte(cpustate->regs.w[DX]);
+}
+
+void IX86_OPS::PREFIX86(_inaxdx)() /* Opcode 0xed */
+{
+ unsigned port = cpustate->regs.w[DX];
+#ifdef I80286
+ if (PM && (CPL>IOPL)) throw TRAP(GENERAL_PROTECTION_FAULT, 0);
+#endif
+ ICOUNT -= timing.in_dx16;
+ cpustate->regs.w[AX] = read_port_word(port);
+}
+
+void IX86_OPS::PREFIX86(_outdxal)() /* Opcode 0xee */
+{
+#ifdef I80286
+ if (PM && (CPL>IOPL)) throw TRAP(GENERAL_PROTECTION_FAULT, 0);
+#endif
+ ICOUNT -= timing.out_dx8;
+ write_port_byte(cpustate->regs.w[DX], cpustate->regs.b[AL]);
+}
+
+void IX86_OPS::PREFIX86(_outdxax)() /* Opcode 0xef */
+{
+ unsigned port = cpustate->regs.w[DX];
+#ifdef I80286
+ if (PM && (CPL>IOPL)) throw TRAP(GENERAL_PROTECTION_FAULT, 0);
+#endif
+ ICOUNT -= timing.out_dx16;
+ write_port_word(port, cpustate->regs.w[AX]);
+}
+
+
+/* I think thats not a V20 instruction...*/
+void IX86_OPS::PREFIX86(_lock)() /* Opcode 0xf0 */
+{
+#ifdef I80286
+ if(PM && (CPL>IOPL)) throw TRAP(GENERAL_PROTECTION_FAULT,0);
+#endif
+ ICOUNT -= timing.nop;
+ PREFIX(_instruction)[FETCHOP](); /* un-interruptible */
+}
+
+void IX86_OPS::PREFIX(_pop_ss)() /* Opcode 0x17 */
+{
+#ifdef I80286
+ i80286_pop_seg(cpustate, SS);
+#else
+ POP(cpustate->sregs[SS]);
+ cpustate->base[SS] = SegBase(SS);
+#endif
+ ICOUNT -= timing.pop_seg;
+ PREFIX(_instruction)[FETCHOP](cpustate); /* no interrupt before next instruction */
+}
+
+void IX86_OPS::PREFIX(_mov_sregw)() /* Opcode 0x8e */
+{
+ unsigned ModRM = FETCH;
+ WORD src = GetRMWord(ModRM);
+
+ ICOUNT -= (ModRM >= 0xc0) ? timing.mov_sr : timing.mov_sm;
+#ifdef I80286
+ switch (ModRM & 0x38)
+ {
+ case 0x00: /* mov es,ew */
+ i80286_data_descriptor(cpustate,ES,src);
+ break;
+ case 0x18: /* mov ds,ew */
+ i80286_data_descriptor(cpustate,DS,src);
+ break;
+ case 0x10: /* mov ss,ew */
+ i80286_data_descriptor(cpustate,SS,src);
+ cpustate->seg_prefix = FALSE;
+ PREFIX(_instruction)[FETCHOP](cpustate);
+ break;
+ case 0x08: /* mov cs,ew */
+ PREFIX(_invalid)(cpustate);
+ break; /* doesn't do a jump far */
+ }
+#else
+ switch (ModRM & 0x38)
+ {
+ case 0x00: /* mov es,ew */
+ cpustate->sregs[ES] = src;
+ cpustate->base[ES] = SegBase(ES);
+ break;
+ case 0x18: /* mov ds,ew */
+ cpustate->sregs[DS] = src;
+ cpustate->base[DS] = SegBase(DS);
+ break;
+ case 0x10: /* mov ss,ew */
+ cpustate->sregs[SS] = src;
+ cpustate->base[SS] = SegBase(SS); /* no interrupt allowed before next instr */
+ cpustate->seg_prefix = FALSE;
+ PREFIX(_instruction)[FETCHOP](cpustate);
+ break;
+ case 0x08: /* mov cs,ew */
+#ifndef I80186
+ int ip = cpustate->pc - cpustate->base[CS];
+ cpustate->sregs[CS] = src;
+ cpustate->base[CS] = SegBase(CS);
+ cpustate->pc = (ip + cpustate->base[CS]) & AMASK;
+ CHANGE_PC(cpustate->pc);
+#endif
+ break;
+ }
+#endif
+}
+void IX86_OPS::PREFIX(_sti)() /* Opcode 0xfb */
+{
+#ifdef I80286
+ if(PM && (CPL>IOPL)) throw TRAP(GENERAL_PROTECTION_FAULT,0);
+#endif
+ ICOUNT -= timing.flag_ops;
+ SetIF(1);
+ PREFIX(_instruction)[FETCHOP](cpustate); /* no interrupt before next instruction */
+
+ /* if an interrupt is pending, signal an interrupt */
+ if (cpustate->irq_state) {
+#ifdef I80286
+ i80286_interrupt_descriptor(cpustate, cpustate->pic->get_intr_ack(), 2, -1);
+#else
+ PREFIX86(_interrupt)(cpustate, (UINT32)-1);
+#endif
+ cpustate->irq_state = 0;
+ }
+}
+
+//#ifndef I80186
+void IX86_OPS::PREFIX86(_hlt)() /* Opcode 0xf4 */
+{
+#ifdef I80286
+ if(PM && (CPL!=0)) throw TRAP(GENERAL_PROTECTION_FAULT,0);
+#endif
+ cpustate->halted=1;
+ ICOUNT = 0;
+}
+
+void IX86_OPS::PREFIX86(_cli)() /* Opcode 0xfa */
+{
+#ifdef I80286
+ if(PM && (CPL>IOPL)) throw TRAP(GENERAL_PROTECTION_FAULT,0);
+#endif
+ ICOUNT -= timing.flag_ops;
+ SetIF(0);
+}
+
+void IX86_OPS::PREFIX86(_ffpre)() /* Opcode 0xff */
+{
+ unsigned ModRM = FETCHOP;
+ unsigned tmp;
+ unsigned tmp1, tmp2;
+ WORD ip;
+
+ switch(ModRM & 0x38)
+ {
+ case 0x00: /* INC ew */
+ ICOUNT -= (ModRM >= 0xc0) ? timing.incdec_r16 : timing.incdec_m16;
+ tmp = GetRMWord(ModRM);
+ tmp1 = tmp+1;
+
+ SetOFW_Add(tmp1,tmp,1);
+ SetAF(tmp1,tmp,1);
+ SetSZPF_Word(tmp1);
+
+ PutbackRMWord(ModRM,(WORD)tmp1);
+ break;
+
+ case 0x08: /* DEC ew */
+ ICOUNT -= (ModRM >= 0xc0) ? timing.incdec_r16 : timing.incdec_m16;
+ tmp = GetRMWord(ModRM);
+ tmp1 = tmp-1;
+
+ SetOFW_Sub(tmp1,1,tmp);
+ SetAF(tmp1,tmp,1);
+ SetSZPF_Word(tmp1);
+
+ PutbackRMWord(ModRM,(WORD)tmp1);
+ break;
+
+ case 0x10: /* CALL ew */
+ ICOUNT -= (ModRM >= 0xc0) ? timing.call_r16 : timing.call_m16;
+ tmp = GetRMWord(ModRM);
+#ifdef I86_PSEUDO_BIOS
+ if(cpustate->bios != NULL && cpustate->bios->bios_call_i86((cpustate->base[CS] + (WORD)tmp) & AMASK, cpustate->regs.w, cpustate->sregs, &cpustate->ZeroVal, &cpustate->CarryVal)) {
+ ICOUNT -= timing.call_far;
+ return;
+ }
+#endif
+ ip = cpustate->pc - cpustate->base[CS];
+ PUSH(ip);
+ cpustate->pc = (cpustate->base[CS] + (WORD)tmp) & AMASK;
+ CHANGE_PC(cpustate->pc);
+ break;
+
+ case 0x18: /* CALL FAR ea */
+ ICOUNT -= timing.call_m32;
+ tmp = cpustate->sregs[CS]; /* HJB 12/13/98 need to skip displacements of cpustate->ea */
+ tmp1 = GetRMWord(ModRM);
+ tmp2 = GetnextRMWord;
+#ifdef I86_PSEUDO_BIOS
+ if(cpustate->bios != NULL && cpustate->bios->bios_call_i86(((tmp2 << 4) + tmp1) & AMASK, cpustate->regs.w, cpustate->sregs, &cpustate->ZeroVal, &cpustate->CarryVal)) {
+ return;
+ }
+#endif
+ ip = cpustate->pc - cpustate->base[CS];
+#ifdef I80286
+ i80286_code_descriptor(cpustate, tmp2, tmp1, 2);
+#else
+ cpustate->sregs[CS] = tmp2;
+ cpustate->base[CS] = SegBase(CS);
+ cpustate->pc = (cpustate->base[CS] + tmp1) & AMASK;
+#endif
+ PUSH(tmp);
+ PUSH(ip);
+ CHANGE_PC(cpustate->pc);
+ break;
+
+ case 0x20: /* JMP ea */
+ ICOUNT -= (ModRM >= 0xc0) ? timing.jmp_r16 : timing.jmp_m16;
+ ip = GetRMWord(ModRM);
+ cpustate->pc = (cpustate->base[CS] + ip) & AMASK;
+ CHANGE_PC(cpustate->pc);
+ break;
+
+ case 0x28: /* JMP FAR ea */
+ ICOUNT -= timing.jmp_m32;
+
+#ifdef I80286
+ tmp = GetRMWord(ModRM);
+ i80286_code_descriptor(cpustate, GetnextRMWord, tmp, 1);
+#else
+ cpustate->pc = GetRMWord(ModRM);
+ cpustate->sregs[CS] = GetnextRMWord;
+ cpustate->base[CS] = SegBase(CS);
+ cpustate->pc = (cpustate->pc + cpustate->base[CS]) & AMASK;
+#endif
+ CHANGE_PC(cpustate->pc);
+ break;
+
+ case 0x30: /* PUSH ea */
+ ICOUNT -= (ModRM >= 0xc0) ? timing.push_r16 : timing.push_m16;
+ tmp = GetRMWord(ModRM);
+ PUSH(tmp);
+ break;
+ default:
+ tmp = GetRMWord(ModRM); // 286 doesn't matter but 8086?
+ return PREFIX(_invalid)(cpustate);
+ }
+}
+
+
+void IX86_OPS::PREFIX86(_invalid)()
+{
+ logerror("illegal instruction %.2x at %.5x\n",PEEKBYTE(cpustate->pc-1), cpustate->pc);
+#ifdef I80286
+ throw TRAP(ILLEGAL_INSTRUCTION,-1);
+#else
+ /* i8086/i8088 ignore an invalid opcode. */
+ /* i80186/i80188 probably also ignore an invalid opcode. */
+ ICOUNT -= 10;
+#endif
+}
+
+#ifndef I80286
+void IX86_OPS::PREFIX86(_invalid_2b)()
+{
+ unsigned ModRM = FETCH;
+ GetRMByte(ModRM);
+ logerror("illegal 2 byte instruction %.2x at %.5x\n",PEEKBYTE(cpustate->pc-2), cpustate->pc-2);
+ ICOUNT -= 10;
+}
+#endif
+
+void IX86_BASE::PREFIX(_inc_bx)() /* Opcode 0x43 */
+{
+ IncWordReg(BX);
+}
+
+void IX86_BASE::PREFIX86(_int3)() /* Opcode 0xcc */
+{
+ ICOUNT -= timing.int3;
+ PREFIX(_interrupt)(3);
+}
+
+void IX86_BASE::PREFIX86(_int)() /* Opcode 0xcd */
+{
+ unsigned int_num = FETCH;
+ ICOUNT -= timing.int_imm;
+#ifdef I86_PSEUDO_BIOS
+ if(cpustate->bios != NULL && cpustate->bios->bios_int_i86(int_num, cpustate->regs.w, cpustate->sregs, &cpustate->ZeroVal, &cpustate->CarryVal)) {
+ return;
+ }
+#endif
+ PREFIX(_interrupt)(int_num);
+}
+
+void IX86_OPS::PREFIX86(_into)(i8086_state *cpustate) /* Opcode 0xce */
+{
+ if (OF) {
+ ICOUNT -= timing.into_t;
+ PREFIX(_interrupt)(cpustate, 4);
+ } else ICOUNT -= timing.into_nt;
+}
+
+
+
+#ifndef I80286
+void IX86_BASE::PREFIX86(_iret)() /* Opcode 0xcf */
+{
+ ICOUNT -= timing.iret;
+ POP(cpustate->pc);
+ POP(cpustate->sregs[CS]);
+ cpustate->base[CS] = SegBase(CS);
+ cpustate->pc = (cpustate->pc + cpustate->base[CS]) & AMASK;
+ PREFIX(_popf)(cpustate);
+ CHANGE_PC(cpustate->pc);
+
+ /* if the IF is set, and an interrupt is pending, signal an interrupt */
+ if (cpustate->IF && cpustate->irq_state) {
+ PREFIX(_interrupt)(cpustate, (UINT32)-1);
+ cpustate->irq_state = 0;
+ }
+}
+#endif
+
+
+
+/* I think thats not a V20 instruction...*/
+void IX86_BASE::PREFIX86(_lock)() /* Opcode 0xf0 */
+{
+#ifdef I80286
+ if(PM && (CPL>IOPL)) throw TRAP(GENERAL_PROTECTION_FAULT,0);
+#endif
+ ICOUNT -= timing.nop;
+ PREFIX(_instruction)[FETCHOP](cpustate); /* un-interruptible */
+}
+#endif
+void IX86_BASE::PREFIX(_pop_ss)() /* Opcode 0x17 */
+{
+#ifdef I80286
+ i80286_pop_seg(cpustate, SS);
+#else
+ POP(cpustate->sregs[SS]);
+ cpustate->base[SS] = SegBase(SS);
+#endif
+ ICOUNT -= timing.pop_seg;
+ PREFIX(_instruction)[FETCHOP](cpustate); /* no interrupt before next instruction */
+}
+
+void IX86_BASE::PREFIX(_es)() /* Opcode 0x26 */
+{
+ cpustate->seg_prefix = TRUE;
+ cpustate->prefix_seg = ES;
+ ICOUNT -= timing.override;
+ PREFIX(_instruction)[FETCHOP](cpustate);
+}
+
+void IX86_BASE::PREFIX(_cs)() /* Opcode 0x2e */
+{
+ cpustate->seg_prefix = TRUE;
+ cpustate->prefix_seg = CS;
+ ICOUNT -= timing.override;
+ PREFIX(_instruction)[FETCHOP](cpustate);
+}
+
+void IX86_BASE::PREFIX(_ss)() /* Opcode 0x36 */
+{
+ cpustate->seg_prefix = TRUE;
+ cpustate->prefix_seg = SS;
+ ICOUNT -= timing.override;
+ PREFIX(_instruction)[FETCHOP](cpustate);
+}
+
+void IX86_BASE::PREFIX(_ds)() /* Opcode 0x3e */
+{
+ cpustate->seg_prefix = TRUE;
+ cpustate->prefix_seg = DS;
+ ICOUNT -= timing.override;
+ PREFIX(_instruction)[FETCHOP](cpustate);
+}
+
+void IX86_BASE::PREFIX(_mov_sregw)() /* Opcode 0x8e */
+{
+ unsigned ModRM = FETCH;
+ WORD src = GetRMWord(ModRM);
+
+ ICOUNT -= (ModRM >= 0xc0) ? timing.mov_sr : timing.mov_sm;
+#ifdef I80286
+ switch (ModRM & 0x38)
+ {
+ case 0x00: /* mov es,ew */
+ i80286_data_descriptor(cpustate,ES,src);
+ break;
+ case 0x18: /* mov ds,ew */
+ i80286_data_descriptor(cpustate,DS,src);
+ break;
+ case 0x10: /* mov ss,ew */
+ i80286_data_descriptor(cpustate,SS,src);
+ cpustate->seg_prefix = FALSE;
+ PREFIX(_instruction)[FETCHOP](cpustate);
+ break;
+ case 0x08: /* mov cs,ew */
+ PREFIX(_invalid)(cpustate);
+ break; /* doesn't do a jump far */
+ }
+#else
+ switch (ModRM & 0x38)
+ {
+ case 0x00: /* mov es,ew */
+ cpustate->sregs[ES] = src;
+ cpustate->base[ES] = SegBase(ES);
+ break;
+ case 0x18: /* mov ds,ew */
+ cpustate->sregs[DS] = src;
+ cpustate->base[DS] = SegBase(DS);
+ break;
+ case 0x10: /* mov ss,ew */
+ cpustate->sregs[SS] = src;
+ cpustate->base[SS] = SegBase(SS); /* no interrupt allowed before next instr */
+ cpustate->seg_prefix = FALSE;
+ PREFIX(_instruction)[FETCHOP](cpustate);
+ break;
+ case 0x08: /* mov cs,ew */
+#ifndef I80186
+ int ip = cpustate->pc - cpustate->base[CS];
+ cpustate->sregs[CS] = src;
+ cpustate->base[CS] = SegBase(CS);
+ cpustate->pc = (ip + cpustate->base[CS]) & AMASK;
+ CHANGE_PC(cpustate->pc);
+#endif
+ break;
+ }
+#endif
+}
+
+void IX86_BASE::PREFIX(_repne)() /* Opcode 0xf2 */
+{
+ PREFIX(rep)(0);
+}
+
+void IX86_BASE::PREFIX(_repe)() /* Opcode 0xf3 */
+{
+ PREFIX(rep)(1);
+}
+
+void IX86_BASE::PREFIX(_sti)() /* Opcode 0xfb */
+{
+#ifdef I80286
+ if(PM && (CPL>IOPL)) throw TRAP(GENERAL_PROTECTION_FAULT,0);
+#endif
+ ICOUNT -= timing.flag_ops;
+ SetIF(1);
+ PREFIX(_instruction)[FETCHOP](cpustate); /* no interrupt before next instruction */
+
+ /* if an interrupt is pending, signal an interrupt */
+ if (cpustate->irq_state) {
+#ifdef I80286
+ i80286_interrupt_descriptor(cpustate, cpustate->pic->get_intr_ack(), 2, -1);
+#else
+ PREFIX86(_interrupt)(cpustate, (UINT32)-1);
+#endif
+ cpustate->irq_state = 0;
+ }
+}
+void IX86_BASE::PREFIX86(_hlt)() /* Opcode 0xf4 */
+{
+#ifdef I80286
+ if(PM && (CPL!=0)) throw TRAP(GENERAL_PROTECTION_FAULT,0);
+#endif
+ cpustate->halted=1;
+ ICOUNT = 0;
+}
+
+void IX86_BASE::PREFIX86(_f6pre)()
+{
+ /* Opcode 0xf6 */
+ unsigned ModRM = FETCH;
+ unsigned tmp = (unsigned)GetRMByte(ModRM);
+ unsigned tmp2;
+
+
+ switch (ModRM & 0x38)
+ {
+ case 0x00: /* TEST Eb, data8 */
+ case 0x08: /* ??? */
+ ICOUNT -= (ModRM >= 0xc0) ? timing.alu_ri8 : timing.alu_mi8_ro;
+ tmp &= FETCH;
+
+ cpustate->CarryVal = cpustate->OverVal = cpustate->AuxVal = 0;
+ SetSZPF_Byte(tmp);
+ break;
+
+ case 0x10: /* NOT Eb */
+ ICOUNT -= (ModRM >= 0xc0) ? timing.negnot_r8 : timing.negnot_m8;
+ PutbackRMByte(ModRM,~tmp);
+ break;
+
+ case 0x18: /* NEG Eb */
+ ICOUNT -= (ModRM >= 0xc0) ? timing.negnot_r8 : timing.negnot_m8;
+ tmp2=0;
+ SUBB(tmp2,tmp);
+ PutbackRMByte(ModRM,tmp2);
+ break;
+ case 0x20: /* MUL AL, Eb */
+ ICOUNT -= (ModRM >= 0xc0) ? timing.mul_r8 : timing.mul_m8;
+ {
+ UINT16 result;
+ tmp2 = cpustate->regs.b[AL];
+
+ SetSF((INT8)tmp2);
+ SetPF(tmp2);
+
+ result = (UINT16)tmp2*tmp;
+ cpustate->regs.w[AX]=(WORD)result;
+
+ SetZF(cpustate->regs.w[AX]);
+ cpustate->CarryVal = cpustate->OverVal = (cpustate->regs.b[AH] != 0);
+ }
+ break;
+ case 0x28: /* IMUL AL, Eb */
+ ICOUNT -= (ModRM >= 0xc0) ? timing.imul_r8 : timing.imul_m8;
+ {
+ INT16 result;
+
+ tmp2 = (unsigned)cpustate->regs.b[AL];
+
+ SetSF((INT8)tmp2);
+ SetPF(tmp2);
+
+ result = (INT16)((INT8)tmp2)*(INT16)((INT8)tmp);
+ cpustate->regs.w[AX]=(WORD)result;
+
+ SetZF(cpustate->regs.w[AX]);
+
+ cpustate->CarryVal = cpustate->OverVal = (result >> 7 != 0) && (result >> 7 != -1);
+ }
+ break;
+ case 0x30: /* DIV AL, Ew */
+ ICOUNT -= (ModRM >= 0xc0) ? timing.div_r8 : timing.div_m8;
+ {
+ UINT16 result;
+
+ result = cpustate->regs.w[AX];
+
+ if (tmp)
+ {
+ if ((result / tmp) > 0xff)
+ {
+ PREFIX(_interrupt)(cpustate, 0);
+ break;
+ }
+ else
+ {
+ cpustate->regs.b[AH] = result % tmp;
+ cpustate->regs.b[AL] = result / tmp;
+ }
+ }
+ else
+ {
+ PREFIX(_interrupt)(cpustate, 0);
+ break;
+ }
+ }
+ break;
+ case 0x38: /* IDIV AL, Ew */
+ ICOUNT -= (ModRM >= 0xc0) ? timing.idiv_r8 : timing.idiv_m8;
+ {
+
+ INT16 result;
+
+ result = cpustate->regs.w[AX];
+
+ if (tmp)
+ {
+ tmp2 = result % (INT16)((INT8)tmp);
+
+ if ((result /= (INT16)((INT8)tmp)) > 0xff)
+ {
+ PREFIX(_interrupt)(cpustate, 0);
+ break;
+ }
+ else
+ {
+ cpustate->regs.b[AL] = result;
+ cpustate->regs.b[AH] = tmp2;
+ }
+ }
+ else
+ {
+ PREFIX(_interrupt)(cpustate, 0);
+ break;
+ }
+ }
+ break;
+ }
+}
+
+
+void IX86_BASE::PREFIX86(_f7pre)()
+{
+ /* Opcode 0xf7 */
+ unsigned ModRM = FETCH;
+ unsigned tmp = GetRMWord(ModRM);
+ unsigned tmp2;
+
+
+ switch (ModRM & 0x38)
+ {
+ case 0x00: /* TEST Ew, data16 */
+ case 0x08: /* ??? */
+ ICOUNT -= (ModRM >= 0xc0) ? timing.alu_ri16 : timing.alu_mi16_ro;
+ tmp2 = FETCH;
+ tmp2 += FETCH << 8;
+
+ tmp &= tmp2;
+
+ cpustate->CarryVal = cpustate->OverVal = cpustate->AuxVal = 0;
+ SetSZPF_Word(tmp);
+ break;
+
+ case 0x10: /* NOT Ew */
+ ICOUNT -= (ModRM >= 0xc0) ? timing.negnot_r16 : timing.negnot_m16;
+ tmp = ~tmp;
+ PutbackRMWord(ModRM,tmp);
+ break;
+
+ case 0x18: /* NEG Ew */
+ ICOUNT -= (ModRM >= 0xc0) ? timing.negnot_r16 : timing.negnot_m16;
+ tmp2 = 0;
+ SUBW(tmp2,tmp);
+ PutbackRMWord(ModRM,tmp2);
+ break;
+ case 0x20: /* MUL AX, Ew */
+ ICOUNT -= (ModRM >= 0xc0) ? timing.mul_r16 : timing.mul_m16;
+ {
+ UINT32 result;
+ tmp2 = cpustate->regs.w[AX];
+
+ SetSF((INT16)tmp2);
+ SetPF(tmp2);
+
+ result = (UINT32)tmp2*tmp;
+ cpustate->regs.w[AX]=(WORD)result;
+ result >>= 16;
+ cpustate->regs.w[DX]=result;
+
+ SetZF(cpustate->regs.w[AX] | cpustate->regs.w[DX]);
+ cpustate->CarryVal = cpustate->OverVal = (cpustate->regs.w[DX] != 0);
+ }
+ break;
+
+ case 0x28: /* IMUL AX, Ew */
+ ICOUNT -= (ModRM >= 0xc0) ? timing.imul_r16 : timing.imul_m16;
+ {
+ INT32 result;
+
+ tmp2 = cpustate->regs.w[AX];
+
+ SetSF((INT16)tmp2);
+ SetPF(tmp2);
+
+ result = (INT32)((INT16)tmp2)*(INT32)((INT16)tmp);
+ cpustate->CarryVal = cpustate->OverVal = (result >> 15 != 0) && (result >> 15 != -1);
+
+ cpustate->regs.w[AX]=(WORD)result;
+ result = (WORD)(result >> 16);
+ cpustate->regs.w[DX]=result;
+
+ SetZF(cpustate->regs.w[AX] | cpustate->regs.w[DX]);
+ }
+ break;
+ case 0x30: /* DIV AX, Ew */
+ ICOUNT -= (ModRM >= 0xc0) ? timing.div_r16 : timing.div_m16;
+ {
+ UINT32 result;
+
+ result = (cpustate->regs.w[DX] << 16) + cpustate->regs.w[AX];
+
+ if (tmp)
+ {
+ tmp2 = result % tmp;
+ if ((result / tmp) > 0xffff)
+ {
+ PREFIX(_interrupt)(cpustate, 0);
+ break;
+ }
+ else
+ {
+ cpustate->regs.w[DX]=tmp2;
+ result /= tmp;
+ cpustate->regs.w[AX]=result;
+ }
+ }
+ else
+ {
+ PREFIX(_interrupt)(cpustate, 0);
+ break;
+ }
+ }
+ break;
+ case 0x38: /* IDIV AX, Ew */
+ ICOUNT -= (ModRM >= 0xc0) ? timing.idiv_r16 : timing.idiv_m16;
+ {
+ INT32 result;
+
+ result = (cpustate->regs.w[DX] << 16) + cpustate->regs.w[AX];
+
+ if (tmp)
+ {
+ tmp2 = result % (INT32)((INT16)tmp);
+ if ((result /= (INT32)((INT16)tmp)) > 0xffff)
+ {
+ PREFIX(_interrupt)(cpustate, 0);
+ break;
+ }
+ else
+ {
+ cpustate->regs.w[AX]=result;
+ cpustate->regs.w[DX]=tmp2;
+ }
+ }
+ else
+ {
+ PREFIX(_interrupt)(cpustate, 0);
+ break;
+ }
+ }
+ break;
+ }
+}
+
+void IX86_BASE::PREFIX86(_cli)() /* Opcode 0xfa */
+{
+#ifdef I80286
+ if(PM && (CPL>IOPL)) throw TRAP(GENERAL_PROTECTION_FAULT,0);
+#endif
+ ICOUNT -= timing.flag_ops;
+ SetIF(0);
+}
+
+void IX86_BASE::PREFIX86(_ffpre)() /* Opcode 0xff */
+{
+ unsigned ModRM = FETCHOP;
+ unsigned tmp;
+ unsigned tmp1, tmp2;
+ WORD ip;
+
+ switch(ModRM & 0x38)
+ {
+ case 0x00: /* INC ew */
+ ICOUNT -= (ModRM >= 0xc0) ? timing.incdec_r16 : timing.incdec_m16;
+ tmp = GetRMWord(ModRM);
+ tmp1 = tmp+1;
+
+ SetOFW_Add(tmp1,tmp,1);
+ SetAF(tmp1,tmp,1);
+ SetSZPF_Word(tmp1);
+
+ PutbackRMWord(ModRM,(WORD)tmp1);
+ break;
+
+ case 0x08: /* DEC ew */
+ ICOUNT -= (ModRM >= 0xc0) ? timing.incdec_r16 : timing.incdec_m16;
+ tmp = GetRMWord(ModRM);
+ tmp1 = tmp-1;
+
+ SetOFW_Sub(tmp1,1,tmp);
+ SetAF(tmp1,tmp,1);
+ SetSZPF_Word(tmp1);
+
+ PutbackRMWord(ModRM,(WORD)tmp1);
+ break;
+
+ case 0x10: /* CALL ew */
+ ICOUNT -= (ModRM >= 0xc0) ? timing.call_r16 : timing.call_m16;
+ tmp = GetRMWord(ModRM);
+#ifdef I86_PSEUDO_BIOS
+ if(cpustate->bios != NULL && cpustate->bios->bios_call_i86((cpustate->base[CS] + (WORD)tmp) & AMASK, cpustate->regs.w, cpustate->sregs, &cpustate->ZeroVal, &cpustate->CarryVal)) {
+ ICOUNT -= timing.call_far;
+ return;
+ }
+#endif
+ ip = cpustate->pc - cpustate->base[CS];
+ PUSH(ip);
+ cpustate->pc = (cpustate->base[CS] + (WORD)tmp) & AMASK;
+ CHANGE_PC(cpustate->pc);
+ break;
+
+ case 0x18: /* CALL FAR ea */
+ ICOUNT -= timing.call_m32;
+ tmp = cpustate->sregs[CS]; /* HJB 12/13/98 need to skip displacements of cpustate->ea */
+ tmp1 = GetRMWord(ModRM);
+ tmp2 = GetnextRMWord;
+#ifdef I86_PSEUDO_BIOS
+ if(cpustate->bios != NULL && cpustate->bios->bios_call_i86(((tmp2 << 4) + tmp1) & AMASK, cpustate->regs.w, cpustate->sregs, &cpustate->ZeroVal, &cpustate->CarryVal)) {
+ return;
+ }
+#endif
+ ip = cpustate->pc - cpustate->base[CS];
+#ifdef I80286
+ i80286_code_descriptor(cpustate, tmp2, tmp1, 2);
+#else
+ cpustate->sregs[CS] = tmp2;
+ cpustate->base[CS] = SegBase(CS);
+ cpustate->pc = (cpustate->base[CS] + tmp1) & AMASK;
+#endif
+ PUSH(tmp);
+ PUSH(ip);
+ CHANGE_PC(cpustate->pc);
+ break;
+
+ case 0x20: /* JMP ea */
+ ICOUNT -= (ModRM >= 0xc0) ? timing.jmp_r16 : timing.jmp_m16;
+ ip = GetRMWord(ModRM);
+ cpustate->pc = (cpustate->base[CS] + ip) & AMASK;
+ CHANGE_PC(cpustate->pc);
+ break;
+
+ case 0x28: /* JMP FAR ea */
+ ICOUNT -= timing.jmp_m32;
+
+#ifdef I80286
+ tmp = GetRMWord(ModRM);
+ i80286_code_descriptor(cpustate, GetnextRMWord, tmp, 1);
+#else
+ cpustate->pc = GetRMWord(ModRM);
+ cpustate->sregs[CS] = GetnextRMWord;
+ cpustate->base[CS] = SegBase(CS);
+ cpustate->pc = (cpustate->pc + cpustate->base[CS]) & AMASK;
+#endif
+ CHANGE_PC(cpustate->pc);
+ break;
+
+ case 0x30: /* PUSH ea */
+ ICOUNT -= (ModRM >= 0xc0) ? timing.push_r16 : timing.push_m16;
+ tmp = GetRMWord(ModRM);
+ PUSH(tmp);
+ break;
+ default:
+ tmp = GetRMWord(ModRM); // 286 doesn't matter but 8086?
+ return PREFIX(_invalid)(cpustate);
+ }
+}
+
+void IX86_BASE::PREFIX86(_invalid)()
+{
+ logerror("illegal instruction %.2x at %.5x\n",PEEKBYTE(cpustate->pc-1), cpustate->pc);
+#ifdef I80286
+ throw TRAP(ILLEGAL_INSTRUCTION,-1);
+#else
+ /* i8086/i8088 ignore an invalid opcode. */
+ /* i80186/i80188 probably also ignore an invalid opcode. */
+ ICOUNT -= 10;
+#endif
+}
+
+#ifndef I80286
+void IX86_BASE::PREFIX86(_invalid_2b)()
+{
+ unsigned ModRM = FETCH;
+ GetRMByte(ModRM);
+ logerror("illegal 2 byte instruction %.2x at %.5x\n",PEEKBYTE(cpustate->pc-2), cpustate->pc-2);
+ ICOUNT -= 10;
+}
+#endif
+//#endif
--- /dev/null
+#include "./ix86_opdef.h"
+
+#define PREFIX(XXX) PREFIXV30(XXXX)
+
+void IX86_OPS_BASE::PREFIX(_interrupt)(unsigned int_num)
+{
+ unsigned dest_seg, dest_off;
+ WORD ip = cpustate->pc - cpustate->base[CS];
+
+ if (int_num == -1)
+ int_num = cpustate->pic->get_intr_ack();
+
+ dest_off = ReadWord(int_num*4);
+ dest_seg = ReadWord(int_num*4+2);
+
+ PREFIX(_pushf());
+ cpustate->TF = cpustate->IF = 0;
+ PUSH(cpustate->sregs[CS]);
+ PUSH(ip);
+ cpustate->sregs[CS] = (WORD)dest_seg;
+ cpustate->base[CS] = SegBase(CS);
+ cpustate->pc = (cpustate->base[CS] + dest_off) & AMASK;
+ CHANGE_PC(cpustate->pc);
+
+ cpustate->extra_cycles += timing.exception;
+}
+// ??
+void IX86_OPS_BASE::PREFIX(_trap)()
+{
+ PREFIX(_instruction)[FETCHOP]();
+ PREFIX(_interrupt)(1);
+}
+
+void IX86_OPS_BASE::PREFIX(_pushf)() /* Opcode 0x9c */
+{
+ unsigned tmp;
+ ICOUNT -= timing.pushf;
+
+ tmp = CompressFlags();
+ PUSH( tmp );
+}
+
+void IX86_OPS_BASE::PREFIX(rep)(int flagval)
+{
+ /* Handles rep- and repnz- prefixes. flagval is the value of ZF for the
+ loop to continue for CMPS and SCAS instructions. */
+
+ unsigned next = FETCHOP;
+
+ switch(next)
+ {
+ case 0x26: /* ES: */
+ cpustate->seg_prefix = TRUE;
+ cpustate->prefix_seg = ES;
+ if (!cpustate->rep_in_progress)
+ ICOUNT -= timing.override;
+ PREFIX(rep)(flagval);
+ break;
+ case 0x2e: /* CS: */
+ cpustate->seg_prefix = TRUE;
+ cpustate->prefix_seg = CS;
+ if (!cpustate->rep_in_progress)
+ ICOUNT -= timing.override;
+ PREFIX(rep)(flagval);
+ break;
+ case 0x36: /* SS: */
+ cpustate->seg_prefix = TRUE;
+ cpustate->prefix_seg = SS;
+ if (!cpustate->rep_in_progress)
+ ICOUNT -= timing.override;
+ PREFIX(rep)(flagval);
+ break;
+ case 0x3e: /* DS: */
+ cpustate->seg_prefix = TRUE;
+ cpustate->prefix_seg = DS;
+ if (!cpustate->rep_in_progress)
+ ICOUNT -= timing.override;
+ PREFIX(rep)(flagval);
+ break;
+ case 0x6c: /* REP INSB */
+ if (!cpustate->rep_in_progress)
+ ICOUNT -= timing.rep_ins8_base;
+ cpustate->rep_in_progress = FALSE;
+ while(cpustate->regs.w[CX])
+ {
+// if (ICOUNT <= 0) { cpustate->pc = cpustate->prevpc; cpustate->rep_in_progress = TRUE; break; }
+ PutMemB(ES,cpustate->regs.w[DI],read_port_byte(cpustate->regs.w[DX]));
+ cpustate->regs.w[CX]--;
+ cpustate->regs.w[DI] += cpustate->DirVal;
+ ICOUNT -= timing.rep_ins8_count;
+ }
+ break;
+ case 0x6d: /* REP INSW */
+ if (!cpustate->rep_in_progress)
+ ICOUNT -= timing.rep_ins16_base;
+ cpustate->rep_in_progress = FALSE;
+ while(cpustate->regs.w[CX])
+ {
+// if (ICOUNT <= 0) { cpustate->pc = cpustate->prevpc; cpustate->rep_in_progress = TRUE; break; }
+ PutMemW(ES,cpustate->regs.w[DI],read_port_word(cpustate->regs.w[DX]));
+ cpustate->regs.w[CX]--;
+ cpustate->regs.w[DI] += 2 * cpustate->DirVal;
+ ICOUNT -= timing.rep_ins16_count;
+ }
+ break;
+ case 0x6e: /* REP OUTSB */
+ if (!cpustate->rep_in_progress)
+ ICOUNT -= timing.rep_outs8_base;
+ cpustate->rep_in_progress = FALSE;
+ while(cpustate->regs.w[CX])
+ {
+// if (ICOUNT <= 0) { cpustate->pc = cpustate->prevpc; cpustate->rep_in_progress = TRUE; break; }
+ write_port_byte(cpustate->regs.w[DX],GetMemB(DS,cpustate->regs.w[SI]));
+ cpustate->regs.w[CX]--;
+ cpustate->regs.w[SI] += cpustate->DirVal; /* GOL 11/27/01 */
+ ICOUNT -= timing.rep_outs8_count;
+ }
+ break;
+ case 0x6f: /* REP OUTSW */
+ if (!cpustate->rep_in_progress)
+ ICOUNT -= timing.rep_outs16_base;
+ cpustate->rep_in_progress = FALSE;
+ while(cpustate->regs.w[CX])
+ {
+// if (ICOUNT <= 0) { cpustate->pc = cpustate->prevpc; cpustate->rep_in_progress = TRUE; break; }
+ write_port_word(cpustate->regs.w[DX],GetMemW(DS,cpustate->regs.w[SI]));
+ cpustate->regs.w[CX]--;
+ cpustate->regs.w[SI] += 2 * cpustate->DirVal; /* GOL 11/27/01 */
+ ICOUNT -= timing.rep_outs16_count;
+ }
+ break;
+ case 0xa4: /* REP MOVSB */
+ if (!cpustate->rep_in_progress)
+ ICOUNT -= timing.rep_movs8_base;
+ cpustate->rep_in_progress = FALSE;
+ while(cpustate->regs.w[CX])
+ {
+ BYTE tmp;
+
+// if (ICOUNT <= 0) { cpustate->pc = cpustate->prevpc; cpustate->rep_in_progress = TRUE; break; }
+ tmp = GetMemB(DS,cpustate->regs.w[SI]);
+ PutMemB(ES,cpustate->regs.w[DI], tmp);
+ cpustate->regs.w[CX]--;
+ cpustate->regs.w[DI] += cpustate->DirVal;
+ cpustate->regs.w[SI] += cpustate->DirVal;
+ ICOUNT -= timing.rep_movs8_count;
+ }
+ break;
+ case 0xa5: /* REP MOVSW */
+ if (!cpustate->rep_in_progress)
+ ICOUNT -= timing.rep_movs16_base;
+ cpustate->rep_in_progress = FALSE;
+ while(cpustate->regs.w[CX])
+ {
+ WORD tmp;
+
+// if (ICOUNT <= 0) { cpustate->pc = cpustate->prevpc; cpustate->rep_in_progress = TRUE; break; }
+ tmp = GetMemW(DS,cpustate->regs.w[SI]);
+ PutMemW(ES,cpustate->regs.w[DI], tmp);
+ cpustate->regs.w[CX]--;
+ cpustate->regs.w[DI] += 2 * cpustate->DirVal;
+ cpustate->regs.w[SI] += 2 * cpustate->DirVal;
+ ICOUNT -= timing.rep_movs16_count;
+ }
+ break;
+ case 0xa6: /* REP(N)E CMPSB */
+ if (!cpustate->rep_in_progress)
+ ICOUNT -= timing.rep_cmps8_base;
+ cpustate->rep_in_progress = FALSE;
+ cpustate->ZeroVal = !flagval;
+ while(cpustate->regs.w[CX] && (ZF == flagval))
+ {
+ unsigned dst, src;
+
+// if (ICOUNT <= 0) { cpustate->pc = cpustate->prevpc; cpustate->rep_in_progress = TRUE; break; }
+ dst = GetMemB(ES, cpustate->regs.w[DI]);
+ src = GetMemB(DS, cpustate->regs.w[SI]);
+ SUBB(src,dst); /* opposite of the usual convention */
+ cpustate->regs.w[CX]--;
+ cpustate->regs.w[DI] += cpustate->DirVal;
+ cpustate->regs.w[SI] += cpustate->DirVal;
+ ICOUNT -= timing.rep_cmps8_count;
+ }
+ break;
+ case 0xa7: /* REP(N)E CMPSW */
+ if (!cpustate->rep_in_progress)
+ ICOUNT -= timing.rep_cmps16_base;
+ cpustate->rep_in_progress = FALSE;
+ cpustate->ZeroVal = !flagval;
+ while(cpustate->regs.w[CX] && (ZF == flagval))
+ {
+ unsigned dst, src;
+
+// if (ICOUNT <= 0) { cpustate->pc = cpustate->prevpc; cpustate->rep_in_progress = TRUE; break; }
+ dst = GetMemW(ES, cpustate->regs.w[DI]);
+ src = GetMemW(DS, cpustate->regs.w[SI]);
+ SUBW(src,dst); /* opposite of the usual convention */
+ cpustate->regs.w[CX]--;
+ cpustate->regs.w[DI] += 2 * cpustate->DirVal;
+ cpustate->regs.w[SI] += 2 * cpustate->DirVal;
+ ICOUNT -= timing.rep_cmps16_count;
+ }
+ break;
+ case 0xaa: /* REP STOSB */
+ if (!cpustate->rep_in_progress)
+ ICOUNT -= timing.rep_stos8_base;
+ cpustate->rep_in_progress = FALSE;
+ while(cpustate->regs.w[CX])
+ {
+// if (ICOUNT <= 0) { cpustate->pc = cpustate->prevpc; cpustate->rep_in_progress = TRUE; break; }
+ PutMemB(ES,cpustate->regs.w[DI],cpustate->regs.b[AL]);
+ cpustate->regs.w[CX]--;
+ cpustate->regs.w[DI] += cpustate->DirVal;
+ ICOUNT -= timing.rep_stos8_count;
+ }
+ break;
+ case 0xab: /* REP STOSW */
+ if (!cpustate->rep_in_progress)
+ ICOUNT -= timing.rep_stos16_base;
+ cpustate->rep_in_progress = FALSE;
+ while(cpustate->regs.w[CX])
+ {
+// if (ICOUNT <= 0) { cpustate->pc = cpustate->prevpc; cpustate->rep_in_progress = TRUE; break; }
+ PutMemW(ES,cpustate->regs.w[DI],cpustate->regs.w[AX]);
+ cpustate->regs.w[CX]--;
+ cpustate->regs.w[DI] += 2 * cpustate->DirVal;
+ ICOUNT -= timing.rep_stos16_count;
+ }
+ break;
+ case 0xac: /* REP LODSB */
+ if (!cpustate->rep_in_progress)
+ ICOUNT -= timing.rep_lods8_base;
+ cpustate->rep_in_progress = FALSE;
+ while(cpustate->regs.w[CX])
+ {
+// if (ICOUNT <= 0) { cpustate->pc = cpustate->prevpc; cpustate->rep_in_progress = TRUE; break; }
+ cpustate->regs.b[AL] = GetMemB(DS,cpustate->regs.w[SI]);
+ cpustate->regs.w[CX]--;
+ cpustate->regs.w[SI] += cpustate->DirVal;
+ ICOUNT -= timing.rep_lods8_count;
+ }
+ break;
+ case 0xad: /* REP LODSW */
+ if (!cpustate->rep_in_progress)
+ ICOUNT -= timing.rep_lods16_base;
+ cpustate->rep_in_progress = FALSE;
+ while(cpustate->regs.w[CX])
+ {
+// if (ICOUNT <= 0) { cpustate->pc = cpustate->prevpc; cpustate->rep_in_progress = TRUE; break; }
+ cpustate->regs.w[AX] = GetMemW(DS,cpustate->regs.w[SI]);
+ cpustate->regs.w[CX]--;
+ cpustate->regs.w[SI] += 2 * cpustate->DirVal;
+ ICOUNT -= timing.rep_lods16_count;
+ }
+ break;
+ case 0xae: /* REP(N)E SCASB */
+ if (!cpustate->rep_in_progress)
+ ICOUNT -= timing.rep_scas8_base;
+ cpustate->rep_in_progress = FALSE;
+ cpustate->ZeroVal = !flagval;
+ while(cpustate->regs.w[CX] && (ZF == flagval))
+ {
+ unsigned src, dst;
+
+// if (ICOUNT <= 0) { cpustate->pc = cpustate->prevpc; cpustate->rep_in_progress = TRUE; break; }
+ src = GetMemB(ES, cpustate->regs.w[DI]);
+ dst = cpustate->regs.b[AL];
+ SUBB(dst,src);
+ cpustate->regs.w[CX]--;
+ cpustate->regs.w[DI] += cpustate->DirVal;
+ ICOUNT -= timing.rep_scas8_count;
+ }
+ break;
+ case 0xaf: /* REP(N)E SCASW */
+ if (!cpustate->rep_in_progress)
+ ICOUNT -= timing.rep_scas16_base;
+ cpustate->rep_in_progress = FALSE;
+ cpustate->ZeroVal = !flagval;
+ while(cpustate->regs.w[CX] && (ZF == flagval))
+ {
+ unsigned src, dst;
+
+// if (ICOUNT <= 0) { cpustate->pc = cpustate->prevpc; cpustate->rep_in_progress = TRUE; break; }
+ src = GetMemW(ES, cpustate->regs.w[DI]);
+ dst = cpustate->regs.w[AX];
+ SUBW(dst,src);
+ cpustate->regs.w[CX]--;
+ cpustate->regs.w[DI] += 2 * cpustate->DirVal;
+ ICOUNT -= timing.rep_scas16_count;
+ }
+ break;
+ default:
+ PREFIX(_instruction)[next]();
+ }
+}
+
+void IX86_OPS_BASE::PREFIXV30(_0fpre)() /* Opcode 0x0f */
+{
+ static const unsigned bytes[] = {
+ 1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096, 8192, 16384, 32768
+ };
+
+ unsigned Opcode = FETCH;
+ unsigned ModRM;
+ unsigned tmp;
+ unsigned tmp2;
+
+ switch (Opcode)
+ {
+ case 0x10: /* 0F 10 47 30 - TEST1 [bx+30h],cl */
+ ModRM = FETCH;
+ if (ModRM >= 0xc0)
+ {
+ tmp = cpustate->regs.b[Mod_RM.RM.b[ModRM]];
+ ICOUNT -= 3;
+ }
+ else
+ {
+ int old = ICOUNT;
+
+ (void)(*GetEA[ModRM])(cpustate);
+ tmp = ReadByte(cpustate->ea);
+ ICOUNT = old - 12; /* my source says 14 cycles everytime and not
+ * ModRM-dependent like GetEA[] does..hmmm */
+ }
+ tmp2 = cpustate->regs.b[CL] & 0x7;
+ cpustate->ZeroVal = tmp & bytes[tmp2] ? 1 : 0;
+/* SetZF(tmp & (1<<tmp2)); */
+ break;
+
+ case 0x11: /* 0F 11 47 30 - TEST1 [bx+30h],cl */
+ ModRM = FETCH;
+ /* tmp = GetRMWord(ModRM); */
+ if (ModRM >= 0xc0)
+ {
+ tmp = cpustate->regs.w[Mod_RM.RM.w[ModRM]];
+ ICOUNT -= 3;
+ }
+ else
+ {
+ int old = ICOUNT;
+
+ (void)(*GetEA[ModRM])(cpustate);
+ tmp = ReadWord(cpustate->ea);
+ ICOUNT = old - 12; /* my source says 14 cycles everytime and not
+ * ModRM-dependent like GetEA[] does..hmmm */
+ }
+ tmp2 = cpustate->regs.b[CL] & 0xF;
+ cpustate->ZeroVal = tmp & bytes[tmp2] ? 1 : 0;
+/* SetZF(tmp & (1<<tmp2)); */
+ break;
+
+ case 0x12: /* 0F 12 [mod:000:r/m] - CLR1 reg/m8,cl */
+ ModRM = FETCH;
+ /* need the long if due to correct cycles OB[19.07.99] */
+ if (ModRM >= 0xc0)
+ {
+ tmp = cpustate->regs.b[Mod_RM.RM.b[ModRM]];
+ ICOUNT -= 5;
+ }
+ else
+ {
+ int old = ICOUNT;
+
+ (void)(*GetEA[ModRM])(cpustate);
+ tmp = ReadByte(cpustate->ea);
+ ICOUNT = old - 14; /* my source says 14 cycles everytime and not
+ * ModRM-dependent like GetEA[] does..hmmm */
+ }
+ tmp2 = cpustate->regs.b[CL] & 0x7; /* hey its a Byte so &07 NOT &0f */
+ tmp &= ~(bytes[tmp2]);
+ PutbackRMByte(ModRM, tmp);
+ break;
+
+ case 0x13: /* 0F 13 [mod:000:r/m] - CLR1 reg/m16,cl */
+ ModRM = FETCH;
+ /* tmp = GetRMWord(ModRM); */
+ if (ModRM >= 0xc0)
+ {
+ tmp = cpustate->regs.w[Mod_RM.RM.w[ModRM]];
+ ICOUNT -= 5;
+ }
+ else
+ {
+ int old = ICOUNT;
+
+ (void)(*GetEA[ModRM])(cpustate);
+ tmp = ReadWord(cpustate->ea);
+ ICOUNT = old - 14; /* my source says 14 cycles everytime and not
+ * ModRM-dependent like GetEA[] does..hmmm */
+ }
+ tmp2 = cpustate->regs.b[CL] & 0xF; /* this time its a word */
+ tmp &= ~(bytes[tmp2]);
+ PutbackRMWord(ModRM, tmp);
+ break;
+
+ case 0x14: /* 0F 14 47 30 - SET1 [bx+30h],cl */
+ ModRM = FETCH;
+ if (ModRM >= 0xc0)
+ {
+ tmp = cpustate->regs.b[Mod_RM.RM.b[ModRM]];
+ ICOUNT -= 4;
+ }
+ else
+ {
+ int old = ICOUNT;
+
+ (void)(*GetEA[ModRM])(cpustate);
+ tmp = ReadByte(cpustate->ea);
+ ICOUNT = old - 13;
+ }
+ tmp2 = cpustate->regs.b[CL] & 0x7;
+ tmp |= (bytes[tmp2]);
+ PutbackRMByte(ModRM, tmp);
+ break;
+
+ case 0x15: /* 0F 15 C6 - SET1 si,cl */
+ ModRM = FETCH;
+ /* tmp = GetRMWord(ModRM); */
+ if (ModRM >= 0xc0)
+ {
+ tmp = cpustate->regs.w[Mod_RM.RM.w[ModRM]];
+ ICOUNT -= 4;
+ }
+ else
+ {
+ int old = ICOUNT;
+
+ (void)(*GetEA[ModRM])(cpustate);
+ tmp = ReadWord(cpustate->ea);
+ ICOUNT = old - 13;
+ }
+ tmp2 = cpustate->regs.b[CL] & 0xF;
+ tmp |= (bytes[tmp2]);
+ PutbackRMWord(ModRM, tmp);
+ break;
+
+ case 0x16: /* 0F 16 C6 - NOT1 si,cl */
+ ModRM = FETCH;
+ /* need the long if due to correct cycles OB[19.07.99] */
+ if (ModRM >= 0xc0)
+ {
+ tmp = cpustate->regs.b[Mod_RM.RM.b[ModRM]];
+ ICOUNT -= 4;
+ }
+ else
+ {
+ int old = ICOUNT;
+
+ (void)(*GetEA[ModRM])(cpustate);
+ tmp = ReadByte(cpustate->ea);
+ ICOUNT = old - 18; /* my source says 18 cycles everytime and not
+ * ModRM-dependent like GetEA[] does..hmmm */
+ }
+ tmp2 = cpustate->regs.b[CL] & 0x7; /* hey its a Byte so &07 NOT &0f */
+ if (tmp & bytes[tmp2])
+ tmp &= ~(bytes[tmp2]);
+ else
+ tmp |= (bytes[tmp2]);
+ PutbackRMByte(ModRM, tmp);
+ break;
+
+ case 0x17: /* 0F 17 C6 - NOT1 si,cl */
+ ModRM = FETCH;
+ /* tmp = GetRMWord(ModRM); */
+ if (ModRM >= 0xc0)
+ {
+ tmp = cpustate->regs.w[Mod_RM.RM.w[ModRM]];
+ ICOUNT -= 4;
+ }
+ else
+ {
+ int old = ICOUNT;
+
+ (void)(*GetEA[ModRM])(cpustate);
+ tmp = ReadWord(cpustate->ea);
+ ICOUNT = old - 18; /* my source says 14 cycles everytime and not
+ * ModRM-dependent like GetEA[] does..hmmm */
+ }
+ tmp2 = cpustate->regs.b[CL] & 0xF; /* this time its a word */
+ if (tmp & bytes[tmp2])
+ tmp &= ~(bytes[tmp2]);
+ else
+ tmp |= (bytes[tmp2]);
+ PutbackRMWord(ModRM, tmp);
+ break;
+
+ case 0x18: /* 0F 18 XX - TEST1 [bx+30h],07 */
+ ModRM = FETCH;
+ /* tmp = GetRMByte(ModRM); */
+ if (ModRM >= 0xc0)
+ {
+ tmp = cpustate->regs.b[Mod_RM.RM.b[ModRM]];
+ ICOUNT -= 4;
+ }
+ else
+ {
+ int old = ICOUNT;
+
+ (void)(*GetEA[ModRM])(cpustate);
+ tmp = ReadByte(cpustate->ea);
+ ICOUNT = old - 13; /* my source says 15 cycles everytime and not
+ * ModRM-dependent like GetEA[] does..hmmm */
+ }
+ tmp2 = FETCH;
+ tmp2 &= 0xF;
+ cpustate->ZeroVal = tmp & (bytes[tmp2]) ? 1 : 0;
+/* SetZF(tmp & (1<<tmp2)); */
+ break;
+
+ case 0x19: /* 0F 19 XX - TEST1 [bx+30h],07 */
+ ModRM = FETCH;
+ /* tmp = GetRMWord(ModRM); */
+ if (ModRM >= 0xc0)
+ {
+ tmp = cpustate->regs.w[Mod_RM.RM.w[ModRM]];
+ ICOUNT -= 4;
+ }
+ else
+ {
+ int old = ICOUNT;
+
+ (void)(*GetEA[ModRM])(cpustate);
+ tmp = ReadWord(cpustate->ea);
+ ICOUNT = old - 13; /* my source says 14 cycles everytime and not
+ * ModRM-dependent like GetEA[] does..hmmm */
+ }
+ tmp2 = FETCH;
+ tmp2 &= 0xf;
+ cpustate->ZeroVal = tmp & (bytes[tmp2]) ? 1 : 0;
+/* SetZF(tmp & (1<<tmp2)); */
+ break;
+
+ case 0x1a: /* 0F 1A 06 - CLR1 si,cl */
+ ModRM = FETCH;
+ /* tmp = GetRMByte(ModRM); */
+ if (ModRM >= 0xc0)
+ {
+ tmp = cpustate->regs.b[Mod_RM.RM.b[ModRM]];
+ ICOUNT -= 6;
+ }
+ else
+ {
+ int old = ICOUNT;
+
+ (void)(*GetEA[ModRM])(cpustate);
+ tmp = ReadByte(cpustate->ea);
+ ICOUNT = old - 15; /* my source says 15 cycles everytime and not
+ * ModRM-dependent like GetEA[] does..hmmm */
+ }
+ tmp2 = FETCH;
+ tmp2 &= 0x7;
+ tmp &= ~(bytes[tmp2]);
+ PutbackRMByte(ModRM, tmp);
+ break;
+
+ case 0x1B: /* 0F 1B 06 - CLR1 si,cl */
+ ModRM = FETCH;
+ /* tmp = GetRMWord(ModRM); */
+ if (ModRM >= 0xc0)
+ {
+ tmp = cpustate->regs.w[Mod_RM.RM.w[ModRM]];
+ ICOUNT -= 6;
+ }
+ else
+ {
+ int old = ICOUNT;
+
+ (void)(*GetEA[ModRM])(cpustate);
+ tmp = ReadWord(cpustate->ea);
+ ICOUNT = old - 15; /* my source says 15 cycles everytime and not
+ * ModRM-dependent like GetEA[] does..hmmm */
+ }
+ tmp2 = FETCH;
+ tmp2 &= 0xF;
+ tmp &= ~(bytes[tmp2]);
+ PutbackRMWord(ModRM, tmp);
+ break;
+
+ case 0x1C: /* 0F 1C 47 30 - SET1 [bx+30h],cl */
+ ModRM = FETCH;
+ /* tmp = GetRMByte(ModRM); */
+ if (ModRM >= 0xc0)
+ {
+ tmp = cpustate->regs.b[Mod_RM.RM.b[ModRM]];
+ ICOUNT -= 5;
+ }
+ else
+ {
+ int old = ICOUNT;
+
+ (void)(*GetEA[ModRM])(cpustate);
+ tmp = ReadByte(cpustate->ea);
+ ICOUNT = old - 14; /* my source says 15 cycles everytime and not
+ * ModRM-dependent like GetEA[] does..hmmm */
+ }
+ tmp2 = FETCH;
+ tmp2 &= 0x7;
+ tmp |= (bytes[tmp2]);
+ PutbackRMByte(ModRM, tmp);
+ break;
+
+ case 0x1D: /* 0F 1D C6 - SET1 si,cl */
+ /* logerror("PC=%06x : Set1 ",activecpu_get_pc()-2); */
+ ModRM = FETCH;
+ if (ModRM >= 0xc0)
+ {
+ tmp = cpustate->regs.w[Mod_RM.RM.w[ModRM]];
+ ICOUNT -= 5;
+ /* logerror("reg=%04x ->",tmp); */
+ }
+ else
+ {
+ int old = ICOUNT;
+
+ (void)(*GetEA[ModRM])(cpustate); /* calculate EA */
+ tmp = ReadWord(cpustate->ea); /* read from EA */
+ ICOUNT = old - 14;
+ /* logerror("[%04x]=%04x ->",EA,tmp); */
+ }
+ tmp2 = FETCH;
+ tmp2 &= 0xF;
+ tmp |= (bytes[tmp2]);
+ /* logerror("%04x",tmp); */
+ PutbackRMWord(ModRM, tmp);
+ break;
+
+ case 0x1e: /* 0F 1e C6 - NOT1 si,07 */
+ ModRM = FETCH;
+ /* tmp = GetRMByte(ModRM); */
+ if (ModRM >= 0xc0)
+ {
+ tmp = cpustate->regs.b[Mod_RM.RM.b[ModRM]];
+ ICOUNT -= 5;
+ }
+ else
+ {
+ int old = ICOUNT;
+
+ (void)(*GetEA[ModRM])(cpustate);
+ tmp = ReadByte(cpustate->ea);
+ ICOUNT = old - 19;
+ }
+ tmp2 = FETCH;
+ tmp2 &= 0x7;
+ if (tmp & bytes[tmp2])
+ tmp &= ~(bytes[tmp2]);
+ else
+ tmp |= (bytes[tmp2]);
+ PutbackRMByte(ModRM, tmp);
+ break;
+
+ case 0x1f: /* 0F 1f C6 - NOT1 si,07 */
+ ModRM = FETCH;
+ //tmp = GetRMWord(ModRM);
+ if (ModRM >= 0xc0)
+ {
+ tmp = cpustate->regs.w[Mod_RM.RM.w[ModRM]];
+ ICOUNT -= 5;
+ }
+ else
+ {
+ int old = ICOUNT;
+
+ (void)(*GetEA[ModRM])(cpustate);
+ tmp = ReadWord(cpustate->ea);
+ ICOUNT = old - 19; /* my source says 15 cycles everytime and not
+ * ModRM-dependent like GetEA[] does..hmmm */
+ }
+ tmp2 = FETCH;
+ tmp2 &= 0xF;
+ if (tmp & bytes[tmp2])
+ tmp &= ~(bytes[tmp2]);
+ else
+ tmp |= (bytes[tmp2]);
+ PutbackRMWord(ModRM, tmp);
+ break;
+
+ case 0x20: /* 0F 20 59 - add4s */
+ {
+ /* length in words ! */
+ int count = (cpustate->regs.b[CL] + 1) / 2;
+ int i;
+ unsigned di = cpustate->regs.w[DI];
+ unsigned si = cpustate->regs.w[SI];
+
+ cpustate->ZeroVal = 1;
+ cpustate->CarryVal = 0; /* NOT ADC */
+ for (i = 0; i < count; i++)
+ {
+ int v1, v2;
+ int result;
+
+ tmp = GetMemB(DS, si);
+ tmp2 = GetMemB(ES, di);
+
+ v1 = (tmp >> 4) * 10 + (tmp & 0xf);
+ v2 = (tmp2 >> 4) * 10 + (tmp2 & 0xf);
+ result = v1 + v2 + cpustate->CarryVal;
+ cpustate->CarryVal = result > 99 ? 1 : 0;
+ result = result % 100;
+ v1 = ((result / 10) << 4) | (result % 10);
+ PutMemB(ES, di, v1);
+ if (v1)
+ cpustate->ZeroVal = 0;
+ si++;
+ di++;
+ }
+ cpustate->OverVal = cpustate->CarryVal;
+ ICOUNT -= 7 + 19 * count; /* 7+19n, n #operand words */
+ }
+ break;
+
+ case 0x22: /* 0F 22 59 - sub4s */
+ {
+ int count = (cpustate->regs.b[CL] + 1) / 2;
+ int i;
+ unsigned di = cpustate->regs.w[DI];
+ unsigned si = cpustate->regs.w[SI];
+
+ cpustate->ZeroVal = 1;
+ cpustate->CarryVal = 0; /* NOT ADC */
+ for (i = 0; i < count; i++)
+ {
+ int v1, v2;
+ int result;
+
+ tmp = GetMemB(ES, di);
+ tmp2 = GetMemB(DS, si);
+
+ v1 = (tmp >> 4) * 10 + (tmp & 0xf);
+ v2 = (tmp2 >> 4) * 10 + (tmp2 & 0xf);
+ if (v1 < (v2 + cpustate->CarryVal))
+ {
+ v1 += 100;
+ result = v1 - (v2 + cpustate->CarryVal);
+ cpustate->CarryVal = 1;
+ }
+ else
+ {
+ result = v1 - (v2 + cpustate->CarryVal);
+ cpustate->CarryVal = 0;
+ }
+ v1 = ((result / 10) << 4) | (result % 10);
+ PutMemB(ES, di, v1);
+ if (v1)
+ cpustate->ZeroVal = 0;
+ si++;
+ di++;
+ }
+ cpustate->OverVal = cpustate->CarryVal;
+ ICOUNT -= 7 + 19 * count;
+ }
+ break;
+
+ case 0x25:
+ /*
+ * ----------O-MOVSPA---------------------------------
+ * OPCODE MOVSPA - Move Stack Pointer After Bank Switched
+ *
+ * CPU: NEC V25,V35,V25 Plus,V35 Plus,V25 Software Guard
+ * Type of Instruction: System
+ *
+ * Instruction: MOVSPA
+ *
+ * Description: This instruction transfer both SS and SP of the old register
+ * bank to new register bank after the bank has been switched by
+ * interrupt or BRKCS instruction.
+ *
+ * Flags Affected: None
+ *
+ * CPU mode: RM
+ *
+ * +++++++++++++++++++++++
+ * Physical Form: MOVSPA
+ * COP (Code of Operation) : 0Fh 25h
+ *
+ * Clocks: 16
+ */
+ logerror("PC=%06x : MOVSPA\n", activecpu_get_pc() - 2);
+ ICOUNT -= 16;
+ break;
+ case 0x26: /* 0F 22 59 - cmp4s */
+ {
+ int count = (cpustate->regs.b[CL] + 1) / 2;
+ int i;
+ unsigned di = cpustate->regs.w[DI];
+ unsigned si = cpustate->regs.w[SI];
+
+ cpustate->ZeroVal = 1;
+ cpustate->CarryVal = 0; /* NOT ADC */
+ for (i = 0; i < count; i++)
+ {
+ int v1, v2;
+ int result;
+
+ tmp = GetMemB(ES, di);
+ tmp2 = GetMemB(DS, si);
+
+ v1 = (tmp >> 4) * 10 + (tmp & 0xf);
+ v2 = (tmp2 >> 4) * 10 + (tmp2 & 0xf);
+ if (v1 < (v2 + cpustate->CarryVal))
+ {
+ v1 += 100;
+ result = v1 - (v2 + cpustate->CarryVal);
+ cpustate->CarryVal = 1;
+ }
+ else
+ {
+ result = v1 - (v2 + cpustate->CarryVal);
+ cpustate->CarryVal = 0;
+ }
+ v1 = ((result / 10) << 4) | (result % 10);
+/* PutMemB(ES, di,v1); */ /* no store, only compare */
+ if (v1)
+ cpustate->ZeroVal = 0;
+ si++;
+ di++;
+ }
+ cpustate->OverVal = cpustate->CarryVal;
+ ICOUNT -= 7 + 19 * (cpustate->regs.b[CL] + 1); // 7+19n, n #operand bytes
+ }
+ break;
+ case 0x28: /* 0F 28 C7 - ROL4 bh */
+ ModRM = FETCH;
+ /* tmp = GetRMByte(ModRM); */
+ if (ModRM >= 0xc0)
+ {
+ tmp = cpustate->regs.b[Mod_RM.RM.b[ModRM]];
+ ICOUNT -= 25;
+ }
+ else
+ {
+ int old = ICOUNT;
+
+ (void)(*GetEA[ModRM])(cpustate);
+ tmp = ReadByte(cpustate->ea);
+ ICOUNT = old - 28;
+ }
+ tmp <<= 4;
+ tmp |= cpustate->regs.b[AL] & 0xF;
+ cpustate->regs.b[AL] = (cpustate->regs.b[AL] & 0xF0) | ((tmp >> 8) & 0xF);
+ tmp &= 0xff;
+ PutbackRMByte(ModRM, tmp);
+ break;
+
+ /* Is this a REAL instruction?? */
+ case 0x29: /* 0F 29 C7 - ROL4 bx */
+
+ ModRM = FETCH;
+ /*
+ * if (ModRM >= 0xc0)
+ * {
+ * tmp=cpustate->regs.w[Mod_RM.RM.w[ModRM]];
+ * ICOUNT-=29;
+ * }
+ * else
+ * {
+ * int old=ICOUNT;
+ * (*GetEA[ModRM])();
+ * tmp=ReadWord(cpustate->ea);
+ * ICOUNT=old-33;
+ * }
+ * tmp <<= 4;
+ * tmp |= cpustate->regs.b[AL] & 0xF;
+ * cpustate->regs.b[AL] = (cpustate->regs.b[AL] & 0xF0) | ((tmp>>8)&0xF);
+ * tmp &= 0xffff;
+ * PutbackRMWord(ModRM,tmp);
+ */
+ logerror("PC=%06x : ROL4 %02x\n", activecpu_get_pc() - 3, ModRM);
+ break;
+
+ case 0x2A: /* 0F 2a c2 - ROR4 bh */
+ ModRM = FETCH;
+ /* tmp = GetRMByte(ModRM); */
+ if (ModRM >= 0xc0)
+ {
+ tmp = cpustate->regs.b[Mod_RM.RM.b[ModRM]];
+ ICOUNT -= 29;
+ }
+ else
+ {
+ int old = ICOUNT;
+
+ (void)(*GetEA[ModRM])(cpustate);
+ tmp = ReadByte(cpustate->ea);
+ ICOUNT = old - 33;
+ }
+ tmp2 = (cpustate->regs.b[AL] & 0xF) << 4;
+ cpustate->regs.b[AL] = (cpustate->regs.b[AL] & 0xF0) | (tmp & 0xF);
+ tmp = tmp2 | (tmp >> 4);
+ PutbackRMByte(ModRM, tmp);
+ break;
+
+ case 0x2B: // 0F 2b c2 - ROR4 bx
+ ModRM = FETCH;
+ /*
+ * /* tmp = GetRMWord(ModRM);
+ * if (ModRM >= 0xc0)
+ * {
+ * tmp=cpustate->regs.w[Mod_RM.RM.w[ModRM]];
+ * ICOUNT-=29;
+ * }
+ * else {
+ * int old=ICOUNT;
+ * (*GetEA[ModRM])();
+ * tmp=ReadWord(cpustate->ea);
+ * ICOUNT=old-33;
+ * }
+ * tmp2 = (cpustate->regs.b[AL] & 0xF)<<4;
+ * cpustate->regs.b[AL] = (cpustate->regs.b[AL] & 0xF0) | (tmp&0xF);
+ * tmp = tmp2 | (tmp>>4);
+ * PutbackRMWord(ModRM,tmp);
+ */
+ logerror("PC=%06x : ROR4 %02x\n", activecpu_get_pc() - 3, ModRM);
+ break;
+
+ case 0x2D: /* 0Fh 2Dh <1111 1RRR> */
+ /* OPCODE BRKCS - Break with Contex Switch
+ * CPU: NEC V25,V35,V25 Plus,V35 Plus,V25 Software Guard
+ * Description:
+ *
+ * Perform a High-Speed Software Interrupt with contex-switch to
+ * register bank indicated by the lower 3-bits of 'bank'.
+ *
+ * Info: NEC V25/V35/V25 Plus/V35 Plus Bank System
+ *
+ * This Chips have 8 32bytes register banks, which placed in
+ * Internal chip RAM by addresses:
+ * xxE00h..xxE1Fh Bank 0
+ * xxE20h..xxE3Fh Bank 1
+ * .........
+ * xxEC0h..xxEDFh Bank 6
+ * xxEE0h..xxEFFh Bank 7
+ * xxF00h..xxFFFh Special Functions Register
+ * Where xx is Value of IDB register.
+ * IBD is Byte Register contained Internal data area base
+ * IBD addresses is FFFFFh and xxFFFh where xx is data in IBD.
+ *
+ * Format of Bank:
+ * +0 Reserved
+ * +2 Vector PC
+ * +4 Save PSW
+ * +6 Save PC
+ * +8 DS0 ;DS
+ * +A SS ;SS
+ * +C PS ;CS
+ * +E DS1 ;ES
+ * +10 IY ;DI
+ * +11 IX ;SI
+ * +14 BP ;BP
+ * +16 SP ;SP
+ * +18 BW ;BX
+ * +1A DW ;DX
+ * +1C CW ;CX
+ * +1E AW ;AX
+ *
+ * Format of V25 etc. PSW (FLAGS):
+ * Bit Description
+ * 15 1
+ * 14 RB2 \
+ * 13 RB1 > Current Bank Number
+ * 12 RB0 /
+ * 11 V ;OF
+ * 10 IYR ;DF
+ * 9 IE ;IF
+ * 8 BRK ;TF
+ * 7 S ;SF
+ * 6 Z ;ZF
+ * 5 F1 General Purpose user flag #1 (accessed by Flag Special Function Register)
+ * 4 AC ;AF
+ * 3 F0 General purpose user flag #0 (accessed by Flag Special Function Register)
+ * 2 P ;PF
+ * 1 BRKI I/O Trap Enable Flag
+ * 0 CY ;CF
+ *
+ * Flags Affected: None
+ */
+ ModRM = FETCH;
+ logerror("PC=%06x : BRKCS %02x\n", activecpu_get_pc() - 3, ModRM);
+ ICOUNT -= 15; /* checked ! */
+ break;
+
+ case 0x31: /* 0F 31 [mod:reg:r/m] - INS reg8,reg8 or INS reg8,imm4 */
+ ModRM = FETCH;
+ logerror("PC=%06x : INS ", activecpu_get_pc() - 2);
+ if (ModRM >= 0xc0)
+ {
+ tmp = cpustate->regs.b[Mod_RM.RM.b[ModRM]];
+ logerror("ModRM=%04x \n", ModRM);
+ ICOUNT -= 29;
+ }
+ else
+ {
+ int old = ICOUNT;
+
+ (void)(*GetEA[ModRM])(cpustate);
+ tmp = ReadByte(cpustate->ea);
+ logerror("ModRM=%04x Byte=%04x\n", EA, tmp);
+ ICOUNT = old - 33;
+ }
+
+ /* more to come
+ * bfl=tmp2 & 0xf; /* bit field length
+ * bfs=tmp & 0xf; /* bit field start (bit offset in DS:SI)
+ * cpustate->regs.b[AH] =0; /* AH =0
+ */
+
+ /* 2do: the rest is silence....yet
+ * ----------O-INS------------------------------------
+ * OPCODE INS - Insert Bit String
+ *
+ * CPU: NEC/Sony all V-series
+ * Type of Instruction: User
+ *
+ * Instruction: INS start,len
+ *
+ * Description:
+ *
+ * BitField [ BASE = ES:DI
+ * START BIT OFFSET = start
+ * LENGTH = len
+ * ] <- AX [ bits= (len-1)..0]
+ *
+ * Note: di and start automatically UPDATE
+ * Note: Alternative Name of this instruction is NECINS
+ *
+ * Flags Affected: None
+ *
+ * CPU mode: RM
+ *
+ * +++++++++++++++++++++++
+ * Physical Form : INS reg8,reg8
+ * COP (Code of Operation) : 0FH 31H PostByte
+ */
+
+ /* ICOUNT-=31; */ /* 31 -117 clocks ....*/
+ break;
+
+ case 0x33: /* 0F 33 [mod:reg:r/m] - EXT reg8,reg8 or EXT reg8,imm4 */
+ ModRM = FETCH;
+ logerror("PC=%06x : EXT ", activecpu_get_pc() - 2);
+ if (ModRM >= 0xc0)
+ {
+ tmp = cpustate->regs.b[Mod_RM.RM.b[ModRM]];
+ logerror("ModRM=%04x \n", ModRM);
+ ICOUNT -= 29;
+ }
+ else
+ {
+ int old = ICOUNT;
+
+ (void)(*GetEA[ModRM])(cpustate);
+ tmp = ReadByte(cpustate->ea);
+ logerror("ModRM=%04x Byte=%04x\n", EA, tmp);
+ ICOUNT = old - 33;
+ }
+ /* 2do: the rest is silence....yet
+ /*
+ * bfl=tmp2 & 0xf; /* bit field length
+ * bfs=tmp & 0xf; /* bit field start (bit offset in DS:SI)
+ * cpustate->regs.b[AH] =0; /* AH =0
+ */
+
+ /*
+ *
+ * ----------O-EXT------------------------------------
+ * OPCODE EXT - Extract Bit Field
+ *
+ * CPU: NEC/Sony all V-series
+ * Type of Instruction: User
+ *
+ * Instruction: EXT start,len
+ *
+ * Description:
+ *
+ * AX <- BitField [
+ * BASE = DS:SI
+ * START BIT OFFSET = start
+ * LENGTH = len
+ * ];
+ *
+ * Note: si and start automatically UPDATE
+ *
+ * Flags Affected: None
+ *
+ * CPU mode: RM
+ *
+ * +++++++++++++++++++++++
+ * Physical Form : EXT reg8,reg8
+ * COP (Code of Operation) : 0FH 33H PostByte
+ *
+ * Clocks: EXT reg8,reg8
+ * NEC V20: 26-55
+ */
+
+ /* NEC_ICount-=26; */ /* 26 -55 clocks ....*/
+ break;
+
+ case 0x91:
+ /*
+ * ----------O-RETRBI---------------------------------
+ * OPCODE RETRBI - Return from Register Bank Context
+ * Switch Interrupt.
+ *
+ * CPU: NEC V25,V35,V25 Plus,V35 Plus,V25 Software Guard
+ * Type of Instruction: System
+ *
+ * Instruction: RETRBI
+ *
+ * Description:
+ *
+ * PC <- Save PC;
+ * PSW <- Save PSW;
+ *
+ * Flags Affected: All
+ *
+ * CPU mode: RM
+ *
+ * +++++++++++++++++++++++
+ * Physical Form: RETRBI
+ * COP (Code of Operation) : 0Fh 91h
+ *
+ * Clocks: 12
+ */
+ logerror("PC=%06x : RETRBI\n", activecpu_get_pc() - 2);
+ ICOUNT -= 12;
+ break;
+
+ case 0x94:
+ /*
+ * ----------O-TSKSW----------------------------------
+ * OPCODE TSKSW - Task Switch
+ *
+ * CPU: NEC V25,V35,V25 Plus,V35 Plus,V25 Software Guard
+ * Type of Instruction: System
+ *
+ * Instruction: TSKSW reg16
+ *
+ * Description: Perform a High-Speed task switch to the register bank indicated
+ * by lower 3 bits of reg16. The PC and PSW are saved in the old
+ * banks. PC and PSW save Registers and the new PC and PSW values
+ * are retrived from the new register bank's save area.
+ *
+ * Note: See BRKCS instruction for more Info about banks.
+ *
+ * Flags Affected: All
+ *
+ * CPU mode: RM
+ *
+ * +++++++++++++++++++++++
+ * Physical Form: TSCSW reg16
+ * COP (Code of Operation) : 0Fh 94h <1111 1RRR>
+ *
+ * Clocks: 11
+ */
+ ModRM = FETCH;
+
+ logerror("PC=%06x : TSCSW %02x\n", activecpu_get_pc() - 3, ModRM);
+ ICOUNT -= 11;
+ break;
+
+ case 0x95:
+ /*
+ * ----------O-MOVSPB---------------------------------
+ * OPCODE MOVSPB - Move Stack Pointer Before Bamk Switching
+ *
+ * CPU: NEC V25,V35,V25 Plus,V35 Plus,V25 Software Guard
+ * Type of Instruction: System
+ *
+ * Instruction: MOVSPB Number_of_bank
+ *
+ * Description: The MOVSPB instruction transfers the current SP and SS before
+ * the bank switching to new register bank.
+ *
+ * Note: New Register Bank Number indicated by lower 3bit of Number_of_
+ * _bank.
+ *
+ * Note: See BRKCS instruction for more info about banks.
+ *
+ * Flags Affected: None
+ *
+ * CPU mode: RM
+ *
+ * +++++++++++++++++++++++
+ * Physical Form: MOVSPB reg16
+ * COP (Code of Operation) : 0Fh 95h <1111 1RRR>
+ *
+ * Clocks: 11
+ */
+ ModRM = FETCH;
+ logerror("PC=%06x : MOVSPB %02x\n", activecpu_get_pc() - 3, ModRM);
+ ICOUNT -= 11;
+ break;
+
+ case 0xbe:
+ /*
+ * ----------O-STOP-----------------------------------
+ * OPCODE STOP - Stop CPU
+ *
+ * CPU: NEC V25,V35,V25 Plus,V35 Plus,V25 Software Guard
+ * Type of Instruction: System
+ *
+ * Instruction: STOP
+ *
+ * Description:
+ * PowerDown instruction, Stop Oscillator,
+ * Halt CPU.
+ *
+ * Flags Affected: None
+ *
+ * CPU mode: RM
+ *
+ * +++++++++++++++++++++++
+ * Physical Form: STOP
+ * COP (Code of Operation) : 0Fh BEh
+ *
+ * Clocks: N/A
+ */
+ logerror("PC=%06x : STOP\n", activecpu_get_pc() - 2);
+ ICOUNT -= 2; /* of course this is crap */
+ break;
+
+ case 0xe0:
+ /*
+ * ----------O-BRKXA----------------------------------
+ * OPCODE BRKXA - Break to Expansion Address
+ *
+ * CPU: NEC V33/V53 only
+ * Type of Instruction: System
+ *
+ * Instruction: BRKXA int_vector
+ *
+ * Description:
+ * [sp-1,sp-2] <- PSW ; PSW EQU FLAGS
+ * [sp-3,sp-4] <- PS ; PS EQU CS
+ * [sp-5,sp-6] <- PC ; PC EQU IP
+ * SP <- SP -6
+ * IE <- 0
+ * BRK <- 0
+ * MD <- 0
+ * PC <- [int_vector*4 +0,+1]
+ * PS <- [int_vector*4 +2,+3]
+ * Enter Expansion Address Mode.
+ *
+ * Note: In NEC V53 Memory Space dividing into 1024 16K pages.
+ * The programming model is Same as in Normal mode.
+ *
+ * Mechanism is:
+ * 20 bit Logical Address: 19..14 Page Num 13..0 Offset
+ *
+ * page Num convertin by internal table to 23..14 Page Base
+ * tHE pHYIXCAL ADDRESS is both Base and Offset.
+ *
+ * Address Expansion Registers:
+ * logical Address A19..A14 I/O Address
+ * 0 FF00h
+ * 1 FF02h
+ * ... ...
+ * 63 FF7Eh
+ *
+ * Register XAM aliased with port # FF80h indicated current mode
+ * of operation.
+ * Format of XAM register (READ ONLY):
+ * 15..1 reserved
+ * 0 XA Flag, if=1 then in XA mode.
+ *
+ * Format of V53 PSW:
+ * 15..12 1
+ * 11 V
+ * 10 IYR
+ * 9 IE
+ * 8 BRK
+ * 7 S
+ * 6 Z
+ * 5 0
+ * 4 AC
+ * 3 0
+ * 2 P
+ * 1 1
+ * 0 CY
+ *
+ * Flags Affected: None
+ *
+ * CPU mode: RM
+ *
+ * +++++++++++++++++++++++
+ * Physical Form: BRKXA imm8
+ * COP (Code of Operation) : 0Fh E0h imm8
+ */
+
+ ModRM = FETCH;
+ logerror("PC=%06x : BRKXA %02x\n", activecpu_get_pc() - 3, ModRM);
+ ICOUNT -= 12;
+ break;
+
+ case 0xf0:
+ /*
+ * ----------O-RETXA----------------------------------
+ * OPCODE RETXA - Return from Expansion Address
+ *
+ * CPU: NEC V33/V53 only
+ * Type of Instruction: System
+ *
+ * Instruction: RETXA int_vector
+ *
+ * Description:
+ * [sp-1,sp-2] <- PSW ; PSW EQU FLAGS
+ * [sp-3,sp-4] <- PS ; PS EQU CS
+ * [sp-5,sp-6] <- PC ; PC EQU IP
+ * SP <- SP -6
+ * IE <- 0
+ * BRK <- 0
+ * MD <- 0
+ * PC <- [int_vector*4 +0,+1]
+ * PS <- [int_vector*4 +2,+3]
+ * Disable EA mode.
+ *
+ * Flags Affected: None
+ *
+ * CPU mode: RM
+ *
+ * +++++++++++++++++++++++
+ * Physical Form: RETXA imm8
+ * COP (Code of Operation) : 0Fh F0h imm8
+ *
+ * Clocks: 12
+ */
+ ModRM = FETCH;
+ logerror("PC=%06x : RETXA %02x\n", activecpu_get_pc() - 3, ModRM);
+ ICOUNT -= 12;
+ break;
+
+ case 0xff: /* 0F ff imm8 - BRKEM */
+ /*
+ * OPCODE BRKEM - Break for Emulation
+ *
+ * CPU: NEC/Sony V20/V30/V40/V50
+ * Description:
+ *
+ * PUSH FLAGS
+ * PUSH CS
+ * PUSH IP
+ * MOV CS,0:[intnum*4+2]
+ * MOV IP,0:[intnum*4]
+ * MD <- 0; // Enable 8080 emulation
+ *
+ * Note:
+ * BRKEM instruction do software interrupt and then New CS,IP loaded
+ * it switch to 8080 mode i.e. CPU will execute 8080 code.
+ * Mapping Table of Registers in 8080 Mode
+ * 8080 Md. A B C D E H L SP PC F
+ * native. AL CH CL DH DL BH BL BP IP FLAGS(low)
+ * For Return of 8080 mode use CALLN instruction.
+ * Note: I.e. 8080 addressing only 64KB then "Real Address" is CS*16+PC
+ *
+ * Flags Affected: MD
+ */
+ ModRM = FETCH;
+ ICOUNT -= 38;
+ logerror("PC=%06x : BRKEM %02x\n", activecpu_get_pc() - 3, ModRM);
+ PREFIX86(_interrupt)(cpustate, ModRM);
+ break;
+ }
+}
+
+void IX86_OPS_BASE::PREFIXV30(_brkn)() /* Opcode 0x63 BRKN - Break to Native Mode */
+{
+ /*
+ * CPU: NEC (V25/V35) Software Guard only
+ * Instruction: BRKN int_vector
+ *
+ * Description:
+ * [sp-1,sp-2] <- PSW ; PSW EQU FLAGS
+ * [sp-3,sp-4] <- PS ; PS EQU CS
+ * [sp-5,sp-6] <- PC ; PC EQU IP
+ * SP <- SP -6
+ * IE <- 0
+ * BRK <- 0
+ * MD <- 1
+ * PC <- [int_vector*4 +0,+1]
+ * PS <- [int_vector*4 +2,+3]
+ *
+ * Note: The BRKN instruction switches operations in Native Mode
+ * from Security Mode via Interrupt call. In Normal Mode
+ * Instruction executed as mPD70320/70322 (V25) operation mode.
+ *
+ * Flags Affected: None
+ *
+ * CPU mode: RM
+ *
+ * +++++++++++++++++++++++
+ * Physical Form: BRKN imm8
+ * COP (Code of Operation) : 63h imm8
+ *
+ * Clocks: 56+10T [44+10T]
+ */
+ /* ICOUNT-=56; */
+ unsigned int_vector;
+
+ int_vector = FETCH;
+ logerror("PC=%06x : BRKN %02x\n", activecpu_get_pc() - 2, int_vector);
+}
+
+void IX86_OPS_BASE::PREFIXV30(repc)(int flagval)
+{
+ /* Handles repc- and repnc- prefixes. flagval is the value of ZF
+ * for the loop to continue for CMPS and SCAS instructions.
+ */
+
+ unsigned next = FETCHOP;
+ unsigned count = cpustate->regs.w[CX];
+
+ switch (next)
+ {
+ case 0x26: /* ES: */
+ cpustate->seg_prefix = TRUE;
+ cpustate->prefix_seg = ES;
+ ICOUNT -= 2;
+ PREFIXV30(repc)(cpustate, flagval);
+ break;
+ case 0x2e: /* CS: */
+ cpustate->seg_prefix = TRUE;
+ cpustate->prefix_seg = CS;
+ ICOUNT -= 2;
+ PREFIXV30(repc)(cpustate, flagval);
+ break;
+ case 0x36: /* SS: */
+ cpustate->seg_prefix = TRUE;
+ cpustate->prefix_seg = SS;
+ ICOUNT -= 2;
+ PREFIXV30(repc)(cpustate, flagval);
+ break;
+ case 0x3e: /* DS: */
+ cpustate->seg_prefix = TRUE;
+ cpustate->prefix_seg = DS;
+ ICOUNT -= 2;
+ PREFIXV30(repc)(cpustate, flagval);
+ break;
+ case 0x6c: /* REP INSB */
+ ICOUNT -= 9 - count;
+ for (; (CF == flagval) && (count > 0); count--)
+ PREFIX186(_insb)(cpustate);
+ cpustate->regs.w[CX] = count;
+ break;
+ case 0x6d: /* REP INSW */
+ ICOUNT -= 9 - count;
+ for (; (CF == flagval) && (count > 0); count--)
+ PREFIX186(_insw)(cpustate);
+ cpustate->regs.w[CX] = count;
+ break;
+ case 0x6e: /* REP OUTSB */
+ ICOUNT -= 9 - count;
+ for (; (CF == flagval) && (count > 0); count--)
+ PREFIX186(_outsb)(cpustate);
+ cpustate->regs.w[CX] = count;
+ break;
+ case 0x6f: /* REP OUTSW */
+ ICOUNT -= 9 - count;
+ for (; (CF == flagval) && (count > 0); count--)
+ PREFIX186(_outsw)(cpustate);
+ cpustate->regs.w[CX] = count;
+ break;
+ case 0xa4: /* REP MOVSB */
+ ICOUNT -= 9 - count;
+ for (; (CF == flagval) && (count > 0); count--)
+ PREFIX86(_movsb)(cpustate);
+ cpustate->regs.w[CX] = count;
+ break;
+ case 0xa5: /* REP MOVSW */
+ ICOUNT -= 9 - count;
+ for (; (CF == flagval) && (count > 0); count--)
+ PREFIX86(_movsw)(cpustate);
+ cpustate->regs.w[CX] = count;
+ break;
+ case 0xa6: /* REP(N)E CMPSB */
+ ICOUNT -= 9;
+ for (cpustate->ZeroVal = !flagval; (ZF == flagval) && (CF == flagval) && (count > 0); count--)
+ PREFIX86(_cmpsb)(cpustate);
+ cpustate->regs.w[CX] = count;
+ break;
+ case 0xa7: /* REP(N)E CMPSW */
+ ICOUNT -= 9;
+ for (cpustate->ZeroVal = !flagval; (ZF == flagval) && (CF == flagval) && (count > 0); count--)
+ PREFIX86(_cmpsw)(cpustate);
+ cpustate->regs.w[CX] = count;
+ break;
+ case 0xaa: /* REP STOSB */
+ ICOUNT -= 9 - count;
+ for (; (CF == flagval) && (count > 0); count--)
+ PREFIX86(_stosb)(cpustate);
+ cpustate->regs.w[CX] = count;
+ break;
+ case 0xab: /* REP STOSW */
+ ICOUNT -= 9 - count;
+ for (; (CF == flagval) && (count > 0); count--)
+ PREFIX86(_stosw)(cpustate);
+ cpustate->regs.w[CX] = count;
+ break;
+ case 0xac: /* REP LODSB */
+ ICOUNT -= 9;
+ for (; (CF == flagval) && (count > 0); count--)
+ PREFIX86(_lodsb)(cpustate);
+ cpustate->regs.w[CX] = count;
+ break;
+ case 0xad: /* REP LODSW */
+ ICOUNT -= 9;
+ for (; (CF == flagval) && (count > 0); count--)
+ PREFIX86(_lodsw)(cpustate);
+ cpustate->regs.w[CX] = count;
+ break;
+ case 0xae: /* REP(N)E SCASB */
+ ICOUNT -= 9;
+ for (cpustate->ZeroVal = !flagval; (ZF == flagval) && (CF == flagval) && (count > 0); count--)
+ PREFIX86(_scasb)(cpustate);
+ cpustate->regs.w[CX] = count;
+ break;
+ case 0xaf: /* REP(N)E SCASW */
+ ICOUNT -= 9;
+ for (cpustate->ZeroVal = !flagval; (ZF == flagval) && (CF == flagval) && (count > 0); count--)
+ PREFIX86(_scasw)(cpustate);
+ cpustate->regs.w[CX] = count;
+ break;
+ default:
+ PREFIXV30(_instruction)[next](cpustate);
+ }
+}
+
+void IX86_OPS_BASE::PREFIXV30(_repnc)() /* Opcode 0x64 */
+{
+ PREFIXV30(repc)(cpustate, 0);
+}
+
+void IX86_OPS_BASE::PREFIXV30(_repc)() /* Opcode 0x65 */
+{
+ PREFIXV30(repc)(cpustate, 1);
+}
+
+void IX86_OPS_BASE::PREFIXV30(_aad)() /* Opcode 0xd5 */
+{
+ unsigned mult = FETCH;
+
+ ICOUNT -= timing.aad;
+
+// cpustate->regs.b[AL] = cpustate->regs.b[AH] * mult + cpustate->regs.b[AL];
+ cpustate->regs.b[AL] = cpustate->regs.b[AH] * 10 + cpustate->regs.b[AL];
+ cpustate->regs.b[AH] = 0;
+
+ SetZF(cpustate->regs.b[AL]);
+ SetPF(cpustate->regs.b[AL]);
+ cpustate->SignVal = 0;
+}
+
+void IX86_OPS_BASE::PREFIXV30(_setalc)() /* Opcode 0xd6 */
+{
+ /*
+ * ----------O-SETALC---------------------------------
+ * OPCODE SETALC - Set AL to Carry Flag
+ *
+ * CPU: Intel 8086 and all its clones and upward
+ * compatibility chips.
+ * Type of Instruction: User
+ *
+ * Instruction: SETALC
+ *
+ * Description:
+ *
+ * IF (CF=0) THEN AL:=0 ELSE AL:=FFH;
+ *
+ * Flags Affected: None
+ *
+ * CPU mode: RM,PM,VM,SMM
+ *
+ * Physical Form: SETALC
+ * COP (Code of Operation): D6H
+ * Clocks: 80286 : n/a [3]
+ * 80386 : n/a [3]
+ * Cx486SLC : n/a [2]
+ * i486 : n/a [3]
+ * Pentium : n/a [3]
+ * Note: n/a is Time that Intel etc not say.
+ * [3] is real time it executed.
+ *
+ */
+ cpustate->regs.b[AL] = (CF) ? 0xff : 0x00;
+ ICOUNT -= 3; // V30
+ logerror("PC=%06x : SETALC\n", activecpu_get_pc() - 1);
+}
+
+#if 0
+void IX86_OPS_BASE::PREFIXV30(_brks)() /* Opcode 0xf1 - Break to Security Mode */
+{
+ /*
+ * CPU: NEC (V25/V35) Software Guard only
+ * Instruction: BRKS int_vector
+ *
+ * Description:
+ * [sp-1,sp-2] <- PSW ; PSW EQU FLAGS
+ * [sp-3,sp-4] <- PS ; PS EQU CS
+ * [sp-5,sp-6] <- PC ; PC EQU IP
+ * SP <- SP -6
+ * IE <- 0
+ * BRK <- 0
+ * MD <- 0
+ * PC <- [int_vector*4 +0,+1]
+ * PS <- [int_vector*4 +2,+3]
+ *
+ * Note: The BRKS instruction switches operations in Security Mode
+ * via Interrupt call. In Security Mode the fetched operation
+ * code is executed after conversion in accordance with build-in
+ * translation table
+ *
+ * Flags Affected: None
+ *
+ * CPU mode: RM
+ *
+ * +++++++++++++++++++++++
+ * Physical Form: BRKS imm8
+ * Clocks: 56+10T [44+10T]
+ */
+ unsigned int_vector;
+
+ int_vector = FETCH;
+ logerror("PC=%06x : BRKS %02x\n", activecpu_get_pc() - 2, int_vector);
+}
+#endif
+
+void IX86_OPS::PREFIX(_pop_ss)() /* Opcode 0x17 */
+{
+ POP(cpustate->sregs[SS]);
+ cpustate->base[SS] = SegBase(SS);
+
+ ICOUNT -= timing.pop_seg;
+ PREFIX(_instruction)[FETCHOP](cpustate); /* no interrupt before next instruction */
+}
+
+void IX86_OPS::PREFIX(_mov_sregw)() /* Opcode 0x8e */
+{
+ unsigned ModRM = FETCH;
+ WORD src = GetRMWord(ModRM);
+
+ ICOUNT -= (ModRM >= 0xc0) ? timing.mov_sr : timing.mov_sm;
+ switch (ModRM & 0x38)
+ {
+ case 0x00: /* mov es,ew */
+ cpustate->sregs[ES] = src;
+ cpustate->base[ES] = SegBase(ES);
+ break;
+ case 0x18: /* mov ds,ew */
+ cpustate->sregs[DS] = src;
+ cpustate->base[DS] = SegBase(DS);
+ break;
+ case 0x10: /* mov ss,ew */
+ cpustate->sregs[SS] = src;
+ cpustate->base[SS] = SegBase(SS); /* no interrupt allowed before next instr */
+ cpustate->seg_prefix = FALSE;
+ PREFIX(_instruction)[FETCHOP](cpustate);
+ break;
+ case 0x08: /* mov cs,ew */
+//#ifndef I80186
+ int ip = cpustate->pc - cpustate->base[CS];
+ cpustate->sregs[CS] = src;
+ cpustate->base[CS] = SegBase(CS);
+ cpustate->pc = (ip + cpustate->base[CS]) & AMASK;
+ CHANGE_PC(cpustate->pc);
+//#endif
+ break;
+ }
+}
+
+void IX86_OPS::PREFIX(_sti)() /* Opcode 0xfb */
+{
+ ICOUNT -= timing.flag_ops;
+ SetIF(1);
+ PREFIX(_instruction)[FETCHOP](cpustate); /* no interrupt before next instruction */
+
+ /* if an interrupt is pending, signal an interrupt */
+ if (cpustate->irq_state) {
+ PREFIX86(_interrupt)(cpustate, (UINT32)-1);
+ cpustate->irq_state = 0;
+ }
+}
+
+void IX86_OPS_BASE::PREFIX(_inc_bx)() /* Opcode 0x43 */
+{
+ IncWordReg(BX);
+}
+
+void IX86_OPS_BASE::PREFIX(_pop_ss)() /* Opcode 0x17 */
+{
+ POP(cpustate->sregs[SS]);
+ cpustate->base[SS] = SegBase(SS);
+
+ ICOUNT -= timing.pop_seg;
+ PREFIX(_instruction)[FETCHOP](cpustate); /* no interrupt before next instruction */
+}
+
+void IX86_OPS_BASE::PREFIX(_es)() /* Opcode 0x26 */
+{
+ cpustate->seg_prefix = TRUE;
+ cpustate->prefix_seg = ES;
+ ICOUNT -= timing.override;
+ PREFIX(_instruction)[FETCHOP](cpustate);
+}
+
+void IX86_OPS_BASE::PREFIX(_cs)() /* Opcode 0x2e */
+{
+ cpustate->seg_prefix = TRUE;
+ cpustate->prefix_seg = CS;
+ ICOUNT -= timing.override;
+ PREFIX(_instruction)[FETCHOP](cpustate);
+}
+
+void IX86_OPS_BASE::PREFIX(_ss)() /* Opcode 0x36 */
+{
+ cpustate->seg_prefix = TRUE;
+ cpustate->prefix_seg = SS;
+ ICOUNT -= timing.override;
+ PREFIX(_instruction)[FETCHOP](cpustate);
+}
+
+void IX86_OPS_BASE::PREFIX(_ds)() /* Opcode 0x3e */
+{
+ cpustate->seg_prefix = TRUE;
+ cpustate->prefix_seg = DS;
+ ICOUNT -= timing.override;
+ PREFIX(_instruction)[FETCHOP](cpustate);
+}
+
+void IX86_OPS_BASE::PREFIX(_mov_sregw)() /* Opcode 0x8e */
+{
+ unsigned ModRM = FETCH;
+ WORD src = GetRMWord(ModRM);
+
+ ICOUNT -= (ModRM >= 0xc0) ? timing.mov_sr : timing.mov_sm;
+ switch (ModRM & 0x38)
+ {
+ case 0x00: /* mov es,ew */
+ cpustate->sregs[ES] = src;
+ cpustate->base[ES] = SegBase(ES);
+ break;
+ case 0x18: /* mov ds,ew */
+ cpustate->sregs[DS] = src;
+ cpustate->base[DS] = SegBase(DS);
+ break;
+ case 0x10: /* mov ss,ew */
+ cpustate->sregs[SS] = src;
+ cpustate->base[SS] = SegBase(SS); /* no interrupt allowed before next instr */
+ cpustate->seg_prefix = FALSE;
+ PREFIX(_instruction)[FETCHOP](cpustate);
+ break;
+ case 0x08: /* mov cs,ew */
+//#ifndef I80186
+ int ip = cpustate->pc - cpustate->base[CS];
+ cpustate->sregs[CS] = src;
+ cpustate->base[CS] = SegBase(CS);
+ cpustate->pc = (ip + cpustate->base[CS]) & AMASK;
+ CHANGE_PC(cpustate->pc);
+//#endif
+ break;
+ }
+}
+
+void IX86_OPS_BASE::PREFIX(_repne)() /* Opcode 0xf2 */
+{
+ PREFIX(rep)(0);
+}
+
+void IX86_OPS_BASE::PREFIX(_repe)() /* Opcode 0xf3 */
+{
+ PREFIX(rep)(1);
+}
+
+void IX86_OPS_BASE::PREFIX(_sti)() /* Opcode 0xfb */
+{
+ ICOUNT -= timing.flag_ops;
+ SetIF(1);
+ PREFIX(_instruction)[FETCHOP](cpustate); /* no interrupt before next instruction */
+
+ /* if an interrupt is pending, signal an interrupt */
+ if (cpustate->irq_state) {
+ PREFIX86(_interrupt)(cpustate, (UINT32)-1);
+ cpustate->irq_state = 0;
+ }
+}
--- /dev/null
+//void IX86_BASE::PREFIXV30(_0fpre)();
+//void IX86_BASE::PREFIXV30(_repnc)();
+//void IX86_BASE::PREFIXV30(_repc)();
+//void IX86_BASE::PREFIXV30(_aad)();
+//void IX86_BASE::PREFIXV30(_setalc)();
+#if 0
+//void IX86_BASE::PREFIXV30(_brks)();
+#endif
+
+/* changed instructions */
+//void IX86_BASE::PREFIX(_pop_ss)();
+//void IX86_BASE::PREFIX(_es)();
+//void IX86_BASE::PREFIX(_cs)();
+//void IX86_BASE::PREFIX(_ss)();
+//void IX86_BASE::PREFIX(_ds)();
+//void IX86_BASE::PREFIX(_mov_sregw)();
+//void IX86_BASE::PREFIXV30(_repne)();
+//void IX86_BASE::PREFIXV30(_repe)();
+//void IX86_BASE::PREFIXV30(_sti)();
--- /dev/null
+#ifndef __LIBNEWDEV_LIBCPUI86_IX86_CPUSTAT_H__
+#define __LIBNEWDEV_LIBCPUI86_IX86_CPUSTAT_H__
+
+
+/***************************************************************************/
+/* cpu state */
+/***************************************************************************/
+/* I86 registers */
+union i80286basicregs
+{ /* eight general registers */
+ UINT16 w[8]; /* viewed as 16 bits registers */
+ UINT8 b[16]; /* or as 8 bit registers */
+};
+
+class DEVICE;
+class EMU;
+class DEBUGGER;
+struct i80286_state
+{
+ i80286basicregs regs;
+ UINT32 amask; /* address mask */
+ UINT32 pc;
+ UINT32 prevpc;
+
+ UINT16 ip;
+ UINT32 sp;
+
+ UINT16 flags;
+ UINT16 msw;
+ UINT32 base[4];
+ UINT16 sregs[4];
+ UINT16 limit[4];
+ UINT8 rights[4];
+ bool valid[4];
+ struct {
+ UINT32 base;
+ UINT16 limit;
+ } gdtr, idtr;
+ struct {
+ UINT16 sel;
+ UINT32 base;
+ UINT16 limit;
+ UINT8 rights;
+ } ldtr, tr;
+
+ DEVICE *pic;
+ DEVICE *program;
+ DEVICE *io;
+//#ifdef I86_PSEUDO_BIOS
+ DEVICE *bios;
+//#endif
+//#ifdef SINGLE_MODE_DMA
+ DEVICE *dma;
+//#endif
+//#ifdef USE_DEBUGGER
+ EMU *emu;
+ DEBUGGER *debugger;
+ DEVICE *program_stored;
+ DEVICE *io_stored;
+//#endif
+ INT32 AuxVal, OverVal, SignVal, ZeroVal, CarryVal, DirVal; /* 0 or non-0 valued flags */
+ UINT8 ParityVal;
+ UINT8 TF, IF; /* 0 or 1 valued flags */
+ UINT8 MF; /* V30 mode flag */
+
+ UINT8 int_vector;
+ INT8 nmi_state;
+ INT8 irq_state;
+ INT8 test_state;
+ UINT8 rep_in_progress;
+ INT32 extra_cycles; /* extra cycles for interrupts */
+
+ int halted; /* Is the CPU halted ? */
+ int busreq;
+ int trap_level;
+ int shutdown;
+
+ int icount;
+ char seg_prefix;
+ UINT8 prefix_seg;
+ unsigned ea;
+ UINT16 eo; /* HJB 12/13/98 effective offset of the address (before segment is added) */
+ UINT8 ea_seg; /* effective segment of the address */
+};
+#define i8086_state i80286_state
+#define i8086basicregs i80286basicregs
+
+struct i80x86_timing
+{
+ int id;
+
+ UINT8 exception, iret; /* exception, IRET */
+ UINT8 int3, int_imm, into_nt, into_t; /* INTs */
+ UINT8 override; /* segment overrides */
+ UINT8 flag_ops, lahf, sahf; /* flag operations */
+ UINT8 aaa, aas, aam, aad; /* arithmetic adjusts */
+ UINT8 daa, das; /* decimal adjusts */
+ UINT8 cbw, cwd; /* sign extension */
+ UINT8 hlt, load_ptr, lea, nop, wait, xlat; /* misc */
+
+ UINT8 jmp_short, jmp_near, jmp_far; /* direct JMPs */
+ UINT8 jmp_r16, jmp_m16, jmp_m32; /* indirect JMPs */
+ UINT8 call_near, call_far; /* direct CALLs */
+ UINT8 call_r16, call_m16, call_m32; /* indirect CALLs */
+ UINT8 ret_near, ret_far, ret_near_imm, ret_far_imm; /* returns */
+ UINT8 jcc_nt, jcc_t, jcxz_nt, jcxz_t; /* conditional JMPs */
+ UINT8 loop_nt, loop_t, loope_nt, loope_t; /* loops */
+
+ UINT8 in_imm8, in_imm16, in_dx8, in_dx16; /* port reads */
+ UINT8 out_imm8, out_imm16, out_dx8, out_dx16; /* port writes */
+
+ UINT8 mov_rr8, mov_rm8, mov_mr8; /* move, 8-bit */
+ UINT8 mov_ri8, mov_mi8; /* move, 8-bit immediate */
+ UINT8 mov_rr16, mov_rm16, mov_mr16; /* move, 16-bit */
+ UINT8 mov_ri16, mov_mi16; /* move, 16-bit immediate */
+ UINT8 mov_am8, mov_am16, mov_ma8, mov_ma16; /* move, AL/AX memory */
+ UINT8 mov_sr, mov_sm, mov_rs, mov_ms; /* move, segment registers */
+ UINT8 xchg_rr8, xchg_rm8; /* exchange, 8-bit */
+ UINT8 xchg_rr16, xchg_rm16, xchg_ar16; /* exchange, 16-bit */
+
+ UINT8 push_r16, push_m16, push_seg, pushf; /* pushes */
+ UINT8 pop_r16, pop_m16, pop_seg, popf; /* pops */
+
+ UINT8 alu_rr8, alu_rm8, alu_mr8; /* ALU ops, 8-bit */
+ UINT8 alu_ri8, alu_mi8, alu_mi8_ro; /* ALU ops, 8-bit immediate */
+ UINT8 alu_rr16, alu_rm16, alu_mr16; /* ALU ops, 16-bit */
+ UINT8 alu_ri16, alu_mi16, alu_mi16_ro; /* ALU ops, 16-bit immediate */
+ UINT8 alu_r16i8, alu_m16i8, alu_m16i8_ro; /* ALU ops, 16-bit w/8-bit immediate */
+ UINT8 mul_r8, mul_r16, mul_m8, mul_m16; /* MUL */
+ UINT8 imul_r8, imul_r16, imul_m8, imul_m16; /* IMUL */
+ UINT8 div_r8, div_r16, div_m8, div_m16; /* DIV */
+ UINT8 idiv_r8, idiv_r16, idiv_m8, idiv_m16; /* IDIV */
+ UINT8 incdec_r8, incdec_r16, incdec_m8, incdec_m16; /* INC/DEC */
+ UINT8 negnot_r8, negnot_r16, negnot_m8, negnot_m16; /* NEG/NOT */
+
+ UINT8 rot_reg_1, rot_reg_base, rot_reg_bit; /* reg shift/rotate */
+ UINT8 rot_m8_1, rot_m8_base, rot_m8_bit; /* m8 shift/rotate */
+ UINT8 rot_m16_1, rot_m16_base, rot_m16_bit; /* m16 shift/rotate */
+
+ UINT8 cmps8, rep_cmps8_base, rep_cmps8_count; /* CMPS 8-bit */
+ UINT8 cmps16, rep_cmps16_base, rep_cmps16_count; /* CMPS 16-bit */
+ UINT8 scas8, rep_scas8_base, rep_scas8_count; /* SCAS 8-bit */
+ UINT8 scas16, rep_scas16_base, rep_scas16_count; /* SCAS 16-bit */
+ UINT8 lods8, rep_lods8_base, rep_lods8_count; /* LODS 8-bit */
+ UINT8 lods16, rep_lods16_base, rep_lods16_count; /* LODS 16-bit */
+ UINT8 stos8, rep_stos8_base, rep_stos8_count; /* STOS 8-bit */
+ UINT8 stos16, rep_stos16_base, rep_stos16_count; /* STOS 16-bit */
+ UINT8 movs8, rep_movs8_base, rep_movs8_count; /* MOVS 8-bit */
+ UINT8 movs16, rep_movs16_base, rep_movs16_count; /* MOVS 16-bit */
+
+ void * check1; /* marker to make sure we line up */
+
+ UINT8 ins8, rep_ins8_base, rep_ins8_count; /* (80186) INS 8-bit */
+ UINT8 ins16, rep_ins16_base, rep_ins16_count; /* (80186) INS 16-bit */
+ UINT8 outs8, rep_outs8_base, rep_outs8_count; /* (80186) OUTS 8-bit */
+ UINT8 outs16, rep_outs16_base, rep_outs16_count; /* (80186) OUTS 16-bit */
+ UINT8 push_imm, pusha, popa; /* (80186) PUSH immediate, PUSHA/POPA */
+ UINT8 imul_rri8, imul_rmi8; /* (80186) IMUL immediate 8-bit */
+ UINT8 imul_rri16, imul_rmi16; /* (80186) IMUL immediate 16-bit */
+ UINT8 enter0, enter1, enter_base, enter_count, leave; /* (80186) ENTER/LEAVE */
+ UINT8 bound; /* (80186) BOUND */
+
+ void * check2; /* marker to make sure we line up */
+};
+
+#endif
--- /dev/null
+#include "./i86priv.h"
+#include "./i86.h"
+
+//#ifdef I80286
+//#undef GetMemB
+//#undef GetMemW
+//#undef PutMemB
+//#undef PutMemW
+//#undef PUSH
+//#undef POP
+//#undef IOPL
+//#undef NT
+//#undef xF
+
+//#define GetMemB(Seg,Off) (read_mem_byte(GetMemAddr(cpustate,Seg,Off,1,I80286_READ)))
+//#define GetMemW(Seg,Off) (read_mem_word(GetMemAddr(cpustate,Seg,Off,2,I80286_READ)))
+//#define PutMemB(Seg,Off,x) write_mem_byte(GetMemAddr(cpustate,Seg,Off,1,I80286_WRITE), (x))
+//#define PutMemW(Seg,Off,x) write_mem_word(GetMemAddr(cpustate,Seg,Off,2,I80286_WRITE), (x))
+
+//#define PUSH(val) { if(PM) i80286_check_permission(cpustate, SS, cpustate->regs.w[SP]-2, I80286_WORD, I80286_WRITE); cpustate->regs.w[SP] -= 2; WriteWord(((cpustate->base[SS] + cpustate->regs.w[SP]) & AMASK), val); }
+//#define POP(var) { if(PM) i80286_check_permission(cpustate, SS, cpustate->regs.w[SP], I80286_WORD, I80286_READ); cpustate->regs.w[SP] += 2; var = ReadWord(((cpustate->base[SS] + ((cpustate->regs.w[SP]-2) & 0xffff)) & AMASK)); }
+
+//#define IOPL ((cpustate->flags&0x3000)>>12)
+//#define NT ((cpustate->flags&0x4000)>>14)
+//#define xF (0)
+//#endif
+//#include "./instr86.h"
+#include "./table86.h"
+//#include "./instr186.h"
+#include "./table186.h"
+#include "./instr286.h"
+#include "./table286.h"
+//#include "./instrv30.h"
+#include "./tablev30.h"
+
+#include "ix86_real.h"
+
+void X86_OPS::CPU_EXECUTE( i8086 )
+{
+ if (cpustate->halted || cpustate->busreq)
+ {
+#ifdef SINGLE_MODE_DMA
+ if(cpustate->dma != NULL) {
+ cpustate->dma->do_dma();
+ }
+#endif
+ if (icount == -1) {
+ int passed_icount = max(1, cpustate->extra_cycles);
+ // this is main cpu, cpustate->icount is not used
+ /*cpustate->icount = */cpustate->extra_cycles = 0;
+ return passed_icount;
+ } else {
+ cpustate->icount += icount;
+ int base_icount = cpustate->icount;
+
+ /* adjust for any interrupts that came in */
+ cpustate->icount -= cpustate->extra_cycles;
+ cpustate->extra_cycles = 0;
+
+ /* if busreq is raised, spin cpu while remained clock */
+ if (cpustate->icount > 0) {
+ cpustate->icount = 0;
+ }
+ return base_icount - cpustate->icount;
+ }
+ }
+
+ if (icount == -1) {
+ cpustate->icount = 1;
+ } else {
+ cpustate->icount += icount;
+ }
+ int base_icount = cpustate->icount;
+
+ /* copy over the cycle counts if they're not correct */
+ if (timing.id != 8086)
+ timing = i8086_cycles;
+
+ /* adjust for any interrupts that came in */
+ cpustate->icount -= cpustate->extra_cycles;
+ cpustate->extra_cycles = 0;
+
+ /* run until we're out */
+ while (cpustate->icount > 0 && !cpustate->busreq)
+ {
+#ifdef USE_DEBUGGER
+ bool now_debugging = cpustate->debugger->now_debugging;
+ if(now_debugging) {
+ cpustate->debugger->check_break_points(cpustate->pc);
+ if(cpustate->debugger->now_suspended) {
+ cpustate->emu->mute_sound();
+ while(cpustate->debugger->now_debugging && cpustate->debugger->now_suspended) {
+ cpustate->emu->sleep(10);
+ }
+ }
+ if(cpustate->debugger->now_debugging) {
+ cpustate->program = cpustate->io = cpustate->debugger;
+ } else {
+ now_debugging = false;
+ }
+ cpustate->seg_prefix = FALSE;
+ cpustate->prevpc = cpustate->pc;
+ TABLE86;
+ if(now_debugging) {
+ if(!cpustate->debugger->now_going) {
+ cpustate->debugger->now_suspended = true;
+ }
+ cpustate->program = cpustate->program_stored;
+ cpustate->io = cpustate->io_stored;
+ }
+ } else {
+#endif
+ cpustate->seg_prefix = FALSE;
+ cpustate->prevpc = cpustate->pc;
+ TABLE86;
+#ifdef USE_DEBUGGER
+ }
+#endif
+#ifdef SINGLE_MODE_DMA
+ if(cpustate->dma != NULL) {
+ cpustate->dma->do_dma();
+ }
+#endif
+ /* adjust for any interrupts that came in */
+ cpustate->icount -= cpustate->extra_cycles;
+ cpustate->extra_cycles = 0;
+ }
+
+ /* if busreq is raised, spin cpu while remained clock */
+ if (cpustate->icount > 0 && cpustate->busreq) {
+ cpustate->icount = 0;
+ }
+ return base_icount - cpustate->icount;
+}
+
+void X86_OPS::CPU_EXECUTE( i80186 )
+{
+ if (cpustate->halted || cpustate->busreq)
+ {
+#ifdef SINGLE_MODE_DMA
+ if (cpustate->dma != NULL) {
+ cpustate->dma->do_dma();
+ }
+#endif
+ if (icount == -1) {
+ int passed_icount = max(1, cpustate->extra_cycles);
+ // this is main cpu, cpustate->icount is not used
+ /*cpustate->icount = */cpustate->extra_cycles = 0;
+ return passed_icount;
+ } else {
+ cpustate->icount += icount;
+ int base_icount = cpustate->icount;
+
+ /* adjust for any interrupts that came in */
+ cpustate->icount -= cpustate->extra_cycles;
+ cpustate->extra_cycles = 0;
+
+ /* if busreq is raised, spin cpu while remained clock */
+ if (cpustate->icount > 0) {
+ cpustate->icount = 0;
+ }
+ return base_icount - cpustate->icount;
+ }
+ }
+
+ if (icount == -1) {
+ cpustate->icount = 1;
+ } else {
+ cpustate->icount += icount;
+ }
+ int base_icount = cpustate->icount;
+
+ /* copy over the cycle counts if they're not correct */
+ if (timing.id != 80186)
+ timing = i80186_cycles;
+
+ /* adjust for any interrupts that came in */
+ cpustate->icount -= cpustate->extra_cycles;
+ cpustate->extra_cycles = 0;
+
+ /* run until we're out */
+ while (cpustate->icount > 0 && !cpustate->busreq)
+ {
+#ifdef USE_DEBUGGER
+ bool now_debugging = cpustate->debugger->now_debugging;
+ if(now_debugging) {
+ cpustate->debugger->check_break_points(cpustate->pc);
+ if(cpustate->debugger->now_suspended) {
+ cpustate->emu->mute_sound();
+ while(cpustate->debugger->now_debugging && cpustate->debugger->now_suspended) {
+ cpustate->emu->sleep(10);
+ }
+ }
+ if(cpustate->debugger->now_debugging) {
+ cpustate->program = cpustate->io = cpustate->debugger;
+ } else {
+ now_debugging = false;
+ }
+ cpustate->seg_prefix = FALSE;
+ cpustate->prevpc = cpustate->pc;
+ TABLE186;
+ if(now_debugging) {
+ if(!cpustate->debugger->now_going) {
+ cpustate->debugger->now_suspended = true;
+ }
+ cpustate->program = cpustate->program_stored;
+ cpustate->io = cpustate->io_stored;
+ }
+ } else {
+#endif
+ cpustate->seg_prefix = FALSE;
+ cpustate->prevpc = cpustate->pc;
+ TABLE186;
+#ifdef USE_DEBUGGER
+ }
+#endif
+#ifdef SINGLE_MODE_DMA
+ if (cpustate->dma != NULL) {
+ cpustate->dma->do_dma();
+ }
+#endif
+ /* adjust for any interrupts that came in */
+ cpustate->icount -= cpustate->extra_cycles;
+ cpustate->extra_cycles = 0;
+ }
+
+ /* if busreq is raised, spin cpu while remained clock */
+ if (cpustate->icount > 0 && cpustate->busreq) {
+ cpustate->icount = 0;
+ }
+ return base_icount - cpustate->icount;
+}
+
+void X86_OPS::CPU_EXECUTE( i80286 )
+{
+ if (cpustate->halted || cpustate->busreq)
+ {
+#ifdef SINGLE_MODE_DMA
+ if (cpustate->dma != NULL) {
+ cpustate->dma->do_dma();
+ }
+#endif
+ if (icount == -1) {
+ int passed_icount = max(1, cpustate->extra_cycles);
+ // this is main cpu, cpustate->icount is not used
+ /*cpustate->icount = */cpustate->extra_cycles = 0;
+ return passed_icount;
+ } else {
+ cpustate->icount += icount;
+ int base_icount = cpustate->icount;
+
+ /* adjust for any interrupts that came in */
+ cpustate->icount -= cpustate->extra_cycles;
+ cpustate->extra_cycles = 0;
+
+ /* if busreq is raised, spin cpu while remained clock */
+ if (cpustate->icount > 0) {
+ cpustate->icount = 0;
+ }
+ return base_icount - cpustate->icount;
+ }
+ }
+
+ if (icount == -1) {
+ cpustate->icount = 1;
+ } else {
+ cpustate->icount += icount;
+ }
+ int base_icount = cpustate->icount;
+
+ /* copy over the cycle counts if they're not correct */
+ if (timing.id != 80286)
+ timing = i80286_cycles;
+
+ /* adjust for any interrupts that came in */
+ cpustate->icount -= cpustate->extra_cycles;
+ cpustate->extra_cycles = 0;
+
+ /* run until we're out */
+ while(cpustate->icount > 0 && !cpustate->busreq)
+ {
+#ifdef USE_DEBUGGER
+ bool now_debugging = cpustate->debugger->now_debugging;
+ if(now_debugging) {
+ cpustate->debugger->check_break_points(cpustate->pc);
+ if(cpustate->debugger->now_suspended) {
+ cpustate->emu->mute_sound();
+ while(cpustate->debugger->now_debugging && cpustate->debugger->now_suspended) {
+ cpustate->emu->sleep(10);
+ }
+ }
+ if(cpustate->debugger->now_debugging) {
+ cpustate->program = cpustate->io = cpustate->debugger;
+ } else {
+ now_debugging = false;
+ }
+ cpustate->seg_prefix=FALSE;
+ try
+ {
+ if (PM && ((cpustate->pc-cpustate->base[CS]) > cpustate->limit[CS]))
+ throw TRAP(GENERAL_PROTECTION_FAULT, cpustate->sregs[CS] & ~3);
+ cpustate->prevpc = cpustate->pc;
+
+ TABLE286 // call instruction
+ }
+ catch (UINT32 e)
+ {
+ i80286_trap2(cpustate,e);
+ }
+ if(now_debugging) {
+ if(!cpustate->debugger->now_going) {
+ cpustate->debugger->now_suspended = true;
+ }
+ cpustate->program = cpustate->program_stored;
+ cpustate->io = cpustate->io_stored;
+ }
+ } else {
+#endif
+ cpustate->seg_prefix=FALSE;
+ try
+ {
+ if (PM && ((cpustate->pc-cpustate->base[CS]) > cpustate->limit[CS]))
+ throw TRAP(GENERAL_PROTECTION_FAULT, cpustate->sregs[CS] & ~3);
+ cpustate->prevpc = cpustate->pc;
+
+ TABLE286 // call instruction
+ }
+ catch (UINT32 e)
+ {
+ i80286_trap2(cpustate,e);
+ }
+#ifdef USE_DEBUGGER
+ }
+#endif
+#ifdef SINGLE_MODE_DMA
+ if (cpustate->dma != NULL) {
+ cpustate->dma->do_dma();
+ }
+#endif
+ /* adjust for any interrupts that came in */
+ cpustate->icount -= cpustate->extra_cycles;
+ cpustate->extra_cycles = 0;
+ }
+
+ /* if busreq is raised, spin cpu while remained clock */
+ if (cpustate->icount > 0 && cpustate->busreq) {
+ cpustate->icount = 0;
+ }
+ return base_icount - cpustate->icount;
+}
+
+void X86_OPS::CPU_EXECUTE( v30 )
+{
+ if (cpustate->halted || cpustate->busreq)
+ {
+#ifdef SINGLE_MODE_DMA
+ if (cpustate->dma != NULL) {
+ cpustate->dma->do_dma();
+ }
+#endif
+ if (icount == -1) {
+ int passed_icount = max(1, cpustate->extra_cycles);
+ // this is main cpu, cpustate->icount is not used
+ /*cpustate->icount = */cpustate->extra_cycles = 0;
+ return passed_icount;
+ } else {
+ cpustate->icount += icount;
+ int base_icount = cpustate->icount;
+
+ /* adjust for any interrupts that came in */
+ cpustate->icount -= cpustate->extra_cycles;
+ cpustate->extra_cycles = 0;
+
+ /* if busreq is raised, spin cpu while remained clock */
+ if (cpustate->icount > 0) {
+ cpustate->icount = 0;
+ }
+ return base_icount - cpustate->icount;
+ }
+ }
+
+ if (icount == -1) {
+ cpustate->icount = 1;
+ } else {
+ cpustate->icount += icount;
+ }
+ int base_icount = cpustate->icount;
+
+ /* copy over the cycle counts if they're not correct */
+ if (timing.id != 80186)
+ timing = i80186_cycles;
+
+ /* adjust for any interrupts that came in */
+ cpustate->icount -= cpustate->extra_cycles;
+ cpustate->extra_cycles = 0;
+
+ /* run until we're out */
+ while (cpustate->icount > 0 && !cpustate->busreq)
+ {
+#ifdef USE_DEBUGGER
+ bool now_debugging = cpustate->debugger->now_debugging;
+ if(now_debugging) {
+ cpustate->debugger->check_break_points(cpustate->pc);
+ if(cpustate->debugger->now_suspended) {
+ cpustate->emu->mute_sound();
+ while(cpustate->debugger->now_debugging && cpustate->debugger->now_suspended) {
+ cpustate->emu->sleep(10);
+ }
+ }
+ if(cpustate->debugger->now_debugging) {
+ cpustate->program = cpustate->io = cpustate->debugger;
+ } else {
+ now_debugging = false;
+ }
+ cpustate->seg_prefix = FALSE;
+ cpustate->prevpc = cpustate->pc;
+ TABLEV30;
+ if(now_debugging) {
+ if(!cpustate->debugger->now_going) {
+ cpustate->debugger->now_suspended = true;
+ }
+ cpustate->program = cpustate->program_stored;
+ cpustate->io = cpustate->io_stored;
+ }
+ } else {
+#endif
+ cpustate->seg_prefix = FALSE;
+ cpustate->prevpc = cpustate->pc;
+ TABLEV30;
+#ifdef USE_DEBUGGER
+ }
+#endif
+#ifdef SINGLE_MODE_DMA
+ if (cpustate->dma != NULL) {
+ cpustate->dma->do_dma();
+ }
+#endif
+ /* adjust for any interrupts that came in */
+ cpustate->icount -= cpustate->extra_cycles;
+ cpustate->extra_cycles = 0;
+ }
+
+ /* if busreq is raised, spin cpu while remained clock */
+ if (cpustate->icount > 0 && cpustate->busreq) {
+ cpustate->icount = 0;
+ }
+ return base_icount - cpustate->icount;
+}
+
+void X86_OPS::set_irq_line_v30(int irqline, int state)
+{
+ if (state != CLEAR_LINE && cpustate->halted)
+ {
+ cpustate->halted = 0;
+ }
+
+ if (irqline == INPUT_LINE_NMI)
+ {
+ if (cpustate->nmi_state == state)
+ return;
+ cpustate->nmi_state = state;
+
+ /* on a rising edge, signal the NMI */
+ if (state != CLEAR_LINE)
+ {
+ PREFIXV30(_interrupt)(cpustate, I8086_NMI_INT_VECTOR);
+ cpustate->nmi_state = CLEAR_LINE;
+ }
+ }
+ else
+ {
+ cpustate->irq_state = state;
+
+ /* if the IF is set, signal an interrupt */
+ if (state != CLEAR_LINE && cpustate->IF) {
+ PREFIXV30(_interrupt)(cpustate, (UINT32)-1);
+ cpustate->irq_state = CLEAR_LINE;
+ }
+ }
+}
+
--- /dev/null
+#ifndef __LIBNEWDEV_LIBCPUI86_IX86_OPDEF_H__
+#define __LIBNEWDEV_LIBCPUI86_IX86_OPDEF_H__
+
+#include "./ix86_cpustat.h"
+enum {
+ IX86_CPU_I8086 = 0,
+ IX86_CPU_I8088,
+ IX86_CPU_I80C86,
+ IX86_CPU_I80C88,
+ IX86_CPU_I80186,
+ IX86_CPU_I80188,
+ IX86_CPU_I80286,
+ IX86_CPU_V30,
+ IX86_CPU_V20,
+ IX86_CPU_V30MX,
+ IX86_CPU_V40,
+ IX86_CPU_V50,
+ IX86_CPU_V33,
+ IX86_CPU_V25,
+ IX86_CPU_V35,
+};
+
+class DEVICE;
+class EMU;
+class DEBUGGER;
+class IX86_OPS_BASE {
+protected:
+ DEVICE *d_mem;
+ DEVICE *d_pic;
+ DEVICE *d_io;
+ DEVICE *d_dma;
+ DEVICE *d_bios;
+ EMU *emu;
+ DEBUGGER *debugger;
+ UINT8 parity_table[256];
+ struct i80x86_timing timing;
+ void i80286_urinit(void);
+ i80286_state *cpustate;
+ public:
+ IX86_OPS_BASE() {
+ }
+ IX86_OPS_BASE() {};
+
+ i86_state *cpu_init_i8086();
+ i86_state *cpu_init_i8088();
+ i86_state *cpu_init_i80186();
+ i86_state *cpu_init_i80286();
+ i86_state *cpu_init_v30();
+ virtual void CPU_EXECUTE( i8086 );
+ void set_irq_line_86(int irqline, int state);
+ void cpu_reset_i8086();
+
+ virtual void CPU_EXECUTE( i80186 );
+ void set_irq_line_186(int irqline, int state);
+ void cpu_reset_i80186();
+
+ virtual void CPU_EXECUTE( i80286 );
+ void set_irq_line_286(int irqline, int state);
+ void cpu_reset_i80286();
+ void i80286_set_a20_line(int state);
+ virtual void CPU_EXECUTE( v30 );
+ void set_irq_line_v30(int irqline, int state);
+ void cpu_reset_v30();
+
+ virtual void PREFIX186(_pusha)(); /* Opcode 0x60 */
+ virtual void PREFIX186(_popa)(); /* Opcode 0x61 */
+ virtual void PREFIX186(_insb)(); /* Opcode 0x6c */
+ virtual void PREFIX186(_insw)(); /* Opcode 0x6d */
+ virtual void PREFIX186(_outsb)(); /* Opcode 0x6e */
+ virtual void PREFIX186(_outsw)(); /* Opcode 0x6f */
+ virtual void PREFIX186(_enter)(); /* Opcode 0xc8 */
+
+ virtual void PREFIX86(_rotate_shift_Byte)(unsigned ModRM, unsigned count, unsigned src);
+ virtual void PREFIX86(_rotate_shift_Word)(unsigned ModRM, unsigned count, unsigned src);
+
+
+ virtual void PREFIX86(_pop_es)(); /* Opcode 0x07 */
+ virtual void PREFIX86(_pop_cs)(); /* Opcode 0x0f */
+ virtual void PREFIX86(_push_sp)(); /* Opcode 0x54 */
+ virtual void PREFIX86(_call_far)();
+ virtual void PREFIX86(_wait)(); /* Opcode 0x9b */
+
+ virtual void PREFIX86(_popf)(); /* Opcode 0x9d */
+ virtual void PREFIX86(_les_dw)(); /* Opcode 0xc4 */
+ virtual void PREFIX86(_lds_dw)(); /* Opcode 0xc5 */
+ virtual void PREFIX86(_retf_d16)(); /* Opcode 0xca */
+ virtual void PREFIX86(_retf)(); /* Opcode 0xcb */
+
+ virtual void PREFIX86(_int)(); /* Opcode 0xcd */
+ virtual void PREFIX86(_into)(); /* Opcode 0xce */
+ virtual void PREFIX86(_iret)(); /* Opcode 0xcf */
+ virtual void PREFIX86(_rotshft_bcl)(); /* Opcode 0xd2 */
+ virtual void PREFIX86(_escape)(); /* Opcodes 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde and 0xdf */
+ virtual void PREFIX86(_inal)(); /* Opcode 0xe4 */
+ virtual void PREFIX86(_inax)(); /* Opcode 0xe5 */
+ virtual void PREFIX86(_outal)(); /* Opcode 0xe6 */
+ virtual void PREFIX86(_outax)(); /* Opcode 0xe7 */
+ virtual void PREFIX86(_call_d16)(); /* Opcode 0xe8 */
+ virtual void PREFIX86(_jmp_d16)(); /* Opcode 0xe9 */
+ virtual void PREFIX86(_jmp_far)(); /* Opcode 0xea */
+ virtual void PREFIX86(_jmp_d8)(); /* Opcode 0xeb */
+ virtual void PREFIX86(_inaldx)(); /* Opcode 0xec */
+ virtual void PREFIX86(_inaxdx)(); /* Opcode 0xed */
+ virtual void PREFIX86(_outdxal)(); /* Opcode 0xee */
+ virtual void PREFIX86(_outdxax)(); /* Opcode 0xef */
+ virtual void PREFIX86(_lock)(); /* Opcode 0xf0 */
+ virtual void PREFIX86(_hlt)(); /* Opcode 0xf4 */
+ virtual void PREFIX86(_cli)(); /* Opcode 0xfa */
+ virtual void PREFIX86(_ffpre)(); /* Opcode 0xff */
+ virtual void PREFIX86(_invalid)();
+ virtual void PREFIX86(_invalid_2b)();
+
+public:
+ // Not Virtual
+
+ // 80186
+ void PREFIX186(_bound)(); /* Opcode 0x62 */
+ void PREFIX186(_push_d16)(); /* Opcode 0x68 */
+ void PREFIX186(_imul_d16)(); /* Opcode 0x69 */
+ void PREFIX186(_push_d8)(); /* Opcode 0x6a */
+ void PREFIX186(_imul_d8)(); /* Opcode 0x6b */
+ void PREFIX186(_rotshft_bd8)(); /* Opcode 0xc0 */
+ void PREFIX186(_rotshft_wd8)(); /* Opcode 0xc1 */
+ void PREFIX186(_leave)(); /* Opcode 0xc9 */
+ void PREFIX186(_rotshft_bcl)(); /* Opcode 0xd2 */
+ void PREFIX186(_rotshft_wcl)(); /* Opcode 0xd3 */
+// 80286
+ void PREFIX286(_0fpre)();
+ void PREFIX286(_arpl)(); /* 0x63 */
+
+ void PREFIX286(_popf)();
+ void PREFIX286(_iret)();
+ void PREFIX286(_retf_d16)();
+ void PREFIX286(_retf)();
+ void PREFIX286(_escape)(); /* Opcodes 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde */
+ void PREFIX286(_escape_7)(); /* Opcode 0xdf */
+// V30
+ void PREFIXV30(_0fpre)(); /* Opcode 0x0f */
+ void PREFIXV30(_brkn)(); /* Opcode 0x63 BRKN - Break to Native Mode */
+ void PREFIXV30(repc)(int flagval);
+ void PREFIXV30(_repnc)(); /* Opcode 0x64 */
+ void PREFIXV30(_repc)(); /* Opcode 0x65 */
+ void PREFIXV30(_aad)(); /* Opcode 0xd5 */
+ void PREFIXV30(_setalc)(); /* Opcode 0xd6 */
+ void PREFIXV30(_brks)(); /* Opcode 0xf1 - Break to Security Mode */
+// 8086
+
+ void PREFIX86(_add_br8)(); /* Opcode 0x00 */
+ void PREFIX86(_add_wr16)(); /* Opcode 0x01 */
+ void PREFIX86(_add_r8b)(); /* Opcode 0x02 */
+ void PREFIX86(_add_r16w)(); /* Opcode 0x03 */
+ void PREFIX86(_add_ald8)(); /* Opcode 0x04 */
+ void PREFIX86(_add_axd16)(); /* Opcode 0x05 */
+ void PREFIX86(_push_es)(); /* Opcode 0x06 */
+
+ void PREFIX86(_or_br8)(); /* Opcode 0x08 */
+ void PREFIX86(_or_wr16)(); /* Opcode 0x09 */
+ void PREFIX86(_or_r8b)(); /* Opcode 0x0a */
+ void PREFIX86(_or_r16w)(); /* Opcode 0x0b */
+ void PREFIX86(_or_ald8)(); /* Opcode 0x0c */
+ void PREFIX86(_or_axd16)(); /* Opcode 0x0d */
+ void PREFIX86(_push_cs)(); /* Opcode 0x0e */
+
+ void PREFIX86(_adc_br8)(); /* Opcode 0x10 */
+ void PREFIX86(_adc_wr16)(); /* Opcode 0x11 */
+ void PREFIX86(_adc_r8b)(); /* Opcode 0x12 */
+ void PREFIX86(_adc_r16w)(); /* Opcode 0x13 */
+ void PREFIX86(_adc_ald8)(); /* Opcode 0x14 */
+ void PREFIX86(_adc_axd16)(); /* Opcode 0x15 */
+
+ void PREFIX86(_push_ss)(); /* Opcode 0x16 */
+ void PREFIX86(_sbb_br8)(); /* Opcode 0x18 */
+ void PREFIX86(_sbb_wr16)(); /* Opcode 0x19 */
+ void PREFIX86(_sbb_r8b)(); /* Opcode 0x1a */
+ void PREFIX86(_sbb_r16w)(); /* Opcode 0x1b */
+ void PREFIX86(_sbb_ald8)(); /* Opcode 0x1c */
+ void PREFIX86(_sbb_axd16)(); /* Opcode 0x1d */
+ void PREFIX86(_push_ds)(); /* Opcode 0x1e */
+ void PREFIX86(_pop_ds)(); /* Opcode 0x1f */
+ void PREFIX86(_and_br8)(); /* Opcode 0x20 */
+ void PREFIX86(_and_wr16)(); /* Opcode 0x21 */
+ void PREFIX86(_and_r8b)(); /* Opcode 0x22 */
+ void PREFIX86(_and_r16w)(); /* Opcode 0x23 */
+ void PREFIX86(_and_ald8)(); /* Opcode 0x24 */
+ void PREFIX86(_and_axd16)(); /* Opcode 0x25 */
+ void PREFIX86(_daa)(); /* Opcode 0x27 */
+ void PREFIX86(_sub_br8)(); /* Opcode 0x28 */
+ void PREFIX86(_sub_wr16)(); /* Opcode 0x29 */
+ void PREFIX86(_sub_r8b)(); /* Opcode 0x2a */
+ void PREFIX86(_sub_r16w)(); /* Opcode 0x2b */
+ void PREFIX86(_sub_ald8)(); /* Opcode 0x2c */
+ void PREFIX86(_sub_axd16)(); /* Opcode 0x2d */
+ void PREFIX86(_das)(); /* Opcode 0x2f */
+ void PREFIX86(_xor_br8)(); /* Opcode 0x30 */
+ void PREFIX86(_xor_wr16)(); /* Opcode 0x31 */
+ void PREFIX86(_xor_r8b)(); /* Opcode 0x32 */
+ void PREFIX86(_xor_r16w)(); /* Opcode 0x33 */
+ void PREFIX86(_xor_ald8)(); /* Opcode 0x34 */
+ void PREFIX86(_xor_axd16)(); /* Opcode 0x35 */
+ void PREFIX86(_aaa)(); /* Opcode 0x37 */
+ void PREFIX86(_cmp_br8)(); /* Opcode 0x38 */
+ void PREFIX86(_cmp_wr16)(); /* Opcode 0x39 */
+ void PREFIX86(_cmp_r8b)(); /* Opcode 0x3a */
+ void PREFIX86(_cmp_r16w)(); /* Opcode 0x3b */
+ void PREFIX86(_cmp_ald8)(); /* Opcode 0x3c */
+ void PREFIX86(_cmp_axd16)(); /* Opcode 0x3d */
+ void PREFIX86(_aas)(); /* Opcode 0x3f */
+ void PREFIX86(_inc_ax)(); /* Opcode 0x40 */
+ void PREFIX86(_inc_cx)(); /* Opcode 0x41 */
+ void PREFIX86(_inc_dx)(); /* Opcode 0x42 */
+
+ void PREFIX86(_inc_sp)(); /* Opcode 0x44 */
+ void PREFIX86(_inc_bp)(); /* Opcode 0x45 */
+ void PREFIX86(_inc_si)(); /* Opcode 0x46 */
+ void PREFIX86(_inc_di)(); /* Opcode 0x47 */
+ void PREFIX86(_dec_ax)(); /* Opcode 0x48 */
+ void PREFIX86(_dec_cx)(); /* Opcode 0x49 */
+ void PREFIX86(_dec_dx)(); /* Opcode 0x4a */
+ void PREFIX86(_dec_bx)(); /* Opcode 0x4b */
+ void PREFIX86(_dec_sp)(); /* Opcode 0x4c */
+ void PREFIX86(_dec_bp)(); /* Opcode 0x4d */
+ void PREFIX86(_dec_si)(); /* Opcode 0x4e */
+ void PREFIX86(_dec_di)(); /* Opcode 0x4f */
+ void PREFIX86(_push_ax)(); /* Opcode 0x50 */
+ void PREFIX86(_push_cx)(); /* Opcode 0x51 */
+ void PREFIX86(_push_dx)(); /* Opcode 0x52 */
+ void PREFIX86(_push_bx)(); /* Opcode 0x53 */
+
+ void PREFIX86(_push_bp)(); /* Opcode 0x55 */
+ void PREFIX86(_push_si)(); /* Opcode 0x56 */
+ void PREFIX86(_push_di)(); /* Opcode 0x57 */
+ void PREFIX86(_pop_ax)(); /* Opcode 0x58 */
+ void PREFIX86(_pop_cx)(); /* Opcode 0x59 */
+ void PREFIX86(_pop_dx)(); /* Opcode 0x5a */
+ void PREFIX86(_pop_bx)(); /* Opcode 0x5b */
+ void PREFIX86(_pop_sp)(); /* Opcode 0x5c */
+ void PREFIX86(_pop_bp)(); /* Opcode 0x5d */
+ void PREFIX86(_pop_si)(); /* Opcode 0x5e */
+ void PREFIX86(_pop_di)(); /* Opcode 0x5f */
+ void PREFIX86(_jo)(); /* Opcode 0x70 */
+ void PREFIX86(_jno)(); /* Opcode 0x71 */
+ void PREFIX86(_jb)(); /* Opcode 0x72 */
+ void PREFIX86(_jnb)(); /* Opcode 0x73 */
+ void PREFIX86(_jz)(); /* Opcode 0x74 */
+ void PREFIX86(_jnz)(); /* Opcode 0x75 */
+ void PREFIX86(_jbe)(); /* Opcode 0x76 */
+ void PREFIX86(_jnbe)(); /* Opcode 0x77 */
+ void PREFIX86(_js)(); /* Opcode 0x78 */
+ void PREFIX86(_jns)(); /* Opcode 0x79 */
+ void PREFIX86(_jp)(); /* Opcode 0x7a */
+ void PREFIX86(_jnp)(); /* Opcode 0x7b */
+ void PREFIX86(_jl)(); /* Opcode 0x7c */
+ void PREFIX86(_jnl)(); /* Opcode 0x7d */
+ void PREFIX86(_jle)(); /* Opcode 0x7e */
+ void PREFIX86(_jnle)(); /* Opcode 0x7f */
+ void PREFIX86(_80pre)(); /* Opcode 0x80 */
+ void PREFIX86(_81pre)(); /* Opcode 0x81 */
+ void PREFIX86(_82pre)(); /* Opcode 0x82 */
+ void PREFIX86(_83pre)(); /* Opcode 0x83 */
+ void PREFIX86(_test_br8)(); /* Opcode 0x84 */
+ void PREFIX86(_test_wr16)(); /* Opcode 0x85 */
+ void PREFIX86(_xchg_br8)(); /* Opcode 0x86 */
+ void PREFIX86(_xchg_wr16)(); /* Opcode 0x87 */
+ void PREFIX86(_mov_br8)(); /* Opcode 0x88 */
+ void PREFIX86(_mov_wr16)(); /* Opcode 0x89 */
+ void PREFIX86(_mov_r8b)(); /* Opcode 0x8a */
+ void PREFIX86(_mov_r16w)(); /* Opcode 0x8b */
+ void PREFIX86(_mov_wsreg)(); /* Opcode 0x8c */
+ void PREFIX86(_lea)(); /* Opcode 0x8d */
+ void PREFIX86(_popw)(); /* Opcode 0x8f */
+ void PREFIX86(_nop)(); /* Opcode 0x90 */
+ void PREFIX86(_xchg_axcx)(); /* Opcode 0x91 */
+ void PREFIX86(_xchg_axdx)(); /* Opcode 0x92 */
+ void PREFIX86(_xchg_axbx)(); /* Opcode 0x93 */
+ void PREFIX86(_xchg_axsp)(); /* Opcode 0x94 */
+ void PREFIX86(_xchg_axbp)(); /* Opcode 0x95 */
+ void PREFIX86(_xchg_axsi)(); /* Opcode 0x96 */
+ void PREFIX86(_xchg_axdi)(); /* Opcode 0x97 */
+ void PREFIX86(_cbw)(); /* Opcode 0x98 */
+ void PREFIX86(_cwd)(); /* Opcode 0x99 */
+
+ void PREFIX86(_sahf)(); /* Opcode 0x9e */
+ void PREFIX86(_lahf)(); /* Opcode 0x9f */
+ void PREFIX86(_mov_aldisp)(); /* Opcode 0xa0 */
+ void PREFIX86(_mov_axdisp)(); /* Opcode 0xa1 */
+ void PREFIX86(_mov_dispal)(); /* Opcode 0xa2 */
+ void PREFIX86(_mov_dispax)(); /* Opcode 0xa3 */
+ void PREFIX86(_movsb)(); /* Opcode 0xa4 */
+ void PREFIX86(_movsw)(); /* Opcode 0xa5 */
+ void PREFIX86(_cmpsb)(); /* Opcode 0xa6 */
+ void PREFIX86(_cmpsw)(); /* Opcode 0xa7 */
+ void PREFIX86(_test_ald8)(); /* Opcode 0xa8 */
+ void PREFIX86(_test_axd16)(); /* Opcode 0xa9 */
+ void PREFIX86(_stosb)(); /* Opcode 0xaa */
+ void PREFIX86(_stosw)(); /* Opcode 0xab */
+ void PREFIX86(_lodsb)(); /* Opcode 0xac */
+ void PREFIX86(_lodsw)(); /* Opcode 0xad */
+ void PREFIX86(_scasb)(); /* Opcode 0xae */
+ void PREFIX86(_scasw)(); /* Opcode 0xaf */
+ void PREFIX86(_mov_ald8)(); /* Opcode 0xb0 */
+ void PREFIX86(_mov_cld8)(); /* Opcode 0xb1 */
+ void PREFIX86(_mov_dld8)(); /* Opcode 0xb2 */
+ void PREFIX86(_mov_bld8)(); /* Opcode 0xb3 */
+ void PREFIX86(_mov_ahd8)(); /* Opcode 0xb4 */
+ void PREFIX86(_mov_chd8)(); /* Opcode 0xb5 */
+ void PREFIX86(_mov_dhd8)(); /* Opcode 0xb6 */
+ void PREFIX86(_mov_bhd8)(); /* Opcode 0xb7 */
+ void PREFIX86(_mov_axd16)(); /* Opcode 0xb8 */
+ void PREFIX86(_mov_cxd16)(); /* Opcode 0xb9 */
+ void PREFIX86(_mov_dxd16)(); /* Opcode 0xba */
+ void PREFIX86(_mov_bxd16)(); /* Opcode 0xbb */
+ void PREFIX86(_mov_spd16)(); /* Opcode 0xbc */
+ void PREFIX86(_mov_bpd16)(); /* Opcode 0xbd */
+ void PREFIX86(_mov_sid16)(); /* Opcode 0xbe */
+ void PREFIX86(_mov_did16)(); /* Opcode 0xbf */
+ void PREFIX86(_ret_d16)(); /* Opcode 0xc2 */
+ void PREFIX86(_ret)(); /* Opcode 0xc3 */
+
+ void PREFIX86(_mov_bd8)(); /* Opcode 0xc6 */
+ void PREFIX86(_mov_wd16)(); /* Opcode 0xc7 */
+
+ void PREFIX86(_rotshft_b)(); /* Opcode 0xd0 */
+ void PREFIX86(_rotshft_w)(); /* Opcode 0xd1 */
+
+ void PREFIX86(_aad)(); /* Opcode 0xd5 */
+ void PREFIX86(_xlat)(); /* Opcode 0xd7 */
+
+ void PREFIX86(_loopne)(); /* Opcode 0xe0 */
+ void PREFIX86(_loope)(); /* Opcode 0xe1 */
+ void PREFIX86(_loop)(); /* Opcode 0xe2 */
+ void PREFIX86(_jcxz)(); /* Opcode 0xe3 */
+
+ void PREFIX86(_jmp_d16)(); /* Opcode 0xe9 */
+ void PREFIX86(_jmp_far)(); /* Opcode 0xea */
+ void PREFIX86(_jmp_d8)(); /* Opcode 0xeb */
+
+ void PREFIX86(_cmc)(); /* Opcode 0xf5 */
+ void PREFIX86(_f6pre)();
+ void PREFIX86(_f7pre)();
+ void PREFIX86(_clc)(); /* Opcode 0xf8 */
+ void PREFIX86(_stc)(); /* Opcode 0xf9 */
+
+ void PREFIX86(_cld)(); /* Opcode 0xfc */
+ void PREFIX86(_std)(); /* Opcode 0xfd */
+ void PREFIX86(_fepre)(); /* Opcode 0xfe */
+
+ // PREFIX()
+ void PREFIX86(_pushf)(); /* Opcode 0x9c */
+ void PREFIX186(_pushf)(); /* Opcode 0x9c */
+ void PREFIX286(_pushf)(); /* Opcode 0x9c */
+ void PREFIXV30(_pushf)(); /* Opcode 0x9c */
+
+
+ void PREFIX86(_pop_ss)(); /* Opcode 0x17 */
+ void PREFIX86(_mov_sregw)(); /* Opcode 0x8e */
+ void PREFIX86(_sti)(); /* Opcode 0xfb */
+
+ void PREFIX186(_pop_ss)(); /* Opcode 0x17 */
+ void PREFIX186(_mov_sregw)(); /* Opcode 0x8e */
+ void PREFIX186(_sti)(); /* Opcode 0xfb */
+
+ void PREFIX286(_pop_ss)(); /* Opcode 0x17 */
+ void PREFIX286(_mov_sregw)(); /* Opcode 0x8e */
+ void PREFIX286(_sti)(); /* Opcode 0xfb */
+
+ void PREFIXV30(_pop_ss)(); /* Opcode 0x17 */
+ void PREFIXV30(_mov_sregw)(); /* Opcode 0x8e */
+ void PREFIXV30(_sti)(); /* Opcode 0xfb */
+
+ void PREFIX86(_es)(); /* Opcode 0x26 */
+ void PREFIX86(_cs)(); /* Opcode 0x2e */
+ void PREFIX86(_ss)(); /* Opcode 0x36 */
+ void PREFIX86(_ds)(); /* Opcode 0x3e */
+ void PREFIX86(_inc_bx)(); /* Opcode 0x43 */
+ void PREFIX86(_repne)(); /* Opcode 0xf2 */
+ void PREFIX86(_repe)(); /* Opcode 0xf3 */
+
+ void PREFIX186(_es)(); /* Opcode 0x26 */
+ void PREFIX186(_cs)(); /* Opcode 0x2e */
+ void PREFIX186(_ss)(); /* Opcode 0x36 */
+ void PREFIX186(_ds)(); /* Opcode 0x3e */
+ void PREFIX186(_inc_bx)(); /* Opcode 0x43 */
+ void PREFIX186(_repne)(); /* Opcode 0xf2 */
+ void PREFIX186(_repe)(); /* Opcode 0xf3 */
+
+ void PREFIX286(_es)(); /* Opcode 0x26 */
+ void PREFIX286(_cs)(); /* Opcode 0x2e */
+ void PREFIX286(_ss)(); /* Opcode 0x36 */
+ void PREFIX286(_ds)(); /* Opcode 0x3e */
+ void PREFIX286(_inc_bx)(); /* Opcode 0x43 */
+ void PREFIX286(_repne)(); /* Opcode 0xf2 */
+ void PREFIX286(_repe)(); /* Opcode 0xf3 */
+
+ void PREFIXV30(_es)(); /* Opcode 0x26 */
+ void PREFIXV30(_cs)(); /* Opcode 0x2e */
+ void PREFIXV30(_ss)(); /* Opcode 0x36 */
+ void PREFIXV30(_ds)(); /* Opcode 0x3e */
+ void PREFIXV30(_inc_bx)(); /* Opcode 0x43 */
+ void PREFIXV30(_repne)(); /* Opcode 0xf2 */
+ void PREFIXV30(_repe)(); /* Opcode 0xf3 */
+
+protected:
+ void i80286_trap2(UINT32 error);
+ void i80286_pop_seg(int reg);
+ void i80286_data_descriptor_full(int reg, UINT16 selector, int cpl, UINT32 trap, UINT16 offset, int size);
+ void i80286_data_descriptor(int reg, UINT16 selector);
+ void i80286_switch_task(UINT16 ntask, int type);
+ void i80286_code_descriptor(UINT16 selector, UINT16 offset, int gate);
+ void i80286_interrupt_descriptor(UINT16 number, int hwint, int error);
+ void i80286_load_flags(UINT16 flags, int cpl);
+ void i80286_check_permission(UINT8 check_seg, UINT32 offset, UINT16 size, i80286_operation operation);
+
+ void PREFIX86(_interrupt)(unsigned int_num);
+ void PREFIX86(_trap)();
+
+ void PREFIX186(_interrupt)(unsigned int_num);
+ void PREFIX186(_trap)();
+ void PREFIX286(_interrupt)(unsigned int_num);
+ void PREFIX286(_trap)();
+
+ void PREFIXV30(_interrupt)(unsigned int_num);
+ void PREFIXV30(_trap)();
+
+ void PREFIX86(rep)(int flagval);
+ void PREFIX186(rep)(int flagval);
+ void PREFIX286(rep)(int flagval);
+ void PREFIXV30(rep)(int flagval);
+public:
+};
+extern const struct i80x86_timing i8086_cycles;
+extern const struct i80x86_timing i80186_cycles;
+extern const struct i80x86_timing i80286_cycles;
+extern unsigned (IX86_OPS_BASE::*GetEA[192])();
+
+#endif
--- /dev/null
+static struct
+{
+ struct
+ {
+ WREGS w[256];
+ BREGS b[256];
+ } reg;
+ struct
+ {
+ WREGS w[256];
+ BREGS b[256];
+ } RM;
+} Mod_RM;
+
+#define RegWord(ModRM) cpustate->regs.w[Mod_RM.reg.w[ModRM]]
+#define RegByte(ModRM) cpustate->regs.b[Mod_RM.reg.b[ModRM]]
+
+#define GetRMWord(ModRM) \
+ ((ModRM) >= 0xc0 ? cpustate->regs.w[Mod_RM.RM.w[ModRM]] : ( (*GetEA[ModRM])(cpustate), ReadWord( cpustate->ea ) ))
+
+#define PutbackRMWord(ModRM,val) \
+{ \
+ if (ModRM >= 0xc0) cpustate->regs.w[Mod_RM.RM.w[ModRM]]=val; \
+ else WriteWord(cpustate->ea,val); \
+}
+
+#define GetnextRMWord ReadWord(cpustate->ea+2)
+
+#define GetRMWordOffset(offs) \
+ ReadWord(cpustate->ea-cpustate->eo+(UINT16)(cpustate->eo+offs))
+
+#define GetRMByteOffset(offs) \
+ ReadByte(cpustate->ea-cpustate->eo+(UINT16)(cpustate->eo+offs))
+
+#define PutRMWord(ModRM,val) \
+{ \
+ if (ModRM >= 0xc0) \
+ cpustate->regs.w[Mod_RM.RM.w[ModRM]]=val; \
+ else { \
+ (*GetEA[ModRM])(cpustate); \
+ WriteWord( cpustate->ea ,val); \
+ } \
+}
+
+#define PutRMWordOffset(offs, val) \
+ WriteWord( cpustate->ea-cpustate->eo+(UINT16)(cpustate->eo+offs), val)
+
+#define PutRMByteOffset(offs, val) \
+ WriteByte( cpustate->ea-cpustate->eo+(UINT16)(cpustate->eo+offs), val)
+
+#define PutImmRMWord(ModRM) \
+{ \
+ WORD val; \
+ if (ModRM >= 0xc0) \
+ FETCHWORD(cpustate->regs.w[Mod_RM.RM.w[ModRM]]) \
+ else { \
+ (*GetEA[ModRM])(cpustate); \
+ FETCHWORD(val) \
+ WriteWord( cpustate->ea , val); \
+ } \
+}
+
+#define GetRMByte(ModRM) \
+ ((ModRM) >= 0xc0 ? cpustate->regs.b[Mod_RM.RM.b[ModRM]] : ReadByte( (*GetEA[ModRM])(cpustate) ))
+
+#define PutRMByte(ModRM,val) \
+{ \
+ if (ModRM >= 0xc0) \
+ cpustate->regs.b[Mod_RM.RM.b[ModRM]]=val; \
+ else \
+ WriteByte( (*GetEA[ModRM])(cpustate) ,val); \
+}
+
+#define PutImmRMByte(ModRM) \
+{ \
+ if (ModRM >= 0xc0) \
+ cpustate->regs.b[Mod_RM.RM.b[ModRM]]=FETCH; \
+ else { \
+ (*GetEA[ModRM])(cpustate); \
+ WriteByte( cpustate->ea , FETCH ); \
+ } \
+}
+
+#define PutbackRMByte(ModRM,val) \
+{ \
+ if (ModRM >= 0xc0) \
+ cpustate->regs.b[Mod_RM.RM.b[ModRM]]=val; \
+ else \
+ WriteByte(cpustate->ea,val); \
+}
+
+#define DEF_br8(dst,src) \
+ unsigned ModRM = FETCHOP; \
+ unsigned src = RegByte(ModRM); \
+ unsigned dst = GetRMByte(ModRM)
+
+#define DEF_wr16(dst,src) \
+ unsigned ModRM = FETCHOP; \
+ unsigned src = RegWord(ModRM); \
+ unsigned dst = GetRMWord(ModRM)
+
+#define DEF_r8b(dst,src) \
+ unsigned ModRM = FETCHOP; \
+ unsigned dst = RegByte(ModRM); \
+ unsigned src = GetRMByte(ModRM)
+
+#define DEF_r16w(dst,src) \
+ unsigned ModRM = FETCHOP; \
+ unsigned dst = RegWord(ModRM); \
+ unsigned src = GetRMWord(ModRM)
+
+#define DEF_ald8(dst,src) \
+ unsigned src = FETCHOP; \
+ unsigned dst = cpustate->regs.b[AL]
+
+#define DEF_axd16(dst,src) \
+ unsigned src = FETCHOP; \
+ unsigned dst = cpustate->regs.w[AX]; \
+ src += (FETCH << 8)
--- /dev/null
+static struct
+{
+ struct
+ {
+ WREGS w[256];
+ BREGS b[256];
+ } reg;
+ struct
+ {
+ WREGS w[256];
+ BREGS b[256];
+ } RM;
+} Mod_RM;
+
+#define RegWord(ModRM) cpustate->regs.w[Mod_RM.reg.w[ModRM]]
+#define RegByte(ModRM) cpustate->regs.b[Mod_RM.reg.b[ModRM]]
+
+#define GetRMWord(ModRM) \
+ ((ModRM) >= 0xc0 ? cpustate->regs.w[Mod_RM.RM.w[ModRM]] : ( (*GetEA[ModRM])(cpustate), i80286_check_permission(cpustate, cpustate->ea_seg, cpustate->eo, I80286_WORD, I80286_READ), ReadWord( cpustate->ea ) ))
+
+#define PutbackRMWord(ModRM,val) \
+{ \
+ if (ModRM >= 0xc0) cpustate->regs.w[Mod_RM.RM.w[ModRM]]=val; \
+ else \
+ { \
+ i80286_check_permission(cpustate, cpustate->ea_seg, cpustate->eo, I80286_WORD, I80286_WRITE); \
+ WriteWord(cpustate->ea,val); \
+ } \
+}
+
+#define GetnextRMWord \
+ ( \
+ i80286_check_permission(cpustate, cpustate->ea_seg, cpustate->ea + 2 - cpustate->base[cpustate->ea_seg], I80286_WORD, I80286_READ), \
+ ReadWord(cpustate->ea+2) \
+ )
+
+#define GetRMWordOffset(offs) \
+ ( \
+ i80286_check_permission(cpustate, cpustate->ea_seg, (UINT16)(cpustate->eo+offs), I80286_WORD, I80286_READ), \
+ ReadWord(cpustate->ea-cpustate->eo+(UINT16)(cpustate->eo+offs)) \
+ )
+
+#define GetRMByteOffset(offs) \
+ ( \
+ i80286_check_permission(cpustate, cpustate->ea_seg, (UINT16)(cpustate->eo+offs), I80286_BYTE, I80286_READ), \
+ ReadByte(cpustate->ea-cpustate->eo+(UINT16)(cpustate->eo+offs)) \
+ )
+
+#define PutRMWord(ModRM,val) \
+{ \
+ if (ModRM >= 0xc0) \
+ cpustate->regs.w[Mod_RM.RM.w[ModRM]]=val; \
+ else { \
+ (*GetEA[ModRM])(cpustate); \
+ i80286_check_permission(cpustate, cpustate->ea_seg, cpustate->eo, I80286_WORD, I80286_WRITE); \
+ WriteWord( cpustate->ea ,val); \
+ } \
+}
+
+#define PutRMWordOffset(offs, val) \
+ i80286_check_permission(cpustate, cpustate->ea_seg, (UINT16)(cpustate->eo+offs), I80286_WORD, I80286_WRITE); \
+ WriteWord( cpustate->ea-cpustate->eo+(UINT16)(cpustate->eo+offs), val)
+
+#define PutRMByteOffset(offs, val) \
+ i80286_check_permission(cpustate, cpustate->ea_seg, (UINT16)(cpustate->eo+offs), I80286_BYTE, I80286_WRITE); \
+ WriteByte( cpustate->ea-cpustate->eo+(UINT16)(cpustate->eo+offs), val)
+
+#define PutImmRMWord(ModRM) \
+{ \
+ WORD val; \
+ if (ModRM >= 0xc0) \
+ FETCHWORD(cpustate->regs.w[Mod_RM.RM.w[ModRM]]) \
+ else { \
+ (*GetEA[ModRM])(cpustate); \
+ i80286_check_permission(cpustate, cpustate->ea_seg, cpustate->eo, I80286_WORD, I80286_WRITE); \
+ FETCHWORD(val) \
+ WriteWord( cpustate->ea , val); \
+ } \
+}
+
+#define GetRMByte(ModRM) \
+ ((ModRM) >= 0xc0 ? cpustate->regs.b[Mod_RM.RM.b[ModRM]] : ( (*GetEA[ModRM])(cpustate), i80286_check_permission(cpustate, cpustate->ea_seg, cpustate->eo, I80286_BYTE, I80286_READ), ReadByte( cpustate->ea )) )
+
+#define PutRMByte(ModRM,val) \
+{ \
+ if (ModRM >= 0xc0) \
+ cpustate->regs.b[Mod_RM.RM.b[ModRM]]=val; \
+ else \
+ { \
+ (*GetEA[ModRM])(cpustate); \
+ i80286_check_permission(cpustate, cpustate->ea_seg, cpustate->eo, I80286_BYTE, I80286_WRITE); \
+ WriteByte( cpustate->ea,val); \
+ } \
+}
+
+#define PutImmRMByte(ModRM) \
+{ \
+ if (ModRM >= 0xc0) \
+ cpustate->regs.b[Mod_RM.RM.b[ModRM]]=FETCH; \
+ else { \
+ (*GetEA[ModRM])(cpustate); \
+ i80286_check_permission(cpustate, cpustate->ea_seg, cpustate->eo, I80286_BYTE, I80286_WRITE); \
+ WriteByte( cpustate->ea , FETCH ); \
+ } \
+}
+
+#define PutbackRMByte(ModRM,val) \
+{ \
+ if (ModRM >= 0xc0) \
+ cpustate->regs.b[Mod_RM.RM.b[ModRM]]=val; \
+ else \
+ { \
+ i80286_check_permission(cpustate, cpustate->ea_seg, cpustate->eo, I80286_BYTE, I80286_WRITE); \
+ WriteByte(cpustate->ea,val); \
+ } \
+}
+
+#define DEF_br8(dst,src) \
+ unsigned ModRM = FETCHOP; \
+ unsigned src = RegByte(ModRM); \
+ unsigned dst = GetRMByte(ModRM)
+
+#define DEF_wr16(dst,src) \
+ unsigned ModRM = FETCHOP; \
+ unsigned src = RegWord(ModRM); \
+ unsigned dst = GetRMWord(ModRM)
+
+#define DEF_r8b(dst,src) \
+ unsigned ModRM = FETCHOP; \
+ unsigned dst = RegByte(ModRM); \
+ unsigned src = GetRMByte(ModRM)
+
+#define DEF_r16w(dst,src) \
+ unsigned ModRM = FETCHOP; \
+ unsigned dst = RegWord(ModRM); \
+ unsigned src = GetRMWord(ModRM)
+
+#define DEF_ald8(dst,src) \
+ unsigned src = FETCHOP; \
+ unsigned dst = cpustate->regs.b[AL]
+
+#define DEF_axd16(dst,src) \
+ unsigned src = FETCHOP; \
+ unsigned dst = cpustate->regs.w[AX]; \
+ src += (FETCH << 8)
--- /dev/null
+Based on MAME 0.149.
+Add NEC V30 instructions based on MAME 0.128.
--- /dev/null
+const void (IX86_OPS_BASE::*PREFIX186(_instruction)[256])(i8086_state *cpustate) =
+{
+ &IX86_OPS_BASE::PREFIX86(_add_br8), /* 0x00 */
+ &IX86_OPS_BASE::PREFIX86(_add_wr16), /* 0x01 */
+ &IX86_OPS_BASE::PREFIX86(_add_r8b), /* 0x02 */
+ &IX86_OPS_BASE::PREFIX86(_add_r16w), /* 0x03 */
+ &IX86_OPS_BASE::PREFIX86(_add_ald8), /* 0x04 */
+ &IX86_OPS_BASE::PREFIX86(_add_axd16), /* 0x05 */
+ &IX86_OPS_BASE::PREFIX86(_push_es), /* 0x06 */
+ &IX86_OPS_BASE::PREFIX86(_pop_es), /* 0x07 */
+ &IX86_OPS_BASE::PREFIX86(_or_br8), /* 0x08 */
+ &IX86_OPS_BASE::PREFIX86(_or_wr16), /* 0x09 */
+ &IX86_OPS_BASE::PREFIX86(_or_r8b), /* 0x0a */
+ &IX86_OPS_BASE::PREFIX86(_or_r16w), /* 0x0b */
+ &IX86_OPS_BASE::PREFIX86(_or_ald8), /* 0x0c */
+ &IX86_OPS_BASE::PREFIX86(_or_axd16), /* 0x0d */
+ &IX86_OPS_BASE::PREFIX86(_push_cs), /* 0x0e */
+ &IX86_OPS_BASE::PREFIX86(_invalid),
+ &IX86_OPS_BASE::PREFIX86(_adc_br8), /* 0x10 */
+ &IX86_OPS_BASE::PREFIX86(_adc_wr16), /* 0x11 */
+ &IX86_OPS_BASE::PREFIX86(_adc_r8b), /* 0x12 */
+ &IX86_OPS_BASE::PREFIX86(_adc_r16w), /* 0x13 */
+ &IX86_OPS_BASE::PREFIX86(_adc_ald8), /* 0x14 */
+ &IX86_OPS_BASE::PREFIX86(_adc_axd16), /* 0x15 */
+ &IX86_OPS_BASE::PREFIX86(_push_ss), /* 0x16 */
+ &IX86_OPS_BASE::PREFIX186(_pop_ss), /* 0x17 */
+ &IX86_OPS_BASE::PREFIX86(_sbb_br8), /* 0x18 */
+ &IX86_OPS_BASE::PREFIX86(_sbb_wr16), /* 0x19 */
+ &IX86_OPS_BASE::PREFIX86(_sbb_r8b), /* 0x1a */
+ &IX86_OPS_BASE::PREFIX86(_sbb_r16w), /* 0x1b */
+ &IX86_OPS_BASE::PREFIX86(_sbb_ald8), /* 0x1c */
+ &IX86_OPS_BASE::PREFIX86(_sbb_axd16), /* 0x1d */
+ &IX86_OPS_BASE::PREFIX86(_push_ds), /* 0x1e */
+ &IX86_OPS_BASE::PREFIX86(_pop_ds), /* 0x1f */
+ &IX86_OPS_BASE::PREFIX86(_and_br8), /* 0x20 */
+ &IX86_OPS_BASE::PREFIX86(_and_wr16), /* 0x21 */
+ &IX86_OPS_BASE::PREFIX86(_and_r8b), /* 0x22 */
+ &IX86_OPS_BASE::PREFIX86(_and_r16w), /* 0x23 */
+ &IX86_OPS_BASE::PREFIX86(_and_ald8), /* 0x24 */
+ &IX86_OPS_BASE::PREFIX86(_and_axd16), /* 0x25 */
+ &IX86_OPS_BASE::PREFIX186(_es), /* 0x26 */
+ &IX86_OPS_BASE::PREFIX86(_daa), /* 0x27 */
+ &IX86_OPS_BASE::PREFIX86(_sub_br8), /* 0x28 */
+ &IX86_OPS_BASE::PREFIX86(_sub_wr16), /* 0x29 */
+ &IX86_OPS_BASE::PREFIX86(_sub_r8b), /* 0x2a */
+ &IX86_OPS_BASE::PREFIX86(_sub_r16w), /* 0x2b */
+ &IX86_OPS_BASE::PREFIX86(_sub_ald8), /* 0x2c */
+ &IX86_OPS_BASE::PREFIX86(_sub_axd16), /* 0x2d */
+ &IX86_OPS_BASE::PREFIX186(_cs), /* 0x2e */
+ &IX86_OPS_BASE::PREFIX86(_das), /* 0x2f */
+ &IX86_OPS_BASE::PREFIX86(_xor_br8), /* 0x30 */
+ &IX86_OPS_BASE::PREFIX86(_xor_wr16), /* 0x31 */
+ &IX86_OPS_BASE::PREFIX86(_xor_r8b), /* 0x32 */
+ &IX86_OPS_BASE::PREFIX86(_xor_r16w), /* 0x33 */
+ &IX86_OPS_BASE::PREFIX86(_xor_ald8), /* 0x34 */
+ &IX86_OPS_BASE::PREFIX86(_xor_axd16), /* 0x35 */
+ &IX86_OPS_BASE::PREFIX186(_ss), /* 0x36 */
+ &IX86_OPS_BASE::PREFIX86(_aaa), /* 0x37 */
+ &IX86_OPS_BASE::PREFIX86(_cmp_br8), /* 0x38 */
+ &IX86_OPS_BASE::PREFIX86(_cmp_wr16), /* 0x39 */
+ &IX86_OPS_BASE::PREFIX86(_cmp_r8b), /* 0x3a */
+ &IX86_OPS_BASE::PREFIX86(_cmp_r16w), /* 0x3b */
+ &IX86_OPS_BASE::PREFIX86(_cmp_ald8), /* 0x3c */
+ &IX86_OPS_BASE::PREFIX86(_cmp_axd16), /* 0x3d */
+ &IX86_OPS_BASE::PREFIX186(_ds), /* 0x3e */
+ &IX86_OPS_BASE::PREFIX86(_aas), /* 0x3f */
+ &IX86_OPS_BASE::PREFIX86(_inc_ax), /* 0x40 */
+ &IX86_OPS_BASE::PREFIX86(_inc_cx), /* 0x41 */
+ &IX86_OPS_BASE::PREFIX86(_inc_dx), /* 0x42 */
+ &IX86_OPS_BASE::PREFIX86(_inc_bx), /* 0x43 */
+ &IX86_OPS_BASE::PREFIX86(_inc_sp), /* 0x44 */
+ &IX86_OPS_BASE::PREFIX86(_inc_bp), /* 0x45 */
+ &IX86_OPS_BASE::PREFIX86(_inc_si), /* 0x46 */
+ &IX86_OPS_BASE::PREFIX86(_inc_di), /* 0x47 */
+ &IX86_OPS_BASE::PREFIX86(_dec_ax), /* 0x48 */
+ &IX86_OPS_BASE::PREFIX86(_dec_cx), /* 0x49 */
+ &IX86_OPS_BASE::PREFIX86(_dec_dx), /* 0x4a */
+ &IX86_OPS_BASE::PREFIX86(_dec_bx), /* 0x4b */
+ &IX86_OPS_BASE::PREFIX86(_dec_sp), /* 0x4c */
+ &IX86_OPS_BASE::PREFIX86(_dec_bp), /* 0x4d */
+ &IX86_OPS_BASE::PREFIX86(_dec_si), /* 0x4e */
+ &IX86_OPS_BASE::PREFIX86(_dec_di), /* 0x4f */
+ &IX86_OPS_BASE::PREFIX86(_push_ax), /* 0x50 */
+ &IX86_OPS_BASE::PREFIX86(_push_cx), /* 0x51 */
+ &IX86_OPS_BASE::PREFIX86(_push_dx), /* 0x52 */
+ &IX86_OPS_BASE::PREFIX86(_push_bx), /* 0x53 */
+ &IX86_OPS_BASE::PREFIX86(_push_sp), /* 0x54 */
+ &IX86_OPS_BASE::PREFIX86(_push_bp), /* 0x55 */
+ &IX86_OPS_BASE::PREFIX86(_push_si), /* 0x56 */
+ &IX86_OPS_BASE::PREFIX86(_push_di), /* 0x57 */
+ &IX86_OPS_BASE::PREFIX86(_pop_ax), /* 0x58 */
+ &IX86_OPS_BASE::PREFIX86(_pop_cx), /* 0x59 */
+ &IX86_OPS_BASE::PREFIX86(_pop_dx), /* 0x5a */
+ &IX86_OPS_BASE::PREFIX86(_pop_bx), /* 0x5b */
+ &IX86_OPS_BASE::PREFIX86(_pop_sp), /* 0x5c */
+ &IX86_OPS_BASE::PREFIX86(_pop_bp), /* 0x5d */
+ &IX86_OPS_BASE::PREFIX86(_pop_si), /* 0x5e */
+ &IX86_OPS_BASE::PREFIX86(_pop_di), /* 0x5f */
+ &IX86_OPS_BASE::PREFIX186(_pusha), /* 0x60 */
+ &IX86_OPS_BASE::PREFIX186(_popa), /* 0x61 */
+ &IX86_OPS_BASE::PREFIX186(_bound), /* 0x62 */
+ &IX86_OPS_BASE::PREFIX86(_invalid),
+ &IX86_OPS_BASE::PREFIX86(_invalid),
+ &IX86_OPS_BASE::PREFIX86(_invalid),
+ &IX86_OPS_BASE::PREFIX86(_invalid),
+ &IX86_OPS_BASE::PREFIX86(_invalid),
+ &IX86_OPS_BASE::PREFIX186(_push_d16), /* 0x68 */
+ &IX86_OPS_BASE::PREFIX186(_imul_d16), /* 0x69 */
+ &IX86_OPS_BASE::PREFIX186(_push_d8), /* 0x6a */
+ &IX86_OPS_BASE::PREFIX186(_imul_d8), /* 0x6b */
+ &IX86_OPS_BASE::PREFIX186(_insb), /* 0x6c */
+ &IX86_OPS_BASE::PREFIX186(_insw), /* 0x6d */
+ &IX86_OPS_BASE::PREFIX186(_outsb), /* 0x6e */
+ &IX86_OPS_BASE::PREFIX186(_outsw), /* 0x6f */
+ &IX86_OPS_BASE::PREFIX86(_jo), /* 0x70 */
+ &IX86_OPS_BASE::PREFIX86(_jno), /* 0x71 */
+ &IX86_OPS_BASE::PREFIX86(_jb), /* 0x72 */
+ &IX86_OPS_BASE::PREFIX86(_jnb), /* 0x73 */
+ &IX86_OPS_BASE::PREFIX86(_jz), /* 0x74 */
+ &IX86_OPS_BASE::PREFIX86(_jnz), /* 0x75 */
+ &IX86_OPS_BASE::PREFIX86(_jbe), /* 0x76 */
+ &IX86_OPS_BASE::PREFIX86(_jnbe), /* 0x77 */
+ &IX86_OPS_BASE::PREFIX86(_js), /* 0x78 */
+ &IX86_OPS_BASE::PREFIX86(_jns), /* 0x79 */
+ &IX86_OPS_BASE::PREFIX86(_jp), /* 0x7a */
+ &IX86_OPS_BASE::PREFIX86(_jnp), /* 0x7b */
+ &IX86_OPS_BASE::PREFIX86(_jl), /* 0x7c */
+ &IX86_OPS_BASE::PREFIX86(_jnl), /* 0x7d */
+ &IX86_OPS_BASE::PREFIX86(_jle), /* 0x7e */
+ &IX86_OPS_BASE::PREFIX86(_jnle), /* 0x7f */
+ &IX86_OPS_BASE::PREFIX86(_80pre), /* 0x80 */
+ &IX86_OPS_BASE::PREFIX86(_81pre), /* 0x81 */
+ &IX86_OPS_BASE::PREFIX86(_82pre), /* 0x82 */
+ &IX86_OPS_BASE::PREFIX86(_83pre), /* 0x83 */
+ &IX86_OPS_BASE::PREFIX86(_test_br8), /* 0x84 */
+ &IX86_OPS_BASE::PREFIX86(_test_wr16), /* 0x85 */
+ &IX86_OPS_BASE::PREFIX86(_xchg_br8), /* 0x86 */
+ &IX86_OPS_BASE::PREFIX86(_xchg_wr16), /* 0x87 */
+ &IX86_OPS_BASE::PREFIX86(_mov_br8), /* 0x88 */
+ &IX86_OPS_BASE::PREFIX86(_mov_wr16), /* 0x89 */
+ &IX86_OPS_BASE::PREFIX86(_mov_r8b), /* 0x8a */
+ &IX86_OPS_BASE::PREFIX86(_mov_r16w), /* 0x8b */
+ &IX86_OPS_BASE::PREFIX86(_mov_wsreg), /* 0x8c */
+ &IX86_OPS_BASE::PREFIX86(_lea), /* 0x8d */
+ &IX86_OPS_BASE::PREFIX186(_mov_sregw), /* 0x8e */
+ &IX86_OPS_BASE::PREFIX86(_popw), /* 0x8f */
+ &IX86_OPS_BASE::PREFIX86(_nop), /* 0x90 */
+ &IX86_OPS_BASE::PREFIX86(_xchg_axcx), /* 0x91 */
+ &IX86_OPS_BASE::PREFIX86(_xchg_axdx), /* 0x92 */
+ &IX86_OPS_BASE::PREFIX86(_xchg_axbx), /* 0x93 */
+ &IX86_OPS_BASE::PREFIX86(_xchg_axsp), /* 0x94 */
+ &IX86_OPS_BASE::PREFIX86(_xchg_axbp), /* 0x95 */
+ &IX86_OPS_BASE::PREFIX86(_xchg_axsi), /* 0x97 */
+ &IX86_OPS_BASE::PREFIX86(_xchg_axdi), /* 0x97 */
+ &IX86_OPS_BASE::PREFIX86(_cbw), /* 0x98 */
+ &IX86_OPS_BASE::PREFIX86(_cwd), /* 0x99 */
+ &IX86_OPS_BASE::PREFIX86(_call_far), /* 0x9a */
+ &IX86_OPS_BASE::PREFIX86(_wait), /* 0x9b */
+ &IX86_OPS_BASE::PREFIX86(_pushf), /* 0x9c */
+ &IX86_OPS_BASE::PREFIX86(_popf), /* 0x9d */
+ &IX86_OPS_BASE::PREFIX86(_sahf), /* 0x9e */
+ &IX86_OPS_BASE::PREFIX86(_lahf), /* 0x9f */
+ &IX86_OPS_BASE::PREFIX86(_mov_aldisp), /* 0xa0 */
+ &IX86_OPS_BASE::PREFIX86(_mov_axdisp), /* 0xa1 */
+ &IX86_OPS_BASE::PREFIX86(_mov_dispal), /* 0xa2 */
+ &IX86_OPS_BASE::PREFIX86(_mov_dispax), /* 0xa3 */
+ &IX86_OPS_BASE::PREFIX86(_movsb), /* 0xa4 */
+ &IX86_OPS_BASE::PREFIX86(_movsw), /* 0xa5 */
+ &IX86_OPS_BASE::PREFIX86(_cmpsb), /* 0xa6 */
+ &IX86_OPS_BASE::PREFIX86(_cmpsw), /* 0xa7 */
+ &IX86_OPS_BASE::PREFIX86(_test_ald8), /* 0xa8 */
+ &IX86_OPS_BASE::PREFIX86(_test_axd16), /* 0xa9 */
+ &IX86_OPS_BASE::PREFIX86(_stosb), /* 0xaa */
+ &IX86_OPS_BASE::PREFIX86(_stosw), /* 0xab */
+ &IX86_OPS_BASE::PREFIX86(_lodsb), /* 0xac */
+ &IX86_OPS_BASE::PREFIX86(_lodsw), /* 0xad */
+ &IX86_OPS_BASE::PREFIX86(_scasb), /* 0xae */
+ &IX86_OPS_BASE::PREFIX86(_scasw), /* 0xaf */
+ &IX86_OPS_BASE::PREFIX86(_mov_ald8), /* 0xb0 */
+ &IX86_OPS_BASE::PREFIX86(_mov_cld8), /* 0xb1 */
+ &IX86_OPS_BASE::PREFIX86(_mov_dld8), /* 0xb2 */
+ &IX86_OPS_BASE::PREFIX86(_mov_bld8), /* 0xb3 */
+ &IX86_OPS_BASE::PREFIX86(_mov_ahd8), /* 0xb4 */
+ &IX86_OPS_BASE::PREFIX86(_mov_chd8), /* 0xb5 */
+ &IX86_OPS_BASE::PREFIX86(_mov_dhd8), /* 0xb6 */
+ &IX86_OPS_BASE::PREFIX86(_mov_bhd8), /* 0xb7 */
+ &IX86_OPS_BASE::PREFIX86(_mov_axd16), /* 0xb8 */
+ &IX86_OPS_BASE::PREFIX86(_mov_cxd16), /* 0xb9 */
+ &IX86_OPS_BASE::PREFIX86(_mov_dxd16), /* 0xba */
+ &IX86_OPS_BASE::PREFIX86(_mov_bxd16), /* 0xbb */
+ &IX86_OPS_BASE::PREFIX86(_mov_spd16), /* 0xbc */
+ &IX86_OPS_BASE::PREFIX86(_mov_bpd16), /* 0xbd */
+ &IX86_OPS_BASE::PREFIX86(_mov_sid16), /* 0xbe */
+ &IX86_OPS_BASE::PREFIX86(_mov_did16), /* 0xbf */
+ &IX86_OPS_BASE::PREFIX186(_rotshft_bd8), /* 0xc0 */
+ &IX86_OPS_BASE::PREFIX186(_rotshft_wd8), /* 0xc1 */
+ &IX86_OPS_BASE::PREFIX86(_ret_d16), /* 0xc2 */
+ &IX86_OPS_BASE::PREFIX86(_ret), /* 0xc3 */
+ &IX86_OPS_BASE::PREFIX86(_les_dw), /* 0xc4 */
+ &IX86_OPS_BASE::PREFIX86(_lds_dw), /* 0xc5 */
+ &IX86_OPS_BASE::PREFIX86(_mov_bd8), /* 0xc6 */
+ &IX86_OPS_BASE::PREFIX86(_mov_wd16), /* 0xc7 */
+ &IX86_OPS_BASE::PREFIX186(_enter), /* 0xc8 */
+ &IX86_OPS_BASE::PREFIX186(_leave), /* 0xc9 */
+ &IX86_OPS_BASE::PREFIX86(_retf_d16), /* 0xca */
+ &IX86_OPS_BASE::PREFIX86(_retf), /* 0xcb */
+ &IX86_OPS_BASE::PREFIX86(_int3), /* 0xcc */
+ &IX86_OPS_BASE::PREFIX86(_int), /* 0xcd */
+ &IX86_OPS_BASE::PREFIX86(_into), /* 0xce */
+ &IX86_OPS_BASE::PREFIX86(_iret), /* 0xcf */
+ &IX86_OPS_BASE::PREFIX86(_rotshft_b), /* 0xd0 */
+ &IX86_OPS_BASE::PREFIX86(_rotshft_w), /* 0xd1 */
+ &IX86_OPS_BASE::PREFIX186(_rotshft_bcl), /* 0xd2 */
+ &IX86_OPS_BASE::PREFIX186(_rotshft_wcl), /* 0xd3 */
+ &IX86_OPS_BASE::PREFIX86(_aam), /* 0xd4 */
+ &IX86_OPS_BASE::PREFIX86(_aad), /* 0xd5 */
+ &IX86_OPS_BASE::PREFIX86(_invalid),
+ &IX86_OPS_BASE::PREFIX86(_xlat), /* 0xd7 */
+ &IX86_OPS_BASE::PREFIX86(_escape), /* 0xd8 */
+ &IX86_OPS_BASE::PREFIX86(_escape), /* 0xd9 */
+ &IX86_OPS_BASE::PREFIX86(_escape), /* 0xda */
+ &IX86_OPS_BASE::PREFIX86(_escape), /* 0xdb */
+ &IX86_OPS_BASE::PREFIX86(_escape), /* 0xdc */
+ &IX86_OPS_BASE::PREFIX86(_escape), /* 0xdd */
+ &IX86_OPS_BASE::PREFIX86(_escape), /* 0xde */
+ &IX86_OPS_BASE::PREFIX86(_escape), /* 0xdf */
+ &IX86_OPS_BASE::PREFIX86(_loopne), /* 0xe0 */
+ &IX86_OPS_BASE::PREFIX86(_loope), /* 0xe1 */
+ &IX86_OPS_BASE::PREFIX86(_loop), /* 0xe2 */
+ &IX86_OPS_BASE::PREFIX86(_jcxz), /* 0xe3 */
+ &IX86_OPS_BASE::PREFIX86(_inal), /* 0xe4 */
+ &IX86_OPS_BASE::PREFIX86(_inax), /* 0xe5 */
+ &IX86_OPS_BASE::PREFIX86(_outal), /* 0xe6 */
+ &IX86_OPS_BASE::PREFIX86(_outax), /* 0xe7 */
+ &IX86_OPS_BASE::PREFIX86(_call_d16), /* 0xe8 */
+ &IX86_OPS_BASE::PREFIX86(_jmp_d16), /* 0xe9 */
+ &IX86_OPS_BASE::PREFIX86(_jmp_far), /* 0xea */
+ &IX86_OPS_BASE::PREFIX86(_jmp_d8), /* 0xeb */
+ &IX86_OPS_BASE::PREFIX86(_inaldx), /* 0xec */
+ &IX86_OPS_BASE::PREFIX86(_inaxdx), /* 0xed */
+ &IX86_OPS_BASE::PREFIX86(_outdxal), /* 0xee */
+ &IX86_OPS_BASE::PREFIX86(_outdxax), /* 0xef */
+ &IX86_OPS_BASE::PREFIX86(_lock), /* 0xf0 */
+ &IX86_OPS_BASE::PREFIX86(_invalid), /* 0xf1 */
+ &IX86_OPS_BASE::PREFIX186(_repne), /* 0xf2 */
+ &IX86_OPS_BASE::PREFIX186(_repe), /* 0xf3 */
+ &IX86_OPS_BASE::PREFIX86(_hlt), /* 0xf4 */
+ &IX86_OPS_BASE::PREFIX86(_cmc), /* 0xf5 */
+ &IX86_OPS_BASE::PREFIX86(_f6pre), /* 0xf6 */
+ &IX86_OPS_BASE::PREFIX86(_f7pre), /* 0xf7 */
+ &IX86_OPS_BASE::PREFIX86(_clc), /* 0xf8 */
+ &IX86_OPS_BASE::PREFIX86(_stc), /* 0xf9 */
+ &IX86_OPS_BASE::PREFIX86(_cli), /* 0xfa */
+ &IX86_OPS_BASE::PREFIX186(_sti), /* 0xfb */
+ &IX86_OPS_BASE::PREFIX86(_cld), /* 0xfc */
+ &IX86_OPS_BASE::PREFIX86(_std), /* 0xfd */
+ &IX86_OPS_BASE::PREFIX86(_fepre), /* 0xfe */
+ &IX86_OPS_BASE::PREFIX86(_ffpre) /* 0xff */
+};
+
+#if defined(BIGCASE) && !defined(RS6000)
+ /* Some compilers cannot handle large case statements */
+#define TABLE186 \
+ switch(FETCHOP)\
+ {\
+ case 0x00: PREFIX86(_add_br8)(cpustate); break;\
+ case 0x01: PREFIX86(_add_wr16)(cpustate); break;\
+ case 0x02: PREFIX86(_add_r8b)(cpustate); break;\
+ case 0x03: PREFIX86(_add_r16w)(cpustate); break;\
+ case 0x04: PREFIX86(_add_ald8)(cpustate); break;\
+ case 0x05: PREFIX86(_add_axd16)(cpustate); break;\
+ case 0x06: PREFIX86(_push_es)(cpustate); break;\
+ case 0x07: PREFIX86(_pop_es)(cpustate); break;\
+ case 0x08: PREFIX86(_or_br8)(cpustate); break;\
+ case 0x09: PREFIX86(_or_wr16)(cpustate); break;\
+ case 0x0a: PREFIX86(_or_r8b)(cpustate); break;\
+ case 0x0b: PREFIX86(_or_r16w)(cpustate); break;\
+ case 0x0c: PREFIX86(_or_ald8)(cpustate); break;\
+ case 0x0d: PREFIX86(_or_axd16)(cpustate); break;\
+ case 0x0e: PREFIX86(_push_cs)(cpustate); break;\
+ case 0x0f: PREFIX86(_invalid)(cpustate); break;\
+ case 0x10: PREFIX86(_adc_br8)(cpustate); break;\
+ case 0x11: PREFIX86(_adc_wr16)(cpustate); break;\
+ case 0x12: PREFIX86(_adc_r8b)(cpustate); break;\
+ case 0x13: PREFIX86(_adc_r16w)(cpustate); break;\
+ case 0x14: PREFIX86(_adc_ald8)(cpustate); break;\
+ case 0x15: PREFIX86(_adc_axd16)(cpustate); break;\
+ case 0x16: PREFIX86(_push_ss)(cpustate); break;\
+ case 0x17: PREFIX186(_pop_ss)(cpustate); break;\
+ case 0x18: PREFIX86(_sbb_br8)(cpustate); break;\
+ case 0x19: PREFIX86(_sbb_wr16)(cpustate); break;\
+ case 0x1a: PREFIX86(_sbb_r8b)(cpustate); break;\
+ case 0x1b: PREFIX86(_sbb_r16w)(cpustate); break;\
+ case 0x1c: PREFIX86(_sbb_ald8)(cpustate); break;\
+ case 0x1d: PREFIX86(_sbb_axd16)(cpustate); break;\
+ case 0x1e: PREFIX86(_push_ds)(cpustate); break;\
+ case 0x1f: PREFIX86(_pop_ds)(cpustate); break;\
+ case 0x20: PREFIX86(_and_br8)(cpustate); break;\
+ case 0x21: PREFIX86(_and_wr16)(cpustate); break;\
+ case 0x22: PREFIX86(_and_r8b)(cpustate); break;\
+ case 0x23: PREFIX86(_and_r16w)(cpustate); break;\
+ case 0x24: PREFIX86(_and_ald8)(cpustate); break;\
+ case 0x25: PREFIX86(_and_axd16)(cpustate); break;\
+ case 0x26: PREFIX86(_es)(cpustate); break;\
+ case 0x27: PREFIX86(_daa)(cpustate); break;\
+ case 0x28: PREFIX86(_sub_br8)(cpustate); break;\
+ case 0x29: PREFIX86(_sub_wr16)(cpustate); break;\
+ case 0x2a: PREFIX86(_sub_r8b)(cpustate); break;\
+ case 0x2b: PREFIX86(_sub_r16w)(cpustate); break;\
+ case 0x2c: PREFIX86(_sub_ald8)(cpustate); break;\
+ case 0x2d: PREFIX86(_sub_axd16)(cpustate); break;\
+ case 0x2e: PREFIX86(_cs)(cpustate); break;\
+ case 0x2f: PREFIX86(_das)(cpustate); break;\
+ case 0x30: PREFIX86(_xor_br8)(cpustate); break;\
+ case 0x31: PREFIX86(_xor_wr16)(cpustate); break;\
+ case 0x32: PREFIX86(_xor_r8b)(cpustate); break;\
+ case 0x33: PREFIX86(_xor_r16w)(cpustate); break;\
+ case 0x34: PREFIX86(_xor_ald8)(cpustate); break;\
+ case 0x35: PREFIX86(_xor_axd16)(cpustate); break;\
+ case 0x36: PREFIX86(_ss)(cpustate); break;\
+ case 0x37: PREFIX86(_aaa)(cpustate); break;\
+ case 0x38: PREFIX86(_cmp_br8)(cpustate); break;\
+ case 0x39: PREFIX86(_cmp_wr16)(cpustate); break;\
+ case 0x3a: PREFIX86(_cmp_r8b)(cpustate); break;\
+ case 0x3b: PREFIX86(_cmp_r16w)(cpustate); break;\
+ case 0x3c: PREFIX86(_cmp_ald8)(cpustate); break;\
+ case 0x3d: PREFIX86(_cmp_axd16)(cpustate); break;\
+ case 0x3e: PREFIX86(_ds)(cpustate); break;\
+ case 0x3f: PREFIX86(_aas)(cpustate); break;\
+ case 0x40: PREFIX86(_inc_ax)(cpustate); break;\
+ case 0x41: PREFIX86(_inc_cx)(cpustate); break;\
+ case 0x42: PREFIX86(_inc_dx)(cpustate); break;\
+ case 0x43: PREFIX86(_inc_bx)(cpustate); break;\
+ case 0x44: PREFIX86(_inc_sp)(cpustate); break;\
+ case 0x45: PREFIX86(_inc_bp)(cpustate); break;\
+ case 0x46: PREFIX86(_inc_si)(cpustate); break;\
+ case 0x47: PREFIX86(_inc_di)(cpustate); break;\
+ case 0x48: PREFIX86(_dec_ax)(cpustate); break;\
+ case 0x49: PREFIX86(_dec_cx)(cpustate); break;\
+ case 0x4a: PREFIX86(_dec_dx)(cpustate); break;\
+ case 0x4b: PREFIX86(_dec_bx)(cpustate); break;\
+ case 0x4c: PREFIX86(_dec_sp)(cpustate); break;\
+ case 0x4d: PREFIX86(_dec_bp)(cpustate); break;\
+ case 0x4e: PREFIX86(_dec_si)(cpustate); break;\
+ case 0x4f: PREFIX86(_dec_di)(cpustate); break;\
+ case 0x50: PREFIX86(_push_ax)(cpustate); break;\
+ case 0x51: PREFIX86(_push_cx)(cpustate); break;\
+ case 0x52: PREFIX86(_push_dx)(cpustate); break;\
+ case 0x53: PREFIX86(_push_bx)(cpustate); break;\
+ case 0x54: PREFIX86(_push_sp)(cpustate); break;\
+ case 0x55: PREFIX86(_push_bp)(cpustate); break;\
+ case 0x56: PREFIX86(_push_si)(cpustate); break;\
+ case 0x57: PREFIX86(_push_di)(cpustate); break;\
+ case 0x58: PREFIX86(_pop_ax)(cpustate); break;\
+ case 0x59: PREFIX86(_pop_cx)(cpustate); break;\
+ case 0x5a: PREFIX86(_pop_dx)(cpustate); break;\
+ case 0x5b: PREFIX86(_pop_bx)(cpustate); break;\
+ case 0x5c: PREFIX86(_pop_sp)(cpustate); break;\
+ case 0x5d: PREFIX86(_pop_bp)(cpustate); break;\
+ case 0x5e: PREFIX86(_pop_si)(cpustate); break;\
+ case 0x5f: PREFIX86(_pop_di)(cpustate); break;\
+ case 0x60: PREFIX186(_pusha)(cpustate); break;\
+ case 0x61: PREFIX186(_popa)(cpustate); break;\
+ case 0x62: PREFIX186(_bound)(cpustate); break;\
+ case 0x63: PREFIX86(_invalid)(cpustate); break;\
+ case 0x64: PREFIX86(_invalid)(cpustate); break;\
+ case 0x65: PREFIX86(_invalid)(cpustate); break;\
+ case 0x66: PREFIX86(_invalid)(cpustate); break;\
+ case 0x67: PREFIX86(_invalid)(cpustate); break;\
+ case 0x68: PREFIX186(_push_d16)(cpustate); break;\
+ case 0x69: PREFIX186(_imul_d16)(cpustate); break;\
+ case 0x6a: PREFIX186(_push_d8)(cpustate); break;\
+ case 0x6b: PREFIX186(_imul_d8)(cpustate); break;\
+ case 0x6c: PREFIX186(_insb)(cpustate); break;\
+ case 0x6d: PREFIX186(_insw)(cpustate); break;\
+ case 0x6e: PREFIX186(_outsb)(cpustate); break;\
+ case 0x6f: PREFIX186(_outsw)(cpustate); break;\
+ case 0x70: PREFIX86(_jo)(cpustate); break;\
+ case 0x71: PREFIX86(_jno)(cpustate); break;\
+ case 0x72: PREFIX86(_jb)(cpustate); break;\
+ case 0x73: PREFIX86(_jnb)(cpustate); break;\
+ case 0x74: PREFIX86(_jz)(cpustate); break;\
+ case 0x75: PREFIX86(_jnz)(cpustate); break;\
+ case 0x76: PREFIX86(_jbe)(cpustate); break;\
+ case 0x77: PREFIX86(_jnbe)(cpustate); break;\
+ case 0x78: PREFIX86(_js)(cpustate); break;\
+ case 0x79: PREFIX86(_jns)(cpustate); break;\
+ case 0x7a: PREFIX86(_jp)(cpustate); break;\
+ case 0x7b: PREFIX86(_jnp)(cpustate); break;\
+ case 0x7c: PREFIX86(_jl)(cpustate); break;\
+ case 0x7d: PREFIX86(_jnl)(cpustate); break;\
+ case 0x7e: PREFIX86(_jle)(cpustate); break;\
+ case 0x7f: PREFIX86(_jnle)(cpustate); break;\
+ case 0x80: PREFIX86(_80pre)(cpustate); break;\
+ case 0x81: PREFIX86(_81pre)(cpustate); break;\
+ case 0x82: PREFIX86(_82pre)(cpustate); break;\
+ case 0x83: PREFIX86(_83pre)(cpustate); break;\
+ case 0x84: PREFIX86(_test_br8)(cpustate); break;\
+ case 0x85: PREFIX86(_test_wr16)(cpustate); break;\
+ case 0x86: PREFIX86(_xchg_br8)(cpustate); break;\
+ case 0x87: PREFIX86(_xchg_wr16)(cpustate); break;\
+ case 0x88: PREFIX86(_mov_br8)(cpustate); break;\
+ case 0x89: PREFIX86(_mov_wr16)(cpustate); break;\
+ case 0x8a: PREFIX86(_mov_r8b)(cpustate); break;\
+ case 0x8b: PREFIX86(_mov_r16w)(cpustate); break;\
+ case 0x8c: PREFIX86(_mov_wsreg)(cpustate); break;\
+ case 0x8d: PREFIX86(_lea)(cpustate); break;\
+ case 0x8e: PREFIX186(_mov_sregw)(cpustate); break;\
+ case 0x8f: PREFIX86(_popw)(cpustate); break;\
+ case 0x90: PREFIX86(_nop)(cpustate); break;\
+ case 0x91: PREFIX86(_xchg_axcx)(cpustate); break;\
+ case 0x92: PREFIX86(_xchg_axdx)(cpustate); break;\
+ case 0x93: PREFIX86(_xchg_axbx)(cpustate); break;\
+ case 0x94: PREFIX86(_xchg_axsp)(cpustate); break;\
+ case 0x95: PREFIX86(_xchg_axbp)(cpustate); break;\
+ case 0x96: PREFIX86(_xchg_axsi)(cpustate); break;\
+ case 0x97: PREFIX86(_xchg_axdi)(cpustate); break;\
+ case 0x98: PREFIX86(_cbw)(cpustate); break;\
+ case 0x99: PREFIX86(_cwd)(cpustate); break;\
+ case 0x9a: PREFIX86(_call_far)(cpustate); break;\
+ case 0x9b: PREFIX86(_wait)(cpustate); break;\
+ case 0x9c: PREFIX86(_pushf)(cpustate); break;\
+ case 0x9d: PREFIX86(_popf)(cpustate); break;\
+ case 0x9e: PREFIX86(_sahf)(cpustate); break;\
+ case 0x9f: PREFIX86(_lahf)(cpustate); break;\
+ case 0xa0: PREFIX86(_mov_aldisp)(cpustate); break;\
+ case 0xa1: PREFIX86(_mov_axdisp)(cpustate); break;\
+ case 0xa2: PREFIX86(_mov_dispal)(cpustate); break;\
+ case 0xa3: PREFIX86(_mov_dispax)(cpustate); break;\
+ case 0xa4: PREFIX86(_movsb)(cpustate); break;\
+ case 0xa5: PREFIX86(_movsw)(cpustate); break;\
+ case 0xa6: PREFIX86(_cmpsb)(cpustate); break;\
+ case 0xa7: PREFIX86(_cmpsw)(cpustate); break;\
+ case 0xa8: PREFIX86(_test_ald8)(cpustate); break;\
+ case 0xa9: PREFIX86(_test_axd16)(cpustate); break;\
+ case 0xaa: PREFIX86(_stosb)(cpustate); break;\
+ case 0xab: PREFIX86(_stosw)(cpustate); break;\
+ case 0xac: PREFIX86(_lodsb)(cpustate); break;\
+ case 0xad: PREFIX86(_lodsw)(cpustate); break;\
+ case 0xae: PREFIX86(_scasb)(cpustate); break;\
+ case 0xaf: PREFIX86(_scasw)(cpustate); break;\
+ case 0xb0: PREFIX86(_mov_ald8)(cpustate); break;\
+ case 0xb1: PREFIX86(_mov_cld8)(cpustate); break;\
+ case 0xb2: PREFIX86(_mov_dld8)(cpustate); break;\
+ case 0xb3: PREFIX86(_mov_bld8)(cpustate); break;\
+ case 0xb4: PREFIX86(_mov_ahd8)(cpustate); break;\
+ case 0xb5: PREFIX86(_mov_chd8)(cpustate); break;\
+ case 0xb6: PREFIX86(_mov_dhd8)(cpustate); break;\
+ case 0xb7: PREFIX86(_mov_bhd8)(cpustate); break;\
+ case 0xb8: PREFIX86(_mov_axd16)(cpustate); break;\
+ case 0xb9: PREFIX86(_mov_cxd16)(cpustate); break;\
+ case 0xba: PREFIX86(_mov_dxd16)(cpustate); break;\
+ case 0xbb: PREFIX86(_mov_bxd16)(cpustate); break;\
+ case 0xbc: PREFIX86(_mov_spd16)(cpustate); break;\
+ case 0xbd: PREFIX86(_mov_bpd16)(cpustate); break;\
+ case 0xbe: PREFIX86(_mov_sid16)(cpustate); break;\
+ case 0xbf: PREFIX86(_mov_did16)(cpustate); break;\
+ case 0xc0: PREFIX186(_rotshft_bd8)(cpustate); break;\
+ case 0xc1: PREFIX186(_rotshft_wd8)(cpustate); break;\
+ case 0xc2: PREFIX86(_ret_d16)(cpustate); break;\
+ case 0xc3: PREFIX86(_ret)(cpustate); break;\
+ case 0xc4: PREFIX86(_les_dw)(cpustate); break;\
+ case 0xc5: PREFIX86(_lds_dw)(cpustate); break;\
+ case 0xc6: PREFIX86(_mov_bd8)(cpustate); break;\
+ case 0xc7: PREFIX86(_mov_wd16)(cpustate); break;\
+ case 0xc8: PREFIX186(_enter)(cpustate); break;\
+ case 0xc9: PREFIX186(_leave)(cpustate); break;\
+ case 0xca: PREFIX86(_retf_d16)(cpustate); break;\
+ case 0xcb: PREFIX86(_retf)(cpustate); break;\
+ case 0xcc: PREFIX86(_int3)(cpustate); break;\
+ case 0xcd: PREFIX86(_int)(cpustate); break;\
+ case 0xce: PREFIX86(_into)(cpustate); break;\
+ case 0xcf: PREFIX86(_iret)(cpustate); break;\
+ case 0xd0: PREFIX86(_rotshft_b)(cpustate); break;\
+ case 0xd1: PREFIX86(_rotshft_w)(cpustate); break;\
+ case 0xd2: PREFIX186(_rotshft_bcl)(cpustate); break;\
+ case 0xd3: PREFIX186(_rotshft_wcl)(cpustate); break;\
+ case 0xd4: PREFIX86(_aam)(cpustate); break;\
+ case 0xd5: PREFIX86(_aad)(cpustate); break;\
+ case 0xd6: PREFIX86(_invalid)(cpustate); break;\
+ case 0xd7: PREFIX86(_xlat)(cpustate); break;\
+ case 0xd8: PREFIX86(_escape)(cpustate); break;\
+ case 0xd9: PREFIX86(_escape)(cpustate); break;\
+ case 0xda: PREFIX86(_escape)(cpustate); break;\
+ case 0xdb: PREFIX86(_escape)(cpustate); break;\
+ case 0xdc: PREFIX86(_escape)(cpustate); break;\
+ case 0xdd: PREFIX86(_escape)(cpustate); break;\
+ case 0xde: PREFIX86(_escape)(cpustate); break;\
+ case 0xdf: PREFIX86(_escape)(cpustate); break;\
+ case 0xe0: PREFIX86(_loopne)(cpustate); break;\
+ case 0xe1: PREFIX86(_loope)(cpustate); break;\
+ case 0xe2: PREFIX86(_loop)(cpustate); break;\
+ case 0xe3: PREFIX86(_jcxz)(cpustate); break;\
+ case 0xe4: PREFIX86(_inal)(cpustate); break;\
+ case 0xe5: PREFIX86(_inax)(cpustate); break;\
+ case 0xe6: PREFIX86(_outal)(cpustate); break;\
+ case 0xe7: PREFIX86(_outax)(cpustate); break;\
+ case 0xe8: PREFIX86(_call_d16)(cpustate); break;\
+ case 0xe9: PREFIX86(_jmp_d16)(cpustate); break;\
+ case 0xea: PREFIX86(_jmp_far)(cpustate); break;\
+ case 0xeb: PREFIX86(_jmp_d8)(cpustate); break;\
+ case 0xec: PREFIX86(_inaldx)(cpustate); break;\
+ case 0xed: PREFIX86(_inaxdx)(cpustate); break;\
+ case 0xee: PREFIX86(_outdxal)(cpustate); break;\
+ case 0xef: PREFIX86(_outdxax)(cpustate); break;\
+ case 0xf0: PREFIX86(_lock)(cpustate); break;\
+ case 0xf1: PREFIX86(_invalid)(cpustate); break;\
+ case 0xf2: PREFIX186(_repne)(); break;\
+ case 0xf3: PREFIX186(_repe)(); break;\
+ case 0xf4: PREFIX86(_hlt)(cpustate); break;\
+ case 0xf5: PREFIX86(_cmc)(cpustate); break;\
+ case 0xf6: PREFIX86(_f6pre)(cpustate); break;\
+ case 0xf7: PREFIX86(_f7pre)(cpustate); break;\
+ case 0xf8: PREFIX86(_clc)(cpustate); break;\
+ case 0xf9: PREFIX86(_stc)(cpustate); break;\
+ case 0xfa: PREFIX86(_cli)(cpustate); break;\
+ case 0xfb: PREFIX186(_sti)(cpustate); break;\
+ case 0xfc: PREFIX86(_cld)(cpustate); break;\
+ case 0xfd: PREFIX86(_std)(cpustate); break;\
+ case 0xfe: PREFIX86(_fepre)(cpustate); break;\
+ case 0xff: PREFIX86(_ffpre)(cpustate); break;\
+ };
+#else
+#define TABLE186 PREFIX186(_instruction)[FETCHOP]();
+#endif
--- /dev/null
+/*
+ * special 286 protected mode instructions missing
+ * at the time the same like table186.h
+ */
+
+const void (IX86_OPS_BASE::*PREFIX286(_instruction)[256])() =
+{
+ &IX86_OPS_BASE::PREFIX86(_add_br8), /* 0x00 */
+ &IX86_OPS_BASE::PREFIX86(_add_wr16), /* 0x01 */
+ &IX86_OPS_BASE::PREFIX86(_add_r8b), /* 0x02 */
+ &IX86_OPS_BASE::PREFIX86(_add_r16w), /* 0x03 */
+ &IX86_OPS_BASE::PREFIX86(_add_ald8), /* 0x04 */
+ &IX86_OPS_BASE::PREFIX86(_add_axd16), /* 0x05 */
+ &IX86_OPS_BASE::PREFIX86(_push_es), /* 0x06 */
+ &IX86_OPS_BASE::PREFIX86(_pop_es), /* 0x07 */
+ &IX86_OPS_BASE::PREFIX86(_or_br8), /* 0x08 */
+ &IX86_OPS_BASE::PREFIX86(_or_wr16), /* 0x09 */
+ &IX86_OPS_BASE::PREFIX86(_or_r8b), /* 0x0a */
+ &IX86_OPS_BASE::PREFIX86(_or_r16w), /* 0x0b */
+ &IX86_OPS_BASE::PREFIX86(_or_ald8), /* 0x0c */
+ &IX86_OPS_BASE::PREFIX86(_or_axd16), /* 0x0d */
+ &IX86_OPS_BASE::PREFIX86(_push_cs), /* 0x0e */
+ &IX86_OPS_BASE::PREFIX286(_0fpre),
+ &IX86_OPS_BASE::PREFIX86(_adc_br8), /* 0x10 */
+ &IX86_OPS_BASE::PREFIX86(_adc_wr16), /* 0x11 */
+ &IX86_OPS_BASE::PREFIX86(_adc_r8b), /* 0x12 */
+ &IX86_OPS_BASE::PREFIX86(_adc_r16w), /* 0x13 */
+ &IX86_OPS_BASE::PREFIX86(_adc_ald8), /* 0x14 */
+ &IX86_OPS_BASE::PREFIX86(_adc_axd16), /* 0x15 */
+ &IX86_OPS_BASE::PREFIX86(_push_ss), /* 0x16 */
+ &IX86_OPS_BASE::PREFIX286(_pop_ss), /* 0x17 */
+ &IX86_OPS_BASE::PREFIX86(_sbb_br8), /* 0x18 */
+ &IX86_OPS_BASE::PREFIX86(_sbb_wr16), /* 0x19 */
+ &IX86_OPS_BASE::PREFIX86(_sbb_r8b), /* 0x1a */
+ &IX86_OPS_BASE::PREFIX86(_sbb_r16w), /* 0x1b */
+ &IX86_OPS_BASE::PREFIX86(_sbb_ald8), /* 0x1c */
+ &IX86_OPS_BASE::PREFIX86(_sbb_axd16), /* 0x1d */
+ &IX86_OPS_BASE::PREFIX86(_push_ds), /* 0x1e */
+ &IX86_OPS_BASE::PREFIX86(_pop_ds), /* 0x1f */
+ &IX86_OPS_BASE::PREFIX86(_and_br8), /* 0x20 */
+ &IX86_OPS_BASE::PREFIX86(_and_wr16), /* 0x21 */
+ &IX86_OPS_BASE::PREFIX86(_and_r8b), /* 0x22 */
+ &IX86_OPS_BASE::PREFIX86(_and_r16w), /* 0x23 */
+ &IX86_OPS_BASE::PREFIX86(_and_ald8), /* 0x24 */
+ &IX86_OPS_BASE::PREFIX86(_and_axd16), /* 0x25 */
+ &IX86_OPS_BASE::PREFIX286(_es), /* 0x26 */
+ &IX86_OPS_BASE::PREFIX86(_daa), /* 0x27 */
+ &IX86_OPS_BASE::PREFIX86(_sub_br8), /* 0x28 */
+ &IX86_OPS_BASE::PREFIX86(_sub_wr16), /* 0x29 */
+ &IX86_OPS_BASE::PREFIX86(_sub_r8b), /* 0x2a */
+ &IX86_OPS_BASE::PREFIX86(_sub_r16w), /* 0x2b */
+ &IX86_OPS_BASE::PREFIX86(_sub_ald8), /* 0x2c */
+ &IX86_OPS_BASE::PREFIX86(_sub_axd16), /* 0x2d */
+ &IX86_OPS_BASE::PREFIX286(_cs), /* 0x2e */
+ &IX86_OPS_BASE::PREFIX86(_das), /* 0x2f */
+ &IX86_OPS_BASE::PREFIX86(_xor_br8), /* 0x30 */
+ &IX86_OPS_BASE::PREFIX86(_xor_wr16), /* 0x31 */
+ &IX86_OPS_BASE::PREFIX86(_xor_r8b), /* 0x32 */
+ &IX86_OPS_BASE::PREFIX86(_xor_r16w), /* 0x33 */
+ &IX86_OPS_BASE::PREFIX86(_xor_ald8), /* 0x34 */
+ &IX86_OPS_BASE::PREFIX86(_xor_axd16), /* 0x35 */
+ &IX86_OPS_BASE::PREFIX286(_ss), /* 0x36 */
+ &IX86_OPS_BASE::PREFIX86(_aaa), /* 0x37 */
+ &IX86_OPS_BASE::PREFIX86(_cmp_br8), /* 0x38 */
+ &IX86_OPS_BASE::PREFIX86(_cmp_wr16), /* 0x39 */
+ &IX86_OPS_BASE::PREFIX86(_cmp_r8b), /* 0x3a */
+ &IX86_OPS_BASE::PREFIX86(_cmp_r16w), /* 0x3b */
+ &IX86_OPS_BASE::PREFIX86(_cmp_ald8), /* 0x3c */
+ &IX86_OPS_BASE::PREFIX86(_cmp_axd16), /* 0x3d */
+ &IX86_OPS_BASE::PREFIX286(_ds), /* 0x3e */
+ &IX86_OPS_BASE::PREFIX86(_aas), /* 0x3f */
+ &IX86_OPS_BASE::PREFIX86(_inc_ax), /* 0x40 */
+ &IX86_OPS_BASE::PREFIX86(_inc_cx), /* 0x41 */
+ &IX86_OPS_BASE::PREFIX86(_inc_dx), /* 0x42 */
+ &IX86_OPS_BASE::PREFIX286(_inc_bx), /* 0x43 */
+ &IX86_OPS_BASE::PREFIX86(_inc_sp), /* 0x44 */
+ &IX86_OPS_BASE::PREFIX86(_inc_bp), /* 0x45 */
+ &IX86_OPS_BASE::PREFIX86(_inc_si), /* 0x46 */
+ &IX86_OPS_BASE::PREFIX86(_inc_di), /* 0x47 */
+ &IX86_OPS_BASE::PREFIX86(_dec_ax), /* 0x48 */
+ &IX86_OPS_BASE::PREFIX86(_dec_cx), /* 0x49 */
+ &IX86_OPS_BASE::PREFIX86(_dec_dx), /* 0x4a */
+ &IX86_OPS_BASE::PREFIX86(_dec_bx), /* 0x4b */
+ &IX86_OPS_BASE::PREFIX86(_dec_sp), /* 0x4c */
+ &IX86_OPS_BASE::PREFIX86(_dec_bp), /* 0x4d */
+ &IX86_OPS_BASE::PREFIX86(_dec_si), /* 0x4e */
+ &IX86_OPS_BASE::PREFIX86(_dec_di), /* 0x4f */
+ &IX86_OPS_BASE::PREFIX86(_push_ax), /* 0x50 */
+ &IX86_OPS_BASE::PREFIX86(_push_cx), /* 0x51 */
+ &IX86_OPS_BASE::PREFIX86(_push_dx), /* 0x52 */
+ &IX86_OPS_BASE::PREFIX86(_push_bx), /* 0x53 */
+ &IX86_OPS_BASE::PREFIX86(_push_sp), /* 0x54 */
+ &IX86_OPS_BASE::PREFIX86(_push_bp), /* 0x55 */
+ &IX86_OPS_BASE::PREFIX86(_push_si), /* 0x56 */
+ &IX86_OPS_BASE::PREFIX86(_push_di), /* 0x57 */
+ &IX86_OPS_BASE::PREFIX86(_pop_ax), /* 0x58 */
+ &IX86_OPS_BASE::PREFIX86(_pop_cx), /* 0x59 */
+ &IX86_OPS_BASE::PREFIX86(_pop_dx), /* 0x5a */
+ &IX86_OPS_BASE::PREFIX86(_pop_bx), /* 0x5b */
+ &IX86_OPS_BASE::PREFIX86(_pop_sp), /* 0x5c */
+ &IX86_OPS_BASE::PREFIX86(_pop_bp), /* 0x5d */
+ &IX86_OPS_BASE::PREFIX86(_pop_si), /* 0x5e */
+ &IX86_OPS_BASE::PREFIX86(_pop_di), /* 0x5f */
+ &IX86_OPS_BASE::PREFIX186(_pusha), /* 0x60 */
+ &IX86_OPS_BASE::PREFIX186(_popa), /* 0x61 */
+ &IX86_OPS_BASE::PREFIX186(_bound), /* 0x62 */
+ &IX86_OPS_BASE::PREFIX286(_arpl), /* 0x63 */
+ &IX86_OPS_BASE::PREFIX286(_invalid),
+ &IX86_OPS_BASE::PREFIX286(_invalid),
+ &IX86_OPS_BASE::PREFIX286(_invalid),
+ &IX86_OPS_BASE::PREFIX286(_invalid),
+ &IX86_OPS_BASE::PREFIX186(_push_d16), /* 0x68 */
+ &IX86_OPS_BASE::PREFIX186(_imul_d16), /* 0x69 */
+ &IX86_OPS_BASE::PREFIX186(_push_d8), /* 0x6a */
+ &IX86_OPS_BASE::PREFIX186(_imul_d8), /* 0x6b */
+ &IX86_OPS_BASE::PREFIX286(_insb), /* 0x6c */
+ &IX86_OPS_BASE::PREFIX286(_insw), /* 0x6d */
+ &IX86_OPS_BASE::PREFIX286(_outsb), /* 0x6e */
+ &IX86_OPS_BASE::PREFIX286(_outsw), /* 0x6f */
+ &IX86_OPS_BASE::PREFIX86(_jo), /* 0x70 */
+ &IX86_OPS_BASE::PREFIX86(_jno), /* 0x71 */
+ &IX86_OPS_BASE::PREFIX86(_jb), /* 0x72 */
+ &IX86_OPS_BASE::PREFIX86(_jnb), /* 0x73 */
+ &IX86_OPS_BASE::PREFIX86(_jz), /* 0x74 */
+ &IX86_OPS_BASE::PREFIX86(_jnz), /* 0x75 */
+ &IX86_OPS_BASE::PREFIX86(_jbe), /* 0x76 */
+ &IX86_OPS_BASE::PREFIX86(_jnbe), /* 0x77 */
+ &IX86_OPS_BASE::PREFIX86(_js), /* 0x78 */
+ &IX86_OPS_BASE::PREFIX86(_jns), /* 0x79 */
+ &IX86_OPS_BASE::PREFIX86(_jp), /* 0x7a */
+ &IX86_OPS_BASE::PREFIX86(_jnp), /* 0x7b */
+ &IX86_OPS_BASE::PREFIX86(_jl), /* 0x7c */
+ &IX86_OPS_BASE::PREFIX86(_jnl), /* 0x7d */
+ &IX86_OPS_BASE::PREFIX86(_jle), /* 0x7e */
+ &IX86_OPS_BASE::PREFIX86(_jnle), /* 0x7f */
+ &IX86_OPS_BASE::PREFIX86(_80pre), /* 0x80 */
+ &IX86_OPS_BASE::PREFIX86(_81pre), /* 0x81 */
+ &IX86_OPS_BASE::PREFIX86(_82pre), /* 0x82 */
+ &IX86_OPS_BASE::PREFIX86(_83pre), /* 0x83 */
+ &IX86_OPS_BASE::PREFIX86(_test_br8), /* 0x84 */
+ &IX86_OPS_BASE::PREFIX86(_test_wr16), /* 0x85 */
+ &IX86_OPS_BASE::PREFIX86(_xchg_br8), /* 0x86 */
+ &IX86_OPS_BASE::PREFIX86(_xchg_wr16), /* 0x87 */
+ &IX86_OPS_BASE::PREFIX86(_mov_br8), /* 0x88 */
+ &IX86_OPS_BASE::PREFIX86(_mov_wr16), /* 0x89 */
+ &IX86_OPS_BASE::PREFIX86(_mov_r8b), /* 0x8a */
+ &IX86_OPS_BASE::PREFIX86(_mov_r16w), /* 0x8b */
+ &IX86_OPS_BASE::PREFIX86(_mov_wsreg), /* 0x8c */
+ &IX86_OPS_BASE::PREFIX86(_lea), /* 0x8d */
+ &IX86_OPS_BASE::PREFIX286(_mov_sregw), /* 0x8e */
+ &IX86_OPS_BASE::PREFIX86(_popw), /* 0x8f */
+ &IX86_OPS_BASE::PREFIX86(_nop), /* 0x90 */
+ &IX86_OPS_BASE::PREFIX86(_xchg_axcx), /* 0x91 */
+ &IX86_OPS_BASE::PREFIX86(_xchg_axdx), /* 0x92 */
+ &IX86_OPS_BASE::PREFIX86(_xchg_axbx), /* 0x93 */
+ &IX86_OPS_BASE::PREFIX86(_xchg_axsp), /* 0x94 */
+ &IX86_OPS_BASE::PREFIX86(_xchg_axbp), /* 0x95 */
+ &IX86_OPS_BASE::PREFIX86(_xchg_axsi), /* 0x97 */
+ &IX86_OPS_BASE::PREFIX86(_xchg_axdi), /* 0x97 */
+ &IX86_OPS_BASE::PREFIX86(_cbw), /* 0x98 */
+ &IX86_OPS_BASE::PREFIX86(_cwd), /* 0x99 */
+ &IX86_OPS_BASE::PREFIX86(_call_far), /* 0x9a */
+ &IX86_OPS_BASE::PREFIX86(_wait), /* 0x9b */
+ &IX86_OPS_BASE::PREFIX286(_pushf), /* 0x9c */
+ &IX86_OPS_BASE::PREFIX286(_popf), /* 0x9d */
+ &IX86_OPS_BASE::PREFIX86(_sahf), /* 0x9e */
+ &IX86_OPS_BASE::PREFIX86(_lahf), /* 0x9f */
+ &IX86_OPS_BASE::PREFIX86(_mov_aldisp), /* 0xa0 */
+ &IX86_OPS_BASE::PREFIX86(_mov_axdisp), /* 0xa1 */
+ &IX86_OPS_BASE::PREFIX86(_mov_dispal), /* 0xa2 */
+ &IX86_OPS_BASE::PREFIX86(_mov_dispax), /* 0xa3 */
+ &IX86_OPS_BASE::PREFIX86(_movsb), /* 0xa4 */
+ &IX86_OPS_BASE::PREFIX86(_movsw), /* 0xa5 */
+ &IX86_OPS_BASE::PREFIX86(_cmpsb), /* 0xa6 */
+ &IX86_OPS_BASE::PREFIX86(_cmpsw), /* 0xa7 */
+ &IX86_OPS_BASE::PREFIX86(_test_ald8), /* 0xa8 */
+ &IX86_OPS_BASE::PREFIX86(_test_axd16), /* 0xa9 */
+ &IX86_OPS_BASE::PREFIX86(_stosb), /* 0xaa */
+ &IX86_OPS_BASE::PREFIX86(_stosw), /* 0xab */
+ &IX86_OPS_BASE::PREFIX86(_lodsb), /* 0xac */
+ &IX86_OPS_BASE::PREFIX86(_lodsw), /* 0xad */
+ &IX86_OPS_BASE::PREFIX86(_scasb), /* 0xae */
+ &IX86_OPS_BASE::PREFIX86(_scasw), /* 0xaf */
+ &IX86_OPS_BASE::PREFIX86(_mov_ald8), /* 0xb0 */
+ &IX86_OPS_BASE::PREFIX86(_mov_cld8), /* 0xb1 */
+ &IX86_OPS_BASE::PREFIX86(_mov_dld8), /* 0xb2 */
+ &IX86_OPS_BASE::PREFIX86(_mov_bld8), /* 0xb3 */
+ &IX86_OPS_BASE::PREFIX86(_mov_ahd8), /* 0xb4 */
+ &IX86_OPS_BASE::PREFIX86(_mov_chd8), /* 0xb5 */
+ &IX86_OPS_BASE::PREFIX86(_mov_dhd8), /* 0xb6 */
+ &IX86_OPS_BASE::PREFIX86(_mov_bhd8), /* 0xb7 */
+ &IX86_OPS_BASE::PREFIX86(_mov_axd16), /* 0xb8 */
+ &IX86_OPS_BASE::PREFIX86(_mov_cxd16), /* 0xb9 */
+ &IX86_OPS_BASE::PREFIX86(_mov_dxd16), /* 0xba */
+ &IX86_OPS_BASE::PREFIX86(_mov_bxd16), /* 0xbb */
+ &IX86_OPS_BASE::PREFIX86(_mov_spd16), /* 0xbc */
+ &IX86_OPS_BASE::PREFIX86(_mov_bpd16), /* 0xbd */
+ &IX86_OPS_BASE::PREFIX86(_mov_sid16), /* 0xbe */
+ &IX86_OPS_BASE::PREFIX86(_mov_did16), /* 0xbf */
+ &IX86_OPS_BASE::PREFIX186(_rotshft_bd8), /* 0xc0 */
+ &IX86_OPS_BASE::PREFIX186(_rotshft_wd8), /* 0xc1 */
+ &IX86_OPS_BASE::PREFIX86(_ret_d16), /* 0xc2 */
+ &IX86_OPS_BASE::PREFIX86(_ret), /* 0xc3 */
+ &IX86_OPS_BASE::PREFIX86(_les_dw), /* 0xc4 */
+ &IX86_OPS_BASE::PREFIX86(_lds_dw), /* 0xc5 */
+ &IX86_OPS_BASE::PREFIX86(_mov_bd8), /* 0xc6 */
+ &IX86_OPS_BASE::PREFIX86(_mov_wd16), /* 0xc7 */
+ &IX86_OPS_BASE::PREFIX186(_enter), /* 0xc8 */
+ &IX86_OPS_BASE::PREFIX186(_leave), /* 0xc9 */
+ &IX86_OPS_BASE::PREFIX286(_retf_d16), /* 0xca */
+ &IX86_OPS_BASE::PREFIX286(_retf), /* 0xcb */
+ &IX86_OPS_BASE::PREFIX86(_int3), /* 0xcc */
+ &IX86_OPS_BASE::PREFIX86(_int), /* 0xcd */
+ &IX86_OPS_BASE::PREFIX86(_into), /* 0xce */
+ &IX86_OPS_BASE::PREFIX286(_iret), /* 0xcf */
+ &IX86_OPS_BASE::PREFIX86(_rotshft_b), /* 0xd0 */
+ &IX86_OPS_BASE::PREFIX86(_rotshft_w), /* 0xd1 */
+ &IX86_OPS_BASE::PREFIX186(_rotshft_bcl), /* 0xd2 */
+ &IX86_OPS_BASE::PREFIX186(_rotshft_wcl), /* 0xd3 */
+ &IX86_OPS_BASE::PREFIX86(_aam), /* 0xd4 */
+ &IX86_OPS_BASE::PREFIX86(_aad), /* 0xd5 */
+ &IX86_OPS_BASE::PREFIX286(_invalid),
+ &IX86_OPS_BASE::PREFIX86(_xlat), /* 0xd7 */
+ &IX86_OPS_BASE::PREFIX286(_escape), /* 0xd8 */
+ &IX86_OPS_BASE::PREFIX286(_escape), /* 0xd9 */
+ &IX86_OPS_BASE::PREFIX286(_escape), /* 0xda */
+ &IX86_OPS_BASE::PREFIX286(_escape), /* 0xdb */
+ &IX86_OPS_BASE::PREFIX286(_escape), /* 0xdc */
+ &IX86_OPS_BASE::PREFIX286(_escape), /* 0xdd */
+ &IX86_OPS_BASE::PREFIX286(_escape), /* 0xde */
+ &IX86_OPS_BASE::PREFIX286(_escape_7), /* 0xdf */
+ &IX86_OPS_BASE::PREFIX86(_loopne), /* 0xe0 */
+ &IX86_OPS_BASE::PREFIX86(_loope), /* 0xe1 */
+ &IX86_OPS_BASE::PREFIX86(_loop), /* 0xe2 */
+ &IX86_OPS_BASE::PREFIX86(_jcxz), /* 0xe3 */
+ &IX86_OPS_BASE::PREFIX86(_inal), /* 0xe4 */
+ &IX86_OPS_BASE::PREFIX86(_inax), /* 0xe5 */
+ &IX86_OPS_BASE::PREFIX86(_outal), /* 0xe6 */
+ &IX86_OPS_BASE::PREFIX86(_outax), /* 0xe7 */
+ &IX86_OPS_BASE::PREFIX86(_call_d16), /* 0xe8 */
+ &IX86_OPS_BASE::PREFIX86(_jmp_d16), /* 0xe9 */
+ &IX86_OPS_BASE::PREFIX86(_jmp_far), /* 0xea */
+ &IX86_OPS_BASE::PREFIX86(_jmp_d8), /* 0xeb */
+ &IX86_OPS_BASE::PREFIX86(_inaldx), /* 0xec */
+ &IX86_OPS_BASE::PREFIX86(_inaxdx), /* 0xed */
+ &IX86_OPS_BASE::PREFIX86(_outdxal), /* 0xee */
+ &IX86_OPS_BASE::PREFIX86(_outdxax), /* 0xef */
+ &IX86_OPS_BASE::PREFIX86(_lock), /* 0xf0 */
+ &IX86_OPS_BASE::PREFIX286(_invalid), /* 0xf1 */
+ &IX86_OPS_BASE::PREFIX286(_repne), /* 0xf2 */
+ &IX86_OPS_BASE::PREFIX286(_repe), /* 0xf3 */
+ &IX86_OPS_BASE::PREFIX86(_hlt), /* 0xf4 */
+ &IX86_OPS_BASE::PREFIX86(_cmc), /* 0xf5 */
+ &IX86_OPS_BASE::PREFIX86(_f6pre), /* 0xf6 */
+ &IX86_OPS_BASE::PREFIX86(_f7pre), /* 0xf7 */
+ &IX86_OPS_BASE::PREFIX86(_clc), /* 0xf8 */
+ &IX86_OPS_BASE::PREFIX86(_stc), /* 0xf9 */
+ &IX86_OPS_BASE::PREFIX86(_cli), /* 0xfa */
+ &IX86_OPS_BASE::PREFIX286(_sti), /* 0xfb */
+ &IX86_OPS_BASE::PREFIX86(_cld), /* 0xfc */
+ &IX86_OPS_BASE::PREFIX86(_std), /* 0xfd */
+ &IX86_OPS_BASE::PREFIX86(_fepre), /* 0xfe */
+ &IX86_OPS_BASE::PREFIX86(_ffpre) /* 0xff */
+};
+
+#if defined(BIGCASE) && !defined(RS6000)
+ /* Some compilers cannot handle large case statements */
+#define TABLE286 \
+ switch(FETCHOP)\
+ {\
+ case 0x00: PREFIX86(_add_br8)(cpustate); break;\
+ case 0x01: PREFIX86(_add_wr16)(cpustate); break;\
+ case 0x02: PREFIX86(_add_r8b)(cpustate); break;\
+ case 0x03: PREFIX86(_add_r16w)(cpustate); break;\
+ case 0x04: PREFIX86(_add_ald8)(cpustate); break;\
+ case 0x05: PREFIX86(_add_axd16)(cpustate); break;\
+ case 0x06: PREFIX86(_push_es)(cpustate); break;\
+ case 0x07: PREFIX86(_pop_es)(cpustate); break;\
+ case 0x08: PREFIX86(_or_br8)(cpustate); break;\
+ case 0x09: PREFIX86(_or_wr16)(cpustate); break;\
+ case 0x0a: PREFIX86(_or_r8b)(cpustate); break;\
+ case 0x0b: PREFIX86(_or_r16w)(cpustate); break;\
+ case 0x0c: PREFIX86(_or_ald8)(cpustate); break;\
+ case 0x0d: PREFIX86(_or_axd16)(cpustate); break;\
+ case 0x0e: PREFIX86(_push_cs)(cpustate); break;\
+ case 0x0f: PREFIX286(_0fpre)(cpustate); break;\
+ case 0x10: PREFIX86(_adc_br8)(cpustate); break;\
+ case 0x11: PREFIX86(_adc_wr16)(cpustate); break;\
+ case 0x12: PREFIX86(_adc_r8b)(cpustate); break;\
+ case 0x13: PREFIX86(_adc_r16w)(cpustate); break;\
+ case 0x14: PREFIX86(_adc_ald8)(cpustate); break;\
+ case 0x15: PREFIX86(_adc_axd16)(cpustate); break;\
+ case 0x16: PREFIX86(_push_ss)(cpustate); break;\
+ case 0x17: PREFIX286(_pop_ss)(cpustate); break;\
+ case 0x18: PREFIX86(_sbb_br8)(cpustate); break;\
+ case 0x19: PREFIX86(_sbb_wr16)(cpustate); break;\
+ case 0x1a: PREFIX86(_sbb_r8b)(cpustate); break;\
+ case 0x1b: PREFIX86(_sbb_r16w)(cpustate); break;\
+ case 0x1c: PREFIX86(_sbb_ald8)(cpustate); break;\
+ case 0x1d: PREFIX86(_sbb_axd16)(cpustate); break;\
+ case 0x1e: PREFIX86(_push_ds)(cpustate); break;\
+ case 0x1f: PREFIX86(_pop_ds)(cpustate); break;\
+ case 0x20: PREFIX86(_and_br8)(cpustate); break;\
+ case 0x21: PREFIX86(_and_wr16)(cpustate); break;\
+ case 0x22: PREFIX86(_and_r8b)(cpustate); break;\
+ case 0x23: PREFIX86(_and_r16w)(cpustate); break;\
+ case 0x24: PREFIX86(_and_ald8)(cpustate); break;\
+ case 0x25: PREFIX86(_and_axd16)(cpustate); break;\
+ case 0x26: PREFIX286(_es)(cpustate); break;\
+ case 0x27: PREFIX86(_daa)(cpustate); break;\
+ case 0x28: PREFIX86(_sub_br8)(cpustate); break;\
+ case 0x29: PREFIX86(_sub_wr16)(cpustate); break;\
+ case 0x2a: PREFIX86(_sub_r8b)(cpustate); break;\
+ case 0x2b: PREFIX86(_sub_r16w)(cpustate); break;\
+ case 0x2c: PREFIX86(_sub_ald8)(cpustate); break;\
+ case 0x2d: PREFIX86(_sub_axd16)(cpustate); break;\
+ case 0x2e: PREFIX286(_cs)(cpustate); break;\
+ case 0x2f: PREFIX86(_das)(cpustate); break;\
+ case 0x30: PREFIX86(_xor_br8)(cpustate); break;\
+ case 0x31: PREFIX86(_xor_wr16)(cpustate); break;\
+ case 0x32: PREFIX86(_xor_r8b)(cpustate); break;\
+ case 0x33: PREFIX86(_xor_r16w)(cpustate); break;\
+ case 0x34: PREFIX86(_xor_ald8)(cpustate); break;\
+ case 0x35: PREFIX86(_xor_axd16)(cpustate); break;\
+ case 0x36: PREFIX286(_ss)(cpustate); break;\
+ case 0x37: PREFIX86(_aaa)(cpustate); break;\
+ case 0x38: PREFIX86(_cmp_br8)(cpustate); break;\
+ case 0x39: PREFIX86(_cmp_wr16)(cpustate); break;\
+ case 0x3a: PREFIX86(_cmp_r8b)(cpustate); break;\
+ case 0x3b: PREFIX86(_cmp_r16w)(cpustate); break;\
+ case 0x3c: PREFIX86(_cmp_ald8)(cpustate); break;\
+ case 0x3d: PREFIX86(_cmp_axd16)(cpustate); break;\
+ case 0x3e: PREFIX286(_ds)(cpustate); break;\
+ case 0x3f: PREFIX86(_aas)(cpustate); break;\
+ case 0x40: PREFIX86(_inc_ax)(cpustate); break;\
+ case 0x41: PREFIX86(_inc_cx)(cpustate); break;\
+ case 0x42: PREFIX86(_inc_dx)(cpustate); break;\
+ case 0x43: PREFIX286(_inc_bx)(cpustate); break;\
+ case 0x44: PREFIX86(_inc_sp)(cpustate); break;\
+ case 0x45: PREFIX86(_inc_bp)(cpustate); break;\
+ case 0x46: PREFIX86(_inc_si)(cpustate); break;\
+ case 0x47: PREFIX86(_inc_di)(cpustate); break;\
+ case 0x48: PREFIX86(_dec_ax)(cpustate); break;\
+ case 0x49: PREFIX86(_dec_cx)(cpustate); break;\
+ case 0x4a: PREFIX86(_dec_dx)(cpustate); break;\
+ case 0x4b: PREFIX86(_dec_bx)(cpustate); break;\
+ case 0x4c: PREFIX86(_dec_sp)(cpustate); break;\
+ case 0x4d: PREFIX86(_dec_bp)(cpustate); break;\
+ case 0x4e: PREFIX86(_dec_si)(cpustate); break;\
+ case 0x4f: PREFIX86(_dec_di)(cpustate); break;\
+ case 0x50: PREFIX86(_push_ax)(cpustate); break;\
+ case 0x51: PREFIX86(_push_cx)(cpustate); break;\
+ case 0x52: PREFIX86(_push_dx)(cpustate); break;\
+ case 0x53: PREFIX86(_push_bx)(cpustate); break;\
+ case 0x54: PREFIX86(_push_sp)(cpustate); break;\
+ case 0x55: PREFIX86(_push_bp)(cpustate); break;\
+ case 0x56: PREFIX86(_push_si)(cpustate); break;\
+ case 0x57: PREFIX86(_push_di)(cpustate); break;\
+ case 0x58: PREFIX86(_pop_ax)(cpustate); break;\
+ case 0x59: PREFIX86(_pop_cx)(cpustate); break;\
+ case 0x5a: PREFIX86(_pop_dx)(cpustate); break;\
+ case 0x5b: PREFIX86(_pop_bx)(cpustate); break;\
+ case 0x5c: PREFIX86(_pop_sp)(cpustate); break;\
+ case 0x5d: PREFIX86(_pop_bp)(cpustate); break;\
+ case 0x5e: PREFIX86(_pop_si)(cpustate); break;\
+ case 0x5f: PREFIX86(_pop_di)(cpustate); break;\
+ case 0x60: PREFIX186(_pusha)(cpustate); break;\
+ case 0x61: PREFIX186(_popa)(cpustate); break;\
+ case 0x62: PREFIX186(_bound)(cpustate); break;\
+ case 0x63: PREFIX286(_arpl)(cpustate); break;\
+ case 0x64: PREFIX286(_invalid)(cpustate); break;\
+ case 0x65: PREFIX286(_invalid)(cpustate); break;\
+ case 0x66: PREFIX286(_invalid)(cpustate); break;\
+ case 0x67: PREFIX286(_invalid)(cpustate); break;\
+ case 0x68: PREFIX186(_push_d16)(cpustate); break;\
+ case 0x69: PREFIX186(_imul_d16)(cpustate); break;\
+ case 0x6a: PREFIX186(_push_d8)(cpustate); break;\
+ case 0x6b: PREFIX186(_imul_d8)(cpustate); break;\
+ case 0x6c: PREFIX286(_insb)(cpustate); break;\
+ case 0x6d: PREFIX286(_insw)(cpustate); break;\
+ case 0x6e: PREFIX286(_outsb)(cpustate); break;\
+ case 0x6f: PREFIX286(_outsw)(cpustate); break;\
+ case 0x70: PREFIX86(_jo)(cpustate); break;\
+ case 0x71: PREFIX86(_jno)(cpustate); break;\
+ case 0x72: PREFIX86(_jb)(cpustate); break;\
+ case 0x73: PREFIX86(_jnb)(cpustate); break;\
+ case 0x74: PREFIX86(_jz)(cpustate); break;\
+ case 0x75: PREFIX86(_jnz)(cpustate); break;\
+ case 0x76: PREFIX86(_jbe)(cpustate); break;\
+ case 0x77: PREFIX86(_jnbe)(cpustate); break;\
+ case 0x78: PREFIX86(_js)(cpustate); break;\
+ case 0x79: PREFIX86(_jns)(cpustate); break;\
+ case 0x7a: PREFIX86(_jp)(cpustate); break;\
+ case 0x7b: PREFIX86(_jnp)(cpustate); break;\
+ case 0x7c: PREFIX86(_jl)(cpustate); break;\
+ case 0x7d: PREFIX86(_jnl)(cpustate); break;\
+ case 0x7e: PREFIX86(_jle)(cpustate); break;\
+ case 0x7f: PREFIX86(_jnle)(cpustate); break;\
+ case 0x80: PREFIX86(_80pre)(cpustate); break;\
+ case 0x81: PREFIX86(_81pre)(cpustate); break;\
+ case 0x82: PREFIX86(_82pre)(cpustate); break;\
+ case 0x83: PREFIX86(_83pre)(cpustate); break;\
+ case 0x84: PREFIX86(_test_br8)(cpustate); break;\
+ case 0x85: PREFIX86(_test_wr16)(cpustate); break;\
+ case 0x86: PREFIX86(_xchg_br8)(cpustate); break;\
+ case 0x87: PREFIX86(_xchg_wr16)(cpustate); break;\
+ case 0x88: PREFIX86(_mov_br8)(cpustate); break;\
+ case 0x89: PREFIX86(_mov_wr16)(cpustate); break;\
+ case 0x8a: PREFIX86(_mov_r8b)(cpustate); break;\
+ case 0x8b: PREFIX86(_mov_r16w)(cpustate); break;\
+ case 0x8c: PREFIX86(_mov_wsreg)(cpustate); break;\
+ case 0x8d: PREFIX86(_lea)(cpustate); break;\
+ case 0x8e: PREFIX286(_mov_sregw)(cpustate); break;\
+ case 0x8f: PREFIX86(_popw)(cpustate); break;\
+ case 0x90: PREFIX86(_nop)(cpustate); break;\
+ case 0x91: PREFIX86(_xchg_axcx)(cpustate); break;\
+ case 0x92: PREFIX86(_xchg_axdx)(cpustate); break;\
+ case 0x93: PREFIX86(_xchg_axbx)(cpustate); break;\
+ case 0x94: PREFIX86(_xchg_axsp)(cpustate); break;\
+ case 0x95: PREFIX86(_xchg_axbp)(cpustate); break;\
+ case 0x96: PREFIX86(_xchg_axsi)(cpustate); break;\
+ case 0x97: PREFIX86(_xchg_axdi)(cpustate); break;\
+ case 0x98: PREFIX86(_cbw)(cpustate); break;\
+ case 0x99: PREFIX86(_cwd)(cpustate); break;\
+ case 0x9a: PREFIX86(_call_far)(cpustate); break;\
+ case 0x9b: PREFIX86(_wait)(cpustate); break;\
+ case 0x9c: PREFIX286(_pushf)(cpustate); break;\
+ case 0x9d: PREFIX286(_popf)(cpustate); break;\
+ case 0x9e: PREFIX86(_sahf)(cpustate); break;\
+ case 0x9f: PREFIX86(_lahf)(cpustate); break;\
+ case 0xa0: PREFIX86(_mov_aldisp)(cpustate); break;\
+ case 0xa1: PREFIX86(_mov_axdisp)(cpustate); break;\
+ case 0xa2: PREFIX86(_mov_dispal)(cpustate); break;\
+ case 0xa3: PREFIX86(_mov_dispax)(cpustate); break;\
+ case 0xa4: PREFIX86(_movsb)(cpustate); break;\
+ case 0xa5: PREFIX86(_movsw)(cpustate); break;\
+ case 0xa6: PREFIX86(_cmpsb)(cpustate); break;\
+ case 0xa7: PREFIX86(_cmpsw)(cpustate); break;\
+ case 0xa8: PREFIX86(_test_ald8)(cpustate); break;\
+ case 0xa9: PREFIX86(_test_axd16)(cpustate); break;\
+ case 0xaa: PREFIX86(_stosb)(cpustate); break;\
+ case 0xab: PREFIX86(_stosw)(cpustate); break;\
+ case 0xac: PREFIX86(_lodsb)(cpustate); break;\
+ case 0xad: PREFIX86(_lodsw)(cpustate); break;\
+ case 0xae: PREFIX86(_scasb)(cpustate); break;\
+ case 0xaf: PREFIX86(_scasw)(cpustate); break;\
+ case 0xb0: PREFIX86(_mov_ald8)(cpustate); break;\
+ case 0xb1: PREFIX86(_mov_cld8)(cpustate); break;\
+ case 0xb2: PREFIX86(_mov_dld8)(cpustate); break;\
+ case 0xb3: PREFIX86(_mov_bld8)(cpustate); break;\
+ case 0xb4: PREFIX86(_mov_ahd8)(cpustate); break;\
+ case 0xb5: PREFIX86(_mov_chd8)(cpustate); break;\
+ case 0xb6: PREFIX86(_mov_dhd8)(cpustate); break;\
+ case 0xb7: PREFIX86(_mov_bhd8)(cpustate); break;\
+ case 0xb8: PREFIX86(_mov_axd16)(cpustate); break;\
+ case 0xb9: PREFIX86(_mov_cxd16)(cpustate); break;\
+ case 0xba: PREFIX86(_mov_dxd16)(cpustate); break;\
+ case 0xbb: PREFIX86(_mov_bxd16)(cpustate); break;\
+ case 0xbc: PREFIX86(_mov_spd16)(cpustate); break;\
+ case 0xbd: PREFIX86(_mov_bpd16)(cpustate); break;\
+ case 0xbe: PREFIX86(_mov_sid16)(cpustate); break;\
+ case 0xbf: PREFIX86(_mov_did16)(cpustate); break;\
+ case 0xc0: PREFIX186(_rotshft_bd8)(cpustate); break;\
+ case 0xc1: PREFIX186(_rotshft_wd8)(cpustate); break;\
+ case 0xc2: PREFIX86(_ret_d16)(cpustate); break;\
+ case 0xc3: PREFIX86(_ret)(cpustate); break;\
+ case 0xc4: PREFIX86(_les_dw)(cpustate); break;\
+ case 0xc5: PREFIX86(_lds_dw)(cpustate); break;\
+ case 0xc6: PREFIX86(_mov_bd8)(cpustate); break;\
+ case 0xc7: PREFIX86(_mov_wd16)(cpustate); break;\
+ case 0xc8: PREFIX186(_enter)(cpustate); break;\
+ case 0xc9: PREFIX186(_leave)(cpustate); break;\
+ case 0xca: PREFIX286(_retf_d16)(cpustate); break;\
+ case 0xcb: PREFIX286(_retf)(cpustate); break;\
+ case 0xcc: PREFIX86(_int3)(cpustate); break;\
+ case 0xcd: PREFIX86(_int)(cpustate); break;\
+ case 0xce: PREFIX86(_into)(cpustate); break;\
+ case 0xcf: PREFIX286(_iret)(cpustate); break;\
+ case 0xd0: PREFIX86(_rotshft_b)(cpustate); break;\
+ case 0xd1: PREFIX86(_rotshft_w)(cpustate); break;\
+ case 0xd2: PREFIX186(_rotshft_bcl)(cpustate); break;\
+ case 0xd3: PREFIX186(_rotshft_wcl)(cpustate); break;\
+ case 0xd4: PREFIX86(_aam)(cpustate); break;\
+ case 0xd5: PREFIX86(_aad)(cpustate); break;\
+ case 0xd6: PREFIX286(_invalid)(cpustate); break;\
+ case 0xd7: PREFIX86(_xlat)(cpustate); break;\
+ case 0xd8: PREFIX286(_escape)(cpustate); break;\
+ case 0xd9: PREFIX286(_escape)(cpustate); break;\
+ case 0xda: PREFIX286(_escape)(cpustate); break;\
+ case 0xdb: PREFIX286(_escape)(cpustate); break;\
+ case 0xdc: PREFIX286(_escape)(cpustate); break;\
+ case 0xdd: PREFIX286(_escape)(cpustate); break;\
+ case 0xde: PREFIX286(_escape)(cpustate); break;\
+ case 0xdf: PREFIX286(_escape_7)(cpustate); break;\
+ case 0xe0: PREFIX86(_loopne)(cpustate); break;\
+ case 0xe1: PREFIX86(_loope)(cpustate); break;\
+ case 0xe2: PREFIX86(_loop)(cpustate); break;\
+ case 0xe3: PREFIX86(_jcxz)(cpustate); break;\
+ case 0xe4: PREFIX86(_inal)(cpustate); break;\
+ case 0xe5: PREFIX86(_inax)(cpustate); break;\
+ case 0xe6: PREFIX86(_outal)(cpustate); break;\
+ case 0xe7: PREFIX86(_outax)(cpustate); break;\
+ case 0xe8: PREFIX86(_call_d16)(cpustate); break;\
+ case 0xe9: PREFIX86(_jmp_d16)(cpustate); break;\
+ case 0xea: PREFIX86(_jmp_far)(cpustate); break;\
+ case 0xeb: PREFIX86(_jmp_d8)(cpustate); break;\
+ case 0xec: PREFIX86(_inaldx)(cpustate); break;\
+ case 0xed: PREFIX86(_inaxdx)(cpustate); break;\
+ case 0xee: PREFIX86(_outdxal)(cpustate); break;\
+ case 0xef: PREFIX86(_outdxax)(cpustate); break;\
+ case 0xf0: PREFIX86(_lock)(cpustate); break;\
+ case 0xf1: PREFIX286(_invalid)(cpustate); break;\
+ case 0xf2: PREFIX286(_repne)(cpustate); break;\
+ case 0xf3: PREFIX286(_repe)(cpustate); break;\
+ case 0xf4: PREFIX86(_hlt)(cpustate); break;\
+ case 0xf5: PREFIX86(_cmc)(cpustate); break;\
+ case 0xf6: PREFIX86(_f6pre)(cpustate); break;\
+ case 0xf7: PREFIX86(_f7pre)(cpustate); break;\
+ case 0xf8: PREFIX86(_clc)(cpustate); break;\
+ case 0xf9: PREFIX86(_stc)(cpustate); break;\
+ case 0xfa: PREFIX86(_cli)(cpustate); break;\
+ case 0xfb: PREFIX286(_sti)(cpustate); break;\
+ case 0xfc: PREFIX86(_cld)(cpustate); break;\
+ case 0xfd: PREFIX86(_std)(cpustate); break;\
+ case 0xfe: PREFIX86(_fepre)(cpustate); break;\
+ case 0xff: PREFIX86(_ffpre)(cpustate); break;\
+ };
+#else
+#define TABLE286 PREFIX286(_instruction)[FETCHOP]();
+#endif
--- /dev/null
+const void (IX86_OPS_BASE::*PREFIX86(_instruction)[256])() =
+{
+ &IX86_OPS_BASE::PREFIX86(_add_br8), /* 0x00 */
+ &IX86_OPS_BASE::PREFIX86(_add_wr16), /* 0x01 */
+ &IX86_OPS_BASE::PREFIX86(_add_r8b), /* 0x02 */
+ &IX86_OPS_BASE::PREFIX86(_add_r16w), /* 0x03 */
+ &IX86_OPS_BASE::PREFIX86(_add_ald8), /* 0x04 */
+ &IX86_OPS_BASE::PREFIX86(_add_axd16), /* 0x05 */
+ &IX86_OPS_BASE::PREFIX86(_push_es), /* 0x06 */
+ &IX86_OPS_BASE::PREFIX86(_pop_es), /* 0x07 */
+ &IX86_OPS_BASE::PREFIX86(_or_br8), /* 0x08 */
+ &IX86_OPS_BASE::PREFIX86(_or_wr16), /* 0x09 */
+ &IX86_OPS_BASE::PREFIX86(_or_r8b), /* 0x0a */
+ &IX86_OPS_BASE::PREFIX86(_or_r16w), /* 0x0b */
+ &IX86_OPS_BASE::PREFIX86(_or_ald8), /* 0x0c */
+ &IX86_OPS_BASE::PREFIX86(_or_axd16), /* 0x0d */
+ &IX86_OPS_BASE::PREFIX86(_push_cs), /* 0x0e */
+ &IX86_OPS_BASE::PREFIX86(_pop_cs), /* 0x0f */
+ &IX86_OPS_BASE::PREFIX86(_adc_br8), /* 0x10 */
+ &IX86_OPS_BASE::PREFIX86(_adc_wr16), /* 0x11 */
+ &IX86_OPS_BASE::PREFIX86(_adc_r8b), /* 0x12 */
+ &IX86_OPS_BASE::PREFIX86(_adc_r16w), /* 0x13 */
+ &IX86_OPS_BASE::PREFIX86(_adc_ald8), /* 0x14 */
+ &IX86_OPS_BASE::PREFIX86(_adc_axd16), /* 0x15 */
+ &IX86_OPS_BASE::PREFIX86(_push_ss), /* 0x16 */
+ &IX86_OPS_BASE::PREFIX86(_pop_ss), /* 0x17 */
+ &IX86_OPS_BASE::PREFIX86(_sbb_br8), /* 0x18 */
+ &IX86_OPS_BASE::PREFIX86(_sbb_wr16), /* 0x19 */
+ &IX86_OPS_BASE::PREFIX86(_sbb_r8b), /* 0x1a */
+ &IX86_OPS_BASE::PREFIX86(_sbb_r16w), /* 0x1b */
+ &IX86_OPS_BASE::PREFIX86(_sbb_ald8), /* 0x1c */
+ &IX86_OPS_BASE::PREFIX86(_sbb_axd16), /* 0x1d */
+ &IX86_OPS_BASE::PREFIX86(_push_ds), /* 0x1e */
+ &IX86_OPS_BASE::PREFIX86(_pop_ds), /* 0x1f */
+ &IX86_OPS_BASE::PREFIX86(_and_br8), /* 0x20 */
+ &IX86_OPS_BASE::PREFIX86(_and_wr16), /* 0x21 */
+ &IX86_OPS_BASE::PREFIX86(_and_r8b), /* 0x22 */
+ &IX86_OPS_BASE::PREFIX86(_and_r16w), /* 0x23 */
+ &IX86_OPS_BASE::PREFIX86(_and_ald8), /* 0x24 */
+ &IX86_OPS_BASE::PREFIX86(_and_axd16), /* 0x25 */
+ &IX86_OPS_BASE::PREFIX86(_es), /* 0x26 */
+ &IX86_OPS_BASE::PREFIX86(_daa), /* 0x27 */
+ &IX86_OPS_BASE::PREFIX86(_sub_br8), /* 0x28 */
+ &IX86_OPS_BASE::PREFIX86(_sub_wr16), /* 0x29 */
+ &IX86_OPS_BASE::PREFIX86(_sub_r8b), /* 0x2a */
+ &IX86_OPS_BASE::PREFIX86(_sub_r16w), /* 0x2b */
+ &IX86_OPS_BASE::PREFIX86(_sub_ald8), /* 0x2c */
+ &IX86_OPS_BASE::PREFIX86(_sub_axd16), /* 0x2d */
+ &IX86_OPS_BASE::PREFIX86(_cs), /* 0x2e */
+ &IX86_OPS_BASE::PREFIX86(_das), /* 0x2f */
+ &IX86_OPS_BASE::PREFIX86(_xor_br8), /* 0x30 */
+ &IX86_OPS_BASE::PREFIX86(_xor_wr16), /* 0x31 */
+ &IX86_OPS_BASE::PREFIX86(_xor_r8b), /* 0x32 */
+ &IX86_OPS_BASE::PREFIX86(_xor_r16w), /* 0x33 */
+ &IX86_OPS_BASE::PREFIX86(_xor_ald8), /* 0x34 */
+ &IX86_OPS_BASE::PREFIX86(_xor_axd16), /* 0x35 */
+ &IX86_OPS_BASE::PREFIX86(_ss), /* 0x36 */
+ &IX86_OPS_BASE::PREFIX86(_aaa), /* 0x37 */
+ &IX86_OPS_BASE::PREFIX86(_cmp_br8), /* 0x38 */
+ &IX86_OPS_BASE::PREFIX86(_cmp_wr16), /* 0x39 */
+ &IX86_OPS_BASE::PREFIX86(_cmp_r8b), /* 0x3a */
+ &IX86_OPS_BASE::PREFIX86(_cmp_r16w), /* 0x3b */
+ &IX86_OPS_BASE::PREFIX86(_cmp_ald8), /* 0x3c */
+ &IX86_OPS_BASE::PREFIX86(_cmp_axd16), /* 0x3d */
+ &IX86_OPS_BASE::PREFIX86(_ds), /* 0x3e */
+ &IX86_OPS_BASE::PREFIX86(_aas), /* 0x3f */
+ &IX86_OPS_BASE::PREFIX86(_inc_ax), /* 0x40 */
+ &IX86_OPS_BASE::PREFIX86(_inc_cx), /* 0x41 */
+ &IX86_OPS_BASE::PREFIX86(_inc_dx), /* 0x42 */
+ &IX86_OPS_BASE::PREFIX86(_inc_bx), /* 0x43 */
+ &IX86_OPS_BASE::PREFIX86(_inc_sp), /* 0x44 */
+ &IX86_OPS_BASE::PREFIX86(_inc_bp), /* 0x45 */
+ &IX86_OPS_BASE::PREFIX86(_inc_si), /* 0x46 */
+ &IX86_OPS_BASE::PREFIX86(_inc_di), /* 0x47 */
+ &IX86_OPS_BASE::PREFIX86(_dec_ax), /* 0x48 */
+ &IX86_OPS_BASE::PREFIX86(_dec_cx), /* 0x49 */
+ &IX86_OPS_BASE::PREFIX86(_dec_dx), /* 0x4a */
+ &IX86_OPS_BASE::PREFIX86(_dec_bx), /* 0x4b */
+ &IX86_OPS_BASE::PREFIX86(_dec_sp), /* 0x4c */
+ &IX86_OPS_BASE::PREFIX86(_dec_bp), /* 0x4d */
+ &IX86_OPS_BASE::PREFIX86(_dec_si), /* 0x4e */
+ &IX86_OPS_BASE::PREFIX86(_dec_di), /* 0x4f */
+ &IX86_OPS_BASE::PREFIX86(_push_ax), /* 0x50 */
+ &IX86_OPS_BASE::PREFIX86(_push_cx), /* 0x51 */
+ &IX86_OPS_BASE::PREFIX86(_push_dx), /* 0x52 */
+ &IX86_OPS_BASE::PREFIX86(_push_bx), /* 0x53 */
+ &IX86_OPS_BASE::PREFIX86(_push_sp), /* 0x54 */
+ &IX86_OPS_BASE::PREFIX86(_push_bp), /* 0x55 */
+ &IX86_OPS_BASE::PREFIX86(_push_si), /* 0x56 */
+ &IX86_OPS_BASE::PREFIX86(_push_di), /* 0x57 */
+ &IX86_OPS_BASE::PREFIX86(_pop_ax), /* 0x58 */
+ &IX86_OPS_BASE::PREFIX86(_pop_cx), /* 0x59 */
+ &IX86_OPS_BASE::PREFIX86(_pop_dx), /* 0x5a */
+ &IX86_OPS_BASE::PREFIX86(_pop_bx), /* 0x5b */
+ &IX86_OPS_BASE::PREFIX86(_pop_sp), /* 0x5c */
+ &IX86_OPS_BASE::PREFIX86(_pop_bp), /* 0x5d */
+ &IX86_OPS_BASE::PREFIX86(_pop_si), /* 0x5e */
+ &IX86_OPS_BASE::PREFIX86(_pop_di), /* 0x5f */
+ &IX86_OPS_BASE::PREFIX86(_invalid_2b), // &IX86_OPS_BASE::PREFIX86(_pusha), /* 0x60 */
+ &IX86_OPS_BASE::PREFIX86(_invalid_2b), // &IX86_OPS_BASE::PREFIX86(_popa), /* 0x61 */
+ &IX86_OPS_BASE::PREFIX86(_invalid_2b), // &IX86_OPS_BASE::PREFIX86(_bound), /* 0x62 */
+ &IX86_OPS_BASE::PREFIX86(_invalid_2b),
+ &IX86_OPS_BASE::PREFIX86(_invalid_2b),
+ &IX86_OPS_BASE::PREFIX86(_invalid_2b),
+ &IX86_OPS_BASE::PREFIX86(_invalid_2b),
+ &IX86_OPS_BASE::PREFIX86(_invalid_2b),
+ &IX86_OPS_BASE::PREFIX86(_invalid_2b), //i_push_d16), /* 0x68 */
+ &IX86_OPS_BASE::PREFIX86(_invalid_2b), //i_imul_d16), /* 0x69 */
+ &IX86_OPS_BASE::PREFIX86(_invalid_2b), //i_push_d8), /* 0x6a */
+ &IX86_OPS_BASE::PREFIX86(_invalid_2b), //i_imul_d8), /* 0x6b */
+ &IX86_OPS_BASE::PREFIX86(_invalid_2b), //i_insb), /* 0x6c */
+ &IX86_OPS_BASE::PREFIX86(_invalid_2b), //i_insw), /* 0x6d */
+ &IX86_OPS_BASE::PREFIX86(_invalid_2b), //i_outsb), /* 0x6e */
+ &IX86_OPS_BASE::PREFIX86(_invalid_2b), //i_outsw), /* 0x6f */
+ &IX86_OPS_BASE::PREFIX86(_jo), /* 0x70 */
+ &IX86_OPS_BASE::PREFIX86(_jno), /* 0x71 */
+ &IX86_OPS_BASE::PREFIX86(_jb), /* 0x72 */
+ &IX86_OPS_BASE::PREFIX86(_jnb), /* 0x73 */
+ &IX86_OPS_BASE::PREFIX86(_jz), /* 0x74 */
+ &IX86_OPS_BASE::PREFIX86(_jnz), /* 0x75 */
+ &IX86_OPS_BASE::PREFIX86(_jbe), /* 0x76 */
+ &IX86_OPS_BASE::PREFIX86(_jnbe), /* 0x77 */
+ &IX86_OPS_BASE::PREFIX86(_js), /* 0x78 */
+ &IX86_OPS_BASE::PREFIX86(_jns), /* 0x79 */
+ &IX86_OPS_BASE::PREFIX86(_jp), /* 0x7a */
+ &IX86_OPS_BASE::PREFIX86(_jnp), /* 0x7b */
+ &IX86_OPS_BASE::PREFIX86(_jl), /* 0x7c */
+ &IX86_OPS_BASE::PREFIX86(_jnl), /* 0x7d */
+ &IX86_OPS_BASE::PREFIX86(_jle), /* 0x7e */
+ &IX86_OPS_BASE::PREFIX86(_jnle), /* 0x7f */
+ &IX86_OPS_BASE::PREFIX86(_80pre), /* 0x80 */
+ &IX86_OPS_BASE::PREFIX86(_81pre), /* 0x81 */
+ &IX86_OPS_BASE::PREFIX86(_82pre), /* 0x82 */
+ &IX86_OPS_BASE::PREFIX86(_83pre), /* 0x83 */
+ &IX86_OPS_BASE::PREFIX86(_test_br8), /* 0x84 */
+ &IX86_OPS_BASE::PREFIX86(_test_wr16), /* 0x85 */
+ &IX86_OPS_BASE::PREFIX86(_xchg_br8), /* 0x86 */
+ &IX86_OPS_BASE::PREFIX86(_xchg_wr16), /* 0x87 */
+ &IX86_OPS_BASE::PREFIX86(_mov_br8), /* 0x88 */
+ &IX86_OPS_BASE::PREFIX86(_mov_wr16), /* 0x89 */
+ &IX86_OPS_BASE::PREFIX86(_mov_r8b), /* 0x8a */
+ &IX86_OPS_BASE::PREFIX86(_mov_r16w), /* 0x8b */
+ &IX86_OPS_BASE::PREFIX86(_mov_wsreg), /* 0x8c */
+ &IX86_OPS_BASE::PREFIX86(_lea), /* 0x8d */
+ &IX86_OPS_BASE::PREFIX86(_mov_sregw), /* 0x8e */
+ &IX86_OPS_BASE::PREFIX86(_popw), /* 0x8f */
+ &IX86_OPS_BASE::PREFIX86(_nop), /* 0x90 */
+ &IX86_OPS_BASE::PREFIX86(_xchg_axcx), /* 0x91 */
+ &IX86_OPS_BASE::PREFIX86(_xchg_axdx), /* 0x92 */
+ &IX86_OPS_BASE::PREFIX86(_xchg_axbx), /* 0x93 */
+ &IX86_OPS_BASE::PREFIX86(_xchg_axsp), /* 0x94 */
+ &IX86_OPS_BASE::PREFIX86(_xchg_axbp), /* 0x95 */
+ &IX86_OPS_BASE::PREFIX86(_xchg_axsi), /* 0x97 */
+ &IX86_OPS_BASE::PREFIX86(_xchg_axdi), /* 0x97 */
+ &IX86_OPS_BASE::PREFIX86(_cbw), /* 0x98 */
+ &IX86_OPS_BASE::PREFIX86(_cwd), /* 0x99 */
+ &IX86_OPS_BASE::PREFIX86(_call_far), /* 0x9a */
+ &IX86_OPS_BASE::PREFIX86(_wait), /* 0x9b */
+ &IX86_OPS_BASE::PREFIX86(_pushf), /* 0x9c */
+ &IX86_OPS_BASE::PREFIX86(_popf), /* 0x9d */
+ &IX86_OPS_BASE::PREFIX86(_sahf), /* 0x9e */
+ &IX86_OPS_BASE::PREFIX86(_lahf), /* 0x9f */
+ &IX86_OPS_BASE::PREFIX86(_mov_aldisp), /* 0xa0 */
+ &IX86_OPS_BASE::PREFIX86(_mov_axdisp), /* 0xa1 */
+ &IX86_OPS_BASE::PREFIX86(_mov_dispal), /* 0xa2 */
+ &IX86_OPS_BASE::PREFIX86(_mov_dispax), /* 0xa3 */
+ &IX86_OPS_BASE::PREFIX86(_movsb), /* 0xa4 */
+ &IX86_OPS_BASE::PREFIX86(_movsw), /* 0xa5 */
+ &IX86_OPS_BASE::PREFIX86(_cmpsb), /* 0xa6 */
+ &IX86_OPS_BASE::PREFIX86(_cmpsw), /* 0xa7 */
+ &IX86_OPS_BASE::PREFIX86(_test_ald8), /* 0xa8 */
+ &IX86_OPS_BASE::PREFIX86(_test_axd16), /* 0xa9 */
+ &IX86_OPS_BASE::PREFIX86(_stosb), /* 0xaa */
+ &IX86_OPS_BASE::PREFIX86(_stosw), /* 0xab */
+ &IX86_OPS_BASE::PREFIX86(_lodsb), /* 0xac */
+ &IX86_OPS_BASE::PREFIX86(_lodsw), /* 0xad */
+ &IX86_OPS_BASE::PREFIX86(_scasb), /* 0xae */
+ &IX86_OPS_BASE::PREFIX86(_scasw), /* 0xaf */
+ &IX86_OPS_BASE::PREFIX86(_mov_ald8), /* 0xb0 */
+ &IX86_OPS_BASE::PREFIX86(_mov_cld8), /* 0xb1 */
+ &IX86_OPS_BASE::PREFIX86(_mov_dld8), /* 0xb2 */
+ &IX86_OPS_BASE::PREFIX86(_mov_bld8), /* 0xb3 */
+ &IX86_OPS_BASE::PREFIX86(_mov_ahd8), /* 0xb4 */
+ &IX86_OPS_BASE::PREFIX86(_mov_chd8), /* 0xb5 */
+ &IX86_OPS_BASE::PREFIX86(_mov_dhd8), /* 0xb6 */
+ &IX86_OPS_BASE::PREFIX86(_mov_bhd8), /* 0xb7 */
+ &IX86_OPS_BASE::PREFIX86(_mov_axd16), /* 0xb8 */
+ &IX86_OPS_BASE::PREFIX86(_mov_cxd16), /* 0xb9 */
+ &IX86_OPS_BASE::PREFIX86(_mov_dxd16), /* 0xba */
+ &IX86_OPS_BASE::PREFIX86(_mov_bxd16), /* 0xbb */
+ &IX86_OPS_BASE::PREFIX86(_mov_spd16), /* 0xbc */
+ &IX86_OPS_BASE::PREFIX86(_mov_bpd16), /* 0xbd */
+ &IX86_OPS_BASE::PREFIX86(_mov_sid16), /* 0xbe */
+ &IX86_OPS_BASE::PREFIX86(_mov_did16), /* 0xbf */
+ &IX86_OPS_BASE::PREFIX86(_invalid), // &IX86_OPS_BASE::PREFIX86(_rotshft_bd8), /* 0xc0 */
+ &IX86_OPS_BASE::PREFIX86(_invalid), // &IX86_OPS_BASE::PREFIX86(_rotshft_wd8), /* 0xc1 */
+ &IX86_OPS_BASE::PREFIX86(_ret_d16), /* 0xc2 */
+ &IX86_OPS_BASE::PREFIX86(_ret), /* 0xc3 */
+ &IX86_OPS_BASE::PREFIX86(_les_dw), /* 0xc4 */
+ &IX86_OPS_BASE::PREFIX86(_lds_dw), /* 0xc5 */
+ &IX86_OPS_BASE::PREFIX86(_mov_bd8), /* 0xc6 */
+ &IX86_OPS_BASE::PREFIX86(_mov_wd16), /* 0xc7 */
+ &IX86_OPS_BASE::PREFIX86(_invalid), //i_enter), /* 0xc8 */
+ &IX86_OPS_BASE::PREFIX86(_invalid), //leave), /* 0xc9 */
+ &IX86_OPS_BASE::PREFIX86(_retf_d16), /* 0xca */
+ &IX86_OPS_BASE::PREFIX86(_retf), /* 0xcb */
+ &IX86_OPS_BASE::PREFIX86(_int3), /* 0xcc */
+ &IX86_OPS_BASE::PREFIX86(_int), /* 0xcd */
+ &IX86_OPS_BASE::PREFIX86(_into), /* 0xce */
+ &IX86_OPS_BASE::PREFIX86(_iret), /* 0xcf */
+ &IX86_OPS_BASE::PREFIX86(_rotshft_b), /* 0xd0 */
+ &IX86_OPS_BASE::PREFIX86(_rotshft_w), /* 0xd1 */
+ &IX86_OPS_BASE::PREFIX86(_rotshft_bcl), /* 0xd2 */
+ &IX86_OPS_BASE::PREFIX86(_rotshft_wcl), /* 0xd3 */
+ &IX86_OPS_BASE::PREFIX86(_aam), /* 0xd4 */
+ &IX86_OPS_BASE::PREFIX86(_aad), /* 0xd5 */
+ &IX86_OPS_BASE::PREFIX86(_invalid),
+ &IX86_OPS_BASE::PREFIX86(_xlat), /* 0xd7 */
+ &IX86_OPS_BASE::PREFIX86(_escape), /* 0xd8 */
+ &IX86_OPS_BASE::PREFIX86(_escape), /* 0xd9 */
+ &IX86_OPS_BASE::PREFIX86(_escape), /* 0xda */
+ &IX86_OPS_BASE::PREFIX86(_escape), /* 0xdb */
+ &IX86_OPS_BASE::PREFIX86(_escape), /* 0xdc */
+ &IX86_OPS_BASE::PREFIX86(_escape), /* 0xdd */
+ &IX86_OPS_BASE::PREFIX86(_escape), /* 0xde */
+ &IX86_OPS_BASE::PREFIX86(_escape), /* 0xdf */
+ &IX86_OPS_BASE::PREFIX86(_loopne), /* 0xe0 */
+ &IX86_OPS_BASE::PREFIX86(_loope), /* 0xe1 */
+ &IX86_OPS_BASE::PREFIX86(_loop), /* 0xe2 */
+ &IX86_OPS_BASE::PREFIX86(_jcxz), /* 0xe3 */
+ &IX86_OPS_BASE::PREFIX86(_inal), /* 0xe4 */
+ &IX86_OPS_BASE::PREFIX86(_inax), /* 0xe5 */
+ &IX86_OPS_BASE::PREFIX86(_outal), /* 0xe6 */
+ &IX86_OPS_BASE::PREFIX86(_outax), /* 0xe7 */
+ &IX86_OPS_BASE::PREFIX86(_call_d16), /* 0xe8 */
+ &IX86_OPS_BASE::PREFIX86(_jmp_d16), /* 0xe9 */
+ &IX86_OPS_BASE::PREFIX86(_jmp_far), /* 0xea */
+ &IX86_OPS_BASE::PREFIX86(_jmp_d8), /* 0xeb */
+ &IX86_OPS_BASE::PREFIX86(_inaldx), /* 0xec */
+ &IX86_OPS_BASE::PREFIX86(_inaxdx), /* 0xed */
+ &IX86_OPS_BASE::PREFIX86(_outdxal), /* 0xee */
+ &IX86_OPS_BASE::PREFIX86(_outdxax), /* 0xef */
+ &IX86_OPS_BASE::PREFIX86(_lock), /* 0xf0 */
+ &IX86_OPS_BASE::PREFIX86(_invalid), /* 0xf1 */
+ &IX86_OPS_BASE::PREFIX86(_repne), /* 0xf2 */
+ &IX86_OPS_BASE::PREFIX86(_repe), /* 0xf3 */
+ &IX86_OPS_BASE::PREFIX86(_hlt), /* 0xf4 */
+ &IX86_OPS_BASE::PREFIX86(_cmc), /* 0xf5 */
+ &IX86_OPS_BASE::PREFIX86(_f6pre), /* 0xf6 */
+ &IX86_OPS_BASE::PREFIX86(_f7pre), /* 0xf7 */
+ &IX86_OPS_BASE::PREFIX86(_clc), /* 0xf8 */
+ &IX86_OPS_BASE::PREFIX86(_stc), /* 0xf9 */
+ &IX86_OPS_BASE::PREFIX86(_cli), /* 0xfa */
+ &IX86_OPS_BASE::PREFIX86(_sti), /* 0xfb */
+ &IX86_OPS_BASE::PREFIX86(_cld), /* 0xfc */
+ &IX86_OPS_BASE::PREFIX86(_std), /* 0xfd */
+ &IX86_OPS_BASE::PREFIX86(_fepre), /* 0xfe */
+ &IX86_OPS_BASE::PREFIX86(_ffpre) /* 0xff */
+};
+
+#if defined(BIGCASE) && !defined(RS6000)
+ /* Some compilers cannot handle large case statements */
+#define TABLE86 \
+ switch(FETCHOP)\
+ {\
+ case 0x00: PREFIX86(_add_br8)(); break;\
+ case 0x01: PREFIX86(_add_wr16)(); break;\
+ case 0x02: PREFIX86(_add_r8b)(); break;\
+ case 0x03: PREFIX86(_add_r16w)(); break;\
+ case 0x04: PREFIX86(_add_ald8)(); break;\
+ case 0x05: PREFIX86(_add_axd16)(); break;\
+ case 0x06: PREFIX86(_push_es)(); break;\
+ case 0x07: PREFIX86(_pop_es)(); break;\
+ case 0x08: PREFIX86(_or_br8)(); break;\
+ case 0x09: PREFIX86(_or_wr16)(); break;\
+ case 0x0a: PREFIX86(_or_r8b)(); break;\
+ case 0x0b: PREFIX86(_or_r16w)(); break;\
+ case 0x0c: PREFIX86(_or_ald8)(); break;\
+ case 0x0d: PREFIX86(_or_axd16)(); break;\
+ case 0x0e: PREFIX86(_push_cs)(); break;\
+ case 0x0f: PREFIX86(_invalid)(); break;\
+ case 0x10: PREFIX86(_adc_br8)(); break;\
+ case 0x11: PREFIX86(_adc_wr16)(); break;\
+ case 0x12: PREFIX86(_adc_r8b)(); break;\
+ case 0x13: PREFIX86(_adc_r16w)(); break;\
+ case 0x14: PREFIX86(_adc_ald8)(); break;\
+ case 0x15: PREFIX86(_adc_axd16)(); break;\
+ case 0x16: PREFIX86(_push_ss)(); break;\
+ case 0x17: PREFIX86(_pop_ss)(); break;\
+ case 0x18: PREFIX86(_sbb_br8)(); break;\
+ case 0x19: PREFIX86(_sbb_wr16)(); break;\
+ case 0x1a: PREFIX86(_sbb_r8b)(); break;\
+ case 0x1b: PREFIX86(_sbb_r16w)(); break;\
+ case 0x1c: PREFIX86(_sbb_ald8)(); break;\
+ case 0x1d: PREFIX86(_sbb_axd16)(); break;\
+ case 0x1e: PREFIX86(_push_ds)(); break;\
+ case 0x1f: PREFIX86(_pop_ds)(); break;\
+ case 0x20: PREFIX86(_and_br8)(); break;\
+ case 0x21: PREFIX86(_and_wr16)(); break;\
+ case 0x22: PREFIX86(_and_r8b)(); break;\
+ case 0x23: PREFIX86(_and_r16w)(); break;\
+ case 0x24: PREFIX86(_and_ald8)(); break;\
+ case 0x25: PREFIX86(_and_axd16)(); break;\
+ case 0x26: PREFIX86(_es)(); break;\
+ case 0x27: PREFIX86(_daa)(); break;\
+ case 0x28: PREFIX86(_sub_br8)(); break;\
+ case 0x29: PREFIX86(_sub_wr16)(); break;\
+ case 0x2a: PREFIX86(_sub_r8b)(); break;\
+ case 0x2b: PREFIX86(_sub_r16w)(); break;\
+ case 0x2c: PREFIX86(_sub_ald8)(); break;\
+ case 0x2d: PREFIX86(_sub_axd16)(); break;\
+ case 0x2e: PREFIX86(_cs)(); break; \
+ case 0x2f: PREFIX86(_das)(cpustate); break;\
+ case 0x30: PREFIX86(_xor_br8)(cpustate); break;\
+ case 0x31: PREFIX86(_xor_wr16)(cpustate); break;\
+ case 0x32: PREFIX86(_xor_r8b)(cpustate); break;\
+ case 0x33: PREFIX86(_xor_r16w)(cpustate); break;\
+ case 0x34: PREFIX86(_xor_ald8)(cpustate); break;\
+ case 0x35: PREFIX86(_xor_axd16)(cpustate); break;\
+ case 0x36: PREFIX86(_ss)(cpustate); break;\
+ case 0x37: PREFIX86(_aaa)(cpustate); break;\
+ case 0x38: PREFIX86(_cmp_br8)(cpustate); break;\
+ case 0x39: PREFIX86(_cmp_wr16)(cpustate); break;\
+ case 0x3a: PREFIX86(_cmp_r8b)(cpustate); break;\
+ case 0x3b: PREFIX86(_cmp_r16w)(cpustate); break;\
+ case 0x3c: PREFIX86(_cmp_ald8)(cpustate); break;\
+ case 0x3d: PREFIX86(_cmp_axd16)(cpustate); break;\
+ case 0x3e: PREFIX86(_ds)(cpustate); break;\
+ case 0x3f: PREFIX86(_aas)(cpustate); break;\
+ case 0x40: PREFIX86(_inc_ax)(cpustate); break;\
+ case 0x41: PREFIX86(_inc_cx)(cpustate); break;\
+ case 0x42: PREFIX86(_inc_dx)(cpustate); break;\
+ case 0x43: PREFIX86(_inc_bx)(cpustate); break;\
+ case 0x44: PREFIX86(_inc_sp)(cpustate); break;\
+ case 0x45: PREFIX86(_inc_bp)(cpustate); break;\
+ case 0x46: PREFIX86(_inc_si)(cpustate); break;\
+ case 0x47: PREFIX86(_inc_di)(cpustate); break;\
+ case 0x48: PREFIX86(_dec_ax)(cpustate); break;\
+ case 0x49: PREFIX86(_dec_cx)(cpustate); break;\
+ case 0x4a: PREFIX86(_dec_dx)(cpustate); break;\
+ case 0x4b: PREFIX86(_dec_bx)(cpustate); break;\
+ case 0x4c: PREFIX86(_dec_sp)(cpustate); break;\
+ case 0x4d: PREFIX86(_dec_bp)(cpustate); break;\
+ case 0x4e: PREFIX86(_dec_si)(cpustate); break;\
+ case 0x4f: PREFIX86(_dec_di)(cpustate); break;\
+ case 0x50: PREFIX86(_push_ax)(cpustate); break;\
+ case 0x51: PREFIX86(_push_cx)(cpustate); break;\
+ case 0x52: PREFIX86(_push_dx)(cpustate); break;\
+ case 0x53: PREFIX86(_push_bx)(cpustate); break;\
+ case 0x54: PREFIX86(_push_sp)(cpustate); break;\
+ case 0x55: PREFIX86(_push_bp)(cpustate); break;\
+ case 0x56: PREFIX86(_push_si)(cpustate); break;\
+ case 0x57: PREFIX86(_push_di)(cpustate); break;\
+ case 0x58: PREFIX86(_pop_ax)(cpustate); break;\
+ case 0x59: PREFIX86(_pop_cx)(cpustate); break;\
+ case 0x5a: PREFIX86(_pop_dx)(cpustate); break;\
+ case 0x5b: PREFIX86(_pop_bx)(cpustate); break;\
+ case 0x5c: PREFIX86(_pop_sp)(cpustate); break;\
+ case 0x5d: PREFIX86(_pop_bp)(cpustate); break;\
+ case 0x5e: PREFIX86(_pop_si)(cpustate); break;\
+ case 0x5f: PREFIX86(_pop_di)(cpustate); break;\
+ case 0x60: PREFIX86(_invalid_2b)(cpustate); break;\
+ case 0x61: PREFIX86(_invalid_2b)(cpustate); break;\
+ case 0x62: PREFIX86(_invalid_2b)(cpustate); break;\
+ case 0x63: PREFIX86(_invalid_2b)(cpustate); break;\
+ case 0x64: PREFIX86(_invalid_2b)(cpustate); break;\
+ case 0x65: PREFIX86(_invalid_2b)(cpustate); break;\
+ case 0x66: PREFIX86(_invalid_2b)(cpustate); break;\
+ case 0x67: PREFIX86(_invalid_2b)(cpustate); break;\
+ case 0x68: PREFIX86(_invalid_2b)(cpustate); break;\
+ case 0x69: PREFIX86(_invalid_2b)(cpustate); break;\
+ case 0x6a: PREFIX86(_invalid_2b)(cpustate); break;\
+ case 0x6b: PREFIX86(_invalid_2b)(cpustate); break;\
+ case 0x6c: PREFIX86(_invalid_2b)(cpustate); break;\
+ case 0x6d: PREFIX86(_invalid_2b)(cpustate); break;\
+ case 0x6e: PREFIX86(_invalid_2b)(cpustate); break;\
+ case 0x6f: PREFIX86(_invalid_2b)(cpustate); break;\
+ case 0x70: PREFIX86(_jo)(cpustate); break;\
+ case 0x71: PREFIX86(_jno)(cpustate); break;\
+ case 0x72: PREFIX86(_jb)(cpustate); break;\
+ case 0x73: PREFIX86(_jnb)(cpustate); break;\
+ case 0x74: PREFIX86(_jz)(cpustate); break;\
+ case 0x75: PREFIX86(_jnz)(cpustate); break;\
+ case 0x76: PREFIX86(_jbe)(cpustate); break;\
+ case 0x77: PREFIX86(_jnbe)(cpustate); break;\
+ case 0x78: PREFIX86(_js)(cpustate); break;\
+ case 0x79: PREFIX86(_jns)(cpustate); break;\
+ case 0x7a: PREFIX86(_jp)(cpustate); break;\
+ case 0x7b: PREFIX86(_jnp)(cpustate); break;\
+ case 0x7c: PREFIX86(_jl)(cpustate); break;\
+ case 0x7d: PREFIX86(_jnl)(cpustate); break;\
+ case 0x7e: PREFIX86(_jle)(cpustate); break;\
+ case 0x7f: PREFIX86(_jnle)(cpustate); break;\
+ case 0x80: PREFIX86(_80pre)(cpustate); break;\
+ case 0x81: PREFIX86(_81pre)(cpustate); break;\
+ case 0x82: PREFIX86(_82pre)(cpustate); break;\
+ case 0x83: PREFIX86(_83pre)(cpustate); break;\
+ case 0x84: PREFIX86(_test_br8)(cpustate); break;\
+ case 0x85: PREFIX86(_test_wr16)(cpustate); break;\
+ case 0x86: PREFIX86(_xchg_br8)(cpustate); break;\
+ case 0x87: PREFIX86(_xchg_wr16)(cpustate); break;\
+ case 0x88: PREFIX86(_mov_br8)(cpustate); break;\
+ case 0x89: PREFIX86(_mov_wr16)(cpustate); break;\
+ case 0x8a: PREFIX86(_mov_r8b)(cpustate); break;\
+ case 0x8b: PREFIX86(_mov_r16w)(cpustate); break;\
+ case 0x8c: PREFIX86(_mov_wsreg)(cpustate); break;\
+ case 0x8d: PREFIX86(_lea)(cpustate); break;\
+ case 0x8e: PREFIX86(_mov_sregw)(cpustate); break;\
+ case 0x8f: PREFIX86(_popw)(cpustate); break;\
+ case 0x90: PREFIX86(_nop)(cpustate); break;\
+ case 0x91: PREFIX86(_xchg_axcx)(cpustate); break;\
+ case 0x92: PREFIX86(_xchg_axdx)(cpustate); break;\
+ case 0x93: PREFIX86(_xchg_axbx)(cpustate); break;\
+ case 0x94: PREFIX86(_xchg_axsp)(cpustate); break;\
+ case 0x95: PREFIX86(_xchg_axbp)(cpustate); break;\
+ case 0x96: PREFIX86(_xchg_axsi)(cpustate); break;\
+ case 0x97: PREFIX86(_xchg_axdi)(cpustate); break;\
+ case 0x98: PREFIX86(_cbw)(cpustate); break;\
+ case 0x99: PREFIX86(_cwd)(cpustate); break;\
+ case 0x9a: PREFIX86(_call_far)(cpustate); break;\
+ case 0x9b: PREFIX86(_wait)(cpustate); break;\
+ case 0x9c: PREFIX86(_pushf)(cpustate); break;\
+ case 0x9d: PREFIX86(_popf)(cpustate); break;\
+ case 0x9e: PREFIX86(_sahf)(cpustate); break;\
+ case 0x9f: PREFIX86(_lahf)(cpustate); break;\
+ case 0xa0: PREFIX86(_mov_aldisp)(cpustate); break;\
+ case 0xa1: PREFIX86(_mov_axdisp)(cpustate); break;\
+ case 0xa2: PREFIX86(_mov_dispal)(cpustate); break;\
+ case 0xa3: PREFIX86(_mov_dispax)(cpustate); break;\
+ case 0xa4: PREFIX86(_movsb)(cpustate); break;\
+ case 0xa5: PREFIX86(_movsw)(cpustate); break;\
+ case 0xa6: PREFIX86(_cmpsb)(cpustate); break;\
+ case 0xa7: PREFIX86(_cmpsw)(cpustate); break;\
+ case 0xa8: PREFIX86(_test_ald8)(cpustate); break;\
+ case 0xa9: PREFIX86(_test_axd16)(cpustate); break;\
+ case 0xaa: PREFIX86(_stosb)(cpustate); break;\
+ case 0xab: PREFIX86(_stosw)(cpustate); break;\
+ case 0xac: PREFIX86(_lodsb)(cpustate); break;\
+ case 0xad: PREFIX86(_lodsw)(cpustate); break;\
+ case 0xae: PREFIX86(_scasb)(cpustate); break;\
+ case 0xaf: PREFIX86(_scasw)(cpustate); break;\
+ case 0xb0: PREFIX86(_mov_ald8)(cpustate); break;\
+ case 0xb1: PREFIX86(_mov_cld8)(cpustate); break;\
+ case 0xb2: PREFIX86(_mov_dld8)(cpustate); break;\
+ case 0xb3: PREFIX86(_mov_bld8)(cpustate); break;\
+ case 0xb4: PREFIX86(_mov_ahd8)(cpustate); break;\
+ case 0xb5: PREFIX86(_mov_chd8)(cpustate); break;\
+ case 0xb6: PREFIX86(_mov_dhd8)(cpustate); break;\
+ case 0xb7: PREFIX86(_mov_bhd8)(cpustate); break;\
+ case 0xb8: PREFIX86(_mov_axd16)(cpustate); break;\
+ case 0xb9: PREFIX86(_mov_cxd16)(cpustate); break;\
+ case 0xba: PREFIX86(_mov_dxd16)(cpustate); break;\
+ case 0xbb: PREFIX86(_mov_bxd16)(cpustate); break;\
+ case 0xbc: PREFIX86(_mov_spd16)(cpustate); break;\
+ case 0xbd: PREFIX86(_mov_bpd16)(cpustate); break;\
+ case 0xbe: PREFIX86(_mov_sid16)(cpustate); break;\
+ case 0xbf: PREFIX86(_mov_did16)(cpustate); break;\
+ case 0xc0: PREFIX86(_invalid)(cpustate); break;\
+ case 0xc1: PREFIX86(_invalid)(cpustate); break;\
+ case 0xc2: PREFIX86(_ret_d16)(cpustate); break;\
+ case 0xc3: PREFIX86(_ret)(cpustate); break;\
+ case 0xc4: PREFIX86(_les_dw)(cpustate); break;\
+ case 0xc5: PREFIX86(_lds_dw)(cpustate); break;\
+ case 0xc6: PREFIX86(_mov_bd8)(cpustate); break;\
+ case 0xc7: PREFIX86(_mov_wd16)(cpustate); break;\
+ case 0xc8: PREFIX86(_invalid)(cpustate); break;\
+ case 0xc9: PREFIX86(_invalid)(cpustate); break;\
+ case 0xca: PREFIX86(_retf_d16)(cpustate); break;\
+ case 0xcb: PREFIX86(_retf)(cpustate); break;\
+ case 0xcc: PREFIX86(_int3)(cpustate); break;\
+ case 0xcd: PREFIX86(_int)(cpustate); break;\
+ case 0xce: PREFIX86(_into)(cpustate); break;\
+ case 0xcf: PREFIX86(_iret)(cpustate); break;\
+ case 0xd0: PREFIX86(_rotshft_b)(cpustate); break;\
+ case 0xd1: PREFIX86(_rotshft_w)(cpustate); break;\
+ case 0xd2: PREFIX86(_rotshft_bcl)(cpustate); break;\
+ case 0xd3: PREFIX86(_rotshft_wcl)(cpustate); break;\
+ case 0xd4: PREFIX86(_aam)(cpustate); break;\
+ case 0xd5: PREFIX86(_aad)(cpustate); break;\
+ case 0xd6: PREFIX86(_invalid)(cpustate); break;\
+ case 0xd7: PREFIX86(_xlat)(cpustate); break;\
+ case 0xd8: PREFIX86(_escape)(cpustate); break;\
+ case 0xd9: PREFIX86(_escape)(cpustate); break;\
+ case 0xda: PREFIX86(_escape)(cpustate); break;\
+ case 0xdb: PREFIX86(_escape)(cpustate); break;\
+ case 0xdc: PREFIX86(_escape)(cpustate); break;\
+ case 0xdd: PREFIX86(_escape)(cpustate); break;\
+ case 0xde: PREFIX86(_escape)(cpustate); break;\
+ case 0xdf: PREFIX86(_escape)(cpustate); break;\
+ case 0xe0: PREFIX86(_loopne)(cpustate); break;\
+ case 0xe1: PREFIX86(_loope)(cpustate); break;\
+ case 0xe2: PREFIX86(_loop)(cpustate); break;\
+ case 0xe3: PREFIX86(_jcxz)(cpustate); break;\
+ case 0xe4: PREFIX86(_inal)(cpustate); break;\
+ case 0xe5: PREFIX86(_inax)(cpustate); break;\
+ case 0xe6: PREFIX86(_outal)(cpustate); break;\
+ case 0xe7: PREFIX86(_outax)(cpustate); break;\
+ case 0xe8: PREFIX86(_call_d16)(cpustate); break;\
+ case 0xe9: PREFIX86(_jmp_d16)(cpustate); break;\
+ case 0xea: PREFIX86(_jmp_far)(cpustate); break;\
+ case 0xeb: PREFIX86(_jmp_d8)(cpustate); break;\
+ case 0xec: PREFIX86(_inaldx)(cpustate); break;\
+ case 0xed: PREFIX86(_inaxdx)(cpustate); break;\
+ case 0xee: PREFIX86(_outdxal)(cpustate); break;\
+ case 0xef: PREFIX86(_outdxax)(cpustate); break;\
+ case 0xf0: PREFIX86(_lock)(cpustate); break;\
+ case 0xf1: PREFIX86(_invalid)(cpustate); break;\
+ case 0xf2: PREFIX86(_repne)(cpustate); break;\
+ case 0xf3: PREFIX86(_repe)(cpustate); break;\
+ case 0xf4: PREFIX86(_hlt)(cpustate); break;\
+ case 0xf5: PREFIX86(_cmc)(cpustate); break;\
+ case 0xf6: PREFIX86(_f6pre)(cpustate); break;\
+ case 0xf7: PREFIX86(_f7pre)(cpustate); break;\
+ case 0xf8: PREFIX86(_clc)(cpustate); break;\
+ case 0xf9: PREFIX86(_stc)(cpustate); break;\
+ case 0xfa: PREFIX86(_cli)(cpustate); break;\
+ case 0xfb: PREFIX86(_sti)(cpustate); break;\
+ case 0xfc: PREFIX86(_cld)(cpustate); break;\
+ case 0xfd: PREFIX86(_std)(cpustate); break;\
+ case 0xfe: PREFIX86(_fepre)(cpustate); break;\
+ case 0xff: PREFIX86(_ffpre)(cpustate); break;\
+ };
+#else
+#define TABLE86 PREFIX86(_instruction)[FETCHOP]();
+#endif
--- /dev/null
+// special nec instructions missing
+// at the time the same like table186.h
+
+const void (IX86_OPS_BASE::*PREFIXV30(_instruction)[256])() =
+{
+ &IX86_OPS_BASE::PREFIX86(_add_br8), /* 0x00 */
+ &IX86_OPS_BASE::PREFIX86(_add_wr16), /* 0x01 */
+ &IX86_OPS_BASE::PREFIX86(_add_r8b), /* 0x02 */
+ &IX86_OPS_BASE::PREFIX86(_add_r16w), /* 0x03 */
+ &IX86_OPS_BASE::PREFIX86(_add_ald8), /* 0x04 */
+ &IX86_OPS_BASE::PREFIX86(_add_axd16), /* 0x05 */
+ &IX86_OPS_BASE::PREFIX86(_push_es), /* 0x06 */
+ &IX86_OPS_BASE::PREFIX86(_pop_es), /* 0x07 */
+ &IX86_OPS_BASE::PREFIX86(_or_br8), /* 0x08 */
+ &IX86_OPS_BASE::PREFIX86(_or_wr16), /* 0x09 */
+ &IX86_OPS_BASE::PREFIX86(_or_r8b), /* 0x0a */
+ &IX86_OPS_BASE::PREFIX86(_or_r16w), /* 0x0b */
+ &IX86_OPS_BASE::PREFIX86(_or_ald8), /* 0x0c */
+ &IX86_OPS_BASE::PREFIX86(_or_axd16), /* 0x0d */
+ &IX86_OPS_BASE::PREFIX86(_push_cs), /* 0x0e */
+ &IX86_OPS_BASE::PREFIXV30(_0fpre), /* 0x0f */
+ &IX86_OPS_BASE::PREFIX86(_adc_br8), /* 0x10 */
+ &IX86_OPS_BASE::PREFIX86(_adc_wr16), /* 0x11 */
+ &IX86_OPS_BASE::PREFIX86(_adc_r8b), /* 0x12 */
+ &IX86_OPS_BASE::PREFIX86(_adc_r16w), /* 0x13 */
+ &IX86_OPS_BASE::PREFIX86(_adc_ald8), /* 0x14 */
+ &IX86_OPS_BASE::PREFIX86(_adc_axd16), /* 0x15 */
+ &IX86_OPS_BASE::PREFIX86(_push_ss), /* 0x16 */
+ &IX86_OPS_BASE::PREFIXV30(_pop_ss), /* 0x17 */
+ &IX86_OPS_BASE::PREFIX86(_sbb_br8), /* 0x18 */
+ &IX86_OPS_BASE::PREFIX86(_sbb_wr16), /* 0x19 */
+ &IX86_OPS_BASE::PREFIX86(_sbb_r8b), /* 0x1a */
+ &IX86_OPS_BASE::PREFIX86(_sbb_r16w), /* 0x1b */
+ &IX86_OPS_BASE::PREFIX86(_sbb_ald8), /* 0x1c */
+ &IX86_OPS_BASE::PREFIX86(_sbb_axd16), /* 0x1d */
+ &IX86_OPS_BASE::PREFIX86(_push_ds), /* 0x1e */
+ &IX86_OPS_BASE::PREFIX86(_pop_ds), /* 0x1f */
+ &IX86_OPS_BASE::PREFIX86(_and_br8), /* 0x20 */
+ &IX86_OPS_BASE::PREFIX86(_and_wr16), /* 0x21 */
+ &IX86_OPS_BASE::PREFIX86(_and_r8b), /* 0x22 */
+ &IX86_OPS_BASE::PREFIX86(_and_r16w), /* 0x23 */
+ &IX86_OPS_BASE::PREFIX86(_and_ald8), /* 0x24 */
+ &IX86_OPS_BASE::PREFIX86(_and_axd16), /* 0x25 */
+ &IX86_OPS_BASE::PREFIXV30(_es), /* 0x26 */
+ &IX86_OPS_BASE::PREFIX86(_daa), /* 0x27 */
+ &IX86_OPS_BASE::PREFIX86(_sub_br8), /* 0x28 */
+ &IX86_OPS_BASE::PREFIX86(_sub_wr16), /* 0x29 */
+ &IX86_OPS_BASE::PREFIX86(_sub_r8b), /* 0x2a */
+ &IX86_OPS_BASE::PREFIX86(_sub_r16w), /* 0x2b */
+ &IX86_OPS_BASE::PREFIX86(_sub_ald8), /* 0x2c */
+ &IX86_OPS_BASE::PREFIX86(_sub_axd16), /* 0x2d */
+ &IX86_OPS_BASE::PREFIXV30(_cs), /* 0x2e */
+ &IX86_OPS_BASE::PREFIX86(_das), /* 0x2f */
+ &IX86_OPS_BASE::PREFIX86(_xor_br8), /* 0x30 */
+ &IX86_OPS_BASE::PREFIX86(_xor_wr16), /* 0x31 */
+ &IX86_OPS_BASE::PREFIX86(_xor_r8b), /* 0x32 */
+ &IX86_OPS_BASE::PREFIX86(_xor_r16w), /* 0x33 */
+ &IX86_OPS_BASE::PREFIX86(_xor_ald8), /* 0x34 */
+ &IX86_OPS_BASE::PREFIX86(_xor_axd16), /* 0x35 */
+ &IX86_OPS_BASE::PREFIXV30(_ss), /* 0x36 */
+ &IX86_OPS_BASE::PREFIX86(_aaa), /* 0x37 */
+ &IX86_OPS_BASE::PREFIX86(_cmp_br8), /* 0x38 */
+ &IX86_OPS_BASE::PREFIX86(_cmp_wr16), /* 0x39 */
+ &IX86_OPS_BASE::PREFIX86(_cmp_r8b), /* 0x3a */
+ &IX86_OPS_BASE::PREFIX86(_cmp_r16w), /* 0x3b */
+ &IX86_OPS_BASE::PREFIX86(_cmp_ald8), /* 0x3c */
+ &IX86_OPS_BASE::PREFIX86(_cmp_axd16), /* 0x3d */
+ &IX86_OPS_BASE::PREFIXV30(_ds), /* 0x3e */
+ &IX86_OPS_BASE::PREFIX86(_aas), /* 0x3f */
+ &IX86_OPS_BASE::PREFIX86(_inc_ax), /* 0x40 */
+ &IX86_OPS_BASE::PREFIX86(_inc_cx), /* 0x41 */
+ &IX86_OPS_BASE::PREFIX86(_inc_dx), /* 0x42 */
+ &IX86_OPS_BASE::PREFIX86(_inc_bx), /* 0x43 */
+ &IX86_OPS_BASE::PREFIX86(_inc_sp), /* 0x44 */
+ &IX86_OPS_BASE::PREFIX86(_inc_bp), /* 0x45 */
+ &IX86_OPS_BASE::PREFIX86(_inc_si), /* 0x46 */
+ &IX86_OPS_BASE::PREFIX86(_inc_di), /* 0x47 */
+ &IX86_OPS_BASE::PREFIX86(_dec_ax), /* 0x48 */
+ &IX86_OPS_BASE::PREFIX86(_dec_cx), /* 0x49 */
+ &IX86_OPS_BASE::PREFIX86(_dec_dx), /* 0x4a */
+ &IX86_OPS_BASE::PREFIX86(_dec_bx), /* 0x4b */
+ &IX86_OPS_BASE::PREFIX86(_dec_sp), /* 0x4c */
+ &IX86_OPS_BASE::PREFIX86(_dec_bp), /* 0x4d */
+ &IX86_OPS_BASE::PREFIX86(_dec_si), /* 0x4e */
+ &IX86_OPS_BASE::PREFIX86(_dec_di), /* 0x4f */
+ &IX86_OPS_BASE::PREFIX86(_push_ax), /* 0x50 */
+ &IX86_OPS_BASE::PREFIX86(_push_cx), /* 0x51 */
+ &IX86_OPS_BASE::PREFIX86(_push_dx), /* 0x52 */
+ &IX86_OPS_BASE::PREFIX86(_push_bx), /* 0x53 */
+ &IX86_OPS_BASE::PREFIX86(_push_sp), /* 0x54 */
+ &IX86_OPS_BASE::PREFIX86(_push_bp), /* 0x55 */
+ &IX86_OPS_BASE::PREFIX86(_push_si), /* 0x56 */
+ &IX86_OPS_BASE::PREFIX86(_push_di), /* 0x57 */
+ &IX86_OPS_BASE::PREFIX86(_pop_ax), /* 0x58 */
+ &IX86_OPS_BASE::PREFIX86(_pop_cx), /* 0x59 */
+ &IX86_OPS_BASE::PREFIX86(_pop_dx), /* 0x5a */
+ &IX86_OPS_BASE::PREFIX86(_pop_bx), /* 0x5b */
+ &IX86_OPS_BASE::PREFIX86(_pop_sp), /* 0x5c */
+ &IX86_OPS_BASE::PREFIX86(_pop_bp), /* 0x5d */
+ &IX86_OPS_BASE::PREFIX86(_pop_si), /* 0x5e */
+ &IX86_OPS_BASE::PREFIX86(_pop_di), /* 0x5f */
+ &IX86_OPS_BASE::PREFIX186(_pusha), /* 0x60 */
+ &IX86_OPS_BASE::PREFIX186(_popa), /* 0x61 */
+ &IX86_OPS_BASE::PREFIX186(_bound), /* 0x62 */
+ &IX86_OPS_BASE::PREFIX86(_invalid), /* 0x63 */
+ &IX86_OPS_BASE::PREFIXV30(_repnc), /* 0x64 */
+ &IX86_OPS_BASE::PREFIXV30(_repc), /* 0x65 */
+ &IX86_OPS_BASE::PREFIX86(_invalid), /* 0x66 */
+ &IX86_OPS_BASE::PREFIX86(_invalid), /* 0x67 */
+ &IX86_OPS_BASE::PREFIX186(_push_d16), /* 0x68 */
+ &IX86_OPS_BASE::PREFIX186(_imul_d16), /* 0x69 */
+ &IX86_OPS_BASE::PREFIX186(_push_d8), /* 0x6a */
+ &IX86_OPS_BASE::PREFIX186(_imul_d8), /* 0x6b */
+ &IX86_OPS_BASE::PREFIX186(_insb), /* 0x6c */
+ &IX86_OPS_BASE::PREFIX186(_insw), /* 0x6d */
+ &IX86_OPS_BASE::PREFIX186(_outsb), /* 0x6e */
+ &IX86_OPS_BASE::PREFIX186(_outsw), /* 0x6f */
+ &IX86_OPS_BASE::PREFIX86(_jo), /* 0x70 */
+ &IX86_OPS_BASE::PREFIX86(_jno), /* 0x71 */
+ &IX86_OPS_BASE::PREFIX86(_jb), /* 0x72 */
+ &IX86_OPS_BASE::PREFIX86(_jnb), /* 0x73 */
+ &IX86_OPS_BASE::PREFIX86(_jz), /* 0x74 */
+ &IX86_OPS_BASE::PREFIX86(_jnz), /* 0x75 */
+ &IX86_OPS_BASE::PREFIX86(_jbe), /* 0x76 */
+ &IX86_OPS_BASE::PREFIX86(_jnbe), /* 0x77 */
+ &IX86_OPS_BASE::PREFIX86(_js), /* 0x78 */
+ &IX86_OPS_BASE::PREFIX86(_jns), /* 0x79 */
+ &IX86_OPS_BASE::PREFIX86(_jp), /* 0x7a */
+ &IX86_OPS_BASE::PREFIX86(_jnp), /* 0x7b */
+ &IX86_OPS_BASE::PREFIX86(_jl), /* 0x7c */
+ &IX86_OPS_BASE::PREFIX86(_jnl), /* 0x7d */
+ &IX86_OPS_BASE::PREFIX86(_jle), /* 0x7e */
+ &IX86_OPS_BASE::PREFIX86(_jnle), /* 0x7f */
+ &IX86_OPS_BASE::PREFIX86(_80pre), /* 0x80 */
+ &IX86_OPS_BASE::PREFIX86(_81pre), /* 0x81 */
+ &IX86_OPS_BASE::PREFIX86(_82pre), /* 0x82 */
+ &IX86_OPS_BASE::PREFIX86(_83pre), /* 0x83 */
+ &IX86_OPS_BASE::PREFIX86(_test_br8), /* 0x84 */
+ &IX86_OPS_BASE::PREFIX86(_test_wr16), /* 0x85 */
+ &IX86_OPS_BASE::PREFIX86(_xchg_br8), /* 0x86 */
+ &IX86_OPS_BASE::PREFIX86(_xchg_wr16), /* 0x87 */
+ &IX86_OPS_BASE::PREFIX86(_mov_br8), /* 0x88 */
+ &IX86_OPS_BASE::PREFIX86(_mov_wr16), /* 0x89 */
+ &IX86_OPS_BASE::PREFIX86(_mov_r8b), /* 0x8a */
+ &IX86_OPS_BASE::PREFIX86(_mov_r16w), /* 0x8b */
+ &IX86_OPS_BASE::PREFIX86(_mov_wsreg), /* 0x8c */
+ &IX86_OPS_BASE::PREFIX86(_lea), /* 0x8d */
+ &IX86_OPS_BASE::PREFIXV30(_mov_sregw), /* 0x8e */
+ &IX86_OPS_BASE::PREFIX86(_popw), /* 0x8f */
+ &IX86_OPS_BASE::PREFIX86(_nop), /* 0x90 */
+ &IX86_OPS_BASE::PREFIX86(_xchg_axcx), /* 0x91 */
+ &IX86_OPS_BASE::PREFIX86(_xchg_axdx), /* 0x92 */
+ &IX86_OPS_BASE::PREFIX86(_xchg_axbx), /* 0x93 */
+ &IX86_OPS_BASE::PREFIX86(_xchg_axsp), /* 0x94 */
+ &IX86_OPS_BASE::PREFIX86(_xchg_axbp), /* 0x95 */
+ &IX86_OPS_BASE::PREFIX86(_xchg_axsi), /* 0x97 */
+ &IX86_OPS_BASE::PREFIX86(_xchg_axdi), /* 0x97 */
+ &IX86_OPS_BASE::PREFIX86(_cbw), /* 0x98 */
+ &IX86_OPS_BASE::PREFIX86(_cwd), /* 0x99 */
+ &IX86_OPS_BASE::PREFIX86(_call_far), /* 0x9a */
+ &IX86_OPS_BASE::PREFIX86(_wait), /* 0x9b */
+ &IX86_OPS_BASE::PREFIXV30(_pushf), /* 0x9c */
+ &IX86_OPS_BASE::PREFIX86(_popf), /* 0x9d */
+ &IX86_OPS_BASE::PREFIX86(_sahf), /* 0x9e */
+ &IX86_OPS_BASE::PREFIX86(_lahf), /* 0x9f */
+ &IX86_OPS_BASE::PREFIX86(_mov_aldisp), /* 0xa0 */
+ &IX86_OPS_BASE::PREFIX86(_mov_axdisp), /* 0xa1 */
+ &IX86_OPS_BASE::PREFIX86(_mov_dispal), /* 0xa2 */
+ &IX86_OPS_BASE::PREFIX86(_mov_dispax), /* 0xa3 */
+ &IX86_OPS_BASE::PREFIX86(_movsb), /* 0xa4 */
+ &IX86_OPS_BASE::PREFIX86(_movsw), /* 0xa5 */
+ &IX86_OPS_BASE::PREFIX86(_cmpsb), /* 0xa6 */
+ &IX86_OPS_BASE::PREFIX86(_cmpsw), /* 0xa7 */
+ &IX86_OPS_BASE::PREFIX86(_test_ald8), /* 0xa8 */
+ &IX86_OPS_BASE::PREFIX86(_test_axd16), /* 0xa9 */
+ &IX86_OPS_BASE::PREFIX86(_stosb), /* 0xaa */
+ &IX86_OPS_BASE::PREFIX86(_stosw), /* 0xab */
+ &IX86_OPS_BASE::PREFIX86(_lodsb), /* 0xac */
+ &IX86_OPS_BASE::PREFIX86(_lodsw), /* 0xad */
+ &IX86_OPS_BASE::PREFIX86(_scasb), /* 0xae */
+ &IX86_OPS_BASE::PREFIX86(_scasw), /* 0xaf */
+ &IX86_OPS_BASE::PREFIX86(_mov_ald8), /* 0xb0 */
+ &IX86_OPS_BASE::PREFIX86(_mov_cld8), /* 0xb1 */
+ &IX86_OPS_BASE::PREFIX86(_mov_dld8), /* 0xb2 */
+ &IX86_OPS_BASE::PREFIX86(_mov_bld8), /* 0xb3 */
+ &IX86_OPS_BASE::PREFIX86(_mov_ahd8), /* 0xb4 */
+ &IX86_OPS_BASE::PREFIX86(_mov_chd8), /* 0xb5 */
+ &IX86_OPS_BASE::PREFIX86(_mov_dhd8), /* 0xb6 */
+ &IX86_OPS_BASE::PREFIX86(_mov_bhd8), /* 0xb7 */
+ &IX86_OPS_BASE::PREFIX86(_mov_axd16), /* 0xb8 */
+ &IX86_OPS_BASE::PREFIX86(_mov_cxd16), /* 0xb9 */
+ &IX86_OPS_BASE::PREFIX86(_mov_dxd16), /* 0xba */
+ &IX86_OPS_BASE::PREFIX86(_mov_bxd16), /* 0xbb */
+ &IX86_OPS_BASE::PREFIX86(_mov_spd16), /* 0xbc */
+ &IX86_OPS_BASE::PREFIX86(_mov_bpd16), /* 0xbd */
+ &IX86_OPS_BASE::PREFIX86(_mov_sid16), /* 0xbe */
+ &IX86_OPS_BASE::PREFIX86(_mov_did16), /* 0xbf */
+ &IX86_OPS_BASE::PREFIX186(_rotshft_bd8), /* 0xc0 */
+ &IX86_OPS_BASE::PREFIX186(_rotshft_wd8), /* 0xc1 */
+ &IX86_OPS_BASE::PREFIX86(_ret_d16), /* 0xc2 */
+ &IX86_OPS_BASE::PREFIX86(_ret), /* 0xc3 */
+ &IX86_OPS_BASE::PREFIX86(_les_dw), /* 0xc4 */
+ &IX86_OPS_BASE::PREFIX86(_lds_dw), /* 0xc5 */
+ &IX86_OPS_BASE::PREFIX86(_mov_bd8), /* 0xc6 */
+ &IX86_OPS_BASE::PREFIX86(_mov_wd16), /* 0xc7 */
+ &IX86_OPS_BASE::PREFIX186(_enter), /* 0xc8 */
+ &IX86_OPS_BASE::PREFIX186(_leave), /* 0xc9 */
+ &IX86_OPS_BASE::PREFIX86(_retf_d16), /* 0xca */
+ &IX86_OPS_BASE::PREFIX86(_retf), /* 0xcb */
+ &IX86_OPS_BASE::PREFIX86(_int3), /* 0xcc */
+ &IX86_OPS_BASE::PREFIX86(_int), /* 0xcd */
+ &IX86_OPS_BASE::PREFIX86(_into), /* 0xce */
+ &IX86_OPS_BASE::PREFIX86(_iret), /* 0xcf */
+ &IX86_OPS_BASE::PREFIX86(_rotshft_b), /* 0xd0 */
+ &IX86_OPS_BASE::PREFIX86(_rotshft_w), /* 0xd1 */
+ &IX86_OPS_BASE::PREFIX86(_rotshft_bcl), /* 0xd2 */
+ &IX86_OPS_BASE::PREFIX86(_rotshft_wcl), /* 0xd3 */
+ &IX86_OPS_BASE::PREFIX86(_aam), /* 0xd4 */
+ &IX86_OPS_BASE::PREFIXV30(_aad), /* 0xd5 */
+ &IX86_OPS_BASE::PREFIXV30(_setalc), /* 0xd6 */
+ &IX86_OPS_BASE::PREFIX86(_xlat), /* 0xd7 */
+ &IX86_OPS_BASE::PREFIX86(_escape), /* 0xd8 */
+ &IX86_OPS_BASE::PREFIX86(_escape), /* 0xd9 */
+ &IX86_OPS_BASE::PREFIX86(_escape), /* 0xda */
+ &IX86_OPS_BASE::PREFIX86(_escape), /* 0xdb */
+ &IX86_OPS_BASE::PREFIX86(_escape), /* 0xdc */
+ &IX86_OPS_BASE::PREFIX86(_escape), /* 0xdd */
+ &IX86_OPS_BASE::PREFIX86(_escape), /* 0xde */
+ &IX86_OPS_BASE::PREFIX86(_escape), /* 0xdf */
+ &IX86_OPS_BASE::PREFIX86(_loopne), /* 0xe0 */
+ &IX86_OPS_BASE::PREFIX86(_loope), /* 0xe1 */
+ &IX86_OPS_BASE::PREFIX86(_loop), /* 0xe2 */
+ &IX86_OPS_BASE::PREFIX86(_jcxz), /* 0xe3 */
+ &IX86_OPS_BASE::PREFIX86(_inal), /* 0xe4 */
+ &IX86_OPS_BASE::PREFIX86(_inax), /* 0xe5 */
+ &IX86_OPS_BASE::PREFIX86(_outal), /* 0xe6 */
+ &IX86_OPS_BASE::PREFIX86(_outax), /* 0xe7 */
+ &IX86_OPS_BASE::PREFIX86(_call_d16), /* 0xe8 */
+ &IX86_OPS_BASE::PREFIX86(_jmp_d16), /* 0xe9 */
+ &IX86_OPS_BASE::PREFIX86(_jmp_far), /* 0xea */
+ &IX86_OPS_BASE::PREFIX86(_jmp_d8), /* 0xeb */
+ &IX86_OPS_BASE::PREFIX86(_inaldx), /* 0xec */
+ &IX86_OPS_BASE::PREFIX86(_inaxdx), /* 0xed */
+ &IX86_OPS_BASE::PREFIX86(_outdxal), /* 0xee */
+ &IX86_OPS_BASE::PREFIX86(_outdxax), /* 0xef */
+ &IX86_OPS_BASE::PREFIX86(_lock), /* 0xf0 */
+ &IX86_OPS_BASE::PREFIX86(_invalid), /* 0xf1 */
+ &IX86_OPS_BASE::PREFIXV30(_repne), /* 0xf2 */
+ &IX86_OPS_BASE::PREFIXV30(_repe), /* 0xf3 */
+ &IX86_OPS_BASE::PREFIX86(_hlt), /* 0xf4 */
+ &IX86_OPS_BASE::PREFIX86(_cmc), /* 0xf5 */
+ &IX86_OPS_BASE::PREFIX86(_f6pre), /* 0xf6 */
+ &IX86_OPS_BASE::PREFIX86(_f7pre), /* 0xf7 */
+ &IX86_OPS_BASE::PREFIX86(_clc), /* 0xf8 */
+ &IX86_OPS_BASE::PREFIX86(_stc), /* 0xf9 */
+ &IX86_OPS_BASE::PREFIX86(_cli), /* 0xfa */
+ &IX86_OPS_BASE::PREFIXV30(_sti), /* 0xfb */
+ &IX86_OPS_BASE::PREFIX86(_cld), /* 0xfc */
+ &IX86_OPS_BASE::PREFIX86(_std), /* 0xfd */
+ &IX86_OPS_BASE::PREFIX86(_fepre), /* 0xfe */
+ &IX86_OPS_BASE::PREFIX86(_ffpre) /* 0xff */
+};
+
+#if defined(BIGCASE) && !defined(RS6000)
+ /* Some compilers cannot handle large case statements */
+#define TABLEV30 \
+ switch(FETCHOP)\
+ {\
+ case 0x00: PREFIX86(_add_br8)(cpustate); break;\
+ case 0x01: PREFIX86(_add_wr16)(cpustate); break;\
+ case 0x02: PREFIX86(_add_r8b)(cpustate); break;\
+ case 0x03: PREFIX86(_add_r16w)(cpustate); break;\
+ case 0x04: PREFIX86(_add_ald8)(cpustate); break;\
+ case 0x05: PREFIX86(_add_axd16)(cpustate); break;\
+ case 0x06: PREFIX86(_push_es)(cpustate); break;\
+ case 0x07: PREFIX86(_pop_es)(cpustate); break;\
+ case 0x08: PREFIX86(_or_br8)(cpustate); break;\
+ case 0x09: PREFIX86(_or_wr16)(cpustate); break;\
+ case 0x0a: PREFIX86(_or_r8b)(cpustate); break;\
+ case 0x0b: PREFIX86(_or_r16w)(cpustate); break;\
+ case 0x0c: PREFIX86(_or_ald8)(cpustate); break;\
+ case 0x0d: PREFIX86(_or_axd16)(cpustate); break;\
+ case 0x0e: PREFIX86(_push_cs)(cpustate); break;\
+ case 0x0f: PREFIX86(_invalid)(cpustate); break;\
+ case 0x0f: PREFIXV30(_0fpre)(cpustate); break;\
+ case 0x10: PREFIX86(_adc_br8)(cpustate); break;\
+ case 0x11: PREFIX86(_adc_wr16)(cpustate); break;\
+ case 0x12: PREFIX86(_adc_r8b)(cpustate); break;\
+ case 0x13: PREFIX86(_adc_r16w)(cpustate); break;\
+ case 0x14: PREFIX86(_adc_ald8)(cpustate); break;\
+ case 0x15: PREFIX86(_adc_axd16)(cpustate); break;\
+ case 0x16: PREFIX86(_push_ss)(cpustate); break;\
+ case 0x17: PREFIXV30(_pop_ss)(cpustate); break;\
+ case 0x18: PREFIX86(_sbb_br8)(cpustate); break;\
+ case 0x19: PREFIX86(_sbb_wr16)(cpustate); break;\
+ case 0x1a: PREFIX86(_sbb_r8b)(cpustate); break;\
+ case 0x1b: PREFIX86(_sbb_r16w)(cpustate); break;\
+ case 0x1c: PREFIX86(_sbb_ald8)(cpustate); break;\
+ case 0x1d: PREFIX86(_sbb_axd16)(cpustate); break;\
+ case 0x1e: PREFIX86(_push_ds)(cpustate); break;\
+ case 0x1f: PREFIX86(_pop_ds)(cpustate); break;\
+ case 0x20: PREFIX86(_and_br8)(cpustate); break;\
+ case 0x21: PREFIX86(_and_wr16)(cpustate); break;\
+ case 0x22: PREFIX86(_and_r8b)(cpustate); break;\
+ case 0x23: PREFIX86(_and_r16w)(cpustate); break;\
+ case 0x24: PREFIX86(_and_ald8)(cpustate); break;\
+ case 0x25: PREFIX86(_and_axd16)(cpustate); break;\
+ case 0x26: PREFIXV30(_es)(cpustate); break;\
+ case 0x27: PREFIX86(_daa)(cpustate); break;\
+ case 0x28: PREFIX86(_sub_br8)(cpustate); break;\
+ case 0x29: PREFIX86(_sub_wr16)(cpustate); break;\
+ case 0x2a: PREFIX86(_sub_r8b)(cpustate); break;\
+ case 0x2b: PREFIX86(_sub_r16w)(cpustate); break;\
+ case 0x2c: PREFIX86(_sub_ald8)(cpustate); break;\
+ case 0x2d: PREFIX86(_sub_axd16)(cpustate); break;\
+ case 0x2e: PREFIXV30(_cs)(cpustate); break;\
+ case 0x2f: PREFIX86(_das)(cpustate); break;\
+ case 0x30: PREFIX86(_xor_br8)(cpustate); break;\
+ case 0x31: PREFIX86(_xor_wr16)(cpustate); break;\
+ case 0x32: PREFIX86(_xor_r8b)(cpustate); break;\
+ case 0x33: PREFIX86(_xor_r16w)(cpustate); break;\
+ case 0x34: PREFIX86(_xor_ald8)(cpustate); break;\
+ case 0x35: PREFIX86(_xor_axd16)(cpustate); break;\
+ case 0x36: PREFIXV30(_ss)(cpustate); break;\
+ case 0x37: PREFIX86(_aaa)(cpustate); break;\
+ case 0x38: PREFIX86(_cmp_br8)(cpustate); break;\
+ case 0x39: PREFIX86(_cmp_wr16)(cpustate); break;\
+ case 0x3a: PREFIX86(_cmp_r8b)(cpustate); break;\
+ case 0x3b: PREFIX86(_cmp_r16w)(cpustate); break;\
+ case 0x3c: PREFIX86(_cmp_ald8)(cpustate); break;\
+ case 0x3d: PREFIX86(_cmp_axd16)(cpustate); break;\
+ case 0x3e: PREFIXV30(_ds)(cpustate); break;\
+ case 0x3f: PREFIX86(_aas)(cpustate); break;\
+ case 0x40: PREFIX86(_inc_ax)(cpustate); break;\
+ case 0x41: PREFIX86(_inc_cx)(cpustate); break;\
+ case 0x42: PREFIX86(_inc_dx)(cpustate); break;\
+ case 0x43: PREFIX86(_inc_bx)(cpustate); break;\
+ case 0x44: PREFIX86(_inc_sp)(cpustate); break;\
+ case 0x45: PREFIX86(_inc_bp)(cpustate); break;\
+ case 0x46: PREFIX86(_inc_si)(cpustate); break;\
+ case 0x47: PREFIX86(_inc_di)(cpustate); break;\
+ case 0x48: PREFIX86(_dec_ax)(cpustate); break;\
+ case 0x49: PREFIX86(_dec_cx)(cpustate); break;\
+ case 0x4a: PREFIX86(_dec_dx)(cpustate); break;\
+ case 0x4b: PREFIX86(_dec_bx)(cpustate); break;\
+ case 0x4c: PREFIX86(_dec_sp)(cpustate); break;\
+ case 0x4d: PREFIX86(_dec_bp)(cpustate); break;\
+ case 0x4e: PREFIX86(_dec_si)(cpustate); break;\
+ case 0x4f: PREFIX86(_dec_di)(cpustate); break;\
+ case 0x50: PREFIX86(_push_ax)(cpustate); break;\
+ case 0x51: PREFIX86(_push_cx)(cpustate); break;\
+ case 0x52: PREFIX86(_push_dx)(cpustate); break;\
+ case 0x53: PREFIX86(_push_bx)(cpustate); break;\
+ case 0x54: PREFIX86(_push_sp)(cpustate); break;\
+ case 0x55: PREFIX86(_push_bp)(cpustate); break;\
+ case 0x56: PREFIX86(_push_si)(cpustate); break;\
+ case 0x57: PREFIX86(_push_di)(cpustate); break;\
+ case 0x58: PREFIX86(_pop_ax)(cpustate); break;\
+ case 0x59: PREFIX86(_pop_cx)(cpustate); break;\
+ case 0x5a: PREFIX86(_pop_dx)(cpustate); break;\
+ case 0x5b: PREFIX86(_pop_bx)(cpustate); break;\
+ case 0x5c: PREFIX86(_pop_sp)(cpustate); break;\
+ case 0x5d: PREFIX86(_pop_bp)(cpustate); break;\
+ case 0x5e: PREFIX86(_pop_si)(cpustate); break;\
+ case 0x5f: PREFIX86(_pop_di)(cpustate); break;\
+ case 0x60: PREFIX186(_pusha)(cpustate); break;\
+ case 0x61: PREFIX186(_popa)(cpustate); break;\
+ case 0x62: PREFIX186(_bound)(cpustate); break;\
+ case 0x63: PREFIX86(_invalid)(cpustate); break;\
+ case 0x64: PREFIXV30(_repnc)(cpustate); break;\
+ case 0x65: PREFIXV30(_repc)(cpustate); break;\
+ case 0x66: PREFIX86(_invalid)(cpustate); break;\
+ case 0x67: PREFIX86(_invalid)(cpustate); break;\
+ case 0x68: PREFIX186(_push_d16)(cpustate); break;\
+ case 0x69: PREFIX186(_imul_d16)(cpustate); break;\
+ case 0x6a: PREFIX186(_push_d8)(cpustate); break;\
+ case 0x6b: PREFIX186(_imul_d8)(cpustate); break;\
+ case 0x6c: PREFIX186(_insb)(cpustate); break;\
+ case 0x6d: PREFIX186(_insw)(cpustate); break;\
+ case 0x6e: PREFIX186(_outsb)(cpustate); break;\
+ case 0x6f: PREFIX186(_outsw)(cpustate); break;\
+ case 0x70: PREFIX86(_jo)(cpustate); break;\
+ case 0x71: PREFIX86(_jno)(cpustate); break;\
+ case 0x72: PREFIX86(_jb)(cpustate); break;\
+ case 0x73: PREFIX86(_jnb)(cpustate); break;\
+ case 0x74: PREFIX86(_jz)(cpustate); break;\
+ case 0x75: PREFIX86(_jnz)(cpustate); break;\
+ case 0x76: PREFIX86(_jbe)(cpustate); break;\
+ case 0x77: PREFIX86(_jnbe)(cpustate); break;\
+ case 0x78: PREFIX86(_js)(cpustate); break;\
+ case 0x79: PREFIX86(_jns)(cpustate); break;\
+ case 0x7a: PREFIX86(_jp)(cpustate); break;\
+ case 0x7b: PREFIX86(_jnp)(cpustate); break;\
+ case 0x7c: PREFIX86(_jl)(cpustate); break;\
+ case 0x7d: PREFIX86(_jnl)(cpustate); break;\
+ case 0x7e: PREFIX86(_jle)(cpustate); break;\
+ case 0x7f: PREFIX86(_jnle)(cpustate); break;\
+ case 0x80: PREFIX86(_80pre)(cpustate); break;\
+ case 0x81: PREFIX86(_81pre)(cpustate); break;\
+ case 0x82: PREFIX86(_82pre)(cpustate); break;\
+ case 0x83: PREFIX86(_83pre)(cpustate); break;\
+ case 0x84: PREFIX86(_test_br8)(cpustate); break;\
+ case 0x85: PREFIX86(_test_wr16)(cpustate); break;\
+ case 0x86: PREFIX86(_xchg_br8)(cpustate); break;\
+ case 0x87: PREFIX86(_xchg_wr16)(cpustate); break;\
+ case 0x88: PREFIX86(_mov_br8)(cpustate); break;\
+ case 0x89: PREFIX86(_mov_wr16)(cpustate); break;\
+ case 0x8a: PREFIX86(_mov_r8b)(cpustate); break;\
+ case 0x8b: PREFIX86(_mov_r16w)(cpustate); break;\
+ case 0x8c: PREFIX86(_mov_wsreg)(cpustate); break;\
+ case 0x8d: PREFIX86(_lea)(cpustate); break;\
+ case 0x8e: PREFIXV30(_mov_sregw)(cpustate); break;\
+ case 0x8f: PREFIX86(_popw)(cpustate); break;\
+ case 0x90: PREFIX86(_nop)(cpustate); break;\
+ case 0x91: PREFIX86(_xchg_axcx)(cpustate); break;\
+ case 0x92: PREFIX86(_xchg_axdx)(cpustate); break;\
+ case 0x93: PREFIX86(_xchg_axbx)(cpustate); break;\
+ case 0x94: PREFIX86(_xchg_axsp)(cpustate); break;\
+ case 0x95: PREFIX86(_xchg_axbp)(cpustate); break;\
+ case 0x96: PREFIX86(_xchg_axsi)(cpustate); break;\
+ case 0x97: PREFIX86(_xchg_axdi)(cpustate); break;\
+ case 0x98: PREFIX86(_cbw)(cpustate); break;\
+ case 0x99: PREFIX86(_cwd)(cpustate); break;\
+ case 0x9a: PREFIX86(_call_far)(cpustate); break;\
+ case 0x9b: PREFIX86(_wait)(cpustate); break;\
+ case 0x9c: PREFIX86(_pushf)(cpustate); break;\
+ case 0x9d: PREFIX86(_popf)(cpustate); break;\
+ case 0x9e: PREFIX86(_sahf)(cpustate); break;\
+ case 0x9f: PREFIX86(_lahf)(cpustate); break;\
+ case 0xa0: PREFIX86(_mov_aldisp)(cpustate); break;\
+ case 0xa1: PREFIX86(_mov_axdisp)(cpustate); break;\
+ case 0xa2: PREFIX86(_mov_dispal)(cpustate); break;\
+ case 0xa3: PREFIX86(_mov_dispax)(cpustate); break;\
+ case 0xa4: PREFIX86(_movsb)(cpustate); break;\
+ case 0xa5: PREFIX86(_movsw)(cpustate); break;\
+ case 0xa6: PREFIX86(_cmpsb)(cpustate); break;\
+ case 0xa7: PREFIX86(_cmpsw)(cpustate); break;\
+ case 0xa8: PREFIX86(_test_ald8)(cpustate); break;\
+ case 0xa9: PREFIX86(_test_axd16)(cpustate); break;\
+ case 0xaa: PREFIX86(_stosb)(cpustate); break;\
+ case 0xab: PREFIX86(_stosw)(cpustate); break;\
+ case 0xac: PREFIX86(_lodsb)(cpustate); break;\
+ case 0xad: PREFIX86(_lodsw)(cpustate); break;\
+ case 0xae: PREFIX86(_scasb)(cpustate); break;\
+ case 0xaf: PREFIX86(_scasw)(cpustate); break;\
+ case 0xb0: PREFIX86(_mov_ald8)(cpustate); break;\
+ case 0xb1: PREFIX86(_mov_cld8)(cpustate); break;\
+ case 0xb2: PREFIX86(_mov_dld8)(cpustate); break;\
+ case 0xb3: PREFIX86(_mov_bld8)(cpustate); break;\
+ case 0xb4: PREFIX86(_mov_ahd8)(cpustate); break;\
+ case 0xb5: PREFIX86(_mov_chd8)(cpustate); break;\
+ case 0xb6: PREFIX86(_mov_dhd8)(cpustate); break;\
+ case 0xb7: PREFIX86(_mov_bhd8)(cpustate); break;\
+ case 0xb8: PREFIX86(_mov_axd16)(cpustate); break;\
+ case 0xb9: PREFIX86(_mov_cxd16)(cpustate); break;\
+ case 0xba: PREFIX86(_mov_dxd16)(cpustate); break;\
+ case 0xbb: PREFIX86(_mov_bxd16)(cpustate); break;\
+ case 0xbc: PREFIX86(_mov_spd16)(cpustate); break;\
+ case 0xbd: PREFIX86(_mov_bpd16)(cpustate); break;\
+ case 0xbe: PREFIX86(_mov_sid16)(cpustate); break;\
+ case 0xbf: PREFIX86(_mov_did16)(cpustate); break;\
+ case 0xc0: PREFIX186(_rotshft_bd8)(cpustate); break;\
+ case 0xc1: PREFIX186(_rotshft_wd8)(cpustate); break;\
+ case 0xc2: PREFIX86(_ret_d16)(cpustate); break;\
+ case 0xc3: PREFIX86(_ret)(cpustate); break;\
+ case 0xc4: PREFIX86(_les_dw)(cpustate); break;\
+ case 0xc5: PREFIX86(_lds_dw)(cpustate); break;\
+ case 0xc6: PREFIX86(_mov_bd8)(cpustate); break;\
+ case 0xc7: PREFIX86(_mov_wd16)(cpustate); break;\
+ case 0xc8: PREFIX186(_enter)(cpustate); break;\
+ case 0xc9: PREFIX186(_leave)(cpustate); break;\
+ case 0xca: PREFIX86(_retf_d16)(cpustate); break;\
+ case 0xcb: PREFIX86(_retf)(cpustate); break;\
+ case 0xcc: PREFIX86(_int3)(cpustate); break;\
+ case 0xcd: PREFIX86(_int)(cpustate); break;\
+ case 0xce: PREFIX86(_into)(cpustate); break;\
+ case 0xcf: PREFIX86(_iret)(cpustate); break;\
+ case 0xd0: PREFIX86(_rotshft_b)(cpustate); break;\
+ case 0xd1: PREFIX86(_rotshft_w)(cpustate); break;\
+ case 0xd2: PREFIX86(_rotshft_bcl)(cpustate); break;\
+ case 0xd3: PREFIX86(_rotshft_wcl)(cpustate); break;\
+ case 0xd4: PREFIX86(_aam)(cpustate); break;\
+ case 0xd5: PREFIXV30(_aad)(cpustate); break;\
+ case 0xd6: PREFIXV30(_setalc)(cpustate); break;\
+ case 0xd7: PREFIX86(_xlat)(cpustate); break;\
+ case 0xd8: PREFIX86(_escape)(cpustate); break;\
+ case 0xd9: PREFIX86(_escape)(cpustate); break;\
+ case 0xda: PREFIX86(_escape)(cpustate); break;\
+ case 0xdb: PREFIX86(_escape)(cpustate); break;\
+ case 0xdc: PREFIX86(_escape)(cpustate); break;\
+ case 0xdd: PREFIX86(_escape)(cpustate); break;\
+ case 0xde: PREFIX86(_escape)(cpustate); break;\
+ case 0xdf: PREFIX86(_escape)(cpustate); break;\
+ case 0xe0: PREFIX86(_loopne)(cpustate); break;\
+ case 0xe1: PREFIX86(_loope)(cpustate); break;\
+ case 0xe2: PREFIX86(_loop)(cpustate); break;\
+ case 0xe3: PREFIX86(_jcxz)(cpustate); break;\
+ case 0xe4: PREFIX86(_inal)(cpustate); break;\
+ case 0xe5: PREFIX86(_inax)(cpustate); break;\
+ case 0xe6: PREFIX86(_outal)(cpustate); break;\
+ case 0xe7: PREFIX86(_outax)(cpustate); break;\
+ case 0xe8: PREFIX86(_call_d16)(cpustate); break;\
+ case 0xe9: PREFIX86(_jmp_d16)(cpustate); break;\
+ case 0xea: PREFIX86(_jmp_far)(cpustate); break;\
+ case 0xeb: PREFIX86(_jmp_d8)(cpustate); break;\
+ case 0xec: PREFIX86(_inaldx)(cpustate); break;\
+ case 0xed: PREFIX86(_inaxdx)(cpustate); break;\
+ case 0xee: PREFIX86(_outdxal)(cpustate); break;\
+ case 0xef: PREFIX86(_outdxax)(cpustate); break;\
+ case 0xf0: PREFIX86(_lock)(cpustate); break;\
+ case 0xf1: PREFIX86(_invalid)(cpustate); break;\
+ case 0xf2: PREFIXV30(_repne)(cpustate); break;\
+ case 0xf3: PREFIXV30(_repe)(cpustate); break;\
+ case 0xf4: PREFIX86(_hlt)(cpustate); break;\
+ case 0xf5: PREFIX86(_cmc)(cpustate); break;\
+ case 0xf6: PREFIX86(_f6pre)(cpustate); break;\
+ case 0xf7: PREFIX86(_f7pre)(cpustate); break;\
+ case 0xf8: PREFIX86(_clc)(cpustate); break;\
+ case 0xf9: PREFIX86(_stc)(cpustate); break;\
+ case 0xfa: PREFIX86(_cli)(cpustate); break;\
+ case 0xfb: PREFIXV30(_sti)(cpustate); break;\
+ case 0xfc: PREFIX86(_cld)(cpustate); break;\
+ case 0xfd: PREFIX86(_std)(cpustate); break;\
+ case 0xfe: PREFIX86(_fepre)(cpustate); break;\
+ case 0xff: PREFIX86(_ffpre)(cpustate); break;\
+ };
+#else
+#define TABLEV30 PREFIXV30(_instruction)[FETCHOP]();
+#endif