FreeCalypso > hg > fc-magnetite
comparison helpers/srec4ram.c @ 92:40b08f6cb2b8
srec4ram helper utility written
author | Mychaela Falconia <falcon@freecalypso.org> |
---|---|
date | Sun, 02 Oct 2016 19:32:00 +0000 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
91:a1ed3269da48 | 92:40b08f6cb2b8 |
---|---|
1 /* | |
2 * This ad hoc utility is used as part of building RAM-loadable | |
3 * firmware images for targets with large RAM. It reads the ramimage.m0 | |
4 * S-record file produced by TI's hex470 post-linker and re-emits it | |
5 * in another SREC form that is suitable for feeding to fc-xram. | |
6 */ | |
7 | |
8 #include <sys/types.h> | |
9 #include <ctype.h> | |
10 #include <stdio.h> | |
11 #include <stdlib.h> | |
12 #include <string.h> | |
13 #include <strings.h> | |
14 | |
15 char *infname; | |
16 FILE *inf, *outf; | |
17 char srecbuf[80]; | |
18 u_char srecbin[40], srecout[40]; | |
19 int lineno; | |
20 | |
21 decode_hex_byte(s) | |
22 char *s; | |
23 { | |
24 register int u, l; | |
25 | |
26 if (!isxdigit(s[0]) || !isxdigit(s[1])) | |
27 return(-1); | |
28 if (isdigit(s[0])) | |
29 u = s[0] - '0'; | |
30 else if (isupper(s[0])) | |
31 u = s[0] - 'A' + 10; | |
32 else | |
33 u = s[0] - 'a' + 10; | |
34 if (isdigit(s[1])) | |
35 l = s[1] - '0'; | |
36 else if (isupper(s[1])) | |
37 l = s[1] - 'A' + 10; | |
38 else | |
39 l = s[1] - 'a' + 10; | |
40 return((u << 4) | l); | |
41 } | |
42 | |
43 srec2bin() | |
44 { | |
45 register int i, l, b; | |
46 | |
47 l = decode_hex_byte(srecbuf + 2); | |
48 if (l < 1) { | |
49 fprintf(stderr, "%s line %d: S-record length octet is bad\n", | |
50 infname, lineno); | |
51 exit(1); | |
52 } | |
53 srecbin[0] = l; | |
54 if (l > 35) { | |
55 fprintf(stderr, | |
56 "%s line %d: S-record is longer than expected\n", | |
57 infname, lineno); | |
58 exit(1); | |
59 } | |
60 for (i = 1; i <= l; i++) { | |
61 b = decode_hex_byte(srecbuf + i*2 + 2); | |
62 if (b < 0) { | |
63 fprintf(stderr, "%s line %d: hex decode error\n", | |
64 infname, lineno); | |
65 exit(1); | |
66 } | |
67 srecbin[i] = b; | |
68 } | |
69 return(0); | |
70 } | |
71 | |
72 srec_cksum() | |
73 { | |
74 u_char accum; | |
75 register int i, len; | |
76 | |
77 len = srecbin[0] + 1; | |
78 accum = 0; | |
79 for (i = 0; i < len; i++) | |
80 accum += srecbin[i]; | |
81 if (accum != 0xFF) { | |
82 fprintf(stderr, "%s line %d: bad checksum\n", infname, lineno); | |
83 exit(1); | |
84 } | |
85 return(0); | |
86 } | |
87 | |
88 emit_output_srec(type, buf) | |
89 u_char *buf; | |
90 { | |
91 int i; | |
92 u_char accum = 0; | |
93 | |
94 putc('S', outf); | |
95 putc(type, outf); | |
96 for (i = 0; i < buf[0]; i++) { | |
97 fprintf(outf, "%02X", buf[i]); | |
98 accum += buf[i]; | |
99 } | |
100 fprintf(outf, "%02X\n", ~accum & 0xFF); | |
101 return 0; | |
102 } | |
103 | |
104 transform_s3() | |
105 { | |
106 int datalen; | |
107 u_char *sp, *dp; | |
108 int i; | |
109 | |
110 if (srecbin[0] < 6) { | |
111 fprintf(stderr, | |
112 "%s line %d: S3 record is too short\n", | |
113 infname, lineno); | |
114 exit(1); | |
115 } | |
116 datalen = srecbin[0] - 5; | |
117 if (datalen & 1) { | |
118 fprintf(stderr, "%s line %d: odd data length\n", | |
119 infname, lineno); | |
120 exit(1); | |
121 } | |
122 sp = srecbin; | |
123 dp = srecout; | |
124 for (i = 0; i < 5; i++) | |
125 *dp++ = *sp++; | |
126 for (i = 0; i < datalen; i += 2) { | |
127 dp[0] = sp[1]; | |
128 dp[1] = sp[0]; | |
129 sp += 2; | |
130 dp += 2; | |
131 } | |
132 return 0; | |
133 } | |
134 | |
135 generate_vectors_record() | |
136 { | |
137 u_char *dp; | |
138 u_long addr; | |
139 int i; | |
140 | |
141 srecout[0] = 28 + 5; | |
142 srecout[1] = 0x00; | |
143 srecout[2] = 0x80; | |
144 srecout[3] = 0x00; | |
145 srecout[4] = 0x00; | |
146 dp = srecout + 5; | |
147 for (i = 0; i < 7; i++) { | |
148 addr = 0x01004000 + i * 4; | |
149 *dp++ = addr; | |
150 *dp++ = addr >> 8; | |
151 *dp++ = addr >> 16; | |
152 *dp++ = addr >> 24; | |
153 } | |
154 emit_output_srec('3', srecout); | |
155 return 0; | |
156 } | |
157 | |
158 generate_jump_record() | |
159 { | |
160 srecout[0] = 5; | |
161 srecout[1] = 0x01; | |
162 srecout[2] = 0x00; | |
163 srecout[3] = 0x40; | |
164 srecout[4] = 0x58; | |
165 emit_output_srec('7', srecout); | |
166 return 0; | |
167 } | |
168 | |
169 main(argc, argv) | |
170 char **argv; | |
171 { | |
172 if (argc < 2 || argc > 3) { | |
173 fprintf(stderr, "usage: %s input.m0 [output.srec]\n", argv[0]); | |
174 exit(1); | |
175 } | |
176 infname = argv[1]; | |
177 inf = fopen(infname, "r"); | |
178 if (!inf) { | |
179 perror(infname); | |
180 exit(1); | |
181 } | |
182 if (argc > 2) { | |
183 outf = fopen(argv[2], "w"); | |
184 if (!outf) { | |
185 perror(argv[2]); | |
186 exit(1); | |
187 } | |
188 } else | |
189 outf = stdout; | |
190 for (lineno = 1; ; lineno++) { | |
191 if (!fgets(srecbuf, sizeof srecbuf, inf)) { | |
192 fprintf(stderr, "%s: premature EOF\n", infname); | |
193 exit(1); | |
194 } | |
195 if (srecbuf[0] != 'S') { | |
196 fprintf(stderr, "%s line %d: not an S-record\n", | |
197 infname, lineno); | |
198 exit(1); | |
199 } | |
200 srec2bin(); | |
201 srec_cksum(); | |
202 switch (srecbuf[1]) { | |
203 case '0': | |
204 emit_output_srec('0', srecbin); | |
205 continue; | |
206 case '3': | |
207 transform_s3(); | |
208 emit_output_srec('3', srecout); | |
209 continue; | |
210 case '7': | |
211 break; | |
212 default: | |
213 fprintf(stderr, "%s line %d: unexpected S%c record\n", | |
214 infname, lineno, srecbuf[1]); | |
215 exit(1); | |
216 } | |
217 break; | |
218 } | |
219 generate_vectors_record(); | |
220 generate_jump_record(); | |
221 exit(0); | |
222 } |