cpu updates (privileged instructions, trapflag handling)
Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2275
This commit is contained in:
parent
85850ccc22
commit
b48eceebe7
12 changed files with 1352 additions and 109 deletions
|
@ -49,8 +49,8 @@ Bits CPU_Core_Dyn_X86_Run(void);
|
|||
|
||||
extern Bit16u parity_lookup[256];
|
||||
|
||||
void CPU_LLDT(Bitu selector);
|
||||
void CPU_LTR(Bitu selector);
|
||||
bool CPU_LLDT(Bitu selector);
|
||||
bool CPU_LTR(Bitu selector);
|
||||
void CPU_LIDT(Bitu limit,Bitu base);
|
||||
void CPU_LGDT(Bitu limit,Bitu base);
|
||||
|
||||
|
@ -68,6 +68,9 @@ bool CPU_WRITE_CRX(Bitu cr,Bitu value);
|
|||
Bitu CPU_GET_CRX(Bitu cr);
|
||||
bool CPU_READ_CRX(Bitu cr,Bit32u & retvalue);
|
||||
|
||||
bool CPU_WRITE_DRX(Bitu dr,Bitu value);
|
||||
bool CPU_READ_DRX(Bitu dr,Bit32u & retvalue);
|
||||
|
||||
void CPU_SMSW(Bitu & word);
|
||||
Bitu CPU_LMSW(Bitu word);
|
||||
|
||||
|
@ -93,6 +96,7 @@ void CPU_ENTER(bool use32,Bitu bytes,Bitu level);
|
|||
#define CPU_INT_SOFTWARE 0x1
|
||||
#define CPU_INT_EXCEPTION 0x2
|
||||
#define CPU_INT_HAS_ERROR 0x4
|
||||
#define CPU_INT_NOIOPLCHECK 0x8
|
||||
|
||||
void CPU_Interrupt(Bitu num,Bitu type,Bitu oldeip);
|
||||
INLINE void CPU_HW_Interrupt(Bitu num) {
|
||||
|
@ -101,6 +105,9 @@ INLINE void CPU_HW_Interrupt(Bitu num) {
|
|||
INLINE void CPU_SW_Interrupt(Bitu num,Bitu oldeip) {
|
||||
CPU_Interrupt(num,CPU_INT_SOFTWARE,oldeip);
|
||||
}
|
||||
INLINE void CPU_SW_Interrupt_NoIOPLCheck(Bitu num,Bitu oldeip) {
|
||||
CPU_Interrupt(num,CPU_INT_SOFTWARE|CPU_INT_NOIOPLCHECK,oldeip);
|
||||
}
|
||||
|
||||
bool CPU_PrepareException(Bitu which,Bitu error);
|
||||
void CPU_Exception(Bitu which,Bitu error=0);
|
||||
|
@ -116,18 +123,25 @@ void CPU_Push32(Bitu value);
|
|||
|
||||
void CPU_SetFlags(Bitu word,Bitu mask);
|
||||
|
||||
|
||||
#define EXCEPTION_UD 6
|
||||
#define EXCEPTION_TS 10
|
||||
#define EXCEPTION_NP 11
|
||||
#define EXCEPTION_SS 12
|
||||
#define EXCEPTION_GP 13
|
||||
|
||||
#define CR0_PROTECTION 0x00000001
|
||||
#define CR0_MONITORPROCESSOR 0x00000002
|
||||
#define CR0_FPUEMULATION 0x00000004
|
||||
#define CR0_TASKSWITCH 0x00000008
|
||||
#define CR0_FPUPRESENT 0x00000010
|
||||
#define CR0_PAGING 0x80000000
|
||||
|
||||
|
||||
// *********************************************************************
|
||||
// Descriptor
|
||||
// *********************************************************************
|
||||
|
||||
#define CR0_PROTECTION 0x00000001
|
||||
#define CR0_FPUENABLED 0x00000002
|
||||
#define CR0_FPUMONITOR 0x00000004
|
||||
#define CR0_TASKSWITCH 0x00000008
|
||||
#define CR0_FPUPRESENT 0x00000010
|
||||
#define CR0_PAGING 0x80000000
|
||||
|
||||
|
||||
#define DESC_INVALID 0x00
|
||||
#define DESC_286_TSS_A 0x01
|
||||
#define DESC_LDT 0x02
|
||||
|
@ -360,9 +374,16 @@ public:
|
|||
return ldt_value;
|
||||
}
|
||||
bool LLDT(Bitu value) {
|
||||
//TODO checking
|
||||
if ((value&0xfffc)==0) {
|
||||
ldt_value=0;
|
||||
ldt_base=0;
|
||||
ldt_limit=0;
|
||||
return true;
|
||||
}
|
||||
Descriptor desc;
|
||||
GetDescriptor(value,desc);
|
||||
if (!GetDescriptor(value,desc)) return !CPU_PrepareException(EXCEPTION_GP,value);
|
||||
if (desc.Type()!=DESC_LDT) return !CPU_PrepareException(EXCEPTION_GP,value);
|
||||
if (!desc.saved.seg.p) return !CPU_PrepareException(EXCEPTION_NP,value);
|
||||
ldt_base=desc.GetBase();
|
||||
ldt_limit=desc.GetLimit();
|
||||
ldt_value=value;
|
||||
|
@ -410,6 +431,7 @@ struct CPUBlock {
|
|||
Bitu which,error;
|
||||
} exception;
|
||||
Bits direction;
|
||||
Bit32u drx[8];
|
||||
};
|
||||
|
||||
extern CPUBlock cpu;
|
||||
|
|
|
@ -472,12 +472,18 @@ l_M_Ed:
|
|||
CPU_CPUID();
|
||||
goto nextopcode;
|
||||
case D_HLT:
|
||||
if (cpu.pmode && cpu.cpl) EXCEPTION(EXCEPTION_GP);
|
||||
FillFlags();
|
||||
CPU_HLT(GetIP());
|
||||
return CBRET_NONE;
|
||||
case D_CLTS:
|
||||
//TODO Really clear it sometime
|
||||
if (cpu.pmode && cpu.cpl) goto illegalopcode;
|
||||
cpu.cr0&=(~CR0_TASKSWITCH);
|
||||
goto nextopcode;
|
||||
case D_ICEBP:
|
||||
FillFlags();
|
||||
CPU_SW_Interrupt_NoIOPLCheck(1,GetIP());
|
||||
continue;
|
||||
default:
|
||||
LOG(LOG_CPU,LOG_ERROR)("LOAD:Unhandled code %d opcode %X",inst.code.load,inst.entry);
|
||||
goto illegalopcode;
|
||||
|
|
|
@ -376,6 +376,7 @@ switch (inst.code.op) {
|
|||
return inst.op1.d;
|
||||
case O_GRP6w:
|
||||
case O_GRP6d:
|
||||
if ((reg_flags & FLAG_VM) || (!cpu.pmode)) goto illegalopcode;
|
||||
switch (inst.rm_index) {
|
||||
case 0x00: /* SLDT */
|
||||
{
|
||||
|
@ -392,10 +393,12 @@ switch (inst.code.op) {
|
|||
}
|
||||
break;
|
||||
case 0x02: /* LLDT */
|
||||
CPU_LLDT(inst.op1.d);
|
||||
if (cpu.cpl) EXCEPTION(EXCEPTION_GP);
|
||||
if (CPU_LLDT(inst.op1.d)) RunException();
|
||||
goto nextopcode; /* Else value will saved */
|
||||
case 0x03: /* LTR */
|
||||
CPU_LTR(inst.op1.d);
|
||||
if (cpu.cpl) EXCEPTION(EXCEPTION_GP);
|
||||
if (CPU_LTR(inst.op1.d)) RunException();
|
||||
goto nextopcode; /* Else value will saved */
|
||||
case 0x04: /* VERR */
|
||||
FillFlags();
|
||||
|
@ -407,6 +410,7 @@ switch (inst.code.op) {
|
|||
goto nextopcode; /* Else value will saved */
|
||||
default:
|
||||
LOG(LOG_CPU,LOG_ERROR)("Group 6 Illegal subfunction %X",inst.rm_index);
|
||||
goto illegalopcode;
|
||||
}
|
||||
break;
|
||||
case O_GRP7w:
|
||||
|
@ -429,9 +433,11 @@ switch (inst.code.op) {
|
|||
goto nextopcode;
|
||||
}
|
||||
case 2: /* LGDT */
|
||||
if (cpu.pmode && cpu.cpl) EXCEPTION(EXCEPTION_GP);
|
||||
CPU_LGDT(LoadMw(inst.rm_eaa),LoadMd(inst.rm_eaa+2)&((inst.code.op == O_GRP7w) ? 0xFFFFFF : 0xFFFFFFFF));
|
||||
goto nextopcode;
|
||||
case 3: /* LIDT */
|
||||
if (cpu.pmode && cpu.cpl) EXCEPTION(EXCEPTION_GP);
|
||||
CPU_LIDT(LoadMw(inst.rm_eaa),LoadMd(inst.rm_eaa+2)&((inst.code.op == O_GRP7w) ? 0xFFFFFF : 0xFFFFFFFF));
|
||||
goto nextopcode;
|
||||
case 4: /* SMSW */
|
||||
|
@ -446,6 +452,7 @@ switch (inst.code.op) {
|
|||
goto nextopcode;
|
||||
default:
|
||||
LOG(LOG_CPU,LOG_ERROR)("Group 7 Illegal subfunction %X",inst.rm_index);
|
||||
goto illegalopcode;
|
||||
}
|
||||
break;
|
||||
case O_M_CRx_Rd:
|
||||
|
@ -455,14 +462,14 @@ switch (inst.code.op) {
|
|||
if (CPU_READ_CRX(inst.rm_index,inst.op1.d)) RunException();
|
||||
break;
|
||||
case O_M_DRx_Rd:
|
||||
// LOG(LOG_CPU,LOG_NORMAL)("MOV DR%d,%X",inst.rm_index,inst.op1.d);
|
||||
if (CPU_WRITE_DRX(inst.rm_index,inst.op1.d)) RunException();
|
||||
break;
|
||||
case O_M_Rd_DRx:
|
||||
inst.op1.d=0;
|
||||
// LOG(LOG_CPU,LOG_NORMAL)("MOV %X,DR%d",inst.op1.d,inst.rm_index);
|
||||
if (CPU_READ_DRX(inst.rm_index,inst.op1.d)) RunException();
|
||||
break;
|
||||
case O_LAR:
|
||||
{
|
||||
if ((reg_flags & FLAG_VM) || (!cpu.pmode)) goto illegalopcode;
|
||||
FillFlags();
|
||||
Bitu ar=inst.op2.d;
|
||||
CPU_LAR(inst.op1.w,ar);
|
||||
|
@ -471,6 +478,7 @@ switch (inst.code.op) {
|
|||
break;
|
||||
case O_LSL:
|
||||
{
|
||||
if ((reg_flags & FLAG_VM) || (!cpu.pmode)) goto illegalopcode;
|
||||
FillFlags();
|
||||
Bitu limit=inst.op2.d;
|
||||
CPU_LSL(inst.op1.w,limit);
|
||||
|
|
|
@ -171,7 +171,7 @@ static OpCode OpCodeTable[1024]={
|
|||
{L_REGw ,O_OUTb ,0 ,REGI_DX},{L_REGw ,O_OUTw ,0 ,REGI_DX},
|
||||
|
||||
/* 0xf0 - 0xf7 */
|
||||
{D_LOCK ,0 ,0 ,0 },{0 ,0 ,0 ,0 },
|
||||
{D_LOCK ,0 ,0 ,0 },{D_ICEBP ,0 ,0 ,0 },
|
||||
{L_PREREPNE ,0 ,0 ,0 },{L_PREREP ,0 ,0 ,0 },
|
||||
{D_HLT ,0 ,0 ,0 },{D_CMC ,0 ,0 ,0 },
|
||||
{L_MODRM ,8 ,0 ,M_GRP },{L_MODRM ,9 ,0 ,M_GRP },
|
||||
|
@ -526,7 +526,7 @@ static OpCode OpCodeTable[1024]={
|
|||
{L_REGw ,O_OUTb ,0 ,REGI_DX},{L_REGw ,O_OUTd ,0 ,REGI_DX},
|
||||
|
||||
/* 0x2f0 - 0x2f7 */
|
||||
{D_LOCK ,0 ,0 ,0 },{0 ,0 ,0 ,0 },
|
||||
{D_LOCK ,0 ,0 ,0 },{D_ICEBP ,0 ,0 ,0 },
|
||||
{L_PREREPNE ,0 ,0 ,0 },{L_PREREP ,0 ,0 ,0 },
|
||||
{0 ,0 ,0 ,0 },{D_CMC ,0 ,0 ,0 },
|
||||
{L_MODRM ,8 ,0 ,M_GRP },{L_MODRM ,0xa ,0 ,M_GRP },
|
||||
|
|
|
@ -45,7 +45,7 @@ enum {
|
|||
D_SAHF,D_LAHF,
|
||||
D_CPUID,
|
||||
D_HLT,D_CLTS,
|
||||
D_LOCK,
|
||||
D_LOCK,D_ICEBP,
|
||||
L_ERROR,
|
||||
};
|
||||
|
||||
|
|
|
@ -188,13 +188,12 @@ decode_end:
|
|||
}
|
||||
|
||||
Bits CPU_Core_Normal_Trap_Run(void) {
|
||||
|
||||
Bits oldCycles = CPU_Cycles;
|
||||
CPU_Cycles = 1;
|
||||
core.trap.skip=false;
|
||||
|
||||
Bits ret=CPU_Core_Normal_Run();
|
||||
if (!core.trap.skip) CPU_SW_Interrupt(1,reg_eip);
|
||||
if (!core.trap.skip) CPU_HW_Interrupt(1);
|
||||
CPU_Cycles = oldCycles-1;
|
||||
cpudecoder = &CPU_Core_Normal_Run;
|
||||
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
|
||||
CASE_0F_W(0x00) /* GRP 6 Exxx */
|
||||
{
|
||||
if ((reg_flags & FLAG_VM) || (!cpu.pmode)) goto illegal_opcode;
|
||||
GetRM;Bitu which=(rm>>3)&7;
|
||||
switch (which) {
|
||||
case 0x00: /* SLDT */
|
||||
|
@ -37,10 +38,20 @@
|
|||
if (rm >= 0xc0 ) {GetEArw;loadval=*earw;}
|
||||
else {GetEAa;loadval=LoadMw(eaa);}
|
||||
switch (which) {
|
||||
case 0x02:CPU_LLDT(loadval);break;
|
||||
case 0x03:CPU_LTR(loadval);break;
|
||||
case 0x04:CPU_VERR(loadval);break;
|
||||
case 0x05:CPU_VERW(loadval);break;
|
||||
case 0x02:
|
||||
if (cpu.cpl) EXCEPTION(EXCEPTION_GP);
|
||||
if (CPU_LLDT(loadval)) RUNEXCEPTION();
|
||||
break;
|
||||
case 0x03:
|
||||
if (cpu.cpl) EXCEPTION(EXCEPTION_GP);
|
||||
if (CPU_LTR(loadval)) RUNEXCEPTION();
|
||||
break;
|
||||
case 0x04:
|
||||
CPU_VERR(loadval);
|
||||
break;
|
||||
case 0x05:
|
||||
CPU_VERW(loadval);
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
@ -66,9 +77,11 @@
|
|||
SaveMd(eaa+2,base);
|
||||
break;
|
||||
case 0x02: /* LGDT */
|
||||
if (cpu.pmode && cpu.cpl) EXCEPTION(EXCEPTION_GP);
|
||||
CPU_LGDT(LoadMw(eaa),LoadMd(eaa+2) & 0xFFFFFF);
|
||||
break;
|
||||
case 0x03: /* LIDT */
|
||||
if (cpu.pmode && cpu.cpl) EXCEPTION(EXCEPTION_GP);
|
||||
CPU_LIDT(LoadMw(eaa),LoadMd(eaa+2) & 0xFFFFFF);
|
||||
break;
|
||||
case 0x04: /* SMSW */
|
||||
|
@ -83,6 +96,12 @@
|
|||
} else {
|
||||
GetEArw;Bitu limit;
|
||||
switch (which) {
|
||||
case 0x02: /* LGDT */
|
||||
if (cpu.pmode && cpu.cpl) EXCEPTION(EXCEPTION_GP);
|
||||
goto illegal_opcode;
|
||||
case 0x03: /* LIDT */
|
||||
if (cpu.pmode && cpu.cpl) EXCEPTION(EXCEPTION_GP);
|
||||
goto illegal_opcode;
|
||||
case 0x04: /* SMSW */
|
||||
CPU_SMSW(limit);
|
||||
*earw=limit;
|
||||
|
@ -98,6 +117,7 @@
|
|||
break;
|
||||
CASE_0F_W(0x02) /* LAR Gw,Ew */
|
||||
{
|
||||
if ((reg_flags & FLAG_VM) || (!cpu.pmode)) goto illegal_opcode;
|
||||
FillFlags();
|
||||
GetRMrw;Bitu ar=*rmrw;
|
||||
if (rm >= 0xc0) {
|
||||
|
@ -110,6 +130,7 @@
|
|||
break;
|
||||
CASE_0F_W(0x03) /* LSL Gw,Ew */
|
||||
{
|
||||
if ((reg_flags & FLAG_VM) || (!cpu.pmode)) goto illegal_opcode;
|
||||
FillFlags();
|
||||
GetRMrw;Bitu limit=*rmrw;
|
||||
if (rm >= 0xc0) {
|
||||
|
@ -121,54 +142,59 @@
|
|||
}
|
||||
break;
|
||||
CASE_0F_B(0x06) /* CLTS */
|
||||
if (cpu.pmode && cpu.cpl) EXCEPTION(EXCEPTION_GP);
|
||||
cpu.cr0&=(~CR0_TASKSWITCH);
|
||||
break;
|
||||
CASE_0F_B(0x20) /* MOV Rd.CRx */
|
||||
{
|
||||
GetRM;
|
||||
Bitu which=(rm >> 3) & 7;
|
||||
if (rm >= 0xc0 ) {
|
||||
GetEArd;
|
||||
Bit32u crx_value;
|
||||
if (CPU_READ_CRX(which,crx_value)) RUNEXCEPTION();
|
||||
*eard=crx_value;
|
||||
} else {
|
||||
GetEAa;
|
||||
if (rm < 0xc0 ) {
|
||||
rm |= 0xc0;
|
||||
LOG(LOG_CPU,LOG_ERROR)("MOV XXX,CR%d with non-register",which);
|
||||
}
|
||||
GetEArd;
|
||||
Bit32u crx_value;
|
||||
if (CPU_READ_CRX(which,crx_value)) RUNEXCEPTION();
|
||||
*eard=crx_value;
|
||||
}
|
||||
break;
|
||||
CASE_0F_B(0x21) /* MOV Rd,DRx */
|
||||
{
|
||||
GetRM;
|
||||
Bitu which=(rm >> 3) & 7;
|
||||
if (rm >= 0xc0 ) {
|
||||
GetEArd;
|
||||
} else {
|
||||
GetEAa;
|
||||
if (rm < 0xc0 ) {
|
||||
rm |= 0xc0;
|
||||
LOG(LOG_CPU,LOG_ERROR)("MOV XXX,DR% with non-register",which);
|
||||
}
|
||||
GetEArd;
|
||||
Bit32u drx_value;
|
||||
if (CPU_READ_DRX(which,drx_value)) RUNEXCEPTION();
|
||||
*eard=drx_value;
|
||||
}
|
||||
break;
|
||||
CASE_0F_B(0x22) /* MOV CRx,Rd */
|
||||
{
|
||||
GetRM;
|
||||
Bitu which=(rm >> 3) & 7;
|
||||
if (rm >= 0xc0 ) {
|
||||
GetEArd;
|
||||
if (CPU_WRITE_CRX(which,*eard)) RUNEXCEPTION();
|
||||
} else goto illegal_opcode;
|
||||
if (rm < 0xc0 ) {
|
||||
rm |= 0xc0;
|
||||
LOG(LOG_CPU,LOG_ERROR)("MOV XXX,CR% with non-register",which);
|
||||
}
|
||||
GetEArd;
|
||||
if (CPU_WRITE_CRX(which,*eard)) RUNEXCEPTION();
|
||||
}
|
||||
break;
|
||||
CASE_0F_B(0x23) /* MOV DRx,Rd */
|
||||
{
|
||||
GetRM;
|
||||
Bitu which=(rm >> 3) & 7;
|
||||
if (rm >= 0xc0 ) {
|
||||
GetEArd;
|
||||
} else {
|
||||
GetEAa;
|
||||
if (rm < 0xc0 ) {
|
||||
rm |= 0xc0;
|
||||
LOG(LOG_CPU,LOG_ERROR)("MOV DR%,XXX with non-register",which);
|
||||
}
|
||||
GetEArd;
|
||||
if (CPU_WRITE_DRX(which,*eard)) RUNEXCEPTION();
|
||||
}
|
||||
break;
|
||||
CASE_0F_W(0x80) /* JO */
|
||||
|
|
|
@ -331,8 +331,8 @@
|
|||
case 0x05: /* MOV Ew,GS */
|
||||
val=SegValue(gs);break;
|
||||
default:
|
||||
val=0;
|
||||
E_Exit("CPU:8c:Illegal RM Byte");
|
||||
LOG(LOG_CPU,LOG_ERROR)("CPU:8c:Illegal RM Byte");
|
||||
goto illegal_opcode;
|
||||
}
|
||||
if (rm >= 0xc0 ) {GetEArd;*eard=val;}
|
||||
else {GetEAa;SaveMw(eaa,val);}
|
||||
|
@ -389,6 +389,12 @@
|
|||
Bit32u newip=Fetchd();Bit16u newcs=Fetchw();
|
||||
FillFlags();
|
||||
CPU_CALL(true,newcs,newip,GETIP);
|
||||
#if CPU_TRAP_CHECK
|
||||
if (GETFLAG(TF)) {
|
||||
cpudecoder=CPU_Core_Normal_Trap_Run;
|
||||
return CBRET_NONE;
|
||||
}
|
||||
#endif
|
||||
continue;
|
||||
}
|
||||
CASE_D(0x9c) /* PUSHFD */
|
||||
|
@ -581,6 +587,12 @@
|
|||
Bit16u newcs=Fetchw();
|
||||
FillFlags();
|
||||
CPU_JMP(true,newcs,newip,GETIP);
|
||||
#if CPU_TRAP_CHECK
|
||||
if (GETFLAG(TF)) {
|
||||
cpudecoder=CPU_Core_Normal_Trap_Run;
|
||||
return CBRET_NONE;
|
||||
}
|
||||
#endif
|
||||
continue;
|
||||
}
|
||||
CASE_D(0xeb) /* JMP Jb */
|
||||
|
@ -657,11 +669,18 @@
|
|||
continue;
|
||||
case 0x03: /* CALL FAR Ed */
|
||||
{
|
||||
if (rm >= 0xc0) goto illegal_opcode;
|
||||
GetEAa;
|
||||
Bit32u newip=LoadMd(eaa);
|
||||
Bit16u newcs=LoadMw(eaa+4);
|
||||
FillFlags();
|
||||
CPU_CALL(true,newcs,newip,GETIP);
|
||||
#if CPU_TRAP_CHECK
|
||||
if (GETFLAG(TF)) {
|
||||
cpudecoder=CPU_Core_Normal_Trap_Run;
|
||||
return CBRET_NONE;
|
||||
}
|
||||
#endif
|
||||
continue;
|
||||
}
|
||||
case 0x04: /* JMP NEAR Ed */
|
||||
|
@ -670,11 +689,18 @@
|
|||
continue;
|
||||
case 0x05: /* JMP FAR Ed */
|
||||
{
|
||||
if (rm >= 0xc0) goto illegal_opcode;
|
||||
GetEAa;
|
||||
Bit32u newip=LoadMd(eaa);
|
||||
Bit16u newcs=LoadMw(eaa+4);
|
||||
FillFlags();
|
||||
CPU_JMP(true,newcs,newip,GETIP);
|
||||
#if CPU_TRAP_CHECK
|
||||
if (GETFLAG(TF)) {
|
||||
cpudecoder=CPU_Core_Normal_Trap_Run;
|
||||
return CBRET_NONE;
|
||||
}
|
||||
#endif
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
|
|
|
@ -15,8 +15,10 @@
|
|||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
CASE_0F_D(0x00) /* GRP 6 Exxx */
|
||||
{
|
||||
if ((reg_flags & FLAG_VM) || (!cpu.pmode)) goto illegal_opcode;
|
||||
GetRM;Bitu which=(rm>>3)&7;
|
||||
switch (which) {
|
||||
case 0x00: /* SLDT */
|
||||
|
@ -37,15 +39,26 @@
|
|||
if (rm >= 0xc0 ) {GetEArw;loadval=*earw;}
|
||||
else {GetEAa;loadval=LoadMw(eaa);}
|
||||
switch (which) {
|
||||
case 0x02:CPU_LLDT(loadval);break;
|
||||
case 0x03:CPU_LTR(loadval);break;
|
||||
case 0x04:CPU_VERR(loadval);break;
|
||||
case 0x05:CPU_VERW(loadval);break;
|
||||
case 0x02:
|
||||
if (cpu.cpl) EXCEPTION(EXCEPTION_GP);
|
||||
if (CPU_LLDT(loadval)) RUNEXCEPTION();
|
||||
break;
|
||||
case 0x03:
|
||||
if (cpu.cpl) EXCEPTION(EXCEPTION_GP);
|
||||
if (CPU_LTR(loadval)) RUNEXCEPTION();
|
||||
break;
|
||||
case 0x04:
|
||||
CPU_VERR(loadval);
|
||||
break;
|
||||
case 0x05:
|
||||
CPU_VERW(loadval);
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
LOG(LOG_CPU,LOG_ERROR)("GRP6:Illegal call %2X",which);
|
||||
goto illegal_opcode;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
@ -66,9 +79,11 @@
|
|||
SaveMd(eaa+2,(Bit32u)base);
|
||||
break;
|
||||
case 0x02: /* LGDT */
|
||||
if (cpu.pmode && cpu.cpl) EXCEPTION(EXCEPTION_GP);
|
||||
CPU_LGDT(LoadMw(eaa),LoadMd(eaa+2));
|
||||
break;
|
||||
case 0x03: /* LIDT */
|
||||
if (cpu.pmode && cpu.cpl) EXCEPTION(EXCEPTION_GP);
|
||||
CPU_LIDT(LoadMw(eaa),LoadMd(eaa+2));
|
||||
break;
|
||||
case 0x04: /* SMSW */
|
||||
|
@ -77,21 +92,28 @@
|
|||
break;
|
||||
case 0x06: /* LMSW */
|
||||
limit=LoadMw(eaa);
|
||||
if (!CPU_LMSW((Bit16u)limit)) goto decode_end;
|
||||
if (CPU_LMSW((Bit16u)limit)) RUNEXCEPTION();
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
GetEArd;Bitu limit;
|
||||
switch (which) {
|
||||
case 0x02: /* LGDT */
|
||||
if (cpu.pmode && cpu.cpl) EXCEPTION(EXCEPTION_GP);
|
||||
goto illegal_opcode;
|
||||
case 0x03: /* LIDT */
|
||||
if (cpu.pmode && cpu.cpl) EXCEPTION(EXCEPTION_GP);
|
||||
goto illegal_opcode;
|
||||
case 0x04: /* SMSW */
|
||||
CPU_SMSW(limit);
|
||||
*eard=(Bit32u)limit;
|
||||
break;
|
||||
case 0x06: /* LMSW */
|
||||
if (!CPU_LMSW(*eard)) goto decode_end;
|
||||
if (CPU_LMSW(*eard)) RUNEXCEPTION();
|
||||
break;
|
||||
default:
|
||||
LOG(LOG_CPU,LOG_ERROR)("Illegal group 7 RM subfunction %d",which);
|
||||
goto illegal_opcode;
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -100,6 +122,7 @@
|
|||
break;
|
||||
CASE_0F_D(0x02) /* LAR Gd,Ed */
|
||||
{
|
||||
if ((reg_flags & FLAG_VM) || (!cpu.pmode)) goto illegal_opcode;
|
||||
FillFlags();
|
||||
GetRMrd;Bitu ar=*rmrd;
|
||||
if (rm >= 0xc0) {
|
||||
|
@ -112,6 +135,7 @@
|
|||
break;
|
||||
CASE_0F_D(0x03) /* LSL Gd,Ew */
|
||||
{
|
||||
if ((reg_flags & FLAG_VM) || (!cpu.pmode)) goto illegal_opcode;
|
||||
FillFlags();
|
||||
GetRMrd;Bitu limit=*rmrd;
|
||||
/* Just load 16-bit values for selectors */
|
||||
|
|
|
@ -472,8 +472,8 @@
|
|||
case 0x05: /* MOV Ew,GS */
|
||||
val=SegValue(gs);break;
|
||||
default:
|
||||
val=0;
|
||||
E_Exit("CPU:8c:Illegal RM Byte");
|
||||
LOG(LOG_CPU,LOG_ERROR)("CPU:8c:Illegal RM Byte");
|
||||
goto illegal_opcode;
|
||||
}
|
||||
if (rm >= 0xc0 ) {GetEArw;*earw=val;}
|
||||
else {GetEAa;SaveMw(eaa,val);}
|
||||
|
@ -551,6 +551,12 @@
|
|||
FillFlags();
|
||||
Bit16u newip=Fetchw();Bit16u newcs=Fetchw();
|
||||
CPU_CALL(false,newcs,newip,GETIP);
|
||||
#if CPU_TRAP_CHECK
|
||||
if (GETFLAG(TF)) {
|
||||
cpudecoder=CPU_Core_Normal_Trap_Run;
|
||||
return CBRET_NONE;
|
||||
}
|
||||
#endif
|
||||
continue;
|
||||
}
|
||||
CASE_B(0x9b) /* WAIT */
|
||||
|
@ -727,7 +733,7 @@
|
|||
if (DEBUG_Breakpoint())
|
||||
return debugCallback;
|
||||
#endif
|
||||
CPU_SW_Interrupt(3,GETIP);
|
||||
CPU_SW_Interrupt_NoIOPLCheck(3,GETIP);
|
||||
#if CPU_TRAP_CHECK
|
||||
core.trap.skip=true;
|
||||
#endif
|
||||
|
@ -761,14 +767,14 @@
|
|||
{
|
||||
FillFlags();
|
||||
CPU_IRET(false,GETIP);
|
||||
#if CPU_PIC_CHECK
|
||||
if (GETFLAG(IF) && PIC_IRQCheck) return CBRET_NONE;
|
||||
#endif
|
||||
#if CPU_TRAP_CHECK
|
||||
if (GETFLAG(TF)) {
|
||||
cpudecoder=CPU_Core_Normal_Trap_Run;
|
||||
return CBRET_NONE;
|
||||
}
|
||||
#endif
|
||||
#if CPU_PIC_CHECK
|
||||
if (GETFLAG(IF) && PIC_IRQCheck) return CBRET_NONE;
|
||||
#endif
|
||||
continue;
|
||||
}
|
||||
|
@ -900,6 +906,12 @@
|
|||
Bit16u newcs=Fetchw();
|
||||
FillFlags();
|
||||
CPU_JMP(false,newcs,newip,GETIP);
|
||||
#if CPU_TRAP_CHECK
|
||||
if (GETFLAG(TF)) {
|
||||
cpudecoder=CPU_Core_Normal_Trap_Run;
|
||||
return CBRET_NONE;
|
||||
}
|
||||
#endif
|
||||
continue;
|
||||
}
|
||||
CASE_W(0xeb) /* JMP Jb */
|
||||
|
@ -928,6 +940,13 @@
|
|||
CASE_B(0xf0) /* LOCK */
|
||||
LOG(LOG_CPU,LOG_NORMAL)("CPU:LOCK"); /* FIXME: see case D_LOCK in core_full/load.h */
|
||||
break;
|
||||
CASE_B(0xf1) /* ICEBP */
|
||||
FillFlags();
|
||||
CPU_SW_Interrupt_NoIOPLCheck(1,GETIP);
|
||||
#if CPU_TRAP_CHECK
|
||||
core.trap.skip=true;
|
||||
#endif
|
||||
continue;
|
||||
CASE_B(0xf2) /* REPNZ */
|
||||
DO_PREFIX_REP(false);
|
||||
break;
|
||||
|
@ -935,6 +954,7 @@
|
|||
DO_PREFIX_REP(true);
|
||||
break;
|
||||
CASE_B(0xf4) /* HLT */
|
||||
if (cpu.pmode && cpu.cpl) EXCEPTION(EXCEPTION_GP);
|
||||
FillFlags();
|
||||
CPU_HLT(GETIP);
|
||||
return CBRET_NONE; //Needs to return for hlt cpu core
|
||||
|
@ -1094,11 +1114,18 @@
|
|||
continue;
|
||||
case 0x03: /* CALL Ep */
|
||||
{
|
||||
if (rm >= 0xc0) goto illegal_opcode;
|
||||
GetEAa;
|
||||
Bit16u newip=LoadMw(eaa);
|
||||
Bit16u newcs=LoadMw(eaa+2);
|
||||
FillFlags();
|
||||
CPU_CALL(false,newcs,newip,GETIP);
|
||||
#if CPU_TRAP_CHECK
|
||||
if (GETFLAG(TF)) {
|
||||
cpudecoder=CPU_Core_Normal_Trap_Run;
|
||||
return CBRET_NONE;
|
||||
}
|
||||
#endif
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
|
@ -1108,11 +1135,18 @@
|
|||
continue;
|
||||
case 0x05: /* JMP Ep */
|
||||
{
|
||||
if (rm >= 0xc0) goto illegal_opcode;
|
||||
GetEAa;
|
||||
Bit16u newip=LoadMw(eaa);
|
||||
Bit16u newcs=LoadMw(eaa+2);
|
||||
FillFlags();
|
||||
CPU_JMP(false,newcs,newip,GETIP);
|
||||
#if CPU_TRAP_CHECK
|
||||
if (GETFLAG(TF)) {
|
||||
cpudecoder=CPU_Core_Normal_Trap_Run;
|
||||
return CBRET_NONE;
|
||||
}
|
||||
#endif
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
|
|
1182
src/cpu/cpu.cpp
1182
src/cpu/cpu.cpp
File diff suppressed because it is too large
Load diff
|
@ -16,7 +16,7 @@
|
|||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
/* $Id: ems.cpp,v 1.41 2005-07-07 19:53:02 qbix79 Exp $ */
|
||||
/* $Id: ems.cpp,v 1.42 2005-08-15 13:43:44 c2woody Exp $ */
|
||||
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
@ -729,8 +729,8 @@ static Bitu INT67_Handler(void) {
|
|||
/* Load tables and initialize segment registers */
|
||||
CPU_LGDT(new_gdt_limit, new_gdt_base);
|
||||
CPU_LIDT(new_idt_limit, new_idt_base);
|
||||
CPU_LLDT(new_ldt);
|
||||
CPU_LTR(new_tr);
|
||||
if (CPU_LLDT(new_ldt)) LOG_MSG("VCPI:Could not load LDT with %x",new_ldt);
|
||||
if (CPU_LTR(new_tr)) LOG_MSG("VCPI:Could not load TR with %x",new_tr);
|
||||
|
||||
CPU_SetSegGeneral(ds,0);
|
||||
CPU_SetSegGeneral(es,0);
|
||||
|
@ -796,8 +796,8 @@ static Bitu VCPI_PM_Handler() {
|
|||
/* Load descriptor table registers */
|
||||
CPU_LGDT(0xff, vcpi.private_area+0x0000);
|
||||
CPU_LIDT(0x7ff, vcpi.private_area+0x2000);
|
||||
CPU_LLDT(0x08);
|
||||
CPU_LTR(0x10);
|
||||
if (CPU_LLDT(0x08)) LOG_MSG("VCPI:Could not load LDT");
|
||||
if (CPU_LTR(0x10)) LOG_MSG("VCPI:Could not load TR");
|
||||
|
||||
reg_flags&=(~FLAG_NT);
|
||||
reg_esp+=8; // skip interrupt return information
|
||||
|
@ -1107,8 +1107,8 @@ public:
|
|||
CPU_SET_CRX(0, 1);
|
||||
CPU_LGDT(0xff, vcpi.private_area+0x0000);
|
||||
CPU_LIDT(0x7ff, vcpi.private_area+0x2000);
|
||||
CPU_LLDT(0x08);
|
||||
CPU_LTR(0x10);
|
||||
if (CPU_LLDT(0x08)) LOG_MSG("VCPI:Could not load LDT");
|
||||
if (CPU_LTR(0x10)) LOG_MSG("VCPI:Could not load TR");
|
||||
|
||||
CPU_Push32(SegValue(gs));
|
||||
CPU_Push32(SegValue(fs));
|
||||
|
|
Loading…
Add table
Reference in a new issue