1
0
Fork 0

Support for 0x67 prefix and some new 0x66 prefixed instructions.

Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@573
This commit is contained in:
Sjoerd van der Berg 2002-12-16 14:43:54 +00:00
parent 6e61c2621a
commit 4f04dd2b8a
7 changed files with 196 additions and 70 deletions

View file

@ -293,7 +293,16 @@ restart:
#include "prefix_66.h"
break;
case 0x67: /* Address Size Prefix */
#ifdef CPU_PREFIX_67
prefix.mark|=PREFIX_ADDR;
#ifdef CPU_PREFIX_COUNT
prefix.count++;
#endif
lookupEATable=EAPrefixTable[prefix.mark];
goto restart;
#else
NOTDONE;
#endif
break;
#endif
case 0x68: /* PUSH Iw */
@ -657,26 +666,22 @@ restart:
}
case 0xa0: /* MOV AL,Ob */
{
GetEADirect;
reg_al=LoadMb(eaa);
reg_al=LoadMb(GetEADirect[prefix.mark]());
}
break;
case 0xa1: /* MOV AX,Ow */
{
GetEADirect;
reg_ax=LoadMw(eaa);
reg_ax=LoadMw(GetEADirect[prefix.mark]());
}
break;
case 0xa2: /* MOV Ob,AL */
{
GetEADirect;
SaveMb(eaa,reg_al);
SaveMb(GetEADirect[prefix.mark](),reg_al);
}
break;
case 0xa3: /* MOV Ow,AX */
{
GetEADirect;
SaveMw(eaa,reg_ax);
SaveMw(GetEADirect[prefix.mark](),reg_ax);
}
break;
case 0xa4: /* MOVSB */
@ -956,6 +961,7 @@ restart:
case 0xde: /* FPU ESC 6 */
case 0xdf: /* FPU ESC 7 */
{
LOG_WARN("FPU used");
Bit8u rm=Fetchb();
if (rm<0xc0) GetEAa;
}
@ -974,9 +980,15 @@ restart:
else ADDIPFAST(1);
break;
case 0xe3: /* JCXZ */
if (!reg_cx) ADDIPFAST(Fetchbs());
else ADDIPFAST(1);
break;
{
Bitu test;
if (prefix.mark & PREFIX_ADDR) {
test=reg_ecx;PrefixReset;
} else test=reg_cx;
if (!test) ADDIPFAST(Fetchbs());
else ADDIPFAST(1);
break;
}
case 0xe4: /* IN AL,Ib */
{ Bit16u port=Fetchb();reg_al=IO_Read(port);}
break;

View file

@ -149,12 +149,23 @@ switch(Fetchb()) {
reg_edi=Pop_32();reg_edi=Pop_32();reg_ebp=Pop_32();Pop_32();//Don't save ESP
reg_ebx=Pop_32();reg_edx=Pop_32();reg_ecx=Pop_32();reg_eax=Pop_32();
break;
case 0x68: /* PUSH Id */
Push_32(Fetchd());break;
case 0x64: /* SEG FS: */
SegPrefix_66(fs);break;
case 0x65: /* SEG GS: */
SegPrefix_66(gs);break;
case 0x67: /* Address Size Prefix */
#ifdef CPU_PREFIX_67
prefix.mark|=PREFIX_ADDR;
#ifdef CPU_PREFIX_COUNT
prefix.count++;
#endif
lookupEATable=EAPrefixTable[prefix.mark];
goto restart_66;
#else
NOTDONE;
#endif
case 0x68: /* PUSH Id */
Push_32(Fetchd());break;
case 0x69: /* IMUL Gd,Ed,Id */
{
GetRMrd;
@ -267,6 +278,15 @@ switch(Fetchb()) {
case 0x8c:
LOG_WARN("CPU:66:8c looped back");
break;
case 0x8d: /* LEA */
{
prefix.segbase=0;
prefix.mark|=PREFIX_SEG;
lookupEATable=EAPrefixTable[prefix.mark];
GetRMrd;GetEAa;
*rmrd=(Bit32u)eaa;
break;
}
case 0x8f: /* POP Ed */
{
GetRM;
@ -321,14 +341,12 @@ switch(Fetchb()) {
}
case 0xa1: /* MOV EAX,Ow */
{
GetEADirect;
reg_eax=LoadMd(eaa);
reg_eax=LoadMd(GetEADirect[prefix.mark]());
}
break;
case 0xa3: /* MOV Ow,EAX */
{
GetEADirect;
SaveMd(eaa,reg_eax);
SaveMd(GetEADirect[prefix.mark](),reg_eax);
}
break;
case 0xa5: /* MOVSD */
@ -383,6 +401,18 @@ switch(Fetchb()) {
reg_edi=Fetchd();break;
case 0xc1: /* GRP2 Ed,Ib */
GRP2D(Fetchb());break;
case 0xc4: /* LES */
{
GetRMrd;GetEAa;
*rmrd=LoadMd(eaa);SegSet16(es,LoadMw(eaa+4));
break;
}
case 0xc5: /* LDS */
{
GetRMrd;GetEAa;
*rmrd=LoadMd(eaa);SegSet16(ds,LoadMw(eaa+4));
break;
}
case 0xc7: /* MOV Ed,Id */
{
GetRM;

View file

@ -33,6 +33,14 @@ switch (Fetchb()) {
else {GetEAa;DSHRD(eaa,*rmrd,Fetchb(),LoadMd,SaveMd);}
break;
}
case 0xad: /* SHRD Ed,Gd,Cl */
{
GetRMrd;
if (rm >= 0xc0 ) {GetEArd;DSHRD(*eard,*rmrd,reg_cl,LoadRd,SaveRd);}
else {GetEAa;DSHRD(eaa,*rmrd,reg_cl,LoadMd,SaveMd);}
break;
}
case 0xb6: /* MOVZX Gd,Eb */
{
GetRMrd;
@ -44,8 +52,8 @@ switch (Fetchb()) {
{
GetRMrd;
Bit64s res;
if (rm >= 0xc0 ) {GetEArd;res=(Bit64s)(*rmrd) * (Bit64s)(*eards);}
else {GetEAa;res=(Bit64s)(*rmrd) * (Bit64s)LoadMds(eaa);}
if (rm >= 0xc0 ) {GetEArd;res=((Bit64s)((Bit32s)*rmrd) * (Bit64s)((Bit32s)*eards));}
else {GetEAa;res=((Bit64s)((Bit32s)*rmrd) * (Bit64s)LoadMds(eaa));}
*rmrd=(Bit32s)(res);
flags.type=t_MUL;
if ((res>-((Bit64s)(2147483647)+1)) && (res<(Bit64s)2147483647)) {flags.cf=false;flags.of=false;}
@ -108,6 +116,56 @@ switch (Fetchb()) {
flags.type=t_CF;
break;
}
case 0xbb: /* BTC Ed,Gd */
{
GetRMrd;
Bit32u mask=1 << (*rmrd & 31);
if (rm >= 0xc0 ) {
GetEArd;
flags.cf=(*eard & mask)>0;
*eard^=mask;
} else {
GetEAa;Bit32u old=LoadMd(eaa);
flags.cf=(old & mask)>0;
SaveMd(eaa,old ^ mask);
}
if (flags.type!=t_CF) { flags.prev_type=flags.type;flags.type=t_CF; }
break;
}
case 0xbc: /* BSF Gd,Ed */
{
GetRMrd;
Bit32u result,value;
if (rm >= 0xc0) { GetEArd; value=*eard; }
else { GetEAa; value=LoadMd(eaa); }
if (value==0) {
flags.zf = true;
} else {
result = 0;
while ((value & 0x01)==0) { result++; value>>=1; }
flags.zf = false;
*rmrd = result;
}
flags.type=t_UNKNOWN;
break;
}
case 0xbd: /* BSR Gd,Ed */
{
GetRMrd;
Bit32u result,value;
if (rm >= 0xc0) { GetEArd; value=*eard; }
else { GetEAa; value=LoadMd(eaa); }
if (value==0) {
flags.zf = true;
} else {
result = 35; // Operandsize-1
while ((value & 0x80000000)==0) { result--; value<<=1; }
flags.zf = false;
*rmrd = result;
}
flags.type=t_UNKNOWN;
break;
}
case 0xbe: /* MOVSX Gd,Eb */
{
GetRMrd;

View file

@ -59,6 +59,12 @@ switch(Fetchb()) {
/* 0x21 MOV Rd,DRx (386) */
/* 0x22 MOV CRx,Rd (386) */
/* 0x23 MOV DRx,Rd (386) */
case 0x23: /* MOV DRx,Rd */
{
GetRM;
LOG_DEBUG("CPU:0F:23 does nothing");
}
break;
/* 0x24 MOV Rd,TRx (386) */
/* 0x26 MOV TRx,Rd (386) */
/* 0x30 WRMSR (P5) */
@ -394,7 +400,6 @@ switch(Fetchb()) {
flags.type=t_UNKNOWN;
break;
}
/* 0xbd BSR Gw,Ew */
case 0xbe: /* MOVSX Gw,Eb */
{
GetRMrw;

View file

@ -95,13 +95,17 @@ static INLINE Bit32u Pop_32() {
from=SegBase(ds)+reg_si; \
}
#include "helpers.h"
#include "table_ea.h"
#include "../modrm.h"
#include "instructions.h"
static Bit8s table_df_8[2]={1,-1};
static Bit16s table_df_16[2]={2,-2};
static Bit32s table_df_32[2]={4,-4};
static void Repeat_Normal(bool testz,bool prefix_66) {
PhysPt base_si,base_di;
@ -110,6 +114,7 @@ static void Repeat_Normal(bool testz,bool prefix_66) {
if (flags.df) direct=-1;
else direct=1;
base_di=SegBase(es);
if (prefix.mark & PREFIX_ADDR) E_Exit("Unhandled 0x67 prefixed string op");
rep_again:
if (prefix.mark & PREFIX_SEG) {
base_si=(prefix.segbase);
@ -137,6 +142,16 @@ rep_again:
prefix.mark|=PREFIX_SEG;
prefix.count++;
goto rep_again;
case 0x64: /* FS Prefix */
prefix.segbase=SegBase(fs);
prefix.mark|=PREFIX_SEG;
prefix.count++;
goto rep_again;
case 0x65: /* GS Prefix */
prefix.segbase=SegBase(gs);
prefix.mark|=PREFIX_SEG;
prefix.count++;
goto rep_again;
case 0x66: /* Size Prefix */
prefix.count++;
prefix_66=!prefix_66;

View file

@ -19,6 +19,8 @@
/* Some variables for EA Loolkup */
typedef EAPoint (*GetEATable[256])(void);
typedef EAPoint (*EA_LookupHandler)(void);
static GetEATable * lookupEATable;
#define PREFIX_NONE 0x0
@ -35,6 +37,7 @@ static struct {
/* Gets initialized at the bottem, can't seem to declare forward references */
static GetEATable * EAPrefixTable[4];
#define SegPrefix(blah) \
prefix.segbase=SegBase(blah); \
prefix.mark|=PREFIX_SEG; \
@ -55,29 +58,6 @@ static GetEATable * EAPrefixTable[4];
prefix.count=0; \
lookupEATable=EAPrefixTable[PREFIX_NONE];
#if 1
#define GetEADirect \
EAPoint eaa;switch (prefix.mark) { \
case PREFIX_NONE:eaa=SegBase(ds)+Fetchw();break; \
case PREFIX_SEG:eaa=prefix.segbase+Fetchw();PrefixReset;break; \
case PREFIX_ADDR:eaa=SegBase(ds)+Fetchd();PrefixReset;break; \
case PREFIX_SEG_ADDR:eaa=prefix.segbase+Fetchd();PrefixReset;break; \
}
#else
#define GetEADirect \
EAPoint eaa; \
if (!prefix.mark) { eaa=SegBase(ds)+Fetchw();} \
else if (prefix.mark == PREFIX_SEG) { eaa=prefix.segbase+Fetchw();PrefixReset;} \
else if (prefix.mark == PREFIX_ADDR) { eaa=SegBase(ds)+Fetchd();PrefixReset;} \
else if (prefix.mark == PREFIX_SEG_ADDR) { eaa=prefix.segbase+Fetchd();PrefixReset;}
#endif
/* The MOD/RM Decoder for EA for this decoder's addressing modes */
static EAPoint EA_16_00_n(void) { return SegBase(ds)+(Bit16u)(reg_bx+(Bit16s)reg_si); }
@ -240,32 +220,32 @@ INLINE EAPoint Sib(Bitu mode) {
};
static EAPoint EA_32_00_n(void) { return SegBase(ds)+reg_eax; }
static EAPoint EA_32_01_n(void) { return SegBase(ds)+reg_ecx; }
static EAPoint EA_32_02_n(void) { return SegBase(ds)+reg_edx; }
static EAPoint EA_32_03_n(void) { return SegBase(ds)+reg_ebx; }
static EAPoint EA_32_04_n(void) { return Sib(0);}
static EAPoint EA_32_05_n(void) { return SegBase(ds)+Fetchd(); }
static EAPoint EA_32_06_n(void) { return SegBase(ds)+reg_esi; }
static EAPoint EA_32_07_n(void) { return SegBase(ds)+reg_edi; }
static EAPoint EA_32_00_n(void) { PrefixReset;return SegBase(ds)+reg_eax; }
static EAPoint EA_32_01_n(void) { PrefixReset;return SegBase(ds)+reg_ecx; }
static EAPoint EA_32_02_n(void) { PrefixReset;return SegBase(ds)+reg_edx; }
static EAPoint EA_32_03_n(void) { PrefixReset;return SegBase(ds)+reg_ebx; }
static EAPoint EA_32_04_n(void) { PrefixReset;return Sib(0);}
static EAPoint EA_32_05_n(void) { PrefixReset;return SegBase(ds)+Fetchd(); }
static EAPoint EA_32_06_n(void) { PrefixReset;return SegBase(ds)+reg_esi; }
static EAPoint EA_32_07_n(void) { PrefixReset;return SegBase(ds)+reg_edi; }
static EAPoint EA_32_40_n(void) { return SegBase(ds)+reg_eax+Fetchbs(); }
static EAPoint EA_32_41_n(void) { return SegBase(ds)+reg_ecx+Fetchbs(); }
static EAPoint EA_32_42_n(void) { return SegBase(ds)+reg_edx+Fetchbs(); }
static EAPoint EA_32_43_n(void) { return SegBase(ds)+reg_ebx+Fetchbs(); }
static EAPoint EA_32_44_n(void) { return Sib(1)+Fetchbs();}
static EAPoint EA_32_45_n(void) { return SegBase(ss)+reg_ebp+Fetchbs(); }
static EAPoint EA_32_46_n(void) { return SegBase(ds)+reg_esi+Fetchbs(); }
static EAPoint EA_32_47_n(void) { return SegBase(ds)+reg_edi+Fetchbs(); }
static EAPoint EA_32_40_n(void) { PrefixReset;return SegBase(ds)+reg_eax+Fetchbs(); }
static EAPoint EA_32_41_n(void) { PrefixReset;return SegBase(ds)+reg_ecx+Fetchbs(); }
static EAPoint EA_32_42_n(void) { PrefixReset;return SegBase(ds)+reg_edx+Fetchbs(); }
static EAPoint EA_32_43_n(void) { PrefixReset;return SegBase(ds)+reg_ebx+Fetchbs(); }
static EAPoint EA_32_44_n(void) { PrefixReset;return Sib(1)+Fetchbs();}
static EAPoint EA_32_45_n(void) { PrefixReset;return SegBase(ss)+reg_ebp+Fetchbs(); }
static EAPoint EA_32_46_n(void) { PrefixReset;return SegBase(ds)+reg_esi+Fetchbs(); }
static EAPoint EA_32_47_n(void) { PrefixReset;return SegBase(ds)+reg_edi+Fetchbs(); }
static EAPoint EA_32_80_n(void) { return SegBase(ds)+reg_eax+Fetchds(); }
static EAPoint EA_32_81_n(void) { return SegBase(ds)+reg_ecx+Fetchds(); }
static EAPoint EA_32_82_n(void) { return SegBase(ds)+reg_edx+Fetchds(); }
static EAPoint EA_32_83_n(void) { return SegBase(ds)+reg_ebx+Fetchds(); }
static EAPoint EA_32_84_n(void) { return Sib(2)+Fetchds();}
static EAPoint EA_32_85_n(void) { return SegBase(ss)+reg_ebp+Fetchds(); }
static EAPoint EA_32_86_n(void) { return SegBase(ds)+reg_esi+Fetchds(); }
static EAPoint EA_32_87_n(void) { return SegBase(ds)+reg_edi+Fetchds(); }
static EAPoint EA_32_80_n(void) { PrefixReset;return SegBase(ds)+reg_eax+Fetchds(); }
static EAPoint EA_32_81_n(void) { PrefixReset;return SegBase(ds)+reg_ecx+Fetchds(); }
static EAPoint EA_32_82_n(void) { PrefixReset;return SegBase(ds)+reg_edx+Fetchds(); }
static EAPoint EA_32_83_n(void) { PrefixReset;return SegBase(ds)+reg_ebx+Fetchds(); }
static EAPoint EA_32_84_n(void) { PrefixReset;return Sib(2)+Fetchds();}
static EAPoint EA_32_85_n(void) { PrefixReset;return SegBase(ss)+reg_ebp+Fetchds(); }
static EAPoint EA_32_86_n(void) { PrefixReset;return SegBase(ds)+reg_esi+Fetchds(); }
static EAPoint EA_32_87_n(void) { PrefixReset;return SegBase(ds)+reg_edi+Fetchds(); }
static GetEATable GetEA_32_n={
/* 00 */
@ -327,7 +307,8 @@ INLINE EAPoint Sib_s(Bitu mode) {
case 7: /* EDI Base */
base=prefix.segbase+reg_edi;break;
}
base+=*SIBIndex[(sib >> 3) &7] << (sib >> 6); PrefixReset;
base+=*SIBIndex[(sib >> 3) &7] << (sib >> 6);
PrefixReset;
return base;
};
@ -396,4 +377,21 @@ static GetEATable GetEA_32_s={
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
};
static EAPoint GetEADirect_NONE(void) {
EAPoint result=SegBase(ds)+Fetchw();
return result;
}
static EAPoint GetEADirect_SEG(void) {
EAPoint result=prefix.segbase+Fetchw();PrefixReset;
return result;
}
static EAPoint GetEADirect_ADDR(void) {
EAPoint result=SegBase(ds)+Fetchd();PrefixReset;
return result;
}
static EAPoint GetEADirect_SEG_ADDR(void) {
EAPoint result=prefix.segbase+Fetchd();PrefixReset;
return result;
}
static EA_LookupHandler GetEADirect[4]={GetEADirect_NONE,GetEADirect_SEG,GetEADirect_ADDR,GetEADirect_SEG_ADDR};

View file

@ -55,10 +55,14 @@ extern Bitu cycle_count;
/* Enable parts of the cpu emulation */
#define CPU_386 //Enable 386 instructions
#define CPU_PREFIX_67 //Enable the 0x67 prefix
#define CPU_PREFIX_COUNT //Enable counting of prefixes
#if C_FPU
#define CPU_FPU //Enable FPU escape instructions
#endif
#include "core_16/support.h"
static Bitu CPU_Real_16_Slow_Decode_Trap(void);
@ -73,7 +77,11 @@ static Bitu CPU_Real_16_Slow_Decode(void) {
if (DEBUG_HeavyIsBreakpoint()) return 1;
#endif
#include "core_16/main.h"
// if (prefix.count) LOG_DEBUG("Prefix for non prefixed instruction");
if (prefix.count) {
PrefixReset;
//DEBUG_HeavyWriteLogInstruction();
LOG_DEBUG("Prefix for non prefixed instruction");
}
CPU_Cycles--;
}
#include "core_16/stop.h"