Mercurial > repos > blastem
comparison z80_to_x86.c @ 299:42e1a986f2d0
Fix calcuation of IX/IY dipslacements. Fix a bunch of stuff related to the IX/IY bit/shift/rotate instructions.
author | Mike Pavone <pavone@retrodev.com> |
---|---|
date | Wed, 08 May 2013 22:46:03 -0700 |
parents | dba661846579 |
children | 9adc1dce39bf |
comparison
equal
deleted
inserted
replaced
298:170722e80fc0 | 299:42e1a986f2d0 |
---|---|
187 break; | 187 break; |
188 case Z80_IX_DISPLACE: | 188 case Z80_IX_DISPLACE: |
189 case Z80_IY_DISPLACE: | 189 case Z80_IY_DISPLACE: |
190 reg = opts->regs[inst->addr_mode == Z80_IX_DISPLACE ? Z80_IX : Z80_IY]; | 190 reg = opts->regs[inst->addr_mode == Z80_IX_DISPLACE ? Z80_IX : Z80_IY]; |
191 dst = mov_rr(dst, reg, areg, SZ_W); | 191 dst = mov_rr(dst, reg, areg, SZ_W); |
192 dst = add_ir(dst, inst->immed, areg, SZ_W); | 192 dst = add_ir(dst, inst->ea_reg, areg, SZ_W); |
193 size = z80_size(inst); | 193 size = z80_size(inst); |
194 if (read) { | 194 if (read) { |
195 if (modify) { | 195 if (modify) { |
196 //dst = push_r(dst, SCRATCH1); | 196 //dst = push_r(dst, SCRATCH1); |
197 dst = mov_rrdisp8(dst, SCRATCH1, CONTEXT, offsetof(z80_context, scratch1), SZ_W); | 197 dst = mov_rrdisp8(dst, SCRATCH1, CONTEXT, offsetof(z80_context, scratch1), SZ_W); |
878 dst = mov_irdisp8(dst, inst->immed, CONTEXT, offsetof(z80_context, im), SZ_B); | 878 dst = mov_irdisp8(dst, inst->immed, CONTEXT, offsetof(z80_context, im), SZ_B); |
879 break; | 879 break; |
880 case Z80_RLC: | 880 case Z80_RLC: |
881 cycles = inst->immed == 0 ? 4 : (inst->addr_mode == Z80_IX_DISPLACE || inst->addr_mode == Z80_IY_DISPLACE ? 16 : 8); | 881 cycles = inst->immed == 0 ? 4 : (inst->addr_mode == Z80_IX_DISPLACE || inst->addr_mode == Z80_IY_DISPLACE ? 16 : 8); |
882 dst = zcycles(dst, cycles); | 882 dst = zcycles(dst, cycles); |
883 if (inst->reg == Z80_UNUSED) { | 883 if (inst->addr_mode != Z80_UNUSED) { |
884 dst = translate_z80_ea(inst, &dst_op, dst, opts, READ, MODIFY); | 884 dst = translate_z80_ea(inst, &dst_op, dst, opts, READ, MODIFY); |
885 dst = translate_z80_reg(inst, &src_op, dst, opts); //For IX/IY variants that also write to a register | |
885 dst = zcycles(dst, 1); | 886 dst = zcycles(dst, 1); |
886 } else { | 887 } else { |
888 src_op.mode = Z80_UNUSED; | |
887 dst = translate_z80_reg(inst, &dst_op, dst, opts); | 889 dst = translate_z80_reg(inst, &dst_op, dst, opts); |
888 } | 890 } |
889 dst = rol_ir(dst, 1, dst_op.base, SZ_B); | 891 dst = rol_ir(dst, 1, dst_op.base, SZ_B); |
892 if (src_op.mode != Z80_UNUSED) { | |
893 dst = mov_rr(dst, dst_op.base, src_op.base, SZ_B); | |
894 } | |
890 dst = setcc_rdisp8(dst, CC_C, CONTEXT, zf_off(ZF_C)); | 895 dst = setcc_rdisp8(dst, CC_C, CONTEXT, zf_off(ZF_C)); |
891 dst = mov_irdisp8(dst, 0, CONTEXT, zf_off(ZF_N), SZ_B); | 896 dst = mov_irdisp8(dst, 0, CONTEXT, zf_off(ZF_N), SZ_B); |
892 //TODO: Implement half-carry flag | 897 //TODO: Implement half-carry flag |
893 dst = cmp_ir(dst, 0, dst_op.base, SZ_B); | 898 dst = cmp_ir(dst, 0, dst_op.base, SZ_B); |
894 dst = setcc_rdisp8(dst, CC_P, CONTEXT, zf_off(ZF_PV)); | 899 dst = setcc_rdisp8(dst, CC_P, CONTEXT, zf_off(ZF_PV)); |
895 dst = setcc_rdisp8(dst, CC_Z, CONTEXT, zf_off(ZF_Z)); | 900 dst = setcc_rdisp8(dst, CC_Z, CONTEXT, zf_off(ZF_Z)); |
896 dst = setcc_rdisp8(dst, CC_S, CONTEXT, zf_off(ZF_S)); | 901 dst = setcc_rdisp8(dst, CC_S, CONTEXT, zf_off(ZF_S)); |
897 if (inst->reg == Z80_UNUSED) { | 902 if (inst->addr_mode != Z80_UNUSED) { |
898 dst = z80_save_result(dst, inst); | 903 dst = z80_save_result(dst, inst); |
904 if (src_op.mode != MODE_UNUSED) { | |
905 dst = z80_save_reg(dst, inst, opts); | |
906 } | |
899 } else { | 907 } else { |
900 dst = z80_save_reg(dst, inst, opts); | 908 dst = z80_save_reg(dst, inst, opts); |
901 } | 909 } |
902 break; | 910 break; |
903 case Z80_RL: | 911 case Z80_RL: |
904 cycles = inst->immed == 0 ? 4 : (inst->addr_mode == Z80_IX_DISPLACE || inst->addr_mode == Z80_IY_DISPLACE ? 16 : 8); | 912 cycles = inst->immed == 0 ? 4 : (inst->addr_mode == Z80_IX_DISPLACE || inst->addr_mode == Z80_IY_DISPLACE ? 16 : 8); |
905 dst = zcycles(dst, cycles); | 913 dst = zcycles(dst, cycles); |
906 if (inst->reg == Z80_UNUSED) { | 914 if (inst->addr_mode != Z80_UNUSED) { |
907 dst = translate_z80_ea(inst, &dst_op, dst, opts, READ, MODIFY); | 915 dst = translate_z80_ea(inst, &dst_op, dst, opts, READ, MODIFY); |
916 dst = translate_z80_reg(inst, &src_op, dst, opts); //For IX/IY variants that also write to a register | |
908 dst = zcycles(dst, 1); | 917 dst = zcycles(dst, 1); |
909 } else { | 918 } else { |
919 src_op.mode = Z80_UNUSED; | |
910 dst = translate_z80_reg(inst, &dst_op, dst, opts); | 920 dst = translate_z80_reg(inst, &dst_op, dst, opts); |
911 } | 921 } |
912 dst = bt_irdisp8(dst, 0, CONTEXT, zf_off(ZF_C), SZ_B); | 922 dst = bt_irdisp8(dst, 0, CONTEXT, zf_off(ZF_C), SZ_B); |
913 dst = rcl_ir(dst, 1, dst_op.base, SZ_B); | 923 dst = rcl_ir(dst, 1, dst_op.base, SZ_B); |
924 if (src_op.mode != Z80_UNUSED) { | |
925 dst = mov_rr(dst, dst_op.base, src_op.base, SZ_B); | |
926 } | |
914 dst = setcc_rdisp8(dst, CC_C, CONTEXT, zf_off(ZF_C)); | 927 dst = setcc_rdisp8(dst, CC_C, CONTEXT, zf_off(ZF_C)); |
915 dst = mov_irdisp8(dst, 0, CONTEXT, zf_off(ZF_N), SZ_B); | 928 dst = mov_irdisp8(dst, 0, CONTEXT, zf_off(ZF_N), SZ_B); |
916 //TODO: Implement half-carry flag | 929 //TODO: Implement half-carry flag |
917 dst = cmp_ir(dst, 0, dst_op.base, SZ_B); | 930 dst = cmp_ir(dst, 0, dst_op.base, SZ_B); |
918 dst = setcc_rdisp8(dst, CC_P, CONTEXT, zf_off(ZF_PV)); | 931 dst = setcc_rdisp8(dst, CC_P, CONTEXT, zf_off(ZF_PV)); |
919 dst = setcc_rdisp8(dst, CC_Z, CONTEXT, zf_off(ZF_Z)); | 932 dst = setcc_rdisp8(dst, CC_Z, CONTEXT, zf_off(ZF_Z)); |
920 dst = setcc_rdisp8(dst, CC_S, CONTEXT, zf_off(ZF_S)); | 933 dst = setcc_rdisp8(dst, CC_S, CONTEXT, zf_off(ZF_S)); |
921 if (inst->reg == Z80_UNUSED) { | 934 if (inst->addr_mode != Z80_UNUSED) { |
922 dst = z80_save_result(dst, inst); | 935 dst = z80_save_result(dst, inst); |
936 if (src_op.mode != MODE_UNUSED) { | |
937 dst = z80_save_reg(dst, inst, opts); | |
938 } | |
923 } else { | 939 } else { |
924 dst = z80_save_reg(dst, inst, opts); | 940 dst = z80_save_reg(dst, inst, opts); |
925 } | 941 } |
926 break; | 942 break; |
927 case Z80_RRC: | 943 case Z80_RRC: |
928 cycles = inst->immed == 0 ? 4 : (inst->addr_mode == Z80_IX_DISPLACE || inst->addr_mode == Z80_IY_DISPLACE ? 16 : 8); | 944 cycles = inst->immed == 0 ? 4 : (inst->addr_mode == Z80_IX_DISPLACE || inst->addr_mode == Z80_IY_DISPLACE ? 16 : 8); |
929 dst = zcycles(dst, cycles); | 945 dst = zcycles(dst, cycles); |
930 if (inst->reg == Z80_UNUSED) { | 946 if (inst->addr_mode != Z80_UNUSED) { |
931 dst = translate_z80_ea(inst, &dst_op, dst, opts, READ, MODIFY); | 947 dst = translate_z80_ea(inst, &dst_op, dst, opts, READ, MODIFY); |
948 dst = translate_z80_reg(inst, &src_op, dst, opts); //For IX/IY variants that also write to a register | |
932 dst = zcycles(dst, 1); | 949 dst = zcycles(dst, 1); |
933 } else { | 950 } else { |
951 src_op.mode = Z80_UNUSED; | |
934 dst = translate_z80_reg(inst, &dst_op, dst, opts); | 952 dst = translate_z80_reg(inst, &dst_op, dst, opts); |
935 } | 953 } |
936 dst = ror_ir(dst, 1, dst_op.base, SZ_B); | 954 dst = ror_ir(dst, 1, dst_op.base, SZ_B); |
955 if (src_op.mode != Z80_UNUSED) { | |
956 dst = mov_rr(dst, dst_op.base, src_op.base, SZ_B); | |
957 } | |
937 dst = setcc_rdisp8(dst, CC_C, CONTEXT, zf_off(ZF_C)); | 958 dst = setcc_rdisp8(dst, CC_C, CONTEXT, zf_off(ZF_C)); |
938 dst = mov_irdisp8(dst, 0, CONTEXT, zf_off(ZF_N), SZ_B); | 959 dst = mov_irdisp8(dst, 0, CONTEXT, zf_off(ZF_N), SZ_B); |
939 //TODO: Implement half-carry flag | 960 //TODO: Implement half-carry flag |
940 dst = cmp_ir(dst, 0, dst_op.base, SZ_B); | 961 dst = cmp_ir(dst, 0, dst_op.base, SZ_B); |
941 dst = setcc_rdisp8(dst, CC_P, CONTEXT, zf_off(ZF_PV)); | 962 dst = setcc_rdisp8(dst, CC_P, CONTEXT, zf_off(ZF_PV)); |
942 dst = setcc_rdisp8(dst, CC_Z, CONTEXT, zf_off(ZF_Z)); | 963 dst = setcc_rdisp8(dst, CC_Z, CONTEXT, zf_off(ZF_Z)); |
943 dst = setcc_rdisp8(dst, CC_S, CONTEXT, zf_off(ZF_S)); | 964 dst = setcc_rdisp8(dst, CC_S, CONTEXT, zf_off(ZF_S)); |
944 if (inst->reg == Z80_UNUSED) { | 965 if (inst->addr_mode != Z80_UNUSED) { |
945 dst = z80_save_result(dst, inst); | 966 dst = z80_save_result(dst, inst); |
967 if (src_op.mode != MODE_UNUSED) { | |
968 dst = z80_save_reg(dst, inst, opts); | |
969 } | |
946 } else { | 970 } else { |
947 dst = z80_save_reg(dst, inst, opts); | 971 dst = z80_save_reg(dst, inst, opts); |
948 } | 972 } |
949 break; | 973 break; |
950 case Z80_RR: | 974 case Z80_RR: |
951 cycles = inst->immed == 0 ? 4 : (inst->addr_mode == Z80_IX_DISPLACE || inst->addr_mode == Z80_IY_DISPLACE ? 16 : 8); | 975 cycles = inst->immed == 0 ? 4 : (inst->addr_mode == Z80_IX_DISPLACE || inst->addr_mode == Z80_IY_DISPLACE ? 16 : 8); |
952 dst = zcycles(dst, cycles); | 976 dst = zcycles(dst, cycles); |
953 if (inst->reg == Z80_UNUSED) { | 977 if (inst->addr_mode != Z80_UNUSED) { |
954 dst = translate_z80_ea(inst, &dst_op, dst, opts, READ, MODIFY); | 978 dst = translate_z80_ea(inst, &dst_op, dst, opts, READ, MODIFY); |
979 dst = translate_z80_reg(inst, &src_op, dst, opts); //For IX/IY variants that also write to a register | |
955 dst = zcycles(dst, 1); | 980 dst = zcycles(dst, 1); |
956 } else { | 981 } else { |
982 src_op.mode = Z80_UNUSED; | |
957 dst = translate_z80_reg(inst, &dst_op, dst, opts); | 983 dst = translate_z80_reg(inst, &dst_op, dst, opts); |
958 } | 984 } |
959 dst = bt_irdisp8(dst, 0, CONTEXT, zf_off(ZF_C), SZ_B); | 985 dst = bt_irdisp8(dst, 0, CONTEXT, zf_off(ZF_C), SZ_B); |
960 dst = rcr_ir(dst, 1, dst_op.base, SZ_B); | 986 dst = rcr_ir(dst, 1, dst_op.base, SZ_B); |
987 if (src_op.mode != Z80_UNUSED) { | |
988 dst = mov_rr(dst, dst_op.base, src_op.base, SZ_B); | |
989 } | |
961 dst = setcc_rdisp8(dst, CC_C, CONTEXT, zf_off(ZF_C)); | 990 dst = setcc_rdisp8(dst, CC_C, CONTEXT, zf_off(ZF_C)); |
962 dst = mov_irdisp8(dst, 0, CONTEXT, zf_off(ZF_N), SZ_B); | 991 dst = mov_irdisp8(dst, 0, CONTEXT, zf_off(ZF_N), SZ_B); |
963 //TODO: Implement half-carry flag | 992 //TODO: Implement half-carry flag |
964 dst = cmp_ir(dst, 0, dst_op.base, SZ_B); | 993 dst = cmp_ir(dst, 0, dst_op.base, SZ_B); |
965 dst = setcc_rdisp8(dst, CC_P, CONTEXT, zf_off(ZF_PV)); | 994 dst = setcc_rdisp8(dst, CC_P, CONTEXT, zf_off(ZF_PV)); |
966 dst = setcc_rdisp8(dst, CC_Z, CONTEXT, zf_off(ZF_Z)); | 995 dst = setcc_rdisp8(dst, CC_Z, CONTEXT, zf_off(ZF_Z)); |
967 dst = setcc_rdisp8(dst, CC_S, CONTEXT, zf_off(ZF_S)); | 996 dst = setcc_rdisp8(dst, CC_S, CONTEXT, zf_off(ZF_S)); |
968 if (inst->reg == Z80_UNUSED) { | 997 if (inst->addr_mode != Z80_UNUSED) { |
969 dst = z80_save_result(dst, inst); | 998 dst = z80_save_result(dst, inst); |
999 if (src_op.mode != MODE_UNUSED) { | |
1000 dst = z80_save_reg(dst, inst, opts); | |
1001 } | |
970 } else { | 1002 } else { |
971 dst = z80_save_reg(dst, inst, opts); | 1003 dst = z80_save_reg(dst, inst, opts); |
972 } | 1004 } |
973 break; | 1005 break; |
974 case Z80_SLA: | 1006 case Z80_SLA: |
975 case Z80_SLL: | 1007 case Z80_SLL: |
976 cycles = inst->addr_mode == Z80_IX_DISPLACE || inst->addr_mode == Z80_IY_DISPLACE ? 16 : 8; | 1008 cycles = inst->addr_mode == Z80_IX_DISPLACE || inst->addr_mode == Z80_IY_DISPLACE ? 16 : 8; |
977 dst = zcycles(dst, cycles); | 1009 dst = zcycles(dst, cycles); |
978 if (inst->reg == Z80_UNUSED) { | 1010 if (inst->addr_mode != Z80_UNUSED) { |
979 dst = translate_z80_ea(inst, &dst_op, dst, opts, READ, MODIFY); | 1011 dst = translate_z80_ea(inst, &dst_op, dst, opts, READ, MODIFY); |
1012 dst = translate_z80_reg(inst, &src_op, dst, opts); //For IX/IY variants that also write to a register | |
980 dst = zcycles(dst, 1); | 1013 dst = zcycles(dst, 1); |
981 } else { | 1014 } else { |
1015 src_op.mode = Z80_UNUSED; | |
982 dst = translate_z80_reg(inst, &dst_op, dst, opts); | 1016 dst = translate_z80_reg(inst, &dst_op, dst, opts); |
983 } | 1017 } |
984 dst = shl_ir(dst, 1, dst_op.base, SZ_B); | 1018 dst = shl_ir(dst, 1, dst_op.base, SZ_B); |
1019 if (src_op.mode != Z80_UNUSED) { | |
1020 dst = mov_rr(dst, dst_op.base, src_op.base, SZ_B); | |
1021 } | |
985 dst = mov_irdisp8(dst, 0, CONTEXT, zf_off(ZF_N), SZ_B); | 1022 dst = mov_irdisp8(dst, 0, CONTEXT, zf_off(ZF_N), SZ_B); |
986 //TODO: Implement half-carry flag | 1023 //TODO: Implement half-carry flag |
987 dst = cmp_ir(dst, 0, dst_op.base, SZ_B); | 1024 dst = cmp_ir(dst, 0, dst_op.base, SZ_B); |
988 dst = setcc_rdisp8(dst, CC_P, CONTEXT, zf_off(ZF_PV)); | 1025 dst = setcc_rdisp8(dst, CC_P, CONTEXT, zf_off(ZF_PV)); |
989 dst = setcc_rdisp8(dst, CC_Z, CONTEXT, zf_off(ZF_Z)); | 1026 dst = setcc_rdisp8(dst, CC_Z, CONTEXT, zf_off(ZF_Z)); |
990 dst = setcc_rdisp8(dst, CC_S, CONTEXT, zf_off(ZF_S)); | 1027 dst = setcc_rdisp8(dst, CC_S, CONTEXT, zf_off(ZF_S)); |
991 if (inst->reg == Z80_UNUSED) { | 1028 if (inst->addr_mode != Z80_UNUSED) { |
992 dst = z80_save_result(dst, inst); | 1029 dst = z80_save_result(dst, inst); |
1030 if (src_op.mode != MODE_UNUSED) { | |
1031 dst = z80_save_reg(dst, inst, opts); | |
1032 } | |
993 } else { | 1033 } else { |
994 dst = z80_save_reg(dst, inst, opts); | 1034 dst = z80_save_reg(dst, inst, opts); |
995 } | 1035 } |
996 break; | 1036 break; |
997 case Z80_SRA: | 1037 case Z80_SRA: |
998 cycles = inst->addr_mode == Z80_IX_DISPLACE || inst->addr_mode == Z80_IY_DISPLACE ? 16 : 8; | 1038 cycles = inst->addr_mode == Z80_IX_DISPLACE || inst->addr_mode == Z80_IY_DISPLACE ? 16 : 8; |
999 dst = zcycles(dst, cycles); | 1039 dst = zcycles(dst, cycles); |
1000 if (inst->reg == Z80_UNUSED) { | 1040 if (inst->addr_mode != Z80_UNUSED) { |
1001 dst = translate_z80_ea(inst, &dst_op, dst, opts, READ, MODIFY); | 1041 dst = translate_z80_ea(inst, &dst_op, dst, opts, READ, MODIFY); |
1042 dst = translate_z80_reg(inst, &src_op, dst, opts); //For IX/IY variants that also write to a register | |
1002 dst = zcycles(dst, 1); | 1043 dst = zcycles(dst, 1); |
1003 } else { | 1044 } else { |
1045 src_op.mode = Z80_UNUSED; | |
1004 dst = translate_z80_reg(inst, &dst_op, dst, opts); | 1046 dst = translate_z80_reg(inst, &dst_op, dst, opts); |
1005 } | 1047 } |
1006 dst = sar_ir(dst, 1, dst_op.base, SZ_B); | 1048 dst = sar_ir(dst, 1, dst_op.base, SZ_B); |
1049 if (src_op.mode != Z80_UNUSED) { | |
1050 dst = mov_rr(dst, dst_op.base, src_op.base, SZ_B); | |
1051 } | |
1007 dst = mov_irdisp8(dst, 0, CONTEXT, zf_off(ZF_N), SZ_B); | 1052 dst = mov_irdisp8(dst, 0, CONTEXT, zf_off(ZF_N), SZ_B); |
1008 //TODO: Implement half-carry flag | 1053 //TODO: Implement half-carry flag |
1009 dst = cmp_ir(dst, 0, dst_op.base, SZ_B); | 1054 dst = cmp_ir(dst, 0, dst_op.base, SZ_B); |
1010 dst = setcc_rdisp8(dst, CC_P, CONTEXT, zf_off(ZF_PV)); | 1055 dst = setcc_rdisp8(dst, CC_P, CONTEXT, zf_off(ZF_PV)); |
1011 dst = setcc_rdisp8(dst, CC_Z, CONTEXT, zf_off(ZF_Z)); | 1056 dst = setcc_rdisp8(dst, CC_Z, CONTEXT, zf_off(ZF_Z)); |
1012 dst = setcc_rdisp8(dst, CC_S, CONTEXT, zf_off(ZF_S)); | 1057 dst = setcc_rdisp8(dst, CC_S, CONTEXT, zf_off(ZF_S)); |
1013 if (inst->reg == Z80_UNUSED) { | 1058 if (inst->addr_mode != Z80_UNUSED) { |
1014 dst = z80_save_result(dst, inst); | 1059 dst = z80_save_result(dst, inst); |
1060 if (src_op.mode != MODE_UNUSED) { | |
1061 dst = z80_save_reg(dst, inst, opts); | |
1062 } | |
1015 } else { | 1063 } else { |
1016 dst = z80_save_reg(dst, inst, opts); | 1064 dst = z80_save_reg(dst, inst, opts); |
1017 } | 1065 } |
1018 break; | 1066 break; |
1019 case Z80_SRL: | 1067 case Z80_SRL: |
1020 cycles = inst->addr_mode == Z80_IX_DISPLACE || inst->addr_mode == Z80_IY_DISPLACE ? 16 : 8; | 1068 cycles = inst->addr_mode == Z80_IX_DISPLACE || inst->addr_mode == Z80_IY_DISPLACE ? 16 : 8; |
1021 dst = zcycles(dst, cycles); | 1069 dst = zcycles(dst, cycles); |
1022 if (inst->reg == Z80_UNUSED) { | 1070 if (inst->addr_mode != Z80_UNUSED) { |
1023 dst = translate_z80_ea(inst, &dst_op, dst, opts, READ, MODIFY); | 1071 dst = translate_z80_ea(inst, &dst_op, dst, opts, READ, MODIFY); |
1072 dst = translate_z80_reg(inst, &src_op, dst, opts); //For IX/IY variants that also write to a register | |
1024 dst = zcycles(dst, 1); | 1073 dst = zcycles(dst, 1); |
1025 } else { | 1074 } else { |
1075 src_op.mode = Z80_UNUSED; | |
1026 dst = translate_z80_reg(inst, &dst_op, dst, opts); | 1076 dst = translate_z80_reg(inst, &dst_op, dst, opts); |
1027 } | 1077 } |
1028 dst = shr_ir(dst, 1, dst_op.base, SZ_B); | 1078 dst = shr_ir(dst, 1, dst_op.base, SZ_B); |
1079 if (src_op.mode != Z80_UNUSED) { | |
1080 dst = mov_rr(dst, dst_op.base, src_op.base, SZ_B); | |
1081 } | |
1029 dst = mov_irdisp8(dst, 0, CONTEXT, zf_off(ZF_N), SZ_B); | 1082 dst = mov_irdisp8(dst, 0, CONTEXT, zf_off(ZF_N), SZ_B); |
1030 //TODO: Implement half-carry flag | 1083 //TODO: Implement half-carry flag |
1031 dst = cmp_ir(dst, 0, dst_op.base, SZ_B); | 1084 dst = cmp_ir(dst, 0, dst_op.base, SZ_B); |
1032 dst = setcc_rdisp8(dst, CC_P, CONTEXT, zf_off(ZF_PV)); | 1085 dst = setcc_rdisp8(dst, CC_P, CONTEXT, zf_off(ZF_PV)); |
1033 dst = setcc_rdisp8(dst, CC_Z, CONTEXT, zf_off(ZF_Z)); | 1086 dst = setcc_rdisp8(dst, CC_Z, CONTEXT, zf_off(ZF_Z)); |
1034 dst = setcc_rdisp8(dst, CC_S, CONTEXT, zf_off(ZF_S)); | 1087 dst = setcc_rdisp8(dst, CC_S, CONTEXT, zf_off(ZF_S)); |
1035 if (inst->reg == Z80_UNUSED) { | 1088 if (inst->addr_mode != Z80_UNUSED) { |
1036 dst = z80_save_result(dst, inst); | 1089 dst = z80_save_result(dst, inst); |
1090 if (src_op.mode != MODE_UNUSED) { | |
1091 dst = z80_save_reg(dst, inst, opts); | |
1092 } | |
1037 } else { | 1093 } else { |
1038 dst = z80_save_reg(dst, inst, opts); | 1094 dst = z80_save_reg(dst, inst, opts); |
1039 } | 1095 } |
1040 case Z80_RLD: | 1096 case Z80_RLD: |
1041 dst = zcycles(dst, 8); | 1097 dst = zcycles(dst, 8); |
1106 dst = setcc_rdisp8(dst, CC_C, CONTEXT, zf_off(ZF_Z)); | 1162 dst = setcc_rdisp8(dst, CC_C, CONTEXT, zf_off(ZF_Z)); |
1107 break; | 1163 break; |
1108 case Z80_SET: | 1164 case Z80_SET: |
1109 cycles = (inst->addr_mode == Z80_IX_DISPLACE || inst->addr_mode == Z80_IY_DISPLACE) ? 8 : 16; | 1165 cycles = (inst->addr_mode == Z80_IX_DISPLACE || inst->addr_mode == Z80_IY_DISPLACE) ? 8 : 16; |
1110 dst = zcycles(dst, cycles); | 1166 dst = zcycles(dst, cycles); |
1111 dst = translate_z80_ea(inst, &src_op, dst, opts, READ, DONT_MODIFY); | 1167 dst = translate_z80_ea(inst, &src_op, dst, opts, READ, MODIFY); |
1168 if (inst->reg != Z80_USE_IMMED) { | |
1169 dst = translate_z80_reg(inst, &dst_op, dst, opts); | |
1170 } | |
1112 if (inst->addr_mode != Z80_REG) { | 1171 if (inst->addr_mode != Z80_REG) { |
1113 //Reads normally take 3 cycles, but the read in the middle of a set instruction takes 4 | 1172 //Reads normally take 3 cycles, but the read in the middle of a set instruction takes 4 |
1114 dst = zcycles(dst, 1); | 1173 dst = zcycles(dst, 1); |
1115 } | 1174 } |
1116 dst = bts_ir(dst, inst->immed, src_op.base, SZ_B); | 1175 dst = bts_ir(dst, inst->immed, src_op.base, SZ_B); |
1176 if (inst->reg != Z80_USE_IMMED) { | |
1177 dst = mov_rr(dst, src_op.base, dst_op.base, SZ_B); | |
1178 } | |
1117 if (inst->addr_mode != Z80_REG) { | 1179 if (inst->addr_mode != Z80_REG) { |
1118 dst = z80_save_result(dst, inst); | 1180 dst = z80_save_result(dst, inst); |
1181 if (inst->reg != Z80_USE_IMMED) { | |
1182 dst = z80_save_reg(dst, inst, opts); | |
1183 } | |
1119 } | 1184 } |
1120 break; | 1185 break; |
1121 case Z80_RES: | 1186 case Z80_RES: |
1122 cycles = (inst->addr_mode == Z80_IX_DISPLACE || inst->addr_mode == Z80_IY_DISPLACE) ? 8 : 16; | 1187 cycles = (inst->addr_mode == Z80_IX_DISPLACE || inst->addr_mode == Z80_IY_DISPLACE) ? 8 : 16; |
1123 dst = zcycles(dst, cycles); | 1188 dst = zcycles(dst, cycles); |
1124 dst = translate_z80_ea(inst, &src_op, dst, opts, READ, DONT_MODIFY); | 1189 dst = translate_z80_ea(inst, &src_op, dst, opts, READ, MODIFY); |
1190 if (inst->reg != Z80_USE_IMMED) { | |
1191 dst = translate_z80_reg(inst, &dst_op, dst, opts); | |
1192 } | |
1125 if (inst->addr_mode != Z80_REG) { | 1193 if (inst->addr_mode != Z80_REG) { |
1126 //Reads normally take 3 cycles, but the read in the middle of a set instruction takes 4 | 1194 //Reads normally take 3 cycles, but the read in the middle of a set instruction takes 4 |
1127 dst = zcycles(dst, 1); | 1195 dst = zcycles(dst, 1); |
1128 } | 1196 } |
1129 dst = btr_ir(dst, inst->immed, src_op.base, SZ_B); | 1197 dst = btr_ir(dst, inst->immed, src_op.base, SZ_B); |
1198 if (inst->reg != Z80_USE_IMMED) { | |
1199 dst = mov_rr(dst, src_op.base, dst_op.base, SZ_B); | |
1200 } | |
1130 if (inst->addr_mode != Z80_REG) { | 1201 if (inst->addr_mode != Z80_REG) { |
1131 dst = z80_save_result(dst, inst); | 1202 dst = z80_save_result(dst, inst); |
1203 if (inst->reg != Z80_USE_IMMED) { | |
1204 dst = z80_save_reg(dst, inst, opts); | |
1205 } | |
1132 } | 1206 } |
1133 break; | 1207 break; |
1134 case Z80_JP: { | 1208 case Z80_JP: { |
1135 cycles = 4; | 1209 cycles = 4; |
1136 if (inst->addr_mode != Z80_REG) { | 1210 if (inst->addr_mode != Z80_REG) { |