mirror of https://github.com/PCSX2/pcsx2.git
Some updates by Jake and 2 lines from me, hope this fixes savestates. Please test guys :)
git-svn-id: http://pcsx2-playground.googlecode.com/svn/trunk@359 a6443dda-0b58-4228-96e9-037be469359c
This commit is contained in:
parent
266875132d
commit
361afda5ed
125
pcsx2/Counters.c
125
pcsx2/Counters.c
|
@ -83,14 +83,6 @@ static __forceinline void cpuRcntSet()
|
|||
nextsCounter = cpuRegs.cycle;
|
||||
nextCounter = (counters[5].sCycle + counters[5].CycleT) - cpuRegs.cycle;
|
||||
|
||||
// if we're running behind, the diff will be negative.
|
||||
// (and running behind means we need to branch again ASAP)
|
||||
if( nextCounter <= 0 )
|
||||
{
|
||||
nextCounter = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
for (i = 0; i < 4; i++)
|
||||
_rcntSet( i );
|
||||
|
||||
|
@ -487,7 +479,6 @@ static __forceinline void VSyncEnd(u32 sCycle) // VSync End
|
|||
hwIntcIrq(3); // HW Irq
|
||||
psxVBlankEnd(); // psxCounters vBlank End
|
||||
if (gates) rcntEndGate(0x8, sCycle); // Counters End Gate Code
|
||||
SysUpdate(); // check for and handle keyevents
|
||||
frameLimit(); // limit FPS (also handles frameskip and VUskip)
|
||||
}
|
||||
|
||||
|
@ -542,6 +533,8 @@ __forceinline void rcntUpdate_vSync()
|
|||
counters[5].sCycle += vSyncInfo.Blank;
|
||||
counters[5].CycleT = vSyncInfo.Render;
|
||||
counters[5].mode = MODE_VRENDER;
|
||||
|
||||
SysUpdate(); // check for and handle keyevents
|
||||
}
|
||||
else // VSYNC end / VRENDER begin
|
||||
{
|
||||
|
@ -570,7 +563,7 @@ __forceinline void rcntUpdate_vSync()
|
|||
|
||||
static __forceinline void __fastcall _cpuTestTarget( int i )
|
||||
{
|
||||
//counters[i].target &= 0xffff;
|
||||
if (counters[i].count < counters[i].target) return;
|
||||
|
||||
if(counters[i].mode & 0x100) {
|
||||
|
||||
|
@ -586,6 +579,21 @@ static __forceinline void __fastcall _cpuTestTarget( int i )
|
|||
else counters[i].target |= 0x10000000;
|
||||
}
|
||||
|
||||
static __forceinline void _cpuTestOverflow( int i )
|
||||
{
|
||||
if (counters[i].count <= 0xffff) return;
|
||||
|
||||
if (counters[i].mode & 0x0200) { // Overflow interrupt
|
||||
EECNT_LOG("EE counter %d overflow mode %x count %x target %x\n", i, counters[i].mode, counters[i].count, counters[i].target);
|
||||
counters[i].mode |= 0x0800; // Overflow flag
|
||||
hwIntcIrq(counters[i].interrupt);
|
||||
}
|
||||
|
||||
// wrap counter back around zero, and enable the future target:
|
||||
counters[i].count -= 0x10000;
|
||||
counters[i].target &= 0xffff;
|
||||
}
|
||||
|
||||
|
||||
// forceinline note: this method is called from two locations, but one
|
||||
// of them is the interpreter, which doesn't count. ;) So might as
|
||||
|
@ -596,14 +604,16 @@ __forceinline void rcntUpdate()
|
|||
|
||||
rcntUpdate_vSync();
|
||||
|
||||
// Update all counters?
|
||||
// This code shouldn't be needed. Counters are updated as needed when
|
||||
// Reads, Writes, and Target/Overflow events occur. The rest of the
|
||||
// time the counters can be left unmodified.
|
||||
|
||||
// Update counters so that we can perform overflow and target tests.
|
||||
|
||||
for (i=0; i<=3; i++) {
|
||||
if ( gates & (1<<i) ) continue;
|
||||
if ((counters[i].mode & 0x80) && (counters[i].mode & 0x3) != 0x3) {
|
||||
|
||||
// We want to count gated counters (except the hblank which excluded below)
|
||||
//if ( gates & (1<<i) ) continue;
|
||||
|
||||
if (!(counters[i].mode & 0x80)) continue;
|
||||
|
||||
if((counters[i].mode & 0x3) != 0x3) { // don't count hblank sources
|
||||
|
||||
s32 change = cpuRegs.cycle - counters[i].sCycleT;
|
||||
if( change > 0 ) {
|
||||
|
@ -621,26 +631,8 @@ __forceinline void rcntUpdate()
|
|||
{
|
||||
if (!(counters[i].mode & 0x80)) continue; // Stopped
|
||||
|
||||
// Target reached?
|
||||
if (counters[i].count >= counters[i].target)
|
||||
_cpuTestTarget( i );
|
||||
|
||||
if (counters[i].count > 0xffff) {
|
||||
|
||||
if (counters[i].mode & 0x0200) { // Overflow interrupt
|
||||
EECNT_LOG("EE counter %d overflow mode %x count %x target %x\n", i, counters[i].mode, counters[i].count, counters[i].target);
|
||||
counters[i].mode |= 0x0800; // Overflow flag
|
||||
hwIntcIrq(counters[i].interrupt);
|
||||
}
|
||||
counters[i].count -= 0x10000;
|
||||
counters[i].target &= 0xffff;
|
||||
|
||||
// Target reached after overflow?
|
||||
// It's possible that a Target very near zero (1-10, etc) could have already been reached.
|
||||
// Checking for it now
|
||||
//if (counters[i].count >= counters[i].target)
|
||||
// _cpuTestTarget( i );
|
||||
}
|
||||
_cpuTestTarget( i );
|
||||
_cpuTestOverflow( i );
|
||||
}
|
||||
cpuRcntSet();
|
||||
}
|
||||
|
@ -665,6 +657,21 @@ void rcntWcount(int index, u32 value)
|
|||
_rcntSet( index );
|
||||
}
|
||||
|
||||
static void _rcntSetGate( int index )
|
||||
{
|
||||
if((counters[index].mode & 0xF) == 0x7) {
|
||||
gates &= ~(1<<index);
|
||||
SysPrintf("Counters: Gate Disabled\n");
|
||||
//counters[index].mode &= ~0x80;
|
||||
}
|
||||
else if (counters[index].mode & 0x4) {
|
||||
gates |= (1<<index);
|
||||
counters[index].mode &= ~0x80;
|
||||
rcntReset(index);
|
||||
}
|
||||
else gates &= ~(1<<index);
|
||||
}
|
||||
|
||||
void rcntWmode(int index, u32 value)
|
||||
{
|
||||
if(counters[index].mode & 0x80) {
|
||||
|
@ -692,21 +699,11 @@ void rcntWmode(int index, u32 value)
|
|||
case 3: counters[index].rate = vSyncInfo.hBlank+vSyncInfo.hRender; break;
|
||||
}
|
||||
|
||||
if((counters[index].mode & 0xF) == 0x7) {
|
||||
gates &= ~(1<<index);
|
||||
SysPrintf("Counters: Gate Disabled\n");
|
||||
//counters[index].mode &= ~0x80;
|
||||
}
|
||||
else if (counters[index].mode & 0x4) {
|
||||
gates |= (1<<index);
|
||||
counters[index].mode &= ~0x80;
|
||||
rcntReset(index);
|
||||
}
|
||||
else gates &= ~(1<<index);
|
||||
|
||||
_rcntSetGate( index );
|
||||
_rcntSet( index );
|
||||
}
|
||||
|
||||
// mode - 0 means hblank source, 8 means vblank source.
|
||||
void rcntStartGate(unsigned int mode, u32 sCycle) {
|
||||
int i;
|
||||
|
||||
|
@ -749,6 +746,7 @@ void rcntStartGate(unsigned int mode, u32 sCycle) {
|
|||
// rcntUpdate, since we're being called from there anyway.
|
||||
}
|
||||
|
||||
// mode - 0 means hblank signal, 8 means vblank signal.
|
||||
void rcntEndGate(unsigned int mode, u32 sCycle) {
|
||||
int i;
|
||||
|
||||
|
@ -764,7 +762,7 @@ void rcntEndGate(unsigned int mode, u32 sCycle) {
|
|||
counters[i].count = rcntRcount(i);
|
||||
counters[i].mode &= ~0x80;
|
||||
counters[i].sCycleT = sCycle;
|
||||
|
||||
|
||||
break;
|
||||
case 0x10: // Reset and start counting on Vsync start
|
||||
// this is the vsync end so do nothing
|
||||
|
@ -825,22 +823,14 @@ u32 rcntCycle(int index) {
|
|||
|
||||
int rcntFreeze(gzFile f, int Mode) {
|
||||
|
||||
if( Mode == 1 )
|
||||
{
|
||||
// Temp Hack Fix: Adjust some values so that they'll load properly
|
||||
// in the future (this should be removed when a new savestate version
|
||||
// is introduced).
|
||||
|
||||
counters[4].sCycle += vSyncInfo.hRender;
|
||||
counters[5].sCycle += vSyncInfo.Render;
|
||||
}
|
||||
|
||||
gzfreezel(counters);
|
||||
gzfreeze(&nextCounter, sizeof(nextCounter));
|
||||
gzfreeze(&nextsCounter, sizeof(nextsCounter));
|
||||
|
||||
if( Mode == 0 )
|
||||
{
|
||||
int i;
|
||||
|
||||
// Sanity check for loading older savestates:
|
||||
|
||||
if( counters[4].sCycle == 0 )
|
||||
|
@ -848,17 +838,14 @@ int rcntFreeze(gzFile f, int Mode) {
|
|||
|
||||
if( counters[5].sCycle == 0 )
|
||||
counters[5].sCycle = cpuRegs.cycle;
|
||||
|
||||
// make sure the gate flags are set based on the counter modes...
|
||||
for( i=0; i<4; i++ )
|
||||
_rcntSetGate( i );
|
||||
}
|
||||
|
||||
// Old versions of PCSX2 saved the counters *after* incrementing them.
|
||||
// So if we don't roll back here, the counters move past cpuRegs.cycle
|
||||
// and everthing explodes!
|
||||
// Note: Roll back regardless of load or save, since we roll them forward
|
||||
// when saving (above). It's a hack, but it works.
|
||||
|
||||
counters[4].sCycle -= vSyncInfo.hRender;
|
||||
counters[5].sCycle -= vSyncInfo.Render;
|
||||
|
||||
iopBranchAction = 1; // probably not needed but won't hurt anything either.
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -24,9 +24,10 @@
|
|||
typedef struct {
|
||||
u32 count, mode, target, hold;
|
||||
u32 rate, interrupt;
|
||||
u32 Cycle, sCycle;
|
||||
u32 Cycle;
|
||||
u32 sCycle; // start cycle of timer
|
||||
s32 CycleT;
|
||||
u32 sCycleT;
|
||||
u32 sCycleT; // delta values should be signed.
|
||||
} Counter;
|
||||
|
||||
//------------------------------------------------------------------
|
||||
|
|
|
@ -485,6 +485,7 @@ int SaveState(const char *file) {
|
|||
gzwrite(f, &psxRegs.cycle, sizeof(u32)); // used to be IOPoCycle. This retains compatibility.
|
||||
gzwrite(f, &g_nextBranchCycle, sizeof(g_nextBranchCycle));
|
||||
gzwrite(f, &g_psxNextBranchCycle, sizeof(g_psxNextBranchCycle));
|
||||
gzwrite(f, &psxNextsCounter, sizeof(psxNextsCounter));
|
||||
gzwrite(f, &s_iLastCOP0Cycle, sizeof(s_iLastCOP0Cycle));
|
||||
gzwrite(f, s_iLastPERFCycle, sizeof(u32)*2);
|
||||
gzwrite(f, &g_psxWriteOk, sizeof(g_psxWriteOk));
|
||||
|
@ -616,6 +617,7 @@ int LoadState(const char *file) {
|
|||
gzread(f, &dud, sizeof(u32)); // was IOPoCycle
|
||||
gzread(f, &g_nextBranchCycle, sizeof(g_nextBranchCycle));
|
||||
gzread(f, &g_psxNextBranchCycle, sizeof(g_psxNextBranchCycle));
|
||||
gzread(f, &psxNextsCounter, sizeof(psxNextsCounter));
|
||||
gzread(f, &s_iLastCOP0Cycle, sizeof(s_iLastCOP0Cycle));
|
||||
if( dwCurSaveStateVer >= 0x7a30000e ) {
|
||||
gzread(f, s_iLastPERFCycle, sizeof(u32)*2);
|
||||
|
|
|
@ -27,8 +27,8 @@ u8 psxhblankgate = 0;
|
|||
u8 psxvblankgate = 0;
|
||||
u8 psxcntmask = 0;
|
||||
|
||||
// flags when the gate is on (counting)
|
||||
#define IOPCNT_GATE_STOPPED (0x10000000ul)
|
||||
// flags when the gate is off or counter disabled. (do not count)
|
||||
#define IOPCNT_STOPPED (0x10000000ul)
|
||||
|
||||
// used to disable targets until after an overflow
|
||||
#define IOPCNT_FUTURE_TARGET (0x1000000000ULL)
|
||||
|
@ -41,7 +41,7 @@ u8 psxcntmask = 0;
|
|||
// Use an arbitrary value to flag HBLANK counters.
|
||||
// These counters will be counted by the hblank gates coming from the EE,
|
||||
// which ensures they stay 100% in sync with the EE's hblank counters.
|
||||
#define PSXHBLANK 0x2000
|
||||
#define PSXHBLANK 0x2001
|
||||
|
||||
static void psxRcntReset(int index)
|
||||
{
|
||||
|
@ -63,7 +63,7 @@ __forceinline static void _rcntSet( int i )
|
|||
// that into account. Adding the difference from that cycle count to the current one
|
||||
// will do the trick!
|
||||
|
||||
if( psxCounters[i].mode & IOPCNT_GATE_STOPPED || psxCounters[i].rate == PSXHBLANK) return;
|
||||
if( psxCounters[i].mode & IOPCNT_STOPPED || psxCounters[i].rate == PSXHBLANK) return;
|
||||
|
||||
c = (u64)((overflowCap - psxCounters[i].count) * psxCounters[i].rate) - (psxRegs.cycle - psxCounters[i].sCycleT);
|
||||
c += psxRegs.cycle - psxNextsCounter; // adjust for time passed since last rcntUpdate();
|
||||
|
@ -226,7 +226,7 @@ static void _psxCheckStartGate( int i )
|
|||
// get the current count at the time of stoppage:
|
||||
psxCounters[i].count = ( i < 3 ) ?
|
||||
psxRcntRcount16( i ) : psxRcntRcount32( i );
|
||||
psxCounters[i].mode |= IOPCNT_GATE_STOPPED;
|
||||
psxCounters[i].mode |= IOPCNT_STOPPED;
|
||||
return;
|
||||
|
||||
case 0x1: //GATE_ON_ClearStart - count normally with resets after every end gate
|
||||
|
@ -236,7 +236,7 @@ static void _psxCheckStartGate( int i )
|
|||
case 0x2: //GATE_ON_Clear_OFF_Start - start counting on gate start, stop on gate end
|
||||
psxCounters[i].count = 0;
|
||||
psxCounters[i].sCycleT = psxRegs.cycle;
|
||||
psxCounters[i].mode &= ~IOPCNT_GATE_STOPPED;
|
||||
psxCounters[i].mode &= ~IOPCNT_STOPPED;
|
||||
break;
|
||||
|
||||
case 0x3: //GATE_ON_Start - start and count normally on gate end (no restarts or stops or clears)
|
||||
|
@ -256,21 +256,21 @@ static void _psxCheckEndGate(int i)
|
|||
case 0x1: //GATE_ON_ClearStart - count normally with resets after every end gate
|
||||
psxCounters[i].count = 0;
|
||||
psxCounters[i].sCycleT = psxRegs.cycle;
|
||||
psxCounters[i].mode &= ~IOPCNT_GATE_STOPPED;
|
||||
psxCounters[i].mode &= ~IOPCNT_STOPPED;
|
||||
break;
|
||||
|
||||
case 0x2: //GATE_ON_Clear_OFF_Start - start counting on gate start, stop on gate end
|
||||
psxCounters[i].count = ( i < 3 ) ?
|
||||
psxRcntRcount16( i ) : psxRcntRcount32( i );
|
||||
psxCounters[i].mode |= IOPCNT_GATE_STOPPED;
|
||||
psxCounters[i].mode |= IOPCNT_STOPPED;
|
||||
return; // do not set the counter
|
||||
|
||||
case 0x3: //GATE_ON_Start - start and count normally (no restarts or stops or clears)
|
||||
if( psxCounters[i].mode & IOPCNT_GATE_STOPPED )
|
||||
if( psxCounters[i].mode & IOPCNT_STOPPED )
|
||||
{
|
||||
psxCounters[i].count = 0;
|
||||
psxCounters[i].sCycleT = psxRegs.cycle;
|
||||
psxCounters[i].mode &= ~IOPCNT_GATE_STOPPED;
|
||||
psxCounters[i].mode &= ~IOPCNT_STOPPED;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -289,7 +289,7 @@ void psxCheckStartGate16(int i)
|
|||
// We count them here so that they stay nicely synced with the EE's hsync.
|
||||
|
||||
const u32 altSourceCheck = IOPCNT_ALT_SOURCE | IOPCNT_ENABLE_GATE;
|
||||
const u32 stoppedGateCheck = (IOPCNT_GATE_STOPPED | altSourceCheck );
|
||||
const u32 stoppedGateCheck = (IOPCNT_STOPPED | altSourceCheck );
|
||||
|
||||
// count if alt source is enabled and either:
|
||||
// * the gate is enabled and not stopped.
|
||||
|
@ -364,7 +364,7 @@ void psxRcntUpdate()
|
|||
// We can't check the ALTSOURCE flag because the PSXCLOCK source *should*
|
||||
// be counted here.
|
||||
|
||||
if( psxCounters[i].mode & (IOPCNT_GATE_STOPPED | IOPCNT_ENABLE_GATE) ) continue;
|
||||
if( psxCounters[i].mode & (IOPCNT_STOPPED | IOPCNT_ENABLE_GATE) ) continue;
|
||||
if( psxCounters[i].rate == PSXHBLANK ) continue;
|
||||
if( change <= 0 ) continue;
|
||||
|
||||
|
@ -387,7 +387,7 @@ void psxRcntUpdate()
|
|||
// don't do target/oveflow checks for hblankers. Those
|
||||
// checks are done when the counters are updated.
|
||||
if( psxCounters[i].rate == PSXHBLANK ) continue;
|
||||
if( psxCounters[i].mode & IOPCNT_GATE_STOPPED ) continue;
|
||||
if( psxCounters[i].mode & IOPCNT_STOPPED ) continue;
|
||||
|
||||
_rcntTestTarget( i );
|
||||
_rcntTestOverflow( i );
|
||||
|
@ -542,7 +542,7 @@ void psxRcnt2Wmode(u32 value)
|
|||
if((psxCounters[2].mode & 0x7) == 0x7 || (psxCounters[2].mode & 0x7) == 0x1)
|
||||
{
|
||||
//SysPrintf("Gate set on IOP C2, disabling\n");
|
||||
psxCounters[2].mode |= IOPCNT_GATE_STOPPED;
|
||||
psxCounters[2].mode |= IOPCNT_STOPPED;
|
||||
}
|
||||
|
||||
psxCounters[2].count = 0;
|
||||
|
@ -593,7 +593,7 @@ void psxRcnt4Wmode(u32 value)
|
|||
if((psxCounters[4].mode & 0x7) == 0x7 || (psxCounters[4].mode & 0x7) == 0x1)
|
||||
{
|
||||
SysPrintf("Gate set on IOP C4, disabling\n");
|
||||
psxCounters[4].mode |= IOPCNT_GATE_STOPPED;
|
||||
psxCounters[4].mode |= IOPCNT_STOPPED;
|
||||
}
|
||||
|
||||
psxCounters[4].count = 0;
|
||||
|
@ -620,7 +620,7 @@ void psxRcnt5Wmode(u32 value)
|
|||
if((psxCounters[5].mode & 0x7) == 0x7 || (psxCounters[5].mode & 0x7) == 0x1)
|
||||
{
|
||||
SysPrintf("Gate set on IOP C5, disabling\n");
|
||||
psxCounters[5].mode |= IOPCNT_GATE_STOPPED;
|
||||
psxCounters[5].mode |= IOPCNT_STOPPED;
|
||||
}
|
||||
|
||||
psxCounters[5].count = 0;
|
||||
|
@ -673,7 +673,7 @@ u16 psxRcntRcount16(int index)
|
|||
// Don't count HBLANK timers
|
||||
// Don't count stopped gates either.
|
||||
|
||||
if( !( psxCounters[index].mode & IOPCNT_GATE_STOPPED ) &&
|
||||
if( !( psxCounters[index].mode & IOPCNT_STOPPED ) &&
|
||||
( psxCounters[index].rate != PSXHBLANK ) )
|
||||
{
|
||||
u32 delta = (u32)((psxRegs.cycle - psxCounters[index].sCycleT) / psxCounters[index].rate);
|
||||
|
@ -693,7 +693,7 @@ u32 psxRcntRcount32(int index)
|
|||
|
||||
PSXCNT_LOG("IOP Counter[%d] > readCount32 = %lx", index, retval );
|
||||
|
||||
if( !( psxCounters[index].mode & IOPCNT_GATE_STOPPED ) &&
|
||||
if( !( psxCounters[index].mode & IOPCNT_STOPPED ) &&
|
||||
( psxCounters[index].rate != PSXHBLANK ) )
|
||||
{
|
||||
u32 delta = (u32)((psxRegs.cycle - psxCounters[index].sCycleT) / psxCounters[index].rate);
|
||||
|
@ -707,7 +707,7 @@ u32 psxRcntRcount32(int index)
|
|||
|
||||
u64 psxRcntCycles(int index)
|
||||
{
|
||||
if(psxCounters[index].mode & IOPCNT_GATE_STOPPED || psxCounters[index].rate == PSXHBLANK ) return psxCounters[index].count;
|
||||
if(psxCounters[index].mode & IOPCNT_STOPPED || psxCounters[index].rate == PSXHBLANK ) return psxCounters[index].count;
|
||||
return (u64)(psxCounters[index].count + (u32)((psxRegs.cycle - psxCounters[index].sCycleT) / psxCounters[index].rate));
|
||||
}
|
||||
|
||||
|
@ -716,7 +716,7 @@ int psxRcntFreeze(gzFile f, int Mode)
|
|||
{
|
||||
if( Mode == 0 && (dwCurSaveStateVer < 0x7a300010) )
|
||||
{
|
||||
// --- Reading Mode ---
|
||||
// --- Reading Mode, Old Version ---
|
||||
// struct used to be 32bit count and target
|
||||
int i;
|
||||
u32 val;
|
||||
|
@ -731,16 +731,26 @@ int psxRcntFreeze(gzFile f, int Mode)
|
|||
else
|
||||
{
|
||||
gzfreezel(psxCounters);
|
||||
}
|
||||
|
||||
if( Mode == 0 )
|
||||
{
|
||||
// This is needed to make old save states compatible.
|
||||
psxCounters[6].rate = ((Config.Hacks & 0x4) ? 768 : (768*8));
|
||||
psxCounters[6].CycleT = psxCounters[6].rate;
|
||||
psxCounters[7].rate = PSXCLK/1000;
|
||||
psxCounters[7].CycleT = psxCounters[7].rate;
|
||||
if( Mode == 0 )
|
||||
{
|
||||
// This is needed to make old save states compatible.
|
||||
|
||||
psxCounters[6].rate = ((Config.Hacks & 0x4) ? 768 : (768*8));
|
||||
psxCounters[6].CycleT = psxCounters[6].rate;
|
||||
psxCounters[7].rate = PSXCLK/1000;
|
||||
psxCounters[7].CycleT = psxCounters[7].rate;
|
||||
|
||||
// PSXHBLANK is now an arbitrary value, since it can differ based
|
||||
// on PAL/NTSC and is timed by the EE.
|
||||
|
||||
if(psxCounters[1].mode & IOPCNT_ALT_SOURCE)
|
||||
psxCounters[1].rate = PSXHBLANK;
|
||||
|
||||
if(psxCounters[3].mode & IOPCNT_ALT_SOURCE)
|
||||
psxCounters[3].rate = PSXHBLANK;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
#ifndef __PSXCOUNTERS_H__
|
||||
#define __PSXCOUNTERS_H__
|
||||
|
||||
// fixme: sCycle and Cycle are unused.
|
||||
// fixme: sCycle, Cycle, and otarget are unused
|
||||
// Can't remove them without making a new savestate version though.
|
||||
|
||||
typedef struct {
|
||||
|
|
Loading…
Reference in New Issue