1 /* Hey EMACS -*- linux-c -*- */
2 /* $Id: link_nul.c 1059 2005-05-14 09:45:42Z roms $ */
3
4 /* libticalcs2 - hand-helds support library, a part of the TiLP project
5 * Copyright (c) 1999-2005 Romain Liévin
6 * Copyright (c) 2005 Benjamin Moody (ROM dumper)
7 * Copyright (c) 2006 Tyler Cassidy
8 * Copyright (C) 2006 Kevin Kofler
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software Foundation,
22 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
23 */
24
25 /*
26 TI73/TI83+/TI84+ support.
27 */
28
29 #ifdef HAVE_CONFIG_H
30 #include <config.h>
31 #endif
32
33 #include <stdio.h>
34 #include <stdlib.h>
35 #include <string.h>
36 #include <time.h>
37
38 #include "ticalcs.h"
39 #include "gettext.h"
40 #include "internal.h"
41 #include "logging.h"
42 #include "error.h"
43
44 #include "dbus_pkt.h"
45 #include "cmdz80.h"
46 #include "rom73.h"
47 #include "rom83p.h"
48 #include "rom84pc.h"
49 #include "romdump.h"
50 #include "keys83p.h"
51
52 #define SEND_RDY ti73_send_RDY
53 #define SEND_KEY ti73_send_KEY
54 #define SEND_SCR ti73_send_SCR
55 #define SEND_ACK ti73_send_ACK
56 #define SEND_VAR ti73_send_VAR
57 #define SEND_VAR2 ti73_send_VAR2
58 #define SEND_XDP ti73_send_XDP
59 #define SEND_REQ ti73_send_REQ
60 #define SEND_REQ2 ti73_send_REQ2
61 #define SEND_RTS ti73_send_RTS
62 #define SEND_CTS ti73_send_CTS
63 #define SEND_DEL ti73_send_DEL
64 #define SEND_VER ti73_send_VER
65 #define SEND_EOT ti73_send_EOT
66
67 #define RECV_ACK ti73_recv_ACK
68 #define RECV_VAR ti73_recv_VAR
69 #define RECV_VAR2 ti73_recv_VAR2
70 #define RECV_XDP ti73_recv_XDP
71 #define RECV_SKP ti73_recv_SKP
72 #define RECV_CTS ti73_recv_CTS
73
74 // Screen coordinates of the TI83+
75 #define TI73_ROWS 64
76 #define TI73_COLS 96
77 #define TI84PC_ROWS 240
78 #define TI84PC_COLS 320
79
is_ready(CalcHandle * handle)80 static int is_ready (CalcHandle* handle)
81 {
82 int ret;
83 uint16_t status;
84
85 ret = SEND_RDY(handle);
86 if (!ret)
87 {
88 ret = RECV_ACK(handle, &status);
89 if (!ret)
90 {
91 ret = (MSB(status) & 0x01) ? ERR_NOT_READY : 0;
92 }
93 }
94
95 return ret;
96 }
97
send_key(CalcHandle * handle,uint32_t key)98 static int send_key (CalcHandle* handle, uint32_t key)
99 {
100 int ret;
101 uint16_t status;
102
103 ret = SEND_KEY(handle, (uint16_t)key);
104 if (!ret)
105 {
106 ret = RECV_ACK(handle, &status); // when the key is received
107 if (!ret)
108 {
109 ret = RECV_ACK(handle, NULL); // after it completes the resulting action
110 }
111 }
112
113 return ret;
114 }
115
execute(CalcHandle * handle,VarEntry * ve,const char * args)116 static int execute (CalcHandle* handle, VarEntry *ve, const char* args)
117 {
118 int ret;
119
120 if (handle->model == CALC_TI73 && ve->type == TI73_ASM)
121 {
122 return ERR_VOID_FUNCTION;
123 }
124
125 // Go back to homescreen
126 PAUSE(200);
127 ret = send_key(handle, KEY83P_Quit);
128 if (!ret)
129 {
130 ret = send_key(handle, KEY83P_Clear);
131 if (!ret)
132 {
133 ret = send_key(handle, KEY83P_Clear);
134 }
135 }
136
137 if (!ret)
138 {
139 // Launch program by remote control
140 if (ve->type == TI83p_ASM)
141 {
142 ret = send_key(handle, KEY83P_Asm);
143 }
144 if (!ret)
145 {
146 ret = send_key(handle, KEY83P_Exec);
147 if (!ret)
148 {
149 unsigned int i;
150 for (i = 0; !ret && i < strlen(ve->name); i++)
151 {
152 const CalcKey *ck = ticalcs_keys_83p((ve->name)[i]);
153 ret = send_key(handle, (uint32_t)(ck->normal.value));
154 }
155
156 if (!ret)
157 {
158 ret = send_key(handle, KEY83P_Enter);
159
160 PAUSE(200);
161 }
162 }
163 }
164 }
165
166 return ret;
167 }
168
recv_screen(CalcHandle * handle,CalcScreenCoord * sc,uint8_t ** bitmap)169 static int recv_screen (CalcHandle* handle, CalcScreenCoord* sc, uint8_t** bitmap)
170 {
171 int ret;
172 uint8_t *buffer = handle->buffer2;
173 uint8_t *data = NULL;
174
175 data = (uint8_t *)ticalcs_alloc_screen(65537U);
176 if (data == NULL)
177 {
178 return ERR_MALLOC;
179 }
180
181 ret = SEND_SCR(handle);
182 if (!ret)
183 {
184 ret = RECV_ACK(handle, NULL);
185 if (!ret)
186 {
187 uint16_t pktsize;
188 ret = RECV_XDP(handle, &pktsize, data);
189 if (!ret || ret == ERR_CHECKSUM) // problem with checksum
190 {
191 ret = SEND_ACK(handle);
192 if (!ret)
193 {
194 if (pktsize == TI73_COLS * TI73_ROWS / 8)
195 {
196 /* TI-73 / 83+ / 84+ */
197 sc->width = TI73_COLS;
198 sc->height = TI73_ROWS;
199 sc->clipped_width = TI73_COLS;
200 sc->clipped_height = TI73_ROWS;
201 sc->pixel_format = CALC_PIXFMT_MONO;
202 *bitmap = ticalcs_realloc_screen(data, TI73_COLS * TI73_ROWS / 8);
203 }
204 else
205 {
206 /* TI-84+CSE */
207 uint32_t size = pktsize;
208
209 sc->width = TI84PC_COLS;
210 sc->height = TI84PC_ROWS;
211 sc->clipped_width = TI84PC_COLS;
212 sc->clipped_height = TI84PC_ROWS;
213 sc->pixel_format = CALC_PIXFMT_RGB_565_LE;
214
215 while (1)
216 {
217 ret = RECV_XDP(handle, &pktsize, buffer);
218 if (ret == ERR_EOT)
219 {
220 ret = SEND_ACK(handle);
221 break;
222 }
223
224 *bitmap = ticalcs_realloc_screen(data, size + pktsize);
225 if (*bitmap != NULL)
226 {
227 data = *bitmap;
228 memcpy(data + size, buffer, pktsize);
229 size += pktsize;
230
231 ret = SEND_ACK(handle);
232 if (ret)
233 {
234 break;
235 }
236
237 update_->max1 = TI84PC_COLS * TI84PC_ROWS * 2;
238 update_->cnt1 = size;
239 update_->pbar();
240 }
241 else
242 {
243 ticalcs_free_screen(data);
244 ret = ERR_MALLOC;
245 break;
246 }
247 }
248
249 if (!ret)
250 {
251 *bitmap = ticalcs_alloc_screen(TI84PC_ROWS * TI84PC_COLS * 2);
252 ret = ticalcs_screen_84pcse_rle_uncompress(data, size, *bitmap, TI84PC_ROWS * TI84PC_COLS * 2);
253 }
254 }
255 }
256 }
257 }
258 }
259
260 if (ret)
261 {
262 ticalcs_free_screen(*bitmap);
263 *bitmap = NULL;
264 }
265
266 return ret;
267 }
268
get_dirlist(CalcHandle * handle,GNode ** vars,GNode ** apps)269 static int get_dirlist (CalcHandle* handle, GNode** vars, GNode** apps)
270 {
271 int ret;
272 TreeInfo *ti;
273 GNode *folder, *root, *node;
274 uint16_t unused;
275 uint32_t memory;
276 char *utf8;
277
278 ret = dirlist_init_trees(handle, vars, apps);
279 if (ret)
280 {
281 return ret;
282 }
283 ti = (*vars)->data;
284
285 ret = SEND_REQ(handle, 0x0000, TI73_DIR, "\0\0\0\0\0\0\0", 0x00, 0x00);
286 if (!ret)
287 {
288 ret = RECV_ACK(handle, &unused);
289 if (!ret)
290 {
291 ret = RECV_XDP(handle, &unused, handle->buffer2);
292 if (!ret)
293 {
294 ret = SEND_ACK(handle);
295 if (!ret)
296 {
297 uint8_t * mem = (uint8_t *)handle->buffer2;
298 memory = (((uint32_t)(mem[1])) << 8) | mem[0]; // Clamp mem_free to a 16-bit value.
299 }
300 }
301 }
302 }
303 if (ret)
304 {
305 return ret;
306 }
307
308 ti->mem_free = memory;
309
310 folder = dirlist_create_append_node(NULL, vars);
311 if (!folder)
312 {
313 return ERR_MALLOC;
314 }
315 root = dirlist_create_append_node(NULL, apps);
316 if (!root)
317 {
318 return ERR_MALLOC;
319 }
320
321 // Add permanent variables (Window, RclWindow, TblSet aka WINDW, ZSTO, TABLE)
322 {
323 VarEntry *ve;
324
325 ve = tifiles_ve_create();
326 ve->type = TI84p_WINDW;
327 node = dirlist_create_append_node(ve, &folder);
328
329 if (node != NULL)
330 {
331 if (handle->model != CALC_TI73)
332 {
333 ve = tifiles_ve_create();
334 ve->type = TI84p_ZSTO;
335 node = dirlist_create_append_node(ve, &folder);
336 }
337
338 if (node != NULL)
339 {
340 ve = tifiles_ve_create();
341 ve->type = TI84p_TABLE;
342 node = dirlist_create_append_node(ve, &folder);
343 }
344 }
345 }
346
347 if (!node)
348 {
349 return ERR_MALLOC;
350 }
351
352 for (;;)
353 {
354 VarEntry *ve = tifiles_ve_create();
355 uint16_t ve_size;
356 int ret2;
357
358 ret = RECV_VAR(handle, &ve_size, &ve->type, ve->name, &ve->attr, &ve->version);
359 ve->size = ve_size;
360 ret2 = SEND_ACK(handle);
361 if (ret)
362 {
363 if (ret == ERR_EOT)
364 {
365 ret = 0;
366 }
367 error:
368 tifiles_ve_delete(ve);
369 break;
370 }
371 if (ret2)
372 {
373 ret = ret2;
374 goto error;
375 }
376
377 if (ve->type == TI73_APPL)
378 {
379 /* Size is reported as a number of pages -- compute amount
380 of space consumed (the actual application may be
381 somewhat smaller.) Note: the MSB of the "size" word is
382 the application's starting page number. */
383 ve->size = (ve->size & 0xff) * 0x4000;
384 }
385
386 node = dirlist_create_append_node(ve, (ve->type != TI73_APPL) ? &folder : &root);
387 if (!node)
388 {
389 return ERR_MALLOC;
390 }
391
392 utf8 = ticonv_varname_to_utf8(handle->model, ve->name, ve->type);
393 ticalcs_slprintf(update_->text, sizeof(update_->text), _("Parsing %s"), utf8);
394 ticonv_utf8_free(utf8);
395 update_label();
396 }
397
398 return ret;
399 }
400
get_memfree(CalcHandle * handle,uint32_t * ram,uint32_t * flash)401 static int get_memfree (CalcHandle* handle, uint32_t* ram, uint32_t* flash)
402 {
403 int ret;
404 uint16_t unused;
405
406 *ram = -1;
407 *flash = -1;
408
409 ret = SEND_REQ(handle, 0x0000, TI73_DIR, "\0\0\0\0\0\0\0", 0x00, 0x00);
410 if (!ret)
411 {
412 ret = RECV_ACK(handle, &unused);
413 if (!ret)
414 {
415 ret = RECV_XDP(handle, &unused, handle->buffer2);
416 if (!ret)
417 {
418 ret = SEND_EOT(handle);
419 if (!ret)
420 {
421 uint8_t * mem = (uint8_t *)handle->buffer2;
422 *ram = (((uint32_t)(mem[1])) << 8) | mem[0]; // Clamp mem_free to a 16-bit value.
423 }
424 }
425 }
426 }
427
428 return ret;
429 }
430
send_backup(CalcHandle * handle,BackupContent * content)431 static int send_backup (CalcHandle* handle, BackupContent* content)
432 {
433 int ret;
434 uint16_t length;
435 char varname[9];
436 uint8_t rej_code;
437 uint16_t status;
438
439 length = content->data_length1;
440 varname[0] = LSB(content->data_length2);
441 varname[1] = MSB(content->data_length2);
442 varname[2] = LSB(content->data_length3);
443 varname[3] = MSB(content->data_length3);
444 varname[4] = LSB(content->mem_address);
445 varname[5] = MSB(content->mem_address);
446 varname[6] = 0;
447 varname[7] = 0;
448 varname[8] = 0;
449
450 do
451 {
452 ret = SEND_RTS(handle, content->data_length1, TI73_BKUP, varname, 0x00, content->version);
453 if (!ret)
454 {
455 ret = RECV_ACK(handle, &status);
456 if (!ret)
457 {
458 ret = RECV_SKP(handle, &rej_code);
459 if (!ret)
460 {
461 ret = SEND_ACK(handle);
462 }
463 }
464 }
465 if (!ret)
466 {
467 switch (rej_code)
468 {
469 case DBUS_REJ_EXIT:
470 case DBUS_REJ_SKIP:
471 return ERR_ABORT;
472 case DBUS_REJ_MEMORY:
473 return ERR_OUT_OF_MEMORY;
474 case DBUS_REJ_VERSION:
475 return ERR_VAR_VERSION;
476 case 0: // CTS
477 break;
478 default:
479 return ERR_VAR_REJECTED;
480 }
481
482 update_->cnt2 = 0;
483 update_->max2 = 3;
484 update_->pbar();
485
486 ret = SEND_XDP(handle, content->data_length1, content->data_part1);
487 if (!ret)
488 {
489 ret = RECV_ACK(handle, &status);
490 }
491 if (ret)
492 {
493 break;
494 }
495 update_->cnt2++;
496 update_->pbar();
497
498 ret = SEND_XDP(handle, content->data_length2, content->data_part2);
499 if (!ret)
500 {
501 ret = RECV_ACK(handle, &status);
502 }
503 if (ret)
504 {
505 break;
506 }
507 update_->cnt2++;
508 update_->pbar();
509
510 ret = SEND_XDP(handle, content->data_length3, content->data_part3);
511 if (!ret)
512 {
513 ret = RECV_ACK(handle, &status);
514 }
515 if (ret)
516 {
517 break;
518 }
519 update_->cnt2++;
520 update_->pbar();
521
522 ret = SEND_ACK(handle);
523 }
524 } while(0);
525
526 return ret;
527 }
528
recv_backup(CalcHandle * handle,BackupContent * content)529 static int recv_backup (CalcHandle* handle, BackupContent* content)
530 {
531 int ret;
532 char varname[9];
533 uint8_t attr, ver;
534
535 content->model = handle->model;
536 ticalcs_strlcpy(content->comment, tifiles_comment_set_backup(), sizeof(content->comment));
537
538 varname[0] = 0;
539 ret = SEND_REQ(handle, 0x0000, TI73_BKUP, "\0\0\0\0\0\0\0", 0x00, 0x00);
540 if (!ret)
541 {
542 ret = RECV_ACK(handle, NULL);
543 }
544 if (ret)
545 {
546 return ret;
547 }
548
549 do
550 {
551 ret = RECV_VAR(handle, &content->data_length1, &content->type, varname, &attr, &ver);
552 if (ret)
553 {
554 break;
555 }
556
557 content->data_length2 = (uint8_t)varname[0] | (((uint16_t)(uint8_t)varname[1]) << 8);
558 content->data_length3 = (uint8_t)varname[2] | (((uint16_t)(uint8_t)varname[3]) << 8);
559 content->mem_address = (uint8_t)varname[4] | (((uint16_t)(uint8_t)varname[5]) << 8);
560 content->version = ver;
561 ret = SEND_ACK(handle);
562 if (!ret)
563 {
564 ret = SEND_CTS(handle);
565 if (!ret)
566 {
567 ret = RECV_ACK(handle, NULL);
568 }
569 }
570 if (ret)
571 {
572 break;
573 }
574
575 update_->cnt2 = 0;
576 update_->max2 = 3;
577 update_->pbar();
578
579 content->data_part1 = tifiles_ve_alloc_data(65536);
580 ret = RECV_XDP(handle, &content->data_length1, content->data_part1);
581 if (!ret)
582 {
583 ret = SEND_ACK(handle);
584 }
585 if (ret)
586 {
587 break;
588 }
589 update_->cnt2++;
590 update_->pbar();
591
592 content->data_part2 = tifiles_ve_alloc_data(65536);
593 ret = RECV_XDP(handle, &content->data_length2, content->data_part2);
594 if (!ret)
595 {
596 ret = SEND_ACK(handle);
597 }
598 if (ret)
599 {
600 break;
601 }
602 update_->cnt2++;
603 update_->pbar();
604
605 content->data_part3 = tifiles_ve_alloc_data(65536);
606 ret = RECV_XDP(handle, &content->data_length3, content->data_part3);
607 if (!ret)
608 {
609 ret = SEND_ACK(handle);
610 }
611 if (ret)
612 {
613 break;
614 }
615 update_->cnt2++;
616 update_->pbar();
617
618 content->data_part4 = NULL;
619 } while(0);
620
621 return ret;
622 }
623
send_var(CalcHandle * handle,CalcMode mode,FileContent * content)624 static int send_var (CalcHandle* handle, CalcMode mode, FileContent* content)
625 {
626 int ret = 0;
627 unsigned int i;
628 uint8_t rej_code;
629 uint16_t status;
630
631 update_->cnt2 = 0;
632 update_->max2 = content->num_entries;
633
634 for (i = 0; !ret && i < content->num_entries; i++)
635 {
636 VarEntry *entry = content->entries[i];
637 uint16_t size;
638
639 if (!ticalcs_validate_varentry(entry))
640 {
641 ticalcs_critical("%s: skipping invalid content entry #%u", __FUNCTION__, i);
642 continue;
643 }
644
645 if (entry->action == ACT_SKIP)
646 {
647 ticalcs_info("%s: skipping variable #%u because requested", __FUNCTION__, i);
648 continue;
649 }
650
651 if (entry->size >= 65536U)
652 {
653 ticalcs_critical("%s: oversized variable has size %u, clamping to 65535", __FUNCTION__, entry->size);
654 size = 65535;
655 }
656 else
657 {
658 size = (uint16_t)entry->size;
659 }
660
661 ret = SEND_RTS(handle, size, entry->type, entry->name, entry->attr, entry->version);
662 if (!ret)
663 {
664 ret = RECV_ACK(handle, &status);
665 if (!ret)
666 {
667 ret = RECV_SKP(handle, &rej_code);
668 if (!ret)
669 {
670 ret = SEND_ACK(handle);
671 }
672 }
673 }
674 if (ret)
675 {
676 break;
677 }
678
679 switch (rej_code)
680 {
681 case DBUS_REJ_EXIT:
682 ret = ERR_ABORT;
683 break;
684 case DBUS_REJ_SKIP:
685 continue;
686 case DBUS_REJ_MEMORY:
687 ret = ERR_OUT_OF_MEMORY;
688 break;
689 case DBUS_REJ_VERSION:
690 ret = ERR_VAR_VERSION;
691 // Fall through.
692 case 0: // CTS
693 break;
694 default:
695 ret = ERR_VAR_REJECTED;
696 break;
697 }
698
699 if (ret)
700 {
701 break;
702 }
703
704 ticonv_varname_to_utf8_sn(handle->model, entry->name, update_->text, sizeof(update_->text), entry->type);
705 update_label();
706
707 ret = SEND_XDP(handle, size, entry->data);
708 if (!ret)
709 {
710 ret = RECV_ACK(handle, &status);
711 if (!ret)
712 {
713 ret = SEND_EOT(handle);
714 if (!ret)
715 {
716 ticalcs_info("Sent variable #%u", i);
717
718 update_->cnt2 = i+1;
719 update_->max2 = content->num_entries;
720 update_->pbar();
721 }
722 }
723 }
724 }
725
726 return ret;
727 }
728
recv_var(CalcHandle * handle,CalcMode mode,FileContent * content,VarRequest * vr)729 static int recv_var (CalcHandle* handle, CalcMode mode, FileContent* content, VarRequest* vr)
730 {
731 int ret;
732 uint16_t unused;
733 VarEntry *ve;
734 uint16_t ve_size;
735
736 content->model = handle->model;
737 ticalcs_strlcpy(content->comment, tifiles_comment_set_single(), sizeof(content->comment));
738 content->num_entries = 1;
739 content->entries = tifiles_ve_create_array(1);
740 ve = content->entries[0] = tifiles_ve_create();
741 memcpy(ve, vr, sizeof(VarEntry));
742
743 ticonv_varname_to_utf8_sn(handle->model, vr->name, update_->text, sizeof(update_->text), vr->type);
744 update_label();
745
746 do
747 {
748 // silent request
749 ret = SEND_REQ(handle, (uint16_t)vr->size, vr->type, vr->name, vr->attr, vr->version);
750 if (!ret)
751 {
752 ret = RECV_ACK(handle, &unused);
753 if (!ret)
754 {
755 ret = RECV_VAR(handle, &ve_size, &ve->type, ve->name, &ve->attr, &ve->version);
756 }
757 }
758 if (ret)
759 {
760 break;
761 }
762
763 ve->size = ve_size;
764
765 ret = SEND_ACK(handle);
766 if (!ret)
767 {
768 ret = SEND_CTS(handle);
769 if (!ret)
770 {
771 ret = RECV_ACK(handle, NULL);
772 }
773 }
774 if (ret)
775 {
776 break;
777 }
778
779 ve->data = tifiles_ve_alloc_data(ve->size);
780 ret = RECV_XDP(handle, &ve_size, ve->data);
781 if (!ret)
782 {
783 ve->size = ve_size;
784
785 if (handle->model != CALC_TI73 && ve->type == TI83p_PIC)
786 {
787 if (ve->version >= 0xA)
788 {
789 content->model = CALC_TI84PC;
790 }
791 else
792 {
793 content->model = CALC_TI83P;
794 }
795 }
796
797 ret = SEND_ACK(handle);
798 }
799 } while(0);
800
801 return ret;
802 }
803
804 static int get_version (CalcHandle* handle, CalcInfos* infos);
805
send_flash(CalcHandle * handle,FlashContent * content)806 static int send_flash (CalcHandle* handle, FlashContent* content)
807 {
808 int ret;
809 FlashContent *ptr;
810 unsigned int i, j;
811 uint16_t size;
812 int cpu15mhz = 0;
813
814 // search for data header
815 for (ptr = content; ptr != NULL; ptr = ptr->next)
816 {
817 if (ptr->data_type == TI83p_AMS || ptr->data_type == TI83p_APPL)
818 {
819 break;
820 }
821 }
822 if (ptr == NULL)
823 {
824 return -1;
825 }
826
827 if (ptr->data_type == TI83p_AMS)
828 {
829 size = 0x100;
830 }
831 else if (ptr->data_type == TI83p_APPL)
832 {
833 size = 0x80;
834 }
835 else
836 {
837 return -1;
838 }
839
840 // check for 83+ Silver Edition (not usable in boot mode, sic!)
841 if (handle->model != CALC_TI73 && ptr->data_type == TI83p_APPL)
842 {
843 CalcInfos infos;
844
845 ret = get_version(handle, &infos);
846 if (ret)
847 {
848 return ret;
849 }
850 cpu15mhz = infos.hw_version & 1;
851
852 if (!infos.battery)
853 {
854 ticalcs_info(_("Battery low, stopping flash app transfer"));
855 return -1;
856 }
857 }
858
859 ticalcs_info(_("FLASH name: \"%s\""), ptr->name);
860 ticalcs_info(_("FLASH size: %i bytes."), ptr->data_length);
861
862 ticonv_varname_to_utf8_sn(handle->model, ptr->name, update_->text, sizeof(update_->text), ptr->data_type);
863 update_label();
864
865 update_->cnt2 = 0;
866 update_->max2 = ptr->data_length;
867
868 for (i = 0; !ret && i < ptr->num_pages; i++)
869 {
870 FlashPage *fp = ptr->pages[i];
871
872 if ((ptr->data_type == TI83p_AMS) && (i == 1)) // need relocation ?
873 {
874 fp->addr = 0x4000;
875 }
876
877 for (j = 0; !ret && j < fp->size; j += size)
878 {
879 uint16_t addr = fp->addr + j;
880 uint8_t* data = fp->data + j;
881
882 ret = SEND_VAR2(handle, size, ptr->data_type, fp->flag, addr, fp->page);
883 if (!ret)
884 {
885 ret = RECV_ACK(handle, NULL);
886 }
887 if (ret)
888 {
889 break;
890 }
891
892 if (handle->model == CALC_TI73 && ptr->data_type == TI83p_APPL)
893 {
894 ret = RECV_CTS(handle, 0);
895 } // Depends on OS version?
896 else
897 {
898 ret = RECV_CTS(handle, 10);
899 }
900 if (!ret)
901 {
902 ret = SEND_ACK(handle);
903 if (!ret)
904 {
905 ret = SEND_XDP(handle, size, data);
906 if (!ret)
907 {
908 ret = RECV_ACK(handle, NULL);
909 if (!ret)
910 {
911 update_->cnt2 += size;
912 update_->pbar();
913 }
914 }
915 }
916 }
917 }
918
919 /* Note:
920 TI83+SE, TI84+ and TI84+SE don't need a pause (otherwise transfer fails).
921 TI73 and TI83+ need a pause (otherwise transfer fails).
922 Delay also causes OS transfers to fail on the 15Mhz calcs and unneeded for OS's
923 */
924 if (!ret && !cpu15mhz && ptr->data_type == TI83p_APPL)
925 {
926 if (i == 1)
927 {
928 PAUSE(1000); // This pause is NEEDED !
929 }
930 if (i == ptr->num_pages - 2)
931 {
932 PAUSE(2500); // This pause is NEEDED !
933 }
934 }
935 }
936
937 if (!ret)
938 {
939 ret = SEND_EOT(handle);
940 if (!ret)
941 {
942 ret = RECV_ACK(handle, NULL);
943 }
944 }
945
946 return ret;
947 }
948
recv_flash(CalcHandle * handle,FlashContent * content,VarRequest * vr)949 static int recv_flash (CalcHandle* handle, FlashContent* content, VarRequest* vr)
950 {
951 int ret;
952 FlashPage *fp;
953 uint16_t data_addr;
954 uint16_t old_page = 0;
955 uint16_t data_page;
956 uint16_t data_length;
957 uint8_t data_type;
958 uint32_t size;
959 int first_block;
960 int page;
961 int offset;
962 uint8_t buffer[FLASH_PAGE_SIZE + 4];
963
964 ticonv_varname_to_utf8_sn(handle->model, vr->name, update_->text, sizeof(update_->text), vr->type);
965 update_label();
966
967 content->model = handle->model;
968 ticalcs_strlcpy(content->name, vr->name, sizeof(content->name));
969 content->data_type = vr->type;
970 content->device_type = handle->model == CALC_TI73 ? DEVICE_TYPE_73 : DEVICE_TYPE_83P;
971 content->num_pages = 2048; // TI83+ has 512 KB of FLASH max
972 content->pages = tifiles_fp_create_array(content->num_pages);
973
974 page = 0;
975 fp = content->pages[page] = tifiles_fp_create();
976
977 ret = SEND_REQ2(handle, 0x00, TI73_APPL, vr->name, 0x00);
978 if (!ret)
979 {
980 ret = RECV_ACK(handle, NULL);
981 }
982 if (ret)
983 {
984 return ret;
985 }
986
987 update_->cnt2 = 0;
988 update_->max2 = vr->size;
989
990 for (size = 0, first_block = 1, offset = 0; !ret;)
991 {
992 char name[9];
993 int ret2;
994
995 ret = RECV_VAR2(handle, &data_length, &data_type, name, &data_addr, &data_page);
996 ret2 = SEND_ACK(handle);
997 if (ret)
998 {
999 if (ret == ERR_EOT)
1000 {
1001 ret = 0;
1002 }
1003 break;
1004 }
1005 if (ret2)
1006 {
1007 ret = ret2;
1008 break;
1009 }
1010
1011 if (first_block)
1012 {
1013 old_page = data_page;
1014
1015 fp->addr = data_addr & 0x4000;
1016 fp->page = data_page;
1017 }
1018 if (old_page != data_page)
1019 {
1020 fp->addr = data_addr & 0x4000;
1021 fp->page = old_page;
1022 fp->flag = 0x80;
1023 fp->size = offset;
1024 fp->data = tifiles_fp_alloc_data(FLASH_PAGE_SIZE);
1025 memcpy(fp->data, buffer, fp->size);
1026
1027 page++;
1028 offset = 0;
1029 old_page = data_page;
1030
1031 fp = content->pages[page] = tifiles_fp_create();
1032 }
1033
1034 ret = SEND_CTS(handle);
1035 if (!ret)
1036 {
1037 ret = RECV_ACK(handle, NULL);
1038 if (!ret)
1039 {
1040 ret = RECV_XDP(handle, &data_length, &buffer[offset]);
1041 if (!ret)
1042 {
1043 ret = SEND_ACK(handle);
1044 }
1045 }
1046 }
1047 if (ret)
1048 {
1049 break;
1050 }
1051
1052 if (first_block)
1053 {
1054 first_block = 0;
1055
1056 /* compute actual application size */
1057 if (buffer[0] == 0x80 && buffer[1] == 0x0f)
1058 {
1059 uint32_t len = ((uint32_t)(buffer[2])) << 24 | ((uint32_t)(buffer[3])) << 16 | ((uint32_t)(buffer[4])) << 8 | (uint32_t)(buffer[5]);
1060 update_->max2 = len + 75;
1061 }
1062 }
1063
1064 size += data_length;
1065 offset += data_length;
1066
1067 update_->cnt2 = size;
1068 update_->pbar();
1069 }
1070
1071 fp->addr = data_addr & 0x4000;
1072 fp->page = old_page;
1073 fp->flag = 0x80;
1074 fp->size = offset;
1075 fp->data = tifiles_fp_alloc_data(FLASH_PAGE_SIZE);
1076 memcpy(fp->data, buffer, fp->size);
1077 page++;
1078
1079 content->num_pages = page;
1080
1081 return ret;
1082 }
1083
recv_idlist(CalcHandle * handle,uint8_t * id)1084 static int recv_idlist (CalcHandle* handle, uint8_t* id)
1085 {
1086 int ret;
1087 uint16_t unused;
1088 uint16_t varsize;
1089 uint8_t vartype;
1090 char varname[9];
1091 uint8_t varattr;
1092 uint8_t version;
1093 uint8_t data[16];
1094 int i;
1095
1096 ticalcs_strlcpy(update_->text, "ID-LIST", sizeof(update_->text));
1097 update_label();
1098
1099 ret = SEND_REQ(handle, 0x0000, TI73_IDLIST, "\0\0\0\0\0\0\0", 0x00, 0x00);
1100 if (!ret)
1101 {
1102 ret = RECV_ACK(handle, &unused);
1103 if (!ret)
1104 {
1105 ret = RECV_VAR(handle, &varsize, &vartype, varname, &varattr, &version);
1106 if (!ret)
1107 {
1108 ret = SEND_ACK(handle);
1109 if (!ret)
1110 {
1111 ret = SEND_CTS(handle);
1112 if (!ret)
1113 {
1114 ret = RECV_ACK(handle, NULL);
1115 if (!ret)
1116 {
1117 ret = RECV_XDP(handle, &varsize, data);
1118 if (!ret)
1119 {
1120 ret = SEND_ACK(handle);
1121 if (!ret)
1122 {
1123 i = data[9];
1124 data[9] = data[10];
1125 data[10] = i;
1126
1127 for (i = 4; i < varsize; i++)
1128 {
1129 sprintf((char *)&id[2 * (i-4)], "%02x", data[i]);
1130 }
1131 id[7*2] = '\0';
1132 }
1133 }
1134 }
1135 }
1136 }
1137 }
1138 }
1139 }
1140
1141 return ret;
1142 }
1143
dump_rom_1(CalcHandle * handle)1144 static int dump_rom_1 (CalcHandle* handle)
1145 {
1146 // Send dumping program
1147 if (handle->model == CALC_TI73)
1148 {
1149 return rd_send(handle, "romdump.73p", romDumpSize73, romDump73);
1150 }
1151 else
1152 {
1153 CalcInfos infos;
1154
1155 int ret = get_version(handle, &infos);
1156 if (!ret)
1157 {
1158 if (infos.hw_version < 5)
1159 {
1160 ret = rd_send(handle, "romdump.8Xp", romDumpSize8Xp, romDump8Xp);
1161 }
1162 else
1163 {
1164 ret = rd_send(handle, "romdump.8Xp", romDumpSize84pc, romDump84pc);
1165 }
1166 }
1167
1168 return ret;
1169 }
1170 }
1171
dump_rom_2(CalcHandle * handle,CalcDumpSize size,const char * filename)1172 static int dump_rom_2 (CalcHandle* handle, CalcDumpSize size, const char *filename)
1173 {
1174 static const uint16_t keys_83p[] = {
1175 0x40, 0x09, 0x09, 0xFC9C, /* Quit, Clear, Clear, Asm( */
1176 0xDA, 0xAB, 0xA8, 0xA6, /* prgm, R, O, M */
1177 0x9D, 0xAE, 0xA6, 0xA9, /* D, U, M, P */
1178 0x86, 0x05 }; /* ), Enter */
1179
1180 static const uint16_t keys_73[] = {
1181 0x40, 0x09, 0x09, 0xDA, /* Quit, Clear, Clear, prgm */
1182 0xAB, 0xA8, 0xA6, 0x9D, /* R, O, M, D, */
1183 0xAE, 0xA6, 0xA9, 0x05 }; /* U, M, P, Enter */
1184
1185 int ret = 0;
1186 const uint16_t *keys;
1187 unsigned int i, nkeys;
1188
1189 if (handle->model == CALC_TI73)
1190 {
1191 keys = keys_73;
1192 nkeys = sizeof(keys_73) / sizeof(keys_73[0]);
1193 }
1194 else
1195 {
1196 keys = keys_83p;
1197 nkeys = sizeof(keys_83p) / sizeof(keys_83p[0]);
1198 }
1199
1200 // Launch program by remote control
1201 PAUSE(200);
1202 for (i = 0; !ret && i < nkeys - 1; i++)
1203 {
1204 ret = send_key(handle, (uint32_t)(keys[i]));
1205 PAUSE(100);
1206 }
1207
1208 if (!ret)
1209 {
1210 // This fixes a 100% reproducible timeout: send_key normally requests an ACK,
1211 // but when the program is running, no ACK is sent. Therefore, hit the Enter key
1212 // without requesting an ACK.
1213 ret = SEND_KEY(handle, keys[i]);
1214 if (!ret)
1215 {
1216 ret = RECV_ACK(handle, NULL); // when the key is received
1217 if (!ret)
1218 {
1219 PAUSE(1000);
1220
1221 // Get dump
1222 // (Normally there would be another ACK after the program exits,
1223 // but the ROM dumper disables that behavior)
1224 ret = rd_dump(handle, filename);
1225 }
1226 }
1227 }
1228
1229 return ret;
1230 }
1231
set_clock(CalcHandle * handle,CalcClock * _clock)1232 static int set_clock (CalcHandle* handle, CalcClock* _clock)
1233 {
1234 int ret;
1235 uint8_t buffer[9];
1236 uint32_t calc_time;
1237
1238 struct tm ref, cur;
1239 time_t r, c, now;
1240
1241 time(&now); // retrieve current DST setting
1242 memcpy(&ref, localtime(&now), sizeof(struct tm));
1243
1244 ref.tm_year = 1997 - 1900;
1245 ref.tm_mon = 0;
1246 ref.tm_yday = 0;
1247 ref.tm_mday = 1;
1248 ref.tm_wday = 3;
1249 ref.tm_hour = 0;
1250 ref.tm_min = 0;
1251 ref.tm_sec = 0;
1252 //ref.tm_isdst = 1;
1253 r = mktime(&ref);
1254 //printf("%s\n", asctime(&ref));
1255
1256 cur.tm_year = _clock->year - 1900;
1257 cur.tm_mon = _clock->month - 1;
1258 cur.tm_mday = _clock->day;
1259 cur.tm_hour = _clock->hours;
1260 cur.tm_min = _clock->minutes;
1261 cur.tm_sec = _clock->seconds;
1262 cur.tm_isdst = 1;
1263 c = mktime(&cur);
1264 //printf("%s\n", asctime(&cur));
1265
1266 calc_time = (uint32_t)difftime(c, r);
1267
1268 buffer[0] = 0;
1269 buffer[1] = 0;
1270 buffer[2] = MSB(MSW(calc_time));
1271 buffer[3] = LSB(MSW(calc_time));
1272 buffer[4] = MSB(LSW(calc_time));
1273 buffer[5] = LSB(LSW(calc_time));
1274 buffer[6] = _clock->date_format;
1275 buffer[7] = _clock->time_format;
1276 buffer[8] = 0xff;
1277
1278 ticalcs_strlcpy(update_->text, _("Setting clock..."), sizeof(update_->text));
1279 update_label();
1280
1281 ret = SEND_RTS(handle, 13, TI73_CLK, "\0x08\0\0\0\0\0\0\0", 0x00, 0x00);
1282 if (!ret)
1283 {
1284 ret = RECV_ACK(handle, NULL);
1285 if (!ret)
1286 {
1287 ret = RECV_CTS(handle, 13);
1288 if (!ret)
1289 {
1290 ret = SEND_ACK(handle);
1291 if (!ret)
1292 {
1293 ret = SEND_XDP(handle, 9, buffer);
1294 if (!ret)
1295 {
1296 ret = RECV_ACK(handle, NULL);
1297 if (!ret)
1298 {
1299 ret = SEND_EOT(handle);
1300 }
1301 }
1302 }
1303 }
1304 }
1305 }
1306
1307 return ret;
1308 }
1309
get_clock(CalcHandle * handle,CalcClock * _clock)1310 static int get_clock (CalcHandle* handle, CalcClock* _clock)
1311 {
1312 int ret;
1313 uint16_t varsize;
1314 uint8_t vartype;
1315 uint8_t varattr;
1316 uint8_t version;
1317 char varname[9];
1318 uint8_t * buffer = handle->buffer2;
1319 uint32_t calc_time;
1320
1321 struct tm ref, *cur;
1322 time_t r, c, now;
1323
1324 ticalcs_strlcpy(update_->text, _("Getting clock..."), sizeof(update_->text));
1325 update_label();
1326
1327 ret = SEND_REQ(handle, 0x0000, TI73_CLK, "\0x08\0\0\0\0\0\0\0", 0x00, 0x00);
1328 if (!ret)
1329 {
1330 ret = RECV_ACK(handle, NULL);
1331 if (!ret)
1332 {
1333 ret = RECV_VAR(handle, &varsize, &vartype, varname, &varattr, &version);
1334 if (!ret)
1335 {
1336 ret = SEND_ACK(handle);
1337 if (!ret)
1338 {
1339 ret = SEND_CTS(handle);
1340 if (!ret)
1341 {
1342 ret = RECV_ACK(handle, NULL);
1343 if (!ret)
1344 {
1345 ret = RECV_XDP(handle, &varsize, buffer);
1346 if (!ret)
1347 {
1348 ret = SEND_ACK(handle);
1349 }
1350 }
1351 }
1352 }
1353 }
1354 }
1355 }
1356
1357 if (!ret)
1358 {
1359 calc_time = (((uint32_t)(buffer[2])) << 24) | (((uint32_t)(buffer[3])) << 16) | (((uint32_t)(buffer[4])) << 8) | (uint32_t)(buffer[5]);
1360 //printf("<%08x>\n", time);
1361
1362 time(&now); // retrieve current DST setting
1363 memcpy(&ref, localtime(&now), sizeof(struct tm));;
1364 ref.tm_year = 1997 - 1900;
1365 ref.tm_mon = 0;
1366 ref.tm_yday = 0;
1367 ref.tm_mday = 1;
1368 ref.tm_wday = 3;
1369 ref.tm_hour = 0;
1370 ref.tm_min = 0;
1371 ref.tm_sec = 0;
1372 //ref.tm_isdst = 1;
1373 r = mktime(&ref);
1374 //printf("%s\n", asctime(&ref));
1375
1376 c = r + calc_time;
1377 cur = localtime(&c);
1378 //printf("%s\n", asctime(cur));
1379
1380 _clock->year = cur->tm_year + 1900;
1381 _clock->month = cur->tm_mon + 1;
1382 _clock->day = cur->tm_mday;
1383 _clock->hours = cur->tm_hour;
1384 _clock->minutes = cur->tm_min;
1385 _clock->seconds = cur->tm_sec;
1386
1387 _clock->date_format = buffer[6];
1388 _clock->time_format = buffer[7];
1389 }
1390
1391 return ret;
1392 }
1393
del_var(CalcHandle * handle,VarRequest * vr)1394 static int del_var (CalcHandle* handle, VarRequest* vr)
1395 {
1396 int ret;
1397 char *utf8;
1398
1399 utf8 = ticonv_varname_to_utf8(handle->model, vr->name, vr->type);
1400 ticalcs_slprintf(update_->text, sizeof(update_->text), _("Deleting %s..."), utf8);
1401 ticonv_utf8_free(utf8);
1402 update_label();
1403
1404 ret = SEND_DEL(handle, (uint16_t)vr->size, vr->type, vr->name, vr->attr);
1405 if (!ret)
1406 {
1407 ret = RECV_ACK(handle, NULL);
1408 if (!ret)
1409 {
1410 ret = RECV_ACK(handle, NULL);
1411 }
1412 }
1413
1414 return ret;
1415 }
1416
get_version(CalcHandle * handle,CalcInfos * infos)1417 static int get_version (CalcHandle* handle, CalcInfos* infos)
1418 {
1419 int ret;
1420 uint16_t length;
1421 uint8_t buf[32];
1422
1423 ret = SEND_VER(handle);
1424 if (!ret)
1425 {
1426 ret = RECV_ACK(handle, NULL);
1427 if (!ret)
1428 {
1429 ret = SEND_CTS(handle);
1430 if (!ret)
1431 {
1432 ret = RECV_ACK(handle, NULL);
1433 if (!ret)
1434 {
1435 ret = RECV_XDP(handle, &length, buf);
1436 if (!ret)
1437 {
1438 ret = SEND_ACK(handle);
1439 }
1440 }
1441 }
1442 }
1443 }
1444
1445 if (!ret)
1446 {
1447 memset(infos, 0, sizeof(CalcInfos));
1448 if (handle->model == CALC_TI73)
1449 {
1450 ticalcs_slprintf(infos->os_version, sizeof(infos->os_version), "%1x.%02x", buf[0], buf[1]);
1451 ticalcs_slprintf(infos->boot_version, sizeof(infos->boot_version), "%1x.%02x", buf[2], buf[3]);
1452 }
1453 else
1454 {
1455 ticalcs_slprintf(infos->os_version, sizeof(infos->os_version), "%1i.%02i", buf[0], buf[1]);
1456 ticalcs_slprintf(infos->boot_version, sizeof(infos->boot_version), "%1i.%02i", buf[2], buf[3]);
1457 }
1458 infos->battery = (buf[4] & 1) ? 0 : 1;
1459 infos->hw_version = buf[5];
1460 switch(buf[5])
1461 {
1462 case 0: infos->model = CALC_TI83P; break;
1463 case 1: infos->model = CALC_TI83P; break;
1464 case 2: infos->model = CALC_TI84P; break;
1465 case 3: infos->model = CALC_TI84P; break;
1466 case 5: infos->model = CALC_TI84PC; break;
1467 default: infos->model = CALC_TI84PC; break; // If new models ever arise, they'll probably be 84+CSE or newer anyway.
1468 }
1469 infos->language_id = buf[6];
1470 infos->sub_lang_id = buf[7];
1471 infos->mask = INFOS_BOOT_VERSION | INFOS_OS_VERSION | INFOS_BATTERY | INFOS_HW_VERSION | INFOS_CALC_MODEL | INFOS_LANG_ID | INFOS_SUB_LANG_ID;
1472
1473 tifiles_hexdump(buf, length);
1474 ticalcs_info(_(" OS: %s"), infos->os_version);
1475 ticalcs_info(_(" BIOS: %s"), infos->boot_version);
1476 ticalcs_info(_(" HW: %i"), infos->hw_version);
1477 ticalcs_info(_(" Battery: %s"), infos->battery ? _("good") : _("low"));
1478 }
1479
1480 return ret;
1481 }
1482
send_cert(CalcHandle * handle,FlashContent * content)1483 static int send_cert (CalcHandle* handle, FlashContent* content)
1484 {
1485 int ret = 0;
1486 FlashContent *ptr;
1487 int i, nblocks;
1488 uint16_t size = 0xE8;
1489
1490 // search for cert header
1491 for (ptr = content; ptr != NULL; ptr = ptr->next)
1492 {
1493 if (ptr->data_type == TI83p_CERT)
1494 {
1495 break;
1496 }
1497 }
1498
1499 if (ptr != NULL)
1500 {
1501 // send content
1502 ticalcs_info(_("FLASH name: \"%s\""), ptr->name);
1503 ticalcs_info(_("FLASH size: %i bytes."), ptr->data_length);
1504
1505 nblocks = ptr->data_length / size;
1506 update_->max2 = nblocks;
1507
1508 ret = SEND_VAR2(handle, size, ptr->data_type, 0x04, 0x4000, 0x00);
1509 if (!ret)
1510 {
1511 ret = RECV_ACK(handle, NULL);
1512 if (!ret)
1513 {
1514 ret = RECV_CTS(handle, 10);
1515 if (!ret)
1516 {
1517 ret = SEND_ACK(handle);
1518 }
1519 }
1520 }
1521
1522 for (i = 0; !ret && i <= nblocks; i++)
1523 {
1524 uint16_t length = size;
1525
1526 ret = SEND_XDP(handle, length, (ptr->data_part) + length * i);
1527 if (!ret)
1528 {
1529 ret = RECV_ACK(handle, NULL);
1530 if (!ret)
1531 {
1532 ret = RECV_CTS(handle, size);
1533 if (!ret)
1534 {
1535 ret = SEND_ACK(handle);
1536 if (!ret)
1537 {
1538 update_->cnt2 = i;
1539 update_->pbar();
1540 }
1541 }
1542 }
1543 }
1544 }
1545
1546 if (!ret)
1547 {
1548 ret = SEND_EOT(handle);
1549 ticalcs_info(_("Header sent completely."));
1550 }
1551 }
1552
1553 return ret;
1554 }
1555
recv_cert(CalcHandle * handle,FlashContent * content)1556 static int recv_cert (CalcHandle* handle, FlashContent* content)
1557 {
1558 int ret;
1559 int i;
1560 uint8_t buf[256];
1561
1562 ticalcs_strlcpy(update_->text, _("Receiving certificate"), sizeof(update_->text));
1563 update_label();
1564
1565 content->model = handle->model;
1566 content->name[0] = 0;
1567 content->data_type = TI83p_CERT;
1568 content->device_type = 0x73;
1569 content->num_pages = 0;
1570 content->data_part = (uint8_t *)tifiles_ve_alloc_data(2 * 1024 * 1024); // 2MB max
1571
1572 ret = SEND_REQ2(handle, 0x00, TI83p_GETCERT, "\0\0\0\0\0\0\0", 0x00);
1573 if (!ret)
1574 {
1575 ret = RECV_ACK(handle, NULL);
1576 if (!ret)
1577 {
1578 ret = ticables_cable_recv(handle->cable, buf, 4); //VAR w/ no header
1579 if (!ret)
1580 {
1581 ticalcs_info(" TI->PC: VAR");
1582 ret = SEND_ACK(handle);
1583
1584 for (i = 0, content->data_length = 0; !ret; i++)
1585 {
1586 uint16_t block_size;
1587
1588 ret = SEND_CTS(handle);
1589 if (!ret)
1590 {
1591 ret = RECV_ACK(handle, NULL);
1592 if (!ret)
1593 {
1594 ret = RECV_XDP(handle, &block_size, content->data_part);
1595 if (!ret)
1596 {
1597 ret = SEND_ACK(handle);
1598 if (!ret)
1599 {
1600 content->data_length += block_size;
1601
1602 update_->cnt2 += block_size;
1603 update_->pbar();
1604 }
1605 }
1606 }
1607 }
1608 }
1609 }
1610 }
1611 }
1612
1613 return ret;
1614 }
1615
1616 const CalcFncts calc_73 =
1617 {
1618 CALC_TI73,
1619 "TI73",
1620 "TI-73",
1621 "TI-73",
1622 OPS_ISREADY | OPS_KEYS | OPS_SCREEN | OPS_DIRLIST | OPS_BACKUP | OPS_VARS |
1623 OPS_FLASH | OPS_IDLIST | OPS_ROMDUMP | OPS_VERSION | OPS_OS |
1624 FTS_SILENT | FTS_MEMFREE | FTS_FLASH | FTS_BACKUP,
1625 PRODUCT_ID_TI73,
1626 {"", /* is_ready */
1627 "", /* send_key */
1628 "", /* execute */
1629 "1P", /* recv_screen */
1630 "1L", /* get_dirlist */
1631 "", /* get_memfree */
1632 "2P", /* send_backup */
1633 "2P", /* recv_backup */
1634 "2P1L", /* send_var */
1635 "1P1L", /* recv_var */
1636 "2P1L", /* send_var_ns */
1637 "1P1L", /* recv_var_ns */
1638 "2P1L", /* send_app */
1639 "2P1L", /* recv_app */
1640 "2P", /* send_os */
1641 "1L", /* recv_idlist */
1642 "2P", /* dump_rom_1 */
1643 "2P", /* dump_rom_2 */
1644 "", /* set_clock */
1645 "", /* get_clock */
1646 "1L", /* del_var */
1647 "1L", /* new_folder */
1648 "", /* get_version */
1649 "1L", /* send_cert */
1650 "1L", /* recv_cert */
1651 "", /* rename */
1652 "", /* chattr */
1653 "", /* send_all_vars_backup */
1654 "" /* recv_all_vars_backup */ },
1655 &is_ready,
1656 &send_key,
1657 &execute,
1658 &recv_screen,
1659 &get_dirlist,
1660 &get_memfree,
1661 &send_backup,
1662 &recv_backup,
1663 &send_var,
1664 &recv_var,
1665 &noop_send_var_ns,
1666 &noop_recv_var_ns,
1667 &send_flash,
1668 &recv_flash,
1669 &send_flash,
1670 &recv_idlist,
1671 &dump_rom_1,
1672 &dump_rom_2,
1673 &set_clock,
1674 &get_clock,
1675 &del_var,
1676 &noop_new_folder,
1677 &get_version,
1678 &send_cert,
1679 &recv_cert,
1680 &noop_rename_var,
1681 &noop_change_attr,
1682 &noop_send_all_vars_backup,
1683 &noop_recv_all_vars_backup
1684 };
1685
1686 const CalcFncts calc_83p =
1687 {
1688 CALC_TI83P,
1689 "TI83+",
1690 "TI-83 Plus",
1691 "TI-83 Plus",
1692 OPS_ISREADY | OPS_KEYS | OPS_SCREEN | OPS_DIRLIST | OPS_BACKUP | OPS_VARS |
1693 OPS_FLASH | OPS_IDLIST | OPS_ROMDUMP | OPS_DELVAR | OPS_VERSION | OPS_OS |
1694 FTS_SILENT | FTS_MEMFREE | FTS_FLASH | FTS_CERT | FTS_BACKUP,
1695 PRODUCT_ID_TI83P,
1696 {"", /* is_ready */
1697 "", /* send_key */
1698 "", /* execute */
1699 "1P", /* recv_screen */
1700 "1L", /* get_dirlist */
1701 "", /* get_memfree */
1702 "2P", /* send_backup */
1703 "2P", /* recv_backup */
1704 "2P1L", /* send_var */
1705 "1P1L", /* recv_var */
1706 "2P1L", /* send_var_ns */
1707 "1P1L", /* recv_var_ns */
1708 "2P1L", /* send_app */
1709 "2P1L", /* recv_app */
1710 "2P", /* send_os */
1711 "1L", /* recv_idlist */
1712 "2P", /* dump_rom_1 */
1713 "2P", /* dump_rom_2 */
1714 "", /* set_clock */
1715 "", /* get_clock */
1716 "1L", /* del_var */
1717 "1L", /* new_folder */
1718 "", /* get_version */
1719 "1L", /* send_cert */
1720 "1L", /* recv_cert */
1721 "", /* rename */
1722 "", /* chattr */
1723 "", /* send_all_vars_backup */
1724 "" /* recv_all_vars_backup */ },
1725 &is_ready,
1726 &send_key,
1727 &execute,
1728 &recv_screen,
1729 &get_dirlist,
1730 &get_memfree,
1731 &send_backup,
1732 &recv_backup,
1733 &send_var,
1734 &recv_var,
1735 &noop_send_var_ns,
1736 &noop_recv_var_ns,
1737 &send_flash,
1738 &recv_flash,
1739 &send_flash,
1740 &recv_idlist,
1741 &dump_rom_1,
1742 &dump_rom_2,
1743 &set_clock,
1744 &get_clock,
1745 &del_var,
1746 &noop_new_folder,
1747 &get_version,
1748 &send_cert,
1749 &recv_cert,
1750 &noop_rename_var,
1751 &noop_change_attr,
1752 &noop_send_all_vars_backup,
1753 &noop_recv_all_vars_backup
1754 };
1755
1756 const CalcFncts calc_84p =
1757 {
1758 CALC_TI84P,
1759 "TI84+",
1760 "TI-84 Plus",
1761 "TI-84 Plus",
1762 OPS_ISREADY | OPS_KEYS | OPS_SCREEN | OPS_DIRLIST | OPS_BACKUP | OPS_VARS |
1763 OPS_FLASH | OPS_IDLIST | OPS_ROMDUMP | OPS_CLOCK | OPS_DELVAR | OPS_VERSION | OPS_OS |
1764 FTS_SILENT | FTS_MEMFREE | FTS_FLASH | FTS_CERT | FTS_BACKUP,
1765 PRODUCT_ID_TI84P,
1766 {"", /* is_ready */
1767 "", /* send_key */
1768 "", /* execute */
1769 "1P", /* recv_screen */
1770 "1L", /* get_dirlist */
1771 "", /* get_memfree */
1772 "2P", /* send_backup */
1773 "2P", /* recv_backup */
1774 "2P1L", /* send_var */
1775 "1P1L", /* recv_var */
1776 "2P1L", /* send_var_ns */
1777 "1P1L", /* recv_var_ns */
1778 "2P1L", /* send_app */
1779 "2P1L", /* recv_app */
1780 "2P", /* send_os */
1781 "1L", /* recv_idlist */
1782 "2P", /* dump_rom_1 */
1783 "2P", /* dump_rom_2 */
1784 "", /* set_clock */
1785 "", /* get_clock */
1786 "1L", /* del_var */
1787 "1L", /* new_folder */
1788 "", /* get_version */
1789 "1L", /* send_cert */
1790 "1L", /* recv_cert */
1791 "", /* rename */
1792 "", /* chattr */
1793 "", /* send_all_vars_backup */
1794 "" /* recv_all_vars_backup */ },
1795 &is_ready,
1796 &send_key,
1797 &execute,
1798 &recv_screen,
1799 &get_dirlist,
1800 &get_memfree,
1801 &send_backup,
1802 &recv_backup,
1803 &send_var,
1804 &recv_var,
1805 &noop_send_var_ns,
1806 &noop_recv_var_ns,
1807 &send_flash,
1808 &recv_flash,
1809 &send_flash,
1810 &recv_idlist,
1811 &dump_rom_1,
1812 &dump_rom_2,
1813 &set_clock,
1814 &get_clock,
1815 &del_var,
1816 &noop_new_folder,
1817 &get_version,
1818 &send_cert,
1819 &recv_cert,
1820 &noop_rename_var,
1821 &noop_change_attr,
1822 &noop_send_all_vars_backup,
1823 &noop_recv_all_vars_backup
1824 };
1825
1826 const CalcFncts calc_84pcse =
1827 {
1828 CALC_TI84PC,
1829 "TI84+CSE",
1830 "TI-84 Plus Color Silver Edition",
1831 "TI-84 Plus Color Silver Edition",
1832 OPS_ISREADY | OPS_KEYS | OPS_SCREEN | OPS_DIRLIST | OPS_BACKUP | OPS_VARS |
1833 OPS_FLASH | OPS_IDLIST | OPS_ROMDUMP | OPS_CLOCK | OPS_DELVAR | OPS_VERSION | OPS_OS |
1834 FTS_SILENT | FTS_MEMFREE | FTS_FLASH | FTS_CERT | FTS_BACKUP,
1835 PRODUCT_ID_TI84PCSE,
1836 {"", /* is_ready */
1837 "", /* send_key */
1838 "", /* execute */
1839 "1P", /* recv_screen */
1840 "1L", /* get_dirlist */
1841 "", /* get_memfree */
1842 "2P", /* send_backup */
1843 "2P", /* recv_backup */
1844 "2P1L", /* send_var */
1845 "1P1L", /* recv_var */
1846 "2P1L", /* send_var_ns */
1847 "1P1L", /* recv_var_ns */
1848 "2P1L", /* send_app */
1849 "2P1L", /* recv_app */
1850 "2P", /* send_os */
1851 "1L", /* recv_idlist */
1852 "2P", /* dump_rom_1 */
1853 "2P", /* dump_rom_2 */
1854 "", /* set_clock */
1855 "", /* get_clock */
1856 "1L", /* del_var */
1857 "1L", /* new_folder */
1858 "", /* get_version */
1859 "1L", /* send_cert */
1860 "1L", /* recv_cert */
1861 "", /* rename */
1862 "", /* chattr */
1863 "", /* send_all_vars_backup */
1864 "" /* recv_all_vars_backup */ },
1865 &is_ready,
1866 &send_key,
1867 &execute,
1868 &recv_screen,
1869 &get_dirlist,
1870 &get_memfree,
1871 &send_backup,
1872 &recv_backup,
1873 &send_var,
1874 &recv_var,
1875 &noop_send_var_ns,
1876 &noop_recv_var_ns,
1877 &send_flash,
1878 &recv_flash,
1879 &send_flash,
1880 &recv_idlist,
1881 &dump_rom_1,
1882 &dump_rom_2,
1883 &set_clock,
1884 &get_clock,
1885 &del_var,
1886 &noop_new_folder,
1887 &get_version,
1888 &send_cert,
1889 &recv_cert,
1890 &noop_rename_var,
1891 &noop_change_attr,
1892 &noop_send_all_vars_backup,
1893 &noop_recv_all_vars_backup
1894 };
1895