
; ***********************
; *                     *
; *  'BOULDER BOMBERS'  *
; *         by          *
; *     Mark Price      *
; *                     *
; ***********************
;
; ZERO-PAGE VARIABLES
;
    *=  $12
;
CLOCK DB    1
DELYVAL DB    1
DIR DB    1
EXPLODE DB    1
HOLDIT DB    1
MASK DB    1
ONSCR DB   1
PLAY DB    1
PLAYERS DB    1
RKILL DB    1
TDIR DB    1
XCOUNT DB    1
YCOUNT DB    1
BMBDRP DB    1,1
BRUN   DB  1,1
DRPFREQ  DB 1,1
DRPRATE  DB 1,1
FREMEN  DB 1,1
BOMBS DB 1,1
PLYRX DB 1,1
PLYRY DB 1,1
RCKHIT  DB 1,1
ROCKS  DB 1,1
SCRPTR DB 1,1
;
; KEYBOARD VARIABLES
;
CH  =   $02FC
CH1 =   $02F2
;
PMAREA = $3000
PL0 =   PMAREA+1024
PL1 =   PL0+256
PL2 =   PL1+256
PL3 =   PL2+256
;
ROMCH = $E000   ;ROM CHR SET
CHARS = $2C00   ;MY CHR SET
;
; SYSTEM EQUATES
;
AUDCTL = $D208
AUDC1 = $D201
AUDC2 = $D203
AUDC3 = $D205
AUDC4 = $D207
AUDF1 = $D200
AUDF3 = $D204
AUDF4 = $D206
CHBASE = $D409
COLBAK = $D01A
COLPF0 = $D016
COLPF1 = $D017
COLPF2 = $D018
COLPF3 = $D019
COLPM0 = $D012
COLPM1 = $D013
COLPM2 = $D014
COLPM3 = $D015
CONSOL = $D01F
DLIST = $D402
DMACTL = $D400
SDMCTL = $022F
GRACTL = $D01D
HITCLR = $D01E
HPOSP0 = $D000
HPOSP1 = $D001
HPOSP2 = $D002
HPOSP3 = $D003
NMIEN = $D40E
PL2PF = $D006
PMBASE = $D407
PORTA = $D300
RANDOM = $D20A
SIZEP0 = $D008
SKCTL = $D20F
TRIG0 = $D010
;
    *=  $2000
;
INIT LDX #111   ;COPY MY CHARS
MYCHRS LDA MYCHARS,X
    STA CHARS,X
    DEX
    BPL MYCHRS
    LDA #0      ;DISABLE VBI
    STA NMIEN
    LDA #$34    ;SET COLORS
    STA COLPF0
    LDA #$28
    STA COLPF1
    LDA #$84
    STA COLPF2
    LDA #$C4
    STA COLPF3
    LDA #0
    STA COLBAK
    LDX #3      ;INIT PLAYERS
STWIDTH STA SIZEP0,X
    DEX
    BPL STWIDTH
    LDA #$28
    STA COLPM0
    LDA #$84
    STA COLPM1
    LDA #$C8
    STA COLPM2
    LDA #$C8
    STA COLPM3
    LDA # >PMAREA
    STA PMBASE
    LDA #$3E
    STA DMACTL
    LDA #3
    STA GRACTL
    LDY #112    ;INIT CHR SET
SETCH1 LDA ROMCH,Y
    STA CHARS,Y
    INY
    BNE SETCH1
SETCH2 LDA ROMCH+256,Y
    STA CHARS+256,Y
    INY
    BNE SETCH2
    LDA # >CHARS
    STA CHBASE
    LDA #0      ;INIT VARS
    LDY #SCRPTR+1-CLOCK
ZEROVAR STA CLOCK,Y
    DEY
    BPL ZEROVAR
    LDY #$27    ;SET SCREEN DISP
CLRTOP STA CANYON,Y
    DEY
    BPL CLRTOP
    JSR SETSCRN
    LDA #0      ;INIT SOUND
    STA AUDCTL
    LDA #3
    STA SKCTL
    LDA #56     ;SET PLAYER
    STA PLYRY   ;  LANES
    LDA #72
    STA PLYRY+1
;
RESTART LDA #44 ;SET PLAYER
    STA PLYRX   ; START
    LDA #204    ; POSITIONS
    STA PLYRX+1
    LDA #0      ;TURN OFF SCREEN
    STA DMACTL
    STA AUDC3   ; EXPLOSIONS,
    STA EXPLODE
    STA AUDC4   ; AND BKG SOUND
    JSR PMCLR   ;CLEAR PLAYERS
    LDA # <DLIST1 ;SET TITLE
    STA DLIST   ; SCREEN
    LDA # >DLIST1
    STA DLIST+1
    LDA #$FF    ;SET GAME SPEED
    STA DELYVAL ; FOR TITLES
    LDA #1      ;SET START DIR
    STA DIR
    STA PLAY    ;SET PLAY FALSE
    LDA #0      ;PLAYERS NOT
    STA ONSCR   ; ON SCREEN
    LDA #$3E    ;TURN SCREEN
    STA DMACTL  ; BACK ON
    LDA #3      ; INIT CLOCK
    STA CLOCK
GTCNSL LDA CONSOL ;CHECK CONSOL
    AND #3      ; SWITCHES
    CMP #1      ;SELECT PRESSED?
    BNE CHKSTRT ; NO, TRY START
SELECT LDA CONSOL ; YES, WAIT FOR
    AND #2      ; KEY RELEASE
    BEQ SELECT
    LDA PLAYERS ;CHANGE # OF
    EOR #1      ; PLAYERS
    STA PLAYERS
    CLC
    ADC #$11    ; & SET ON SCREEN
    STA SCNOPLR
    BNE MOVET   ;(MOVE PLAYERS)
CHKSTRT CMP #2  ;IF START THEN
    BEQ START   ; START GAME
MOVET LDA ONSCR ;IF ON SCREEN,
    BNE MOVIT   ; THEN MOVE
    LDA RANDOM  ;ELSE, PICK OUT
    AND #1      ; NEW SHIP TYPE
    TAX
    LDA MASKS,X
    STA MASK    ; & SET IT
MOVIT JSR MOVEPLR ;MOVE PLAYERS
    JMP GTCNSL  ;DO CHECK AGAIN
;
START LDA CONSOL ;WAIT FOR KEY
    AND #1      ; RELEASE
    BEQ START
    LDA #3      ;SET GAME SPEED
    STA DELYVAL ; TO $FF+$04
    LDA #0      ;SET PLAY TRUE
    STA PLAY
    STA DMACTL  ;TURN OFF SCREEN
    LDX #2      ;SET SCORES TO
ZEROSCR STA SCORE1,X ; ZERO
    STA SCORE2,X
    DEX
    BPL ZEROSCR
    LDA #$10
    STA SCORE1+3
    STA SCORE2+3
    LDX #2      ;SET BOMBS LEFT
    LDA #$CD    ; TO THREE
STBMBC STA BOMB1,X
    STA BOMB2,X
    DEX
    BPL STBMBC
    LDA #3
    STA BOMBS
    STA BOMBS+1
    LDA #$11    ;SET NEXT FREE
    STA FREMEN  ; BOMB AT 1000
    STA FREMEN+1
    LDA PLAYERS ;SET SECOND
    ASL A       ; PLAYER MESSAGE
    ASL A       ; TO 'PLAYER 2'
    ASL A       ; OR 'COMPUTER'
    LDX #7
    TAY
STP2MS LDA P2COMPT,Y
    STA P2MSG,X
    INY
    DEX
    BPL STP2MS
    LDA # <DLIST2 ;SET DLIST
    STA DLIST   ; TO GAME
    LDA # >DLIST2 ; SCREEN
    STA DLIST+1
    LDA #$3E    ;TURN ON SCREEN
    STA DMACTL
;
NEWSCRN JSR SETSCRN ;SET CANYON
    LDA #3      ;SET TYPE TO
    STA MASK    ; BALLOON
    STA CLOCK   ;AND BEGIN CLOCK
    LDA #1
    STA DIR     ;DIR = RIGHT
    STA ROCKS+1 ;ROCKS IN
    LDA #42     ; CANYON=298
    STA ROCKS
    JSR PMCLR   ;CLEAR PLAYERS
    LDA #0      ;SET PLAYERS ON
    STA ONSCR   ; SCREEN=FALSE
    STA AUDF4
    LDA #44     ;SET START
    STA PLYRX   ; POSITIONS
    LDA #204    ; OF PLAYERS
    STA PLYRX+1
    STA HITCLR  ;CLEAR HITS
    LDA #8      ;#ROCKS PER BOMB
    STA RKILL   ; (MAX) =8
    LDA DELYVAL ;SPEED UP THE
    CMP #$AF    ; GAME JUST A BIT
    BEQ BMBLOOP ; (UNLESS ALREADY
    SEC         ; AT MAX SPEED)
    SBC #4
    STA DELYVAL
;
; BOMB MOVEMONT, HIT CHECKS,
; SCORE AND HIGHSCORE SET
;
BMBLOOP LDX #1  ;GET PLAYER INDEX
BMBNLOP LDA BMBDRP,X ;IF BOMB NOT
    BNE CHKHITS ; DROPPED
    JMP CHKDRP  ; CHECK TRIG
CHKHITS LDA PL2PF,X ;BOMB HIT
    BNE CKHROK  ; ANYTHING?
    JMP LWRBMB  ; NO,MOVE BOMB
CKHROK AND #7   ;IF HIT ONLY
    BNE BHITRK  ; COLOR 3, IT
    JMP KILLBMB ; GETS ERASED
BHITRK LDA #0   ;SET POINTER
    STA SCRPTR+1 ; INTO SCREEN
    LDA BMBDRP,X ; RAM WHERE THE
    SEC         ; ROCK HIT IS.
    SBC #103    ;1ST, GET BOMB'S
    AND #$F8    ; Y-POS TRANS-
    STA SCRPTR  ; LATED INTO
    ASL SCRPTR  ; ROW NUMBER
    ASL SCRPTR  ;AND MULTIPLY IT
    ROL SCRPTR+1 ; BY 40
    CLC
    ADC SCRPTR
    STA SCRPTR
    BCC GTP0
    INC SCRPTR+1
GTP0 LDA PLYRX,X ;THEN, CHANGE
    SEC         ; X-POS INTO THE
    SBC #47     ; COLUMN NUMBER
    LSR A
    LSR A
    CLC         ;AND ADD IT ON
    ADC SCRPTR
    STA SCRPTR
    BCC GTPA
    INC SCRPTR+1
GTPA CLC        ; ADD SCREEN
    ADC # <CANYON ; START
    STA SCRPTR  ; ADDRESS
    LDA SCRPTR+1
    ADC # >CANYON
    STA SCRPTR+1
    LDY #0      ;CLEAR INDEX
    LDA (SCRPTR),Y ; & GET CHAR
    BEQ GTP1    ;IF IT'S BLANK
    CMP #4      ; OR ABOVE 4
    BCC GOTCHR  ; THIS ISN'T IT.
GTP1 INY        ; TRY AGAIN,ONE
    LDA (SCRPTR),Y ; RIGHT
    BEQ GTP2
    CMP #4
    BCC GOTCHR
GTP2 LDY #$28   ;IF WE STILL
    LDA (SCRPTR),Y ; DON'T GET IT
    BEQ GTP3    ; TRY 1 DOWN
    CMP #4
    BCC GOTCHR
GTP3 INY        ;THEN, BOTH AT
    LDA (SCRPTR),Y ; ONCE
    BNE GCKRCK
    JMP LWRBMB  ;IF BY THIS
GCKRCK CMP #4   ; TIME, WE DONT
    BCC GOTCHR  ; HAVE IT, THEN
    JMP LWRBMB  ; GIVE UP
GOTCHR ASL A    ;HOLD SCORE=
    STA HOLDIT  ; CHAR * 2
    LDA #0      ;ERASE ROCK ON
    STA (SCRPTR),Y ; SCREEN
    LDA ROCKS   ;LOWER # OF
    SEC         ; ROCKS LEFT
    SBC #1
    STA ROCKS
    BCS GOT1
    DEC ROCKS+1
GOT1 LDA #$FE   ;START EXPLOSION
    STA EXPLODE ; SOUND
;
; ADD ON TO SCORE
;
    LDY SCRNDX,X ;GET BASE INDEX
    LDA HOLDIT  ; TO SCORES,AND
    CLC         ; ADD TO SCORE
    ADC SCORE1,Y
    STA SCORE1,Y
    LDA #3      ;SET DIGIT # FOR
    STA HOLDIT  ; ROLLOVER PROT.
ADDSCR LDA SCORE1,Y ;DONE?
    BEQ CHKHI   ; YES, CHECK HIGH
    CMP #26     ;DIGIT >10?
    BCC SCUNDX  ; NO, GO RIGHT
    SEC         ;SUB 10 FROM
    SBC #10     ; THIS DIGIT
    STA SCORE1,Y
    DEY         ;POINT TO NEXT
    DEC HOLDIT
    BMI CHKHI   ;ROLLOVER! LEAVE
    LDA SCORE1,Y ;GET DIGIT
    BNE SCBRK   ;IF BLANK, SET
    LDA #$10    ; TO ZERO
SCBRK CLC       ;ADD 1
    ADC #1
    STA SCORE1,Y ; AND SAVE IT
    BNE ADDSCR  ;CHECK THIS DIGIT
SCUNDX INY      ;GO RIGHT ONE
    INC HOLDIT  ; DIGIT
    BNE ADDSCR
;
; CHECK FOR HIGH SCORE
;
CHKHI LDA # <SCORE1
    STA SCRPTR  ;SET POINTER
    LDA # >SCORE1 ; TO SCORE FOR
    STA SCRPTR+1 ; PLAYER 1
    TXA         ;IF IT ISN'T
    BEQ CHKSCR  ; PLAYER 1, THEN
    LDA #10     ; ADD TO GET
    CLC         ; POINTER FOR
    ADC SCRPTR  ; PLAYER 2
    STA SCRPTR
    BCC CHKSCR
    INC SCRPTR+1
CHKSCR LDY #0   ;BEGIN AT HI END
CHECKSC LDA (SCRPTR),Y
    CMP HISCOR,Y ;COMPARE 'EM
    BEQ CKNXDG  ;IF SAME,DO NEXT
    BCS STHISC  ;IF PLAYER > SET
    BCC CHKFRM  ;IF HIGH > SKIP
CKNXDG INY      ;DO NEXT DIGIT
    CPY #4      ;IF ALL DONE,
    BNE CHECKSC ; THEN IT'S THE
    BEQ CHKFRM  ; SAME, SKIP
;
; SET HIGH SCORE
;
STHISC LDY #3   ;COPY THE
SETDIGT LDA (SCRPTR),Y ; NEW HIGH
    STA HISCOR,Y ; SCORE INTO
    DEY         ; HISCOR
    BPL SETDIGT
;
; CHECK FOR GETTING EXTRA BOMBS
;
CHKFRM LDY SCRNDX,X ;GET SCORE
    LDA SCORE1-3,Y ; IN THOUSANDS
    CMP FREMEN,X ;IF NOT FREE
    BNE STRKHT  ; BOMB YET,SKIP.
    INC BOMBS,X ;ELSE, UP BOMBS
    LDA BOMBS,X ; BY 1
    CMP #4      ;IF BOMBS>=4,
    BCS UPDTFM  ; KEEP IN RESERVE
    CLC         ;IF BOMBS LESS
    ADC SCRNDX,X ; THAN 4, THEN
    TAY         ; SET EXTRA
    LDA #$CD    ; ON SCREEN
    STA BOMB1-4,Y
UPDTFM INC FREMEN,X ;SET FOR NEXT
;
STRKHT INC RCKHIT,X ;IF NEW # OF
    LDA RCKHIT,X ; ROCKS HIT =
    CMP RKILL   ; MAX,KILL BOMB
    BNE LWRBMB  ; ELSE, LOWER IT
KILLBMB TXA     ;SET POINTER
    CLC         ; TO BOMB
    ADC # >PL2
    STA SCRPTR+1
    LDA BMBDRP,X
    STA SCRPTR
    LDY #5      ;AND ERASE IT
    LDA #0
ERABOMB STA (SCRPTR),Y
    DEY
    BPL ERABOMB
KILBOMB TXA     ;TURN OFF SOUND
    ASL A       ; FOR THIS BOMB
    TAY
    LDA #0
    STA AUDF1,Y
    STA AUDC1,Y
    STA BMBDRP,X ;SET FLAG OFF
    LDA RCKHIT,X ;IF IT DIDN'T
    BNE DONXBMB ; HIT ANYTHING,
    JSR LWRMISS ; LOWER # BOMBS
    JMP DONXBMB ; & DO NEXT
;
; LOWER THE BOMBS
;
LWRBMB TXA
    CLC
    ADC # >PL2  ;SET POINTER TO
    STA SCRPTR+1 ; BOMB
    LDA BMBDRP,X
    STA SCRPTR
    LDA #0      ;ERASE THE BOMB
    LDY #5
ERBMB STA (SCRPTR),Y
    DEY
    BPL ERBMB
    INC DRPRATE,X ;UP DROP SPEED
    LDA DRPRATE,X
    LSR A       ;UPDATE POSITION
    LSR A
    LSR A
    LSR A
    STA HOLDIT
    CLC
    ADC BMBDRP,X
    CMP #196    ;OUT OF RANGE?
    BCS KILBOMB ; YES, KILL IT
    STA BMBDRP,X ;ELSE, SET
    STA SCRPTR  ; THE BOMB
    LDY #5
SETBOMB LDA CHARS+96,Y
    STA (SCRPTR),Y
    DEY
    BPL SETBOMB
    TXA         ;SET Y TO INDEX
    ASL A       ; THE SOUND REGS
    TAY
    LDA HOLDIT  ;UPDATE SOUND
    CLC         ; OF DROPPING
    ADC DRPFREQ,X ; BOMB
    STA DRPFREQ,X
    STA AUDF1,Y
    LDA #$A8
    SEC
    SBC HOLDIT
    STA AUDC1,Y
DONXBMB DEX     ;RESET INDEX
    BMI DOPLMV  ;IF BOTH NOT
    JMP BMBNLOP ; DONE, DO NEXT
;
; CHECK & DROP BOMBS
;
CHKDRP LDA BOMBS,X ;IF NO BOMBS LEFT
    BEQ DONXBMB ; THEN DO NEXT
    TXA         ;IF NOT THE
    CLC         ; COMPUTER,CHECK
    SBC PLAYERS ; TRIGGER
    BNE CHKTRG  ;IT'S PLAYER!
    LDA DIR     ;GOING LEFT?
    BMI GOINGR  ;NO!
    LDA PLYRX,X ;GET COMPUTER X
    CMP #$44    ;TOO FAR LEFT?
    BCC DONXBMB ;YES!
    BCS TRYDRP  ;NO, TRY DROP!
GOINGR LDA PLYRX,X ;GET COMP. X
    CMP #$B8    ;TOO FAR RIGHT?
    BCS DONXBMB ;YES!
TRYDRP LDA RANDOM ;COMPUTER DROPS
    AND #15     ; A BOMB IF
    BEQ DROPIT  ; RANDOM SAYS TO
    BNE DONXBMB ;ELSE DO NEXT
CHKTRG LDA TRIG0,X ;TRIG PUSHED?
    BNE DONXBMB ; NO, DO NEXT
DROPIT LDA PLYRY,X ;DROP: SET
    CLC         ; BOMB Y TO
    ADC #8      ; PLAYER Y+8
    STA BMBDRP,X
    LDA #0      ;CLEAR DROP RATE
    STA DRPRATE,X
    STA RCKHIT,X ; AND ROCKS HIT
    INC BRUN,X  ;UP BOMBS DROPPED
    LDA #50     ;SET THE SOUND
    STA DRPFREQ,X ; FLAG
    BNE DONXBMB ;AND DO NEXT
;
DOPLMV STA HITCLR ;CLEAR HITS
    JSR MOVEPLR ;MOVE PLAYERS
    LDA EXPLODE ;EXPLOSION GOING?
    BEQ CKRSTRT ; NO,SKIP
    DEC EXPLODE ;UPDATE EXPLOSION
    DEC EXPLODE ; SOUND
    EOR #$F0
    STA AUDF3
    LSR A
    LSR A
    LSR A
    LSR A
    EOR #$8F
    STA AUDC3
CKRSTRT LDA CONSOL ;ANY CONSOLE
    CMP #7      ; BUTTONS PUSHED?
    BEQ CKNSCR  ;IF YES, THEN
    JMP RESTART ; RE-START
CKNSCR LDA ROCKS ;# OF ROCKS LEFT
    BNE CHKPAUS ; = ZERO?
    LDA ROCKS+1 ;IF YES, THEN
    BNE CHKPAUS ; SET UP A
    JMP NEWSCRN ; NEW SCREEN
CHKPAUS LDA CH  ;SPACEBAR PRESSED?
    CMP #33
    BNE CKDRRCK ;NO, CONTINUE
    LDA #0      ;YES, PAUSE GAME
    STA AUDC1   ;TURN OFF MAIN
    STA AUDC2   ; SOUNDS
    STA AUDC3
HLDPTRN LDA PORTA ;WAIT FOR STICK
    CMP #$FF    ; MOVEMENT
    BEQ HLDPTRN
    LDA #$FF    ;RESET CH FOR
    STA CH      ; ANOTHER PAUSE
    STA CH1
CKDRRCK LDA CLOCK ;TIME TO DROP
    AND #15     ; SUSPENDED
    BEQ DRPROCK ; ROCKS?
    JMP BMBLOOP ;NO, DO BOMBS
DRPROCK LDA #39 ;SET COLUMN TO 39
    STA XCOUNT
DSTYCNT LDA #8  ;ROW TO 8
    STA YCOUNT  ;AND SET POINTER
    LDA <CANYON+360 ; TO XCOUNT
    CLC         ; PLUS CANYON
    ADC XCOUNT  ; START
    STA SCRPTR
    LDA >CANYON+360
    ADC #0
    STA SCRPTR+1
RK2DRP LDY #0   ;ROCK FALL LOOP:
    LDA (SCRPTR),Y ;NOTHING THERE
    BEQ DONXRCK ; THEN TRY NEXT UP
    TAX         ;ELSE HOLD IT
    LDY #$28    ; & LOOK UNDERNEATH
    LDA (SCRPTR),Y
    BNE DONXRCK ;NOT BLANK-DO NEXT
    TXA         ;BLANK, MOVE ROCK
    STA (SCRPTR),Y ; ABOVE DOWN
    LDY #0
    TYA
    STA (SCRPTR),Y
    LDA SCRPTR  ; & GO UP ONE
    SEC         ; SO WHOLE COLUMN
    SBC #$28    ; WON'T FALL AT
    STA SCRPTR  ; ONCE
    BCS NOVER
    DEC SCRPTR+1
NOVER DEC YCOUNT ;LAST ROW DONE?
    BMI DONXCOL ; YES, DO NEXT COL
DONXRCK LDA SCRPTR ;GO UP ONE
    SEC         ; ROW
    SBC #$28
    STA SCRPTR
    BCS NOVER2
    DEC SCRPTR+1
NOVER2 DEC YCOUNT ;LAST ROW DONE?
    BPL RK2DRP  ; YES, DO NEXT COL
DONXCOL DEC XCOUNT ;LAST COL DONE?
    BPL DSTYCNT ; NO, DO NEXT
    JMP BMBLOOP ;DO BOMBS AGAIN
;
; MOVE PLAYER,CHECK FOR LEAVING
; SCREEN, END GAME CHECK, SWITCH
; SHIP TYPES
;
MOVEPLR LDA ONSCR ;IF NOT ON
    BNE ADDCLOK ; SCREEN, SET SOUND
    LDA MASK    ; AND PLAYERS
    CMP #3      ;BALLOON?
    BEQ STBLSND ; YES, DO THAT
    LDA #$96    ;SET PLANE SOUND
    STA AUDF4
    LDA #$24
    STA AUDC4
    BNE ADDCLOK ; & GOTO CLOCK ADD
STBLSND LDA #0  ;SET WIND SOUND
    STA AUDF4
    LDA #2
    STA AUDC4
    LDX #1      ;SET BALLOON
STBLNS LDA PLYRY,X
    STA SCRPTR
    TXA
    CLC
    ADC # >PL0
    STA SCRPTR+1
    LDY #15
SETBALN LDA CHARS+80,Y
    STA (SCRPTR),Y
    DEY
    BPL SETBALN
    DEX
    BPL STBLNS
ADDCLOK INC CLOCK ;ADD TO CLOCK
    LDA CLOCK   ;IF CLOCK AND
    AND MASK    ; MASK<>0 THEN
    BNE DODELAY ; DON'T MOVE
    LDA PLYRX   ;MOVE THE PLAYERS
    CLC         ;FIRST PLAYER 1
    ADC DIR
    STA PLYRX
    STA HPOSP0
    STA HPOSP2
    LDA DIR     ;THEN PLAYER 2
    EOR #$FE
    CLC
    ADC PLYRX+1
    STA PLYRX+1
    STA HPOSP1
    STA HPOSP3
    LDA MASK    ;IF ON PLANES
    CMP #1      ; THEN CHECK IF
    BNE DODELAY ; TIME TO ANIMATE
    LDA CLOCK   ; PROPS
    AND #2
    BEQ DODELAY ;NO, SKIP THIS
    LDA DIR     ;SET TEMP DIR
    STA TDIR    ;(WILL BE KILLED)
    LDX #1
ANILOOP LDA PLYRY,X ;SET POINTER
    STA SCRPTR  ; TO PLAYER
    TXA
    CLC
    ADC # >PL0
    STA SCRPTR+1
    LDA CLOCK   ;GET IMAGE INDEX
    AND #4      ; FROM CLOCK
    ASL A
    STA HOLDIT  ; AND HOLD IT
    LDA TDIR    ;GET DIRECTION
    AND #$10    ; INDEX FROM
    CLC         ; DIR
    ADC HOLDIT  ;& ADD 'EM TO GET
    STX HOLDIT  ; INDEX.
    TAX         ;SAVE PLAYER #
    LDY #0      ;SET PLAYER
ANISET LDA CHARS+48,X
    STA (SCRPTR),Y
    INX
    INY
    CPY #8
    BNE ANISET
    LDA TDIR    ;REVERSE TDIR
    EOR #$FE
    STA TDIR
    LDX HOLDIT  ;GET PLAYER #
    DEX         ; & ANIMATE NEXT
    BPL ANILOOP
DODELAY LDX #15 ;WAIT FOR A
DELAY1 LDY DELYVAL ; WHILE TO MAKE
DELAY2 DEY      ; GAME PLAYABLE
    BNE DELAY2
    DEX
    BNE DELAY1
    LDA #1      ;PLAYERS ARE NOW
    STA ONSCR   ; ON SCREEN
    LDA PLYRX   ;BUT CHECK TO
    CMP #44     ; SEE IF THEY
    BEQ OFFSCR  ; AREN'T
    CMP #204
    BNE MPGOBAK ;IF ON, RETURN
OFFSCR LDA #0   ;ELSE, TURN OFF
    STA AUDC3   ; EXPLOSIONS AND
    STA AUDC4   ; BKG SOUND
    STA EXPLODE
    STA ONSCR   ;SET ONSCR FALSE
    LDX #1
CHKBR LDA BMBDRP,X ;IF A BOMB IS
    BEQ CKBRN   ; IN THE AIR, AND
    LDA RCKHIT,X ; IT HASN'T HIT
    BNE CKBRN   ; ANYTHING YET,
    JSR LWRMISS ; IT'S A MISS
CKBRN LDA BRUN,X ;IF NO BOMBS
    BNE CKNBR   ; DROPPED THIS
    JSR LWRMISS ; PASS,IT'S A MISS
CKNBR DEX
    BPL CHKBR
    JSR PMCLR   ;CLEAR OUT PLAYERS
    LDX PLAYERS ;IF THE ACTUAL
    LDA BOMBS   ; PLAYERS HAVE
    CLC         ; NO MORE BOMBS,
    ADC BOMBS,X ; AND WE'RE ON A
    ADC PLAY    ; GAME, END IT
    BEQ ENDGAME
    LDA DIR     ;REVERSE DIRECTION
    EOR #$FE
    STA DIR
    LDX PLYRY   ;CHANGE PLAYER
    LDY PLYRY+1 ; LANES
    STX PLYRY+1
    STY PLYRY
    LDA #3      ;RESET CLOCK
    STA CLOCK
    LDA ROCKS+1 ;IF HALF OF THE
    BNE MPGOBAK ; ROCKS ARE GONE
    LDA ROCKS   ; THEN SWITCH
    CMP #149    ; TO PLANES
    BCS MPGOBAK ;ELSE RETURN
    LDA #1      ;SET MOVE RATE
    STA MASK    ; MASK
    LDA #4      ;PLANE BOMBS GET
    STA RKILL   ; MAX OF 4 ROCKS
MPGOBAK RTS     ;RETURN
;
ENDGAME PLA     ;GET RID OF
    PLA         ; RETURN ADDRESS
    LDA #8      ;DO DELAY SO
    STA HOLDIT  ; THE PLAYERS
WAIT0 LDX #$FF  ; CAN SEE THE
WAIT1 LDY #$FF  ; FINAL SCORE
WAIT2 LDA CONSOL ; (END DELAY
    CMP #7      ; EARLY WITH
    BNE ENDGOBK ; CONSOL KEY)
    DEY
    BNE WAIT2
    DEX
    BNE WAIT1
    DEC HOLDIT
    BPL WAIT0
ENDGOBK JMP RESTART ;GO TITLE SCREEN
;
; SET CANYON SCREEN IMAGE
;
SETSCRN LDY #0  ;COPY ROCKS &
SETSC1 LDA ROCKIMG,Y ; CANYON TO
    STA CANYON+40,Y ; SCREEN
    INY
    BNE SETSC1
    LDY #145
SETSC2 LDA ROCKIMG+255,Y
    STA CANYON+295,Y
    DEY
    BNE SETSC2
    RTS         ;RETURN
;
; LOWER NUMBER OF BOMBS LEFT
;
LWRMISS LDA BOMBS,X ;IF ALREADY
    BEQ LWMGOBK ; ZERO, EXIT
    DEC BOMBS,X ;LOWER BOMBS LEFT
    LDA BOMBS,X ;IF AT LEAST 3
    CMP #3      ; LEFT, RETURN
    BCS LWMGOBK
    CLC         ;GET INDEX FOR
    ADC SCRNDX,X ; SCREEN TO
    TAY         ; ERASE BOMB
    LDA #0
    STA BOMB1-3,Y
LWMGOBK RTS     ;RETURN
;
; CLEAR PLAYERS,BOMB Y POSITIONS,
; BOMBS DROPPED THIS PASS, AND
; TURN OFF BOMB SOUNDS
;
PMCLR LDA #0
    TAY
PMCLOOP STA PL0,Y ;CLEAR ALL
    STA PL1,Y   ; PLAYERS
    STA PL2,Y
    STA PL3,Y
    DEY
    BNE PMCLOOP
    STA BMBDRP  ;CLEAR BOMB Y
    STA BMBDRP+1 ; POSITION
    STA BRUN    ; & BOMBS DROPPED
    STA BRUN+1  ; THIS PASS
    STA AUDC1   ;TURN OFF BOMB
    STA AUDC2   ; FALL SOUNDS
    RTS
;
; PLAYER 2/COMPUTER MESSAGES
;
P2COMPT .SBYTE "RETUPMOC2 REYALP" ;Inverse Charecters
;
; MISC DATA
;
SCRNDX .BYTE 3,13
MASKS .BYTE 1,3
;
; TITLE SCREEN DISPLAY LIST
;
DLIST1 .BYTE $70,$70,$70,$46
    .WORD GAME
    .BYTE $70,$70,$70,$70,$70
    .BYTE $70,$70,$70,$70,$44
    .WORD CANYON+40
    .BYTE 4,4,4,4,4,4,4,4,4,$47
    .WORD TITLE
    .BYTE 6,6,$41
    .WORD DLIST1
;
; GAME DISPLAY LIST
;
DLIST2 .BYTE $70,$70,$70,$70
    .BYTE $70,$70,$70,$70,$70
    .BYTE $70,$70,$70,$70,$44
    .WORD CANYON+40
    .BYTE 4,4,4,4,4,4,4,4,4,$46
    .WORD GAME
    .BYTE $70,6,6,$41
    .WORD DLIST2
;
; TITLES
;
TITLE .SBYTE "  boulder " ;Inverse Chars
    .SBYTE " bombers  " ;Inverse Chars
    .SBYTE "   by  mark price   "
    .SBYTE "     PLAYERS: "
SCNOPLR .BYTE $11,0,0,0,0,0
;
; BOTTOM OF GAME SCREEN
;
GAME .SBYTE "     HIGH: "
HISCOR .SBYTE "   0      PLAYER 1   "
P2MSG .BYTE 0,0,0,0,0,0,0,0,0,0
SCORE1 .BYTE 0,0,0,0,0
BOMB1 .BYTE 0,0,0,0,0
SCORE2 .BYTE 0,0,0,0,0
BOMB2 .BYTE 0,0,0,0
;
; DATA FOR CANYON
;
ROCKIMG .BYTE 1,1,1,1,1,1,1,1,1,1
    .BYTE 1,1,1,1,1,1,1,1,1,1
    .BYTE 1,1,1,1,1,1,1,1,1,1
    .BYTE 1,1,1,1,1,1,1,1,1,1
    .BYTE $85,1,1,1,1,1,1,1,1,1
    .BYTE 1,1,1,1,1,1,1,1,1,1
    .BYTE 1,1,1,1,1,1,1,1,1,1
    .BYTE 1,1,1,1,1,1,1,1,1,$85
    .BYTE $84,$85,1,1,1,1,1,1,1,1
    .BYTE 1,1,1,1,1,1,1,1,1,1
    .BYTE 1,1,1,1,1,1,1,1,1,1
    .BYTE 1,1,1,1,1,1,1,1,$84,$85
    .BYTE $84,$85,2,2,2,2,2,2,2,2
    .BYTE 2,2,2,2,2,2,2,2,2,2
    .BYTE 2,2,2,2,2,2,2,2,2,2
    .BYTE 2,2,2,2,2,2,2,2,$84,$85
    .BYTE $84,$84,$85,2,2,2,2,2,2,2
    .BYTE 2,2,2,2,2,2,2,2,2,2
    .BYTE 2,2,2,2,2,2,2,2,2,2
    .BYTE 2,2,2,2,2,2,2,$84,$84,$85
    .BYTE $84,$84,$85,2,2,2,2,2,2,2
    .BYTE 2,2,2,2,2,2,2,2,2,2
    .BYTE 2,2,2,2,2,2,2,2,2,2
    .BYTE 2,2,2,2,2,2,2,$84,$84,$85
    .BYTE $84,$84,$84,$85,3
    .BYTE 3,3,3,3,3,3,3
    .BYTE $85,3,3,3,3,3,3,3,3,3,3,3
    .BYTE 3,3,3,$85,3,3,3,3,3,3,3,3
    .BYTE $84,$84,$84,$85,$84,$84
    .BYTE $84,$85,3,3,3,3
    .BYTE 3,3,3,$84,$84,$85
    .BYTE 3,$85,3,3,3,3
    .BYTE 3,3,3,3,$85,3
    .BYTE $84,$84,$85,3,3,3
    .BYTE 3,3,3,3,$84,$84
    .BYTE $84,$85,$84,$84,$84,$84
    .BYTE $85,3,3,3,3,3
    .BYTE $84,$84,$84,$84,$84,$84
    .BYTE $85,3,3,3,3,3
    .BYTE 3,$84,$84,$84,$84,$84
    .BYTE $84,$85,3,3,3,3
    .BYTE 3,$84,$84,$84,$84,$85
    .BYTE $84,$84,$84,$84,$84,$85
    .BYTE 3,3,3,$84,$84,$84
    .BYTE $84,$84,$84,$84,$84,$85
    .BYTE 3,3,3,3,$84,$84
    .BYTE $84,$84,$84,$84,$84,$84
    .BYTE $85,3,3,3,$84,$84
    .BYTE $84,$84,$84,$85
;
; CHARACTER SET DATA
;
MYCHARS .BYTE 0,0,0,0,0,0,0,0
    .BYTE 84,84,84,84,84,84,84,0
    .BYTE 168,168,168,168,168,168,168,0
    .BYTE 252,252,252,252,252,252,252,0
    .BYTE 255,255,255,255,255,255,255,255
    .BYTE 252,252,252,252,252,252,252,252
    .BYTE 0,0,1,3,63,211,254,128
    .BYTE 0,0,1,131,191,211,126,0
    .BYTE 0,0,128,192,252,203,127,1
    .BYTE 0,0,128,193,253,203,126,0
    .BYTE 60,126,255,0,255,255,126,60
    .BYTE 24,36,36,24,24,0,0,0
    .BYTE 160,64,224,224,224,64,0,0
    .BYTE 108,124,56,124,124,124,56,16
;
; ON-SCREEN CANYON
;
CANYON = *+$0190
;
    *=  $02E0
    .WORD INIT  ;RUN ADDRESS
;

