1 /* Hey EMACS -*- linux-c -*- */
2
3 /* libticalcs - Ti Calculator library, a part of the TiLP project
4 * Copyright (C) 1999-2005 Romain Liévin
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software Foundation,
18 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19 */
20
21 /*
22 This unit handles:
23 * TI-92 commands;
24 * TI-89/92+/V200/89T commands.
25 */
26
27 #include <stdio.h>
28 #include <string.h>
29
30 #include "ticalcs.h"
31 #include "internal.h"
32 #include "dbus_pkt.h"
33 #include "error.h"
34 #include "logging.h"
35 #include "cmd68k.h"
36
37 #ifdef _MSC_VER
38 #pragma warning( disable : 4761 4244)
39 #endif
40
ti68k_handle_to_dbus_mid(CalcHandle * handle)41 TIEXPORT3 uint8_t TICALL ti68k_handle_to_dbus_mid(CalcHandle * handle)
42 {
43 if (ticalcs_validate_handle(handle))
44 {
45 switch (handle->model)
46 {
47 case CALC_TI89:
48 case CALC_TI89T:
49 return DBUS_MID_PC_TI89;
50 case CALC_TI92:
51 return DBUS_MID_PC_TI92;
52 case CALC_TI92P:
53 return DBUS_MID_PC_TI92p;
54 case CALC_V200:
55 return DBUS_MID_PC_V200;
56 default:
57 return DBUS_MID_PC_TIXX;
58 }
59 }
60 return 0;
61 }
62
ti68k_send_simple_cmd(CalcHandle * handle,uint8_t target,uint8_t cmd,const char * cmdname,uint16_t length,const uint8_t * data)63 static inline int ti68k_send_simple_cmd(CalcHandle * handle, uint8_t target, uint8_t cmd, const char * cmdname, uint16_t length, const uint8_t* data)
64 {
65 VALIDATE_HANDLE(handle);
66
67 ticalcs_info(" PC->TI: %s", cmdname);
68 return dbus_send(handle, target, cmd, length, data);
69 }
70
71 static const uint8_t dbus_errors[] = { 0x03, 0x25, 0x1e, 0x21, 0x07, 0x24, 0x08 };
72
err_code(uint8_t * data)73 static int err_code(uint8_t *data)
74 {
75 int i;
76 int code = data[2];
77
78 ticalcs_info(" TI->PC: SKP (%02x)", data[0]);
79 for (i = 0; i < (int)(sizeof(dbus_errors) / sizeof(dbus_errors[0])); i++)
80 {
81 if(dbus_errors[i] == code)
82 {
83 return i+1;
84 }
85 }
86
87 ticalcs_warning("D-BUS error code not found in list. Please report it at <tilp-devel@lists.sf.net>.");
88
89 return 0;
90 }
91
ti68k_send_VAR(CalcHandle * handle,uint32_t varsize,uint8_t vartype,const char * varname,uint8_t target)92 TIEXPORT3 int TICALL ti68k_send_VAR(CalcHandle* handle, uint32_t varsize, uint8_t vartype, const char *varname, uint8_t target)
93 {
94 uint8_t buffer[32];
95 char trans[127];
96 uint8_t extra = (target == DBUS_MID_PC_TI92) ? 0 : ((vartype == TI89_BKUP) ? 0 : 1);
97 uint16_t len;
98
99 VALIDATE_HANDLE(handle);
100 VALIDATE_NONNULL(varname);
101
102 len = (uint16_t)strlen(varname);
103 if (len > 17)
104 {
105 ticalcs_critical("Oversized variable name has length %i, clamping to 17", len);
106 len = 17;
107 }
108
109 ticonv_varname_to_utf8_sn(handle->model, varname, trans, sizeof(trans), vartype);
110
111 buffer[0] = LSB(LSW(varsize));
112 buffer[1] = MSB(LSW(varsize));
113 buffer[2] = LSB(MSW(varsize));
114 buffer[3] = MSB(MSW(varsize));
115 buffer[4] = vartype;
116 buffer[5] = len;
117 memcpy(buffer + 6, varname, len);
118 buffer[6 + len] = 0x03;
119
120 ticalcs_info(" PC->TI: VAR (size=0x%08X=%i, id=%02X, name=%s)", varsize, varsize, vartype, trans);
121 return dbus_send(handle, target, DBUS_CMD_VAR, 6 + len + extra, buffer);
122 }
123
ti68k_send_CTS(CalcHandle * handle,uint8_t target)124 TIEXPORT3 int TICALL ti68k_send_CTS(CalcHandle* handle, uint8_t target)
125 {
126 return ti68k_send_simple_cmd(handle, target, DBUS_CMD_CTS, "CTS", 2, NULL);
127 }
128
ti68k_send_XDP(CalcHandle * handle,uint32_t length,const uint8_t * data,uint8_t target)129 TIEXPORT3 int TICALL ti68k_send_XDP(CalcHandle* handle, uint32_t length, const uint8_t * data, uint8_t target)
130 {
131 VALIDATE_HANDLE(handle);
132
133 ticalcs_info(" PC->TI: XDP (0x%04X = %i bytes)", length, length);
134 return dbus_send(handle, target, DBUS_CMD_XDP, length, data);
135 }
136
ti89_send_SKP(CalcHandle * handle,uint8_t rej_code)137 TIEXPORT3 int TICALL ti89_send_SKP(CalcHandle* handle, uint8_t rej_code)
138 {
139 uint8_t buffer[4] = { rej_code, 0, 0, 0 };
140
141 VALIDATE_HANDLE(handle);
142
143 ticalcs_info(" PC->TI: SKP (rejection code = %i)", rej_code);
144 return dbus_send(handle, ti68k_handle_to_dbus_mid(handle), DBUS_CMD_SKP, 3, buffer);
145 }
146
ti92_send_SKP(CalcHandle * handle,uint8_t rej_code)147 TIEXPORT3 int TICALL ti92_send_SKP(CalcHandle* handle, uint8_t rej_code)
148 {
149 VALIDATE_HANDLE(handle);
150
151 ticalcs_info(" PC->TI: SKP (rejection code = %i)", rej_code);
152 return dbus_send(handle, DBUS_MID_PC_TI92, DBUS_CMD_SKP, 1, &rej_code);
153 }
154
ti68k_send_ACK(CalcHandle * handle,uint8_t target)155 TIEXPORT3 int TICALL ti68k_send_ACK(CalcHandle* handle, uint8_t target)
156 {
157 return ti68k_send_simple_cmd(handle, target, DBUS_CMD_ACK, "ACK", 2, NULL);
158 }
159
ti68k_send_ERR(CalcHandle * handle,uint8_t target)160 TIEXPORT3 int TICALL ti68k_send_ERR(CalcHandle* handle, uint8_t target)
161 {
162 return ti68k_send_simple_cmd(handle, target, DBUS_CMD_ERR, "ERR", 2, NULL);
163 }
164
ti68k_send_RDY(CalcHandle * handle,uint8_t target)165 TIEXPORT3 int TICALL ti68k_send_RDY(CalcHandle* handle, uint8_t target)
166 {
167 return ti68k_send_simple_cmd(handle, target, DBUS_CMD_RDY, "RDY", 2, NULL);
168 }
169
ti68k_send_SCR(CalcHandle * handle,uint8_t target)170 TIEXPORT3 int TICALL ti68k_send_SCR(CalcHandle* handle, uint8_t target)
171 {
172 return ti68k_send_simple_cmd(handle, target, DBUS_CMD_SCR, "SCR", 2, NULL);
173 }
174
ti68k_send_CNT(CalcHandle * handle,uint8_t target)175 TIEXPORT3 int TICALL ti68k_send_CNT(CalcHandle* handle, uint8_t target)
176 {
177 return ti68k_send_simple_cmd(handle, target, DBUS_CMD_CNT, "CNT", 2, NULL);
178 }
179
ti68k_send_KEY(CalcHandle * handle,uint16_t scancode,uint8_t target)180 TIEXPORT3 int TICALL ti68k_send_KEY(CalcHandle* handle, uint16_t scancode, uint8_t target)
181 {
182 uint8_t buf[4] = { target, DBUS_CMD_KEY, LSB(scancode), MSB(scancode) };
183
184 VALIDATE_HANDLE(handle);
185
186 ticalcs_info(" PC->TI: KEY");
187 return ticables_cable_send(handle->cable, buf, 4);
188 }
189
ti68k_send_EOT(CalcHandle * handle,uint8_t target)190 TIEXPORT3 int TICALL ti68k_send_EOT(CalcHandle* handle, uint8_t target)
191 {
192 return ti68k_send_simple_cmd(handle, target, DBUS_CMD_EOT, "EOT", 2, NULL);
193 }
194
ti89_send_REQ(CalcHandle * handle,uint32_t varsize,uint8_t vartype,const char * varname)195 TIEXPORT3 int TICALL ti89_send_REQ(CalcHandle* handle, uint32_t varsize, uint8_t vartype, const char *varname)
196 {
197 uint8_t buffer[32];
198 uint16_t len;
199
200 VALIDATE_HANDLE(handle);
201 VALIDATE_NONNULL(varname);
202 len = (uint16_t)strlen(varname);
203 if (len > 17)
204 {
205 ticalcs_critical("Oversized variable name has length %i, clamping to 17", len);
206 len = 17;
207 }
208
209 buffer[0] = LSB(LSW(varsize));
210 buffer[1] = MSB(LSW(varsize));
211 buffer[2] = LSB(MSW(varsize));
212 buffer[3] = MSB(MSW(varsize));
213 buffer[4] = vartype;
214 buffer[5] = len;
215 memcpy(buffer + 6, varname, len);
216 buffer[6 + len] = 0x00;
217
218 len += 6 + 1;
219 if (vartype != TI89_CLK) {
220 len--;
221 }
222
223 ticalcs_info(" PC->TI: REQ (size=0x%08X=%i, id=%02X, name=%s)", varsize, varsize, vartype, varname);
224 return dbus_send(handle, ti68k_handle_to_dbus_mid(handle), DBUS_CMD_REQ, len, buffer);
225 }
226
ti92_send_REQ(CalcHandle * handle,uint32_t varsize,uint8_t vartype,const char * varname)227 TIEXPORT3 int TICALL ti92_send_REQ(CalcHandle* handle, uint32_t varsize, uint8_t vartype, const char *varname)
228 {
229 uint8_t buffer[32];
230 uint16_t len;
231
232 VALIDATE_HANDLE(handle);
233 VALIDATE_NONNULL(varname);
234 len = (uint16_t)strlen(varname);
235 if (len > 17)
236 {
237 ticalcs_critical("Oversized variable name has length %i, clamping to 17", len);
238 len = 17;
239 }
240
241 buffer[0] = 0;
242 buffer[1] = 0;
243 buffer[2] = 0;
244 buffer[3] = 0;
245 buffer[4] = vartype;
246 buffer[5] = len;
247 memcpy(buffer + 6, varname, len);
248
249 ticalcs_info(" PC->TI: REQ (size=0x%08X=%i, id=%02X, name=%s)", varsize, varsize, vartype, varname);
250 return dbus_send(handle, DBUS_MID_PC_TI92, DBUS_CMD_REQ, 6 + len, buffer);
251 }
252
ti89_send_RTS(CalcHandle * handle,uint32_t varsize,uint8_t vartype,const char * varname)253 TIEXPORT3 int TICALL ti89_send_RTS(CalcHandle* handle, uint32_t varsize, uint8_t vartype, const char *varname)
254 {
255 uint8_t buffer[32];
256 uint16_t len;
257
258 VALIDATE_HANDLE(handle);
259 VALIDATE_NONNULL(varname);
260 len = (uint16_t)strlen(varname);
261 if (len > 17)
262 {
263 ticalcs_critical("Oversized variable name has length %i, clamping to 17", len);
264 len = 17;
265 }
266
267 buffer[0] = LSB(LSW(varsize));
268 buffer[1] = MSB(LSW(varsize));
269 buffer[2] = LSB(MSW(varsize));
270 buffer[3] = MSB(MSW(varsize));
271 buffer[4] = vartype;
272 buffer[5] = len;
273 memcpy(buffer + 6, varname, len);
274 buffer[6 + len] = 0x00;
275
276 len += 6 + 1;
277 // used by AMS <= 2.09 ?
278 //if ((vartype == TI89_AMS) || (vartype == TI89_APPL)) len--;
279
280 ticalcs_info(" PC->TI: RTS (size=0x%08X=%i, id=%02X, name=%s)", varsize, varsize, vartype, varname);
281 return dbus_send(handle, ti68k_handle_to_dbus_mid(handle), DBUS_CMD_RTS, len, buffer);
282 }
283
ti92_send_RTS(CalcHandle * handle,uint32_t varsize,uint8_t vartype,const char * varname)284 TIEXPORT3 int TICALL ti92_send_RTS(CalcHandle* handle, uint32_t varsize, uint8_t vartype, const char *varname)
285 {
286 uint8_t buffer[32];
287 uint16_t len;
288
289 VALIDATE_HANDLE(handle);
290 VALIDATE_NONNULL(varname);
291 len = (uint16_t)strlen(varname);
292 if (len > 17)
293 {
294 ticalcs_critical("Oversized variable name has length %i, clamping to 17", len);
295 len = 17;
296 }
297
298 buffer[0] = LSB(LSW(varsize));
299 buffer[1] = MSB(LSW(varsize));
300 buffer[2] = LSB(MSW(varsize));
301 buffer[3] = MSB(MSW(varsize));
302 buffer[4] = vartype;
303 buffer[5] = len;
304 memcpy(buffer + 6, varname, len);
305
306 ticalcs_info(" PC->TI: RTS (size=0x%08X=%i, id=%02X, name=%s)", varsize, varsize, vartype, varname);
307 return dbus_send(handle, DBUS_MID_PC_TI92, DBUS_CMD_RTS, 6 + len, buffer);
308 }
309
ti89_send_RTS2(CalcHandle * handle,uint32_t varsize,uint8_t vartype,uint8_t hw_id)310 TIEXPORT3 int TICALL ti89_send_RTS2(CalcHandle* handle, uint32_t varsize, uint8_t vartype, uint8_t hw_id)
311 {
312 uint8_t buffer[9];
313
314 VALIDATE_HANDLE(handle);
315
316 buffer[0] = LSB(LSW(varsize));
317 buffer[1] = MSB(LSW(varsize));
318 buffer[2] = LSB(MSW(varsize));
319 buffer[3] = MSB(MSW(varsize));
320 buffer[4] = vartype;
321 buffer[5] = 0x00;
322 buffer[6] = 0x08;
323 buffer[7] = 0x00;
324 buffer[8] = hw_id; // 0x08 -> V200, 0x09 -> Titanium (Hardware ID)
325
326 ticalcs_info(" PC->TI: RTS (size=0x%08X=%i, id=%02X, hw_id=%02x)", varsize, varsize, vartype, hw_id);
327 return dbus_send(handle, ti68k_handle_to_dbus_mid(handle), DBUS_CMD_RTS, 9, buffer);
328 }
329
ti89_send_VER(CalcHandle * handle)330 TIEXPORT3 int TICALL ti89_send_VER(CalcHandle* handle)
331 {
332 return ti68k_send_simple_cmd(handle, ti68k_handle_to_dbus_mid(handle), DBUS_CMD_VER, "VER", 2, NULL);
333 }
334
ti89_send_DEL(CalcHandle * handle,uint32_t varsize,uint8_t vartype,const char * varname)335 TIEXPORT3 int TICALL ti89_send_DEL(CalcHandle* handle, uint32_t varsize, uint8_t vartype, const char *varname)
336 {
337 uint8_t buffer[32];
338 uint16_t len;
339
340 VALIDATE_HANDLE(handle);
341 VALIDATE_NONNULL(varname);
342 len = (uint16_t)strlen(varname);
343 if (len > 17)
344 {
345 ticalcs_critical("Oversized variable name has length %i, clamping to 17", len);
346 len = 17;
347 }
348
349 buffer[0] = 0;
350 buffer[1] = 0;
351 buffer[2] = 0;
352 buffer[3] = 0;
353 buffer[4] = 0;
354 buffer[5] = len;
355 memcpy(buffer + 6, varname, len);
356
357 ticalcs_info(" PC->TI: DEL (size=0x%08X=%i, id=%02X, name=%s)", varsize, varsize, vartype, varname);
358 return dbus_send(handle, ti68k_handle_to_dbus_mid(handle), DBUS_CMD_DEL, 6 + len, buffer);
359 }
360
ti89_recv_VAR(CalcHandle * handle,uint32_t * varsize,uint8_t * vartype,char * varname)361 TIEXPORT3 int TICALL ti89_recv_VAR(CalcHandle* handle, uint32_t * varsize, uint8_t * vartype, char *varname)
362 {
363 uint8_t host, cmd;
364 uint8_t *buffer;
365 uint16_t length;
366 uint8_t strl;
367 uint8_t flag;
368 char * varname_nofldname;
369 int ret;
370
371 VALIDATE_HANDLE(handle);
372 VALIDATE_NONNULL(varsize);
373 VALIDATE_NONNULL(vartype);
374 VALIDATE_NONNULL(varname);
375
376 buffer = (uint8_t *)handle->buffer;
377 ret = dbus_recv(handle, &host, &cmd, &length, buffer);
378 if (ret)
379 {
380 return ret;
381 }
382
383 if (cmd == DBUS_CMD_EOT)
384 {
385 ticalcs_info(" TI->PC: EOT");
386 return ERR_EOT; // not really an error
387 }
388 if (cmd == DBUS_CMD_SKP)
389 {
390 return ERR_CALC_ERROR1 + err_code(buffer);
391 }
392 if (cmd != DBUS_CMD_VAR)
393 {
394 return ERR_INVALID_CMD;
395 }
396
397 *varsize = buffer[0] | (((uint32_t)buffer[1]) << 8) | (((uint32_t)buffer[2]) << 16) | (((uint32_t)buffer[3]) << 24);
398 *vartype = buffer[4];
399 strl = buffer[5];
400 memcpy(varname, buffer + 6, strl);
401 varname[strl] = '\0';
402 flag = buffer[6 + strl];
403
404 if ((length != (6 + strlen(varname))) && (length != (7 + strlen(varname))))
405 {
406 return ERR_INVALID_PACKET;
407 }
408
409 ticalcs_info(" TI->PC: VAR (size=0x%08X=%i, id=%02X, name=%s, flag=%i)", *varsize, *varsize, *vartype, varname, flag);
410 varname_nofldname = tifiles_get_varname(varname);
411 if (varname_nofldname != varname)
412 {
413 // This variable name contains a folder name. Erase it.
414 ticalcs_info(" TI->PC: VAR: the variable name contains a folder name, stripping it.");
415 memmove(varname, varname_nofldname, strlen(varname_nofldname)+1);
416 }
417
418 return 0;
419 }
420
ti92_recv_VAR(CalcHandle * handle,uint32_t * varsize,uint8_t * vartype,char * varname)421 TIEXPORT3 int TICALL ti92_recv_VAR(CalcHandle* handle, uint32_t * varsize, uint8_t * vartype, char *varname)
422 {
423 uint8_t host, cmd;
424 uint8_t *buffer;
425 uint16_t length;
426 uint8_t strl;
427 int ret;
428
429 VALIDATE_HANDLE(handle);
430 VALIDATE_NONNULL(varsize);
431 VALIDATE_NONNULL(vartype);
432 VALIDATE_NONNULL(varname);
433
434 buffer = (uint8_t *)handle->buffer;
435 ret = dbus_recv(handle, &host, &cmd, &length, buffer);
436 if (ret)
437 {
438 return ret;
439 }
440
441 if (cmd == DBUS_CMD_EOT)
442 {
443 ticalcs_info(" TI->PC: EOT");
444 return ERR_EOT; // not really an error
445 }
446 if (cmd == DBUS_CMD_SKP)
447 {
448 return ERR_VAR_REJECTED;
449 }
450 if (cmd != DBUS_CMD_VAR)
451 {
452 return ERR_INVALID_CMD;
453 }
454
455 *varsize = buffer[0] | (((uint32_t)buffer[1]) << 8) | (((uint32_t)buffer[2]) << 16) | (((uint32_t)buffer[3]) << 24);
456 *vartype = buffer[4];
457 strl = buffer[5];
458 memcpy(varname, buffer + 6, strl);
459 varname[strl] = '\0';
460
461 if (length != (6 + strlen(varname)))
462 {
463 return ERR_INVALID_PACKET;
464 }
465
466 ticalcs_info(" TI->PC: VAR (size=0x%08X=%i, id=%02X, name=%s)", *varsize, *varsize, *vartype, varname);
467
468 return 0;
469 }
470
ti68k_recv_CTS(CalcHandle * handle,uint8_t is_92)471 static int ti68k_recv_CTS(CalcHandle* handle, uint8_t is_92)
472 {
473 uint8_t host, cmd;
474 uint16_t length;
475 uint8_t *buffer;
476 int ret;
477
478 VALIDATE_HANDLE(handle);
479
480 buffer = (uint8_t *)handle->buffer;
481 ret = dbus_recv(handle, &host, &cmd, &length, buffer);
482 if (ret)
483 {
484 return ret;
485 }
486
487 if (cmd == DBUS_CMD_SKP)
488 {
489 return is_92 ? ERR_VAR_REJECTED : ERR_CALC_ERROR1 + err_code(buffer);
490 }
491 else if (cmd != DBUS_CMD_CTS)
492 {
493 return ERR_INVALID_CMD;
494 }
495 if (length != 0x0000)
496 {
497 return ERR_CTS_ERROR;
498 }
499
500 ticalcs_info(" TI->PC: CTS");
501
502 return 0;
503 }
504
ti89_recv_CTS(CalcHandle * handle)505 TIEXPORT3 int TICALL ti89_recv_CTS(CalcHandle* handle)
506 {
507 return ti68k_recv_CTS(handle, 0);
508 }
509
ti92_recv_CTS(CalcHandle * handle)510 TIEXPORT3 int TICALL ti92_recv_CTS(CalcHandle* handle)
511 {
512 return ti68k_recv_CTS(handle, 1);
513 }
514
ti68k_recv_SKP(CalcHandle * handle,uint8_t * rej_code)515 TIEXPORT3 int TICALL ti68k_recv_SKP(CalcHandle* handle, uint8_t * rej_code)
516 {
517 uint8_t host, cmd;
518 uint16_t length;
519 uint8_t *buffer;
520 int retval;
521
522 VALIDATE_HANDLE(handle);
523 VALIDATE_NONNULL(rej_code);
524
525 buffer = (uint8_t *)handle->buffer;
526 *rej_code = 0;
527
528 retval = dbus_recv(handle, &host, &cmd, &length, buffer);
529 if (retval == 0)
530 {
531 if (cmd == DBUS_CMD_CTS)
532 {
533 ticalcs_info("CTS");
534 }
535 else
536 {
537 if (cmd != DBUS_CMD_SKP)
538 {
539 retval = ERR_INVALID_CMD;
540 }
541 else
542 {
543 ticalcs_info(" TI->PC: SKP (rejection code = %i)", buffer[0]);
544 if (rej_code != NULL)
545 {
546 *rej_code = buffer[0];
547 }
548 }
549 }
550 }
551
552 return retval;
553 }
554
ti68k_recv_XDP(CalcHandle * handle,uint16_t * length,uint8_t * data)555 TIEXPORT3 int TICALL ti68k_recv_XDP(CalcHandle* handle, uint16_t * length, uint8_t * data)
556 {
557 uint8_t host, cmd;
558 int err;
559 uint16_t len;
560
561 VALIDATE_HANDLE(handle);
562 VALIDATE_NONNULL(length);
563
564 err = dbus_recv(handle, &host, &cmd, &len, data);
565 *length = len;
566
567 if (cmd != DBUS_CMD_XDP)
568 {
569 return ERR_INVALID_CMD;
570 }
571
572 if (!err)
573 {
574 ticalcs_info(" TI->PC: XDP (%04X=%i bytes)", *length, *length);
575 }
576
577 return err;
578 }
579
580 /* ACK: receive acknowledge
581 - status [in/out]: if NULL is passed, the function checks that 00 00 has
582 been received. Otherwise, it put in status the received value.
583 - int [out]: an error code
584 */
ti68k_recv_ACK(CalcHandle * handle,uint16_t * status,uint8_t is_92)585 static int ti68k_recv_ACK(CalcHandle* handle, uint16_t * status, uint8_t is_92)
586 {
587 uint8_t host, cmd;
588 uint16_t length;
589 uint8_t *buffer;
590 int ret;
591
592 VALIDATE_HANDLE(handle);
593
594 buffer = (uint8_t *)handle->buffer;
595 ret = dbus_recv(handle, &host, &cmd, &length, buffer);
596 if (ret)
597 {
598 return ret;
599 }
600
601 if (!is_92 && cmd == DBUS_CMD_SKP)
602 {
603 return ERR_CALC_ERROR1 + err_code(buffer);
604 }
605
606 if (status != NULL)
607 {
608 *status = length;
609 }
610 else if (length != 0x0000)
611 {
612 return ERR_NACK;
613 }
614
615 if (cmd != DBUS_CMD_ACK)
616 {
617 return ERR_INVALID_CMD;
618 }
619
620 ticalcs_info(" TI->PC: ACK");
621
622 return 0;
623 }
624
ti89_recv_ACK(CalcHandle * handle,uint16_t * status)625 TIEXPORT3 int TICALL ti89_recv_ACK(CalcHandle* handle, uint16_t * status)
626 {
627 return ti68k_recv_ACK(handle, status, 0);
628 }
629
ti92_recv_ACK(CalcHandle * handle,uint16_t * status)630 TIEXPORT3 int TICALL ti92_recv_ACK(CalcHandle* handle, uint16_t * status)
631 {
632 return ti68k_recv_ACK(handle, status, 1);
633 }
634
ti68k_recv_CNT(CalcHandle * handle)635 TIEXPORT3 int TICALL ti68k_recv_CNT(CalcHandle* handle)
636 {
637 uint8_t host, cmd;
638 uint16_t sts;
639 int ret;
640
641 VALIDATE_HANDLE(handle);
642
643 ret = dbus_recv(handle, &host, &cmd, &sts, NULL);
644 if (ret)
645 {
646 return ret;
647 }
648
649 if (cmd == DBUS_CMD_EOT)
650 {
651 return ERR_EOT; // not really an error
652 }
653
654 if (cmd != DBUS_CMD_CNT)
655 {
656 return ERR_INVALID_CMD;
657 }
658
659 ticalcs_info(" TI->PC: CNT");
660
661 return 0;
662 }
663
ti68k_recv_EOT(CalcHandle * handle)664 TIEXPORT3 int TICALL ti68k_recv_EOT(CalcHandle* handle)
665 {
666 uint8_t host, cmd;
667 uint16_t length;
668 int ret;
669
670 VALIDATE_HANDLE(handle);
671
672 ret = dbus_recv(handle, &host, &cmd, &length, NULL);
673 if (ret)
674 {
675 return ret;
676 }
677
678 if (cmd != DBUS_CMD_EOT)
679 {
680 return ERR_INVALID_CMD;
681 }
682
683 ticalcs_info(" TI->PC: EOT");
684
685 return 0;
686 }
687
ti68k_recv_RTS(CalcHandle * handle,uint32_t * varsize,uint8_t * vartype,char * varname,uint8_t is_92)688 static int ti68k_recv_RTS(CalcHandle* handle, uint32_t * varsize, uint8_t * vartype, char *varname, uint8_t is_92)
689 {
690 uint8_t host, cmd;
691 uint8_t *buffer;
692 uint16_t length;
693 uint8_t strl;
694 int ret;
695
696 VALIDATE_HANDLE(handle);
697 VALIDATE_NONNULL(varsize);
698 VALIDATE_NONNULL(vartype);
699 VALIDATE_NONNULL(varname);
700
701 buffer = (uint8_t *)handle->buffer;
702 ret = dbus_recv(handle, &host, &cmd, &length, buffer);
703 if (ret)
704 {
705 return ret;
706 }
707
708 if (cmd == DBUS_CMD_EOT)
709 {
710 return ERR_EOT; // not really an error
711 }
712 else if (cmd == DBUS_CMD_SKP)
713 {
714 return is_92 ? ERR_VAR_REJECTED : ERR_CALC_ERROR1 + err_code(buffer);
715 }
716 else if (cmd != DBUS_CMD_VAR)
717 {
718 return ERR_INVALID_CMD;
719 }
720
721 *varsize = buffer[0] | (((uint32_t)buffer[1]) << 8) | (((uint32_t)buffer[2]) << 16) | (((uint32_t)buffer[3]) << 24);
722 *vartype = buffer[4];
723 strl = buffer[5];
724 memcpy(varname, buffer + 6, strl);
725 varname[strl] = '\0';
726
727 if (length != (6 + strlen(varname)))
728 {
729 return ERR_INVALID_PACKET;
730 }
731
732 ticalcs_info(" TI->PC: RTS (size=0x%08X=%i, id=%02X, name=%s)", *varsize, *varsize, *vartype, varname);
733
734 return 0;
735 }
736
ti89_recv_RTS(CalcHandle * handle,uint32_t * varsize,uint8_t * vartype,char * varname)737 TIEXPORT3 int TICALL ti89_recv_RTS(CalcHandle* handle, uint32_t * varsize, uint8_t * vartype, char *varname)
738 {
739 return ti68k_recv_RTS(handle, varsize, vartype, varname, 0);
740 }
741
ti92_recv_RTS(CalcHandle * handle,uint32_t * varsize,uint8_t * vartype,char * varname)742 TIEXPORT3 int TICALL ti92_recv_RTS(CalcHandle* handle, uint32_t * varsize, uint8_t * vartype, char *varname)
743 {
744 return ti68k_recv_RTS(handle, varsize, vartype, varname, 1);
745 }
746