mirror of
https://github.com/dborth/snes9xgx.git
synced 2024-11-24 03:29:22 +01:00
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
9816922af5
commit
221bab8a9a
@ -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 )\
|
BOOST::uint8_t* SNES_SPC::run_until_( time_t end_time )\
|
||||||
{\
|
{\
|
||||||
rel_time_t rel_time = m.spc_time - 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.spc_time = end_time;\
|
||||||
m.dsp_time += rel_time;\
|
m.dsp_time += rel_time;\
|
||||||
m.timers [0].next_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 [0].next_time -= rel_time;\
|
||||||
m.timers [1].next_time -= rel_time;\
|
m.timers [1].next_time -= rel_time;\
|
||||||
m.timers [2].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];\
|
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
|
// Greatest number of clocks early that emulation can stop early due to
|
||||||
// not being able to execute current instruction without going over
|
// not being able to execute current instruction without going over
|
||||||
// allowed time.
|
// 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
|
// Catch timers up to CPU
|
||||||
for ( int i = 0; i < timer_count; i++ )
|
for ( int i = 0; i < timer_count; i++ )
|
||||||
|
@ -106,6 +106,8 @@ public:
|
|||||||
|
|
||||||
//// Snes9x Accessor
|
//// Snes9x Accessor
|
||||||
|
|
||||||
|
void spc_allow_time_overflow( bool );
|
||||||
|
|
||||||
void dsp_set_spc_snapshot_callback( void (*callback) (void) );
|
void dsp_set_spc_snapshot_callback( void (*callback) (void) );
|
||||||
void dsp_dump_spc_snapshot( void );
|
void dsp_dump_spc_snapshot( void );
|
||||||
void dsp_set_stereo_switch( int );
|
void dsp_set_stereo_switch( int );
|
||||||
@ -258,6 +260,9 @@ private:
|
|||||||
static char const signature [signature_size + 1];
|
static char const signature [signature_size + 1];
|
||||||
|
|
||||||
void save_regs( uint8_t out [reg_count] );
|
void save_regs( uint8_t out [reg_count] );
|
||||||
|
|
||||||
|
// Snes9x timing hack
|
||||||
|
bool allow_time_overflow;
|
||||||
};
|
};
|
||||||
|
|
||||||
#include <assert.h>
|
#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(); }
|
inline bool SNES_SPC::check_kon() { return dsp.check_kon(); }
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
inline void SNES_SPC::spc_allow_time_overflow( bool allow ) { allow_time_overflow = allow; }
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -68,6 +68,8 @@ blargg_err_t SNES_SPC::init()
|
|||||||
m.cycle_table [i * 2 + 0] = n >> 4;
|
m.cycle_table [i * 2 + 0] = n >> 4;
|
||||||
m.cycle_table [i * 2 + 1] = n & 0x0F;
|
m.cycle_table [i * 2 + 1] = n & 0x0F;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
allow_time_overflow = false;
|
||||||
|
|
||||||
#if SPC_LESS_ACCURATE
|
#if SPC_LESS_ACCURATE
|
||||||
memcpy( reg_times, reg_times_, sizeof reg_times );
|
memcpy( reg_times, reg_times_, sizeof reg_times );
|
||||||
|
@ -196,7 +196,9 @@ loop:
|
|||||||
check( (unsigned) y < 0x100 );
|
check( (unsigned) y < 0x100 );
|
||||||
|
|
||||||
opcode = *pc;
|
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;
|
goto out_of_time;
|
||||||
|
|
||||||
#ifdef SPC_CPU_OPCODE_HOOK
|
#ifdef SPC_CPU_OPCODE_HOOK
|
||||||
|
@ -598,6 +598,11 @@ void S9xAPUTimingSetSpeedup (int ticks)
|
|||||||
UpdatePlaybackRate();
|
UpdatePlaybackRate();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void S9xAPUAllowTimeOverflow (bool allow)
|
||||||
|
{
|
||||||
|
spc_core->spc_allow_time_overflow(allow);
|
||||||
|
}
|
||||||
|
|
||||||
void S9xResetAPU (void)
|
void S9xResetAPU (void)
|
||||||
{
|
{
|
||||||
spc::reference_time = 0;
|
spc::reference_time = 0;
|
||||||
|
@ -195,6 +195,7 @@ void S9xAPUExecute (void);
|
|||||||
void S9xAPUEndScanline (void);
|
void S9xAPUEndScanline (void);
|
||||||
void S9xAPUSetReferenceTime (int32);
|
void S9xAPUSetReferenceTime (int32);
|
||||||
void S9xAPUTimingSetSpeedup (int);
|
void S9xAPUTimingSetSpeedup (int);
|
||||||
|
void S9xAPUAllowTimeOverflow (bool);
|
||||||
void S9xAPULoadState (uint8 *);
|
void S9xAPULoadState (uint8 *);
|
||||||
void S9xAPUSaveState (uint8 *);
|
void S9xAPUSaveState (uint8 *);
|
||||||
void S9xDumpSPCSnapshot (void);
|
void S9xDumpSPCSnapshot (void);
|
||||||
|
@ -3530,6 +3530,7 @@ void CMemory::ApplyROMFixes (void)
|
|||||||
//// APU timing hacks :(
|
//// APU timing hacks :(
|
||||||
|
|
||||||
Timings.APUSpeedup = 0;
|
Timings.APUSpeedup = 0;
|
||||||
|
Timings.APUAllowTimeOverflow = FALSE;
|
||||||
|
|
||||||
if (!Settings.DisableGameSpecificHacks)
|
if (!Settings.DisableGameSpecificHacks)
|
||||||
{
|
{
|
||||||
@ -3571,9 +3572,15 @@ void CMemory::ApplyROMFixes (void)
|
|||||||
match_na("HEIWA Parlor!Mini8") || // Parlor mini 8
|
match_na("HEIWA Parlor!Mini8") || // Parlor mini 8
|
||||||
match_nn("SANKYO Fever! \xCC\xA8\xB0\xCA\xDE\xB0!")) // SANKYO Fever! Fever!
|
match_nn("SANKYO Fever! \xCC\xA8\xB0\xCA\xDE\xB0!")) // SANKYO Fever! Fever!
|
||||||
Timings.APUSpeedup = 1;
|
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);
|
S9xAPUTimingSetSpeedup(Timings.APUSpeedup);
|
||||||
|
S9xAPUAllowTimeOverflow(Timings.APUAllowTimeOverflow);
|
||||||
|
|
||||||
//// Other timing hacks :(
|
//// Other timing hacks :(
|
||||||
|
|
||||||
|
@ -334,6 +334,7 @@ struct STimings
|
|||||||
int32 NMIDMADelay; // The delay of NMI trigger after DMA transfers. Snes9x cannot emulate correctly.
|
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 IRQPendCount; // This value is just a hack, because Snes9x cannot emulate any events in an opcode.
|
||||||
int32 APUSpeedup;
|
int32 APUSpeedup;
|
||||||
|
bool8 APUAllowTimeOverflow;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct SSettings
|
struct SSettings
|
||||||
|
Loading…
Reference in New Issue
Block a user