changeset 887:fb4d09f874dd

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
author Michael Pavone <pavone@retrodev.com>
date Sat, 14 Nov 2015 13:56:41 -0800
parents fb1f11fd0692
children bc127fa1f800
files m68k_core_x86.c
diffstat 1 files changed, 6 insertions(+), 2 deletions(-) [+]
line wrap: on
line diff
--- a/m68k_core_x86.c	Sat Nov 14 10:01:43 2015 -0800
+++ b/m68k_core_x86.c	Sat Nov 14 13:56:41 2015 -0800
@@ -2525,6 +2525,8 @@
 	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 @@
 	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);