Re: A86: graphlink protocol
[Prev][Next][Index][Thread]
Re: A86: graphlink protocol
On Fri, 12 Sep 1997, Joseph Gaffney wrote:
> At 10:10 PM 9/12/97 -0400, Butler Family wrote:
> >can someone give me some info on the graphlink protocol sending and
> >recieving and how the .86* files are saved
> >thanx
> >Patrick
> >
>
> I do believe it is simply RS232 protocol, the PIC in the GL changes it.
>
The GraphLink is I2C (eye-squared-see) on the calc end and RS232 on the
computer end. I've attached a file Per Finander cooked up back in the
good old days of TI-85 hacking.
--------
Dan Eble (mailto:eble@cis.ohio-state.edu)
(http://www.cis.ohio-state.edu/~eble)
Date: 12-14-94 (13:36) * Number: 4848 of 4865 (Refer# NONE)
To: DAN EBLE
From: pfimdt93@hvdc.hv.se, PER FINANDER
Subj: Calc-TI - TI85/TI82 Link protocol
Message-ID: <941214143653.353b-2.2b8-pfimdt93@hvdc.hv.se>
TI85/TI82 link-protocol
-----------------------
The linkinterface uses 2 outputs (RTS/DTR) and 2 inputs (CTS/DSR) on the
serial port to communicate with the TI85/TI82. The bits CTS/DSR can be
read from port $3F8+6, bit 4 (CTS) and bit 5 (DSR). The bits RTS/DTR is
controlled from port $3F8+4, bit 0 (DTR) and bit 1 (RTS). $3F8 is the port-
address for COM1: (or $2F8 if COM2: is used).
I've included 5 routines in Pascal to show how to send/receive bytes to/from
the TI85/TI82. These routines are not optimized and doesn't contain any
timeout check. The constant "PortAddr" contains the base-port address to the
com-port. PortAddr=$3F8 if the link-interface is in COM1: or $2F8 if COM2: is
used. The "InitPort" procedure must be called as fast as possible, because
if CTS & DSR isn't set, then the calculator will slow down when the link
is connected.
All data is sent in packages. A packet looks like this:
ID From: $85=TI85 ($82=TI82), $05 (Computer communicating with TI85) /
| $02 (Computer communicating with TI82)
|
| Command: $06 : Variable-header (used to initiate a variabletransmission)
| | $15 : Data part (the datapart of a variable)
| | $36 : Answer skip/abort
| | $56 : Package received OK (used to acknowledge a package)
| | $92 : No more variables to send (used to end a transmission)
| | $6D : Send screendump
| | Low byte
| | Data word / Size of DataPart | High byte
| | | Data zero or more bytes | |
|-- |-- |---- |----------------- |- |-
$85 $56 00 00 [DataPart:00 .. 00 Checksum: 00 00]
Checksum=(Sum of all bytes in the datapart) and 65535
A transmission can look like this:
a variable: ABC:REAL=3.1415... (PI) from TI85 to computer (all values in hex)
ID $85=TI85 (byte, $82 for a TI82)
| Command (byte): Var-header
| | Packet length (word, 4+NameLength for a Var-header)
| | |
| | | ------Datapart------
| | | Variable length (word)
| | | | Type (byte 0=Real number)
| | | | | Name Length (byte)
| | | | | | Name
| | | | | | | Checksum,(0A+03+41+42+43) and FFFF
|- |- |---- |---- |- |- |------- |----
TI85: 85 06 07 00 0A 00 00 03 41 42 43 D3 00
COMPUTER: 05 56 00 00
|- |- |----
| | No packet
| Command: Received OK
ID $05 = Computer <=> TI85
($02 = Computer <=> TI82)
Received OK
| Command: Data part
| | Packet length: 10 bytes for a REAL
| | | Data (PI)
|- |- |---- |----------------------------
TI85: 85 56 00 00 85 15 0A 00 00 00 FC 31 41 59 26 53 58 98
COMPUTER: 05 09 00 00
|- |----
| No packet
Command: Ready to receive data part
Checksum Command: No more variables
| | 10 bytes data was sent
|---- |- |----
TI85: 30 03 85 92 0A 00 "Done..."
COMPUTER: 05 56 00 00 05 56 00 00 END
|- |-
Received OK Received OK
If a TI82 is used instead of a TI85, the Var-header command changes:
1. The "Type" byte - TI82/TI85 have different variable types
2. The "Name length" byte - don't exists for the TI82. The name is Zero-
terminated.
Example: the variable ABC on a TI82 (header command):
82 06 07 00 0A 00 00 41 42 43 00 D0 00
|------- |-
Name Zero - terminates the string
After a Var-header have been sent, then the calculator (or computer) waits
for a "Received OK"-command and an answer. The answer can be one of the
following (the computer sends, TI85 receives and answers) :
85 09 07 00 : Continue (header-datalength: 7 bytes)
85 5A 07 00 : Checksum error, send last package again
The two following answers can occur if the variable already exists in memory:
85 36 01 00 02 02 00 : Variable skipped ("Skip" was pressed)
85 36 01 00 01 01 00 : Variable refused ("Exit" was pressed)
If more than one variable is send, then a "Var-header" command when the
reciever (calculator or computer),have acknowledged the datapackage instead
of a "No more variables"-command.
The "Type"-byte (for a TI85) can have one of the following values (hex):
00 Real
01 Cplx
02 Vectr 03 Vectr complex
04 List 05 List complex
06 Matrx 07 Matrx complex
08 Const 09 Const complex
0A Equ
0B Range
0C Strng
0D-10 GDB
11 Pict
12 Prgm
13 Range
14 ?
15-1B Range
I'm not sure everything's alright about the TI82 because I just borrowed one
for a weekend. But if anyone can figure out more about the TI82 and the
CBL-format (for both TI82 & TI85), send me a note.
Note:
The "Send screendump" command can be sent to the TI85/TI82 to download
a screendump to the computer. The TI85/TI82 will send a "Received Ok"-command
and the a datapackage of 1024 bytes. The datapackage is a copy of the
memoryarea $FC00-FFFF (the screen). This works almost anytime (it's not
necessary the calculator is in the LINK-menu), but it won't work when a
program is running (except if the program is waiting for a key).
****** Procedure to set/reset RTS/DTR:
procedure SetPort(Bits:Byte);
{ Input: "Bits", a byte 0 - 3, bit 0 = DTR, bit 1 = RTS }
begin
Port[PortAddr+4]:=Bits and 3;
end;
****** Function to read CTS/DSR:
function GetPort:Byte;
{ Returns a byte 0 - 3, bit 0 = CTS, bit 1 = DSR }
{ if GetPort returns 0, then the calculator have noticed a timeout }
begin
GetPort:=(Port[PortAddr+6] and 48) div 16;
{ if KeyPressed then HALT(1); }
{ Add the line above if you don't add a timeout-check somewhere else. }
{ The program will probably hang in "GetPort" when the calculator }
{ causes a Timeout }
end;
****** To send a byte to the TI85/TI82:
procedure Send(B:Byte);
{ Sends the byte B to the calculator }
var
BitLoop:Byte;
begin
{ Send the bits from bit 0 -> bit 7 }
SetPort(3);
for BitLoop:=0 to 7 do begin
{ Wait for calculator to be ready to recieve a bit }
{ RTS and DTR must be set }
while GetPort<>3 do;
if (B and 1)=0 then begin
{ Send 0 : DTR=1, DSR=0 }
SetPort(1);
{ Wait for calculator to set RTS=1 }
while (GetPort and 2)=2 do;
{ CTS=1, DSR=1 }
SetPort(3);
{ Wait for calculator to set RTS=0 }
while (GetPort and 2)=0 do;
end else begin
{ Send 1 : CTS=0, DSR=1 }
SetPort(2);
{ Wait for calculator to set DTR=1 }
while (GetPort and 1)=1 do;
{ CTS=1, DSR=1 }
SetPort(3);
{ Wait for calculator to set DTR=0 }
while (GetPort and 1)=0 do;
end;
B:=B div 2;
end;
end;
****** To recieve a byte from the TI85/TI82:
function Receive:Byte;
{ Recieves a byte from calculator }
var
B,CurrentBit,BitLoop:Byte;
begin
CurrentBit:=1;
B:=0;
{ Recieve bit 0 first }
SetPort(3);
for BitLoop:=0 to 7 do begin
{ Wait for the calculator to send a bit }
while GetPort=3 do;
{ Check it the calculator sends a 1 or 0 }
if GetPort=1 then begin
{ 1 }
B:=B or CurrentBit;
{ CTS=1, DSR=0 }
SetPort(1);
{ Wait while RTS=0 }
while (GetPort and 2)=0 do;
end else begin
{ 0 }
{ CTS=0, DSR=1 }
SetPort(2);
{ Wait while DTR=0 }
while (GetPort and 1)=0 do;
end;
{ CTS=1, DSR=1 }
SetPort(3);
{ Wait for calculator to set RTS & DTR }
while GetPort<>3 do;
CurrentBit:=CurrentBit*2;
end;
Receive:=B;
end;
****** Initiates the com-port (MUST be called before anything else)
procedure InitPort;
begin
Port[PortAddr+1]:=0;
Port[PortAddr+2]:=1;
Port[PortAddr+3]:=0;
Port[PortAddr+4]:=3;
Port[PortAddr+5]:=96;
Port[PortAddr+6]:=50;
Port[PortAddr+7]:=0;
{ Set CTS & DSR }
SetPort(3);
end;
--------------------------
Per Finander
e-mail:pfimdt93@hvdc.hv.se
References: