diff options
-rw-r--r-- | blastem.c | 3 | ||||
-rw-r--r-- | m68k_core.h | 2 | ||||
-rw-r--r-- | m68k_core_x86.c | 21 |
3 files changed, 24 insertions, 2 deletions
@@ -156,6 +156,9 @@ void adjust_int_cycle(m68k_context * context, vdp_context * v_context) } } } + if (context->int_cycle > context->current_cycle) { + context->int_pending = 0; + } /*if (context->int_cycle != old_int_cycle) { printf("int cycle changed to: %d, level: %d @ %d(%d), frame: %d, vcounter: %d, hslot: %d, mask: %d, hint_counter: %d\n", context->int_cycle, context->int_num, v_context->cycles, context->current_cycle, v_context->frame, v_context->vcounter, v_context->hslot, context->status & 0x7, v_context->hint_counter); old_int_cycle = context->int_cycle; diff --git a/m68k_core.h b/m68k_core.h index 7135000..86aed4c 100644 --- a/m68k_core.h +++ b/m68k_core.h @@ -59,11 +59,11 @@ typedef struct { uint32_t int_num; uint16_t *mem_pointers[NUM_MEM_AREAS]; void *video_context; - uint16_t reserved; native_map_slot *native_code_map; m68k_options *options; void *system; + uint8_t int_pending; uint8_t ram_code_flags[]; } m68k_context; diff --git a/m68k_core_x86.c b/m68k_core_x86.c index fff5855..e584190 100644 --- a/m68k_core_x86.c +++ b/m68k_core_x86.c @@ -2010,6 +2010,10 @@ void translate_m68k_andi_ori_ccr_sr(m68k_options *opts, m68kinst *inst) } if ((inst->op == M68K_ANDI_SR && (inst->src.params.immed & 0x700) != 0x700) || (inst->op == M68K_ORI_SR && inst->src.params.immed & 0x700)) { + if (inst->op == M68K_ANDI_SR) { + //set int pending flag in case we trigger an interrupt as a result of the mask change + mov_irdisp(code, 1, opts->gen.context_reg, offsetof(m68k_context, int_pending), SZ_B); + } call(code, opts->do_sync); } } @@ -2035,9 +2039,11 @@ void translate_m68k_eori_ccr_sr(m68k_options *opts, m68kinst *inst) if (inst->src.params.immed & 0x10) { xor_flag(opts, 1, FLAG_X); } - if (inst->op == M68K_ORI_SR) { + if (inst->op == M68K_EORI_SR) { xor_irdisp(code, inst->src.params.immed >> 8, opts->gen.context_reg, offsetof(m68k_context, status), SZ_B); if (inst->src.params.immed & 0x700) { + //set int pending flag in case we trigger an interrupt as a result of the mask change + mov_irdisp(code, 1, opts->gen.context_reg, offsetof(m68k_context, int_pending), SZ_B); call(code, opts->do_sync); } } @@ -2065,6 +2071,10 @@ void translate_m68k_move_ccr_sr(m68k_options *opts, m68kinst *inst, host_ea *src //leave supervisor mode swap_ssp_usp(opts); } + if (((src_op->disp >> 8) & 7) < 7) { + //set int pending flag in case we trigger an interrupt as a result of the mask change + mov_irdisp(code, 1, opts->gen.context_reg, offsetof(m68k_context, int_pending), SZ_B); + } call(code, opts->do_sync); } cycles(&opts->gen, 12); @@ -2466,6 +2476,8 @@ void init_m68k_opts(m68k_options * opts, memmap_chunk * memmap, uint32_t num_chu } shr_ir(code, 8, opts->gen.scratch1, SZ_W); mov_rrdisp(code, opts->gen.scratch1, opts->gen.context_reg, offsetof(m68k_context, status), SZ_B); + //set int pending flag in case we trigger an interrupt as a result of the mask change + mov_irdisp(code, 1, opts->gen.context_reg, offsetof(m68k_context, int_pending), SZ_B); retn(code); opts->set_ccr = code->cur; @@ -2499,6 +2511,13 @@ void init_m68k_opts(m68k_options * opts, memmap_chunk * memmap, uint32_t num_chu *skip_sync = code->cur - (skip_sync+1); retn(code); *do_int = code->cur - (do_int+1); + //implement 1 instruction latency + cmp_irdisp(code, 0, opts->gen.context_reg, offsetof(m68k_context, int_pending), SZ_B); + do_int = code->cur + 1; + jcc(code, CC_NZ, do_int); + mov_irdisp(code, 1, opts->gen.context_reg, offsetof(m68k_context, int_pending), SZ_B); + retn(code); + *do_int = code->cur - (do_int + 1); //set target cycle to sync cycle mov_rdispr(code, opts->gen.context_reg, offsetof(m68k_context, sync_cycle), opts->gen.limit, SZ_D); //swap USP and SSP if not already in supervisor mode |