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_B(0x00)												/* ADD Eb,Gb */
20 		RMEbGb(ADDB);break;
21 	CASE_W(0x01)												/* ADD Ew,Gw */
22 		RMEwGw(ADDW);break;
23 	CASE_B(0x02)												/* ADD Gb,Eb */
24 		RMGbEb(ADDB);break;
25 	CASE_W(0x03)												/* ADD Gw,Ew */
26 		RMGwEw(ADDW);break;
27 	CASE_B(0x04)												/* ADD AL,Ib */
28 		ALIb(ADDB);break;
29 	CASE_W(0x05)												/* ADD AX,Iw */
30 		AXIw(ADDW);break;
31 	CASE_W(0x06)												/* PUSH ES */
32 		Push_16(SegValue(es));break;
33 	CASE_W(0x07)												/* POP ES */
34 		if (CPU_PopSeg(es,false)) RUNEXCEPTION();
35 		break;
36 	CASE_B(0x08)												/* OR Eb,Gb */
37 		RMEbGb(ORB);break;
38 	CASE_W(0x09)												/* OR Ew,Gw */
39 		RMEwGw(ORW);break;
40 	CASE_B(0x0a)												/* OR Gb,Eb */
41 		RMGbEb(ORB);break;
42 	CASE_W(0x0b)												/* OR Gw,Ew */
43 		RMGwEw(ORW);break;
44 	CASE_B(0x0c)												/* OR AL,Ib */
45 		ALIb(ORB);break;
46 	CASE_W(0x0d)												/* OR AX,Iw */
47 		AXIw(ORW);break;
48 	CASE_W(0x0e)												/* PUSH CS */
49 		Push_16(SegValue(cs));break;
50 	CASE_B(0x0f)												/* 2 byte opcodes*/
51 		core.opcode_index|=OPCODE_0F;
52 		goto restart_opcode;
53 		break;
54 	CASE_B(0x10)												/* ADC Eb,Gb */
55 		RMEbGb(ADCB);break;
56 	CASE_W(0x11)												/* ADC Ew,Gw */
57 		RMEwGw(ADCW);break;
58 	CASE_B(0x12)												/* ADC Gb,Eb */
59 		RMGbEb(ADCB);break;
60 	CASE_W(0x13)												/* ADC Gw,Ew */
61 		RMGwEw(ADCW);break;
62 	CASE_B(0x14)												/* ADC AL,Ib */
63 		ALIb(ADCB);break;
64 	CASE_W(0x15)												/* ADC AX,Iw */
65 		AXIw(ADCW);break;
66 	CASE_W(0x16)												/* PUSH SS */
67 		Push_16(SegValue(ss));break;
68 	CASE_W(0x17)												/* POP SS */
69 		if (CPU_PopSeg(ss,false)) RUNEXCEPTION();
70 		CPU_Cycles++; //Always do another instruction
71 		break;
72 	CASE_B(0x18)												/* SBB Eb,Gb */
73 		RMEbGb(SBBB);break;
74 	CASE_W(0x19)												/* SBB Ew,Gw */
75 		RMEwGw(SBBW);break;
76 	CASE_B(0x1a)												/* SBB Gb,Eb */
77 		RMGbEb(SBBB);break;
78 	CASE_W(0x1b)												/* SBB Gw,Ew */
79 		RMGwEw(SBBW);break;
80 	CASE_B(0x1c)												/* SBB AL,Ib */
81 		ALIb(SBBB);break;
82 	CASE_W(0x1d)												/* SBB AX,Iw */
83 		AXIw(SBBW);break;
84 	CASE_W(0x1e)												/* PUSH DS */
85 		Push_16(SegValue(ds));break;
86 	CASE_W(0x1f)												/* POP DS */
87 		if (CPU_PopSeg(ds,false)) RUNEXCEPTION();
88 		break;
89 	CASE_B(0x20)												/* AND Eb,Gb */
90 		RMEbGb(ANDB);break;
91 	CASE_W(0x21)												/* AND Ew,Gw */
92 		RMEwGw(ANDW);break;
93 	CASE_B(0x22)												/* AND Gb,Eb */
94 		RMGbEb(ANDB);break;
95 	CASE_W(0x23)												/* AND Gw,Ew */
96 		RMGwEw(ANDW);break;
97 	CASE_B(0x24)												/* AND AL,Ib */
98 		ALIb(ANDB);break;
99 	CASE_W(0x25)												/* AND AX,Iw */
100 		AXIw(ANDW);break;
101 	CASE_B(0x26)												/* SEG ES: */
102 		DO_PREFIX_SEG(es);break;
103 	CASE_B(0x27)												/* DAA */
104 		DAA();break;
105 	CASE_B(0x28)												/* SUB Eb,Gb */
106 		RMEbGb(SUBB);break;
107 	CASE_W(0x29)												/* SUB Ew,Gw */
108 		RMEwGw(SUBW);break;
109 	CASE_B(0x2a)												/* SUB Gb,Eb */
110 		RMGbEb(SUBB);break;
111 	CASE_W(0x2b)												/* SUB Gw,Ew */
112 		RMGwEw(SUBW);break;
113 	CASE_B(0x2c)												/* SUB AL,Ib */
114 		ALIb(SUBB);break;
115 	CASE_W(0x2d)												/* SUB AX,Iw */
116 		AXIw(SUBW);break;
117 	CASE_B(0x2e)												/* SEG CS: */
118 		DO_PREFIX_SEG(cs);break;
119 	CASE_B(0x2f)												/* DAS */
120 		DAS();break;
121 	CASE_B(0x30)												/* XOR Eb,Gb */
122 		RMEbGb(XORB);break;
123 	CASE_W(0x31)												/* XOR Ew,Gw */
124 		RMEwGw(XORW);break;
125 	CASE_B(0x32)												/* XOR Gb,Eb */
126 		RMGbEb(XORB);break;
127 	CASE_W(0x33)												/* XOR Gw,Ew */
128 		RMGwEw(XORW);break;
129 	CASE_B(0x34)												/* XOR AL,Ib */
130 		ALIb(XORB);break;
131 	CASE_W(0x35)												/* XOR AX,Iw */
132 		AXIw(XORW);break;
133 	CASE_B(0x36)												/* SEG SS: */
134 		DO_PREFIX_SEG(ss);break;
135 	CASE_B(0x37)												/* AAA */
136 		AAA();break;
137 	CASE_B(0x38)												/* CMP Eb,Gb */
138 		RMEbGb(CMPB);break;
139 	CASE_W(0x39)												/* CMP Ew,Gw */
140 		RMEwGw(CMPW);break;
141 	CASE_B(0x3a)												/* CMP Gb,Eb */
142 		RMGbEb(CMPB);break;
143 	CASE_W(0x3b)												/* CMP Gw,Ew */
144 		RMGwEw(CMPW);break;
145 	CASE_B(0x3c)												/* CMP AL,Ib */
146 		ALIb(CMPB);break;
147 	CASE_W(0x3d)												/* CMP AX,Iw */
148 		AXIw(CMPW);break;
149 	CASE_B(0x3e)												/* SEG DS: */
150 		DO_PREFIX_SEG(ds);break;
151 	CASE_B(0x3f)												/* AAS */
152 		AAS();break;
153 	CASE_W(0x40)												/* INC AX */
154 		INCW(reg_ax,LoadRw,SaveRw);break;
155 	CASE_W(0x41)												/* INC CX */
156 		INCW(reg_cx,LoadRw,SaveRw);break;
157 	CASE_W(0x42)												/* INC DX */
158 		INCW(reg_dx,LoadRw,SaveRw);break;
159 	CASE_W(0x43)												/* INC BX */
160 		INCW(reg_bx,LoadRw,SaveRw);break;
161 	CASE_W(0x44)												/* INC SP */
162 		INCW(reg_sp,LoadRw,SaveRw);break;
163 	CASE_W(0x45)												/* INC BP */
164 		INCW(reg_bp,LoadRw,SaveRw);break;
165 	CASE_W(0x46)												/* INC SI */
166 		INCW(reg_si,LoadRw,SaveRw);break;
167 	CASE_W(0x47)												/* INC DI */
168 		INCW(reg_di,LoadRw,SaveRw);break;
169 	CASE_W(0x48)												/* DEC AX */
170 		DECW(reg_ax,LoadRw,SaveRw);break;
171 	CASE_W(0x49)												/* DEC CX */
172   		DECW(reg_cx,LoadRw,SaveRw);break;
173 	CASE_W(0x4a)												/* DEC DX */
174 		DECW(reg_dx,LoadRw,SaveRw);break;
175 	CASE_W(0x4b)												/* DEC BX */
176 		DECW(reg_bx,LoadRw,SaveRw);break;
177 	CASE_W(0x4c)												/* DEC SP */
178 		DECW(reg_sp,LoadRw,SaveRw);break;
179 	CASE_W(0x4d)												/* DEC BP */
180 		DECW(reg_bp,LoadRw,SaveRw);break;
181 	CASE_W(0x4e)												/* DEC SI */
182 		DECW(reg_si,LoadRw,SaveRw);break;
183 	CASE_W(0x4f)												/* DEC DI */
184 		DECW(reg_di,LoadRw,SaveRw);break;
185 	CASE_W(0x50)												/* PUSH AX */
186 		Push_16(reg_ax);break;
187 	CASE_W(0x51)												/* PUSH CX */
188 		Push_16(reg_cx);break;
189 	CASE_W(0x52)												/* PUSH DX */
190 		Push_16(reg_dx);break;
191 	CASE_W(0x53)												/* PUSH BX */
192 		Push_16(reg_bx);break;
193 	CASE_W(0x54)												/* PUSH SP */
194 		Push_16(reg_sp);break;
195 	CASE_W(0x55)												/* PUSH BP */
196 		Push_16(reg_bp);break;
197 	CASE_W(0x56)												/* PUSH SI */
198 		Push_16(reg_si);break;
199 	CASE_W(0x57)												/* PUSH DI */
200 		Push_16(reg_di);break;
201 	CASE_W(0x58)												/* POP AX */
202 		reg_ax=Pop_16();break;
203 	CASE_W(0x59)												/* POP CX */
204 		reg_cx=Pop_16();break;
205 	CASE_W(0x5a)												/* POP DX */
206 		reg_dx=Pop_16();break;
207 	CASE_W(0x5b)												/* POP BX */
208 		reg_bx=Pop_16();break;
209 	CASE_W(0x5c)												/* POP SP */
210 		reg_sp=Pop_16();break;
211 	CASE_W(0x5d)												/* POP BP */
212 		reg_bp=Pop_16();break;
213 	CASE_W(0x5e)												/* POP SI */
214 		reg_si=Pop_16();break;
215 	CASE_W(0x5f)												/* POP DI */
216 		reg_di=Pop_16();break;
217 	CASE_W(0x60)												/* PUSHA */
218 		{
219 			Bit16u old_sp=reg_sp;
220 			Push_16(reg_ax);Push_16(reg_cx);Push_16(reg_dx);Push_16(reg_bx);
221 			Push_16(old_sp);Push_16(reg_bp);Push_16(reg_si);Push_16(reg_di);
222 		}
223 		break;
224 	CASE_W(0x61)												/* POPA */
225 		reg_di=Pop_16();reg_si=Pop_16();reg_bp=Pop_16();Pop_16();//Don't save SP
226 		reg_bx=Pop_16();reg_dx=Pop_16();reg_cx=Pop_16();reg_ax=Pop_16();
227 		break;
228 	CASE_W(0x62)												/* BOUND */
229 		{
230 			Bit16s bound_min, bound_max;
231 			GetRMrw;GetEAa;
232 			bound_min=LoadMw(eaa);
233 			bound_max=LoadMw(eaa+2);
234 			if ( (((Bit16s)*rmrw) < bound_min) || (((Bit16s)*rmrw) > bound_max) ) {
235 				EXCEPTION(5);
236 			}
237 		}
238 		break;
239 	CASE_W(0x63)												/* ARPL Ew,Rw */
240 		{
241 			if ((reg_flags & FLAG_VM) || (!cpu.pmode)) goto illegal_opcode;
242 			GetRMrw;
243 			if (rm >= 0xc0 ) {
244 				GetEArw;Bitu new_sel=*earw;
245 				CPU_ARPL(new_sel,*rmrw);
246 				*earw=(Bit16u)new_sel;
247 			} else {
248 				GetEAa;Bitu new_sel=LoadMw(eaa);
249 				CPU_ARPL(new_sel,*rmrw);
250 				SaveMw(eaa,(Bit16u)new_sel);
251 			}
252 		}
253 		break;
254 	CASE_B(0x64)												/* SEG FS: */
255 		DO_PREFIX_SEG(fs);break;
256 	CASE_B(0x65)												/* SEG GS: */
257 		DO_PREFIX_SEG(gs);break;
258 	CASE_B(0x66)												/* Operand Size Prefix */
259 		core.opcode_index=(cpu.code.big^0x1)*0x200;
260 		goto restart_opcode;
261 	CASE_B(0x67)												/* Address Size Prefix */
262 		DO_PREFIX_ADDR();
263 	CASE_W(0x68)												/* PUSH Iw */
264 		Push_16(Fetchw());break;
265 	CASE_W(0x69)												/* IMUL Gw,Ew,Iw */
266 		RMGwEwOp3(DIMULW,Fetchws());
267 		break;
268 	CASE_W(0x6a)												/* PUSH Ib */
269 		Push_16(Fetchbs());
270 		break;
271 	CASE_W(0x6b)												/* IMUL Gw,Ew,Ib */
272 		RMGwEwOp3(DIMULW,Fetchbs());
273 		break;
274 	CASE_B(0x6c)												/* INSB */
275 		if (CPU_IO_Exception(reg_dx,1)) RUNEXCEPTION();
276 		DoString(R_INSB);break;
277 	CASE_W(0x6d)												/* INSW */
278 		if (CPU_IO_Exception(reg_dx,2)) RUNEXCEPTION();
279 		DoString(R_INSW);break;
280 	CASE_B(0x6e)												/* OUTSB */
281 		if (CPU_IO_Exception(reg_dx,1)) RUNEXCEPTION();
282 		DoString(R_OUTSB);break;
283 	CASE_W(0x6f)												/* OUTSW */
284 		if (CPU_IO_Exception(reg_dx,2)) RUNEXCEPTION();
285 		DoString(R_OUTSW);break;
286 	CASE_W(0x70)												/* JO */
287 		JumpCond16_b(TFLG_O);break;
288 	CASE_W(0x71)												/* JNO */
289 		JumpCond16_b(TFLG_NO);break;
290 	CASE_W(0x72)												/* JB */
291 		JumpCond16_b(TFLG_B);break;
292 	CASE_W(0x73)												/* JNB */
293 		JumpCond16_b(TFLG_NB);break;
294 	CASE_W(0x74)												/* JZ */
295   		JumpCond16_b(TFLG_Z);break;
296 	CASE_W(0x75)												/* JNZ */
297 		JumpCond16_b(TFLG_NZ);break;
298 	CASE_W(0x76)												/* JBE */
299 		JumpCond16_b(TFLG_BE);break;
300 	CASE_W(0x77)												/* JNBE */
301 		JumpCond16_b(TFLG_NBE);break;
302 	CASE_W(0x78)												/* JS */
303 		JumpCond16_b(TFLG_S);break;
304 	CASE_W(0x79)												/* JNS */
305 		JumpCond16_b(TFLG_NS);break;
306 	CASE_W(0x7a)												/* JP */
307 		JumpCond16_b(TFLG_P);break;
308 	CASE_W(0x7b)												/* JNP */
309 		JumpCond16_b(TFLG_NP);break;
310 	CASE_W(0x7c)												/* JL */
311 		JumpCond16_b(TFLG_L);break;
312 	CASE_W(0x7d)												/* JNL */
313 		JumpCond16_b(TFLG_NL);break;
314 	CASE_W(0x7e)												/* JLE */
315 		JumpCond16_b(TFLG_LE);break;
316 	CASE_W(0x7f)												/* JNLE */
317 		JumpCond16_b(TFLG_NLE);break;
318 	CASE_B(0x80)												/* Grpl Eb,Ib */
319 	CASE_B(0x82)												/* Grpl Eb,Ib Mirror instruction*/
320 		{
321 			GetRM;Bitu which=(rm>>3)&7;
322 			if (rm>= 0xc0) {
323 				GetEArb;Bit8u ib=Fetchb();
324 				switch (which) {
325 				case 0x00:ADDB(*earb,ib,LoadRb,SaveRb);break;
326 				case 0x01: ORB(*earb,ib,LoadRb,SaveRb);break;
327 				case 0x02:ADCB(*earb,ib,LoadRb,SaveRb);break;
328 				case 0x03:SBBB(*earb,ib,LoadRb,SaveRb);break;
329 				case 0x04:ANDB(*earb,ib,LoadRb,SaveRb);break;
330 				case 0x05:SUBB(*earb,ib,LoadRb,SaveRb);break;
331 				case 0x06:XORB(*earb,ib,LoadRb,SaveRb);break;
332 				case 0x07:CMPB(*earb,ib,LoadRb,SaveRb);break;
333 				}
334 			} else {
335 				GetEAa;Bit8u ib=Fetchb();
336 				switch (which) {
337 				case 0x00:ADDB(eaa,ib,LoadMb,SaveMb);break;
338 				case 0x01: ORB(eaa,ib,LoadMb,SaveMb);break;
339 				case 0x02:ADCB(eaa,ib,LoadMb,SaveMb);break;
340 				case 0x03:SBBB(eaa,ib,LoadMb,SaveMb);break;
341 				case 0x04:ANDB(eaa,ib,LoadMb,SaveMb);break;
342 				case 0x05:SUBB(eaa,ib,LoadMb,SaveMb);break;
343 				case 0x06:XORB(eaa,ib,LoadMb,SaveMb);break;
344 				case 0x07:CMPB(eaa,ib,LoadMb,SaveMb);break;
345 				}
346 			}
347 			break;
348 		}
349 	CASE_W(0x81)												/* Grpl Ew,Iw */
350 		{
351 			GetRM;Bitu which=(rm>>3)&7;
352 			if (rm>= 0xc0) {
353 				GetEArw;Bit16u iw=Fetchw();
354 				switch (which) {
355 				case 0x00:ADDW(*earw,iw,LoadRw,SaveRw);break;
356 				case 0x01: ORW(*earw,iw,LoadRw,SaveRw);break;
357 				case 0x02:ADCW(*earw,iw,LoadRw,SaveRw);break;
358 				case 0x03:SBBW(*earw,iw,LoadRw,SaveRw);break;
359 				case 0x04:ANDW(*earw,iw,LoadRw,SaveRw);break;
360 				case 0x05:SUBW(*earw,iw,LoadRw,SaveRw);break;
361 				case 0x06:XORW(*earw,iw,LoadRw,SaveRw);break;
362 				case 0x07:CMPW(*earw,iw,LoadRw,SaveRw);break;
363 				}
364 			} else {
365 				GetEAa;Bit16u iw=Fetchw();
366 				switch (which) {
367 				case 0x00:ADDW(eaa,iw,LoadMw,SaveMw);break;
368 				case 0x01: ORW(eaa,iw,LoadMw,SaveMw);break;
369 				case 0x02:ADCW(eaa,iw,LoadMw,SaveMw);break;
370 				case 0x03:SBBW(eaa,iw,LoadMw,SaveMw);break;
371 				case 0x04:ANDW(eaa,iw,LoadMw,SaveMw);break;
372 				case 0x05:SUBW(eaa,iw,LoadMw,SaveMw);break;
373 				case 0x06:XORW(eaa,iw,LoadMw,SaveMw);break;
374 				case 0x07:CMPW(eaa,iw,LoadMw,SaveMw);break;
375 				}
376 			}
377 			break;
378 		}
379 	CASE_W(0x83)												/* Grpl Ew,Ix */
380 		{
381 			GetRM;Bitu which=(rm>>3)&7;
382 			if (rm>= 0xc0) {
383 				GetEArw;Bit16u iw=(Bit16s)Fetchbs();
384 				switch (which) {
385 				case 0x00:ADDW(*earw,iw,LoadRw,SaveRw);break;
386 				case 0x01: ORW(*earw,iw,LoadRw,SaveRw);break;
387 				case 0x02:ADCW(*earw,iw,LoadRw,SaveRw);break;
388 				case 0x03:SBBW(*earw,iw,LoadRw,SaveRw);break;
389 				case 0x04:ANDW(*earw,iw,LoadRw,SaveRw);break;
390 				case 0x05:SUBW(*earw,iw,LoadRw,SaveRw);break;
391 				case 0x06:XORW(*earw,iw,LoadRw,SaveRw);break;
392 				case 0x07:CMPW(*earw,iw,LoadRw,SaveRw);break;
393 				}
394 			} else {
395 				GetEAa;Bit16u iw=(Bit16s)Fetchbs();
396 				switch (which) {
397 				case 0x00:ADDW(eaa,iw,LoadMw,SaveMw);break;
398 				case 0x01: ORW(eaa,iw,LoadMw,SaveMw);break;
399 				case 0x02:ADCW(eaa,iw,LoadMw,SaveMw);break;
400 				case 0x03:SBBW(eaa,iw,LoadMw,SaveMw);break;
401 				case 0x04:ANDW(eaa,iw,LoadMw,SaveMw);break;
402 				case 0x05:SUBW(eaa,iw,LoadMw,SaveMw);break;
403 				case 0x06:XORW(eaa,iw,LoadMw,SaveMw);break;
404 				case 0x07:CMPW(eaa,iw,LoadMw,SaveMw);break;
405 				}
406 			}
407 			break;
408 		}
409 	CASE_B(0x84)												/* TEST Eb,Gb */
410 		RMEbGb(TESTB);
411 		break;
412 	CASE_W(0x85)												/* TEST Ew,Gw */
413 		RMEwGw(TESTW);
414 		break;
415 	CASE_B(0x86)												/* XCHG Eb,Gb */
416 		{
417 			GetRMrb;Bit8u oldrmrb=*rmrb;
418 			if (rm >= 0xc0 ) {GetEArb;*rmrb=*earb;*earb=oldrmrb;}
419 			else {GetEAa;*rmrb=LoadMb(eaa);SaveMb(eaa,oldrmrb);}
420 			break;
421 		}
422 	CASE_W(0x87)												/* XCHG Ew,Gw */
423 		{
424 			GetRMrw;Bit16u oldrmrw=*rmrw;
425 			if (rm >= 0xc0 ) {GetEArw;*rmrw=*earw;*earw=oldrmrw;}
426 			else {GetEAa;*rmrw=LoadMw(eaa);SaveMw(eaa,oldrmrw);}
427 			break;
428 		}
429 	CASE_B(0x88)												/* MOV Eb,Gb */
430 		{
431 			GetRMrb;
432 			if (rm >= 0xc0 ) {GetEArb;*earb=*rmrb;}
433 			else {
434 				if (cpu.pmode) {
435 					if (GCC_UNLIKELY((rm==0x05) && (!cpu.code.big))) {
436 						Descriptor desc;
437 						cpu.gdt.GetDescriptor(SegValue(core.base_val_ds),desc);
438 						if ((desc.Type()==DESC_CODE_R_NC_A) || (desc.Type()==DESC_CODE_R_NC_NA)) {
439 							CPU_Exception(EXCEPTION_GP,SegValue(core.base_val_ds) & 0xfffc);
440 							continue;
441 						}
442 					}
443 				}
444 				GetEAa;SaveMb(eaa,*rmrb);
445 			}
446 			break;
447 		}
448 	CASE_W(0x89)												/* MOV Ew,Gw */
449 		{
450 			GetRMrw;
451 			if (rm >= 0xc0 ) {GetEArw;*earw=*rmrw;}
452 			else {GetEAa;SaveMw(eaa,*rmrw);}
453 			break;
454 		}
455 	CASE_B(0x8a)												/* MOV Gb,Eb */
456 		{
457 			GetRMrb;
458 			if (rm >= 0xc0 ) {GetEArb;*rmrb=*earb;}
459 			else {GetEAa;*rmrb=LoadMb(eaa);}
460 			break;
461 		}
462 	CASE_W(0x8b)												/* MOV Gw,Ew */
463 		{
464 			GetRMrw;
465 			if (rm >= 0xc0 ) {GetEArw;*rmrw=*earw;}
466 			else {GetEAa;*rmrw=LoadMw(eaa);}
467 			break;
468 		}
469 	CASE_W(0x8c)												/* Mov Ew,Sw */
470 		{
471 			GetRM;Bit16u val;Bitu which=(rm>>3)&7;
472 			switch (which) {
473 			case 0x00:					/* MOV Ew,ES */
474 				val=SegValue(es);break;
475 			case 0x01:					/* MOV Ew,CS */
476 				val=SegValue(cs);break;
477 			case 0x02:					/* MOV Ew,SS */
478 				val=SegValue(ss);break;
479 			case 0x03:					/* MOV Ew,DS */
480 				val=SegValue(ds);break;
481 			case 0x04:					/* MOV Ew,FS */
482 				val=SegValue(fs);break;
483 			case 0x05:					/* MOV Ew,GS */
484 				val=SegValue(gs);break;
485 			default:
486 				LOG(LOG_CPU,LOG_ERROR)("CPU:8c:Illegal RM Byte");
487 				goto illegal_opcode;
488 			}
489 			if (rm >= 0xc0 ) {GetEArw;*earw=val;}
490 			else {GetEAa;SaveMw(eaa,val);}
491 			break;
492 		}
493 	CASE_W(0x8d)												/* LEA Gw */
494 		{
495 			//Little hack to always use segprefixed version
496 			BaseDS=BaseSS=0;
497 			GetRMrw;
498 			if (TEST_PREFIX_ADDR) {
499 				*rmrw=(Bit16u)(*EATable[256+rm])();
500 			} else {
501 				*rmrw=(Bit16u)(*EATable[rm])();
502 			}
503 			break;
504 		}
505 	CASE_B(0x8e)												/* MOV Sw,Ew */
506 		{
507 			GetRM;Bit16u val;Bitu which=(rm>>3)&7;
508 			if (rm >= 0xc0 ) {GetEArw;val=*earw;}
509 			else {GetEAa;val=LoadMw(eaa);}
510 			switch (which) {
511 			case 0x02:					/* MOV SS,Ew */
512 				CPU_Cycles++; //Always do another instruction
513 			case 0x00:					/* MOV ES,Ew */
514 			case 0x03:					/* MOV DS,Ew */
515 			case 0x05:					/* MOV GS,Ew */
516 			case 0x04:					/* MOV FS,Ew */
517 				if (CPU_SetSegGeneral((SegNames)which,val)) RUNEXCEPTION();
518 				break;
519 			default:
520 				goto illegal_opcode;
521 			}
522 			break;
523 		}
524 	CASE_W(0x8f)												/* POP Ew */
525 		{
526 			Bit16u val=Pop_16();
527 			GetRM;
528 			if (rm >= 0xc0 ) {GetEArw;*earw=val;}
529 			else {GetEAa;SaveMw(eaa,val);}
530 			break;
531 		}
532 	CASE_B(0x90)												/* NOP */
533 		break;
534 	CASE_W(0x91)												/* XCHG CX,AX */
535 		{ Bit16u temp=reg_ax;reg_ax=reg_cx;reg_cx=temp; }
536 		break;
537 	CASE_W(0x92)												/* XCHG DX,AX */
538 		{ Bit16u temp=reg_ax;reg_ax=reg_dx;reg_dx=temp; }
539 		break;
540 	CASE_W(0x93)												/* XCHG BX,AX */
541 		{ Bit16u temp=reg_ax;reg_ax=reg_bx;reg_bx=temp; }
542 		break;
543 	CASE_W(0x94)												/* XCHG SP,AX */
544 		{ Bit16u temp=reg_ax;reg_ax=reg_sp;reg_sp=temp; }
545 		break;
546 	CASE_W(0x95)												/* XCHG BP,AX */
547 		{ Bit16u temp=reg_ax;reg_ax=reg_bp;reg_bp=temp; }
548 		break;
549 	CASE_W(0x96)												/* XCHG SI,AX */
550 		{ Bit16u temp=reg_ax;reg_ax=reg_si;reg_si=temp; }
551 		break;
552 	CASE_W(0x97)												/* XCHG DI,AX */
553 		{ Bit16u temp=reg_ax;reg_ax=reg_di;reg_di=temp; }
554 		break;
555 	CASE_W(0x98)												/* CBW */
556 		reg_ax=(Bit8s)reg_al;break;
557 	CASE_W(0x99)												/* CWD */
558 		if (reg_ax & 0x8000) reg_dx=0xffff;else reg_dx=0;
559 		break;
560 	CASE_W(0x9a)												/* CALL Ap */
561 		{
562 			FillFlags();
563 			Bit16u newip=Fetchw();Bit16u newcs=Fetchw();
564 			CPU_CALL(false,newcs,newip,GETIP);
565 #if CPU_TRAP_CHECK
566 			if (GETFLAG(TF)) {
567 				cpudecoder=CPU_Core_Normal_Trap_Run;
568 				return CBRET_NONE;
569 			}
570 #endif
571 			continue;
572 		}
573 	CASE_B(0x9b)												/* WAIT */
574 		break; /* No waiting here */
575 	CASE_W(0x9c)												/* PUSHF */
576 		if (CPU_PUSHF(false)) RUNEXCEPTION();
577 		break;
578 	CASE_W(0x9d)												/* POPF */
579 		if (CPU_POPF(false)) RUNEXCEPTION();
580 #if CPU_TRAP_CHECK
581 		if (GETFLAG(TF)) {
582 			cpudecoder=CPU_Core_Normal_Trap_Run;
583 			goto decode_end;
584 		}
585 #endif
586 #if	CPU_PIC_CHECK
587 		if (GETFLAG(IF) && PIC_IRQCheck) goto decode_end;
588 #endif
589 		break;
590 	CASE_B(0x9e)												/* SAHF */
591 		SETFLAGSb(reg_ah);
592 		break;
593 	CASE_B(0x9f)												/* LAHF */
594 		FillFlags();
595 		reg_ah=reg_flags&0xff;
596 		break;
597 	CASE_B(0xa0)												/* MOV AL,Ob */
598 		{
599 			GetEADirect;
600 			reg_al=LoadMb(eaa);
601 		}
602 		break;
603 	CASE_W(0xa1)												/* MOV AX,Ow */
604 		{
605 			GetEADirect;
606 			reg_ax=LoadMw(eaa);
607 		}
608 		break;
609 	CASE_B(0xa2)												/* MOV Ob,AL */
610 		{
611 			GetEADirect;
612 			SaveMb(eaa,reg_al);
613 		}
614 		break;
615 	CASE_W(0xa3)												/* MOV Ow,AX */
616 		{
617 			GetEADirect;
618 			SaveMw(eaa,reg_ax);
619 		}
620 		break;
621 	CASE_B(0xa4)												/* MOVSB */
622 		DoString(R_MOVSB);break;
623 	CASE_W(0xa5)												/* MOVSW */
624 		DoString(R_MOVSW);break;
625 	CASE_B(0xa6)												/* CMPSB */
626 		DoString(R_CMPSB);break;
627 	CASE_W(0xa7)												/* CMPSW */
628 		DoString(R_CMPSW);break;
629 	CASE_B(0xa8)												/* TEST AL,Ib */
630 		ALIb(TESTB);break;
631 	CASE_W(0xa9)												/* TEST AX,Iw */
632 		AXIw(TESTW);break;
633 	CASE_B(0xaa)												/* STOSB */
634 		DoString(R_STOSB);break;
635 	CASE_W(0xab)												/* STOSW */
636 		DoString(R_STOSW);break;
637 	CASE_B(0xac)												/* LODSB */
638 		DoString(R_LODSB);break;
639 	CASE_W(0xad)												/* LODSW */
640 		DoString(R_LODSW);break;
641 	CASE_B(0xae)												/* SCASB */
642 		DoString(R_SCASB);break;
643 	CASE_W(0xaf)												/* SCASW */
644 		DoString(R_SCASW);break;
645 	CASE_B(0xb0)												/* MOV AL,Ib */
646 		reg_al=Fetchb();break;
647 	CASE_B(0xb1)												/* MOV CL,Ib */
648 		reg_cl=Fetchb();break;
649 	CASE_B(0xb2)												/* MOV DL,Ib */
650 		reg_dl=Fetchb();break;
651 	CASE_B(0xb3)												/* MOV BL,Ib */
652 		reg_bl=Fetchb();break;
653 	CASE_B(0xb4)												/* MOV AH,Ib */
654 		reg_ah=Fetchb();break;
655 	CASE_B(0xb5)												/* MOV CH,Ib */
656 		reg_ch=Fetchb();break;
657 	CASE_B(0xb6)												/* MOV DH,Ib */
658 		reg_dh=Fetchb();break;
659 	CASE_B(0xb7)												/* MOV BH,Ib */
660 		reg_bh=Fetchb();break;
661 	CASE_W(0xb8)												/* MOV AX,Iw */
662 		reg_ax=Fetchw();break;
663 	CASE_W(0xb9)												/* MOV CX,Iw */
664 		reg_cx=Fetchw();break;
665 	CASE_W(0xba)												/* MOV DX,Iw */
666 		reg_dx=Fetchw();break;
667 	CASE_W(0xbb)												/* MOV BX,Iw */
668 		reg_bx=Fetchw();break;
669 	CASE_W(0xbc)												/* MOV SP,Iw */
670 		reg_sp=Fetchw();break;
671 	CASE_W(0xbd)												/* MOV BP.Iw */
672 		reg_bp=Fetchw();break;
673 	CASE_W(0xbe)												/* MOV SI,Iw */
674 		reg_si=Fetchw();break;
675 	CASE_W(0xbf)												/* MOV DI,Iw */
676 		reg_di=Fetchw();break;
677 	CASE_B(0xc0)												/* GRP2 Eb,Ib */
678 		GRP2B(Fetchb());break;
679 	CASE_W(0xc1)												/* GRP2 Ew,Ib */
680 		GRP2W(Fetchb());break;
681 	CASE_W(0xc2)												/* RETN Iw */
682 		reg_eip=Pop_16();
683 		reg_esp+=Fetchw();
684 		continue;
685 	CASE_W(0xc3)												/* RETN */
686 		reg_eip=Pop_16();
687 		continue;
688 	CASE_W(0xc4)												/* LES */
689 		{
690 			GetRMrw;
691 			if (rm >= 0xc0) goto illegal_opcode;
692 			GetEAa;
693 			if (CPU_SetSegGeneral(es,LoadMw(eaa+2))) RUNEXCEPTION();
694 			*rmrw=LoadMw(eaa);
695 			break;
696 		}
697 	CASE_W(0xc5)												/* LDS */
698 		{
699 			GetRMrw;
700 			if (rm >= 0xc0) goto illegal_opcode;
701 			GetEAa;
702 			if (CPU_SetSegGeneral(ds,LoadMw(eaa+2))) RUNEXCEPTION();
703 			*rmrw=LoadMw(eaa);
704 			break;
705 		}
706 	CASE_B(0xc6)												/* MOV Eb,Ib */
707 		{
708 			GetRM;
709 			if (rm >= 0xc0) {GetEArb;*earb=Fetchb();}
710 			else {GetEAa;SaveMb(eaa,Fetchb());}
711 			break;
712 		}
713 	CASE_W(0xc7)												/* MOV EW,Iw */
714 		{
715 			GetRM;
716 			if (rm >= 0xc0) {GetEArw;*earw=Fetchw();}
717 			else {GetEAa;SaveMw(eaa,Fetchw());}
718 			break;
719 		}
720 	CASE_W(0xc8)												/* ENTER Iw,Ib */
721 		{
722 			Bitu bytes=Fetchw();
723 			Bitu level=Fetchb();
724 			CPU_ENTER(false,bytes,level);
725 		}
726 		break;
727 	CASE_W(0xc9)												/* LEAVE */
728 		reg_esp&=cpu.stack.notmask;
729 		reg_esp|=(reg_ebp&cpu.stack.mask);
730 		reg_bp=Pop_16();
731 		break;
732 	CASE_W(0xca)												/* RETF Iw */
733 		{
734 			Bitu words=Fetchw();
735 			FillFlags();
736 			CPU_RET(false,words,GETIP);
737 			continue;
738 		}
739 	CASE_W(0xcb)												/* RETF */
740 		FillFlags();
741 		CPU_RET(false,0,GETIP);
742 		continue;
743 	CASE_B(0xcc)												/* INT3 */
744 #if C_DEBUG
745 		FillFlags();
746 		if (DEBUG_Breakpoint())
747 			return debugCallback;
748 #endif
749 		CPU_SW_Interrupt_NoIOPLCheck(3,GETIP);
750 #if CPU_TRAP_CHECK
751 		cpu.trap_skip=true;
752 #endif
753 		continue;
754 	CASE_B(0xcd)												/* INT Ib */
755 		{
756 			Bit8u num=Fetchb();
757 #if C_DEBUG
758 			FillFlags();
759 			if (DEBUG_IntBreakpoint(num)) {
760 				return debugCallback;
761 			}
762 #endif
763 			CPU_SW_Interrupt(num,GETIP);
764 #if CPU_TRAP_CHECK
765 			cpu.trap_skip=true;
766 #endif
767 			continue;
768 		}
769 	CASE_B(0xce)												/* INTO */
770 		if (get_OF()) {
771 			CPU_SW_Interrupt(4,GETIP);
772 #if CPU_TRAP_CHECK
773 			cpu.trap_skip=true;
774 #endif
775 			continue;
776 		}
777 		break;
778 	CASE_W(0xcf)												/* IRET */
779 		{
780 			CPU_IRET(false,GETIP);
781 #if CPU_TRAP_CHECK
782 			if (GETFLAG(TF)) {
783 				cpudecoder=CPU_Core_Normal_Trap_Run;
784 				return CBRET_NONE;
785 			}
786 #endif
787 #if CPU_PIC_CHECK
788 			if (GETFLAG(IF) && PIC_IRQCheck) return CBRET_NONE;
789 #endif
790 			continue;
791 		}
792 	CASE_B(0xd0)												/* GRP2 Eb,1 */
793 		GRP2B(1);break;
794 	CASE_W(0xd1)												/* GRP2 Ew,1 */
795 		GRP2W(1);break;
796 	CASE_B(0xd2)												/* GRP2 Eb,CL */
797 		GRP2B(reg_cl);break;
798 	CASE_W(0xd3)												/* GRP2 Ew,CL */
799 		GRP2W(reg_cl);break;
800 	CASE_B(0xd4)												/* AAM Ib */
801 		AAM(Fetchb());break;
802 	CASE_B(0xd5)												/* AAD Ib */
803 		AAD(Fetchb());break;
804 	CASE_B(0xd6)												/* SALC */
805 		reg_al = get_CF() ? 0xFF : 0;
806 		break;
807 	CASE_B(0xd7)												/* XLAT */
808 		if (TEST_PREFIX_ADDR) {
809 			reg_al=LoadMb(BaseDS+(Bit32u)(reg_ebx+reg_al));
810 		} else {
811 			reg_al=LoadMb(BaseDS+(Bit16u)(reg_bx+reg_al));
812 		}
813 		break;
814 #ifdef CPU_FPU
815 	CASE_B(0xd8)												/* FPU ESC 0 */
816 		if (x86_fpu_enabled) {
817 			FPU_ESC(0);
818 		} else {
819 			Bit8u rm = Fetchb();
820 			if (rm<0xc0) GetEAa;
821 		}
822 		break;
823 	CASE_B(0xd9)												/* FPU ESC 1 */
824 		if (x86_fpu_enabled) {
825 			FPU_ESC(1);
826 		} else {
827 			Bit8u rm = Fetchb();
828 			if (rm<0xc0) GetEAa;
829 		}
830 	break;
831 	CASE_B(0xda)												/* FPU ESC 2 */
832 		if (x86_fpu_enabled) {
833 			FPU_ESC(2);
834 		} else {
835 			Bit8u rm = Fetchb();
836 			if (rm<0xc0) GetEAa;
837 		}
838 	break;
839 	CASE_B(0xdb)												/* FPU ESC 3 */
840 		if (x86_fpu_enabled) {
841 			FPU_ESC(3);
842 		} else {
843 			Bit8u rm = Fetchb();
844 			if (rm<0xc0) GetEAa;
845 		}
846 	break;
847 	CASE_B(0xdc)												/* FPU ESC 4 */
848 		if (x86_fpu_enabled) {
849 			FPU_ESC(4);
850 		} else {
851 			Bit8u rm = Fetchb();
852 			if (rm<0xc0) GetEAa;
853 		}
854 	break;
855 	CASE_B(0xdd)												/* FPU ESC 5 */
856 		if (x86_fpu_enabled) {
857 			FPU_ESC(5);
858 		} else {
859 			Bit8u rm = Fetchb();
860 			if (rm<0xc0) GetEAa;
861 		}
862 	break;
863 	CASE_B(0xde)												/* FPU ESC 6 */
864 		if (x86_fpu_enabled) {
865 			FPU_ESC(6);
866 		} else {
867 			Bit8u rm = Fetchb();
868 			if (rm<0xc0) GetEAa;
869 		}
870 	break;
871 	CASE_B(0xdf)												/* FPU ESC 7 */
872 		if (x86_fpu_enabled) {
873 			FPU_ESC(7);
874 		} else {
875 			Bit8u rm = Fetchb();
876 			if (rm<0xc0) GetEAa;
877 		}
878 	break;
879 #else
880 	CASE_B(0xd8)												/* FPU ESC 0 */
881 	CASE_B(0xd9)												/* FPU ESC 1 */
882 	CASE_B(0xda)												/* FPU ESC 2 */
883 	CASE_B(0xdb)												/* FPU ESC 3 */
884 	CASE_B(0xdc)												/* FPU ESC 4 */
885 	CASE_B(0xdd)												/* FPU ESC 5 */
886 	CASE_B(0xde)												/* FPU ESC 6 */
887 	CASE_B(0xdf)												/* FPU ESC 7 */
888 		{
889 			LOG(LOG_CPU,LOG_NORMAL)("FPU used");
890 			Bit8u rm=Fetchb();
891 			if (rm<0xc0) GetEAa;
892 		}
893 		break;
894 #endif
895 	CASE_W(0xe0)												/* LOOPNZ */
896 		if (TEST_PREFIX_ADDR) {
897 			JumpCond16_b(--reg_ecx && !get_ZF());
898 		} else {
899 			JumpCond16_b(--reg_cx && !get_ZF());
900 		}
901 		break;
902 	CASE_W(0xe1)												/* LOOPZ */
903 		if (TEST_PREFIX_ADDR) {
904 			JumpCond16_b(--reg_ecx && get_ZF());
905 		} else {
906 			JumpCond16_b(--reg_cx && get_ZF());
907 		}
908 		break;
909 	CASE_W(0xe2)												/* LOOP */
910 		if (TEST_PREFIX_ADDR) {
911 			JumpCond16_b(--reg_ecx);
912 		} else {
913 			JumpCond16_b(--reg_cx);
914 		}
915 		break;
916 	CASE_W(0xe3)												/* JCXZ */
917 		JumpCond16_b(!(reg_ecx & AddrMaskTable[core.prefixes& PREFIX_ADDR]));
918 		break;
919 	CASE_B(0xe4)												/* IN AL,Ib */
920 		{
921 			Bitu port=Fetchb();
922 			if (CPU_IO_Exception(port,1)) RUNEXCEPTION();
923 			reg_al=IO_ReadB(port);
924 			break;
925 		}
926 	CASE_W(0xe5)												/* IN AX,Ib */
927 		{
928 			Bitu port=Fetchb();
929 			if (CPU_IO_Exception(port,2)) RUNEXCEPTION();
930 			reg_al=IO_ReadW(port);
931 			break;
932 		}
933 	CASE_B(0xe6)												/* OUT Ib,AL */
934 		{
935 			Bitu port=Fetchb();
936 			if (CPU_IO_Exception(port,1)) RUNEXCEPTION();
937 			IO_WriteB(port,reg_al);
938 			break;
939 		}
940 	CASE_W(0xe7)												/* OUT Ib,AX */
941 		{
942 			Bitu port=Fetchb();
943 			if (CPU_IO_Exception(port,2)) RUNEXCEPTION();
944 			IO_WriteW(port,reg_ax);
945 			break;
946 		}
947 	CASE_W(0xe8)												/* CALL Jw */
948 		{
949 			Bit16u addip=Fetchws();
950 			SAVEIP;
951 			Push_16(reg_eip);
952 			reg_eip=(Bit16u)(reg_eip+addip);
953 			continue;
954 		}
955 	CASE_W(0xe9)												/* JMP Jw */
956 		{
957 			Bit16u addip=Fetchws();
958 			SAVEIP;
959 			reg_eip=(Bit16u)(reg_eip+addip);
960 			continue;
961 		}
962 	CASE_W(0xea)												/* JMP Ap */
963 		{
964 			Bit16u newip=Fetchw();
965 			Bit16u newcs=Fetchw();
966 			FillFlags();
967 			CPU_JMP(false,newcs,newip,GETIP);
968 #if CPU_TRAP_CHECK
969 			if (GETFLAG(TF)) {
970 				cpudecoder=CPU_Core_Normal_Trap_Run;
971 				return CBRET_NONE;
972 			}
973 #endif
974 			continue;
975 		}
976 	CASE_W(0xeb)												/* JMP Jb */
977 		{
978 			Bit16s addip=Fetchbs();
979 			SAVEIP;
980 			reg_eip=(Bit16u)(reg_eip+addip);
981 			continue;
982 		}
983 	CASE_B(0xec)												/* IN AL,DX */
984 		if (CPU_IO_Exception(reg_dx,1)) RUNEXCEPTION();
985 		reg_al=IO_ReadB(reg_dx);
986 		break;
987 	CASE_W(0xed)												/* IN AX,DX */
988 		if (CPU_IO_Exception(reg_dx,2)) RUNEXCEPTION();
989 		reg_ax=IO_ReadW(reg_dx);
990 		break;
991 	CASE_B(0xee)												/* OUT DX,AL */
992 		if (CPU_IO_Exception(reg_dx,1)) RUNEXCEPTION();
993 		IO_WriteB(reg_dx,reg_al);
994 		break;
995 	CASE_W(0xef)												/* OUT DX,AX */
996 		if (CPU_IO_Exception(reg_dx,2)) RUNEXCEPTION();
997 		IO_WriteW(reg_dx,reg_ax);
998 		break;
999 	CASE_B(0xf0)												/* LOCK */
1000 		LOG(LOG_CPU,LOG_NORMAL)("CPU:LOCK"); /* FIXME: see case D_LOCK in core_full/load.h */
1001 		break;
1002 	CASE_B(0xf1)												/* ICEBP */
1003 		CPU_SW_Interrupt_NoIOPLCheck(1,GETIP);
1004 #if CPU_TRAP_CHECK
1005 		cpu.trap_skip=true;
1006 #endif
1007 		continue;
1008 	CASE_B(0xf2)												/* REPNZ */
1009 		DO_PREFIX_REP(false);
1010 		break;
1011 	CASE_B(0xf3)												/* REPZ */
1012 		DO_PREFIX_REP(true);
1013 		break;
1014 	CASE_B(0xf4)												/* HLT */
1015 		if (cpu.pmode && cpu.cpl) EXCEPTION(EXCEPTION_GP);
1016 		FillFlags();
1017 		CPU_HLT(GETIP);
1018 		return CBRET_NONE;		//Needs to return for hlt cpu core
1019 	CASE_B(0xf5)												/* CMC */
1020 		FillFlags();
1021 		SETFLAGBIT(CF,!(reg_flags & FLAG_CF));
1022 		break;
1023 	CASE_B(0xf6)												/* GRP3 Eb(,Ib) */
1024 		{
1025 			GetRM;Bitu which=(rm>>3)&7;
1026 			switch (which) {
1027 			case 0x00:											/* TEST Eb,Ib */
1028 			case 0x01:											/* TEST Eb,Ib Undocumented*/
1029 				{
1030 					if (rm >= 0xc0 ) {GetEArb;TESTB(*earb,Fetchb(),LoadRb,0)}
1031 					else {GetEAa;TESTB(eaa,Fetchb(),LoadMb,0);}
1032 					break;
1033 				}
1034 			case 0x02:											/* NOT Eb */
1035 				{
1036 					if (rm >= 0xc0 ) {GetEArb;*earb=~*earb;}
1037 					else {GetEAa;SaveMb(eaa,~LoadMb(eaa));}
1038 					break;
1039 				}
1040 			case 0x03:											/* NEG Eb */
1041 				{
1042 					lflags.type=t_NEGb;
1043 					if (rm >= 0xc0 ) {
1044 						GetEArb;lf_var1b=*earb;lf_resb=0-lf_var1b;
1045 						*earb=lf_resb;
1046 					} else {
1047 						GetEAa;lf_var1b=LoadMb(eaa);lf_resb=0-lf_var1b;
1048  						SaveMb(eaa,lf_resb);
1049 					}
1050 					break;
1051 				}
1052 			case 0x04:											/* MUL AL,Eb */
1053 				RMEb(MULB);
1054 				break;
1055 			case 0x05:											/* IMUL AL,Eb */
1056 				RMEb(IMULB);
1057 				break;
1058 			case 0x06:											/* DIV Eb */
1059 				RMEb(DIVB);
1060 				break;
1061 			case 0x07:											/* IDIV Eb */
1062 				RMEb(IDIVB);
1063 				break;
1064 			}
1065 			break;
1066 		}
1067 	CASE_W(0xf7)												/* GRP3 Ew(,Iw) */
1068 		{
1069 			GetRM;Bitu which=(rm>>3)&7;
1070 			switch (which) {
1071 			case 0x00:											/* TEST Ew,Iw */
1072 			case 0x01:											/* TEST Ew,Iw Undocumented*/
1073 				{
1074 					if (rm >= 0xc0 ) {GetEArw;TESTW(*earw,Fetchw(),LoadRw,SaveRw);}
1075 					else {GetEAa;TESTW(eaa,Fetchw(),LoadMw,SaveMw);}
1076 					break;
1077 				}
1078 			case 0x02:											/* NOT Ew */
1079 				{
1080 					if (rm >= 0xc0 ) {GetEArw;*earw=~*earw;}
1081 					else {GetEAa;SaveMw(eaa,~LoadMw(eaa));}
1082 					break;
1083 				}
1084 			case 0x03:											/* NEG Ew */
1085 				{
1086 					lflags.type=t_NEGw;
1087 					if (rm >= 0xc0 ) {
1088 						GetEArw;lf_var1w=*earw;lf_resw=0-lf_var1w;
1089 						*earw=lf_resw;
1090 					} else {
1091 						GetEAa;lf_var1w=LoadMw(eaa);lf_resw=0-lf_var1w;
1092  						SaveMw(eaa,lf_resw);
1093 					}
1094 					break;
1095 				}
1096 			case 0x04:											/* MUL AX,Ew */
1097 				RMEw(MULW);
1098 				break;
1099 			case 0x05:											/* IMUL AX,Ew */
1100 				RMEw(IMULW)
1101 				break;
1102 			case 0x06:											/* DIV Ew */
1103 				RMEw(DIVW)
1104 				break;
1105 			case 0x07:											/* IDIV Ew */
1106 				RMEw(IDIVW)
1107 				break;
1108 			}
1109 			break;
1110 		}
1111 	CASE_B(0xf8)												/* CLC */
1112 		FillFlags();
1113 		SETFLAGBIT(CF,false);
1114 		break;
1115 	CASE_B(0xf9)												/* STC */
1116 		FillFlags();
1117 		SETFLAGBIT(CF,true);
1118 		break;
1119 	CASE_B(0xfa)												/* CLI */
1120 		if (CPU_CLI()) RUNEXCEPTION();
1121 		break;
1122 	CASE_B(0xfb)												/* STI */
1123 		if (CPU_STI()) RUNEXCEPTION();
1124 #if CPU_PIC_CHECK
1125 		if (GETFLAG(IF) && PIC_IRQCheck) goto decode_end;
1126 #endif
1127 		break;
1128 	CASE_B(0xfc)												/* CLD */
1129 		SETFLAGBIT(DF,false);
1130 		cpu.direction=1;
1131 		break;
1132 	CASE_B(0xfd)												/* STD */
1133 		SETFLAGBIT(DF,true);
1134 		cpu.direction=-1;
1135 		break;
1136 	CASE_B(0xfe)												/* GRP4 Eb */
1137 		{
1138 			GetRM;Bitu which=(rm>>3)&7;
1139 			switch (which) {
1140 			case 0x00:										/* INC Eb */
1141 				RMEb(INCB);
1142 				break;
1143 			case 0x01:										/* DEC Eb */
1144 				RMEb(DECB);
1145 				break;
1146 			case 0x07:										/* CallBack */
1147 				{
1148 					Bitu cb=Fetchw();
1149 					FillFlags();SAVEIP;
1150 					return cb;
1151 				}
1152 			default:
1153 				E_Exit("Illegal GRP4 Call %d",(rm>>3) & 7);
1154 				break;
1155 			}
1156 			break;
1157 		}
1158 	CASE_W(0xff)												/* GRP5 Ew */
1159 		{
1160 			GetRM;Bitu which=(rm>>3)&7;
1161 			switch (which) {
1162 			case 0x00:										/* INC Ew */
1163 				RMEw(INCW);
1164 				break;
1165 			case 0x01:										/* DEC Ew */
1166 				RMEw(DECW);
1167 				break;
1168 			case 0x02:										/* CALL Ev */
1169 				if (rm >= 0xc0 ) {GetEArw;reg_eip=*earw;}
1170 				else {GetEAa;reg_eip=LoadMw(eaa);}
1171 				Push_16(GETIP);
1172 				continue;
1173 			case 0x03:										/* CALL Ep */
1174 				{
1175 					if (rm >= 0xc0) goto illegal_opcode;
1176 					GetEAa;
1177 					Bit16u newip=LoadMw(eaa);
1178 					Bit16u newcs=LoadMw(eaa+2);
1179 					FillFlags();
1180 					CPU_CALL(false,newcs,newip,GETIP);
1181 #if CPU_TRAP_CHECK
1182 					if (GETFLAG(TF)) {
1183 						cpudecoder=CPU_Core_Normal_Trap_Run;
1184 						return CBRET_NONE;
1185 					}
1186 #endif
1187 					continue;
1188 				}
1189 				break;
1190 			case 0x04:										/* JMP Ev */
1191 				if (rm >= 0xc0 ) {GetEArw;reg_eip=*earw;}
1192 				else {GetEAa;reg_eip=LoadMw(eaa);}
1193 				continue;
1194 			case 0x05:										/* JMP Ep */
1195 				{
1196 					if (rm >= 0xc0) goto illegal_opcode;
1197 					GetEAa;
1198 					Bit16u newip=LoadMw(eaa);
1199 					Bit16u newcs=LoadMw(eaa+2);
1200 					FillFlags();
1201 					CPU_JMP(false,newcs,newip,GETIP);
1202 #if CPU_TRAP_CHECK
1203 					if (GETFLAG(TF)) {
1204 						cpudecoder=CPU_Core_Normal_Trap_Run;
1205 						return CBRET_NONE;
1206 					}
1207 #endif
1208 					continue;
1209 				}
1210 				break;
1211 			case 0x06:										/* PUSH Ev */
1212 				if (rm >= 0xc0 ) {GetEArw;Push_16(*earw);}
1213 				else {GetEAa;Push_16(LoadMw(eaa));}
1214 				break;
1215 			default:
1216 				LOG(LOG_CPU,LOG_ERROR)("CPU:GRP5:Illegal Call %2X",which);
1217 				goto illegal_opcode;
1218 			}
1219 			break;
1220 		}
1221 
1222 
1223 
1224 
1225