1 /****************************************************************************
2 *			  real mode i286 emulator v1.4 by Fabrice Frances				*
3 *				(initial work based on David Hedley's pcemu)                *
4 ****************************************************************************/
5 
6 /*
7  * file will be included in all cpu variants
8  * put non i86 instructions in own files (i286, i386, nec)
9  * function renaming will be added when neccessary
10  * timing value should move to separate array
11  */
12 
13 #undef ICOUNT
14 
15 #ifdef V20
16 #define ICOUNT nec_ICount
17 #else
18 #define ICOUNT i86_ICount
19 #endif
20 
21 
22 #if !defined(V20) && !defined(I186)
PREFIX86(_interrupt)23 static void PREFIX86(_interrupt)(unsigned int_num)
24 {
25 	unsigned dest_seg, dest_off;
26 	WORD ip = I.pc - I.base[CS];
27 
28 	if (int_num == -1)
29 		int_num = (*I.irq_callback)(0);
30 
31 #ifdef I286
32 	if (PM) {
33 		i286_interrupt_descriptor(int_num);
34 	} else {
35 #endif
36 		dest_off = ReadWord(int_num*4);
37 		dest_seg = ReadWord(int_num*4+2);
38 
39 		PREFIX(_pushf());
40 		I.TF = I.IF = 0;
41 		PUSH(I.sregs[CS]);
42 		PUSH(ip);
43 		I.sregs[CS] = (WORD)dest_seg;
44 		I.base[CS] = SegBase(CS);
45 		I.pc = (I.base[CS] + dest_off) & AMASK;
46 #ifdef I286
47 	}
48 #endif
49 	CHANGE_PC(I.pc);
50 
51 	I.extra_cycles += cycles.exception;
52 }
53 
PREFIX86(_trap)54 static void PREFIX86(_trap)(void)
55 {
56 	PREFIX(_instruction)[FETCHOP]();
57 	PREFIX(_interrupt)(1);
58 }
59 #endif
60 
61 #ifndef I186
PREFIX86(_rotate_shift_Byte)62 static void PREFIX86(_rotate_shift_Byte)(unsigned ModRM, unsigned count)
63 {
64 	unsigned src = (unsigned)GetRMByte(ModRM);
65 	unsigned dst=src;
66 
67 	if (count==0)
68 	{
69 		ICOUNT -= (ModRM >= 0xc0) ? cycles.rot_reg_base : cycles.rot_m8_base;
70 	}
71 	else if (count==1)
72 	{
73 		ICOUNT -= (ModRM >= 0xc0) ? cycles.rot_reg_1 : cycles.rot_m8_1;
74 
75 		switch (ModRM & 0x38)
76 		{
77 		case 0x00:	/* ROL eb,1 */
78 			I.CarryVal = src & 0x80;
79 			dst=(src<<1)+CF;
80 			PutbackRMByte(ModRM,dst);
81 			I.OverVal = (src^dst)&0x80;
82 			break;
83 		case 0x08:	/* ROR eb,1 */
84 			I.CarryVal = src & 0x01;
85 			dst = ((CF<<8)+src) >> 1;
86 			PutbackRMByte(ModRM,dst);
87 			I.OverVal = (src^dst)&0x80;
88 			break;
89 		case 0x10:	/* RCL eb,1 */
90 			dst=(src<<1)+CF;
91 			PutbackRMByte(ModRM,dst);
92 			SetCFB(dst);
93 			I.OverVal = (src^dst)&0x80;
94 			break;
95 		case 0x18:	/* RCR eb,1 */
96 			dst = ((CF<<8)+src) >> 1;
97 			PutbackRMByte(ModRM,dst);
98 			I.CarryVal = src & 0x01;
99 			I.OverVal = (src^dst)&0x80;
100 			break;
101 		case 0x20:	/* SHL eb,1 */
102 		case 0x30:
103 			dst = src << 1;
104 			PutbackRMByte(ModRM,dst);
105 			SetCFB(dst);
106 			I.OverVal = (src^dst)&0x80;
107 			I.AuxVal = 1;
108 			SetSZPF_Byte(dst);
109 			break;
110 		case 0x28:	/* SHR eb,1 */
111 			dst = src >> 1;
112 			PutbackRMByte(ModRM,dst);
113 			I.CarryVal = src & 0x01;
114 			I.OverVal = src & 0x80;
115 			I.AuxVal = 1;
116 			SetSZPF_Byte(dst);
117 			break;
118 		case 0x38:	/* SAR eb,1 */
119 			dst = ((INT8)src) >> 1;
120 			PutbackRMByte(ModRM,dst);
121 			I.CarryVal = src & 0x01;
122 			I.OverVal = 0;
123 			I.AuxVal = 1;
124 			SetSZPF_Byte(dst);
125 			break;
126 		}
127 	}
128 	else
129 	{
130 		ICOUNT -= (ModRM >= 0xc0) ? cycles.rot_reg_base + cycles.rot_reg_bit : cycles.rot_m8_base + cycles.rot_m8_bit;
131 
132 		switch (ModRM & 0x38)
133 		{
134 		case 0x00:	/* ROL eb,count */
135 			for (; count > 0; count--)
136 			{
137 				I.CarryVal = dst & 0x80;
138 				dst = (dst << 1) + CF;
139 			}
140 			PutbackRMByte(ModRM,(BYTE)dst);
141 			break;
142 		case 0x08:	/* ROR eb,count */
143 			for (; count > 0; count--)
144 			{
145 				I.CarryVal = dst & 0x01;
146 				dst = (dst >> 1) + (CF << 7);
147 			}
148 			PutbackRMByte(ModRM,(BYTE)dst);
149 			break;
150 		case 0x10:	/* RCL eb,count */
151 			for (; count > 0; count--)
152 			{
153 				dst = (dst << 1) + CF;
154 				SetCFB(dst);
155 			}
156 			PutbackRMByte(ModRM,(BYTE)dst);
157 			break;
158 		case 0x18:	/* RCR eb,count */
159 			for (; count > 0; count--)
160 			{
161 				dst = (CF<<8)+dst;
162 				I.CarryVal = dst & 0x01;
163 				dst >>= 1;
164 			}
165 			PutbackRMByte(ModRM,(BYTE)dst);
166 			break;
167 		case 0x20:
168 		case 0x30:	/* SHL eb,count */
169 			dst <<= count;
170 			SetCFB(dst);
171 			I.AuxVal = 1;
172 			SetSZPF_Byte(dst);
173 			PutbackRMByte(ModRM,(BYTE)dst);
174 			break;
175 		case 0x28:	/* SHR eb,count */
176 			dst >>= count-1;
177 			I.CarryVal = dst & 0x1;
178 			dst >>= 1;
179 			SetSZPF_Byte(dst);
180 			I.AuxVal = 1;
181 			PutbackRMByte(ModRM,(BYTE)dst);
182 			break;
183 		case 0x38:	/* SAR eb,count */
184 			dst = ((INT8)dst) >> (count-1);
185 			I.CarryVal = dst & 0x1;
186 			dst = ((INT8)((BYTE)dst)) >> 1;
187 			SetSZPF_Byte(dst);
188 			I.AuxVal = 1;
189 			PutbackRMByte(ModRM,(BYTE)dst);
190 			break;
191 		}
192 	}
193 }
194 
PREFIX86(_rotate_shift_Word)195 static void PREFIX86(_rotate_shift_Word)(unsigned ModRM, unsigned count)
196 {
197 	unsigned src = GetRMWord(ModRM);
198 	unsigned dst=src;
199 
200 	if (count==0)
201 	{
202 		ICOUNT -= (ModRM >= 0xc0) ? cycles.rot_reg_base : cycles.rot_m16_base;
203 	}
204 	else if (count==1)
205 	{
206 		ICOUNT -= (ModRM >= 0xc0) ? cycles.rot_reg_1 : cycles.rot_m16_1;
207 
208 		switch (ModRM & 0x38)
209 		{
210 #if 0
211 		case 0x00:	/* ROL ew,1 */
212 			tmp2 = (tmp << 1) + CF;
213 			SetCFW(tmp2);
214 			I.OverVal = !(!(tmp & 0x4000)) != CF;
215 			PutbackRMWord(ModRM,tmp2);
216 			break;
217 		case 0x08:	/* ROR ew,1 */
218 			I.CarryVal = tmp & 0x01;
219 			tmp2 = (tmp >> 1) + ((unsigned)CF << 15);
220 			I.OverVal = !(!(tmp & 0x8000)) != CF;
221 			PutbackRMWord(ModRM,tmp2);
222 			break;
223 		case 0x10:	/* RCL ew,1 */
224 			tmp2 = (tmp << 1) + CF;
225 			SetCFW(tmp2);
226 			I.OverVal = (tmp ^ (tmp << 1)) & 0x8000;
227 			PutbackRMWord(ModRM,tmp2);
228 			break;
229 		case 0x18:	/* RCR ew,1 */
230 			tmp2 = (tmp >> 1) + ((unsigned)CF << 15);
231 			I.OverVal = !(!(tmp & 0x8000)) != CF;
232 			I.CarryVal = tmp & 0x01;
233 			PutbackRMWord(ModRM,tmp2);
234 			break;
235 		case 0x20:	/* SHL ew,1 */
236 		case 0x30:
237 			tmp <<= 1;
238 
239             SetCFW(tmp);
240 			SetOFW_Add(tmp,tmp2,tmp2);
241 			I.AuxVal = 1;
242 			SetSZPF_Word(tmp);
243 
244 			PutbackRMWord(ModRM,tmp);
245 			break;
246 		case 0x28:	/* SHR ew,1 */
247 			I.CarryVal = tmp & 0x01;
248 			I.OverVal = tmp & 0x8000;
249 
250 			tmp2 = tmp >> 1;
251 
252 			SetSZPF_Word(tmp2);
253 			I.AuxVal = 1;
254 			PutbackRMWord(ModRM,tmp2);
255 			break;
256 			case 0x38:	/* SAR ew,1 */
257 			I.CarryVal = tmp & 0x01;
258 			I.OverVal = 0;
259 
260 			tmp2 = (tmp >> 1) | (tmp & 0x8000);
261 
262 			SetSZPF_Word(tmp2);
263 			I.AuxVal = 1;
264 			PutbackRMWord(ModRM,tmp2);
265 			break;
266 #else
267 		case 0x00:	/* ROL ew,1 */
268 			I.CarryVal = src & 0x8000;
269 			dst=(src<<1)+CF;
270 			PutbackRMWord(ModRM,dst);
271 			I.OverVal = (src^dst)&0x8000;
272 			break;
273 		case 0x08:	/* ROR ew,1 */
274 			I.CarryVal = src & 0x01;
275 			dst = ((CF<<16)+src) >> 1;
276 			PutbackRMWord(ModRM,dst);
277 			I.OverVal = (src^dst)&0x8000;
278 			break;
279 		case 0x10:	/* RCL ew,1 */
280 			dst=(src<<1)+CF;
281 			PutbackRMWord(ModRM,dst);
282 			SetCFW(dst);
283 			I.OverVal = (src^dst)&0x8000;
284 			break;
285 		case 0x18:	/* RCR ew,1 */
286 			dst = ((CF<<16)+src) >> 1;
287 			PutbackRMWord(ModRM,dst);
288 			I.CarryVal = src & 0x01;
289 			I.OverVal = (src^dst)&0x8000;
290 			break;
291 		case 0x20:	/* SHL ew,1 */
292 		case 0x30:
293 			dst = src << 1;
294 			PutbackRMWord(ModRM,dst);
295 			SetCFW(dst);
296 			I.OverVal = (src^dst)&0x8000;
297 			I.AuxVal = 1;
298 			SetSZPF_Word(dst);
299 			break;
300 		case 0x28:	/* SHR ew,1 */
301 			dst = src >> 1;
302 			PutbackRMWord(ModRM,dst);
303 			I.CarryVal = src & 0x01;
304 			I.OverVal = src & 0x8000;
305 			I.AuxVal = 1;
306 			SetSZPF_Word(dst);
307 			break;
308 		case 0x38:	/* SAR ew,1 */
309 			dst = ((INT16)src) >> 1;
310 			PutbackRMWord(ModRM,dst);
311 			I.CarryVal = src & 0x01;
312 			I.OverVal = 0;
313 			I.AuxVal = 1;
314 			SetSZPF_Word(dst);
315 			break;
316 #endif
317 		}
318 	}
319 	else
320 	{
321 		ICOUNT -= (ModRM >= 0xc0) ? cycles.rot_reg_base + cycles.rot_reg_bit : cycles.rot_m8_base + cycles.rot_m16_bit;
322 
323 		switch (ModRM & 0x38)
324 		{
325 		case 0x00:	/* ROL ew,count */
326 			for (; count > 0; count--)
327 			{
328 				I.CarryVal = dst & 0x8000;
329 				dst = (dst << 1) + CF;
330 			}
331 			PutbackRMWord(ModRM,dst);
332 			break;
333 		case 0x08:	/* ROR ew,count */
334 			for (; count > 0; count--)
335 			{
336 				I.CarryVal = dst & 0x01;
337 				dst = (dst >> 1) + (CF << 15);
338 			}
339 			PutbackRMWord(ModRM,dst);
340 			break;
341 		case 0x10:  /* RCL ew,count */
342 			for (; count > 0; count--)
343 			{
344 				dst = (dst << 1) + CF;
345 				SetCFW(dst);
346 			}
347 			PutbackRMWord(ModRM,dst);
348 			break;
349 		case 0x18:	/* RCR ew,count */
350 			for (; count > 0; count--)
351 			{
352 				dst = dst + (CF << 16);
353 				I.CarryVal = dst & 0x01;
354 				dst >>= 1;
355 			}
356 			PutbackRMWord(ModRM,dst);
357 			break;
358 		case 0x20:
359 		case 0x30:	/* SHL ew,count */
360 			dst <<= count;
361 			SetCFW(dst);
362 			I.AuxVal = 1;
363 			SetSZPF_Word(dst);
364 			PutbackRMWord(ModRM,dst);
365 			break;
366 		case 0x28:	/* SHR ew,count */
367 			dst >>= count-1;
368 			I.CarryVal = dst & 0x1;
369 			dst >>= 1;
370 			SetSZPF_Word(dst);
371 			I.AuxVal = 1;
372 			PutbackRMWord(ModRM,dst);
373 			break;
374 		case 0x38:	/* SAR ew,count */
375 			dst = ((INT16)dst) >> (count-1);
376 			I.CarryVal = dst & 0x01;
377 			dst = ((INT16)((WORD)dst)) >> 1;
378 			SetSZPF_Word(dst);
379 			I.AuxVal = 1;
380 			PutbackRMWord(ModRM,dst);
381 			break;
382 		}
383 	}
384 }
385 #endif
386 
PREFIX(rep)387 static void PREFIX(rep)(int flagval)
388 {
389     /* Handles rep- and repnz- prefixes. flagval is the value of ZF for the
390 		 loop  to continue for CMPS and SCAS instructions. */
391 
392 	unsigned next = FETCHOP;
393 	unsigned count = I.regs.w[CX];
394 
395     switch(next)
396     {
397 	case 0x26:  /* ES: */
398 		seg_prefix=TRUE;
399 		prefix_base=I.base[ES];
400 		ICOUNT -= cycles.override;
401 		PREFIX(rep)(flagval);
402 		break;
403 	case 0x2e:  /* CS: */
404 		seg_prefix=TRUE;
405 		prefix_base=I.base[CS];
406 		ICOUNT -= cycles.override;
407 		PREFIX(rep)(flagval);
408 		break;
409 	case 0x36:  /* SS: */
410 		seg_prefix=TRUE;
411 		prefix_base=I.base[SS];
412 		ICOUNT -= cycles.override;
413 		PREFIX(rep)(flagval);
414 		break;
415 	case 0x3e:  /* DS: */
416 		seg_prefix=TRUE;
417 		prefix_base=I.base[DS];
418 		ICOUNT -= cycles.override;
419 		PREFIX(rep)(flagval);
420 		break;
421 #ifndef I86
422 	case 0x6c:	/* REP INSB */
423 		ICOUNT -= cycles.rep_ins8_base;
424 		for (; count > 0; count--)
425 		{
426 			if (ICOUNT <= 0) { I.pc = I.prevpc; break; }
427 			PutMemB(ES,I.regs.w[DI],read_port(I.regs.w[DX]));
428 			I.regs.w[DI] += I.DirVal;
429 			ICOUNT -= cycles.rep_ins8_count;
430 		}
431 		I.regs.w[CX]=count;
432 		break;
433 	case 0x6d:  /* REP INSW */
434 		ICOUNT -= cycles.rep_ins16_base;
435 		for (; count > 0; count--)
436 		{
437 			if (ICOUNT <= 0) { I.pc = I.prevpc; break; }
438 			PutMemB(ES,I.regs.w[DI],read_port(I.regs.w[DX]));
439 			PutMemB(ES,I.regs.w[DI]+1,read_port(I.regs.w[DX]+1));
440 			I.regs.w[DI] += 2 * I.DirVal;
441 			ICOUNT -= cycles.rep_ins16_count;
442 		}
443 		I.regs.w[CX]=count;
444 		break;
445 	case 0x6e:  /* REP OUTSB */
446 		ICOUNT -= cycles.rep_outs8_base;
447 		for (; count > 0; count--)
448 		{
449 			if (ICOUNT <= 0) { I.pc = I.prevpc; break; }
450 			write_port(I.regs.w[DX],GetMemB(DS,I.regs.w[SI]));
451 			I.regs.w[SI] += I.DirVal; /* GOL 11/27/01 */
452 			ICOUNT -= cycles.rep_outs8_count;
453 		}
454 		I.regs.w[CX]=count;
455 		break;
456 	case 0x6f:  /* REP OUTSW */
457 		ICOUNT -= cycles.rep_outs16_base;
458 		for (; count > 0; count--)
459 		{
460 			if (ICOUNT <= 0) { I.pc = I.prevpc; break; }
461 			write_port(I.regs.w[DX],GetMemB(DS,I.regs.w[SI]));
462 			write_port(I.regs.w[DX]+1,GetMemB(DS,I.regs.w[SI]+1));
463 			I.regs.w[SI] += 2 * I.DirVal; /* GOL 11/27/01 */
464 			ICOUNT -= cycles.rep_outs16_count;
465 		}
466 		I.regs.w[CX]=count;
467 		break;
468 #endif
469 	case 0xa4:  /* REP MOVSB */
470 		ICOUNT -= cycles.rep_movs8_base;
471 		for (; count > 0; count--)
472 		{
473 			BYTE tmp;
474 
475 			if (ICOUNT <= 0) { I.pc = I.prevpc; break; }
476 			tmp = GetMemB(DS,I.regs.w[SI]);
477 			PutMemB(ES,I.regs.w[DI], tmp);
478 			I.regs.w[DI] += I.DirVal;
479 			I.regs.w[SI] += I.DirVal;
480 			ICOUNT -= cycles.rep_movs8_count;
481 		}
482 		I.regs.w[CX]=count;
483 		break;
484 	case 0xa5:  /* REP MOVSW */
485 		ICOUNT -= cycles.rep_movs16_base;
486 		for (; count > 0; count--)
487 		{
488 			WORD tmp;
489 
490 			if (ICOUNT <= 0) { I.pc = I.prevpc; break; }
491 			tmp = GetMemW(DS,I.regs.w[SI]);
492 			PutMemW(ES,I.regs.w[DI], tmp);
493 			I.regs.w[DI] += 2 * I.DirVal;
494 			I.regs.w[SI] += 2 * I.DirVal;
495 			ICOUNT -= cycles.rep_movs16_count;
496 		}
497 		I.regs.w[CX]=count;
498 		break;
499 	case 0xa6:  /* REP(N)E CMPSB */
500 		ICOUNT -= cycles.rep_cmps8_base;
501 		for (I.ZeroVal = !flagval; (ZF == flagval) && (count > 0); count--)
502 		{
503 			unsigned dst, src;
504 
505 			if (ICOUNT <= 0) { I.pc = I.prevpc; break; }
506 			dst = GetMemB(ES, I.regs.w[DI]);
507 			src = GetMemB(DS, I.regs.w[SI]);
508 		    SUBB(src,dst); /* opposite of the usual convention */
509 			I.regs.w[DI] += I.DirVal;
510 			I.regs.w[SI] += I.DirVal;
511 			ICOUNT -= cycles.rep_cmps8_count;
512 		}
513 		I.regs.w[CX]=count;
514 		break;
515 	case 0xa7:  /* REP(N)E CMPSW */
516 		ICOUNT -= cycles.rep_cmps16_base;
517 		for (I.ZeroVal = !flagval; (ZF == flagval) && (count > 0); count--)
518 		{
519 			unsigned dst, src;
520 
521 			if (ICOUNT <= 0) { I.pc = I.prevpc; break; }
522 			dst = GetMemW(ES, I.regs.w[DI]);
523 			src = GetMemW(DS, I.regs.w[SI]);
524 		    SUBB(src,dst); /* opposite of the usual convention */
525 			I.regs.w[DI] += 2 * I.DirVal;
526 			I.regs.w[SI] += 2 * I.DirVal;
527 			ICOUNT -= cycles.rep_cmps16_count;
528 		}
529 		I.regs.w[CX]=count;
530 		break;
531 	case 0xaa:  /* REP STOSB */
532 		ICOUNT -= cycles.rep_stos8_base;
533 		for (; count > 0; count--)
534 		{
535 			if (ICOUNT <= 0) { I.pc = I.prevpc; break; }
536 			PutMemB(ES,I.regs.w[DI],I.regs.b[AL]);
537 			I.regs.w[DI] += I.DirVal;
538 			ICOUNT -= cycles.rep_stos8_count;
539 		}
540 		I.regs.w[CX]=count;
541 		break;
542 	case 0xab:  /* REP STOSW */
543 		ICOUNT -= cycles.rep_stos16_base;
544 		for (; count > 0; count--)
545 		{
546 			if (ICOUNT <= 0) { I.pc = I.prevpc; break; }
547 			PutMemB(ES,I.regs.w[DI],I.regs.b[AL]);
548 			PutMemB(ES,I.regs.w[DI]+1,I.regs.b[AH]);
549 			I.regs.w[DI] += 2 * I.DirVal;
550 			ICOUNT -= cycles.rep_stos16_count;
551 		}
552 		I.regs.w[CX]=count;
553 		break;
554 	case 0xac:  /* REP LODSB */
555 		ICOUNT -= cycles.rep_lods8_base;
556 		for (; count > 0; count--)
557 		{
558 			if (ICOUNT <= 0) { I.pc = I.prevpc; break; }
559 			I.regs.b[AL] = GetMemB(DS,I.regs.w[SI]);
560 			I.regs.w[SI] += I.DirVal;
561 			ICOUNT -= cycles.rep_lods8_count;
562 		}
563 		I.regs.w[CX]=count;
564 		break;
565 	case 0xad:  /* REP LODSW */
566 		ICOUNT -= cycles.rep_lods16_base;
567 		for (; count > 0; count--)
568 		{
569 			if (ICOUNT <= 0) { I.pc = I.prevpc; break; }
570 			I.regs.w[AX] = GetMemW(DS,I.regs.w[SI]);
571 			I.regs.w[SI] += 2 * I.DirVal;
572 			ICOUNT -= cycles.rep_lods16_count;
573 		}
574 		I.regs.w[CX]=count;
575 		break;
576 	case 0xae:  /* REP(N)E SCASB */
577 		ICOUNT -= cycles.rep_scas8_base;
578 		for (I.ZeroVal = !flagval; (ZF == flagval) && (count > 0); count--)
579 		{
580 			unsigned src, dst;
581 
582 			if (ICOUNT <= 0) { I.pc = I.prevpc; break; }
583 			src = GetMemB(ES, I.regs.w[DI]);
584 			dst = I.regs.b[AL];
585 		    SUBB(dst,src);
586 			I.regs.w[DI] += I.DirVal;
587 			ICOUNT -= cycles.rep_scas8_count;
588 		}
589 		I.regs.w[CX]=count;
590 		break;
591 	case 0xaf:  /* REP(N)E SCASW */
592 		ICOUNT -= cycles.rep_scas16_base;
593 		for (I.ZeroVal = !flagval; (ZF == flagval) && (count > 0); count--)
594 		{
595 			unsigned src, dst;
596 
597 			if (ICOUNT <= 0) { I.pc = I.prevpc; break; }
598 			src = GetMemW(ES, I.regs.w[DI]);
599 			dst = I.regs.w[AX];
600 		    SUBW(dst,src);
601 			I.regs.w[DI] += 2 * I.DirVal;
602 			ICOUNT -= cycles.rep_scas16_count;
603 		}
604 		I.regs.w[CX]=count;
605 		break;
606 	default:
607 		PREFIX(_instruction)[next]();
608 	}
609 }
610 
611 #ifndef I186
PREFIX86(_add_br8)612 static void PREFIX86(_add_br8)(void)    /* Opcode 0x00 */
613 {
614 	DEF_br8(dst,src);
615 	ICOUNT -= (ModRM >= 0xc0) ? cycles.alu_rr8 : cycles.alu_mr8;
616 	ADDB(dst,src);
617     PutbackRMByte(ModRM,dst);
618 }
619 
PREFIX86(_add_wr16)620 static void PREFIX86(_add_wr16)(void)    /* Opcode 0x01 */
621 {
622     DEF_wr16(dst,src);
623 	ICOUNT -= (ModRM >= 0xc0) ? cycles.alu_rr16 : cycles.alu_mr16;
624 	ADDW(dst,src);
625 	PutbackRMWord(ModRM,dst);
626 }
627 
PREFIX86(_add_r8b)628 static void PREFIX86(_add_r8b)(void)    /* Opcode 0x02 */
629 {
630 	DEF_r8b(dst,src);
631 	ICOUNT -= (ModRM >= 0xc0) ? cycles.alu_rr8 : cycles.alu_rm8;
632     ADDB(dst,src);
633     RegByte(ModRM)=dst;
634 }
635 
PREFIX86(_add_r16w)636 static void PREFIX86(_add_r16w)(void)    /* Opcode 0x03 */
637 {
638     DEF_r16w(dst,src);
639 	ICOUNT -= (ModRM >= 0xc0) ? cycles.alu_rr16 : cycles.alu_rm16;
640 	ADDW(dst,src);
641 	RegWord(ModRM)=dst;
642 }
643 
644 
PREFIX86(_add_ald8)645 static void PREFIX86(_add_ald8)(void)    /* Opcode 0x04 */
646 {
647     DEF_ald8(dst,src);
648 	ICOUNT -= cycles.alu_ri8;
649     ADDB(dst,src);
650 	I.regs.b[AL]=dst;
651 }
652 
653 
PREFIX86(_add_axd16)654 static void PREFIX86(_add_axd16)(void)    /* Opcode 0x05 */
655 {
656     DEF_axd16(dst,src);
657 	ICOUNT -= cycles.alu_ri16;
658 	ADDW(dst,src);
659 	I.regs.w[AX]=dst;
660 }
661 
662 
PREFIX86(_push_es)663 static void PREFIX86(_push_es)(void)    /* Opcode 0x06 */
664 {
665 	ICOUNT -= cycles.push_seg;
666 	PUSH(I.sregs[ES]);
667 }
668 
669 
PREFIX86(_pop_es)670 static void PREFIX86(_pop_es)(void)    /* Opcode 0x07 */
671 {
672 	POP(I.sregs[ES]);
673 	I.base[ES] = SegBase(ES);
674 	ICOUNT -= cycles.pop_seg;
675 }
676 
PREFIX86(_or_br8)677 static void PREFIX86(_or_br8)(void)    /* Opcode 0x08 */
678 {
679     DEF_br8(dst,src);
680 	ICOUNT -= (ModRM >= 0xc0) ? cycles.alu_rr8 : cycles.alu_mr8;
681 	ORB(dst,src);
682     PutbackRMByte(ModRM,dst);
683 }
684 
PREFIX86(_or_wr16)685 static void PREFIX86(_or_wr16)(void)    /* Opcode 0x09 */
686 {
687 	DEF_wr16(dst,src);
688 	ICOUNT -= (ModRM >= 0xc0) ? cycles.alu_rr16 : cycles.alu_mr16;
689     ORW(dst,src);
690     PutbackRMWord(ModRM,dst);
691 }
692 
PREFIX86(_or_r8b)693 static void PREFIX86(_or_r8b)(void)    /* Opcode 0x0a */
694 {
695 	DEF_r8b(dst,src);
696 	ICOUNT -= (ModRM >= 0xc0) ? cycles.alu_rr8 : cycles.alu_rm8;
697     ORB(dst,src);
698     RegByte(ModRM)=dst;
699 }
700 
PREFIX86(_or_r16w)701 static void PREFIX86(_or_r16w)(void)    /* Opcode 0x0b */
702 {
703     DEF_r16w(dst,src);
704 	ICOUNT -= (ModRM >= 0xc0) ? cycles.alu_rr16 : cycles.alu_rm16;
705     ORW(dst,src);
706     RegWord(ModRM)=dst;
707 }
708 
PREFIX86(_or_ald8)709 static void PREFIX86(_or_ald8)(void)    /* Opcode 0x0c */
710 {
711     DEF_ald8(dst,src);
712 	ICOUNT -= cycles.alu_ri8;
713     ORB(dst,src);
714 	I.regs.b[AL]=dst;
715 }
716 
PREFIX86(_or_axd16)717 static void PREFIX86(_or_axd16)(void)    /* Opcode 0x0d */
718 {
719     DEF_axd16(dst,src);
720 	ICOUNT -= cycles.alu_ri16;
721 	ORW(dst,src);
722 	I.regs.w[AX]=dst;
723 }
724 
PREFIX86(_push_cs)725 static void PREFIX86(_push_cs)(void)    /* Opcode 0x0e */
726 {
727 	ICOUNT -= cycles.push_seg;
728 	PUSH(I.sregs[CS]);
729 }
730 
731 /* Opcode 0x0f invalid */
732 
PREFIX86(_adc_br8)733 static void PREFIX86(_adc_br8)(void)    /* Opcode 0x10 */
734 {
735     DEF_br8(dst,src);
736 	ICOUNT -= (ModRM >= 0xc0) ? cycles.alu_rr8 : cycles.alu_mr8;
737     src+=CF;
738     ADDB(dst,src);
739     PutbackRMByte(ModRM,dst);
740 }
741 
PREFIX86(_adc_wr16)742 static void PREFIX86(_adc_wr16)(void)    /* Opcode 0x11 */
743 {
744     DEF_wr16(dst,src);
745 	ICOUNT -= (ModRM >= 0xc0) ? cycles.alu_rr16 : cycles.alu_mr16;
746     src+=CF;
747     ADDW(dst,src);
748 	PutbackRMWord(ModRM,dst);
749 }
750 
PREFIX86(_adc_r8b)751 static void PREFIX86(_adc_r8b)(void)    /* Opcode 0x12 */
752 {
753     DEF_r8b(dst,src);
754 	ICOUNT -= (ModRM >= 0xc0) ? cycles.alu_rr8 : cycles.alu_rm8;
755 	src+=CF;
756     ADDB(dst,src);
757     RegByte(ModRM)=dst;
758 }
759 
PREFIX86(_adc_r16w)760 static void PREFIX86(_adc_r16w)(void)    /* Opcode 0x13 */
761 {
762     DEF_r16w(dst,src);
763 	ICOUNT -= (ModRM >= 0xc0) ? cycles.alu_rr16 : cycles.alu_rm16;
764 	src+=CF;
765     ADDW(dst,src);
766     RegWord(ModRM)=dst;
767 }
768 
PREFIX86(_adc_ald8)769 static void PREFIX86(_adc_ald8)(void)    /* Opcode 0x14 */
770 {
771     DEF_ald8(dst,src);
772 	ICOUNT -= cycles.alu_ri8;
773     src+=CF;
774     ADDB(dst,src);
775 	I.regs.b[AL] = dst;
776 }
777 
PREFIX86(_adc_axd16)778 static void PREFIX86(_adc_axd16)(void)    /* Opcode 0x15 */
779 {
780 	DEF_axd16(dst,src);
781 	ICOUNT -= cycles.alu_ri16;
782 	src+=CF;
783     ADDW(dst,src);
784 	I.regs.w[AX]=dst;
785 }
786 
PREFIX86(_push_ss)787 static void PREFIX86(_push_ss)(void)    /* Opcode 0x16 */
788 {
789 	PUSH(I.sregs[SS]);
790 	ICOUNT -= cycles.push_seg;
791 }
792 
PREFIX86(_pop_ss)793 static void PREFIX86(_pop_ss)(void)    /* Opcode 0x17 */
794 {
795 #ifdef I286
796 	UINT16 tmp;
797 	POP(tmp);
798 	i286_data_descriptor(SS, tmp);
799 #else
800 	POP(I.sregs[SS]);
801 	I.base[SS] = SegBase(SS);
802 #endif
803 	ICOUNT -= cycles.pop_seg;
804 	PREFIX(_instruction)[FETCHOP](); /* no interrupt before next instruction */
805 }
806 
PREFIX86(_sbb_br8)807 static void PREFIX86(_sbb_br8)(void)    /* Opcode 0x18 */
808 {
809     DEF_br8(dst,src);
810 	ICOUNT -= (ModRM >= 0xc0) ? cycles.alu_rr8 : cycles.alu_mr8;
811     src+=CF;
812     SUBB(dst,src);
813     PutbackRMByte(ModRM,dst);
814 }
815 
PREFIX86(_sbb_wr16)816 static void PREFIX86(_sbb_wr16)(void)    /* Opcode 0x19 */
817 {
818     DEF_wr16(dst,src);
819 	ICOUNT -= (ModRM >= 0xc0) ? cycles.alu_rr16 : cycles.alu_mr16;
820     src+=CF;
821 	SUBW(dst,src);
822 	PutbackRMWord(ModRM,dst);
823 }
824 
PREFIX86(_sbb_r8b)825 static void PREFIX86(_sbb_r8b)(void)    /* Opcode 0x1a */
826 {
827 	DEF_r8b(dst,src);
828 	ICOUNT -= (ModRM >= 0xc0) ? cycles.alu_rr8 : cycles.alu_rm8;
829 	src+=CF;
830     SUBB(dst,src);
831     RegByte(ModRM)=dst;
832 }
833 
PREFIX86(_sbb_r16w)834 static void PREFIX86(_sbb_r16w)(void)    /* Opcode 0x1b */
835 {
836     DEF_r16w(dst,src);
837 	ICOUNT -= (ModRM >= 0xc0) ? cycles.alu_rr16 : cycles.alu_rm16;
838 	src+=CF;
839     SUBW(dst,src);
840     RegWord(ModRM)= dst;
841 }
842 
PREFIX86(_sbb_ald8)843 static void PREFIX86(_sbb_ald8)(void)    /* Opcode 0x1c */
844 {
845     DEF_ald8(dst,src);
846 	ICOUNT -= cycles.alu_ri8;
847     src+=CF;
848     SUBB(dst,src);
849 	I.regs.b[AL] = dst;
850 }
851 
PREFIX86(_sbb_axd16)852 static void PREFIX86(_sbb_axd16)(void)    /* Opcode 0x1d */
853 {
854     DEF_axd16(dst,src);
855 	ICOUNT -= cycles.alu_ri16;
856 	src+=CF;
857     SUBW(dst,src);
858 	I.regs.w[AX]=dst;
859 }
860 
PREFIX86(_push_ds)861 static void PREFIX86(_push_ds)(void)    /* Opcode 0x1e */
862 {
863 	PUSH(I.sregs[DS]);
864 	ICOUNT -= cycles.push_seg;
865 }
866 
PREFIX86(_pop_ds)867 static void PREFIX86(_pop_ds)(void)    /* Opcode 0x1f */
868 {
869 #ifdef I286
870 	UINT16 tmp;
871 	POP(tmp);
872 	i286_data_descriptor(DS,tmp);
873 #else
874 	POP(I.sregs[DS]);
875 	I.base[DS] = SegBase(DS);
876 #endif
877 	ICOUNT -= cycles.push_seg;
878 }
879 
PREFIX86(_and_br8)880 static void PREFIX86(_and_br8)(void)    /* Opcode 0x20 */
881 {
882     DEF_br8(dst,src);
883 	ICOUNT -= (ModRM >= 0xc0) ? cycles.alu_rr8 : cycles.alu_mr8;
884     ANDB(dst,src);
885     PutbackRMByte(ModRM,dst);
886 }
887 
PREFIX86(_and_wr16)888 static void PREFIX86(_and_wr16)(void)    /* Opcode 0x21 */
889 {
890     DEF_wr16(dst,src);
891 	ICOUNT -= (ModRM >= 0xc0) ? cycles.alu_rr16 : cycles.alu_mr16;
892     ANDW(dst,src);
893     PutbackRMWord(ModRM,dst);
894 }
895 
PREFIX86(_and_r8b)896 static void PREFIX86(_and_r8b)(void)    /* Opcode 0x22 */
897 {
898     DEF_r8b(dst,src);
899 	ICOUNT -= (ModRM >= 0xc0) ? cycles.alu_rr8 : cycles.alu_rm8;
900     ANDB(dst,src);
901     RegByte(ModRM)=dst;
902 }
903 
PREFIX86(_and_r16w)904 static void PREFIX86(_and_r16w)(void)    /* Opcode 0x23 */
905 {
906     DEF_r16w(dst,src);
907 	ICOUNT -= (ModRM >= 0xc0) ? cycles.alu_rr16 : cycles.alu_rm16;
908 	ANDW(dst,src);
909     RegWord(ModRM)=dst;
910 }
911 
PREFIX86(_and_ald8)912 static void PREFIX86(_and_ald8)(void)    /* Opcode 0x24 */
913 {
914     DEF_ald8(dst,src);
915 	ICOUNT -= cycles.alu_ri8;
916     ANDB(dst,src);
917 	I.regs.b[AL] = dst;
918 }
919 
PREFIX86(_and_axd16)920 static void PREFIX86(_and_axd16)(void)    /* Opcode 0x25 */
921 {
922     DEF_axd16(dst,src);
923 	ICOUNT -= cycles.alu_ri16;
924     ANDW(dst,src);
925 	I.regs.w[AX]=dst;
926 }
927 
PREFIX86(_es)928 static void PREFIX86(_es)(void)    /* Opcode 0x26 */
929 {
930 	seg_prefix=TRUE;
931 	prefix_base=I.base[ES];
932 	ICOUNT -= cycles.override;
933 	PREFIX(_instruction)[FETCHOP]();
934 }
935 
PREFIX86(_daa)936 static void PREFIX86(_daa)(void)    /* Opcode 0x27 */
937 {
938 	if (AF || ((I.regs.b[AL] & 0xf) > 9))
939 	{
940 		int tmp;
941 		I.regs.b[AL] = tmp = I.regs.b[AL] + 6;
942 		I.AuxVal = 1;
943 		I.CarryVal |= tmp & 0x100;
944 	}
945 
946 	if (CF || (I.regs.b[AL] > 0x9f))
947 	{
948 		I.regs.b[AL] += 0x60;
949 		I.CarryVal = 1;
950 	}
951 
952 	SetSZPF_Byte(I.regs.b[AL]);
953 	ICOUNT -= cycles.daa;
954 }
955 
PREFIX86(_sub_br8)956 static void PREFIX86(_sub_br8)(void)    /* Opcode 0x28 */
957 {
958     DEF_br8(dst,src);
959 	ICOUNT -= (ModRM >= 0xc0) ? cycles.alu_rr8 : cycles.alu_mr8;
960     SUBB(dst,src);
961     PutbackRMByte(ModRM,dst);
962 }
963 
PREFIX86(_sub_wr16)964 static void PREFIX86(_sub_wr16)(void)    /* Opcode 0x29 */
965 {
966     DEF_wr16(dst,src);
967 	ICOUNT -= (ModRM >= 0xc0) ? cycles.alu_rr16 : cycles.alu_mr16;
968     SUBW(dst,src);
969     PutbackRMWord(ModRM,dst);
970 }
971 
PREFIX86(_sub_r8b)972 static void PREFIX86(_sub_r8b)(void)    /* Opcode 0x2a */
973 {
974     DEF_r8b(dst,src);
975 	ICOUNT -= (ModRM >= 0xc0) ? cycles.alu_rr8 : cycles.alu_rm8;
976 	SUBB(dst,src);
977     RegByte(ModRM)=dst;
978 }
979 
PREFIX86(_sub_r16w)980 static void PREFIX86(_sub_r16w)(void)    /* Opcode 0x2b */
981 {
982     DEF_r16w(dst,src);
983 	ICOUNT -= (ModRM >= 0xc0) ? cycles.alu_rr16 : cycles.alu_rm16;
984     SUBW(dst,src);
985     RegWord(ModRM)=dst;
986 }
987 
PREFIX86(_sub_ald8)988 static void PREFIX86(_sub_ald8)(void)    /* Opcode 0x2c */
989 {
990     DEF_ald8(dst,src);
991 	ICOUNT -= cycles.alu_ri8;
992     SUBB(dst,src);
993 	I.regs.b[AL] = dst;
994 }
995 
PREFIX86(_sub_axd16)996 static void PREFIX86(_sub_axd16)(void)    /* Opcode 0x2d */
997 {
998 	DEF_axd16(dst,src);
999 	ICOUNT -= cycles.alu_ri16;
1000     SUBW(dst,src);
1001 	I.regs.w[AX]=dst;
1002 }
1003 
PREFIX86(_cs)1004 static void PREFIX86(_cs)(void)    /* Opcode 0x2e */
1005 {
1006     seg_prefix=TRUE;
1007 	prefix_base=I.base[CS];
1008 	ICOUNT -= cycles.override;
1009 	PREFIX(_instruction)[FETCHOP]();
1010 }
1011 
PREFIX86(_das)1012 static void PREFIX86(_das)(void)    /* Opcode 0x2f */
1013 {
1014 	UINT8 tmpAL=I.regs.b[AL];
1015 	if (AF || ((I.regs.b[AL] & 0xf) > 9))
1016 	{
1017 		int tmp;
1018 		I.regs.b[AL] = tmp = I.regs.b[AL] - 6;
1019 		I.AuxVal = 1;
1020 		I.CarryVal |= tmp & 0x100;
1021 	}
1022 
1023 	if (CF || (tmpAL > 0x9f))
1024 	{
1025 		I.regs.b[AL] -= 0x60;
1026 		I.CarryVal = 1;
1027 	}
1028 
1029 	SetSZPF_Byte(I.regs.b[AL]);
1030 	ICOUNT -= cycles.das;
1031 }
1032 
PREFIX86(_xor_br8)1033 static void PREFIX86(_xor_br8)(void)    /* Opcode 0x30 */
1034 {
1035     DEF_br8(dst,src);
1036 	ICOUNT -= (ModRM >= 0xc0) ? cycles.alu_rr8 : cycles.alu_mr8;
1037     XORB(dst,src);
1038 	PutbackRMByte(ModRM,dst);
1039 }
1040 
PREFIX86(_xor_wr16)1041 static void PREFIX86(_xor_wr16)(void)    /* Opcode 0x31 */
1042 {
1043 	DEF_wr16(dst,src);
1044 	ICOUNT -= (ModRM >= 0xc0) ? cycles.alu_rr16 : cycles.alu_mr16;
1045 	XORW(dst,src);
1046     PutbackRMWord(ModRM,dst);
1047 }
1048 
PREFIX86(_xor_r8b)1049 static void PREFIX86(_xor_r8b)(void)    /* Opcode 0x32 */
1050 {
1051     DEF_r8b(dst,src);
1052 	ICOUNT -= (ModRM >= 0xc0) ? cycles.alu_rr8 : cycles.alu_rm8;
1053     XORB(dst,src);
1054     RegByte(ModRM)=dst;
1055 }
1056 
PREFIX86(_xor_r16w)1057 static void PREFIX86(_xor_r16w)(void)    /* Opcode 0x33 */
1058 {
1059     DEF_r16w(dst,src);
1060 	ICOUNT -= (ModRM >= 0xc0) ? cycles.alu_rr16 : cycles.alu_rm16;
1061     XORW(dst,src);
1062 	RegWord(ModRM)=dst;
1063 }
1064 
PREFIX86(_xor_ald8)1065 static void PREFIX86(_xor_ald8)(void)    /* Opcode 0x34 */
1066 {
1067 	DEF_ald8(dst,src);
1068 	ICOUNT -= cycles.alu_ri8;
1069     XORB(dst,src);
1070 	I.regs.b[AL] = dst;
1071 }
1072 
PREFIX86(_xor_axd16)1073 static void PREFIX86(_xor_axd16)(void)    /* Opcode 0x35 */
1074 {
1075     DEF_axd16(dst,src);
1076 	ICOUNT -= cycles.alu_ri16;
1077     XORW(dst,src);
1078 	I.regs.w[AX]=dst;
1079 }
1080 
PREFIX86(_ss)1081 static void PREFIX86(_ss)(void)    /* Opcode 0x36 */
1082 {
1083 	seg_prefix=TRUE;
1084 	prefix_base=I.base[SS];
1085 	ICOUNT -= cycles.override;
1086 	PREFIX(_instruction)[FETCHOP]();
1087 }
1088 
PREFIX86(_aaa)1089 static void PREFIX86(_aaa)(void)    /* Opcode 0x37 */
1090 {
1091 	UINT8 ALcarry=1;
1092 	if (I.regs.b[AL]>0xf9) ALcarry=2;
1093 
1094 	if (AF || ((I.regs.b[AL] & 0xf) > 9))
1095     {
1096 		I.regs.b[AL] += 6;
1097 		I.regs.b[AH] += ALcarry;
1098 		I.AuxVal = 1;
1099 		I.CarryVal = 1;
1100     }
1101 	else
1102 	{
1103 		I.AuxVal = 0;
1104 		I.CarryVal = 0;
1105     }
1106 	I.regs.b[AL] &= 0x0F;
1107 	ICOUNT -= cycles.aaa;
1108 }
1109 
PREFIX86(_cmp_br8)1110 static void PREFIX86(_cmp_br8)(void)    /* Opcode 0x38 */
1111 {
1112     DEF_br8(dst,src);
1113 	ICOUNT -= (ModRM >= 0xc0) ? cycles.alu_rr8 : cycles.alu_rm8;
1114     SUBB(dst,src);
1115 }
1116 
PREFIX86(_cmp_wr16)1117 static void PREFIX86(_cmp_wr16)(void)    /* Opcode 0x39 */
1118 {
1119 	DEF_wr16(dst,src);
1120 	ICOUNT -= (ModRM >= 0xc0) ? cycles.alu_rr16 : cycles.alu_rm16;
1121     SUBW(dst,src);
1122 }
1123 
PREFIX86(_cmp_r8b)1124 static void PREFIX86(_cmp_r8b)(void)    /* Opcode 0x3a */
1125 {
1126     DEF_r8b(dst,src);
1127 	ICOUNT -= (ModRM >= 0xc0) ? cycles.alu_rr8 : cycles.alu_rm8;
1128     SUBB(dst,src);
1129 }
1130 
PREFIX86(_cmp_r16w)1131 static void PREFIX86(_cmp_r16w)(void)    /* Opcode 0x3b */
1132 {
1133 	DEF_r16w(dst,src);
1134 	ICOUNT -= (ModRM >= 0xc0) ? cycles.alu_rr16 : cycles.alu_rm16;
1135     SUBW(dst,src);
1136 }
1137 
PREFIX86(_cmp_ald8)1138 static void PREFIX86(_cmp_ald8)(void)    /* Opcode 0x3c */
1139 {
1140     DEF_ald8(dst,src);
1141 	ICOUNT -= cycles.alu_ri8;
1142     SUBB(dst,src);
1143 }
1144 
PREFIX86(_cmp_axd16)1145 static void PREFIX86(_cmp_axd16)(void)    /* Opcode 0x3d */
1146 {
1147     DEF_axd16(dst,src);
1148 	ICOUNT -= cycles.alu_ri16;
1149     SUBW(dst,src);
1150 }
1151 
PREFIX86(_ds)1152 static void PREFIX86(_ds)(void)    /* Opcode 0x3e */
1153 {
1154 	seg_prefix=TRUE;
1155 	prefix_base=I.base[DS];
1156 	ICOUNT -= cycles.override;
1157 	PREFIX(_instruction)[FETCHOP]();
1158 }
1159 
PREFIX86(_aas)1160 static void PREFIX86(_aas)(void)    /* Opcode 0x3f */
1161 {
1162 	UINT8 ALcarry=1;
1163 	if (I.regs.b[AL]>0xf9) ALcarry=2;
1164 
1165 	if (AF || ((I.regs.b[AL] & 0xf) > 9))
1166     {
1167 		I.regs.b[AL] -= 6;
1168 		I.regs.b[AH] -= 1;
1169 		I.AuxVal = 1;
1170 		I.CarryVal = 1;
1171     }
1172 	else
1173 	{
1174 		I.AuxVal = 0;
1175 		I.CarryVal = 0;
1176     }
1177 	I.regs.b[AL] &= 0x0F;
1178 	ICOUNT -= cycles.aas;
1179 }
1180 
1181 #define IncWordReg(Reg) 					\
1182 {											\
1183 	unsigned tmp = (unsigned)I.regs.w[Reg]; \
1184 	unsigned tmp1 = tmp+1;					\
1185 	SetOFW_Add(tmp1,tmp,1); 				\
1186 	SetAF(tmp1,tmp,1);						\
1187 	SetSZPF_Word(tmp1); 					\
1188 	I.regs.w[Reg]=tmp1; 					\
1189 	ICOUNT -= cycles.incdec_r16;			\
1190 }
1191 
PREFIX86(_inc_ax)1192 static void PREFIX86(_inc_ax)(void)    /* Opcode 0x40 */
1193 {
1194     IncWordReg(AX);
1195 }
1196 
PREFIX86(_inc_cx)1197 static void PREFIX86(_inc_cx)(void)    /* Opcode 0x41 */
1198 {
1199     IncWordReg(CX);
1200 }
1201 
PREFIX86(_inc_dx)1202 static void PREFIX86(_inc_dx)(void)    /* Opcode 0x42 */
1203 {
1204 	IncWordReg(DX);
1205 }
1206 
PREFIX(_inc_bx)1207 static void PREFIX(_inc_bx)(void)    /* Opcode 0x43 */
1208 {
1209 	IncWordReg(BX);
1210 }
1211 
PREFIX86(_inc_sp)1212 static void PREFIX86(_inc_sp)(void)    /* Opcode 0x44 */
1213 {
1214     IncWordReg(SP);
1215 }
1216 
PREFIX86(_inc_bp)1217 static void PREFIX86(_inc_bp)(void)    /* Opcode 0x45 */
1218 {
1219 	IncWordReg(BP);
1220 }
1221 
PREFIX86(_inc_si)1222 static void PREFIX86(_inc_si)(void)    /* Opcode 0x46 */
1223 {
1224 	IncWordReg(SI);
1225 }
1226 
PREFIX86(_inc_di)1227 static void PREFIX86(_inc_di)(void)    /* Opcode 0x47 */
1228 {
1229     IncWordReg(DI);
1230 }
1231 
1232 #define DecWordReg(Reg) 					\
1233 { 											\
1234 	unsigned tmp = (unsigned)I.regs.w[Reg]; \
1235     unsigned tmp1 = tmp-1; 					\
1236     SetOFW_Sub(tmp1,1,tmp); 				\
1237     SetAF(tmp1,tmp,1); 						\
1238 	SetSZPF_Word(tmp1);						\
1239 	I.regs.w[Reg]=tmp1; 					\
1240 	ICOUNT -= cycles.incdec_r16;			\
1241 }
1242 
PREFIX86(_dec_ax)1243 static void PREFIX86(_dec_ax)(void)    /* Opcode 0x48 */
1244 {
1245     DecWordReg(AX);
1246 }
1247 
PREFIX86(_dec_cx)1248 static void PREFIX86(_dec_cx)(void)    /* Opcode 0x49 */
1249 {
1250 	DecWordReg(CX);
1251 }
1252 
PREFIX86(_dec_dx)1253 static void PREFIX86(_dec_dx)(void)    /* Opcode 0x4a */
1254 {
1255 	DecWordReg(DX);
1256 }
1257 
PREFIX86(_dec_bx)1258 static void PREFIX86(_dec_bx)(void)    /* Opcode 0x4b */
1259 {
1260 	DecWordReg(BX);
1261 }
1262 
PREFIX86(_dec_sp)1263 static void PREFIX86(_dec_sp)(void)    /* Opcode 0x4c */
1264 {
1265     DecWordReg(SP);
1266 }
1267 
PREFIX86(_dec_bp)1268 static void PREFIX86(_dec_bp)(void)    /* Opcode 0x4d */
1269 {
1270     DecWordReg(BP);
1271 }
1272 
PREFIX86(_dec_si)1273 static void PREFIX86(_dec_si)(void)    /* Opcode 0x4e */
1274 {
1275     DecWordReg(SI);
1276 }
1277 
PREFIX86(_dec_di)1278 static void PREFIX86(_dec_di)(void)    /* Opcode 0x4f */
1279 {
1280     DecWordReg(DI);
1281 }
1282 
PREFIX86(_push_ax)1283 static void PREFIX86(_push_ax)(void)    /* Opcode 0x50 */
1284 {
1285 	ICOUNT -= cycles.push_r16;
1286 	PUSH(I.regs.w[AX]);
1287 }
1288 
PREFIX86(_push_cx)1289 static void PREFIX86(_push_cx)(void)    /* Opcode 0x51 */
1290 {
1291 	ICOUNT -= cycles.push_r16;
1292 	PUSH(I.regs.w[CX]);
1293 }
1294 
PREFIX86(_push_dx)1295 static void PREFIX86(_push_dx)(void)    /* Opcode 0x52 */
1296 {
1297 	ICOUNT -= cycles.push_r16;
1298 	PUSH(I.regs.w[DX]);
1299 }
1300 
PREFIX86(_push_bx)1301 static void PREFIX86(_push_bx)(void)    /* Opcode 0x53 */
1302 {
1303 	ICOUNT -= cycles.push_r16;
1304 	PUSH(I.regs.w[BX]);
1305 }
1306 
PREFIX86(_push_sp)1307 static void PREFIX86(_push_sp)(void)    /* Opcode 0x54 */
1308 {
1309 	ICOUNT -= cycles.push_r16;
1310 	PUSH(I.regs.w[SP]);
1311 }
1312 
PREFIX86(_push_bp)1313 static void PREFIX86(_push_bp)(void)    /* Opcode 0x55 */
1314 {
1315 	ICOUNT -= cycles.push_r16;
1316 	PUSH(I.regs.w[BP]);
1317 }
1318 
1319 
PREFIX86(_push_si)1320 static void PREFIX86(_push_si)(void)    /* Opcode 0x56 */
1321 {
1322 	ICOUNT -= cycles.push_r16;
1323 	PUSH(I.regs.w[SI]);
1324 }
1325 
PREFIX86(_push_di)1326 static void PREFIX86(_push_di)(void)    /* Opcode 0x57 */
1327 {
1328 	ICOUNT -= cycles.push_r16;
1329 	PUSH(I.regs.w[DI]);
1330 }
1331 
PREFIX86(_pop_ax)1332 static void PREFIX86(_pop_ax)(void)    /* Opcode 0x58 */
1333 {
1334 	ICOUNT -= cycles.pop_r16;
1335 	POP(I.regs.w[AX]);
1336 }
1337 
PREFIX86(_pop_cx)1338 static void PREFIX86(_pop_cx)(void)    /* Opcode 0x59 */
1339 {
1340 	ICOUNT -= cycles.pop_r16;
1341 	POP(I.regs.w[CX]);
1342 }
1343 
PREFIX86(_pop_dx)1344 static void PREFIX86(_pop_dx)(void)    /* Opcode 0x5a */
1345 {
1346 	ICOUNT -= cycles.pop_r16;
1347 	POP(I.regs.w[DX]);
1348 }
1349 
PREFIX86(_pop_bx)1350 static void PREFIX86(_pop_bx)(void)    /* Opcode 0x5b */
1351 {
1352 	ICOUNT -= cycles.pop_r16;
1353 	POP(I.regs.w[BX]);
1354 }
1355 
PREFIX86(_pop_sp)1356 static void PREFIX86(_pop_sp)(void)    /* Opcode 0x5c */
1357 {
1358 	ICOUNT -= cycles.pop_r16;
1359 	POP(I.regs.w[SP]);
1360 }
1361 
PREFIX86(_pop_bp)1362 static void PREFIX86(_pop_bp)(void)    /* Opcode 0x5d */
1363 {
1364 	ICOUNT -= cycles.pop_r16;
1365 	POP(I.regs.w[BP]);
1366 }
1367 
PREFIX86(_pop_si)1368 static void PREFIX86(_pop_si)(void)    /* Opcode 0x5e */
1369 {
1370 	ICOUNT -= cycles.pop_r16;
1371 	POP(I.regs.w[SI]);
1372 }
1373 
PREFIX86(_pop_di)1374 static void PREFIX86(_pop_di)(void)    /* Opcode 0x5f */
1375 {
1376 	ICOUNT -= cycles.pop_r16;
1377 	POP(I.regs.w[DI]);
1378 }
1379 
PREFIX86(_jo)1380 static void PREFIX86(_jo)(void)    /* Opcode 0x70 */
1381 {
1382 	int tmp = (int)((INT8)FETCH);
1383 	if (OF)
1384 	{
1385 		I.pc += tmp;
1386 		ICOUNT -= cycles.jcc_t;
1387 /* ASG - can probably assume this is safe
1388 		CHANGE_PC(I.pc);*/
1389 	} else ICOUNT -= cycles.jcc_nt;
1390 }
1391 
PREFIX86(_jno)1392 static void PREFIX86(_jno)(void)    /* Opcode 0x71 */
1393 {
1394 	int tmp = (int)((INT8)FETCH);
1395 	if (!OF) {
1396 		I.pc += tmp;
1397 		ICOUNT -= cycles.jcc_t;
1398 /* ASG - can probably assume this is safe
1399 		CHANGE_PC(I.pc);*/
1400 	} else ICOUNT -= cycles.jcc_nt;
1401 }
1402 
PREFIX86(_jb)1403 static void PREFIX86(_jb)(void)    /* Opcode 0x72 */
1404 {
1405 	int tmp = (int)((INT8)FETCH);
1406 	if (CF) {
1407 		I.pc += tmp;
1408 		ICOUNT -= cycles.jcc_t;
1409 /* ASG - can probably assume this is safe
1410 		CHANGE_PC(I.pc);*/
1411 	} else ICOUNT -= cycles.jcc_nt;
1412 }
1413 
PREFIX86(_jnb)1414 static void PREFIX86(_jnb)(void)    /* Opcode 0x73 */
1415 {
1416 	int tmp = (int)((INT8)FETCH);
1417 	if (!CF) {
1418 		I.pc += tmp;
1419 		ICOUNT -= cycles.jcc_t;
1420 /* ASG - can probably assume this is safe
1421 		CHANGE_PC(I.pc);*/
1422 	} else ICOUNT -= cycles.jcc_nt;
1423 }
1424 
PREFIX86(_jz)1425 static void PREFIX86(_jz)(void)    /* Opcode 0x74 */
1426 {
1427 	int tmp = (int)((INT8)FETCH);
1428 	if (ZF) {
1429 		I.pc += tmp;
1430 		ICOUNT -= cycles.jcc_t;
1431 /* ASG - can probably assume this is safe
1432 		CHANGE_PC(I.pc);*/
1433 	} else ICOUNT -= cycles.jcc_nt;
1434 }
1435 
PREFIX86(_jnz)1436 static void PREFIX86(_jnz)(void)    /* Opcode 0x75 */
1437 {
1438 	int tmp = (int)((INT8)FETCH);
1439 	if (!ZF) {
1440 		I.pc += tmp;
1441 		ICOUNT -= cycles.jcc_t;
1442 /* ASG - can probably assume this is safe
1443 		CHANGE_PC(I.pc);*/
1444 	} else ICOUNT -= cycles.jcc_nt;
1445 }
1446 
PREFIX86(_jbe)1447 static void PREFIX86(_jbe)(void)    /* Opcode 0x76 */
1448 {
1449 	int tmp = (int)((INT8)FETCH);
1450     if (CF || ZF) {
1451 		I.pc += tmp;
1452 		ICOUNT -= cycles.jcc_t;
1453 /* ASG - can probably assume this is safe
1454 		CHANGE_PC(I.pc);*/
1455 	} else ICOUNT -= cycles.jcc_nt;
1456 }
1457 
PREFIX86(_jnbe)1458 static void PREFIX86(_jnbe)(void)    /* Opcode 0x77 */
1459 {
1460 	int tmp = (int)((INT8)FETCH);
1461 	 if (!(CF || ZF)) {
1462 		I.pc += tmp;
1463 		ICOUNT -= cycles.jcc_t;
1464 /* ASG - can probably assume this is safe
1465 		CHANGE_PC(I.pc);*/
1466 	} else ICOUNT -= cycles.jcc_nt;
1467 }
1468 
PREFIX86(_js)1469 static void PREFIX86(_js)(void)    /* Opcode 0x78 */
1470 {
1471 	int tmp = (int)((INT8)FETCH);
1472     if (SF) {
1473 		I.pc += tmp;
1474 		ICOUNT -= cycles.jcc_t;
1475 /* ASG - can probably assume this is safe
1476 		CHANGE_PC(I.pc);*/
1477 	} else ICOUNT -= cycles.jcc_nt;
1478 }
1479 
PREFIX86(_jns)1480 static void PREFIX86(_jns)(void)    /* Opcode 0x79 */
1481 {
1482 	int tmp = (int)((INT8)FETCH);
1483     if (!SF) {
1484 		I.pc += tmp;
1485 		ICOUNT -= cycles.jcc_t;
1486 /* ASG - can probably assume this is safe
1487 		CHANGE_PC(I.pc);*/
1488 	} else ICOUNT -= cycles.jcc_nt;
1489 }
1490 
PREFIX86(_jp)1491 static void PREFIX86(_jp)(void)    /* Opcode 0x7a */
1492 {
1493 	int tmp = (int)((INT8)FETCH);
1494     if (PF) {
1495 		I.pc += tmp;
1496 		ICOUNT -= cycles.jcc_t;
1497 /* ASG - can probably assume this is safe
1498 		CHANGE_PC(I.pc);*/
1499 	} else ICOUNT -= cycles.jcc_nt;
1500 }
1501 
PREFIX86(_jnp)1502 static void PREFIX86(_jnp)(void)    /* Opcode 0x7b */
1503 {
1504 	int tmp = (int)((INT8)FETCH);
1505     if (!PF) {
1506 		I.pc += tmp;
1507 		ICOUNT -= cycles.jcc_t;
1508 /* ASG - can probably assume this is safe
1509 		CHANGE_PC(I.pc);*/
1510 	} else ICOUNT -= cycles.jcc_nt;
1511 }
1512 
PREFIX86(_jl)1513 static void PREFIX86(_jl)(void)    /* Opcode 0x7c */
1514 {
1515 	int tmp = (int)((INT8)FETCH);
1516     if ((SF!=OF)&&!ZF) {
1517 		I.pc += tmp;
1518 		ICOUNT -= cycles.jcc_t;
1519 /* ASG - can probably assume this is safe
1520 		CHANGE_PC(I.pc);*/
1521 	} else ICOUNT -= cycles.jcc_nt;
1522 }
1523 
PREFIX86(_jnl)1524 static void PREFIX86(_jnl)(void)    /* Opcode 0x7d */
1525 {
1526 	int tmp = (int)((INT8)FETCH);
1527     if (ZF||(SF==OF)) {
1528 		I.pc += tmp;
1529 		ICOUNT -= cycles.jcc_t;
1530 /* ASG - can probably assume this is safe
1531 		CHANGE_PC(I.pc);*/
1532 	} else ICOUNT -= cycles.jcc_nt;
1533 }
1534 
PREFIX86(_jle)1535 static void PREFIX86(_jle)(void)    /* Opcode 0x7e */
1536 {
1537 	int tmp = (int)((INT8)FETCH);
1538     if (ZF||(SF!=OF)) {
1539 		I.pc += tmp;
1540 		ICOUNT -= cycles.jcc_t;
1541 /* ASG - can probably assume this is safe
1542 		CHANGE_PC(I.pc);*/
1543 	} else ICOUNT -= cycles.jcc_nt;
1544 }
1545 
PREFIX86(_jnle)1546 static void PREFIX86(_jnle)(void)    /* Opcode 0x7f */
1547 {
1548 	int tmp = (int)((INT8)FETCH);
1549     if ((SF==OF)&&!ZF) {
1550 		I.pc += tmp;
1551 		ICOUNT -= cycles.jcc_t;
1552 /* ASG - can probably assume this is safe
1553 		CHANGE_PC(I.pc);*/
1554 	} else ICOUNT -= cycles.jcc_nt;
1555 }
1556 
PREFIX86(_80pre)1557 static void PREFIX86(_80pre)(void)    /* Opcode 0x80 */
1558 {
1559 	unsigned ModRM = FETCHOP;
1560 	unsigned dst = GetRMByte(ModRM);
1561     unsigned src = FETCH;
1562 
1563     switch (ModRM & 0x38)
1564 	{
1565     case 0x00:  /* ADD eb,d8 */
1566         ADDB(dst,src);
1567         PutbackRMByte(ModRM,dst);
1568         ICOUNT -= (ModRM >= 0xc0) ? cycles.alu_ri8 : cycles.alu_mi8;
1569 		break;
1570     case 0x08:  /* OR eb,d8 */
1571         ORB(dst,src);
1572 		PutbackRMByte(ModRM,dst);
1573         ICOUNT -= (ModRM >= 0xc0) ? cycles.alu_ri8 : cycles.alu_mi8;
1574 		break;
1575     case 0x10:  /* ADC eb,d8 */
1576         src+=CF;
1577         ADDB(dst,src);
1578 		PutbackRMByte(ModRM,dst);
1579         ICOUNT -= (ModRM >= 0xc0) ? cycles.alu_ri8 : cycles.alu_mi8;
1580 		break;
1581     case 0x18:  /* SBB eb,b8 */
1582 		src+=CF;
1583 		SUBB(dst,src);
1584         PutbackRMByte(ModRM,dst);
1585         ICOUNT -= (ModRM >= 0xc0) ? cycles.alu_ri8 : cycles.alu_mi8;
1586 		break;
1587     case 0x20:  /* AND eb,d8 */
1588         ANDB(dst,src);
1589 		PutbackRMByte(ModRM,dst);
1590         ICOUNT -= (ModRM >= 0xc0) ? cycles.alu_ri8 : cycles.alu_mi8;
1591 		break;
1592     case 0x28:  /* SUB eb,d8 */
1593         SUBB(dst,src);
1594         PutbackRMByte(ModRM,dst);
1595         ICOUNT -= (ModRM >= 0xc0) ? cycles.alu_ri8 : cycles.alu_mi8;
1596 		break;
1597     case 0x30:  /* XOR eb,d8 */
1598         XORB(dst,src);
1599 		PutbackRMByte(ModRM,dst);
1600         ICOUNT -= (ModRM >= 0xc0) ? cycles.alu_ri8 : cycles.alu_mi8;
1601 		break;
1602     case 0x38:  /* CMP eb,d8 */
1603         SUBB(dst,src);
1604         ICOUNT -= (ModRM >= 0xc0) ? cycles.alu_ri8 : cycles.alu_mi8_ro;
1605 		break;
1606 	}
1607 }
1608 
1609 
PREFIX86(_81pre)1610 static void PREFIX86(_81pre)(void)    /* Opcode 0x81 */
1611 {
1612 	unsigned ModRM = FETCH;
1613 	unsigned dst = GetRMWord(ModRM);
1614     unsigned src = FETCH;
1615     src+= (FETCH << 8);
1616 
1617 	switch (ModRM & 0x38)
1618     {
1619     case 0x00:  /* ADD ew,d16 */
1620 		ADDW(dst,src);
1621 		PutbackRMWord(ModRM,dst);
1622         ICOUNT -= (ModRM >= 0xc0) ? cycles.alu_ri16 : cycles.alu_mi16;
1623 		break;
1624     case 0x08:  /* OR ew,d16 */
1625         ORW(dst,src);
1626         PutbackRMWord(ModRM,dst);
1627         ICOUNT -= (ModRM >= 0xc0) ? cycles.alu_ri16 : cycles.alu_mi16;
1628 		break;
1629 	case 0x10:	/* ADC ew,d16 */
1630 		src+=CF;
1631 		ADDW(dst,src);
1632         PutbackRMWord(ModRM,dst);
1633         ICOUNT -= (ModRM >= 0xc0) ? cycles.alu_ri16 : cycles.alu_mi16;
1634 		break;
1635     case 0x18:  /* SBB ew,d16 */
1636         src+=CF;
1637 		SUBW(dst,src);
1638         PutbackRMWord(ModRM,dst);
1639         ICOUNT -= (ModRM >= 0xc0) ? cycles.alu_ri16 : cycles.alu_mi16;
1640 		break;
1641     case 0x20:  /* AND ew,d16 */
1642         ANDW(dst,src);
1643 		PutbackRMWord(ModRM,dst);
1644         ICOUNT -= (ModRM >= 0xc0) ? cycles.alu_ri16 : cycles.alu_mi16;
1645 		break;
1646     case 0x28:  /* SUB ew,d16 */
1647         SUBW(dst,src);
1648         PutbackRMWord(ModRM,dst);
1649         ICOUNT -= (ModRM >= 0xc0) ? cycles.alu_ri16 : cycles.alu_mi16;
1650 		break;
1651     case 0x30:  /* XOR ew,d16 */
1652 		XORW(dst,src);
1653         PutbackRMWord(ModRM,dst);
1654         ICOUNT -= (ModRM >= 0xc0) ? cycles.alu_ri16 : cycles.alu_mi16;
1655 		break;
1656     case 0x38:  /* CMP ew,d16 */
1657         SUBW(dst,src);
1658         ICOUNT -= (ModRM >= 0xc0) ? cycles.alu_ri16 : cycles.alu_mi16_ro;
1659 		break;
1660     }
1661 }
1662 
PREFIX86(_82pre)1663 static void PREFIX86(_82pre)(void)	 /* Opcode 0x82 */
1664 {
1665 	unsigned ModRM = FETCH;
1666 	unsigned dst = GetRMByte(ModRM);
1667 	unsigned src = FETCH;
1668 
1669 	switch (ModRM & 0x38)
1670 	{
1671 	case 0x00:	/* ADD eb,d8 */
1672 		ADDB(dst,src);
1673 		PutbackRMByte(ModRM,dst);
1674         ICOUNT -= (ModRM >= 0xc0) ? cycles.alu_ri8 : cycles.alu_mi8;
1675 		break;
1676 	case 0x08:	/* OR eb,d8 */
1677 		ORB(dst,src);
1678 		PutbackRMByte(ModRM,dst);
1679         ICOUNT -= (ModRM >= 0xc0) ? cycles.alu_ri8 : cycles.alu_mi8;
1680 		break;
1681 	case 0x10:	/* ADC eb,d8 */
1682 		src+=CF;
1683 		ADDB(dst,src);
1684 		PutbackRMByte(ModRM,dst);
1685         ICOUNT -= (ModRM >= 0xc0) ? cycles.alu_ri8 : cycles.alu_mi8;
1686 		break;
1687 	case 0x18:	/* SBB eb,d8 */
1688         src+=CF;
1689 		SUBB(dst,src);
1690 		PutbackRMByte(ModRM,dst);
1691         ICOUNT -= (ModRM >= 0xc0) ? cycles.alu_ri8 : cycles.alu_mi8;
1692 		break;
1693 	case 0x20:	/* AND eb,d8 */
1694 		ANDB(dst,src);
1695 		PutbackRMByte(ModRM,dst);
1696         ICOUNT -= (ModRM >= 0xc0) ? cycles.alu_ri8 : cycles.alu_mi8;
1697 		break;
1698 	case 0x28:	/* SUB eb,d8 */
1699 		SUBB(dst,src);
1700 		PutbackRMByte(ModRM,dst);
1701         ICOUNT -= (ModRM >= 0xc0) ? cycles.alu_ri8 : cycles.alu_mi8;
1702 		break;
1703 	case 0x30:	/* XOR eb,d8 */
1704 		XORB(dst,src);
1705 		PutbackRMByte(ModRM,dst);
1706         ICOUNT -= (ModRM >= 0xc0) ? cycles.alu_ri8 : cycles.alu_mi8;
1707 		break;
1708 	case 0x38:	/* CMP eb,d8 */
1709 		SUBB(dst,src);
1710         ICOUNT -= (ModRM >= 0xc0) ? cycles.alu_ri8 : cycles.alu_mi8_ro;
1711 		break;
1712 	}
1713 }
1714 
PREFIX86(_83pre)1715 static void PREFIX86(_83pre)(void)    /* Opcode 0x83 */
1716 {
1717 	unsigned ModRM = FETCH;
1718     unsigned dst = GetRMWord(ModRM);
1719     unsigned src = (WORD)((INT16)((INT8)FETCH));
1720 
1721 	switch (ModRM & 0x38)
1722     {
1723     case 0x00:  /* ADD ew,d16 */
1724         ADDW(dst,src);
1725         PutbackRMWord(ModRM,dst);
1726         ICOUNT -= (ModRM >= 0xc0) ? cycles.alu_r16i8 : cycles.alu_m16i8;
1727 		break;
1728     case 0x08:  /* OR ew,d16 */
1729 		ORW(dst,src);
1730         PutbackRMWord(ModRM,dst);
1731         ICOUNT -= (ModRM >= 0xc0) ? cycles.alu_r16i8 : cycles.alu_m16i8;
1732 		break;
1733     case 0x10:  /* ADC ew,d16 */
1734         src+=CF;
1735 		ADDW(dst,src);
1736         PutbackRMWord(ModRM,dst);
1737         ICOUNT -= (ModRM >= 0xc0) ? cycles.alu_r16i8 : cycles.alu_m16i8;
1738 		break;
1739 	case 0x18:	/* SBB ew,d16 */
1740 		src+=CF;
1741         SUBW(dst,src);
1742         PutbackRMWord(ModRM,dst);
1743         ICOUNT -= (ModRM >= 0xc0) ? cycles.alu_r16i8 : cycles.alu_m16i8;
1744 		break;
1745 	case 0x20:	/* AND ew,d16 */
1746         ANDW(dst,src);
1747         PutbackRMWord(ModRM,dst);
1748         ICOUNT -= (ModRM >= 0xc0) ? cycles.alu_r16i8 : cycles.alu_m16i8;
1749 		break;
1750     case 0x28:  /* SUB ew,d16 */
1751 		SUBW(dst,src);
1752 		PutbackRMWord(ModRM,dst);
1753         ICOUNT -= (ModRM >= 0xc0) ? cycles.alu_r16i8 : cycles.alu_m16i8;
1754 		break;
1755     case 0x30:  /* XOR ew,d16 */
1756 		XORW(dst,src);
1757         PutbackRMWord(ModRM,dst);
1758         ICOUNT -= (ModRM >= 0xc0) ? cycles.alu_r16i8 : cycles.alu_m16i8;
1759 		break;
1760     case 0x38:  /* CMP ew,d16 */
1761         SUBW(dst,src);
1762         ICOUNT -= (ModRM >= 0xc0) ? cycles.alu_r16i8 : cycles.alu_m16i8_ro;
1763 		break;
1764     }
1765 }
1766 
PREFIX86(_test_br8)1767 static void PREFIX86(_test_br8)(void)    /* Opcode 0x84 */
1768 {
1769     DEF_br8(dst,src);
1770 	ICOUNT -= (ModRM >= 0xc0) ? cycles.alu_rr8 : cycles.alu_rm8;
1771     ANDB(dst,src);
1772 }
1773 
PREFIX86(_test_wr16)1774 static void PREFIX86(_test_wr16)(void)    /* Opcode 0x85 */
1775 {
1776     DEF_wr16(dst,src);
1777 	ICOUNT -= (ModRM >= 0xc0) ? cycles.alu_rr16 : cycles.alu_rm16;
1778 	ANDW(dst,src);
1779 }
1780 
PREFIX86(_xchg_br8)1781 static void PREFIX86(_xchg_br8)(void)    /* Opcode 0x86 */
1782 {
1783     DEF_br8(dst,src);
1784 	ICOUNT -= (ModRM >= 0xc0) ? cycles.xchg_rr8 : cycles.xchg_rm8;
1785     RegByte(ModRM)=dst;
1786     PutbackRMByte(ModRM,src);
1787 }
1788 
PREFIX86(_xchg_wr16)1789 static void PREFIX86(_xchg_wr16)(void)    /* Opcode 0x87 */
1790 {
1791     DEF_wr16(dst,src);
1792 	ICOUNT -= (ModRM >= 0xc0) ? cycles.xchg_rr16 : cycles.xchg_rm16;
1793     RegWord(ModRM)=dst;
1794     PutbackRMWord(ModRM,src);
1795 }
1796 
PREFIX86(_mov_br8)1797 static void PREFIX86(_mov_br8)(void)    /* Opcode 0x88 */
1798 {
1799 	unsigned ModRM = FETCH;
1800     BYTE src = RegByte(ModRM);
1801 	ICOUNT -= (ModRM >= 0xc0) ? cycles.mov_rr8 : cycles.mov_mr8;
1802     PutRMByte(ModRM,src);
1803 }
1804 
PREFIX86(_mov_wr16)1805 static void PREFIX86(_mov_wr16)(void)    /* Opcode 0x89 */
1806 {
1807 	unsigned ModRM = FETCH;
1808     WORD src = RegWord(ModRM);
1809 	ICOUNT -= (ModRM >= 0xc0) ? cycles.mov_rr16 : cycles.mov_mr16;
1810     PutRMWord(ModRM,src);
1811 }
1812 
PREFIX86(_mov_r8b)1813 static void PREFIX86(_mov_r8b)(void)    /* Opcode 0x8a */
1814 {
1815 	unsigned ModRM = FETCH;
1816     BYTE src = GetRMByte(ModRM);
1817 	ICOUNT -= (ModRM >= 0xc0) ? cycles.mov_rr8 : cycles.mov_rm8;
1818     RegByte(ModRM)=src;
1819 }
1820 
PREFIX86(_mov_r16w)1821 static void PREFIX86(_mov_r16w)(void)    /* Opcode 0x8b */
1822 {
1823 	unsigned ModRM = FETCH;
1824 	WORD src = GetRMWord(ModRM);
1825 	ICOUNT -= (ModRM >= 0xc0) ? cycles.mov_rr8 : cycles.mov_rm16;
1826 	RegWord(ModRM)=src;
1827 }
1828 
PREFIX86(_mov_wsreg)1829 static void PREFIX86(_mov_wsreg)(void)    /* Opcode 0x8c */
1830 {
1831 	unsigned ModRM = FETCH;
1832 	ICOUNT -= (ModRM >= 0xc0) ? cycles.mov_rs : cycles.mov_ms;
1833 #ifdef I286
1834 	if (ModRM & 0x20) {	/* HJB 12/13/98 1xx is invalid */
1835 		i286_trap2(ILLEGAL_INSTRUCTION);
1836 		return;
1837 	}
1838 #else
1839 	if (ModRM & 0x20) return;	/* HJB 12/13/98 1xx is invalid */
1840 #endif
1841 	PutRMWord(ModRM,I.sregs[(ModRM & 0x38) >> 3]);
1842 }
1843 
PREFIX86(_lea)1844 static void PREFIX86(_lea)(void)    /* Opcode 0x8d */
1845 {
1846 	unsigned ModRM = FETCH;
1847 	ICOUNT -= cycles.lea;
1848 	(void)(*GetEA[ModRM])();
1849 	RegWord(ModRM)=EO;	/* HJB 12/13/98 effective offset (no segment part) */
1850 }
1851 
PREFIX86(_mov_sregw)1852 static void PREFIX86(_mov_sregw)(void)    /* Opcode 0x8e */
1853 {
1854 	unsigned ModRM = FETCH;
1855     WORD src = GetRMWord(ModRM);
1856 
1857 	ICOUNT -= (ModRM >= 0xc0) ? cycles.mov_sr : cycles.mov_sm;
1858 #ifdef I286
1859     switch (ModRM & 0x38)
1860     {
1861     case 0x00:  /* mov es,ew */
1862 		i286_data_descriptor(ES,src);
1863 		break;
1864     case 0x18:  /* mov ds,ew */
1865 		i286_data_descriptor(DS,src);
1866 		break;
1867     case 0x10:  /* mov ss,ew */
1868 		i286_data_descriptor(SS,src);
1869 		PREFIX(_instruction)[FETCHOP]();
1870 		break;
1871     case 0x08:  /* mov cs,ew */
1872 		break;  /* doesn't do a jump far */
1873     }
1874 #else
1875     switch (ModRM & 0x38)
1876     {
1877     case 0x00:  /* mov es,ew */
1878 		I.sregs[ES] = src;
1879 		I.base[ES] = SegBase(ES);
1880 		break;
1881     case 0x18:  /* mov ds,ew */
1882 		I.sregs[DS] = src;
1883 		I.base[DS] = SegBase(DS);
1884 		break;
1885     case 0x10:  /* mov ss,ew */
1886 		I.sregs[SS] = src;
1887 		I.base[SS] = SegBase(SS); /* no interrupt allowed before next instr */
1888 		PREFIX(_instruction)[FETCHOP]();
1889 		break;
1890     case 0x08:  /* mov cs,ew */
1891 		break;  /* doesn't do a jump far */
1892     }
1893 #endif
1894 }
1895 
PREFIX86(_popw)1896 static void PREFIX86(_popw)(void)    /* Opcode 0x8f */
1897 {
1898 	unsigned ModRM = FETCH;
1899     WORD tmp;
1900 	POP(tmp);
1901 	ICOUNT -= (ModRM >= 0xc0) ? cycles.pop_r16 : cycles.pop_m16;
1902 	PutRMWord(ModRM,tmp);
1903 }
1904 
1905 
1906 #define XchgAXReg(Reg) 				\
1907 { 									\
1908     WORD tmp; 						\
1909 	tmp = I.regs.w[Reg]; 			\
1910 	I.regs.w[Reg] = I.regs.w[AX]; 	\
1911 	I.regs.w[AX] = tmp; 			\
1912 	ICOUNT -= cycles.xchg_ar16; 	\
1913 }
1914 
1915 
PREFIX86(_nop)1916 static void PREFIX86(_nop)(void)    /* Opcode 0x90 */
1917 {
1918     /* this is XchgAXReg(AX); */
1919 	ICOUNT -= cycles.nop;
1920 }
1921 
PREFIX86(_xchg_axcx)1922 static void PREFIX86(_xchg_axcx)(void)    /* Opcode 0x91 */
1923 {
1924 	XchgAXReg(CX);
1925 }
1926 
PREFIX86(_xchg_axdx)1927 static void PREFIX86(_xchg_axdx)(void)    /* Opcode 0x92 */
1928 {
1929     XchgAXReg(DX);
1930 }
1931 
PREFIX86(_xchg_axbx)1932 static void PREFIX86(_xchg_axbx)(void)    /* Opcode 0x93 */
1933 {
1934 	XchgAXReg(BX);
1935 }
1936 
PREFIX86(_xchg_axsp)1937 static void PREFIX86(_xchg_axsp)(void)    /* Opcode 0x94 */
1938 {
1939 	XchgAXReg(SP);
1940 }
1941 
PREFIX86(_xchg_axbp)1942 static void PREFIX86(_xchg_axbp)(void)    /* Opcode 0x95 */
1943 {
1944     XchgAXReg(BP);
1945 }
1946 
PREFIX86(_xchg_axsi)1947 static void PREFIX86(_xchg_axsi)(void)    /* Opcode 0x96 */
1948 {
1949 	XchgAXReg(SI);
1950 }
1951 
PREFIX86(_xchg_axdi)1952 static void PREFIX86(_xchg_axdi)(void)    /* Opcode 0x97 */
1953 {
1954 	XchgAXReg(DI);
1955 }
1956 
PREFIX86(_cbw)1957 static void PREFIX86(_cbw)(void)    /* Opcode 0x98 */
1958 {
1959 	ICOUNT -= cycles.cbw;
1960 	I.regs.b[AH] = (I.regs.b[AL] & 0x80) ? 0xff : 0;
1961 }
1962 
PREFIX86(_cwd)1963 static void PREFIX86(_cwd)(void)    /* Opcode 0x99 */
1964 {
1965 	ICOUNT -= cycles.cwd;
1966 	I.regs.w[DX] = (I.regs.b[AH] & 0x80) ? 0xffff : 0;
1967 }
1968 
PREFIX86(_call_far)1969 static void PREFIX86(_call_far)(void)
1970 {
1971     unsigned tmp, tmp2;
1972 	WORD ip;
1973 
1974 	tmp = FETCH;
1975 	tmp += FETCH << 8;
1976 
1977 	tmp2 = FETCH;
1978 	tmp2 += FETCH << 8;
1979 
1980 	ip = I.pc - I.base[CS];
1981 	PUSH(I.sregs[CS]);
1982 	PUSH(ip);
1983 
1984 #ifdef I286
1985 	i286_code_descriptor(tmp2, tmp);
1986 #else
1987 	I.sregs[CS] = (WORD)tmp2;
1988 	I.base[CS] = SegBase(CS);
1989 	I.pc = (I.base[CS] + (WORD)tmp) & AMASK;
1990 #endif
1991 	ICOUNT -= cycles.call_far;
1992 	CHANGE_PC(I.pc);
1993 }
1994 
PREFIX86(_wait)1995 static void PREFIX86(_wait)(void)    /* Opcode 0x9b */
1996 {
1997 	ICOUNT -= cycles.wait;
1998 }
1999 
PREFIX86(_pushf)2000 static void PREFIX86(_pushf)(void)    /* Opcode 0x9c */
2001 {
2002 	ICOUNT -= cycles.pushf;
2003 #ifdef I286
2004     PUSH( CompressFlags() | 0xc000 );
2005 #elif defined V20
2006     PUSH( CompressFlags() | 0xe000 );
2007 #else
2008     PUSH( CompressFlags() | 0xf000 );
2009 #endif
2010 }
2011 
PREFIX86(_popf)2012 static void PREFIX86(_popf)(void)    /* Opcode 0x9d */
2013 {
2014 	unsigned tmp;
2015     POP(tmp);
2016 	ICOUNT -= cycles.popf;
2017     ExpandFlags(tmp);
2018 
2019 	if (I.TF) PREFIX(_trap)();
2020 
2021 	/* if the IF is set, and an interrupt is pending, signal an interrupt */
2022 	if (I.IF && I.irq_state)
2023 #ifdef V20
2024 		PREFIX(_interrupt)(-1, 0);
2025 #else
2026 		PREFIX(_interrupt)(-1);
2027 #endif
2028 }
2029 
PREFIX86(_sahf)2030 static void PREFIX86(_sahf)(void)    /* Opcode 0x9e */
2031 {
2032 	unsigned tmp = (CompressFlags() & 0xff00) | (I.regs.b[AH] & 0xd5);
2033 	ICOUNT -= cycles.sahf;
2034     ExpandFlags(tmp);
2035 }
2036 
PREFIX86(_lahf)2037 static void PREFIX86(_lahf)(void)    /* Opcode 0x9f */
2038 {
2039 	I.regs.b[AH] = CompressFlags() & 0xff;
2040 	ICOUNT -= cycles.lahf;
2041 }
2042 
2043 
PREFIX86(_mov_aldisp)2044 static void PREFIX86(_mov_aldisp)(void)    /* Opcode 0xa0 */
2045 {
2046 	unsigned addr;
2047 
2048 	addr = FETCH;
2049 	addr += FETCH << 8;
2050 
2051 	ICOUNT -= cycles.mov_am8;
2052 	I.regs.b[AL] = GetMemB(DS, addr);
2053 }
2054 
PREFIX86(_mov_axdisp)2055 static void PREFIX86(_mov_axdisp)(void)    /* Opcode 0xa1 */
2056 {
2057 	unsigned addr;
2058 
2059 	addr = FETCH;
2060 	addr += FETCH << 8;
2061 
2062 	ICOUNT -= cycles.mov_am16;
2063 	I.regs.b[AL] = GetMemB(DS, addr);
2064 	I.regs.b[AH] = GetMemB(DS, addr+1);
2065 }
2066 
PREFIX86(_mov_dispal)2067 static void PREFIX86(_mov_dispal)(void)    /* Opcode 0xa2 */
2068 {
2069     unsigned addr;
2070 
2071 	addr = FETCH;
2072 	addr += FETCH << 8;
2073 
2074 	ICOUNT -= cycles.mov_ma8;
2075 	PutMemB(DS, addr, I.regs.b[AL]);
2076 }
2077 
PREFIX86(_mov_dispax)2078 static void PREFIX86(_mov_dispax)(void)    /* Opcode 0xa3 */
2079 {
2080 	unsigned addr;
2081 
2082 	addr = FETCH;
2083 	addr += FETCH << 8;
2084 
2085 	ICOUNT -= cycles.mov_ma16;
2086 	PutMemB(DS, addr, I.regs.b[AL]);
2087 	PutMemB(DS, addr+1, I.regs.b[AH]);
2088 }
2089 
PREFIX86(_movsb)2090 static void PREFIX86(_movsb)(void)    /* Opcode 0xa4 */
2091 {
2092 	BYTE tmp = GetMemB(DS,I.regs.w[SI]);
2093 	PutMemB(ES,I.regs.w[DI], tmp);
2094 	I.regs.w[DI] += I.DirVal;
2095 	I.regs.w[SI] += I.DirVal;
2096 	ICOUNT -= cycles.movs8;
2097 }
2098 
PREFIX86(_movsw)2099 static void PREFIX86(_movsw)(void)    /* Opcode 0xa5 */
2100 {
2101 	WORD tmp = GetMemW(DS,I.regs.w[SI]);
2102 	PutMemW(ES,I.regs.w[DI], tmp);
2103 	I.regs.w[DI] += 2 * I.DirVal;
2104 	I.regs.w[SI] += 2 * I.DirVal;
2105 	ICOUNT -= cycles.movs16;
2106 }
2107 
PREFIX86(_cmpsb)2108 static void PREFIX86(_cmpsb)(void)    /* Opcode 0xa6 */
2109 {
2110 	unsigned dst = GetMemB(ES, I.regs.w[DI]);
2111 	unsigned src = GetMemB(DS, I.regs.w[SI]);
2112     SUBB(src,dst); /* opposite of the usual convention */
2113 	I.regs.w[DI] += I.DirVal;
2114 	I.regs.w[SI] += I.DirVal;
2115 	ICOUNT -= cycles.cmps8;
2116 }
2117 
PREFIX86(_cmpsw)2118 static void PREFIX86(_cmpsw)(void)    /* Opcode 0xa7 */
2119 {
2120 	unsigned dst = GetMemW(ES, I.regs.w[DI]);
2121 	unsigned src = GetMemW(DS, I.regs.w[SI]);
2122 	SUBW(src,dst); /* opposite of the usual convention */
2123 	I.regs.w[DI] += 2 * I.DirVal;
2124 	I.regs.w[SI] += 2 * I.DirVal;
2125 	ICOUNT -= cycles.cmps16;
2126 }
2127 
PREFIX86(_test_ald8)2128 static void PREFIX86(_test_ald8)(void)    /* Opcode 0xa8 */
2129 {
2130     DEF_ald8(dst,src);
2131 	ICOUNT -= cycles.alu_ri8;
2132     ANDB(dst,src);
2133 }
2134 
PREFIX86(_test_axd16)2135 static void PREFIX86(_test_axd16)(void)    /* Opcode 0xa9 */
2136 {
2137     DEF_axd16(dst,src);
2138 	ICOUNT -= cycles.alu_ri16;
2139     ANDW(dst,src);
2140 }
2141 
PREFIX86(_stosb)2142 static void PREFIX86(_stosb)(void)    /* Opcode 0xaa */
2143 {
2144 	PutMemB(ES,I.regs.w[DI],I.regs.b[AL]);
2145 	I.regs.w[DI] += I.DirVal;
2146 	ICOUNT -= cycles.stos8;
2147 }
2148 
PREFIX86(_stosw)2149 static void PREFIX86(_stosw)(void)    /* Opcode 0xab */
2150 {
2151 	PutMemB(ES,I.regs.w[DI],I.regs.b[AL]);
2152 	PutMemB(ES,I.regs.w[DI]+1,I.regs.b[AH]);
2153 	I.regs.w[DI] += 2 * I.DirVal;
2154 	ICOUNT -= cycles.stos16;
2155 }
2156 
PREFIX86(_lodsb)2157 static void PREFIX86(_lodsb)(void)    /* Opcode 0xac */
2158 {
2159 	I.regs.b[AL] = GetMemB(DS,I.regs.w[SI]);
2160 	I.regs.w[SI] += I.DirVal;
2161 	ICOUNT -= cycles.lods8;
2162 }
2163 
PREFIX86(_lodsw)2164 static void PREFIX86(_lodsw)(void)    /* Opcode 0xad */
2165 {
2166 	I.regs.w[AX] = GetMemW(DS,I.regs.w[SI]);
2167 	I.regs.w[SI] += 2 * I.DirVal;
2168 	ICOUNT -= cycles.lods16;
2169 }
2170 
PREFIX86(_scasb)2171 static void PREFIX86(_scasb)(void)    /* Opcode 0xae */
2172 {
2173 	unsigned src = GetMemB(ES, I.regs.w[DI]);
2174 	unsigned dst = I.regs.b[AL];
2175     SUBB(dst,src);
2176 	I.regs.w[DI] += I.DirVal;
2177 	ICOUNT -= cycles.scas8;
2178 }
2179 
PREFIX86(_scasw)2180 static void PREFIX86(_scasw)(void)    /* Opcode 0xaf */
2181 {
2182 	unsigned src = GetMemW(ES, I.regs.w[DI]);
2183 	unsigned dst = I.regs.w[AX];
2184     SUBW(dst,src);
2185 	I.regs.w[DI] += 2 * I.DirVal;
2186 	ICOUNT -= cycles.scas16;
2187 }
2188 
PREFIX86(_mov_ald8)2189 static void PREFIX86(_mov_ald8)(void)    /* Opcode 0xb0 */
2190 {
2191 	I.regs.b[AL] = FETCH;
2192 	ICOUNT -= cycles.mov_ri8;
2193 }
2194 
PREFIX86(_mov_cld8)2195 static void PREFIX86(_mov_cld8)(void)    /* Opcode 0xb1 */
2196 {
2197 	I.regs.b[CL] = FETCH;
2198 	ICOUNT -= cycles.mov_ri8;
2199 }
2200 
PREFIX86(_mov_dld8)2201 static void PREFIX86(_mov_dld8)(void)    /* Opcode 0xb2 */
2202 {
2203 	I.regs.b[DL] = FETCH;
2204 	ICOUNT -= cycles.mov_ri8;
2205 }
2206 
PREFIX86(_mov_bld8)2207 static void PREFIX86(_mov_bld8)(void)    /* Opcode 0xb3 */
2208 {
2209 	I.regs.b[BL] = FETCH;
2210 	ICOUNT -= cycles.mov_ri8;
2211 }
2212 
PREFIX86(_mov_ahd8)2213 static void PREFIX86(_mov_ahd8)(void)    /* Opcode 0xb4 */
2214 {
2215 	I.regs.b[AH] = FETCH;
2216 	ICOUNT -= cycles.mov_ri8;
2217 }
2218 
PREFIX86(_mov_chd8)2219 static void PREFIX86(_mov_chd8)(void)    /* Opcode 0xb5 */
2220 {
2221 	I.regs.b[CH] = FETCH;
2222 	ICOUNT -= cycles.mov_ri8;
2223 }
2224 
PREFIX86(_mov_dhd8)2225 static void PREFIX86(_mov_dhd8)(void)    /* Opcode 0xb6 */
2226 {
2227 	I.regs.b[DH] = FETCH;
2228 	ICOUNT -= cycles.mov_ri8;
2229 }
2230 
PREFIX86(_mov_bhd8)2231 static void PREFIX86(_mov_bhd8)(void)    /* Opcode 0xb7 */
2232 {
2233 	I.regs.b[BH] = FETCH;
2234 	ICOUNT -= cycles.mov_ri8;
2235 }
2236 
PREFIX86(_mov_axd16)2237 static void PREFIX86(_mov_axd16)(void)    /* Opcode 0xb8 */
2238 {
2239 	I.regs.b[AL] = FETCH;
2240 	I.regs.b[AH] = FETCH;
2241 	ICOUNT -= cycles.mov_ri16;
2242 }
2243 
PREFIX86(_mov_cxd16)2244 static void PREFIX86(_mov_cxd16)(void)    /* Opcode 0xb9 */
2245 {
2246 	I.regs.b[CL] = FETCH;
2247 	I.regs.b[CH] = FETCH;
2248 	ICOUNT -= cycles.mov_ri16;
2249 }
2250 
PREFIX86(_mov_dxd16)2251 static void PREFIX86(_mov_dxd16)(void)    /* Opcode 0xba */
2252 {
2253 	I.regs.b[DL] = FETCH;
2254 	I.regs.b[DH] = FETCH;
2255 	ICOUNT -= cycles.mov_ri16;
2256 }
2257 
PREFIX86(_mov_bxd16)2258 static void PREFIX86(_mov_bxd16)(void)    /* Opcode 0xbb */
2259 {
2260 	I.regs.b[BL] = FETCH;
2261 	I.regs.b[BH] = FETCH;
2262 	ICOUNT -= cycles.mov_ri16;
2263 }
2264 
PREFIX86(_mov_spd16)2265 static void PREFIX86(_mov_spd16)(void)    /* Opcode 0xbc */
2266 {
2267 	I.regs.b[SPL] = FETCH;
2268 	I.regs.b[SPH] = FETCH;
2269 	ICOUNT -= cycles.mov_ri16;
2270 }
2271 
PREFIX86(_mov_bpd16)2272 static void PREFIX86(_mov_bpd16)(void)    /* Opcode 0xbd */
2273 {
2274 	I.regs.b[BPL] = FETCH;
2275 	I.regs.b[BPH] = FETCH;
2276 	ICOUNT -= cycles.mov_ri16;
2277 }
2278 
PREFIX86(_mov_sid16)2279 static void PREFIX86(_mov_sid16)(void)    /* Opcode 0xbe */
2280 {
2281 	I.regs.b[SIL] = FETCH;
2282 	I.regs.b[SIH] = FETCH;
2283 	ICOUNT -= cycles.mov_ri16;
2284 }
2285 
PREFIX86(_mov_did16)2286 static void PREFIX86(_mov_did16)(void)    /* Opcode 0xbf */
2287 {
2288 	I.regs.b[DIL] = FETCH;
2289 	I.regs.b[DIH] = FETCH;
2290 	ICOUNT -= cycles.mov_ri16;
2291 }
2292 
PREFIX86(_ret_d16)2293 static void PREFIX86(_ret_d16)(void)    /* Opcode 0xc2 */
2294 {
2295 	unsigned count = FETCH;
2296 	count += FETCH << 8;
2297 	POP(I.pc);
2298 	I.pc = (I.pc + I.base[CS]) & AMASK;
2299 	I.regs.w[SP]+=count;
2300 	ICOUNT -= cycles.ret_near_imm;
2301 	CHANGE_PC(I.pc);
2302 }
2303 
PREFIX86(_ret)2304 static void PREFIX86(_ret)(void)    /* Opcode 0xc3 */
2305 {
2306 	POP(I.pc);
2307 	I.pc = (I.pc + I.base[CS]) & AMASK;
2308 	ICOUNT -= cycles.ret_near;
2309 	CHANGE_PC(I.pc);
2310 }
2311 
PREFIX86(_les_dw)2312 static void PREFIX86(_les_dw)(void)    /* Opcode 0xc4 */
2313 {
2314 	unsigned ModRM = FETCH;
2315     WORD tmp = GetRMWord(ModRM);
2316 
2317     RegWord(ModRM)= tmp;
2318 #ifdef I286
2319 	i286_data_descriptor(ES,GetnextRMWord);
2320 #else
2321 	I.sregs[ES] = GetnextRMWord;
2322 	I.base[ES] = SegBase(ES);
2323 #endif
2324 	ICOUNT -= cycles.load_ptr;
2325 }
2326 
PREFIX86(_lds_dw)2327 static void PREFIX86(_lds_dw)(void)    /* Opcode 0xc5 */
2328 {
2329 	unsigned ModRM = FETCH;
2330     WORD tmp = GetRMWord(ModRM);
2331 
2332     RegWord(ModRM)=tmp;
2333 #ifdef I286
2334 	i286_data_descriptor(DS,GetnextRMWord);
2335 #else
2336 	I.sregs[DS] = GetnextRMWord;
2337 	I.base[DS] = SegBase(DS);
2338 #endif
2339 	ICOUNT -= cycles.load_ptr;
2340 }
2341 
PREFIX86(_mov_bd8)2342 static void PREFIX86(_mov_bd8)(void)    /* Opcode 0xc6 */
2343 {
2344 	unsigned ModRM = FETCH;
2345 	ICOUNT -= (ModRM >= 0xc0) ? cycles.mov_ri8 : cycles.mov_mi8;
2346 	PutImmRMByte(ModRM);
2347 }
2348 
PREFIX86(_mov_wd16)2349 static void PREFIX86(_mov_wd16)(void)    /* Opcode 0xc7 */
2350 {
2351 	unsigned ModRM = FETCH;
2352 	ICOUNT -= (ModRM >= 0xc0) ? cycles.mov_ri16 : cycles.mov_mi16;
2353 	PutImmRMWord(ModRM);
2354 }
2355 
PREFIX86(_retf_d16)2356 static void PREFIX86(_retf_d16)(void)    /* Opcode 0xca */
2357 {
2358 	unsigned count = FETCH;
2359 	count += FETCH << 8;
2360 
2361 #ifdef I286
2362 	{
2363 		int tmp, tmp2;
2364 		POP(tmp2);
2365 		POP(tmp);
2366 		i286_code_descriptor(tmp, tmp2);
2367 	}
2368 #else
2369 	POP(I.pc);
2370 	POP(I.sregs[CS]);
2371 	I.base[CS] = SegBase(CS);
2372 	I.pc = (I.pc + I.base[CS]) & AMASK;
2373 #endif
2374 	I.regs.w[SP]+=count;
2375 	ICOUNT -= cycles.ret_far_imm;
2376 	CHANGE_PC(I.pc);
2377 }
2378 
PREFIX86(_retf)2379 static void PREFIX86(_retf)(void)    /* Opcode 0xcb */
2380 {
2381 #ifdef I286
2382 	{
2383 		int tmp, tmp2;
2384 		POP(tmp2);
2385 		POP(tmp);
2386 		i286_code_descriptor(tmp, tmp2);
2387 	}
2388 #else
2389 	POP(I.pc);
2390 	POP(I.sregs[CS]);
2391 	I.base[CS] = SegBase(CS);
2392 	I.pc = (I.pc + I.base[CS]) & AMASK;
2393 #endif
2394 	ICOUNT -= cycles.ret_far;
2395 	CHANGE_PC(I.pc);
2396 }
2397 
PREFIX86(_int3)2398 static void PREFIX86(_int3)(void)    /* Opcode 0xcc */
2399 {
2400 	ICOUNT -= cycles.int3;
2401 #ifdef V20
2402 	PREFIX(_interrupt)(3,0);
2403 #else
2404 	PREFIX(_interrupt)(3);
2405 #endif
2406 }
2407 
PREFIX86(_int)2408 static void PREFIX86(_int)(void)    /* Opcode 0xcd */
2409 {
2410 	unsigned int_num = FETCH;
2411 	ICOUNT -= cycles.int_imm;
2412 #ifdef V20
2413 	PREFIX(_interrupt)(int_num,0);
2414 #else
2415 	PREFIX(_interrupt)(int_num);
2416 #endif
2417 }
2418 
PREFIX86(_into)2419 static void PREFIX86(_into)(void)    /* Opcode 0xce */
2420 {
2421 	if (OF) {
2422 		ICOUNT -= cycles.into_t;
2423 #ifdef V20
2424 		PREFIX(_interrupt)(4,0);
2425 #else
2426 		PREFIX(_interrupt)(4);
2427 #endif
2428 	} else ICOUNT -= cycles.into_nt;
2429 }
2430 
PREFIX86(_iret)2431 static void PREFIX86(_iret)(void)    /* Opcode 0xcf */
2432 {
2433 	ICOUNT -= cycles.iret;
2434 #ifdef I286
2435 	{
2436 		int tmp, tmp2;
2437 		POP(tmp2);
2438 		POP(tmp);
2439 		i286_code_descriptor(tmp, tmp2);
2440 	}
2441 #else
2442 	POP(I.pc);
2443 	POP(I.sregs[CS]);
2444 	I.base[CS] = SegBase(CS);
2445 	I.pc = (I.pc + I.base[CS]) & AMASK;
2446 #endif
2447     PREFIX(_popf)();
2448 	CHANGE_PC(I.pc);
2449 
2450 	/* if the IF is set, and an interrupt is pending, signal an interrupt */
2451 	if (I.IF && I.irq_state)
2452 #ifdef V20
2453 		PREFIX(_interrupt)(-1, 0);
2454 #else
2455 		PREFIX(_interrupt)(-1);
2456 #endif
2457 }
2458 
PREFIX86(_rotshft_b)2459 static void PREFIX86(_rotshft_b)(void)    /* Opcode 0xd0 */
2460 {
2461 	PREFIX(_rotate_shift_Byte)(FETCHOP,1);
2462 }
2463 
2464 
PREFIX86(_rotshft_w)2465 static void PREFIX86(_rotshft_w)(void)    /* Opcode 0xd1 */
2466 {
2467 	PREFIX(_rotate_shift_Word)(FETCHOP,1);
2468 }
2469 
2470 
PREFIX86(_rotshft_bcl)2471 static void PREFIX86(_rotshft_bcl)(void)    /* Opcode 0xd2 */
2472 {
2473 	PREFIX(_rotate_shift_Byte)(FETCHOP,I.regs.b[CL]);
2474 }
2475 
PREFIX86(_rotshft_wcl)2476 static void PREFIX86(_rotshft_wcl)(void)    /* Opcode 0xd3 */
2477 {
2478 	PREFIX(_rotate_shift_Word)(FETCHOP,I.regs.b[CL]);
2479 }
2480 
2481 /* OB: Opcode works on NEC V-Series but not the Variants              */
2482 /*     one could specify any byte value as operand but the NECs */
2483 /*     always substitute 0x0a.              */
PREFIX86(_aam)2484 static void PREFIX86(_aam)(void)    /* Opcode 0xd4 */
2485 {
2486 	unsigned mult = FETCH;
2487 
2488 	ICOUNT -= cycles.aam;
2489 #ifndef V20
2490 	if (mult == 0)
2491 		PREFIX(_interrupt)(0);
2492 	else
2493 	{
2494 		I.regs.b[AH] = I.regs.b[AL] / mult;
2495 		I.regs.b[AL] %= mult;
2496 
2497 		SetSZPF_Word(I.regs.w[AX]);
2498 	}
2499 #else
2500 
2501 	if (mult == 0)
2502 		PREFIX(_interrupt)(0,0);
2503     else
2504     {
2505 		I.regs.b[AH] = I.regs.b[AL] / 10;
2506 		I.regs.b[AL] %= 10;
2507 		SetSZPF_Word(I.regs.w[AX]);
2508     }
2509 #endif
2510 }
2511 
PREFIX86(_aad)2512 static void PREFIX86(_aad)(void)    /* Opcode 0xd5 */
2513 {
2514 	unsigned mult = FETCH;
2515 
2516 	ICOUNT -= cycles.aad;
2517 
2518 #ifndef V20
2519 	I.regs.b[AL] = I.regs.b[AH] * mult + I.regs.b[AL];
2520 	I.regs.b[AH] = 0;
2521 
2522 	SetZF(I.regs.b[AL]);
2523 	SetPF(I.regs.b[AL]);
2524 	I.SignVal = 0;
2525 #else
2526 /* OB: Opcode works on NEC V-Series but not the Variants 	*/
2527 /*     one could specify any byte value as operand but the NECs */
2528 /*     always substitute 0x0a.					*/
2529 	I.regs.b[AL] = I.regs.b[AH] * 10 + I.regs.b[AL];
2530 	I.regs.b[AH] = 0;
2531 
2532 	SetZF(I.regs.b[AL]);
2533 	SetPF(I.regs.b[AL]);
2534 	I.SignVal = 0;
2535 	mult=0;
2536 #endif
2537 }
2538 
2539 
PREFIX86(_xlat)2540 static void PREFIX86(_xlat)(void)    /* Opcode 0xd7 */
2541 {
2542 	unsigned dest = I.regs.w[BX]+I.regs.b[AL];
2543 
2544 	ICOUNT -= cycles.xlat;
2545 	I.regs.b[AL] = GetMemB(DS, dest);
2546 }
2547 
PREFIX86(_escape)2548 static void PREFIX86(_escape)(void)    /* Opcodes 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde and 0xdf */
2549 {
2550 	unsigned ModRM = FETCH;
2551 	ICOUNT -= cycles.nop;
2552     GetRMByte(ModRM);
2553 }
2554 
PREFIX86(_loopne)2555 static void PREFIX86(_loopne)(void)    /* Opcode 0xe0 */
2556 {
2557 	int disp = (int)((INT8)FETCH);
2558 	unsigned tmp = I.regs.w[CX]-1;
2559 
2560 	I.regs.w[CX]=tmp;
2561 
2562     if (!ZF && tmp) {
2563 		ICOUNT -= cycles.loop_t;
2564 		I.pc += disp;
2565 /* ASG - can probably assume this is safe
2566 		CHANGE_PC(I.pc);*/
2567 	} else ICOUNT -= cycles.loop_nt;
2568 }
2569 
PREFIX86(_loope)2570 static void PREFIX86(_loope)(void)    /* Opcode 0xe1 */
2571 {
2572 	int disp = (int)((INT8)FETCH);
2573 	unsigned tmp = I.regs.w[CX]-1;
2574 
2575 	I.regs.w[CX]=tmp;
2576 
2577 	if (ZF && tmp) {
2578 		ICOUNT -= cycles.loope_t;
2579 		 I.pc += disp;
2580 /* ASG - can probably assume this is safe
2581 		 CHANGE_PC(I.pc);*/
2582 	 } else ICOUNT -= cycles.loope_nt;
2583 }
2584 
PREFIX86(_loop)2585 static void PREFIX86(_loop)(void)    /* Opcode 0xe2 */
2586 {
2587 	int disp = (int)((INT8)FETCH);
2588 	unsigned tmp = I.regs.w[CX]-1;
2589 
2590 	I.regs.w[CX]=tmp;
2591 
2592     if (tmp) {
2593 		ICOUNT -= cycles.loop_t;
2594 		I.pc += disp;
2595 /* ASG - can probably assume this is safe
2596 		CHANGE_PC(I.pc);*/
2597 	} else ICOUNT -= cycles.loop_nt;
2598 }
2599 
PREFIX86(_jcxz)2600 static void PREFIX86(_jcxz)(void)    /* Opcode 0xe3 */
2601 {
2602 	int disp = (int)((INT8)FETCH);
2603 
2604 	if (I.regs.w[CX] == 0) {
2605 		ICOUNT -= cycles.jcxz_t;
2606 		I.pc += disp;
2607 /* ASG - can probably assume this is safe
2608 		CHANGE_PC(I.pc);*/
2609 	} else
2610 		ICOUNT -= cycles.jcxz_nt;
2611 }
2612 
PREFIX86(_inal)2613 static void PREFIX86(_inal)(void)    /* Opcode 0xe4 */
2614 {
2615 	unsigned port = FETCH;
2616 
2617 	ICOUNT -= cycles.in_imm8;
2618 	I.regs.b[AL] = read_port(port);
2619 }
2620 
PREFIX86(_inax)2621 static void PREFIX86(_inax)(void)    /* Opcode 0xe5 */
2622 {
2623 	unsigned port = FETCH;
2624 
2625 	ICOUNT -= cycles.in_imm16;
2626 	I.regs.b[AL] = read_port(port);
2627 	I.regs.b[AH] = read_port(port+1);
2628 }
2629 
PREFIX86(_outal)2630 static void PREFIX86(_outal)(void)    /* Opcode 0xe6 */
2631 {
2632 	unsigned port = FETCH;
2633 
2634 	ICOUNT -= cycles.out_imm8;
2635 	write_port(port, I.regs.b[AL]);
2636 }
2637 
PREFIX86(_outax)2638 static void PREFIX86(_outax)(void)    /* Opcode 0xe7 */
2639 {
2640 	unsigned port = FETCH;
2641 
2642 	ICOUNT -= cycles.out_imm16;
2643 	write_port(port, I.regs.b[AL]);
2644 	write_port(port+1, I.regs.b[AH]);
2645 }
2646 
PREFIX86(_call_d16)2647 static void PREFIX86(_call_d16)(void)    /* Opcode 0xe8 */
2648 {
2649 	WORD ip, tmp;
2650 
2651 	FETCHWORD(tmp);
2652 	ip = I.pc - I.base[CS];
2653 	PUSH(ip);
2654 	ip += tmp;
2655 	I.pc = (ip + I.base[CS]) & AMASK;
2656 	ICOUNT -= cycles.call_near;
2657 	CHANGE_PC(I.pc);
2658 }
2659 
PREFIX86(_jmp_d16)2660 static void PREFIX86(_jmp_d16)(void)    /* Opcode 0xe9 */
2661 {
2662 	WORD ip, tmp;
2663 
2664 	FETCHWORD(tmp);
2665 	ip = I.pc - I.base[CS] + tmp;
2666 	I.pc = (ip + I.base[CS]) & AMASK;
2667 	ICOUNT -= cycles.jmp_near;
2668 	CHANGE_PC(I.pc);
2669 }
2670 
PREFIX86(_jmp_far)2671 static void PREFIX86(_jmp_far)(void)    /* Opcode 0xea */
2672 {
2673 	unsigned tmp,tmp1;
2674 
2675 	tmp = FETCH;
2676 	tmp += FETCH << 8;
2677 
2678 	tmp1 = FETCH;
2679 	tmp1 += FETCH << 8;
2680 
2681 #ifdef I286
2682 	i286_code_descriptor(tmp1,tmp);
2683 #else
2684 	I.sregs[CS] = (WORD)tmp1;
2685 	I.base[CS] = SegBase(CS);
2686 	I.pc = (I.base[CS] + tmp) & AMASK;
2687 #endif
2688 	ICOUNT -= cycles.jmp_far;
2689 	CHANGE_PC(I.pc);
2690 }
2691 
PREFIX86(_jmp_d8)2692 static void PREFIX86(_jmp_d8)(void)    /* Opcode 0xeb */
2693 {
2694 	int tmp = (int)((INT8)FETCH);
2695 	I.pc += tmp;
2696 /* ASG - can probably assume this is safe
2697 	CHANGE_PC(I.pc);*/
2698 	ICOUNT -= cycles.jmp_short;
2699 }
2700 
PREFIX86(_inaldx)2701 static void PREFIX86(_inaldx)(void)    /* Opcode 0xec */
2702 {
2703 	ICOUNT -= cycles.in_dx8;
2704 	I.regs.b[AL] = read_port(I.regs.w[DX]);
2705 }
2706 
PREFIX86(_inaxdx)2707 static void PREFIX86(_inaxdx)(void)    /* Opcode 0xed */
2708 {
2709 	unsigned port = I.regs.w[DX];
2710 
2711 	ICOUNT -= cycles.in_dx16;
2712 	I.regs.b[AL] = read_port(port);
2713 	I.regs.b[AH] = read_port(port+1);
2714 }
2715 
PREFIX86(_outdxal)2716 static void PREFIX86(_outdxal)(void)    /* Opcode 0xee */
2717 {
2718 	ICOUNT -= cycles.out_dx8;
2719 	write_port(I.regs.w[DX], I.regs.b[AL]);
2720 }
2721 
PREFIX86(_outdxax)2722 static void PREFIX86(_outdxax)(void)    /* Opcode 0xef */
2723 {
2724 	unsigned port = I.regs.w[DX];
2725 
2726 	ICOUNT -= cycles.out_dx16;
2727 	write_port(port, I.regs.b[AL]);
2728 	write_port(port+1, I.regs.b[AH]);
2729 }
2730 
2731 /* I think thats not a V20 instruction...*/
PREFIX86(_lock)2732 static void PREFIX86(_lock)(void)    /* Opcode 0xf0 */
2733 {
2734 	ICOUNT -= cycles.nop;
2735 	PREFIX(_instruction)[FETCHOP]();  /* un-interruptible */
2736 }
2737 #endif
2738 
PREFIX(_repne)2739 static void PREFIX(_repne)(void)    /* Opcode 0xf2 */
2740 {
2741 	 PREFIX(rep)(0);
2742 }
2743 
PREFIX(_repe)2744 static void PREFIX(_repe)(void)    /* Opcode 0xf3 */
2745 {
2746 	 PREFIX(rep)(1);
2747 }
2748 
2749 #ifndef I186
PREFIX86(_hlt)2750 static void PREFIX86(_hlt)(void)    /* Opcode 0xf4 */
2751 {
2752 	I.pc--;
2753 	ICOUNT = 0;
2754 }
2755 
PREFIX86(_cmc)2756 static void PREFIX86(_cmc)(void)    /* Opcode 0xf5 */
2757 {
2758 	ICOUNT -= cycles.flag_ops;
2759 	I.CarryVal = !CF;
2760 }
2761 
PREFIX86(_f6pre)2762 static void PREFIX86(_f6pre)(void)
2763 {
2764 	/* Opcode 0xf6 */
2765 	unsigned ModRM = FETCH;
2766     unsigned tmp = (unsigned)GetRMByte(ModRM);
2767     unsigned tmp2;
2768 
2769 
2770     switch (ModRM & 0x38)
2771     {
2772     case 0x00:  /* TEST Eb, data8 */
2773     case 0x08:  /* ??? */
2774 		ICOUNT -= (ModRM >= 0xc0) ? cycles.alu_ri8 : cycles.alu_mi8_ro;
2775 		tmp &= FETCH;
2776 
2777 		I.CarryVal = I.OverVal = I.AuxVal = 0;
2778 		SetSZPF_Byte(tmp);
2779 		break;
2780 
2781     case 0x10:  /* NOT Eb */
2782 		ICOUNT -= (ModRM >= 0xc0) ? cycles.negnot_r8 : cycles.negnot_m8;
2783 		PutbackRMByte(ModRM,~tmp);
2784 		break;
2785 
2786 	 case 0x18:  /* NEG Eb */
2787 		ICOUNT -= (ModRM >= 0xc0) ? cycles.negnot_r8 : cycles.negnot_m8;
2788         tmp2=0;
2789         SUBB(tmp2,tmp);
2790         PutbackRMByte(ModRM,tmp2);
2791 		break;
2792     case 0x20:  /* MUL AL, Eb */
2793 		ICOUNT -= (ModRM >= 0xc0) ? cycles.mul_r8 : cycles.mul_m8;
2794 		{
2795 			UINT16 result;
2796 			tmp2 = I.regs.b[AL];
2797 
2798 			SetSF((INT8)tmp2);
2799 			SetPF(tmp2);
2800 
2801 			result = (UINT16)tmp2*tmp;
2802 			I.regs.w[AX]=(WORD)result;
2803 
2804 			SetZF(I.regs.w[AX]);
2805 			I.CarryVal = I.OverVal = (I.regs.b[AH] != 0);
2806 		}
2807 		break;
2808 	 case 0x28:  /* IMUL AL, Eb */
2809 		ICOUNT -= (ModRM >= 0xc0) ? cycles.imul_r8 : cycles.imul_m8;
2810 		{
2811 			INT16 result;
2812 
2813 			tmp2 = (unsigned)I.regs.b[AL];
2814 
2815 			SetSF((INT8)tmp2);
2816 			SetPF(tmp2);
2817 
2818 			result = (INT16)((INT8)tmp2)*(INT16)((INT8)tmp);
2819 			I.regs.w[AX]=(WORD)result;
2820 
2821 			SetZF(I.regs.w[AX]);
2822 
2823 			I.CarryVal = I.OverVal = (result >> 7 != 0) && (result >> 7 != -1);
2824 		}
2825 		break;
2826     case 0x30:  /* DIV AL, Ew */
2827 		ICOUNT -= (ModRM >= 0xc0) ? cycles.div_r8 : cycles.div_m8;
2828 		{
2829 			UINT16 result;
2830 
2831 			result = I.regs.w[AX];
2832 
2833 			if (tmp)
2834 			{
2835 				if ((result / tmp) > 0xff)
2836 				{
2837 #ifdef V20
2838 					PREFIX(_interrupt)(0,0);
2839 #else
2840 					PREFIX(_interrupt)(0);
2841 #endif
2842 					break;
2843 				}
2844 				else
2845 				{
2846 					I.regs.b[AH] = result % tmp;
2847 					I.regs.b[AL] = result / tmp;
2848 				}
2849 			}
2850 			else
2851 			{
2852 #ifdef V20
2853 				PREFIX(_interrupt)(0,0);
2854 #else
2855 				PREFIX(_interrupt)(0);
2856 #endif
2857 				break;
2858 			}
2859 		}
2860 		break;
2861     case 0x38:  /* IDIV AL, Ew */
2862 		ICOUNT -= (ModRM >= 0xc0) ? cycles.idiv_r8 : cycles.idiv_m8;
2863 		{
2864 
2865 			INT16 result;
2866 
2867 			result = I.regs.w[AX];
2868 
2869 			if (tmp)
2870 			{
2871 				tmp2 = result % (INT16)((INT8)tmp);
2872 
2873 				if ((result /= (INT16)((INT8)tmp)) > 0xff)
2874 				{
2875 #ifdef V20
2876 					PREFIX(_interrupt)(0,0);
2877 #else
2878 					PREFIX(_interrupt)(0);
2879 #endif
2880 					break;
2881 				}
2882 				else
2883 				{
2884 					I.regs.b[AL] = result;
2885 					I.regs.b[AH] = tmp2;
2886 				}
2887 			}
2888 			else
2889 			{
2890 #ifdef V20
2891 				PREFIX(_interrupt)(0,0);
2892 #else
2893 				PREFIX(_interrupt)(0);
2894 #endif
2895 				break;
2896 			}
2897 		}
2898 		break;
2899     }
2900 }
2901 
2902 
PREFIX86(_f7pre)2903 static void PREFIX86(_f7pre)(void)
2904 {
2905 	/* Opcode 0xf7 */
2906 	unsigned ModRM = FETCH;
2907 	 unsigned tmp = GetRMWord(ModRM);
2908     unsigned tmp2;
2909 
2910 
2911     switch (ModRM & 0x38)
2912     {
2913     case 0x00:  /* TEST Ew, data16 */
2914     case 0x08:  /* ??? */
2915 		ICOUNT -= (ModRM >= 0xc0) ? cycles.alu_ri16 : cycles.alu_mi16_ro;
2916 		tmp2 = FETCH;
2917 		tmp2 += FETCH << 8;
2918 
2919 		tmp &= tmp2;
2920 
2921 		I.CarryVal = I.OverVal = I.AuxVal = 0;
2922 		SetSZPF_Word(tmp);
2923 		break;
2924 
2925     case 0x10:  /* NOT Ew */
2926 		ICOUNT -= (ModRM >= 0xc0) ? cycles.negnot_r16 : cycles.negnot_m16;
2927 		tmp = ~tmp;
2928 		PutbackRMWord(ModRM,tmp);
2929 		break;
2930 
2931     case 0x18:  /* NEG Ew */
2932 		ICOUNT -= (ModRM >= 0xc0) ? cycles.negnot_r16 : cycles.negnot_m16;
2933         tmp2 = 0;
2934         SUBW(tmp2,tmp);
2935         PutbackRMWord(ModRM,tmp2);
2936 		break;
2937     case 0x20:  /* MUL AX, Ew */
2938 		ICOUNT -= (ModRM >= 0xc0) ? cycles.mul_r16 : cycles.mul_m16;
2939 		{
2940 			UINT32 result;
2941 			tmp2 = I.regs.w[AX];
2942 
2943 			SetSF((INT16)tmp2);
2944 			SetPF(tmp2);
2945 
2946 			result = (UINT32)tmp2*tmp;
2947 			I.regs.w[AX]=(WORD)result;
2948             result >>= 16;
2949 			I.regs.w[DX]=result;
2950 
2951 			SetZF(I.regs.w[AX] | I.regs.w[DX]);
2952 			I.CarryVal = I.OverVal = (I.regs.w[DX] != 0);
2953 		}
2954 		break;
2955 
2956     case 0x28:  /* IMUL AX, Ew */
2957 		ICOUNT -= (ModRM >= 0xc0) ? cycles.imul_r16 : cycles.imul_m16;
2958 		{
2959 			INT32 result;
2960 
2961 			tmp2 = I.regs.w[AX];
2962 
2963 			SetSF((INT16)tmp2);
2964 			SetPF(tmp2);
2965 
2966 			result = (INT32)((INT16)tmp2)*(INT32)((INT16)tmp);
2967 			I.CarryVal = I.OverVal = (result >> 15 != 0) && (result >> 15 != -1);
2968 
2969 			I.regs.w[AX]=(WORD)result;
2970 			result = (WORD)(result >> 16);
2971 			I.regs.w[DX]=result;
2972 
2973 			SetZF(I.regs.w[AX] | I.regs.w[DX]);
2974 		}
2975 		break;
2976 	 case 0x30:  /* DIV AX, Ew */
2977 		ICOUNT -= (ModRM >= 0xc0) ? cycles.div_r16 : cycles.div_m16;
2978 		{
2979 			UINT32 result;
2980 
2981 			result = (I.regs.w[DX] << 16) + I.regs.w[AX];
2982 
2983 			if (tmp)
2984 			{
2985 				tmp2 = result % tmp;
2986 				if ((result / tmp) > 0xffff)
2987 				{
2988 #ifdef V20
2989 					PREFIX(_interrupt)(0,0);
2990 #else
2991 					PREFIX(_interrupt)(0);
2992 #endif
2993 					break;
2994 				}
2995 				else
2996 				{
2997 					I.regs.w[DX]=tmp2;
2998 					result /= tmp;
2999 					I.regs.w[AX]=result;
3000 				}
3001 			}
3002 			else
3003 			{
3004 #ifdef V20
3005 				PREFIX(_interrupt)(0,0);
3006 #else
3007 				PREFIX(_interrupt)(0);
3008 #endif
3009 				break;
3010 			}
3011 		}
3012 		break;
3013     case 0x38:  /* IDIV AX, Ew */
3014 		ICOUNT -= (ModRM >= 0xc0) ? cycles.idiv_r16 : cycles.idiv_m16;
3015 		{
3016 			INT32 result;
3017 
3018 			result = (I.regs.w[DX] << 16) + I.regs.w[AX];
3019 
3020 			if (tmp)
3021 			{
3022 				tmp2 = result % (INT32)((INT16)tmp);
3023 				if ((result /= (INT32)((INT16)tmp)) > 0xffff)
3024 				{
3025 #ifdef V20
3026 					PREFIX(_interrupt)(0,0);
3027 #else
3028 					PREFIX(_interrupt)(0);
3029 #endif
3030 					break;
3031 				}
3032 				else
3033 				{
3034 					I.regs.w[AX]=result;
3035 					I.regs.w[DX]=tmp2;
3036 				}
3037 			}
3038 			else
3039 			{
3040 #ifdef V20
3041 				PREFIX(_interrupt)(0,0);
3042 #else
3043 				PREFIX(_interrupt)(0);
3044 #endif
3045 				break;
3046 			}
3047 		}
3048 		break;
3049     }
3050 }
3051 
3052 
PREFIX86(_clc)3053 static void PREFIX86(_clc)(void)    /* Opcode 0xf8 */
3054 {
3055 	ICOUNT -= cycles.flag_ops;
3056 	I.CarryVal = 0;
3057 }
3058 
PREFIX86(_stc)3059 static void PREFIX86(_stc)(void)    /* Opcode 0xf9 */
3060 {
3061 	ICOUNT -= cycles.flag_ops;
3062 	I.CarryVal = 1;
3063 }
3064 
PREFIX86(_cli)3065 static void PREFIX86(_cli)(void)    /* Opcode 0xfa */
3066 {
3067 	ICOUNT -= cycles.flag_ops;
3068 	SetIF(0);
3069 }
3070 
PREFIX86(_sti)3071 static void PREFIX86(_sti)(void)    /* Opcode 0xfb */
3072 {
3073 	ICOUNT -= cycles.flag_ops;
3074 	SetIF(1);
3075 	PREFIX(_instruction)[FETCHOP](); /* no interrupt before next instruction */
3076 
3077 	/* if an interrupt is pending, signal an interrupt */
3078 	if (I.irq_state)
3079 #ifdef V20
3080 		PREFIX(_interrupt)(-1, 0);
3081 #else
3082 		PREFIX(_interrupt)(-1);
3083 #endif
3084 }
3085 
PREFIX86(_cld)3086 static void PREFIX86(_cld)(void)    /* Opcode 0xfc */
3087 {
3088 	ICOUNT -= cycles.flag_ops;
3089 	SetDF(0);
3090 }
3091 
PREFIX86(_std)3092 static void PREFIX86(_std)(void)    /* Opcode 0xfd */
3093 {
3094 	ICOUNT -= cycles.flag_ops;
3095 	SetDF(1);
3096 }
3097 
PREFIX86(_fepre)3098 static void PREFIX86(_fepre)(void)    /* Opcode 0xfe */
3099 {
3100 	unsigned ModRM = FETCH;
3101 	unsigned tmp = GetRMByte(ModRM);
3102     unsigned tmp1;
3103 
3104 	ICOUNT -= (ModRM >= 0xc0) ? cycles.incdec_r8 : cycles.incdec_m8;
3105     if ((ModRM & 0x38) == 0)  /* INC eb */
3106 	 {
3107 		tmp1 = tmp+1;
3108 		SetOFB_Add(tmp1,tmp,1);
3109     }
3110 	 else  /* DEC eb */
3111     {
3112 		tmp1 = tmp-1;
3113 		SetOFB_Sub(tmp1,1,tmp);
3114     }
3115 
3116     SetAF(tmp1,tmp,1);
3117     SetSZPF_Byte(tmp1);
3118 
3119     PutbackRMByte(ModRM,(BYTE)tmp1);
3120 }
3121 
3122 
PREFIX86(_ffpre)3123 static void PREFIX86(_ffpre)(void)    /* Opcode 0xff */
3124 {
3125 	unsigned ModRM = FETCHOP;
3126     unsigned tmp;
3127     unsigned tmp1;
3128     WORD ip;
3129 
3130     switch(ModRM & 0x38)
3131     {
3132     case 0x00:  /* INC ew */
3133 		ICOUNT -= (ModRM >= 0xc0) ? cycles.incdec_r16 : cycles.incdec_m16;
3134 		tmp = GetRMWord(ModRM);
3135 		tmp1 = tmp+1;
3136 
3137 		SetOFW_Add(tmp1,tmp,1);
3138 		SetAF(tmp1,tmp,1);
3139 		SetSZPF_Word(tmp1);
3140 
3141 		PutbackRMWord(ModRM,(WORD)tmp1);
3142 		break;
3143 
3144     case 0x08:  /* DEC ew */
3145 		ICOUNT -= (ModRM >= 0xc0) ? cycles.incdec_r16 : cycles.incdec_m16;
3146 		tmp = GetRMWord(ModRM);
3147 		tmp1 = tmp-1;
3148 
3149 		SetOFW_Sub(tmp1,1,tmp);
3150 		SetAF(tmp1,tmp,1);
3151 		SetSZPF_Word(tmp1);
3152 
3153 		PutbackRMWord(ModRM,(WORD)tmp1);
3154 		break;
3155 
3156     case 0x10:  /* CALL ew */
3157 		ICOUNT -= (ModRM >= 0xc0) ? cycles.call_r16 : cycles.call_m16;
3158 		tmp = GetRMWord(ModRM);
3159 		ip = I.pc - I.base[CS];
3160 		PUSH(ip);
3161 		I.pc = (I.base[CS] + (WORD)tmp) & AMASK;
3162 		CHANGE_PC(I.pc);
3163 		break;
3164 
3165 	case 0x18:  /* CALL FAR ea */
3166 		ICOUNT -= cycles.call_m32;
3167 		tmp = I.sregs[CS];	/* HJB 12/13/98 need to skip displacements of EA */
3168 		tmp1 = GetRMWord(ModRM);
3169 		ip = I.pc - I.base[CS];
3170 		PUSH(tmp);
3171 		PUSH(ip);
3172 #ifdef I286
3173 		i286_code_descriptor(GetnextRMWord, tmp1);
3174 #else
3175 		I.sregs[CS] = GetnextRMWord;
3176 		I.base[CS] = SegBase(CS);
3177 		I.pc = (I.base[CS] + tmp1) & AMASK;
3178 #endif
3179 		CHANGE_PC(I.pc);
3180 		break;
3181 
3182     case 0x20:  /* JMP ea */
3183 		ICOUNT -= (ModRM >= 0xc0) ? cycles.jmp_r16 : cycles.jmp_m16;
3184 		ip = GetRMWord(ModRM);
3185 		I.pc = (I.base[CS] + ip) & AMASK;
3186 		CHANGE_PC(I.pc);
3187 		break;
3188 
3189     case 0x28:  /* JMP FAR ea */
3190 		ICOUNT -= cycles.jmp_m32;
3191 
3192 #ifdef I286
3193 		tmp = GetRMWord(ModRM);
3194 		i286_code_descriptor(GetnextRMWord, tmp);
3195 #else
3196 		I.pc = GetRMWord(ModRM);
3197 		I.sregs[CS] = GetnextRMWord;
3198 		I.base[CS] = SegBase(CS);
3199 		I.pc = (I.pc + I.base[CS]) & AMASK;
3200 #endif
3201 		CHANGE_PC(I.pc);
3202 		break;
3203 
3204     case 0x30:  /* PUSH ea */
3205 		ICOUNT -= (ModRM >= 0xc0) ? cycles.push_r16 : cycles.push_m16;
3206 		tmp = GetRMWord(ModRM);
3207 		PUSH(tmp);
3208 		break;
3209 	 }
3210 }
3211 
3212 
PREFIX86(_invalid)3213 static void PREFIX86(_invalid)(void)
3214 {
3215 #ifdef I286
3216 	i286_trap2(ILLEGAL_INSTRUCTION);
3217 #else
3218 	 /* makes the cpu loops forever until user resets it */
3219 	/*{ extern int debug_key_pressed; debug_key_pressed = 1; } */
3220 	log_cb(RETRO_LOG_DEBUG, LOGPRE "illegal instruction %.2x at %.5x\n",PEEKBYTE(I.pc), I.pc);
3221 	I.pc--;
3222 	ICOUNT -= 10;
3223 #endif
3224 }
3225 #endif
3226