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