1 /*
2  *  Copyright (C) 2002-2010  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
15  *  along with this program; if not, write to the Free Software
16  *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
17  */
18 
19 	CASE_D(0x01)												/* ADD Ed,Gd */
20 		RMEdGd(ADDD);break;
21 	CASE_D(0x03)												/* ADD Gd,Ed */
22 		RMGdEd(ADDD);break;
23 	CASE_D(0x05)												/* ADD EAX,Id */
24 		EAXId(ADDD);break;
25 	CASE_D(0x06)												/* PUSH ES */
26 		Push_32(SegValue(es));break;
27 	CASE_D(0x07)												/* POP ES */
28 		if (CPU_PopSeg(es,true)) RUNEXCEPTION();
29 		break;
30 	CASE_D(0x09)												/* OR Ed,Gd */
31 		RMEdGd(ORD);break;
32 	CASE_D(0x0b)												/* OR Gd,Ed */
33 		RMGdEd(ORD);break;
34 	CASE_D(0x0d)												/* OR EAX,Id */
35 		EAXId(ORD);break;
36 	CASE_D(0x0e)												/* PUSH CS */
37 		Push_32(SegValue(cs));break;
38 	CASE_D(0x11)												/* ADC Ed,Gd */
39 		RMEdGd(ADCD);break;
40 	CASE_D(0x13)												/* ADC Gd,Ed */
41 		RMGdEd(ADCD);break;
42 	CASE_D(0x15)												/* ADC EAX,Id */
43 		EAXId(ADCD);break;
44 	CASE_D(0x16)												/* PUSH SS */
45 		Push_32(SegValue(ss));break;
46 	CASE_D(0x17)												/* POP SS */
47 		if (CPU_PopSeg(ss,true)) RUNEXCEPTION();
48 		CPU_Cycles++;
49 		break;
50 	CASE_D(0x19)												/* SBB Ed,Gd */
51 		RMEdGd(SBBD);break;
52 	CASE_D(0x1b)												/* SBB Gd,Ed */
53 		RMGdEd(SBBD);break;
54 	CASE_D(0x1d)												/* SBB EAX,Id */
55 		EAXId(SBBD);break;
56 	CASE_D(0x1e)												/* PUSH DS */
57 		Push_32(SegValue(ds));break;
58 	CASE_D(0x1f)												/* POP DS */
59 		if (CPU_PopSeg(ds,true)) RUNEXCEPTION();
60 		break;
61 	CASE_D(0x21)												/* AND Ed,Gd */
62 		RMEdGd(ANDD);break;
63 	CASE_D(0x23)												/* AND Gd,Ed */
64 		RMGdEd(ANDD);break;
65 	CASE_D(0x25)												/* AND EAX,Id */
66 		EAXId(ANDD);break;
67 	CASE_D(0x29)												/* SUB Ed,Gd */
68 		RMEdGd(SUBD);break;
69 	CASE_D(0x2b)												/* SUB Gd,Ed */
70 		RMGdEd(SUBD);break;
71 	CASE_D(0x2d)												/* SUB EAX,Id */
72 		EAXId(SUBD);break;
73 	CASE_D(0x31)												/* XOR Ed,Gd */
74 		RMEdGd(XORD);break;
75 	CASE_D(0x33)												/* XOR Gd,Ed */
76 		RMGdEd(XORD);break;
77 	CASE_D(0x35)												/* XOR EAX,Id */
78 		EAXId(XORD);break;
79 	CASE_D(0x39)												/* CMP Ed,Gd */
80 		RMEdGd(CMPD);break;
81 	CASE_D(0x3b)												/* CMP Gd,Ed */
82 		RMGdEd(CMPD);break;
83 	CASE_D(0x3d)												/* CMP EAX,Id */
84 		EAXId(CMPD);break;
85 	CASE_D(0x40)												/* INC EAX */
86 		INCD(reg_eax,LoadRd,SaveRd);break;
87 	CASE_D(0x41)												/* INC ECX */
88 		INCD(reg_ecx,LoadRd,SaveRd);break;
89 	CASE_D(0x42)												/* INC EDX */
90 		INCD(reg_edx,LoadRd,SaveRd);break;
91 	CASE_D(0x43)												/* INC EBX */
92 		INCD(reg_ebx,LoadRd,SaveRd);break;
93 	CASE_D(0x44)												/* INC ESP */
94 		INCD(reg_esp,LoadRd,SaveRd);break;
95 	CASE_D(0x45)												/* INC EBP */
96 		INCD(reg_ebp,LoadRd,SaveRd);break;
97 	CASE_D(0x46)												/* INC ESI */
98 		INCD(reg_esi,LoadRd,SaveRd);break;
99 	CASE_D(0x47)												/* INC EDI */
100 		INCD(reg_edi,LoadRd,SaveRd);break;
101 	CASE_D(0x48)												/* DEC EAX */
102 		DECD(reg_eax,LoadRd,SaveRd);break;
103 	CASE_D(0x49)												/* DEC ECX */
104 		DECD(reg_ecx,LoadRd,SaveRd);break;
105 	CASE_D(0x4a)												/* DEC EDX */
106 		DECD(reg_edx,LoadRd,SaveRd);break;
107 	CASE_D(0x4b)												/* DEC EBX */
108 		DECD(reg_ebx,LoadRd,SaveRd);break;
109 	CASE_D(0x4c)												/* DEC ESP */
110 		DECD(reg_esp,LoadRd,SaveRd);break;
111 	CASE_D(0x4d)												/* DEC EBP */
112 		DECD(reg_ebp,LoadRd,SaveRd);break;
113 	CASE_D(0x4e)												/* DEC ESI */
114 		DECD(reg_esi,LoadRd,SaveRd);break;
115 	CASE_D(0x4f)												/* DEC EDI */
116 		DECD(reg_edi,LoadRd,SaveRd);break;
117 	CASE_D(0x50)												/* PUSH EAX */
118 		Push_32(reg_eax);break;
119 	CASE_D(0x51)												/* PUSH ECX */
120 		Push_32(reg_ecx);break;
121 	CASE_D(0x52)												/* PUSH EDX */
122 		Push_32(reg_edx);break;
123 	CASE_D(0x53)												/* PUSH EBX */
124 		Push_32(reg_ebx);break;
125 	CASE_D(0x54)												/* PUSH ESP */
126 		Push_32(reg_esp);break;
127 	CASE_D(0x55)												/* PUSH EBP */
128 		Push_32(reg_ebp);break;
129 	CASE_D(0x56)												/* PUSH ESI */
130 		Push_32(reg_esi);break;
131 	CASE_D(0x57)												/* PUSH EDI */
132 		Push_32(reg_edi);break;
133 	CASE_D(0x58)												/* POP EAX */
134 		reg_eax=Pop_32();break;
135 	CASE_D(0x59)												/* POP ECX */
136 		reg_ecx=Pop_32();break;
137 	CASE_D(0x5a)												/* POP EDX */
138 		reg_edx=Pop_32();break;
139 	CASE_D(0x5b)												/* POP EBX */
140 		reg_ebx=Pop_32();break;
141 	CASE_D(0x5c)												/* POP ESP */
142 		reg_esp=Pop_32();break;
143 	CASE_D(0x5d)												/* POP EBP */
144 		reg_ebp=Pop_32();break;
145 	CASE_D(0x5e)												/* POP ESI */
146 		reg_esi=Pop_32();break;
147 	CASE_D(0x5f)												/* POP EDI */
148 		reg_edi=Pop_32();break;
149 	CASE_D(0x60)												/* PUSHAD */
150 	{
151 		Bitu tmpesp = reg_esp;
152 		Push_32(reg_eax);Push_32(reg_ecx);Push_32(reg_edx);Push_32(reg_ebx);
153 		Push_32(tmpesp);Push_32(reg_ebp);Push_32(reg_esi);Push_32(reg_edi);
154 	}; break;
155 	CASE_D(0x61)												/* POPAD */
156 		reg_edi=Pop_32();reg_esi=Pop_32();reg_ebp=Pop_32();Pop_32();//Don't save ESP
157 		reg_ebx=Pop_32();reg_edx=Pop_32();reg_ecx=Pop_32();reg_eax=Pop_32();
158 		break;
159 	CASE_D(0x62)												/* BOUND Ed */
160 		{
161 			Bit32s bound_min, bound_max;
162 			GetRMrd;GetEAa;
163 			bound_min=LoadMd(eaa);
164 			bound_max=LoadMd(eaa+4);
165 			if ( (((Bit32s)*rmrd) < bound_min) || (((Bit32s)*rmrd) > bound_max) ) {
166 				EXCEPTION(5);
167 			}
168 		}
169 		break;
170 	CASE_D(0x63)												/* ARPL Ed,Rd */
171 		{
172 			if (((cpu.pmode) && (reg_flags & FLAG_VM)) || (!cpu.pmode)) goto illegal_opcode;
173 			GetRMrw;
174 			if (rm >= 0xc0 ) {
175 				GetEArd;Bitu new_sel=(Bit16u)*eard;
176 				CPU_ARPL(new_sel,*rmrw);
177 				*eard=(Bit32u)new_sel;
178 			} else {
179 				GetEAa;Bitu new_sel=LoadMw(eaa);
180 				CPU_ARPL(new_sel,*rmrw);
181 				SaveMd(eaa,(Bit32u)new_sel);
182 			}
183 		}
184 		break;
185 	CASE_D(0x68)												/* PUSH Id */
186 		Push_32(Fetchd());break;
187 	CASE_D(0x69)												/* IMUL Gd,Ed,Id */
188 		RMGdEdOp3(DIMULD,Fetchds());
189 		break;
190 	CASE_D(0x6a)												/* PUSH Ib */
191 		Push_32(Fetchbs());break;
192 	CASE_D(0x6b)												/* IMUL Gd,Ed,Ib */
193 		RMGdEdOp3(DIMULD,Fetchbs());
194 		break;
195 	CASE_D(0x6d)												/* INSD */
196 		if (CPU_IO_Exception(reg_dx,4)) RUNEXCEPTION();
197 		DoString(R_INSD);break;
198 	CASE_D(0x6f)												/* OUTSD */
199 		if (CPU_IO_Exception(reg_dx,4)) RUNEXCEPTION();
200 		DoString(R_OUTSD);break;
201 	CASE_D(0x70)												/* JO */
202 		JumpCond32_b(TFLG_O);break;
203 	CASE_D(0x71)												/* JNO */
204 		JumpCond32_b(TFLG_NO);break;
205 	CASE_D(0x72)												/* JB */
206 		JumpCond32_b(TFLG_B);break;
207 	CASE_D(0x73)												/* JNB */
208 		JumpCond32_b(TFLG_NB);break;
209 	CASE_D(0x74)												/* JZ */
210   		JumpCond32_b(TFLG_Z);break;
211 	CASE_D(0x75)												/* JNZ */
212 		JumpCond32_b(TFLG_NZ);break;
213 	CASE_D(0x76)												/* JBE */
214 		JumpCond32_b(TFLG_BE);break;
215 	CASE_D(0x77)												/* JNBE */
216 		JumpCond32_b(TFLG_NBE);break;
217 	CASE_D(0x78)												/* JS */
218 		JumpCond32_b(TFLG_S);break;
219 	CASE_D(0x79)												/* JNS */
220 		JumpCond32_b(TFLG_NS);break;
221 	CASE_D(0x7a)												/* JP */
222 		JumpCond32_b(TFLG_P);break;
223 	CASE_D(0x7b)												/* JNP */
224 		JumpCond32_b(TFLG_NP);break;
225 	CASE_D(0x7c)												/* JL */
226 		JumpCond32_b(TFLG_L);break;
227 	CASE_D(0x7d)												/* JNL */
228 		JumpCond32_b(TFLG_NL);break;
229 	CASE_D(0x7e)												/* JLE */
230 		JumpCond32_b(TFLG_LE);break;
231 	CASE_D(0x7f)												/* JNLE */
232 		JumpCond32_b(TFLG_NLE);break;
233 	CASE_D(0x81)												/* Grpl Ed,Id */
234 		{
235 			GetRM;Bitu which=(rm>>3)&7;
236 			if (rm >= 0xc0) {
237 				GetEArd;Bit32u id=Fetchd();
238 				switch (which) {
239 				case 0x00:ADDD(*eard,id,LoadRd,SaveRd);break;
240 				case 0x01: ORD(*eard,id,LoadRd,SaveRd);break;
241 				case 0x02:ADCD(*eard,id,LoadRd,SaveRd);break;
242 				case 0x03:SBBD(*eard,id,LoadRd,SaveRd);break;
243 				case 0x04:ANDD(*eard,id,LoadRd,SaveRd);break;
244 				case 0x05:SUBD(*eard,id,LoadRd,SaveRd);break;
245 				case 0x06:XORD(*eard,id,LoadRd,SaveRd);break;
246 				case 0x07:CMPD(*eard,id,LoadRd,SaveRd);break;
247 				}
248 			} else {
249 				GetEAa;Bit32u id=Fetchd();
250 				switch (which) {
251 				case 0x00:ADDD(eaa,id,LoadMd,SaveMd);break;
252 				case 0x01: ORD(eaa,id,LoadMd,SaveMd);break;
253 				case 0x02:ADCD(eaa,id,LoadMd,SaveMd);break;
254 				case 0x03:SBBD(eaa,id,LoadMd,SaveMd);break;
255 				case 0x04:ANDD(eaa,id,LoadMd,SaveMd);break;
256 				case 0x05:SUBD(eaa,id,LoadMd,SaveMd);break;
257 				case 0x06:XORD(eaa,id,LoadMd,SaveMd);break;
258 				case 0x07:CMPD(eaa,id,LoadMd,SaveMd);break;
259 				}
260 			}
261 		}
262 		break;
263 	CASE_D(0x83)												/* Grpl Ed,Ix */
264 		{
265 			GetRM;Bitu which=(rm>>3)&7;
266 			if (rm >= 0xc0) {
267 				GetEArd;Bit32u id=(Bit32s)Fetchbs();
268 				switch (which) {
269 				case 0x00:ADDD(*eard,id,LoadRd,SaveRd);break;
270 				case 0x01: ORD(*eard,id,LoadRd,SaveRd);break;
271 				case 0x02:ADCD(*eard,id,LoadRd,SaveRd);break;
272 				case 0x03:SBBD(*eard,id,LoadRd,SaveRd);break;
273 				case 0x04:ANDD(*eard,id,LoadRd,SaveRd);break;
274 				case 0x05:SUBD(*eard,id,LoadRd,SaveRd);break;
275 				case 0x06:XORD(*eard,id,LoadRd,SaveRd);break;
276 				case 0x07:CMPD(*eard,id,LoadRd,SaveRd);break;
277 				}
278 			} else {
279 				GetEAa;Bit32u id=(Bit32s)Fetchbs();
280 				switch (which) {
281 				case 0x00:ADDD(eaa,id,LoadMd,SaveMd);break;
282 				case 0x01: ORD(eaa,id,LoadMd,SaveMd);break;
283 				case 0x02:ADCD(eaa,id,LoadMd,SaveMd);break;
284 				case 0x03:SBBD(eaa,id,LoadMd,SaveMd);break;
285 				case 0x04:ANDD(eaa,id,LoadMd,SaveMd);break;
286 				case 0x05:SUBD(eaa,id,LoadMd,SaveMd);break;
287 				case 0x06:XORD(eaa,id,LoadMd,SaveMd);break;
288 				case 0x07:CMPD(eaa,id,LoadMd,SaveMd);break;
289 				}
290 			}
291 		}
292 		break;
293 	CASE_D(0x85)												/* TEST Ed,Gd */
294 		RMEdGd(TESTD);break;
295 	CASE_D(0x87)												/* XCHG Ed,Gd */
296 		{
297 			GetRMrd;Bit32u oldrmrd=*rmrd;
298 			if (rm >= 0xc0 ) {GetEArd;*rmrd=*eard;*eard=oldrmrd;}
299 			else {GetEAa;*rmrd=LoadMd(eaa);SaveMd(eaa,oldrmrd);}
300 			break;
301 		}
302 	CASE_D(0x89)												/* MOV Ed,Gd */
303 		{
304 			GetRMrd;
305 			if (rm >= 0xc0 ) {GetEArd;*eard=*rmrd;}
306 			else {GetEAa;SaveMd(eaa,*rmrd);}
307 			break;
308 		}
309 	CASE_D(0x8b)												/* MOV Gd,Ed */
310 		{
311 			GetRMrd;
312 			if (rm >= 0xc0 ) {GetEArd;*rmrd=*eard;}
313 			else {GetEAa;*rmrd=LoadMd(eaa);}
314 			break;
315 		}
316 	CASE_D(0x8c)												/* Mov Ew,Sw */
317 			{
318 				GetRM;Bit16u val;Bitu which=(rm>>3)&7;
319 				switch (which) {
320 				case 0x00:					/* MOV Ew,ES */
321 					val=SegValue(es);break;
322 				case 0x01:					/* MOV Ew,CS */
323 					val=SegValue(cs);break;
324 				case 0x02:					/* MOV Ew,SS */
325 					val=SegValue(ss);break;
326 				case 0x03:					/* MOV Ew,DS */
327 					val=SegValue(ds);break;
328 				case 0x04:					/* MOV Ew,FS */
329 					val=SegValue(fs);break;
330 				case 0x05:					/* MOV Ew,GS */
331 					val=SegValue(gs);break;
332 				default:
333 					LOG(LOG_CPU,LOG_ERROR)("CPU:8c:Illegal RM Byte");
334 					goto illegal_opcode;
335 				}
336 				if (rm >= 0xc0 ) {GetEArd;*eard=val;}
337 				else {GetEAa;SaveMw(eaa,val);}
338 				break;
339 			}
340 	CASE_D(0x8d)												/* LEA Gd */
341 		{
342 			//Little hack to always use segprefixed version
343 			GetRMrd;
344 			BaseDS=BaseSS=0;
345 			if (TEST_PREFIX_ADDR) {
346 				*rmrd=(Bit32u)(*EATable[256+rm])();
347 			} else {
348 				*rmrd=(Bit32u)(*EATable[rm])();
349 			}
350 			break;
351 		}
352 	CASE_D(0x8f)												/* POP Ed */
353 		{
354 			Bit32u val=Pop_32();
355 			GetRM;
356 			if (rm >= 0xc0 ) {GetEArd;*eard=val;}
357 			else {GetEAa;SaveMd(eaa,val);}
358 			break;
359 		}
360 	CASE_D(0x91)												/* XCHG ECX,EAX */
361 		{ Bit32u temp=reg_eax;reg_eax=reg_ecx;reg_ecx=temp;break;}
362 	CASE_D(0x92)												/* XCHG EDX,EAX */
363 		{ Bit32u temp=reg_eax;reg_eax=reg_edx;reg_edx=temp;break;}
364 		break;
365 	CASE_D(0x93)												/* XCHG EBX,EAX */
366 		{ Bit32u temp=reg_eax;reg_eax=reg_ebx;reg_ebx=temp;break;}
367 		break;
368 	CASE_D(0x94)												/* XCHG ESP,EAX */
369 		{ Bit32u temp=reg_eax;reg_eax=reg_esp;reg_esp=temp;break;}
370 		break;
371 	CASE_D(0x95)												/* XCHG EBP,EAX */
372 		{ Bit32u temp=reg_eax;reg_eax=reg_ebp;reg_ebp=temp;break;}
373 		break;
374 	CASE_D(0x96)												/* XCHG ESI,EAX */
375 		{ Bit32u temp=reg_eax;reg_eax=reg_esi;reg_esi=temp;break;}
376 		break;
377 	CASE_D(0x97)												/* XCHG EDI,EAX */
378 		{ Bit32u temp=reg_eax;reg_eax=reg_edi;reg_edi=temp;break;}
379 		break;
380 	CASE_D(0x98)												/* CWDE */
381 		reg_eax=(Bit16s)reg_ax;break;
382 	CASE_D(0x99)												/* CDQ */
383 		if (reg_eax & 0x80000000) reg_edx=0xffffffff;
384 		else reg_edx=0;
385 		break;
386 	CASE_D(0x9a)												/* CALL FAR Ad */
387 		{
388 			Bit32u newip=Fetchd();Bit16u newcs=Fetchw();
389 			FillFlags();
390 			CPU_CALL(true,newcs,newip,GETIP);
391 #if CPU_TRAP_CHECK
392 			if (GETFLAG(TF)) {
393 				cpudecoder=CPU_Core_Normal_Trap_Run;
394 				return CBRET_NONE;
395 			}
396 #endif
397 			continue;
398 		}
399 	CASE_D(0x9c)												/* PUSHFD */
400 		if (CPU_PUSHF(true)) RUNEXCEPTION();
401 		break;
402 	CASE_D(0x9d)												/* POPFD */
403 		if (CPU_POPF(true)) RUNEXCEPTION();
404 #if CPU_TRAP_CHECK
405 		if (GETFLAG(TF)) {
406 			cpudecoder=CPU_Core_Normal_Trap_Run;
407 			goto decode_end;
408 		}
409 #endif
410 #if CPU_PIC_CHECK
411 		if (GETFLAG(IF) && PIC_IRQCheck) goto decode_end;
412 #endif
413 		break;
414 	CASE_D(0xa1)												/* MOV EAX,Od */
415 		{
416 			GetEADirect;
417 			reg_eax=LoadMd(eaa);
418 		}
419 		break;
420 	CASE_D(0xa3)												/* MOV Od,EAX */
421 		{
422 			GetEADirect;
423 			SaveMd(eaa,reg_eax);
424 		}
425 		break;
426 	CASE_D(0xa5)												/* MOVSD */
427 		DoString(R_MOVSD);break;
428 	CASE_D(0xa7)												/* CMPSD */
429 		DoString(R_CMPSD);break;
430 	CASE_D(0xa9)												/* TEST EAX,Id */
431 		EAXId(TESTD);break;
432 	CASE_D(0xab)												/* STOSD */
433 		DoString(R_STOSD);break;
434 	CASE_D(0xad)												/* LODSD */
435 		DoString(R_LODSD);break;
436 	CASE_D(0xaf)												/* SCASD */
437 		DoString(R_SCASD);break;
438 	CASE_D(0xb8)												/* MOV EAX,Id */
439 		reg_eax=Fetchd();break;
440 	CASE_D(0xb9)												/* MOV ECX,Id */
441 		reg_ecx=Fetchd();break;
442 	CASE_D(0xba)												/* MOV EDX,Iw */
443 		reg_edx=Fetchd();break;
444 	CASE_D(0xbb)												/* MOV EBX,Id */
445 		reg_ebx=Fetchd();break;
446 	CASE_D(0xbc)												/* MOV ESP,Id */
447 		reg_esp=Fetchd();break;
448 	CASE_D(0xbd)												/* MOV EBP.Id */
449 		reg_ebp=Fetchd();break;
450 	CASE_D(0xbe)												/* MOV ESI,Id */
451 		reg_esi=Fetchd();break;
452 	CASE_D(0xbf)												/* MOV EDI,Id */
453 		reg_edi=Fetchd();break;
454 	CASE_D(0xc1)												/* GRP2 Ed,Ib */
455 		GRP2D(Fetchb());break;
456 	CASE_D(0xc2)												/* RETN Iw */
457 		reg_eip=Pop_32();
458 		reg_esp+=Fetchw();
459 		continue;
460 	CASE_D(0xc3)												/* RETN */
461 		reg_eip=Pop_32();
462 		continue;
463 	CASE_D(0xc4)												/* LES */
464 		{
465 			GetRMrd;
466 			if (rm >= 0xc0) goto illegal_opcode;
467 			GetEAa;
468 			if (CPU_SetSegGeneral(es,LoadMw(eaa+4))) RUNEXCEPTION();
469 			*rmrd=LoadMd(eaa);
470 			break;
471 		}
472 	CASE_D(0xc5)												/* LDS */
473 		{
474 			GetRMrd;
475 			if (rm >= 0xc0) goto illegal_opcode;
476 			GetEAa;
477 			if (CPU_SetSegGeneral(ds,LoadMw(eaa+4))) RUNEXCEPTION();
478 			*rmrd=LoadMd(eaa);
479 			break;
480 		}
481 	CASE_D(0xc7)												/* MOV Ed,Id */
482 		{
483 			GetRM;
484 			if (rm >= 0xc0) {GetEArd;*eard=Fetchd();}
485 			else {GetEAa;SaveMd(eaa,Fetchd());}
486 			break;
487 		}
488 	CASE_D(0xc8)												/* ENTER Iw,Ib */
489 		{
490 			Bitu bytes=Fetchw();
491 			Bitu level=Fetchb();
492 			CPU_ENTER(true,bytes,level);
493 		}
494 		break;
495 	CASE_D(0xc9)												/* LEAVE */
496 		reg_esp&=cpu.stack.notmask;
497 		reg_esp|=(reg_ebp&cpu.stack.mask);
498 		reg_ebp=Pop_32();
499 		break;
500 	CASE_D(0xca)												/* RETF Iw */
501 		{
502 			Bitu words=Fetchw();
503 			FillFlags();
504 			CPU_RET(true,words,GETIP);
505 			continue;
506 		}
507 	CASE_D(0xcb)												/* RETF */
508 		{
509 			FillFlags();
510             CPU_RET(true,0,GETIP);
511 			continue;
512 		}
513 	CASE_D(0xcf)												/* IRET */
514 		{
515 			CPU_IRET(true,GETIP);
516 #if CPU_TRAP_CHECK
517 			if (GETFLAG(TF)) {
518 				cpudecoder=CPU_Core_Normal_Trap_Run;
519 				return CBRET_NONE;
520 			}
521 #endif
522 #if CPU_PIC_CHECK
523 			if (GETFLAG(IF) && PIC_IRQCheck) return CBRET_NONE;
524 #endif
525 			continue;
526 		}
527 	CASE_D(0xd1)												/* GRP2 Ed,1 */
528 		GRP2D(1);break;
529 	CASE_D(0xd3)												/* GRP2 Ed,CL */
530 		GRP2D(reg_cl);break;
531 	CASE_D(0xe0)												/* LOOPNZ */
532 		if (TEST_PREFIX_ADDR) {
533 			JumpCond32_b(--reg_ecx && !get_ZF());
534 		} else {
535 			JumpCond32_b(--reg_cx && !get_ZF());
536 		}
537 		break;
538 	CASE_D(0xe1)												/* LOOPZ */
539 		if (TEST_PREFIX_ADDR) {
540 			JumpCond32_b(--reg_ecx && get_ZF());
541 		} else {
542 			JumpCond32_b(--reg_cx && get_ZF());
543 		}
544 		break;
545 	CASE_D(0xe2)												/* LOOP */
546 		if (TEST_PREFIX_ADDR) {
547 			JumpCond32_b(--reg_ecx);
548 		} else {
549 			JumpCond32_b(--reg_cx);
550 		}
551 		break;
552 	CASE_D(0xe3)												/* JCXZ */
553 		JumpCond32_b(!(reg_ecx & AddrMaskTable[core.prefixes& PREFIX_ADDR]));
554 		break;
555 	CASE_D(0xe5)												/* IN EAX,Ib */
556 		{
557 			Bitu port=Fetchb();
558 			if (CPU_IO_Exception(port,4)) RUNEXCEPTION();
559 			reg_eax=IO_ReadD(port);
560 			break;
561 		}
562 	CASE_D(0xe7)												/* OUT Ib,EAX */
563 		{
564 			Bitu port=Fetchb();
565 			if (CPU_IO_Exception(port,4)) RUNEXCEPTION();
566 			IO_WriteD(port,reg_eax);
567 			break;
568 		}
569 	CASE_D(0xe8)												/* CALL Jd */
570 		{
571 			Bit32s addip=Fetchds();
572 			SAVEIP;
573 			Push_32(reg_eip);
574 			reg_eip+=addip;
575 			continue;
576 		}
577 	CASE_D(0xe9)												/* JMP Jd */
578 		{
579 			Bit32s addip=Fetchds();
580 			SAVEIP;
581 			reg_eip+=addip;
582 			continue;
583 		}
584 	CASE_D(0xea)												/* JMP Ad */
585 		{
586 			Bit32u newip=Fetchd();
587 			Bit16u newcs=Fetchw();
588 			FillFlags();
589 			CPU_JMP(true,newcs,newip,GETIP);
590 #if CPU_TRAP_CHECK
591 			if (GETFLAG(TF)) {
592 				cpudecoder=CPU_Core_Normal_Trap_Run;
593 				return CBRET_NONE;
594 			}
595 #endif
596 			continue;
597 		}
598 	CASE_D(0xeb)												/* JMP Jb */
599 		{
600 			Bit32s addip=Fetchbs();
601 			SAVEIP;
602 			reg_eip+=addip;
603 			continue;
604 		}
605 	CASE_D(0xed)												/* IN EAX,DX */
606 		reg_eax=IO_ReadD(reg_dx);
607 		break;
608 	CASE_D(0xef)												/* OUT DX,EAX */
609 		IO_WriteD(reg_dx,reg_eax);
610 		break;
611 	CASE_D(0xf7)												/* GRP3 Ed(,Id) */
612 		{
613 			GetRM;Bitu which=(rm>>3)&7;
614 			switch (which) {
615 			case 0x00:											/* TEST Ed,Id */
616 			case 0x01:											/* TEST Ed,Id Undocumented*/
617 				{
618 					if (rm >= 0xc0 ) {GetEArd;TESTD(*eard,Fetchd(),LoadRd,SaveRd);}
619 					else {GetEAa;TESTD(eaa,Fetchd(),LoadMd,SaveMd);}
620 					break;
621 				}
622 			case 0x02:											/* NOT Ed */
623 				{
624 					if (rm >= 0xc0 ) {GetEArd;*eard=~*eard;}
625 					else {GetEAa;SaveMd(eaa,~LoadMd(eaa));}
626 					break;
627 				}
628 			case 0x03:											/* NEG Ed */
629 				{
630 					lflags.type=t_NEGd;
631 					if (rm >= 0xc0 ) {
632 							GetEArd;lf_var1d=*eard;lf_resd=0-lf_var1d;
633 						*eard=lf_resd;
634 					} else {
635 						GetEAa;lf_var1d=LoadMd(eaa);lf_resd=0-lf_var1d;
636 							SaveMd(eaa,lf_resd);
637 					}
638 					break;
639 				}
640 			case 0x04:											/* MUL EAX,Ed */
641 				RMEd(MULD);
642 				break;
643 			case 0x05:											/* IMUL EAX,Ed */
644 				RMEd(IMULD);
645 				break;
646 			case 0x06:											/* DIV Ed */
647 				RMEd(DIVD);
648 				break;
649 			case 0x07:											/* IDIV Ed */
650 				RMEd(IDIVD);
651 				break;
652 			}
653 			break;
654 		}
655 	CASE_D(0xff)												/* GRP 5 Ed */
656 		{
657 			GetRM;Bitu which=(rm>>3)&7;
658 			switch (which) {
659 			case 0x00:											/* INC Ed */
660 				RMEd(INCD);
661 				break;
662 			case 0x01:											/* DEC Ed */
663 				RMEd(DECD);
664 				break;
665 			case 0x02:											/* CALL NEAR Ed */
666 				if (rm >= 0xc0 ) {GetEArd;reg_eip=*eard;}
667 				else {GetEAa;reg_eip=LoadMd(eaa);}
668 				Push_32(GETIP);
669 				continue;
670 			case 0x03:											/* CALL FAR Ed */
671 				{
672 					if (rm >= 0xc0) goto illegal_opcode;
673 					GetEAa;
674 					Bit32u newip=LoadMd(eaa);
675 					Bit16u newcs=LoadMw(eaa+4);
676 					FillFlags();
677 					CPU_CALL(true,newcs,newip,GETIP);
678 #if CPU_TRAP_CHECK
679 					if (GETFLAG(TF)) {
680 						cpudecoder=CPU_Core_Normal_Trap_Run;
681 						return CBRET_NONE;
682 					}
683 #endif
684 					continue;
685 				}
686 			case 0x04:											/* JMP NEAR Ed */
687 				if (rm >= 0xc0 ) {GetEArd;reg_eip=*eard;}
688 				else {GetEAa;reg_eip=LoadMd(eaa);}
689 				continue;
690 			case 0x05:											/* JMP FAR Ed */
691 				{
692 					if (rm >= 0xc0) goto illegal_opcode;
693 					GetEAa;
694 					Bit32u newip=LoadMd(eaa);
695 					Bit16u newcs=LoadMw(eaa+4);
696 					FillFlags();
697 					CPU_JMP(true,newcs,newip,GETIP);
698 #if CPU_TRAP_CHECK
699 					if (GETFLAG(TF)) {
700 						cpudecoder=CPU_Core_Normal_Trap_Run;
701 						return CBRET_NONE;
702 					}
703 #endif
704 					continue;
705 				}
706 				break;
707 			case 0x06:											/* Push Ed */
708 				if (rm >= 0xc0 ) {GetEArd;Push_32(*eard);}
709 				else {GetEAa;Push_32(LoadMd(eaa));}
710 				break;
711 			default:
712 				LOG(LOG_CPU,LOG_ERROR)("CPU:66:GRP5:Illegal call %2X",which);
713 				goto illegal_opcode;
714 			}
715 			break;
716 		}
717 
718 
719