From be9d7aa532f6ac9f6550adb454ae6c801f15373c Mon Sep 17 00:00:00 2001 From: Michael Pavone Date: Sat, 14 Nov 2015 13:56:41 -0800 Subject: Prevent the current interrupt number from being changed while interrupt is being processed. This fixes a bug in Sonic 2 split screen that showed up when interrupt timing was adjusted --- m68k_core_x86.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/m68k_core_x86.c b/m68k_core_x86.c index 9a43f01..59f92bc 100644 --- a/m68k_core_x86.c +++ b/m68k_core_x86.c @@ -2525,6 +2525,8 @@ void init_m68k_opts(m68k_options * opts, memmap_chunk * memmap, uint32_t num_chu mov_irdisp(code, 1, opts->gen.context_reg, offsetof(m68k_context, int_pending), SZ_B); retn(code); *do_int = code->cur - (do_int + 1); + //save interrupt number so it can't change during interrupt processing + push_rdisp(code, opts->gen.context_reg, offsetof(m68k_context, int_num)); //save PC as stored in scratch1 for later push_r(code, opts->gen.scratch1); //set target cycle to sync cycle @@ -2580,9 +2582,11 @@ void init_m68k_opts(m68k_options * opts, memmap_chunk * memmap, uint32_t num_chu add_ir(code, 2, opts->gen.scratch2, SZ_D); call(code, opts->write_32_lowfirst); - //calculate interrupt vector address - mov_rdispr(code, opts->gen.context_reg, offsetof(m68k_context, int_num), opts->gen.scratch1, SZ_D); + //restore saved interrupt number + pop_r(code, opts->gen.scratch1); + //ack the interrupt (happens earlier on hardware, but shouldn't be an observable difference) mov_rrdisp(code, opts->gen.scratch1, opts->gen.context_reg, offsetof(m68k_context, int_ack), SZ_W); + //calculate the vector address shl_ir(code, 2, opts->gen.scratch1, SZ_D); add_ir(code, 0x60, opts->gen.scratch1, SZ_D); call(code, opts->read_32); -- cgit v1.2.3