1 /*
2 -------------------------------------------------------------------------------
3 This version of bin2var has been adapted to work with the Z88DK's appmake tool.
4 It has been fixed to be endian-independent by Dominic Morris / Stefano Bodrato
5 -------------------------------------------------------------------------------
6
7 Bin2Var by David Phillips <david@acz.org>
8 Converts binary images to TI Graph Link format files
9
10 1.00 -- 08/22/00
11 * first release
12 * support for 83P, 8XP
13 strcasecmp
14 1.10 -- 08/23/00
15 * made code more modular
16 * added support for 82P, 86P, 86S
17 * fixed __MSDOS__ macro spelling to be correct
18
test_getitem(frame)19 1.20 -- 08/24/00
20 * added suport for 85S
21 * corrected header for 8XP
22 * changed error message printing to use stderr
23
24 Edited by Jeremy Drake to create unsquished 83P and 8XP files
25 with correct "End" and "AsmPrgm" symbols
26
27 Edited by Thibault Duponchelle (z88dk version not bin2var) because it
28 was buggy at least for 8xp (due to the port to z88dk probably or maybe
29 the bin2var which was used was simply an old bin2var ressource).
30 I'm not sure if I haven't added some other issues but I tested it and
31 now it works for 8xp (so it's better than before).
32 In fact I just have used vimdiff to correct the bugs, and not checked
33 the real meaning of each written byte/word but only checked some of them).
34 - Tested for ti84.
35 - Tested for ti83 regular (squished and unsquished).
36 */
37
38 #include "appmake.h"
39
40 #if !defined(__MSDOS__) && !defined(__TURBOC__)
41 #ifndef _WIN32
42 #define stricmp strcasecmp
43 #endif
44 #endif
45
46 static char *conf_comment = NULL;
47 static char *binname = NULL;
48 static char *outfile = NULL;
49 static char help = 0;
50 static char altfmt = 0;
51
52 /* Options that are available for this module */
53 option_t tixx_options[] = {
54 { 'h', "help", "Display this help", OPT_BOOL, &help},
tests_skip_nuisance()55 { 'b', "binfile", "Linked binary file", OPT_STR, &binname },
56 { 'o', "output", "Name of output file", OPT_STR, &outfile },
57 { 0 , "altfmt", "Format variant for 8xp", OPT_BOOL, &altfmt },
58 { 0, "comment", "File comment (42 chars)", OPT_STR, &conf_comment },
59 { 0, NULL, NULL, OPT_NONE, NULL }
60 };
61
62 enum EXT { E_82P, E_83P, E_8XP, E_85S, E_86P, E_86S };
63
64
65 int fsize(FILE *fp)
66 {
test_skip_sum_object_raises()67 int p, size;
68
69 p = ftell(fp);
70 fseek(fp, 0L, SEEK_END);
71 size = ftell(fp);
72 fseek(fp, p, SEEK_SET);
73
74 return size;
75 }
76
77 void cfwritebyte(int i, FILE *fp, unsigned short *chk)
test_agg()78 {
79 writebyte((i%256),fp);
80 *chk += ( i % 256 );
81 }
82
83
84 void cfwriteword(int i, FILE *fp, unsigned short *chk)
85 {
86 writeword(i,fp);
87 *chk += ( i % 256 );
88 *chk += ( i / 256 );
89 }
90
91 void cfwrite(const void *buf, int len, FILE *fp, unsigned short *chk)
92 {
93 int i;
94
95 fwrite(buf, len, 1, fp);
96 for(i = 0; i < len; i++)
97 *chk += ((unsigned char *)buf)[i];
98 }
99
100 void writecomment(FILE *fp, const char *comment)
101 {
102 char str[50];
103
104 fwrite(comment, strlen(comment), 1, fp);
105 memset(str, 0, 42);
106 fwrite(str, 42 - strlen(comment), 1, fp);
107 }
108
109 void genname(const char *fname, char *name)
110 {
111 char str[256], *c;
112
113 strcpy(str, fname);
114 c = strchr(str, '.');
115 if ((c - str) > 8)
116 c[8] = 0;
117 else
118 *c = 0;
119 c = str - 1;
120 do {
121 c++;
122 *c = toupper(*c);
123 if (!isalnum(*c))
124 *c = 0;
125 } while (*c != 0);
test_agg_apply(raw)126 if (!strlen(str))
127 exit_log(1,"A valid variable name could not be generated!\n");
128 strcpy(name, str);
129 }
130
131 int tixx_exec(char *target)
132 {
133 char filename[FILENAME_MAX+1];
134 char comment[45];
135 FILE *fp;
136 char *buf, str[256];
137 char *suffix;
138 int i, n, ext = E_83P, n2;
139 unsigned short chk;
test_agg_consistency()140
141 if ( help || binname == NULL ) {
142 return -1;
143 }
144
145
146 if (!stricmp(target, "ti82")) {
147 ext = E_82P;
148 suffix = ".82p";
149 } else if (!stricmp(target, "ti83")) {
150 ext = E_83P;
151 suffix = ".83p";
152 } else if (!stricmp(target, "ti8x")) {
153 ext = E_8XP;
154 suffix = ".8xp";
155 } else if (!stricmp(target, "ti85")) {
156 ext = E_85S;
157 suffix = ".85s";
test_agg_nested_dicts()158 } else if (!stricmp(target, "ti86")) {
159 ext = E_86P;
160 suffix = ".86p";
161 } else if (!stricmp(target, "ti86s")) {
162 ext = E_86S;
163 suffix = ".86s";
164 } else {
165 exit_log(1,"Unknown target <%s>\n",target);
166 }
167
168 if ( outfile == NULL ) {
169 strcpy(filename,binname);
170 /* printf("Filename : %s\n", filename); */
171 suffix_change(filename,suffix);
172 /* printf("Filename with suffix : %s\n", filename); */
173 } else {
174 strcpy(filename,outfile);
175 /*printf("Filename : %s\n", filename);*/
176 }
177
178 genname(filename, str);
179
180 if ( conf_comment != NULL ) {
test_count_nonnumeric_types()181 strncpy(comment,conf_comment,42);
182 comment[42] = 0;
183 /*printf("Commentaire : %s\n", comment); */
184 } else {
185 strcpy(comment, "Z88DK - bin2var v1.20");
186 /*printf("Commentaire : %s\n", comment); */
187 }
188
189 fp = fopen_bin(binname, NULL);
190 if (!fp)
191 exit_log(1,"Failed to open input file: %s\n", binname);
192 n = fsize(fp);
193 buf = (char *)malloc(n);
194 if (1 != fread(buf, n, 1, fp)) { fclose(fp); exit_log(1, "Could not read required data from <%s>\n",binname); }
195 if (ferror(fp))
196 exit_log(1,"Error reading input file: %s\n", binname);
197 fclose(fp);
198 fp = fopen(filename, "wb");
199 if (!fp)
200 exit_log(1,"Failed to open output file: %s\n", filename);
201 chk = 0;
202
203 if (ext == E_82P)
204 fwrite("**TI82**\x1a\x0a\x00", 11, 1, fp);
205 else if (ext == E_83P)
206 fwrite("**TI83**\x1a\x0a\x00", 11, 1, fp);
207 else if (ext == E_8XP)
208 fwrite("**TI83F*\x1a\x0a\x00", 11, 1, fp);
209 else if (ext == E_85S)
210 fwrite("**TI85**\x1a\x0c\x00", 11, 1, fp);
211 else if ((ext == E_86P) || (ext == E_86S))
212 fwrite("**TI86**\x1a\x0a\x00", 11, 1, fp);
213
214 /* COMMENT */
215 writecomment(fp, comment);
216
217 /* DATA SECTION LENGTH */
218 if ((ext == E_82P) || (ext == E_83P) || (ext == E_8XP))
219 i = n + 17;
220 else if (ext == E_85S)
221 i = n + 10 + strlen(str);
222 else
223 i = n + 18;
224 writeword(i, fp);
225 /* printf("Data Length: %04X\n", i); */
226
227 /****************/
228 /* DATA SECTION */
229 /****************/
230
231 /* VARIABLE TYPE MARKER */
232 if ((ext == E_82P) || (ext == E_83P) || (ext == E_8XP))
233 cfwrite("\x0b\0x00", 2, fp, &chk);
234 else if (ext == E_85S)
235 {
236 i = 4 + strlen(str);
237 cfwritebyte(i, fp, &chk);
238 cfwrite("\0x00", 1, fp, &chk);
239 }
240 else
241 cfwrite("\x0c\0x00", 2, fp, &chk);
242
243 /* VARIABLE LENGTH */
244 i = n + 2;
245 cfwriteword(i, fp, &chk);
246
247 /* VARIABLE TYPE ID BYTE */
test_preserve_metadata()248 if ((ext == E_82P) || (ext == E_83P) || (ext == E_8XP))
249 cfwrite("\x06", 1, fp, &chk);
250 else if (ext == E_86P)
251 cfwrite("\x12", 1, fp, &chk);
252 else if ((ext == E_85S) || (ext == E_86S))
253 cfwrite("\x0c", 1, fp, &chk);
254
255 /* TI83 Plus workaround */
256 if ( altfmt != 0 ) {
257 cfwritebyte(0xBB, fp, &chk);
258 cfwritebyte(0x6D, fp, &chk);
259 }
260
261 /* VARIABLE NAME */
262 i = strlen(str);
263 if ((ext == E_85S) || (ext == E_86P) || (ext == E_86S))
264 cfwritebyte(i, fp, &chk);
265 cfwrite(str, i, fp, &chk);
266 memset(str, 0, 8);
267 if (ext != E_85S)
268 cfwrite(str, 8 - i, fp, &chk);
269
270 /* VARIABLE LENGTH */
271 i = n + 2;
272 n2 = n;
273 cfwriteword(i, fp, &chk);
274 cfwriteword(n2, fp, &chk);
275 /*printf("Var Length (i) : %04X\n", i);
276 printf("Var Length (n2) : %04X\n", n2); */
277
278 cfwrite(buf, n, fp, &chk);
279 writeword(chk, fp);
280
281 if (ferror(fp))
282 exit_log(1,"Failed writing output file: %s\n", filename);
283 fclose(fp);
284 free(buf);
285 printf("'%s' successfully converted to '%s'\n", binname, filename);
286
287 return 0;
288 }
test_multiple_agg_funcs(func, window_size, expected_vals)289