diff --git a/src/cpu/core_full/load.h b/src/cpu/core_full/load.h index 6645860c..d029def4 100644 --- a/src/cpu/core_full/load.h +++ b/src/cpu/core_full/load.h @@ -186,15 +186,19 @@ l_M_Ed: case M_GRP: inst.code=Groups[inst.code.op][inst.rm_index]; goto l_MODRMswitch; - case M_GRP_Ib: - inst_op2_d=Fetchb(); + case M_SHIFT_Ib: + inst_op2_d=Fetchb() & 0x1f; + if (!inst_op2_d) + break; inst.code=Groups[inst.code.op][inst.rm_index]; goto l_MODRMswitch; - case M_GRP_CL: - inst_op2_d=reg_cl; + case M_SHIFT_CL: + inst_op2_d=reg_cl & 0x1f; + if (!inst_op2_d) + break; inst.code=Groups[inst.code.op][inst.rm_index]; goto l_MODRMswitch; - case M_GRP_1: + case M_SHIFT_1: inst_op2_d=1; inst.code=Groups[inst.code.op][inst.rm_index]; goto l_MODRMswitch; diff --git a/src/cpu/core_full/optable.h b/src/cpu/core_full/optable.h index 7a0ac82f..1ea95db4 100644 --- a/src/cpu/core_full/optable.h +++ b/src/cpu/core_full/optable.h @@ -155,7 +155,7 @@ static OpCode OpCodeTable[1024]={ {L_Iw ,0 ,S_REGw ,REGI_SI},{L_Iw ,0 ,S_REGw ,REGI_DI}, /* 0xc0 - 0xc7 */ -{L_MODRM ,5 ,0 ,M_GRP_Ib },{L_MODRM ,6 ,0 ,M_GRP_Ib }, +{L_MODRM ,5 ,0 ,M_SHIFT_Ib },{L_MODRM ,6 ,0 ,M_SHIFT_Ib }, {L_POPw ,0 ,S_IPIw ,0 },{L_POPw ,0 ,S_IP ,0 }, {L_MODRM ,O_SEGES ,S_SEGGw,M_Efw },{L_MODRM ,O_SEGDS ,S_SEGGw,M_Efw }, {L_MODRM ,0 ,S_Eb ,M_Ib },{L_MODRM ,0 ,S_Ew ,M_Iw }, @@ -166,8 +166,8 @@ static OpCode OpCodeTable[1024]={ {L_INTO ,O_INT ,0 ,0 },{D_IRETw ,0 ,0 ,0 }, /* 0xd0 - 0xd7 */ -{L_MODRM ,5 ,0 ,M_GRP_1 },{L_MODRM ,6 ,0 ,M_GRP_1 }, -{L_MODRM ,5 ,0 ,M_GRP_CL },{L_MODRM ,6 ,0 ,M_GRP_CL }, +{L_MODRM ,5 ,0 ,M_SHIFT_1 },{L_MODRM ,6 ,0 ,M_SHIFT_1 }, +{L_MODRM ,5 ,0 ,M_SHIFT_CL },{L_MODRM ,6 ,0 ,M_SHIFT_CL }, {L_Ib ,O_AAM ,0 ,0 },{L_Ib ,O_AAD ,0 ,0 }, {D_SETALC ,0 ,0 ,0 },{D_XLAT ,0 ,0 ,0 }, //TODO FPU @@ -511,7 +511,7 @@ static OpCode OpCodeTable[1024]={ {L_Id ,0 ,S_REGd ,REGI_SI},{L_Id ,0 ,S_REGd ,REGI_DI}, /* 0x2c0 - 0x2c7 */ -{L_MODRM ,5 ,0 ,M_GRP_Ib },{L_MODRM ,7 ,0 ,M_GRP_Ib }, +{L_MODRM ,5 ,0 ,M_SHIFT_Ib },{L_MODRM ,7 ,0 ,M_SHIFT_Ib }, {L_POPd ,0 ,S_IPIw ,0 },{L_POPd ,0 ,S_IP ,0 }, {L_MODRM ,O_SEGES ,S_SEGGd,M_Efd },{L_MODRM ,O_SEGDS ,S_SEGGd,M_Efd }, {L_MODRM ,0 ,S_Eb ,M_Ib },{L_MODRM ,0 ,S_Ed ,M_Id }, @@ -522,8 +522,8 @@ static OpCode OpCodeTable[1024]={ {L_INTO ,O_INT ,0 ,0 },{D_IRETd ,0 ,0 ,0 }, /* 0x2d0 - 0x2d7 */ -{L_MODRM ,5 ,0 ,M_GRP_1 },{L_MODRM ,7 ,0 ,M_GRP_1 }, -{L_MODRM ,5 ,0 ,M_GRP_CL },{L_MODRM ,7 ,0 ,M_GRP_CL }, +{L_MODRM ,5 ,0 ,M_SHIFT_1 },{L_MODRM ,7 ,0 ,M_SHIFT_1 }, +{L_MODRM ,5 ,0 ,M_SHIFT_CL },{L_MODRM ,7 ,0 ,M_SHIFT_CL }, {L_Ib ,O_AAM ,0 ,0 },{L_Ib ,O_AAD ,0 ,0 }, {D_SETALC ,0 ,0 ,0 },{D_XLAT ,0 ,0 ,0 }, /* 0x2d8 - 0x2df */ diff --git a/src/cpu/core_full/support.h b/src/cpu/core_full/support.h index 6ac7711e..f8d8b332 100644 --- a/src/cpu/core_full/support.h +++ b/src/cpu/core_full/support.h @@ -167,7 +167,8 @@ enum { M_SEG,M_EA, M_GRP, - M_GRP_Ib,M_GRP_CL,M_GRP_1, + //Special shift groups + M_SHIFT_1, M_SHIFT_Ib,M_SHIFT_CL, M_POPw,M_POPd }; diff --git a/src/cpu/cpu.cpp b/src/cpu/cpu.cpp index 95cd2839..bc1c576e 100644 --- a/src/cpu/cpu.cpp +++ b/src/cpu/cpu.cpp @@ -1925,17 +1925,17 @@ bool CPU_SetSegGeneral(SegNames seg,Bitu value) { if (seg==ss) { // Stack needs to be non-zero if ((value & 0xfffc)==0) { - E_Exit("CPU_SetSegGeneral: Stack segment zero"); -// return CPU_PrepareException(EXCEPTION_GP,0); +// E_Exit("CPU_SetSegGeneral: Stack segment zero"); + return CPU_PrepareException(EXCEPTION_GP,0); } Descriptor desc; if (!cpu.gdt.GetDescriptor(value,desc)) { - E_Exit("CPU_SetSegGeneral: Stack segment beyond limits"); -// return CPU_PrepareException(EXCEPTION_GP,value & 0xfffc); +// E_Exit("CPU_SetSegGeneral: Stack segment beyond limits"); + return CPU_PrepareException(EXCEPTION_GP,value & 0xfffc); } if (((value & 3)!=cpu.cpl) || (desc.DPL()!=cpu.cpl)) { - E_Exit("CPU_SetSegGeneral: Stack segment with invalid privileges"); -// return CPU_PrepareException(EXCEPTION_GP,value & 0xfffc); +// E_Exit("CPU_SetSegGeneral: Stack segment with invalid privileges"); + return CPU_PrepareException(EXCEPTION_GP,value & 0xfffc); } switch (desc.Type()) { @@ -2006,9 +2006,11 @@ bool CPU_SetSegGeneral(SegNames seg,Bitu value) { bool CPU_PopSeg(SegNames seg,bool use32) { Bitu val=mem_readw(SegPhys(ss) + (reg_esp & cpu.stack.mask)); + Bitu addsp = use32 ? 0x04 : 0x02; + //Calcullate this beforehande since the stack mask might change + Bit32u new_esp = (reg_esp&cpu.stack.notmask) | ((reg_esp + addsp)&cpu.stack.mask); if (CPU_SetSegGeneral(seg,val)) return true; - Bitu addsp=use32?0x04:0x02; - reg_esp=(reg_esp&cpu.stack.notmask)|((reg_esp+addsp)&cpu.stack.mask); + reg_esp = new_esp; return false; } diff --git a/src/cpu/instructions.h b/src/cpu/instructions.h index 9265f6cd..404ab68b 100644 --- a/src/cpu/instructions.h +++ b/src/cpu/instructions.h @@ -228,14 +228,6 @@ #define ROLB(op1,op2,load,save) \ - if (!(op2&0x7)) { \ - if (op2&0x18) { \ - FillFlagsNoCFOF(); \ - SETFLAGBIT(CF,op1 & 1); \ - SETFLAGBIT(OF,(op1 & 1) ^ (op1 >> 7)); \ - } \ - break; \ - } \ FillFlagsNoCFOF(); \ lf_var1b=load(op1); \ lf_var2b=op2&0x07; \ @@ -246,14 +238,6 @@ SETFLAGBIT(OF,(lf_resb & 1) ^ (lf_resb >> 7)); #define ROLW(op1,op2,load,save) \ - if (!(op2&0xf)) { \ - if (op2&0x10) { \ - FillFlagsNoCFOF(); \ - SETFLAGBIT(CF,op1 & 1); \ - SETFLAGBIT(OF,(op1 & 1) ^ (op1 >> 15)); \ - } \ - break; \ - } \ FillFlagsNoCFOF(); \ lf_var1w=load(op1); \ lf_var2b=op2&0xf; \ @@ -264,7 +248,6 @@ SETFLAGBIT(OF,(lf_resw & 1) ^ (lf_resw >> 15)); #define ROLD(op1,op2,load,save) \ - if (!op2) break; \ FillFlagsNoCFOF(); \ lf_var1d=load(op1); \ lf_var2b=op2; \ @@ -276,14 +259,6 @@ #define RORB(op1,op2,load,save) \ - if (!(op2&0x7)) { \ - if (op2&0x18) { \ - FillFlagsNoCFOF(); \ - SETFLAGBIT(CF,op1>>7); \ - SETFLAGBIT(OF,(op1>>7) ^ ((op1>>6) & 1)); \ - } \ - break; \ - } \ FillFlagsNoCFOF(); \ lf_var1b=load(op1); \ lf_var2b=op2&0x07; \ @@ -294,14 +269,6 @@ SETFLAGBIT(OF,(lf_resb ^ (lf_resb<<1)) & 0x80); #define RORW(op1,op2,load,save) \ - if (!(op2&0xf)) { \ - if (op2&0x10) { \ - FillFlagsNoCFOF(); \ - SETFLAGBIT(CF,op1>>15); \ - SETFLAGBIT(OF,(op1>>15) ^ ((op1>>14) & 1)); \ - } \ - break; \ - } \ FillFlagsNoCFOF(); \ lf_var1w=load(op1); \ lf_var2b=op2&0xf; \ @@ -312,7 +279,6 @@ SETFLAGBIT(OF,(lf_resw ^ (lf_resw<<1)) & 0x8000); #define RORD(op1,op2,load,save) \ - if (!op2) break; \ FillFlagsNoCFOF(); \ lf_var1d=load(op1); \ lf_var2b=op2; \ @@ -366,8 +332,6 @@ SETFLAGBIT(OF,(reg_flags & 1) ^ (lf_resd >> 31)); \ } - - #define RCRB(op1,op2,load,save) \ if (op2%9) { \ Bit8u cf=(Bit8u)FillFlags()&0x1; \ @@ -413,21 +377,18 @@ #define SHLB(op1,op2,load,save) \ - if (!op2) break; \ lf_var1b=load(op1);lf_var2b=op2; \ lf_resb=lf_var1b << lf_var2b; \ save(op1,lf_resb); \ lflags.type=t_SHLb; #define SHLW(op1,op2,load,save) \ - if (!op2) break; \ lf_var1w=load(op1);lf_var2b=op2 ; \ lf_resw=lf_var1w << lf_var2b; \ save(op1,lf_resw); \ lflags.type=t_SHLw; #define SHLD(op1,op2,load,save) \ - if (!op2) break; \ lf_var1d=load(op1);lf_var2b=op2; \ lf_resd=lf_var1d << lf_var2b; \ save(op1,lf_resd); \ @@ -435,21 +396,18 @@ #define SHRB(op1,op2,load,save) \ - if (!op2) break; \ lf_var1b=load(op1);lf_var2b=op2; \ lf_resb=lf_var1b >> lf_var2b; \ save(op1,lf_resb); \ lflags.type=t_SHRb; #define SHRW(op1,op2,load,save) \ - if (!op2) break; \ lf_var1w=load(op1);lf_var2b=op2; \ lf_resw=lf_var1w >> lf_var2b; \ save(op1,lf_resw); \ lflags.type=t_SHRw; #define SHRD(op1,op2,load,save) \ - if (!op2) break; \ lf_var1d=load(op1);lf_var2b=op2; \ lf_resd=lf_var1d >> lf_var2b; \ save(op1,lf_resd); \ @@ -457,7 +415,6 @@ #define SARB(op1,op2,load,save) \ - if (!op2) break; \ lf_var1b=load(op1);lf_var2b=op2; \ if (lf_var2b>8) lf_var2b=8; \ if (lf_var1b & 0x80) { \ @@ -470,7 +427,6 @@ lflags.type=t_SARb; #define SARW(op1,op2,load,save) \ - if (!op2) break; \ lf_var1w=load(op1);lf_var2b=op2; \ if (lf_var2b>16) lf_var2b=16; \ if (lf_var1w & 0x8000) { \ @@ -483,7 +439,6 @@ lflags.type=t_SARw; #define SARD(op1,op2,load,save) \ - if (!op2) break; \ lf_var2b=op2;lf_var1d=load(op1); \ if (lf_var1d & 0x80000000) { \ lf_resd=(lf_var1d >> lf_var2b)| \ @@ -836,6 +791,7 @@ if (rm >= 0xc0) { \ GetEArb; \ Bit8u val=blah & 0x1f; \ + if (!val) break; \ switch (which) { \ case 0x00:ROLB(*earb,val,LoadRb,SaveRb);break; \ case 0x01:RORB(*earb,val,LoadRb,SaveRb);break; \ @@ -849,6 +805,7 @@ } else { \ GetEAa; \ Bit8u val=blah & 0x1f; \ + if (!val) break; \ switch (which) { \ case 0x00:ROLB(eaa,val,LoadMb,SaveMb);break; \ case 0x01:RORB(eaa,val,LoadMb,SaveMb);break; \ @@ -870,6 +827,7 @@ if (rm >= 0xc0) { \ GetEArw; \ Bit8u val=blah & 0x1f; \ + if (!val) break; \ switch (which) { \ case 0x00:ROLW(*earw,val,LoadRw,SaveRw);break; \ case 0x01:RORW(*earw,val,LoadRw,SaveRw);break; \ @@ -883,6 +841,7 @@ } else { \ GetEAa; \ Bit8u val=blah & 0x1f; \ + if (!val) break; \ switch (which) { \ case 0x00:ROLW(eaa,val,LoadMw,SaveMw);break; \ case 0x01:RORW(eaa,val,LoadMw,SaveMw);break; \ @@ -903,6 +862,7 @@ if (rm >= 0xc0) { \ GetEArd; \ Bit8u val=blah & 0x1f; \ + if (!val) break; \ switch (which) { \ case 0x00:ROLD(*eard,val,LoadRd,SaveRd);break; \ case 0x01:RORD(*eard,val,LoadRd,SaveRd);break; \ @@ -916,6 +876,7 @@ } else { \ GetEAa; \ Bit8u val=blah & 0x1f; \ + if (!val) break; \ switch (which) { \ case 0x00:ROLD(eaa,val,LoadMd,SaveMd);break; \ case 0x01:RORD(eaa,val,LoadMd,SaveMd);break; \