diff options
author | Mike Pavone <pavone@retrodev.com> | 2013-04-26 22:27:17 -0700 |
---|---|---|
committer | Mike Pavone <pavone@retrodev.com> | 2013-04-26 22:27:17 -0700 |
commit | e2831e79c7d9c9d26cf39d5ebf0b6771d338112a (patch) | |
tree | 5bfacf4c38482e2c4e7bfc3be744e82fb9d28eaf | |
parent | 17887b4d8549205ceede462e984f1ca2e3f1916b (diff) |
Implement BIT and DJNZ (tested). Fix register mapping for IYL.
-rw-r--r-- | z80_to_x86.c | 47 |
1 files changed, 39 insertions, 8 deletions
diff --git a/z80_to_x86.c b/z80_to_x86.c index 8df0621..8f0c877 100644 --- a/z80_to_x86.c +++ b/z80_to_x86.c @@ -530,19 +530,29 @@ uint8_t * translate_z80inst(z80inst * inst, uint8_t * dst, z80_context * context case Z80_SLL: case Z80_SRL: case Z80_RLD: - case Z80_RRD: + case Z80_RRD:*/ case Z80_BIT: - case Z80_SET: - 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, 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 = setcc_rdisp8(dst, CC_C, CONTEXT, zf_off(ZF_Z)); + break; + //case Z80_SET: + //case Z80_RES: case Z80_JP: { cycles = 4; - if (inst->addr_mode != MODE_REG_INDIRECT) { + if (inst->addr_mode != Z80_REG) { cycles += 6; } else if(inst->ea_reg == Z80_IX || inst->ea_reg == Z80_IY) { cycles += 4; } dst = zcycles(dst, cycles); - if (inst->addr_mode != MODE_REG_INDIRECT && inst->immed < 0x4000) { + if (inst->addr_mode != Z80_REG_INDIRECT && inst->immed < 0x4000) { uint8_t * call_dst = z80_get_native_address(context, inst->immed); if (!call_dst) { opts->deferred = defer_address(opts->deferred, inst->immed, dst + 1); @@ -551,7 +561,7 @@ uint8_t * translate_z80inst(z80inst * inst, uint8_t * dst, z80_context * context } dst = jmp(dst, call_dst); } else { - if (inst->addr_mode == MODE_REG_INDIRECT) { + if (inst->addr_mode == Z80_REG_INDIRECT) { dst = mov_rr(dst, opts->regs[inst->ea_reg], SCRATCH1, SZ_W); } else { dst = mov_ir(dst, inst->immed, SCRATCH1, SZ_W); @@ -660,7 +670,28 @@ uint8_t * translate_z80inst(z80inst * inst, uint8_t * dst, z80_context * context *no_jump_off = dst - (no_jump_off+1); break; } - //case Z80_DJNZ:*/ + case Z80_DJNZ: + dst = zcycles(dst, 8);//T States: 5,3 + dst = sub_ir(dst, 1, opts->regs[Z80_B], SZ_B); + uint8_t *no_jump_off = dst+1; + dst = jcc(dst, CC_Z, dst+2); + dst = zcycles(dst, 5);//T States: 5 + uint16_t dest_addr = address + inst->immed + 2; + if (dest_addr < 0x4000) { + uint8_t * call_dst = z80_get_native_address(context, dest_addr); + if (!call_dst) { + opts->deferred = defer_address(opts->deferred, dest_addr, dst + 1); + //fake address to force large displacement + call_dst = dst + 256; + } + dst = jmp(dst, call_dst); + } else { + dst = mov_ir(dst, dest_addr, SCRATCH1, SZ_W); + dst = call(dst, (uint8_t *)z80_native_addr); + dst = jmp_r(dst, SCRATCH1); + } + *no_jump_off = dst - (no_jump_off+1); + break; case Z80_CALL: { dst = zcycles(dst, 11);//T States: 4,3,4 dst = sub_ir(dst, 2, opts->regs[Z80_SP], SZ_W); @@ -892,7 +923,7 @@ void init_x86_z80_opts(x86_z80_options * options) options->regs[Z80_IXH] = DH; options->regs[Z80_IXL] = RDX; options->regs[Z80_IYH] = -1; - options->regs[Z80_IYL] = -1; + options->regs[Z80_IYL] = R8; options->regs[Z80_I] = -1; options->regs[Z80_R] = -1; options->regs[Z80_A] = R10; |