Subject: [stella] Animating the Marbles From: Paul Slocum <paul-stella@xxxxxxxxxxxxxx> Date: Tue, 02 Jul 2002 22:17:37 -0500 |
;--------------------------------------------------------------------------- ; Marble Craze by Paul Slocum ;--------------------------------------------------------------------------- ;------------------------------ ; Marble Craze bank 1 ;------------------------------ ; Includes: ; ; - Game Kernal ; - Variable Initialization ; - Game Loop Logic ;------------------------------ ; LEVEL IDEAS ; Easy wall level (1st) ; Adventure ; Combat ; Easy Does It ; Dungeon ; Earthworld ; Fireworld ; Jump level ; Intersection Puzzler ; Get the Gems ; Grand Prix ; Grand Prix 2 ; Waterworld ; Airworld ; Video Game Characters ; Up,Down,Right,Left Power Bars ; Slope level ; Slope level 2 ; Key level ; Tightrope ; Rainbow Road ; Diagonal Paths ; Warps? ; Big open level ; Invisible Maze (catacombs) ; Power up extensions (get power up on each screen to extend path) ; MUSIC IDEAS ; Techno beat w/ arpeggiated music ; Slower song with 2 part arpeggiated melody ; Reverberated square song processor 6502 include vcs.h ;--------------------------- TODO ; ; Switch to 32k ; ; GENERALIZE LEVEL READING ; SLOPE DATA STRUCTURE ; Check PF ; 2637 ; 2666 = 47 bytes ; Load Screen ; 2778 ; 2837 = 191 bytes ; Get Value = 20 bytes? ; ; Allow alternate songs ; ; Slow animation/allow turn off ; ; Look into modifying kernal for more animation ; ;-------------------------------- ;------------------------ TODO LATER ; ; Fall off animation/fading ; Jump handling ; ; Slope handling ; ; Write C program to generate levels ; ; Stop, Up, Down etc power ups ; ; Warp power ups? ; ; (Lives bug)? ; ; Add friction? ; ;------------------------------------ ;-------------------- SUGGESTIONS: ; ; Fat paddle center ; ; Friction ; ; Time about up indicator (sound or visual) ; ; Clean up respawn handling (restart sound? indicator?) ; ; Preview next screen ; ; Show ball rolling/falling off ; ; Track Ball control ; ; ------------------------------------ ;--------------------------------------------------------------------------- ; Constants ;--------------------------------------------------------------------------- LASTLEVEL equ 2 KERNAL_DELAY equ 8 TIMECOLOR equ $86 STATUSCOLOR equ $48 INTROCOLOR equ $8A ; Flags in level variable ENDGAME equ %10000000 NEXTLEVEL equ %01000000 WINGAME equ %00100000 NUMBEROFLIVES equ 8 ;---------------------------- status ;Status bits FLASH equ 16 NOGAME equ 32 NOTIME equ 64 DONE equ 128 ; Status NORMAL equ 0 FALLOFF equ 1 + FLASH RESET equ 2 + FLASH SCREENLOAD equ 3 LOADREADY equ 6 FINISHED equ 4 + NOTIME + DONE STARTUP equ 5 + FLASH + NOTIME GETREADY equ 7 + FLASH + NOTIME GAMEOVER equ 8 + NOTIME + FLASH + DONE + NOGAME INACTIVE equ 9 + NOTIME + DONE + NOGAME ENDLEVEL equ 10 + NOTIME ;+ SKIPLOGIC TIMEUP equ 11 + FLASH ;-------------------------------------- ;-------------------------- power ups PWR20PTS equ %00000001 PWR50PTS equ %00000010 PWR100PTS equ %00000011 PWR5SEC equ %00000100 PWR10SEC equ %00000101 PWR20SEC equ %00000110 PWRWALLS equ %00000111 PWR1UP equ %00001000 PWRKEY equ %00001001 HPWR20PTS equ %00010000 HPWR50PTS equ %00100000 HPWR100PTS equ %00110000 HPWR5SEC equ %01000000 HPWR10SEC equ %01010000 HPWR20SEC equ %01100000 HPWRWALLS equ %01110000 HPWR1UP equ %10000000 HPWRKEY equ %10010000 ;------------------------------------- ; Bankswitching BANK1 equ $1FF6 BANK2 equ $1FF7 BANK3 equ $1FF8 BANK4 equ $1FF9 ;--------------------------------------------------------------------------- ; RAM Variables ;--------------------------------------------------------------------------- playField equ $80 ; 72 bytes (12 lines * 5) + 12 color bytes ; Variables for title screen only option equ $80 paddle equ $81 debounce equ $84 bounce equ $85 titleBlank equ $86 startGame equ $87 ;------------------------------------ 8 bytes ; 16 bit temp (overlaps with pfBuffer) temp16L equ $C8 temp16H equ $C9 levelL equ $CA ; temp level pointer (during game logic) levelH equ $CB screenL equ $CC ; temp screen pointer (during game logic) screenH equ $CD temp equ $CE ; two more temps (for game logic) temp2 equ $CF ;------ pfBuffer equ $C8 ; 8 bytes ;------------------------------------ pMarble equ $D0; 2 bytes pMarble2 equ $D2; 2 bytes pfColor equ $D4 frame equ $D5 p1x equ $D6 p2x equ $D7 p1y equ $D8 p2y equ $D9 p1xVel equ $DA p2xVel equ $DB p1yVel equ $DC p2yVel equ $DD pwr1x equ $DE pwr2x equ $DF pwr1y equ $E0 pwr2y equ $E1 padVal1 equ $E2 padVal3 equ $E3 padVal2 equ $E4 padVal4 equ $E5 ; 102 bytes total level equ $E6 p1Screen equ $E7 ; bit 7 = WALLS flag, bit 6 & 5 = falling count p2Screen equ $E8 ; "" p1Status equ $E9 p2Status equ $EA p1Counter equ $EB p2Counter equ $EC p1TimeL equ $ED p2TimeL equ $EE p1TimeH equ $EF p2TimeH equ $F0 temp5 equ $F1 p1Lives equ $F2 ; High 4 bits store power up type p2Lives equ $F3 ; High 4 bits store power up type bkColor equ $F4 pwrArray1 equ $F5 pwrArray2 equ $F6 beat equ $F7 measure equ $F8 p1ScoreL equ $F9 p2ScoreL equ $FA p1ScoreH equ $FB p2ScoreH equ $FC titleOptions equ $FD ; 126 bytes total (added titleOptions) ;------------------------------------------------- ; Temporary Game Logic Variables ;------------------------------------------------- screen equ pMarble player equ pMarble+1 status equ temp5 ;-------------------------------------------------- ; These two temp variables are in the stack area, ; and are only used during the kernal where ; the stack is not used. temp3 equ $FE temp4 equ $FF ;--------------------------------------------------------------------------- ;--------------------------------------------------------------------------- org $1000 ;--------------------------------------------------------------------------- ;--------------------------------------------------------------------------- marbleData2 byte 0,0,0,0,0,0,0,0 byte 0,0,0,0,0,0,0,0 byte 0,0,0,0,0,0,0,0 byte 0,0,0,0,0,0,0,0 byte 0,0,0,0,0,0,0,0 byte 0,0,0,0,0,0,0,0 byte 0,0,0,0,0,0,0,0 byte 0,0,0,0,0,0,0,0 byte 0,0,0,0,0,0,0,0 byte 0,0,0,0,0,0,0,0 byte 0,0,0,0,0,0,0,0 byte 0,0,0,0,0,0,0,0 byte 0,0,0,0,0,0,0,0 byte 0,0,0,0,0,0,0,0 byte 0,0,0,0,0,0,0,0 byte 0,0,0,0,0,0,0,0 byte 0,0,0,0,0,0,0,0 byte 0,0,0,0,0,0,0,0 byte 0,0,0,0,0,0,0 byte #%00111100 byte #%01111110 byte #%01111110 byte #%11111111 byte #%11111111 byte #%11111111 byte #%11111111 byte #%11111111 byte #%11111111 byte #%01111110 byte #%01111110 byte #%00111100 align 256 marbleData3 byte 0,0,0,0,0,0,0,0 byte 0,0,0,0,0,0,0,0 byte 0,0,0,0,0,0,0,0 byte 0,0,0,0,0,0,0,0 byte 0,0,0,0,0,0,0,0 byte 0,0,0,0,0,0,0,0 byte 0,0,0,0,0,0,0,0 byte 0,0,0,0,0,0,0,0 byte 0,0,0,0,0,0,0,0 byte 0,0,0,0,0,0,0,0 byte 0,0,0,0,0,0,0 byte #%00111100 byte #%01111110 byte #%01111110 byte #%11111111 byte #%11111111 byte #%11111111 byte #%11111111 byte #%11111111 byte #%11111111 byte #%01111110 byte #%01111110 byte #%00111100 ; total = 99 bytes byte 0,0,0,0,0,0,0,0 byte 0,0,0,0,0,0,0,0 byte 0,0,0,0,0,0,0,0 byte 0,0,0,0,0,0,0,0 byte 0,0,0,0,0,0,0,0 byte 0,0,0,0,0,0,0,0 byte 0,0,0,0,0,0,0,0 byte 0,0,0,0,0,0,0,0 align 256 movement byte #%01110001, #%01100001, #%01010001, #%01000001, #%00110001, #%00100001, #%00010001, #%00000001 byte #%11110001, #%11100001, #%11010001, #%11000001, #%10110001, #%10100001, #%10010001 byte #%01110010, #%01100010, #%01010010, #%01000010, #%00110010, #%00100010, #%00010010, #%00000010 byte #%11110010, #%11100010, #%11010010, #%11000010, #%10110010, #%10100010, #%10010010 byte #%01110011, #%01100011, #%01010011, #%01000011, #%00110011, #%00100011, #%00010011, #%00000011 byte #%11110011, #%11100011, #%11010011, #%11000011, #%10110011, #%10100011, #%10010011 byte #%01110100, #%01100100, #%01010100, #%01000100, #%00110100, #%00100100, #%00010100, #%00000100 byte #%11110100, #%11100100, #%11010100, #%11000100, #%10110100, #%10100100, #%10010100 byte #%01110101, #%01100101, #%01010101, #%01000101, #%00110101, #%00100101, #%00010101, #%00000101 byte #%11110101, #%11100101, #%11010101, #%11000101, #%10110101, #%10100101, #%10010101 byte #%01110110, #%01100110, #%01010110, #%01000110, #%00110110, #%00100110, #%00010110, #%00000110 byte #%11110110, #%11100110, #%11010110, #%11000110, #%10110110, #%10100110, #%10010110 byte #%01110111, #%01100111, #%01010111, #%01000111, #%00110111, #%00100111, #%00010111, #%00000111 byte #%11110111, #%11100111, #%11010111, #%11000111, #%10110111, #%10100111, #%10010111 byte #%01111000, #%01101000, #%01011000, #%01001000, #%00111000, #%00101000, #%00011000, #%00001000 byte #%11111000, #%11101000, #%11011000, #%11001000, #%10111000, #%10101000, #%10011000 byte #%01111001, #%01101001, #%01011001, #%01001001, #%00111001, #%00101001, #%00011001, #%00001001 byte #%11111001, #%11101001, #%11011001, #%11001001, #%10111001, #%10101001, #%10011001 byte #%01111010, #%01101010, #%01011010, #%01001010, #%00111010, #%00101010, #%00011010, #%00001010 byte #%11111010, #%11101010, #%11011010, #%11001010, #%10111010, #%10101010, #%10011010 paddleDecode byte 0,0,0,0,0,0,1,1,1,1,1,1,1 byte 2,2,2,2,2,2,3,3,3,3,3,3,3 byte 4,4,4,4,4,4,5,5,5,5,5,5,5 byte 5,5,5,5,5,5,6,6,6,6,6,6,6 byte 6,6,6,6,6,6,7,7,7,7,7,7,7 byte 7,7,7,7,7,7,8,8,8,8,8,8,8 byte 8,8,8,8,8,8,8,8,8,8,8,8,8 byte 9,9,9,9,9,9,9,9,9,9,9,9,9 byte 10,10,10,10,10,10,10,10,10,10,10,10,10 byte 11,11,11,11,11,11,11,11,11,11,11,11,11 byte 12,12,12,12,12,12,12,12,12,12,12,12,12 byte 13,13,13,13,13,13,14,14,14,14,14,14,14 byte 15,15,15,15,15,15 ;-------------------------------------------------------------------------- ; Draw Screen ;-------------------------------------------------------------------------- drawScreen ;******************* Position P0/P1 for Score *********************** sta HMCLR ; Set horizontal player positions for score sta WSYNC lda #%11000000 sta HMM0 lda #%11010000 sta HMM1 nop lda (temp),x lda (temp),x lda temp sta RESP0 lda temp lda (temp),x sta RESM0 lda temp sta RESBL nop lda temp sta RESP1 lda #%00100000 sta HMP0 lda #%00010000 sta HMBL sta RESM1 sta WSYNC sta HMOVE lda #0 sta COLUBK ; ************** Score Draw Loop ******************** jmp callDrawScore rtnCallDrawScore ; ************** Future Status and Timer (22 lines) **************** lda #$0F sta COLUPF ; ***************** Position Game Objects ********************* ; DEBUG LIVES PROBLEM ; lda p1Lives ; sta PF2 ; nop nop lda temp ; waste 3 cycles sta temp ; Set sizes lda #32 ;2 sta NUSIZ1 ;3 lda #0 sta NUSIZ0 ;3 ; ***************** Position M0 (Divider Line) ********************* sta RESM0 sta PF1 ;3 ; DEBUG LIVES PROBLEM ; lda #$0F ; sta PF2 ;3 sta HMCLR lda #%01000000 sta HMM0 lda #6 sta temp4 ; preLoad playfield color buffer lda playField+71+6 sta pfBuffer+7 sta WSYNC ; Set player colors to white lda #$0F ;2 sta COLUP0 ;3 sta COLUP1 ;3 ;**************** Position P0 (Left Marble) *************** lda p1x lsr tax STA WSYNC ; Uses a lookup table to get the fine and course movement lda movement,x STA HMP0 AND #$0F TAY pPos1 DEY BPL pPos1 STA RESP0 STA WSYNC STA HMOVE ;**************** Position P1 (Right Marble) *************** nop nop lda p2x clc adc #5 lsr tax ; Uses a lookup table to get the fine and course movement lda movement,x STA HMP1 ldx #0 stx HMP0 stx HMM0 AND #$0F TAY pPos2 DEY BPL pPos2 STA RESP1 ; **************** Position M1 (Power Ups) ********************* ; DBEUG LIVES PROBLEM ; lda #0 ; sta PF2 STA WSYNC STA HMOVE ; Power up flickers between player 1 and 2 ; power up. ldx pwr1x lda frame and #%00000001 beq powerUp1 lda pwr2x clc adc #77 tax powerUp1 ; Uses a lookup table to get the fine and course movement lda movement,x ldy #$0F sta WSYNC sta HMCLR STA HMM1 AND #$0F TAY pPos3 DEY BPL pPos3 STA RESM1 sta WSYNC sta HMOVE ; The Ball is used to show the center divider in the score ; area, but M0 is used in the game area. Turn on M0 here. lda #$FF sta ENAM0 ;******* Calculate line position of Vertical Paddle bar (Ball) ******* ; temp16L stores the position ; of the vertical paddle indicator ldx padVal1 lda frame and #1 beq vertPad1 ldx padVal3 vertPad1 lda paddleDecode,x sta temp3 lda #14 sec sbc temp3 bcc padZero clc adc #1 jmp notPadZero padZero lda #1 notPadZero sta temp3 ldx #$0 cmp #13 bmi ballOff ldx #$FF ballOff stx ENABL lda #%00010000 sta CTRLPF sta WSYNC ; Draw top white line lda #$0F sta COLUBK sta COLUBK ;*********** Position Ball (shows vertical Paddle position) *********** ; The ball graphics flickers between the left side and right side ; to indicate both player's vertical paddle positions lda frame and #1 bne right ldx #4 ballL dex bne ballL lda #%11010000 sta HMBL nop sta RESBL jmp endBallPos right ldx #9 ballR dex bne ballR lda #%10110000 sta HMBL nop sta RESBL endBallPos sta WSYNC sta HMOVE lda bkColor sta COLUBK lda #$FF sta ENAM0 ;--------------------------- set startup text to display (or not) ; 147 = no intro display ldx #147 ; Check for GAMEOVER/ENDLEVEL flags lda level and #%11100000 bne showDisplay ; Check for startup lda p1Status cmp #STARTUP bne noStartup showDisplay ldx #148 ; 148 = show display noStartup stx temp5 ;------------------------------------------ ;***************** General Setup for Screen Drawing ******************* ; Alternate the two kernals every frame lda frame and #%00000001 beq gotoScanLoop2 jmp gotoScanLoop3 gotoScanLoop2 ; Playfield Reference ; ; pfBuffer ; 0 = PF0.1 ; 1 = PF1.1 ; 2 = PF2.1 ; 3 = PF0.2 ; 4 = PF1.2 ; 5 = PF2.2 ; 6 = PFCOLOR1 ; 7 = PFCOLOR2 ; ; 0 Hblank 22 PF0 28 PF1 38 PF2 48 PF0 56 PF1 66 PF2 76 ; |----22----||--6--||---10----||---10----||--6--||---10----||---10----|| ; 4---7 7-------0 0-------7 4---7 7-------0 0-------7 ;========================================================================== ; ; KERNAL A ; ;========================================================================== ; ********* Draw Horizontal Paddle Indicator Left ********* lda pfColor sta COLUPF ; Don't show paddles if INACTIVE lda p1Status cmp #INACTIVE bne showBall lda #255 sta temp3 ; location of ball line position sta WSYNC sta WSYNC jmp endPaddleDisplay showBall ; Get paddle value ldx padVal2 lda paddleDecode,x ldy #2 hLoopA sta WSYNC asl asl tax ; Use array to convert paddle value ; to playfield data lda hPaddleDisplay,x sta PF0 lda hPaddleDisplay+1,x sta PF1 lda hPaddleDisplay+2,x sta PF2 ldx #2 hPadA dex bne hPadA ; Turn off display lda #0 sta PF0 sta PF1 sta PF2 ; Get paddle value ldx padVal2 lda paddleDecode,x dey bne hLoopA endPaddleDisplay sta WSYNC ; ***************** Prepare for Kernal Loop **************** ; Set starting Paddle counter values lda #161 sta padVal1 sta padVal2 ; Delay a bit before start of kernal loop ldx #6 kBDelay dex bne kBDelay ; PreLoad the next right-playfield color lda playField+71 sta pfBuffer+7 ; preload temp2 value (x/2) lda #6 sta temp4 ; number of blocks ldx #12 ;2 = 18 ; Use Y to track the actual line ldy #156 ;2 20 scanLoop2 ; lda pfColor ; waste cycles txs ; waste cycles lda playField-1,x ;4 76 ; 1A) setup ;--------------------------------------- sta PF0 ;3 sta pfBuffer ;3 lda (pMarble),y ;5* sta GRP0 ;3 lda playField+11,x ;4 sta PF1 ;3 lda playField+23,x ;4 sta PF2 ;3 lda (pMarble2),y ;5* sta GRP1 ;3 lda pfBuffer ;3 asl ;2 asl ;2 asl ;2 asl ;2 sta PF0 ;3 48 sta pfBuffer+3 ;3 lda playField+35,x ;4 sta PF1 ;3 55 lda playField+47,x ;4 sta PF2 ;3 ; sta pfBuffer+5 ;3 dey ;2 lda (pMarble),y ;5* ; 2A) colors ;--------------------------------------- sta GRP0 ;3 lda pfBuffer ;3 sta PF0 ;3 ldx temp4 lda playField+59,x ;4 66 sta COLUPF ;3 sta pfBuffer+6 ;3 tsx lda playField+11,x ;4 sta PF1 ;3 lda playField+23,x ;4 sta PF2 ;3 34 lda (pMarble2),y ;4 sta GRP1 ;3 ; nop lda pfBuffer+3 ;3 sta PF0 ;3 52 lda playField+35,x ;4 sta PF1 ;3 lda pfBuffer+7 ;3 sta COLUPF ;3 ; lda pfBuffer+5 ;4 lda playField+47,x ;4 sta PF2 ;3 sta pfBuffer+5 ;3 dey ;2 lda (pMarble),y ;4* sta GRP0 ;3 ; 3A) paddles ;--------------------------------------- lda pfBuffer ;3 sta PF0 ;3 lda pfColor ;3 sta COLUPF ;3 lda playField+11,x ;4 sta PF1 ;3 sta pfBuffer+1 ;3 lda playField+23,x ;4 sta PF2 ;3 lda (pMarble2),y ;4 sta GRP1 ;3 39 ; nop lda pfBuffer+3 ;3 sta PF0 ;3 52 lda playField+35,x ;4 sta PF1 ;3 lda pfBuffer+5 ;4 sta PF2 ;3 dey ;2 lda (pMarble),y ;4* sta GRP0 ;3 68 lda INPT0 ;3 bmi paddles1 ;2 or 3 sty padVal1 ;3 paddles1 lda pfBuffer ;3 sta PF0 ;3 sta WSYNC ; 4A) colors ;--------------------------------------- lda pfBuffer+6 ;3 sta COLUPF ;3 lda pfBuffer+1 ;4 sta PF1 ;3 lda playField+23,x ;4 sta PF2 ;3 29 sta pfBuffer+2 ;3 lda (pMarble2),y ;4 sta GRP1 ;3 lda pfBuffer+3 ;3 sta PF0 ;3 52 lda playField+35,x ;4 sta PF1 ;3 lda pfBuffer+7 ;3 sta COLUPF ;3 lda pfBuffer+5 ;4 sta PF2 ;3 dey ;2 lda (pMarble),y ;4* sta GRP0 ;3 lda pfBuffer ;3 sta PF0 ;3 ; 5A) paddles ;--------------------------------------- lda pfBuffer ;3 sta PF0 ;3 lda pfColor ;3 sta COLUPF ;3 lda pfBuffer+1 ;3 sta PF1 ;3 lda pfBuffer+2 ;3 sta PF2 ;3 29 lda (pMarble2),y ;4 sta GRP1 ;3 lda pfBuffer+3 ;3 sta PF0 ;3 52 lda playField+35,x ;4 sta PF1 ;3 sta pfBuffer+4 lda pfBuffer+5 ;4 sta PF2 ;3 dey ;2 lda (pMarble),y ;4* sta GRP0 ;3 lda pfBuffer ;3 sta PF0 ;3 lda INPT1 ;3 bmi paddles2 ;2 or 3 sty padVal2 ;3 paddles2 sta WSYNC ; 6A) colors ;--------------------------------------- lda pfBuffer+6 ;3 sta COLUPF ;3 txs ldx pfBuffer+1 ;3 stx PF1 ;3 lda pfBuffer+2 ;3 sta PF2 ;3 lda (pMarble2),y ;4 sta GRP1 ;3 dey ;2 lda pfBuffer+3 ;3 sta PF0 ;3 lda pfBuffer+4 ;3 sta PF1 ;3 lda pfBuffer+7 ;3 sta COLUPF ;3 lda pfBuffer+5 ;4 sta PF2 ;3 lda (pMarble),y ;4* sta GRP0 ;3 lda pfBuffer ;3 sta PF0 ;3 ; 7A) more setup ;--------------------------------------- ; lda pfBuffer ;3 ; sta PF0 ;3 lda pfColor ;3 stx PF1 ;3 sta COLUPF ;3 ; Draw the power up (using missile 1) tsx ;2 txa ;2 ldx #ENABL ;2 txs ;2 cmp temp3 php cmp pwr1y ;2 php ;3 tax lda pfBuffer+2 ;3 sta PF2 ;3 lda (pMarble2),y ;4 sta GRP1 ;3 lda pfBuffer+3 ;3 sta PF0 ;3 lda pfBuffer+4 ;3 sta PF1 ;3 lda pfBuffer+5 ;4 sta PF2 ;3 dey ;2 lda (pMarble),y ;4* sta GRP0 ;3 txs nop lda pfBuffer ;3 sta WSYNC sta PF0 ;3 ldx pfBuffer+1 ;3 ; 8A) colors ;--------------------------------------- lda pfBuffer+6 ;3 sta COLUPF ;3 stx PF1 ;3 lda pfBuffer+2 ;3 sta PF2 ;3 lda (pMarble2),y ;4 sta GRP1 ;3 dey ;2 lda pfBuffer+3 ;3 sta PF0 ;3 lda pfBuffer+4 ;3 sta PF1 ;3 lda pfBuffer+7 ;3 sta COLUPF ;3 lda pfBuffer+5 ;4 sta PF2 ;3 lda (pMarble),y ;4* sta GRP0 ;3 lda pfBuffer ;3 sta PF0 ;3 ; 9A) paddles ;--------------------------------------- lda pfBuffer ;3 sta PF0 ;3 lda pfColor ;3 sta COLUPF ;3 stx PF1 ;3 lda pfBuffer+2 ;3 sta PF2 ;3 lda (pMarble2),y ;4 sta GRP1 ;3 cpy temp5 ; Check for message display bne noMessageDisplay ; display message jmp messageDisplay noMessageDisplay nop lda pfBuffer+3 ;3 sta PF0 ;3 lda pfBuffer+4 ;3 sta PF1 ;3 lda pfBuffer+5 ;4 sta PF2 ;3 dey ;2 lda (pMarble),y ;4* sta GRP0 ;3 lda pfBuffer ;3 sta PF0 ;3 lda INPT0 ;3 bmi paddles3 ;2 or 3 sty padVal1 ;3 paddles3 sta WSYNC ; 10A) colors ;--------------------------------------- lda pfBuffer+6 ;3 sta COLUPF ;3 stx PF1 ;3 lda #0 sta ENAM1 lda pfBuffer+2 ;3 sta PF2 ;3 lda (pMarble2),y ;4 sta GRP1 ;3 ;nop lda pfBuffer+3 ;3 sta PF0 ;3 lda pfBuffer+4 ;3 sta PF1 ;3 dey ;2 lda pfBuffer+7 ;3 sta COLUPF ;3 lda pfBuffer+5 ;4 sta PF2 ;3 lda (pMarble),y ;4* sta GRP0 ;3 lda pfBuffer ;3 sta PF0 ;3 ; 11A) paddles ;--------------------------------------- lda pfBuffer ;3 sta PF0 ;3 lda pfColor ;3 sta COLUPF ;3 stx PF1 ;3 lda pfBuffer+2 ;3 sta PF2 ;3 lda (pMarble2),y ;4 sta GRP1 ;3 ; This gets X out of the stack register, ; divides it by two and stores it for use ; with the color shading. tsx txa lsr sta temp4 lda pfBuffer+3 ;3 sta PF0 ;3 lda pfBuffer+4 ;3 sta PF1 ;3 lda pfBuffer+5 ;4 sta PF2 ;3 dey ;2 lda (pMarble),y ;4* sta GRP0 ;3 lda pfBuffer ;3 sta PF0 ;3 lda INPT1 ;3 bmi paddles4 ;2 or 3 sty padVal2 ;3 paddles4 sta WSYNC ; 12A) colors ;--------------------------------------- lda pfBuffer+6 ;3 sta COLUPF ;3 lda pfBuffer+1 ;3 sta PF1 ;3 lda pfBuffer+2 ;3 sta PF2 ;3 lda (pMarble2),y ;4 sta GRP1 ;3 ; Grab that color pointer ldx temp4 dey ;2 lda pfBuffer+3 ;3 sta PF0 ;3 lda pfBuffer+4 ;3 sta PF1 ;3 lda pfBuffer+7 ;3 sta COLUPF ;3 lda pfBuffer+5 ;4 sta PF2 ;3 lda (pMarble),y ;4* sta GRP0 ;3 lda pfBuffer ;3 sta PF0 ;3 ; 13A) setup for loop ;--------------------------------------- lda pfColor ;3 sta COLUPF ;3 lda pfBuffer+1 ;3 sta PF1 ;3 ;nop ; Load the next right-playfield color lda playField+65,x ;4 66 sta pfBuffer+7 ;3 lda pfBuffer+2 ;3 sta PF2 ;3 lda (pMarble2),y sta GRP1 tsx ;2 dey lda pfBuffer+3 ;3 sta PF0 ;3 lda pfBuffer+4 ;4 sta PF1 ;3 lda pfBuffer+5 ;3 sta PF2 ;3 dex ;2 beq quitScanLoop2 ;2 jmp scanLoop2 ;3 must be 70 ;******************* End Of Kernal A ******************* ;========================================================================== ; ; KERNAL CLEAN UP ; ;========================================================================== quitScanLoop2 sta WSYNC ; Draw the white line at the bottom lda #$0F sta COLUPF lda #255 sta PF0 sta PF1 sta PF2 endOfScreen ; One more scanline sta WSYNC lda #0 sta COLUBK sta PF0 sta ENABL sta ENAM0 sta PF1 sta PF2 sta COLUP0 sta COLUP1 ; restore stack ldx #255 txs jmp rtnDrawScreen ;========================================================================== ; ; messageDisplay ; ;-------------------------------------------------------------------------- ; Displays text in middle of game screen ;========================================================================== messageDisplay ; Finish current line (cuts in a 9th scanline in loop) lda pfBuffer+3 ;3 sta PF0 ;3 lda pfBuffer+4 ;3 sta PF1 ;3 lda pfBuffer+5 ;4 sta PF2 ;3 lda frame and #1 beq padFrame01 lda INPT2 bmi paddles13 ;2 or 3 sty padVal3 ;3 jmp paddles13 padFrame01 lda INPT0 ;3 bmi paddles13 ;2 or 3 sty padVal1 ;3 paddles13 sta WSYNC ; call function to display text in bank 3 jmp callIntroMessage rtnCallIntroMessage ; sta WSYNC ; Set player colors to white lda #$0F ;2 sta COLUP0 ;3 sta COLUP1 ;3 ; Now, have to reposition the player graphics ; since they were moved to display the text.. ;**************** Position P0 (Left Marble) *************** lda p1x lsr tax STA WSYNC ; Uses a lookup table to get the fine and course movement lda movement,x STA HMP0 AND #$0F TAY pPos5 DEY BPL pPos5 STA RESP0 STA WSYNC STA HMOVE ;**************** Position P1 (Right Marble) *************** nop nop lda p2x clc adc #5 lsr tax ; Uses a lookup table to get the fine and course movement lda movement,x STA HMP1 ldx #0 stx HMP0 stx HMM0 AND #$0F TAY pPos6 DEY BPL pPos6 STA RESP1 STA WSYNC STA HMOVE lda #255 sta PF1 sta PF2 ; *********************************************************** ; Restore remaining registers and variables to resume ; drawing the screen... ; restore X and Y ldx pfBuffer+1 txs ldy pfBuffer+2 lda #32 ;2 sta NUSIZ1 lda #$00 ; set both players to normal sta NUSIZ0 sta VDELP0 sta VDELP1 ; sta WSYNC tya sec sbc #31 tay sta WSYNC lda bkColor sta COLUBK lda #0 sta PF1 sta PF2 tsx dex dex txa lsr sta temp4 tax ; Load the next right-playfield color lda playField+65,x ;4 66 sta pfBuffer+7 ;3 lda playField+59,x ;4 66 sta pfBuffer+6 tsx dex dex dex txs ; Don't change number of cycles after this... sta WSYNC lda #0 sta PF1 sta PF2 lda #%00010000 sta CTRLPF lda pfColor ;3 sta COLUPF ;3 lda #255 sta ENAM0 lda frame and #1 beq reEnterLoop2 ldx #3 messageLoop1 dex bne messageLoop1 nop nop tsx jmp scanLoop3 reEnterLoop2 ldx #3 messageLoop2 dex bne messageLoop2 lda temp tsx jmp scanLoop2 hPaddleDisplay ; 64 bytes byte %00010000, %00000000, %00000000, %00000000 byte %00010000, %00000000, %00000000, %00000000 byte %00010000, %00000000, %00000000, %00000000 byte %00010000, %00000000, %00000000, %00000000 byte %01100000, %00000000, %00000000, %00000000 byte %10000000, %10000000, %00000000, %00000000 byte %00000000, %01100000, %00000000, %00000000 byte %00000000, %00011000, %00000000, %00000000 byte %00000000, %00000110, %00000000, %00000000 byte %00000000, %00000001, %00000001, %00000000 byte %00000000, %00000000, %00000110, %00000000 byte %00000000, %00000000, %00011000, %00000000 byte %00000000, %00000000, %01100000, %00000000 byte %00000000, %00000000, %10000000, %00000000 byte %00000000, %00000000, %10000000, %00000000 byte %00000000, %00000000, %10000000, %00000000 ;========================================================================== ; ; KERNAL B ; ;========================================================================== gotoScanLoop3 ; ******* Draw horizontal Paddle Indicator Right ******* lda pfColor sta COLUPF lda p2Status cmp #INACTIVE bne showBall2 lda #255 sta temp3 ; location of ball line position sta WSYNC sta WSYNC jmp endPaddleDisplay2 showBall2 ldy #2 hLoopB sta WSYNC ; Get paddle value ldx padVal4 lda paddleDecode,x ldx #0 stx PF0 stx PF1 stx PF2 asl asl ldx #2 hPadB dex bne hPadB tax lda hPaddleDisplay,x sta PF0 lda hPaddleDisplay+1,x sta PF1 lda hPaddleDisplay+2,x sta PF2 dey bne hLoopB endPaddleDisplay2 sta WSYNC ldx #0 stx PF0 stx PF1 stx PF2 ldx #4 kADelay dex bne kADelay ; PreLoad the next right-playfield color lda playField+71 sta pfBuffer+7 ; PreLoad the next left-playfield color lda playField+59+6; ; lda #$54 sta pfBuffer+6 ; Set starting paddle counter values lda #161 sta padVal3 sta padVal4 ; number of blocks ldx #12 ;2 = 18 ; Use Y to track the actual line ldy #156 ;2 20 scanLoop3 lda pfColor ; sta COLUPF lda playField-1,x ;4 76 ; 1B) setup ;--------------------------------------- sta PF0 ;3 sta pfBuffer ;3 lda (pMarble),y ;5* sta GRP0 ;3 lda playField+11,x ;4 sta PF1 ;3 lda playField+23,x ;4 sta PF2 ;3 lda (pMarble2),y ;5* sta GRP1 ;3 lda pfBuffer ;3 asl ;2 asl ;2 asl ;2 asl ;2 sta PF0 ;3 48 sta pfBuffer+3 ;3 lda playField+35,x ;4 sta PF1 ;3 55 lda playField+47,x ;4 sta PF2 ;3 sta pfBuffer+5 ;3 dey ;2 lda (pMarble),y ;4* sta GRP0 ;3 68 ; 2B) paddles ;--------------------------------------- lda pfBuffer ;3 sta PF0 ;3 lda playField+11,x ;4 sta PF1 ;3 sta pfBuffer+1 ;3 lda playField+23,x ;4 sta PF2 ;3 sta pfBuffer+2 ;3 lda (pMarble2),y ;4 sta GRP1 ;3 39 ; nop ; nop ; nop dey ;2 lda pfBuffer+3 ;3 sta PF0 ;3 52 lda playField+35,x ;4 sta PF1 ;3 sta pfBuffer+4 ;3 lda pfBuffer+5 ;4 sta PF2 ;3 lda (pMarble),y ;4* sta GRP0 ;3 68 lda INPT2 ;3 bmi paddles5 ;2 or 3 sty padVal3 ;3 paddles5 lda pfBuffer ;3 sta PF0 ;3 ; lda (pMarble),y ;5* ; sta GRP0 ;3 sta WSYNC ; 3B) colors ;--------------------------------------- lda pfBuffer+6 ;4 66 sta COLUPF ;3 ; sta pfBuffer+6 ;3 nop nop lda pfBuffer+1 ;3 sta PF1 ;3 lda pfBuffer+2 ;3 sta PF2 ;3 34 lda (pMarble2),y ;4 sta GRP1 ;3 nop nop nop lda pfBuffer+3 ;3 sta PF0 ;3 52 lda pfBuffer+7 ;3 sta COLUPF ;3 lda pfBuffer+4 ;3 sta PF1 ;3 lda pfBuffer+5 ;4 sta PF2 ;3 dey ;2 lda (pMarble),y ;4* sta GRP0 ;3 ; 4B) paddles ;--------------------------------------- lda pfBuffer ;3 sta PF0 ;3 lda pfColor ;3 sta COLUPF ;3 lda pfBuffer+1 ;3 sta PF1 ;3 lda pfBuffer+2 ;3 sta PF2 ;3 29 lda (pMarble2),y ;4 sta GRP1 ;3 dey ;2 nop nop lda pfBuffer+3 ;3 sta PF0 ;3 52 lda pfBuffer+4 ;3 sta PF1 ;3 lda pfBuffer+5 ;4 sta PF2 ;3 lda (pMarble),y ;4* sta GRP0 ;3 lda pfBuffer ;3 sta PF0 ;3 lda INPT3 ;3 bmi paddles6 ;2 or 3 sty padVal4 ;3 paddles6 sta WSYNC ; 5B) colors ;--------------------------------------- lda pfBuffer+6 ;3 sta COLUPF ;3 lda pfBuffer+1 ;4 sta PF1 ;3 lda playField+23,x ;4 sta PF2 ;3 29 sta pfBuffer+2 ;3 lda (pMarble2),y ;4 sta GRP1 ;3 lda pfBuffer+3 ;3 sta PF0 ;3 52 lda playField+35,x ;4 sta PF1 ;3 lda pfBuffer+7 ;3 sta COLUPF ;3 lda pfBuffer+5 ;4 sta PF2 ;3 dey ;2 lda (pMarble),y ;4* sta GRP0 ;3 lda pfBuffer ;3 sta PF0 ;3 ; 6B) more setup ;--------------------------------------- lda pfColor ;3 sta COLUPF ;3 lda pfBuffer+1 ;3 sta PF1 ;3 lda pfBuffer+2 ;3 sta PF2 ;3 lda (pMarble2),y ;4 sta GRP1 ;3 ; Draw the power up (using missile 1) txa ;2 ldx #ENABL ;2 txs ;2 cmp temp3 php cmp pwr2y ;2 php ;3 tax lda pfBuffer+3 ;3 sta PF0 ;3 lda pfBuffer+4 ;3 sta PF1 ;3 lda pfBuffer+5 ;4 sta PF2 ;3 dey ;2 lda (pMarble),y ;4* sta GRP0 ;3 lda pfBuffer ;3 sta PF0 ;3 nop ; 7B) colors ;--------------------------------------- lda pfBuffer+6 ;3 sta COLUPF ;3 txs ldx pfBuffer+1 ;3 stx PF1 ;3 lda pfBuffer+2 ;3 sta PF2 ;3 lda (pMarble2),y ;4 sta GRP1 ;3 dey ;2 nop lda temp3 ; waste 3 cycles lda pfBuffer+3 ;3 sta PF0 ;3 lda pfBuffer+7 ;3 sta COLUPF ;3 lda pfBuffer+4 ;3 sta PF1 ;3 lda pfBuffer+5 ;4 sta PF2 ;3 lda (pMarble),y ;4* sta GRP0 ;3 ; 8B) paddles ;--------------------------------------- lda pfBuffer ;3 sta PF0 ;3 lda pfColor ;3 sta COLUPF ;3 stx PF1 ;3 lda pfBuffer+2 ;3 sta PF2 ;3 lda (pMarble2),y ;4 sta GRP1 ;3 nop ;8 nop nop nop lda pfBuffer+3 ;3 sta PF0 ;3 lda pfBuffer+4 ;3 sta PF1 ;3 lda pfBuffer+5 ;4 sta PF2 ;3 dey ;2 lda (pMarble),y ;4* sta GRP0 ;3 lda pfBuffer ;3 sta PF0 ;3 lda INPT2 ;3 bmi paddles7 ;2 or 3 sty padVal3 ;3 paddles7 sta WSYNC ; 9B) colors ;--------------------------------------- lda pfBuffer+6 ;3 sta COLUPF ;3 stx PF1 ;3 lda pfBuffer+2 ;3 sta PF2 ;3 lda (pMarble2),y ;4 sta GRP1 ;3 cpy temp5 bne noMessage2 jmp messageDisplay noMessage2 dey ;2 lda #0 ;2 sta ENAM1 ;3 lda pfBuffer+3 ;3 sta PF0 ;3 lda pfBuffer+7 ;3 sta COLUPF ;3 lda pfBuffer+4 ;3 sta PF1 ;3 lda pfBuffer+5 ;4 sta PF2 ;3 lda (pMarble),y ;4* sta GRP0 ;3 ; 10B) paddles ;--------------------------------------- lda pfBuffer ;3 sta PF0 ;3 lda pfColor ;3 sta COLUPF ;3 stx PF1 ;3 lda pfBuffer+2 ;3 sta PF2 ;3 lda (pMarble2),y ;4 sta GRP1 ;3 lda temp3 ; waste 3 cycles nop nop nop dey ;2 lda pfBuffer+3 ;3 sta PF0 ;3 lda pfBuffer+4 ;3 sta PF1 ;3 lda pfBuffer+5 ;4 sta PF2 ;3 lda (pMarble),y ;4* sta GRP0 ;3 lda pfBuffer ;3 sta PF0 ;3 lda INPT3 ;3 bmi paddles8 ;2 or 3 sty padVal4 ;3 paddles8 sta WSYNC ; 11B) colors ;--------------------------------------- lda pfBuffer+6 ;3 sta COLUPF ;3 stx PF1 ;3 lda pfBuffer+2 ;3 sta PF2 ;3 lda (pMarble2),y ;4 sta GRP1 ;3 lda temp3 ; waste 3 cycles nop nop nop nop dey ;2 lda pfBuffer+3 ;3 sta PF0 ;3 lda pfBuffer+7 ;3 sta COLUPF ;3 lda pfBuffer+4 ;3 sta PF1 ;3 lda pfBuffer+5 ;4 sta PF2 ;3 lda (pMarble),y ;4* sta GRP0 ;3 lda pfBuffer ;3 sta PF0 ;3 ; 12B) nothing ;--------------------------------------- lda pfColor ;3 sta COLUPF ;3 stx PF1 ;3 lda pfBuffer+2 ;3 sta PF2 ;3 lda (pMarble2),y ;4 sta GRP1 ;3 ; This gets X out of the stack register, ; divides it by two and stores it for use ; with the color shading. tsx txa lsr nop tax lda playField+59,x ;4 66 sta pfBuffer+6 lda pfBuffer+3 ;3 sta PF0 ;3 lda pfBuffer+4 ;3 sta PF1 ;3 lda pfBuffer+5 ;4 sta PF2 ;3 dey ;2 lda (pMarble),y ;4* sta GRP0 ;3 nop lda pfBuffer ;3 sta PF0 ;3 ; 13B) setup for loop ;--------------------------------------- lda pfBuffer+1 ;3 sta PF1 ;3 ; Load the next right-playfield color lda playField+65,x ;4 66 sta pfBuffer+7 ;3 tsx lda pfBuffer+2 ;3 sta PF2 ;3 lda (pMarble2),y sta GRP1 nop dey lda pfBuffer+3 ;3 sta PF0 ;3 lda pfBuffer+4 ;4 sta PF1 ;3 lda pfBuffer+5 ;3 sta PF2 ;3 dex ;2 beq quitScanLoop3 ;2 jmp scanLoop3 ;3 must be 70 quitScanLoop3 sta WSYNC lda #$0F sta COLUPF lda #255 sta PF0 sta PF1 sta PF2 jmp endOfScreen ; ******************* End of Kernal B ****************** ;========================================================================== ; ; Start of Program ; ;-------------------------------------------------------------------------- ; Clear memory, locate character graphics positions and such, ; initialize key memory values, start GameLoop. ;========================================================================== Start sei cld ldx #$FF txs lda #0 clear sta 0,x dex bne clear ; Initialize Variables jsr initVar ;========================================================================== ; ; GameLoop ; ;========================================================================== GameLoop jmp VSync ;start vertical retrace rtnVSync lda level cmp #255 beq noGameSelect lda SWCHB and #2 beq resetGame ; ---------------------------------------- ; Reset game when level = 254 lda level cmp #254 bne noGameSelect resetGame lda #0 ldx #$78 clrVar sta $80,x dex bpl clrVar ; Variables for title screen only lda #0 ; sta option ; sta paddle ; sta debounce ; sta bounce ; sta titleBlank ; sta startGame ; sta beat ; sta measure sta AUDV0 sta AUDV1 lda #255 sta level lda #50 sta titleBlank sta debounce noGameSelect ;--------------------------------------- ; if the level is set to 255, the title ; screen is run. lda level cmp #255 bne gameMode jmp callTitleScreen gameMode jmp VBlank ; spare time during screen blank ; uses jmp to avoid extra stack usage VBlankReturn sta CXCLR inc frame jmp drawScreen ; draw one screen rtnDrawScreen rtnCallTitleScreen jmp overscan ; do overscan rtnOverscan jmp GameLoop ;back to top ;========================================================================== ; ; Initialize variables ; ;========================================================================== initVar ; Set initialization flag. ; This stays set until the first frame is drawn. lda #$0f ;set text color to white sta COLUP0 sta COLUP1 lda #80 sta padVal1 sta padVal2 sta padVal3 sta padVal4 lda #128 sta p1xVel sta p1yVel sta p2xVel sta p2yVel lda #120 sta p2xVel lda #STARTUP sta p1Status sta p2Status lda #200 sta p1Counter sta p2Counter lda #$25 sta p2TimeH sta p2TimeL lda #3 sta p1Lives ; sta p2Lives lda #255 sta level lda #1 ;sta p1Screen ;sta p2Screen rts ;========================================================================== ; ; VSync ; ;------------------------------------------------------------------------- ; Game timers are elapsed during VSync ;========================================================================== VSync lda #2 ;bit 1 needs to be 1 to start retrace sta VSYNC ;start retrace sta WSYNC ;wait a few lines ;--------------- elapse game timer 1 lda p1Status ;3 and #NOTIME ;2 bne noDecTime1 ;2 ; Handle Time ldx #0 ;2 jsr elapseTime ;5 noDecTime1 ;------------------------------------ lda #44 ;prepare timer to exit blank period (44) sta WSYNC sta TIM64T ;turn it on ;--------------- elapse game timer 2 lda p2Status ;3 and #NOTIME ;2 bne noDecTime2 ;2 ; Handle Time ldx #1 ;2 jsr elapseTime ;5 noDecTime2 ;------------------------------------ lda #44 ;bit 1 needs to be 1 to start retrace sta WSYNC ;wait one more sta VSYNC ;done with retrace, write 0 to bit 1 jmp rtnVSync ;========================================================================== ; ; VBlank ; ;-------------------------------------------------------------------------- ; Handle user input and display setup during the VBLANK period ;========================================================================== VBlank jmp callVBlank2 ; call VBlank routines in bank 2 VBlank2Return ; ------- Cycle headroom: remove these in release version sta WSYNC sta WSYNC sta WSYNC sta WSYNC ;--------------------------------------------------------- jmp VBlankReturn ; use jmps to avoid extra stack usage ;========================================================================== ; ; incScore ; ;-------------------------------------------------------------------------- ; Increase BCD score by one ; ; preload ; X: player number (0 or 1) ;========================================================================== incScore sed lda #1 clc adc p1ScoreL,x sta p1ScoreL,x lda #0 adc p1ScoreH,x sta p1ScoreH,x cld rts ;========================================================================== ; ; decTime ; ;-------------------------------------------------------------------------- ; Elapse 1/10th of a second of time ; ; preload: ; X: number of player (0 or 1) ;========================================================================== decTime sed ; Make sure it's not already at zero lda p1TimeL,x bne contDecTime2 lda p1TimeH,x bne contDecTime2 cld rts contDecTime2 lda p1TimeL,x and #$0F sec sbc #1 and #$0F sta p1TimeL,x lda p1TimeH,x sbc #0 sta p1TimeH,x cld rts ; other rts ;========================================================================== ; ; elapseTime ; ;-------------------------------------------------------------------------- ; Elapse 1 frame of time ; ; Max cycles = about 52 ; ; preload: ; X: number of player (0 or 1) ;========================================================================== elapseTime lda p1TimeL,x ;4 and #$F0 ;2 bne noDecTime ;2 sed ;2 lda p1TimeL,x ;4 and #$0F ;2 sec ;2 sbc #1 ;2 and #$0F ;2 sta p1TimeL,x ;4 lda p1TimeH,x ;4 sbc #0 ;2 ; If carry is clear then time rolled... bcc setTimeZero ;2 sta p1TimeH,x ;4 endElapseTime cld ;2 lda p1TimeL,x ;4 ora #%01010000 ;2 sta p1TimeL,x ;4 rts ; other rts ;5 setTimeZero cld lda #0 sta p1TimeL,x sta p1TimeH,x rts noDecTime lda p1TimeL,x sec sbc #%00010000 sta p1TimeL,x rts ;========================================================================== ; ; Overscan ; ;========================================================================== overscan sta WSYNC lda #33 ; Use the timer to make sure overscan takes (34) sta TIM64T ; 30 scan lines. 29 scan lines * 76 = 2204 / 64 = 34.4 ; Skip OS processing if in Title Screen mode lda level cmp #255 bne doOS jmp endOS doOS ;------------------------------------- ; Invert vertical paddle values (1&3) sec ;2 -- about 22 cycles max lda frame ;3 and #1 ;2 bne invPad3 ;2* lda #161 ;2 sbc padVal1 ;3 sta padVal1 ;3 jmp quitInv ;3 invPad3 lda #161 ;2 sbc padVal3 ;3 sta padVal3 ;3 quitInv ;-------------------------------------- ;---------------------------------------- ; Call game logic routines in bank 2 jmp callProcessGameLogic rtnCallProcessGameLogic ;----------------------------------------- ; --------------- status state machine ldx #0 jsr handleStatus ldx #1 jsr handleStatus ;------------------------------------ ;------------------- check for end of game ;jmp endGameCheck lda level and #%11100000 bne endGameCheck lda p1Status and #DONE beq endGameCheck lda p2Status and #DONE beq endGameCheck lda #255 sta p1Counter sta p2Counter ldx #0 jsr endSetup ldx #1 jsr endSetup ; default to NEXTLEVEL flag ldx #NEXTLEVEL lda p1Status and #NOGAME beq setFlag lda p2Status and #NOGAME beq setFlag ldx #ENDGAME setFlag txa ora level sta level endGameCheck ;------------------------------------- ;----------------------------------handle game/level end flags lda p1Counter bne endFlags lda level and #ENDGAME beq checkEndLevel ; signal to go back to title screen lda #254 sta level ; Not doing this causes one extra ; point to be added to scores at end lda #0 sta pwrArray1 sta pwrArray2 jmp endFlags ; check for next level flag checkEndLevel lda level and #NEXTLEVEL beq gameEnd2 ldx #0 jsr nextLevelSetup ldx #1 jsr nextLevelSetup ; reset flags inc level lda #%00011111 and level sta level lda #0 sta pwrArray1 sta pwrArray2 ; sta p1x ; sta p1y ; sta p2x ; sta p2y ; Check to see if the last level was completed lda level cmp #LASTLEVEL bne notLastLevel lda level ora #WINGAME sta level ldx #0 lda p1Status cmp #STARTUP bne noP1Win ldx #255 noP1Win stx pwrArray1 ldx #0 lda p2Status cmp #STARTUP bne noP2Win ldx #255 noP2Win stx pwrArray2 lda #INACTIVE sta p1Status sta p2Status notLastLevel lda #250 sta p1Counter sta p2Counter sta pfColor jmp endFlags gameEnd2 ; After finishing all levels, go to game over lda level and #WINGAME beq endFlags lda level and #%00011111 ora #ENDGAME sta level lda #255 sta p1Counter sta p2Counter endFlags ;--------------------------------------------------- ;----------------------- score end of level lda p1Status cmp #ENDLEVEL bne notScore1 ldx #0 jsr scoreLevel notScore1 lda p2Status cmp #ENDLEVEL bne notScore2 ldx #1 jsr scoreLevel notScore2 ;------------------------------------------ ;------------------------ end of game bonus lda level and #WINGAME beq noBonus2 lda pwrArray1 beq noBonus1 ldx #0 jsr incScore noBonus1 lda pwrArray2 beq noBonus2 ldx #1 jsr incScore noBonus2 ;----------------------------------------------- endOS ;---------------- OS cycle overhead: remove in release version sta WSYNC sta WSYNC sta WSYNC sta WSYNC sta WSYNC sta WSYNC sta WSYNC sta WSYNC ;--------------------------------------------------------- endOSLoop lda INTIM ; We finished, but wait for timer bne endOSLoop ; by looping till zero sta WSYNC ; End last scanline lda #$82 sta VBLANK jmp rtnOverscan ;========================================================================== ; ; scoreLevel ; ;========================================================================== scoreLevel sed ; Decrease two 1/10th seconds ldy #2 ;-------------------------- scoreLoop ; Check that score isn't at zero lda p1TimeL,x bne point lda p1TimeH,x bne point cld endScoreLevel rts point ; dec time lda p1TimeL,x sec sbc #1 and #$0F sta p1TimeL,x lda p1TimeH,x sbc #0 sta p1TimeH,x dey bne scoreLoop ;--------------------------- lda p1ScoreL,x clc adc #1 sta p1ScoreL,x lda p1ScoreH,x adc #0 sta p1ScoreH,x cld rts ; other rts ;========================================================================== ; ; nextLevelSetup ; ;========================================================================== nextLevelSetup lda p1Status,x cmp #ENDLEVEL bne endLevelSetup lda #STARTUP sta p1Status,x lda #0 sta p1Screen,x lda #200 sta p1Counter,x endLevelSetup lda p1Status,x cmp #GAMEOVER bne doneLevelSetup lda #INACTIVE sta p1Status,x doneLevelSetup rts ;========================================================================== ; ; endSetup ; ;-------------------------------------------------------------------------- ; Adjusts status at end of level/game ;========================================================================== endSetup lda p1Status,x cmp #FINISHED bne checkGameOver lda #ENDLEVEL sta p1Status,x rts checkGameOver ; cmp #GAMEOVER ; bne doneEndSetup ; lda #INACTIVE ; sta p1Status,x doneEndSetup rts ; multiple rts ;========================================================================== ; ; handleStatus ; ;-------------------------------------------------------------------------- ; Status state machine ; ; Preload: ; X: Player number (0 or 1) ;========================================================================== handleStatus lda p1Counter,x beq check sec sbc #1 sta p1Counter,x rts check ; skip all this if WINGAME flag set lda level and #WINGAME bne endStatus lda p1Status,x beq endStatus cmp #FALLOFF bne nextCheck lda #RESET ldy #130 jmp endStatus nextCheck cmp #RESET bne nextCheck2 lda #NORMAL jmp endStatus nextCheck2 cmp #STARTUP bne nextCheck3 lda #GETREADY ldy #150 jmp endStatus nextCheck3 cmp #GETREADY bne nextCheck4 lda #NORMAL jmp endStatus nextCheck4 cmp #TIMEUP bne endStatus lda #$15 sta p1TimeH,x lda #RESET ldy #120 jmp endStatus endStatus sta p1Status,x tya sta p1Counter,x rts ; other rts in function ;========================================================================== ; ; callProcessGameLogic ;-------------------------------------------------------------------------- ; Call to bank 2 ;========================================================================== org $1FA0 callProcessGameLogic ldx BANK2 nop nop nop nop nop nop jmp rtnCallProcessGameLogic ;========================================================================== ; ; callIntroMessage ; ;-------------------------------------------------------------------------- ; Call to bank 3 ;========================================================================== org $1FB0 callIntroMessage ldx BANK3 nop nop nop nop nop nop jmp rtnCallIntroMessage ;========================================================================== ; ; callTitleScreen ; ;-------------------------------------------------------------------------- ; Call to bank 3 ;========================================================================== org $1FC0 callTitleScreen ldx BANK3 nop nop nop nop nop nop jmp rtnCallTitleScreen ;-------------------------------------------------------------------------- ; callDrawScore ;-------------------------------------------------------------------------- ; Call to bank 4 ;-------------------------------------------------------------------------- org $1FD0 callDrawScore ldx BANK4 nop nop nop nop nop nop jmp rtnCallDrawScore ;-------------------------------------------------------------------------- ; callVBlank2 ;-------------------------------------------------------------------------- ; Call to bank 2 ;-------------------------------------------------------------------------- org $1FE0 callVBlank2 ldx BANK2 nop nop nop nop nop nop jmp VBlank2Return ;--------------------------------------------------------------------------- ; Program Startup Vector ;--------------------------------------------------------------------------- org $1FF3 ; The cart may start in bank 2, then a bankswitch ; will occur and land here... jmp Start ; Start program org $1FFC ; Program startup vector .word Start .word Start include marbank2.asm include marbank3.asm include marbank4.asm
Current Thread |
---|
|
<- Previous | Index | Next -> |
---|---|---|
[stella] "kernel panic!", KirkIsrael | Thread | Re: [stella] Animating the Marbles, Thomas Jentzsch |
[stella] "kernel panic!", KirkIsrael | Date | Re: [stella] Higher Resolution thro, Clay Halliwell |
Month |