ttchecksum.c 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203
  1. /******************************************************************************
  2. *
  3. * project name: TI-68k Developer Utilities
  4. * file name: ttchecksum.c
  5. * initial date: 21/08/2000
  6. * author: thomas.nussbaumer@gmx.net
  7. * description: corrects checksum of .89s/.89y/.9xs/9xy files
  8. *
  9. ******************************************************************************/
  10. /*
  11. This file is part of TI-68k Developer Utilities.
  12. This file is free software; you can redistribute it and/or
  13. modify it under the terms of the GNU Lesser General Public
  14. License as published by the Free Software Foundation; either
  15. version 2.1 of the License, or (at your option) any later version.
  16. As a special exception, UNMODIFIED copies of ttchecksum may also be
  17. redistributed or sold without source code, for any purpose. (The Lesser
  18. General Public License restrictions do apply in other respects; for example,
  19. they cover modification of the program.) This exception notice must be
  20. removed on modified copies of this file.
  21. This program is distributed in the hope that it will be useful,
  22. but WITHOUT ANY WARRANTY; without even the implied warranty of
  23. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  24. Lesser General Public License for more details.
  25. You should have received a copy of the GNU Lesser General Public
  26. License along with this library; if not, write to the Free Software
  27. Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  28. */
  29. #include <stdio.h>
  30. #include <string.h>
  31. #include <stdlib.h>
  32. #include "ttversion.h"
  33. #include "revtools.h"
  34. #include "tt.h"
  35. #include "strhead.h"
  36. #ifdef FILE_REVISION
  37. #undef FILE_REVISION
  38. #endif
  39. #define FILE_REVISION "1.7"
  40. //=============================================================================
  41. // outputs usage information of this tool
  42. //=============================================================================
  43. void PrintUsage() {
  44. fprintf(USAGE_OUT, "Usage: ttchecksum <infile>\n\n"\
  45. " corrects the checksum of 89z/89s/89y/9xz/9xs/9xy calculator files.\n\n"\
  46. " NOTE: if the embedded filelength doesn't match the real filelength\n"\
  47. " (for example: caused by an invalid FTP transfer) the file\n"\
  48. " cannot be corrected.\n");
  49. }
  50. //=============================================================================
  51. // an old friend ...
  52. //=============================================================================
  53. int main(int argc,char *argv[]) {
  54. FILE* fp;
  55. unsigned long len;
  56. unsigned long embedded_len;
  57. unsigned char ftype;
  58. unsigned char chk1;
  59. unsigned char chk2;
  60. unsigned int ochecksum;
  61. unsigned int checksum;
  62. //unsigned char h[4];
  63. unsigned long loop;
  64. StrHeader header;
  65. PRINT_ID("TTChecksum");
  66. if (argc !=2) {
  67. PrintUsage();
  68. return 1;
  69. }
  70. // open inputfile
  71. if (!(fp = fopen(argv[1],"rb+"))) {
  72. fprintf(stderr,"ERROR: cannot open inputfile %s\n",argv[1]);
  73. return 1;
  74. }
  75. // read TI header
  76. if (fread(&header,sizeof(StrHeader),1,fp) != 1) {
  77. fprintf(stderr,"ERROR: cannot read TI fileheader from %s\n",argv[1]);
  78. fclose(fp);
  79. return 1;
  80. }
  81. // check for valid TI signature
  82. if (strncmp(header.signature,"**TI",4)) {
  83. fprintf(stderr,"ERROR: file doesn't start with '**TI'\n");
  84. fclose(fp);
  85. return 1;
  86. }
  87. // goto end of file
  88. if (fseek(fp,-3,SEEK_END)) {
  89. fprintf(stderr,"ERROR: cannot seek to filetype\n");
  90. fclose(fp);
  91. return 1;
  92. }
  93. // read filetype, checksum bytes and get length of file
  94. ftype = fgetc(fp);
  95. chk1 = fgetc(fp);
  96. chk2 = fgetc(fp);
  97. len = (unsigned long)ftell(fp);
  98. // calculate embedded file length
  99. embedded_len = ((((unsigned long)(header.size[3]))<<24) +
  100. (((unsigned long)(header.size[2]))<<16) +
  101. (((unsigned long)(header.size[1]))<<8) +
  102. ((unsigned long)(header.size[0])));
  103. // if real length missmatches embedded length -> cannot correct this problem
  104. if (embedded_len != len) {
  105. fprintf(stderr,"FATAL: embedded len (%lu) doesn't match real length (%lu).\nCannot correct this file.\n",len,embedded_len);
  106. fclose(fp);
  107. return 1;
  108. }
  109. // calculate checksum from checksum bytes
  110. ochecksum = (chk2 << 8) + chk1;
  111. // print some details about the file
  112. fprintf(stderr,"length=%lu type=%02x checksum=%u (0x%02x%02x)\n",len,ftype,ochecksum,chk1,chk2);
  113. if (ftype != 0x2d && ftype != 0xf8 && ftype != 0xf3) {
  114. fprintf(stderr,"ERROR: file neither STR, ASM nor OTH type\n");
  115. fclose(fp);
  116. return 1;
  117. }
  118. // evaluate checksum by our own ...
  119. fseek(fp,sizeof(StrHeader)-2,SEEK_SET);
  120. checksum = 0;
  121. for (loop=sizeof(StrHeader)-2;loop<len-2;loop++) {
  122. checksum += fgetc(fp);
  123. }
  124. chk1 = checksum%256;
  125. chk2 = checksum/256;
  126. checksum = (chk2 << 8) + chk1;
  127. // compare original checksum and our checksum ...
  128. if (checksum == ochecksum) {
  129. fprintf(stderr,"checksum already ok. will not patch.\n");
  130. }
  131. else {
  132. fprintf(stderr,"checksum wrong. correcting it to %u (0x%02x%02x)\n",checksum,chk1,chk2);
  133. fseek(fp,-2,SEEK_END);
  134. fputc(chk1,fp);
  135. fputc(chk2,fp);
  136. }
  137. fclose(fp);
  138. return 0;
  139. }
  140. //#############################################################################
  141. //###################### NO MORE FAKES BEYOND THIS LINE #######################
  142. //#############################################################################
  143. //
  144. //=============================================================================
  145. // Revision History
  146. //=============================================================================
  147. //
  148. // Revision 1.7 2009/01/25 Lionel Debroux
  149. // Changes by Romain Liévin and/or me for 64-bit compatibility.
  150. // Adapt to new version display (revtools.h).
  151. //
  152. // Revision 1.6 2002/03/04 10:21:42 tnussb
  153. // compares now embedded filelength with real filelength
  154. //
  155. // Revision 1.5 2002/02/07 09:49:37 tnussb
  156. // all local includes changed, because header files are now located in pctools folder
  157. //
  158. // Revision 1.4 2001/01/06 10:01:09 Thomas Nussbaumer
  159. // operates now on 89z and 9xz files, too
  160. //
  161. // Revision 1.3 2000/11/28 00:07:32 Thomas Nussbaumer
  162. // using now USAGE_OUT stream for usage info
  163. //
  164. // Revision 1.2 2000/08/23 19:49:17 Thomas Nussbaumer
  165. // adapted to automatic version display (revtools.h)
  166. //
  167. // Revision 1.1 2000/08/21 17:12:27 Thomas Nussbaumer
  168. // initial version
  169. //
  170. //
  171. //
  172. //