processor 6502
include vcs.h
org $F000
;Variables ------
YPosFromBot = $80;
VisiblePlayerLine = $81;
PICS = $82;
ROLLING_COUNTER = $83;
Graphics_Buffer = $84
YPosFromBotE1 = $85;
VisibleEnemyLine = $86;
VisibleEnemyLineCurrent = $87;
EnemyLineBuffer = $88;
VisiblePlayerLineCurrent = $90;
BG_0 = $91;
BG_1 = $92;
BG_2 = $93;
; Constants ------
playerheight ds #8;
;generic start up stuff...
Start
SEI
CLD
LDX #$FF
TXS
LDA #0
STA ROLLING_COUNTER
STA PICS
STA EnemyLineBuffer
ClearMem
STA 0,X
DEX
BNE ClearMem
LDA #$00 ;start with a black background
STA COLUBK
LDA #$1C ;lets go for bright yellow, the traditional color for happyfaces
STA COLUP0
;Setting some variables...
LDA #80
STA YPosFromBot ;Initial Y Position
STA YPosFromBotE1
LDA #010001 ; 2 cycles
STA BG_0 ; 3 cycles
STA BG_1 ; 3 cycles
STA BG_2 ; 3 cycles
;; Let's set up the sweeping line. as Missile 1
LDA #2
; STA ENAM1 ;enable it
LDA #33
STA COLUP0 ;color it
STA COLUP1 ;color it
LDA #$10
; STA NUSIZ0 ;make it quadwidth (not so thin, that)
STA NUSIZ1 ;make it quadwidth (not so thin, that)
LDA #000000 ; set to not move
STA HMM1 ; of HMM1 sets it to moving
;VSYNC time
MainLoop ;+++++++++++++++++++++++++++The start of a new screen
LDA #0
STA GRP0
STA GRP1
STA PF0
STA PF1
STA PF2
LDA #2
STA VSYNC
STA WSYNC
; for up and down, we INC or DEC
; the Y Position
LDA #010000 ;Down?
BIT SWCHA
BNE SkipMoveDown
INC YPosFromBot
INC YPosFromBotE1
INC YPosFromBotE1
SkipMoveDown
LDA #100000 ;Up?
BIT SWCHA
BNE SkipMoveUp
DEC YPosFromBot
DEC YPosFromBotE1
DEC YPosFromBotE1
SkipMoveUp
; for left and right, we're gonna
; set the horizontal speed, and then do
; a single HMOVE. We'll use X to hold the
; horizontal speed, then store it in the
; appropriate register
;assum horiz speed will be zero
LDX #0
LDA #%01000000 ;Left?
BIT SWCHA
BNE SkipMoveLeft
LDX #$10 ;a 1 in the left nibble means go left
;; moving left, so we need the mirror image
LDA #001000 ;a 1 in D3 of REFP0 says make it mirror
STA REFP0
STA REFP1
SkipMoveLeft
LDA #%10000000 ;Right?
BIT SWCHA
BNE SkipMoveRight
LDX #$F0 ;a -1 in the left nibble means go right...
;; moving right, cancel any mirrorimage
LDA #000000
STA REFP0
STA REFP1
SkipMoveRight
STX HMP0 ;set the move for player 0, not the missile like last time...
STX HMP1 ;set the move for player 0, not the missile like last time...
; see if player and missile collide, and change the background color if so
;just a review...comparisons of numbers always seem a little backwards to me,
;since it's easier to load up the accumulator with the test value, and then
;compare that value to what's in the register we're interested.
;in this case, we want to see if D7 of CXM1P (meaning Player 0 hit
; missile 1) is on. So we put 10000000 into the Accumulator,
;then use BIT to compare it to the value in CXM1P
LDA #%10000000
BIT CXM1P
BEQ NoCollision ;skip if not hitting...
LDA YPosFromBot ;must be a hit! load in the YPos...
STA COLUBK ;and store as the bgcolor
NoCollision
STA CXCLR ;reset the collision detection for next time
STA WSYNC ;//////////////////////////////////////////////
;setup pic animations ----------------------------------------------
INC ROLLING_COUNTER
LDA ROLLING_COUNTER
AND #15 ;every 8th screen swap to next image of player
CMP #8
BEQ PICSET4
JMP PICSET3
PICSET4 LDA PICS
CMP #8
BEQ PICSET
LDA #8
JMP PICSET2
PICSET LDA #0
PICSET2 STA PICS
PICSET3
LDA ROLLING_COUNTER
AND #25 ;how often to move enemy, larger number is slower
CMP #8
BEQ PICSET5
LDA #001111 ; +1 in the left nibble
JMP PICSET6
PICSET5 LDA #011111 ; 0 in the left nibble
PICSET6 STA HMP1 ; of HMP1 sets it to moving the enemy
LDA #8
CLC
ADC PICS ;add value of pics to Accumulator
STA VisibleEnemyLineCurrent
LDA #8
CLC
ADC PICS ;add value of pics to Accumulator
STA VisiblePlayerLineCurrent
;setup pic animations ----------------------------------------------
STA WSYNC ;//////////////////////////////////////////////
LDA #43
STA TIM64T
LDA #0
STA VSYNC
;------------------------- setup backgrounds 20 pixels accross
LDA #255 ; 3 cycles
STA PF0 ; 3 cycles
STA PF1 ; 3 cycles
STA PF2 ; 3 cycles
;-------------------------
WaitForVblankEnd
LDA INTIM
BNE WaitForVblankEnd
LDY #4 ; was 191
STA WSYNC
STA HMOVE
STA VBLANK
;main scanline loop...
PreScanLoop
ScanLoop1 ;start of kernal +++++++++++++++++++++++ for skyline
LDA PFCOLOR-1,Y ; 4 cycles
STA COLUBK ;and store as the bgcolor ; 3 cycles
LDA PFData0-1,Y ; 4 cycles
STA PF0 ; 3 cycles
LDA PFData1-1,Y ; 4 cycles
STA RESM0 ; 3 cycles places left scan line leftmost
STA PF1 ; 3 cycles
LDA PFData2-1,Y ; 4 cycles
STA PF2 ; 3 cycles
LDA #0 ;2 cycles =30
STA GRP1 ; put player 1 into grp1 3 cycles
STA GRP0 ;put that line as player graphic 0 ;3 cycles =28
DEY ;count down number of scan lines 2 cycles =71
STA WSYNC ;3 cycles =74
BNE ScanLoop1 ;2 cycles =76
EndScanLoop1 ;end of kernal +++++++++++++++++++++++ for skyline
LDA #100;
STA COLUBK ;and store as the bgcolor
LDY #186 ; was 191 was 186
LDA #0
STA PF0 ; 3 cycles
STA PF1 ; 3 cycles
STA PF2 ; 3 cycles
LDA #%11100011 ;The last 3 bits control number and size of players
;the firs 3 bits control missle size
STA NUSIZ0
STA NUSIZ1
STA WSYNC ;3 cycles
ScanLoop ;start of kernal +++++++++++++++++++++++ for players
;-------------------------- y register is the line number currently being drawn
; SPRITE DRAW
tya ; 2 Transfers the byte in the Y Register to the Accumulator.
sec ; 2 Sets the carry (C) flag (in the processor Status Register byte).
sbc YPosFromBot ; 3 Subtracts a byte in memory from the byte in the Accumulator, and "borrows" if necessary.
adc #8 ; 2 Adds byte in memory to the byte in the Accumulator, plus the carry flag if set.
bcs .Draw ; 2(3) Branches up to 127 bytes forward or 128 bytes backward from its own address if the carry flag is set.
nop ; 2 Wait
nop ; 2 Wait
sec ; 2 Sets the carry (C) flag
bcs .skipDraw ; 3 Branches up to 127 bytes forward or 128 bytes backward from its own address if the carry flag is set.
.Draw
lda MainPlayerGraphics,y ; 5 Loads the Accumulator with a byte from memory.
sta GRP0 ; 3 Stores the byte in the Accumulator into memory.
.skipDraw
;-->18 cycles used
;--------------------------
; STA GRP0 ;set player graphics 3 cycles
; STA GRP1 ;set player graphics 3 cycles
DEY ;count down number of scan lines 2 cycles =
STA WSYNC ;3 cycles =
BNE ScanLoop ;2 cycles =
EndScanLoop ;end of kernal +++++++++++++++++ for players
STA WSYNC
STA VBLANK
LDX #24
OverScanWait
STA WSYNC
DEX
BNE OverScanWait
JMP MainLoop
MainPlayerGraphics
.byte #010100
.byte #010100
.byte #011000
.byte #011000
.byte #%01111110
.byte #010000
.byte #111000
.byte #111000
SpriteEnd
.byte #100010
.byte #100100
.byte #101000
.byte #011000
.byte #%01111110
.byte #010000
.byte #111000
.byte #111000
EnemyGraphics
.byte #%01111000
.byte #%10000100
.byte #001000
.byte #010000
.byte #010000
.byte #010000
.byte #111000
.byte #111000
.byte #%01111000
.byte #%01001000
.byte #010000
.byte #100000
.byte #100000
.byte #100000
.byte #%01110000
.byte #%01110000
PFData0
.byte #001111
.byte #011111
.byte #%01111111
.byte #%11111111
PFData1
.byte #000000
.byte #001110
.byte #111111
.byte #%01111111
PFData2
.byte #000000
.byte #011000
.byte #%10111100
.byte #%11111111
PFCOLOR
.byte #$5F
.byte #$5D
.byte #$5B
.byte #$59
org $FFFC
.word Start
.word Start














