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 }