Changed exception handling to let core start the exception.
Added support for segment load exceptions Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1482
This commit is contained in:
parent
a3f5f3c445
commit
9c7b2aa638
11 changed files with 206 additions and 155 deletions
|
@ -61,9 +61,12 @@ l_M_Ewx:
|
|||
if (inst.rm<0xc0) inst.op1.ds=(Bit16s)LoadMw(inst.rm_eaa);
|
||||
else inst.op1.ds=(Bit16s)reg_16(inst.rm_eai);
|
||||
break;
|
||||
case M_EwIb:
|
||||
inst.op2.d=Fetchb();
|
||||
goto l_M_Ew;
|
||||
case M_EwIbx:
|
||||
inst.op2.ds=Fetchbs();
|
||||
goto l_M_Ew;
|
||||
goto l_M_Ew;
|
||||
case M_EwIw:
|
||||
inst.op2.d=Fetchw();
|
||||
goto l_M_Ew;
|
||||
|
@ -96,6 +99,9 @@ l_M_Ew:
|
|||
if (inst.rm<0xc0) inst.op1.d=(Bit32s)LoadMd(inst.rm_eaa);
|
||||
else inst.op1.d=(Bit32s)reg_32(inst.rm_eai);
|
||||
break;
|
||||
case M_EdIb:
|
||||
inst.op2.d=Fetchb();
|
||||
goto l_M_Ed;
|
||||
case M_EdIbx:
|
||||
inst.op2.ds=Fetchbs();
|
||||
goto l_M_Ed;
|
||||
|
@ -486,7 +492,10 @@ l_M_Ed:
|
|||
goto nextopcode;
|
||||
case D_HLT:
|
||||
LEAVECORE;
|
||||
CPU_HLT(IPPoint-inst.start);
|
||||
if (CPU_HLT()) {
|
||||
reg_eip-=IPPoint-inst.start;
|
||||
CPU_StartException();
|
||||
}
|
||||
return CBRET_NONE;
|
||||
default:
|
||||
LOG(LOG_CPU,LOG_ERROR)("LOAD:Unhandled code %d opcode %X",inst.code.load,inst.entry);
|
||||
|
|
|
@ -345,7 +345,10 @@ switch (inst.code.op) {
|
|||
else if (DEBUG_IntBreakpoint(inst.op1.b))
|
||||
return debugCallback;
|
||||
#endif
|
||||
CPU_SW_Interrupt(inst.op1.b,IPPoint-inst.start);
|
||||
if (CPU_SW_Interrupt(inst.op1.b)) {
|
||||
reg_eip-=IPPoint-inst.start;
|
||||
CPU_StartException();
|
||||
}
|
||||
goto restart_core;
|
||||
case O_INb:
|
||||
reg_al=IO_Read(inst.op1.d);
|
||||
|
@ -453,11 +456,11 @@ switch (inst.code.op) {
|
|||
inst.op1.d=CPU_GET_CRX(inst.rm_index);
|
||||
break;
|
||||
case O_M_DRx_Rd:
|
||||
LOG(LOG_CPU,LOG_NORMAL)("MOV DR%d,%X",inst.rm_index,inst.op1.d);
|
||||
// LOG(LOG_CPU,LOG_NORMAL)("MOV DR%d,%X",inst.rm_index,inst.op1.d);
|
||||
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);
|
||||
// LOG(LOG_CPU,LOG_NORMAL)("MOV %X,DR%d",inst.op1.d,inst.rm_index);
|
||||
break;
|
||||
case O_LAR:
|
||||
{
|
||||
|
@ -483,14 +486,14 @@ switch (inst.code.op) {
|
|||
break;
|
||||
case O_BSFw:
|
||||
{
|
||||
FillFlags();
|
||||
if (!inst.op1.w) {
|
||||
SETFLAGBIT(ZF,true);
|
||||
goto nextopcode;
|
||||
} else {
|
||||
Bitu count=0;
|
||||
while (count<16) {
|
||||
if ((inst.op1.w>>count) & 1) break;
|
||||
count++;
|
||||
while (1) {
|
||||
if (inst.op1.w & 0x1) break;
|
||||
count++;inst.op1.w>>=1;
|
||||
}
|
||||
inst.op1.d=count;
|
||||
SETFLAGBIT(ZF,false);
|
||||
|
@ -502,11 +505,12 @@ switch (inst.code.op) {
|
|||
FillFlags();
|
||||
if (!inst.op1.d) {
|
||||
SETFLAGBIT(ZF,true);
|
||||
goto nextopcode;
|
||||
} else {
|
||||
Bitu count=0;
|
||||
while (count<32) {
|
||||
if ((inst.op1.d>>count) & 1) break;
|
||||
count++;
|
||||
while (1) {
|
||||
if (inst.op1.d & 0x1) break;
|
||||
count++;inst.op1.d>>=1;
|
||||
}
|
||||
inst.op1.d=count;
|
||||
SETFLAGBIT(ZF,false);
|
||||
|
@ -518,11 +522,12 @@ switch (inst.code.op) {
|
|||
FillFlags();
|
||||
if (!inst.op1.w) {
|
||||
SETFLAGBIT(ZF,true);
|
||||
goto nextopcode;
|
||||
} else {
|
||||
Bits count=15;
|
||||
while (count>0) {
|
||||
if ((inst.op1.w>>count) & 1) break;
|
||||
count--;
|
||||
Bitu count=15;
|
||||
while (1) {
|
||||
if (inst.op1.w & 0x8000) break;
|
||||
count--;inst.op1.w<<=1;
|
||||
}
|
||||
inst.op1.d=count;
|
||||
SETFLAGBIT(ZF,false);
|
||||
|
@ -534,11 +539,12 @@ switch (inst.code.op) {
|
|||
FillFlags();
|
||||
if (!inst.op1.d) {
|
||||
SETFLAGBIT(ZF,true);
|
||||
goto nextopcode;
|
||||
} else {
|
||||
Bits count=31;
|
||||
while (count>0) {
|
||||
if ((inst.op1.d>>count) & 1) break;
|
||||
count--;
|
||||
Bitu count=31;
|
||||
while (1) {
|
||||
if (inst.op1.d & 0x80000000) break;
|
||||
count--;inst.op1.d<<=1;
|
||||
}
|
||||
inst.op1.d=count;
|
||||
SETFLAGBIT(ZF,false);
|
||||
|
@ -546,57 +552,42 @@ switch (inst.code.op) {
|
|||
}
|
||||
break;
|
||||
case O_BTw:
|
||||
FillFlags();
|
||||
SETFLAGBIT(CF,(inst.op1.d & (1 << (inst.op2.d & 15))));
|
||||
break;
|
||||
case O_BTSw:
|
||||
FillFlags();
|
||||
SETFLAGBIT(CF,(inst.op1.d & (1 << (inst.op2.d & 15))));
|
||||
inst.op1.d|=(1 << (inst.op2.d & 15));
|
||||
break;
|
||||
case O_BTCw:
|
||||
FillFlags();
|
||||
SETFLAGBIT(CF,(inst.op1.d & (1 << (inst.op2.d & 15))));
|
||||
inst.op1.d&=~(1 << (inst.op2.d & 15));
|
||||
break;
|
||||
case O_BTRw:
|
||||
{
|
||||
Bitu val;PhysPt read;
|
||||
Bitu mask=1 << (inst.op1.d & 15);
|
||||
FillFlags();
|
||||
if (inst.rm<0xc0) {
|
||||
read=inst.rm_eaa;//+2*(inst.op1.d / 16);
|
||||
val=mem_readw(read);
|
||||
} else {
|
||||
val=reg_16(inst.rm_eai);
|
||||
}
|
||||
SETFLAGBIT(CF,(val&mask)>0);
|
||||
if (inst.code.op==O_BTSw) val|=mask;
|
||||
if (inst.code.op==O_BTRw) val&=~mask;
|
||||
if (inst.code.op==O_BTCw) val^=mask;
|
||||
if (inst.code.op==O_BTw) break;
|
||||
if (inst.rm<0xc0) {
|
||||
mem_writew(read,val);
|
||||
} else {
|
||||
reg_16(inst.rm_eai)=val;
|
||||
}
|
||||
}
|
||||
FillFlags();
|
||||
SETFLAGBIT(CF,(inst.op1.d & (1 << (inst.op2.d & 15))));
|
||||
inst.op1.d^=(1 << (inst.op2.d & 15));
|
||||
break;
|
||||
case O_BTd:
|
||||
case O_BTSd:
|
||||
case O_BTCd:
|
||||
case O_BTRd:
|
||||
{
|
||||
Bitu val;PhysPt read;
|
||||
Bitu mask=1 << (inst.op1.d & 31);
|
||||
FillFlags();
|
||||
if (inst.rm<0xc0) {
|
||||
read=inst.rm_eaa;//+4*(inst.op1.d / 32);
|
||||
val=mem_readd(read);
|
||||
} else {
|
||||
val=reg_32(inst.rm_eai);
|
||||
}
|
||||
SETFLAGBIT(CF,(val&mask)>0);
|
||||
if (inst.code.op==O_BTSd) val|=mask;
|
||||
if (inst.code.op==O_BTRd) val&=~mask;
|
||||
if (inst.code.op==O_BTCd) val^=mask;
|
||||
if (inst.code.op==O_BTd) break;
|
||||
if (inst.rm<0xc0) {
|
||||
mem_writed(read,val);
|
||||
} else {
|
||||
reg_32(inst.rm_eai)=val;
|
||||
}
|
||||
}
|
||||
FillFlags();
|
||||
SETFLAGBIT(CF,(inst.op1.d & (1 << (inst.op2.d & 31))));
|
||||
break;
|
||||
case O_BTSd:
|
||||
FillFlags();
|
||||
SETFLAGBIT(CF,(inst.op1.d & (1 << (inst.op2.d & 31))));
|
||||
inst.op1.d|=(1 << (inst.op2.d & 31));
|
||||
break;
|
||||
case O_BTCd:
|
||||
FillFlags();
|
||||
SETFLAGBIT(CF,(inst.op1.d & (1 << (inst.op2.d & 31))));
|
||||
inst.op1.d&=~(1 << (inst.op2.d & 31));
|
||||
break;
|
||||
case O_BTRd:
|
||||
FillFlags();
|
||||
SETFLAGBIT(CF,(inst.op1.d & (1 << (inst.op2.d & 31))));
|
||||
inst.op1.d^=(1 << (inst.op2.d & 31));
|
||||
case O_BSWAP:
|
||||
BSWAP(inst.op1.d);
|
||||
break;
|
||||
|
|
|
@ -294,23 +294,23 @@ static OpCode OpCodeTable[1024]={
|
|||
|
||||
/* 0x1a0 - 0x1a7 */
|
||||
{L_SEG ,0 ,S_PUSHw ,fs },{L_POPw ,0 ,S_SEGI ,fs },
|
||||
{D_CPUID ,0 ,0 ,0 },{L_MODRM ,O_BTw ,0 ,M_Gw },
|
||||
{D_CPUID ,0 ,0 ,0 },{L_MODRM ,O_BTw ,S_Ew ,M_EwGw },
|
||||
{L_MODRM ,O_DSHLw ,S_Ew,M_EwGwIb },{L_MODRM ,O_DSHLw ,S_Ew ,M_EwGwCL },
|
||||
{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 },
|
||||
/* 0x1a8 - 0x1af */
|
||||
{L_SEG ,0 ,S_PUSHw ,gs },{L_POPw ,0 ,S_SEGI ,gs },
|
||||
{0 ,0 ,0 ,0 },{L_MODRM ,O_BTSw ,0 ,M_Gw },
|
||||
{0 ,0 ,0 ,0 },{L_MODRM ,O_BTSw ,S_Ew ,M_EwGw },
|
||||
{L_MODRM ,O_DSHRw ,S_Ew,M_EwGwIb },{L_MODRM ,O_DSHRw ,S_Ew ,M_EwGwCL },
|
||||
{0 ,0 ,0 ,0 },{L_MODRM ,O_IMULRw ,S_Gw ,M_EwxGwx },
|
||||
|
||||
/* 0x1b0 - 0x1b7 */
|
||||
{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 },
|
||||
{L_MODRM ,O_SEGSS ,S_SEGGw,M_Efw },{L_MODRM ,O_BTRw ,0 ,M_Gw },
|
||||
{L_MODRM ,O_SEGSS ,S_SEGGw,M_Efw },{L_MODRM ,O_BTRw ,S_Ew ,M_EwGw },
|
||||
{L_MODRM ,O_SEGFS ,S_SEGGw,M_Efw },{L_MODRM ,O_SEGGS ,S_SEGGw,M_Efw },
|
||||
{L_MODRM ,0 ,S_Gw ,M_Eb },{L_MODRM ,0 ,S_Gw ,M_Ew },
|
||||
/* 0x1b8 - 0x1bf */
|
||||
{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 },
|
||||
{L_MODRM ,0xe ,0 ,M_GRP },{L_MODRM ,O_BTCw ,0 ,M_Gw },
|
||||
{L_MODRM ,0xe ,0 ,M_GRP },{L_MODRM ,O_BTCw ,S_Ew ,M_EwGw },
|
||||
{L_MODRM ,O_BSFw ,S_Gw ,M_Ew },{L_MODRM ,O_BSRw ,S_Gw ,M_Ew },
|
||||
{L_MODRM ,0 ,S_Gw ,M_Ebx },{L_MODRM ,0 ,S_Gw ,M_Ewx },
|
||||
|
||||
|
@ -650,23 +650,23 @@ static OpCode OpCodeTable[1024]={
|
|||
|
||||
/* 0x3a0 - 0x3a7 */
|
||||
{L_SEG ,0 ,S_PUSHd ,fs },{L_POPd ,0 ,S_SEGI ,fs },
|
||||
{D_CPUID ,0 ,0 ,0 },{L_MODRM ,O_BTd ,0 ,M_Gd },
|
||||
{D_CPUID ,0 ,0 ,0 },{L_MODRM ,O_BTd ,S_Ed ,M_EdGd },
|
||||
{L_MODRM ,O_DSHLd ,S_Ed,M_EdGdIb },{L_MODRM ,O_DSHLd ,S_Ed ,M_EdGdCL },
|
||||
{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 },
|
||||
/* 0x3a8 - 0x3af */
|
||||
{L_SEG ,0 ,S_PUSHd ,gs },{L_POPd ,0 ,S_SEGI ,gs },
|
||||
{0 ,0 ,0 ,0 },{L_MODRM ,O_BTSd ,0 ,M_Gd },
|
||||
{0 ,0 ,0 ,0 },{L_MODRM ,O_BTSd ,S_Ed ,M_EdGd },
|
||||
{L_MODRM ,O_DSHRd ,S_Ed,M_EdGdIb },{L_MODRM ,O_DSHRd ,S_Ed ,M_EdGdCL },
|
||||
{0 ,0 ,0 ,0 },{L_MODRM ,O_IMULRd ,S_Gd ,M_EdxGdx },
|
||||
|
||||
/* 0x3b0 - 0x3b7 */
|
||||
{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 },
|
||||
{L_MODRM ,O_SEGSS ,S_SEGGd,M_Efd },{L_MODRM ,O_BTRd ,0 ,M_Gd },
|
||||
{L_MODRM ,O_SEGSS ,S_SEGGd,M_Efd },{L_MODRM ,O_BTRd ,S_Ed ,M_EdGd },
|
||||
{L_MODRM ,O_SEGFS ,S_SEGGd,M_Efd },{L_MODRM ,O_SEGGS ,S_SEGGd,M_Efd },
|
||||
{L_MODRM ,0 ,S_Gd ,M_Eb },{L_MODRM ,0 ,S_Gd ,M_Ew },
|
||||
/* 0x3b8 - 0x3bf */
|
||||
{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 },
|
||||
{L_MODRM ,0xf ,0 ,M_GRP },{L_MODRM ,O_BTCd ,0 ,M_Gd },
|
||||
{L_MODRM ,0xf ,0 ,M_GRP },{L_MODRM ,O_BTCd ,S_Ed ,M_EdGd },
|
||||
{L_MODRM ,O_BSFd ,S_Gd ,M_Ed },{L_MODRM ,O_BSRd ,S_Gd ,M_Ed },
|
||||
{L_MODRM ,0 ,S_Gd ,M_Ebx },{L_MODRM ,0 ,S_Gd ,M_Ewx },
|
||||
|
||||
|
@ -796,13 +796,13 @@ static OpCode Groups[16][8]={
|
|||
},{ /* 0x0e Group 8 Ew */
|
||||
{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 },
|
||||
{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 },
|
||||
{0 ,O_BTw ,0 ,M_Ib },{0 ,O_BTSw ,0 ,M_Ib },
|
||||
{0 ,O_BTRw ,0 ,M_Ib },{0 ,O_BTCw ,0 ,M_Ib },
|
||||
{0 ,O_BTw ,S_Ew ,M_EwIb },{0 ,O_BTSw ,S_Ew ,M_EwIb },
|
||||
{0 ,O_BTRw ,S_Ew ,M_EwIb },{0 ,O_BTCw ,S_Ew ,M_EwIb },
|
||||
},{ /* 0x0f Group 8 Ed */
|
||||
{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 },
|
||||
{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 },
|
||||
{0 ,O_BTd ,0 ,M_Ib },{0 ,O_BTSd ,0 ,M_Ib },
|
||||
{0 ,O_BTRd ,0 ,M_Ib },{0 ,O_BTCd ,0 ,M_Ib },
|
||||
{0 ,O_BTd ,S_Ed ,M_Ib },{0 ,O_BTSd ,S_Ed ,M_EdIb },
|
||||
{0 ,O_BTRd ,S_Ed ,M_Ib },{0 ,O_BTCd ,S_Ed ,M_EdIb },
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -133,7 +133,7 @@ enum {
|
|||
M_Ewx,M_Ew,M_Gw,M_EwGw,M_GwEw,M_EwxGwx,
|
||||
M_Edx,M_Ed,M_Gd,M_EdGd,M_GdEd,M_EdxGdx,
|
||||
|
||||
M_EbIb,
|
||||
M_EbIb,M_EwIb,M_EdIb,
|
||||
M_EwIw,M_EwIbx,M_EwxIbx,M_EwxIwx,M_EwGwIb,M_EwGwCL,
|
||||
M_EdId,M_EdIbx,M_EdGdIb,M_EdGdCL,
|
||||
|
||||
|
|
|
@ -152,9 +152,9 @@ static GetEATable * EAPrefixTable[8] = {
|
|||
#define EALookupTable (*(core.ea_table))
|
||||
|
||||
|
||||
static Bits CPU_Core_Normal_Decode_Trap(void);
|
||||
Bits CPU_Core_Normal_Decode_Trap(void);
|
||||
|
||||
static Bits CPU_Core_Normal_Decode(void) {
|
||||
Bits CPU_Core_Normal_Decode(void) {
|
||||
decode_start:
|
||||
if (cpu.code.big) {
|
||||
core.index_default=0x200;
|
||||
|
@ -165,7 +165,7 @@ decode_start:
|
|||
}
|
||||
LOADIP;
|
||||
lflags.type=t_UNKNOWN;
|
||||
while (CPU_Cycles>0) {
|
||||
while (CPU_Cycles-->0) {
|
||||
core.op_start=core.ip_lookup;
|
||||
core.opcode_index=core.index_default;
|
||||
core.prefixes=core.prefix_default;
|
||||
|
@ -179,7 +179,6 @@ decode_start:
|
|||
};
|
||||
#endif
|
||||
#endif
|
||||
CPU_Cycles--;
|
||||
restart_prefix:
|
||||
core.ea_table=EAPrefixTable[core.prefixes];
|
||||
restart_opcode:
|
||||
|
@ -203,15 +202,16 @@ restart_opcode:
|
|||
return CBRET_NONE;
|
||||
}
|
||||
|
||||
static Bits CPU_Core_Normal_Decode_Trap(void) {
|
||||
Bits CPU_Core_Normal_Decode_Trap(void) {
|
||||
|
||||
Bits oldCycles = CPU_Cycles;
|
||||
CPU_Cycles = 1;
|
||||
core.trap.skip=false;
|
||||
|
||||
Bits ret=CPU_Core_Normal_Decode();
|
||||
if (!core.trap.skip) CPU_SW_Interrupt(1,0);
|
||||
|
||||
if (!core.trap.skip) if (CPU_SW_Interrupt(1)) {
|
||||
E_Exit("Exception in trap flag cpu core, noooooooo");
|
||||
}
|
||||
CPU_Cycles = oldCycles-1;
|
||||
cpudecoder = &CPU_Core_Normal_Decode;
|
||||
|
||||
|
|
|
@ -141,3 +141,17 @@
|
|||
} \
|
||||
}
|
||||
|
||||
#define POPSEG(_SEG_,_VAL_,_ESP_CHANGE_) \
|
||||
if (CPU_SetSegGeneral(_SEG_,_VAL_)) { \
|
||||
LEAVECORE; \
|
||||
reg_eip-=(core.ip_lookup-core.op_start);reg_esp-=_ESP_CHANGE_; \
|
||||
CPU_StartException();goto decode_start; \
|
||||
}
|
||||
|
||||
#define LOADSEG(_SEG_,_SEG_VAL_) \
|
||||
if (CPU_SetSegGeneral(_SEG_,_SEG_VAL_)) { \
|
||||
LEAVECORE; \
|
||||
reg_eip-=(core.ip_lookup-core.op_start); \
|
||||
CPU_StartException();goto decode_start; \
|
||||
} \
|
||||
|
||||
|
|
|
@ -242,8 +242,9 @@
|
|||
|
||||
CASE_0F_W(0xa0) /* PUSH FS */
|
||||
Push_16(SegValue(fs));break;
|
||||
CASE_0F_W(0xa1) /* POP FS */
|
||||
CPU_SetSegGeneral(fs,Pop_16());break;
|
||||
CASE_0F_W(0xa1) /* POP FS */
|
||||
POPSEG(fs,Pop_16(),2);
|
||||
break;
|
||||
CASE_0F_B(0xa2) /* CPUID */
|
||||
CPU_CPUID();break;
|
||||
CASE_0F_W(0xa3) /* BT Ew,Gw */
|
||||
|
@ -268,7 +269,7 @@
|
|||
CASE_0F_W(0xa8) /* PUSH GS */
|
||||
Push_16(SegValue(gs));break;
|
||||
CASE_0F_W(0xa9) /* POP GS */
|
||||
CPU_SetSegGeneral(gs,Pop_16());break;
|
||||
POPSEG(fs,Pop_16(),2);break;
|
||||
CASE_0F_W(0xab) /* BTS Ew,Gw */
|
||||
{
|
||||
FillFlags();GetRMrw;
|
||||
|
@ -295,8 +296,10 @@
|
|||
break;
|
||||
CASE_0F_W(0xb2) /* LSS Ew */
|
||||
{
|
||||
CPU_Cycles++;
|
||||
GetRMrw;GetEAa;
|
||||
*rmrw=LoadMw(eaa);CPU_SetSegGeneral(ss,LoadMw(eaa+2));
|
||||
LOADSEG(ss,LoadMw(eaa+2));
|
||||
*rmrw=LoadMw(eaa);
|
||||
break;
|
||||
}
|
||||
CASE_0F_W(0xb3) /* BTR Ew,Gw */
|
||||
|
@ -317,13 +320,15 @@
|
|||
CASE_0F_W(0xb4) /* LFS Ew */
|
||||
{
|
||||
GetRMrw;GetEAa;
|
||||
*rmrw=LoadMw(eaa);CPU_SetSegGeneral(fs,LoadMw(eaa+2));
|
||||
LOADSEG(fs,LoadMw(eaa+2));
|
||||
*rmrw=LoadMw(eaa);
|
||||
break;
|
||||
}
|
||||
CASE_0F_W(0xb5) /* LGS Ew */
|
||||
{
|
||||
GetRMrw;GetEAa;
|
||||
*rmrw=LoadMw(eaa);CPU_SetSegGeneral(gs,LoadMw(eaa+2));
|
||||
LOADSEG(gs,LoadMw(eaa+2));
|
||||
*rmrw=LoadMw(eaa);
|
||||
break;
|
||||
}
|
||||
CASE_0F_W(0xb6) /* MOVZX Gw,Eb */
|
||||
|
|
|
@ -24,8 +24,8 @@
|
|||
EAXId(ADDD);break;
|
||||
CASE_D(0x06) /* PUSH ES */
|
||||
Push_32(SegValue(es));break;
|
||||
CASE_D(0x07) /* POP ES */
|
||||
CPU_SetSegGeneral(es,(Bit16u)Pop_32());break;
|
||||
CASE_D(0x07) /* POP ES */
|
||||
POPSEG(es,Pop_32(),4);break;
|
||||
CASE_D(0x09) /* OR Ed,Gd */
|
||||
RMEdGd(ORD);break;
|
||||
CASE_D(0x0b) /* OR Gd,Ed */
|
||||
|
@ -40,10 +40,12 @@
|
|||
RMGdEd(ADCD);break;
|
||||
CASE_D(0x15) /* ADC EAX,Id */
|
||||
EAXId(ADCD);break;
|
||||
CASE_D(0x16) /* PUSH SS */
|
||||
CASE_D(0x16) /* PUSH SS */
|
||||
Push_32(SegValue(ss));break;
|
||||
CASE_D(0x17) /* POP SS */
|
||||
CPU_SetSegGeneral(ss,(Bit16u)Pop_32());break;
|
||||
CASE_D(0x17) /* POP SS */
|
||||
POPSEG(ss,Pop_32(),4);
|
||||
CPU_Cycles++;
|
||||
break;
|
||||
CASE_D(0x19) /* SBB Ed,Gd */
|
||||
RMEdGd(SBBD);break;
|
||||
CASE_D(0x1b) /* SBB Gd,Ed */
|
||||
|
@ -53,7 +55,7 @@
|
|||
CASE_D(0x1e) /* PUSH DS */
|
||||
Push_32(SegValue(ds));break;
|
||||
CASE_D(0x1f) /* POP DS */
|
||||
CPU_SetSegGeneral(ds,(Bit16u)Pop_32());break;
|
||||
POPSEG(ds,Pop_32(),4);break;
|
||||
CASE_D(0x21) /* AND Ed,Gd */
|
||||
RMEdGd(ANDD);break;
|
||||
CASE_D(0x23) /* AND Gd,Ed */
|
||||
|
@ -417,13 +419,15 @@
|
|||
CASE_D(0xc4) /* LES */
|
||||
{
|
||||
GetRMrd;GetEAa;
|
||||
*rmrd=LoadMd(eaa);CPU_SetSegGeneral(es,LoadMw(eaa+4));
|
||||
LOADSEG(es,LoadMw(eaa+4));
|
||||
*rmrd=LoadMd(eaa);
|
||||
break;
|
||||
}
|
||||
CASE_D(0xc5) /* LDS */
|
||||
{
|
||||
GetRMrd;GetEAa;
|
||||
*rmrd=LoadMd(eaa);CPU_SetSegGeneral(ds,LoadMw(eaa+4));
|
||||
LOADSEG(ds,LoadMw(eaa+4));
|
||||
*rmrd=LoadMd(eaa);
|
||||
break;
|
||||
}
|
||||
CASE_D(0xc7) /* MOV Ed,Id */
|
||||
|
|
|
@ -159,8 +159,7 @@
|
|||
CASE_0F_D(0xa0) /* PUSH FS */
|
||||
Push_32(SegValue(fs));break;
|
||||
CASE_0F_D(0xa1) /* POP FS */
|
||||
CPU_SetSegGeneral(fs,(Bit16u)Pop_32());break;
|
||||
|
||||
POPSEG(fs,Pop_32(),4);break;
|
||||
CASE_0F_D(0xa3) /* BT Ed,Gd */
|
||||
{
|
||||
FillFlags();GetRMrd;
|
||||
|
@ -183,7 +182,7 @@
|
|||
CASE_0F_D(0xa8) /* PUSH GS */
|
||||
Push_32(SegValue(gs));break;
|
||||
CASE_0F_D(0xa9) /* POP GS */
|
||||
CPU_SetSegGeneral(gs,(Bit16u)Pop_32());break;
|
||||
POPSEG(gs,Pop_32(),4);break;
|
||||
CASE_0F_D(0xab) /* BTS Ed,Gd */
|
||||
{
|
||||
FillFlags();GetRMrd;
|
||||
|
@ -214,7 +213,9 @@
|
|||
CASE_0F_D(0xb2) /* LSS Ed */
|
||||
{
|
||||
GetRMrd;GetEAa;
|
||||
*rmrd=LoadMd(eaa);CPU_SetSegGeneral(ss,LoadMw(eaa+4));
|
||||
LOADSEG(ss,LoadMw(eaa+4));
|
||||
CPU_Cycles++;
|
||||
*rmrd=LoadMd(eaa);
|
||||
break;
|
||||
}
|
||||
CASE_0F_D(0xb3) /* BTR Ed,Gd */
|
||||
|
@ -235,13 +236,15 @@
|
|||
CASE_0F_D(0xb4) /* LFS Ed */
|
||||
{
|
||||
GetRMrd;GetEAa;
|
||||
*rmrd=LoadMd(eaa);CPU_SetSegGeneral(fs,LoadMw(eaa+4));
|
||||
LOADSEG(fs,LoadMw(eaa+4));
|
||||
*rmrd=LoadMd(eaa);
|
||||
break;
|
||||
}
|
||||
CASE_0F_D(0xb5) /* LGS Ed */
|
||||
{
|
||||
GetRMrd;GetEAa;
|
||||
*rmrd=LoadMd(eaa);CPU_SetSegGeneral(gs,LoadMw(eaa+4));
|
||||
LOADSEG(gs,LoadMw(eaa+4));
|
||||
*rmrd=LoadMd(eaa);
|
||||
break;
|
||||
}
|
||||
CASE_0F_D(0xb6) /* MOVZX Gd,Eb */
|
||||
|
|
|
@ -30,8 +30,8 @@
|
|||
AXIw(ADDW);break;
|
||||
CASE_W(0x06) /* PUSH ES */
|
||||
Push_16(SegValue(es));break;
|
||||
CASE_W(0x07) /* POP ES */
|
||||
CPU_SetSegGeneral(es,Pop_16());break;
|
||||
CASE_W(0x07) /* POP ES */
|
||||
POPSEG(es,Pop_16(),2);break;
|
||||
CASE_B(0x08) /* OR Eb,Gb */
|
||||
RMEbGb(ORB);break;
|
||||
CASE_W(0x09) /* OR Ew,Gw */
|
||||
|
@ -65,7 +65,9 @@
|
|||
CASE_W(0x16) /* PUSH SS */
|
||||
Push_16(SegValue(ss));break;
|
||||
CASE_W(0x17) /* POP SS */
|
||||
CPU_SetSegGeneral(ss,Pop_16());break;
|
||||
POPSEG(ss,Pop_16(),2);
|
||||
CPU_Cycles++; //Always do another instruction
|
||||
break;
|
||||
CASE_B(0x18) /* SBB Eb,Gb */
|
||||
RMEbGb(SBBB);break;
|
||||
CASE_W(0x19) /* SBB Ew,Gw */
|
||||
|
@ -81,7 +83,8 @@
|
|||
CASE_W(0x1e) /* PUSH DS */
|
||||
Push_16(SegValue(ds));break;
|
||||
CASE_W(0x1f) /* POP DS */
|
||||
CPU_SetSegGeneral(ds,Pop_16());break;
|
||||
POPSEG(ds,Pop_16(),2);
|
||||
break;
|
||||
CASE_B(0x20) /* AND Eb,Gb */
|
||||
RMEbGb(ANDB);break;
|
||||
CASE_W(0x21) /* AND Ew,Gw */
|
||||
|
@ -489,21 +492,17 @@
|
|||
if (rm >= 0xc0 ) {GetEArw;val=*earw;}
|
||||
else {GetEAa;val=LoadMw(eaa);}
|
||||
switch (which) {
|
||||
case 0x02: /* MOV SS,Ew */
|
||||
CPU_Cycles++; //Always do another instruction
|
||||
case 0x00: /* MOV ES,Ew */
|
||||
CPU_SetSegGeneral(es,val);break;
|
||||
case 0x03: /* MOV DS,Ew */
|
||||
case 0x05: /* MOV GS,Ew */
|
||||
case 0x04: /* MOV FS,Ew */
|
||||
LOADSEG((SegNames)which,val);
|
||||
break;
|
||||
case 0x01: /* MOV CS,Ew Illegal*/
|
||||
E_Exit("CPU:Illegal MOV CS Call");
|
||||
break;
|
||||
case 0x02: /* MOV SS,Ew */
|
||||
CPU_SetSegGeneral(ss,val);
|
||||
CPU_Cycles++; //Always do another instruction
|
||||
break;
|
||||
case 0x03: /* MOV DS,Ew */
|
||||
CPU_SetSegGeneral(ds,val);break;
|
||||
case 0x04: /* MOV FS,Ew */
|
||||
CPU_SetSegGeneral(fs,val);break;
|
||||
case 0x05: /* MOV GS,Ew */
|
||||
CPU_SetSegGeneral(gs,val);break;
|
||||
default:
|
||||
E_Exit("CPU:8E:Illegal RM Byte");
|
||||
}
|
||||
|
@ -673,13 +672,15 @@
|
|||
CASE_W(0xc4) /* LES */
|
||||
{
|
||||
GetRMrw;GetEAa;
|
||||
*rmrw=LoadMw(eaa);CPU_SetSegGeneral(es,LoadMw(eaa+2));
|
||||
LOADSEG(es,LoadMw(eaa+2));
|
||||
*rmrw=LoadMw(eaa);
|
||||
break;
|
||||
}
|
||||
CASE_W(0xc5) /* LDS */
|
||||
{
|
||||
GetRMrw;GetEAa;
|
||||
*rmrw=LoadMw(eaa);CPU_SetSegGeneral(ds,LoadMw(eaa+2));
|
||||
LOADSEG(ds,LoadMw(eaa+2));
|
||||
*rmrw=LoadMw(eaa);
|
||||
break;
|
||||
}
|
||||
CASE_B(0xc6) /* MOV Eb,Ib */
|
||||
|
@ -751,7 +752,10 @@
|
|||
return debugCallback;
|
||||
}
|
||||
#endif
|
||||
CPU_SW_Interrupt(3,core.ip_lookup-core.op_start);
|
||||
if (CPU_SW_Interrupt(3)) {
|
||||
reg_eip-=(core.ip_lookup-core.op_start);
|
||||
CPU_StartException();
|
||||
};
|
||||
#if CPU_TRAP_CHECK
|
||||
core.trap.skip=true;
|
||||
#endif
|
||||
|
@ -765,7 +769,10 @@
|
|||
return debugCallback;
|
||||
}
|
||||
#endif
|
||||
CPU_SW_Interrupt(num,core.ip_lookup-core.op_start);
|
||||
if (CPU_SW_Interrupt(num)) {
|
||||
reg_eip-=core.ip_lookup-core.op_start;
|
||||
CPU_StartException();
|
||||
}
|
||||
#if CPU_TRAP_CHECK
|
||||
core.trap.skip=true;
|
||||
#endif
|
||||
|
@ -775,7 +782,10 @@
|
|||
CASE_B(0xce) /* INTO */
|
||||
if (get_OF()) {
|
||||
LEAVECORE;
|
||||
CPU_SW_Interrupt(4,core.ip_lookup-core.op_start);
|
||||
if (CPU_SW_Interrupt(4)) {
|
||||
reg_eip-=core.ip_lookup-core.op_start;
|
||||
CPU_StartException();
|
||||
}
|
||||
#if CPU_TRAP_CHECK
|
||||
core.trap.skip=true;
|
||||
#endif
|
||||
|
@ -950,8 +960,12 @@
|
|||
break;
|
||||
CASE_B(0xf4) /* HLT */
|
||||
LEAVECORE;
|
||||
CPU_HLT(core.ip_lookup-core.op_start);
|
||||
return CBRET_NONE;
|
||||
if (CPU_HLT()) {
|
||||
reg_eip-=core.ip_lookup-core.op_start;
|
||||
CPU_StartException();
|
||||
goto decode_start;
|
||||
}
|
||||
return CBRET_NONE; //Needs to return for hlt cpu core
|
||||
CASE_B(0xf5) /* CMC */
|
||||
FillFlags();
|
||||
SETFLAGBIT(CF,!(reg_flags & FLAG_CF));
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
/* $Id: cpu.cpp,v 1.40 2003-12-10 13:20:26 qbix79 Exp $ */
|
||||
/* $Id: cpu.cpp,v 1.41 2003-12-10 17:02:22 harekiet Exp $ */
|
||||
|
||||
#include <assert.h>
|
||||
#include "dosbox.h"
|
||||
|
@ -45,9 +45,13 @@ Bits CPU_CycleUp = 0;
|
|||
Bits CPU_CycleDown = 0;
|
||||
CPU_Decoder * cpudecoder;
|
||||
|
||||
void CPU_Real_16_Slow_Start(bool big);
|
||||
static struct {
|
||||
Bitu which,errorcode;
|
||||
} exception;
|
||||
|
||||
void CPU_Core_Full_Start(bool big);
|
||||
void CPU_Core_Normal_Start(bool big);
|
||||
void CPU_Dynamic_Start(bool big);
|
||||
|
||||
static Bits CPU_Core_Normal_Decode(void);
|
||||
static Bits CPU_Core_Full_Decode(void);
|
||||
|
@ -272,12 +276,22 @@ doconforming:
|
|||
return true;
|
||||
}
|
||||
|
||||
Bit8u lastint;
|
||||
void CPU_Exception(Bitu num,Bitu error_code) {
|
||||
// LOG_MSG("Exception %d CS:%X IP:%X FLAGS:%X",num,SegValue(cs),reg_eip,reg_flags);
|
||||
CPU_Interrupt(num,error_code,((num>=8) ? CPU_INT_HAS_ERROR : 0));
|
||||
void CPU_StartException(void) {
|
||||
CPU_Interrupt(cpu.exception.which,CPU_INT_EXCEPTION | ((cpu.exception.which>=8) ? CPU_INT_HAS_ERROR : 0));
|
||||
}
|
||||
void CPU_Interrupt(Bitu num,Bitu error_code,Bitu type) {
|
||||
void CPU_SetupException(Bitu which,Bitu error) {
|
||||
cpu.exception.which=which;
|
||||
cpu.exception.error=error;
|
||||
}
|
||||
|
||||
void CPU_Exception(Bitu which,Bitu error ) {
|
||||
// LOG_MSG("Exception %d CS:%X IP:%X FLAGS:%X",num,SegValue(cs),reg_eip,reg_flags);
|
||||
CPU_SetupException(which,error);
|
||||
CPU_StartException();
|
||||
}
|
||||
|
||||
Bit8u lastint;
|
||||
bool CPU_Interrupt(Bitu num,Bitu type) {
|
||||
lastint=num;
|
||||
#if C_DEBUG
|
||||
switch (num) {
|
||||
|
@ -290,7 +304,7 @@ void CPU_Interrupt(Bitu num,Bitu error_code,Bitu type) {
|
|||
case 0x03:
|
||||
if (DEBUG_Breakpoint()) {
|
||||
CPU_Cycles=0;
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
};
|
||||
#endif
|
||||
|
@ -307,7 +321,7 @@ void CPU_Interrupt(Bitu num,Bitu error_code,Bitu type) {
|
|||
Segs.val[cs]=mem_readw(base+(num << 2)+2);
|
||||
Segs.phys[cs]=Segs.val[cs]<<4;
|
||||
cpu.code.big=false;
|
||||
return;
|
||||
return false;
|
||||
} else {
|
||||
/* Protected Mode Interrupt */
|
||||
// if (type&CPU_INT_SOFTWARE && cpu.v86) goto realmode_interrupt;
|
||||
|
@ -316,18 +330,16 @@ void CPU_Interrupt(Bitu num,Bitu error_code,Bitu type) {
|
|||
if ((reg_flags & FLAG_VM) && (type&CPU_INT_SOFTWARE)) {
|
||||
LOG_MSG("Software int in v86, AH %X IOPL %x",reg_ah,(reg_flags & FLAG_IOPL) >>12);
|
||||
if ((reg_flags & FLAG_IOPL)!=FLAG_IOPL) {
|
||||
reg_eip-=error_code;
|
||||
CPU_Exception(13,0);
|
||||
return;
|
||||
CPU_SetupException(13,0);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
Descriptor gate;
|
||||
//TODO Check for software interrupt and check gate's dpl<cpl
|
||||
cpu.idt.GetDescriptor(num<<3,gate);
|
||||
if (type&CPU_INT_SOFTWARE && gate.DPL()<cpu.cpl) {
|
||||
reg_eip-=error_code;
|
||||
CPU_Exception(13,num*8+2);
|
||||
return;
|
||||
CPU_SetupException(13,num*8+2);
|
||||
return true;
|
||||
}
|
||||
switch (gate.Type()) {
|
||||
case DESC_286_INT_GATE: case DESC_386_INT_GATE:
|
||||
|
@ -393,12 +405,12 @@ do_interrupt:
|
|||
CPU_Push32(reg_flags);
|
||||
CPU_Push32(SegValue(cs));
|
||||
CPU_Push32(reg_eip);
|
||||
if (type & CPU_INT_HAS_ERROR) CPU_Push32(error_code);
|
||||
if (type & CPU_INT_HAS_ERROR) CPU_Push32(cpu.exception.error);
|
||||
} else { /* 16-bit gate */
|
||||
CPU_Push16(reg_flags & 0xffff);
|
||||
CPU_Push16(SegValue(cs));
|
||||
CPU_Push16(reg_ip);
|
||||
if (type & CPU_INT_HAS_ERROR) CPU_Push16(error_code);
|
||||
if (type & CPU_INT_HAS_ERROR) CPU_Push16(cpu.exception.error);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
|
@ -414,16 +426,16 @@ do_interrupt:
|
|||
cpu.code.big=cs_desc.Big()>0;
|
||||
LOG(LOG_CPU,LOG_NORMAL)("INT:Gate to %X:%X big %d %s",gate_sel,gate_off,cs_desc.Big(),gate.Type() & 0x8 ? "386" : "286");
|
||||
reg_eip=gate_off;
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
case DESC_TASK_GATE:
|
||||
CPU_SwitchTask(gate.GetSelector(),TSwitch_CALL_INT);
|
||||
if (type & CPU_INT_HAS_ERROR) {
|
||||
//TODO Be sure about this, seems somewhat unclear
|
||||
if (cpu_tss.is386) CPU_Push32(error_code);
|
||||
else CPU_Push16(error_code);
|
||||
if (cpu_tss.is386) CPU_Push32(cpu.exception.error);
|
||||
else CPU_Push16(cpu.exception.error);
|
||||
}
|
||||
return;
|
||||
return false;
|
||||
default:
|
||||
E_Exit("Illegal descriptor type %X for int %X",gate.Type(),num);
|
||||
}
|
||||
|
@ -1075,7 +1087,7 @@ void CPU_VERW(Bitu selector) {
|
|||
}
|
||||
|
||||
|
||||
void CPU_SetSegGeneral(SegNames seg,Bitu value) {
|
||||
bool CPU_SetSegGeneral(SegNames seg,Bitu value) {
|
||||
Segs.val[seg]=value;
|
||||
if (!cpu.pmode || (reg_flags & FLAG_VM)) {
|
||||
Segs.phys[seg]=value << 4;
|
||||
|
@ -1083,6 +1095,7 @@ void CPU_SetSegGeneral(SegNames seg,Bitu value) {
|
|||
cpu.stack.big=false;
|
||||
cpu.stack.mask=0xffff;
|
||||
}
|
||||
return false;
|
||||
} else {
|
||||
Descriptor desc;
|
||||
cpu.gdt.GetDescriptor(value,desc);
|
||||
|
@ -1096,6 +1109,7 @@ void CPU_SetSegGeneral(SegNames seg,Bitu value) {
|
|||
cpu.stack.mask=0xffff;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1129,17 +1143,14 @@ static Bits HLT_Decode(void) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
void CPU_HLT(Bitu oplen) {
|
||||
if (cpu.cpl) {
|
||||
reg_eip-=oplen;
|
||||
CPU_Exception(13,0);
|
||||
return;
|
||||
}
|
||||
bool CPU_HLT(void) {
|
||||
if (cpu.cpl) return true;
|
||||
CPU_Cycles=0;
|
||||
cpu.hlt.cs=SegValue(cs);
|
||||
cpu.hlt.eip=reg_eip;
|
||||
cpu.hlt.old_decoder=cpudecoder;
|
||||
cpudecoder=&HLT_Decode;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue