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-80 commands;
24   * TI-82 & TI-83 commands;
25   * TI-85 & TI-86 commands;
26   * TI-73 & TI-83+ & TI-84+ commands.
27 */
28 
29 #include <stdio.h>
30 #include <string.h>
31 
32 #include "ticalcs.h"
33 #include "internal.h"
34 #include "dbus_pkt.h"
35 #include "error.h"
36 #include "logging.h"
37 #include "cmdz80.h"
38 
39 #ifdef _MSC_VER
40 #pragma warning( disable : 4761 )
41 #endif
42 
43 // Share some commands between TI-82 & TI-83, TI-85 & TI-86, TI-73 & TI-83+ & TI-84+
44 #define TI7383p_PC ((handle != NULL) ? ((handle->model == CALC_TI73) ? TI73_PC : TI83p_PC) : 0)
45 #define TI7383p_BKUP ((handle->model == CALC_TI73) ? TI73_BKUP : TI83p_BKUP)
46 #define EXTRAS ((handle->model == CALC_TI73) ? 0 : 2)
47 #define TI8283_BKUP ((handle->model == CALC_TI82) ? TI82_BKUP : TI83_BKUP)
48 #define TI8586_BKUP ((handle->model == CALC_TI85) ? TI85_BKUP : TI86_BKUP)
49 
tiz80_handle_to_dbus_mid(CalcHandle * handle)50 TIEXPORT3 uint8_t TICALL tiz80_handle_to_dbus_mid(CalcHandle * handle)
51 {
52 	if (ticalcs_validate_handle(handle))
53 	{
54 		switch (handle->model)
55 		{
56 		case CALC_TI73:
57 			return DBUS_MID_PC_TI73;
58 		case CALC_TI82:
59 			return DBUS_MID_PC_TI82;
60 		case CALC_TI83:
61 			return DBUS_MID_PC_TI83;
62 		case CALC_TI83P:
63 		case CALC_TI84P:
64 		case CALC_TI84PC:
65 			return DBUS_MID_PC_TI83p;
66 		case CALC_TI85:
67 			return DBUS_MID_PC_TI85;
68 		case CALC_TI86:
69 			return DBUS_MID_PC_TI86;
70 		default:
71 			return DBUS_MID_PC_TIXX;
72 		}
73 	}
74 	return 0;
75 }
76 
tiz80_send_simple_cmd(CalcHandle * handle,uint8_t target,uint8_t cmd,const char * cmdname,uint16_t length,const uint8_t * data)77 static inline int tiz80_send_simple_cmd(CalcHandle * handle, uint8_t target, uint8_t cmd, const char * cmdname, uint16_t length, const uint8_t* data)
78 {
79 	VALIDATE_HANDLE(handle);
80 
81 	ticalcs_info(" PC->TI: %s", cmdname);
82 	return dbus_send(handle, target, cmd, length, data);
83 }
84 
85 /* VAR: Variable (std var header: NUL padded, fixed length) */
tiz80_send_bkup_VAR(CalcHandle * handle,uint8_t * buffer,uint16_t varsize,uint8_t vartype,const char * varname,uint8_t target)86 static int tiz80_send_bkup_VAR(CalcHandle* handle, uint8_t *buffer, uint16_t varsize, uint8_t vartype, const char * varname, uint8_t target)
87 {
88 	memcpy((char *)buffer + 3, varname, 6);
89 	ticalcs_info(" PC->TI: VAR (size=0x%04X=%d, id=%02X, name=(<backup>))", varsize, varsize, vartype);
90 	return dbus_send(handle, target, DBUS_CMD_VAR, 9, buffer);
91 }
92 
ti73_send_VAR(CalcHandle * handle,uint16_t varsize,uint8_t vartype,const char * varname,uint8_t varattr,uint8_t version)93 TIEXPORT3 int TICALL ti73_send_VAR(CalcHandle* handle, uint16_t varsize, uint8_t vartype, const char *varname, uint8_t varattr, uint8_t version)
94 {
95 	uint8_t buffer[16];
96 	char trans[127];
97 
98 	VALIDATE_HANDLE(handle);
99 	VALIDATE_NONNULL(varname);
100 
101 	buffer[0] = LSB(varsize);
102 	buffer[1] = MSB(varsize);
103 	buffer[2] = vartype;
104 
105 	if (vartype != TI7383p_BKUP || version != 0)
106 	{
107 		memcpy((char *)buffer + 3, varname, 8);
108 		buffer[11] = version;
109 		buffer[12] = (varattr == ATTRB_ARCHIVED) ? 0x80 : 0x00;
110 
111 		ticonv_varname_to_utf8_sn(handle->model, varname, trans, sizeof(trans), vartype);
112 		ticalcs_info(" PC->TI: VAR (size=0x%04X=%d, id=%02X, name=%s, attr=%d, version=%d)", varsize, varsize, vartype, trans, varattr, version);
113 
114 		return dbus_send(handle, tiz80_handle_to_dbus_mid_7383p(handle), DBUS_CMD_VAR, 11 + EXTRAS, buffer);
115 	}
116 	else
117 	{
118 		return tiz80_send_bkup_VAR(handle, buffer, varsize, vartype, varname, tiz80_handle_to_dbus_mid_7383p(handle));
119 	}
120 }
121 
ti82_send_VAR(CalcHandle * handle,uint16_t varsize,uint8_t vartype,const char * varname)122 TIEXPORT3 int TICALL ti82_send_VAR(CalcHandle* handle, uint16_t varsize, uint8_t vartype, const char *varname)
123 {
124 	uint8_t buffer[16];
125 	char trans[127];
126 
127 	VALIDATE_HANDLE(handle);
128 	VALIDATE_NONNULL(varname);
129 
130 	buffer[0] = LSB(varsize);
131 	buffer[1] = MSB(varsize);
132 	buffer[2] = vartype;
133 
134 	if (vartype != TI8283_BKUP)
135 	{
136 		memcpy((char *)buffer + 3, varname, 8);
137 
138 		ticonv_varname_to_utf8_sn(handle->model, varname, trans, sizeof(trans), vartype);
139 		ticalcs_info(" PC->TI: VAR (size=0x%04X=%d, id=%02X, name=%s)", varsize, varsize, vartype, trans);
140 
141 		return dbus_send(handle, tiz80_handle_to_dbus_mid_8283(handle), DBUS_CMD_VAR, 11, buffer);
142 	}
143 	else
144 	{
145 		return tiz80_send_bkup_VAR(handle, buffer, varsize, vartype, varname, tiz80_handle_to_dbus_mid_8283(handle));
146 	}
147 }
148 
ti85_send_VAR(CalcHandle * handle,uint16_t varsize,uint8_t vartype,const char * varname)149 TIEXPORT3 int TICALL ti85_send_VAR(CalcHandle* handle, uint16_t varsize, uint8_t vartype, const char *varname)
150 {
151 	uint8_t buffer[16];
152 	char trans[127];
153 
154 	VALIDATE_HANDLE(handle);
155 	VALIDATE_NONNULL(varname);
156 
157 	buffer[0] = LSB(varsize);
158 	buffer[1] = MSB(varsize);
159 	buffer[2] = vartype;
160 
161 	if (vartype != TI8586_BKUP)
162 	{
163 		int len = strlen(varname);
164 		if (len > 8)
165 		{
166 			ticalcs_critical("Oversized variable name has length %d, clamping to 8", len);
167 			len = 8;
168 		}
169 		buffer[3] = len;
170 		memcpy((char *)buffer + 4, varname, len);
171 
172 		ticonv_varname_to_utf8_sn(handle->model, varname, trans, sizeof(trans), vartype);
173 		ticalcs_info(" PC->TI: VAR (size=0x%04X=%d, id=%02X, name=%s)", varsize, varsize, vartype, trans);
174 
175 		return dbus_send(handle, tiz80_handle_to_dbus_mid_8586(handle), DBUS_CMD_VAR, 4 + len, buffer);
176 	}
177 	else
178 	{
179 		return tiz80_send_bkup_VAR(handle, buffer, varsize, vartype, varname, tiz80_handle_to_dbus_mid_8586(handle));
180 	}
181 }
182 
183 /* FLASH (special var header: size, id, flag, offset, page) */
ti73_send_VAR2(CalcHandle * handle,uint32_t length,uint8_t type,uint8_t flag,uint16_t offset,uint16_t page)184 TIEXPORT3 int TICALL ti73_send_VAR2(CalcHandle* handle, uint32_t length, uint8_t type, uint8_t flag, uint16_t offset, uint16_t page)
185 {
186 	uint8_t buffer[11];
187 
188 	VALIDATE_HANDLE(handle);
189 
190 	buffer[0] = LSB(LSW(length));
191 	buffer[1] = MSB(LSW(length));
192 	buffer[2] = type;
193 	buffer[3] = LSB(MSW(length));
194 	buffer[4] = MSB(MSW(length));
195 	buffer[5] = flag;
196 	buffer[6] = LSB(offset);
197 	buffer[7] = MSB(offset);
198 	buffer[8] = LSB(page);
199 	buffer[9] = MSB(page);
200 
201 	ticalcs_info(" PC->TI: VAR (size=0x%08X=%d, id=%02X, flag=%02X, offset=%04X, page=%02X)", length, length, type, flag, offset, page);
202 
203 	return dbus_send(handle, tiz80_handle_to_dbus_mid_7383p(handle), DBUS_CMD_VAR, 10, buffer);
204 }
205 
tiz80_send_CTS(CalcHandle * handle,uint8_t target)206 TIEXPORT3 int TICALL tiz80_send_CTS(CalcHandle* handle, uint8_t target)
207 {
208 	return tiz80_send_simple_cmd(handle, target, DBUS_CMD_CTS, "CTS", 0, NULL);
209 }
210 
tiz80_send_XDP(CalcHandle * handle,uint16_t length,const uint8_t * data,uint8_t target)211 TIEXPORT3 int TICALL tiz80_send_XDP(CalcHandle* handle, uint16_t length, const uint8_t * data, uint8_t target)
212 {
213 	VALIDATE_HANDLE(handle);
214 
215 	ticalcs_info(" PC->TI: XDP (0x%04X = %d bytes)", length, length);
216 	return dbus_send(handle, target, DBUS_CMD_XDP, length, data);
217 }
218 
tiz80_send_SKP(CalcHandle * handle,uint8_t rej_code,uint8_t target)219 TIEXPORT3 int TICALL tiz80_send_SKP(CalcHandle* handle, uint8_t rej_code, uint8_t target)
220 {
221 	VALIDATE_HANDLE(handle);
222 
223 	ticalcs_info(" PC->TI: SKP (rejection code = %d)", rej_code);
224 	return dbus_send(handle, target, DBUS_CMD_SKP, 1, &rej_code);
225 }
226 
tiz80_send_ACK(CalcHandle * handle,uint8_t target)227 TIEXPORT3 int TICALL tiz80_send_ACK(CalcHandle* handle, uint8_t target)
228 {
229 	return tiz80_send_simple_cmd(handle, target, DBUS_CMD_ACK, "ACK", 2, NULL);
230 }
231 
tiz80_send_ERR(CalcHandle * handle,uint8_t target)232 TIEXPORT3 int TICALL tiz80_send_ERR(CalcHandle* handle, uint8_t target)
233 {
234 	return tiz80_send_simple_cmd(handle, target, DBUS_CMD_ERR, "ERR", 2, NULL);
235 }
236 
ti73_send_RDY(CalcHandle * handle)237 TIEXPORT3 int TICALL ti73_send_RDY(CalcHandle* handle)
238 {
239 	return tiz80_send_simple_cmd(handle, tiz80_handle_to_dbus_mid_7383p(handle), DBUS_CMD_RDY, "RDY", 2, NULL);
240 }
241 
tiz80_send_SCR(CalcHandle * handle,uint8_t target)242 TIEXPORT3 int TICALL tiz80_send_SCR(CalcHandle* handle, uint8_t target)
243 {
244 	return tiz80_send_simple_cmd(handle, target, DBUS_CMD_SCR, "SCR", 2, NULL);
245 }
246 
ti80_send_SCR(CalcHandle * handle)247 TIEXPORT3 int TICALL ti80_send_SCR(CalcHandle* handle)
248 {
249 	return tiz80_send_simple_cmd(handle, DBUS_MID_PC_TI80, DBUS_CMD_SCR, "SCR", 0, NULL);
250 }
251 
tiz80_send_KEY(CalcHandle * handle,uint16_t scancode,uint8_t target)252 TIEXPORT3 int TICALL tiz80_send_KEY(CalcHandle* handle, uint16_t scancode, uint8_t target)
253 {
254 	uint8_t buf[4] = { target, DBUS_CMD_KEY, LSB(scancode), MSB(scancode) };
255 
256 	VALIDATE_HANDLE(handle);
257 
258 	ticalcs_info(" PC->TI: KEY");
259 	return ticables_cable_send(handle->cable, buf, 4);
260 }
261 
tiz80_send_EOT(CalcHandle * handle,uint8_t target)262 TIEXPORT3 int TICALL tiz80_send_EOT(CalcHandle* handle, uint8_t target)
263 {
264 	return tiz80_send_simple_cmd(handle, target, DBUS_CMD_EOT, "EOT", 2, NULL);
265 }
266 
267 /* REQ: request variable (std var header: NUL padded, fixed length) */
ti73_send_REQ(CalcHandle * handle,uint16_t varsize,uint8_t vartype,const char * varname,uint8_t varattr,uint8_t version)268 TIEXPORT3 int TICALL ti73_send_REQ(CalcHandle* handle, uint16_t varsize, uint8_t vartype, const char *varname, uint8_t varattr, uint8_t version)
269 {
270 	uint8_t buffer[16];
271 	char trans[127];
272 
273 	VALIDATE_HANDLE(handle);
274 	VALIDATE_NONNULL(varname);
275 
276 	buffer[0] = LSB(varsize);
277 	buffer[1] = MSB(varsize);
278 	buffer[2] = vartype;
279 	memcpy((char *)buffer + 3, varname, 8);
280 	buffer[11] = version;
281 	buffer[12] = (varattr == ATTRB_ARCHIVED) ? 0x80 : 0x00;
282 
283 	ticonv_varname_to_utf8_sn(handle->model, varname, trans, sizeof(trans), vartype);
284 	ticalcs_info(" PC->TI: REQ (size=0x%04X=%d, id=%02X, name=%s, attr=%d)", varsize, varsize, vartype, trans, varattr);
285 
286 	if (vartype != TI83p_IDLIST && vartype != TI83p_GETCERT)
287 	{
288 		return dbus_send(handle, tiz80_handle_to_dbus_mid_7383p(handle), DBUS_CMD_REQ, 11 + EXTRAS, buffer);
289 	}
290 	else if (vartype != TI83p_GETCERT && handle->model != CALC_TI73)
291 	{
292 		return dbus_send(handle, tiz80_handle_to_dbus_mid_7383p(handle), DBUS_CMD_REQ, 11, buffer);
293 	}
294 	else
295 	{
296 		return dbus_send(handle, DBUS_MID_PC_TI73, DBUS_CMD_REQ, 3, buffer);
297 	}
298 }
299 
ti82_send_REQ(CalcHandle * handle,uint16_t varsize,uint8_t vartype,const char * varname)300 TIEXPORT3 int TICALL ti82_send_REQ(CalcHandle* handle, uint16_t varsize, uint8_t vartype, const char *varname)
301 {
302 	uint8_t buffer[16];
303 	char trans[127];
304 
305 	VALIDATE_HANDLE(handle);
306 	VALIDATE_NONNULL(varname);
307 
308 	buffer[0] = LSB(varsize);
309 	buffer[1] = MSB(varsize);
310 	buffer[2] = vartype;
311 	memcpy((char *)buffer + 3, varname, 8);
312 
313 	ticonv_varname_to_utf8_sn(handle->model, varname, trans, sizeof(trans), vartype);
314 	ticalcs_info(" PC->TI: REQ (size=0x%04X=%d, id=%02X, name=%s)", varsize, varsize, vartype, trans);
315 
316 	return dbus_send(handle, tiz80_handle_to_dbus_mid_8283(handle), DBUS_CMD_REQ, 11, buffer);
317 }
318 
ti85_send_REQ(CalcHandle * handle,uint16_t varsize,uint8_t vartype,const char * varname)319 TIEXPORT3 int TICALL ti85_send_REQ(CalcHandle* handle, uint16_t varsize, uint8_t vartype, const char *varname)
320 {
321 	uint8_t buffer[16];
322 	char trans[127];
323 	int len;
324 
325 	VALIDATE_HANDLE(handle);
326 	VALIDATE_NONNULL(varname);
327 
328 	ticonv_varname_to_utf8_sn(handle->model, varname, trans, sizeof(trans), vartype);
329 	ticalcs_info(" PC->TI: REQ (size=0x%04X=%d, id=%02X, name=%s)", varsize, varsize, vartype, trans);
330 
331 	if ((handle->model == CALC_TI86) && (vartype >= TI86_DIR) && (vartype <= TI86_ZRCL))
332 	{
333 		memset(buffer, 0, 6);
334 		buffer[2] = vartype;
335 		return dbus_send(handle, DBUS_MID_PC_TI86, DBUS_CMD_REQ, 5, buffer);
336 	}
337 	else if ((handle->model == CALC_TI86) && (vartype == TI86_BKUP))
338 	{
339 		memset(buffer, 0, 12);
340 		buffer[2] = vartype;
341 		return dbus_send(handle, DBUS_MID_PC_TI86, DBUS_CMD_REQ, 11, buffer);
342 	}
343 	else
344 	{
345 		buffer[0] = LSB(varsize);
346 		buffer[1] = MSB(varsize);
347 		buffer[2] = vartype;
348 		len = strlen(varname);
349 		if (len > 8)
350 		{
351 			ticalcs_critical("Oversized variable name has length %d, clamping to 8", len);
352 			len = 8;
353 		}
354 		buffer[3] = len;
355 		memcpy((char *)buffer + 4, varname, len);
356 
357 		return dbus_send(handle, tiz80_handle_to_dbus_mid_8586(handle), DBUS_CMD_REQ, 4 + len, buffer);
358 	}
359 }
360 
361 /* FLASH (special var header: size, id, flag, offset, page) */
ti73_send_REQ2(CalcHandle * handle,uint16_t appsize,uint8_t apptype,const char * appname,uint8_t appattr)362 TIEXPORT3 int TICALL ti73_send_REQ2(CalcHandle* handle, uint16_t appsize, uint8_t apptype, const char *appname, uint8_t appattr)
363 {
364 	uint8_t buffer[16];
365 
366 	/* Note: attribute/version bytes are not used (and will be ignored
367 	   by the calculator if included in the packet.)  The 'appattr'
368 	   parameter has no effect. */
369 
370 	VALIDATE_HANDLE(handle);
371 	VALIDATE_NONNULL(appname);
372 
373 	buffer[0] = LSB(appsize);
374 	buffer[1] = MSB(appsize);
375 	buffer[2] = apptype;
376 	memcpy((char *)buffer + 3, appname, 8);
377 
378 	ticalcs_info(" PC->TI: REQ (size=0x%04X=%d, id=%02X, name=%s)", appsize, appsize, apptype, appname);
379 	return dbus_send(handle, tiz80_handle_to_dbus_mid_7383p(handle), DBUS_CMD_REQ, 11, buffer);
380 }
381 
382 /* Request to send (std var header: NUL padded, fixed length) */
ti73_send_RTS(CalcHandle * handle,uint16_t varsize,uint8_t vartype,const char * varname,uint8_t varattr,uint8_t version)383 TIEXPORT3 int TICALL ti73_send_RTS(CalcHandle* handle, uint16_t varsize, uint8_t vartype, const char *varname, uint8_t varattr, uint8_t version)
384 {
385 	uint8_t buffer[16];
386 	char trans[127];
387 
388 	VALIDATE_HANDLE(handle);
389 	VALIDATE_NONNULL(varname);
390 
391 	buffer[0] = LSB(varsize);
392 	buffer[1] = MSB(varsize);
393 	buffer[2] = vartype;
394 	memcpy((char *)buffer + 3, varname, 8);
395 	buffer[11] = version;
396 	buffer[12] = (varattr == ATTRB_ARCHIVED) ? 0x80 : 0x00;
397 
398 	ticonv_varname_to_utf8_sn(handle->model, varname, trans, sizeof(trans), vartype);
399 	ticalcs_info(" PC->TI: RTS (size=0x%04X=%d, id=%02X, name=%s, attr=%d)", varsize, varsize, vartype, trans, varattr);
400 
401 	if (vartype != TI7383p_BKUP || version != 0)
402 	{
403 		// backup: special header
404 		return dbus_send(handle, tiz80_handle_to_dbus_mid_7383p(handle), DBUS_CMD_RTS, 11 + EXTRAS, buffer);
405 	}
406 	else
407 	{
408 		return dbus_send(handle, tiz80_handle_to_dbus_mid_7383p(handle), DBUS_CMD_RTS, 9, buffer);
409 	}
410 }
411 
412 /* Request to send (std var header: NUL padded, fixed length) */
ti82_send_RTS(CalcHandle * handle,uint16_t varsize,uint8_t vartype,const char * varname)413 TIEXPORT3 int TICALL ti82_send_RTS(CalcHandle* handle, uint16_t varsize, uint8_t vartype, const char *varname)
414 {
415 	uint8_t buffer[16];
416 	char trans[127];
417 
418 	VALIDATE_HANDLE(handle);
419 	VALIDATE_NONNULL(varname);
420 
421 	buffer[0] = LSB(varsize);
422 	buffer[1] = MSB(varsize);
423 	buffer[2] = vartype;
424 	memcpy((char *)buffer + 3, varname, 8);
425 
426 	ticonv_varname_to_utf8_sn(handle->model, varname, trans, sizeof(trans), vartype);
427 	ticalcs_info(" PC->TI: RTS (size=0x%04X=%d, id=%02X, name=%s)", varsize, varsize, vartype, trans);
428 
429 	if (vartype != TI8283_BKUP)
430 	{
431 		// backup: special header
432 		return dbus_send(handle, tiz80_handle_to_dbus_mid_8283(handle), DBUS_CMD_RTS, 11, buffer);
433 	}
434 	else
435 	{
436 		return dbus_send(handle, tiz80_handle_to_dbus_mid_8283(handle), DBUS_CMD_RTS, 9, buffer);
437 	}
438 }
439 
440 /* Request to send (var header: SPC padded, fixed length) */
ti85_send_RTS(CalcHandle * handle,uint16_t varsize,uint8_t vartype,const char * varname)441 TIEXPORT3 int TICALL ti85_send_RTS(CalcHandle* handle, uint16_t varsize, uint8_t vartype, const char *varname)
442 {
443 	uint8_t buffer[16];
444 	char trans[127];
445 	int len;
446 
447 	VALIDATE_HANDLE(handle);
448 	VALIDATE_NONNULL(varname);
449 
450 	buffer[0] = LSB(varsize);
451 	buffer[1] = MSB(varsize);
452 	buffer[2] = vartype;
453 	len = strlen(varname);
454 	if (len > 8)
455 	{
456 		ticalcs_critical("Oversized variable name has length %d, clamping to 8", len);
457 		len = 8;
458 	}
459 	buffer[3] = len;
460 	memset(buffer + 4, ' ', 8);
461 	memcpy((char *)buffer + 4, varname, len);
462 
463 	ticonv_varname_to_utf8_sn(handle->model, varname, trans, sizeof(trans), vartype);
464 	ticalcs_info(" PC->TI: RTS (size=0x%04X=%d, id=%02X, name=%s)", varsize, varsize, vartype, trans);
465 
466 	return dbus_send(handle, tiz80_handle_to_dbus_mid_8586(handle), DBUS_CMD_RTS, 12, buffer);
467 
468 	return 0;
469 }
470 
471 /* Send an invalid packet that causes the calc to execute assembly
472    code stored in the most recently transferred variable.
473 
474    The program must perform whatever cleanup is necessary, including
475    restoring (FPS), (OPS), and (errSP).  You can do so by calling
476    ResetStacks, or by jumping to JForceCmdNoChar when you exit.  For
477    ROM-independent methods, see romdump.asm.
478 */
ti82_send_asm_exec(CalcHandle * handle,VarEntry * var)479 int ti82_send_asm_exec(CalcHandle* handle, VarEntry * var)
480 {
481 	uint16_t ioData;
482 	uint16_t errSP;
483 	uint16_t onSP;
484 	uint16_t tempMem;
485 	uint16_t fpBase;
486 	uint8_t buffer[50];
487 	uint16_t length, offset, endptr, es, sum;
488 
489 	VALIDATE_HANDLE(handle);
490 	VALIDATE_VARENTRY(var);
491 
492 	if (handle->model != CALC_TI82 && handle->model != CALC_TI85)
493 	{
494 		ticalcs_critical("asm_exec not supported for this model");
495 		return ERR_UNSUPPORTED;
496 	}
497 
498 	ioData  = (handle->model == CALC_TI82 ? 0x81fd : 0x831e);
499 	errSP   = (handle->model == CALC_TI82 ? 0x821a : 0x8338);
500 	onSP    = (handle->model == CALC_TI82 ? 0x8143 : 0x81bc);
501 	tempMem = (handle->model == CALC_TI82 ? 0x8d0a : 0x8bdd);
502 	fpBase  = (handle->model == CALC_TI82 ? 0x8d0c : 0x8bdf);
503 
504 	buffer[0] = (handle->model == CALC_TI82 ? DBUS_MID_PC_TI82 : DBUS_MID_PC_TI85);
505 	buffer[1] = DBUS_CMD_VAR;
506 
507 	/* Warning: Heavy wizardry begins here. ;) */
508 
509 	length = errSP + 2 - ioData;
510 	buffer[2] = LSB(length);
511 	buffer[3] = MSB(length);
512 
513 	memset(buffer + 4, 0, length);
514 
515 	/* ld sp, (onSP) */
516 	buffer[4] = 0xed; buffer[5] = 0x7b; buffer[6] = LSB(onSP); buffer[7] = MSB(onSP);
517 	/* ld hl, (endptr) */
518 	endptr = (var->name[0] == 0x24 ? fpBase : tempMem);
519 	buffer[8] = 0x2a; buffer[9] = LSB(endptr); buffer[10] = MSB(endptr);
520 	/* ld de, -program_size */
521 	offset = -(var->size - 2);
522 	buffer[11] = 0x11; buffer[12] = LSB(offset); buffer[13] = MSB(offset);
523 	/* add hl, de */
524 	buffer[14] = 0x19;
525 	/* jp (hl) */
526 	buffer[15] = 0xe9;
527 
528 	es = 4 + errSP - ioData;
529 	buffer[es] = LSB(errSP - 11); buffer[es + 1] = MSB(errSP - 11);
530 
531 	buffer[es - 4] = (handle->model == CALC_TI82 ? 0x88 : 0);
532 	buffer[es - 3] = LSB(ioData); buffer[es - 2] = MSB(ioData);
533 
534 	sum = tifiles_checksum(buffer + 4, length) + 0x5555;
535 	buffer[4 + length] = LSB(sum);
536 	buffer[4 + length + 1] = MSB(sum);
537 
538 	ticalcs_info(" PC->TI: VAR (exec assembly; program size = 0x%04X)", var->size);
539 
540 	return ticables_cable_send(handle->cable, buffer, length + 6);
541 }
542 
ti73_send_VER(CalcHandle * handle)543 TIEXPORT3 int TICALL ti73_send_VER(CalcHandle* handle)
544 {
545 	return tiz80_send_simple_cmd(handle, tiz80_handle_to_dbus_mid_7383p(handle), DBUS_CMD_VER, "VER", 2, NULL);
546 }
547 
ti73_send_DEL(CalcHandle * handle,uint16_t varsize,uint8_t vartype,const char * varname,uint8_t varattr)548 TIEXPORT3 int TICALL ti73_send_DEL(CalcHandle* handle, uint16_t varsize, uint8_t vartype, const char *varname, uint8_t varattr)
549 {
550 	uint8_t buffer[16];
551 	char trans[127];
552 
553 	/* Note: attribute/version bytes are not used (and will be ignored
554 	   by the calculator if included in the packet.)  The 'varattr'
555 	   parameter has no effect. */
556 
557 	VALIDATE_HANDLE(handle);
558 	VALIDATE_NONNULL(varname);
559 
560 	buffer[0] = LSB(varsize);
561 	buffer[1] = MSB(varsize);
562 	buffer[2] = vartype == TI83p_APPL ? 0x14 : vartype;
563 	memcpy((char *)buffer + 3, varname, 8);
564 
565 	ticonv_varname_to_utf8_sn(handle->model, varname, trans, sizeof(trans), vartype);
566 	ticalcs_info(" PC->TI: DEL (name=%s)", trans);
567 
568 	return dbus_send(handle, tiz80_handle_to_dbus_mid_7383p(handle), DBUS_CMD_DEL, 11, buffer);
569 }
570 
ti73_send_DUMP(CalcHandle * handle,uint16_t page)571 TIEXPORT3 int TICALL ti73_send_DUMP(CalcHandle* handle, uint16_t page)
572 {
573 	uint8_t buffer[8] = { page, 0x00, 0x00, 0x40, 0x00, 0x40, 0x0C, 0x00 };
574 
575 	VALIDATE_HANDLE(handle);
576 
577 	ticalcs_info(" PC->TI: DUMP (page=%02X)", page);
578 	return dbus_send(handle, DBUS_MID_PC_TI83p, DBUS_CMD_DMP, 8, buffer);
579 }
580 
ti73_send_EKE(CalcHandle * handle)581 TIEXPORT3 int TICALL ti73_send_EKE(CalcHandle* handle)
582 {
583 	return tiz80_send_simple_cmd(handle, tiz80_handle_to_dbus_mid_7383p(handle), DBUS_CMD_EKE, "EKE", 2, NULL);
584 }
585 
ti73_send_DKE(CalcHandle * handle)586 TIEXPORT3 int TICALL ti73_send_DKE(CalcHandle* handle)
587 {
588 	return tiz80_send_simple_cmd(handle, tiz80_handle_to_dbus_mid_7383p(handle), DBUS_CMD_DKE, "DKE", 2, NULL);
589 }
590 
ti73_send_ELD(CalcHandle * handle)591 TIEXPORT3 int TICALL ti73_send_ELD(CalcHandle* handle)
592 {
593 	return tiz80_send_simple_cmd(handle, tiz80_handle_to_dbus_mid_7383p(handle), DBUS_CMD_ELD, "ELD", 2, NULL);
594 }
595 
ti73_send_DLD(CalcHandle * handle)596 TIEXPORT3 int TICALL ti73_send_DLD(CalcHandle* handle)
597 {
598 	return tiz80_send_simple_cmd(handle, tiz80_handle_to_dbus_mid_7383p(handle), DBUS_CMD_DLD, "DLD", 2, NULL);
599 }
600 
ti73_send_GID(CalcHandle * handle)601 TIEXPORT3 int TICALL ti73_send_GID(CalcHandle* handle)
602 {
603 	return tiz80_send_simple_cmd(handle, tiz80_handle_to_dbus_mid_7383p(handle), DBUS_CMD_GID, "GID", 2, NULL);
604 }
605 
ti73_send_RID(CalcHandle * handle)606 TIEXPORT3 int TICALL ti73_send_RID(CalcHandle* handle)
607 {
608 	return tiz80_send_simple_cmd(handle, tiz80_handle_to_dbus_mid_7383p(handle), DBUS_CMD_RID, "RID", 2, NULL);
609 }
610 
ti73_send_SID(CalcHandle * handle,uint8_t * data)611 TIEXPORT3 int TICALL ti73_send_SID(CalcHandle* handle, uint8_t * data)
612 {
613 	return tiz80_send_simple_cmd(handle, tiz80_handle_to_dbus_mid_7383p(handle), DBUS_CMD_SID, "SID", 32, data);
614 }
615 
ti73_recv_VAR(CalcHandle * handle,uint16_t * varsize,uint8_t * vartype,char * varname,uint8_t * varattr,uint8_t * version)616 TIEXPORT3 int TICALL ti73_recv_VAR(CalcHandle* handle, uint16_t * varsize, uint8_t * vartype, char *varname, uint8_t * varattr, uint8_t * version)
617 {
618 	uint8_t host, cmd;
619 	uint8_t *buffer;
620 	uint16_t length;
621 	char trans[127];
622 	int ret;
623 
624 	VALIDATE_HANDLE(handle);
625 	VALIDATE_NONNULL(varsize);
626 	VALIDATE_NONNULL(vartype);
627 	VALIDATE_NONNULL(varname);
628 	VALIDATE_NONNULL(varattr);
629 	VALIDATE_NONNULL(version);
630 
631 	buffer = (uint8_t *)handle->buffer;
632 	memset(buffer, 0, 13);
633 	ret = dbus_recv(handle, &host, &cmd, &length, buffer);
634 	if (ret)
635 	{
636 		return ret;
637 	}
638 
639 	if (cmd == DBUS_CMD_EOT)
640 	{
641 		return ERR_EOT; // not really an error
642 	}
643 
644 	if (cmd == DBUS_CMD_SKP)
645 	{
646 		return ERR_VAR_REJECTED;
647 	}
648 
649 	if (cmd != DBUS_CMD_VAR)
650 	{
651 		return ERR_INVALID_CMD;
652 	}
653 
654 	if(length < 9 || length > 13) //if ((length != (11 + EXTRAS)) && (length != 9))
655 	{
656 		return ERR_INVALID_PACKET;
657 	}
658 
659 	*varsize = buffer[0] | (((uint16_t)buffer[1]) << 8);
660 	*vartype = buffer[2];
661 	memcpy(varname, (char *)buffer + 3, 8);
662 	varname[8] = '\0';
663 	*version = buffer[11];
664 	*varattr = (buffer[12] & 0x80) ? ATTRB_ARCHIVED : ATTRB_NONE;
665 
666 	ticonv_varname_to_utf8_sn(handle->model, varname, trans, sizeof(trans), *vartype);
667 	ticalcs_info(" TI->PC: VAR (size=0x%04X=%d, id=%02X, name=%s, attr=%d)", *varsize, *varsize, *vartype, trans, *varattr);
668 
669 	return 0;
670 }
671 
ti82_recv_VAR(CalcHandle * handle,uint16_t * varsize,uint8_t * vartype,char * varname)672 TIEXPORT3 int TICALL ti82_recv_VAR(CalcHandle* handle, uint16_t * varsize, uint8_t * vartype, char *varname)
673 {
674 	uint8_t host, cmd;
675 	uint8_t *buffer;
676 	uint16_t length;
677 	char trans[127];
678 	int ret;
679 
680 	VALIDATE_HANDLE(handle);
681 	VALIDATE_NONNULL(varsize);
682 	VALIDATE_NONNULL(vartype);
683 	VALIDATE_NONNULL(varname);
684 
685 	buffer = (uint8_t *)handle->buffer;
686 	ret = dbus_recv(handle, &host, &cmd, &length, buffer);
687 	if (ret)
688 	{
689 		return ret;
690 	}
691 
692 	if (cmd == DBUS_CMD_EOT)
693 	{
694 		return ERR_EOT;		// not really an error
695 	}
696 
697 	if (cmd == DBUS_CMD_SKP)
698 	{
699 		return ERR_VAR_REJECTED;
700 	}
701 
702 	if (cmd != DBUS_CMD_VAR)
703 	{
704 		return ERR_INVALID_CMD;
705 	}
706 
707 	if ((length != 11) && (length != 9))
708 	{
709 		return ERR_INVALID_PACKET;
710 	}
711 
712 	*varsize = buffer[0] | (((uint16_t)buffer[1]) << 8);
713 	*vartype = buffer[2];
714 	memcpy(varname, (char *)buffer + 3, 8);
715 	varname[8] = '\0';
716 
717 	ticonv_varname_to_utf8_sn(handle->model, varname, trans, sizeof(trans), *vartype);
718 	ticalcs_info(" TI->PC: VAR (size=0x%04X=%d, id=%02X, name=%s)", *varsize, *varsize, *vartype, trans);
719 
720 	return 0;
721 }
722 
ti85_recv_VAR(CalcHandle * handle,uint16_t * varsize,uint8_t * vartype,char * varname)723 TIEXPORT3 int TICALL ti85_recv_VAR(CalcHandle* handle, uint16_t * varsize, uint8_t * vartype, char *varname)
724 {
725 	uint8_t host, cmd;
726 	uint8_t *buffer;
727 	uint16_t length;
728 	char trans[127];
729 	int ret;
730 
731 	VALIDATE_HANDLE(handle);
732 	VALIDATE_NONNULL(varsize);
733 	VALIDATE_NONNULL(vartype);
734 	VALIDATE_NONNULL(varname);
735 
736 	buffer = (uint8_t *)handle->buffer;
737 	ret = dbus_recv(handle, &host, &cmd, &length, buffer);
738 	if (ret)
739 	{
740 		return ret;
741 	}
742 
743 	if (cmd == DBUS_CMD_EOT)
744 	{
745 		return ERR_EOT;		// not really an error
746 	}
747 
748 	if (cmd == DBUS_CMD_SKP)
749 	{
750 		return ERR_VAR_REJECTED;
751 	}
752 
753 	if (cmd != DBUS_CMD_VAR)
754 	{
755 		return ERR_INVALID_CMD;
756 	}
757 
758 	//if((length != (4+strlen(varname))) && (length != 9))
759 	//return ERR_INVALID_PACKET;
760 
761 	*varsize = buffer[0] | (((uint16_t)buffer[1]) << 8);
762 	*vartype = buffer[2];
763 	if (*vartype != TI8586_BKUP)
764 	{
765 		uint8_t len = buffer[3];
766 		if (len > 8)
767 		{
768 			len = 8;
769 		}
770 		memcpy(varname, (char *)buffer + 4, len);
771 		varname[8] = '\0';
772 	}
773 	else
774 	{
775 		memcpy(varname, (char *)buffer + 3, 8);
776 	}
777 
778 	ticonv_varname_to_utf8_sn(handle->model, varname, trans, sizeof(trans), *vartype);
779 	ticalcs_info(" TI->PC: VAR (size=0x%04X=%d, id=%02X, name=%s)", *varsize, *varsize, *vartype, trans);
780 
781 	return 0;
782 }
783 
784 /* FLASH (special var header: size, id, flag, offset, page) */
ti73_recv_VAR2(CalcHandle * handle,uint16_t * length,uint8_t * type,char * name,uint16_t * offset,uint16_t * page)785 TIEXPORT3 int TICALL ti73_recv_VAR2(CalcHandle* handle, uint16_t * length, uint8_t * type, char *name, uint16_t * offset, uint16_t * page)
786 {
787 	uint8_t host, cmd;
788 	uint8_t *buffer;
789 	uint16_t len;
790 	int ret;
791 
792 	VALIDATE_HANDLE(handle);
793 	VALIDATE_NONNULL(length);
794 	VALIDATE_NONNULL(type);
795 	VALIDATE_NONNULL(name);
796 	VALIDATE_NONNULL(offset);
797 	VALIDATE_NONNULL(page);
798 
799 	buffer = (uint8_t *)handle->buffer;
800 	ret = dbus_recv(handle, &host, &cmd, &len, buffer);
801 	if (ret)
802 	{
803 		return ret;
804 	}
805 
806 	if (cmd == DBUS_CMD_EOT)
807 	{
808 		return ERR_EOT; // not really an error
809 	}
810 
811 	if (cmd == DBUS_CMD_SKP)
812 	{
813 		return ERR_VAR_REJECTED;
814 	}
815 
816 	if (cmd != DBUS_CMD_VAR)
817 	{
818 		return ERR_INVALID_CMD;
819 	}
820 
821 	if (len != 10)
822 	{
823 		return ERR_INVALID_PACKET;
824 	}
825 
826 	*length = buffer[0] | (((uint16_t)buffer[1]) << 8);
827 	*type = buffer[2];
828 	memcpy(name, (char *)buffer + 3, 3);
829 	name[3] = '\0';
830 	*offset = buffer[6] | (((uint16_t)buffer[7]) << 8);
831 	*page = buffer[8] | (((uint16_t)buffer[9]) << 8);
832 	*page &= 0xff;
833 
834 	ticalcs_info(" TI->PC: VAR (size=0x%04X=%d, type=%02X, name=%s, offset=%04X, page=%02X)", *length, *length, *type, name, *offset, *page);
835 
836 	return 0;
837 }
838 
tiz80_recv_CTS(CalcHandle * handle,uint16_t length)839 TIEXPORT3 int TICALL tiz80_recv_CTS(CalcHandle* handle, uint16_t length)
840 {
841 	uint8_t host, cmd;
842 	uint16_t len;
843 	uint8_t *buffer;
844 	int ret;
845 
846 	VALIDATE_HANDLE(handle);
847 
848 	buffer = (uint8_t *)handle->buffer;
849 	ret = dbus_recv(handle, &host, &cmd, &len, buffer);
850 	if (ret)
851 	{
852 		return ret;
853 	}
854 
855 	if (cmd == DBUS_CMD_SKP)
856 	{
857 		return ERR_VAR_REJECTED;
858 	}
859 	else if (cmd != DBUS_CMD_CTS)
860 	{
861 		return ERR_INVALID_CMD;
862 	}
863 
864 	if (length != len)
865 	{
866 		return ERR_CTS_ERROR;
867 	}
868 
869 	ticalcs_info(" TI->PC: CTS");
870 
871 	return 0;
872 }
873 
tiz80_recv_SKP(CalcHandle * handle,uint8_t * rej_code)874 TIEXPORT3 int TICALL tiz80_recv_SKP(CalcHandle* handle, uint8_t * rej_code)
875 {
876 	uint8_t host, cmd;
877 	uint16_t length;
878 	uint8_t *buffer;
879 	int ret;
880 
881 	VALIDATE_HANDLE(handle);
882 	VALIDATE_NONNULL(rej_code);
883 
884 	buffer = (uint8_t *)handle->buffer;
885 	*rej_code = 0;
886 	ret = dbus_recv(handle, &host, &cmd, &length, buffer);
887 	if (ret)
888 	{
889 		return ret;
890 	}
891 
892 	if (cmd == DBUS_CMD_CTS)
893 	{
894 		ticalcs_info(" TI->PC: CTS");
895 		return 0;
896 	}
897 
898 	if (cmd != DBUS_CMD_SKP)
899 	{
900 		return ERR_INVALID_CMD;
901 	}
902 
903 	*rej_code = buffer[0];
904 	ticalcs_info(" TI->PC: SKP (rejection code = %d)", *rej_code);
905 
906 	return 0;
907 }
908 
tiz80_recv_XDP(CalcHandle * handle,uint16_t * length,uint8_t * data,uint8_t is_73)909 static int tiz80_recv_XDP(CalcHandle* handle, uint16_t * length, uint8_t * data, uint8_t is_73)
910 {
911 	uint8_t host, cmd;
912 	int ret;
913 
914 	VALIDATE_HANDLE(handle);
915 
916 	ret = dbus_recv(handle, &host, &cmd, length, data);
917 	if (ret)
918 	{
919 		return ret;
920 	}
921 
922 	if (is_73 && cmd == DBUS_CMD_EOT)
923 	{
924 		ticalcs_info(" TI->PC: EOT");
925 		return ERR_EOT;
926 	}
927 	if (cmd != DBUS_CMD_XDP)
928 	{
929 		return ERR_INVALID_CMD;
930 	}
931 
932 	ticalcs_info(" TI->PC: XDP (%04X=%d bytes)", *length, *length);
933 
934 	return 0;
935 }
936 
ti73_recv_XDP(CalcHandle * handle,uint16_t * length,uint8_t * data)937 TIEXPORT3 int TICALL ti73_recv_XDP(CalcHandle* handle, uint16_t * length, uint8_t * data)
938 {
939 	return tiz80_recv_XDP(handle, length, data, 1);
940 }
941 
ti82_recv_XDP(CalcHandle * handle,uint16_t * length,uint8_t * data)942 TIEXPORT3 int TICALL ti82_recv_XDP(CalcHandle* handle, uint16_t * length, uint8_t * data)
943 {
944 	return tiz80_recv_XDP(handle, length, data, 0);
945 }
946 
ti85_recv_XDP(CalcHandle * handle,uint16_t * length,uint8_t * data)947 TIEXPORT3 int TICALL ti85_recv_XDP(CalcHandle* handle, uint16_t * length, uint8_t * data)
948 {
949 	return tiz80_recv_XDP(handle, length, data, 0);
950 }
951 
ti80_recv_XDP(CalcHandle * handle,uint16_t * length,uint8_t * data)952 TIEXPORT3 int TICALL ti80_recv_XDP(CalcHandle* handle, uint16_t * length, uint8_t * data)
953 {
954 	return tiz80_recv_XDP(handle, length, data, 0);
955 }
956 
ti73_recv_SID(CalcHandle * handle,uint16_t * length,uint8_t * data)957 TIEXPORT3 int TICALL ti73_recv_SID(CalcHandle* handle, uint16_t * length, uint8_t * data)
958 {
959 	uint8_t host, cmd;
960 	int ret;
961 
962 	ret = dbus_recv(handle, &host, &cmd, length, data);
963 	if (ret)
964 	{
965 		return ret;
966 	}
967 
968 	if (cmd == DBUS_CMD_EOT)
969 	{
970 		ticalcs_info(" TI->PC: EOT");
971 		return ERR_EOT;
972 	}
973 	else if (cmd != DBUS_CMD_SID)
974 	{
975 		return ERR_INVALID_CMD;
976 	}
977 
978 	ticalcs_info(" TI->PC: SID (%04X bytes)", *length);
979 
980 	return 0;
981 }
982 
983 /* ACK: receive acknowledge
984   - status [in/out]: if NULL is passed, the function checks that 00 00 has
985   been received. Otherwise, it put in status the received value.
986   - int [out]: an error code
987 */
tiz80_recv_ACK(CalcHandle * handle,uint16_t * status)988 TIEXPORT3 int TICALL tiz80_recv_ACK(CalcHandle* handle, uint16_t * status)
989 {
990 	uint8_t host, cmd;
991 	uint16_t length;
992 	uint8_t *buffer;
993 	int ret;
994 
995 	VALIDATE_HANDLE(handle);
996 
997 	buffer = (uint8_t *)handle->buffer;
998 	ret = dbus_recv(handle, &host, &cmd, &length, buffer);
999 	if (ret)
1000 	{
1001 		return ret;
1002 	}
1003 
1004 	if (status != NULL)
1005 	{
1006 		*status = length;
1007 	}
1008 	else if (length != 0x0000) // is an error code ? (=5 when app is rejected)
1009 	{
1010 		return ERR_NACK;
1011 	}
1012 
1013 	if (cmd != DBUS_CMD_ACK)
1014 	{
1015 		return ERR_INVALID_CMD;
1016 	}
1017 
1018 	ticalcs_info(" TI->PC: ACK");
1019 
1020 	return 0;
1021 }
1022 
ti82_recv_ERR(CalcHandle * handle,uint16_t * status)1023 TIEXPORT3 int TICALL ti82_recv_ERR(CalcHandle* handle, uint16_t * status)
1024 {
1025 	uint8_t host, cmd;
1026 	uint16_t sts;
1027 	int ret;
1028 
1029 	VALIDATE_HANDLE(handle);
1030 
1031 	ret = dbus_recv(handle, &host, &cmd, &sts, NULL);
1032 	if (ret && ret != ERR_CHECKSUM)
1033 	{
1034 		return ret;
1035 	}
1036 
1037 	if (status != NULL)
1038 	{
1039 		*status = sts;
1040 	}
1041 
1042 	if (cmd != DBUS_CMD_ERR)
1043 	{
1044 		return ERR_INVALID_CMD;
1045 	}
1046 
1047 	ticalcs_info(" TI->PC: ERR");
1048 
1049 	return 0;
1050 }
1051 
ti73_recv_RTS(CalcHandle * handle,uint16_t * varsize,uint8_t * vartype,char * varname,uint8_t * varattr,uint8_t * version)1052 TIEXPORT3 int TICALL ti73_recv_RTS(CalcHandle* handle, uint16_t * varsize, uint8_t * vartype, char *varname, uint8_t * varattr, uint8_t * version)
1053 {
1054 	uint8_t host, cmd;
1055 	uint8_t *buffer;
1056 	char trans[127];
1057 	int ret;
1058 
1059 	VALIDATE_HANDLE(handle);
1060 	VALIDATE_NONNULL(varsize);
1061 	VALIDATE_NONNULL(vartype);
1062 	VALIDATE_NONNULL(varname);
1063 	VALIDATE_NONNULL(varattr);
1064 	VALIDATE_NONNULL(version);
1065 
1066 	buffer = (uint8_t *)handle->buffer;
1067 	memset(buffer, 0, 13);
1068 	ret = dbus_recv(handle, &host, &cmd, varsize, buffer);
1069 	if (ret)
1070 	{
1071 		return ret;
1072 	}
1073 
1074 	if (cmd != DBUS_CMD_RTS)
1075 	{
1076 		return ERR_INVALID_CMD;
1077 	}
1078 
1079 	if (*varsize < 13)
1080 	{
1081 		return ERR_INVALID_PACKET;
1082 	}
1083 
1084 	*varsize = buffer[0] | (((uint16_t)buffer[1]) << 8);
1085 	*vartype = buffer[2];
1086 	memcpy(varname, (char *)buffer + 3, 8);
1087 	varname[8] = '\0';
1088 	*version = buffer[11];
1089 	*varattr = (buffer[12] & 0x80) ? ATTRB_ARCHIVED : ATTRB_NONE;
1090 
1091 	ticonv_varname_to_utf8_sn(handle->model, varname, trans, sizeof(trans), *vartype);
1092 	ticalcs_info(" TI->PC: RTS (size=0x%04X=%d, id=%02X, name=%s, attr=%d)", *varsize, *varsize, *vartype, trans, *varattr);
1093 
1094 	return 0;
1095 }
1096 
ti82_recv_RTS(CalcHandle * handle,uint16_t * varsize,uint8_t * vartype,char * varname)1097 TIEXPORT3 int TICALL ti82_recv_RTS(CalcHandle* handle, uint16_t * varsize, uint8_t * vartype, char *varname)
1098 {
1099 	uint8_t host, cmd;
1100 	uint8_t *buffer;
1101 	char trans[127];
1102 	int ret;
1103 
1104 	VALIDATE_HANDLE(handle);
1105 	VALIDATE_NONNULL(varsize);
1106 	VALIDATE_NONNULL(vartype);
1107 	VALIDATE_NONNULL(varname);
1108 
1109 	buffer = (uint8_t *)handle->buffer;
1110 	ret = dbus_recv(handle, &host, &cmd, varsize, buffer);
1111 	if (ret)
1112 	{
1113 		return ret;
1114 	}
1115 
1116 	if (cmd != DBUS_CMD_RTS)
1117 	{
1118 		return ERR_INVALID_CMD;
1119 	}
1120 
1121 	*varsize = buffer[0] | (((uint16_t)buffer[1]) << 8);
1122 	*vartype = buffer[2];
1123 	memcpy(varname, (char *)buffer + 3, 8);
1124 	varname[8] = '\0';
1125 
1126 	ticonv_varname_to_utf8_sn(handle->model, varname, trans, sizeof(trans), *vartype);
1127 	ticalcs_info(" TI->PC: RTS (size=0x%04X=%d, id=%02X, name=%s)", *varsize, *varsize, *vartype, trans);
1128 
1129 	return 0;
1130 }
1131 
ti85_recv_RTS(CalcHandle * handle,uint16_t * varsize,uint8_t * vartype,char * varname)1132 TIEXPORT3 int TICALL ti85_recv_RTS(CalcHandle* handle, uint16_t * varsize, uint8_t * vartype, char *varname)
1133 {
1134 	uint8_t host, cmd;
1135 	uint8_t *buffer;
1136 	char trans[127];
1137 	uint8_t strl;
1138 	int ret;
1139 
1140 	VALIDATE_HANDLE(handle);
1141 	VALIDATE_NONNULL(varsize);
1142 	VALIDATE_NONNULL(vartype);
1143 	VALIDATE_NONNULL(varname);
1144 
1145 	buffer = (uint8_t *)handle->buffer;
1146 	ret = dbus_recv(handle, &host, &cmd, varsize, buffer);
1147 	if (ret)
1148 	{
1149 		return ret;
1150 	}
1151 
1152 	if (cmd != DBUS_CMD_RTS)
1153 	{
1154 		return ERR_INVALID_CMD;
1155 	}
1156 
1157 	*varsize = buffer[0] | (((uint16_t)buffer[1]) << 8);
1158 	*vartype = buffer[2];
1159 	strl = buffer[3];
1160 	if (strl > 8)
1161 	{
1162 		strl = 8;
1163 	}
1164 	memcpy(varname, (char *)buffer + 4, strl);
1165 	varname[8] = '\0';
1166 
1167 	ticonv_varname_to_utf8_sn(handle->model, varname, trans, sizeof(trans), *vartype);
1168 	ticalcs_info(" TI->PC: RTS (size=0x%04X=%d, id=%02X, name=%s)", *varsize, *varsize, *vartype, trans);
1169 
1170 	return 0;
1171 }
1172