So, I've been trying to figure out how to send/receive data through the I/O port, and I've sort of come up with a way. It's probably not original but it seems to work.

Basically, on the cable, you have the tip and the ring. Either can be high, low, or one or the other. This creates 4 different states that the cable can be in.
To send these states out the I/O port, we simply use "out" and send it through port 0.

Most people would write a state like this:

Code:
ld a, %00000010
out (0), a ; send a through port 0 (I/O port)


However, with my method I am using to send data, the state itself doesn't really matter, just the fact that there are 4 of them. So you could replace that for this for simplicity:

Code:
ld a, 2
out (0), a


The four different states are 00000001, 00000010, 00000011, and 00000000, but again, we can just refer to them as 0, 1, 2, and 3 for simplicity.

You can read what is being sent out through the I/O cable with "in":


Code:
in a, (0)
call AToString ; custom
bcall(_PutS)


When you send one of these values out the I/O cable, the inverse happens on the other side. What I mean by this is if you were to send a "00000010" the receiver would read a "00000001". I've noticed this from experimentation. I'm not very good with hardware so I am unsure the mechanics behind why, but just know that it is inverted.

In much simpler terms, the inversion is like so:


Code:
1   ->   2
2   ->   1
3   ->   0
0   ->   3


If a 1 is sent out the I/O port, the receiver will read a 2. If a 2 is sent, a 1. 3, 0. And 0, 3.

Now to transfer data, what I have done is taken advantage of the first three states and laid the last one aside as a "terminating" state. Basically, if the sender sends a 0 (default position), then it knows the message is done being sent.

The logic I've used to send data basically has the receiver go into a sort of "receiving" mode where it logs the current state and waits for a state change. Once there is a state change, it uses that to determine whether a 0 or 1 is being sent, or whether the message is over.

The logic in pseudo-code works like this:

Code:
Receiving Side:
if (0) -> (1)
then bit=0
if (0) -> (2)
then bit=1

if (1) -> (0)
then bit=0
if (1) -> (2)
then bit=1

if (2) -> (0)
then bit=0
if (2) -> (1)
then bit=1

if (anything) -> (3)
then finish

if (3) -> (1)
then bit=0
if (3) -> (2)
then bit=1
if (3) -> (0)
then finish


The first state before the arrow is the previous state.
The one after the arrow is the new one.

The default state is 3 and all transmissions start on 3.
If the sender sends a new state out the I/O port then that state change can be turned into a byte with the logic above.

For example, if the sender were to do something like this:

Code:
(psuedo-code)
out -> 2
out -> 1
out -> 3
out -> 1
out -> 3
out -> 1
out -> 3
out -> 2
out -> 0


Since these are all inverted, the receiver would receive 1,2,0,2,0,2,0,1,3.
Since the default state is 3, that means the receiver is going through states like this:

Code:
3->1->2->0->2->0->2->0->1->3


If we use the logic above in the various if statements, we can see that this would correspond to:

Code:
3->1 = 0
1->2 = 1
2->0 = 0
0->2 = 1
2->0 = 0
0->2 = 1
2->0 = 0
0->1 = 0
0->3 = End


If the receiver were to record all these state changes, he could put all these bits together into 1 byte and get 01010100, or, the letter T.

Anywho, that's how I managed to send a byte through the I/O port.

Here's my library so far:
http://pastebin.com/8YpUbSvx

Sorry if you think it's messy and not optimized. I'm not that far into Assembly.

Here is an example of using my library to send the letter "T" from my TI-84+CSE to my TI-84+:

Sending program:

Code:
#include "ti84pluscse.inc"
.org userMem-2
.db $EF, $69

start:

   call FindData
    ld (hl), '0' \ inc hl
    ld (hl), '1' \ inc hl
    ld (hl), '0' \ inc hl
    ld (hl), '1' \ inc hl
    ld (hl), '0' \ inc hl
    ld (hl), '1' \ inc hl
    ld (hl), '0' \ inc hl
    ld (hl), '0' \ inc hl
   call SendDataSafe
   ret
   
#include "transfer.h"



Code:
#include    "ti83plus.inc"
.org        userMem-2
.db         $BB,$6D

start:
   call ReceiveDataSafe
    call CompressData
    call FindDataCompressed
    ld a, (hl)
    bcall(_PutC)
    bcall(_NewLine)
 
#include    "transfer.h"


I'm not sure why, but I've noticed that sometimes bits are dropped in the library I'm working on. Like, if I were to send "1111" over, it may come over as "1101" or "1011". I'm unsure of why. But bits never seem to be gained, so I've created a slower but safer way of sending data were it sends it three times then compares them, so if you get something like "1101", "1001", and "0111" then it knows it's supposed to be "1111".

The call that sends and receives it three times have "Safe" after it. Such as, "ReceiveDataSafe" and "SendDataSafe" are much more accurate than "SendData" and "ReceiveData", but are also much slower.

The data gets sent over as a string of ones and zeros. But I'm working on a compression routine that will compress that all into bytes. Currently, the "CompressData" routine just compresses the first byte in the string to a byte.

I'm also working on a routine that will decompress the data. That way, you can send bytes over.
For the Z80 calculators, I would recommend the Bell library, which you can find here Smile I'm using it for the next version of AB5 for linkplay, and it works smoothly and is easy to operate.
Okay, so for some reason, my code has gotten extremely buggy and since it's gotten really long (~700 lines) it's become a bit too tedious to fix it. I just can't find the errors.

I think I'm going to stop on this project, but I'm pretty sure my concept still stands. I made a video showing that I managed to send two text strings from one calculator to the other and I also have a short slide-show showing the logic behind it.

If you want to see that for a reference, here it is:


I'll probably use the Bell library if I ever actually need to transfer data. I don't really have any projects in mind that require data transfer. I sort of just wanted to learn this for the fun of it and to see if I could do it.
I would personally like to give a vote for the CALCnet library, while we're offering alternatives. Wink I don't have a form of it explicitly available for the TI-84+CSE yet, but the code should be well-nigh identical except for different safeRAM. Very nice job on the link protocol concept, and it seems sound to me. I'm sorry to hear that it didn't quite work out.
  
Register to Join the Conversation
Have your own thoughts to add to this or any other topic? Want to ask a question, offer a suggestion, share your own programs and projects, upload a file to the file archives, get help with calculator and computer programming, or simply chat with like-minded coders and tech and calculator enthusiasts via the site-wide AJAX SAX widget? Registration for a free Cemetech account only takes a minute.

» Go to Registration page
Page 1 of 1
» All times are UTC - 5 Hours
 
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum

 

Advertisement