As I've re-acquainted myself with BASIC, I've found myself getting more and more annoyed with how slow / restrictive it is, and while I've seen some really impressive BASIC games; all the best programs seem to be written in ASM, so I figured I'd give it a try. I'm making this thread to document my progress. So far, I've finished through Day 14 of "Learn TI-83+ Assembly in 28 Days", and made a program that fills the screen with "X" to practice. The code doesn't exit properly, so it just runs in an infinite loop.

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

.org userMem
.db t2ByteTok, tAsmCmp

Start:
    BCALL(_HomeUp) ; Defines intial values

DrawingLoop:
    LD A, 'X'
    BCALL(_PutC) ;Draws character to the screen and stores the new cursor value in (CurRow) and (CurCol)
    LD HL, (CurCol) ; Loads the value of (CurCol) into HL so I can ensure the value isn't too high
    LD A, L
    ADD A, H ; Gets the value of (CurCol) into A so I can actually do the comparison
    CP 16
    JR NC, IncrementRow ; Jumps to IncrementRow if (CurCol) is 16 or higher, restarts the loop otherwise
    JR DrawingLoop
IncrementRow:
    BCALL(_NewLine) ; Increments the row
    LD A, (CurRow)
    CP 8 ; Ensures the row value isn't too high and starts the erasure loop if it is
    JR NC, Exit
    JR DrawingLoop
Exit:
    nop
.end

I really like how fast ASM is, but I'm not a huge fan of registers so far; especially since the system seems incredibly picky which ones you can use with each instruction.
Nice, needs a ret nc instead of the jr nc, exit.
Have fun! Assembly can be challenging to learn, but also incredibly satisfying to have success with.

Monado07 wrote:
I really like how fast ASM is, but I'm not a huge fan of registers so far; especially since the system seems incredibly picky which ones you can use with each instruction.

You'll get used to that Razz It becomes more apparent over time that each of the registers have their own special use, eg. B as a counter, C for "in" and "out" instructions, etc.
I was able to create a program that prints the Fibonacci sequence up to the 16 bit integer limit. I had some difficulty because I forgot some BCALLs change HL; but I was able to fix the problem by using the stack. Unlike the last program, this one exits properly.


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

.org userMem
.db t2ByteTok, tAsmCmp

start:
   BCALL(_HomeUp)
   LD B, 0
    LD C, 1
   LD H, 0
   LD L, 0
   OR A
FibonacciLoop:
    ADD HL, BC
    RET C
   PUSH HL ; Pushes HL to the stack since the BCALLs mess it up
   BCALL(_NewLine)
    BCALL(_DispHL)
   BCALL(_GetKey) ; Pauses program until a key is pressed
   
   POP HL ; Restores old value of HL
   
    LD (temp), BC ; Loads BC into temp so I can swap its value with HL
    LD C, L
    LD B, H ; Loads HL into BC
    LD HL, (temp) ; values are now swapped, so I can display the next number in the sequence
    ADD HL, BC
    RET C
   PUSH HL
   BCALL(_NewLine)
    BCALL(_DispHL)
   BCALL(_GetKey) ; Pauses program until a key is pressed
   
   POP HL
   
    LD (temp), HL ; Loads HL into temp so I can swap its value with BC
    LD L, C
    LD H, B ; Loads BC into HL
    LD BC, (temp) ; values are now swapped, so I can display the next number in the sequence
    JR FibonacciLoop
temp:
    .EQU $8000
Nice work, a good tip is that you can use the stack to swap registers around too if you want:

Code:
   set appAutoScroll,(iy + appFlags) ; flag to ensure screen autoscrolls
   ld hl,0
   ld de,1
fibloop:
   push hl
   push de
   bcall(_dispHL)
   bcall(_getKey)
   bcall(_newline)
   pop hl
   pop de
   add hl,de
   jr nc,fibloop
   ret


You will notice how the order in which hl & de are popped from the stack is the opposite in which they were pushed which effectively swaps them.
I've been struggling to create a program to perform 8 bit addition. I have this so far:

Code:
.nolist
#include "ti83plus.inc"
.list
.org userMem-2
.db $BB,$6D
start:
   bcall(_ClrLCDFull)
    ld hl, inputText1
    bcall(_PutS)
   bcall(_NewLine)
   ld hl, 0
   call numberSelection
   pop hl
   ld (num1), hl
   
   bcall(_ClrLCDFull)
   ld hl, 0
   ld (CurCol), hl
   ld (CurRow), hl
    ld hl, inputText2
    bcall(_PutS)
   bcall(_NewLine)
   ld hl, 0
   call numberSelection
   pop hl
   ld a, l
   ld hl, (num1)
   add a, l
   ld l, a
   push hl
   
   bcall(_ClrLCDFull)
    ld hl, answer
    bcall(_PutS)
   bcall(_NewLine)
   pop hl
   bcall(_DispHL)
   ret
numberSelection:
   push hl ; Preserves HL
   bcall(_DispHL)
   bcall(_GetKey)
   cp kUp
   jr z, increase
   cp kDown
   jr Z, decrease
   cp kEnter
   ret z
   ld hl, 0
   ld (CurCol), hl
   pop hl
   jr numberSelection
   
increase:
   ld hl, 0
   ld (CurCol), hl
   pop hl
   ld a, l
   push hl
   ld hl, 1
   add a, l
   pop hl
   ld l, a
   jr numberSelection
   
decrease:
   ld hl, 0
   ld (CurCol), hl
   pop hl
   ld a, l
   push hl
   ld hl, 1
   sub a, l
   pop hl
   ld l, a
   jr numberSelection
inputText1:
    .db "INPT NUM 1: ",0
inputText2:
    .db "INPT NUM 2: ",0
answer:
   .db "ANSWER: ",0
num1:
   .equ $8000

Using the up and down keys to choose the values seems to work fine, but the calculator crashes after the second value is selected, sometimes displaying a large number as the answer. I know BCALLs change HL, but from using the debugger (a tool I've found myself getting quite familiar with as I've written this program), the correct values seem to be getting PUSHed to the stack. The problem seems to be that an incorrect value is being POPed into HL after RET Z is executed. I'm unsure how this is happening though since there aren't any PUSH instructions between the result being PUSHed and the problematic POP instruction.
Tracing it myself:
  • start
  • call numberSelection: pushes return address
  • push hl
  • assume key = enter; return, popping preserved HL as return address: probably crash

It looks like you're trying to store temporaries on the stack separately from return addresses but there's only one stack so that's not possible.
I managed to fix the issue, I'd forgotten that CALL pushes the return address to the stack, and I had to rewrite the program to work around that. This is really unoptimized, and the answer will wrap around if it's over 255, but frankly I'm just glad it's finally working after days of debugging.

Code:
.nolist
#include "ti83plus.inc"
.list
.org userMem-2
.db $BB,$6D
start:
   bcall(_ClrLCDFull)
   ld hl, 0
   ld (CurCol), hl
   ld (CurRow), hl
    ld hl, inputText1
    bcall(_PutS)
   bcall(_NewLine)
   ld hl, 0
   call numberSelection1
   bcall(_ClrLCDFull)
   ld hl, 0
   ld (CurCol), hl
   ld (CurRow), hl
    ld hl, inputText2
    bcall(_PutS)
   bcall(_NewLine)
   ld hl, 0
   call numberSelection2
   ld hl, (num1)
   ld a, l
   ld hl, (num2)
   add a, l
   ld h, 0
   ld l, a
   push hl
   bcall(_ClrLCDFull)
   ld hl, 0
   ld (CurCol), hl
   ld (CurRow), hl
    ld hl, answer
    bcall(_PutS)
   bcall(_NewLine)
   pop hl
   bcall(_DispHL)
   ret
numberSelection1:
   push hl ; Preserves HL
   bcall(_DispHL)
   bcall(_GetKey)
   cp kUp
   jr z, increase1
   cp kDown
   jr Z, decrease1
   cp kEnter
   jr Z, putHLInVarNum1
   ld hl, 0
   ld (CurCol), hl
   pop hl
   jr numberSelection1

increase1:
   ld hl, 0
   ld (CurCol), hl
   pop hl
   ld a, l
   push hl
   ld hl, 1
   add a, l
   pop hl
   ld l, a
   jr numberSelection1
   
decrease1:
   ld hl, 0
   ld (CurCol), hl
   pop hl
   ld a, l
   push hl
   ld hl, 1
   sub a, l
   pop hl
   ld l, a
   jr numberSelection1
putHLInVarNum1:
   pop hl
   ld (num1), hl
   RET
numberSelection2:
   push hl ; Preserves HL
   bcall(_DispHL)
   bcall(_GetKey)
   cp kUp
   jr z, increase2
   cp kDown
   jr Z, decrease2
   cp kEnter
   jr Z, putHLInVarNum2
   ld hl, 0
   ld (CurCol), hl
   pop hl
   jr numberSelection2
increase2:
   ld hl, 0
   ld (CurCol), hl
   pop hl
   ld a, l
   push hl
   ld hl, 1
   add a, l
   pop hl
   ld l, a
   jr numberSelection2
   
decrease2:
   ld hl, 0
   ld (CurCol), hl
   pop hl
   ld a, l
   push hl
   ld hl, 1
   sub a, l
   pop hl
   ld l, a
   jr numberSelection2
putHLInVarNum2:
   pop hl
   ld (num2), hl
   RET
   
   
inputText1:
    .db "INPT NUM 1: ",0
inputText2:
    .db "INPT NUM 2: ",0
answer:
   .db "ANSWER: ",0
num1:
   .equ $8000
num2:
   .equ $8002
Glad you got it working, a few tips:
CurCol and CurRow are only 1 byte each, so writing HL to them writes 2 bytes to each address. In the case of CurRow it's ok since CurCol follows it directly in RAM (so writing hl=0 to CurRow has the effect of zeroing out BOTH CurRow and CurCol). Writing 2 bytes to CurCol however will overwrite the memory after it, which is CurOffset by the looks. You could use A instead or you could take advantage of the 16-bit write and do something like ld hl,(5*256)+2 to write 2 in CurRow and 5 in CurCol at the same time.

Have a think about a way that you could use 1 function for 'numberSelection' instead of 2 very similar ones.

There are ways to utilise registers and only use the stack when needed. It's generally not good practice and difficult for debugging to have functions that rely on uneven stack usage, as I think you found out here since CALL uses the stack too. Usually you would use the stack to save registers around functions like:

Code:
push hl
call function
pop hl
tr1p1ea wrote:
Glad you got it working, a few tips:
CurCol and CurRow are only 1 byte each, so writing HL to them writes 2 bytes to each address. In the case of CurRow it's ok since CurCol follows it directly in RAM (so writing hl=0 to CurRow has the effect of zeroing out BOTH CurRow and CurCol). Writing 2 bytes to CurCol however will overwrite the memory after it, which is CurOffset by the looks. You could use A instead or you could take advantage of the 16-bit write and do something like ld hl,(5*256)+2 to write 2 in CurRow and 5 in CurCol at the same time.

Have a think about a way that you could use 1 function for 'numberSelection' instead of 2 very similar ones.

There are ways to utilise registers and only use the stack when needed. It's generally not good practice and difficult for debugging to have functions that rely on uneven stack usage, as I think you found out here since CALL uses the stack too. Usually you would use the stack to save registers around functions like:

Code:
push hl
call function
pop hl


I took a look at the problem and I was able to compress NumberSelection into 1 function (also getting rid of "increase2" and "decrease2" in the process), it was easier than expected as well. I think I'm slowly starting to get more comfortable with ASM, though I've gotten to Day 24 in Learn TI-83+ Plus Assembly in 28 days and interrupts / the graphics buffer have definitely re-humbled me. This is the new code:


Code:
.nolist
#include "ti83plus.inc"
.list
.org userMem-2
.db $BB,$6D
start:
   bcall(_ClrLCDFull)
   ld hl, 0
   ld (CurCol), hl
   ld (CurRow), hl
   ld hl, inputText1
   bcall(_PutS)
   bcall(_NewLine)
   ld hl, 0
   ld (state), HL ; Used to store whether the first or second number is being inputted
   call numberSelection
   
   bcall(_ClrLCDFull)
   ld hl, 0
   ld (CurRow), hl
   ld hl, inputText2
   bcall(_PutS)
   bcall(_NewLine)
   ld hl, 1
   ld (state), HL ; Used to store whether the first or second number is being inputted
   ld hl, 0
   call numberSelection
   
   ld hl, (num1)
   ld a, l
   ld hl, (num2)
   add a, l ; The actual addition
   ld h, 0
   ld l, a
   push hl
   bcall(_ClrLCDFull)
   ld hl, 0
   ld (CurRow), hl ; Zeros out both CurRow and CurCol
   ld hl, answer
   bcall(_PutS)
   bcall(_NewLine)
   pop hl
   bcall(_DispHL) ; Displays final answer
   ld a, 3
   ld (CurRow), a
   ld a, 0
   ld (CurCol), a
   ld hl, exitPrompt
   bcall(_PutS)
   bcall(_getKey)
   ret
numberSelection:
   push hl ; Preserves HL
   bcall(_DispHL)
   bcall(_GetKey)
   cp kUp
   jr z, increase
   cp kDown
   jr Z, decrease
   cp kEnter
   jr Z, determine
   ld hl, 0
   ld (CurCol), hl
   pop hl
   jr numberSelection

increase:
   ld hl, 0
   ld (CurCol), hl
   pop hl
   ld a, l
   push hl
   ld hl, 1
   add a, l
   pop hl
   ld l, a
   jr numberSelection
   
decrease:
   ld hl, 0
   ld (CurCol), hl
   pop hl
   ld a, l
   push hl
   ld hl, 1
   sub a, l
   pop hl
   ld l, a
   jr numberSelection

determine:
   ld hl, (state)
   ld a, l
   cp 0
   jr Z, putHLInVarNum1
   jr putHLInVarNum2
putHLInVarNum1:
   pop hl
   ld (num1), hl
   ret

putHLInVarNum2:
   pop hl
   ld (num2), hl
   ret   
inputText1:
    .db "INPT NUM 1: ",0
inputText2:
    .db "INPT NUM 2: ",0
answer:
   .db "ANSWER: ",0
exitPrompt:
   .db "PRESS ANY TO EXT",0
num1:
   .equ $8000
num2:
   .equ $8002
state:
   .equ $8004

Side note: are there standard conventions for ASM programs here (eg: using uppercase / lowercase for instructions, how to name labels, etc)? From what I've read there aren't really any for the Z80 in general, but I'm unsure if this community prefers any particular style / if there are any that are considered better.
I've now finished Learn TI-83 Plus Assembly in 28 Days. Overall, I found the tutorial really helpful, I came into it never having used any type of ASM and most days felt reasonably challenging / in-depth without getting too confusing. Some of the more technical parts (eg: Days 8, 9 and 15) tripped me up, but I feel like I have at least a decent basis to start looking at other people's programs and be able to figure out what they were going for.

As for ASM itself, the main challenge seems to come from the fact the syntax is so simple, most instructions are really bare-bones; but that means you have to construct stuff manually that BASIC has specific commands for, making sure you manage all your registers correctly lest you get a RAM clear. I really like how flexible that makes it though; even really simple programs feel like my own original creation instead of having to do things the TI-approved way, and of course the speed is insane compared to BASIC due to being assembled.

Going forward, I plan on downloading some simple Assembly programs and trying to add / remove small things as well as continuing to make progressively more complex stuff on my own. With a medium-term goal of mine (want to finish this before Jun. 31) being to port the Hangman game I wrote about a month ago to ASM without sacrificing any functionality. It was decently complex, which should provide a good challenge, but I also wrote it myself so I know exactly how everything works, an ASM port would also improve the sluggish speed. It's definitely pretty nerve-wracking knowing I've pretty much exhausted all the instructional material on the language, but I'm excited to continue learning.
In your last section of code above, I note that you still several instances of the memory-overwriting with curcol, such as:

Code:
   ld hl, 0
   ld (CurCol), hl
   ld (CurRow), hl
Since your state can only be 0 or 1, you can make that be one byte and use a rather than hl to access it as well, saving a few bytes. And for that matter, you can then use xor a as a substitute for ld a,0, thus:
Code:
   xor a
   ld (state), a ; Used to store whether the first or second number is being inputted
and later:
Code:
   ld a,1
   ld (state), a ; Used to store whether the first or second number is being inputted
   ld hl, 0
   call numberSelection
Finally, using appData as scratch memory is a good idea, but it's much more common to use the symbols (which also facilitate porting and updating) and to use offsets from previous equates, so that you can insert one later if needed without changing all the values:
Code:
    num1 .equ appData   ; 2 bytes
    num2 .equ num1 + 2  ; 2 bytes
    state .equ num2 + 2 ; 1 byte

Quote:
Going forward, I plan on downloading some simple Assembly programs and trying to add / remove small things as well as continuing to make progressively more complex stuff on my own. With a medium-term goal of mine (want to finish this before Jun. 31) being to port the Hangman game I wrote about a month ago to ASM without sacrificing any functionality.
That sounds like a perfect next step: reading and understanding others' code (an important prerequisite to modifying it, of course), and then a medium-difficulty project of your own. Please do keep the questions coming, and we'll be happy to help!
Monado07 wrote:
As I've re-acquainted myself with BASIC, I've found myself getting more and more annoyed with how slow / restrictive it is, and while I've seen some really impressive BASIC games; all the best programs seem to be written in ASM, so I figured I'd give it a try. I'm making this thread to document my progress. So far, I've finished through Day 14 of "Learn TI-83+ Assembly in 28 Days", and made a program that fills the screen with "X" to practice. The code doesn't exit properly, so it just runs in an infinite loop.

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

.org userMem
.db t2ByteTok, tAsmCmp

It happen the same thing with me, but in my case, I dont know where to learn z80 ASM.

Start:
    BCALL(_HomeUp) ; Defines intial values

DrawingLoop:
    LD A, 'X'
    BCALL(_PutC) ;Draws character to the screen and stores the new cursor value in (CurRow) and (CurCol)
    LD HL, (CurCol) ; Loads the value of (CurCol) into HL so I can ensure the value isn't too high
    LD A, L
    ADD A, H ; Gets the value of (CurCol) into A so I can actually do the comparison
    CP 16
    JR NC, IncrementRow ; Jumps to IncrementRow if (CurCol) is 16 or higher, restarts the loop otherwise
    JR DrawingLoop
IncrementRow:
    BCALL(_NewLine) ; Increments the row
    LD A, (CurRow)
    CP 8 ; Ensures the row value isn't too high and starts the erasure loop if it is
    JR NC, Exit
    JR DrawingLoop
Exit:
    nop
.end

I really like how fast ASM is, but I'm not a huge fan of registers so far; especially since the system seems incredibly picky which ones you can use with each instruction.





It happen the same thing with me, But in my case I dont know where to start or where I can learn. Graphing Calculator
It's been a while since I updated this thread, I originally intended to continue posting every few days like before, but my Spring Break happened and I figured I'd take a break since I was burned out. Then it ended and I became busy again, which made me even more burnt out, I put off doing ASM for a few days, which became weeks, which became months, the usual story. In any case, I graduated from HS on May. 21 and resolved to get back to ASM since I no longer had any excuses. I picked up a program idea from before I fell off and just forced myself to finish it to get myself back in the groove, and I'm finally done! The program is a simple 4-function calculator with key input, and to be honest making it was a ROUGH process, I was very out of practice and adding a prompt injected a ton of complexity (eg: handling the buffer, converting from ASCII to decimal, echo, how to distinguish between number and character input, etc). I ended up leaning heavily on the tutorial for the majority of the input stuff (Day 27 was a huge lifesaver) as well as the multiplication / division, though I did my best to rename stuff and try to understand everything so I wasn't just copy / pasting. Overall, I'm pretty happy with the result, multiplication and division are only 8 bit compared to the 16 bit addition / subtraction functions, and it's definitely not efficient at all, but just having everything display properly feels like a minor miracle. I'll probably continue with my previous plan on looking at other programs after this, and aim to finish a simple Pong game before Jun. 10. The source code for my calculator program is below.

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

.org userMem-2
.db $BB,$6D
#DEFINE letterBufferSize 1
#DEFINE numberBufferSize 3

Start:
   BCALL(_ClrLCDFull)
   BCALL(_HomeUp)
   LD HL, InputText1
   BCALL(_PutS)
   LD A, 0
   LD (Value), A
ErrorReset
   CALL GetSelection
   CP $41 ; Code for "A"
   JR Z, Continue
   CP $53 ; Code for "S"
   JR Z, Continue
   CP $4d ; Code for "M"
   JR Z, Continue
   CP $44 ; Code for "D"
   JR Z, Continue
   JR Start
Continue:
   PUSH AF
   CALL NumberSelection
   POP AF
   CP $41 ; Code for "A"
   JP Z, Addition
   CP $53 ; Code for "S"
   JP Z, Subtraction
   CP $4d ; Code for "M"
   JP Z, Multiplication
   CP $44 ; Code for "D"
   JP Z, Division
   
GetSelection:
   LD HL, Buffer
   LD (buf_ptr), HL
   XOR A ;Erases A
   LD B, A ;B is used to track how many letters have been inputted

InputLoop:
   EX DE, HL
   BCALL(_GetCSC)
   EX DE, HL
   OR A
   JR Z, InputLoop
   CP skEnter
   JR NZ, EnterWasntPressed
   LD (HL), 0 ;Closes off buffer
   LD HL, Buffer
   LD A, (HL)
   RET
   
EnterWasntPressed:
   LD C, A
   LD A, (Value)
   CP $0
   JR NZ, NumberProcessing ; Detects if letters or numbers are being processed
   LD A, B
   CP letterBufferSize
   JR Z, InputLoop
   LD A, C
   SUB skAdd
   JR C, InputLoop
   CP skMath - skAdd + 1
   JR NC, InputLoop
   PUSH HL
   LD H, 0
   LD L, A
   LD DE, CharTable
   ADD HL, DE
   LD A, (HL)
   POP HL
   BCALL(_PutC)
   LD (HL), A
   INC HL
   INC B
   JR InputLoop
NumberProcessing:
   LD A, B
   CP numberBufferSize
   JR Z, InputLoop
   LD A, C
   SUB skAdd
   JR C, InputLoop
   CP skMath - skAdd + 1
   JR NC, InputLoop
   PUSH HL
   LD H, 0
   LD L, A
   LD DE, NormTable
   ADD HL, DE
   LD A, (HL)
   POP HL
   BCALL(_PutC)
   LD (HL), A
   INC HL
   INC B
   JR InputLoop
GetCharacter:
   PUSH HL
   LD HL, (buf_ptr)
   LD A, (HL)
   OR A
   SCF
   JR Z, GetCharacterFinished
   INC HL
   LD (buf_ptr), HL
   OR A
GetCharacterFinished:
   POP HL
   RET
UngetCharacter:
   PUSH HL
   PUSH DE
   LD HL, (buf_ptr)
   LD DE, Buffer
   BCALL(_CpHLDE)
   SCF
   JR Z, UngetCharacterFinished
   DEC HL
   LD (buf_ptr), HL
   OR A
UngetCharacterFinished:
   POP DE
   POP HL
   RET
   
NumberSelection:
   BCALL(_ClrLCDFull)
   BCALL(_HomeUp)
   LD HL, InputText2
   BCALL(_PutS)
   LD A, 1
   LD (Value), A
   CALL GetSelection
   CALL AsciiToDecimal
   LD A, H
   LD (Num1), A
   LD A, L
   LD (Num1 + 1), A
   BCALL(_NewLine)
   BCALL(_NewLine)
   LD HL, InputText3
   BCALL(_PutS)
   CALL GetSelection
   CALL AsciiToDecimal
   LD A, H
   LD (Num2), A
   LD A, L
   LD (Num2 + 1), A
   RET
AnswerSequence:
   BCALL(_NewLine)
   BCALL(_NewLine)
   LD HL, AnswerText
   BCALL(_PutS)
   LD HL, (Answer)
   BCALL(_DispHL)
   BCALL(_NewLine)
   RET
   
   
Addition:
   LD A, (Num1)
   LD H, A
   LD A, (Num1 + 1)
   LD L, A
   LD A, (Num2)
   LD D, A
   LD A, (Num2 + 1)
   LD E, A
   ADD HL, DE
   LD A, L
   LD (Answer), A
   LD A, H
   LD (Answer + 1), A
   JR AnswerSequence
   RET

Subtraction:
   LD A, (Num1)
   LD H, A
   LD A, (Num1 + 1)
   LD L, A
   LD A, (Num2)
   LD D, A
   LD A, (Num2 + 1)
   LD E, A
   BCALL(_CpHLDE)
   JR C, SubtractionUnderflowHandler
   OR A
   SBC HL, DE
   LD A, L
   LD (Answer), A
   LD A, H
   LD (Answer + 1), A
   JR AnswerSequence
SubtractionUnderflowHandler:
   LD HL, 0
   LD (Answer), HL
   JR AnswerSequence
   RET
   
Multiplication:
   LD A, (Num1 + 1)
   LD D, A
   LD A, (Num2 + 1)
   LD E, A
   CALL MultiplicationFunction
   LD A, L
   LD (Answer), A
   LD A, H
   LD (Answer + 1), A
   JR AnswerSequence
MultiplicationFunction:
   LD HL, 0
   XOR A
   OR D
   RET Z
   OR E
   RET Z
   LD B, D
   LD D, H
MultiplicationLoop:
   ADD HL, DE
   DJNZ MultiplicationLoop
   RET
   
Division:
   LD A, (Num1 + 1)
   LD L, A
   LD H, 0
   LD A, (Num2 + 1)
   LD D, A
   CALL DivisionFunction
   LD A, L
   LD (Answer), A
   LD A, H
   LD (Answer + 1), A
   JP AnswerSequence
   
DivisionFunction:
   XOR A
   LD B, 16
DivisionLoop:
   ADD HL, HL
   RLA
   JR C, DivisionOverflow
   CP D
   JR C, DivisionSkip
DivisionOverflow
   SUB D
   INC L
DivisionSkip:
   DJNZ DivisionLoop
   RET

AsciiToDecimal:
   LD HL, 0
   LD B, H
Loop:
   CALL GetCharacter
   CCF
   RET NC
   SUB '0'
   JR C, Check
   CP 10
   CCF
   RET C
   LD D, H
   LD E, L
   ADD HL, HL
   ADD HL, HL
   ADD HL, DE
   ADD HL, HL
   JR C, Overflow
   LD C, A
   ADD HL, BC
   JR NC, Loop
Overflow:
   EX DE, HL
   JP UngetCharacter
Check:
   CP ' ' - '0'
   RET Z
   SCF
   RET


InputText1:
   .DB "INPUT OPERATION "
   .DB "(A, S, M, D): ",0
InputText2:
   .DB "INPUT NUM 1:",0
InputText3:
   .DB "INPUT NUM 2:",0
AnswerText:
   .DB "ANSWER:",0
ErrorText1:
   .DB "INVALID ENTRY!",0
Buffer:
   .EQU TextShadow ; 4 bytes
buf_ptr:
   .EQU Buffer + letterBufferSize + 3 ; 1 byte, stores position in buffer
Value:
   .EQU AppData ; 1 byte, stores whether numbers or letters should be processed
Num1:
   .EQU AppData + 1 ; 2 bytes, stores first number
Num2:
   .EQU AppData + 3 ; 2 bytes, stores second number
Answer:
   .EQU AppData + 5 ; 2 bytes, stores final answer
   
CharTable: ;Copied from tutorial
   .DB  "'WRMH", 0, 0            ; + - × ÷ ^ undefined
   .DB  "?", LTheta, "VQLG", 0, 0  ; (-) 3 6 9 ) TAN VARS undefined
   .DB  ":ZUPKFC", 0            ; . 2 5 8 ( COS PRGM STAT
   .DB  " YTOJEB", 0, 0          ; 0 1 4 7 , SIN APPS XTθn undefined
   .DB  "XSNIDA"               ; STO LN LOG x2 x-1 MATH
NormTable: ; Also copied from tutorial
   .DB  "+-*/^", $FF, $FF           ; + - × ÷ ^ CLEAR undefined
   .DB  "_369)", $C1, "]", $FF       ; (-) 3 6 9 ) TAN VARS undefined
   .DB  ".258({};"                ; . 2 5 8 ( COS PRGM STAT
   .DB  "0147, <>|", $FF            ; 0 1 4 7 , SIN APPS XTθn undefined
   .DB  $05, "!@#%&"               ; STO LN LOG x2 x-1 MATH
Looks like I'm not going to hit my goal, I've made a substantial amount of progress (got graphics as well as the movement for the left paddle working), but the logic for the ball is really tripping me up, every time I fix one bug with it, another issue seems to pop up. Been slowly working through everything (thank god for being able to step the program, I would've quit ASM weeks ago if I had to just intuit what was going wrong), but it's going to take at least a few more days until everything is worked out. Here's what I have so far:


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

.org userMem-2
.db $BB,$6D
Start:
   BCALL(_ClrLCDFull)
   BCALL(_HomeUp)
   LD HL, TitleScreenText
   BCALL(_PutS)
   BCALL(_GetKey)
   
   LD A, 40
   LD (LeftPaddleYPosition), A
   LD (RightPaddleYPosition), A
   LD A, 48
   LD (BallXPosition), A
   LD A, 32
   LD (BallYPosition), A ; Sets up initial coordinates
   LD A, 0
   LD (BallHorizontalDirection), A ; 0 = going left, 1 = going right
   LD (BallVerticalDirection), A ; 0 = going up, 1 = going down
GameLoop:
   CALL DrawPaddles
   CALL DrawBall
   BCALL(_GrBufCpy) ; Draws stuff with coordinates from last loop
   CALL DrawPaddles
   CALL DrawBall ; Clears sprites so there's no overlap when they're drawn again with new coordinates
   
   LD A, %11111110
   OUT (1), A
   NOP
   NOP
   IN A, (1)
   CP %11110111
   CALL Z, LeftPaddleUp
   CP %11111110
   CALL Z, LeftPaddleDown ; Reads key input
   
   
   
   CALL UpdateBallPosition
   LD HL, (BallOutOfBounds)
   LD A, L
   CP 1
   CALL PauseGameForDebug
   
   JR GameLoop
PauseGameForDebug:
   BCALL(_GetKey)
   RET

; Draws paddles
;--------------------------------
DrawPaddles:
   LD DE, (LeftPaddleYPosition)
   LD D, 9
   
   LD A, E
   SUB 20
   LD L, A ; Puts (E - 20) in L
   
   CALL DrawVerticalLine
   
   LD DE, (RightPaddleYPosition)
   LD D, 86
   
   LD A, E
   SUB 20
   LD L, A
   
   CALL DrawVerticalLine
   RET
;--------------------------------
; Draws ball
;--------------------------------
DrawBall:
   LD HL, (BallXPosition)
   LD A, L
   LD L, H
   CALL FetchPixel
   XOR (HL)
   LD (HL), A
   RET

LeftPaddleUp:
   LD HL, (LeftPaddleYPosition)
   DEC L
   LD A, L
   CP 19
   JR NZ, ContinueLeftPaddleUp
   LD A, 20
ContinueLeftPaddleUp:
   LD (LeftPaddleYPosition), A
   RET
LeftPaddleDown:
   LD HL, (LeftPaddleYPosition)
   INC L
   LD A, L
   CP 65
   JR NZ, ContinueLeftPaddleDown
   LD A, 64
ContinueLeftPaddleDown:
   LD (LeftPaddleYPosition), A
   RET
   
UpdateBallPosition:
   LD HL, (BallHorizontalDirection)
   LD A, H
   CP 0
   JR NZ, MoveBallRight
MoveBallLeft:
   LD HL, (BallXPosition)
   DEC H
   LD A, H
   LD (BallXPosition), A
   JR UpdateBallVerticalPosition
MoveBallRight:
   LD HL, (BallXPosition)
   INC H
   LD A, H
   LD (BallXPosition), A
UpdateBallVerticalPosition:
   LD HL, (BallVerticalDirection)
   LD A, H
   CP 0
   JR NZ, MoveBallDown
MoveBallUp:
   LD HL, (BallYPosition)
   DEC L
   LD A, L
   LD (BallYPosition), A
   JR ChangeYDirection
MoveBallDown:
   LD HL, (BallYPosition)
   INC L
   LD A, L
   LD (BallYPosition), A
ChangeYDirection:
   LD HL, (BallYPosition)
   LD A, H
   CP 1
   JR Z, FlipBallDown
   CP 63
   JR Z, FlipBallUp
FlipBallDown
   LD A, 1
   LD (BallVerticalDirection), A
   JR ChangeXDirectionLeftPaddle
FlipBallUp
   LD A, 1
   LD (BallVerticalDirection), A
ChangeXDirectionLeftPaddle
   LD HL, (BallYPosition)
   LD A, H
   CP 9
   JR NZ, ChangeXDirectionRightPaddle ; jumps to other check if not at X position 9 since it won't need to flip if it isn't touching the paddles
   LD HL, (LeftPaddleYPosition)
   LD B, 40 ; The paddle is 20 pixels long, so we'll need to check 20 times to make sure the ball isn't overlapping any of them. No need to check for X since the procedure would've alreadyexited if it didn't fit
ChangeXDirectionLeftPaddleLoop:
   CP L
   JR Z, FlipBallRight
   DEC L
   DJNZ ChangeXDirectionLeftPaddleLoop
   LD A, 1
   LD (BallOutOfBounds), A
   RET
ChangeXDirectionRightPaddle:
   LD HL, (BallYPosition)
   LD A, L
   CP 86
   RET NZ ; can exit procedure if untrue since this is the last check
   LD HL, (RightPaddleYPosition)
   LD B, 40
ChangeXDirectionRightPaddleLoop:
   CP L
   JR Z, FlipBallLeft
   DEC L
   DJNZ ChangeXDirectionRightPaddleLoop
   LD A, 1
   LD (BallOutOfBounds), A
   RET
FlipBallLeft:
   LD A, 1
   LD (BallHorizontalDirection), A
   RET
FlipBallRight:
   LD A, 0
   LD (BallHorizontalDirection), A
   RET
   
   

   
DrawVerticalLine: ; Draws vertical line, column from D, Y1 from E, Y2 from L
   LD A, E
   SUB L
   RET Z
   PUSH AF ; A is storing the length of the line, E needs to be a higher value than L
   LD A, D
   CALL FetchPixel
   POP BC ; Puts A into B, which lets the DJNZ loop draw the right amount of pixels
   LD DE, 12 ; There are 12 bytes in each row, so adding 12 each time means pixels will always be drawn in the same column
   LD C, A
DrawVerticalLineLoop:
   LD A, C
   XOR (HL)
   LD (HL), A
   ADD HL, DE
   DJNZ DrawVerticalLineLoop
   RET
   
FetchPixel: ; Takes Y in L and X in A - Returns address in HL and a bitmask in A
    LD  H, 0
    LD  D, H
    LD  E, L
    ADD HL, HL
    ADD HL, DE
    ADD HL, HL
    ADD HL, HL
    LD  E, A
    SRL E
    SRL E
    SRL E
    ADD HL, DE
    LD  DE, PlotSScreen
    ADD HL, DE
   AND 7
   LD B, A
   LD A, $80
    RET Z
FetchPixelLoop:
    RRCA
    DJNZ FetchPixelLoop
    RET
   
LeftPaddleYPosition:
   .EQU AppData ; 1 byte
RightPaddleYPosition:
   .EQU AppData + 1 ; 1 byte
BallXPosition:
   .EQU AppData + 2 ; 1 byte
BallYPosition:
   .EQU AppData + 3 ; 1 byte
BallHorizontalDirection:; Vertical direction
   .EQU AppData + 4 ; 1 byte
BallVerticalDirection: ; Horizontal direction
   .EQU AppData + 5 ; 1 byte
BallOutOfBounds:
   .EQU AppData + 6 ; 1 byte
TitleScreenText:
   .DB "      PONG      "
   .DB "BY: JOHN CAMOU  "
   .DB "PRESS ANY BUTTON",0
I've finally finished Pong, getting the ball to work was really annoying and I had to rewrite that whole section, but after that it was mostly smooth sailing. I'd say about 70% of the source code is my own work compared to 30% I copy / pasted from tutorials (eg: the "FetchPixel" and "RandomNumberGenerator" procedures). My ultimate assembly goal is to make a full-fledged RPG for the 83+, but this project taught me that I still have quite a while until I'll be good enough to tackle that. My code is below, and I'd really appreciate any feedback since it's a bit of a mess.


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

.org userMem-2
.db $BB,$6D
Start:
   LD (RandData), DE
   BCALL(_ClrLCDFull)
   BCALL(_HomeUp)
   LD HL, TitleScreenText
   BCALL(_PutS)
   BCALL(_GetKey)
   LD A, 0
   LD (LeftPaddleScore), A
   LD (RightPaddleScore), A ; Sets up intial values
   

SetUpGame:
   LD A, 40
   LD (LeftPaddleYPosition), A
   LD (RightPaddleYPosition), A
   LD A, 48
   LD (BallXPosition), A
   LD A, 32
   LD (BallYPosition), A ; Sets up intial coordinates
   LD A, 0
   LD (BallHorizontalDirection), A ; 0 = going left, 1 = going right
   LD (BallVerticalDirection), A ; 0 = going up, 1 = going down
   LD (BallOutOfBounds), A ; Sets up values for start of game state
   
   BCALL(_ClrLCDFull)
   CALL DrawPaddles
   CALL DrawBall
   BCALL(_GrBufCpy)
   LD A, 0
   LD (CurRow), A
   LD A, 0
   LD (CurCol), A
   LD HL, PromptText
   BCALL(_PutS)
   
   LD A, (LeftPaddleScore)
   CP 0
   JR Z, ZeroLeftPaddle
   CP 1
   JR Z, OneLeftPaddle
   CP 2
   JR Z, TwoLeftPaddle
   CP 3
   JR Z, ThreeLeftPaddle
   CP 4
   JR Z, FourLeftPaddle
   CP 5
   JR Z, FiveLeftPaddle

ZeroLeftPaddle:
   LD A, 48
   LD (LeftPaddleScoreAscii), A
   JR ContinueAsciiConversion
OneLeftPaddle:
   LD A, 49
   LD (LeftPaddleScoreAscii), A
   JR ContinueAsciiConversion
TwoLeftPaddle:
   LD A, 50
   LD (LeftPaddleScoreAscii), A
   JR ContinueAsciiConversion
ThreeLeftPaddle:
   LD A, 51
   LD (LeftPaddleScoreAscii), A
   JR ContinueAsciiConversion
FourLeftPaddle
   LD A, 52
   LD (LeftPaddleScoreAscii), A
   JR ContinueAsciiConversion
FiveLeftPaddle:
   LD A, 53
   LD (LeftPaddleScoreAscii), A
ContinueAsciiConversion:
   LD A, (RightPaddleScore)
   CP 0
   JR Z, ZeroRightPaddle
   CP 1
   JR Z, OneRightPaddle
   CP 2
   JR Z, TwoRightPaddle
   CP 3
   JR Z, ThreeRightPaddle
   CP 4
   JR Z, FourRightPaddle
   CP 5
   JR Z, FiveRightPaddle
ZeroRightPaddle:
   LD A, 48
   LD (RightPaddleScoreAscii), A
   JR ContinueSetupGame
OneRightPaddle:
   LD A, 49
   LD (RightPaddleScoreAscii), A
   JR ContinueSetupGame
TwoRightPaddle:
   LD A, 50
   LD (RightPaddleScoreAscii), A
   JR ContinueSetupGame
ThreeRightPaddle:
   LD A, 51
   LD (RightPaddleScoreAscii), A
   JR ContinueSetupGame
FourRightPaddle
   LD A, 52
   LD (RightPaddleScoreAscii), A
   JR ContinueSetupGame
FiveRightPaddle:
   LD A, 53
   LD (RightPaddleScoreAscii), A ; Super inefficient but it gets the job done and idk how to write a decimal-to-ASCII algorithm
ContinueSetupGame:
   LD A, 3
   LD (CurCol), A
   LD A, 3
   LD (CurRow), A
   LD A, (LeftPaddleScoreAscii)
   BCALL(_PutC)
   LD A, 12
   LD (CurCol), A
   LD A, (RightPaddleScoreAscii)
   BCALL(_PutC)


   BCALL(_GetKey)
   CALL DrawPaddles
   CALL DrawBall

   
GameLoop:
   CALL DrawPaddles
   CALL DrawBall
   BCALL(_GrBufCpy) ; Draws stuff with coordinates from last loop
   CALL DrawPaddles
   CALL DrawBall ; Clears sprites so there's no overlap when they're drawn again with new coordinates
   
   LD A, %11111110
   OUT (1), A
   NOP
   NOP
   IN A, (1)
   CP %11110111
   CALL Z, LeftPaddleUp
   CP %11111110
   CALL Z, LeftPaddleDown ; Reads key input
   
   
   
   CALL UpdateBallPosition
   CALL UpdateRightPaddlePosition
   
   LD A, (BallOutOfBounds)
   CP 1
   JR Z, ChangeScore
   JR GameLoop

ChangeScore:
   LD A, (BallXPosition)
   CP 86
   JR Z, LeftPaddleScoreUp
RightPaddleScoreUp:
   LD A, (RightPaddleScore)
   INC A
   LD (RightPaddleScore), A
   CP 6
   JP Z, EndGameRightPaddleWon
   JP SetupGame
LeftPaddleScoreUp:
   LD A, (LeftPaddleScore)
   INC A
   LD (LeftPaddleScore), A
   CP 6
   JP Z, EndGameLeftPaddleWon
   JP SetupGame
   
;Handles updating the right paddle's position
;--------------------------------
UpdateRightPaddlePosition:
   CALL RandomNumberGenerator
   CP 175
   JR NC, WrongChoice
   LD A, (BallVerticalDirection)
   CP 0
   JR Z, MoveRightPaddleUp
   CP 1
   JR Z, MoveRightPaddleDown
MoveRightPaddleUp:
   LD HL, (RightPaddleYPosition)
   DEC L
   LD A, L
   CP 14
   JR NZ, ContinueRightPaddleUp
   LD A, 15
ContinueRightPaddleUp:
   LD (RightPaddleYPosition), A
   RET
MoveRightPaddleDown:
   LD HL, (RightPaddleYPosition)
   INC L
   LD A, L
   CP 65
   JR NZ, ContinueRightPaddleDown
   LD A, 64
ContinueRightPaddleDown:
   LD (RightPaddleYPosition), A
   RET
WrongChoice:
   LD A, (BallVerticalDirection)
   CP 0
   JR Z, MoveRightPaddleDown
   CP 1
   JR Z, MoveRightPaddleUp
;--------------------------------
;Handles updating the ball's position - WORKING
;--------------------------------
UpdateBallPosition:
UpdateBallHorizontalPosition:
   LD A, (BallHorizontalDirection)
   CP 1
   JR Z, MoveBallRight
MoveBallLeft:
   LD A, (BallXPosition)
   DEC A
   LD (BallXPosition), A
   JR UpdateBallVerticalPosition
MoveBallRight:
   LD A, (BallXPosition)
   INC A
   LD (BallXPosition), A
UpdateBallVerticalPosition
   LD A, (BallVerticalDirection)
   CP 1
   JR Z, MoveBallDown
MoveBallUp:
   LD A, (BallYPosition)
   DEC A
   LD (BallYPosition), A
   JR CheckVerticalFlip
MoveBallDown
   LD A, (BallYPosition)
   INC A
   LD (BallYPosition), A
CheckVerticalFlip:
   LD A, (BallYPosition)
   CP 1
   JR Z, FlipDown
   CP 64
   JR Z, FlipUp
   JR CheckHorizontalFlip
FlipDown:
   LD A, 1
   LD (BallVerticalDirection), A
   JR CheckHorizontalFlip
FlipUp:
   LD A, 0
   LD (BallVerticalDirection), A

CheckHorizontalFlip:
   LD A, (BallXPosition)
   CP 9
   JR Z, CheckIfLeftPaddleIsColliding
   CP 86
   JR Z, CheckIfRightPaddleIsColliding
   RET
CheckIfLeftPaddleIsColliding:
   LD A, (BallYPosition)
   LD HL, (LeftPaddleYPosition)
   LD B, 15 ; The paddles are 20px wide, so we'll need to loop 15 times to check all of them
CheckIfLeftPaddleIsCollidingLoop:
   CP L
   JR Z, FlipRight
   DEC L
   DJNZ CheckIfLeftPaddleIsCollidingLoop
   LD A, 1
   LD (BallOutOfBounds), A
   RET
FlipRight:
   LD A, 1
   LD (BallHorizontalDirection), A
   RET
CheckIfRightPaddleIsColliding:
   LD A, (BallYPosition)
   LD HL, (RightPaddleYPosition)
   LD B, 15 ; The paddles are 15px wide, so we'll need to loop 20 times to check all of them
CheckIfRightPaddleIsCollidingLoop:
   CP L
   JR Z, FlipLeft
   DEC L
   DJNZ CheckIfRightPaddleIsCollidingLoop
   LD A, 1
   LD (BallOutOfBounds), A
   RET
FlipLeft:
   LD A, 0
   LD (BallHorizontalDirection), A
   RET
;--------------------------------


; Draws paddles - WORKING
;--------------------------------
DrawPaddles:
   LD DE, (LeftPaddleYPosition)
   LD D, 9
   
   LD A, E
   SUB 15
   LD L, A ; Puts (E - 15) in L
   
   CALL DrawVerticalLine
   
   LD DE, (RightPaddleYPosition)
   LD D, 86
   
   LD A, E
   SUB 15
   LD L, A
   
   CALL DrawVerticalLine
   RET
;--------------------------------
; Draws ball - WORKING
;--------------------------------
DrawBall:
   LD HL, (BallXPosition)
   LD A, L
   LD L, H
   CALL FetchPixel
   XOR (HL)
   LD (HL), A
   RET
;--------------------------------
;Handles left paddle movement - WORKING
;--------------------------------
LeftPaddleUp:
   LD HL, (LeftPaddleYPosition)
   DEC L
   LD A, L
   CP 14
   JR NZ, ContinueLeftPaddleUp
   LD A, 15
ContinueLeftPaddleUp:
   LD (LeftPaddleYPosition), A
   RET
LeftPaddleDown:
   LD HL, (LeftPaddleYPosition)
   INC L
   LD A, L
   CP 65
   JR NZ, ContinueLeftPaddleDown
   LD A, 64
ContinueLeftPaddleDown:
   LD (LeftPaddleYPosition), A
   RET
;--------------------------------
   
   
EndGameLeftPaddleWon:
   BCALL(_ClrLCDFull)
   BCALL(_HomeUp)
   LD HL, LeftPaddleWonText
   BCALL(_PutS)
   RET
EndGameRightPaddleWon:
   BCALL(_ClrLCDFull)
   BCALL(_HomeUp)
   LD HL, RightPaddleWonText
   BCALL(_PutS)
   RET
   

;Handles rendering - WORKING
;--------------------------------
DrawVerticalLine: ; Draws vertical line, column from D, Y1 from E, Y2 from L
   LD A, E
   SUB L
   RET Z
   PUSH AF ; A is storing the length of the line, E needs to be a higher value than L
   LD A, D
   CALL FetchPixel
   POP BC ; Puts A into B, which lets the DJNZ loop draw the right amount of pixels
   LD DE, 12 ; There are 12 bytes in each row, so adding 12 each time means pixels will always be drawn in the same column
   LD C, A
DrawVerticalLineLoop:
   LD A, C
   XOR (HL)
   LD (HL), A
   ADD HL, DE
   DJNZ DrawVerticalLineLoop
   RET
FetchPixel: ; Takes Y in L and X in A - Returns address in HL and a bitmask in A
    LD  H, 0
    LD  D, H
    LD  E, L
    ADD HL, HL
    ADD HL, DE
    ADD HL, HL
    ADD HL, HL
    LD  E, A
    SRL E
    SRL E
    SRL E
    ADD HL, DE
    LD  DE, PlotSScreen
    ADD HL, DE
   AND 7
   LD B, A
   LD A, $80
    RET Z
FetchPixelLoop:
    RRCA
    DJNZ FetchPixelLoop
    RET
;--------------------------------
RandomNumberGenerator: ; Copy & pasted from WikiTI
    PUSH HL
    PUSH DE
    LD DE,(randData)
    LD A, R
    LD D, A
    LD E, (HL)
    ADD HL, DE
    ADD A, L
    XOR H
    LD (randData), HL
    POP DE
    POP HL
    RET

;Data
;--------------------------------
LeftPaddleYPosition:
   .EQU AppData ; 1 byte
RightPaddleYPosition:
   .EQU AppData + 1 ; 1 byte
BallXPosition:
   .EQU AppData + 2 ; 1 byte
BallYPosition:
   .EQU AppData + 3 ; 1 byte
BallHorizontalDirection:; Vertical direction
   .EQU AppData + 4 ; 1 byte
BallVerticalDirection: ; Horizontal direction
   .EQU AppData + 5 ; 1 byte
BallOutOfBounds:
   .EQU AppData + 6 ; 1 byte
LeftPaddleScore:
   .EQU AppData + 7 ; 1 byte
RightPaddleScore:
   .EQU AppData + 8 ; 1 byte
LeftPaddleScoreAscii:
   .EQU AppData + 9 ; 1 byte
RightPaddleScoreAscii:
   .EQU AppData + 10 ; 1 byte
RandData:
   .EQU AppData + 11 ; 2 bytes
TitleScreenText:
   .DB "      PONG      "
   .DB "BY: JOHN CAMOU  "
   .DB "PRESS ANY BUTTON",0
PromptText:
   .DB "PRESS ANY       "
   .DB "        TO START",0
LeftPaddleWonText:
   .DB "LEFT        WINS",0
RightPaddleWonText:
   .DB "RIGHT       WINS",0
  
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