1 /****************************************************************************
\r
2 * real mode i286 emulator v1.4 by Fabrice Frances *
\r
3 * (initial work based on David Hedley's pcemu) *
\r
4 ****************************************************************************/
\r
7 * file will be included in all cpu variants
\r
8 * put non i86 instructions in own files (i286, i386, nec)
\r
9 * function renaming will be added when necessary
\r
10 * timing value should move to separate array
\r
16 Moved several instruction stubs so that they are compiled separately for
\r
17 the 8086 and 80186. The instructions affected are :
\r
19 _pop_ss, _es, _cs, _ss, _ds, _mov_sregw and _sti
\r
21 This is because they call the next instruction directly as it cannot be
\r
22 interrupted. If they are not compiled separately when executing on an
\r
23 80186, the wrong set of instructions are used (the 8086 set). This has
\r
24 the serious effect of ignoring the next instruction, as invalid, *IF*
\r
25 it is an 80186 specific instruction.
\r
31 #define ICOUNT cpustate->icount
\r
34 #if !defined(I80186)
\r
35 static void PREFIX86(_interrupt)(i8086_state *cpustate, unsigned int_num)
\r
37 unsigned dest_seg, dest_off;
\r
38 WORD ip = cpustate->pc - cpustate->base[CS];
\r
41 int_num = cpustate->pic->intr_ack();
\r
45 i80286_interrupt_descriptor(cpustate, int_num, 0, 0);
\r
48 dest_off = ReadWord(int_num*4);
\r
49 dest_seg = ReadWord(int_num*4+2);
\r
51 PREFIX(_pushf(cpustate));
\r
52 cpustate->TF = cpustate->IF = 0;
\r
53 PUSH(cpustate->sregs[CS]);
\r
55 cpustate->sregs[CS] = (WORD)dest_seg;
\r
56 cpustate->base[CS] = SegBase(CS);
\r
57 cpustate->pc = (cpustate->base[CS] + dest_off) & AMASK;
\r
58 CHANGE_PC(cpustate->pc);
\r
62 cpustate->extra_cycles += timing.exception;
\r
65 static void PREFIX86(_trap)(i8086_state *cpustate)
\r
67 PREFIX(_instruction)[FETCHOP](cpustate);
\r
68 PREFIX(_interrupt)(cpustate, 1);
\r
73 static void PREFIX86(_rotate_shift_Byte)(i8086_state *cpustate, unsigned ModRM, unsigned count, unsigned src)
\r
75 // unsigned src = (unsigned)GetRMByte(ModRM);
\r
80 ICOUNT -= (ModRM >= 0xc0) ? timing.rot_reg_base : timing.rot_m8_base;
\r
84 ICOUNT -= (ModRM >= 0xc0) ? timing.rot_reg_1 : timing.rot_m8_1;
\r
86 switch (ModRM & 0x38)
\r
88 case 0x00: /* ROL eb,1 */
\r
89 cpustate->CarryVal = src & 0x80;
\r
91 PutbackRMByte(ModRM,dst);
\r
92 cpustate->OverVal = (src^dst)&0x80;
\r
94 case 0x08: /* ROR eb,1 */
\r
95 cpustate->CarryVal = src & 0x01;
\r
96 dst = ((CF<<8)+src) >> 1;
\r
97 PutbackRMByte(ModRM,dst);
\r
98 cpustate->OverVal = (src^dst)&0x80;
\r
100 case 0x10: /* RCL eb,1 */
\r
102 PutbackRMByte(ModRM,dst);
\r
104 cpustate->OverVal = (src^dst)&0x80;
\r
106 case 0x18: /* RCR eb,1 */
\r
107 dst = ((CF<<8)+src) >> 1;
\r
108 PutbackRMByte(ModRM,dst);
\r
109 cpustate->CarryVal = src & 0x01;
\r
110 cpustate->OverVal = (src^dst)&0x80;
\r
112 case 0x20: /* SHL eb,1 */
\r
115 PutbackRMByte(ModRM,dst);
\r
117 cpustate->OverVal = (src^dst)&0x80;
\r
118 cpustate->AuxVal = 1;
\r
121 case 0x28: /* SHR eb,1 */
\r
123 PutbackRMByte(ModRM,dst);
\r
124 cpustate->CarryVal = src & 0x01;
\r
125 cpustate->OverVal = src & 0x80;
\r
126 cpustate->AuxVal = 1;
\r
129 case 0x38: /* SAR eb,1 */
\r
130 dst = ((INT8)src) >> 1;
\r
131 PutbackRMByte(ModRM,dst);
\r
132 cpustate->CarryVal = src & 0x01;
\r
133 cpustate->OverVal = 0;
\r
134 cpustate->AuxVal = 1;
\r
142 ICOUNT -= (ModRM >= 0xc0) ? timing.rot_reg_base + (timing.rot_reg_bit * count) : timing.rot_m8_base + (timing.rot_m8_bit * count);
\r
144 switch (ModRM & 0x38)
\r
146 case 0x00: /* ROL eb,count */
\r
147 for (; count > 0; count--)
\r
149 cpustate->CarryVal = dst & 0x80;
\r
150 dst = (dst << 1) + CF;
\r
152 PutbackRMByte(ModRM,(BYTE)dst);
\r
154 case 0x08: /* ROR eb,count */
\r
155 for (; count > 0; count--)
\r
157 cpustate->CarryVal = dst & 0x01;
\r
158 dst = (dst >> 1) + (CF << 7);
\r
160 PutbackRMByte(ModRM,(BYTE)dst);
\r
162 case 0x10: /* RCL eb,count */
\r
163 for (; count > 0; count--)
\r
165 dst = (dst << 1) + tmpcf;
\r
166 tmpcf = (int)((dst & 0x100) != 0);
\r
168 PutbackRMByte(ModRM,(BYTE)dst);
\r
169 cpustate->CarryVal = tmpcf;
\r
171 case 0x18: /* RCR eb,count */
\r
172 for (; count > 0; count--)
\r
174 dst = (tmpcf<<8)+dst;
\r
175 tmpcf = dst & 0x01;
\r
178 PutbackRMByte(ModRM,(BYTE)dst);
\r
179 cpustate->CarryVal = tmpcf;
\r
182 case 0x30: /* SHL eb,count */
\r
183 for(int i=0;i<count;i++) dst<<= 1;
\r
185 cpustate->AuxVal = 1;
\r
187 PutbackRMByte(ModRM,(BYTE)dst);
\r
189 case 0x28: /* SHR eb,count */
\r
190 for(int i=0;i<count-1;i++) dst>>= 1;
\r
191 cpustate->CarryVal = dst & 0x1;
\r
194 cpustate->AuxVal = 1;
\r
195 PutbackRMByte(ModRM,(BYTE)dst);
\r
197 case 0x38: /* SAR eb,count */
\r
198 for(int i=0;i<count-1;i++) dst = ((INT8)dst) >> 1;
\r
199 cpustate->CarryVal = dst & 0x1;
\r
200 dst = ((INT8)((BYTE)dst)) >> 1;
\r
202 cpustate->AuxVal = 1;
\r
203 PutbackRMByte(ModRM,(BYTE)dst);
\r
209 static void PREFIX86(_rotate_shift_Word)(i8086_state *cpustate, unsigned ModRM, unsigned count, unsigned src)
\r
211 // unsigned src = GetRMWord(ModRM);
\r
216 ICOUNT -= (ModRM >= 0xc0) ? timing.rot_reg_base : timing.rot_m16_base;
\r
220 ICOUNT -= (ModRM >= 0xc0) ? timing.rot_reg_1 : timing.rot_m16_1;
\r
222 switch (ModRM & 0x38)
\r
225 case 0x00: /* ROL ew,1 */
\r
226 tmp2 = (tmp << 1) + CF;
\r
228 cpustate->OverVal = !(!(tmp & 0x4000)) != CF;
\r
229 PutbackRMWord(ModRM,tmp2);
\r
231 case 0x08: /* ROR ew,1 */
\r
232 cpustate->CarryVal = tmp & 0x01;
\r
233 tmp2 = (tmp >> 1) + ((unsigned)CF << 15);
\r
234 cpustate->OverVal = !(!(tmp & 0x8000)) != CF;
\r
235 PutbackRMWord(ModRM,tmp2);
\r
237 case 0x10: /* RCL ew,1 */
\r
238 tmp2 = (tmp << 1) + CF;
\r
240 cpustate->OverVal = (tmp ^ (tmp << 1)) & 0x8000;
\r
241 PutbackRMWord(ModRM,tmp2);
\r
243 case 0x18: /* RCR ew,1 */
\r
244 tmp2 = (tmp >> 1) + ((unsigned)CF << 15);
\r
245 cpustate->OverVal = !(!(tmp & 0x8000)) != CF;
\r
246 cpustate->CarryVal = tmp & 0x01;
\r
247 PutbackRMWord(ModRM,tmp2);
\r
249 case 0x20: /* SHL ew,1 */
\r
254 SetOFW_Add(tmp,tmp2,tmp2);
\r
255 cpustate->AuxVal = 1;
\r
258 PutbackRMWord(ModRM,tmp);
\r
260 case 0x28: /* SHR ew,1 */
\r
261 cpustate->CarryVal = tmp & 0x01;
\r
262 cpustate->OverVal = tmp & 0x8000;
\r
266 SetSZPF_Word(tmp2);
\r
267 cpustate->AuxVal = 1;
\r
268 PutbackRMWord(ModRM,tmp2);
\r
270 case 0x38: /* SAR ew,1 */
\r
271 cpustate->CarryVal = tmp & 0x01;
\r
272 cpustate->OverVal = 0;
\r
274 tmp2 = (tmp >> 1) | (tmp & 0x8000);
\r
276 SetSZPF_Word(tmp2);
\r
277 cpustate->AuxVal = 1;
\r
278 PutbackRMWord(ModRM,tmp2);
\r
281 case 0x00: /* ROL ew,1 */
\r
282 cpustate->CarryVal = src & 0x8000;
\r
284 PutbackRMWord(ModRM,dst);
\r
285 cpustate->OverVal = (src^dst)&0x8000;
\r
287 case 0x08: /* ROR ew,1 */
\r
288 cpustate->CarryVal = src & 0x01;
\r
289 dst = ((CF<<16)+src) >> 1;
\r
290 PutbackRMWord(ModRM,dst);
\r
291 cpustate->OverVal = (src^dst)&0x8000;
\r
293 case 0x10: /* RCL ew,1 */
\r
295 PutbackRMWord(ModRM,dst);
\r
297 cpustate->OverVal = (src^dst)&0x8000;
\r
299 case 0x18: /* RCR ew,1 */
\r
300 dst = ((CF<<16)+src) >> 1;
\r
301 PutbackRMWord(ModRM,dst);
\r
302 cpustate->CarryVal = src & 0x01;
\r
303 cpustate->OverVal = (src^dst)&0x8000;
\r
305 case 0x20: /* SHL ew,1 */
\r
308 PutbackRMWord(ModRM,dst);
\r
310 cpustate->OverVal = (src^dst)&0x8000;
\r
311 cpustate->AuxVal = 1;
\r
314 case 0x28: /* SHR ew,1 */
\r
316 PutbackRMWord(ModRM,dst);
\r
317 cpustate->CarryVal = src & 0x01;
\r
318 cpustate->OverVal = src & 0x8000;
\r
319 cpustate->AuxVal = 1;
\r
322 case 0x38: /* SAR ew,1 */
\r
323 dst = ((INT16)src) >> 1;
\r
324 PutbackRMWord(ModRM,dst);
\r
325 cpustate->CarryVal = src & 0x01;
\r
326 cpustate->OverVal = 0;
\r
327 cpustate->AuxVal = 1;
\r
336 ICOUNT -= (ModRM >= 0xc0) ? timing.rot_reg_base + (timing.rot_reg_bit * count) : timing.rot_m8_base + (timing.rot_m16_bit * count);
\r
338 switch (ModRM & 0x38)
\r
340 case 0x00: /* ROL ew,count */
\r
341 for (; count > 0; count--)
\r
343 cpustate->CarryVal = dst & 0x8000;
\r
344 dst = (dst << 1) + CF;
\r
346 PutbackRMWord(ModRM,dst);
\r
348 case 0x08: /* ROR ew,count */
\r
349 for (; count > 0; count--)
\r
351 cpustate->CarryVal = dst & 0x01;
\r
352 dst = (dst >> 1) + (CF << 15);
\r
354 PutbackRMWord(ModRM,dst);
\r
356 case 0x10: /* RCL ew,count */
\r
357 for (; count > 0; count--)
\r
359 dst = (dst << 1) + tmpcf;
\r
360 tmpcf = (int)((dst & 0x10000) != 0);
\r
362 PutbackRMWord(ModRM,dst);
\r
363 cpustate->CarryVal = tmpcf;
\r
365 case 0x18: /* RCR ew,count */
\r
366 for (; count > 0; count--)
\r
368 dst = dst + (tmpcf << 16);
\r
369 tmpcf = dst & 0x01;
\r
372 PutbackRMWord(ModRM,dst);
\r
373 cpustate->CarryVal = tmpcf;
\r
376 case 0x30: /* SHL ew,count */
\r
377 for(int i=0;i<count;i++) dst<<= 1;
\r
379 cpustate->AuxVal = 1;
\r
381 PutbackRMWord(ModRM,dst);
\r
383 case 0x28: /* SHR ew,count */
\r
384 for(int i=0;i<count-1;i++) dst>>= 1;
\r
385 cpustate->CarryVal = dst & 0x1;
\r
388 cpustate->AuxVal = 1;
\r
389 PutbackRMWord(ModRM,dst);
\r
391 case 0x38: /* SAR ew,count */
\r
392 for(int i=0;i<count-1;i++) dst = ((INT16)dst) >> 1;
\r
393 cpustate->CarryVal = dst & 0x01;
\r
394 dst = ((INT16)((WORD)dst)) >> 1;
\r
396 cpustate->AuxVal = 1;
\r
397 PutbackRMWord(ModRM,dst);
\r
404 static void PREFIX(rep)(i8086_state *cpustate,int flagval)
\r
406 /* Handles rep- and repnz- prefixes. flagval is the value of ZF for the
\r
407 loop to continue for CMPS and SCAS instructions. */
\r
409 unsigned next = FETCHOP;
\r
413 case 0x26: /* ES: */
\r
414 cpustate->seg_prefix = TRUE;
\r
415 cpustate->prefix_seg = ES;
\r
416 if (!cpustate->rep_in_progress)
\r
417 ICOUNT -= timing.override;
\r
418 PREFIX(rep)(cpustate, flagval);
\r
420 case 0x2e: /* CS: */
\r
421 cpustate->seg_prefix = TRUE;
\r
422 cpustate->prefix_seg = CS;
\r
423 if (!cpustate->rep_in_progress)
\r
424 ICOUNT -= timing.override;
\r
425 PREFIX(rep)(cpustate, flagval);
\r
427 case 0x36: /* SS: */
\r
428 cpustate->seg_prefix = TRUE;
\r
429 cpustate->prefix_seg = SS;
\r
430 if (!cpustate->rep_in_progress)
\r
431 ICOUNT -= timing.override;
\r
432 PREFIX(rep)(cpustate, flagval);
\r
434 case 0x3e: /* DS: */
\r
435 cpustate->seg_prefix = TRUE;
\r
436 cpustate->prefix_seg = DS;
\r
437 if (!cpustate->rep_in_progress)
\r
438 ICOUNT -= timing.override;
\r
439 PREFIX(rep)(cpustate, flagval);
\r
442 case 0x6c: /* REP INSB */
\r
444 if (PM && (CPL>IOPL)) throw TRAP(GENERAL_PROTECTION_FAULT, 0);
\r
446 if (!cpustate->rep_in_progress)
\r
447 ICOUNT -= timing.rep_ins8_base;
\r
448 cpustate->rep_in_progress = FALSE;
\r
449 while(cpustate->regs.w[CX])
\r
451 // if (ICOUNT <= 0) { cpustate->pc = cpustate->prevpc; cpustate->rep_in_progress = TRUE; break; }
\r
452 PutMemB(ES,cpustate->regs.w[DI],read_port_byte(cpustate->regs.w[DX]));
\r
453 cpustate->regs.w[CX]--;
\r
454 cpustate->regs.w[DI] += cpustate->DirVal;
\r
455 ICOUNT -= timing.rep_ins8_count;
\r
458 case 0x6d: /* REP INSW */
\r
460 if (PM && (CPL>IOPL)) throw TRAP(GENERAL_PROTECTION_FAULT, 0);
\r
462 if (!cpustate->rep_in_progress)
\r
463 ICOUNT -= timing.rep_ins16_base;
\r
464 cpustate->rep_in_progress = FALSE;
\r
465 while(cpustate->regs.w[CX])
\r
467 // if (ICOUNT <= 0) { cpustate->pc = cpustate->prevpc; cpustate->rep_in_progress = TRUE; break; }
\r
468 PutMemW(ES,cpustate->regs.w[DI],read_port_word(cpustate->regs.w[DX]));
\r
469 cpustate->regs.w[CX]--;
\r
470 cpustate->regs.w[DI] += 2 * cpustate->DirVal;
\r
471 ICOUNT -= timing.rep_ins16_count;
\r
474 case 0x6e: /* REP OUTSB */
\r
476 if (PM && (CPL>IOPL)) throw TRAP(GENERAL_PROTECTION_FAULT, 0);
\r
478 if (!cpustate->rep_in_progress)
\r
479 ICOUNT -= timing.rep_outs8_base;
\r
480 cpustate->rep_in_progress = FALSE;
\r
481 while(cpustate->regs.w[CX])
\r
483 // if (ICOUNT <= 0) { cpustate->pc = cpustate->prevpc; cpustate->rep_in_progress = TRUE; break; }
\r
484 write_port_byte(cpustate->regs.w[DX],GetMemB(DS,cpustate->regs.w[SI]));
\r
485 cpustate->regs.w[CX]--;
\r
486 cpustate->regs.w[SI] += cpustate->DirVal; /* GOL 11/27/01 */
\r
487 ICOUNT -= timing.rep_outs8_count;
\r
490 case 0x6f: /* REP OUTSW */
\r
492 if (PM && (CPL>IOPL)) throw TRAP(GENERAL_PROTECTION_FAULT, 0);
\r
494 if (!cpustate->rep_in_progress)
\r
495 ICOUNT -= timing.rep_outs16_base;
\r
496 cpustate->rep_in_progress = FALSE;
\r
497 while(cpustate->regs.w[CX])
\r
499 // if (ICOUNT <= 0) { cpustate->pc = cpustate->prevpc; cpustate->rep_in_progress = TRUE; break; }
\r
500 write_port_word(cpustate->regs.w[DX],GetMemW(DS,cpustate->regs.w[SI]));
\r
501 cpustate->regs.w[CX]--;
\r
502 cpustate->regs.w[SI] += 2 * cpustate->DirVal; /* GOL 11/27/01 */
\r
503 ICOUNT -= timing.rep_outs16_count;
\r
507 case 0xa4: /* REP MOVSB */
\r
508 if (!cpustate->rep_in_progress)
\r
509 ICOUNT -= timing.rep_movs8_base;
\r
510 cpustate->rep_in_progress = FALSE;
\r
511 while(cpustate->regs.w[CX])
\r
515 // if (ICOUNT <= 0) { cpustate->pc = cpustate->prevpc; cpustate->rep_in_progress = TRUE; break; }
\r
516 tmp = GetMemB(DS,cpustate->regs.w[SI]);
\r
517 PutMemB(ES,cpustate->regs.w[DI], tmp);
\r
518 cpustate->regs.w[CX]--;
\r
519 cpustate->regs.w[DI] += cpustate->DirVal;
\r
520 cpustate->regs.w[SI] += cpustate->DirVal;
\r
521 ICOUNT -= timing.rep_movs8_count;
\r
524 case 0xa5: /* REP MOVSW */
\r
525 if (!cpustate->rep_in_progress)
\r
526 ICOUNT -= timing.rep_movs16_base;
\r
527 cpustate->rep_in_progress = FALSE;
\r
528 while(cpustate->regs.w[CX])
\r
532 // if (ICOUNT <= 0) { cpustate->pc = cpustate->prevpc; cpustate->rep_in_progress = TRUE; break; }
\r
533 tmp = GetMemW(DS,cpustate->regs.w[SI]);
\r
534 PutMemW(ES,cpustate->regs.w[DI], tmp);
\r
535 cpustate->regs.w[CX]--;
\r
536 cpustate->regs.w[DI] += 2 * cpustate->DirVal;
\r
537 cpustate->regs.w[SI] += 2 * cpustate->DirVal;
\r
538 ICOUNT -= timing.rep_movs16_count;
\r
541 case 0xa6: /* REP(N)E CMPSB */
\r
542 if (!cpustate->rep_in_progress)
\r
543 ICOUNT -= timing.rep_cmps8_base;
\r
544 cpustate->rep_in_progress = FALSE;
\r
545 cpustate->ZeroVal = !flagval;
\r
546 while(cpustate->regs.w[CX] && (ZF == flagval))
\r
550 // if (ICOUNT <= 0) { cpustate->pc = cpustate->prevpc; cpustate->rep_in_progress = TRUE; break; }
\r
551 dst = GetMemB(ES, cpustate->regs.w[DI]);
\r
552 src = GetMemB(DS, cpustate->regs.w[SI]);
\r
553 SUBB(src,dst); /* opposite of the usual convention */
\r
554 cpustate->regs.w[CX]--;
\r
555 cpustate->regs.w[DI] += cpustate->DirVal;
\r
556 cpustate->regs.w[SI] += cpustate->DirVal;
\r
557 ICOUNT -= timing.rep_cmps8_count;
\r
560 case 0xa7: /* REP(N)E CMPSW */
\r
561 if (!cpustate->rep_in_progress)
\r
562 ICOUNT -= timing.rep_cmps16_base;
\r
563 cpustate->rep_in_progress = FALSE;
\r
564 cpustate->ZeroVal = !flagval;
\r
565 while(cpustate->regs.w[CX] && (ZF == flagval))
\r
569 // if (ICOUNT <= 0) { cpustate->pc = cpustate->prevpc; cpustate->rep_in_progress = TRUE; break; }
\r
570 dst = GetMemW(ES, cpustate->regs.w[DI]);
\r
571 src = GetMemW(DS, cpustate->regs.w[SI]);
\r
572 SUBW(src,dst); /* opposite of the usual convention */
\r
573 cpustate->regs.w[CX]--;
\r
574 cpustate->regs.w[DI] += 2 * cpustate->DirVal;
\r
575 cpustate->regs.w[SI] += 2 * cpustate->DirVal;
\r
576 ICOUNT -= timing.rep_cmps16_count;
\r
579 case 0xaa: /* REP STOSB */
\r
580 if (!cpustate->rep_in_progress)
\r
581 ICOUNT -= timing.rep_stos8_base;
\r
582 cpustate->rep_in_progress = FALSE;
\r
583 while(cpustate->regs.w[CX])
\r
585 // if (ICOUNT <= 0) { cpustate->pc = cpustate->prevpc; cpustate->rep_in_progress = TRUE; break; }
\r
586 PutMemB(ES,cpustate->regs.w[DI],cpustate->regs.b[AL]);
\r
587 cpustate->regs.w[CX]--;
\r
588 cpustate->regs.w[DI] += cpustate->DirVal;
\r
589 ICOUNT -= timing.rep_stos8_count;
\r
592 case 0xab: /* REP STOSW */
\r
593 if (!cpustate->rep_in_progress)
\r
594 ICOUNT -= timing.rep_stos16_base;
\r
595 cpustate->rep_in_progress = FALSE;
\r
596 while(cpustate->regs.w[CX])
\r
598 // if (ICOUNT <= 0) { cpustate->pc = cpustate->prevpc; cpustate->rep_in_progress = TRUE; break; }
\r
599 PutMemW(ES,cpustate->regs.w[DI],cpustate->regs.w[AX]);
\r
600 cpustate->regs.w[CX]--;
\r
601 cpustate->regs.w[DI] += 2 * cpustate->DirVal;
\r
602 ICOUNT -= timing.rep_stos16_count;
\r
605 case 0xac: /* REP LODSB */
\r
606 if (!cpustate->rep_in_progress)
\r
607 ICOUNT -= timing.rep_lods8_base;
\r
608 cpustate->rep_in_progress = FALSE;
\r
609 while(cpustate->regs.w[CX])
\r
611 // if (ICOUNT <= 0) { cpustate->pc = cpustate->prevpc; cpustate->rep_in_progress = TRUE; break; }
\r
612 cpustate->regs.b[AL] = GetMemB(DS,cpustate->regs.w[SI]);
\r
613 cpustate->regs.w[CX]--;
\r
614 cpustate->regs.w[SI] += cpustate->DirVal;
\r
615 ICOUNT -= timing.rep_lods8_count;
\r
618 case 0xad: /* REP LODSW */
\r
619 if (!cpustate->rep_in_progress)
\r
620 ICOUNT -= timing.rep_lods16_base;
\r
621 cpustate->rep_in_progress = FALSE;
\r
622 while(cpustate->regs.w[CX])
\r
624 // if (ICOUNT <= 0) { cpustate->pc = cpustate->prevpc; cpustate->rep_in_progress = TRUE; break; }
\r
625 cpustate->regs.w[AX] = GetMemW(DS,cpustate->regs.w[SI]);
\r
626 cpustate->regs.w[CX]--;
\r
627 cpustate->regs.w[SI] += 2 * cpustate->DirVal;
\r
628 ICOUNT -= timing.rep_lods16_count;
\r
631 case 0xae: /* REP(N)E SCASB */
\r
632 if (!cpustate->rep_in_progress)
\r
633 ICOUNT -= timing.rep_scas8_base;
\r
634 cpustate->rep_in_progress = FALSE;
\r
635 cpustate->ZeroVal = !flagval;
\r
636 while(cpustate->regs.w[CX] && (ZF == flagval))
\r
640 // if (ICOUNT <= 0) { cpustate->pc = cpustate->prevpc; cpustate->rep_in_progress = TRUE; break; }
\r
641 src = GetMemB(ES, cpustate->regs.w[DI]);
\r
642 dst = cpustate->regs.b[AL];
\r
644 cpustate->regs.w[CX]--;
\r
645 cpustate->regs.w[DI] += cpustate->DirVal;
\r
646 ICOUNT -= timing.rep_scas8_count;
\r
649 case 0xaf: /* REP(N)E SCASW */
\r
650 if (!cpustate->rep_in_progress)
\r
651 ICOUNT -= timing.rep_scas16_base;
\r
652 cpustate->rep_in_progress = FALSE;
\r
653 cpustate->ZeroVal = !flagval;
\r
654 while(cpustate->regs.w[CX] && (ZF == flagval))
\r
658 // if (ICOUNT <= 0) { cpustate->pc = cpustate->prevpc; cpustate->rep_in_progress = TRUE; break; }
\r
659 src = GetMemW(ES, cpustate->regs.w[DI]);
\r
660 dst = cpustate->regs.w[AX];
\r
662 cpustate->regs.w[CX]--;
\r
663 cpustate->regs.w[DI] += 2 * cpustate->DirVal;
\r
664 ICOUNT -= timing.rep_scas16_count;
\r
668 PREFIX(_instruction)[next](cpustate);
\r
673 static void PREFIX86(_add_br8)(i8086_state *cpustate) /* Opcode 0x00 */
\r
676 ICOUNT -= (ModRM >= 0xc0) ? timing.alu_rr8 : timing.alu_mr8;
\r
678 PutbackRMByte(ModRM,dst);
\r
681 static void PREFIX86(_add_wr16)(i8086_state *cpustate) /* Opcode 0x01 */
\r
684 ICOUNT -= (ModRM >= 0xc0) ? timing.alu_rr16 : timing.alu_mr16;
\r
686 PutbackRMWord(ModRM,dst);
\r
689 static void PREFIX86(_add_r8b)(i8086_state *cpustate) /* Opcode 0x02 */
\r
692 ICOUNT -= (ModRM >= 0xc0) ? timing.alu_rr8 : timing.alu_rm8;
\r
694 RegByte(ModRM)=dst;
\r
697 static void PREFIX86(_add_r16w)(i8086_state *cpustate) /* Opcode 0x03 */
\r
700 ICOUNT -= (ModRM >= 0xc0) ? timing.alu_rr16 : timing.alu_rm16;
\r
702 RegWord(ModRM)=dst;
\r
706 static void PREFIX86(_add_ald8)(i8086_state *cpustate) /* Opcode 0x04 */
\r
709 ICOUNT -= timing.alu_ri8;
\r
711 cpustate->regs.b[AL]=dst;
\r
715 static void PREFIX86(_add_axd16)(i8086_state *cpustate) /* Opcode 0x05 */
\r
717 DEF_axd16(dst,src);
\r
718 ICOUNT -= timing.alu_ri16;
\r
720 cpustate->regs.w[AX]=dst;
\r
724 static void PREFIX86(_push_es)(i8086_state *cpustate) /* Opcode 0x06 */
\r
726 ICOUNT -= timing.push_seg;
\r
727 PUSH(cpustate->sregs[ES]);
\r
731 static void PREFIX86(_pop_es)(i8086_state *cpustate) /* Opcode 0x07 */
\r
734 i80286_pop_seg(cpustate,ES);
\r
736 POP(cpustate->sregs[ES]);
\r
737 cpustate->base[ES] = SegBase(ES);
\r
739 ICOUNT -= timing.pop_seg;
\r
742 static void PREFIX86(_or_br8)(i8086_state *cpustate) /* Opcode 0x08 */
\r
745 ICOUNT -= (ModRM >= 0xc0) ? timing.alu_rr8 : timing.alu_mr8;
\r
747 PutbackRMByte(ModRM,dst);
\r
750 static void PREFIX86(_or_wr16)(i8086_state *cpustate) /* Opcode 0x09 */
\r
753 ICOUNT -= (ModRM >= 0xc0) ? timing.alu_rr16 : timing.alu_mr16;
\r
755 PutbackRMWord(ModRM,dst);
\r
758 static void PREFIX86(_or_r8b)(i8086_state *cpustate) /* Opcode 0x0a */
\r
761 ICOUNT -= (ModRM >= 0xc0) ? timing.alu_rr8 : timing.alu_rm8;
\r
763 RegByte(ModRM)=dst;
\r
766 static void PREFIX86(_or_r16w)(i8086_state *cpustate) /* Opcode 0x0b */
\r
769 ICOUNT -= (ModRM >= 0xc0) ? timing.alu_rr16 : timing.alu_rm16;
\r
771 RegWord(ModRM)=dst;
\r
774 static void PREFIX86(_or_ald8)(i8086_state *cpustate) /* Opcode 0x0c */
\r
777 ICOUNT -= timing.alu_ri8;
\r
779 cpustate->regs.b[AL]=dst;
\r
782 static void PREFIX86(_or_axd16)(i8086_state *cpustate) /* Opcode 0x0d */
\r
784 DEF_axd16(dst,src);
\r
785 ICOUNT -= timing.alu_ri16;
\r
787 cpustate->regs.w[AX]=dst;
\r
790 static void PREFIX86(_push_cs)(i8086_state *cpustate) /* Opcode 0x0e */
\r
792 ICOUNT -= timing.push_seg;
\r
793 PUSH(cpustate->sregs[CS]);
\r
797 static void PREFIX86(_pop_cs)(i8086_state *cpustate) /* Opcode 0x0f */
\r
799 int ip = cpustate->pc - cpustate->base[CS];
\r
800 ICOUNT -= timing.push_seg;
\r
801 POP(cpustate->sregs[CS]);
\r
802 cpustate->base[CS] = SegBase(CS);
\r
803 cpustate->pc = (ip + cpustate->base[CS]) & AMASK;
\r
804 CHANGE_PC(cpustate->pc);
\r
808 static void PREFIX86(_adc_br8)(i8086_state *cpustate) /* Opcode 0x10 */
\r
812 ICOUNT -= (ModRM >= 0xc0) ? timing.alu_rr8 : timing.alu_mr8;
\r
814 ADCB(dst,src,tmpcf);
\r
815 PutbackRMByte(ModRM,dst);
\r
816 cpustate->CarryVal = tmpcf;
\r
819 static void PREFIX86(_adc_wr16)(i8086_state *cpustate) /* Opcode 0x11 */
\r
823 ICOUNT -= (ModRM >= 0xc0) ? timing.alu_rr16 : timing.alu_mr16;
\r
825 ADCW(dst,src,tmpcf);
\r
826 PutbackRMWord(ModRM,dst);
\r
827 cpustate->CarryVal = tmpcf;
\r
830 static void PREFIX86(_adc_r8b)(i8086_state *cpustate) /* Opcode 0x12 */
\r
833 ICOUNT -= (ModRM >= 0xc0) ? timing.alu_rr8 : timing.alu_rm8;
\r
836 RegByte(ModRM)=dst;
\r
839 static void PREFIX86(_adc_r16w)(i8086_state *cpustate) /* Opcode 0x13 */
\r
842 ICOUNT -= (ModRM >= 0xc0) ? timing.alu_rr16 : timing.alu_rm16;
\r
845 RegWord(ModRM)=dst;
\r
848 static void PREFIX86(_adc_ald8)(i8086_state *cpustate) /* Opcode 0x14 */
\r
851 ICOUNT -= timing.alu_ri8;
\r
854 cpustate->regs.b[AL] = dst;
\r
857 static void PREFIX86(_adc_axd16)(i8086_state *cpustate) /* Opcode 0x15 */
\r
859 DEF_axd16(dst,src);
\r
860 ICOUNT -= timing.alu_ri16;
\r
863 cpustate->regs.w[AX]=dst;
\r
866 static void PREFIX86(_push_ss)(i8086_state *cpustate) /* Opcode 0x16 */
\r
868 PUSH(cpustate->sregs[SS]);
\r
869 ICOUNT -= timing.push_seg;
\r
872 static void PREFIX86(_sbb_br8)(i8086_state *cpustate) /* Opcode 0x18 */
\r
876 ICOUNT -= (ModRM >= 0xc0) ? timing.alu_rr8 : timing.alu_mr8;
\r
878 SBBB(dst,src,tmpcf);
\r
879 PutbackRMByte(ModRM,dst);
\r
880 cpustate->CarryVal = tmpcf;
\r
883 static void PREFIX86(_sbb_wr16)(i8086_state *cpustate) /* Opcode 0x19 */
\r
887 ICOUNT -= (ModRM >= 0xc0) ? timing.alu_rr16 : timing.alu_mr16;
\r
889 SBBW(dst,src,tmpcf);
\r
890 PutbackRMWord(ModRM,dst);
\r
891 cpustate->CarryVal = tmpcf;
\r
894 static void PREFIX86(_sbb_r8b)(i8086_state *cpustate) /* Opcode 0x1a */
\r
897 ICOUNT -= (ModRM >= 0xc0) ? timing.alu_rr8 : timing.alu_rm8;
\r
900 RegByte(ModRM)=dst;
\r
903 static void PREFIX86(_sbb_r16w)(i8086_state *cpustate) /* Opcode 0x1b */
\r
906 ICOUNT -= (ModRM >= 0xc0) ? timing.alu_rr16 : timing.alu_rm16;
\r
909 RegWord(ModRM)= dst;
\r
912 static void PREFIX86(_sbb_ald8)(i8086_state *cpustate) /* Opcode 0x1c */
\r
915 ICOUNT -= timing.alu_ri8;
\r
918 cpustate->regs.b[AL] = dst;
\r
921 static void PREFIX86(_sbb_axd16)(i8086_state *cpustate) /* Opcode 0x1d */
\r
923 DEF_axd16(dst,src);
\r
924 ICOUNT -= timing.alu_ri16;
\r
927 cpustate->regs.w[AX]=dst;
\r
930 static void PREFIX86(_push_ds)(i8086_state *cpustate) /* Opcode 0x1e */
\r
932 PUSH(cpustate->sregs[DS]);
\r
933 ICOUNT -= timing.push_seg;
\r
936 static void PREFIX86(_pop_ds)(i8086_state *cpustate) /* Opcode 0x1f */
\r
939 i80286_pop_seg(cpustate,DS);
\r
941 POP(cpustate->sregs[DS]);
\r
942 cpustate->base[DS] = SegBase(DS);
\r
944 ICOUNT -= timing.push_seg;
\r
947 static void PREFIX86(_and_br8)(i8086_state *cpustate) /* Opcode 0x20 */
\r
950 ICOUNT -= (ModRM >= 0xc0) ? timing.alu_rr8 : timing.alu_mr8;
\r
952 PutbackRMByte(ModRM,dst);
\r
955 static void PREFIX86(_and_wr16)(i8086_state *cpustate) /* Opcode 0x21 */
\r
958 ICOUNT -= (ModRM >= 0xc0) ? timing.alu_rr16 : timing.alu_mr16;
\r
960 PutbackRMWord(ModRM,dst);
\r
963 static void PREFIX86(_and_r8b)(i8086_state *cpustate) /* Opcode 0x22 */
\r
966 ICOUNT -= (ModRM >= 0xc0) ? timing.alu_rr8 : timing.alu_rm8;
\r
968 RegByte(ModRM)=dst;
\r
971 static void PREFIX86(_and_r16w)(i8086_state *cpustate) /* Opcode 0x23 */
\r
974 ICOUNT -= (ModRM >= 0xc0) ? timing.alu_rr16 : timing.alu_rm16;
\r
976 RegWord(ModRM)=dst;
\r
979 static void PREFIX86(_and_ald8)(i8086_state *cpustate) /* Opcode 0x24 */
\r
982 ICOUNT -= timing.alu_ri8;
\r
984 cpustate->regs.b[AL] = dst;
\r
987 static void PREFIX86(_and_axd16)(i8086_state *cpustate) /* Opcode 0x25 */
\r
989 DEF_axd16(dst,src);
\r
990 ICOUNT -= timing.alu_ri16;
\r
992 cpustate->regs.w[AX]=dst;
\r
995 static void PREFIX86(_daa)(i8086_state *cpustate) /* Opcode 0x27 */
\r
997 if (AF || ((cpustate->regs.b[AL] & 0xf) > 9))
\r
1000 cpustate->regs.b[AL] = tmp = cpustate->regs.b[AL] + 6;
\r
1001 cpustate->AuxVal = 1;
\r
1002 cpustate->CarryVal |= tmp & 0x100;
\r
1005 if (CF || (cpustate->regs.b[AL] > 0x9f))
\r
1007 cpustate->regs.b[AL] += 0x60;
\r
1008 cpustate->CarryVal = 1;
\r
1011 SetSZPF_Byte(cpustate->regs.b[AL]);
\r
1012 ICOUNT -= timing.daa;
\r
1015 static void PREFIX86(_sub_br8)(i8086_state *cpustate) /* Opcode 0x28 */
\r
1018 ICOUNT -= (ModRM >= 0xc0) ? timing.alu_rr8 : timing.alu_mr8;
\r
1020 PutbackRMByte(ModRM,dst);
\r
1023 static void PREFIX86(_sub_wr16)(i8086_state *cpustate) /* Opcode 0x29 */
\r
1025 DEF_wr16(dst,src);
\r
1026 ICOUNT -= (ModRM >= 0xc0) ? timing.alu_rr16 : timing.alu_mr16;
\r
1028 PutbackRMWord(ModRM,dst);
\r
1031 static void PREFIX86(_sub_r8b)(i8086_state *cpustate) /* Opcode 0x2a */
\r
1034 ICOUNT -= (ModRM >= 0xc0) ? timing.alu_rr8 : timing.alu_rm8;
\r
1036 RegByte(ModRM)=dst;
\r
1039 static void PREFIX86(_sub_r16w)(i8086_state *cpustate) /* Opcode 0x2b */
\r
1041 DEF_r16w(dst,src);
\r
1042 ICOUNT -= (ModRM >= 0xc0) ? timing.alu_rr16 : timing.alu_rm16;
\r
1044 RegWord(ModRM)=dst;
\r
1047 static void PREFIX86(_sub_ald8)(i8086_state *cpustate) /* Opcode 0x2c */
\r
1049 DEF_ald8(dst,src);
\r
1050 ICOUNT -= timing.alu_ri8;
\r
1052 cpustate->regs.b[AL] = dst;
\r
1055 static void PREFIX86(_sub_axd16)(i8086_state *cpustate) /* Opcode 0x2d */
\r
1057 DEF_axd16(dst,src);
\r
1058 ICOUNT -= timing.alu_ri16;
\r
1060 cpustate->regs.w[AX]=dst;
\r
1063 static void PREFIX86(_das)(i8086_state *cpustate) /* Opcode 0x2f */
\r
1065 UINT8 tmpAL=cpustate->regs.b[AL];
\r
1066 if (AF || ((cpustate->regs.b[AL] & 0xf) > 9))
\r
1069 cpustate->regs.b[AL] = tmp = cpustate->regs.b[AL] - 6;
\r
1070 cpustate->AuxVal = 1;
\r
1071 cpustate->CarryVal |= tmp & 0x100;
\r
1074 if (CF || (tmpAL > 0x9f))
\r
1076 cpustate->regs.b[AL] -= 0x60;
\r
1077 cpustate->CarryVal = 1;
\r
1080 SetSZPF_Byte(cpustate->regs.b[AL]);
\r
1081 ICOUNT -= timing.das;
\r
1084 static void PREFIX86(_xor_br8)(i8086_state *cpustate) /* Opcode 0x30 */
\r
1087 ICOUNT -= (ModRM >= 0xc0) ? timing.alu_rr8 : timing.alu_mr8;
\r
1089 PutbackRMByte(ModRM,dst);
\r
1092 static void PREFIX86(_xor_wr16)(i8086_state *cpustate) /* Opcode 0x31 */
\r
1094 DEF_wr16(dst,src);
\r
1095 ICOUNT -= (ModRM >= 0xc0) ? timing.alu_rr16 : timing.alu_mr16;
\r
1097 PutbackRMWord(ModRM,dst);
\r
1100 static void PREFIX86(_xor_r8b)(i8086_state *cpustate) /* Opcode 0x32 */
\r
1103 ICOUNT -= (ModRM >= 0xc0) ? timing.alu_rr8 : timing.alu_rm8;
\r
1105 RegByte(ModRM)=dst;
\r
1108 static void PREFIX86(_xor_r16w)(i8086_state *cpustate) /* Opcode 0x33 */
\r
1110 DEF_r16w(dst,src);
\r
1111 ICOUNT -= (ModRM >= 0xc0) ? timing.alu_rr16 : timing.alu_rm16;
\r
1113 RegWord(ModRM)=dst;
\r
1116 static void PREFIX86(_xor_ald8)(i8086_state *cpustate) /* Opcode 0x34 */
\r
1118 DEF_ald8(dst,src);
\r
1119 ICOUNT -= timing.alu_ri8;
\r
1121 cpustate->regs.b[AL] = dst;
\r
1124 static void PREFIX86(_xor_axd16)(i8086_state *cpustate) /* Opcode 0x35 */
\r
1126 DEF_axd16(dst,src);
\r
1127 ICOUNT -= timing.alu_ri16;
\r
1129 cpustate->regs.w[AX]=dst;
\r
1132 static void PREFIX86(_aaa)(i8086_state *cpustate) /* Opcode 0x37 */
\r
1135 if (cpustate->regs.b[AL]>0xf9) ALcarry=2;
\r
1137 if (AF || ((cpustate->regs.b[AL] & 0xf) > 9))
\r
1139 cpustate->regs.b[AL] += 6;
\r
1140 cpustate->regs.b[AH] += ALcarry;
\r
1141 cpustate->AuxVal = 1;
\r
1142 cpustate->CarryVal = 1;
\r
1146 cpustate->AuxVal = 0;
\r
1147 cpustate->CarryVal = 0;
\r
1149 cpustate->regs.b[AL] &= 0x0F;
\r
1150 ICOUNT -= timing.aaa;
\r
1153 static void PREFIX86(_cmp_br8)(i8086_state *cpustate) /* Opcode 0x38 */
\r
1156 ICOUNT -= (ModRM >= 0xc0) ? timing.alu_rr8 : timing.alu_rm8;
\r
1160 static void PREFIX86(_cmp_wr16)(i8086_state *cpustate) /* Opcode 0x39 */
\r
1162 DEF_wr16(dst,src);
\r
1163 ICOUNT -= (ModRM >= 0xc0) ? timing.alu_rr16 : timing.alu_rm16;
\r
1167 static void PREFIX86(_cmp_r8b)(i8086_state *cpustate) /* Opcode 0x3a */
\r
1170 ICOUNT -= (ModRM >= 0xc0) ? timing.alu_rr8 : timing.alu_rm8;
\r
1174 static void PREFIX86(_cmp_r16w)(i8086_state *cpustate) /* Opcode 0x3b */
\r
1176 DEF_r16w(dst,src);
\r
1177 ICOUNT -= (ModRM >= 0xc0) ? timing.alu_rr16 : timing.alu_rm16;
\r
1181 static void PREFIX86(_cmp_ald8)(i8086_state *cpustate) /* Opcode 0x3c */
\r
1183 DEF_ald8(dst,src);
\r
1184 ICOUNT -= timing.alu_ri8;
\r
1188 static void PREFIX86(_cmp_axd16)(i8086_state *cpustate) /* Opcode 0x3d */
\r
1190 DEF_axd16(dst,src);
\r
1191 ICOUNT -= timing.alu_ri16;
\r
1195 static void PREFIX86(_aas)(i8086_state *cpustate) /* Opcode 0x3f */
\r
1197 // UINT8 ALcarry=1;
\r
1198 // if (cpustate->regs.b[AL]>0xf9) ALcarry=2;
\r
1200 if (AF || ((cpustate->regs.b[AL] & 0xf) > 9))
\r
1202 cpustate->regs.b[AL] -= 6;
\r
1203 cpustate->regs.b[AH] -= 1;
\r
1204 cpustate->AuxVal = 1;
\r
1205 cpustate->CarryVal = 1;
\r
1209 cpustate->AuxVal = 0;
\r
1210 cpustate->CarryVal = 0;
\r
1212 cpustate->regs.b[AL] &= 0x0F;
\r
1213 ICOUNT -= timing.aas;
\r
1216 #define IncWordReg(Reg) \
\r
1218 unsigned tmp = (unsigned)cpustate->regs.w[Reg]; \
\r
1219 unsigned tmp1 = tmp+1; \
\r
1220 SetOFW_Add(tmp1,tmp,1); \
\r
1221 SetAF(tmp1,tmp,1); \
\r
1222 SetSZPF_Word(tmp1); \
\r
1223 cpustate->regs.w[Reg]=tmp1; \
\r
1224 ICOUNT -= timing.incdec_r16; \
\r
1227 static void PREFIX86(_inc_ax)(i8086_state *cpustate) /* Opcode 0x40 */
\r
1232 static void PREFIX86(_inc_cx)(i8086_state *cpustate) /* Opcode 0x41 */
\r
1237 static void PREFIX86(_inc_dx)(i8086_state *cpustate) /* Opcode 0x42 */
\r
1242 static void PREFIX(_inc_bx)(i8086_state *cpustate) /* Opcode 0x43 */
\r
1247 static void PREFIX86(_inc_sp)(i8086_state *cpustate) /* Opcode 0x44 */
\r
1252 static void PREFIX86(_inc_bp)(i8086_state *cpustate) /* Opcode 0x45 */
\r
1257 static void PREFIX86(_inc_si)(i8086_state *cpustate) /* Opcode 0x46 */
\r
1262 static void PREFIX86(_inc_di)(i8086_state *cpustate) /* Opcode 0x47 */
\r
1267 #define DecWordReg(Reg) \
\r
1269 unsigned tmp = (unsigned)cpustate->regs.w[Reg]; \
\r
1270 unsigned tmp1 = tmp-1; \
\r
1271 SetOFW_Sub(tmp1,1,tmp); \
\r
1272 SetAF(tmp1,tmp,1); \
\r
1273 SetSZPF_Word(tmp1); \
\r
1274 cpustate->regs.w[Reg]=tmp1; \
\r
1275 ICOUNT -= timing.incdec_r16; \
\r
1278 static void PREFIX86(_dec_ax)(i8086_state *cpustate) /* Opcode 0x48 */
\r
1283 static void PREFIX86(_dec_cx)(i8086_state *cpustate) /* Opcode 0x49 */
\r
1288 static void PREFIX86(_dec_dx)(i8086_state *cpustate) /* Opcode 0x4a */
\r
1293 static void PREFIX86(_dec_bx)(i8086_state *cpustate) /* Opcode 0x4b */
\r
1298 static void PREFIX86(_dec_sp)(i8086_state *cpustate) /* Opcode 0x4c */
\r
1303 static void PREFIX86(_dec_bp)(i8086_state *cpustate) /* Opcode 0x4d */
\r
1308 static void PREFIX86(_dec_si)(i8086_state *cpustate) /* Opcode 0x4e */
\r
1313 static void PREFIX86(_dec_di)(i8086_state *cpustate) /* Opcode 0x4f */
\r
1318 static void PREFIX86(_push_ax)(i8086_state *cpustate) /* Opcode 0x50 */
\r
1320 ICOUNT -= timing.push_r16;
\r
1321 PUSH(cpustate->regs.w[AX]);
\r
1324 static void PREFIX86(_push_cx)(i8086_state *cpustate) /* Opcode 0x51 */
\r
1326 ICOUNT -= timing.push_r16;
\r
1327 PUSH(cpustate->regs.w[CX]);
\r
1330 static void PREFIX86(_push_dx)(i8086_state *cpustate) /* Opcode 0x52 */
\r
1332 ICOUNT -= timing.push_r16;
\r
1333 PUSH(cpustate->regs.w[DX]);
\r
1336 static void PREFIX86(_push_bx)(i8086_state *cpustate) /* Opcode 0x53 */
\r
1338 ICOUNT -= timing.push_r16;
\r
1339 PUSH(cpustate->regs.w[BX]);
\r
1342 static void PREFIX86(_push_sp)(i8086_state *cpustate) /* Opcode 0x54 */
\r
1344 ICOUNT -= timing.push_r16;
\r
1346 PUSH(cpustate->regs.w[SP]+2);
\r
1348 PUSH(cpustate->regs.w[SP]);
\r
1352 static void PREFIX86(_push_bp)(i8086_state *cpustate) /* Opcode 0x55 */
\r
1354 ICOUNT -= timing.push_r16;
\r
1355 PUSH(cpustate->regs.w[BP]);
\r
1359 static void PREFIX86(_push_si)(i8086_state *cpustate) /* Opcode 0x56 */
\r
1361 ICOUNT -= timing.push_r16;
\r
1362 PUSH(cpustate->regs.w[SI]);
\r
1365 static void PREFIX86(_push_di)(i8086_state *cpustate) /* Opcode 0x57 */
\r
1367 ICOUNT -= timing.push_r16;
\r
1368 PUSH(cpustate->regs.w[DI]);
\r
1371 static void PREFIX86(_pop_ax)(i8086_state *cpustate) /* Opcode 0x58 */
\r
1373 ICOUNT -= timing.pop_r16;
\r
1374 POP(cpustate->regs.w[AX]);
\r
1377 static void PREFIX86(_pop_cx)(i8086_state *cpustate) /* Opcode 0x59 */
\r
1379 ICOUNT -= timing.pop_r16;
\r
1380 POP(cpustate->regs.w[CX]);
\r
1383 static void PREFIX86(_pop_dx)(i8086_state *cpustate) /* Opcode 0x5a */
\r
1385 ICOUNT -= timing.pop_r16;
\r
1386 POP(cpustate->regs.w[DX]);
\r
1389 static void PREFIX86(_pop_bx)(i8086_state *cpustate) /* Opcode 0x5b */
\r
1391 ICOUNT -= timing.pop_r16;
\r
1392 POP(cpustate->regs.w[BX]);
\r
1395 static void PREFIX86(_pop_sp)(i8086_state *cpustate) /* Opcode 0x5c */
\r
1397 ICOUNT -= timing.pop_r16;
\r
1398 POP(cpustate->regs.w[SP]);
\r
1401 static void PREFIX86(_pop_bp)(i8086_state *cpustate) /* Opcode 0x5d */
\r
1403 ICOUNT -= timing.pop_r16;
\r
1404 POP(cpustate->regs.w[BP]);
\r
1407 static void PREFIX86(_pop_si)(i8086_state *cpustate) /* Opcode 0x5e */
\r
1409 ICOUNT -= timing.pop_r16;
\r
1410 POP(cpustate->regs.w[SI]);
\r
1413 static void PREFIX86(_pop_di)(i8086_state *cpustate) /* Opcode 0x5f */
\r
1415 ICOUNT -= timing.pop_r16;
\r
1416 POP(cpustate->regs.w[DI]);
\r
1419 static void PREFIX86(_jo)(i8086_state *cpustate) /* Opcode 0x70 */
\r
1421 int tmp = (int)((INT8)FETCH);
\r
1424 cpustate->pc += tmp;
\r
1425 ICOUNT -= timing.jcc_t;
\r
1426 /* ASG - can probably assume this is safe
\r
1427 CHANGE_PC(cpustate->pc);*/
\r
1428 } else ICOUNT -= timing.jcc_nt;
\r
1431 static void PREFIX86(_jno)(i8086_state *cpustate) /* Opcode 0x71 */
\r
1433 int tmp = (int)((INT8)FETCH);
\r
1435 cpustate->pc += tmp;
\r
1436 ICOUNT -= timing.jcc_t;
\r
1437 /* ASG - can probably assume this is safe
\r
1438 CHANGE_PC(cpustate->pc);*/
\r
1439 } else ICOUNT -= timing.jcc_nt;
\r
1442 static void PREFIX86(_jb)(i8086_state *cpustate) /* Opcode 0x72 */
\r
1444 int tmp = (int)((INT8)FETCH);
\r
1446 cpustate->pc += tmp;
\r
1447 ICOUNT -= timing.jcc_t;
\r
1448 /* ASG - can probably assume this is safe
\r
1449 CHANGE_PC(cpustate->pc);*/
\r
1450 } else ICOUNT -= timing.jcc_nt;
\r
1453 static void PREFIX86(_jnb)(i8086_state *cpustate) /* Opcode 0x73 */
\r
1455 int tmp = (int)((INT8)FETCH);
\r
1457 cpustate->pc += tmp;
\r
1458 ICOUNT -= timing.jcc_t;
\r
1459 /* ASG - can probably assume this is safe
\r
1460 CHANGE_PC(cpustate->pc);*/
\r
1461 } else ICOUNT -= timing.jcc_nt;
\r
1464 static void PREFIX86(_jz)(i8086_state *cpustate) /* Opcode 0x74 */
\r
1466 int tmp = (int)((INT8)FETCH);
\r
1468 cpustate->pc += tmp;
\r
1469 ICOUNT -= timing.jcc_t;
\r
1470 /* ASG - can probably assume this is safe
\r
1471 CHANGE_PC(cpustate->pc);*/
\r
1472 } else ICOUNT -= timing.jcc_nt;
\r
1475 static void PREFIX86(_jnz)(i8086_state *cpustate) /* Opcode 0x75 */
\r
1477 int tmp = (int)((INT8)FETCH);
\r
1479 cpustate->pc += tmp;
\r
1480 ICOUNT -= timing.jcc_t;
\r
1481 /* ASG - can probably assume this is safe
\r
1482 CHANGE_PC(cpustate->pc);*/
\r
1483 } else ICOUNT -= timing.jcc_nt;
\r
1486 static void PREFIX86(_jbe)(i8086_state *cpustate) /* Opcode 0x76 */
\r
1488 int tmp = (int)((INT8)FETCH);
\r
1490 cpustate->pc += tmp;
\r
1491 ICOUNT -= timing.jcc_t;
\r
1492 /* ASG - can probably assume this is safe
\r
1493 CHANGE_PC(cpustate->pc);*/
\r
1494 } else ICOUNT -= timing.jcc_nt;
\r
1497 static void PREFIX86(_jnbe)(i8086_state *cpustate) /* Opcode 0x77 */
\r
1499 int tmp = (int)((INT8)FETCH);
\r
1500 if (!(CF || ZF)) {
\r
1501 cpustate->pc += tmp;
\r
1502 ICOUNT -= timing.jcc_t;
\r
1503 /* ASG - can probably assume this is safe
\r
1504 CHANGE_PC(cpustate->pc);*/
\r
1505 } else ICOUNT -= timing.jcc_nt;
\r
1508 static void PREFIX86(_js)(i8086_state *cpustate) /* Opcode 0x78 */
\r
1510 int tmp = (int)((INT8)FETCH);
\r
1512 cpustate->pc += tmp;
\r
1513 ICOUNT -= timing.jcc_t;
\r
1514 /* ASG - can probably assume this is safe
\r
1515 CHANGE_PC(cpustate->pc);*/
\r
1516 } else ICOUNT -= timing.jcc_nt;
\r
1519 static void PREFIX86(_jns)(i8086_state *cpustate) /* Opcode 0x79 */
\r
1521 int tmp = (int)((INT8)FETCH);
\r
1523 cpustate->pc += tmp;
\r
1524 ICOUNT -= timing.jcc_t;
\r
1525 /* ASG - can probably assume this is safe
\r
1526 CHANGE_PC(cpustate->pc);*/
\r
1527 } else ICOUNT -= timing.jcc_nt;
\r
1530 static void PREFIX86(_jp)(i8086_state *cpustate) /* Opcode 0x7a */
\r
1532 int tmp = (int)((INT8)FETCH);
\r
1534 cpustate->pc += tmp;
\r
1535 ICOUNT -= timing.jcc_t;
\r
1536 /* ASG - can probably assume this is safe
\r
1537 CHANGE_PC(cpustate->pc);*/
\r
1538 } else ICOUNT -= timing.jcc_nt;
\r
1541 static void PREFIX86(_jnp)(i8086_state *cpustate) /* Opcode 0x7b */
\r
1543 int tmp = (int)((INT8)FETCH);
\r
1545 cpustate->pc += tmp;
\r
1546 ICOUNT -= timing.jcc_t;
\r
1547 /* ASG - can probably assume this is safe
\r
1548 CHANGE_PC(cpustate->pc);*/
\r
1549 } else ICOUNT -= timing.jcc_nt;
\r
1552 static void PREFIX86(_jl)(i8086_state *cpustate) /* Opcode 0x7c */
\r
1554 int tmp = (int)((INT8)FETCH);
\r
1555 if ((SF!=OF)&&!ZF) {
\r
1556 cpustate->pc += tmp;
\r
1557 ICOUNT -= timing.jcc_t;
\r
1558 /* ASG - can probably assume this is safe
\r
1559 CHANGE_PC(cpustate->pc);*/
\r
1560 } else ICOUNT -= timing.jcc_nt;
\r
1563 static void PREFIX86(_jnl)(i8086_state *cpustate) /* Opcode 0x7d */
\r
1565 int tmp = (int)((INT8)FETCH);
\r
1566 if (ZF||(SF==OF)) {
\r
1567 cpustate->pc += tmp;
\r
1568 ICOUNT -= timing.jcc_t;
\r
1569 /* ASG - can probably assume this is safe
\r
1570 CHANGE_PC(cpustate->pc);*/
\r
1571 } else ICOUNT -= timing.jcc_nt;
\r
1574 static void PREFIX86(_jle)(i8086_state *cpustate) /* Opcode 0x7e */
\r
1576 int tmp = (int)((INT8)FETCH);
\r
1577 if (ZF||(SF!=OF)) {
\r
1578 cpustate->pc += tmp;
\r
1579 ICOUNT -= timing.jcc_t;
\r
1580 /* ASG - can probably assume this is safe
\r
1581 CHANGE_PC(cpustate->pc);*/
\r
1582 } else ICOUNT -= timing.jcc_nt;
\r
1585 static void PREFIX86(_jnle)(i8086_state *cpustate) /* Opcode 0x7f */
\r
1587 int tmp = (int)((INT8)FETCH);
\r
1588 if ((SF==OF)&&!ZF) {
\r
1589 cpustate->pc += tmp;
\r
1590 ICOUNT -= timing.jcc_t;
\r
1591 /* ASG - can probably assume this is safe
\r
1592 CHANGE_PC(cpustate->pc);*/
\r
1593 } else ICOUNT -= timing.jcc_nt;
\r
1596 static void PREFIX86(_80pre)(i8086_state *cpustate) /* Opcode 0x80 */
\r
1598 unsigned ModRM = FETCHOP;
\r
1599 unsigned dst = GetRMByte(ModRM);
\r
1600 unsigned src = FETCH;
\r
1603 switch (ModRM & 0x38)
\r
1605 case 0x00: /* ADD eb,d8 */
\r
1607 PutbackRMByte(ModRM,dst);
\r
1608 ICOUNT -= (ModRM >= 0xc0) ? timing.alu_ri8 : timing.alu_mi8;
\r
1610 case 0x08: /* OR eb,d8 */
\r
1612 PutbackRMByte(ModRM,dst);
\r
1613 ICOUNT -= (ModRM >= 0xc0) ? timing.alu_ri8 : timing.alu_mi8;
\r
1615 case 0x10: /* ADC eb,d8 */
\r
1617 ADCB(dst,src,tmpcf);
\r
1618 PutbackRMByte(ModRM,dst);
\r
1619 cpustate->CarryVal = tmpcf;
\r
1620 ICOUNT -= (ModRM >= 0xc0) ? timing.alu_ri8 : timing.alu_mi8;
\r
1622 case 0x18: /* SBB eb,b8 */
\r
1624 SBBB(dst,src,tmpcf);
\r
1625 PutbackRMByte(ModRM,dst);
\r
1626 cpustate->CarryVal = tmpcf;
\r
1627 ICOUNT -= (ModRM >= 0xc0) ? timing.alu_ri8 : timing.alu_mi8;
\r
1629 case 0x20: /* AND eb,d8 */
\r
1631 PutbackRMByte(ModRM,dst);
\r
1632 ICOUNT -= (ModRM >= 0xc0) ? timing.alu_ri8 : timing.alu_mi8;
\r
1634 case 0x28: /* SUB eb,d8 */
\r
1636 PutbackRMByte(ModRM,dst);
\r
1637 ICOUNT -= (ModRM >= 0xc0) ? timing.alu_ri8 : timing.alu_mi8;
\r
1639 case 0x30: /* XOR eb,d8 */
\r
1641 PutbackRMByte(ModRM,dst);
\r
1642 ICOUNT -= (ModRM >= 0xc0) ? timing.alu_ri8 : timing.alu_mi8;
\r
1644 case 0x38: /* CMP eb,d8 */
\r
1646 ICOUNT -= (ModRM >= 0xc0) ? timing.alu_ri8 : timing.alu_mi8_ro;
\r
1652 static void PREFIX86(_81pre)(i8086_state *cpustate) /* Opcode 0x81 */
\r
1654 unsigned ModRM = FETCH;
\r
1655 unsigned dst = GetRMWord(ModRM);
\r
1656 unsigned src = FETCH;
\r
1658 src+= (FETCH << 8);
\r
1660 switch (ModRM & 0x38)
\r
1662 case 0x00: /* ADD ew,d16 */
\r
1664 PutbackRMWord(ModRM,dst);
\r
1665 ICOUNT -= (ModRM >= 0xc0) ? timing.alu_ri16 : timing.alu_mi16;
\r
1667 case 0x08: /* OR ew,d16 */
\r
1669 PutbackRMWord(ModRM,dst);
\r
1670 ICOUNT -= (ModRM >= 0xc0) ? timing.alu_ri16 : timing.alu_mi16;
\r
1672 case 0x10: /* ADC ew,d16 */
\r
1674 ADCW(dst,src,tmpcf);
\r
1675 PutbackRMWord(ModRM,dst);
\r
1676 cpustate->CarryVal = tmpcf;
\r
1677 ICOUNT -= (ModRM >= 0xc0) ? timing.alu_ri16 : timing.alu_mi16;
\r
1679 case 0x18: /* SBB ew,d16 */
\r
1681 SBBW(dst,src,tmpcf);
\r
1682 PutbackRMWord(ModRM,dst);
\r
1683 cpustate->CarryVal = tmpcf;
\r
1684 ICOUNT -= (ModRM >= 0xc0) ? timing.alu_ri16 : timing.alu_mi16;
\r
1686 case 0x20: /* AND ew,d16 */
\r
1688 PutbackRMWord(ModRM,dst);
\r
1689 ICOUNT -= (ModRM >= 0xc0) ? timing.alu_ri16 : timing.alu_mi16;
\r
1691 case 0x28: /* SUB ew,d16 */
\r
1693 PutbackRMWord(ModRM,dst);
\r
1694 ICOUNT -= (ModRM >= 0xc0) ? timing.alu_ri16 : timing.alu_mi16;
\r
1696 case 0x30: /* XOR ew,d16 */
\r
1698 PutbackRMWord(ModRM,dst);
\r
1699 ICOUNT -= (ModRM >= 0xc0) ? timing.alu_ri16 : timing.alu_mi16;
\r
1701 case 0x38: /* CMP ew,d16 */
\r
1703 ICOUNT -= (ModRM >= 0xc0) ? timing.alu_ri16 : timing.alu_mi16_ro;
\r
1708 static void PREFIX86(_82pre)(i8086_state *cpustate) /* Opcode 0x82 */
\r
1710 unsigned ModRM = FETCH;
\r
1711 unsigned dst = GetRMByte(ModRM);
\r
1712 unsigned src = FETCH;
\r
1715 switch (ModRM & 0x38)
\r
1717 case 0x00: /* ADD eb,d8 */
\r
1719 PutbackRMByte(ModRM,dst);
\r
1720 ICOUNT -= (ModRM >= 0xc0) ? timing.alu_ri8 : timing.alu_mi8;
\r
1722 case 0x08: /* OR eb,d8 */
\r
1724 PutbackRMByte(ModRM,dst);
\r
1725 ICOUNT -= (ModRM >= 0xc0) ? timing.alu_ri8 : timing.alu_mi8;
\r
1727 case 0x10: /* ADC eb,d8 */
\r
1729 ADCB(dst,src,tmpcf);
\r
1730 PutbackRMByte(ModRM,dst);
\r
1731 cpustate->CarryVal = tmpcf;
\r
1732 ICOUNT -= (ModRM >= 0xc0) ? timing.alu_ri8 : timing.alu_mi8;
\r
1734 case 0x18: /* SBB eb,d8 */
\r
1736 SBBB(dst,src,tmpcf);
\r
1737 PutbackRMByte(ModRM,dst);
\r
1738 cpustate->CarryVal = tmpcf;
\r
1739 ICOUNT -= (ModRM >= 0xc0) ? timing.alu_ri8 : timing.alu_mi8;
\r
1741 case 0x20: /* AND eb,d8 */
\r
1743 PutbackRMByte(ModRM,dst);
\r
1744 ICOUNT -= (ModRM >= 0xc0) ? timing.alu_ri8 : timing.alu_mi8;
\r
1746 case 0x28: /* SUB eb,d8 */
\r
1748 PutbackRMByte(ModRM,dst);
\r
1749 ICOUNT -= (ModRM >= 0xc0) ? timing.alu_ri8 : timing.alu_mi8;
\r
1751 case 0x30: /* XOR eb,d8 */
\r
1753 PutbackRMByte(ModRM,dst);
\r
1754 ICOUNT -= (ModRM >= 0xc0) ? timing.alu_ri8 : timing.alu_mi8;
\r
1756 case 0x38: /* CMP eb,d8 */
\r
1758 ICOUNT -= (ModRM >= 0xc0) ? timing.alu_ri8 : timing.alu_mi8_ro;
\r
1763 static void PREFIX86(_83pre)(i8086_state *cpustate) /* Opcode 0x83 */
\r
1765 unsigned ModRM = FETCH;
\r
1766 unsigned dst = GetRMWord(ModRM);
\r
1767 unsigned src = (WORD)((INT16)((INT8)FETCH));
\r
1770 switch (ModRM & 0x38)
\r
1772 case 0x00: /* ADD ew,d16 */
\r
1774 PutbackRMWord(ModRM,dst);
\r
1775 ICOUNT -= (ModRM >= 0xc0) ? timing.alu_r16i8 : timing.alu_m16i8;
\r
1777 case 0x08: /* OR ew,d16 */
\r
1779 PutbackRMWord(ModRM,dst);
\r
1780 ICOUNT -= (ModRM >= 0xc0) ? timing.alu_r16i8 : timing.alu_m16i8;
\r
1782 case 0x10: /* ADC ew,d16 */
\r
1784 ADCW(dst,src,tmpcf);
\r
1785 PutbackRMWord(ModRM,dst);
\r
1786 cpustate->CarryVal = tmpcf;
\r
1787 ICOUNT -= (ModRM >= 0xc0) ? timing.alu_r16i8 : timing.alu_m16i8;
\r
1789 case 0x18: /* SBB ew,d16 */
\r
1791 SBBW(dst,src,tmpcf);
\r
1792 PutbackRMWord(ModRM,dst);
\r
1793 cpustate->CarryVal = tmpcf;
\r
1794 ICOUNT -= (ModRM >= 0xc0) ? timing.alu_r16i8 : timing.alu_m16i8;
\r
1796 case 0x20: /* AND ew,d16 */
\r
1798 PutbackRMWord(ModRM,dst);
\r
1799 ICOUNT -= (ModRM >= 0xc0) ? timing.alu_r16i8 : timing.alu_m16i8;
\r
1801 case 0x28: /* SUB ew,d16 */
\r
1803 PutbackRMWord(ModRM,dst);
\r
1804 ICOUNT -= (ModRM >= 0xc0) ? timing.alu_r16i8 : timing.alu_m16i8;
\r
1806 case 0x30: /* XOR ew,d16 */
\r
1808 PutbackRMWord(ModRM,dst);
\r
1809 ICOUNT -= (ModRM >= 0xc0) ? timing.alu_r16i8 : timing.alu_m16i8;
\r
1811 case 0x38: /* CMP ew,d16 */
\r
1813 ICOUNT -= (ModRM >= 0xc0) ? timing.alu_r16i8 : timing.alu_m16i8_ro;
\r
1818 static void PREFIX86(_test_br8)(i8086_state *cpustate) /* Opcode 0x84 */
\r
1821 ICOUNT -= (ModRM >= 0xc0) ? timing.alu_rr8 : timing.alu_rm8;
\r
1825 static void PREFIX86(_test_wr16)(i8086_state *cpustate) /* Opcode 0x85 */
\r
1827 DEF_wr16(dst,src);
\r
1828 ICOUNT -= (ModRM >= 0xc0) ? timing.alu_rr16 : timing.alu_rm16;
\r
1832 static void PREFIX86(_xchg_br8)(i8086_state *cpustate) /* Opcode 0x86 */
\r
1835 ICOUNT -= (ModRM >= 0xc0) ? timing.xchg_rr8 : timing.xchg_rm8;
\r
1836 PutbackRMByte(ModRM,src);
\r
1837 RegByte(ModRM)=dst;
\r
1840 static void PREFIX86(_xchg_wr16)(i8086_state *cpustate) /* Opcode 0x87 */
\r
1842 DEF_wr16(dst,src);
\r
1843 ICOUNT -= (ModRM >= 0xc0) ? timing.xchg_rr16 : timing.xchg_rm16;
\r
1844 PutbackRMWord(ModRM,src);
\r
1845 RegWord(ModRM)=dst;
\r
1848 static void PREFIX86(_mov_br8)(i8086_state *cpustate) /* Opcode 0x88 */
\r
1850 unsigned ModRM = FETCH;
\r
1851 BYTE src = RegByte(ModRM);
\r
1852 ICOUNT -= (ModRM >= 0xc0) ? timing.mov_rr8 : timing.mov_mr8;
\r
1853 PutRMByte(ModRM,src);
\r
1856 static void PREFIX86(_mov_wr16)(i8086_state *cpustate) /* Opcode 0x89 */
\r
1858 unsigned ModRM = FETCH;
\r
1859 WORD src = RegWord(ModRM);
\r
1860 ICOUNT -= (ModRM >= 0xc0) ? timing.mov_rr16 : timing.mov_mr16;
\r
1861 PutRMWord(ModRM,src);
\r
1864 static void PREFIX86(_mov_r8b)(i8086_state *cpustate) /* Opcode 0x8a */
\r
1866 unsigned ModRM = FETCH;
\r
1867 BYTE src = GetRMByte(ModRM);
\r
1868 ICOUNT -= (ModRM >= 0xc0) ? timing.mov_rr8 : timing.mov_rm8;
\r
1869 RegByte(ModRM)=src;
\r
1872 static void PREFIX86(_mov_r16w)(i8086_state *cpustate) /* Opcode 0x8b */
\r
1874 unsigned ModRM = FETCH;
\r
1875 WORD src = GetRMWord(ModRM);
\r
1876 ICOUNT -= (ModRM >= 0xc0) ? timing.mov_rr8 : timing.mov_rm16;
\r
1877 RegWord(ModRM)=src;
\r
1880 static void PREFIX86(_mov_wsreg)(i8086_state *cpustate) /* Opcode 0x8c */
\r
1882 unsigned ModRM = FETCH;
\r
1883 ICOUNT -= (ModRM >= 0xc0) ? timing.mov_rs : timing.mov_ms;
\r
1884 if (ModRM & 0x20) { /* HJB 12/13/98 1xx is invalid */
\r
1885 cpustate->pc = cpustate->prevpc;
\r
1886 return PREFIX86(_invalid)(cpustate);
\r
1889 PutRMWord(ModRM,cpustate->sregs[(ModRM & 0x38) >> 3]);
\r
1892 static void PREFIX86(_lea)(i8086_state *cpustate) /* Opcode 0x8d */
\r
1894 unsigned ModRM = FETCH;
\r
1895 ICOUNT -= timing.lea;
\r
1896 (void)(*GetEA[ModRM])(cpustate);
\r
1897 RegWord(ModRM)=cpustate->eo; /* HJB 12/13/98 effective offset (no segment part) */
\r
1900 static void PREFIX86(_popw)(i8086_state *cpustate) /* Opcode 0x8f */
\r
1902 unsigned ModRM = FETCH;
\r
1904 tmp = ReadWord(cpustate->base[SS] + cpustate->regs.w[SP]);
\r
1905 ICOUNT -= (ModRM >= 0xc0) ? timing.pop_r16 : timing.pop_m16;
\r
1906 PutRMWord(ModRM,tmp);
\r
1907 cpustate->regs.w[SP] += 2;
\r
1911 #define XchgAXReg(Reg) \
\r
1914 tmp = cpustate->regs.w[Reg]; \
\r
1915 cpustate->regs.w[Reg] = cpustate->regs.w[AX]; \
\r
1916 cpustate->regs.w[AX] = tmp; \
\r
1917 ICOUNT -= timing.xchg_ar16; \
\r
1921 static void PREFIX86(_nop)(i8086_state *cpustate) /* Opcode 0x90 */
\r
1923 /* this is XchgAXReg(AX); */
\r
1924 ICOUNT -= timing.nop;
\r
1927 static void PREFIX86(_xchg_axcx)(i8086_state *cpustate) /* Opcode 0x91 */
\r
1932 static void PREFIX86(_xchg_axdx)(i8086_state *cpustate) /* Opcode 0x92 */
\r
1937 static void PREFIX86(_xchg_axbx)(i8086_state *cpustate) /* Opcode 0x93 */
\r
1942 static void PREFIX86(_xchg_axsp)(i8086_state *cpustate) /* Opcode 0x94 */
\r
1947 static void PREFIX86(_xchg_axbp)(i8086_state *cpustate) /* Opcode 0x95 */
\r
1952 static void PREFIX86(_xchg_axsi)(i8086_state *cpustate) /* Opcode 0x96 */
\r
1957 static void PREFIX86(_xchg_axdi)(i8086_state *cpustate) /* Opcode 0x97 */
\r
1962 static void PREFIX86(_cbw)(i8086_state *cpustate) /* Opcode 0x98 */
\r
1964 ICOUNT -= timing.cbw;
\r
1965 cpustate->regs.b[AH] = (cpustate->regs.b[AL] & 0x80) ? 0xff : 0;
\r
1968 static void PREFIX86(_cwd)(i8086_state *cpustate) /* Opcode 0x99 */
\r
1970 ICOUNT -= timing.cwd;
\r
1971 cpustate->regs.w[DX] = (cpustate->regs.b[AH] & 0x80) ? 0xffff : 0;
\r
1974 static void PREFIX86(_call_far)(i8086_state *cpustate)
\r
1976 unsigned int tmp, tmp2;
\r
1980 tmp += FETCH << 8;
\r
1983 tmp2 += FETCH << 8;
\r
1985 #ifdef I86_BIOS_CALL
\r
1986 if(cpustate->bios != NULL && cpustate->bios->bios_call(((tmp2 << 4) + tmp) & AMASK, cpustate->regs.w, cpustate->sregs, &cpustate->ZeroVal, &cpustate->CarryVal)) {
\r
1987 ICOUNT -= timing.call_far;
\r
1992 ip = cpustate->pc - cpustate->base[CS];
\r
1993 cs = cpustate->sregs[CS];
\r
1996 i80286_code_descriptor(cpustate, tmp2, tmp, 2);
\r
1998 cpustate->sregs[CS] = (WORD)tmp2;
\r
1999 cpustate->base[CS] = SegBase(CS);
\r
2000 cpustate->pc = (cpustate->base[CS] + (WORD)tmp) & AMASK;
\r
2004 ICOUNT -= timing.call_far;
\r
2005 CHANGE_PC(cpustate->pc);
\r
2008 static void PREFIX86(_wait)(i8086_state *cpustate) /* Opcode 0x9b */
\r
2011 if ((cpustate->msw&0x0a) == 0x0a) throw TRAP(FPU_UNAVAILABLE,-1);
\r
2013 if (cpustate->test_state)
\r
2019 ICOUNT -= timing.wait;
\r
2022 static void PREFIX86(_pushf)(i8086_state *cpustate) /* Opcode 0x9c */
\r
2025 ICOUNT -= timing.pushf;
\r
2027 tmp = CompressFlags();
\r
2029 if(!PM) ( tmp &= ~0xf000 );
\r
2035 static void PREFIX86(_popf)(i8086_state *cpustate) /* Opcode 0x9d */
\r
2039 ICOUNT -= timing.popf;
\r
2042 cpustate->flags = tmp;
\r
2043 cpustate->flags = CompressFlags();
\r
2045 if (cpustate->TF) PREFIX(_trap)(cpustate);
\r
2047 /* if the IF is set, and an interrupt is pending, signal an interrupt */
\r
2048 if (cpustate->IF && cpustate->irq_state) {
\r
2049 PREFIX(_interrupt)(cpustate, (UINT32)-1);
\r
2050 cpustate->irq_state = 0;
\r
2055 static void PREFIX86(_sahf)(i8086_state *cpustate) /* Opcode 0x9e */
\r
2057 unsigned tmp = (CompressFlags() & 0xff00) | (cpustate->regs.b[AH] & 0xd5);
\r
2058 ICOUNT -= timing.sahf;
\r
2062 static void PREFIX86(_lahf)(i8086_state *cpustate) /* Opcode 0x9f */
\r
2064 cpustate->regs.b[AH] = CompressFlags() & 0xff;
\r
2065 ICOUNT -= timing.lahf;
\r
2069 static void PREFIX86(_mov_aldisp)(i8086_state *cpustate) /* Opcode 0xa0 */
\r
2074 addr += FETCH << 8;
\r
2076 ICOUNT -= timing.mov_am8;
\r
2077 cpustate->regs.b[AL] = GetMemB(DS, addr);
\r
2080 static void PREFIX86(_mov_axdisp)(i8086_state *cpustate) /* Opcode 0xa1 */
\r
2085 addr += FETCH << 8;
\r
2087 ICOUNT -= timing.mov_am16;
\r
2088 cpustate->regs.w[AX] = GetMemW(DS, addr);
\r
2091 static void PREFIX86(_mov_dispal)(i8086_state *cpustate) /* Opcode 0xa2 */
\r
2096 addr += FETCH << 8;
\r
2098 ICOUNT -= timing.mov_ma8;
\r
2099 PutMemB(DS, addr, cpustate->regs.b[AL]);
\r
2102 static void PREFIX86(_mov_dispax)(i8086_state *cpustate) /* Opcode 0xa3 */
\r
2107 addr += FETCH << 8;
\r
2109 ICOUNT -= timing.mov_ma16;
\r
2110 PutMemW(DS, addr, cpustate->regs.w[AX]);
\r
2113 static void PREFIX86(_movsb)(i8086_state *cpustate) /* Opcode 0xa4 */
\r
2115 BYTE tmp = GetMemB(DS,cpustate->regs.w[SI]);
\r
2116 PutMemB(ES,cpustate->regs.w[DI], tmp);
\r
2117 cpustate->regs.w[DI] += cpustate->DirVal;
\r
2118 cpustate->regs.w[SI] += cpustate->DirVal;
\r
2119 ICOUNT -= timing.movs8;
\r
2122 static void PREFIX86(_movsw)(i8086_state *cpustate) /* Opcode 0xa5 */
\r
2124 WORD tmp = GetMemW(DS,cpustate->regs.w[SI]);
\r
2125 PutMemW(ES,cpustate->regs.w[DI], tmp);
\r
2126 cpustate->regs.w[DI] += 2 * cpustate->DirVal;
\r
2127 cpustate->regs.w[SI] += 2 * cpustate->DirVal;
\r
2128 ICOUNT -= timing.movs16;
\r
2131 static void PREFIX86(_cmpsb)(i8086_state *cpustate) /* Opcode 0xa6 */
\r
2133 unsigned dst = GetMemB(ES, cpustate->regs.w[DI]);
\r
2134 unsigned src = GetMemB(DS, cpustate->regs.w[SI]);
\r
2135 SUBB(src,dst); /* opposite of the usual convention */
\r
2136 cpustate->regs.w[DI] += cpustate->DirVal;
\r
2137 cpustate->regs.w[SI] += cpustate->DirVal;
\r
2138 ICOUNT -= timing.cmps8;
\r
2141 static void PREFIX86(_cmpsw)(i8086_state *cpustate) /* Opcode 0xa7 */
\r
2143 unsigned dst = GetMemW(ES, cpustate->regs.w[DI]);
\r
2144 unsigned src = GetMemW(DS, cpustate->regs.w[SI]);
\r
2145 SUBW(src,dst); /* opposite of the usual convention */
\r
2146 cpustate->regs.w[DI] += 2 * cpustate->DirVal;
\r
2147 cpustate->regs.w[SI] += 2 * cpustate->DirVal;
\r
2148 ICOUNT -= timing.cmps16;
\r
2151 static void PREFIX86(_test_ald8)(i8086_state *cpustate) /* Opcode 0xa8 */
\r
2153 DEF_ald8(dst,src);
\r
2154 ICOUNT -= timing.alu_ri8;
\r
2158 static void PREFIX86(_test_axd16)(i8086_state *cpustate) /* Opcode 0xa9 */
\r
2160 DEF_axd16(dst,src);
\r
2161 ICOUNT -= timing.alu_ri16;
\r
2165 static void PREFIX86(_stosb)(i8086_state *cpustate) /* Opcode 0xaa */
\r
2167 PutMemB(ES,cpustate->regs.w[DI],cpustate->regs.b[AL]);
\r
2168 cpustate->regs.w[DI] += cpustate->DirVal;
\r
2169 ICOUNT -= timing.stos8;
\r
2172 static void PREFIX86(_stosw)(i8086_state *cpustate) /* Opcode 0xab */
\r
2174 PutMemW(ES,cpustate->regs.w[DI],cpustate->regs.w[AX]);
\r
2175 cpustate->regs.w[DI] += 2 * cpustate->DirVal;
\r
2176 ICOUNT -= timing.stos16;
\r
2179 static void PREFIX86(_lodsb)(i8086_state *cpustate) /* Opcode 0xac */
\r
2181 cpustate->regs.b[AL] = GetMemB(DS,cpustate->regs.w[SI]);
\r
2182 cpustate->regs.w[SI] += cpustate->DirVal;
\r
2183 ICOUNT -= timing.lods8;
\r
2186 static void PREFIX86(_lodsw)(i8086_state *cpustate) /* Opcode 0xad */
\r
2188 cpustate->regs.w[AX] = GetMemW(DS,cpustate->regs.w[SI]);
\r
2189 cpustate->regs.w[SI] += 2 * cpustate->DirVal;
\r
2190 ICOUNT -= timing.lods16;
\r
2193 static void PREFIX86(_scasb)(i8086_state *cpustate) /* Opcode 0xae */
\r
2195 unsigned src = GetMemB(ES, cpustate->regs.w[DI]);
\r
2196 unsigned dst = cpustate->regs.b[AL];
\r
2198 cpustate->regs.w[DI] += cpustate->DirVal;
\r
2199 ICOUNT -= timing.scas8;
\r
2202 static void PREFIX86(_scasw)(i8086_state *cpustate) /* Opcode 0xaf */
\r
2204 unsigned src = GetMemW(ES, cpustate->regs.w[DI]);
\r
2205 unsigned dst = cpustate->regs.w[AX];
\r
2207 cpustate->regs.w[DI] += 2 * cpustate->DirVal;
\r
2208 ICOUNT -= timing.scas16;
\r
2211 static void PREFIX86(_mov_ald8)(i8086_state *cpustate) /* Opcode 0xb0 */
\r
2213 cpustate->regs.b[AL] = FETCH;
\r
2214 ICOUNT -= timing.mov_ri8;
\r
2217 static void PREFIX86(_mov_cld8)(i8086_state *cpustate) /* Opcode 0xb1 */
\r
2219 cpustate->regs.b[CL] = FETCH;
\r
2220 ICOUNT -= timing.mov_ri8;
\r
2223 static void PREFIX86(_mov_dld8)(i8086_state *cpustate) /* Opcode 0xb2 */
\r
2225 cpustate->regs.b[DL] = FETCH;
\r
2226 ICOUNT -= timing.mov_ri8;
\r
2229 static void PREFIX86(_mov_bld8)(i8086_state *cpustate) /* Opcode 0xb3 */
\r
2231 cpustate->regs.b[BL] = FETCH;
\r
2232 ICOUNT -= timing.mov_ri8;
\r
2235 static void PREFIX86(_mov_ahd8)(i8086_state *cpustate) /* Opcode 0xb4 */
\r
2237 cpustate->regs.b[AH] = FETCH;
\r
2238 ICOUNT -= timing.mov_ri8;
\r
2241 static void PREFIX86(_mov_chd8)(i8086_state *cpustate) /* Opcode 0xb5 */
\r
2243 cpustate->regs.b[CH] = FETCH;
\r
2244 ICOUNT -= timing.mov_ri8;
\r
2247 static void PREFIX86(_mov_dhd8)(i8086_state *cpustate) /* Opcode 0xb6 */
\r
2249 cpustate->regs.b[DH] = FETCH;
\r
2250 ICOUNT -= timing.mov_ri8;
\r
2253 static void PREFIX86(_mov_bhd8)(i8086_state *cpustate) /* Opcode 0xb7 */
\r
2255 cpustate->regs.b[BH] = FETCH;
\r
2256 ICOUNT -= timing.mov_ri8;
\r
2259 static void PREFIX86(_mov_axd16)(i8086_state *cpustate) /* Opcode 0xb8 */
\r
2261 cpustate->regs.b[AL] = FETCH;
\r
2262 cpustate->regs.b[AH] = FETCH;
\r
2263 ICOUNT -= timing.mov_ri16;
\r
2266 static void PREFIX86(_mov_cxd16)(i8086_state *cpustate) /* Opcode 0xb9 */
\r
2268 cpustate->regs.b[CL] = FETCH;
\r
2269 cpustate->regs.b[CH] = FETCH;
\r
2270 ICOUNT -= timing.mov_ri16;
\r
2273 static void PREFIX86(_mov_dxd16)(i8086_state *cpustate) /* Opcode 0xba */
\r
2275 cpustate->regs.b[DL] = FETCH;
\r
2276 cpustate->regs.b[DH] = FETCH;
\r
2277 ICOUNT -= timing.mov_ri16;
\r
2280 static void PREFIX86(_mov_bxd16)(i8086_state *cpustate) /* Opcode 0xbb */
\r
2282 cpustate->regs.b[BL] = FETCH;
\r
2283 cpustate->regs.b[BH] = FETCH;
\r
2284 ICOUNT -= timing.mov_ri16;
\r
2287 static void PREFIX86(_mov_spd16)(i8086_state *cpustate) /* Opcode 0xbc */
\r
2289 cpustate->regs.b[SPL] = FETCH;
\r
2290 cpustate->regs.b[SPH] = FETCH;
\r
2291 ICOUNT -= timing.mov_ri16;
\r
2294 static void PREFIX86(_mov_bpd16)(i8086_state *cpustate) /* Opcode 0xbd */
\r
2296 cpustate->regs.b[BPL] = FETCH;
\r
2297 cpustate->regs.b[BPH] = FETCH;
\r
2298 ICOUNT -= timing.mov_ri16;
\r
2301 static void PREFIX86(_mov_sid16)(i8086_state *cpustate) /* Opcode 0xbe */
\r
2303 cpustate->regs.b[SIL] = FETCH;
\r
2304 cpustate->regs.b[SIH] = FETCH;
\r
2305 ICOUNT -= timing.mov_ri16;
\r
2308 static void PREFIX86(_mov_did16)(i8086_state *cpustate) /* Opcode 0xbf */
\r
2310 cpustate->regs.b[DIL] = FETCH;
\r
2311 cpustate->regs.b[DIH] = FETCH;
\r
2312 ICOUNT -= timing.mov_ri16;
\r
2315 static void PREFIX86(_ret_d16)(i8086_state *cpustate) /* Opcode 0xc2 */
\r
2317 unsigned count = FETCH;
\r
2318 count += FETCH << 8;
\r
2319 POP(cpustate->pc);
\r
2320 cpustate->pc = (cpustate->pc + cpustate->base[CS]) & AMASK;
\r
2321 cpustate->regs.w[SP]+=count;
\r
2322 ICOUNT -= timing.ret_near_imm;
\r
2323 CHANGE_PC(cpustate->pc);
\r
2326 static void PREFIX86(_ret)(i8086_state *cpustate) /* Opcode 0xc3 */
\r
2328 POP(cpustate->pc);
\r
2329 cpustate->pc = (cpustate->pc + cpustate->base[CS]) & AMASK;
\r
2330 ICOUNT -= timing.ret_near;
\r
2331 CHANGE_PC(cpustate->pc);
\r
2334 static void PREFIX86(_les_dw)(i8086_state *cpustate) /* Opcode 0xc4 */
\r
2336 unsigned ModRM = FETCH;
\r
2337 WORD tmp = GetRMWord(ModRM);
\r
2340 i80286_data_descriptor(cpustate,ES,GetnextRMWord);
\r
2342 cpustate->sregs[ES] = GetnextRMWord;
\r
2343 cpustate->base[ES] = SegBase(ES);
\r
2345 RegWord(ModRM)= tmp;
\r
2346 ICOUNT -= timing.load_ptr;
\r
2349 static void PREFIX86(_lds_dw)(i8086_state *cpustate) /* Opcode 0xc5 */
\r
2351 unsigned ModRM = FETCH;
\r
2352 WORD tmp = GetRMWord(ModRM);
\r
2355 i80286_data_descriptor(cpustate,DS,GetnextRMWord);
\r
2357 cpustate->sregs[DS] = GetnextRMWord;
\r
2358 cpustate->base[DS] = SegBase(DS);
\r
2360 RegWord(ModRM)=tmp;
\r
2361 ICOUNT -= timing.load_ptr;
\r
2364 static void PREFIX86(_mov_bd8)(i8086_state *cpustate) /* Opcode 0xc6 */
\r
2366 unsigned ModRM = FETCH;
\r
2367 ICOUNT -= (ModRM >= 0xc0) ? timing.mov_ri8 : timing.mov_mi8;
\r
2368 PutImmRMByte(ModRM);
\r
2371 static void PREFIX86(_mov_wd16)(i8086_state *cpustate) /* Opcode 0xc7 */
\r
2373 unsigned ModRM = FETCH;
\r
2374 ICOUNT -= (ModRM >= 0xc0) ? timing.mov_ri16 : timing.mov_mi16;
\r
2375 PutImmRMWord(ModRM);
\r
2379 static void PREFIX86(_retf_d16)(i8086_state *cpustate) /* Opcode 0xca */
\r
2381 unsigned count = FETCH;
\r
2382 count += FETCH << 8;
\r
2384 POP(cpustate->pc);
\r
2385 POP(cpustate->sregs[CS]);
\r
2386 cpustate->base[CS] = SegBase(CS);
\r
2387 cpustate->pc = (cpustate->pc + cpustate->base[CS]) & AMASK;
\r
2388 cpustate->regs.w[SP]+=count;
\r
2389 ICOUNT -= timing.ret_far_imm;
\r
2390 CHANGE_PC(cpustate->pc);
\r
2393 static void PREFIX86(_retf)(i8086_state *cpustate) /* Opcode 0xcb */
\r
2395 POP(cpustate->pc);
\r
2396 POP(cpustate->sregs[CS]);
\r
2397 cpustate->base[CS] = SegBase(CS);
\r
2398 cpustate->pc = (cpustate->pc + cpustate->base[CS]) & AMASK;
\r
2399 ICOUNT -= timing.ret_far;
\r
2400 CHANGE_PC(cpustate->pc);
\r
2404 static void PREFIX86(_int3)(i8086_state *cpustate) /* Opcode 0xcc */
\r
2406 ICOUNT -= timing.int3;
\r
2407 PREFIX(_interrupt)(cpustate, 3);
\r
2410 static void PREFIX86(_int)(i8086_state *cpustate) /* Opcode 0xcd */
\r
2412 unsigned int_num = FETCH;
\r
2413 ICOUNT -= timing.int_imm;
\r
2414 #ifdef I86_BIOS_CALL
\r
2415 if(cpustate->bios != NULL && cpustate->bios->bios_int(int_num, cpustate->regs.w, cpustate->sregs, &cpustate->ZeroVal, &cpustate->CarryVal)) {
\r
2419 PREFIX(_interrupt)(cpustate, int_num);
\r
2422 static void PREFIX86(_into)(i8086_state *cpustate) /* Opcode 0xce */
\r
2425 ICOUNT -= timing.into_t;
\r
2426 PREFIX(_interrupt)(cpustate, 4);
\r
2427 } else ICOUNT -= timing.into_nt;
\r
2431 static void PREFIX86(_iret)(i8086_state *cpustate) /* Opcode 0xcf */
\r
2433 ICOUNT -= timing.iret;
\r
2434 POP(cpustate->pc);
\r
2435 POP(cpustate->sregs[CS]);
\r
2436 cpustate->base[CS] = SegBase(CS);
\r
2437 cpustate->pc = (cpustate->pc + cpustate->base[CS]) & AMASK;
\r
2438 PREFIX(_popf)(cpustate);
\r
2439 CHANGE_PC(cpustate->pc);
\r
2441 /* if the IF is set, and an interrupt is pending, signal an interrupt */
\r
2442 if (cpustate->IF && cpustate->irq_state) {
\r
2443 PREFIX(_interrupt)(cpustate, (UINT32)-1);
\r
2444 cpustate->irq_state = 0;
\r
2449 static void PREFIX86(_rotshft_b)(i8086_state *cpustate) /* Opcode 0xd0 */
\r
2451 unsigned ModRM = FETCHOP;
\r
2452 PREFIX(_rotate_shift_Byte)(cpustate,ModRM,1,GetRMByte(ModRM));
\r
2456 static void PREFIX86(_rotshft_w)(i8086_state *cpustate) /* Opcode 0xd1 */
\r
2458 unsigned ModRM = FETCHOP;
\r
2459 PREFIX(_rotate_shift_Word)(cpustate,ModRM,1,GetRMWord(ModRM));
\r
2464 static void PREFIX86(_rotshft_bcl)(i8086_state *cpustate) /* Opcode 0xd2 */
\r
2466 unsigned ModRM = FETCHOP;
\r
2467 PREFIX(_rotate_shift_Byte)(cpustate,ModRM,cpustate->regs.b[CL],GetRMByte(ModRM));
\r
2470 static void PREFIX86(_rotshft_wcl)(i8086_state *cpustate) /* Opcode 0xd3 */
\r
2472 unsigned ModRM = FETCHOP;
\r
2473 PREFIX(_rotate_shift_Word)(cpustate,ModRM,cpustate->regs.b[CL],GetRMWord(ModRM));
\r
2477 /* OB: Opcode works on NEC V-Series but not the Variants */
\r
2478 /* one could specify any byte value as operand but the NECs */
\r
2479 /* always substitute 0x0a. */
\r
2480 static void PREFIX86(_aam)(i8086_state *cpustate) /* Opcode 0xd4 */
\r
2482 unsigned mult = FETCH;
\r
2484 ICOUNT -= timing.aam;
\r
2486 PREFIX(_interrupt)(cpustate, 0);
\r
2489 cpustate->regs.b[AH] = cpustate->regs.b[AL] / mult;
\r
2490 cpustate->regs.b[AL] %= mult;
\r
2492 SetSZPF_Word(cpustate->regs.w[AX]);
\r
2496 static void PREFIX86(_aad)(i8086_state *cpustate) /* Opcode 0xd5 */
\r
2498 unsigned mult = FETCH;
\r
2500 ICOUNT -= timing.aad;
\r
2502 cpustate->regs.b[AL] = cpustate->regs.b[AH] * mult + cpustate->regs.b[AL];
\r
2503 cpustate->regs.b[AH] = 0;
\r
2505 SetZF(cpustate->regs.b[AL]);
\r
2506 SetPF(cpustate->regs.b[AL]);
\r
2507 cpustate->SignVal = 0;
\r
2511 static void PREFIX86(_xlat)(i8086_state *cpustate) /* Opcode 0xd7 */
\r
2513 unsigned dest = cpustate->regs.w[BX]+cpustate->regs.b[AL];
\r
2515 ICOUNT -= timing.xlat;
\r
2516 cpustate->regs.b[AL] = GetMemB(DS, dest);
\r
2520 static void PREFIX86(_escape)(i8086_state *cpustate) /* Opcodes 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde and 0xdf */
\r
2522 unsigned ModRM = FETCH;
\r
2523 ICOUNT -= timing.nop;
\r
2528 static void PREFIX86(_loopne)(i8086_state *cpustate) /* Opcode 0xe0 */
\r
2530 int disp = (int)((INT8)FETCH);
\r
2531 unsigned tmp = cpustate->regs.w[CX]-1;
\r
2533 cpustate->regs.w[CX]=tmp;
\r
2536 ICOUNT -= timing.loop_t;
\r
2537 cpustate->pc += disp;
\r
2538 /* ASG - can probably assume this is safe
\r
2539 CHANGE_PC(cpustate->pc);*/
\r
2540 } else ICOUNT -= timing.loop_nt;
\r
2543 static void PREFIX86(_loope)(i8086_state *cpustate) /* Opcode 0xe1 */
\r
2545 int disp = (int)((INT8)FETCH);
\r
2546 unsigned tmp = cpustate->regs.w[CX]-1;
\r
2548 cpustate->regs.w[CX]=tmp;
\r
2551 ICOUNT -= timing.loope_t;
\r
2552 cpustate->pc += disp;
\r
2553 /* ASG - can probably assume this is safe
\r
2554 CHANGE_PC(cpustate->pc);*/
\r
2555 } else ICOUNT -= timing.loope_nt;
\r
2558 static void PREFIX86(_loop)(i8086_state *cpustate) /* Opcode 0xe2 */
\r
2560 int disp = (int)((INT8)FETCH);
\r
2561 unsigned tmp = cpustate->regs.w[CX]-1;
\r
2563 cpustate->regs.w[CX]=tmp;
\r
2566 ICOUNT -= timing.loop_t;
\r
2567 cpustate->pc += disp;
\r
2568 /* ASG - can probably assume this is safe
\r
2569 CHANGE_PC(cpustate->pc);*/
\r
2570 } else ICOUNT -= timing.loop_nt;
\r
2573 static void PREFIX86(_jcxz)(i8086_state *cpustate) /* Opcode 0xe3 */
\r
2575 int disp = (int)((INT8)FETCH);
\r
2577 if (cpustate->regs.w[CX] == 0) {
\r
2578 ICOUNT -= timing.jcxz_t;
\r
2579 cpustate->pc += disp;
\r
2580 /* ASG - can probably assume this is safe
\r
2581 CHANGE_PC(cpustate->pc);*/
\r
2583 ICOUNT -= timing.jcxz_nt;
\r
2586 static void PREFIX86(_inal)(i8086_state *cpustate) /* Opcode 0xe4 */
\r
2590 if (PM && (CPL>IOPL)) throw TRAP(GENERAL_PROTECTION_FAULT, 0);
\r
2594 ICOUNT -= timing.in_imm8;
\r
2595 cpustate->regs.b[AL] = read_port_byte(port);
\r
2598 static void PREFIX86(_inax)(i8086_state *cpustate) /* Opcode 0xe5 */
\r
2602 if (PM && (CPL>IOPL)) throw TRAP(GENERAL_PROTECTION_FAULT, 0);
\r
2606 ICOUNT -= timing.in_imm16;
\r
2607 cpustate->regs.w[AX] = read_port_word(port);
\r
2610 static void PREFIX86(_outal)(i8086_state *cpustate) /* Opcode 0xe6 */
\r
2614 if (PM && (CPL>IOPL)) throw TRAP(GENERAL_PROTECTION_FAULT, 0);
\r
2618 ICOUNT -= timing.out_imm8;
\r
2619 write_port_byte(port, cpustate->regs.b[AL]);
\r
2622 static void PREFIX86(_outax)(i8086_state *cpustate) /* Opcode 0xe7 */
\r
2626 if (PM && (CPL>IOPL)) throw TRAP(GENERAL_PROTECTION_FAULT, 0);
\r
2630 ICOUNT -= timing.out_imm16;
\r
2631 write_port_word(port, cpustate->regs.w[AX]);
\r
2634 static void PREFIX86(_call_d16)(i8086_state *cpustate) /* Opcode 0xe8 */
\r
2639 #ifdef I86_BIOS_CALL
\r
2640 if(cpustate->bios != NULL && cpustate->bios->bios_call((cpustate->pc + tmp) & AMASK, cpustate->regs.w, cpustate->sregs, &cpustate->ZeroVal, &cpustate->CarryVal)) {
\r
2641 ICOUNT -= timing.call_near;
\r
2645 ip = cpustate->pc - cpustate->base[CS];
\r
2648 cpustate->pc = (ip + cpustate->base[CS]) & AMASK;
\r
2649 ICOUNT -= timing.call_near;
\r
2650 CHANGE_PC(cpustate->pc);
\r
2653 static void PREFIX86(_jmp_d16)(i8086_state *cpustate) /* Opcode 0xe9 */
\r
2658 ip = cpustate->pc - cpustate->base[CS] + tmp;
\r
2659 cpustate->pc = (ip + cpustate->base[CS]) & AMASK;
\r
2660 ICOUNT -= timing.jmp_near;
\r
2661 CHANGE_PC(cpustate->pc);
\r
2664 static void PREFIX86(_jmp_far)(i8086_state *cpustate) /* Opcode 0xea */
\r
2666 unsigned tmp,tmp1;
\r
2669 tmp += FETCH << 8;
\r
2672 tmp1 += FETCH << 8;
\r
2675 i80286_code_descriptor(cpustate, tmp1,tmp, 1);
\r
2677 cpustate->sregs[CS] = (WORD)tmp1;
\r
2678 cpustate->base[CS] = SegBase(CS);
\r
2679 cpustate->pc = (cpustate->base[CS] + tmp) & AMASK;
\r
2681 ICOUNT -= timing.jmp_far;
\r
2682 CHANGE_PC(cpustate->pc);
\r
2685 static void PREFIX86(_jmp_d8)(i8086_state *cpustate) /* Opcode 0xeb */
\r
2687 int tmp = (int)((INT8)FETCH);
\r
2688 cpustate->pc += tmp;
\r
2689 /* ASG - can probably assume this is safe
\r
2690 CHANGE_PC(cpustate->pc);*/
\r
2691 ICOUNT -= timing.jmp_short;
\r
2694 static void PREFIX86(_inaldx)(i8086_state *cpustate) /* Opcode 0xec */
\r
2697 if (PM && (CPL>IOPL)) throw TRAP(GENERAL_PROTECTION_FAULT, 0);
\r
2699 ICOUNT -= timing.in_dx8;
\r
2700 cpustate->regs.b[AL] = read_port_byte(cpustate->regs.w[DX]);
\r
2703 static void PREFIX86(_inaxdx)(i8086_state *cpustate) /* Opcode 0xed */
\r
2705 unsigned port = cpustate->regs.w[DX];
\r
2707 if (PM && (CPL>IOPL)) throw TRAP(GENERAL_PROTECTION_FAULT, 0);
\r
2709 ICOUNT -= timing.in_dx16;
\r
2710 cpustate->regs.w[AX] = read_port_word(port);
\r
2713 static void PREFIX86(_outdxal)(i8086_state *cpustate) /* Opcode 0xee */
\r
2716 if (PM && (CPL>IOPL)) throw TRAP(GENERAL_PROTECTION_FAULT, 0);
\r
2718 ICOUNT -= timing.out_dx8;
\r
2719 write_port_byte(cpustate->regs.w[DX], cpustate->regs.b[AL]);
\r
2722 static void PREFIX86(_outdxax)(i8086_state *cpustate) /* Opcode 0xef */
\r
2724 unsigned port = cpustate->regs.w[DX];
\r
2726 if (PM && (CPL>IOPL)) throw TRAP(GENERAL_PROTECTION_FAULT, 0);
\r
2728 ICOUNT -= timing.out_dx16;
\r
2729 write_port_word(port, cpustate->regs.w[AX]);
\r
2732 /* I think thats not a V20 instruction...*/
\r
2733 static void PREFIX86(_lock)(i8086_state *cpustate) /* Opcode 0xf0 */
\r
2736 if(PM && (CPL>IOPL)) throw TRAP(GENERAL_PROTECTION_FAULT,0);
\r
2738 ICOUNT -= timing.nop;
\r
2739 PREFIX(_instruction)[FETCHOP](cpustate); /* un-interruptible */
\r
2743 static void PREFIX(_pop_ss)(i8086_state *cpustate) /* Opcode 0x17 */
\r
2746 i80286_pop_seg(cpustate, SS);
\r
2748 POP(cpustate->sregs[SS]);
\r
2749 cpustate->base[SS] = SegBase(SS);
\r
2751 ICOUNT -= timing.pop_seg;
\r
2752 PREFIX(_instruction)[FETCHOP](cpustate); /* no interrupt before next instruction */
\r
2755 static void PREFIX(_es)(i8086_state *cpustate) /* Opcode 0x26 */
\r
2757 cpustate->seg_prefix = TRUE;
\r
2758 cpustate->prefix_seg = ES;
\r
2759 ICOUNT -= timing.override;
\r
2760 PREFIX(_instruction)[FETCHOP](cpustate);
\r
2763 static void PREFIX(_cs)(i8086_state *cpustate) /* Opcode 0x2e */
\r
2765 cpustate->seg_prefix = TRUE;
\r
2766 cpustate->prefix_seg = CS;
\r
2767 ICOUNT -= timing.override;
\r
2768 PREFIX(_instruction)[FETCHOP](cpustate);
\r
2771 static void PREFIX(_ss)(i8086_state *cpustate) /* Opcode 0x36 */
\r
2773 cpustate->seg_prefix = TRUE;
\r
2774 cpustate->prefix_seg = SS;
\r
2775 ICOUNT -= timing.override;
\r
2776 PREFIX(_instruction)[FETCHOP](cpustate);
\r
2779 static void PREFIX(_ds)(i8086_state *cpustate) /* Opcode 0x3e */
\r
2781 cpustate->seg_prefix = TRUE;
\r
2782 cpustate->prefix_seg = DS;
\r
2783 ICOUNT -= timing.override;
\r
2784 PREFIX(_instruction)[FETCHOP](cpustate);
\r
2787 static void PREFIX(_mov_sregw)(i8086_state *cpustate) /* Opcode 0x8e */
\r
2789 unsigned ModRM = FETCH;
\r
2790 WORD src = GetRMWord(ModRM);
\r
2792 ICOUNT -= (ModRM >= 0xc0) ? timing.mov_sr : timing.mov_sm;
\r
2794 switch (ModRM & 0x38)
\r
2796 case 0x00: /* mov es,ew */
\r
2797 i80286_data_descriptor(cpustate,ES,src);
\r
2799 case 0x18: /* mov ds,ew */
\r
2800 i80286_data_descriptor(cpustate,DS,src);
\r
2802 case 0x10: /* mov ss,ew */
\r
2803 i80286_data_descriptor(cpustate,SS,src);
\r
2804 cpustate->seg_prefix = FALSE;
\r
2805 PREFIX(_instruction)[FETCHOP](cpustate);
\r
2807 case 0x08: /* mov cs,ew */
\r
2808 PREFIX(_invalid)(cpustate);
\r
2809 break; /* doesn't do a jump far */
\r
2812 switch (ModRM & 0x38)
\r
2814 case 0x00: /* mov es,ew */
\r
2815 cpustate->sregs[ES] = src;
\r
2816 cpustate->base[ES] = SegBase(ES);
\r
2818 case 0x18: /* mov ds,ew */
\r
2819 cpustate->sregs[DS] = src;
\r
2820 cpustate->base[DS] = SegBase(DS);
\r
2822 case 0x10: /* mov ss,ew */
\r
2823 cpustate->sregs[SS] = src;
\r
2824 cpustate->base[SS] = SegBase(SS); /* no interrupt allowed before next instr */
\r
2825 cpustate->seg_prefix = FALSE;
\r
2826 PREFIX(_instruction)[FETCHOP](cpustate);
\r
2828 case 0x08: /* mov cs,ew */
\r
2830 int ip = cpustate->pc - cpustate->base[CS];
\r
2831 cpustate->sregs[CS] = src;
\r
2832 cpustate->base[CS] = SegBase(CS);
\r
2833 cpustate->pc = (ip + cpustate->base[CS]) & AMASK;
\r
2834 CHANGE_PC(cpustate->pc);
\r
2841 static void PREFIX(_repne)(i8086_state *cpustate) /* Opcode 0xf2 */
\r
2843 PREFIX(rep)(cpustate, 0);
\r
2846 static void PREFIX(_repe)(i8086_state *cpustate) /* Opcode 0xf3 */
\r
2848 PREFIX(rep)(cpustate, 1);
\r
2851 static void PREFIX(_sti)(i8086_state *cpustate) /* Opcode 0xfb */
\r
2854 if(PM && (CPL>IOPL)) throw TRAP(GENERAL_PROTECTION_FAULT,0);
\r
2856 ICOUNT -= timing.flag_ops;
\r
2858 PREFIX(_instruction)[FETCHOP](cpustate); /* no interrupt before next instruction */
\r
2860 /* if an interrupt is pending, signal an interrupt */
\r
2861 if (cpustate->irq_state) {
\r
2863 i80286_interrupt_descriptor(cpustate, cpustate->pic->intr_ack(), 2, -1);
\r
2865 PREFIX86(_interrupt)(cpustate, (UINT32)-1);
\r
2867 cpustate->irq_state = 0;
\r
2872 static void PREFIX86(_hlt)(i8086_state *cpustate) /* Opcode 0xf4 */
\r
2875 if(PM && (CPL!=0)) throw TRAP(GENERAL_PROTECTION_FAULT,0);
\r
2877 cpustate->halted=1;
\r
2881 static void PREFIX86(_cmc)(i8086_state *cpustate) /* Opcode 0xf5 */
\r
2883 ICOUNT -= timing.flag_ops;
\r
2884 cpustate->CarryVal = !CF;
\r
2887 static void PREFIX86(_f6pre)(i8086_state *cpustate)
\r
2890 unsigned ModRM = FETCH;
\r
2891 unsigned tmp = (unsigned)GetRMByte(ModRM);
\r
2895 switch (ModRM & 0x38)
\r
2897 case 0x00: /* TEST Eb, data8 */
\r
2898 case 0x08: /* ??? */
\r
2899 ICOUNT -= (ModRM >= 0xc0) ? timing.alu_ri8 : timing.alu_mi8_ro;
\r
2902 cpustate->CarryVal = cpustate->OverVal = cpustate->AuxVal = 0;
\r
2903 SetSZPF_Byte(tmp);
\r
2906 case 0x10: /* NOT Eb */
\r
2907 ICOUNT -= (ModRM >= 0xc0) ? timing.negnot_r8 : timing.negnot_m8;
\r
2908 PutbackRMByte(ModRM,~tmp);
\r
2911 case 0x18: /* NEG Eb */
\r
2912 ICOUNT -= (ModRM >= 0xc0) ? timing.negnot_r8 : timing.negnot_m8;
\r
2915 PutbackRMByte(ModRM,tmp2);
\r
2917 case 0x20: /* MUL AL, Eb */
\r
2918 ICOUNT -= (ModRM >= 0xc0) ? timing.mul_r8 : timing.mul_m8;
\r
2921 tmp2 = cpustate->regs.b[AL];
\r
2923 SetSF((INT8)tmp2);
\r
2926 result = (UINT16)tmp2*tmp;
\r
2927 cpustate->regs.w[AX]=(WORD)result;
\r
2929 SetZF(cpustate->regs.w[AX]);
\r
2930 cpustate->CarryVal = cpustate->OverVal = (cpustate->regs.b[AH] != 0);
\r
2933 case 0x28: /* IMUL AL, Eb */
\r
2934 ICOUNT -= (ModRM >= 0xc0) ? timing.imul_r8 : timing.imul_m8;
\r
2938 tmp2 = (unsigned)cpustate->regs.b[AL];
\r
2940 SetSF((INT8)tmp2);
\r
2943 result = (INT16)((INT8)tmp2)*(INT16)((INT8)tmp);
\r
2944 cpustate->regs.w[AX]=(WORD)result;
\r
2946 SetZF(cpustate->regs.w[AX]);
\r
2948 cpustate->CarryVal = cpustate->OverVal = (result >> 7 != 0) && (result >> 7 != -1);
\r
2951 case 0x30: /* DIV AL, Ew */
\r
2952 ICOUNT -= (ModRM >= 0xc0) ? timing.div_r8 : timing.div_m8;
\r
2956 result = cpustate->regs.w[AX];
\r
2960 if ((result / tmp) > 0xff)
\r
2962 PREFIX(_interrupt)(cpustate, 0);
\r
2967 cpustate->regs.b[AH] = result % tmp;
\r
2968 cpustate->regs.b[AL] = result / tmp;
\r
2973 PREFIX(_interrupt)(cpustate, 0);
\r
2978 case 0x38: /* IDIV AL, Ew */
\r
2979 ICOUNT -= (ModRM >= 0xc0) ? timing.idiv_r8 : timing.idiv_m8;
\r
2984 result = cpustate->regs.w[AX];
\r
2988 tmp2 = result % (INT16)((INT8)tmp);
\r
2990 if ((result /= (INT16)((INT8)tmp)) > 0xff)
\r
2992 PREFIX(_interrupt)(cpustate, 0);
\r
2997 cpustate->regs.b[AL] = result;
\r
2998 cpustate->regs.b[AH] = tmp2;
\r
3003 PREFIX(_interrupt)(cpustate, 0);
\r
3012 static void PREFIX86(_f7pre)(i8086_state *cpustate)
\r
3015 unsigned ModRM = FETCH;
\r
3016 unsigned tmp = GetRMWord(ModRM);
\r
3020 switch (ModRM & 0x38)
\r
3022 case 0x00: /* TEST Ew, data16 */
\r
3023 case 0x08: /* ??? */
\r
3024 ICOUNT -= (ModRM >= 0xc0) ? timing.alu_ri16 : timing.alu_mi16_ro;
\r
3026 tmp2 += FETCH << 8;
\r
3030 cpustate->CarryVal = cpustate->OverVal = cpustate->AuxVal = 0;
\r
3031 SetSZPF_Word(tmp);
\r
3034 case 0x10: /* NOT Ew */
\r
3035 ICOUNT -= (ModRM >= 0xc0) ? timing.negnot_r16 : timing.negnot_m16;
\r
3037 PutbackRMWord(ModRM,tmp);
\r
3040 case 0x18: /* NEG Ew */
\r
3041 ICOUNT -= (ModRM >= 0xc0) ? timing.negnot_r16 : timing.negnot_m16;
\r
3044 PutbackRMWord(ModRM,tmp2);
\r
3046 case 0x20: /* MUL AX, Ew */
\r
3047 ICOUNT -= (ModRM >= 0xc0) ? timing.mul_r16 : timing.mul_m16;
\r
3050 tmp2 = cpustate->regs.w[AX];
\r
3052 SetSF((INT16)tmp2);
\r
3055 result = (UINT32)tmp2*tmp;
\r
3056 cpustate->regs.w[AX]=(WORD)result;
\r
3058 cpustate->regs.w[DX]=result;
\r
3060 SetZF(cpustate->regs.w[AX] | cpustate->regs.w[DX]);
\r
3061 cpustate->CarryVal = cpustate->OverVal = (cpustate->regs.w[DX] != 0);
\r
3065 case 0x28: /* IMUL AX, Ew */
\r
3066 ICOUNT -= (ModRM >= 0xc0) ? timing.imul_r16 : timing.imul_m16;
\r
3070 tmp2 = cpustate->regs.w[AX];
\r
3072 SetSF((INT16)tmp2);
\r
3075 result = (INT32)((INT16)tmp2)*(INT32)((INT16)tmp);
\r
3076 cpustate->CarryVal = cpustate->OverVal = (result >> 15 != 0) && (result >> 15 != -1);
\r
3078 cpustate->regs.w[AX]=(WORD)result;
\r
3079 result = (WORD)(result >> 16);
\r
3080 cpustate->regs.w[DX]=result;
\r
3082 SetZF(cpustate->regs.w[AX] | cpustate->regs.w[DX]);
\r
3085 case 0x30: /* DIV AX, Ew */
\r
3086 ICOUNT -= (ModRM >= 0xc0) ? timing.div_r16 : timing.div_m16;
\r
3090 result = (cpustate->regs.w[DX] << 16) + cpustate->regs.w[AX];
\r
3094 tmp2 = result % tmp;
\r
3095 if ((result / tmp) > 0xffff)
\r
3097 PREFIX(_interrupt)(cpustate, 0);
\r
3102 cpustate->regs.w[DX]=tmp2;
\r
3104 cpustate->regs.w[AX]=result;
\r
3109 PREFIX(_interrupt)(cpustate, 0);
\r
3114 case 0x38: /* IDIV AX, Ew */
\r
3115 ICOUNT -= (ModRM >= 0xc0) ? timing.idiv_r16 : timing.idiv_m16;
\r
3119 result = (cpustate->regs.w[DX] << 16) + cpustate->regs.w[AX];
\r
3123 tmp2 = result % (INT32)((INT16)tmp);
\r
3124 if ((result /= (INT32)((INT16)tmp)) > 0xffff)
\r
3126 PREFIX(_interrupt)(cpustate, 0);
\r
3131 cpustate->regs.w[AX]=result;
\r
3132 cpustate->regs.w[DX]=tmp2;
\r
3137 PREFIX(_interrupt)(cpustate, 0);
\r
3146 static void PREFIX86(_clc)(i8086_state *cpustate) /* Opcode 0xf8 */
\r
3148 ICOUNT -= timing.flag_ops;
\r
3149 cpustate->CarryVal = 0;
\r
3152 static void PREFIX86(_stc)(i8086_state *cpustate) /* Opcode 0xf9 */
\r
3154 ICOUNT -= timing.flag_ops;
\r
3155 cpustate->CarryVal = 1;
\r
3158 static void PREFIX86(_cli)(i8086_state *cpustate) /* Opcode 0xfa */
\r
3161 if(PM && (CPL>IOPL)) throw TRAP(GENERAL_PROTECTION_FAULT,0);
\r
3163 ICOUNT -= timing.flag_ops;
\r
3167 static void PREFIX86(_cld)(i8086_state *cpustate) /* Opcode 0xfc */
\r
3169 ICOUNT -= timing.flag_ops;
\r
3173 static void PREFIX86(_std)(i8086_state *cpustate) /* Opcode 0xfd */
\r
3175 ICOUNT -= timing.flag_ops;
\r
3179 static void PREFIX86(_fepre)(i8086_state *cpustate) /* Opcode 0xfe */
\r
3181 unsigned ModRM = FETCH;
\r
3182 unsigned tmp = GetRMByte(ModRM);
\r
3185 ICOUNT -= (ModRM >= 0xc0) ? timing.incdec_r8 : timing.incdec_m8;
\r
3186 if ((ModRM & 0x38) == 0) /* INC eb */
\r
3189 SetOFB_Add(tmp1,tmp,1);
\r
3194 SetOFB_Sub(tmp1,1,tmp);
\r
3197 SetAF(tmp1,tmp,1);
\r
3198 SetSZPF_Byte(tmp1);
\r
3200 PutbackRMByte(ModRM,(BYTE)tmp1);
\r
3204 static void PREFIX86(_ffpre)(i8086_state *cpustate) /* Opcode 0xff */
\r
3206 unsigned ModRM = FETCHOP;
\r
3208 unsigned tmp1, tmp2;
\r
3211 switch(ModRM & 0x38)
\r
3213 case 0x00: /* INC ew */
\r
3214 ICOUNT -= (ModRM >= 0xc0) ? timing.incdec_r16 : timing.incdec_m16;
\r
3215 tmp = GetRMWord(ModRM);
\r
3218 SetOFW_Add(tmp1,tmp,1);
\r
3219 SetAF(tmp1,tmp,1);
\r
3220 SetSZPF_Word(tmp1);
\r
3222 PutbackRMWord(ModRM,(WORD)tmp1);
\r
3225 case 0x08: /* DEC ew */
\r
3226 ICOUNT -= (ModRM >= 0xc0) ? timing.incdec_r16 : timing.incdec_m16;
\r
3227 tmp = GetRMWord(ModRM);
\r
3230 SetOFW_Sub(tmp1,1,tmp);
\r
3231 SetAF(tmp1,tmp,1);
\r
3232 SetSZPF_Word(tmp1);
\r
3234 PutbackRMWord(ModRM,(WORD)tmp1);
\r
3237 case 0x10: /* CALL ew */
\r
3238 ICOUNT -= (ModRM >= 0xc0) ? timing.call_r16 : timing.call_m16;
\r
3239 tmp = GetRMWord(ModRM);
\r
3240 #ifdef I86_BIOS_CALL
\r
3241 if(cpustate->bios != NULL && cpustate->bios->bios_call((cpustate->base[CS] + (WORD)tmp) & AMASK, cpustate->regs.w, cpustate->sregs, &cpustate->ZeroVal, &cpustate->CarryVal)) {
\r
3242 ICOUNT -= timing.call_far;
\r
3246 ip = cpustate->pc - cpustate->base[CS];
\r
3248 cpustate->pc = (cpustate->base[CS] + (WORD)tmp) & AMASK;
\r
3249 CHANGE_PC(cpustate->pc);
\r
3252 case 0x18: /* CALL FAR ea */
\r
3253 ICOUNT -= timing.call_m32;
\r
3254 tmp = cpustate->sregs[CS]; /* HJB 12/13/98 need to skip displacements of cpustate->ea */
\r
3255 tmp1 = GetRMWord(ModRM);
\r
3256 tmp2 = GetnextRMWord;
\r
3257 #ifdef I86_BIOS_CALL
\r
3258 if(cpustate->bios != NULL && cpustate->bios->bios_call(((tmp2 << 4) + tmp1) & AMASK, cpustate->regs.w, cpustate->sregs, &cpustate->ZeroVal, &cpustate->CarryVal)) {
\r
3262 ip = cpustate->pc - cpustate->base[CS];
\r
3264 i80286_code_descriptor(cpustate, tmp2, tmp1, 2);
\r
3266 cpustate->sregs[CS] = tmp2;
\r
3267 cpustate->base[CS] = SegBase(CS);
\r
3268 cpustate->pc = (cpustate->base[CS] + tmp1) & AMASK;
\r
3272 CHANGE_PC(cpustate->pc);
\r
3275 case 0x20: /* JMP ea */
\r
3276 ICOUNT -= (ModRM >= 0xc0) ? timing.jmp_r16 : timing.jmp_m16;
\r
3277 ip = GetRMWord(ModRM);
\r
3278 cpustate->pc = (cpustate->base[CS] + ip) & AMASK;
\r
3279 CHANGE_PC(cpustate->pc);
\r
3282 case 0x28: /* JMP FAR ea */
\r
3283 ICOUNT -= timing.jmp_m32;
\r
3286 tmp = GetRMWord(ModRM);
\r
3287 i80286_code_descriptor(cpustate, GetnextRMWord, tmp, 1);
\r
3289 cpustate->pc = GetRMWord(ModRM);
\r
3290 cpustate->sregs[CS] = GetnextRMWord;
\r
3291 cpustate->base[CS] = SegBase(CS);
\r
3292 cpustate->pc = (cpustate->pc + cpustate->base[CS]) & AMASK;
\r
3294 CHANGE_PC(cpustate->pc);
\r
3297 case 0x30: /* PUSH ea */
\r
3298 ICOUNT -= (ModRM >= 0xc0) ? timing.push_r16 : timing.push_m16;
\r
3299 tmp = GetRMWord(ModRM);
\r
3303 tmp = GetRMWord(ModRM); // 286 doesn't matter but 8086?
\r
3304 return PREFIX(_invalid)(cpustate);
\r
3309 static void PREFIX86(_invalid)(i8086_state *cpustate)
\r
3311 logerror("illegal instruction %.2x at %.5x\n",PEEKBYTE(cpustate->pc-1), cpustate->pc);
\r
3313 throw TRAP(ILLEGAL_INSTRUCTION,-1);
\r
3315 /* i8086/i8088 ignore an invalid opcode. */
\r
3316 /* i80186/i80188 probably also ignore an invalid opcode. */
\r
3322 static void PREFIX86(_invalid_2b)(i8086_state *cpustate)
\r
3324 unsigned ModRM = FETCH;
\r
3326 logerror("illegal 2 byte instruction %.2x at %.5x\n",PEEKBYTE(cpustate->pc-2), cpustate->pc-2);
\r