* as/z80/string.h: disable this header for gcc 3.2
[fw/sdcc] / support / makebin / makebin.c
1 /** @name makebin - turn a .ihx file into a binary image.
2  */
3 #include <stdio.h>
4 #include <unistd.h>
5 #include <stdlib.h>
6 #include <string.h>
7
8 typedef unsigned char BYTE;
9
10 #define FILL_BYTE 0xFF
11
12 int getnibble(char **p)
13 {
14   int ret = *((*p)++) - '0';
15   if (ret > 9) {
16     ret -= 'A' - '9' - 1;
17   }
18   return ret;
19 }
20
21 int getbyte(char **p)
22 {
23   return (getnibble(p) << 4) | getnibble(p);
24 }
25
26 void usage(void)
27 {
28   fprintf(stderr, 
29           "makebin: convert a Intel IHX file to binary.\n"
30           "Usage: makebin [-p] [-s romsize] [-h]\n");
31 }
32
33 int main(int argc, char **argv)
34 {
35     int size = 32768, pack = 0, real_size = 0;
36     BYTE *rom;
37     char line[256];
38     char *p;
39
40     argc--;
41     argv++;
42
43     while (argc--) {
44         if (**argv != '-') {
45             usage();
46             return -1;
47         }
48         switch (argv[0][1]) {
49         case 's':
50             if (argc < 1) {
51                 usage();
52                 return -1;
53             }
54             argc--;
55             argv++;
56             size = atoi(*argv);
57             break;
58         case 'h':
59             usage();
60             return 0;
61         case 'p':
62             pack = 1;
63             break;
64         default:
65             usage();
66             return -1;
67         }
68         argv++;
69     }
70
71     rom = malloc(size);
72     if (rom == NULL) {
73         fprintf(stderr, "error: couldn't allocate room for the image.\n");
74         return -1;
75     }
76     memset(rom, FILL_BYTE, size);
77     while (fgets(line, 256, stdin) != NULL) {
78         int nbytes;
79         int addr;
80
81         if (*line != ':') {
82             fprintf(stderr, "error: invalid IHX line.\n");
83             return -2;
84         }
85         p = line+1;
86         nbytes = getbyte(&p);
87         addr = getbyte(&p)<<8 | getbyte(&p);
88         getbyte(&p);
89
90         while (nbytes--) {
91             if (addr < size)
92                 rom[addr++] = getbyte(&p);
93         }
94
95         if (addr > real_size)
96             real_size = addr;
97     }
98
99     if (pack)
100         fwrite(rom, 1, real_size, stdout);
101     else
102         fwrite(rom, 1, size, stdout);
103     
104     return 0;
105 }