summaryrefslogtreecommitdiffstatshomepage
path: root/src/emu/cpu/i86
diff options
context:
space:
mode:
author Miodrag Milanovic <mmicko@gmail.com>2011-01-10 14:30:01 +0000
committer Miodrag Milanovic <mmicko@gmail.com>2011-01-10 14:30:01 +0000
commit7e8ad4aae56c10bf3f4ed84879acfd8981b6cf32 (patch)
tree60f4c8a1405ce9b89252081c57692d217810f763 /src/emu/cpu/i86
parent83768eaec6f3e347f9c7ddd710824bb822e2fc87 (diff)
Fixed handling 80186 instructions [Phill Harvey-Smith]
Diffstat (limited to 'src/emu/cpu/i86')
-rw-r--r--src/emu/cpu/i86/instr186.h7
-rw-r--r--src/emu/cpu/i86/instr86.c218
-rw-r--r--src/emu/cpu/i86/table186.h22
3 files changed, 135 insertions, 112 deletions
diff --git a/src/emu/cpu/i86/instr186.h b/src/emu/cpu/i86/instr186.h
index 86c8b285c2b..f7d57a20716 100644
--- a/src/emu/cpu/i86/instr186.h
+++ b/src/emu/cpu/i86/instr186.h
@@ -23,5 +23,12 @@ static void PREFIX186(_outsb)(i8086_state *cpustate);
static void PREFIX186(_outsw)(i8086_state *cpustate);
/* changed instructions */
+static void PREFIX(_pop_ss)(i8086_state *cpustate);
+static void PREFIX(_es)(i8086_state *cpustate);
+static void PREFIX(_cs)(i8086_state *cpustate);
+static void PREFIX(_ss)(i8086_state *cpustate);
+static void PREFIX(_ds)(i8086_state *cpustate);
+static void PREFIX(_mov_sregw)(i8086_state *cpustate);
static void PREFIX186(_repne)(i8086_state *cpustate);
static void PREFIX186(_repe)(i8086_state *cpustate);
+static void PREFIX186(_sti)(i8086_state *cpustate);
diff --git a/src/emu/cpu/i86/instr86.c b/src/emu/cpu/i86/instr86.c
index 1d8de5b609f..ee0c5c0a50c 100644
--- a/src/emu/cpu/i86/instr86.c
+++ b/src/emu/cpu/i86/instr86.c
@@ -10,6 +10,22 @@
* timing value should move to separate array
*/
+/*
+ PHS - 2010-12-29
+
+ Moved several instruction stubs so that they are compiled separately for
+ the 8086 and 80186. The instructions affected are :
+
+ _pop_ss, _es, _cs, _ss, _ds, _mov_sregw and _sti
+
+ This is because they call the next instruction directly as it cannot be
+ interrupted. If they are not compiled separately when executing on an
+ 80186, the wrong set of instructions are used (the 8086 set). This has
+ the serious effect of ignoring the next instruction, as invalid, *IF*
+ it is an 80186 specific instruction.
+
+*/
+
#undef ICOUNT
#define ICOUNT cpustate->icount
@@ -821,20 +837,6 @@ static void PREFIX86(_push_ss)(i8086_state *cpustate) /* Opcode 0x16 */
ICOUNT -= timing.push_seg;
}
-static void PREFIX86(_pop_ss)(i8086_state *cpustate) /* Opcode 0x17 */
-{
-#ifdef I80286
- UINT16 tmp;
- POP(tmp);
- i80286_data_descriptor(cpustate, SS, tmp);
-#else
- POP(cpustate->sregs[SS]);
- cpustate->base[SS] = SegBase(SS);
-#endif
- ICOUNT -= timing.pop_seg;
- PREFIX(_instruction)[FETCHOP](cpustate); /* no interrupt before next instruction */
-}
-
static void PREFIX86(_sbb_br8)(i8086_state *cpustate) /* Opcode 0x18 */
{
DEF_br8(dst,src);
@@ -956,14 +958,6 @@ static void PREFIX86(_and_axd16)(i8086_state *cpustate) /* Opcode 0x25 */
cpustate->regs.w[AX]=dst;
}
-static void PREFIX86(_es)(i8086_state *cpustate) /* Opcode 0x26 */
-{
- cpustate->seg_prefix = TRUE;
- cpustate->prefix_seg = ES;
- ICOUNT -= timing.override;
- PREFIX(_instruction)[FETCHOP](cpustate);
-}
-
static void PREFIX86(_daa)(i8086_state *cpustate) /* Opcode 0x27 */
{
if (AF || ((cpustate->regs.b[AL] & 0xf) > 9))
@@ -1032,14 +1026,6 @@ static void PREFIX86(_sub_axd16)(i8086_state *cpustate) /* Opcode 0x2d */
cpustate->regs.w[AX]=dst;
}
-static void PREFIX86(_cs)(i8086_state *cpustate) /* Opcode 0x2e */
-{
- cpustate->seg_prefix = TRUE;
- cpustate->prefix_seg = CS;
- ICOUNT -= timing.override;
- PREFIX(_instruction)[FETCHOP](cpustate);
-}
-
static void PREFIX86(_das)(i8086_state *cpustate) /* Opcode 0x2f */
{
UINT8 tmpAL=cpustate->regs.b[AL];
@@ -1109,14 +1095,6 @@ static void PREFIX86(_xor_axd16)(i8086_state *cpustate) /* Opcode 0x35 */
cpustate->regs.w[AX]=dst;
}
-static void PREFIX86(_ss)(i8086_state *cpustate) /* Opcode 0x36 */
-{
- cpustate->seg_prefix = TRUE;
- cpustate->prefix_seg = SS;
- ICOUNT -= timing.override;
- PREFIX(_instruction)[FETCHOP](cpustate);
-}
-
static void PREFIX86(_aaa)(i8086_state *cpustate) /* Opcode 0x37 */
{
UINT8 ALcarry=1;
@@ -1180,14 +1158,6 @@ static void PREFIX86(_cmp_axd16)(i8086_state *cpustate) /* Opcode 0x3d */
SUBW(dst,src);
}
-static void PREFIX86(_ds)(i8086_state *cpustate) /* Opcode 0x3e */
-{
- cpustate->seg_prefix = TRUE;
- cpustate->prefix_seg = DS;
- ICOUNT -= timing.override;
- PREFIX(_instruction)[FETCHOP](cpustate);
-}
-
static void PREFIX86(_aas)(i8086_state *cpustate) /* Opcode 0x3f */
{
UINT8 ALcarry=1;
@@ -1880,50 +1850,6 @@ static void PREFIX86(_lea)(i8086_state *cpustate) /* Opcode 0x8d */
RegWord(ModRM)=cpustate->eo; /* HJB 12/13/98 effective offset (no segment part) */
}
-static void PREFIX86(_mov_sregw)(i8086_state *cpustate) /* Opcode 0x8e */
-{
- unsigned ModRM = FETCH;
- WORD src = GetRMWord(ModRM);
-
- ICOUNT -= (ModRM >= 0xc0) ? timing.mov_sr : timing.mov_sm;
-#ifdef I80286
- switch (ModRM & 0x38)
- {
- case 0x00: /* mov es,ew */
- i80286_data_descriptor(cpustate,ES,src);
- break;
- case 0x18: /* mov ds,ew */
- i80286_data_descriptor(cpustate,DS,src);
- break;
- case 0x10: /* mov ss,ew */
- i80286_data_descriptor(cpustate,SS,src);
- PREFIX(_instruction)[FETCHOP](cpustate);
- break;
- case 0x08: /* mov cs,ew */
- break; /* doesn't do a jump far */
- }
-#else
- switch (ModRM & 0x38)
- {
- case 0x00: /* mov es,ew */
- cpustate->sregs[ES] = src;
- cpustate->base[ES] = SegBase(ES);
- break;
- case 0x18: /* mov ds,ew */
- cpustate->sregs[DS] = src;
- cpustate->base[DS] = SegBase(DS);
- break;
- case 0x10: /* mov ss,ew */
- cpustate->sregs[SS] = src;
- cpustate->base[SS] = SegBase(SS); /* no interrupt allowed before next instr */
- PREFIX(_instruction)[FETCHOP](cpustate);
- break;
- case 0x08: /* mov cs,ew */
- break; /* doesn't do a jump far */
- }
-#endif
-}
-
static void PREFIX86(_popw)(i8086_state *cpustate) /* Opcode 0x8f */
{
unsigned ModRM = FETCH;
@@ -2722,6 +2648,96 @@ static void PREFIX86(_lock)(i8086_state *cpustate) /* Opcode 0xf0 */
}
#endif
+static void PREFIX(_pop_ss)(i8086_state *cpustate) /* Opcode 0x17 */
+{
+#ifdef I80286
+ UINT16 tmp;
+ POP(tmp);
+ i80286_data_descriptor(cpustate, SS, tmp);
+#else
+ POP(cpustate->sregs[SS]);
+ cpustate->base[SS] = SegBase(SS);
+#endif
+ ICOUNT -= timing.pop_seg;
+ PREFIX(_instruction)[FETCHOP](cpustate); /* no interrupt before next instruction */
+}
+
+static void PREFIX(_es)(i8086_state *cpustate) /* Opcode 0x26 */
+{
+ cpustate->seg_prefix = TRUE;
+ cpustate->prefix_seg = ES;
+ ICOUNT -= timing.override;
+ PREFIX(_instruction)[FETCHOP](cpustate);
+}
+
+static void PREFIX(_cs)(i8086_state *cpustate) /* Opcode 0x2e */
+{
+ cpustate->seg_prefix = TRUE;
+ cpustate->prefix_seg = CS;
+ ICOUNT -= timing.override;
+ PREFIX(_instruction)[FETCHOP](cpustate);
+}
+
+static void PREFIX(_ss)(i8086_state *cpustate) /* Opcode 0x36 */
+{
+ cpustate->seg_prefix = TRUE;
+ cpustate->prefix_seg = SS;
+ ICOUNT -= timing.override;
+ PREFIX(_instruction)[FETCHOP](cpustate);
+}
+
+static void PREFIX(_ds)(i8086_state *cpustate) /* Opcode 0x3e */
+{
+ cpustate->seg_prefix = TRUE;
+ cpustate->prefix_seg = DS;
+ ICOUNT -= timing.override;
+ PREFIX(_instruction)[FETCHOP](cpustate);
+}
+
+static void PREFIX(_mov_sregw)(i8086_state *cpustate) /* Opcode 0x8e */
+{
+ unsigned ModRM = FETCH;
+ WORD src = GetRMWord(ModRM);
+
+ ICOUNT -= (ModRM >= 0xc0) ? timing.mov_sr : timing.mov_sm;
+#ifdef I80286
+ switch (ModRM & 0x38)
+ {
+ case 0x00: /* mov es,ew */
+ i80286_data_descriptor(cpustate,ES,src);
+ break;
+ case 0x18: /* mov ds,ew */
+ i80286_data_descriptor(cpustate,DS,src);
+ break;
+ case 0x10: /* mov ss,ew */
+ i80286_data_descriptor(cpustate,SS,src);
+ PREFIX(_instruction)[FETCHOP](cpustate);
+ break;
+ case 0x08: /* mov cs,ew */
+ break; /* doesn't do a jump far */
+ }
+#else
+ switch (ModRM & 0x38)
+ {
+ case 0x00: /* mov es,ew */
+ cpustate->sregs[ES] = src;
+ cpustate->base[ES] = SegBase(ES);
+ break;
+ case 0x18: /* mov ds,ew */
+ cpustate->sregs[DS] = src;
+ cpustate->base[DS] = SegBase(DS);
+ break;
+ case 0x10: /* mov ss,ew */
+ cpustate->sregs[SS] = src;
+ cpustate->base[SS] = SegBase(SS); /* no interrupt allowed before next instr */
+ PREFIX(_instruction)[FETCHOP](cpustate);
+ break;
+ case 0x08: /* mov cs,ew */
+ break; /* doesn't do a jump far */
+ }
+#endif
+}
+
static void PREFIX(_repne)(i8086_state *cpustate) /* Opcode 0xf2 */
{
PREFIX(rep)(cpustate, 0);
@@ -2732,6 +2748,17 @@ static void PREFIX(_repe)(i8086_state *cpustate) /* Opcode 0xf3 */
PREFIX(rep)(cpustate, 1);
}
+static void PREFIX(_sti)(i8086_state *cpustate) /* Opcode 0xfb */
+{
+ ICOUNT -= timing.flag_ops;
+ SetIF(1);
+ PREFIX(_instruction)[FETCHOP](cpustate); /* no interrupt before next instruction */
+
+ /* if an interrupt is pending, signal an interrupt */
+ if (cpustate->irq_state)
+ PREFIX86(_interrupt)(cpustate, (UINT32)-1);
+}
+
#ifndef I80186
static void PREFIX86(_hlt)(i8086_state *cpustate) /* Opcode 0xf4 */
{
@@ -3022,17 +3049,6 @@ static void PREFIX86(_cli)(i8086_state *cpustate) /* Opcode 0xfa */
SetIF(0);
}
-static void PREFIX86(_sti)(i8086_state *cpustate) /* Opcode 0xfb */
-{
- ICOUNT -= timing.flag_ops;
- SetIF(1);
- PREFIX(_instruction)[FETCHOP](cpustate); /* no interrupt before next instruction */
-
- /* if an interrupt is pending, signal an interrupt */
- if (cpustate->irq_state)
- PREFIX(_interrupt)(cpustate, (UINT32)-1);
-}
-
static void PREFIX86(_cld)(i8086_state *cpustate) /* Opcode 0xfc */
{
ICOUNT -= timing.flag_ops;
diff --git a/src/emu/cpu/i86/table186.h b/src/emu/cpu/i86/table186.h
index 0a8669413ed..e4b65ca5ca4 100644
--- a/src/emu/cpu/i86/table186.h
+++ b/src/emu/cpu/i86/table186.h
@@ -23,7 +23,7 @@ static void (*const PREFIX186(_instruction)[256])(i8086_state *cpustate) =
PREFIX86(_adc_ald8), /* 0x14 */
PREFIX86(_adc_axd16), /* 0x15 */
PREFIX86(_push_ss), /* 0x16 */
- PREFIX86(_pop_ss), /* 0x17 */
+ PREFIX186(_pop_ss), /* 0x17 */
PREFIX86(_sbb_br8), /* 0x18 */
PREFIX86(_sbb_wr16), /* 0x19 */
PREFIX86(_sbb_r8b), /* 0x1a */
@@ -38,7 +38,7 @@ static void (*const PREFIX186(_instruction)[256])(i8086_state *cpustate) =
PREFIX86(_and_r16w), /* 0x23 */
PREFIX86(_and_ald8), /* 0x24 */
PREFIX86(_and_axd16), /* 0x25 */
- PREFIX86(_es), /* 0x26 */
+ PREFIX186(_es), /* 0x26 */
PREFIX86(_daa), /* 0x27 */
PREFIX86(_sub_br8), /* 0x28 */
PREFIX86(_sub_wr16), /* 0x29 */
@@ -46,24 +46,24 @@ static void (*const PREFIX186(_instruction)[256])(i8086_state *cpustate) =
PREFIX86(_sub_r16w), /* 0x2b */
PREFIX86(_sub_ald8), /* 0x2c */
PREFIX86(_sub_axd16), /* 0x2d */
- PREFIX86(_cs), /* 0x2e */
- PREFIX86(_das), /* 0x2f */
+ PREFIX186(_cs), /* 0x2e */
+ PREFIX86(_das), /* 0x2f */
PREFIX86(_xor_br8), /* 0x30 */
PREFIX86(_xor_wr16), /* 0x31 */
PREFIX86(_xor_r8b), /* 0x32 */
PREFIX86(_xor_r16w), /* 0x33 */
PREFIX86(_xor_ald8), /* 0x34 */
PREFIX86(_xor_axd16), /* 0x35 */
- PREFIX86(_ss), /* 0x36 */
- PREFIX86(_aaa), /* 0x37 */
+ PREFIX186(_ss), /* 0x36 */
+ PREFIX86(_aaa), /* 0x37 */
PREFIX86(_cmp_br8), /* 0x38 */
PREFIX86(_cmp_wr16), /* 0x39 */
PREFIX86(_cmp_r8b), /* 0x3a */
PREFIX86(_cmp_r16w), /* 0x3b */
PREFIX86(_cmp_ald8), /* 0x3c */
PREFIX86(_cmp_axd16), /* 0x3d */
- PREFIX86(_ds), /* 0x3e */
- PREFIX86(_aas), /* 0x3f */
+ PREFIX186(_ds), /* 0x3e */
+ PREFIX86(_aas), /* 0x3f */
PREFIX86(_inc_ax), /* 0x40 */
PREFIX86(_inc_cx), /* 0x41 */
PREFIX86(_inc_dx), /* 0x42 */
@@ -142,7 +142,7 @@ static void (*const PREFIX186(_instruction)[256])(i8086_state *cpustate) =
PREFIX86(_mov_r16w), /* 0x8b */
PREFIX86(_mov_wsreg), /* 0x8c */
PREFIX86(_lea), /* 0x8d */
- PREFIX86(_mov_sregw), /* 0x8e */
+ PREFIX186(_mov_sregw), /* 0x8e */
PREFIX86(_popw), /* 0x8f */
PREFIX86(_nop), /* 0x90 */
PREFIX86(_xchg_axcx), /* 0x91 */
@@ -251,7 +251,7 @@ static void (*const PREFIX186(_instruction)[256])(i8086_state *cpustate) =
PREFIX86(_clc), /* 0xf8 */
PREFIX86(_stc), /* 0xf9 */
PREFIX86(_cli), /* 0xfa */
- PREFIX86(_sti), /* 0xfb */
+ PREFIX186(_sti), /* 0xfb */
PREFIX86(_cld), /* 0xfc */
PREFIX86(_std), /* 0xfd */
PREFIX86(_fepre), /* 0xfe */
@@ -514,7 +514,7 @@ static void (*const PREFIX186(_instruction)[256])(i8086_state *cpustate) =
case 0xf8: PREFIX86(_clc)(cpustate); break;\
case 0xf9: PREFIX86(_stc)(cpustate); break;\
case 0xfa: PREFIX86(_cli)(cpustate); break;\
- case 0xfb: PREFIX86(_sti)(cpustate); break;\
+ case 0xfb: PREFIX186(_sti)(cpustate); break;\
case 0xfc: PREFIX86(_cld)(cpustate); break;\
case 0xfd: PREFIX86(_std)(cpustate); break;\
case 0xfe: PREFIX86(_fepre)(cpustate); break;\