From 9c7b2aa63826ce1830e2b431d60a59fb746a2661 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Wed, 10 Dec 2003 17:02:22 +0000 Subject: [PATCH] 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 --- src/cpu/core_full/load.h | 13 +++- src/cpu/core_full/op.h | 117 +++++++++++++---------------- src/cpu/core_full/optable.h | 24 +++--- src/cpu/core_full/support.h | 2 +- src/cpu/core_normal.cpp | 14 ++-- src/cpu/core_normal/helpers.h | 14 ++++ src/cpu/core_normal/prefix_0f.h | 17 +++-- src/cpu/core_normal/prefix_66.h | 20 +++-- src/cpu/core_normal/prefix_66_0f.h | 15 ++-- src/cpu/core_normal/prefix_none.h | 58 ++++++++------ src/cpu/cpu.cpp | 67 ++++++++++------- 11 files changed, 206 insertions(+), 155 deletions(-) diff --git a/src/cpu/core_full/load.h b/src/cpu/core_full/load.h index fc3caf66..64740693 100644 --- a/src/cpu/core_full/load.h +++ b/src/cpu/core_full/load.h @@ -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); diff --git a/src/cpu/core_full/op.h b/src/cpu/core_full/op.h index 4bc16941..c54567a5 100644 --- a/src/cpu/core_full/op.h +++ b/src/cpu/core_full/op.h @@ -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; diff --git a/src/cpu/core_full/optable.h b/src/cpu/core_full/optable.h index 7213c6fc..3b82fca2 100644 --- a/src/cpu/core_full/optable.h +++ b/src/cpu/core_full/optable.h @@ -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 }, diff --git a/src/cpu/core_full/support.h b/src/cpu/core_full/support.h index 685b5b2c..ade673e8 100644 --- a/src/cpu/core_full/support.h +++ b/src/cpu/core_full/support.h @@ -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, diff --git a/src/cpu/core_normal.cpp b/src/cpu/core_normal.cpp index 467451da..af52aeea 100644 --- a/src/cpu/core_normal.cpp +++ b/src/cpu/core_normal.cpp @@ -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; diff --git a/src/cpu/core_normal/helpers.h b/src/cpu/core_normal/helpers.h index 6a30e052..97727801 100644 --- a/src/cpu/core_normal/helpers.h +++ b/src/cpu/core_normal/helpers.h @@ -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; \ + } \ + diff --git a/src/cpu/core_normal/prefix_0f.h b/src/cpu/core_normal/prefix_0f.h index 150a5c33..16ce83ed 100644 --- a/src/cpu/core_normal/prefix_0f.h +++ b/src/cpu/core_normal/prefix_0f.h @@ -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 */ diff --git a/src/cpu/core_normal/prefix_66.h b/src/cpu/core_normal/prefix_66.h index 397f4f09..2bae5eb2 100644 --- a/src/cpu/core_normal/prefix_66.h +++ b/src/cpu/core_normal/prefix_66.h @@ -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 */ diff --git a/src/cpu/core_normal/prefix_66_0f.h b/src/cpu/core_normal/prefix_66_0f.h index 9aa15dc2..3ceb1160 100644 --- a/src/cpu/core_normal/prefix_66_0f.h +++ b/src/cpu/core_normal/prefix_66_0f.h @@ -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 */ diff --git a/src/cpu/core_normal/prefix_none.h b/src/cpu/core_normal/prefix_none.h index ac649c59..e1b2953b 100644 --- a/src/cpu/core_normal/prefix_none.h +++ b/src/cpu/core_normal/prefix_none.h @@ -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)); diff --git a/src/cpu/cpu.cpp b/src/cpu/cpu.cpp index 4081808a..d750fee2 100644 --- a/src/cpu/cpu.cpp +++ b/src/cpu/cpu.cpp @@ -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 #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 dpl0; 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; }