;.Q.!.B
; ======================================
; HARVEY WALLBANGER by Charles Bachand
; ======================================
; ======================================
; Copyright (C) 1982 ANALOG Magazine
; ======================================
; ------------------------
; Operating System Equates
; ------------------------
HPOSP0 = $D000 ;player 0 horizontal position
M0PF = $D000 ;missile 0/playfield collision
HPOSP2 = $D002 ;player 2 horizontal position
HPOSP3 = $D003 ;player 3 horizontal position
HPOSM0 = $D004 ;missile 0 horizontal position
P0PF = $D004 ;player 0/playfield collisions
P0PL = $D00C ;player 0 to player collisions
GRP2 = $D00F ;player 2 graphics register
COLBK = $D01A ;background color
GRACTL = $D01D ;graphics control register
HITCLR = $D01E ;collision 'HIT' clear
CONSOL = $D01F ;console switch port
AUDF1 = $D200 ;audio frequency 1
AUDC1 = $D201 ;audio volume 1
AUDF2 = $D202 ;audio frequency 2
AUDC2 = $D203 ;audio volume 2
AUDF3 = $D204 ;audio frequency 3
AUDC3 = $D205 ;audio volume 3
AUDF4 = $D206 ;audio frequency 4
AUDC4 = $D207 ;audio volume 4
RANDOM = $D20A ;random number generator
IRQEN = $D20E ;IRQ interrupt enable
PMBASE = $D407 ;P/M base address
WSYNC = $D40A ;wait for horizontal sync
VCOUNT = $D40B ;scan line counter
SETVBV = $E45C ;set vertical blank vector
XITVBV = $E462 ;vertical blank exit vector
SIOINT = $E465 ;serial I/O initialization
ATRACT = $004D ;atract mode counter
; -----------------------
; System Shadow Registers
; -----------------------
RTCLOK = $0012 ;system clock
CDTMV1 = $0218 ;system timer 1
CDTMV2 = $021A ;system timer 2
CDTMA1 = $0226 ;system timer 1 vector
CDTMA2 = $0228 ;system timer 2 vector
SDMCTL = $022F ;DMA control
SDLSTL = $0230 ;display list pointer
GPRIOR = $026F ;graphics priority
STICK0 = $0278 ;joystick 1
STRIG0 = $0284 ;trigger 1
PCOLR0 = $02C0 ;player 0 color
PCOLR1 = $02C1 ;player 1 color
PCOLR2 = $02C2 ;player 2 color
PCOLR3 = $02C3 ;player 3 color
COLOR2 = $02C6 ;playfield 2 color
COLOR3 = $02C7 ;playfield 3 color
COLOR4 = $02C8 ;background color
; -------------------
; Page Zero Variables
; -------------------
Org $0080 ;area not used by system
PIC DS 2 ;rabbit image pointer
; --------------------------
; Player / Missile RAM Space
; --------------------------
Org $3000 ;out of everyones way
PM Org *+$180 ;first area not used
MISL Org *+$80 ;Missile graphics area
PLR0 Org *+$80 ;player 0 graphics area
PLR1 Org *+$80 ;player 1 graphics area
PLR2 Org *+$80 ;player 2 graphics area
PLR3 Org *+$80 ;player 3 graphics area
; -------------------
; Program entry point
; -------------------
JMP HARVEY
; -----------------
; Game display list
; -----------------
DL DB $70,$70 ;32 blank scan lines
DB $70,$70
DB $47 ;mode 2 line w/LMS bit
DW DISP ;address of game display
DB $07,$07 ;9 more mode 2 lines
DB $07,$07
DB $07,$07
DB $07,$07
DB $07
DB $70,$70 ;skip 16 lines
DB $46 ;mode 1 lime w/LMS bit
DW SLINE ;address of score line
DB $41 ;jump on vertical blank
DW DL ;to start of display list
; ---------------
; Score line data
; ---------------
SLINE DB 'R' ; +$A0
DB 'A' ; +$A0
DB 'B' ; +$A0
DB 'B' ; +$A0
DB 'I' ; +$A0
DB 'T' ; +$A0
DB 'S' ; +$A0
DB ':' ; +$A0
RNUM DB '3' ; +$A0 ;number of rabbits
DB ' ' ; +$A0
DB 'S' ; +$A0
DB 'C' ; +$A0
DB 'O' ; +$A0
DB 'R' ; +$A0
DB 'E' ; +$A0
DB ':' ; +$A0
SNUM DB '0' ; +$A0 ;score display
DB '0' ; +$A0
DB '0' ; +$A0
DB '0' ; +$A0
; -----------------
; Game over message
; -----------------
GOMSG DB 'game'
DB 0,0,'ov'
DB 'er',$80
PSMSG DB 'pres'
DB 's',0,0,'s'
DB 'tart',$80
; -------------------
; Initialization Code
; -------------------
HARVEY CLD ;clear decimal flag
JSR SIOINT ;stop cassette
LDA #'3' ; +$A0;display for '3'
STA RNUM ;3 lives (display)
LDA #3 ;get 3 lives
STA LIVES ;initialize counter
LDA #'0' ; +$A0;display for '0'
STA SNUM ;store in the four
STA SNUM+1 ;bytes used for the
STA SNUM+2 ;score display
STA SNUM+3 ;area.
MORE LDA #60 ;get 1 second count
STA TIM2ST ;set reset value
STA CDTMV2 ;set system timer #2
JSR CLSCRN ;clear game playfield
LDY #2 ;display 3 numbers (0-2)
INUMS JSR PUTNUM ;put the number on screen
DEY ;decrement number counter
BPL INUMS ;done yet? No.
LDA
DL ;high byte DL address
STA SDLSTL+1 ;DL pointer (high)
LDA #$04 ;set PF over PLAYER
STA GPRIOR ;graphics priority
LDA #40 ;high wall
STA BYLOC ;starting location
LDA #196 ;low wall
STA BYLOC+1 ;starting location
LDA #60 ;left wall
STA BXLOC ;starting location
STA HPOSP2 ;hardware register
LDA #184 ;right wall
STA BXLOC+1 ;starting location
STA HPOSP3 ;hardware register
LDA #122 ;center screen-4 color clocks
STA HARX ;Harvey's initial X position
LDA #55 ;center P/M-8 bytes
STA HARY ;Harvey's initial Y position
LDA #$2E ;set P/M DMA on bits
STA SDMCTL ;store in DMA control
LDA #3 ;set P/M enable bits on
STA GRACTL ;store in graphics control
LDA >PM ;get high byte of P/M addr
STA PMBASE ;point hardware to it
LDA #$96 ;light blue color
STA COLOR2 ;default color too dark
LDA #$48 ;pink color
STA COLOR3 ;same here
LDA #$18 ;gold color
STA PCOLR0 ;set rabbit color
LDA #$98 ;blue color
STA PCOLR1 ;set missile 1 color
LDA #$34 ;red-orange color
STA PCOLR2 ;left wall color
LDA #$C4 ;green color
STA PCOLR3 ;right wall color
LDA #1 ;initialize trigger flag-
STA STRIGF ;to no shot fired
LDX >VB ;address of VB (MSB)
LDY T1 ;addr of timer 1 routine MSB
STA CDTMA1+1 ;set timer 1 vector MSB
LDA T2 ;addr of timer 2 routine MSB
STA CDTMA2+1 ;set timer 2 vector MSB
LDA #1 ;get 4.25 second count
STA CDTMV1+1 ;set system timer #1
LDA #0 ;get a zero
STA HITCLR ;reset collision registers
STA DIESW ;rabbit is alive
STA TICTOC ;reset tictoc counter
STA VOL1 ;start with no tictoc sound
STA VOL2 ;start with no shuffle noise
STA IRQEN ;disable all IRQ interrupts
LDX #3 ;set index value to 3
WINCZ STA WINC,X ;zero wall mover counter
STA SHOTX,X ;zero X missile location
STA SHOTY,X ;zero Y missile location
STA SINCX,X ;zero X missile increment
STA SINCY,X ;zero Y missile increment
DEX ;next wall mover counter
BPL WINCZ ;more walls/missiles? Yes.
TAX ;set index to zero
IM01 STA MISL,X ;clear Missile area
STA PLR0,X ;clear Player 0, 1 area
INX ;do next byte
BNE IM01 ;done yet? No.
LDA #$FF ;turn on pixels
IM23 STA PLR2,X ;set Player 2, 3 area
INX ;do next byte
BNE IM23 ;done yet? No.
; ------------------------------------------
; Main program used to generate the display.
; Actual game done entirely during display's
; vertical blank processing routine.
; ------------------------------------------
HBARS INX ;increment wall pointer
TXA ;transfer pointer to Acc
AND #1 ;mask off lowest bit
TAX ;put back in X register
LDA BYLOC,X ;get wall vertical position
LSR A ;divide by 2, odd=carry set
PHP ;save carry flag
VCHECK CMP VCOUNT ;compare with line counter
BNE VCHECK ;not yet!
STA WSYNC ;start at new line
PLP ;get carry flag back
BCC ONELIN ;branch on even line number
STA WSYNC ;wait for next line
ONELIN LDA RANDOM ;random background color
AND #$F6 ;max lum of 6
STA COLBK ;for horizontal walls
LDY #10 ;let's have 10 lines of this
LINES LDA #0 ;get a zero for overlap
STA GRP2,X ;background overlaps player
STA WSYNC ;wait for next line
LDA RANDOM ;random background color
AND #$F6 ;max lum of 6
STA COLBK ;for horizontal walls
DEY ;decrement line counter
BNE LINES ;10 lines done yet? No!
LDA COLOR4 ;get original background
STA COLBK ;store in background
LDA LIVES ;more lives
BEQ HB1 ;No. skip code
LDA DIESW ;a new life?
BPL HB1 ;No.
JMP MORE ;Yes. more lives
HB1 LDA CONSOL ;check for start switch
AND #$01 ;mask off bit
BNE HBARS ;start? No.
JMP HARVEY ;restart game
; -----------------------------------------
; System timer #1 interrupt handler.
; Used to speed up walls every 4.25 seconds.
; -----------------------------------------
T1 LDA TIM2ST ;get wall speed
CMP #2 ;must stop at two
BEQ TIM1 ;is it two? Yes.
DEC TIM2ST ;No, then decrement
TIM1 LDA #1 ;get 4.25 second cycle time
STA CDTMV1+1 ;reset timer #1
RTS ;return
; -------------------------------------------
; System timer #2 interrupt handler.
; Used to move walls and initiate wall noise.
; -------------------------------------------
T2 LDA TIM2ST ;get timer #2 value
STA CDTMV2 ;reset timer #2
INC BYLOC ;move top wall down
DEC BYLOC+1 ;move bottom wall up
INC BXLOC ;change left wall location
LDA BXLOC ;get new location
STA HPOSP2 ;change player 2 position
DEC BXLOC+1 ;change right wall location
LDA BXLOC+1 ;get new location
STA HPOSP3 ;change player 3 position
INC TICTOC ;increment TIC-TOC counter
LDA TICTOC ;get counter value
AND #1 ;just need 0 or 1 value
TAX ;use for index
LDA METRO,X ;get sound frequency
STA AUDF1 ;change frequency
LDA #$08 ;get volume value
STA VOL1 ;save in volume counter
RTS ;return
; -------------------------------------------
; Deferred vertical blank processing routine.
; Here is where all the actual game playing
; takes place. This could be quite long.
; -------------------------------------------
VB LDA DIESW ;rabbit dying?
BNE VB0 ;He sure is.
LDA LIVES ;any lives left?
BNE VB0 ;There sure are.
JSR CLSCRN ;clear screen of numbers
LDX #0 ;initialize X with zero
STX AUDC1 ;stop tictoc sound
STX AUDC2 ;stop dying sound
STX AUDC3 ;stop gun noise
STX AUDC4 ;stop number sound
STX CDTMV1 ;shut off the two timers
STX CDTMV1+1 ;ditto.
STX CDTMV2 ;same here.
GOPRT LDA GOMSG,X ;get a character
BMI PSINIT ;end of scring? Yes.
STA DISP+85,X ;put on screen
INX ;increment index
JMP GOPRT ;continue
PSINIT LDX #0 ;zero the index
PSPRT LDA PSMSG,X ;get another character
BMI VBXIT ;end of string? Yes.
STA DISP+144,X ;put on screen
INX ;increment index
JMP PSPRT ;continue
VBXIT JMP VBX ;exit vertical blank
VB0 LDA P0PL ;player/player collisions
STA P0PLT ;store in temp variable
LDA P0PF ;player to PF collisions
STA P0PFT ;store in temp variable
LDA NSOUND ;treasure sound counter
BMI NOSND ;end of sound? Yes.
DEC NSOUND ;decrement volume
LSR A ;divide volume by 2
ORA #$A0 ;add pure tone
STA AUDC4 ;change volume
NOSND LDA VOL1 ;get tictoc volume value
BMI SND2 ;if <0 we produce no sound
DEC VOL1 ;decrement volume value
ORA #$C0 ;mask on the distortion
STA AUDC1 ;generate the tictoc sound
SND2 LDA VOL2 ;get shuffle volume
BMI SND3 ;if <0 we produce no sound
DEC VOL2 ;decrement volume value
ORA #$80 ;mask on the distortion
STA AUDC2 ;generate the shuffle noise
SND3 LDA FREQ3 ;get shot frequency
INC FREQ3 ;increment shot frequency
INC FREQ3 ;do it again
INC FREQ3 ;and one last time
STA AUDF3 ;change frequency (lower)
LDA DIESW ;is rabbit dying
BEQ TMOV1 ;No. continue
INC DIESW ;Yes. 2 second die period
INC PCOLR0 ;change rabbit colors
INC PCOLR0 ;again
LDA PCOLR0 ;get number
ASL A ;*2
ASL A ;*4
ASL A ;*8
STA AUDF2 ;use as frequency
LDA #$88 ;get distortion
STA AUDC2 ;make sound
JMP VBX ;exit vertical blank
TMOV1 LDA WINC ;check push wall up
BEQ TMOV2 ;push up? No.
DEC WINC ;decrement push up counter
LDA BYLOC ;get top wall location
CMP #28 ;compare with top of screen
BEQ TMOV2 ;at top? Yes.
DEC BYLOC ;move wall up
TMOV2 LDA WINC+1 ;check push wall down
BEQ TMOV3 ;push down? No.
DEC WINC+1 ;decrement push down counter
LDA BYLOC+1 ;get bottom wall location
CMP #204 ;compare bottom of screen
BEQ TMOV3 ;at bottom? Yes.
INC BYLOC+1 ;move wall down
TMOV3 LDA WINC+2 ;check push wall left
BEQ TMOV4 ;push left? No.
DEC WINC+2 ;decrement push left counter
LDA BXLOC ;get left wall position
STA HPOSP2 ;move left wall player
CMP #39 ;check for left wall limit
BEQ TMOV4 ;at limit? Yes.
DEC BXLOC ;move wall left
TMOV4 LDA WINC+3 ;check push wall right
BEQ TMOVX ;push right? No.
DEC WINC+3 ;decrement push right counter
LDA BXLOC+1 ;get right wall position
STA HPOSP3 ;move right wall player
CMP #208 ;check for right wall limit
BEQ TMOVX ;at limit? Yes.
INC BXLOC+1 ;move wall right
TMOVX LDA #0 ;get a zero
STA ATRACT ;poke out atract mode
STA XTEMP ;zero rabbit X increment
STA YTEMP ;zero rabbit Y increment
LDA STICK0 ;get joystick value
CMP #$0F ;at center position?
BEQ CENTER ;Yes. skip code
LDA RTCLOK+2 ;get real time clock LSB
AND #$07 ;at 1/7.5 second mark?
BNE CENTER ;No. skip code
LDA #$10 ;get shuffle frequency
STA AUDF2 ;set frequency register
LDA #$04 ;get volume value
STA VOL2 ;set shuffle volume
CENTER LDA STICK0 ;get joystick value
SEC ;set carry for subtract
SBC #5 ;values 5-15 only
ASL A ;5-15 now 0,2,4,...
TAX ;use for index
LDA RTCLOK+2 ;get real time clock LSB
ROR A ;divide by 2
ROR A ;divide by 4
ROR A ;divide by 8
ROR A ;carry set/reset at .13 sec
LDA PK1,X ;get rabbit picture LSB
BCC PICMVL ;other pic at .13 sec? No.
LDA PK2,X ;get alternate picture LSB
PICMVL STA PIC ;store LSB of pic address
LDA PK1+1,X ;get rabbit picture MSB
BCC PICMVH ;other pic at .13 sec? No.
LDA PK2+1,X ;get alternate picture MSB
PICMVH STA PIC+1 ;store MSB of pic address
LDX #3 ;count 3 downto 0
CHKSTK LSR STICK0 ;shift bit into carry
BCS CHKNXT ;correct direction? No.
LDA STBLX,X ;check X movement direction
BEQ CHK0 ;movement allowed? No.
STA XTEMP ;store X movement value
CHK0 LDA STBLY,X ;check Y movement direction
BEQ CHKNXT ;movement allowed? No.
STA YTEMP ;store Y movement value
CHKNXT DEX ;do next stick position
BPL CHKSTK ;done yet? No.
LDA P0PLT ;get player 0 collision
CMP #$0C ;left/right squeze?
BNE NOSQUE ;No. Check indvdual walls
DEC RNUM ;decrement lives display
DEC LIVES ;decrement lines counter
INC DIESW ;the rabbit has died switch
NOSQUE AND #$04 ;check left wall collision
BEQ BMPRT ;hit left wall? No.
INC HARX ;Yes. Move rabbit to right
LDA #0 ;get zero value
STA XTEMP ;stop rabbit X movement
BMPRT LDA P0PLT ;get player 0 collision
AND #$08 ;check right wall collision
BEQ BMPUP ;hit right wall? No.
DEC HARX ;Yes. Move rabbit to left
LDA #0 ;get zero value
STA XTEMP ;stop rabbit X movement
BMPUP CLC ;clear carry for add
LDA BYLOC ;top wall Y location
ADC #4 ;offset by 4
LSR A ;divide by 2
CMP HARY ;compare rabbit Y location
BCC BMPDN ;hit top wall? No.
DEC RNUM ;decrement lives display
DEC LIVES ;decrement lines counter
INC DIESW ;the rabbit has died switch
BMPDN LDA HARY ;get rabbit Y location
ADC #10 ;offset by 10
ASL A ;multiply by 2
CMP BYLOC+1 ;compare bottom wall Y
BCC NOBMP ;hit bottom wall? No.
DEC RNUM ;decrement lives display
DEC LIVES ;decrement lines counter
INC DIESW ;the rabbit has died switch
NOBMP CLC ;clear carry for add
LDA HARX ;get rabbit X position
ADC XTEMP ;add X increment
STA HARX ;save new rabbit X position
STA HPOSP0 ;position rabbit player 0
CLC ;clear carry for add
LDA HARY ;get rabbit Y position
ADC YTEMP ;add Y increment
STA HARY ;save new rabbit Y position
TAX ;use position as index
LDY #0 ;initialize picture counter
MOVHAR LDA (PIC),Y ;get rabbit picture byte
STA PLR0,X ;store in player 0 area
INX ;increment player pointer
INY ;increment picture pointer
CPY #14 ;check for end of picture
BNE MOVHAR ;at end? No.
LDA STRIG0 ;get trigger value
CMP STRIGF ;compare with trigger flag
STA STRIGF ;save new trigger flag
BCS NOFIRE ;shot fired? No.
LDA XTEMP ;rabbit X increment
ORA YTEMP ;OR rabbit Y increment
BNE FIREGN ;rabbit stationary? No.
INC STRIGF ;set trigger flag to 1
BNE NOFIRE ;skip fire routine
FIREGN LDA #$40 ;initialize frequency
STA FREQ3 ;zero audio freq 3
LDA #$04 ;shot volume + distortion
STA AUDC3 ;enable volume 3
INC SHOTS ;increment shot pointer
LDA SHOTS ;get shot pointer
AND #3 ;make it 0-3 only
TAX ;use pointer for index
LDA XTEMP ;get rabbit X increment
ASL A ;make shot twice as fast
STA SINCX,X ;set missile X increment
LDA YTEMP ;get rabbit Y increment
ASL A ;make shot twice as fast
STA SINCY,X ;set missile Y increment
CLC ;clear carry for add
LDA HARX ;get rabbit X position
ADC #3 ;move to center X of rabbit
STA SHOTX,X ;shot initial X position
LDA HARY ;get rabbit Y position
ADC #8 ;move to center Y of rabbit
STA SHOTY,X ;shot initial Y position
NOFIRE LDA #0 ;zero accumulator
TAX ;zero X index
ERASES STA MISL,X ;zero all missiles
INX ;next missile byte
BPL ERASES ;done? No.
LDX #3 ;count 3 downto 0
PLOTS LDA SINCX,X ;get missile X increment
ORA SINCY,X ;OR missile Y increment
BEQ NOPLOT ;any movement? No.
LDA SHOTY,X ;missile Y position
CLC ;clear carry for add
ADC SINCY,X ;add Y increment
STA SHOTY,X ;store new Y position
TAY ;Y position now index
ASL A ;multiply by 2
ADC #2 ;offset for compare
CMP BYLOC+1 ;compare with bottom wall
BCC HITTP ;hit bottom wall? No.
JSR ZINCXY ;zero missile increments
ADC WINC+1 ;add 8 to wall increment
STA WINC+1 ;new bottom wall increment
JMP PLOTNH ;continue
HITTP SBC #12 ;offset for bottom side
CMP BYLOC ;compare with top wall
BCS PLOTNH ;hit top wall? No.
JSR ZINCXY ;zero missile increments
ADC WINC ;add 8 to wall increment
STA WINC ;new top wall increment
PLOTNH LDA MISL,Y ;get missile byte
ORA MISMSK,X ;OR missile mask
STA MISL,Y ;store new byte
LDA MISL+1,Y ;get next missile byte
ORA MISMSK,X ;OR missile mask
STA MISL+1,Y ;store new next byte
LDA M0PF,X ;missile/playfield collision
LDY #0 ;init Y register
MHPF ROR A ;collision?
BCC MHPF0 ;No. No. No.
JMP MHIT ;Yes. Yes. Yes.
MHPF0 INY ;try next bit
CPY #4 ;any more bits?
BNE MHPF ;Certainly! Yuk. Yuk.
CLC ;clear carry for add
LDA SHOTX,X ;get missile X position
ADC SINCX,X ;add X increment
STA SHOTX,X ;store new X position
STA HPOSM0,X ;position missile
CMP BXLOC+1 ;compare missile with wall
BCC HITLF ;hit right wall? No.
JSR ZINCXY ;zero missile increments
ADC WINC+3 ;add 8 to wall increment
STA WINC+3 ;new wall increment
JMP NOPLOT ;continue
HITLF SBC #6 ;offset for right side
CMP BXLOC ;compare with left wall
BCS NOPLOT ;hit left wall? No.
JSR ZINCXY ;zero missile increments
ADC WINC+2 ;add 8 to wall increment
STA WINC+2 ;new wall increment
NOPLOT DEX ;next missile
BMI NOPL1 ;missiles done? Yes.
JMP PLOTS ;continue loop
NOPL1 LDX #3 ;set up pointer
LDA #0 ;zero accumulator
CHKMIS ORA SINCX,X ;OR in X increments
ORA SINCY,X ;OR in Y increments
DEX ;decrement pointer
BPL CHKMIS ;at end? No.
CMP #0 ;check shot increments
BNE NOSSND ;any increments? Yes.
STA AUDC3 ;end shot sound
NOSSND LDY #0 ;initialize Y index
MISHIT LSR P0PFT ;shift collision to carry
BCC MH1 ;collision w/number? No.
JSR ERANUM ;erase the number
LDA VTBL,Y ;get value of number
PHA ;save on stack
JSR PUTNUM ;put out a new number
PLA ;get old number
TAY ;use as counter value
BEQ SCX ;was it zero? Yes.
SCORER LDX #3 ;point to score low digit
SC1 INC SNUM,X ;increment digit
LDA SNUM,X ;get digit
CMP #'9' ; +$A1 ;past ATASCII '9'+color?
BNE SCY ;No. continue
LDA #'0' ; +$A0 ;reset digit
STA SNUM,X ;change score display
DEX ;point to next digit
BPL SC1 ;score rolled over? No.
SCY DEY ;decrement value
BNE SCORER ;scoring done? No.
SCX JMP VBX ;exit routine
MH1 INY ;check next color digit
CPY #3 ;done 0-2 yet?
BNE MISHIT ;No. continue
VBX STA HITCLR ;clear collision registers
JMP XITVBV ;exit deferred vertical blank
MHIT TXA ;save X register
PHA ;on stack
JSR ERANUM ;erase number hit and
JSR PUTNUM ;put a new one on screen
PLA ;pull X register
TAX ;from stack
JMP NOPLOT ;continue on
; -------------------------
; Commonly used subroutines
; -------------------------
; Clear missile display area
ZINCXY LDA #0 ;get zero value
STA SINCX,X ;zero missile X increment
STA SINCY,X ;zero missile Y increment
CLC ;clear carry for add
LDA #8 ;get value for add
RTS ;we return to the program
; Clear the game playfield
CLSCRN LDX #200 ;set 0-199 bytes
LDA #0 ;to zero
CL0 STA DISP-1,X ;store in display
DEX ;count down
BNE CL0 ;past zero yet? No.
RTS ;return to program
; Put random number from 0-9 on screen at
; a random location 0-199
PUTNUM LDX RANDOM ;get random number
CPX #200 ;is number < 200?
BCS PUTNUM ;No. try another
LDA DISP,X ;see if space is occupied
BNE PUTNUM ;Yes. try again
PN0 LDA RANDOM ;get another random number
AND #$0F ;limit it to 0-15
CMP #10 ;is number < 10?
BCS PN0 ;No. try another
STA VTBL,Y ;save number
ORA CTBL,Y ;OR with color
STA DISP,X ;put number on screen
TXA ;move screen offset to A
STA ATBL,Y ;save screen offset
RTS ;end of routine
; Erase number from screen
ERANUM LDA #0 ;get zero for blank
LDX ATBL,Y ;get # position on screen
STA DISP,X ;blank number on screen
LDA RANDOM ;get random number
AND #$1F ;mask off high bits
ORA #$10 ;make it $10-$1F
STA AUDF4 ;use as sound frequency
LDA #30 ;initialize-
STA NSOUND ;volume counter
RTS ;end of routine
; ----------------------------
; Program tables and constants
; ----------------------------
MISMSK DB $03 ;missile 0 mask
DB $0C ;missile 1 mask
DB $30 ;missile 2 mask
DB $C0 ;missile 3 mask
HARLF1 DB 0,0 ;left view #1
DB $12,$0A
DB $3C,$74
DB $3C,$1C
DB $1E,$3E
DB $3F,$7E
HARLF2 DB 0,0 ;left view #2
DB $0B,$0A
DB $3C,$74
DB $3C,$1C
DB $1E,$3E
DB $3E,$F7
HARRT1 DB 0,0 ;right view #1
DB $48,$50
DB $3C,$2E
DB $3C,$38
DB $78,$7C
DB $FC,$7E
HARRT2 DB 0,0 ;right view #2
DB $D0,$50
DB $3C,$2E
DB $3C,$38
DB $78,$7C
DB $7C,$EF
HARFR1 DB 0,0 ;front view #1
DB $42,$24
DB $3C,$14
DB $3C,$18
DB $3C,$7E
DB $7E,$E7
HARFR2 DB 0,0 ;front view #2
DB $42,$24
DB $3C,$28
DB $3C,$18
DB $3C,$7E
DB $7E,$E7
HARDN1 DB 0,0 ;down view #1
DB $44,$24
DB $3C,$14
DB $3C,$18
DB $3C,$7E
DB $FE,$07
HARDN2 DB 0,0 ;down view #2
DB $22,$24
DB $3C,$28
DB $3C,$18
DB $3C,$7E
DB $7F,$E0
HARUP1 DB 0,0 ;up view #1
DB $44,$24
DB $3C,$3C
DB $3C,$18
DB $3C,$66
DB $FE,$07
HARUP2 DB 0,0 ;up view #2
DB $22,$24
DB $3C,$3C
DB $3C,$18
DB $3C,$66
DB $7F,$E0
DB 0,0
PK1 DW HARRT1 ;rabbit pictures set 1
DW HARRT1
DW HARRT1
DW 0
DW HARLF1
DW HARLF1
DW HARLF1
DW 0
DW HARDN1
DW HARUP1
DW HARFR1
PK2 DW HARRT2 ;rabbit pictures set 2
DW HARRT2
DW HARRT2
DW 0
DW HARLF2
DW HARLF2
DW HARLF2
DW 0
DW HARDN2
DW HARUP2
DW HARFR2
CTBL DB $10,$50 ;color offset table
DB $90
METRO DB 38,41 ;tictoc tones
STBLX DB $01,$FF ;joystick X increments
DB $00,$00
STBLY DB $00,$00 ;joystick Y increments
DB $01,$FF
; ---------------------
; Variable Storage Area
; ---------------------
HARX DB 0 ;Harvey's X locatin
HARY DB 0 ;Harvey's Y location
BYLOC DB 0,0 ;horizontal wall Y locations
BXLOC DB 0,0 ;vertical wall X locations
VOL1 DB 0 ;tictoc volume
VOL2 DB 0 ;shuffle volume
FREQ3 DB 0 ;shot frequency
NSOUND DB 0 ;pick number up sound
TICTOC DB 0 ;tictoc sound counter
TIM2ST DB 0 ;wall speed timer
WINC DB 0,0,0,0 ;wall mover counters
STRIGF DB 0 ;trigger compare register
XTEMP DB 0 ;temporary variable
YTEMP DB 0 ;temporary variable
P0PLT DB 0 ;player 0 collision shadow
P0PFT DB 0 ;PL to PF collision shadow
VTBL DB 0,0,0 ;value of #'s on screen
ATBL DB 0,0,0 ;screen offset to #'s
SHOTS DB 0 ;shot enable counter
LIVES DB 0 ;number of lives left
DIESW DB 0 ;rabbit dying switch
SHOTX DB 0,0,0,0 ;missile X location
SHOTY DB 0,0,0,0 ;missile Y location
SINCX DB 0,0,0,0 ;missile X increment
SINCY DB 0,0,0,0 ;missile Y increment
DISP Org *+200 ;screen display area
End HARVEY