//////////////////////////////////////////////////////////////////////////////
//
// Asura_PS2_Timers.h
//
// Copyright (c) 2002-2004 Rebellion. All rights reserved.
//
//////////////////////////////////////////////////////////////////////////////

// B E G I N   F I L E   W R A P P E R ///////////////////////////////////////

#ifdef ASURA_USE_PRAGMA_ONCE
    #pragma once
#endif

#ifndef ___ASURA_PS2_TIMERS_H___
#define ___ASURA_PS2_TIMERS_H___ 1

// C O N S T A N T S /////////////////////////////////////////////////////////

// This value was obtained from the newsgroups.
static const float ASURA_PS2_EE_CYCLES_PER_SEC = 294912000.0f;

// The timer register is a 32 bit unsigned value.
static const u_int ASURA_PS2_MAX_CYCLE_COUNT = 0xFFFFFFFFu;

// C L A S S E S /////////////////////////////////////////////////////////////

class Asura_PS2_Timers
{

    public:

        // C L A S S   M E T H O D S /////////////////////////////////////////

        static inline u_int GetCycleCount( void )
        {
            u_int uCount;
	        asm __volatile__( "mfc0 %0, $9" : "=r" (uCount) );
	        return uCount;
        }

        // This accounts for up to one timer wrap (~14.6 seconds.)
        static inline u_int GetElapsedCycles( u_int uStartCycles, u_int uEndCycles = GetCycleCount() )
        {
            return( uEndCycles >= uStartCycles ? uEndCycles - uStartCycles : uEndCycles + (ASURA_PS2_MAX_CYCLE_COUNT - uStartCycles) );
        }

        static float ConvertCyclesToSeconds( u_int uCycles );

};
// End class Asura_PS2_Timers.

// E N D   F I L E   W R A P P E R ///////////////////////////////////////////

#endif // #ifndef ___ASURA_PS2_TIMERS_H___
