Example #1
0
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;
    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;
    }
    verboseLog( 5, "[RCNT %i] scount: %x\n", index, value );
}
Example #2
0
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();
}
Example #3
0
void psxRcntWcount( u32 index, u32 value )
{
    verboseLog( 2, "[RCNT %i] wcount: %x\n", index, value );

    psxRcntUpdate();

    _psxRcntWcount( index, value );
    psxRcntSet();
}
Example #4
0
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();
}
Example #5
0
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;
            }

            // TODO: wcount must work.
            if( value & Rc2Disable )
            {
                rcnts[index].rate = 0xffffffff;
            }
        break;
    }

    _psxRcntWcount( index, 0 );
    psxRcntSet();
}
Example #6
0
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;
}
Example #7
0
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;
}
Example #8
0
static inline
u32 _psxRcntRcount( u32 index )
{
    u32 count  = psxRegs.cycle;
    count -= rcnts[index].cycleStart;
    if (rcnts[index].rate > 1)
        count /= rcnts[index].rate;

#ifdef DEBUG
    if( count > 0x10000 )
        verboseLog( 1, "[RCNT %i] rcount > 0x10000: %x\n", index, count );
#endif
    count &= 0xffff;

    return count;
}
Example #9
0
static inline
u32 _psxRcntRcount( u32 index )
{
    u32 count;

    count  = psxRegs.cycle;
    count -= rcnts[index].cycleStart;
    count /= rcnts[index].rate;

    if( count > 0xffff )
    {
        verboseLog( 1, "[RCNT %i] rcount > 0xffff: %x\n", index, count );
        count &= 0xffff;
    }

    return count;
}
Example #10
0
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;
}
Example #11
0
u32 psxRcntRtarget( u32 index )
{
    verboseLog( 2, "[RCNT %i] rtarget: %x\n", index, rcnts[index].target );

    return rcnts[index].target;
}
Example #12
0
static
void psxRcntReset( u32 index )
{
    u32 rcycles;

    rcnts[index].mode |= RcUnknown10;

    if( rcnts[index].counterState == CountToTarget )
    {
        rcycles = psxRegs.cycle - rcnts[index].cycleStart;
        if( rcnts[index].mode & RcCountToTarget )
        {
            rcycles -= rcnts[index].target * rcnts[index].rate;
            rcnts[index].cycleStart = psxRegs.cycle - rcycles;
        }
        else
        {
            rcnts[index].cycle = 0x10000 * rcnts[index].rate;
            rcnts[index].counterState = CountToOverflow;
        }

        if( rcnts[index].mode & RcIrqOnTarget )
        {
            if( (rcnts[index].mode & RcIrqRegenerate) || (!rcnts[index].irqState) )
            {
                verboseLog( 3, "[RCNT %i] irq\n", index );
                setIrq( rcnts[index].irq );
                rcnts[index].irqState = 1;
            }
        }

        rcnts[index].mode |= RcCountEqTarget;

        if( rcycles < 0x10000 * rcnts[index].rate )
            return;
    }

    if( rcnts[index].counterState == CountToOverflow )
    {
        rcycles = psxRegs.cycle - rcnts[index].cycleStart;
        rcycles -= 0x10000 * rcnts[index].rate;

        rcnts[index].cycleStart = psxRegs.cycle - rcycles;

        if( rcycles < rcnts[index].target * rcnts[index].rate )
        {
            rcnts[index].cycle = rcnts[index].target * rcnts[index].rate;
            rcnts[index].counterState = CountToTarget;
        }

        if( rcnts[index].mode & RcIrqOnOverflow )
        {
            if( (rcnts[index].mode & RcIrqRegenerate) || (!rcnts[index].irqState) )
            {
                verboseLog( 3, "[RCNT %i] irq\n", index );
                setIrq( rcnts[index].irq );
                rcnts[index].irqState = 1;
            }
        }

        rcnts[index].mode |= RcOverflow;
    }
}