rjlhex.c 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235
  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. #include <stdio.h>
  20. #include <stdlib.h>
  21. #include <string.h>
  22. #include <ctype.h>
  23. #include "rjlhex.h"
  24. /*
  25. * hex_open: Create a hex_file from a FILE *
  26. *
  27. * f is assumed to already be open for reading, with the
  28. * pointer at the start of the file.
  29. */
  30. hex_file *hex_open(FILE *f)
  31. {
  32. hex_file *r;
  33. if(f==NULL) {
  34. return NULL;
  35. }
  36. r=malloc(sizeof(hex_file));
  37. if(r == NULL) {
  38. return NULL;
  39. }
  40. r->f=f;
  41. r->addr=0;
  42. return r;
  43. }
  44. /*
  45. * hex_raw_read: Create a hex_record from the next line of f
  46. *
  47. * f is assumed to already be open for reading, with the
  48. * pointer at the start of the line to parse.
  49. */
  50. hex_record *hex_raw_read(FILE *f)
  51. {
  52. hex_record *r;
  53. hex_record *tempr;
  54. char *s=NULL;
  55. size_t ssize=0;
  56. char temps[10];
  57. int i;
  58. unsigned char check=0;
  59. if(f == NULL) {
  60. return NULL;
  61. }
  62. r=malloc(sizeof(hex_record));
  63. if(r == NULL) {
  64. return NULL;
  65. }
  66. getline(&s, &ssize, f);
  67. // :llaaaatt[dd...]cc
  68. // :
  69. if(strlen(s)<1 || s[0] != ':') {
  70. free(r);
  71. free(s);
  72. return NULL;
  73. }
  74. // ll
  75. if(strlen(s)<3 || !isxdigit(s[1]) || !isxdigit(s[2])) {
  76. free(r);
  77. free(s);
  78. return NULL;
  79. }
  80. sprintf(temps, "0x%c%c", s[1], s[2]);
  81. r->datlen=strtol(temps, NULL, 16);
  82. check += r->datlen;
  83. if(strlen(s) < r->datlen*2 + 11) {
  84. free(r);
  85. free(s);
  86. return NULL;
  87. }
  88. for(i=3;i<r->datlen*2+11;i++) {
  89. if(!isxdigit(s[i])) {
  90. free(r);
  91. free(s);
  92. return NULL;
  93. }
  94. }
  95. tempr=realloc(r, sizeof(hex_record) + r->datlen*2);
  96. if(tempr == NULL) {
  97. free(r);
  98. free(s);
  99. return NULL;
  100. }
  101. r=tempr;
  102. // aaaa
  103. sprintf(temps, "0x%c%c%c%c", s[3], s[4], s[5], s[6]);
  104. r->addr=strtol(temps, NULL, 16);
  105. sprintf(temps, "0x%c%c", s[3], s[4]);
  106. check+=strtol(temps, NULL, 16);
  107. sprintf(temps, "0x%c%c", s[5], s[6]);
  108. check+=strtol(temps, NULL, 16);
  109. // tt
  110. sprintf(temps, "0x%c%c", s[7], s[8]);
  111. r->type=strtol(temps, NULL, 16);
  112. check += r->type;
  113. // [dd...]
  114. for(i=0;i<r->datlen;i++) {
  115. sprintf(temps, "0x%c%c", s[9+2*i], s[10+2*i]);
  116. r->data[i]=strtol(temps, NULL, 16);
  117. check+=r->data[i];
  118. }
  119. // cc
  120. sprintf(temps, "0x%c%c", s[r->datlen*2+9], s[r->datlen*2+10]);
  121. r->checksum=strtol(temps, NULL, 16);
  122. // printf("check is %x, 2c of check is %x\n", check, (unsigned char)(-((int)check)));
  123. // printf("checksum wanted is %x\n", r->checksum);
  124. free(s);
  125. if((unsigned char)(-((int)check)) != r->checksum) {
  126. printf("hex_raw_read(): BAD CHECKSUM: got %x, wanted %x\n",
  127. (unsigned char)(-((int)check)), r->checksum);
  128. free(r);
  129. return NULL;
  130. }
  131. return r;
  132. }
  133. /*
  134. * hex_read: Return the next hex_record from f
  135. */
  136. hex_record *hex_read(hex_file *f)
  137. {
  138. hex_record *r;
  139. if(f == NULL) {
  140. return NULL;
  141. }
  142. r=hex_raw_read(f->f);
  143. if(r == NULL) {
  144. return NULL;
  145. }
  146. switch(r->type) {
  147. case 0: // data
  148. r->addr += f->addr;
  149. break;
  150. case 1: // EOF
  151. /*
  152. * Do nothing, although something could be done on these
  153. *
  154. * It'll only get more data past this on a funny file,
  155. * and the assumption is that user-supplied files are usually ok
  156. * (which may not be a good assumption)
  157. */
  158. break;
  159. case 2: // hex86 address
  160. f->addr = (r->data[0] << 12) + (r->data[1] << 4); // endianness?
  161. break;
  162. case 4: // hex386 address
  163. f->addr = (r->data[0] << 24) + (r->data[1] << 16); // endianness?
  164. break;
  165. }
  166. return r;
  167. }