; Pac Man for Commodore 64 *=$4600 Incasm "PacManData.asm" *=$0801 ;******************************************* ; Auto start by putting "SYS5120" at the ; Beginning of the BASIC area (starts machine code at $1400 = #5120) ;******************************************* ; 5 1 2 0 BYTE $0B, $10, $0A, $00, $9E, $35, $31, $32, $30, $00, $00, $00 ;*********************************** ; Variables ;*********************************** ;C64 Colors: ; 0 = black 8 = orange ; 1 = white 9 = brown ; 2 = red 10 = light red ; 3 = cyan 11 = dark gray ; 4 = purple 12 = medium gray ; 5 = green 13 = light green ; 6 = blue 14 = light blue ; 7 = yellow 15 = light gray ; Pac Man Colors PacManColor$ BYTE 7; 7=yellow BadGuyColor$ BYTE 1, 2, 3, 4 BackgroundColor0$ BYTE 0 ; Normally 14 = light blue BackgroundColor1$ BYTE 0 ; Normally 0 = black BackgroundColor2$ BYTE 5 ; Normally 5 = green BadGuy0Color$ BYTE 1; BadGuy1Color$ BYTE 2; BadGuy2Color$ BYTE 3; BadGuy3Color$ BYTE 5; BorderColor$ BYTE 0 GameOverColor$ BYTE 7 PausedColor$ BYTE 7 PrizeColor$ BYTE 10 ScreenCharStart = $0400 ; #1024 ScreenColorStart = $D800 ; #55296 ;Timer1$ BYTE 0 ;Timer2$ BYTE 0 DelayTime$ BYTE 0 Color$ BYTE 0 Character$ BYTE 0 XCoord$ BYTE 0 YCoord$ BYTE 0 Index$ BYTE 0 ScoreHighByte$ BYTE 0 ScoreMiddleByte$ BYTE 0 ScoreLowByte$ BYTE 0 AddToScore$ BYTE 0 ScoreOnesDigit$ BYTE 0 ScoreTensDigit$ BYTE 0 ScoreHundredsDigit$ BYTE 0 ScoreThousandsDigit$ BYTE 0 ScoreTenThousandsDigit$ BYTE 0 ScoreHundredThousandsDigit$ BYTE 0 GamePaused$ BYTE 0 ChompsBCDHighByte$ BYTE 0 ChompsBCDMiddleByte$ BYTE 0 ChompsBCDLowByte$ BYTE 0 AddToChompsBCD$ BYTE 0 ChompsCountBCD$ BYTE 0 ChompsBCDOnesDigit$ BYTE 0 ChompsBCDTensDigit$ BYTE 0 ChompsBCDHundredsDigit$ BYTE 0 ChompsBCDThousandsDigit$ BYTE 0 TensOfChomps$ BYTE 0 PelletsHexHighByte$ BYTE 0 PelletsHexMiddleByte$ BYTE 0 PelletsHexLowByte$ BYTE 0 PelletsHex64sDigit$ BYTE 0 PelletsHex32sDigit$ BYTE 0 PelletsHex16sDigit$ BYTE 0 PelletsHexOnesDigit$ BYTE 0 AddToPelletsHex$ BYTE 0 PacManOldX$ BYTE 11 PacManOldY$ BYTE 10 PacManCurrentX$ BYTE 11 PacManCurrentY$ BYTE 10 PacManFutureX$ BYTE 12 PacManFutureY$ BYTE 10 PacManDirection$ BYTE 2; 0=Left 1=Down 2=Right 3=Up PacManMouthState$ BYTE 0; 0=Closed 1=Open PacManIsThere$ BYTE 0 CheckForPacManX$ BYTE 0 CheckForPacManY$ BYTE 0 PacManHittingBadGuy$ BYTE 0 IndexOfBadGuyHit$ BYTE 0 LivesRemaining$ BYTE 3 PacManCharacter$ BYTE 0 BadGuyOldX$ BYTE 16, 17, 22, 23 BadGuyCurrentX$ BYTE 16, 17, 22, 23 BadGuyFutureX$ BYTE 15, 17, 22, 24 BadGuyOldY$ BYTE 12, 9, 9, 12 BadGuyCurrentY$ BYTE 12, 9, 9, 12 BadGuyFutureY$ BYTE 12, 9, 9, 12 BadGuyDirection$ BYTE 0, 0, 2, 2 ;0=Left 1=Down 2=Right 3=Up BadGuyOldCharacter$ BYTE 32, 32, 32, 32 BadGuyOldColor$ BYTE 1, 1, 1, 1 BadGuyIndex$ BYTE 0 BadGuysBlueMode$ BYTE 0 BadGuysBlueModeCounter$ BYTE 0 DisplayXCoord$ BYTE 0 DisplayYCoord$ BYTE 0 HallTestSquareX$ BYTE 0; X coordinate of square to check for intersection-ness HallTestSquareY$ BYTE 0; X coordinate of square to check for intersection-ness SquareIsOpen$ BYTE 0 PeekedCharacter$ BYTE 0 PeekedColor$ BYTE 0 DisplayCharacter$ BYTE 0 CheckForOpenX$ BYTE 0 CheckForOpenY$ BYTE 0 ThisSquareCharacter$ BYTE 0 SquareIsHorizontalHallway$ BYTE 0 SquareIsVerticalHallway$ BYTE 0 Osc1Pitch$ BYTE 200 ;Osc2Pitch$ BYTE 200 ;Osc3Pitch$ BYTE 200 ;Osc4Pitch$ BYTE 200 SoundVolume$ BYTE 0 ThereIsAPellet$ BYTE 0 PelletCheckX$ BYTE 0 PelletCheckY$ BYTE 0 PelletCheckHexX$ BYTE 0 PelletCheckHexY$ BYTE 0 Osc1GateOnVal$ BYTE 33 Osc2GateOnVal$ BYTE 33 Osc3GateOnVal$ BYTE 65 Osc1GateOffVal$ BYTE 32 Osc2GateOffVal$ BYTE 32 Osc3GateOffVal$ BYTE 64 Direction$ BYTE 0 MovementIsHorizontal$ BYTE 0 MovementIsVertical$ BYTE 0 HorizInHorizHallway$ BYTE 0 VertInVertHallway$ BYTE 0 ;Sound settings SIDAttack1$ BYTE 0 SIDDecay1$ BYTE 0 SIDSustain1$ BYTE 15 SIDRelease1$ BYTE 0 SID_HF1@ BYTE 0 SID_LF1@ BYTE 0 SIDAttack2$ BYTE 0 SIDDecay2$ BYTE 6 SIDSustain2$ BYTE 0 SIDRelease2$ BYTE 0 SID_HF2@ BYTE 0 SID_LF2@ BYTE 0 SIDAttack3$ BYTE 0 SIDDecay3$ BYTE 0 SIDSustain3$ BYTE 15 SIDRelease3$ BYTE 0 SID_HF3@ BYTE 0 SID_LF3@ BYTE 0 TempoDelay$ BYTE 26 SIDVolume@ BYTE 0 DutyCycleHighByte3$ BYTE 8 BassStartAddress$ BYTE 0 MelodyStartAddress$ BYTE 0 BassMIDINote$ BYTE 0 MelMIDINote$ BYTE 0 MelNoteIndex$ BYTE 0 BassNoteIndex$ BYTE 0 PitchTranspose$ BYTE 0 TransposeIndex$ BYTE 0 BeatCounter$ BYTE 0 CurrentBeatCounter64Bit$ BYTE 0 OldBeatCounter64Bit$ BYTE 0 CurrentBeatCounter32Bit$ BYTE 0 OldBeatCounter32Bit$ BYTE 0 BassPitchHighByte$ BYTE 0 BassPitchLowByte$ BYTE 0 NoteSelect$ BYTE 0 GateSelect$ BYTE 0 ThisBassNote$ BYTE 0 ThisMelodyNote$ BYTE 0 ThisBassGate$ BYTE 0 ThisMelodyGate$ BYTE 0 CurrentSongSection$ BYTE 0 OldSongSection$ BYTE 0 CurrentMelodyPattern$ BYTE 0 CurrentBassPattern$ BYTE 0 CurrentSynthPatch$ BYTE 0 GameOverIndex$ PausedIndex$ *=$1400 LDA #$93 JSR $FFD2 ; Clear screen ; 110 ;LDA #28 ; binary 0001 1100 ;STA 53272 ; Put in program char mode start chars at $3000 = #12288 LDA #30 ; binary 0001 1110 STA 53272 ; Put in program char mode start chars at $3800 = #14338 ;-Turn on multi color mode ;- Normal value of 53270 is 200 ;- The formula below produces 216 ;- poke53270,peek(53270)or16 LDA #216 STA 53270 LDA BorderColor$ STA 53280 ;Set background color 0 LDA BackgroundColor0$ STA 53281 ;Set background color 1 LDA BackgroundColor1$ STA 53282 ;Set background color 2 LDA BackgroundColor2$ STA 53283 ;************************************************ ; Initialize SID chip for Chomp Sound ;************************************************ JSR InitializeSIDChip ;OSCILLATOR 1 - CHOMPS ;Envelope Generator LDA #0 STA SIDAttack1$ LDA #0 STA SIDDecay1$ LDA #9 STA SIDSustain1$ LDA #0 STA SIDRelease1$ LDA SIDAttack1$ ASL ASL ASL ASL CLC ADC SIDDecay1$ STA 54277 LDA SIDSustain1$ ASL ASL ASL ASL CLC ADC SIDRelease1$ STA 54278 JMP ShowStartScreen NewGame LDA #0 STA ScoreHighByte$ STA ScoreMiddleByte$ STA ScoreLowByte$ STA ScoreHundredThousandsDigit$ STA ScoreTenThousandsDigit$ STA ScoreThousandsDigit$ STA ScoreHundredsDigit$ STA ScoreTensDigit$ STA ScoreOnesDigit$ LDA #0 STA AddToScore$ JSR AddAndDisplayScore ; Select patch for music = Osc 2 and 3 JSR SelectSynthPatch0 LDA #3 STA LivesRemaining$ LDA #21 STA TempoDelay$ NewLevel ;Speed up tempo (reduce TempoDelay) if tempodelay is still nore than 5 LDA TempoDelay$ CMP #3 BMI DontSpeedUp LDA TempoDelay$ SEC CLD SBC #5 STA TempoDelay$ DontSpeedUp JSR DrawMazeScreenColors JSR DrawMazeScreen JSR DrawPrize ;Reset Chomp count LDA #0 STA ChompsBCDHighByte$ STA ChompsBCDMiddleByte$ STA ChompsBCDLowByte$ STA ChompsBCDThousandsDigit$ STA ChompsBCDHundredsDigit$ STA ChompsBCDTensDigit$ STA ChompsBCDOnesDigit$ STA PelletsHexHighByte$ STA PelletsHexMiddleByte$ STA PelletsHexLowByte$ ;********************************************** ;Draw Power Pills ;********************************************** LDA #1 STA XCoord$ LDA #4 STA YCoord$ JSR DrawPowerPill LDA #37 STA XCoord$ LDA #4 STA YCoord$ JSR DrawPowerPill LDA #1 STA XCoord$ LDA #21 STA YCoord$ JSR DrawPowerPill LDA #37 STA XCoord$ LDA #21 STA YCoord$ JSR DrawPowerPill NewLife JSR ResetMusic ; Initialize BadGuys LDA #0 STA BadGuysBlueMode$ LDA #0 STA BadGuyIndex$ LDX #0 LDA #16 STA BadGuyOldX$,x STA BadGuyCurrentX$,x LDA #16 STA BadGuyFutureX$,x LDA #12 STA BadGuyOldY$,x STA BadGuyCurrentY$,x STA BadGuyFutureY$,x LDA #1 STA BadGuyDirection$,x ;0=Left 1=Down 2=Right 3=Up LDA #32 STA BadGuyOldCharacter$,x LDA #1 STA BadGuyOldColor$,x LDX #1 LDA #17 STA BadGuyOldX$,x STA BadGuyCurrentX$,x LDA #17 STA BadGuyFutureX$,x LDA #9 STA BadGuyOldY$,x STA BadGuyCurrentY$,x STA BadGuyFutureY$,x LDA #0 STA BadGuyDirection$,x ;0=Left 1=Down 2=Right 3=Up LDA #32 STA BadGuyOldCharacter$,x LDA #1 STA BadGuyOldColor$,x LDX #2 LDA #22 STA BadGuyOldX$,x STA BadGuyCurrentX$,x LDA #22 STA BadGuyFutureX$,x LDA #9 STA BadGuyOldY$,x STA BadGuyCurrentY$,x STA BadGuyFutureY$,x LDA #2 STA BadGuyDirection$,x ;0=Left 1=Down 2=Right 3=Up LDA #32 STA BadGuyOldCharacter$,x LDA #1 STA BadGuyOldColor$,x LDX #3 LDA #23 STA BadGuyOldX$,x STA BadGuyCurrentX$,x LDA #24 STA BadGuyFutureX$,x LDA #12 STA BadGuyOldY$,x STA BadGuyCurrentY$,x STA BadGuyFutureY$,x LDA #2 STA BadGuyDirection$,x ;0=Left 1=Down 2=Right 3=Up LDA #32 STA BadGuyOldCharacter$,x LDA #1 STA BadGuyOldColor$,x ;Intitialize PacMan LDA #19 STA PacManOldX$ LDA #2 STA PacManOldY$ LDA #19 STA PacManCurrentX$ LDA #2 STA PacManCurrentY$ LDA #20 STA PacManFutureX$ LDA #2 STA PacManFutureY$ LDA #2 STA PacManDirection$ ; 0=Left 1=Down 2=Right 3=Up ; ;Intitialize PacMan for debugging ; LDA #38 ; STA PacManOldX$ ; LDA #1 ; STA PacManOldY$ ; LDA #38 ; STA PacManCurrentX$ ; LDA #1 ; STA PacManCurrentY$ ; LDA #37 ; STA PacManFutureX$ ; LDA #1 ; STA PacManFutureY$ ; LDA #0 ; STA PacManDirection$ ; 0=Left 1=Down 2=Right 3=Up ;Draw pac men indicating lives left ;First erase all pac men so the last one won't be there LDA #1 STA XCoord$ LDA #0 STA YCoord$ JSR EraseCharacter LDA #3 STA XCoord$ LDA #0 STA YCoord$ JSR EraseCharacter LDA #5 STA XCoord$ LDA #0 STA YCoord$ JSR EraseCharacter LDA #0 STA Index$ DrawAnIndicatorOrb LDA Index$ ASL ; left shift = multiply number by 2 so pac men will have spaces in between CLC CLD ADC #1 STA XCoord$ LDA #0 STA YCoord$ LDA PacManColor$ STA Color$ ;LDA #106 ; Pac Man Facing Right with mouth closed LDA #107 ; Pac Man Facing Right with mouth open STA Character$ JSR DrawCharacter INC Index$ LDA Index$ CMP LivesRemaining$ BMI DrawAnIndicatorOrb LDA #0 STA PacManMouthState$ ; 0=Closed 1=Open STA DisplayXCoord$ STA DisplayYCoord$ STA HallTestSquareX$ STA HallTestSquareY$ ;STA OpenSquaresFound$ STA SquareIsOpen$ STA PeekedCharacter$ STA DisplayCharacter$ STA CheckForOpenX$ STA CheckForOpenY$ ;Initialize Mussic ;LDX #0 ;LDA MelodyPatternOrder ;STA CurrentMelodyPattern$ ;LDA BassPatternOrder ;STA CurrentBassPattern$ ;LDA SynthPatchOrder ;STA CurrentSynthPatch$ ;CMP #1 ;BNE SelectPatch0 ;JSR SelectSynthPatch1 SelectPatch0 ;JSR SelectSynthPatch0 ;******************************************************************************* ; Main Loop ;******************************************************************************* MainLoop ;********************************************** ;Draw Pac Man ;********************************************** ;Erase Old PacMan LDA PacManOldX$ STA XCoord$ LDA PacManOldY$ STA YCoord$ JSR EraseCharacter JSR GetKeyboardKey JSR MovePacMan LDA PacManCurrentX$ STA XCoord$ LDA PacManCurrentY$ STA YCoord$ JSR DrawPacMan JSR MakeChompUpSoundIfPellet JSR PlayNextNote JSR CheckForCollision LDA #4 ; LDA #40 ; STA DelayTime$ ; JSR AddTimeDelay JSR GetKeyboardKey JSR MovePacMan LDA PacManCurrentX$ STA XCoord$ LDA PacManCurrentY$ STA YCoord$ JSR DrawPacMan JSR MakeChompDownSoundIfPellet JSR CheckForCollision LDA #4 ; LDA #40 ; STA DelayTime$ ; JSR AddTimeDelay LDA PacManCurrentX$ STA PacManOldX$ LDA PacManCurrentY$ STA PacManOldY$ LDA PacManFutureX$ STA PacManCurrentX$ LDA PacManFutureY$ STA PacManCurrentY$ ; ;If the number of Chomps is greater than a certain amount, ; ;start counting the number of Pellets on the screen every 32-bit ; ;cycle to see if PacMan has eaten them all LDA ChompsBCDHundredsDigit$ ASL A ASL A ASL A ASL A AND #$F0 ; get rid of whatever came in from the bottom CLC SED ADC ChompsBCDTensDigit$ STA TensOfChomps$ ;STA Character$ ;LDA #10 ;STA XCoord$ ;LDA #3 ;STA YCoord$ ;LDA #0 ;STA Color$ ;JSR DrawCharacter ; Start counting the pellets on the screen after 450 chomps LDA TensOfChomps$ CMP #$45 ; 45 BCD ;CMP #1 ; 1 BCD BMI DontCountPellets LDA BeatCounter$ AND #$0F CMP #0 ; Only count Pellets every 16th beat of the music riff BNE DontCountPellets JSR CountPelletsHex DontCountPellets CLD ;********************************************** ;UpdateBadGuys ;********************************************** LDA #0 STA BadGuyIndex$ UpdateBadGuys JSR MoveBadGuy ;Copy Current values to Old values LDX BadGuyIndex$ LDA BadGuyCurrentX$,x STA BadGuyOldX$,x LDA BadGuyCurrentY$,x STA BadGuyOldY$,x ;Copy Future Values to Current values LDA BadGuyFutureX$,x STA BadGuyCurrentX$,x LDA BadGuyFutureY$,x STA BadGuyCurrentY$,x LDA BadGuyCurrentX$,x STA XCoord$ LDA BadGuyCurrentY$,x STA YCoord$ JSR DrawBadGuy INC BadGuyIndex$ LDA BadGuyIndex$ CMP #4 BMI UpdateBadGuys LDA BadGuysBlueMode$ CMP #1 BNE NoBlueModeCounter INC BadGuysBlueModeCounter$ LDA BadGuysBlueModeCounter$ CMP #63 BNE KeepCounting LDA #0 STA BadGuysBlueMode$ ; Count has reached limit, so exit blue mode STA BadGuysBlueModeCounter$ KeepCounting NoBlueModeCounter ;Freeze JMP Freeze JMP MainLoop BRK ;******************************************************************************* ; Subroutines ;******************************************************************************* ;************************************************* ; DrawPowerPill ;************************************************* ;Draw a power pill Subroutine (XCoord, YCoord) ; Draw the left side DrawPowerPill LDA #10 STA Color$ LDA #110 STA Character$ JSR DrawCharacter ;Increment X Coord by 1 INC XCoord$ ;Draw the right side LDA #10 STA Color$ LDA #111 LDA #111 STA Character$ JSR DrawCharacter RTS ;************************************************* ; DrawPellets ;************************************************* ;Draw Pellets Subroutine (XCoord, YCoord) DrawPellets LDA #$07 ; Color is Yellow STA Color$ LDA #112 ; Character is Pellets STA Character$ JSR DrawCharacter RTS ;************************************************* ; CountPelletsHex ;************************************************* ;Count the number of Pellets characters on the screen ; in a 2-byte hexadecimal number CountPelletsHex LDA #0 STA AddToPelletsHex$ LDA #0 STA PelletsHexHighByte$ STA PelletsHexMiddleByte$ STA PelletsHexLowByte$ LDA #0 STA PelletCheckHexX$ LDA #0 STA PelletCheckHexY$ PelletsHexXLoop LDA #0 STA PelletCheckHexY$ PelletsHexYLoop ; ;Display X value ; LDA #3 ; STA DisplayXCoord$ ; LDA #0 ; STA DisplayYCoord$ ; LDA PelletCheckHexX$ ; STA DisplayCharacter$ ; JSR Displaynumber ; ;Display Y value ; LDA #7 ; STA DisplayXCoord$ ; LDA #0 ; STA DisplayYCoord$ ; LDA PelletCheckHexY$ ; STA DisplayCharacter$ ; JSR Displaynumber ;LDA #10 ;STA DelayTime$ ;JSR AddTimeDelay LDA PelletCheckHexX$ STA XCoord$ LDA PelletCheckHexY$ STA YCoord$ JSR PeekCharacter LDA PeekedCharacter$ CMP #112 BNE NotAPelletsCharacterH LDA #1 STA AddToPelletsHex$ JSR AddToPelletsHexTotal NotAPelletsCharacterH INC PelletCheckHexY$ LDA PelletCheckHexY$ CMP #24 BMI PelletsHexYLoop INC PelletCheckHexX$ LDA PelletCheckHexX$ CMP #39 BMI PelletsHexXLoop ;Have we eaten all Pellets? LDA PelletsHexHighByte$ ORA PelletsHexMiddleByte$ ORA PelletsHexLowByte$ CMP #0 BNE HexNotAllEaten ;BRK ;end game if all Pellets eaten JMP NewLevel HexNotAllEaten ;JSR DisplayChompsBCDTotal RTS ;************************************************* ; DrawPrize ;************************************************* ;Draw prize Subroutine ;Draw the left side DrawPrize LDA #19 STA XCoord$ ; X Coordinate Always the same LDA #7 STA YCoord$ ; Y Coordinate Always the same LDA PrizeColor$ STA Color$ LDA #113 ; Left Side character STA Character$ JSR DrawCharacter ;Increment X Coord by 1 LDA XCoord$ CLC ADC #$01 STA XCoord$ ;Draw the right side LDA #114 STA Character$ JSR DrawCharacter RTS ;************************************************* ; AddTimeDelay ;************************************************* AddTimeDelay LDX DelayTime$ TDL1 LDY #255 TDL2 DEY BNE TDL2 DEX BNE TDL1 RTS ;************************************************* ; DrawPacMan ;************************************************* ;Draw PacMan Subroutine (XCoord, YCoord, PacManDirection) ;Draw different char depending on direction and mouth state ; 0=Left 1=Down 2=Right 3=Up DrawPacMan ;LDA #10 LDA PacManColor$ STA Color$ LDX PacManDirection$ FacingLeft CPX #$00 BNE FacingDown LDA #102 ; Draw Facing Left STA PacManCharacter$ FacingDown CPX #$01 BNE FacingRight LDA #104 ; Draw Facing Down STA PacManCharacter$ FacingRight CPX #$02 BNE FacingUp LDA #106 ; Draw Facing Right STA PacManCharacter$ FacingUp CPX #$03 BNE OpenClosed LDA #108 ; Draw Facing Up STA PacManCharacter$ OpenClosed LDA PacManMouthState$ ; If mouth is open, use the next character CMP #0 BEQ DontAdd INC PacManCharacter$ DontAdd ; JSR PeekCharacter ; LDA PeekedCharacter$ ; CMP #112 ; it's a pellet ; BNE DontAddToPelletCount ; ; LDA #1 ; STA AddToChompsBCD$ ; JSR AddToChompsBCDTotal ;DontAddToPelletCount LDA PacManCharacter$ STA Character$ JSR DrawCharacter ;Alternate mouth state each time Pac Man is drawn LDA PacManMouthState$ CMP #$00 BNE SetTo0 LDA #$01 STA PacManMouthState$ JMP EndOfDrawPacMan SetTo0 LDA #$00 STA PacManMouthState$ EndOfDrawPacMan RTS ; ;************************************************* ; ; MovePacMan ; ;************************************************* MovePacMan ;CalculateFuturePosition CheckForLeft LDA PacManDirection$ ; 0=Left 1=Down 2=Right 3=Up CMP #00 ; He's 'Facing left BNE CheckForRight LDX PacManCurrentX$ DEX STX PacManFutureX$ CheckForRight LDA PacManDirection$ ; 0=Left 1=Down 2=Right 3=Up CMP #02 ; He's 'Facing Right BNE CheckForUp LDX PacManCurrentX$ INX STX PacManFutureX$ CheckForUp LDA PacManDirection$ ; 0=Left 1=Down 2=Right 3=Up CMP #03 ; He's Facing Up BNE CheckForDown LDX PacManCurrentY$ DEX STX PacManFutureY$ CheckForDown LDA PacManDirection$ ; 0=Left 1=Down 2=Right 3=Up CMP #01 ; Face Down BNE CheckForBadGuy LDX PacManCurrentY$ INX STX PacManFutureY$ CheckForBadGuy LDA PacManFutureX$ STA XCoord$ LDA PacManFutureY$ STA YCoord$ JSR PeekCharacter CMP #115 BNE CheckForPellet JMP HandleCollision CheckForPellet LDA PacManCurrentX$ STA XCoord$ LDA PacManCurrentY$ STA YCoord$ JSR PeekCharacter LDA PeekedCharacter$ CMP #112 BNE NoPellet LDA #1 STA ThereIsAPellet$ JMP CheckForObstacles NoPellet ;LDA #$0 ;STA ThereIsAPellet$ ;CheckForObstacles CheckForObstacles LDA PacManFutureX$ STA CheckForOpenX$ LDA PacManFutureY$ STA CheckForOpenY$ JSR CheckForOpenSquare LDA SquareIsOpen$ CMP #0 BNE CheckForPowerPillLeft ;There is an obstacle so set future vals to current vals LDA PacManCurrentX$ STA PacManFutureX$ LDA PacManCurrentY$ STA PacManFutureY$ JMP FinishMovePacMan ;Check for power pill characters CheckForPowerPillLeft LDA PeekedCharacter$ STA ThisSquareCharacter$ CMP #110 BNE CheckForPowerPillRight ;Erase left and right power pill characters LDA PacManFutureX$ STA XCoord$ LDA PacManFutureY$ STA YCoord$ JSR EraseCharacter INC XCoord$ JSR EraseCharacter LDA #$1 STA BadGuysBlueMode$ LDA #0 STA BeatCounter$ LDA #0 STA BadGuysBlueModeCounter$ CheckForPowerPillRight LDA ThisSquareCharacter$ CMP #111 BNE CheckForLeftPrize ;Erase right and left power pill characters LDA PacManFutureX$ STA XCoord$ LDA PacManFutureY$ STA YCoord$ JSR EraseCharacter DEC XCoord$ JSR EraseCharacter LDA #$1 STA BadGuysBlueMode$ LDA #0 STA BeatCounter$ LDA #0 STA BadGuysBlueModeCounter$ CheckForLeftPrize LDA ThisSquareCharacter$ CMP #113 BNE CheckForRightPrize ;Erase left and right Prize characters LDA PacManFutureX$ STA XCoord$ LDA PacManFutureY$ STA YCoord$ JSR EraseCharacter INC XCoord$ JSR EraseCharacter LDA #200 STA AddToScore$ JSR AddAndDisplayScore JSR PrizeSound CheckForRightPrize LDA ThisSquareCharacter$ CMP #114 BNE FinishMovePacMan ;Erase right and left Prize characters LDA PacManFutureX$ STA XCoord$ LDA PacManFutureY$ STA YCoord$ JSR EraseCharacter DEC XCoord$ JSR EraseCharacter LDA #200 STA AddToScore$ JSR AddAndDisplayScore JSR PrizeSound FinishMovePacMan RTS ;************************************************* ; PrizeSound ;************************************************* PrizeSound ;LDA #15 ;STA 54296 ; Volume LDA #25 STA 54272; Low frequency Register LDA #0 STA 54272; High frequency Register STA Osc1Pitch$ LDA #33 ; Voice 1 sawtooth wave, Gate on ;LDA #17 ; Voice 1 triangle wave, Gate on STA 54276 PrizeLoop LDA Osc1Pitch$ STA 54273 LDA #10 ;LDA #0 STA DelayTime$ JSR AddTimeDelay LDA Osc1Pitch$ CLC ADC #2 STA Osc1Pitch$ CMP #50 BMI PrizeLoop LDA #32 ; Voice 1 sawtooth wave, Gate off ;LDA #16 ; Voice 1 triangle wave, Gate off STA 54276 ;LDA #$00 ;STA 54296; Volume off ;Add 10 to score RTS ;************************************************* ; CheckForCollision ;************************************************* CheckForCollision ;Check for collision with PacMan LDA #0 STA BadGuyIndex$ CheckBadGuy LDA #1 STA PacManHittingBadGuy$ CheckCollisionX LDX BadGuyIndex$ LDA BadGuyCurrentX$,x CMP PacManCurrentX$ BEQ CheckCollisionY LDA #0 ; set PacManHittingBadGuy to 0 if X coordinates are different STA PacManHittingBadGuy$ CheckCollisionY LDX BadGuyIndex$ LDA BadGuyCurrentY$,x CMP PacManCurrentY$ BEQ DoesPacManDie LDA #0 ; set PacManHittingBadGuy to 0 if Y coordinates are different STA PacManHittingBadGuy$ DoesPacManDie LDA PacManHittingBadGuy$ CMP #1 BEQ HandleCollision INC BadGuyIndex$ LDA BadGuyIndex$ CMP #4 BMI CheckBadGuy NoCollision RTS ;************************************************* ; HandleCollision ;************************************************* HandleCollision LDA BadGuyIndex$ STA IndexOfBadGuyHit$ LDA BadGuysBlueMode$ CMP #1 BNE BroDeath JSR PacManEatsBadGuy RTS BroDeath JMP PacManDies ;RTS ;************************************************* ; PacManDies ;************************************************* PacManDies ;LDA #15 ;STA 54296 ; Volume DEC LivesRemaining$ ;Turn off music = oscillators 2 and 3 LDA Osc2GateOffVal$ STA 54283; Bass = osc 2 Gate off LDA Osc3GateOffVal$ STA 54290; Melody Voice 3, Gate off BeginDeathSound LDA #100 STA Osc1Pitch$ LDA #33 STA 54276; Gate on LDA PacManOldX$ STA XCoord$ LDA PacManOldY$ STA YCoord$ JSR EraseCharacter ;This was sometimes erasing Pellets during a collision ;LDA PacManFutureX$ ;STA XCoord$ ;LDA PacManFutureY$ ;STA YCoord$ ;JSR EraseCharacter LDA #102 STA Character$ LDA PacManColor$ STA Color$ LDA PacManCurrentX$ STA XCoord$ LDA PacManCurrentY$ STA YCoord$ DeathSoundLoop JSR DrawCharacter INC Character$ LDA Character$ CMP #109 BNE Not109Yet LDA #102 STA Character$ Not109Yet LDA #20 STA DelayTime$ JSR AddTimeDelay LDX Osc1Pitch$ LDA PitchRegHi,x STA 54273 ;Voice 1 frequency high byte LDA PitchRegLo,x STA 54272 ;Voice 1 frequency low byte DEC Osc1Pitch$ LDA Osc1Pitch$ CMP #60 BPL DeathSoundLoop LDA #32 STA 54276; Gate off LDA #255 ;LDA #0 STA DelayTime$ JSR AddTimeDelay LDA LivesRemaining$ CMP #0 BNE GameNotOverYet JSR GameOverMan GameNotOverYet ;Erase Pac Man LDA PacManCurrentX$ STA XCoord$ LDA PacManCurrentY$ STA YCoord$ JSR EraseCharacter ;Erase BadGuys LDA #0 STA BadGuyIndex$ BadGuyDeathLoop ; Replace characters in current BadGuy locations LDX BadGuyIndex$ LDA BadGuyCurrentX$,x STA XCoord$ LDA BadGuyCurrentY$,x STA YCoord$ LDX BadGuyIndex$ LDA BadGuyOldCharacter$,x STA Character$ LDA BadGuyOldColor$,x STA Color$ JSR DrawCharacter INC BadGuyIndex$ LDA BadGuyIndex$ CMP #4 BNE BadGuyDeathLoop JMP NewLife ; start with PacMan and BadGuys in original positions ;JMP NewLevel for testing NewLevel jump ;************************************************* ; PacManEatsBadGuy ;************************************************* PacManEatsBadGuy ;Check if there's a pellet in the square to be erased ;JSR PeekCharacter ; ;Erase the square with the BadGuy LDX IndexOfBadGuyHit$ LDA BadGuyOldX$,x STA XCoord$ LDA BadGuyOldY$,x STA YCoord$ JSR EraseCharacter ;New - erase old position LDX IndexOfBadGuyHit$ LDA BadGuyCurrentX$,x STA XCoord$ LDA BadGuyCurrentY$,x STA YCoord$ JSR EraseCharacter ;;New - erase future position ;LDX IndexOfBadGuyHit$ ;LDA BadGuyFutureX$,x ;STA XCoord$ ;LDA BadGuyFutureY$,x ;STA YCoord$ ;JSR EraseCharacter LDX IndexOfBadGuyHit$ LDA #32 STA BadGuyOldCharacter$,x LDA #19 STA BadGuyCurrentX$,x LDA #12 STA BadGuyCurrentY$,x LDA #19 STA BadGuyOldX$,x LDA #12 STA BadGuyOldY$,x LDA #19 STA BadGuyFutureX$,x LDA #11 STA BadGuyFutureY$,x LDA #3 STA BadGuyDirection$,x ; 0=Left 1=Down 2=Right 3=Up ;Chomp Sound! LDA #25 STA 54272; Low frequency Register LDA #100 STA 54272; High frequency Register STA Osc1Pitch$ LDA #33 ; Voice 1 sawtooth wave, Gate on ;LDA #17 ; Voice 1 triangle wave, Gate on STA 54276; Gate on ChompBadGuyLoop LDA Osc1Pitch$ STA 54273 LDA #3 ;LDA #0 STA DelayTime$ JSR AddTimeDelay LDA Osc1Pitch$ SBC #1 STA Osc1Pitch$ CMP #0 BPL ChompBadGuyLoop LDA #32 ; Voice 1 sawtooth wave, Gate off ;LDA #16 ; Voice 1 triangle wave, Gate off STA 54276 ;Add 10 (100 on display) to score LDA #10 STA AddToScore$ JSR AddAndDisplayScore RTS ;************************************************* ; DrawBadGuy ;************************************************* ;Draw BadGuy Subroutine (XCoord, YCoord, BadGuyDirection) ; 0=Left 1=Down 2=Right 3=Up DrawBadGuy ; BadGuyDirection$ ; Store the old location of this BadGuy in XCoord$ and YCoord$ LDX BadGuyIndex$ LDA BadGuyOldX$,x STA XCoord$ LDX BadGuyIndex$ LDA BadGuyOldY$,x STA YCoord$ ;At the BadGuy's old location, draw the character that was ;there before we drew the BadGuy over it unless it is ;a BadGuy character = 115 (or a PacMan character 102-109)??? LDX BadGuyIndex$ LDA BadGuyOldCharacter$,x STA Character$ CMP #115 BEQ DontReplaceChar LDX BadGuyIndex$ LDA BadGuyOldCharacter$,x STA Character$ LDX BadGuyIndex$ LDA BadGuyOldColor$,x STA Color$ JSR DrawCharacter DontReplaceChar ; Recall current location of this BadGuy LDX BadGuyIndex$ LDA BadGuyCurrentX$,x STA XCoord$ LDX BadGuyIndex$ LDA BadGuyCurrentY$,x STA YCoord$ ;Store the character and color at this location before ;drawing the BadGuy there, so that it can be put ;back when the BadGuy moves off the square. JSR PeekCharacter LDA PeekedCharacter$ LDX BadGuyIndex$ STA BadGuyOldCharacter$,x LDA PeekedColor$ LDX BadGuyIndex$ STA BadGuyOldColor$,x ;Draw the BadGuy in the new location ; 1=white, 6=dark blue 3=cyan LDA BadGuysBlueMode$ CMP #0 BEQ BlueModeIsOff LDX BadGuyIndex$ LDA #6 STA BadGuyColor$,x ; COLOR IS Dark Blue 3=cyan JMP LoadBadGuyColor BlueModeIsOff ; Colors: ; 0=black 1=white 2=red 3=cyan 4= LDX #0 LDA BadGuy0Color$ STA BadGuyColor$,x LDX #1 LDA BadGuy1Color$ STA BadGuyColor$,x LDX #2 LDA BadGuy2Color$ STA BadGuyColor$,x LDX #3 LDA BadGuy3Color$ STA BadGuyColor$,x LoadBadGuyColor LDX BadGuyIndex$ LDA BadGuyColor$,x STA Color$ LDA #115 ; BadGuy character STA Character$ JSR DrawCharacter RTS ;************************************************* ; MoveBadGuy ;************************************************* MoveBadGuy ; ;Display BadGuyDirection$ at 2,0 ; LDX BadGuyIndex$ ; LDA BadGuyDirection$,x ; STA DisplayCharacter$ ; LDA #2 ; STA DisplayXCoord$ ; LDA #0 ; STA DisplayYCoord$ ; JSR DisplayNumber ; LDA #200 ; STA DelayTime$ ; JSR AddTimeDelay ; delay to make it easier to see the number ;Are we in a hallway? LDX BadGuyIndex$ LDA BadGuyCurrentX$,x STA XCoord$ LDX BadGuyIndex$ LDA BadGuyCurrentY$,x STA YCoord$ JSR CheckForHallway ;Are we moving horizontally or vertically LDX BadGuyIndex$ LDA BadGuyDirection$,x; 0=Left 1=Down 2=Right 3=Up STA Direction$ JSR FindAxisOfMovement ; outputs: MovementIsHorizontal$ ; MovementIsVertical$ ; If he's in a horiz hallway and moving horizontally, he ; should keep going the same way LDA SquareIsHorizontalHallway$ AND MovementIsHorizontal$ STA HorizInHorizHallway$ ; LDA #15 ; STA DisplayXCoord$ ; LDA #0 ; STA DisplayYCoord$ ; LDA #1 ; STA Color$ ; LDA HorizInHorizHallway$ ; STA DisplayCharacter$ ; JSR DisplayNumber LDA HorizInHorizHallway$ CMP #01 BNE CheckVerticalMovement ;We are in a horizontal hallway moving horizontally, ;so keep going the same direction. Jump over ;random number assignment JMP CheckForBadGuyLeft CheckVerticalMovement LDA SquareIsVerticalHallway$ AND MovementIsVertical$ STA VertInVertHallway$ LDA VertInVertHallway$ CMP #01 BEQ CheckForBadGuyLeft ;We are in a vertical hallway moving vertically, ;so keep going the same direction. Jump over ;random number assignment ;CalculateFuturePosition FindARandomNumber ;LDA $DC04 LDA $DC05 EOR $DC04 SBC $DC05 AND #$03 LDX BadGuyIndex$ STA BadGuyDirection$,x; 0=Left 1=Down 2=Right 3=Up CheckForBadGuyLeft LDX BadGuyIndex$ LDA BadGuyDirection$,x; 0=Left 1=Down 2=Right 3=Up CMP #00 ; He's 'Facing left BNE CheckForBadGuyRight LDX BadGuyIndex$ LDY BadGuyCurrentX$,x DEY TYA ; Move left LDX BadGuyIndex$ STA BadGuyFutureX$,x CheckForBadGuyRight LDX BadGuyIndex$ LDA BadGuyDirection$,x ; 0=Left 1=Down 2=Right 3=Up CMP #02 ; He's 'Facing Right BNE CheckForBadGuyUp LDX BadGuyIndex$ LDY BadGuyCurrentX$,x INY ; Move right TYA LDX BadGuyIndex$ STA BadGuyFutureX$,x CheckForBadGuyUp LDX BadGuyIndex$ LDA BadGuyDirection$,x ; 0=Left 1=Down 2=Right 3=Up CMP #03 ; He's 'Facing Up BNE CheckForBadGuyDown LDX BadGuyIndex$ LDY BadGuyCurrentY$,x DEY ; Move up TYA LDX BadGuyIndex$ STA BadGuyFutureY$,x CheckForBadGuyDown LDX BadGuyIndex$ LDA BadGuyDirection$,x ; 0=Left 1=Down 2=Right 3=Up CMP #01 ; Face Down BNE CheckForBadGuyObstacles LDX BadGuyIndex$ LDY BadGuyCurrentY$,x INY ; Move down TYA LDX BadGuyIndex$ STA BadGuyFutureY$,x ;CheckForBadGuyObstacles CheckForBadGuyObstacles ;Check for PacMan at future position ;Load values LDX BadGuyIndex$ LDA BadGuyFutureX$,x STA CheckForPacManX$ LDX BadGuyIndex$ LDA BadGuyFutureY$,x STA CheckForPacManY$ ;Is Pac Man There? JSR CheckForPacMan LDA PacManIsThere$ CMP #1 BNE CheckObst JMP HandleCollision ;Check for obstacles CheckObst LDX BadGuyIndex$ LDA BadGuyFutureX$,x STA CheckForOpenX$ LDX BadGuyIndex$ LDA BadGuyFutureY$,x STA CheckForOpenY$ CheckOpen JSR CheckForOpenSquare LDA SquareIsOpen$ ; returns 1 if the square is open CMP #0 BNE NoBadGuyObstacles ; Set future to present since there is an obstacle in the way LDX BadGuyIndex$ LDA BadGuyCurrentX$,x STA BadGuyFutureX$,x LDA BadGuyCurrentY$,x STA BadGuyFutureY$,x JMP FindARandomNumber ; go back and pick another random # NoBadGuyObstacles RTS ;************************************************* ; FindAxisOfMovement ;************************************************* FindAxisOfMovement ; input = Direction$ ; outputs: MovementIsHorizontal$ ; MovementIsVertical$ ; 0=Left 1=Down 2=Right 3=Up ;Check for left movement LDA Direction$ CMP #0 ; are we going left? BNE CheckForDownMovement ;We are moving left LDA #1 STA MovementIsHorizontal$ LDA #0 STA MovementIsVertical$ JMP Return CheckForDownMovement LDA Direction$ CMP #1 ; are we going down? BNE CheckForRightMovement ;We are moving down LDA #0 STA MovementIsHorizontal$ LDA #1 STA MovementIsVertical$ JMP Return CheckForRightMovement LDA Direction$ CMP #2 ; are we going right? BNE WeAreMovingUp ;We are moving right LDA #1 STA MovementIsHorizontal$ LDA #0 STA MovementIsVertical$ JMP Return WeAreMovingUp ;We are moving up LDA #0 STA MovementIsHorizontal$ LDA #1 STA MovementIsVertical$ Return ; ;Display BadGuyDirection$ at 2,0 ; LDA MovementIsHorizontal$ ; STA DisplayCharacter$ ; LDA #4 ; STA DisplayXCoord$ ; LDA #0 ; STA DisplayYCoord$ ; JSR DisplayNumber ; LDA MovementIsVertical$ ; STA DisplayCharacter$ ; LDA #6 ; STA DisplayXCoord$ ; LDA #0 ; STA DisplayYCoord$ ; JSR DisplayNumber RTS ;************************************************* ; CheckForPacMan ;************************************************* ;Looks for Pac Man at XCoord$, YCoord$ and sets ;PacManIsThere$ to 1 if he is there. ;Pac Man characters are 102-109 CheckForPacMan LDA #1 STA PacManIsThere$ LDA CheckForPacManX$ STA XCoord$ LDA CheckForPacManY$ STA YCoord$ JSR PeekCharacter ; ;Display for debugging ; LDA PeekedCharacter$ ; STA Character$ ; LDA #4 ; STA XCoord$ ; LDA #0 ; STA YCoord$ ; JSR DrawCharacter LDA PeekedCharacter$ CMP #102 BPL CharIsGE102 ; GE (greater than or equal to) 102 LDA #0 STA PacManIsThere$ CharIsGE102 LDA PeekedCharacter$ CMP #110 BMI CharIsLessThan110 LDA #0 STA PacManIsThere$ CharIsLessThan110 ; ;Display for debugging ; LDA PacManIsThere$ ; STA DisplayCharacter$ ; LDA #6 ; STA DisplayXCoord$ ; LDA #0 ; STA DisplayYCoord$ ; JSR DisplayNumber ; RTS ;************************************************* ; MakeChompUpSoundIfPellet ;************************************************* MakeChompUpSoundIfPellet ;LDA #15 ;STA 54296 ; Volume LDA #25 STA 54272; Low frequency Register LDA #0 STA 54272; High frequency Register STA Osc1Pitch$ LDA ThereIsAPellet$ STA AddToScore$ JSR AddAndDisplayScore LDA ThereIsAPellet$ STA AddToChompsBCD$ JSR AddToChompsBCDTotal ;JSR DisplayChompsBCDTotal ;LDA #32 ; Voice 1 sawtooth wave LDA #16 ; Voice 1 triangle wave CLC CLD ADC ThereIsAPellet$ ; gate is 1 if there is a pellet STA 54276 ChompUpLoop LDA Osc1Pitch$ STA 54273 LDA #5 ;LDA #0 STA DelayTime$ JSR AddTimeDelay LDA Osc1Pitch$ CLC ADC #5 STA Osc1Pitch$ CMP #50 BMI ChompUpLoop ;LDA #32 ; Voice 1 sawtooth wave, Gate off LDA #16 ; Voice 1 triangle wave, Gate off STA 54276 ;LDA #$00 ;STA 54296; Volume off ;Add 10 to score RTS ;************************************************* ; MakeChompDownSoundIfPellet ;************************************************* MakeChompDownSoundIfPellet LDA #25 STA 54272; Low frequency Register LDA #50 STA 54272; High frequency Register STA Osc1Pitch$ LDA #16 ; Voice 1 triangle wave CLC CLD ADC ThereIsAPellet$ ; gate is 1 if there is a pellet STA 54276 ChompDownLoop LDA Osc1Pitch$ STA 54273 LDA #5 ;LDA #0 STA DelayTime$ JSR AddTimeDelay LDA Osc1Pitch$ SBC #5 STA Osc1Pitch$ CMP #0 BPL ChompDownLoop ;LDA #32 ; Voice 1 sawtooth wave, Gate off LDA #16 ; Voice 1 triangle wave, Gate off STA 54276 ;LDA #$00 ;STA 54296; Volume off ;Stop chomping sound once Pellets is et LDA #0 STA ThereIsAPellet$ RTS ;************************************************* ; EraseCharacter ;************************************************* ;Erase Character EraseCharacter ;Check to see if there is a pellet in the square to be erased JSR PeekCharacter LDA PeekedCharacter$ CMP #112 BNE JustEraseIt LDA #1 STA AddToChompsBCD$ JSR AddToChompsBCDTotal JustEraseIt LDA #$20 ; A Space STA Character$ JSR DrawCharacter RTS ;************************************************* ; GetKeyboardKey ;************************************************* ;Get key from keyboard PEEK(197) GetKeyboardKey LDA $00C5 STA Character$ ZKey LDA Character$ CMP #12 ; Z key BNE CKey LDA #00 ; Face left STA PacManDirection$ ; 0=Left 1=Down 2=Right 3=Up CKey LDA Character$ CMP #20 ; C key BNE RightBracket LDA #02 ; Face right STA PacManDirection$ ; 0=Left 1=Down 2=Right 3=Up RightBracket LDA Character$ CMP #50 ; ] key BNE Semicolon LDA #03 ; Face Up STA PacManDirection$ ; 0=Left 1=Down 2=Right 3=Up Semicolon LDA Character$ CMP #24 ; semicolon BNE QKey LDA #01 ; Face Down STA PacManDirection$ ; 0=Left 1=Down 2=Right 3=Up QKey LDA Character$ CMP #62 ; Q=quit BNE PKey CLD ; otherwise the C64 ends up in a weird state! BRK PKey LDA Character$ CMP #41 ; P = pause game BNE KeyDone JSR PauseGame KeyDone RTS ;Keyboard characters ; A B C D E F G H I J K L M N O P Q R S T U V W X Y Z ;10 28 20 18 14 21 26 29 33 34 37 42 36 39 38 41 62 17 13 22 30 31 9 23 25 12 PausedMessage ; X= 9 10 11 12 13 14 15 16 17 18 19 ; R _ T O _ R E S U M E BYTE 18, 32, 20, 15, 32, 18, 5, 19, 21, 13, 5; Y=0 ;************************************************* ; PauseGame ;************************************************* PauseGame ;Clear keyboard buffer so the existing space char doesn't ;RTS back from this subroutine LDA #0 STA 198 ;STA 197 LDA PausedColor$ STA Color$ LDA #0 STA PausedIndex$ LDA #0 STA YCoord$ LDA #9 STA XCoord$ PausedXLoop LDX PausedIndex$ LDA PausedMessage,x STA Character$ JSR DrawCharacter INC PausedIndex$ INC XCoord$ LDA XCoord$ CMP #20 BNE PausedXLoop LookForRKey LDA $00C5 CMP #17 ; R to resume ;CMP #60 ; Space bar = pause or unpause BNE LookForRKey EraseMessage LDA #0 STA YCoord$ LDA #9 STA XCoord$ UnpausedXLoop JSR EraseCharacter INC XCoord$ LDA XCoord$ CMP #20 BNE UnpausedXLoop RTS ;************************************************* ; PeekCharacter ;************************************************* ;PeekCharacter Subroutine (XCoord, YCoord) ;Finds the character at XCoord$, YCoord$ and sets PeekedCharacter$ to that PeekCharacter ;Character LDX YCoord$ LDY XCoord$ LDA ScreenOffsetLo,x STA $fd LDA ScreenOffsetHi,x STA $fe LDA ($fd),y STA PeekedCharacter$ ;Color LDX YCoord$ LDY XCoord$ LDA ScrColorOffsetLo,x STA $fd LDA ScrColorOffsetHi,x STA $fe LDA ($fd),y STA PeekedColor$ RTS ;************************************************* ; CheckForHallway ;************************************************* ;CheckForHallway (XCoord, YCoord) CheckForHallway ; returns two variables: SquareIsAHorizontalHallway$ ; and SquareIsAVerticalHallway$. ;Check if the square is a horizontal hallway, i.e. has obstacles above and ;below and open squares on both sides. ;Simultaneously check if the square is a vertical hallway, i.e. has obstacles on both ;sides but open squares above and below ;Start off with SquareIsHorizontalHallway$ =and ;SquareIsVerticalHallway$ = 1. Then change them to 0 ;if any condition is not met LDA #1 STA SquareIsHorizontalHallway$ LDA #1 STA SquareIsVerticalHallway$ ;Store XCoord$ and YCoord$ in HallTestX$ and HallTestY$ for testing LDA XCoord$ STA HallTestSquareX$ LDA YCoord$ STA HallTestSquareY$ ; Y register is used to increment or decrement coordinates to check a ;neighboring square ;Check Square Above CheckSquareAbove LDA HallTestSquareX$ STA CheckForOpenX$ ; Used by the CheckForOpenSquare subroutine LDY HallTestSquareY$ DEY ; Decrement Y to check the square above STY CheckForOpenY$ ; Used by the CheckForOpenSquare subroutine JSR CheckForOpenSquare LDA SquareIsOpen$ ; Returned by CheckForOpenSquare subroutine ; If there's an open square above, then the ; square is not a horizontal hallway. But it still ; might be a vertical hallway. CMP #1 BNE CheckSquareToRight LDA #0 STA SquareIsHorizontalHallway$ CheckSquareToRight LDY HallTestSquareX$ INY STY CheckForOpenX$ LDA HallTestSquareY$ STA CheckForOpenY$ JSR CheckForOpenSquare LDA SquareIsOpen$ ; Returned by CheckForOpenSquare subroutine ; If there's an open square to the right, then the ; square is not a vertical hallway. But it still ; might be a horizontal hallway. CMP #1 BNE CheckSquareBelow LDA #0 STA SquareIsVerticalHallway$ CheckSquareBelow LDA HallTestSquareX$ STA CheckForOpenX$ LDY HallTestSquareY$ INY STY CheckForOpenY$ JSR CheckForOpenSquare LDA SquareIsOpen$ ; Returned by CheckForOpenSquare subroutine ; If there's an open square above, then the ; square is not a horizontal hallway. But it still ; might be a vertical hallway. CMP #1 BNE CheckSquareToLeft LDA #0 STA SquareIsHorizontalHallway$ CheckSquareToLeft LDY HallTestSquareX$ DEY STY CheckForOpenX$ LDA HallTestSquareY$ STA CheckForOpenY$ JSR CheckForOpenSquare LDA SquareIsOpen$ ; Returned by CheckForOpenSquare subroutine ; If there's an open square to the left, then the ; square is not a vertical hallway. But it still ; might be a horizontal hallway. CMP #1 BNE EndHallwayCheck LDA #0 STA SquareIsVerticalHallway$ EndHallwayCheck ; The values of SquareIsHorizontalHallway$ and ; SquareIsVerticalHallway$ are now correct ;; ;Display value of SquareIsHorizontalHallway$ ;; ; at 10,0 ; LDA #10 ; STA DisplayXCoord$ ; LDA #0 ; STA DisplayYCoord$ ; LDA #1 ; STA Color$ ; LDA SquareIsHorizontalHallway$ ; STA DisplayCharacter$ ; JSR DisplayNumber ;; ;; ;Display value of SquareIsVerticalHallway$ ;; ; at 12,0 ; LDA #12 ; STA DisplayXCoord$ ; LDA #0 ; STA DisplayYCoord$ ; LDA #1 ; STA Color$ ; LDA SquareIsVerticalHallway$ ; STA DisplayCharacter$ ; JSR DisplayNumber RTS ;************************************************* ; AddAndDisplayScore ;************************************************* AddAndDisplayScore LDA ScoreLowByte$ CLC SED ;set decimal mode, so result will be BCD ADC AddToScore$ STA ScoreLowByte$ BCC ScoreTens ; Jump over hundreds and thousands calculations ; if there is no carry bit from the add LDA ScoreMiddleByte$ ; Carry bit was set after addition to ScoreLowByte$ ; so add 1 to ScoreMiddleByte$ SED ; decimal mode so result will be BCD CLC ADC #1 STA ScoreMiddleByte$ BCC ScoreThousands LDA ScoreHighByte$ ; Carry bit was set after addition to ScoreMiddleByte$ ; so add 1 to ScoreHighByte$ SED ; decimal mode so result will be BCD CLC ADC #1 STA ScoreHighByte$ ; Hundred Thousands digit LDA ScoreHighByte$ LSR A LSR A LSR A LSR A AND #$0F STA ScoreHundredThousandsDigit$ ; Ten thousands digit LDA ScoreHighByte$ AND #$0F STA ScoreTenThousandsDigit$ ScoreThousands ; Thousands digit LDA ScoreMiddleByte$ LSR A LSR A LSR A LSR A AND #$0F STA ScoreThousandsDigit$ ; Hundreds digit LDA ScoreMiddleByte$ AND #$0F STA ScoreHundredsDigit$ ScoreTens ; Tens digit LDA ScoreLowByte$ LSR A LSR A LSR A LSR A AND #$0F STA ScoreTensDigit$ ; Ones digit LDA ScoreLowByte$ AND #$0F STA ScoreOnesDigit$ ;Display all the digits LDA ScoreHundredThousandsDigit$ STA DisplayCharacter$ LDA #33 STA DisplayXCoord$ LDA #0 STA DisplayYCoord$ JSR DisplayNumber LDA ScoreTenThousandsDigit$ STA DisplayCharacter$ LDA #34 STA DisplayXCoord$ LDA #0 STA DisplayYCoord$ JSR DisplayNumber LDA ScoreThousandsDigit$ STA DisplayCharacter$ LDA #35 STA DisplayXCoord$ LDA #0 STA DisplayYCoord$ JSR DisplayNumber LDA ScoreHundredsDigit$ STA DisplayCharacter$ LDA #36 STA DisplayXCoord$ LDA #0 STA DisplayYCoord$ JSR DisplayNumber LDA ScoreTensDigit$ STA DisplayCharacter$ LDA #37 STA DisplayXCoord$ LDA #0 STA DisplayYCoord$ JSR DisplayNumber LDA ScoreOnesDigit$ STA DisplayCharacter$ LDA #38 STA DisplayXCoord$ LDA #0 STA DisplayYCoord$ JSR DisplayNumber RTS ;************************************************* ; AddToChompsBCDTotal ;************************************************* AddToChompsBCDTotal ;This subroutine counts the number of chomps of Pellets. LDA ChompsBCDLowByte$ CLC SED ;set decimal mode, so result will be BCD ADC AddToChompsBCD$ STA ChompsBCDLowByte$ BCC ChompsBCDTens ; Jump over hundreds and thousands calculations ; if there is no carry bit from the add LDA ChompsBCDMiddleByte$ ; Carry bit was set after addition to Pellets_LowByte$ ; so add 1 to Pellets_MiddleByte$ SED ; decimal mode so result will be BCD CLC ADC #1 STA ChompsBCDMiddleByte$ ; Thousands digit LDA ChompsBCDMiddleByte$ LSR A LSR A LSR A LSR A AND #$0F STA ChompsBCDThousandsDigit$ ; Hundreds digit LDA ChompsBCDMiddleByte$ AND #$0F STA ChompsBCDHundredsDigit$ ChompsBCDTens ; Tens digit LDA ChompsBCDLowByte$ LSR A LSR A LSR A LSR A AND #$0F STA ChompsBCDTensDigit$ ; Ones digit LDA ChompsBCDLowByte$ AND #$0F STA ChompsBCDOnesDigit$ RTS ;************************************************* ; AddToPelletsHexTotal ;************************************************* AddToPelletsHexTotal ;This subroutine counts the number of Pellets on the ;screen. It is called when the number of chomps approaches the ;total amount. This is because the count of chomps occasionally ;skips and becomes inaccurate. Scanning the screen make ;sure the program recognizes when all the Pellets is really gone. LDA PelletsHexLowByte$ CLC ADC AddToPelletsHex$ STA PelletsHexLowByte$ BCC PelletsHex16s ; Jump over 64s and 32s calculations ; if there is no carry bit from the add LDA PelletsHexMiddleByte$ ; Carry bit was set after addition to Pellets_LowByte$ ; so add 1 to Pellets_MiddleByte$ CLC ADC #1 STA PelletsHexMiddleByte$ ; 64s digit LDA PelletsHexMiddleByte$ LSR A LSR A LSR A LSR A AND #$0F STA PelletsHex64sDigit$ ; 32s digit LDA PelletsHexMiddleByte$ AND #$0F STA PelletsHex32sDigit$ PelletsHex16s ; 16s digit LDA PelletsHexLowByte$ LSR A LSR A LSR A LSR A AND #$0F STA PelletsHex16sDigit$ ; Ones digit LDA PelletsHexLowByte$ AND #$0F STA PelletsHexOnesDigit$ RTS ;************************************************* ; CheckForOpenSquare ;************************************************* CheckForOpenSquare ; Open square is a space (32), Pellets (112), ; power pill (110-111), or prize (113-114) ; or a BadGuy (115) or PacMan (102-109)????? ;old working way! LDA #0 STA SquareIsOpen$ LDA CheckForOpenX$ STA XCoord$ LDA CheckForOpenY$ STA YCoord$ JSR PeekCharacter LDA PeekedCharacter$ CMP #32 BNE Not32; It's not a space INC SquareIsOpen$ Not32 LDA PeekedCharacter$ CMP #110 BNE Not110; It's not power pill left INC SquareIsOpen$ Not110 LDA PeekedCharacter$ CMP #111 BNE Not111; It's not power pill right INC SquareIsOpen$ Not111 LDA PeekedCharacter$ CMP #112 BNE Not112; It's not a pellet INC SquareIsOpen$ Not112 LDA PeekedCharacter$ CMP #113 BNE Not113; It's not prize left INC SquareIsOpen$ Not113 LDA PeekedCharacter$ CMP #114 BNE Not114; It's not prize right INC SquareIsOpen$ Not114 LDA PeekedCharacter$ CMP #115 BNE Not115; It's not a BadGuy INC SquareIsOpen$ Not115 RTS ;************************************************* ; DisplayNumber ;************************************************* DisplayNumber LDA #7 ; yellow STA Color$ LDA DisplayXCoord$ STA XCoord$ LDA DisplayYCoord$ STA YCoord$ LDA DisplayCharacter$ ;LDA #1 ; To Test Display CLC ADC #48 STA Character$ JSR DrawCharacter RTS ;************************************************* ; DrawCharacter ;************************************************* ;DrawCharacter Subroutine (XCoord, YCoord, Color, Character) ;;Puts a character Character$ on the screen at XCoord$, YCoord$ with color Color$ ;ScreenCharStart = $0400 ;#1024 ;ScreenColorStart = $D800 ; #55296 DrawCharacter ;Color LDX YCoord$ LDY XCoord$ LDA ScrColorOffsetLo,x STA $fd LDA ScrColorOffsetHi,x STA $fe LDA Color$ STA ($fd),y ;Character LDX YCoord$ LDY XCoord$ LDA ScreenOffsetLo,x STA $fd LDA ScreenOffsetHi,x STA $fe LDA Character$ STA ($fd),y RTS ;************************************************* ; GameOverMan ;************************************************* GameOverMessage ; X= 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 BYTE 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32 ; Y=9 ; G A M E O V E R , M A N ! BYTE 32, 7, 1,13, 5,32,15,22, 5,18,44,32,13, 1,14,33,32 ; Y=10 BYTE 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32 ; Y=11 ; Q = Q U I T BYTE 32,32,32,32,17,32,61,32,17,21, 9,20,32,32,32,32,32 ; Y=12 BYTE 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32 ; Y=13 ; N = N E W G A M E BYTE 32,32,14,32,61,32,14, 5,23,32, 7, 1,13, 5,32,32,32 ; Y=14 BYTE 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32 ; Y=15 GameOverMan LDA GameOverColor$ STA Color$ LDA #0 STA GameOverIndex$ LDA #9 STA YCoord$ GameOverYLoop LDA #11 STA XCoord$ GameOverXLoop LDX GameOverIndex$ LDA GameOverMessage,x STA Character$ JSR DrawCharacter INC GameOverIndex$ INC XCoord$ LDA XCoord$ CMP #28 BNE GameOverXLoop INC YCoord$ LDA YCoord$ CMP #16 BNE GameOverYLoop EndGetKeyboardKey LDA $00C5 STA Character$ CMP #62 ; Q Key BNE NotQ LDA #0 STA 198 ; clear keyboard buffer so there won't be left over chars on the screen BRK NotQ LDA Character$ CMP #39 ; N Key BNE NotN JMP NewGame NotN JMP EndGetKeyboardKey BRK ;************************************************* ; Initialize SID chip ;************************************************* InitializeSIDChip LDA #0 STA 54272 STA 54273 STA 54274 STA 54275 STA 54276 STA 54277 STA 54278 STA 54279 STA 54280 STA 54281 STA 54282 STA 54283 STA 54284 STA 54285 STA 54286 STA 54287 STA 54288 STA 54289 STA 54290 STA 54291 STA 54292 STA 54293 STA 54294 STA 54295 STA 54296 RTS ;************************************************* ; PlayNextNote ;************************************************* PlayNextNote LDA CurrentSongSection$ CMP OldSongSection$ BEQ NotNewSongSection ;Only do this stuff if we are starting a new song section LDX CurrentSongSection$ LDA MelodyPatternOrder,x STA CurrentMelodyPattern$ LDX CurrentSongSection$ LDA BassPatternOrder,x STA CurrentBassPattern$ LDX CurrentSongSection$ LDA SynthPatchOrder,x STA CurrentSynthPatch$ LDX TransposeIndex$ LDA TransposeCycle,x STA PitchTranspose$ ;Select Synth patch LDA CurrentSynthPatch$ CMP #0 BNE SynthPatchNot0 JSR SelectSynthPatch0 JMP SynthPatchSelected SynthPatchNot0 LDA CurrentSynthPatch$ CMP #1 BNE SynthPatchNot1 JSR SelectSynthPatch1 JMP SynthPatchSelected SynthPatchNot1 LDA CurrentSynthPatch$ CMP #2 BNE SynthPatchNot2 JSR SelectSynthPatch2 JMP SynthPatchSelected SynthPatchNot2 SynthPatchSelected ;Go to next pitch transpose value LDA TransposeIndex$ CLC CLD ADC #1 STA TransposeIndex$ CMP #12 BMI NotEndOfTransposeCycle LDA #0 STA TransposeIndex$ NotEndOfTransposeCycle NotNewSongSection ;LDA #15 ;STA 54296 ; Volume LDA BeatCounter$ AND #$1F ; Just use lowest 5 bits = 32-beat pattern STA NoteSelect$ CLD CLC ADC #32 STA GateSelect$; gate values are 32 steps after note values in the array ;PWM on osc 3 = melody voice ;Osc 3 Duty Cycle High byte - use bottom 4 bits only INC DutyCycleHighByte3$ LDA DutyCycleHighByte3$ AND #$0F CMP #0 BEQ DontSetDutyCycleToZero LDA DutyCycleHighByte3$ STA 54289 DontSetDutyCycleToZero BeginPlayNote ;*********************** ; Bass = Oscillator 2 ;*********************** LDX NoteSelect$ LDA CurrentBassPattern$ CMP #0 BNE BassLineIsNot0 ;Get the next note in bass line 0 LDA BassLine0,x STA ThisBassNote$ JMP BassLineSelected BassLineIsNot0 LDA CurrentBassPattern$ CMP #1 BNE BassLineIsNot1 ;Get the next note in bass line 1 LDA BassLine1,x STA ThisBassNote$ JMP BassLineSelected BassLineIsNot1 LDA CurrentBassPattern$ CMP #2 BNE BassLineIsNot2 ;Get the next note in bass line 2 LDA BassLine2,x STA ThisBassNote$ JMP BassLineSelected BassLineIsNot2 LDA CurrentBassPattern$ CMP #3 BNE BassLineIsNot3 ;Get the next note in bass line 3 LDA BassLine3,x STA ThisBassNote$ JMP BassLineSelected BassLineIsNot3 ; LDA CurrentBassPattern$ ; CMP #3 ; BNE BassLineIsNot3; ; ; ;Get the next note in bass line 1 ; LDA BassLine3,x ; JMP BassLineSelected ;BassLineIsNot3 BassLineSelected LDA ThisBassNote$ CLD ; Clear decimal mode CLC ; Clear carry bit ADC PitchTranspose$ ; transpose ;CLC ;CLD ;SBC #4 TAX LDA PitchRegHi,x STA 54280 ;Voice 2 frequency high byte LDA PitchRegLo,x STA 54279 ;Voice 2 frequency low byte LDX GateSelect$ LDA CurrentBassPattern$ CMP #0 BNE BassGateIsNot0 ;Get the next gate in bass line 0 LDA BassLine0,x STA ThisBassGate$ JMP BassGateSelected BassGateIsNot0 LDA CurrentBassPattern$ CMP #1 BNE BassGateIsNot1 ;Get the next gate in bass line 1 LDA BassLine1,x STA ThisBassGate$ JMP BassGateSelected BassGateIsNot1 LDA CurrentBassPattern$ CMP #2 BNE BassGateIsNot2 ;Get the next gate in bass line 2 LDA BassLine2,x STA ThisBassGate$ JMP BassGateSelected BassGateIsNot2 LDA CurrentBassPattern$ CMP #3 BNE BassGateIsNot3 ;Get the next gate in bass line 3 LDA BassLine3,x STA ThisBassGate$ JMP BassGateSelected BassGateIsNot3 BassGateSelected ;*********************** ; Melody = Oscillator 3 ;*********************** LDX NoteSelect$ LDA CurrentMelodyPattern$ CMP #0 BNE MelodyLineIsNot0 ;Get the next note in Melody line 0 LDA MelodyLine0,x STA ThisMelodyNote$ JMP MelodyLineSelected MelodyLineIsNot0 LDA CurrentMelodyPattern$ CMP #1 BNE MelodyLineIsNot1 ;Get the next note in Melody line 1 LDA MelodyLine1,x STA ThisMelodyNote$ JMP MelodyLineSelected MelodyLineIsNot1 LDA CurrentMelodyPattern$ CMP #2 BNE MelodyLineIsNot2 ;Get the next note in Melody line 2 LDA MelodyLine2,x STA ThisMelodyNote$ JMP MelodyLineSelected MelodyLineIsNot2 LDA CurrentMelodyPattern$ CMP #3 BNE MelodyLineIsNot3 ;Get the next note in Melody line 3 LDA MelodyLine3,x STA ThisMelodyNote$ JMP MelodyLineSelected MelodyLineIsNot3 MelodyLineSelected LDA ThisMelodyNote$ CLD ; Clear decimal mode CLC ; Clear carry bit ADC PitchTranspose$ ; transpose ;CLD ;CLC ;SBC #4 TAX LDA PitchRegHi,x STA 54287 ;Voice 2 frequency high byte LDA PitchRegLo,x STA 54286 ;Voice 2 frequency low byte LDX GateSelect$ LDA CurrentMelodyPattern$ CMP #0 BNE MelodyGateIsNot0 ;Get the next gate in Melody line 0 LDA MelodyLine0,x STA ThisMelodyGate$ JMP MelodyGateSelected MelodyGateIsNot0 LDA CurrentMelodyPattern$ CMP #1 BNE MelodyGateIsNot1 ;Get the next gate in Melody line 1 LDA MelodyLine1,x STA ThisMelodyGate$ JMP MelodyGateSelected MelodyGateIsNot1 LDA CurrentMelodyPattern$ CMP #2 BNE MelodyGateIsNot2 ;Get the next gate in Melody line 2 LDA MelodyLine2,x STA ThisMelodyGate$ JMP MelodyGateSelected MelodyGateIsNot2 LDA CurrentMelodyPattern$ CMP #3 BNE MelodyGateIsNot3 ;Get the next gate in Melody line 3 LDA MelodyLine3,x STA ThisMelodyGate$ JMP MelodyGateSelected MelodyGateIsNot3 MelodyGateSelected ;Activate gates if needed ; Bass Gate Off LDA ThisBassGate$ CMP #1 BNE SkipBassGateOff LDA Osc2GateOffVal$ STA 54283; Bass = osc 2 Gate off SkipBassGateOff ; Melody Gate Off LDA ThisMelodyGate$ CMP #1 BNE SkipMelodyGateOff LDA Osc3GateOffVal$ STA 54290; Melody Voice 3, Gate off SkipMelodyGateOff ;LDA #15 ; Wait so Env Gen has time to fire LDA TempoDelay$ ; Wait so Env Gen has time to fire STA DelayTime$ JSR AddTimeDelay ; Bass Gate On LDA ThisBassGate$ CMP #1 BNE SkipBassGateOn LDA Osc2GateOnVal$ STA 54283; Bass = Voice 2, Gate on SkipBassGateOn ; Melody Gate On LDA ThisMelodyGate$ CMP #1 BNE SkipMelodyGateOn LDA Osc3GateOnVal$ STA 54290; Melody = Voice 3 Gate on SkipMelodyGateOn ;LDA #15 ; Wait so Env Gen has time to fire LDA TempoDelay$ ; Wait so Env Gen has time to fire STA DelayTime$ JSR AddTimeDelay ;Advance to next beat of the current pattern for next time LDA BeatCounter$ CLC ADC #1 AND #$7F STA BeatCounter$ ;Move to next song section when BeatCounter$ 64 bit changes LDA BeatCounter$ AND #$40 ; select just the 64 bit ;AND #$20 ; select just the 32 bit LSR LSR LSR LSR LSR LSR STA CurrentBeatCounter64Bit$ ;STA CurrentBeatCounter32Bit$ LDA CurrentSongSection$ STA OldSongSection$ LDA CurrentBeatCounter64Bit$ CMP OldBeatCounter64Bit$ ;LDA CurrentBeatCounter32Bit$ ;CMP OldBeatCounter32Bit$ BEQ DontIncrementSongSection ; Don't increment CurrentSongSection if 64 bit is the same as last time ; Increment CurrentSongSection LDA CurrentSongSection$ CLC CLD ADC #1 AND #$0F ; only use bottom 4 bits to select one of 16 song sections STA CurrentSongSection$ DontIncrementSongSection LDA CurrentBeatCounter64Bit$ STA OldBeatCounter64Bit$ ;LDA CurrentBeatCounter32Bit$ ;STA OldBeatCounter32Bit$ RTS ;************************************************* ; ResetMusic ;************************************************* ResetMusic LDA #15 STA OldSongSection$ LDA #0 STA BeatCounter$ STA CurrentSongSection$ STA CurrentMelodyPattern$ STA CurrentBassPattern$ STA CurrentSynthPatch$ STA TransposeIndex$ STA PitchTranspose$ STA CurrentBeatCounter64Bit$ ;STA CurrentBeatCounter32Bit$ RTS MelodyPatternOrder BYTE 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3 BassPatternOrder BYTE 0, 1, 2, 3, 1, 2, 3, 0, 2, 3, 0, 1, 3, 0, 1, 2 SynthPatchOrder BYTE 0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2, 0 ; ; C F Bb Eb Ab Db Gb B E A D G ;TransposeCycle BYTE 0, 5, 10, 3, 8, 1, 6, 11, 4, 9, 2, 7 ;Up a 4th ; F Bb Eb Ab Db Gb B E A D G C TransposeCycle BYTE 5, 10, 15, 8, 13, 6, 11, 16, 9, 14, 7, 12 ; ;Happy Birthday ; ; F Bb Eb Ab Db Gb B E A D G C ;TransposeCycle BYTE 5, 5, 10, 10, 15, 15, 8, 8, 13, 13, 6, 6 ;Pattern 0 MelodyLine0 ;Main Riff ; C5 C5 Bb4 C5 R G4 R G4 C5 F5 E5 C5 R, R, R, R C5 C5 Bb4 C5 R G4 R G4 C5 F5 E5 C5 R, R, R, R BYTE 84, 84, 82, 84, 0, 79, 0, 79, 84, 89, 88, 84, 0, 0, 0, 0, 84, 84, 82, 84, 0, 79, 0, 79, 84, 89, 88, 84, 0, 0, 0, 0 ;Notes BYTE 1, 1, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1 ;Gates ; ; Happy Birthday ; ; A5 A5 G5 G5 R R C6 C6 B5 B5 B5 B5 B5, B5, G5, G5 A5 A5 G5 G5 R R D6 D6 C5 C5 C5 C5 C5 R G5 G5 ; BYTE 93, 93, 91, 91, 0, 0, 96, 96, 95, 95, 95, 95, 95, 95, 91, 91, 93, 93, 91, 91, 0, 0, 98, 98, 96, 96, 96, 96, 95, 0, 91, 91 ;Notes ; BYTE 1, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 1, 1 ;Gates BassLine0 ;Main Riff ; C1 C2 C1 C2 C1 C2 C1 C2 C1 C2 C1 C2 C1 C2 C1 C2 C1 C2 C1 C2 C1 C2 C1 C2 C1 C2 C1 C2 C1 C2 C1 C2 BYTE 36, 48, 36, 48, 36, 48, 36, 48, 36, 48, 36, 48, 36, 48, 36, 48, 36, 48, 36, 48, 36, 48, 36, 48, 36, 48, 36, 48, 36, 48, 36, 48 ;Notes BYTE 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 ;Gates ;Pattern 1 MelodyLine1 ; ;Won't You Take Me Riff ; ;Vocal Version ; ; R R R G4 Bb4 G4 Bb4 G4 R R R C5 C5 Eb5 Eb5 Eb5 R R R G4 Bb4 G4 Bb5 C5 R R R C5 C5 Eb4 Eb4 Eb4 ; BYTE 0, 0, 0, 79, 82, 79, 82, 79, 0, 0, 0, 84, 84, 87, 87, 87, 0, 0, 0, 79, 82, 79, 82, 84, 0, 0, 0, 84, 84, 75, 75, 75 ;Notes ; BYTE 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0 ;Gates ;Violin Version ; R R R G4 Bb4 G4 Bb4 G4 R R R Bb4 C5 Bb4 Eb5 Eb5 R R R G4 Bb4 G4 Bb4 C5 R R R Bb4 C5 C5 Eb4 Eb4 BYTE 0, 0, 0, 79, 82, 79, 82, 79, 0, 0, 0, 82, 84, 82, 87, 87, 0, 0, 0, 79, 82, 79, 82, 84, 0, 0, 0, 82, 84, 84, 75, 75 ;Notes BYTE 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 0 ;Gates ; ; Happy Birthday ; ; G6 G6 E6 E6 E6 E6 C6 C6 B5 B5 A5 A5 A5, A5, F6, F6 E6 E6 C6 C6 C6 C6 D6 D6 C5 C5 C5 C5 C5 R G5 G5 ; BYTE 103,103,100,100,100,100, 96, 96, 95, 95, 93, 93, 93, 93,101,101,100,100, 96, 96, 96, 96, 98, 98, 96, 96, 96, 96, 96, 0, 91, 91 ;Notes ; BYTE 1, 0, 1, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 1, 1, 1, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 1, 1 ;Gates ; Note number list for reference while making riffs ;Note C0 C#0 D0 D#0 E0 F0 F#0 G0 G#0 A0 A#0 B0 C1 C#1 D1 D#1 E1 F1 F#1 G1 G#1 A1 A#1 B1 ;MIDI 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 ;Note C2 C#2 D2 D#2 E2 F2 F#2 G2 G#2 A2 A#2 B2 C3 C#3 D3 D#3 E3 F3 F#3 G3 G#3 A3 A#3 B3 ;MIDI 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 ;Note C4 C#4 D4 D#4 E4 F4 F#4 G4 G#4 A4 A#4 B4 C5 C#5 D5 D#5 E5 F5 F#5 G5 G#5 A5 A#5 B5 ;MIDI 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86, 87 88 89 90 91 92 93 94 95 ;Note C6 C#6 D6 D#6 E6 F6 F#6 G6 G#6 A6 A#6 B6 C7 C#7 D7 D#7 E7 F7 F#7 G7 G#7 A7 A#7 B7 ;MIDI 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 BassLine1 ;Won't You Take Me Riff ; C2 C2 G1 G1 Bb1 Bb1 B1 B1 C2 C2 G1 G1 Bb1 Bb1 B1 B1 C2 C2 G1 G1 Bb1 Bb1 B1 B1 C2 C2 G1 G1 Bb1 Bb1 B1 B1 BYTE 48, 48, 43, 43, 46, 46, 47, 47, 48, 48, 43, 43, 46, 46, 47, 47, 48, 48, 43, 43, 46, 46, 47, 47, 48, 48, 43, 43, 46, 46, 47, 47 ;Notes BYTE 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 ;Gates ; ;Happy Birthday ; ; C1 C2 C1 C2 E1 E2 E1 E2 F1 F2 F1 F2 F#1 F#2 F#1 F#2 G1 G2 G1 G2 A1 A2 B1 B2 C1 C2 C1 C2 C1 C2 C1 C2 ; BYTE 36, 48, 36, 48, 40, 52, 40, 52, 41, 53, 41, 53, 42, 54, 42, 54, 43, 55, 43, 55, 45, 57, 47, 59, 36, 48, 36, 48, 36, 48, 36, 48 ;Notes ; BYTE 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 ;Gates ;Pattern 2 MelodyLine2 ;Main Riff ; C3 C3 C3 C3 E3 E3 E3 E3 G3 G3 R E4 R, D4, C4, C4 C5 C5 Bb4 C5 R G4 R G4 C5 F5 E5 C5 R, R, R, R BYTE 60, 60, 60, 60, 64, 64, 64, 64, 67, 67, 0, 76, 0, 74, 72, 72, 84, 84, 82, 84, 0, 79, 0, 79, 84, 89, 88, 84, 0, 0, 0, 0 ;Notes BYTE 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 1, 0, 1, 1, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1 ;Gates BassLine2 ;Main Riff ; C1 C2 G1 C2 C1 C2 G1 C2 C1 C2 G1 C2 C1 C2 G1 C2 C1 C2 G1 C2 C1 C2 G1 C2 C1 C2 G1 C2 C1 C2 G1 C2 BYTE 36, 48, 43, 48, 36, 48, 43, 48, 36, 48, 43, 48, 36, 48, 43, 48, 36, 48, 43, 48, 36, 48, 43, 48, 36, 48, 43, 48, 36, 48, 43, 48 ;Notes BYTE 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 ;Gates MelodyLine3 ;Main Riff ; Bb4 Bb4 Bb4 Bb4 A4 A4 A4 A4 G4 G4 G4 G4 F4, F4, F4, E4 C5 C5 Bb4 C5 R G4 R G4 C5 F5 E5 C5 R, R, R, R BYTE 82, 82, 82, 82, 81, 81, 81, 81, 79, 79, 79, 79, 77, 77, 77, 76, 84, 84, 82, 84, 0, 79, 0, 79, 84, 89, 88, 84, 0, 0, 0, 0 ;Notes BYTE 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1 ;Gates BassLine3 ;Main Riff ; C1 C1 E1 E1 G1 G1 Bb1 Bb1 C2 C2 Bb1 Bb1 G1 G1 E1 E2 C1 C1 E1 E1 G1 G1 Bb1 Bb1 C2 C2 Bb1 Bb1 G1 G1 E1 E2 BYTE 36, 36, 40, 40, 43, 43, 46, 46, 48, 48, 46, 46, 43, 43, 40, 40, 36, 36, 40, 40, 43, 43, 46, 46, 48, 48, 46, 46, 43, 43, 40, 40 ;Notes BYTE 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 ;Gates ;************************************************* ; SelectSynthPatch0 ;************************************************* SelectSynthPatch0 ;OSCILLATOR 2 - BASS ;Osc 2 Waveform select ;Gate Off Value LDA #32 ; Noise=128, Pulse=64, 32=Saw, 16=Triangle STA Osc2GateOffVal$ CLC CLD ADC #1 STA Osc2GateOnVal$ ;;Waveform = sawtooth ;LDA 54283 ;ORA #$20 ; Turn on sawtooth bit ;STA 54283 ;Envelope Generator LDA #0 STA SIDAttack2$ LDA #9 STA SIDDecay2$ LDA #0 STA SIDSustain2$ LDA #0 STA SIDRelease2$ LDA SIDAttack2$ ASL ASL ASL ASL CLC ADC SIDDecay2$ STA 54284 LDA SIDSustain2$ ASL ASL ASL ASL CLC ADC SIDRelease2$ STA 54285 ;OSCILLATOR 3 - MELODY ;Osc 3 Waveform select ;Gate Off Value LDA #64 ; Noise=128, Pulse=64, 32=Saw, 16=Triangle STA Osc3GateOffVal$ CLC CLD LDA #65 ; Noise=129, Pulse=65, 33=Saw, 17=Triangle STA Osc3GateOnVal$ ;;Waveform = pulse ;LDA 54290 ;ORA #$40 ; Turn on pulse wave bit ;STA 54290 ;Envelope Generator LDA #0 STA SIDAttack3$ LDA #6 STA SIDDecay3$ LDA #0 STA SIDSustain3$ LDA #0 STA SIDRelease3$ LDA SIDAttack3$ ASL ASL ASL ASL CLC ADC SIDDecay3$ STA 54291 LDA SIDSustain3$ ASL ASL ASL ASL CLC ADC SIDRelease3$ STA 54292 ;Osc 3 pulse wave duty cycle ;Low byte LDA #$00 STA 54288 ;Duty Cycle High byte - use bottom 4 bits only LDA #$08 ; square STA 54289 LDA #31 STA 54296 ; Main Volume 15, low pass filter mode LDA #2 ; Res = 0, Osc 1&3 (chomp and melody) don't go through filter, but osc 2 (bass) does ;LDA #4 ; Res = 0, Osc 1&2 (chomp and bass) don't go through filter, but osc 3 (melody) does ;LDA #0 ; Res = 0, Osc 1-3 don't go through filter STA 54295 LDA #$00 STA 54293 ; Filter cutoff low byte, low 3 bits only ;LDA #255 LDA #40 STA 54294 ; Filter cutoff high byte ;LDA #0 ;STA PitchTranspose$ RTS ;************************************************* ; SelectSynthPatch1 ;************************************************* SelectSynthPatch1 ;OSCILLATOR 2 - BASS ;Osc 2 Waveform select ;Gate Off Value LDA #32 ; Noise=128, Pulse=64, 32=Saw, 16=Triangle STA Osc2GateOffVal$ CLC CLD ADC #1 STA Osc2GateOnVal$ ;Waveform = sawtooth ;LDA 54283 ;ORA #$20 ; Turn on sawtooth bit ;STA 54283 ;Envelope Generator LDA #0 STA SIDAttack2$ LDA #8 STA SIDDecay2$ LDA #3 STA SIDSustain2$ LDA #0 STA SIDRelease2$ LDA SIDAttack2$ ASL ASL ASL ASL CLC ADC SIDDecay2$ STA 54284 LDA SIDSustain2$ ASL ASL ASL ASL CLC ADC SIDRelease2$ STA 54285 ;OSCILLATOR 3 - MELODY ;Osc 3 Waveform select ;Gate Off Value LDA #64 ; Noise=128, Pulse=64, 32=Saw, 16=Triangle STA Osc3GateOffVal$ CLC CLD LDA #65 ; Noise=129, Pulse=65, 33=Saw, 17=Triangle STA Osc3GateOnVal$ ;Envelope Generator LDA #6 STA SIDAttack3$ LDA #8 STA SIDDecay3$ LDA #0 STA SIDSustain3$ LDA #0 STA SIDRelease3$ LDA SIDAttack3$ ASL ASL ASL ASL CLC ADC SIDDecay3$ STA 54291 LDA SIDSustain3$ ASL ASL ASL ASL CLC ADC SIDRelease3$ STA 54292 ;Osc 3 pulse wave duty cycle ;Low byte LDA #$00 STA 54288 ;Duty Cycle High byte - use bottom 4 bits only LDA #$08 ; square STA 54289 LDA #31 STA 54296 ; Main Volume 15, low pass filter mode ;LDA #2 ; Res = 0, Osc 1&3 (chomp and melody) don't go through filter, but osc 2 (bass) does LDA #4 ; Res = 0, Osc 1&2 (chomp and bass) don't go through filter, but osc 3 (melody) does ;LDA #0 ; Res = 0, Osc 1-3 don't go through filter STA 54295 LDA #$00 STA 54293 ; Filter cutoff low byte, low 3 bits only ; LDA #255 LDA #40 STA 54294 ; Filter cutoff high byte ;LDA #0 ;STA PitchTranspose$ RTS ;************************************************* ; SelectSynthPatch2 ;************************************************* SelectSynthPatch2 ;OSCILLATOR 2 - BASS ;Osc 2 Waveform select ;Gate Off Value LDA #64 ; Noise=128, Pulse=64, 32=Saw, 16=Triangle STA Osc2GateOffVal$ CLC CLD ADC #1 STA Osc2GateOnVal$ ;Osc 2 pulse wave duty cycle ;Low byte LDA #$00 STA 54281 ;Osc 2 pulse wave Duty Cycle High byte - use bottom 4 bits only LDA #$08 ; square STA 54282 ;Envelope Generator LDA #0 STA SIDAttack2$ LDA #8 STA SIDDecay2$ LDA #3 STA SIDSustain2$ LDA #0 STA SIDRelease2$ LDA SIDAttack2$ ASL ASL ASL ASL CLC ADC SIDDecay2$ STA 54284 LDA SIDSustain2$ ASL ASL ASL ASL CLC ADC SIDRelease2$ STA 54285 ;OSCILLATOR 3 - MELODY ;Osc 3 Waveform select ;Gate Off Value LDA #32 ; Noise=128, Pulse=64, 32=Saw, 16=Triangle STA Osc3GateOffVal$ CLC CLD ADC #1 STA Osc3GateOnVal$ ;Envelope Generator LDA #7 STA SIDAttack3$ LDA #5 STA SIDDecay3$ LDA #0 STA SIDSustain3$ LDA #0 STA SIDRelease3$ LDA SIDAttack3$ ASL ASL ASL ASL CLC ADC SIDDecay3$ STA 54291 LDA SIDSustain3$ ASL ASL ASL ASL CLC ADC SIDRelease3$ STA 54292 ;Osc 3 pulse wave duty cycle ;Low byte LDA #$00 STA 54288 ;Duty Cycle High byte - use bottom 4 bits only LDA #$08 ; square STA 54289 LDA #31 STA 54296 ; Main Volume 15, low pass filter mode LDA #2 ; Res = 0, Osc 1&3 (chomp and melody) don't go through filter, but osc 2 (bass) does ;LDA #4 ; Res = 0, Osc 1&2 (chomp and bass) don't go through filter, but osc 3 (melody) does ;LDA #0 ; Res = 0, Osc 1-3 don't go through filter STA 54295 LDA #$00 STA 54293 ; Filter cutoff low byte, low 3 bits only ; LDA #255 LDA #40 STA 54294 ; Filter cutoff high byte ;LDA #0 ;STA PitchTranspose$ RTS ; Pitch reguster values for MIDI Note Numbers ; High Byte PitchRegHi BYTE 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0; values 0-23 give no pitch ;Note C0 C#0 D0 D#0 E0 F0 F#0 G0 G#0 A0 A#0 B0 ;MIDI 24 25 26 27 28 29 30 31 32 33 34 35 ; Octave 0 MIDI 24-35 BYTE 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2 ;Note C1 C#1 D1 D#1 E1 F1 F#1 G1 G#1 A1 A#1 B1 ;MIDI 36 37 38 39 40 41 42 43 44 45 46 47 ; Octave 1 MIDI 36-47 BYTE 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 4 ;Note C2 C#2 D2 D#2 E2 F2 F#2 G2 G#2 A2 A#2 B2 ;MIDI 48 49 50 51 52 53 54 55 56 57 58 59 ; Octave 2 MIDI 48-59 BYTE 4, 4, 4, 5, 5, 5, 6, 6, 6, 7, 7, 8 ;Note C3 C#3 D3 D#3 E3 F3 F#3 G3 G#3 A3 A#3 B3 ;MIDI 60 61 62 63 64 65 66 67 68 69 70 71 ; Octave 3 MIDI 60-71 BYTE 8, 9, 9, 10, 10, 11, 12, 12, 13, 14, 15, 16 ;Note C4 C#4 D4 D#4 E4 F4 F#4 G4 G#4 A4 A#4 B4 ;MIDI 72 73 74 75 76 77 78 79 80 81 82 83 ; Octave 4 MIDI 72-83 BYTE 17, 18, 19, 20, 21, 22, 24, 25, 27, 28, 30, 32 ;Note C5 C#5 D5 D#5 E5 F5 F#5 G5 G#5 A5 A#5 B5 ;MIDI 84, 85 86, 87 88 89 90 91 92 93 94 95 ; Octave 5 MIDI 84-95 BYTE 34, 36, 38, 40, 43, 45, 48, 51, 54, 57, 61, 64 ;Note C6 C#6 D6 D#6 E6 F6 F#6 G6 G#6 A6 A#6 B6 ;MIDI 96, 97 98, 99 100 101 102 103 104 105 106 107 ; Octave 6 MIDI 96-107 BYTE 68, 72, 76, 81, 86, 91, 96, 102, 108, 115, 122, 129 ;Note C7 C#7 D7 D#7 E7 F7 F#7 G7 G#7 A7 A#7 B7 ;MIDI108, 109 110, 111 112 113 114 115 116 117 118 119 ; Octave 7 MIDI 108-119 BYTE 137, 145, 153, 163, 172, 183, 193, 205, 217, 230, 244 ;Low Byte PitchRegLo BYTE 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0; values 0-23 give no pitch ;Note C0 C#0 D0 D#0 E0 F0 F#0 G0 G#0 A0 A#0 B0 ;MIDI 24 25 26 27 28 29 30 31 32 33 34 35 ; Octave 0 MIDI 24-35 BYTE 18, 35, 52, 70, 90, 110, 132, 155, 179, 205, 233, 6 ;Note C1 C#1 D1 D#1 E1 F1 F#1 G1 G#1 A1 A#1 B1 ;MIDI 36 37 38 39 40 41 42 43 44 45 46 47 ; Octave 1 MIDI 36-47 BYTE 37, 69, 104, 140, 179, 220, 8, 54, 103, 155, 210, 12 ;Note C2 C#2 D2 D#2 E2 F2 F#2 G2 G#2 A2 A#2 B2 ;MIDI 48 49 50 51 52 53 54 55 56 57 58 59 ; Octave 2 MIDI 48-59 BYTE 73, 139, 208, 25, 103, 185, 16, 108, 206, 53, 163, 23 ;Note C3 C#3 D3 D#3 E3 F3 F#3 G3 G#3 A3 A#3 B3 ;MIDI 60 61 62 63 64 65 66 67 68 69 70 71 ; Octave 3 MIDI 60-71 BYTE 147, 21, 159, 60, 205, 114, 32, 216, 156, 107, 70, 47 ;Note C4 C#4 D4 D#4 E4 F4 F#4 G4 G#4 A4 A#4 B4 ;MIDI 72 73 74 75 76 77 78 79 80 81 82 83 ; Octave 4 MIDI 72-83 BYTE 37, 42, 63, 100, 154, 227, 63, 177, 56, 214, 141, 94 ;Note C5 C#5 D5 D#5 E5 F5 F#5 G5 G#5 A5 A#5 B5 ;MIDI 84, 85 86, 87 88 89 90 91 92 93 94 95 ; Octave 5 MIDI 84-95 BYTE 75, 85, 126, 200, 52, 198, 127, 97, 111, 172, 126, 188 ;Note C6 C#6 D6 D#6 E6 F6 F#6 G6 G#6 A6 A#6 B6 ;MIDI 96, 97 98, 99 100 101 102 103 104 105 106 107 ; Octave 6 MIDI 96-107 BYTE 149, 169, 252, 161, 105, 140, 254, 194, 223, 88, 52, 120 ;Note C7 C#7 D7 D#7 E7 F7 F#7 G7 G#7 A7 A#7 B7 ;MIDI108, 109 110, 111 112 113 114 115 116 117 118 119 ; Octave 7 MIDI 108-119 BYTE 43, 83, 247, 31, 210, 25, 252, 133, 189, 176, 103 ;************************************************* ; ScreenOffset and ScrColorOffset arrays ;************************************************* ;; Each item is the address of the first character on a line of the screen - Number separated by #40 = $28 ScreenOffsetHi BYTE $04,$04,$04,$04,$04,$04,$04,$05,$05,$05,$05,$05,$05,$06,$06,$06,$06,$06,$06,$06,$07,$07,$07,$07,$07 ScreenOffsetLo BYTE $00,$28,$50,$78,$A0,$C8,$F0,$18,$40,$68,$90,$B8,$E0,$08,$30,$58,$80,$A8,$D0,$F8,$20,$48,$70,$98,$C0 ScrColorOffsetHi BYTE $D8,$D8,$D8,$D8,$D8,$D8,$D8,$D9,$D9,$D9,$D9,$D9,$D9,$DA,$DA,$DA,$DA,$DA,$DA,$DA,$DB,$DB,$DB,$DB,$DB ScrColorOffsetLo BYTE $00,$28,$50,$78,$A0,$C8,$F0,$18,$40,$68,$90,$B8,$E0,$08,$30,$58,$80,$A8,$D0,$F8,$20,$48,$70,$98,$C0 ShowStartScreen ; Start Screen JSR DrawStartScreenColors JSR DrawStartScreen ;LDA #8 ;STA CurrentSongSection$ ;LDA #8 ;STA CurrentMelodyPattern$ ;STA CurrentBassPattern$ JSR SelectSynthPatch0 StartGetKeyboardKey JSR PlayNextNote LDA #100 STA DelayTime$ JSR AddTimeDelay LDA $00C5 ;STA Character$ CMP #13 ; S Key BNE NotS JMP NewGame NotS JMP StartGetKeyboardKey RTS *=$3D00 ;;*********************************************************** ;; Draw Start Screen ;; Character Data goes to $ScreenCharStart = $0400 ;;************************************************************* ;; Characters DrawStartScreen LDA #$00 STA $fb LDA #$04 ;top byte of screen memory start STA $fc LDX #$00 ;bottom byte of screen memory start LDA StartScreenCharsL,x STA $fd LDA StartScreenCharsH,x STA $fe LDX #4; repeat several times because each y loop is 255 repetitions StartScreenMainLoop LDY #$00 StartScreenLoop1 LDA ($fd),y STA ($fb),y DEY BNE StartScreenLoop1 INC $fc INC $fe DEX BNE StartScreenMainLoop RTS StartScreenCharsL byte StartScreenChars ;;*********************************************************** ;; StartScreenColors ;; Color Data goes to ScreenColorStart = $D800 ;;************************************************************* ; Colors DrawStartScreenColors LDA #$00 STA $fb LDA #$D8 ; top byte of screen memory start STA $fc LDX #$00 ; bottom byte of screen memory start LDA StartScreenColorsL,x STA $fd LDA StartScreenColorsH,x STA $fe LDX #4 StartColorsMainLoop LDY #$00 StartColorLoop1 LDA ($fd),y STA ($fb),y DEY BNE StartColorLoop1 INC $fc INC $fe DEX BNE StartColorsMainLoop RTS StartScreenColorsL byte StartScreenColors ;;*********************************************************** ;; Draw Maze Screen ;; Character Data goes to $ScreenCharStart = $0400 ;;************************************************************* ;; Characters DrawMazeScreen LDA #$00 STA $fb LDA #$04 ;top byte of screen memory start STA $fc LDX #$00 ;bottom byte of screen memory start LDA MAPL,x STA $fd LDA MAPH,x STA $fe LDX #4; repeat several times because each y loop is 255 repetitions MazeScreenMainLoop LDY #$00 MazeScreenLoop1 LDA ($fd),y STA ($fb),y DEY BNE MazeScreenLoop1 INC $fc INC $fe DEX BNE MazeScreenMainLoop RTS MAPL byte MazeScreenCharacters ;;*********************************************************** ;; Colors ;; Color Data goes to ScreenColorStart = $D800 ;;************************************************************* ; Colors DrawMazeScreenColors LDA #$00 STA $fb LDA #$D8 ; top byte of screen memory start STA $fc LDX #$00 ; bottom byte of screen memory start LDA cMAPL,x STA $fd LDA cMAPH,x STA $fe LDX #4 MazeScreenColorsMainLoop LDY #$00 MazeScreenColorsLoop1 LDA ($fd),y STA ($fb),y DEY BNE MazeScreenColorsLoop1 INC $fc INC $fe DEX BNE MazeScreenColorsMainLoop RTS cMAPL byte MazeScreenColors