music.c 6.85 KB
/*====================================================================
 * music.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: music.c,v $
        $Revision: 1.1.1.1 $
        $Date: 2002/05/02 03:27:18 $
 *---------------------------------------------------------------------*/

#include <ultralog.h>
#include <ramrom.h>
#include <sched.h>
#include "misc.h"
#include "music.h"
#include "sequence.h"
#include "audio.h"
#include "cursor.h"
#include "musicUI.h"
#include "transport.h"
#include "UniversalSP.h"


/**** 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     mainThread;
static OSThread     rmonThread;

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

/**** function prototypes for private functions in this file ****/
static void             gameproc(void *);
static void             mainproc(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 ****/
u32                 controller;
u32                 controllervalid;
GFXInfo             gInfo[2];

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

/**** audio globals ****/
extern ALUSPlayer   *seqp;


/**** logging stuff ****/
OSLog       logger;
OSLog       *log = &logger;
u32         logData[LOG_LEN];

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(&mainThread, 1, (void(*)(void *))mainproc, arg,
                  (void *)(mainThreadStack+STACKSIZE/8), (OSPri)MAIN_PRIORITY);

    osStartThread(&mainThread);
}

static void
mainproc(char *argv) 
{
    osCreateThread(&gameThread, 6, gameproc, argv,
                   gameThreadStack+STACKSIZE/8, (OSPri)GAME_PRIORITY);

    /**** 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);

    if (!debugger)
        osStartThread(&gameThread);

    osSetThreadPri(0, 0);
    for(;;);
}

static void
gameproc(void *argv)
{
    int             displaybuffer = 0;
    int             drawbuffer = 0;
    int             pendingGFX = 0;
    int             framecount = 0;    
    GFXMsg          *msg;
    OSScClient      client;
    GFXInfo         *gfxp;
    GFXMsg          controllermsg;

    if (logging)
        osCreateLog(log, logData, LOG_LEN);


    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);

    osScAddClient(&sc, &client, &gfxFrameMsgQ);    

    initGFX();


    if ((controller = initControllers()) < 0)
        controllervalid = 0;
    else
        controllervalid = 1;

    controllermsg.gen.type = SCHED_CONTROLLER_MSG;
    
    /* MUST call initControllers before this point */
    osSetEventMesg(OS_EVENT_SI, &gfxFrameMsgQ, (OSMesg)&controllermsg);

    AudioInit();
    UIInit ();
    Crsr_Init ();

    while (1)
    {
        (void) osRecvMesg(&gfxFrameMsgQ, (OSMesg *)&msg, OS_MESG_BLOCK);

        switch (msg->gen.type)
        {
            case (OS_SC_RETRACE_MSG):
                /*
                 *  if not overrunning, create a new gfx task.
                 *  Start the controller read. Check audio.
                 */
                if (logging)
                    osLogEvent(log, LOG_RETRACE, 1, pendingGFX);
                    
                if (pendingGFX < 2) /* don't do if already have 2 tasks */
                {
                    createGfxTask(&gInfo[drawbuffer]); 
                    pendingGFX++;
                    drawbuffer ^= 1; /* switch drawbuffer */
                }
                
                if (controllervalid)
                {
                    osContStartReadData(&gfxFrameMsgQ);
                    controllervalid = 0;
                }

                if(alUSPGetState(seqp) == AL_STOPPED)
                {
                    Seq_CheckStatus();
                }
                break;

            case (OS_SC_DONE_MSG):
                gfxp = &gInfo[displaybuffer];       
                
                if (logging)
                    osLogEvent(log, LOG_RDP_DONE, 2, gfxp->cfb, framecount);
                framecount++;        /* increment frame counter */
                displaybuffer ^= 1;  /* switch the displaybuffer */
                pendingGFX--;        /* decrement number of pending tasks */
                break;
                
            case SCHED_CONTROLLER_MSG:
                UpdateController();
                break;

            default:
                PRINTF("gameproc loop unknown intr 0x%x\n", msg->gen.type);
                break;
        }
    }
}