; Sean Smith ; AFROsoft Programming Division ; ; AFROAGE: 2 years and still growing ; AFROSIZE: Easily past 11 Inches ; DATE: Saturday, 09 September, 2000 17:14:06 ; PRGM PURPOSE: Present a simple pong game, with ample comments ; TYPE: Game/Tutorial ; Covers Direct Input ; Goes over GameFlow process ; GAME LEVEL: New players, to Pong Experts ; SOURCE TUTORIAL: People who grasp simple register usage ; People who can already write text to the screen ; People who want a simple game to look at. #include "ti86asm.inc" .org _asm_exec_ram nop jp ProgStart .dw 0 .dw ShellTitle ShellTitle: .db "AFROSoft BounceBalls",0 ProgStart: call 4AB1h ; turn off the run indic. call _clrLCD ; clear the LCD screen xor a ; sets a to zero, faster and smaller than ; ld a,0 ld (score),a ; set our score to zero ld (_penRow), a ; because a is still zero... ld (_penCol), a ; we are using it to set the row and column ld hl,Intro ; loads the information at the label Intro into hl call _vputs ; calls _vputs, displays the info in hl at _penRow, _penCol TitleScreen: ; our "get-how-hard-we-want-it loop" ld a,%10111111 ; we are using direct input. Bit 6 is set so we can ; check for the menu keys (the FKeys) out (1),a ; send our quere to the port in a,(1) ; read our quere from the port cp %10111111,a ; did the exit key get pressed? jp z,ExitMe ; if so, we jump to the end. cp %11101111,a ; did the F1 key get pressed? jp z,F1 ; if so, we jump to the label F1 cp %11110111,a ; ditto, with F2 jp z,F2 ; ditto, with F2 cp %11111011,a ; ditto, with F3 jp z,F3 ; ditto, with F3 cp %11111101,a ; ditto, with F4 jp z,F4 ; ditto, with F4 cp %11111110 ; ditto, with F5 jp z,F5 ; ditto, with F5 jp nz,TitleScreen ; If none of the desired keys were pressed, we ; jump back to the top of our loop. F1: ld a,55 ; Hard is the value we use to set how hard ld (Hard),a ; the game is. What it actually is, is the jp Start ; value that is used in a loop later to set ; how fast the game goes. F2: ld a,40 ; because we cannot directly load 40 into (Hard), ld (Hard),a ; we 'indirectly' give it that value, by loading jp Start ; 40 into the a register, then the a register ; into (Hard). F3: ld a,25 ; Person A: Knock knock ld (Hard),a ; jp Start ; Person B: Who's there? F4: ld a,10 ; Person A: Tanya Harding ld (Hard),a ; jp Start ; Person B: Tanya Harding W.. F5: ld a,5 ; Person A interrupts, and hits Person ld (Hard),a ; B in the back of the leg with a steel jp Start ; pipe :) Start: ; Begin out main loop ; ; Here, we will be doing the normal stuff ; that a game does. ; ; a. get input from the user ; b. store input from the user ; c. calculate game data (e.x a ball moving) ; d. evaluate game data ; e. draw graphics ; f. check to see if the game is over. ;Ball Setup ld a,2 ; ballX is a value used to keep track of the pong ld (ballX),a ; ball's X coordinate ld a,10 ld (ballY),a ; ballY obviously holds the ball's Y coord. ld a,(ballX) ; we are loading 2 temporary values here: the balls ld (tmpX),a ; x and y values. We do this, because we will need to ld a,(ballY) ; erase the old ball later, and put a new one at a ld (tmpY),a ; different location on the screen. ; In pong games, the ball can move in 4 directions: ; up and left, up and right ; down and left, down and right ; ; we use the values ballUD and ballLR to keep track of ; witch direction the ball is moving ; I am making it so that: the ball starts out going in ; a specific direction (up and left). Some people would ; randomize the values here. Fell free to skip this next ; area. ; randomize code: uncomment the next lines, and delete from ; [ld a,1] to [ld (ballLR),a] ;--------------------------------------------------------------------------------; ;--------------------------------------------------------------------------------; ; ; call _random ; generates a random number (either 0 or 1) and stores it ; ; in the special memory crap area called op1. ; ; call _convop1 ; converts an integral value out of op1. it stores it in the ; ; 24 bit-ish register AHL. because our number is only going ; ; to be 1 or 0, then the registers A and H can be disregarded. ; ; l has our random number... I hope :) ; ; ld a,l ; now the register a has our random number. ; ld (ballUD),a ; ; call _random ; i'm sure there is a more efficent way of doing this... ; call _convop1 ; but who cares, its my code! muahahaahaha! ; ; ld a,l ; ld (ballLR),a ; ; ; I hope this works, you know I'm not going to take the time ; ; to see if it actually compiles. gya hah. huzzah! ; ;--------------------------------------------------------------------------------; ;--------------------------------------------------------------------------------; ; back to our normal program ld a,1 ; if ballUD has the value of 0, the ball is moving up ld (ballUD),a ; so, if ballUD has the value of 1, the ball is moving down xor a ; again, remember than any number xor'd itself = zero ld (ballLR),a ; if ballLR has 0, we move the ball left. Obviously then, if ; ballLR has the value of 1, we move the ball right. ld a,2 ; _curRow and _curCol are both equated in the header file. ld (_curRow),a ; they set where text goes when using the call _puts, _putc, ld a,10 ; or _putps. remember, these 'take' whats in hl, and displays ld (_curCol),a ; them in a fixed width font on the home screen. ld hl, ball ; note that ball is a null terminated (,0) string at the bottom call _puts ; puts our ball at (2, 10). ; End Ball Setup ; Paddle Setup ld a,7 ; we are practicly doing the same thing as we did up above ld (padX),a ; padX and padY are the X and Y coords of our paddle. ld a,4 ; we are just loading their values up for later, when we want ld (padY),a ; to move our paddle around ld a, (padX) ; If you couldnt figure it out, this part is loading up ld (tmpPadX),a ; our temp paddle values. When we finally decide to move the ld a, (padY) ; paddle around, we will want to clear where it was last. ld (tmpPadY),a ld a,7 ; I hate boy's who sing 'bout krombie n fitch... ld (_curRow),a ; their music really makes me sick ld a,4 ; and I think it's lame when they sing about the summer time... ld (_curCol),a ; the summer time... ld hl, Pad ; Pad is our paddle. call _puts ; put that baby down ; End Paddle Setup call _getkey ; we have this call here to just sit around and wait for a ; keypress, so our user won't be startled by the beginning ; of the game. ; at this point in the program, we have a screen that looks ; like this: ; +-------------------------------------------+ ; |BounceBall! F1=Easy ... F5=Diffucult| (small text) ; | _ | ; | (_) | ; | | ; | | ; | | ; | | ; | -======- | ; +-------------------------------------------+ ; ; pretty cheezy, eh? ; getKeyPress: ; Here we go, more direct input. I didn't go into too much detail ; earlier, because I didn't feel like it. Here we go: ; ; dInput is the best way to get keypresses. Its faster than _getky and ; _getkey. It also can be nicer on the batteries. we use dInput ; by accessing the ports on the ti-86. Thanks Assembley Studio 86, for ; this wonderful chart: ; ; 7 6 5 4 3 2 1 0 ; 6 MORE EXIT 2nd F1 F2 F3 F4 F5 ; 5 ALPHA GRAPH LOG LN x² , STO &&&&& ; 4 x-VAR TABLE SIN EE 7 4 1 0 ; 3 DEL PRGM COS ( 8 5 2 . ; 2 &&&&& CUSTOM TAN ) 9 6 3 (-) ; 1 &&&&& CLEAR ^ ÷ × - + ENTER ; 0 &&&&& &&&&& &&&&& &&&&& UP RIGHT LEFT DOWN ; ; note: &&&&& means that there is no key occupied by that section ; ; to use dInput, first we decide what row(s) we want to use. We pick ; the row number, turn off the corresponding bit in the number %11111111 ; and send it to port 1. ; ; e.x. I want to read in row 5, witch has alpha, graph, log, ln, ect... ; so i set the 5th bit in the number to %1111111 to zero (if you don't ; know, the bytes are in this order %76543210), witch would be %11011111. ; ; I would load up %11011111 into the register a, then send it out to the ; port. when I read in from that port, a will be magicly changed, based on ; what key is pressed. when we read in from the port, and the alpha key ; is pressed, then a will read %01111111 !!! Look at alpha on our chart. ; it is in column 7! so the 7th bit is turned off! wow. ; ld a,%10111110 ; We have here bit 0 and bit 6 set. We can do this because, if you look, ; there are empty spots in the bit 0 row. to be precise, column 7-4 ; have no key set to them. So, we can activate another row (in this case ; row 6, because it has a key we want that lays between column 7-4 (the ; exit key, witch is in column 6.) out (1),a ; send our quere (our rows to look at) to the port in a,(1) ; read our quere (what key(s) are being pressed) from the port ; because we merged two rows (because the 0 row has open spaces, ; we now have a new column, that looks like this: ;---------------------------------------------------------------- ; part of row 6 | part of row 0 ;---------------------------------------------------------------- ; 7 6 5 4 | 3 2 1 0 ; MORE EXIT 2nd F1 | UP RIGHT LEFT DOWN ;---------------------------------------------------------------- ;---------------------------------------------------------------- ; a has the value of the key being pressed, because we used in a,(1). ; so, we can use the cp statment to see what key is being pressed. ; ; If you want to really be elite, you could use the bit statment. ; e.x. ; bit 6 ; jp z,exitWasJustPressed ; cp %10111111,a ; was the exit key pressed? jp z,ExitMe ; then we quit out of the game. cp %11111011,a ; was the right key pressed? jp z,kpRight ; then we jump to the right key pressed label cp %11111101,a ; was the left key pressed? jp z,kpLeft ; then we stick our left side in, we stick our left side out... jp nz,BallStuff ; no keys were pressed (nz) OR keys were pressed, and now we are ready ; to move the ball around. kpLeft: ; this area handles the movement of the paddle ; the user pressed left to come here. ld a,(padY) ; we load up the last stored Y coord of the paddle into a cp 0 ; is our paddle at the rightmost side? (shaddup oldskoo progr's. ; everyone OLD knows that there are better ways to do cp 0. Let the ; new coder get jiggy with cp 0. Yea yea, I know I used xor a ;p) jp z,LeftStuff ; if our paddle was at the leftmost side, then dont move it left ; any more. dec a ; our paddle isn't at 0, so we can move it left more. so we dec ld (padY),a ; it's Y value, and reload it into padY LeftStuff: jp BallStuff ; Ok. we are here because either: ; a. the left value changed, or ; b. it didn't ; ; in either case, we now go do stuff with the ball. So ; we jump to BallStuff kpRight: ; the exact same as above, yet the user pressed right. ld a,(padY) ; load up the Y value ; If you believe cp 14 ; check if it is too far ; the western sun jp z,RightStuff ; if so, dont increase it ; is falling down ; ; on everyone... inc a ; if not, increase Y and ; ld (padY),a ; store it back in padY ; FOTL, NARRYAN, 1997 RightStuff: jp BallStuff ; Ok. we are here because either: ; a. the right value changed, or ; b. it didn't ; ; in either case, we now go do stuff with the ball. So ; we jump to BallStuff BallStuff: ; whooho, we finally get to move the ball around! yah. ; Just to give you a rundown at this point of what we have done: ; ; We have set up our game screen ; We set up the values needed for our game ; We have taken in user input ; We have evaluated user input, and stored values. ; ; hmm, what else do we have to do? Hint, hint: ; ; c. calculate game data (e.x a ball moving) ; d. evaluate game data (collision detection) ; e. draw graphics (paddle and bal) ; f. check to see if the game is over. (duh) ; remember way back when, at the beginning of the game, we had the ; user press a F1-F5 key? What did that do again? I did tell you. ; Begin Speed Control ; We will be using hard to calculate how fast our game goes. ld a,(Hard) ; load a up with our hard value. note that it was a number ;p ld b,a ; load a into b, or effectivly loading (Hard) into b. loop: ; begin a loop halt ; this command halts the cpu for a moment. djnz loop ; Decrement B, and jump if not zero. it basicly does this ; ; End Speed Control ; e.x. ; ; B = 10 ; LOOP: ; HALT ; B := B - 1 ; If B is not equal to 0 then go back to LOOP ; If B is equal to 0 then exit LOOP ld a,(ballX) ; we need to backup the X and Y values of the ball, so ld (tmpX),a ; we can erase them later, once we have NEW X and Y values. ld a,(ballY) ld (tmpY),a ;update the ball here, no matter if they press a key or not ld a, (ballUD) ; load a with the ball up/down direction value cp 0 ; is the ball moving up? jp nz, balldown ; if not, the it has to be moving down. Jump to ball down area ballup: ; we are here because the ball is moving up, and we need to make ; sure that it doesn't go too far up. ld a, (ballX) ; our ball's x value. cp 1 ; is the ball at the top of the screen? jp z, nosubX ; If so, don't decrease its X value. Because it's at the top, we need ; to bounce it off the ceiling, and reset it's flag, to tell it to ; go down. ; because we didn't jump, that means that the ball can be moved up. ld a,(ballX) ; load up the ball's X value sub 1 ; Obviously, decrease the distance from the top (the X value.) ld (ballX),a ; re-store the ball's X value jp leftRight ; because we sucessfully moved the ball up at this point, we need ; to decide if we move the ball left or right. nosubX: ; we jumped here because the ball is at the top of the screen, and we ; need to tell it to bounce, and go the other way. this is simply done ; by changing the value of ballUD (remember, ballUD tells the ball ; witch direction it needs to go!) ; remember, if ballUD has 0 in it, go up. If it has 1, go down. ld a,1 ; load a with 1, because we want to move the ball up. ld (ballUD),a ; store the value of a into the up down direction flag. ld a,(ballX) ; get the ball's X value add a,1 ; we add 1 to it, because the ball is going down, not up ld (ballX),a ; save our balls new X value jp leftRight ; the ball is going the right way up and dow now, so we need to jump ; to the area that handles left and right motion balldown: ; we are here because the ballUD flag told us that the ball was moving ; down, and not up. So, we need to see if: The ball is at the bottom. ; if it is not, we need to add one to the ball's X value. If it is ; then we need to do three important things. ; ; check to see if the ball hit the paddle ; if not, game over d00d! ; if so, we need to increase their score! ld a, (ballX) ; load a with the ball's X value cp 6 ; is the ball at the bottom of the screen? jp z, noaddX ; If it is, jump to noaddX, and check if we need to either add points ; or call a game over. ; ; if it isn't, we can safely move the ball down a bit. ;ball not at the bottom of the screen ld a,(ballX) ; the balls x value add a,1 ; increase it (witch will move it down a square) ld (ballX),a ; resave the ball's X value jp leftRight ; ok, we sucessfully changed its up/down motion, now we need to ; do something about the left and right motion. ;end ball not... noaddX: ; the ball is at the bottom of the screen, so dont add to the x val. ; We need to check if it comes in contact with the paddle. ; if it does, bounce ball (reset the up/down flag, add to the score, ; and check for left/right motion). If it does not come in contact with ; the paddle, then its game over for the user. We jump to the end, and ; tell them their score. ; We know the ball's X value, because it is right above the paddle. ; now we need to see if if: ; [pad's left side] <= [ball] <= [pad's right side] ld a, (ballY) ; load the ball's Y value, to check it. ld c,a ; load a into c, effectively moving (ballY into c) ld a, (padY) ; load the paddle's Y value into a, so we can do a compare between them cp c ; we are comparing the ball to the pad now. jp m, next1 ; if the ball's Y value is greater than the pad, go to next step jp z, next1 ; if the ball's Y value is equal to the pad, go to the next step jp p, ExitMe ; if the ball's Y value is less than the pad's, go to the end. jp nz, ExitMe ; just in case, if we get this far, lets go to the end anyway next1: ; at this point, we know that the ball is at least ; ; [pad's left side] <= [ball]. ; ; we check to see if: ; ; [ball] <= [pad's right side] add a,4 ; the paddle is 5 'squares' long. a has the location of the first ; square, so we add 4 to account for the rest of the paddle. cp c ; again, compare the ball's Y value to the paddle jp z, bounceup ; ok. returned zero, so that means the ball hit the right side, thus ; meeting the condition of [pL] <= [B] <=[pR] jp p, bounceup ; ok. returned a positive number. that means the ball's Y value is less ; than the right side's Y value, thus meeting the condition of ; [pL] <= [B] <=[pR] jp m, ExitMe ; it didn't meet any of the conditions, so we are outta here! bounceup: ; Ok, we are here because we jumped here. We jumped here because ; the ball met the conditions needed to bouce back up. Since it hit ; the paddle, we need to make it go flying back out, increase the users ; score, and go on to show the ball and the paddle. xor a ; a=0 ld (ballUD),a ; put 0 into the Ball Up Down Flag, witch directs us to move the ball ; up (U=0, D=1) next time around. ld a,(score) ; open up our score. add a,1 ; add a point ld (score),a ; store the score. jp showball ; go update all the graphics. leftRight: ; We are here because the ball sucessfully moved either up a space, or ; down a space. Because the ball must move either left or right also, we ; now go check to see what way the ball will go. ld a, (ballLR) ; load the "ball-goes-left-or-right flag value into a" cp 0 ; 0=left, 1 = right. is the ball going left? jp nz, ballright ; if nz, that means the ball is going right. ballLeft: ; time to move the ball left, unless it is next to the wall. in that ; case, we need to reset its left-right directional flag, so it will ; move right next time around. ld a, (ballY) ; load the ball's Y value into a. cp 1 ; is the ball at the left of the screen? jp z, nosubY ; if so, jump to nosubY. if not, move it left. ; the ball is not at the left of the screen ; we need to move the ball left a space. ; ball left mover ld a,(ballY) ; load the ball's Y value AGAIN sub 1 ; decrease it by one, to move it left ld (ballY),a ; save the Y value AGAIN jp showball ; ok, we have sucessfully moved it either up and left, or down ; and left. its time to show that. So we jump to showball. ;end ball left mover nosubY: ; the ball is at the left of the screen ; so we need to reset the left-right flag ; to move the ball right next cycle ld a,1 ; load the right flag value(0=L, 1=R) ld (ballLR),a ; set the right motion flag. jp showball ; we have sucessfully moved up or down, and bounced off the left wall. ; because we are now moving right, we need to show that. Lets go update ; the screen. ballright: ; we jumped here because the ballLR flag was set to 1. So, we need to ; check the ball's Y position, see if it is too far right, if so, then ; reset the flag to make it bounce. If not, then we increase the Y val. ld a, (ballY) ; monkies always look cp 18 ; is the ball at the far right of the screen? jp z, noaddY ; jump if it is. go on if it isn't. ; the ball is not at the bottom of the screen ; we need to move the ball down a space. ; ball right mover ld a,(ballY) ; apes always say it. add a,1 ; increase the Y value ld (ballY),a ; re-store the Y value from a jp showball ; ok, so we have sucessfully moved up or down, and moved it right. ; now it is time for us to update the graphics ; end ball right mover noaddY: ; we jumped here because the ball is at the right of the screen ; and needs to be bounced off the wall. So, lets reset that flag! xor a ; a=0 ld (ballLR),a ; we set the ballLR directional flag with 0, because we are bouncing ; it off the right wall, and it needs to go left now. L=0. R=1 jp showball ; Ok, so we have either moved up or down sucessfully, and also bounced ; off the right wall. now we need to update the graphics. showball: ; WHOOHOO! we are amost done! Well, When I say We, I mean me. By the way ; Do you know what I hate about school? It's the smell! ;p ; ; Ok, we have come far. Lets look at our original todo list. ; ; CHECK a. get input from the user ; CHECK b. store input from the user ; CHECK c. calculate game data (e.x a ball moving) ; CHECK d. evaluate game data ; BZZZZ e. draw graphics ; CHECK f. check to see if the game is over. ; ; what do we have left to do in our game loop? I'm sorry, the correct ; answer is letter E. We have done all of these calculations, all this ; bounds checking, and quite frankly, It is time to give the user some ; eye candy. Here's the easy part. All we need to do is show a few ; graphics, based on the values we recieved earlier. What values, you ; ask? Well, all we need to show is: the pad w/ its x and y vals, and ; the ball with it's x and y vals. Along with this, we need to use ; the temp x and y vals we have accumulated so far to erase anything old ; clearing ball ld a,(tmpX) ; load up the ball's old X value ld (_curRow),a ; load that x value into curRow ld a,(tmpY) ; load up the ball's old Y value ld (_curCol),a ; they're magically delicious, but I like 'em too ld hl, blnk ; load hl with the stuff at blnk (blank ball) call _puts ; clear that old ball! ; end clearing ball. ; new ball ; we have the old gone, so bring in the new stuff. ld a,(ballX) ; load up the most recent X value ld (_curRow),a ; put it into the row ld a,(ballY) ; load up the most recent Y value ld (_curCol),a ; put it into the col ld hl, ball ; load the new ball call _puts ; show the new ball ;end new ball ;copy ball current to temp ; next time around, we will have a new x and y, so we will want ; to clear the old one. ld a,(ballX) ; load the current X into a ld (tmpX),a ; ... into temporary ld a,(ballY) ; load the current Y into a ld (tmpY),a ; ... into temporary ;end copy current ball to tmp ; clearing pad ; just like with the ball, we clear the old paddle ld a,(tmpPadX) ; By now, I hope that you have figured out that padX never changes ld (_curRow),a ; but we still have it there, just in case I change the game. ld a,(tmpPadY) ; If I wanted to free some space up, I could always remove it. sub 1 ; for our blank pad ld (_curCol),a ; but space isn't my first issue here. ld hl, Padblnk call _puts ; end clearing pad ; load new pad ; noting new, nothing special ld a,(padY) ; same old, same old ld (_curCol),a ; exactly the same as above ld a,(padX) ; so why don't I add some ansi art? ld (_curRow),a ; or is it ascii? ld hl, Pad ; _,_ call _puts ; <^> <{';'}> <^> S U P E R ; end load new pad ; \\__,/\/\,__// A S M ; copy current pad to temp..; '---|S|---' M A N ld a, (padY) ; /' '\ ld (tmpPadY),a ; / /-\ \ or... Sam USA, Per. MN ld a, (padX) ; _/ /---\ \_ (Wait, I don't live in Per, MN. Oh well.) ld (tmpPadX),a ; |__/ \__| how about Samper Us, man! ; end copy current pad to temp pad (possibly holding your tounge, while saying ; sample us, man!) jp getKeyPress ; Its time to lather, rinse, and repeat, until either the user ; presses the exit key, or the user screws up and drops the ball. ExitMe: ; We jumped here because either our user sucks at pong, or ; they got tired of the cheezy graphics. At any rate, we need ; to print out their high score, give some props to me, and get out. call _clrScrn ; not only clears the screen, but cleans in those hard to reach call _clrLCD ; places. printscores: ; We want the user to know how much they suc... I mean rule, so here ; is where we can do that. xor a ; curRow, curCol, both at 0. ld (_curRow), a ld (_curCol), a ld hl, gmvr ; load up the gameover message. call _puts ; print that bad boy out. ld a,2 ; next up is... ld (_curRow), a ; the you scored message xor a ; xor a = ld a,0 ld (_curCol), a ; foo ld hl,msg ; "Your score is: " call _puts ; send out that mean sucka. ld hl,0000h ; We are clearing the 16 bit register pair, so we can get ; the score, and print it out. ld a, (score) ; We load the score into a. ld l,a ; we move it into l, or the lower half of the 16 bit register ; hl xor a ;load 0 into a, for next thing... call _dispAHL ; _dispAHL displays the value of the 24 bit register, AHL. It puts ; it on the screen, and advances the cursor. When using this, we ; need to make sure that the values we have are the values we want. ; for instance, any values in the a register, h register, or l ; register will affect output. So, here is what we have done ; (lets say our score is 5.) ; AHL: %????????,????????,???????? = ? ; ld hl, 000h ; AHL: %????????,00000000,00000000 = ? ; ld a, (score) ; AHL: %00000101,00000000,00000000 = 327680, not 5 ; ld l,a ; AHL: %00000101,00000000,00000101 = 327685, not 5 ; xor a ; AHL: %00000000,00000000,00000101 = 5, BINGO! ld a,4 ; go down to row 4 ld (_curRow), a xor a ; column 0 ld (_curCol), a ld hl,me ; load hl with my name call _puts ; give me maddd props ld a,5 ; next row ld (_curRow), a xor a ; same column ld (_curCol), a ld hl,email ; flash my email call _puts ; super duper maddd props ld a,6 ld (_curRow),a xor a ld (_curCol),a ld hl,quitmsg call _puts press: call _getkey ; Wait for user to press any key. cp 006h jr nz,press ld a,7 ; move the curRow down two, so it doesnt overwrite my email ld (_curRow), a call 4AADh ; re-enable the run indic. ret ; return to "where we were" before prgm exec. Intro: .db "BounceBall! F1=Easy ... F5=Diffucult",0 msg: .db "Your score is: ",0 gmvr: .db "Game Over!",0 me: .db "Sean Smith",0 email: .db "afrosean@hotmail.com",0 quitmsg: .db "enter to exit.",0 ball: .db "O",0 blnk: .db " ",0 Pad: .db "-===-",0 Padblnk: .db " ",0 ballX: .db 0 ; 8 bit variables... ball x ballY: .db 0 ; ball y tmpX: .db 0 ; temp ball x value tmpY: .db 0 ; temp ball y value ballUD .db 0 ; ball up down directional flag ballLR .db 0 ; ball left right directional flag padX: .db 0 ; paddle x value padY: .db 0 ; paddle y value tmpPadX: .db 0 ; temp paddle x value tmpPadY: .db 0 ; temp paddle y value Hard: .db 0 ; speed control (really a loop value) score: .db 0 ; stores score .end ; goodbye