Mercurial > repos > blastem
comparison z80_to_x86.c @ 1043:3980ef0f6307
Implement block CP instructions. Fix bug that would corrupt context reg in DAA. Fix flag values for when LD block instructions are interrupted part way through.
author | Michael Pavone <pavone@retrodev.com> |
---|---|
date | Sun, 24 Jul 2016 18:53:22 -0700 |
parents | a6c6b621d0dc |
children | 1625555e346e |
comparison
equal
deleted
inserted
replaced
1042:a6c6b621d0dc | 1043:3980ef0f6307 |
---|---|
605 if (opts->regs[Z80_BC] >= 0) { | 605 if (opts->regs[Z80_BC] >= 0) { |
606 sub_ir(code, 1, opts->regs[Z80_BC], SZ_W); | 606 sub_ir(code, 1, opts->regs[Z80_BC], SZ_W); |
607 } else { | 607 } else { |
608 sub_irdisp(code, 1, opts->gen.context_reg, zr_off(Z80_BC), SZ_W); | 608 sub_irdisp(code, 1, opts->gen.context_reg, zr_off(Z80_BC), SZ_W); |
609 } | 609 } |
610 mov_irdisp(code, 0, opts->gen.context_reg, zf_off(ZF_H), SZ_B); | |
611 mov_irdisp(code, 0, opts->gen.context_reg, zf_off(ZF_N), SZ_B); | |
610 uint8_t * cont = code->cur+1; | 612 uint8_t * cont = code->cur+1; |
611 jcc(code, CC_Z, code->cur+2); | 613 jcc(code, CC_Z, code->cur+2); |
612 cycles(&opts->gen, 7); | 614 cycles(&opts->gen, 7); |
613 //TODO: Figure out what the flag state should be here | 615 mov_irdisp(code, 1, opts->gen.context_reg, zf_off(ZF_PV), SZ_B); |
614 //TODO: Figure out whether an interrupt can interrupt this | |
615 jmp(code, start); | 616 jmp(code, start); |
616 *cont = code->cur - (cont + 1); | 617 *cont = code->cur - (cont + 1); |
617 cycles(&opts->gen, 2); | 618 cycles(&opts->gen, 2); |
618 mov_irdisp(code, 0, opts->gen.context_reg, zf_off(ZF_H), SZ_B); | |
619 mov_irdisp(code, 0, opts->gen.context_reg, zf_off(ZF_N), SZ_B); | |
620 mov_irdisp(code, 0, opts->gen.context_reg, zf_off(ZF_PV), SZ_B); | 619 mov_irdisp(code, 0, opts->gen.context_reg, zf_off(ZF_PV), SZ_B); |
621 break; | 620 break; |
622 } | 621 } |
623 case Z80_LDD: { | 622 case Z80_LDD: { |
624 cycles(&opts->gen, 8); | 623 cycles(&opts->gen, 8); |
666 if (opts->regs[Z80_BC] >= 0) { | 665 if (opts->regs[Z80_BC] >= 0) { |
667 sub_ir(code, 1, opts->regs[Z80_BC], SZ_W); | 666 sub_ir(code, 1, opts->regs[Z80_BC], SZ_W); |
668 } else { | 667 } else { |
669 sub_irdisp(code, 1, opts->gen.context_reg, zr_off(Z80_BC), SZ_W); | 668 sub_irdisp(code, 1, opts->gen.context_reg, zr_off(Z80_BC), SZ_W); |
670 } | 669 } |
670 mov_irdisp(code, 0, opts->gen.context_reg, zf_off(ZF_H), SZ_B); | |
671 mov_irdisp(code, 0, opts->gen.context_reg, zf_off(ZF_N), SZ_B); | |
671 uint8_t * cont = code->cur+1; | 672 uint8_t * cont = code->cur+1; |
672 jcc(code, CC_Z, code->cur+2); | 673 jcc(code, CC_Z, code->cur+2); |
673 cycles(&opts->gen, 7); | 674 cycles(&opts->gen, 7); |
674 //TODO: Figure out what the flag state should be here | 675 mov_irdisp(code, 1, opts->gen.context_reg, zf_off(ZF_PV), SZ_B); |
675 jmp(code, start); | 676 jmp(code, start); |
676 *cont = code->cur - (cont + 1); | 677 *cont = code->cur - (cont + 1); |
677 cycles(&opts->gen, 2); | 678 cycles(&opts->gen, 2); |
678 mov_irdisp(code, 0, opts->gen.context_reg, zf_off(ZF_H), SZ_B); | |
679 mov_irdisp(code, 0, opts->gen.context_reg, zf_off(ZF_N), SZ_B); | |
680 mov_irdisp(code, 0, opts->gen.context_reg, zf_off(ZF_PV), SZ_B); | 679 mov_irdisp(code, 0, opts->gen.context_reg, zf_off(ZF_PV), SZ_B); |
681 break; | 680 break; |
682 } | 681 } |
683 /*case Z80_CPI: | 682 case Z80_CPI: |
684 case Z80_CPIR: | 683 cycles(&opts->gen, 8);//T-States 4,4 |
684 zreg_to_native(opts, Z80_HL, opts->gen.scratch1); | |
685 call(code, opts->read_8);//T-States 3 | |
686 cmp_rr(code, opts->gen.scratch1, opts->regs[Z80_A], SZ_B); | |
687 mov_irdisp(code, 1, opts->gen.context_reg, zf_off(ZF_N), SZ_B); | |
688 setcc_rdisp(code, CC_Z, opts->gen.context_reg, zf_off(ZF_Z)); | |
689 setcc_rdisp(code, CC_S, opts->gen.context_reg, zf_off(ZF_S)); | |
690 //TODO: Implement half-carry flag | |
691 cycles(&opts->gen, 5);//T-States 5 | |
692 if (opts->regs[Z80_HL] >= 0) { | |
693 add_ir(code, 1, opts->regs[Z80_HL], SZ_W); | |
694 } else { | |
695 add_irdisp(code, 1, opts->gen.context_reg, zr_off(Z80_HL), SZ_W); | |
696 } | |
697 if (opts->regs[Z80_BC] >= 0) { | |
698 sub_ir(code, 1, opts->regs[Z80_BC], SZ_W); | |
699 } else { | |
700 sub_irdisp(code, 1, opts->gen.context_reg, zr_off(Z80_BC), SZ_W); | |
701 } | |
702 setcc_rdisp(code, CC_NZ, opts->gen.context_reg, zf_off(ZF_PV)); | |
703 break; | |
704 case Z80_CPIR: { | |
705 cycles(&opts->gen, 8);//T-States 4,4 | |
706 zreg_to_native(opts, Z80_HL, opts->gen.scratch1); | |
707 call(code, opts->read_8);//T-States 3 | |
708 cmp_rr(code, opts->gen.scratch1, opts->regs[Z80_A], SZ_B); | |
709 mov_irdisp(code, 1, opts->gen.context_reg, zf_off(ZF_N), SZ_B); | |
710 setcc_rdisp(code, CC_Z, opts->gen.context_reg, zf_off(ZF_Z)); | |
711 setcc_rdisp(code, CC_S, opts->gen.context_reg, zf_off(ZF_S)); | |
712 //TODO: Implement half-carry flag | |
713 cycles(&opts->gen, 5);//T-States 5 | |
714 if (opts->regs[Z80_HL] >= 0) { | |
715 add_ir(code, 1, opts->regs[Z80_HL], SZ_W); | |
716 } else { | |
717 add_irdisp(code, 1, opts->gen.context_reg, zr_off(Z80_HL), SZ_W); | |
718 } | |
719 if (opts->regs[Z80_BC] >= 0) { | |
720 sub_ir(code, 1, opts->regs[Z80_BC], SZ_W); | |
721 } else { | |
722 sub_irdisp(code, 1, opts->gen.context_reg, zr_off(Z80_BC), SZ_W); | |
723 } | |
724 setcc_rdisp(code, CC_NZ, opts->gen.context_reg, zf_off(ZF_PV)); | |
725 uint8_t * cont = code->cur+1; | |
726 jcc(code, CC_Z, code->cur+2); | |
727 cmp_rr(code, opts->gen.scratch1, opts->regs[Z80_A], SZ_B); | |
728 uint8_t * cont2 = code->cur+1; | |
729 jcc(code, CC_Z, code->cur+2); | |
730 //repeat case | |
731 cycles(&opts->gen, 5);//T-States 5 | |
732 jmp(code, start); | |
733 *cont = code->cur - (cont + 1); | |
734 *cont2 = code->cur - (cont2 + 1); | |
735 break; | |
736 } | |
685 case Z80_CPD: | 737 case Z80_CPD: |
686 case Z80_CPDR: | 738 cycles(&opts->gen, 8);//T-States 4,4 |
687 break;*/ | 739 zreg_to_native(opts, Z80_HL, opts->gen.scratch1); |
740 call(code, opts->read_8);//T-States 3 | |
741 cmp_rr(code, opts->gen.scratch1, opts->regs[Z80_A], SZ_B); | |
742 mov_irdisp(code, 1, opts->gen.context_reg, zf_off(ZF_N), SZ_B); | |
743 setcc_rdisp(code, CC_Z, opts->gen.context_reg, zf_off(ZF_Z)); | |
744 setcc_rdisp(code, CC_S, opts->gen.context_reg, zf_off(ZF_S)); | |
745 //TODO: Implement half-carry flag | |
746 cycles(&opts->gen, 5);//T-States 5 | |
747 if (opts->regs[Z80_HL] >= 0) { | |
748 sub_ir(code, 1, opts->regs[Z80_HL], SZ_W); | |
749 } else { | |
750 sub_irdisp(code, 1, opts->gen.context_reg, zr_off(Z80_HL), SZ_W); | |
751 } | |
752 if (opts->regs[Z80_BC] >= 0) { | |
753 sub_ir(code, 1, opts->regs[Z80_BC], SZ_W); | |
754 } else { | |
755 sub_irdisp(code, 1, opts->gen.context_reg, zr_off(Z80_BC), SZ_W); | |
756 } | |
757 setcc_rdisp(code, CC_NZ, opts->gen.context_reg, zf_off(ZF_PV)); | |
758 break; | |
759 case Z80_CPDR: { | |
760 cycles(&opts->gen, 8);//T-States 4,4 | |
761 zreg_to_native(opts, Z80_HL, opts->gen.scratch1); | |
762 call(code, opts->read_8);//T-States 3 | |
763 cmp_rr(code, opts->gen.scratch1, opts->regs[Z80_A], SZ_B); | |
764 mov_irdisp(code, 1, opts->gen.context_reg, zf_off(ZF_N), SZ_B); | |
765 setcc_rdisp(code, CC_Z, opts->gen.context_reg, zf_off(ZF_Z)); | |
766 setcc_rdisp(code, CC_S, opts->gen.context_reg, zf_off(ZF_S)); | |
767 //TODO: Implement half-carry flag | |
768 cycles(&opts->gen, 5);//T-States 5 | |
769 if (opts->regs[Z80_HL] >= 0) { | |
770 sub_ir(code, 1, opts->regs[Z80_HL], SZ_W); | |
771 } else { | |
772 sub_irdisp(code, 1, opts->gen.context_reg, zr_off(Z80_HL), SZ_W); | |
773 } | |
774 if (opts->regs[Z80_BC] >= 0) { | |
775 sub_ir(code, 1, opts->regs[Z80_BC], SZ_W); | |
776 } else { | |
777 sub_irdisp(code, 1, opts->gen.context_reg, zr_off(Z80_BC), SZ_W); | |
778 } | |
779 setcc_rdisp(code, CC_NZ, opts->gen.context_reg, zf_off(ZF_PV)); | |
780 uint8_t * cont = code->cur+1; | |
781 jcc(code, CC_Z, code->cur+2); | |
782 cmp_rr(code, opts->gen.scratch1, opts->regs[Z80_A], SZ_B); | |
783 uint8_t * cont2 = code->cur+1; | |
784 jcc(code, CC_Z, code->cur+2); | |
785 //repeat case | |
786 cycles(&opts->gen, 5);//T-States 5 | |
787 jmp(code, start); | |
788 *cont = code->cur - (cont + 1); | |
789 *cont2 = code->cur - (cont2 + 1); | |
790 break; | |
791 } | |
688 case Z80_ADD: | 792 case Z80_ADD: |
689 num_cycles = 4; | 793 num_cycles = 4; |
690 if (inst->addr_mode == Z80_IX_DISPLACE || inst->addr_mode == Z80_IY_DISPLACE) { | 794 if (inst->addr_mode == Z80_IX_DISPLACE || inst->addr_mode == Z80_IY_DISPLACE) { |
691 num_cycles += 12; | 795 num_cycles += 12; |
692 } else if(inst->addr_mode == Z80_IMMED) { | 796 } else if(inst->addr_mode == Z80_IMMED) { |
1055 setcc_rdisp(code, CC_Z, opts->gen.context_reg, zf_off(ZF_Z)); | 1159 setcc_rdisp(code, CC_Z, opts->gen.context_reg, zf_off(ZF_Z)); |
1056 setcc_rdisp(code, CC_S, opts->gen.context_reg, zf_off(ZF_S)); | 1160 setcc_rdisp(code, CC_S, opts->gen.context_reg, zf_off(ZF_S)); |
1057 setcc_rdisp(code, CC_P, opts->gen.context_reg, zf_off(ZF_PV)); | 1161 setcc_rdisp(code, CC_P, opts->gen.context_reg, zf_off(ZF_PV)); |
1058 code_ptr no_carry = code->cur+1; | 1162 code_ptr no_carry = code->cur+1; |
1059 jcc(code, CC_NC, code->cur+2); | 1163 jcc(code, CC_NC, code->cur+2); |
1060 mov_ir(code, 1, opts->gen.context_reg, zf_off(ZF_C)); | 1164 mov_irdisp(code, 1, opts->gen.context_reg, zf_off(ZF_C), SZ_B); |
1061 *no_carry = code->cur - (no_carry + 1); | 1165 *no_carry = code->cur - (no_carry + 1); |
1062 //TODO: Implement half-carry flag | 1166 //TODO: Implement half-carry flag |
1063 break; | 1167 break; |
1064 case Z80_CPL: | 1168 case Z80_CPL: |
1065 cycles(&opts->gen, 4); | 1169 cycles(&opts->gen, 4); |