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)
"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
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 (email@example.com) and George NACHMAN (firstname.lastname@example.org). You can find other informations from David ELLSWORTH (email@example.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').
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.
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)
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.