changeset 1332:87bbc4bec958

Fix timing for branch not taken case in the M68K BCC intruction
author Michael Pavone <pavone@retrodev.com>
date Wed, 26 Apr 2017 21:55:12 -0700
parents 9bba5ff5beb8
children 69c25e1188e5
files m68k_core_x86.c
diffstat 1 files changed, 16 insertions(+), 4 deletions(-) [+]
line wrap: on
line diff
--- a/m68k_core_x86.c	Wed Apr 26 01:12:28 2017 -0700
+++ b/m68k_core_x86.c	Wed Apr 26 21:55:12 2017 -0700
@@ -794,20 +794,32 @@
 void translate_m68k_bcc(m68k_options * opts, m68kinst * inst)
 {
 	code_info *code = &opts->gen.code;
-	cycles(&opts->gen, 10);//TODO: Adjust this for branch not taken case
+	
 	int32_t disp = inst->src.params.immed;
 	uint32_t after = inst->address + 2;
 	if (inst->extra.cond == COND_TRUE) {
+		cycles(&opts->gen, 10);
 		jump_m68k_abs(opts, after + disp);
 	} else {
+		uint8_t cond = m68k_eval_cond(opts, inst->extra.cond);
+		code_ptr do_branch = code->cur + 1;
+		jcc(code, cond, do_branch);
+		
+		cycles(&opts->gen, inst->variant == VAR_BYTE ? 8 : 12);
+		code_ptr done = code->cur + 1;
+		jmp(code, done);
+		
+		*do_branch = code->cur - (do_branch + 1);
+		cycles(&opts->gen, 10);
 		code_ptr dest_addr = get_native_address(opts, after + disp);
-		uint8_t cond = m68k_eval_cond(opts, inst->extra.cond);
 		if (!dest_addr) {
-			opts->gen.deferred = defer_address(opts->gen.deferred, after + disp, code->cur + 2);
+			opts->gen.deferred = defer_address(opts->gen.deferred, after + disp, code->cur + 1);
 			//dummy address to be replaced later, make sure it generates a 4-byte displacement
 			dest_addr = code->cur + 256;
 		}
-		jcc(code, cond, dest_addr);
+		jmp(code, dest_addr);
+		
+		*done = code->cur - (done + 1);
 	}
 }