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