scripts

misc scripts and tools
git clone git://git.2f30.org/scripts.git
Log | Files | Refs

makeip.c (3964B)


      1 #include <stdio.h>
      2 #include <stdlib.h>
      3 #include <string.h>
      4 
      5 
      6 #define NUM_FIELDS 11
      7 
      8 struct field;
      9 
     10 int check_areasym(char *, struct field *);
     11 
     12 struct field {
     13   char *name;
     14   int pos;
     15   int len;
     16   int (*extra_check)(char *, struct field *);
     17 } fields[NUM_FIELDS] = {
     18   { "Hardware ID", 0x0, 0x10, NULL },
     19   { "Maker ID", 0x10, 0x10, NULL },
     20   { "Device Info", 0x20, 0x10, NULL },
     21   { "Area Symbols", 0x30, 0x8, check_areasym },
     22   { "Peripherals", 0x38, 0x8, NULL },
     23   { "Product No", 0x40, 0xa, NULL },
     24   { "Version", 0x4a, 0x6, NULL },
     25   { "Release Date", 0x50, 0x10, NULL },
     26   { "Boot Filename", 0x60, 0x10, NULL },
     27   { "SW Maker Name", 0x70, 0x10, NULL },
     28   { "Game Title", 0x80, 0x80, NULL },
     29 };
     30 
     31 int filled_in[NUM_FIELDS];
     32 
     33 int check_areasym(char *ptr, struct field *f)
     34 {
     35   int i, a = 0;
     36   for(i=0; i<f->len; i++)
     37     switch(ptr[i]) {
     38      case 'J':
     39        a |= (1<<0);
     40        break;
     41      case 'U':
     42        a |= (1<<1);
     43        break;
     44      case 'E':
     45        a |= (1<<2);
     46        break;
     47      case ' ':
     48        break;
     49      default:
     50        fprintf(stderr, "Unknown area symbol '%c'.\n", ptr[i]);
     51        return 0;
     52     }
     53   for(i=0; i<f->len; i++)
     54     if((a & (1<<i)) == 0)
     55       ptr[i] = ' ';
     56     else
     57       ptr[i] = "JUE"[i];
     58   return 1;
     59 }
     60 
     61 void trim(char *str)
     62 {
     63   int l = strlen(str);
     64   while(l>0 && (str[l-1] == '\r' || str[l-1] == '\n' ||
     65 		str[l-1] == ' ' || str[l-1] == '\t'))
     66     str[--l]='\0';
     67 }
     68 
     69 int parse_input(FILE *fh, char *ip)
     70 {
     71   static char buf[80];
     72   int i;
     73   memset(filled_in, 0, sizeof(filled_in));
     74   while(fgets(buf, sizeof(buf), fh)) {
     75     char *p;
     76     trim(buf);
     77     if(*buf)
     78       if((p = strchr(buf, ':'))) {
     79 	*p++ = '\0';
     80 	trim(buf);
     81 	for(i=0; i<NUM_FIELDS; i++)
     82 	  if(!strcmp(buf, fields[i].name))
     83 	    break;
     84 	if(i>=NUM_FIELDS) {
     85 	  fprintf(stderr, "Unknown field \"%s\".\n", buf);
     86 	  return 0;
     87 	}
     88 	memset(ip+fields[i].pos, ' ', fields[i].len);
     89 	while(*p == ' ' || *p == '\t')
     90 	  p++;
     91 	if(strlen(p)>fields[i].len) {
     92 	  fprintf(stderr, "Data for field \"%s\" is too long.\n", fields[i]);
     93 	  return 0;
     94 	}
     95 	memcpy(ip+fields[i].pos, p, strlen(p));
     96 	if(fields[i].extra_check!=NULL &&
     97 	   !(*fields[i].extra_check)(ip+fields[i].pos, &fields[i]))
     98 	  return 0;
     99 	filled_in[i] = 1;
    100       } else {
    101 	fprintf(stderr, "Missing : on line.\n");
    102 	return 0;
    103       }
    104   }
    105 
    106   for(i=0; i<NUM_FIELDS; i++)
    107     if(!filled_in[i]) {
    108       fprintf(stderr, "Missing value for \"%s\".\n", fields[i]);
    109       return 0;
    110     }
    111       
    112   return 1;
    113 }
    114 
    115 int calcCRC(const unsigned char *buf, int size)
    116 {
    117   int i, c, n = 0xffff;
    118   for (i = 0; i < size; i++)
    119   {
    120     n ^= (buf[i]<<8);
    121     for (c = 0; c < 8; c++)
    122       if (n & 0x8000)
    123         n = (n << 1) ^ 4129;
    124       else
    125         n = (n << 1);
    126   }
    127   return n & 0xffff;
    128 }
    129 
    130 void update_crc(char *ip)
    131 {
    132   int n = calcCRC((unsigned char *)(ip+0x40), 16);
    133   char buf[5];
    134   sprintf(buf, "%04X", n);
    135   if(memcmp(buf, ip+0x20, 4)) {
    136     printf("Setting CRC to %s (was %.4s)\n", buf, ip+0x20);
    137     memcpy(ip+0x20, buf, 4);
    138   }
    139 }
    140 
    141 void makeip(char *ip_tmpl, char *in, char *out)
    142 {
    143   static char ip[0x8000];
    144   FILE *fh = fopen(ip_tmpl, "rb");
    145   if(fh == NULL) {
    146     fprintf(stderr, "Can't open \"%s\".\n", ip_tmpl);
    147     exit(1);
    148   }
    149   if(fread(ip, 1, 0x8000, fh) != 0x8000) {
    150     fprintf(stderr, "Read error.\n");
    151     exit(1);
    152   }
    153   fclose(fh);
    154   fh = fopen(in, "r");
    155   if(fh == NULL) {
    156     fprintf(stderr, "Can't open \"%s\".\n", in);
    157     exit(1);
    158   }
    159   if(!parse_input(fh, ip))
    160     exit(1);
    161   fclose(fh);
    162   update_crc(ip);
    163   fh = fopen(out, "wb");
    164   if(fh == NULL) {
    165     fprintf(stderr, "Can't open \"%s\".\n", out);
    166     exit(1);
    167   }
    168   if(fwrite(ip, 1, 0x8000, fh) != 0x8000) {
    169     fprintf(stderr, "Write error.\n");
    170     exit(1);
    171   }
    172   fclose(fh);
    173 }
    174 
    175 int main(int argc, char *argv[])
    176 {
    177   char *ip_tmpl;
    178 
    179   if(argc != 3) {
    180     fprintf(stderr, "Usage: %s ip.txt IP.BIN\n", argv[0]);
    181     exit(1);
    182   }
    183 
    184   ip_tmpl = getenv("IP_TEMPLATE_FILE");
    185   if(ip_tmpl == NULL)
    186     ip_tmpl = "IP.TMPL";
    187 
    188   makeip(ip_tmpl, argv[1], argv[2]);
    189 
    190   return 0;
    191 }