;--------------------------------------- ;FOR SPEED WE NEED V2 ;by Richard Bayliss ;ASSEMBLE IT - GAME 4 ;(This is OLD source, converted to C64 ;Studio and slightly updated). ;--------------------------------------- !to "fswn.prg",cbm ;Generate program ;setup the perameters for the game scrmap = $4000 ;where the screen map ;is located speedcount = $02 ;the storage for the ;moving car's scrspeed ydelay = $03 ;Vertical scroller delay ypos = $04 ;Vertical scroller position store = $03f0 ;collision storage shield = $0340 ;temporary shield clockdelay = $0341 ;delay for game time level = $0342 ;the actual speed of ;the enemy cars gamesync = $0c pointer = $0336 ;animation pointer MusicInit = $1000 ;Init music MusicPlay = $1003 ;Play music ;No BASIC SYS this time. Exomizer will do the ;job instead ;) ;Import status panel charset *=$0800 !bin "bin\charset.prg",,2 ;PRG file instead of RAW BIN ;Music *=$1000 !bin "bin\music.prg",,2 ;Game charset *=$2000 !bin "bin\gamecharset.prg",,2 ;Sprite data *=$2800 !bin "bin\sprites.prg",,2 ;Map data (Basically a screen set for wrapping down scroller) *=$4000 !bin "bin\mapdata.prg",,2 ;Status layout *=$6000 !bin "bin\status.prg",,2 ;Main code. *= $5800;jump address ;all irq vectors turned off game sei lda #$81 sta $dc0d sta $dd0d lda #$00 sta $d01a lda #$31 sta $0314 lda #$ea sta $0315 ;1. clear the screen. (don't use jsr ;$e544 is it can fail to work properly ;on a c128. ;screen gets cleared using spacebar char ldx #$00 stx pointer clearscrn lda #$20 sta $0400,x sta $0500,x sta $0600,x sta $06e8,x inx bne clearscrn lda #$00 sta $d021 sta $d020 ;initialize the game music lda #$00 jsr MusicInit lda #$00 sta mapread+1 lda #$40 sta mapread+2 ;initialize everything else, so that the sei lda #$00 sta $d021 sta $d020 lda #$01;level 1 is set sta level lda #$00 ;speed counter sta speedcount;and delay are sta clockdelay;zeroed lda #$06 ;shield is sta shield;initialized lda #$18 ;charset and sta $d018 ;screen multi sta $d016 ;colour is on lda #$ff ;all sprites and sta $d01c ;multicols are sta $d015 ;activated ;2. copy all the graphics data to the ;screen and fill the whole screen with ;green multicolour ($0d). ldx #$00 copy1a lda #$0d sta $d800,x sta $d900,x sta $da00,x sta $dae8,x lda $4000,x sta $0400,x lda $4100,x sta $0500,x lda $4200,x sta $0600,x lda $42e8,x sta $06e8,x inx bne copy1a lda #$09;white lines on road sta $d812 sta $d813 sta $d812+(1*40) sta $d813+(1*40) sta $d812+(2*40) sta $d813+(2*40) sta $d812+(3*40) sta $d813+(3*40) sta $d812+(4*40) sta $d813+(4*40) sta $d812+(5*40) sta $d813+(5*40) sta $d812+(6*40) sta $d813+(6*40) sta $d812+(7*40) sta $d813+(7*40) sta $d812+(8*40) sta $d813+(8*40) sta $d812+(9*40) sta $d813+(9*40) sta $d812+(10*40) sta $d813+(10*40) sta $d812+(11*40) sta $d813+(11*40) sta $d812+(12*40) sta $d813+(12*40) sta $d812+(13*40) sta $d813+(13*40) sta $d812+(14*40) sta $d813+(14*40) sta $d812+(15*40) sta $d813+(15*40) sta $d812+(16*40) sta $d813+(16*40) sta $d812+(17*40) sta $d813+(17*40) ;3. paste the status bar on to the ;bottom portion of the screen ldx #$00 copy1b lda $6000,x ;where status lies sta $06f8,x lda #$0f;grey screen sta $daf8,x inx cpx #$f0 bne copy1b ;4. setup the colour and screen settings lda #$00;grey sta $d023;screen m.col 2 lda #$09;brown sta $d022;screen m.col 1 lda #$1b sta $d011;turn screen on lda #$00 sta $d012;init rastersplit ;5. setup all the sprites and positions lda #$a0 sta $07f8;player sprite type lda #$a1 sta $07f9;enemy sprite types sta $07fa sta $07fb sta $07fc sta $07fd sta $07fe sta $07ff ;this is the loop for setting up a ;sprite position, accordingly to the ;values of the data tables. ldx #$00 setpos lda position+$00,x ;positions sta $d002,x inx cpx #$0e bne setpos ;default the player's position lda #$68 sta $d000 lda #$50 sta $d001 ;sprite multicolours lda #$0b sta $d025 lda #$0c sta $d026 lda #$0a sta $d027 ;initialise the irq interrupt player ldx #irq1 stx $0314 sty $0315 lda #$36 sta $d012 lda #$7f sta $dc0d lda #$1b sta $d011 lda #$01 sta $d01a cli jmp dogamesync ;IRQ - the bottom raster irq1 inc $d019 lda $dc0d sta $dd0d ;our loop for the sprite colours, all ;painted in black, so that we can mask ;those sprites behind the status panel. ldx #$00 coloop lda #$00 sta $d028,x inx cpx #$07 bne coloop lda #$00 sta $d012 lda #$1b sta $d011 lda #$08 sta $d016;screen multicol off lda #$00 sta $d01c;off lda #$ff;all sprites black sta $d01b;and behind the ;screen. lda #$03 sta $dd00 lda #$12;score charset sta $d018 ldx #irq2 ;Point to hibyte of second irq stx $0314 sty $0315 jmp $ea7e ;9. the bottom raster irq2 inc $d019 lda #$c4 sta $d012 ;straighten the bottom raster using ;general timing ldx #$0a time1 dex bne time1 ldx #$00;all sprites are multicoloured colspr lda colours+$00,x sta $d028,x inx cpx #$07 bne colspr ;now for the main bits for the second ;raster. lda #$1b;screen on sta $d011 lda #$18;screen multicolor sta $d016;is on lda #$03 sta $dd00 lda #$ff;sprite multicol on sta $d01c lda #$00;all sprites in front sta $d01b;of the graphics lda #$18;game graphics on sta $d018 ldx #irq1 ;Point back to hibyte of IRQ1 stx $0314 sty $0315 lda #$01;add 1 to gamesync sta gamesync jsr movebad;move enemies jsr movejoy;joystick jsr PalNTSCPlayer;play music jmp $ea7e ;PALNTSC Check for music player PalNTSCPlayer lda $02a6 ;Machine type cmp #$01 beq PAL inc ntsctimer lda ntsctimer cmp #$06 beq resetntsctimer PAL jsr MusicPlay rts resetntsctimer lda #0 sta ntsctimer rts ;10. gamesynchronize routines then call em dogamesync lda #$00 sta gamesync lda gamesync raswait cmp gamesync beq raswait jsr scroll;call rough map ;scroll jsr collision;check collision jsr time ;operate timer jsr score;increase score jsr animate;animate sprites jmp dogamesync;loop in gamesync ;11. our routine for the rough map ;scro scroll lda ypos sec sbc #$03 and #$07 sta ypos bcs noscroll jmp doscroll noscroll rts ;the main map up the screen ;this is the area where the screen ;chars are pulled from one area to ;another on the game screen. doscroll ldx #39 ;Reversed loop scrolloop ;for scrolling all ;map screen chars lda $0400+(1*40),x sta $0400+(0*40),x lda $0400+(2*40),x sta $0400+(1*40),x lda $0400+(3*40),x sta $0400+(2*40),x lda $0400+(4*40),x sta $0400+(3*40),x lda $0400+(5*40),x sta $0400+(4*40),x lda $0400+(6*40),x sta $0400+(5*40),x lda $0400+(7*40),x sta $0400+(6*40),x lda $0400+(8*40),x sta $0400+(7*40),x lda $0400+(9*40),x sta $0400+(8*40),x lda $0400+(10*40),x sta $0400+(9*40),x lda $0400+(11*40),x sta $0400+(10*40),x lda $0400+(12*40),x sta $0400+(11*40),x lda $0400+(13*40),x sta $0400+(12*40),x lda $0400+(13*40),x sta $0400+(12*40),x lda $0400+(14*40),x sta $0400+(13*40),x lda $0400+(15*40),x sta $0400+(14*40),x lda $0400+(16*40),x sta $0400+(15*40),x lda $0400+(17*40),x sta $0400+(16*40),x lda #$20 sta $06d0,x ; mapread lda scrmap,x ;check if map cmp #$00 ;uses '@' character (0) beq resetmap ;if so, then ;restart the ;scroll. sta $0400+(17*40),x ;Otherwise draw dex bpl scrolloop lda mapread+1 clc adc #40 ;Read next row of map sta mapread+1 lda mapread+2 adc #0 sta mapread+2 rts resetmap lda #<$4000 ;restart map sta mapread+1 lda #>$4000 sta mapread+2 jmp mapread ;12. the joystick being read in port 2 ; movejoy lda $dc00 lsr a lsr a bcs left left lsr a bcs right ldx $d000 dex dex dex dex cpx #$68 bcs setleft ldx #$68 setleft stx $d000 right lsr a bcs fire ldx $d000 inx inx inx inx cpx #$e8 bcc setright ldx #$eb setright stx $d000 fire rts ;13. enemy movements ;you should also be familiar with this ; ;also, as it was kind if introduced in ;the missile blasta source. movebad ldx #$00 badloop lda $d003,x sec sbc level sta $d003,x lda $d003,x cmp #$0c bcs randplc lda randpos+$00 sta $d002,x lda #$fc randplc sta $d003,x norand inx inx cpx #$0e bne badloop lda randpos+$00 sta randpos+$09 ldx #$00 random lda randpos+$01,x sta randpos+$00,x inx cpx #$09 bne random rts ;14. ;a simple collision using $d01e (mo collision lda $d01e lsr a bcc alive dec shield lda shield;if shield is zeroed cmp #$00;game is over. beq dead alive rts ;15. player is dead, so do game over dead ldx #$00 deadloop lda $6100,x sta $07c0,x sta $07c0,x inx cpx #$28 bne deadloop jmp gameover ;16. score routine (you should be ;familiar with this right now. score inc $077c ldx #$05 sc lda $0777,x cmp #$3a bne sc2 lda #$30 sta $0777,x inc $0776,x sc2 dex bne sc rts ;17. clock routine (you should also be ; time inc clockdelay lda clockdelay cmp #$30 bne notime lda #$00 sta clockdelay dec $0796 lda $0796 cmp #$2f bne notime lda #$39 sta $0796 dec $0795 lda $0795 cmp #$2f bne notime lda #$30 sta $0796 lda #$36 sta $0795 ;18. time is up so go on to the next ;level. inc level inc $078a lda level cmp #$09 bne notime ;19. all levels are complete, so now ;the player has won the game lda #$38 sta $078a ldx #$00 wintext lda $6540,x sta $07c0,x inx cpx #$28 bne wintext lda #$02 tax tay jsr $1000 jmp gameover notime rts ;20. our simple press fire to play again gameover sei lda #$00 sta $d015 lda #$12 sta $d018 ldx #$00 clear2 lda #$20 sta $0400+(0*40),x sta $0400+(1*40),x sta $0400+(2*40),x sta $0400+(3*40),x sta $0400+(4*40),x sta $0400+(5*40),x sta $0400+(6*40),x sta $0400+(7*40),x sta $0400+(8*40),x sta $0400+(9*40),x sta $0400+(10*40),x sta $0400+(11*40),x sta $0400+(12*40),x sta $0400+(13*40),x sta $0400+(14*40),x sta $0400+(15*40),x sta $0400+(16*40),x sta $0400+(17*40),x sta $0400+(18*40),x inx cpx #$28 bne clear2 lda #$03 tax tay jsr $1000 hitfire lda #$80 ras cmp $d012 bne ras lda #$08 sta $d016 jsr $1003;music still play lda $dc00 lsr a lsr a lsr a lsr a lsr a bcs hitfire jmp game ;21. our animation process animate ldx pointer lda frame1+$00,x sta $07f8 ldy frame2+$00,x sty $07f9 sty $07fa sty $07fb sty $07fc sty $07fd sty $07fe sty $07ff inx cpx #$0b beq resetpt inc pointer rts resetpt ldx #$00 stx pointer rts ntsctimer !byte 0 ;PAL/NTSC pointer ;22. the data tables for the f.s.w.n ;game ; positions for the player position !byte $90,$00,$78,$30,$80,$60 !byte $b0,$60,$a0,$d0,$e8,$20 !byte $c0,$d8 ;random positions for enemies randpos !byte $68,$e8,$78,$d8,$88,$c8 !byte $98,$b8,$a8 ;colours for all sprites colours !byte $0a,$03,$0d,$07,$0f,$0a !byte $0e,$0d ;player animation table frame1 !byte $a0,$a0,$a0,$a0,$a0,$a0 !byte $a1,$a1,$a1,$a1,$a1,$a1 !byte $a1,$00,$00,$00,$00 ;enemy anim table frame2 !byte $a2,$a2,$a2,$a2,$a2,$a2 !byte $a3,$a3,$a3,$a3,$a3,$a3