mirror of https://github.com/PCSX2/pcsx2.git
Applied the IOP counter optimization to the EE counters. Don't expect any noticeable speedups though, since this doesn't really affect the hsync/vsync counters which are the ones that end up doing 90% of the work. (but there's always a chance that it'll favor a game that likes to abuse the counters)
git-svn-id: http://pcsx2-playground.googlecode.com/svn/trunk@280 a6443dda-0b58-4228-96e9-037be469359c
This commit is contained in:
parent
f113aab091
commit
1fbeeeb678
|
@ -48,23 +48,31 @@ void rcntReset(int index) {
|
|||
rcntUpd(index);
|
||||
}
|
||||
|
||||
void rcntSet() {
|
||||
// Updates the state of the nextCounter value (if needed) to serve
|
||||
// any pending events for the given counter.
|
||||
// Call this method after any modifications to the state of a counter.
|
||||
static __forceinline void _rcntSet( int i )
|
||||
{
|
||||
u32 c;
|
||||
if (!(counters[i].mode & 0x80) || (counters[i].mode & 0x3) == 0x3) return; // Stopped
|
||||
|
||||
c = ((0x10000 - counters[i].count) * counters[i].rate) - (cpuRegs.cycle - counters[i].sCycleT);
|
||||
if (c < nextCounter) nextCounter = c;
|
||||
|
||||
//if(!(counters[i].mode & 0x100) || counters[i].target > 0xffff) continue;
|
||||
|
||||
c = ((counters[i].target - counters[i].count) * counters[i].rate) - (cpuRegs.cycle - counters[i].sCycleT);
|
||||
if (c < nextCounter) nextCounter = c;
|
||||
}
|
||||
|
||||
static __forceinline void cpuRcntSet() {
|
||||
int i;
|
||||
|
||||
nextCounter = (counters[4].CycleT < counters[5].CycleT) ? counters[4].CycleT : counters[5].CycleT;
|
||||
nextsCounter = cpuRegs.cycle;
|
||||
|
||||
for (i = 0; i < 4; i++) {
|
||||
if (!(counters[i].mode & 0x80) || (counters[i].mode & 0x3) == 0x3) continue; // Stopped
|
||||
|
||||
c = ((0x10000 - counters[i].count) * counters[i].rate) - (cpuRegs.cycle - counters[i].sCycleT);
|
||||
if (c < nextCounter) nextCounter = c;
|
||||
|
||||
//if(!(counters[i].mode & 0x100) || counters[i].target > 0xffff) continue;
|
||||
c = ((counters[i].target - counters[i].count) * counters[i].rate) - (cpuRegs.cycle - counters[i].sCycleT);
|
||||
if (c < nextCounter) nextCounter = c;
|
||||
}
|
||||
for (i = 0; i < 4; i++)
|
||||
_rcntSet( i );
|
||||
}
|
||||
|
||||
void rcntInit() {
|
||||
|
@ -88,7 +96,7 @@ void rcntInit() {
|
|||
#endif
|
||||
|
||||
for (i=0; i<4; i++) rcntUpd(i);
|
||||
rcntSet();
|
||||
cpuRcntSet();
|
||||
|
||||
assert(Cpu != NULL && Cpu->ExecuteVU1Block != NULL );
|
||||
s_prevExecuteVU1Block = Cpu->ExecuteVU1Block;
|
||||
|
@ -150,7 +158,7 @@ void UpdateVSyncRate() {
|
|||
iTicks = (GetTickFrequency() / 5994) * 100;
|
||||
SysPrintf("Framelimiter rate updated (UpdateVSyncRate): 59.94 fps NTSC\n");
|
||||
}
|
||||
rcntSet();
|
||||
cpuRcntSet();
|
||||
}
|
||||
|
||||
void FrameLimiter()
|
||||
|
@ -398,7 +406,7 @@ static __forceinline void hScanline()
|
|||
if (difference >= HBLANK_TIME_ ) {
|
||||
hScanlineNextCycle(difference, HBLANK_TIME_);
|
||||
rcntStartGate(0, counters[4].sCycle);
|
||||
psxCheckStartGate(0);
|
||||
psxCheckStartGate16(0);
|
||||
counters[4].mode = MODE_HRENDER;
|
||||
}
|
||||
}
|
||||
|
@ -408,13 +416,14 @@ static __forceinline void hScanline()
|
|||
if (CSRw & 0x4) GSCSRr |= 4; // signal
|
||||
if (!(GSIMR&0x400)) gsIrq();
|
||||
if (gates) rcntEndGate(0, counters[4].sCycle);
|
||||
if (psxhblankgate) psxCheckEndGate(0);
|
||||
if (psxhblankgate) psxCheckEndGate16(0);
|
||||
counters[4].mode = MODE_HBLANK;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void vSync()
|
||||
// Only called from one place so might as well inline it.
|
||||
static __forceinline void vSync()
|
||||
{
|
||||
u32 diff = (cpuRegs.cycle - counters[5].sCycle);
|
||||
|
||||
|
@ -435,7 +444,10 @@ void vSync()
|
|||
}
|
||||
}
|
||||
|
||||
void rcntUpdate()
|
||||
// forceinline note: this method is called from two locations, but one
|
||||
// of them is the interpreter, which doesn't count. ;) So might as
|
||||
// well forceinline it!
|
||||
__forceinline void rcntUpdate()
|
||||
{
|
||||
int i;
|
||||
|
||||
|
@ -488,7 +500,7 @@ void rcntUpdate()
|
|||
}
|
||||
}
|
||||
|
||||
rcntSet();
|
||||
cpuRcntSet();
|
||||
}
|
||||
|
||||
void rcntWcount(int index, u32 value)
|
||||
|
@ -506,7 +518,7 @@ void rcntWcount(int index, u32 value)
|
|||
counters[index].sCycleT = cpuRegs.cycle - change;
|
||||
}
|
||||
|
||||
rcntSet();
|
||||
_rcntSet( index );
|
||||
}
|
||||
|
||||
void rcntWmode(int index, u32 value)
|
||||
|
@ -552,7 +564,7 @@ void rcntWmode(int index, u32 value)
|
|||
counters[index].target &= 0xffff;
|
||||
}*/
|
||||
|
||||
rcntSet();
|
||||
_rcntSet( index );
|
||||
}
|
||||
|
||||
void rcntStartGate(unsigned int mode, u32 sCycle) {
|
||||
|
@ -584,6 +596,9 @@ void rcntStartGate(unsigned int mode, u32 sCycle) {
|
|||
break;
|
||||
}
|
||||
}
|
||||
// Note: No need to set counters here.
|
||||
// They'll get set later on in rcntUpdate, since we're
|
||||
// being called from there anyway.
|
||||
}
|
||||
|
||||
void rcntEndGate(unsigned int mode, u32 sCycle) {
|
||||
|
@ -601,7 +616,7 @@ void rcntEndGate(unsigned int mode, u32 sCycle) {
|
|||
break;
|
||||
case 0x10:
|
||||
counters[i].count = rcntRcount(i);
|
||||
break;
|
||||
break; // skip the _rcntSet
|
||||
case 0x20: //Reset and start counting on Vsync end
|
||||
case 0x30: //Reset and start counting on Vsync start and end
|
||||
counters[i].mode |= 0x80;
|
||||
|
@ -612,6 +627,9 @@ void rcntEndGate(unsigned int mode, u32 sCycle) {
|
|||
break;
|
||||
}
|
||||
}
|
||||
// Note: No need to set counters here.
|
||||
// They'll get set later on in rcntUpdate, since we're
|
||||
// being called from there anyway.
|
||||
}
|
||||
|
||||
void rcntWtarget(int index, u32 value) {
|
||||
|
@ -623,7 +641,7 @@ void rcntWtarget(int index, u32 value) {
|
|||
//SysPrintf("EE Saving target %d from early trigger, target = %x, count = %x\n", index, counters[index].target, rcntCycle(index));
|
||||
counters[index].target |= 0x10000000;
|
||||
}
|
||||
rcntSet();
|
||||
_rcntSet( index );
|
||||
}
|
||||
|
||||
void rcntWhold(int index, u32 value) {
|
||||
|
|
|
@ -92,8 +92,9 @@ typedef struct {
|
|||
extern Counter counters[6];
|
||||
extern u32 nextCounter, nextsCounter;
|
||||
|
||||
extern void rcntUpdate();
|
||||
|
||||
void rcntInit();
|
||||
void rcntUpdate();
|
||||
void rcntStartGate(unsigned int mode, u32 sCycle);
|
||||
void rcntEndGate(unsigned int mode, u32 sCycle);
|
||||
void rcntWcount(int index, u32 value);
|
||||
|
|
|
@ -155,127 +155,133 @@ void psxRcntInit() {
|
|||
void psxVBlankStart() {
|
||||
cdvdVsync();
|
||||
psxHu32(0x1070)|= 1;
|
||||
if(psxvblankgate & 1) psxCheckStartGate(1);
|
||||
if(psxvblankgate & (1 << 3)) psxCheckStartGate(3);
|
||||
if(psxvblankgate & 1) psxCheckStartGate16(1);
|
||||
if(psxvblankgate & (1 << 3)) psxCheckStartGate32(3);
|
||||
}
|
||||
|
||||
void psxVBlankEnd() {
|
||||
psxHu32(0x1070)|= 0x800;
|
||||
if(psxvblankgate & 1) psxCheckEndGate(1);
|
||||
if(psxvblankgate & (1 << 3)) psxCheckEndGate(3);
|
||||
if(psxvblankgate & 1) psxCheckEndGate16(1);
|
||||
if(psxvblankgate & (1 << 3)) psxCheckEndGate32(3);
|
||||
}
|
||||
|
||||
void psxCheckEndGate(int counter) { //Check Gate events when Vsync Ends
|
||||
int i = counter;
|
||||
void psxCheckEndGate16(int i)
|
||||
{
|
||||
//SysPrintf("End Gate %x\n", counter);
|
||||
if(counter < 3){ //Gates for 16bit counters
|
||||
if((psxCounters[i].mode & 0x1) == 0) return; //Ignore Gate
|
||||
|
||||
switch((psxCounters[i].mode & 0x6) >> 1) {
|
||||
case 0x0: //GATE_ON_count
|
||||
psxCounters[i].count += (u16)psxRcntRcount16(i); //Only counts when signal is on
|
||||
break;
|
||||
case 0x1: //GATE_ON_ClearStart
|
||||
if(psxCounters[i].mode & 0x10000000)psxRcntUpd16(i);
|
||||
psxCounters[i].mode &= ~0x10000000;
|
||||
break;
|
||||
case 0x2: //GATE_ON_Clear_OFF_Start
|
||||
psxCounters[i].mode &= ~0x10000000;
|
||||
psxRcntUpd16(i);
|
||||
break;
|
||||
case 0x3: //GATE_ON_Start
|
||||
break;
|
||||
default:
|
||||
SysPrintf("PCSX2 Warning: 16bit IOP Counter Gate Not Set!\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
assert(i < 3);
|
||||
|
||||
if(counter >= 3){ //Gates for 32bit counters
|
||||
if((psxCounters[i].mode & 0x1) == 0) return; //Ignore Gate
|
||||
if((psxCounters[i].mode & 0x1) == 0) return; //Ignore Gate
|
||||
|
||||
switch((psxCounters[i].mode & 0x6) >> 1) {
|
||||
case 0x0: //GATE_ON_count
|
||||
psxCounters[i].count += (u32)psxRcntRcount32(i); //Only counts when signal is on
|
||||
break;
|
||||
case 0x1: //GATE_ON_ClearStart
|
||||
if(psxCounters[i].mode & 0x10000000)psxRcntUpd32(i);
|
||||
psxCounters[i].mode &= ~0x10000000;
|
||||
break;
|
||||
case 0x2: //GATE_ON_Clear_OFF_Start
|
||||
psxCounters[i].mode &= ~0x10000000;
|
||||
psxRcntUpd32(i);
|
||||
break;
|
||||
case 0x3: //GATE_ON_Start
|
||||
break;
|
||||
default:
|
||||
SysPrintf("PCSX2 Warning: 32bit IOP Counter Gate Not Set!\n");
|
||||
break;
|
||||
}
|
||||
switch((psxCounters[i].mode & 0x6) >> 1) {
|
||||
case 0x0: //GATE_ON_count
|
||||
psxCounters[i].count += (u16)psxRcntRcount16(i); //Only counts when signal is on
|
||||
break;
|
||||
case 0x1: //GATE_ON_ClearStart
|
||||
if(psxCounters[i].mode & 0x10000000)psxRcntUpd16(i);
|
||||
psxCounters[i].mode &= ~0x10000000;
|
||||
break;
|
||||
case 0x2: //GATE_ON_Clear_OFF_Start
|
||||
psxCounters[i].mode &= ~0x10000000;
|
||||
psxRcntUpd16(i);
|
||||
break;
|
||||
case 0x3: //GATE_ON_Start
|
||||
break;
|
||||
default:
|
||||
SysPrintf("PCSX2 Warning: 16bit IOP Counter Gate Not Set!\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
void psxCheckStartGate(int counter) { //Check Gate events when Vsync Starts
|
||||
int i = counter;
|
||||
|
||||
if(counter == 0){
|
||||
void psxCheckEndGate32(int i)
|
||||
{
|
||||
assert(i >= 3);
|
||||
|
||||
if((psxCounters[i].mode & 0x1) == 0) return; //Ignore Gate
|
||||
|
||||
switch((psxCounters[i].mode & 0x6) >> 1) {
|
||||
case 0x0: //GATE_ON_count
|
||||
psxCounters[i].count += (u32)psxRcntRcount32(i); //Only counts when signal is on
|
||||
break;
|
||||
case 0x1: //GATE_ON_ClearStart
|
||||
if(psxCounters[i].mode & 0x10000000)psxRcntUpd32(i);
|
||||
psxCounters[i].mode &= ~0x10000000;
|
||||
break;
|
||||
case 0x2: //GATE_ON_Clear_OFF_Start
|
||||
psxCounters[i].mode &= ~0x10000000;
|
||||
psxRcntUpd32(i);
|
||||
break;
|
||||
case 0x3: //GATE_ON_Start
|
||||
break;
|
||||
default:
|
||||
SysPrintf("PCSX2 Warning: 32bit IOP Counter Gate Not Set!\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void psxCheckStartGate16(int i)
|
||||
{
|
||||
assert( i < 3 );
|
||||
|
||||
//Check Gate events when Vsync Starts
|
||||
|
||||
if(i == 0)
|
||||
{
|
||||
if((psxCounters[1].mode & 0x101) == 0x100 || (psxCounters[1].mode & 0x10000101) == 0x101)psxCounters[1].count++;
|
||||
if((psxCounters[3].mode & 0x101) == 0x100 || (psxCounters[3].mode & 0x10000101) == 0x101)psxCounters[3].count++;
|
||||
/*if(SPU2async)
|
||||
{
|
||||
SPU2async(psxRegs.cycle - psxCounters[6].sCycleT);
|
||||
//SysPrintf("cycles sent to SPU2 %x\n", psxRegs.cycle - psxCounters[6].sCycleT);
|
||||
psxCounters[6].sCycleT = psxRegs.cycle;
|
||||
}*/
|
||||
}
|
||||
|
||||
if((psxCounters[i].mode & 0x1) == 0) return; //Ignore Gate
|
||||
|
||||
if(counter < 3){ //Gates for 16bit counters
|
||||
//SysPrintf("PSX Gate %x\n", i);
|
||||
switch((psxCounters[i].mode & 0x6) >> 1) {
|
||||
case 0x0: //GATE_ON_count
|
||||
psxRcntUpd32(i);
|
||||
psxCounters[i].mode |= 0x10000000;
|
||||
break;
|
||||
case 0x1: //GATE_ON_ClearStart
|
||||
if(psxCounters[i].mode & 0x10000000)psxRcntUpd16(i);
|
||||
psxCounters[i].mode &= ~0x10000000;
|
||||
break;
|
||||
case 0x2: //GATE_ON_Clear_OFF_Start
|
||||
psxRcntReset32(i);
|
||||
psxCounters[i].mode |= 0x10000000;
|
||||
break;
|
||||
case 0x3: //GATE_ON_Start
|
||||
psxCounters[i].mode &= ~0x10000000;
|
||||
break;
|
||||
default:
|
||||
SysPrintf("PCSX2 Warning: 16bit IOP Counter Gate Not Set!\n");
|
||||
break;
|
||||
}
|
||||
//SysPrintf("PSX Gate %x\n", i);
|
||||
switch((psxCounters[i].mode & 0x6) >> 1)
|
||||
{
|
||||
case 0x0: //GATE_ON_count
|
||||
psxRcntUpd32(i);
|
||||
psxCounters[i].mode |= 0x10000000;
|
||||
break;
|
||||
case 0x1: //GATE_ON_ClearStart
|
||||
if(psxCounters[i].mode & 0x10000000)psxRcntUpd16(i);
|
||||
psxCounters[i].mode &= ~0x10000000;
|
||||
break;
|
||||
case 0x2: //GATE_ON_Clear_OFF_Start
|
||||
psxRcntReset32(i);
|
||||
psxCounters[i].mode |= 0x10000000;
|
||||
break;
|
||||
case 0x3: //GATE_ON_Start
|
||||
psxCounters[i].mode &= ~0x10000000;
|
||||
break;
|
||||
default:
|
||||
SysPrintf("PCSX2 Warning: 16bit IOP Counter Gate Not Set!\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(counter >= 3){ //Gates for 32bit counters
|
||||
//SysPrintf("PSX Gate %x\n", i);
|
||||
switch((psxCounters[i].mode & 0x6) >> 1) {
|
||||
case 0x0: //GATE_ON_count
|
||||
psxRcntUpd32(i);
|
||||
psxCounters[i].mode &= ~0x10000000;
|
||||
break;
|
||||
case 0x1: //GATE_ON_ClearStart
|
||||
if(psxCounters[i].mode & 0x10000000)psxRcntUpd32(i);
|
||||
psxCounters[i].mode &= ~0x10000000;
|
||||
break;
|
||||
case 0x2: //GATE_ON_Clear_OFF_Start
|
||||
psxRcntReset32(i);
|
||||
psxCounters[i].mode |= 0x10000000;
|
||||
break;
|
||||
case 0x3: //GATE_ON_Start
|
||||
psxCounters[i].mode &= ~0x10000000;
|
||||
break;
|
||||
default:
|
||||
SysPrintf("PCSX2 Warning: 32bit IOP Counter Gate Not Set!\n");
|
||||
break;
|
||||
}
|
||||
void psxCheckStartGate32(int i)
|
||||
{
|
||||
assert(i >= 3);
|
||||
|
||||
if((psxCounters[i].mode & 0x1) == 0) return; //Ignore Gate
|
||||
|
||||
//SysPrintf("PSX Gate %x\n", i);
|
||||
switch((psxCounters[i].mode & 0x6) >> 1) {
|
||||
case 0x0: //GATE_ON_count
|
||||
psxRcntUpd32(i);
|
||||
psxCounters[i].mode &= ~0x10000000;
|
||||
break;
|
||||
case 0x1: //GATE_ON_ClearStart
|
||||
if(psxCounters[i].mode & 0x10000000)psxRcntUpd32(i);
|
||||
psxCounters[i].mode &= ~0x10000000;
|
||||
break;
|
||||
case 0x2: //GATE_ON_Clear_OFF_Start
|
||||
psxRcntReset32(i);
|
||||
psxCounters[i].mode |= 0x10000000;
|
||||
break;
|
||||
case 0x3: //GATE_ON_Start
|
||||
psxCounters[i].mode &= ~0x10000000;
|
||||
break;
|
||||
default:
|
||||
SysPrintf("PCSX2 Warning: 32bit IOP Counter Gate Not Set!\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -50,7 +50,9 @@ int psxRcntFreeze(gzFile f, int Mode);
|
|||
|
||||
void psxVBlankStart();
|
||||
void psxVBlankEnd();
|
||||
void psxCheckStartGate(int counter);
|
||||
void psxCheckEndGate(int counter);
|
||||
void psxCheckStartGate16(int counter);
|
||||
void psxCheckEndGate16(int counter);
|
||||
void psxCheckStartGate32(int counter);
|
||||
void psxCheckEndGate32(int counter);
|
||||
|
||||
#endif /* __PSXCOUNTERS_H__ */
|
||||
|
|
|
@ -33,6 +33,8 @@
|
|||
using namespace std;
|
||||
|
||||
extern "C" {
|
||||
|
||||
|
||||
#include "zlib.h"
|
||||
#include "Elfheader.h"
|
||||
#include "Misc.h"
|
||||
|
|
Loading…
Reference in New Issue