	.nolist
	#include "ion.inc"
	#include "keys.inc"
	.list
#ifdef TI83P
	.org	progstart-2
	.db	$BB,$6D
#else
	.org	progstart
#endif
	ret
	jr	nc,start
	.db "Bolldin by Andreas Finne",0

start:
	bcall(_indicatorOff)
	bcall(_clrlcdf)
	bcall(_cleargbuf)
	ld a,50                         ;Can't put coin further down than 50
	ld (YEdge),a
	ld a,63                         ;Can't put coin further right than 60
	ld (XEdge),a
	ld hl,$0000
	ld (Score),hl
	ld a,1
	ld (Level),a
	ld a,3
	ld (Spd),a
	ld (Diff),a
	ld de,plotsscreen+48
	ld bc,156
	ld hl,PIC_PAGE
	ldir
	bcall(_copygbuf)
	ld bc,25*256+1
	ld (penCol),bc
	ld hl,SpeedTxt
	bcall(_vputs)
	ld bc,35*256+1
	ld (penCol),bc
	bcall(_vputs)
	ld bc,45*256+1
	ld (penCol),bc
	bcall(_vputs)
	ld bc,45*256+50
	ld (penCol),bc
	bcall(_vputs)
	ld bc,55*256+12
	ld (penCol),bc
	bcall(_vputs)
	ld hl,25*256+50
	ld (penCol),hl
	ld hl,SndTxt
	bcall(_vputs)
	ld bc,35*256+50
	ld (penCol),bc
	bcall(_vputs)
	call DispSpdDiff

StartKey:        
	call RandXY
	bcall(_getcsc)
	ld hl,Diff
	cp G_UP
	jr z,IncRoutine
	cp G_DOWN
	jr z,DecRoutine
	ld hl,Spd
	cp G_LEFT
	jr z,DecRoutine
	cp G_RIGHT
	jr z,IncRoutine
	cp G_ENTER
	jr z,SetActualSpeed
	cp G_CLEAR
	ret z
	jr StartKey

IncRoutine:
	ld a,(hl)
	cp 5
	jr z,ResR
	inc a
	ld (hl),a
	call DispSpdDiff
	jr StartKey
ResR:
	ld a,1
	ld (hl),a
	call DispSpdDiff
	jr StartKey

DecRoutine:
	ld a,(hl)
	cp 1
	jr z,SetR
	dec a
	ld (hl),a
	call DispSpdDiff
	jr StartKey
SetR:
	ld a,5
	ld (hl),a
	call DispSpdDiff
	jr StartKey

SetActualSpeed:
	ld a,(Spd)
	dec a
	ld c,a
	ld b,0
	ld hl,SpeedTbl
	add hl,bc
	ld a,(hl)
	ld (Speed),a
	
SetActualDiff:
	ld a,(Diff)
	ld b,a
	ld a,150
SADLoop:
	sub 20
	djnz SADLoop
	ld (DiffSometh),a
	
FinalSetup:
	ld (Counter),a
        set 7,(iy+20)	
Begin:        

	bcall(_cleargbuf)

; Thanks to Jimmy Mårdell

drawboard:
	bcall(_clrlcdf)
	ld hl,plotsscreen+20
	ld de,$0c
	ld b,62
	ld a,$01
MLoop:
	ld (hl),a
	add hl,de
	djnz MLoop
	ld ix,plotsscreen
	ld de,$0c
	ld b,64
VLoop:
	ld (ix),$80
	ld (ix+$0B),$01
	add ix,de
	djnz VLoop
	ld hl,plotsscreen
	ld de,plotsscreen+756
	ld b,12
	ld a,$FF
HLoop:
	ld (hl),a
	ld (de),a
	inc hl
	inc de
	djnz HLoop

SetupScreen:    
	ld hl,2*256+73        ;2 into l, 102 into h
	ld (penCol),hl        ;102 into _penCol, 2 into _penRow
	ld hl,LevelStr2        ;Load text into hl
	bcall(_vputs)            ;Put it out in small font
	ld bc,18*256+73       ;Same as previous
	ld (penCol),bc
	bcall(_vputs)
	ld bc,34*256+73        ;2 into l, 102 into h
	ld (penCol),bc        ;102 into _penCol, 2 into _penRow
	bcall(_vputs)            ;Put it out in small font
	ld hl,10*256+81       ;10 into h, 110 into l (I think) 
	ld (penCol),hl        ;110 into _penCol, 10 into _penRow
	ld a,(Level)           ;Load current level into a
	add a,'0'
	bcall(_vputmap)
	ld hl,26*256+77       ;Same as previous
	ld (penCol),hl
	ld hl,(Score)          ;Load Score into hl
	call DispHL            ;Routine to display hl
	ld hl,42*256+77       ;Same as previous
	ld (penCol),hl
	ld hl,(Hiscore)          ;Load Score into hl
	call DispHL            ;Routine to display hl
DisplaySprites:
;Bolldin      
	ld a,13                ;45 into a
	ld (BallX),a           ;a into Ball's x-coordinate
	ld a,27                ;27 into a
	ld (BallY),a           ;a into Ball's y-coordinate
	ld hl,Bolldin          ;Sprite into hl
	call DispBall          ;Put it on the screen

;Coin        
	ld a,30                ;Same as for Bolldin
	ld (CoinY),a           ;Have to do this in order to get the 
	ld (CoinX),a           ;original x and y coordinates or else
	ld a,(CoinY)           ;the missed coin wouldn't go away
	ld e,a                 ;
	ld a,(CoinX)           ;
	ld hl,Coin             ;
	call PutSprite         ;Puts it on the screen
	call DispCoin          ;Deletes it and puts out a new at random position
	call EnemySetup        ;Setup the enemy's coordinates

;**************** Setup ready, Start actual game ************************

;********************GameLoop***********************
Top:
	bcall(_copygbuf)
	ld      a,(Speed)      ;Speed into a
WaitLoop:
	HALT                   ;Saves battery power
	dec     a              ;decrease a
	or      a              ;Loops 'Speed' times before read keypress
	jr      NZ, WaitLoop   ;If a isn't zero go back to WaitLoop

MoveLoop:
	call DecCounter
	call RandXY            ;Randomize coordinates
	ld a,$BF
	out (1),a
	nop
	nop
	in a,(1)
	bit 6,a
	call z,Pause           ;Is it? Call pause
	ld a,$FD
	out (1),a
	nop
	nop
	in a,(1)
	bit 6,a
	jp z,GameOver          ;Is it? Jump to GameOver
	ld a,$FE
	out (1),a
	nop
	nop
	in a,(1)
	bit 1,a
	jr z,MoveLeft
	bit 2,a
	jr z,MoveRight
	bit 3,a
	jr z,MoveUp
	bit 0,a
	jr z,MoveDown
	jp MoveEnemy           ;If no key was pressed, move the enemy
	
	
MoveUp:
	call RandXY            ;Randomize Coin's variables
	ld a,(BallY)           ;Ball y-coordinate into a
	cp 1                   ;Is it 1?
	jp z,MoveEnemy         ;Can't move up if already highest, move enemy
	call DispBall          ;Remove from previous position
	ld a,(BallY)           ;Ball y-coordinate into a
	dec a                  ;Decrease it
	ld (BallY),a           ;Load new y into y-coordinate
	jr SmthRoutine


MoveDown:
	call RandXY             ;Same as MoveUp
	ld a,(BallY)
	cp 55
	jp z,MoveEnemy         ;Can't go further down than 55!
	call DispBall
	ld a,(BallY)
	inc a
	ld (BallY),a
	jr SmthRoutine
	

MoveRight:
	call RandXY             ;Same as MoveDown
	ld a,(BallX)                    
	cp 63			;92                          
	jp z,MoveEnemy         ;Can't go further right than 92!         
	call DispBall                   
	ld a,(BallX)                    
	inc a                           
	ld (BallX),a                    
	jr SmthRoutine
	

MoveLeft:
	call RandXY             ;Same as MoveRight
	ld a,(BallX)       
	cp 1
	jp z,MoveEnemy         ;Can't go further left than 1!
	call DispBall
	ld a,(BallX)
	dec a
	ld (BallX),a

SmthRoutine:
	call DispBall          ;Put it out at new position
	call CheckCoin         ;Check if you take a coin
	jp MoveEnemy           ;Move the enemy


;**********************End of GameLoop*********************

;********************* Check if Coin is taken ************************
CheckCoin:                 ;Routine to check if you take a coin
	ld a,(BallX)           ;First it checks if ball x-coord and coin 
	ld c,a                 ;x-coord are close to each other. If they are
	ld a,(CoinX)           ;then it checks the y-coordinates.
	sub 6                  
	ld b,12                
CheckCoinLoop:        
	inc a                   ;increases a so you don't have to be exactly on the same spot as the coin it's enough if you touch it
	cp c                    ;Compare ball x and coin x 
	jr z,CheckCY            ;if they are equal check y-coords       
	djnz CheckCoinLoop      ;Decrease b, if not zero go back to CheckCoinLoop
	ret

CheckCY:                    ;Check if y-coords are close to each other
	ld a,(BallY)            ;If they are you took the coin!
	ld c,a                  ;BallY into c
	ld a,(CoinY)            ;CoinY into a
	sub 6                   ;Subtract 6 from a
	ld b,12                 ;12 into b. Loop 12 times
CheckCYLoop:        
	inc a                   ;Increase a one step
	cp c                    ;Compare with c (=BallY)
	jr z,TakeCoin           ;If equal, you took the coin
	djnz CheckCYLoop        ;Decrease b, check if zero, if not, go back to CheckCYLoop
	ret                     ;Return from call

;******************* Coin is taken ***********************
TakeCoin:
	call DispCoin
	call ResCounter        ;Resets the counter     
	ld hl,(Score)          ;Score into hl
	ld bc,10               ;Load 10 into bc
	add hl,bc              ;Add bc to hl
	ld (Score),hl          ;Load back hl into Score (Now 10 higher)
	call PutScore          ;Put the score out
CheckLevel:
	ld a,(Level)            ;Level into a
	cp 1                    ;Is it 1?
	jr z,Check100           ;If level=1 check if 100 points
	cp 2                    ;Is it 2?
	jr z,Check200           ;If level=2 check if 200 points
	cp 3                    ;Is it 3?
	jr z,Check300           ;If level=3 check if 300 points
	ret                     ;Return from call

Check100:
	ld hl,(Score)           ;Score into hl, everything up to 255 into l
	ld a,l                  ;Load l into a
	cp $64
	jr nc,LevelUp           ;If a equals or is greater than b goto level up
	ret

Check200:               
	ld hl,(Score)           ;Same as Check100
	ld a,l
	cp $C8
	jr nc,LevelUp
	ret

Check300:
	ld hl,(Score)           ;Score into hl
	ld a,h                  ;Since we are going to check if you have 300 points and l only
	or a                    ;holds 255, we must first check if there's something in h.
							;(Anything above 255 goes into h)
	ret z
CheckLL:
	ld a,l                  ;This is pretty complicated. If score is 256, then h=1 l=0
	cp 44                   ;Thus, h has the value of 256. If you have 300 points, there's
							;1 in h (=256) and in l 300-256=44
	jr nc,LevelUp           ;That's why we compare it with 44
	ret                     ;If a equals or is greater than b, goto level up

LevelUp:
	ld a,(Level)            ;Level into a
	inc a                   ;Increase it
	ld (Level),a            ;Load back a into level
	ld hl,10*256+81       
        ld (penCol),hl        ;110 into _penCol, 10 into _penRow
	ld a,(Level)           ;Load current level into a
	add a,'0'
	bcall(_vputmap)
	ld a,(Speed)           ;Speed into a
	dec a                  ;Decrese it
	ld (Speed),a           ;A into speed
	ld a,(Level)
	cp 2
	call z,Enemy2Setup
	ld a,(Level)
	cp 3
	call z,Enemy3Setup
	ld a,(Level)
	cp 4
	call z,Enemy4Setup
	ret                    ;Return from call

;****************Move and check if Enemy crasches into the wall**************
MoveEnemy:                     ;Move the enemy
	call RandXY             ;Randomize coin x and y 
	ld a,(Level)
	cp 2
	jr z,EnemyM2
	cp 3
	jp z,EnemyM3
	cp 4
	jp z,EnemyM4
Enemy1:        
	ld a,(EnemX)           ;Load enemy x-coord into a
	cp 1                   ;Compare to 1
	jr z,Crasch            ;If equal goto Crasch
;**************Check if Ball is hit*************************
	ld a,(EnemX)           ;Enemy x-coord into a
	ld b,a                 ;a into b
	ld a,(BallX)           ;Ball x-coord into a
	add a,6                ;Add 6 to a
	cp b                   ;Compare b to a
	jp z,CheckY            ;If equal check y-coords
	dec a                  ;Checks again with difference 5
	cp b                   ;if I didn't have this you could go 
	jp z,CheckY            ;straight through the enemy

Tillbaka:                  ;If the Ball wasn't hit it comes back here
	call DispEnemy         ;Removes the enemy from old position
	ld a,(EnemX)           ;x-coord into a
	dec a                  ;decrease a
	ld (EnemX),a           ;a into x-coord
	call DispEnemy         ;Display enemy at new position
	jp Top                 ;Go all the way back and check keys again
		

Crasch:                                 ;If the enemy crasches into wall.
	call DispEnemy                  ;Remove enemy
        ld a,(EnemyY)                    ;Load coords into a and e
	ld e,a
	ld a,(EnemX)
	ld hl,Boom                      ;Load crasch sprite into hl
	call PutSprite                  ;Put it out
        ld a,(EnemyY)                    ;Load coords into a and e
	ld e,a
	ld a,(EnemX)
	ld hl,Boom                      ;Load crasch sprite into hl
	call PutSprite                  ;Remove it
	call EnemySetup                 ;New enemy
	jp Top                          ;All the way back to key check

EnemyM2:        
	ld a,(Enem2X)           ;Load enemy x-coord into a
	cp 63                   ;Compare to 1
	jr z,Crasch2            ;If equal goto Crasch

;**************Check if Ball is hit*************************
	ld a,(Enem2X)           ;Enemy x-coord into a
	ld b,a                 ;a into b
	ld a,(BallX)           ;Ball x-coord into a
	sub 6                ;Add 6 to a
	cp b                   ;Compare b to a
	jp z,Check2Y            ;If equal check y-coords
	inc a                  ;Checks again with difference 5
	cp b                   ;if I didn't have this you could go 
	jp z,Check2Y            ;straight through the enemy

Tillbaka2:                      ;If the Ball wasn't hit it comes back here
	call DispEnemy2         ;Removes the enemy from old position
	ld a,(Enem2X)           ;x-coord into a
	inc a                  ;increase a
	ld (Enem2X),a           ;a into x-coord
	call DispEnemy2         ;Display enemy at new position
	jr Enemy1               ;Check enemy1

Crasch2:                                 ;If the enemy crasches into wall.
	call DispEnemy2                  ;Remove enemy
	ld a,(Enem2Y)                    ;Load coords into a and e
	ld e,a
	ld a,(Enem2X)
	ld hl,Boom                      ;Load crasch sprite into hl
	call PutSprite                  ;Put it out
	ld a,(Enem2Y)                    ;Load coords into a and e
	ld e,a
	ld a,(Enem2X)
	ld hl,Boom                      ;Load crasch sprite into hl
	call PutSprite                  ;Remove it
	call Enemy2Setup                 ;New enemy
	jp Enemy1                          ;All the way back to key check

EnemyM3:        
	ld a,(Enem3Y)           ;Load enemy x-coord into a
	cp 1                   ;Compare to 1
	jr z,Crasch3            ;If equal goto Crasch

;**************Check if Ball is hit*************************
	ld a,(Enem3Y)           ;Enemy x-coord into a
	ld b,a                 ;a into b
	ld a,(BallY)           ;Ball x-coord into a
	add a,6                 ;Add 6 to a
	cp b                   ;Compare b to a
	jp z,Check1X            ;If equal check y-coords
	inc a                  ;Checks again with difference 5
	cp b                   ;if I didn't have this you could go 
	jp z,Check1X            ;straight through the enemy

Tillbaka3:                      ;If the Ball wasn't hit it comes back here
	call DispEnemy3         ;Removes the enemy from old position
	ld a,(Enem3Y)           ;x-coord into a
	dec a                  ;decrease a
	ld (Enem3Y),a           ;a into x-coord
	call DispEnemy3         ;Display enemy at new position
	jr EnemyM2                ;Go all the way back and check keys again
		

Crasch3:                                 ;If the enemy crasches into wall.
	call DispEnemy3                  ;Remove enemy
	ld a,(Enem3Y)                    ;Load coords into a and e
	ld e,a
	ld a,(Enem3X)
	ld hl,Boom                      ;Load crasch sprite into hl
	call PutSprite                  ;Put it out
	ld a,(Enem3Y)                    ;Load coords into a and e
	ld e,a
	ld a,(Enem3X)
	ld hl,Boom                      ;Load crasch sprite into hl
	call PutSprite                  ;Remove it
	call Enemy3Setup                 ;New enemy
	jp EnemyM2                          ;All the way back to key check

EnemyM4:        
	ld a,(Enem4Y)           ;Load enemy x-coord into a
	cp 56                   ;Compare to 1
	jr z,Crasch4            ;If equal goto Crasch
;**************Check if Ball is hit*************************
	ld a,(Enem4Y)           ;Enemy x-coord into a
	ld b,a                 ;a into b
	ld a,(BallY)           ;Ball x-coord into a
	sub 6                ;Add 6 to a
	cp b                   ;Compare b to a
	jp z,Check2X            ;If equal check y-coords
	inc a                  ;Checks again with difference 5
	cp b                   ;if I didn't have this you could go 
	jp z,Check2X            ;straight through the enemy

Tillbaka4:                      ;If the Ball wasn't hit it comes back here
	call DispEnemy4         ;Removes the enemy from old position
	ld a,(Enem4Y)           ;x-coord into a
	inc a                  ;decrease a
	ld (Enem4Y),a           ;a into x-coord
	call DispEnemy4         ;Display enemy at new position
	jr EnemyM3                ;Go all the way back and check keys again
		

Crasch4:                                 ;If the enemy crasches into wall.
	call DispEnemy4                  ;Remove enemy
	ld a,(Enem4Y)                    ;Load coords into a and e
	ld e,a
	ld a,(Enem4X)
	ld hl,Boom                      ;Load crasch sprite into hl
	call PutSprite                  ;Put it out
	ld a,(Enem4Y)                    ;Load coords into a and e
	ld e,a
	ld a,(Enem4X)
	ld hl,Boom                      ;Load crasch sprite into hl
	call PutSprite                  ;Remove it
	call Enemy4Setup                 ;New enemy
	jp EnemyM3                          ;All the way back to key check


CheckY:                                 ;Another routine to check if 
	ld a,(BallY)                    ;y-coords are equal
	ld c,a                          ;Ball and enemy don't have to be on
        ld a,(EnemyY)                    ;the same height. It's enough if they
	sub 6                           ;touch
	ld b,13                         ;If coords are equal goto BallHit
CheckYLoop:        
	inc a
	cp c
	jr z,BallHit
	djnz CheckYLoop
	jp Tillbaka                     ;Whew! Ball wasn't hit. Now go back.
	
Check2Y:                                 ;Another routine to check if 
	ld a,(BallY)                    ;y-coords are equal
	ld c,a                          ;Ball and enemy don't have to be on
	ld a,(Enem2Y)                    ;the same height. It's enough if they
	sub 6                           ;touch
	ld b,13                         ;If coords are equal goto BallHit
Check2YLoop:        
	inc a
	cp c
	jp z,BallHit
	djnz Check2YLoop
	jp Tillbaka2                     ;Whew! Ball wasn't hit. Now go back.

Check1X:                                 ;Another routine to check if 
	ld a,(BallX)                    ;y-coords are equal
	ld c,a                          ;Ball and enemy don't have to be on
	ld a,(Enem3X)                    ;the same height. It's enough if they
	sub 6                           ;touch
	ld b,13                         ;If coords are equal goto BallHit
Check1XLoop:        
	inc a
	cp c
	jp z,BallHit
	djnz Check1XLoop
	jp Tillbaka3                    ;Whew! Ball wasn't hit. Now go back.

Check2X:                                 ;Another routine to check if 
	ld a,(BallX)                    ;y-coords are equal
	ld c,a                          ;Ball and enemy don't have to be on
	ld a,(Enem4X)                    ;the same height. It's enough if they
	sub 6                           ;touch
	ld b,13                         ;If coords are equal goto BallHit
Check2XLoop:        
	inc a
	cp c
	jp z,BallHit
	djnz Check2XLoop
	jp Tillbaka4                    ;Whew! Ball wasn't hit. Now go back.

BallHit:                                ;No!!!! The Ball was hit
	ld a,(BallY)
	ld e,a
	ld a,(BallX)
	ld hl,Bolldin
	call PutSprite                  ;Remove it
	ld a,(BallY)
	ld e,a
	ld a,(BallX)
	ld hl,Hit                       ;Put the hit sprite instead
	call PutSprite
	bcall(_copygbuf)
	call Delay                      ;A little longer delay
	jp GameOver                     ;GameOver!


;*******************************************************
#include "first3.asm"    ;includes the file containing the picture
;*******************************************************



DispSpdDiff        
	ld hl,25*256+40
	ld (penCol),hl
	ld a,(Spd)
	add a,'0'
	bcall(_vputmap)
	ld hl,35*256+40
	ld (penCol),hl
	ld a,(Diff)
	add a,'0'
	bcall(_vputmap)
	ret


;---------------- Sprite stuff from POKE by Ahmed El-Helw ---------------
DispBall:
	call RandXY
	ld a,(BallY)
	ld e,a
	ld a,(BallX)
	ld hl,Bolldin
	call PutSprite
	ret

DispCoin:
	call RandXY
	ld a,(CoinY)
	ld e,a
	ld a,(CoinX)
	ld hl,Coin
	call PutSprite
	ld a,(Rand2)
	ld (CoinY),a
	ld e,a
	ld a,(Rand1)
	ld (CoinX),a
	ld hl,Coin
	call PutSprite
	ret

DispEnemy:                              ;XORs the Enemy on/off the screen
	call RandXY
        ld a,(EnemyY)                    ;Enemy y into a
	ld e,a                          ;a goes into e, e = y-coord
	ld a,(EnemX)                    ;Enemy x into a
	ld hl,Enemy                     ;Sprite into hl
	call PutSprite                  ;XOR it!
	ret                             ;Return to call

DispEnemy2:                              ;XORs the Enemy on/off the screen
	call RandXY
	ld a,(Enem2Y)                    ;Enemy y into a
	ld e,a                          ;a goes into e, e = y-coord
	ld a,(Enem2X)                    ;Enemy x into a
	ld hl,Enemy2                     ;Sprite into hl
	call PutSprite                  ;XOR it!
	ret                             ;Return to call

DispEnemy3:                              ;XORs the Enemy on/off the screen
	call RandXY
	ld a,(Enem3Y)                    ;Enemy y into a
	ld e,a                          ;a goes into e, e = y-coord
	ld a,(Enem3X)                    ;Enemy x into a
	ld hl,Enemy3                     ;Sprite into hl
	call PutSprite                  ;XOR it!
	ret                             ;Return to call

DispEnemy4:                              ;XORs the Enemy on/off the screen
	call RandXY
	ld a,(Enem4Y)                    ;Enemy y into a
	ld e,a                          ;a goes into e, e = y-coord
	ld a,(Enem4X)                    ;Enemy x into a
	ld hl,Enemy4                     ;Sprite into hl
	call PutSprite                  ;XOR it!
	ret                             ;Return to call


MissCoin:
	ld hl,(Score)                   ;Score into hl
	ld a,h                          ;Load anything over 255 into a
	or a
	jr z,CheckL                     ;If a<b Check l
DecScore:        
	dec hl                          ;Decrease hl
	dec hl                          ;Decrease hl
	ld (Score),hl                   ;Load hl into score
	jr PutScore                   ;Put out the score on the screen

CheckL:
	ld a,l                          ;Load l into a
	cp 2
	jr nc,DecScore                  ;If a is bigger than or equals b 
					;Goto DecScore
ScoreRes:
	ld hl,$0000                     ;Load 0 into hl
	ld (Score),hl                   ;Load hl into Score
PutScore:
	ld hl,26*256+77
	ld (penCol),hl
	ld hl,Empty
	bcall(_vputs)
	ld hl,26*256+77
	ld (penCol),hl                 ;105 into _pencol, 26 into _penRow
	ld hl,(Score)
	call DispHL
	ret


;***********************GameOver!*****************************
GameOver:
	ld hl,$0306
	ld (curRow),hl                 ;$06 into _curRow $03 into _curCol
	ld hl,GameOverSt                ;Text into hl
	bcall(_puts)                      ;Put it out @ 3,6
	ld hl,(Hiscore)
	ld d,h
	ld e,l
	ld hl,(Score)
	bcall(_cphlde)
	jr z,GOLoop
	jr nc,NewHiscore
	
GOLoop:        
	bcall(_getcsc)                    ;Get the recent key pressed
	cp G_ENTER
	jr nz,GOLoop
	bcall(_homeup)                    ;Put the cursor in the upper left corner
	bcall(_clrlcdf)
	ret

NewHiscore:
	ld hl,$0204
	ld (curRow),hl
	ld hl,Hsctxt
	bcall(_puts)
	ld hl,(Score)
	ld (Hiscore),hl
	jr GOLoop

EnemySetup:   
	ld a,63                         ;Load 92 into a
	ld (EnemX),a                    ;a into x-coord
	ld a,53                    ;Random number into a
	call Random
	inc a
        ld (EnemyY),a                    ;a into y-coord
	halt
	call DispEnemy                  ;Display it
	ret
Enemy2Setup:   
	ld a,1                         ;Load 92 into a
	ld (Enem2X),a                    ;a into x-coord
	ld a,53                    ;Random number into a
	call Random
	inc a
	ld (Enem2Y),a                    ;a into y-coord
	halt
	call DispEnemy2                  ;Display it
	ret

Enemy3Setup:   
	ld a,56                         ;Load 92 into a
	ld (Enem3Y),a                    ;a into x-coord
	ld a,54                    ;Random number into a
	call Random
	inc a
	ld (Enem3X),a                    ;a into y-coord
	halt
	call DispEnemy3                  ;Display it
	ret

Enemy4Setup:   
	ld a,1                         ;Load 92 into a
	ld (Enem4Y),a                    ;a into x-coord
	ld a,54                    ;Random number into a
	call Random
	inc a
	ld (Enem4X),a                    ;a into y-coord
	halt
	call DispEnemy4                  ;Display it
	ret


DecCounter:
	ld a,(Counter)
	dec a
	ld (Counter),a
	or a
	ret nz
RemoveCoin:
	call DispCoin
	call MissCoin
ResCounter:
	ld a,(DiffSometh)
	ld (Counter),a
	ret


;---------------- From Kollums ---------------------------
RandXY:
RandomizeX:
    ld a, (XEdge)
    inc a
    ld b, a
    ld a, (Rand1)
    inc a
    cp b
    jr z, RANDINC_1                 
    ld (Rand1), a 
    jr RandomizeY
RANDINC_1: 
    ld a, 1 
    ld (Rand1), a 
RandomizeY:
    ld a, (YEdge)
    inc a
    ld b, a
    ld a, (Rand2)
    inc a
    cp b
    jr z, RANDINC_2                 
    ld (Rand2), a 
    ret 
RANDINC_2: 
    ld a, 1 
    ld (Rand2), a 
    ret 

;********************************************************************
;* RANDOM routine from ZTetris by Jimmy Mårdell                     *
;********************************************************************


Random:                ; Creates a random number 0 <= x < A
	ld b,a
	ld a,r
	add a,a
	ld hl,0
	ld d,0
	ld e,a
RMul:
	add hl,de
	djnz RMul
	ld a,h
	ret



DispHL:
	ld	c,'0'  			; save ascii value for zero
	ld	de,OP1+5		; point to end of the buffer
	xor	a				; zero terminate string
	ld	(de),a			; set last byte to zero
DispHL0:
	bcall(_divhlby10)	; next digit
	dec	de				; next position
	add	a,c				; convert to ascii
	ld	(de),a			; save digit
	ld	a,h				; load upper byte
	or	l				; check with lower byte for zero
	jr	nz,DispHL0		; loop
	ex	de,hl			; point to buffer
	bcall(_vputs)		; print number
	ret					; we're done


Pause:
	bcall(_clrlcdf)
	ld hl,$0404
	ld (curRow),hl                 ;$06 into _curRow, $04 into _curCol
	ld hl,PauseStr
	bcall(_puts)
	bcall(_getcsc)
	xor a
PauseLoop:
	bcall(_getcsc)
	cp G_DEL
	jr z,PauseLoop
	or a
	jr z,PauseLoop
	bcall(_copygbuf)
	ret


;hl = image
;a = x coord
;e = y coord

PutSprite:

        push    hl              ; Save sprite address

;ÛÛÛÛ   Calculate the address in graphbuf   ÛÛÛÛ

        ld      hl,0            ; Do y*12
        ld      d,0
        add     hl,de
        add     hl,de
        add     hl,de
        add     hl,hl
        add     hl,hl

        ld      d,0             ; Do x/8
        ld      e,a
        srl     e
        srl     e
        srl     e
        add     hl,de

        ld      de,GRAPH_MEM
        add     hl,de           ; Add address to graphbuf

        ld      b,00000111b     ; Get the remainder of x/8
        and     b
        cp      0               ; Is this sprite aligned to 8*n,y?
        jr      z,ALIGN

;ÛÛÛÛ   Non aligned sprite blit starts here   ÛÛÛÛ

        pop     ix              ; ix->sprite
        ld      d,a             ; d=how many bits to shift each line

        ld      e,8             ; Line loop
LILOP:  ld      b,(ix+0)        ; Get sprite data

        ld      c,0             ; Shift loop
        push    de
SHLOP:  srl     b
        rr      c
        dec     d
        jr      nz,SHLOP
        pop     de

	ld      a,b             ; Write line to graphbuf
        xor      (hl)
        ld      (hl),a
        inc     hl
        ld      a,c
        xor       (hl)
        ld      (hl),a
        ld      bc,11           ; Calculate next line address
        add     hl,bc
        inc     ix              ; Inc spritepointer

        dec     e
        jr      nz,LILOP        ; Next line
        ret

;ÛÛÛÛ   Aligned sprite blit starts here   ÛÛÛÛ

ALIGN:                          ; Blit an aligned sprite to graphbuf
        pop     de              ; de->sprite
        ld      b,8
ALOP1:  

	ld      a,(de)
	xor      (hl)
        ld      (hl),a
        inc     de
        push    bc
        ld      bc,12
        add     hl,bc
        pop     bc
        djnz    ALOP1
	RET


;-------------------Delay from Poke--------------------

Delay:                             ;Delay Loop, converted from Dan Eble's 85 Bounce
	LD BC,$C000                     ;dlay length->bc
delayLoop:
	DEC BC                          ;bc-1->bc
	LD A, B                         ;Loads b into a
	OR C                            ;Checks if c=0
	JR NZ, delayLoop               ;if not, continue loop  
	ret                             ;Return to Call

;**************** Start of text and variables ********************'

SpeedTxt:  .db "Speed:",0
DiffTxt:   .db "Difficulty:",0
StartTxt:  .db "Start:",0
Start2Txt:     .db "ENTER",0
Email:     .db "a_finne@hotmail.com",0

SndTxt:    .db "l/r",0
AlphaTxt:  .db "u/d",0
    
GameOverSt:
	.db "Game Over!",0

LevelStr2:
	.db "Level:",0

ScoreStr:
	.db "Score:",0

Hiscstr:
	.db "High:",0


Empty:
	.db "                  ",0

PauseStr:
	.db "*PAUSED*",0

Hsctxt: .db "New Hiscore!",0

Bolldin:
	.db %00011110
	.db %01111111
	.db %01111111
	.db %11111110
	.db %01111100
	.db %01111100
	.db %00111100
	.db %00010000

Enemy:
	.db %00000000
	.db %00110000
	.db %01100000
	.db %10111111
	.db %10111111
	.db %01100000
	.db %00110000
	.db %00000000

Enemy2:
	.db %00000000
	.db %00001100
	.db %00000110
	.db %11111101
	.db %11111101
	.db %00000110
	.db %00001100
	.db %00000000

Enemy3:
	.db %00011000
	.db %00100100
	.db %01111110
	.db %01011010
	.db %00011000
	.db %00011000
	.db %00011000
	.db %00011000

Enemy4:
	.db %00011000
	.db %00011000
	.db %00011000
	.db %00011000
	.db %01011010
	.db %01111110
	.db %00100100
	.db %00011000

Coin:
	.db %00111000
	.db %01000100
	.db %10010010
	.db %10010010
	.db %10010010
	.db %01000100
	.db %00111000
	.db %00000000

Boom:
	.db %00000000
	.db %00110000
	.db %01000000
	.db %10101000
	.db %00000000
	.db %01100000
	.db %00001000
	.db %00000000

Hit:
	.db %01111000
	.db %11111100
	.db %11110000
	.db %11110000
	.db %01111000
	.db %01111100
	.db %00011110
	.db %00001100


BallX:  .db 0
BallY:  .db 0
EnemyY:  .db 0
EnemX:  .db 0
Enem2Y: .db 0
Enem2X: .db 0
Enem3Y: .db 0
Enem3X: .db 0
Enem4Y: .db 0
Enem4X: .db 0
CoinX:  .db 0
CoinY:  .db 0
Level:  .db 0
Score:  .db 0,0
Hiscore:        .db 0,0
Speed:  .db 0
Fade:   .db 0
NowMask:
	.db 0
XEdge:      
	.db 0
YEdge:
	.db 0

Rand1:
	.db 0
Rand2:
	.db 0
Counter:
	.db 0
Diff:   .db 0
Spd:    .db 0
DiffSometh:
	.db 0
SpeedTbl:
	.db 10,8,6,5,4

.end
