# HG changeset patch # User Mike Pavone # Date 1368083694 25200 # Node ID e0e81551fd7ebc1e0f93c3800da7136cce8490dd # Parent b6393b89a7e46cdd3511b051d1bff8b3fac4d920 Deal with the fact that there's no 8-bit version of the BT family of instructions on x86 diff -r b6393b89a7e4 -r e0e81551fd7e z80_to_x86.c --- a/z80_to_x86.c Wed May 08 23:44:49 2013 -0700 +++ b/z80_to_x86.c Thu May 09 00:14:54 2013 -0700 @@ -1150,29 +1150,48 @@ dst = ror_ir(dst, 8, SCRATCH1, SZ_W); dst = call(dst, (uint8_t *)z80_write_byte); break; - case Z80_BIT: + case Z80_BIT: { cycles = (inst->addr_mode == Z80_IX_DISPLACE || inst->addr_mode == Z80_IY_DISPLACE) ? 8 : 16; dst = zcycles(dst, cycles); - dst = translate_z80_ea(inst, &src_op, dst, opts, READ, DONT_MODIFY); + uint8_t bit; + if ((inst->addr_mode & 0x1F) == Z80_REG && opts->regs[inst->ea_reg] >= AH && opts->regs[inst->ea_reg] <= BH) { + src_op.base = opts->regs[z80_word_reg(inst->ea_reg)]; + size = SZ_W; + bit = inst->immed + 8; + } else { + size = SZ_B; + bit = inst->immed; + dst = translate_z80_ea(inst, &src_op, dst, opts, READ, DONT_MODIFY); + } if (inst->addr_mode != Z80_REG) { //Reads normally take 3 cycles, but the read at the end of a bit instruction takes 4 dst = zcycles(dst, 1); } - dst = bt_ir(dst, inst->immed, src_op.base, SZ_B); + dst = bt_ir(dst, bit, src_op.base, size); dst = setcc_rdisp8(dst, CC_NC, CONTEXT, zf_off(ZF_Z)); dst = setcc_rdisp8(dst, CC_NC, CONTEXT, zf_off(ZF_PV)); dst = mov_irdisp8(dst, 0, CONTEXT, zf_off(ZF_N), SZ_B); if (inst->immed == 7) { - dst = cmp_ir(dst, 0, src_op.base, SZ_B); + dst = cmp_ir(dst, 0, src_op.base, size); dst = setcc_rdisp8(dst, CC_S, CONTEXT, zf_off(ZF_S)); } else { dst = mov_irdisp8(dst, 0, CONTEXT, zf_off(ZF_S), SZ_B); } break; - case Z80_SET: + } + case Z80_SET: { cycles = (inst->addr_mode == Z80_IX_DISPLACE || inst->addr_mode == Z80_IY_DISPLACE) ? 8 : 16; dst = zcycles(dst, cycles); - dst = translate_z80_ea(inst, &src_op, dst, opts, READ, MODIFY); + uint8_t bit; + if ((inst->addr_mode & 0x1F) == Z80_REG && opts->regs[inst->ea_reg] >= AH && opts->regs[inst->ea_reg] <= BH) { + src_op.base = opts->regs[z80_word_reg(inst->ea_reg)]; + size = SZ_W; + bit = inst->immed + 8; + } else { + size = SZ_B; + bit = inst->immed; + dst = translate_z80_ea(inst, &src_op, dst, opts, READ, DONT_MODIFY); + } if (inst->reg != Z80_USE_IMMED) { dst = translate_z80_reg(inst, &dst_op, dst, opts); } @@ -1180,9 +1199,61 @@ //Reads normally take 3 cycles, but the read in the middle of a set instruction takes 4 dst = zcycles(dst, 1); } - dst = bts_ir(dst, inst->immed, src_op.base, SZ_B); + dst = bts_ir(dst, bit, src_op.base, size); if (inst->reg != Z80_USE_IMMED) { - dst = mov_rr(dst, src_op.base, dst_op.base, SZ_B); + if (size == SZ_W) { + if (dst_op.base >= R8) { + dst = ror_ir(dst, 8, src_op.base, SZ_W); + dst = mov_rr(dst, opts->regs[z80_low_reg(inst->ea_reg)], dst_op.base, SZ_B); + dst = ror_ir(dst, 8, src_op.base, SZ_W); + } else { + dst = mov_rr(dst, opts->regs[inst->ea_reg], dst_op.base, SZ_B); + } + } else { + dst = mov_rr(dst, src_op.base, dst_op.base, SZ_B); + } + } + if ((inst->addr_mode & 0x1F) != Z80_REG) { + dst = z80_save_result(dst, inst); + if (inst->reg != Z80_USE_IMMED) { + dst = z80_save_reg(dst, inst, opts); + } + } + break; + } + case Z80_RES: { + cycles = (inst->addr_mode == Z80_IX_DISPLACE || inst->addr_mode == Z80_IY_DISPLACE) ? 8 : 16; + dst = zcycles(dst, cycles); + uint8_t bit; + if ((inst->addr_mode & 0x1F) == Z80_REG && opts->regs[inst->ea_reg] >= AH && opts->regs[inst->ea_reg] <= BH) { + src_op.base = opts->regs[z80_word_reg(inst->ea_reg)]; + size = SZ_W; + bit = inst->immed + 8; + } else { + size = SZ_B; + bit = inst->immed; + dst = translate_z80_ea(inst, &src_op, dst, opts, READ, DONT_MODIFY); + } + if (inst->reg != Z80_USE_IMMED) { + dst = translate_z80_reg(inst, &dst_op, dst, opts); + } + if (inst->addr_mode != Z80_REG) { + //Reads normally take 3 cycles, but the read in the middle of a set instruction takes 4 + dst = zcycles(dst, 1); + } + dst = btr_ir(dst, bit, src_op.base, size); + if (inst->reg != Z80_USE_IMMED) { + if (size == SZ_W) { + if (dst_op.base >= R8) { + dst = ror_ir(dst, 8, src_op.base, SZ_W); + dst = mov_rr(dst, opts->regs[z80_low_reg(inst->ea_reg)], dst_op.base, SZ_B); + dst = ror_ir(dst, 8, src_op.base, SZ_W); + } else { + dst = mov_rr(dst, opts->regs[inst->ea_reg], dst_op.base, SZ_B); + } + } else { + dst = mov_rr(dst, src_op.base, dst_op.base, SZ_B); + } } if (inst->addr_mode != Z80_REG) { dst = z80_save_result(dst, inst); @@ -1191,28 +1262,7 @@ } } break; - case Z80_RES: - cycles = (inst->addr_mode == Z80_IX_DISPLACE || inst->addr_mode == Z80_IY_DISPLACE) ? 8 : 16; - dst = zcycles(dst, cycles); - dst = translate_z80_ea(inst, &src_op, dst, opts, READ, MODIFY); - if (inst->reg != Z80_USE_IMMED) { - dst = translate_z80_reg(inst, &dst_op, dst, opts); - } - if (inst->addr_mode != Z80_REG) { - //Reads normally take 3 cycles, but the read in the middle of a set instruction takes 4 - dst = zcycles(dst, 1); - } - dst = btr_ir(dst, inst->immed, src_op.base, SZ_B); - if (inst->reg != Z80_USE_IMMED) { - dst = mov_rr(dst, src_op.base, dst_op.base, SZ_B); - } - if (inst->addr_mode != Z80_REG) { - dst = z80_save_result(dst, inst); - if (inst->reg != Z80_USE_IMMED) { - dst = z80_save_reg(dst, inst, opts); - } - } - break; + } case Z80_JP: { cycles = 4; if (inst->addr_mode != Z80_REG) {