loadrom.c 3.94 KB
/*
 * 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.
 *
 * $Revision: 1.1.1.1 $
 */

#include <sys/file.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <signal.h>
#include <bstring.h>
#include <string.h>
#include <getopt.h>

#include <sys/u64gio.h>
#include <libaudio.h>
#include "midiApp.h"
#include "midiDmon.h"
#include "midiGlobals.h"


int writeNverify(int u64fd, unsigned int ramromOffset, int bufSize, unsigned char *buf);

extern int    gRomImageSize;
extern char   gRomImage[];



void loadrom(void)
{
    int             retval;
    unsigned int    romOffset = 0; 	/* rom will internally offset game to 0x800 */
    int             errorsFound = 0;
    int             u64fd;

    if ((u64fd = open(DEV_U64, O_RDWR | O_NOCTTY)) < 0)
    {
        fprintf(stderr, "%s: unable to open %s",gAppName, DEV_U64);
        exit(1);
    } 

    /* Assert RESET  */
    if ( (retval = ioctl(u64fd, U64_RESET, 1) ) < 0 )
    {
        fprintf(stderr, "%s: Error starting U64_RESET ioctl",gAppName);
        exit(1);
    } 

    /* Write the contents of the ROM file into ramrom first.   */
    if (writeNverify(u64fd, romOffset, gRomImageSize, gRomImage) > 0)
    {
        fprintf(stderr, "%s: write & readback of rom image failed.\n",gAppName);
        exit(1);
    }

    /* Release RESET; game will subsequently boot itself. */
    if ( (retval = ioctl(u64fd, U64_RESET, 0) ) < 0 )
    {
        fprintf(stderr, "%s: Error after U64_RESET ioctl",gAppName);
        exit(1);
    } 

    close(u64fd);
}

/*
 * Returns number of errors encountered.
 * Can be greatly shortened by not verifying
 */
int writeNverify(int u64fd, unsigned int ramromOffset, int bufSize, unsigned char *buf)
{
    unsigned char *readBuf, *pSrc, *pDst;
    u64_write_arg_t arg;
    int retval, i, error;

    if ((ramromOffset + bufSize) > RAMROM_SIZE)
    {
        fprintf(stderr, "%s: Ramrom image too big! %d bytes\n",gAppName, bufSize);
        return(1);
    }

    /* Tell the kernel to copyin our data into ramrom.   */
    arg.buffer = (void *)buf;
    arg.ramrom_addr = ramromOffset;
    arg.nbytes = bufSize;
    arg.value = -1; /* Inhibits acknowledge cycle with game */

    if ( (retval = ioctl(u64fd, U64_WRITE, &arg) ) < 0 )
    {
        fprintf(stderr, "%s: Error after U64_WRITE ioctl, return value %d",gAppName,retval);
        return(1);
    } 

    /* Read back & verify, to ensure our load worked. Not needed, just protective  */
    readBuf = malloc(bufSize);
    if (readBuf == NULL)
    {
        fprintf(stderr, "%s: unable to malloc buffer to hold %d bytes\n",gAppName,bufSize);
        return(1);
    }
    
    /* Tell the kernel to copyout ramrom data into our buffer.   */
    arg.buffer = (void *)readBuf;
    arg.ramrom_addr = ramromOffset;
    arg.nbytes = bufSize;
    arg.value = -1; /* Inhibits acknowledge cycle with game */

    if ( (retval = ioctl(u64fd, U64_READ, &arg) ) < 0 )
    {
        fprintf(stderr, "%s: Error after U64_READ ioctl, return value %d",gAppName,retval);
        return(1);
    } 

    /* check that what you read is what you wrote */
    for (i = 0, error = 0, pSrc = buf, pDst = readBuf; i < bufSize; i++)
    {
        if (*pSrc != *pDst)
            error++;

        pSrc++;
        pDst++;
    }
	return(error);
}