1 /* Hey EMACS -*- linux-c -*- */
2 /* $Id$ */
3
4 /* libticalcs2 - hand-helds support library, a part of the TiLP project
5 * Copyright (C) 1999-2005 Romain Liévin
6 * Copyright (C) 2006 Kevin Kofler
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software Foundation,
20 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21 */
22
23 /*
24 TI89 Titanium support thru DirectUsb link.
25 */
26
27 #ifdef HAVE_CONFIG_H
28 #include <config.h>
29 #endif
30
31 #include <stdio.h>
32 #include <stdlib.h>
33 #include <string.h>
34 #include <time.h>
35
36 #include "ticalcs.h"
37 #include "gettext.h"
38 #include "internal.h"
39 #include "logging.h"
40 #include "error.h"
41
42 #include "dusb_vpkt.h"
43 #include "dusb_cmd.h"
44
45 #include "rom89t.h"
46 #include "romdump.h"
47 #include "keys89.h"
48
49 // Screen coordinates of the Titanium
50 #define TI89T_ROWS 128
51 #define TI89T_COLS 240
52 #define TI89T_ROWS_VISIBLE 100
53 #define TI89T_COLS_VISIBLE 160
54
is_ready(CalcHandle * handle)55 static int is_ready (CalcHandle* handle)
56 {
57 int ret;
58 static const DUSBModeSet mode = DUSB_MODE_NORMAL;
59
60 ret = dusb_cmd_s_mode_set(handle, mode);
61 if (!ret)
62 {
63 ret = dusb_cmd_r_mode_ack(handle);
64 }
65
66 return ret;
67 }
68
send_key(CalcHandle * handle,uint32_t key)69 static int send_key (CalcHandle* handle, uint32_t key)
70 {
71 int ret;
72
73 PAUSE(25); // this pause is needed between 2 keys
74 ret = dusb_cmd_s_execute(handle, "", "", DUSB_EID_KEY, "", (uint16_t)key);
75 if (!ret)
76 {
77 ret = dusb_cmd_r_data_ack(handle);
78 }
79
80 return ret;
81 }
82
execute(CalcHandle * handle,VarEntry * ve,const char * args)83 static int execute (CalcHandle* handle, VarEntry *ve, const char *args)
84 {
85 uint8_t action;
86 int ret;
87
88 switch (ve->type)
89 {
90 case TI89t_ASM: action = DUSB_EID_ASM; break;
91 case TI89t_APPL: action = DUSB_EID_APP; break;
92 default: action = DUSB_EID_PRGM; break;
93 }
94
95 ret = dusb_cmd_s_execute(handle, ve->folder, ve->name, action, args, 0);
96 if (!ret)
97 {
98 ret = dusb_cmd_r_data_ack(handle);
99 }
100
101 return ret;
102 }
103
recv_screen(CalcHandle * handle,CalcScreenCoord * sc,uint8_t ** bitmap)104 static int recv_screen (CalcHandle* handle, CalcScreenCoord* sc, uint8_t** bitmap)
105 {
106 static const uint16_t pid[] = { DUSB_PID_SCREENSHOT };
107 const int size = 1;
108 DUSBCalcParam **param;
109 int ret;
110
111 *bitmap = (uint8_t *)ticalcs_alloc_screen(TI89T_COLS * TI89T_ROWS / 8);
112 if (*bitmap == NULL)
113 {
114 return ERR_MALLOC;
115 }
116
117 sc->width = TI89T_COLS;
118 sc->height = TI89T_ROWS;
119 sc->clipped_width = TI89T_COLS_VISIBLE;
120 sc->clipped_height = TI89T_ROWS_VISIBLE;
121 sc->pixel_format = CALC_PIXFMT_MONO;
122
123 param = dusb_cp_new_array(handle, size);
124 ret = dusb_cmd_s_param_request(handle, size, pid);
125 while (!ret)
126 {
127 ret = dusb_cmd_r_param_data(handle, size, param);
128 if (!ret)
129 {
130 if (!param[0]->ok || param[0]->size != TI89T_COLS * TI89T_ROWS / 8)
131 {
132 ticalcs_free_screen(*bitmap);
133 ret = ERR_INVALID_PACKET;
134 break;
135 }
136
137 memcpy(*bitmap, param[0]->data, TI89T_COLS * TI89T_ROWS / 8);
138
139 // Clip the unused part of the screen (nevertheless usable with asm programs)
140 if (sc->format == SCREEN_CLIPPED)
141 {
142 int i, j, k;
143
144 for (i = 0, j = 0; j < TI89T_ROWS_VISIBLE; j++)
145 {
146 for (k = 0; k < (TI89T_COLS_VISIBLE >> 3); k++)
147 {
148 (*bitmap)[i++] = (*bitmap)[j * (TI89T_COLS >> 3) + k];
149 }
150 }
151 }
152 }
153 break;
154 }
155 dusb_cp_del_array(handle, size, param);
156
157 return ret;
158 }
159
get_dirlist(CalcHandle * handle,GNode ** vars,GNode ** apps)160 static int get_dirlist (CalcHandle* handle, GNode** vars, GNode** apps)
161 {
162 static const uint16_t aids[] = { DUSB_AID_VAR_TYPE, DUSB_AID_ARCHIVED, DUSB_AID_4APPVAR, DUSB_AID_VAR_SIZE, DUSB_AID_LOCKED, DUSB_AID_UNKNOWN_42 };
163 const int size = sizeof(aids) / sizeof(uint16_t);
164 int ret;
165 DUSBCalcAttr **attr;
166 GNode *root, *folder = NULL;
167 char fldname[40];
168 char varname[40];
169 char folder_name[40] = "";
170 char *u1, *u2;
171
172 ret = dirlist_init_trees(handle, vars, apps);
173 if (ret)
174 {
175 return ret;
176 }
177
178 root = dirlist_create_append_node(NULL, apps);
179 if (!root)
180 {
181 return ERR_MALLOC;
182 }
183
184 ret = dusb_cmd_s_dirlist_request(handle, size, aids);
185 if (!ret)
186 {
187 for (;;)
188 {
189 VarEntry *ve;
190 GNode *node;
191
192 attr = dusb_ca_new_array(handle, size);
193 ret = dusb_cmd_r_var_header(handle, fldname, varname, attr);
194 if (ret)
195 {
196 // Not a real error.
197 if (ret == ERR_EOT)
198 {
199 ret = 0;
200 }
201 dusb_ca_del_array(handle, size, attr);
202 break;
203 }
204
205 ve = tifiles_ve_create();
206 ticalcs_strlcpy(ve->folder, fldname, sizeof(ve->folder));
207 ticalcs_strlcpy(ve->name, varname, sizeof(ve->name));
208 ve->size = ( (((uint32_t)(attr[3]->data[0])) << 24)
209 | (((uint32_t)(attr[3]->data[1])) << 16)
210 | (((uint32_t)(attr[3]->data[2])) << 8)
211 | (((uint32_t)(attr[3]->data[3])) ));
212 ve->type = (uint32_t)(attr[0]->data[3]);
213 ve->attr = attr[1]->data[0] ? ATTRB_ARCHIVED : attr[4]->data[0] ? ATTRB_LOCKED : ATTRB_NONE;
214 dusb_ca_del_array(handle, size, attr);
215
216 if (ve->type == TI89_DIR)
217 {
218 ticalcs_strlcpy(folder_name, ve->folder, sizeof(folder_name));
219 ticalcs_strlcpy(ve->name, ve->folder, sizeof(ve->name));
220 ve->folder[0] = 0;
221
222 folder = dirlist_create_append_node(ve, vars);
223 }
224 else
225 {
226 if (!strcmp(ve->folder, "main") && (!strcmp(ve->name, "regcoef") || !strcmp(ve->name, "regeq")))
227 {
228 tifiles_ve_delete(ve);
229 }
230 else
231 {
232 node = dirlist_create_append_node(ve, (ve->type != TI89_APPL) ? &folder : &root);
233 if (!node)
234 {
235 ret = ERR_MALLOC;
236 break;
237 }
238 }
239 }
240 /*
241 ticalcs_info(_("Name: %8s | Type: %8s | Attr: %i | Size: %08X"),
242 ve->name,
243 tifiles_vartype2string(handle->model, ve->type),
244 ve->attr,
245 ve->size);
246 */
247 u1 = ticonv_varname_to_utf8(handle->model, ((VarEntry *) (folder->data))->name, -1);
248 u2 = ticonv_varname_to_utf8(handle->model, ve->name, ve->type);
249 ticalcs_slprintf(update_->text, sizeof(update_->text), _("Parsing %s/%s"), u1, u2);
250 ticonv_utf8_free(u2);
251 ticonv_utf8_free(u1);
252 update_label();
253 }
254 }
255
256 return ret;
257 }
258
get_memfree(CalcHandle * handle,uint32_t * ram,uint32_t * flash)259 static int get_memfree (CalcHandle* handle, uint32_t* ram, uint32_t* flash)
260 {
261 static const uint16_t pids[] = { DUSB_PID_FREE_RAM, DUSB_PID_FREE_FLASH };
262 const int size = sizeof(pids) / sizeof(uint16_t);
263 DUSBCalcParam **params;
264 int ret;
265
266 params = dusb_cp_new_array(handle, size);
267 if (params != NULL)
268 {
269 ret = dusb_cmd_s_param_request(handle, size, pids);
270 if (!ret)
271 {
272 ret = dusb_cmd_r_param_data(handle, size, params);
273 if (!ret)
274 {
275 if (params[0]->ok && params[0]->size == 8 && params[1]->ok && params[1]->size == 8)
276 {
277 *ram = ( (((uint32_t)(params[0]->data[4])) << 24)
278 | (((uint32_t)(params[0]->data[5])) << 16)
279 | (((uint32_t)(params[0]->data[6])) << 8)
280 | (((uint32_t)(params[0]->data[7])) ));
281 *flash = ( (((uint32_t)(params[1]->data[4])) << 24)
282 | (((uint32_t)(params[1]->data[5])) << 16)
283 | (((uint32_t)(params[1]->data[6])) << 8)
284 | (((uint32_t)(params[1]->data[7])) ));
285 }
286 else
287 {
288 ret = ERR_INVALID_PACKET;
289 }
290 }
291 }
292 }
293 else
294 {
295 ret = ERR_MALLOC;
296 }
297 dusb_cp_del_array(handle, size, params);
298
299 return ret;
300 }
301
send_var(CalcHandle * handle,CalcMode mode,FileContent * content)302 static int send_var (CalcHandle* handle, CalcMode mode, FileContent* content)
303 {
304 unsigned int i;
305 int ret = 0;
306
307 update_->cnt2 = 0;
308 update_->max2 = content->num_entries;
309
310 for (i = 0; i < content->num_entries; i++)
311 {
312 DUSBCalcAttr **attrs;
313 const int nattrs = 4;
314 VarEntry * entry = content->entries[i];
315 uint32_t pkt_size;
316 uint32_t size;
317 char varname[18];
318
319 if (!ticalcs_validate_varentry(entry))
320 {
321 ticalcs_critical("%s: skipping invalid content entry #%u", __FUNCTION__, i);
322 continue;
323 }
324
325 if (entry->action == ACT_SKIP)
326 {
327 ticalcs_info("%s: skipping variable #%u because requested", __FUNCTION__, i);
328 continue;
329 }
330
331 if (entry->folder[0])
332 {
333 tifiles_build_fullname(handle->model, varname, entry->folder, entry->name);
334 }
335 else
336 {
337 ticalcs_strlcpy(varname, entry->name, sizeof(varname));
338 }
339
340 ticonv_varname_to_utf8_sn(handle->model, varname, update_->text, sizeof(update_->text), entry->type);
341 update_label();
342
343 attrs = dusb_ca_new_array(handle, nattrs);
344 attrs[0] = dusb_ca_new(handle, DUSB_AID_VAR_TYPE, 4);
345 attrs[0]->data[0] = 0xF0; attrs[0]->data[1] = 0x0C;
346 attrs[0]->data[2] = 0x00; attrs[0]->data[3] = entry->type;
347 attrs[1] = dusb_ca_new(handle, DUSB_AID_ARCHIVED, 1);
348 attrs[1]->data[0] = entry->attr == ATTRB_ARCHIVED ? 1 : 0;
349 attrs[2] = dusb_ca_new(handle, DUSB_AID_VAR_VERSION, 4);
350 attrs[2]->data[0] = 0;
351 attrs[3] = dusb_ca_new(handle, DUSB_AID_LOCKED, 1);
352 attrs[3]->data[0] = entry->attr == ATTRB_LOCKED ? 1 : 0;
353
354 size = entry->size;
355 if (entry->size >= 65536U)
356 {
357 ticalcs_critical("%s: variable size %u is suspiciously large", __FUNCTION__, size);
358 }
359
360 if (!(size & 1))
361 {
362 ret = is_ready(handle);
363 }
364
365 if (ret)
366 {
367 dusb_ca_del_array(handle, nattrs, attrs);
368 break;
369 }
370
371 ret = dusb_cmd_s_rts(handle, entry->folder, entry->name, size, nattrs, CA(attrs));
372 dusb_ca_del_array(handle, nattrs, attrs);
373 if (ret)
374 {
375 break;
376 }
377 ret = dusb_cmd_r_data_ack(handle);
378 if (ret)
379 {
380 break;
381 }
382 /*
383 When sending variables with an odd varsize, bufer has to be negotiatied again with an even value.
384 Moreover, buffer has to be smaller. Ti-Connect always use 0x3A which is very small for big variables.
385 I prefer using an heuristic value to optimize data rate.
386 */
387 if (size & 1)
388 {
389 pkt_size = size / 10;
390 pkt_size >>= 1;
391 pkt_size <<= 1;
392
393 if (pkt_size < 0x3a)
394 {
395 pkt_size = 0x3a;
396 }
397
398 ret = dusb_send_buf_size_request(handle, pkt_size);
399 if (ret)
400 {
401 break;
402 }
403 ret = dusb_recv_buf_size_alloc(handle, NULL);
404 if (ret)
405 {
406 break;
407 }
408 }
409
410 ret = dusb_cmd_s_var_content(handle, size, entry->data);
411 if (ret)
412 {
413 break;
414 }
415 ret = dusb_cmd_r_data_ack(handle);
416 if (ret)
417 {
418 break;
419 }
420 ret = dusb_cmd_s_eot(handle);
421 if (ret)
422 {
423 break;
424 }
425
426 update_->cnt2 = i + 1;
427 update_->max2 = content->num_entries;
428 update_->pbar();
429
430 PAUSE(50); // needed
431 }
432
433 return ret;
434 }
435
recv_var(CalcHandle * handle,CalcMode mode,FileContent * content,VarRequest * vr)436 static int recv_var (CalcHandle* handle, CalcMode mode, FileContent* content, VarRequest* vr)
437 {
438 static const uint16_t aids[] = { DUSB_AID_ARCHIVED, DUSB_AID_VAR_VERSION, DUSB_AID_LOCKED };
439 const int naids = sizeof(aids) / sizeof(uint16_t);
440 DUSBCalcAttr **attrs;
441 const int nattrs = 1;
442 char fldname[40], varname[40];
443 uint8_t *data;
444 VarEntry *ve;
445 int ret;
446
447 ticonv_varname_to_utf8_sn(handle->model, vr->name, update_->text, sizeof(update_->text), vr->type);
448 update_label();
449
450 attrs = dusb_ca_new_array(handle, nattrs);
451 attrs[0] = dusb_ca_new(handle, DUSB_AID_VAR_TYPE2, 4);
452 attrs[0]->data[0] = 0xF0; attrs[0]->data[1] = 0x0C;
453 attrs[0]->data[2] = 0x00; attrs[0]->data[3] = vr->type;
454
455 ret = dusb_cmd_s_var_request(handle, vr->folder, vr->name, naids, aids, nattrs, CA(attrs));
456 dusb_ca_del_array(handle, nattrs, attrs);
457 if (!ret)
458 {
459 attrs = dusb_ca_new_array(handle, naids);
460 ret = dusb_cmd_r_var_header(handle, fldname, varname, attrs);
461 if (!ret)
462 {
463 ret = dusb_cmd_r_var_content(handle, NULL, &data);
464 if (!ret)
465 {
466 content->model = handle->model;
467 ticalcs_strlcpy(content->comment, tifiles_comment_set_single(), sizeof(content->comment));
468 content->num_entries = 1;
469
470 content->entries = tifiles_ve_create_array(1);
471 ve = content->entries[0] = tifiles_ve_create();
472 memcpy(ve, vr, sizeof(VarEntry));
473
474 ve->data = tifiles_ve_alloc_data(ve->size);
475 memcpy(ve->data, data, ve->size);
476 g_free(data);
477 }
478 }
479
480 dusb_ca_del_array(handle, naids, attrs);
481 }
482
483 return ret;
484 }
485
send_all_vars_backup(CalcHandle * handle,FileContent * content)486 static int send_all_vars_backup (CalcHandle* handle, FileContent* content)
487 {
488 return send_var(handle, MODE_BACKUP, content);
489 }
490
send_flash(CalcHandle * handle,FlashContent * content)491 static int send_flash (CalcHandle* handle, FlashContent* content)
492 {
493 FlashContent *ptr;
494 DUSBCalcAttr **attrs;
495 const int nattrs = 4;
496 int ret = 0;
497
498 // send all headers except license
499 for (ptr = content; ptr != NULL; ptr = ptr->next)
500 {
501 if (ptr->data_type == TI89_LICENSE)
502 {
503 continue;
504 }
505
506 ticalcs_info(_("FLASH name: \"%s\""), ptr->name);
507 ticalcs_info(_("FLASH size: %i bytes."), ptr->data_length);
508
509 ticonv_varname_to_utf8_sn(handle->model, ptr->name, update_->text, sizeof(update_->text), ptr->data_type);
510 update_label();
511
512 attrs = dusb_ca_new_array(handle, nattrs);
513 attrs[0] = dusb_ca_new(handle, DUSB_AID_VAR_TYPE, 4);
514 attrs[0]->data[0] = 0xF0; attrs[0]->data[1] = 0x0C;
515 attrs[0]->data[2] = 0x00; attrs[0]->data[3] = ptr->data_type;
516 attrs[1] = dusb_ca_new(handle, DUSB_AID_ARCHIVED, 1);
517 attrs[1]->data[0] = 0;
518 attrs[2] = dusb_ca_new(handle, DUSB_AID_VAR_VERSION, 4);
519 attrs[2]->data[3] = 1;
520 attrs[3] = dusb_ca_new(handle, DUSB_AID_LOCKED, 1);
521 attrs[3]->data[0] = 0;
522
523 ret = dusb_cmd_s_rts(handle, "", ptr->name, ptr->data_length, nattrs, CA(attrs));
524 dusb_ca_del_array(handle, nattrs, attrs);
525 if (ret)
526 {
527 break;
528 }
529 ret = dusb_cmd_r_data_ack(handle);
530 if (ret)
531 {
532 break;
533 }
534 ret = dusb_cmd_s_var_content(handle, ptr->data_length, ptr->data_part);
535 if (ret)
536 {
537 break;
538 }
539 ret = dusb_cmd_r_data_ack(handle);
540 if (ret)
541 {
542 break;
543 }
544 ret = dusb_cmd_s_eot(handle);
545 if (ret)
546 {
547 break;
548 }
549 }
550
551 return ret;
552 }
553
recv_flash(CalcHandle * handle,FlashContent * content,VarRequest * vr)554 static int recv_flash (CalcHandle* handle, FlashContent* content, VarRequest* vr)
555 {
556 static const uint16_t aids[] = { DUSB_AID_ARCHIVED, DUSB_AID_VAR_VERSION, DUSB_AID_LOCKED };
557 const int naids = sizeof(aids) / sizeof(uint16_t);
558 DUSBCalcAttr **attrs;
559 const int nattrs = 1;
560 char fldname[40], varname[40];
561 uint8_t *data;
562 uint32_t data_length;
563 int ret;
564
565 ticonv_varname_to_utf8_sn(handle->model, vr->name, update_->text, sizeof(update_->text), vr->type);
566 update_label();
567
568 attrs = dusb_ca_new_array(handle, nattrs);
569 attrs[0] = dusb_ca_new(handle, DUSB_AID_VAR_TYPE2, 4);
570 attrs[0]->data[0] = 0xF0; attrs[0]->data[1] = 0x0C;
571 attrs[0]->data[2] = 0x00; attrs[0]->data[3] = vr->type;
572
573 ret = dusb_cmd_s_var_request(handle, "", vr->name, naids, aids, nattrs, CA(attrs));
574 dusb_ca_del_array(handle, nattrs, attrs);
575 if (!ret)
576 {
577 attrs = dusb_ca_new_array(handle, naids);
578 ret = dusb_cmd_r_var_header(handle, fldname, varname, attrs);
579 if (!ret)
580 {
581 ret = dusb_cmd_r_var_content(handle, &data_length, &data);
582 if (!ret)
583 {
584 content->model = handle->model;
585 ticalcs_strlcpy(content->name, vr->name, sizeof(content->name));
586 content->data_type = vr->type;
587 content->device_type = DEVICE_TYPE_89;
588 content->data_length = data_length;
589 content->data_part = data; // Borrow this memory block.
590 content->hw_id = handle->calc->product_id;
591
592 // Do NOT g_free(data);
593 }
594 }
595 dusb_ca_del_array(handle, naids, attrs);
596 }
597
598 return ret;
599 }
600
send_os(CalcHandle * handle,FlashContent * content)601 static int send_os (CalcHandle* handle, FlashContent* content)
602 {
603 DUSBModeSet mode = { 2, 1, 0, 0, 0x0fa0 }; //MODE_BASIC;
604 uint32_t pkt_size = 0x3ff;
605 uint32_t hdr_size = 0;
606 uint32_t hdr_offset = 0;
607 FlashContent *ptr;
608 uint8_t *d;
609 int i, r, q;
610 int ret;
611
612 // search for data header
613 for (ptr = content; ptr != NULL; ptr = ptr->next)
614 {
615 if (ptr->data_type == TI89_AMS || ptr->data_type == TI89_APPL)
616 {
617 break;
618 }
619 }
620 if (ptr == NULL)
621 {
622 return ERR_INVALID_PARAMETER;
623 }
624 if (ptr->data_type != TI89_AMS)
625 {
626 return ERR_INVALID_PARAMETER;
627 }
628 if (ptr->data_part == NULL)
629 {
630 return ERR_INVALID_PARAMETER;
631 }
632
633 // search for OS header (offset & size)
634 hdr_offset = 2+4;
635 for (i = hdr_offset, d = ptr->data_part; (d[i] != 0xCC) || (d[i+1] != 0xCC) || (d[i+2] != 0xCC) || (d[i+3] != 0xCC); i++);
636 hdr_size = i - hdr_offset - 6;
637
638 do
639 {
640 // switch to BASIC mode
641 ret = dusb_cmd_s_mode_set(handle, mode);
642 if (ret)
643 {
644 break;
645 }
646 ret = dusb_cmd_r_mode_ack(handle);
647 if (ret)
648 {
649 break;
650 }
651
652 // start OS transfer
653 ret = dusb_cmd_s_os_begin(handle, ptr->data_length);
654 if (ret)
655 {
656 break;
657 }
658 ret = dusb_cmd_r_os_ack(handle, &pkt_size);
659 if (ret)
660 {
661 break;
662 }
663
664 // send OS header/signature
665 ret = dusb_cmd_s_os_header_89(handle, hdr_size, ptr->data_part + hdr_offset);
666 if (ret)
667 {
668 break;
669 }
670 ret = dusb_cmd_r_os_ack(handle, &pkt_size);
671 if (ret)
672 {
673 break;
674 }
675
676 // send OS data
677 q = ptr->data_length / 0x2000;
678 r = ptr->data_length % 0x2000;
679
680 update_->cnt2 = 0;
681 update_->max2 = q;
682
683 for (i = 0; i < q; i++)
684 {
685 ret = dusb_cmd_s_os_data_89(handle, 0x2000, ptr->data_part + i*0x2000);
686 if (ret)
687 {
688 goto end;
689 }
690 ret = dusb_cmd_r_data_ack(handle);
691 if (ret)
692 {
693 goto end;
694 }
695
696 update_->cnt2 = i;
697 update_->pbar();
698 }
699
700 ret = dusb_cmd_s_os_data_89(handle, r, ptr->data_part + i*0x2000);
701 if (ret)
702 {
703 break;
704 }
705 ret = dusb_cmd_r_data_ack(handle);
706 if (ret)
707 {
708 break;
709 }
710
711 update_->cnt2 = i;
712 update_->pbar();
713
714 ret = dusb_cmd_s_eot(handle);
715 if (ret)
716 {
717 break;
718 }
719 PAUSE(500);
720 ret = dusb_cmd_r_eot_ack(handle);
721 } while (0);
722 end:
723
724 return ret;
725 }
726
recv_idlist(CalcHandle * handle,uint8_t * id)727 static int recv_idlist (CalcHandle* handle, uint8_t* id)
728 {
729 static const uint16_t pid[] = { DUSB_PID_FULL_ID };
730 const int size = 1;
731 DUSBCalcParam **params;
732 int ret;
733
734 ticalcs_strlcpy(update_->text, "ID-LIST", sizeof(update_->text));
735 update_label();
736
737 params = dusb_cp_new_array(handle, size);
738 if (params != NULL)
739 {
740 ret = dusb_cmd_s_param_request(handle, size, pid);
741 if (!ret)
742 {
743 ret = dusb_cmd_r_param_data(handle, size, params);
744 if (!ret)
745 {
746 if (params[0]->ok && params[0]->size == 18)
747 {
748 memcpy(&id[0], &(params[0]->data[1]), 5);
749 memcpy(&id[5], &(params[0]->data[7]), 5);
750 memcpy(&id[10], &(params[0]->data[13]), 5);
751 id[14] = '\0';
752 }
753 else
754 {
755 ret = ERR_INVALID_PACKET;
756 }
757 }
758 }
759 }
760 else
761 {
762 ret = ERR_MALLOC;
763 }
764 dusb_cp_del_array(handle, size, params);
765
766 return ret;
767 }
768
dump_rom_1(CalcHandle * handle)769 static int dump_rom_1 (CalcHandle* handle)
770 {
771 DUSBCalcParam *param;
772 int ret;
773
774 // Go back to HOME screen
775 param = dusb_cp_new(handle, DUSB_PID_HOMESCREEN, 1);
776 param->data[0] = 1;
777 ret = dusb_cmd_s_param_set(handle, param);
778 dusb_cp_del(handle, param);
779 if (!ret)
780 {
781 ret = dusb_cmd_r_data_ack(handle);
782 if (!ret)
783 {
784 // Send dumping program
785 ret = rd_send(handle, "romdump.89z", romDumpSize89t, romDump89t);
786 PAUSE(1000);
787 }
788 }
789
790 return ret;
791 }
792
dump_rom_2(CalcHandle * handle,CalcDumpSize size,const char * filename)793 static int dump_rom_2 (CalcHandle* handle, CalcDumpSize size, const char *filename)
794 {
795 int ret;
796
797 ret = dusb_cmd_s_execute(handle, "main", "romdump", DUSB_EID_ASM, "", 0);
798 if (!ret)
799 {
800 ret = dusb_cmd_r_data_ack(handle);
801 if (!ret)
802 {
803 // Get dump
804 ret = rd_dump(handle, filename);
805 }
806 }
807
808 return ret;
809 }
810
set_clock(CalcHandle * handle,CalcClock * _clock)811 static int set_clock (CalcHandle* handle, CalcClock* _clock)
812 {
813 DUSBCalcParam *param;
814 uint32_t calc_time;
815 struct tm ref, cur;
816 time_t r, c, now;
817 int ret;
818
819 time(&now);
820 memcpy(&ref, localtime(&now), sizeof(struct tm));
821
822 ref.tm_year = 1997 - 1900;
823 ref.tm_mon = 0;
824 ref.tm_yday = 0;
825 ref.tm_mday = 1;
826 ref.tm_wday = 3;
827 ref.tm_hour = 0;
828 ref.tm_min = 0;
829 ref.tm_sec = 0;
830 //ref.tm_isdst = 1;
831 r = mktime(&ref);
832
833 cur.tm_year = _clock->year - 1900;
834 cur.tm_mon = _clock->month - 1;
835 cur.tm_mday = _clock->day;
836 cur.tm_hour = _clock->hours;
837 cur.tm_min = _clock->minutes;
838 cur.tm_sec = _clock->seconds;
839 cur.tm_isdst = 1;
840 c = mktime(&cur);
841
842 calc_time = (uint32_t)difftime(c, r);
843
844 ticalcs_strlcpy(update_->text, _("Setting clock..."), sizeof(update_->text));
845 update_label();
846
847 do
848 {
849 param = dusb_cp_new(handle, DUSB_PID_CLK_SEC_SINCE_1997, 4);
850 param->data[0] = MSB(MSW(calc_time));
851 param->data[1] = LSB(MSW(calc_time));
852 param->data[2] = MSB(LSW(calc_time));
853 param->data[3] = LSB(LSW(calc_time));
854 ret = dusb_cmd_s_param_set(handle, param);
855 dusb_cp_del(handle, param);
856 if (ret)
857 {
858 break;
859 }
860
861 ret = dusb_cmd_r_data_ack(handle);
862 if (ret)
863 {
864 break;
865 }
866
867 param = dusb_cp_new(handle, DUSB_PID_CLK_DATE_FMT, 1);
868 param->data[0] = _clock->date_format == 3 ? 0 : _clock->date_format;
869 ret = dusb_cmd_s_param_set(handle, param);
870 dusb_cp_del(handle, param);
871 if (ret)
872 {
873 break;
874 }
875
876 ret = dusb_cmd_r_data_ack(handle);
877 if (ret)
878 {
879 break;
880 }
881
882 param = dusb_cp_new(handle, DUSB_PID_CLK_TIME_FMT, 1);
883 param->data[0] = _clock->time_format == 24 ? 1 : 0;
884 ret = dusb_cmd_s_param_set(handle, param);
885 dusb_cp_del(handle, param);
886 if (ret)
887 {
888 break;
889 }
890
891 ret = dusb_cmd_r_data_ack(handle);
892 if (ret)
893 {
894 break;
895 }
896
897 param = dusb_cp_new(handle, DUSB_PID_CLK_ON, 1);
898 param->data[0] = _clock->state;
899 ret = dusb_cmd_s_param_set(handle, param);
900 dusb_cp_del(handle, param);
901 if (ret)
902 {
903 break;
904 }
905
906 ret = dusb_cmd_r_data_ack(handle);
907 } while (0);
908
909 return ret;
910 }
911
get_clock(CalcHandle * handle,CalcClock * _clock)912 static int get_clock (CalcHandle* handle, CalcClock* _clock)
913 {
914 static const uint16_t pids[5] = { DUSB_PID_CLASSIC_CLK_SUPPORT, DUSB_PID_CLK_SEC_SINCE_1997, DUSB_PID_CLK_DATE_FMT, DUSB_PID_CLK_TIME_FMT, DUSB_PID_CLK_ON };
915 const int size = sizeof(pids) / sizeof(uint16_t);
916 DUSBCalcParam **params;
917 uint32_t calc_time;
918 struct tm ref, *cur;
919 time_t r, c, now;
920 int ret;
921
922 // get raw clock
923 ticalcs_strlcpy(update_->text, _("Getting clock..."), sizeof(update_->text));
924 update_label();
925
926 params = dusb_cp_new_array(handle, size);
927 ret = dusb_cmd_s_param_request(handle, size, pids);
928 if (!ret)
929 {
930 ret = dusb_cmd_r_param_data(handle, size, params);
931 if (!ret)
932 {
933 // It's not a fatal error if DUSB_PID_CLASSIC_CLK_SUPPORT is not handled.
934 if (params[0]->ok && params[0]->size == 1)
935 {
936 if (!params[0]->data[0])
937 {
938 ret = ERR_UNSUPPORTED;
939 }
940 }
941 else
942 {
943 if ( params[1]->ok && params[0]->size == 4
944 && params[2]->ok && params[1]->size == 1
945 && params[3]->ok && params[2]->size == 1
946 && params[4]->ok && params[3]->size == 1)
947 {
948 // and computes
949 calc_time = (((uint32_t)params[0]->data[0]) << 24) | (((uint32_t)params[0]->data[1]) << 16) | (((uint32_t)params[0]->data[2]) << 8) | (params[0]->data[3] << 0);
950
951 time(&now); // retrieve current DST setting
952 memcpy(&ref, localtime(&now), sizeof(struct tm));
953 ref.tm_year = 1997 - 1900;
954 ref.tm_mon = 0;
955 ref.tm_yday = 0;
956 ref.tm_mday = 1;
957 ref.tm_wday = 3;
958 ref.tm_hour = 0;
959 ref.tm_min = 0;
960 ref.tm_sec = 0;
961 //ref.tm_isdst = 1;
962 r = mktime(&ref);
963
964 c = r + calc_time;
965 cur = localtime(&c);
966
967 _clock->year = cur->tm_year + 1900;
968 _clock->month = cur->tm_mon + 1;
969 _clock->day = cur->tm_mday;
970 _clock->hours = cur->tm_hour;
971 _clock->minutes = cur->tm_min;
972 _clock->seconds = cur->tm_sec;
973
974 _clock->date_format = params[1]->data[0] == 0 ? 3 : params[1]->data[0];
975 _clock->time_format = params[2]->data[0] ? 24 : 12;
976 _clock->state = params[3]->data[0];
977 }
978 else
979 {
980 ret = ERR_INVALID_PACKET;
981 }
982 }
983 }
984 }
985 dusb_cp_del_array(handle, size, params);
986
987 return ret;
988 }
989
del_var(CalcHandle * handle,VarRequest * vr)990 static int del_var (CalcHandle* handle, VarRequest* vr)
991 {
992 DUSBCalcAttr **attr;
993 const int size = 1;
994 char varname[68];
995 char *utf8;
996 int ret;
997
998 tifiles_build_fullname(handle->model, varname, vr->folder, vr->name);
999 utf8 = ticonv_varname_to_utf8(handle->model, varname, vr->type);
1000 ticalcs_slprintf(update_->text, sizeof(update_->text), _("Deleting %s..."), utf8);
1001 ticonv_utf8_free(utf8);
1002 update_label();
1003
1004 attr = dusb_ca_new_array(handle, size);
1005 attr[0] = dusb_ca_new(handle, DUSB_AID_VAR_TYPE2, 4);
1006 attr[0]->data[0] = 0xF0; attr[0]->data[1] = 0x0C;
1007 attr[0]->data[2] = 0x00; attr[0]->data[3] = vr->type;
1008
1009 ret = dusb_cmd_s_var_delete(handle, vr->folder, vr->name, size, CA(attr));
1010 dusb_ca_del_array(handle, size, attr);
1011 if (!ret)
1012 {
1013 ret = dusb_cmd_r_data_ack(handle);
1014 }
1015
1016 return ret;
1017 }
1018
rename_var(CalcHandle * handle,VarRequest * oldname,VarRequest * newname)1019 static int rename_var (CalcHandle* handle, VarRequest* oldname, VarRequest* newname)
1020 {
1021 DUSBCalcAttr **attrs;
1022 const int size = 1;
1023 char varname1[68], varname2[68];
1024 char *utf81, *utf82;
1025 int ret;
1026
1027 tifiles_build_fullname(handle->model, varname1, oldname->folder, oldname->name);
1028 tifiles_build_fullname(handle->model, varname2, newname->folder, newname->name);
1029 utf81 = ticonv_varname_to_utf8(handle->model, varname1, oldname->type);
1030 utf82 = ticonv_varname_to_utf8(handle->model, varname2, newname->type);
1031 ticalcs_slprintf(update_->text, sizeof(update_->text), _("Renaming %s to %s..."), utf81, utf82);
1032 ticonv_utf8_free(utf82);
1033 ticonv_utf8_free(utf81);
1034 update_label();
1035
1036 attrs = dusb_ca_new_array(handle, size);
1037 attrs[0] = dusb_ca_new(handle, DUSB_AID_VAR_TYPE2, 4);
1038 attrs[0]->data[0] = 0xF0; attrs[0]->data[1] = 0x0C;
1039 attrs[0]->data[2] = 0x00; attrs[0]->data[3] = oldname->type;
1040
1041 ret = dusb_cmd_s_var_modify(handle, oldname->folder, oldname->name, 1, CA(attrs), newname->folder, newname->name, 0, NULL);
1042 dusb_ca_del_array(handle, size, attrs);
1043 if (!ret)
1044 {
1045 ret = dusb_cmd_r_data_ack(handle);
1046 }
1047
1048 return ret;
1049 }
1050
change_attr(CalcHandle * handle,VarRequest * vr,FileAttr attr)1051 static int change_attr (CalcHandle* handle, VarRequest* vr, FileAttr attr)
1052 {
1053 DUSBCalcAttr **srcattrs;
1054 DUSBCalcAttr **dstattrs;
1055 int ret = 0;
1056 char *utf8;
1057
1058 utf8 = ticonv_varname_to_utf8(handle->model, vr->folder, -1);
1059 ticalcs_slprintf(update_->text, sizeof(update_->text), _("Changing attributes of %s..."), utf8);
1060 ticonv_utf8_free(utf8);
1061 update_label();
1062
1063 srcattrs = dusb_ca_new_array(handle, 1);
1064 srcattrs[0] = dusb_ca_new(handle, DUSB_AID_VAR_TYPE2, 4);
1065 srcattrs[0]->data[0] = 0xF0; srcattrs[0]->data[1] = 0x0C;
1066 srcattrs[0]->data[2] = 0x00; srcattrs[0]->data[3] = vr->type;
1067
1068 dstattrs = dusb_ca_new_array(handle, 2);
1069 dstattrs[0] = dusb_ca_new(handle, DUSB_AID_ARCHIVED, 1);
1070 dstattrs[0]->data[0] = (attr == ATTRB_ARCHIVED ? 0x01 : 0x00);
1071 dstattrs[1] = dusb_ca_new(handle, DUSB_AID_LOCKED, 1);
1072 dstattrs[1]->data[0] = (attr == ATTRB_LOCKED ? 0x01 : 0x00);
1073
1074 ret = dusb_cmd_s_var_modify(handle, vr->folder, vr->name, 1, CA(srcattrs), vr->folder, vr->name, 2, CA(dstattrs));
1075 dusb_ca_del_array(handle, 2, dstattrs);
1076 dusb_ca_del_array(handle, 1, srcattrs);
1077 if (!ret)
1078 {
1079 ret = dusb_cmd_r_data_ack(handle);
1080 }
1081
1082 return ret;
1083 }
1084
new_folder(CalcHandle * handle,VarRequest * vr)1085 static int new_folder (CalcHandle* handle, VarRequest* vr)
1086 {
1087 uint8_t data[16] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x0A, 0x40, 0x00, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x23 };
1088 char *fldname = vr->folder;
1089 DUSBCalcParam *param;
1090 DUSBCalcAttr **attrs;
1091 const int nattrs = 4;
1092 char *utf8;
1093 int ret;
1094
1095 utf8 = ticonv_varname_to_utf8(handle->model, vr->folder, -1);
1096 ticalcs_slprintf(update_->text, sizeof(update_->text), _("Creating %s..."), utf8);
1097 ticonv_utf8_free(utf8);
1098 update_label();
1099
1100 // send empty expression in specified folder
1101 attrs = dusb_ca_new_array(handle, nattrs);
1102 attrs[0] = dusb_ca_new(handle, DUSB_AID_VAR_TYPE, 4);
1103 attrs[0]->data[0] = 0xF0; attrs[0]->data[1] = 0x0C;
1104 attrs[0]->data[2] = 0x00; attrs[0]->data[3] = 0x00;
1105 attrs[1] = dusb_ca_new(handle, DUSB_AID_ARCHIVED, 1);
1106 attrs[1]->data[0] = 0;
1107 attrs[2] = dusb_ca_new(handle, DUSB_AID_VAR_VERSION, 4);
1108 attrs[2]->data[0] = 0;
1109 attrs[3] = dusb_ca_new(handle, DUSB_AID_LOCKED, 1);
1110 attrs[3]->data[0] = 0;
1111
1112 do
1113 {
1114 ret = dusb_cmd_s_rts(handle, fldname, "a1234567", sizeof(data), nattrs, CA(attrs));
1115 dusb_ca_del_array(handle, nattrs, attrs);
1116 if (ret)
1117 {
1118 break;
1119 }
1120
1121 ret = dusb_cmd_r_data_ack(handle);
1122 if (ret)
1123 {
1124 break;
1125 }
1126
1127 ret = dusb_cmd_s_var_content(handle, sizeof(data), data);
1128 if (ret)
1129 {
1130 break;
1131 }
1132
1133 ret = dusb_cmd_r_data_ack(handle);
1134 if (ret)
1135 {
1136 break;
1137 }
1138
1139 ret = dusb_cmd_s_eot(handle);
1140 if (ret)
1141 {
1142 break;
1143 }
1144
1145 // go back to HOME screen
1146 param = dusb_cp_new(handle, DUSB_PID_HOMESCREEN, 1);
1147 param->data[0] = 1;
1148 ret = dusb_cmd_s_param_set(handle, param);
1149 dusb_cp_del(handle, param);
1150 if (ret)
1151 {
1152 break;
1153 }
1154
1155 ret = dusb_cmd_r_data_ack(handle);
1156 if (ret)
1157 {
1158 break;
1159 }
1160
1161 // delete 'a1234567' variable
1162 ticalcs_strlcpy(vr->name, "a1234567", sizeof(vr->name));
1163 ret = del_var(handle, vr);
1164 } while (0);
1165
1166 return ret;
1167 }
1168
get_version(CalcHandle * handle,CalcInfos * infos)1169 static int get_version (CalcHandle* handle, CalcInfos* infos)
1170 {
1171 static const uint16_t pids1[] = {
1172 DUSB_PID_PRODUCT_NAME, DUSB_PID_MAIN_PART_ID,
1173 DUSB_PID_HW_VERSION, DUSB_PID_LANGUAGE_ID, DUSB_PID_SUBLANG_ID, DUSB_PID_DEVICE_TYPE,
1174 DUSB_PID_BOOT_VERSION, DUSB_PID_OS_VERSION,
1175 DUSB_PID_PHYS_RAM, DUSB_PID_USER_RAM, DUSB_PID_FREE_RAM,
1176 DUSB_PID_PHYS_FLASH, DUSB_PID_FREE_FLASH, DUSB_PID_FREE_FLASH,
1177 DUSB_PID_LCD_WIDTH, DUSB_PID_LCD_HEIGHT,
1178 };
1179 static const uint16_t pids2[] = {
1180 DUSB_PID_BITS_PER_PIXEL, DUSB_PID_BATTERY, DUSB_PID_OS_MODE, DUSB_PID_CLASSIC_CLK_SUPPORT
1181 }; // Titanium can't manage more than 16 parameters at a time
1182 const int size1 = sizeof(pids1) / sizeof(uint16_t);
1183 const int size2 = sizeof(pids2) / sizeof(uint16_t);
1184 DUSBCalcParam **params1;
1185 DUSBCalcParam **params2;
1186 int i = 0;
1187 int ret = 0;
1188
1189 ticalcs_strlcpy(update_->text, _("Getting version..."), sizeof(update_->text));
1190 update_label();
1191
1192 memset(infos, 0, sizeof(CalcInfos));
1193 params1 = dusb_cp_new_array(handle, size1);
1194 params2 = dusb_cp_new_array(handle, size2);
1195
1196 do
1197 {
1198 ret = dusb_cmd_s_param_request(handle, size1, pids1);
1199 if (!ret)
1200 {
1201 ret = dusb_cmd_r_param_data(handle, size1, params1);
1202 if (!ret)
1203 {
1204 ret = dusb_cmd_s_param_request(handle, size2, pids2);
1205 if (!ret)
1206 {
1207 ret = dusb_cmd_r_param_data(handle, size2, params2);
1208 }
1209 }
1210 }
1211
1212 if (ret)
1213 {
1214 break;
1215 }
1216
1217 if (params1[i]->ok)
1218 {
1219 ticalcs_strlcpy(infos->product_name, (char *)params1[i]->data, sizeof(infos->product_name));
1220 infos->mask |= INFOS_PRODUCT_NAME;
1221 }
1222 i++;
1223
1224 if (params1[i]->ok && params1[i]->size >= 18)
1225 {
1226 strncpy(infos->main_calc_id, (char*)&(params1[i]->data[1]), 5);
1227 strncpy(infos->main_calc_id+5, (char*)&(params1[i]->data[7]), 5);
1228 strncpy(infos->main_calc_id+10, (char*)&(params1[i]->data[13]), 4);
1229 infos->main_calc_id[14] = 0;
1230 infos->mask |= INFOS_MAIN_CALC_ID;
1231 ticalcs_strlcpy(infos->product_id, infos->main_calc_id, sizeof(infos->product_id));
1232 infos->mask |= INFOS_PRODUCT_ID;
1233 }
1234 i++;
1235
1236 if (params1[i]->ok && params1[i]->size == 2)
1237 {
1238 infos->hw_version = ((((uint16_t)params1[i]->data[0]) << 8) | params1[i]->data[1]) + 1;
1239 infos->mask |= INFOS_HW_VERSION; // hw version or model ?
1240 }
1241 i++;
1242
1243 if (params1[i]->ok && params1[i]->size == 1)
1244 {
1245 infos->language_id = params1[i]->data[0];
1246 infos->mask |= INFOS_LANG_ID;
1247 }
1248 i++;
1249
1250 if (params1[i]->ok && params1[i]->size == 1)
1251 {
1252 infos->sub_lang_id = params1[i]->data[0];
1253 infos->mask |= INFOS_SUB_LANG_ID;
1254 }
1255 i++;
1256
1257 if (params1[i]->ok && params1[i]->size == 2)
1258 {
1259 infos->device_type = params1[i]->data[1];
1260 infos->mask |= INFOS_DEVICE_TYPE;
1261 }
1262 i++;
1263
1264 if (params1[i]->ok && params1[i]->size == 4)
1265 {
1266 ticalcs_slprintf(infos->boot_version, sizeof(infos->boot_version), "%1u.%02ub%u", params1[i]->data[1], params1[i]->data[2], params1[i]->data[3]);
1267 infos->mask |= INFOS_BOOT_VERSION;
1268 }
1269 i++;
1270
1271 if (params1[i]->ok && params1[i]->size == 3)
1272 {
1273 ticalcs_slprintf(infos->os_version, sizeof(infos->os_version), "%1u.%02u", params1[i]->data[1], params1[i]->data[2]);
1274 infos->mask |= INFOS_OS_VERSION;
1275 }
1276 i++;
1277
1278 if (params1[i]->ok && params1[i]->size == 8)
1279 {
1280 infos->ram_phys = ( (((uint64_t)(params1[i]->data[ 0])) << 56)
1281 | (((uint64_t)(params1[i]->data[ 1])) << 48)
1282 | (((uint64_t)(params1[i]->data[ 2])) << 40)
1283 | (((uint64_t)(params1[i]->data[ 3])) << 32)
1284 | (((uint64_t)(params1[i]->data[ 4])) << 24)
1285 | (((uint64_t)(params1[i]->data[ 5])) << 16)
1286 | (((uint64_t)(params1[i]->data[ 6])) << 8)
1287 | (((uint64_t)(params1[i]->data[ 7])) ));
1288 infos->mask |= INFOS_RAM_PHYS;
1289 }
1290 i++;
1291 if (params1[i]->ok && params1[i]->size == 8)
1292 {
1293 infos->ram_user = ( (((uint64_t)(params1[i]->data[ 0])) << 56)
1294 | (((uint64_t)(params1[i]->data[ 1])) << 48)
1295 | (((uint64_t)(params1[i]->data[ 2])) << 40)
1296 | (((uint64_t)(params1[i]->data[ 3])) << 32)
1297 | (((uint64_t)(params1[i]->data[ 4])) << 24)
1298 | (((uint64_t)(params1[i]->data[ 5])) << 16)
1299 | (((uint64_t)(params1[i]->data[ 6])) << 8)
1300 | (((uint64_t)(params1[i]->data[ 7])) ));
1301 infos->mask |= INFOS_RAM_USER;
1302 }
1303 i++;
1304 if (params1[i]->ok && params1[i]->size == 8)
1305 {
1306 infos->ram_free = ( (((uint64_t)(params1[i]->data[ 0])) << 56)
1307 | (((uint64_t)(params1[i]->data[ 1])) << 48)
1308 | (((uint64_t)(params1[i]->data[ 2])) << 40)
1309 | (((uint64_t)(params1[i]->data[ 3])) << 32)
1310 | (((uint64_t)(params1[i]->data[ 4])) << 24)
1311 | (((uint64_t)(params1[i]->data[ 5])) << 16)
1312 | (((uint64_t)(params1[i]->data[ 6])) << 8)
1313 | (((uint64_t)(params1[i]->data[ 7])) ));
1314 infos->mask |= INFOS_RAM_FREE;
1315 }
1316 i++;
1317
1318 if (params1[i]->ok && params1[i]->size == 8)
1319 {
1320 infos->flash_phys = ( (((uint64_t)(params1[i]->data[ 0])) << 56)
1321 | (((uint64_t)(params1[i]->data[ 1])) << 48)
1322 | (((uint64_t)(params1[i]->data[ 2])) << 40)
1323 | (((uint64_t)(params1[i]->data[ 3])) << 32)
1324 | (((uint64_t)(params1[i]->data[ 4])) << 24)
1325 | (((uint64_t)(params1[i]->data[ 5])) << 16)
1326 | (((uint64_t)(params1[i]->data[ 6])) << 8)
1327 | (((uint64_t)(params1[i]->data[ 7])) ));
1328 infos->mask |= INFOS_FLASH_PHYS;
1329 }
1330 i++;
1331 if (params1[i]->ok && params1[i]->size == 8)
1332 {
1333 infos->flash_user = ( (((uint64_t)(params1[i]->data[ 0])) << 56)
1334 | (((uint64_t)(params1[i]->data[ 1])) << 48)
1335 | (((uint64_t)(params1[i]->data[ 2])) << 40)
1336 | (((uint64_t)(params1[i]->data[ 3])) << 32)
1337 | (((uint64_t)(params1[i]->data[ 4])) << 24)
1338 | (((uint64_t)(params1[i]->data[ 5])) << 16)
1339 | (((uint64_t)(params1[i]->data[ 6])) << 8)
1340 | (((uint64_t)(params1[i]->data[ 7])) ));
1341 infos->mask |= INFOS_FLASH_USER;
1342 }
1343 i++;
1344 if (params1[i]->ok && params1[i]->size == 8)
1345 {
1346 infos->flash_free = ( (((uint64_t)(params1[i]->data[ 0])) << 56)
1347 | (((uint64_t)(params1[i]->data[ 1])) << 48)
1348 | (((uint64_t)(params1[i]->data[ 2])) << 40)
1349 | (((uint64_t)(params1[i]->data[ 3])) << 32)
1350 | (((uint64_t)(params1[i]->data[ 4])) << 24)
1351 | (((uint64_t)(params1[i]->data[ 5])) << 16)
1352 | (((uint64_t)(params1[i]->data[ 6])) << 8)
1353 | (((uint64_t)(params1[i]->data[ 7])) ));
1354 infos->mask |= INFOS_FLASH_FREE;
1355 }
1356 i++;
1357
1358 if (params1[i]->ok && params1[i]->size == 2)
1359 {
1360 infos->lcd_width = ( (((uint16_t)params1[i]->data[ 0]) << 8)
1361 | (((uint16_t)params1[i]->data[ 1]) ));
1362 infos->mask |= INFOS_LCD_WIDTH;
1363 }
1364 i++;
1365 if (params1[i]->ok && params1[i]->size == 2)
1366 {
1367 infos->lcd_height = ( (((uint16_t)params1[i]->data[ 0]) << 8)
1368 | (((uint16_t)params1[i]->data[ 1]) ));
1369 infos->mask |= INFOS_LCD_HEIGHT;
1370 }
1371 i++;
1372
1373 i = 0;
1374 if (params2[i]->ok && params2[i]->size == 1)
1375 {
1376 infos->bits_per_pixel = params2[i]->data[0];
1377 infos->mask |= INFOS_BPP;
1378 }
1379
1380 if (params2[i]->ok && params2[i]->size == 1)
1381 {
1382 infos->battery = params2[i]->data[0];
1383 infos->mask |= INFOS_BATTERY;
1384 }
1385 i++;
1386
1387 if (params2[i]->ok && params2[i]->size == 1)
1388 {
1389 infos->run_level = params2[i]->data[0];
1390 infos->mask |= INFOS_RUN_LEVEL;
1391 }
1392 i++;
1393
1394 if (params2[i]->ok && params2[i]->size == 1)
1395 {
1396 infos->clock_support = params2[i]->data[0];
1397 infos->mask |= INFOS_CLOCK_SUPPORT;
1398 }
1399 i++;
1400
1401 infos->model = CALC_TI89T;
1402 infos->mask |= INFOS_CALC_MODEL;
1403 } while (0);
1404
1405 dusb_cp_del_array(handle, size2, params2);
1406 dusb_cp_del_array(handle, size1, params1);
1407
1408 return ret;
1409 }
1410
1411 const CalcFncts calc_89t_usb =
1412 {
1413 CALC_TI89T_USB,
1414 "Titanium",
1415 "TI-89 Titanium",
1416 N_("TI-89 Titanium thru DirectLink"),
1417 OPS_ISREADY | OPS_SCREEN | OPS_DIRLIST | OPS_VARS | OPS_FLASH | OPS_OS | OPS_ROMDUMP |
1418 OPS_IDLIST | OPS_CLOCK | OPS_DELVAR | OPS_NEWFLD | OPS_VERSION | OPS_BACKUP | OPS_KEYS |
1419 OPS_RENAME | OPS_CHATTR |
1420 FTS_SILENT | FTS_MEMFREE | FTS_FLASH | FTS_FOLDER,
1421 PRODUCT_ID_TI89T,
1422 {"", /* is_ready */
1423 "", /* send_key */
1424 "", /* execute */
1425 "1P", /* recv_screen */
1426 "1L", /* get_dirlist */
1427 "", /* get_memfree */
1428 "2P1L", /* send_backup */
1429 "2P1L", /* recv_backup */
1430 "2P1L", /* send_var */
1431 "1P1L", /* recv_var */
1432 "2P1L", /* send_var_ns */
1433 "1P1L", /* recv_var_ns */
1434 "2P1L", /* send_app */
1435 "2P1L", /* recv_app */
1436 "2P", /* send_os */
1437 "1L", /* recv_idlist */
1438 "2P", /* dump_rom_1 */
1439 "2P", /* dump_rom_2 */
1440 "", /* set_clock */
1441 "", /* get_clock */
1442 "1L", /* del_var */
1443 "1L", /* new_folder */
1444 "", /* get_version */
1445 "1L", /* send_cert */
1446 "1L", /* recv_cert */
1447 "", /* rename */
1448 "", /* chattr */
1449 "2P1L", /* send_all_vars_backup */
1450 "2P1L" /* recv_all_vars_backup */ },
1451 &is_ready,
1452 &send_key,
1453 &execute,
1454 &recv_screen,
1455 &get_dirlist,
1456 &get_memfree,
1457 &noop_send_backup,
1458 &noop_recv_backup,
1459 &send_var,
1460 &recv_var,
1461 &noop_send_var_ns,
1462 &noop_recv_var_ns,
1463 &send_flash,
1464 &recv_flash,
1465 &send_os,
1466 &recv_idlist,
1467 &dump_rom_1,
1468 &dump_rom_2,
1469 &set_clock,
1470 &get_clock,
1471 &del_var,
1472 &new_folder,
1473 &get_version,
1474 &noop_send_cert,
1475 &noop_recv_cert,
1476 &rename_var,
1477 &change_attr,
1478 &send_all_vars_backup,
1479 &tixx_recv_all_vars_backup
1480 };
1481