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[DI] += I.DirVal;
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[DI] += 2 * I.DirVal;
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 = GetMemB(ES, I.regs.w[DI]);
523 			src = GetMemB(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 	if (AF || ((I.regs.b[AL] & 0xf) > 9))
1015 	{
1016 		int tmp;
1017 		I.regs.b[AL] = tmp = I.regs.b[AL] - 6;
1018 		I.AuxVal = 1;
1019 		I.CarryVal |= tmp & 0x100;
1020 	}
1021 
1022 	if (CF || (I.regs.b[AL] > 0x9f))
1023 	{
1024 		I.regs.b[AL] -= 0x60;
1025 		I.CarryVal = 1;
1026 	}
1027 
1028 	SetSZPF_Byte(I.regs.b[AL]);
1029 	ICOUNT -= cycles.das;
1030 }
1031 
PREFIX86(_xor_br8)1032 static void PREFIX86(_xor_br8)(void)    /* Opcode 0x30 */
1033 {
1034     DEF_br8(dst,src);
1035 	ICOUNT -= (ModRM >= 0xc0) ? cycles.alu_rr8 : cycles.alu_mr8;
1036     XORB(dst,src);
1037 	PutbackRMByte(ModRM,dst);
1038 }
1039 
PREFIX86(_xor_wr16)1040 static void PREFIX86(_xor_wr16)(void)    /* Opcode 0x31 */
1041 {
1042 	DEF_wr16(dst,src);
1043 	ICOUNT -= (ModRM >= 0xc0) ? cycles.alu_rr16 : cycles.alu_mr16;
1044 	XORW(dst,src);
1045     PutbackRMWord(ModRM,dst);
1046 }
1047 
PREFIX86(_xor_r8b)1048 static void PREFIX86(_xor_r8b)(void)    /* Opcode 0x32 */
1049 {
1050     DEF_r8b(dst,src);
1051 	ICOUNT -= (ModRM >= 0xc0) ? cycles.alu_rr8 : cycles.alu_rm8;
1052     XORB(dst,src);
1053     RegByte(ModRM)=dst;
1054 }
1055 
PREFIX86(_xor_r16w)1056 static void PREFIX86(_xor_r16w)(void)    /* Opcode 0x33 */
1057 {
1058     DEF_r16w(dst,src);
1059 	ICOUNT -= (ModRM >= 0xc0) ? cycles.alu_rr16 : cycles.alu_rm16;
1060     XORW(dst,src);
1061 	RegWord(ModRM)=dst;
1062 }
1063 
PREFIX86(_xor_ald8)1064 static void PREFIX86(_xor_ald8)(void)    /* Opcode 0x34 */
1065 {
1066 	DEF_ald8(dst,src);
1067 	ICOUNT -= cycles.alu_ri8;
1068     XORB(dst,src);
1069 	I.regs.b[AL] = dst;
1070 }
1071 
PREFIX86(_xor_axd16)1072 static void PREFIX86(_xor_axd16)(void)    /* Opcode 0x35 */
1073 {
1074     DEF_axd16(dst,src);
1075 	ICOUNT -= cycles.alu_ri16;
1076     XORW(dst,src);
1077 	I.regs.w[AX]=dst;
1078 }
1079 
PREFIX86(_ss)1080 static void PREFIX86(_ss)(void)    /* Opcode 0x36 */
1081 {
1082 	seg_prefix=TRUE;
1083 	prefix_base=I.base[SS];
1084 	ICOUNT -= cycles.override;
1085 	PREFIX(_instruction)[FETCHOP]();
1086 }
1087 
PREFIX86(_aaa)1088 static void PREFIX86(_aaa)(void)    /* Opcode 0x37 */
1089 {
1090 	if (AF || ((I.regs.b[AL] & 0xf) > 9))
1091     {
1092 		I.regs.b[AL] += 6;
1093 		I.regs.b[AH] += 1;
1094 		I.AuxVal = 1;
1095 		I.CarryVal = 1;
1096     }
1097 	else
1098 	{
1099 		I.AuxVal = 0;
1100 		I.CarryVal = 0;
1101     }
1102 	I.regs.b[AL] &= 0x0F;
1103 	ICOUNT -= cycles.aaa;
1104 }
1105 
PREFIX86(_cmp_br8)1106 static void PREFIX86(_cmp_br8)(void)    /* Opcode 0x38 */
1107 {
1108     DEF_br8(dst,src);
1109 	ICOUNT -= (ModRM >= 0xc0) ? cycles.alu_rr8 : cycles.alu_rm8;
1110     SUBB(dst,src);
1111 }
1112 
PREFIX86(_cmp_wr16)1113 static void PREFIX86(_cmp_wr16)(void)    /* Opcode 0x39 */
1114 {
1115 	DEF_wr16(dst,src);
1116 	ICOUNT -= (ModRM >= 0xc0) ? cycles.alu_rr16 : cycles.alu_rm16;
1117     SUBW(dst,src);
1118 }
1119 
PREFIX86(_cmp_r8b)1120 static void PREFIX86(_cmp_r8b)(void)    /* Opcode 0x3a */
1121 {
1122     DEF_r8b(dst,src);
1123 	ICOUNT -= (ModRM >= 0xc0) ? cycles.alu_rr8 : cycles.alu_rm8;
1124     SUBB(dst,src);
1125 }
1126 
PREFIX86(_cmp_r16w)1127 static void PREFIX86(_cmp_r16w)(void)    /* Opcode 0x3b */
1128 {
1129 	DEF_r16w(dst,src);
1130 	ICOUNT -= (ModRM >= 0xc0) ? cycles.alu_rr16 : cycles.alu_rm16;
1131     SUBW(dst,src);
1132 }
1133 
PREFIX86(_cmp_ald8)1134 static void PREFIX86(_cmp_ald8)(void)    /* Opcode 0x3c */
1135 {
1136     DEF_ald8(dst,src);
1137 	ICOUNT -= cycles.alu_ri8;
1138     SUBB(dst,src);
1139 }
1140 
PREFIX86(_cmp_axd16)1141 static void PREFIX86(_cmp_axd16)(void)    /* Opcode 0x3d */
1142 {
1143     DEF_axd16(dst,src);
1144 	ICOUNT -= cycles.alu_ri16;
1145     SUBW(dst,src);
1146 }
1147 
PREFIX86(_ds)1148 static void PREFIX86(_ds)(void)    /* Opcode 0x3e */
1149 {
1150 	seg_prefix=TRUE;
1151 	prefix_base=I.base[DS];
1152 	ICOUNT -= cycles.override;
1153 	PREFIX(_instruction)[FETCHOP]();
1154 }
1155 
PREFIX86(_aas)1156 static void PREFIX86(_aas)(void)    /* Opcode 0x3f */
1157 {
1158 	if (AF || ((I.regs.b[AL] & 0xf) > 9))
1159     {
1160 		I.regs.b[AL] -= 6;
1161 		I.regs.b[AH] -= 1;
1162 		I.AuxVal = 1;
1163 		I.CarryVal = 1;
1164     }
1165 	else
1166 	{
1167 		I.AuxVal = 0;
1168 		I.CarryVal = 0;
1169     }
1170 	I.regs.b[AL] &= 0x0F;
1171 	ICOUNT -= cycles.aas;
1172 }
1173 
1174 #define IncWordReg(Reg) 					\
1175 {											\
1176 	unsigned tmp = (unsigned)I.regs.w[Reg]; \
1177 	unsigned tmp1 = tmp+1;					\
1178 	SetOFW_Add(tmp1,tmp,1); 				\
1179 	SetAF(tmp1,tmp,1);						\
1180 	SetSZPF_Word(tmp1); 					\
1181 	I.regs.w[Reg]=tmp1; 					\
1182 	ICOUNT -= cycles.incdec_r16;			\
1183 }
1184 
PREFIX86(_inc_ax)1185 static void PREFIX86(_inc_ax)(void)    /* Opcode 0x40 */
1186 {
1187     IncWordReg(AX);
1188 }
1189 
PREFIX86(_inc_cx)1190 static void PREFIX86(_inc_cx)(void)    /* Opcode 0x41 */
1191 {
1192     IncWordReg(CX);
1193 }
1194 
PREFIX86(_inc_dx)1195 static void PREFIX86(_inc_dx)(void)    /* Opcode 0x42 */
1196 {
1197 	IncWordReg(DX);
1198 }
1199 
PREFIX(_inc_bx)1200 static void PREFIX(_inc_bx)(void)    /* Opcode 0x43 */
1201 {
1202 	IncWordReg(BX);
1203 }
1204 
PREFIX86(_inc_sp)1205 static void PREFIX86(_inc_sp)(void)    /* Opcode 0x44 */
1206 {
1207     IncWordReg(SP);
1208 }
1209 
PREFIX86(_inc_bp)1210 static void PREFIX86(_inc_bp)(void)    /* Opcode 0x45 */
1211 {
1212 	IncWordReg(BP);
1213 }
1214 
PREFIX86(_inc_si)1215 static void PREFIX86(_inc_si)(void)    /* Opcode 0x46 */
1216 {
1217 	IncWordReg(SI);
1218 }
1219 
PREFIX86(_inc_di)1220 static void PREFIX86(_inc_di)(void)    /* Opcode 0x47 */
1221 {
1222     IncWordReg(DI);
1223 }
1224 
1225 #define DecWordReg(Reg) 					\
1226 { 											\
1227 	unsigned tmp = (unsigned)I.regs.w[Reg]; \
1228     unsigned tmp1 = tmp-1; 					\
1229     SetOFW_Sub(tmp1,1,tmp); 				\
1230     SetAF(tmp1,tmp,1); 						\
1231 	SetSZPF_Word(tmp1);						\
1232 	I.regs.w[Reg]=tmp1; 					\
1233 	ICOUNT -= cycles.incdec_r16;			\
1234 }
1235 
PREFIX86(_dec_ax)1236 static void PREFIX86(_dec_ax)(void)    /* Opcode 0x48 */
1237 {
1238     DecWordReg(AX);
1239 }
1240 
PREFIX86(_dec_cx)1241 static void PREFIX86(_dec_cx)(void)    /* Opcode 0x49 */
1242 {
1243 	DecWordReg(CX);
1244 }
1245 
PREFIX86(_dec_dx)1246 static void PREFIX86(_dec_dx)(void)    /* Opcode 0x4a */
1247 {
1248 	DecWordReg(DX);
1249 }
1250 
PREFIX86(_dec_bx)1251 static void PREFIX86(_dec_bx)(void)    /* Opcode 0x4b */
1252 {
1253 	DecWordReg(BX);
1254 }
1255 
PREFIX86(_dec_sp)1256 static void PREFIX86(_dec_sp)(void)    /* Opcode 0x4c */
1257 {
1258     DecWordReg(SP);
1259 }
1260 
PREFIX86(_dec_bp)1261 static void PREFIX86(_dec_bp)(void)    /* Opcode 0x4d */
1262 {
1263     DecWordReg(BP);
1264 }
1265 
PREFIX86(_dec_si)1266 static void PREFIX86(_dec_si)(void)    /* Opcode 0x4e */
1267 {
1268     DecWordReg(SI);
1269 }
1270 
PREFIX86(_dec_di)1271 static void PREFIX86(_dec_di)(void)    /* Opcode 0x4f */
1272 {
1273     DecWordReg(DI);
1274 }
1275 
PREFIX86(_push_ax)1276 static void PREFIX86(_push_ax)(void)    /* Opcode 0x50 */
1277 {
1278 	ICOUNT -= cycles.push_r16;
1279 	PUSH(I.regs.w[AX]);
1280 }
1281 
PREFIX86(_push_cx)1282 static void PREFIX86(_push_cx)(void)    /* Opcode 0x51 */
1283 {
1284 	ICOUNT -= cycles.push_r16;
1285 	PUSH(I.regs.w[CX]);
1286 }
1287 
PREFIX86(_push_dx)1288 static void PREFIX86(_push_dx)(void)    /* Opcode 0x52 */
1289 {
1290 	ICOUNT -= cycles.push_r16;
1291 	PUSH(I.regs.w[DX]);
1292 }
1293 
PREFIX86(_push_bx)1294 static void PREFIX86(_push_bx)(void)    /* Opcode 0x53 */
1295 {
1296 	ICOUNT -= cycles.push_r16;
1297 	PUSH(I.regs.w[BX]);
1298 }
1299 
PREFIX86(_push_sp)1300 static void PREFIX86(_push_sp)(void)    /* Opcode 0x54 */
1301 {
1302 	ICOUNT -= cycles.push_r16;
1303 	PUSH(I.regs.w[SP]);
1304 }
1305 
PREFIX86(_push_bp)1306 static void PREFIX86(_push_bp)(void)    /* Opcode 0x55 */
1307 {
1308 	ICOUNT -= cycles.push_r16;
1309 	PUSH(I.regs.w[BP]);
1310 }
1311 
1312 
PREFIX86(_push_si)1313 static void PREFIX86(_push_si)(void)    /* Opcode 0x56 */
1314 {
1315 	ICOUNT -= cycles.push_r16;
1316 	PUSH(I.regs.w[SI]);
1317 }
1318 
PREFIX86(_push_di)1319 static void PREFIX86(_push_di)(void)    /* Opcode 0x57 */
1320 {
1321 	ICOUNT -= cycles.push_r16;
1322 	PUSH(I.regs.w[DI]);
1323 }
1324 
PREFIX86(_pop_ax)1325 static void PREFIX86(_pop_ax)(void)    /* Opcode 0x58 */
1326 {
1327 	ICOUNT -= cycles.pop_r16;
1328 	POP(I.regs.w[AX]);
1329 }
1330 
PREFIX86(_pop_cx)1331 static void PREFIX86(_pop_cx)(void)    /* Opcode 0x59 */
1332 {
1333 	ICOUNT -= cycles.pop_r16;
1334 	POP(I.regs.w[CX]);
1335 }
1336 
PREFIX86(_pop_dx)1337 static void PREFIX86(_pop_dx)(void)    /* Opcode 0x5a */
1338 {
1339 	ICOUNT -= cycles.pop_r16;
1340 	POP(I.regs.w[DX]);
1341 }
1342 
PREFIX86(_pop_bx)1343 static void PREFIX86(_pop_bx)(void)    /* Opcode 0x5b */
1344 {
1345 	ICOUNT -= cycles.pop_r16;
1346 	POP(I.regs.w[BX]);
1347 }
1348 
PREFIX86(_pop_sp)1349 static void PREFIX86(_pop_sp)(void)    /* Opcode 0x5c */
1350 {
1351 	ICOUNT -= cycles.pop_r16;
1352 	POP(I.regs.w[SP]);
1353 }
1354 
PREFIX86(_pop_bp)1355 static void PREFIX86(_pop_bp)(void)    /* Opcode 0x5d */
1356 {
1357 	ICOUNT -= cycles.pop_r16;
1358 	POP(I.regs.w[BP]);
1359 }
1360 
PREFIX86(_pop_si)1361 static void PREFIX86(_pop_si)(void)    /* Opcode 0x5e */
1362 {
1363 	ICOUNT -= cycles.pop_r16;
1364 	POP(I.regs.w[SI]);
1365 }
1366 
PREFIX86(_pop_di)1367 static void PREFIX86(_pop_di)(void)    /* Opcode 0x5f */
1368 {
1369 	ICOUNT -= cycles.pop_r16;
1370 	POP(I.regs.w[DI]);
1371 }
1372 
PREFIX86(_jo)1373 static void PREFIX86(_jo)(void)    /* Opcode 0x70 */
1374 {
1375 	int tmp = (int)((INT8)FETCH);
1376 	if (OF)
1377 	{
1378 		I.pc += tmp;
1379 		ICOUNT -= cycles.jcc_t;
1380 /* ASG - can probably assume this is safe
1381 		CHANGE_PC(I.pc);*/
1382 	} else ICOUNT -= cycles.jcc_nt;
1383 }
1384 
PREFIX86(_jno)1385 static void PREFIX86(_jno)(void)    /* Opcode 0x71 */
1386 {
1387 	int tmp = (int)((INT8)FETCH);
1388 	if (!OF) {
1389 		I.pc += tmp;
1390 		ICOUNT -= cycles.jcc_t;
1391 /* ASG - can probably assume this is safe
1392 		CHANGE_PC(I.pc);*/
1393 	} else ICOUNT -= cycles.jcc_nt;
1394 }
1395 
PREFIX86(_jb)1396 static void PREFIX86(_jb)(void)    /* Opcode 0x72 */
1397 {
1398 	int tmp = (int)((INT8)FETCH);
1399 	if (CF) {
1400 		I.pc += tmp;
1401 		ICOUNT -= cycles.jcc_t;
1402 /* ASG - can probably assume this is safe
1403 		CHANGE_PC(I.pc);*/
1404 	} else ICOUNT -= cycles.jcc_nt;
1405 }
1406 
PREFIX86(_jnb)1407 static void PREFIX86(_jnb)(void)    /* Opcode 0x73 */
1408 {
1409 	int tmp = (int)((INT8)FETCH);
1410 	if (!CF) {
1411 		I.pc += tmp;
1412 		ICOUNT -= cycles.jcc_t;
1413 /* ASG - can probably assume this is safe
1414 		CHANGE_PC(I.pc);*/
1415 	} else ICOUNT -= cycles.jcc_nt;
1416 }
1417 
PREFIX86(_jz)1418 static void PREFIX86(_jz)(void)    /* Opcode 0x74 */
1419 {
1420 	int tmp = (int)((INT8)FETCH);
1421 	if (ZF) {
1422 		I.pc += tmp;
1423 		ICOUNT -= cycles.jcc_t;
1424 /* ASG - can probably assume this is safe
1425 		CHANGE_PC(I.pc);*/
1426 	} else ICOUNT -= cycles.jcc_nt;
1427 }
1428 
PREFIX86(_jnz)1429 static void PREFIX86(_jnz)(void)    /* Opcode 0x75 */
1430 {
1431 	int tmp = (int)((INT8)FETCH);
1432 	if (!ZF) {
1433 		I.pc += tmp;
1434 		ICOUNT -= cycles.jcc_t;
1435 /* ASG - can probably assume this is safe
1436 		CHANGE_PC(I.pc);*/
1437 	} else ICOUNT -= cycles.jcc_nt;
1438 }
1439 
PREFIX86(_jbe)1440 static void PREFIX86(_jbe)(void)    /* Opcode 0x76 */
1441 {
1442 	int tmp = (int)((INT8)FETCH);
1443     if (CF || ZF) {
1444 		I.pc += tmp;
1445 		ICOUNT -= cycles.jcc_t;
1446 /* ASG - can probably assume this is safe
1447 		CHANGE_PC(I.pc);*/
1448 	} else ICOUNT -= cycles.jcc_nt;
1449 }
1450 
PREFIX86(_jnbe)1451 static void PREFIX86(_jnbe)(void)    /* Opcode 0x77 */
1452 {
1453 	int tmp = (int)((INT8)FETCH);
1454 	 if (!(CF || ZF)) {
1455 		I.pc += tmp;
1456 		ICOUNT -= cycles.jcc_t;
1457 /* ASG - can probably assume this is safe
1458 		CHANGE_PC(I.pc);*/
1459 	} else ICOUNT -= cycles.jcc_nt;
1460 }
1461 
PREFIX86(_js)1462 static void PREFIX86(_js)(void)    /* Opcode 0x78 */
1463 {
1464 	int tmp = (int)((INT8)FETCH);
1465     if (SF) {
1466 		I.pc += tmp;
1467 		ICOUNT -= cycles.jcc_t;
1468 /* ASG - can probably assume this is safe
1469 		CHANGE_PC(I.pc);*/
1470 	} else ICOUNT -= cycles.jcc_nt;
1471 }
1472 
PREFIX86(_jns)1473 static void PREFIX86(_jns)(void)    /* Opcode 0x79 */
1474 {
1475 	int tmp = (int)((INT8)FETCH);
1476     if (!SF) {
1477 		I.pc += tmp;
1478 		ICOUNT -= cycles.jcc_t;
1479 /* ASG - can probably assume this is safe
1480 		CHANGE_PC(I.pc);*/
1481 	} else ICOUNT -= cycles.jcc_nt;
1482 }
1483 
PREFIX86(_jp)1484 static void PREFIX86(_jp)(void)    /* Opcode 0x7a */
1485 {
1486 	int tmp = (int)((INT8)FETCH);
1487     if (PF) {
1488 		I.pc += tmp;
1489 		ICOUNT -= cycles.jcc_t;
1490 /* ASG - can probably assume this is safe
1491 		CHANGE_PC(I.pc);*/
1492 	} else ICOUNT -= cycles.jcc_nt;
1493 }
1494 
PREFIX86(_jnp)1495 static void PREFIX86(_jnp)(void)    /* Opcode 0x7b */
1496 {
1497 	int tmp = (int)((INT8)FETCH);
1498     if (!PF) {
1499 		I.pc += tmp;
1500 		ICOUNT -= cycles.jcc_t;
1501 /* ASG - can probably assume this is safe
1502 		CHANGE_PC(I.pc);*/
1503 	} else ICOUNT -= cycles.jcc_nt;
1504 }
1505 
PREFIX86(_jl)1506 static void PREFIX86(_jl)(void)    /* Opcode 0x7c */
1507 {
1508 	int tmp = (int)((INT8)FETCH);
1509     if ((SF!=OF)&&!ZF) {
1510 		I.pc += tmp;
1511 		ICOUNT -= cycles.jcc_t;
1512 /* ASG - can probably assume this is safe
1513 		CHANGE_PC(I.pc);*/
1514 	} else ICOUNT -= cycles.jcc_nt;
1515 }
1516 
PREFIX86(_jnl)1517 static void PREFIX86(_jnl)(void)    /* Opcode 0x7d */
1518 {
1519 	int tmp = (int)((INT8)FETCH);
1520     if (ZF||(SF==OF)) {
1521 		I.pc += tmp;
1522 		ICOUNT -= cycles.jcc_t;
1523 /* ASG - can probably assume this is safe
1524 		CHANGE_PC(I.pc);*/
1525 	} else ICOUNT -= cycles.jcc_nt;
1526 }
1527 
PREFIX86(_jle)1528 static void PREFIX86(_jle)(void)    /* Opcode 0x7e */
1529 {
1530 	int tmp = (int)((INT8)FETCH);
1531     if (ZF||(SF!=OF)) {
1532 		I.pc += tmp;
1533 		ICOUNT -= cycles.jcc_t;
1534 /* ASG - can probably assume this is safe
1535 		CHANGE_PC(I.pc);*/
1536 	} else ICOUNT -= cycles.jcc_nt;
1537 }
1538 
PREFIX86(_jnle)1539 static void PREFIX86(_jnle)(void)    /* Opcode 0x7f */
1540 {
1541 	int tmp = (int)((INT8)FETCH);
1542     if ((SF==OF)&&!ZF) {
1543 		I.pc += tmp;
1544 		ICOUNT -= cycles.jcc_t;
1545 /* ASG - can probably assume this is safe
1546 		CHANGE_PC(I.pc);*/
1547 	} else ICOUNT -= cycles.jcc_nt;
1548 }
1549 
PREFIX86(_80pre)1550 static void PREFIX86(_80pre)(void)    /* Opcode 0x80 */
1551 {
1552 	unsigned ModRM = FETCHOP;
1553 	unsigned dst = GetRMByte(ModRM);
1554     unsigned src = FETCH;
1555 
1556     switch (ModRM & 0x38)
1557 	{
1558     case 0x00:  /* ADD eb,d8 */
1559         ADDB(dst,src);
1560         PutbackRMByte(ModRM,dst);
1561         ICOUNT -= (ModRM >= 0xc0) ? cycles.alu_ri8 : cycles.alu_mi8;
1562 		break;
1563     case 0x08:  /* OR eb,d8 */
1564         ORB(dst,src);
1565 		PutbackRMByte(ModRM,dst);
1566         ICOUNT -= (ModRM >= 0xc0) ? cycles.alu_ri8 : cycles.alu_mi8;
1567 		break;
1568     case 0x10:  /* ADC eb,d8 */
1569         src+=CF;
1570         ADDB(dst,src);
1571 		PutbackRMByte(ModRM,dst);
1572         ICOUNT -= (ModRM >= 0xc0) ? cycles.alu_ri8 : cycles.alu_mi8;
1573 		break;
1574     case 0x18:  /* SBB eb,b8 */
1575 		src+=CF;
1576 		SUBB(dst,src);
1577         PutbackRMByte(ModRM,dst);
1578         ICOUNT -= (ModRM >= 0xc0) ? cycles.alu_ri8 : cycles.alu_mi8;
1579 		break;
1580     case 0x20:  /* AND eb,d8 */
1581         ANDB(dst,src);
1582 		PutbackRMByte(ModRM,dst);
1583         ICOUNT -= (ModRM >= 0xc0) ? cycles.alu_ri8 : cycles.alu_mi8;
1584 		break;
1585     case 0x28:  /* SUB eb,d8 */
1586         SUBB(dst,src);
1587         PutbackRMByte(ModRM,dst);
1588         ICOUNT -= (ModRM >= 0xc0) ? cycles.alu_ri8 : cycles.alu_mi8;
1589 		break;
1590     case 0x30:  /* XOR eb,d8 */
1591         XORB(dst,src);
1592 		PutbackRMByte(ModRM,dst);
1593         ICOUNT -= (ModRM >= 0xc0) ? cycles.alu_ri8 : cycles.alu_mi8;
1594 		break;
1595     case 0x38:  /* CMP eb,d8 */
1596         SUBB(dst,src);
1597         ICOUNT -= (ModRM >= 0xc0) ? cycles.alu_ri8 : cycles.alu_mi8_ro;
1598 		break;
1599 	}
1600 }
1601 
1602 
PREFIX86(_81pre)1603 static void PREFIX86(_81pre)(void)    /* Opcode 0x81 */
1604 {
1605 	unsigned ModRM = FETCH;
1606 	unsigned dst = GetRMWord(ModRM);
1607     unsigned src = FETCH;
1608     src+= (FETCH << 8);
1609 
1610 	switch (ModRM & 0x38)
1611     {
1612     case 0x00:  /* ADD ew,d16 */
1613 		ADDW(dst,src);
1614 		PutbackRMWord(ModRM,dst);
1615         ICOUNT -= (ModRM >= 0xc0) ? cycles.alu_ri16 : cycles.alu_mi16;
1616 		break;
1617     case 0x08:  /* OR ew,d16 */
1618         ORW(dst,src);
1619         PutbackRMWord(ModRM,dst);
1620         ICOUNT -= (ModRM >= 0xc0) ? cycles.alu_ri16 : cycles.alu_mi16;
1621 		break;
1622 	case 0x10:	/* ADC ew,d16 */
1623 		src+=CF;
1624 		ADDW(dst,src);
1625         PutbackRMWord(ModRM,dst);
1626         ICOUNT -= (ModRM >= 0xc0) ? cycles.alu_ri16 : cycles.alu_mi16;
1627 		break;
1628     case 0x18:  /* SBB ew,d16 */
1629         src+=CF;
1630 		SUBW(dst,src);
1631         PutbackRMWord(ModRM,dst);
1632         ICOUNT -= (ModRM >= 0xc0) ? cycles.alu_ri16 : cycles.alu_mi16;
1633 		break;
1634     case 0x20:  /* AND ew,d16 */
1635         ANDW(dst,src);
1636 		PutbackRMWord(ModRM,dst);
1637         ICOUNT -= (ModRM >= 0xc0) ? cycles.alu_ri16 : cycles.alu_mi16;
1638 		break;
1639     case 0x28:  /* SUB ew,d16 */
1640         SUBW(dst,src);
1641         PutbackRMWord(ModRM,dst);
1642         ICOUNT -= (ModRM >= 0xc0) ? cycles.alu_ri16 : cycles.alu_mi16;
1643 		break;
1644     case 0x30:  /* XOR ew,d16 */
1645 		XORW(dst,src);
1646         PutbackRMWord(ModRM,dst);
1647         ICOUNT -= (ModRM >= 0xc0) ? cycles.alu_ri16 : cycles.alu_mi16;
1648 		break;
1649     case 0x38:  /* CMP ew,d16 */
1650         SUBW(dst,src);
1651         ICOUNT -= (ModRM >= 0xc0) ? cycles.alu_ri16 : cycles.alu_mi16_ro;
1652 		break;
1653     }
1654 }
1655 
PREFIX86(_82pre)1656 static void PREFIX86(_82pre)(void)	 /* Opcode 0x82 */
1657 {
1658 	unsigned ModRM = FETCH;
1659 	unsigned dst = GetRMByte(ModRM);
1660 	unsigned src = FETCH;
1661 
1662 	switch (ModRM & 0x38)
1663 	{
1664 	case 0x00:	/* ADD eb,d8 */
1665 		ADDB(dst,src);
1666 		PutbackRMByte(ModRM,dst);
1667         ICOUNT -= (ModRM >= 0xc0) ? cycles.alu_ri8 : cycles.alu_mi8;
1668 		break;
1669 	case 0x08:	/* OR eb,d8 */
1670 		ORB(dst,src);
1671 		PutbackRMByte(ModRM,dst);
1672         ICOUNT -= (ModRM >= 0xc0) ? cycles.alu_ri8 : cycles.alu_mi8;
1673 		break;
1674 	case 0x10:	/* ADC eb,d8 */
1675 		src+=CF;
1676 		ADDB(dst,src);
1677 		PutbackRMByte(ModRM,dst);
1678         ICOUNT -= (ModRM >= 0xc0) ? cycles.alu_ri8 : cycles.alu_mi8;
1679 		break;
1680 	case 0x18:	/* SBB eb,d8 */
1681         src+=CF;
1682 		SUBB(dst,src);
1683 		PutbackRMByte(ModRM,dst);
1684         ICOUNT -= (ModRM >= 0xc0) ? cycles.alu_ri8 : cycles.alu_mi8;
1685 		break;
1686 	case 0x20:	/* AND eb,d8 */
1687 		ANDB(dst,src);
1688 		PutbackRMByte(ModRM,dst);
1689         ICOUNT -= (ModRM >= 0xc0) ? cycles.alu_ri8 : cycles.alu_mi8;
1690 		break;
1691 	case 0x28:	/* SUB eb,d8 */
1692 		SUBB(dst,src);
1693 		PutbackRMByte(ModRM,dst);
1694         ICOUNT -= (ModRM >= 0xc0) ? cycles.alu_ri8 : cycles.alu_mi8;
1695 		break;
1696 	case 0x30:	/* XOR eb,d8 */
1697 		XORB(dst,src);
1698 		PutbackRMByte(ModRM,dst);
1699         ICOUNT -= (ModRM >= 0xc0) ? cycles.alu_ri8 : cycles.alu_mi8;
1700 		break;
1701 	case 0x38:	/* CMP eb,d8 */
1702 		SUBB(dst,src);
1703         ICOUNT -= (ModRM >= 0xc0) ? cycles.alu_ri8 : cycles.alu_mi8_ro;
1704 		break;
1705 	}
1706 }
1707 
PREFIX86(_83pre)1708 static void PREFIX86(_83pre)(void)    /* Opcode 0x83 */
1709 {
1710 	unsigned ModRM = FETCH;
1711     unsigned dst = GetRMWord(ModRM);
1712     unsigned src = (WORD)((INT16)((INT8)FETCH));
1713 
1714 	switch (ModRM & 0x38)
1715     {
1716     case 0x00:  /* ADD ew,d16 */
1717         ADDW(dst,src);
1718         PutbackRMWord(ModRM,dst);
1719         ICOUNT -= (ModRM >= 0xc0) ? cycles.alu_r16i8 : cycles.alu_m16i8;
1720 		break;
1721     case 0x08:  /* OR ew,d16 */
1722 		ORW(dst,src);
1723         PutbackRMWord(ModRM,dst);
1724         ICOUNT -= (ModRM >= 0xc0) ? cycles.alu_r16i8 : cycles.alu_m16i8;
1725 		break;
1726     case 0x10:  /* ADC ew,d16 */
1727         src+=CF;
1728 		ADDW(dst,src);
1729         PutbackRMWord(ModRM,dst);
1730         ICOUNT -= (ModRM >= 0xc0) ? cycles.alu_r16i8 : cycles.alu_m16i8;
1731 		break;
1732 	case 0x18:	/* SBB ew,d16 */
1733 		src+=CF;
1734         SUBW(dst,src);
1735         PutbackRMWord(ModRM,dst);
1736         ICOUNT -= (ModRM >= 0xc0) ? cycles.alu_r16i8 : cycles.alu_m16i8;
1737 		break;
1738 	case 0x20:	/* AND ew,d16 */
1739         ANDW(dst,src);
1740         PutbackRMWord(ModRM,dst);
1741         ICOUNT -= (ModRM >= 0xc0) ? cycles.alu_r16i8 : cycles.alu_m16i8;
1742 		break;
1743     case 0x28:  /* SUB ew,d16 */
1744 		SUBW(dst,src);
1745 		PutbackRMWord(ModRM,dst);
1746         ICOUNT -= (ModRM >= 0xc0) ? cycles.alu_r16i8 : cycles.alu_m16i8;
1747 		break;
1748     case 0x30:  /* XOR ew,d16 */
1749 		XORW(dst,src);
1750         PutbackRMWord(ModRM,dst);
1751         ICOUNT -= (ModRM >= 0xc0) ? cycles.alu_r16i8 : cycles.alu_m16i8;
1752 		break;
1753     case 0x38:  /* CMP ew,d16 */
1754         SUBW(dst,src);
1755         ICOUNT -= (ModRM >= 0xc0) ? cycles.alu_r16i8 : cycles.alu_m16i8_ro;
1756 		break;
1757     }
1758 }
1759 
PREFIX86(_test_br8)1760 static void PREFIX86(_test_br8)(void)    /* Opcode 0x84 */
1761 {
1762     DEF_br8(dst,src);
1763 	ICOUNT -= (ModRM >= 0xc0) ? cycles.alu_rr8 : cycles.alu_rm8;
1764     ANDB(dst,src);
1765 }
1766 
PREFIX86(_test_wr16)1767 static void PREFIX86(_test_wr16)(void)    /* Opcode 0x85 */
1768 {
1769     DEF_wr16(dst,src);
1770 	ICOUNT -= (ModRM >= 0xc0) ? cycles.alu_rr16 : cycles.alu_rm16;
1771 	ANDW(dst,src);
1772 }
1773 
PREFIX86(_xchg_br8)1774 static void PREFIX86(_xchg_br8)(void)    /* Opcode 0x86 */
1775 {
1776     DEF_br8(dst,src);
1777 	ICOUNT -= (ModRM >= 0xc0) ? cycles.xchg_rr8 : cycles.xchg_rm8;
1778     RegByte(ModRM)=dst;
1779     PutbackRMByte(ModRM,src);
1780 }
1781 
PREFIX86(_xchg_wr16)1782 static void PREFIX86(_xchg_wr16)(void)    /* Opcode 0x87 */
1783 {
1784     DEF_wr16(dst,src);
1785 	ICOUNT -= (ModRM >= 0xc0) ? cycles.xchg_rr16 : cycles.xchg_rm16;
1786     RegWord(ModRM)=dst;
1787     PutbackRMWord(ModRM,src);
1788 }
1789 
PREFIX86(_mov_br8)1790 static void PREFIX86(_mov_br8)(void)    /* Opcode 0x88 */
1791 {
1792 	unsigned ModRM = FETCH;
1793     BYTE src = RegByte(ModRM);
1794 	ICOUNT -= (ModRM >= 0xc0) ? cycles.mov_rr8 : cycles.mov_mr8;
1795     PutRMByte(ModRM,src);
1796 }
1797 
PREFIX86(_mov_wr16)1798 static void PREFIX86(_mov_wr16)(void)    /* Opcode 0x89 */
1799 {
1800 	unsigned ModRM = FETCH;
1801     WORD src = RegWord(ModRM);
1802 	ICOUNT -= (ModRM >= 0xc0) ? cycles.mov_rr16 : cycles.mov_mr16;
1803     PutRMWord(ModRM,src);
1804 }
1805 
PREFIX86(_mov_r8b)1806 static void PREFIX86(_mov_r8b)(void)    /* Opcode 0x8a */
1807 {
1808 	unsigned ModRM = FETCH;
1809     BYTE src = GetRMByte(ModRM);
1810 	ICOUNT -= (ModRM >= 0xc0) ? cycles.mov_rr8 : cycles.mov_rm8;
1811     RegByte(ModRM)=src;
1812 }
1813 
PREFIX86(_mov_r16w)1814 static void PREFIX86(_mov_r16w)(void)    /* Opcode 0x8b */
1815 {
1816 	unsigned ModRM = FETCH;
1817 	WORD src = GetRMWord(ModRM);
1818 	ICOUNT -= (ModRM >= 0xc0) ? cycles.mov_rr8 : cycles.mov_rm16;
1819 	RegWord(ModRM)=src;
1820 }
1821 
PREFIX86(_mov_wsreg)1822 static void PREFIX86(_mov_wsreg)(void)    /* Opcode 0x8c */
1823 {
1824 	unsigned ModRM = FETCH;
1825 	ICOUNT -= (ModRM >= 0xc0) ? cycles.mov_rs : cycles.mov_ms;
1826 #ifdef I286
1827 	if (ModRM & 0x20) {	/* HJB 12/13/98 1xx is invalid */
1828 		i286_trap2(ILLEGAL_INSTRUCTION);
1829 		return;
1830 	}
1831 #else
1832 	if (ModRM & 0x20) return;	/* HJB 12/13/98 1xx is invalid */
1833 #endif
1834 	PutRMWord(ModRM,I.sregs[(ModRM & 0x38) >> 3]);
1835 }
1836 
PREFIX86(_lea)1837 static void PREFIX86(_lea)(void)    /* Opcode 0x8d */
1838 {
1839 	unsigned ModRM = FETCH;
1840 	ICOUNT -= cycles.lea;
1841 	(void)(*GetEA[ModRM])();
1842 	RegWord(ModRM)=EO;	/* HJB 12/13/98 effective offset (no segment part) */
1843 }
1844 
PREFIX86(_mov_sregw)1845 static void PREFIX86(_mov_sregw)(void)    /* Opcode 0x8e */
1846 {
1847 	unsigned ModRM = FETCH;
1848     WORD src = GetRMWord(ModRM);
1849 
1850 	ICOUNT -= (ModRM >= 0xc0) ? cycles.mov_sr : cycles.mov_sm;
1851 #ifdef I286
1852     switch (ModRM & 0x38)
1853     {
1854     case 0x00:  /* mov es,ew */
1855 		i286_data_descriptor(ES,src);
1856 		break;
1857     case 0x18:  /* mov ds,ew */
1858 		i286_data_descriptor(DS,src);
1859 		break;
1860     case 0x10:  /* mov ss,ew */
1861 		i286_data_descriptor(SS,src);
1862 		PREFIX(_instruction)[FETCHOP]();
1863 		break;
1864     case 0x08:  /* mov cs,ew */
1865 		break;  /* doesn't do a jump far */
1866     }
1867 #else
1868     switch (ModRM & 0x38)
1869     {
1870     case 0x00:  /* mov es,ew */
1871 		I.sregs[ES] = src;
1872 		I.base[ES] = SegBase(ES);
1873 		break;
1874     case 0x18:  /* mov ds,ew */
1875 		I.sregs[DS] = src;
1876 		I.base[DS] = SegBase(DS);
1877 		break;
1878     case 0x10:  /* mov ss,ew */
1879 		I.sregs[SS] = src;
1880 		I.base[SS] = SegBase(SS); /* no interrupt allowed before next instr */
1881 		PREFIX(_instruction)[FETCHOP]();
1882 		break;
1883     case 0x08:  /* mov cs,ew */
1884 		break;  /* doesn't do a jump far */
1885     }
1886 #endif
1887 }
1888 
PREFIX86(_popw)1889 static void PREFIX86(_popw)(void)    /* Opcode 0x8f */
1890 {
1891 	unsigned ModRM = FETCH;
1892     WORD tmp;
1893 	POP(tmp);
1894 	ICOUNT -= (ModRM >= 0xc0) ? cycles.pop_r16 : cycles.pop_m16;
1895 	PutRMWord(ModRM,tmp);
1896 }
1897 
1898 
1899 #define XchgAXReg(Reg) 				\
1900 { 									\
1901     WORD tmp; 						\
1902 	tmp = I.regs.w[Reg]; 			\
1903 	I.regs.w[Reg] = I.regs.w[AX]; 	\
1904 	I.regs.w[AX] = tmp; 			\
1905 	ICOUNT -= cycles.xchg_ar16; 	\
1906 }
1907 
1908 
PREFIX86(_nop)1909 static void PREFIX86(_nop)(void)    /* Opcode 0x90 */
1910 {
1911     /* this is XchgAXReg(AX); */
1912 	ICOUNT -= cycles.nop;
1913 }
1914 
PREFIX86(_xchg_axcx)1915 static void PREFIX86(_xchg_axcx)(void)    /* Opcode 0x91 */
1916 {
1917 	XchgAXReg(CX);
1918 }
1919 
PREFIX86(_xchg_axdx)1920 static void PREFIX86(_xchg_axdx)(void)    /* Opcode 0x92 */
1921 {
1922     XchgAXReg(DX);
1923 }
1924 
PREFIX86(_xchg_axbx)1925 static void PREFIX86(_xchg_axbx)(void)    /* Opcode 0x93 */
1926 {
1927 	XchgAXReg(BX);
1928 }
1929 
PREFIX86(_xchg_axsp)1930 static void PREFIX86(_xchg_axsp)(void)    /* Opcode 0x94 */
1931 {
1932 	XchgAXReg(SP);
1933 }
1934 
PREFIX86(_xchg_axbp)1935 static void PREFIX86(_xchg_axbp)(void)    /* Opcode 0x95 */
1936 {
1937     XchgAXReg(BP);
1938 }
1939 
PREFIX86(_xchg_axsi)1940 static void PREFIX86(_xchg_axsi)(void)    /* Opcode 0x96 */
1941 {
1942 	XchgAXReg(SI);
1943 }
1944 
PREFIX86(_xchg_axdi)1945 static void PREFIX86(_xchg_axdi)(void)    /* Opcode 0x97 */
1946 {
1947 	XchgAXReg(DI);
1948 }
1949 
PREFIX86(_cbw)1950 static void PREFIX86(_cbw)(void)    /* Opcode 0x98 */
1951 {
1952 	ICOUNT -= cycles.cbw;
1953 	I.regs.b[AH] = (I.regs.b[AL] & 0x80) ? 0xff : 0;
1954 }
1955 
PREFIX86(_cwd)1956 static void PREFIX86(_cwd)(void)    /* Opcode 0x99 */
1957 {
1958 	ICOUNT -= cycles.cwd;
1959 	I.regs.w[DX] = (I.regs.b[AH] & 0x80) ? 0xffff : 0;
1960 }
1961 
PREFIX86(_call_far)1962 static void PREFIX86(_call_far)(void)
1963 {
1964     unsigned tmp, tmp2;
1965 	WORD ip;
1966 
1967 	tmp = FETCH;
1968 	tmp += FETCH << 8;
1969 
1970 	tmp2 = FETCH;
1971 	tmp2 += FETCH << 8;
1972 
1973 	ip = I.pc - I.base[CS];
1974 	PUSH(I.sregs[CS]);
1975 	PUSH(ip);
1976 
1977 #ifdef I286
1978 	i286_code_descriptor(tmp2, tmp);
1979 #else
1980 	I.sregs[CS] = (WORD)tmp2;
1981 	I.base[CS] = SegBase(CS);
1982 	I.pc = (I.base[CS] + (WORD)tmp) & AMASK;
1983 #endif
1984 	ICOUNT -= cycles.call_far;
1985 	CHANGE_PC(I.pc);
1986 }
1987 
PREFIX86(_wait)1988 static void PREFIX86(_wait)(void)    /* Opcode 0x9b */
1989 {
1990 	ICOUNT -= cycles.wait;
1991 }
1992 
PREFIX86(_pushf)1993 static void PREFIX86(_pushf)(void)    /* Opcode 0x9c */
1994 {
1995 	ICOUNT -= cycles.pushf;
1996 #ifdef I286
1997     PUSH( CompressFlags() | 0xc000 );
1998 #elif defined V20
1999     PUSH( CompressFlags() | 0xe000 );
2000 #else
2001     PUSH( CompressFlags() | 0xf000 );
2002 #endif
2003 }
2004 
PREFIX86(_popf)2005 static void PREFIX86(_popf)(void)    /* Opcode 0x9d */
2006 {
2007 	unsigned tmp;
2008     POP(tmp);
2009 	ICOUNT -= cycles.popf;
2010     ExpandFlags(tmp);
2011 
2012 	if (I.TF) PREFIX(_trap)();
2013 
2014 	/* if the IF is set, and an interrupt is pending, signal an interrupt */
2015 	if (I.IF && I.irq_state)
2016 #ifdef V20
2017 		PREFIX(_interrupt)(-1, 0);
2018 #else
2019 		PREFIX(_interrupt)(-1);
2020 #endif
2021 }
2022 
PREFIX86(_sahf)2023 static void PREFIX86(_sahf)(void)    /* Opcode 0x9e */
2024 {
2025 	unsigned tmp = (CompressFlags() & 0xff00) | (I.regs.b[AH] & 0xd5);
2026 	ICOUNT -= cycles.sahf;
2027     ExpandFlags(tmp);
2028 }
2029 
PREFIX86(_lahf)2030 static void PREFIX86(_lahf)(void)    /* Opcode 0x9f */
2031 {
2032 	I.regs.b[AH] = CompressFlags() & 0xff;
2033 	ICOUNT -= cycles.lahf;
2034 }
2035 
2036 
PREFIX86(_mov_aldisp)2037 static void PREFIX86(_mov_aldisp)(void)    /* Opcode 0xa0 */
2038 {
2039 	unsigned addr;
2040 
2041 	addr = FETCH;
2042 	addr += FETCH << 8;
2043 
2044 	ICOUNT -= cycles.mov_am8;
2045 	I.regs.b[AL] = GetMemB(DS, addr);
2046 }
2047 
PREFIX86(_mov_axdisp)2048 static void PREFIX86(_mov_axdisp)(void)    /* Opcode 0xa1 */
2049 {
2050 	unsigned addr;
2051 
2052 	addr = FETCH;
2053 	addr += FETCH << 8;
2054 
2055 	ICOUNT -= cycles.mov_am16;
2056 	I.regs.b[AL] = GetMemB(DS, addr);
2057 	I.regs.b[AH] = GetMemB(DS, addr+1);
2058 }
2059 
PREFIX86(_mov_dispal)2060 static void PREFIX86(_mov_dispal)(void)    /* Opcode 0xa2 */
2061 {
2062     unsigned addr;
2063 
2064 	addr = FETCH;
2065 	addr += FETCH << 8;
2066 
2067 	ICOUNT -= cycles.mov_ma8;
2068 	PutMemB(DS, addr, I.regs.b[AL]);
2069 }
2070 
PREFIX86(_mov_dispax)2071 static void PREFIX86(_mov_dispax)(void)    /* Opcode 0xa3 */
2072 {
2073 	unsigned addr;
2074 
2075 	addr = FETCH;
2076 	addr += FETCH << 8;
2077 
2078 	ICOUNT -= cycles.mov_ma16;
2079 	PutMemB(DS, addr, I.regs.b[AL]);
2080 	PutMemB(DS, addr+1, I.regs.b[AH]);
2081 }
2082 
PREFIX86(_movsb)2083 static void PREFIX86(_movsb)(void)    /* Opcode 0xa4 */
2084 {
2085 	BYTE tmp = GetMemB(DS,I.regs.w[SI]);
2086 	PutMemB(ES,I.regs.w[DI], tmp);
2087 	I.regs.w[DI] += I.DirVal;
2088 	I.regs.w[SI] += I.DirVal;
2089 	ICOUNT -= cycles.movs8;
2090 }
2091 
PREFIX86(_movsw)2092 static void PREFIX86(_movsw)(void)    /* Opcode 0xa5 */
2093 {
2094 	WORD tmp = GetMemW(DS,I.regs.w[SI]);
2095 	PutMemW(ES,I.regs.w[DI], tmp);
2096 	I.regs.w[DI] += 2 * I.DirVal;
2097 	I.regs.w[SI] += 2 * I.DirVal;
2098 	ICOUNT -= cycles.movs16;
2099 }
2100 
PREFIX86(_cmpsb)2101 static void PREFIX86(_cmpsb)(void)    /* Opcode 0xa6 */
2102 {
2103 	unsigned dst = GetMemB(ES, I.regs.w[DI]);
2104 	unsigned src = GetMemB(DS, I.regs.w[SI]);
2105     SUBB(src,dst); /* opposite of the usual convention */
2106 	I.regs.w[DI] += I.DirVal;
2107 	I.regs.w[SI] += I.DirVal;
2108 	ICOUNT -= cycles.cmps8;
2109 }
2110 
PREFIX86(_cmpsw)2111 static void PREFIX86(_cmpsw)(void)    /* Opcode 0xa7 */
2112 {
2113 	unsigned dst = GetMemW(ES, I.regs.w[DI]);
2114 	unsigned src = GetMemW(DS, I.regs.w[SI]);
2115 	SUBW(src,dst); /* opposite of the usual convention */
2116 	I.regs.w[DI] += 2 * I.DirVal;
2117 	I.regs.w[SI] += 2 * I.DirVal;
2118 	ICOUNT -= cycles.cmps16;
2119 }
2120 
PREFIX86(_test_ald8)2121 static void PREFIX86(_test_ald8)(void)    /* Opcode 0xa8 */
2122 {
2123     DEF_ald8(dst,src);
2124 	ICOUNT -= cycles.alu_ri8;
2125     ANDB(dst,src);
2126 }
2127 
PREFIX86(_test_axd16)2128 static void PREFIX86(_test_axd16)(void)    /* Opcode 0xa9 */
2129 {
2130     DEF_axd16(dst,src);
2131 	ICOUNT -= cycles.alu_ri16;
2132     ANDW(dst,src);
2133 }
2134 
PREFIX86(_stosb)2135 static void PREFIX86(_stosb)(void)    /* Opcode 0xaa */
2136 {
2137 	PutMemB(ES,I.regs.w[DI],I.regs.b[AL]);
2138 	I.regs.w[DI] += I.DirVal;
2139 	ICOUNT -= cycles.stos8;
2140 }
2141 
PREFIX86(_stosw)2142 static void PREFIX86(_stosw)(void)    /* Opcode 0xab */
2143 {
2144 	PutMemB(ES,I.regs.w[DI],I.regs.b[AL]);
2145 	PutMemB(ES,I.regs.w[DI]+1,I.regs.b[AH]);
2146 	I.regs.w[DI] += 2 * I.DirVal;
2147 	ICOUNT -= cycles.stos16;
2148 }
2149 
PREFIX86(_lodsb)2150 static void PREFIX86(_lodsb)(void)    /* Opcode 0xac */
2151 {
2152 	I.regs.b[AL] = GetMemB(DS,I.regs.w[SI]);
2153 	I.regs.w[SI] += I.DirVal;
2154 	ICOUNT -= cycles.lods8;
2155 }
2156 
PREFIX86(_lodsw)2157 static void PREFIX86(_lodsw)(void)    /* Opcode 0xad */
2158 {
2159 	I.regs.w[AX] = GetMemW(DS,I.regs.w[SI]);
2160 	I.regs.w[SI] += 2 * I.DirVal;
2161 	ICOUNT -= cycles.lods16;
2162 }
2163 
PREFIX86(_scasb)2164 static void PREFIX86(_scasb)(void)    /* Opcode 0xae */
2165 {
2166 	unsigned src = GetMemB(ES, I.regs.w[DI]);
2167 	unsigned dst = I.regs.b[AL];
2168     SUBB(dst,src);
2169 	I.regs.w[DI] += I.DirVal;
2170 	ICOUNT -= cycles.scas8;
2171 }
2172 
PREFIX86(_scasw)2173 static void PREFIX86(_scasw)(void)    /* Opcode 0xaf */
2174 {
2175 	unsigned src = GetMemW(ES, I.regs.w[DI]);
2176 	unsigned dst = I.regs.w[AX];
2177     SUBW(dst,src);
2178 	I.regs.w[DI] += 2 * I.DirVal;
2179 	ICOUNT -= cycles.scas16;
2180 }
2181 
PREFIX86(_mov_ald8)2182 static void PREFIX86(_mov_ald8)(void)    /* Opcode 0xb0 */
2183 {
2184 	I.regs.b[AL] = FETCH;
2185 	ICOUNT -= cycles.mov_ri8;
2186 }
2187 
PREFIX86(_mov_cld8)2188 static void PREFIX86(_mov_cld8)(void)    /* Opcode 0xb1 */
2189 {
2190 	I.regs.b[CL] = FETCH;
2191 	ICOUNT -= cycles.mov_ri8;
2192 }
2193 
PREFIX86(_mov_dld8)2194 static void PREFIX86(_mov_dld8)(void)    /* Opcode 0xb2 */
2195 {
2196 	I.regs.b[DL] = FETCH;
2197 	ICOUNT -= cycles.mov_ri8;
2198 }
2199 
PREFIX86(_mov_bld8)2200 static void PREFIX86(_mov_bld8)(void)    /* Opcode 0xb3 */
2201 {
2202 	I.regs.b[BL] = FETCH;
2203 	ICOUNT -= cycles.mov_ri8;
2204 }
2205 
PREFIX86(_mov_ahd8)2206 static void PREFIX86(_mov_ahd8)(void)    /* Opcode 0xb4 */
2207 {
2208 	I.regs.b[AH] = FETCH;
2209 	ICOUNT -= cycles.mov_ri8;
2210 }
2211 
PREFIX86(_mov_chd8)2212 static void PREFIX86(_mov_chd8)(void)    /* Opcode 0xb5 */
2213 {
2214 	I.regs.b[CH] = FETCH;
2215 	ICOUNT -= cycles.mov_ri8;
2216 }
2217 
PREFIX86(_mov_dhd8)2218 static void PREFIX86(_mov_dhd8)(void)    /* Opcode 0xb6 */
2219 {
2220 	I.regs.b[DH] = FETCH;
2221 	ICOUNT -= cycles.mov_ri8;
2222 }
2223 
PREFIX86(_mov_bhd8)2224 static void PREFIX86(_mov_bhd8)(void)    /* Opcode 0xb7 */
2225 {
2226 	I.regs.b[BH] = FETCH;
2227 	ICOUNT -= cycles.mov_ri8;
2228 }
2229 
PREFIX86(_mov_axd16)2230 static void PREFIX86(_mov_axd16)(void)    /* Opcode 0xb8 */
2231 {
2232 	I.regs.b[AL] = FETCH;
2233 	I.regs.b[AH] = FETCH;
2234 	ICOUNT -= cycles.mov_ri16;
2235 }
2236 
PREFIX86(_mov_cxd16)2237 static void PREFIX86(_mov_cxd16)(void)    /* Opcode 0xb9 */
2238 {
2239 	I.regs.b[CL] = FETCH;
2240 	I.regs.b[CH] = FETCH;
2241 	ICOUNT -= cycles.mov_ri16;
2242 }
2243 
PREFIX86(_mov_dxd16)2244 static void PREFIX86(_mov_dxd16)(void)    /* Opcode 0xba */
2245 {
2246 	I.regs.b[DL] = FETCH;
2247 	I.regs.b[DH] = FETCH;
2248 	ICOUNT -= cycles.mov_ri16;
2249 }
2250 
PREFIX86(_mov_bxd16)2251 static void PREFIX86(_mov_bxd16)(void)    /* Opcode 0xbb */
2252 {
2253 	I.regs.b[BL] = FETCH;
2254 	I.regs.b[BH] = FETCH;
2255 	ICOUNT -= cycles.mov_ri16;
2256 }
2257 
PREFIX86(_mov_spd16)2258 static void PREFIX86(_mov_spd16)(void)    /* Opcode 0xbc */
2259 {
2260 	I.regs.b[SPL] = FETCH;
2261 	I.regs.b[SPH] = FETCH;
2262 	ICOUNT -= cycles.mov_ri16;
2263 }
2264 
PREFIX86(_mov_bpd16)2265 static void PREFIX86(_mov_bpd16)(void)    /* Opcode 0xbd */
2266 {
2267 	I.regs.b[BPL] = FETCH;
2268 	I.regs.b[BPH] = FETCH;
2269 	ICOUNT -= cycles.mov_ri16;
2270 }
2271 
PREFIX86(_mov_sid16)2272 static void PREFIX86(_mov_sid16)(void)    /* Opcode 0xbe */
2273 {
2274 	I.regs.b[SIL] = FETCH;
2275 	I.regs.b[SIH] = FETCH;
2276 	ICOUNT -= cycles.mov_ri16;
2277 }
2278 
PREFIX86(_mov_did16)2279 static void PREFIX86(_mov_did16)(void)    /* Opcode 0xbf */
2280 {
2281 	I.regs.b[DIL] = FETCH;
2282 	I.regs.b[DIH] = FETCH;
2283 	ICOUNT -= cycles.mov_ri16;
2284 }
2285 
PREFIX86(_ret_d16)2286 static void PREFIX86(_ret_d16)(void)    /* Opcode 0xc2 */
2287 {
2288 	unsigned count = FETCH;
2289 	count += FETCH << 8;
2290 	POP(I.pc);
2291 	I.pc = (I.pc + I.base[CS]) & AMASK;
2292 	I.regs.w[SP]+=count;
2293 	ICOUNT -= cycles.ret_near_imm;
2294 	CHANGE_PC(I.pc);
2295 }
2296 
PREFIX86(_ret)2297 static void PREFIX86(_ret)(void)    /* Opcode 0xc3 */
2298 {
2299 	POP(I.pc);
2300 	I.pc = (I.pc + I.base[CS]) & AMASK;
2301 	ICOUNT -= cycles.ret_near;
2302 	CHANGE_PC(I.pc);
2303 }
2304 
PREFIX86(_les_dw)2305 static void PREFIX86(_les_dw)(void)    /* Opcode 0xc4 */
2306 {
2307 	unsigned ModRM = FETCH;
2308     WORD tmp = GetRMWord(ModRM);
2309 
2310     RegWord(ModRM)= tmp;
2311 #ifdef I286
2312 	i286_data_descriptor(ES,GetnextRMWord);
2313 #else
2314 	I.sregs[ES] = GetnextRMWord;
2315 	I.base[ES] = SegBase(ES);
2316 #endif
2317 	ICOUNT -= cycles.load_ptr;
2318 }
2319 
PREFIX86(_lds_dw)2320 static void PREFIX86(_lds_dw)(void)    /* Opcode 0xc5 */
2321 {
2322 	unsigned ModRM = FETCH;
2323     WORD tmp = GetRMWord(ModRM);
2324 
2325     RegWord(ModRM)=tmp;
2326 #ifdef I286
2327 	i286_data_descriptor(DS,GetnextRMWord);
2328 #else
2329 	I.sregs[DS] = GetnextRMWord;
2330 	I.base[DS] = SegBase(DS);
2331 #endif
2332 	ICOUNT -= cycles.load_ptr;
2333 }
2334 
PREFIX86(_mov_bd8)2335 static void PREFIX86(_mov_bd8)(void)    /* Opcode 0xc6 */
2336 {
2337 	unsigned ModRM = FETCH;
2338 	ICOUNT -= (ModRM >= 0xc0) ? cycles.mov_ri8 : cycles.mov_mi8;
2339 	PutImmRMByte(ModRM);
2340 }
2341 
PREFIX86(_mov_wd16)2342 static void PREFIX86(_mov_wd16)(void)    /* Opcode 0xc7 */
2343 {
2344 	unsigned ModRM = FETCH;
2345 	ICOUNT -= (ModRM >= 0xc0) ? cycles.mov_ri16 : cycles.mov_mi16;
2346 	PutImmRMWord(ModRM);
2347 }
2348 
PREFIX86(_retf_d16)2349 static void PREFIX86(_retf_d16)(void)    /* Opcode 0xca */
2350 {
2351 	unsigned count = FETCH;
2352 	count += FETCH << 8;
2353 
2354 #ifdef I286
2355 	{
2356 		int tmp, tmp2;
2357 		POP(tmp2);
2358 		POP(tmp);
2359 		i286_code_descriptor(tmp, tmp2);
2360 	}
2361 #else
2362 	POP(I.pc);
2363 	POP(I.sregs[CS]);
2364 	I.base[CS] = SegBase(CS);
2365 	I.pc = (I.pc + I.base[CS]) & AMASK;
2366 #endif
2367 	I.regs.w[SP]+=count;
2368 	ICOUNT -= cycles.ret_far_imm;
2369 	CHANGE_PC(I.pc);
2370 }
2371 
PREFIX86(_retf)2372 static void PREFIX86(_retf)(void)    /* Opcode 0xcb */
2373 {
2374 #ifdef I286
2375 	{
2376 		int tmp, tmp2;
2377 		POP(tmp2);
2378 		POP(tmp);
2379 		i286_code_descriptor(tmp, tmp2);
2380 	}
2381 #else
2382 	POP(I.pc);
2383 	POP(I.sregs[CS]);
2384 	I.base[CS] = SegBase(CS);
2385 	I.pc = (I.pc + I.base[CS]) & AMASK;
2386 #endif
2387 	ICOUNT -= cycles.ret_far;
2388 	CHANGE_PC(I.pc);
2389 }
2390 
PREFIX86(_int3)2391 static void PREFIX86(_int3)(void)    /* Opcode 0xcc */
2392 {
2393 	ICOUNT -= cycles.int3;
2394 #ifdef V20
2395 	PREFIX(_interrupt)(3,0);
2396 #else
2397 	PREFIX(_interrupt)(3);
2398 #endif
2399 }
2400 
PREFIX86(_int)2401 static void PREFIX86(_int)(void)    /* Opcode 0xcd */
2402 {
2403 	unsigned int_num = FETCH;
2404 	ICOUNT -= cycles.int_imm;
2405 #ifdef V20
2406 	PREFIX(_interrupt)(int_num,0);
2407 #else
2408 	PREFIX(_interrupt)(int_num);
2409 #endif
2410 }
2411 
PREFIX86(_into)2412 static void PREFIX86(_into)(void)    /* Opcode 0xce */
2413 {
2414 	if (OF) {
2415 		ICOUNT -= cycles.into_t;
2416 #ifdef V20
2417 		PREFIX(_interrupt)(4,0);
2418 #else
2419 		PREFIX(_interrupt)(4);
2420 #endif
2421 	} else ICOUNT -= cycles.into_nt;
2422 }
2423 
PREFIX86(_iret)2424 static void PREFIX86(_iret)(void)    /* Opcode 0xcf */
2425 {
2426 	ICOUNT -= cycles.iret;
2427 #ifdef I286
2428 	{
2429 		int tmp, tmp2;
2430 		POP(tmp2);
2431 		POP(tmp);
2432 		i286_code_descriptor(tmp, tmp2);
2433 	}
2434 #else
2435 	POP(I.pc);
2436 	POP(I.sregs[CS]);
2437 	I.base[CS] = SegBase(CS);
2438 	I.pc = (I.pc + I.base[CS]) & AMASK;
2439 #endif
2440     PREFIX(_popf)();
2441 	CHANGE_PC(I.pc);
2442 
2443 	/* if the IF is set, and an interrupt is pending, signal an interrupt */
2444 	if (I.IF && I.irq_state)
2445 #ifdef V20
2446 		PREFIX(_interrupt)(-1, 0);
2447 #else
2448 		PREFIX(_interrupt)(-1);
2449 #endif
2450 }
2451 
PREFIX86(_rotshft_b)2452 static void PREFIX86(_rotshft_b)(void)    /* Opcode 0xd0 */
2453 {
2454 	PREFIX(_rotate_shift_Byte)(FETCHOP,1);
2455 }
2456 
2457 
PREFIX86(_rotshft_w)2458 static void PREFIX86(_rotshft_w)(void)    /* Opcode 0xd1 */
2459 {
2460 	PREFIX(_rotate_shift_Word)(FETCHOP,1);
2461 }
2462 
2463 
PREFIX86(_rotshft_bcl)2464 static void PREFIX86(_rotshft_bcl)(void)    /* Opcode 0xd2 */
2465 {
2466 	PREFIX(_rotate_shift_Byte)(FETCHOP,I.regs.b[CL]);
2467 }
2468 
PREFIX86(_rotshft_wcl)2469 static void PREFIX86(_rotshft_wcl)(void)    /* Opcode 0xd3 */
2470 {
2471 	PREFIX(_rotate_shift_Word)(FETCHOP,I.regs.b[CL]);
2472 }
2473 
2474 /* OB: Opcode works on NEC V-Series but not the Variants              */
2475 /*     one could specify any byte value as operand but the NECs */
2476 /*     always substitute 0x0a.              */
PREFIX86(_aam)2477 static void PREFIX86(_aam)(void)    /* Opcode 0xd4 */
2478 {
2479 	unsigned mult = FETCH;
2480 
2481 	ICOUNT -= cycles.aam;
2482 #ifndef V20
2483 	if (mult == 0)
2484 		PREFIX(_interrupt)(0);
2485 	else
2486 	{
2487 		I.regs.b[AH] = I.regs.b[AL] / mult;
2488 		I.regs.b[AL] %= mult;
2489 
2490 		SetSZPF_Word(I.regs.w[AX]);
2491 	}
2492 #else
2493 
2494 	if (mult == 0)
2495 		PREFIX(_interrupt)(0,0);
2496     else
2497     {
2498 		I.regs.b[AH] = I.regs.b[AL] / 10;
2499 		I.regs.b[AL] %= 10;
2500 		SetSZPF_Word(I.regs.w[AX]);
2501     }
2502 #endif
2503 }
2504 
PREFIX86(_aad)2505 static void PREFIX86(_aad)(void)    /* Opcode 0xd5 */
2506 {
2507 	unsigned mult = FETCH;
2508 
2509 	ICOUNT -= cycles.aad;
2510 
2511 #ifndef V20
2512 	I.regs.b[AL] = I.regs.b[AH] * mult + I.regs.b[AL];
2513 	I.regs.b[AH] = 0;
2514 
2515 	SetZF(I.regs.b[AL]);
2516 	SetPF(I.regs.b[AL]);
2517 	I.SignVal = 0;
2518 #else
2519 /* OB: Opcode works on NEC V-Series but not the Variants 	*/
2520 /*     one could specify any byte value as operand but the NECs */
2521 /*     always substitute 0x0a.					*/
2522 	I.regs.b[AL] = I.regs.b[AH] * 10 + I.regs.b[AL];
2523 	I.regs.b[AH] = 0;
2524 
2525 	SetZF(I.regs.b[AL]);
2526 	SetPF(I.regs.b[AL]);
2527 	I.SignVal = 0;
2528 	mult=0;
2529 #endif
2530 }
2531 
2532 
PREFIX86(_xlat)2533 static void PREFIX86(_xlat)(void)    /* Opcode 0xd7 */
2534 {
2535 	unsigned dest = I.regs.w[BX]+I.regs.b[AL];
2536 
2537 	ICOUNT -= cycles.xlat;
2538 	I.regs.b[AL] = GetMemB(DS, dest);
2539 }
2540 
PREFIX86(_escape)2541 static void PREFIX86(_escape)(void)    /* Opcodes 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde and 0xdf */
2542 {
2543 	unsigned ModRM = FETCH;
2544 	ICOUNT -= cycles.nop;
2545     GetRMByte(ModRM);
2546 }
2547 
PREFIX86(_loopne)2548 static void PREFIX86(_loopne)(void)    /* Opcode 0xe0 */
2549 {
2550 	int disp = (int)((INT8)FETCH);
2551 	unsigned tmp = I.regs.w[CX]-1;
2552 
2553 	I.regs.w[CX]=tmp;
2554 
2555     if (!ZF && tmp) {
2556 		ICOUNT -= cycles.loop_t;
2557 		I.pc += disp;
2558 /* ASG - can probably assume this is safe
2559 		CHANGE_PC(I.pc);*/
2560 	} else ICOUNT -= cycles.loop_nt;
2561 }
2562 
PREFIX86(_loope)2563 static void PREFIX86(_loope)(void)    /* Opcode 0xe1 */
2564 {
2565 	int disp = (int)((INT8)FETCH);
2566 	unsigned tmp = I.regs.w[CX]-1;
2567 
2568 	I.regs.w[CX]=tmp;
2569 
2570 	if (ZF && tmp) {
2571 		ICOUNT -= cycles.loope_t;
2572 		 I.pc += disp;
2573 /* ASG - can probably assume this is safe
2574 		 CHANGE_PC(I.pc);*/
2575 	 } else ICOUNT -= cycles.loope_nt;
2576 }
2577 
PREFIX86(_loop)2578 static void PREFIX86(_loop)(void)    /* Opcode 0xe2 */
2579 {
2580 	int disp = (int)((INT8)FETCH);
2581 	unsigned tmp = I.regs.w[CX]-1;
2582 
2583 	I.regs.w[CX]=tmp;
2584 
2585     if (tmp) {
2586 		ICOUNT -= cycles.loop_t;
2587 		I.pc += disp;
2588 /* ASG - can probably assume this is safe
2589 		CHANGE_PC(I.pc);*/
2590 	} else ICOUNT -= cycles.loop_nt;
2591 }
2592 
PREFIX86(_jcxz)2593 static void PREFIX86(_jcxz)(void)    /* Opcode 0xe3 */
2594 {
2595 	int disp = (int)((INT8)FETCH);
2596 
2597 	if (I.regs.w[CX] == 0) {
2598 		ICOUNT -= cycles.jcxz_t;
2599 		I.pc += disp;
2600 /* ASG - can probably assume this is safe
2601 		CHANGE_PC(I.pc);*/
2602 	} else
2603 		ICOUNT -= cycles.jcxz_nt;
2604 }
2605 
PREFIX86(_inal)2606 static void PREFIX86(_inal)(void)    /* Opcode 0xe4 */
2607 {
2608 	unsigned port = FETCH;
2609 
2610 	ICOUNT -= cycles.in_imm8;
2611 	I.regs.b[AL] = read_port(port);
2612 }
2613 
PREFIX86(_inax)2614 static void PREFIX86(_inax)(void)    /* Opcode 0xe5 */
2615 {
2616 	unsigned port = FETCH;
2617 
2618 	ICOUNT -= cycles.in_imm16;
2619 	I.regs.b[AL] = read_port(port);
2620 	I.regs.b[AH] = read_port(port+1);
2621 }
2622 
PREFIX86(_outal)2623 static void PREFIX86(_outal)(void)    /* Opcode 0xe6 */
2624 {
2625 	unsigned port = FETCH;
2626 
2627 	ICOUNT -= cycles.out_imm8;
2628 	write_port(port, I.regs.b[AL]);
2629 }
2630 
PREFIX86(_outax)2631 static void PREFIX86(_outax)(void)    /* Opcode 0xe7 */
2632 {
2633 	unsigned port = FETCH;
2634 
2635 	ICOUNT -= cycles.out_imm16;
2636 	write_port(port, I.regs.b[AL]);
2637 	write_port(port+1, I.regs.b[AH]);
2638 }
2639 
PREFIX86(_call_d16)2640 static void PREFIX86(_call_d16)(void)    /* Opcode 0xe8 */
2641 {
2642 	WORD ip, tmp;
2643 
2644 	FETCHWORD(tmp);
2645 	ip = I.pc - I.base[CS];
2646 	PUSH(ip);
2647 	ip += tmp;
2648 	I.pc = (ip + I.base[CS]) & AMASK;
2649 	ICOUNT -= cycles.call_near;
2650 	CHANGE_PC(I.pc);
2651 }
2652 
PREFIX86(_jmp_d16)2653 static void PREFIX86(_jmp_d16)(void)    /* Opcode 0xe9 */
2654 {
2655 	WORD ip, tmp;
2656 
2657 	FETCHWORD(tmp);
2658 	ip = I.pc - I.base[CS] + tmp;
2659 	I.pc = (ip + I.base[CS]) & AMASK;
2660 	ICOUNT -= cycles.jmp_near;
2661 	CHANGE_PC(I.pc);
2662 }
2663 
PREFIX86(_jmp_far)2664 static void PREFIX86(_jmp_far)(void)    /* Opcode 0xea */
2665 {
2666 	unsigned tmp,tmp1;
2667 
2668 	tmp = FETCH;
2669 	tmp += FETCH << 8;
2670 
2671 	tmp1 = FETCH;
2672 	tmp1 += FETCH << 8;
2673 
2674 #ifdef I286
2675 	i286_code_descriptor(tmp1,tmp);
2676 #else
2677 	I.sregs[CS] = (WORD)tmp1;
2678 	I.base[CS] = SegBase(CS);
2679 	I.pc = (I.base[CS] + tmp) & AMASK;
2680 #endif
2681 	ICOUNT -= cycles.jmp_far;
2682 	CHANGE_PC(I.pc);
2683 }
2684 
PREFIX86(_jmp_d8)2685 static void PREFIX86(_jmp_d8)(void)    /* Opcode 0xeb */
2686 {
2687 	int tmp = (int)((INT8)FETCH);
2688 	I.pc += tmp;
2689 /* ASG - can probably assume this is safe
2690 	CHANGE_PC(I.pc);*/
2691 	ICOUNT -= cycles.jmp_short;
2692 }
2693 
PREFIX86(_inaldx)2694 static void PREFIX86(_inaldx)(void)    /* Opcode 0xec */
2695 {
2696 	ICOUNT -= cycles.in_dx8;
2697 	I.regs.b[AL] = read_port(I.regs.w[DX]);
2698 }
2699 
PREFIX86(_inaxdx)2700 static void PREFIX86(_inaxdx)(void)    /* Opcode 0xed */
2701 {
2702 	unsigned port = I.regs.w[DX];
2703 
2704 	ICOUNT -= cycles.in_dx16;
2705 	I.regs.b[AL] = read_port(port);
2706 	I.regs.b[AH] = read_port(port+1);
2707 }
2708 
PREFIX86(_outdxal)2709 static void PREFIX86(_outdxal)(void)    /* Opcode 0xee */
2710 {
2711 	ICOUNT -= cycles.out_dx8;
2712 	write_port(I.regs.w[DX], I.regs.b[AL]);
2713 }
2714 
PREFIX86(_outdxax)2715 static void PREFIX86(_outdxax)(void)    /* Opcode 0xef */
2716 {
2717 	unsigned port = I.regs.w[DX];
2718 
2719 	ICOUNT -= cycles.out_dx16;
2720 	write_port(port, I.regs.b[AL]);
2721 	write_port(port+1, I.regs.b[AH]);
2722 }
2723 
2724 /* I think thats not a V20 instruction...*/
PREFIX86(_lock)2725 static void PREFIX86(_lock)(void)    /* Opcode 0xf0 */
2726 {
2727 	ICOUNT -= cycles.nop;
2728 	PREFIX(_instruction)[FETCHOP]();  /* un-interruptible */
2729 }
2730 #endif
2731 
PREFIX(_repne)2732 static void PREFIX(_repne)(void)    /* Opcode 0xf2 */
2733 {
2734 	 PREFIX(rep)(0);
2735 }
2736 
PREFIX(_repe)2737 static void PREFIX(_repe)(void)    /* Opcode 0xf3 */
2738 {
2739 	 PREFIX(rep)(1);
2740 }
2741 
2742 #ifndef I186
PREFIX86(_hlt)2743 static void PREFIX86(_hlt)(void)    /* Opcode 0xf4 */
2744 {
2745 	I.pc--;
2746 	ICOUNT = 0;
2747 }
2748 
PREFIX86(_cmc)2749 static void PREFIX86(_cmc)(void)    /* Opcode 0xf5 */
2750 {
2751 	ICOUNT -= cycles.flag_ops;
2752 	I.CarryVal = !CF;
2753 }
2754 
PREFIX86(_f6pre)2755 static void PREFIX86(_f6pre)(void)
2756 {
2757 	/* Opcode 0xf6 */
2758 	unsigned ModRM = FETCH;
2759     unsigned tmp = (unsigned)GetRMByte(ModRM);
2760     unsigned tmp2;
2761 
2762 
2763     switch (ModRM & 0x38)
2764     {
2765     case 0x00:  /* TEST Eb, data8 */
2766     case 0x08:  /* ??? */
2767 		ICOUNT -= (ModRM >= 0xc0) ? cycles.alu_ri8 : cycles.alu_mi8_ro;
2768 		tmp &= FETCH;
2769 
2770 		I.CarryVal = I.OverVal = I.AuxVal = 0;
2771 		SetSZPF_Byte(tmp);
2772 		break;
2773 
2774     case 0x10:  /* NOT Eb */
2775 		ICOUNT -= (ModRM >= 0xc0) ? cycles.negnot_r8 : cycles.negnot_m8;
2776 		PutbackRMByte(ModRM,~tmp);
2777 		break;
2778 
2779 	 case 0x18:  /* NEG Eb */
2780 		ICOUNT -= (ModRM >= 0xc0) ? cycles.negnot_r8 : cycles.negnot_m8;
2781         tmp2=0;
2782         SUBB(tmp2,tmp);
2783         PutbackRMByte(ModRM,tmp2);
2784 		break;
2785     case 0x20:  /* MUL AL, Eb */
2786 		ICOUNT -= (ModRM >= 0xc0) ? cycles.mul_r8 : cycles.mul_m8;
2787 		{
2788 			UINT16 result;
2789 			tmp2 = I.regs.b[AL];
2790 
2791 			SetSF((INT8)tmp2);
2792 			SetPF(tmp2);
2793 
2794 			result = (UINT16)tmp2*tmp;
2795 			I.regs.w[AX]=(WORD)result;
2796 
2797 			SetZF(I.regs.w[AX]);
2798 			I.CarryVal = I.OverVal = (I.regs.b[AH] != 0);
2799 		}
2800 		break;
2801 	 case 0x28:  /* IMUL AL, Eb */
2802 		ICOUNT -= (ModRM >= 0xc0) ? cycles.imul_r8 : cycles.imul_m8;
2803 		{
2804 			INT16 result;
2805 
2806 			tmp2 = (unsigned)I.regs.b[AL];
2807 
2808 			SetSF((INT8)tmp2);
2809 			SetPF(tmp2);
2810 
2811 			result = (INT16)((INT8)tmp2)*(INT16)((INT8)tmp);
2812 			I.regs.w[AX]=(WORD)result;
2813 
2814 			SetZF(I.regs.w[AX]);
2815 
2816 			I.CarryVal = I.OverVal = (result >> 7 != 0) && (result >> 7 != -1);
2817 		}
2818 		break;
2819     case 0x30:  /* DIV AL, Ew */
2820 		ICOUNT -= (ModRM >= 0xc0) ? cycles.div_r8 : cycles.div_m8;
2821 		{
2822 			UINT16 result;
2823 
2824 			result = I.regs.w[AX];
2825 
2826 			if (tmp)
2827 			{
2828 				if ((result / tmp) > 0xff)
2829 				{
2830 #ifdef V20
2831 					PREFIX(_interrupt)(0,0);
2832 #else
2833 					PREFIX(_interrupt)(0);
2834 #endif
2835 					break;
2836 				}
2837 				else
2838 				{
2839 					I.regs.b[AH] = result % tmp;
2840 					I.regs.b[AL] = result / tmp;
2841 				}
2842 			}
2843 			else
2844 			{
2845 #ifdef V20
2846 				PREFIX(_interrupt)(0,0);
2847 #else
2848 				PREFIX(_interrupt)(0);
2849 #endif
2850 				break;
2851 			}
2852 		}
2853 		break;
2854     case 0x38:  /* IDIV AL, Ew */
2855 		ICOUNT -= (ModRM >= 0xc0) ? cycles.idiv_r8 : cycles.idiv_m8;
2856 		{
2857 
2858 			INT16 result;
2859 
2860 			result = I.regs.w[AX];
2861 
2862 			if (tmp)
2863 			{
2864 				tmp2 = result % (INT16)((INT8)tmp);
2865 
2866 				if ((result /= (INT16)((INT8)tmp)) > 0xff)
2867 				{
2868 #ifdef V20
2869 					PREFIX(_interrupt)(0,0);
2870 #else
2871 					PREFIX(_interrupt)(0);
2872 #endif
2873 					break;
2874 				}
2875 				else
2876 				{
2877 					I.regs.b[AL] = result;
2878 					I.regs.b[AH] = tmp2;
2879 				}
2880 			}
2881 			else
2882 			{
2883 #ifdef V20
2884 				PREFIX(_interrupt)(0,0);
2885 #else
2886 				PREFIX(_interrupt)(0);
2887 #endif
2888 				break;
2889 			}
2890 		}
2891 		break;
2892     }
2893 }
2894 
2895 
PREFIX86(_f7pre)2896 static void PREFIX86(_f7pre)(void)
2897 {
2898 	/* Opcode 0xf7 */
2899 	unsigned ModRM = FETCH;
2900 	 unsigned tmp = GetRMWord(ModRM);
2901     unsigned tmp2;
2902 
2903 
2904     switch (ModRM & 0x38)
2905     {
2906     case 0x00:  /* TEST Ew, data16 */
2907     case 0x08:  /* ??? */
2908 		ICOUNT -= (ModRM >= 0xc0) ? cycles.alu_ri16 : cycles.alu_mi16_ro;
2909 		tmp2 = FETCH;
2910 		tmp2 += FETCH << 8;
2911 
2912 		tmp &= tmp2;
2913 
2914 		I.CarryVal = I.OverVal = I.AuxVal = 0;
2915 		SetSZPF_Word(tmp);
2916 		break;
2917 
2918     case 0x10:  /* NOT Ew */
2919 		ICOUNT -= (ModRM >= 0xc0) ? cycles.negnot_r16 : cycles.negnot_m16;
2920 		tmp = ~tmp;
2921 		PutbackRMWord(ModRM,tmp);
2922 		break;
2923 
2924     case 0x18:  /* NEG Ew */
2925 		ICOUNT -= (ModRM >= 0xc0) ? cycles.negnot_r16 : cycles.negnot_m16;
2926         tmp2 = 0;
2927         SUBW(tmp2,tmp);
2928         PutbackRMWord(ModRM,tmp2);
2929 		break;
2930     case 0x20:  /* MUL AX, Ew */
2931 		ICOUNT -= (ModRM >= 0xc0) ? cycles.mul_r16 : cycles.mul_m16;
2932 		{
2933 			UINT32 result;
2934 			tmp2 = I.regs.w[AX];
2935 
2936 			SetSF((INT16)tmp2);
2937 			SetPF(tmp2);
2938 
2939 			result = (UINT32)tmp2*tmp;
2940 			I.regs.w[AX]=(WORD)result;
2941             result >>= 16;
2942 			I.regs.w[DX]=result;
2943 
2944 			SetZF(I.regs.w[AX] | I.regs.w[DX]);
2945 			I.CarryVal = I.OverVal = (I.regs.w[DX] != 0);
2946 		}
2947 		break;
2948 
2949     case 0x28:  /* IMUL AX, Ew */
2950 		ICOUNT -= (ModRM >= 0xc0) ? cycles.imul_r16 : cycles.imul_m16;
2951 		{
2952 			INT32 result;
2953 
2954 			tmp2 = I.regs.w[AX];
2955 
2956 			SetSF((INT16)tmp2);
2957 			SetPF(tmp2);
2958 
2959 			result = (INT32)((INT16)tmp2)*(INT32)((INT16)tmp);
2960 			I.CarryVal = I.OverVal = (result >> 15 != 0) && (result >> 15 != -1);
2961 
2962 			I.regs.w[AX]=(WORD)result;
2963 			result = (WORD)(result >> 16);
2964 			I.regs.w[DX]=result;
2965 
2966 			SetZF(I.regs.w[AX] | I.regs.w[DX]);
2967 		}
2968 		break;
2969 	 case 0x30:  /* DIV AX, Ew */
2970 		ICOUNT -= (ModRM >= 0xc0) ? cycles.div_r16 : cycles.div_m16;
2971 		{
2972 			UINT32 result;
2973 
2974 			result = (I.regs.w[DX] << 16) + I.regs.w[AX];
2975 
2976 			if (tmp)
2977 			{
2978 				tmp2 = result % tmp;
2979 				if ((result / tmp) > 0xffff)
2980 				{
2981 #ifdef V20
2982 					PREFIX(_interrupt)(0,0);
2983 #else
2984 					PREFIX(_interrupt)(0);
2985 #endif
2986 					break;
2987 				}
2988 				else
2989 				{
2990 					I.regs.w[DX]=tmp2;
2991 					result /= tmp;
2992 					I.regs.w[AX]=result;
2993 				}
2994 			}
2995 			else
2996 			{
2997 #ifdef V20
2998 				PREFIX(_interrupt)(0,0);
2999 #else
3000 				PREFIX(_interrupt)(0);
3001 #endif
3002 				break;
3003 			}
3004 		}
3005 		break;
3006     case 0x38:  /* IDIV AX, Ew */
3007 		ICOUNT -= (ModRM >= 0xc0) ? cycles.idiv_r16 : cycles.idiv_m16;
3008 		{
3009 			INT32 result;
3010 
3011 			result = (I.regs.w[DX] << 16) + I.regs.w[AX];
3012 
3013 			if (tmp)
3014 			{
3015 				tmp2 = result % (INT32)((INT16)tmp);
3016 				if ((result /= (INT32)((INT16)tmp)) > 0xffff)
3017 				{
3018 #ifdef V20
3019 					PREFIX(_interrupt)(0,0);
3020 #else
3021 					PREFIX(_interrupt)(0);
3022 #endif
3023 					break;
3024 				}
3025 				else
3026 				{
3027 					I.regs.w[AX]=result;
3028 					I.regs.w[DX]=tmp2;
3029 				}
3030 			}
3031 			else
3032 			{
3033 #ifdef V20
3034 				PREFIX(_interrupt)(0,0);
3035 #else
3036 				PREFIX(_interrupt)(0);
3037 #endif
3038 				break;
3039 			}
3040 		}
3041 		break;
3042     }
3043 }
3044 
3045 
PREFIX86(_clc)3046 static void PREFIX86(_clc)(void)    /* Opcode 0xf8 */
3047 {
3048 	ICOUNT -= cycles.flag_ops;
3049 	I.CarryVal = 0;
3050 }
3051 
PREFIX86(_stc)3052 static void PREFIX86(_stc)(void)    /* Opcode 0xf9 */
3053 {
3054 	ICOUNT -= cycles.flag_ops;
3055 	I.CarryVal = 1;
3056 }
3057 
PREFIX86(_cli)3058 static void PREFIX86(_cli)(void)    /* Opcode 0xfa */
3059 {
3060 	ICOUNT -= cycles.flag_ops;
3061 	SetIF(0);
3062 }
3063 
PREFIX86(_sti)3064 static void PREFIX86(_sti)(void)    /* Opcode 0xfb */
3065 {
3066 	ICOUNT -= cycles.flag_ops;
3067 	SetIF(1);
3068 	PREFIX(_instruction)[FETCHOP](); /* no interrupt before next instruction */
3069 
3070 	/* if an interrupt is pending, signal an interrupt */
3071 	if (I.irq_state)
3072 #ifdef V20
3073 		PREFIX(_interrupt)(-1, 0);
3074 #else
3075 		PREFIX(_interrupt)(-1);
3076 #endif
3077 }
3078 
PREFIX86(_cld)3079 static void PREFIX86(_cld)(void)    /* Opcode 0xfc */
3080 {
3081 	ICOUNT -= cycles.flag_ops;
3082 	SetDF(0);
3083 }
3084 
PREFIX86(_std)3085 static void PREFIX86(_std)(void)    /* Opcode 0xfd */
3086 {
3087 	ICOUNT -= cycles.flag_ops;
3088 	SetDF(1);
3089 }
3090 
PREFIX86(_fepre)3091 static void PREFIX86(_fepre)(void)    /* Opcode 0xfe */
3092 {
3093 	unsigned ModRM = FETCH;
3094 	unsigned tmp = GetRMByte(ModRM);
3095     unsigned tmp1;
3096 
3097 	ICOUNT -= (ModRM >= 0xc0) ? cycles.incdec_r8 : cycles.incdec_m8;
3098     if ((ModRM & 0x38) == 0)  /* INC eb */
3099 	 {
3100 		tmp1 = tmp+1;
3101 		SetOFB_Add(tmp1,tmp,1);
3102     }
3103 	 else  /* DEC eb */
3104     {
3105 		tmp1 = tmp-1;
3106 		SetOFB_Sub(tmp1,1,tmp);
3107     }
3108 
3109     SetAF(tmp1,tmp,1);
3110     SetSZPF_Byte(tmp1);
3111 
3112     PutbackRMByte(ModRM,(BYTE)tmp1);
3113 }
3114 
3115 
PREFIX86(_ffpre)3116 static void PREFIX86(_ffpre)(void)    /* Opcode 0xff */
3117 {
3118 	unsigned ModRM = FETCHOP;
3119     unsigned tmp;
3120     unsigned tmp1;
3121     WORD ip;
3122 
3123     switch(ModRM & 0x38)
3124     {
3125     case 0x00:  /* INC ew */
3126 		ICOUNT -= (ModRM >= 0xc0) ? cycles.incdec_r16 : cycles.incdec_m16;
3127 		tmp = GetRMWord(ModRM);
3128 		tmp1 = tmp+1;
3129 
3130 		SetOFW_Add(tmp1,tmp,1);
3131 		SetAF(tmp1,tmp,1);
3132 		SetSZPF_Word(tmp1);
3133 
3134 		PutbackRMWord(ModRM,(WORD)tmp1);
3135 		break;
3136 
3137     case 0x08:  /* DEC ew */
3138 		ICOUNT -= (ModRM >= 0xc0) ? cycles.incdec_r16 : cycles.incdec_m16;
3139 		tmp = GetRMWord(ModRM);
3140 		tmp1 = tmp-1;
3141 
3142 		SetOFW_Sub(tmp1,1,tmp);
3143 		SetAF(tmp1,tmp,1);
3144 		SetSZPF_Word(tmp1);
3145 
3146 		PutbackRMWord(ModRM,(WORD)tmp1);
3147 		break;
3148 
3149     case 0x10:  /* CALL ew */
3150 		ICOUNT -= (ModRM >= 0xc0) ? cycles.call_r16 : cycles.call_m16;
3151 		tmp = GetRMWord(ModRM);
3152 		ip = I.pc - I.base[CS];
3153 		PUSH(ip);
3154 		I.pc = (I.base[CS] + (WORD)tmp) & AMASK;
3155 		CHANGE_PC(I.pc);
3156 		break;
3157 
3158 	case 0x18:  /* CALL FAR ea */
3159 		ICOUNT -= cycles.call_m32;
3160 		tmp = I.sregs[CS];	/* HJB 12/13/98 need to skip displacements of EA */
3161 		tmp1 = GetRMWord(ModRM);
3162 		ip = I.pc - I.base[CS];
3163 		PUSH(tmp);
3164 		PUSH(ip);
3165 #ifdef I286
3166 		i286_code_descriptor(GetnextRMWord, tmp1);
3167 #else
3168 		I.sregs[CS] = GetnextRMWord;
3169 		I.base[CS] = SegBase(CS);
3170 		I.pc = (I.base[CS] + tmp1) & AMASK;
3171 #endif
3172 		CHANGE_PC(I.pc);
3173 		break;
3174 
3175     case 0x20:  /* JMP ea */
3176 		ICOUNT -= (ModRM >= 0xc0) ? cycles.jmp_r16 : cycles.jmp_m16;
3177 		ip = GetRMWord(ModRM);
3178 		I.pc = (I.base[CS] + ip) & AMASK;
3179 		CHANGE_PC(I.pc);
3180 		break;
3181 
3182     case 0x28:  /* JMP FAR ea */
3183 		ICOUNT -= cycles.jmp_m32;
3184 
3185 #ifdef I286
3186 		tmp = GetRMWord(ModRM);
3187 		i286_code_descriptor(GetnextRMWord, tmp);
3188 #else
3189 		I.pc = GetRMWord(ModRM);
3190 		I.sregs[CS] = GetnextRMWord;
3191 		I.base[CS] = SegBase(CS);
3192 		I.pc = (I.pc + I.base[CS]) & AMASK;
3193 #endif
3194 		CHANGE_PC(I.pc);
3195 		break;
3196 
3197     case 0x30:  /* PUSH ea */
3198 		ICOUNT -= (ModRM >= 0xc0) ? cycles.push_r16 : cycles.push_m16;
3199 		tmp = GetRMWord(ModRM);
3200 		PUSH(tmp);
3201 		break;
3202 	 }
3203 }
3204 
3205 
PREFIX86(_invalid)3206 static void PREFIX86(_invalid)(void)
3207 {
3208 #ifdef I286
3209 	i286_trap2(ILLEGAL_INSTRUCTION);
3210 #else
3211 	 /* makes the cpu loops forever until user resets it */
3212 	/*{ extern int debug_key_pressed; debug_key_pressed = 1; } */
3213 	/*logerror("illegal instruction %.2x at %.5x\n",PEEKBYTE(I.pc), I.pc);*/
3214 	I.pc--;
3215 	ICOUNT -= 10;
3216 #endif
3217 }
3218 #endif
3219