makeipl.c 5.39 KB
/********************************************************************************
					 NINTENDO64 Disk Drive IPL4 ROM Maker


						Programmed by Yasunari Nishida

			 Copyright 1997 Nintendo co., ltd. all rights reserved


								July 17, 1997
 ********************************************************************************/

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


#define	FALSE					0
#define	TRUE					1

#define	IPLROMID_JPNCODE		0xC3
#define	IPLROMID_USACODE		0x04
#define	IPLROMID_ADDRESS		0x09FF00

#define	   PROGRAM_NAME			"rom"
#define	 KANJIFONT_NAME			"FONT/kanjifont.bin"
#define	 ASCIIFONT_NAME			"FONT/asciifont.bin"
#define	KANJITABLE_NAME			"FONT/kanjitable.bin"
#define	ASCIITABLE_NAME			"FONT/asciitable.bin"
#define	 SOUNDDATA_NAME			"AUDIO/sounddata.bin"

#define	IPL4_ROM_SIZE			0x400000

#define	   PROGRAM_ADDRESS		0x000000
#define	 KANJIFONT_ADDRESS		0x0A0000
#define  ASCIIFONT_ADDRESS		0x11EE80
#define	KANJITABLE_ADDRESS		0x138800
#define	ASCIITABLE_ADDRESS		0x139248
#define	 SOUNDDATA_ADDRESS		0x140000

#define	   PROGRAM_MAXSIZE		0x0A0000
#define	 KANJIFONT_MAXSIZE		0x07EE80
#define	 ASCIIFONT_MAXSIZE		0x01988A
#define	KANJITABLE_MAXSIZE		0x000A48
#define	ASCIITABLE_MAXSIZE		0x006C60
#define	 SOUNDDATA_MAXSIZE		0x2C0000


static char romImage[IPL4_ROM_SIZE+1];		/* IPL4 ROM image buffer	*/
											/* +1 for overflow check	*/

static int iplromID = IPLROMID_JPNCODE;
static int verbose  = FALSE;

/************************************************************************/
/*																		*/
/*	Read binary data into the ROM image buffer.							*/
/*																		*/
/************************************************************************/
static void
ClearRomImage(void)
{
	long index = 0;


	srandom(755416136);
	while (index < PROGRAM_MAXSIZE) {
		romImage[index++] = (random() >> 8) & 0xff;
	}
	while (index < IPL4_ROM_SIZE) {
		romImage[index++] = 0xff;
	}
	romImage[IPLROMID_ADDRESS] = iplromID;
}
/************************************************************************/
/*																		*/
/*	Read binary data into the ROM image buffer.							*/
/*																		*/
/************************************************************************/
static long
ReadBinaryData(char *filename, long address, long maxsize)
{
	FILE *fp;
	long count;


	if ((fp = fopen(filename, "r")) == NULL) {
		perror(filename);
		return(0);
	}
	count = fread(&romImage[address], sizeof(char), maxsize+1, fp);
	fclose(fp);

	if (count > maxsize) {
		fprintf(stderr, "%s: data is overflow.\n", filename);
		return(0);
	}
	if (verbose) {
		fprintf(stderr, "%20s: %08XH - %08XH  (%08XH)\n", filename, address, address+count-1, count);
	}
	return(count);
}
/************************************************************************/
/*																		*/
/*	Write IPL4 ROM image.												*/
/*																		*/
/************************************************************************/
static long
WriteRomImage(char *filename)
{
	FILE *fp;
	long count = 0;

	if ((fp = fopen(filename, "w")) != NULL) {
		count = fwrite(romImage, sizeof(char), IPL4_ROM_SIZE, fp);
		fclose(fp);
	}
	return(count);
}
/************************************************************************/
/*																		*/
/*		Check command options.											*/
/*																		*/
/************************************************************************/
static int
CheckOption(int argc, char **argv)
{
	int showhelp = FALSE;


	while (--argc > 0) {
		if (**++argv == '-') {
			switch ((*argv)[1]) {
				default : showhelp = TRUE;					break;
				case 'h': showhelp = TRUE;					break;
				case 'v': verbose  = TRUE;					break;
				case 'a': iplromID = IPLROMID_USACODE;		break;
				case 'j': iplromID = IPLROMID_JPNCODE;		break;
			}
		}
	}
	return(showhelp);
}
/************************************************************************/
/*																		*/
/*		Check command options.											*/
/*																		*/
/************************************************************************/
static void
ShowHelp(void)
{
	fprintf(stderr, "Usage: makeipl [-a][-j][-h][-v]\n");
	fprintf(stderr, "   -a: for USA.\n");
	fprintf(stderr, "   -j: for Japan. (default)\n");
	fprintf(stderr, "   -h: show this help.\n");
	fprintf(stderr, "   -v: verbose mode.\n");
}
/************************************************************************/
/*																		*/
/*	Main																*/
/*																		*/
/************************************************************************/
extern int
main(int argc, char **argv)
{
	fprintf(stderr, "NINTENDO64 Disk Drive IPL4 ROM Maker  [July 17, 1997]\n");
	if (CheckOption(argc, argv)) {
		ShowHelp();
		exit(1);
	}
	ClearRomImage();
	if (ReadBinaryData(   PROGRAM_NAME,    PROGRAM_ADDRESS,    PROGRAM_MAXSIZE) == 0)  exit(1);
	if (ReadBinaryData( KANJIFONT_NAME,  KANJIFONT_ADDRESS,  KANJIFONT_MAXSIZE) == 0)  exit(1);
	if (ReadBinaryData( ASCIIFONT_NAME,  ASCIIFONT_ADDRESS,  ASCIIFONT_MAXSIZE) == 0)  exit(1);
	if (ReadBinaryData(KANJITABLE_NAME, KANJITABLE_ADDRESS, KANJITABLE_MAXSIZE) == 0)  exit(1);
	if (ReadBinaryData(ASCIITABLE_NAME, ASCIITABLE_ADDRESS, ASCIITABLE_MAXSIZE) == 0)  exit(1);
	if (ReadBinaryData( SOUNDDATA_NAME,  SOUNDDATA_ADDRESS,  SOUNDDATA_MAXSIZE) == 0)  exit(1);

	if (WriteRomImage("ipl4") != IPL4_ROM_SIZE) {
		fprintf(stderr, "IPL4 ROM image cannot create.\n");
		exit(1);
	}
	if (verbose) {
		fprintf(stderr, "\nfile \"ipl4\" is created.\n");
		fprintf(stderr, "completed.\n");
	}
	return(0);
}