mirror of
https://github.com/holub/mame
synced 2025-05-24 23:05:32 +03:00
i286.c: Partially implemented protected mode. Fixed verw, verr, lar, lsl, and arpl instructions. [Wilbert Pol]
This commit is contained in:
parent
dd12c245a8
commit
5976655411
1
.gitattributes
vendored
1
.gitattributes
vendored
@ -185,6 +185,7 @@ src/emu/cpu/i86/instr286.h svneol=native#text/plain
|
||||
src/emu/cpu/i86/instr86.c svneol=native#text/plain
|
||||
src/emu/cpu/i86/instr86.h svneol=native#text/plain
|
||||
src/emu/cpu/i86/modrm.h svneol=native#text/plain
|
||||
src/emu/cpu/i86/modrm286.h svneol=native#text/plain
|
||||
src/emu/cpu/i86/table186.h svneol=native#text/plain
|
||||
src/emu/cpu/i86/table286.h svneol=native#text/plain
|
||||
src/emu/cpu/i86/table86.h svneol=native#text/plain
|
||||
|
@ -669,6 +669,7 @@ $(CPUOBJ)/i86/i286.o: $(CPUSRC)/i86/i286.c \
|
||||
$(CPUSRC)/i86/instr86.c \
|
||||
$(CPUSRC)/i86/instr186.c \
|
||||
$(CPUSRC)/i86/instr286.c \
|
||||
$(CPUSRC)/i86/modrm286.h \
|
||||
$(I86DEPS)
|
||||
|
||||
$(CPUOBJ)/i386/i386.o: $(CPUSRC)/i386/i386.c \
|
||||
|
@ -1,29 +1,29 @@
|
||||
static unsigned EA_000(i8086_state *cpustate) { cpustate->icount-=7; cpustate->eo=(WORD)(cpustate->regs.w[BX]+cpustate->regs.w[SI]); cpustate->ea=DefaultBase(DS)+cpustate->eo; return cpustate->ea; }
|
||||
static unsigned EA_001(i8086_state *cpustate) { cpustate->icount-=8; cpustate->eo=(WORD)(cpustate->regs.w[BX]+cpustate->regs.w[DI]); cpustate->ea=DefaultBase(DS)+cpustate->eo; return cpustate->ea; }
|
||||
static unsigned EA_002(i8086_state *cpustate) { cpustate->icount-=8; cpustate->eo=(WORD)(cpustate->regs.w[BP]+cpustate->regs.w[SI]); cpustate->ea=DefaultBase(SS)+cpustate->eo; return cpustate->ea; }
|
||||
static unsigned EA_003(i8086_state *cpustate) { cpustate->icount-=7; cpustate->eo=(WORD)(cpustate->regs.w[BP]+cpustate->regs.w[DI]); cpustate->ea=DefaultBase(SS)+cpustate->eo; return cpustate->ea; }
|
||||
static unsigned EA_004(i8086_state *cpustate) { cpustate->icount-=5; cpustate->eo=cpustate->regs.w[SI]; cpustate->ea=DefaultBase(DS)+cpustate->eo; return cpustate->ea; }
|
||||
static unsigned EA_005(i8086_state *cpustate) { cpustate->icount-=5; cpustate->eo=cpustate->regs.w[DI]; cpustate->ea=DefaultBase(DS)+cpustate->eo; return cpustate->ea; }
|
||||
static unsigned EA_006(i8086_state *cpustate) { cpustate->icount-=6; cpustate->eo=FETCHOP; cpustate->eo+=FETCHOP<<8; cpustate->ea=DefaultBase(DS)+cpustate->eo; return cpustate->ea; }
|
||||
static unsigned EA_007(i8086_state *cpustate) { cpustate->icount-=5; cpustate->eo=cpustate->regs.w[BX]; cpustate->ea=DefaultBase(DS)+cpustate->eo; return cpustate->ea; }
|
||||
static unsigned EA_000(i8086_state *cpustate) { cpustate->icount-=7; cpustate->eo=(WORD)(cpustate->regs.w[BX]+cpustate->regs.w[SI]); cpustate->ea_seg=DefaultSeg(DS); cpustate->ea=DefaultBase(DS)+cpustate->eo; return cpustate->ea; }
|
||||
static unsigned EA_001(i8086_state *cpustate) { cpustate->icount-=8; cpustate->eo=(WORD)(cpustate->regs.w[BX]+cpustate->regs.w[DI]); cpustate->ea_seg=DefaultSeg(DS); cpustate->ea=DefaultBase(DS)+cpustate->eo; return cpustate->ea; }
|
||||
static unsigned EA_002(i8086_state *cpustate) { cpustate->icount-=8; cpustate->eo=(WORD)(cpustate->regs.w[BP]+cpustate->regs.w[SI]); cpustate->ea_seg=DefaultSeg(SS); cpustate->ea=DefaultBase(SS)+cpustate->eo; return cpustate->ea; }
|
||||
static unsigned EA_003(i8086_state *cpustate) { cpustate->icount-=7; cpustate->eo=(WORD)(cpustate->regs.w[BP]+cpustate->regs.w[DI]); cpustate->ea_seg=DefaultSeg(SS); cpustate->ea=DefaultBase(SS)+cpustate->eo; return cpustate->ea; }
|
||||
static unsigned EA_004(i8086_state *cpustate) { cpustate->icount-=5; cpustate->eo=cpustate->regs.w[SI]; cpustate->ea_seg=DefaultSeg(DS); cpustate->ea=DefaultBase(DS)+cpustate->eo; return cpustate->ea; }
|
||||
static unsigned EA_005(i8086_state *cpustate) { cpustate->icount-=5; cpustate->eo=cpustate->regs.w[DI]; cpustate->ea_seg=DefaultSeg(DS); cpustate->ea=DefaultBase(DS)+cpustate->eo; return cpustate->ea; }
|
||||
static unsigned EA_006(i8086_state *cpustate) { cpustate->icount-=6; cpustate->eo=FETCHOP; cpustate->eo+=FETCHOP<<8; cpustate->ea_seg=DefaultSeg(DS); cpustate->ea=DefaultBase(DS)+cpustate->eo; return cpustate->ea; }
|
||||
static unsigned EA_007(i8086_state *cpustate) { cpustate->icount-=5; cpustate->eo=cpustate->regs.w[BX]; cpustate->ea_seg=DefaultSeg(DS); cpustate->ea=DefaultBase(DS)+cpustate->eo; return cpustate->ea; }
|
||||
|
||||
static unsigned EA_100(i8086_state *cpustate) { cpustate->icount-=11; cpustate->eo=(WORD)(cpustate->regs.w[BX]+cpustate->regs.w[SI]+(INT8)FETCHOP); cpustate->ea=DefaultBase(DS)+cpustate->eo; return cpustate->ea; }
|
||||
static unsigned EA_101(i8086_state *cpustate) { cpustate->icount-=12; cpustate->eo=(WORD)(cpustate->regs.w[BX]+cpustate->regs.w[DI]+(INT8)FETCHOP); cpustate->ea=DefaultBase(DS)+cpustate->eo; return cpustate->ea; }
|
||||
static unsigned EA_102(i8086_state *cpustate) { cpustate->icount-=12; cpustate->eo=(WORD)(cpustate->regs.w[BP]+cpustate->regs.w[SI]+(INT8)FETCHOP); cpustate->ea=DefaultBase(SS)+cpustate->eo; return cpustate->ea; }
|
||||
static unsigned EA_103(i8086_state *cpustate) { cpustate->icount-=11; cpustate->eo=(WORD)(cpustate->regs.w[BP]+cpustate->regs.w[DI]+(INT8)FETCHOP); cpustate->ea=DefaultBase(SS)+cpustate->eo; return cpustate->ea; }
|
||||
static unsigned EA_104(i8086_state *cpustate) { cpustate->icount-=9; cpustate->eo=(WORD)(cpustate->regs.w[SI]+(INT8)FETCHOP); cpustate->ea=DefaultBase(DS)+cpustate->eo; return cpustate->ea; }
|
||||
static unsigned EA_105(i8086_state *cpustate) { cpustate->icount-=9; cpustate->eo=(WORD)(cpustate->regs.w[DI]+(INT8)FETCHOP); cpustate->ea=DefaultBase(DS)+cpustate->eo; return cpustate->ea; }
|
||||
static unsigned EA_106(i8086_state *cpustate) { cpustate->icount-=9; cpustate->eo=(WORD)(cpustate->regs.w[BP]+(INT8)FETCHOP); cpustate->ea=DefaultBase(SS)+cpustate->eo; return cpustate->ea; }
|
||||
static unsigned EA_107(i8086_state *cpustate) { cpustate->icount-=9; cpustate->eo=(WORD)(cpustate->regs.w[BX]+(INT8)FETCHOP); cpustate->ea=DefaultBase(DS)+cpustate->eo; return cpustate->ea; }
|
||||
static unsigned EA_100(i8086_state *cpustate) { cpustate->icount-=11; cpustate->eo=(WORD)(cpustate->regs.w[BX]+cpustate->regs.w[SI]+(INT8)FETCHOP); cpustate->ea_seg=DefaultSeg(DS); cpustate->ea=DefaultBase(DS)+cpustate->eo; return cpustate->ea; }
|
||||
static unsigned EA_101(i8086_state *cpustate) { cpustate->icount-=12; cpustate->eo=(WORD)(cpustate->regs.w[BX]+cpustate->regs.w[DI]+(INT8)FETCHOP); cpustate->ea_seg=DefaultSeg(DS); cpustate->ea=DefaultBase(DS)+cpustate->eo; return cpustate->ea; }
|
||||
static unsigned EA_102(i8086_state *cpustate) { cpustate->icount-=12; cpustate->eo=(WORD)(cpustate->regs.w[BP]+cpustate->regs.w[SI]+(INT8)FETCHOP); cpustate->ea_seg=DefaultSeg(SS); cpustate->ea=DefaultBase(SS)+cpustate->eo; return cpustate->ea; }
|
||||
static unsigned EA_103(i8086_state *cpustate) { cpustate->icount-=11; cpustate->eo=(WORD)(cpustate->regs.w[BP]+cpustate->regs.w[DI]+(INT8)FETCHOP); cpustate->ea_seg=DefaultSeg(SS); cpustate->ea=DefaultBase(SS)+cpustate->eo; return cpustate->ea; }
|
||||
static unsigned EA_104(i8086_state *cpustate) { cpustate->icount-=9; cpustate->eo=(WORD)(cpustate->regs.w[SI]+(INT8)FETCHOP); cpustate->ea_seg=DefaultSeg(DS); cpustate->ea=DefaultBase(DS)+cpustate->eo; return cpustate->ea; }
|
||||
static unsigned EA_105(i8086_state *cpustate) { cpustate->icount-=9; cpustate->eo=(WORD)(cpustate->regs.w[DI]+(INT8)FETCHOP); cpustate->ea_seg=DefaultSeg(DS); cpustate->ea=DefaultBase(DS)+cpustate->eo; return cpustate->ea; }
|
||||
static unsigned EA_106(i8086_state *cpustate) { cpustate->icount-=9; cpustate->eo=(WORD)(cpustate->regs.w[BP]+(INT8)FETCHOP); cpustate->ea_seg=DefaultSeg(SS); cpustate->ea=DefaultBase(SS)+cpustate->eo; return cpustate->ea; }
|
||||
static unsigned EA_107(i8086_state *cpustate) { cpustate->icount-=9; cpustate->eo=(WORD)(cpustate->regs.w[BX]+(INT8)FETCHOP); cpustate->ea_seg=DefaultSeg(DS); cpustate->ea=DefaultBase(DS)+cpustate->eo; return cpustate->ea; }
|
||||
|
||||
static unsigned EA_200(i8086_state *cpustate) { cpustate->icount-=11; cpustate->eo=FETCHOP; cpustate->eo+=FETCHOP<<8; cpustate->eo+=cpustate->regs.w[BX]+cpustate->regs.w[SI]; cpustate->ea=DefaultBase(DS)+(WORD)cpustate->eo; return cpustate->ea; }
|
||||
static unsigned EA_201(i8086_state *cpustate) { cpustate->icount-=12; cpustate->eo=FETCHOP; cpustate->eo+=FETCHOP<<8; cpustate->eo+=cpustate->regs.w[BX]+cpustate->regs.w[DI]; cpustate->ea=DefaultBase(DS)+(WORD)cpustate->eo; return cpustate->ea; }
|
||||
static unsigned EA_202(i8086_state *cpustate) { cpustate->icount-=12; cpustate->eo=FETCHOP; cpustate->eo+=FETCHOP<<8; cpustate->eo+=cpustate->regs.w[BP]+cpustate->regs.w[SI]; cpustate->ea=DefaultBase(SS)+(WORD)cpustate->eo; return cpustate->ea; }
|
||||
static unsigned EA_203(i8086_state *cpustate) { cpustate->icount-=11; cpustate->eo=FETCHOP; cpustate->eo+=FETCHOP<<8; cpustate->eo+=cpustate->regs.w[BP]+cpustate->regs.w[DI]; cpustate->ea=DefaultBase(SS)+(WORD)cpustate->eo; return cpustate->ea; }
|
||||
static unsigned EA_204(i8086_state *cpustate) { cpustate->icount-=9; cpustate->eo=FETCHOP; cpustate->eo+=FETCHOP<<8; cpustate->eo+=cpustate->regs.w[SI]; cpustate->ea=DefaultBase(DS)+(WORD)cpustate->eo; return cpustate->ea; }
|
||||
static unsigned EA_205(i8086_state *cpustate) { cpustate->icount-=9; cpustate->eo=FETCHOP; cpustate->eo+=FETCHOP<<8; cpustate->eo+=cpustate->regs.w[DI]; cpustate->ea=DefaultBase(DS)+(WORD)cpustate->eo; return cpustate->ea; }
|
||||
static unsigned EA_206(i8086_state *cpustate) { cpustate->icount-=9; cpustate->eo=FETCHOP; cpustate->eo+=FETCHOP<<8; cpustate->eo+=cpustate->regs.w[BP]; cpustate->ea=DefaultBase(SS)+(WORD)cpustate->eo; return cpustate->ea; }
|
||||
static unsigned EA_207(i8086_state *cpustate) { cpustate->icount-=9; cpustate->eo=FETCHOP; cpustate->eo+=FETCHOP<<8; cpustate->eo+=cpustate->regs.w[BX]; cpustate->ea=DefaultBase(DS)+(WORD)cpustate->eo; return cpustate->ea; }
|
||||
static unsigned EA_200(i8086_state *cpustate) { cpustate->icount-=11; cpustate->eo=FETCHOP; cpustate->eo+=FETCHOP<<8; cpustate->eo+=cpustate->regs.w[BX]+cpustate->regs.w[SI]; cpustate->ea_seg=DefaultSeg(DS); cpustate->ea=DefaultBase(DS)+(WORD)cpustate->eo; return cpustate->ea; }
|
||||
static unsigned EA_201(i8086_state *cpustate) { cpustate->icount-=12; cpustate->eo=FETCHOP; cpustate->eo+=FETCHOP<<8; cpustate->eo+=cpustate->regs.w[BX]+cpustate->regs.w[DI]; cpustate->ea_seg=DefaultSeg(DS); cpustate->ea=DefaultBase(DS)+(WORD)cpustate->eo; return cpustate->ea; }
|
||||
static unsigned EA_202(i8086_state *cpustate) { cpustate->icount-=12; cpustate->eo=FETCHOP; cpustate->eo+=FETCHOP<<8; cpustate->eo+=cpustate->regs.w[BP]+cpustate->regs.w[SI]; cpustate->ea_seg=DefaultSeg(SS); cpustate->ea=DefaultBase(SS)+(WORD)cpustate->eo; return cpustate->ea; }
|
||||
static unsigned EA_203(i8086_state *cpustate) { cpustate->icount-=11; cpustate->eo=FETCHOP; cpustate->eo+=FETCHOP<<8; cpustate->eo+=cpustate->regs.w[BP]+cpustate->regs.w[DI]; cpustate->ea_seg=DefaultSeg(DS); cpustate->ea=DefaultBase(SS)+(WORD)cpustate->eo; return cpustate->ea; }
|
||||
static unsigned EA_204(i8086_state *cpustate) { cpustate->icount-=9; cpustate->eo=FETCHOP; cpustate->eo+=FETCHOP<<8; cpustate->eo+=cpustate->regs.w[SI]; cpustate->ea_seg=DefaultSeg(DS); cpustate->ea=DefaultBase(DS)+(WORD)cpustate->eo; return cpustate->ea; }
|
||||
static unsigned EA_205(i8086_state *cpustate) { cpustate->icount-=9; cpustate->eo=FETCHOP; cpustate->eo+=FETCHOP<<8; cpustate->eo+=cpustate->regs.w[DI]; cpustate->ea_seg=DefaultSeg(DS); cpustate->ea=DefaultBase(DS)+(WORD)cpustate->eo; return cpustate->ea; }
|
||||
static unsigned EA_206(i8086_state *cpustate) { cpustate->icount-=9; cpustate->eo=FETCHOP; cpustate->eo+=FETCHOP<<8; cpustate->eo+=cpustate->regs.w[BP]; cpustate->ea_seg=DefaultSeg(SS); cpustate->ea=DefaultBase(SS)+(WORD)cpustate->eo; return cpustate->ea; }
|
||||
static unsigned EA_207(i8086_state *cpustate) { cpustate->icount-=9; cpustate->eo=FETCHOP; cpustate->eo+=FETCHOP<<8; cpustate->eo+=cpustate->regs.w[BX]; cpustate->ea_seg=DefaultSeg(DS); cpustate->ea=DefaultBase(DS)+(WORD)cpustate->eo; return cpustate->ea; }
|
||||
|
||||
static unsigned (*const GetEA[192])(i8086_state *cpustate)={
|
||||
EA_000, EA_001, EA_002, EA_003, EA_004, EA_005, EA_006, EA_007,
|
||||
|
@ -75,10 +75,11 @@ struct _i80286_state
|
||||
int halted; /* Is the CPU halted ? */
|
||||
|
||||
int icount;
|
||||
unsigned prefix_base;
|
||||
char seg_prefix;
|
||||
UINT8 prefix_seg;
|
||||
unsigned ea;
|
||||
UINT16 eo; /* HJB 12/13/98 effective offset of the address (before segment is added) */
|
||||
UINT8 ea_seg; /* effective segment of the address */
|
||||
};
|
||||
|
||||
INLINE i80286_state *get_safe_token(running_device *device)
|
||||
@ -105,7 +106,7 @@ static struct i80x86_timing timing;
|
||||
#define i8086_state i80286_state
|
||||
|
||||
#include "ea.h"
|
||||
#include "modrm.h"
|
||||
#include "modrm286.h"
|
||||
#include "instr86.h"
|
||||
#include "instr186.h"
|
||||
#include "instr286.h"
|
||||
@ -226,8 +227,15 @@ static CPU_EXECUTE( i80286 )
|
||||
cpustate->seg_prefix=FALSE;
|
||||
cpustate->prevpc = cpustate->pc;
|
||||
|
||||
try
|
||||
{
|
||||
TABLE286 // call instruction
|
||||
}
|
||||
catch (int e)
|
||||
{
|
||||
i80286_trap2(cpustate,e);
|
||||
}
|
||||
}
|
||||
|
||||
/* adjust for any interrupts that came in */
|
||||
cpustate->icount -= cpustate->extra_cycles;
|
||||
|
@ -62,10 +62,11 @@ struct _i8086_state
|
||||
address_space *io;
|
||||
int icount;
|
||||
|
||||
unsigned prefix_base; /* base address of the latest prefix segment */
|
||||
char seg_prefix; /* prefix segment indicator */
|
||||
UINT8 prefix_seg; /* The prefixed segment */
|
||||
unsigned ea;
|
||||
UINT16 eo; /* HJB 12/13/98 effective offset of the address (before segment is added) */
|
||||
UINT8 ea_seg; /* effective segment of the address */
|
||||
|
||||
devcb_resolved_write_line out_tmrout0_func;
|
||||
devcb_resolved_write_line out_tmrout1_func;
|
||||
@ -556,7 +557,7 @@ CPU_GET_INFO( i8086 )
|
||||
case CPUINFO_INT_CLOCK_MULTIPLIER: info->i = 1; break;
|
||||
case CPUINFO_INT_CLOCK_DIVIDER: info->i = 1; break;
|
||||
case CPUINFO_INT_MIN_INSTRUCTION_BYTES: info->i = 1; break;
|
||||
case CPUINFO_INT_MAX_INSTRUCTION_BYTES: info->i = 8; break;
|
||||
case CPUINFO_INT_MAX_INSTRUCTION_BYTES: info->i = 16; break;
|
||||
case CPUINFO_INT_MIN_CYCLES: info->i = 1; break;
|
||||
case CPUINFO_INT_MAX_CYCLES: info->i = 50; break;
|
||||
|
||||
|
@ -98,7 +98,8 @@ typedef enum {
|
||||
|
||||
#define SegBase(Seg) (cpustate->sregs[Seg] << 4)
|
||||
|
||||
#define DefaultBase(Seg) ((cpustate->seg_prefix && (Seg == DS || Seg == SS)) ? cpustate->prefix_base : cpustate->base[Seg])
|
||||
#define DefaultSeg(Seg) ((cpustate->seg_prefix && (Seg == DS || Seg == SS)) ? cpustate->prefix_seg : Seg)
|
||||
#define DefaultBase(Seg) ((cpustate->seg_prefix && (Seg == DS || Seg == SS)) ? cpustate->base[cpustate->prefix_seg] : cpustate->base[Seg])
|
||||
|
||||
#define GetMemB(Seg,Off) (read_mem_byte((DefaultBase(Seg) + (Off)) & AMASK))
|
||||
#define GetMemW(Seg,Off) (read_mem_word((DefaultBase(Seg) + (Off)) & AMASK))
|
||||
|
@ -17,8 +17,9 @@
|
||||
7 p present 0 gives trap when accessed
|
||||
UINT16 reserved (should be zero)
|
||||
*/
|
||||
#define WRITEABLE(a) ((a&0xa)==2)
|
||||
#define READABLE(a) ( ((a&0xa)==0xa)|| ((a&8)==0) )
|
||||
#define IS_PRESENT(a) ( ( (a) & 0x80 ) == 0x80 )
|
||||
#define IS_WRITEABLE(a) ( ( (a) & 0xa ) == 2 )
|
||||
#define IS_READABLE(a) ( ( ( (a) & 0xa ) == 0xa ) || ( ( (a) & 8 ) == 0 ) )
|
||||
|
||||
static void i80286_trap2(i80286_state *cpustate,int number)
|
||||
{
|
||||
@ -205,22 +206,22 @@ static void PREFIX286(_0fpre)(i8086_state *cpustate)
|
||||
if (!PM) i80286_trap2(cpustate,ILLEGAL_INSTRUCTION);
|
||||
tmp=GetRMWord(ModRM);
|
||||
if (tmp&4) {
|
||||
cpustate->ZeroVal=( ((tmp&~7)<cpustate->ldtr.limit)
|
||||
&& READABLE( ReadByte(cpustate->ldtr.base+(tmp&~7)+5)) );
|
||||
cpustate->ZeroVal=! ( ((tmp&~7)<cpustate->ldtr.limit)
|
||||
&& IS_READABLE( ReadByte(cpustate->ldtr.base+(tmp&~7)+5)) );
|
||||
} else {
|
||||
cpustate->ZeroVal=( ((tmp&~7)<cpustate->gdtr.limit)
|
||||
&& READABLE( ReadByte(cpustate->gdtr.base+(tmp&~7)+5)) );
|
||||
cpustate->ZeroVal=! ( ((tmp&~7)<cpustate->gdtr.limit)
|
||||
&& IS_READABLE( ReadByte(cpustate->gdtr.base+(tmp&~7)+5)) );
|
||||
}
|
||||
break;
|
||||
case 0x28: /* verw */
|
||||
if (!PM) i80286_trap2(cpustate,ILLEGAL_INSTRUCTION);
|
||||
tmp=GetRMWord(ModRM);
|
||||
if (tmp&4) {
|
||||
cpustate->ZeroVal=( ((tmp&~7)<cpustate->ldtr.limit)
|
||||
&& WRITEABLE( ReadByte(cpustate->ldtr.base+(tmp&~7)+5)) );
|
||||
cpustate->ZeroVal=! ( ((tmp&~7)<cpustate->ldtr.limit)
|
||||
&& IS_WRITEABLE( ReadByte(cpustate->ldtr.base+(tmp&~7)+5)) );
|
||||
} else {
|
||||
cpustate->ZeroVal=( ((tmp&~7)<cpustate->gdtr.limit)
|
||||
&& WRITEABLE( ReadByte(cpustate->gdtr.base+(tmp&~7)+5)) );
|
||||
cpustate->ZeroVal=! ( ((tmp&~7)<cpustate->gdtr.limit)
|
||||
&& IS_WRITEABLE( ReadByte(cpustate->gdtr.base+(tmp&~7)+5)) );
|
||||
}
|
||||
break;
|
||||
default:
|
||||
@ -268,20 +269,30 @@ static void PREFIX286(_0fpre)(i8086_state *cpustate)
|
||||
case 2: /* LAR */
|
||||
ModRM = FETCHOP;
|
||||
tmp=GetRMWord(ModRM);
|
||||
cpustate->ZeroVal=i80286_selector_okay(cpustate,tmp);
|
||||
if (cpustate->ZeroVal) {
|
||||
RegWord(ModRM)=tmp;
|
||||
if ( i80286_selector_okay(cpustate,tmp) )
|
||||
{
|
||||
cpustate->ZeroVal = 0;
|
||||
RegWord(ModRM) = ReadByte( i80286_selector_to_address(cpustate,tmp) + 5 ) << 8;
|
||||
}
|
||||
else
|
||||
{
|
||||
cpustate->ZeroVal = 1;
|
||||
}
|
||||
break;
|
||||
case 3: /* LSL */
|
||||
if (!PM) i80286_trap2(cpustate,ILLEGAL_INSTRUCTION);
|
||||
ModRM = FETCHOP;
|
||||
tmp=GetRMWord(ModRM);
|
||||
cpustate->ZeroVal=i80286_selector_okay(cpustate,tmp);
|
||||
if (cpustate->ZeroVal) {
|
||||
if ( i80286_selector_okay(cpustate,tmp) )
|
||||
{
|
||||
cpustate->ZeroVal = 0;
|
||||
addr=i80286_selector_to_address(cpustate,tmp);
|
||||
RegWord(ModRM)=ReadWord(addr);
|
||||
}
|
||||
else
|
||||
{
|
||||
cpustate->ZeroVal = 1;
|
||||
}
|
||||
break;
|
||||
case 6: /* clts */
|
||||
if (PM&&(CPL!=0)) i80286_trap2(cpustate,GENERAL_PROTECTION_FAULT);
|
||||
@ -295,14 +306,59 @@ static void PREFIX286(_0fpre)(i8086_state *cpustate)
|
||||
|
||||
static void PREFIX286(_arpl)(i8086_state *cpustate) /* 0x63 */
|
||||
{
|
||||
if (PM) {
|
||||
UINT16 ModRM=FETCHOP, tmp=GetRMWord(ModRM);
|
||||
if (PM)
|
||||
{
|
||||
UINT16 ModRM=FETCHOP, tmp=GetRMWord(ModRM), source=RegWord(ModRM);
|
||||
|
||||
cpustate->ZeroVal=i80286_selector_okay(cpustate,RegWord(ModRM))
|
||||
&&i80286_selector_okay(cpustate,RegWord(ModRM))
|
||||
&&((tmp&3)<(RegWord(ModRM)&3));
|
||||
if (cpustate->ZeroVal) PutbackRMWord(ModRM, (tmp&~3)|(RegWord(ModRM)&3));
|
||||
} else {
|
||||
if ( i80286_selector_okay(cpustate,tmp) &&i80286_selector_okay(cpustate,source) &&((tmp&3)<(source&3)) )
|
||||
{
|
||||
cpustate->ZeroVal = 0;
|
||||
PutbackRMWord(ModRM, (tmp&~3)|(source&3));
|
||||
}
|
||||
else
|
||||
{
|
||||
cpustate->ZeroVal = 1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
i80286_trap2(cpustate,ILLEGAL_INSTRUCTION);
|
||||
}
|
||||
}
|
||||
|
||||
static void i80286_check_permission(i8086_state *cpustate, UINT8 check_seg, UINT16 offset, i80286_size size, i80286_operation operation)
|
||||
{
|
||||
if (PM)
|
||||
{
|
||||
/* Is the segment physically present? */
|
||||
if ( ! IS_PRESENT( cpustate->rights[check_seg] ) )
|
||||
throw GENERAL_PROTECTION_FAULT;
|
||||
|
||||
/* Would we go past the segment boundary? */
|
||||
if ( offset + size > cpustate->limit[check_seg] )
|
||||
{
|
||||
throw GENERAL_PROTECTION_FAULT;
|
||||
}
|
||||
|
||||
switch(operation)
|
||||
{
|
||||
case I80286_READ:
|
||||
/* Is the segment readable? */
|
||||
if ( ! IS_READABLE( cpustate->rights[check_seg] ) )
|
||||
throw GENERAL_PROTECTION_FAULT;
|
||||
break;
|
||||
|
||||
case I80286_WRITE:
|
||||
/* Is the segment writeable? */
|
||||
if ( ! IS_WRITEABLE( cpustate->rights[check_seg] ) )
|
||||
throw GENERAL_PROTECTION_FAULT;
|
||||
break;
|
||||
|
||||
case I80286_EXECUTE:
|
||||
/* TODO */
|
||||
break;
|
||||
}
|
||||
/* TODO: Mark segment as accessed? */
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -11,3 +11,18 @@ static void i80286_code_descriptor(i80286_state *cpustate,UINT16 selector, UINT1
|
||||
static void i80286_data_descriptor(i80286_state *cpustate,int reg, UINT16 selector);
|
||||
static void PREFIX286(_0fpre)(i80286_state *cpustate);
|
||||
static void PREFIX286(_arpl)(i80286_state *cpustate);
|
||||
|
||||
enum i80286_size
|
||||
{
|
||||
I80286_BYTE = 1,
|
||||
I80286_WORD = 2
|
||||
};
|
||||
|
||||
enum i80286_operation
|
||||
{
|
||||
I80286_READ = 1,
|
||||
I80286_WRITE,
|
||||
I80286_EXECUTE
|
||||
};
|
||||
|
||||
static void i80286_check_permission(i8086_state *cpustate, UINT8 check_seg, UINT16 offset, i80286_size size, i80286_operation operation);
|
||||
|
@ -391,29 +391,29 @@ static void PREFIX(rep)(i8086_state *cpustate,int flagval)
|
||||
switch(next)
|
||||
{
|
||||
case 0x26: /* ES: */
|
||||
cpustate->seg_prefix=TRUE;
|
||||
cpustate->prefix_base=cpustate->base[ES];
|
||||
cpustate->seg_prefix = TRUE;
|
||||
cpustate->prefix_seg = ES;
|
||||
if (!cpustate->rep_in_progress)
|
||||
ICOUNT -= timing.override;
|
||||
PREFIX(rep)(cpustate, flagval);
|
||||
break;
|
||||
case 0x2e: /* CS: */
|
||||
cpustate->seg_prefix=TRUE;
|
||||
cpustate->prefix_base=cpustate->base[CS];
|
||||
cpustate->seg_prefix = TRUE;
|
||||
cpustate->prefix_seg = CS;
|
||||
if (!cpustate->rep_in_progress)
|
||||
ICOUNT -= timing.override;
|
||||
PREFIX(rep)(cpustate, flagval);
|
||||
break;
|
||||
case 0x36: /* SS: */
|
||||
cpustate->seg_prefix=TRUE;
|
||||
cpustate->prefix_base=cpustate->base[SS];
|
||||
cpustate->seg_prefix = TRUE;
|
||||
cpustate->prefix_seg = SS;
|
||||
if (!cpustate->rep_in_progress)
|
||||
ICOUNT -= timing.override;
|
||||
PREFIX(rep)(cpustate, flagval);
|
||||
break;
|
||||
case 0x3e: /* DS: */
|
||||
cpustate->seg_prefix=TRUE;
|
||||
cpustate->prefix_base=cpustate->base[DS];
|
||||
cpustate->seg_prefix = TRUE;
|
||||
cpustate->prefix_seg = DS;
|
||||
if (!cpustate->rep_in_progress)
|
||||
ICOUNT -= timing.override;
|
||||
PREFIX(rep)(cpustate, flagval);
|
||||
@ -958,8 +958,8 @@ static void PREFIX86(_and_axd16)(i8086_state *cpustate) /* Opcode 0x25 */
|
||||
|
||||
static void PREFIX86(_es)(i8086_state *cpustate) /* Opcode 0x26 */
|
||||
{
|
||||
cpustate->seg_prefix=TRUE;
|
||||
cpustate->prefix_base=cpustate->base[ES];
|
||||
cpustate->seg_prefix = TRUE;
|
||||
cpustate->prefix_seg = ES;
|
||||
ICOUNT -= timing.override;
|
||||
PREFIX(_instruction)[FETCHOP](cpustate);
|
||||
}
|
||||
@ -1034,8 +1034,8 @@ static void PREFIX86(_sub_axd16)(i8086_state *cpustate) /* Opcode 0x2d */
|
||||
|
||||
static void PREFIX86(_cs)(i8086_state *cpustate) /* Opcode 0x2e */
|
||||
{
|
||||
cpustate->seg_prefix=TRUE;
|
||||
cpustate->prefix_base=cpustate->base[CS];
|
||||
cpustate->seg_prefix = TRUE;
|
||||
cpustate->prefix_seg = CS;
|
||||
ICOUNT -= timing.override;
|
||||
PREFIX(_instruction)[FETCHOP](cpustate);
|
||||
}
|
||||
@ -1111,8 +1111,8 @@ static void PREFIX86(_xor_axd16)(i8086_state *cpustate) /* Opcode 0x35 */
|
||||
|
||||
static void PREFIX86(_ss)(i8086_state *cpustate) /* Opcode 0x36 */
|
||||
{
|
||||
cpustate->seg_prefix=TRUE;
|
||||
cpustate->prefix_base=cpustate->base[SS];
|
||||
cpustate->seg_prefix = TRUE;
|
||||
cpustate->prefix_seg = SS;
|
||||
ICOUNT -= timing.override;
|
||||
PREFIX(_instruction)[FETCHOP](cpustate);
|
||||
}
|
||||
@ -1182,8 +1182,8 @@ static void PREFIX86(_cmp_axd16)(i8086_state *cpustate) /* Opcode 0x3d */
|
||||
|
||||
static void PREFIX86(_ds)(i8086_state *cpustate) /* Opcode 0x3e */
|
||||
{
|
||||
cpustate->seg_prefix=TRUE;
|
||||
cpustate->prefix_base=cpustate->base[DS];
|
||||
cpustate->seg_prefix = TRUE;
|
||||
cpustate->prefix_seg = DS;
|
||||
ICOUNT -= timing.override;
|
||||
PREFIX(_instruction)[FETCHOP](cpustate);
|
||||
}
|
||||
@ -3165,10 +3165,9 @@ static void PREFIX86(_invalid)(i8086_state *cpustate)
|
||||
#ifdef I80286
|
||||
i80286_trap2(cpustate,ILLEGAL_INSTRUCTION);
|
||||
#else
|
||||
/* makes the cpu loops forever until user resets it */
|
||||
/*{ debugger_break(Machine); } */
|
||||
logerror("illegal instruction %.2x at %.5x\n",PEEKBYTE(cpustate->pc), cpustate->pc);
|
||||
cpustate->pc--;
|
||||
/* i8086/i8088 ignore an invalid opcode. */
|
||||
/* i80186/i80188 probably also ignore an invalid opcode. */
|
||||
logerror("illegal instruction %.2x at %.5x\n",PEEKBYTE(cpustate->pc-1), cpustate->pc);
|
||||
ICOUNT -= 10;
|
||||
#endif
|
||||
}
|
||||
|
145
src/emu/cpu/i86/modrm286.h
Normal file
145
src/emu/cpu/i86/modrm286.h
Normal file
@ -0,0 +1,145 @@
|
||||
static struct
|
||||
{
|
||||
struct
|
||||
{
|
||||
WREGS w[256];
|
||||
BREGS b[256];
|
||||
} reg;
|
||||
struct
|
||||
{
|
||||
WREGS w[256];
|
||||
BREGS b[256];
|
||||
} RM;
|
||||
} Mod_RM;
|
||||
|
||||
#define RegWord(ModRM) cpustate->regs.w[Mod_RM.reg.w[ModRM]]
|
||||
#define RegByte(ModRM) cpustate->regs.b[Mod_RM.reg.b[ModRM]]
|
||||
|
||||
#define GetRMWord(ModRM) \
|
||||
((ModRM) >= 0xc0 ? cpustate->regs.w[Mod_RM.RM.w[ModRM]] : ( (*GetEA[ModRM])(cpustate), i80286_check_permission(cpustate, cpustate->ea_seg, cpustate->eo, I80286_WORD, I80286_READ), ReadWord( cpustate->ea ) ))
|
||||
|
||||
#define PutbackRMWord(ModRM,val) \
|
||||
{ \
|
||||
if (ModRM >= 0xc0) cpustate->regs.w[Mod_RM.RM.w[ModRM]]=val; \
|
||||
else \
|
||||
{ \
|
||||
i80286_check_permission(cpustate, cpustate->ea_seg, cpustate->eo, I80286_WORD, I80286_WRITE); \
|
||||
WriteWord(cpustate->ea,val); \
|
||||
} \
|
||||
}
|
||||
|
||||
#define GetnextRMWord \
|
||||
( \
|
||||
i80286_check_permission(cpustate, cpustate->ea_seg, cpustate->ea + 2 - cpustate->base[cpustate->ea_seg], I80286_WORD, I80286_READ), \
|
||||
ReadWord(cpustate->ea+2) \
|
||||
)
|
||||
|
||||
#define GetRMWordOffset(offs) \
|
||||
( \
|
||||
i80286_check_permission(cpustate, cpustate->ea_seg, (UINT16)(cpustate->eo+offs), I80286_WORD, I80286_READ), \
|
||||
ReadWord(cpustate->ea-cpustate->eo+(UINT16)(cpustate->eo+offs)) \
|
||||
)
|
||||
|
||||
#define GetRMByteOffset(offs) \
|
||||
( \
|
||||
i80286_check_permission(cpustate, cpustate->ea_seg, (UINT16)(cpustate->eo+offs), I80286_BYTE, I80286_READ), \
|
||||
ReadByte(cpustate->ea-cpustate->eo+(UINT16)(cpustate->eo+offs)) \
|
||||
)
|
||||
|
||||
#define PutRMWord(ModRM,val) \
|
||||
{ \
|
||||
if (ModRM >= 0xc0) \
|
||||
cpustate->regs.w[Mod_RM.RM.w[ModRM]]=val; \
|
||||
else { \
|
||||
(*GetEA[ModRM])(cpustate); \
|
||||
i80286_check_permission(cpustate, cpustate->ea_seg, cpustate->eo, I80286_WORD, I80286_WRITE); \
|
||||
WriteWord( cpustate->ea ,val); \
|
||||
} \
|
||||
}
|
||||
|
||||
#define PutRMWordOffset(offs, val) \
|
||||
i80286_check_permission(cpustate, cpustate->ea_seg, (UINT16)(cpustate->eo+offs), I80286_WORD, I80286_WRITE); \
|
||||
WriteWord( cpustate->ea-cpustate->eo+(UINT16)(cpustate->eo+offs), val)
|
||||
|
||||
#define PutRMByteOffset(offs, val) \
|
||||
i80286_check_permission(cpustate, cpustate->ea_seg, (UINT16)(cpustate->eo+offs), I80286_BYTE, I80286_WRITE); \
|
||||
WriteByte( cpustate->ea-cpustate->eo+(UINT16)(cpustate->eo+offs), val)
|
||||
|
||||
#define PutImmRMWord(ModRM) \
|
||||
{ \
|
||||
WORD val; \
|
||||
if (ModRM >= 0xc0) \
|
||||
FETCHWORD(cpustate->regs.w[Mod_RM.RM.w[ModRM]]) \
|
||||
else { \
|
||||
(*GetEA[ModRM])(cpustate); \
|
||||
i80286_check_permission(cpustate, cpustate->ea_seg, cpustate->eo, I80286_WORD, I80286_WRITE); \
|
||||
FETCHWORD(val) \
|
||||
WriteWord( cpustate->ea , val); \
|
||||
} \
|
||||
}
|
||||
|
||||
#define GetRMByte(ModRM) \
|
||||
((ModRM) >= 0xc0 ? cpustate->regs.b[Mod_RM.RM.b[ModRM]] : ( (*GetEA[ModRM])(cpustate), i80286_check_permission(cpustate, cpustate->ea_seg, cpustate->eo, I80286_BYTE, I80286_READ), ReadByte( cpustate->ea )) )
|
||||
|
||||
#define PutRMByte(ModRM,val) \
|
||||
{ \
|
||||
if (ModRM >= 0xc0) \
|
||||
cpustate->regs.b[Mod_RM.RM.b[ModRM]]=val; \
|
||||
else \
|
||||
{ \
|
||||
(*GetEA[ModRM])(cpustate); \
|
||||
i80286_check_permission(cpustate, cpustate->ea_seg, cpustate->eo, I80286_BYTE, I80286_WRITE); \
|
||||
WriteByte( cpustate->ea,val); \
|
||||
} \
|
||||
}
|
||||
|
||||
#define PutImmRMByte(ModRM) \
|
||||
{ \
|
||||
if (ModRM >= 0xc0) \
|
||||
cpustate->regs.b[Mod_RM.RM.b[ModRM]]=FETCH; \
|
||||
else { \
|
||||
(*GetEA[ModRM])(cpustate); \
|
||||
i80286_check_permission(cpustate, cpustate->ea_seg, cpustate->eo, I80286_BYTE, I80286_WRITE); \
|
||||
WriteByte( cpustate->ea , FETCH ); \
|
||||
} \
|
||||
}
|
||||
|
||||
#define PutbackRMByte(ModRM,val) \
|
||||
{ \
|
||||
if (ModRM >= 0xc0) \
|
||||
cpustate->regs.b[Mod_RM.RM.b[ModRM]]=val; \
|
||||
else \
|
||||
{ \
|
||||
i80286_check_permission(cpustate, cpustate->ea_seg, cpustate->eo, I80286_BYTE, I80286_WRITE); \
|
||||
WriteByte(cpustate->ea,val); \
|
||||
} \
|
||||
}
|
||||
|
||||
#define DEF_br8(dst,src) \
|
||||
unsigned ModRM = FETCHOP; \
|
||||
unsigned src = RegByte(ModRM); \
|
||||
unsigned dst = GetRMByte(ModRM)
|
||||
|
||||
#define DEF_wr16(dst,src) \
|
||||
unsigned ModRM = FETCHOP; \
|
||||
unsigned src = RegWord(ModRM); \
|
||||
unsigned dst = GetRMWord(ModRM)
|
||||
|
||||
#define DEF_r8b(dst,src) \
|
||||
unsigned ModRM = FETCHOP; \
|
||||
unsigned dst = RegByte(ModRM); \
|
||||
unsigned src = GetRMByte(ModRM)
|
||||
|
||||
#define DEF_r16w(dst,src) \
|
||||
unsigned ModRM = FETCHOP; \
|
||||
unsigned dst = RegWord(ModRM); \
|
||||
unsigned src = GetRMWord(ModRM)
|
||||
|
||||
#define DEF_ald8(dst,src) \
|
||||
unsigned src = FETCHOP; \
|
||||
unsigned dst = cpustate->regs.b[AL]
|
||||
|
||||
#define DEF_axd16(dst,src) \
|
||||
unsigned src = FETCHOP; \
|
||||
unsigned dst = cpustate->regs.w[AX]; \
|
||||
src += (FETCH << 8)
|
Loading…
Reference in New Issue
Block a user