; JezzBall version 2.1 by Magnus Svedin -96

#include "TI-85.H"

.org 0                  
.db "JezzBall v2.1 by MSv",0       

XPos = $80df        ;Current X-Position of cursors
YPos = $80e0        ;Current Y-Position of cursors
LastMove = $80e1    ;0=y, other=x
LineOffs1 = $80e2   ;position of one edge of the line
LineOffs2 = $80e3   ;position of the other edge of the line
LinePos = $80e4     ;line-coord, if 0, no current line
LineDir = $80e5     ;0=hor, other=ver
curkey = $80e6      ;key pressed
clock = $80e7       ;all bits toggle each loop
NumBalls = $80e8    ;Number of balls in play (=level)
XBallDir = $80e9    ;X-Direction of all balls. bit0=Ball1, 1=positive move 
YBallDir = $80ea    ;Y-Direction of all balls. bit0=Ball1, 1=positive move 
XBallMove = $80eb   ;X-Speed of all balls. bit0=Ball1
YBallMove = $80ec   ;X-Speed of all balls. bit0=Ball1
XPosB1 = $80ed      ;X-Position of ball 1
YPosB1 = $80ee      ;Y-Position of ball 1
XPosB2 = $80ef      ;     /\
YPosB2 = $80f0      ;   / || \
XPosB3 = $80f1      ; /   ||   \
YPosB3 = $80f2      ;     ||
XPosB4 = $80f3      ;     ||
YPosB4 = $80f4      ;     ||
XPosB5 = $80f5      ;     ||
YPosB5 = $80f6      ;     ||
XPosB6 = $80f7      ;     ||
YPosB6 = $80f8      ;     ||
XPosB7 = $80f9      ;     ||
YPosB7 = $80fa      ;     ||
XPosB8 = $80fb      ;     ||
YPosB8 = $80fc      ;     ||
CurBall = $80fd     ; Current ball (number 1-8)
CurPosPtr = $80fe   ; Pointer to current ball's x-pos   WORD!
tmp = $8100         ; Temporary variable used in varies functions.
Lives = $8101       ; Lives left
Speed = $8102       ; Copy of speed for ingame-usage
OldContrast = $8103 ; Contrast set before jezzball
ActiveControl = $8104 ; 0=speedscroll active, other constscroll active
tmp2 = $8105        ; Temporary variable used when tmp is occupied
RectX1 = $8106      ; Low x-coord in rectangle
RectX2 = $8107      ; High x-coord in rectangle
RectY1 = $8108      ; Low y-coord in rectangle
RectY2 = $8109      ; High y-coord in rectangle
tmp3 = $810a        ; guess what...
Score = $810b       ; Current score
ScoreTxt = $810d    ; ASCII-copy of score, for printing on screen (5 bytes)
LevelDone = $8112   ; Indicator if level is complete, non-zero=level complete
LastScore = $8113   ; Score at beginning of level (used to see if 75% is done)
Move = $8115        ; Movement of cursor bits: 0=right, 1=left, 2=up, 3=down
clock2 = $8116      ; same as clock but toggles every second loop
RotateCount = $8117 ; Counter to make cursor-rotation happen every 8:th loop at maximum
;Limit is 8187!!!

; The ball coord points to the top left pixel of the ball.

Start:                  
  ld a, $00
  ld (LevelDone), a
  ld (LinePos), a  
  ld (clock), a
  ld (clock2), a
  ld a, $01
  ld (NumBalls), a
  ld (Lives), a
  ld hl, $0000
  ld (Score), hl
  ld (LastScore), hl

  CALL_(RandomBalls)

  ld a, $04             ;set rom-page for graph-routines
  out (5), a
  ROM_CALL(CLEARLCD)    ;clear screen
  JUMP_(StartIntro)     ;show intro-screen
AfterIntro:
  ROM_CALL(CLEARLCD)    ;clear screen
  CALL_(DrawFrame)      ;draw frame

  ld de, (PROGRAM_ADDR) ;init speed-variable (must be done after intro)
  ld hl, SpeedDB
  add hl, de
  ld a, (hl)
  ld (Speed), a

  ld a, (CONTRAST)      ;change contrast and save old
  ld (OldContrast), a
  ld b, a
  ld hl, ContrastDB
  add hl, de
  ld a, (hl)
  add a, b
  cp $1e
  jr c, ContrastIsOk
  ld a, $1e
ContrastIsOk:
  ld (CONTRAST), a  
	out (2),a

  CALL_(DrawBalls)

LoopStart:              ;start of main loop
  ld a, (clock)         ;change clock
  xor $ff
  ld (clock), a
  cp $00
  jr z, LSDontToggle
  ld a, (clock2)
  xor $ff
  ld (clock2), a
LSDontToggle:
  ld a, (RotateCount)   
  srl a
  ld (RotateCount), a
  ld a, $3e             ;mask out unused keys
  out (1), a
  in a, (1)             ;read key-press
  ld (curkey), a
  bit 6, a              ;call key-functions
  JUMP_Z(LeaveGame)     
  ld a, (curkey)
  bit 3, a
  CALL_Z(MoveUp)
  ld a, (curkey)
  bit 0, a
  CALL_Z(MoveDown)
  ld a, (curkey)
  bit 1, a
  CALL_Z(MoveLeft)
  ld a, (curkey)
  bit 2, a
  CALL_Z(MoveRight)
  ld a, (curkey)
  bit 5, a
  CALL_Z(InitLine)
  ld a, (curkey)
  bit 7, a
  CALL_Z(PrintScreen)

  CALL_(DrawBalls)       ;erase balls (and cursor) before ballmoves
  ld a, (curkey)          ;this must take place while cursor is invisible
  bit 4, a
  CALL_Z(RotateCursor)
  CALL_(MoveCursor)      ;cursor must be moved while it's invisible
  ld a, (LinePos)         ;Continue line-drawing if neccesary
  cp $00
  CALL_NZ(DrawLine)

  ld a, $00               ;move all existing balls
  ld hl, XPosB1
  ld (CurPosPtr), hl
LMBStl1:
  inc a
  ld (CurBall), a
  CALL_(MoveBall)
  CALL_(CheckMove)
  ld hl, (CurPosPtr)
  inc hl
  inc hl
  ld (CurPosPtr), hl
  ld a, (CurBall)
  ld hl, NumBalls
  cp (hl)
  jr nz, LMBStl1

  CALL_(DrawBalls)        ;draw balls in new positions

  ld a, (LevelDone)     ;check if level is done
  cp $00
  JUMP_NZ(NextLevel)

  ld a, (Lives)           ;check if there's any lives left
  cp $00
  JUMP_Z(GameOver)

  ld a, (NumBalls)
  cp $09
  JUMP_Z(GameDone)

  ld a, (Speed)               ;Pause-loop
  inc a
PauseL1:
  ld b, $ff
PauseL2:
  dec b
  jr nz, PauseL2
  dec a
  jr nz, PauseL1

  JUMP_(LoopStart)

ChangeDir:        ;Make sure hl=XBallDir or YBallDir
  ld a, $01             ;find bit to change for current ball
  push hl
  ld hl, CurBall
  ld b, (hl)
  dec b
  jr z, CXEnd
CXSt:
  rlca
  djnz CXSt
CXEnd:
  pop hl
  xor (hl)
  ld (hl), a
  ret

LineHit:    ;called (JUMP'ed) if ball hits line
  CALL_(InverseScreen)
  ld b, $ff
LHPauseStl1:
  ld a, $a0
LHPauseStl2:
  dec a
  jr nz, LHPauseStl2
  djnz LHPauseStl1
  CALL_(InverseScreen)
  ld hl, Lives     ;decrease lives
  dec (hl)
  CALL_(DrawLives)
  ld hl, LinePos    ;needed later
  ld a, (LineDir)
  cp $00            ;check direction of line
  jr z, LHHor     
  ld b, (hl)   ;line is (was) vertical
  ld a, (LineOffs1)
  ld c, a
  dec c
LHHStl1:            ;erase line
  inc c
  CALL_(ResPixel)
  ld a, (LineOffs2)
  cp c
  jr nz, LHHStl1
  ld hl, XBallDir   ; make ball bounce
  CALL_(ChangeDir)
  jr LHEnd
LHHor:              ;line is (was) horisontal
  ld a, (LineOffs1)
  ld b, a
  dec b
  ld c, (hl)
LHVStl1:
  inc b
  CALL_(ResPixel)   ;unerase those pixels that were black before line
  ld a, (LineOffs2)
  cp b
  jr nz, LHVStl1
  ld hl, YBallDir     ;bounce ball
  CALL_(ChangeDir)
LHEnd:
  ld hl, LinePos
  ld a, $00
  ld (hl), a 
  JUMP_(CMLineChkEnd)   ;continue at correct place

CheckMove:
  ld hl, (CurPosPtr)      ;Check if ball is in top of screen
  ld a, $01
  cp (hl)
  jr nz, CMBNotLeft
  inc (hl)                ;move ball away from border
  ld hl, XBallDir
  CALL_(ChangeDir)        ;change ball-x-direction
CMBNotLeft:
  ld a, $5d
  ld hl, (CurPosPtr)
  cp (hl)
  jr nz, CMBNotRight
  dec (hl)
  ld hl, XBallDir
  CALL_(ChangeDir)
CMBNotRight:
  ld a, $01
  ld hl, (CurPosPtr)
  inc hl
  cp (hl)
  jr nz, CMBNotTop
  inc (hl)
  ld hl, YBallDir
  CALL_(ChangeDir)
CMBNotTop:
  ld a, $3d
  ld hl, (CurPosPtr)
  inc hl
  cp (hl)
  jr nz, CMBNotBot
  dec (hl)
  ld hl, YBallDir
  CALL_(ChangeDir)
CMBNotBot:              ; Start checking for pixel-hits (hits with lines)
  ld a, $00             ; 01 This is the bit number of each pixel in tmp.
  ld (tmp), a           ; 32 
  ld hl, (CurPosPtr)
  ld b, (hl)
  inc hl
  ld c, (hl)
  CALL_(GetPixel)
  cp $00
  jr z, CMNoPix1
  ld hl, tmp
  set 0, (hl)
CMNoPix1:
  inc b
  CALL_(GetPixel)
  cp $00
  jr z, CMNoPix2
  ld hl, tmp
  set 1, (hl)
CMNoPix2:
  inc c
  CALL_(GetPixel)
  cp $00
  jr z, CMNoPix3
  ld hl, tmp
  set 2, (hl)
CMNoPix3:
  dec b
  CALL_(GetPixel)
  cp $00
  jr z, CMNoPix4
  ld hl, tmp
  set 3, (hl)
CMNoPix4:
  ld a, $00
  ld hl, tmp
  cp (hl)
  ret z                 ;return if there's no hit
  ld a, (LinePos)       ;check if there's a current line
  cp $00
  JUMP_Z(CMLineChkEnd)  ;if not start checking for old-line-hits
  ld a, (LineDir)       ;check in what direction line is
  cp $00
  JUMP_Z(CMLineChkHorSt)
  ld a, (LinePos)       ;vertical line
  ld hl, (CurPosPtr)    ;check if x-coord is the same as current line's
  cp (hl)
  jr z, CMLineChkVerXHit
  dec a
  cp (hl)
  JUMP_NZ(CMLineChkEnd)
CMLineChkVerXHit:       ;x-coord of ball equals line's
  inc hl
  ld a, (LineOffs1)     ;is y-coord less line's low y-coord?
  dec a
  dec a
  cp (hl)
  JUMP_NC(CMLineChkEnd)  ;if so, there's no hit
  ld a, (LineOffs2)       ;is y-coord more than line's high y-coord?
  dec a
  cp (hl)
  JUMP_C(CMLineChkEnd)   ;if so there's no hit
  JUMP_(LineHit)        ;if it got all the way here there's a hit
CMLineChkHorSt:          ;check if ball hits current x-line
  ld hl, (CurPosPtr)
  ld a, (LineOffs1)   ;check if ball is to the left of line
  dec a
  dec a
  cp (hl)
  JUMP_NC(CMLineChkEnd)   ;if so, there's no hit
  ld a, (LineOffs2)     ;check if ball is to the right of line
  dec a
  cp (hl)
  JUMP_C(CMLineChkEnd)  ;if so, there's no hit
CMLineChkHorXHit:        
  inc hl
  ld a, (LinePos)        ;check if y-coords match
  cp (hl)
  JUMP_Z(LineHit)
  dec a
  cp (hl)
  JUMP_NZ(CMLineChkEnd)  ; othervise, start checking of old-line-hits
  JUMP_(LineHit)
CMLineChkEnd:
  ld hl, tmp
  bit 0, (hl)
  jr z, CMNotTop        ;check if top-pixels are 1
  bit 1, (hl)
  jr z, CMNotTop  
  ld hl, (CurPosPtr)    ;if they are, continue here
  inc hl                ;move ball down
  inc (hl)
  ld hl, YBallDir       ;change y-direction of ball
  CALL_(ChangeDir)
  JUMP_(CMNotBot)
CMNotTop:
  ld hl, tmp
  bit 2, (hl)
  jr z, CMNotBot
  bit 3, (hl)
  jr z, CMNotBot
  ld hl, (CurPosPtr)
  inc hl
  dec (hl)
  ld hl, YBallDir
  CALL_(ChangeDir)
CMNotBot:
  ld hl, tmp
  bit 0, (hl)
  jr z, CMNotLeft
  bit 3, (hl)
  jr z, CMNotLeft
  ld hl, (CurPosPtr)
  inc (hl)
  ld hl, XBallDir
  CALL_(ChangeDir)
  jr CMNotRight
CMNotLeft:
  ld hl, tmp
  bit 1, (hl)
  jr z, CMNotRight
  bit 2, (hl)
  jr z, CMNotRight
  ld hl, (CurPosPtr)
  dec (hl)
  ld hl, XBallDir
  CALL_(ChangeDir)
CMNotRight:
  ret

MoveBall:
  ld hl, (CurPosPtr)
  ld a, (clock)
  ld ix, XBallMove      
  or (ix)
  ld d, a
  ld ix, CurBall
  ld b, (ix)
  dec b
  jr z, MBNSRLX1
MBChkX:
  srl d
  djnz MBChkX
MBNSRLX1:
  ld a, d
  and $01
  JUMP_Z(MBStartY)      ;if x-ball movement is 0 and clock is 0, goto y-move
  ld a, (XBallDir)
  ld d, a
  ld ix, CurBall
  ld b, (ix)
  dec b
  jr z, MBNSRLX2
MBMovX:
  srl d
  djnz MBMovX
MBNSRLX2:
  ld a, d
  and $01
  jr z, MBDecX
  inc (hl)
  jr MBStartY
MBDecX:
  dec (hl)
MBStartY:
  inc hl
  ld a, (clock)
  ld ix, YBallMove
  or (ix)
  ld d, a
  ld ix, CurBall
  ld b, (ix)
  dec b
  jr z, MBNSRLY1
MBChkY:
  srl d
  djnz MBChkY
MBNSRLY1:
  ld a, d
  and $01
  ret z               ;if y-ball movement is 0 and clock is 0, return
  ld a, (YBallDir)    ;check move-direction
  ld d, a
  ld ix, CurBall
  ld b, (ix)
  dec b
  jr z, MBNSRLY2
MBMovY:
  srl d
  djnz MBMovY
MBNSRLY2:
  ld a, d
  and $01
  jr z, MBDecY
  inc (hl)            ;increase coord if positive move-direction.....         
  ret
MBDecY:
  dec (hl)            ;decrease if negative
  ret

RandomBalls:
  ld hl, XBallDir       ;Randomize ball pos and movement
  ld b, $04
RBStl1:                 ;generate randoms for move and directions
  ld a, r
  ld (hl), a
  inc hl
  djnz RBStl1

  ld hl, XPosB1         ;generate randoms within screen for positions
  ld b, $08
RBStl2:
  ld a, r
  cp $03        ;check if number is in range
  jr c, RBStl2
  cp $5c
  jr nc, RBStl2
  ld (hl), a
  inc hl
RBStl3:
  ld a, r
  cp $03
  jr c, RBStl3
  cp $3c
  jr nc, RBStl3
  ld (hl), a
  inc hl
  djnz RBStl2
  ret

DrawBalls:
  ld a, (XPos)      ;toggle pixels under cursor
  ld b, a
  ld a, (YPos)
  ld c, a
  CALL_(ChgPixel)
  inc b
  CALL_(ChgPixel)
  dec b
  dec b
  CALL_(ChgPixel)
  inc b
  inc c
  CALL_(ChgPixel)
  dec c
  dec c
  CALL_(ChgPixel)
  ld a, (LastMove)
  cp $00
  jr nz, DBVerCursor
  inc c
  dec b
  dec b
  CALL_(ChgPixel)
  inc b
  inc b
  inc b
  inc b
  CALL_(ChgPixel)
  jr DBCursorDone
DBVerCursor:
  dec c
  CALL_(ChgPixel)
  inc c
  inc c
  inc c
  inc c
  CALL_(ChgPixel)
DBCursorDone:
  ld hl, XPosB1     ;toggle pixels under all balls
  ld a, $00
DBStl1:
  inc a
  ld (CurBall), a
  ld b, (hl)
  inc hl
  ld c, (hl)
  inc hl
  push hl
  CALL_(ChgPixel)
  inc b
  CALL_(ChgPixel)
  inc c
  CALL_(ChgPixel)
  dec b
  CALL_(ChgPixel)
  ld a, (CurBall)
  ld hl, NumBalls
  cp (hl)
  pop hl
  jr nz, DBStl1
  ret

DrawLine:
  ld a, (clock)       ; These lines makes line increase with one pixel
  cp $00              ; 3/4 loops (balls moves 1 pixel/loop at most)
  jr nz, DLDoIt       ; (default setting)
  ld a, (clock2)      ;         /\
  cp $00              ;       / || \
  ret z               ;         ||
DLDoIt:               ;         ||
;  ld a, (clock)       ; Uncomment these 3 lines if you'ld like the line
;  cp $00              ; to increase by one pixel every second loop. (hard)
;  ret z               ; And comment out the default setting (abobve).
; If you'ld like line to increase by one pixel every loop (easy)
; then comment out both the functions abobve
  ld a, (LinePos)         ;check if there is a current line
  cp $00
  ret z                   ;if not return
  ld a, (LineDir)         ;check direction of line
  cp $00
  JUMP_NZ(DLVer)
  ld a, (LinePos)         ;Line was horisontal
  ld c, a
  ld a, (LineOffs1)       
  dec a
  ld b, a
  CALL_(GetPixel)         ;check if the pixel to the left of line 1 is black
  cp $00
  jr nz, DLH1Done
  ld a, (LineOffs1)
  dec a
  ld (LineOffs1), a       ;otherwise draw another pixel
  CALL_(SetPixel)
DLH1Done:
  ld a, (LineOffs2)
  inc a
  ld b, a
  CALL_(GetPixel)
  cp $00
  jr nz, DLH2Done
  ld a, (LineOffs2)
  inc a
  ld (LineOffs2), a
  CALL_(SetPixel)
  ret                     ;if second part of line was not done, return
DLH2Done:
  ld a, (LineOffs1)       ;check if first part of line is done
  dec a
  ld b, a
  CALL_(GetPixel)
  cp $00
  ret z                   ;if not, return
  ld a, (LineOffs1)       ;check won areas abowe(however that damn word is spelled)line
  ld (RectX1), a
  ld b, a
  ld a, (LineOffs2)
  ld (RectX2), a
  ld a, (LinePos)
  dec a
  ld c, a
  ld (RectY2), a
  CALL_(GetPixel)       ;if line is just below a black area, bail out
  cp $00
  jr nz, DLHUnderStart
  inc c
DLHStl1:
  dec c
  CALL_(GetPixel)
  cp $00
  jr z, DLHStl1
  inc c
  ld a, c
  ld (RectY1), a
  CALL_(CheckRect)        ;call procedure to check if any ball is inside rect and draw rect if not
DLHUnderStart:
  ld a, (LinePos)         ;check won areas under line
  inc a
  ld c, a
  ld (RectY1), a
  ld a, (LineOffs1)
  ld b, a
  CALL_(GetPixel)
  cp $00                  ;if line is just abobve a black area, bail out
  jr nz, DLHUDone
  dec c
DLHUStl1:
  inc c
  CALL_(GetPixel)
  cp $00
  jr z, DLHUStl1
  dec c
  ld a, c
  ld (RectY2), a
  CALL_(CheckRect)        ;call procedure to check if any ball is
DLHUDone:
  ld a, $00               ;indicate that there's no active line
  ld (LinePos), a
  ret
DLVer:                    ;Vertical line
  ld a, (LinePos)
  ld b, a
  ld a, (LineOffs1)       ;add one pixel to top to line
  dec a
  ld c, a
  CALL_(GetPixel)
  cp $00
  jr nz, DLV1Done
  ld a, (LineOffs1)
  dec a
  ld (LineOffs1), a
  CALL_(SetPixel)
DLV1Done:
  ld a, (LineOffs2)       ;add one pixel from bottom
  inc a
  ld c, a
  CALL_(GetPixel)
  cp $00
  jr nz, DLV2Done
  ld a, (LineOffs2)
  inc a
  ld (LineOffs2), a
  CALL_(SetPixel)
  ret  
DLV2Done:
  ld a, (LineOffs1)
  dec a
  ld c, a
  CALL_(GetPixel)
  cp $00
  ret z
  ld a, (LineOffs1)       ;check won areas to the left of line
  ld c, a               
  ld (RectY1), a
  ld a, (LineOffs2)
  ld (RectY2), a
  ld a, (LinePos)
  dec a
  ld b, a
  ld (RectX2), a
  CALL_(GetPixel)
  cp $00
  jr nz, DLVUnderStart
  inc b
DLVStl1:
  dec b
  CALL_(GetPixel)
  cp $00
  jr z, DLVStl1
  inc b
  ld a, b
  ld (RectX1), a
  CALL_(CheckRect)        ;call procedure to check if any ball is within area and to draw rect if not
DLVUnderStart:
  ld a, (LineOffs1)
  ld c, a               ;check won areas on the right of line
  ld a, (LinePos)
  inc a
  ld b, a
  ld (RectX1), a
  CALL_(GetPixel)
  cp $00
  jr nz, DLVUDone
  dec b
DLVUStl1:
  inc b
  CALL_(GetPixel)         ;loop until white pixel is found
  cp $00
  jr z, DLVUStl1
  dec b
  ld a, b
  ld (RectX2), a
  CALL_(CheckRect)        ;call procedure to check if any ball is
DLVUDone:
  ld a, $00               ;finsh line off
  ld (LinePos), a
  ret

InitLine:
  ld a, (LinePos)         ;return if there already is a line
  cp $00
  ret nz
  ld a, (XPos)            ;check if it's black under the cursor, if so return
  ld b, a                 ;note that black=white when the cursor is drawed
  ld a, (YPos)            ;(it is now), since it inverts what's under it
  ld c, a
  CALL_(GetPixel)
  cp $00
  ret z
  ld a, (LastMove)        ;check direction of line
  ld (LineDir), a         
  cp $00
  JUMP_Z(InitLineHor)     
  ld a, (XPos)            ;line will be vertical
  ld (LinePos), a
  ld a, (YPos)
  inc a
  ld (LineOffs1), a       ;the line going upwards will start one pixel down
  dec a                   ;so there won't be a gap between the two lines
  ld (LineOffs2), a
  ret
InitLineHor:
  ld a, (YPos)
  ld (LinePos), a
  ld a, (XPos)
  inc a                   ;the line going to the left will start one pixel
  ld (LineOffs1), a       ;to the right so there won't be a gap.
  dec a
  ld (LineOffs2), a
  ret

MoveUp:
  ld a, (YPos)
  cp $02
  ret z
  ld ix, Move
  set 2, (ix)
  ld a, $00
  ret

MoveDown:
  ld a, (YPos)
  cp $3d
  ret z
  ld ix, Move
  set 3, (ix)
  ld a, $00
  ret

MoveLeft:
  ld a, (XPos)
  cp $02
  ret z
  ld ix, Move
  set 0, (ix)
  ret

MoveRight:
  ld a, (XPos)
  cp $5d
  ret z
  ld ix, Move
  set 1, (ix)
  ret


GetPixel:  ;  X-value in b, Y-value in c   
  ld a, $3f
  sub c
  ld c, a
  ROM_CALL(FIND_PIXEL)
  ld de, VIDEO_MEM
  add hl, de
  and (hl)
  ld d, a
  ld a, $3f
  sub c
  ld c, a
  ld a, d
  ret     ;a=nonzero:pixel is 1, a=zero:pixel is 0

ChgPixel:  ;  X-value in b, Y-value in c   
  ld a, $3f
  sub c
  ld c, a
  ROM_CALL(FIND_PIXEL)
  ld de, VIDEO_MEM
  add hl, de
  xor (hl)
  ld (hl), a
  ld a, $3f
  sub c
  ld c, a
  ret

SetPixel:  ;  X-value in b, Y-value in c   
  ld a, $3f
  sub c
  ld c, a
  ROM_CALL(FIND_PIXEL)
  ld de, VIDEO_MEM
  add hl, de
  or (hl)
  ld (hl), a
  ld a, $3f
  sub c
  ld c, a
  ret

ResPixel:  ; X-value in b, Y-value in c   
  ld a, $3f
  sub c
  ld c, a
  ROM_CALL(FIND_PIXEL)
  ld de, VIDEO_MEM
  add hl, de
  cpl
  and (hl)
  ld (hl), a
  ld a, $3f
  sub c
  ld c, a
  ret

DrawFrame:
  ld c, $00
DFStl1:
  ld b, $5f
DFStl2:
  CALL_(SetPixel)
  djnz DFStl2
  CALL_(SetPixel)
  inc c
  ld a, c
  cp $01
  jr z, DFStl1
  cp $02
  JUMP_Z(DFGoDown)
  cp $3f
  jr z, DFStl1      ;horisontal lines drawed
  ld b, $00
DFStl3:
  ld c, $02
DFStl4:
  CALL_(SetPixel)
  inc c
  ld a, c
  cp $3e
  jr nz, DFStl4
  inc b
  ld a, b
  cp $01
  jr z, DFStl3
  cp $02
  JUMP_Z(DFGoRight)
  cp $5f
  jr z, DFStl3
  ld hl, ScoreText      ;print score-text
  ld de, (PROGRAM_ADDR)
  add hl, de
  ld a, $67
  ld (CURSOR_X), a
  ld a, $01
  ld (CURSOR_Y), a
  ROM_CALL(D_ZM_STR)
  ld hl, LivesText      ;print lives-text
  add hl, de
  ld a, $67
  ld (CURSOR_X), a
  ld a, $10
  ld (CURSOR_Y), a
  ROM_CALL(D_ZM_STR)
  ld hl, HiScoreText    ;print "HiScore"
  add hl, de
  ld a, $64
  ld (CURSOR_X), a
  ld a, $20
  ld (CURSOR_Y), a
  ROM_CALL(D_ZM_STR)
  ld hl, HiScore
  add hl, de
  call LD_HL_MHL
  ld a, $67
  ld (CURSOR_X), a
  ld a, $27
  ld (CURSOR_Y), a
  CALL_(PrintNumber)
  ld de, (PROGRAM_ADDR)
  ld hl, ByText
  add hl, de
  ld a, $6d
  ld (CURSOR_X), a
  ld a, $2e
  ld (CURSOR_Y), a
  ROM_CALL(D_ZM_STR)
  ld hl, HiName
  add hl, de
  ld a, $6b
  ld (CURSOR_X), a
  ld a, $35
  ld (CURSOR_Y), a
  ROM_CALL(D_ZM_STR)
  CALL_(DrawScore)
  CALL_(DrawLives)
  ld a, $30             ;init values
  ld (XPos), a          
  ld a, $20
  ld (YPos), a
  ret
DFGoDown:
  ld c, $3e
  JUMP_(DFStl1)
DFGoRight:
  ld b, $5e
  JUMP_(DFStl3)

GameOver:
  ld de, (PROGRAM_ADDR)
  ld hl, HiScore
  add hl, de
  call LD_HL_MHL
  ld de, (Score)
  call CP_HL_DE
  JUMP_C(EnterIntls)
  ld de, (PROGRAM_ADDR)
  ld hl, GameOverText
  add hl, de
  ld a, $04           
  ld (CURSOR_COL), a
  ld a, $03
  ld (CURSOR_ROW), a
  ROM_CALL(D_ZT_STR)
GOKeyLoop:
  call GET_KEY
  cp $36
  jr z, GOCont
  cp $37
  jr z, GOCont
  cp $09
  jr nz, GOKeyLoop
GOCont:
  CALL_(LeaveGame)
  ret

LeaveGame:
  ld a, (OldContrast)   ;reset contrast
  ld (CONTRAST), a
	out (2),a
  ld a, $01
  ld (ZS_BITS), a
  ret

StartIntro:
  ld de, (PROGRAM_ADDR)     ;copy logo to graph-mem
  ld hl, IntroImage
  add hl, de
  ld de, VIDEO_MEM
  ld bc, $0100
  ldir
  set 3, (IY+05)            ;print first text inverse
  ld a, $00
  ld (CURSOR_COL), a
  ld a, $03
  ld (CURSOR_ROW), a
  ld de, (PROGRAM_ADDR)
  ld hl, IntroText1
  add hl, de
  ROM_CALL(D_ZT_STR)
  ld hl, IntroText2         ;draw scroll-bar-text
  add hl, de
  ld a, $16
  ld (CURSOR_X), a
  ld a, $21
  ld (CURSOR_Y), a
  ROM_CALL(D_ZM_STR)
  ld hl, IntroText3
  add hl, de
  ld a, $16
  ld (CURSOR_X), a
  ld a, $2e
  ld (CURSOR_Y), a
  ROM_CALL(D_ZM_STR)
  ld hl, IntroText4         ;draw "press enter..." text
  add hl, de
  ld a, $53
  ld (CURSOR_X), a
  ld a, $3a
  ld (CURSOR_Y), a
  ROM_CALL(D_ZM_STR)
  ld c, $28                 ;draw scroll-bars
  CALL_(DoScrollRect)
  ld c, $35
  CALL_(DoScrollRect)
  CALL_(InitSpeedScroll)    ;get old speed-value
  CALL_(InitContrScroll)    ;get old contrast-increase
  ld c, $29                 ;draw scrollbar-pointers
  CALL_(DrawSBCursor)
  ld a, $00
  ld (ActiveControl), a
SIStl:                  ; Intro key-loop start
  call GET_KEY
  ld (tmp), a
  cp $37
  jr nz, SINotExit
  ld a, (CONTRAST)
  ld (OldContrast), a
  JUMP_(LeaveGame)
SINotExit:
  cp $38
  jr nz, SINotMore
  CALL_(PrintScreen)
  jr SIStl
SINotMore:
  cp $01
  jr nz, SINot1
  ld a, (ActiveControl)
  cp $00          
  jr nz, SINot1
  CALL_(ToggleActive)
  ld a, $01
  ld (ActiveControl), a
SINot1:
  ld a, (tmp)
  cp $04
  jr nz, SINot4
  ld a, (ActiveControl)
  cp $00        
  jr z, SINot4
  CALL_(ToggleActive)
  ld a, $00
  ld (ActiveControl), a
SINot4:
  ld a, (tmp)
  cp $09
  JUMP_Z(AfterIntro)
  cp $55
  JUMP_Z(AfterIntro)
  cp $03
  jr nz, SINotRight
  ld a, (ActiveControl)
  cp $00
  jr nz, SIACRConst
  ld a, $00
  CALL_(ChangeSpeed)
  jr SINotRight
SIACRConst:
  ld a, $02
  CALL_(ChangeContr)
SINotRight:
  ld a, (tmp)
  cp $02
  JUMP_NZ(SIStl)
  ld a, (ActiveControl)
  cp $00
  jr nz, SIACLConst
  ld a, $02
  CALL_(ChangeSpeed)
  JUMP_(SIStl)
SIACLConst:
  ld a, $00
  CALL_(ChangeContr)
  JUMP_(SIStl)

ChangeContr:    ;a=0:decrease, a=2:increase
  ld (tmp2), a
  CALL_(InitContrScroll)  ;erase old
  ld de, (PROGRAM_ADDR)
  ld hl, ContrastDB
  add hl, de
  ld b, (hl)
  ld a, (tmp2)
  add a,b
  dec a         ;new speed in a
  cp $ff        ;check new value
  jr z, CCEnd
  cp $0b
  jr z, CCEnd
  ld (hl), a    ;value was ok...
CCEnd:
  CALL_(InitContrScroll)
  ret

ChangeSpeed:    ;a=0:decrease, a=2:increase
  ld (tmp2), a
  CALL_(InitSpeedScroll)  ;erase old
  ld de, (PROGRAM_ADDR)
  ld hl, SpeedDB
  add hl, de
  ld b, (hl)
  ld a, (tmp2)
  add a,b
  dec a         ;new speed in a
  cp $ff        ;check new value
  jr z, CSEnd
  cp $51
  jr z, CSEnd
  ld (hl), a    ;value was ok...
CSEnd:
  CALL_(InitSpeedScroll)
  ret

ToggleActive:
  ld c, $29
  CALL_(DrawSBCursor)
  ld c, $36
  CALL_(DrawSBCursor)
  ret

DrawSBCursor:   ;y-value in c
  ld b, $14
  CALL_(ChgPixel)
  inc c
  CALL_(ChgPixel)
  inc c
  CALL_(ChgPixel)
  dec c
  dec b
  CALL_(ChgPixel)
  ld b, $6b
  CALL_(ChgPixel)
  dec b
  CALL_(ChgPixel)
  dec c
  CALL_(ChgPixel)
  inc c
  inc c
  CALL_(ChgPixel)
  ret

InitContrScroll:
  ld de, (PROGRAM_ADDR)
  ld hl, ContrastDB
  add hl, de
  ld a, (hl)
  sla a
  sla a
  sla a
  add a, $17
  ld b, a
  ld c, $36
  CALL_(ChgPixel)
  inc c
  CALL_(ChgPixel)
  inc c
  CALL_(ChgPixel)
  ret

InitSpeedScroll:
  ld de, (PROGRAM_ADDR)
  ld hl, SpeedDB
  add hl, de
  ld a, $67
  sub (hl)
  ld b, a
  ld c, $29
  CALL_(ChgPixel)
  inc c
  CALL_(ChgPixel)
  inc c
  CALL_(ChgPixel)
  ret

DoScrollRect:     ;  y-coord in c
  ld a, $00
DSRLineStart:
  inc a
  ld (tmp), a
  ld b, $68
DSRStl1:
  CALL_(SetPixel)
  dec b
  ld a, b
  cp $15
  jr nz, DSRStl1
  inc c
  inc c
  inc c
  inc c
  ld a, (tmp)
  cp $01
  jr z, DSRLineStart
  ld a, c
  sub $05
  ld c, a
  ld b, $16
  CALL_(SetPixel)
  dec c
  CALL_(SetPixel)
  dec c
  CALL_(SetPixel)
  ld b, $68
  CALL_(SetPixel)
  inc c
  CALL_(SetPixel)
  inc c
  CALL_(SetPixel)
  ret

CheckRect:      ;proc to check if there's any balls within rect, otherwise, draw rect
  ld hl, XPosB1
  ld a, $00
  ld b, a    ; b=current ball
CRStl1:
  ld a, (RectX1)
  dec a
  cp (hl)
  jr nc, CRNotInsideX
  ld a, (RectX2)
  cp (hl)
  jr c, CRNotInsideX
  inc hl
  ld a, (RectY1)
  dec a
  cp (hl)
  jr nc, CRNotInside
  ld a, (RectY2)
  cp (hl)
  jr c, CRNotInside
  ret     ;If any ball inside, don't draw rectangle
CRNotInsideX:
  inc hl
CRNotInside:
  inc hl
  inc b
  ld a, (NumBalls)
  cp b
  JUMP_NZ(CRStl1)
  CALL_(DrawRect)   ;If all balls passed test, draw rect
  ret

DrawScore:
  ld hl, (Score)
  ld a, $67
  ld (CURSOR_X), a
  ld a, $07
  ld (CURSOR_Y), a
  CALL_(PrintNumber)
  ret

PrintNumber:       ;number to print in hl, CURSOR_X and Y set 
  ld de, ScoreTxt+4   ;buffer to store ASCII in
  ld b, $05           ;number of digits to print
PNStl1:
  call UNPACK_HL      ;call function to convert from number to digit
  add a, '0'          ;convert digit to ASCII-number for digit
  ld (de), a          ;store in ASCII-buffer
  dec de
  djnz PNStl1         ;loop 5 times
  ld hl, ScoreTxt
  ld b, $05
  res 3, (iy+5)         ;overwrite current screen with menu-texts
  ROM_CALL(D_LM_STR)  ;print it to screen
  ret

DrawLives:
  ld a, (Lives)   
  add a, '0'
  ld (tmp), a
  ld hl, tmp
  ld a, $6f
  ld (CURSOR_X), a
  ld a, $16
  ld (CURSOR_Y), a
  ld b, $01
  res 3, (iy+5)         ;overwrite current screen with menu-texts
  ROM_CALL(D_LM_STR)
  ret

PrintScreen:      ;This routine is written by Ed Plese, Jr. Thank you!
  ld hl,$FC00
  ld de,GRAPH_MEM
  ld bc,1024
  ldir
  ret

CheckArea:
  ld hl, (LastScore)  ;check if 4128 points has been earned at this level
  ld de, $1020   
  add hl, de
  ld de, (Score)
  call CP_HL_DE
  ret nc
  ld a, $01
  ld (LevelDone), a
  ret

NextLevel:
  ld a, $03           ;print "Level Done!"
  ld (CURSOR_COL), a
  ld a, $03
  ld (CURSOR_ROW), a
  ld de, (PROGRAM_ADDR)
  ld hl, LevelText
  add hl, de
  ROM_CALL(D_ZT_STR)
  ld a, $00
  ld (LevelDone), a
  ld hl, (Score)        ;increase score by 1000 for each life left
  ld a, (Lives)
  ld b, a
  ld de, $03e8
NLStl1:
  add hl, de
  djnz NLStl1
  ld (Score), hl
  ld a, (NumBalls)    ;increase number of balls
  inc a
  ld (NumBalls), a
  ld (Lives), a       ;set up number of new lives
  ld a, (Speed)       ;decrease delay since it's slower when there's more balls
  sub $03
  jr c, NLAlreadyMax
  ld (Speed), a
NLAlreadyMax:
  ld b, $ff        ;pause loop
NLPauseStl1:
  ld c, $ff
NLPauseStl2:
  push de
  dec c
  pop de
  jr nz, NLPauseStl2
  dec b
  jr nz, NLPauseStl1
  ROM_CALL(CLEARLCD)
  CALL_(DrawFrame)
  CALL_(RandomBalls)
  ld hl, (Score)
  ld (LastScore), hl
  CALL_(DrawBalls)
  JUMP_(LoopStart)

EnterIntls:
  ld a, $02           ;print "New HiScore"
  ld (CURSOR_COL), a
  ld a, $02
  ld (CURSOR_ROW), a
  ld de, (PROGRAM_ADDR)
  ld hl, NewHiScoreText
  add hl, de
  ROM_CALL(D_ZT_STR)
  ld a, $01           ;print "Enter Initials"
  ld (CURSOR_COL), a               
  ld a, $03
  ld (CURSOR_ROW), a
  ld de, (PROGRAM_ADDR)
  ld hl, EnterIntlsText
  add hl, de
  ROM_CALL(D_ZT_STR)
  ld a, $06           ;print @@@
  ld (CURSOR_COL), a               
  ld a, $04
  ld (CURSOR_ROW), a
  ld a, $41
  ROM_CALL(TX_CHARPUT)
  ROM_CALL(TX_CHARPUT)
  ROM_CALL(TX_CHARPUT)
  ld a, $06           
  ld (CURSOR_COL), a               
  ld b, $41
  ld c, $00
EIKeyLoop:
  call GET_KEY
  cp $04
  jr nz, EINotUp
  dec b
  ld a, b
  cp $40
  jr nz, EIUpNotInc
  inc b
  inc a
EIUpNotInc:
  push bc
  ROM_CALL(TX_CHARPUT)
  pop bc
  jr EIDecCursor
EINotUp:
  cp $01
  jr nz, EINotDown
  inc b
  ld a, b
  cp $5b
  jr nz, EIDownNotInc
  dec a
  dec b
EIDownNotInc:
  push bc
  ROM_CALL(TX_CHARPUT)
  pop bc
  jr EIDecCursor
EINotDown:
  cp $36
  jr nz, EIKeyLoop
  ld hl, HiName         ;update hiscore name
  ld de, (PROGRAM_ADDR)
  ld a, $00
  cp c
  jr z, EIFirstIndex
EINameIndex:
  inc de
  dec c
  jr nz, EINameIndex
  ld c, $01
EIFirstIndex:
  add hl, de
  inc c
  ld (hl), b
  ld b, $41             ;print char and move cursor
  ld a, (CURSOR_COL)
  inc a
  ld (CURSOR_COL), a
  cp $09
  JUMP_NZ(EIKeyLoop)
  ld ix, Score          ;update hiscore
  ld de, (PROGRAM_ADDR)
  ld hl, HiScore
  add hl, de
  ld a, (ix)
  ld (hl), a
  inc ix
  inc hl
  ld a, (ix)
  ld (hl), a
  JUMP_(GOCont)
EIDecCursor:
  ld a, (CURSOR_COL)
  dec a
  ld (CURSOR_COL), a
  JUMP_(EIKeyLoop)

InverseScreen:
  ld hl, VIDEO_MEM
  ld de, $0000    ;video_mem + 1025
ISStl1:
  ld a, (hl)
  xor $ff
  ld (hl), a
  inc hl
  call CP_HL_DE
  jr nz, ISStl1
  ret

GameDone:
  ld de, (PROGRAM_ADDR)
  ld hl, GameDoneText
  add hl, de
  ld a, $00           
  ld (CURSOR_COL), a
  ld a, $01
  ld (CURSOR_ROW), a
  ROM_CALL(D_ZT_STR)
  JUMP_(GameOver)

DrawRect:          
  ld a, (RectX1)      ;first update score
  ld b, a
  ld a, (RectX2)
  sub b
  inc a
  ld c, a
  ld b, $00
  push bc         ;bc=delta x
  ld a, (RectY1)
  ld b, a
  ld a, (RectY2)
  sub b
  inc a             ;a=delta y
  ld hl, (Score)
  pop bc  
DRScoreStl1:
  add hl, bc
  dec a
  jr nz, DRScoreStl1    ;add delta x for each y-line
  ld (Score), hl
  CALL_(DrawScore)    ;update score on screen
  CALL_(CheckArea)  ;check if level is done
;here is where the actual drawing takes place
  ld a, (RectX1)    ;tmp=delta x -1
  ld b, a
  ld a, (RectX2)
  sub b
  ld (tmp), a
  ld a, (RectY1)    ;tmp2=delta y
  ld c, a
  ld a, (RectY2)
  sub c
  inc a
  ld (tmp2), a
  ld a, (RectX1)
  ld b, a           ;load top-left byte in a
  ld a, $3f
  sub c
  ld c, a
  ld a, $00
  ld ix, tmp
  cp (ix)
  JUMP_Z(DROnePixel)
  ROM_CALL(FIND_PIXEL)
  ld ix, tmp
DRStl1:             ;fill top-bits in a (or as many as specified in tmp)
  ld b, a
  srl a
  or b
  dec (ix)
  jr z, DRDone1
  bit 0, a
  jr z, DRStl1
DRDone1:              ;or the bits onto the screen
  ld c, a
  ld de, VIDEO_MEM
  add hl, de
  ld (tmp3), hl
  ld a, (tmp2)
  ld b, a
  ld de, $10
DRStl2:
  ld a, (hl)
  or c
  ld (hl), a
  add hl, de
  djnz DRStl2
  ld a, (tmp)       ;return if no columns left to fill
  cp $00
  ret z
DR8bitStl1:
  ld hl, (tmp3)     ;move hl-pointer to top-line, next 8-bit col
  inc hl
  ld (tmp3), hl
  ld a, (tmp)
  cp $08            ;check if 8-cols are left to set
  jr c, DR8bitDone
  sub $08
  ld (tmp), a       ;decrease x-cols-left with 8 cols
  ld a, (tmp2)
  ld b, a
DR8bitStl2:         ;fill it up!
  ld (hl), $ff
  add hl, de
  djnz DR8bitStl2
  jr DR8bitStl1
DR8bitDone:
  ld a, (tmp)     ;fill last pixels
  cp $00                                     
  ret z
  ld c, $80
DRFinalStl1:      ;start loop of pixels to fill
  ld a, (tmp)
  dec a
  jr z, DRFinalDone
  ld (tmp), a
  ld a, c
  srl a
  or c
  ld c, a
  jr DRFinalStl1
DRFinalDone:      ;or the bits onto the screen
  ld a, (tmp2)
  ld b, a
  ld de, $10
DRFinalStl2:
  ld a, (hl)
  or c
  ld (hl), a
  add hl, de
  djnz DRFinalStl2
;this is the end of the draw-code
  ld a, (RectX2)    ;now check if the damn bug has occured
  ld b, a
  ld a, (RectY1)
  ld c, a
  CALL_(GetPixel)
  cp $00
  ret nz            ;if not return
DRFixBugStl1:       ;if it has, fill the last line
  CALL_(SetPixel)
  inc c
  ld a, (RectY2)
  cp c
  jr nc, DRFixBugStl1
  ret
DROnePixel:     ;also part of drawrect
  ROM_CALL(FIND_PIXEL)
  JUMP_(DRDone1)

MoveCursor:
  ld ix, Move
  bit 0, (ix)
  jr z, MCNotLeft
  ld a, (XPos)
  dec a
  ld (LastMove), a
  ld (XPos), a
  res 0, (ix)
MCNotLeft:
  bit 1, (ix)
  jr z, MCNotRight
  ld a, (XPos)
  inc a
  ld (LastMove), a
  ld (XPos), a
  res 1, (ix)
MCNotRight:
  bit 2, (ix)
  jr z, MCNotUp
  ld a, (YPos)
  dec a
  ld (YPos), a
  res 2, (ix)
  ld a, $00
  ld (LastMove), a
MCNotUp:
  bit 3, (ix)
  ret z
  ld a, (YPos)
  inc a
  ld (YPos), a
  res 3, (ix)
  ld a, $00
  ld (LastMove), a
  ret

RotateCursor:
  ld a, (RotateCount)
  cp $00
  ret nz
  ld a, $ff
  ld (RotateCount), a
  ld a, (LastMove)
  cp $00
  jr z, RCIsZero
  ld a, $00
  ld (LastMove), a
  ret
RCIsZero:
  ld a, $01
  ld (LastMove), a
  ret

IntroImage:
.db $7F, $F9, $FF, $E7, $FF, $9F, $FE, $7F
.db $F8, $3F, $F8, $F8, $07, $C0, $00, $00, $00, $F9, $F0, $00, $0F, $80, $3E, $7C
.db $FC, $7E, $FC, $F8, $07, $C0, $00, $00, $00, $F9, $F0, $00, $1F, $00, $7C, $7C
.db $7C, $7C, $7C, $F8, $07, $C0, $00, $00, $00, $F9, $F0, $00, $1E, $00, $78, $7C
.db $7C, $7C, $7C, $F8, $07, $C0, $00, $00, $00, $F9, $F0, $00, $3E, $00, $F8, $7C
.db $7C, $7C, $7C, $F8, $07, $C0, $00, $00, $00, $F9, $FF, $00, $FF, $03, $FC, $7F
.db $F8, $7F, $FC, $F8, $07, $C0, $00, $00, $00, $F9, $F0, $00, $7C, $01, $F0, $7C
.db $7C, $7C, $7C, $F8, $07, $C0, $00, $00, $00, $F9, $F0, $00, $78, $01, $E0, $7C
.db $3E, $7C, $7C, $F8, $07, $C0, $00, $00, $00, $F9, $F0, $00, $F8, $03, $E0, $7C
.db $3E, $7C, $7C, $F8, $07, $C0, $00, $00, $78, $F9, $F0, $01, $F0, $07, $C0, $7C
.db $3E, $7C, $7C, $F8, $07, $C0, $00, $00, $78, $F9, $F0, $01, $F0, $07, $C0, $7C
.db $3E, $7C, $7C, $F8, $07, $C0, $03, $04, $78, $F9, $F0, $03, $E0, $0F, $80, $7C
.db $3E, $7C, $7C, $F8, $07, $C0, $04, $8C, $78, $F9, $F0, $03, $C0, $0F, $00, $7C
.db $3E, $7C, $7C, $F8, $07, $C0, $50, $84, $78, $F9, $F0, $07, $C0, $1F, $00, $7C
.db $3E, $7C, $7C, $F8, $07, $C0, $53, $04, $7D, $F9, $F0, $07, $C0, $1F, $00, $7C
.db $3E, $7C, $7C, $F8, $07, $C0, $54, $04, $3F, $F1, $FF, $E7, $FF, $9F, $FE, $7F
.db $FC, $7C, $7C, $FF, $E7, $FF, $27, $A4


SpeedDB:  .db $20
ContrastDB: .db $05
IntroText1: .db "By Magnus Svedin  -96",0
IntroText2: .db "Speed",0
IntroText3: .db "Contrast increase",0
IntroText4: .db "Press Enter...",0
GameDoneText: .db "That's all folks", 0
ScoreText: .db "Score", 0
LivesText: .db "Lives", 0
HiScoreText: .db "HiScore", 0
ByText: .db "By:", 0
HiScore: .db $10, $27
HiName: .db "MSv", 0
LevelText: .db "Level done!", 0
GameOverText: .db "GAME OVER", 0
NewHiScoreText: .db "New HiScore!", 0
EnterIntlsText: .db "Enter initials", 0
.end


