Hello All!

I just started programming my first asm project and I was wondering how to best test i/o port byte transfers. I have been trying Wabbitemu (v1.5.6.20). So far everything has been freezing up when I try to run code with the 'connect to' option activated on both calculators. Any suggestions?

P.S. I am not using CalcNet... is that blasphemous?
Welcome to Cemetech, Snipes! I hope that you'll Introduce Yourself as soon as you get a chance. WabbitEmu has quite poor link port emulation as of the last time I tried it; I use PindurTI for CALCnet testing. It has truer link and interrupt emulation, although a bit of a harder-to-use interface. It's not explicitly blasphemous that you're not using CALCnet, especially since it's your first ASM project, but if you start doing anything moderately complex, I do strongly suggest you use it.
Thank you very much! Also, the protocol I came up with happened to be very close to Tachyon Link (I figured this out after I read through your CALCnet whitepaper) and I only need to connect the calculator and an arduino, so it should work for now. I do like CALCnet though.
You're welcome to use CALCnet and the CALCnet Arduino routines too, if you'd like, but good luck with your protocol. You should document it so we can look through it for possible flaws or suggestions, if you'd like.
Now that Christmas is over, I have had a chance to look at this project again. I have everything working except the aforementioned linking protocol. I wanted to get things working between calculators first, but my routine is not quite working. I have tried several things and it still freezes up on the receiving end (the sender does not check if the bit was received). I think the sender is going too quickly or I am not correctly checking the LSB on the receiving end. Anyway, the code is as follows:


Code:
.nolist
    #include    "ti83plus.inc"
.list

.org    $9D93
.db    t2ByteTok, tAsmCmp

Main:
   IN   A, (0)         ;read link port status
   RRA
   CALL   NC, getData

   b_call(_GetCSC)
   CP   skEnter
   CALL   Z, sendData
   
   CP   skClear
   JR   NZ, Main


   RET            ;Exit the program



sendData:
   DI
   LD   A, 1         ;Pull clock line low to signal transfer
   OUT   (0), A

sendSynchWait:
   IN   A, (0)         ;Check for data line to go low
   RRA
   RRA
   JR   C, sendSynchWait
   
   XOR   A         ;Reset the data and clock lines
   OUT   (0), A

resetWait:
   IN   A, (0)
   CP   3
   JR   Z, resetWait

   LD   HL, Data      ;Get byte from memory
   LD   A, (HL)
   LD   C, A
   LD   B, 4         ;8 bits, 2 bits/loop, 4 loops

sendHigh:
   XOR   A         ;set A to 0
   RR   C         ;put LSB of C in carry
   CCF            ;invert carry
   RLA            ;put carry in LSB of A
   SCF            ;set carry
   RLA            ;shift left, add 1
   OUT   (0), A         ;send out the bit
   CALL   pause
sendLow:
   XOR   A         ;set A to 0
   RR   C         ;put LSB of C in carry
   CCF            ;invert carry
   RLA            ;put carry in LSB of A
   SLA   A         ;shift left, add 0
   OUT   (0), A         ;send out the bit
   CALL   pause
   DJNZ   sendHigh

   EI
   RET


getData:
   DI
   LD   A, 2         ;pull data line low
   OUT   (0), A
   
recSynchWait:
   IN   A, (0)         ;check for line reset
   CP   3
   JR   NZ, recSynchWait

   XOR   A         ;reset both lines
   OUT   (0), A         
   LD   C, A         ;clear C
   LD   B, 4         ;8 bits, 2 bits/loop, 4 loops

receiveHigh:
   IN   A, (0)         ;check if clock was pulled low
   RRA
   JR   C, receiveHigh
   
   RRA            ;get bit
   RL   C

receiveLow:
   IN   A, (0)         ;check if clock was pulled high
   RRA
   JR   NC, receiveLow

   RRA            ;get bit
   RL   C

   DJNZ   receiveHigh

   LD   A, C         ;display transfer
   LD   H, 0
   LD   L, A
   b_call(_DispHL)

   EI
   RET

pause:
   PUSH   BC
   LD   B, $FF
pLoop:
   CALL   $000B
   DJNZ   pLoop
   
   POP   BC
   RET


Data:
   .DB   8


.end
.end
I'm very uncomfortable with the way that you're not ding any sort of timing synchronization at all there. What if you start reading in the middle of a frame? How do you know you'll have any sync?
Quote:
I'm very uncomfortable with the way that you're not ding any sort of timing synchronization at all there. What if you start reading in the middle of a frame? How do you know you'll have any sync?


I went back and tried to fix the synchronization. I am not sure if this is what you meant.

Send:

Code:
sendData:
   DI
   LD   B, 3         ;number of retries

IOStatus:
   PUSH   BC         ;save counter
   CALL   checkIO         ;see if IO is busy or not
   POP   BC
   OR   0         ;checkIO returns 0 if busy
   JR   NZ, sendSynch      ;not busy, begin synch
   DJNZ   IOStatus      ;retry

   ;error message

   EI
   RET            ;go back to main
   
sendSynch:
   LD   A, 1
   OUT   (0), A         ;pull clock line low

sendSynchWait:
   IN   A, (0)         ;check for data line to be pulled low
   RRA
   RRA
   JR   C, sendSynchWait
   
   XOR   A
   OUT   (0), A         ;release the clock line

sendSynchWait2:
   IN   A, (0)         ;check for data line to be released
   RRA
   RRA
   JR   NC, sendSynchWait2


Receive:

Code:
Main:
   IN   A, (0)         ;read link port status
   CP   2
   CALL   Z, getData

        ...

getData:
   DI
   LD   A, 2
   OUT   (0), A         ;pull data line low

waitSynch:
   IN   A, (0)         ;check for clock line to be released
   RRA
   JR   NC, waitSynch
   
   XOR   A
   OUT   (0), A         ;release data line


I also added a check on the sending side to see if the IO port was busy or not. I was hoping you could give me some more specific suggestions. The full code is below.


Code:
.nolist
    #include    "ti83plus.inc"
.list

.org    $9D93
.db    t2ByteTok, tAsmCmp

Main:
   IN   A, (0)         ;read link port status
   CP   2
   CALL   Z, getData

   b_call(_GetCSC)         ;get keypress
   CP   skEnter
   CALL   Z, sendData      ;send data if enter was pressed
   
   CP   skClear         ;check if clear was pressed
   JR   NZ, Main


   RET            ;Exit the program

;--------------------------------------------------------------------------------
;             Send Routines
;--------------------------------------------------------------------------------

;----------------------------------sendData--------------------------------------

sendData:
   DI
   LD   B, 3         ;number of retries

IOStatus:
   PUSH   BC         ;save counter
   CALL   checkIO         ;see if IO is busy or not
   POP   BC
   OR   0         ;checkIO returns 0 if busy
   JR   NZ, sendSynch      ;not busy, begin synch
   DJNZ   IOStatus      ;retry

   ;error message

   EI
   RET            ;go back to main
   
sendSynch:
   LD   A, 1
   OUT   (0), A         ;pull clock line low

sendSynchWait:
   IN   A, (0)         ;check for data line to be pulled low
   RRA
   RRA
   JR   C, sendSynchWait
   
   XOR   A
   OUT   (0), A         ;release the clock line

sendSynchWait2:
   IN   A, (0)         ;check for data line to be released
   RRA
   RRA
   JR   NC, sendSynchWait2

   LD   HL, Length      ;location of byte
   LD   B, 1         ;number of bytes to send
   CALL   sendByte

   LD   B, 2         ;number of times to resend

sendPayload:
   PUSH   BC         ;save resend value
   LD   A, (Length)      ;number of bytes to send
   LD   B, A
   LD   HL, Data      ;location of data
   CALL   sendByte

getACKNAK:
   IN   A, (0)
   CP   3
   JR   NZ, getACKNAK

   OR   0
   POP   BC         ;restore resend counter
   JR   Z, sendSuccess

   ;error message for resend

   DJNZ   sendPayload

   ;error message for failed transmission

sendSuccess:
   EI
   RET
   
;-----------------------------------sendByte-------------------------------------

sendByte:
   PUSH   BC         ;save
   LD   B, 4         ;8 bits, 2 bits/loop, 4 loops
   LD   C, (HL)         ;get byte from memory
   CALL   delay
   
transmitdata:
   XOR   A         ;clear A
   RRC   C         ;put LSB of C in carry
   CCF            ;invert the carry
   RLA            ;put carry in LSB of A
   SLA   A
   INC   A         ;A is %0000 00X1 (X is data bit)
   OUT   (0), A
   CALL   delay
   
   XOR   A
   RRC   C
   CCF
   RLA
   SLA   A         ;A is %0000 00X0
   OUT   (0), A
   CALL   delay
   DJNZ   transmitData

   POP   BC         ;restore number of bytes to send
   INC   HL         ;go to next byte location
   DJNZ   sendByte

   DEC   HL         ;HL points to location of last byte
   XOR   A
   OUT   (0), A         ;release data line
   RET

;----------------------------------checkIO---------------------------------------

checkIO:
   LD   DE, $FFFF      ;set a long counter

checkIOLoop:
   IN   A, (0)         ;read in IO port
   LD   C, A         ;save in C
   RRA            ;check LSB of A
   JR   NC, checkNoise

noise:
   DEC   DE
   LD   A, D         ;"convert" to 8 bits
   OR   E
   JR   NZ, checkIOLoop      ;check if counter reached zero

   LD   A, 1         ;IO port is clear
   RET

checkNoise:
   LD   B, 15         ;counter for noise loop

checkNoiseLoop:
   IN   A, (0)         ;read in IO port
   CP   C         ;check with saved IO read
   JR   NZ, noise      ;noise will set NZ
   DEC   DE
   DJNZ   checkNoiseLoop      ;not noise, repeat

   XOR   A         ;IO line is busy
   RET

;--------------------------------------------------------------------------------
;            Receive Routines
;--------------------------------------------------------------------------------

;-----------------------------------getData--------------------------------------

getData:
   DI
   LD   A, 2
   OUT   (0), A         ;pull data line low

waitSynch:
   IN   A, (0)         ;check for clock line to be released
   RRA
   JR   NC, waitSynch
   
   XOR   A
   OUT   (0), A         ;release data line
   
   LD   HL, LengthSave
   LD   B, 1         ;number of bytes to receive
   CALL   getByte
   LD   (HL), C         ;save length

   LD   B, 2         ;number of times to rereceive

receivePayload:
   PUSH   BC         ;save retry counter
   LD   A, (LengthSave)
   LD   B, A         ;length of data to receive
   LD   HL, DataSave
   CALL   getByte

   LD   A, (CheckSum)
   POP   BC
   OR   0
   JR   Z, receiveSuccess

   LD   A, 1
   OUT   (0), A         ;send checksum fail
   CALL   delay
   XOR   A
   OUT   (0), A         ;release lines

   DJNZ   receivePayload

receiveSuccess:
   LD   A, 3
   OUT   (0), A         ;send checksum success
   CALL   delay
   XOR   A
   OUT   (0), A         ;release lines

   EI
   RET

;----------------------------------getByte---------------------------------------

getByte:
   PUSH   BC
   XOR   A
   LD   C, A         ;C contains byte to recieve
   LD   B, 4

receiveClockLow:
   IN   A, (0)
   RRA            ;check if clock line is low
   JR   C, receiveClockLow

   RRA            ;put data bit in carry
   RR   C         ;put carry in MSB of C

receiveClockHigh:
   IN   A, (0)
   RRA
   JR   NC, receiveClockHigh

   RRA            ;put data bit in carry
   RR   C         ;put carry in MSB of C

   DJNZ   receiveClockLow

   LD   (HL), C         ;save data

   LD   A, (CheckSum)
   ADD   A, C         ;add new byte to check sum
   LD   (checkSum), A

   POP   BC         ;restore data length counter
   INC   HL         ;HL points to next data save location
   DJNZ   getByte

   DEC   HL         ;HL points to last data save location
   RET
   

;--------------------------------------------------------------------------------
;             Common Routines
;--------------------------------------------------------------------------------

delay:
   CALL   $000B
   RET   

;--------------------------------------------------------------------------------
;             Hard Coded Data
;--------------------------------------------------------------------------------

Length:
   .DB   2

Data:
   .DB   8, 248

LengthSave:
   .DB   0

DataSave:
   .DB   0

CheckSum:
   .DB   0

.end
.end


I was also wondering how you connected to the arduino. Did you just break out the TRS connecter directly to pins or did they control transistors to let power through to the pins? Also, how much current can the IO port source/sink?

Below is the program I wrote that the linking code for. I want to connect to a linux server and use the calculator as a quick terminal window. So far, I can type letters, numbers, hit enter for newline and clear to exit. I know you have done variable width char stuff before. Is it better to save a width table or use the b_call() to load the char?


Code:
.nolist
#include    "ti83plus.inc"
.list

.org    $9D93
.db    t2ByteTok, tAsmCmp

#define BUFSIZE  100
buffer      .EQU appBackUpScreen      ;holds the entered chars
buf_ptr      .EQU buffer + BUFSIZE + 1
wrapmem      .EQU buffer + BUFSIZE + 3   ;holds the position of each char
wrap_ptr   .EQU buffer + BUFSIZE + BUFSIZE + 4

GetStr:
   b_call(_RunIndicOff)
   b_call(_ClrScrnFull)
   b_call(_HomeUp)
   
   RES   AppTextSave, (IY + AppFlags)
   SET   ShiftAlpha, (IY + ShiftFlags)   ;Turn on alphabet
   RES   ShiftLwrAlph, (IY + ShiftFlags)
   
   LD   HL, wrapmem      ;initialize pointer to position data
   LD   (wrap_ptr), HL
   LD   DE, buffer      ;initialize pointer to char data
   LD   (buf_ptr), DE
   
   XOR   A
   LD   (PenCol), A      ;set the location to (0,0)
   INC   A
   LD   (PenRow), A

Startup:
   LD   HL, strtmsg      ;HL points to the startup message
   LD   B, (HL)         ;B now contains the string length
   INC   HL         ;HL points the first letter

startLoop:
   LD   A, (HL)         ;put a char in A
   PUSH   BC         ;save the counter
   PUSH   HL         ;save the pointer
   CALL   displayChar      ;display the char
   POP   HL         ;restore the pointer
   POP   BC         ;restore the counter
   INC   HL         ;point to the next char
   DJNZ   startLoop      ;repeat
   
   XOR   A
   LD   HL, CharCount      ;reset the character counter
   LD   (HL), A

   LD   HL, wrapmem      ;initialize pointer to position data
   LD   (wrap_ptr), HL
   LD   DE, buffer      ;initialize pointer to char data
   LD   (buf_ptr), DE

Main:
   LD   HL, CursorState + 1
   LD   A, (HL)
   OR   A
   JR   NZ, noCursor
      
   CALL   toggleCursor

noCursor:
   DEC   A
   LD   (HL), A
   
   ;CALL   LinkStatus      ;check for incoming data
   
   CALL   GetKey
   OR   A         ;check if a key was pressed
   JR   Z, Main

   CP   skClear
   JR   Z, Exit
   
   PUSH   AF
   LD   HL, CursorState
   LD   A, (HL)
   CP   1
   CALL   Z, toggleCursor
   POP   AF
   
   CALL   ReadKey

   JR   Main

Exit:   
   RES   ShiftAlpha, (IY + ShiftFlags)   ;turn off alpha characters
   b_call(_RunIndicOn)
   b_call(_ClrScrnFull)
   
   RET            ;exit program


GetKey:
   b_call(_GetCSC)         ;scan for keypress
   
   RET            ;return to Main


ReadKey:
   CP   sk2nd         ;check if 2nd key was pressed
   JR   NZ, Not2nd
   
   LD   HL, Flags + ShiftFlags   ;toggle uppercase/lowercase
   LD   A, (HL)
   XOR   32
   LD   (HL), A
   RET            ;go to main

Not2nd:
   CP   skAlpha         ;check if alpha was pressed
   JR   NZ, NotAlpha

   LD   HL, Flags + ShiftFlags   ;toggle alphabet/numberic
   LD   A, (HL)
   XOR   16
   LD   (HL), A
   RET            ;go to main

NotAlpha:
   CP   skDel         ;check if delete was pressed
   JR   NZ, NotDel
   
   LD   HL, CharCount
   LD   A, (HL)         ;check if there are any chars
   OR   A
   JR   NZ, delChar
   RET            ;return to main

delChar:
   DEC   A         ;decrement char counter
   LD   (HL), A         
   LD   HL, (wrap_ptr)      ;get the position data pointer
   DEC   HL         ;go back one position in the array
   LD   C, (HL)         ;get the previous char position
   LD   A, (PenCol)      ;get the current location
   OR   A         ;check if current position is left edge
   JR   NZ, sameRow
   
   LD   A, 95         ;See how close to right edge the previous char was
   SUB   C
   LD   B, A         ;make the difference a loop counter
   LD   A, (HL)         ;get previous location
   LD   (PenCol), A      ;move cursor back one char
   LD   A, (PenRow)      ;move cursor up one row
   ADD   A, -7
   LD   (PenRow), A
   CALL   delLoop         ;"erase" the char
   
   LD   A, (HL)         ;the cursor moved forward to "erase"
   LD   (PenCol), A      ;move it back
   LD   (wrap_ptr), HL      ;save the current pointer position
   RET            ;return to main

sameRow:
   SUB   C         ;figure out the number of pixels between the two chars
   LD   B, A         ;save difference as loop counter
   LD   A, (HL)         ;get previous location
   LD   (PenCol), A      ;move cursor back one char
   CALL   delLoop         ;"erase" the char

   LD   A, (HL)         ;move cursor back again
   LD   (PenCol), A
   LD   (wrap_ptr), HL      ;save current pointer position
   RET            ;return to main

delLoop:
   LD   A, $20         ;A holds the <space> token
   b_call(_VPutMap)      ;draw a <space>
   DJNZ   delLoop         ;repeat until char is "erased"

   RET
   
NotDel:
   CP   skEnter         ;check if clear was pressed
   JR   NZ, NotEnter
   
   XOR   A
   LD   HL, CharCount      ;reset char counter
   LD   (HL), A
   
   LD   HL, wrapmem      ;reset pointer to position data
   LD   (wrap_ptr), HL
   LD   DE, buffer      ;reset pointer to char data
   LD   (buf_ptr), DE
   
   LD   A, $FE         ;display a newline char
   JR   validChar

NotEnter:
   LD   C, A         ;save A for awhile
   LD   HL, CharCount
   LD   A, (HL)         ;check if buffer is full
   CP   BUFSIZE
   RET   Z         ;return to main
   
   LD   A, C         ;restore A

   SUB   skAdd         ;check if A is a keypress in the range we want
   RET   C         ;return to main
   CP   skMath - skAdd + 1
   RET   NC         ;return to main

   LD   DE, CharTable      ;DE points to uppercase char LUT
   BIT   ShiftAlpha, (IY + ShiftFlags)   ;check if alpha is mode
   JR   NZ, AlphaMode
   
   LD   DE, NormalTable      ;DE points to numeric char LUT
   JR   lowerMode
   
AlphaMode:
   BIT   ShiftLwrAlph, (IY + ShiftFlags)   ;check if lowercase alphabet
   JR   NZ, lowerMode
   LD   DE, LowerTable      ;DE points to lowercase char LUT
   
lowerMode:
   LD   H, 0         ;put keypress in HL
   LD   L, A
   ADD   HL, DE         ;add keypress offset to the pointer
   LD   A, (HL)         ;to the char data table and save it in A
   
   CALL   displayChar
   RET            ;return to main

displayChar:
   LD   C, A         ;save char for awhile
   LD   H, 0         ;put char in HL
   LD   L, A
   LD   DE, WidthTable - $20   ;DE points to WidthTable

   CP   $FF
   JR   NZ, validChar
   RET

validChar:
   CP   $FE
   JR   NZ, notReturn
   
   LD   A, (PenRow)
   ADD   A, 7
   
   CP   64
   CALL   Z, scrollUp
   
   LD   (PenRow), A
   XOR   A
   LD   (PenCol), A
   RET

notReturn:
   CP   $c1
   JR   NZ, notLBracket
   LD   A, 3
   JR   checkEdge

notLBracket:
   ADD   HL, DE         ;add the offset and store in HL
   LD   A, (HL)         ;store the width pointed to in the table

checkEdge:
   LD   HL, Pencol      ;add the next char width to the current
   ADD   A, (HL)         ;cursor position

   CP   95         ;check if past right edge of screen
   JR   C, sameLine
   
   LD   A, (PenRow)      ;move cursor down a row
   ADD   A, 7
   CP   64

   CALL   Z, scrollUp
   
   LD   (PenRow), A

   XOR   A         ;move cursor to left edge
   LD   (PenCol), A

sameLine:
   LD   HL, (wrap_ptr)      ;store the position of the cursor into
   LD   A, (PenCol)      ;the position data pointed by HL
   LD   (HL), A
   INC   HL         ;move pointer to next memory address
   LD   (wrap_ptr), HL      ;save pointer
   
   LD   A, C         ;restore char to A
   PUSH   AF         ;save char for later
   b_call(_VPutMap)      ;display char
   POP   AF         ;restore char
   LD   DE, buf_ptr      ;DE points to buffer

   LD   (DE), A         ;store char in buffer
   INC   DE         ;move pointer to next memory address
   LD   (buf_ptr), DE
   LD   HL, CharCount
   LD   A, (HL)
   INC   A         ;increment char counter
   LD   (HL), A
   RET

scrollUp:
   PUSH   HL
   PUSH   BC
   PUSH   DE
   PUSH   AF
   
   DI
   
   LD   A, $07
   OUT   ($10), A      ;set column auto-increment mode
   CALL   lcdBusy

   LD   A, $20         ;set column to zero
   OUT   ($10), A

   LD   C, $87         ;C holds read row

column:
   INC   C
   LD   A, C
   CP   $BF
   JR   Z, scrollDone

   CALL   lcdBusy
   OUT   ($10), A      ;set read row
   
   CALL   lcdBusy
   IN   A, ($11)      ;dummy read
   
   LD   B, 12         ;12 columns per row
   LD   HL, ScrollData
   
readRow:
   CALL   lcdBusy
   IN   A, ($11)      ;read a byte
   LD   (HL), A         ;save it away
   INC   HL
   DJNZ   readRow
   
   LD   A, C
   SUB   7

   CALL   lcdBusy
   OUT   ($10), A      ;set write row
   
   CALL   lcdBusy
   LD   A, $20
   OUT   ($10), A      ;reset column to zero
   
   LD   B, 12
   LD   HL, ScrollData
   
writeRow:
   LD   A, (HL)         ;load a byte
   INC   HL
   CALL   lcdBusy
   OUT   ($11), A      ;write a byte
   DJNZ   writeRow

   CALL   lcdBusy
   LD   A, $20
   OUT   ($10), A      ;reset column to zero
   JR   column

scrollDone:
   LD   C, $B7
   
column2:
   INC   C
   LD   A, C
   CP   $BF
   JR   Z, exitScroll

   CALL   lcdBusy
   OUT   ($10), A      ;set read row
   
   LD   B, 12
   LD   HL, ScrollData
   
clearLowest:
   LD   A, 0         ;load a byte
   CALL   lcdBusy
   OUT   ($11), A      ;write a byte
   DJNZ   clearLowest

   CALL   lcdBusy
   LD   A, $20
   OUT   ($10), A      ;reset column to zero
   JR   column2

exitScroll:
   CALL   lcdBusy
   LD   A, $05
   OUT   ($10), A      ;set row auto increment mode
   
   POP   AF
   POP   DE
   POP   BC
   POP   HL
   
   SUB   7
   EI

   RET

toggleCursor:
   PUSH   HL
   PUSH   BC
   PUSH   DE
   PUSH   AF
   
   DI

   LD   HL, CursorState
   LD   A, (HL)
   XOR   1         ;flip the state flag
   LD   (HL), A

   LD   A, (PenRow)      ;set row to current position
   ADD   A, $80
   OUT   ($10), A
   
   LD   A, (PenCol)      ;A holds read column
   SRL   A
   SRL   A         ;divide by 8 to get byte column
   SRL   A
   ADD   A, $20         ;A holds correct LCD column
   
   LD   HL, CursorCol
   LD   (HL), A         ;save column for later

   CALL   lcdBusy
   OUT   ($10), A      ;set column
      
   LD   A, (PenCol)
   AND   7
   LD   B, A
   LD   A, $80         ;A is %1000 0000
   JR   Z, skipMask

maskLoop:
   RRCA            ;move the 1 to the correct spot
   DJNZ   maskLoop

skipMask:
   LD   C, A         ;save the bitmask

   CALL   lcdBusy
   IN   A, ($11)      ;dummy read

   LD   B, 7         ;read seven lines
   LD   HL, ScrollData

toggleRow:
   CALL   lcdBusy
   IN   A, ($11)      ;read a byte
   LD   (HL), A         ;save the row
   INC   HL
   DJNZ   toggleRow
   
   CALL   lcdBusy
   LD   A, (PenRow)      ;move back to correct row
   ADD   A, $80
   OUT   ($10), A
   
   CALL   lcdBusy
   LD   HL, CursorCol
   LD   A, (HL)         ;move back to correct column
   OUT   ($10), A

   LD   B, 7
   LD   HL, ScrollData

drawCursor:
   LD   A, (HL)         ;draw the cursor
   INC   HL
   XOR   C         ;toggle the cursor bit
   CALL   lcdBusy
   OUT   ($11), A
   DJNZ   drawCursor

   CALL   lcdBusy

   POP   AF
   POP   DE
   POP   BC
   POP   HL

   EI
   RET

lcdBusy:
   PUSH   AF
   CALL   $000B
   POP   AF
   RET


ScrollData:
   .DB   0,0,0,0,0,0,0,0,0,0,0,0

CursorCol:
   .DB   0

CursorState:
   .DB   0,0

CharCount:
   .DB   0

CharTable:            ;LUT for uppercase chars
   .DB   $22, "WRMH", $FF, $FF
   .DB   "?@VQLG", $FF, $FF
   .DB   ":ZUPKFC", $FF
   .DB   " YTOJEB", $FF, $FF
   .DB   "XSNIDA"

LowerTable:            ;LUT for lowercase chars
   .DB   $27, "wrmh", $FF, $FF
   .DB   "_/vqlg", $FF, $FF
   .DB   $7C, "zupkfc", $FF
   .DB   " ytojeb", $FF, $FF
   .DB   "xsnida"

NormalTable:            ;LUT for numeric/symbolic chars
   .DB   "+-*/^", $FF, $FF
   .DB   $7E, "369)", $C1, "]", $FF
   .DB   ".258({};"
   .DB   "0147,<>",$5B, $FF
   .DB   $24, "!=#%&"

WidthTable:
   .DB   1,2,4,6,6,4,6,2,3,3,6,4,3,4,2,4
   .DB   4,4,4,4,4,4,4,4,4,4,2,3,4,4,4,4
   .DB   6,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4
   .DB   4,4,4,4,4,4,4,4,4,4,4,4,4,3,4,4
   .DB   3,4,4,4,4,4,3,4,4,2,4,4,3,6,4,4
   .DB   4,4,4,3,3,4,4,6,4,4,5,4,2,4,5,4

strtmsg:
   .DB   64
   .DB   "     =Terminal Connect Alpha=", $FE
   .DB   "          (c) 2011  Frozen Flame", $FE, $FE

save_sp:
   .DW   0

.end
.end
Regarding the GUI/text entry stuff, you could save yourself some sanity by just using the Doors CS GUI functions for text input. Smile They're very easy and straightforward, and would likely speed up your development process. Doors CS also exposes a width table as of the latest beta that programs can use to calculate character widths, since the TI-OS's bcall is slooooow.

Transistors would break the bidirectionality of the link port when interfacing with the Arduino, unless you used something like a tristate buffer. I just connect the pins directly (tip and ring are the two data lines, base is ground). The link port shouldn't source more than a few mA if you can help it, nor sink more than a few mA.
  
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