Mercurial > repos > blastem
comparison z80inst.c @ 203:0ae589d4c3f9
Add support for 2-byte IX instructions to decoder
author | Mike Pavone <pavone@retrodev.com> |
---|---|
date | Tue, 22 Jan 2013 20:21:05 -0800 |
parents | 693ad04b965e |
children | 02dfa5962522 |
comparison
equal
deleted
inserted
replaced
202:693ad04b965e | 203:0ae589d4c3f9 |
---|---|
488 //F | 488 //F |
489 BIT_BLOCK(Z80_SET, 6), | 489 BIT_BLOCK(Z80_SET, 6), |
490 BIT_BLOCK(Z80_SET, 7) | 490 BIT_BLOCK(Z80_SET, 7) |
491 }; | 491 }; |
492 | 492 |
493 z80inst z80_tbl_ix[256 | 493 z80inst z80_tbl_ix[256] = { |
494 //0 | |
495 NOP2, | |
496 NOP2, | |
497 NOP2, | |
498 NOP2, | |
499 NOP2, | |
500 NOP2, | |
501 NOP2, | |
502 NOP2, | |
503 NOP2, | |
504 {Z80_ADD, Z80_IX, Z80_REG, Z80_BC, 0}, | |
505 NOP2, | |
506 NOP2, | |
507 NOP2, | |
508 NOP2, | |
509 NOP2, | |
510 NOP2, | |
511 //1 | |
512 NOP2, | |
513 NOP2, | |
514 NOP2, | |
515 NOP2, | |
516 NOP2, | |
517 NOP2, | |
518 NOP2, | |
519 NOP2, | |
520 NOP2, | |
521 {Z80_ADD, Z80_IX, Z80_REG, Z80_DE, 0}, | |
522 NOP2, | |
523 NOP2, | |
524 NOP2, | |
525 NOP2, | |
526 NOP2, | |
527 NOP2, | |
528 //2 | |
529 NOP2, | |
530 {Z80_LD, Z80_IX, Z80_IMMED, Z80_UNUSED, 0}, | |
531 {Z80_LD, Z80_IX, Z80_IMMED_INDIRECT | Z80_DIR, Z80_UNUSED, 0}, | |
532 {Z80_INC, Z80_IX, Z80_UNUSED, Z80_UNUSED, 0}, | |
533 {Z80_INC, Z80_IXH, Z80_UNUSED, Z80_UNUSED, 0}, | |
534 {Z80_DEC, Z80_IXH, Z80_UNUSED, Z80_UNUSED, 0}, | |
535 {Z80_LD, Z80_IXH, Z80_IMMED, Z80_UNUSED, 0}, | |
536 NOP2, | |
537 NOP2, | |
538 {Z80_ADD, Z80_IX, Z80_REG, Z80_IX, 0}, | |
539 {Z80_LD, Z80_IX, Z80_IMMED_INDIRECT, Z80_UNUSED, 0}, | |
540 {Z80_DEC, Z80_IX, Z80_UNUSED, Z80_UNUSED, 0}, | |
541 {Z80_INC, Z80_IXL, Z80_UNUSED, Z80_UNUSED, 0}, | |
542 {Z80_DEC, Z80_IXL, Z80_UNUSED, Z80_UNUSED, 0}, | |
543 {Z80_LD, Z80_IXL, Z80_IMMED, Z80_UNUSED, 0}, | |
544 NOP2, | |
545 //3 | |
546 NOP2, | |
547 NOP2, | |
548 NOP2, | |
549 NOP2, | |
550 {Z80_INC, Z80_UNUSED, Z80_IX_DISPLACE, 0, 0}, | |
551 {Z80_DEC, Z80_UNUSED, Z80_IX_DISPLACE, 0, 0}, | |
552 {Z80_LD, Z80_USE_IMMED, Z80_IX_DISPLACE | Z80_DIR, 0, 0}, | |
553 NOP2, | |
554 NOP2, | |
555 {Z80_ADD, Z80_IX, Z80_REG, Z80_SP, 0}, | |
556 NOP2, | |
557 NOP2, | |
558 NOP2, | |
559 NOP2, | |
560 NOP2, | |
561 NOP2, | |
562 //4 | |
563 NOP2, | |
564 NOP2, | |
565 NOP2, | |
566 NOP2, | |
567 {Z80_LD, Z80_B, Z80_REG, Z80_IXH, 0}, | |
568 {Z80_LD, Z80_B, Z80_REG, Z80_IXL, 0}, | |
569 {Z80_LD, Z80_B, Z80_IX_DISPLACE, 0, 0}, | |
570 NOP2, | |
571 NOP2, | |
572 NOP2, | |
573 NOP2, | |
574 NOP2, | |
575 {Z80_LD, Z80_C, Z80_REG, Z80_IXH, 0}, | |
576 {Z80_LD, Z80_C, Z80_REG, Z80_IXL, 0}, | |
577 {Z80_LD, Z80_C, Z80_IX_DISPLACE, 0, 0}, | |
578 NOP2, | |
579 //5 | |
580 NOP2, | |
581 NOP2, | |
582 NOP2, | |
583 NOP2, | |
584 {Z80_LD, Z80_D, Z80_REG, Z80_IXH, 0}, | |
585 {Z80_LD, Z80_D, Z80_REG, Z80_IXL, 0}, | |
586 {Z80_LD, Z80_D, Z80_IX_DISPLACE, 0, 0}, | |
587 NOP2, | |
588 NOP2, | |
589 NOP2, | |
590 NOP2, | |
591 NOP2, | |
592 {Z80_LD, Z80_E, Z80_REG, Z80_IXH, 0}, | |
593 {Z80_LD, Z80_E, Z80_REG, Z80_IXL, 0}, | |
594 {Z80_LD, Z80_E, Z80_IX_DISPLACE, 0, 0}, | |
595 NOP2, | |
596 //6 | |
597 {Z80_LD, Z80_IXH, Z80_REG, Z80_B, 0}, | |
598 {Z80_LD, Z80_IXH, Z80_REG, Z80_C, 0}, | |
599 {Z80_LD, Z80_IXH, Z80_REG, Z80_D, 0}, | |
600 {Z80_LD, Z80_IXH, Z80_REG, Z80_E, 0}, | |
601 {Z80_LD, Z80_IXH, Z80_REG, Z80_IXH, 0}, | |
602 {Z80_LD, Z80_IXH, Z80_REG, Z80_IXL, 0}, | |
603 {Z80_LD, Z80_H, Z80_IX_DISPLACE, 0, 0}, | |
604 {Z80_LD, Z80_IXH, Z80_REG, Z80_A, 0}, | |
605 {Z80_LD, Z80_IXL, Z80_REG, Z80_B, 0}, | |
606 {Z80_LD, Z80_IXL, Z80_REG, Z80_C, 0}, | |
607 {Z80_LD, Z80_IXL, Z80_REG, Z80_D, 0}, | |
608 {Z80_LD, Z80_IXL, Z80_REG, Z80_E, 0}, | |
609 {Z80_LD, Z80_IXL, Z80_REG, Z80_IXH, 0}, | |
610 {Z80_LD, Z80_IXL, Z80_REG, Z80_IXL, 0}, | |
611 {Z80_LD, Z80_L, Z80_IX_DISPLACE, 0, 0}, | |
612 {Z80_LD, Z80_IXL, Z80_REG, Z80_A, 0}, | |
613 //7 | |
614 {Z80_LD, Z80_B, Z80_IX_DISPLACE | Z80_DIR, 0, 0}, | |
615 {Z80_LD, Z80_C, Z80_IX_DISPLACE | Z80_DIR, 0, 0}, | |
616 {Z80_LD, Z80_D, Z80_IX_DISPLACE | Z80_DIR, 0, 0}, | |
617 {Z80_LD, Z80_E, Z80_IX_DISPLACE | Z80_DIR, 0, 0}, | |
618 {Z80_LD, Z80_H, Z80_IX_DISPLACE | Z80_DIR, 0, 0}, | |
619 {Z80_LD, Z80_L, Z80_IX_DISPLACE | Z80_DIR, 0, 0}, | |
620 NOP2, | |
621 {Z80_LD, Z80_A, Z80_IX_DISPLACE | Z80_DIR, 0, 0}, | |
622 NOP2, | |
623 NOP2, | |
624 NOP2, | |
625 NOP2, | |
626 {Z80_LD, Z80_A, Z80_REG, Z80_IXH, 0}, | |
627 {Z80_LD, Z80_A, Z80_REG, Z80_IXL, 0}, | |
628 {Z80_LD, Z80_A, Z80_IX_DISPLACE, 0, 0}, | |
629 NOP2, | |
630 //8 | |
631 NOP2, | |
632 NOP2, | |
633 NOP2, | |
634 NOP2, | |
635 {Z80_ADD, Z80_A, Z80_REG, Z80_IXH, 0}, | |
636 {Z80_ADD, Z80_A, Z80_REG, Z80_IXL, 0}, | |
637 {Z80_ADD, Z80_A, Z80_IX_DISPLACE, 0, 0}, | |
638 NOP2, | |
639 NOP2, | |
640 NOP2, | |
641 NOP2, | |
642 NOP2, | |
643 {Z80_ADC, Z80_A, Z80_REG, Z80_IXH, 0}, | |
644 {Z80_ADC, Z80_A, Z80_REG, Z80_IXL, 0}, | |
645 {Z80_ADC, Z80_A, Z80_IX_DISPLACE, 0, 0}, | |
646 NOP2, | |
647 //9 | |
648 NOP2, | |
649 NOP2, | |
650 NOP2, | |
651 NOP2, | |
652 {Z80_SUB, Z80_A, Z80_REG, Z80_IXH, 0}, | |
653 {Z80_SUB, Z80_A, Z80_REG, Z80_IXL, 0}, | |
654 {Z80_SUB, Z80_A, Z80_IX_DISPLACE, 0, 0}, | |
655 NOP2, | |
656 NOP2, | |
657 NOP2, | |
658 NOP2, | |
659 NOP2, | |
660 {Z80_SBC, Z80_A, Z80_REG, Z80_IXH, 0}, | |
661 {Z80_SBC, Z80_A, Z80_REG, Z80_IXL, 0}, | |
662 {Z80_SBC, Z80_A, Z80_IX_DISPLACE, 0, 0}, | |
663 NOP2, | |
664 //A | |
665 NOP2, | |
666 NOP2, | |
667 NOP2, | |
668 NOP2, | |
669 {Z80_AND, Z80_A, Z80_REG, Z80_IXH, 0}, | |
670 {Z80_AND, Z80_A, Z80_REG, Z80_IXL, 0}, | |
671 {Z80_AND, Z80_A, Z80_IX_DISPLACE, 0, 0}, | |
672 NOP2, | |
673 NOP2, | |
674 NOP2, | |
675 NOP2, | |
676 NOP2, | |
677 {Z80_XOR, Z80_A, Z80_REG, Z80_IXH, 0}, | |
678 {Z80_XOR, Z80_A, Z80_REG, Z80_IXL, 0}, | |
679 {Z80_XOR, Z80_A, Z80_IX_DISPLACE, 0, 0}, | |
680 NOP2, | |
681 //B | |
682 NOP2, | |
683 NOP2, | |
684 NOP2, | |
685 NOP2, | |
686 {Z80_OR, Z80_A, Z80_REG, Z80_IXH, 0}, | |
687 {Z80_OR, Z80_A, Z80_REG, Z80_IXL, 0}, | |
688 {Z80_OR, Z80_A, Z80_IX_DISPLACE, 0, 0}, | |
689 NOP2, | |
690 NOP2, | |
691 NOP2, | |
692 NOP2, | |
693 NOP2, | |
694 {Z80_CP, Z80_A, Z80_REG, Z80_IXH, 0}, | |
695 {Z80_CP, Z80_A, Z80_REG, Z80_IXL, 0}, | |
696 {Z80_CP, Z80_A, Z80_IX_DISPLACE, 0, 0}, | |
697 NOP2, | |
698 //C | |
699 NOP2, | |
700 NOP2, | |
701 NOP2, | |
702 NOP2, | |
703 NOP2, | |
704 NOP2, | |
705 NOP2, | |
706 NOP2, | |
707 NOP2, | |
708 NOP2, | |
709 NOP2, | |
710 NOP2, | |
711 NOP2, | |
712 NOP2, | |
713 NOP2, | |
714 NOP2, | |
715 //D | |
716 NOP2, | |
717 NOP2, | |
718 NOP2, | |
719 NOP2, | |
720 NOP2, | |
721 NOP2, | |
722 NOP2, | |
723 NOP2, | |
724 NOP2, | |
725 NOP2, | |
726 NOP2, | |
727 NOP2, | |
728 NOP2, | |
729 NOP2, | |
730 NOP2, | |
731 NOP2, | |
732 //E | |
733 NOP2, | |
734 {Z80_POP, Z80_IX, Z80_UNUSED, Z80_UNUSED, 0}, | |
735 NOP2, | |
736 {Z80_EX, Z80_IX, Z80_REG_INDIRECT | Z80_DIR, Z80_SP, 0}, | |
737 NOP2, | |
738 {Z80_PUSH, Z80_IX, Z80_UNUSED, Z80_UNUSED, 0}, | |
739 NOP2, | |
740 NOP2, | |
741 NOP2, | |
742 {Z80_JP, Z80_UNUSED, Z80_REG_INDIRECT, Z80_IX, 0}, | |
743 NOP2, | |
744 NOP2, | |
745 NOP2, | |
746 NOP2, | |
747 NOP2, | |
748 NOP2, | |
749 //F | |
750 NOP2, | |
751 NOP2, | |
752 NOP2, | |
753 NOP2, | |
754 NOP2, | |
755 NOP2, | |
756 NOP2, | |
757 NOP2, | |
758 NOP2, | |
759 {Z80_LD, Z80_SP, Z80_REG, Z80_IX, 0}, | |
760 NOP2, | |
761 NOP2, | |
762 NOP2, | |
763 NOP2, | |
764 NOP2, | |
765 NOP2 | |
766 }; | |
494 | 767 |
495 uint8_t * z80_decode(uint8_t * istream, z80inst * decoded) | 768 uint8_t * z80_decode(uint8_t * istream, z80inst * decoded) |
496 { | 769 { |
497 if (*istream == 0xCB) { | 770 if (*istream == 0xCB) { |
498 istream++; | 771 istream++; |
499 memcpy(decoded, z80_tbl_bit + *istream, sizeof(z80inst)); | 772 memcpy(decoded, z80_tbl_bit + *istream, sizeof(z80inst)); |
500 } else if (*istream == 0xDD) { | 773 } else if (*istream == 0xDD) { |
774 istream++; | |
775 if (*istream == 0xCB) { | |
776 } else { | |
777 memcpy(decoded, z80_tbl_ix + *istream, sizeof(z80inst)); | |
778 } | |
501 } else if (*istream == 0xED) { | 779 } else if (*istream == 0xED) { |
502 istream++; | 780 istream++; |
503 if (*istream < 0x40 || *istream >= 0xC0) { | 781 if (*istream < 0x40 || *istream >= 0xC0) { |
504 memcpy(decoded, z80_tbl_extd + 0xBF, sizeof(z80inst)); | 782 memcpy(decoded, z80_tbl_extd + 0xBF, sizeof(z80inst)); |
505 } else { | 783 } else { |
508 } else if (*istream == 0xFD) { | 786 } else if (*istream == 0xFD) { |
509 } else { | 787 } else { |
510 memcpy(decoded, z80_tbl_a + *istream, sizeof(z80inst)); | 788 memcpy(decoded, z80_tbl_a + *istream, sizeof(z80inst)); |
511 | 789 |
512 } | 790 } |
513 if ((decoded->addr_mode & 0xF) == Z80_IMMED && decoded->op != Z80_RST && decoded->op != Z80_IM) { | 791 if ((decoded->addr_mode & 0x1F) == Z80_IX_DISPLACE || (decoded->addr_mode & 0x1F) == Z80_IY_DISPLACE) { |
792 decoded->ea_reg = *(++istream); | |
793 } else if ((decoded->addr_mode & 0x1F) == Z80_IMMED && decoded->op != Z80_RST && decoded->op != Z80_IM) { | |
514 decoded->immed = *(++istream); | 794 decoded->immed = *(++istream); |
515 if (decoded->reg >= Z80_BC && decoded->reg < Z80_USE_IMMED) { | 795 if (decoded->reg >= Z80_BC && decoded->reg < Z80_USE_IMMED) { |
516 decoded->immed |= *(++istream) << 8; | 796 decoded->immed |= *(++istream) << 8; |
517 } else if (decoded->immed & 0x80) { | 797 } else if (decoded->immed & 0x80) { |
518 decoded->immed |= 0xFF00; | 798 decoded->immed |= 0xFF00; |
519 } | 799 } |
520 } else if ((decoded->addr_mode & 0xF) == Z80_IMMED_INDIRECT) { | 800 } else if ((decoded->addr_mode & 0x1F) == Z80_IMMED_INDIRECT) { |
521 decoded->immed = *(++istream); | 801 decoded->immed = *(++istream); |
522 if (decoded->op != Z80_OUT && decoded->op != Z80_IN) { | 802 if (decoded->op != Z80_OUT && decoded->op != Z80_IN) { |
523 decoded->immed |= *(++istream) << 8; | 803 decoded->immed |= *(++istream) << 8; |
524 } | 804 } |
525 } else if (decoded->reg == Z80_USE_IMMED && decoded->op != Z80_BIT && decoded->op != Z80_RES && decoded->op != Z80_SET) { | 805 } |
806 if (decoded->reg == Z80_USE_IMMED && decoded->op != Z80_BIT && decoded->op != Z80_RES && decoded->op != Z80_SET) { | |
526 decoded->immed = *(++istream); | 807 decoded->immed = *(++istream); |
527 } | 808 } |
528 return istream+1; | 809 return istream+1; |
529 } | 810 } |
530 | 811 |
606 "e", | 887 "e", |
607 "h", | 888 "h", |
608 "l", | 889 "l", |
609 "", | 890 "", |
610 "a", | 891 "a", |
892 "ixh", | |
893 "ixl", | |
611 "i", | 894 "i", |
612 "r", | 895 "r", |
613 "bc", | 896 "bc", |
614 "de", | 897 "de", |
615 "hl", | 898 "hl", |
616 "sp", | 899 "sp", |
617 "af", | 900 "af", |
901 "ix", | |
902 "iy", | |
618 }; | 903 }; |
619 | 904 |
620 char * z80_conditions[Z80_CC_M+1] = { | 905 char * z80_conditions[Z80_CC_M+1] = { |
621 "nz", | 906 "nz", |
622 "z", | 907 "z", |
630 | 915 |
631 int z80_disasm(z80inst * decoded, char * dst) | 916 int z80_disasm(z80inst * decoded, char * dst) |
632 { | 917 { |
633 int len = sprintf(dst, "%s", z80_mnemonics[decoded->op]); | 918 int len = sprintf(dst, "%s", z80_mnemonics[decoded->op]); |
634 if (decoded->addr_mode & Z80_DIR) { | 919 if (decoded->addr_mode & Z80_DIR) { |
635 switch (decoded->addr_mode & 0xF) | 920 switch (decoded->addr_mode & 0x1F) |
636 { | 921 { |
637 case Z80_REG: | 922 case Z80_REG: |
638 len += sprintf(dst+len, " %s", z80_regs[decoded->ea_reg]); | 923 len += sprintf(dst+len, " %s", z80_regs[decoded->ea_reg]); |
639 break; | 924 break; |
640 case Z80_REG_INDIRECT: | 925 case Z80_REG_INDIRECT: |
643 case Z80_IMMED: | 928 case Z80_IMMED: |
644 len += sprintf(dst+len, " %d", decoded->immed); | 929 len += sprintf(dst+len, " %d", decoded->immed); |
645 break; | 930 break; |
646 case Z80_IMMED_INDIRECT: | 931 case Z80_IMMED_INDIRECT: |
647 len += sprintf(dst+len, " (%d)", decoded->immed); | 932 len += sprintf(dst+len, " (%d)", decoded->immed); |
933 break; | |
934 case Z80_IX_DISPLACE: | |
935 len += sprintf(dst+len, " (ix+%d)", decoded->ea_reg); | |
936 break; | |
937 case Z80_IY_DISPLACE: | |
938 len += sprintf(dst+len, " (iy+%d)", decoded->ea_reg); | |
648 break; | 939 break; |
649 } | 940 } |
650 if (decoded->reg == Z80_USE_IMMED) { | 941 if (decoded->reg == Z80_USE_IMMED) { |
651 len += sprintf(dst+len, " %d", decoded->immed); | 942 len += sprintf(dst+len, " %d", decoded->immed); |
652 } else if (decoded->reg != Z80_UNUSED) { | 943 } else if (decoded->reg != Z80_UNUSED) { |
678 len += sprintf(dst+len, "%s %d", decoded->reg == Z80_UNUSED ? "" : "," , decoded->immed); | 969 len += sprintf(dst+len, "%s %d", decoded->reg == Z80_UNUSED ? "" : "," , decoded->immed); |
679 break; | 970 break; |
680 case Z80_IMMED_INDIRECT: | 971 case Z80_IMMED_INDIRECT: |
681 len += sprintf(dst+len, "%s (%d)", decoded->reg == Z80_UNUSED ? "" : "," , decoded->immed); | 972 len += sprintf(dst+len, "%s (%d)", decoded->reg == Z80_UNUSED ? "" : "," , decoded->immed); |
682 break; | 973 break; |
974 case Z80_IX_DISPLACE: | |
975 len += sprintf(dst+len, "%s (ix+%d)", decoded->reg == Z80_UNUSED ? "" : "," , decoded->ea_reg); | |
976 break; | |
977 case Z80_IY_DISPLACE: | |
978 len += sprintf(dst+len, "%s (iy+%d)", decoded->reg == Z80_UNUSED ? "" : "," , decoded->ea_reg); | |
979 break; | |
683 } | 980 } |
684 } | 981 } |
685 return len; | 982 return len; |
686 } | 983 } |
687 | 984 |