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