changed the counters algorithm again; some games didn't like the algorithm from 228...

git-svn-id: http://pcsx2-playground.googlecode.com/svn/trunk@240 a6443dda-0b58-4228-96e9-037be469359c
This commit is contained in:
cottonvibes 2008-10-27 06:37:52 +00:00 committed by Gregory Hainaut
parent c9e333b4d5
commit 86c35c57b0
2 changed files with 53 additions and 82 deletions

View File

@ -52,7 +52,7 @@ void rcntSet() {
u32 c;
int i;
nextCounter = 0xffffffff;
nextCounter = HBLANK_TIME_;
nextsCounter = cpuRegs.cycle;
for (i = 0; i < 4; i++) {
@ -67,6 +67,7 @@ void rcntSet() {
}
//Calculate HBlank
/*
if (counters[4].mode & MODE_HBLANK) { //hBlank
if (Config.PsxType&1) { if (HBLANK_TIME_PAL < nextCounter) nextCounter = HBLANK_TIME_PAL; }
else if (HBLANK_TIME_NTSC < nextCounter) nextCounter = HBLANK_TIME_NTSC;
@ -74,7 +75,7 @@ void rcntSet() {
else { //not hBlank (drawing part of the scanline)
if (Config.PsxType&1) { if (HRENDER_TIME_PAL < nextCounter) nextCounter = HRENDER_TIME_PAL; }
else if (HRENDER_TIME_NTSC < nextCounter) nextCounter = HRENDER_TIME_NTSC;
}
}*/
}
void rcntInit() {
@ -144,7 +145,7 @@ void UpdateVSyncRate() {
counters[4].sCycle = cpuRegs.cycle; // Update Counter 4's Start Cycle to match CPU's cycle
counters[5].mode = MODE_VRENDER; // Counter 5 takes care of vSync/vBlanks
counters[5].rate = MODE_VBLANK1; // Rate is just used to alternate between vBlank1 and vBlank2 modes (because of interlacing, one half-frame can have a different number of vBlank scanlines)
counters[5].sCycle = cpuRegs.cycle; // Update Counter 5's Start Cycle to match CPU's cycle
if (Config.CustomFps > 0) {
iTicks = GetTickFrequency() / Config.CustomFps;
@ -339,6 +340,19 @@ __forceinline void frameLimit()
}
}
__forceinline void VBlankStart()
{
psxVBlankStart(); // psxCounters vBlank Start
if (gates) rcntStartGate(0x8); // Counters Start Gate code
}
__forceinline void VBlankEnd()
{
psxVBlankEnd(); // psxCounters vBlank End
if (gates) rcntEndGate(0x8); // Counters End Gate Code
SysUpdate(); // check for and handle keyevents
}
__forceinline void VSyncStart() // VSync Start (240 hsyncs)
{
vSyncDebugStuff(); // EE Profiling and Debug code
@ -346,8 +360,8 @@ __forceinline void VSyncStart() // VSync Start (240 hsyncs)
if (!(GSIMR&0x800)) gsIrq(); //GS Irq
hwIntcIrq(2); // HW Irq
VBlankStart();
if (Config.Patch) applypatch(1); // Apply patches (ToDo: clean up patch code)
}
__forceinline void VSyncEnd() // VSync End (22 hsyncs)
@ -365,110 +379,64 @@ __forceinline void VSyncEnd() // VSync End (22 hsyncs)
}
hwIntcIrq(3); // HW Irq
VBlankEnd();
frameLimit(); // limit FPS (also handles frameskip and VUskip)
}
__forceinline void VBlankStart()
{
psxVBlankStart(); // psxCounters vSync Start
if (gates) rcntStartGate(0x8); // Counters Start Gate code
}
__forceinline void VBlankEnd()
{
psxVBlankEnd(); // psxCounters vBlank End
if (gates) rcntEndGate(0x8); // Counters End Gate Code
SysUpdate(); // check for and handle keyevents
}
#define hScanlineOptimization(diff, compareValue, incrementCounters) { \
if (diff >= compareValue) { \
u32 increment = (diff / compareValue); \
SysPrintf("Counters Optimization\n"); \
counters[4].count += increment; \
if (incrementCounters) { \
/*Update counters using the hblank as the clock*/ \
if ((counters[0].mode & 0x83) == 0x83) counters[0].count += (increment * HBLANK_COUNTER_SPEED); \
if ((counters[1].mode & 0x83) == 0x83) counters[1].count += (increment * HBLANK_COUNTER_SPEED); \
if ((counters[2].mode & 0x83) == 0x83) counters[2].count += (increment * HBLANK_COUNTER_SPEED); \
if ((counters[3].mode & 0x83) == 0x83) counters[3].count += (increment * HBLANK_COUNTER_SPEED); \
u32 increment = (diff / compareValue); \
/* if counter's count increases on hblank gate's off signal OR if counter increases every hblank, THEN add to the counter */ \
if ( (!(counters[0].mode & 0x30) && (gates & (1<<0))) || (((counters[0].mode & 0x83) == 0x83) && !(gates & (1<<0))) ) counters[0].count += (increment * HBLANK_COUNTER_SPEED); \
if ( (!(counters[1].mode & 0x30) && (gates & (1<<1))) || (((counters[1].mode & 0x83) == 0x83) && !(gates & (1<<1))) ) counters[1].count += (increment * HBLANK_COUNTER_SPEED); \
if ( (!(counters[2].mode & 0x30) && (gates & (1<<2))) || (((counters[2].mode & 0x83) == 0x83) && !(gates & (1<<2))) ) counters[2].count += (increment * HBLANK_COUNTER_SPEED); \
if ( (!(counters[3].mode & 0x30) && (gates & (1<<3))) || (((counters[3].mode & 0x83) == 0x83) && !(gates & (1<<3))) ) counters[3].count += (increment * HBLANK_COUNTER_SPEED); \
} \
} \
}
int hScanline()
__forceinline void hScanline()
{
u32 difference = (cpuRegs.cycle - counters[4].sCycle);
if (counters[4].mode & MODE_HBLANK) { //HBLANK Start
if (difference >= HBLANK_TIME_ ) {
//hScanlineOptimization(difference, (SCANLINE_ + HBLANK_TIME_), 1);
hScanlineOptimization(difference, (SCANLINE_ + HBLANK_TIME_), 1);
rcntStartGate(0);
psxCheckStartGate(0);
counters[4].sCycle = cpuRegs.cycle;
counters[4].mode ^= MODE_HBLANK;
counters[4].mode = MODE_HRENDER;
}
}
else { //HBLANK END / HRENDER Begin
if (difference >= (HRENDER_TIME_)) {
//hScanlineOptimization(difference, (SCANLINE_ + HRENDER_TIME_), 0);
hScanlineOptimization(difference, (SCANLINE_ + HRENDER_TIME_), 1);
if (CSRw & 0x4) GSCSRr |= 4; // signal
if (!(GSIMR&0x400)) gsIrq();
if (gates) rcntEndGate(0);
if (psxhblankgate) psxCheckEndGate(0);
counters[4].count += HBLANK_COUNTER_SPEED; //increment counter!
counters[4].sCycle = cpuRegs.cycle;
counters[4].mode ^= MODE_HBLANK;
return 0; // Count Incremented
counters[4].mode = MODE_HBLANK;
}
}
return 1; // Count not Incremented
}
void vSync()
{
if (hScanline()) return; // render the next scanline; if no-change, then exit function
hScanline();
switch (counters[5].mode) {
case MODE_VRENDER: //vRender is running
if (counters[4].count > SCANLINES_VRENDER_) { // Check if should change state to VBlank
//VRENDER END/VBLANK START CODE HERE:
VBlankStart();
counters[4].count -= SCANLINES_VRENDER_;
counters[5].mode = MODE_VBLANK; // Set to VBLANK MODE
}
break;
case MODE_VBLANK: //vBlank is running
if (counters[5].rate == MODE_VBLANK1) {
if (counters[4].count > SCANLINES_VBLANK1_) { //Check if should change state to VSYNC
//VBLANK END/VSYNC START CODE HERE:
VBlankEnd();
VSyncStart();
counters[4].count -= SCANLINES_VBLANK1_;
counters[5].mode = MODE_VSYNC; // Set to VSYNC MODE
counters[5].rate = MODE_VBLANK2;
}
}
else {
if (counters[4].count > SCANLINES_VBLANK2_) { //Check if should change state to VSYNC
//VBLANK END/VSYNC START CODE HERE:
VBlankEnd();
VSyncStart();
counters[4].count -= SCANLINES_VBLANK2_;
counters[5].mode = MODE_VSYNC; // Set to VSYNC MODE
counters[5].rate = MODE_VBLANK1;
}
}
break;
case MODE_VSYNC: //vSync is running
if (counters[4].count > SCANLINES_VSYNC_) { //Check if should change state to VRENDER
//VSYNC END/RENDER START CODE HERE:
VSyncEnd();
counters[4].count -= SCANLINES_VSYNC_;
counters[5].mode = MODE_VRENDER; // Set to VRENDER MODE
}
break;
if ((cpuRegs.cycle - counters[5].sCycle) >= (VSYNC_ / 2)) {
if (counters[5].mode == MODE_VSYNC) {
VSyncEnd();
counters[5].mode = MODE_VRENDER;
}
else {
VSyncStart();
counters[5].mode = MODE_VSYNC;
}
counters[5].sCycle = cpuRegs.cycle;
}
}
@ -602,8 +570,8 @@ void rcntStartGate(unsigned int mode) {
switch (counters[i].mode & 0x30) {
case 0x00: //Count When Signal is low (off)
counters[i].mode &= ~0x80; // Stop Counting since signal is On
rcntUpd(i);
counters[i].mode |= 0x80;
break;
case 0x10: //Reset and start counting on Vsync start
case 0x30: //Reset and start counting on Vsync start and end
@ -624,9 +592,9 @@ void rcntEndGate(unsigned int mode) {
switch (counters[i].mode & 0x30) {
case 0x00: //Count When Signal is low (off)
counters[i].mode |= 0x80; // Start Counting since signal is Off
counters[i].count = rcntRcount(i);
rcntUpd(i);
counters[i].mode &= ~0x80;
break;
case 0x20: //Reset and start counting on Vsync end
case 0x30: //Reset and start counting on Vsync start and end

View File

@ -35,10 +35,11 @@ typedef struct {
//------------------------------------------------------------------
// NTSC Timing Information!!! (some scanline info is guessed)
//------------------------------------------------------------------
#define SCANLINE_NTSC 18743 //(PS2CLK / 15734.25)
#define HRENDER_TIME_NTSC 15528 //time from hblank end to hblank start (PS2CLK / 18991.368423051722991900181367568)
#define HBLANK_TIME_NTSC 3215 //time from hblank start to hblank end (PS2CLK / 91738.91105912572817760653181028)
#define SCANLINE_NTSC (PS2CLK / 15734.25)//18743
#define HRENDER_TIME_NTSC (u32)(SCANLINE_NTSC / 2)//15528 //time from hblank end to hblank start (PS2CLK / 18991.368423051722991900181367568)
#define HBLANK_TIME_NTSC (u32)(SCANLINE_NTSC / 2)//3215 //time from hblank start to hblank end (PS2CLK / 91738.91105912572817760653181028)
#define VSYNC_NTSC (PS2CLK / 59.94) //hz
#define VSYNC_HALF_NTSC (VSYNC_NTSC / 2) //hz
#define SCANLINES_TOTAL_NTSC 525 // total number of scanlines
#define SCANLINES_VSYNC_NTSC 3 // scanlines that are used for syncing every half-frame
@ -49,10 +50,11 @@ typedef struct {
//------------------------------------------------------------------
// PAL Timing Information!!! (some scanline info is guessed)
//------------------------------------------------------------------
#define SCANLINE_PAL 18874
#define HRENDER_TIME_PAL 15335 //time from hblank end to hblank start
#define HBLANK_TIME_PAL 3539 //time from hblank start to hblank end
#define VSYNC_PAL (PS2CLK / 50) //hz
#define SCANLINE_PAL (PS2CLK / 15625)//18874
#define HRENDER_TIME_PAL (u32)(SCANLINE_PAL / 2)//15335 //time from hblank end to hblank start
#define HBLANK_TIME_PAL (u32)(SCANLINE_PAL / 2)//3539 //time from hblank start to hblank end
#define VSYNC_PAL (PS2CLK / 50) //hz
#define VSYNC_HALF_PAL (VSYNC_PAL / 2) //hz
#define SCANLINES_TOTAL_PAL 625 // total number of scanlines
#define SCANLINES_VSYNC_PAL 5 // scanlines that are used for syncing every half-frame
@ -67,6 +69,7 @@ typedef struct {
#define HRENDER_TIME_ (u32)((Config.PsxType&1) ? HRENDER_TIME_PAL : HRENDER_TIME_NTSC) * HBLANK_TIMER_SLOWDOWN
#define HBLANK_TIME_ (u32)((Config.PsxType&1) ? HBLANK_TIME_PAL : HBLANK_TIME_NTSC) * HBLANK_TIMER_SLOWDOWN
#define VSYNC_ (u32)((Config.PsxType&1) ? VSYNC_PAL : VSYNC_NTSC)
#define VSYNC_HALF_ (u32)((Config.PsxType&1) ? VSYNC_HALF_PAL : VSYNC_HALF_NTSC)
#define SCANLINES_TOTAL_ (u32)((Config.PsxType&1) ? SCANLINES_TOTAL_PAL : SCANLINES_TOTAL_NTSC)
#define SCANLINES_VSYNC_ (u32)((Config.PsxType&1) ? SCANLINES_VSYNC_PAL : SCANLINES_VSYNC_NTSC)