|Have You Played Atari Today?||2600|5200|7800|Lynx|Jaguar|Forums|Store|
OK! We made it through our first program. Our second is going to be darn similar. Baby steps and all that.
The last program was a line, because that was about the easiest thing I could think to make, since we didn't have to do anything on every scanline. (Heck, we didn't even really have to do everything for every frame, except for the HMOVE.) So now we're going to make something just slightly more complex, a moving dot.
Why is a dot more complex than a line? Because we have to figure out when to turn the dot on, and when to turn it off. The code that you do during the scanlines (as opposed to during the Overscan or Vertical Blank) is called the "kernal" code, and it has to be tight, because you have very little time to do program logic. Sometimes, you might need 2 scanlines to do all your thinking, thus making a "two line kernal". (Though in that case, you have to be careful...since a lot of the kernal is setting up the graphical "things", if you change those things while the line is being drawn, weird things might result. Also wonderful things, if you're very careful with the timing... more careful than I've learned to be.)
Anyay, lets dive right into the code. I'll try to focus on commenting mostly on the new stuff, which I'll put in red for your reading convenience. (This means you should copy and paste from the web browser directly, not using "View Source"...and don't forget the VCS.H and stuff!)
; a moving dot by Kirk Israel processor 6502 include vcs.h org $F000 ;we start by setting up two "variables" ;this means we tell DASM that when we say ;variablename, we mean this specific memory ;location (we have $80 to $FF to play with) ;we'll use this one to store the vertical position YPosFromBot = $80; ;more on the use of this variable below VisibleMissileLine = $81; ;generic start up stuff... Start SEI CLD LDX #$FF ;we're so clever, we LDX TXS ;once and use that for LDA #0 ;both TXS ad the ClearMem loop ClearMem STA 0,X DEX BNE ClearMem LDA #$00 STA COLUBK LDA #66 ;Lets go for purpley! STA COLUP0 LDA #80 STA YPosFromBot ;set Initial Y Position ;NUSIZ0 sets the size and multiplying ;of the sprite and missiles --see the Stella ;guide for details LDA #$20 STA NUSIZ0 ;Quad Width for now ;VSYNC time MainLoop LDA #2 STA VSYNC STA WSYNC STA WSYNC STA WSYNC LDA #43 STA TIM64T LDA #0 STA VSYNC ;#% is a way of indicating a binary actual number ;(just like #$ starts a hex number and # a decimal number) LDA #%00010000 ;put value of 1 in the left nibble (slow move right) STA HMM0 ;set the move for missile 0 WaitForVblankEnd LDA INTIM BNE WaitForVblankEnd LDY #191 STA WSYNC STA VBLANK STA WSYNC STA HMOVE ;main scanline loop... ScanLoop STA WSYNC ; here the idea is that VisibleMissileLine ; is zero if the line isn't being drawn now, ; otherwise it's however many lines we have to go ; there are probably more efficient ways of doing this ; we see if this is the line (line # stored in Y) is the ; one that we start the missile on CheckActivateMissile CPY YPosFromBot ;compare Y to the YPosFromBot... BNE SkipActivateMissile ;if not equal, skip this... LDA #8 ;otherwise say that this should go STA VisibleMissileLine ;on for 8 lines SkipActivateMissile ;turn missile off then see if it's turned on LDA #0 STA ENAM0 ; ;if the VisibleMissileLine is non zero, ;we're drawing it ; LDA VisibleMissileLine ;load the value of what missile line we're showing BEQ FinishMissile ;if zero we aren't showing, skip it IsMissileOn LDA #2 ;otherwise STA ENAM0 ;showit DEC VisibleMissileLine ;and decrement the missile line thing FinishMissile DEY ;decrement scanline counter BNE ScanLoop ;lather rinse repeat ;overscan same as last time LDA #2 STA WSYNC STA VBLANK LDX #30 OverScanWait STA WSYNC DEX BNE OverScanWait JMP MainLoop org $FFFC .word Start .word Start
Next: The Joy of Sticks