;TI-83+ to PIC Library ;Thomas Henry ;This revision: 5/3/2013 ;Be sure to peruse the "TI Link Protocol Guide" to make sense ;of the various RTS, ACK, DATA, EOT, etc. commands and to ;see the almost countless other operations that are possible. ;----- Global Variables ;The following two should be declared in the main program and ;only used throughout for their intended purposes. ;dim value as string ;floating point number ;dim name as byte ;name of variable (A-Z) ;----- Local Variables ;These are only used in the library routines here. dim paramB, dummyB, idxJ, idxK, tempB, places as byte dim paramW, chkW as word dim numTI(9) ;packed value in TI format ;----- Local Constants #define ASCII0 0x30 ;ASCII code for zero ;----- Subroutines sub getByte(out paramB) ;get a single byte paramB = 0 ;byte built up here repeat 8 ;eight bits to a byte paramB = paramB / 2 ;make room for next bit do ;both lines idle high if Data0 off then ;it's a zero dir Data1 out set Data1 off ;acknowledge on Data1 do while (Data0 off) ;wait for Data0 to go high loop dir Data1 in ;idle Data1 again goto bitDone ;factor in a zero end if if Data1 off then ;it's a one dir Data0 out set Data0 off ;acknowledge on Data0 do while (Data1 off) ;wait for Data1 to go high loop dir Data0 in ;idle Data0 again set paramB.7 on ;factor in a one goto bitDone end if loop ;else we're still idling bitDone: ;ready for next bit end repeat end sub ;----- sub sendByte(in paramB) ;send a single byte repeat 8 ;eight bits in byte if (paramB.0 off) then ;fetch next bit dir Data0 out ;alert calculator set Data0 off do while (Data1 on) ;wait for acknowledgment loop set Data0 on ;acknowledge acknowledgment do while (Data1 off) ;wait for all clear loop else dir Data1 out ;alert calculator set Data1 off do while (Data0 on) ;wait for acknowledgment loop set Data1 on ;acknowledge acknowledgment do while (Data0 off) ;wait for all clear loop end if paramB = paramB / 2 ;get set for next bit dir Data0 in ;idle the lines again dir Data1 in end repeat end sub ;----- sub sendCmd(paramW) ;send a 16-bit key command sendByte(0x23) ;machine ID sendByte(0x87) ;CMD sendByte(paramW) ;command-LSB sendByte(paramW_H) ;command-MSB repeat 8 ;dump ACK from TI getByte(dummyB) end repeat end sub ;----- sub sendNum ;output: value = fixed point number in string form ;output: name = real number variable name (A-Z) numTI = 0,0,0,0,0,0,0,0,0 ;default the output to zeros idxJ = 1 ;index into value string idxK = 3 ;index into packed number if value(idxJ)="-" then ;check for minus sign numTI(1)= 0x80 ;80=negative, 0=non-negative idxJ++ ;go to next character end if if value(idxJ)=ASCII0 then ;ignore any leading zero idxJ++ ;go to next character end if numTI(2) = 0x7F ;assume a negative exponent if value(idxJ)="." then ;value is less than one idxJ++ ;go to next character do while value(idxJ)=ASCII0 ;count zeros to the right numTI(2)-- ;decrease exponent idxJ++ ;go to next character loop else ;it's one or greater do while (value(idxJ)<>".") ;scan until decimal point numTI(2)++ ;increase exponent idxJ++ ;check next character if idxJ>len(value) then goto sendNum1 ;off end of string loop end if sendNum1: ;now scan for mantissa idxJ = 1 ;go to start of string again do while value(idxJ) < "1" ;pass leading "-", "." or ASCII0 idxJ++ ;go to next character loop do while idxJ <= len(value) ;scan the rest now if value(idxJ) >= ASCII0 then ;its a digit tempB = value(idxJ) - ASCII0 ;get BCD of high digit numTI(idxK) = 16 * tempB ;store the high nibble idxJ++ ;point to next character if idxJ > len(value) then ;ran off end of string tempB = 0x00 ;so right pad with a zero else if value(idxJ) = "." then ;skip over decimal point idxJ++ ;go to next character end if tempB = value(idxJ) - ASCII0 ;else get BCD of low digit end if numTI(idxK) = numTI(idxK)|tempB ;factor in low nibble idxK++ ;point to next slot end if idxJ++ ;go to next character loop sendByte(0x23) ;machine ID sendByte(0xC9) ;RTS sendByte(0x0D) ;length of command-LSB sendByte(0x00) ;length of command-MSB sendByte(0x09) ;size of data-LSB sendByte(0x00) ;size of data-MSB sendByte(0x00) ;ID for real number sendByte(name) ;ASCII of variable name (A-Z) repeat 9 ;padding and dud bytes sendByte(0x00) end repeat chkW = [word] name + 9 ;create checksum sendByte(chkW) ;send LSB sendByte(chkW_H) ;send MSB repeat 8 ;dump response from TI getByte(dummyB) end repeat sendByte(0x23) ;machine ID sendByte(0x56) ;ACK sendByte(0x00) ;size of data-LSB sendByte(0x00) ;size of data-MSB sendByte(0x23) ;machine ID sendByte(0x15) ;DATA sendByte(0x09) ;size of data-LSB sendByte(0x00) ;size of data-MSB chkW = 0 ;send the value and for idxJ = 1 to 9 ;create checksum simultaneously sendByte(numTI(idxJ)) chkW = chkW + numTI(idxJ) next sendByte(chkW) ;send checksum in parts sendByte(chkW_H) repeat 4 ;dump response from TI getByte(dummyB) end repeat sendByte(0x23) ;machine ID sendByte(0x92) ;EOT sendByte(0x00) ;size of data-LSB sendByte(0x00) ;size of data-MSB end sub ;----- sub getNum ;input: value = fixed point number in string form ;input: name = real number variable name (A-Z) sendByte(0x23) ;machine ID sendByte(0xA2) ;REQ sendByte(0x0D) ;length of command-LSB sendByte(0x00) ;length of command-MSB sendByte(0x09) ;size of data-LSB sendByte(0x00) ;size of data-MSB sendByte(0x00) ;ID for real number sendByte(name) ;ASCII of name name (A-Z) repeat 9 ;padding and dud bytes sendByte(0x00) end repeat chkW = [word] name + 9 ;create checksum sendByte(chkW) ;send LSB sendByte(chkW_H) ;send MSB repeat 23 ;dump response from TI getByte(dummyB) end repeat sendByte(0x23) ;machine ID sendByte(0x56) ;ACK sendByte(0x00) ;size of data-LSB sendByte(0x00) ;size of data-MSB sendByte(0x23) ;machine ID sendByte(0x09) ;CTS sendByte(0x00) ;size of data-LSB sendByte(0x00) ;size of data-MSB repeat 8 ;dump ACK from TI getByte(dummyB) end repeat for idxK = 1 to 9 ;get the value from TI getByte(numTI(idxK)) ;store the packed TI number next idxK repeat 2 ;dump checksum from TI getByte(dummyB) end repeat sendByte(0x23) ;machine ID sendByte(0x56) ;ACK sendByte(0x00) ;size of data-LSB sendByte(0x00) ;size of data-MSB idxJ = 1 ;index into value string if numTI(1) = 0x80 then ;it's a negative number value(idxJ) = "-" idxJ++ ;get set for next end if if numTI(2) < 0x80 then ;it's a negative exponent value(idxJ) = ASCII0 ;install leading zero idxJ++ ;get set for next value(idxJ) = "." ;install decimal point idxJ++ ;get set for next places = 0x7F - numTI(2) ;number of places to count repeat places ;plop in the zeros value(idxJ) = ASCII0 idxJ++ ;get set for the next end repeat for idxK = 3 to 9 ;follow with significant digits tempB = numTI(idxK) / 16 ;get first digit of pair value(idxJ) = tempB + ASCII0 ;make into ASCII and store idxJ++ ;get set for the next tempB = numTI(idxK) & 0x0F ;second digit of pair value(idxJ) = tempB + ASCII0 ;make into ASCII and store idxJ++ ;get set for the next next idxK else ;it's a positive exponent places = numTI(2) - 0x7F ;places to the decimal point for idxK = 3 to 9 ;follow with significant digits tempB = numTI(idxK) / 16 ;first digit of pair value(idxJ) = tempB + ASCII0 ;make into ASCII and store idxJ++ ;get set for the next places-- if places = 0 then ;time for a decimal point? value(idxJ) = "." idxJ++ ;get set for the next end if tempB = numTI(idxK) & 0x0F ;second digit of pair value(idxJ) = tempB + ASCII0 ;make into ASCII and store idxJ++ ;get set for the next places-- if places = 0 then ;time for a decimal point? value(idxJ) = "." idxJ++ ;get set for the next end if next idxK ;scan next BCD end if idxJ-- ;set length of string, then value(0) = idxJ ;work backwards and do while (value(idxJ)=ASCII0) ;trim trailing zeros value(0)-- ;by altering length of string idxJ-- if idxJ=1 then goto getNum1 ;leave a single zero though loop getNum1: end sub