Fixed handling 80186 instructions [Phill Harvey-Smith]

This commit is contained in:
Miodrag Milanovic 2011-01-10 14:30:01 +00:00
parent 83768eaec6
commit 7e8ad4aae5
3 changed files with 135 additions and 112 deletions

View File

@ -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);

View File

@ -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;

View File

@ -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,7 +46,7 @@ static void (*const PREFIX186(_instruction)[256])(i8086_state *cpustate) =
PREFIX86(_sub_r16w), /* 0x2b */
PREFIX86(_sub_ald8), /* 0x2c */
PREFIX86(_sub_axd16), /* 0x2d */
PREFIX86(_cs), /* 0x2e */
PREFIX186(_cs), /* 0x2e */
PREFIX86(_das), /* 0x2f */
PREFIX86(_xor_br8), /* 0x30 */
PREFIX86(_xor_wr16), /* 0x31 */
@ -54,7 +54,7 @@ static void (*const PREFIX186(_instruction)[256])(i8086_state *cpustate) =
PREFIX86(_xor_r16w), /* 0x33 */
PREFIX86(_xor_ald8), /* 0x34 */
PREFIX86(_xor_axd16), /* 0x35 */
PREFIX86(_ss), /* 0x36 */
PREFIX186(_ss), /* 0x36 */
PREFIX86(_aaa), /* 0x37 */
PREFIX86(_cmp_br8), /* 0x38 */
PREFIX86(_cmp_wr16), /* 0x39 */
@ -62,7 +62,7 @@ static void (*const PREFIX186(_instruction)[256])(i8086_state *cpustate) =
PREFIX86(_cmp_r16w), /* 0x3b */
PREFIX86(_cmp_ald8), /* 0x3c */
PREFIX86(_cmp_axd16), /* 0x3d */
PREFIX86(_ds), /* 0x3e */
PREFIX186(_ds), /* 0x3e */
PREFIX86(_aas), /* 0x3f */
PREFIX86(_inc_ax), /* 0x40 */
PREFIX86(_inc_cx), /* 0x41 */
@ -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;\