diff --git a/src/cpu/core_16/main.h b/src/cpu/core_16/main.h index b1cfee22..9d72cf2e 100644 --- a/src/cpu/core_16/main.h +++ b/src/cpu/core_16/main.h @@ -274,7 +274,7 @@ restart: GetRMrw;GetEAa; bound_min=LoadMw(eaa); bound_max=LoadMw(eaa+2); - if ( (*rmrw < bound_min) || (*rmrw > bound_max) ) { + if ( (((Bit16s)*rmrw) < bound_min) || (((Bit16s)*rmrw) > bound_max) ) { INTERRUPT(5); } } @@ -675,35 +675,27 @@ restart: break; } case 0xa0: /* MOV AL,Ob */ - if (segprefix_on) { - reg_al=LoadMb(segprefix_base+Fetchw()); - SegPrefixReset; - } else { - reg_al=LoadMb(SegBase(ds)+Fetchw()); + { + GetEADirect; + reg_al=LoadMb(eaa); } break; case 0xa1: /* MOV AX,Ow */ - if (segprefix_on) { - reg_ax=LoadMw(segprefix_base+Fetchw()); - SegPrefixReset; - } else { - reg_ax=LoadMw(SegBase(ds)+Fetchw()); + { + GetEADirect; + reg_ax=LoadMw(eaa); } break; case 0xa2: /* MOV Ob,AL */ - if (segprefix_on) { - SaveMb((segprefix_base+Fetchw()),reg_al); - SegPrefixReset; - } else { - SaveMb((SegBase(ds)+Fetchw()),reg_al); + { + GetEADirect; + SaveMb(eaa,reg_al); } break; case 0xa3: /* MOV Ow,AX */ - if (segprefix_on) { - SaveMw((segprefix_base+Fetchw()),reg_ax); - SegPrefixReset; - } else { - SaveMw((SegBase(ds)+Fetchw()),reg_ax); + { + GetEADirect; + SaveMw(eaa,reg_ax); } break; case 0xa4: /* MOVSB */ @@ -944,9 +936,9 @@ restart: reg_al = get_CF() ? 0xFF : 0; break; case 0xd7: /* XLAT */ - if (segprefix_on) { + if (prefixes & PREFIX_SEG) { reg_al=LoadMb(segprefix_base+(Bit16u)(reg_bx+reg_al)); - SegPrefixReset; + PrefixReset; } else { reg_al=LoadMb(SegBase(ds)+(Bit16u)(reg_bx+reg_al)); } @@ -1061,9 +1053,9 @@ restart: { EAPoint to=SegBase(es); EAPoint from; - if (segprefix_on) { + if (prefixes & PREFIX_SEG) { from=(segprefix_base); - SegPrefixReset; + PrefixReset; } else { from=SegBase(ds); } diff --git a/src/cpu/core_16/prefix_66.h b/src/cpu/core_16/prefix_66.h index 9f1c141a..d34ad4b4 100644 --- a/src/cpu/core_16/prefix_66.h +++ b/src/cpu/core_16/prefix_66.h @@ -278,19 +278,15 @@ switch(Fetchb()) { break; } case 0xa1: /* MOV EAX,Ow */ - if (segprefix_on) { - reg_eax=LoadMd(segprefix_base+Fetchw()); - SegPrefixReset; - } else { - reg_eax=LoadMd(SegBase(ds)+Fetchw()); + { + GetEADirect; + reg_eax=LoadMd(eaa); } break; case 0xa3: /* MOV Ow,EAX */ - if (segprefix_on) { - SaveMd((segprefix_base+Fetchw()),reg_eax); - SegPrefixReset; - } else { - SaveMd((SegBase(ds)+Fetchw()),reg_eax); + { + GetEADirect; + SaveMd(eaa,reg_eax); } break; case 0xa5: /* MOVSD */ diff --git a/src/cpu/core_16/prefix_of.h b/src/cpu/core_16/prefix_of.h index 5d845201..3decea1f 100644 --- a/src/cpu/core_16/prefix_of.h +++ b/src/cpu/core_16/prefix_of.h @@ -23,6 +23,7 @@ switch(Fetchb()) { break; GetRM; switch (rm & 0x38) { + case 0x00: default: E_Exit("CPU:GRP6:Illegal call %2X",(rm>>3) &3); } @@ -350,7 +351,7 @@ switch(Fetchb()) { if (flags.type!=t_CF) { flags.prev_type=flags.type;flags.type=t_CF; } break; } - case 0xbc: /* 0xbc BSF Gw,Ew */ + case 0xbc: /* 0xbc BSF Gw,Ew */ { GetRMrw; Bit16u result,value; diff --git a/src/cpu/core_16/table_ea.h b/src/cpu/core_16/table_ea.h index a1d86559..c6972693 100644 --- a/src/cpu/core_16/table_ea.h +++ b/src/cpu/core_16/table_ea.h @@ -21,25 +21,44 @@ typedef EAPoint (*GetEATable[256])(void); static GetEATable * lookupEATable; +#define PREFIX_NONE 0x0 +#define PREFIX_SEG 0x1 +#define PREFIX_ADDR 0x2 +#define PREFIX_SEG_ADDR 0x3 + + +static Bitu prefixes; static EAPoint segprefix_base; -static bool segprefix_on=false; + +/* Gets initialized at the bottem, can't seem to declare forward references */ +static GetEATable * EAPrefixTable[4]; + #define SegPrefix(blah) \ segprefix_base=SegBase(blah); \ - segprefix_on=true; \ - lookupEATable=&GetEA_16_s; \ + prefixes|=PREFIX_SEG; \ + lookupEATable=EAPrefixTable[prefixes]; \ goto restart; \ #define SegPrefix_66(blah) \ segprefix_base=SegBase(blah); \ - segprefix_on=true; \ - lookupEATable=&GetEA_16_s; \ + prefixes|=PREFIX_SEG; \ + lookupEATable=EAPrefixTable[prefixes]; \ goto restart_66; \ +#define PrefixReset \ + prefixes=PREFIX_NONE;lookupEATable=EAPrefixTable[PREFIX_NONE]; + +#define GetEADirect \ +EAPoint eaa;switch (prefixes) { \ +case PREFIX_NONE:eaa=SegBase(ds)+Fetchw();break; \ +case PREFIX_SEG:eaa=segprefix_base+Fetchw();PrefixReset;break; \ +case PREFIX_ADDR:eaa=SegBase(ds)+Fetchd();PrefixReset;break; \ +case PREFIX_SEG_ADDR:eaa=segprefix_base+Fetchd();PrefixReset;break; \ +} + -#define SegPrefixReset \ - segprefix_on=false;lookupEATable=&GetEA_16_n; /* The MOD/RM Decoder for EA for this decoder's addressing modes */ @@ -106,34 +125,34 @@ static GetEATable GetEA_16_n={ }; -#define prefixed(val) EAPoint ret=segprefix_base+val;SegPrefixReset;return ret; +#define segprefixed(val) EAPoint ret=segprefix_base+val;PrefixReset;return ret; -static EAPoint EA_16_00_s(void) { prefixed((Bit16u)(reg_bx+(Bit16s)reg_si)) } -static EAPoint EA_16_01_s(void) { prefixed((Bit16u)(reg_bx+(Bit16s)reg_di)) } -static EAPoint EA_16_02_s(void) { prefixed((Bit16u)(reg_bp+(Bit16s)reg_si)) } -static EAPoint EA_16_03_s(void) { prefixed((Bit16u)(reg_bp+(Bit16s)reg_di)) } -static EAPoint EA_16_04_s(void) { prefixed((Bit16u)(reg_si)) } -static EAPoint EA_16_05_s(void) { prefixed((Bit16u)(reg_di)) } -static EAPoint EA_16_06_s(void) { prefixed((Bit16u)(Fetchw())) } -static EAPoint EA_16_07_s(void) { prefixed((Bit16u)(reg_bx)) } +static EAPoint EA_16_00_s(void) { segprefixed((Bit16u)(reg_bx+(Bit16s)reg_si)) } +static EAPoint EA_16_01_s(void) { segprefixed((Bit16u)(reg_bx+(Bit16s)reg_di)) } +static EAPoint EA_16_02_s(void) { segprefixed((Bit16u)(reg_bp+(Bit16s)reg_si)) } +static EAPoint EA_16_03_s(void) { segprefixed((Bit16u)(reg_bp+(Bit16s)reg_di)) } +static EAPoint EA_16_04_s(void) { segprefixed((Bit16u)(reg_si)) } +static EAPoint EA_16_05_s(void) { segprefixed((Bit16u)(reg_di)) } +static EAPoint EA_16_06_s(void) { segprefixed((Bit16u)(Fetchw())) } +static EAPoint EA_16_07_s(void) { segprefixed((Bit16u)(reg_bx)) } -static EAPoint EA_16_40_s(void) { prefixed((Bit16u)(reg_bx+(Bit16s)reg_si+Fetchbs())) } -static EAPoint EA_16_41_s(void) { prefixed((Bit16u)(reg_bx+(Bit16s)reg_di+Fetchbs())) } -static EAPoint EA_16_42_s(void) { prefixed((Bit16u)(reg_bp+(Bit16s)reg_si+Fetchbs())) } -static EAPoint EA_16_43_s(void) { prefixed((Bit16u)(reg_bp+(Bit16s)reg_di+Fetchbs())) } -static EAPoint EA_16_44_s(void) { prefixed((Bit16u)(reg_si+Fetchbs())) } -static EAPoint EA_16_45_s(void) { prefixed((Bit16u)(reg_di+Fetchbs())) } -static EAPoint EA_16_46_s(void) { prefixed((Bit16u)(reg_bp+Fetchbs())) } -static EAPoint EA_16_47_s(void) { prefixed((Bit16u)(reg_bx+Fetchbs())) } +static EAPoint EA_16_40_s(void) { segprefixed((Bit16u)(reg_bx+(Bit16s)reg_si+Fetchbs())) } +static EAPoint EA_16_41_s(void) { segprefixed((Bit16u)(reg_bx+(Bit16s)reg_di+Fetchbs())) } +static EAPoint EA_16_42_s(void) { segprefixed((Bit16u)(reg_bp+(Bit16s)reg_si+Fetchbs())) } +static EAPoint EA_16_43_s(void) { segprefixed((Bit16u)(reg_bp+(Bit16s)reg_di+Fetchbs())) } +static EAPoint EA_16_44_s(void) { segprefixed((Bit16u)(reg_si+Fetchbs())) } +static EAPoint EA_16_45_s(void) { segprefixed((Bit16u)(reg_di+Fetchbs())) } +static EAPoint EA_16_46_s(void) { segprefixed((Bit16u)(reg_bp+Fetchbs())) } +static EAPoint EA_16_47_s(void) { segprefixed((Bit16u)(reg_bx+Fetchbs())) } -static EAPoint EA_16_80_s(void) { prefixed((Bit16u)(reg_bx+(Bit16s)reg_si+Fetchws())) } -static EAPoint EA_16_81_s(void) { prefixed((Bit16u)(reg_bx+(Bit16s)reg_di+Fetchws())) } -static EAPoint EA_16_82_s(void) { prefixed((Bit16u)(reg_bp+(Bit16s)reg_si+Fetchws())) } -static EAPoint EA_16_83_s(void) { prefixed((Bit16u)(reg_bp+(Bit16s)reg_di+Fetchws())) } -static EAPoint EA_16_84_s(void) { prefixed((Bit16u)(reg_si+Fetchws())) } -static EAPoint EA_16_85_s(void) { prefixed((Bit16u)(reg_di+Fetchws())) } -static EAPoint EA_16_86_s(void) { prefixed((Bit16u)(reg_bp+Fetchws())) } -static EAPoint EA_16_87_s(void) { prefixed((Bit16u)(reg_bx+Fetchws())) } +static EAPoint EA_16_80_s(void) { segprefixed((Bit16u)(reg_bx+(Bit16s)reg_si+Fetchws())) } +static EAPoint EA_16_81_s(void) { segprefixed((Bit16u)(reg_bx+(Bit16s)reg_di+Fetchws())) } +static EAPoint EA_16_82_s(void) { segprefixed((Bit16u)(reg_bp+(Bit16s)reg_si+Fetchws())) } +static EAPoint EA_16_83_s(void) { segprefixed((Bit16u)(reg_bp+(Bit16s)reg_di+Fetchws())) } +static EAPoint EA_16_84_s(void) { segprefixed((Bit16u)(reg_si+Fetchws())) } +static EAPoint EA_16_85_s(void) { segprefixed((Bit16u)(reg_di+Fetchws())) } +static EAPoint EA_16_86_s(void) { segprefixed((Bit16u)(reg_bp+Fetchws())) } +static EAPoint EA_16_87_s(void) { segprefixed((Bit16u)(reg_bx+Fetchws())) } static GetEATable GetEA_16_s={ /* 00 */ @@ -281,3 +300,117 @@ static GetEATable GetEA_32_n={ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; +INLINE EAPoint Sib_s(Bitu mode) { + Bit8u sib=Fetchb(); + EAPoint base; + switch (sib&7) { + case 0: /* EAX Base */ + base=segprefix_base+reg_eax;break; + case 1: /* ECX Base */ + base=segprefix_base+reg_ecx;break; + case 2: /* EDX Base */ + base=segprefix_base+reg_edx;break; + case 3: /* EBX Base */ + base=segprefix_base+reg_ebx;break; + case 4: /* ESP Base */ + base=segprefix_base+reg_esp;break; + case 5: /* #1 Base */ + if (!mode) { + base=segprefix_base+Fetchd();break; + } else { + base=segprefix_base+reg_ebp;break; + } + case 6: /* ESI Base */ + base=segprefix_base+reg_esi;break; + case 7: /* EDI Base */ + base=segprefix_base+reg_edi;break; + } + Bitu shift=sib >> 6; + switch ((sib >>3) &7) { + case 0: /* EAX Index */ + base+=(Bit32s)reg_eax<