From 4c7550971ee6dff37652e26225df16c90f120608 Mon Sep 17 00:00:00 2001 From: cottonvibes Date: Sun, 26 Oct 2008 04:12:27 +0000 Subject: [PATCH] fixed some counters problems, should be more smooth and stable. one of the problems i'm having is that rcntUpdate() should be called more-often, but i don't know where i should put it... git-svn-id: http://pcsx2-playground.googlecode.com/svn/trunk@238 a6443dda-0b58-4228-96e9-037be469359c --- pcsx2/Counters.c | 57 ++++++++++++++++++++++++------------------------ pcsx2/Counters.h | 2 +- 2 files changed, 30 insertions(+), 29 deletions(-) diff --git a/pcsx2/Counters.c b/pcsx2/Counters.c index 17015a360a..0f7baf2dbb 100644 --- a/pcsx2/Counters.c +++ b/pcsx2/Counters.c @@ -139,12 +139,12 @@ u64 GetCPUTicks() void UpdateVSyncRate() { - counters[4].count = 0; - counters[4].mode = MODE_HRENDER; // Counter 4 takes care of hBlanks - counters[4].sCycle = cpuRegs.cycle; // Update Counter 4's Start Cycle + counters[4].count = 0; // Set number of scanlines/hblanks to zero + counters[4].mode = MODE_HRENDER; // Counter 4 takes care of scanlines, so set the mode to HRENDER (drawing part of scanline) + 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; + 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) if (Config.CustomFps > 0) { iTicks = GetTickFrequency() / Config.CustomFps; @@ -381,16 +381,28 @@ __forceinline void VBlankEnd() 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); \ + } \ + } \ +} + int hScanline() { u32 difference = (cpuRegs.cycle - counters[4].sCycle); if (counters[4].mode & MODE_HBLANK) { //HBLANK Start if (difference >= HBLANK_TIME_ ) { - if (difference >= (SCANLINE_ + HBLANK_TIME_)) { - //SysPrintf("Counters Optimization 1\n"); - counters[4].count += (cpuRegs.cycle - counters[4].sCycle) / (SCANLINE_ + HBLANK_TIME_); - } + //hScanlineOptimization(difference, (SCANLINE_ + HBLANK_TIME_), 1); rcntStartGate(0); psxCheckStartGate(0); counters[4].sCycle = cpuRegs.cycle; @@ -399,10 +411,7 @@ int hScanline() } else { //HBLANK END / HRENDER Begin if (difference >= (HRENDER_TIME_)) { - if (difference >= (SCANLINE_ + HRENDER_TIME_)) { - //SysPrintf("Counters Optimization 2\n"); - counters[4].count += (cpuRegs.cycle - counters[4].sCycle) / (SCANLINE_ + HRENDER_TIME_); - } + //hScanlineOptimization(difference, (SCANLINE_ + HRENDER_TIME_), 0); if (CSRw & 0x4) GSCSRr |= 4; // signal if (!(GSIMR&0x400)) gsIrq(); if (gates) rcntEndGate(0); @@ -411,10 +420,10 @@ int hScanline() counters[4].sCycle = cpuRegs.cycle; counters[4].mode ^= MODE_HBLANK; - return 0; + return 0; // Count Incremented } } - return 1; + return 1; // Count not Incremented } void vSync() @@ -559,7 +568,7 @@ void rcntWmode(int index, u32 value) case 0: counters[index].rate = 2; break; case 1: counters[index].rate = 32; break; case 2: counters[index].rate = 512; break; - case 3: counters[index].rate = PS2HBLANK; break; + case 3: counters[index].rate = SCANLINE_; break; } if((counters[index].mode & 0xF) == 0x7) { @@ -587,19 +596,14 @@ void rcntStartGate(unsigned int mode) { for (i=0; i <=3; i++) { //Gates for counters - if ((mode == 0) && ((counters[i].mode & 0x83) == 0x83)) counters[i].count++; //Update counters using the hblank as the clock + if ((mode == 0) && ((counters[i].mode & 0x83) == 0x83)) counters[i].count += HBLANK_COUNTER_SPEED; //Update counters using the hblank as the clock if (!(gates & (1<> 4); switch (counters[i].mode & 0x30) { case 0x00: //Count When Signal is low (off) - counters[i].count = rcntRcount(i); rcntUpd(i); - counters[i].mode &= ~0x80; - break; - case 0x20: //Reset and start counting on Vsync end - //Do Nothing + 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 @@ -607,7 +611,6 @@ void rcntStartGate(unsigned int mode) { rcntReset(i); counters[i].target &= 0xffff; break; - } } } @@ -618,14 +621,12 @@ void rcntEndGate(unsigned int mode) { for(i=0; i <=3; i++) { //Gates for counters if (!(gates & (1<> 4); + switch (counters[i].mode & 0x30) { case 0x00: //Count When Signal is low (off) + counters[i].count = rcntRcount(i); rcntUpd(i); - counters[i].mode |= 0x80; - break; - case 0x10: //Reset and start counting on Vsync start - //Do Nothing + 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 7476fa98bb..8ee6d0805f 100644 --- a/pcsx2/Counters.h +++ b/pcsx2/Counters.h @@ -61,7 +61,7 @@ typedef struct { #define SCANLINES_VBLANK2_PAL 20 // scanlines used for vblank2 (odd interlace) //------------------------------------------------------------------ -// PAL Timing Information!!! +// Timing (PAL/NTSC) Information!!! //------------------------------------------------------------------ #define SCANLINE_ (u32)((Config.PsxType&1) ? SCANLINE_PAL : SCANLINE_NTSC) * HBLANK_TIMER_SLOWDOWN #define HRENDER_TIME_ (u32)((Config.PsxType&1) ? HRENDER_TIME_PAL : HRENDER_TIME_NTSC) * HBLANK_TIMER_SLOWDOWN