Rev 253 | Details | Compare with Previous | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
86 | 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; |
||
253 | ddp | 17 | BYTE s[256], s1[256], target[256]; |
86 | ddp | 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 | |||
148 | ddp | 75 | void readhex(FILE* f, BYTE* buff, LONGWORD buffsize) |
86 | ddp | 76 | { |
148 | ddp | 77 | BYTE b, hexlen, datatype; |
86 | ddp | 78 | LONGWORD x0, x1, adr, segadr; |
79 | |||
148 | ddp | 80 | for (adr=0;adr<buffsize;adr++) buff[adr]=0xff; |
86 | ddp | 81 | err=0; |
82 | segadr=0; |
||
83 | row=0; |
||
84 | while (!feof(f)) |
||
85 | { |
||
86 | row++; |
||
87 | col=0; |
||
88 | if (fgets(s,255,f) && strlen(s)) |
||
89 | { |
||
90 | if (s[col]!=':') print_err_rc(); |
||
91 | col++; |
||
92 | checksum=0; |
||
93 | hexlen=getbyte(); |
||
94 | x1=getbyte(); |
||
95 | x0=getbyte(); |
||
96 | adr=segadr|(x1<<8)|x0; |
||
97 | datatype=getbyte(); |
||
98 | switch (datatype) |
||
99 | { |
||
100 | // Data record |
||
101 | case 0: while (hexlen>0) |
||
102 | { |
||
103 | b=getbyte(); |
||
104 | hexlen--; |
||
148 | ddp | 105 | if (adr<buffsize) buff[adr]=b; |
86 | ddp | 106 | adr++; |
107 | } |
||
108 | break; |
||
109 | // End of file record |
||
110 | case 1: if (hexlen!=0) print_err_r(HEXLEN); |
||
111 | break; |
||
112 | // Extended segment address record |
||
113 | case 2: x1=getbyte(); |
||
114 | x0=getbyte(); |
||
115 | segadr=(x1<<12)|(x0<<4); |
||
116 | if (hexlen!=2) print_err_r(HEXLEN); |
||
117 | break; |
||
118 | // Start segment address record |
||
119 | case 3: break; |
||
120 | // Extended linear address record |
||
121 | case 4: x1=getbyte(); |
||
122 | x0=getbyte(); |
||
123 | segadr=(x1<<24)|(x0<<16); |
||
124 | if (hexlen!=2) print_err_r(HEXLEN); |
||
125 | break; |
||
126 | // Start linear address record |
||
127 | case 5: break; |
||
128 | default: print_err_r(DATATYPE); |
||
129 | while (hexlen!=0) { getbyte(); hexlen--; } |
||
130 | } |
||
131 | getbyte(); |
||
132 | if (checksum!=0) print_err_r(CHECKSUM); |
||
133 | } |
||
134 | } |
||
148 | ddp | 135 | } |
86 | ddp | 136 | |
148 | ddp | 137 | //----------------------------------------------------------------------------- |
86 | ddp | 138 | |
148 | ddp | 139 | void makebitmap(BYTE* buff, BYTE* dest, LONGWORD buffsize) |
140 | { |
||
141 | BYTE b, m; |
||
142 | LONGWORD adr, i, j; |
||
86 | ddp | 143 | |
148 | ddp | 144 | j=0; |
86 | ddp | 145 | adr=0; |
146 | do |
||
147 | { |
||
148 | m=0; |
||
149 | b=0xff; |
||
150 | for (i=0;i<256;i++) b&=buff[adr++]; |
||
151 | if (b!=0xff) m|=0x01; |
||
152 | b=0xff; |
||
153 | for (i=0;i<256;i++) b&=buff[adr++]; |
||
154 | if (b!=0xff) m|=0x02; |
||
155 | b=0xff; |
||
156 | for (i=0;i<256;i++) b&=buff[adr++]; |
||
157 | if (b!=0xff) m|=0x04; |
||
158 | b=0xff; |
||
159 | for (i=0;i<256;i++) b&=buff[adr++]; |
||
160 | if (b!=0xff) m|=0x08; |
||
161 | b=0xff; |
||
162 | for (i=0;i<256;i++) b&=buff[adr++]; |
||
163 | if (b!=0xff) m|=0x10; |
||
164 | b=0xff; |
||
165 | for (i=0;i<256;i++) b&=buff[adr++]; |
||
166 | if (b!=0xff) m|=0x20; |
||
167 | b=0xff; |
||
168 | for (i=0;i<256;i++) b&=buff[adr++]; |
||
169 | if (b!=0xff) m|=0x40; |
||
170 | b=0xff; |
||
171 | for (i=0;i<256;i++) b&=buff[adr++]; |
||
172 | if (b!=0xff) m|=0x80; |
||
148 | ddp | 173 | dest[j++]=m; |
86 | ddp | 174 | } |
148 | ddp | 175 | while (adr<buffsize); |
176 | } |
||
86 | ddp | 177 | |
148 | ddp | 178 | //----------------------------------------------------------------------------- |
179 | |||
180 | int main(int argc,char*argv[]) |
||
181 | { |
||
182 | BYTE b, o; |
||
183 | WORD i, ih, crc; |
||
184 | struct tm stm; |
||
185 | BYTE vs[57]; //58-1 |
||
186 | WORD tabcrc[256]; |
||
187 | BYTE fbuff[0x1e000]; |
||
188 | BYTE ebuff[4096]; |
||
189 | BYTE header[0x80]; |
||
190 | LONGWORD adr; |
||
191 | FILE* f; |
||
192 | |||
193 | printf("ZX EVO project: HEX to BIN + CRC + Header\n"); |
||
253 | ddp | 194 | if (argc<5) { printf("usage: make_fw <HexFileName> <EepFileName> <OutputFileName> <VersionFileName>\n"); return 2; } |
148 | ddp | 195 | |
196 | header[0]='Z'; |
||
197 | header[1]='X'; |
||
198 | header[2]='E'; |
||
199 | header[3]='V'; |
||
200 | header[4]='O'; |
||
201 | header[5]=0x1a; |
||
202 | for (ih=0x06; ih<0x80; ih++) header[ih]=0; |
||
203 | ih=6; |
||
204 | o=0; |
||
253 | ddp | 205 | if (argc==6) |
148 | ddp | 206 | { |
253 | ddp | 207 | strncpy(s1,argv[5],1); |
148 | ddp | 208 | if (s1[0]=='o') o=0x80; |
209 | } |
||
210 | |||
253 | ddp | 211 | strncpy(s1,argv[4],255); |
148 | ddp | 212 | f=fopen(s1,"rt"); |
213 | vs[0]=0; |
||
214 | if (f) |
||
215 | { |
||
216 | fgets(vs,56,f); |
||
217 | fclose(f); |
||
218 | } |
||
192 | ddp | 219 | for (i=0; i<57; i++) |
220 | if ( (vs[i]<0x20) || (vs[i]>=0x80) ) |
||
221 | { |
||
222 | vs[i]=0; |
||
223 | break; |
||
224 | } |
||
148 | ddp | 225 | i=strlen(vs); |
253 | ddp | 226 | if (!i) strcpy(vs, "No info"); |
148 | ddp | 227 | |
228 | strcpy(&header[ih], vs); |
||
229 | ih=strlen(header); |
||
230 | |||
231 | strncpy(s1,argv[1],255); |
||
232 | printf("Open file %s... ",s1); |
||
233 | f=fopen(s1,"rt"); |
||
234 | if (!f) { printf("Can't open file\n"); return 1; } |
||
235 | printf("Read... "); |
||
236 | readhex(f,fbuff,0x1e000); |
||
237 | fclose(f); |
||
238 | printf("Close.\n"); |
||
253 | ddp | 239 | if (err) { printf("Total %u error(s)!\n",err); return 3; } |
148 | ddp | 240 | |
241 | strncpy(s1,argv[2],255); |
||
242 | printf("Open file %s... ",s1); |
||
243 | f=fopen(s1,"rt"); |
||
244 | if (!f) |
||
245 | printf("Can't open file\n"); |
||
246 | else |
||
247 | { |
||
248 | printf("Read... "); |
||
249 | readhex(f,ebuff,4096); |
||
250 | fclose(f); |
||
251 | printf("Close.\n"); |
||
253 | ddp | 252 | if (err) { printf("Total %u error(s)!\n",err); return 3; } |
148 | ddp | 253 | } |
254 | |||
255 | // comments place |
||
256 | { |
||
257 | time_t tt; |
||
258 | tt=time(NULL); |
||
259 | memcpy(&stm,localtime(&tt),sizeof(stm)); |
||
260 | } |
||
261 | i=(WORD)(((stm.tm_year-100)&0x3f)<<9) | (((stm.tm_mon+1)&0x0f)<<5) | (stm.tm_mday&0x1f); |
||
180 | chrv | 262 | header[0x003f]=fbuff[0x1dffd]=(i>>8)&0x7f|o; |
263 | header[0x003e]=fbuff[0x1dffc]=i&0xff; |
||
148 | ddp | 264 | |
265 | strncpy(&fbuff[0x1dff0], vs, 12); |
||
266 | |||
267 | for (i=0;i<256;i++) |
||
268 | { |
||
269 | crc=i<<8; |
||
270 | b=8; |
||
271 | do |
||
272 | { |
||
273 | if (crc&0x8000) |
||
274 | crc=(crc<<1)^0x1021; |
||
275 | else |
||
276 | crc<<=1; |
||
277 | b--; |
||
278 | } |
||
279 | while ((b)&&(crc)); |
||
280 | tabcrc[i]=crc; |
||
281 | } |
||
282 | |||
283 | crc=0xffff; |
||
284 | for (adr=0;adr<0x1dffe;adr++) crc=tabcrc[(crc>>8)^fbuff[adr]]^(crc<<8); |
||
285 | fbuff[0x1dffe]=crc>>8; |
||
286 | fbuff[0x1dfff]=crc&0xff; |
||
287 | |||
288 | makebitmap(fbuff,&header[0x40],0x1e000); |
||
289 | makebitmap(ebuff,&header[0x7c],4096); |
||
290 | |||
86 | ddp | 291 | crc=0x0000; |
292 | for (i=0;i<0x7e;i++) crc=tabcrc[(crc>>8)^header[i]]^(crc<<8); |
||
293 | header[0x7e]=crc>>8; |
||
294 | header[0x7f]=crc&0xff; |
||
295 | |||
253 | ddp | 296 | strncpy(target,argv[3],255); |
297 | f=fopen(target,"wb"); |
||
86 | ddp | 298 | if (!f) { printf("Can't create output file!\n"); return 1; } |
299 | fwrite(header,1,0x80,f); |
||
300 | adr=0; |
||
301 | do |
||
302 | { |
||
303 | b=0xff; |
||
148 | ddp | 304 | for (i=0;i<256;i++) b&=fbuff[adr++]; |
305 | if (b!=0xff) fwrite(&fbuff[adr-256],256,1,f); |
||
86 | ddp | 306 | } |
307 | while (adr<0x1e000); |
||
148 | ddp | 308 | adr=0; |
309 | do |
||
310 | { |
||
311 | b=0xff; |
||
312 | for (i=0;i<256;i++) b&=ebuff[adr++]; |
||
313 | if (b!=0xff) fwrite(&ebuff[adr-256],256,1,f); |
||
314 | } |
||
315 | while (adr<4096); |
||
86 | ddp | 316 | fclose(f); |
253 | ddp | 317 | printf("Created file %s\n",target); |
86 | ddp | 318 | return 0; |
319 | } |