gbi2mem.c 3.38 KB

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

char *OutputFileBase = NULL;
char *InputFile = NULL;

void usage(void)
{
    fprintf(stderr, "usage:  gbi2mem -i input.out -o output \n");
    fprintf(stderr, "\tcreates output.{mem,tsk} \n");
    fprintf(stderr, "\tinput.out can be created with: gload | tee input.out\n");
    fprintf(stderr, "\t(hit ^c when ===... appears;\n");
    fprintf(stderr, "\t use guDumpGbiDL or guDumpTurbo in program)\n");
    exit(0);
}

void parse_args(int argc, char *argv[])
{
    int c;
    extern char *optarg;
    extern int optind;
    char *ofile = NULL;
    
    while ((c = getopt(argc, argv, "i:o:")) != EOF) {
	switch (c)
	    {
	    case 'i':
		InputFile = strdup(optarg);
		break;
	    case 'o':
		OutputFileBase = strdup(optarg);
		break;
	    default:
		usage();
		break;		
	    }    
    }

    
if (OutputFileBase == NULL) printf("NO OUT FILE\n");
else printf("OUTFILE=%s\n",OutputFileBase);
if (InputFile == NULL) printf("NO IN FILE\n");
else printf("INFILE=%s\n",InputFile);
    if (OutputFileBase == NULL)
	usage();	   
}

#define MAXLINE 20
void getline(char *buf, FILE *fp)
{
	int i=0,c;
	while ((c=getc(fp)) != '\n')  {
		if (i<MAXLINE-1) buf[i++]=c;
	}
	buf[i]='\0';
}

main(int argc, char *argv[])
{
	char	buf[MAXLINE];
	FILE	*fp;
	char	file1[100],file2[100];
	char	dram[0x400000];
	int	done=0,addr,taskaddr,num,tasklen=0,*dp;


	parse_args(argc, argv);

	if (InputFile) {
	    if(!(fp=fopen(InputFile,"r"))) {
		fprintf(stderr,"error opening %s\n",file2);
		exit(0);
	    }
	} else {
	    fp=stdin;
	}

	file1[0]='\0';
	strcat(file1,OutputFileBase);
	strcat(file1,".tsk");
	file2[0]='\0';
	strcat(file2,OutputFileBase);
	strcat(file2,".mem");

	while(1) {
		getline(buf,fp);
		if (!strcmp(&buf[0],"GBI_DUMP_START:"))
			break;
	}

	while(!done) {
		getline(buf,fp);
		switch (buf[0]) {
		    case '$' :	/* task header address */
			sscanf(&buf[2],"%x",&taskaddr);
			tasklen=0;
			if (1) fprintf(stderr,"dumping task header\n");
			else
		    case '@' :  /* display list address */
			if (1) fprintf(stderr,"dumping display list\n");
			else
		    case '&' :  /* dma data address */
			if (1) fprintf(stderr,"dumping dma\n");
			else
		    case '?' :  /* code/code data address */
			if (1) fprintf(stderr,"dumping code/code data\n");
			else
		    case '%' :  /* texture address */
			if (1) fprintf(stderr,"dumping texture\n");
			sscanf(&buf[2],"%x",&addr);
			break;

		    case '<' :		/* task header data */
			tasklen += 4;
		    case '>' :		/* 1st half of display list command */
		    case '-' :		/* 2nd half of display list command */
		    case '+' :		/* dma data */
		    case '*' :		/* texture data */
		    case '|' :		/* code/code data */
			sscanf(&buf[1],"%x",&num);
			dp=(int *)&dram[addr];
			*dp=num;
			addr += 4;
			break;

		    case '^' :
			done=1;
			break;
		}
	}
	if (InputFile) {
		fclose(fp);
	}

/*
 * save .tsk file
 */
	if(!(fp=fopen(file2,"w"))) {
		fprintf(stderr,"error opening %s\n",file2);
		exit(0);
	}
	fprintf(stderr,"\nwriting file %s\n", file2);
	fwrite((void *)&dram[0],sizeof(char),0x400000,fp);
	fclose(fp);

/*
 * save .tsk file
 */
	for (addr=taskaddr; addr<taskaddr+tasklen; addr += 4)
		dram[addr] &= 0x7f;

	if(!(fp=fopen(file1,"w"))) {
		fprintf(stderr,"error opening %s\n",file1);
		exit(0);
	}
	fprintf(stderr,"\nwriting file %s\n", file1);
	fwrite((void *)&dram[taskaddr],sizeof(char),tasklen,fp);
	fclose(fp);

	fprintf(stderr,"done!\n");
}