Re: LZ: Link Programming Help
[Prev][Next][Index][Thread]
Re: LZ: Link Programming Help
houston 00 wrote:
> Second, can somebody send me some examples of link programs (the source,
> please!)
K, read this attatchment. :)
Cheers and Good Luck,
--
~Keith
TSK3000@Prodigy.Net
----
VISIT THE OFFICIAL CSHELL HOMEPAGE AT:
http://pages.prodigy.net/tsk3000/CShell/
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 & 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 & 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 & 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' & '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.com
References: