DOSBox-X
|
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]= { ®_eax,®_ecx,®_edx,®_ebx,&SIBZero,®_ebp,®_esi,®_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