contreaddata.c 3.7 KB

/**************************************************************************
 *                                                                        *
 *               Copyright (C) 1995, Silicon Graphics, Inc.               *
 *                                                                        *
 *  These coded instructions, statements, and computer programs  contain  *
 *  unpublished  proprietary  information of Silicon Graphics, Inc., and  *
 *  are protected by Federal copyright law.  They  may  not be disclosed  *
 *  to  third  parties  or copied or duplicated in any form, in whole or  *
 *  in part, without the prior written consent of Silicon Graphics, Inc.  *
 *                                                                        *
 **************************************************************************/

#include "osint.h"
#include "controller.h"
#include "siint.h"
#ifdef BBPLAYER
#include "bbint.h"	/*XXXblythe remove when hack no longer needed*/
#endif

static void	__osPackReadData(void);

/*
 * This call issues a read data command to controllers to get  input
 * data from controllers.
 * A value of 0 is returned if the calls succeed, otherwise
 * -1 is returned
 */
s32
osContStartReadData(OSMesgQueue *mq)
{
	s32	ret = 0;

	/* Block to get resource token */
	__osSiGetAccess();

	if (CONT_READ != __osContLastCmd) {

		/* Set up request command format for all channels */

		__osPackReadData();
		ret = __osSiRawStartDma(OS_WRITE, &__osContPifRam);
		(void)osRecvMesg(mq, (OSMesg *)NULL, OS_MESG_BLOCK);
	}

	/* trigger pifmacro */
	ret = __osSiRawStartDma(OS_READ, &__osContPifRam);


        /* 
         * Always make the last command an illegal one, so we never optimize
         * out the DMA write
         */
	__osContLastCmd = CONT_SETCH - 1;
	
	/* Return resource token */
	__osSiRelAccess();
	return(ret);
}


/*
 * Reformat the 64 bytes RAM data into OSContPad format 
 * and check error code.
 */
void
osContGetReadData(OSContPad *data)
{
	u8 			*ptr = (u8 *)(&__osContPifRam);
	__OSContReadFormat 	readformat;
	int 			i;

        for (i = 0; i < __osMaxControllers; i++, 
		ptr += sizeof(readformat), data++) {

                /* read read format for all the channel */

                readformat = *((__OSContReadFormat *)ptr);
#ifndef _HW_VERSION_1
                data->errno = (u8)((readformat.rxsize & CON_ERR_MASK) >> 4);
#else
                data->errno = (u8)(((readformat.txsize & CON_ERR_MASK) >> 4)
                | ((readformat.rxsize & CON_ERR_MASK) >> 6));
#endif
                if (data->errno)
                        continue;
                data->button = readformat.button;
                data->stick_x = readformat.stick_x;
                data->stick_y = readformat.stick_y;
        }
#ifdef BBPLAYER
	if (__osBbIsBb && __osBbHackFlags) {
	    OSContPad tmp;

	    data -= __osMaxControllers;
	    tmp = data[0];
            data[0] = data[__osBbHackFlags];
            data[__osBbHackFlags] = tmp;
	}
#endif
}

static void
__osPackReadData(void)
{
	u8 			*ptr = (u8 *)(&__osContPifRam);
	__OSContReadFormat 	readformat;
	int 			i;

	/* clear pif ram */

	for (i = 0; i < PIFRAMSIZE-1 ; i++)
		__osContPifRam.ramarray[i] = 0;
#ifndef _HW_VERSION_1
	__osContPifRam.pifstatus = CONT_FORMAT;
#else
	__osContPifRam.pifstatus = 0;
#endif 

	/* Setup read format for each channel */

	readformat.dummy = 0xff;
	readformat.txsize = 1;
	readformat.rxsize = 4;
	readformat.cmd = CONT_READ;
	readformat.button = 0xffff;
	readformat.stick_x = (s8)0xff;
	readformat.stick_y = (s8)0xff;

	for(i=0; i < __osMaxControllers; i++) {
		/* setup read format for connected channel */

		*((__OSContReadFormat *)ptr) = readformat;
		ptr += sizeof(readformat);
	}
#ifndef _HW_VERSION_1
	*((u8 *)ptr) = FORMAT_END;
#endif
}