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