comparison m68k_core_x86.c @ 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 9f149f0e98b7
children a7774fc2de4b
comparison
equal deleted inserted replaced
886:fb1f11fd0692 887:fb4d09f874dd
2523 do_int = code->cur + 1; 2523 do_int = code->cur + 1;
2524 jcc(code, CC_NZ, do_int); 2524 jcc(code, CC_NZ, do_int);
2525 mov_irdisp(code, 1, opts->gen.context_reg, offsetof(m68k_context, int_pending), SZ_B); 2525 mov_irdisp(code, 1, opts->gen.context_reg, offsetof(m68k_context, int_pending), SZ_B);
2526 retn(code); 2526 retn(code);
2527 *do_int = code->cur - (do_int + 1); 2527 *do_int = code->cur - (do_int + 1);
2528 //save interrupt number so it can't change during interrupt processing
2529 push_rdisp(code, opts->gen.context_reg, offsetof(m68k_context, int_num));
2528 //save PC as stored in scratch1 for later 2530 //save PC as stored in scratch1 for later
2529 push_r(code, opts->gen.scratch1); 2531 push_r(code, opts->gen.scratch1);
2530 //set target cycle to sync cycle 2532 //set target cycle to sync cycle
2531 mov_rdispr(code, opts->gen.context_reg, offsetof(m68k_context, sync_cycle), opts->gen.limit, SZ_D); 2533 mov_rdispr(code, opts->gen.context_reg, offsetof(m68k_context, sync_cycle), opts->gen.limit, SZ_D);
2532 //swap USP and SSP if not already in supervisor mode 2534 //swap USP and SSP if not already in supervisor mode
2578 //save PC 2580 //save PC
2579 areg_to_native(opts, 7, opts->gen.scratch2); 2581 areg_to_native(opts, 7, opts->gen.scratch2);
2580 add_ir(code, 2, opts->gen.scratch2, SZ_D); 2582 add_ir(code, 2, opts->gen.scratch2, SZ_D);
2581 call(code, opts->write_32_lowfirst); 2583 call(code, opts->write_32_lowfirst);
2582 2584
2583 //calculate interrupt vector address 2585 //restore saved interrupt number
2584 mov_rdispr(code, opts->gen.context_reg, offsetof(m68k_context, int_num), opts->gen.scratch1, SZ_D); 2586 pop_r(code, opts->gen.scratch1);
2587 //ack the interrupt (happens earlier on hardware, but shouldn't be an observable difference)
2585 mov_rrdisp(code, opts->gen.scratch1, opts->gen.context_reg, offsetof(m68k_context, int_ack), SZ_W); 2588 mov_rrdisp(code, opts->gen.scratch1, opts->gen.context_reg, offsetof(m68k_context, int_ack), SZ_W);
2589 //calculate the vector address
2586 shl_ir(code, 2, opts->gen.scratch1, SZ_D); 2590 shl_ir(code, 2, opts->gen.scratch1, SZ_D);
2587 add_ir(code, 0x60, opts->gen.scratch1, SZ_D); 2591 add_ir(code, 0x60, opts->gen.scratch1, SZ_D);
2588 call(code, opts->read_32); 2592 call(code, opts->read_32);
2589 call(code, opts->native_addr_and_sync); 2593 call(code, opts->native_addr_and_sync);
2590 //2 prefetch bus operations + 2 idle bus cycles 2594 //2 prefetch bus operations + 2 idle bus cycles