diff --git a/src/cpu/core_full/load.h b/src/cpu/core_full/load.h index 1b33fe4c..8c9764f1 100644 --- a/src/cpu/core_full/load.h +++ b/src/cpu/core_full/load.h @@ -195,7 +195,10 @@ l_M_Ed: inst.op1.d=Fetchw(); inst.op2.d=Fetchw(); break; - + case L_Ifd: + inst.op1.d=Fetchd(); + inst.op2.d=Fetchw(); + break; /* Direct load of registers */ case L_REGbIb: inst.op2.d=Fetchb(); @@ -376,9 +379,21 @@ l_M_Ed: goto nextopcode; } case D_LEAVEw: - reg_sp=reg_bp; + if (cpu.state & STATE_STACK32) { + reg_esp=reg_ebp; + } else { + reg_sp=reg_bp; + } reg_bp=Pop_16(); goto nextopcode; + case D_LEAVEd: + if (cpu.state & STATE_STACK32) { + reg_esp=reg_ebp; + } else { + reg_sp=reg_bp; + } + reg_ebp=Pop_32(); + goto nextopcode; case D_DAA: DAA(); goto nextopcode; diff --git a/src/cpu/core_full/op.h b/src/cpu/core_full/op.h index 5c5ed872..62f285d7 100644 --- a/src/cpu/core_full/op.h +++ b/src/cpu/core_full/op.h @@ -333,6 +333,11 @@ switch (inst.code.op) { CPU_JMP(false,inst.op2.d,inst.op1.d); LoadIP(); goto nextopcode; + case O_JMPFd: + CPU_JMP(true,inst.op2.d,inst.op1.d); + LoadIP(); + goto nextopcode; + case O_INT: SaveIP(); #if C_DEBUG @@ -383,9 +388,27 @@ switch (inst.code.op) { case O_GRP6w: case O_GRP6d: switch (inst.rm_index) { + case 0x00: /* SLDT */ + { + Bitu selector; + CPU_SLDT(selector); + inst.op1.d=selector; + } + break; + case 0x01: /* STR */ + { + Bitu selector; + CPU_STR(selector); + inst.op1.d=selector; + } + break; case 0x02: /* LLDT */ CPU_LLDT(inst.op1.d); goto nextopcode; /* Else value will saved */ + case 0x03: /* LTR */ + CPU_LTR(inst.op1.d); + goto nextopcode; /* Else value will saved */ + default: LOG(LOG_ERROR|LOG_CPU,"Group 6 Illegal subfunction %X",inst.rm_index); } @@ -437,7 +460,46 @@ switch (inst.code.op) { case O_LAR: { Bitu ar;CPU_LAR(inst.op1.d,ar); - inst.op2.d=ar; + inst.op1.d=ar; + } + break; + case O_LSL: + { + Bitu limit;CPU_LSL(inst.op1.d,limit); + inst.op1.d=limit; + } + break; + case O_ARPL: + { + Bitu new_sel=inst.op1.d; + CPU_ARPL(new_sel,inst.op2.d); + inst.op1.d=new_sel; + } + break; + case O_BTw: + case O_BTSw: + case O_BTCw: + 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; + } } break; case O_BTd: diff --git a/src/cpu/core_full/optable.h b/src/cpu/core_full/optable.h index 08054c04..bb10ff32 100644 --- a/src/cpu/core_full/optable.h +++ b/src/cpu/core_full/optable.h @@ -69,7 +69,7 @@ static OpCode OpCodeTable[1024]={ /* 0x60 - 0x67 */ {D_PUSHAw ,0 ,0 ,0 },{D_POPAw ,0 ,0 ,0 }, -{L_MODRM ,O_BOUNDw ,0 ,0 },{0 ,0 ,0 ,0 }, +{L_MODRM ,O_BOUNDw ,0 ,0 },{L_MODRM ,O_ARPL ,S_Ew ,M_EwGw }, {L_PRESEG ,0 ,0 ,fs },{L_PRESEG ,0 ,0 ,gs }, {L_PREOP ,0 ,0 ,0 },{L_PREADD ,0 ,0 ,0 }, /* 0x68 - 0x6f */ @@ -182,7 +182,7 @@ static OpCode OpCodeTable[1024]={ /* 0x100 - 0x107 */ {L_MODRM ,O_GRP6w ,S_Ew ,M_Ew },{L_MODRM ,O_GRP7w ,S_Ew ,M_Ew }, -{L_MODRM ,O_LAR ,S_Gw ,M_Ew },{0 ,0 ,0 ,0 }, +{L_MODRM ,O_LAR ,S_Gw ,M_Ew },{L_MODRM ,O_LSL ,S_Gw ,M_Ew }, {0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, {0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, /* 0x108 - 0x10f */ @@ -539,7 +539,7 @@ static OpCode OpCodeTable[1024]={ /* 0x300 - 0x307 */ {L_MODRM ,O_GRP6d ,S_Ew ,M_Ew },{L_MODRM ,O_GRP7d ,S_Ew ,M_Ew }, -{L_MODRM ,O_LAR ,S_Gd ,M_Ed },{0 ,0 ,0 ,0 }, +{L_MODRM ,O_LAR ,S_Gd ,M_Ew },{L_MODRM ,O_LSL ,S_Gd ,M_Ew }, {0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, {0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, /* 0x308 - 0x30f */ diff --git a/src/cpu/core_full/support.h b/src/cpu/core_full/support.h index 23afd1db..9460c6df 100644 --- a/src/cpu/core_full/support.h +++ b/src/cpu/core_full/support.h @@ -82,7 +82,8 @@ enum { O_GRP6w,O_GRP6d, O_GRP7w,O_GRP7d, O_M_Cd_Rd,O_M_Rd_Cd, - O_LAR, + O_LAR,O_LSL, + O_ARPL, O_BTw,O_BTSw,O_BTRw,O_BTCw, O_BTd,O_BTSd,O_BTRd,O_BTCd,