1 /*
2 * Copyright (C) 2002-2021 The DOSBox Team
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License along
15 * with this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17 */
18
19 typedef PhysPt (*EA_LookupHandler)(void);
20
21 /* The MOD/RM Decoder for EA for this decoder's addressing modes */
EA_16_00_n(void)22 static PhysPt EA_16_00_n(void) { return BaseDS+(Bit16u)(reg_bx+(Bit16s)reg_si); }
EA_16_01_n(void)23 static PhysPt EA_16_01_n(void) { return BaseDS+(Bit16u)(reg_bx+(Bit16s)reg_di); }
EA_16_02_n(void)24 static PhysPt EA_16_02_n(void) { return BaseSS+(Bit16u)(reg_bp+(Bit16s)reg_si); }
EA_16_03_n(void)25 static PhysPt EA_16_03_n(void) { return BaseSS+(Bit16u)(reg_bp+(Bit16s)reg_di); }
EA_16_04_n()26 static PhysPt EA_16_04_n() { return BaseDS + reg_si; }
EA_16_05_n()27 static PhysPt EA_16_05_n() { return BaseDS + reg_di; }
EA_16_06_n()28 static PhysPt EA_16_06_n() { return BaseDS + Fetchw(); }
EA_16_07_n()29 static PhysPt EA_16_07_n() { return BaseDS + reg_bx; }
30
EA_16_40_n(void)31 static PhysPt EA_16_40_n(void) { return BaseDS+(Bit16u)(reg_bx+(Bit16s)reg_si+Fetchbs()); }
EA_16_41_n(void)32 static PhysPt EA_16_41_n(void) { return BaseDS+(Bit16u)(reg_bx+(Bit16s)reg_di+Fetchbs()); }
EA_16_42_n(void)33 static PhysPt EA_16_42_n(void) { return BaseSS+(Bit16u)(reg_bp+(Bit16s)reg_si+Fetchbs()); }
EA_16_43_n(void)34 static PhysPt EA_16_43_n(void) { return BaseSS+(Bit16u)(reg_bp+(Bit16s)reg_di+Fetchbs()); }
EA_16_44_n(void)35 static PhysPt EA_16_44_n(void) { return BaseDS+(Bit16u)(reg_si+Fetchbs()); }
EA_16_45_n(void)36 static PhysPt EA_16_45_n(void) { return BaseDS+(Bit16u)(reg_di+Fetchbs()); }
EA_16_46_n(void)37 static PhysPt EA_16_46_n(void) { return BaseSS+(Bit16u)(reg_bp+Fetchbs()); }
EA_16_47_n(void)38 static PhysPt EA_16_47_n(void) { return BaseDS+(Bit16u)(reg_bx+Fetchbs()); }
39
EA_16_80_n(void)40 static PhysPt EA_16_80_n(void) { return BaseDS+(Bit16u)(reg_bx+(Bit16s)reg_si+Fetchws()); }
EA_16_81_n(void)41 static PhysPt EA_16_81_n(void) { return BaseDS+(Bit16u)(reg_bx+(Bit16s)reg_di+Fetchws()); }
EA_16_82_n(void)42 static PhysPt EA_16_82_n(void) { return BaseSS+(Bit16u)(reg_bp+(Bit16s)reg_si+Fetchws()); }
EA_16_83_n(void)43 static PhysPt EA_16_83_n(void) { return BaseSS+(Bit16u)(reg_bp+(Bit16s)reg_di+Fetchws()); }
EA_16_84_n(void)44 static PhysPt EA_16_84_n(void) { return BaseDS+(Bit16u)(reg_si+Fetchws()); }
EA_16_85_n(void)45 static PhysPt EA_16_85_n(void) { return BaseDS+(Bit16u)(reg_di+Fetchws()); }
EA_16_86_n(void)46 static PhysPt EA_16_86_n(void) { return BaseSS+(Bit16u)(reg_bp+Fetchws()); }
EA_16_87_n(void)47 static PhysPt EA_16_87_n(void) { return BaseDS+(Bit16u)(reg_bx+Fetchws()); }
48
49 static Bit32u SIBZero=0;
50 static Bit32u * SIBIndex[8]= { ®_eax,®_ecx,®_edx,®_ebx,&SIBZero,®_ebp,®_esi,®_edi };
51
Sib(Bitu mode)52 static inline PhysPt Sib(Bitu mode) {
53 Bit8u sib=Fetchb();
54 PhysPt base;
55 switch (sib&7) {
56 case 0: /* EAX Base */
57 base=BaseDS+reg_eax;break;
58 case 1: /* ECX Base */
59 base=BaseDS+reg_ecx;break;
60 case 2: /* EDX Base */
61 base=BaseDS+reg_edx;break;
62 case 3: /* EBX Base */
63 base=BaseDS+reg_ebx;break;
64 case 4: /* ESP Base */
65 base=BaseSS+reg_esp;break;
66 case 5: /* #1 Base */
67 if (!mode) {
68 base=BaseDS+Fetchd();break;
69 } else {
70 base=BaseSS+reg_ebp;break;
71 }
72 case 6: /* ESI Base */
73 base=BaseDS+reg_esi;break;
74 case 7: /* EDI Base */
75 base=BaseDS+reg_edi;break;
76 }
77 base+=*SIBIndex[(sib >> 3) &7] << (sib >> 6);
78 return base;
79 }
80
EA_32_00_n(void)81 static PhysPt EA_32_00_n(void) { return BaseDS+reg_eax; }
EA_32_01_n(void)82 static PhysPt EA_32_01_n(void) { return BaseDS+reg_ecx; }
EA_32_02_n(void)83 static PhysPt EA_32_02_n(void) { return BaseDS+reg_edx; }
EA_32_03_n(void)84 static PhysPt EA_32_03_n(void) { return BaseDS+reg_ebx; }
EA_32_04_n(void)85 static PhysPt EA_32_04_n(void) { return Sib(0);}
EA_32_05_n(void)86 static PhysPt EA_32_05_n(void) { return BaseDS+Fetchd(); }
EA_32_06_n(void)87 static PhysPt EA_32_06_n(void) { return BaseDS+reg_esi; }
EA_32_07_n(void)88 static PhysPt EA_32_07_n(void) { return BaseDS+reg_edi; }
89
EA_32_40_n(void)90 static PhysPt EA_32_40_n(void) { return BaseDS+reg_eax+Fetchbs(); }
EA_32_41_n(void)91 static PhysPt EA_32_41_n(void) { return BaseDS+reg_ecx+Fetchbs(); }
EA_32_42_n(void)92 static PhysPt EA_32_42_n(void) { return BaseDS+reg_edx+Fetchbs(); }
EA_32_43_n(void)93 static PhysPt EA_32_43_n(void) { return BaseDS+reg_ebx+Fetchbs(); }
EA_32_44_n(void)94 static PhysPt EA_32_44_n(void) { PhysPt temp=Sib(1);return temp+Fetchbs();}
95 //static PhysPt EA_32_44_n(void) { return Sib(1)+Fetchbs();}
EA_32_45_n(void)96 static PhysPt EA_32_45_n(void) { return BaseSS+reg_ebp+Fetchbs(); }
EA_32_46_n(void)97 static PhysPt EA_32_46_n(void) { return BaseDS+reg_esi+Fetchbs(); }
EA_32_47_n(void)98 static PhysPt EA_32_47_n(void) { return BaseDS+reg_edi+Fetchbs(); }
99
EA_32_80_n(void)100 static PhysPt EA_32_80_n(void) { return BaseDS+reg_eax+Fetchds(); }
EA_32_81_n(void)101 static PhysPt EA_32_81_n(void) { return BaseDS+reg_ecx+Fetchds(); }
EA_32_82_n(void)102 static PhysPt EA_32_82_n(void) { return BaseDS+reg_edx+Fetchds(); }
EA_32_83_n(void)103 static PhysPt EA_32_83_n(void) { return BaseDS+reg_ebx+Fetchds(); }
EA_32_84_n(void)104 static PhysPt EA_32_84_n(void) { PhysPt temp=Sib(2);return temp+Fetchds();}
105 //static PhysPt EA_32_84_n(void) { return Sib(2)+Fetchds();}
EA_32_85_n(void)106 static PhysPt EA_32_85_n(void) { return BaseSS+reg_ebp+Fetchds(); }
EA_32_86_n(void)107 static PhysPt EA_32_86_n(void) { return BaseDS+reg_esi+Fetchds(); }
EA_32_87_n(void)108 static PhysPt EA_32_87_n(void) { return BaseDS+reg_edi+Fetchds(); }
109
110 static GetEAHandler EATable[512]={
111 /* 00 */
112 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,
113 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,
114 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,
115 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,
116 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,
117 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,
118 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,
119 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,
120 /* 01 */
121 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,
122 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,
123 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,
124 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,
125 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,
126 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,
127 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,
128 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,
129 /* 10 */
130 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,
131 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,
132 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,
133 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,
134 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,
135 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,
136 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,
137 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,
138 /* 11 These are illegal so make em 0 */
139 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
140 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
141 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
142 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
143 /* 00 */
144 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,
145 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,
146 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,
147 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,
148 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,
149 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,
150 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,
151 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,
152 /* 01 */
153 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,
154 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,
155 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,
156 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,
157 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,
158 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,
159 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,
160 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,
161 /* 10 */
162 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,
163 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,
164 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,
165 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,
166 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,
167 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,
168 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,
169 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,
170 /* 11 These are illegal so make em 0 */
171 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
172 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
173 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
174 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
175 };
176
177 #define GetEADirect \
178 PhysPt eaa; \
179 if (TEST_PREFIX_ADDR) { \
180 eaa=BaseDS+Fetchd(); \
181 } else { \
182 eaa=BaseDS+Fetchw(); \
183 } \
184
185
186