Re: TI-H: Talk 85


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

Re: TI-H: Talk 85



DAMN!  Who the hell invented this theory?  THERE IS NO CLOCK SIGNAL 
BETWEEN THE CALCS!!!!   GET IT STRAIGHT, FOR THE LOVE OF GOD!!


>The Black is ground. White is the transfer wire, and
>the red is the clock wire. From this you can tell that
>the ti-85 runs on a single directional parallel basis.
>(this is all based upon my observations).


Here we go...  (thanx site!)
--------
This txt file covers the port 7 of the TI-85, that is the port that 
is 
connected to the link.  With the information presented here, you 
should
know enough to be able to write a two player game, a file transfer 
program,
or even connect two calculators together for any purpose.


Circuit-
The jack that connects the two calculators has three connections.  
The big 
one is GND.  Then other two are W and R.  They are both at 5V when 
not 
activated and pulled to ground when they are.  


Example-
I wrote this program to help illustrate how the link works.  For now, 
just
type it in, it will all be clear later. (hopefully)


#include "TI-85.H"


;Program Title
.org 0
.db "Port 7",0


Init:
     CALL_ROM(CLEARLCD)
KeyLoop:
     call GET_KEY
     cp   $37
     jr   z, Exit
     cp   $02                 ; <-?
     jr   z, SendW
     cp   $03                 ; ->?
     jr   z, SendR
     cp   $01                 ; \/ ?
     jr   z, SendWR           
     cp   $04                 ; /\ ?
     jp   z, SendN
    


     ld   hl, $FC10
     in   a, ($07)
     ld   (hl), a
     ld   hl, $FC20
     ld   B, 11111111b
     ld   (hl), B


     jr   KeyLoop


SendN:
     ld   a, $C0
     out  ($07), a
     jr   KeyLoop


SendR:
     ld   a, $D4
     out  ($07), a
     jr   KeyLoop


SendW:
     ld   a, $E8
     out  ($07), a
     jr   KeyLoop


SendWR:
     ld   a, $FC
     out  ($07), a
     jr   KeyLoop


Exit:
     ld   a, $C0
     out  ($07), a
     ret
.end




This will display a guide line at the top left of the LCD and over 
that it will show the status of port 7.  The Left, Right, Down, and 
Up 
keys will control the output of turning W, R, both W and R, and 
neither
When you turn them active, you can see bits 2 and 3 turn on as they
are puuled to ground (0V).  Bits 1 and 0 show the input, notice if 
it
is not connected to anything that it will show both, meaning that 
they are
at 5V or not active.  When you turn on W or R, that pixel should shut 
off
as it is pulled to ground, becomes 0V and is active. (0V=active, 
5V=not 
active).  Fool around with this, try hooking it up to someone elses
TI-85 and have them send or recieve stuff as you run port7.asm.  
Learn 
from it.


Sending Junk-
Now that you know how it works (you do, right?)  Here is how to make 
it
do what you want.  Use the command 
out ($07), a
to send what's in the accumulator to the port 7.  Here is what you 
should
send:
11000000 ($C0) = Neither pulled to ground
11101000 ($E8) = W pulled to ground
11010100 ($D4) = R pulled to ground
11111100 ($FC) = W &amp; R pulled to ground
So you jsut put the value in the accumulator and then out it to port 
7!


Recieving Junk-
To recieve is also simple, just read the bottom two bytes (remember 
the
program at the begining)  Basicly if the bit is on then it is at 5V
and thus not active or off.  so you first 
in a, ($07) 
in order to put what's in port 7 into the accumulator. then you
and $03 
to mask off bits 0 and 1, the input bits.  then all you do is compare 
it 
to what you want.  
00000011 = Neither is pulled to ground
00000010 = R is pulled to ground
00000001 = W is pulled to ground
00000000 = R &amp; W are pulled to ground
NOTE: you cannot tell wheither YOUR TI-85 or the TI-85 on the other 
end 
of the link cable are pulling it to ground.  You might try also 
putting
the rest into account, however.  


Protocols-
The protocol that the TI-85 uses to send bytes is as follows:
The sending 85 pulls one wire for bit 0:
     W=1   R=0
The recieving 85 pulls the other wire in confirmation
Both 85s clear the link
Loop again for next bit


Sending Code-
After reading about all of this I was still confused, so I 
dissasembled 
the resieve and send byte routines of the TI-85's ROM.  I discovered
their address from another GREAT txt file on port 7 (Don't ask me 
how
he figured them out) anyway, they are at page 5, 643Bh and 6559h
I will now go over and explain them (which is basicly the whole point 


of this text file, the previous stuff was review) 


;Send Byte   A=The sending byte
.org 0
     ld c, a        ; This just puts the byte to send in C
     ld b, $0008    ; There are 8 bits to send (Seriel remember)
SendBit:     
     ld de, $FFFF   ; This is for the timing loop
     rr c           ; This rotates the register c right and puts the 
right
                      bit in the carry flag.  So each loop has it's 
bit
                      put in the carry flag.  Pretty neat.
     jr nc, SendR   ; If there is no carry (i.e. the current bit is 
0)
                      then send a R
     ld a, $E8      ; Else send a W because we have a 1
     jp SendIt      ; Then actually Send it!!
SendR:
     ld a, $D4      ; We have a 0, so send a R (D4h)
SendIt:
     out ($07), a   ; This actually sends it!
WaitConfirmation:
     in a, ($07)    ; Read the port
     and $03        ; Mask off bits 1 and 0 (see above text)
     jp z, Continue ; If it is zero (both R and W pulled to ground,
                      then continue
     in a, ($07)    ; If not, then read the port and try again
     and $03
     jp z, Continue 
     dec de         ; Both wern't active that means the calc on the
                      other side hasn't received it (The other TI 
should
                      pull the other one to ground to show that it 
has
                      recieved the bit) so loop through and try again.


                      It uses de as a counter (it was set in the 
beg)
     ld a, d
     or e           ; This basiclly does or e,d and will make z 0 if 
both
                      d and e are zero, or de is zero. (i.e. counter 
is
                      0 and we are done with loop, or a time-out)
     jp nz, WaitConfirmation 
Error:
     jp ErrorHandler; Branislav suggested this was an error handler,
                      I don't know, but whatever the case don't 
include it
                      in your implementations.  Instead, put in a jr 
to your
                      own error handlers.
     ld a, $0C      ; Get ready to clear R &amp; W (C0h = both off, see 
above)
     out ($07), a   ; Actually clear them
     ld de, $FFFF   ; Get de counter ready for next loop to make sure 


                      link is cleared.  when de reaches 0 it times 
out.
ClearLoop:     
     dec de
     ld a, d
     or e           ; Again this is or e,d and will continue if de is 
not 0
     jr z, Error    ; We timed out, so go to error handler (see 
above)
     in a, ($07)    ; Read the port 7 again
     and $03        ; Performs a Self-Destruct
     cp $03         ; makes sure link is cleared, or both are not 
active
                      or both are at 5V
     jp nz, ClearLoop ; If not, then clear and wait again.   
     djnz SendBit   ; Basiclky a 'dec b' &amp; 'jr nz, SendBit'  It will 
loop
                      again to send the next bit
     ret            ; Goes back to your program


You should use a method similar to this when making your programs.  
Make
sure to always shut off both W and R when you are done using them, 
put 
them at 5V, send C0h to port 7.  Isn't it amazing all the work that 
calculator does while all you see is that little worm move in the 
upper
right corner of your LCD. :)


Recieve Byte Code-
;Recieve Byte A=recieved byte
     .org 0
     ld b, $08      ; There are 8 bits to recieve
     ld de, $FFFF   ; Setup timeout counter to wait for bit
                      if this de reaches 0 it is a time-out and it 
goes
                      to an error handler
     jr WaitLoopEnd ; This jumps to the end of the loop, I have NO 
idea
                      why this "jr" is here???
WaitLoop:
     in a, ($07)    ; Read port 7
     and $03        ; Mask the last two bits
     jr z, Error    ; Cause an error if BOTH are active
     cp $03         ; Compare it to 11 (Both NOT active)
     jp nz, Continue; If at least one is active, continue.  
                      Notice if both were active it would have caused 
an
                      error, so this is really only one being active
     in a, ($07)    ; Read port 7 again
     and $03        ; Mask the last two bits
     jr z, Error    ; I think this will cause an error if they are 
BOTH
                      active
     cp $03
     jp nz, Continue; Same as last time, continue if at lesat 1 is 
active
     dec de         ; Decrease counter
     ld a, d
     or e           ; or d, e
     jp nz, WaitLoop; If counter (de) is not 0 then loop again.
     jp TimeOut     ; Cause an error if we timed out waiting for a 
bit
Continue:
     sub $02        ; This is where is gets interesting.  It will 
subtract
                      10b from the accumulator (or the last two bits 
of
                      what it received)  Remember a W=1 R=0. 
                      So:    W        R
                            01       10
                           -10 (02) -10
                           ----     ----
                            01 C     00  
                      The C means the carry flag was set because the 
result 
                      was less then 0, (-1h)  So now the Carry flag 
is set
                      if we recieved a W and clear if we recieved a R.
  NICE
     jp nc, Got0    ; Go to the part for receiving a 0 if we had no 
carry
                      flag set (we got an R)
----------------------------------------------------------------------
-----
Got1:
     ld a, $D4      ; Get ready to send a R ($D4 = Send a R, see 
above text)
     out ($07), a   ; Send the W in confirmation that we recieved the 
bit.
                      now, both wires should be pulled
     rr c           ; This is neat.  We recieved a W or a 1, because 
of that
                      our carry flag was set. so now we are rotating 
that 
                      carry flag into the register c.  So each loop 
will
                      rotate the recieved bit into c until we have 
the 
                      complete byte.
     ld de, $FFFF   ; Get counter ready
LoopR:
     in a, ($07)    ; Read the link
     and $03        ; Tell the calc to emmit radio interference
     cp $02         ; Is the R (and ONLY the R) active?
                      The reason it does this is becasue when the 
sending
                      85 receives the confirmation signal it will 
clear it's
                      port, thus the W it sent will not be active 
when 
                      the port it clear.  The R will be, however, 
because
                      WE are the ones pulling it.  
     jp z, ClearLink
     dec de         ; lower time-out counter
     ld a, d
     or e           ; or e, d
     jp nz, LoopR   ; Loop until sending 85 has cleared it's side of 
the 
                      link.
     jr Error       ; We timed out, so cause an error.
----------------------------------------------------------------------
----
ClearLink:
     ld a, $C0      ; get ready to clear our side of the link
     out ($07), a   ; Just Do It!
     ld d, $04      ; Get counter ready.  The reason it is so low is 
that
                      this time we aren't waiting for the other 85 to 
do
                      anything.  We are just clearing our side, so it 
SHOULD
                      clear AS SOON as we do it.  Thus the 3 loops.
ClearLoop:     
     dec d          ; Lower counter
     jr z, NextBit  ; If we time-out it says, "oh well" and continues 
with 
                      the next loop.  We can do this because if there 
is an
                      error, it will catch it on the next bit.  Note: 
there
                      is no need for the or d, e shtuph because we 
are
                      only dealing with the d, not de.
     in a, ($07)    ; See a pattern?
     and $03        
     cp $03         ; Is it clear?
     jp nz, ClearLoop ; If it's not clear, try again
NextBit:
     djnz WaitLoop  ; Go back and do it ALL over again if B is not 0
                      i.e. we have more bits to recieve
     ld a, c        ; We don't have any more bits to recieve, so put 
the
                      received byte in a.
     ret            ; and return ($C9)


----------------------------------------------------------------------
------
Got0:
     ld a, $E8      ; This is where we were sent if we got a R (0)
                      Put E8h into a to send a confirming W
     out ($07), a   ; Confirm
     rr c           ; rotate the 0 (of the carry flag) into the 
register c
     ld de, $FFFF   ; Get counter ready for loop
LoopW:
     in a, ($07)    ; perform a memory checksum :)
     and $03        ; Mask off last two bits.
     cp $01         ; Is ONLY the W active.  (See above for indepth 
analysis)
     jp z, ClearLink; Go clear link and finish 
     dec de         ; Decrease counter
     ld a, d
     or e           ; or e, d
     jp nz, LoopW   ; Keep Looping!
Error:
     jr ErrorHandler ; This is where we are sent if there is an error 


                      (except for one time at the beg) It goes off
                      somewhere in lala land.


OK!  You should now thoughrouly understand the port 7 and how to use 
it.
Remember, don't limit yourself to this, get creative.  And also 
remember I
didn't write this code, it is the ROM function call that is built 
into 
the TI-85.  I would like to thank Dan Eble (TI-85 GOD!), Branislav 
Bozgai, and of course Texas Instruments.  If you have any comments or 


questions you can reach me at:
site@xnet.co
--------




____
~Keith
FFNP69C@PRODIGY.COM


"There's a fine line between fishing and just standing on the shore 
like an idiot."
  --Steven Wright


Follow-Ups: References: