FreeCalypso > hg > freecalypso-tools
comparison miscutil/srec-regions.c @ 622:89e9e79a7f55
srec-regions utility written, compiles
author | Mychaela Falconia <falcon@freecalypso.org> |
---|---|
date | Thu, 27 Feb 2020 07:59:47 +0000 |
parents | |
children | 7485e75d9477 |
comparison
equal
deleted
inserted
replaced
621:f44770a652eb | 622:89e9e79a7f55 |
---|---|
1 /* | |
2 * This program parses an S-record file (TI's *.m0 or otherwise), identifies | |
3 * the set of discontiguous regions into which this SREC image deposits bits, | |
4 * and lists these identified regions. | |
5 */ | |
6 | |
7 #include <sys/types.h> | |
8 #include <stdio.h> | |
9 #include <ctype.h> | |
10 #include <string.h> | |
11 #include <strings.h> | |
12 #include <stdlib.h> | |
13 | |
14 char *infname; | |
15 FILE *inf; | |
16 char srecbuf[1024]; | |
17 u_char srecbin[256]; | |
18 int lineno, state; | |
19 u_long region_start, region_end; | |
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 for (i = 1; i <= l; i++) { | |
55 b = decode_hex_byte(srecbuf + i*2 + 2); | |
56 if (b < 0) { | |
57 fprintf(stderr, "%s line %d: hex decode error\n", | |
58 infname, lineno); | |
59 exit(1); | |
60 } | |
61 srecbin[i] = b; | |
62 } | |
63 return(0); | |
64 } | |
65 | |
66 srec_cksum() | |
67 { | |
68 u_char accum; | |
69 register int i, len; | |
70 | |
71 len = srecbin[0] + 1; | |
72 accum = 0; | |
73 for (i = 0; i < len; i++) | |
74 accum += srecbin[i]; | |
75 if (accum != 0xFF) { | |
76 fprintf(stderr, "%s line %d: bad checksum\n", infname, lineno); | |
77 exit(1); | |
78 } | |
79 return(0); | |
80 } | |
81 | |
82 main(argc, argv) | |
83 char **argv; | |
84 { | |
85 register int i; | |
86 u_long curaddr; | |
87 int datalen; | |
88 | |
89 if (argc != 2) { | |
90 fprintf(stderr, "usage: %s image.m0\n", argv[0]); | |
91 exit(1); | |
92 } | |
93 infname = argv[1]; | |
94 inf = fopen(infname, "r"); | |
95 if (!inf) { | |
96 perror(infname); | |
97 exit(1); | |
98 } | |
99 | |
100 state = 0; | |
101 for (lineno = 1; ; lineno++) { | |
102 if (!fgets(srecbuf, sizeof srecbuf, inf)) { | |
103 fprintf(stderr, "%s: premature EOF\n", infname); | |
104 exit(1); | |
105 } | |
106 if (srecbuf[0] != 'S') { | |
107 fprintf(stderr, "%s line %d: not an S-record\n", | |
108 infname, lineno); | |
109 exit(1); | |
110 } | |
111 switch (srecbuf[1]) { | |
112 case '0': | |
113 if (state == 0) | |
114 break; | |
115 else | |
116 goto badtype; | |
117 case '3': | |
118 if (state == 0) | |
119 goto badtype; | |
120 else | |
121 break; | |
122 case '7': | |
123 if (state == 2) | |
124 break; | |
125 else | |
126 goto badtype; | |
127 default: | |
128 badtype: | |
129 fprintf(stderr, | |
130 "%s line %d: S-record type unexpected\n", | |
131 infname, lineno); | |
132 exit(1); | |
133 } | |
134 srec2bin(); | |
135 srec_cksum(); | |
136 switch (srecbuf[1]) { | |
137 case '0': | |
138 state = 1; | |
139 continue; | |
140 case '3': | |
141 if (srecbin[0] < 6) { | |
142 fprintf(stderr, | |
143 "%s line %d: S3 record is too short\n", | |
144 infname, lineno); | |
145 exit(1); | |
146 } | |
147 curaddr = (srecbin[1] << 24) | (srecbin[2] << 16) | | |
148 (srecbin[3] << 8) | srecbin[4]; | |
149 datalen = srecbin[0] - 5; | |
150 if (state < 2) { | |
151 region_start = curaddr; | |
152 region_end = curaddr + datalen; | |
153 state = 2; | |
154 continue; | |
155 } | |
156 if (curaddr < region_end) { | |
157 fprintf(stderr, | |
158 "%s line %d: address going backwards\n", | |
159 infname, lineno); | |
160 exit(1); | |
161 } | |
162 if (curaddr > region_end) { | |
163 printf("0x%08lX to 0x%08lX (%lu bytes)\n", | |
164 region_start, region_end, | |
165 region_end - region_start); | |
166 region_start = curaddr; | |
167 } | |
168 region_end = curaddr + datalen; | |
169 continue; | |
170 case '7': | |
171 printf("0x%08lX to 0x%08lX (%lu bytes)\n", | |
172 region_start, region_end, | |
173 region_end - region_start); | |
174 exit(0); | |
175 default: | |
176 abort(); | |
177 } | |
178 } | |
179 } |