mirror of
https://github.com/holub/mame
synced 2025-04-21 07:52:35 +03:00
i286 - More protected mode fixes by Carl (no whatsnew)
This commit is contained in:
parent
8f7dba221c
commit
d96852828b
@ -170,6 +170,7 @@ static CPU_RESET( i80286 )
|
||||
cpustate->ldtr.rights=cpustate->tr.rights=0;
|
||||
cpustate->ldtr.sel=cpustate->tr.sel=0;
|
||||
cpustate->rep_in_progress = FALSE;
|
||||
cpustate->seg_prefix = FALSE;
|
||||
|
||||
CHANGE_PC(cpustate->pc);
|
||||
|
||||
@ -239,10 +240,12 @@ static CPU_EXECUTE( i80286 )
|
||||
debugger_instruction_hook(device, cpustate->pc);
|
||||
|
||||
cpustate->seg_prefix=FALSE;
|
||||
cpustate->prevpc = cpustate->pc;
|
||||
|
||||
try
|
||||
{
|
||||
if (PM && ((cpustate->pc-cpustate->base[CS]) > cpustate->limit[CS]))
|
||||
throw TRAP(GENERAL_PROTECTION_FAULT, cpustate->sregs[CS] & ~3);
|
||||
cpustate->prevpc = cpustate->pc;
|
||||
|
||||
TABLE286 // call instruction
|
||||
}
|
||||
catch (UINT32 e)
|
||||
|
@ -248,7 +248,6 @@ static void i80286_code_descriptor(i80286_state *cpustate,UINT16 selector, UINT1
|
||||
if (!IDX(gatesel)||(gatesel>cpustate->gdtr.limit)) throw TRAP(GENERAL_PROTECTION_FAULT,IDXTBL(gatesel));
|
||||
addr = cpustate->gdtr.base+IDX(gatesel);
|
||||
}
|
||||
addr = cpustate->gdtr.base+IDX(gatesel);
|
||||
gatedesc[0] = ReadWord(addr);
|
||||
gatedesc[1] = ReadWord(addr+2);
|
||||
gatedesc[2] = ReadWord(addr+4);
|
||||
@ -260,8 +259,10 @@ static void i80286_code_descriptor(i80286_state *cpustate,UINT16 selector, UINT1
|
||||
|
||||
if (!CONF(r)&&(DPL(r)<CPL)) { // inner call
|
||||
UINT16 ssdesc[3];
|
||||
UINT16 tss_ss,tss_sp, oldss, oldsp;
|
||||
int oldsp_phy, ssr, i;
|
||||
UINT16 tss_ss, tss_sp, oldss, oldsp;
|
||||
UINT32 oldstk;
|
||||
UINT8 ssr;
|
||||
int i;
|
||||
if(gate == 1) throw TRAP(GENERAL_PROTECTION_FAULT,IDXTBL(gatesel)); // can't jmp to inner
|
||||
tss_ss = ReadWord(cpustate->tr.base+TSS_SS0+(DPL(r)*4));
|
||||
tss_sp = ReadWord(cpustate->tr.base+TSS_SP0+(DPL(r)*4));
|
||||
@ -278,19 +279,20 @@ static void i80286_code_descriptor(i80286_state *cpustate,UINT16 selector, UINT1
|
||||
ssdesc[1] = ReadWord(addr+2);
|
||||
ssdesc[2] = ReadWord(addr+4);
|
||||
ssr = RIGHTS(ssdesc);
|
||||
if ((RPL(tss_ss) != DPL(r)) || DPL(ssr) != DPL(r)) TRAP(INVALID_TSS,IDXTBL(tss_ss));
|
||||
if ((RPL(tss_ss) != DPL(r)) || (DPL(ssr) != DPL(r))) TRAP(INVALID_TSS,IDXTBL(tss_ss));
|
||||
if (!RW(ssr) || !PRES(ssr)) throw TRAP(INVALID_TSS,IDXTBL(tss_ss));
|
||||
oldss = cpustate->sregs[SS];
|
||||
oldsp = cpustate->regs.w[SP];
|
||||
oldsp_phy = cpustate->base[SS]+oldsp+(GATECNT(desc)*2);
|
||||
oldstk = cpustate->base[SS]+oldsp;
|
||||
cpustate->sregs[SS]=tss_ss;
|
||||
cpustate->limit[SS]=LIMIT(ssdesc);
|
||||
cpustate->base[SS]=BASE(ssdesc);
|
||||
cpustate->rights[SS]=RIGHTS(ssdesc);
|
||||
cpustate->regs.w[SP] = tss_sp;
|
||||
PUSH(oldss);
|
||||
PUSH(oldsp);
|
||||
for (i = 0; i < GATECNT(desc); i++)
|
||||
PUSH(ReadWord(oldsp_phy-(i*2)));
|
||||
for (i = GATECNT(desc)-1; i >= 0; i--)
|
||||
PUSH(ReadWord(oldstk+(i*2)));
|
||||
}
|
||||
cpustate->sregs[CS]=IDXTBL(gatesel) | DPL(r);
|
||||
cpustate->limit[CS]=LIMIT(gatedesc);
|
||||
@ -384,6 +386,7 @@ static void i80286_interrupt_descriptor(i80286_state *cpustate,UINT16 number, in
|
||||
cpustate->limit[SS]=LIMIT(ssdesc);
|
||||
cpustate->base[SS]=BASE(ssdesc);
|
||||
cpustate->rights[SS]=RIGHTS(ssdesc);
|
||||
cpustate->regs.w[SP] = tss_sp;
|
||||
PUSH(oldss);
|
||||
PUSH(oldsp);
|
||||
}
|
||||
@ -479,7 +482,7 @@ static void PREFIX286(_0fpre)(i8086_state *cpustate)
|
||||
cpustate->ZeroVal=0;
|
||||
else if (CODE(r) && CONF(r))
|
||||
cpustate->ZeroVal=1;
|
||||
else if ((DPL(r)<CPL) || (DPL(r)<RPL(tmp)))
|
||||
else if (DPL(r)<PMAX(CPL,RPL(tmp)))
|
||||
cpustate->ZeroVal=0;
|
||||
else cpustate->ZeroVal=1;
|
||||
}
|
||||
@ -498,7 +501,7 @@ static void PREFIX286(_0fpre)(i8086_state *cpustate)
|
||||
r = RIGHTS(desc);
|
||||
if (!SEGDESC(r) || CODE(r))
|
||||
cpustate->ZeroVal=0;
|
||||
else if ((DPL(r)<CPL) || (DPL(r)<RPL(tmp)))
|
||||
else if (DPL(r)<PMAX(CPL,RPL(tmp)))
|
||||
cpustate->ZeroVal=0;
|
||||
else cpustate->ZeroVal=1;
|
||||
}
|
||||
@ -539,7 +542,7 @@ static void PREFIX286(_0fpre)(i8086_state *cpustate)
|
||||
case 0x30: /* lmsw */
|
||||
if (PM&&(CPL!=0)) throw TRAP(GENERAL_PROTECTION_FAULT,0);
|
||||
msw = GetRMWord(ModRM);
|
||||
if (!PM&(msw&1)) cpustate->sregs[CS] = IDX(cpustate->sregs[CS]); // cheat and set cpl to 0
|
||||
if (!PM&&(msw&1)) cpustate->sregs[CS] = IDX(cpustate->sregs[CS]); // cheat and set cpl to 0
|
||||
cpustate->msw=(cpustate->msw&1)|msw;
|
||||
break;
|
||||
default:
|
||||
@ -619,7 +622,7 @@ static void PREFIX286(_0fpre)(i8086_state *cpustate)
|
||||
|
||||
case 6: /* clts */
|
||||
if (PM&&(CPL!=0)) throw TRAP(GENERAL_PROTECTION_FAULT,0);
|
||||
cpustate->msw=~8;
|
||||
cpustate->msw&=~8;
|
||||
break;
|
||||
default:
|
||||
throw TRAP(ILLEGAL_INSTRUCTION,-1);
|
||||
|
@ -435,6 +435,9 @@ static void PREFIX(rep)(i8086_state *cpustate,int flagval)
|
||||
break;
|
||||
#ifndef I8086
|
||||
case 0x6c: /* REP INSB */
|
||||
#ifdef I80286
|
||||
if (PM && (CPL>IOPL)) throw TRAP(GENERAL_PROTECTION_FAULT, 0);
|
||||
#endif
|
||||
if (!cpustate->rep_in_progress)
|
||||
ICOUNT -= timing.rep_ins8_base;
|
||||
cpustate->rep_in_progress = FALSE;
|
||||
@ -448,6 +451,9 @@ static void PREFIX(rep)(i8086_state *cpustate,int flagval)
|
||||
cpustate->regs.w[CX]=count;
|
||||
break;
|
||||
case 0x6d: /* REP INSW */
|
||||
#ifdef I80286
|
||||
if (PM && (CPL>IOPL)) throw TRAP(GENERAL_PROTECTION_FAULT, 0);
|
||||
#endif
|
||||
if (!cpustate->rep_in_progress)
|
||||
ICOUNT -= timing.rep_ins16_base;
|
||||
cpustate->rep_in_progress = FALSE;
|
||||
@ -461,6 +467,9 @@ static void PREFIX(rep)(i8086_state *cpustate,int flagval)
|
||||
cpustate->regs.w[CX]=count;
|
||||
break;
|
||||
case 0x6e: /* REP OUTSB */
|
||||
#ifdef I80286
|
||||
if (PM && (CPL>IOPL)) throw TRAP(GENERAL_PROTECTION_FAULT, 0);
|
||||
#endif
|
||||
if (!cpustate->rep_in_progress)
|
||||
ICOUNT -= timing.rep_outs8_base;
|
||||
cpustate->rep_in_progress = FALSE;
|
||||
@ -474,6 +483,9 @@ static void PREFIX(rep)(i8086_state *cpustate,int flagval)
|
||||
cpustate->regs.w[CX]=count;
|
||||
break;
|
||||
case 0x6f: /* REP OUTSW */
|
||||
#ifdef I80286
|
||||
if (PM && (CPL>IOPL)) throw TRAP(GENERAL_PROTECTION_FAULT, 0);
|
||||
#endif
|
||||
if (!cpustate->rep_in_progress)
|
||||
ICOUNT -= timing.rep_outs16_base;
|
||||
cpustate->rep_in_progress = FALSE;
|
||||
@ -2519,7 +2531,11 @@ static void PREFIX86(_jcxz)(i8086_state *cpustate) /* Opcode 0xe3 */
|
||||
|
||||
static void PREFIX86(_inal)(i8086_state *cpustate) /* Opcode 0xe4 */
|
||||
{
|
||||
unsigned port = FETCH;
|
||||
unsigned port;
|
||||
#ifdef I80286
|
||||
if (PM && (CPL>IOPL)) throw TRAP(GENERAL_PROTECTION_FAULT, 0);
|
||||
#endif
|
||||
port = FETCH;
|
||||
|
||||
ICOUNT -= timing.in_imm8;
|
||||
cpustate->regs.b[AL] = read_port_byte(port);
|
||||
@ -2527,7 +2543,11 @@ static void PREFIX86(_inal)(i8086_state *cpustate) /* Opcode 0xe4 */
|
||||
|
||||
static void PREFIX86(_inax)(i8086_state *cpustate) /* Opcode 0xe5 */
|
||||
{
|
||||
unsigned port = FETCH;
|
||||
unsigned port;
|
||||
#ifdef I80286
|
||||
if (PM && (CPL>IOPL)) throw TRAP(GENERAL_PROTECTION_FAULT, 0);
|
||||
#endif
|
||||
port = FETCH;
|
||||
|
||||
ICOUNT -= timing.in_imm16;
|
||||
cpustate->regs.w[AX] = read_port_word(port);
|
||||
@ -2535,7 +2555,11 @@ static void PREFIX86(_inax)(i8086_state *cpustate) /* Opcode 0xe5 */
|
||||
|
||||
static void PREFIX86(_outal)(i8086_state *cpustate) /* Opcode 0xe6 */
|
||||
{
|
||||
unsigned port = FETCH;
|
||||
unsigned port;
|
||||
#ifdef I80286
|
||||
if (PM && (CPL>IOPL)) throw TRAP(GENERAL_PROTECTION_FAULT, 0);
|
||||
#endif
|
||||
port = FETCH;
|
||||
|
||||
ICOUNT -= timing.out_imm8;
|
||||
write_port_byte(port, cpustate->regs.b[AL]);
|
||||
@ -2543,7 +2567,11 @@ static void PREFIX86(_outal)(i8086_state *cpustate) /* Opcode 0xe6 */
|
||||
|
||||
static void PREFIX86(_outax)(i8086_state *cpustate) /* Opcode 0xe7 */
|
||||
{
|
||||
unsigned port = FETCH;
|
||||
unsigned port;
|
||||
#ifdef I80286
|
||||
if (PM && (CPL>IOPL)) throw TRAP(GENERAL_PROTECTION_FAULT, 0);
|
||||
#endif
|
||||
port = FETCH;
|
||||
|
||||
ICOUNT -= timing.out_imm16;
|
||||
write_port_word(port, cpustate->regs.w[AX]);
|
||||
@ -2605,6 +2633,9 @@ static void PREFIX86(_jmp_d8)(i8086_state *cpustate) /* Opcode 0xeb */
|
||||
|
||||
static void PREFIX86(_inaldx)(i8086_state *cpustate) /* Opcode 0xec */
|
||||
{
|
||||
#ifdef I80286
|
||||
if (PM && (CPL>IOPL)) throw TRAP(GENERAL_PROTECTION_FAULT, 0);
|
||||
#endif
|
||||
ICOUNT -= timing.in_dx8;
|
||||
cpustate->regs.b[AL] = read_port_byte(cpustate->regs.w[DX]);
|
||||
}
|
||||
@ -2612,13 +2643,18 @@ static void PREFIX86(_inaldx)(i8086_state *cpustate) /* Opcode 0xec */
|
||||
static void PREFIX86(_inaxdx)(i8086_state *cpustate) /* Opcode 0xed */
|
||||
{
|
||||
unsigned port = cpustate->regs.w[DX];
|
||||
|
||||
#ifdef I80286
|
||||
if (PM && (CPL>IOPL)) throw TRAP(GENERAL_PROTECTION_FAULT, 0);
|
||||
#endif
|
||||
ICOUNT -= timing.in_dx16;
|
||||
cpustate->regs.w[AX] = read_port_word(port);
|
||||
}
|
||||
|
||||
static void PREFIX86(_outdxal)(i8086_state *cpustate) /* Opcode 0xee */
|
||||
{
|
||||
#ifdef I80286
|
||||
if (PM && (CPL>IOPL)) throw TRAP(GENERAL_PROTECTION_FAULT, 0);
|
||||
#endif
|
||||
ICOUNT -= timing.out_dx8;
|
||||
write_port_byte(cpustate->regs.w[DX], cpustate->regs.b[AL]);
|
||||
}
|
||||
@ -2626,7 +2662,9 @@ static void PREFIX86(_outdxal)(i8086_state *cpustate) /* Opcode 0xee */
|
||||
static void PREFIX86(_outdxax)(i8086_state *cpustate) /* Opcode 0xef */
|
||||
{
|
||||
unsigned port = cpustate->regs.w[DX];
|
||||
|
||||
#ifdef I80286
|
||||
if (PM && (CPL>IOPL)) throw TRAP(GENERAL_PROTECTION_FAULT, 0);
|
||||
#endif
|
||||
ICOUNT -= timing.out_dx16;
|
||||
write_port_word(port, cpustate->regs.w[AX]);
|
||||
}
|
||||
@ -2634,6 +2672,9 @@ static void PREFIX86(_outdxax)(i8086_state *cpustate) /* Opcode 0xef */
|
||||
/* I think thats not a V20 instruction...*/
|
||||
static void PREFIX86(_lock)(i8086_state *cpustate) /* Opcode 0xf0 */
|
||||
{
|
||||
#ifdef I80286
|
||||
if(PM && (CPL>IOPL)) throw TRAP(GENERAL_PROTECTION_FAULT,0);
|
||||
#endif
|
||||
ICOUNT -= timing.nop;
|
||||
PREFIX(_instruction)[FETCHOP](cpustate); /* un-interruptible */
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user