1
0
Fork 0

better compatibility while in v86-mode (Strike Commander etc.)

Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2228
This commit is contained in:
Sebastian Strohhäcker 2005-07-04 20:20:19 +00:00
parent 352640d5a9
commit 0e0f294202
4 changed files with 57 additions and 20 deletions

View file

@ -63,8 +63,10 @@ void CPU_ARPL(Bitu & dest_sel,Bitu src_sel);
void CPU_LAR(Bitu selector,Bitu & ar);
void CPU_LSL(Bitu selector,Bitu & limit);
bool CPU_SET_CRX(Bitu cr,Bitu value);
void CPU_SET_CRX(Bitu cr,Bitu value);
bool CPU_WRITE_CRX(Bitu cr,Bitu value);
Bitu CPU_GET_CRX(Bitu cr);
bool CPU_READ_CRX(Bitu cr,Bit32u & retvalue);
void CPU_SMSW(Bitu & word);
Bitu CPU_LMSW(Bitu word);

View file

@ -128,7 +128,9 @@
Bitu which=(rm >> 3) & 7;
if (rm >= 0xc0 ) {
GetEArd;
*eard=CPU_GET_CRX(which);
Bit32u crx_value;
if (CPU_READ_CRX(which,crx_value)) RUNEXCEPTION();
*eard=crx_value;
} else {
GetEAa;
LOG(LOG_CPU,LOG_ERROR)("MOV XXX,CR%d with non-register",which);
@ -153,7 +155,7 @@
Bitu which=(rm >> 3) & 7;
if (rm >= 0xc0 ) {
GetEArd;
if (CPU_SET_CRX(which,*eard)) RUNEXCEPTION();
if (CPU_WRITE_CRX(which,*eard)) RUNEXCEPTION();
} else goto illegal_opcode;
}
break;

View file

@ -16,7 +16,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/* $Id: cpu.cpp,v 1.70 2005-04-25 19:01:11 qbix79 Exp $ */
/* $Id: cpu.cpp,v 1.71 2005-07-04 20:20:18 c2woody Exp $ */
#include <assert.h>
#include "dosbox.h"
@ -82,7 +82,7 @@ void CPU_Core_Dyn_X86_Init(void);
}
#elif defined(CPU_CHECK_EXCEPT)
#define CPU_CHECK_COND(cond,msg,exc,sel) { \
if (cond) {
if (cond) { \
CPU_Exception(exc,sel); \
return; \
} \
@ -158,10 +158,14 @@ bool CPU_STI(void) {
}
bool CPU_POPF(Bitu use32) {
if ((reg_flags & FLAG_VM) && (GETFLAG(IOPL)!=FLAG_IOPL))
if (cpu.pmode && GETFLAG(VM) && (GETFLAG(IOPL)!=FLAG_IOPL)) {
/* Not enough privileges to execute POPF */
return CPU_PrepareException(EXCEPTION_GP,0);
Bitu mask=cpu.cpl ? FMASK_NORMAL : FMASK_ALL;
if ((GETFLAG_IOPL<cpu.cpl) && !(reg_flags & FLAG_VM)) mask &= (~FLAG_IF);
}
Bitu mask=FMASK_ALL;
/* IOPL field can only be modified when CPL=0 or in real mode: */
if (cpu.pmode && (cpu.cpl>0)) mask &= (~FLAG_IOPL);
if (cpu.pmode && !GETFLAG(VM) && (GETFLAG_IOPL<cpu.cpl)) mask &= (~FLAG_IF);
if (use32)
CPU_SetFlags(CPU_Pop32(),mask);
else CPU_SetFlags(CPU_Pop16(),mask & 0xffff);
@ -169,10 +173,12 @@ bool CPU_POPF(Bitu use32) {
}
bool CPU_PUSHF(Bitu use32) {
if ((reg_flags & FLAG_VM) && (GETFLAG(IOPL)!=FLAG_IOPL))
if (cpu.pmode && GETFLAG(VM) && (GETFLAG(IOPL)!=FLAG_IOPL)) {
/* Not enough privileges to execute PUSHF */
return CPU_PrepareException(EXCEPTION_GP,0);
}
if (use32)
CPU_Push32(reg_flags & 0x00fcffff);
CPU_Push32(reg_flags & 0xfcffff);
else CPU_Push16(reg_flags);
return false;
}
@ -631,15 +637,14 @@ do_interrupt:
void CPU_IRET(bool use32,Bitu oldeip) {
if (!cpu.pmode) { /* RealMode IRET */
realmode_iret:
if (use32) {
reg_eip=CPU_Pop32();
SegSet16(cs,CPU_Pop32());
CPU_SetFlagsd(CPU_Pop32());
CPU_SetFlags(CPU_Pop32(),FMASK_ALL);
} else {
reg_eip=CPU_Pop16();
SegSet16(cs,CPU_Pop16());
CPU_SetFlagsw(CPU_Pop16());
CPU_SetFlags(CPU_Pop16(),FMASK_ALL & 0xffff);
}
cpu.code.big=false;
return;
@ -649,7 +654,21 @@ realmode_iret:
// win3.x e
CPU_Exception(EXCEPTION_GP,0);
return;
} else goto realmode_iret;
} else {
if (use32) {
reg_eip=CPU_Pop32();
SegSet16(cs,CPU_Pop32());
/* IOPL can not be modified in v86 mode by IRET */
CPU_SetFlags(CPU_Pop32(),FMASK_NORMAL|FLAG_NT);
} else {
reg_eip=CPU_Pop16();
SegSet16(cs,CPU_Pop16());
/* IOPL can not be modified in v86 mode by IRET */
CPU_SetFlags(CPU_Pop16(),FMASK_NORMAL|FLAG_NT);
}
cpu.code.big=false;
return;
}
}
/* Check if this is task IRET */
if (GETFLAG(NT)) {
@ -1380,12 +1399,12 @@ void CPU_SIDT(Bitu & limit,Bitu & base) {
}
bool CPU_SET_CRX(Bitu cr,Bitu value) {
void CPU_SET_CRX(Bitu cr,Bitu value) {
switch (cr) {
case 0:
{
Bitu changed=cpu.cr0 ^ value;
if (!changed) return false;
if (!changed) return;
cpu.cr0=value;
if (value & CR0_PROTECTION) {
cpu.pmode=true;
@ -1408,6 +1427,11 @@ bool CPU_SET_CRX(Bitu cr,Bitu value) {
LOG(LOG_CPU,LOG_ERROR)("Unhandled MOV CR%d,%X",cr,value);
break;
}
}
bool CPU_WRITE_CRX(Bitu cr,Bitu value) {
if (cpu.pmode && GETFLAG(VM)) return CPU_PrepareException(EXCEPTION_GP,0);
else CPU_SET_CRX(cr,value);
return false;
}
@ -1426,6 +1450,12 @@ Bitu CPU_GET_CRX(Bitu cr) {
return 0;
}
bool CPU_READ_CRX(Bitu cr,Bit32u & retvalue) {
if (cpu.pmode && GETFLAG(VM)) return CPU_PrepareException(EXCEPTION_GP,0);
retvalue=CPU_GET_CRX(cr);
return false;
}
void CPU_SMSW(Bitu & word) {
word=cpu.cr0;

View file

@ -16,7 +16,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/* $Id: dos_execute.cpp,v 1.45 2005-02-10 10:20:51 qbix79 Exp $ */
/* $Id: dos_execute.cpp,v 1.46 2005-07-04 20:20:19 c2woody Exp $ */
#include <string.h>
#include <ctype.h>
@ -131,7 +131,7 @@ bool DOS_Terminate(bool tsr) {
/* Set the CS:IP stored in int 0x22 back on the stack */
mem_writew(SegPhys(ss)+reg_sp+0,RealOff(old22));
mem_writew(SegPhys(ss)+reg_sp+2,RealSeg(old22));
mem_writew(SegPhys(ss)+reg_sp+4,0x200); //stack isn't preserved
mem_writew(SegPhys(ss)+reg_sp+4,reg_flags&(~FLAG_CF));
// Free memory owned by process
if (!tsr) DOS_FreeProcessMemory(mempsp);
DOS_UpdatePSPName();
@ -376,10 +376,13 @@ bool DOS_Execute(char * name,PhysPt block_pt,Bit8u flags) {
reg_sp-=6;
mem_writew(SegPhys(ss)+reg_sp+0,RealOff(csip));
mem_writew(SegPhys(ss)+reg_sp+2,RealSeg(csip));
mem_writew(SegPhys(ss)+reg_sp+4,0x200);
/* DOS starts programs with a RETF, so our IRET
should not modify the flags (e.g. IOPL in v86 mode) */
mem_writew(SegPhys(ss)+reg_sp+4,reg_flags&(~FLAG_CF));
/* Setup the rest of the registers */
reg_ax=0;reg_si=0x100;
reg_cx=reg_dx=reg_bx=reg_di=reg_bp=0;
reg_cx=reg_dx=reg_bx=reg_di=0;
reg_bp=0x91c; /* DOS internal stack begin relict */
SegSet16(ds,pspseg);SegSet16(es,pspseg);
#if C_DEBUG
/* Started from debug.com, then set breakpoint at start */