Rev 183 | Details | Compare with Previous | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
79 | ddp | 1 | #include <stdio.h> |
2 | #include <stdlib.h> |
||
3 | #include <string.h> |
||
4 | #include <time.h> |
||
5 | |||
6 | typedef unsigned char BYTE; |
||
7 | typedef unsigned short WORD; |
||
8 | typedef unsigned long LONGWORD; |
||
9 | |||
10 | #define HEXLEN 0 |
||
11 | #define DATATYPE 1 |
||
12 | #define CHECKSUM 2 |
||
13 | |||
14 | BYTE checksum; |
||
15 | WORD col, row; |
||
16 | LONGWORD err; |
||
17 | BYTE s[256], s1[256]; |
||
18 | |||
19 | //----------------------------------------------------------------------------- |
||
20 | |||
21 | void print_err_rc() |
||
22 | { |
||
23 | printf("Error! (Row %d, Col %d)\n",row,col+1); |
||
24 | err++; |
||
25 | } |
||
26 | |||
27 | //----------------------------------------------------------------------------- |
||
28 | |||
29 | void print_err_r(BYTE cause) |
||
30 | { |
||
31 | BYTE* cause_str[3]={"Number of byte","Unknown datatype","Checksum"}; |
||
32 | printf("Error! %s. (Row %d)\n",cause_str[cause],row); |
||
33 | err++; |
||
34 | } |
||
35 | |||
36 | //----------------------------------------------------------------------------- |
||
37 | |||
38 | BYTE getbyte() |
||
39 | { |
||
40 | BYTE b1, b0; |
||
41 | |||
42 | b1=s[col]; |
||
43 | if ( ( (b1>=0x30)&&(b1<=0x39) )||( (b1>=0x41)&&(b1<=0x46) ) ) |
||
44 | { |
||
45 | b1-=0x30; |
||
46 | if (b1>9) b1-=7; |
||
47 | } |
||
48 | else |
||
49 | { |
||
50 | print_err_rc(); |
||
51 | b1=0; |
||
52 | } |
||
53 | col++; |
||
54 | |||
55 | b0=s[col]; |
||
56 | if ( ( (b0>=0x30)&&(b0<=0x39) )||( (b0>=0x41)&&(b0<=0x46) ) ) |
||
57 | { |
||
58 | b0-=0x30; |
||
59 | if (b0>9) b0-=7; |
||
60 | } |
||
61 | else |
||
62 | { |
||
63 | print_err_rc(); |
||
64 | b0=0; |
||
65 | } |
||
66 | col++; |
||
67 | |||
68 | b0|=(b1<<4); |
||
69 | checksum+=b0; |
||
70 | return b0; |
||
71 | } |
||
72 | |||
73 | //----------------------------------------------------------------------------- |
||
74 | |||
75 | int main(int argc,char*argv[]) |
||
76 | { |
||
77 | BYTE h[]="0123456789ABCDEF"; |
||
78 | BYTE b, m, o, hexlen, datatype; |
||
79 | WORD i, crc; |
||
80 | LONGWORD x0, x1, adr, segadr; |
||
81 | struct tm stm; |
||
82 | BYTE vs[86]; |
||
83 | BYTE E2Phead[0x98] = { |
||
84 | 0x45,0x32,0x50,0x21,0x4C,0x61,0x6E,0x63,0xC0,0x10,0x30,0x00,0x03,0x00,0x00,0x10, |
||
85 | 0x02,0x00,0x00,0x77,0x00,0x00,0x00,0x02,0x00,0x00,0x41,0x54,0x6D,0x65,0x67,0x61, |
||
86 | 0x31,0x32,0x38 }; |
||
87 | WORD tabcrc[256]; |
||
88 | BYTE buff[0x2000]; |
||
89 | FILE* f; |
||
90 | |||
91 | o=0; |
||
92 | printf("ZX EVO project: Calc CRC for bootloader\n"); |
||
288 | ddp | 93 | if (argc<3) { printf("usage: crcbldr <HexFileName> [<VersionFileName>]\n"); return 2; } |
79 | ddp | 94 | |
95 | for (adr=0;adr<0x2000;adr++) buff[adr]=0xff; |
||
96 | if (argc==4) |
||
97 | { |
||
98 | strncpy(s1,argv[3],1); |
||
99 | if (s1[0]=='o') o=0x80; |
||
100 | } |
||
101 | |||
102 | strncpy(s1,argv[2],255); |
||
103 | f=fopen(s1,"rt"); |
||
104 | vs[0]=0; |
||
105 | if (f) |
||
106 | { |
||
107 | fgets(vs,13,f); |
||
108 | fclose(f); |
||
109 | } |
||
110 | i=strlen(vs); |
||
111 | if ((i) && (vs[i-1]=='\n')) vs[--i]=0; |
||
112 | if (!i) |
||
113 | { |
||
114 | strcpy(vs, "No info"); |
||
115 | o=0; |
||
116 | } |
||
117 | |||
118 | strncpy(s1,argv[1],255); |
||
119 | f=fopen(s1,"rt"); |
||
120 | if (!f) { printf("Can't open file %s!\n",s1); return 1; } |
||
121 | |||
122 | err=0; |
||
123 | segadr=0; |
||
124 | row=0; |
||
125 | while (!feof(f)) |
||
126 | { |
||
127 | row++; |
||
128 | col=0; |
||
129 | if (fgets(s,255,f) && strlen(s)) |
||
130 | { |
||
131 | if (s[col]!=':') print_err_rc(); |
||
132 | col++; |
||
133 | checksum=0; |
||
134 | hexlen=getbyte(); |
||
135 | x1=getbyte(); |
||
136 | x0=getbyte(); |
||
137 | adr=segadr|(x1<<8)|x0; |
||
138 | datatype=getbyte(); |
||
139 | switch (datatype) |
||
140 | { |
||
141 | // Data record |
||
142 | case 0: while (hexlen>0) |
||
143 | { |
||
144 | b=getbyte(); |
||
145 | hexlen--; |
||
146 | if ( (adr>=0x1e000) && (adr<0x20000) ) buff[adr-0x1e000]=b; |
||
147 | adr++; |
||
148 | } |
||
149 | break; |
||
150 | // End of file record |
||
151 | case 1: if (hexlen!=0) print_err_r(HEXLEN); |
||
152 | break; |
||
153 | // Extended segment address record |
||
154 | case 2: x1=getbyte(); |
||
155 | x0=getbyte(); |
||
156 | segadr=(x1<<12)|(x0<<4); |
||
157 | if (hexlen!=2) print_err_r(HEXLEN); |
||
158 | break; |
||
159 | // Start segment address record |
||
160 | case 3: break; |
||
161 | // Extended linear address record |
||
162 | case 4: x1=getbyte(); |
||
163 | x0=getbyte(); |
||
164 | segadr=(x1<<24)|(x0<<16); |
||
165 | if (hexlen!=2) print_err_r(HEXLEN); |
||
166 | break; |
||
167 | // Start linear address record |
||
168 | case 5: break; |
||
169 | default: print_err_r(DATATYPE); |
||
170 | while (hexlen!=0) { getbyte(); hexlen--; } |
||
171 | } |
||
172 | getbyte(); |
||
173 | if (checksum!=0) print_err_r(CHECKSUM); |
||
174 | } |
||
175 | } |
||
176 | fclose(f); |
||
177 | |||
288 | ddp | 178 | if (err) { printf("Total %d error(s)!\n",(int)err); return 3; } |
79 | ddp | 179 | |
180 | for (i=0;i<256;i++) |
||
181 | { |
||
182 | crc=i<<8; |
||
183 | b=8; |
||
184 | do |
||
185 | { |
||
186 | if (crc&0x8000) |
||
187 | crc=(crc<<1)^0x1021; |
||
188 | else |
||
189 | crc<<=1; |
||
190 | b--; |
||
191 | } |
||
192 | while ((b)&&(crc)); |
||
193 | tabcrc[i]=crc; |
||
194 | } |
||
195 | |||
196 | strncpy(&buff[0x1ff0], vs, 12); |
||
197 | { |
||
198 | time_t tt; |
||
199 | tt=time(NULL); |
||
200 | memcpy(&stm,localtime(&tt),sizeof(stm)); |
||
201 | } |
||
202 | i=(WORD)( (((stm.tm_year-100)&0x3f)<<9) | (((stm.tm_mon+1)&0x0f)<<5) | (stm.tm_mday&0x1f) ); |
||
183 | ddp | 203 | buff[0x1ffd]=(i>>8)&0x7f|o; |
204 | buff[0x1ffc]=i&0xff; |
||
79 | ddp | 205 | |
206 | crc=0xffff; |
||
207 | for (adr=0;adr<0x1ffe;adr++) crc=tabcrc[(crc>>8)^buff[adr]]^(crc<<8); |
||
208 | buff[0x1ffe]=crc>>8; |
||
209 | buff[0x1fff]=crc&0xff; |
||
210 | |||
211 | // - - - - - - - - |
||
212 | |||
288 | ddp | 213 | f=fopen("zxevo_bl.hex","wt"); |
79 | ddp | 214 | if (!f) { printf("Can't create output file!\n"); return 1; } |
215 | |||
216 | fputs(":020000020000FC\n:01000000FF00\n:020000021000EC\n",f); |
||
217 | s[0]=':'; |
||
218 | s[1]='1'; |
||
219 | s[2]='0'; |
||
220 | adr=0; |
||
221 | |||
222 | do |
||
223 | { |
||
224 | checksum=0xf0; |
||
225 | m=3; |
||
226 | b=((adr>>8)&0xff)+0xe0; |
||
227 | checksum-=b; |
||
228 | s[m++]=h[b>>4]; |
||
229 | s[m++]=h[b&0x0f]; |
||
230 | b=adr&0xff; |
||
231 | checksum-=b; |
||
232 | s[m++]=h[b>>4]; |
||
233 | s[m++]=h[b&0x0f]; |
||
234 | s[m++]='0'; |
||
235 | s[m++]='0'; |
||
236 | for (i=0;i<16;i++) |
||
237 | { |
||
238 | b=buff[adr++]; |
||
239 | checksum-=b; |
||
240 | s[m++]=h[b>>4]; |
||
241 | s[m++]=h[b&0x0f]; |
||
242 | } |
||
243 | s[m++]=h[checksum>>4]; |
||
244 | s[m++]=h[checksum&0x0f]; |
||
245 | s[m++]='\n'; |
||
246 | s[m]=0; |
||
247 | fputs(s,f); |
||
248 | } |
||
249 | while (adr<0x2000); |
||
250 | |||
251 | fputs(":00000001FF\n",f); |
||
252 | fclose(f); |
||
253 | |||
288 | ddp | 254 | printf("Created file zxevo_bl.hex\n"); |
79 | ddp | 255 | |
256 | // - - - - - - - - |
||
257 | |||
258 | for (i=0;i<256;i++) |
||
259 | { |
||
260 | crc=i; |
||
261 | b=8; |
||
262 | do |
||
263 | { |
||
264 | if (crc&0x0001) |
||
265 | crc=(crc>>1)^0xa001; |
||
266 | else |
||
267 | crc>>=1; |
||
268 | b--; |
||
269 | } |
||
270 | while ((b)&&(crc)); |
||
271 | tabcrc[i]=crc; |
||
272 | } |
||
273 | |||
274 | i=strlen(vs); |
||
275 | vs[i++]=' '; |
||
276 | b=stm.tm_mday&0x1f; |
||
277 | vs[i++]=h[b/10]; |
||
278 | vs[i++]=h[b%10]; |
||
279 | vs[i++]='.'; |
||
280 | b=stm.tm_mon+1; |
||
281 | vs[i++]=h[b/10]; |
||
282 | vs[i++]=h[b%10]; |
||
283 | vs[i++]='.'; |
||
284 | vs[i++]='2'; |
||
285 | vs[i++]='0'; |
||
286 | b=stm.tm_year-100; |
||
287 | vs[i++]=h[b/10]; |
||
288 | vs[i++]=h[b%10]; |
||
289 | vs[i]=0; |
||
183 | ddp | 290 | if (!o) strcpy(&vs[i]," beta"); |
79 | ddp | 291 | |
292 | strncpy(&E2Phead[0x3a],vs,85); |
||
293 | E2Phead[0x90]=0x02; |
||
294 | E2Phead[0x91]=0x00; |
||
295 | |||
296 | crc=0xd001; // precalculated for empty space before |
||
297 | for (adr=0;adr<0x2000;adr++) crc=tabcrc[(crc&0xff)^buff[adr]]^(crc>>8); |
||
298 | for (adr=0;adr<0x1000;adr++) crc=tabcrc[(~crc)&0xff]^(crc>>8); // postcalculating for empty space after |
||
299 | E2Phead[0x94]=crc&0xff; |
||
300 | E2Phead[0x95]=crc>>8; |
||
301 | |||
302 | crc=0; |
||
303 | for (adr=0;adr<0x96;adr++) crc=tabcrc[(crc&0xff)^E2Phead[adr]]^(crc>>8); |
||
304 | E2Phead[0x96]=crc&0xff; |
||
305 | E2Phead[0x97]=crc>>8; |
||
306 | |||
288 | ddp | 307 | f=fopen("zxevo_bl.e2p","wb"); |
79 | ddp | 308 | if (!f) { printf("Can't create output file!\n"); return 1; } |
309 | fwrite(E2Phead,1,0x98,f); |
||
310 | for (adr=0;adr<256;adr++) s1[adr]=0xff; |
||
311 | for (adr=0;adr<0x1e0;adr++) fwrite(s1,1,256,f); |
||
312 | fwrite(buff,1,0x2000,f); |
||
313 | for (adr=0;adr<0x10;adr++) fwrite(s1,1,256,f); |
||
314 | fclose(f); |
||
315 | |||
288 | ddp | 316 | printf("Created file zxevo_bl.e2p\n"); |
79 | ddp | 317 | |
318 | return 0; |
||
319 | } |