summaryrefslogtreecommitdiff
path: root/m68k_core_x86.c
diff options
context:
space:
mode:
authorMichael Pavone <pavone@retrodev.com>2017-04-26 21:55:12 -0700
committerMichael Pavone <pavone@retrodev.com>2017-04-26 21:55:12 -0700
commit174396b1c744e9bd3ac438f8660f25cd59568b4a (patch)
tree9be7e80502f67038cbeffaf1a9666538b3f6a738 /m68k_core_x86.c
parent0203112fa769b18d945223ead4f1b90838b353f6 (diff)
Fix timing for branch not taken case in the M68K BCC intruction
Diffstat (limited to 'm68k_core_x86.c')
-rw-r--r--m68k_core_x86.c20
1 files changed, 16 insertions, 4 deletions
diff --git a/m68k_core_x86.c b/m68k_core_x86.c
index 2ec0e90..fede6ff 100644
--- a/m68k_core_x86.c
+++ b/m68k_core_x86.c
@@ -794,20 +794,32 @@ uint8_t m68k_eval_cond(m68k_options * opts, uint8_t cc)
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 {
- code_ptr dest_addr = get_native_address(opts, after + disp);
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);
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);
}
}