1
0
Fork 0

Fix flag behaviour of several shift/rotate instructions, cause exceptions and fix potention 'pop ss' problems

Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@4256
This commit is contained in:
Sjoerd van der Berg 2019-09-08 12:42:21 +00:00
parent 53666d5f27
commit bca40f5561
5 changed files with 33 additions and 65 deletions

View file

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

View file

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

View file

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

View file

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

View file

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