changeset 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 55b550fe8891
children f822d9216968
files z80_to_x86.c z80inst.c
diffstat 2 files changed, 63 insertions(+), 37 deletions(-) [+]
line wrap: on
line diff
--- a/z80_to_x86.c	Tue Dec 16 01:05:00 2014 -0800
+++ b/z80_to_x86.c	Tue Dec 16 01:10:54 2014 -0800
@@ -157,7 +157,7 @@
 				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 @@
 					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 @@
 		} 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 @@
 		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 @@
 		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 @@
 		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 @@
 		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 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);
--- a/z80inst.c	Tue Dec 16 01:05:00 2014 -0800
+++ b/z80inst.c	Tue Dec 16 01:10:54 2014 -0800
@@ -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 @@
 	{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 @@
 };
 
 #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 @@
 };
 
 #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 @@
 		}
 	} 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);