;bball.asm

;(c) Tim FitzRandolph, 1996

;Here is a simple bouncing ball demo.  It isn't perfect, but it works.
;Please don't cut-and-paste from this code (why would you want to)!!!
;
;Let me know if you find it useful, at timfitz@ix.netcom.com

;okay, here we go!



#include "ti-85.h"

.org 0
.db "bounce",0

ballx = $80DF           ;balls X position
bally = $80E0           ;balls Y position
balld = $80E1           ;balls direction (see below)
;
;
;
;               BALL DIRECTION SETUP:
;
;                     8    1
;                 7   |    |   2
;                   \  |  |  /
;                     \ || /
;                     / || \
;                   /  |  |  \
;                 6   |    |   3
;                     5    4
;
;
; NOTE: I set it up on purpose so that the ball would never go straight
; up or across.  This makes is so the ball never gets stuck in an endless
;loop.
;
;okay, on with the code.


;LOAD VARIALES AND STUFF-------------------------------------------+
Init:
        ld a,4
        out (5),a                       ;set to graphics mode

        ROM_CALL(CLEARLCD)              ;clear the screen

        ld a,60                         ;set balls initial position
        ld (ballx),a

        ld a,30                         ;same as above
        ld (bally),a


;ASK PLAYER FOR INITIAL BALL DIRECTION-----------------------------+
EnterDirection:

        ld hl,(PROGRAM_ADDR)    ;display text
        ld de,enterstr
        add hl,de
        ROM_CALL(D_ZT_STR)
enterloop:
        call GET_KEY            ;check for a keypress
        cp $22          ;1 pressed?
        JUMP_Z(d1)
        cp $1A          ;2 pressed?
        JUMP_Z(d2)
        cp $12          ;3 pressed?
        JUMP_Z(d3)
        cp $23          ;4 pressed?
        JUMP_Z(d4)
        cp $1B          ;5 pressed?
        JUMP_Z(d5)
        cp $13          ;6 pressed?
        JUMP_Z(d6)
        cp $24          ;7 pressed?
        JUMP_Z(d7)
        cp $1C          ;8 pressed?
        JUMP_Z(d8)
        cp $37
        ret z
        JUMP_(enterloop)

d1:
        ld a,1
        ld (balld),a    ;set balls direction
        JUMP_(Loop)

d2:
        ld a,2
        ld (balld),a    ;set balls direction
        JUMP_(Loop)

d3:
        ld a,3
        ld (balld),a    ;set balls direction
        JUMP_(Loop)

d4:
        ld a,4
        ld (balld),a    ;set balls direction
        JUMP_(Loop)

d5:
        ld a,5
        ld (balld),a    ;set balls direction
        JUMP_(Loop)

d6:
        ld a,6
        ld (balld),a    ;set balls direction
        JUMP_(Loop)

d7:
        ld a,7
        ld (balld),a    ;set balls direction
        JUMP_(Loop)

d8:
        ld a,8
        ld (balld),a    ;set balls direction
        JUMP_(Loop)


;ACTUAL PROGRAM LOOP-----------------------------------------+
Loop:
        ROM_CALL(CLEARLCD)              ;clear the screen
theloop:
        CALL_(EraseBall)        ;erase the ball
        CALL_(MoveBall)         ;move the ball (depending upon direction)
        CALL_(BounceBall)       ;bounce the ball if need be
        CALL_(DrawBall)         ;redraw the ball
        JUMP_(KeyTest)          ;see if its time to quit
continue:
        CALL_(DelayLoop)        ;delay a bit
        JUMP_(theloop)          ;loop back to start

KeyTest:
        call GET_KEY
        cp $37          ;EXIT pressed?
        ret z
        JUMP_(continue)

EraseBall:              ;erase the ball
        ld a,(ballx)
        ld b,a
        ld a,(bally)
        ld C,a

        CALL_(ErasePixel)
        inc B
        CALL_(ErasePixel)
        inc C
        CALL_(ErasePixel)
        dec B
        CALL_(ErasePixel)

        ret


DrawBall:               ;draw the ball
        ld a,(ballx)
        ld b,a
        ld a,(bally)
        ld c,a

        CALL_(PlotPixel)
        inc B
        CALL_(PlotPixel)
        inc C
        CALL_(PlotPixel)
        dec B
        CALL_(PlotPixel)

        ret

MoveBall:               ;move the ball, depending on direction set.
        ld a,(balld)
        cp 1            ;direction 1?
        JUMP_Z(move1)
        cp 2            ;direction 2?
        JUMP_Z(move2)
        cp 3            ;direction 3?
        JUMP_Z(move3)
        cp 4            ;direction 4?
        JUMP_Z(move4)
        cp 5            ;you get the idea.
        JUMP_Z(move5)
        cp 6
        JUMP_Z(move6)
        cp 7
        JUMP_Z(move7)
        cp 8
        JUMP_Z(move8)

        ret

move1:                  ;move the ball (direction 1)
        ld a,(ballx)
        inc a           ;over 1...
        ld (ballx),a

        ld a,(bally)
        inc a           ;up 2.
        inc a
        ld (bally),a
        ret

move2:
        ld a,(ballx)
        inc a           ;over 2...
        inc a
        ld (ballx),a

        ld a,(bally)
        inc a           ;up 1.
        ld (bally),a
        ret


move3:
        ld a,(ballx)
        inc a           ;over 2...
        inc a
        ld (ballx),a

        ld a,(bally)
        dec a           ;down 1.
        ld (bally),a
        ret

move4:
        ld a,(ballx)
        inc a           ;over 1...
        ld (ballx),a

        ld a,(bally)
        dec a           ;down 2.
        dec a
        ld (bally),a
        ret

move5:
        ld a,(ballx)
        dec a           ;back 1...
        ld (ballx),a

        ld a,(bally)
        dec a           ;down 2.
        dec a
        ld (bally),a
        ret

move6:
        ld a,(ballx)
        dec a           ;back 2...
        dec a
        ld (ballx),a

        ld a,(bally)
        dec a           ;down 1.
        ld (bally),a
        ret


move7:
        ld a,(ballx)
        dec a           ;back 2...
        dec a           
        ld (ballx),a

        ld a,(bally)
        inc a           ;up 1.
        ld (bally),a
        ret

move8:
        ld a,(ballx)
        dec a           ;back 1...
        ld (ballx),a

        ld a,(bally)
        inc a           ;up 2.
        inc a
        ld (bally),a
        ret

BounceBall:                     ;bounce the ball if its at the end of the screen!
        ld a,(ballx)
        cp 127          ;too far right?
        CALL_Z(bleft)
        cp 126          ;too far right?
        CALL_Z(bleft)
        cp 1            ;too far left?
        CALL_Z(bright)
        cp 2            ;too far left?
        CALL_Z(bright)

        ld a,(bally)
        cp 1            ;too far down?
        CALL_Z(bup)
        cp 2            ;too far down?
        CALL_Z(bup)
        cp 63           ;too far up?
        CALL_Z(bdown)
        cp 62           ;too far up?
        CALL_Z(bdown)
        ret

bleft:                          ;bounce ball left
        ld a,(balld)
        cp 1            ;direction 1?
        CALL_Z(left1)
        cp 2            ;direction 2?
        CALL_Z(left2)
        cp 3            ;you get the idea.
        CALL_Z(left3)
        cp 4
        CALL_Z(left4)

        ret

left1:
        ld a,8          ;reset direction to 8
        ld (balld),a
        ld a,0
        ret

left2:
        ld a,7          ;reset to 7...
        ld (balld),a
        ld a,0
        ret

left3:
        ld a,6          ;6....
        ld (balld),a
        ld a,0
        ret

left4:                  ;etc.
        ld a,5
        ld (balld),a
        ld a,0
        ret

bright:                 ;bounce right
        ld a,(balld)
        cp 8
        CALL_Z(right8)
        cp 7
        CALL_Z(right7)
        cp 6
        CALL_Z(right6)
        cp 5
        CALL_Z(right5)

        ret

right8:
        ld a,1
        ld (balld),a
        ld a,0
        ret

right7:
        ld a,2
        ld (balld),a
        ld a,0
        ret

right6:
        ld a,3
        ld (balld),a
        ld a,0
        ret

right5:
        ld a,4
        ld (balld),a
        ld a,0
        ret


bup:                    ;bounce up
        ld a,(balld)
        cp 3
        CALL_Z(up3)
        cp 4
        CALL_Z(up4)
        cp 5
        CALL_Z(up5)
        cp 6
        CALL_Z(up6)

        ret

up3:
        ld a,2
        ld (balld),a
        ld a,0
        ret

up4:
        ld a,1
        ld (balld),a
        ld a,0
        ret

up5:
        ld a,8
        ld (balld),a
        ld a,0
        ret

up6:
        ld a,7
        ld (balld),a
        ld a,0
        ret

bdown:                          ;bounce down
        ld a,(balld)
        cp 7
        CALL_Z(down7)
        cp 8
        CALL_Z(down8)
        cp 1
        CALL_Z(down1)
        cp 2
        CALL_Z(down2)

        ret

down7:
        ld a,6
        ld (balld),a
        ld a,0
        ret

down8:
        ld a,5
        ld (balld),a
        ld a,0
        ret

down1:
        ld a,4
        ld (balld),a
        ld a,0
        ret

down2:
        ld a,3
        ld (balld),a
        ld a,0
        ret

DelayLoop:      ;delay (pretty much taken from TEXAN.ASM (thanks Magnus)
        push af
        push bc
        ld bc,$1DFF
dloop:
        dec bc
        ld a,b
        or c
        jr nz,dloop
        pop bc
        pop af
        ret

PlotPixel:                      ;draw a pixel (thanks again, magnus)
        ROM_CALL(FIND_PIXEL)
        ld de,$FC00
        add hl,de
        or (HL)
        ld (HL),A
        ret


ErasePixel:                     ;remove a pixel.  (thanks magnus)
        ROM_CALL(FIND_PIXEL)
        ld de,$FC00
        add hl,de
        xor 255
        and (HL)
        ld (HL),A
        ret
        

enterstr:       .db "enter direction 1-8",0




;oh boy!  The end!

.end


