Mercurial > repos > blastem
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 |