Mercurial > repos > blastem
comparison z80_to_x86.c @ 651:103d5cabbe14
Fix flags for rra, rrca, rla and rlca. Fix timing for rr, rrc, rl and rlc when using IX or IY. Fix access to I and R registers (R still needs to be made 7-bit though). Fix flags for ld a, i. The fix for access to I fixes PCM playback in Titan Overdrive and music playback in Crackdown.
author | Michael Pavone <pavone@retrodev.com> |
---|---|
date | Tue, 16 Dec 2014 01:10:54 -0800 |
parents | 2d7e84ae818c |
children | f822d9216968 |
comparison
equal
deleted
inserted
replaced
650:55b550fe8891 | 651:103d5cabbe14 |
---|---|
155 ea->base = SCRATCH1; | 155 ea->base = SCRATCH1; |
156 } else { | 156 } else { |
157 ea->base = opts->regs[Z80_IYL]; | 157 ea->base = opts->regs[Z80_IYL]; |
158 dst = ror_ir(dst, 8, opts->regs[Z80_IY], SZ_W); | 158 dst = ror_ir(dst, 8, opts->regs[Z80_IY], SZ_W); |
159 } | 159 } |
160 } else { | 160 } else if(opts->regs[inst->ea_reg] >= 0) { |
161 ea->base = opts->regs[inst->ea_reg]; | 161 ea->base = opts->regs[inst->ea_reg]; |
162 if (ea->base >= AH && ea->base <= BH && inst->reg != Z80_UNUSED && inst->reg != Z80_USE_IMMED) { | 162 if (ea->base >= AH && ea->base <= BH && inst->reg != Z80_UNUSED && inst->reg != Z80_USE_IMMED) { |
163 uint8_t other_reg = opts->regs[inst->reg]; | 163 uint8_t other_reg = opts->regs[inst->reg]; |
164 if (other_reg >= R8 || (other_reg >= RSP && other_reg <= RDI)) { | 164 if (other_reg >= R8 || (other_reg >= RSP && other_reg <= RDI)) { |
165 //we can't mix an *H reg with a register that requires the REX prefix | 165 //we can't mix an *H reg with a register that requires the REX prefix |
166 ea->base = opts->regs[z80_low_reg(inst->ea_reg)]; | 166 ea->base = opts->regs[z80_low_reg(inst->ea_reg)]; |
167 dst = ror_ir(dst, 8, ea->base, SZ_W); | 167 dst = ror_ir(dst, 8, ea->base, SZ_W); |
168 } | 168 } |
169 } | 169 } |
170 } else { | |
171 ea->mode = MODE_REG_DISPLACE8; | |
172 ea->base = CONTEXT; | |
173 ea->disp = offsetof(z80_context, regs) + inst->ea_reg; | |
170 } | 174 } |
171 break; | 175 break; |
172 case Z80_REG_INDIRECT: | 176 case Z80_REG_INDIRECT: |
173 dst = mov_rr(dst, opts->regs[inst->ea_reg], areg, SZ_W); | 177 dst = mov_rr(dst, opts->regs[inst->ea_reg], areg, SZ_W); |
174 size = z80_size(inst); | 178 size = z80_size(inst); |
387 } | 391 } |
388 } else if(src_op.mode == MODE_IMMED) { | 392 } else if(src_op.mode == MODE_IMMED) { |
389 dst = mov_ir(dst, src_op.disp, dst_op.base, size); | 393 dst = mov_ir(dst, src_op.disp, dst_op.base, size); |
390 } else { | 394 } else { |
391 dst = mov_rdisp8r(dst, src_op.base, src_op.disp, dst_op.base, size); | 395 dst = mov_rdisp8r(dst, src_op.base, src_op.disp, dst_op.base, size); |
396 } | |
397 if (inst->ea_reg == Z80_I && inst->addr_mode == Z80_REG) { | |
398 //ld a, i sets some flags | |
399 //TODO: Implement half-carry flag | |
400 dst = cmp_ir(dst, 0, dst_op.base, SZ_B); | |
401 dst = setcc_rdisp8(dst, CC_Z, CONTEXT, zf_off(ZF_Z)); | |
402 dst = setcc_rdisp8(dst, CC_S, CONTEXT, zf_off(ZF_S)); | |
403 dst = mov_irdisp8(dst, 0, CONTEXT, zf_off(ZF_N), SZ_B);; | |
404 dst = mov_rdisp8r(dst, CONTEXT, offsetof(z80_context, iff2), SCRATCH1, SZ_B); | |
405 dst = mov_rrdisp8(dst, SCRATCH1, CONTEXT, zf_off(ZF_PV), SZ_B); | |
392 } | 406 } |
393 dst = z80_save_reg(dst, inst, opts); | 407 dst = z80_save_reg(dst, inst, opts); |
394 dst = z80_save_ea(dst, inst, opts); | 408 dst = z80_save_ea(dst, inst, opts); |
395 if (inst->addr_mode & Z80_DIR) { | 409 if (inst->addr_mode & Z80_DIR) { |
396 dst = z80_save_result(dst, inst); | 410 dst = z80_save_result(dst, inst); |
943 dst = mov_rr(dst, dst_op.base, src_op.base, SZ_B); | 957 dst = mov_rr(dst, dst_op.base, src_op.base, SZ_B); |
944 } | 958 } |
945 dst = setcc_rdisp8(dst, CC_C, CONTEXT, zf_off(ZF_C)); | 959 dst = setcc_rdisp8(dst, CC_C, CONTEXT, zf_off(ZF_C)); |
946 dst = mov_irdisp8(dst, 0, CONTEXT, zf_off(ZF_N), SZ_B); | 960 dst = mov_irdisp8(dst, 0, CONTEXT, zf_off(ZF_N), SZ_B); |
947 //TODO: Implement half-carry flag | 961 //TODO: Implement half-carry flag |
948 dst = cmp_ir(dst, 0, dst_op.base, SZ_B); | 962 if (inst->immed) { |
949 dst = setcc_rdisp8(dst, CC_P, CONTEXT, zf_off(ZF_PV)); | 963 //rlca does not set these flags |
950 dst = setcc_rdisp8(dst, CC_Z, CONTEXT, zf_off(ZF_Z)); | 964 dst = cmp_ir(dst, 0, dst_op.base, SZ_B); |
951 dst = setcc_rdisp8(dst, CC_S, CONTEXT, zf_off(ZF_S)); | 965 dst = setcc_rdisp8(dst, CC_P, CONTEXT, zf_off(ZF_PV)); |
966 dst = setcc_rdisp8(dst, CC_Z, CONTEXT, zf_off(ZF_Z)); | |
967 dst = setcc_rdisp8(dst, CC_S, CONTEXT, zf_off(ZF_S)); | |
968 } | |
952 if (inst->addr_mode != Z80_UNUSED) { | 969 if (inst->addr_mode != Z80_UNUSED) { |
953 dst = z80_save_result(dst, inst); | 970 dst = z80_save_result(dst, inst); |
954 if (src_op.mode != MODE_UNUSED) { | 971 if (src_op.mode != MODE_UNUSED) { |
955 dst = z80_save_reg(dst, inst, opts); | 972 dst = z80_save_reg(dst, inst, opts); |
956 } | 973 } |
975 dst = mov_rr(dst, dst_op.base, src_op.base, SZ_B); | 992 dst = mov_rr(dst, dst_op.base, src_op.base, SZ_B); |
976 } | 993 } |
977 dst = setcc_rdisp8(dst, CC_C, CONTEXT, zf_off(ZF_C)); | 994 dst = setcc_rdisp8(dst, CC_C, CONTEXT, zf_off(ZF_C)); |
978 dst = mov_irdisp8(dst, 0, CONTEXT, zf_off(ZF_N), SZ_B); | 995 dst = mov_irdisp8(dst, 0, CONTEXT, zf_off(ZF_N), SZ_B); |
979 //TODO: Implement half-carry flag | 996 //TODO: Implement half-carry flag |
980 dst = cmp_ir(dst, 0, dst_op.base, SZ_B); | 997 if (inst->immed) { |
981 dst = setcc_rdisp8(dst, CC_P, CONTEXT, zf_off(ZF_PV)); | 998 //rla does not set these flags |
982 dst = setcc_rdisp8(dst, CC_Z, CONTEXT, zf_off(ZF_Z)); | 999 dst = cmp_ir(dst, 0, dst_op.base, SZ_B); |
983 dst = setcc_rdisp8(dst, CC_S, CONTEXT, zf_off(ZF_S)); | 1000 dst = setcc_rdisp8(dst, CC_P, CONTEXT, zf_off(ZF_PV)); |
1001 dst = setcc_rdisp8(dst, CC_Z, CONTEXT, zf_off(ZF_Z)); | |
1002 dst = setcc_rdisp8(dst, CC_S, CONTEXT, zf_off(ZF_S)); | |
1003 } | |
984 if (inst->addr_mode != Z80_UNUSED) { | 1004 if (inst->addr_mode != Z80_UNUSED) { |
985 dst = z80_save_result(dst, inst); | 1005 dst = z80_save_result(dst, inst); |
986 if (src_op.mode != MODE_UNUSED) { | 1006 if (src_op.mode != MODE_UNUSED) { |
987 dst = z80_save_reg(dst, inst, opts); | 1007 dst = z80_save_reg(dst, inst, opts); |
988 } | 1008 } |
1006 dst = mov_rr(dst, dst_op.base, src_op.base, SZ_B); | 1026 dst = mov_rr(dst, dst_op.base, src_op.base, SZ_B); |
1007 } | 1027 } |
1008 dst = setcc_rdisp8(dst, CC_C, CONTEXT, zf_off(ZF_C)); | 1028 dst = setcc_rdisp8(dst, CC_C, CONTEXT, zf_off(ZF_C)); |
1009 dst = mov_irdisp8(dst, 0, CONTEXT, zf_off(ZF_N), SZ_B); | 1029 dst = mov_irdisp8(dst, 0, CONTEXT, zf_off(ZF_N), SZ_B); |
1010 //TODO: Implement half-carry flag | 1030 //TODO: Implement half-carry flag |
1011 dst = cmp_ir(dst, 0, dst_op.base, SZ_B); | 1031 if (inst->immed) { |
1012 dst = setcc_rdisp8(dst, CC_P, CONTEXT, zf_off(ZF_PV)); | 1032 //rrca does not set these flags |
1013 dst = setcc_rdisp8(dst, CC_Z, CONTEXT, zf_off(ZF_Z)); | 1033 dst = cmp_ir(dst, 0, dst_op.base, SZ_B); |
1014 dst = setcc_rdisp8(dst, CC_S, CONTEXT, zf_off(ZF_S)); | 1034 dst = setcc_rdisp8(dst, CC_P, CONTEXT, zf_off(ZF_PV)); |
1035 dst = setcc_rdisp8(dst, CC_Z, CONTEXT, zf_off(ZF_Z)); | |
1036 dst = setcc_rdisp8(dst, CC_S, CONTEXT, zf_off(ZF_S)); | |
1037 } | |
1015 if (inst->addr_mode != Z80_UNUSED) { | 1038 if (inst->addr_mode != Z80_UNUSED) { |
1016 dst = z80_save_result(dst, inst); | 1039 dst = z80_save_result(dst, inst); |
1017 if (src_op.mode != MODE_UNUSED) { | 1040 if (src_op.mode != MODE_UNUSED) { |
1018 dst = z80_save_reg(dst, inst, opts); | 1041 dst = z80_save_reg(dst, inst, opts); |
1019 } | 1042 } |
1038 dst = mov_rr(dst, dst_op.base, src_op.base, SZ_B); | 1061 dst = mov_rr(dst, dst_op.base, src_op.base, SZ_B); |
1039 } | 1062 } |
1040 dst = setcc_rdisp8(dst, CC_C, CONTEXT, zf_off(ZF_C)); | 1063 dst = setcc_rdisp8(dst, CC_C, CONTEXT, zf_off(ZF_C)); |
1041 dst = mov_irdisp8(dst, 0, CONTEXT, zf_off(ZF_N), SZ_B); | 1064 dst = mov_irdisp8(dst, 0, CONTEXT, zf_off(ZF_N), SZ_B); |
1042 //TODO: Implement half-carry flag | 1065 //TODO: Implement half-carry flag |
1043 dst = cmp_ir(dst, 0, dst_op.base, SZ_B); | 1066 if (inst->immed) { |
1044 dst = setcc_rdisp8(dst, CC_P, CONTEXT, zf_off(ZF_PV)); | 1067 //rra does not set these flags |
1045 dst = setcc_rdisp8(dst, CC_Z, CONTEXT, zf_off(ZF_Z)); | 1068 dst = cmp_ir(dst, 0, dst_op.base, SZ_B); |
1046 dst = setcc_rdisp8(dst, CC_S, CONTEXT, zf_off(ZF_S)); | 1069 dst = setcc_rdisp8(dst, CC_P, CONTEXT, zf_off(ZF_PV)); |
1070 dst = setcc_rdisp8(dst, CC_Z, CONTEXT, zf_off(ZF_Z)); | |
1071 dst = setcc_rdisp8(dst, CC_S, CONTEXT, zf_off(ZF_S)); | |
1072 } | |
1047 if (inst->addr_mode != Z80_UNUSED) { | 1073 if (inst->addr_mode != Z80_UNUSED) { |
1048 dst = z80_save_result(dst, inst); | 1074 dst = z80_save_result(dst, inst); |
1049 if (src_op.mode != MODE_UNUSED) { | 1075 if (src_op.mode != MODE_UNUSED) { |
1050 dst = z80_save_reg(dst, inst, opts); | 1076 dst = z80_save_reg(dst, inst, opts); |
1051 } | 1077 } |
2103 } | 2129 } |
2104 } | 2130 } |
2105 | 2131 |
2106 void zremove_breakpoint(z80_context * context, uint16_t address) | 2132 void zremove_breakpoint(z80_context * context, uint16_t address) |
2107 { | 2133 { |
2108 context->breakpoint_flags[address / sizeof(uint8_t)] &= 1 << (address % sizeof(uint8_t)); | 2134 context->breakpoint_flags[address / sizeof(uint8_t)] &= ~(1 << (address % sizeof(uint8_t))); |
2109 uint8_t * native = z80_get_native_address(context, address); | 2135 uint8_t * native = z80_get_native_address(context, address); |
2110 if (native) { | 2136 if (native) { |
2111 z80_check_cycles_int(native, address); | 2137 z80_check_cycles_int(native, address); |
2112 } | 2138 } |
2113 } | 2139 } |