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]= { &reg_eax,&reg_ecx,&reg_edx,&reg_ebx,&SIBZero,&reg_ebp,&reg_esi,&reg_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