#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
typedef unsigned char BYTE;
typedef unsigned short WORD;
typedef unsigned long LONGWORD;
#define HEXLEN 0
#define DATATYPE 1
#define CHECKSUM 2
BYTE checksum;
WORD col, row;
LONGWORD err;
BYTE s[256], s1[256];
//-----------------------------------------------------------------------------
void print_err_rc()
{
printf("Error! (Row %d, Col %d)\n",row
,col
+1);
err++;
}
//-----------------------------------------------------------------------------
void print_err_r(BYTE cause)
{
BYTE* cause_str[3]={"Number of byte","Unknown datatype","Checksum"};
printf("Error! %s. (Row %d)\n",cause_str
[cause
],row
);
err++;
}
//-----------------------------------------------------------------------------
BYTE getbyte()
{
BYTE b1, b0;
b1=s[col];
if ( ( (b1>=0x30)&&(b1<=0x39) )||( (b1>=0x41)&&(b1<=0x46) ) )
{
b1-=0x30;
if (b1>9) b1-=7;
}
else
{
print_err_rc();
b1=0;
}
col++;
b0=s[col];
if ( ( (b0>=0x30)&&(b0<=0x39) )||( (b0>=0x41)&&(b0<=0x46) ) )
{
b0-=0x30;
if (b0>9) b0-=7;
}
else
{
print_err_rc();
b0=0;
}
col++;
b0|=(b1<<4);
checksum+=b0;
return b0;
}
//-----------------------------------------------------------------------------
int main(int argc,char*argv[])
{
BYTE h[]="0123456789ABCDEF";
BYTE b, m, o, hexlen, datatype;
WORD i, crc;
LONGWORD x0, x1, adr, segadr;
struct tm stm;
BYTE vs[86];
BYTE E2Phead[0x98] = {
0x45,0x32,0x50,0x21,0x4C,0x61,0x6E,0x63,0xC0,0x10,0x30,0x00,0x03,0x00,0x00,0x10,
0x02,0x00,0x00,0x77,0x00,0x00,0x00,0x02,0x00,0x00,0x41,0x54,0x6D,0x65,0x67,0x61,
0x31,0x32,0x38 };
WORD tabcrc[256];
BYTE buff[0x2000];
FILE* f;
o=0;
printf("ZX EVO project: Calc CRC for bootloader\n");
if (argc
<3) { printf("usage: crcbldr <HexFileName> [<VersionFileName>]\n"); return 2; }
for (adr=0;adr<0x2000;adr++) buff[adr]=0xff;
if (argc==4)
{
if (s1[0]=='o') o=0x80;
}
vs[0]=0;
if (f)
{
}
if ((i) && (vs[i-1]=='\n')) vs[--i]=0;
if (!i)
{
o=0;
}
if (!f
) { printf("Can't open file %s!\n",s1
); return 1; }
err=0;
segadr=0;
row=0;
{
row++;
col=0;
{
if (s[col]!=':') print_err_rc();
col++;
checksum=0;
hexlen=getbyte();
x1=getbyte();
x0=getbyte();
adr=segadr|(x1<<8)|x0;
datatype=getbyte();
switch (datatype)
{
// Data record
case 0: while (hexlen>0)
{
b=getbyte();
hexlen--;
if ( (adr>=0x1e000) && (adr<0x20000) ) buff[adr-0x1e000]=b;
adr++;
}
break;
// End of file record
case 1: if (hexlen!=0) print_err_r(HEXLEN);
break;
// Extended segment address record
case 2: x1=getbyte();
x0=getbyte();
segadr=(x1<<12)|(x0<<4);
if (hexlen!=2) print_err_r(HEXLEN);
break;
// Start segment address record
case 3: break;
// Extended linear address record
case 4: x1=getbyte();
x0=getbyte();
segadr=(x1<<24)|(x0<<16);
if (hexlen!=2) print_err_r(HEXLEN);
break;
// Start linear address record
case 5: break;
default: print_err_r(DATATYPE);
while (hexlen!=0) { getbyte(); hexlen--; }
}
getbyte();
if (checksum!=0) print_err_r(CHECKSUM);
}
}
if (err
) { printf("Total %d error(s)!\n",(int)err
); return 3; }
for (i=0;i<256;i++)
{
crc=i<<8;
b=8;
do
{
if (crc&0x8000)
crc=(crc<<1)^0x1021;
else
crc<<=1;
b--;
}
while ((b)&&(crc));
tabcrc[i]=crc;
}
{
time_t tt;
}
i=(WORD)( (((stm.tm_year-100)&0x3f)<<9) | (((stm.tm_mon+1)&0x0f)<<5) | (stm.tm_mday&0x1f) );
buff[0x1ffd]=(i>>8)&0x7f|o;
buff[0x1ffc]=i&0xff;
crc=0xffff;
for (adr=0;adr<0x1ffe;adr++) crc=tabcrc[(crc>>8)^buff[adr]]^(crc<<8);
buff[0x1ffe]=crc>>8;
buff[0x1fff]=crc&0xff;
// - - - - - - - -
f
=fopen("zxevo_bl.hex","wt");
if (!f
) { printf("Can't create output file!\n"); return 1; }
fputs(":020000020000FC\n:01000000FF00\n:020000021000EC\n",f
);
s[0]=':';
s[1]='1';
s[2]='0';
adr=0;
do
{
checksum=0xf0;
m=3;
b=((adr>>8)&0xff)+0xe0;
checksum-=b;
s[m++]=h[b>>4];
s[m++]=h[b&0x0f];
b=adr&0xff;
checksum-=b;
s[m++]=h[b>>4];
s[m++]=h[b&0x0f];
s[m++]='0';
s[m++]='0';
for (i=0;i<16;i++)
{
b=buff[adr++];
checksum-=b;
s[m++]=h[b>>4];
s[m++]=h[b&0x0f];
}
s[m++]=h[checksum>>4];
s[m++]=h[checksum&0x0f];
s[m++]='\n';
s[m]=0;
}
while (adr<0x2000);
fputs(":00000001FF\n",f
);
printf("Created file zxevo_bl.hex\n");
// - - - - - - - -
for (i=0;i<256;i++)
{
crc=i;
b=8;
do
{
if (crc&0x0001)
crc=(crc>>1)^0xa001;
else
crc>>=1;
b--;
}
while ((b)&&(crc));
tabcrc[i]=crc;
}
vs[i++]=' ';
b=stm.tm_mday&0x1f;
vs[i++]=h[b/10];
vs[i++]=h[b%10];
vs[i++]='.';
b=stm.tm_mon+1;
vs[i++]=h[b/10];
vs[i++]=h[b%10];
vs[i++]='.';
vs[i++]='2';
vs[i++]='0';
b=stm.tm_year-100;
vs[i++]=h[b/10];
vs[i++]=h[b%10];
vs[i]=0;
if (!o
) strcpy(&vs
[i
]," beta");
E2Phead[0x90]=0x02;
E2Phead[0x91]=0x00;
crc=0xd001; // precalculated for empty space before
for (adr=0;adr<0x2000;adr++) crc=tabcrc[(crc&0xff)^buff[adr]]^(crc>>8);
for (adr=0;adr<0x1000;adr++) crc=tabcrc[(~crc)&0xff]^(crc>>8); // postcalculating for empty space after
E2Phead[0x94]=crc&0xff;
E2Phead[0x95]=crc>>8;
crc=0;
for (adr=0;adr<0x96;adr++) crc=tabcrc[(crc&0xff)^E2Phead[adr]]^(crc>>8);
E2Phead[0x96]=crc&0xff;
E2Phead[0x97]=crc>>8;
f
=fopen("zxevo_bl.e2p","wb");
if (!f
) { printf("Can't create output file!\n"); return 1; }
for (adr=0;adr<256;adr++) s1[adr]=0xff;
for (adr
=0;adr
<0x1e0;adr
++) fwrite(s1
,1,256,f
);
for (adr
=0;adr
<0x10;adr
++) fwrite(s1
,1,256,f
);
printf("Created file zxevo_bl.e2p\n");
return 0;
}