home *** CD-ROM | disk | FTP | other *** search
/ The C Users' Group Library 1994 August / wc-cdrom-cusersgrouplibrary-1994-08.iso / vol_100 / 149_01 / hextos.c < prev    next >
Text File  |  1989-01-13  |  5KB  |  219 lines

  1. /*
  2.     HEADER:        CUG149;
  3.     TITLE:        Intel Hex to Motorola S-Record Converter;
  4.     FILENAME:    HEXTOS.C;
  5.     VERSION:    0.1;
  6.     DATE:        08/08/1985;
  7.  
  8.     DESCRIPTION:    "This program converts the Intel hex object files from
  9.             the 6801 cross-assembler to Motorola S-record object
  10.             files that can be read my Motorola's monitors and
  11.             program loaders.";
  12.  
  13.     KEYWORDS:    Software Development, Utilities, Motorola, Hex Files;
  14.  
  15.     SYSTEM:        CP/M-80, HP-UX, MSDOS, PCDOS;
  16.     COMPILERS:    AZTEC C II, Eco-C, HP-UX, Microsoft C;
  17.  
  18.     WARNINGS:    "Since this program has been compiled on a UNIX look-
  19.             alike (HP-UX), portability to UNIX should be trivial.
  20.             Since it has compiled on three full-featured compilers,
  21.             portability to MSDOS should be easy.";
  22.  
  23.     AUTHORS:    William C. Colley III;
  24. */
  25.  
  26. /*
  27.         Intel Hex to Motorola S-Record Converter
  28.  
  29.         Copyright (c) 1985 William C. Colley, III
  30.  
  31. In dealing with Motorola processors, one is dealing with two object file
  32. formats.  Most EPROM programmers, CP/M-based software, etc. uses the Intel
  33. hexadecimal object format, so that is what my cross-assemblers produce.
  34. Motorola's loaders almost all use a different format called the Motorola
  35. S-record format.  This utility converts an Intel hex file to Motorola S-record
  36. format.  The command line looks like this:
  37.  
  38.     hextoc input_file output_file
  39.  
  40. Compilation, assembly, and linkage instructions for various compilers:
  41.  
  42.     A)  AZTEC C II (version 1.06B):
  43.  
  44.         1)  Comment out all compiler names below except "AZTEC_C_II".
  45.  
  46.         2)  Run the following command lines:
  47.  
  48.             A>cc hextos
  49.             A>as hextos -zap
  50.             A>ln hextos.o -lc
  51.             A>era hextos.o
  52.  
  53.     B)  Eco-C (version 3.10):
  54.  
  55.         1)  Comment out all compiler names below except "ECO_C".
  56.  
  57.         2)  Run the following command lines:
  58.  
  59.             A>cp hextos -i -m
  60.             A>l80 hextos,hextos/n/e
  61.             A>era hextos.mac
  62.             A>era hextos.rel
  63.  
  64.     C)  HP-UX (a UNIX look-alike on an HP 9000 Series 200/500, 68000-based
  65.         machine):
  66.  
  67.         1)  Comment out all compiler names below except "HP_UX".
  68.  
  69.         2)  Run the following command line:
  70.  
  71.             . cc hextos.c
  72.  
  73.     D)  Microsoft C (version 3.00):
  74.  
  75.         1)  Comment out all compiler names below except "MICROSOFT_C".
  76.  
  77.         2)  Run the following command line:
  78.  
  79.             C>cl a68.c a68eval.c a68util.c
  80. */
  81.  
  82. /* Compiler dependencies:                        */
  83.  
  84. #define        AZTEC_C_II        1
  85. /* #define    ECO_C            1                */
  86. /* #define    HP_UX            1                */
  87. /* #define    MICROSOFT_C        1                */
  88.  
  89. #ifdef    AZTEC_C_II
  90.  
  91. #define    getc(f)        agetc(f)
  92. #define    putc(c,f)    aputc(c,f)
  93.  
  94. #endif
  95.  
  96. #include <stdio.h>
  97.  
  98. /* Warning and Error messages:                        */
  99.  
  100. #define    BADEOF        "Unexpected EOF on Intel hex file"
  101. #define    BADREC        "Bad record in Intel hex file"
  102. #define    DSKFULL        "Disk or directory full"
  103. #define    HEXOPEN        "Could not open Intel hex file"
  104. #define    SCREATE        "Could not create S-record file"
  105. #define    USAGE        "Usage:  hextos infile outfile"
  106.  
  107. #define    START        0
  108. #define    DATA        1
  109. #define    END        9
  110.  
  111. static unsigned sum;
  112. static unsigned hdr[] = { 'H', 'D', 'R', '9' };
  113.  
  114. #define    HDRSIZ        (sizeof(hdr) / sizeof(unsigned))
  115.  
  116. static FILE *ihex = NULL;
  117. static FILE *srec = NULL;
  118.  
  119. main(argc,argv)
  120. int argc;
  121. char **argv;
  122. {
  123.     static char c;
  124.     static unsigned addr, *bp, buf[256], cnt, getb(), siz;
  125.     void error(), putr(), scan();
  126.  
  127.     puts("Intel Hex to Motorola S-Record Converter Ver 0.1");
  128.     puts("Copyright (c) 1985 William C. Colley, III\n");
  129.  
  130.     if (argc != 3) error(USAGE);
  131.     if (!(ihex = fopen(*++argv,"r"))) error(HEXOPEN);
  132.     if (!(srec = fopen(*++argv,"w"))) error(SCREATE);
  133.  
  134.     putr(START,HDRSIZ,0,hdr);
  135.  
  136.     for (;;) {
  137.     sum = 0;  scan(':');
  138.     cnt = getb();  addr = getb();  addr = (addr << 8) + getb();
  139.     switch (getb()) {
  140.         case 0:    for (bp = buf; bp <= buf + cnt; *bp++ = getb());
  141.             if (sum & 0xff) error(BADREC);
  142.             for (bp = buf; siz = cnt > 30 ? 30 : cnt; cnt -= siz) {
  143.                 putr(DATA,siz,addr,bp);  addr += siz;  bp += siz;
  144.             }
  145.             break;
  146.  
  147.         case 1:    getb();  fclose(ihex);
  148.             if (cnt || (sum & 0xff)) error(BADREC);
  149.             putr(END,0,addr,NULL);
  150.             if (fclose(srec) == EOF) error(DSKFULL);
  151.             puts("File successfully converted");
  152.             return;
  153.  
  154.         default:    error(BADREC);
  155.     }
  156.     }
  157. }
  158.  
  159. static void scan(c)
  160. char c;
  161. {
  162.     static char d;
  163.     void error();
  164.  
  165.     while ((d = getc(ihex)) != EOF) if ((d & 0177) == c) return;
  166.     error(BADEOF);
  167. }
  168.  
  169. static unsigned getb()
  170. {
  171.     static unsigned getn(), u;
  172.  
  173.     u = getn();
  174.     sum += (u = (u << 4) + getn());
  175.     return u;
  176. }
  177.  
  178. static unsigned getn()
  179. {
  180.     static char c;
  181.     void error();
  182.  
  183.     if ((c = getc(ihex)) == EOF) error(BADEOF);
  184.     if ((c = toupper(c & 0177)) >= '0' && c <= '9') return c - '0';
  185.     if (c >= 'A' && c <= 'F') return c - ('A' - 10);
  186.     error(BADREC);
  187. }
  188.  
  189. static char digit[] = "0123456789ABCDEF";
  190.  
  191. static void putr(typ,cnt,adr,dat)
  192. unsigned typ,cnt,adr;
  193. unsigned *dat;
  194. {
  195.     void error(), putb();
  196.  
  197.     putc('S',srec);  putc(digit[typ],srec);
  198.     sum = 0;  putb(cnt + 3);
  199.     putb(adr >> 8);  putb(adr & 0xff);
  200.     while (cnt--) putb(*dat++);
  201.     putb(~sum & 0xff);  putc('\n',srec);
  202.     if (ferror(srec)) error(DSKFULL);
  203. }
  204.  
  205. static void putb(b)
  206. unsigned b;
  207. {
  208.     sum += b;
  209.     putc(digit[b >> 4],srec);
  210.     putc(digit[b & 0x0f],srec);
  211. }
  212.  
  213. static void error(msg)
  214. char *msg;
  215. {
  216.     printf("Error -- %s\n",msg);
  217.     exit(EOF);
  218. }
  219.