;------------------------------------------------
;
; My VCS Game
; by Author
;
;------------------------------------------------
    processor 6502
    include vcs.h
	include macro.h
	
;------------------------------------------------
; Constants
;------------------------------------------------
SKY         = #0
ROAD        = #0
ROAD_LINES  = #$1F
ROAD_START  = #15

UFO_HEIGHT  = #14
UFO_COLOR   = #$60
UFO_GEAR    = #$82

ERR_HEIGHT  = #13
ERR_COLOR   = #$57

VAN_HEIGHT  = #8
VAN_COLOR	= #$C0

BUILDING_COLOR = #$F0
WINDOW_COLOR   = #$1F

;------------------------------------------------
; Variables
;------------------------------------------------
    SEG.U   variables
    ORG     $80

UfoXPos				ds 1
UfoYPos				ds 1
UfoMissileActive	ds 1
UfoMissileY			ds 1
UfoMissileBuffer	ds 1
UfoLife				ds 1

ErrXPos			ds 1
ErrYPos			ds 1
ErrDeployed		ds 1
ErrTimeLeft		ds 1
ErrLife			ds 1
ErrBuildTime	ds 1

VanXPos				ds 1
VanMissileActive	ds 1
VanMissileY			ds 1
VanMissileBuffer	ds 1
VanLife				ds 1

Grp0Buffer		ds 1
Grp0Line		ds 1
Grp1Buffer		ds 1
Grp1Line		ds 1
BgColor			ds 1

BuildingLife	ds 1
Windows			ds 1

FrameCounter	ds 1
UfoAttackSound	ds 1
VanAttackSound	ds 1

DeathScreen		ds 1
DeathLine		ds 1

;------------------------------------------------
; START OF ROM
;------------------------------------------------
    SEG   Bank0
	ORG   $F000       	; 4k ROM start point

Start 
	CLEAN_START			; Clear RAM and Registers
	lda	#SKY
	sta BgColor
	sta COLUBK
	lda	#WINDOW_COLOR
	sta	COLUPF
	lda #UFO_COLOR
	sta	COLUP0
	lda #UFO_GEAR
	sta COLUP1
	
	;--- sprite settings
	lda #%00010101
	sta NUSIZ0
	sta NUSIZ1
	
	lda #30
	sta	UfoYPos
	sta ErrYPos
	lda #30
	sta UfoXPos
	sta ErrXPos
	sta VanXPos

	lda #1
	sta ErrDeployed
	
	lda #UFO_COLOR
	sta UfoLife
	
	lda #UFO_GEAR
	sta ErrLife
	
	lda #VAN_COLOR
	sta VanLife
	
	lda #BUILDING_COLOR
	sta BuildingLife

	lda #1
	sta CTRLPF

	lda #0
	sta FrameCounter
	sta DeathScreen
	
	lda #0
    sta UfoAttackSound
	sta VanAttackSound
	sta AUDV0
	sta AUDV1
    
	;Van Sound
	lda #2
	sta AUDC1
	lda #4
	sta AUDF1
	
    lda #2
    sta AUDC0

	;--- missile settings	
	lda #%00000010
	sta	RESMP0
	sta	RESMP1
	lda #0
	sta UfoMissileActive
	sta VanMissileActive
	
	jmp MainLoop
	


PositionVan

PositionVanBody
    sta WSYNC           ;begin scanline
    ldy VanXPos    ;+3  3
    lda HorzTable,Y     ;+4  7
    sta HMP0            ;+3 10
    and #$0F            ;+2 12
    tay                 ;+2 14
VBody  
    dey                 ;+2 16
    bpl VBody            ;when branch not taken: +2 (18 + x*5)
    sta RESP0           ;(21 + x*5)
    sta WSYNC

PositionVanWheels
    sta WSYNC           ;begin scanline
    ldy VanXPos    ;+3  3
    lda HorzTable,Y     ;+4  7
    sta HMP1            ;+3 10
    and #$0F            ;+2 12
    tay                 ;+2 14
VWheels  
    dey                 ;+2 16
    bpl VWheels            ;when branch not taken: +2 (18 + x*5)
    sta RESP1           ;(21 + x*5)
    sta WSYNC
    sta HMOVE
    sleep #24
	rts




MainLoop
	lda #0
	sta	VBLANK
	VERTICAL_SYNC
    lda     #43
    sta     TIM64T


;----- Check Joystick 0
.checkJoy0Up
    lda #%00010000    		;Up?
    bit SWCHA
    bne .checkJoy0Down
    lda UfoYPos
    cmp #64
    beq .checkJoy0Right
    inc UfoYPos
    lda ErrDeployed
	beq .checkJoy0Right
	inc ErrYPos
    jmp	.checkJoy0Right

.checkJoy0Down
    lda #%00100000    		;Down?
    bit SWCHA
    bne .checkJoy0Right
    lda UfoYPos
	cmp #30
   	beq .checkJoy0Right
    dec UfoYPos
	lda ErrDeployed
	beq .checkJoy0Right
	dec ErrYPos
	jmp	.checkJoy0Right

.checkJoy0Right
    lda #%10000000          ;Right?
    bit SWCHA
    bne .checkJoy0Left
	lda UfoXPos
	cmp #135
	beq .checkJoy0Left
	inc UfoXPos
	lda ErrDeployed
	beq .moveUfoDone
	inc ErrXPos
	jmp .moveUfoDone
    
.checkJoy0Left
    lda #%01000000          ;Left?
    bit SWCHA
    bne .moveUfoDone
	lda UfoXPos
	cmp #13
	beq .moveUfoDone
	dec UfoXPos
	lda ErrDeployed
	beq .moveUfoDone
	dec ErrXPos



;----- Finish Move
.moveUfoDone

;----- Missiles
.disposeUfoMissile
	lda UfoMissileY
	cmp #0
	bne .disposeVanMissile
	lda #0
	sta UfoMissileActive

.disposeVanMissile
	lda VanMissileY
	cmp #65
	bne .checkFireUfoMissile
	lda #0
	sta VanMissileActive

.checkFireUfoMissile
	dec UfoMissileY
	
.checkActivateUfoMissile		
	lda #$80
	bit INPT4
	bne .done
	lda ErrDeployed
	beq .fireMissile
	lda #0
	sta ErrDeployed
	lda #ERR_COLOR
	sta ErrLife
	lda ErrYPos
	sta ErrBuildTime
.fireMissile
	lda UfoMissileActive
	bne .done
	lda	UfoYPos
	sbc #UFO_HEIGHT
	sta	UfoMissileY
	lda #%00000010
	sta	RESMP1
	lda #1
	sta UfoMissileActive




.done



;; COLLISION

.checkUfoHit
    lda	CXM1P
	bmi .ufoHits
	jmp .checkVanHit
.ufoHits
	lda UfoMissileY
	cmp #ROAD_START
	bcs .checkVanHit
    lda #15
    sta UfoAttackSound
	lda #0
	sta UfoMissileY
	inc VanLife

.checkVanHit
	lda CXM0P
	bmi .vanHitsUfo
	asl
	bmi .vanHitsErr
	jmp .nocollide
.vanHitsErr
	lda ErrDeployed
	bne .vanHitsUfo
	inc ErrLife
	jmp .vanHits
.vanHitsUfo
	inc UfoLife
.vanHits
	lda #15
	sta VanAttackSound
	lda #65
	sta VanMissileY

.nocollide



.checkUfoAttackSound
	ldx UfoAttackSound
	beq .checkVanAttackSound
	dex
	stx UfoAttackSound
	stx AUDV0
	
.checkVanAttackSound
	ldx VanAttackSound
	beq .soundsDone
	dex 
	stx VanAttackSound
	stx AUDV1
	
.soundsDone



.resetPF
;----- reset PF
	lda	#0
	sta	PF0
	sta	PF1
	sta	PF2
	sta CXCLR

	lda	#WINDOW_COLOR
	sta	COLUPF
	lda ErrLife
	sta	COLUP0
	lda UfoLife
	sta COLUP1





		
;----- horiz position
.waitForVBlank
	lda INTIM
	bne .waitForVBlank

	lda DeathScreen
	beq StartDrawing
	jmp DeathLoop



;; missile drawing routines

MissileCode

.checkUfoMissile
	lda UfoMissileActive
	beq .noUfoMissile
	cpx UfoMissileY
	bne .noUfoMissile
	lda #%00000010
	sta UfoMissileBuffer
	lda #0
	sta	RESMP1
	beq .checkVanMissile

.noUfoMissile
	sta UfoMissileBuffer
	
.checkVanMissile
	lda VanMissileActive
	beq .noVanMissile
	cpx VanMissileY
	bne .noVanMissile
	lda #%00000010
	sta VanMissileBuffer
	lda #0
	sta RESMP0
	beq .returnFromMissile

.noVanMissile
	sta VanMissileBuffer
	
.returnFromMissile
	rts


UfoDrawingCode

.checkUfo
	cpx UfoYPos
	bne .skipUfo
	lda #UFO_HEIGHT
	sta	Grp0Line

.skipUfo
	ldy Grp0Line
	beq .checkSecondSprite
	
.drawUfo
    lda UfoBody-1,Y
    sta Grp0Buffer
    dec Grp0Line


.checkSecondSprite
	lda ErrDeployed
	beq .checkErr

.checkGear
	cpx ErrYPos
	bne .skipGear
	lda #UFO_HEIGHT
	sta	Grp1Line

.skipGear
	ldy Grp1Line
	beq .returnFromDrawing
	
.drawGear
    lda UfoGear-1,Y
    sta Grp1Buffer
    dec Grp1Line
	jmp .returnFromDrawing

.checkErr
	cpx ErrYPos
	bne .skipErr
	lda #ERR_HEIGHT
	sta	Grp1Line

.skipErr
	ldy Grp1Line
	beq .returnFromDrawing
	
.drawErr
    lda ErrBody-1,Y
    sta Grp1Buffer
    dec Grp1Line
	jmp .returnFromDrawing

.returnFromDrawing
	rts

;----- DRAW THE VISIBLE SCREEN
StartDrawing

	ldx #64
.drawscreen
	sta WSYNC
	lda BgColor
	sta COLUBK
	lda Windows
	sta PF1
	sta PF2
	lda	Grp0Buffer
	sta	GRP1
	lda Grp1Buffer
	sta GRP0
	lda UfoMissileBuffer
	sta ENAM1
	lda VanMissileBuffer
	sta ENAM0

	sta WSYNC

	jsr MissileCode

	
.checkBuildingStart
	cpx #53
	beq .setBuildingColor
	bcc .checkWindows
	jmp .checkBuildingEnd
	
.setBuildingColor
	lda BuildingLife
	sta BgColor

.checkWindows
	txa 
	and #%00000111
	bne .checkBuildingEnd
	lda Windows
	eor #%01100110
	sta Windows

.checkBuildingEnd
	cpx #ROAD_START
	beq .setVanPosition
	bcs .continueBuilding
.drawVan
	lda #0
	sta Windows
	lda VanBody-1,X
    sta Grp1Buffer
	lda VanWheels-1,X
	sta Grp0Buffer
	jmp .finishPlayerLine
	
.setVanPosition
	jsr PositionVan
	dex
	lda #ROAD
	sta BgColor
	lda VanLife
	sta COLUP0
	lda #$02
	sta COLUP1
	jmp .drawVan

.continueBuilding
	jsr UfoDrawingCode

.finishPlayerLine
	dex
	bne .drawscreen

DrawingDone
	lda #%01000010
	sta VBLANK
	sta WSYNC
    lda #36
    sta TIM64T

	; ---- run code
;----- Check Joystick 1
.checkJoy1Right
    lda #%00001000          ;Right?
    bit SWCHA
    bne .checkJoy1Left
    lda VanXPos
    cmp #135
    beq .moveVanDone
    inc VanXPos
	jmp .moveVanDone

.checkJoy1Left
    lda #%00000100          ;Left?
    bit SWCHA
    bne .moveVanDone
    lda VanXPos
	cmp #13
	beq .moveVanDone
    dec VanXPos

;----- Finish Move
.moveVanDone

;; check van player firing missile after you draw van
	;; but before resetting position for UFOs
.checkFireVanMissile
	lda VanMissileY
	cmp #65
	beq .checkActivateVanMissile
	inc VanMissileY

.checkActivateVanMissile		
	lda #$80
	bit INPT5
	bne PositionUfoBody
	lda VanMissileActive
	cmp #0
	bne PositionUfoBody
	lda	#ROAD_START
	sta	VanMissileY
	lda #%00000010
	sta	RESMP0
	lda #0
	sta RESMP0
	lda #1
	sta VanMissileActive
	lda #15
	sta VanAttackSound



; Position Sprites to create Ufo
PositionUfoBody
	sta WSYNC
	ldx UfoXPos
    lda HorzTable,X     ;+4  7
    sta HMP1            ;+3 10
    and #$0F            ;+2 12
    tax                 ;+2 14
Body  
    dex                 ;+2 16
    bpl Body            ;when branch not taken: +2 (18 + x*5)
    sta RESP1           ;(21 + x*5)
	sta WSYNC

PositionUfoGear
	sta WSYNC
    ldx ErrXPos         ;+3  3
    lda HorzTable,X     ;+4  7
    sta HMP0            ;+3 10
    and #$0F            ;+2 12
    tax                 ;+2 14
Gear  
    dex                 ;+2 16
    bpl Gear            ;when branch not taken: +2 (18 + x*5)
    sta RESP0           ;(21 + x*5)
	sta WSYNC
    sta HMOVE


;Life Management
	lda ErrDeployed
	bne .checkUfoLife
	inc FrameCounter
	lda FrameCounter
	cmp ErrBuildTime
	bne .checkUfoLife
	dec ErrLife	
	lda #0
	sta FrameCounter
	

.checkUfoLife	
	lda UfoLife
	and #$0F
	eor #$0F
	bne .checkVanLife
	jmp .showDeathScreen
	
.checkVanLife
	lda VanLife
	and #$0F
	eor #$0F
	bne .checkErrBuildingLife
	jmp .showDeathScreen
	
.checkErrBuildingLife
	lda ErrDeployed
	bne .lifeChecksDone
	lda ErrLife
	and #$0F
	bne .checkErrKilled
	lda #30
	sta VanAttackSound
	lda #1
	sta ErrDeployed
	lda #UFO_GEAR
	sta ErrLife
	lda UfoXPos
	sta ErrXPos
	lda UfoYPos
	sta ErrYPos
	
	lda UfoLife
	and #$0F
	beq .hurtBuilding
	dec UfoLife
	
.hurtBuilding
	inc BuildingLife
	lda BuildingLife
	and #$0F
	eor #$0F
	bne .lifeChecksDone
	jmp .showDeathScreen
.checkErrKilled
	eor #$0F
	bne .lifeChecksDone
	lda #30
	sta UfoAttackSound
	lda #1
	sta ErrDeployed
	lda #UFO_GEAR
	sta ErrLife
	lda UfoXPos
	sta ErrXPos
	lda UfoYPos
	sta ErrYPos
	
	lda VanLife
	and #$0F
	beq .lifeChecksDone
	dec VanLife
	
	jmp .lifeChecksDone
		
.showDeathScreen
	lda #192
	sta DeathScreen

.lifeChecksDone

.waitForOverscan
    lda     INTIM
    bne     .waitForOverscan

	jmp MainLoop


DeathLoop

	lda #0
	sta CTRLPF
	
	ldy #48
.deathLoop
	sty COLUPF
	tya
	and #%00000111
	tax

	REPEAT 4

	sta WSYNC	
	lda LPFData0,X
	sta PF0
	lda LPFData1,X
	sta PF1
	lda LPFData2,X
	sta PF2

	sleep #6

	lda RPFData0,X
	sta PF0
	lda RPFData1,X
	sta PF1
	lda RPFData2,X
	sta PF2

	REPEND

	dey
	beq .deathLoopDone
	jmp .deathLoop
	
.deathLoopDone


	lda #1
	sta ErrDeployed
	
	lda #UFO_COLOR
	sta UfoLife
	lda #UFO_GEAR
	sta ErrLife
	lda #VAN_COLOR
	sta VanLife
	lda #BUILDING_COLOR
	sta BuildingLife

	lda UfoXPos
	sta ErrXPos
	lda UfoYPos
	sta ErrYPos

	lda #1
	sta CTRLPF


	jmp DrawingDone



;------------------------------------------------
; ROM Tables
;------------------------------------------------

	BOUNDARY 0

HorzTable    ;this must not cross a page boundary
    .byte $00,$F0,$E0,$D0,$C0,$B0,$A0,$90
    .byte $71,$61,$51,$41,$31,$21,$11,$01,$F1,$E1,$D1,$C1,$B1,$A1,$91
    .byte $72,$62,$52,$42,$32,$22,$12,$02,$F2,$E2,$D2,$C2,$B2,$A2,$92
    .byte $73,$63,$53,$43,$33,$23,$13,$03,$F3,$E3,$D3,$C3,$B3,$A3,$93
    .byte $74,$64,$54,$44,$34,$24,$14,$04,$F4,$E4,$D4,$C4,$B4,$A4,$94
    .byte $75,$65,$55,$45,$35,$25,$15,$05,$F5,$E5,$D5,$C5,$B5,$A5,$95
    .byte $76,$66,$56,$46,$36,$26,$16,$06,$F6,$E6,$D6,$C6,$B6,$A6,$96
    .byte $77,$67,$57,$47,$37,$27,$17,$07,$F7,$E7,$D7,$C7,$B7,$A7,$97
    .byte $78,$68,$58,$48,$38,$28,$18,$08,$F8,$E8,$D8,$C8,$B8,$A8,$98
    .byte $79,$69,$59,$49,$39,$29,$19,$09,$F9,$E9,$D9,$C9,$B9,$A9,$99
    .byte $7A,$6A,$5A,$4A,$3A,$2A,$1A,$0A,$FA,$EA,$DA,$CA,$BA,$AA,$9A






LPFData0
	.byte #%00000000
    .byte #%00100000
    .byte #%00100000
    .byte #%00100000
    .byte #%10100000
    .byte #%01100000
    .byte #%00100000
    .byte #%00000000
RPFData0
    .byte #%00000000
    .byte #%10100000
    .byte #%10100000
    .byte #%01100000
    .byte #%11100000
    .byte #%10100000
    .byte #%11100000
    .byte #%00000000


LPFData1
    .byte #%00000000
    .byte #%01011101
    .byte #%01010101
    .byte #%01010101
    .byte #%01010101
    .byte #%11010101
    .byte #%01011101
    .byte #%00000000
RPFData1
	.byte #%00000000
    .byte #%01110111
    .byte #%01010100
    .byte #%01010100
    .byte #%01010100
    .byte #%01010100
    .byte #%01010100
    .byte #%00000000


LPFData2
    .byte #%00000000
    .byte #%10001011
    .byte #%11001010
    .byte #%10101010
    .byte #%10101010
    .byte #%10011010
    .byte #%10001011
    .byte #%00000000
RPFData2
    .byte #%00000000
    .byte #%11101110
    .byte #%00100010
    .byte #%01000010
    .byte #%01000110
    .byte #%10000010
    .byte #%11101110
    .byte #%00000000



UfoBgColor
    .byte #$70, #$71, #$72, #$73, #$74, #$75, #$76, #$77, #$78, #$79, #$7A, #$7B, #$25 

UfoBody
	.byte #%00000000
	.byte #%00000000
    .byte #%00000000
    .byte #%00111100
    .byte #%01111110
    .byte #%11111111
    .byte #%11111111
    .byte #%11111111
    .byte #%11111111
    .byte #%11111111
    .byte #%01111110
    .byte #%00111100
	.byte #%00000000


UfoGear
    .byte #%00000000
    .byte #%11011011
    .byte #%01011010
    .byte #%00111100
    .byte #%00011000
    .byte #%00000000
    .byte #%01111110
    .byte #%01011010
    .byte #%01111110
    .byte #%00000000
    .byte #%00000000
    .byte #%00000000
    .byte #%00000000
    .byte #%00000000

ErrBody
    .byte #%00000000
    .byte #%00000000
    .byte #%00000000
    .byte #%01100110
    .byte #%00011000
    .byte #%00111100
    .byte #%10111101
    .byte #%10111101
    .byte #%01111110
    .byte #%00111100
    .byte #%00111000
    .byte #%00001000
    .byte #%00000000



VanBody
	.byte #%00000000
	.byte #%00000000
	.byte #%00000000
	.byte #%00000000
	.byte #%00000000
	.byte #%11111111
    .byte #%11111111
    .byte #%11111111
    .byte #%11111111
    .byte #%11111100
    .byte #%11111000
	.byte #%00000000
	.byte #%00000000
	.byte #%00000000



VanWheels
    .byte #%00000000
    .byte #%00000000
    .byte #%00000000
    .byte #%00000000
    .byte #%11101110
    .byte #%10101010
    .byte #%11101110
    .byte #%00000000
    .byte #%00000000
    .byte #%00000000
    .byte #%00000000
    .byte #%00000000
    .byte #%00000000
    .byte #%00000000
    .byte #%00000000
    .byte #%00000000
    .byte #%00000000
    .byte #%00000000
    .byte #%00000000





;------------------------------------------------
; Interrupt Vectors
;------------------------------------------------
    echo [*-$F000]d, " ROM bytes used"
	ORG    $FFFA
	.word  Start         ; NMI
	.word  Start         ; RESET
	.word  Start         ; IRQ
    
	END