Previous 199869 Revisions Next

r24043 Tuesday 2nd July, 2013 at 13:25:53 UTC by Carl
i86: modernize 80[1]86 [Carl, Wilbert Pol]
--
80286 is a WIP
[src/emu/cpu/i86]i86.c i86.h
[src/mame/includes]gottlieb.h
[src/mess/machine]pc.c

trunk/src/emu/cpu/i86/i86.c
r24042r24043
11/****************************************************************************
2*             real mode i286 emulator v1.4 by Fabrice Frances               *
3*               (initial work based on David Hedley's pcemu)                *
2
3    NEC V20/V30/V33 emulator modified back to a 8086/80186 emulator
4
5    (Re)Written June-September 2000 by Bryan McPhail (mish@tendril.co.uk) based
6    on code by Oliver Bergmann (Raul_Bloodworth@hotmail.com) who based code
7    on the i286 emulator by Fabrice Frances which had initial work based on
8    David Hedley's pcemu(!).
9
410****************************************************************************/
5/* 26.March 2000 PeT changed set_irq_line */
611
712#include "emu.h"
813#include "debugger.h"
9
10#include "host.h"
11#include "i86priv.h"
1214#include "i86.h"
1315
14extern int i386_dasm_one(char *buffer, UINT32 eip, const UINT8 *oprom, int mode);
16enum SREGS { ES=0, CS, SS, DS };
17enum WREGS { AX=0, CX, DX, BX, SP, BP, SI, DI };
1518
16#define VERBOSE 0
17#define LOG(x) do { if (VERBOSE) mame_printf_debug x; } while (0)
19#define I8086_NMI_INT_VECTOR 2
1820
21enum BREGS {
22   AL = NATIVE_ENDIAN_VALUE_LE_BE(0x0, 0x1),
23   AH = NATIVE_ENDIAN_VALUE_LE_BE(0x1, 0x0),
24   CL = NATIVE_ENDIAN_VALUE_LE_BE(0x2, 0x3),
25   CH = NATIVE_ENDIAN_VALUE_LE_BE(0x3, 0x2),
26   DL = NATIVE_ENDIAN_VALUE_LE_BE(0x4, 0x5),
27   DH = NATIVE_ENDIAN_VALUE_LE_BE(0x5, 0x4),
28   BL = NATIVE_ENDIAN_VALUE_LE_BE(0x6, 0x7),
29   BH = NATIVE_ENDIAN_VALUE_LE_BE(0x7, 0x6),
30   SPL = NATIVE_ENDIAN_VALUE_LE_BE(0x8, 0x9),
31   SPH = NATIVE_ENDIAN_VALUE_LE_BE(0x9, 0x8),
32   BPL = NATIVE_ENDIAN_VALUE_LE_BE(0xa, 0xb),
33   BPH = NATIVE_ENDIAN_VALUE_LE_BE(0xb, 0xa),
34   SIL = NATIVE_ENDIAN_VALUE_LE_BE(0xc, 0xd),
35   SIH = NATIVE_ENDIAN_VALUE_LE_BE(0xd, 0xc),
36   DIL = NATIVE_ENDIAN_VALUE_LE_BE(0xe, 0xf),
37   DIH = NATIVE_ENDIAN_VALUE_LE_BE(0xf, 0xe)
38};
1939
20/* All pre-i286 CPUs have a 1MB address space */
21#define AMASK   0xfffff
40enum
41{
42   EXCEPTION, IRET,                                /* EXCEPTION, iret */
43   INT3, INT_IMM, INTO_NT, INTO_T,                 /* intS */
44   OVERRIDE,                                       /* SEGMENT OVERRIDES */
45   FLAG_OPS, LAHF, SAHF,                           /* FLAG OPERATIONS */
46   AAA, AAS, AAM, AAD,                             /* ARITHMETIC ADJUSTS */
47   DAA, DAS,                                       /* DECIMAL ADJUSTS */
48   CBW, CWD,                                       /* SIGN EXTENSION */
49   HLT, LOAD_PTR, LEA, NOP, WAIT, XLAT,            /* MISC */
2250
51   JMP_SHORT, JMP_NEAR, JMP_FAR,                   /* DIRECT jmpS */
52   JMP_R16, JMP_M16, JMP_M32,                      /* INDIRECT jmpS */
53   CALL_NEAR, CALL_FAR,                            /* DIRECT callS */
54   CALL_R16, CALL_M16, CALL_M32,                   /* INDIRECT callS */
55   RET_NEAR, RET_FAR, RET_NEAR_IMM, RET_FAR_IMM,   /* RETURNS */
56   JCC_NT, JCC_T, JCXZ_NT, JCXZ_T,                 /* CONDITIONAL jmpS */
57   LOOP_NT, LOOP_T, LOOPE_NT, LOOPE_T,             /* LOOPS */
2358
24/* I86 registers */
25union i8086basicregs
26{                                      /* eight general registers */
27   UINT16 w[8];                       /* viewed as 16 bits registers */
28   UINT8 b[16];                       /* or as 8 bit registers */
59   IN_IMM8, IN_IMM16, IN_DX8, IN_DX16,             /* PORT READS */
60   OUT_IMM8, OUT_IMM16, OUT_DX8, OUT_DX16,         /* PORT WRITES */
61
62   MOV_RR8, MOV_RM8, MOV_MR8,                      /* MOVE, 8-BIT */
63   MOV_RI8, MOV_MI8,                               /* MOVE, 8-BIT IMMEDIATE */
64   MOV_RR16, MOV_RM16, MOV_MR16,                   /* MOVE, 16-BIT */
65   MOV_RI16, MOV_MI16,                             /* MOVE, 16-BIT IMMEDIATE */
66   MOV_AM8, MOV_AM16, MOV_MA8, MOV_MA16,           /* MOVE, al/ax MEMORY */
67   MOV_SR, MOV_SM, MOV_RS, MOV_MS,                 /* MOVE, SEGMENT REGISTERS */
68   XCHG_RR8, XCHG_RM8,                             /* EXCHANGE, 8-BIT */
69   XCHG_RR16, XCHG_RM16, XCHG_AR16,                /* EXCHANGE, 16-BIT */
70
71   PUSH_R16, PUSH_M16, PUSH_SEG, PUSHF,            /* PUSHES */
72   POP_R16, POP_M16, POP_SEG, POPF,                /* POPS */
73
74   ALU_RR8, ALU_RM8, ALU_MR8,                      /* alu OPS, 8-BIT */
75   ALU_RI8, ALU_MI8, ALU_MI8_RO,                   /* alu OPS, 8-BIT IMMEDIATE */
76   ALU_RR16, ALU_RM16, ALU_MR16,                   /* alu OPS, 16-BIT */
77   ALU_RI16, ALU_MI16, ALU_MI16_RO,                /* alu OPS, 16-BIT IMMEDIATE */
78   ALU_R16I8, ALU_M16I8, ALU_M16I8_RO,             /* alu OPS, 16-BIT W/8-BIT IMMEDIATE */
79   MUL_R8, MUL_R16, MUL_M8, MUL_M16,               /* mul */
80   IMUL_R8, IMUL_R16, IMUL_M8, IMUL_M16,           /* imul */
81   DIV_R8, DIV_R16, DIV_M8, DIV_M16,               /* div */
82   IDIV_R8, IDIV_R16, IDIV_M8, IDIV_M16,           /* idiv */
83   INCDEC_R8, INCDEC_R16, INCDEC_M8, INCDEC_M16,   /* inc/dec */
84   NEGNOT_R8, NEGNOT_R16, NEGNOT_M8, NEGNOT_M16,   /* neg/not */
85
86   ROT_REG_1, ROT_REG_BASE, ROT_REG_BIT,           /* REG SHIFT/ROTATE */
87   ROT_M8_1, ROT_M8_BASE, ROT_M8_BIT,              /* M8 SHIFT/ROTATE */
88   ROT_M16_1, ROT_M16_BASE, ROT_M16_BIT,           /* M16 SHIFT/ROTATE */
89
90   CMPS8, REP_CMPS8_BASE, REP_CMPS8_COUNT,         /* cmps 8-BIT */
91   CMPS16, REP_CMPS16_BASE, REP_CMPS16_COUNT,      /* cmps 16-BIT */
92   SCAS8, REP_SCAS8_BASE, REP_SCAS8_COUNT,         /* scas 8-BIT */
93   SCAS16, REP_SCAS16_BASE, REP_SCAS16_COUNT,      /* scas 16-BIT */
94   LODS8, REP_LODS8_BASE, REP_LODS8_COUNT,         /* lods 8-BIT */
95   LODS16, REP_LODS16_BASE, REP_LODS16_COUNT,      /* lods 16-BIT */
96   STOS8, REP_STOS8_BASE, REP_STOS8_COUNT,         /* stos 8-BIT */
97   STOS16, REP_STOS16_BASE, REP_STOS16_COUNT,      /* stos 16-BIT */
98   MOVS8, REP_MOVS8_BASE, REP_MOVS8_COUNT,         /* movs 8-BIT */
99   MOVS16, REP_MOVS16_BASE, REP_MOVS16_COUNT,      /* movs 16-BIT */
100
101   INS8, REP_INS8_BASE, REP_INS8_COUNT,            /* (80186) ins 8-BIT */
102   INS16, REP_INS16_BASE, REP_INS16_COUNT,         /* (80186) ins 16-BIT */
103   OUTS8, REP_OUTS8_BASE, REP_OUTS8_COUNT,         /* (80186) outs 8-BIT */
104   OUTS16, REP_OUTS16_BASE, REP_OUTS16_COUNT,      /* (80186) outs 16-BIT */
105   PUSH_IMM, PUSHA, POPA,                          /* (80186) push IMMEDIATE, pusha/popa */
106   IMUL_RRI8, IMUL_RMI8,                           /* (80186) imul IMMEDIATE 8-BIT */
107   IMUL_RRI16, IMUL_RMI16,                         /* (80186) imul IMMEDIATE 16-BIT */
108   ENTER0, ENTER1, ENTER_BASE, ENTER_COUNT, LEAVE, /* (80186) enter/leave */
109   BOUND                                           /* (80186) bound */
29110};
30111
31struct i8086_state
112const UINT8 i8086_cpu_device::m_i8086_timing[] =
32113{
33   i8086basicregs regs;
34   offs_t fetch_xor;
35   UINT32 pc;
36   UINT32 prevpc;
37   UINT32 base[4];
38   UINT16 sregs[4];
39   UINT16 flags;
40   device_irq_acknowledge_callback irq_callback;
41   INT32 AuxVal, OverVal, SignVal, ZeroVal, CarryVal, DirVal;      /* 0 or non-0 valued flags */
42   UINT8 ParityVal;
43   UINT8 TF, IF;                  /* 0 or 1 valued flags */
44   UINT8 MF;                          /* V30 mode flag */
45   UINT8 int_vector;
46   INT8 nmi_state;
47   INT8 irq_state;
48   INT8 test_state;
49   UINT8 rep_in_progress;
50   INT32 extra_cycles;       /* extra cycles for interrupts */
114   51,32,          /* exception, IRET */
115      2, 0, 4, 2, /* INTs */
116      2,              /* segment overrides */
117      2, 4, 4,        /* flag operations */
118      4, 4,83,60, /* arithmetic adjusts */
119      4, 4,           /* decimal adjusts */
120      2, 5,           /* sign extension */
121      2,24, 2, 2, 3,11,   /* misc */
51122
52   int halted;         /* Is the CPU halted ? */
123   15,15,15,       /* direct JMPs */
124   11,18,24,       /* indirect JMPs */
125   19,28,          /* direct CALLs */
126   16,21,37,       /* indirect CALLs */
127   20,32,24,31,    /* returns */
128      4,16, 6,18, /* conditional JMPs */
129      5,17, 6,18, /* loops */
53130
54   UINT16 ip;
55   UINT32 sp;
131   10,14, 8,12,    /* port reads */
132   10,14, 8,12,    /* port writes */
56133
57   legacy_cpu_device *device;
58   address_space *program;
59   direct_read_data *direct;
60   address_space *io;
61   int icount;
134      2, 8, 9,        /* move, 8-bit */
135      4,10,           /* move, 8-bit immediate */
136      2, 8, 9,        /* move, 16-bit */
137      4,10,           /* move, 16-bit immediate */
138   10,10,10,10,    /* move, AL/AX memory */
139      2, 8, 2, 9, /* move, segment registers */
140      4,17,           /* exchange, 8-bit */
141      4,17, 3,        /* exchange, 16-bit */
62142
63   char seg_prefix;                   /* prefix segment indicator */
64   UINT8   prefix_seg;                 /* The prefixed segment */
65   unsigned ea;
66   UINT16 eo; /* HJB 12/13/98 effective offset of the address (before segment is added) */
67   UINT8 ea_seg;   /* effective segment of the address */
143   15,24,14,14,    /* pushes */
144   12,25,12,12,    /* pops */
68145
69   devcb_resolved_write_line   out_tmrout0_func;
70   devcb_resolved_write_line   out_tmrout1_func;
146      3, 9,16,        /* ALU ops, 8-bit */
147      4,17,10,        /* ALU ops, 8-bit immediate */
148      3, 9,16,        /* ALU ops, 16-bit */
149      4,17,10,        /* ALU ops, 16-bit immediate */
150      4,17,10,        /* ALU ops, 16-bit w/8-bit immediate */
151   70,118,76,128,  /* MUL */
152   80,128,86,138,  /* IMUL */
153   80,144,86,154,  /* DIV */
154   101,165,107,175,/* IDIV */
155      3, 2,15,15, /* INC/DEC */
156      3, 3,16,16, /* NEG/NOT */
157
158      2, 8, 4,        /* reg shift/rotate */
159   15,20, 4,       /* m8 shift/rotate */
160   15,20, 4,       /* m16 shift/rotate */
161
162   22, 9,21,       /* CMPS 8-bit */
163   22, 9,21,       /* CMPS 16-bit */
164   15, 9,14,       /* SCAS 8-bit */
165   15, 9,14,       /* SCAS 16-bit */
166   12, 9,11,       /* LODS 8-bit */
167   12, 9,11,       /* LODS 16-bit */
168   11, 9,10,       /* STOS 8-bit */
169   11, 9,10,       /* STOS 16-bit */
170   18, 9,17,       /* MOVS 8-bit */
171   18, 9,17,       /* MOVS 16-bit */
71172};
72
73INLINE i8086_state *get_safe_token(device_t *device)
173/* these come from the Intel 80186 datasheet */
174const UINT8 i80186_cpu_device::m_i80186_timing[] =
74175{
75   assert(device != NULL);
76   assert(device->type() == I8086 ||
77         device->type() == I8088 ||
78         device->type() == I80186 ||
79         device->type() == I80188);
80   return (i8086_state *)downcast<legacy_cpu_device *>(device)->token();
81}
176   45,28,          /* exception, IRET */
177      0, 2, 4, 3, /* INTs */
178      2,              /* segment overrides */
179      2, 2, 3,        /* flag operations */
180      8, 7,19,15, /* arithmetic adjusts */
181      4, 4,           /* decimal adjusts */
182      2, 4,           /* sign extension */
183      2,18, 6, 2, 6,11,   /* misc */
82184
185   14,14,14,       /* direct JMPs */
186   11,17,26,       /* indirect JMPs */
187   15,23,          /* direct CALLs */
188   13,19,38,       /* indirect CALLs */
189   16,22,18,25,    /* returns */
190      4,13, 5,15, /* conditional JMPs */
191      6,16, 6,16, /* loops */
83192
84#include "i86time.c"
193   10,10, 8, 8,    /* port reads */
194      9, 9, 7, 7, /* port writes */
85195
196      2, 9,12,        /* move, 8-bit */
197      3,12,           /* move, 8-bit immediate */
198      2, 9,12,        /* move, 16-bit */
199      4,13,           /* move, 16-bit immediate */
200      8, 8, 9, 9, /* move, AL/AX memory */
201      2,11, 2,11, /* move, segment registers */
202      4,17,           /* exchange, 8-bit */
203      4,17, 3,        /* exchange, 16-bit */
204
205   10,16, 9, 9,    /* pushes */
206   10,20, 8, 8,    /* pops */
207
208      3,10,10,        /* ALU ops, 8-bit */
209      4,16,10,        /* ALU ops, 8-bit immediate */
210      3,10,10,        /* ALU ops, 16-bit */
211      4,16,10,        /* ALU ops, 16-bit immediate */
212      4,16,10,        /* ALU ops, 16-bit w/8-bit immediate */
213   26,35,32,41,    /* MUL */
214   25,34,31,40,    /* IMUL */
215   29,38,35,44,    /* DIV */
216   44,53,50,59,    /* IDIV */
217      3, 3,15,15, /* INC/DEC */
218      3, 3,10,10, /* NEG/NOT */
219
220      2, 5, 1,        /* reg shift/rotate */
221   15,17, 1,       /* m8 shift/rotate */
222   15,17, 1,       /* m16 shift/rotate */
223
224   22, 5,22,       /* CMPS 8-bit */
225   22, 5,22,       /* CMPS 16-bit */
226   15, 5,15,       /* SCAS 8-bit */
227   15, 5,15,       /* SCAS 16-bit */
228   12, 6,11,       /* LODS 8-bit */
229   12, 6,11,       /* LODS 16-bit */
230   10, 6, 9,       /* STOS 8-bit */
231   10, 6, 9,       /* STOS 16-bit */
232   14, 8, 8,       /* MOVS 8-bit */
233   14, 8, 8,       /* MOVS 16-bit */
234
235   14, 8, 8,       /* (80186) INS 8-bit */
236   14, 8, 8,       /* (80186) INS 16-bit */
237   14, 8, 8,       /* (80186) OUTS 8-bit */
238   14, 8, 8,       /* (80186) OUTS 16-bit */
239   14,68,83,       /* (80186) PUSH immediate, PUSHA/POPA */
240   22,29,          /* (80186) IMUL immediate 8-bit */
241   25,32,          /* (80186) IMUL immediate 16-bit */
242   15,25,4,16, 8,  /* (80186) ENTER/LEAVE */
243   33,             /* (80186) BOUND */
244};
245
246#define CF      (m_CarryVal!=0)
247#define SF      (m_SignVal<0)
248#define ZF      (m_ZeroVal==0)
249#define PF      m_parity_table[(UINT8)m_ParityVal]
250#define AF      (m_AuxVal!=0)
251#define OF      (m_OverVal!=0)
252
253
86254/***************************************************************************/
87255/* cpu state                                                               */
88256/***************************************************************************/
89257
90258
91static struct i80x86_timing timing;
92
93static UINT8 parity_table[256];
94
95259/* The interrupt number of a pending external interrupt pending NMI is 2.   */
96260/* For INTR interrupts, the level is caught on the bus during an INTA cycle */
97261
98#define PREFIX(name) i8086##name
99#define PREFIX86(name) i8086##name
262#define INT_IRQ 0x01
263#define NMI_IRQ 0x02
100264
101#define I8086
102#include "instr86.h"
103#include "ea.h"
104#include "modrm.h"
105#include "table86.h"
265/***************************************************************************/
106266
107#include "instr86.c"
108#undef I8086
267const device_type I8086 = &device_creator<i8086_cpu_device>;
268const device_type I8088 = &device_creator<i8088_cpu_device>;
269const device_type I80186 = &device_creator<i80186_cpu_device>;
270const device_type I80188 = &device_creator<i80188_cpu_device>;
109271
272i80188_cpu_device::i80188_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
273   : i80186_cpu_device(mconfig, I80188, "I80188", tag, owner, clock, "i80188", __FILE__, 8)
274{
275   memcpy(m_timing, m_i80186_timing, sizeof(m_i80186_timing));
276}
110277
111/***************************************************************************/
112static void i8086_state_register(device_t *device)
278i80186_cpu_device::i80186_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
279   : i8086_common_cpu_device(mconfig, I80186, "I80186", tag, owner, clock, "i80186", __FILE__)
280   , m_program_config("program", ENDIANNESS_LITTLE, 16, 20, 0)
281   , m_io_config("io", ENDIANNESS_LITTLE, 16, 16, 0)
113282{
114   i8086_state *cpustate = get_safe_token(device);
115   device->save_item(NAME(cpustate->regs.w));
116   device->save_item(NAME(cpustate->pc));
117   device->save_item(NAME(cpustate->prevpc));
118   device->save_item(NAME(cpustate->base));
119   device->save_item(NAME(cpustate->sregs));
120   device->save_item(NAME(cpustate->flags));
121   device->save_item(NAME(cpustate->AuxVal));
122   device->save_item(NAME(cpustate->OverVal));
123   device->save_item(NAME(cpustate->SignVal));
124   device->save_item(NAME(cpustate->ZeroVal));
125   device->save_item(NAME(cpustate->CarryVal));
126   device->save_item(NAME(cpustate->DirVal));
127   device->save_item(NAME(cpustate->ParityVal));
128   device->save_item(NAME(cpustate->TF));
129   device->save_item(NAME(cpustate->IF));
130   device->save_item(NAME(cpustate->MF));
131   device->save_item(NAME(cpustate->int_vector));
132   device->save_item(NAME(cpustate->nmi_state));
133   device->save_item(NAME(cpustate->irq_state));
134   device->save_item(NAME(cpustate->extra_cycles));
135   device->save_item(NAME(cpustate->halted));
136   device->save_item(NAME(cpustate->test_state));  /* PJB 03/05 */
137   device->save_item(NAME(cpustate->rep_in_progress)); /* PJB 03/05 */
283   memcpy(m_timing, m_i80186_timing, sizeof(m_i80186_timing));
138284}
139285
140static CPU_INIT( i8086 )
286i80186_cpu_device::i80186_cpu_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock, const char *shortname, const char *source, int data_bus_size)
287   : i8086_common_cpu_device(mconfig, type, name, tag, owner, clock, shortname, source)
288   , m_program_config("program", ENDIANNESS_LITTLE, data_bus_size, 20, 0)
289   , m_io_config("io", ENDIANNESS_LITTLE, data_bus_size, 16, 0)
141290{
142   i8086_state *cpustate = get_safe_token(device);
143   unsigned int i, j, c;
144   static const BREGS reg_name[8] = {AL, CL, DL, BL, AH, CH, DH, BH};
145   for (i = 0; i < 256; i++)
291}
292
293void i80186_cpu_device::execute_run()
294{
295   while(m_icount > 0 )
146296   {
147      for (j = i, c = 0; j > 0; j >>= 1)
148         if (j & 1)
149            c++;
297      if ( m_seg_prefix_next )
298      {
299         m_seg_prefix = true;
300         m_seg_prefix_next = false;
301      }
302      else
303      {
304         m_prev_ip = m_ip;
305         m_seg_prefix = false;
150306
151      parity_table[i] = !(c & 1);
307            /* Dispatch IRQ */
308         if ( m_pending_irq && m_no_interrupt == 0 )
309         {
310            if ( m_pending_irq & NMI_IRQ )
311            {
312               interrupt(I8086_NMI_INT_VECTOR);
313               m_pending_irq &= ~NMI_IRQ;
314            }
315            else if ( m_IF )
316            {
317               /* the actual vector is retrieved after pushing flags */
318               /* and clearing the IF */
319               interrupt(-1);
320            }
321         }
322
323         /* No interrupt allowed between last instruction and this one */
324         if ( m_no_interrupt )
325         {
326            m_no_interrupt--;
327         }
328
329         /* trap should allow one instruction to be executed */
330         if ( m_fire_trap )
331         {
332            if ( m_fire_trap >= 2 )
333            {
334               interrupt(1);
335               m_fire_trap = 0;
336            }
337            else
338            {
339               m_fire_trap++;
340            }
341         }
342      }
343
344      debugger_instruction_hook( this, pc() );
345
346      UINT8 op = fetch_op();
347
348      switch(op)
349      {
350         case 0x60: // i_pusha
351            {
352               UINT32 tmp = m_regs.w[SP];
353
354               PUSH(m_regs.w[AX]);
355               PUSH(m_regs.w[CX]);
356               PUSH(m_regs.w[DX]);
357               PUSH(m_regs.w[BX]);
358               PUSH(tmp);
359               PUSH(m_regs.w[BP]);
360               PUSH(m_regs.w[SI]);
361               PUSH(m_regs.w[DI]);
362               CLK(PUSHA);
363            }
364            break;
365
366         case 0x61: // i_popa
367            m_regs.w[DI] = POP();
368            m_regs.w[SI] = POP();
369            m_regs.w[BP] = POP();
370                        POP();
371            m_regs.w[BX] = POP();
372            m_regs.w[DX] = POP();
373            m_regs.w[CX] = POP();
374            m_regs.w[AX] = POP();
375            CLK(POPA);
376            break;
377
378         case 0x62: // i_bound
379            {
380               UINT32 low,high,tmp;
381               m_modrm = fetch();
382               low = GetRMWord();
383               high = GetnextRMWord();
384               tmp = RegWord();
385               if (tmp<low || tmp>high)
386                  interrupt(5);
387               CLK(BOUND);
388               logerror("%s: %06x: bound %04x high %04x low %04x tmp\n", tag(), pc(), high, low, tmp);
389            }
390            break;
391
392         case 0x68: // i_push_d16
393            PUSH( fetch_word() );
394            CLK(PUSH_IMM);
395            break;
396
397         case 0x69: // i_imul_d16
398            {
399               UINT32 tmp;
400               DEF_r16w();
401               tmp = fetch_word();
402               m_dst = (INT32)((INT16)m_src)*(INT32)((INT16)tmp);
403               m_CarryVal = m_OverVal = (((INT32)m_dst) >> 15 != 0) && (((INT32)m_dst) >> 15 != -1);
404               RegWord(m_dst);
405               CLKM(IMUL_RRI16, IMUL_RMI16);
406            }
407            break;
408
409         case 0x6a: // i_push_d8
410            PUSH( (UINT16)((INT16)((INT8)fetch())) );
411            CLK(PUSH_IMM);
412            break;
413
414         case 0x6b: // i_imul_d8
415            {
416               UINT32 src2;
417               DEF_r16w();
418               src2= (UINT16)((INT16)((INT8)fetch()));
419               m_dst = (INT32)((INT16)m_src)*(INT32)((INT16)src2);
420               m_CarryVal = m_OverVal = (((INT32)m_dst) >> 15 != 0) && (((INT32)m_dst) >> 15 != -1);
421               RegWord(m_dst);
422               CLKM(IMUL_RRI8, IMUL_RMI8);
423            }
424            break;
425
426         case 0x6c: // i_insb
427            i_insb();
428            break;
429
430         case 0x6d: // i_insw
431            i_insw();
432            break;
433
434         case 0x6e: // i_outsb
435            i_outsb();
436            break;
437
438         case 0x6f: // i_outsw
439            i_outsw();
440            break;
441
442         case 0xc0: // i_rotshft_bd8
443            {
444               UINT8 c;
445               m_modrm = fetch();
446               m_src = GetRMByte();
447               m_dst = m_src;
448               c = fetch() & 0x1f;
449               CLKM(ROT_REG_BASE,ROT_M8_BASE);
450               m_icount -= m_timing[ROT_REG_BIT] * c;
451               if (c)
452               {
453                  switch ( m_modrm & 0x38 )
454                  {
455                  case 0x00: do { ROL_BYTE();  c--; } while (c>0); PutbackRMByte(m_dst); break;
456                  case 0x08: do { ROR_BYTE();  c--; } while (c>0); PutbackRMByte(m_dst); break;
457                  case 0x10: do { ROLC_BYTE(); c--; } while (c>0); PutbackRMByte(m_dst); break;
458                  case 0x18: do { RORC_BYTE(); c--; } while (c>0); PutbackRMByte(m_dst); break;
459                  case 0x30:
460                  case 0x20: SHL_BYTE(c); break;
461                  case 0x28: SHR_BYTE(c); break;
462                  case 0x38: SHRA_BYTE(c); break;
463                  }
464               }
465            }
466            break;
467
468         case 0xc1: // i_rotshft_wd8
469            {
470               UINT8 c;
471               m_modrm = fetch();
472               m_src = GetRMWord();
473               m_dst = m_src;
474               c = fetch() & 0x1f;
475               CLKM(ROT_REG_BASE,ROT_M16_BASE);
476               m_icount -= m_timing[ROT_REG_BIT] * c;
477               if (c)
478               {
479                  switch ( m_modrm & 0x38 )
480                  {
481                  case 0x00: do { ROL_WORD();  c--; } while (c>0); PutbackRMWord(m_dst); break;
482                  case 0x08: do { ROR_WORD();  c--; } while (c>0); PutbackRMWord(m_dst); break;
483                  case 0x10: do { ROLC_WORD(); c--; } while (c>0); PutbackRMWord(m_dst); break;
484                  case 0x18: do { RORC_WORD(); c--; } while (c>0); PutbackRMWord(m_dst); break;
485                  case 0x30:
486                  case 0x20: SHL_WORD(c); break;
487                  case 0x28: SHR_WORD(c); break;
488                  case 0x38: SHRA_WORD(c); break;
489                  }
490               }
491            }
492            break;
493
494         case 0xc8: // i_enter
495            {
496               UINT16 nb = fetch();
497               UINT32 level;
498
499               nb |= fetch() << 8;
500               level = fetch();
501               CLK(!level ? ENTER0 : (level == 1) ? ENTER1 : (ENTER_BASE + (level * ENTER_COUNT)));
502               PUSH(m_regs.w[BP]);
503               m_regs.w[BP] = m_regs.w[SP];
504               m_regs.w[SP] -= nb;
505               for (int i=1; i<level; i++)
506               {
507                  PUSH( GetMemW(SS,m_regs.w[BP] - i*2) );
508               }
509               if (level)
510               {
511                  PUSH(m_regs.w[BP]);
512               }
513            }
514            break;
515
516         case 0xc9: // i_leave
517            m_regs.w[SP] = m_regs.w[BP];
518            m_regs.w[BP] = POP();
519            CLK(LEAVE);
520            break;
521
522         case 0xd2: // i_rotshft_bcl
523            {
524               UINT8 c;
525
526               m_modrm = fetch();
527               m_src = GetRMByte();
528               m_dst = m_src;
529               c = m_regs.b[CL] & 0x1f;
530               CLKM(ROT_REG_BASE,ROT_M16_BASE);
531               m_icount -= m_timing[ROT_REG_BIT] * c;
532               if (c)
533               {
534                  switch ( m_modrm & 0x38 )
535                  {
536                  case 0x00: do { ROL_BYTE();  c--; } while (c>0); PutbackRMByte(m_dst); break;
537                  case 0x08: do { ROR_BYTE();  c--; } while (c>0); PutbackRMByte(m_dst); break;
538                  case 0x10: do { ROLC_BYTE(); c--; } while (c>0); PutbackRMByte(m_dst); break;
539                  case 0x18: do { RORC_BYTE(); c--; } while (c>0); PutbackRMByte(m_dst); break;
540                  case 0x30:
541                  case 0x20: SHL_BYTE(c); break;
542                  case 0x28: SHR_BYTE(c); break;
543                  case 0x38: SHRA_BYTE(c); break;
544                  }
545               }
546            }
547            break;
548
549         case 0xd3: // i_rotshft_wcl
550            {
551               UINT8 c;
552
553               m_modrm = fetch();
554               m_src = GetRMWord();
555               m_dst = m_src;
556               c = m_regs.b[CL] & 0x1f;
557               CLKM(ROT_REG_BASE,ROT_M16_BASE);
558               m_icount -= m_timing[ROT_REG_BIT] * c;
559               if (c)
560               {
561                  switch ( m_modrm & 0x38 )
562                  {
563                     case 0x00: do { ROL_WORD();  c--; } while (c>0); PutbackRMWord(m_dst); break;
564                     case 0x08: do { ROR_WORD();  c--; } while (c>0); PutbackRMWord(m_dst); break;
565                     case 0x10: do { ROLC_WORD(); c--; } while (c>0); PutbackRMWord(m_dst); break;
566                     case 0x18: do { RORC_WORD(); c--; } while (c>0); PutbackRMWord(m_dst); break;
567                     case 0x30:
568                     case 0x20: SHL_WORD(c); break;
569                     case 0x28: SHR_WORD(c); break;
570                     case 0x38: SHRA_WORD(c); break;
571                  }
572               }
573            }
574            break;
575
576         case 0xf2: // i_repne
577         case 0xf3:
578            {
579               bool pass = false;
580               UINT8 next = repx_op();
581               UINT16 c = m_regs.w[CX];
582
583               switch (next)
584               {
585               case 0x6c:  CLK(OVERRIDE); if (c) do { i_insb();  c--; } while (c>0 && m_icount>0);          m_regs.w[CX]=c; m_seg_prefix = false; m_seg_prefix_next = false; break;
586               case 0x6d:  CLK(OVERRIDE); if (c) do { i_insw();  c--; } while (c>0 && m_icount>0);          m_regs.w[CX]=c; m_seg_prefix = false; m_seg_prefix_next = false; break;
587               case 0x6e:  CLK(OVERRIDE); if (c) do { i_outsb(); c--; } while (c>0 && m_icount>0);          m_regs.w[CX]=c; m_seg_prefix = false; m_seg_prefix_next = false; break;
588               case 0x6f:  CLK(OVERRIDE); if (c) do { i_outsw(); c--; } while (c>0 && m_icount>0);          m_regs.w[CX]=c; m_seg_prefix = false; m_seg_prefix_next = false; break;
589               default:
590                  // Decrement IP and pass on
591                  m_ip -= 1;
592                  pass = true;
593               }
594               if(!pass)
595               {
596                  if(c)
597                     m_ip = m_prev_ip;
598                  break;
599               }
600            }
601
602         default:
603            if(!common_op(op))
604            {
605               m_icount -= 10; // UD fault timing?
606               logerror("%s: %06x: Invalid Opcode %02x\n", tag(), pc(), op);
607               m_ip = m_prev_ip;
608               interrupt(6); // 80186 has #UD
609               break;
610            }
611      }
152612   }
613}
153614
154   for (i = 0; i < 256; i++)
615i8088_cpu_device::i8088_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
616   : i8086_cpu_device(mconfig, I8088, "I8088", tag, owner, clock, "i8088", __FILE__, 8)
617{
618   memcpy(m_timing, m_i8086_timing, sizeof(m_i8086_timing));
619}
620
621i8086_cpu_device::i8086_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
622   : i8086_common_cpu_device(mconfig, I8086, "I8086", tag, owner, clock, "i8086", __FILE__)
623   , m_program_config("program", ENDIANNESS_LITTLE, 16, 20, 0)
624   , m_io_config("io", ENDIANNESS_LITTLE, 16, 16, 0)
625{
626   memcpy(m_timing, m_i8086_timing, sizeof(m_i8086_timing));
627}
628
629i8086_cpu_device::i8086_cpu_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock, const char *shortname, const char *source, int data_bus_size)
630   : i8086_common_cpu_device(mconfig, type, name, tag, owner, clock, shortname, source)
631   , m_program_config("program", ENDIANNESS_LITTLE, data_bus_size, 20, 0)
632   , m_io_config("io", ENDIANNESS_LITTLE, data_bus_size, 16, 0)
633{
634}
635
636void i8086_cpu_device::execute_run()
637{
638   while(m_icount > 0 )
155639   {
156      Mod_RM.reg.b[i] = reg_name[(i & 0x38) >> 3];
157      Mod_RM.reg.w[i] = (WREGS) ((i & 0x38) >> 3);
640      if ( m_seg_prefix_next )
641      {
642         m_seg_prefix = true;
643         m_seg_prefix_next = false;
644      }
645      else
646      {
647         m_prev_ip = m_ip;
648         m_seg_prefix = false;
649
650            /* Dispatch IRQ */
651         if ( m_pending_irq && m_no_interrupt == 0 )
652         {
653            if ( m_pending_irq & NMI_IRQ )
654            {
655               interrupt(I8086_NMI_INT_VECTOR);
656               m_pending_irq &= ~NMI_IRQ;
657            }
658            else if ( m_IF )
659            {
660               /* the actual vector is retrieved after pushing flags */
661               /* and clearing the IF */
662               interrupt(-1);
663            }
664         }
665
666         /* No interrupt allowed between last instruction and this one */
667         if ( m_no_interrupt )
668         {
669            m_no_interrupt--;
670         }
671
672         /* trap should allow one instruction to be executed */
673         if ( m_fire_trap )
674         {
675            if ( m_fire_trap >= 2 )
676            {
677               interrupt(1);
678               m_fire_trap = 0;
679            }
680            else
681            {
682               m_fire_trap++;
683            }
684         }
685      }
686
687      debugger_instruction_hook( this, pc() );
688
689      UINT8 op = fetch_op();
690
691      switch(op)
692      {
693         case 0x0f:
694            m_sregs[CS] = POP();
695            CLK(POP_SEG);
696            break;
697
698         case 0xd2: // i_rotshft_bcl
699            {
700               UINT8 c;
701
702               m_modrm = fetch();
703               m_src = GetRMByte();
704               m_dst = m_src;
705               c = m_regs.b[CL];
706               CLKM(ROT_REG_BASE,ROT_M8_BASE);
707               m_icount -= m_timing[ROT_REG_BIT] * c;
708               if (c)
709               {
710                  switch ( m_modrm & 0x38 )
711                  {
712                  case 0x00: do { ROL_BYTE();  c--; } while (c>0); PutbackRMByte(m_dst); break;
713                  case 0x08: do { ROR_BYTE();  c--; } while (c>0); PutbackRMByte(m_dst); break;
714                  case 0x10: do { ROLC_BYTE(); c--; } while (c>0); PutbackRMByte(m_dst); break;
715                  case 0x18: do { RORC_BYTE(); c--; } while (c>0); PutbackRMByte(m_dst); break;
716                  case 0x30:
717                  case 0x20: SHL_BYTE(c); break;
718                  case 0x28: SHR_BYTE(c); break;
719                  case 0x38: SHRA_BYTE(c); break;
720                  }
721               }
722            }
723            break;
724
725         case 0xd3: // i_rotshft_wcl
726            {
727               UINT8 c;
728
729               m_modrm = fetch();
730               m_src = GetRMWord();
731               m_dst = m_src;
732               c = m_regs.b[CL];
733               CLKM(ROT_REG_BASE,ROT_M16_BASE);
734               m_icount -= m_timing[ROT_REG_BIT] * c;
735               if (c)
736               {
737                  switch ( m_modrm & 0x38 )
738                  {
739                     case 0x00: do { ROL_WORD();  c--; } while (c>0); PutbackRMWord(m_dst); break;
740                     case 0x08: do { ROR_WORD();  c--; } while (c>0); PutbackRMWord(m_dst); break;
741                     case 0x10: do { ROLC_WORD(); c--; } while (c>0); PutbackRMWord(m_dst); break;
742                     case 0x18: do { RORC_WORD(); c--; } while (c>0); PutbackRMWord(m_dst); break;
743                     case 0x30:
744                     case 0x20: SHL_WORD(c); break;
745                     case 0x28: SHR_WORD(c); break;
746                     case 0x38: SHRA_WORD(c); break;
747                  }
748               }
749            }
750            break;
751
752         default:
753            if(!common_op(op))
754            {
755               m_icount -= 10;
756               logerror("%s: %06x: Invalid Opcode %02x\n", tag(), pc(), op);
757               break;
758            }
759            break;
760      }
158761   }
762}
159763
160   for (i = 0xc0; i < 0x100; i++)
764i8086_common_cpu_device::i8086_common_cpu_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock, const char *shortname, const char *source)
765   : cpu_device(mconfig, type, name, tag, owner, clock, shortname, source)
766   , m_ip(0)
767   , m_TF(0)
768   , m_int_vector(0)
769   , m_pending_irq(0)
770   , m_nmi_state(0)
771   , m_irq_state(0)
772   , m_test_state(0)
773   , m_pc(0)
774{
775   static const BREGS reg_name[8]={ AL, CL, DL, BL, AH, CH, DH, BH };
776
777   /* Set up parity lookup table. */
778   for (UINT16 i = 0;i < 256; i++)
161779   {
162      Mod_RM.RM.w[i] = (WREGS) (i & 7);
163      Mod_RM.RM.b[i] = (BREGS) reg_name[i & 7];
780      UINT16 c = 0;
781      for (UINT16 j = i; j > 0; j >>= 1)
782      {
783         if (j & 1) c++;
784      }
785      m_parity_table[i] = !(c & 1);
164786   }
165787
166   cpustate->irq_callback = irqcallback;
167   cpustate->device = device;
168   cpustate->program = &device->space(AS_PROGRAM);
169   cpustate->direct = &cpustate->program->direct();
170   cpustate->io = &device->space(AS_IO);
788   for (UINT16 i = 0; i < 256; i++)
789   {
790      m_Mod_RM.reg.b[i] = reg_name[(i & 0x38) >> 3];
791      m_Mod_RM.reg.w[i] = (WREGS) ( (i & 0x38) >> 3) ;
792   }
171793
172   /* set up the state table */
794   for (UINT16 i = 0xc0; i < 0x100; i++)
173795   {
174      device_state_interface *state;
175      device->interface(state);
176      state->state_add(STATE_GENPC, "GENPC", cpustate->pc).mask(0xfffff).formatstr("%9s").callimport();
177      state->state_add(I8086_IP,    "IP",    cpustate->ip).callimport().callexport();
178      state->state_add(I8086_FLAGS, "FLAGS", cpustate->flags).callimport().callexport().noshow();
179      state->state_add(STATE_GENFLAGS, "GENFLAGS", cpustate->flags).callimport().callexport().noshow().formatstr("%16s");
180      state->state_add(I8086_AX,    "AX",    cpustate->regs.w[AX]);
181      state->state_add(I8086_BX,    "BX",    cpustate->regs.w[BX]);
182      state->state_add(I8086_CX,    "CX",    cpustate->regs.w[CX]);
183      state->state_add(I8086_DX,    "DX",    cpustate->regs.w[DX]);
184      state->state_add(I8086_SI,    "SI",    cpustate->regs.w[SI]);
185      state->state_add(I8086_DI,    "DI",    cpustate->regs.w[DI]);
186      state->state_add(I8086_BP,    "BP",    cpustate->regs.w[BP]);
187      state->state_add(I8086_SP,    "SP",    cpustate->regs.w[SP]);
188      state->state_add(STATE_GENSP, "GENSP", cpustate->sp).mask(0xfffff).formatstr("%9s").callimport().callexport();
189      state->state_add(I8086_AL,    "AL",    cpustate->regs.b[AL]).noshow();
190      state->state_add(I8086_BL,    "BL",    cpustate->regs.b[BL]).noshow();
191      state->state_add(I8086_CL,    "CL",    cpustate->regs.b[CL]).noshow();
192      state->state_add(I8086_DL,    "DL",    cpustate->regs.b[DL]).noshow();
193      state->state_add(I8086_AH,    "AH",    cpustate->regs.b[AH]).noshow();
194      state->state_add(I8086_BH,    "BH",    cpustate->regs.b[BH]).noshow();
195      state->state_add(I8086_CH,    "CH",    cpustate->regs.b[CH]).noshow();
196      state->state_add(I8086_DH,    "DH",    cpustate->regs.b[DH]).noshow();
197      state->state_add(I8086_CS,    "CS",    cpustate->sregs[CS]).callimport();
198      state->state_add(I8086_DS,    "DS",    cpustate->sregs[DS]).callimport();
199      state->state_add(I8086_ES,    "ES",    cpustate->sregs[ES]).callimport();
200      state->state_add(I8086_SS,    "SS",    cpustate->sregs[SS]).callimport();
796      m_Mod_RM.RM.w[i] = (WREGS)( i & 7 );
797      m_Mod_RM.RM.b[i] = (BREGS)reg_name[i & 7];
201798   }
799}
202800
203   i8086_state_register(device);
204   cpustate->fetch_xor = BYTE_XOR_LE(0);
801void i8086_common_cpu_device::state_string_export(const device_state_entry &entry, astring &string)
802{
803   switch (entry.index())
804   {
805      case STATE_GENPC:
806         string.printf("%08X", pc() );
807         break;
808
809      case STATE_GENFLAGS:
810         {
811            UINT16 flags = CompressFlags();
812            string.printf("%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c",
813               flags & 0x8000 ? '1':'.',
814               flags & 0x4000 ? '1':'.',
815               flags & 0x2000 ? '1':'.',
816               flags & 0x1000 ? '1':'.',
817               flags & 0x0800 ? 'O':'.',
818               flags & 0x0400 ? 'D':'.',
819               flags & 0x0200 ? 'I':'.',
820               flags & 0x0100 ? 'T':'.',
821               flags & 0x0080 ? 'S':'.',
822               flags & 0x0040 ? 'Z':'.',
823               flags & 0x0020 ? '0':'.',
824               flags & 0x0010 ? 'A':'.',
825               flags & 0x0008 ? '0':'.',
826               flags & 0x0004 ? 'P':'.',
827               flags & 0x0002 ? '1':'.',
828               flags & 0x0001 ? 'C':'.');
829         }
830         break;
831   }
205832}
206833
207static CPU_INIT( i8088 )
834void i8086_common_cpu_device::device_start()
208835{
209   i8086_state *cpustate = get_safe_token(device);
210   CPU_INIT_CALL(i8086);
211   cpustate->fetch_xor = 0;
836   m_program = &space(AS_PROGRAM);
837   m_direct = &m_program->direct();
838   m_io = &space(AS_IO);
839
840   save_item(NAME(m_regs.w));
841   save_item(NAME(m_sregs));
842   save_item(NAME(m_ip));
843   save_item(NAME(m_prev_ip));
844   save_item(NAME(m_TF));
845   save_item(NAME(m_IF));
846   save_item(NAME(m_DF));
847   save_item(NAME(m_SignVal));
848   save_item(NAME(m_int_vector));
849   save_item(NAME(m_pending_irq));
850   save_item(NAME(m_nmi_state));
851   save_item(NAME(m_irq_state));
852   save_item(NAME(m_AuxVal));
853   save_item(NAME(m_OverVal));
854   save_item(NAME(m_ZeroVal));
855   save_item(NAME(m_CarryVal));
856   save_item(NAME(m_ParityVal));
857   save_item(NAME(m_seg_prefix));
858   save_item(NAME(m_seg_prefix_next));
859
860   // Register state for debugger
861//  state_add( I8086_PC, "PC", m_PC ).callimport().callexport().formatstr("%04X");
862   state_add( I8086_IP, "IP", m_ip         ).callimport().callexport().formatstr("%04X");
863   state_add( I8086_AX, "AX", m_regs.w[AX] ).callimport().callexport().formatstr("%04X");
864   state_add( I8086_CX, "CX", m_regs.w[CS] ).callimport().callexport().formatstr("%04X");
865   state_add( I8086_DX, "DX", m_regs.w[DX] ).callimport().callexport().formatstr("%04X");
866   state_add( I8086_BX, "BX", m_regs.w[BX] ).callimport().callexport().formatstr("%04X");
867   state_add( I8086_SP, "SP", m_regs.w[SP] ).callimport().callexport().formatstr("%04X");
868   state_add( I8086_BP, "BP", m_regs.w[BP] ).callimport().callexport().formatstr("%04X");
869   state_add( I8086_SI, "SI", m_regs.w[SI] ).callimport().callexport().formatstr("%04X");
870   state_add( I8086_DI, "DI", m_regs.w[DI] ).callimport().callexport().formatstr("%04X");
871   state_add( I8086_ES, "ES", m_sregs[ES] ).callimport().callexport().formatstr("%04X");
872   state_add( I8086_CS, "CS", m_sregs[CS] ).callimport().callexport().formatstr("%04X");
873   state_add( I8086_SS, "SS", m_sregs[SS] ).callimport().callexport().formatstr("%04X");
874   state_add( I8086_DS, "DS", m_sregs[DS] ).callimport().callexport().formatstr("%04X");
875   state_add( I8086_VECTOR, "V", m_int_vector).callimport().callexport().formatstr("%02X");
876
877   state_add(STATE_GENPC, "curpc", m_pc).callimport().callexport().formatstr("%05X");
878   state_add(STATE_GENFLAGS, "GENFLAGS", m_TF).callimport().callexport().formatstr("%16s").noshow();
879
880   m_icountptr = &m_icount;
212881}
213882
214static CPU_INIT( i80186 )
883
884void i8086_common_cpu_device::device_reset()
215885{
216   i8086_state *cpustate = get_safe_token(device);
886   m_ZeroVal = 1;
887   m_ParityVal = 1;
888   m_regs.w[AX] = 0;
889   m_regs.w[CX] = 0;
890   m_regs.w[DX] = 0;
891   m_regs.w[BX] = 0;
892   m_regs.w[SP] = 0;
893   m_regs.w[BP] = 0;
894   m_regs.w[SI] = 0;
895   m_regs.w[DI] = 0;
896   m_sregs[ES] = 0;
897   m_sregs[CS] = 0xffff;
898   m_sregs[SS] = 0;
899   m_sregs[DS] = 0;
900   m_ip = 0;
901   m_prev_ip = 0;
902   m_SignVal = 0;
903   m_AuxVal = 0;
904   m_OverVal = 0;
905   m_CarryVal = 0;
906   m_TF = 0;
907   m_IF = 0;
908   m_DF = 0;
909   m_int_vector = 0;
910   m_pending_irq = 0;
911   m_nmi_state = 0;
912   m_irq_state = 0;
913   m_no_interrupt = 0;
914   m_fire_trap = 0;
915   m_prefix_base = 0;
916   m_seg_prefix = false;
917   m_seg_prefix_next = false;
918   m_ea = 0;
919   m_eo = 0;
920   m_e16 = 0;
921   m_modrm = 0;
922   m_dst = 0;
923   m_src = 0;
924}
217925
218   CPU_INIT_CALL(i8086);
219926
220   /* resolve callbacks */
221   i80186_interface *intf = (i80186_interface *) device->static_config();
927inline UINT32 i8086_common_cpu_device::pc()
928{
929   m_pc = ( m_sregs[CS] << 4 ) + m_ip;
930   return m_pc;
931}
222932
223   if (intf != NULL)
933
934inline UINT8 i8086_common_cpu_device::read_byte(UINT32 addr)
935{
936   return m_program->read_byte(addr);
937}
938
939
940inline UINT16 i8086_common_cpu_device::read_word(UINT32 addr)
941{
942   return m_program->read_word_unaligned(addr);
943}
944
945
946inline void i8086_common_cpu_device::write_byte(UINT32 addr, UINT8 data)
947{
948   m_program->write_byte(addr, data);
949}
950
951
952inline void i8086_common_cpu_device::write_word(UINT32 addr, UINT16 data)
953{
954   m_program->write_word_unaligned(addr, data);
955}
956
957
958inline UINT8 i8086_common_cpu_device::read_port_byte(UINT16 port)
959{
960   return m_io->read_byte(port);
961}
962
963inline UINT16 i8086_common_cpu_device::read_port_word(UINT16 port)
964{
965   return m_io->read_word_unaligned(port);
966}
967
968inline void i8086_common_cpu_device::write_port_byte(UINT16 port, UINT8 data)
969{
970   m_io->write_byte(port, data);
971}
972
973inline void i8086_common_cpu_device::write_port_word(UINT16 port, UINT16 data)
974{
975   m_io->write_word_unaligned(port, data);
976}
977
978inline UINT8 i8086_common_cpu_device::fetch_op()
979{
980   UINT8 data = m_direct->read_decrypted_byte( pc() );
981   m_ip++;
982   return data;
983}
984
985
986inline UINT8 i8086_common_cpu_device::fetch()
987{
988   UINT8 data = m_direct->read_raw_byte( pc() );
989   m_ip++;
990   return data;
991}
992
993
994inline UINT16 i8086_common_cpu_device::fetch_word()
995{
996   UINT16 data = fetch();
997   data |= ( fetch() << 8 );
998   return data;
999}
1000
1001
1002inline UINT8 i8086_common_cpu_device::repx_op()
1003{
1004   UINT8 next = fetch_op();
1005   bool seg_prefix = false;
1006   int seg = 0;
1007
1008   switch (next)
2241009   {
225      cpustate->out_tmrout0_func.resolve(intf->out_tmrout0_func, *device);
226      cpustate->out_tmrout1_func.resolve(intf->out_tmrout1_func, *device);
1010   case 0x26:
1011      seg_prefix = true;
1012      seg = ES;
1013      break;
1014   case 0x2e:
1015      seg_prefix = true;
1016      seg = CS;
1017      break;
1018   case 0x36:
1019      seg_prefix = true;
1020      seg = SS;
1021      break;
1022   case 0x3e:
1023      seg_prefix = true;
1024      seg = DS;
1025      break;
2271026   }
1027
1028   if ( seg_prefix )
1029   {
1030      m_seg_prefix = true;
1031      m_seg_prefix_next = true;
1032      m_prefix_base = m_sregs[seg] << 4;
1033      next = fetch_op();
1034      CLK(OVERRIDE);
1035   }
1036
1037   return next;
2281038}
2291039
230static CPU_RESET( i8086 )
1040
1041inline void i8086_common_cpu_device::CLK(UINT8 op)
2311042{
232   i8086_state *cpustate = get_safe_token(device);
233   device_irq_acknowledge_callback save_irqcallback;
234   offs_t save_xor;
1043   m_icount -= m_timing[op];
1044}
2351045
236   save_irqcallback = cpustate->irq_callback;
237   save_xor = cpustate->fetch_xor;
238   memset(cpustate, 0, sizeof(*cpustate));
239   cpustate->irq_callback = save_irqcallback;
240   cpustate->fetch_xor = save_xor;
241   cpustate->device = device;
242   cpustate->program = &device->space(AS_PROGRAM);
243   cpustate->direct = &cpustate->program->direct();
244   cpustate->io = &device->space(AS_IO);
2451046
246   cpustate->sregs[CS] = 0xffff;
247   cpustate->base[CS] = SegBase(CS);
248   cpustate->pc = 0xffff0 & AMASK;
249   ExpandFlags(cpustate->flags);
1047inline void i8086_common_cpu_device::CLKM(UINT8 op_reg, UINT8 op_mem)
1048{
1049   m_icount -= ( m_modrm >= 0xc0 ) ? m_timing[op_reg] : m_timing[op_mem];
1050}
2501051
251   cpustate->halted = 0;
1052
1053inline UINT32 i8086_common_cpu_device::default_base(int seg)
1054{
1055   if ( m_seg_prefix && (seg==DS || seg==SS) )
1056   {
1057      return m_prefix_base;
1058   }
1059   else
1060   {
1061      return m_sregs[seg] << 4;
1062   }
2521063}
2531064
254static CPU_EXIT( i8086 )
1065
1066inline UINT32 i8086_common_cpu_device::get_ea()
2551067{
256   /* nothing to do ? */
1068   switch( m_modrm & 0xc7 )
1069   {
1070   case 0x00:
1071      m_eo = m_regs.w[BX] + m_regs.w[SI];
1072      m_ea = default_base(DS) + m_eo;
1073      break;
1074   case 0x01:
1075      m_eo = m_regs.w[BX] + m_regs.w[DI];
1076      m_ea = default_base(DS) + m_eo;
1077      break;
1078   case 0x02:
1079      m_eo = m_regs.w[BP] + m_regs.w[SI];
1080      m_ea = default_base(SS) + m_eo;
1081      break;
1082   case 0x03:
1083      m_eo = m_regs.w[BP] + m_regs.w[DI];
1084      m_ea = default_base(SS) + m_eo;
1085      break;
1086   case 0x04:
1087      m_eo = m_regs.w[SI];
1088      m_ea = default_base(DS) + m_eo;
1089      break;
1090   case 0x05:
1091      m_eo = m_regs.w[DI];
1092      m_ea = default_base(DS) + m_eo;
1093      break;
1094   case 0x06:
1095      m_eo = fetch_word();
1096      m_ea = default_base(DS) + m_eo;
1097      break;
1098   case 0x07:
1099      m_eo = m_regs.w[BX];
1100      m_ea = default_base(DS) + m_eo;
1101      break;
1102
1103   case 0x40:
1104      m_eo = m_regs.w[BX] + m_regs.w[SI] + (INT8)fetch();
1105      m_ea = default_base(DS) + m_eo;
1106      break;
1107   case 0x41:
1108      m_eo = m_regs.w[BX] + m_regs.w[DI] + (INT8)fetch();
1109      m_ea = default_base(DS) + m_eo;
1110      break;
1111   case 0x42:
1112      m_eo = m_regs.w[BP] + m_regs.w[SI] + (INT8)fetch();
1113      m_ea = default_base(SS) + m_eo;
1114      break;
1115   case 0x43:
1116      m_eo = m_regs.w[BP] + m_regs.w[DI] + (INT8)fetch();
1117      m_ea = default_base(SS) + m_eo;
1118      break;
1119   case 0x44:
1120      m_eo = m_regs.w[SI] + (INT8)fetch();
1121      m_ea = default_base(DS) + m_eo;
1122      break;
1123   case 0x45:
1124      m_eo = m_regs.w[DI] + (INT8)fetch();
1125      m_ea = default_base(DS) + m_eo;
1126      break;
1127   case 0x46:
1128      m_eo = m_regs.w[BP] + (INT8)fetch();
1129      m_ea = default_base(SS) + m_eo;
1130      break;
1131   case 0x47:
1132      m_eo = m_regs.w[BX] + (INT8)fetch();
1133      m_ea = default_base(DS) + m_eo;
1134      break;
1135
1136   case 0x80:
1137      m_e16 = fetch_word();
1138      m_eo = m_regs.w[BX] + m_regs.w[SI] + (INT16)m_e16;
1139      m_ea = default_base(DS) + m_eo;
1140      break;
1141   case 0x81:
1142      m_e16 = fetch_word();
1143      m_eo = m_regs.w[BX] + m_regs.w[DI] + (INT16)m_e16;
1144      m_ea = default_base(DS) + m_eo;
1145      break;
1146   case 0x82:
1147      m_e16 = fetch_word();
1148      m_eo = m_regs.w[BP] + m_regs.w[SI] + (INT16)m_e16;
1149      m_ea = default_base(SS) + m_eo;
1150      break;
1151   case 0x83:
1152      m_e16 = fetch_word();
1153      m_eo = m_regs.w[BP] + m_regs.w[DI] + (INT16)m_e16;
1154      m_ea = default_base(SS) + m_eo;
1155      break;
1156   case 0x84:
1157      m_e16 = fetch_word();
1158      m_eo = m_regs.w[SI] + (INT16)m_e16;
1159      m_ea = default_base(DS) + m_eo;
1160      break;
1161   case 0x85:
1162      m_e16 = fetch_word();
1163      m_eo = m_regs.w[DI] + (INT16)m_e16;
1164      m_ea = default_base(DS) + m_eo;
1165      break;
1166   case 0x86:
1167      m_e16 = fetch_word();
1168      m_eo = m_regs.w[BP] + (INT16)m_e16;
1169      m_ea = default_base(SS) + m_eo;
1170      break;
1171   case 0x87:
1172      m_e16 = fetch_word();
1173      m_eo = m_regs.w[BX] + (INT16)m_e16;
1174      m_ea = default_base(DS) + m_eo;
1175      break;
1176   }
1177
1178   return m_ea;
2571179}
2581180
259/* ASG 971222 -- added these interface functions */
2601181
261static void set_irq_line(i8086_state *cpustate, int irqline, int state)
1182inline void i8086_common_cpu_device::PutbackRMByte(UINT8 data)
2621183{
263   if (state != CLEAR_LINE && cpustate->halted)
1184   if ( m_modrm >= 0xc0 )
2641185   {
265      cpustate->halted = 0;
1186      m_regs.b[ m_Mod_RM.RM.b[ m_modrm ] ] = data;
2661187   }
1188   else
1189   {
1190      write_byte( m_ea, data );
1191   }
1192}
2671193
268   if (irqline == INPUT_LINE_NMI)
1194
1195inline void i8086_common_cpu_device::PutbackRMWord(UINT16 data)
1196{
1197   if ( m_modrm >= 0xc0 )
2691198   {
270      if (cpustate->nmi_state == state)
271         return;
272      cpustate->nmi_state = state;
1199      m_regs.w[ m_Mod_RM.RM.w[ m_modrm ] ] = data;
1200   }
1201   else
1202   {
1203      write_word( m_ea, data );
1204   }
1205}
2731206
274      /* on a rising edge, signal the NMI */
275      if (state != CLEAR_LINE)
276      {
277         PREFIX(_interrupt)(cpustate, I8086_NMI_INT_VECTOR);
278      }
1207inline void i8086_common_cpu_device::PutImmRMWord()
1208{
1209   if ( m_modrm >= 0xc0 )
1210   {
1211      m_regs.w[ m_Mod_RM.RM.w[ m_modrm ] ] = fetch_word();
2791212   }
2801213   else
2811214   {
282      cpustate->irq_state = state;
1215      UINT32 addr = get_ea();
1216      write_word( addr, fetch_word() );
1217   }
1218}
2831219
284      /* if the IF is set, signal an interrupt */
285      if (state != CLEAR_LINE && cpustate->IF)
286         PREFIX(_interrupt)(cpustate, (UINT32)-1);
1220inline void i8086_common_cpu_device::PutRMWord(UINT16 val)
1221{
1222   if ( m_modrm >= 0xc0 )
1223   {
1224      m_regs.w[ m_Mod_RM.RM.w[ m_modrm ] ] = val;
2871225   }
1226   else
1227   {
1228      write_word( get_ea(), val );
1229   }
2881230}
2891231
290static void set_drq_line(i8086_state *cpustate, int irqline, int state)
1232
1233inline void i8086_common_cpu_device::PutRMByte(UINT8 val)
2911234{
292   // TODO implement me
1235   if ( m_modrm >= 0xc0 )
1236   {
1237      m_regs.b[ m_Mod_RM.RM.b[ m_modrm ] ] = val;
1238   }
1239   else
1240   {
1241      write_byte( get_ea(), val );
1242   }
2931243}
2941244
295static void set_tmrin_line(i8086_state *cpustate, int irqline, int state)
1245
1246inline void i8086_common_cpu_device::PutImmRMByte()
2961247{
297   // TODO implement me
1248   if ( m_modrm >= 0xc0 )
1249   {
1250      m_regs.b[ m_Mod_RM.RM.b[ m_modrm ] ] = fetch();
1251   }
1252   else
1253   {
1254      UINT32 addr = get_ea();
1255      write_byte( addr, fetch() );
1256   }
2981257}
2991258
300/* PJB 03/05 */
301static void set_test_line(i8086_state *cpustate, int state)
1259
1260inline void i8086_common_cpu_device::DEF_br8()
3021261{
303   cpustate->test_state = !state;
1262   m_modrm = fetch();
1263   m_src = RegByte();
1264   m_dst = GetRMByte();
3041265}
3051266
306static CPU_EXECUTE( i8086 )
1267
1268inline void i8086_common_cpu_device::DEF_wr16()
3071269{
308   i8086_state *cpustate = get_safe_token(device);
1270   m_modrm = fetch();
1271   m_src = RegWord();
1272   m_dst = GetRMWord();
1273}
3091274
3101275
311   if (cpustate->halted)
1276inline void i8086_common_cpu_device::DEF_r8b()
1277{
1278   m_modrm = fetch();
1279   m_dst = RegByte();
1280   m_src = GetRMByte();
1281}
1282
1283
1284inline void i8086_common_cpu_device::DEF_r16w()
1285{
1286   m_modrm = fetch();
1287   m_dst = RegWord();
1288   m_src = GetRMWord();
1289}
1290
1291
1292inline void i8086_common_cpu_device::DEF_ald8()
1293{
1294   m_src = fetch();
1295   m_dst = m_regs.b[AL];
1296}
1297
1298
1299inline void i8086_common_cpu_device::DEF_axd16()
1300{
1301   m_src = fetch_word();
1302   m_dst = m_regs.w[AX];
1303}
1304
1305
1306
1307inline void i8086_common_cpu_device::RegByte(UINT8 data)
1308{
1309   m_regs.b[ m_Mod_RM.reg.b[ m_modrm ] ] = data;
1310}
1311
1312
1313inline void i8086_common_cpu_device::RegWord(UINT16 data)
1314{
1315   m_regs.w[ m_Mod_RM.reg.w[ m_modrm ] ] = data;
1316}
1317
1318
1319inline UINT8 i8086_common_cpu_device::RegByte()
1320{
1321   return m_regs.b[ m_Mod_RM.reg.b[ m_modrm ] ];
1322}
1323
1324
1325inline UINT16 i8086_common_cpu_device::RegWord()
1326{
1327   return m_regs.w[ m_Mod_RM.reg.w[ m_modrm ] ];
1328}
1329
1330
1331inline UINT16 i8086_common_cpu_device::GetRMWord()
1332{
1333   if ( m_modrm >= 0xc0 )
3121334   {
313      cpustate->icount = 0;
314      return;
1335      return m_regs.w[ m_Mod_RM.RM.w[ m_modrm ] ];
3151336   }
1337   else
1338   {
1339      return read_word( get_ea() );
1340   }
1341}
3161342
317   /* copy over the cycle counts if they're not correct */
318   if (timing.id != 8086)
319      timing = i8086_cycles;
3201343
321   /* adjust for any interrupts that came in */
322   cpustate->icount -= cpustate->extra_cycles;
323   cpustate->extra_cycles = 0;
1344inline UINT16 i8086_common_cpu_device::GetnextRMWord()
1345{
1346   UINT32 addr = ( m_ea & 0xf0000 ) | ( ( m_ea + 2 ) & 0xffff );
3241347
325   /* run until we're out */
326   while (cpustate->icount > 0)
1348   return read_word( addr );
1349}
1350
1351
1352inline UINT8 i8086_common_cpu_device::GetRMByte()
1353{
1354   if ( m_modrm >= 0xc0 )
3271355   {
328      LOG(("[%04x:%04x]=%02x\tF:%04x\tAX=%04x\tBX=%04x\tCX=%04x\tDX=%04x %d%d%d%d%d%d%d%d%d\n",
329            cpustate->sregs[CS], cpustate->pc - cpustate->base[CS], ReadByte(cpustate->pc), cpustate->flags, cpustate->regs.w[AX], cpustate->regs.w[BX], cpustate->regs.w[CX], cpustate->regs.w[DX], cpustate->AuxVal ? 1 : 0, cpustate->OverVal ? 1 : 0,
330            cpustate->SignVal ? 1 : 0, cpustate->ZeroVal ? 1 : 0, cpustate->CarryVal ? 1 : 0, cpustate->ParityVal ? 1 : 0, cpustate->TF, cpustate->IF, cpustate->DirVal < 0 ? 1 : 0));
331      debugger_instruction_hook(device, cpustate->pc);
1356      return m_regs.b[ m_Mod_RM.RM.b[ m_modrm ] ];
1357   }
1358   else
1359   {
1360      return read_byte( get_ea() );
1361   }
1362}
3321363
333      cpustate->seg_prefix = FALSE;
334      cpustate->prevpc = cpustate->pc;
335      TABLE86;
1364
1365inline void i8086_common_cpu_device::PutMemB(int seg, UINT16 offset, UINT8 data)
1366{
1367   write_byte( default_base( seg ) + offset, data);
1368}
1369
1370
1371inline void i8086_common_cpu_device::PutMemW(int seg, UINT16 offset, UINT16 data)
1372{
1373   // if offset == 0xffff, 8086 writes to 0xffff and 0, 80186 writes to 0xffff and 0x10000
1374   write_word( default_base( seg ) + offset, data);
1375}
1376
1377
1378inline UINT8 i8086_common_cpu_device::GetMemB(int seg, UINT16 offset)
1379{
1380   return read_byte( default_base(seg) + offset );
1381}
1382
1383
1384inline UINT16 i8086_common_cpu_device::GetMemW(int seg, UINT16 offset)
1385{
1386   return read_word( default_base(seg) + offset );
1387}
1388
1389
1390// Setting flags
1391
1392inline void i8086_common_cpu_device::set_CFB(UINT32 x)
1393{
1394   m_CarryVal = x & 0x100;
1395}
1396
1397inline void i8086_common_cpu_device::set_CFW(UINT32 x)
1398{
1399   m_CarryVal = x & 0x10000;
1400}
1401
1402inline void i8086_common_cpu_device::set_AF(UINT32 x,UINT32 y,UINT32 z)
1403{
1404   m_AuxVal = (x ^ (y ^ z)) & 0x10;
1405}
1406
1407inline void i8086_common_cpu_device::set_SF(UINT32 x)
1408{
1409   m_SignVal = x;
1410}
1411
1412inline void i8086_common_cpu_device::set_ZF(UINT32 x)
1413{
1414   m_ZeroVal = x;
1415}
1416
1417inline void i8086_common_cpu_device::set_PF(UINT32 x)
1418{
1419   m_ParityVal = x;
1420}
1421
1422inline void i8086_common_cpu_device::set_SZPF_Byte(UINT32 x)
1423{
1424   m_SignVal = m_ZeroVal = m_ParityVal = (INT8)x;
1425}
1426
1427inline void i8086_common_cpu_device::set_SZPF_Word(UINT32 x)
1428{
1429   m_SignVal = m_ZeroVal = m_ParityVal = (INT16)x;
1430}
1431
1432inline void i8086_common_cpu_device::set_OFW_Add(UINT32 x,UINT32 y,UINT32 z)
1433{
1434   m_OverVal = (x ^ y) & (x ^ z) & 0x8000;
1435}
1436
1437inline void i8086_common_cpu_device::set_OFB_Add(UINT32 x,UINT32 y,UINT32 z)
1438{
1439   m_OverVal = (x ^ y) & (x ^ z) & 0x80;
1440}
1441
1442inline void i8086_common_cpu_device::set_OFW_Sub(UINT32 x,UINT32 y,UINT32 z)
1443{
1444   m_OverVal = (z ^ y) & (z ^ x) & 0x8000;
1445}
1446
1447inline void i8086_common_cpu_device::set_OFB_Sub(UINT32 x,UINT32 y,UINT32 z)
1448{
1449   m_OverVal = (z ^ y) & (z ^ x) & 0x80;
1450}
1451
1452
1453inline UINT16 i8086_common_cpu_device::CompressFlags()
1454{
1455   return (CF ? 1 : 0)
1456      | (1 << 1)
1457      | (PF ? 4 : 0)
1458      | (AF ? 0x10 : 0)
1459      | (ZF ? 0x40 : 0)
1460      | (SF ? 0x80 : 0)
1461      | (m_TF << 8)
1462      | (m_IF << 9)
1463      | (m_DF << 10)
1464      | (OF << 11)
1465      | (0xf << 12);
1466}
1467
1468inline void i8086_common_cpu_device::ExpandFlags(UINT16 f)
1469{
1470   m_CarryVal = (f) & 1;
1471   m_ParityVal = !((f) & 4);
1472   m_AuxVal = (f) & 16;
1473   m_ZeroVal = !((f) & 64);
1474   m_SignVal = (f) & 128 ? -1 : 0;
1475   m_TF = ((f) & 256) == 256;
1476   m_IF = ((f) & 512) == 512;
1477   m_DF = ((f) & 1024) == 1024;
1478   m_OverVal = (f) & 2048;
1479}
1480
1481inline void i8086_common_cpu_device::i_insb()
1482{
1483   PutMemB( ES, m_regs.w[DI], read_port_byte( m_regs.w[DX] ) );
1484   m_regs.w[DI] += -2 * m_DF + 1;
1485   CLK(IN_IMM8);
1486}
1487
1488inline void i8086_common_cpu_device::i_insw()
1489{
1490   PutMemW( ES, m_regs.w[DI], read_port_word( m_regs.w[DX] ) );
1491   m_regs.w[DI] += -4 * m_DF + 2;
1492   CLK(IN_IMM16);
1493}
1494
1495inline void i8086_common_cpu_device::i_outsb()
1496{
1497   write_port_byte( m_regs.w[DX], GetMemB( DS, m_regs.w[SI] ) );
1498   m_regs.w[SI] += -2 * m_DF + 1;
1499   CLK(OUT_IMM8);
1500}
1501
1502inline void i8086_common_cpu_device::i_outsw()
1503{
1504   write_port_word( m_regs.w[DX], GetMemW( DS, m_regs.w[SI] ) );
1505   m_regs.w[SI] += -4 * m_DF + 2;
1506   CLK(OUT_IMM16);
1507}
1508
1509inline void i8086_common_cpu_device::i_movsb()
1510{
1511   UINT8 tmp = GetMemB( DS, m_regs.w[SI] );
1512   PutMemB( ES, m_regs.w[DI], tmp);
1513   m_regs.w[DI] += -2 * m_DF + 1;
1514   m_regs.w[SI] += -2 * m_DF + 1;
1515   CLK(MOVS8);
1516}
1517
1518inline void i8086_common_cpu_device::i_movsw()
1519{
1520   UINT16 tmp = GetMemW( DS, m_regs.w[SI] );
1521   PutMemW( ES, m_regs.w[DI], tmp );
1522   m_regs.w[DI] += -4 * m_DF + 2;
1523   m_regs.w[SI] += -4 * m_DF + 2;
1524   CLK(MOVS16);
1525}
1526
1527inline void i8086_common_cpu_device::i_cmpsb()
1528{
1529   m_src = GetMemB( ES, m_regs.w[DI] );
1530   m_dst = GetMemB( DS, m_regs.w[SI] );
1531   SUBB();
1532   m_regs.w[DI] += -2 * m_DF + 1;
1533   m_regs.w[SI] += -2 * m_DF + 1;
1534   CLK(CMPS8);
1535}
1536
1537inline void i8086_common_cpu_device::i_cmpsw()
1538{
1539   m_src = GetMemW( ES, m_regs.w[DI] );
1540   m_dst = GetMemW( DS, m_regs.w[SI] );
1541   SUBX();
1542   m_regs.w[DI] += -4 * m_DF + 2;
1543   m_regs.w[SI] += -4 * m_DF + 2;
1544   CLK(CMPS16);
1545}
1546
1547inline void i8086_common_cpu_device::i_stosb()
1548{
1549   PutMemB( ES, m_regs.w[DI], m_regs.b[AL] );
1550   m_regs.w[DI] += -2 * m_DF + 1;
1551   CLK(STOS8);
1552}
1553
1554inline void i8086_common_cpu_device::i_stosw()
1555{
1556   PutMemW( ES, m_regs.w[DI], m_regs.w[AX] );
1557   m_regs.w[DI] += -4 * m_DF + 2;
1558   CLK(STOS16);
1559}
1560
1561inline void i8086_common_cpu_device::i_lodsb()
1562{
1563   m_regs.b[AL] = GetMemB( DS, m_regs.w[SI] );
1564   m_regs.w[SI] += -2 * m_DF + 1;
1565   CLK(LODS8);
1566}
1567
1568inline void i8086_common_cpu_device::i_lodsw()
1569{
1570   m_regs.w[AX] = GetMemW( DS, m_regs.w[SI] );
1571   m_regs.w[SI] += -4 * m_DF + 2;
1572   CLK(LODS16);
1573}
1574
1575inline void i8086_common_cpu_device::i_scasb()
1576{
1577   m_src = GetMemB( ES, m_regs.w[DI] );
1578   m_dst = m_regs.b[AL];
1579   SUBB();
1580   m_regs.w[DI] += -2 * m_DF + 1;
1581   CLK(SCAS8);
1582}
1583
1584inline void i8086_common_cpu_device::i_scasw()
1585{
1586   m_src = GetMemW( ES, m_regs.w[DI] );
1587   m_dst = m_regs.w[AX];
1588   SUBX();
1589   m_regs.w[DI] += -4 * m_DF + 2;
1590   CLK(SCAS16);
1591}
1592
1593
1594inline void i8086_common_cpu_device::i_popf()
1595{
1596   UINT32 tmp = POP();
1597
1598   ExpandFlags(tmp);
1599   CLK(POPF);
1600   if (m_TF)
1601   {
1602      m_fire_trap = 1;
3361603   }
1604}
3371605
338   /* adjust for any interrupts that came in */
339   cpustate->icount -= cpustate->extra_cycles;
340   cpustate->extra_cycles = 0;
1606
1607inline void i8086_common_cpu_device::ADDB()
1608{
1609   UINT32 res = m_dst + m_src;
1610
1611   set_CFB(res);
1612   set_OFB_Add(res,m_src,m_dst);
1613   set_AF(res,m_src,m_dst);
1614   set_SZPF_Byte(res);
1615   m_dst = res & 0xff;
3411616}
3421617
3431618
344static CPU_DISASSEMBLE( i8086 )
1619inline void i8086_common_cpu_device::ADDX()
3451620{
346   return i386_dasm_one(buffer, pc, oprom, 1);
1621   UINT32 res = m_dst + m_src;
1622
1623   set_CFW(res);
1624   set_OFW_Add(res,m_src,m_dst);
1625   set_AF(res,m_src,m_dst);
1626   set_SZPF_Word(res);
1627   m_dst = res & 0xffff;
3471628}
3481629
3491630
1631inline void i8086_common_cpu_device::SUBB()
1632{
1633   UINT32 res = m_dst - m_src;
3501634
351#include "i86.h"
1635   set_CFB(res);
1636   set_OFB_Sub(res,m_src,m_dst);
1637   set_AF(res,m_src,m_dst);
1638   set_SZPF_Byte(res);
1639   m_dst = res & 0xff;
1640}
3521641
353#undef PREFIX
354#define PREFIX(name) i80186##name
355#define PREFIX186(name) i80186##name
3561642
357#define I80186
358#include "instr186.h"
359#include "table186.h"
1643inline void i8086_common_cpu_device::SUBX()
1644{
1645   UINT32 res = m_dst - m_src;
3601646
361#include "instr86.c"
362#include "instr186.c"
363#undef I80186
1647   set_CFW(res);
1648   set_OFW_Sub(res,m_src,m_dst);
1649   set_AF(res,m_src,m_dst);
1650   set_SZPF_Word(res);
1651   m_dst = res & 0xffff;
1652}
3641653
365static CPU_EXECUTE( i80186 )
1654
1655inline void i8086_common_cpu_device::ORB()
3661656{
367   i8086_state *cpustate = get_safe_token(device);
1657   m_dst |= m_src;
1658   m_CarryVal = m_OverVal = m_AuxVal = 0;
1659   set_SZPF_Byte(m_dst);
1660}
3681661
369   /* copy over the cycle counts if they're not correct */
370   if (timing.id != 80186)
371      timing = i80186_cycles;
3721662
373   /* adjust for any interrupts that came in */
374   cpustate->icount -= cpustate->extra_cycles;
375   cpustate->extra_cycles = 0;
1663inline void i8086_common_cpu_device::ORW()
1664{
1665   m_dst |= m_src;
1666   m_CarryVal = m_OverVal = m_AuxVal = 0;
1667   set_SZPF_Word(m_dst);
1668}
3761669
377   /* run until we're out */
378   while (cpustate->icount > 0)
1670
1671inline void i8086_common_cpu_device::ANDB()
1672{
1673   m_dst &= m_src;
1674   m_CarryVal = m_OverVal = m_AuxVal = 0;
1675   set_SZPF_Byte(m_dst);
1676}
1677
1678
1679inline void i8086_common_cpu_device::ANDX()
1680{
1681   m_dst &= m_src;
1682   m_CarryVal = m_OverVal = m_AuxVal = 0;
1683   set_SZPF_Word(m_dst);
1684}
1685
1686
1687inline void i8086_common_cpu_device::XORB()
1688{
1689   m_dst ^= m_src;
1690   m_CarryVal = m_OverVal = m_AuxVal = 0;
1691   set_SZPF_Byte(m_dst);
1692}
1693
1694
1695inline void i8086_common_cpu_device::XORW()
1696{
1697   m_dst ^= m_src;
1698   m_CarryVal = m_OverVal = m_AuxVal = 0;
1699   set_SZPF_Word(m_dst);
1700}
1701
1702
1703inline void i8086_common_cpu_device::ROL_BYTE()
1704{
1705   m_CarryVal = m_dst & 0x80;
1706   m_dst = (m_dst << 1) | ( CF ? 1 : 0 );
1707}
1708
1709inline void i8086_common_cpu_device::ROL_WORD()
1710{
1711   m_CarryVal = m_dst & 0x8000;
1712   m_dst = (m_dst << 1) | ( CF ? 1 : 0 );
1713}
1714
1715inline void i8086_common_cpu_device::ROR_BYTE()
1716{
1717   m_CarryVal = m_dst & 0x1;
1718   m_dst = (m_dst >> 1) | (CF ? 0x80 : 0x00);
1719}
1720
1721inline void i8086_common_cpu_device::ROR_WORD()
1722{
1723   m_CarryVal = m_dst & 0x1;
1724   m_dst = (m_dst >> 1) + (CF ? 0x8000 : 0x0000);
1725}
1726
1727inline void i8086_common_cpu_device::ROLC_BYTE()
1728{
1729   m_dst = (m_dst << 1) | ( CF ? 1 : 0 );
1730   set_CFB(m_dst);
1731}
1732
1733inline void i8086_common_cpu_device::ROLC_WORD()
1734{
1735   m_dst = (m_dst << 1) | ( CF ? 1 : 0 );
1736   set_CFW(m_dst);
1737}
1738
1739inline void i8086_common_cpu_device::RORC_BYTE()
1740{
1741   m_dst |= ( CF ? 0x100 : 0x00);
1742   m_CarryVal = m_dst & 0x01;
1743   m_dst >>= 1;
1744}
1745
1746inline void i8086_common_cpu_device::RORC_WORD()
1747{
1748   m_dst |= ( CF ? 0x10000 : 0);
1749   m_CarryVal = m_dst & 0x01;
1750   m_dst >>= 1;
1751}
1752
1753inline void i8086_common_cpu_device::SHL_BYTE(UINT8 c)
1754{
1755   m_dst <<= c;
1756   set_CFB(m_dst);
1757   set_SZPF_Byte(m_dst);
1758   PutbackRMByte(m_dst);
1759}
1760
1761inline void i8086_common_cpu_device::SHL_WORD(UINT8 c)
1762{
1763   m_dst <<= c;
1764   set_CFW(m_dst);
1765   set_SZPF_Word(m_dst);
1766   PutbackRMWord(m_dst);
1767}
1768
1769inline void i8086_common_cpu_device::SHR_BYTE(UINT8 c)
1770{
1771   m_dst >>= c-1;
1772   m_CarryVal = m_dst & 0x1;
1773   m_dst >>= 1;
1774   set_SZPF_Byte(m_dst);
1775   PutbackRMByte(m_dst);
1776}
1777
1778inline void i8086_common_cpu_device::SHR_WORD(UINT8 c)
1779{
1780   m_dst >>= c-1;
1781   m_CarryVal = m_dst & 0x1;
1782   m_dst >>= 1;
1783   set_SZPF_Word(m_dst);
1784   PutbackRMWord(m_dst);
1785}
1786
1787inline void i8086_common_cpu_device::SHRA_BYTE(UINT8 c)
1788{
1789   m_dst = ((INT8)m_dst) >> (c-1);
1790   m_CarryVal = m_dst & 0x1;
1791   m_dst = m_dst >> 1;
1792   set_SZPF_Byte(m_dst);
1793   PutbackRMByte(m_dst);
1794}
1795
1796inline void i8086_common_cpu_device::SHRA_WORD(UINT8 c)
1797{
1798   m_dst = ((INT16)m_dst) >> (c-1);
1799   m_CarryVal = m_dst & 0x1;
1800   m_dst = m_dst >> 1;
1801   set_SZPF_Word(m_dst);
1802   PutbackRMWord(m_dst);
1803}
1804
1805
1806inline void i8086_common_cpu_device::XchgAXReg(UINT8 reg)
1807{
1808   UINT16 tmp = m_regs.w[reg];
1809
1810   m_regs.w[reg] = m_regs.w[AX];
1811   m_regs.w[AX] = tmp;
1812}
1813
1814
1815inline void i8086_common_cpu_device::IncWordReg(UINT8 reg)
1816{
1817   UINT32 tmp = m_regs.w[reg];
1818   UINT32 tmp1 = tmp+1;
1819
1820   m_OverVal = (tmp == 0x7fff);
1821   set_AF(tmp1,tmp,1);
1822   set_SZPF_Word(tmp1);
1823   m_regs.w[reg] = tmp1;
1824}
1825
1826
1827inline void i8086_common_cpu_device::DecWordReg(UINT8 reg)
1828{
1829   UINT32 tmp = m_regs.w[reg];
1830   UINT32 tmp1 = tmp-1;
1831
1832   m_OverVal = (tmp == 0x8000);
1833   set_AF(tmp1,tmp,1);
1834   set_SZPF_Word(tmp1);
1835   m_regs.w[reg] = tmp1;
1836}
1837
1838
1839inline void i8086_common_cpu_device::PUSH(UINT16 data)
1840{
1841   m_regs.w[SP] -= 2;
1842   write_word( ( m_sregs[SS] << 4 ) + m_regs.w[SP], data );
1843}
1844
1845
1846inline UINT16 i8086_common_cpu_device::POP()
1847{
1848   UINT16 data = read_word( ( m_sregs[SS] << 4 ) + m_regs.w[SP] );
1849
1850   m_regs.w[SP] += 2;
1851   return data;
1852}
1853
1854
1855inline void i8086_common_cpu_device::JMP(bool cond)
1856{
1857   int rel  = (int)((INT8)fetch());
1858
1859   if (cond)
3791860   {
380      LOG(("[%04x:%04x]=%02x\tAX=%04x\tBX=%04x\tCX=%04x\tDX=%04x\n", cpustate->sregs[CS], cpustate->pc, ReadByte(cpustate->pc), cpustate->regs.w[AX],
381            cpustate->regs.w[BX], cpustate->regs.w[CX], cpustate->regs.w[DX]));
382      debugger_instruction_hook(device, cpustate->pc);
1861      m_ip += rel;
1862      CLK(JCC_T);
1863   }
1864   else
1865      CLK(JCC_NT);
1866}
3831867
384      cpustate->seg_prefix = FALSE;
385      cpustate->prevpc = cpustate->pc;
386      TABLE186;
1868
1869inline void i8086_common_cpu_device::ADJ4(INT8 param1,INT8 param2)
1870{
1871   if (AF || ((m_regs.b[AL] & 0xf) > 9))
1872   {
1873      UINT16 tmp;
1874      tmp = m_regs.b[AL] + param1;
1875      m_regs.b[AL] = tmp;
1876      m_AuxVal = 1;
1877      m_CarryVal |= tmp & 0x100;
3871878   }
1879   if (CF || (m_regs.b[AL]>0x9f))
1880   {
1881      m_regs.b[AL] += param2;
1882      m_CarryVal = 1;
1883   }
1884   set_SZPF_Byte(m_regs.b[AL]);
1885}
3881886
389   /* adjust for any interrupts that came in */
390   cpustate->icount -= cpustate->extra_cycles;
391   cpustate->extra_cycles = 0;
1887
1888inline void i8086_common_cpu_device::ADJB(INT8 param1, INT8 param2)
1889{
1890   if (AF || ((m_regs.b[AL] & 0xf) > 9))
1891   {
1892      m_regs.b[AL] += param1;
1893      m_regs.b[AH] += param2;
1894      m_AuxVal = 1;
1895      m_CarryVal = 1;
1896   }
1897   else
1898   {
1899      m_AuxVal = 0;
1900      m_CarryVal = 0;
1901   }
1902   m_regs.b[AL] &= 0x0F;
3921903}
3931904
3941905
1906void i8086_common_cpu_device::interrupt(int int_num)
1907{
1908   PUSH( CompressFlags() );
1909   m_TF = m_IF = 0;
3951910
1911   if (int_num == -1)
1912   {
1913      int_num = standard_irq_callback(0);
3961914
397/**************************************************************************
398 * STATE IMPORT/EXPORT
399 **************************************************************************/
1915      m_irq_state = CLEAR_LINE;
1916      m_pending_irq &= ~INT_IRQ;
1917   }
4001918
401static CPU_IMPORT_STATE( i8086 )
1919   UINT16 dest_off = read_word( int_num * 4 + 0 );
1920   UINT16 dest_seg = read_word( int_num * 4 + 2 );
1921
1922   PUSH(m_sregs[CS]);
1923   PUSH(m_ip);
1924   m_ip = dest_off;
1925   m_sregs[CS] = dest_seg;
1926}
1927
1928
1929void i8086_common_cpu_device::execute_set_input( int inptnum, int state )
4021930{
403   i8086_state *cpustate = get_safe_token(device);
1931   if (inptnum == INPUT_LINE_NMI)
1932   {
1933      if ( m_nmi_state == state )
1934      {
1935         return;
1936      }
1937      m_nmi_state = state;
1938      if (state != CLEAR_LINE)
1939      {
1940         m_pending_irq |= NMI_IRQ;
1941      }
1942   }
1943   else if(inptnum == INPUT_LINE_TEST)
1944      m_test_state = state;
1945   else
1946   {
1947      m_irq_state = state;
1948      if (state == CLEAR_LINE)
1949      {
1950         m_pending_irq &= ~INT_IRQ;
1951      }
1952      else
1953      {
1954         m_pending_irq |= INT_IRQ;
1955      }
1956   }
1957}
4041958
405   switch (entry.index())
1959
1960offs_t i8086_common_cpu_device::disasm_disassemble(char *buffer, offs_t pc, const UINT8 *oprom, const UINT8 *opram, UINT32 options)
1961{
1962   extern int i386_dasm_one(char *buffer, offs_t eip, const UINT8 *oprom, int mode);
1963   return i386_dasm_one(buffer, pc, oprom, 1);
1964}
1965
1966
1967bool i8086_common_cpu_device::common_op(UINT8 op)
1968{
1969   switch(op)
4061970   {
407      case I8086_GENPC:
408         if (cpustate->pc - cpustate->base[CS] >= 0x10000)
1971      case 0x00: // i_add_br8
1972         DEF_br8();
1973         ADDB();
1974         PutbackRMByte(m_dst);
1975         CLKM(ALU_RR8,ALU_MR8);
1976         break;
1977
1978      case 0x01: // i_add_wr16
1979         DEF_wr16();
1980         ADDX();
1981         PutbackRMWord(m_dst);
1982         CLKM(ALU_RR16,ALU_MR16);
1983         break;
1984
1985      case 0x02: // i_add_r8b
1986         DEF_r8b();
1987         ADDB();
1988         RegByte(m_dst);
1989         CLKM(ALU_RR8,ALU_RM8);
1990         break;
1991
1992      case 0x03: // i_add_r16w
1993         DEF_r16w();
1994         ADDX();
1995         RegWord(m_dst);
1996         CLKM(ALU_RR16,ALU_RM16);
1997         break;
1998
1999      case 0x04: // i_add_ald8
2000         DEF_ald8();
2001         ADDB();
2002         m_regs.b[AL] = m_dst;
2003         CLK(ALU_RI8);
2004         break;
2005
2006      case 0x05: // i_add_axd16
2007         DEF_axd16();
2008         ADDX();
2009         m_regs.w[AX] = m_dst;
2010         CLK(ALU_RI16);
2011         break;
2012
2013      case 0x06: // i_push_es
2014         PUSH(m_sregs[ES]);
2015         CLK(PUSH_SEG);
2016         break;
2017
2018      case 0x07: // i_pop_es
2019         m_sregs[ES] = POP();
2020         CLK(POP_SEG);
2021         break;
2022
2023      case 0x08: // i_or_br8
2024         DEF_br8();
2025         ORB();
2026         PutbackRMByte(m_dst);
2027         CLKM(ALU_RR8,ALU_MR8);
2028         break;
2029
2030      case 0x09: // i_or_wr16
2031         DEF_wr16();
2032         ORW();
2033         PutbackRMWord(m_dst);
2034         CLKM(ALU_RR16,ALU_MR16);
2035         break;
2036
2037      case 0x0a: // i_or_r8b
2038         DEF_r8b();
2039         ORB();
2040         RegByte(m_dst);
2041         CLKM(ALU_RR8,ALU_RM8);
2042         break;
2043
2044      case 0x0b: // i_or_r16w
2045         DEF_r16w();
2046         ORW();
2047         RegWord(m_dst);
2048         CLKM(ALU_RR16,ALU_RM16);
2049         break;
2050
2051      case 0x0c: // i_or_ald8
2052         DEF_ald8();
2053         ORB();
2054         m_regs.b[AL] = m_dst;
2055         CLK(ALU_RI8);
2056         break;
2057
2058      case 0x0d: // i_or_axd16
2059         DEF_axd16();
2060         ORW();
2061         m_regs.w[AX] = m_dst;
2062         CLK(ALU_RI16);
2063         break;
2064
2065      case 0x0e: // i_push_cs
2066         PUSH(m_sregs[CS]);
2067         CLK(PUSH_SEG);
2068         break;
2069
2070      case 0x10: // i_adc_br8
2071         DEF_br8();
2072         m_src += CF ? 1 : 0;
2073         ADDB();
2074         PutbackRMByte(m_dst);
2075         CLKM(ALU_RR8,ALU_MR8);
2076         break;
2077
2078      case 0x11: // i_adc_wr16
2079         DEF_wr16();
2080         m_src += CF ? 1 : 0;
2081         ADDX();
2082         PutbackRMWord(m_dst);
2083         CLKM(ALU_RR16,ALU_MR16);
2084         break;
2085
2086      case 0x12: // i_adc_r8b
2087         DEF_r8b();
2088         m_src += CF ? 1 : 0;
2089         ADDB();
2090         RegByte(m_dst);
2091         CLKM(ALU_RR8,ALU_RM8);
2092         break;
2093
2094      case 0x13: // i_adc_r16w
2095         DEF_r16w();
2096         m_src += CF ? 1 : 0;
2097         ADDX();
2098         RegWord(m_dst);
2099         CLKM(ALU_RR16,ALU_RM16);
2100         break;
2101
2102      case 0x14: // i_adc_ald8
2103         DEF_ald8();
2104         m_src += CF ? 1 : 0;
2105         ADDB();
2106         m_regs.b[AL] = m_dst;
2107         CLK(ALU_RI8);
2108         break;
2109
2110      case 0x15: // i_adc_axd16
2111         DEF_axd16();
2112         m_src += CF ? 1 : 0;
2113         ADDX();
2114         m_regs.w[AX] = m_dst;
2115         CLK(ALU_RI16);
2116         break;
2117
2118      case 0x16: // i_push_ss
2119         PUSH(m_sregs[SS]);
2120         CLK(PUSH_SEG);
2121         break;
2122
2123      case 0x17: // i_pop_ss
2124         m_sregs[SS] = POP();
2125         CLK(POP_SEG);
2126         m_no_interrupt = 1;
2127         break;
2128
2129      case 0x18: // i_sbb_br8
2130         DEF_br8();
2131         m_src += CF ? 1 : 0;
2132         SUBB();
2133         PutbackRMByte(m_dst);
2134         CLKM(ALU_RR8,ALU_MR8);
2135         break;
2136
2137      case 0x19: // i_sbb_wr16
2138         DEF_wr16();
2139         m_src += CF ? 1 : 0;
2140         SUBX();
2141         PutbackRMWord(m_dst);
2142         CLKM(ALU_RR16,ALU_MR16);
2143         break;
2144
2145      case 0x1a: // i_sbb_r8b
2146         DEF_r8b();
2147         m_src += CF ? 1 : 0;
2148         SUBB();
2149         RegByte(m_dst);
2150         CLKM(ALU_RR8,ALU_RM8);
2151         break;
2152
2153      case 0x1b: // i_sbb_r16w
2154         DEF_r16w();
2155         m_src += CF ? 1 : 0;
2156         SUBX();
2157         RegWord(m_dst);
2158         CLKM(ALU_RR16,ALU_RM16);
2159         break;
2160
2161      case 0x1c: // i_sbb_ald8
2162         DEF_ald8();
2163         m_src += CF ? 1 : 0;
2164         SUBB();
2165         m_regs.b[AL] = m_dst;
2166         CLK(ALU_RI8);
2167         break;
2168
2169      case 0x1d: // i_sbb_axd16
2170         DEF_axd16();
2171         m_src += CF ? 1 : 0;
2172         SUBX();
2173         m_regs.w[AX] = m_dst;
2174         CLK(ALU_RI16);
2175         break;
2176
2177      case 0x1e: // i_push_ds
2178         PUSH(m_sregs[DS]);
2179         CLK(PUSH_SEG);
2180         break;
2181
2182      case 0x1f: // i_pop_ds
2183         m_sregs[DS] = POP();
2184         CLK(POP_SEG);
2185         break;
2186
2187
2188      case 0x20: // i_and_br8
2189         DEF_br8();
2190         ANDB();
2191         PutbackRMByte(m_dst);
2192         CLKM(ALU_RR8,ALU_MR8);
2193         break;
2194
2195      case 0x21: // i_and_wr16
2196         DEF_wr16();
2197         ANDX();
2198         PutbackRMWord(m_dst);
2199         CLKM(ALU_RR16,ALU_MR16);
2200         break;
2201
2202      case 0x22: // i_and_r8b
2203         DEF_r8b();
2204         ANDB();
2205         RegByte(m_dst);
2206         CLKM(ALU_RR8,ALU_RM8);
2207         break;
2208
2209      case 0x23: // i_and_r16w
2210         DEF_r16w();
2211         ANDX();
2212         RegWord(m_dst);
2213         CLKM(ALU_RR16,ALU_RM16);
2214         break;
2215
2216      case 0x24: // i_and_ald8
2217         DEF_ald8();
2218         ANDB();
2219         m_regs.b[AL] = m_dst;
2220         CLK(ALU_RI8);
2221         break;
2222
2223      case 0x25: // i_and_axd16
2224         DEF_axd16();
2225         ANDX();
2226         m_regs.w[AX] = m_dst;
2227         CLK(ALU_RI16);
2228         break;
2229
2230      case 0x26: // i_es
2231         m_seg_prefix_next = true;
2232         m_prefix_base = m_sregs[ES]<<4;
2233         CLK(OVERRIDE);
2234         break;
2235
2236      case 0x27: // i_daa
2237         ADJ4(6,0x60);
2238         CLK(DAA);
2239         break;
2240
2241
2242      case 0x28: // i_sub_br8
2243         DEF_br8();
2244         SUBB();
2245         PutbackRMByte(m_dst);
2246         CLKM(ALU_RR8,ALU_MR8);
2247         break;
2248
2249      case 0x29: // i_sub_wr16
2250         DEF_wr16();
2251         SUBX();
2252         PutbackRMWord(m_dst);
2253         CLKM(ALU_RR16,ALU_MR16);
2254         break;
2255
2256      case 0x2a: // i_sub_r8b
2257         DEF_r8b();
2258         SUBB();
2259         RegByte(m_dst);
2260         CLKM(ALU_RR8,ALU_RM8);
2261         break;
2262
2263      case 0x2b: // i_sub_r16w
2264         DEF_r16w();
2265         SUBX();
2266         RegWord(m_dst);
2267         CLKM(ALU_RR16,ALU_RM16);
2268         break;
2269
2270      case 0x2c: // i_sub_ald8
2271         DEF_ald8();
2272         SUBB();
2273         m_regs.b[AL] = m_dst;
2274         CLK(ALU_RI8);
2275         break;
2276
2277      case 0x2d: // i_sub_axd16
2278         DEF_axd16();
2279         SUBX();
2280         m_regs.w[AX] = m_dst;
2281         CLK(ALU_RI16);
2282         break;
2283
2284      case 0x2e: // i_cs
2285         m_seg_prefix_next = true;
2286         m_prefix_base = m_sregs[CS]<<4;
2287         CLK(OVERRIDE);
2288         break;
2289
2290      case 0x2f: // i_das
2291         ADJ4(-6,-0x60);
2292         CLK(DAS);
2293         break;
2294
2295
2296      case 0x30: // i_xor_br8
2297         DEF_br8();
2298         XORB();
2299         PutbackRMByte(m_dst);
2300         CLKM(ALU_RR8,ALU_MR8);
2301         break;
2302
2303      case 0x31: // i_xor_wr16
2304         DEF_wr16();
2305         XORW();
2306         PutbackRMWord(m_dst);
2307         CLKM(ALU_RR16,ALU_RM16);
2308         break;
2309
2310      case 0x32: // i_xor_r8b
2311         DEF_r8b();
2312         XORB();
2313         RegByte(m_dst);
2314         CLKM(ALU_RR8,ALU_RM8);
2315         break;
2316
2317      case 0x33: // i_xor_r16w
2318         DEF_r16w();
2319         XORW();
2320         RegWord(m_dst);
2321         CLKM(ALU_RR16,ALU_RM16);
2322         break;
2323
2324      case 0x34: // i_xor_ald8
2325         DEF_ald8();
2326         XORB();
2327         m_regs.b[AL] = m_dst;
2328         CLK(ALU_RI8);
2329         break;
2330
2331      case 0x35: // i_xor_axd16
2332         DEF_axd16();
2333         XORW();
2334         m_regs.w[AX] = m_dst;
2335         CLK(ALU_RI16);
2336         break;
2337
2338      case 0x36: // i_ss
2339         m_seg_prefix_next = true;
2340         m_prefix_base = m_sregs[SS]<<4;
2341         CLK(OVERRIDE);
2342         break;
2343
2344      case 0x37: // i_aaa
2345         ADJB(6, (m_regs.b[AL] > 0xf9) ? 2 : 1);
2346         CLK(AAA);
2347         break;
2348
2349
2350      case 0x38: // i_cmp_br8
2351         DEF_br8();
2352         SUBB();
2353         CLKM(ALU_RR8,ALU_RM8);
2354         break;
2355
2356      case 0x39: // i_cmp_wr16
2357         DEF_wr16();
2358         SUBX();
2359         CLKM(ALU_RR16,ALU_RM16);
2360         break;
2361
2362      case 0x3a: // i_cmp_r8b
2363         DEF_r8b();
2364         SUBB();
2365         CLKM(ALU_RR8,ALU_RM8);
2366         break;
2367
2368      case 0x3b: // i_cmp_r16w
2369         DEF_r16w();
2370         SUBX();
2371         CLKM(ALU_RR16,ALU_RM16);
2372         break;
2373
2374      case 0x3c: // i_cmp_ald8
2375         DEF_ald8();
2376         SUBB();
2377         CLK(ALU_RI8);
2378         break;
2379
2380      case 0x3d: // i_cmp_axd16
2381         DEF_axd16();
2382         SUBX();
2383         CLK(ALU_RI16);
2384         break;
2385
2386      case 0x3e: // i_ds
2387         m_seg_prefix_next = true;
2388         m_prefix_base = m_sregs[DS]<<4;
2389         CLK(OVERRIDE);
2390         break;
2391
2392      case 0x3f: // i_aas
2393         ADJB(-6, (m_regs.b[AL] < 6) ? -2 : -1);
2394         CLK(AAS);
2395         break;
2396
2397
2398      case 0x40: // i_inc_ax
2399         IncWordReg(AX);
2400         CLK(INCDEC_R16);
2401         break;
2402
2403      case 0x41: // i_inc_cx
2404         IncWordReg(CX);
2405         CLK(INCDEC_R16);
2406         break;
2407
2408      case 0x42: // i_inc_dx
2409         IncWordReg(DX);
2410         CLK(INCDEC_R16);
2411         break;
2412
2413      case 0x43: // i_inc_bx
2414         IncWordReg(BX);
2415         CLK(INCDEC_R16);
2416         break;
2417
2418      case 0x44: // i_inc_sp
2419         IncWordReg(SP);
2420         CLK(INCDEC_R16);
2421         break;
2422
2423      case 0x45: // i_inc_bp
2424         IncWordReg(BP);
2425         CLK(INCDEC_R16);
2426         break;
2427
2428      case 0x46: // i_inc_si
2429         IncWordReg(SI);
2430         CLK(INCDEC_R16);
2431         break;
2432
2433      case 0x47: // i_inc_di
2434         IncWordReg(DI);
2435         CLK(INCDEC_R16);
2436         break;
2437
2438
2439      case 0x48: // i_dec_ax
2440         DecWordReg(AX);
2441         CLK(INCDEC_R16);
2442         break;
2443
2444      case 0x49: // i_dec_cx
2445         DecWordReg(CX);
2446         CLK(INCDEC_R16);
2447         break;
2448
2449      case 0x4a: // i_dec_dx
2450         DecWordReg(DX);
2451         CLK(INCDEC_R16);
2452         break;
2453
2454      case 0x4b: // i_dec_bx
2455         DecWordReg(BX);
2456         CLK(INCDEC_R16);
2457         break;
2458
2459      case 0x4c: // i_dec_sp
2460         DecWordReg(SP);
2461         CLK(INCDEC_R16);
2462         break;
2463
2464      case 0x4d: // i_dec_bp
2465         DecWordReg(BP);
2466         CLK(INCDEC_R16);
2467         break;
2468
2469      case 0x4e: // i_dec_si
2470         DecWordReg(SI);
2471         CLK(INCDEC_R16);
2472         break;
2473
2474      case 0x4f: // i_dec_di
2475         DecWordReg(DI);
2476         CLK(INCDEC_R16);
2477         break;
2478
2479
2480      case 0x50: // i_push_ax
2481         PUSH(m_regs.w[AX]);
2482         CLK(PUSH_R16);
2483         break;
2484
2485      case 0x51: // i_push_cx
2486         PUSH(m_regs.w[CX]);
2487         CLK(PUSH_R16);
2488         break;
2489
2490      case 0x52: // i_push_dx
2491         PUSH(m_regs.w[DX]);
2492         CLK(PUSH_R16);
2493         break;
2494
2495      case 0x53: // i_push_bx
2496         PUSH(m_regs.w[BX]);
2497         CLK(PUSH_R16);
2498         break;
2499
2500      case 0x54: // i_push_sp
2501         PUSH(m_regs.w[SP]-2);
2502         CLK(PUSH_R16);
2503         break;
2504
2505      case 0x55: // i_push_bp
2506         PUSH(m_regs.w[BP]);
2507         CLK(PUSH_R16);
2508         break;
2509
2510      case 0x56: // i_push_si
2511         PUSH(m_regs.w[SI]);
2512         CLK(PUSH_R16);
2513         break;
2514
2515      case 0x57: // i_push_di
2516         PUSH(m_regs.w[DI]);
2517         CLK(PUSH_R16);
2518         break;
2519
2520
2521      case 0x58: // i_pop_ax
2522         m_regs.w[AX] = POP();
2523         CLK(POP_R16);
2524         break;
2525
2526      case 0x59: // i_pop_cx
2527         m_regs.w[CX] = POP();
2528         CLK(POP_R16);
2529         break;
2530
2531      case 0x5a: // i_pop_dx
2532         m_regs.w[DX] = POP();
2533         CLK(POP_R16);
2534         break;
2535
2536      case 0x5b: // i_pop_bx
2537         m_regs.w[BX] = POP();
2538         CLK(POP_R16);
2539         break;
2540
2541      case 0x5c: // i_pop_sp
2542         m_regs.w[SP] = POP();
2543         CLK(POP_R16);
2544         break;
2545
2546      case 0x5d: // i_pop_bp
2547         m_regs.w[BP] = POP();
2548         CLK(POP_R16);
2549         break;
2550
2551      case 0x5e: // i_pop_si
2552         m_regs.w[SI] = POP();
2553         CLK(POP_R16);
2554         break;
2555
2556      case 0x5f: // i_pop_di
2557         m_regs.w[DI] = POP();
2558         CLK(POP_R16);
2559         break;
2560
2561
2562      case 0x70: // i_jo
2563         JMP( OF);
2564         break;
2565
2566      case 0x71: // i_jno
2567         JMP(!OF);
2568         break;
2569
2570      case 0x72: // i_jc
2571         JMP( CF);
2572         break;
2573
2574      case 0x73: // i_jnc
2575         JMP(!CF);
2576         break;
2577
2578      case 0x74: // i_jz
2579         JMP( ZF);
2580         break;
2581
2582      case 0x75: // i_jnz
2583         JMP(!ZF);
2584         break;
2585
2586      case 0x76: // i_jce
2587         JMP(CF || ZF);
2588         break;
2589
2590      case 0x77: // i_jnce
2591         JMP(!(CF || ZF));
2592         break;
2593
2594      case 0x78: // i_js
2595         JMP( SF);
2596         break;
2597
2598      case 0x79: // i_jns
2599         JMP(!SF);
2600         break;
2601
2602      case 0x7a: // i_jp
2603         JMP( PF);
2604         break;
2605
2606      case 0x7b: // i_jnp
2607         JMP(!PF);
2608         break;
2609
2610      case 0x7c: // i_jl
2611         JMP((SF!=OF)&&(!ZF));
2612         break;
2613
2614      case 0x7d: // i_jnl
2615         JMP((ZF)||(SF==OF));
2616         break;
2617
2618      case 0x7e: // i_jle
2619         JMP((ZF)||(SF!=OF));
2620         break;
2621
2622      case 0x7f: // i_jnle
2623         JMP((SF==OF)&&(!ZF));
2624         break;
2625
2626
2627      case 0x80: // i_80pre
2628         m_modrm = fetch();
2629         m_dst = GetRMByte();
2630         m_src = fetch();
2631         if (m_modrm >=0xc0 )             { CLK(ALU_RI8); }
2632         else if ((m_modrm & 0x38)==0x38) { CLK(ALU_MI8_RO); }
2633         else                             { CLK(ALU_MI8); }
2634         switch (m_modrm & 0x38)
4092635         {
410            cpustate->base[CS] = cpustate->pc & 0xffff0;
411            cpustate->sregs[CS] = cpustate->base[CS] >> 4;
2636         case 0x00:                      ADDB(); PutbackRMByte(m_dst);   break;
2637         case 0x08:                      ORB();  PutbackRMByte(m_dst);   break;
2638         case 0x10: m_src += CF ? 1 : 0; ADDB(); PutbackRMByte(m_dst);   break;
2639         case 0x18: m_src += CF ? 1 : 0; SUBB(); PutbackRMByte(m_dst);   break;
2640         case 0x20:                      ANDB(); PutbackRMByte(m_dst);   break;
2641         case 0x28:                      SUBB(); PutbackRMByte(m_dst);   break;
2642         case 0x30:                      XORB(); PutbackRMByte(m_dst);   break;
2643         case 0x38:                      SUBB();                         break;  /* CMP */
4122644         }
4132645         break;
4142646
415      case I8086_IP:
416         cpustate->pc = cpustate->base[CS] + cpustate->ip;
2647
2648      case 0x81: // i_81pre
2649         m_modrm = fetch();
2650         m_dst = GetRMWord();
2651         m_src = fetch_word();
2652         if (m_modrm >=0xc0 )             { CLK(ALU_RI16); }
2653         else if ((m_modrm & 0x38)==0x38) { CLK(ALU_MI16_RO); }
2654         else                             { CLK(ALU_MI16); }
2655         switch (m_modrm & 0x38)
2656         {
2657         case 0x00:                      ADDX(); PutbackRMWord(m_dst);   break;
2658         case 0x08:                      ORW();  PutbackRMWord(m_dst);   break;
2659         case 0x10: m_src += CF ? 1 : 0; ADDX(); PutbackRMWord(m_dst);   break;
2660         case 0x18: m_src += CF ? 1 : 0; SUBX(); PutbackRMWord(m_dst);   break;
2661         case 0x20:                      ANDX(); PutbackRMWord(m_dst);   break;
2662         case 0x28:                      SUBX(); PutbackRMWord(m_dst);   break;
2663         case 0x30:                      XORW(); PutbackRMWord(m_dst);   break;
2664         case 0x38:                      SUBX();                         break;  /* CMP */
2665         }
4172666         break;
4182667
419      case I8086_GENSP:
420         if (cpustate->sp - cpustate->base[SS] >= 0x10000)
2668
2669      case 0x82: // i_82pre
2670         m_modrm = fetch();
2671         m_dst = GetRMByte();
2672         m_src = (INT8)fetch();
2673         if (m_modrm >=0xc0 )             { CLK(ALU_RI8); }
2674         else if ((m_modrm & 0x38)==0x38) { CLK(ALU_MI8_RO); }
2675         else                             { CLK(ALU_MI8); }
2676         switch (m_modrm & 0x38)
4212677         {
422            cpustate->base[SS] = cpustate->sp & 0xffff0;
423            cpustate->sregs[SS] = cpustate->base[SS] >> 4;
2678         case 0x00:                      ADDB(); PutbackRMByte(m_dst);   break;
2679         case 0x08:                      ORB();  PutbackRMByte(m_dst);   break;
2680         case 0x10: m_src += CF ? 1 : 0; ADDB(); PutbackRMByte(m_dst);   break;
2681         case 0x18: m_src += CF ? 1 : 0; SUBB(); PutbackRMByte(m_dst);   break;
2682         case 0x20:                      ANDB(); PutbackRMByte(m_dst);   break;
2683         case 0x28:                      SUBB(); PutbackRMByte(m_dst);   break;
2684         case 0x30:                      XORB(); PutbackRMByte(m_dst);   break;
2685         case 0x38:                      SUBB();                         break; /* CMP */
4242686         }
425         cpustate->regs.w[SP] = cpustate->sp - cpustate->base[SS];
4262687         break;
4272688
428      case I8086_FLAGS:
429      case STATE_GENFLAGS:
430         ExpandFlags(cpustate->flags);
2689
2690      case 0x83: // i_83pre
2691         m_modrm = fetch();
2692         m_dst = GetRMWord();
2693         m_src = (UINT16)((INT16)((INT8)fetch()));
2694         if (m_modrm >=0xc0 )             { CLK(ALU_R16I8); }
2695         else if ((m_modrm & 0x38)==0x38) { CLK(ALU_M16I8_RO); }
2696         else                             { CLK(ALU_M16I8); }
2697         switch (m_modrm & 0x38)
2698         {
2699         case 0x00:                      ADDX(); PutbackRMWord(m_dst); break;
2700         case 0x08:                      ORW();  PutbackRMWord(m_dst); break;
2701         case 0x10: m_src += CF ? 1 : 0; ADDX(); PutbackRMWord(m_dst); break;
2702         case 0x18: m_src += CF ? 1 : 0; SUBX(); PutbackRMWord(m_dst); break;
2703         case 0x20:                      ANDX(); PutbackRMWord(m_dst); break;
2704         case 0x28:                      SUBX(); PutbackRMWord(m_dst); break;
2705         case 0x30:                      XORW(); PutbackRMWord(m_dst); break;
2706         case 0x38:                      SUBX();                       break; /* CMP */
2707         }
4312708         break;
4322709
433      case I8086_ES:
434         cpustate->base[ES] = SegBase(ES);
2710
2711      case 0x84: // i_test_br8
2712         DEF_br8();
2713         ANDB();
2714         CLKM(ALU_RR8,ALU_RM8);
4352715         break;
4362716
437      case I8086_CS:
438         cpustate->base[CS] = SegBase(CS);
2717      case 0x85: // i_test_wr16
2718         DEF_wr16();
2719         ANDX();
2720         CLKM(ALU_RR16,ALU_RM16);
4392721         break;
4402722
441      case I8086_SS:
442         cpustate->base[SS] = SegBase(SS);
2723      case 0x86: // i_xchg_br8
2724         DEF_br8();
2725         RegByte(m_dst);
2726         PutbackRMByte(m_src);
2727         CLKM(XCHG_RR8,XCHG_RM8);
4432728         break;
4442729
445      case I8086_DS:
446         cpustate->base[DS] = SegBase(DS);
2730      case 0x87: // i_xchg_wr16
2731         DEF_wr16();
2732         RegWord(m_dst);
2733         PutbackRMWord(m_src);
2734         CLKM(XCHG_RR16,XCHG_RM16);
4472735         break;
4482736
449      default:
450         fatalerror("CPU_IMPORT_STATE(i8086) called for unexpected value\n");
2737
2738      case 0x88: // i_mov_br8
2739         m_modrm = fetch();
2740         m_src = RegByte();
2741         PutRMByte(m_src);
2742         CLKM(ALU_RR8,ALU_MR8);
4512743         break;
452   }
453}
4542744
2745      case 0x89: // i_mov_wr16
2746         m_modrm = fetch();
2747         m_src = RegWord();
2748         PutRMWord(m_src);
2749         CLKM(ALU_RR16,ALU_MR16);
2750         break;
4552751
456static CPU_EXPORT_STATE( i8086 )
457{
458   i8086_state *cpustate = get_safe_token(device);
2752      case 0x8a: // i_mov_r8b
2753         m_modrm = fetch();
2754         m_src = GetRMByte();
2755         RegByte(m_src);
2756         CLKM(ALU_RR8,ALU_RM8);
2757         break;
4592758
460   switch (entry.index())
461   {
462      case I8086_IP:
463         cpustate->ip = cpustate->pc - cpustate->base[CS];
2759      case 0x8b: // i_mov_r16w
2760         m_modrm = fetch();
2761         m_src = GetRMWord();
2762         RegWord(m_src);
2763         CLKM(ALU_RR16,ALU_RM16);
4642764         break;
4652765
466      case I8086_FLAGS:
467      case STATE_GENFLAGS:
468         cpustate->flags = CompressFlags();
2766      case 0x8c: // i_mov_wsreg
2767         m_modrm = fetch();
2768         PutRMWord(m_sregs[(m_modrm & 0x38) >> 3]);
2769         CLKM(MOV_RS,MOV_MS);
4692770         break;
4702771
471      case I8086_GENSP:
472         cpustate->sp = cpustate->base[SS] + cpustate->regs.w[SP];
2772      case 0x8d: // i_lea
2773         m_modrm = fetch();
2774         get_ea();
2775         RegWord(m_eo);
2776         CLK(LEA);
4732777         break;
4742778
475      default:
476         fatalerror("CPU_EXPORT_STATE(i8086) called for unexpected value\n");
2779      case 0x8e: // i_mov_sregw
2780         m_modrm = fetch();
2781         m_src = GetRMWord();
2782         CLKM(MOV_SR,MOV_SM);
2783         switch (m_modrm & 0x38)
2784         {
2785         case 0x00:  /* mov es,ew */
2786            m_sregs[ES] = m_src;
2787            break;
2788         case 0x08:  /* mov cs,ew */
2789            m_sregs[CS] = m_src;
2790            break;
2791         case 0x10:  /* mov ss,ew */
2792            m_sregs[SS] = m_src;
2793            m_no_interrupt = 1;
2794            break;
2795         case 0x18:  /* mov ds,ew */
2796            m_sregs[DS] = m_src;
2797            break;
2798         default:
2799            logerror("%s: %06x: Mov Sreg - Invalid register\n", tag(), pc());
2800         }
4772801         break;
478   }
479}
4802802
2803      case 0x8f: // i_popw
2804         m_modrm = fetch();
2805         PutRMWord( POP() );
2806         CLKM(POP_R16,POP_M16);
2807         break;
4812808
482static CPU_EXPORT_STRING( i8086 )
483{
484   i8086_state *cpustate = get_safe_token(device);
2809      case 0x90: // i_nop
2810         CLK(NOP);
2811         break;
4852812
486   switch (entry.index())
487   {
488      case I8086_GENPC:
489         string.printf("%04X:%04X", cpustate->sregs[CS] & 0xffff, (cpustate->pc - cpustate->base[CS]) & 0xffff);
2813      case 0x91: // i_xchg_axcx
2814         XchgAXReg(CX);
2815         CLK(XCHG_AR16);
4902816         break;
4912817
492      case I8086_GENSP:
493         string.printf("%04X:%04X", cpustate->sregs[SS] & 0xffff, cpustate->regs.w[SP] & 0xffff);
2818      case 0x92: // i_xchg_axdx
2819         XchgAXReg(DX);
2820         CLK(XCHG_AR16);
4942821         break;
4952822
496      case STATE_GENFLAGS:
497         cpustate->flags = CompressFlags();
498         string.printf("%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c",
499               cpustate->flags & 0x8000 ? '1' : '.',
500               cpustate->flags & 0x4000 ? '1' : '.',
501               cpustate->flags & 0x2000 ? '1' : '.',
502               cpustate->flags & 0x1000 ? '1' : '.',
503               cpustate->flags & 0x0800 ? 'O' : '.',
504               cpustate->flags & 0x0400 ? 'D' : '.',
505               cpustate->flags & 0x0200 ? 'I' : '.',
506               cpustate->flags & 0x0100 ? 'T' : '.',
507               cpustate->flags & 0x0080 ? 'S' : '.',
508               cpustate->flags & 0x0040 ? 'Z' : '.',
509               cpustate->flags & 0x0020 ? '0' : '.',
510               cpustate->flags & 0x0010 ? 'A' : '.',
511               cpustate->flags & 0x0008 ? '0' : '.',
512               cpustate->flags & 0x0004 ? 'P' : '.',
513               cpustate->flags & 0x0002 ? '1' : '.',
514               cpustate->flags & 0x0001 ? 'C' : '.');
2823      case 0x93: // i_xchg_axbx
2824         XchgAXReg(BX);
2825         CLK(XCHG_AR16);
5152826         break;
5162827
517      default:
518         fatalerror("CPU_EXPORT_STRING(i8086) called for unexpected value\n");
2828      case 0x94: // i_xchg_axsp
2829         XchgAXReg(SP);
2830         CLK(XCHG_AR16);
5192831         break;
520   }
521}
5222832
2833      case 0x95: // i_xchg_axbp
2834         XchgAXReg(BP);
2835         CLK(XCHG_AR16);
2836         break;
5232837
524/**************************************************************************
525 * Generic set_info
526 **************************************************************************/
2838      case 0x96: // i_xchg_axsi
2839         XchgAXReg(SI);
2840         CLK(XCHG_AR16);
2841         break;
5272842
528static CPU_SET_INFO( i8086 )
529{
530   i8086_state *cpustate = get_safe_token(device);
2843      case 0x97: // i_xchg_axdi
2844         XchgAXReg(DI);
2845         CLK(XCHG_AR16);
2846         break;
5312847
532   switch (state)
533   {
534      /* --- the following bits of info are set as 64-bit signed integers --- */
535      case CPUINFO_INT_INPUT_STATE + 0:               set_irq_line(cpustate, 0, info->i);                 break;
536      case CPUINFO_INT_INPUT_STATE + INPUT_LINE_NMI:  set_irq_line(cpustate, INPUT_LINE_NMI, info->i);    break;
537      case CPUINFO_INT_INPUT_STATE + INPUT_LINE_TEST: set_test_line(cpustate, info->i);                   break; /* PJB 03/05 */
538   }
539}
5402848
2849      case 0x98: // i_cbw
2850         m_regs.b[AH] = (m_regs.b[AL] & 0x80) ? 0xff : 0;
2851         CLK(CBW);
2852         break;
5412853
2854      case 0x99: // i_cwd
2855         m_regs.w[DX] = (m_regs.b[AH] & 0x80) ? 0xffff : 0;
2856         CLK(CWD);
2857         break;
5422858
543/**************************************************************************
544 * Generic get_info
545 **************************************************************************/
2859      case 0x9a: // i_call_far
2860         {
2861            UINT16 tmp = fetch_word();
2862            UINT16 tmp2 = fetch_word();
2863            PUSH(m_sregs[CS]);
2864            PUSH(m_ip);
2865            m_ip = tmp;
2866            m_sregs[CS] = tmp2;
2867            CLK(CALL_FAR);
2868         }
2869         break;
5462870
547CPU_GET_INFO( i8086 )
548{
549   i8086_state *cpustate = (device != NULL && device->token() != NULL) ? get_safe_token(device) : NULL;
2871      case 0x9b: // i_wait
2872         if(m_test_state)
2873         {
2874            m_icount = 0;
2875            m_pc--;
2876         }
2877         else
2878            CLK(WAIT);
2879         break;
5502880
551   switch (state)
552   {
553      /* --- the following bits of info are returned as 64-bit signed integers --- */
554      case CPUINFO_INT_CONTEXT_SIZE:                  info->i = sizeof(i8086_state);          break;
555      case CPUINFO_INT_INPUT_LINES:                   info->i = 1;                            break;
556      case CPUINFO_INT_DEFAULT_IRQ_VECTOR:            info->i = 0xff;                         break;
557      case CPUINFO_INT_ENDIANNESS:                    info->i = ENDIANNESS_LITTLE;                    break;
558      case CPUINFO_INT_CLOCK_MULTIPLIER:              info->i = 1;                            break;
559      case CPUINFO_INT_CLOCK_DIVIDER:                 info->i = 1;                            break;
560      case CPUINFO_INT_MIN_INSTRUCTION_BYTES:         info->i = 1;                            break;
561      case CPUINFO_INT_MAX_INSTRUCTION_BYTES:         info->i = 8;                            break;
562      case CPUINFO_INT_MIN_CYCLES:                    info->i = 1;                            break;
563      case CPUINFO_INT_MAX_CYCLES:                    info->i = 50;                           break;
2881      case 0x9c: // i_pushf
2882         PUSH( CompressFlags() );
2883         CLK(PUSHF);
2884         break;
5642885
565      case CPUINFO_INT_DATABUS_WIDTH + AS_PROGRAM:    info->i = 16;                   break;
566      case CPUINFO_INT_ADDRBUS_WIDTH + AS_PROGRAM: info->i = 20;                  break;
567      case CPUINFO_INT_ADDRBUS_SHIFT + AS_PROGRAM: info->i = 0;                   break;
568      case CPUINFO_INT_DATABUS_WIDTH + AS_DATA:   info->i = 0;                    break;
569      case CPUINFO_INT_ADDRBUS_WIDTH + AS_DATA:   info->i = 0;                    break;
570      case CPUINFO_INT_ADDRBUS_SHIFT + AS_DATA:   info->i = 0;                    break;
571      case CPUINFO_INT_DATABUS_WIDTH + AS_IO:     info->i = 16;                   break;
572      case CPUINFO_INT_ADDRBUS_WIDTH + AS_IO:     info->i = 16;                   break;
573      case CPUINFO_INT_ADDRBUS_SHIFT + AS_IO:     info->i = 0;                    break;
2886      case 0x9d: // i_popf
2887         i_popf();
2888         break;
5742889
575      case CPUINFO_INT_INPUT_STATE + 0:               info->i = cpustate->irq_state;                  break;
576      case CPUINFO_INT_INPUT_STATE + INPUT_LINE_NMI:  info->i = cpustate->nmi_state;                  break;
2890      case 0x9e: // i_sahf
2891         {
2892            UINT32 tmp = (CompressFlags() & 0xff00) | (m_regs.b[AH] & 0xd5);
2893            ExpandFlags(tmp);
2894            CLK(SAHF);
2895         }
2896         break;
5772897
578      case CPUINFO_INT_INPUT_STATE + INPUT_LINE_TEST: info->i = cpustate->test_state;                 break; /* PJB 03/05 */
2898      case 0x9f: // i_lahf
2899         m_regs.b[AH] = CompressFlags();
2900         CLK(LAHF);
2901         break;
5792902
580      case CPUINFO_INT_PREVIOUSPC:                    info->i = cpustate->prevpc;                     break;
5812903
582      /* --- the following bits of info are returned as pointers to data or functions --- */
583      case CPUINFO_FCT_SET_INFO:                      info->setinfo = CPU_SET_INFO_NAME(i8086);           break;
584      case CPUINFO_FCT_INIT:                          info->init = CPU_INIT_NAME(i8086);                  break;
585      case CPUINFO_FCT_RESET:                         info->reset = CPU_RESET_NAME(i8086);                break;
586      case CPUINFO_FCT_EXIT:                          info->exit = CPU_EXIT_NAME(i8086);                  break;
587      case CPUINFO_FCT_EXECUTE:                       info->execute = CPU_EXECUTE_NAME(i8086);            break;
588      case CPUINFO_FCT_BURN:                          info->burn = NULL;                                  break;
589      case CPUINFO_FCT_DISASSEMBLE:                   info->disassemble = CPU_DISASSEMBLE_NAME(i8086);    break;
590      case CPUINFO_PTR_INSTRUCTION_COUNTER:           info->icount = &cpustate->icount;                   break;
591      case CPUINFO_FCT_IMPORT_STATE:                  info->import_state = CPU_IMPORT_STATE_NAME(i8086);  break;
592      case CPUINFO_FCT_EXPORT_STATE:                  info->export_state = CPU_EXPORT_STATE_NAME(i8086);  break;
593      case CPUINFO_FCT_EXPORT_STRING:                 info->export_string = CPU_EXPORT_STRING_NAME(i8086);break;
2904      case 0xa0: // i_mov_aldisp
2905         {
2906            UINT32 addr = fetch_word();
2907            m_regs.b[AL] = GetMemB(DS, addr);
2908            CLK(MOV_AM8);
2909         }
2910         break;
5942911
595      /* --- the following bits of info are returned as NULL-terminated strings --- */
596      case CPUINFO_STR_NAME:                          strcpy(info->s, "8086");                break;
597      case CPUINFO_STR_FAMILY:                        strcpy(info->s, "Intel 80x86");         break;
598      case CPUINFO_STR_VERSION:                       strcpy(info->s, "1.4");                 break;
599      case CPUINFO_STR_SOURCE_FILE:                   strcpy(info->s, __FILE__);              break;
600      case CPUINFO_STR_CREDITS:                       strcpy(info->s, "Real mode i286 emulator v1.4 by Fabrice Frances\n(initial work cpustate->based on David Hedley's pcemu)"); break;
601   }
602}
2912      case 0xa1: // i_mov_axdisp
2913         {
2914            UINT32 addr = fetch_word();
2915            m_regs.b[AL] = GetMemB(DS, addr);
2916            m_regs.b[AH] = GetMemB(DS, addr+1);
2917            CLK(MOV_AM16);
2918         }
2919         break;
6032920
2921      case 0xa2: // i_mov_dispal
2922         {
2923            UINT32 addr = fetch_word();
2924            PutMemB(DS, addr, m_regs.b[AL]);
2925            CLK(MOV_MA8);
2926         }
2927         break;
6042928
605/**************************************************************************
606 * CPU-specific get_info/set_info
607 **************************************************************************/
2929      case 0xa3: // i_mov_dispax
2930         {
2931            UINT32 addr = fetch_word();
2932            PutMemB(DS, addr, m_regs.b[AL]);
2933            PutMemB(DS, addr+1, m_regs.b[AH]);
2934            CLK(MOV_MA16);
2935         }
2936         break;
6082937
609CPU_GET_INFO( i8088 )
610{
611   switch (state)
612   {
613      /* --- the following bits of info are returned as 64-bit signed integers --- */
614      case CPUINFO_INT_DATABUS_WIDTH + AS_PROGRAM:    info->i = 8;                    break;
615      case CPUINFO_INT_DATABUS_WIDTH + AS_IO:     info->i = 8;                    break;
2938      case 0xa4: // i_movsb
2939         i_movsb();
2940         break;
6162941
617      /* --- the following bits of info are returned as pointers to data or functions --- */
618      case CPUINFO_FCT_INIT:                          info->init = CPU_INIT_NAME(i8088);      break;
2942      case 0xa5: // i_movsw
2943         i_movsw();
2944         break;
6192945
620      /* --- the following bits of info are returned as NULL-terminated strings --- */
621      case CPUINFO_STR_NAME:                          strcpy(info->s, "8088");                break;
2946      case 0xa6: // i_cmpsb
2947         i_cmpsb();
2948         break;
6222949
623      default:                                        CPU_GET_INFO_CALL(i8086);               break;
624   }
625}
2950      case 0xa7: // i_cmpsw
2951         i_cmpsw();
2952         break;
6262953
6272954
628/**************************************************************************
629 * CPU-specific get_info/set_info
630 **************************************************************************/
2955      case 0xa8: // i_test_ald8
2956         DEF_ald8();
2957         ANDB();
2958         CLK(ALU_RI8);
2959         break;
6312960
632static CPU_SET_INFO( i80186 )
633{
634   i8086_state *cpustate = get_safe_token(device);
2961      case 0xa9: // i_test_axd16
2962         DEF_axd16();
2963         ANDX();
2964         CLK(ALU_RI16);
2965         break;
6352966
636   switch (state)
637   {
638      /* --- the following bits of info are set as 64-bit signed integers --- */
639      case CPUINFO_INT_INPUT_STATE + INPUT_LINE_INT0:     set_irq_line(cpustate, 0, info->i);                 break;
640      case CPUINFO_INT_INPUT_STATE + INPUT_LINE_INT1:     set_irq_line(cpustate, 1, info->i);                 break;
641      case CPUINFO_INT_INPUT_STATE + INPUT_LINE_INT2:     set_irq_line(cpustate, 2, info->i);                 break;
642      case CPUINFO_INT_INPUT_STATE + INPUT_LINE_INT3:     set_irq_line(cpustate, 3, info->i);                 break;
643      case CPUINFO_INT_INPUT_STATE + INPUT_LINE_DRQ0:     set_drq_line(cpustate, 0, info->i);                 break;
644      case CPUINFO_INT_INPUT_STATE + INPUT_LINE_DRQ1:     set_drq_line(cpustate, 1, info->i);                 break;
645      case CPUINFO_INT_INPUT_STATE + INPUT_LINE_TMRIN0:   set_tmrin_line(cpustate, 0, info->i);               break;
646      case CPUINFO_INT_INPUT_STATE + INPUT_LINE_TMRIN1:   set_tmrin_line(cpustate, 1, info->i);               break;
647      case CPUINFO_INT_INPUT_STATE + INPUT_LINE_NMI:      set_irq_line(cpustate, INPUT_LINE_NMI, info->i);    break;
648      case CPUINFO_INT_INPUT_STATE + INPUT_LINE_TEST:     set_test_line(cpustate, info->i);                   break; /* PJB 03/05 */
649   }
650}
2967      case 0xaa: // i_stosb
2968         i_stosb();
2969         break;
6512970
652CPU_GET_INFO( i80186 )
653{
654   switch (state)
655   {
656      /* --- the following bits of info are returned as 64-bit signed integers --- */
657      case CPUINFO_INT_CLOCK_MULTIPLIER:              info->i = 1;                                break;
658      case CPUINFO_INT_CLOCK_DIVIDER:                 info->i = 2;                                break;
2971      case 0xab: // i_stosw
2972         i_stosw();
2973         break;
6592974
660      /* --- the following bits of info are returned as pointers to data or functions --- */
661      case CPUINFO_FCT_SET_INFO:                      info->setinfo = CPU_SET_INFO_NAME(i80186);  break;
662      case CPUINFO_FCT_INIT:                          info->init = CPU_INIT_NAME(i80186);         break;
663      case CPUINFO_FCT_EXECUTE:                       info->execute = CPU_EXECUTE_NAME(i80186);   break;
2975      case 0xac: // i_lodsb
2976         i_lodsb();
2977         break;
6642978
665      /* --- the following bits of info are returned as NULL-terminated strings --- */
666      case CPUINFO_STR_NAME:                          strcpy(info->s, "80186");                   break;
2979      case 0xad: // i_lodsw
2980         i_lodsw();
2981         break;
6672982
668      default:                                        CPU_GET_INFO_CALL(i8086);                   break;
669   }
670}
2983      case 0xae: // i_scasb
2984         i_scasb();
2985         break;
6712986
2987      case 0xaf: // i_scasw
2988         i_scasw();
2989         break;
6722990
673/**************************************************************************
674 * CPU-specific get_info/set_info
675 **************************************************************************/
6762991
677CPU_GET_INFO( i80188 )
678{
679   switch (state)
680   {
681      /* --- the following bits of info are returned as 64-bit signed integers --- */
682      case CPUINFO_INT_DATABUS_WIDTH + AS_PROGRAM:    info->i = 8;                    break;
683      case CPUINFO_INT_DATABUS_WIDTH + AS_IO:     info->i = 8;                    break;
2992      case 0xb0: // i_mov_ald8
2993         m_regs.b[AL] = fetch();
2994         CLK(MOV_RI8);
2995         break;
6842996
685      /* --- the following bits of info are returned as pointers to data or functions --- */
686      case CPUINFO_FCT_INIT:                          info->init = CPU_INIT_NAME(i8088);      break;
687      case CPUINFO_FCT_EXECUTE:                       info->execute = CPU_EXECUTE_NAME(i80186);break;
2997      case 0xb1: // i_mov_cld8
2998         m_regs.b[CL] = fetch();
2999         CLK(MOV_RI8);
3000         break;
6883001
689      /* --- the following bits of info are returned as NULL-terminated strings --- */
690      case CPUINFO_STR_NAME:                          strcpy(info->s, "80188");               break;
3002      case 0xb2: // i_mov_dld8
3003         m_regs.b[DL] = fetch();
3004         CLK(MOV_RI8);
3005         break;
6913006
692      default:                                        CPU_GET_INFO_CALL(i8086);               break;
3007      case 0xb3: // i_mov_bld8
3008         m_regs.b[BL] = fetch();
3009         CLK(MOV_RI8);
3010         break;
3011
3012      case 0xb4: // i_mov_ahd8
3013         m_regs.b[AH] = fetch();
3014         CLK(MOV_RI8);
3015         break;
3016
3017      case 0xb5: // i_mov_chd8
3018         m_regs.b[CH] = fetch();
3019         CLK(MOV_RI8);
3020         break;
3021
3022      case 0xb6: // i_mov_dhd8
3023         m_regs.b[DH] = fetch();
3024         CLK(MOV_RI8);
3025         break;
3026
3027      case 0xb7: // i_mov_bhd8
3028         m_regs.b[BH] = fetch();
3029         CLK(MOV_RI8);
3030         break;
3031
3032
3033      case 0xb8: // i_mov_axd16
3034         m_regs.b[AL] = fetch();
3035         m_regs.b[AH] = fetch();
3036         CLK(MOV_RI16);
3037         break;
3038
3039      case 0xb9: // i_mov_cxd16
3040         m_regs.b[CL] = fetch();
3041         m_regs.b[CH] = fetch();
3042         CLK(MOV_RI16);
3043         break;
3044
3045      case 0xba: // i_mov_dxd16
3046         m_regs.b[DL] = fetch();
3047         m_regs.b[DH] = fetch();
3048         CLK(MOV_RI16);
3049         break;
3050
3051      case 0xbb: // i_mov_bxd16
3052         m_regs.b[BL] = fetch();
3053         m_regs.b[BH] = fetch();
3054         CLK(MOV_RI16);
3055         break;
3056
3057      case 0xbc: // i_mov_spd16
3058         m_regs.b[SPL] = fetch();
3059         m_regs.b[SPH] = fetch();
3060         CLK(MOV_RI16);
3061         break;
3062
3063      case 0xbd: // i_mov_bpd16
3064         m_regs.b[BPL] = fetch();
3065         m_regs.b[BPH] = fetch();
3066         CLK(MOV_RI16);
3067         break;
3068
3069      case 0xbe: // i_mov_sid16
3070         m_regs.b[SIL] = fetch();
3071         m_regs.b[SIH] = fetch();
3072         CLK(MOV_RI16);
3073         break;
3074
3075      case 0xbf: // i_mov_did16
3076         m_regs.b[DIL] = fetch();
3077         m_regs.b[DIH] = fetch();
3078         CLK(MOV_RI16);
3079         break;
3080
3081
3082      case 0xc2: // i_ret_d16
3083         {
3084            UINT32 count = fetch_word();
3085            m_ip = POP();
3086            m_regs.w[SP] += count;
3087            CLK(RET_NEAR_IMM);
3088         }
3089         break;
3090
3091      case 0xc3: // i_ret
3092         m_ip = POP();
3093         CLK(RET_NEAR);
3094         break;
3095
3096      case 0xc4: // i_les_dw
3097         m_modrm = fetch();
3098         RegWord( GetRMWord() );
3099         m_sregs[ES] = GetnextRMWord();
3100         CLK(LOAD_PTR);
3101         break;
3102
3103      case 0xc5: // i_lds_dw
3104         m_modrm = fetch();
3105         RegWord( GetRMWord() );
3106         m_sregs[DS] = GetnextRMWord();
3107         CLK(LOAD_PTR);
3108         break;
3109
3110      case 0xc6: // i_mov_bd8
3111         m_modrm = fetch();
3112         PutImmRMByte();
3113         CLKM(MOV_RI8,MOV_MI8);
3114         break;
3115
3116      case 0xc7: // i_mov_wd16
3117         m_modrm = fetch();
3118         PutImmRMWord();
3119         CLKM(MOV_RI16,MOV_MI16);
3120         break;
3121
3122
3123      case 0xca: // i_retf_d16
3124         {
3125            UINT32 count = fetch_word();
3126            m_ip = POP();
3127            m_sregs[CS] = POP();
3128            m_regs.w[SP] += count;
3129            CLK(RET_FAR_IMM);
3130         }
3131         break;
3132
3133      case 0xcb: // i_retf
3134         m_ip = POP();
3135         m_sregs[CS] = POP();
3136         CLK(RET_FAR);
3137         break;
3138
3139      case 0xcc: // i_int3
3140         interrupt(3);
3141         CLK(INT3);
3142         break;
3143
3144      case 0xcd: // i_int
3145         interrupt(fetch());
3146         CLK(INT_IMM);
3147         break;
3148
3149      case 0xce: // i_into
3150         if (OF)
3151         {
3152            interrupt(4);
3153            CLK(INTO_T);
3154         }
3155         else
3156            CLK(INTO_NT);
3157         break;
3158
3159      case 0xcf: // i_iret
3160         m_ip = POP();
3161         m_sregs[CS] = POP();
3162         i_popf();
3163         CLK(IRET);
3164         break;
3165
3166      case 0xd0: // i_rotshft_b
3167         m_modrm = fetch();
3168         m_src = GetRMByte();
3169         m_dst = m_src;
3170         CLKM(ROT_REG_1,ROT_M8_1);
3171         switch ( m_modrm & 0x38 )
3172         {
3173         case 0x00: ROL_BYTE();  PutbackRMByte(m_dst); m_OverVal = (m_src ^ m_dst) & 0x80; break;
3174         case 0x08: ROR_BYTE();  PutbackRMByte(m_dst); m_OverVal = (m_src ^ m_dst) & 0x80; break;
3175         case 0x10: ROLC_BYTE(); PutbackRMByte(m_dst); m_OverVal = (m_src ^ m_dst) & 0x80; break;
3176         case 0x18: RORC_BYTE(); PutbackRMByte(m_dst); m_OverVal = (m_src ^ m_dst) & 0x80; break;
3177         case 0x30:
3178         case 0x20: SHL_BYTE(1); m_OverVal = (m_src ^ m_dst) & 0x80; break;
3179         case 0x28: SHR_BYTE(1); m_OverVal = (m_src ^ m_dst) & 0x80; break;
3180         case 0x38: SHRA_BYTE(1); m_OverVal = 0; break;
3181         }
3182         break;
3183
3184      case 0xd1: // i_rotshft_w
3185         m_modrm = fetch();
3186         m_src = GetRMWord();
3187         m_dst = m_src;
3188         CLKM(ROT_REG_1,ROT_M8_1);
3189         switch ( m_modrm & 0x38 )
3190         {
3191         case 0x00: ROL_WORD();  PutbackRMWord(m_dst); m_OverVal = (m_src ^ m_dst) & 0x8000; break;
3192         case 0x08: ROR_WORD();  PutbackRMWord(m_dst); m_OverVal = (m_src ^ m_dst) & 0x8000; break;
3193         case 0x10: ROLC_WORD(); PutbackRMWord(m_dst); m_OverVal = (m_src ^ m_dst) & 0x8000; break;
3194         case 0x18: RORC_WORD(); PutbackRMWord(m_dst); m_OverVal = (m_src ^ m_dst) & 0x8000; break;
3195         case 0x30:
3196         case 0x20: SHL_WORD(1); m_OverVal = (m_src ^ m_dst) & 0x8000;  break;
3197         case 0x28: SHR_WORD(1); m_OverVal = (m_src ^ m_dst) & 0x8000;  break;
3198         case 0x38: SHRA_WORD(1); m_OverVal = 0; break;
3199         }
3200         break;
3201
3202      case 0xd4: // i_aam
3203         fetch();
3204         m_regs.b[AH] = m_regs.b[AL] / 10;
3205         m_regs.b[AL] %= 10;
3206         set_SZPF_Word(m_regs.w[AX]);
3207         CLK(AAM);
3208         break;
3209
3210      case 0xd5: // i_aad
3211         fetch();
3212         m_regs.b[AL] = m_regs.b[AH] * 10 + m_regs.b[AL];
3213         m_regs.b[AH] = 0;
3214         set_SZPF_Byte(m_regs.b[AL]);
3215         CLK(AAD);
3216         break;
3217
3218      case 0xd7: // i_trans
3219         m_regs.b[AL] = GetMemB( DS, m_regs.w[BX] + m_regs.b[AL] );
3220         CLK(XLAT);
3221         break;
3222
3223      case 0xd8: // i_fpo
3224      case 0xd9:
3225      case 0xda:
3226      case 0xdb:
3227      case 0xdc:
3228      case 0xdd:
3229      case 0xde:
3230      case 0xdf:
3231         m_modrm = fetch();
3232         GetRMByte();
3233         CLK(NOP);
3234         logerror("%s: %06x: Unimplemented floating point escape %02x%02x\n", tag(), pc(), op, m_modrm);
3235         break;
3236
3237
3238      case 0xe0: // i_loopne
3239         {
3240            INT8 disp = (INT8)fetch();
3241
3242            m_regs.w[CX]--;
3243            if (!ZF && m_regs.w[CX])
3244            {
3245               m_ip = m_ip + disp;
3246               CLK(LOOP_T);
3247            }
3248            else
3249               CLK(LOOP_NT);
3250         }
3251         break;
3252
3253      case 0xe1: // i_loope
3254         {
3255            INT8 disp = (INT8)fetch();
3256
3257            m_regs.w[CX]--;
3258            if (ZF && m_regs.w[CX])
3259            {
3260               m_ip = m_ip + disp;
3261               CLK(LOOPE_T);
3262            }
3263            else
3264               CLK(LOOPE_NT);
3265         }
3266         break;
3267
3268      case 0xe2: // i_loop
3269         {
3270            INT8 disp = (INT8)fetch();
3271
3272            m_regs.w[CX]--;
3273            if (m_regs.w[CX])
3274            {
3275               m_ip = m_ip + disp;
3276               CLK(LOOP_T);
3277            }
3278            else
3279               CLK(LOOP_NT);
3280         }
3281         break;
3282
3283      case 0xe3: // i_jcxz
3284         {
3285            INT8 disp = (INT8)fetch();
3286
3287            if (m_regs.w[CX] == 0)
3288            {
3289               m_ip = m_ip + disp;
3290               CLK(JCXZ_T);
3291            }
3292            else
3293               CLK(JCXZ_NT);
3294         }
3295         break;
3296
3297      case 0xe4: // i_inal
3298         m_regs.b[AL] = read_port_byte( fetch() );
3299         CLK(IN_IMM8);
3300         break;
3301
3302      case 0xe5: // i_inax
3303         {
3304            UINT8 port = fetch();
3305
3306            m_regs.w[AX] = read_port_word(port);
3307            CLK(IN_IMM16);
3308         }
3309         break;
3310
3311      case 0xe6: // i_outal
3312         write_port_byte( fetch(), m_regs.b[AL]);
3313         CLK(OUT_IMM8);
3314         break;
3315
3316      case 0xe7: // i_outax
3317         {
3318            UINT8 port = fetch();
3319
3320            write_port_word(port, m_regs.w[AX]);
3321            CLK(OUT_IMM16);
3322         }
3323         break;
3324
3325
3326      case 0xe8: // i_call_d16
3327         {
3328            INT16 tmp = (INT16)fetch_word();
3329
3330            PUSH(m_ip);
3331            m_ip = m_ip + tmp;
3332            CLK(CALL_NEAR);
3333         }
3334         break;
3335
3336      case 0xe9: // i_jmp_d16
3337         {
3338            INT16 offset = (INT16)fetch_word();
3339            m_ip += offset;
3340            CLK(JMP_NEAR);
3341         }
3342         break;
3343
3344      case 0xea: // i_jmp_far
3345         {
3346            UINT16 tmp = fetch_word();
3347            UINT16 tmp1 = fetch_word();
3348
3349            m_sregs[CS] = tmp1;
3350            m_ip = tmp;
3351            CLK(JMP_FAR);
3352         }
3353         break;
3354
3355      case 0xeb: // i_jmp_d8
3356         {
3357            int tmp = (int)((INT8)fetch());
3358
3359            CLK(JMP_SHORT);
3360            if (tmp==-2 && m_no_interrupt==0 && (m_pending_irq==0) && m_icount>0)
3361            {
3362               m_icount%=12; /* cycle skip */
3363            }
3364            m_ip = (UINT16)(m_ip+tmp);
3365         }
3366         break;
3367
3368      case 0xec: // i_inaldx
3369         m_regs.b[AL] = read_port_byte(m_regs.w[DX]);
3370         CLK(IN_DX8);
3371         break;
3372
3373      case 0xed: // i_inaxdx
3374         {
3375            UINT32 port = m_regs.w[DX];
3376
3377            m_regs.w[AX] = read_port_word(port);
3378            CLK(IN_DX16);
3379         }
3380         break;
3381
3382      case 0xee: // i_outdxal
3383         write_port_byte(m_regs.w[DX], m_regs.b[AL]);
3384         CLK(OUT_DX8);
3385         break;
3386
3387      case 0xef: // i_outdxax
3388         {
3389            UINT32 port = m_regs.w[DX];
3390
3391            write_port_word(port, m_regs.w[AX]);
3392            CLK(OUT_DX16);
3393         }
3394         break;
3395
3396
3397      case 0xf0: // i_lock
3398         logerror("%s: %06x: Warning - BUSLOCK\n", tag(), pc());
3399         m_no_interrupt = 1;
3400         CLK(NOP);
3401         break;
3402
3403      case 0xf2: // i_repne
3404         {
3405            bool invalid = false;
3406            UINT8 next = repx_op();
3407            UINT16 c = m_regs.w[CX];
3408
3409            switch (next)
3410            {
3411            case 0xa4:  CLK(OVERRIDE); if (c) do { i_movsb(); c--; } while (c>0 && m_icount>0);          m_regs.w[CX]=c; m_seg_prefix = false; m_seg_prefix_next = false; break;
3412            case 0xa5:  CLK(OVERRIDE); if (c) do { i_movsw(); c--; } while (c>0 && m_icount>0);          m_regs.w[CX]=c; m_seg_prefix = false; m_seg_prefix_next = false; break;
3413            case 0xa6:  CLK(OVERRIDE); if (c) do { i_cmpsb(); c--; } while (c>0 && !ZF && m_icount>0);   m_regs.w[CX]=c; m_seg_prefix = false; m_seg_prefix_next = false; break;
3414            case 0xa7:  CLK(OVERRIDE); if (c) do { i_cmpsw(); c--; } while (c>0 && !ZF && m_icount>0);   m_regs.w[CX]=c; m_seg_prefix = false; m_seg_prefix_next = false; break;
3415            case 0xaa:  CLK(OVERRIDE); if (c) do { i_stosb(); c--; } while (c>0 && m_icount>0);          m_regs.w[CX]=c; m_seg_prefix = false; m_seg_prefix_next = false; break;
3416            case 0xab:  CLK(OVERRIDE); if (c) do { i_stosw(); c--; } while (c>0 && m_icount>0);          m_regs.w[CX]=c; m_seg_prefix = false; m_seg_prefix_next = false; break;
3417            case 0xac:  CLK(OVERRIDE); if (c) do { i_lodsb(); c--; } while (c>0 && m_icount>0);          m_regs.w[CX]=c; m_seg_prefix = false; m_seg_prefix_next = false; break;
3418            case 0xad:  CLK(OVERRIDE); if (c) do { i_lodsw(); c--; } while (c>0 && m_icount>0);          m_regs.w[CX]=c; m_seg_prefix = false; m_seg_prefix_next = false; break;
3419            case 0xae:  CLK(OVERRIDE); if (c) do { i_scasb(); c--; } while (c>0 && !ZF && m_icount>0);   m_regs.w[CX]=c; m_seg_prefix = false; m_seg_prefix_next = false; break;
3420            case 0xaf:  CLK(OVERRIDE); if (c) do { i_scasw(); c--; } while (c>0 && !ZF && m_icount>0);   m_regs.w[CX]=c; m_seg_prefix = false; m_seg_prefix_next = false; break;
3421            default:
3422               logerror("%s: %06x: REPNE invalid\n", tag(), pc());
3423               // Decrement IP so the normal instruction will be executed next
3424               m_ip--;
3425               invalid = true;
3426               break;
3427            }
3428            if(c && !invalid)
3429            {
3430               if(!(ZF && ((next & 6) == 6)))
3431                  m_ip = m_prev_ip;
3432            }
3433         }
3434         break;
3435
3436      case 0xf3: // i_repe
3437         {
3438            bool invalid = false;
3439            UINT8 next = repx_op();
3440            UINT16 c = m_regs.w[CX];
3441
3442            switch (next)
3443            {
3444            case 0xa4:  CLK(OVERRIDE); if (c) do { i_movsb(); c--; } while (c>0 && m_icount>0);          m_regs.w[CX]=c; m_seg_prefix = false; m_seg_prefix_next = false; break;
3445            case 0xa5:  CLK(OVERRIDE); if (c) do { i_movsw(); c--; } while (c>0 && m_icount>0);          m_regs.w[CX]=c; m_seg_prefix = false; m_seg_prefix_next = false; break;
3446            case 0xa6:  CLK(OVERRIDE); if (c) do { i_cmpsb(); c--; } while (c>0 && ZF && m_icount>0);    m_regs.w[CX]=c; m_seg_prefix = false; m_seg_prefix_next = false; break;
3447            case 0xa7:  CLK(OVERRIDE); if (c) do { i_cmpsw(); c--; } while (c>0 && ZF && m_icount>0);    m_regs.w[CX]=c; m_seg_prefix = false; m_seg_prefix_next = false; break;
3448            case 0xaa:  CLK(OVERRIDE); if (c) do { i_stosb(); c--; } while (c>0 && m_icount>0);          m_regs.w[CX]=c; m_seg_prefix = false; m_seg_prefix_next = false; break;
3449            case 0xab:  CLK(OVERRIDE); if (c) do { i_stosw(); c--; } while (c>0 && m_icount>0);          m_regs.w[CX]=c; m_seg_prefix = false; m_seg_prefix_next = false; break;
3450            case 0xac:  CLK(OVERRIDE); if (c) do { i_lodsb(); c--; } while (c>0 && m_icount>0);          m_regs.w[CX]=c; m_seg_prefix = false; m_seg_prefix_next = false; break;
3451            case 0xad:  CLK(OVERRIDE); if (c) do { i_lodsw(); c--; } while (c>0 && m_icount>0);          m_regs.w[CX]=c; m_seg_prefix = false; m_seg_prefix_next = false; break;
3452            case 0xae:  CLK(OVERRIDE); if (c) do { i_scasb(); c--; } while (c>0 && ZF && m_icount>0);    m_regs.w[CX]=c; m_seg_prefix = false; m_seg_prefix_next = false; break;
3453            case 0xaf:  CLK(OVERRIDE); if (c) do { i_scasw(); c--; } while (c>0 && ZF && m_icount>0);    m_regs.w[CX]=c; m_seg_prefix = false; m_seg_prefix_next = false; break;
3454            default:
3455               logerror("%s: %06x: REPE invalid\n", tag(), pc());
3456               // Decrement IP so the normal instruction will be executed next
3457               m_ip--;
3458               invalid = true;
3459               break;
3460            }
3461            if(c && !invalid)
3462            {
3463               if(!(!ZF && ((next & 6) == 6)))
3464                  m_ip = m_prev_ip;
3465            }
3466         }
3467         break;
3468
3469      case 0xf4: // i_hlt
3470         logerror("%s: %06x: HALT\n", tag(), pc());
3471         m_icount = 0;
3472         break;
3473
3474      case 0xf5: // i_cmc
3475         m_CarryVal = !m_CarryVal;
3476         CLK(FLAG_OPS);
3477         break;
3478
3479      case 0xf6: // i_f6pre
3480         {
3481            UINT32 tmp;
3482            UINT32 uresult,uresult2;
3483            INT32 result,result2;
3484
3485            m_modrm = fetch();
3486            tmp = GetRMByte();
3487            switch ( m_modrm & 0x38 )
3488            {
3489            case 0x00:  /* TEST */
3490            case 0x08:  /* TEST (alias) */
3491               tmp &= fetch();
3492               m_CarryVal = m_OverVal = 0;
3493               set_SZPF_Byte(tmp);
3494               CLKM(ALU_RI8,ALU_MI8_RO);
3495               break;
3496            case 0x10:  /* NOT */
3497               PutbackRMByte(~tmp);
3498               CLKM(NEGNOT_R8,NEGNOT_M8);
3499               break;
3500            case 0x18:  /* NEG */
3501               m_CarryVal = (tmp!=0) ? 1 : 0;
3502               tmp = (~tmp)+1;
3503               set_SZPF_Byte(tmp);
3504               PutbackRMByte(tmp&0xff);
3505               CLKM(NEGNOT_R8,NEGNOT_M8);
3506               break;
3507            case 0x20:  /* MUL */
3508               uresult = m_regs.b[AL] * tmp;
3509               m_regs.w[AX] = (UINT16)uresult;
3510               m_CarryVal = m_OverVal = (m_regs.b[AH]!=0) ? 1 : 0;
3511               set_ZF(m_regs.w[AX]);
3512               CLKM(MUL_R8,MUL_M8);
3513               break;
3514            case 0x28:  /* IMUL */
3515               result = (INT16)((INT8)m_regs.b[AL])*(INT16)((INT8)tmp);
3516               m_regs.w[AX] = (UINT16)result;
3517               m_CarryVal = m_OverVal = (m_regs.b[AH]!=0) ? 1 : 0;
3518               set_ZF(m_regs.w[AX]);
3519               CLKM(IMUL_R8,IMUL_M8);
3520               break;
3521            case 0x30:  /* DIV */
3522               if (tmp)
3523               {
3524                  uresult = m_regs.w[AX];
3525                  uresult2 = uresult % tmp;
3526                  if ((uresult /= tmp) > 0xff)
3527                  {
3528                     interrupt(0);
3529                  }
3530                  else
3531                  {
3532                     m_regs.b[AL] = uresult;
3533                     m_regs.b[AH] = uresult2;
3534                  }
3535               }
3536               else
3537               {
3538                  interrupt(0);
3539               }
3540               CLKM(DIV_R8,DIV_M8);
3541               break;
3542            case 0x38:  /* IDIV */
3543               if (tmp)
3544               {
3545                  result = (INT16)m_regs.w[AX];
3546                  result2 = result % (INT16)((INT8)tmp);
3547                  if ((result /= (INT16)((INT8)tmp)) > 0xff)
3548                  {
3549                     interrupt(0);
3550                  }
3551                  else
3552                  {
3553                     m_regs.b[AL] = result;
3554                     m_regs.b[AH] = result2;
3555                  }
3556               }
3557               else
3558               {
3559                  interrupt(0);
3560               }
3561               CLKM(IDIV_R8,IDIV_M8);
3562               break;
3563            }
3564         }
3565         break;
3566
3567
3568      case 0xf7: // i_f7pre
3569         {
3570            UINT32 tmp,tmp2;
3571            UINT32 uresult,uresult2;
3572            INT32 result,result2;
3573
3574            m_modrm = fetch();
3575            tmp = GetRMWord();
3576            switch ( m_modrm & 0x38 )
3577            {
3578            case 0x00:  /* TEST */
3579            case 0x08:  /* TEST (alias) */
3580               tmp2 = fetch_word();
3581               tmp &= tmp2;
3582               m_CarryVal = m_OverVal = 0;
3583               set_SZPF_Word(tmp);
3584               CLKM(ALU_RI16,ALU_MI16_RO);
3585               break;
3586               break;
3587            case 0x10:  /* NOT */
3588               PutbackRMWord(~tmp);
3589               CLKM(NEGNOT_R16,NEGNOT_M16);
3590               break;
3591            case 0x18:  /* NEG */
3592               m_CarryVal = (tmp!=0) ? 1 : 0;
3593               tmp = (~tmp) + 1;
3594               set_SZPF_Word(tmp);
3595               PutbackRMWord(tmp);
3596               CLKM(NEGNOT_R16,NEGNOT_M16);
3597               break;
3598            case 0x20:  /* MUL */
3599               uresult = m_regs.w[AX]*tmp;
3600               m_regs.w[AX] = uresult & 0xffff;
3601               m_regs.w[DX] = ((UINT32)uresult)>>16;
3602               m_CarryVal = m_OverVal = (m_regs.w[DX] != 0) ? 1 : 0;
3603               set_ZF(m_regs.w[AX] | m_regs.w[DX]);
3604               CLKM(MUL_R16,MUL_M16);
3605               break;
3606            case 0x28:  /* IMUL */
3607               result = (INT32)((INT16)m_regs.w[AX]) * (INT32)((INT16)tmp);
3608               m_regs.w[AX] = result & 0xffff;
3609               m_regs.w[DX] = result >> 16;
3610               m_CarryVal = m_OverVal = (m_regs.w[DX] != 0) ? 1 : 0;
3611               set_ZF(m_regs.w[AX] | m_regs.w[DX]);
3612               CLKM(IMUL_R16,IMUL_M16);
3613               break;
3614            case 0x30:  /* DIV */
3615               if (tmp)
3616               {
3617                  uresult = (((UINT32)m_regs.w[DX]) << 16) | m_regs.w[AX];
3618                  uresult2 = uresult % tmp;
3619                  if ((uresult /= tmp) > 0xffff)
3620                  {
3621                     interrupt(0);
3622                  }
3623                  else
3624                  {
3625                     m_regs.w[AX] = uresult;
3626                     m_regs.w[DX] = uresult2;
3627                  }
3628               }
3629               else
3630               {
3631                  interrupt(0);
3632               }
3633               CLKM(DIV_R16,DIV_M16);
3634               break;
3635            case 0x38:  /* IDIV */
3636               if (tmp)
3637               {
3638                  result = ((UINT32)m_regs.w[DX] << 16) + m_regs.w[AX];
3639                  result2 = result % (INT32)((INT16)tmp);
3640                  if ((result /= (INT32)((INT16)tmp)) > 0xffff)
3641                  {
3642                     interrupt(0);
3643                  }
3644                  else
3645                  {
3646                     m_regs.w[AX] = result;
3647                     m_regs.w[DX] = result2;
3648                  }
3649               }
3650               else
3651               {
3652                  interrupt(0);
3653               }
3654               CLKM(IDIV_R16,IDIV_M16);
3655               break;
3656            }
3657         }
3658         break;
3659
3660
3661      case 0xf8: // i_clc
3662         m_CarryVal = 0;
3663         CLK(FLAG_OPS);
3664         break;
3665
3666      case 0xf9: // i_stc
3667         m_CarryVal = 1;
3668         CLK(FLAG_OPS);
3669         break;
3670
3671      case 0xfa: // i_cli
3672         m_IF = 0;
3673         CLK(FLAG_OPS);
3674         break;
3675
3676      case 0xfb: // i_sti
3677         m_IF = 1;
3678         CLK(FLAG_OPS);
3679         break;
3680
3681      case 0xfc: // i_cld
3682         m_DF = 0;
3683         CLK(FLAG_OPS);
3684         break;
3685
3686      case 0xfd: // i_std
3687         m_DF = 1;
3688         CLK(FLAG_OPS);
3689         break;
3690
3691      case 0xfe: // i_fepre
3692         {
3693            UINT32 tmp, tmp1;
3694            m_modrm = fetch();
3695            tmp = GetRMByte();
3696            switch ( m_modrm & 0x38 )
3697            {
3698            case 0x00:  /* INC */
3699               tmp1 = tmp+1;
3700               m_OverVal = (tmp==0x7f);
3701               set_AF(tmp1,tmp,1);
3702               set_SZPF_Byte(tmp1);
3703               PutbackRMByte(tmp1);
3704               CLKM(INCDEC_R8,INCDEC_M8);
3705               break;
3706            case 0x08:  /* DEC */
3707               tmp1 = tmp-1;
3708               m_OverVal = (tmp==0x80);
3709               set_AF(tmp1,tmp,1);
3710               set_SZPF_Byte(tmp1);
3711               PutbackRMByte(tmp1);
3712               CLKM(INCDEC_R8,INCDEC_M8);
3713               break;
3714            default:
3715               logerror("%s: %06x: FE Pre with unimplemented mod\n", tag(), pc());
3716               break;
3717            }
3718         }
3719         break;
3720
3721      case 0xff: // i_ffpre
3722         {
3723            UINT32 tmp, tmp1;
3724            m_modrm = fetch();
3725            tmp = GetRMWord();
3726            switch ( m_modrm & 0x38 )
3727            {
3728            case 0x00:  /* INC */
3729               tmp1 = tmp+1;
3730               m_OverVal = (tmp==0x7fff);
3731               set_AF(tmp1,tmp,1);
3732               set_SZPF_Word(tmp1);
3733               PutbackRMWord(tmp1);
3734               CLKM(INCDEC_R16,INCDEC_M16);
3735               break;
3736            case 0x08:  /* DEC */
3737               tmp1 = tmp-1;
3738               m_OverVal = (tmp==0x8000);
3739               set_AF(tmp1,tmp,1);
3740               set_SZPF_Word(tmp1);
3741               PutbackRMWord(tmp1);
3742               CLKM(INCDEC_R16,INCDEC_M16);
3743               break;
3744            case 0x10:  /* CALL */
3745               PUSH(m_ip);
3746               m_ip = tmp;
3747               CLKM(CALL_R16,CALL_M16);
3748               break;
3749            case 0x18:  /* CALL FAR */
3750               tmp1 = m_sregs[CS];
3751               m_sregs[CS] = GetnextRMWord();
3752               PUSH(tmp1);
3753               PUSH(m_ip);
3754               m_ip = tmp;
3755               CLK(CALL_M32);
3756               break;
3757            case 0x20:  /* JMP */
3758               m_ip = tmp;
3759               CLKM(JMP_R16,JMP_M16);
3760               break;
3761            case 0x28:  /* JMP FAR */
3762               m_ip = tmp;
3763               m_sregs[CS] = GetnextRMWord();
3764               CLK(JMP_M32);
3765               break;
3766            case 0x30:
3767               PUSH(tmp);
3768               CLKM(PUSH_R16,PUSH_M16);
3769               break;
3770            default:
3771               logerror("%s: %06x: FF Pre with unimplemented mod\n", tag(), pc());
3772               break;
3773            }
3774         }
3775         break;
3776      default:
3777         return false;
6933778   }
3779   return true;
6943780}
695
696DEFINE_LEGACY_CPU_DEVICE(I8086, i8086);
697DEFINE_LEGACY_CPU_DEVICE(I8088, i8088);
698DEFINE_LEGACY_CPU_DEVICE(I80186, i80186);
699DEFINE_LEGACY_CPU_DEVICE(I80188, i80188);
trunk/src/emu/cpu/i86/i86.h
r24042r24043
1/* ASG 971222 -- rewrote this interface */
2#pragma once
1#ifndef __I8086_H__
2#define __I8086_H__
33
4#ifndef __I86INTF_H__
5#define __I86INTF_H__
4#include "emu.h"
65
6/////////////////////////////////////////////////////////////////
77
8extern const device_type I8086;
9extern const device_type I8088;
10extern const device_type I80186;
11extern const device_type I80188;
12
813#define INPUT_LINE_INT0         INPUT_LINE_IRQ0
914#define INPUT_LINE_INT1         INPUT_LINE_IRQ1
1015#define INPUT_LINE_INT2         INPUT_LINE_IRQ2
r24042r24043
1520#define INPUT_LINE_TMRIN0       23
1621#define INPUT_LINE_TMRIN1       24
1722
23enum
24{
25   I8086_PC=0,
26   I8086_IP, I8086_AX, I8086_CX, I8086_DX, I8086_BX, I8086_SP, I8086_BP, I8086_SI, I8086_DI,
27   I8086_FLAGS, I8086_ES, I8086_CS, I8086_SS, I8086_DS,
28   I8086_VECTOR, I8086_PENDING
29};
1830
19struct i80186_interface
31class i8086_common_cpu_device : public cpu_device
2032{
21   devcb_write_line        out_tmrout0_func;
22   devcb_write_line        out_tmrout1_func;
33public:
34   // construction/destruction
35   i8086_common_cpu_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock, const char *shortname, const char *source);
36
37protected:
38   // device-level overrides
39   virtual void device_start();
40   virtual void device_reset();
41
42   // device_execute_interface overrides
43   virtual UINT32 execute_min_cycles() const { return 1; }
44   virtual UINT32 execute_max_cycles() const { return 50; }
45   virtual UINT32 execute_input_lines() const { return 2; }
46   virtual void execute_set_input(int inputnum, int state);
47
48   // device_disasm_interface overrides
49   virtual UINT32 disasm_min_opcode_bytes() const { return 1; }
50   virtual UINT32 disasm_max_opcode_bytes() const { return 8; }
51   virtual offs_t disasm_disassemble(char *buffer, offs_t pc, const UINT8 *oprom, const UINT8 *opram, UINT32 options);
52
53   // device_state_interface overrides
54   virtual void state_string_export(const device_state_entry &entry, astring &string);
55
56   void interrupt(int int_num);
57   bool common_op(UINT8 op);
58
59   inline UINT32 pc();
60   // Accessing memory and io
61   inline UINT8 read_byte(UINT32 addr);
62   inline UINT16 read_word(UINT32 addr);
63   inline void write_byte(UINT32 addr, UINT8 data);
64   inline void write_word(UINT32 addr, UINT16 data);
65   inline UINT8 read_port_byte(UINT16 port);
66   inline UINT16 read_port_word(UINT16 port);
67   inline void write_port_byte(UINT16 port, UINT8 data);
68   inline void write_port_word(UINT16 port, UINT16 data);
69
70   // Executing instructions
71   inline UINT8 fetch_op();
72   inline UINT8 fetch();
73   inline UINT16 fetch_word();
74   inline UINT8 repx_op();
75
76   // Cycles passed while executing instructions
77   inline void CLK(UINT8 op);
78   inline void CLKM(UINT8 op_reg, UINT8 op_mem);
79
80   // Memory handling while executing instructions
81   inline UINT32 default_base(int seg);
82   inline UINT32 get_ea();
83   inline void PutbackRMByte(UINT8 data);
84   inline void PutbackRMWord(UINT16 data);
85   inline void RegByte(UINT8 data);
86   inline void RegWord(UINT16 data);
87   inline UINT8 RegByte();
88   inline UINT16 RegWord();
89   inline UINT16 GetRMWord();
90   inline UINT16 GetnextRMWord();
91   inline UINT8 GetRMByte();
92   inline void PutMemB(int seg, UINT16 offset, UINT8 data);
93   inline void PutMemW(int seg, UINT16 offset, UINT16 data);
94   inline UINT8 GetMemB(int seg, UINT16 offset);
95   inline UINT16 GetMemW(int seg, UINT16 offset);
96   inline void PutImmRMWord();
97   inline void PutRMWord(UINT16 val);
98   inline void PutRMByte(UINT8 val);
99   inline void PutImmRMByte();
100   inline void DEF_br8();
101   inline void DEF_wr16();
102   inline void DEF_r8b();
103   inline void DEF_r16w();
104   inline void DEF_ald8();
105   inline void DEF_axd16();
106
107   // Flags
108   inline void set_CFB(UINT32 x);
109   inline void set_CFW(UINT32 x);
110   inline void set_AF(UINT32 x,UINT32 y,UINT32 z);
111   inline void set_SF(UINT32 x);
112   inline void set_ZF(UINT32 x);
113   inline void set_PF(UINT32 x);
114   inline void set_SZPF_Byte(UINT32 x);
115   inline void set_SZPF_Word(UINT32 x);
116   inline void set_OFW_Add(UINT32 x,UINT32 y,UINT32 z);
117   inline void set_OFB_Add(UINT32 x,UINT32 y,UINT32 z);
118   inline void set_OFW_Sub(UINT32 x,UINT32 y,UINT32 z);
119   inline void set_OFB_Sub(UINT32 x,UINT32 y,UINT32 z);
120   inline UINT16 CompressFlags();
121   inline void ExpandFlags(UINT16 f);
122
123   // rep instructions
124   inline void i_insb();
125   inline void i_insw();
126   inline void i_outsb();
127   inline void i_outsw();
128   inline void i_movsb();
129   inline void i_movsw();
130   inline void i_cmpsb();
131   inline void i_cmpsw();
132   inline void i_stosb();
133   inline void i_stosw();
134   inline void i_lodsb();
135   inline void i_lodsw();
136   inline void i_scasb();
137   inline void i_scasw();
138   inline void i_popf();
139
140   // sub implementations
141   inline void ADDB();
142   inline void ADDX();
143   inline void SUBB();
144   inline void SUBX();
145   inline void ORB();
146   inline void ORW();
147   inline void ANDB();
148   inline void ANDX();
149   inline void XORB();
150   inline void XORW();
151   inline void ROL_BYTE();
152   inline void ROL_WORD();
153   inline void ROR_BYTE();
154   inline void ROR_WORD();
155   inline void ROLC_BYTE();
156   inline void ROLC_WORD();
157   inline void RORC_BYTE();
158   inline void RORC_WORD();
159   inline void SHL_BYTE(UINT8 c);
160   inline void SHL_WORD(UINT8 c);
161   inline void SHR_BYTE(UINT8 c);
162   inline void SHR_WORD(UINT8 c);
163   inline void SHRA_BYTE(UINT8 c);
164   inline void SHRA_WORD(UINT8 c);
165   inline void XchgAXReg(UINT8 reg);
166   inline void IncWordReg(UINT8 reg);
167   inline void DecWordReg(UINT8 reg);
168   inline void PUSH(UINT16 data);
169   inline UINT16 POP();
170   inline void JMP(bool cond);
171   inline void ADJ4(INT8 param1, INT8 param2);
172   inline void ADJB(INT8 param1, INT8 param2);
173
174protected:
175
176   union
177   {                   /* eight general registers */
178      UINT16 w[8];    /* viewed as 16 bits registers */
179      UINT8  b[16];   /* or as 8 bit registers */
180   } m_regs;
181   UINT16  m_sregs[4];
182
183   UINT16  m_ip;
184   UINT16  m_prev_ip;
185
186   INT32   m_SignVal;
187   UINT32  m_AuxVal, m_OverVal, m_ZeroVal, m_CarryVal, m_ParityVal; /* 0 or non-0 valued flags */
188   UINT8   m_TF, m_IF, m_DF;     /* 0 or 1 valued flags */
189   UINT32  m_int_vector;
190   UINT32  m_pending_irq;
191   UINT32  m_nmi_state;
192   UINT32  m_irq_state;
193   UINT8   m_no_interrupt;
194   UINT8   m_fire_trap;
195   UINT8   m_test_state;
196
197   address_space *m_program;
198   direct_read_data *m_direct;
199   address_space *m_io;
200   int m_icount;
201
202   UINT32 m_prefix_base;   /* base address of the latest prefix segment */
203   bool m_seg_prefix;      /* prefix segment indicator */
204   bool m_seg_prefix_next; /* prefix segment for next instruction */
205
206   UINT32 m_ea;
207   UINT16 m_eo;
208   UINT16 m_e16;
209
210   // Used during execution of instructions
211   UINT8   m_modrm;
212   UINT32  m_dst;
213   UINT32  m_src;
214   UINT32  m_pc;
215
216   // Lookup tables
217   UINT8 m_parity_table[256];
218   struct {
219      struct {
220         int w[256];
221         int b[256];
222      } reg;
223      struct {
224         int w[256];
225         int b[256];
226      } RM;
227   } m_Mod_RM;
228
229   UINT8 m_timing[200];
23230};
24#define I80186_INTERFACE(name) const i80186_interface (name) =
25231
232class i8086_cpu_device : public i8086_common_cpu_device
233{
234public:
235   // construction/destruction
236   i8086_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
237   i8086_cpu_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock, const char *shortname, const char *source, int data_bus_size);
26238
27enum
239   // device_memory_interface overrides
240   virtual const address_space_config *memory_space_config(address_spacenum spacenum = AS_0) const { return (spacenum == AS_PROGRAM) ? &m_program_config : ( (spacenum == AS_IO) ? &m_io_config : NULL ); }
241
242protected:
243   virtual void execute_run();
244
245   address_space_config m_program_config;
246   address_space_config m_io_config;
247   static const UINT8 m_i8086_timing[200];
248};
249
250class i8088_cpu_device : public i8086_cpu_device
28251{
29   I8086_IP,
30   I8086_AX,
31   I8086_CX,
32   I8086_DX,
33   I8086_BX,
34   I8086_SP,
35   I8086_BP,
36   I8086_SI,
37   I8086_DI,
38   I8086_AL,
39   I8086_CL,
40   I8086_DL,
41   I8086_BL,
42   I8086_AH,
43   I8086_CH,
44   I8086_DH,
45   I8086_BH,
46   I8086_FLAGS,
47   I8086_ES,
48   I8086_CS,
49   I8086_SS,
50   I8086_DS,
51   I8086_VECTOR,
252public:
253   // construction/destruction
254   i8088_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
255};
52256
53   I8086_GENPC = STATE_GENPC,
54   I8086_GENSP = STATE_GENSP,
55   I8086_GENPCBASE = STATE_GENPCBASE
257class i80186_cpu_device : public i8086_common_cpu_device
258{
259public:
260   // construction/destruction
261   i80186_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
262   i80186_cpu_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock, const char *shortname, const char *source, int data_bus_size);
263
264   // device_memory_interface overrides
265   virtual const address_space_config *memory_space_config(address_spacenum spacenum = AS_0) const { return (spacenum == AS_PROGRAM) ? &m_program_config : ( (spacenum == AS_IO) ? &m_io_config : NULL ); }
266
267protected:
268   virtual void execute_run();
269
270   address_space_config m_program_config;
271   address_space_config m_io_config;
272   static const UINT8 m_i80186_timing[200];
56273};
57274
58/* Public functions */
59DECLARE_LEGACY_CPU_DEVICE(I8086, i8086);
60DECLARE_LEGACY_CPU_DEVICE(I8088, i8088);
61DECLARE_LEGACY_CPU_DEVICE(I80186, i80186);
62DECLARE_LEGACY_CPU_DEVICE(I80188, i80188);
275class i80188_cpu_device : public i80186_cpu_device
276{
277public:
278   // construction/destruction
279   i80188_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
280};
63281
64#endif /* __I86INTF_H__ */
282
283#endif /* __I8086_H__ */
trunk/src/mess/machine/pc.c
r24042r24043
302302WRITE_LINE_MEMBER(pc_state::pcjr_pic8259_set_int_line)
303303{
304304   UINT32 pc = machine().firstcpu->pc();
305   if ( (pc == 0xF0454) || (pc == 0xFF197) )
305   if ( (pc == 0xF0453) || (pc == 0xFF196) )
306306   {
307      pc_int_delay_timer->adjust( machine().firstcpu->cycles_to_attotime(1), state );
307      pc_int_delay_timer->adjust( machine().firstcpu->cycles_to_attotime(20), state );
308308   }
309309   else
310310   {
trunk/src/mame/includes/gottlieb.h
r24042r24043
250250   { }
251251
252252   // devices
253   required_device<i8088_device> m_maincpu;
253   required_device<cpu_device> m_maincpu;
254254   optional_device<pioneer_pr8210_device> m_laserdisc;
255255   optional_device<gottlieb_sound_r1_device> m_r1_sound;
256256   optional_device<gottlieb_sound_r2_device> m_r2_sound;

Previous 199869 Revisions Next


© 1997-2024 The MAME Team