tools/fsusb/rjlhex.c
changeset 2 2f55e5dd591d
equal deleted inserted replaced
1:f08135942074 2:2f55e5dd591d
       
     1 /*
       
     2 ** This file is part of fsusb_picdem
       
     3 **
       
     4 ** fsusb_picdem is free software; you can redistribute it and/or
       
     5 ** modify it under the terms of the GNU General Public License as
       
     6 ** published by the Free Software Foundation; either version 2 of the
       
     7 ** License, or (at your option) any later version.
       
     8 **
       
     9 ** fsusb_picdem is distributed in the hope that it will be useful, but
       
    10 ** WITHOUT ANY WARRANTY; without even the implied warranty of
       
    11 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
       
    12 ** General Public License for more details.
       
    13 **
       
    14 ** You should have received a copy of the GNU General Public License
       
    15 ** along with fsusb_picdem; if not, write to the Free Software
       
    16 ** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
       
    17 ** 02110-1301, USA
       
    18 */
       
    19 
       
    20 
       
    21 #include <stdio.h>
       
    22 #include <stdlib.h>
       
    23 #include <string.h>
       
    24 #include <ctype.h>
       
    25 #include "rjlhex.h"
       
    26 
       
    27 
       
    28 
       
    29 /*
       
    30  * hex_open: Create a hex_file from a FILE *
       
    31  *
       
    32  * f is assumed to already be open for reading, with the
       
    33  *  pointer at the start of the file.
       
    34  */
       
    35 hex_file *hex_open(FILE *f)
       
    36 {
       
    37   hex_file *r;
       
    38 
       
    39   if(f==NULL) {
       
    40     return NULL;
       
    41   }
       
    42 
       
    43   r=malloc(sizeof(hex_file));
       
    44   if(r == NULL) {
       
    45     return NULL;
       
    46   }
       
    47 
       
    48   r->f=f;
       
    49   r->addr=0;
       
    50   return r;
       
    51 }
       
    52 
       
    53 
       
    54 /*
       
    55  * hex_raw_read: Create a hex_record from the next line of f
       
    56  *
       
    57  * f is assumed to already be open for reading, with the
       
    58  *  pointer at the start of the line to parse.
       
    59  */
       
    60 hex_record *hex_raw_read(FILE *f)
       
    61 {
       
    62   hex_record *r;
       
    63   hex_record *tempr;
       
    64   char *s=NULL;
       
    65   size_t ssize=0;
       
    66   char temps[10];
       
    67   int i;
       
    68   unsigned char check=0;
       
    69 
       
    70 
       
    71 
       
    72   if(f == NULL) {
       
    73     return NULL;
       
    74   }
       
    75 
       
    76   r=malloc(sizeof(hex_record));
       
    77   if(r == NULL) {
       
    78     return NULL;
       
    79   }
       
    80 
       
    81 
       
    82 
       
    83   getline(&s, &ssize, f);
       
    84 
       
    85   // :llaaaatt[dd...]cc
       
    86 
       
    87   // :
       
    88   if(strlen(s)<1 || s[0] != ':') {
       
    89     free(r);
       
    90     free(s);
       
    91     return NULL;
       
    92   }
       
    93 
       
    94 
       
    95 
       
    96   // ll
       
    97   if(strlen(s)<3 || !isxdigit(s[1]) || !isxdigit(s[2])) {
       
    98     free(r);
       
    99     free(s);
       
   100     return NULL;
       
   101   }
       
   102   sprintf(temps, "0x%c%c", s[1], s[2]);
       
   103   r->datlen=strtol(temps, NULL, 16);
       
   104   check += r->datlen;
       
   105 
       
   106 
       
   107 
       
   108   if(strlen(s) < r->datlen*2 + 11) {
       
   109     free(r);
       
   110     free(s);
       
   111     return NULL;
       
   112   }
       
   113 
       
   114   for(i=3;i<r->datlen*2+11;i++) {
       
   115     if(!isxdigit(s[i])) {
       
   116       free(r);
       
   117       free(s);
       
   118       return NULL;
       
   119     }
       
   120   }
       
   121   tempr=realloc(r, sizeof(hex_record) + r->datlen*2);
       
   122   if(tempr == NULL) {
       
   123     free(r);
       
   124     free(s);
       
   125     return NULL;
       
   126   }
       
   127   r=tempr;
       
   128 
       
   129 
       
   130 
       
   131   // aaaa
       
   132 
       
   133   sprintf(temps, "0x%c%c%c%c", s[3], s[4], s[5], s[6]);
       
   134   r->addr=strtol(temps, NULL, 16);
       
   135 
       
   136   sprintf(temps, "0x%c%c", s[3], s[4]);
       
   137   check+=strtol(temps, NULL, 16);
       
   138   sprintf(temps, "0x%c%c", s[5], s[6]);
       
   139   check+=strtol(temps, NULL, 16);
       
   140 
       
   141 
       
   142 
       
   143   // tt
       
   144 
       
   145   sprintf(temps, "0x%c%c", s[7], s[8]);
       
   146   r->type=strtol(temps, NULL, 16);
       
   147   check += r->type;
       
   148 
       
   149 
       
   150 
       
   151   // [dd...]
       
   152 
       
   153   for(i=0;i<r->datlen;i++) {
       
   154     sprintf(temps, "0x%c%c", s[9+2*i], s[10+2*i]);
       
   155     r->data[i]=strtol(temps, NULL, 16);
       
   156     check+=r->data[i];
       
   157   }
       
   158 
       
   159 
       
   160 
       
   161   // cc
       
   162   sprintf(temps, "0x%c%c", s[r->datlen*2+9], s[r->datlen*2+10]);
       
   163   r->checksum=strtol(temps, NULL, 16);
       
   164 
       
   165   //  printf("check is %x, 2c of check is %x\n", check, (unsigned char)(-((int)check)));
       
   166   //  printf("checksum wanted is %x\n", r->checksum);
       
   167 
       
   168   free(s);
       
   169 
       
   170   if((unsigned char)(-((int)check)) != r->checksum) {
       
   171     printf("hex_raw_read(): BAD CHECKSUM: got %x, wanted %x\n",
       
   172            (unsigned char)(-((int)check)), r->checksum);
       
   173     free(r);
       
   174     return NULL;
       
   175   }
       
   176 
       
   177   return r;
       
   178 
       
   179 }
       
   180 
       
   181 
       
   182 /*
       
   183  * hex_read: Return the next hex_record from f
       
   184  */
       
   185 hex_record *hex_read(hex_file *f)
       
   186 {
       
   187   hex_record *r;
       
   188 
       
   189 
       
   190 
       
   191   if(f == NULL) {
       
   192     return NULL;
       
   193   }
       
   194 
       
   195 
       
   196 
       
   197   r=hex_raw_read(f->f);
       
   198   if(r == NULL) {
       
   199     return NULL;
       
   200   }
       
   201 
       
   202 
       
   203 
       
   204   switch(r->type) {
       
   205   case 0: // data
       
   206     r->addr += f->addr;
       
   207     break;
       
   208 
       
   209 
       
   210   case 1: // EOF
       
   211     /*
       
   212      * Do nothing, although something could be done on these
       
   213      *
       
   214      * It'll only get more data past this on a funny file,
       
   215      *  and the assumption is that user-supplied files are usually ok
       
   216      *  (which may not be a good assumption)
       
   217      */
       
   218     break;
       
   219 
       
   220 
       
   221   case 2: // hex86 address
       
   222     f->addr = (r->data[0] << 12) + (r->data[1] << 4); // endianness?
       
   223     break;
       
   224 
       
   225 
       
   226   case 4: // hex386 address
       
   227     f->addr = (r->data[0] << 24) + (r->data[1] << 16); // endianness?
       
   228     break;
       
   229   }
       
   230 
       
   231 
       
   232 
       
   233   return r;
       
   234 }