From 86c35c57b036ca6273952e47b7c96084a3813906 Mon Sep 17 00:00:00 2001 From: cottonvibes Date: Mon, 27 Oct 2008 06:37:52 +0000 Subject: [PATCH] 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 --- pcsx2/Counters.c | 118 +++++++++++++++++------------------------------ pcsx2/Counters.h | 17 ++++--- 2 files changed, 53 insertions(+), 82 deletions(-) diff --git a/pcsx2/Counters.c b/pcsx2/Counters.c index 0f7baf2dbb..b97fe2286f 100644 --- a/pcsx2/Counters.c +++ b/pcsx2/Counters.c @@ -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 diff --git a/pcsx2/Counters.h b/pcsx2/Counters.h index 8ee6d0805f..1b66772f32 100644 --- a/pcsx2/Counters.h +++ b/pcsx2/Counters.h @@ -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)