Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Updated pagefault handling in the normal core. #15

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ Patches/Customizations
* Patched to support max memory of 383MB. This can be used for running Win9x (although not tested)
* Apple Pencil gesture support
* Additional DOS support commands (such as XCOPY, DOSIDLE, MEM etc). See branch `vfile-additions` for more information.
* Updated pagefault handling for normal core. Disables pagefault recursion to enable better support for running Windows 95. See [Vogons discussion](https://www.vogons.org/viewtopic.php?f=41&t=36629)

Acknowledgements
====
Expand Down
11 changes: 6 additions & 5 deletions dosbox/include/cpu.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,11 +41,10 @@


#define CPU_ARCHTYPE_MIXED 0xff
#define CPU_ARCHTYPE_386SLOW 0x30
#define CPU_ARCHTYPE_386FAST 0x35
#define CPU_ARCHTYPE_486OLDSLOW 0x40
#define CPU_ARCHTYPE_486NEWSLOW 0x45
#define CPU_ARCHTYPE_PENTIUMSLOW 0x50
#define CPU_ARCHTYPE_386 0x35
#define CPU_ARCHTYPE_486OLD 0x40
#define CPU_ARCHTYPE_486NEW 0x45
#define CPU_ARCHTYPE_PENTIUM 0x50

/* CPU Cycle Timing */
extern Bit32s CPU_Cycles;
Expand Down Expand Up @@ -89,6 +88,7 @@ void CPU_Reset_AutoAdjust(void);

extern Bit16u parity_lookup[256];

void CPU_SetCPL(Bitu newcpl);
bool CPU_LLDT(Bitu selector);
bool CPU_LTR(Bitu selector);
void CPU_LIDT(Bitu limit,Bitu base);
Expand Down Expand Up @@ -182,6 +182,7 @@ void CPU_SetFlags(Bitu word,Bitu mask);
#define CR0_FPUEMULATION 0x00000004
#define CR0_TASKSWITCH 0x00000008
#define CR0_FPUPRESENT 0x00000010
#define CR0_WRITEPROTECT 0x00010000
#define CR0_PAGING 0x80000000

// reasons for triggering a debug exception
Expand Down
15 changes: 15 additions & 0 deletions dosbox/include/paging.h
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,8 @@ class PageHandler {
/* Some other functions */
void PAGING_Enable(bool enabled);
bool PAGING_Enabled(void);
void PAGING_SetWP(bool wp);
void PAGING_SwitchCPL(bool isUser);

Bitu PAGING_GetDirBase(void);
void PAGING_SetDirBase(Bitu cr3);
Expand Down Expand Up @@ -154,6 +156,7 @@ typedef struct {
struct PagingBlock {
Bitu cr3;
Bitu cr2;
bool wp;
struct {
Bitu page;
PhysPt addr;
Expand All @@ -174,6 +177,18 @@ struct PagingBlock {
Bitu used;
Bit32u entries[PAGING_LINKS];
} links;
struct {
Bitu used;
Bit32u entries[PAGING_LINKS];
} ur_links;
struct {
Bitu used;
Bit32u entries[PAGING_LINKS];
} krw_links;
struct {
Bitu used;
Bit32u entries[PAGING_LINKS];
} kr_links; // WP-only
Bit32u firstmb[LINK_START];
bool enabled;
};
Expand Down
2 changes: 1 addition & 1 deletion dosbox/src/cpu/core_full/load.h
Original file line number Diff line number Diff line change
Expand Up @@ -506,7 +506,7 @@ switch (inst.code.load) {
CPU_SW_Interrupt_NoIOPLCheck(1,GetIP());
continue;
case D_RDTSC: {
if (CPU_ArchitectureType<CPU_ARCHTYPE_PENTIUMSLOW) goto illegalopcode;
if (CPU_ArchitectureType<CPU_ARCHTYPE_PENTIUM) goto illegalopcode;
Bit64s tsc=(Bit64s)(PIC_FullIndex()*(double)(CPU_CycleAutoAdjust?70000:CPU_CycleMax));
reg_edx=(Bit32u)(tsc>>32);
reg_eax=(Bit32u)(tsc&0xffffffff);
Expand Down
6 changes: 3 additions & 3 deletions dosbox/src/cpu/core_full/op.h
Original file line number Diff line number Diff line change
Expand Up @@ -603,15 +603,15 @@ switch (inst.code.op) {
inst_op1_d&=~(1 << (inst_op2_d & 31));
break;
case O_BSWAPw:
if (CPU_ArchitectureType<CPU_ARCHTYPE_486OLDSLOW) goto illegalopcode;
if (CPU_ArchitectureType<CPU_ARCHTYPE_486OLD) goto illegalopcode;
BSWAPW(inst_op1_w);
break;
case O_BSWAPd:
if (CPU_ArchitectureType<CPU_ARCHTYPE_486OLDSLOW) goto illegalopcode;
if (CPU_ArchitectureType<CPU_ARCHTYPE_486OLD) goto illegalopcode;
BSWAPD(inst_op1_d);
break;
case O_CMPXCHG:
if (CPU_ArchitectureType<CPU_ARCHTYPE_486NEWSLOW) goto illegalopcode;
if (CPU_ArchitectureType<CPU_ARCHTYPE_486NEW) goto illegalopcode;
FillFlags();
if (inst_op1_d==reg_eax) {
inst_op1_d=reg_32(inst.rm_index);
Expand Down
40 changes: 17 additions & 23 deletions dosbox/src/cpu/core_normal/prefix_0f.h
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,7 @@
break;
CASE_0F_B(0x08) /* INVD */
CASE_0F_B(0x09) /* WBINVD */
if (CPU_ArchitectureType<CPU_ARCHTYPE_486OLDSLOW) goto illegal_opcode;
if (CPU_ArchitectureType<CPU_ARCHTYPE_486OLD) goto illegal_opcode;
if (cpu.pmode && cpu.cpl) EXCEPTION(EXCEPTION_GP);
break;
CASE_0F_B(0x20) /* MOV Rd.CRx */
Expand All @@ -156,9 +156,7 @@
LOG(LOG_CPU,LOG_ERROR)("MOV XXX,CR%u with non-register",which);
}
GetEArd;
Bit32u crx_value;
if (CPU_READ_CRX(which,crx_value)) RUNEXCEPTION();
*eard=crx_value;
if (CPU_READ_CRX(which,*eard)) RUNEXCEPTION();
}
break;
CASE_0F_B(0x21) /* MOV Rd,DRx */
Expand All @@ -170,9 +168,7 @@
LOG(LOG_CPU,LOG_ERROR)("MOV XXX,DR%u with non-register",which);
}
GetEArd;
Bit32u drx_value;
if (CPU_READ_DRX(which,drx_value)) RUNEXCEPTION();
*eard=drx_value;
if (CPU_READ_DRX(which,*eard)) RUNEXCEPTION();
}
break;
CASE_0F_B(0x22) /* MOV CRx,Rd */
Expand Down Expand Up @@ -208,9 +204,7 @@
LOG(LOG_CPU,LOG_ERROR)("MOV XXX,TR%u with non-register",which);
}
GetEArd;
Bit32u trx_value;
if (CPU_READ_TRX(which,trx_value)) RUNEXCEPTION();
*eard=trx_value;
if (CPU_READ_TRX(which,*eard)) RUNEXCEPTION();
}
break;
CASE_0F_B(0x26) /* MOV TRx,Rd */
Expand All @@ -227,7 +221,7 @@
break;
CASE_0F_B(0x31) /* RDTSC */
{
if (CPU_ArchitectureType<CPU_ARCHTYPE_PENTIUMSLOW) goto illegal_opcode;
if (CPU_ArchitectureType<CPU_ARCHTYPE_PENTIUM) goto illegal_opcode;
/* Use a fixed number when in auto cycles mode as else the reported value changes constantly */
Bit64s tsc=(Bit64s)(PIC_FullIndex()*(double) (CPU_CycleAutoAdjust?70000:CPU_CycleMax));
reg_edx=(Bit32u)(tsc>>32);
Expand Down Expand Up @@ -361,7 +355,7 @@
break;
CASE_0F_B(0xb0) /* cmpxchg Eb,Gb */
{
if (CPU_ArchitectureType<CPU_ARCHTYPE_486OLDSLOW) goto illegal_opcode;
if (CPU_ArchitectureType<CPU_ARCHTYPE_486OLD) goto illegal_opcode;
FillFlags();
GetRMrb;
if (rm >= 0xc0 ) {
Expand Down Expand Up @@ -389,7 +383,7 @@
}
CASE_0F_W(0xb1) /* cmpxchg Ew,Gw */
{
if (CPU_ArchitectureType<CPU_ARCHTYPE_486OLDSLOW) goto illegal_opcode;
if (CPU_ArchitectureType<CPU_ARCHTYPE_486OLD) goto illegal_opcode;
FillFlags();
GetRMrw;
if (rm >= 0xc0 ) {
Expand Down Expand Up @@ -579,42 +573,42 @@
}
CASE_0F_B(0xc0) /* XADD Gb,Eb */
{
if (CPU_ArchitectureType<CPU_ARCHTYPE_486OLDSLOW) goto illegal_opcode;
if (CPU_ArchitectureType<CPU_ARCHTYPE_486OLD) goto illegal_opcode;
GetRMrb;Bit8u oldrmrb=*rmrb;
if (rm >= 0xc0 ) {GetEArb;*rmrb=*earb;*earb+=oldrmrb;}
else {GetEAa;*rmrb=LoadMb(eaa);SaveMb(eaa,LoadMb(eaa)+oldrmrb);}
break;
}
CASE_0F_W(0xc1) /* XADD Gw,Ew */
{
if (CPU_ArchitectureType<CPU_ARCHTYPE_486OLDSLOW) goto illegal_opcode;
if (CPU_ArchitectureType<CPU_ARCHTYPE_486OLD) goto illegal_opcode;
GetRMrw;Bit16u oldrmrw=*rmrw;
if (rm >= 0xc0 ) {GetEArw;*rmrw=*earw;*earw+=oldrmrw;}
else {GetEAa;*rmrw=LoadMw(eaa);SaveMw(eaa,LoadMw(eaa)+oldrmrw);}
break;
}
CASE_0F_W(0xc8) /* BSWAP AX */
if (CPU_ArchitectureType<CPU_ARCHTYPE_486OLDSLOW) goto illegal_opcode;
if (CPU_ArchitectureType<CPU_ARCHTYPE_486OLD) goto illegal_opcode;
BSWAPW(reg_ax);break;
CASE_0F_W(0xc9) /* BSWAP CX */
if (CPU_ArchitectureType<CPU_ARCHTYPE_486OLDSLOW) goto illegal_opcode;
if (CPU_ArchitectureType<CPU_ARCHTYPE_486OLD) goto illegal_opcode;
BSWAPW(reg_cx);break;
CASE_0F_W(0xca) /* BSWAP DX */
if (CPU_ArchitectureType<CPU_ARCHTYPE_486OLDSLOW) goto illegal_opcode;
if (CPU_ArchitectureType<CPU_ARCHTYPE_486OLD) goto illegal_opcode;
BSWAPW(reg_dx);break;
CASE_0F_W(0xcb) /* BSWAP BX */
if (CPU_ArchitectureType<CPU_ARCHTYPE_486OLDSLOW) goto illegal_opcode;
if (CPU_ArchitectureType<CPU_ARCHTYPE_486OLD) goto illegal_opcode;
BSWAPW(reg_bx);break;
CASE_0F_W(0xcc) /* BSWAP SP */
if (CPU_ArchitectureType<CPU_ARCHTYPE_486OLDSLOW) goto illegal_opcode;
if (CPU_ArchitectureType<CPU_ARCHTYPE_486OLD) goto illegal_opcode;
BSWAPW(reg_sp);break;
CASE_0F_W(0xcd) /* BSWAP BP */
if (CPU_ArchitectureType<CPU_ARCHTYPE_486OLDSLOW) goto illegal_opcode;
if (CPU_ArchitectureType<CPU_ARCHTYPE_486OLD) goto illegal_opcode;
BSWAPW(reg_bp);break;
CASE_0F_W(0xce) /* BSWAP SI */
if (CPU_ArchitectureType<CPU_ARCHTYPE_486OLDSLOW) goto illegal_opcode;
if (CPU_ArchitectureType<CPU_ARCHTYPE_486OLD) goto illegal_opcode;
BSWAPW(reg_si);break;
CASE_0F_W(0xcf) /* BSWAP DI */
if (CPU_ArchitectureType<CPU_ARCHTYPE_486OLDSLOW) goto illegal_opcode;
if (CPU_ArchitectureType<CPU_ARCHTYPE_486OLD) goto illegal_opcode;
BSWAPW(reg_di);break;

32 changes: 30 additions & 2 deletions dosbox/src/cpu/core_normal/prefix_66.h
Original file line number Diff line number Diff line change
Expand Up @@ -149,8 +149,36 @@
CASE_D(0x60) /* PUSHAD */
{
Bitu tmpesp = reg_esp;
Push_32(reg_eax);Push_32(reg_ecx);Push_32(reg_edx);Push_32(reg_ebx);
Push_32(tmpesp);Push_32(reg_ebp);Push_32(reg_esi);Push_32(reg_edi);
Bitu tmp=reg_esp;
Bitu tmp2=(tmp&cpu.stack.notmask)|((tmp-4)&cpu.stack.mask);
mem_writed(SegPhys(ss) + (tmp2 & cpu.stack.mask) ,reg_eax);
tmp=tmp2;
tmp2=(tmp&cpu.stack.notmask)|((tmp-4)&cpu.stack.mask);
mem_writed(SegPhys(ss) + (tmp2 & cpu.stack.mask) ,reg_ecx);
tmp=tmp2;
tmp2=(tmp&cpu.stack.notmask)|((tmp-4)&cpu.stack.mask);
mem_writed(SegPhys(ss) + (tmp2 & cpu.stack.mask) ,reg_edx);
tmp=tmp2;
tmp2=(tmp&cpu.stack.notmask)|((tmp-4)&cpu.stack.mask);
mem_writed(SegPhys(ss) + (tmp2 & cpu.stack.mask) ,reg_ebx);
tmp=tmp2;
tmp2=(tmp&cpu.stack.notmask)|((tmp-4)&cpu.stack.mask);
mem_writed(SegPhys(ss) + (tmp2 & cpu.stack.mask) ,tmpesp);
tmp=tmp2;
tmp2=(tmp&cpu.stack.notmask)|((tmp-4)&cpu.stack.mask);
mem_writed(SegPhys(ss) + (tmp2 & cpu.stack.mask) ,reg_ebp);
tmp=tmp2;
tmp2=(tmp&cpu.stack.notmask)|((tmp-4)&cpu.stack.mask);
mem_writed(SegPhys(ss) + (tmp2 & cpu.stack.mask) ,reg_esi);
tmp=tmp2;
tmp2=(tmp&cpu.stack.notmask)|((tmp-4)&cpu.stack.mask);
mem_writed(SegPhys(ss) + (tmp2 & cpu.stack.mask) ,reg_edi);
tmp=tmp2;
reg_esp=tmp;

//Bitu tmpesp = reg_esp;
//Push_32(reg_eax);Push_32(reg_ecx);Push_32(reg_edx);Push_32(reg_ebx);
//Push_32(tmpesp);Push_32(reg_ebp);Push_32(reg_esi);Push_32(reg_edi);
}; break;
CASE_D(0x61) /* POPAD */
reg_edi=Pop_32();reg_esi=Pop_32();reg_ebp=Pop_32();Pop_32();//Don't save ESP
Expand Down
20 changes: 10 additions & 10 deletions dosbox/src/cpu/core_normal/prefix_66_0f.h
Original file line number Diff line number Diff line change
Expand Up @@ -239,7 +239,7 @@
}
CASE_0F_D(0xb1) /* CMPXCHG Ed,Gd */
{
if (CPU_ArchitectureType<CPU_ARCHTYPE_486NEWSLOW) goto illegal_opcode;
if (CPU_ArchitectureType<CPU_ARCHTYPE_486NEW) goto illegal_opcode;
FillFlags();
GetRMrd;
if (rm >= 0xc0) {
Expand Down Expand Up @@ -437,33 +437,33 @@
}
CASE_0F_D(0xc1) /* XADD Gd,Ed */
{
if (CPU_ArchitectureType<CPU_ARCHTYPE_486OLDSLOW) goto illegal_opcode;
if (CPU_ArchitectureType<CPU_ARCHTYPE_486OLD) goto illegal_opcode;
GetRMrd;Bit32u oldrmrd=*rmrd;
if (rm >= 0xc0 ) {GetEArd;*rmrd=*eard;*eard+=oldrmrd;}
else {GetEAa;*rmrd=LoadMd(eaa);SaveMd(eaa,LoadMd(eaa)+oldrmrd);}
break;
}
CASE_0F_D(0xc8) /* BSWAP EAX */
if (CPU_ArchitectureType<CPU_ARCHTYPE_486OLDSLOW) goto illegal_opcode;
if (CPU_ArchitectureType<CPU_ARCHTYPE_486OLD) goto illegal_opcode;
BSWAPD(reg_eax);break;
CASE_0F_D(0xc9) /* BSWAP ECX */
if (CPU_ArchitectureType<CPU_ARCHTYPE_486OLDSLOW) goto illegal_opcode;
if (CPU_ArchitectureType<CPU_ARCHTYPE_486OLD) goto illegal_opcode;
BSWAPD(reg_ecx);break;
CASE_0F_D(0xca) /* BSWAP EDX */
if (CPU_ArchitectureType<CPU_ARCHTYPE_486OLDSLOW) goto illegal_opcode;
if (CPU_ArchitectureType<CPU_ARCHTYPE_486OLD) goto illegal_opcode;
BSWAPD(reg_edx);break;
CASE_0F_D(0xcb) /* BSWAP EBX */
if (CPU_ArchitectureType<CPU_ARCHTYPE_486OLDSLOW) goto illegal_opcode;
if (CPU_ArchitectureType<CPU_ARCHTYPE_486OLD) goto illegal_opcode;
BSWAPD(reg_ebx);break;
CASE_0F_D(0xcc) /* BSWAP ESP */
if (CPU_ArchitectureType<CPU_ARCHTYPE_486OLDSLOW) goto illegal_opcode;
if (CPU_ArchitectureType<CPU_ARCHTYPE_486OLD) goto illegal_opcode;
BSWAPD(reg_esp);break;
CASE_0F_D(0xcd) /* BSWAP EBP */
if (CPU_ArchitectureType<CPU_ARCHTYPE_486OLDSLOW) goto illegal_opcode;
if (CPU_ArchitectureType<CPU_ARCHTYPE_486OLD) goto illegal_opcode;
BSWAPD(reg_ebp);break;
CASE_0F_D(0xce) /* BSWAP ESI */
if (CPU_ArchitectureType<CPU_ARCHTYPE_486OLDSLOW) goto illegal_opcode;
if (CPU_ArchitectureType<CPU_ARCHTYPE_486OLD) goto illegal_opcode;
BSWAPD(reg_esi);break;
CASE_0F_D(0xcf) /* BSWAP EDI */
if (CPU_ArchitectureType<CPU_ARCHTYPE_486OLDSLOW) goto illegal_opcode;
if (CPU_ArchitectureType<CPU_ARCHTYPE_486OLD) goto illegal_opcode;
BSWAPD(reg_edi);break;
48 changes: 42 additions & 6 deletions dosbox/src/cpu/core_normal/prefix_none.h
Original file line number Diff line number Diff line change
Expand Up @@ -217,8 +217,40 @@
CASE_W(0x60) /* PUSHA */
{
Bit16u old_sp=reg_sp;
Push_16(reg_ax);Push_16(reg_cx);Push_16(reg_dx);Push_16(reg_bx);
Push_16(old_sp);Push_16(reg_bp);Push_16(reg_si);Push_16(reg_di);
Bit32u tmp=reg_esp;
//Push_16(reg_ax);
Bitu tmp2=(tmp&cpu.stack.notmask)|((tmp-2)&cpu.stack.mask);
mem_writew(SegPhys(ss) + (tmp2 & cpu.stack.mask) ,reg_ax);
tmp=tmp2;
//Push_16(reg_cx);
tmp2=(tmp&cpu.stack.notmask)|((tmp-2)&cpu.stack.mask);
mem_writew(SegPhys(ss) + (tmp2 & cpu.stack.mask) ,reg_cx);
tmp=tmp2;
//Push_16(reg_dx);
tmp2=(tmp&cpu.stack.notmask)|((tmp-2)&cpu.stack.mask);
mem_writew(SegPhys(ss) + (tmp2 & cpu.stack.mask) ,reg_dx);
tmp=tmp2;
//Push_16(reg_bx);
tmp2=(tmp&cpu.stack.notmask)|((tmp-2)&cpu.stack.mask);
mem_writew(SegPhys(ss) + (tmp2 & cpu.stack.mask) ,reg_bx);
tmp=tmp2;
//Push_16(old_sp);
tmp2=(tmp&cpu.stack.notmask)|((tmp-2)&cpu.stack.mask);
mem_writew(SegPhys(ss) + (tmp2 & cpu.stack.mask) ,old_sp);
tmp=tmp2;
//Push_16(reg_bp);
tmp2=(tmp&cpu.stack.notmask)|((tmp-2)&cpu.stack.mask);
mem_writew(SegPhys(ss) + (tmp2 & cpu.stack.mask) ,reg_bp);
tmp=tmp2;
//Push_16(reg_si);
tmp2=(tmp&cpu.stack.notmask)|((tmp-2)&cpu.stack.mask);
mem_writew(SegPhys(ss) + (tmp2 & cpu.stack.mask) ,reg_si);
tmp=tmp2;
//Push_16(reg_di);
tmp2=(tmp&cpu.stack.notmask)|((tmp-2)&cpu.stack.mask);
mem_writew(SegPhys(ss) + (tmp2 & cpu.stack.mask) ,reg_di);
tmp=tmp2;
reg_sp=tmp;
}
break;
CASE_W(0x61) /* POPA */
Expand Down Expand Up @@ -692,17 +724,21 @@
GetRMrw;
if (rm >= 0xc0) goto illegal_opcode;
GetEAa;
if (CPU_SetSegGeneral(es,LoadMw(eaa+2))) RUNEXCEPTION();
*rmrw=LoadMw(eaa);
Bitu j=LoadMw(eaa+2);
Bitu k=LoadMw(eaa);
if (CPU_SetSegGeneral(es,j)) RUNEXCEPTION();
*rmrw=k;
break;
}
CASE_W(0xc5) /* LDS */
{
GetRMrw;
if (rm >= 0xc0) goto illegal_opcode;
GetEAa;
if (CPU_SetSegGeneral(ds,LoadMw(eaa+2))) RUNEXCEPTION();
*rmrw=LoadMw(eaa);
Bitu j=LoadMw(eaa+2);
Bitu k=LoadMw(eaa);
if (CPU_SetSegGeneral(ds,j)) RUNEXCEPTION();
*rmrw=k;
break;
}
CASE_B(0xc6) /* MOV Eb,Ib */
Expand Down
6 changes: 4 additions & 2 deletions dosbox/src/cpu/core_normal/support.h
Original file line number Diff line number Diff line change
Expand Up @@ -75,9 +75,11 @@ static INLINE Bit32s Fetchds() {
}

#define JumpCond32_d(COND) { \
Bit32s i; \
if (COND) i = Fetchds(); \
SAVEIP; \
if (COND) reg_eip+=Fetchds(); \
reg_eip+=4; \
if (COND) reg_eip+=i; \
else reg_eip+=4; \
continue; \
}

Expand Down
Loading