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);