precalculate inverted stack mask; improve dynamic core stack functions
Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2606
This commit is contained in:
parent
ec58b58543
commit
2ae27a0bb9
5 changed files with 87 additions and 131 deletions
|
@ -418,7 +418,7 @@ struct CPUBlock {
|
|||
GDTDescriptorTable gdt;
|
||||
DescriptorTable idt;
|
||||
struct {
|
||||
Bitu mask;
|
||||
Bitu mask,notmask;
|
||||
bool big;
|
||||
} stack;
|
||||
struct {
|
||||
|
|
|
@ -20,8 +20,6 @@
|
|||
|
||||
#if (C_DYNAMIC_X86)
|
||||
|
||||
#define CHECKED_MEMORY_ACCESS
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
|
@ -46,11 +44,7 @@
|
|||
#include "paging.h"
|
||||
#include "inout.h"
|
||||
|
||||
#ifdef CHECKED_MEMORY_ACCESS
|
||||
#define CACHE_MAXSIZE (4096*2)
|
||||
#else
|
||||
#define CACHE_MAXSIZE (4096)
|
||||
#endif
|
||||
#define CACHE_PAGES (128*8)
|
||||
#define CACHE_TOTAL (CACHE_PAGES*4096)
|
||||
#define CACHE_BLOCKS (64*1024)
|
||||
|
@ -73,7 +67,7 @@ enum {
|
|||
G_EAX,G_ECX,G_EDX,G_EBX,
|
||||
G_ESP,G_EBP,G_ESI,G_EDI,
|
||||
G_ES,G_CS,G_SS,G_DS,G_FS,G_GS,
|
||||
G_FLAGS,G_SMASK,G_EIP,
|
||||
G_FLAGS,G_NEWESP,G_EIP,
|
||||
G_EA,G_STACK,G_CYCLES,
|
||||
G_TMPB,G_TMPW,G_SHIFT,
|
||||
G_EXIT,
|
||||
|
@ -155,7 +149,7 @@ static DynReg DynRegs[G_MAX];
|
|||
#define DREG(_WHICH_) &DynRegs[G_ ## _WHICH_ ]
|
||||
|
||||
static struct {
|
||||
Bitu ea,tmpb,tmpd,stack,shift;
|
||||
Bitu ea,tmpb,tmpd,stack,shift,newesp;
|
||||
} extra_regs;
|
||||
|
||||
static void IllegalOption(const char* msg) {
|
||||
|
@ -326,8 +320,8 @@ void CPU_Core_Dyn_X86_Init(void) {
|
|||
DynRegs[G_FLAGS].data=®_flags;
|
||||
DynRegs[G_FLAGS].flags=DYNFLG_LOAD|DYNFLG_SAVE;
|
||||
|
||||
DynRegs[G_SMASK].data=&cpu.stack.mask;
|
||||
DynRegs[G_SMASK].flags=DYNFLG_LOAD|DYNFLG_SAVE;
|
||||
DynRegs[G_NEWESP].data=&extra_regs.newesp;
|
||||
DynRegs[G_NEWESP].flags=0;
|
||||
|
||||
DynRegs[G_EIP].data=®_eip;
|
||||
DynRegs[G_EIP].flags=DYNFLG_LOAD|DYNFLG_SAVE;
|
||||
|
|
|
@ -220,7 +220,6 @@ static void dyn_fill_blocks(void) {
|
|||
used_save_info=0;
|
||||
}
|
||||
|
||||
#ifdef CHECKED_MEMORY_ACCESS
|
||||
static void dyn_read_byte(DynReg * addr,DynReg * dst,Bitu high) {
|
||||
gen_protectflags();
|
||||
gen_call_function((void *)&mem_readb_checked_x86,"%Dd%Id",addr,&core_dyn.readdata);
|
||||
|
@ -271,50 +270,13 @@ static void dyn_write_word_release(DynReg * addr,DynReg * val,bool dword) {
|
|||
else gen_call_function((void *)&mem_writew_checked_x86,"%Ddr%Dd",addr,val);
|
||||
dyn_check_bool_exception_al();
|
||||
}
|
||||
#else
|
||||
static void dyn_read_byte(DynReg * addr,DynReg * dst,Bitu high) {
|
||||
if (high) gen_call_function((void *)&mem_readb,"%Dd%Rh",addr,dst);
|
||||
else gen_call_function((void *)&mem_readb,"%Dd%Rl",addr,dst);
|
||||
}
|
||||
static void dyn_write_byte(DynReg * addr,DynReg * val,Bitu high) {
|
||||
if (high) gen_call_function((void *)&mem_writeb,"%Dd%Dh",addr,val);
|
||||
else gen_call_function((void *)&mem_writeb,"%Dd%Dd",addr,val);
|
||||
}
|
||||
static void dyn_read_word(DynReg * addr,DynReg * dst,bool dword) {
|
||||
if (dword) gen_call_function((void *)&mem_readd_dyncorex86,"%Dd%Rd",addr,dst);
|
||||
else gen_call_function((void *)&mem_readw_dyncorex86,"%Dd%Rw",addr,dst);
|
||||
}
|
||||
static void dyn_write_word(DynReg * addr,DynReg * val,bool dword) {
|
||||
if (dword) gen_call_function((void *)&mem_writed_dyncorex86,"%Dd%Dd",addr,val);
|
||||
else gen_call_function((void *)&mem_writew_dyncorex86,"%Dd%Dd",addr,val);
|
||||
}
|
||||
static void dyn_read_byte_release(DynReg * addr,DynReg * dst,Bitu high) {
|
||||
if (high) gen_call_function((void *)&mem_readb,"%Ddr%Rh",addr,dst);
|
||||
else gen_call_function((void *)&mem_readb,"%Ddr%Rl",addr,dst);
|
||||
}
|
||||
static void dyn_write_byte_release(DynReg * addr,DynReg * val,Bitu high) {
|
||||
if (high) gen_call_function((void *)&mem_writeb,"%Ddr%Dh",addr,val);
|
||||
else gen_call_function((void *)&mem_writeb,"%Ddr%Dd",addr,val);
|
||||
}
|
||||
static void dyn_read_word_release(DynReg * addr,DynReg * dst,bool dword) {
|
||||
if (dword) gen_call_function((void *)&mem_readd_dyncorex86,"%Ddr%Rd",addr,dst);
|
||||
else gen_call_function((void *)&mem_readw_dyncorex86,"%Ddr%Rw",addr,dst);
|
||||
}
|
||||
static void dyn_write_word_release(DynReg * addr,DynReg * val,bool dword) {
|
||||
if (dword) gen_call_function((void *)&mem_writed_dyncorex86,"%Ddr%Dd",addr,val);
|
||||
else gen_call_function((void *)&mem_writew_dyncorex86,"%Ddr%Dd",addr,val);
|
||||
}
|
||||
#endif
|
||||
|
||||
static void dyn_push_unchecked(DynReg * dynreg) {
|
||||
gen_protectflags();
|
||||
if (decode.big_op) {
|
||||
gen_dop_word_imm(DOP_SUB,true,DREG(ESP),4);
|
||||
} else {
|
||||
gen_dop_word_imm(DOP_SUB,true,DREG(ESP),2);
|
||||
}
|
||||
gen_dop_word(DOP_AND,true,DREG(ESP),DREG(SMASK));
|
||||
gen_dop_word(DOP_MOV,true,DREG(STACK),DREG(ESP));
|
||||
gen_lea(DREG(STACK),DREG(ESP),0,0,decode.big_op?(-4):(-2));
|
||||
gen_dop_word_var(DOP_AND,true,DREG(STACK),&cpu.stack.mask);
|
||||
gen_dop_word_var(DOP_AND,true,DREG(ESP),&cpu.stack.notmask);
|
||||
gen_dop_word(DOP_OR,true,DREG(ESP),DREG(STACK));
|
||||
gen_dop_word(DOP_ADD,true,DREG(STACK),DREG(SS));
|
||||
if (decode.big_op) {
|
||||
gen_call_function((void *)&mem_writed,"%Drd%Dd",DREG(STACK),dynreg);
|
||||
|
@ -326,13 +288,11 @@ static void dyn_push_unchecked(DynReg * dynreg) {
|
|||
|
||||
static void dyn_push(DynReg * dynreg) {
|
||||
gen_protectflags();
|
||||
gen_dop_word(DOP_MOV,true,DREG(STACK),DREG(ESP));
|
||||
if (decode.big_op) {
|
||||
gen_dop_word_imm(DOP_SUB,true,DREG(STACK),4);
|
||||
} else {
|
||||
gen_dop_word_imm(DOP_SUB,true,DREG(STACK),2);
|
||||
}
|
||||
gen_dop_word(DOP_AND,true,DREG(STACK),DREG(SMASK));
|
||||
gen_lea(DREG(STACK),DREG(ESP),0,0,decode.big_op?(-4):(-2));
|
||||
gen_dop_word(DOP_MOV,true,DREG(NEWESP),DREG(ESP));
|
||||
gen_dop_word_var(DOP_AND,true,DREG(STACK),&cpu.stack.mask);
|
||||
gen_dop_word_var(DOP_AND,true,DREG(NEWESP),&cpu.stack.notmask);
|
||||
gen_dop_word(DOP_OR,true,DREG(NEWESP),DREG(STACK));
|
||||
gen_dop_word(DOP_ADD,true,DREG(STACK),DREG(SS));
|
||||
if (decode.big_op) {
|
||||
gen_call_function((void *)&mem_writed_checked_x86,"%Drd%Dd",DREG(STACK),dynreg);
|
||||
|
@ -341,54 +301,36 @@ static void dyn_push(DynReg * dynreg) {
|
|||
gen_call_function((void *)&mem_writew_checked_x86,"%Drd%Dd",DREG(STACK),dynreg);
|
||||
}
|
||||
dyn_check_bool_exception_al();
|
||||
/* everything was ok, change registers now */
|
||||
if (decode.big_op) {
|
||||
gen_dop_word_imm(DOP_SUB,true,DREG(ESP),4);
|
||||
} else {
|
||||
gen_dop_word_imm(DOP_SUB,true,DREG(ESP),2);
|
||||
}
|
||||
gen_dop_word(DOP_AND,true,DREG(ESP),DREG(SMASK));
|
||||
/* everything was ok, change register now */
|
||||
gen_dop_word(DOP_MOV,true,DREG(ESP),DREG(NEWESP));
|
||||
gen_releasereg(DREG(NEWESP));
|
||||
}
|
||||
|
||||
static void dyn_pop_unchecked(DynReg * dynreg) {
|
||||
static void dyn_pop(DynReg * dynreg,bool checked=true) {
|
||||
gen_protectflags();
|
||||
gen_dop_word(DOP_MOV,true,DREG(STACK),DREG(ESP));
|
||||
gen_dop_word(DOP_AND,true,DREG(STACK),DREG(SMASK));
|
||||
gen_dop_word_var(DOP_AND,true,DREG(STACK),&cpu.stack.mask);
|
||||
gen_dop_word(DOP_ADD,true,DREG(STACK),DREG(SS));
|
||||
if (decode.big_op) {
|
||||
gen_call_function((void *)&mem_readd,"%Rd%Drd",dynreg,DREG(STACK));
|
||||
if (checked) {
|
||||
if (decode.big_op) {
|
||||
gen_call_function((void *)&mem_readd_checked_x86,"%Drd%Id",DREG(STACK),&core_dyn.readdata);
|
||||
} else {
|
||||
gen_call_function((void *)&mem_readw_checked_x86,"%Drd%Id",DREG(STACK),&core_dyn.readdata);
|
||||
}
|
||||
dyn_check_bool_exception_al();
|
||||
gen_mov_host(&core_dyn.readdata,dynreg,decode.big_op?4:2);
|
||||
} else {
|
||||
gen_call_function((void *)&mem_readw,"%Rw%Drd",dynreg,DREG(STACK));
|
||||
if (decode.big_op) {
|
||||
gen_call_function((void *)&mem_readd,"%Rd%Drd",dynreg,DREG(STACK));
|
||||
} else {
|
||||
gen_call_function((void *)&mem_readw,"%Rw%Drd",dynreg,DREG(STACK));
|
||||
}
|
||||
}
|
||||
if (dynreg!=DREG(ESP)) {
|
||||
if (decode.big_op) {
|
||||
gen_dop_word_imm(DOP_ADD,true,DREG(ESP),4);
|
||||
} else {
|
||||
gen_dop_word_imm(DOP_ADD,true,DREG(ESP),2);
|
||||
}
|
||||
gen_dop_word(DOP_AND,true,DREG(ESP),DREG(SMASK));
|
||||
}
|
||||
}
|
||||
|
||||
static void dyn_pop(DynReg * dynreg) {
|
||||
gen_protectflags();
|
||||
gen_dop_word(DOP_MOV,true,DREG(STACK),DREG(ESP));
|
||||
gen_dop_word(DOP_AND,true,DREG(STACK),DREG(SMASK));
|
||||
gen_dop_word(DOP_ADD,true,DREG(STACK),DREG(SS));
|
||||
if (decode.big_op) {
|
||||
gen_call_function((void *)&mem_readd_checked_x86,"%Drd%Id",DREG(STACK),&core_dyn.readdata);
|
||||
} else {
|
||||
gen_call_function((void *)&mem_readw_checked_x86,"%Drd%Id",DREG(STACK),&core_dyn.readdata);
|
||||
}
|
||||
dyn_check_bool_exception_al();
|
||||
gen_mov_host(&core_dyn.readdata,dynreg,decode.big_op?4:2);
|
||||
if (dynreg!=DREG(ESP)) {
|
||||
if (decode.big_op) {
|
||||
gen_dop_word_imm(DOP_ADD,true,DREG(ESP),4);
|
||||
} else {
|
||||
gen_dop_word_imm(DOP_ADD,true,DREG(ESP),2);
|
||||
}
|
||||
gen_dop_word(DOP_AND,true,DREG(ESP),DREG(SMASK));
|
||||
gen_lea(DREG(STACK),DREG(ESP),0,0,decode.big_op?4:2);
|
||||
gen_dop_word_var(DOP_AND,true,DREG(STACK),&cpu.stack.mask);
|
||||
gen_dop_word_var(DOP_AND,true,DREG(ESP),&cpu.stack.notmask);
|
||||
gen_dop_word(DOP_OR,true,DREG(ESP),DREG(STACK));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -575,9 +517,7 @@ static void dyn_mov_ebib(void) {
|
|||
if (decode.modrm.mod<3) {
|
||||
dyn_fill_ea();
|
||||
gen_call_write(DREG(EA),decode_fetchb(),1);
|
||||
#ifdef CHECKED_MEMORY_ACCESS
|
||||
dyn_check_bool_exception_al();
|
||||
#endif
|
||||
} else {
|
||||
gen_dop_byte_imm(DOP_MOV,&DynRegs[decode.modrm.rm&3],decode.modrm.rm&4,decode_fetchb());
|
||||
}
|
||||
|
@ -696,9 +636,7 @@ static void dyn_mov_eviv(void) {
|
|||
if (decode.modrm.mod<3) {
|
||||
dyn_fill_ea();
|
||||
gen_call_write(DREG(EA),decode.big_op ? decode_fetchd() : decode_fetchw(),decode.big_op?4:2);
|
||||
#ifdef CHECKED_MEMORY_ACCESS
|
||||
dyn_check_bool_exception_al();
|
||||
#endif
|
||||
} else {
|
||||
gen_dop_word_imm(DOP_MOV,decode.big_op,&DynRegs[decode.modrm.rm],decode.big_op ? decode_fetchd() : decode_fetchw());
|
||||
}
|
||||
|
@ -985,7 +923,6 @@ static void dyn_load_seg(SegNames seg,DynReg * src) {
|
|||
gen_releasereg(DREG(TMPB));
|
||||
} else gen_call_function((void *)CPU_SetSegGeneral,"%Id%Drw",seg,src);
|
||||
gen_releasereg(&DynRegs[G_ES+seg]);
|
||||
if (seg==ss) gen_releasereg(DREG(SMASK));
|
||||
}
|
||||
|
||||
static void dyn_load_seg_off_ea(SegNames seg) {
|
||||
|
@ -1034,7 +971,6 @@ static void dyn_pop_seg(SegNames seg) {
|
|||
gen_releasereg(DREG(TMPB));
|
||||
gen_releasereg(&DynRegs[G_ES+seg]);
|
||||
gen_releasereg(DREG(ESP));
|
||||
if (seg==ss) gen_releasereg(DREG(SMASK));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1062,13 +998,13 @@ static void dyn_enter(void) {
|
|||
|
||||
static void dyn_leave(void) {
|
||||
gen_protectflags();
|
||||
gen_dop_word(DOP_MOV,true,DREG(TMPW),DREG(SMASK));
|
||||
gen_dop_word_var(DOP_MOV,true,DREG(TMPW),&cpu.stack.mask);
|
||||
gen_sop_word(SOP_NOT,true,DREG(TMPW));
|
||||
gen_dop_word(DOP_AND,true,DREG(ESP),DREG(TMPW));
|
||||
gen_dop_word(DOP_MOV,true,DREG(TMPW),DREG(EBP));
|
||||
gen_dop_word(DOP_AND,true,DREG(TMPW),DREG(SMASK));
|
||||
gen_dop_word_var(DOP_AND,true,DREG(TMPW),&cpu.stack.mask);
|
||||
gen_dop_word(DOP_OR,true,DREG(ESP),DREG(TMPW));
|
||||
dyn_pop_unchecked(DREG(EBP));
|
||||
dyn_pop(DREG(EBP),false);
|
||||
gen_releasereg(DREG(TMPW));
|
||||
}
|
||||
|
||||
|
@ -1444,7 +1380,7 @@ restart_prefix:
|
|||
break;
|
||||
case 0x61: /* POPA */
|
||||
for (i=G_EDI;i>=G_EAX;i--) {
|
||||
dyn_pop_unchecked((i!=G_ESP) ? &DynRegs[i] : DREG(TMPW));
|
||||
dyn_pop((i!=G_ESP) ? &DynRegs[i] : DREG(TMPW),false);
|
||||
}
|
||||
gen_releasereg(DREG(TMPW));
|
||||
break;
|
||||
|
@ -1453,7 +1389,7 @@ restart_prefix:
|
|||
case 0x65:dyn_segprefix(gs);goto restart_prefix;
|
||||
//Push immediates
|
||||
//Operand size
|
||||
case 0x66:decode.big_op=!cpu.code.big;;goto restart_prefix;
|
||||
case 0x66:decode.big_op=!cpu.code.big;goto restart_prefix;
|
||||
//Address size
|
||||
case 0x67:decode.big_addr=!cpu.code.big;goto restart_prefix;
|
||||
case 0x68: /* PUSH Iv */
|
||||
|
|
|
@ -457,6 +457,29 @@ finish:
|
|||
else cache_addw(imm);
|
||||
}
|
||||
|
||||
static void gen_dop_word_var(DualOps op,bool dword,DynReg * dr1,void* drd) {
|
||||
GenReg * gr1=FindDynReg(dr1,dword && op==DOP_MOV);
|
||||
Bit8u tmp;
|
||||
switch (op) {
|
||||
case DOP_ADD: tmp=0x03; break;
|
||||
case DOP_ADC: tmp=0x13; break;
|
||||
case DOP_SUB: tmp=0x2b; break;
|
||||
case DOP_SBB: tmp=0x1b; break;
|
||||
case DOP_CMP: tmp=0x3b; break;
|
||||
case DOP_XOR: tmp=0x33; break;
|
||||
case DOP_AND: tmp=0x23; break;
|
||||
case DOP_OR: tmp=0x0b; break;
|
||||
case DOP_TEST: tmp=0x85; break;
|
||||
case DOP_MOV: tmp=0x8b; break;
|
||||
case DOP_XCHG: tmp=0x87; break;
|
||||
default:
|
||||
IllegalOption("gen_dop_word_var");
|
||||
}
|
||||
if (!dword) cache_addb(0x66);
|
||||
cache_addw(tmp|(0x05+((gr1->index)<<3))<<8);
|
||||
cache_addd((Bit32u)drd);
|
||||
}
|
||||
|
||||
static void gen_imul_word(bool dword,DynReg * dr1,DynReg * dr2) {
|
||||
GenReg * gr1=FindDynReg(dr1);GenReg * gr2=FindDynReg(dr2);
|
||||
dr1->flags|=DYNFLG_CHANGED;
|
||||
|
@ -728,21 +751,12 @@ static void gen_call_write(DynReg * dr,Bit32u val,Bitu write_size) {
|
|||
x86gen.regs[X86_REG_EDX]->Clear();
|
||||
/* Do the actual call to the procedure */
|
||||
cache_addb(0xe8);
|
||||
#ifdef CHECKED_MEMORY_ACCESS
|
||||
switch (write_size) {
|
||||
case 1: cache_addd((Bit32u)mem_writeb_checked_x86 - (Bit32u)cache.pos-4); break;
|
||||
case 2: cache_addd((Bit32u)mem_writew_checked_x86 - (Bit32u)cache.pos-4); break;
|
||||
case 4: cache_addd((Bit32u)mem_writed_checked_x86 - (Bit32u)cache.pos-4); break;
|
||||
default: IllegalOption("gen_call_write");
|
||||
}
|
||||
#else
|
||||
switch (write_size) {
|
||||
case 1: cache_addd((Bit32u)mem_writeb - (Bit32u)cache.pos-4); break;
|
||||
case 2: cache_addd((Bit32u)mem_writew_dyncorex86 - (Bit32u)cache.pos-4); break;
|
||||
case 4: cache_addd((Bit32u)mem_writed_dyncorex86 - (Bit32u)cache.pos-4); break;
|
||||
default: IllegalOption("gen_call_write");
|
||||
}
|
||||
#endif
|
||||
|
||||
cache_addw(0xc483); //ADD ESP,8
|
||||
cache_addb(2*4);
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
/* $Id: cpu.cpp,v 1.79 2006-02-26 16:11:00 qbix79 Exp $ */
|
||||
/* $Id: cpu.cpp,v 1.80 2006-04-18 17:44:25 c2woody Exp $ */
|
||||
|
||||
#include <assert.h>
|
||||
#include "dosbox.h"
|
||||
|
@ -90,26 +90,26 @@ void CPU_Core_Dyn_X86_Cache_Init(bool enable_cache);
|
|||
|
||||
|
||||
void CPU_Push16(Bitu value) {
|
||||
Bit32u new_esp=(reg_esp&~cpu.stack.mask)|((reg_esp-2)&cpu.stack.mask);
|
||||
Bit32u new_esp=(reg_esp&cpu.stack.notmask)|((reg_esp-2)&cpu.stack.mask);
|
||||
mem_writew(SegPhys(ss) + (new_esp & cpu.stack.mask) ,value);
|
||||
reg_esp=new_esp;
|
||||
}
|
||||
|
||||
void CPU_Push32(Bitu value) {
|
||||
Bit32u new_esp=(reg_esp&~cpu.stack.mask)|((reg_esp-4)&cpu.stack.mask);
|
||||
Bit32u new_esp=(reg_esp&cpu.stack.notmask)|((reg_esp-4)&cpu.stack.mask);
|
||||
mem_writed(SegPhys(ss) + (new_esp & cpu.stack.mask) ,value);
|
||||
reg_esp=new_esp;
|
||||
}
|
||||
|
||||
Bitu CPU_Pop16(void) {
|
||||
Bitu val=mem_readw(SegPhys(ss) + (reg_esp & cpu.stack.mask));
|
||||
reg_esp=(reg_esp&~cpu.stack.mask)|((reg_esp+2)&cpu.stack.mask);
|
||||
reg_esp=(reg_esp&cpu.stack.notmask)|((reg_esp+2)&cpu.stack.mask);
|
||||
return val;
|
||||
}
|
||||
|
||||
Bitu CPU_Pop32(void) {
|
||||
Bitu val=mem_readd(SegPhys(ss) + (reg_esp & cpu.stack.mask));
|
||||
reg_esp=(reg_esp&~cpu.stack.mask)|((reg_esp+4)&cpu.stack.mask);
|
||||
reg_esp=(reg_esp&cpu.stack.notmask)|((reg_esp+4)&cpu.stack.mask);
|
||||
return val;
|
||||
}
|
||||
|
||||
|
@ -409,11 +409,11 @@ doconforming:
|
|||
bool CPU_IO_Exception(Bitu port,Bitu size) {
|
||||
if (cpu.pmode && ((GETFLAG_IOPL<cpu.cpl) || GETFLAG(VM))) {
|
||||
if (!cpu_tss.is386) goto doexception;
|
||||
PhysPt where=cpu_tss.base+0x66;
|
||||
Bitu ofs=mem_readw(where);
|
||||
PhysPt bwhere=cpu_tss.base+0x66;
|
||||
Bitu ofs=mem_readw(bwhere);
|
||||
if (ofs>cpu_tss.limit) goto doexception;
|
||||
where=cpu_tss.base+ofs+(port/8);
|
||||
Bitu map=mem_readw(where);
|
||||
bwhere=cpu_tss.base+ofs+(port/8);
|
||||
Bitu map=mem_readw(bwhere);
|
||||
Bitu mask=(0xffff>>(16-size)) << (port&7);
|
||||
if (map & mask) goto doexception;
|
||||
}
|
||||
|
@ -552,10 +552,12 @@ void CPU_Interrupt(Bitu num,Bitu type,Bitu oldeip) {
|
|||
if (n_ss_desc.Big()) {
|
||||
cpu.stack.big=true;
|
||||
cpu.stack.mask=0xffffffff;
|
||||
cpu.stack.notmask=0;
|
||||
reg_esp=n_esp;
|
||||
} else {
|
||||
cpu.stack.big=false;
|
||||
cpu.stack.mask=0xffff;
|
||||
cpu.stack.notmask=0xffff0000;
|
||||
reg_sp=n_esp & 0xffff;
|
||||
}
|
||||
|
||||
|
@ -814,10 +816,12 @@ void CPU_IRET(bool use32,Bitu oldeip) {
|
|||
if (n_ss_desc.Big()) {
|
||||
cpu.stack.big=true;
|
||||
cpu.stack.mask=0xffffffff;
|
||||
cpu.stack.notmask=0;
|
||||
reg_esp=n_esp;
|
||||
} else {
|
||||
cpu.stack.big=false;
|
||||
cpu.stack.mask=0xffff;
|
||||
cpu.stack.notmask=0xffff0000;
|
||||
reg_sp=n_esp & 0xffff;
|
||||
}
|
||||
|
||||
|
@ -1070,10 +1074,12 @@ call_code:
|
|||
if (n_ss_desc.Big()) {
|
||||
cpu.stack.big=true;
|
||||
cpu.stack.mask=0xffffffff;
|
||||
cpu.stack.notmask=0;
|
||||
reg_esp=n_esp;
|
||||
} else {
|
||||
cpu.stack.big=false;
|
||||
cpu.stack.mask=0xffff;
|
||||
cpu.stack.notmask=0xffff0000;
|
||||
reg_sp=n_esp & 0xffff;
|
||||
}
|
||||
|
||||
|
@ -1303,10 +1309,12 @@ RET_same_level:
|
|||
if (n_ss_desc.Big()) {
|
||||
cpu.stack.big=true;
|
||||
cpu.stack.mask=0xffffffff;
|
||||
cpu.stack.notmask=0;
|
||||
reg_esp=n_esp+bytes;
|
||||
} else {
|
||||
cpu.stack.big=false;
|
||||
cpu.stack.mask=0xffff;
|
||||
cpu.stack.notmask=0xffff0000;
|
||||
reg_sp=(n_esp & 0xffff)+bytes;
|
||||
}
|
||||
|
||||
|
@ -1712,6 +1720,7 @@ bool CPU_SetSegGeneral(SegNames seg,Bitu value) {
|
|||
if (seg==ss) {
|
||||
cpu.stack.big=false;
|
||||
cpu.stack.mask=0xffff;
|
||||
cpu.stack.notmask=0xffff0000;
|
||||
}
|
||||
return false;
|
||||
} else {
|
||||
|
@ -1750,9 +1759,11 @@ bool CPU_SetSegGeneral(SegNames seg,Bitu value) {
|
|||
if (desc.Big()) {
|
||||
cpu.stack.big=true;
|
||||
cpu.stack.mask=0xffffffff;
|
||||
cpu.stack.notmask=0;
|
||||
} else {
|
||||
cpu.stack.big=false;
|
||||
cpu.stack.mask=0xffff;
|
||||
cpu.stack.notmask=0xffff0000;
|
||||
}
|
||||
} else {
|
||||
if ((value & 0xfffc)==0) {
|
||||
|
@ -1799,7 +1810,7 @@ bool CPU_PopSeg(SegNames seg,bool use32) {
|
|||
Bitu val=mem_readw(SegPhys(ss) + (reg_esp & cpu.stack.mask));
|
||||
if (CPU_SetSegGeneral(seg,val)) return true;
|
||||
Bitu addsp=use32?0x04:0x02;
|
||||
reg_esp=(reg_esp&~cpu.stack.mask)|((reg_esp+addsp)&cpu.stack.mask);
|
||||
reg_esp=(reg_esp&cpu.stack.notmask)|((reg_esp+addsp)&cpu.stack.mask);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -1872,7 +1883,7 @@ void CPU_ENTER(bool use32,Bitu bytes,Bitu level) {
|
|||
}
|
||||
}
|
||||
sp_index-=bytes;
|
||||
reg_esp=(reg_esp&~cpu.stack.mask)|((sp_index)&cpu.stack.mask);
|
||||
reg_esp=(reg_esp&cpu.stack.notmask)|((sp_index)&cpu.stack.mask);
|
||||
}
|
||||
|
||||
extern void GFX_SetTitle(Bits cycles ,Bits frameskip,bool paused);
|
||||
|
@ -1938,6 +1949,7 @@ public:
|
|||
CPU_SET_CRX(0,0); //Initialize
|
||||
cpu.code.big=false;
|
||||
cpu.stack.mask=0xffff;
|
||||
cpu.stack.notmask=0xffff0000;
|
||||
cpu.stack.big=false;
|
||||
cpu.idt.SetBase(0);
|
||||
cpu.idt.SetLimit(1023);
|
||||
|
|
Loading…
Add table
Reference in a new issue