1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24#include <common.h>
25#include <s_record.h>
26
27static int hex1_bin (char c);
28static int hex2_bin (char *s);
29
30int srec_decode (char *input, int *count, ulong *addr, char *data)
31{
32 int i;
33 int v;
34 int srec_type;
35 unsigned char chksum;
36
37 chksum = 0;
38
39
40
41
42
43 for (; *input; ++input) {
44 if (*input == 'S') {
45 ++input;
46 break;
47 }
48 }
49 if (*input == '\0') {
50 return (SREC_EMPTY);
51 }
52
53 v = *input++;
54
55 if ((*count = hex2_bin(input)) < 0) {
56 return (SREC_E_NOSREC);
57 }
58
59 chksum += *count;
60 input += 2;
61
62 switch (v) {
63
64 case '0':
65 srec_type = SREC_START;
66 *count -= 3;
67 break;
68 case '1':
69 srec_type = SREC_DATA2;
70 *count -= 3;
71 break;
72 case '2':
73 srec_type = SREC_DATA3;
74 *count -= 4;
75 break;
76 case '3':
77 srec_type = SREC_DATA4;
78 *count -= 5;
79 break;
80
81 case '5':
82 srec_type = SREC_COUNT;
83 *count = 0;
84 break;
85
86 case '7':
87 srec_type = SREC_END4;
88 *count -= 5;
89 break;
90 case '8':
91 srec_type = SREC_END3;
92 *count -= 4;
93 break;
94 case '9':
95 srec_type = SREC_END2;
96 *count -= 3;
97 break;
98 default:
99 return (SREC_E_BADTYPE);
100 }
101
102
103 *addr = 0;
104
105 switch (v) {
106 case '3':
107 case '7':
108 if ((v = hex2_bin(input)) < 0) {
109 return (SREC_E_NOSREC);
110 }
111 *addr += v;
112 chksum += v;
113 input += 2;
114
115 case '2':
116 case '8':
117 if ((v = hex2_bin(input)) < 0) {
118 return (SREC_E_NOSREC);
119 }
120 *addr <<= 8;
121 *addr += v;
122 chksum += v;
123 input += 2;
124
125 case '0':
126 case '1':
127 case '5':
128 case '9':
129 if ((v = hex2_bin(input)) < 0) {
130 return (SREC_E_NOSREC);
131 }
132 *addr <<= 8;
133 *addr += v;
134 chksum += v;
135 input += 2;
136
137 if ((v = hex2_bin(input)) < 0) {
138 return (SREC_E_NOSREC);
139 }
140 *addr <<= 8;
141 *addr += v;
142 chksum += v;
143 input += 2;
144
145 break;
146 default:
147 return (SREC_E_BADTYPE);
148 }
149
150
151 for (i=0; i < *count; ++i) {
152 if ((v = hex2_bin(input)) < 0) {
153 return (SREC_E_NOSREC);
154 }
155 data[i] = v;
156 chksum += v;
157 input += 2;
158 }
159
160
161 if ((v = hex2_bin(input)) < 0) {
162 return (SREC_E_NOSREC);
163 }
164
165 if ((unsigned char)v != (unsigned char)~chksum) {
166 return (SREC_E_BADCHKS);
167 }
168
169 return (srec_type);
170}
171
172static int hex1_bin (char c)
173{
174 if (c >= '0' && c <= '9')
175 return (c - '0');
176 if (c >= 'a' && c <= 'f')
177 return (c + 10 - 'a');
178 if (c >= 'A' && c <= 'F')
179 return (c + 10 - 'A');
180 return (-1);
181}
182
183static int hex2_bin (char *s)
184{
185 int i, j;
186
187 if ((i = hex1_bin(*s++)) < 0) {
188 return (-1);
189 }
190 if ((j = hex1_bin(*s)) < 0) {
191 return (-1);
192 }
193
194 return ((i<<4) + j);
195}
196