/************************************************************************
 * File: baevent.c                                                      *
 ************************************************************************/

#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include <string.h>

/* Sony lib includes */
#include <eekernel.h>
#include <eetypes.h>
#include <eeregs.h>
#include <libgraph.h>
#include <libdma.h>
#include <libdev.h>
#include "batypes.h"
#include "balibtyp.h"
#include "baevent.h"

#if (!defined(DOXYGEN))
static const char rcsid[] __RWUNUSED__ =
    "@@@@(#)$Id: baevent.c,v 1.15 2001/04/02 13:54:57 johns Exp $";
#endif /* (!defined(DOXYGEN)) */

/****************************************************************************
 _rwSkyInitConfigSystem

  The :: in assemblre fcan condise C++ compilers, 
  which get it their head that it might be a scope operator.
 */
void
_rwSkyInitConfigSystem(void)
{
#if (0)
    RWFUNCTION(RWSTRING("_rwSkyInitConfigSystem"));
#endif /* (0) */

    /* Of course I know what this does :-) */

    /* Reset every unit in sight */
    DPUT_VIF1_FBRST(0x00000001);
    DPUT_VIF0_FBRST(0x00000001);
    DPUT_GIF_CTRL(0x00000001);
    {
        register u_int reg = 0;
        asm("cfc2 %0, $vi28" :"=r"(reg):);
        reg |= 0x00000200;
        asm("ctc2 %0, $vi28"::"r"(reg));
    }
    {
        register u_int reg = 0;
        asm("cfc2 %0, $vi28" :"=r"(reg):);
        reg |= 0x00000002;
        asm("ctc2 %0, $vi28"::"r"(reg));
    }

    sceGsResetPath();
    sceDmaReset(1);

#if (0)
    RWRETURNVOID();
#endif /* (0) */

}

#if (defined(__MWERKS__))

/************************************************************************
 * Inline asm from badma.c converted for CodeWarrior                    *
 ************************************************************************/

#if (defined(RWVERBOSE))
#pragma message (__FILE__ "/" _SKY_EXPAND(__LINE__) ": __MWERKS__ == " _SKY_EXPAND(__MWERKS__))
#endif /* (defined(RWVERBOSE)) */


static int _RwSavedGP=0xdeadbeaf;

/* save restore gp */

void
EventInitSavedGp(void)
{
#if (0)
    RWFUNCTION(RWSTRING("EventInitSavedGp"));
#endif /* (0) */

    asm volatile (".set noat
		.set noreorder
		sw $gp, 0(%0)
		.set reorder
		.set at":: "r" (&_RwSavedGP) );

#if (0)
    RWRETURNVOID();
#endif /* (0) */
}

void
EventIntrGetGp(unsigned int *oldgp)
{
    unsigned int        tmp;

#if (0)
    RWFUNCTION(RWSTRING("EventIntrGetGp"));
    RWASSERT(NULL != oldgp);
#endif /* (0) */

    tmp = *oldgp;

    asm volatile ("or %0, $gp, $0
		.set noat
		.set noreorder	
		lw $gp, 0(%1)
		.set reorder
		.set at " : "=r" ( tmp ) : "r" ( &_RwSavedGP) );

    *oldgp = tmp;

#if (0)
    RWRETURNVOID();
#endif /* (0) */
}

#endif /* (defined(__MWERKS__)) */

