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)
HARDWARE
1 - Home made cable
2 - Hardware protocol
SOFTWARE
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
PLEASE NOTE :
- 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').
HARDWARE
1- HOME MADE CABLE
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
OOOOOOOOOOOOOOOOOOOO
OOOO OOO OOOOOOO
OOOOO OOO OOOOOOO 2.5 mm Jack
OOOO OOO OOOOOOO
OOOOOOOOOOOOOOOOOOOO
OOOOOOOO
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.
2- HARDWARE PROTOCOL
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.
SOFTWARE
1- TI PACKETS
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 :
HEADER
+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
size=0
info=0 or -1
15 = Variable data
size=info (LSB first)
56 = Busy state
size=0
info=0 (sender ready)
info=1 (sender busy)
68 = Check state
size=0
info=0
6D = Screen dump
size=0
info=0
78 = Continue
size=0
info=0
87 = Remote control
size=0
info=key code (LSB first) (see TI92 manual)
92 = End of transmission
size=0
info=0
A2 = Request (variable or directory)
size=info (LSB first)
2- PACKETS DESCRIPTION
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 :
'x'
'var1'
'main\example'
'dir_maxx\var_maxx'
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.
3- VARIABLE DATA DESCRIPTION
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.
TEXT
+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
Remarks:
-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)
4- RETRIEVE/SEND VARIABLE
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).
5- TI92 DIRECTORY
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 :
REPEAT
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.
6- SCREEN DUMP
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)
7- BACKUPS
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
exception).
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
REPEAT
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
END REPEAT
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
REPEAT
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
END REPEAT
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...
8- REMOTE CONTROL
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 |