From b48eceebe77299c80274fbb326e4eea0127dfe4e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Mon, 15 Aug 2005 13:43:44 +0000 Subject: [PATCH] cpu updates (privileged instructions, trapflag handling) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2275 --- include/cpu.h | 46 +- src/cpu/core_full/load.h | 8 +- src/cpu/core_full/op.h | 18 +- src/cpu/core_full/optable.h | 4 +- src/cpu/core_full/support.h | 2 +- src/cpu/core_normal.cpp | 3 +- src/cpu/core_normal/prefix_0f.h | 72 +- src/cpu/core_normal/prefix_66.h | 30 +- src/cpu/core_normal/prefix_66_0f.h | 36 +- src/cpu/core_normal/prefix_none.h | 46 +- src/cpu/cpu.cpp | 1182 +++++++++++++++++++++++++++- src/ints/ems.cpp | 14 +- 12 files changed, 1352 insertions(+), 109 deletions(-) diff --git a/include/cpu.h b/include/cpu.h index 01783145..d1736b45 100644 --- a/include/cpu.h +++ b/include/cpu.h @@ -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; diff --git a/src/cpu/core_full/load.h b/src/cpu/core_full/load.h index 37d1e67d..ce95ddcc 100644 --- a/src/cpu/core_full/load.h +++ b/src/cpu/core_full/load.h @@ -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; diff --git a/src/cpu/core_full/op.h b/src/cpu/core_full/op.h index 410db642..4432c5e2 100644 --- a/src/cpu/core_full/op.h +++ b/src/cpu/core_full/op.h @@ -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); diff --git a/src/cpu/core_full/optable.h b/src/cpu/core_full/optable.h index 683ec41e..cf119948 100644 --- a/src/cpu/core_full/optable.h +++ b/src/cpu/core_full/optable.h @@ -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 }, diff --git a/src/cpu/core_full/support.h b/src/cpu/core_full/support.h index 5521daae..21561c77 100644 --- a/src/cpu/core_full/support.h +++ b/src/cpu/core_full/support.h @@ -45,7 +45,7 @@ enum { D_SAHF,D_LAHF, D_CPUID, D_HLT,D_CLTS, - D_LOCK, + D_LOCK,D_ICEBP, L_ERROR, }; diff --git a/src/cpu/core_normal.cpp b/src/cpu/core_normal.cpp index 0ccfd14e..0588928f 100644 --- a/src/cpu/core_normal.cpp +++ b/src/cpu/core_normal.cpp @@ -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; diff --git a/src/cpu/core_normal/prefix_0f.h b/src/cpu/core_normal/prefix_0f.h index 4b5103cf..749e3d27 100644 --- a/src/cpu/core_normal/prefix_0f.h +++ b/src/cpu/core_normal/prefix_0f.h @@ -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 */ diff --git a/src/cpu/core_normal/prefix_66.h b/src/cpu/core_normal/prefix_66.h index a6bfa76e..aa560535 100644 --- a/src/cpu/core_normal/prefix_66.h +++ b/src/cpu/core_normal/prefix_66.h @@ -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; diff --git a/src/cpu/core_normal/prefix_66_0f.h b/src/cpu/core_normal/prefix_66_0f.h index d7ad2386..224c82a1 100644 --- a/src/cpu/core_normal/prefix_66_0f.h +++ b/src/cpu/core_normal/prefix_66_0f.h @@ -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 */ diff --git a/src/cpu/core_normal/prefix_none.h b/src/cpu/core_normal/prefix_none.h index 3cde3a1d..81e2c7b3 100644 --- a/src/cpu/core_normal/prefix_none.h +++ b/src/cpu/core_normal/prefix_none.h @@ -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; diff --git a/src/cpu/cpu.cpp b/src/cpu/cpu.cpp index b3fb3b44..d8628853 100644 --- a/src/cpu/cpu.cpp +++ b/src/cpu/cpu.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: cpu.cpp,v 1.72 2005-07-09 13:07:48 c2woody Exp $ */ +/* $Id: cpu.cpp,v 1.73 2005-08-15 13:43:44 c2woody Exp $ */ #include #include "dosbox.h" @@ -52,13 +52,6 @@ void CPU_Core_Simple_Init(void); void CPU_Core_Dyn_X86_Init(void); -#define EXCEPTION_UD 6 -#define EXCEPTION_TS 10 -#define EXCEPTION_NP 11 -#define EXCEPTION_SS 12 -#define EXCEPTION_GP 13 - - /* In debug mode exceptions are tested and dosbox exits when * a unhandled exception state is detected. * USE CHECK_EXCEPT to raise an exception in that case to see if that exception @@ -211,16 +204,24 @@ public: } bool SetSelector(Bitu new_sel) { valid=false; - selector=new_sel; - if (!cpu.gdt.GetDescriptor(selector,desc)) return false; + if ((new_sel & 0xfffc)==0) { + selector=0; + base=0; + limit=0; + is386=1; + return true; + } + if (new_sel&4) return false; + if (!cpu.gdt.GetDescriptor(new_sel,desc)) return false; switch (desc.Type()) { case DESC_286_TSS_A: case DESC_286_TSS_B: case DESC_386_TSS_A: case DESC_386_TSS_B: break; default: - valid=false; return false; } + if (!desc.saved.seg.p) return false; + selector=new_sel; valid=true; base=desc.GetBase(); limit=desc.GetLimit(); @@ -244,16 +245,14 @@ enum TSwitchType { bool CPU_SwitchTask(Bitu new_tss_selector,TSwitchType tstype,Bitu old_eip) { TaskStateSegment new_tss; if (!new_tss.SetSelector(new_tss_selector)) - E_Exit("Illegal TSS for switch"); + E_Exit("Illegal TSS for switch, selector=%x, switchtype=%x",new_tss_selector,tstype); if (tstype==TSwitch_IRET) { - if (!cpu_tss.desc.IsBusy()) + if (!new_tss.desc.IsBusy()) E_Exit("TSS not busy for IRET"); } else { if (new_tss.desc.IsBusy()) E_Exit("TSS busy for JMP/CALL/INT"); } - if (!new_tss.desc.saved.seg.p) - E_Exit("TSS not present for switch"); Bitu new_cr3=0; Bitu new_eax,new_ebx,new_ecx,new_edx,new_esp,new_ebp,new_esi,new_edi; Bitu new_es,new_cs,new_ss,new_ds,new_fs,new_gs; @@ -401,7 +400,8 @@ doconforming: CPU_SetSegGeneral(ds,new_ds); CPU_SetSegGeneral(fs,new_fs); CPU_SetSegGeneral(gs,new_gs); - CPU_LTR(new_tss_selector); + if (!cpu_tss.SetSelector(new_tss_selector)) LOG(LOG_CPU,LOG_NORMAL)("TaskSwitch: set tss selector %X failed",new_tss_selector); + cpu_tss.desc.SetBusy(true); // LOG_MSG("Task CPL %X CS:%X IP:%X SS:%X SP:%X eflags %x",cpu.cpl,SegValue(cs),reg_eip,SegValue(ss),reg_esp,reg_flags); return true; } @@ -429,9 +429,1037 @@ void CPU_Exception(Bitu which,Bitu error ) { CPU_Interrupt(which,CPU_INT_EXCEPTION | ((which>=8) ? CPU_INT_HAS_ERROR : 0),reg_eip); } +const char* translateVXDid(Bitu nr) { + switch (nr) { + case 0x0001: return "VMM"; // Virtual Machine Manager + case 0x0002: return "DEBUG"; + case 0x0003: return "VPICD"; // Virtual PIC Device + case 0x0004: return "VDMAD"; // Virtual DMA Device + case 0x0005: return "VTD"; // Virtual Timer Device + case 0x0006: return "V86MMGR"; // Virtual Device + case 0x0007: return "PageSwap"; + case 0x000A: return "VDD"; // Virtual Display Device + case 0x000C: return "VMD"; // Virtual Mouse Device + case 0x000D: return "VKD"; // Virtual Keyboard Device + case 0x000E: return "VCD"; // Virtual COMM Device + case 0x0010: return "IOS"; // BlockDev / IOS + case 0x0011: return "VMCPD"; + case 0x0012: return "EBIOS"; + case 0x0015: return "DOSMGR"; + case 0x0017: return "SHELL"; + case 0x0018: return "VMPoll"; + case 0x001A: return "DOSNET"; + case 0x001B: return "VFD"; + case 0x001C: return "LoadHi"; + case 0x0020: return "Int13"; + case 0x0021: return "PAGEFILE"; + case 0x0026: return "VPOWERD"; + case 0x0027: return "VXDLDR"; + case 0x002A: return "VWIN32"; + case 0x002B: return "VCOMM"; + case 0x0033: return "CONFIGMG"; + case 0x0036: return "VFBACKUP"; + case 0x0037: return "VMINI"; + case 0x0040: return "IFSMgr"; + case 0x0041: return "VCDFSD"; + case 0x0048: return "PERF"; + case 0x011F: return "VFLATD"; + case 0x0446: return "VADLIB"; + case 0x044a: return "mmdevldr"; + case 0x0484: return "IfsMgr"; + case 0x048B: return "VCACHE"; + case 0x357E: return "DSOUND"; + default: + return "unknown"; + } +} + +const char* translateVXDservice(Bitu nr, Bitu sv) { + switch (nr) { + case 0x0001: + switch (sv & 0x7fff) { + case 0x0000 : return "get version"; + case 0x0001 : return "get current VM handle"; + case 0x0002 : return "test current VM handle"; + case 0x0003 : return "get system VM handle"; + case 0x0004 : return "test system VM handle"; + case 0x0005 : return "validate VM handle"; + case 0x0006 : return "get VMM reenter count"; + case 0x0007 : return "begin reentrant execution"; + case 0x0008 : return "end reentrant execution"; + case 0x0009 : return "install V86 breakpoint"; + case 0x000A : return "remove V86 breakpoint"; + case 0x000B : return "allocate V86 callback"; + case 0x000C : return "allocation PM callback"; + case 0x000D : return "call when VM returns"; + case 0x000E : return "schedule global event"; + case 0x000F : return "schedule VM event"; + case 0x0010 : return "call global event"; + case 0x0011 : return "call VM event"; + case 0x0012 : return "cancel global event"; + case 0x0013 : return "cancel VM event"; + case 0x0014 : return "call priority VM event"; + case 0x0015 : return "cancel priority VM event"; + case 0x0016 : return "get NMI handler address"; + case 0x0017 : return "set NMI handler address"; + case 0x0018 : return "hook NMI event"; + case 0x0019 : return "call when VM interrupts enabled"; + case 0x001A : return "enable VM interrupts"; + case 0x001B : return "disable VM interrupts"; + case 0x001C : return "map flat"; + case 0x001D : return "map linear to VM address"; + case 0x001E : return "adjust execution priority"; + case 0x001F : return "begin critical section"; + case 0x0020 : return "end critical section"; + case 0x0021 : return "end critical section and suspend"; + case 0x0022 : return "claim critical section"; + case 0x0023 : return "release critical section"; + case 0x0024 : return "call when not critical"; + case 0x0025 : return "create semaphore"; + case 0x0026 : return "destroy semaphore"; + case 0x0027 : return "wait on semaphore"; + case 0x0028 : return "signal semaphore"; + case 0x0029 : return "get critical section status"; + case 0x002A : return "call when task switched"; + case 0x002B : return "suspend VM"; + case 0x002C : return "resume VM"; + case 0x002D : return "no-fail resume VM"; + case 0x002E : return "nuke VM"; + case 0x002F : return "crash current VM"; + case 0x0030 : return "get execution focus"; + case 0x0031 : return "set execution focus"; + case 0x0032 : return "get time slice priority"; + case 0x0033 : return "set time slice priority"; + case 0x0034 : return "get time slice granularity"; + case 0x0035 : return "set time slice granularity"; + case 0x0036 : return "get time slice information"; + case 0x0037 : return "adjust execution time"; + case 0x0038 : return "release time slice"; + case 0x0039 : return "wake up VM"; + case 0x003A : return "call when idle"; + case 0x003B : return "get next VM handle"; + case 0x003C : return "set global timeout"; + case 0x003D : return "set VM timeout"; + case 0x003E : return "cancel timeout"; + case 0x003F : return "get system time"; + case 0x0040 : return "get VM execution time"; + case 0x0041 : return "hook V86 interrupt chain"; + case 0x0042 : return "get V86 interrupt vector"; + case 0x0043 : return "set V86 interrupt vector"; + case 0x0044 : return "get PM interrupt vector"; + case 0x0045 : return "set PM interrupt vector"; + case 0x0046 : return "simulate interrupt"; + case 0x0047 : return "simulate IRET"; + case 0x0048 : return "simulate far call"; + case 0x0049 : return "simulate far jump"; + case 0x004A : return "simulate far RET"; + case 0x004B : return "simulate far RET N"; + case 0x004C : return "build interrupt stack frame"; + case 0x004D : return "simulate push"; + case 0x004E : return "simulate pop"; + case 0x004F : return "_HeapAllocate"; + case 0x0050 : return "_HeapReAllocate"; + case 0x0051 : return "_HeapFree"; + case 0x0052 : return "_HeapGetSize"; + case 0x0053 : return "_PageAllocate"; + case 0x0054 : return "_PageReAllocate"; + case 0x0055 : return "_PageFree"; + case 0x0056 : return "_PageLock"; + case 0x0057 : return "_PageUnLock"; + case 0x0058 : return "_PageGetSizeAddr"; + case 0x0059 : return "_PageGetAllocInfo"; + case 0x005A : return "_GetFreePageCount"; + case 0x005B : return "_GetSysPageCount"; + case 0x005C : return "_GetVMPgCount"; + case 0x005D : return "_MapIntoV86"; + case 0x005E : return "_PhysIntoV86"; + case 0x005F : return "_TestGlobalV86Mem"; + case 0x0060 : return "_ModifyPageBits"; + case 0x0061 : return "copy page table"; + case 0x0062 : return "map linear into V86"; + case 0x0063 : return "linear page lock"; + case 0x0064 : return "linear page unlock"; + case 0x0065 : return "_SetResetV86Pageabl"; + case 0x0066 : return "_GetV86PageableArray"; + case 0x0067 : return "_PageCheckLinRange"; + case 0x0068 : return "page out dirty pages"; + case 0x0069 : return "discard pages"; + case 0x006A : return "_GetNulPageHandle"; + case 0x006B : return "get first V86 page"; + case 0x006C : return "map physical address to linear address"; + case 0x006D : return "_GetAppFlatDSAlias"; + case 0x006E : return "_SelectorMapFlat"; + case 0x006F : return "_GetDemandPageInfo"; + case 0x0070 : return "_GetSetPageOutCount"; + case 0x0071 : return "hook V86 page"; + case 0x0072 : return "assign device V86 pages"; + case 0x0073 : return "deassign device V86 pages"; + case 0x0074 : return "get array of V86 pages for device"; + case 0x0075 : return "_SetNULPageAddr"; + case 0x0076 : return "allocate GDT selector"; + case 0x0077 : return "free GDT selector"; + case 0x0078 : return "allocate LDT selector"; + case 0x0079 : return "free LDT selector"; + case 0x007A : return "_BuildDescriptorDWORDs"; + case 0x007B : return "get descriptor"; + case 0x007C : return "set descriptor"; + case 0x007D : return "toggle HMA"; + case 0x007E : return "get fault hook addresses"; + case 0x007F : return "hook V86 fault"; + case 0x0080 : return "hook PM fault"; + case 0x0081 : return "hook VMM fault"; + case 0x0082 : return "begin nested V86 execution"; + case 0x0083 : return "begin nested execution"; + case 0x0084 : return "execute V86-mode interrupt"; + case 0x0085 : return "resume execution"; + case 0x0086 : return "end nested execution"; + case 0x0087 : return "allocate PM application callback area"; + case 0x0088 : return "get current PM application callback area"; + case 0x0089 : return "set V86 execution mode"; + case 0x008A : return "set PM execution mode"; + case 0x008B : return "begin using locked PM stack"; + case 0x008C : return "end using locked PM stack"; + case 0x008D : return "save client state"; + case 0x008E : return "restore client state"; + case 0x008F : return "execute VxD interrupt"; + case 0x0090 : return "hook device service"; + case 0x0091 : return "hook device V86 API"; + case 0x0092 : return "hook device PM API"; + case 0x0093 : return "system control (see also #02657)"; + case 0x0094 : return "simulate I/O"; + case 0x0095 : return "install multiple I/O handlers"; + case 0x0096 : return "install I/O handler"; + case 0x0097 : return "enable global trapping"; + case 0x0098 : return "enable local trapping"; + case 0x0099 : return "disable global trapping"; + case 0x009A : return "disable local trapping"; + case 0x009B : return "create list"; + case 0x009C : return "destroy list"; + case 0x009D : return "allocate list"; + case 0x009E : return "attach list"; + case 0x009F : return "attach list tail"; + case 0x00A0 : return "insert into list"; + case 0x00A1 : return "remove from list"; + case 0x00A2 : return "deallocate list"; + case 0x00A3 : return "get first item in list"; + case 0x00A4 : return "get next item in list"; + case 0x00A5 : return "remove first item in list"; + case 0x00A6 : return "add instance item"; + case 0x00A7 : return "allocate device callback area"; + case 0x00A8 : return "allocate global V86 data area"; + case 0x00A9 : return "allocate temporary V86 data area"; + case 0x00AA : return "free temporary V86 data area"; + case 0x00AB : return "get decimal integer from profile"; + case 0x00AC : return "convert decimal string to integer"; + case 0x00AD : return "get fixed-point number from profile"; + case 0x00AE : return "convert fixed-point string"; + case 0x00AF : return "get hex integer from profile"; + case 0x00B0 : return "convert hex string to integer"; + case 0x00B1 : return "get boolean value from profile"; + case 0x00B2 : return "convert boolean string"; + case 0x00B3 : return "get string from profile"; + case 0x00B4 : return "get next string from profile"; + case 0x00B5 : return "get environment string"; + case 0x00B6 : return "get exec path"; + case 0x00B7 : return "get configuration directory"; + case 0x00B8 : return "open file"; + case 0x00B9 : return "get PSP segment"; + case 0x00BA : return "get DOS vectors"; + case 0x00BB : return "get machine information"; + case 0x00BC : return "get/set HMA information"; + case 0x00BD : return "set system exit code"; + case 0x00BE : return "fatal error handler"; + case 0x00BF : return "fatal memory error"; + case 0x00C0 : return "update system clock"; + case 0x00C1 : return "test if debugger installed"; + case 0x00C2 : return "output debugger string"; + case 0x00C3 : return "output debugger character"; + case 0x00C4 : return "input debugger character"; + case 0x00C5 : return "debugger convert hex to binary"; + case 0x00C6 : return "debugger convert hex to decimal"; + case 0x00C7 : return "debugger test if valid handle"; + case 0x00C8 : return "validate client pointer"; + case 0x00C9 : return "test reentry"; + case 0x00CA : return "queue debugger string"; + case 0x00CB : return "log procedure call"; + case 0x00CC : return "debugger test current VM"; + case 0x00CD : return "get PM interrupt type"; + case 0x00CE : return "set PM interrupt type"; + case 0x00CF : return "get last updated system time"; + case 0x00D0 : return "get last updated VM execution time"; + case 0x00D1 : return "test if double-byte character-set lead byte"; + case 0x00D2 : return "_AddFreePhysPage"; + case 0x00D3 : return "_PageResetHandlePAddr"; + case 0x00D4 : return "_SetLastV86Page"; + case 0x00D5 : return "_GetLastV86Page"; + case 0x00D6 : return "_MapFreePhysReg"; + case 0x00D7 : return "_UnmapFreePhysReg"; + case 0x00D8 : return "_XchgFreePhysReg"; + case 0x00D9 : return "_SetFreePhysRegCalBk"; + case 0x00DA : return "get next arena (MCB)"; + case 0x00DB : return "get name of ugly TSR"; + case 0x00DC : return "get debug options"; + case 0x00DD : return "set physical HMA alias"; + case 0x00DE : return "_GetGlblRng0V86IntBase"; + case 0x00DF : return "add global V86 data area"; + case 0x00E0 : return "get/set detailed VM error"; + case 0x00E1 : return "Is_Debug_Chr"; + case 0x00E2 : return "clear monochrome screen"; + case 0x00E3 : return "output character to mono screen"; + case 0x00E4 : return "output string to mono screen"; + case 0x00E5 : return "set current position on mono screen"; + case 0x00E6 : return "get current position on mono screen"; + case 0x00E7 : return "get character from mono screen"; + case 0x00E8 : return "locate byte in ROM"; + case 0x00E9 : return "hook invalid page fault"; + case 0x00EA : return "unhook invalid page fault"; + case 0x00EB : return "set delete on exit file"; + case 0x00EC : return "close VM"; + case 0x00ED : return "Enable_Touch_1st_Meg"; + case 0x00EE : return "Disable_Touch_1st_Meg"; + case 0x00EF : return "install exception handler"; + case 0x00F0 : return "remove exception handler"; + case 0x00F1 : return "Get_Crit_Status_No_Block"; + case 0x00F2 : return "_Schedule_VM_RTI_Event"; + case 0x00F3 : return "_Trace_Out_Service"; + case 0x00F4 : return "_Debug_Out_Service"; + case 0x00F5 : return "_Debug_Flags_Service"; + case 0x00F6 : return "VMM add import module name"; + case 0x00F7 : return "VMM Add DDB"; + case 0x00F8 : return "VMM Remove DDB"; + case 0x00F9 : return "get thread time slice priority"; + case 0x00FA : return "set thread time slice priority"; + case 0x00FB : return "schedule thread event"; + case 0x00FC : return "cancel thread event"; + case 0x00FD : return "set thread timeout"; + case 0x00FE : return "set asynchronous timeout"; + case 0x00FF : return "_AllocatreThreadDataSlot"; + case 0x0100 : return "_FreeThreadDataSlot"; + case 0x0101 : return "create Mutex"; + case 0x0102 : return "destroy Mutex"; + case 0x0103 : return "get Mutex owner"; + case 0x0104 : return "call when thread switched"; + case 0x0105 : return "create thread"; + case 0x0106 : return "start thread"; + case 0x0107 : return "terminate thread"; + case 0x0108 : return "get current thread handle"; + case 0x0109 : return "test current thread handle"; + case 0x010A : return "Get_Sys_Thread_Handle"; + case 0x010B : return "Test_Sys_Thread_Handle"; + case 0x010C : return "Validate_Thread_Handle"; + case 0x010D : return "Get_Initial_Thread_Handle"; + case 0x010E : return "Test_Initial_Thread_Handle"; + case 0x010F : return "Debug_Test_Valid_Thread_Handle"; + case 0x0110 : return "Debug_Test_Cur_Thread"; + case 0x0111 : return "VMM_GetSystemInitState"; + case 0x0112 : return "Cancel_Call_When_Thread_Switched"; + case 0x0113 : return "Get_Next_Thread_Handle"; + case 0x0114 : return "Adjust_Thread_Exec_Priority"; + case 0x0115 : return "_Deallocate_Device_CB_Area"; + case 0x0116 : return "Remove_IO_Handler"; + case 0x0117 : return "Remove_Mult_IO_Handlers"; + case 0x0118 : return "unhook V86 interrupt chain"; + case 0x0119 : return "unhook V86 fault handler"; + case 0x011A : return "unhook PM fault handler"; + case 0x011B : return "unhook VMM fault handler"; + case 0x011C : return "unhook device service"; + case 0x011D : return "_PageReserve"; + case 0x011E : return "_PageCommit"; + case 0x011F : return "_PageDecommit"; + case 0x0120 : return "_PagerRegister"; + case 0x0121 : return "_PagerQuery"; + case 0x0122 : return "_PagerDeregister"; + case 0x0123 : return "_ContextCreate"; + case 0x0124 : return "_ContextDestroy"; + case 0x0125 : return "_PageAttach"; + case 0x0126 : return "_PageFlush"; + case 0x0127 : return "_SignalID"; + case 0x0128 : return "_PageCommitPhys"; + case 0x0129 : return "_Register_Win32_Services"; + case 0x012A : return "Cancel_Call_When_Not_Critical"; + case 0x012B : return "Cancel_Call_When_Idle"; + case 0x012C : return "Cancel_Call_When_Task_Switched"; + case 0x012D : return "_Debug_Printf_Service"; + case 0x012E : return "enter Mutex"; + case 0x012F : return "leave Mutex"; + case 0x0130 : return "simulate VM I/O"; + case 0x0131 : return "Signal_Semaphore_No_Switch"; + case 0x0132 : return "_MMSwitchContext"; + case 0x0133 : return "_MMModifyPermissions"; + case 0x0134 : return "_MMQuery"; + case 0x0135 : return "_EnterMustComplete"; + case 0x0136 : return "_LeaveMustComplete"; + case 0x0137 : return "_ResumeExecMustComplete"; + case 0x0138 : return "get thread termination status"; + case 0x0139 : return "_GetInstanceInfo"; + case 0x013A : return "_ExecIntMustComplete"; + case 0x013B : return "_ExecVxDIntMustComplete"; + case 0x013C : return "begin V86 serialization"; + case 0x013D : return "unhook V86 page"; + case 0x013E : return "VMM_GetVxDLocationList"; + case 0x013F : return "VMM_GetDDBList: get start of VxD chain"; + case 0x0140 : return "unhook NMI event"; + case 0x0141 : return "Get_Instanced_V86_Int_Vector"; + case 0x0142 : return "get or set real DOS PSP"; + case 0x0143 : return "call priority thread event"; + case 0x0144 : return "Get_System_Time_Address"; + case 0x0145 : return "Get_Crit_Status_Thread"; + case 0x0146 : return "Get_DDB"; + case 0x0147 : return "Directed_Sys_Control"; + case 0x0148 : return "_RegOpenKey"; + case 0x0149 : return "_RegCloseKey"; + case 0x014A : return "_RegCreateKey"; + case 0x014B : return "_RegDeleteKey"; + case 0x014C : return "_RegEnumKey"; + case 0x014D : return "_RegQueryValue"; + case 0x014E : return "_RegSetValue"; + case 0x014F : return "_RegDeleteValue"; + case 0x0150 : return "_RegEnumValue"; + case 0x0151 : return "_RegQueryValueEx"; + case 0x0152 : return "_RegSetValueEx"; + case 0x0153 : return "_CallRing3"; + case 0x0154 : return "Exec_PM_Int"; + case 0x0155 : return "_RegFlushKey"; + case 0x0156 : return "_PageCommitContig"; + case 0x0157 : return "_GetCurrentContext"; + case 0x0158 : return "_LocalizeSprintf"; + case 0x0159 : return "_LocalizeStackSprintf"; + case 0x015A : return "Call_Restricted_Event"; + case 0x015B : return "Cancel_Restricted_Event"; + case 0x015C : return "Register_PEF_Provider"; + case 0x015D : return "_GetPhysPageInfo"; + case 0x015E : return "_RegQueryInfoKey"; + case 0x015F : return "MemArb_Reserve_Pages"; + case 0x0160 : return "Time_Slice_Sys_VM_Idle"; + case 0x0161 : return "Time_Slice_Sleep"; + case 0x0162 : return "Boost_With_Decay"; + case 0x0163 : return "Set_Inversion_Pri"; + case 0x0164 : return "Reset_Inversion_Pri"; + case 0x0165 : return "Release_Inversion_Pri"; + case 0x0166 : return "Get_Thread_Win32_Pri"; + case 0x0167 : return "Set_Thread_Win32_Pri"; + case 0x0168 : return "Set_Thread_Static_Boost"; + case 0x0169 : return "Set_VM_Static_Boost"; + case 0x016A : return "Release_Inversion_Pri_ID"; + case 0x016B : return "Attach_Thread_To_Group"; + case 0x016C : return "Detach_Thread_From_Group"; + case 0x016D : return "Set_Group_Static_Boost"; + case 0x016E : return "_GetRegistryPath"; + case 0x016F : return "_GetRegistryKey"; + case 0x0170 : return "_CleanupNestedExec"; + case 0x0171 : return "_RegRemapPreDefKey"; + case 0x0172 : return "End_V86_Serialization"; + case 0x0173 : return "_Assert_Range"; + case 0x0174 : return "_Sprintf"; + case 0x0175 : return "_PageChangePager"; + case 0x0176 : return "_RegCreateDynKey"; + case 0x0177 : return "RegQMulti"; + case 0x0178 : return "Boost_Thread_With_VM"; + case 0x0179 : return "Get_Boot_Flags"; + case 0x017A : return "Set_Boot_Flags"; + case 0x017B : return "_lstrcpyn"; + case 0x017C : return "_lstrlen"; + case 0x017D : return "_lmemcpy"; + case 0x017E : return "_GetVxDName"; + case 0x017F : return "Force_Mutexes_Free"; + case 0x0180 : return "Restore_Forced_Mutexes"; + case 0x0181 : return "_AddReclaimableItem"; + case 0x0182 : return "_SetReclaimableItem"; + case 0x0183 : return "_EnumReclaimableItem"; + case 0x0184 : return "Time_Slice_Wake_Sys_VM"; + case 0x0185 : return "VMM_Replace_Global_Environment"; + case 0x0186 : return "Begin_Non_Serial_Nest_V86_Exec"; + case 0x0187 : return "Get_Nest_Exec_Status"; + case 0x0188 : return "Open_Boot_Log"; + case 0x0189 : return "Write_Boot_Log"; + case 0x018A : return "Close_Boot_Log"; + case 0x018B : return "EnableDisable_Boot_Log"; + case 0x018C : return "_Call_On_My_Stack"; + case 0x018D : return "Get_Inst_V86_Int_Vec_Base"; + case 0x018E : return "_lstrcmpi"; + case 0x018F : return "_strupr"; + case 0x0190 : return "Log_Fault_Call_Out"; + case 0x0191 : return "_AtEventTime"; + default: return "dunnoSV"; + } + case 0x0002: + switch (sv & 0x7fff) { + case 0x0000 : return "get version"; + case 0x0001 : return "DEBUG_Fault"; + case 0x0002 : return "DEBUG_CheckFault"; + case 0x0003 : return "DEBUG_LoadSyms"; + default: return "dunnoSV"; + } + case 0x0003: + switch (sv & 0x7fff) { + case 0x0000 : return "get version"; + case 0x0001 : return "virtualize IRQ"; + case 0x0002 : return "set interrupt request"; + case 0x0003 : return "clear interrupt request"; + case 0x0004 : return "physical EOI"; + case 0x0005 : return "get complete status"; + case 0x0006 : return "get status"; + case 0x0007 : return "test physical request"; + case 0x0008 : return "physically mask"; + case 0x0009 : return "physically unmask"; + case 0x000A : return "set automatic masking"; + case 0x000B : return "get IRQ complete status"; + case 0x000C : return "convert handle to IRQ"; + case 0x000D : return "convert IRQ to interrupt"; + case 0x000E : return "convert interrupt to IRQ"; + case 0x000F : return "call on hardware interrupt"; + case 0x0010 : return "force default owner"; + case 0x0011 : return "force default behavior"; + case 0x0012 : return "VPICD_Auto_Mask_At_Inst_Swap"; + case 0x0013 : return "VPICD_Begin_Inst_Page_Swap"; + case 0x0014 : return "VPICD_End_Inst_Page_Swap"; + case 0x0015 : return "VPICD_Virtual_EOI"; + case 0x0016 : return "VPICD_Get_Virtualization_Count"; + case 0x0017 : return "VPICD_Post_Sys_Critical_Init"; + case 0x0018 : return "VPICD_VM_SlavePIC_Mask_Change"; + default: return "dunnoSV"; + } + case 0x0004: + switch (sv & 0x7fff) { + case 0x0000 : return "get version"; + case 0x0001 : return "virtualize channel"; + case 0x0002 : return "get region information"; + case 0x0003 : return "set region information"; + case 0x0004 : return "get virtual state"; + case 0x0005 : return "set virtual state"; + case 0x0006 : return "set physical state"; + case 0x0007 : return "mask channel"; + case 0x0008 : return "unmask channel"; + case 0x0009 : return "lock DMA region"; + case 0x000A : return "unlock DMA region"; + case 0x000B : return "scatter lock"; + case 0x000C : return "scatter unlock"; + case 0x000D : return "reserve buffer space"; + case 0x000E : return "request buffer"; + case 0x000F : return "release buffer"; + case 0x0010 : return "copy to buffer"; + case 0x0011 : return "copy from buffer"; + case 0x0012 : return "default handler"; + case 0x0013 : return "disable translation"; + case 0x0014 : return "enable translation"; + case 0x0015 : return "get EISA address mode"; + case 0x0016 : return "set EISA address mode"; + case 0x0017 : return "unlock DMA region (ND)"; + case 0x0018 : return "VDMAD_Phys_Mask_Channel"; + case 0x0019 : return "VDMAD_Phys_Unmask_Channel"; + case 0x001A : return "VDMAD_Unvirtualize_Channel"; + case 0x001B : return "VDMAD_Set_IO_Address"; + case 0x001C : return "VDMAD_Get_Phys_Count"; + case 0x001D : return "VDMAD_Get_Phys_Status"; + case 0x001E : return "VDMAD_Get_Max_Phys_Page"; + case 0x001F : return "VDMAD_Set_Channel_Callbacks"; + case 0x0020 : return "VDMAD_Get_Virt_Count"; + case 0x0021 : return "VDMAD_Set_Virt_Count"; + default: return "dunnoSV"; + } + case 0x0005: + switch (sv & 0x7fff) { + case 0x0000 : return "get version"; + case 0x0001 : return "update system clock"; + case 0x0002 : return "get interrupt period"; + case 0x0003 : return "begin minimum interrupt period"; + case 0x0004 : return "end minimum interrupt period"; + case 0x0005 : return "disable trapping"; + case 0x0006 : return "enable trapping"; + case 0x0007 : return "get real time"; + case 0x0008 : return "VTD_Get_Date_And_Time"; + case 0x0009 : return "VTD_Adjust_VM_Count"; + case 0x000A : return "VTD_Delay"; + default: return "dunnoSV"; + } + case 0x0006: + switch (sv & 0x7fff) { + case 0x0000 : return "get version"; + case 0x0001 : return "allocate V86 pages"; + case 0x0002 : return "set EMS and XMS limits"; + case 0x0003 : return "get EMS and XMS limits"; + case 0x0004 : return "set mapping information"; + case 0x0005 : return "get mapping information"; + case 0x0006 : return "Xlat API"; + case 0x0007 : return "load client pointer"; + case 0x0008 : return "allocate buffer"; + case 0x0009 : return "free buffer"; + case 0x000A : return "get Xlat buffer state"; + case 0x000B : return "set Xlat buffer state"; + case 0x000C : return "get VM flat selector"; + case 0x000D : return "map pages"; + case 0x000E : return "free page map region"; + case 0x000F : return "_LocalGlobalReg"; + case 0x0010 : return "get page status"; + case 0x0011 : return "set local A20"; + case 0x0012 : return "reset base pages"; + case 0x0013 : return "set available mapped pages"; + case 0x0014 : return "V86MMGR_NoUMBInitCalls"; + case 0x0015 : return "V86MMGR_Get_EMS_XMS_Avail"; + case 0x0016 : return "V86MMGR_Toggle_HMA"; + case 0x0017 : return "V86MMGR_Dev_Init"; + case 0x0018 : return "V86MMGR_Alloc_UM_Page"; + default: return "dunnoSV"; + } + case 0x0007: + switch (sv & 0x7fff) { + case 0x0000 : return "get version"; + case 0x0001 : return "test create"; + case 0x0002 : return "create swap file"; + case 0x0003 : return "destroy swap file"; + case 0x0004 : return "in"; + case 0x0005 : return "out"; + case 0x0006 : return "test if I/O valid"; + case 0x0007 : return "Read_Or_Write"; + case 0x0008 : return "Grow_File"; + case 0x0009 : return "Init_File"; + default: return "dunnoSV"; + } + case 0x000a: + switch (sv & 0x7fff) { + case 0x0000 : return "get version"; + case 0x0001 : return "PIF state"; + case 0x0002 : return "get GrabRtn"; + case 0x0003 : return "hide cursor"; + case 0x0004 : return "set VM type"; + case 0x0005 : return "get ModTime"; + case 0x0006 : return "set HCurTrk"; + case 0x0007 : return "message clear screen"; + case 0x0008 : return "message foreground color"; + case 0x0009 : return "message background color"; + case 0x000A : return "message output text"; + case 0x000B : return "message set cursor position"; + case 0x000C : return "query access"; + case 0x000D : return "VDD_Check_Update_Soon"; + case 0x000E : return "VDD_Get_Mini_Dispatch_Table"; + case 0x000F : return "VDD_Register_Virtual_Port"; + case 0x0010 : return "VDD_Get_VM_Info"; + case 0x0011 : return "VDD_Get_Special_VM_IDs"; + case 0x0012 : return "VDD_Register_Extra_Screen_Selector"; + case 0x0013 : return "VDD_Takeover_VGA_Port"; + default: return "dunnoSV"; + } + case 0x000c: + switch (sv & 0x7fff) { + case 0x0000 : return "get version"; + case 0x0001 : return "set mouse type"; + case 0x0002 : return "get mouse owner"; + case 0x0003 : return "VMOUSE_Post_Pointer_Message"; + case 0x0004 : return "VMOUSE_Set_Cursor_Proc"; + case 0x0005 : return "VMOUSE_Call_Cursor_Proc"; + case 0x0006 : return "VMOUSE_Set_Mouse_Data~Get_Mouse_Data"; + case 0x0007 : return "VMOUSE_Manipulate_Pointer_Message"; + case 0x0008 : return "VMOUSE_Set_Middle_Button"; + case 0x0009 : return "VMD_Set_Middle_Button"; + case 0x000A : return "VMD_Enable_Disable_Mouse_Events"; + case 0x000B : return "VMD_Post_Absolute_Pointer_Message"; + default: return "dunnoSV"; + } + case 0x000d: + switch (sv & 0x7fff) { + case 0x0000 : return "get version"; + case 0x0001 : return "define hotkey"; + case 0x0002 : return "remove hotkey"; + case 0x0003 : return "locally enable hotkey"; + case 0x0004 : return "locally disable hotkey"; + case 0x0005 : return "reflect hotkey"; + case 0x0006 : return "cancel hotkey state"; + case 0x0007 : return "force keys"; + case 0x0008 : return "get keyboard owner"; + case 0x0009 : return "define paste mode"; + case 0x000A : return "start pasting"; + case 0x000B : return "cancel paste"; + case 0x000C : return "get message key"; + case 0x000D : return "peek message key"; + case 0x000E : return "flush message key queue"; + case 0x000F : return "VKD_Enable_Keyboard"; + case 0x0010 : return "VKD_Disable_Keyboard"; + case 0x0011 : return "VKD_Get_Shift_State"; + case 0x0012 : return "VKD_Filter_Keyboard_Input"; + case 0x0013 : return "VKD_Put_Byte"; + case 0x0014 : return "VKD_Set_Shift_State"; + default: return "dunnoSV"; + } + case 0x000e: + switch (sv & 0x7fff) { + case 0x0000 : return "get version"; + case 0x0001 : return "set port global"; + case 0x0002 : return "get focus"; + case 0x0003 : return "virtualize port"; + case 0x0004 : return "VCD_Acquire_Port"; + case 0x0005 : return "VCD_Free_Port"; + case 0x0006 : return "VCD_Acquire_Port_Windows_Style"; + case 0x0007 : return "VCD_Free_Port_Windows_Style"; + case 0x0008 : return "VCD_Steal_Port_Windows_Style"; + case 0x0009 : return "VCD_Find_COM_Index"; + case 0x000A : return "VCD_Set_Port_Global_Special"; + case 0x000B : return "VCD_Virtualize_Port_Dynamic"; + case 0x000C : return "VCD_Unvirtualize_Port_Dynamic"; + default: return "dunnoSV"; + } + case 0x0010: + switch (sv & 0x7fff) { + case 0x0000 : return "get version"; + case 0x0001 : return "register device"; + case 0x0002 : return "find INT 13 drive"; + case 0x0003 : return "get device list"; + case 0x0004 : return "send command"; + case 0x0005 : return "command complete"; + case 0x0006 : return "synchronous command"; + case 0x0007 : return "IOS_Register"; + case 0x0008 : return "IOS_Requestor_Service"; + case 0x0009 : return "IOS_Exclusive_Access"; + case 0x000A : return "IOS_Send_Next_Command"; + case 0x000B : return "IOS_Set_Async_Time_Out"; + case 0x000C : return "IOS_Signal_Semaphore_No_Switch"; + case 0x000D : return "IOSIdleStatus"; + case 0x000E : return "IOSMapIORSToI24"; + case 0x000F : return "IOSMapIORSToI21"; + case 0x0010 : return "PrintLog"; + default: return "dunnoSV"; + } + case 0x0011: + switch (sv & 0x7fff) { + case 0x0000 : return "get_version"; + case 0x0001 : return "get_virt_state"; + case 0x0002 : return "set_virt_state"; + case 0x0003 : return "get_cr0_state"; + case 0x0004 : return "set_cr0_state"; + case 0x0005 : return "get_thread_state"; + case 0x0006 : return "set_thread_state"; + case 0x0007 : return "get_FP_instruction_size"; + case 0x0008 : return "set_thread_precision"; + default: return "dunnoSV"; + } + case 0x0012: + switch (sv & 0x7fff) { + case 0x0000 : return "get EBIOS version"; + case 0x0001 : return "get unused memory"; + default: return "dunnoSV"; + } + case 0x0015: + switch (sv & 0x7fff) { + case 0x0000 : return "get version"; + case 0x0001 : return "set exec VM data"; + case 0x0002 : return "coyp VM drive state"; + case 0x0003 : return "execute VM"; + case 0x0004 : return "get InDOS pointer"; + case 0x0005 : return "add device"; + case 0x0006 : return "remove device"; + case 0x0007 : return "instance device"; + case 0x0008 : return "get DOS critical status"; + case 0x0009 : return "enable InDOS polling"; + case 0x000A : return "backfill allowed"; + case 0x000B : return "LocalGlobalReg"; + case 0x000C : return "Init_UMB_Area"; + case 0x000D : return "Begin_V86_App"; + case 0x000E : return "End_V86_App"; + case 0x000F : return "Alloc_Local_Sys_VM_Mem"; + case 0x0010 : return "DOSMGR_Grow_CDSs"; + case 0x0011 : return "DOSMGR_Translate_Server_DOS_Call"; + case 0x0012 : return "DOSMGR_MMGR_PSP_Change_Notifier"; + default: return "dunnoSV"; + } + case 0x0017: + switch (sv & 0x7fff) { + case 0x0000 : return "get version"; + case 0x0001 : return "resolve contention"; + case 0x0002 : return "event"; + case 0x0003 : return "SYSMODAL message"; + case 0x0004 : return "message"; + case 0x0005 : return "get VM information"; + case 0x0006 : return "_SHELL_PostMessage"; + case 0x0007 : return "_SHELL_WinExec"; + case 0x0008 : return "_SHELL_CallDll"; + case 0x0009 : return "SHELL_OpenClipboard"; + case 0x000A : return "SHELL_SetClipboardData"; + case 0x000B : return "SHELL_GetClipboardData"; + case 0x000C : return "SHELL_CloseClipboard"; + case 0x000D : return "_SHELL_Install_Taskman_Hooks"; + case 0x000E : return "SHELL_Hook_Properties"; + case 0x000F : return "SHELL_Unhook_Properties"; + case 0x0010 : return "SHELL_OEMKeyScan"; + case 0x0011 : return "SHELL_Update_User_Activity"; + case 0x0012 : return "_SHELL_UnhookSystemBroadcast"; + case 0x0013 : return "_SHELL_LocalAllocEx"; + case 0x0014 : return "_SHELL_LocalFree"; + case 0x0015 : return "_SHELL_LoadLibrary"; + case 0x0016 : return "_SHELL_FreeLibrary"; + case 0x0017 : return "_SHELL_GetProcAddress"; + case 0x0018 : return "_SHELL_CallDll"; + case 0x0019 : return "_SHELL_SuggestSingleMSDOSMode"; + case 0x001A : return "SHELL_CheckHotkeyAllowed"; + case 0x001B : return "_SHELL_GetDOSAppInfo"; + default: return "dunnoSV"; + } + case 0x0018: + switch (sv & 0x7fff) { + case 0x0000 : return "get version"; + case 0x0001 : return "enable/disable"; + case 0x0002 : return "reset detection"; + case 0x0003 : return "check idle"; + default: return "dunnoSV"; + } + case 0x001a: + switch (sv & 0x7fff) { + case 0x0000 : return "get version"; + case 0x0001 : return "send FILESYSCHANGE"; + case 0x0002 : return "do PSP adjust"; + default: return "dunnoSV"; + } + case 0x001b: + case 0x001c: + switch (sv & 0x7fff) { + case 0x0000 : return "get version"; + default: return "dunnoSV"; + } + case 0x0021: + switch (sv & 0x7fff) { + case 0x0000 : return "get version"; + case 0x0001 : return "init file"; + case 0x0002 : return "clean up"; + case 0x0003 : return "grow file"; + case 0x0004 : return "read or write"; + case 0x0005 : return "cancel"; + case 0x0006 : return "test I/O valid"; + case 0x0007 : return "Get_Size_Info"; + case 0x0008 : return "Set_Async_Manager"; + case 0x0009 : return "Call_Async_Manager"; + default: return "dunnoSV"; + } + case 0x0027: + switch (sv & 0x7fff) { + case 0x0000 : return "VXDLDR_Get_Version"; + case 0x0001 : return "VXDLDR_LoadDevice"; + case 0x0002 : return "VXDLDR_UnloadDevice"; + case 0x0003 : return "VXDLDR_DevInitSucceeded"; + case 0x0004 : return "VXDLDR_DevInitFailed"; + case 0x0005 : return "VXDLDR_GetDeviceList"; + case 0x0006 : return "VXDLDR_UnloadMe"; + case 0x0007 : return "PELDR_LoadModule"; + case 0x0008 : return "PELDR_GetModuleHandle"; + case 0x0009 : return "PELDR_GetModuleUsage"; + case 0x000A : return "PELDR_GetEntryPoint"; + case 0x000B : return "PELDR_GetProcAddress"; + case 0x000C : return "PELDR_AddExportTable"; + case 0x000D : return "PELDR_RemoveExportTable"; + case 0x000E : return "PELDR_FreeModule"; + case 0x000F : return "VXDLDR_Notify"; + case 0x0010 : return "_PELDR_InitCompleted"; + case 0x0011 : return "_PELDR_LoadModuleEx"; + default: return "dunnoSV"; + } + case 0x002A: + switch (sv & 0x7fff) { + case 0x0000 : return "VWin32_Get_Version"; + case 0x0001 : return "VWin32_Wake_For_Event"; + case 0x0002 : return "_VWIN32_QueueUserApc"; + case 0x0003 : return "_VWIN32_Get_Thread_Context"; + case 0x0004 : return "_VWIN32_Set_Thread_Context"; + case 0x0005 : return "_VWIN32_CopyMem"; + case 0x0006 : return "_VWIN32_BlockForTermination"; + case 0x0007 : return "_VWIN32_Emulate_Npx"; + case 0x0008 : return "_VWIN32_CheckDelayedNpxTrap"; + case 0x0009 : return "VWIN32_EnterCrstR0"; + case 0x000A : return "VWIN32_LeaveCrstR0"; + case 0x000B : return "_VWIN32_FaultPopup"; + case 0x000C : return "VWIN32_GetContextHandle"; + case 0x000D : return "VWIN32_GetCurrentProcessHandle"; + case 0x000E : return "_VWIN32_SetWin32Event"; + case 0x000F : return "_VWIN32_PulseWin32Event"; + case 0x0010 : return "_VWIN32_ResetWin32Event"; + case 0x0011 : return "_VWIN32_WaitSingleObject"; + case 0x0012 : return "_VWIN32_WaitMultipleObjects"; + case 0x0013 : return "_VWIN32_CreateRing0Thread"; + case 0x0014 : return "_VWIN32_CloseVxDHandle"; + case 0x0015 : return "VWIN32_ActiveTimeBiasSet"; + case 0x0016 : return "VWIN32_GetCurrentDirectory"; + case 0x0017 : return "VWIN32_BlueScreenPopup"; + case 0x0018 : return "VWIN32_TerminateApp"; + case 0x0019 : return "_VWIN32_QueueKernelAPC"; + case 0x001A : return "VWIN32_SysErrorBox"; + case 0x001B : return "_VWIN32_IsClientWin32"; + case 0x001C : return "VWIN32_IFSRIPWhenLev2Taken"; + default: return "dunnoSV"; + } + case 0x002b: + switch (sv & 0x7fff) { + case 0x0000 : return "VCOMM_Get_Version"; + case 0x0001 : return "_VCOMM_Register_Port_Driver"; + case 0x0002 : return "_VCOMM_Acquire_Port"; + case 0x0003 : return "_VCOMM_Release_Port"; + case 0x0004 : return "_VCOMM_OpenComm"; + case 0x0005 : return "_VCOMM_SetCommState"; + case 0x0006 : return "_VCOMM_GetCommState"; + case 0x0007 : return "_VCOMM_SetupComm"; + case 0x0008 : return "_VCOMM_TransmitCommChar"; + case 0x0009 : return "_VCOMM_CloseComm"; + case 0x000A : return "_VCOMM_GetCommQueueStatus"; + case 0x000B : return "_VCOMM_ClearCommError"; + case 0x000C : return "_VCOMM_GetModemStatus"; + case 0x000D : return "_VCOMM_GetCommProperties"; + case 0x000E : return "_VCOMM_EscapeCommFunction"; + case 0x000F : return "_VCOMM_PurgeComm"; + case 0x0010 : return "_VCOMM_SetCommEventMask"; + case 0x0011 : return "_VCOMM_GetCommEventMask"; + case 0x0012 : return "_VCOMM_WriteComm"; + case 0x0013 : return "_VCOMM_ReadComm"; + case 0x0014 : return "_VCOMM_EnableCommNotification"; + case 0x0015 : return "_VCOMM_GetLastError"; + case 0x0016 : return "_VCOMM_Steal_Port"; + case 0x0017 : return "_VCOMM_SetReadCallBack"; + case 0x0018 : return "_VCOMM_SetWriteCallBack"; + case 0x0019 : return "_VCOMM_GetSetCommTimeouts"; + case 0x001A : return "_VCOMM_SetWriteRequest"; + case 0x001B : return "_VCOMM_SetReadRequest"; + case 0x001C : return "_VCOMM_Dequeue_Request"; + case 0x001D : return "_VCOMM_Dequeue_Request"; + case 0x001E : return "_VCOMM_Enumerate_DevNodes"; + case 0x001F : return "VCOMM_Map_Win32DCB_To_Ring0"; + case 0x0020 : return "VCOMM_Map_Ring0DCB_To_Win32"; + case 0x0021 : return "_VCOMM_Get_Contention_Handler"; + case 0x0022 : return "_VCOMM_Map_Name_To_Resource"; + default: return "dunnoSV"; + } + case 0x0033: + switch (sv & 0x7fff) { + case 0x0000 : return "_CONFIGMG_Get_Version"; + case 0x0001 : return "_CONFIGMG_Initialize"; + case 0x0002 : return "_CONFIGMG_Locate_DevNode"; + case 0x0003 : return "_CONFIGMG_Get_Parent"; + case 0x0004 : return "_CONFIGMG_Get_Child"; + case 0x0005 : return "_CONFIGMG_Get_Sibling"; + case 0x0006 : return "_CONFIGMG_Get_Device_ID_Size"; + case 0x0007 : return "_CONFIGMG_Get_Device_ID"; + case 0x0008 : return "_CONFIGMG_Get_Depth"; + case 0x0009 : return "_CONFIGMG_Get_Private_DWord"; + case 0x000A : return "_CONFIGMG_Set_Private_DWord"; + case 0x000B : return "_CONFIGMG_Create_DevNode"; + case 0x000C : return "_CONFIGMG_Query_Remove_SubTree"; + case 0x000D : return "_CONFIGMG_Remove_SubTree"; + case 0x000E : return "_CONFIGMG_Register_Device_Driver"; + case 0x000F : return "_CONFIGMG_Register_Enumerator"; + case 0x0010 : return "_CONFIGMG_Register_Arbitrator"; + case 0x0011 : return "_CONFIGMG_Deregister_Arbitrator"; + case 0x0012 : return "_CONFIGMG_Query_Arbitrator_Free_Size"; + case 0x0013 : return "_CONFIGMG_Query_Arbitrator_Free_Data"; + case 0x0014 : return "_CONFIGMG_Sort_NodeList"; + case 0x0015 : return "_CONFIGMG_Yield"; + case 0x0016 : return "_CONFIGMG_Lock"; + case 0x0017 : return "_CONFIGMG_Unlock"; + case 0x0018 : return "_CONFIGMG_Add_Empty_Log_Conf"; + case 0x0019 : return "_CONFIGMG_Free_Log_Conf"; + case 0x001A : return "_CONFIGMG_Get_First_Log_Conf"; + case 0x001B : return "_CONFIGMG_Get_Next_Log_Conf"; + case 0x001C : return "_CONFIGMG_Add_Res_Des"; + case 0x001D : return "_CONFIGMG_Modify_Res_Des"; + case 0x001E : return "_CONFIGMG_Free_Res_Des"; + case 0x001F : return "_CONFIGMG_Get_Next_Res_Des"; + case 0x0020 : return "_CONFIGMG_Get_Performance_Info"; + case 0x0021 : return "_CONFIGMG_Get_Res_Des_Data_Size"; + case 0x0022 : return "_CONFIGMG_Get_Res_Des_Data"; + case 0x0023 : return "_CONFIGMG_Process_Events_Now"; + case 0x0024 : return "_CONFIGMG_Create_Range_List"; + case 0x0025 : return "_CONFIGMG_Add_Range"; + case 0x0026 : return "_CONFIGMG_Delete_Range"; + case 0x0027 : return "_CONFIGMG_Test_Range_Available"; + case 0x0028 : return "_CONFIGMG_Dup_Range_List"; + case 0x0029 : return "_CONFIGMG_Free_Range_List"; + case 0x002A : return "_CONFIGMG_Invert_Range_List"; + case 0x002B : return "_CONFIGMG_Intersect_Range_List"; + case 0x002C : return "_CONFIGMG_First_Range"; + case 0x002D : return "_CONFIGMG_Next_Range"; + case 0x002E : return "_CONFIGMG_Dump_Range_List"; + case 0x002F : return "_CONFIGMG_Load_DLVxDs"; + case 0x0030 : return "_CONFIGMG_Get_DDBs"; + case 0x0031 : return "_CONFIGMG_Get_CRC_CheckSum"; + case 0x0032 : return "_CONFIGMG_Register_DevLoader"; + case 0x0033 : return "_CONFIGMG_Reenumerate_DevNode"; + case 0x0034 : return "_CONFIGMG_Setup_DevNode"; + case 0x0035 : return "_CONFIGMG_Reset_Children_Marks"; + case 0x0036 : return "_CONFIGMG_Get_DevNode_Status"; + case 0x0037 : return "_CONFIGMG_Remove_Unmarked_Children"; + case 0x0038 : return "_CONFIGMG_ISAPNP_To_CM"; + case 0x0039 : return "_CONFIGMG_CallBack_Device_Driver"; + case 0x003A : return "_CONFIGMG_CallBack_Enumerator"; + case 0x003B : return "_CONFIGMG_Get_Alloc_Log_Conf"; + case 0x003C : return "_CONFIGMG_Get_DevNode_Key_Size"; + case 0x003D : return "_CONFIGMG_Get_DevNode_Key"; + case 0x003E : return "_CONFIGMG_Read_Registry_Value"; + case 0x003F : return "_CONFIGMG_Write_Registry_Value"; + case 0x0040 : return "_CONFIGMG_Disable_DevNode"; + case 0x0041 : return "_CONFIGMG_Enable_DevNode"; + case 0x0042 : return "_CONFIGMG_Move_DevNode"; + case 0x0043 : return "_CONFIGMG_Set_Bus_Info"; + case 0x0044 : return "_CONFIGMG_Get_Bus_Info"; + case 0x0045 : return "_CONFIGMG_Set_HW_Prof"; + case 0x0046 : return "_CONFIGMG_Recompute_HW_Prof"; + case 0x0047 : return "_CONFIGMG_Query_Change_HW_Prof"; + case 0x0048 : return "_CONFIGMG_Get_Device_Driver_Private_DWord"; + case 0x0049 : return "_CONFIGMG_Set_Device_Driver_Private_DWord"; + case 0x004A : return "_CONFIGMG_Get_HW_Prof_Flags"; + case 0x004B : return "_CONFIGMG_Set_HW_Prof_Flags"; + case 0x004C : return "_CONFIGMG_Read_Registry_Log_Confs"; + case 0x004D : return "_CONFIGMG_Run_Detection"; + case 0x004E : return "_CONFIGMG_Call_At_Appy_Time"; + case 0x004F : return "_CONFIGMG_Fail_Change_HW_Prof"; + case 0x0050 : return "_CONFIGMG_Set_Private_Problem"; + case 0x0051 : return "_CONFIGMG_Debug_DevNode"; + case 0x0052 : return "_CONFIGMG_Get_Hardware_Profile_Info"; + case 0x0053 : return "_CONFIGMG_Register_Enumerator_Function"; + case 0x0054 : return "_CONFIGMG_Call_Enumerator_Function"; + case 0x0055 : return "_CONFIGMG_Add_ID"; + case 0x0056 : return "_CONFIGMG_Find_Range"; + case 0x0057 : return "_CONFIGMG_Get_Global_State"; + case 0x0058 : return "_CONFIGMG_Broadcast_Device_Change_Message"; + case 0x0059 : return "_CONFIGMG_Call_DevNode_Handler"; + case 0x005A : return "_CONFIGMG_Remove_Reinsert_All"; + default: return "dunnoSV"; + } + case 0x048B: + switch (sv & 0x7fff) { + case 0x0000 : return "VXDLDR_Get_Version"; + case 0x0001 : return "VCACHE_Register"; + case 0x0002 : return "VCACHE_GetSize"; + case 0x0003 : return "VCACHE_CheckAvail"; + case 0x0004 : return "VCACHE_FindBlock"; + case 0x0005 : return "VCACHE_FreeBlock"; + case 0x0006 : return "VCACHE_MakeMRU"; + case 0x0007 : return "VCACHE_Hold"; + case 0x0008 : return "VCACHE_Unhold"; + case 0x0009 : return "VCACHE_Enum"; + case 0x000A : return "VCACHE_TestHandle"; + case 0x000B : return "VCACHE_VerifySums"; + case 0x000C : return "VCACHE_RecalcSums"; + case 0x000D : return "VCACHE_TestHold"; + case 0x000E : return "VCACHE_GetStats"; + case 0x000F : return "VCache_Deregister"; + case 0x0010 : return "VCache_AdjustMinimum"; + case 0x0011 : return "VCache_SwapBuffers"; + case 0x0012 : return "VCache_RelinquishPage"; + case 0x0013 : return "VCache_UseThisPage"; + case 0x0014 : return "_VCache_CreateLookupCache"; + case 0x0015 : return "_VCache_CloseLookupCache"; + case 0x0016 : return "_VCache_DeleteLookupCache"; + case 0x0017 : return "_VCache_Lookup"; + case 0x0018 : return "_VCache_UpdateLookup"; + default: return "dunnoSV"; + } + default: return "dunnoNR"; + } +} + + Bit8u lastint; void CPU_Interrupt(Bitu num,Bitu type,Bitu oldeip) { lastint=num; +// if ((num!=0x16) && (num!=0x1a) && (num!=0x28) && (num!=0x2a) && (num!=0x13)) LOG_MSG("INT %x EAX:%04X ECX:%04X EDX:%04X EBX:%04X CS:%04X EIP:%08X SS:%04X ESP:%08X",num,reg_eax,reg_ecx,reg_edx,reg_ebx,SegValue(cs),reg_eip,SegValue(ss),reg_esp); + if ((num==0x20) && (cpu.pmode)) { + PhysPt csip20 = SegPhys(cs)+reg_eip; + Bitu sv = mem_readw(csip20+2); + Bitu nr = mem_readw(csip20+4); + LOG_MSG("VxD service %s, %s (%X:%X)",translateVXDid(nr),translateVXDservice(nr,sv),nr,sv); + } #if C_DEBUG switch (num) { case 0xcd: @@ -463,7 +1491,7 @@ void CPU_Interrupt(Bitu num,Bitu type,Bitu oldeip) { return; } else { /* Protected Mode Interrupt */ - if ((reg_flags & FLAG_VM) && (type&CPU_INT_SOFTWARE)) { + if ((reg_flags & FLAG_VM) && (type&CPU_INT_SOFTWARE) && !(type&CPU_INT_NOIOPLCHECK)) { // LOG_MSG("Software int in v86, AH %X IOPL %x",reg_ah,(reg_flags & FLAG_IOPL) >>12); if ((reg_flags & FLAG_IOPL)!=FLAG_IOPL) { CPU_Exception(EXCEPTION_GP,0); @@ -677,13 +1705,7 @@ void CPU_IRET(bool use32,Bitu oldeip) { CPU_CHECK_COND(!cpu_tss.IsValid(), "TASK Iret without valid TSS", EXCEPTION_TS,cpu_tss.selector & 0xfffc) - // check if busy is set - switch (cpu_tss.desc.Type()) { - case DESC_286_TSS_B: case DESC_386_TSS_B: - break; - default: - E_Exit("TASK Iret:TSS not busy"); // or #TS(sel) - } + if (!cpu_tss.desc.IsBusy()) LOG(LOG_CPU,LOG_ERROR)("TASK Iret:TSS not busy"); Bitu back_link=cpu_tss.Get_back(); CPU_SwitchTask(back_link,TSwitch_IRET,oldeip); return; @@ -1238,7 +2260,6 @@ RET_same_level: return; } else { /* Return to outer level */ - if (bytes) E_Exit("RETF outer level with immediate value"); switch (desc.Type()) { case DESC_CODE_N_NC_A:case DESC_CODE_N_NC_NA: case DESC_CODE_R_NC_A:case DESC_CODE_R_NC_NA: @@ -1265,11 +2286,13 @@ RET_same_level: if (use32) { offset=CPU_Pop32(); selector=CPU_Pop32() & 0xffff; + reg_esp+=bytes; n_esp = CPU_Pop32(); n_ss = CPU_Pop32() & 0xffff; } else { offset=CPU_Pop16(); selector=CPU_Pop16(); + reg_esp+=bytes; n_esp = CPU_Pop16(); n_ss = CPU_Pop16(); } @@ -1308,11 +2331,11 @@ RET_same_level: if (n_ss_desc.Big()) { cpu.stack.big=true; cpu.stack.mask=0xffffffff; - reg_esp=n_esp; + reg_esp=n_esp+bytes; } else { cpu.stack.big=false; cpu.stack.mask=0xffff; - reg_sp=n_esp & 0xffff; + reg_sp=(n_esp & 0xffff)+bytes; } Descriptor desc; @@ -1359,18 +2382,43 @@ void CPU_SLDT(Bitu & selector) { selector=cpu.gdt.SLDT(); } -void CPU_LLDT(Bitu selector) { - cpu.gdt.LLDT(selector); +bool CPU_LLDT(Bitu selector) { + if (!cpu.gdt.LLDT(selector)) { + LOG(LOG_CPU,LOG_ERROR)("LLDT failed, selector=%X",selector); + return true; + } LOG(LOG_CPU,LOG_NORMAL)("LDT Set to %X",selector); + return false; } void CPU_STR(Bitu & selector) { selector=cpu_tss.selector; } -void CPU_LTR(Bitu selector) { - cpu_tss.SetSelector(selector); - cpu_tss.desc.SetBusy(true); +bool CPU_LTR(Bitu selector) { + if ((selector & 0xfffc)==0) { + cpu_tss.SetSelector(selector); + return false; + } + TSS_Descriptor desc; + if ((selector & 4) || (!cpu.gdt.GetDescriptor(selector,desc))) { + LOG(LOG_CPU,LOG_ERROR)("LTR failed, selector=%X",selector); + return CPU_PrepareException(EXCEPTION_GP,selector); + } + + if ((desc.Type()==DESC_286_TSS_A) || (desc.Type()==DESC_386_TSS_A)) { + if (!desc.saved.seg.p) { + LOG(LOG_CPU,LOG_ERROR)("LTR failed, selector=%X (not present)",selector); + return CPU_PrepareException(EXCEPTION_NP,selector); + } + if (!cpu_tss.SetSelector(selector)) E_Exit("LTR failed, selector=%X",selector); + cpu_tss.desc.SetBusy(true); + } else { + /* Descriptor was no available TSS descriptor */ + LOG(LOG_CPU,LOG_NORMAL)("LTR failed, selector=%X (type=%X)",selector,desc.Type()); + return CPU_PrepareException(EXCEPTION_GP,selector); + } + return false; } Bitu gdt_count=0; @@ -1413,6 +2461,7 @@ void CPU_SET_CRX(Bitu cr,Bitu value) { PAGING_Enable((value & CR0_PAGING)>0); } else { cpu.pmode=false; + if (value & CR0_PAGING) LOG_MSG("Paging requested without PE=1"); PAGING_Enable(false); LOG(LOG_CPU,LOG_NORMAL)("Real mode"); } @@ -1445,7 +2494,7 @@ Bitu CPU_GET_CRX(Bitu cr) { case 2: return paging.cr2; case 3: - return PAGING_GetDirBase(); + return PAGING_GetDirBase() & 0xfffff000; default: LOG(LOG_CPU,LOG_ERROR)("Unhandled MOV XXX, CR%d",cr); break; @@ -1462,6 +2511,58 @@ bool CPU_READ_CRX(Bitu cr,Bit32u & retvalue) { } +bool CPU_WRITE_DRX(Bitu dr,Bitu value) { + /* Check if privileged to access control registers */ + if (cpu.pmode && (cpu.cpl>0)) return CPU_PrepareException(EXCEPTION_GP,0); + switch (dr) { + case 0: + case 1: + case 2: + case 3: + cpu.drx[dr]=value; + break; + case 4: + case 6: + cpu.drx[6]=(value|0xffff0ff0) & 0xffffefff; + break; + case 5: + case 7: + cpu.drx[7]=(value|0x400) & 0xffff2fff; + break; + default: + LOG(LOG_CPU,LOG_ERROR)("Unhandled MOV DR%d,%X",dr,value); + break; + } + return false; +} + +bool CPU_READ_DRX(Bitu dr,Bit32u & retvalue) { + /* Check if privileged to access control registers */ + if (cpu.pmode && (cpu.cpl>0)) return CPU_PrepareException(EXCEPTION_GP,0); + switch (dr) { + case 0: + case 1: + case 2: + case 3: + case 6: + case 7: + retvalue=cpu.drx[dr]; + break; + case 4: + retvalue=cpu.drx[6]; + break; + case 5: + retvalue=cpu.drx[7]; + break; + default: + LOG(LOG_CPU,LOG_ERROR)("Unhandled MOV XXX, DR%d",dr); + retvalue=0; + break; + } + return false; +} + + void CPU_SMSW(Bitu & word) { word=cpu.cr0; } @@ -1693,8 +2794,7 @@ bool CPU_SetSegGeneral(SegNames seg,Bitu value) { } Descriptor desc; if (!cpu.gdt.GetDescriptor(value,desc)) { - E_Exit("CPU_SetSegGeneral: Segment beyond limits"); -// return CPU_PrepareException(EXCEPTION_GP,value & 0xfffc); + return CPU_PrepareException(EXCEPTION_GP,value & 0xfffc); } switch (desc.Type()) { case DESC_DATA_EU_RO_NA: case DESC_DATA_EU_RO_A: @@ -1738,7 +2838,6 @@ bool CPU_PopSeg(SegNames seg,bool use32) { void CPU_CPUID(void) { switch (reg_eax) { case 0: /* Vendor ID String and maximum level? */ - reg_eax=1; reg_eax=1; /* Maximum level */ reg_ebx='G' | ('e' << 8) | ('n' << 16) | ('u'<< 24); reg_edx='i' | ('n' << 8) | ('e' << 16) | ('I'<< 24); @@ -1767,17 +2866,12 @@ static Bits HLT_Decode(void) { } void CPU_HLT(Bitu oldeip) { - if (cpu.cpl) { - CPU_Exception(EXCEPTION_GP,0); - return; - } reg_eip=oldeip; CPU_Cycles=0; cpu.hlt.cs=SegValue(cs); cpu.hlt.eip=reg_eip; cpu.hlt.old_decoder=cpudecoder; cpudecoder=&HLT_Decode; - return; } void CPU_ENTER(bool use32,Bitu bytes,Bitu level) { @@ -1875,7 +2969,11 @@ public: cpu.stack.big=false; cpu.idt.SetBase(0); cpu.idt.SetLimit(1023); - + + for (Bitu i=0; i<7; i++) cpu.drx[i]=0; + cpu.drx[6]=0xffff1ff0; + cpu.drx[7]=0x00000400; + /* Init the cpu cores */ CPU_Core_Normal_Init(); CPU_Core_Simple_Init(); diff --git a/src/ints/ems.cpp b/src/ints/ems.cpp index f328f2db..e00c2cff 100644 --- a/src/ints/ems.cpp +++ b/src/ints/ems.cpp @@ -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 #include @@ -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));