mirror of https://github.com/snes9xgit/snes9x.git
Introduce new APU timing hack
Timings.APUAllowTimeOverflow allows the SPC to cross the time limit set by CPU.Cycles. Currently fixes Earthworm Jim 2, Ms. Pacman and NBA Hang Time.
This commit is contained in:
parent
6df2bb515a
commit
33b1a63238
|
@ -511,7 +511,7 @@ int SNES_SPC::cpu_read( int addr, rel_time_t time )
|
|||
BOOST::uint8_t* SNES_SPC::run_until_( time_t end_time )\
|
||||
{\
|
||||
rel_time_t rel_time = m.spc_time - end_time;\
|
||||
assert( rel_time <= 0 );\
|
||||
/*assert( rel_time <= 0 );*/\
|
||||
m.spc_time = end_time;\
|
||||
m.dsp_time += rel_time;\
|
||||
m.timers [0].next_time += rel_time;\
|
||||
|
@ -524,7 +524,7 @@ BOOST::uint8_t* SNES_SPC::run_until_( time_t end_time )\
|
|||
m.timers [0].next_time -= rel_time;\
|
||||
m.timers [1].next_time -= rel_time;\
|
||||
m.timers [2].next_time -= rel_time;\
|
||||
assert( m.spc_time <= end_time );\
|
||||
/*assert( m.spc_time >= end_time );*/\
|
||||
return ®S [r_cpuio0];\
|
||||
}
|
||||
|
||||
|
@ -543,7 +543,7 @@ void SNES_SPC::end_frame( time_t end_time )
|
|||
// Greatest number of clocks early that emulation can stop early due to
|
||||
// not being able to execute current instruction without going over
|
||||
// allowed time.
|
||||
assert( -cpu_lag_max <= m.spc_time && m.spc_time <= 0 );
|
||||
assert( -cpu_lag_max <= m.spc_time && m.spc_time <= cpu_lag_max );
|
||||
|
||||
// Catch timers up to CPU
|
||||
for ( int i = 0; i < timer_count; i++ )
|
||||
|
|
|
@ -106,6 +106,8 @@ public:
|
|||
|
||||
//// Snes9x Accessor
|
||||
|
||||
void spc_allow_time_overflow( bool );
|
||||
|
||||
void dsp_set_spc_snapshot_callback( void (*callback) (void) );
|
||||
void dsp_dump_spc_snapshot( void );
|
||||
void dsp_set_stereo_switch( int );
|
||||
|
@ -258,6 +260,9 @@ private:
|
|||
static char const signature [signature_size + 1];
|
||||
|
||||
void save_regs( uint8_t out [reg_count] );
|
||||
|
||||
// Snes9x timing hack
|
||||
bool allow_time_overflow;
|
||||
};
|
||||
|
||||
#include <assert.h>
|
||||
|
@ -285,4 +290,6 @@ inline void SNES_SPC::disable_surround( bool disable ) { dsp.disable_surround( d
|
|||
inline bool SNES_SPC::check_kon() { return dsp.check_kon(); }
|
||||
#endif
|
||||
|
||||
inline void SNES_SPC::spc_allow_time_overflow( bool allow ) { allow_time_overflow = allow; }
|
||||
|
||||
#endif
|
||||
|
|
|
@ -69,6 +69,8 @@ blargg_err_t SNES_SPC::init()
|
|||
m.cycle_table [i * 2 + 1] = n & 0x0F;
|
||||
}
|
||||
|
||||
allow_time_overflow = false;
|
||||
|
||||
#if SPC_LESS_ACCURATE
|
||||
memcpy( reg_times, reg_times_, sizeof reg_times );
|
||||
#endif
|
||||
|
|
|
@ -196,7 +196,9 @@ loop:
|
|||
check( (unsigned) y < 0x100 );
|
||||
|
||||
opcode = *pc;
|
||||
if ( (rel_time += m.cycle_table [opcode]) > 0 )
|
||||
if (allow_time_overflow && rel_time >= 0 )
|
||||
goto stop;
|
||||
if ( (rel_time += m.cycle_table [opcode]) > 0 && !allow_time_overflow)
|
||||
goto out_of_time;
|
||||
|
||||
#ifdef SPC_CPU_OPCODE_HOOK
|
||||
|
|
|
@ -598,6 +598,11 @@ void S9xAPUTimingSetSpeedup (int ticks)
|
|||
UpdatePlaybackRate();
|
||||
}
|
||||
|
||||
void S9xAPUAllowTimeOverflow (bool allow)
|
||||
{
|
||||
spc_core->spc_allow_time_overflow(allow);
|
||||
}
|
||||
|
||||
void S9xResetAPU (void)
|
||||
{
|
||||
spc::reference_time = 0;
|
||||
|
|
|
@ -195,6 +195,7 @@ void S9xAPUExecute (void);
|
|||
void S9xAPUEndScanline (void);
|
||||
void S9xAPUSetReferenceTime (int32);
|
||||
void S9xAPUTimingSetSpeedup (int);
|
||||
void S9xAPUAllowTimeOverflow (bool);
|
||||
void S9xAPULoadState (uint8 *);
|
||||
void S9xAPUSaveState (uint8 *);
|
||||
void S9xDumpSPCSnapshot (void);
|
||||
|
|
|
@ -3513,6 +3513,7 @@ void CMemory::ApplyROMFixes (void)
|
|||
//// APU timing hacks :(
|
||||
|
||||
Timings.APUSpeedup = 0;
|
||||
Timings.APUAllowTimeOverflow = FALSE;
|
||||
|
||||
if (!Settings.DisableGameSpecificHacks)
|
||||
{
|
||||
|
@ -3554,9 +3555,15 @@ void CMemory::ApplyROMFixes (void)
|
|||
match_na("HEIWA Parlor!Mini8") || // Parlor mini 8
|
||||
match_nn("SANKYO Fever! \xCC\xA8\xB0\xCA\xDE\xB0!")) // SANKYO Fever! Fever!
|
||||
Timings.APUSpeedup = 1;
|
||||
|
||||
if (match_na ("EARTHWORM JIM 2") || // Earthworm Jim 2
|
||||
match_na ("NBA Hangtime") || // NBA Hang Time
|
||||
match_na ("MSPACMAN")) // Ms Pacman
|
||||
Timings.APUAllowTimeOverflow = TRUE;
|
||||
}
|
||||
|
||||
S9xAPUTimingSetSpeedup(Timings.APUSpeedup);
|
||||
S9xAPUAllowTimeOverflow(Timings.APUAllowTimeOverflow);
|
||||
|
||||
//// Other timing hacks :(
|
||||
|
||||
|
|
1
snes9x.h
1
snes9x.h
|
@ -334,6 +334,7 @@ struct STimings
|
|||
int32 NMIDMADelay; // The delay of NMI trigger after DMA transfers. Snes9x cannot emulate correctly.
|
||||
int32 IRQPendCount; // This value is just a hack, because Snes9x cannot emulate any events in an opcode.
|
||||
int32 APUSpeedup;
|
||||
bool8 APUAllowTimeOverflow;
|
||||
};
|
||||
|
||||
struct SSettings
|
||||
|
|
Loading…
Reference in New Issue