DOSBox-X
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Defines
src/cpu/core_normal/table_ea.h
00001 /*
00002  *  Copyright (C) 2002-2020  The DOSBox Team
00003  *
00004  *  This program is free software; you can redistribute it and/or modify
00005  *  it under the terms of the GNU General Public License as published by
00006  *  the Free Software Foundation; either version 2 of the License, or
00007  *  (at your option) any later version.
00008  *
00009  *  This program is distributed in the hope that it will be useful,
00010  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00011  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012  *  GNU General Public License for more details.
00013  *
00014  *  You should have received a copy of the GNU General Public License along
00015  *  with this program; if not, write to the Free Software Foundation, Inc.,
00016  *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
00017  */
00018 
00019 typedef PhysPt (*EA_LookupHandler)(void);
00020 
00021 /* The MOD/RM Decoder for EA for this decoder's addressing modes */
00022 static PhysPt EA_16_00_n(void) { return BaseDS+(Bit16u)(reg_bx+reg_si); }
00023 static PhysPt EA_16_01_n(void) { return BaseDS+(Bit16u)(reg_bx+reg_di); }
00024 static PhysPt EA_16_02_n(void) { return BaseSS+(Bit16u)(reg_bp+reg_si); }
00025 static PhysPt EA_16_03_n(void) { return BaseSS+(Bit16u)(reg_bp+reg_di); }
00026 static PhysPt EA_16_04_n(void) { return BaseDS+(Bit16u)(reg_si); }
00027 static PhysPt EA_16_05_n(void) { return BaseDS+(Bit16u)(reg_di); }
00028 static PhysPt EA_16_06_n(void) { return BaseDS+(Bit16u)(Fetchw());}
00029 static PhysPt EA_16_07_n(void) { return BaseDS+(Bit16u)(reg_bx); }
00030 
00031 static PhysPt EA_16_40_n(void) { return BaseDS+(Bit16u)(reg_bx+reg_si+(Bit16u)Fetchbs()); }
00032 static PhysPt EA_16_41_n(void) { return BaseDS+(Bit16u)(reg_bx+reg_di+(Bit16u)Fetchbs()); }
00033 static PhysPt EA_16_42_n(void) { return BaseSS+(Bit16u)(reg_bp+reg_si+(Bit16u)Fetchbs()); }
00034 static PhysPt EA_16_43_n(void) { return BaseSS+(Bit16u)(reg_bp+reg_di+(Bit16u)Fetchbs()); }
00035 static PhysPt EA_16_44_n(void) { return BaseDS+(Bit16u)(reg_si+(Bit16u)Fetchbs()); }
00036 static PhysPt EA_16_45_n(void) { return BaseDS+(Bit16u)(reg_di+(Bit16u)Fetchbs()); }
00037 static PhysPt EA_16_46_n(void) { return BaseSS+(Bit16u)(reg_bp+(Bit16u)Fetchbs()); }
00038 static PhysPt EA_16_47_n(void) { return BaseDS+(Bit16u)(reg_bx+(Bit16u)Fetchbs()); }
00039 
00040 static PhysPt EA_16_80_n(void) { return BaseDS+(Bit16u)(reg_bx+reg_si+(Bit16u)Fetchws()); }
00041 static PhysPt EA_16_81_n(void) { return BaseDS+(Bit16u)(reg_bx+reg_di+(Bit16u)Fetchws()); }
00042 static PhysPt EA_16_82_n(void) { return BaseSS+(Bit16u)(reg_bp+reg_si+(Bit16u)Fetchws()); }
00043 static PhysPt EA_16_83_n(void) { return BaseSS+(Bit16u)(reg_bp+reg_di+(Bit16u)Fetchws()); }
00044 static PhysPt EA_16_84_n(void) { return BaseDS+(Bit16u)(reg_si+(Bit16u)Fetchws()); }
00045 static PhysPt EA_16_85_n(void) { return BaseDS+(Bit16u)(reg_di+(Bit16u)Fetchws()); }
00046 static PhysPt EA_16_86_n(void) { return BaseSS+(Bit16u)(reg_bp+(Bit16u)Fetchws()); }
00047 static PhysPt EA_16_87_n(void) { return BaseDS+(Bit16u)(reg_bx+(Bit16u)Fetchws()); }
00048 
00049 static Bit32u SIBZero=0;
00050 static Bit32u * SIBIndex[8]= { &reg_eax,&reg_ecx,&reg_edx,&reg_ebx,&SIBZero,&reg_ebp,&reg_esi,&reg_edi };
00051 
00052 static INLINE PhysPt Sib(Bitu mode) {
00053         Bit8u sib=Fetchb();
00054         PhysPt base;
00055         switch (sib&7) {
00056         case 0: /* EAX Base */
00057                 base=BaseDS+reg_eax;break;
00058         case 1: /* ECX Base */
00059                 base=BaseDS+reg_ecx;break;
00060         case 2: /* EDX Base */
00061                 base=BaseDS+reg_edx;break;
00062         case 3: /* EBX Base */
00063                 base=BaseDS+reg_ebx;break;
00064         case 4: /* ESP Base */
00065                 base=BaseSS+reg_esp;break;
00066         case 5: /* #1 Base */
00067                 if (!mode) {
00068                         base=BaseDS+Fetchd();break;
00069                 } else {
00070                         base=BaseSS+reg_ebp;break;
00071                 }
00072         case 6: /* ESI Base */
00073                 base=BaseDS+reg_esi;break;
00074         case 7: /* EDI Base */
00075                 base=BaseDS+reg_edi;break;
00076         }
00077         base+=*SIBIndex[(sib >> 3) &7] << (sib >> 6);
00078         return base;
00079 }
00080 
00081 static PhysPt EA_32_00_n(void) { return BaseDS+reg_eax; }
00082 static PhysPt EA_32_01_n(void) { return BaseDS+reg_ecx; }
00083 static PhysPt EA_32_02_n(void) { return BaseDS+reg_edx; }
00084 static PhysPt EA_32_03_n(void) { return BaseDS+reg_ebx; }
00085 static PhysPt EA_32_04_n(void) { return Sib(0);}
00086 static PhysPt EA_32_05_n(void) { return BaseDS+Fetchd(); }
00087 static PhysPt EA_32_06_n(void) { return BaseDS+reg_esi; }
00088 static PhysPt EA_32_07_n(void) { return BaseDS+reg_edi; }
00089 
00090 static PhysPt EA_32_40_n(void) { return BaseDS+reg_eax+(PhysPt)Fetchbs(); }
00091 static PhysPt EA_32_41_n(void) { return BaseDS+reg_ecx+(PhysPt)Fetchbs(); }
00092 static PhysPt EA_32_42_n(void) { return BaseDS+reg_edx+(PhysPt)Fetchbs(); }
00093 static PhysPt EA_32_43_n(void) { return BaseDS+reg_ebx+(PhysPt)Fetchbs(); }
00094 static PhysPt EA_32_44_n(void) { PhysPt temp=Sib(1);return temp+(PhysPt)Fetchbs();}
00095 //static PhysPt EA_32_44_n(void) { return Sib(1)+Fetchbs();}
00096 static PhysPt EA_32_45_n(void) { return BaseSS+reg_ebp+(PhysPt)Fetchbs(); }
00097 static PhysPt EA_32_46_n(void) { return BaseDS+reg_esi+(PhysPt)Fetchbs(); }
00098 static PhysPt EA_32_47_n(void) { return BaseDS+reg_edi+(PhysPt)Fetchbs(); }
00099 
00100 static PhysPt EA_32_80_n(void) { return BaseDS+reg_eax+(PhysPt)Fetchds(); }
00101 static PhysPt EA_32_81_n(void) { return BaseDS+reg_ecx+(PhysPt)Fetchds(); }
00102 static PhysPt EA_32_82_n(void) { return BaseDS+reg_edx+(PhysPt)Fetchds(); }
00103 static PhysPt EA_32_83_n(void) { return BaseDS+reg_ebx+(PhysPt)Fetchds(); }
00104 static PhysPt EA_32_84_n(void) { PhysPt temp=Sib(2);return temp+(PhysPt)Fetchds();}
00105 //static PhysPt EA_32_84_n(void) { return Sib(2)+Fetchds();}
00106 static PhysPt EA_32_85_n(void) { return BaseSS+reg_ebp+(PhysPt)Fetchds(); }
00107 static PhysPt EA_32_86_n(void) { return BaseDS+reg_esi+(PhysPt)Fetchds(); }
00108 static PhysPt EA_32_87_n(void) { return BaseDS+reg_edi+(PhysPt)Fetchds(); }
00109 
00110 static GetEAHandler EATable[512]={
00111 /* 00 */
00112         EA_16_00_n,EA_16_01_n,EA_16_02_n,EA_16_03_n,EA_16_04_n,EA_16_05_n,EA_16_06_n,EA_16_07_n,
00113         EA_16_00_n,EA_16_01_n,EA_16_02_n,EA_16_03_n,EA_16_04_n,EA_16_05_n,EA_16_06_n,EA_16_07_n,
00114         EA_16_00_n,EA_16_01_n,EA_16_02_n,EA_16_03_n,EA_16_04_n,EA_16_05_n,EA_16_06_n,EA_16_07_n,
00115         EA_16_00_n,EA_16_01_n,EA_16_02_n,EA_16_03_n,EA_16_04_n,EA_16_05_n,EA_16_06_n,EA_16_07_n,
00116         EA_16_00_n,EA_16_01_n,EA_16_02_n,EA_16_03_n,EA_16_04_n,EA_16_05_n,EA_16_06_n,EA_16_07_n,
00117         EA_16_00_n,EA_16_01_n,EA_16_02_n,EA_16_03_n,EA_16_04_n,EA_16_05_n,EA_16_06_n,EA_16_07_n,
00118         EA_16_00_n,EA_16_01_n,EA_16_02_n,EA_16_03_n,EA_16_04_n,EA_16_05_n,EA_16_06_n,EA_16_07_n,
00119         EA_16_00_n,EA_16_01_n,EA_16_02_n,EA_16_03_n,EA_16_04_n,EA_16_05_n,EA_16_06_n,EA_16_07_n,
00120 /* 01 */
00121         EA_16_40_n,EA_16_41_n,EA_16_42_n,EA_16_43_n,EA_16_44_n,EA_16_45_n,EA_16_46_n,EA_16_47_n,
00122         EA_16_40_n,EA_16_41_n,EA_16_42_n,EA_16_43_n,EA_16_44_n,EA_16_45_n,EA_16_46_n,EA_16_47_n,
00123         EA_16_40_n,EA_16_41_n,EA_16_42_n,EA_16_43_n,EA_16_44_n,EA_16_45_n,EA_16_46_n,EA_16_47_n,
00124         EA_16_40_n,EA_16_41_n,EA_16_42_n,EA_16_43_n,EA_16_44_n,EA_16_45_n,EA_16_46_n,EA_16_47_n,
00125         EA_16_40_n,EA_16_41_n,EA_16_42_n,EA_16_43_n,EA_16_44_n,EA_16_45_n,EA_16_46_n,EA_16_47_n,
00126         EA_16_40_n,EA_16_41_n,EA_16_42_n,EA_16_43_n,EA_16_44_n,EA_16_45_n,EA_16_46_n,EA_16_47_n,
00127         EA_16_40_n,EA_16_41_n,EA_16_42_n,EA_16_43_n,EA_16_44_n,EA_16_45_n,EA_16_46_n,EA_16_47_n,
00128         EA_16_40_n,EA_16_41_n,EA_16_42_n,EA_16_43_n,EA_16_44_n,EA_16_45_n,EA_16_46_n,EA_16_47_n,
00129 /* 10 */
00130         EA_16_80_n,EA_16_81_n,EA_16_82_n,EA_16_83_n,EA_16_84_n,EA_16_85_n,EA_16_86_n,EA_16_87_n,
00131         EA_16_80_n,EA_16_81_n,EA_16_82_n,EA_16_83_n,EA_16_84_n,EA_16_85_n,EA_16_86_n,EA_16_87_n,
00132         EA_16_80_n,EA_16_81_n,EA_16_82_n,EA_16_83_n,EA_16_84_n,EA_16_85_n,EA_16_86_n,EA_16_87_n,
00133         EA_16_80_n,EA_16_81_n,EA_16_82_n,EA_16_83_n,EA_16_84_n,EA_16_85_n,EA_16_86_n,EA_16_87_n,
00134         EA_16_80_n,EA_16_81_n,EA_16_82_n,EA_16_83_n,EA_16_84_n,EA_16_85_n,EA_16_86_n,EA_16_87_n,
00135         EA_16_80_n,EA_16_81_n,EA_16_82_n,EA_16_83_n,EA_16_84_n,EA_16_85_n,EA_16_86_n,EA_16_87_n,
00136         EA_16_80_n,EA_16_81_n,EA_16_82_n,EA_16_83_n,EA_16_84_n,EA_16_85_n,EA_16_86_n,EA_16_87_n,
00137         EA_16_80_n,EA_16_81_n,EA_16_82_n,EA_16_83_n,EA_16_84_n,EA_16_85_n,EA_16_86_n,EA_16_87_n,
00138 /* 11 These are illegal so make em 0 */
00139         0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,
00140         0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,
00141         0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,
00142         0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,
00143 /* 00 */
00144         EA_32_00_n,EA_32_01_n,EA_32_02_n,EA_32_03_n,EA_32_04_n,EA_32_05_n,EA_32_06_n,EA_32_07_n,
00145         EA_32_00_n,EA_32_01_n,EA_32_02_n,EA_32_03_n,EA_32_04_n,EA_32_05_n,EA_32_06_n,EA_32_07_n,
00146         EA_32_00_n,EA_32_01_n,EA_32_02_n,EA_32_03_n,EA_32_04_n,EA_32_05_n,EA_32_06_n,EA_32_07_n,
00147         EA_32_00_n,EA_32_01_n,EA_32_02_n,EA_32_03_n,EA_32_04_n,EA_32_05_n,EA_32_06_n,EA_32_07_n,
00148         EA_32_00_n,EA_32_01_n,EA_32_02_n,EA_32_03_n,EA_32_04_n,EA_32_05_n,EA_32_06_n,EA_32_07_n,
00149         EA_32_00_n,EA_32_01_n,EA_32_02_n,EA_32_03_n,EA_32_04_n,EA_32_05_n,EA_32_06_n,EA_32_07_n,
00150         EA_32_00_n,EA_32_01_n,EA_32_02_n,EA_32_03_n,EA_32_04_n,EA_32_05_n,EA_32_06_n,EA_32_07_n,
00151         EA_32_00_n,EA_32_01_n,EA_32_02_n,EA_32_03_n,EA_32_04_n,EA_32_05_n,EA_32_06_n,EA_32_07_n,
00152 /* 01 */
00153         EA_32_40_n,EA_32_41_n,EA_32_42_n,EA_32_43_n,EA_32_44_n,EA_32_45_n,EA_32_46_n,EA_32_47_n,
00154         EA_32_40_n,EA_32_41_n,EA_32_42_n,EA_32_43_n,EA_32_44_n,EA_32_45_n,EA_32_46_n,EA_32_47_n,
00155         EA_32_40_n,EA_32_41_n,EA_32_42_n,EA_32_43_n,EA_32_44_n,EA_32_45_n,EA_32_46_n,EA_32_47_n,
00156         EA_32_40_n,EA_32_41_n,EA_32_42_n,EA_32_43_n,EA_32_44_n,EA_32_45_n,EA_32_46_n,EA_32_47_n,
00157         EA_32_40_n,EA_32_41_n,EA_32_42_n,EA_32_43_n,EA_32_44_n,EA_32_45_n,EA_32_46_n,EA_32_47_n,
00158         EA_32_40_n,EA_32_41_n,EA_32_42_n,EA_32_43_n,EA_32_44_n,EA_32_45_n,EA_32_46_n,EA_32_47_n,
00159         EA_32_40_n,EA_32_41_n,EA_32_42_n,EA_32_43_n,EA_32_44_n,EA_32_45_n,EA_32_46_n,EA_32_47_n,
00160         EA_32_40_n,EA_32_41_n,EA_32_42_n,EA_32_43_n,EA_32_44_n,EA_32_45_n,EA_32_46_n,EA_32_47_n,
00161 /* 10 */
00162         EA_32_80_n,EA_32_81_n,EA_32_82_n,EA_32_83_n,EA_32_84_n,EA_32_85_n,EA_32_86_n,EA_32_87_n,
00163         EA_32_80_n,EA_32_81_n,EA_32_82_n,EA_32_83_n,EA_32_84_n,EA_32_85_n,EA_32_86_n,EA_32_87_n,
00164         EA_32_80_n,EA_32_81_n,EA_32_82_n,EA_32_83_n,EA_32_84_n,EA_32_85_n,EA_32_86_n,EA_32_87_n,
00165         EA_32_80_n,EA_32_81_n,EA_32_82_n,EA_32_83_n,EA_32_84_n,EA_32_85_n,EA_32_86_n,EA_32_87_n,
00166         EA_32_80_n,EA_32_81_n,EA_32_82_n,EA_32_83_n,EA_32_84_n,EA_32_85_n,EA_32_86_n,EA_32_87_n,
00167         EA_32_80_n,EA_32_81_n,EA_32_82_n,EA_32_83_n,EA_32_84_n,EA_32_85_n,EA_32_86_n,EA_32_87_n,
00168         EA_32_80_n,EA_32_81_n,EA_32_82_n,EA_32_83_n,EA_32_84_n,EA_32_85_n,EA_32_86_n,EA_32_87_n,
00169         EA_32_80_n,EA_32_81_n,EA_32_82_n,EA_32_83_n,EA_32_84_n,EA_32_85_n,EA_32_86_n,EA_32_87_n,
00170 /* 11 These are illegal so make em 0 */
00171         0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,
00172         0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,
00173         0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,
00174         0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0
00175 };
00176 
00177 extern bool do_seg_limits;
00178 
00179 #define GetEADirect(sz)                                         \
00180         PhysPt eaa;                                             \
00181         if (TEST_PREFIX_ADDR)                                   \
00182                 eaa=Fetchd();                                   \
00183         else                                                    \
00184                 eaa=Fetchw();                                   \
00185         if (do_seg_limits) {                                    \
00186                 if (Segs.expanddown[core.base_val_ds]) {        \
00187                         if (eaa <= SegLimit(core.base_val_ds)) {\
00188                                 LOG_MSG("Limit check %x <= %x (E)",(unsigned int)eaa,(unsigned int)SegLimit(core.base_val_ds)); \
00189                                 goto gp_fault;                  \
00190                         }                                       \
00191                 }                                               \
00192                 else {                                          \
00193                         if ((eaa+(sz)-1UL) > SegLimit(core.base_val_ds)) { \
00194                                 LOG_MSG("Limit check %x+%x-1 = %x > %x",(unsigned int)eaa,(unsigned int)sz,(unsigned int)(eaa+(sz)-1U),(unsigned int)SegLimit(core.base_val_ds)); \
00195                                 goto gp_fault;                  \
00196                         }                                       \
00197                 }                                               \
00198         }                                                       \
00199         eaa += BaseDS;
00200