diff options
| author | SND\edgbla_cp <SND\edgbla_cp@e17a0e51-4ae3-4d35-97c3-1a29b211df97> | 2010-05-02 16:52:05 +0000 |
|---|---|---|
| committer | SND\edgbla_cp <SND\edgbla_cp@e17a0e51-4ae3-4d35-97c3-1a29b211df97> | 2010-05-02 16:52:05 +0000 |
| commit | 462adb75586b96728d66698bb20a934f38dd674d (patch) | |
| tree | 5a5ed9684f69c53e5896f0b6f1e15fb08203eed4 /libpcsxcore | |
| parent | 3adece8b48417154bcb6d6d0932db74458e6835c (diff) | |
| download | pcsxr-462adb75586b96728d66698bb20a934f38dd674d.tar.gz | |
Root counters code was written from scratch.
Final Fantasy 8/9, Vandal Hearts 1/2, Wipeout, Lifeforce Tenka work properly now.
Parasite Eve 2 and InuYasha weren't fixed - it's impossible right now, an overall
emulator's precision is too low. It's needed to count the proper CPU timing and to get rid of BIAS.
Because of the same reason it's useless to set the vsync interrupt on vblank, even if it
would fix some games - Pandemonium for example, but would also broke the
others - Final Fantasy IX for example, I've chosen the last one.
Savestate compatibility is lost.
git-svn-id: https://pcsxr.svn.codeplex.com/svn/pcsxr@47077 e17a0e51-4ae3-4d35-97c3-1a29b211df97
Diffstat (limited to 'libpcsxcore')
| -rw-r--r-- | libpcsxcore/ix86/iR3000A.c | 10 | ||||
| -rw-r--r-- | libpcsxcore/ix86_64/iR3000A-64.c | 10 | ||||
| -rw-r--r-- | libpcsxcore/misc.c | 4 | ||||
| -rw-r--r-- | libpcsxcore/ppc/pR3000A.c | 22 | ||||
| -rw-r--r-- | libpcsxcore/psxcounters.c | 600 | ||||
| -rw-r--r-- | libpcsxcore/psxcounters.h | 26 | ||||
| -rw-r--r-- | libpcsxcore/psxhw.c | 24 |
7 files changed, 469 insertions, 227 deletions
diff --git a/libpcsxcore/ix86/iR3000A.c b/libpcsxcore/ix86/iR3000A.c index f3e4058f..2bd70586 100644 --- a/libpcsxcore/ix86/iR3000A.c +++ b/libpcsxcore/ix86/iR3000A.c @@ -1354,16 +1354,22 @@ static void recLHU() { if (!_Rt_) return; iRegs[_Rt_].state = ST_UNK; - MOVZX32M16toR(EAX, (u32)&psxCounters[(addr >> 4) & 0x3].mode); + PUSH32I((addr >> 4) & 0x3); + CALLFunc((u32)psxRcntRmode); + MOVZX32R16toR(EAX, EAX); MOV32RtoM((u32)&psxRegs.GPR.r[_Rt_], EAX); + resp+= 4; return; case 0x1f801108: case 0x1f801118: case 0x1f801128: if (!_Rt_) return; iRegs[_Rt_].state = ST_UNK; - MOVZX32M16toR(EAX, (u32)&psxCounters[(addr >> 4) & 0x3].target); + PUSH32I((addr >> 4) & 0x3); + CALLFunc((u32)psxRcntRtarget); + MOVZX32R16toR(EAX, EAX); MOV32RtoM((u32)&psxRegs.GPR.r[_Rt_], EAX); + resp+= 4; return; } } diff --git a/libpcsxcore/ix86_64/iR3000A-64.c b/libpcsxcore/ix86_64/iR3000A-64.c index 2a636cfc..399ec09f 100644 --- a/libpcsxcore/ix86_64/iR3000A-64.c +++ b/libpcsxcore/ix86_64/iR3000A-64.c @@ -1428,16 +1428,22 @@ static void recLHU() { if (!_Rt_) return; iRegs[_Rt_].state = ST_UNK; - MOVZX32M16toR(EAX, (uptr)&psxCounters[(addr >> 4) & 0x3].mode); + MOV64ItoR(X86ARG1, (addr >> 4) & 0x3); + CALLFunc((uptr)psxRcntRmode); + MOVZX32R16toR(EAX, EAX); MOV32RtoM((uptr)&psxRegs.GPR.r[_Rt_], EAX); + resp+= 4; return; case 0x1f801108: case 0x1f801118: case 0x1f801128: if (!_Rt_) return; iRegs[_Rt_].state = ST_UNK; - MOVZX32M16toR(EAX, (uptr)&psxCounters[(addr >> 4) & 0x3].target); + MOV64ItoR(X86ARG1, (addr >> 4) & 0x3); + CALLFunc((uptr)psxRcntRtarget); + MOVZX32R16toR(EAX, EAX); MOV32RtoM((uptr)&psxRegs.GPR.r[_Rt_], EAX); + resp+= 4; return; } } diff --git a/libpcsxcore/misc.c b/libpcsxcore/misc.c index 7d773b96..c40723c1 100644 --- a/libpcsxcore/misc.c +++ b/libpcsxcore/misc.c @@ -337,7 +337,7 @@ int CheckCdrom() { Config.PsxType = 1; // pal else Config.PsxType = 0; // ntsc } - psxUpdateVSyncRate(); + if (CdromLabel[0] == ' ') { strncpy(CdromLabel, CdromId, 9); } @@ -612,7 +612,7 @@ int RecvPcsxInfo() { NET_recvData(&Config.SpuIrq, sizeof(Config.SpuIrq), PSE_NET_BLOCKING); NET_recvData(&Config.RCntFix, sizeof(Config.RCntFix), PSE_NET_BLOCKING); NET_recvData(&Config.PsxType, sizeof(Config.PsxType), PSE_NET_BLOCKING); - psxUpdateVSyncRate(); + //psxUpdateVSyncRate(); SysUpdate(); diff --git a/libpcsxcore/ppc/pR3000A.c b/libpcsxcore/ppc/pR3000A.c index 7d1628ae..d0037b64 100644 --- a/libpcsxcore/ppc/pR3000A.c +++ b/libpcsxcore/ppc/pR3000A.c @@ -13,7 +13,7 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin Steet, Fifth Floor, Boston, MA 02111-1307 USA */ #ifdef _MSC_VER_ @@ -2011,15 +2011,27 @@ static void recLHU() { case 0x1f801104: case 0x1f801114: case 0x1f801124: if (!_Rt_) return; - LIW(PutHWReg32(_Rt_), (u32)&psxCounters[(addr >> 4) & 0x3].mode); - LWZ(PutHWReg32(_Rt_), 0, GetHWReg32(_Rt_)); + ReserveArgs(1); + LIW(PutHWRegSpecial(ARG1), (addr >> 4) & 0x3); + DisposeHWReg(iRegs[_Rt_].reg); + InvalidateCPURegs(); + CALLFunc((u32)psxRcntRmode); + + SetDstCPUReg(3); + PutHWReg32(_Rt_); return; case 0x1f801108: case 0x1f801118: case 0x1f801128: if (!_Rt_) return; - LIW(PutHWReg32(_Rt_), (u32)&psxCounters[(addr >> 4) & 0x3].target); - LWZ(PutHWReg32(_Rt_), 0, GetHWReg32(_Rt_)); + ReserveArgs(1); + LIW(PutHWRegSpecial(ARG1), (addr >> 4) & 0x3); + DisposeHWReg(iRegs[_Rt_].reg); + InvalidateCPURegs(); + CALLFunc((u32)psxRcntRtarget); + + SetDstCPUReg(3); + PutHWReg32(_Rt_); return; } } diff --git a/libpcsxcore/psxcounters.c b/libpcsxcore/psxcounters.c index 34710299..2b7acaf1 100644 --- a/libpcsxcore/psxcounters.c +++ b/libpcsxcore/psxcounters.c @@ -1,5 +1,5 @@ /*************************************************************************** - * Copyright (C) 2007 Ryan Schultz, PCSX-df Team, PCSX team * + * Copyright (C) 2010 by Blade_Arma * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * @@ -18,230 +18,452 @@ ***************************************************************************/ /* -* Internal PSX counters. -*/ + * Internal PSX counters. + */ #include "psxcounters.h" #include "cheat.h" -static int cnts = 4; -psxCounter psxCounters[5]; - -static void psxRcntUpd(unsigned long index) { - psxCounters[index].sCycle = psxRegs.cycle; - if (((!(psxCounters[index].mode & 1)) || (index!=2)) && - psxCounters[index].mode & 0x30) { - if (psxCounters[index].mode & 0x10) { // Interrupt on target - psxCounters[index].Cycle = ((psxCounters[index].target - psxCounters[index].count) * psxCounters[index].rate) / BIAS; - } else { // Interrupt on 0xffff - psxCounters[index].Cycle = ((0xffff - psxCounters[index].count) * psxCounters[index].rate) / BIAS; - } - } else psxCounters[index].Cycle = 0xffffffff; -// if (index == 2) SysPrintf("Cycle %x\n", psxCounters[index].Cycle); +/******************************************************************************/ + +typedef struct +{ + u16 mode, target; + u32 rate, irq, counterState, irqState; + u32 cycle, cycleStart; +} Rcnt; + +enum +{ + Rc0Gate = 0x0001, // 0 not implemented + Rc1Gate = 0x0001, // 0 not implemented + Rc2Disable = 0x0001, // 0 not implemented + RcUnknown1 = 0x0002, // 1 ? + RcUnknown2 = 0x0004, // 2 ? + RcCountToTarget = 0x0008, // 3 + RcIrqOnTarget = 0x0010, // 4 + RcIrqOnOverflow = 0x0020, // 5 + RcIrqRegenerate = 0x0040, // 6 + RcUnknown7 = 0x0080, // 7 ? + Rc0PixelClock = 0x0100, // 8 fake implementation + Rc1HSyncClock = 0x0100, // 8 + Rc2Unknown8 = 0x0100, // 8 ? + Rc0Unknown9 = 0x0200, // 9 ? + Rc1Unknown9 = 0x0200, // 9 ? + Rc2OneEighthClock = 0x0200, // 9 + RcUnknown10 = 0x0400, // 10 ? + RcCountEqTarget = 0x0800, // 11 + RcOverflow = 0x1000, // 12 + RcUnknown13 = 0x2000, // 13 ? (always zero) + RcUnknown14 = 0x4000, // 14 ? (always zero) + RcUnknown15 = 0x8000, // 15 ? (always zero) +}; + +#define CounterQuantity ( 4 ) +//static const u32 CounterQuantity = 4; + +static const u32 CountToOverflow = 0; +static const u32 CountToTarget = 1; + +static const u32 FrameRate[] = { 60, 50 }; +static const u32 VBlankStart[] = { 240, 256 }; +static const u32 HSyncTotal[] = { 262, 312 }; +static const u32 SpuUpdInterval[] = { 23, 22 }; + +static const s32 VerboseLevel = 0; + +/******************************************************************************/ + +static Rcnt rcnts[ CounterQuantity ]; + +static u32 hSyncCount; +static u32 spuSyncCount; + +/******************************************************************************/ + +static inline +void setIrq( u32 irq ) +{ + psxHu32ref(0x1070) |= SWAPu32(irq); + psxRegs.interrupt |= 0x80000000; } -static void psxRcntReset(unsigned long index) { -// SysPrintf("psxRcntReset %x (mode=%x)\n", index, psxCounters[index].mode); - psxCounters[index].count = 0; - psxRcntUpd(index); - -// if (index == 2) SysPrintf("rcnt2 %x\n", psxCounters[index].mode); - psxHu32ref(0x1070)|= SWAPu32(psxCounters[index].interrupt); - psxRegs.interrupt|= 0x80000000; - if (!(psxCounters[index].mode & 0x40)) { // Only 1 interrupt - psxCounters[index].Cycle = 0xffffffff; - } // else Continuos interrupt mode +static +void verboseLog( s32 level, const s8 *str, ... ) +{ + if( level <= VerboseLevel ) + { + va_list va; + char buf[ 4096 ]; + + va_start( va, str ); + vsprintf( buf, str, va ); + va_end( va ); + + printf( buf ); + fflush( stdout ); + } } -static void psxRcntSet() { - int i; - - psxNextCounter = 0x7fffffff; - psxNextsCounter = psxRegs.cycle; - - for (i=0; i<cnts; i++) { - s32 count; +/******************************************************************************/ + +static inline +void _psxRcntWcount( u32 index, u32 value ) +{ + if( value > 0xffff ) + { + verboseLog( 1, "[RCNT %i] wcount > 0xffff: %x\n", index, value ); + value &= 0xffff; + } + + rcnts[index].cycleStart = psxRegs.cycle * BIAS; + rcnts[index].cycleStart -= value * rcnts[index].rate; + + // TODO: <= + if( value < rcnts[index].target ) + { + rcnts[index].cycle = rcnts[index].target * rcnts[index].rate; + rcnts[index].counterState = CountToTarget; + } + else + { + rcnts[index].cycle = 0xffff * rcnts[index].rate; + rcnts[index].counterState = CountToOverflow; + } +} - if (psxCounters[i].Cycle == 0xffffffff) continue; +static inline +u32 _psxRcntRcount( u32 index ) +{ + u32 count; - count = psxCounters[i].Cycle - (psxRegs.cycle - psxCounters[i].sCycle); + count = psxRegs.cycle * BIAS; + count -= rcnts[index].cycleStart; + count /= rcnts[index].rate; - if (count < 0) { - psxNextCounter = 0; break; - } + if( count > 0xffff ) + { + verboseLog( 1, "[RCNT %i] rcount > 0xffff: %x\n", index, count ); + count &= 0xffff; + } - if (count < (s32)psxNextCounter) { - psxNextCounter = count; - } - } + return count; } -void psxRcntInit() { +/******************************************************************************/ + +static +void psxRcntSet() +{ + s32 countToUpdate; + u32 i; - memset(psxCounters, 0, sizeof(psxCounters)); + psxNextsCounter = psxRegs.cycle * BIAS; + psxNextCounter = 0x7fffffff; - psxCounters[0].rate = 1; psxCounters[0].interrupt = 0x10; - psxCounters[1].rate = 1; psxCounters[1].interrupt = 0x20; - psxCounters[2].rate = 1; psxCounters[2].interrupt = 0x40; + for( i = 0; i < CounterQuantity; ++i ) + { + countToUpdate = rcnts[i].cycle - (psxNextsCounter - rcnts[i].cycleStart); - psxCounters[3].interrupt = 1; - psxCounters[3].mode = 0x58; // The VSync counter mode - psxCounters[3].target = 1; - psxUpdateVSyncRate(); + if( countToUpdate < 0 ) + { + psxNextCounter = 0; + break; + } - if (SPU_async != NULL) { - cnts = 5; + if( countToUpdate < (s32)psxNextCounter ) + { + psxNextCounter = countToUpdate; + } + } +} - psxCounters[4].rate = 768 * 64; - psxCounters[4].target = 1; - psxCounters[4].mode = 0x58; - } else cnts = 4; +/******************************************************************************/ + +static +void psxRcntReset( u32 index ) +{ + u32 count; + + if( rcnts[index].counterState == CountToTarget ) + { + if( rcnts[index].mode & RcCountToTarget ) + { + count = psxRegs.cycle * BIAS; + count -= rcnts[index].cycleStart; + count /= rcnts[index].rate; + count -= rcnts[index].target; + } + else + { + count = _psxRcntRcount( index ); + } + + _psxRcntWcount( index, count ); + + if( rcnts[index].mode & RcIrqOnTarget ) + { + if( (rcnts[index].mode & RcIrqRegenerate) || (!rcnts[index].irqState) ) + { + setIrq( rcnts[index].irq ); + rcnts[index].irqState = 1; + } + } + + rcnts[index].mode |= RcCountEqTarget; + } + else if( rcnts[index].counterState == CountToOverflow ) + { + count = psxRegs.cycle * BIAS; + count -= rcnts[index].cycleStart; + count /= rcnts[index].rate; + count -= 0xffff; + + _psxRcntWcount( index, count ); + + if( rcnts[index].mode & RcIrqOnOverflow ) + { + if( (rcnts[index].mode & RcIrqRegenerate) || (!rcnts[index].irqState) ) + { + setIrq( rcnts[index].irq ); + rcnts[index].irqState = 1; + } + } + + rcnts[index].mode |= RcOverflow; + } + + rcnts[index].mode |= RcUnknown10; + + psxRcntSet(); +} - psxRcntUpd(0); psxRcntUpd(1); psxRcntUpd(2); psxRcntUpd(3); - psxRcntSet(); +void psxRcntUpdate() +{ + u32 cycle; + + cycle = psxRegs.cycle * BIAS; + + // rcnt 0. + if( cycle - rcnts[0].cycleStart >= rcnts[0].cycle ) + { + psxRcntReset( 0 ); + } + + // rcnt 1. + if( cycle - rcnts[1].cycleStart >= rcnts[1].cycle ) + { + psxRcntReset( 1 ); + } + + // rcnt 2. + if( cycle - rcnts[2].cycleStart >= rcnts[2].cycle ) + { + psxRcntReset( 2 ); + } + + // rcnt base. + if( cycle - rcnts[3].cycleStart >= rcnts[3].cycle ) + { + psxRcntReset( 3 ); + + spuSyncCount++; + hSyncCount++; + + // Update spu. + if( spuSyncCount == SpuUpdInterval[Config.PsxType] ) + { + spuSyncCount = 0; + + if( SPU_async ) + { + SPU_async( SpuUpdInterval[Config.PsxType] * rcnts[3].target ); + } + } + /* + // For the best times. :D + // VSync irq. + if( hSyncCount == VBlankStart[Config.PsxType] ) + { + setIrq( 0x01 ); + } + */ + // Update lace. (with InuYasha fix) + if( hSyncCount == (Config.VSyncWA ? HSyncTotal[Config.PsxType] / 2 : HSyncTotal[Config.PsxType]) ) + { + hSyncCount = 0; + + setIrq( 0x01 ); + + GPU_updateLace(); + SysUpdate(); + ApplyCheats(); + } + } + + DebugVSync(); } -void psxUpdateVSyncRate() { - if (Config.PsxType) // ntsc - 0 | pal - 1 - psxCounters[3].rate = (PSXCLK / 50);// / BIAS; - else psxCounters[3].rate = (PSXCLK / 60);// / BIAS; - psxCounters[3].rate-= (psxCounters[3].rate / 262) * 22; - if (Config.VSyncWA) psxCounters[3].rate/= 2; +/******************************************************************************/ + +void psxRcntWcount( u32 index, u32 value ) +{ + verboseLog( 2, "[RCNT %i] wcount: %x\n", index, value ); + + psxRcntUpdate(); + + _psxRcntWcount( index, value ); + psxRcntSet(); } -void psxUpdateVSyncRateEnd() { - if (Config.PsxType) // ntsc - 0 | pal - 1 - psxCounters[3].rate = (PSXCLK / 50);// / BIAS; - else psxCounters[3].rate = (PSXCLK / 60);// / BIAS; - psxCounters[3].rate = (psxCounters[3].rate / 262) * 22; - if (Config.VSyncWA) psxCounters[3].rate/= 2; +void psxRcntWmode( u32 index, u32 value ) +{ + verboseLog( 1, "[RCNT %i] wmode: %x\n", index, value ); + + psxRcntUpdate(); + + rcnts[index].mode = value; + rcnts[index].irqState = 0; + + switch( index ) + { + case 0: + if( value & Rc0PixelClock ) + { + rcnts[index].rate = 5; + } + else + { + rcnts[index].rate = 1; + } + break; + case 1: + if( value & Rc1HSyncClock ) + { + rcnts[index].rate = (PSXCLK / (FrameRate[Config.PsxType] * HSyncTotal[Config.PsxType])); + } + else + { + rcnts[index].rate = 1; + } + break; + case 2: + if( value & Rc2OneEighthClock ) + { + rcnts[index].rate = 8; + } + else + { + rcnts[index].rate = 1; + } + break; + } + + _psxRcntWcount( index, 0 ); + psxRcntSet(); } -void psxRcntUpdate() { - if ((psxRegs.cycle - psxCounters[3].sCycle) >= psxCounters[3].Cycle) { - if (psxCounters[3].mode & 0x10000) { // VSync End (22 hsyncs) - psxCounters[3].mode&=~0x10000; - psxUpdateVSyncRate(); - psxRcntUpd(3); - GPU_updateLace(); // updateGPU - SysUpdate(); - ApplyCheats(); -#ifdef GTE_LOG - GTE_LOG("VSync\n"); -#endif - } else { // VSync Start (240 hsyncs) - psxCounters[3].mode|= 0x10000; - psxUpdateVSyncRateEnd(); - psxRcntUpd(3); - psxHu32ref(0x1070)|= SWAPu32(1); - psxRegs.interrupt|= 0x80000000; - } - } - - if ((psxRegs.cycle - psxCounters[0].sCycle) >= psxCounters[0].Cycle) { - psxRcntReset(0); - } - - if ((psxRegs.cycle - psxCounters[1].sCycle) >= psxCounters[1].Cycle) { - psxRcntReset(1); - } - - if ((psxRegs.cycle - psxCounters[2].sCycle) >= psxCounters[2].Cycle) { - psxRcntReset(2); - } - - if (cnts >= 5) { - if ((psxRegs.cycle - psxCounters[4].sCycle) >= psxCounters[4].Cycle) { - SPU_async((psxRegs.cycle - psxCounters[4].sCycle) * BIAS); - psxRcntReset(4); - } - } - - psxRcntSet(); - DebugVSync(); +void psxRcntWtarget( u32 index, u32 value ) +{ + verboseLog( 1, "[RCNT %i] wtarget: %x\n", index, value ); + + psxRcntUpdate(); + + rcnts[index].target = value; + + _psxRcntWcount( index, _psxRcntRcount( index ) ); + psxRcntSet(); } -void psxRcntWcount(u32 index, u32 value) { -// SysPrintf("writeCcount[%d] = %x\n", index, value); -// PSXCPU_LOG("writeCcount[%d] = %x\n", index, value); - psxCounters[index].count = value; - psxRcntUpd(index); - psxRcntSet(); +/******************************************************************************/ + +u32 psxRcntRcount( u32 index ) +{ + u32 count; + + psxRcntUpdate(); + + count = _psxRcntRcount( index ); + + // Parasite Eve 2 fix. + if( index == 2 ) + { + if( Config.RCntFix ) + { + if( rcnts[index].counterState == CountToTarget ) + { + count /= BIAS; + } + } + } + + verboseLog( 2, "[RCNT %i] rcount: %x\n", index, count ); + + return count; } -void psxRcntWmode(u32 index, u32 value) { -// SysPrintf("writeCmode[%ld] = %lx\n", index, value); - psxCounters[index].mode = value; - psxCounters[index].count = 0; - if(index == 0) { - switch (value & 0x300) { - case 0x100: - psxCounters[index].rate = ((psxCounters[3].rate /** BIAS*/) / 386) / 262; // seems ok - break; - default: - psxCounters[index].rate = 1; - } - } - else if(index == 1) { - switch (value & 0x300) { - case 0x100: - psxCounters[index].rate = (psxCounters[3].rate /** BIAS*/) / 262; // seems ok - break; - default: - psxCounters[index].rate = 1; - } - } - else if(index == 2) { - switch (value & 0x300) { - case 0x200: - psxCounters[index].rate = 8; // 1/8 speed - break; - default: - psxCounters[index].rate = 1; // normal speed - } - } - - // Need to set a rate and target - psxRcntUpd(index); - psxRcntSet(); +u32 psxRcntRmode( u32 index ) +{ + u16 mode; + + psxRcntUpdate(); + + mode = rcnts[index].mode; + rcnts[index].mode &= 0xe7ff; + + verboseLog( 2, "[RCNT %i] rmode: %x\n", index, mode ); + + return mode; } -void psxRcntWtarget(u32 index, u32 value) { -// SysPrintf("writeCtarget[%ld] = %lx\n", index, value); - psxCounters[index].target = value; - psxRcntUpd(index); - psxRcntSet(); +u32 psxRcntRtarget( u32 index ) +{ + verboseLog( 2, "[RCNT %i] rtarget: %x\n", index, rcnts[index].target ); + + return rcnts[index].target; } -u32 psxRcntRcount(u32 index) { - u32 ret; - -// if ((!(psxCounters[index].mode & 1)) || (index!=2)) { - if (psxCounters[index].mode & 0x08) { // Wrap at target - if (Config.RCntFix) { // Parasite Eve 2 - ret = (psxCounters[index].count + /*BIAS **/ ((psxRegs.cycle - psxCounters[index].sCycle) / psxCounters[index].rate)) & 0xffff; - } else { - ret = (psxCounters[index].count + BIAS * ((psxRegs.cycle - psxCounters[index].sCycle) / psxCounters[index].rate)) & 0xffff; - } - } else { // Wrap at 0xffff - ret = (psxCounters[index].count + BIAS * (psxRegs.cycle / psxCounters[index].rate)) & 0xffff; - if (Config.RCntFix) { // Vandal Hearts 1/2 - ret/= 16; - } - } -// return (psxCounters[index].count + BIAS * ((psxRegs.cycle - psxCounters[index].sCycle) / psxCounters[index].rate)) & 0xffff; -// } else return 0; - -// SysPrintf("readCcount[%ld] = %lx (mode %lx, target %lx, cycle %lx)\n", index, ret, psxCounters[index].mode, psxCounters[index].target, psxRegs.cycle); - - return ret; +/******************************************************************************/ + +void psxRcntInit() +{ + s32 i; + + // rcnt0. + rcnts[0].rate = 1; + rcnts[0].irq = 0x10; + + // rcnt1. + rcnts[1].rate = 1; + rcnts[1].irq = 0x20; + + // rcnt2. + rcnts[2].rate = 1; + rcnts[2].irq = 0x40; + + // rcnt base. + rcnts[3].rate = 1; + rcnts[3].mode = RcCountToTarget; + rcnts[3].target = (PSXCLK / (FrameRate[Config.PsxType] * HSyncTotal[Config.PsxType])); + + for( i = 0; i < CounterQuantity; ++i ) + { + _psxRcntWcount( i, 0 ); + } + + psxRcntSet(); } -int psxRcntFreeze(gzFile f, int Mode) { - char Unused[4096 - sizeof(psxCounter)]; +/******************************************************************************/ - gzfreezel(psxCounters); - gzfreezel(Unused); +s32 psxRcntFreeze( gzFile f, s32 Mode ) +{ + s8 unused[ 4096 - sizeof(rcnts) ]; - return 0; + gzfreezel( rcnts ); + gzfreezel( unused ); + + return 0; } + +/******************************************************************************/ diff --git a/libpcsxcore/psxcounters.h b/libpcsxcore/psxcounters.h index c292b679..30ea6954 100644 --- a/libpcsxcore/psxcounters.h +++ b/libpcsxcore/psxcounters.h @@ -1,5 +1,5 @@ /*************************************************************************** - * Copyright (C) 2007 Ryan Schultz, PCSX-df Team, PCSX team * + * Copyright (C) 2010 by Blade_Arma * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * @@ -25,23 +25,19 @@ #include "psxmem.h" #include "plugins.h" -typedef struct { - u32 count, mode, target; - u32 sCycle, Cycle, rate, interrupt; -} psxCounter; - -extern psxCounter psxCounters[5]; - u32 psxNextCounter, psxNextsCounter; void psxRcntInit(); void psxRcntUpdate(); -void psxRcntWcount(u32 index, u32 value); -void psxRcntWmode(u32 index, u32 value); -void psxRcntWtarget(u32 index, u32 value); -u32 psxRcntRcount(u32 index); -int psxRcntFreeze(gzFile f, int Mode); -void psxUpdateVSyncRate(); +void psxRcntWcount( u32 index, u32 value ); +void psxRcntWmode( u32 index, u32 value ); +void psxRcntWtarget( u32 index, u32 value ); + +u32 psxRcntRcount( u32 index ); +u32 psxRcntRmode( u32 index ); +u32 psxRcntRtarget( u32 index ); + +s32 psxRcntFreeze( gzFile f, s32 Mode ); -#endif /* __PSXCOUNTERS_H__ */ +#endif // __PSXCOUNTERS_H__ diff --git a/libpcsxcore/psxhw.c b/libpcsxcore/psxhw.c index 5b1e6963..3139fc35 100644 --- a/libpcsxcore/psxhw.c +++ b/libpcsxcore/psxhw.c @@ -118,13 +118,13 @@ u16 psxHwRead16(u32 add) { #endif return hard; case 0x1f801104: - hard = psxCounters[0].mode; + hard = psxRcntRmode(0); #ifdef PSXHW_LOG PSXHW_LOG("T0 mode read16: %x\n", hard); #endif return hard; case 0x1f801108: - hard = psxCounters[0].target; + hard = psxRcntRtarget(0); #ifdef PSXHW_LOG PSXHW_LOG("T0 target read16: %x\n", hard); #endif @@ -136,13 +136,13 @@ u16 psxHwRead16(u32 add) { #endif return hard; case 0x1f801114: - hard = psxCounters[1].mode; + hard = psxRcntRmode(1); #ifdef PSXHW_LOG PSXHW_LOG("T1 mode read16: %x\n", hard); #endif return hard; case 0x1f801118: - hard = psxCounters[1].target; + hard = psxRcntRtarget(1); #ifdef PSXHW_LOG PSXHW_LOG("T1 target read16: %x\n", hard); #endif @@ -154,13 +154,13 @@ u16 psxHwRead16(u32 add) { #endif return hard; case 0x1f801124: - hard = psxCounters[2].mode; + hard = psxRcntRmode(2); #ifdef PSXHW_LOG PSXHW_LOG("T2 mode read16: %x\n", hard); #endif return hard; case 0x1f801128: - hard = psxCounters[2].target; + hard = psxRcntRtarget(2); #ifdef PSXHW_LOG PSXHW_LOG("T2 target read16: %x\n", hard); #endif @@ -273,13 +273,13 @@ u32 psxHwRead32(u32 add) { #endif return hard; case 0x1f801104: - hard = psxCounters[0].mode; + hard = psxRcntRmode(0); #ifdef PSXHW_LOG PSXHW_LOG("T0 mode read32: %lx\n", hard); #endif return hard; case 0x1f801108: - hard = psxCounters[0].target; + hard = psxRcntRtarget(0); #ifdef PSXHW_LOG PSXHW_LOG("T0 target read32: %lx\n", hard); #endif @@ -291,13 +291,13 @@ u32 psxHwRead32(u32 add) { #endif return hard; case 0x1f801114: - hard = psxCounters[1].mode; + hard = psxRcntRmode(1); #ifdef PSXHW_LOG PSXHW_LOG("T1 mode read32: %lx\n", hard); #endif return hard; case 0x1f801118: - hard = psxCounters[1].target; + hard = psxRcntRtarget(1); #ifdef PSXHW_LOG PSXHW_LOG("T1 target read32: %lx\n", hard); #endif @@ -309,13 +309,13 @@ u32 psxHwRead32(u32 add) { #endif return hard; case 0x1f801124: - hard = psxCounters[2].mode; + hard = psxRcntRmode(2); #ifdef PSXHW_LOG PSXHW_LOG("T2 mode read32: %lx\n", hard); #endif return hard; case 0x1f801128: - hard = psxCounters[2].target; + hard = psxRcntRtarget(2); #ifdef PSXHW_LOG PSXHW_LOG("T2 target read32: %lx\n", hard); #endif |
