static void psxRcntReset( u32 index ) { u32 count; if( rcnts[index].counterState == CountToTarget ) { if( rcnts[index].mode & RcCountToTarget ) { count = psxRegs.cycle; 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) ) { verboseLog( 3, "[RCNT %i] irq: %x\n", index, count ); setIrq( rcnts[index].irq ); rcnts[index].irqState = 1; } } rcnts[index].mode |= RcCountEqTarget; } else if( rcnts[index].counterState == CountToOverflow ) { count = psxRegs.cycle; 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) ) { verboseLog( 3, "[RCNT %i] irq: %x\n", index, count ); setIrq( rcnts[index].irq ); rcnts[index].irqState = 1; } } rcnts[index].mode |= RcOverflow; } rcnts[index].mode |= RcUnknown10; psxRcntSet(); }
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(); }
u32 psxRcntRcount( u32 index ) { #ifdef DEBUG_ANALYSIS dbg_anacnt_psxRcntRcount++; #endif pcsx4all_prof_start_with_pause(PCSX4ALL_PROF_COUNTERS,PCSX4ALL_PROF_CPU); u32 count; #ifndef USE_NO_IDLE_LOOP if (autobias) { u32 cycle_next=rcnts[index].cycle+rcnts[index].cycleStart; if (cycle_next>psxRegs.cycle) { if (psxRegs.io_cycle_counter>(psxRegs.cycle+32) && psxRegs.io_cycle_counter<cycle_next) { cycle_next = psxRegs.io_cycle_counter - psxRegs.cycle - 24; } else { cycle_next = 12+((cycle_next - psxRegs.cycle)&0x1FF); } if (rcnts[index].target) { unsigned value=(((rcnts[index].target)*(rcnts[index].rate+1))/4)*BIAS; if (value<cycle_next) psxRegs.cycle+=value; else psxRegs.cycle+=cycle_next; } else { psxRegs.cycle+=cycle_next; } } } #endif psxRcntUpdate(); count = _psxRcntRcount( index ); // Parasite Eve 2 fix. if( Config.RCntFix ) { if( index == 2 ) { if( rcnts[index].counterState == CountToTarget ) { count=UDIV(count,BIAS); } } } #ifdef DEBUG_BIOS dbgf("[RCNT %i] rcount: %x\n", index, count ); #endif pcsx4all_prof_end_with_resume(PCSX4ALL_PROF_COUNTERS,PCSX4ALL_PROF_CPU); return count; }
void psxRcntWtarget( u32 index, u32 value ) { #ifdef DEBUG_BIOS dbgf("[RCNT %i] wtarget: %x\n", index, value ); #endif psxRcntUpdate(); rcnts[index].target = value; _psxRcntWcount( index, _psxRcntRcount( index ) ); psxRcntSet(); }
u32 psxRcntRcount( u32 index ) { u32 count; psxRcntUpdate(); count = _psxRcntRcount( index ); // Parasite Eve 2 fix - artificial clock jitter based on BIAS // TODO: any other games depend on getting excepted value from RCNT? if( Config.HackFix && index == 2 && rcnts[index].counterState == CountToTarget && (Config.RCntFix || ((rcnts[index].mode & 0x2FF) == JITTER_FLAGS)) ) { /* *The problem is that... * *We generate too many cycles during PSX HW hardware operations. * *OR * *We simply count too many cycles here for RCNTs. * *OR * *RCNT implementation here is only 99% compatible. Assumed this since easities to fix (only PE2 known to be affected). */ static u32 clast = 0xffff; static u32 cylast = 0; u32 count1 = count; count /= BIAS; verboseLog( 4, "[RCNT %i] rcountpe2: %x %x %x (%u)\n", index, count, count1, clast, (psxRegs.cycle-cylast)); cylast=psxRegs.cycle; clast=count; } verboseLog( 2, "[RCNT %i] rcount: %x\n", index, count ); return count; }
u32 psxRcntRcount( u32 index ) { u32 count; psxRcntUpdate(); count = _psxRcntRcount( index ); // Parasite Eve 2 fix. if( Config.RCntFix ) { if( index == 2 ) { if( rcnts[index].counterState == CountToTarget ) { count /= BIAS; } } } verboseLog( 2, "[RCNT %i] rcount: %x\n", index, count ); return count; }
static void psxRcntReset( u32 index ) { u32 count; if( rcnts[index].counterState == CountToTarget ) { if( rcnts[index].mode & RcCountToTarget ) { count = psxRegs.cycle; count -= rcnts[index].cycleStart; if (rcnts[index].rate > 1) count = UDIV(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) ) { #ifdef DEBUG_BIOS dbgf("[RCNT %i] irq: %x\n", index, count ); #endif setIrq( rcnts[index].irq ); rcnts[index].irqState = 1; } } rcnts[index].mode |= RcCountEqTarget; } else if( rcnts[index].counterState == CountToOverflow ) { count = psxRegs.cycle; count -= rcnts[index].cycleStart; if (rcnts[index].rate > 1) count = UDIV(count,rcnts[index].rate); count -= 0xffff; _psxRcntWcount( index, count ); if( rcnts[index].mode & RcIrqOnOverflow ) { if( (rcnts[index].mode & RcIrqRegenerate) || (!rcnts[index].irqState) ) { #ifdef DEBUG_BIOS dbgf("[RCNT %i] irq: %x\n", index, count ); #endif setIrq( rcnts[index].irq ); rcnts[index].irqState = 1; } } rcnts[index].mode |= RcOverflow; } rcnts[index].mode |= RcUnknown10; psxRcntSet(); }