files9x.c 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206
  1. /* Hey EMACS -*- linux-c -*- */
  2. /* $Id: files9x.c 3227 2007-02-26 19:40:27Z roms $ */
  3. /* libtifiles - file format library, a part of the TiLP project
  4. * Copyright (C) 1999-2005 Romain Liévin
  5. * Copyright (C) 2007 Kevin Kofler
  6. *
  7. * This program is free software; you can redistribute it and/or modify
  8. * it under the terms of the GNU General Public License as published by
  9. * the Free Software Foundation; either version 2 of the License, or
  10. * (at your option) any later version.
  11. *
  12. * This program is distributed in the hope that it will be useful,
  13. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  15. * GNU General Public License for more details.
  16. *
  17. * You should have received a copy of the GNU General Public License
  18. * along with this program; if not, write to the Free Software
  19. * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  20. */
  21. /*
  22. TI File Format handling routines
  23. Calcs: 89/89tm/92/92+/V200
  24. */
  25. #include <stdio.h>
  26. #include <stdlib.h>
  27. #include <string.h>
  28. #include <time.h>
  29. #include <assert.h>
  30. #include "tifiles.h"
  31. #include "error.h"
  32. #include "macros.h"
  33. #include "files9x.h"
  34. #include "rwfile.h"
  35. #define tifiles_info(x...) (fprintf(stderr, x),fprintf(stderr, "\n"))
  36. #define TI89_AMS 0x23
  37. #define TI89_APPL 0x24
  38. #define TI89_CERTIF 0x25
  39. #define TI89_LICENSE 0x3E
  40. #ifndef DISABLE_TI9X
  41. /********/
  42. /* Misc */
  43. /********/
  44. /***********/
  45. /* Reading */
  46. /***********/
  47. static int check_device_type(uint8_t id)
  48. {
  49. const uint8_t types[] = { 0, DEVICE_TYPE_89, DEVICE_TYPE_92P };
  50. int i;
  51. for(i = 1; i <= (int)(sizeof(types)/sizeof(uint8_t)); i++)
  52. if(types[i] == id)
  53. return i;
  54. return 0;
  55. }
  56. static int check_data_type(uint8_t id)
  57. {
  58. const uint8_t types[] = { 0, TI89_AMS, TI89_APPL, TI89_CERTIF, TI89_LICENSE };
  59. int i;
  60. for(i = 1; i <= (int)(sizeof(types)/sizeof(uint8_t)); i++)
  61. if(types[i] == id)
  62. return i;
  63. return 0;
  64. }
  65. /**
  66. * ti9x_file_read_flash:
  67. * @filename: name of flash file to open.
  68. * @content: where to store the file content.
  69. *
  70. * Load the flash file into a #FlashContent structure.
  71. *
  72. * Structure content must be freed with #tifiles_content_delete_flash when
  73. * no longer used. If error occurs, the structure content is released for you.
  74. *
  75. * Return value: an error code, 0 otherwise.
  76. **/
  77. int ti9x_file_read_flash(const char *filename, Ti9xFlash *head)
  78. {
  79. FILE *f;
  80. Ti9xFlash *content = head;
  81. int tib = 0;
  82. char signature[9];
  83. if (!tifiles_file_is_flash(filename) && !tifiles_file_is_tib(filename))
  84. return ERR_INVALID_FILE;
  85. // detect file type (old or new format)
  86. tib = tifiles_file_is_tib(filename);
  87. f = gfopen(filename, "rb");
  88. if (f == NULL)
  89. {
  90. tifiles_info("Unable to open this file: %s\n", filename);
  91. return ERR_FILE_OPEN;
  92. }
  93. if (tib)
  94. { // tib is an old format but mainly used by developers
  95. memset(content, 0, sizeof(Ti9xFlash));
  96. if(fseek(f, 0, SEEK_END)) goto tfrf;
  97. content->data_length = (uint32_t) ftell(f);
  98. if(fseek(f, 0, SEEK_SET)) goto tfrf;
  99. strcpy(content->name, "basecode");
  100. content->data_type = 0x23; // FLASH os
  101. content->data_part = (uint8_t *) calloc(content->data_length, 1);
  102. if (content->data_part == NULL)
  103. {
  104. fclose(f);
  105. return ERR_MALLOC;
  106. }
  107. if(fread(content->data_part, 1, content->data_length, f) < content->data_length) goto tfrf;
  108. switch(content->data_part[8])
  109. {
  110. case 1: content->device_type = DEVICE_TYPE_92P; break; // TI92+
  111. case 3: content->device_type = DEVICE_TYPE_89; break; // TI89
  112. // value added by the TI community according to HWID parameter
  113. // doesn't have any 'legal' existence.
  114. case 8: content->device_type = DEVICE_TYPE_92P; break; // V200PLT
  115. case 9: content->device_type = DEVICE_TYPE_89; break; // Titanium
  116. }
  117. content->next = NULL;
  118. }
  119. else
  120. {
  121. for (content = head;; content = content->next)
  122. {
  123. if(fread_8_chars(f, signature) < 0) goto tfrf;
  124. content->model = tifiles_file_get_model(filename);
  125. if(fread_byte(f, &(content->revision_major)) < 0) goto tfrf;
  126. if(fread_byte(f, &(content->revision_minor)) < 0) goto tfrf;
  127. if(fread_byte(f, &(content->flags)) < 0) goto tfrf;
  128. if(fread_byte(f, &(content->object_type)) < 0) goto tfrf;
  129. if(fread_byte(f, &(content->revision_day)) < 0) goto tfrf;
  130. if(fread_byte(f, &(content->revision_month)) < 0) goto tfrf;
  131. if(fread_word(f, &(content->revision_year)) < 0) goto tfrf;
  132. if(fskip(f, 1) < 0) goto tfrf;
  133. if(fread_8_chars(f, content->name) < 0) goto tfrf;
  134. if(fskip(f, 23) < 0) goto tfrf;
  135. if(fread_byte(f, &(content->device_type)) < 0) goto tfrf;
  136. if(fread_byte(f, &(content->data_type)) < 0) goto tfrf;
  137. if(fskip(f, 23) < 0) goto tfrf;
  138. if(fread_byte(f, &(content->hw_id)) < 0) goto tfrf;
  139. if(fread_long(f, &(content->data_length)) < 0) goto tfrf;
  140. if(content->data_type != TI89_LICENSE && !check_device_type(content->device_type))
  141. return ERR_INVALID_FILE;
  142. if(!check_data_type(content->data_type))
  143. return ERR_INVALID_FILE;
  144. content->data_part = (uint8_t *) calloc(content->data_length, 1);
  145. if (content->data_part == NULL)
  146. {
  147. fclose(f);
  148. tifiles_content_delete_flash(content);
  149. return ERR_MALLOC;
  150. }
  151. if(fread(content->data_part, 1, content->data_length, f) < content->data_length) goto tfrf;
  152. content->next = NULL;
  153. // check for end of file
  154. if(fread_8_chars(f, signature) < 0)
  155. break;
  156. if(strcmp(signature, "**TIFL**") || feof(f))
  157. break;
  158. if(fseek(f, -8, SEEK_CUR)) goto tfrf;
  159. content->next = (Ti9xFlash *) calloc(1, sizeof(Ti9xFlash));
  160. if (content->next == NULL)
  161. {
  162. fclose(f);
  163. tifiles_content_delete_flash(content);
  164. return ERR_MALLOC;
  165. }
  166. }
  167. }
  168. fclose(f);
  169. return 0;
  170. tfrf: // release on exit
  171. fclose(f);
  172. tifiles_content_delete_flash(content);
  173. return ERR_FILE_IO;
  174. }
  175. #endif