Re: TI-hp link


[Prev][Next][Index][Thread]

Re: TI-hp link



On 23 Jul 1996 14:07:51 GMT,  [1mDoug Sapp [0m <c639692@gold.missouri.edu>
wrote:
>James Rankin (monty@nrv.net) wrote:
>: Muhammad A. Khan wrote:
>: > 1. What type of sending protocol does the ti use and what are the baud
rates
>
>: The 92 works at 9600 baud.
>
>Yeah, but what's the protocal?  I've got an HP and a TI-92.  HP is real
>easy to link because it's a standard RS-232 port supporting XModem and
>Kermit.  As far as I can tell TI made up their own protocal.
>
You will also notice that raw signals themselves are also quite diffrent
from RS-232. Here is a bit of information.




--- port_7.txt ---


                        /-----------------\
                        | TI-85 LINK info |
                        |      Port 7     |
                        \-----------------/
                                by
                         Branislav Bozgai
                        bozgai@svf.stuba.sk
                               1995
Connector:
----------        _____
Jack 2.5mm stereo  | | - GND (Ground)
                   |_|
                   |_| - W (White wire)
                   |_| - R (Red wire)




Electrical performance:
-----------------------
All data are transmitted in binary form - logical '1' or '0'
        1 = 5V (4.9V)
        0 = 0V
but TI-85 uses 'negative logic' that means: 0 (0V) = active signal
                                            1 (5V) = not active
So when you turn your calculator ON you can measure between W and GND 5V
(also between R and GND 5V) that means everything is in quiet state.




Programming:
------------
Sending:
If you want to make some wire active: OUT(7),$E8 ; W=0, R=1
                                      OUT(7),$D4 ; W=1, R=0
                                      OUT(7),$FC ; W=0, R=0
To deactivate signals:                OUT(7),$C0 ; W=1, R=1


In assembly (e.g. if I want to make W active):  LD   A,$E8
                                                OUT  (7),A


You can use other numbers to out (but may cause abnormal operation,
I think that I can explain how it works) but TI's system is using only
those above.


Note: Don't forget to out $C0 at the end of transmittion otherwise
      both sending and receiving calculators slow down.
      TI is using $FC to signalise an error.


Reading:  IN   A,(7)
          AND  3                        ; upper bits are not important
          CP   3
          JR   Z, Nothig_is_active      ; W=1, R=1
          CP   2
          JR   Z, R_is_active           ; W=1, R=0
          CP   1
          JR   Z, W_is_active           ; W=0, R=1
          CP   0
          JR   Z, W_and_R_are_active    ; W=0, R=0


$C0 = 192 = %11000000
$D4 = 212 = %11010100
$E8 = 232 = %11101000
$FC = 252 = %11111100


All routines related to link port are in ROM page 5.
In TALK I'm using ROM_send_byte and ROM_read_byte routines.
ROM_send_byte is at address:    $643B = LD  C,A
                          to    $647C = RET
Input:    A - byte to send
Destroys: DE, BC, HL


ROM_read_byte is at address:    $6559 = LD  B,$08
                          to    $65CB = JR  $6603
Output:   A - received byte
Destroys: DE, BC, HL


But I'm mot calling this routines directly because they both call
function $0A87 (which is error handler I think) which cause crash.
Can somebody help with that?
I've modified them slightly replaced JP to JR and JP $0A87 to RET.


*********************************************************************
There were questions on calc-ti about where can people get from
Dan Eble's ZShell and other asm progs.
So I'm running anonymous FTP server at address:
                       ftp.svf.stuba.sk
There is directory ti and there you'll find everything you want.
Feel free to upload anything you want into ti/incoming.
I'll move it into readable area within a week.
NOTE:If you can't get connection, the server may be down so please
     try later (we are trying to keep it in work non-stop but we have
     some problems)


Any comments or questions to this file mail to: bozgai@svf.stuba.sk
or copy to /dev/null :)






-- protocol.txt --


by Per Finander
e-mail: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 &amp; 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 &amp; 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 &amp; 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 &amp; DSR }
   SetPort(3);
 end;




--------------------------
Per Finander
e-mail:pfimdt93@hvdc.hv.se


References: