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