Home  |  < Projects >  |  About  |  Links Enhanced  |  Home

NGL  |  CVSreport  |  blof  |  crmtrainer  |  htgrep  |  dbackup  |  vctool  |  wormstat  |  Cell shading  |  GLtune  |  < TI92 >

TI92 link protocol

Release 1.0 03/21/1997
"How to communicate with the TI92 from a computer & PC application" Vincent CARON (Vincent.Caron@ecl1999.ec-lyon.fr)

1 - Home made cable
2 - Hardware protocol

1 - TI packets
2 - Packets description
3 - Variable data description
4 - Retrieve/send variable
5 - TI92 directory
6 - Screen dump
7 - Backups
8 - Remote control

- This technical documentation file comes along the PLINK! communication
  software. Please contact the author for more informations.
- All numbers are in HEXADECIMAL format (OFFSETs and DATA BYTEs), except
  when stated. Example : 1..27d reads "1 to 27 decimal".
- All strings are in C format. They are arrays [1..maxsize] of char, with
  an ending zero if the actual size of the string is less than maxsize.
  In this case, any char after a #0 has no meaning and is not obviously
  equal to #0.
  It seems that the TI92 pads strings with #0 all the time.
- Data description convention :
    offset     length (bytes)     description/type
       +0           1                  beginning (byte [unsigned])
       +xx          yy                 ...
  You will also encounter :
    xl xh       : x is a word, read LSB first (l=low / h=hi)
    Ll Lh Hl Hh : read a double word, LSB first.
  This is Pascal BOURON's notation (thanks !).
- No type is signed unless stated. (byte,word,double word)
- Due to the fact that the Motorola MC68000 processor uses the big endian
  format, you must read integers from left to right, LSB first (Least
  Significant Byte). Example :
       +10        4       12 51 78 A3 (double word)
  You will read the double word A3785112 at offset 10 (hexa).
  Remember that Intel's processors (ix86) use little endian format : you
  read integers from left to right, MSB first (Most Significant Byte). Thus
  12 51 78 A3 is the double word 125178A3.
  LSB (TI92) or MSB (PC) first will be specified for integers longer than
  a byte.
  Practically, you will only find big endian format (MC68000, LSB first)
  integers in TI92's protocol. Little endian format only appears on PC's
  archive files.
- These informations are the result of long researches (since 02/95!), and
  have been completed with and compared to TI-PROT.TXT by Pascal BOURON
  (bouron@ENS-Cachan.fr). Hardware communication routines by Ben EATER
  (themouse@wam.umd.edu) and George NACHMAN (ltduck@wam.umd.edu).
  You can find other informations from David ELLSWORTH (davidells@aol.com),
  the author of FARGO (TI92 assembly support), Dan EBLE and Rob TAYLOR
  (see http://www.ticalc.org).
- General consideration on TI92's behaviour (reliable for ROM 1.3) :
   * unless stated, all communications run well when the TI92 is in its
     HOME screen. Variable transfer won't work if a dialogue is open (the
     TI92 will send 'not ready' to any attempt).
   * if the TI92 is switched off, it will turn on when a byte is send thru
     the link port. The TI92 needs about 800 ms to wake up (delay to reach
     the 'ready' state).
   * the TI92 auto-power off feature will turn off the calc within 1 or 2
     minutes when the TI92 has been woken up by the link port. Normal
     activity auto-power off needs 6 idle minutes.
   * with "home made" cables, the TI92 seems to freeze sometimes. This is
     due to LPT1 idle state (0) not corresponding to TI92 idle state (lines
     to 1).
     Win'95 always reset LPT1 to 0 when closing a DOS session (Win3.1 does
     not). So be careful, and remember to unplug your TI92 when you are
     finished (or else the batteries won't cope).
     Note that the TI92 needs about 800 ms to recover from the "frozen"
     state (that is to be in a 'ready state').


  This cable works on a parallel port of a PC computer. It should actually
work with any computer having a standard parallel port.

  Components required :
    - a 25 pins male D-sub
    - a 2.5 mm stereo jack
    - 2 wires shielded cable (<1.5 m)
    - 2 silicon diodes (supporting some mA, 0.6V threshold, like 1N4148)

 \ .   .   .   .   .   .   .   .   .   .   .   .   . /
  \  .   .   .   .   .   .   .   .   .   .   .   .  /   D-sub 25pin male

     13             3      12             2   22        Pin number
      |             |       |             |    |
      | ----------- |       | ----------- |    |
      |-|    D  | |-|       |-|    D  | |-|    |        Diodes
      | -----------         | -----------      |
      |                     |                  |
      |                     |                  |
      |                     |                  |
    Head                  Ring              Shield

           Head  Ring  Shield
             |     |      |
             |     |      |    OOOOOOOO
           OOOO   OOO  OOOOOOO
          OOOOO   OOO  OOOOOOO                          2.5 mm Jack
           OOOO   OOO  OOOOOOO

  Parallel port pin-out :
     2  D0   data bit 0
     3  D1   data bit 1
    12  PO   Paper Out
    13  OL   On Line
    22  GND  Ground

    Be carefull when purchasing the 2.5 mm jack plug. They often have
  slightly different shapes that could lead to the following problems.
  If the pin is too tight, you will have bad connections. But if the pin
  has a too big 'head', you are likely to damage your I/O port. Further
  use of TI's cable (with cylindrical pin) could be impossible.

  The TI92 calculator doesn't use the standard RS232 serial link protocol.
Describing the complete hardware protocol goes below the scope of this file.
If you use a home-made parallel port link cable, the following pseudo-code
will be convenient for a PC:
   (thanks to George NACHMAN and Ben EATER)

  - InPort and OutPort refer to the two different registers of the PIO
    controller. For a PC, OutPort=LPTx base address (data register),
    Inport=OutPort+001 (status register). Pins D0 and D1 are used for PC
    output, pins OL (On Line) and PO (Paper Out) are used for PC input.
      OutPort=$01 (bit 0, data register)  -> D0 set to +5V
      OutPort=$02 (bit 1, data register)  -> D1 set to +5V
      InPort =$10 (bit 4, status register)-> OL set to +5V
      Inport =$20 (bit 5, status register)-> PO set to +5V

  - The Wait() instruction waits for a boolean to be true or a constant
    delay to be up. When a problem occurs, the execution should not be
    stuck in a Wait(), waiting for a never coming InPort value.

Procedure Send (x : byte)
 | Byte n
 | For n<-0 To 7                 ;send low to hi bit of x
 |   OutPort<-$03                ;assume port is idle
 |   If (x And 2^n)=0
 |     OutPort<-$01              ; bit n of x is cleared
 |     Wait (InPort And $20=0)
 |     OutPort<-$03
 |     Wait (InPort And $20=$20)
 |   Else
 |     OutPort<-$02              ; bit n of x is set
 |     Wait (InPort And $10=0)
 |     OutPort<-$03
 |     Wait (InPort And $10=$10)
 |   EndIf
 | EndFor
End Send()

Function Get : Byte
 | Byte i,n,x
 | x<-0
 | For n<-0 To 7                           ;get low to hi bit of x
 |   Wait ((i<-InPort And $30)<>$30)       ;C-like code !
 |   If i=$10
 |     x<-x+2^n                            ;bit n of x is set
 |     OutPort<-$01
 |     Wait ((InPort And $20)=$20)
 |   Else
 |     OutPort<-$02                        ;bit n of x is cleared
 |     Wait ((InPort And $10)=$10)
 |   EndIf
 |   OutPort<-$03                          ;assume port is idle
 | EndFor
 | Return (x)
End Send

    These routines should be working on other platforms than PC... I would
  be pleased hearing that. I may also try them on a HP Apollo/9000 (Unix
  platform), but I don't think a lot of people would be interested in a
  Unix version...
    I reached a 6 Kb/s transfer rate with an assembler version of these
  routines, but they were unreliable on fast computers. A safe way to code
  them is to code them slow.


  The TI92 calculator like other TI calcs doesn't communicate in raw mode,
that is sending datas directly to the port. Instead, the protocol consists
of a dialogue between the computer and the calc. This dialogue consists of
words called 'packets'. Physically, a packet cannot be less than 4 bytes,
and has a standard format :

    +0     1    Sender
    +1     1    Type
    +2     2    info (often n = the packet size)
  BODY          (some packet types only)
    +4     n    n data bytes
  CHECKSUM      (some packet types only)
    +4+n   2    checksum

  To calculate the checksum of the packet, you'll have to sum byte by byte
the n data bytes of the BODY in an unsigned 16bits counter. Then compare
it to the CHECKSUM given in the packet (LSB first) : if it doesn't match
with the calculated checksum, the packet is corrupted.

  Sender :
    09 = Computer
    89 = TI92

  Type :
    06 = Variable header
          size=info (LSB first) (7 to 23 bytes)
    09 = Wait state
          info=0 or -1
    15 = Variable data
          size=info (LSB first)
    56 = Busy state
          info=0 (sender ready)
          info=1 (sender busy)
    68 = Check state
    6D = Screen dump
    78 = Continue
    87 = Remote control
          info=key code (LSB first) (see TI92 manual)
    92 = End of transmission
    A2 = Request (variable or directory)
          size=info (LSB first)

    xx stands for the sender, equals 09 for PC->TI92 transfers, 89 for
  TI92->PC. Some packets are unidirectionnal (only PC->TI92 for 6D/screen
  dump, 87/remote control, A2/request).

    06 (variable header)
       HEADER     xx 06 lo hi
       BODY       Ll Lh Hl Hh ty le c1 c2 ...
       CHECKSUM   sl sh

       lo hi       = BODY size (7..23d bytes) (word)
       Ll Lh Hl Hh = variable size (long word)
       ty          = variable type (see table below)
       le          = length of the variable name string (1..17 chars)
       c1 c2 ...   = variable name string
       sl sh       = checksum of BODY (word)

       Valid TI92 variables types are :
           00   EXPR          0E   FIG
           04   LIST          10   PIC
           06   MAT           12   PGRM
           0A   DATA          13   FUNC
           0B   TEXT          14   MAC
           0C   STR           19   DIR
           0D   GDB           1F   FOLD
         The 'DIR' type is only used for the TI92's directory request. Do not
       mix up with 'FOLD' which is a TI92 folder. (see section 5) The TI92
       also uses a pseudo-variable for backups, type 1D.

         The name of a variable is between 1 and 17d bytes long. A directory
       path can be added to the name of the variable, using char '\'. Both
       names and directories must not exceed 8 chars. Examples :

         When the TI92 receives a single variable name "varxxxxx", it will
       store it on its current folder, and overwrite it without any warning
       if the variable already exists.
         If the TI92 receives a variable name with its path "pathxxx\varxxxx",
       it will try to receive it to the "pathxxxx" folder. If the folder does
       not exist, it will be immediatly created. If the variable already
       exists, it will be overwritten without any warning.
         (These two paragraphs apply to the direct transfer protocol, working
       while the TI92 is in its HOME page. You will get erasing confirmations
       if you use the Var-Link.)

         Variable type 1F is special : this is the description of a TI92
       folder. In this case, the variable name string is a 1 to 8 chars
       string, and the variable size refers to the number of variable held
       in this folder.

    09 (Wait state)
       HEADER     xx 09 00 00
       BODY       none
       CHECKSUM   none

         The sender means to the receiver it is waiting for data.

    15 (variable data)
       HEADER     xx 15 lo hi
       BODY       ?? ?? ?? ...
       CHECKSUM   sl sh

       lo hi = BODY size (word)
       sl sh = checksum of BODY (word)

         The body of variable data packets depends on the variable type.
       You can read the description of some variable data packet bodies in
       section 3.

    56 (Busy state)
       HEADER     xx 56 00 st
       BODY       none
       CHECKSUM   none

       st = state byte

         If st=0 then the sender (xx) is ready for transfer. If st<>0, the
       sender is not ready to accept data (st=1 usually).

    68 (State request)
       HEADER     xx 68 00 00
       BODY       none
       CHECKSUM   none

         This packet is a 'command' that waits for a 'busy state packet' (56)
       and thus check if the receiver is available for transfer.

    6D (screen dump)
       HEADER     09 6D 00 00
       BODY       ?? ?? ?? ...
       CHECKSUM   sl sh

       lo hi = BODY size (word)
       sl sh = checksum of BODY (word)

         The TI92 can be asked a screen backup at any time. It will answer
       a data packet (type 15), whose body contains a 240*128d bitmap (3840d
       bytes). See section 6.

    87 (remote control)
       HEADER     09 87 lo hi
       BODY       none
       CHECKSUM   none

       lo hi = key code (word)

         The remote control feature perfectly simulates a key press on TI92's
       keyboard. See section 8.

    92 (end of transmission)
       HEADER     xx 92 00 00
       BODY       none
       CHECKSUM   none

       This is a command used at the end of a transfer dialogue, to release
    the receiver device.

    A2 (variable/directory request)
       HEADER     09 A2 lo hi
       BODY       00 00 00 00 ty le c1 c2 ...
       CHECKSUM   sl sh

       lo hi     = BODY size (6..23 bytes) (word)
       ty        = variable type (see table at packet 06)
       le        = length of the variable name string (0..17 chars)
       c1 c2 ... = variable name string
       sl sh = checksum of BODY (word)

      This command packet asks the TI92 to send a variable or its complete
    directory. See section 4 and 5 for more details.

    This section describes the BODY of the 'variable data packet' (15) send
  in a TI92->PC transfer. The storage of information is of course dependent
  on the type of the variable.

    +0       2      0  0
    +2       4      variable size (TI Var-link size-2) = n+4
    +6       2      position of cursor (in characters)
    +8       n      characters (see remarks)
    +8+n     2      0 E0

    -A line always begins with a #32 (blank) character.
    -A line ends with a #13 (RC) character, except for the last line.

  ... (to be continued)

    The protocol is described by the following dialogue, where ss is sender,
  and rr is receiver (09 or 92). (step 1 and 2 are optionnal)
    The SEND protocol (PC->TI92) is handled by the I/O port interrupt routine
  of the TI92, which can only be triggered when it is in its HOME screen. The
  Var-Link uses this dialogue from step 3, but needs an operator to set the
  TI92 in receive mode.
    The RETRIEVE protocol (TI92->PC) will be identical, but this time the TI92
  will trigger it by sending a 'variable header packet' (06). (step 3)

    1- ss 68 00 00     is receiver ready ?
    2- rr 56 00 xx     xx=0  -> ready
                       xx<>0 -> busy, go step 1
    3- ss 06 lo hi     send variable header
       ?? ?? ?? ...
    4- rr 56 00 xx     xx=0  -> ready
                       xx<>0 -> busy, give up
    5- rr 09 00 00     waiting for data
    6- ss 56 00 00     sender ready, data coming up
    7- ss 15 lo hi     variable data
       ?? ?? ?? ...
    8- rr 56 00 xx     xx=0  -> all right
                       xx<>0 -> busy, give up
    9- ss 92 00 00     end of transfer
    10-rr 56 00 xx     xx=0  -> ended
                       xx<>0 -> busy, give up

    Hopefully the TI92 supports a 'request variable' function, that is really
  simple. This will only work if the TI92 is in its HOME screen, with no open
  dialogue box, or else you will get a 'busy state' from the TI92.
    To use the request, add step 2a and 2b after step 2 of the preceding
  dialogue with :

    2a- 09 A2 lo hi     computer requests a variable
        ?? ?? ?? ...    see section 2
    2b- 89 56 00 xx

    If the variable requested does not exist, the dialogue stop at step 2b,
  the calc sending a 'not ready state' (56 with info xx<>0).

    The TI92 directory request is a particular case of the request function.
  You have to request for a variable whose name string is a null string, and
  whose type is 19 (DIR).

    1- 09 A2 06 00         HEADER   PC requests TI92's directory
       00 00 00 00 19 00   BODY
       19 00               CHECKSUM
    2- 89 56 00 xx         xx=0  -> TI92 ready
                           xx<>0 -> TI92 busy, go step 1 or give up
    3- 89 06 lo hi         HEADER   variable header (folder description)
       ?? ?? ?? ...        BODY
       sl sh               CHECKSUM

    At step 3, the TI92 sends in a 'variable header packet' the description
  of a folder(???). Then follows this recurrent dialogue :

    1- 09 56 00 00         computer ready
    2- 09 09 FF FF         computer waiting
    3- 89 56 00 xx         xx=0  -> TI92 ready
                           xx<>0 -> TI92 busy, give up
    4- 89 15 lo hi         HEADER   variable/folder description
       00 00 00 00
       c1 .. c8            variable/folder name string (8 chars)
       ty                  variable type
       st                  variable state (0=normal, 1=edit)
       Ll Lh Hl Hh         variable size
                           (number of variables if variable type is folder/1F)
       sl sh               CHECKSUM
    5- 09 56 00 00         Computer ready
    6- 89 xx 00 00         Continue (xx=78) or end of transmission (xx=92)
  UNTIL xx<>78             xx should be 92 to terminate

  The TI92 will sequentially send :
    - a folder 'foldxxxx' (variable type 1F, size = number of variables held)
    - variables 'varxxxxx' belonging to 'foldxxxx', if it is not empty.
    - another folder, then its content...
  Note that the TI92 will send folder and variables in alphabetical order.

    The TI92 can be asked for a screen dump at any time, even when 'BUSY'
  is highlited on the screen. It will stop everything and send the dump
  thru the I/O port. This operation should take a few seconds (1 second
  mini). Here is the dialogue :

    1- 09 6D 00 00     PC requests screen dump
    2- 89 56 00 xx     xx=0  -> TI92 ready
                       xx<>0 -> TI92 busy, go step 1 or give up
    3- 89 15 lo hi     HEADER data packet
       ?? ?? ?? ...    BODY   240*128d bitmap (3840d bytes)
       sl sh           CHECKSUM
    4- 09 56 00 00     PC received (ready)

    lo hi = 3840d bytes (240*128d bits)

    Backups consist in a partial dump of TI92's memory. They can be about
  from 38 Kb to 100 Kb. The TI92 can receive or send a backup at any time.
  If a send (to TI) backup operation fails in its middle, the TI92 will
  reset and restart a new (clean) session. (FARGO installation is an

    Receiving the backup, the dialogue begins like a variable request :

    1- 09 A2 11 00       request
       00 00 00 00 1D 0B 6D 61 69 6E 5C 62 61 63 6B 75 70  "main\backup"
                                                           type 1D, size 0
       9F 04             checksum
    2- 89 56 00 xx       xx=0 (ready), busy else

      3- 89 06 09 00     variable header
         Bl Bh 00 00 1D 03 31 2E 33  block size = B bytes block
                                     ROM        = "1.3"
                                     type       = 1D
         B6 00           checksum
      4- 09 56 00 00     PC OK
      5- 09 09 Bl Bh     waiting for BhBl bytes
      6- 89 56 00 xx     xx=0 (ready), busy else
      7- 89 15 Dl Dh     data packet, DhDl=BhBl+4 bytes
         ?? ?? ?? ...
         Sl Sh           checksum
      8- 09 56 00 00     PC OK

    9-  89 92 00 00      TI92 end of transmission
    10- 09 56 00 00      PC OK

    Some explanation :

    You never know the total size of the backup until it is finished ! The
  best way to detect the end of the REPEAT ... END REPEAT is to check for
  the 89 92 00 00 (end of transmission) packet received at step 3 instead
  of the packet header.
    Data packets are 4 bytes longer than the announced size in the variable
  header packet. That's the way TI92 send variables. To store the backup in
  a file, just leave the 4 first bytes of each block, and concatenate them
  into one block.
    The TI92 usually send backups in 1024d bytes blocks, unless the last
  block is undetermined since the backup size is not likely to be a multiple
  of 1024d !

    And now, how to send a backup. If you stop the conversation too long
  (about 1.5 sec. considered as 'time up' by the TI92), the TI92 will auto-
  maticly reset (and that's handy). Here is the dialogue :

    1- 09 06 05 00       variable header
       Ll Lh Hl Hh 1D    backup size, type 1D
       Sl Sh             checksum
    2- 89 56 00 xx       xx=0 (ready), busy else

      3- 09 06 05 00     variable header
         00 00 00 00 1D  type 1D
         1D 00           checksum
      4- 89 56 00 xx     xx=0 (ready), busy else
      5- 89 09 00 00     waiting for block
      6- 09 56 00 00     PC OK
      7- 09 15 Bl Bh     BhBl = block size
         ?? ?? ?? ...    block data
         Sl Sh           checksum
      8- 89 56 00 xx     xx=0 (ready), busy else

    9 - 09 92 00 00      end of transmission

    Some explanation :

    The transfer should be done with 1024d blocks like a lot of ROMs do when
  a TI92 send a backup. These blocks can be taken rawly in a backup file.
  Have a look at FORMATS.DOC for more technical information.
    If the transfer succeed, the TI92 will reset (blue screen) and restart
  the session you backed up before. That's all...

    There are two ways to remotely control your TI92.

    You can put your TI92 in a special mode. From the Home screen, press
  F5 + Diamond + '(' + 'R' (one after each other). The TI92 will now
  immediatly convert a word received from the link port as a key stroke.
  The TI92 will send the FF byte after each word. (See TI92 manual for the
  key codes)
    Output is also redirected to the link port. Any result (Enter key pressed)
  is send in ASCII code with a terminal FF byte.
    To reset the TI92 back to normal mode, send the magic keyword thru the
  port : F5 + Diamond + '(' + 'R'.

    You can use the TI92 in its normal mode. Send a RC packet :
      09 87 ll hh    where hhll is the key code (see TI92 manual)
    The TI92 will answer for each code sent :
      89 56 00 xx    xx=0 (ready), busy else
    This kind of remote control totally simulates the strike of a key. Any
  result will be displayed on TI92's screen just as if a user was in front
  of it.

Contact : Vincent Caron <vincent _at_ zerodeux.net> Last modified on Sunday 26 Jun 2005 15:11