X-Git-Url: https://notaz.gp2x.de/cgi-bin/gitweb.cgi?p=pcsx_rearmed.git;a=blobdiff_plain;f=libpcsxcore%2Fpsxcounters.c;h=e8d2796b5a9b0a3546a4865e707ae70a0e3d1c56;hp=fc4c5b1d2046443dbc4ce74fd1cd76615c617a0b;hb=ddbaf678c49d33cf60f1eac5069e3275baa2c685;hpb=fc8145b709406b946c1d5527ff89ed419596fd17 diff --git a/libpcsxcore/psxcounters.c b/libpcsxcore/psxcounters.c index fc4c5b1d..e8d2796b 100644 --- a/libpcsxcore/psxcounters.c +++ b/libpcsxcore/psxcounters.c @@ -22,17 +22,11 @@ */ #include "psxcounters.h" +#include "gpu.h" #include "debug.h" /******************************************************************************/ -typedef struct Rcnt -{ - u16 mode, target; - u32 rate, irq, counterState, irqState; - u32 cycle, cycleStart; -} Rcnt; - enum { Rc0Gate = 0x0001, // 0 not implemented @@ -68,16 +62,21 @@ static const u32 CountToTarget = 1; static const u32 FrameRate[] = { 60, 50 }; static const u32 VBlankStart[] = { 240, 256 }; static const u32 HSyncTotal[] = { 263, 313 }; -static const u32 SpuUpdInterval[] = { 23, 22 }; +static const u32 SpuUpdInterval[] = { 32, 32 }; -static const s32 VerboseLevel = 0; +#define VERBOSE_LEVEL 0 +static const s32 VerboseLevel = VERBOSE_LEVEL; /******************************************************************************/ -static Rcnt rcnts[ CounterQuantity ]; +Rcnt rcnts[ CounterQuantity ]; static u32 hSyncCount = 0; static u32 spuSyncCount = 0; +static u32 hsync_steps = 0; +static u32 gpu_wants_hcnt = 0; +static u32 base_cycle = 0; +static u32 frame_counter = 0; u32 psxNextCounter = 0, psxNextsCounter = 0; @@ -90,8 +89,9 @@ void setIrq( u32 irq ) } static -void verboseLog( s32 level, const char *str, ... ) +void verboseLog( u32 level, const char *str, ... ) { +#if VERBOSE_LEVEL > 0 if( level <= VerboseLevel ) { va_list va; @@ -104,6 +104,7 @@ void verboseLog( s32 level, const char *str, ... ) printf( "%s", buf ); fflush( stdout ); } +#endif } /******************************************************************************/ @@ -140,7 +141,8 @@ u32 _psxRcntRcount( u32 index ) count = psxRegs.cycle; count -= rcnts[index].cycleStart; - count /= rcnts[index].rate; + if (rcnts[index].rate > 1) + count /= rcnts[index].rate; if( count > 0xffff ) { @@ -177,6 +179,9 @@ void psxRcntSet() psxNextCounter = countToUpdate; } } + + psxRegs.interrupt |= (1 << PSXINT_RCNT); + new_dyna_set_event(PSXINT_RCNT, psxNextCounter); } /******************************************************************************/ @@ -192,7 +197,8 @@ void psxRcntReset( u32 index ) { count = psxRegs.cycle; count -= rcnts[index].cycleStart; - count /= rcnts[index].rate; + if (rcnts[index].rate > 1) + count /= rcnts[index].rate; count -= rcnts[index].target; } else @@ -218,7 +224,8 @@ void psxRcntReset( u32 index ) { count = psxRegs.cycle; count -= rcnts[index].cycleStart; - count /= rcnts[index].rate; + if (rcnts[index].rate > 1) + count /= rcnts[index].rate; count -= 0xffff; _psxRcntWcount( index, count ); @@ -268,10 +275,11 @@ void psxRcntUpdate() // rcnt base. if( cycle - rcnts[3].cycleStart >= rcnts[3].cycle ) { - psxRcntReset( 3 ); + u32 leftover_cycles = cycle - rcnts[3].cycleStart - rcnts[3].cycle; + u32 next_vsync, next_lace; - spuSyncCount++; - hSyncCount++; + spuSyncCount += hsync_steps; + hSyncCount += hsync_steps; // Update spu. if( spuSyncCount >= SpuUpdInterval[Config.PsxType] ) @@ -287,8 +295,10 @@ void psxRcntUpdate() // VSync irq. if( hSyncCount == VBlankStart[Config.PsxType] ) { - GPU_vBlank( 1, &hSyncCount ); - + GPU_vBlank( 1, &hSyncCount, &gpu_wants_hcnt ); + //if( !(HW_GPU_STATUS & PSXGPU_ILACE) ) // hmh + HW_GPU_STATUS |= PSXGPU_LCF; + // For the best times. :D //setIrq( 0x01 ); } @@ -297,16 +307,45 @@ void psxRcntUpdate() if( hSyncCount >= (Config.VSyncWA ? HSyncTotal[Config.PsxType] / BIAS : HSyncTotal[Config.PsxType]) ) { hSyncCount = 0; + frame_counter++; - GPU_vBlank( 0, &hSyncCount ); + GPU_vBlank( 0, &hSyncCount, &gpu_wants_hcnt ); setIrq( 0x01 ); EmuUpdate(); GPU_updateLace(); + + HW_GPU_STATUS &= ~PSXGPU_LCF; + if( HW_GPU_STATUS & PSXGPU_ILACE ) + HW_GPU_STATUS |= frame_counter << 31; } + + // Schedule next call, in hsyncs + hsync_steps = SpuUpdInterval[Config.PsxType] - spuSyncCount; + next_vsync = VBlankStart[Config.PsxType] - hSyncCount; // ok to overflow + next_lace = HSyncTotal[Config.PsxType] - hSyncCount; + if( next_vsync && next_vsync < hsync_steps ) + hsync_steps = next_vsync; + if( next_lace && next_lace < hsync_steps ) + hsync_steps = next_lace; + if( gpu_wants_hcnt ) + hsync_steps = 1; + + rcnts[3].cycleStart = cycle - leftover_cycles; + if (Config.PsxType) + // 20.12 precision, clk / 50 / 313 ~= 2164.14 + base_cycle += hsync_steps * 8864320; + else + // clk / 60 / 263 ~= 2146.31 + base_cycle += hsync_steps * 8791293; + rcnts[3].cycle = base_cycle >> 12; + base_cycle &= 0xfff; + psxRcntSet(); } +#ifndef NDEBUG DebugVSync(); +#endif } /******************************************************************************/ @@ -315,8 +354,6 @@ void psxRcntWcount( u32 index, u32 value ) { verboseLog( 2, "[RCNT %i] wcount: %x\n", index, value ); - psxRcntUpdate(); - _psxRcntWcount( index, value ); psxRcntSet(); } @@ -325,8 +362,6 @@ void psxRcntWmode( u32 index, u32 value ) { verboseLog( 1, "[RCNT %i] wmode: %x\n", index, value ); - psxRcntUpdate(); - rcnts[index].mode = value; rcnts[index].irqState = 0; @@ -378,8 +413,6 @@ void psxRcntWtarget( u32 index, u32 value ) { verboseLog( 1, "[RCNT %i] wtarget: %x\n", index, value ); - psxRcntUpdate(); - rcnts[index].target = value; _psxRcntWcount( index, _psxRcntRcount( index ) ); @@ -392,8 +425,6 @@ u32 psxRcntRcount( u32 index ) { u32 count; - psxRcntUpdate(); - count = _psxRcntRcount( index ); // Parasite Eve 2 fix. @@ -417,8 +448,6 @@ u32 psxRcntRmode( u32 index ) { u16 mode; - psxRcntUpdate(); - mode = rcnts[index].mode; rcnts[index].mode &= 0xe7ff; @@ -464,6 +493,7 @@ void psxRcntInit() hSyncCount = 0; spuSyncCount = 0; + hsync_steps = 1; psxRcntSet(); } @@ -478,6 +508,11 @@ s32 psxRcntFreeze( gzFile f, s32 Mode ) gzfreeze( &psxNextCounter, sizeof(psxNextCounter) ); gzfreeze( &psxNextsCounter, sizeof(psxNextsCounter) ); + if (Mode == 0) + hsync_steps = (psxRegs.cycle - rcnts[3].cycleStart) / rcnts[3].target; + + base_cycle = 0; + return 0; }