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