comparison 68kinst.c @ 630:47123183c336

Improve support for disassembling 68010+ binaries
author Michael Pavone <pavone@retrodev.com>
date Wed, 08 Oct 2014 22:18:34 -0700
parents 775802dab98f
children 4a6ec64acd79
comparison
equal deleted inserted replaced
629:9089951a1994 630:47123183c336
170 decoded->src.params.regs.pri = m68k_reg_quick_field(*istream); 170 decoded->src.params.regs.pri = m68k_reg_quick_field(*istream);
171 decoded->extra.size = OPSIZE_BYTE; 171 decoded->extra.size = OPSIZE_BYTE;
172 istream = m68k_decode_op(istream, decoded->extra.size, &(decoded->dst)); 172 istream = m68k_decode_op(istream, decoded->extra.size, &(decoded->dst));
173 if (!istream) { 173 if (!istream) {
174 decoded->op = M68K_INVALID; 174 decoded->op = M68K_INVALID;
175 return start+1; 175 break;
176 } 176 }
177 if (decoded->dst.addr_mode == MODE_REG) { 177 if (decoded->dst.addr_mode == MODE_REG) {
178 decoded->extra.size = OPSIZE_LONG; 178 decoded->extra.size = OPSIZE_LONG;
179 } 179 }
180 } else if ((*istream & 0xF00) == 0x800) { 180 } else if ((*istream & 0xF00) == 0x800) {
200 decoded->src.params.immed = *(++istream) & 0xFF; 200 decoded->src.params.immed = *(++istream) & 0xFF;
201 decoded->extra.size = OPSIZE_BYTE; 201 decoded->extra.size = OPSIZE_BYTE;
202 istream = m68k_decode_op_ex(istream, opmode, reg, decoded->extra.size, &(decoded->dst)); 202 istream = m68k_decode_op_ex(istream, opmode, reg, decoded->extra.size, &(decoded->dst));
203 if (!istream) { 203 if (!istream) {
204 decoded->op = M68K_INVALID; 204 decoded->op = M68K_INVALID;
205 return start+1; 205 break;
206 } 206 }
207 if (decoded->dst.addr_mode == MODE_REG) { 207 if (decoded->dst.addr_mode == MODE_REG) {
208 decoded->extra.size = OPSIZE_LONG; 208 decoded->extra.size = OPSIZE_LONG;
209 } 209 }
210 } else if ((*istream & 0xC0) == 0xC0) { 210 } else if ((*istream & 0xC0) == 0xC0) {
246 break; 246 break;
247 } 247 }
248 istream = m68k_decode_op_ex(istream, opmode, reg, size, &(decoded->dst)); 248 istream = m68k_decode_op_ex(istream, opmode, reg, size, &(decoded->dst));
249 if (!istream) { 249 if (!istream) {
250 decoded->op = M68K_INVALID; 250 decoded->op = M68K_INVALID;
251 return start+1; 251 break;
252 } 252 }
253 } 253 }
254 break; 254 break;
255 case 1: 255 case 1:
256 //ANDI, ANDI to CCR, ANDI to SR 256 //ANDI, ANDI to CCR, ANDI to SR
285 break; 285 break;
286 } 286 }
287 istream = m68k_decode_op_ex(istream, opmode, reg, size, &(decoded->dst)); 287 istream = m68k_decode_op_ex(istream, opmode, reg, size, &(decoded->dst));
288 if (!istream) { 288 if (!istream) {
289 decoded->op = M68K_INVALID; 289 decoded->op = M68K_INVALID;
290 return start+1; 290 break;
291 } 291 }
292 } 292 }
293 break; 293 break;
294 case 2: 294 case 2:
295 decoded->op = M68K_SUB; 295 decoded->op = M68K_SUB;
312 break; 312 break;
313 } 313 }
314 istream = m68k_decode_op_ex(istream, opmode, reg, size, &(decoded->dst)); 314 istream = m68k_decode_op_ex(istream, opmode, reg, size, &(decoded->dst));
315 if (!istream) { 315 if (!istream) {
316 decoded->op = M68K_INVALID; 316 decoded->op = M68K_INVALID;
317 return start+1; 317 break;
318 } 318 }
319 break; 319 break;
320 case 3: 320 case 3:
321 decoded->op = M68K_ADD; 321 decoded->op = M68K_ADD;
322 decoded->variant = VAR_IMMEDIATE; 322 decoded->variant = VAR_IMMEDIATE;
338 break; 338 break;
339 } 339 }
340 istream = m68k_decode_op_ex(istream, opmode, reg, size, &(decoded->dst)); 340 istream = m68k_decode_op_ex(istream, opmode, reg, size, &(decoded->dst));
341 if (!istream) { 341 if (!istream) {
342 decoded->op = M68K_INVALID; 342 decoded->op = M68K_INVALID;
343 return start+1; 343 break;
344 } 344 }
345 break; 345 break;
346 case 4: 346 case 4:
347 //BTST, BCHG, BCLR, BSET 347 //BTST, BCHG, BCLR, BSET
348 switch ((*istream >> 6) & 0x3) 348 switch ((*istream >> 6) & 0x3)
363 decoded->src.addr_mode = MODE_IMMEDIATE; 363 decoded->src.addr_mode = MODE_IMMEDIATE;
364 decoded->src.params.immed = *(++istream) & 0xFF; 364 decoded->src.params.immed = *(++istream) & 0xFF;
365 istream = m68k_decode_op(istream, OPSIZE_BYTE, &(decoded->dst)); 365 istream = m68k_decode_op(istream, OPSIZE_BYTE, &(decoded->dst));
366 if (!istream) { 366 if (!istream) {
367 decoded->op = M68K_INVALID; 367 decoded->op = M68K_INVALID;
368 return start+1; 368 break;
369 } 369 }
370 break; 370 break;
371 case 5: 371 case 5:
372 //EORI, EORI to CCR, EORI to SR 372 //EORI, EORI to CCR, EORI to SR
373 if ((*istream & 0xFF) == 0x3C) { 373 if ((*istream & 0xFF) == 0x3C) {
401 break; 401 break;
402 } 402 }
403 istream = m68k_decode_op_ex(istream, opmode, reg, size, &(decoded->dst)); 403 istream = m68k_decode_op_ex(istream, opmode, reg, size, &(decoded->dst));
404 if (!istream) { 404 if (!istream) {
405 decoded->op = M68K_INVALID; 405 decoded->op = M68K_INVALID;
406 return start+1; 406 break;
407 } 407 }
408 } 408 }
409 break; 409 break;
410 case 6: 410 case 6:
411 decoded->op = M68K_CMP; 411 decoded->op = M68K_CMP;
425 case OPSIZE_LONG: 425 case OPSIZE_LONG:
426 immed = *(++istream); 426 immed = *(++istream);
427 decoded->src.params.immed = (immed << 16) | *(++istream); 427 decoded->src.params.immed = (immed << 16) | *(++istream);
428 break; 428 break;
429 } 429 }
430 istream = m68k_decode_op_ex(istream, opmode, reg, size, &(decoded->dst)); 430 istream = m68k_decode_op_ex(istream, opmode, reg, decoded->extra.size, &(decoded->dst));
431 if (!istream) { 431 if (!istream) {
432 decoded->op = M68K_INVALID; 432 decoded->op = M68K_INVALID;
433 return start+1; 433 break;
434 } 434 }
435 break; 435 break;
436 case 7: 436 case 7:
437 437 #ifdef M68010
438 438 decoded->op = M68K_MOVES;
439 decoded->extra.size = *istream >> 6 & 0x3;
440 immed = *(++istream);
441 reg = immed >> 12 & 0x7;
442 opmode = immed & 0x8000 ? MODE_AREG : MODE_REG;
443 if (immed & 0x800) {
444 m68k_decode_op_ex(istream, *start >> 3 & 0x7, *start & 0x7, decoded->extra.size, &(decoded->src));
445 decoded->dst.addr_mode = opmode;
446 decoded->dst.params.regs.pri = reg;
447 } else {
448 decoded->src.addr_mode = opmode;
449 decoded->src.params.regs.pri = reg;
450 m68k_decode_op_ex(istream, *start >> 3 & 0x7, *start & 0x7, decoded->extra.size, &(decoded->dst));
451 }
452 #endif
439 break; 453 break;
440 } 454 }
441 } 455 }
442 break; 456 break;
443 case MOVE_BYTE: 457 case MOVE_BYTE:
448 opmode = (*istream >> 6) & 0x7; 462 opmode = (*istream >> 6) & 0x7;
449 reg = m68k_reg_quick_field(*istream); 463 reg = m68k_reg_quick_field(*istream);
450 istream = m68k_decode_op(istream, decoded->extra.size, &(decoded->src)); 464 istream = m68k_decode_op(istream, decoded->extra.size, &(decoded->src));
451 if (!istream) { 465 if (!istream) {
452 decoded->op = M68K_INVALID; 466 decoded->op = M68K_INVALID;
453 return start+1; 467 break;
454 } 468 }
455 istream = m68k_decode_op_ex(istream, opmode, reg, decoded->extra.size, &(decoded->dst)); 469 istream = m68k_decode_op_ex(istream, opmode, reg, decoded->extra.size, &(decoded->dst));
456 if (!istream || decoded->dst.addr_mode == MODE_IMMEDIATE) { 470 if (!istream || decoded->dst.addr_mode == MODE_IMMEDIATE) {
457 decoded->op = M68K_INVALID; 471 decoded->op = M68K_INVALID;
458 return start+1; 472 break;
459 } 473 }
460 break; 474 break;
461 case MISC: 475 case MISC:
462 476
463 if ((*istream & 0x1C0) == 0x1C0) { 477 if ((*istream & 0x1C0) == 0x1C0) {
466 decoded->dst.addr_mode = MODE_AREG; 480 decoded->dst.addr_mode = MODE_AREG;
467 decoded->dst.params.regs.pri = m68k_reg_quick_field(*istream); 481 decoded->dst.params.regs.pri = m68k_reg_quick_field(*istream);
468 istream = m68k_decode_op(istream, decoded->extra.size, &(decoded->src)); 482 istream = m68k_decode_op(istream, decoded->extra.size, &(decoded->src));
469 if (!istream) { 483 if (!istream) {
470 decoded->op = M68K_INVALID; 484 decoded->op = M68K_INVALID;
471 return start+1; 485 break;
472 } 486 }
473 } else { 487 } else {
474 if (*istream & 0x100) { 488 if (*istream & 0x100) {
475 decoded->op = M68K_CHK; 489 decoded->op = M68K_CHK;
476 if ((*istream & 0x180) == 0x180) { 490 if ((*istream & 0x180) == 0x180) {
487 decoded->dst.addr_mode = MODE_REG; 501 decoded->dst.addr_mode = MODE_REG;
488 decoded->dst.params.regs.pri = m68k_reg_quick_field(*istream); 502 decoded->dst.params.regs.pri = m68k_reg_quick_field(*istream);
489 istream = m68k_decode_op(istream, decoded->extra.size, &(decoded->src)); 503 istream = m68k_decode_op(istream, decoded->extra.size, &(decoded->src));
490 if (!istream) { 504 if (!istream) {
491 decoded->op = M68K_INVALID; 505 decoded->op = M68K_INVALID;
492 return start+1; 506 break;
493 } 507 }
494 } else { 508 } else {
495 opmode = (*istream >> 3) & 0x7; 509 opmode = (*istream >> 3) & 0x7;
496 if ((*istream & 0xB80) == 0x880 && opmode != MODE_REG && opmode != MODE_AREG) { 510 if ((*istream & 0xB80) == 0x880 && opmode != MODE_REG && opmode != MODE_AREG) {
497 //TODO: Check for invalid modes that are dependent on direction 511 //TODO: Check for invalid modes that are dependent on direction
502 decoded->dst.addr_mode = MODE_REG; 516 decoded->dst.addr_mode = MODE_REG;
503 decoded->dst.params.immed = *(++istream); 517 decoded->dst.params.immed = *(++istream);
504 istream = m68k_decode_op_ex(istream, opmode, reg, decoded->extra.size, &(decoded->src)); 518 istream = m68k_decode_op_ex(istream, opmode, reg, decoded->extra.size, &(decoded->src));
505 if (!istream) { 519 if (!istream) {
506 decoded->op = M68K_INVALID; 520 decoded->op = M68K_INVALID;
507 return start+1; 521 break;
508 } 522 }
509 if (decoded->src.addr_mode == MODE_PC_DISPLACE || decoded->src.addr_mode == MODE_PC_INDEX_DISP8) { 523 if (decoded->src.addr_mode == MODE_PC_DISPLACE || decoded->src.addr_mode == MODE_PC_INDEX_DISP8) {
510 //adjust displacement to account for extra instruction word 524 //adjust displacement to account for extra instruction word
511 decoded->src.params.regs.displacement += 2; 525 decoded->src.params.regs.displacement += 2;
512 } 526 }
514 decoded->src.addr_mode = MODE_REG; 528 decoded->src.addr_mode = MODE_REG;
515 decoded->src.params.immed = *(++istream); 529 decoded->src.params.immed = *(++istream);
516 istream = m68k_decode_op_ex(istream, opmode, reg, decoded->extra.size, &(decoded->dst)); 530 istream = m68k_decode_op_ex(istream, opmode, reg, decoded->extra.size, &(decoded->dst));
517 if (!istream) { 531 if (!istream) {
518 decoded->op = M68K_INVALID; 532 decoded->op = M68K_INVALID;
519 return start+1; 533 break;
520 } 534 }
521 } 535 }
522 } else { 536 } else {
523 optype = (*istream >> 9) & 0x7; 537 optype = (*istream >> 9) & 0x7;
524 size = (*istream >> 6) & 0x3; 538 size = (*istream >> 6) & 0x3;
534 } 548 }
535 decoded->extra.size = size; 549 decoded->extra.size = size;
536 istream= m68k_decode_op(istream, size, &(decoded->dst)); 550 istream= m68k_decode_op(istream, size, &(decoded->dst));
537 if (!istream) { 551 if (!istream) {
538 decoded->op = M68K_INVALID; 552 decoded->op = M68K_INVALID;
539 return start+1; 553 break;
540 } 554 }
541 break; 555 break;
542 case 1: 556 case 1:
543 //MOVE from CCR or CLR 557 //MOVE from CCR or CLR
544 if (size == OPSIZE_INVALID) { 558 if (size == OPSIZE_INVALID) {
545 #ifdef M68010 559 #ifdef M68010
546 decoded->op = M68K_MOVE_FROM_CCR; 560 decoded->op = M68K_MOVE_FROM_CCR;
547 size = OPSIZE_WORD; 561 size = OPSIZE_WORD;
548 #else 562 #else
549 return istream+1; 563 break;
550 #endif 564 #endif
551 } else { 565 } else {
552 decoded->op = M68K_CLR; 566 decoded->op = M68K_CLR;
553 } 567 }
554 decoded->extra.size = size; 568 decoded->extra.size = size;
555 istream= m68k_decode_op(istream, size, &(decoded->dst)); 569 istream= m68k_decode_op(istream, size, &(decoded->dst));
556 if (!istream) { 570 if (!istream) {
557 decoded->op = M68K_INVALID; 571 decoded->op = M68K_INVALID;
558 return start+1; 572 break;
559 } 573 }
560 break; 574 break;
561 case 2: 575 case 2:
562 //MOVE to CCR or NEG 576 //MOVE to CCR or NEG
563 if (size == OPSIZE_INVALID) { 577 if (size == OPSIZE_INVALID) {
564 decoded->op = M68K_MOVE_CCR; 578 decoded->op = M68K_MOVE_CCR;
565 size = OPSIZE_WORD; 579 size = OPSIZE_WORD;
566 istream= m68k_decode_op(istream, size, &(decoded->src)); 580 istream= m68k_decode_op(istream, size, &(decoded->src));
567 if (!istream) { 581 if (!istream) {
568 decoded->op = M68K_INVALID; 582 decoded->op = M68K_INVALID;
569 return start+1; 583 break;
570 } 584 }
571 } else { 585 } else {
572 decoded->op = M68K_NEG; 586 decoded->op = M68K_NEG;
573 istream= m68k_decode_op(istream, size, &(decoded->dst)); 587 istream= m68k_decode_op(istream, size, &(decoded->dst));
574 if (!istream) { 588 if (!istream) {
575 decoded->op = M68K_INVALID; 589 decoded->op = M68K_INVALID;
576 return start+1; 590 break;
577 } 591 }
578 } 592 }
579 decoded->extra.size = size; 593 decoded->extra.size = size;
580 break; 594 break;
581 case 3: 595 case 3:
584 decoded->op = M68K_MOVE_SR; 598 decoded->op = M68K_MOVE_SR;
585 size = OPSIZE_WORD; 599 size = OPSIZE_WORD;
586 istream= m68k_decode_op(istream, size, &(decoded->src)); 600 istream= m68k_decode_op(istream, size, &(decoded->src));
587 if (!istream) { 601 if (!istream) {
588 decoded->op = M68K_INVALID; 602 decoded->op = M68K_INVALID;
589 return start+1; 603 break;
590 } 604 }
591 } else { 605 } else {
592 decoded->op = M68K_NOT; 606 decoded->op = M68K_NOT;
593 istream= m68k_decode_op(istream, size, &(decoded->dst)); 607 istream= m68k_decode_op(istream, size, &(decoded->dst));
594 if (!istream) { 608 if (!istream) {
595 decoded->op = M68K_INVALID; 609 decoded->op = M68K_INVALID;
596 return start+1; 610 break;
597 } 611 }
598 } 612 }
599 decoded->extra.size = size; 613 decoded->extra.size = size;
600 break; 614 break;
601 case 4: 615 case 4:
646 decoded->op = M68K_NBCD; 660 decoded->op = M68K_NBCD;
647 decoded->extra.size = OPSIZE_BYTE; 661 decoded->extra.size = OPSIZE_BYTE;
648 istream = m68k_decode_op(istream, OPSIZE_BYTE, &(decoded->dst)); 662 istream = m68k_decode_op(istream, OPSIZE_BYTE, &(decoded->dst));
649 if (!istream) { 663 if (!istream) {
650 decoded->op = M68K_INVALID; 664 decoded->op = M68K_INVALID;
651 return start+1; 665 break;
652 } 666 }
653 } else if((*istream & 0x1C0) == 0x40) { 667 } else if((*istream & 0x1C0) == 0x40) {
654 decoded->op = M68K_PEA; 668 decoded->op = M68K_PEA;
655 decoded->extra.size = OPSIZE_LONG; 669 decoded->extra.size = OPSIZE_LONG;
656 istream = m68k_decode_op(istream, OPSIZE_LONG, &(decoded->src)); 670 istream = m68k_decode_op(istream, OPSIZE_LONG, &(decoded->src));
657 if (!istream) { 671 if (!istream) {
658 decoded->op = M68K_INVALID; 672 decoded->op = M68K_INVALID;
659 return start+1; 673 break;
660 } 674 }
661 } 675 }
662 } 676 }
663 break; 677 break;
664 case 5: 678 case 5:
676 decoded->op = M68K_TST; 690 decoded->op = M68K_TST;
677 decoded->extra.size = size; 691 decoded->extra.size = size;
678 istream = m68k_decode_op(istream, decoded->extra.size, &(decoded->src)); 692 istream = m68k_decode_op(istream, decoded->extra.size, &(decoded->src));
679 if (!istream) { 693 if (!istream) {
680 decoded->op = M68K_INVALID; 694 decoded->op = M68K_INVALID;
681 return start+1; 695 break;
682 } 696 }
683 } 697 }
684 } 698 }
685 break; 699 break;
686 case 6: 700 case 6:
700 } 714 }
701 decoded->extra.size = OPSIZE_UNSIZED; 715 decoded->extra.size = OPSIZE_UNSIZED;
702 istream = m68k_decode_op(istream, OPSIZE_UNSIZED, &(decoded->src)); 716 istream = m68k_decode_op(istream, OPSIZE_UNSIZED, &(decoded->src));
703 if (!istream) { 717 if (!istream) {
704 decoded->op = M68K_INVALID; 718 decoded->op = M68K_INVALID;
705 return start+1; 719 break;
706 } 720 }
707 } else { 721 } else {
708 //it would appear bit 6 needs to be set for it to be a valid instruction here 722 //it would appear bit 6 needs to be set for it to be a valid instruction here
709 switch((*istream >> 3) & 0x7) 723 switch((*istream >> 3) & 0x7)
710 { 724 {
781 } 795 }
782 break; 796 break;
783 case 7: 797 case 7:
784 //MOVEC 798 //MOVEC
785 #ifdef M68010 799 #ifdef M68010
800 decoded->op = M68K_MOVEC;
801 immed = *(++istream);
802 reg = immed >> 12 & 0x7;
803 opmode = immed & 0x8000 ? MODE_AREG : MODE_REG;
804 if (immed & 0x800) {
805 if (immed > MAX_HIGH_CR) {
806 decoded->op = M68K_INVALID;
807 break;
808 } else {
809 immed = immed - 0x800 + CR_USP;
810 }
811 } else {
812 if (immed > MAX_LOW_CR) {
813 decoded->op = M68K_INVALID;
814 break;
815 }
816 }
817 if (*start & 1) {
818 decoded->src.addr_mode = opmode;
819 decoded->src.params.regs.pri = reg;
820 decoded->dst.params.immed = immed;
821 } else {
822 decoded->dst.addr_mode = opmode;
823 decoded->dst.params.regs.pri = reg;
824 decoded->src.params.immed = immed;
825 }
786 #endif 826 #endif
787 break; 827 break;
788 } 828 }
789 } 829 }
790 break; 830 break;
814 decoded->op = M68K_SCC; 854 decoded->op = M68K_SCC;
815 decoded->extra.cond = (*istream >> 8) & 0xF; 855 decoded->extra.cond = (*istream >> 8) & 0xF;
816 istream = m68k_decode_op(istream, OPSIZE_BYTE, &(decoded->dst)); 856 istream = m68k_decode_op(istream, OPSIZE_BYTE, &(decoded->dst));
817 if (!istream) { 857 if (!istream) {
818 decoded->op = M68K_INVALID; 858 decoded->op = M68K_INVALID;
819 return start+1; 859 break;
820 } 860 }
821 } 861 }
822 } else { 862 } else {
823 //ADDQ, SUBQ 863 //ADDQ, SUBQ
824 decoded->variant = VAR_QUICK; 864 decoded->variant = VAR_QUICK;
835 decoded->op = M68K_ADD; 875 decoded->op = M68K_ADD;
836 } 876 }
837 istream = m68k_decode_op(istream, size, &(decoded->dst)); 877 istream = m68k_decode_op(istream, size, &(decoded->dst));
838 if (!istream) { 878 if (!istream) {
839 decoded->op = M68K_INVALID; 879 decoded->op = M68K_INVALID;
840 return start+1; 880 break;
841 } 881 }
842 } 882 }
843 break; 883 break;
844 case BRANCH: 884 case BRANCH:
845 m68k_decode_cond(*istream, decoded); 885 m68k_decode_cond(*istream, decoded);
863 decoded->src.params.immed = immed; 903 decoded->src.params.immed = immed;
864 break; 904 break;
865 case MOVEQ: 905 case MOVEQ:
866 if (*istream & 0x100) { 906 if (*istream & 0x100) {
867 decoded->op = M68K_INVALID; 907 decoded->op = M68K_INVALID;
868 return start+1; 908 break;
869 } 909 }
870 decoded->op = M68K_MOVE; 910 decoded->op = M68K_MOVE;
871 decoded->variant = VAR_QUICK; 911 decoded->variant = VAR_QUICK;
872 decoded->extra.size = OPSIZE_LONG; 912 decoded->extra.size = OPSIZE_LONG;
873 decoded->src.addr_mode = MODE_IMMEDIATE; 913 decoded->src.addr_mode = MODE_IMMEDIATE;
889 decoded->dst.addr_mode = MODE_REG; 929 decoded->dst.addr_mode = MODE_REG;
890 decoded->dst.params.regs.pri = (*istream >> 9) & 0x7; 930 decoded->dst.params.regs.pri = (*istream >> 9) & 0x7;
891 istream = m68k_decode_op(istream, OPSIZE_WORD, &(decoded->src)); 931 istream = m68k_decode_op(istream, OPSIZE_WORD, &(decoded->src));
892 if (!istream || decoded->src.addr_mode == MODE_AREG) { 932 if (!istream || decoded->src.addr_mode == MODE_AREG) {
893 decoded->op = M68K_INVALID; 933 decoded->op = M68K_INVALID;
894 return start+1; 934 break;
895 } 935 }
896 break; 936 break;
897 case 4: 937 case 4:
898 decoded->op = M68K_SBCD; 938 decoded->op = M68K_SBCD;
899 decoded->dst.addr_mode = decoded->src.addr_mode = *istream & 0x8 ? MODE_AREG_PREDEC : MODE_REG; 939 decoded->dst.addr_mode = decoded->src.addr_mode = *istream & 0x8 ? MODE_AREG_PREDEC : MODE_REG;
914 decoded->dst.addr_mode = MODE_REG; 954 decoded->dst.addr_mode = MODE_REG;
915 decoded->dst.params.regs.pri = (*istream >> 9) & 0x7; 955 decoded->dst.params.regs.pri = (*istream >> 9) & 0x7;
916 istream = m68k_decode_op(istream, OPSIZE_WORD, &(decoded->src)); 956 istream = m68k_decode_op(istream, OPSIZE_WORD, &(decoded->src));
917 if (!istream || decoded->src.addr_mode == MODE_AREG) { 957 if (!istream || decoded->src.addr_mode == MODE_AREG) {
918 decoded->op = M68K_INVALID; 958 decoded->op = M68K_INVALID;
919 return start+1; 959 break;
920 } 960 }
921 break; 961 break;
922 } 962 }
923 } else { 963 } else {
924 decoded->op = M68K_OR; 964 decoded->op = M68K_OR;
927 decoded->src.addr_mode = MODE_REG; 967 decoded->src.addr_mode = MODE_REG;
928 decoded->src.params.regs.pri = (*istream >> 9) & 0x7; 968 decoded->src.params.regs.pri = (*istream >> 9) & 0x7;
929 istream = m68k_decode_op(istream, size, &(decoded->dst)); 969 istream = m68k_decode_op(istream, size, &(decoded->dst));
930 if (!istream) { 970 if (!istream) {
931 decoded->op = M68K_INVALID; 971 decoded->op = M68K_INVALID;
932 return start+1; 972 break;
933 } 973 }
934 } else { 974 } else {
935 decoded->dst.addr_mode = MODE_REG; 975 decoded->dst.addr_mode = MODE_REG;
936 decoded->dst.params.regs.pri = (*istream >> 9) & 0x7; 976 decoded->dst.params.regs.pri = (*istream >> 9) & 0x7;
937 istream = m68k_decode_op(istream, size, &(decoded->src)); 977 istream = m68k_decode_op(istream, size, &(decoded->src));
938 if (!istream) { 978 if (!istream) {
939 decoded->op = M68K_INVALID; 979 decoded->op = M68K_INVALID;
940 return start+1; 980 break;
941 } 981 }
942 } 982 }
943 } 983 }
944 break; 984 break;
945 case SUB_SUBX: 985 case SUB_SUBX:
954 decoded->dst.addr_mode = MODE_AREG; 994 decoded->dst.addr_mode = MODE_AREG;
955 decoded->dst.params.regs.pri = m68k_reg_quick_field(*istream); 995 decoded->dst.params.regs.pri = m68k_reg_quick_field(*istream);
956 istream = m68k_decode_op(istream, OPSIZE_LONG, &(decoded->src)); 996 istream = m68k_decode_op(istream, OPSIZE_LONG, &(decoded->src));
957 if (!istream) { 997 if (!istream) {
958 decoded->op = M68K_INVALID; 998 decoded->op = M68K_INVALID;
959 return start+1; 999 break;
960 } 1000 }
961 } else { 1001 } else {
962 decoded->extra.size = size; 1002 decoded->extra.size = size;
963 decoded->src.addr_mode = MODE_REG; 1003 decoded->src.addr_mode = MODE_REG;
964 decoded->src.params.regs.pri = m68k_reg_quick_field(*istream); 1004 decoded->src.params.regs.pri = m68k_reg_quick_field(*istream);
965 istream = m68k_decode_op(istream, size, &(decoded->dst)); 1005 istream = m68k_decode_op(istream, size, &(decoded->dst));
966 if (!istream) { 1006 if (!istream) {
967 decoded->op = M68K_INVALID; 1007 decoded->op = M68K_INVALID;
968 return start+1; 1008 break;
969 } 1009 }
970 } 1010 }
971 } else { 1011 } else {
972 //SUBX 1012 //SUBX
973 decoded->op = M68K_SUBX; 1013 decoded->op = M68K_SUBX;
991 } 1031 }
992 decoded->dst.params.regs.pri = m68k_reg_quick_field(*istream); 1032 decoded->dst.params.regs.pri = m68k_reg_quick_field(*istream);
993 istream = m68k_decode_op(istream, decoded->extra.size, &(decoded->src)); 1033 istream = m68k_decode_op(istream, decoded->extra.size, &(decoded->src));
994 if (!istream) { 1034 if (!istream) {
995 decoded->op = M68K_INVALID; 1035 decoded->op = M68K_INVALID;
996 return start+1; 1036 break;
997 } 1037 }
998 } 1038 }
999 break; 1039 break;
1000 case RESERVED: 1040 case RESERVED:
1001 break; 1041 break;
1009 decoded->dst.addr_mode = MODE_AREG; 1049 decoded->dst.addr_mode = MODE_AREG;
1010 decoded->dst.params.regs.pri = m68k_reg_quick_field(*istream); 1050 decoded->dst.params.regs.pri = m68k_reg_quick_field(*istream);
1011 istream = m68k_decode_op(istream, decoded->extra.size, &(decoded->src)); 1051 istream = m68k_decode_op(istream, decoded->extra.size, &(decoded->src));
1012 if (!istream) { 1052 if (!istream) {
1013 decoded->op = M68K_INVALID; 1053 decoded->op = M68K_INVALID;
1014 return start+1; 1054 break;
1015 } 1055 }
1016 } else { 1056 } else {
1017 reg = m68k_reg_quick_field(*istream); 1057 reg = m68k_reg_quick_field(*istream);
1018 istream = m68k_decode_op(istream, size, &(decoded->dst)); 1058 istream = m68k_decode_op(istream, size, &(decoded->dst));
1019 if (!istream) { 1059 if (!istream) {
1020 decoded->op = M68K_INVALID; 1060 decoded->op = M68K_INVALID;
1021 return start+1; 1061 break;
1022 } 1062 }
1023 decoded->extra.size = size; 1063 decoded->extra.size = size;
1024 if (decoded->dst.addr_mode == MODE_AREG) { 1064 if (decoded->dst.addr_mode == MODE_AREG) {
1025 //CMPM 1065 //CMPM
1026 decoded->src.addr_mode = decoded->dst.addr_mode = MODE_AREG_POSTINC; 1066 decoded->src.addr_mode = decoded->dst.addr_mode = MODE_AREG_POSTINC;
1044 } 1084 }
1045 decoded->dst.params.regs.pri = m68k_reg_quick_field(*istream); 1085 decoded->dst.params.regs.pri = m68k_reg_quick_field(*istream);
1046 istream = m68k_decode_op(istream, decoded->extra.size, &(decoded->src)); 1086 istream = m68k_decode_op(istream, decoded->extra.size, &(decoded->src));
1047 if (!istream) { 1087 if (!istream) {
1048 decoded->op = M68K_INVALID; 1088 decoded->op = M68K_INVALID;
1049 return start+1; 1089 break;
1050 } 1090 }
1051 } 1091 }
1052 break; 1092 break;
1053 case AND_MUL_ABCD_EXG: 1093 case AND_MUL_ABCD_EXG:
1054 //page 575 for summary 1094 //page 575 for summary
1067 decoded->dst.addr_mode = MODE_REG; 1107 decoded->dst.addr_mode = MODE_REG;
1068 decoded->dst.params.regs.pri = m68k_reg_quick_field(*istream); 1108 decoded->dst.params.regs.pri = m68k_reg_quick_field(*istream);
1069 istream = m68k_decode_op(istream, OPSIZE_WORD, &(decoded->src)); 1109 istream = m68k_decode_op(istream, OPSIZE_WORD, &(decoded->src));
1070 if (!istream) { 1110 if (!istream) {
1071 decoded->op = M68K_INVALID; 1111 decoded->op = M68K_INVALID;
1072 return start+1; 1112 break;
1073 } 1113 }
1074 } else if(!(*istream & 0xF0)) { 1114 } else if(!(*istream & 0xF0)) {
1075 decoded->op = M68K_ABCD; 1115 decoded->op = M68K_ABCD;
1076 decoded->extra.size = OPSIZE_BYTE; 1116 decoded->extra.size = OPSIZE_BYTE;
1077 decoded->src.params.regs.pri = *istream & 0x7; 1117 decoded->src.params.regs.pri = *istream & 0x7;
1098 decoded->src.addr_mode = MODE_REG; 1138 decoded->src.addr_mode = MODE_REG;
1099 decoded->src.params.regs.pri = m68k_reg_quick_field(*istream); 1139 decoded->src.params.regs.pri = m68k_reg_quick_field(*istream);
1100 istream = m68k_decode_op(istream, decoded->extra.size, &(decoded->dst)); 1140 istream = m68k_decode_op(istream, decoded->extra.size, &(decoded->dst));
1101 if (!istream) { 1141 if (!istream) {
1102 decoded->op = M68K_INVALID; 1142 decoded->op = M68K_INVALID;
1103 return start+1; 1143 break;
1104 } 1144 }
1105 } 1145 }
1106 } else { 1146 } else {
1107 if ((*istream & 0xC0) == 0xC0) { 1147 if ((*istream & 0xC0) == 0xC0) {
1108 decoded->op = M68K_MULU; 1148 decoded->op = M68K_MULU;
1110 decoded->dst.addr_mode = MODE_REG; 1150 decoded->dst.addr_mode = MODE_REG;
1111 decoded->dst.params.regs.pri = m68k_reg_quick_field(*istream); 1151 decoded->dst.params.regs.pri = m68k_reg_quick_field(*istream);
1112 istream = m68k_decode_op(istream, OPSIZE_WORD, &(decoded->src)); 1152 istream = m68k_decode_op(istream, OPSIZE_WORD, &(decoded->src));
1113 if (!istream) { 1153 if (!istream) {
1114 decoded->op = M68K_INVALID; 1154 decoded->op = M68K_INVALID;
1115 return start+1; 1155 break;
1116 } 1156 }
1117 } else { 1157 } else {
1118 decoded->op = M68K_AND; 1158 decoded->op = M68K_AND;
1119 decoded->extra.size = (*istream >> 6) & 0x3; 1159 decoded->extra.size = (*istream >> 6) & 0x3;
1120 decoded->dst.addr_mode = MODE_REG; 1160 decoded->dst.addr_mode = MODE_REG;
1121 decoded->dst.params.regs.pri = m68k_reg_quick_field(*istream); 1161 decoded->dst.params.regs.pri = m68k_reg_quick_field(*istream);
1122 istream = m68k_decode_op(istream, decoded->extra.size, &(decoded->src)); 1162 istream = m68k_decode_op(istream, decoded->extra.size, &(decoded->src));
1123 if (!istream) { 1163 if (!istream) {
1124 decoded->op = M68K_INVALID; 1164 decoded->op = M68K_INVALID;
1125 return start+1; 1165 break;
1126 } 1166 }
1127 } 1167 }
1128 } 1168 }
1129 break; 1169 break;
1130 case ADD_ADDX: 1170 case ADD_ADDX:
1139 decoded->dst.addr_mode = MODE_AREG; 1179 decoded->dst.addr_mode = MODE_AREG;
1140 decoded->dst.params.regs.pri = m68k_reg_quick_field(*istream); 1180 decoded->dst.params.regs.pri = m68k_reg_quick_field(*istream);
1141 istream = m68k_decode_op(istream, OPSIZE_LONG, &(decoded->src)); 1181 istream = m68k_decode_op(istream, OPSIZE_LONG, &(decoded->src));
1142 if (!istream) { 1182 if (!istream) {
1143 decoded->op = M68K_INVALID; 1183 decoded->op = M68K_INVALID;
1144 return start+1; 1184 break;
1145 } 1185 }
1146 } else { 1186 } else {
1147 decoded->extra.size = size; 1187 decoded->extra.size = size;
1148 decoded->src.addr_mode = MODE_REG; 1188 decoded->src.addr_mode = MODE_REG;
1149 decoded->src.params.regs.pri = m68k_reg_quick_field(*istream); 1189 decoded->src.params.regs.pri = m68k_reg_quick_field(*istream);
1150 istream = m68k_decode_op(istream, size, &(decoded->dst)); 1190 istream = m68k_decode_op(istream, size, &(decoded->dst));
1151 if (!istream) { 1191 if (!istream) {
1152 decoded->op = M68K_INVALID; 1192 decoded->op = M68K_INVALID;
1153 return start+1; 1193 break;
1154 } 1194 }
1155 } 1195 }
1156 } else { 1196 } else {
1157 //ADDX 1197 //ADDX
1158 decoded->op = M68K_ADDX; 1198 decoded->op = M68K_ADDX;
1176 } 1216 }
1177 decoded->dst.params.regs.pri = m68k_reg_quick_field(*istream); 1217 decoded->dst.params.regs.pri = m68k_reg_quick_field(*istream);
1178 istream = m68k_decode_op(istream, decoded->extra.size, &(decoded->src)); 1218 istream = m68k_decode_op(istream, decoded->extra.size, &(decoded->src));
1179 if (!istream) { 1219 if (!istream) {
1180 decoded->op = M68K_INVALID; 1220 decoded->op = M68K_INVALID;
1181 return start+1; 1221 break;
1182 } 1222 }
1183 } 1223 }
1184 break; 1224 break;
1185 case SHIFT_ROTATE: 1225 case SHIFT_ROTATE:
1186 if ((*istream & 0x8C0) == 0xC0) { 1226 if ((*istream & 0x8C0) == 0xC0) {
1213 } 1253 }
1214 decoded->extra.size = OPSIZE_WORD; 1254 decoded->extra.size = OPSIZE_WORD;
1215 istream = m68k_decode_op(istream, OPSIZE_WORD, &(decoded->dst)); 1255 istream = m68k_decode_op(istream, OPSIZE_WORD, &(decoded->dst));
1216 if (!istream) { 1256 if (!istream) {
1217 decoded->op = M68K_INVALID; 1257 decoded->op = M68K_INVALID;
1218 return start+1; 1258 break;
1219 } 1259 }
1220 } else if((*istream & 0xC0) != 0xC0) { 1260 } else if((*istream & 0xC0) != 0xC0) {
1221 switch(((*istream >> 2) & 0x6) | ((*istream >> 8) & 1)) 1261 switch(((*istream >> 2) & 0x6) | ((*istream >> 8) & 1))
1222 { 1262 {
1223 case 0: 1263 case 0:
1267 } 1307 }
1268 break; 1308 break;
1269 case COPROC: 1309 case COPROC:
1270 //TODO: Implement me 1310 //TODO: Implement me
1271 break; 1311 break;
1312 }
1313 if (decoded->op == M68K_INVALID) {
1314 decoded->src.params.immed = *start;
1315 return start + 1;
1272 } 1316 }
1273 return istream+1; 1317 return istream+1;
1274 } 1318 }
1275 1319
1276 uint32_t m68k_branch_target(m68kinst * inst, uint32_t *dregs, uint32_t *aregs) 1320 uint32_t m68k_branch_target(m68kinst * inst, uint32_t *dregs, uint32_t *aregs)
1414 "tas", 1458 "tas",
1415 "trap", 1459 "trap",
1416 "trapv", 1460 "trapv",
1417 "tst", 1461 "tst",
1418 "unlk", 1462 "unlk",
1419 "invalid" 1463 "invalid",
1464 #ifdef M68010
1465 "bkpt",
1466 "move", //from ccr
1467 "movec",
1468 "moves",
1469 #endif
1470 #ifdef M68020
1471 "bfchg",
1472 "bfclr",
1473 "bfexts",
1474 "bfextu",
1475 "bfffo",
1476 "bfins",
1477 "bfset",
1478 "bftst",
1479 "callm",
1480 "cas",
1481 "cas2",
1482 "chk2",
1483 "cmp2",
1484 "cpbcc",
1485 "cpdbcc",
1486 "cpgen",
1487 "cprestore",
1488 "cpsave",
1489 "cpscc",
1490 "cptrapcc",
1491 "divsl",
1492 "divul",
1493 "extb",
1494 "pack",
1495 "rtm",
1496 "trapcc",
1497 "unpk"
1498 #endif
1420 }; 1499 };
1421 1500
1422 char * cond_mnem[] = { 1501 char * cond_mnem[] = {
1423 "ra", 1502 "ra",
1424 "f", 1503 "f",
1435 "ge", 1514 "ge",
1436 "lt", 1515 "lt",
1437 "gt", 1516 "gt",
1438 "le" 1517 "le"
1439 }; 1518 };
1519 #ifdef M68010
1520 char * cr_mnem[] = {
1521 "SFC",
1522 "DFC",
1523 #ifdef M68020
1524 "CACR",
1525 #endif
1526 "USP",
1527 "VBR",
1528 #ifdef M68020
1529 "CAAR",
1530 "MSP",
1531 "ISP"
1532 #endif
1533 };
1534 #endif
1440 1535
1441 int m68k_disasm_op(m68k_op_info *decoded, char *dst, int need_comma, uint8_t labels, uint32_t address) 1536 int m68k_disasm_op(m68k_op_info *decoded, char *dst, int need_comma, uint8_t labels, uint32_t address)
1442 { 1537 {
1443 char * c = need_comma ? "," : ""; 1538 char * c = need_comma ? "," : "";
1444 switch(decoded->addr_mode) 1539 switch(decoded->addr_mode)
1609 } else { 1704 } else {
1610 ret += sprintf(dst + ret, "USP, "); 1705 ret += sprintf(dst + ret, "USP, ");
1611 ret += m68k_disasm_op(&(decoded->dst), dst + ret, 0, labels, decoded->address); 1706 ret += m68k_disasm_op(&(decoded->dst), dst + ret, 0, labels, decoded->address);
1612 } 1707 }
1613 return ret; 1708 return ret;
1709 case M68K_INVALID:
1710 ret = sprintf(dst, "dc.w $%X", decoded->src.params.immed);
1711 return ret;
1712 #ifdef M68010
1713 case M68K_MOVEC:
1714 ret = sprintf(dst, "%s ", mnemonics[decoded->op]);
1715 if (decoded->src.addr_mode == MODE_UNUSED) {
1716 ret += sprintf(dst + ret, "%s, ", cr_mnem[decoded->src.params.immed]);
1717 ret += m68k_disasm_op(&(decoded->dst), dst + ret, 0, labels, decoded->address);
1718 } else {
1719 ret += m68k_disasm_op(&(decoded->src), dst + ret, 0, labels, decoded->address);
1720 ret += sprintf(dst + ret, ", %s", cr_mnem[decoded->dst.params.immed]);
1721 }
1722 return ret;
1723 #endif
1614 default: 1724 default:
1615 size = decoded->extra.size; 1725 size = decoded->extra.size;
1616 ret = sprintf(dst, "%s%s%s", 1726 ret = sprintf(dst, "%s%s%s",
1617 mnemonics[decoded->op], 1727 mnemonics[decoded->op],
1618 decoded->variant == VAR_QUICK ? "q" : (decoded->variant == VAR_IMMEDIATE ? "i" : ""), 1728 decoded->variant == VAR_QUICK ? "q" : (decoded->variant == VAR_IMMEDIATE ? "i" : ""),