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:
parent
53666d5f27
commit
bca40f5561
5 changed files with 33 additions and 65 deletions
|
@ -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;
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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
|
||||
};
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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; \
|
||||
|
|
Loading…
Add table
Reference in a new issue