Mercurial > repos > blastem
comparison z80_to_x86.c @ 308:e0e81551fd7e
Deal with the fact that there's no 8-bit version of the BT family of instructions on x86
author | Mike Pavone <pavone@retrodev.com> |
---|---|
date | Thu, 09 May 2013 00:14:54 -0700 |
parents | b6393b89a7e4 |
children | cb6a37861e42 |
comparison
equal
deleted
inserted
replaced
307:b6393b89a7e4 | 308:e0e81551fd7e |
---|---|
1148 | 1148 |
1149 dst = mov_rr(dst, opts->regs[Z80_HL], SCRATCH2, SZ_W); | 1149 dst = mov_rr(dst, opts->regs[Z80_HL], SCRATCH2, SZ_W); |
1150 dst = ror_ir(dst, 8, SCRATCH1, SZ_W); | 1150 dst = ror_ir(dst, 8, SCRATCH1, SZ_W); |
1151 dst = call(dst, (uint8_t *)z80_write_byte); | 1151 dst = call(dst, (uint8_t *)z80_write_byte); |
1152 break; | 1152 break; |
1153 case Z80_BIT: | 1153 case Z80_BIT: { |
1154 cycles = (inst->addr_mode == Z80_IX_DISPLACE || inst->addr_mode == Z80_IY_DISPLACE) ? 8 : 16; | 1154 cycles = (inst->addr_mode == Z80_IX_DISPLACE || inst->addr_mode == Z80_IY_DISPLACE) ? 8 : 16; |
1155 dst = zcycles(dst, cycles); | 1155 dst = zcycles(dst, cycles); |
1156 dst = translate_z80_ea(inst, &src_op, dst, opts, READ, DONT_MODIFY); | 1156 uint8_t bit; |
1157 if ((inst->addr_mode & 0x1F) == Z80_REG && opts->regs[inst->ea_reg] >= AH && opts->regs[inst->ea_reg] <= BH) { | |
1158 src_op.base = opts->regs[z80_word_reg(inst->ea_reg)]; | |
1159 size = SZ_W; | |
1160 bit = inst->immed + 8; | |
1161 } else { | |
1162 size = SZ_B; | |
1163 bit = inst->immed; | |
1164 dst = translate_z80_ea(inst, &src_op, dst, opts, READ, DONT_MODIFY); | |
1165 } | |
1157 if (inst->addr_mode != Z80_REG) { | 1166 if (inst->addr_mode != Z80_REG) { |
1158 //Reads normally take 3 cycles, but the read at the end of a bit instruction takes 4 | 1167 //Reads normally take 3 cycles, but the read at the end of a bit instruction takes 4 |
1159 dst = zcycles(dst, 1); | 1168 dst = zcycles(dst, 1); |
1160 } | 1169 } |
1161 dst = bt_ir(dst, inst->immed, src_op.base, SZ_B); | 1170 dst = bt_ir(dst, bit, src_op.base, size); |
1162 dst = setcc_rdisp8(dst, CC_NC, CONTEXT, zf_off(ZF_Z)); | 1171 dst = setcc_rdisp8(dst, CC_NC, CONTEXT, zf_off(ZF_Z)); |
1163 dst = setcc_rdisp8(dst, CC_NC, CONTEXT, zf_off(ZF_PV)); | 1172 dst = setcc_rdisp8(dst, CC_NC, CONTEXT, zf_off(ZF_PV)); |
1164 dst = mov_irdisp8(dst, 0, CONTEXT, zf_off(ZF_N), SZ_B); | 1173 dst = mov_irdisp8(dst, 0, CONTEXT, zf_off(ZF_N), SZ_B); |
1165 if (inst->immed == 7) { | 1174 if (inst->immed == 7) { |
1166 dst = cmp_ir(dst, 0, src_op.base, SZ_B); | 1175 dst = cmp_ir(dst, 0, src_op.base, size); |
1167 dst = setcc_rdisp8(dst, CC_S, CONTEXT, zf_off(ZF_S)); | 1176 dst = setcc_rdisp8(dst, CC_S, CONTEXT, zf_off(ZF_S)); |
1168 } else { | 1177 } else { |
1169 dst = mov_irdisp8(dst, 0, CONTEXT, zf_off(ZF_S), SZ_B); | 1178 dst = mov_irdisp8(dst, 0, CONTEXT, zf_off(ZF_S), SZ_B); |
1170 } | 1179 } |
1171 break; | 1180 break; |
1172 case Z80_SET: | 1181 } |
1182 case Z80_SET: { | |
1173 cycles = (inst->addr_mode == Z80_IX_DISPLACE || inst->addr_mode == Z80_IY_DISPLACE) ? 8 : 16; | 1183 cycles = (inst->addr_mode == Z80_IX_DISPLACE || inst->addr_mode == Z80_IY_DISPLACE) ? 8 : 16; |
1174 dst = zcycles(dst, cycles); | 1184 dst = zcycles(dst, cycles); |
1175 dst = translate_z80_ea(inst, &src_op, dst, opts, READ, MODIFY); | 1185 uint8_t bit; |
1186 if ((inst->addr_mode & 0x1F) == Z80_REG && opts->regs[inst->ea_reg] >= AH && opts->regs[inst->ea_reg] <= BH) { | |
1187 src_op.base = opts->regs[z80_word_reg(inst->ea_reg)]; | |
1188 size = SZ_W; | |
1189 bit = inst->immed + 8; | |
1190 } else { | |
1191 size = SZ_B; | |
1192 bit = inst->immed; | |
1193 dst = translate_z80_ea(inst, &src_op, dst, opts, READ, DONT_MODIFY); | |
1194 } | |
1176 if (inst->reg != Z80_USE_IMMED) { | 1195 if (inst->reg != Z80_USE_IMMED) { |
1177 dst = translate_z80_reg(inst, &dst_op, dst, opts); | 1196 dst = translate_z80_reg(inst, &dst_op, dst, opts); |
1178 } | 1197 } |
1179 if (inst->addr_mode != Z80_REG) { | 1198 if (inst->addr_mode != Z80_REG) { |
1180 //Reads normally take 3 cycles, but the read in the middle of a set instruction takes 4 | 1199 //Reads normally take 3 cycles, but the read in the middle of a set instruction takes 4 |
1181 dst = zcycles(dst, 1); | 1200 dst = zcycles(dst, 1); |
1182 } | 1201 } |
1183 dst = bts_ir(dst, inst->immed, src_op.base, SZ_B); | 1202 dst = bts_ir(dst, bit, src_op.base, size); |
1184 if (inst->reg != Z80_USE_IMMED) { | 1203 if (inst->reg != Z80_USE_IMMED) { |
1185 dst = mov_rr(dst, src_op.base, dst_op.base, SZ_B); | 1204 if (size == SZ_W) { |
1205 if (dst_op.base >= R8) { | |
1206 dst = ror_ir(dst, 8, src_op.base, SZ_W); | |
1207 dst = mov_rr(dst, opts->regs[z80_low_reg(inst->ea_reg)], dst_op.base, SZ_B); | |
1208 dst = ror_ir(dst, 8, src_op.base, SZ_W); | |
1209 } else { | |
1210 dst = mov_rr(dst, opts->regs[inst->ea_reg], dst_op.base, SZ_B); | |
1211 } | |
1212 } else { | |
1213 dst = mov_rr(dst, src_op.base, dst_op.base, SZ_B); | |
1214 } | |
1215 } | |
1216 if ((inst->addr_mode & 0x1F) != Z80_REG) { | |
1217 dst = z80_save_result(dst, inst); | |
1218 if (inst->reg != Z80_USE_IMMED) { | |
1219 dst = z80_save_reg(dst, inst, opts); | |
1220 } | |
1221 } | |
1222 break; | |
1223 } | |
1224 case Z80_RES: { | |
1225 cycles = (inst->addr_mode == Z80_IX_DISPLACE || inst->addr_mode == Z80_IY_DISPLACE) ? 8 : 16; | |
1226 dst = zcycles(dst, cycles); | |
1227 uint8_t bit; | |
1228 if ((inst->addr_mode & 0x1F) == Z80_REG && opts->regs[inst->ea_reg] >= AH && opts->regs[inst->ea_reg] <= BH) { | |
1229 src_op.base = opts->regs[z80_word_reg(inst->ea_reg)]; | |
1230 size = SZ_W; | |
1231 bit = inst->immed + 8; | |
1232 } else { | |
1233 size = SZ_B; | |
1234 bit = inst->immed; | |
1235 dst = translate_z80_ea(inst, &src_op, dst, opts, READ, DONT_MODIFY); | |
1236 } | |
1237 if (inst->reg != Z80_USE_IMMED) { | |
1238 dst = translate_z80_reg(inst, &dst_op, dst, opts); | |
1239 } | |
1240 if (inst->addr_mode != Z80_REG) { | |
1241 //Reads normally take 3 cycles, but the read in the middle of a set instruction takes 4 | |
1242 dst = zcycles(dst, 1); | |
1243 } | |
1244 dst = btr_ir(dst, bit, src_op.base, size); | |
1245 if (inst->reg != Z80_USE_IMMED) { | |
1246 if (size == SZ_W) { | |
1247 if (dst_op.base >= R8) { | |
1248 dst = ror_ir(dst, 8, src_op.base, SZ_W); | |
1249 dst = mov_rr(dst, opts->regs[z80_low_reg(inst->ea_reg)], dst_op.base, SZ_B); | |
1250 dst = ror_ir(dst, 8, src_op.base, SZ_W); | |
1251 } else { | |
1252 dst = mov_rr(dst, opts->regs[inst->ea_reg], dst_op.base, SZ_B); | |
1253 } | |
1254 } else { | |
1255 dst = mov_rr(dst, src_op.base, dst_op.base, SZ_B); | |
1256 } | |
1186 } | 1257 } |
1187 if (inst->addr_mode != Z80_REG) { | 1258 if (inst->addr_mode != Z80_REG) { |
1188 dst = z80_save_result(dst, inst); | 1259 dst = z80_save_result(dst, inst); |
1189 if (inst->reg != Z80_USE_IMMED) { | 1260 if (inst->reg != Z80_USE_IMMED) { |
1190 dst = z80_save_reg(dst, inst, opts); | 1261 dst = z80_save_reg(dst, inst, opts); |
1191 } | 1262 } |
1192 } | 1263 } |
1193 break; | 1264 break; |
1194 case Z80_RES: | 1265 } |
1195 cycles = (inst->addr_mode == Z80_IX_DISPLACE || inst->addr_mode == Z80_IY_DISPLACE) ? 8 : 16; | |
1196 dst = zcycles(dst, cycles); | |
1197 dst = translate_z80_ea(inst, &src_op, dst, opts, READ, MODIFY); | |
1198 if (inst->reg != Z80_USE_IMMED) { | |
1199 dst = translate_z80_reg(inst, &dst_op, dst, opts); | |
1200 } | |
1201 if (inst->addr_mode != Z80_REG) { | |
1202 //Reads normally take 3 cycles, but the read in the middle of a set instruction takes 4 | |
1203 dst = zcycles(dst, 1); | |
1204 } | |
1205 dst = btr_ir(dst, inst->immed, src_op.base, SZ_B); | |
1206 if (inst->reg != Z80_USE_IMMED) { | |
1207 dst = mov_rr(dst, src_op.base, dst_op.base, SZ_B); | |
1208 } | |
1209 if (inst->addr_mode != Z80_REG) { | |
1210 dst = z80_save_result(dst, inst); | |
1211 if (inst->reg != Z80_USE_IMMED) { | |
1212 dst = z80_save_reg(dst, inst, opts); | |
1213 } | |
1214 } | |
1215 break; | |
1216 case Z80_JP: { | 1266 case Z80_JP: { |
1217 cycles = 4; | 1267 cycles = 4; |
1218 if (inst->addr_mode != Z80_REG) { | 1268 if (inst->addr_mode != Z80_REG) { |
1219 cycles += 6; | 1269 cycles += 6; |
1220 } else if(inst->ea_reg == Z80_IX || inst->ea_reg == Z80_IY) { | 1270 } else if(inst->ea_reg == Z80_IX || inst->ea_reg == Z80_IY) { |