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 | } |