/* ** fp880718/010413 convert sxf, fpc, dmp & hex to binary file */ #include #include #include #include #define LINLEN 544 /* number of bytes per line */ #define S1F 1 #define S2F 2 #define S3F 3 #define FPC 4 #define DMP 5 #define HEX 6 /* fpc type defs */ #define ABS 0 #define DAT 1 #define REL 2 #define HDR 3 #define REP 4 unsigned long check, length, address, code, lincnt; unsigned long msize, data; unsigned long begadr, endadr, count, total; unsigned long hex20, hex32; FILE *ifp, *ofp; char buf[LINLEN + 1]; unsigned char header[257]; /* ** check file name extension ** return value 0 if error */ int ckext(char *fname) { int p; if((p=strlen(fname)-4)<0) return(0); if(strcmpi(&fname[p], ".s1f")==0) return(S1F); if(strcmpi(&fname[p], ".s2f")==0) return(S2F); if(strcmpi(&fname[p], ".s3f")==0) return(S3F); if(strcmpi(&fname[p], ".fpc")==0) return(FPC); if(strcmpi(&fname[p], ".dmp")==0) return(DMP); if(strcmpi(&fname[p], ".hex")==0) return(HEX); return(0); } unsigned long gethex(char *p, int n) { unsigned long h = 0; int i = 0; char c; while((n==0)||(i'*') c=(c-'%')-1; else c=c-'%'; v*=85L; v+=(long)c; } return(v); } void quit(int e, char *p) { switch(e) { case 0 : fprintf(stderr, "ready\n"); break; case 1 : fprintf(stderr, "Usage: load infile outfile {options}\n"); fprintf(stderr, "Infile format depends on the file extension.\n"); fprintf(stderr, ".S1F Motorola S1/S9 format (16-bit addresses)\n"); fprintf(stderr, ".S2F Motorola S2/S8 format (24-bit addresses)\n"); fprintf(stderr, ".S3F Motorola S3/S7 format (32-bit addresses)\n"); fprintf(stderr, ".FPC Four Packed Code (32-bit addresses)\n"); fprintf(stderr, ".DMP dump in hex(and ascii)(32-bit addresses)\n"); fprintf(stderr, ".HEX intel format (16/32-bit addresses)\n"); fprintf(stderr, "Outfile is any binary file.\n"); fprintf(stderr, "Fill option: -f fillbyte\n"); fprintf(stderr, "Check double option: -c\n"); fprintf(stderr, "Extra pass for checking double used locations\n"); fprintf(stderr, "Extend low address option: -l addressvalue\n"); fprintf(stderr, "Extend high address option: -h addressvalue\n"); fprintf(stderr, "Highest is first unused address\n"); fprintf(stderr, "Values are in hex.\n"); break; case 2 : fprintf(stderr, "invalid infile extension\n"); break; case 3 : fprintf(stderr, "can't open infile %s\n", p); break; case 4 : fprintf(stderr, "can't open outfile %s\n", p); break; case 5 : fprintf(stderr, "not enough memory\n"); break; case 6 : fprintf(stderr, "checksum error in line: %lu\n", lincnt); break; case 7 : fprintf(stderr, "release memory error\n"); break; case 8 : fprintf(stderr, "no valid bytes encountered\n"); break; case 9 : fprintf(stderr, "invalid outfile extension\n"); break; case 10 : fprintf(stderr, "unknown option %s\n", p); break; case 11 : fprintf(stderr, "can't write outfile %s\n", p); break; default : fprintf(stderr, "program aborted : error=%d - %s\n", e, p); break; } exit(e); } void main (int argc, char *argv[]) { unsigned char fill=0x00; unsigned char * mp=NULL; int pass, i, j, mode, next, chkd; unsigned long u; chkd=0; begadr=0L; endadr=0L; count=0L; fprintf(stdout, "NFeRTARI load 010413\n"); if(argc<3) quit(1, ""); if((ckext(argv[2]))!=0) quit(9, ""); if((mode = ckext(argv[1]))==0) quit(2, ""); next=3; while(next2) { for(i=0; i5) { length-=5; count+=length; address=gethex(buf+4, 8); if(begadr==endadr) { begadr=address; endadr=address+length; } else { if(begadr>address) begadr=address; if(endadr5) { length-=5; address=gethex(buf+4, 8); for(i=0; i5) { length-=5; address=gethex(buf+4, 8); for(i=0; i4) { length-=4; count+=length; address=gethex(buf+4, 6); if(begadr==endadr) { begadr=address; endadr=address+length; } else { if(begadr>address) begadr=address; if(endadr4) { length-=4; address=gethex(buf+4, 6); for(i=0; i4) { length-=4; address=gethex(buf+4, 6); for(i=0; i3) { length-=3; count+=length; address=gethex(buf+4, 4); if(begadr==endadr) { begadr=address; endadr=address+length; } else { if(begadr>address) begadr=address; if(endadr3) { length-=3; address=gethex(buf+4, 4); for(i=0; i3) { length-=3; address=gethex(buf+4, 4); for(i=0; i>16)&255L; check=(check>>24)&255L; switch(code) { case ABS : case REL : if(length>=4) { if(code==ABS) address=getqfpc(buf+6); else address+=getqfpc(buf+6); if(pass==0) { count+=(length-4); if(begadr==endadr) { begadr=address; endadr=address+length-4; } else { if(begadr>address) begadr=address; if(endadr>8); check+=address+(address>>8)+(address>>16)+(address>>24); } i=0; for(j=0; j<=(length-1)/4; j++) { data=getqfpc(buf+11+j*5); do { if(i<(length-4)) switch(pass) { case 0 : check+=data>>(((255-i)%4)*8); break; case 1 : *(mp+i+address-begadr)+=1; break; case 2 : *(mp+i+address-begadr)=data>>(((255-i)%4)*8); break; } i++; } while((i%4)!=0); } if(pass==0) if(check&255) quit(6, buf); address+=(length-4); } break; case DAT : if(pass==0) { count+=(length); if(begadr==endadr) { begadr=address; endadr=address+length; } else { if(begadr>address) begadr=address; if(endadr>8); } i=0; for(j=0; j<=(length)/4; j++) { data=getqfpc(buf+6+j*5); do { if(i>(((255-i)%4)*8); break; case 1 : *(mp+i+address-begadr)+=1; break; case 2 : *(mp+i+address-begadr)=data>>(((255-i)%4)*8); break; } i++; } while((i%4)!=0); } if(pass==0) if(check&255) quit(6, buf); address+=(length); break; case REP : if(length==4) { data=getqfpc(buf+6); j=(int)(data>>16)&255; if(pass==0) { count+=(j); if(begadr==endadr) { begadr=address; endadr=address+j; } else { if(begadr>address) begadr=address; if(endadr>8); check+=data+(data>>8)+(data>>16)+(data>>24); if(check&255) quit(6, buf); } else { for(i=0; i2)) break; i=j; while(isxdigit(toascii(buf[j]))) j++; if((j-i)<1) break; switch(pass) { case 1 : *(mp+length+address-begadr)+=1; break; case 2 : *(mp+length+address-begadr)=gethex(buf+i, 0); break; default : break; } length++; } if(pass==0) { count+=length; if(begadr==endadr) { begadr=address; endadr=address+length; } else { if(begadr>address) begadr=address; if(endadraddress) begadr=address; if(endadr1) fprintf(stdout, "double at : %8lX\n", begadr+u); } for(u=0; u<(total); u++) mp[u]=fill; pass+=1; break; case 2 : check=0L; for(u=0; u<(total); u++) check+=(unsigned long)mp[u]; fprintf(stdout, "checksum : %8lX\n", check); pass+=1; break; } } /* write output file */ if ((ofp = fopen (argv[2], "wb"))==NULL) quit(4, argv[2]); if(fwrite(mp, 1, total, ofp)!=total) quit(11, argv[2]); /* u=0L; while(total) { if(total<32768L) { if(fwrite((void *)&mp[u], 1, (unsigned int)total, ofp)!=(unsigned int)total) quit(11, argv[2]); total=0L; } else { if(fwrite((void *)&mp[u], 1, 32768, ofp)!=32768) quit(11, argv[2]); total-=32768L; u+=32768L; } } */ fclose(ofp); free(mp); quit(0, ""); }