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