LIST OFF ; *** P L A Q U E A T T A C K *** ; Copyright 1983 Activision, Inc ; Programmer: Steve Cartwright ; Analyzed, labeled and commented ; by Dennis Debro ; Last Update: February 20, 2020 ; ; *** 123 BYTES OF RAM USED 5 BYTES FREE ; *** 29 BYTES OF ROM FREE ; ; ============================================================================== ; = THIS REVERSE-ENGINEERING PROJECT IS BEING SUPPLIED TO THE PUBLIC DOMAIN = ; = FOR EDUCATIONAL PURPOSES ONLY. THOUGH THE CODE WILL ASSEMBLE INTO THE = ; = EXACT GAME ROM, THE LABELS AND COMMENTS ARE THE INTERPRETATION OF MY OWN = ; = AND MAY NOT REPRESENT THE ORIGINAL VISION OF THE AUTHOR. = ; = = ; = THE ASSEMBLED CODE IS © 1983, ACTIVISION = ; = = ; ============================================================================== ; ; - Steve Cartwright's third VCS game with Activision ; - Game was completed in 6 weeks ; - developed because another Activision game was behind schedule ; - Borrows heavily from Megamania ; - Looks as though they planned to have 5 game options ; - PAL50 version ~17% slower than NTSC ; - screen is disabled when no player activity for ; ~1:12 for NTSC and ~1:30 for PAL50 processor 6502 include "vcs.h" include "macro.h" include "tia_constants.h" ; ; Make sure we are using vcs.h version 1.05 or greater. ; IF VERSION_VCS < 105 echo "" echo "*** ERROR: vcs.h file *must* be version 1.05 or higher!" echo "*** Updates to this file, DASM, and associated tools are" echo "*** available at https://dasm-assembler.github.io/" echo "" err ENDIF ; ; Make sure we are using macro.h version 1.01 or greater. ; IF VERSION_MACRO < 101 echo "" echo "*** ERROR: macro.h file *must* be version 1.01 or higher!" echo "*** Updates to this file, DASM, and associated tools are" echo "*** available at https://dasm-assembler.github.io/" echo "" err ENDIF LIST ON ;=============================================================================== ; A S S E M B L E R - S W I T C H E S ;=============================================================================== NTSC = 0 PAL50 = 1 PAL60 = 2 TRUE = 1 FALSE = 0 IFNCONST COMPILE_REGION COMPILE_REGION = NTSC ; change to compile for different regions ENDIF IF !(COMPILE_REGION = NTSC || COMPILE_REGION = PAL50 || COMPILE_REGION = PAL60) echo "" echo "*** ERROR: Invalid COMPILE_REGION value" echo "*** Valid values: NTSC = 0, PAL50 = 1, PAL60 = 2" echo "" err ENDIF ;=============================================================================== ; F R A M E T I M I N G S ;=============================================================================== IF COMPILE_REGION = NTSC || COMPILE_REGION = PAL60 VBLANK_TIME = 53 OVERSCAN_TIME = 35 ELSE VBLANK_TIME = 85 OVERSCAN_TIME = 62 ENDIF ;=============================================================================== ; C O L O R - C O N S T A N T S ;=============================================================================== BLACK = $00 WHITE = $0E IF COMPILE_REGION = NTSC YELLOW = $10 RED_ORANGE = $20 BRICK_RED = $30 RED = $40 PURPLE = $50 COBALT_BLUE = $60 ULTRAMARINE_BLUE = $70 BLUE = $80 BLUE_2 = BLUE LT_BLUE = $90 GREEN = $C0 DK_GREEN = $D0 COLOR_PLAYER1_TOOTHPASTE_TUBE = LT_BLUE + 10 COLOR_PLAYER2_TOOTHPASTE_TUBE = DK_GREEN + 6 COLOR_HOT_DOG = BRICK_RED ELSE YELLOW = $20 RED_ORANGE = $20 GREEN = $30 BRICK_RED = $40 DK_GREEN = $50 RED = $60 PURPLE = $70 BLUE = $B0 LT_BLUE = $C0 BLUE_2 = $D0 COLOR_PLAYER1_TOOTHPASTE_TUBE = BLUE_2 + 10 COLOR_PLAYER2_TOOTHPASTE_TUBE = GREEN + 6 COLOR_HOT_DOG = RED ENDIF ;=============================================================================== ; U S E R - C O N S T A N T S ;=============================================================================== ROM_BASE = $F000 H_FONT = 8 H_LIVES = 10 H_COPYRIGHT = 8 H_TOOTHPASTE_TUBE = 22 H_KERNEL = 104 H_TOOTHPASTE = 8 H_TOOTH = 14 H_JUNK_FOOD = 18 H_HAMBURGER = 11 H_HOTDOG = 8 H_FRIES = 13 H_STRAWBERRY = 14 H_GUM_DROPS = 14 H_DONUTS = 9 H_CANDY_CANES = 14 H_ICE_CREAM_CONES = 14 SELECT_DELAY = 30 MAX_JUNK_FOOD_SECTIONS = 8 XMIN = 0 XMAX = 160 TOOTHPASTE_TUBE_YMIN = 8 TOOTHPASTE_TUBE_YMAX = 74 TOOTHPASTE_TUBE_XMIN = 15 TOOTHPASTE_TUBE_XMAX = 141 INIT_GAME_FRAME_DELAY = 32 INCREMENT_LEVEL_FRAME_DELAY = 32 STARTING_NEW_WAVE_FRAME_DELAY = 48 SWAP_PLAYERS_FRAME_DELAY = 80 SWAP_VARIABLES_FRAME_DELAY = 16 TOOTH_PLACEMENT_SOUND_FRAME_DELAY = 16 INIT_TOOTHPASTE_TUBE_VERT_FACING_UP = TOOTHPASTE_TUBE_YMIN - 1 INIT_TOOTHPASTE_TUBE_VERT_FACING_DOWN = TOOTHPASTE_TUBE_YMAX INIT_TOOTHPASTE_TUBE_HORIZ_POS = (XMAX / 2) - 1 TOOTHPASTE_YMAX = 224 ; SWCHA joystick bits: MY_MOVE_RIGHT = <(MOVE_RIGHT) >> 4 MY_MOVE_LEFT = <(MOVE_LEFT) >> 4 MY_MOVE_DOWN = <(MOVE_DOWN) >> 4 MY_MOVE_UP = <(MOVE_UP) >> 4 ; Toothpaste Tube facing values TOOTHPASTE_TUBE_FACING_UP = 0 << 7 TOOTHPASTE_TUBE_FACING_DOWN = 1 << 7 ; gameState status values DEMO_MODE = %10000000 ; current wave status values JUNK_FOOD_VERT_DIR_MASK = %10000000 TOOTH_DECAYING_MASK = %01000000 SWAP_PLAYER_VARIABLES = %00000100 ADVANCING_NEW_WAVE = %00000010 STARTING_NEW_WAVE = %00000001 MAX_TOOTH_PASTE_TUBE_ANIMATION_IDX = 11 MAX_TOOTH_DECAY_ANIMATION = 4 MAX_RESERVED_TEETH = 6 ; wave time values WAVE_TIME_ADVANCED = 33 WAVE_TIME_BEGINNER = 48 ; object score values (BCD) WAVE_01_POINTS = $05 WAVE_02_POINTS = $10 WAVE_03_POINTS = $15 WAVE_04_POINTS = $20 WAVE_05_POINTS = $25 WAVE_06_POINTS = $30 WAVE_07_POINTS = $35 WAVE_08_POINTS = $40 ; arriving Junk Food values NO_ARRIVING_JUNK_FOOD = 1 JUNK_FOOD_MOVE_LEFT = 0 JUNK_FOOD_MOVE_RIGHT = 1 INIT_JUNK_FOOD_HORIZ_MOVE = JUNK_FOOD_MOVE_RIGHT << 3 | JUNK_FOOD_MOVE_LEFT << 2 | JUNK_FOOD_MOVE_RIGHT << 1 | JUNK_FOOD_MOVE_LEFT ;=============================================================================== ; M A C R O S ;=============================================================================== ;------------------------------------------------------- ; FILL_BOUNDARY byte# ; Original author: Dennis Debro (borrowed from Bob Smith / Thomas Jentzsch) ; ; Push data to a certain position inside a page and keep count of how ; many free bytes the programmer will have. ; ; eg: FILL_BOUNDARY 5, 234 ; position at byte #5 in page with $EA is byte filler FREE_BYTES SET 0 .BYTES_TO_SKIP SET 0 MAC FILL_BOUNDARY IF <. > {1} .BYTES_TO_SKIP SET (256 - <.) + {1} ELSE .BYTES_TO_SKIP SET (256 - <.) - (256 - {1}) ENDIF REPEAT .BYTES_TO_SKIP FREE_BYTES SET FREE_BYTES + 1 .byte {2} REPEND ENDM ;=============================================================================== ; Z P - V A R I A B L E S ;=============================================================================== SEG.U variables .org $80 gameSelection ds 1 frameCount ds 1 randomSeed ds 1 selectDebounce ds 1 playerControlValues ds 1 junkFoodGraphicPtrs ds 2 junkFoodColorPtrs ds 2 toothpasteTubeGraphPtrs ds 2 digitPointers ds 12 colorCycleMode ds 1 gameState ds 1 copyrightScrollRate ds 1 currentPlayerNumber ds 1 lowerTeethNUSIZ ds 4 upperTeethNUSIZ ds 4 teethPatternIndexes ds 2 ;-------------------------------------- lowerTeethPatternIndex = teethPatternIndexes upperTeethPatternIndex = lowerTeethPatternIndex + 1 toothDecayColors ds 2 ;-------------------------------------- lowerToothDecayColor = toothDecayColors upperToothDecayColor = lowerToothDecayColor + 1 toothDecayHorizPos ds 2 ;-------------------------------------- lowerToothDecayHorizPos = toothDecayHorizPos upperToothDecayHorizPos = lowerToothDecayHorizPos + 1 toothpasteVelocity ds 1 topJunkFoodGraphicIndex ds 1 toothpasteTubeHorizPos ds 1 toothpasteHorizPos ds 1 removeTeethPattern ds 1 decayingToothHorizPositionIndex ds 1 junkFoodHorizPos ds 6 toothpasteTubeVertPos ds 1 toothpasteVertPos ds 1 currentPlayerVariables ds 7 ;-------------------------------------- bonusTeeth = currentPlayerVariables playerScore = bonusTeeth + 1 currentWave = playerScore + 3 toothPatternValues = currentWave + 1 ;-------------------------------------- lowerTeethValues = toothPatternValues upperTeethValues = lowerTeethValues + 1 reservePlayerVariables ds 7 ;-------------------------------------- reservePlayerLives = reservePlayerVariables reservePlayerScore = reservePlayerLives + 1 reservePlayerWave = reservePlayerScore + 3 reservePlayerToothPattenValues = reservePlayerWave + 1 ;-------------------------------------- reservePlayerLowerTeethValues = reservePlayerToothPattenValues reservePlayerUpperTeethValues = reservePlayerLowerTeethValues + 1 junkFoodPatternIndex ds 8 junkFoodHorizMovementValues ds 2 ;-------------------------------------- arrivingJunkFoodHorizMovement = junkFoodHorizMovementValues normalJunkFoodHorizMovement = arrivingJunkFoodHorizMovement + 1 movementSpeedValues ds 3 ;-------------------------------------- junkFoodHorizSpeedValue = movementSpeedValues junkFoodVertSpeedValue = junkFoodHorizSpeedValue + 1 arrivingJunkFoodSpeedValue = junkFoodVertSpeedValue + 1 junkFoodPositionDeltaValues ds 3 ;-------------------------------------- junkFoodHorizDelta = junkFoodPositionDeltaValues junkFoodVertDelta = junkFoodHorizDelta + 1 arrivingJunkFoodHorizDelta = junkFoodVertDelta + 1 fractionalPositionValues ds 3 ;-------------------------------------- junkFoodHorizFractionalPosValue = fractionalPositionValues junkFoodVertFractionalPosValue = junkFoodHorizFractionalPosValue + 1 currentWaveStatus ds 1 frameDelayValue ds 1 zp_Unused_01 ds 2 junkFoodCollisionValues ds 8 toothDecayAnimationIndexes ds 2 ;-------------------------------------- lowerToothDecayAnimationIdx = toothDecayAnimationIndexes upperToothDecayAnimationIdx = lowerToothDecayAnimationIdx + 1 upperToothDecayGraphPtr ds 2 lowerToothDecayGraphPtr ds 2 zp_Unused_02 ds 1 toothPlacementSoundValues ds 1 wavePointValue ds 1 toothBonusSoundVolume ds 1 toothPlacementSoundVolume ds 1 toothpasteSoundValue ds 1 junkFoodHitSoundValue ds 1 toothpasteTubeAnimationIdx ds 1 toothpasteTubeFacingDir ds 1 tmpPlayerJoystickValues ds 1 ;-------------------------------------- tmpCharHolder = tmpPlayerJoystickValues ;-------------------------------------- tmpScanline = tmpCharHolder ;-------------------------------------- tmpJunkFoodDiv15Remainder = tmpScanline ;-------------------------------------- tmpJunkFoodPatternIndex = tmpJunkFoodDiv15Remainder ;-------------------------------------- tmpBonusToothBitIndex = tmpJunkFoodPatternIndex ;-------------------------------------- tmpLowerTeethPatternIndex = tmpBonusToothBitIndex ;-------------------------------------- tmpJunkFoodIndex = tmpLowerTeethPatternIndex ;-------------------------------------- tmpBoundaryJunkFoodHorizPos = tmpJunkFoodIndex ;-------------------------------------- tmpBonusTeethLoopCount = tmpBoundaryJunkFoodHorizPos ;-------------------------------------- tmpMovementSpeedValue = tmpBonusTeethLoopCount tmpSixDigitLoopCount ds 1 ;-------------------------------------- tmpJunkFoodKernelSection = tmpSixDigitLoopCount ;-------------------------------------- tmpUpperTeethPatternIndex = tmpJunkFoodKernelSection ;-------------------------------------- tmpJunkFoodPattern = tmpUpperTeethPatternIndex ;-------------------------------------- tmpArrivingJunkFoodDirection = tmpJunkFoodPattern tmpDrawLogoLoopCount ds 1 ;-------------------------------------- tmpArrivingJunkFoodLocation = tmpDrawLogoLoopCount tmpToothIndex ds 1 tmpJunkFoodHorizPos ds 1 tmpJunkFoodNUSIZIndex ds 1 ;-------------------------------------- tmpJunkFoodNUSIZValue = tmpJunkFoodNUSIZIndex toothpasteStatus ds 1 numberOfDecayingTeeth ds 2 ;-------------------------------------- numberOfLowerDecayingTeeth = numberOfDecayingTeeth numberOfUpperDecayingTeeth = numberOfLowerDecayingTeeth + 1 echo "***",(* - $80 - 3)d, "BYTES OF RAM USED", ($100 - * + 3)d, "BYTES FREE" ;=============================================================================== ; R O M - C O D E ;=============================================================================== SEG Bank0 .org ROM_BASE Start ; ; Set up everything so the power up state is known. ; sei ; disable interrupts cld ; clear decimal mode ldx #0 ClearRAM lda #0 .clearLoop sta VSYNC,x txs inx stx CTRLPF ; set to PF_NO_REFLECT and MSBL_SIZE1 bne .clearLoop jsr InitializeGameVariables ldx randomSeed ; get random seed value bne MainLoop ; branch if been through cart startup once inx ; x = 1 stx randomSeed ; initialize random seed jmp JumpIntoConsoleSwitchCheck MainLoop lda junkFoodHorizPos + 5 ; get top Junk Food horizontal position ldx #8 ; assume to keep all Junk Food pattern cmp #XMAX - 32 bcc .setTopJunkFoodNUSIZValue ; branch if all 3 patterns visable sbc #XMAX - 32 jsr Div16 tax ; set index for NUSIZ masking table .setTopJunkFoodNUSIZValue lda junkFoodPatternIndex + 7 ; get top Junk Food pattern value and JunkFoodNUSIZIndexMaskingValues,x sta tmpJunkFoodNUSIZIndex ; set index for reading NUSIZ table beq .setTmpJunkFoodHorizPosition ; branch if no Junk Food present tax ; move index value to x register lda PlayerNUSIZValueTable,x ; get NUSIZx value for pattern sta tmpJunkFoodNUSIZValue lda JunkFoodHorizOffsetTable,x clc adc junkFoodHorizPos + 5 ; increment by top Junk Food position cmp #XMAX bcc .setTmpJunkFoodHorizPosition sbc #(XMAX / 2) + 16 .setTmpJunkFoodHorizPosition sta tmpJunkFoodHorizPos ldx #<[upperToothDecayAnimationIdx - toothDecayAnimationIndexes] .determineToothDecayColor ldy #YELLOW + 14 ; assume tooth decay lda toothDecayAnimationIndexes,x ; get tooth decay animation index beq .clearToothDecayHorizPosition lda frameCount ; get current frame count and #3 bne .setToothDecayColor dec toothDecayAnimationIndexes,x ; tooth decay animated every 4 frames beq .clearToothDecayHorizPosition lda frameCount ; get current frame count and #7 bne .setToothDecayColor ldy #WHITE - 2 bpl .setToothDecayColor ; unconditional branch .clearToothDecayHorizPosition sta toothDecayHorizPos,x ; clear horizontal position (i.e. a = 0) sta numberOfDecayingTeeth,x tay ; set y register to BLACK .setToothDecayColor sty toothDecayColors,x dex bpl .determineToothDecayColor ldx toothpasteTubeAnimationIdx ; get Toothpaste Tube animation index cpx #MAX_TOOTH_PASTE_TUBE_ANIMATION_IDX bcc .determineToothpasteTubeGraphicLSBValue ldx #MAX_TOOTH_PASTE_TUBE_ANIMATION_IDX .determineToothpasteTubeGraphicLSBValue lda UpFacingToothpasteTubeLSBValues,x;get up facing graphic LSB value bit toothpasteTubeFacingDir ; check Toothpaste Tube vert direction bpl .setToothpasteTubeGraphicLSBValue;branch if facing up lda DownFacingToothpasteTubeLSBValues,x;get down facing graphic LSB value .setToothpasteTubeGraphicLSBValue sta toothpasteTubeGraphPtrs ldx upperToothDecayAnimationIdx jsr DetermineToothDecayGraphLSBValue sta upperToothDecayGraphPtr ldx lowerToothDecayAnimationIdx jsr DetermineToothDecayGraphLSBValue sta lowerToothDecayGraphPtr ldx currentPlayerNumber ; get the current player number lda ToothpasteTubeColors,x ; get player Toothpaste Tube color sta COLUP0 ; set color for player's score sta COLUP1 DisplayKernel .waitTime lda INTIM bne .waitTime sta WSYNC ; wait for next scan line sta HMOVE lda colorCycleMode ; get color cycle mode value rol ; rotate D7 to D1 rol rol and #DISABLE_TIA ; disable TIA when no player activity sta VBLANK jsr SetupFontHeightSixDigitDisplay lda #NumberFonts .initDigitPointersMSBValue sty digitPointers,x dex dex bpl .initDigitPointersMSBValue dey sty junkFoodColorPtrs + 1 ; Junk Food colors 1 page below NumberFonts dey sty junkFoodGraphicPtrs + 1 ; Junk Food graphics 1 page below colors sty upperToothDecayGraphPtr + 1 sty lowerToothDecayGraphPtr + 1 dey sty toothpasteTubeGraphPtrs + 1 ; Toothpaste Tube graphics 1 page below lda #INIT_GAME_FRAME_DELAY sta frameDelayValue lda #TOOTHPASTE_YMAX sta toothpasteVertPos ; set Toothpaste vertical position lda #15 sta toothPlacementSoundValues ldx #%00111100 stx lowerTeethValues ; initialize teeth values stx upperTeethValues lda gameSelection ; get the current game selection lsr ; shift D0 to carry bcc .setWaveStateToStartNewWave ; branch if ONE_PLAYER game stx reservePlayerLowerTeethValues; initialize reserve player teeth values stx reservePlayerUpperTeethValues .setWaveStateToStartNewWave lda #STARTING_NEW_WAVE sta currentWaveStatus ldx #MAX_JUNK_FOOD_SECTIONS - 1 .resetJunkFoodValues lda #7 << 4 | 7 sta junkFoodPatternIndex,x lda #XMAX + 32 sta junkFoodHorizPos - 2,x dex bpl .resetJunkFoodValues rts MoveArrivingJunkFoodHorizontally lda arrivingJunkFoodSpeedValue ; get arriving junk food speed lsr ; divide value by 16 lsr lsr lsr clc adc #1 sta tmpArrivingJunkFoodLocation lda junkFoodPatternIndex,x ; get Junk Food pattern value and #$0F ; keep current player Junk Food pattern beq .doneMoveArrivingJunkFoodHorizontally;branch if no Junk Food items lda arrivingJunkFoodHorizMovement and BitIsolationValues,x bne .doneMoveArrivingJunkFoodHorizontally lda randomSeed ; get random seed value and #$3F ; 0 <= a <= 63 adc #48 ; 48 <= a <= 111 cmp #(XMAX / 2) bcs .setArrivingJunkFoodDirection sec sbc #31 ; 17 <= a <= 48 .setArrivingJunkFoodDirection sta tmpArrivingJunkFoodDirection cmp #(XMAX / 2) lda junkFoodHorizPos - 2,x ; get Junk Food horizonal position bcs .moveArrivingJunkFoodLeft adc arrivingJunkFoodHorizDelta ; move Junk Food to the right sta junkFoodHorizPos - 2,x sec sbc tmpArrivingJunkFoodDirection cmp tmpArrivingJunkFoodLocation bcc .setJunkFoodToNotArriving rts .moveArrivingJunkFoodLeft sbc arrivingJunkFoodHorizDelta ; move Junk Food to the left sta junkFoodHorizPos - 2,x lda tmpArrivingJunkFoodDirection sec sbc junkFoodHorizPos - 2,x cmp tmpArrivingJunkFoodLocation bcs .doneMoveArrivingJunkFoodHorizontally .setJunkFoodToNotArriving lda arrivingJunkFoodHorizMovement ora BitIsolationValues,x sta arrivingJunkFoodHorizMovement .doneMoveArrivingJunkFoodHorizontally rts MoveNormalJunkFoodHorizontally lda arrivingJunkFoodHorizMovement; get arriving Junk Food values and BitIsolationValues,x beq .doneMoveNormalJunkFoodHorizontally;branch if Junk Food arriving lda junkFoodPatternIndex,x ; get Junk Food pattern value and #7 ; keep current player Junk Food pattern bne .determineNormalJunkFoodHorizDirection;branch if Junk Food present lda #XMAX + 32 sta junkFoodHorizPos - 2,x rts .determineNormalJunkFoodHorizDirection lda normalJunkFoodHorizMovement ; get normal Junk Food movement values and BitIsolationValues,x beq .moveJunkFoodLeft ; branch if bit set to move left lda junkFoodHorizPos - 2,x ; get Junk Food horizonal position clc adc junkFoodHorizDelta ; increment Junk Food horizontal position sta junkFoodHorizPos - 2,x cmp #XMAX - 50 bcs .changeNormalJunkFoodHorizDirection rts .moveJunkFoodLeft lda junkFoodHorizPos - 2,x ; get Junk Food horizontal position sec sbc junkFoodHorizDelta ; decrement Junk Food horizontal position sta junkFoodHorizPos - 2,x cmp #XMIN + 11 bcs .doneMoveNormalJunkFoodHorizontally .changeNormalJunkFoodHorizDirection lda normalJunkFoodHorizMovement eor BitIsolationValues,x sta normalJunkFoodHorizMovement .doneMoveNormalJunkFoodHorizontally rts CheckToRemoveDecayingTooth sta tmpJunkFoodPattern sta tmpArrivingJunkFoodLocation ; not needed or used for routine ldx toothDecayAnimationIndexes,y ; get tooth decay animation value dex cpx #3 bcc .removeTooth ; branch if time to remove decaying tooth ldx #5 .searchForDecayingTooth lda tmpBoundaryJunkFoodHorizPos ; get boundary Junk Food horizontal position sec sbc ToothHorizontalPositionValues,x cmp #XMIN + 14 bcc .foundToothToDecay ; branch if within range of Tooth asl tmpJunkFoodPattern dex bpl .searchForDecayingTooth inx ; x = 0 stx toothDecayAnimationIndexes,y rts .foundToothToDecay stx decayingToothHorizPositionIndex lda tmpJunkFoodPattern and teethPatternIndexes,y sta removeTeethPattern bne SetStartingToothDecayAnimationRate sta toothDecayAnimationIndexes,y ; clear tooth decay animation index rts SetStartingToothDecayAnimationRate lda toothDecayAnimationIndexes,y ; get tooth decay animation value bne SetDecayingToothHorizPosition; branch if tooth decaying sty tmpToothIndex tay ; a = 0 lda currentWaveStatus ; get current wave status values ora #TOOTH_DECAYING_MASK sta currentWaveStatus ; set status to show tooth decaying lda lowerTeethPatternIndex ; get lower teeth pattern index sta lowerTeethValues lda upperTeethPatternIndex ldx #15 .determineNumberOfRemainingTeeth lsr lowerTeethValues ; shift lower teeth values right ror ; rotate carry to D7 and D0 to carry bcc .nextNumberOfRemainingTeeth ; branch if tooth missing iny ; increment number of remaining teeth .nextNumberOfRemainingTeeth dex bpl .determineNumberOfRemainingTeeth cpy #5 bcc SetToothDecayAnimationIndexValue;branch if less than 5 teeth remaining lda #22 sec sbc currentWave bcs .setToothDecayAnimationIndexValue SetToothDecayAnimationIndexValue lda #0 .setToothDecayAnimationIndexValue clc adc #7 ldy tmpToothIndex ; get tooth index value sta toothDecayAnimationIndexes,y ; set tooth decay animation value SetDecayingToothHorizPosition ldx decayingToothHorizPositionIndex lda removeTeethPattern .determineDecayingToothPattern cpx #5 bcs .setDecayingToothHorizPosition lsr ; shift remove teeth pattern right inx bpl .determineDecayingToothPattern;unconditional branch .setDecayingToothHorizPosition sta numberOfDecayingTeeth,y tax lda JunkFoodHorizOffsetTable,x ; get Junk Food horizontal offset ldx decayingToothHorizPositionIndex clc adc ToothHorizontalPositionValues,x;increment by Tooth horizontal position adc #8 ; increment by decaying tooth offset sta toothDecayHorizPos,y rts .removeTooth lda removeTeethPattern ; get teeth pattern to remove and teethPatternIndexes,y ; isolate teeth to be removed eor teethPatternIndexes,y ; flip pattern value to remove teeth sta teethPatternIndexes,y rts SwapPlayerVariables ldx #6 .swapPlayerVariables lda currentPlayerVariables,x ldy reservePlayerVariables,x sty currentPlayerVariables,x sta reservePlayerVariables,x dex bpl .swapPlayerVariables ldx #MAX_JUNK_FOOD_SECTIONS - 1 .swapJunkFoodPatternValues lda junkFoodPatternIndex,x ; get Junk Food pattern value jsr ShiftUpperNybblesToLower sta tmpJunkFoodPatternIndex lda junkFoodPatternIndex,x ; get Junk Food pattern value asl asl asl asl ora tmpJunkFoodPatternIndex sta junkFoodPatternIndex,x dex bpl .swapJunkFoodPatternValues lda gameSelection ; get the current game selection lsr ; shift D0 to carry bcc .doneSwapPlayerVariables ; branch if ONE_PLAYER game lda currentPlayerNumber ; get the current player number eor #1 ; flip D0 sta currentPlayerNumber ; set new current player number .doneSwapPlayerVariables lda #SWAP_VARIABLES_FRAME_DELAY sta frameDelayValue rts .byte $85,$02,$85,$2A,$A2,$0B,$95,$8B,$CA,$CA,$10,$FA;unused opcodes SetupFontHeightSixDigitDisplay lda #H_FONT - 1 ; 2 sta tmpSixDigitLoopCount ; 3 SetupForSixDigitDisplay sta WSYNC ;-------------------------------------- sta HMOVE ; 3 SLEEP 2 ; 2 SLEEP 2 ; 2 SLEEP 2 ; 2 SLEEP 2 ; 2 ldx #HMOVE_R1 | MSBL_SIZE8 | THREE_COPIES;2 stx NUSIZ0 ; 3 = @16 stx NUSIZ1 ; 3 = @19 ldy #PF_REFLECT ; 2 lda #HMOVE_L4 ; 2 SLEEP 2 ; 2 sta RESP0 ; 3 = @28 sta RESP1 ; 3 = @31 sta RESBL ; 3 = @34 sty CTRLPF ; 3 = @37 sta HMBL ; 3 = @40 stx HMP0 ; 3 = @43 sta WSYNC ;-------------------------------------- sta HMOVE ; 3 sty VDELP0 ; 3 = @06 sty VDELP1 ; 3 = @09 dey ; 2 y = 0 sty GRP0 ; 3 = @14 sty GRP1 ; 3 = @17 sty GRP0 ; 3 = @20 sta tmpCharHolder ; 3 sta HMCLR ; 3 = @26 .drawSixDigitDisplay ldy tmpSixDigitLoopCount ; 3 lda (digitPointers + 10),y ; 5 sta tmpCharHolder ; 3 lda (digitPointers + 8),y ; 5 tax ; 2 lda (digitPointers),y ; 5 sta WSYNC ;-------------------------------------- sta HMOVE ; 3 sta GRP0 ; 3 = @06 lda (digitPointers + 2),y ; 5 sta GRP1 ; 3 = @14 lda (digitPointers + 4),y ; 5 sta GRP0 ; 3 = @22 lda (digitPointers + 6),y ; 5 ldy tmpCharHolder ; 3 sta GRP1 ; 3 = @33 stx GRP0 ; 3 = @36 sty GRP1 ; 3 = @39 sta GRP0 ; 3 = @42 dec tmpSixDigitLoopCount ; 5 bpl .drawSixDigitDisplay ; 2³ lda #HMOVE_R8 ; 2 sta HMP0 ; 3 = @54 sta HMP1 ; 3 = @57 sta WSYNC ;-------------------------------------- sta HMOVE ; 3 lda #0 ; 2 sta GRP0 ; 3 = @08 sta GRP1 ; 3 = @11 sta GRP0 ; 3 = @14 rts ; 6 FILL_BOUNDARY 0, 234 ToothpasteTubeGraphics DownFacingToothpasteTube_03 .byte $00 ; |........| .byte $20 ; |..X.....| .byte $20 ; |..X.....| .byte $20 ; |..X.....| .byte $70 ; |.XXX....| .byte $F8 ; |XXXXX...| .byte $70 ; |.XXX....| .byte $88 ; |X...X...| .byte $F8 ; |XXXXX...| .byte $F8 ; |XXXXX...| .byte $F8 ; |XXXXX...| .byte $F8 ; |XXXXX...| .byte $F8 ; |XXXXX...| .byte $70 ; |.XXX....| .byte $F8 ; |XXXXX...| .byte $7C ; |.XXXXX..| ; ; last 7 bytes bytes shared with next table so don't cross page boundaries ; UpFacingToothpasteTube_03 .byte $00 ; |........| .byte $00 ; |........| .byte $00 ; |........| .byte $00 ; |........| .byte $00 ; |........| .byte $00 ; |........| .byte $00 ; |........| .byte $00 ; |........| .byte $7C ; |.XXXXX..| .byte $F8 ; |XXXXX...| .byte $70 ; |.XXX....| .byte $F8 ; |XXXXX...| .byte $F8 ; |XXXXX...| .byte $F8 ; |XXXXX...| .byte $F8 ; |XXXXX...| .byte $F8 ; |XXXXX...| .byte $88 ; |X...X...| .byte $70 ; |.XXX....| .byte $F8 ; |XXXXX...| .byte $70 ; |.XXX....| .byte $20 ; |..X.....| .byte $20 ; |..X.....| .byte $20 ; |..X.....| DownFacingToothpasteTube_02 .byte $00 ; |........| .byte $20 ; |..X.....| .byte $20 ; |..X.....| .byte $20 ; |..X.....| .byte $70 ; |.XXX....| .byte $F8 ; |XXXXX...| .byte $70 ; |.XXX....| .byte $88 ; |X...X...| .byte $F8 ; |XXXXX...| .byte $F8 ; |XXXXX...| .byte $F8 ; |XXXXX...| .byte $F8 ; |XXXXX...| .byte $F8 ; |XXXXX...| .byte $F8 ; |XXXXX...| .byte $F8 ; |XXXXX...| .byte $70 ; |.XXX....| .byte $F8 ; |XXXXX...| .byte $7C ; |.XXXXX..| ; ; last 5 bytes shared with next table so don't cross page boundaries ; UpFacingToothpasteTube_02 .byte $00 ; |........| .byte $00 ; |........| .byte $00 ; |........| .byte $00 ; |........| .byte $00 ; |........| .byte $00 ; |........| .byte $7C ; |.XXXXX..| .byte $F8 ; |XXXXX...| .byte $70 ; |.XXX....| .byte $F8 ; |XXXXX...| .byte $F8 ; |XXXXX...| .byte $F8 ; |XXXXX...| .byte $F8 ; |XXXXX...| .byte $F8 ; |XXXXX...| .byte $F8 ; |XXXXX...| .byte $F8 ; |XXXXX...| .byte $88 ; |X...X...| .byte $70 ; |.XXX....| .byte $F8 ; |XXXXX...| .byte $70 ; |.XXX....| .byte $20 ; |..X.....| .byte $20 ; |..X.....| .byte $20 ; |..X.....| DownFacingToothpasteTube_04 .byte $00 ; |........| .byte $20 ; |..X.....| .byte $20 ; |..X.....| .byte $20 ; |..X.....| .byte $70 ; |.XXX....| .byte $F8 ; |XXXXX...| .byte $70 ; |.XXX....| .byte $88 ; |X...X...| .byte $F8 ; |XXXXX...| .byte $F8 ; |XXXXX...| .byte $F8 ; |XXXXX...| .byte $70 ; |.XXX....| .byte $F8 ; |XXXXX...| .byte $7C ; |.XXXXX..| ; ; last 9 bytes shared with next table so don't cross page boundaries ; UpFacingToothpasteTube_04 .byte $00 ; |........| .byte $00 ; |........| .byte $00 ; |........| .byte $00 ; |........| .byte $00 ; |........| .byte $00 ; |........| .byte $00 ; |........| .byte $00 ; |........| .byte $00 ; |........| .byte $00 ; |........| .byte $7C ; |.XXXXX..| .byte $F8 ; |XXXXX...| .byte $70 ; |.XXX....| .byte $F8 ; |XXXXX...| .byte $F8 ; |XXXXX...| .byte $F8 ; |XXXXX...| .byte $88 ; |X...X...| .byte $70 ; |.XXX....| .byte $F8 ; |XXXXX...| .byte $70 ; |.XXX....| .byte $20 ; |..X.....| .byte $20 ; |..X.....| .byte $20 ; |..X.....| DownFacingToothpasteTube_05 .byte $00 ; |........| .byte $20 ; |..X.....| .byte $20 ; |..X.....| .byte $20 ; |..X.....| .byte $70 ; |.XXX....| .byte $F8 ; |XXXXX...| .byte $70 ; |.XXX....| .byte $88 ; |X...X...| .byte $F8 ; |XXXXX...| .byte $70 ; |.XXX....| .byte $F8 ; |XXXXX...| .byte $7C ; |.XXXXX..| ; ; last 11 bytes shared with next table so don't cross page boundaries ; BlankToothpasteTube .byte $00 ; |........| .byte $00 ; |........| .byte $00 ; |........| .byte $00 ; |........| .byte $00 ; |........| .byte $00 ; |........| .byte $00 ; |........| .byte $00 ; |........| .byte $00 ; |........| .byte $00 ; |........| .byte $00 ; |........| ; ; last 12 bytes shared with next table so don't cross page boundaries ; UpFacingToothpasteTube_05 .byte $00 ; |........| .byte $00 ; |........| .byte $00 ; |........| .byte $00 ; |........| .byte $00 ; |........| .byte $00 ; |........| .byte $00 ; |........| .byte $00 ; |........| .byte $00 ; |........| .byte $00 ; |........| .byte $00 ; |........| .byte $00 ; |........| .byte $7C ; |.XXXXX..| .byte $F8 ; |XXXXX...| .byte $70 ; |.XXX....| .byte $F8 ; |XXXXX...| .byte $88 ; |X...X...| .byte $70 ; |.XXX....| .byte $F8 ; |XXXXX...| .byte $70 ; |.XXX....| .byte $20 ; |..X.....| .byte $20 ; |..X.....| .byte $20 ; |..X.....| DownFacingToothpasteTube_01 .byte $00 ; |........| .byte $20 ; |..X.....| .byte $20 ; |..X.....| .byte $20 ; |..X.....| .byte $70 ; |.XXX....| .byte $F8 ; |XXXXX...| .byte $70 ; |.XXX....| .byte $88 ; |X...X...| .byte $F8 ; |XXXXX...| .byte $F8 ; |XXXXX...| .byte $F8 ; |XXXXX...| .byte $F8 ; |XXXXX...| .byte $F8 ; |XXXXX...| .byte $F8 ; |XXXXX...| .byte $F8 ; |XXXXX...| .byte $F8 ; |XXXXX...| .byte $F8 ; |XXXXX...| .byte $70 ; |.XXX....| .byte $F8 ; |XXXXX...| .byte $7C ; |.XXXXX..| ; ; last 3 bytes shared with next table so don't cross page boundaries ; UpFacingToothpasteTube_01 .byte $00 ; |........| .byte $00 ; |........| .byte $00 ; |........| .byte $00 ; |........| .byte $7C ; |.XXXXX..| .byte $F8 ; |XXXXX...| .byte $70 ; |.XXX....| .byte $F8 ; |XXXXX...| .byte $F8 ; |XXXXX...| .byte $F8 ; |XXXXX...| .byte $F8 ; |XXXXX...| .byte $F8 ; |XXXXX...| .byte $F8 ; |XXXXX...| .byte $F8 ; |XXXXX...| .byte $F8 ; |XXXXX...| .byte $F8 ; |XXXXX...| .byte $88 ; |X...X...| .byte $70 ; |.XXX....| .byte $F8 ; |XXXXX...| .byte $70 ; |.XXX....| .byte $20 ; |..X.....| .byte $20 ; |..X.....| .byte $20 ; |..X.....| UpFacingToothpasteTube_00 .byte $00 ; |........| .byte $7C ; |.XXXXX..| .byte $F8 ; |XXXXX...| .byte $70 ; |.XXX....| .byte $F8 ; |XXXXX...| .byte $F8 ; |XXXXX...| .byte $F8 ; |XXXXX...| .byte $F8 ; |XXXXX...| .byte $F8 ; |XXXXX...| .byte $F8 ; |XXXXX...| .byte $F8 ; |XXXXX...| .byte $F8 ; |XXXXX...| .byte $F8 ; |XXXXX...| .byte $F8 ; |XXXXX...| .byte $F8 ; |XXXXX...| .byte $F8 ; |XXXXX...| .byte $88 ; |X...X...| .byte $70 ; |.XXX....| .byte $F8 ; |XXXXX...| .byte $70 ; |.XXX....| .byte $20 ; |..X.....| .byte $20 ; |..X.....| .byte $20 ; |..X.....| DownFacingToothpasteTube_00 .byte $00 ; |........| .byte $20 ; |..X.....| .byte $20 ; |..X.....| .byte $20 ; |..X.....| .byte $70 ; |.XXX....| .byte $F8 ; |XXXXX...| .byte $70 ; |.XXX....| .byte $88 ; |X...X...| .byte $F8 ; |XXXXX...| .byte $F8 ; |XXXXX...| .byte $F8 ; |XXXXX...| .byte $F8 ; |XXXXX...| .byte $F8 ; |XXXXX...| .byte $F8 ; |XXXXX...| .byte $F8 ; |XXXXX...| .byte $F8 ; |XXXXX...| .byte $F8 ; |XXXXX...| .byte $F8 ; |XXXXX...| .byte $F8 ; |XXXXX...| .byte $F8 ; |XXXXX...| .byte $70 ; |.XXX....| .byte $F8 ; |XXXXX...| .byte $7C ; |.XXXXX..| TeethNUSIZValues .byte ONE_COPY, TWO_MED_COPIES, TWO_COPIES, THREE_COPIES JunkFoodGraphics HamburgerGraphics .byte $00 ; |........| .byte $FF ; |XXXXXXXX| .byte $FF ; |XXXXXXXX| .byte $7E ; |.XXXXXX.| .byte $FF ; |XXXXXXXX| .byte $7E ; |.XXXXXX.| .byte $FF ; |XXXXXXXX| .byte $7E ; |.XXXXXX.| .byte $FF ; |XXXXXXXX| .byte $FF ; |XXXXXXXX| .byte $7E ; |.XXXXXX.| .byte $00 ; |........| .byte $00 ; |........| .byte $00 ; |........| .byte $00 ; |........| .byte $00 ; |........| .byte $00 ; |........| .byte $00 ; |........| StrawberriesGraphics .byte $00 ; |........| .byte $3C ; |..XXXX..| .byte $3C ; |..XXXX..| .byte $5E ; |.X.XXXX.| .byte $76 ; |.XXX.XX.| .byte $5E ; |.X.XXXX.| .byte $FB ; |XXXXX.XX| .byte $BF ; |X.XXXXXX| .byte $FF ; |XXXXXXXX| .byte $7E ; |.XXXXXX.| .byte $7E ; |.XXXXXX.| .byte $18 ; |...XX...| .byte $3C ; |..XXXX..| .byte $14 ; |...X.X..| .byte $00 ; |........| .byte $00 ; |........| .byte $00 ; |........| .byte $00 ; |........| HotdogGraphics .byte $00 ; |........| .byte $3C ; |..XXXX..| .byte $7E ; |.XXXXXX.| .byte $7E ; |.XXXXXX.| .byte $FF ; |XXXXXXXX| .byte $FF ; |XXXXXXXX| .byte $7E ; |.XXXXXX.| .byte $3C ; |..XXXX..| .byte $00 ; |........| .byte $00 ; |........| .byte $00 ; |........| .byte $00 ; |........| .byte $00 ; |........| .byte $00 ; |........| .byte $00 ; |........| .byte $00 ; |........| .byte $00 ; |........| .byte $00 ; |........| GumDropsGraphics .byte $00 ; |........| .byte $3C ; |..XXXX..| .byte $3C ; |..XXXX..| .byte $7E ; |.XXXXXX.| .byte $7E ; |.XXXXXX.| .byte $7E ; |.XXXXXX.| .byte $7E ; |.XXXXXX.| .byte $3C ; |..XXXX..| .byte $08 ; |....X...| .byte $08 ; |....X...| .byte $04 ; |.....X..| .byte $04 ; |.....X..| .byte $02 ; |......X.| .byte $03 ; |......XX| .byte $00 ; |........| .byte $00 ; |........| .byte $00 ; |........| .byte $00 ; |........| FriesGraphics .byte $00 ; |........| .byte $7F ; |.XXXXXXX| .byte $6B ; |.XX.X.XX| .byte $55 ; |.X.X.X.X| .byte $55 ; |.X.X.X.X| .byte $6B ; |.XX.X.XX| .byte $7F ; |.XXXXXXX| .byte $7F ; |.XXXXXXX| .byte $3E ; |..XXXXX.| .byte $EE ; |XXX.XXX.| .byte $AF ; |X.X.XXXX| .byte $25 ; |..X..X.X| .byte $24 ; |..X..X..| .byte $00 ; |........| .byte $00 ; |........| .byte $00 ; |........| .byte $00 ; |........| .byte $00 ; |........| DonutsGraphics .byte $00 ; |........| .byte $3C ; |..XXXX..| .byte $7E ; |.XXXXXX.| .byte $FF ; |XXXXXXXX| .byte $FF ; |XXXXXXXX| .byte $E7 ; |XXX..XXX| .byte $C3 ; |XX....XX| .byte $7E ; |.XXXXXX.| .byte $3C ; |..XXXX..| .byte $00 ; |........| .byte $00 ; |........| .byte $00 ; |........| .byte $00 ; |........| .byte $00 ; |........| .byte $00 ; |........| .byte $00 ; |........| .byte $00 ; |........| .byte $00 ; |........| CandyCanesGraphics .byte $00 ; |........| .byte $30 ; |..XX....| .byte $30 ; |..XX....| .byte $30 ; |..XX....| .byte $30 ; |..XX....| .byte $30 ; |..XX....| .byte $30 ; |..XX....| .byte $30 ; |..XX....| .byte $30 ; |..XX....| .byte $33 ; |..XX..XX| .byte $33 ; |..XX..XX| .byte $3F ; |..XXXXXX| .byte $1E ; |...XXXX.| .byte $0C ; |....XX..| .byte $00 ; |........| .byte $00 ; |........| .byte $00 ; |........| .byte $00 ; |........| IceCreamConesGraphics .byte $00 ; |........| .byte $1C ; |...XXX..| .byte $1C ; |...XXX..| .byte $1C ; |...XXX..| .byte $1C ; |...XXX..| .byte $3E ; |..XXXXX.| .byte $3E ; |..XXXXX.| .byte $1C ; |...XXX..| .byte $3E ; |..XXXXX.| .byte $1C ; |...XXX..| .byte $3E ; |..XXXXX.| .byte $1C ; |...XXX..| .byte $3E ; |..XXXXX.| .byte $1C ; |...XXX..| .byte $00 ; |........| .byte $00 ; |........| .byte $00 ; |........| .byte $00 ; |........| ToothGraphic .byte $00 ; |........| .byte $42 ; |.X....X.| .byte $42 ; |.X....X.| .byte $E7 ; |XXX..XXX| .byte $E7 ; |XXX..XXX| .byte $FF ; |XXXXXXXX| .byte $FF ; |XXXXXXXX| .byte $FF ; |XXXXXXXX| .byte $FF ; |XXXXXXXX| .byte $FF ; |XXXXXXXX| .byte $FF ; |XXXXXXXX| .byte $FF ; |XXXXXXXX| .byte $FF ; |XXXXXXXX| .byte $C3 ; |XX....XX| ToothDecayGraphic_2 .byte $00 ; |........| .byte $42 ; |.X....X.| .byte $42 ; |.X....X.| .byte $E7 ; |XXX..XXX| .byte $E7 ; |XXX..XXX| .byte $C3 ; |XX....XX| .byte $C3 ; |XX....XX| .byte $00 ; |........| .byte $00 ; |........| .byte $00 ; |........| .byte $00 ; |........| .byte $00 ; |........| .byte $00 ; |........| .byte $00 ; |........| ToothDecayGraphic_1 .byte $00 ; |........| .byte $42 ; |.X....X.| .byte $42 ; |.X....X.| .byte $E7 ; |XXX..XXX| .byte $E7 ; |XXX..XXX| .byte $FF ; |XXXXXXXX| .byte $E7 ; |XXX..XXX| .byte $E7 ; |XXX..XXX| .byte $C3 ; |XX....XX| .byte $C3 ; |XX....XX| .byte $00 ; |........| .byte $00 ; |........| .byte $00 ; |........| .byte $00 ; |........| ToothDecayGraphic_0 .byte $00 ; |........| .byte $42 ; |.X....X.| .byte $42 ; |.X....X.| .byte $E7 ; |XXX..XXX| .byte $E7 ; |XXX..XXX| .byte $FF ; |XXXXXXXX| .byte $FF ; |XXXXXXXX| .byte $FF ; |XXXXXXXX| .byte $E7 ; |XXX..XXX| .byte $E7 ; |XXX..XXX| .byte $C3 ; |XX....XX| .byte $C3 ; |XX....XX| .byte $00 ; |........| .byte $00 ; |........| JunkFoodNUSIZIndexMaskingValues .byte %110 .byte %100 .byte %000 .byte %000 .byte %000 .byte %000 .byte %001 .byte %011 .byte %111 ToothpasteTubeColors .byte COLOR_PLAYER1_TOOTHPASTE_TUBE, COLOR_PLAYER2_TOOTHPASTE_TUBE PlayToothPlacementSounds bit gameState ; check current game state bmi .donePlayToothPlacementSounds; branch if in DEMO_MODE lda #31 sta toothPlacementSoundVolume sta AUDV0 sta AUDV1 lda #12 sta AUDC0 sta AUDC1 inc toothPlacementSoundValues lda toothPlacementSoundValues clc adc #2 eor #$1F sta AUDF0 lsr sta AUDF1 lda lowerTeethValues ora upperTeethValues bne .donePlayToothPlacementSounds lda #TOOTH_PLACEMENT_SOUND_FRAME_DELAY sta frameDelayValue .donePlayToothPlacementSounds jmp MainLoop JunkFoodColors HamburgerColors .byte BLACK, RED_ORANGE + 8, RED_ORANGE + 8, YELLOW + 2, GREEN + 4, RED + 2 .byte YELLOW + 10, YELLOW + 2, RED_ORANGE + 8, RED_ORANGE + 6, RED_ORANGE + 4 StrawberriesColors .byte BLACK, RED + 2, RED + 2, RED + 4, RED + 4, RED + 4, RED + 4, RED + 4 .byte RED + 2, RED + 2, GREEN + 6, GREEN + 6, GREEN + 6, GREEN + 6 HotdogColors .byte BLACK, YELLOW + 4, YELLOW + 6, YELLOW + 8, COLOR_HOT_DOG + 2 .byte COLOR_HOT_DOG + 2, YELLOW + 8, YELLOW + 4, BLACK GumDropsColors .byte BLACK, RED + 2, RED + 4, RED + 4, RED + 4, RED + 4, RED + 4, RED + 2 .byte GREEN + 6, GREEN + 6, GREEN + 6, GREEN + 6, GREEN + 6, GREEN + 6 FriesColors .byte BLACK, WHITE - 2, WHITE - 2, WHITE - 2, WHITE - 2, WHITE - 2, WHITE - 2 .byte YELLOW + 4, YELLOW + 8, YELLOW + 8, YELLOW + 8, YELLOW + 8, YELLOW + 8 DonutsColors .byte BLACK, RED_ORANGE + 4, RED_ORANGE + 4, RED_ORANGE + 4, RED + 10 .byte RED + 10, RED + 10, RED + 10, RED + 10 CandyCanesColors .byte BLACK, WHITE - 2, WHITE - 2, RED + 4, RED + 4, WHITE - 2, WHITE - 2 .byte RED + 4, RED + 4, WHITE - 2, WHITE - 2, RED + 4, RED + 4, WHITE - 2 IceCreamConesColors .byte BLACK, RED_ORANGE + 8, RED_ORANGE + 8, RED_ORANGE + 8, RED_ORANGE + 8 .byte RED_ORANGE + 8, RED_ORANGE + 8, GREEN + 6, GREEN + 6, GREEN + 6 .byte WHITE - 2, RED + 4, RED + 4, RED + 4 PF1GumGraphicValues .byte $FF ; |XXXXXXXX| .byte $FF ; |XXXXXXXX| .byte $FF ; |XXXXXXXX| .byte $FF ; |XXXXXXXX| .byte $FF ; |XXXXXXXX| .byte $FF ; |XXXXXXXX| .byte $FF ; |XXXXXXXX| .byte $FF ; |XXXXXXXX| .byte $FF ; |XXXXXXXX| .byte $FF ; |XXXXXXXX| .byte $F8 ; |XXXXX...| .byte $F0 ; |XXXX....| .byte $00 ; |........| .byte $00 ; |........| .byte $00 ; |........| .byte $00 ; |........| PF2GumGraphicValues .byte $FF ; |XXXXXXXX| .byte $FF ; |XXXXXXXX| .byte $FF ; |XXXXXXXX| .byte $FF ; |XXXXXXXX| .byte $7F ; |.XXXXXXX| .byte $3F ; |..XXXXXX| .byte $0F ; |....XXXX| .byte $03 ; |......XX| .byte $01 ; |.......X| .byte $00 ; |........| .byte $00 ; |........| .byte $00 ; |........| .byte $00 ; |........| .byte $00 ; |........| .byte $00 ; |........| .byte $00 ; |........| ToothDecayAnimationValues .byte