audiotest.c 7.09 KB
/*====================================================================
 * audiotest.c
 *
 * Audio performance monitoring tool
 *
 * Copyright 1995, Silicon Graphics, Inc.
 * All Rights Reserved.
 *
 * This is UNPUBLISHED PROPRIETARY SOURCE CODE of Silicon Graphics,
 * Inc.; the contents of this file may not be disclosed to third
 * parties, copied or duplicated in any form, in whole or in part,
 * without the prior written permission of Silicon Graphics, Inc.
 *
 * RESTRICTED RIGHTS LEGEND:
 * Use, duplication or disclosure by the Government is subject to
 * restrictions as set forth in subdivision (c)(1)(ii) of the Rights
 * in Technical Data and Computer Software clause at DFARS
 * 252.227-7013, and/or in similar or successor clauses in the FAR,
 * DOD or NASA FAR Supplement. Unpublished - rights reserved under the
 * Copyright Laws of the United States.
 *====================================================================*/

/*---------------------------------------------------------------------*
        Copyright (C) 1998 Nintendo. (Originated by SGI)
        
        $RCSfile: audiotest.c,v $
        $Revision: 1.1.1.1 $
        $Date: 2002/05/02 03:27:08 $
 *---------------------------------------------------------------------*/

#include <ultralog.h>
#include <ramrom.h>
#include <sched.h>
#include "audiotest.h"
#include "misc.h"
#include "seqpTest.h"

extern test_cntrl Test0;
extern test_cntrl Test1;
extern test_cntrl Test2;
extern test_cntrl Test3;
extern test_cntrl Test4;
extern test_cntrl Test5;
extern test_cntrl seqpTest;
extern test_cntrl OsAiTest;
extern test_cntrl synScriptTest;

test_cntrl  *tests[] = {
    &OsAiTest, /* hardware bug test */
    &Test0,
    &Test1,
    &Test2,		/* synth monkey */
    &Test3,		/* priority test */
    &Test4,		/* sndplayer monkey */
    &Test5,		/* engine rev test */
    &synScriptTest,	/* synth special case tests */
    &seqpTest, 		/* seqplayer special case tests and monkey */
    NULL
};


/**** Stack for boot code.  Space can be reused after 1st thread starts ****/
u64             bootStack[STACKSIZE/8];

/**** threads used by this file ****/
static OSThread     gameThread;
static OSThread     initThread;
static OSThread     rmonThread;

/**** Stacks for the threads ****/
static u64          gameThreadStack[STACKSIZE/8];
static u64          initThreadStack[STACKSIZE/8];
static u64          rmonStack[RMON_STACKSIZE/8];

/**** function prototypes for private functions in this file ****/
static void         gameproc(void *);
static void         initproc(char *);

/**** message queues and message buffers used by PI manager ****/
static OSMesg           PiMessages[DMA_QUEUE_SIZE];
static OSMesgQueue      PiMessageQ;

/**** message queues and message buffers used by romCopy ****/
OSMesgQueue         dmaMessageQ;
OSMesg              dmaMessageBuf[MAX_MESGS];

/**** message queues and message buffers used by grafix processes ****/
OSMesgQueue         gfxFrameMsgQ;
OSMesg              gfxFrameMsgBuf[MAX_MESGS];

/**** Some globals ****/
OSScClient          gfxClient;
GFXInfo             gInfo[2];
u32                 gTestDone;

/**** Scheduler globals ****/
OSSched             sc;
u64                 scheduleStack[OS_SC_STACKSIZE/8];


static void initGame(void);

OSPiHandle	*handler;

boot(void *arg)
{
    int i;
    u32 *argp;
    u32 argbuf[16];
    
    osInitialize();

    handler = osCartRomInit();

    argp = (u32 *)RAMROM_APP_WRITE_ADDR;
    for (i=0; i<sizeof(argbuf)/4; i++, argp++) 
        osEPiReadIo(handler, (u32)argp, &argbuf[i]);   /* Assume no DMA */
    
    parse_args((char *)argbuf);
    
    osCreateThread(&initThread, 1, (void(*)(void *))initproc, arg,
                  (void *)(initThreadStack+STACKSIZE/8), (OSPri)INIT_PRIORITY);

    osStartThread(&initThread);
}

static void
initproc(char *argv) 
{

    /**** Start PI Mgr for access to cartridge  ****/
    osCreatePiManager((OSPri) OS_PRIORITY_PIMGR, &PiMessageQ, PiMessages,
                      DMA_QUEUE_SIZE);

    /**** Start rmonThread so you can do printf's ****/
    osCreateThread(&rmonThread, 0, rmonMain, (void *)0,
                   (void *)(rmonStack+RMON_STACKSIZE/8),
                   (OSPri) OS_PRIORITY_RMON );
    osStartThread(&rmonThread);

    /**** Create the game thread and start it up ****/
    osCreateThread(&gameThread, 6, gameproc, argv,
                   gameThreadStack+STACKSIZE/8, (OSPri)GAME_PRIORITY);

    osStartThread(&gameThread);

    /**** Set the thread to be the idle thread ****/
    osSetThreadPri(0, IDLE_PRIORITY);
    for(;;);
}


/************************************************************
 *
 *    A continual loop, primarily used for servicing the starts
 *    of graphic tasks and controller reads. If InitTest starts
 *    an audio manager, tests can be serviced by voice handler,
 *    otherwise they are called by the test's retrace proc.
 *
 ************************************************************/	
static void
gameproc(void *argv)
{
    u8             displaybuffer = 0;
    u8             drawbuffer = 0;
    u8             pendingGFX = 0;
    u8             cntrlReadNeeded = TRUE;
    GFXMsg         *msg;
    GFXInfo        *gfxp;
    u32            testNum = 0,subTestNum;
    test_cntrl     *test;

    initGame();

    test = tests[testNum];

    while( test != NULL )
    {
	for( subTestNum = 0; subTestNum < test->numSubTests ; subTestNum++)
	{
	    (*(test->InitTest))(subTestNum);
	    gTestDone = FALSE;

	    while (gTestDone == FALSE)
	    {
		osRecvMesg(&gfxFrameMsgQ, (OSMesg *)&msg, OS_MESG_BLOCK);
		switch (msg->gen.type)
		{
		    case (OS_SC_RETRACE_MSG):
			if(test->retraceProc)
			    (*(test->retraceProc))(test->retraceData);

			if (pendingGFX < 2) /* don't do if already have 2 tasks */
			{
			    createGfxTask(&gInfo[drawbuffer]);
			    pendingGFX++;
			    drawbuffer ^= 1; /* switch drawbuffer */
			}
			
			if (cntrlReadNeeded)
			{
			    osContStartReadData(&gfxFrameMsgQ);
			    cntrlReadNeeded = FALSE;
			}
			break;
			
		    case (OS_SC_DONE_MSG):
			gfxp = &gInfo[displaybuffer];
			displaybuffer ^= 1;  /* switch the displaybuffer */
			pendingGFX--;        /* decrement number of pending tasks */
			break;
                
		    case SCHED_CONTROLLER_MSG:
			UpdateController(test);
			cntrlReadNeeded = TRUE; /* might want to reset this somewhere else */
			break;
			
		    default:
			break;
		}
	    }
	    (*(test->StopTest))(subTestNum);
	    PRINTF("Test %d, SubTest %d completed\n",testNum,subTestNum); 
	}

	PRINTF("Test %d completed\n",testNum);
	testNum++;
	test = tests[testNum];
    }
}


void initGame(void)
{
    /**** set up a couple message q's ****/
    osCreateMesgQueue(&dmaMessageQ, dmaMessageBuf, MAX_MESGS);
    osCreateMesgQueue(&gfxFrameMsgQ, gfxFrameMsgBuf, MAX_MESGS);

    /**** Initialize the RCP task scheduler ****/
    osCreateScheduler(&sc, (void *)(scheduleStack + OS_SC_STACKSIZE/8),
                      SCHEDULER_PRIORITY, OS_VI_NTSC_LAN1, NUM_FIELDS);

    /**** Add ourselves to the scheduler to receive retrace messages ****/
    osScAddClient(&sc, &gfxClient, &gfxFrameMsgQ);    

    /**** Call the initialization routines ****/

    initGFX(); 
    initCntrl(); 
}


void TestDone(void)
{
    gTestDone = TRUE;
}