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:
parent
352640d5a9
commit
0e0f294202
4 changed files with 57 additions and 20 deletions
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 */
|
||||
|
|
Loading…
Add table
Reference in a new issue