Mercurial > repos > blastem
comparison z80_to_x86.c @ 247:682e505f5757
Implement rotation and bit set/reset instructions (untested).
author | Mike Pavone <pavone@retrodev.com> |
---|---|
date | Sun, 28 Apr 2013 22:41:30 -0700 |
parents | ed548c77b598 |
children | 9c7a3db7bcd0 |
comparison
equal
deleted
inserted
replaced
246:ed548c77b598 | 247:682e505f5757 |
---|---|
657 break; | 657 break; |
658 case Z80_IM: | 658 case Z80_IM: |
659 dst = zcycles(dst, 4); | 659 dst = zcycles(dst, 4); |
660 dst = mov_irdisp8(dst, inst->immed, CONTEXT, offsetof(z80_context, im), SZ_B); | 660 dst = mov_irdisp8(dst, inst->immed, CONTEXT, offsetof(z80_context, im), SZ_B); |
661 break; | 661 break; |
662 /*case Z80_RLC: | 662 case Z80_RLC: |
663 cycles = inst->immed == 1 ? 4 : (inst->addr_mode == Z80_IX_DISPLACE || inst->addr_mode == Z80_IY_DISPLACE ? 16 : 8); | |
664 dst = zcycles(dst, cycles); | |
665 if (inst->reg == Z80_UNUSED) { | |
666 dst = translate_z80_ea(inst, &dst_op, dst, opts, READ, MODIFY); | |
667 dst = zcycles(dst, 1); | |
668 } else { | |
669 dst = translate_z80_reg(inst, &dst_op, dst, opts); | |
670 } | |
671 dst = rol_ir(dst, 1, dst_op.base, SZ_B); | |
672 dst = setcc_rdisp8(dst, CC_C, CONTEXT, zf_off(ZF_C)); | |
673 dst = mov_irdisp8(dst, 0, CONTEXT, zf_off(ZF_N), SZ_B); | |
674 //TODO: Implement half-carry flag | |
675 dst = cmp_ir(dst, 0, dst_op.base, SZ_B); | |
676 dst = setcc_rdisp8(dst, CC_P, CONTEXT, zf_off(ZF_PV)); | |
677 dst = setcc_rdisp8(dst, CC_Z, CONTEXT, zf_off(ZF_Z)); | |
678 dst = setcc_rdisp8(dst, CC_S, CONTEXT, zf_off(ZF_S)); | |
679 if (inst->reg == Z80_UNUSED) { | |
680 dst = z80_save_result(dst, inst); | |
681 } else { | |
682 dst = z80_save_reg(dst, inst, opts); | |
683 } | |
684 break; | |
663 case Z80_RL: | 685 case Z80_RL: |
686 cycles = inst->immed == 1 ? 4 : (inst->addr_mode == Z80_IX_DISPLACE || inst->addr_mode == Z80_IY_DISPLACE ? 16 : 8); | |
687 dst = zcycles(dst, cycles); | |
688 if (inst->reg == Z80_UNUSED) { | |
689 dst = translate_z80_ea(inst, &dst_op, dst, opts, READ, MODIFY); | |
690 dst = zcycles(dst, 1); | |
691 } else { | |
692 dst = translate_z80_reg(inst, &dst_op, dst, opts); | |
693 } | |
694 dst = bt_irdisp8(dst, 0, CONTEXT, zf_off(ZF_C), SZ_B); | |
695 dst = rcl_ir(dst, 1, dst_op.base, SZ_B); | |
696 dst = setcc_rdisp8(dst, CC_C, CONTEXT, zf_off(ZF_C)); | |
697 dst = mov_irdisp8(dst, 0, CONTEXT, zf_off(ZF_N), SZ_B); | |
698 //TODO: Implement half-carry flag | |
699 dst = cmp_ir(dst, 0, dst_op.base, SZ_B); | |
700 dst = setcc_rdisp8(dst, CC_P, CONTEXT, zf_off(ZF_PV)); | |
701 dst = setcc_rdisp8(dst, CC_Z, CONTEXT, zf_off(ZF_Z)); | |
702 dst = setcc_rdisp8(dst, CC_S, CONTEXT, zf_off(ZF_S)); | |
703 if (inst->reg == Z80_UNUSED) { | |
704 dst = z80_save_result(dst, inst); | |
705 } else { | |
706 dst = z80_save_reg(dst, inst, opts); | |
707 } | |
708 break; | |
664 case Z80_RRC: | 709 case Z80_RRC: |
710 cycles = inst->immed == 1 ? 4 : (inst->addr_mode == Z80_IX_DISPLACE || inst->addr_mode == Z80_IY_DISPLACE ? 16 : 8); | |
711 dst = zcycles(dst, cycles); | |
712 if (inst->reg == Z80_UNUSED) { | |
713 dst = translate_z80_ea(inst, &dst_op, dst, opts, READ, MODIFY); | |
714 dst = zcycles(dst, 1); | |
715 } else { | |
716 dst = translate_z80_reg(inst, &dst_op, dst, opts); | |
717 } | |
718 dst = ror_ir(dst, 1, dst_op.base, SZ_B); | |
719 dst = setcc_rdisp8(dst, CC_C, CONTEXT, zf_off(ZF_C)); | |
720 dst = mov_irdisp8(dst, 0, CONTEXT, zf_off(ZF_N), SZ_B); | |
721 //TODO: Implement half-carry flag | |
722 dst = cmp_ir(dst, 0, dst_op.base, SZ_B); | |
723 dst = setcc_rdisp8(dst, CC_P, CONTEXT, zf_off(ZF_PV)); | |
724 dst = setcc_rdisp8(dst, CC_Z, CONTEXT, zf_off(ZF_Z)); | |
725 dst = setcc_rdisp8(dst, CC_S, CONTEXT, zf_off(ZF_S)); | |
726 if (inst->reg == Z80_UNUSED) { | |
727 dst = z80_save_result(dst, inst); | |
728 } else { | |
729 dst = z80_save_reg(dst, inst, opts); | |
730 } | |
731 break; | |
665 case Z80_RR: | 732 case Z80_RR: |
666 case Z80_SLA: | 733 cycles = inst->immed == 1 ? 4 : (inst->addr_mode == Z80_IX_DISPLACE || inst->addr_mode == Z80_IY_DISPLACE ? 16 : 8); |
734 dst = zcycles(dst, cycles); | |
735 if (inst->reg == Z80_UNUSED) { | |
736 dst = translate_z80_ea(inst, &dst_op, dst, opts, READ, MODIFY); | |
737 dst = zcycles(dst, 1); | |
738 } else { | |
739 dst = translate_z80_reg(inst, &dst_op, dst, opts); | |
740 } | |
741 dst = bt_irdisp8(dst, 0, CONTEXT, zf_off(ZF_C), SZ_B); | |
742 dst = rcr_ir(dst, 1, dst_op.base, SZ_B); | |
743 dst = setcc_rdisp8(dst, CC_C, CONTEXT, zf_off(ZF_C)); | |
744 dst = mov_irdisp8(dst, 0, CONTEXT, zf_off(ZF_N), SZ_B); | |
745 //TODO: Implement half-carry flag | |
746 dst = cmp_ir(dst, 0, dst_op.base, SZ_B); | |
747 dst = setcc_rdisp8(dst, CC_P, CONTEXT, zf_off(ZF_PV)); | |
748 dst = setcc_rdisp8(dst, CC_Z, CONTEXT, zf_off(ZF_Z)); | |
749 dst = setcc_rdisp8(dst, CC_S, CONTEXT, zf_off(ZF_S)); | |
750 if (inst->reg == Z80_UNUSED) { | |
751 dst = z80_save_result(dst, inst); | |
752 } else { | |
753 dst = z80_save_reg(dst, inst, opts); | |
754 } | |
755 break; | |
756 /*case Z80_SLA: | |
667 case Z80_SRA: | 757 case Z80_SRA: |
668 case Z80_SLL: | 758 case Z80_SLL: |
669 case Z80_SRL: | 759 case Z80_SRL: |
670 case Z80_RLD: | 760 case Z80_RLD: |
671 case Z80_RRD:*/ | 761 case Z80_RRD:*/ |
678 dst = zcycles(dst, 1); | 768 dst = zcycles(dst, 1); |
679 } | 769 } |
680 dst = bt_ir(dst, inst->immed, src_op.base, SZ_B); | 770 dst = bt_ir(dst, inst->immed, src_op.base, SZ_B); |
681 dst = setcc_rdisp8(dst, CC_C, CONTEXT, zf_off(ZF_Z)); | 771 dst = setcc_rdisp8(dst, CC_C, CONTEXT, zf_off(ZF_Z)); |
682 break; | 772 break; |
683 //case Z80_SET: | 773 case Z80_SET: |
684 //case Z80_RES: | 774 cycles = (inst->addr_mode == Z80_IX_DISPLACE || inst->addr_mode == Z80_IY_DISPLACE) ? 8 : 16; |
775 dst = zcycles(dst, cycles); | |
776 dst = translate_z80_ea(inst, &src_op, dst, opts, READ, DONT_MODIFY); | |
777 if (inst->addr_mode != Z80_REG) { | |
778 //Reads normally take 3 cycles, but the read in the middle of a set instruction takes 4 | |
779 dst = zcycles(dst, 1); | |
780 } | |
781 dst = bts_ir(dst, inst->immed, src_op.base, SZ_B); | |
782 if (inst->addr_mode != Z80_REG) { | |
783 dst = z80_save_result(dst, inst); | |
784 } | |
785 break; | |
786 case Z80_RES: | |
787 cycles = (inst->addr_mode == Z80_IX_DISPLACE || inst->addr_mode == Z80_IY_DISPLACE) ? 8 : 16; | |
788 dst = zcycles(dst, cycles); | |
789 dst = translate_z80_ea(inst, &src_op, dst, opts, READ, DONT_MODIFY); | |
790 if (inst->addr_mode != Z80_REG) { | |
791 //Reads normally take 3 cycles, but the read in the middle of a set instruction takes 4 | |
792 dst = zcycles(dst, 1); | |
793 } | |
794 dst = btr_ir(dst, inst->immed, src_op.base, SZ_B); | |
795 if (inst->addr_mode != Z80_REG) { | |
796 dst = z80_save_result(dst, inst); | |
797 } | |
798 break; | |
685 case Z80_JP: { | 799 case Z80_JP: { |
686 cycles = 4; | 800 cycles = 4; |
687 if (inst->addr_mode != Z80_REG) { | 801 if (inst->addr_mode != Z80_REG) { |
688 cycles += 6; | 802 cycles += 6; |
689 } else if(inst->ea_reg == Z80_IX || inst->ea_reg == Z80_IY) { | 803 } else if(inst->ea_reg == Z80_IX || inst->ea_reg == Z80_IY) { |