;KRAZY KATERPILLARS
;DAVID HUFF
;
;
;RUN ADDRESS: $2000
;
;
	.OPT	NOEJECT
	.TAB	12,17,28
;
;SYSTEM EQUATES
;
HPOSP0	=	$D000
HPOSM0	=	$D004
SIZEP0	=	$D008
SIZEM	=	$D00C
M0PF	=	$D000
P0PF	=	$D004
M0PL	=	$D008
PMBASE	=	$D407
HITCLR	=	$D01E
GRACTL	=	$D01D
SDMCTL	=	$022F
GPRIOR	=	$026F
SDLSTL	=	$0230
VDSLST	=	$0200
CHBAS	=	$02F4
STICK0	=	$0278
STRIG0	=	$0284
PCOLR0	=	$02C0
COLOR0	=	$02C4
ATRACT	=	$4D
COLPF0	=	$D016
AUDCTL	=	$D208
AUDF1	=	$D200
AUDC1	=	$D201
AUDF2	=	$D202
AUDC2	=	$D203
AUDF3	=	$D204
AUDC3	=	$D205
AUDF4	=	$D206
AUDC4	=	$D207
RANDOM	=	$D20A
XITVBV	=	$E462
SETVBV	=	$E45C
SIOINV	=	$E465
NMIEN	=	$D40E
WSYNC	=	$D40A
CONSOL	=	$D01F
;
;PROGRAM REGISTERS
;
	*=	$B0
;
VP0LO	*=	*+1	;Y POS. PLAYER0
VP0HI	*=	*+1
SHP0	*=	*+1	;X POS. PLAYER0
VP1LO	*=	*+1	;Y POS. PLAYER1
VP1HI	*=	*+1
SHM0	*=	*+4	;X POS. MISSILES
VPMLO	*=	*+4	;Y POS. MISSILES
HPOSM	*=	*+1	;X POS. COLLISION
VPM0LO	*=	*+1	;Y POS. COLLISION
VPM0HI	*=	*+1
COLLO	*=	*+1	;COLLISION ADDR
COLHI	*=	*+1
DMLO	*=	*+1	;START SCREEN MEM
DMHI	*=	*+1
DLCNT	*=	*+1	;DLI COUNTER
OLDSET	*=	*+2	;ADDR ROM CHSET
NEWSET	*=	*+2	;ADDR NEW CHSET
;
	*=	$0600
;
STOP	*=	*+1	;PLAYER MOVEMENT?
TEMPHI	*=	*+1	;TEMPS
LOX8	*=	*+1
SAVEX	*=	*+1
TRGCNT	*=	*+1	;READ TRIGGER?
M0SND	*=	*+1	;SOUNDS
HITSND	*=	*+1
P0SND	*=	*+1
LVLSND	*=	*+1
LVLFLG	*=	*+1	;NEW LEVEL?
LEVEL	*=	*+1	;BCD LEVEL #
LEVHEX	*=	*+1	;HEX LEVEL #
LEVORG	*=	*+1	;ORIGINAL LEVEL
P0DEAD	*=	*+1	;PLAYER DEAD?
SPEED	*=	*+1	;BUGS SPEED
BUGCNT	*=	*+1	;# OF BUGS
SCORE	*=	*+3	;SCORE
SCOADD	*=	*+3	;ADD TO SCORE
DIGIT	*=	*+1	;FOR DISPLAY
LIVES	*=	*+1	;LIVES
TIMER	*=	*+1	;DELAY TIMER
CPYCNT	*=	*+1	;PAGES TO MOVE
CPYTMP	*=	*+1	;TEMP
MSTAT	*=	*+1	;WHICH MISSILES OUT
MSTOP	*=	*+4	;DISTANCE TO GO
SPKFLG	*=	*+4	;SPIKE ON?
;
PMB	=	$2800	;PMBASE ADDRESS
CHBASE	=	PMB	;CHARACTER SET BASE
SCOMEM	=	$3000	;SCORE LINE
DMEM	=	SCOMEM+40	;DISPLAY MEMORY
;
;
	*=	$2000
;
	JMP	START
;
;
;DISPLAY LIST FOR TITLE
;
DLTITL	.BYTE	$70,$70,$70,$70,$70
	.BYTE	$47
	.WORD	TITLE
	.BYTE	$70,7,$70,$70,$70,6,$70,$70,6
	.BYTE	$70,$70,$70,$70,$70,$70,$70,6,$30,6
	.BYTE	$41
	.WORD	DLTITL
;
;
;TITLE MEMORY
;
TITLE
	.BYTE	0,0,0,0,0,0,0,43,114,161,58,121
	*=	*+12
	.BYTE	43,97,180,37,114,176,41
	.BYTE	108,172,33,114,179
	*=	*+13
	.BYTE	226,249
	*=	*+14
	.BYTE	228,225,246,233,228,0,232,245,230,230
	*=	*+9
	.BYTE	243,229,236,229,227,244,0
	.BYTE	236,229,246,229,236
	*=	*+8
	.BYTE	240,242,229,243,243,0
	.BYTE	243,244,225,242,244
	*=	*+10
;
;
;GAME DISPLAY LIST
;
DLIST	.BYTE	$70,$70,$70
	.BYTE	$46
	.WORD	SCOMEM
	.BYTE	$86,$C5
	.WORD	DMEM
	.BYTE	$85,$85,$85,$85,$85,$85,$85,$85,$85,$85
	.BYTE	$41
	.WORD	DLIST
;
;
START	CLD
	LDA	#72	;TITLE COLORS
	STA	COLOR0
	LDA	#40
	STA	COLOR0+1
	LDA	#120
	STA	COLOR0+2
	LDA	#104
	STA	COLOR0+3
	LDA	#0	;BACKGND
	STA	COLOR0+4
;
	LDA	#DLTITL&$FF	;SHOW TITLE
	STA	SDLSTL
	LDA	#DLTITL/256
	STA	SDLSTL+1
;
	LDX	#31	;CLEAR PAGE0 REGISTERS
	LDA	#0
CLRP0	STA	$B0,X
	DEX
	BPL	CLRP0
;
	LDX	#0	;CLEAR PAGE6
	TXA
CLRP6	STA	$0600,X
	DEX
	BNE	CLRP6
;
	LDA	#DMEM&$FF	;SET POINTER TO
	STA	DMLO	;SCREEN MEMORY
	LDA	#DMEM/256
	STA	DMHI
	JSR	CLRSM	;CLEAR PLAYFIELD
;
	LDX	#8	;INITIALIZE SOUNDS
	LDA	#0
NOSND	STA	AUDF1,X
	DEX
	BPL	NOSND
	JSR	SIOINV
;
	LDY	#VBLANK&$FF	;START VBI
	LDX	#VBLANK/256
	LDA	#7
	JSR	SETVBV
;
	LDX	#1	;SET LEVEL
	STX	LEVHEX
;
;
;ROTATE TITLE COLORS
;
ROTCOL	LDA	COLOR0+2	;GET COLOR2
	PHA		;SAVE IT
	LDX	#1
COLR	LDA	COLOR0,X	;GET COLOR
	STA	COLOR0+1,X	;MOVE IT
	DEX		;NEXT COLOR
	BPL	COLR
	PLA		;GET COLOR2
	STA	COLOR0	;TO COLOR0
;
	LDA	#15	;DELAY
	STA	TIMER
TM	LDA	CONSOL
	AND	#1	;CHECK START
	BEQ	BEGIN	;PRESSED, BEGIN GAME
	LDA	TIMER	;TIME UP?
	BNE	TM	;NO
;
	LDA	CONSOL
	AND	#2	;CHECK SELECT
	BNE	SHOLEV	;NOT PRESSED
	INC	LEVHEX	;PRESSED
	LDA	#$AA	;BEEP
	STA	AUDC4
	LDA	#121
	STA	AUDF4
	LDA	#10	;DURATION
	STA	LVLSND
SHOLEV	LDA	LEVHEX	;GET LEVEL
	CMP	#10	;TO BIG?
	BCC	OKLEV	;NO
	LDA	#1	;YES,RESET
	STA	LEVHEX
OKLEV	ORA	#$D0	;COLOR3
	LDX	#97
	STA	TITLE,X	;DISPLAY IT
	JMP	ROTCOL	;TITLE ROUTINE
;
BEGIN	DEC	LEVHEX	;WANT (0-9)
	LDX	LEVHEX	;START LEVEL
	STX	LEVEL
	STX	LEVORG	;KEEP ORIGINAL LEVEL
;
;
;REDEFINE CHARACTERS
;
	LDA	#$E0	;ADDR ROM CHSET
	STA	OLDSET+1
	LDA	#CHBASE/256	;NEW CHBASE
	STA	NEWSET+1
	LDA	#0	;LOW BYTES
	STA	OLDSET
	STA	NEWSET
;
	LDX	#1	;DO 2 PAGES OF CHSET
CH1	LDY	#0
CH2	LDA	(OLDSET),Y	;GET ROM
	STA	(NEWSET),Y	;PUT IN RAM
	DEY
	BNE	CH2
	INC	OLDSET+1	;DO NEXT PAGE
	INC	NEWSET+1
	DEX
	BPL	CH1
;
NEWCH	LDX	#39	;REDEFINE CHARACTERS
NEW1	LDA	CHR1,X	;GET CHAR DATA
	STA	CHBASE,X	;MOVE IT
	DEX
	BPL	NEW1
;
;GAME COLORS
;
	LDA	#28	;SCORE NUMBERS
	STA	COLOR0
	LDA	#136	;SCORE LETTERS
	STA	COLOR0+1
	LDA	#204	;BUGS LEGS
	STA	COLOR0+2
	LDA	#42	;MISSILES
	STA	COLOR0+3
	LDA	#0	;BACKGND
	STA	COLOR0+4
;
	LDA	#DLIST&$FF	;GAME DISPLA ON
	STA	SDLSTL
	LDA	#DLIST/256
	STA	SDLSTL+1
;
	LDA	#DLI&$FF	;SET DLI VECTOR
	STA	VDSLST
	LDA	#DLI/256
	STA	VDSLST+1
;
	LDA	#$C0	;ENABLE DLI
	STA	NMIEN
;
	LDA	#CHBASE/256	;SWITCH CHAR BASE
	STA	CHBAS
;
	LDA	#3	;ENABLE P/M
	STA	GRACTL
	LDA	#62	;SINGLE LINE RES.
	STA	SDMCTL
	LDA	#PMB/256	;HI BYTE PMBASE
	STA	PMBASE
	LDA	#16	;FIFTH PLAYER ENABLE
	STA	GPRIOR
	LDX	#0	;NORMAL SIZE
	STX	SIZEP0
	STX	SIZEM
	LDA	#PMB/256+4	;PLAYER0 BASE
	STA	VP0HI
	LDA	#PMB/256+3	;MISSILE BASE
	STA	VPM0HI
	JSR	CLRPM	;CLEAR P/M AREA
;
RESET	LDX	#39	;DISPLAY SCORE LINE
SCRLN	LDA	SCOLN,X
	STA	SCOMEM,X
	DEX
	BPL	SCRLN
;
	LDX	#0	;SCORE = 0
	STX	SCORE
	STX	SCORE+1
	STX	SCORE+2
	JSR	DISPSCO	;PUT ON SCORE
;
	LDX	#4	;4 LIVES
	STX	LIVES
	JSR	NEWLVL	;GET FIRST LEVEL
;
	LDX	#1	;ENABLE MOVEMENT
	STX	STOP
	STX	HITCLR	;CLEAR COLLISIONS
;
;
;
;MAIN LOOP
;
PLAY	JSR	COPY	;MOVE BUGS
	JSR	MFIRE	;MOVE MISSILES
	JSR	DISPSCO	;SHOW SCORE
	JSR	DELAY	;SLOW IT DOWN
	JSR	MFIRE	;MOVE AGAIN
	JSR	CKLEV	;CHECK LEVEL
	LDA	LVLFLG	;COMPLETE?
	BEQ	CHKP0	;NO
	JSR	NEWLVL	;YES,DO NEXT LEVEL
;
CHKP0	LDA	P0DEAD	;PLAYER DEAD
	BEQ	ALIVE	;NO
	JMP	KILLP0	;YES,EXPLOSION
;
ALIVE	JMP	PLAY	;CONTINUE GAME
;
;
;PLAYER KILLED
;
KILLP0	LDA	#0	;NO MOTION
	STA	STOP
	STA	P0DEAD	;RESET FLAG
;
	LDY	#17	;SHOW EXPLOSION
EXP	LDA	EXPLODE,Y	;DATA
	STA	(VP0LO),Y	;SHOW IT
	DEY
	BPL	EXP
;
	LDA	#32	;TURN ON SOUND
	STA	AUDF3
	LDA	#34
	STA	P0SND
DLY	LDA	P0SND	;WAIT
	BNE	DLY
;
	JSR	CLRPM	;CLEAR P/M AREA
;
	DEC	LIVES	;LOSE A LIFE
	LDA	LIVES	;ANY LEFT?
	BEQ	DEAD	;NO
	JSR	DISPLIV	;YES,SHOW THEM
	JSR	CLRSM	;CLEAR SCREEN
	JSR	SETUP	;SETUP LEVEL
	JSR	STARTP0	;RESTART
	LDA	#1
	STA	HITCLR	;CLEAR COLLISION
	STA	STOP	;ALLOW MOVEMENT
	JMP	PLAY	;TO MAIN LOOP
;
;
;
; GAME OVER ROUTINE
;
DEAD	LDX	#8
DD1	LDA	MESSAGE,X	;GAME OVER
	STA	SCOMEM+25,X	;SHOW IT
	DEX
	BPL	DD1
;
	JSR	CLRSM	;CLEAR SCREEN
	LDA	#10
	STA	BUGCNT	;10 BUGS
	JSR	SET1	;SHOW THEM
	LDA	#10
	STA	BUGCNT	;10 BUGS
	INC	DMHI	;NEXT PAGE
	JSR	SET1	;SHOW THEM
	DEC	DMHI	;RESTORE
;
WAIT	LDA	CONSOL
	AND	#1	;START?
	BNE	WT1	;NO
WT2	LDA	CONSOL	;YES
	AND	#1	;RELEASED?
	BEQ	WT2	;NO
	JMP	START	;YES, DO TITLE
;
WT1	LDA	STRIG0	;PRESSED?
	BEQ	RESTART	;YES
	LDA	TIMER	;TIME UP?
	BNE	WAIT	;NO
	JSR	COPY	;MOVE BUGS
	LDA	#10	;RELOAD TIMER
	STA	TIMER
	JMP	WAIT	;KEEP CHECKING
;
RESTART	LDX	LEVORG	;ORIGINAL LEV
	STX	LEVEL	;RESET
	STX	LEVHEX
	JSR	CLRSM	;CLEAR SCREEN
	JMP	RESET	;RESTART
;
;
;
;
;SUBROUTINES
;
;
;MISSILE ROUTINES
;
MFIRE	LDX	#3	;DO 4 MISSILES
CKP0	LDA	M0PL,X	;PLAYER HIT?
	BEQ	NOMHIT	;NO
	INC	P0DEAD	;YES,SET FLAG
	JMP	FMEXIT	;DONE
NOMHIT	DEX		;NEXT MISSILE
	BPL	CKP0
;
	LDX	#3	;DO 4 MISSILES
CKM	LDA	M0PF,X	;BUG HIT?
	BEQ	NOHIT	;NO
	JSR	KILLBUG	;YES, DESTROY IT
NOHIT	DEX		;NEXT MISSILE
	BPL	CKM
;
	LDX	#1	;CLEAR COLLISIONS
	STX	HITCLR
;
	LDX	#3	;MOVE MISSILES IF OUT
FIREM	LDA	MSTAT	;MISSILE STATUS
	AND	MDATA,X	;IS IT OUT?
	BEQ	NOMOVE	;NO
	JSR	MOVEM	;YES, MOVE IT
NOMOVE	DEX		;NEXT ONE
	BPL	FIREM
;
TRIG	LDA	TRGCNT	;CHECK TRIG?
	BEQ	CKTRIG	;YES
	DEC	TRGCNT	;NO
	JMP	FMEXIT	;DONE
;
CKTRIG	LDA	#4	;RESET IT
	STA	TRGCNT
	LDA	STRIG0	;PRESSED?
	BEQ	LAUNCH	;YES, TRY TO FIRE
	JMP	FMEXIT	;NO
;
LAUNCH	LDX	#3
NEXTM	LDA	MSTAT	;ANY AVAILABLE?
	AND	MDATA,X	;CHECK BITS
	BNE	MOUT	;NO,ALREADY OUT
	LDA	MDATA,X	;YES
	ORA	MSTAT	;UPDATE MSTAT
	STA	MSTAT	;TO SHOW IT'S OUT
	JSR	STARTM	;START IT
	JMP	FMEXIT	;CAN ONLY FIRE 1
MOUT	DEX		;TRY NEXT ONE
	BPL	NEXTM
	JMP	FMEXIT
;
STARTM	LDA	#$A6	;MISSILE SOUND
	STA	AUDC1
	LDA	#15
	STA	M0SND
;
	LDA	SHP0	;GET PLAYERS X POS.
	CLC
	ADC	#3	;OFFSET
	STA	HPOSM0,X
	STA	SHM0,X	;SAVE MISSILE POS.
;
	SEC
	LDA	VP0LO	;PLAYERS VERT .POS
	SBC	#5	;OFFSET
	STA	VPMLO,X	;SAVE IT
;
	LDA	#65	;MOVE IT 65 TIMES
	STA	MSTOP,X
;
	JSR	MOVEM	;MOVE IT
	RTS
;
MOVEM	LDA	VPMLO,X	;GET Y
	STA	VPM0LO	;SAVE IT
;
	DEC	MSTOP,X	;DONE?
	BEQ	CLEARM	;YES, CLEAR IT
;
	LDA	SPKFLG,X	;SPIKE?
	BNE	SPIKE	;YES
	LDY	#2	;NO,ERASE OLD POS.
CLRM	LDA	MDATA,X	;GET BITS
	EOR	#$FF	;MAKE MASK
	AND	(VPM0LO),Y	;ZERO BITS
	STA	(VPM0LO),Y	;MISSILE OFF
	DEY
	BPL	CLRM
;
SPIKE	SEC
	LDA	VPM0LO	;OLD Y
	SBC	#3	;MOVE UP 3
	STA	VPM0LO
	STA	VPMLO,X	;SAVE NEW Y
	CMP	#50	;TOP LIMIT
	BCC	SPKON	;YES,SPIKE ON
	LDY	#2	;NO
LOADM	LDA	(VPM0LO),Y
	ORA	MDATA,X	;GET MISSILE BITS
	STA	(VPM0LO),Y	;MISSILE ON
	DEY
	BPL	LOADM
	RTS
;
SPKON	LDA	#255	;SPIKE ON
	STA	VPMLO,X	;MISSILE TO BOTTOM
	STA	SPKFLG,X	;SET FLAG
	RTS
;
CLEARM	LDY	#0	;ERASE A MISSILE
	LDA	#0
	STA	VPM0LO
CLM	LDA	MDATA,X	;GET MISSILE BITS
	EOR	#$FF	;MAKE MASK
	AND	(VPM0LO),Y	;ZERO BITS
	STA	(VPM0LO),Y	;TURN IT OFF
	DEY		;DO ALL OF MISSILE
	BNE	CLM
;
	LDA	#0	;RESET
	STA	MSTOP,X
	STA	SPKFLG,X
;
	LDA	MDATA,X	;MISSILE BITS
	EOR	MSTAT	;MISSILE NOT OUT
	STA	MSTAT	;UPDATE MSTAT
	RTS
;
;
KILLBUG	JSR	CLEARM	;HIT A BUG
	LDA	VPMLO,X	;GET Y POS.
	STA	VPM0LO
	LDA	SHM0,X	;GET X POS
	STA	HPOSM
;
	STX	SAVEX	;SAVE MISSILE #
	JSR	FIND	;GET MEMORY LOCATION
;
	LDA	#0	;ERASE THE BUG
	STA	(COLLO),Y	;FIRST PART
	INY
	STA	(COLLO),Y	;SECOND PART
;
	LDA	#$20	;UP SCORE
	STA	SCOADD+2
;
	LDA	#$A8	;SOUND ON
	STA	AUDC2
	LDA	#11
	STA	HITSND
	LDX	SAVEX	;RECOVER MISSILE #
	RTS
;
FMEXIT	RTS		TO MAIN LOOP
;
MDATA	.BYTE	3,12,48,192
;
;
;
;SHOW NEXT LEVEL
;
NEWLVL	SED		;BCD ADDITION
	CLC
	LDA	LEVEL	;BCD LEVEL
	ADC	#1
	STA	LEVEL
	CLD
;
	LDA	#0
	STA	STOP	;STOP MOVEMENT
	STA	LVLFLG	;RESET FLAG
;
	INC	LEVHEX	;HEX LEVEL
	LDA	LEVHEX
	CMP	#16	;TOO BIG?
	BCC	LEVOK	;NO
	LDA	#14	;YES
	STA	LEVHEX
LEVOK	LDX	LEVHEX	;INDEX
	LDA	LEVSPEED,X	;GET LEVEL SPEED
	STA	SPEED	;FOR COPY ROUTINE
;
	LDA	#$A8	;NEW LEVEL SOUND
	STA	AUDC4
	LDA	#200
	STA	AUDF4
	LDA	#80	;SOUND DURATION
	STA	LVLSND
;
	JSR	CLRPM	;CLEAR P/M
	JSR	DISPLIV	;SHOW LIVES
	JSR	DISPSCO	;SHOW SCORE
	JSR	SETUP	;NEXT LEVEL
	JSR	STARTP0	;START PLAYER
;
	LDA	#150	;DELAY BETWEEN LEVELS
	STA	TIMER
DLEV1	LDA	TIMER
	BNE	DLEV1
	LDA	#1
	STA	STOP	;ALLOW MOVEMENT
	RTS
;
LEVSPEED	.BYTE	0,30,25,20,25,17,10,15
	.BYTE	12,10,10,7,6,5,5,4
;
;
;
DELAY	LDX	SPEED	;SLOW IT DOWN
DE1	LDY	#255
DE2	DEY
	BNE	DE2
	DEX
	BNE	DE1
	RTS
;
;
;
;MOVE THE BUGS
;
COPY	LDX	#2	;DO 2 PAGES
	STX	CPYCNT
;
	LDY	#$FF
	INC	DMHI
	LDA	(DMLO),Y	;GET LAST BYTE
	TAX		;SAVE IT
	DEC	DMHI	;RESTORE
;
CPY1	LDY	#0	;SET TO FIRST BYTE
CPY2	STX	CPYTMP
	LDA	(DMLO),Y	;GET BYTE
	TAX		;STORE
	LDA	CPYTMP	;GET PREVIOUS BYTE
	STA	(DMLO),Y	;MOVE IT
	INY		;NEXT BYTE
	BNE	CPY2
;
	INC	DMHI	;NEXT PAGE
	DEC	CPYCNT	;DONE?
	BNE	CPY1	;NO
;
	DEC	DMHI	;YES,RESTORE
	DEC	DMHI
	RTS
;
;
;
;CALCULATE SCREEN MEMORY ADDRESS
;FROM P/M COORDINATES
;
FIND	SEC
	LDA	HPOSM	;X POS
	SBC	#48	;OFFSET
	LSR	A	;/2
	LSR	A	;/4
	TAX		;X COORD
;
	LDA	#0	;CLEAR
	STA	TEMPHI
;
	SEC		;Y=Y/16*40 BYTES/LINE
	LDA	VPM0LO	;Y POS
	SBC	#48	;OFFSET
	AND	#$F0	;Y/16*16
	LSR	A	;SHIFT RIGHT (*8)
	STA	LOX8	;SAVE *8
;
	ASL	A	;*16
	ASL	A	;*32
	ROL	TEMPHI	;SHIFT CARRY
;
	CLC		;ADD *8+*32=*40
	ADC	LOX8
	STA	COLLO	;*40 LO
	LDA	TEMPHI
	ADC	#0
	STA	COLHI	;*40 HI
;
	CLC		;GET FINAL COLLISION ADDR
	LDA	#DMEM&$FF	;SCREEN MEM
	ADC	COLLO	;ADD POSITION
	STA	COLLO	;COLLISION ADDR LO
	LDA	#DMEM/256
	ADC	COLHI
	STA	COLHI	;COLLISION ADDR HI
;
	TXA		;GET X
	TAY		;Y=INDEX FOR X POS
	RTS
;
;
;
;SCORE AND LEVEL DISPLAY
;
DISPSCO	SED		;BCD ADDITION
	CLC
	LDX	#2	;DO 3 BYTES
TOTAL	LDA	SCORE,X	;GET OLD SCORE
	ADC	SCOADD,X	;ADD TO SCORE
	STA	SCORE,X	;SAVE SCORE
	DEX
	BPL	TOTAL
	CLD
;
	LDX	#2	;CLEAR SCOADD
	LDA	#0
ZERO	STA	SCOADD,X
	DEX
	BPL	ZERO
;
	LDX	#6	;POSITION 6
	LDY	#0
SCODP	LDA	SCORE,Y	;GET BYTE
	JSR	DISP	;DISPLAY IT
	INX		;NEXT POSITION
	INX
	INY		;NEXT BYTE
	CPY	#3	;DO 3 BYTES
	BNE	SCODP
;
DISPLVL	LDX	#17	;POSITION 17
	LDA	LEVEL	;LEVEL
	JSR	DISP	;DISPLAY IT
;
	RTS
;
;
DISP	STA	DIGIT	;BCD # TO SHOW
	AND	#$0F	;LOWER NIBBLE
	ORA	#$10	;COLOR0
;
	STA	SCOMEM+1,X	;DISLPAY IT
	LDA	DIGIT	;GET BCD #
	LSR	A	;GET HIGH NIBBLE
	LSR	A
	LSR	A
	LSR	A
	ORA	#$10	;COLOR0
	STA	SCOMEM,X	;DISPLAY IT
	RTS
;
;
;
;DISPLAY REMAINING LIVES
;
DISPLIV	LDA	#PMB/256+5	;PLAYER 1 Y POS.
	STA	VP1HI
	LDA	#38
	STA	VP1LO
;
	LDX	#3	;REMOVE ALL
	LDA	#0	;FROM SCREEN
LD1	STA	HPOSP0,X
	DEX
	BNE	LD1
;
	LDA	#26	;COLORS
	STA	PCOLR0+1
	STA	PCOLR0+2
	STA	PCOLR0+3
;
	LDX	#2	;DO 3 PLAYERS
LD2	LDY	#13
LD3	LDA	P0DATA,Y	;SHAPE DATA
	STA	(VP1LO),Y	;SHOW IT
	DEY
	BPL	LD3
	INC	VP1HI	;NEXT PLAYER
	DEX
	BPL	LD2
;
	LDX	LIVES
	DEX		;SHOW ONE LESS
	BEQ	LD5	;NONE TO SHOW
LD4	LDA	TABX,X	;POSITIONS
	STA	HPOSP0,X	;SHOW PLAYERS
	DEX
	BNE	LD4
LD5	RTS
;
TABX	.BYTE	0,176,183,190
;
;
;
;DISPLAY LIST INTERRUPT
;
DLI	PHA		;SAVE X,Y,A
	TXA
	PHA
	TYA
	PHA
;
	LDX	DLCNT	;WHICH LINE
	LDA	BODYCLR,X	;COLOR0
	LDY	SPOTCLR,X	;COLOR1
	STA	WSYNC	;WAIT FOR SYNC
	STA	COLPF0	;CHANGE HARDWARE REG
	STY	COLPF0+1
	INC	DLCNT	;NEXT LINE
	CPX	#11	;LAST ONE?
	BNE	DLIEND	;NO
	LDX	#0	;YES
	STX	DLCNT	;RESET TO TOP
;
DLIEND	PLA		;RESTORE X,Y,A
	TAY
	PLA
	TAX
	PLA
	RTI
;
BODYCLR	.BYTE	134,198,24,86,126,182,70,42,6,102,14
;
SPOTCLR	.BYTE	14,26,60,28,136,202,122,70,28,60,168
;
;
;
;
;CLEAR P/M MEMORY
;
CLRPM	LDA	#0	;MISSILE BASE
	STA	VPM0LO
;
	LDX	#5	;DO 5 PAGES UP
	LDA	#0
	TAY
CPM	STA	(VPM0LO),Y	;CLEAR IT
	DEY
	BNE	CPM
	INC	VPM0HI	;NEXT PAGE
	DEX
	BNE	CPM
;
	LDA	#PMB/256+3	;RESET
	STA	VPM0HI
;
	LDX	#3	;UPDATE TO SHOW
	LDA	#0	;ALL MISSILES OFF
OFF	STA	SPKFLG,X
	STA	MSTOP,X
	STA	MSTAT
	DEX
	BPL	OFF
;
	RTS
;
;
;
;START PLAYER
;
STARTP0	LDA	#128	;Y START POS.
	STA	VP0LO
	LDA	#100	;X
	STA	HPOSP0
	STA	SHP0
;
	LDA	#14
	STA	PCOLR0	;COLOR P0
;
	LDY	#13
DISP0	LDA	P0DATA,Y	;SHAPE DATA
	STA	(VP0LO),Y	;SHOW IT
	DEY
	BPL	DISP0
;
	RTS
;
;
;
;CLEAR SCREEN MEMORY
;
CLRSM	LDX	#1	;2 PAGES
	LDA	#0
	TAY
CSM	STA	(DMLO),Y	;CLEAR IT
	DEY
	BNE	CSM
	INC	DMHI	;NEXT PAGE
	DEX
	BPL	CSM
;
	LDA	#DMEM/256	;RESTORE
	STA	DMHI
;
	RTS
;
;
;
;PLAYFIELD SETUP
;
SETUP	JSR	RNDPF	;PUT ON BUGS
	INC	DMHI	;NEXT PAGE OF MEMORY
	JSR	RNDPF	;MORE BUGS
	DEC	DMHI	;RESTORE
;
	CLC
	LDA	DMLO	;FIND ADDR
	ADC	#160	;SCREEN CENTER
	STA	DMLO
	LDA	DMHI
	ADC	#0
	STA	DMHI
;
	LDY	#160	;CLEAR 4 LINES
	LDA	#0	;IN SCREEN CENTER
CP0S	STA	(DMLO),Y	;FOR START
	DEY
	BNE	CP0S
;
	LDA	#DMEM&$FF	;RESTORE
	STA	DMLO
	LDA	#DMEM/256
	STA	DMHI
	RTS
;
;
RNDPF	LDX	LEVHEX	;INDEX
	LDA	BUGLEV,X	;# TO DISPLAY
	STA	BUGCNT
;
SET1	LDY	RANDOM	;POSITION
	JSR	BUG	;SHOW THEM
	DEC	BUGCNT	;ANY MORE?
	BPL	SET1	;YES
	RTS		;NO
;
BUG	LDX	#4	;CHARACTERS 1-4
SBUG	TXA
	STA	(DMLO),Y	;SHOW BUGS
	DEY
	DEX
	BNE	SBUG
;
	RTS
;
BUGLEV	.BYTE	0,6,10,15,25,16,10
	.BYTE	20,22,25,25,27,30,30,35,35
;
;
;
;CHECK IF LEVEL COMPLETE
;
CKLEV	LDX	#1	;2 PAGES
	LDY	#0
CKL1	LDA	(DMLO),Y	;GET MEMORY
	BNE	NOTDONE	; IF<>0 NOT DONE
	DEY		;CHECK NEXT
	BNE	CKL1
	INC	DMHI	;NEXT PAGE
	DEX
	BPL	CKL1
;
	LDX	#1	;ALL ZERO,LEVEL DONE
	STX	LVLFLG	;SET FLAG
	BNE	LVLDONE
;
NOTDONE	LDX	#0	;NOT DONE
	STX	LVLFLG
LVLDONE	LDA	#DMEM/256	;RESET
	STA	DMHI
;
	RTS
;
;
;
;
;
; VBLANK ROUTINE
;
;
VBLANK	CLD
;
	LDX	TIMER	;COUNT DOWN TIMER
	BEQ	SOUND1
	DEC	TIMER
;
SOUND1	LDX	M0SND	;MISSILE SOUND ON?
	BEQ	NOSND1	;NO
	LDA	M0SND1,X	;YES, NEXT FREQ
	STA	AUDF1
	DEC	M0SND
	BNE	SOUND2
NOSND1	LDA	#0	;OFF
	STA	AUDC1
;
SOUND2	LDX	HITSND	;BUG HIT SND ON?
	BEQ	NOSND2	;NO
	LDA	HITSND2,X	;YES, NEXT FREQ
	STA	AUDF2
	DEC	HITSND
	BNE	SOUND3
NOSND2	LDA	#0	;OFF
	STA	AUDC2
;
SOUND3	LDA	P0SND	;BLOW UP SND ON?
	BEQ	NOSND3	;NO
	LSR	A	;YES,/2
	STA	AUDC3
	DEC	P0SND
	BNE	SOUND4
NOSND3	LDA	#0	;OFF
	STA	AUDC3
;
SOUND4	LDX	LVLSND	;SOUND 4 ON?
	BEQ	NOSND4	;NO
	DEC	LVLSND	;YES
	BNE	STOPVB
NOSND4	LDA	#$00	;OFF
	STA	AUDC4
;
STOPVB	LDA	STOP	;CONTINUE?
	BNE	COLCK	;YES
EXIT	JMP	XITVBV	;NO
;
COLCK	LDA	P0PF	;PLAYER HIT?
	BEQ	MOVE	;NO
	INC	P0DEAD	;YES,SET FLAG
	JMP	EXIT
;
MOVE	LDX	SHP0	;PLAYER X POS
	LDY	VP0LO	;Y POS
;
	LDA	STICK0
	LSR	A	;CHECK D0
	BCS	NOTUP	;SET,NO MOTION
	DEY		;NOT SET,MOVE UP 2
	DEY
;
NOTUP	LSR	A	;CHECK D1
	BCS	NOTDOWN	;NO
	INY		;MOVE DOWN 2
	INY
;
NOTDOWN	LSR	A	;CHECK D2
	BCS	NOTLEFT	;NO
	DEX		;MOVE 2 LEFT
	DEX
;
NOTLEFT	LSR	A	;CHECK D3
	BCS	NOTRT	;NO
	INX		;MOVE 2 RIGHT
	INX
;
NOTRT	CPX	#50	;LEFT LIMIT
	BCC	BADX	;TOO FAR
	CPX	#208	;RIGHT LIMIT
	BCC	GOODX	;OK? YES
	LDX	#50	;NO,RESET TO LEFT
GOODX	STX	SHP0	;NEW X POS
	STX	HPOSP0
;
BADX	CPY	#90	;UPPER LIMIT
	BCC	BADY	;TOO FAR? YES
	CPY	#185	;LOWER LIMIT
	BCS	BADY	;TOO FAR? YES
	STY	VP0LO	;OK, SAVE IT
;
BADY	LDY	#13	;READ IN PLAYER
LP1	LDA	P0DATA,Y	;AT VP0LO
	STA	(VP0LO),Y
	DEY
	BPL	LP1
;
	LDA	#0	;STOP ATTRACT
	STA	ATRACT
	JMP	EXIT	;ALL DONE
;
;
;
;DATA TABLES
;
P0DATA
	.BYTE	0,0,8,8,8,28,28,62,62,62,62,62,0,0
;
EXPLODE
	.BYTE	8,16,74,34,72,68,16,133,16
	.BYTE	4,162,20,69,18,72,18,8,16
;
M0SND1
	.BYTE	230,240,250,255,230,200,180,170,150,130
	.BYTE	100,75,65,50,45,40
;
HITSND2
	.BYTE	120,100,90,80,75,70,50,40,30,20,10,5
;
MESSAGE
	.BYTE	167,161,173,165,0,175,182,165,178
;
CHR1	.BYTE	0,0,0,0,0,0,0,0
	.BYTE	0,12,51,86,90,86,51,12
	.BYTE	0,204,51,149,165,149,51,204
	.BYTE	0,204,51,86,90,86,51,204
	.BYTE	0,192,48,148,165,148,48,192
;
SCOLN
	.BYTE	$73,$63,$6F,$72,$65,0,0,0,0,0,0,0,0
	.BYTE	$6C,$76,$6C,0,0,0
	*=	*+21
;
	.END