/* * dl.c * * Convert bin.out file to Motorola S-record text file * Copyright (c) 1986 Eric D. Black * * Usage: * dl [-o oooooo] [-e eeeeee] binfile [srecfile] * where * oooooo is an offset added to to the address of every S-record * (no relocation of addresses in code is done) * eeeeee is the entry point (overrides any found in binfile) * binfile is the binary file in bin.out format * srecfile is the text file to receive S-records, stdout by default * addresses oooooo and eeeeee may be in hexadecimal (leading "0x"), * octal (leading "0"), otherwise decimal */ /* * Permission is given to distribute these files and the code they * generate, and to modify and/or extend them, providing that: * 1) All copyright notices remain intact (you may copyright your * specific changes) * 2) All source code accompanies any distribution, including any * changes and/or enhancements you may have made * 3) Any changes you make are clearly indicated * 4) No direct profit results from that distribution (i.e. you * may not sell this program or anything derived from it, but * you may include it at no charge on a system you sell for profit), * and you may give it away * */ #include #include "bin.out.h" extern char getopt(); extern char *optarg; extern int optind; extern int Enable_Abort; FILE *infile; FILE *outfile; int eflag = 0; int oflag = 0; int entrypt = 0; int offset = 0; main(argc,argv) int argc; char *argv[]; { char c; /* * Process command line using getopt(3) */ if(argc<2) { fprintf(stderr,"Usage: dl [-e xxxx] infile [outfile]\n"); exit(1); } while ((c = getopt(argc, argv, "e:o:")) != EOF) { switch(c) { case 'e': entrypt = getnum(optarg); eflag++; break; case 'o': offset = getnum(optarg); oflag++; break; default: exit(1); /* error msg is printed by getopt */ } } argv += optind; argc -= optind; /* * Get input, output file names */ if((infile=fopen(argv[0],"r"))==NULL) { /* open infile */ fprintf(stderr,"dl: Can't open %s\n",argv[0]); exit(1); } if (argc>1) { if ((outfile = fopen(argv[1],"w")) == NULL) { fprintf(stderr,"dl: Can't open %s\n",argv[1]); exit(1); } } else outfile = stdout; Enable_Abort = 1; dofile(); fclose(infile); fclose(outfile); } /* * Translate input bin.out file to ASCII S-records in output file */ #define RECSIZE 32 /* Size of Motorola S-type records */ dofile() { struct bin binhdr; int Saddr; /* * get header info */ if(fread(&binhdr, sizeof(struct bin),1,infile) != 1) { fprintf(stderr,"dl: error reading input file\n"); exit(1); } if(binhdr.b_magic != BMAGIC) { /* check magic number */ fprintf(stderr,"dl: input not proper b.out file\n"); exit(1); } /* * Entry point is: * 1) as specified on command line, or * 2) as found in input bin.out header (plus offset), or * 3) start of text segment (plus offset) */ if (!eflag) { entrypt = binhdr.b_entry ? binhdr.b_entry : binhdr.b_text; entrypt += offset; } Saddr = offset; /* * Output records for TEXT portion */ outbin(infile,Saddr,binhdr.b_text); Saddr += binhdr.b_text; /* adjust output address */ /* * Output records for DATA segment */ outbin(infile,Saddr,binhdr.b_data); Saddr += binhdr.b_data; /* adjust output address */ /* * Output entry point: as in file header, * else default to start address */ print_s_rec(7,0,0,entrypt); } int checksum; /* * print out one S record of given type */ print_s_rec(type,buffer,Dcount,addr) char *buffer; int Dcount, addr; { fprintf(outfile,"S%d",type); checksum = 0; checkout((char) Dcount+5); checkout((char) (addr>>24)); checkout((char) (addr>>16)); checkout((char) (addr>>8)); checkout((char) addr); while (Dcount--) checkout(*buffer++); puthex(~(checksum & 0XFF)); fprintf(outfile,"\n"); } /* * output byte as two hex chars, keeping running checksum */ checkout(c) char c; { checksum += c; puthex(c); } #define hex(c) c>9 ? c+0X37 : c+0X30 /* macro for hex convert */ /* * print byte as two hex chars */ puthex(b) char b; { char c1,c2; c1=(b>>4) & 0XF; c2=b & 0XF; c1=hex(c1); c2=hex(c2); fprintf(outfile,"%c%c",c1,c2); } /* * put out records from a buffer, using addr as starting S-record * address, for size bytes */ outbuf(buffer,addr,size) char *buffer; int addr, size; { int count, /* counts total number of bytes processed*/ Dcount; /* number of bytes in current record */ for(count=0; count