home *** CD-ROM | disk | FTP | other *** search
- /****************************************/
- /* */
- /* N64 Rom Manager */
- /* */
- /* By Salim Gasmi */
- /* */
- /* salim@gasmi.net */
- /* */
- /****************************************/
-
- #include <stdio.h>
- #include <fcntl.h>
- #include <unistd.h>
- #include <stdlib.h>
- #include <string.h>
-
-
- #define VER "V1.0"
- #define MEGA (1024*1024)
- #define B1 0x80
- #define B2 0x37
-
- #define max2(a, b) ( (a)>(b) ? (a) : (b) )
- #define min2(a, b) ( (a)<(b) ? (a) : (b) )
-
- #define BUFSIZE 32768
- #define SMALBUF 16384
-
- #define CHECKSUM_START 0x1000
- #define CHECKSUM_LENGTH 0x100000L
- #define CHECKSUM_HEADERPOS 0x10
- #define CHECKSUM_END (CHECKSUM_START + CHECKSUM_LENGTH)
-
- #define CHECKSUM_STARTVALUE 0xf8ca4ddc
-
- #define ROL(i, b) (((i)<<(b)) | ((i)>>(32-(b))))
-
- #define BYTES2LONG(b, s) ( (((b)[0^(s)] & 0xffL) << 24) | \
- (((b)[1^(s)] & 0xffL) << 16) | \
- (((b)[2^(s)] & 0xffL) << 8) | \
- (((b)[3^(s)] & 0xffL)) )
-
- #define LONG2BYTES(l, b, s) (b)[0^(s)] = ((l)>>24)&0xff; \
- (b)[1^(s)] = ((l)>>16)&0xff; \
- (b)[2^(s)] = ((l)>> 8)&0xff; \
- (b)[3^(s)] = ((l) )&0xff;
-
-
- int IsRom(unsigned char *);
- void Swap(unsigned char *,int);
- int ChkSum(FILE *,int,long,int);
-
- int main(int argc,char **argv)
- {
- int f,i;
- long l;
- unsigned char v=0;
- unsigned char name[64];
- unsigned char mode[50];
- int ty;
- unsigned char *buf;
- FILE *file;
- unsigned char sbuf[SMALBUF];
- int perc,curr;
-
- if(argc!=3)
- {
- printf("\nUsage : %s -{hvsSc} rom_file\n\n",argv[0]);
- printf("-h : display info about the ROM\n");
- printf("-v : Verify checksum of the ROM\n");
- printf("-s : Swap little<->Big Endian format (fast but need mem)\n");
- printf("-S : Swap little<->Big Endian format (slow but need no mem)\n");
- printf("-c : Regenerate the checksum of the ROM\n\n");
- printf("---- n64rom %s by Salim Gasmi ---- \n\n",VER);
- return(0);
- }
-
- if(strcmp(argv[1],"-h")==0) v=1;
- if(strcmp(argv[1],"-v")==0) v=2;
- if(strcmp(argv[1],"-s")==0) v=3;
- if(strcmp(argv[1],"-c")==0) v=4;
- if(strcmp(argv[1],"-S")==0) v=5;
-
- if(v==0)
- {
- printf("Unknown switch option %s\n",argv[1]);
- return(0);
- }
-
- f=open(argv[2],O_RDWR);
- if(f<0)
- {
- printf("file %s not found or write protected\n",argv[2]);
- return(0);
- }
-
- read(f,name,2);
- lseek(f,0,0);
- l=lseek(f,0,2);
- lseek(f,0,0);
- lseek(f,32,0);
-
- ty=IsRom(name);
-
- if(ty==-1)
- {
- printf("%s is not a N64 ROM\n",argv[2]);
- close(f);
- return(0);
- }
-
- read(f,name,63);
-
- if(ty==1)
- {
- Swap(name,63);
- strcpy(mode,"Little Endian (V64)");
- }
- else strcpy(mode,"Big Endian (Z64)");
-
- if(v==1)
- {
- printf("%s : %s %ld MB %s format\n",argv[2],name,l*8/MEGA,mode);
- close(f);
- return(0);
- }
-
-
- if(v==3)
- {
- lseek(f,0,0);
-
- /* we load the ROM in RAM */
-
- buf=(unsigned char *)malloc(l);
- if(buf==NULL)
- {
- close(f);
- printf("malloc failed\n");
- return(0);
- }
-
-
- printf("reading && Swaping file %s (%ld bytes) (fast mode).... \n",argv[2],l);
-
- read(f,buf,l);
- lseek(f,0,0);
- Swap(buf,l);
- write(f,buf,l);
- free(buf);
- }
-
- if(v==5)
- {
- ty=1;
-
- printf("reading && Swaping file %s (%ld bytes) (slow mode).... \n",argv[2],l);
-
-
- printf("%% done :");
- fflush(stdout);
- perc=l/10;
- curr=0;
-
- i=0;
- while(i!=l)
- {
- lseek(f,i,0);
- read(f,sbuf,SMALBUF);
- Swap(sbuf,SMALBUF);
- lseek(f,i,0);
- write(f,sbuf,SMALBUF);
-
- if(i/perc>curr)
- {
- curr=i/perc;
- printf("%d%% ",curr*10);
- fflush(stdout);
- }
-
- i+=SMALBUF;
- }
- printf("100%%\n");
- fflush(stdout);
- }
-
-
-
- if(v==2 || v==4)
- {
- file=fopen(argv[2],"r+b");
- if(file==NULL)
- {
- printf("file %s not found or write protected\n",argv[1]);
- return(0);
- }
- }
-
- if(v==2)
- {
- if(ChkSum(file,ty,l,1)==0) printf("Checksum of %s is good\n",argv[2]);
- else printf("Checksum of %s is wrong\n",argv[2]);
- fclose(file);
- }
-
- if(v==4)
- {
- if(ChkSum(file,ty,l,0)==0) printf("Checksum of %s regenerated\n",argv[2]);
- else printf("Error writing Checksum of %s\n",argv[2]);
- fclose(file);
- }
-
-
- close(f);
- return(0);
- }
-
-
- int IsRom(unsigned char *a)
- {
- if(a[0]==B1 && a[1]==B2) return(0);
- if(a[0]==B2 && a[1]==B1) return(1);
- return(-1);
- }
-
-
- void Swap(unsigned char *buffer,int l)
- {
- int i;
- unsigned char p;
-
- for(i=0;i<l-1;i=i+2)
- {
- p=buffer[i];
- buffer[i]=buffer[i+1];
- buffer[i+1]=p;
- }
- }
-
-
- int ChkSum(FILE *file,int swapped,long flen,int readonly)
- {
- unsigned char *buffer;
- unsigned long sum1, sum2;
- unsigned long i;
- unsigned long c1, k1, k2;
- unsigned long t1, t2, t3, t4;
- unsigned long t5, t6;
- unsigned int n;
- long clen = CHECKSUM_LENGTH;
- long rlen = flen - CHECKSUM_START;
- int wrong,jj,ret;
-
- buffer=(unsigned char *)malloc(BUFSIZE);
- if(buffer==NULL) return(-99);
-
-
- t1 = CHECKSUM_STARTVALUE;
- t2 = CHECKSUM_STARTVALUE;
- t3 = CHECKSUM_STARTVALUE;
- t4 = CHECKSUM_STARTVALUE;
- t5 = CHECKSUM_STARTVALUE;
- t6 = CHECKSUM_STARTVALUE;
-
- fseek(file, CHECKSUM_START, SEEK_SET);
-
- for( ;; ) {
- if( rlen > 0 ) {
- n = fread(buffer, 1, min2(BUFSIZE, clen), file);
- if( (n & 0x03) != 0 ) {
- n += fread(buffer+n, 1, 4-(n&3), file);
- }
- } else {
- n = min2(BUFSIZE, clen);
- }
- if( (n == 0) || ((n&3) != 0) ) {
- if( (clen != 0) || (n != 0) ) {
- if(readonly==1)
- {
- free(buffer);
- return(-1);
- }
- }
- break;
- }
- for( i=0; i<n; i+=4 ) {
- c1 = BYTES2LONG(&buffer[i], swapped);
- k1 = t6 + c1;
- if( k1 < t6 ) t4++;
- t6 = k1;
- t3 ^= c1;
- k2 = c1 & 0x1f;
- k1 = ROL(c1, k2);
- t5 += k1;
- if( c1 < t2 ) {
- t2 ^= k1;
- } else {
- t2 ^= t6 ^ c1;
- }
- t1 += c1 ^ t5;
- }
- if( rlen > 0 ) {
- rlen -= n;
- if( rlen <= 0 ) memset(buffer, 0, BUFSIZE);
- }
- clen -= n;
- }
- sum1 = t6 ^ t4 ^ t3;
- sum2 = t5 ^ t2 ^ t1;
-
- LONG2BYTES(sum1, &buffer[0], 0);
- LONG2BYTES(sum2, &buffer[4], 0);
- fseek(file, CHECKSUM_HEADERPOS, SEEK_SET);
- fread(buffer+8, 1, 8, file);
-
- wrong=0;
-
- for(jj=0;jj<=7;jj++)
- if(buffer[(jj+8)^swapped]!=buffer[jj]) wrong=-1;
-
- if(readonly==0)
- {
- fseek(file, CHECKSUM_HEADERPOS, SEEK_SET);
- LONG2BYTES(sum1, &buffer[16], swapped);
- LONG2BYTES(sum2, &buffer[20], swapped);
- if( fwrite(buffer+16, 1, 8, file) != 8 ) ret=-1; else ret=0;
- }
- else ret=wrong;
-
- free(buffer);
- return(ret);
- }
-
-