summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--z80_to_x86.c62
-rw-r--r--z80inst.c38
2 files changed, 63 insertions, 37 deletions
diff --git a/z80_to_x86.c b/z80_to_x86.c
index dc6cfaf..b529766 100644
--- a/z80_to_x86.c
+++ b/z80_to_x86.c
@@ -157,7 +157,7 @@ uint8_t * translate_z80_ea(z80inst * inst, x86_ea * ea, uint8_t * dst, x86_z80_o
ea->base = opts->regs[Z80_IYL];
dst = ror_ir(dst, 8, opts->regs[Z80_IY], SZ_W);
}
- } else {
+ } else if(opts->regs[inst->ea_reg] >= 0) {
ea->base = opts->regs[inst->ea_reg];
if (ea->base >= AH && ea->base <= BH && inst->reg != Z80_UNUSED && inst->reg != Z80_USE_IMMED) {
uint8_t other_reg = opts->regs[inst->reg];
@@ -167,6 +167,10 @@ uint8_t * translate_z80_ea(z80inst * inst, x86_ea * ea, uint8_t * dst, x86_z80_o
dst = ror_ir(dst, 8, ea->base, SZ_W);
}
}
+ } else {
+ ea->mode = MODE_REG_DISPLACE8;
+ ea->base = CONTEXT;
+ ea->disp = offsetof(z80_context, regs) + inst->ea_reg;
}
break;
case Z80_REG_INDIRECT:
@@ -390,6 +394,16 @@ uint8_t * translate_z80inst(z80inst * inst, uint8_t * dst, z80_context * context
} else {
dst = mov_rdisp8r(dst, src_op.base, src_op.disp, dst_op.base, size);
}
+ if (inst->ea_reg == Z80_I && inst->addr_mode == Z80_REG) {
+ //ld a, i sets some flags
+ //TODO: Implement half-carry flag
+ dst = cmp_ir(dst, 0, dst_op.base, SZ_B);
+ dst = setcc_rdisp8(dst, CC_Z, CONTEXT, zf_off(ZF_Z));
+ dst = setcc_rdisp8(dst, CC_S, CONTEXT, zf_off(ZF_S));
+ dst = mov_irdisp8(dst, 0, CONTEXT, zf_off(ZF_N), SZ_B);;
+ dst = mov_rdisp8r(dst, CONTEXT, offsetof(z80_context, iff2), SCRATCH1, SZ_B);
+ dst = mov_rrdisp8(dst, SCRATCH1, CONTEXT, zf_off(ZF_PV), SZ_B);
+ }
dst = z80_save_reg(dst, inst, opts);
dst = z80_save_ea(dst, inst, opts);
if (inst->addr_mode & Z80_DIR) {
@@ -945,10 +959,13 @@ uint8_t * translate_z80inst(z80inst * inst, uint8_t * dst, z80_context * context
dst = setcc_rdisp8(dst, CC_C, CONTEXT, zf_off(ZF_C));
dst = mov_irdisp8(dst, 0, CONTEXT, zf_off(ZF_N), SZ_B);
//TODO: Implement half-carry flag
- dst = cmp_ir(dst, 0, dst_op.base, SZ_B);
- dst = setcc_rdisp8(dst, CC_P, CONTEXT, zf_off(ZF_PV));
- dst = setcc_rdisp8(dst, CC_Z, CONTEXT, zf_off(ZF_Z));
- dst = setcc_rdisp8(dst, CC_S, CONTEXT, zf_off(ZF_S));
+ if (inst->immed) {
+ //rlca does not set these flags
+ dst = cmp_ir(dst, 0, dst_op.base, SZ_B);
+ dst = setcc_rdisp8(dst, CC_P, CONTEXT, zf_off(ZF_PV));
+ dst = setcc_rdisp8(dst, CC_Z, CONTEXT, zf_off(ZF_Z));
+ dst = setcc_rdisp8(dst, CC_S, CONTEXT, zf_off(ZF_S));
+ }
if (inst->addr_mode != Z80_UNUSED) {
dst = z80_save_result(dst, inst);
if (src_op.mode != MODE_UNUSED) {
@@ -977,10 +994,13 @@ uint8_t * translate_z80inst(z80inst * inst, uint8_t * dst, z80_context * context
dst = setcc_rdisp8(dst, CC_C, CONTEXT, zf_off(ZF_C));
dst = mov_irdisp8(dst, 0, CONTEXT, zf_off(ZF_N), SZ_B);
//TODO: Implement half-carry flag
- dst = cmp_ir(dst, 0, dst_op.base, SZ_B);
- dst = setcc_rdisp8(dst, CC_P, CONTEXT, zf_off(ZF_PV));
- dst = setcc_rdisp8(dst, CC_Z, CONTEXT, zf_off(ZF_Z));
- dst = setcc_rdisp8(dst, CC_S, CONTEXT, zf_off(ZF_S));
+ if (inst->immed) {
+ //rla does not set these flags
+ dst = cmp_ir(dst, 0, dst_op.base, SZ_B);
+ dst = setcc_rdisp8(dst, CC_P, CONTEXT, zf_off(ZF_PV));
+ dst = setcc_rdisp8(dst, CC_Z, CONTEXT, zf_off(ZF_Z));
+ dst = setcc_rdisp8(dst, CC_S, CONTEXT, zf_off(ZF_S));
+ }
if (inst->addr_mode != Z80_UNUSED) {
dst = z80_save_result(dst, inst);
if (src_op.mode != MODE_UNUSED) {
@@ -1008,10 +1028,13 @@ uint8_t * translate_z80inst(z80inst * inst, uint8_t * dst, z80_context * context
dst = setcc_rdisp8(dst, CC_C, CONTEXT, zf_off(ZF_C));
dst = mov_irdisp8(dst, 0, CONTEXT, zf_off(ZF_N), SZ_B);
//TODO: Implement half-carry flag
- dst = cmp_ir(dst, 0, dst_op.base, SZ_B);
- dst = setcc_rdisp8(dst, CC_P, CONTEXT, zf_off(ZF_PV));
- dst = setcc_rdisp8(dst, CC_Z, CONTEXT, zf_off(ZF_Z));
- dst = setcc_rdisp8(dst, CC_S, CONTEXT, zf_off(ZF_S));
+ if (inst->immed) {
+ //rrca does not set these flags
+ dst = cmp_ir(dst, 0, dst_op.base, SZ_B);
+ dst = setcc_rdisp8(dst, CC_P, CONTEXT, zf_off(ZF_PV));
+ dst = setcc_rdisp8(dst, CC_Z, CONTEXT, zf_off(ZF_Z));
+ dst = setcc_rdisp8(dst, CC_S, CONTEXT, zf_off(ZF_S));
+ }
if (inst->addr_mode != Z80_UNUSED) {
dst = z80_save_result(dst, inst);
if (src_op.mode != MODE_UNUSED) {
@@ -1040,10 +1063,13 @@ uint8_t * translate_z80inst(z80inst * inst, uint8_t * dst, z80_context * context
dst = setcc_rdisp8(dst, CC_C, CONTEXT, zf_off(ZF_C));
dst = mov_irdisp8(dst, 0, CONTEXT, zf_off(ZF_N), SZ_B);
//TODO: Implement half-carry flag
- dst = cmp_ir(dst, 0, dst_op.base, SZ_B);
- dst = setcc_rdisp8(dst, CC_P, CONTEXT, zf_off(ZF_PV));
- dst = setcc_rdisp8(dst, CC_Z, CONTEXT, zf_off(ZF_Z));
- dst = setcc_rdisp8(dst, CC_S, CONTEXT, zf_off(ZF_S));
+ if (inst->immed) {
+ //rra does not set these flags
+ dst = cmp_ir(dst, 0, dst_op.base, SZ_B);
+ dst = setcc_rdisp8(dst, CC_P, CONTEXT, zf_off(ZF_PV));
+ dst = setcc_rdisp8(dst, CC_Z, CONTEXT, zf_off(ZF_Z));
+ dst = setcc_rdisp8(dst, CC_S, CONTEXT, zf_off(ZF_S));
+ }
if (inst->addr_mode != Z80_UNUSED) {
dst = z80_save_result(dst, inst);
if (src_op.mode != MODE_UNUSED) {
@@ -2105,7 +2131,7 @@ void zinsert_breakpoint(z80_context * context, uint16_t address, uint8_t * bp_ha
void zremove_breakpoint(z80_context * context, uint16_t address)
{
- context->breakpoint_flags[address / sizeof(uint8_t)] &= 1 << (address % sizeof(uint8_t));
+ context->breakpoint_flags[address / sizeof(uint8_t)] &= ~(1 << (address % sizeof(uint8_t)));
uint8_t * native = z80_get_native_address(context, address);
if (native) {
z80_check_cycles_int(native, address);
diff --git a/z80inst.c b/z80inst.c
index 0605ebc..cecce6e 100644
--- a/z80inst.c
+++ b/z80inst.c
@@ -1,6 +1,6 @@
/*
Copyright 2013 Michael Pavone
- This file is part of BlastEm.
+ This file is part of BlastEm.
BlastEm is free software distributed under the terms of the GNU General Public License version 3 or greater. See COPYING for full license text.
*/
#include "z80inst.h"
@@ -433,7 +433,7 @@ z80inst z80_tbl_extd[0xC0-0x40] = {
{op, Z80_L, Z80_UNUSED, Z80_UNUSED, 1},\
{op, Z80_UNUSED, Z80_REG_INDIRECT, Z80_HL, 1},\
{op, Z80_A, Z80_UNUSED, Z80_UNUSED, 1}
-
+
#define BIT_BLOCK(op, bit) \
{op, Z80_USE_IMMED, Z80_REG, Z80_B, bit},\
{op, Z80_USE_IMMED, Z80_REG, Z80_C, bit},\
@@ -771,14 +771,14 @@ z80inst z80_tbl_ix[256] = {
};
#define SHIFT_BLOCK_IX(op) \
- {op, Z80_B, Z80_IX_DISPLACE | Z80_DIR, 0, 0},\
- {op, Z80_C, Z80_IX_DISPLACE | Z80_DIR, 0, 0},\
- {op, Z80_D, Z80_IX_DISPLACE | Z80_DIR, 0, 0},\
- {op, Z80_E, Z80_IX_DISPLACE | Z80_DIR, 0, 0},\
- {op, Z80_H, Z80_IX_DISPLACE | Z80_DIR, 0, 0},\
- {op, Z80_L, Z80_IX_DISPLACE | Z80_DIR, 0, 0},\
- {op, Z80_UNUSED, Z80_IX_DISPLACE | Z80_DIR, 0, 0},\
- {op, Z80_A, Z80_IX_DISPLACE | Z80_DIR, 0, 0}
+ {op, Z80_B, Z80_IX_DISPLACE | Z80_DIR, 0, 1},\
+ {op, Z80_C, Z80_IX_DISPLACE | Z80_DIR, 0, 1},\
+ {op, Z80_D, Z80_IX_DISPLACE | Z80_DIR, 0, 1},\
+ {op, Z80_E, Z80_IX_DISPLACE | Z80_DIR, 0, 1},\
+ {op, Z80_H, Z80_IX_DISPLACE | Z80_DIR, 0, 1},\
+ {op, Z80_L, Z80_IX_DISPLACE | Z80_DIR, 0, 1},\
+ {op, Z80_UNUSED, Z80_IX_DISPLACE | Z80_DIR, 0, 1},\
+ {op, Z80_A, Z80_IX_DISPLACE | Z80_DIR, 0, 1}
#define BIT_BLOCK_IX(bit) \
{Z80_BIT, Z80_USE_IMMED, Z80_IX_DISPLACE, 0, bit},\
@@ -1129,14 +1129,14 @@ z80inst z80_tbl_iy[256] = {
};
#define SHIFT_BLOCK_IY(op) \
- {op, Z80_B, Z80_IY_DISPLACE | Z80_DIR, 0, 0},\
- {op, Z80_C, Z80_IY_DISPLACE | Z80_DIR, 0, 0},\
- {op, Z80_D, Z80_IY_DISPLACE | Z80_DIR, 0, 0},\
- {op, Z80_E, Z80_IY_DISPLACE | Z80_DIR, 0, 0},\
- {op, Z80_H, Z80_IY_DISPLACE | Z80_DIR, 0, 0},\
- {op, Z80_L, Z80_IY_DISPLACE | Z80_DIR, 0, 0},\
- {op, Z80_UNUSED, Z80_IY_DISPLACE | Z80_DIR, 0, 0},\
- {op, Z80_A, Z80_IY_DISPLACE | Z80_DIR, 0, 0}
+ {op, Z80_B, Z80_IY_DISPLACE | Z80_DIR, 0, 1},\
+ {op, Z80_C, Z80_IY_DISPLACE | Z80_DIR, 0, 1},\
+ {op, Z80_D, Z80_IY_DISPLACE | Z80_DIR, 0, 1},\
+ {op, Z80_E, Z80_IY_DISPLACE | Z80_DIR, 0, 1},\
+ {op, Z80_H, Z80_IY_DISPLACE | Z80_DIR, 0, 1},\
+ {op, Z80_L, Z80_IY_DISPLACE | Z80_DIR, 0, 1},\
+ {op, Z80_UNUSED, Z80_IY_DISPLACE | Z80_DIR, 0, 1},\
+ {op, Z80_A, Z80_IY_DISPLACE | Z80_DIR, 0, 1}
#define BIT_BLOCK_IY(bit) \
{Z80_BIT, Z80_USE_IMMED, Z80_IY_DISPLACE, 0, bit},\
@@ -1250,7 +1250,7 @@ uint8_t * z80_decode(uint8_t * istream, z80inst * decoded)
}
} else {
memcpy(decoded, z80_tbl_a + *istream, sizeof(z80inst));
-
+
}
if ((decoded->addr_mode & 0x1F) == Z80_IMMED && decoded->op != Z80_RST && decoded->op != Z80_IM) {
decoded->immed = *(++istream);