1
0
Fork 0

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:
Sjoerd van der Berg 2003-12-10 17:02:22 +00:00
parent a3f5f3c445
commit 9c7b2aa638
11 changed files with 206 additions and 155 deletions

View file

@ -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);

View file

@ -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;

View file

@ -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 },

View file

@ -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,

View file

@ -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;

View file

@ -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; \
} \

View file

@ -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 */

View file

@ -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 */

View file

@ -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 */

View file

@ -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));

View file

@ -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;
}