(back to project page)

SuperMarioBros Disassembly

                   ********************************************************************************
                   * Super Mario Bros for the NES                                                 *
                   * Copyright 1985 Nintendo, Inc.                                                *
                   ********************************************************************************
                   * Disassembly by doppelganger (doppelheathen@gmail.com).  Obtained from        *
                   * https://gist.github.com/1wErt3r/4048722 (SMBDIS.ASM, posted 9-Nov-2012).     *
                   *                                                                              *
                   * The binary for this project is the iNES image for the "Japan, USA" version   *
                   * of the ROM.  It has three distinct parts:                                    *
                   *  (1) 16 byte iNES header                                                     *
                   *  (2) 32KB PRG ROM                                                            *
                   *  (3) 8KB CHR ROM                                                             *
                   *                                                                              *
                   * Only the PRG section is directly addressable by the 6502.                    *
                   ********************************************************************************
                   * Project created by Andy McFadden, using 6502bench SourceGen v1.8.  This is a *
                   * straight conversion from the original text listing to SourceGen format.      *
                   * Very little has been changed other than formatting (and, most likely, the    *
                   * introduction of some errors).  I have left spelling errors (e.g. LSFR vs.    *
                   * LFSR) in place.                                                              *
                   *                                                                              *
                   * I converted the player and enemy graphics with the "tile grid" visualizer,   *
                   * which mostly worked but some things need to be flipped horizontally partway  *
                   * through (e.g. the top half is A-B, but the bottom half is A-flipA).  On the  *
                   * bright side, the CHR ROM rendering looks pretty good.                        *
                   *                                                                              *
                   * First posted 2020/05/14                                                      *
                   * Last updated 2021/10/23                                                      *
                   ********************************************************************************
                   GreenKoopa      .eq     $00    {const}
                   DeathMusic      .eq     %00000001 {const}
                   GameModeValue   .eq     1      {const}
                   GroundMusic     .eq     %00000001 {const}
                   Sfx_BigJump     .eq     %00000001 {const}
                   Sfx_BrickShatter .eq    %00000001 {const}
                   Sfx_CoinGrab    .eq     %00000001 {const}
                   World2          .eq     1      {const}
                   BuzzyBeetle     .eq     $02    {const}
                   GameOverMusic   .eq     %00000010 {const}
                   Level3          .eq     2      {const}
                   Sfx_BowserFlame .eq     %00000010 {const}
                   Sfx_Bump        .eq     %00000010 {const}
                   Sfx_GrowPowerUp .eq     %00000010 {const}
                   VictoryModeValue .eq    2      {const}
                   WaterMusic      .eq     %00000010 {const}
                   GameOverModeValue .eq   3      {const}
                   RedKoopa        .eq     $03    {const}
                   Sfx_EnemyStomp  .eq     %00000100 {const}
                   Sfx_GrowVine    .eq     %00000100 {const}
                   UndergroundMusic .eq    %00000100 {const}
                   VictoryMusic    .eq     %00000100 {const}
                   World5          .eq     4      {const}
                   HammerBro       .eq     $05    {const}
                   World6          .eq     5      {const}
                   Goomba          .eq     $06    {const}
                   World7          .eq     6      {const}
                   Bloober         .eq     $07    {const}
                   World8          .eq     7      {const}
                   BulletBill_FrenzyVar .eq $08    {const}
                   CastleMusic     .eq     %00001000 {const}
                   EndOfCastleMusic .eq    %00001000 {const}
                   Sfx_Blast       .eq     %00001000 {const}
                   Sfx_EnemySmack  .eq     %00001000 {const}
                   TallEnemy       .eq     $09    {const}
                   GreyCheepCheep  .eq     $0a    {const}
                   RedCheepCheep   .eq     $0b    {const}
                   Podoboo         .eq     $0c    {const}
                   PiranhaPlant    .eq     $0d    {const}
                   GreenParatroopaJump .eq $0e    {const}
                   CloudMusic      .eq     %00010000 {const}
                   Sfx_PipeDown_Injury .eq %00010000 {const}
                   Sfx_TimerTick   .eq     %00010000 {const}
                   Start_Button    .eq     %00010000 {const}
                   Lakitu          .eq     $11    {const}
                   Spiny           .eq     $12    {const}
                   FlyCheepCheepFrenzy .eq $14    {const}
                   FlyingCheepCheep .eq    $14    {const}
                   Fireworks       .eq     $16    {const}
                   BBill_CCheep_Frenzy .eq $17    {const}
                   Stop_Frenzy     .eq     $18    {const}
                   EndOfLevelMusic .eq     %00100000 {const}
                   PipeIntroMusic  .eq     %00100000 {const}
                   Select_Button   .eq     %00100000 {const}
                   Sfx_Fireball    .eq     %00100000 {const}
                   Sfx_PowerUpGrab .eq     %00100000 {const}
                   Bowser          .eq     $2d    {const}
                   PowerUpObject   .eq     $2e    {const}
                   VineObject      .eq     $2f    {const}
                   FlagpoleFlagObject .eq  $30    {const}
                   StarFlagObject  .eq     $31    {const}
                   JumpspringObject .eq    $32    {const}
                   BulletBill_CannonVar .eq $33    {const}
                   B_Button        .eq     %01000000 {const}
                   Sfx_ExtraLife   .eq     %01000000 {const}
                   StarPowerMusic  .eq     %01000000 {const}
                   TimeRunningOutMusic .eq %01000000 {const}
                   A_Button        .eq     %10000000 {const}
                   Sfx_BowserFall  .eq     %10000000 {const}
                   Sfx_SmallJump   .eq     %10000000 {const}
                   Silence         .eq     %10000000 {const}
                   TitleScreenDataOffset .eq $1ec0  {const}
                   ObjectOffset    .eq     $08
                   FrameCounter    .eq     $09
                   A_B_Buttons     .eq     $0a
                   Up_Down_Buttons .eq     $0b
                   Left_Right_Buttons .eq  $0c
                   PreviousA_B_Buttons .eq $0d
                   GameEngineSubroutine .eq $0e
                   Enemy_Flag      .eq     $0f    {addr/6}
                   Enemy_ID        .eq     $16    {addr/6}
                   Player_State    .eq     $1d
                   Enemy_State     .eq     $1e    {addr/6}
                   Fireball_State  .eq     $24
                   Block_State     .eq     $26
                   Misc_State      .eq     $2a
                   PlayerFacingDir .eq     $33
                   DestinationPageLoc .eq  $34                     ;2 defs for $34
                   FirebarSpinDirection .eq $34
                   VictoryWalkControl .eq  $35
                   PowerUpType     .eq     $39
                   FireballBouncingFlag .eq $3a
                   HammerBroJumpTimer .eq  $3c
                   Player_MovingDir .eq    $45
                   Enemy_MovingDir .eq     $46
                   Player_X_Speed  .eq     $57
                   SprObject_X_Speed .eq   $57
                   BlooperMoveSpeed .eq    $58                     ;11 defs for $58
                   CheepCheepMoveMFlag .eq $58
                   Enemy_X_Speed   .eq     $58
                   ExplosionGfxCounter .eq $58
                   FirebarSpinState_Low .eq $58
                   Jumpspring_FixedYPos .eq $58
                   LakituMoveSpeed .eq     $58
                   PiranhaPlant_Y_Speed .eq $58
                   RedPTroopaCenterYPos .eq $58
                   XMoveSecondaryCounter .eq $58
                   YPlatformCenterYPos .eq $58
                   Fireball_X_Speed .eq    $5e
                   Block_X_Speed   .eq     $60    {addr/3}
                   Misc_X_Speed    .eq     $64
                   Player_PageLoc  .eq     $6d                     ;2 defs for $6d
                   SprObject_PageLoc .eq   $6d
                   Enemy_PageLoc   .eq     $6e    {addr/6}
                   Fireball_PageLoc .eq    $74
                   Block_PageLoc   .eq     $76    {addr/3}
                   Misc_PageLoc    .eq     $7a
                   Bubble_PageLoc  .eq     $83
                   Player_X_Position .eq   $86                     ;2 defs for $86
                   SprObject_X_Position .eq $86
                   Enemy_X_Position .eq    $87    {addr/6}
                   Fireball_X_Position .eq $8d
                   Block_X_Position .eq    $8f    {addr/3}
                   Misc_X_Position .eq     $93
                   Bubble_X_Position .eq   $9c
                   Player_Y_Speed  .eq     $9f
                   SprObject_Y_Speed .eq   $9f
                   BlooperMoveCounter .eq  $a0                     ;7 defs for $a0
                   Enemy_Y_Speed   .eq     $a0
                   ExplosionTimerCounter .eq $a0
                   FirebarSpinState_High .eq $a0
                   LakituMoveDirection .eq $a0
                   PiranhaPlant_MoveFlag .eq $a0
                   XMovePrimaryCounter .eq $a0
                   Fireball_Y_Speed .eq    $a6
                   Block_Y_Speed   .eq     $a8    {addr/3}
                   Misc_Y_Speed    .eq     $ac
                   Player_Y_HighPos .eq    $b5                     ;2 defs for $b5
                   SprObject_Y_HighPos .eq $b5
                   Enemy_Y_HighPos .eq     $b6    {addr/6}
                   Fireball_Y_HighPos .eq  $bc
                   Block_Y_HighPos .eq     $be
                   Misc_Y_HighPos  .eq     $c2
                   Bubble_Y_HighPos .eq    $cb
                   Player_Y_Position .eq   $ce                     ;2 defs for $ce
                   SprObject_Y_Position .eq $ce
                   Enemy_Y_Position .eq    $cf    {addr/6}
                   Fireball_Y_Position .eq $d5
                   Block_Y_Position .eq    $d7    {addr/3}
                   Misc_Y_Position .eq     $db
                   Bubble_Y_Position .eq   $e4
                   AreaData        .eq     $e7    {addr/2}
                   EnemyData       .eq     $e9    {addr/2}
                   NoteLenLookupTblOfs .eq $f0
                   Square1SoundBuffer .eq  $f1
                   Square2SoundBuffer .eq  $f2
                   NoiseSoundBuffer .eq    $f3
                   AreaMusicBuffer .eq     $f4
                   MusicData       .eq     $f5    {addr/2}
                   MusicOffset_Square2 .eq $f7
                   MusicOffset_Square1 .eq $f8
                   MusicOffset_Triangle .eq $f9
                   PauseSoundQueue .eq     $fa
                   AreaMusicQueue  .eq     $fb
                   EventMusicQueue .eq     $fc
                   NoiseSoundQueue .eq     $fd
                   Square2SoundQueue .eq   $fe
                   Square1SoundQueue .eq   $ff
                   VerticalFlipFlag .eq    $0109
                   FlagpoleFNum_Y_Pos .eq  $010d
                   FlagpoleFNum_YMFDummy .eq $010e
                   FlagpoleScore   .eq     $010f
                   FloateyNum_Control .eq  $0110
                   FloateyNum_X_Pos .eq    $0117
                   FloateyNum_Y_Pos .eq    $011e
                   ShellChainCounter .eq   $0125
                   FloateyNum_Timer .eq    $012c
                   DigitModifier   .eq     $0134  {addr/6}
                   Sprite_Data     .eq     $0200  {addr/32}
                   Sprite_Y_Position .eq   $0200
                   Sprite_Tilenumber .eq   $0201
                   Sprite_Attributes .eq   $0202
                   Sprite_X_Position .eq   $0203  {addr/5}
                   VRAM_Buffer1_Offset .eq $0300
                   VRAM_Buffer1    .eq     $0301  {addr/63}
                   VRAM_Buffer2_Offset .eq $0340
                   VRAM_Buffer2    .eq     $0341  {addr/63}
                   BowserBodyControls .eq  $0363
                   BowserFeetCounter .eq   $0364
                   BowserMovementSpeed .eq $0365
                   BowserOrigXPos  .eq     $0366
                   BowserFlameTimerCtrl .eq $0367
                   BowserFront_Offset .eq  $0368
                   BridgeCollapseOffset .eq $0369
                   BowserGfxFlag   .eq     $036a
                   FirebarSpinSpeed .eq    $0388
                   VineFlagOffset  .eq     $0398
                   VineHeight      .eq     $0399
                   VineObjOffset   .eq     $039a
                   VineStart_Y_Position .eq $039d
                   BalPlatformAlignment .eq $03a0
                   Platform_X_Scroll .eq   $03a1
                   HammerThrowingTimer .eq $03a2                   ;2 defs for $03a2
                   PlatformCollisionFlag .eq $03a2
                   Player_Rel_XPos .eq     $03ad                   ;2 defs for $03ad
                   SprObject_Rel_XPos .eq  $03ad
                   Enemy_Rel_XPos  .eq     $03ae
                   Fireball_Rel_XPos .eq   $03af
                   Bubble_Rel_XPos .eq     $03b0
                   Block_Rel_XPos  .eq     $03b1
                   Misc_Rel_XPos   .eq     $03b3
                   Player_Rel_YPos .eq     $03b8                   ;2 defs for $03b8
                   SprObject_Rel_YPos .eq  $03b8
                   Enemy_Rel_YPos  .eq     $03b9
                   Fireball_Rel_YPos .eq   $03ba
                   Bubble_Rel_YPos .eq     $03bb
                   Block_Rel_YPos  .eq     $03bc
                   Misc_Rel_YPos   .eq     $03be
                   Player_SprAttrib .eq    $03c4
                   Enemy_SprAttrib .eq     $03c5  {addr/6}
                   Player_OffscreenBits .eq $03d0                  ;2 defs for $03d0
                   SprObject_OffscrBits .eq $03d0
                   Enemy_OffscreenBits .eq $03d1
                   FBall_OffscreenBits .eq $03d2
                   Bubble_OffscreenBits .eq $03d3
                   Block_OffscreenBits .eq $03d4
                   Misc_OffscreenBits .eq  $03d6
                   EnemyOffscrBitsMasked .eq $03d8
                   Block_Orig_YPos .eq     $03e4
                   Block_BBuf_Low  .eq     $03e6
                   Block_Metatile  .eq     $03e8
                   Block_PageLoc2  .eq     $03ea
                   Block_RepFlag   .eq     $03ec
                   SprDataOffset_Ctrl .eq  $03ee
                   Block_ResidualCounter .eq $03f0
                   Block_Orig_XPos .eq     $03f1
                   AttributeBuffer .eq     $03f9
                   SprObject_X_MoveForce .eq $0400
                   Enemy_X_MoveForce .eq   $0401                   ;3 defs for $0401
                   RedPTroopaOrigXPos .eq  $0401
                   YPlatformTopYPos .eq    $0401
                   Player_YMF_Dummy .eq    $0416
                   SprObject_YMF_Dummy .eq $0416
                   BowserFlamePRandomOfs .eq $0417                 ;3 defs for $0417
                   Enemy_YMF_Dummy .eq     $0417
                   PiranhaPlantUpYPos .eq  $0417
                   Bubble_YMF_Dummy .eq    $042c
                   Player_Y_MoveForce .eq  $0433
                   SprObject_Y_MoveForce .eq $0433
                   CheepCheepOrigYPos .eq  $0434                   ;3 defs for $434
                   Enemy_Y_MoveForce .eq   $0434
                   PiranhaPlantDownYPos .eq $0434
                   Block_Y_MoveForce .eq   $043c  {addr/3}
                   MaximumLeftSpeed .eq    $0450
                   MaximumRightSpeed .eq   $0456
                   Cannon_Offset   .eq     $046a
                   Whirlpool_Offset .eq    $046a
                   Cannon_PageLoc  .eq     $046b                   ;2 defs for $046b
                   Whirlpool_PageLoc .eq   $046b
                   Cannon_X_Position .eq   $0471                   ;2 defs for $0471
                   Whirlpool_LeftExtent .eq $0471
                   Cannon_Y_Position .eq   $0477                   ;2 defs for $0477
                   Whirlpool_Length .eq    $0477
                   Cannon_Timer    .eq     $047d                   ;2 defs for $047d
                   Whirlpool_Flag  .eq     $047d
                   BowserHitPoints .eq     $0483
                   StompChainCounter .eq   $0484
                   Player_CollisionBits .eq $0490
                   Enemy_CollisionBits .eq $0491
                   Player_BoundBoxCtrl .eq $0499                   ;2 defs for $0499
                   SprObj_BoundBoxCtrl .eq $0499
                   Enemy_BoundBoxCtrl .eq  $049a  {addr/6}
                   Fireball_BoundBoxCtrl .eq $04a0
                   Misc_BoundBoxCtrl .eq   $04a2
                   BoundingBox_UL_XPos .eq $04ac
                   BoundingBox_UL_YPos .eq $04ad
                   BoundingBox_DR_XPos .eq $04ae
                   BoundingBox_DR_YPos .eq $04af
                   EnemyBoundingBoxCoord .eq $04b0  {addr/4}
                   Block_Buffer_1  .eq     $0500
                   Block_Buffer_2  .eq     $05d0
                   BlockBufferColumnPos .eq $06a0
                   MetatileBuffer  .eq     $06a1  {addr/11}
                   HammerEnemyOffset .eq   $06ae
                   JumpCoinMiscOffset .eq  $06b7
                   BrickCoinTimerFlag .eq  $06bc
                   Misc_Collision_Flag .eq $06be
                   unused_06c9     .eq     $06c9
                   EnemyFrenzyBuffer .eq   $06cb
                   SecondaryHardMode .eq   $06cc
                   EnemyFrenzyQueue .eq    $06cd
                   FireballCounter .eq     $06ce
                   DuplicateObj_Offset .eq $06cf
                   LakituReappearTimer .eq $06d1
                   NumberofGroupEnemies .eq $06d3
                   ColorRotateOffset .eq   $06d4
                   PlayerGfxOffset .eq     $06d5
                   WarpZoneControl .eq     $06d6
                   FireworksCounter .eq    $06d7
                   MultiLoopCorrectCntr .eq $06d9
                   MultiLoopPassCntr .eq   $06da
                   JumpspringForce .eq     $06db
                   MaxRangeFromOrigin .eq  $06dc
                   BitMFilter      .eq     $06dd
                   ChangeAreaTimer .eq     $06de
                   SprShuffleAmtOffset .eq $06e0
                   SprShuffleAmt   .eq     $06e1  {addr/3}
                   SprDataOffset   .eq     $06e4  {addr/15}
                   Enemy_SprDataOffset .eq $06e5
                   Alt_SprDataOffset .eq   $06ec                   ;2 defs for $06ec
                   Block_SprDataOffset .eq $06ec
                   Bubble_SprDataOffset .eq $06ee
                   FBall_SprDataOffset .eq $06f1
                   Misc_SprDataOffset .eq  $06f3
                   SavedJoypad1Bits .eq    $06fc
                   SavedJoypad2Bits .eq    $06fd
                   Player_X_Scroll .eq     $06ff
                   Player_XSpeedAbsolute .eq $0700
                   FrictionAdderHigh .eq   $0701
                   FrictionAdderLow .eq    $0702
                   RunningSpeed    .eq     $0703
                   SwimmingFlag    .eq     $0704
                   Player_X_MoveForce .eq  $0705
                   DiffToHaltJump  .eq     $0706
                   JumpOrigin_Y_HighPos .eq $0707
                   JumpOrigin_Y_Position .eq $0708
                   VerticalForce   .eq     $0709
                   VerticalForceDown .eq   $070a
                   PlayerChangeSizeFlag .eq $070b
                   PlayerAnimTimerSet .eq  $070c
                   PlayerAnimCtrl  .eq     $070d
                   JumpspringAnimCtrl .eq  $070e
                   FlagpoleCollisionYPos .eq $070f
                   PlayerEntranceCtrl .eq  $0710
                   FireballThrowingTimer .eq $0711
                   DeathMusicLoaded .eq    $0712
                   FlagpoleSoundQueue .eq  $0713
                   CrouchingFlag   .eq     $0714
                   GameTimerSetting .eq    $0715
                   DisableCollisionDet .eq $0716
                   DemoAction      .eq     $0717
                   DemoActionTimer .eq     $0718
                   PrimaryMsgCounter .eq   $0719
                   ScreenLeft_PageLoc .eq  $071a
                   ScreenRight_PageLoc .eq $071b
                   ScreenLeft_X_Pos .eq    $071c
                   ScreenRight_X_Pos .eq   $071d
                   ColumnSets      .eq     $071e
                   AreaParserTaskNum .eq   $071f
                   CurrentNTAddr_High .eq  $0720
                   CurrentNTAddr_Low .eq   $0721
                   Sprite0HitDetectFlag .eq $0722
                   ScrollLock      .eq     $0723
                   CurrentPageLoc  .eq     $0725
                   CurrentColumnPos .eq    $0726
                   TerrainControl  .eq     $0727
                   BackloadingFlag .eq     $0728
                   BehindAreaParserFlag .eq $0729
                   AreaObjectPageLoc .eq   $072a
                   AreaObjectPageSel .eq   $072b
                   AreaDataOffset  .eq     $072c
                   AreaObjOffsetBuffer .eq $072d
                   AreaObjectLength .eq    $0730  {addr/3}
                   AreaStyle       .eq     $0733
                   StaircaseControl .eq    $0734
                   AreaObjectHeight .eq    $0735
                   MushroomLedgeHalfLen .eq $0736
                   EnemyDataOffset .eq     $0739
                   EnemyObjectPageLoc .eq  $073a
                   EnemyObjectPageSel .eq  $073b
                   ScreenRoutineTask .eq   $073c
                   ScrollThirtyTwo .eq     $073d
                   HorizontalScroll .eq    $073f
                   VerticalScroll  .eq     $0740
                   ForegroundScenery .eq   $0741
                   BackgroundScenery .eq   $0742
                   CloudTypeOverride .eq   $0743
                   BackgroundColorCtrl .eq $0744
                   LoopCommand     .eq     $0745
                   StarFlagTaskControl .eq $0746
                   TimerControl    .eq     $0747
                   CoinTallyFor1Ups .eq    $0748
                   SecondaryMsgCounter .eq $0749
                   JoypadBitMask   .eq     $074a
                   AreaType        .eq     $074e
                   AreaAddrsLOffset .eq    $074f
                   AreaPointer     .eq     $0750
                   EntrancePage    .eq     $0751
                   AltEntranceControl .eq  $0752
                   CurrentPlayer   .eq     $0753
                   PlayerSize      .eq     $0754
                   Player_Pos_ForScroll .eq $0755
                   PlayerStatus    .eq     $0756
                   FetchNewGameTimerFlag .eq $0757
                   JoypadOverride  .eq     $0758
                   GameTimerExpiredFlag .eq $0759
                   OnscreenPlayerInfo .eq  $075a  {addr/7}
                   NumberOfLives   .eq     $075a                   ;used by current player
                   HalfwayPage     .eq     $075b
                   LevelNumber     .eq     $075c                   ;the actual dash number
                   Hidden1UpFlag   .eq     $075d
                   CoinTally       .eq     $075e
                   WorldNumber     .eq     $075f
                   AreaNumber      .eq     $0760                   ;internal number used to find areas
                   OffscreenPlayerInfo .eq $0761  {addr/7}
                   OffScr_NumberofLives .eq $0761                  ;used by offscreen player
                   OffScr_Hidden1UpFlag .eq $0764
                   OffScr_WorldNumber .eq  $0766
                   OffScr_AreaNumber .eq   $0767
                   ScrollFractional .eq    $0768
                   DisableIntermediate .eq $0769
                   PrimaryHardMode .eq     $076a
                   WorldSelectNumber .eq   $076b
                   OperMode        .eq     $0770
                   OperMode_Task   .eq     $0772
                   VRAM_Buffer_AddrCtrl .eq $0773
                   DisableScreenFlag .eq   $0774
                   ScrollAmount    .eq     $0775
                   GamePauseStatus .eq     $0776
                   GamePauseTimer  .eq     $0777
                   Mirror_PPU_CTRL_REG1 .eq $0778
                   Mirror_PPU_CTRL_REG2 .eq $0779
                   NumberOfPlayers .eq     $077a
                   IntervalTimerControl .eq $077f
                   Timers          .eq     $0780  {addr/36}
                   SelectTimer     .eq     $0780
                   PlayerAnimTimer .eq     $0781
                   JumpSwimTimer   .eq     $0782
                   RunningTimer    .eq     $0783
                   BlockBounceTimer .eq    $0784
                   SideCollisionTimer .eq  $0785
                   JumpspringTimer .eq     $0786
                   GameTimerCtrlTimer .eq  $0787
                   ClimbSlideTimer .eq     $0789
                   EnemyFrameTimer .eq     $078a
                   FrenzyEnemyTimer .eq    $078f
                   BowserFireBreathTimer .eq $0790
                   StompTimer      .eq     $0791
                   AirBubbleTimer  .eq     $0792
                   ScrollIntervalTimer .eq $0795
                   EnemyIntervalTimer .eq  $0796
                   BrickCoinTimer  .eq     $079d
                   InjuryTimer     .eq     $079e
                   StarInvincibleTimer .eq $079f
                   ScreenTimer     .eq     $07a0
                   WorldEndTimer   .eq     $07a1
                   DemoTimer       .eq     $07a2
                   PseudoRandomBitReg .eq  $07a7  {addr/3}
                   SoundMemory     .eq     $07b0  {addr/32}
                   MusicOffset_Noise .eq   $07b0
                   EventMusicBuffer .eq    $07b1
                   PauseSoundBuffer .eq    $07b2
                   Squ2_NoteLenBuffer .eq  $07b3
                   Squ2_NoteLenCounter .eq $07b4
                   Squ2_EnvelopeDataCtrl .eq $07b5
                   Squ1_NoteLenCounter .eq $07b6
                   Squ1_EnvelopeDataCtrl .eq $07b7
                   Tri_NoteLenBuffer .eq   $07b8
                   Tri_NoteLenCounter .eq  $07b9
                   Noise_BeatLenCounter .eq $07ba
                   Squ1_SfxLenCounter .eq  $07bb
                   Squ2_SfxLenCounter .eq  $07bd
                   Sfx_SecondaryCounter .eq $07be
                   Noise_SfxLenCounter .eq $07bf
                   DAC_Counter     .eq     $07c0
                   NoiseDataLoopbackOfs .eq $07c1
                   NoteLengthTblAdder .eq  $07c4
                   AreaMusicBuffer_Alt .eq $07c5
                   PauseModeFlag   .eq     $07c6
                   GroundMusicHeaderOfs .eq $07c7
                   AltRegContentFlag .eq   $07ca
                   WarmBootOffset  .eq     $07d6
                   TopScoreDisplay .eq     $07d7  {addr/6}
                   ScoreAndCoinDisplay .eq $07dd
                   GameTimerDisplay .eq    $07f8  {addr/3}
                   WorldSelectEnableFlag .eq $07fc
                   ContinueWorld   .eq     $07fd
                   ColdBootOffset  .eq     $07fe
                   WarmBootValidation .eq  $07ff
                   PPUCTRL         .eq     $2000                   ;W VPHB SINN  various
                   PPUMASK         .eq     $2001                   ;W BGRs bMmG  various
                   PPUSTATUS       .eq     $2002                   ;R VSO- ----  various; read resets $2005/2006
                   OAMADDR         .eq     $2003                   ;W OAM read/write address
                   PPUSCROLL       .eq     $2005                   ;WW fine scroll position (two writes: X,Y)
                   PPUADDR         .eq     $2006                   ;WW PPU read/write address (two writes: MSB, LSB)
                   PPUDATA         .eq     $2007                   ;RW PPU data read/write
                   SQ1_VOL         .eq     $4000                   ;DDLC VVVV
                   SQ1_SWEEP       .eq     $4001                   ;EPPP NSSS
                   SQ1_LO          .eq     $4002                   ;TTTT TTTT
                   SQ1_HI          .eq     $4003                   ;LLLL LTTT
                   SQ2_VOL         .eq     $4004                   ;DDLC VVVV
                   SQ2_SWEEP       .eq     $4005                   ;EPPP NSSS
                   SQ2_LO          .eq     $4006                   ;TTTT TTTT
                   TRI_LINEAR      .eq     $4008                   ;CRRR RRRR
                   NOISE_VOL       .eq     $400c                   ;--LC VVVV
                   NOISE_LO        .eq     $400e                   ;L--- PPPP
                   NOISE_HI        .eq     $400f                   ;LLLL L---
                   DMC_RAW         .eq     $4011                   ;-DDD DDDD
                   OAMDMA          .eq     $4014                   ;AAAA AAAA  OAM DMA high address
                   SND_CHN         .eq     $4015                   ;W:---D NT21 R:IF-D NT21
                   JOY1            .eq     $4016                   ;joystick 1 data (R) and joystick strobe (W)
                   JOY2            .eq     $4017                   ;joystick 2 data (R) and frame counter (W)

                   ; 
                   ; iNES file header, for use by emulators.
                   ; (See https://wiki.nesdev.com/w/index.php/INES )
                   ; 
                                   .addrs  NA
0000: 4e 45 53                     .str    β€˜NES’
0003: 1a                           .dd1    $1a                     ;Ctrl+Z
0004: 02                           .dd1    $02                     ;PRG ROM is 2 x 16KB
0005: 01                           .dd1    $01                     ;CHR ROM is 1 x 8KB
0006: 01                           .dd1    %00000001               ;flags 6
0007: 00                           .dd1    %00000000               ;flags 7
0008: 00                           .dd1    %00000000               ;flags 8
0009: 00                           .dd1    %00000000               ;flags 9
000a: 00                           .dd1    %00000000               ;flags 10
000b: 00 00 00 00+                 .bulk   $00,$00,$00,$00,$00     ;padding
                                   .adrend ↑ NA

                   ; 
                   ; Start of main program.
                   ; 
                   ; The RESET vector points here.
                   ; 
                                   .addrs  $8000
8000: 78           Start           sei                             ;pretty standard 6502 type init here
8001: d8                           cld
8002: a9 10                        lda     #%00010000              ;init PPU control register 1
8004: 8d 00 20                     sta     PPUCTRL
8007: a2 ff                        ldx     #$ff                    ;reset stack pointer
8009: 9a                           txs
800a: ad 02 20     VBlank1         lda     PPUSTATUS               ;wait two frames
800d: 10 fb                        bpl     VBlank1
800f: ad 02 20     VBlank2         lda     PPUSTATUS
8012: 10 fb                        bpl     VBlank2
8014: a0 fe                        ldy     #<ColdBootOffset        ;load default cold boot pointer
8016: a2 05                        ldx     #$05                    ;this is where we check for a warm boot
8018: bd d7 07     WBootCheck      lda     TopScoreDisplay,x       ;check each score digit in the top score
801b: c9 0a                        cmp     #10                     ;to see if we have a valid digit
801d: b0 0c                        bcs     ColdBoot                ;if not, give up and proceed with cold boot
801f: ca                           dex
8020: 10 f6                        bpl     WBootCheck
8022: ad ff 07                     lda     WarmBootValidation      ;second checkpoint, check to see if
8025: c9 a5                        cmp     #$a5                    ; another location has a specific value
8027: d0 02                        bne     ColdBoot
8029: a0 d6                        ldy     #<WarmBootOffset        ;if passed both, load warm boot pointer
802b: 20 cc 90     ColdBoot        jsr     InitializeMemory        ;clear memory using pointer in Y
802e: 8d 11 40                     sta     DMC_RAW                 ;reset delta counter load register
8031: 8d 70 07                     sta     OperMode                ;reset primary mode of operation
8034: a9 a5                        lda     #$a5                    ;set warm boot flag
8036: 8d ff 07                     sta     WarmBootValidation
8039: 8d a7 07                     sta     PseudoRandomBitReg      ;set seed for pseudorandom register
803c: a9 0f                        lda     #%00001111
803e: 8d 15 40                     sta     SND_CHN                 ;enable all sound channels except dmc
8041: a9 06                        lda     #%00000110
8043: 8d 01 20                     sta     PPUMASK                 ;turn off clipping for OAM and background
8046: 20 20 82                     jsr     MoveAllSpritesOffscreen
8049: 20 19 8e                     jsr     InitializeNameTables    ;initialize both name tables
804c: ee 74 07                     inc     DisableScreenFlag       ;set flag to disable screen output
804f: ad 78 07                     lda     Mirror_PPU_CTRL_REG1
8052: 09 80                        ora     #%10000000              ;enable NMIs
8054: 20 ed 8e                     jsr     WritePPUReg1
8057: 4c 57 80     EndlessLoop     jmp     EndlessLoop             ;endless loop, need I say more?

                   ; -----------------------------------------------------------------------------
                   ; $00 - vram buffer address table low, also used for pseudorandom bit
                   ; $01 - vram buffer address table high
                   VRAM_AddrTable_Low
805a: 01                           .dd1    <VRAM_Buffer1
805b: a4                           .dd1    <WaterPaletteData
805c: c8                           .dd1    <GroundPaletteData
805d: ec                           .dd1    <UndergroundPaletteData
805e: 10                           .dd1    <CastlePaletteData
805f: 00                           .dd1    <VRAM_Buffer1_Offset
8060: 41                           .dd1    <VRAM_Buffer2
8061: 41                           .dd1    <VRAM_Buffer2
8062: 4c                           .dd1    <BowserPaletteData
8063: 34                           .dd1    <DaySnowPaletteData
8064: 3c                           .dd1    <NightSnowPaletteData
8065: 44                           .dd1    <MushroomPaletteData
8066: 54                           .dd1    <MarioThanksMessage
8067: 68                           .dd1    <LuigiThanksMessage
8068: 7c                           .dd1    <MushroomRetainerSaved
8069: a8                           .dd1    <PrincessSaved1
806a: bf                           .dd1    <PrincessSaved2
806b: de                           .dd1    <WorldSelectMessage1
806c: ef                           .dd1    <WorldSelectMessage2
                   VRAM_AddrTable_High
806d: 03                           .dd1    >VRAM_Buffer1
806e: 8c                           .dd1    >WaterPaletteData
806f: 8c                           .dd1    >GroundPaletteData
8070: 8c                           .dd1    >UndergroundPaletteData
8071: 8d                           .dd1    >CastlePaletteData
8072: 03                           .dd1    >VRAM_Buffer1_Offset
8073: 03                           .dd1    >VRAM_Buffer2
8074: 03                           .dd1    >VRAM_Buffer2
8075: 8d                           .dd1    >BowserPaletteData
8076: 8d                           .dd1    >DaySnowPaletteData
8077: 8d                           .dd1    >NightSnowPaletteData
8078: 8d                           .dd1    >MushroomPaletteData
8079: 8d                           .dd1    >MarioThanksMessage
807a: 8d                           .dd1    >LuigiThanksMessage
807b: 8d                           .dd1    >MushroomRetainerSaved
807c: 8d                           .dd1    >PrincessSaved1
807d: 8d                           .dd1    >PrincessSaved2
807e: 8d                           .dd1    >WorldSelectMessage1
807f: 8d                           .dd1    >WorldSelectMessage2
                   VRAM_Buffer_Offset
8080: 00                           .dd1    <VRAM_Buffer1_Offset
8081: 40                           .dd1    <VRAM_Buffer2_Offset

                   NonMaskableInterrupt
8082: ad 78 07                     lda     Mirror_PPU_CTRL_REG1    ;disable NMIs in mirror reg
8085: 29 7f                        and     #%01111111              ;save all other bits
8087: 8d 78 07                     sta     Mirror_PPU_CTRL_REG1
808a: 29 7e                        and     #%01111110              ;alter name table address to be $2800
808c: 8d 00 20                     sta     PPUCTRL                 ;(essentially $2000) but save other bits
808f: ad 79 07                     lda     Mirror_PPU_CTRL_REG2    ;disable OAM and background display by default
8092: 29 e6                        and     #%11100110
8094: ac 74 07                     ldy     DisableScreenFlag       ;get screen disable flag
8097: d0 05                        bne     ScreenOff               ;if set, used bits as-is
8099: ad 79 07                     lda     Mirror_PPU_CTRL_REG2    ;otherwise reenable bits and save them
809c: 09 1e                        ora     #%00011110
809e: 8d 79 07     ScreenOff       sta     Mirror_PPU_CTRL_REG2    ;save bits for later but not in register at the moment
80a1: 29 e7                        and     #%11100111              ;disable screen for now
80a3: 8d 01 20                     sta     PPUMASK
80a6: ae 02 20                     ldx     PPUSTATUS               ;reset flip-flop and reset scroll registers to zero
80a9: a9 00                        lda     #$00
80ab: 20 e6 8e                     jsr     InitScroll
80ae: 8d 03 20                     sta     OAMADDR                 ;reset spr-ram address register
80b1: a9 02                        lda     #$02                    ;perform spr-ram DMA access on $0200-$02ff
80b3: 8d 14 40                     sta     OAMDMA
80b6: ae 73 07                     ldx     VRAM_Buffer_AddrCtrl    ;load control for pointer to buffer contents
80b9: bd 5a 80                     lda     VRAM_AddrTable_Low,x    ;set indirect at $00 to pointer
80bc: 85 00                        sta     $00
80be: bd 6d 80                     lda     VRAM_AddrTable_High,x
80c1: 85 01                        sta     $01
80c3: 20 dd 8e                     jsr     UpdateScreen            ;update screen with buffer contents
80c6: a0 00                        ldy     #$00
80c8: ae 73 07                     ldx     VRAM_Buffer_AddrCtrl    ;check for usage of $0341
80cb: e0 06                        cpx     #$06
80cd: d0 01                        bne     InitBuffer
80cf: c8                           iny                             ;get offset based on usage
80d0: be 80 80     InitBuffer      ldx     VRAM_Buffer_Offset,y
80d3: a9 00                        lda     #$00                    ;clear buffer header at last location
80d5: 9d 00 03                     sta     VRAM_Buffer1_Offset,x
80d8: 9d 01 03                     sta     VRAM_Buffer1,x
80db: 8d 73 07                     sta     VRAM_Buffer_AddrCtrl    ;reinit address control to $0301
80de: ad 79 07                     lda     Mirror_PPU_CTRL_REG2    ;copy mirror of $2001 to register
80e1: 8d 01 20                     sta     PPUMASK
80e4: 20 d0 f2                     jsr     SoundEngine             ;play sound
80e7: 20 5c 8e                     jsr     ReadJoypads             ;read joypads
80ea: 20 82 81                     jsr     PauseRoutine            ;handle pause
80ed: 20 97 8f                     jsr     UpdateTopScore
80f0: ad 76 07                     lda     GamePauseStatus         ;check for pause status
80f3: 4a                           lsr     A
80f4: b0 25                        bcs     PauseSkip
80f6: ad 47 07                     lda     TimerControl            ;if master timer control not set, decrement
80f9: f0 05                        beq     DecTimers               ;all frame and interval timers
80fb: ce 47 07                     dec     TimerControl
80fe: d0 19                        bne     NoDecTimers
8100: a2 14        DecTimers       ldx     #$14                    ;load end offset for end of frame timers
8102: ce 7f 07                     dec     IntervalTimerControl    ;decrement interval timer control,
8105: 10 07                        bpl     DecTimersLoop           ; if not expired, only frame timers will decrement
8107: a9 14                        lda     #$14
8109: 8d 7f 07                     sta     IntervalTimerControl    ;if control for interval timers expired,
810c: a2 23                        ldx     #$23                    ; interval timers will decrement along with frame timers
810e: bd 80 07     DecTimersLoop   lda     SelectTimer,x           ;check current timer
8111: f0 03                        beq     SkipExpTimer            ;if current timer expired, branch to skip,
8113: de 80 07                     dec     SelectTimer,x           ; otherwise decrement the current timer
8116: ca           SkipExpTimer    dex                             ;move onto next timer
8117: 10 f5                        bpl     DecTimersLoop           ;do this until all timers are dealt with
8119: e6 09        NoDecTimers     inc     FrameCounter            ;increment frame counter
811b: a2 00        PauseSkip       ldx     #$00
811d: a0 07                        ldy     #$07
811f: ad a7 07                     lda     PseudoRandomBitReg      ;get first memory locaion of LSFR bytes
8122: 29 02                        and     #%00000010              ;mask out all but d1
8124: 85 00                        sta     $00                     ;save here
8126: ad a8 07                     lda     PseudoRandomBitReg+1    ;get second memory location
8129: 29 02                        and     #%00000010              ;mask out all but d1
812b: 45 00                        eor     $00                     ;perform exclusive-OR on d1 from first and second bytes
812d: 18                           clc                             ;if neither or both are set, carry will be clear
812e: f0 01                        beq     RotPRandomBit
8130: 38                           sec                             ;if one or the other is set, carry will be set
8131: 7e a7 07     RotPRandomBit   ror     PseudoRandomBitReg,x    ;rotate carry into d7, and rotate last bit into carry
8134: e8                           inx                             ;increment to next byte
8135: 88                           dey                             ;decrement for loop
8136: d0 f9                        bne     RotPRandomBit
8138: ad 22 07                     lda     Sprite0HitDetectFlag    ;check for flag here
813b: f0 1f                        beq     SkipSprite0
813d: ad 02 20     Sprite0Clr      lda     PPUSTATUS               ;wait for sprite 0 flag to clear, which will
8140: 29 40                        and     #%01000000              ; not happen until vblank has ended
8142: d0 f9                        bne     Sprite0Clr
8144: ad 76 07                     lda     GamePauseStatus         ;if in pause mode, do not bother with sprites at all
8147: 4a                           lsr     A
8148: b0 06                        bcs     Sprite0Hit
814a: 20 23 82                     jsr     MoveSpritesOffscreen
814d: 20 c6 81                     jsr     SpriteShuffler
8150: ad 02 20     Sprite0Hit      lda     PPUSTATUS               ;do sprite #0 hit detection
8153: 29 40                        and     #%01000000
8155: f0 f9                        beq     Sprite0Hit
8157: a0 14                        ldy     #$14                    ;small delay, to wait until we hit orizontal blank time
8159: 88           HBlankDelay     dey
815a: d0 fd                        bne     HBlankDelay
815c: ad 3f 07     SkipSprite0     lda     HorizontalScroll        ;set scroll registers from variables
815f: 8d 05 20                     sta     PPUSCROLL
8162: ad 40 07                     lda     VerticalScroll
8165: 8d 05 20                     sta     PPUSCROLL
8168: ad 78 07                     lda     Mirror_PPU_CTRL_REG1    ;load saved mirror of $2000
816b: 48                           pha
816c: 8d 00 20                     sta     PPUCTRL
816f: ad 76 07                     lda     GamePauseStatus         ;if in pause mode, do not perform operation mode stuff
8172: 4a                           lsr     A
8173: b0 03                        bcs     SkipMainOper
8175: 20 12 82                     jsr     OperModeExecutionTree   ;otherwise do one of many, many possible subroutines
8178: ad 02 20     SkipMainOper    lda     PPUSTATUS               ;reset flip-flip
817b: 68                           pla
817c: 09 80                        ora     #%10000000              ;reactivate NMIs
817e: 8d 00 20                     sta     PPUCTRL
8181: 40                           rti                             ;we are done until the next frame!

                   ; -----------------------------------------------------------------------------
8182: ad 70 07     PauseRoutine    lda     OperMode                ;are we in victory mode?
8185: c9 02                        cmp     #VictoryModeValue       ;if so, go ahead
8187: f0 0b                        beq     ChkPauseTimer
8189: c9 01                        cmp     #GameModeValue          ;are we in game mode?
818b: d0 38                        bne     ExitPause               ;if not, leave
818d: ad 72 07                     lda     OperMode_Task           ;if we are in game mode, are we running game engine?
8190: c9 03                        cmp     #$03
8192: d0 31                        bne     ExitPause               ;if not, leave
8194: ad 77 07     ChkPauseTimer   lda     GamePauseTimer          ;check if pause timer is still counting down
8197: f0 04                        beq     ChkStart
8199: ce 77 07                     dec     GamePauseTimer          ;if so, decrement and leave
819c: 60                           rts

819d: ad fc 06     ChkStart        lda     SavedJoypad1Bits        ;check to see if start is pressed
81a0: 29 10                        and     #Start_Button           ;on controller 1
81a2: f0 19                        beq     ClrPauseTimer
81a4: ad 76 07                     lda     GamePauseStatus         ;check to see if timer flag is set
81a7: 29 80                        and     #%10000000              ;and if so, do not reset timer (residual,
81a9: d0 1a                        bne     ExitPause               ; joypad reading routine makes this unnecessary)
81ab: a9 2b                        lda     #$2b                    ;set pause timer
81ad: 8d 77 07                     sta     GamePauseTimer
81b0: ad 76 07                     lda     GamePauseStatus
81b3: a8                           tay
81b4: c8                           iny                             ;set pause sfx queue for next pause mode
81b5: 84 fa                        sty     PauseSoundQueue
81b7: 49 01                        eor     #%00000001              ;invert d0 and set d7
81b9: 09 80                        ora     #%10000000
81bb: d0 05                        bne     SetPause                ;unconditional branch

81bd: ad 76 07     ClrPauseTimer   lda     GamePauseStatus         ;clear timer flag if timer is at zero and start button
81c0: 29 7f                        and     #%01111111              ; is not pressed
81c2: 8d 76 07     SetPause        sta     GamePauseStatus
81c5: 60           ExitPause       rts

                   ; -----------------------------------------------------------------------------
                   ; $00 - used for preset value
81c6: ac 4e 07     SpriteShuffler  ldy     AreaType                ;load level type, likely residual code
81c9: a9 28                        lda     #$28                    ;load preset value which will put it at
81cb: 85 00                        sta     $00                     ; sprite #10
81cd: a2 0e                        ldx     #$0e                    ;start at the end of OAM data offsets
81cf: bd e4 06     ShuffleLoop     lda     SprDataOffset,x         ;check for offset value against
81d2: c5 00                        cmp     $00                     ; the preset value
81d4: 90 0f                        bcc     NextSprOffset           ;if less, skip this part
81d6: ac e0 06                     ldy     SprShuffleAmtOffset     ;get current offset to preset value we want to add
81d9: 18                           clc
81da: 79 e1 06                     adc     SprShuffleAmt,y         ;get shuffle amount, add to current sprite offset
81dd: 90 03                        bcc     StrSprOffset            ;if not exceeded $ff, skip second add
81df: 18                           clc
81e0: 65 00                        adc     $00                     ;otherwise add preset value $28 to offset
81e2: 9d e4 06     StrSprOffset    sta     SprDataOffset,x         ;store new offset here or old one if branched to here
81e5: ca           NextSprOffset   dex                             ;move backwards to next one
81e6: 10 e7                        bpl     ShuffleLoop
81e8: ae e0 06                     ldx     SprShuffleAmtOffset     ;load offset
81eb: e8                           inx
81ec: e0 03                        cpx     #$03                    ;check if offset + 1 goes to 3
81ee: d0 02                        bne     SetAmtOffset            ;if offset + 1 not 3, store
81f0: a2 00                        ldx     #$00                    ;otherwise, init to 0
81f2: 8e e0 06     SetAmtOffset    stx     SprShuffleAmtOffset
81f5: a2 08                        ldx     #$08                    ;load offsets for values and storage
81f7: a0 02                        ldy     #$02
81f9: b9 e9 06     SetMiscOffset   lda     SprDataOffset+5,y       ;load one of three OAM data offsets
81fc: 9d f1 06                     sta     Misc_SprDataOffset-2,x  ;store first one unmodified, but
81ff: 18                           clc                             ; add eight to the second and eight
8200: 69 08                        adc     #$08                    ; more to the third one
8202: 9d f2 06                     sta     Misc_SprDataOffset-1,x  ;note that due to the way X is set up,
8205: 18                           clc                             ; this code loads into the misc sprite offsets
8206: 69 08                        adc     #$08
8208: 9d f3 06                     sta     Misc_SprDataOffset,x
820b: ca                           dex
820c: ca                           dex
820d: ca                           dex
820e: 88                           dey
820f: 10 e8                        bpl     SetMiscOffset           ;do this until all misc spr offsets are loaded
8211: 60                           rts

                   ; -----------------------------------------------------------------------------
                   OperModeExecutionTree
8212: ad 70 07                     lda     OperMode
8215: 20 04 8e                     jsr     JumpEngine

8218: 31 82                        .dd2    TitleScreenMode
821a: dc ae                        .dd2    GameMode
821c: 8b 83                        .dd2    VictoryMode
821e: 18 92                        .dd2    GameOverMode

                   ; -----------------------------------------------------------------------------
                   MoveAllSpritesOffscreen
8220: a0 00                        ldy     #$00                    ;this routine moves all sprites off the screen
8222: 2c                           bit β–Ό   Fireball_BoundBoxCtrl   ;BIT instruction opcode
                   MoveSpritesOffscreen
8223: a0 04                        ldy     #$04                    ;this routine moves all but sprite 0
8225: a9 f8                        lda     #$f8                    ;off the screen
8227: 99 00 02     SprInitLoop     sta     Sprite_Y_Position,y     ;write 248 into OAM data's Y coordinate
822a: c8                           iny                             ;which will move it off the screen
822b: c8                           iny
822c: c8                           iny
822d: c8                           iny
822e: d0 f7                        bne     SprInitLoop
8230: 60                           rts

                   ; -----------------------------------------------------------------------------
8231: ad 72 07     TitleScreenMode lda     OperMode_Task
8234: 20 04 8e                     jsr     JumpEngine

8237: cf 8f                        .dd2    InitializeGame
8239: 67 85                        .dd2    ScreenRoutines
823b: 61 90                        .dd2    PrimaryGameSetup
823d: 45 82                        .dd2    GameMenuRoutine
                   ; -----------------------------------------------------------------------------
                   WSelectBufferTemplate
823f: 04 20 73 01+                 .bulk   $04,$20,$73,$01,$00,$00

8245: a0 00        GameMenuRoutine ldy     #$00
8247: ad fc 06                     lda     SavedJoypad1Bits        ;check to see if either player pressed
824a: 0d fd 06                     ora     SavedJoypad2Bits        ; only the start button (either joypad)
824d: c9 10                        cmp     #Start_Button
824f: f0 04                        beq     StartGame
8251: c9 90                        cmp     #$90                    ;||check to see if A + start was pressed
8253: d0 03                        bne     ChkSelect               ;if not, branch to check select button
8255: 4c d8 82     StartGame       jmp     ChkContinue             ;if either start or A + start, execute here

8258: c9 20        ChkSelect       cmp     #Select_Button          ;check to see if the select button was pressed
825a: f0 1a                        beq     SelectBLogic            ;if so, branch reset demo timer
825c: ae a2 07                     ldx     DemoTimer               ;otherwise check demo timer
825f: d0 0b                        bne     ChkWorldSel             ;if demo timer not expired, branch to check world selection
8261: 8d 80 07                     sta     SelectTimer             ;set controller bits here if running demo
8264: 20 6b 83                     jsr     DemoEngine              ;run through the demo actions
8267: b0 60                        bcs     ResetTitle              ;if carry flag set, demo over, thus branch
8269: 4c c0 82                     jmp     RunDemo                 ;otherwise, run game engine for demo

826c: ae fc 07     ChkWorldSel     ldx     WorldSelectEnableFlag   ;check to see if world selection has been enabled
826f: f0 4a                        beq     NullJoypad
8271: c9 40                        cmp     #B_Button               ;if so, check to see if the B button was pressed
8273: d0 46                        bne     NullJoypad
8275: c8                           iny                             ;if so, increment Y and execute same code as select
8276: ad a2 07     SelectBLogic    lda     DemoTimer               ;if select or B pressed, check demo timer one last time
8279: f0 4e                        beq     ResetTitle              ;if demo timer expired, branch to reset title screen mode
827b: a9 18                        lda     #$18                    ;otherwise reset demo timer
827d: 8d a2 07                     sta     DemoTimer
8280: ad 80 07                     lda     SelectTimer             ;check select/B button timer
8283: d0 36                        bne     NullJoypad              ;if not expired, branch
8285: a9 10                        lda     #$10                    ;otherwise reset select button timer
8287: 8d 80 07                     sta     SelectTimer
828a: c0 01                        cpy     #$01                    ;was the B button pressed earlier?  if so, branch
828c: f0 0e                        beq     IncWorldSel             ;note this will not be run if world selection is disabled
828e: ad 7a 07                     lda     NumberOfPlayers         ;if no, must have been the select button, therefore
8291: 49 01                        eor     #%00000001              ; change number of players and draw icon accordingly
8293: 8d 7a 07                     sta     NumberOfPlayers
8296: 20 25 83                     jsr     DrawMushroomIcon
8299: 4c bb 82                     jmp     NullJoypad

829c: ae 6b 07     IncWorldSel     ldx     WorldSelectNumber       ;increment world select number
829f: e8                           inx
82a0: 8a                           txa
82a1: 29 07                        and     #%00000111              ;mask out higher bits
82a3: 8d 6b 07                     sta     WorldSelectNumber       ;store as current world select number
82a6: 20 0e 83                     jsr     GoContinue
82a9: bd 3f 82     UpdateShroom    lda     WSelectBufferTemplate,x ;write template for world select in vram buffer
82ac: 9d 00 03                     sta     VRAM_Buffer1-1,x        ;do this until all bytes are written
82af: e8                           inx
82b0: e0 06                        cpx     #$06
82b2: 30 f5                        bmi     UpdateShroom
82b4: ac 5f 07                     ldy     WorldNumber             ;get world number from variable and increment for
82b7: c8                           iny                             ; proper display, and put in blank byte before
82b8: 8c 04 03                     sty     VRAM_Buffer1+3          ; null terminator
82bb: a9 00        NullJoypad      lda     #$00                    ;clear joypad bits for player 1
82bd: 8d fc 06                     sta     SavedJoypad1Bits
82c0: 20 ea ae     RunDemo         jsr     GameCoreRoutine         ;run game engine
82c3: a5 0e                        lda     GameEngineSubroutine    ;check to see if we're running lose life routine
82c5: c9 06                        cmp     #$06
82c7: d0 44                        bne     ExitMenu                ;if not, do not do all the resetting below
82c9: a9 00        ResetTitle      lda     #$00                    ;reset game modes, disable
82cb: 8d 70 07                     sta     OperMode                ;sprite 0 check and disable
82ce: 8d 72 07                     sta     OperMode_Task           ;screen output
82d1: 8d 22 07                     sta     Sprite0HitDetectFlag
82d4: ee 74 07                     inc     DisableScreenFlag
82d7: 60                           rts

82d8: ac a2 07     ChkContinue     ldy     DemoTimer               ;if timer for demo has expired, reset modes
82db: f0 ec                        beq     ResetTitle
82dd: 0a                           asl     A                       ;check to see if A button was also pushed
82de: 90 06                        bcc     StartWorld1             ;if not, don't load continue function's world number
82e0: ad fd 07                     lda     ContinueWorld           ;load previously saved world number for secret
82e3: 20 0e 83                     jsr     GoContinue              ;continue function when pressing A + start
82e6: 20 03 9c     StartWorld1     jsr     LoadAreaPointer
82e9: ee 5d 07                     inc     Hidden1UpFlag           ;set 1-up box flag for both players
82ec: ee 64 07                     inc     OffScr_Hidden1UpFlag
82ef: ee 57 07                     inc     FetchNewGameTimerFlag   ;set fetch new game timer flag
82f2: ee 70 07                     inc     OperMode                ;set next game mode
82f5: ad fc 07                     lda     WorldSelectEnableFlag   ;if world select flag is on, then primary
82f8: 8d 6a 07                     sta     PrimaryHardMode         ; hard mode must be on as well
82fb: a9 00                        lda     #$00
82fd: 8d 72 07                     sta     OperMode_Task           ;set game mode here, and clear demo timer
8300: 8d a2 07                     sta     DemoTimer
8303: a2 17                        ldx     #$17
8305: a9 00                        lda     #$00
8307: 9d dd 07     InitScores      sta     ScoreAndCoinDisplay,x   ;clear player scores and coin displays
830a: ca                           dex
830b: 10 fa                        bpl     InitScores
830d: 60           ExitMenu        rts

830e: 8d 5f 07     GoContinue      sta     WorldNumber             ;start both players at the first area
8311: 8d 66 07                     sta     OffScr_WorldNumber      ; of the previously saved world number
8314: a2 00                        ldx     #$00                    ;note that on power-up using this function
8316: 8e 60 07                     stx     AreaNumber              ; will make no difference
8319: 8e 67 07                     stx     OffScr_AreaNumber
831c: 60                           rts

                   ; -----------------------------------------------------------------------------
                   MushroomIconData
831d: 07 22 49 83+                 .bulk   $07,$22,$49,$83,$ce,$24,$24,$00

                   DrawMushroomIcon
8325: a0 07                        ldy     #$07                    ;read eight bytes to be read by transfer routine
8327: b9 1d 83     IconDataRead    lda     MushroomIconData,y      ;note that the default position is set for a
832a: 99 00 03                     sta     VRAM_Buffer1-1,y        ; 1-player game
832d: 88                           dey
832e: 10 f7                        bpl     IconDataRead
8330: ad 7a 07                     lda     NumberOfPlayers         ;check number of players
8333: f0 0a                        beq     ExitIcon                ;if set to 1-player game, we're done
8335: a9 24                        lda     #$24                    ;otherwise, load blank tile in 1-player position
8337: 8d 04 03                     sta     VRAM_Buffer1+3
833a: a9 ce                        lda     #$ce                    ;then load shroom icon tile in 2-player position
833c: 8d 06 03                     sta     VRAM_Buffer1+5
833f: 60           ExitIcon        rts

                   ; -----------------------------------------------------------------------------
8340: 01 80 02 81+ DemoActionData  .bulk   $01,$80,$02,$81,$41,$80,$01,$42,$c2,$02,$80,$41,$c1,$41,$c1,$01
                                    +      $c1,$01,$02,$80,$00
8355: 9b 10 18 05+ DemoTimingData  .bulk   $9b,$10,$18,$05,$2c,$20,$24,$15,$5a,$10,$20,$28,$30,$20,$10,$80
                                    +      $20,$30,$30,$01,$ff,$00

836b: ae 17 07     DemoEngine      ldx     DemoAction              ;load current demo action
836e: ad 18 07                     lda     DemoActionTimer         ;load current action timer
8371: d0 0d                        bne     DoAction                ;if timer still counting down, skip
8373: e8                           inx
8374: ee 17 07                     inc     DemoAction              ;if expired, increment action, X, and
8377: 38                           sec                             ; set carry by default for demo over
8378: bd 54 83                     lda     DemoTimingData-1,x      ;get next timer
837b: 8d 18 07                     sta     DemoActionTimer         ;store as current timer
837e: f0 0a                        beq     DemoOver                ;if timer already at zero, skip
8380: bd 3f 83     DoAction        lda     DemoActionData-1,x      ;get and perform action (current or next)
8383: 8d fc 06                     sta     SavedJoypad1Bits
8386: ce 18 07                     dec     DemoActionTimer         ;decrement action timer
8389: 18                           clc                             ;clear carry if demo still going
838a: 60           DemoOver        rts

                   ; -----------------------------------------------------------------------------
838b: 20 a0 83     VictoryMode     jsr     VictoryModeSubroutines  ;run victory mode subroutines
838e: ad 72 07                     lda     OperMode_Task           ;get current task of victory mode
8391: f0 07                        beq     AutoPlayer              ;if on bridge collapse, skip enemy processing
8393: a2 00                        ldx     #$00
8395: 86 08                        stx     ObjectOffset            ;otherwise reset enemy object offset
8397: 20 47 c0                     jsr     EnemiesAndLoopsCore     ; and run enemy code
839a: 20 2a f1     AutoPlayer      jsr     RelativePlayerPosition  ;get player's relative coordinates
839d: 4c e9 ee                     jmp     PlayerGfxHandler        ;draw the player, then leave

                   VictoryModeSubroutines
83a0: ad 72 07                     lda     OperMode_Task
83a3: 20 04 8e                     jsr     JumpEngine

83a6: ec cf                        .dd2    BridgeCollapse
83a8: b0 83                        .dd2    SetupVictoryMode
83aa: bd 83                        .dd2    PlayerVictoryWalk
83ac: f6 83                        .dd2    PrintVictoryMessages
83ae: 61 84                        .dd2    PlayerEndWorld

                   ; -----------------------------------------------------------------------------
                   SetupVictoryMode
83b0: ae 1b 07                     ldx     ScreenRight_PageLoc     ;get page location of right side of screen
83b3: e8                           inx                             ;increment to next page
83b4: 86 34                        stx     DestinationPageLoc      ;store here
83b6: a9 08                        lda     #EndOfCastleMusic
83b8: 85 fc                        sta     EventMusicQueue         ;play win castle music
83ba: 4c 4e 87                     jmp     IncModeTask_B           ;jump to set next major task in victory mode

                   ; -----------------------------------------------------------------------------
                   PlayerVictoryWalk
83bd: a0 00                        ldy     #$00                    ;set value here to not walk player by default
83bf: 84 35                        sty     VictoryWalkControl
83c1: a5 6d                        lda     Player_PageLoc          ;get player's page location
83c3: c5 34                        cmp     DestinationPageLoc      ;compare with destination page location
83c5: d0 06                        bne     PerformWalk             ;if page locations don't match, branch
83c7: a5 86                        lda     Player_X_Position       ;otherwise get player's horizontal position
83c9: c9 60                        cmp     #$60                    ;compare with preset horizontal position
83cb: b0 03                        bcs     DontWalk                ;if still on other page, branch ahead
83cd: e6 35        PerformWalk     inc     VictoryWalkControl      ;otherwise increment value and Y
83cf: c8                           iny                             ;note Y will be used to walk the player
83d0: 98           DontWalk        tya                             ;put contents of Y in A and
83d1: 20 e6 b0                     jsr     AutoControlPlayer       ; use A to mvoe player to the right or not
83d4: ad 1a 07                     lda     ScreenLeft_PageLoc      ;check page location of left side of screen
83d7: c5 34                        cmp     DestinationPageLoc      ;against set value here
83d9: f0 16                        beq     ExitVWalk               ;branch if equal to change modes if necessary
83db: ad 68 07                     lda     ScrollFractional
83de: 18                           clc                             ;do fixed point math on fractional part of scroll
83df: 69 80                        adc     #$80
83e1: 8d 68 07                     sta     ScrollFractional        ;save fractional movement amount
83e4: a9 01                        lda     #$01                    ;set 1 pixel per frame
83e6: 69 00                        adc     #$00                    ;add carry from previous addition
83e8: a8                           tay                             ;use as scroll amount
83e9: 20 c4 af                     jsr     ScrollScreen            ;do sub to scroll the screen
83ec: 20 6f af                     jsr     UpdScrollVar            ;do another sub to update screen and scroll variables
83ef: e6 35                        inc     VictoryWalkControl      ;increment value to stay in this routine
83f1: a5 35        ExitVWalk       lda     VictoryWalkControl      ;load value set here
83f3: f0 68                        beq     IncModeTask_A           ;if zero, branch to change modes
83f5: 60                           rts                             ;otherwise leave

                   ; -----------------------------------------------------------------------------
                   PrintVictoryMessages
83f6: ad 49 07                     lda     SecondaryMsgCounter     ;load secondary message counter
83f9: d0 48                        bne     IncMsgCounter           ;if set, branch to increment message counters
83fb: ad 19 07                     lda     PrimaryMsgCounter       ;otherwise load primary message counter
83fe: f0 18                        beq     ThankPlayer             ;if set to zero, branch to print first message
8400: c9 09                        cmp     #$09                    ;if at 9 or above, branch elsewhere (this comparison
8402: b0 3f                        bcs     IncMsgCounter           ; is residual code, counter never reaches 9)
8404: ac 5f 07                     ldy     WorldNumber             ;check world number
8407: c0 07                        cpy     #World8
8409: d0 09                        bne     MRetainerMsg            ;if not at world 8, skip to next part
840b: c9 03                        cmp     #$03                    ;check primary message counter again
840d: 90 34                        bcc     IncMsgCounter           ;if not at 3 yet (world 8 only), branch to increment
840f: e9 01                        sbc     #$01                    ;otherwise subtract one
8411: 4c 18 84                     jmp     ThankPlayer             ;and skip to next part

8414: c9 02        MRetainerMsg    cmp     #$02                    ;check primary message counter
8416: 90 2b                        bcc     IncMsgCounter           ;if not at 2 yet (world 1-7 only), branch
8418: a8           ThankPlayer     tay                             ;put primary message counter into Y
8419: d0 08                        bne     SecondPartMsg           ;if counter nonzero, skip this part, do not print first message
841b: ad 53 07                     lda     CurrentPlayer           ;otherwise get player currently on the screen
841e: f0 14                        beq     EvalForMusic            ;if mario, branch
8420: c8                           iny                             ;otherwise increment Y once for luigi and
8421: d0 11                        bne     EvalForMusic            ;do an unconditional branch to the same place
8423: c8           SecondPartMsg   iny                             ;increment Y to do world 8's message
8424: ad 5f 07                     lda     WorldNumber
8427: c9 07                        cmp     #World8                 ;check world number
8429: f0 09                        beq     EvalForMusic            ;if at world 8, branch to next part
842b: 88                           dey                             ;otherwise decrement Y for world 1-7's message
842c: c0 04                        cpy     #$04                    ;if counter at 4 (world 1-7) only
842e: b0 26                        bcs     SetEndTimer             ; branch to set victory end timer
8430: c0 03                        cpy     #$03                    ;if counter at 3 (world 1-7 only)
8432: b0 0f                        bcs     IncMsgCounter           ; branch to keep counting
8434: c0 03        EvalForMusic    cpy     #$03                    ;if counter not yet at 3 (world 8 only), branch
8436: d0 04                        bne     PrintMsg                ; to print message only (note world 1-7 will only
8438: a9 04                        lda     #VictoryMusic           ; reach this code if counter = 0, and will always branch)
843a: 85 fc                        sta     EventMusicQueue         ;otherwise load victory music first (world 8 only)
843c: 98           PrintMsg        tya                             ;put primary message counter in A
843d: 18                           clc                             ;add $0c or 12 to counter thus giving an appropriate value,
843e: 69 0c                        adc     #$0c                    ; ($0c-$0d = first), ($0e = world 1-7's), ($0f-$12 = world 8's)
8440: 8d 73 07                     sta     VRAM_Buffer_AddrCtrl    ;write message counter to vram address controller
8443: ad 49 07     IncMsgCounter   lda     SecondaryMsgCounter
8446: 18                           clc
8447: 69 04                        adc     #$04                    ;add four to secondary message counter
8449: 8d 49 07                     sta     SecondaryMsgCounter
844c: ad 19 07                     lda     PrimaryMsgCounter
844f: 69 00                        adc     #$00                    ;add carry to primary message counter
8451: 8d 19 07                     sta     PrimaryMsgCounter
8454: c9 07                        cmp     #$07                    ;check primary counter one more time
8456: 90 08        SetEndTimer     bcc     ExitMsgs                ;if not reached value yet, branch to leave
8458: a9 06                        lda     #$06
845a: 8d a1 07                     sta     WorldEndTimer           ;otherwise set world end timer
845d: ee 72 07     IncModeTask_A   inc     OperMode_Task           ;move onto next task in mode
8460: 60           ExitMsgs        rts                             ;leave

                   ; -----------------------------------------------------------------------------
8461: ad a1 07     PlayerEndWorld  lda     WorldEndTimer           ;check to see if world end timer expired
8464: d0 20                        bne     EndExitOne              ;branch to leave if not
8466: ac 5f 07                     ldy     WorldNumber             ;check world number
8469: c0 07                        cpy     #World8                 ;if on world 8, player is done with game,
846b: b0 1a                        bcs     EndChkBButton           ; thus branch to read controller
846d: a9 00                        lda     #$00
846f: 8d 60 07                     sta     AreaNumber              ;otherwise initialize area number used as offset
8472: 8d 5c 07                     sta     LevelNumber             ; and level number control to start at area 1
8475: 8d 72 07                     sta     OperMode_Task           ;initialize secondary mode of operation
8478: ee 5f 07                     inc     WorldNumber             ;increment world number to move onto the next world
847b: 20 03 9c                     jsr     LoadAreaPointer         ;get area address offset for the next area
847e: ee 57 07                     inc     FetchNewGameTimerFlag   ;set flag to load game timer from header
8481: a9 01                        lda     #GameModeValue
8483: 8d 70 07                     sta     OperMode                ;set mode of operation to game mode
8486: 60           EndExitOne      rts                             ;and leave

8487: ad fc 06     EndChkBButton   lda     SavedJoypad1Bits
848a: 0d fd 06                     ora     SavedJoypad2Bits        ;check to see if B button was pressed on
848d: 29 40                        and     #B_Button               ; either controller
848f: f0 0d                        beq     EndExitTwo              ;branch to leave if not
8491: a9 01                        lda     #$01                    ;otherwise set world selection flag
8493: 8d fc 07                     sta     WorldSelectEnableFlag
8496: a9 ff                        lda     #$ff                    ;remove onscreen player's lives
8498: 8d 5a 07                     sta     NumberOfLives
849b: 20 48 92                     jsr     TerminateGame           ;do sub to continue other player or end game
849e: 60           EndExitTwo      rts                             ;leave

                   ; -----------------------------------------------------------------------------
                   ; 
                   ; Data is used as tiles for numbers that appear when you defeat enemies.
                   FloateyNumTileData
849f: ff ff                        .bulk   $ff,$ff                 ;dummy
84a1: f6 fb                        .bulk   $f6,$fb                 ;"100"
84a3: f7 fb                        .bulk   $f7,$fb                 ;"200"
84a5: f8 fb                        .bulk   $f8,$fb                 ;"400"
84a7: f9 fb                        .bulk   $f9,$fb                 ;"500"
84a9: fa fb                        .bulk   $fa,$fb                 ;"800"
84ab: f6 50                        .bulk   $f6,$50                 ;"1000"
84ad: f7 50                        .bulk   $f7,$50                 ;"2000"
84af: f8 50                        .bulk   $f8,$50                 ;"4000"
84b1: f9 50                        .bulk   $f9,$50                 ;"5000"
84b3: fa 50                        .bulk   $fa,$50                 ;"8000"
84b5: fd fe                        .bulk   $fd,$fe                 ;"1-UP"
                   ; 
                   ; High nybble is digit number, low nybble is number to add to the digit of the
                   ; player's score.
84b7: ff           ScoreUpdateData .dd1    $ff                     ;dummy
84b8: 41 42 44 45+                 .bulk   $41,$42,$44,$45,$48,$31,$32,$34,$35,$38,$00

                   FloateyNumbersRoutine
84c3: bd 10 01                     lda     FloateyNum_Control,x    ;load control for floatey number
84c6: f0 be                        beq     EndExitOne              ;if zero, branch to leave
84c8: c9 0b                        cmp     #$0b                    ;if less than $0b, branch
84ca: 90 05                        bcc     ChkNumTimer
84cc: a9 0b                        lda     #$0b                    ;otherwise set to $0b, thus keeping
84ce: 9d 10 01                     sta     FloateyNum_Control,x    ; it in range
84d1: a8           ChkNumTimer     tay                             ;use as Y
84d2: bd 2c 01                     lda     FloateyNum_Timer,x      ;check value here
84d5: d0 04                        bne     DecNumTimer             ;if nonzero, branch ahead
84d7: 9d 10 01                     sta     FloateyNum_Control,x    ;initialize floatey number control and leave
84da: 60                           rts

84db: de 2c 01     DecNumTimer     dec     FloateyNum_Timer,x      ;decrement value here
84de: c9 2b                        cmp     #$2b                    ;if not reached a certain point, branch
84e0: d0 1e                        bne     ChkTallEnemy
84e2: c0 0b                        cpy     #$0b                    ;check offset for $0b
84e4: d0 07                        bne     LoadNumTiles            ;branch ahead if not found
84e6: ee 5a 07                     inc     NumberOfLives           ;give player one extra life (1-up)
84e9: a9 40                        lda     #Sfx_ExtraLife
84eb: 85 fe                        sta     Square2SoundQueue       ;and play the 1-up sound
84ed: b9 b7 84     LoadNumTiles    lda     ScoreUpdateData,y       ;load point value here
84f0: 4a                           lsr     A                       ;move high nybble to low
84f1: 4a                           lsr     A
84f2: 4a                           lsr     A
84f3: 4a                           lsr     A
84f4: aa                           tax                             ;use as X offset, essentially the digit
84f5: b9 b7 84                     lda     ScoreUpdateData,y       ;load again and this time
84f8: 29 0f                        and     #%00001111              ;mask out the high nybble
84fa: 9d 34 01                     sta     DigitModifier,x         ;store as amount to add to the digit
84fd: 20 27 bc                     jsr     AddToScore              ;update the score accordingly
8500: bc e5 06     ChkTallEnemy    ldy     Enemy_SprDataOffset,x   ;get OAM data offset for enemy object
8503: b5 16                        lda     Enemy_ID,x              ;get enemy object identifier
8505: c9 12                        cmp     #Spiny
8507: f0 22                        beq     FloateyPart             ;branch if spiny
8509: c9 0d                        cmp     #PiranhaPlant
850b: f0 1e                        beq     FloateyPart             ;branch if piranha plant
850d: c9 05                        cmp     #HammerBro
850f: f0 12                        beq     GetAltOffset            ;branch elsewhere if hammer bro
8511: c9 0a                        cmp     #GreyCheepCheep
8513: f0 16                        beq     FloateyPart             ;branch if cheep-cheep of either color
8515: c9 0b                        cmp     #RedCheepCheep
8517: f0 12                        beq     FloateyPart
8519: c9 09                        cmp     #TallEnemy
851b: b0 06                        bcs     GetAltOffset            ;branch elsewhere if enemy object => $09
851d: b5 1e                        lda     Enemy_State,x
851f: c9 02                        cmp     #$02                    ;if enemy state defeated or otherwise
8521: b0 08                        bcs     FloateyPart             ;$02 or greater, branch beyond this part
8523: ae ee 03     GetAltOffset    ldx     SprDataOffset_Ctrl      ;load some kind of control bit
8526: bc ec 06                     ldy     Alt_SprDataOffset,x     ;get alternate OAM data offset
8529: a6 08                        ldx     ObjectOffset            ;get enemy object offset again
852b: bd 1e 01     FloateyPart     lda     FloateyNum_Y_Pos,x      ;get vertical coordinate for
852e: c9 18                        cmp     #$18                    ; floatey number, if coordinate in the
8530: 90 05                        bcc     SetupNumSpr             ; status bar, branch
8532: e9 01                        sbc     #$01
8534: 9d 1e 01                     sta     FloateyNum_Y_Pos,x      ;otherwise subtract one and store as new
8537: bd 1e 01     SetupNumSpr     lda     FloateyNum_Y_Pos,x      ;get vertical coordinate
853a: e9 08                        sbc     #$08                    ;subtract eight and dump into the
853c: 20 c1 e5                     jsr     DumpTwoSpr              ; left and right sprite's Y coordinates
853f: bd 17 01                     lda     FloateyNum_X_Pos,x      ;get horizontal coordinate
8542: 99 03 02                     sta     Sprite_X_Position,y     ;store into X coordinate of left sprite
8545: 18                           clc
8546: 69 08                        adc     #$08                    ;add eight pixels and store into X
8548: 99 07 02                     sta     Sprite_X_Position+4,y   ; coordinate of right sprite
854b: a9 02                        lda     #$02
854d: 99 02 02                     sta     Sprite_Attributes,y     ;set palette control in attribute bytes
8550: 99 06 02                     sta     Sprite_Attributes+4,y   ; of left and right sprites
8553: bd 10 01                     lda     FloateyNum_Control,x
8556: 0a                           asl     A                       ;multiply our floatey number control by 2
8557: aa                           tax                             ; and use as offset for look-up table
8558: bd 9f 84                     lda     FloateyNumTileData,x
855b: 99 01 02                     sta     Sprite_Tilenumber,y     ;display first half of number of points
855e: bd a0 84                     lda     FloateyNumTileData+1,x
8561: 99 05 02                     sta     Sprite_Tilenumber+4,y   ;display the second half
8564: a6 08                        ldx     ObjectOffset            ;get enemy object offset and leave
8566: 60                           rts

                   ; -----------------------------------------------------------------------------
8567: ad 3c 07     ScreenRoutines  lda     ScreenRoutineTask       ;run one of the following subroutines
856a: 20 04 8e                     jsr     JumpEngine

856d: 8b 85                        .dd2    InitScreen
856f: 9b 85                        .dd2    SetupIntermediate
8571: 52 86                        .dd2    WriteTopStatusLine
8573: 5a 86                        .dd2    WriteBottomStatusLine
8575: 93 86                        .dd2    DisplayTimeUp
8577: 9d 88                        .dd2    ResetSpritesAndScreenTimer
8579: a8 86                        .dd2    DisplayIntermediate
857b: 9d 88                        .dd2    ResetSpritesAndScreenTimer
857d: e6 86                        .dd2    AreaParserTaskControl
857f: bf 85                        .dd2    GetAreaPalette
8581: e3 85                        .dd2    GetBackgroundColor
8583: 43 86                        .dd2    GetAlternatePalette1
8585: ff 86                        .dd2    DrawTitleScreen
8587: 32 87                        .dd2    ClearBuffersDrawIcon
8589: 49 87                        .dd2    WriteTopScore

                   ; -----------------------------------------------------------------------------
858b: 20 20 82     InitScreen      jsr     MoveAllSpritesOffscreen ;initialize all sprites including sprite #0
858e: 20 19 8e                     jsr     InitializeNameTables    ; and erase both name and attribute tables
8591: ad 70 07                     lda     OperMode
8594: f0 32                        beq     NextSubtask             ;if mode still 0, do not load
8596: a2 03                        ldx     #$03                    ;into buffer pointer
8598: 4c c5 85                     jmp     SetVRAMAddr_A

                   ; -----------------------------------------------------------------------------
                   SetupIntermediate
859b: ad 44 07                     lda     BackgroundColorCtrl     ;save current background color control
859e: 48                           pha                             ; and player status to stack
859f: ad 56 07                     lda     PlayerStatus
85a2: 48                           pha
85a3: a9 00                        lda     #$00                    ;set background color to black
85a5: 8d 56 07                     sta     PlayerStatus            ; and player status to not fiery
85a8: a9 02                        lda     #$02                    ;this is the ONLY time background color control
85aa: 8d 44 07                     sta     BackgroundColorCtrl     ; is set to less than 4
85ad: 20 f1 85                     jsr     GetPlayerColors
85b0: 68                           pla                             ;we only execute this routine for
85b1: 8d 56 07                     sta     PlayerStatus            ; the intermediate lives display
85b4: 68                           pla                             ; and once we're done, we return bg
85b5: 8d 44 07                     sta     BackgroundColorCtrl     ; color ctrl and player status from stack
85b8: 4c 45 87                     jmp     IncSubtask              ; then move into the next task

                   ; -----------------------------------------------------------------------------
85bb: 01 02 03 04  AreaPalette     .bulk   $01,$02,$03,$04

85bf: ac 4e 07     GetAreaPalette  ldy     AreaType                ;select appropriate palette to load
85c2: be bb 85                     ldx     AreaPalette,y           ; based on area type
85c5: 8e 73 07     SetVRAMAddr_A   stx     VRAM_Buffer_AddrCtrl    ;store offset into buffer control
85c8: 4c 45 87     NextSubtask     jmp     IncSubtask              ;move onto next task

                   ; -----------------------------------------------------------------------------
                   ; $00 - used as temp counter in GetPlayerColors
                   BGColorCtrl_Addr
85cb: 00 09 0a 04                  .bulk   $00,$09,$0a,$04
                   BackgroundColors
85cf: 22 22 0f 0f                  .bulk   $22,$22,$0f,$0f         ;used by area type if bg color ctrl not set
85d3: 0f 22 0f 0f                  .bulk   $0f,$22,$0f,$0f         ;used by background color control if set
85d7: 22 16 27 18  PlayerColors    .bulk   $22,$16,$27,$18         ;mario's colors
85db: 22 30 27 19                  .bulk   $22,$30,$27,$19         ;luigi's colors
85df: 22 37 27 16                  .bulk   $22,$37,$27,$16         ;fiery (used by both)

                   GetBackgroundColor
85e3: ac 44 07                     ldy     BackgroundColorCtrl     ;check background color control
85e6: f0 06                        beq     NoBGColor               ;if not set, increment task and fetch palette
85e8: b9 c7 85                     lda     BGColorCtrl_Addr-4,y    ;put appropriate palette into vram
85eb: 8d 73 07                     sta     VRAM_Buffer_AddrCtrl    ;note that if set to 5-7, $0301 will not be read
85ee: ee 3c 07     NoBGColor       inc     ScreenRoutineTask       ;increment to next subtask and plod on through
                   ; 
85f1: ae 00 03     GetPlayerColors ldx     VRAM_Buffer1_Offset     ;get current buffer offset
85f4: a0 00                        ldy     #$00
85f6: ad 53 07                     lda     CurrentPlayer           ;check which player is on the screen
85f9: f0 02                        beq     ChkFiery
85fb: a0 04                        ldy     #$04                    ;load offset for luigi
85fd: ad 56 07     ChkFiery        lda     PlayerStatus            ;check player status
8600: c9 02                        cmp     #$02
8602: d0 02                        bne     StartClrGet             ;if fiery, load alternate offset for fiery player
8604: a0 08                        ldy     #$08
8606: a9 03        StartClrGet     lda     #$03                    ;do four colors
8608: 85 00                        sta     $00
860a: b9 d7 85     ClrGetLoop      lda     PlayerColors,y          ;fetch player colors and store them
860d: 9d 04 03                     sta     VRAM_Buffer1+3,x        ; in the buffer
8610: c8                           iny
8611: e8                           inx
8612: c6 00                        dec     $00
8614: 10 f4                        bpl     ClrGetLoop
8616: ae 00 03                     ldx     VRAM_Buffer1_Offset     ;load original offset from before
8619: ac 44 07                     ldy     BackgroundColorCtrl     ;if this value is four or greater, it will be set
861c: d0 03                        bne     SetBGColor              ;therefore use it as offset to background color
861e: ac 4e 07                     ldy     AreaType                ;otherwise use area type bits from area offset as offset
8621: b9 cf 85     SetBGColor      lda     BackgroundColors,y      ; to background color instead
8624: 9d 04 03                     sta     VRAM_Buffer1+3,x
8627: a9 3f                        lda     #$3f                    ;set for sprite palette address
8629: 9d 01 03                     sta     VRAM_Buffer1,x          ;save to buffer
862c: a9 10                        lda     #$10
862e: 9d 02 03                     sta     VRAM_Buffer1+1,x
8631: a9 04                        lda     #$04                    ;write length byte to buffer
8633: 9d 03 03                     sta     VRAM_Buffer1+2,x
8636: a9 00                        lda     #$00                    ;now the null terminator
8638: 9d 08 03                     sta     VRAM_Buffer1+7,x
863b: 8a                           txa                             ;move the buffer pointer ahead 7 bytes
863c: 18                           clc                             ;in case we want to write anything else later
863d: 69 07                        adc     #$07
863f: 8d 00 03     SetVRAMOffset   sta     VRAM_Buffer1_Offset     ;store as new vram buffer offset
8642: 60                           rts

                   ; -----------------------------------------------------------------------------
                   GetAlternatePalette1
8643: ad 33 07                     lda     AreaStyle               ;check for mushroom level style
8646: c9 01                        cmp     #$01
8648: d0 05                        bne     NoAltPal
864a: a9 0b                        lda     #$0b                    ;if found, load appropriate palette
864c: 8d 73 07     SetVRAMAddr_B   sta     VRAM_Buffer_AddrCtrl
864f: 4c 45 87     NoAltPal        jmp     IncSubtask              ;now onto the next task

                   ; -----------------------------------------------------------------------------
                   WriteTopStatusLine
8652: a9 00                        lda     #$00                    ;select main status bar
8654: 20 08 88                     jsr     WriteGameText           ;output it
8657: 4c 45 87                     jmp     IncSubtask              ;onto the next task

                   ; -----------------------------------------------------------------------------
                   WriteBottomStatusLine
865a: 20 30 bc                     jsr     GetSBNybbles            ;write player's score and coin tally to screen
865d: ae 00 03                     ldx     VRAM_Buffer1_Offset
8660: a9 20                        lda     #$20                    ;write address for world-area number on screen
8662: 9d 01 03                     sta     VRAM_Buffer1,x
8665: a9 73                        lda     #$73
8667: 9d 02 03                     sta     VRAM_Buffer1+1,x
866a: a9 03                        lda     #$03                    ;write length for it
866c: 9d 03 03                     sta     VRAM_Buffer1+2,x
866f: ac 5f 07                     ldy     WorldNumber             ;first the world number
8672: c8                           iny
8673: 98                           tya
8674: 9d 04 03                     sta     VRAM_Buffer1+3,x
8677: a9 28                        lda     #$28                    ;next the dash
8679: 9d 05 03                     sta     VRAM_Buffer1+4,x
867c: ac 5c 07                     ldy     LevelNumber             ;next the level number
867f: c8                           iny                             ;increment for proper number display
8680: 98                           tya
8681: 9d 06 03                     sta     VRAM_Buffer1+5,x
8684: a9 00                        lda     #$00                    ;put null terminator on
8686: 9d 07 03                     sta     VRAM_Buffer1+6,x
8689: 8a                           txa                             ;move the buffer offset up by 6 bytes
868a: 18                           clc
868b: 69 06                        adc     #$06
868d: 8d 00 03                     sta     VRAM_Buffer1_Offset
8690: 4c 45 87                     jmp     IncSubtask

                   ; -----------------------------------------------------------------------------
8693: ad 59 07     DisplayTimeUp   lda     GameTimerExpiredFlag    ;if game timer not expired, increment task
8696: f0 0a                        beq     NoTimeUp                ;control 2 tasks forward, otherwise, stay here
8698: a9 00                        lda     #$00
869a: 8d 59 07                     sta     GameTimerExpiredFlag    ;reset timer expiration flag
869d: a9 02                        lda     #$02                    ;output time-up screen to buffer
869f: 4c c7 86                     jmp     OutputInter

86a2: ee 3c 07     NoTimeUp        inc     ScreenRoutineTask       ;increment control task 2 tasks forward
86a5: 4c 45 87                     jmp     IncSubtask

                   ; -----------------------------------------------------------------------------
                   DisplayIntermediate
86a8: ad 70 07                     lda     OperMode                ;check primary mode of operation
86ab: f0 33                        beq     NoInter                 ;if in title screen mode, skip this
86ad: c9 03                        cmp     #GameOverModeValue      ;are we in game over mode?
86af: f0 22                        beq     GameOverInter           ;if so, proceed to display game over screen
86b1: ad 52 07                     lda     AltEntranceControl      ;otherwise check for mode of alternate entry
86b4: d0 2a                        bne     NoInter                 ; and branch if found
86b6: ac 4e 07                     ldy     AreaType                ;check if we are on castle level
86b9: c0 03                        cpy     #$03                    ;and if so, branch (possibly residual)
86bb: f0 05                        beq     PlayerInter
86bd: ad 69 07                     lda     DisableIntermediate     ;if this flag is set, skip intermediate lives display
86c0: d0 1e                        bne     NoInter                 ; and jump to specific task, otherwise
86c2: 20 a4 ef     PlayerInter     jsr     DrawPlayer_Intermediate ;put player in appropriate place for
86c5: a9 01                        lda     #$01                    ; lives display, then output lives display to buffer
86c7: 20 08 88     OutputInter     jsr     WriteGameText
86ca: 20 a5 88                     jsr     ResetScreenTimer
86cd: a9 00                        lda     #$00
86cf: 8d 74 07                     sta     DisableScreenFlag       ;reenable screen output
86d2: 60                           rts

86d3: a9 12        GameOverInter   lda     #$12                    ;set screen timer
86d5: 8d a0 07                     sta     ScreenTimer
86d8: a9 03                        lda     #$03                    ;output game over screen to buffer
86da: 20 08 88                     jsr     WriteGameText
86dd: 4c 4e 87                     jmp     IncModeTask_B

86e0: a9 08        NoInter         lda     #$08                    ;set for specific task and leave
86e2: 8d 3c 07                     sta     ScreenRoutineTask
86e5: 60                           rts

                   ; -----------------------------------------------------------------------------
                   AreaParserTaskControl
86e6: ee 74 07                     inc     DisableScreenFlag       ;turn off screen
86e9: 20 b0 92     TaskLoop        jsr     AreaParserTaskHandler   ;render column set of current area
86ec: ad 1f 07                     lda     AreaParserTaskNum       ;check number of tasks
86ef: d0 f8                        bne     TaskLoop                ;if tasks still not all done, do another one
86f1: ce 1e 07                     dec     ColumnSets              ;do we need to render more column sets?
86f4: 10 03                        bpl     OutputCol
86f6: ee 3c 07                     inc     ScreenRoutineTask       ;if not, move on to the next task
86f9: a9 06        OutputCol       lda     #$06                    ;set vram buffer to output rendered column set
86fb: 8d 73 07                     sta     VRAM_Buffer_AddrCtrl    ; on next NMI
86fe: 60                           rts

                   ; -----------------------------------------------------------------------------
                   ; $00 - vram buffer address table low
                   ; $01 - vram buffer address table high
86ff: ad 70 07     DrawTitleScreen lda     OperMode                ;are we in title screen mode?
8702: d0 4a                        bne     IncModeTask_B           ;if not, exit
8704: a9 1e                        lda     #>TitleScreenDataOffset ;load address $1ec0 into
8706: 8d 06 20                     sta     PPUADDR                 ; the vram address register
8709: a9 c0                        lda     #<TitleScreenDataOffset
870b: 8d 06 20                     sta     PPUADDR
870e: a9 03                        lda     #$03                    ;put address $0300 into
8710: 85 01                        sta     $01                     ; the indirect at $00
8712: a0 00                        ldy     #$00
8714: 84 00                        sty     $00
8716: ad 07 20                     lda     PPUDATA                 ;do one garbage read
8719: ad 07 20     OutputTScr      lda     PPUDATA                 ;get title screen from chr-rom
871c: 91 00                        sta     ($00),y                 ;store 256 bytes into buffer
871e: c8                           iny
871f: d0 02                        bne     ChkHiByte               ;if not past 256 bytesw, do not increment
8721: e6 01                        inc     $01                     ;otherwise increment high byte of indirect
8723: a5 01        ChkHiByte       lda     $01                     ;heck high byte?
8725: c9 04                        cmp     #$04                    ;at $0400?
8727: d0 f0                        bne     OutputTScr              ;if not, loop back and do another
8729: c0 3a                        cpy     #$3a                    ;check if offset points past end of data
872b: 90 ec                        bcc     OutputTScr              ;if not, loop back and do another
872d: a9 05                        lda     #$05                    ;set buffer transfer control to $0300,
872f: 4c 4c 86                     jmp     SetVRAMAddr_B           ; increment task and exit

                   ; -----------------------------------------------------------------------------
                   ClearBuffersDrawIcon
8732: ad 70 07                     lda     OperMode                ;check game mode
8735: d0 17                        bne     IncModeTask_B           ;if not title screen mnode, leave
8737: a2 00                        ldx     #$00                    ;otherwise, clear buffer space
8739: 9d 00 03     TScrClear       sta     VRAM_Buffer1-1,x
873c: 9d 00 04                     sta     VRAM_Buffer1+255,x
873f: ca                           dex
8740: d0 f7                        bne     TScrClear
8742: 20 25 83                     jsr     DrawMushroomIcon        ;draw player select icon
8745: ee 3c 07     IncSubtask      inc     ScreenRoutineTask       ;move onto next task
8748: 60                           rts

                   ; -----------------------------------------------------------------------------
8749: a9 fa        WriteTopScore   lda     #$fa                    ;run display routine to display top score on title
874b: 20 36 bc                     jsr     UpdateNumber
874e: ee 72 07     IncModeTask_B   inc     OperMode_Task           ;move onto next mode
8751: 60                           rts

                   ; -----------------------------------------------------------------------------
                   ; ||TopStatusBarLine
8752: 20 43 05 16+ GameText        .bulk   $20,$43,$05,$16,$0a,$1b,$12,$18 ;"MARIO"
875a: 20 52 0b 20+                 .bulk   $20,$52,$0b,$20,$18,$1b,$15,$0d ;"WORLD  TIME"
8762: 24 24 1d 12+                 .bulk   $24,$24,$1d,$12,$16,$0e
8768: 20 68 05 00+                 .bulk   $20,$68,$05,$00,$24,$24,$2e,$29 ;score trailing digit and coin display
8770: 23 c0 7f aa                  .bulk   $23,$c0,$7f,$aa         ;attribute table data, clears name table 0 to palette 2
8774: 23 c2 01 ea                  .bulk   $23,$c2,$01,$ea         ;attribute table data, used for coin icon in status bar
8778: ff                           .dd1    $ff                     ;end of data block
                   WorldLivesDisplay
8779: 21 cd 07 24+                 .bulk   $21,$cd,$07,$24,$24     ;cross with spaces used on
877e: 29 24 24 24+                 .bulk   $29,$24,$24,$24,$24     ; lives display
8783: 21 4b 09 20+                 .bulk   $21,$4b,$09,$20,$18     ;"WORLD  - " used on lives display
8788: 1b 15 0d 24+                 .bulk   $1b,$15,$0d,$24,$24,$28,$24
878f: 22 0c 47 24                  .bulk   $22,$0c,$47,$24         ;possibly used to clear time up
8793: 23 dc 01 ba                  .bulk   $23,$dc,$01,$ba         ;attribute table data for crown if more than 9 lives
8797: ff                           .dd1    $ff
8798: 21 cd 05 16+ TwoPlayerTimeUp .bulk   $21,$cd,$05,$16,$0a,$1b,$12,$18 ;"MARIO"
87a0: 22 0c 07 1d+                 .bulk   $22,$0c,$07,$1d,$12,$16,$0e,$24,$1e,$19 ;"TIME UP"
87aa: ff                           .dd1    $ff
                   TwoPlayerGameOver
87ab: 21 cd 05 16+                 .bulk   $21,$cd,$05,$16,$0a,$1b,$12,$18 ;"MARIO"
                   OnePlayerGameOver
87b3: 22 0b 09 10+                 .bulk   $22,$0b,$09,$10,$0a,$16,$0e,$24 ;"GAME OVER"
87bb: 18 1f 0e 1b                  .bulk   $18,$1f,$0e,$1b
87bf: ff                           .dd1    $ff
87c0: 25 84 15 20+ WarpZoneWelcome .bulk   $25,$84,$15,$20,$0e,$15,$0c,$18,$16 ;"WELCOME TO WARP ZONE!"
87c9: 0e 24 1d 18+                 .bulk   $0e,$24,$1d,$18,$24,$20,$0a,$1b,$19
87d2: 24 23 18 17+                 .bulk   $24,$23,$18,$17,$0e,$2b
87d8: 26 25 01 24                  .bulk   $26,$25,$01,$24         ;placeholder for left pipe
87dc: 26 2d 01 24                  .bulk   $26,$2d,$01,$24         ;placeholder for middle pipe
87e0: 26 35 01 24                  .bulk   $26,$35,$01,$24         ;placeholder for right pipe
87e4: 27 d9 46 aa                  .bulk   $27,$d9,$46,$aa         ;attribute data
87e8: 27 e1 45 aa                  .bulk   $27,$e1,$45,$aa
87ec: ff                           .dd1    $ff
87ed: 15 1e 12 10+ LuigiName       .bulk   $15,$1e,$12,$10,$12     ;"LUIGI", no address or length
87f2: 04 03 02 00  WarpZoneNumbers .bulk   $04,$03,$02,$00         ;warp zone numbers, note spaces on middle
87f6: 24 05 24 00                  .bulk   $24,$05,$24,$00         ; zone, partly responsible for
87fa: 08 07 06 00                  .bulk   $08,$07,$06,$00         ; the minus world
                   ; || (should be table of single-byte offsets, e.g. TopStatusBarLine-GameText and
                   ; WorldLivesDisplay-GameText)
87fe: 00 00 27 27+ GameTextOffsets .bulk   $00,$00,$27,$27,$46,$4e,$59,$61,$6e,$6e

8808: 48           WriteGameText   pha                             ;save text number to stack
8809: 0a                           asl     A
880a: a8                           tay                             ;multiply by 2 and use as offset
880b: c0 04                        cpy     #$04                    ;if set to do top status bar on world/lives display,
880d: 90 0c                        bcc     LdGameText              ; branch to use current offset as-is
880f: c0 08                        cpy     #$08                    ;if set to do time-up or game over,
8811: 90 02                        bcc     Chk2Players             ;branch to check players
8813: a0 08                        ldy     #$08                    ;otherwise warp zone, therefore set offset
8815: ad 7a 07     Chk2Players     lda     NumberOfPlayers         ;check for number of players
8818: d0 01                        bne     LdGameText              ;if there are two, use current offset to also print name
881a: c8                           iny                             ;otherwise increment offset by one to not print name
881b: be fe 87     LdGameText      ldx     GameTextOffsets,y       ;get offset to message we want to print
881e: a0 00                        ldy     #$00
8820: bd 52 87     GameTextLoop    lda     GameText,x              ;load message data
8823: c9 ff                        cmp     #$ff                    ;check for terminator
8825: f0 07                        beq     EndGameText             ;branch to end text if found
8827: 99 01 03                     sta     VRAM_Buffer1,y          ;otherwise write data to buffer
882a: e8                           inx                             ;and increment increment
882b: c8                           iny
882c: d0 f2                        bne     GameTextLoop            ;do this for 256 bytes if no terminator found
882e: a9 00        EndGameText     lda     #$00                    ;put null terminator at end
8830: 99 01 03                     sta     VRAM_Buffer1,y
8833: 68                           pla                             ;pull original text number from stack
8834: aa                           tax
8835: c9 04                        cmp     #$04                    ;are we printing warp zone?
8837: b0 49                        bcs     PrintWarpZoneNumbers
8839: ca                           dex                             ;are we printing the world/lives display?
883a: d0 23                        bne     CheckPlayerName         ;if not, branch to check player's name
883c: ad 5a 07                     lda     NumberOfLives           ;otherwise, check number of lives
883f: 18                           clc                             ; and increment by one for display
8840: 69 01                        adc     #$01
8842: c9 0a                        cmp     #10                     ;more than 9 lives?
8844: 90 07                        bcc     PutLives
8846: e9 0a                        sbc     #10                     ;if so, subtract 10 and put a crown tile
8848: a0 9f                        ldy     #$9f                    ; next to the difference...strange things happen if
884a: 8c 08 03                     sty     VRAM_Buffer1+7          ; the number of lives exceeds 19
884d: 8d 09 03     PutLives        sta     VRAM_Buffer1+8
8850: ac 5f 07                     ldy     WorldNumber             ;write world and level numbers (incremented for display)
8853: c8                           iny                             ; to the buffer in the spaces surrounding the dash
8854: 8c 14 03                     sty     VRAM_Buffer1+19
8857: ac 5c 07                     ldy     LevelNumber
885a: c8                           iny
885b: 8c 16 03                     sty     VRAM_Buffer1+21         ;we're done here
885e: 60                           rts

885f: ad 7a 07     CheckPlayerName lda     NumberOfPlayers         ;check number of players
8862: f0 1d                        beq     ExitChkName             ;if only 1 player, leave
8864: ad 53 07                     lda     CurrentPlayer           ;load current player
8867: ca                           dex                             ;check to see if current message number is for time up
8868: d0 09                        bne     ChkLuigi
886a: ac 70 07                     ldy     OperMode                ;check for game over mode
886d: c0 03                        cpy     #GameOverModeValue
886f: f0 02                        beq     ChkLuigi
8871: 49 01                        eor     #%00000001              ;if not, must be time up, invert d0 to do other player
8873: 4a           ChkLuigi        lsr     A
8874: 90 0b                        bcc     ExitChkName             ;if mario is current player, do not change the name
8876: a0 04                        ldy     #$04
8878: b9 ed 87     NameLoop        lda     LuigiName,y             ;otherwise, replace "MARIO" with "LUIGI"
887b: 99 04 03                     sta     VRAM_Buffer1+3,y
887e: 88                           dey
887f: 10 f7                        bpl     NameLoop                ;do this until each letter is replaced
8881: 60           ExitChkName     rts

                   PrintWarpZoneNumbers
8882: e9 04                        sbc     #$04                    ;subtract 4 and then shift to the left
8884: 0a                           asl     A                       ; twice to get proper warp zone number
8885: 0a                           asl     A                       ;offset
8886: aa                           tax
8887: a0 00                        ldy     #$00
8889: bd f2 87     WarpNumLoop     lda     WarpZoneNumbers,x       ;print warp zone numbers into the
888c: 99 1c 03                     sta     VRAM_Buffer1+27,y       ; placeholders from earlier
888f: e8                           inx
8890: c8                           iny                             ;put a number in every fourth space
8891: c8                           iny
8892: c8                           iny
8893: c8                           iny
8894: c0 0c                        cpy     #$0c
8896: 90 f1                        bcc     WarpNumLoop
8898: a9 2c                        lda     #$2c                    ;load new buffer pointer at end of message
889a: 4c 3f 86                     jmp     SetVRAMOffset

                   ; -----------------------------------------------------------------------------
                   ResetSpritesAndScreenTimer
889d: ad a0 07                     lda     ScreenTimer             ;check if screen timer has expired
88a0: d0 0b                        bne     NoReset                 ;if not, branch to leave
88a2: 20 20 82                     jsr     MoveAllSpritesOffscreen ;otherwise reset sprites now
                   ResetScreenTimer
88a5: a9 07                        lda     #$07                    ;reset timer again
88a7: 8d a0 07                     sta     ScreenTimer
88aa: ee 3c 07                     inc     ScreenRoutineTask       ;move onto next task
88ad: 60           NoReset         rts

                   ; -----------------------------------------------------------------------------
                   ; $00 - temp vram buffer offset
                   ; $01 - temp metatile buffer offset
                   ; $02 - temp metatile graphics table offset
                   ; $03 - used to store attribute bits
                   ; $04 - used to determine attribute table row
                   ; $05 - used to determine attribute table column
                   ; $06 - metatile graphics table address low
                   ; $07 - metatile graphics table address high
                   RenderAreaGraphics
88ae: ad 26 07                     lda     CurrentColumnPos        ;store LSB of where we're at
88b1: 29 01                        and     #$01
88b3: 85 05                        sta     $05
88b5: ac 40 03                     ldy     VRAM_Buffer2_Offset     ;store vram buffer offset
88b8: 84 00                        sty     $00
88ba: ad 21 07                     lda     CurrentNTAddr_Low       ;get current name table address we're supposed to render
88bd: 99 42 03                     sta     VRAM_Buffer2+1,y
88c0: ad 20 07                     lda     CurrentNTAddr_High
88c3: 99 41 03                     sta     VRAM_Buffer2,y
88c6: a9 9a                        lda     #$9a                    ;store length byte of 26 here with d7 set
88c8: 99 43 03                     sta     VRAM_Buffer2+2,y        ; to increment by 32 (in columns)
88cb: a9 00                        lda     #$00                    ;init attribute row
88cd: 85 04                        sta     $04
88cf: aa                           tax
88d0: 86 01        DrawMTLoop      stx     $01                     ;tore init value of 0 or incremented offset for buffer
88d2: bd a1 06                     lda     MetatileBuffer,x        ;get first metatile number, and mask out all but 2 MSB
88d5: 29 c0                        and     #%11000000
88d7: 85 03                        sta     $03                     ;store attribute table bits here
88d9: 0a                           asl     A                       ;note that metatile format is:
88da: 2a                           rol     A                       ;%xx000000 - attribute table bits
88db: 2a                           rol     A                       ;%00xxxxxx - metatile number
88dc: a8                           tay                             ;rotate bits to d1-d0 and use as offset here
88dd: b9 08 8b                     lda     MetatileGraphics_Low,y  ;get address to graphics table from here
88e0: 85 06                        sta     $06
88e2: b9 0c 8b                     lda     MetatileGraphics_High,y
88e5: 85 07                        sta     $07
88e7: bd a1 06                     lda     MetatileBuffer,x        ;get metatile number again
88ea: 0a                           asl     A                       ;multiply by 4 and use as tile offset
88eb: 0a                           asl     A
88ec: 85 02                        sta     $02
88ee: ad 1f 07                     lda     AreaParserTaskNum       ;get current task number for level processing and
88f1: 29 01                        and     #%00000001              ; mask out all but LSB, then invert LSB, multiply by 2
88f3: 49 01                        eor     #%00000001              ; to get the correct column position in the metatile,
88f5: 0a                           asl     A                       ; then add to the tile offset so we can draw either side
88f6: 65 02                        adc     $02                     ; of the metatiles
88f8: a8                           tay
88f9: a6 00                        ldx     $00                     ;use vram buffer offset from before as X
88fb: b1 06                        lda     ($06),y
88fd: 9d 44 03                     sta     VRAM_Buffer2+3,x        ;get first tile number (top left or top right) and store
8900: c8                           iny
8901: b1 06                        lda     ($06),y                 ;now get the second (bottom left or bottom right) and store
8903: 9d 45 03                     sta     VRAM_Buffer2+4,x
8906: a4 04                        ldy     $04                     ;get current attribute row
8908: a5 05                        lda     $05                     ;get LSB of current column where we're at, and
890a: d0 0e                        bne     RightCheck              ; branch if set (clear = left attrib, set = right)
890c: a5 01                        lda     $01                     ;get current row we're rendering
890e: 4a                           lsr     A                       ;branch if LSB set (clear = top left, set = bottom left)
890f: b0 19                        bcs     LLeft
8911: 26 03                        rol     $03                     ;rotate attribute bits 3 to the left
8913: 26 03                        rol     $03                     ;this in d1-d0, for upper left square
8915: 26 03                        rol     $03
8917: 4c 30 89                     jmp     SetAttrib

891a: a5 01        RightCheck      lda     $01                     ;get LSB of current row we're rendering
891c: 4a                           lsr     A                       ;branch if set (clear = top right, set = bottom right)
891d: b0 0f                        bcs     NextMTRow
891f: 46 03                        lsr     $03                     ;shift attribute bits 4 to the right
8921: 46 03                        lsr     $03
8923: 46 03                        lsr     $03
8925: 46 03                        lsr     $03
8927: 4c 30 89                     jmp     SetAttrib

892a: 46 03        LLeft           lsr     $03                     ;shift attribute bits 2 to the right
892c: 46 03                        lsr     $03                     ;this in d5-d4 for lower left square
892e: e6 04        NextMTRow       inc     $04                     ;move onto next attribute row
8930: b9 f9 03     SetAttrib       lda     AttributeBuffer,y       ;get previously saved bits from before
8933: 05 03                        ora     $03                     ; if any, and put new bits, if any
8935: 99 f9 03                     sta     AttributeBuffer,y       ; onto the old, and store
8938: e6 00                        inc     $00                     ;increment vram buffer offset by 2
893a: e6 00                        inc     $00
893c: a6 01                        ldx     $01                     ;get current gfx buffer row, and check for
893e: e8                           inx                             ; the bottom of the screen
893f: e0 0d                        cpx     #$0d
8941: 90 8d                        bcc     DrawMTLoop              ;if not there yet, loop back
8943: a4 00                        ldy     $00                     ;get current vram buffer offset, increment by 3
8945: c8                           iny                             ;(for name table address and length bytes)
8946: c8                           iny
8947: c8                           iny
8948: a9 00                        lda     #$00
894a: 99 41 03                     sta     VRAM_Buffer2,y          ;put null terminator at end of data for name table
894d: 8c 40 03                     sty     VRAM_Buffer2_Offset     ;store new buffer offset
8950: ee 21 07                     inc     CurrentNTAddr_Low       ;increment name table address low
8953: ad 21 07                     lda     CurrentNTAddr_Low       ;check current low byte
8956: 29 1f                        and     #%00011111              ;if no wraparound, just skip this part
8958: d0 0d                        bne     ExitDrawM
895a: a9 80                        lda     #$80                    ;if wraparound occurs, make sure low byte stays
895c: 8d 21 07                     sta     CurrentNTAddr_Low       ; just under the status bar
895f: ad 20 07                     lda     CurrentNTAddr_High      ; and then invert d2 of the name table address high
8962: 49 04                        eor     #%00000100              ; to move onto the next appropriate name table
8964: 8d 20 07                     sta     CurrentNTAddr_High
8967: 4c bd 89     ExitDrawM       jmp     SetVRAMCtrl             ;jump to set buffer to $0341 and leave

                   ; -----------------------------------------------------------------------------
                   ; $00 - temp attribute table address high (big endian order this time!)
                   ; $01 - temp attribute table address low
                   RenderAttributeTables
896a: ad 21 07                     lda     CurrentNTAddr_Low       ;get low byte of next name table address
896d: 29 1f                        and     #%00011111              ; to be written to, mask out all but 5 LSB,
896f: 38                           sec                             ; subtract four 
8970: e9 04                        sbc     #$04
8972: 29 1f                        and     #%00011111              ;mask out bits again and store
8974: 85 01                        sta     $01
8976: ad 20 07                     lda     CurrentNTAddr_High      ;get high byte and branch if borrow not set
8979: b0 02                        bcs     SetATHigh
897b: 49 04                        eor     #%00000100              ;otherwise invert d2
897d: 29 04        SetATHigh       and     #%00000100              ;mask out all other bits
897f: 09 23                        ora     #$23                    ;add $2300 to the high byte and store
8981: 85 00                        sta     $00
8983: a5 01                        lda     $01                     ;get low byte - 4, divide by 4, add offset for
8985: 4a                           lsr     A                       ; attribute table and store
8986: 4a                           lsr     A
8987: 69 c0                        adc     #$c0                    ;we should now have the appropriate block of
8989: 85 01                        sta     $01                     ; attribute table in our temp address
898b: a2 00                        ldx     #$00
898d: ac 40 03                     ldy     VRAM_Buffer2_Offset     ;get buffer offset
8990: a5 00        AttribLoop      lda     $00
8992: 99 41 03                     sta     VRAM_Buffer2,y          ;store high byte of attribute table address
8995: a5 01                        lda     $01
8997: 18                           clc                             ;get low byte, add 8 because we want to start
8998: 69 08                        adc     #$08                    ; below the status bar, and store
899a: 99 42 03                     sta     VRAM_Buffer2+1,y
899d: 85 01                        sta     $01                     ;also store in temp again
899f: bd f9 03                     lda     AttributeBuffer,x       ;fetch current attribute table byte and store
89a2: 99 44 03                     sta     VRAM_Buffer2+3,y        ; in the buffer
89a5: a9 01                        lda     #$01
89a7: 99 43 03                     sta     VRAM_Buffer2+2,y        ;store length of 1 in buffer
89aa: 4a                           lsr     A
89ab: 9d f9 03                     sta     AttributeBuffer,x       ;clear current byte in attribute buffer
89ae: c8                           iny                             ;increment buffer offset by 4 bytes
89af: c8                           iny
89b0: c8                           iny
89b1: c8                           iny
89b2: e8                           inx                             ;increment attribute offset and check to see
89b3: e0 07                        cpx     #$07                    ; if we're at the end yet
89b5: 90 d9                        bcc     AttribLoop
89b7: 99 41 03                     sta     VRAM_Buffer2,y          ;put null terminator at the end
89ba: 8c 40 03                     sty     VRAM_Buffer2_Offset     ;store offset in case we want to do any more
89bd: a9 06        SetVRAMCtrl     lda     #$06
89bf: 8d 73 07                     sta     VRAM_Buffer_AddrCtrl    ;set buffer to $0341 and leave
89c2: 60                           rts

                   ; -----------------------------------------------------------------------------
                   ; $00 - used as temporary counter in ColorRotation
                   ColorRotatePalette
89c3: 27 27 27 17+                 .bulk   $27,$27,$27,$17,$07,$17
89c9: 3f 0c 04 ff+ BlankPalette    .bulk   $3f,$0c,$04,$ff,$ff,$ff,$ff,$00
                   ; used based on area type
89d1: 0f 07 12 0f  Palette3Data    .bulk   $0f,$07,$12,$0f
89d5: 0f 07 17 0f                  .bulk   $0f,$07,$17,$0f
89d9: 0f 07 17 1c                  .bulk   $0f,$07,$17,$1c
89dd: 0f 07 17 00                  .bulk   $0f,$07,$17,$00

89e1: a5 09        ColorRotation   lda     FrameCounter            ;get frame counter
89e3: 29 07                        and     #$07                    ;mask out all but three LSB
89e5: d0 51                        bne     ExitColorRot            ;branch if not set to zero to do this every eighth frame
89e7: ae 00 03                     ldx     VRAM_Buffer1_Offset     ;check vram buffer offset
89ea: e0 31                        cpx     #$31
89ec: b0 4a                        bcs     ExitColorRot            ;if offset over 48 bytes, branch to leave
89ee: a8                           tay                             ;otherwise use frame counter's 3 LSB as offset here
89ef: b9 c9 89     GetBlankPal     lda     BlankPalette,y          ;get blank palette for palette 3
89f2: 9d 01 03                     sta     VRAM_Buffer1,x          ;store it in the vram buffer
89f5: e8                           inx                             ;increment offsets
89f6: c8                           iny
89f7: c0 08                        cpy     #$08
89f9: 90 f4                        bcc     GetBlankPal             ;do this until all bytes are copied
89fb: ae 00 03                     ldx     VRAM_Buffer1_Offset     ;get current vram buffer offset
89fe: a9 03                        lda     #$03
8a00: 85 00                        sta     $00                     ;set counter here
8a02: ad 4e 07                     lda     AreaType                ;get area type
8a05: 0a                           asl     A                       ;multiply by 4 to get proper offset
8a06: 0a                           asl     A
8a07: a8                           tay                             ;save as offset here
8a08: b9 d1 89     GetAreaPal      lda     Palette3Data,y          ;fetch palette to be written based on area type
8a0b: 9d 04 03                     sta     VRAM_Buffer1+3,x        ;store it to overwrite blank palette in vram buffer
8a0e: c8                           iny
8a0f: e8                           inx
8a10: c6 00                        dec     $00                     ;decrement counter
8a12: 10 f4                        bpl     GetAreaPal              ;do this until the palette is all copied
8a14: ae 00 03                     ldx     VRAM_Buffer1_Offset     ;get current vram buffer offset
8a17: ac d4 06                     ldy     ColorRotateOffset       ;get color cycling offset
8a1a: b9 c3 89                     lda     ColorRotatePalette,y
8a1d: 9d 05 03                     sta     VRAM_Buffer1+4,x        ;get and store current color in second slot of palette
8a20: ad 00 03                     lda     VRAM_Buffer1_Offset
8a23: 18                           clc                             ;add seven bytes to vram buffer offset
8a24: 69 07                        adc     #$07
8a26: 8d 00 03                     sta     VRAM_Buffer1_Offset
8a29: ee d4 06                     inc     ColorRotateOffset       ;increment color cycling offset
8a2c: ad d4 06                     lda     ColorRotateOffset
8a2f: c9 06                        cmp     #$06                    ;check to see if it's still in range
8a31: 90 05                        bcc     ExitColorRot            ;if so, branch to leave
8a33: a9 00                        lda     #$00
8a35: 8d d4 06                     sta     ColorRotateOffset       ;otherwise, init to keep it in range
8a38: 60           ExitColorRot    rts                             ;leave

                   ; -----------------------------------------------------------------------------
                   ; $00 - temp store for offset control bit
                   ; $01 - temp vram buffer offset
                   ; $02 - temp store for vertical high nybble in block buffer routine
                   ; $03 - temp adder for high byte of name table address
                   ; $04, $05 - name table address low/high
                   ; $06, $07 - block buffer address low/high
8a39: 45 45 47 47  BlockGfxData    .bulk   $45,$45,$47,$47
8a3d: 47 47 47 47                  .bulk   $47,$47,$47,$47
8a41: 57 58 59 5a                  .bulk   $57,$58,$59,$5a
8a45: 24 24 24 24                  .bulk   $24,$24,$24,$24
8a49: 26 26 26 26                  .bulk   $26,$26,$26,$26

8a4d: a0 41        RemoveCoin_Axe  ldy     #$41                    ;set low byte so offset points to $0341
8a4f: a9 03                        lda     #$03                    ;load offset for default blank metatile
8a51: ae 4e 07                     ldx     AreaType                ;check area type
8a54: d0 02                        bne     WriteBlankMT            ;if not water type, use offset
8a56: a9 04                        lda     #$04                    ;otherwise load offset for blank metatile used in water
8a58: 20 97 8a     WriteBlankMT    jsr     PutBlockMetatile        ;do a sub to write blank metatile to vram buffer
8a5b: a9 06                        lda     #$06
8a5d: 8d 73 07                     sta     VRAM_Buffer_AddrCtrl    ;set vram address controller to $0341 and leave
8a60: 60                           rts

                   ReplaceBlockMetatile
8a61: 20 6d 8a                     jsr     WriteBlockMetatile      ;write metatile to vram buffer to replace block object
8a64: ee f0 03                     inc     Block_ResidualCounter   ;increment unused counter (residual code)
8a67: de ec 03                     dec     Block_RepFlag,x         ;decrement flag (residual code)
8a6a: 60                           rts                             ;leave

                   DestroyBlockMetatile
8a6b: a9 00                        lda     #$00                    ;force blank metatile if branched/jumped to this point
                   WriteBlockMetatile
8a6d: a0 03                        ldy     #$03                    ;load offset for blank metatile
8a6f: c9 00                        cmp     #$00                    ;check contents of A for blank metatile
8a71: f0 14                        beq     UseBOffset              ;branch if found (unconditional if branched from 8a6b)
8a73: a0 00                        ldy     #$00                    ;load offset for brick metatile w/ line
8a75: c9 58                        cmp     #$58
8a77: f0 0e                        beq     UseBOffset              ;use offset if metatile is brick with coins (w/ line)
8a79: c9 51                        cmp     #$51
8a7b: f0 0a                        beq     UseBOffset              ;use offset if metatile is breakable brick w/ line
8a7d: c8                           iny                             ;increment offset for brick metatile w/o line
8a7e: c9 5d                        cmp     #$5d
8a80: f0 05                        beq     UseBOffset              ;use offset if metatile is brick with coins (w/o line)
8a82: c9 52                        cmp     #$52
8a84: f0 01                        beq     UseBOffset              ;use offset if metatile is breakable brick w/o line
8a86: c8                           iny                             ;if any other metatile, increment offset for empty block
8a87: 98           UseBOffset      tya                             ;put Y in A
8a88: ac 00 03                     ldy     VRAM_Buffer1_Offset     ;get vram buffer offset
8a8b: c8                           iny                             ;move onto next byte
8a8c: 20 97 8a                     jsr     PutBlockMetatile        ;get appropriate block data and write to vram buffer
8a8f: 88           MoveVOffset     dey                             ;decrement vram buffer offset
8a90: 98                           tya                             ;add 10 bytes to it
8a91: 18                           clc
8a92: 69 0a                        adc     #10
8a94: 4c 3f 86                     jmp     SetVRAMOffset           ;branch to store as new vram buffer offset

                   PutBlockMetatile
8a97: 86 00                        stx     $00                     ;store control bit from SprDataOffset_Ctrl
8a99: 84 01                        sty     $01                     ;store vram buffer offset for next byte
8a9b: 0a                           asl     A
8a9c: 0a                           asl     A                       ;multiply A by four and use as X
8a9d: aa                           tax
8a9e: a0 20                        ldy     #$20                    ;load high byte for name table 0
8aa0: a5 06                        lda     $06                     ;get low byte of block buffer pointer
8aa2: c9 d0                        cmp     #$d0                    ;check to see if we're on odd-page block buffer
8aa4: 90 02                        bcc     SaveHAddr               ;if not, use current high byte
8aa6: a0 24                        ldy     #$24                    ;otherwise load high byte for name table 1
8aa8: 84 03        SaveHAddr       sty     $03                     ;save high byte here
8aaa: 29 0f                        and     #$0f                    ;mask out high nybble of block buffer pointer
8aac: 0a                           asl     A                       ;multiply by 2 to get appropriate name table low byte
8aad: 85 04                        sta     $04                     ;and then store it here
8aaf: a9 00                        lda     #$00
8ab1: 85 05                        sta     $05                     ;initialize temp high byte
8ab3: a5 02                        lda     $02                     ;get vertical high nybble offset used in block buffer routine
8ab5: 18                           clc
8ab6: 69 20                        adc     #$20                    ;add 32 pixels for the status bar
8ab8: 0a                           asl     A
8ab9: 26 05                        rol     $05                     ;shift and rotate d7 onto d0 and d6 into carry
8abb: 0a                           asl     A
8abc: 26 05                        rol     $05                     ;shift and rotate d6 onto d0 and d5 into carry
8abe: 65 04                        adc     $04                     ;add low byte of name table and carry to vertical high nybble
8ac0: 85 04                        sta     $04                     ;and store here
8ac2: a5 05                        lda     $05                     ;get whatever was in d7 and d6 of vertical high nybble
8ac4: 69 00                        adc     #$00                    ;add carry
8ac6: 18                           clc
8ac7: 65 03                        adc     $03                     ;then add high byte of name table
8ac9: 85 05                        sta     $05                     ;store here
8acb: a4 01                        ldy     $01                     ;get vram buffer offset to be used
8acd: bd 39 8a     RemBridge       lda     BlockGfxData,x          ;write top left and top right
8ad0: 99 03 03                     sta     VRAM_Buffer1+2,y        ; tile numbers into first spot
8ad3: bd 3a 8a                     lda     BlockGfxData+1,x
8ad6: 99 04 03                     sta     VRAM_Buffer1+3,y
8ad9: bd 3b 8a                     lda     BlockGfxData+2,x        ;write bottom left and bottom
8adc: 99 08 03                     sta     VRAM_Buffer1+7,y        ; right tiles numbers into
8adf: bd 3c 8a                     lda     BlockGfxData+3,x        ; second spot
8ae2: 99 09 03                     sta     VRAM_Buffer1+8,y
8ae5: a5 04                        lda     $04
8ae7: 99 01 03                     sta     VRAM_Buffer1,y          ;write low byte of name table
8aea: 18                           clc                             ; into first slot as read
8aeb: 69 20                        adc     #$20                    ;add 32 bytes to value
8aed: 99 06 03                     sta     VRAM_Buffer1+5,y        ;write low byte of name table
8af0: a5 05                        lda     $05                     ; plus 32 bytes into second slot
8af2: 99 00 03                     sta     VRAM_Buffer1-1,y        ;write high byte of name
8af5: 99 05 03                     sta     VRAM_Buffer1+4,y        ; table address to both slots
8af8: a9 02                        lda     #$02
8afa: 99 02 03                     sta     VRAM_Buffer1+1,y        ;put length of 2 in
8afd: 99 07 03                     sta     VRAM_Buffer1+6,y        ; both slots
8b00: a9 00                        lda     #$00
8b02: 99 0a 03                     sta     VRAM_Buffer1+9,y        ;put null terminator at end
8b05: a6 00                        ldx     $00                     ;get offset control bit here
8b07: 60                           rts                             ;and leave

                   ; -----------------------------------------------------------------------------
                   ; METATILE GRAPHICS TABLE
                   MetatileGraphics_Low
8b08: 10                           .dd1    <Palette0_MTiles
8b09: ac                           .dd1    <Palette1_MTiles
8b0a: 64                           .dd1    <Palette2_MTiles
8b0b: 8c                           .dd1    <Palette3_MTiles
                   MetatileGraphics_High
8b0c: 8b                           .dd1    >Palette0_MTiles
8b0d: 8b                           .dd1    >Palette1_MTiles
8b0e: 8c                           .dd1    >Palette2_MTiles
8b0f: 8c                           .dd1    >Palette3_MTiles
8b10: 24 24 24 24  Palette0_MTiles .bulk   $24,$24,$24,$24         ;blank
8b14: 27 27 27 27                  .bulk   $27,$27,$27,$27         ;black metatile
8b18: 24 24 24 35                  .bulk   $24,$24,$24,$35         ;bush left
8b1c: 36 25 37 25                  .bulk   $36,$25,$37,$25         ;bush middle
8b20: 24 38 24 24                  .bulk   $24,$38,$24,$24         ;bush right
8b24: 24 30 30 26                  .bulk   $24,$30,$30,$26         ;mountain left
8b28: 26 26 34 26                  .bulk   $26,$26,$34,$26         ;mountain left bottom/middle center
8b2c: 24 31 24 32                  .bulk   $24,$31,$24,$32         ;mountain middle top
8b30: 33 26 24 33                  .bulk   $33,$26,$24,$33         ;mountain right
8b34: 34 26 26 26                  .bulk   $34,$26,$26,$26         ;mountain right bottom
8b38: 26 26 26 26                  .bulk   $26,$26,$26,$26         ;mountain middle bottom
8b3c: 24 c0 24 c0                  .bulk   $24,$c0,$24,$c0         ;bridge guardrail
8b40: 24 7f 7f 24                  .bulk   $24,$7f,$7f,$24         ;chain
8b44: b8 ba b9 bb                  .bulk   $b8,$ba,$b9,$bb         ;tall tree, top half
8b48: b8 bc b9 bd                  .bulk   $b8,$bc,$b9,$bd         ;short tree top
8b4c: ba bc bb bd                  .bulk   $ba,$bc,$bb,$bd         ;tall tree top, bottom half
8b50: 60 64 61 65                  .bulk   $60,$64,$61,$65         ;warp pipe end left, points up
8b54: 62 66 63 67                  .bulk   $62,$66,$63,$67         ;warp pipe end right, points up
8b58: 60 64 61 65                  .bulk   $60,$64,$61,$65         ;decoration pipe end left, points up
8b5c: 62 66 63 67                  .bulk   $62,$66,$63,$67         ;decoration pipe end right, points up
8b60: 68 68 69 69                  .bulk   $68,$68,$69,$69         ;pipe shaft left
8b64: 26 26 6a 6a                  .bulk   $26,$26,$6a,$6a         ;pipe shaft right
8b68: 4b 4c 4d 4e                  .bulk   $4b,$4c,$4d,$4e         ;tree ledge left edge
8b6c: 4d 4f 4d 4f                  .bulk   $4d,$4f,$4d,$4f         ;tree ledge middle
8b70: 4d 4e 50 51                  .bulk   $4d,$4e,$50,$51         ;tree ledge right edge
8b74: 6b 70 2c 2d                  .bulk   $6b,$70,$2c,$2d         ;mushroom left edge
8b78: 6c 71 6d 72                  .bulk   $6c,$71,$6d,$72         ;mushroom middle
8b7c: 6e 73 6f 74                  .bulk   $6e,$73,$6f,$74         ;mushroom right edge
8b80: 86 8a 87 8b                  .bulk   $86,$8a,$87,$8b         ;sideways pipe end top
8b84: 88 8c 88 8c                  .bulk   $88,$8c,$88,$8c         ;sideways pipe shaft top
8b88: 89 8d 69 69                  .bulk   $89,$8d,$69,$69         ;sideways pipe joint top
8b8c: 8e 91 8f 92                  .bulk   $8e,$91,$8f,$92         ;sideways pipe end bottom
8b90: 26 93 26 93                  .bulk   $26,$93,$26,$93         ;sideways pipe shaft bottom
8b94: 90 94 69 69                  .bulk   $90,$94,$69,$69         ;sideways pipe joint bottom
8b98: a4 e9 ea eb                  .bulk   $a4,$e9,$ea,$eb         ;seaplant
8b9c: 24 24 24 24                  .bulk   $24,$24,$24,$24         ;blank, used on bricks or blocks that are hit
8ba0: 24 2f 24 3d                  .bulk   $24,$2f,$24,$3d         ;flagpole ball
8ba4: a2 a2 a3 a3                  .bulk   $a2,$a2,$a3,$a3         ;flagpole shaft
8ba8: 24 24 24 24                  .bulk   $24,$24,$24,$24         ;blank, used in conjunction with vines
8bac: a2 a2 a3 a3  Palette1_MTiles .bulk   $a2,$a2,$a3,$a3         ;vertical rope
8bb0: 99 24 99 24                  .bulk   $99,$24,$99,$24         ;horizontal rope
8bb4: 24 a2 3e 3f                  .bulk   $24,$a2,$3e,$3f         ;left pulley
8bb8: 5b 5c 24 a3                  .bulk   $5b,$5c,$24,$a3         ;right pulley
8bbc: 24 24 24 24                  .bulk   $24,$24,$24,$24         ;blank used for balance rope
8bc0: 9d 47 9e 47                  .bulk   $9d,$47,$9e,$47         ;castle top
8bc4: 47 47 27 27                  .bulk   $47,$47,$27,$27         ;castle window left
8bc8: 47 47 47 47                  .bulk   $47,$47,$47,$47         ;castle brick wall
8bcc: 27 27 47 47                  .bulk   $27,$27,$47,$47         ;castle window right
8bd0: a9 47 aa 47                  .bulk   $a9,$47,$aa,$47         ;castle top w/ brick
8bd4: 9b 27 9c 27                  .bulk   $9b,$27,$9c,$27         ;entrance top
8bd8: 27 27 27 27                  .bulk   $27,$27,$27,$27         ;entrance bottom
8bdc: 52 52 52 52                  .bulk   $52,$52,$52,$52         ;green ledge stump
8be0: 80 a0 81 a1                  .bulk   $80,$a0,$81,$a1         ;fence
8be4: be be bf bf                  .bulk   $be,$be,$bf,$bf         ;tree trunk
8be8: 75 ba 76 bb                  .bulk   $75,$ba,$76,$bb         ;mushroom stump top
8bec: ba ba bb bb                  .bulk   $ba,$ba,$bb,$bb         ;mushroom stump bottom
8bf0: 45 47 45 47                  .bulk   $45,$47,$45,$47         ;breakable brick w/ line 
8bf4: 47 47 47 47                  .bulk   $47,$47,$47,$47         ;breakable brick 
8bf8: 45 47 45 47                  .bulk   $45,$47,$45,$47         ;breakable brick (not used)
8bfc: b4 b6 b5 b7                  .bulk   $b4,$b6,$b5,$b7         ;cracked rock terrain
8c00: 45 47 45 47                  .bulk   $45,$47,$45,$47         ;brick with line (power-up)
8c04: 45 47 45 47                  .bulk   $45,$47,$45,$47         ;brick with line (vine)
8c08: 45 47 45 47                  .bulk   $45,$47,$45,$47         ;brick with line (star)
8c0c: 45 47 45 47                  .bulk   $45,$47,$45,$47         ;brick with line (coins)
8c10: 45 47 45 47                  .bulk   $45,$47,$45,$47         ;brick with line (1-up)
8c14: 47 47 47 47                  .bulk   $47,$47,$47,$47         ;brick (power-up)
8c18: 47 47 47 47                  .bulk   $47,$47,$47,$47         ;brick (vine)
8c1c: 47 47 47 47                  .bulk   $47,$47,$47,$47         ;brick (star)
8c20: 47 47 47 47                  .bulk   $47,$47,$47,$47         ;brick (coins)
8c24: 47 47 47 47                  .bulk   $47,$47,$47,$47         ;brick (1-up)
8c28: 24 24 24 24                  .bulk   $24,$24,$24,$24         ;hidden block (1 coin)
8c2c: 24 24 24 24                  .bulk   $24,$24,$24,$24         ;hidden block (1-up)
8c30: ab ac ad ae                  .bulk   $ab,$ac,$ad,$ae         ;solid block (3-d block)
8c34: 5d 5e 5d 5e                  .bulk   $5d,$5e,$5d,$5e         ;solid block (white wall)
8c38: c1 24 c1 24                  .bulk   $c1,$24,$c1,$24         ;bridge
8c3c: c6 c8 c7 c9                  .bulk   $c6,$c8,$c7,$c9         ;bullet bill cannon barrel
8c40: ca cc cb cd                  .bulk   $ca,$cc,$cb,$cd         ;bullet bill cannon top
8c44: 2a 2a 40 40                  .bulk   $2a,$2a,$40,$40         ;bullet bill cannon bottom
8c48: 24 24 24 24                  .bulk   $24,$24,$24,$24         ;blank used for jumpspring
8c4c: 24 47 24 47                  .bulk   $24,$47,$24,$47         ;half brick used for jumpspring
8c50: 82 83 84 85                  .bulk   $82,$83,$84,$85         ;solid block (water level, green rock)
8c54: 24 47 24 47                  .bulk   $24,$47,$24,$47         ;half brick (???)
8c58: 86 8a 87 8b                  .bulk   $86,$8a,$87,$8b         ;water pipe top
8c5c: 8e 91 8f 92                  .bulk   $8e,$91,$8f,$92         ;water pipe bottom
8c60: 24 2f 24 3d                  .bulk   $24,$2f,$24,$3d         ;flag ball (residual object)
8c64: 24 24 24 35  Palette2_MTiles .bulk   $24,$24,$24,$35         ;cloud left
8c68: 36 25 37 25                  .bulk   $36,$25,$37,$25         ;cloud middle
8c6c: 24 38 24 24                  .bulk   $24,$38,$24,$24         ;cloud right
8c70: 24 24 39 24                  .bulk   $24,$24,$39,$24         ;cloud bottom left
8c74: 3a 24 3b 24                  .bulk   $3a,$24,$3b,$24         ;cloud bottom middle
8c78: 3c 24 24 24                  .bulk   $3c,$24,$24,$24         ;cloud bottom right
8c7c: 41 26 41 26                  .bulk   $41,$26,$41,$26         ;water/lava top
8c80: 26 26 26 26                  .bulk   $26,$26,$26,$26         ;water/lava
8c84: b0 b1 b2 b3                  .bulk   $b0,$b1,$b2,$b3         ;cloud level terrain
8c88: 77 79 77 79                  .bulk   $77,$79,$77,$79         ;bowser's bridge
8c8c: 53 55 54 56  Palette3_MTiles .bulk   $53,$55,$54,$56         ;question block (coin)
8c90: 53 55 54 56                  .bulk   $53,$55,$54,$56         ;question block (power-up)
8c94: a5 a7 a6 a8                  .bulk   $a5,$a7,$a6,$a8         ;coin
8c98: c2 c4 c3 c5                  .bulk   $c2,$c4,$c3,$c5         ;underwater coin
8c9c: 57 59 58 5a                  .bulk   $57,$59,$58,$5a         ;empty block
8ca0: 7b 7d 7c 7e                  .bulk   $7b,$7d,$7c,$7e         ;axe
                   ; -----------------------------------------------------------------------------
                   ; VRAM BUFFER DATA FOR LOCATIONS IN PRG-ROM
                   WaterPaletteData
8ca4: 3f 00 20                     .bulk   $3f,$00,$20
8ca7: 0f 15 12 25                  .bulk   $0f,$15,$12,$25
8cab: 0f 3a 1a 0f                  .bulk   $0f,$3a,$1a,$0f
8caf: 0f 30 12 0f                  .bulk   $0f,$30,$12,$0f
8cb3: 0f 27 12 0f                  .bulk   $0f,$27,$12,$0f
8cb7: 22 16 27 18                  .bulk   $22,$16,$27,$18
8cbb: 0f 10 30 27                  .bulk   $0f,$10,$30,$27
8cbf: 0f 16 30 27                  .bulk   $0f,$16,$30,$27
8cc3: 0f 0f 30 10                  .bulk   $0f,$0f,$30,$10
8cc7: 00                           .bulk   $00
                   GroundPaletteData
8cc8: 3f 00 20                     .bulk   $3f,$00,$20
8ccb: 0f 29 1a 0f                  .bulk   $0f,$29,$1a,$0f
8ccf: 0f 36 17 0f                  .bulk   $0f,$36,$17,$0f
8cd3: 0f 30 21 0f                  .bulk   $0f,$30,$21,$0f
8cd7: 0f 27 17 0f                  .bulk   $0f,$27,$17,$0f
8cdb: 0f 16 27 18                  .bulk   $0f,$16,$27,$18
8cdf: 0f 1a 30 27                  .bulk   $0f,$1a,$30,$27
8ce3: 0f 16 30 27                  .bulk   $0f,$16,$30,$27
8ce7: 0f 0f 36 17                  .bulk   $0f,$0f,$36,$17
8ceb: 00                           .bulk   $00
                   UndergroundPaletteData
8cec: 3f 00 20                     .bulk   $3f,$00,$20
8cef: 0f 29 1a 09                  .bulk   $0f,$29,$1a,$09
8cf3: 0f 3c 1c 0f                  .bulk   $0f,$3c,$1c,$0f
8cf7: 0f 30 21 1c                  .bulk   $0f,$30,$21,$1c
8cfb: 0f 27 17 1c                  .bulk   $0f,$27,$17,$1c
8cff: 0f 16 27 18                  .bulk   $0f,$16,$27,$18
8d03: 0f 1c 36 17                  .bulk   $0f,$1c,$36,$17
8d07: 0f 16 30 27                  .bulk   $0f,$16,$30,$27
8d0b: 0f 0c 3c 1c                  .bulk   $0f,$0c,$3c,$1c
8d0f: 00                           .bulk   $00
                   CastlePaletteData
8d10: 3f 00 20                     .bulk   $3f,$00,$20
8d13: 0f 30 10 00                  .bulk   $0f,$30,$10,$00
8d17: 0f 30 10 00                  .bulk   $0f,$30,$10,$00
8d1b: 0f 30 16 00                  .bulk   $0f,$30,$16,$00
8d1f: 0f 27 17 00                  .bulk   $0f,$27,$17,$00
8d23: 0f 16 27 18                  .bulk   $0f,$16,$27,$18
8d27: 0f 1c 36 17                  .bulk   $0f,$1c,$36,$17
8d2b: 0f 16 30 27                  .bulk   $0f,$16,$30,$27
8d2f: 0f 00 30 10                  .bulk   $0f,$00,$30,$10
8d33: 00                           .bulk   $00
                   DaySnowPaletteData
8d34: 3f 00 04                     .bulk   $3f,$00,$04
8d37: 22 30 00 10                  .bulk   $22,$30,$00,$10
8d3b: 00                           .bulk   $00
                   NightSnowPaletteData
8d3c: 3f 00 04                     .bulk   $3f,$00,$04
8d3f: 0f 30 00 10                  .bulk   $0f,$30,$00,$10
8d43: 00                           .bulk   $00
                   MushroomPaletteData
8d44: 3f 00 04                     .bulk   $3f,$00,$04
8d47: 22 27 16 0f                  .bulk   $22,$27,$16,$0f
8d4b: 00                           .bulk   $00
                   BowserPaletteData
8d4c: 3f 14 04                     .bulk   $3f,$14,$04
8d4f: 0f 1a 30 27+                 .bulk   $0f,$1a,$30,$27,$00
                   ; "THANK YOU MARIO"
                   MarioThanksMessage
8d54: 25 48 10                     .bulk   $25,$48,$10
8d57: 1d 11 0a 17+                 .bulk   $1d,$11,$0a,$17,$14,$24
8d5d: 22 18 1e 24                  .bulk   $22,$18,$1e,$24
8d61: 16 0a 1b 12+                 .bulk   $16,$0a,$1b,$12,$18,$2b
8d67: 00                           .dd1    $00
                   ; THANK YOU LUIGI
                   LuigiThanksMessage
8d68: 25 48 10                     .bulk   $25,$48,$10
8d6b: 1d 11 0a 17+                 .bulk   $1d,$11,$0a,$17,$14,$24
8d71: 22 18 1e 24                  .bulk   $22,$18,$1e,$24
8d75: 15 1e 12 10+                 .bulk   $15,$1e,$12,$10,$12,$2b
8d7b: 00                           .dd1    $00
                   ; "BUT OUR PRINCESS IS IN"
                   MushroomRetainerSaved
8d7c: 25 c5 16                     .bulk   $25,$c5,$16
8d7f: 0b 1e 1d 24+                 .bulk   $0b,$1e,$1d,$24,$18,$1e,$1b,$24
8d87: 19 1b 12 17+                 .bulk   $19,$1b,$12,$17,$0c,$0e,$1c,$1c,$24
8d90: 12 1c 24 12+                 .bulk   $12,$1c,$24,$12,$17
                   ; "ANOTHER CASTLE!"
8d95: 26 05 0f                     .bulk   $26,$05,$0f
8d98: 0a 17 18 1d+                 .bulk   $0a,$17,$18,$1d,$11,$0e,$1b,$24
8da0: 0c 0a 1c 1d+                 .bulk   $0c,$0a,$1c,$1d,$15,$0e,$2b,$00
                   ; "YOUR QUEST IS OVER."
8da8: 25 a7 13     PrincessSaved1  .bulk   $25,$a7,$13
8dab: 22 18 1e 1b+                 .bulk   $22,$18,$1e,$1b,$24
8db0: 1a                           .dd1    $1a
8db1: 1e 0e 1c 1d+                 .bulk   $1e,$0e,$1c,$1d,$24
8db6: 12 1c 24 18+                 .bulk   $12,$1c,$24,$18,$1f,$0e,$1b,$af
8dbe: 00                           .dd1    $00
                   ; "WE PRESENT YOU A NEW QUEST."
8dbf: 25 e3 1b     PrincessSaved2  .bulk   $25,$e3,$1b
8dc2: 20 0e 24                     .bulk   $20,$0e,$24
8dc5: 19 1b 0e 1c+                 .bulk   $19,$1b,$0e,$1c,$0e,$17,$1d,$24
8dcd: 22 18 1e 24+                 .bulk   $22,$18,$1e,$24,$0a,$24,$17,$0e,$20,$24
8dd7: 1a 1e 0e 1c+                 .bulk   $1a,$1e,$0e,$1c,$1d,$af
8ddd: 00                           .dd1    $00
                   ; "PUSH BUTTON B"
                   WorldSelectMessage1
8dde: 26 4a 0d                     .bulk   $26,$4a,$0d
8de1: 19 1e 1c 11+                 .bulk   $19,$1e,$1c,$11,$24
8de6: 0b 1e 1d 1d+                 .bulk   $0b,$1e,$1d,$1d,$18,$17,$24,$0b
8dee: 00                           .dd1    $00
                   ; "TO SELECT A WORLD"
                   WorldSelectMessage2
8def: 26 88 11                     .bulk   $26,$88,$11
8df2: 1d 18 24 1c+                 .bulk   $1d,$18,$24,$1c,$0e,$15,$0e,$0c,$1d,$24
8dfc: 0a 24 20 18+                 .bulk   $0a,$24,$20,$18,$1b,$15,$0d
8e03: 00                           .dd1    $00

                   ; -----------------------------------------------------------------------------
                   ; $04 - address low to jump address
                   ; $05 - address high to jump address
                   ; $06 - jump address low
                   ; $07 - jump address high
8e04: 0a           JumpEngine      asl     A                       ;shift bit from contents of A
8e05: a8                           tay
8e06: 68                           pla                             ;pull saved return address from stack
8e07: 85 04                        sta     $04                     ;save to indirect
8e09: 68                           pla
8e0a: 85 05                        sta     $05
8e0c: c8                           iny
8e0d: b1 04                        lda     ($04),y                 ;load pointer from indirect
8e0f: 85 06                        sta     $06                     ;note that if an RTS is performed in next routine
8e11: c8                           iny                             ;it will return to the execution before the sub
8e12: b1 04                        lda     ($04),y                 ; that called this routine
8e14: 85 07                        sta     $07
8e16: 6c 06 00                     jmp     ($0006)                 ;jump to the address we loaded

                   ; -----------------------------------------------------------------------------
                   InitializeNameTables
8e19: ad 02 20                     lda     PPUSTATUS               ;reset flip-flop
8e1c: ad 78 07                     lda     Mirror_PPU_CTRL_REG1    ;load mirror of ppu reg $2000
8e1f: 09 10                        ora     #%00010000              ;set sprites for first 4k and background for second 4k
8e21: 29 f0                        and     #%11110000              ;clear rest of lower nybble, leave higher alone
8e23: 20 ed 8e                     jsr     WritePPUReg1
8e26: a9 24                        lda     #$24                    ;set vram address to start of name table 1
8e28: 20 2d 8e                     jsr     WriteNTAddr
8e2b: a9 20                        lda     #$20                    ;and then set it to name table 0
8e2d: 8d 06 20     WriteNTAddr     sta     PPUADDR
8e30: a9 00                        lda     #$00
8e32: 8d 06 20                     sta     PPUADDR
8e35: a2 04                        ldx     #$04                    ;clear name table with blank tile #24
8e37: a0 c0                        ldy     #$c0
8e39: a9 24                        lda     #$24
8e3b: 8d 07 20     InitNTLoop      sta     PPUDATA                 ;count out exactly 768 tiles
8e3e: 88                           dey
8e3f: d0 fa                        bne     InitNTLoop
8e41: ca                           dex
8e42: d0 f7                        bne     InitNTLoop
8e44: a0 40                        ldy     #64                     ;now to clear the attribute table (with zero this time)
8e46: 8a                           txa
8e47: 8d 00 03                     sta     VRAM_Buffer1_Offset     ;init vram buffer 1 offset
8e4a: 8d 01 03                     sta     VRAM_Buffer1            ;init vram buffer 1
8e4d: 8d 07 20     InitATLoop      sta     PPUDATA
8e50: 88                           dey
8e51: d0 fa                        bne     InitATLoop
8e53: 8d 3f 07                     sta     HorizontalScroll        ;reset scroll variables
8e56: 8d 40 07                     sta     VerticalScroll
8e59: 4c e6 8e                     jmp     InitScroll              ;initialize scroll registers to zero

                   ; -----------------------------------------------------------------------------
                   ; $00 - temp joypad bit
8e5c: a9 01        ReadJoypads     lda     #$01                    ;reset and clear strobe of joypad ports
8e5e: 8d 16 40                     sta     JOY1
8e61: 4a                           lsr     A
8e62: aa                           tax                             ;start with joypad 1's port
8e63: 8d 16 40                     sta     JOY1
8e66: 20 6a 8e                     jsr     ReadPortBits
8e69: e8                           inx                             ;increment for joypad 2's port
8e6a: a0 08        ReadPortBits    ldy     #$08
8e6c: 48           PortLoop        pha                             ;push previous bit onto stack
8e6d: bd 16 40                     lda     JOY1,x                  ;read current bit on joypad port
8e70: 85 00                        sta     $00                     ;check d1 and d0 of port output
8e72: 4a                           lsr     A                       ;this is necessary on the old
8e73: 05 00                        ora     $00                     ; famicom systems in japan
8e75: 4a                           lsr     A
8e76: 68                           pla                             ;read bits from stack
8e77: 2a                           rol     A                       ;rotate bit from carry flag
8e78: 88                           dey
8e79: d0 f1                        bne     PortLoop                ;count down bits left
8e7b: 9d fc 06                     sta     SavedJoypad1Bits,x      ;save controller status here always
8e7e: 48                           pha
8e7f: 29 30                        and     #%00110000              ;check for select or start
8e81: 3d 4a 07                     and     JoypadBitMask,x         ;if neither saved state nor current state
8e84: f0 07                        beq     Save8Bits               ; have any of these two set, branch
8e86: 68                           pla
8e87: 29 cf                        and     #%11001111              ;otherwise store without select
8e89: 9d fc 06                     sta     SavedJoypad1Bits,x      ; or start bits and leave
8e8c: 60                           rts

8e8d: 68           Save8Bits       pla
8e8e: 9d 4a 07                     sta     JoypadBitMask,x         ;save with all bits in another place and leave
8e91: 60                           rts

                   ; -----------------------------------------------------------------------------
                   ; $00 - vram buffer address table low
                   ; $01 - vram buffer address table high
                   WriteBufferToScreen
8e92: 8d 06 20                     sta     PPUADDR                 ;store high byte of vram address
8e95: c8                           iny
8e96: b1 00                        lda     ($00),y                 ;load next byte (second)
8e98: 8d 06 20                     sta     PPUADDR                 ;store low byte of vram address
8e9b: c8                           iny
8e9c: b1 00                        lda     ($00),y                 ;load next byte (third)
8e9e: 0a                           asl     A                       ;shift to left and save in stack
8e9f: 48                           pha
8ea0: ad 78 07                     lda     Mirror_PPU_CTRL_REG1    ;load mirror of $2000,
8ea3: 09 04                        ora     #%00000100              ;set ppu to increment by 32 by default
8ea5: b0 02                        bcs     SetupWrites             ;if d7 of third byte was clear, ppu will
8ea7: 29 fb                        and     #%11111011              ;only increment by 1
8ea9: 20 ed 8e     SetupWrites     jsr     WritePPUReg1            ;write to register
8eac: 68                           pla                             ;pull from stack and shift to left again
8ead: 0a                           asl     A
8eae: 90 03                        bcc     GetLength               ;if d6 of third byte was clear, do not repeat byte
8eb0: 09 02                        ora     #%00000010              ;otherwise set d1 and increment Y
8eb2: c8                           iny
8eb3: 4a           GetLength       lsr     A                       ;shift back to the right to get proper length
8eb4: 4a                           lsr     A                       ;note that d1 will now be in carry
8eb5: aa                           tax
8eb6: b0 01        OutputToVRAM    bcs     RepeatByte              ;if carry set, repeat loading the same byte
8eb8: c8                           iny                             ;otherwise increment Y to load next byte
8eb9: b1 00        RepeatByte      lda     ($00),y                 ;load more data from buffer and write to vram
8ebb: 8d 07 20                     sta     PPUDATA
8ebe: ca                           dex                             ;done writing?
8ebf: d0 f5                        bne     OutputToVRAM
8ec1: 38                           sec
8ec2: 98                           tya
8ec3: 65 00                        adc     $00                     ;add end length plus one to the indirect at $00
8ec5: 85 00                        sta     $00                     ; to allow this routine to read another set of updates
8ec7: a9 00                        lda     #$00
8ec9: 65 01                        adc     $01
8ecb: 85 01                        sta     $01
8ecd: a9 3f                        lda     #$3f                    ;sets vram address to $3f00
8ecf: 8d 06 20                     sta     PPUADDR
8ed2: a9 00                        lda     #$00
8ed4: 8d 06 20                     sta     PPUADDR
8ed7: 8d 06 20                     sta     PPUADDR                 ;then reinitializes it for some reason
8eda: 8d 06 20                     sta     PPUADDR
8edd: ae 02 20     UpdateScreen    ldx     PPUSTATUS               ;reset flip-flop
8ee0: a0 00                        ldy     #$00                    ;load first byte from indirect as a pointer
8ee2: b1 00                        lda     ($00),y
8ee4: d0 ac                        bne     WriteBufferToScreen     ;if byte is zero we have no further updates to make here
8ee6: 8d 05 20     InitScroll      sta     PPUSCROLL               ;store contents of A into scroll registers
8ee9: 8d 05 20                     sta     PPUSCROLL               ;and end whatever subroutine led us here
8eec: 60                           rts

                   ; -----------------------------------------------------------------------------
8eed: 8d 00 20     WritePPUReg1    sta     PPUCTRL                 ;write contents of A to PPU register 1
8ef0: 8d 78 07                     sta     Mirror_PPU_CTRL_REG1    ;and its mirror
8ef3: 60                           rts

                   ; -----------------------------------------------------------------------------
                   ; $00 - used to store status bar nybbles
                   ; $02 - used as temp vram offset
                   ; $03 - used to store length of status bar number
                   ; 
                   ; status bar name table offset and length data
8ef4: f0 06        StatusBarData   .bulk   $f0,$06                 ;top score display on title screen
8ef6: 62 06                        .bulk   $62,$06                 ;player score
8ef8: 62 06                        .bulk   $62,$06
8efa: 6d 02                        .bulk   $6d,$02                 ;coin tally
8efc: 6d 02                        .bulk   $6d,$02
8efe: 7a 03                        .bulk   $7a,$03                 ;game timer
8f00: 06 0c 12 18+ StatusBarOffset .bulk   $06,$0c,$12,$18,$1e,$24

                   PrintStatusBarNumbers
8f06: 85 00                        sta     $00                     ;store player-specific offset
8f08: 20 11 8f                     jsr     OutputNumbers           ;use first nybble to print the coin display
8f0b: a5 00                        lda     $00                     ;move high nybble to low
8f0d: 4a                           lsr     A                       ;and print to score display
8f0e: 4a                           lsr     A
8f0f: 4a                           lsr     A
8f10: 4a                           lsr     A
8f11: 18           OutputNumbers   clc                             ;add 1 to low nybble
8f12: 69 01                        adc     #$01
8f14: 29 0f                        and     #%00001111              ;mask out high nybble
8f16: c9 06                        cmp     #$06
8f18: b0 44                        bcs     ExitOutputN
8f1a: 48                           pha                             ;save incremented value to stack for now and
8f1b: 0a                           asl     A                       ;shift to left and use as offset
8f1c: a8                           tay
8f1d: ae 00 03                     ldx     VRAM_Buffer1_Offset     ;get current buffer pointer
8f20: a9 20                        lda     #$20                    ;put at top of screen by default
8f22: c0 00                        cpy     #$00                    ;are we writing top score on title screen?
8f24: d0 02                        bne     SetupNums
8f26: a9 22                        lda     #$22                    ;if so, put further down on the screen
8f28: 9d 01 03     SetupNums       sta     VRAM_Buffer1,x
8f2b: b9 f4 8e                     lda     StatusBarData,y         ;write low vram address and length of thing
8f2e: 9d 02 03                     sta     VRAM_Buffer1+1,x        ;we're printing to the buffer
8f31: b9 f5 8e                     lda     StatusBarData+1,y
8f34: 9d 03 03                     sta     VRAM_Buffer1+2,x
8f37: 85 03                        sta     $03                     ;save length byte in counter
8f39: 86 02                        stx     $02                     ;and buffer pointer elsewhere for now
8f3b: 68                           pla                             ;pull original incremented value from stack
8f3c: aa                           tax
8f3d: bd 00 8f                     lda     StatusBarOffset,x       ;load offset to value we want to write
8f40: 38                           sec
8f41: f9 f5 8e                     sbc     StatusBarData+1,y       ;subtract from length byte we read before
8f44: a8                           tay                             ;use value as offset to display digits
8f45: a6 02                        ldx     $02
8f47: b9 d7 07     DigitPLoop      lda     TopScoreDisplay,y       ;write digits to the buffer
8f4a: 9d 04 03                     sta     VRAM_Buffer1+3,x
8f4d: e8                           inx
8f4e: c8                           iny
8f4f: c6 03                        dec     $03                     ;do this until all the digits are written
8f51: d0 f4                        bne     DigitPLoop
8f53: a9 00                        lda     #$00                    ;put null terminator at end
8f55: 9d 04 03                     sta     VRAM_Buffer1+3,x
8f58: e8                           inx                             ;increment buffer pointer by 3
8f59: e8                           inx
8f5a: e8                           inx
8f5b: 8e 00 03                     stx     VRAM_Buffer1_Offset     ;store it in case we want to use it again
8f5e: 60           ExitOutputN     rts

                   ; -----------------------------------------------------------------------------
                   DigitsMathRoutine
8f5f: ad 70 07                     lda     OperMode                ;check mode of operation
8f62: c9 00                        cmp     #$00
8f64: f0 16                        beq     EraseDMods              ;if in title screen mode, branch to lock score
8f66: a2 05                        ldx     #$05
8f68: bd 34 01     AddModLoop      lda     DigitModifier,x         ;load digit amount to increment
8f6b: 18                           clc
8f6c: 79 d7 07                     adc     TopScoreDisplay,y       ;add to current digit
8f6f: 30 16                        bmi     BorrowOne               ;if result is a negative number, branch to subtract
8f71: c9 0a                        cmp     #$0a
8f73: b0 19                        bcs     CarryOne                ;if digit greater than $09, branch to add
8f75: 99 d7 07     StoreNewD       sta     TopScoreDisplay,y       ;store as new score or game timer digit
8f78: 88                           dey                             ;move onto next digits in score or game timer
8f79: ca                           dex                             ;and digit amounts to increment
8f7a: 10 ec                        bpl     AddModLoop              ;loop back if we're not done yet
8f7c: a9 00        EraseDMods      lda     #$00                    ;store zero here
8f7e: a2 06                        ldx     #$06                    ;start with the last digit
8f80: 9d 33 01     EraseMLoop      sta     DigitModifier-1,x       ;initialize the digit amounts to increment
8f83: ca                           dex
8f84: 10 fa                        bpl     EraseMLoop              ;do this until they're all reset, then leave
8f86: 60                           rts

8f87: de 33 01     BorrowOne       dec     DigitModifier-1,x       ;decrement the previous digit, then put $09 in
8f8a: a9 09                        lda     #$09                    ; the game timer digit we're currently on to "borrow
8f8c: d0 e7                        bne     StoreNewD               ; the one", then do an unconditional branch back

8f8e: 38           CarryOne        sec                             ;subtract ten from our digit to make it a
8f8f: e9 0a                        sbc     #$0a                    ; proper BCD number, then increment the digit
8f91: fe 33 01                     inc     DigitModifier-1,x       ; preceding current digit to "carry the one" properly
8f94: 4c 75 8f                     jmp     StoreNewD               ;go back to just after we branched here

                   ; -----------------------------------------------------------------------------
8f97: a2 05        UpdateTopScore  ldx     #$05                    ;start with mario's score
8f99: 20 9e 8f                     jsr     TopScoreCheck
8f9c: a2 0b                        ldx     #$0b                    ;now do luigi's score
8f9e: a0 05        TopScoreCheck   ldy     #$05                    ;start with the lowest digit
8fa0: 38                           sec
8fa1: bd dd 07     GetScoreDiff    lda     ScoreAndCoinDisplay,x   ;subtract each player digit from each high score digit
8fa4: f9 d7 07                     sbc     TopScoreDisplay,y       ; from lowest to highest, if any top score digit exceeds
8fa7: ca                           dex                             ; any player digit, borrow will be set until a subsequent
8fa8: 88                           dey                             ; subtraction clears it (player digit is higher than top)
8fa9: 10 f6                        bpl     GetScoreDiff
8fab: 90 0e                        bcc     NoTopSc                 ;check to see if borrow is still set, if so, no new high score
8fad: e8                           inx                             ;increment X and Y once to the start of the score
8fae: c8                           iny
8faf: bd dd 07     CopyScore       lda     ScoreAndCoinDisplay,x   ;store player's score digits into high score memory area
8fb2: 99 d7 07                     sta     TopScoreDisplay,y
8fb5: e8                           inx
8fb6: c8                           iny
8fb7: c0 06                        cpy     #$06                    ;do this until we have stored them all
8fb9: 90 f4                        bcc     CopyScore
8fbb: 60           NoTopSc         rts

                   ; -----------------------------------------------------------------------------
                   DefaultSprOffsets
8fbc: 04 30 48 60+                 .bulk   $04,$30,$48,$60,$78,$90,$a8,$c0,$d8,$e8,$24,$f8,$fc,$28,$2c
8fcb: 18 ff 23 58  Sprite0Data     .bulk   $18,$ff,$23,$58

                   ; -----------------------------------------------------------------------------
8fcf: a0 6f        InitializeGame  ldy     #$6f                    ;clear all memory as in initialization procedure,
8fd1: 20 cc 90                     jsr     InitializeMemory        ; but this time, clear only as far as $076f
8fd4: a0 1f                        ldy     #$1f
8fd6: 99 b0 07     ClrSndLoop      sta     SoundMemory,y           ;clear out memory used
8fd9: 88                           dey                             ; by the sound engines
8fda: 10 fa                        bpl     ClrSndLoop
8fdc: a9 18                        lda     #$18                    ;set demo timer
8fde: 8d a2 07                     sta     DemoTimer
8fe1: 20 03 9c                     jsr     LoadAreaPointer
                   ; 
8fe4: a0 4b        InitializeArea  ldy     #$4b                    ;clear all memory again, only as far as $074b
8fe6: 20 cc 90                     jsr     InitializeMemory        ;this is only necessary if branching from
8fe9: a2 21                        ldx     #$21
8feb: a9 00                        lda     #$00
8fed: 9d 80 07     ClrTimersLoop   sta     Timers,x                ;clear out memory between
8ff0: ca                           dex                             ; $0780 and $07a1
8ff1: 10 fa                        bpl     ClrTimersLoop
8ff3: ad 5b 07                     lda     HalfwayPage
8ff6: ac 52 07                     ldy     AltEntranceControl      ;if AltEntranceControl not set, use halfway page, if any found
8ff9: f0 03                        beq     StartPage
8ffb: ad 51 07                     lda     EntrancePage            ;otherwise use saved entry page number here
8ffe: 8d 1a 07     StartPage       sta     ScreenLeft_PageLoc      ;set as value here
9001: 8d 25 07                     sta     CurrentPageLoc          ;also set as current page
9004: 8d 28 07                     sta     BackloadingFlag         ;set flag here if halfway page or saved entry page number found
9007: 20 38 b0                     jsr     GetScreenPosition       ;get pixel coordinates for screen borders
900a: a0 20                        ldy     #$20                    ;if on odd numbered page, use $2480 as start of rendering
900c: 29 01                        and     #%00000001              ;otherwise use $2080, this address used later as name table
900e: f0 02                        beq     SetInitNTHigh           ; address for rendering of game area
9010: a0 24                        ldy     #$24
9012: 8c 20 07     SetInitNTHigh   sty     CurrentNTAddr_High      ;store name table address
9015: a0 80                        ldy     #$80
9017: 8c 21 07                     sty     CurrentNTAddr_Low
901a: 0a                           asl     A                       ;store LSB of page number in high nybble
901b: 0a                           asl     A                       ; of block buffer column position
901c: 0a                           asl     A
901d: 0a                           asl     A
901e: 8d a0 06                     sta     BlockBufferColumnPos
9021: ce 30 07                     dec     AreaObjectLength        ;set area object lengths for all empty
9024: ce 31 07                     dec     AreaObjectLength+1
9027: ce 32 07                     dec     AreaObjectLength+2
902a: a9 0b                        lda     #$0b                    ;set value for renderer to update 12 column sets
902c: 8d 1e 07                     sta     ColumnSets              ;12 column sets = 24 metatile columns = 1 1/2 screens
902f: 20 22 9c                     jsr     GetAreaDataAddrs        ;get enemy and level addresses and load header
9032: ad 6a 07                     lda     PrimaryHardMode         ;check to see if primary hard mode has been activated
9035: d0 10                        bne     SetSecHard              ;if so, activate the secondary no matter where we're at
9037: ad 5f 07                     lda     WorldNumber             ;otherwise check world number
903a: c9 04                        cmp     #World5                 ;if less than 5, do not activate secondary
903c: 90 0c                        bcc     CheckHalfway
903e: d0 07                        bne     SetSecHard              ;if not equal to, then world > 5, thus activate
9040: ad 5c 07                     lda     LevelNumber             ;otherwise, world 5, so check level number
9043: c9 02                        cmp     #Level3                 ;if 1 or 2, do not set secondary hard mode flag
9045: 90 03                        bcc     CheckHalfway
9047: ee cc 06     SetSecHard      inc     SecondaryHardMode       ;set secondary hard mode flag for areas 5-3 and beyond
904a: ad 5b 07     CheckHalfway    lda     HalfwayPage
904d: f0 05                        beq     DoneInitArea
904f: a9 02                        lda     #$02                    ;if halfway page set, overwrite start position from header
9051: 8d 10 07                     sta     PlayerEntranceCtrl
9054: a9 80        DoneInitArea    lda     #Silence                ;silence music
9056: 85 fb                        sta     AreaMusicQueue
9058: a9 01                        lda     #$01                    ;disable screen output
905a: 8d 74 07                     sta     DisableScreenFlag
905d: ee 72 07                     inc     OperMode_Task           ;increment one of the modes
9060: 60                           rts

                   ; -----------------------------------------------------------------------------
                   PrimaryGameSetup
9061: a9 01                        lda     #$01
9063: 8d 57 07                     sta     FetchNewGameTimerFlag   ;set flag to load game timer from header
9066: 8d 54 07                     sta     PlayerSize              ;set player's size to small
9069: a9 02                        lda     #$02
906b: 8d 5a 07                     sta     NumberOfLives           ;give each player three lives
906e: 8d 61 07                     sta     OffScr_NumberofLives
                   ; 
                   SecondaryGameSetup
9071: a9 00                        lda     #$00
9073: 8d 74 07                     sta     DisableScreenFlag       ;enable screen output
9076: a8                           tay
9077: 99 00 03     ClearVRLoop     sta     VRAM_Buffer1-1,y        ;clear buffer at $0300-$03ff
907a: c8                           iny
907b: d0 fa                        bne     ClearVRLoop
907d: 8d 59 07                     sta     GameTimerExpiredFlag    ;clear game timer exp flag
9080: 8d 69 07                     sta     DisableIntermediate     ;clear skip lives display flag
9083: 8d 28 07                     sta     BackloadingFlag         ;clear value here
9086: a9 ff                        lda     #$ff
9088: 8d a0 03                     sta     BalPlatformAlignment    ;initialize balance platform assignment flag
908b: ad 1a 07                     lda     ScreenLeft_PageLoc      ;get left side page location
908e: 4e 78 07                     lsr     Mirror_PPU_CTRL_REG1    ;shift LSB of ppu register #1 mirror out
9091: 29 01                        and     #$01                    ;mask out all but LSB of page location
9093: 6a                           ror     A                       ;rotate LSB of page location into carry then onto mirror
9094: 2e 78 07                     rol     Mirror_PPU_CTRL_REG1    ;this is to set the proper PPU name table
9097: 20 ed 90                     jsr     GetAreaMusic            ;load proper music into queue
909a: a9 38                        lda     #$38                    ;load sprite shuffle amounts to be used later
909c: 8d e3 06                     sta     SprShuffleAmt+2
909f: a9 48                        lda     #$48
90a1: 8d e2 06                     sta     SprShuffleAmt+1
90a4: a9 58                        lda     #$58
90a6: 8d e1 06                     sta     SprShuffleAmt
90a9: a2 0e                        ldx     #$0e                    ;load default OAM offsets into $06e4-$06f2
90ab: bd bc 8f     ShufAmtLoop     lda     DefaultSprOffsets,x
90ae: 9d e4 06                     sta     SprDataOffset,x
90b1: ca                           dex                             ;do this until they're all set
90b2: 10 f7                        bpl     ShufAmtLoop
90b4: a0 03                        ldy     #$03                    ;set up sprite #0
90b6: b9 cb 8f     ISpr0Loop       lda     Sprite0Data,y
90b9: 99 00 02                     sta     Sprite_Data,y
90bc: 88                           dey
90bd: 10 f7                        bpl     ISpr0Loop
90bf: 20 af 92                     jsr     DoNothing2              ;these jsrs doesn't do anything useful
90c2: 20 aa 92                     jsr     DoNothing1
90c5: ee 22 07                     inc     Sprite0HitDetectFlag    ;set sprite #0 check flag
90c8: ee 72 07                     inc     OperMode_Task           ;increment to next task
90cb: 60                           rts

                   ; -----------------------------------------------------------------------------
                   ; $06 - RAM address low
                   ; $07 - RAM address high
                   InitializeMemory
90cc: a2 07                        ldx     #$07                    ;set initial high byte to $0700-$07ff
90ce: a9 00                        lda     #$00                    ;set initial low byte to start of page (at $00 of page)
90d0: 85 06                        sta     $06
90d2: 86 07        InitPageLoop    stx     $07
90d4: e0 01        InitByteLoop    cpx     #$01                    ;check to see if we're on the stack ($0100-$01ff)
90d6: d0 04                        bne     InitByte                ;if not, go ahead anyway
90d8: c0 60                        cpy     #$60                    ;otherwise, check to see if we're at $0160-$01ff
90da: b0 02                        bcs     SkipByte                ;if so, skip write
90dc: 91 06        InitByte        sta     ($06),y                 ;otherwise, initialize byte with current low byte in Y
90de: 88           SkipByte        dey
90df: c0 ff                        cpy     #$ff                    ;do this until all bytes in page have been erased
90e1: d0 f1                        bne     InitByteLoop
90e3: ca                           dex                             ;go onto the next page
90e4: 10 ec                        bpl     InitPageLoop            ;do this until all pages of memory have been erased
90e6: 60                           rts

                   ; -----------------------------------------------------------------------------
90e7: 02           MusicSelectData .dd1    WaterMusic
90e8: 01                           .dd1    GroundMusic
90e9: 04                           .dd1    UndergroundMusic
90ea: 08                           .dd1    CastleMusic
90eb: 10                           .dd1    CloudMusic
90ec: 20                           .dd1    PipeIntroMusic

90ed: ad 70 07     GetAreaMusic    lda     OperMode                ;if in title screen mode, leave
90f0: f0 23                        beq     ExitGetM
90f2: ad 52 07                     lda     AltEntranceControl      ;check for specific alternate mode of entry
90f5: c9 02                        cmp     #$02                    ;if found, branch without checking starting position
90f7: f0 0d                        beq     ChkAreaType             ; from area object data header
90f9: a0 05                        ldy     #$05                    ;select music for pipe intro scene by default
90fb: ad 10 07                     lda     PlayerEntranceCtrl      ;check value from level header for certain values
90fe: c9 06                        cmp     #$06
9100: f0 0e                        beq     StoreMusic              ;load music for pipe intro scene if header
9102: c9 07                        cmp     #$07                    ;start position either value $06 or $07
9104: f0 0a                        beq     StoreMusic
9106: ac 4e 07     ChkAreaType     ldy     AreaType                ;load area type as offset for music bit
9109: ad 43 07                     lda     CloudTypeOverride
910c: f0 02                        beq     StoreMusic              ;check for cloud type override
910e: a0 04                        ldy     #$04                    ;select music for cloud type level if found
9110: b9 e7 90     StoreMusic      lda     MusicSelectData,y       ;otherwise select appropriate music for level type
9113: 85 fb                        sta     AreaMusicQueue          ;store in queue and leave
9115: 60           ExitGetM        rts

                   ; -----------------------------------------------------------------------------
                   PlayerStarting_X_Pos
9116: 28 18 38 28                  .bulk   $28,$18,$38,$28
911a: 08 00        AltYPosOffset   .bulk   $08,$00
                   PlayerStarting_Y_Pos
911c: 00 20 b0 50+                 .bulk   $00,$20,$b0,$50,$00,$00,$b0,$b0,$f0
                   PlayerBGPriorityData
9125: 00 20 00 00+                 .bulk   $00,$20,$00,$00,$00,$00,$00,$00
912d: 20           GameTimerData   .dd1    $20                     ;dummy byte, used as part of bg priority data
912e: 04 03 02                     .bulk   $04,$03,$02

                   Entrance_GameTimerSetup
9131: ad 1a 07                     lda     ScreenLeft_PageLoc      ;set current page for area objects
9134: 85 6d                        sta     Player_PageLoc          ; as page location for player
9136: a9 28                        lda     #$28                    ;store value here
9138: 8d 0a 07                     sta     VerticalForceDown       ;for fractional movement downwards if necessary
913b: a9 01                        lda     #$01                    ;set high byte of player position and
913d: 85 33                        sta     PlayerFacingDir         ;set facing direction so that player faces right
913f: 85 b5                        sta     Player_Y_HighPos
9141: a9 00                        lda     #$00                    ;set player state to on the ground by default
9143: 85 1d                        sta     Player_State
9145: ce 90 04                     dec     Player_CollisionBits    ;initialize player's collision bits
9148: a0 00                        ldy     #$00                    ;initialize halfway page
914a: 8c 5b 07                     sty     HalfwayPage
914d: ad 4e 07                     lda     AreaType                ;check area type
9150: d0 01                        bne     ChkStPos                ;if water type, set swimming flag, otherwise do not set
9152: c8                           iny
9153: 8c 04 07     ChkStPos        sty     SwimmingFlag
9156: ae 10 07                     ldx     PlayerEntranceCtrl      ;get starting position loaded from header
9159: ac 52 07                     ldy     AltEntranceControl      ;check alternate mode of entry flag for 0 or 1
915c: f0 07                        beq     SetStPos
915e: c0 01                        cpy     #$01
9160: f0 03                        beq     SetStPos
9162: be 18 91                     ldx     AltYPosOffset-2,y       ;if not 0 or 1, override $0710 with new offset in X
9165: b9 16 91     SetStPos        lda     PlayerStarting_X_Pos,y  ;load appropriate horizontal position
9168: 85 86                        sta     Player_X_Position       ; and vertical positions for the player, using
916a: bd 1c 91                     lda     PlayerStarting_Y_Pos,x  ; AltEntranceControl as offset for horizontal and either $0710
916d: 85 ce                        sta     Player_Y_Position       ; or value that overwrote $0710 as offset for vertical
916f: bd 25 91                     lda     PlayerBGPriorityData,x
9172: 8d c4 03                     sta     Player_SprAttrib        ;set player sprite attributes using offset in X
9175: 20 f1 85                     jsr     GetPlayerColors         ;get appropriate player palette
9178: ac 15 07                     ldy     GameTimerSetting        ;get timer control value from header
917b: f0 1a                        beq     ChkOverR                ;if set to zero, branch (do not use dummy byte for this)
917d: ad 57 07                     lda     FetchNewGameTimerFlag   ;do we need to set the game timer? if not, use 
9180: f0 15                        beq     ChkOverR                ; old game timer setting
9182: b9 2d 91                     lda     GameTimerData,y         ;if game timer is set and game timer flag is also set,
9185: 8d f8 07                     sta     GameTimerDisplay        ; use value of game timer control for first digit of game timer
9188: a9 01                        lda     #$01
918a: 8d fa 07                     sta     GameTimerDisplay+2      ;set last digit of game timer to 1
918d: 4a                           lsr     A
918e: 8d f9 07                     sta     GameTimerDisplay+1      ;set second digit of game timer
9191: 8d 57 07                     sta     FetchNewGameTimerFlag   ;clear flag for game timer reset
9194: 8d 9f 07                     sta     StarInvincibleTimer     ;clear star mario timer
9197: ac 58 07     ChkOverR        ldy     JoypadOverride          ;if controller bits not set, branch to skip this part
919a: f0 14                        beq     ChkSwimE
919c: a9 03                        lda     #$03                    ;set player state to climbing
919e: 85 1d                        sta     Player_State
91a0: a2 00                        ldx     #$00                    ;set offset for first slot, for block object
91a2: 20 84 bd                     jsr     InitBlock_XY_Pos
91a5: a9 f0                        lda     #$f0                    ;set vertical coordinate for block object
91a7: 85 d7                        sta     Block_Y_Position
91a9: a2 05                        ldx     #$05                    ;set offset in X for last enemy object buffer slot
91ab: a0 00                        ldy     #$00                    ;set offset in Y for object coordinates used earlier
91ad: 20 1e b9                     jsr     Setup_Vine              ;do a sub to grow vine
91b0: ac 4e 07     ChkSwimE        ldy     AreaType                ;if level not water-type,
91b3: d0 03                        bne     SetPESub                ; skip this subroutine
91b5: 20 0b b7                     jsr     SetupBubble             ;otherwise, execute sub to set up air bubbles
91b8: a9 07        SetPESub        lda     #$07                    ;set to run player entrance subroutine
91ba: 85 0e                        sta     GameEngineSubroutine    ; on the next frame of game engine
91bc: 60                           rts

                   ; -----------------------------------------------------------------------------
                   ; 
                   ; page numbers are in order from -1 to -4
                   HalfwayPageNybbles
91bd: 56 40                        .bulk   $56,$40
91bf: 65 70                        .bulk   $65,$70
91c1: 66 40                        .bulk   $66,$40
91c3: 66 40                        .bulk   $66,$40
91c5: 66 40                        .bulk   $66,$40
91c7: 66 60                        .bulk   $66,$60
91c9: 65 70                        .bulk   $65,$70
91cb: 00 00                        .bulk   $00,$00

91cd: ee 74 07     PlayerLoseLife  inc     DisableScreenFlag       ;disable screen and sprite 0 check
91d0: a9 00                        lda     #$00
91d2: 8d 22 07                     sta     Sprite0HitDetectFlag
91d5: a9 80                        lda     #Silence                ;silence music
91d7: 85 fc                        sta     EventMusicQueue
91d9: ce 5a 07                     dec     NumberOfLives           ;take one life from player
91dc: 10 0b                        bpl     StillInGame             ;if player still has lives, branch
91de: a9 00                        lda     #$00
91e0: 8d 72 07                     sta     OperMode_Task           ;initialize mode task,
91e3: a9 03                        lda     #GameOverModeValue      ;switch to game over mode
91e5: 8d 70 07                     sta     OperMode                ;and leave
91e8: 60                           rts

91e9: ad 5f 07     StillInGame     lda     WorldNumber             ;multiply world number by 2 and use
91ec: 0a                           asl     A                       ; as offset
91ed: aa                           tax
91ee: ad 5c 07                     lda     LevelNumber             ;if in area -3 or -4, increment
91f1: 29 02                        and     #$02                    ; offset by one byte, otherwise
91f3: f0 01                        beq     GetHalfway              ; leave offset alone
91f5: e8                           inx
91f6: bc bd 91     GetHalfway      ldy     HalfwayPageNybbles,x    ;get halfway page number with offset
91f9: ad 5c 07                     lda     LevelNumber             ;check area number's LSB
91fc: 4a                           lsr     A
91fd: 98                           tya                             ;if in area -2 or -4, use lower nybble
91fe: b0 04                        bcs     MaskHPNyb
9200: 4a                           lsr     A                       ;move higher nybble to lower if area
9201: 4a                           lsr     A                       ; number is -1 or -3
9202: 4a                           lsr     A
9203: 4a                           lsr     A
9204: 29 0f        MaskHPNyb       and     #%00001111              ;mask out all but lower nybble
9206: cd 1a 07                     cmp     ScreenLeft_PageLoc
9209: f0 04                        beq     SetHalfway              ;left side of screen must be at the halfway page,
920b: 90 02                        bcc     SetHalfway              ; otherwise player must start at the
920d: a9 00                        lda     #$00                    ;beginning of the level
920f: 8d 5b 07     SetHalfway      sta     HalfwayPage             ;store as halfway page for player
9212: 20 82 92                     jsr     TransposePlayers        ;switch players around if 2-player game
9215: 4c 64 92                     jmp     ContinueGame            ;continue the game

                   ; -----------------------------------------------------------------------------
9218: ad 72 07     GameOverMode    lda     OperMode_Task
921b: 20 04 8e                     jsr     JumpEngine

921e: 24 92                        .dd2    SetupGameOver
9220: 67 85                        .dd2    ScreenRoutines
9222: 37 92                        .dd2    RunGameOver

                   ; -----------------------------------------------------------------------------
9224: a9 00        SetupGameOver   lda     #$00                    ;reset screen routine task control for title screen, game,
9226: 8d 3c 07                     sta     ScreenRoutineTask       ; and game over modes
9229: 8d 22 07                     sta     Sprite0HitDetectFlag    ;disable sprite 0 check
922c: a9 02                        lda     #GameOverMusic
922e: 85 fc                        sta     EventMusicQueue         ;put game over music in secondary queue
9230: ee 74 07                     inc     DisableScreenFlag       ;disable screen output
9233: ee 72 07                     inc     OperMode_Task           ;set secondary mode to 1
9236: 60                           rts

                   ; -----------------------------------------------------------------------------
9237: a9 00        RunGameOver     lda     #$00                    ;reenable screen
9239: 8d 74 07                     sta     DisableScreenFlag
923c: ad fc 06                     lda     SavedJoypad1Bits        ;check controller for start pressed
923f: 29 10                        and     #Start_Button
9241: d0 05                        bne     TerminateGame
9243: ad a0 07                     lda     ScreenTimer             ;if not pressed, wait for
9246: d0 39                        bne     GameIsOn                ; screen timer to expire
9248: a9 80        TerminateGame   lda     #Silence                ;silence music
924a: 85 fc                        sta     EventMusicQueue
924c: 20 82 92                     jsr     TransposePlayers        ;check if other player can keep
924f: 90 13                        bcc     ContinueGame            ; going, and do so if possible
9251: ad 5f 07                     lda     WorldNumber             ;otherwise put world number of current
9254: 8d fd 07                     sta     ContinueWorld           ; player into secret continue function variable
9257: a9 00                        lda     #$00
9259: 0a                           asl     A                       ;residual ASL instruction
925a: 8d 72 07                     sta     OperMode_Task           ;reset all modes to title screen and
925d: 8d a0 07                     sta     ScreenTimer             ; leave
9260: 8d 70 07                     sta     OperMode
9263: 60                           rts

9264: 20 03 9c     ContinueGame    jsr     LoadAreaPointer         ;update level pointer with
9267: a9 01                        lda     #$01                    ; actual world and area numbers, then
9269: 8d 54 07                     sta     PlayerSize              ; reset player's size, status, and
926c: ee 57 07                     inc     FetchNewGameTimerFlag   ; set game timer flag to reload
926f: a9 00                        lda     #$00                    ; game timer from header
9271: 8d 47 07                     sta     TimerControl            ;also set flag for timers to count again
9274: 8d 56 07                     sta     PlayerStatus
9277: 85 0e                        sta     GameEngineSubroutine    ;reset task for game core
9279: 8d 72 07                     sta     OperMode_Task           ;set modes and leave
927c: a9 01                        lda     #$01                    ;if in game over mode, switch back to
927e: 8d 70 07                     sta     OperMode                ; game mode, because game is still on
9281: 60           GameIsOn        rts

                   TransposePlayers
9282: 38                           sec                             ;set carry flag by default to end game
9283: ad 7a 07                     lda     NumberOfPlayers         ;if only a 1 player game, leave
9286: f0 21                        beq     ExTrans
9288: ad 61 07                     lda     OffScr_NumberofLives    ;does offscreen player have any lives left?
928b: 30 1c                        bmi     ExTrans                 ;branch if not
928d: ad 53 07                     lda     CurrentPlayer           ;invert bit to update
9290: 49 01                        eor     #%00000001              ; which player is on the screen
9292: 8d 53 07                     sta     CurrentPlayer
9295: a2 06                        ldx     #$06
9297: bd 5a 07     TransLoop       lda     OnscreenPlayerInfo,x    ;transpose the information
929a: 48                           pha                             ; of the onscreen player
929b: bd 61 07                     lda     OffscreenPlayerInfo,x   ; with that of the offscreen player
929e: 9d 5a 07                     sta     OnscreenPlayerInfo,x
92a1: 68                           pla
92a2: 9d 61 07                     sta     OffscreenPlayerInfo,x
92a5: ca                           dex
92a6: 10 ef                        bpl     TransLoop
92a8: 18                           clc
92a9: 60           ExTrans         rts

                   ; -----------------------------------------------------------------------------
92aa: a9 ff        DoNothing1      lda     #$ff                    ;this is residual code, this value is
92ac: 8d c9 06                     sta     unused_06c9             ; not used anywhere in the program
92af: 60           DoNothing2      rts

                   ; -----------------------------------------------------------------------------
                   AreaParserTaskHandler
92b0: ac 1f 07                     ldy     AreaParserTaskNum       ;check number of tasks here
92b3: d0 05                        bne     DoAPTasks               ;if already set, go ahead
92b5: a0 08                        ldy     #$08
92b7: 8c 1f 07                     sty     AreaParserTaskNum       ;otherwise, set eight by default
92ba: 88           DoAPTasks       dey
92bb: 98                           tya
92bc: 20 c8 92                     jsr     AreaParserTasks
92bf: ce 1f 07                     dec     AreaParserTaskNum       ;if all tasks not complete do not
92c2: d0 03                        bne     SkipATRender            ; render attribute table yet
92c4: 20 6a 89                     jsr     RenderAttributeTables
92c7: 60           SkipATRender    rts

92c8: 20 04 8e     AreaParserTasks jsr     JumpEngine

92cb: db 92                        .dd2    IncrementColumnPos
92cd: ae 88                        .dd2    RenderAreaGraphics
92cf: ae 88                        .dd2    RenderAreaGraphics
92d1: fc 93                        .dd2    AreaParserCore
92d3: db 92                        .dd2    IncrementColumnPos
92d5: ae 88                        .dd2    RenderAreaGraphics
92d7: ae 88                        .dd2    RenderAreaGraphics
92d9: fc 93                        .dd2    AreaParserCore

                   ; -----------------------------------------------------------------------------
                   IncrementColumnPos
92db: ee 26 07                     inc     CurrentColumnPos        ;increment column where we're at
92de: ad 26 07                     lda     CurrentColumnPos
92e1: 29 0f                        and     #%00001111              ;mask out higher nybble
92e3: d0 06                        bne     NoColWrap
92e5: 8d 26 07                     sta     CurrentColumnPos        ;if no bits left set, wrap back to zero (0-f)
92e8: ee 25 07                     inc     CurrentPageLoc          ; and increment page number where we're at
92eb: ee a0 06     NoColWrap       inc     BlockBufferColumnPos    ;increment column offset where we're at
92ee: ad a0 06                     lda     BlockBufferColumnPos
92f1: 29 1f                        and     #%00011111              ;mask out all but 5 LSB (0-1f)
92f3: 8d a0 06                     sta     BlockBufferColumnPos    ;and save
92f6: 60                           rts

                   ; -----------------------------------------------------------------------------
                   ; $00 - used as counter, store for low nybble for background, ceiling byte for
                   ; terrain
                   ; $01 - used to store floor byte for terrain
                   ; $07 - used to store terrain metatile
                   ; $06-$07 - used to store block buffer address
                   BSceneDataOffsets
92f7: 00 30 60                     .bulk   $00,$30,$60
92fa: 93 00 00 11+ BackSceneryData .bulk   $93,$00,$00,$11,$12,$12,$13,$00,$00,$51,$52,$53,$00,$00,$00,$00 ;clouds
                                    +      $00,$00,$01,$02,$02,$03,$00,$00,$00,$00,$00,$00,$91,$92,$93,$00
                                    +      $00,$00,$00,$51,$52,$53,$41,$42,$43,$00,$00,$00,$00,$00,$91,$92
932a: 97 87 88 89+                 .bulk   $97,$87,$88,$89,$99,$00,$00,$00,$11,$12,$13,$a4,$a5,$a5,$a5,$a6 ;mountains and bushes
                                    +      $97,$98,$99,$01,$02,$03,$00,$a4,$a5,$a6,$00,$11,$12,$12,$12,$13
                                    +      $00,$00,$00,$00,$01,$02,$02,$03,$00,$a4,$a5,$a5,$a6,$00,$00,$00
935a: 11 12 12 13+                 .bulk   $11,$12,$12,$13,$00,$00,$00,$00,$00,$00,$00,$9c,$00,$8b,$aa,$aa ;trees and fences
                                    +      $aa,$aa,$11,$12,$13,$8b,$00,$9c,$9c,$00,$00,$01,$02,$03,$11,$12
                                    +      $12,$13,$00,$00,$00,$00,$aa,$aa,$9c,$aa,$00,$8b,$00,$01,$02,$03
                   BackSceneryMetatiles
938a: 80 83 00                     .bulk   $80,$83,$00             ;cloud left
938d: 81 84 00                     .bulk   $81,$84,$00             ;cloud middle
9390: 82 85 00                     .bulk   $82,$85,$00             ;cloud right
9393: 02 00 00                     .bulk   $02,$00,$00             ;bush left
9396: 03 00 00                     .bulk   $03,$00,$00             ;bush middle
9399: 04 00 00                     .bulk   $04,$00,$00             ;bush right
939c: 00 05 06                     .bulk   $00,$05,$06             ;mountain left
939f: 07 06 0a                     .bulk   $07,$06,$0a             ;mountain middle
93a2: 00 08 09                     .bulk   $00,$08,$09             ;mountain right
93a5: 4d 00 00                     .bulk   $4d,$00,$00             ;fence
93a8: 0d 0f 4e                     .bulk   $0d,$0f,$4e             ;tall tree
93ab: 0e 4e 4e                     .bulk   $0e,$4e,$4e             ;short tree
                   FSceneDataOffsets
93ae: 00 0d 1a                     .bulk   $00,$0d,$1a
93b1: 86 87 87 87+ ForeSceneryData .bulk   $86,$87,$87,$87,$87,$87,$87,$87,$87,$87,$87,$69,$69 ;in water
93be: 00 00 00 00+                 .bulk   $00,$00,$00,$00,$00,$45,$47,$47,$47,$47,$47,$00,$00 ;wall
93cb: 00 00 00 00+                 .bulk   $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$86,$87 ;over water
                   TerrainMetatiles
93d8: 69 54 52 62                  .bulk   $69,$54,$52,$62
                   TerrainRenderBits
93dc: 00 00                        .dbd2   %0000000000000000       ;no ceiling or floor
93de: 00 18                        .dbd2   %0000000000011000       ;no ceiling, floor 2
93e0: 01 18                        .dbd2   %0000000100011000       ;ceiling 1, floor 2
93e2: 07 18                        .dbd2   %0000011100011000       ;ceiling 3, floor 2
93e4: 0f 18                        .dbd2   %0000111100011000       ;ceiling 4, floor 2
93e6: ff 18                        .dbd2   %1111111100011000       ;ceiling 8, floor 2
93e8: 01 1f                        .dbd2   %0000000100011111       ;ceiling 1, floor 5
93ea: 07 1f                        .dbd2   %0000011100011111       ;ceiling 3, floor 5
93ec: 0f 1f                        .dbd2   %0000111100011111       ;ceiling 4, floor 5
93ee: 81 1f                        .dbd2   %1000000100011111       ;ceiling 1, floor 6
93f0: 01 00                        .dbd2   %0000000100000000       ;ceiling 1, no floor
93f2: 8f 1f                        .dbd2   %1000111100011111       ;ceiling 4, floor 6
93f4: f1 1f                        .dbd2   %1111000100011111       ;ceiling 1, floor 9
93f6: f9 18                        .dbd2   %1111100100011000       ;ceiling 1, middle 5, floor 2
93f8: f1 18                        .dbd2   %1111000100011000       ;ceiling 1, middle 4, floor 2
93fa: ff 1f                        .dbd2   %1111111100011111       ;completely solid top to bottom

93fc: ad 28 07     AreaParserCore  lda     BackloadingFlag         ;check to see if we are starting right of start
93ff: f0 03                        beq     RenderSceneryTerrain    ;if not, go ahead and render background, foreground and terrain
9401: 20 08 95                     jsr     ProcessAreaData         ;otherwise skip ahead and load level data
                   ; 
                   RenderSceneryTerrain
9404: a2 0c                        ldx     #$0c
9406: a9 00                        lda     #$00
9408: 9d a1 06     ClrMTBuf        sta     MetatileBuffer,x        ;clear out metatile buffer
940b: ca                           dex
940c: 10 fa                        bpl     ClrMTBuf
940e: ac 42 07                     ldy     BackgroundScenery       ;do we need to render the background scenery?
9411: f0 42                        beq     RendFore                ;if not, skip to check the foreground
9413: ad 25 07                     lda     CurrentPageLoc          ;otherwise check for every third page
9416: c9 03        ThirdP          cmp     #$03
9418: 30 05                        bmi     RendBack                ;if less than three we're there
941a: 38                           sec
941b: e9 03                        sbc     #$03                    ;if 3 or more, subtract 3 and 
941d: 10 f7                        bpl     ThirdP                  ;do an unconditional branch
941f: 0a           RendBack        asl     A                       ;move results to higher nybble
9420: 0a                           asl     A
9421: 0a                           asl     A
9422: 0a                           asl     A
9423: 79 f6 92                     adc     BSceneDataOffsets-1,y   ;add to it offset loaded from here
9426: 6d 26 07                     adc     CurrentColumnPos        ;add to the result our current column position
9429: aa                           tax
942a: bd fa 92                     lda     BackSceneryData,x       ;load data from sum of offsets
942d: f0 26                        beq     RendFore                ;if zero, no scenery for that part
942f: 48                           pha
9430: 29 0f                        and     #$0f                    ;save to stack and clear high nybble
9432: 38                           sec
9433: e9 01                        sbc     #$01                    ;subtract one (because low nybble is $01-$0c)
9435: 85 00                        sta     $00                     ;save low nybble
9437: 0a                           asl     A                       ;multiply by three (shift to left and add result to old one)
9438: 65 00                        adc     $00                     ;note that since d7 was nulled, the carry flag is always clear
943a: aa                           tax                             ;save as offset for background scenery metatile data
943b: 68                           pla                             ;get high nybble from stack, move low
943c: 4a                           lsr     A
943d: 4a                           lsr     A
943e: 4a                           lsr     A
943f: 4a                           lsr     A
9440: a8                           tay                             ;use as second offset (used to determine height)
9441: a9 03                        lda     #$03                    ;use previously saved memory location for counter
9443: 85 00                        sta     $00
9445: bd 8a 93     SceLoop1        lda     BackSceneryMetatiles,x  ;load metatile data from offset of (lsb - 1) * 3
9448: 99 a1 06                     sta     MetatileBuffer,y        ;store into buffer from offset of (msb / 16)
944b: e8                           inx
944c: c8                           iny
944d: c0 0b                        cpy     #$0b                    ;if at this location, leave loop
944f: f0 04                        beq     RendFore
9451: c6 00                        dec     $00                     ;decrement until counter expires, barring exception
9453: d0 f0                        bne     SceLoop1
9455: ae 41 07     RendFore        ldx     ForegroundScenery       ;check for foreground data needed or not
9458: f0 13                        beq     RendTerr                ;if not, skip this part
945a: bc ad 93                     ldy     FSceneDataOffsets-1,x   ;load offset from location offset by header value, then
945d: a2 00                        ldx     #$00                    ; reinit X
945f: b9 b1 93     SceLoop2        lda     ForeSceneryData,y       ;load data until counter expires
9462: f0 03                        beq     NoFore                  ;do not store if zero found
9464: 9d a1 06                     sta     MetatileBuffer,x
9467: c8           NoFore          iny
9468: e8                           inx
9469: e0 0d                        cpx     #$0d                    ;store up to end of metatile buffer
946b: d0 f2                        bne     SceLoop2
946d: ac 4e 07     RendTerr        ldy     AreaType                ;check world type for water level
9470: d0 0c                        bne     TerMTile                ;if not water level, skip this part
9472: ad 5f 07                     lda     WorldNumber             ;check world number, if not world number eight
9475: c9 07                        cmp     #World8                 ; then skip this part
9477: d0 05                        bne     TerMTile
9479: a9 62                        lda     #$62                    ;if set as water level and world number eight,
947b: 4c 88 94                     jmp     StoreMT                 ; use castle wall metatile as terrain type

947e: b9 d8 93     TerMTile        lda     TerrainMetatiles,y      ;otherwise get appropriate metatile for area type
9481: ac 43 07                     ldy     CloudTypeOverride       ;check for cloud type override
9484: f0 02                        beq     StoreMT                 ;if not set, keep value otherwise
9486: a9 88                        lda     #$88                    ;use cloud block terrain
9488: 85 07        StoreMT         sta     $07                     ;store value here
948a: a2 00                        ldx     #$00                    ;initialize X, use as metatile buffer offset
948c: ad 27 07                     lda     TerrainControl          ;use yet another value from the header
948f: 0a                           asl     A                       ;multiply by 2 and use as yet another offset
9490: a8                           tay
9491: b9 dc 93     TerrLoop        lda     TerrainRenderBits,y     ;get one of the terrain rendering bit data
9494: 85 00                        sta     $00
9496: c8                           iny                             ;increment Y and use as offset next time around
9497: 84 01                        sty     $01
9499: ad 43 07                     lda     CloudTypeOverride       ;skip if value here is zero
949c: f0 0a                        beq     NoCloud2
949e: e0 00                        cpx     #$00                    ;otherwise, check if we're doing the ceiling byte
94a0: f0 06                        beq     NoCloud2
94a2: a5 00                        lda     $00                     ;if not, mask out all but d3
94a4: 29 08                        and     #%00001000
94a6: 85 00                        sta     $00
94a8: a0 00        NoCloud2        ldy     #$00                    ;start at beginning of bitmasks
94aa: b9 8a c6     TerrBChk        lda     Bitmasks,y              ;load bitmask, then perform AND on contents of first byte
94ad: 24 00                        bit     $00
94af: f0 05                        beq     NextTBit                ;if not set, skip this part (do not write terrain to buffer)
94b1: a5 07                        lda     $07
94b3: 9d a1 06                     sta     MetatileBuffer,x        ;load terrain type metatile number and store into buffer here
94b6: e8           NextTBit        inx                             ;continue until end of buffer
94b7: e0 0d                        cpx     #$0d
94b9: f0 18                        beq     RendBBuf                ;if we're at the end, break out of this loop
94bb: ad 4e 07                     lda     AreaType                ;check world type for underground area
94be: c9 02                        cmp     #$02
94c0: d0 08                        bne     EndUChk                 ;if not underground, skip this part
94c2: e0 0b                        cpx     #$0b
94c4: d0 04                        bne     EndUChk                 ;if we're at the bottom of the screen, override
94c6: a9 54                        lda     #$54                    ; old terrain type with ground level terrain type
94c8: 85 07                        sta     $07
94ca: c8           EndUChk         iny                             ;increment bitmasks offset in Y
94cb: c0 08                        cpy     #$08
94cd: d0 db                        bne     TerrBChk                ;if not all bits checked, loop back  
94cf: a4 01                        ldy     $01
94d1: d0 be                        bne     TerrLoop                ;unconditional branch, use Y to load next byte
94d3: 20 08 95     RendBBuf        jsr     ProcessAreaData         ;do the area data loading routine now
94d6: ad a0 06                     lda     BlockBufferColumnPos
94d9: 20 e1 9b                     jsr     GetBlockBufferAddr      ;get block buffer address from where we're at
94dc: a2 00                        ldx     #$00
94de: a0 00                        ldy     #$00                    ;init index regs and start at beginning of smaller buffer
94e0: 84 00        ChkMTLow        sty     $00
94e2: bd a1 06                     lda     MetatileBuffer,x        ;load stored metatile number
94e5: 29 c0                        and     #%11000000              ;mask out all but 2 MSB
94e7: 0a                           asl     A
94e8: 2a                           rol     A                       ;make %xx000000 into %000000xx
94e9: 2a                           rol     A
94ea: a8                           tay                             ;use as offset in Y
94eb: bd a1 06                     lda     MetatileBuffer,x        ;reload original unmasked value here
94ee: d9 04 95                     cmp     BlockBuffLowBounds,y    ;check for certain values depending on bits set
94f1: b0 02                        bcs     StrBlock                ;if equal or greater, branch
94f3: a9 00                        lda     #$00                    ;if less, init value before storing
94f5: a4 00        StrBlock        ldy     $00                     ;get offset for block buffer
94f7: 91 06                        sta     ($06),y                 ;store value into block buffer
94f9: 98                           tya
94fa: 18                           clc                             ;add 16 (move down one row) to offset
94fb: 69 10                        adc     #$10
94fd: a8                           tay
94fe: e8                           inx                             ;increment column value
94ff: e0 0d                        cpx     #$0d
9501: 90 dd                        bcc     ChkMTLow                ;continue until we pass last row, then leave
9503: 60                           rts

                   ; numbers lower than these with the same attribute bits will not be stored in
                   ; the block buffer
                   BlockBuffLowBounds
9504: 10 51 88 c0                  .bulk   $10,$51,$88,$c0

                   ; -----------------------------------------------------------------------------
                   ; $00 - used to store area object identifier
                   ; $07 - used as adder to find proper area object code
9508: a2 02        ProcessAreaData ldx     #$02                    ;start at the end of area object buffer
950a: 86 08        ProcADLoop      stx     ObjectOffset
950c: a9 00                        lda     #$00                    ;reset flag
950e: 8d 29 07                     sta     BehindAreaParserFlag
9511: ac 2c 07                     ldy     AreaDataOffset          ;get offset of area data pointer
9514: b1 e7                        lda     (AreaData),y            ;get first byte of area object
9516: c9 fd                        cmp     #$fd                    ;if end-of-area, skip all this crap
9518: f0 4b                        beq     RdyDecode
951a: bd 30 07                     lda     AreaObjectLength,x      ;check area object buffer flag
951d: 10 46                        bpl     RdyDecode               ;if buffer not negative, branch, otherwise
951f: c8                           iny
9520: b1 e7                        lda     (AreaData),y            ;get second byte of area object
9522: 0a                           asl     A                       ;check for page select bit (d7), branch if not set
9523: 90 0b                        bcc     Chk1Row13
9525: ad 2b 07                     lda     AreaObjectPageSel       ;check page select
9528: d0 06                        bne     Chk1Row13
952a: ee 2b 07                     inc     AreaObjectPageSel       ;if not already set, set it now
952d: ee 2a 07                     inc     AreaObjectPageLoc       ;and increment page location
9530: 88           Chk1Row13       dey
9531: b1 e7                        lda     (AreaData),y            ;reread first byte of level object
9533: 29 0f                        and     #$0f                    ;mask out high nybble
9535: c9 0d                        cmp     #$0d                    ;row 13?
9537: d0 1b                        bne     Chk1Row14
9539: c8                           iny                             ;if so, reread second byte of level object
953a: b1 e7                        lda     (AreaData),y
953c: 88                           dey                             ;decrement to get ready to read first byte
953d: 29 40                        and     #%01000000              ;check for d6 set (if not, object is page control)
953f: d0 1c                        bne     CheckRear
9541: ad 2b 07                     lda     AreaObjectPageSel       ;if page select is set, do not reread
9544: d0 17                        bne     CheckRear
9546: c8                           iny                             ;if d6 not set, reread second byte
9547: b1 e7                        lda     (AreaData),y
9549: 29 1f                        and     #%00011111              ;mask out all but 5 LSB and store in page control
954b: 8d 2a 07                     sta     AreaObjectPageLoc
954e: ee 2b 07                     inc     AreaObjectPageSel       ;increment page select
9551: 4c 6e 95                     jmp     NextAObj

9554: c9 0e        Chk1Row14       cmp     #$0e                    ;row 14?
9556: d0 05                        bne     CheckRear
9558: ad 28 07                     lda     BackloadingFlag         ;check flag for saved page number and branch if set
955b: d0 08                        bne     RdyDecode               ; to render the object (otherwise bg might not look right)
955d: ad 2a 07     CheckRear       lda     AreaObjectPageLoc       ;check to see if current page of level object is
9560: cd 25 07                     cmp     CurrentPageLoc          ;behind current page of renderer
9563: 90 06                        bcc     SetBehind               ;if so branch
9565: 20 95 95     RdyDecode       jsr     DecodeAreaData          ;do sub and do not turn on flag
9568: 4c 71 95                     jmp     ChkLength

956b: ee 29 07     SetBehind       inc     BehindAreaParserFlag    ;turn on flag if object is behind renderer
956e: 20 89 95     NextAObj        jsr     IncAreaObjOffset        ;increment buffer offset and move on
9571: a6 08        ChkLength       ldx     ObjectOffset            ;get buffer offset
9573: bd 30 07                     lda     AreaObjectLength,x      ;check object length for anything stored here
9576: 30 03                        bmi     ProcLoopb               ;if not, branch to handle loopback
9578: de 30 07                     dec     AreaObjectLength,x      ;otherwise decrement length or get rid of it
957b: ca           ProcLoopb       dex                             ;decrement buffer offset
957c: 10 8c                        bpl     ProcADLoop              ; and loopback unless exceeded buffer
957e: ad 29 07                     lda     BehindAreaParserFlag    ;check for flag set if objects were behind renderer
9581: d0 85                        bne     ProcessAreaData         ;branch if true to load more level data, otherwise
9583: ad 28 07                     lda     BackloadingFlag         ;check for flag set if starting right of page $00
9586: d0 80                        bne     ProcessAreaData         ;branch if true to load more level data, otherwise leave
9588: 60           EndAParse       rts

                   IncAreaObjOffset
9589: ee 2c 07                     inc     AreaDataOffset          ;increment offset of level pointer
958c: ee 2c 07                     inc     AreaDataOffset
958f: a9 00                        lda     #$00                    ;reset page select
9591: 8d 2b 07                     sta     AreaObjectPageSel
9594: 60                           rts

9595: bd 30 07     DecodeAreaData  lda     AreaObjectLength,x      ;check current buffer flag
9598: 30 03                        bmi     Chk1stB
959a: bc 2d 07                     ldy     AreaObjOffsetBuffer,x   ;if not, get offset from buffer
959d: a2 10        Chk1stB         ldx     #$10                    ;load offset of 16 for special row 15
959f: b1 e7                        lda     (AreaData),y            ;get first byte of level object again
95a1: c9 fd                        cmp     #$fd
95a3: f0 e3                        beq     EndAParse               ;if end of level, leave this routine
95a5: 29 0f                        and     #$0f                    ;otherwise, mask out low nybble
95a7: c9 0f                        cmp     #$0f                    ;row 15?
95a9: f0 08                        beq     ChkRow14                ;if so, keep the offset of 16
95ab: a2 08                        ldx     #$08                    ;otherwise load offset of 8 for special row 12
95ad: c9 0c                        cmp     #$0c                    ;row 12?
95af: f0 02                        beq     ChkRow14                ;if so, keep the offset value of 8
95b1: a2 00                        ldx     #$00                    ;otherwise nullify value by default
95b3: 86 07        ChkRow14        stx     $07                     ;store whatever value we just loaded here
95b5: a6 08                        ldx     ObjectOffset            ;get object offset again
95b7: c9 0e                        cmp     #$0e                    ;row 14?
95b9: d0 08                        bne     ChkRow13
95bb: a9 00                        lda     #$00                    ;if so, load offset with $00
95bd: 85 07                        sta     $07
95bf: a9 2e                        lda     #$2e                    ;and load A with another value
95c1: d0 53                        bne     NormObj                 ;unconditional branch

95c3: c9 0d        ChkRow13        cmp     #$0d                    ;row 13?
95c5: d0 1b                        bne     ChkSRows
95c7: a9 22                        lda     #$22                    ;if so, load offset with 34
95c9: 85 07                        sta     $07
95cb: c8                           iny                             ;get next byte
95cc: b1 e7                        lda     (AreaData),y
95ce: 29 40                        and     #%01000000              ;mask out all but d6 (page control obj bit)
95d0: f0 63                        beq     LeavePar                ;if d6 clear, branch to leave (we handled this earlier)
95d2: b1 e7                        lda     (AreaData),y            ;otherwise, get byte again
95d4: 29 7f                        and     #%01111111              ;mask out d7
95d6: c9 4b                        cmp     #$4b                    ;check for loop command in low nybble
95d8: d0 03                        bne     Mask2MSB                ;(plus d6 set for object other than page control)
95da: ee 45 07                     inc     LoopCommand             ;if loop command, set loop command flag
95dd: 29 3f        Mask2MSB        and     #%00111111              ;mask out d7 and d6
95df: 4c 16 96                     jmp     NormObj                 ;and jump

95e2: c9 0c        ChkSRows        cmp     #$0c                    ;row 12-15?
95e4: b0 27                        bcs     SpecObj
95e6: c8                           iny                             ;if not, get second byte of level object
95e7: b1 e7                        lda     (AreaData),y
95e9: 29 70                        and     #%01110000              ;mask out all but d6-d4
95eb: d0 0b                        bne     LrgObj                  ;if any bits set, branch to handle large object
95ed: a9 16                        lda     #$16
95ef: 85 07                        sta     $07                     ;otherwise set offset of 24 for small object
95f1: b1 e7                        lda     (AreaData),y            ;reload second byte of level object
95f3: 29 0f                        and     #%00001111              ;mask out higher nybble and jump
95f5: 4c 16 96                     jmp     NormObj

95f8: 85 00        LrgObj          sta     $00                     ;store value here (branch for large objects)
95fa: c9 70                        cmp     #$70                    ;check for vertical pipe object
95fc: d0 0a                        bne     NotWPipe
95fe: b1 e7                        lda     (AreaData),y            ;if not, reload second byte
9600: 29 08                        and     #%00001000              ;mask out all but d3 (usage control bit)
9602: f0 04                        beq     NotWPipe                ;if d3 clear, branch to get original value
9604: a9 00                        lda     #$00                    ;otherwise, nullify value for warp pipe
9606: 85 00                        sta     $00
9608: a5 00        NotWPipe        lda     $00                     ;get value and jump ahead
960a: 4c 12 96                     jmp     MoveAOId

960d: c8           SpecObj         iny                             ;branch here for rows 12-15
960e: b1 e7                        lda     (AreaData),y
9610: 29 70                        and     #%01110000              ;get next byte and mask out all but d6-d4
9612: 4a           MoveAOId        lsr     A                       ;move d6-d4 to lower nybble
9613: 4a                           lsr     A
9614: 4a                           lsr     A
9615: 4a                           lsr     A
9616: 85 00        NormObj         sta     $00                     ;store value here (branch for small objects and rows 13 and 14)
9618: bd 30 07                     lda     AreaObjectLength,x      ;is there something stored here already?
961b: 10 42                        bpl     RunAObj                 ;if so, branch to do its particular sub
961d: ad 2a 07                     lda     AreaObjectPageLoc       ;otherwise check to see if the object we've loaded is on the
9620: cd 25 07                     cmp     CurrentPageLoc          ;same page as the renderer, and if so, branch
9623: f0 11                        beq     InitRear
9625: ac 2c 07                     ldy     AreaDataOffset          ;if not, get old offset of level pointer
9628: b1 e7                        lda     (AreaData),y            ;and reload first byte
962a: 29 0f                        and     #%00001111
962c: c9 0e                        cmp     #$0e                    ;row 14?
962e: d0 05                        bne     LeavePar
9630: ad 28 07                     lda     BackloadingFlag         ;if so, check backloading flag
9633: d0 21                        bne     StarAObj                ;if set, branch to render object, else leave
9635: 60           LeavePar        rts

9636: ad 28 07     InitRear        lda     BackloadingFlag         ;check backloading flag to see if it's been initialized
9639: f0 0b                        beq     BackColC                ;branch to column-wise check
963b: a9 00                        lda     #$00                    ;if not, initialize both backloading and 
963d: 8d 28 07                     sta     BackloadingFlag         ;behind-renderer flags and leave
9640: 8d 29 07                     sta     BehindAreaParserFlag
9643: 85 08                        sta     ObjectOffset
9645: 60           LoopCmdE        rts

9646: ac 2c 07     BackColC        ldy     AreaDataOffset          ;get first byte again
9649: b1 e7                        lda     (AreaData),y
964b: 29 f0                        and     #%11110000              ;mask out low nybble and move high to low
964d: 4a                           lsr     A
964e: 4a                           lsr     A
964f: 4a                           lsr     A
9650: 4a                           lsr     A
9651: cd 26 07                     cmp     CurrentColumnPos        ;is this where we're at?
9654: d0 df                        bne     LeavePar                ;if not, branch to leave
9656: ad 2c 07     StarAObj        lda     AreaDataOffset          ;if so, load area obj offset and store in buffer
9659: 9d 2d 07                     sta     AreaObjOffsetBuffer,x
965c: 20 89 95                     jsr     IncAreaObjOffset        ;do sub to increment to next object data
965f: a5 00        RunAObj         lda     $00                     ;get stored value and add offset to it
9661: 18                           clc                             ;then use the jump engine with current contents of A
9662: 65 07                        adc     $07
9664: 20 04 8e                     jsr     JumpEngine

                   ; large objects (rows $00-$0b or 00-11, d6-d4 set)
9667: e5 98                        .dd2    VerticalPipe
9669: 40 97                        .dd2    AreaStyleObject         ;used by warp pipes
966b: 2e 9a                        .dd2    RowOfBricks
966d: 3e 9a                        .dd2    RowOfSolidBlocks
966f: f2 99                        .dd2    RowOfCoins
9671: 50 9a                        .dd2    ColumnOfBricks
9673: 59 9a                        .dd2    ColumnOfSolidBlocks
9675: e5 98                        .dd2    VerticalPipe            ;used by decoration pipes
                   ; objects for special row $0c or 12
9677: 41 9b                        .dd2    Hole_Empty
9679: ba 97                        .dd2    PulleyRopeObject
967b: 79 99                        .dd2    Bridge_High
967d: 7c 99                        .dd2    Bridge_Middle
967f: 7f 99                        .dd2    Bridge_Low
9681: 57 99                        .dd2    Hole_Water
9683: 68 99                        .dd2    QuestionBlockRow_High
9685: 6b 99                        .dd2    QuestionBlockRow_Low
                   ; objects for special row $0f or 15
9687: d0 99                        .dd2    EndlessRope
9689: d7 99                        .dd2    BalancePlatRope
968b: 06 98                        .dd2    CastleObject
968d: b7 9a                        .dd2    StaircaseObject
968f: ab 98                        .dd2    ExitPipe
9691: 94 99                        .dd2    FlagBalls_Residual
                   ; small objects (rows $00-$0b or 00-11, d6-d4 all clear)
9693: 0e 9b                        .dd2    QuestionBlock           ;power-up
9695: 0e 9b                        .dd2    QuestionBlock           ;coin
9697: 0e 9b                        .dd2    QuestionBlock           ;hidden, coin
9699: 01 9b                        .dd2    Hidden1UpBlock          ;hidden, 1-up
969b: 19 9b                        .dd2    BrickWithItem           ;brick, power-up
969d: 19 9b                        .dd2    BrickWithItem           ;brick, vine
969f: 19 9b                        .dd2    BrickWithItem           ;brick, star
96a1: 14 9b                        .dd2    BrickWithCoins          ;brick, coins
96a3: 19 9b                        .dd2    BrickWithItem           ;brick, 1-up
96a5: 6f 98                        .dd2    WaterPipe
96a7: 19 9a                        .dd2    EmptyBlock
96a9: d3 9a                        .dd2    JumpSpring
                   ; objects for special row $0d or 13 (d6 set)
96ab: 82 98                        .dd2    IntroPipe
96ad: 9e 99                        .dd2    FlagpoleObject
96af: 09 9a                        .dd2    AxeObj
96b1: 0e 9a                        .dd2    ChainObj
96b3: 01 9a                        .dd2    CastleBridgeObj
96b5: f2 96                        .dd2    ScrollLockObject_Warp
96b7: 0d 97                        .dd2    ScrollLockObject
96b9: 0d 97                        .dd2    ScrollLockObject
96bb: 2b 97                        .dd2    AreaFrenzy              ;flying cheep-cheeps 
96bd: 2b 97                        .dd2    AreaFrenzy              ;bullet bills or swimming cheep-cheeps
96bf: 2b 97                        .dd2    AreaFrenzy              ;stop frenzy
96c1: 45 96                        .dd2    LoopCmdE
                   ; object for special row $0e or 14
96c3: c5 96                        .dd2    AlterAreaAttributes

                   ; -----------------------------------------------------------------------------
                   ; (these apply to all area object subroutines in this section unless otherwise
                   ; stated)
                   ; $00 - used to store offset used to find object code
                   ; $07 - starts with adder from area parser, used to store row offset
                   AlterAreaAttributes
96c5: bc 2d 07                     ldy     AreaObjOffsetBuffer,x   ;load offset for level object data saved in buffer
96c8: c8                           iny                             ;load second byte
96c9: b1 e7                        lda     (AreaData),y
96cb: 48                           pha                             ;save in stack for now
96cc: 29 40                        and     #%01000000
96ce: d0 12                        bne     Alter2                  ;branch if d6 is set
96d0: 68                           pla
96d1: 48                           pha                             ;pull and push offset to copy to A
96d2: 29 0f                        and     #%00001111              ;mask out high nybble and store as
96d4: 8d 27 07                     sta     TerrainControl          ; new terrain height type bits
96d7: 68                           pla
96d8: 29 30                        and     #%00110000              ;pull and mask out all but d5 and d4
96da: 4a                           lsr     A                       ;move bits to lower nybble and store
96db: 4a                           lsr     A                       ; as new background scenery bits
96dc: 4a                           lsr     A
96dd: 4a                           lsr     A
96de: 8d 42 07                     sta     BackgroundScenery       ;then leave
96e1: 60                           rts

96e2: 68           Alter2          pla
96e3: 29 07                        and     #%00000111              ;mask out all but 3 LSB
96e5: c9 04                        cmp     #$04                    ;if four or greater, set color control bits
96e7: 90 05                        bcc     SetFore                 ; and nullify foreground scenery bits
96e9: 8d 44 07                     sta     BackgroundColorCtrl
96ec: a9 00                        lda     #$00
96ee: 8d 41 07     SetFore         sta     ForegroundScenery       ;otherwise set new foreground scenery bits
96f1: 60                           rts

                   ; -----------------------------------------------------------------------------
                   ScrollLockObject_Warp
96f2: a2 04                        ldx     #$04                    ;load value of 4 for game text routine as default
96f4: ad 5f 07                     lda     WorldNumber             ; warp zone (4-3-2), then check world number
96f7: f0 08                        beq     WarpNum
96f9: e8                           inx                             ;if world number > 1, increment for next warp zone (5)
96fa: ac 4e 07                     ldy     AreaType                ;check area type
96fd: 88                           dey
96fe: d0 01                        bne     WarpNum                 ;if ground area type, increment for last warp zone
9700: e8                           inx                             ; (8-7-6) and move on
9701: 8a           WarpNum         txa
9702: 8d d6 06                     sta     WarpZoneControl         ;store number here to be used by warp zone routine
9705: 20 08 88                     jsr     WriteGameText           ;print text and warp zone numbers
9708: a9 0d                        lda     #PiranhaPlant
970a: 20 16 97                     jsr     KillEnemies             ;load identifier for piranha plants and do sub
                   ScrollLockObject
970d: ad 23 07                     lda     ScrollLock              ;invert scroll lock to turn it on
9710: 49 01                        eor     #%00000001
9712: 8d 23 07                     sta     ScrollLock
9715: 60                           rts

                   ; -----------------------------------------------------------------------------
                   ; $00 - used to store enemy identifier in KillEnemies
9716: 85 00        KillEnemies     sta     $00                     ;store identifier here
9718: a9 00                        lda     #$00
971a: a2 04                        ldx     #$04                    ;check for identifier in enemy object buffer
971c: b4 16        KillELoop       ldy     Enemy_ID,x
971e: c4 00                        cpy     $00                     ;if not found, branch
9720: d0 02                        bne     NoKillE
9722: 95 0f                        sta     Enemy_Flag,x
9724: ca           NoKillE         dex                             ;do this until all slots are checked
9725: 10 f5                        bpl     KillELoop
9727: 60                           rts

                   ; -----------------------------------------------------------------------------
9728: 14           FrenzyIDData    .dd1    FlyCheepCheepFrenzy
9729: 17                           .dd1    BBill_CCheep_Frenzy
972a: 18                           .dd1    Stop_Frenzy

972b: a6 00        AreaFrenzy      ldx     $00                     ;use area object identifier bit as offset
972d: bd 20 97                     lda     FrenzyIDData-8,x        ;note that it starts at 8, thus weird address here
9730: a0 05                        ldy     #$05
9732: 88           FreCompLoop     dey                             ;check regular slots of enemy object buffer
9733: 30 07                        bmi     ExitAFrenzy             ;if all slots checked and enemy object not found, branch to store
9735: d9 16 00                     cmp     Enemy_ID,y              ;check for enemy object in buffer versus frenzy object
9738: d0 f8                        bne     FreCompLoop
973a: a9 00                        lda     #$00                    ;if enemy object already present, nullify queue and leave
973c: 8d cd 06     ExitAFrenzy     sta     EnemyFrenzyQueue        ;store enemy into frenzy queue
973f: 60                           rts

                   ; -----------------------------------------------------------------------------
                   ; $06 - used by MushroomLedge to store length
9740: ad 33 07     AreaStyleObject lda     AreaStyle               ;load level object style and jump to the right sub
9743: 20 04 8e                     jsr     JumpEngine

9746: 4c 97                        .dd2    TreeLedge               ;also used for cloud type levels
9748: 78 97                        .dd2    MushroomLedge
974a: 69 9a                        .dd2    BulletBillCannon

974c: 20 bb 9b     TreeLedge       jsr     GetLrgObjAttrib         ;get row and length of green ledge
974f: bd 30 07                     lda     AreaObjectLength,x      ;check length counter for expiration
9752: f0 1f                        beq     EndTreeL
9754: 10 11                        bpl     MidTreeL
9756: 98                           tya
9757: 9d 30 07                     sta     AreaObjectLength,x      ;store lower nybble into buffer flag as length of ledge
975a: ad 25 07                     lda     CurrentPageLoc
975d: 0d 26 07                     ora     CurrentColumnPos        ;are we at the start of the level?
9760: f0 05                        beq     MidTreeL
9762: a9 16                        lda     #$16                    ;render start of tree ledge
9764: 4c b0 97                     jmp     NoUnder

9767: a6 07        MidTreeL        ldx     $07
9769: a9 17                        lda     #$17                    ;render middle of tree ledge
976b: 9d a1 06                     sta     MetatileBuffer,x        ;note that this is also used if ledge position is
976e: a9 4c                        lda     #$4c                    ; at the start of level for continuous effect
9770: 4c aa 97                     jmp     AllUnder                ;now render the part underneath

9773: a9 18        EndTreeL        lda     #$18                    ;render end of tree ledge
9775: 4c b0 97                     jmp     NoUnder

9778: 20 ac 9b     MushroomLedge   jsr     ChkLrgObjLength         ;get shroom dimensions
977b: 84 06                        sty     $06                     ;store length here for now
977d: 90 0c                        bcc     EndMushL
977f: bd 30 07                     lda     AreaObjectLength,x      ;divide length by 2 and store elsewhere
9782: 4a                           lsr     A
9783: 9d 36 07                     sta     MushroomLedgeHalfLen,x
9786: a9 19                        lda     #$19                    ;render start of mushroom
9788: 4c b0 97                     jmp     NoUnder

978b: a9 1b        EndMushL        lda     #$1b                    ;if at the end, render end of mushroom
978d: bc 30 07                     ldy     AreaObjectLength,x
9790: f0 1e                        beq     NoUnder
9792: bd 36 07                     lda     MushroomLedgeHalfLen,x  ;get divided length and store where length
9795: 85 06                        sta     $06                     ; was stored originally
9797: a6 07                        ldx     $07
9799: a9 1a                        lda     #$1a
979b: 9d a1 06                     sta     MetatileBuffer,x        ;render middle of mushroom
979e: c4 06                        cpy     $06                     ;are we smack dab in the center?
97a0: d0 2c                        bne     MushLExit               ;if not, branch to leave
97a2: e8                           inx
97a3: a9 4f                        lda     #$4f
97a5: 9d a1 06                     sta     MetatileBuffer,x        ;render stem top of mushroom underneath the middle
97a8: a9 50                        lda     #$50
97aa: e8           AllUnder        inx
97ab: a0 0f                        ldy     #$0f                    ;set $0f to render all way down
97ad: 4c 7d 9b                     jmp     RenderUnderPart         ;now render the stem of mushroom

97b0: a6 07        NoUnder         ldx     $07                     ;load row of ledge
97b2: a0 00                        ldy     #$00                    ;set 0 for no bottom on this part
97b4: 4c 7d 9b                     jmp     RenderUnderPart

                   ; -----------------------------------------------------------------------------
                   ; tiles used by pulleys and rope object
                   PulleyRopeMetatiles
97b7: 42 41 43                     .bulk   $42,$41,$43

                   PulleyRopeObject
97ba: 20 ac 9b                     jsr     ChkLrgObjLength         ;get length of pulley/rope object
97bd: a0 00                        ldy     #$00                    ;initialize metatile offset
97bf: b0 07                        bcs     RenderPul               ;if starting, render left pulley
97c1: c8                           iny
97c2: bd 30 07                     lda     AreaObjectLength,x      ;if not at the end, render rope
97c5: d0 01                        bne     RenderPul
97c7: c8                           iny                             ;otherwise render right pulley
97c8: b9 b7 97     RenderPul       lda     PulleyRopeMetatiles,y
97cb: 8d a1 06                     sta     MetatileBuffer          ;render at the top of the screen
97ce: 60           MushLExit       rts                             ;and leave

                   ; -----------------------------------------------------------------------------
                   ; $06 - used to store upper limit of rows for CastleObject
97cf: 00 45 45 45+ CastleMetatiles .bulk   $00,$45,$45,$45,$00
97d4: 00 48 47 46+                 .bulk   $00,$48,$47,$46,$00
97d9: 45 49 49 49+                 .bulk   $45,$49,$49,$49,$45
97de: 47 47 4a 47+                 .bulk   $47,$47,$4a,$47,$47
97e3: 47 47 4b 47+                 .bulk   $47,$47,$4b,$47,$47
97e8: 49 49 49 49+                 .bulk   $49,$49,$49,$49,$49
97ed: 47 4a 47 4a+                 .bulk   $47,$4a,$47,$4a,$47
97f2: 47 4b 47 4b+                 .bulk   $47,$4b,$47,$4b,$47
97f7: 47 47 47 47+                 .bulk   $47,$47,$47,$47,$47
97fc: 4a 47 4a 47+                 .bulk   $4a,$47,$4a,$47,$4a
9801: 4b 47 4b 47+                 .bulk   $4b,$47,$4b,$47,$4b

9806: 20 bb 9b     CastleObject    jsr     GetLrgObjAttrib         ;save lower nybble as starting row
9809: 84 07                        sty     $07                     ;if starting row is above $0a, game will crash!!!
980b: a0 04                        ldy     #$04
980d: 20 af 9b                     jsr     ChkLrgObjFixedLength    ;load length of castle if not already loaded
9810: 8a                           txa
9811: 48                           pha                             ;save obj buffer offset to stack
9812: bc 30 07                     ldy     AreaObjectLength,x      ;use current length as offset for castle data
9815: a6 07                        ldx     $07                     ;begin at starting row
9817: a9 0b                        lda     #$0b
9819: 85 06                        sta     $06                     ;load upper limit of number of rows to print
981b: b9 cf 97     CRendLoop       lda     CastleMetatiles,y       ;load current byte using offset
981e: 9d a1 06                     sta     MetatileBuffer,x
9821: e8                           inx                             ;store in buffer and increment buffer offset
9822: a5 06                        lda     $06
9824: f0 07                        beq     ChkCFloor               ;have we reached upper limit yet?
9826: c8                           iny                             ;if not, increment column-wise
9827: c8                           iny                             ; to byte in next row
9828: c8                           iny
9829: c8                           iny
982a: c8                           iny
982b: c6 06                        dec     $06                     ;move closer to upper limit
982d: e0 0b        ChkCFloor       cpx     #$0b                    ;have we reached the row just before floor?
982f: d0 ea                        bne     CRendLoop               ;if not, go back and do another row
9831: 68                           pla
9832: aa                           tax                             ;get obj buffer offset from before
9833: ad 25 07                     lda     CurrentPageLoc
9836: f0 36                        beq     ExitCastle              ;if we're at page 0, we do not need to do anything else
9838: bd 30 07                     lda     AreaObjectLength,x      ;check length
983b: c9 01                        cmp     #$01                    ;if length almost about to expire, put brick at floor
983d: f0 2a                        beq     PlayerStop
983f: a4 07                        ldy     $07                     ;check starting row for tall castle ($00)
9841: d0 04                        bne     NotTall
9843: c9 03                        cmp     #$03                    ;if found, then check to see if we're at the second column
9845: f0 22                        beq     PlayerStop
9847: c9 02        NotTall         cmp     #$02                    ;if not tall castle, check to see if we're at the third column
9849: d0 23                        bne     ExitCastle              ;if we aren't and the castle is tall, don't create flag yet
984b: 20 cb 9b                     jsr     GetAreaObjXPosition     ;otherwise, obtain and save horizontal pixel coordinate
984e: 48                           pha
984f: 20 4a 99                     jsr     FindEmptyEnemySlot      ;find an empty place on the enemy object buffer
9852: 68                           pla
9853: 95 87                        sta     Enemy_X_Position,x      ;then write horizontal coordinate for star flag
9855: ad 25 07                     lda     CurrentPageLoc
9858: 95 6e                        sta     Enemy_PageLoc,x         ;set page location for star flag
985a: a9 01                        lda     #$01
985c: 95 b6                        sta     Enemy_Y_HighPos,x       ;set vertical high byte
985e: 95 0f                        sta     Enemy_Flag,x            ;set flag for buffer
9860: a9 90                        lda     #$90
9862: 95 cf                        sta     Enemy_Y_Position,x      ;set vertical coordinate
9864: a9 31                        lda     #StarFlagObject         ;set star flag value in buffer itself
9866: 95 16                        sta     Enemy_ID,x
9868: 60                           rts

9869: a0 52        PlayerStop      ldy     #$52                    ;put brick at floor to stop player at end of level
986b: 8c ab 06                     sty     MetatileBuffer+10       ;this is only done if we're on the second column
986e: 60           ExitCastle      rts

                   ; -----------------------------------------------------------------------------
986f: 20 bb 9b     WaterPipe       jsr     GetLrgObjAttrib         ;get row and lower nybble
9872: bc 30 07                     ldy     AreaObjectLength,x      ;get length (residual code, water pipe is 1 col thick)
9875: a6 07                        ldx     $07                     ;get row
9877: a9 6b                        lda     #$6b
9879: 9d a1 06                     sta     MetatileBuffer,x        ;draw something here and below it
987c: a9 6c                        lda     #$6c
987e: 9d a2 06                     sta     MetatileBuffer+1,x
9881: 60                           rts

                   ; -----------------------------------------------------------------------------
                   ; $05 - used to store length of vertical shaft in RenderSidewaysPipe
                   ; $06 - used to store leftover horizontal length in RenderSidewaysPipe and
                   ; vertical length in VerticalPipe and GetPipeHeight
9882: a0 03        IntroPipe       ldy     #$03                    ;check if length set, if not set, set it
9884: 20 af 9b                     jsr     ChkLrgObjFixedLength
9887: a0 0a                        ldy     #$0a                    ;set fixed value and render the sideways part
9889: 20 b3 98                     jsr     RenderSidewaysPipe
988c: b0 10                        bcs     NoBlankP                ;if carry flag set, not time to draw vertical pipe part
988e: a2 06                        ldx     #$06                    ;blank everything above the vertical pipe part
9890: a9 00        VPipeSectLoop   lda     #$00                    ; all the way to the top of the screen
9892: 9d a1 06                     sta     MetatileBuffer,x        ; because otherwise it will look like exit pipe
9895: ca                           dex
9896: 10 f8                        bpl     VPipeSectLoop
9898: b9 dd 98                     lda     VerticalPipeData,y      ;draw the end of the vertical pipe part
989b: 8d a8 06                     sta     MetatileBuffer+7
989e: 60           NoBlankP        rts

                   SidePipeShaftData
989f: 15 14                        .bulk   $15,$14                 ;used to control whether or not vertical pipe shaft
98a1: 00 00                        .bulk   $00,$00                 ; is drawn, and if so, controls the metatile number
98a3: 15 1e        SidePipeTopPart .bulk   $15,$1e                 ;top part of sideways part of pipe
98a5: 1d 1c                        .bulk   $1d,$1c
                   SidePipeBottomPart
98a7: 15 21                        .bulk   $15,$21                 ;bottom part of sideways part of pipe
98a9: 20 1f                        .bulk   $20,$1f

98ab: a0 03        ExitPipe        ldy     #$03                    ;check if length set, if not set, set it
98ad: 20 af 9b                     jsr     ChkLrgObjFixedLength
98b0: 20 bb 9b                     jsr     GetLrgObjAttrib         ;get vertical length, then plow on through RenderSidewaysPipe
                   RenderSidewaysPipe
98b3: 88                           dey                             ;decrement twice to make room for shaft at bottom
98b4: 88                           dey                             ; and store here for now as vertical length
98b5: 84 05                        sty     $05
98b7: bc 30 07                     ldy     AreaObjectLength,x      ;get length left over and store here
98ba: 84 06                        sty     $06
98bc: a6 05                        ldx     $05                     ;get vertical length plus one, use as buffer offset
98be: e8                           inx
98bf: b9 9f 98                     lda     SidePipeShaftData,y     ;check for value $00 based on horizontal offset
98c2: c9 00                        cmp     #$00
98c4: f0 08                        beq     DrawSidePart            ;if found, do not draw the vertical pipe shaft
98c6: a2 00                        ldx     #$00
98c8: a4 05                        ldy     $05                     ;init buffer offset and get vertical length
98ca: 20 7d 9b                     jsr     RenderUnderPart         ; and render vertical shaft using tile number in A
98cd: 18                           clc                             ;clear carry flag to be used by IntroPipe
98ce: a4 06        DrawSidePart    ldy     $06                     ;render side pipe part at the bottom
98d0: b9 a3 98                     lda     SidePipeTopPart,y
98d3: 9d a1 06                     sta     MetatileBuffer,x        ;note that the pipe parts are stored
98d6: b9 a7 98                     lda     SidePipeBottomPart,y    ; backwards horizontally
98d9: 9d a2 06                     sta     MetatileBuffer+1,x
98dc: 60                           rts

                   VerticalPipeData
98dd: 11 10                        .bulk   $11,$10                 ;used by pipes that lead somewhere
98df: 15 14                        .bulk   $15,$14
98e1: 13 12                        .bulk   $13,$12                 ;used by decoration pipes
98e3: 15 14                        .bulk   $15,$14

98e5: 20 39 99     VerticalPipe    jsr     GetPipeHeight
98e8: a5 00                        lda     $00                     ;check to see if value was nullified earlier
98ea: f0 04                        beq     WarpPipe                ;(if d3, the usage control bit of second byte, was set)
98ec: c8                           iny
98ed: c8                           iny
98ee: c8                           iny
98ef: c8                           iny                             ;add four if usage control bit was not set
98f0: 98           WarpPipe        tya                             ;save value in stack
98f1: 48                           pha
98f2: ad 60 07                     lda     AreaNumber
98f5: 0d 5f 07                     ora     WorldNumber             ;if at world 1-1, do not add piranha plant ever
98f8: f0 2b                        beq     DrawPipe
98fa: bc 30 07                     ldy     AreaObjectLength,x      ;if on second column of pipe, branch
98fd: f0 26                        beq     DrawPipe                ;(because we only need to do this once)
98ff: 20 4a 99                     jsr     FindEmptyEnemySlot      ;check for an empty moving data buffer space
9902: b0 21                        bcs     DrawPipe                ;if not found, too many enemies, thus skip
9904: 20 cb 9b                     jsr     GetAreaObjXPosition     ;get horizontal pixel coordinate
9907: 18                           clc
9908: 69 08                        adc     #$08                    ;add eight to put the piranha plant in the center
990a: 95 87                        sta     Enemy_X_Position,x      ;store as enemy's horizontal coordinate
990c: ad 25 07                     lda     CurrentPageLoc          ;add carry to current page number
990f: 69 00                        adc     #$00
9911: 95 6e                        sta     Enemy_PageLoc,x         ;store as enemy's page coordinate
9913: a9 01                        lda     #$01
9915: 95 b6                        sta     Enemy_Y_HighPos,x
9917: 95 0f                        sta     Enemy_Flag,x            ;activate enemy flag
9919: 20 d3 9b                     jsr     GetAreaObjYPosition     ;get piranha plant's vertical coordinate and store here
991c: 95 cf                        sta     Enemy_Y_Position,x
991e: a9 0d                        lda     #PiranhaPlant           ;write piranha plant's value into buffer
9920: 95 16                        sta     Enemy_ID,x
9922: 20 87 c7                     jsr     InitPiranhaPlant
9925: 68           DrawPipe        pla                             ;get value saved earlier and use as Y
9926: a8                           tay
9927: a6 07                        ldx     $07                     ;get buffer offset
9929: b9 dd 98                     lda     VerticalPipeData,y      ;draw the appropriate pipe with the Y we loaded earlier
992c: 9d a1 06                     sta     MetatileBuffer,x        ;render the top of the pipe
992f: e8                           inx
9930: b9 df 98                     lda     VerticalPipeData+2,y    ;render the rest of the pipe
9933: a4 06                        ldy     $06                     ;subtract one from length and render the part underneath
9935: 88                           dey
9936: 4c 7d 9b                     jmp     RenderUnderPart

9939: a0 01        GetPipeHeight   ldy     #$01                    ;check for length loaded, if not, load
993b: 20 af 9b                     jsr     ChkLrgObjFixedLength    ;pipe length of 2 (horizontal)
993e: 20 bb 9b                     jsr     GetLrgObjAttrib
9941: 98                           tya                             ;get saved lower nybble as height
9942: 29 07                        and     #$07                    ;save only the three lower bits as
9944: 85 06                        sta     $06                     ; vertical length, then load Y with
9946: bc 30 07                     ldy     AreaObjectLength,x      ; length left over
9949: 60                           rts

                   FindEmptyEnemySlot
994a: a2 00                        ldx     #$00                    ;start at first enemy slot
994c: 18           EmptyChkLoop    clc                             ;clear carry flag by default
994d: b5 0f                        lda     Enemy_Flag,x            ;check enemy buffer for nonzero
994f: f0 05                        beq     ExitEmptyChk            ;if zero, leave
9951: e8                           inx
9952: e0 05                        cpx     #$05                    ;if nonzero, check next value
9954: d0 f6                        bne     EmptyChkLoop
9956: 60           ExitEmptyChk    rts                             ;if all values nonzero, carry flag is set

                   ; -----------------------------------------------------------------------------
9957: 20 ac 9b     Hole_Water      jsr     ChkLrgObjLength         ;get low nybble and save as length
995a: a9 86                        lda     #$86                    ;render waves
995c: 8d ab 06                     sta     MetatileBuffer+10
995f: a2 0b                        ldx     #$0b
9961: a0 01                        ldy     #$01                    ;now render the water underneath
9963: a9 87                        lda     #$87
9965: 4c 7d 9b                     jmp     RenderUnderPart

                   ; -----------------------------------------------------------------------------
                   QuestionBlockRow_High
9968: a9 03                        lda     #$03                    ;start on the fourth row
996a: 2c                           bit β–Ό   PseudoRandomBitReg+2    ;BIT instruction opcode
                   QuestionBlockRow_Low
996b: a9 07                        lda     #$07                    ;start on the eighth row
996d: 48                           pha                             ;save whatever row to the stack for now
996e: 20 ac 9b                     jsr     ChkLrgObjLength         ;get low nybble and save as length
9971: 68                           pla
9972: aa                           tax                             ;render question boxes with coins
9973: a9 c0                        lda     #$c0
9975: 9d a1 06                     sta     MetatileBuffer,x
9978: 60                           rts

                   ; -----------------------------------------------------------------------------
9979: a9 06        Bridge_High     lda     #$06                    ;start on the seventh row from top of screen
997b: 2c                           bit β–Ό   PseudoRandomBitReg+2    ;BIT instruction opcode
997c: a9 07        Bridge_Middle   lda     #$07                    ;start on the eighth row
997e: 2c                           bit β–Ό   $09a9                   ;BIT instruction opcode
997f: a9 09        Bridge_Low      lda     #$09                    ;start on the tenth row
9981: 48                           pha                             ;save whatever row to the stack for now
9982: 20 ac 9b                     jsr     ChkLrgObjLength         ;get low nybble and save as length
9985: 68                           pla
9986: aa                           tax                             ;render bridge railing
9987: a9 0b                        lda     #$0b
9989: 9d a1 06                     sta     MetatileBuffer,x
998c: e8                           inx
998d: a0 00                        ldy     #$00                    ;now render the bridge itself
998f: a9 63                        lda     #$63
9991: 4c 7d 9b                     jmp     RenderUnderPart

                   ; -----------------------------------------------------------------------------
                   FlagBalls_Residual
9994: 20 bb 9b                     jsr     GetLrgObjAttrib         ;get low nybble from object byte
9997: a2 02                        ldx     #$02                    ;render flag balls on third row from top
9999: a9 6d                        lda     #$6d                    ; of screen downwards based on low nybble
999b: 4c 7d 9b                     jmp     RenderUnderPart

                   ; -----------------------------------------------------------------------------
999e: a9 24        FlagpoleObject  lda     #$24                    ;render flagpole ball on top
99a0: 8d a1 06                     sta     MetatileBuffer
99a3: a2 01                        ldx     #$01                    ;now render the flagpole shaft
99a5: a0 08                        ldy     #$08
99a7: a9 25                        lda     #$25
99a9: 20 7d 9b                     jsr     RenderUnderPart
99ac: a9 61                        lda     #$61                    ;render solid block at the bottom
99ae: 8d ab 06                     sta     MetatileBuffer+10
99b1: 20 cb 9b                     jsr     GetAreaObjXPosition
99b4: 38                           sec                             ;get pixel coordinate of where the flagpole is,
99b5: e9 08                        sbc     #$08                    ; subtract eight pixels and use as horizontal
99b7: 85 8c                        sta     Enemy_X_Position+5      ; coordinate for the flag
99b9: ad 25 07                     lda     CurrentPageLoc
99bc: e9 00                        sbc     #$00                    ;subtract borrow from page location and use as
99be: 85 73                        sta     Enemy_PageLoc+5         ; page location for the flag
99c0: a9 30                        lda     #$30
99c2: 85 d4                        sta     Enemy_Y_Position+5      ;set vertical coordinate for flag
99c4: a9 b0                        lda     #$b0
99c6: 8d 0d 01                     sta     FlagpoleFNum_Y_Pos      ;set initial vertical coordinate for flagpole's floatey number
99c9: a9 30                        lda     #FlagpoleFlagObject
99cb: 85 1b                        sta     Enemy_ID+5              ;set flag identifier, note that identifier and coordinates
99cd: e6 14                        inc     Enemy_Flag+5            ;use last space in enemy object buffer
99cf: 60                           rts

                   ; -----------------------------------------------------------------------------
99d0: a2 00        EndlessRope     ldx     #$00                    ;render rope from the top to the bottom of screen
99d2: a0 0f                        ldy     #$0f
99d4: 4c e9 99                     jmp     DrawRope

99d7: 8a           BalancePlatRope txa                             ;save object buffer offset for now
99d8: 48                           pha
99d9: a2 01                        ldx     #$01                    ;blank out all from second row to the bottom
99db: a0 0f                        ldy     #$0f                    ; with blank used for balance platform rope
99dd: a9 44                        lda     #$44
99df: 20 7d 9b                     jsr     RenderUnderPart
99e2: 68                           pla                             ;get back object buffer offset
99e3: aa                           tax
99e4: 20 bb 9b                     jsr     GetLrgObjAttrib         ;get vertical length from lower nybble
99e7: a2 01                        ldx     #$01
99e9: a9 40        DrawRope        lda     #$40                    ;render the actual rope
99eb: 4c 7d 9b                     jmp     RenderUnderPart

                   ; -----------------------------------------------------------------------------
                   CoinMetatileData
99ee: c3 c2 c2 c2                  .bulk   $c3,$c2,$c2,$c2

99f2: ac 4e 07     RowOfCoins      ldy     AreaType                ;get area type
99f5: b9 ee 99                     lda     CoinMetatileData,y      ;load appropriate coin metatile
99f8: 4c 44 9a                     jmp     GetRow

                   ; -----------------------------------------------------------------------------
99fb: 06 07 08     C_ObjectRow     .bulk   $06,$07,$08
                   C_ObjectMetatile
99fe: c5 0c 89                     .bulk   $c5,$0c,$89

9a01: a0 0c        CastleBridgeObj ldy     #$0c                    ;load length of 13 columns
9a03: 20 af 9b                     jsr     ChkLrgObjFixedLength
9a06: 4c 0e 9a                     jmp     ChainObj

9a09: a9 08        AxeObj          lda     #$08                    ;load bowser's palette into sprite portion of palette
9a0b: 8d 73 07                     sta     VRAM_Buffer_AddrCtrl
9a0e: a4 00        ChainObj        ldy     $00                     ;get value loaded earlier from decoder
9a10: be f9 99                     ldx     C_ObjectRow-2,y         ;get appropriate row and metatile for object
9a13: b9 fc 99                     lda     C_ObjectMetatile-2,y
9a16: 4c 20 9a                     jmp     ColObj

9a19: 20 bb 9b     EmptyBlock      jsr     GetLrgObjAttrib         ;get row location
9a1c: a6 07                        ldx     $07
9a1e: a9 c4                        lda     #$c4
9a20: a0 00        ColObj          ldy     #$00                    ;column length of 1
9a22: 4c 7d 9b                     jmp     RenderUnderPart

                   SolidBlockMetatiles
9a25: 69 61 61 62                  .bulk   $69,$61,$61,$62
9a29: 22 51 52 52  BrickMetatiles  .bulk   $22,$51,$52,$52
9a2d: 88                           .dd1    $88                     ;used only by row of bricks object

9a2e: ac 4e 07     RowOfBricks     ldy     AreaType                ;load area type obtained from area offset pointer
9a31: ad 43 07                     lda     CloudTypeOverride       ;check for cloud type override
9a34: f0 02                        beq     DrawBricks
9a36: a0 04                        ldy     #$04                    ;if cloud type, override area type
9a38: b9 29 9a     DrawBricks      lda     BrickMetatiles,y        ;get appropriate metatile
9a3b: 4c 44 9a                     jmp     GetRow                  ;and go render it

                   RowOfSolidBlocks
9a3e: ac 4e 07                     ldy     AreaType                ;load area type obtained from area offset pointer
9a41: b9 25 9a                     lda     SolidBlockMetatiles,y   ;get metatile
9a44: 48           GetRow          pha                             ;store metatile here
9a45: 20 ac 9b                     jsr     ChkLrgObjLength         ;get row number, load length
9a48: a6 07        DrawRow         ldx     $07
9a4a: a0 00                        ldy     #$00                    ;set vertical height of 1
9a4c: 68                           pla
9a4d: 4c 7d 9b                     jmp     RenderUnderPart         ;render object

9a50: ac 4e 07     ColumnOfBricks  ldy     AreaType                ;load area type obtained from area offset
9a53: b9 29 9a                     lda     BrickMetatiles,y        ;get metatile (no cloud override as for row)
9a56: 4c 5f 9a                     jmp     GetRow2

                   ColumnOfSolidBlocks
9a59: ac 4e 07                     ldy     AreaType                ;load area type obtained from area offset
9a5c: b9 25 9a                     lda     SolidBlockMetatiles,y   ;get metatile
9a5f: 48           GetRow2         pha                             ;save metatile to stack for now
9a60: 20 bb 9b                     jsr     GetLrgObjAttrib         ;get length and row
9a63: 68                           pla                             ;restore metatile
9a64: a6 07                        ldx     $07                     ;get starting row
9a66: 4c 7d 9b                     jmp     RenderUnderPart         ;now render the column

                   ; -----------------------------------------------------------------------------
                   BulletBillCannon
9a69: 20 bb 9b                     jsr     GetLrgObjAttrib         ;get row and length of bullet bill cannon
9a6c: a6 07                        ldx     $07                     ;start at first row
9a6e: a9 64                        lda     #$64                    ;render bullet bill cannon
9a70: 9d a1 06                     sta     MetatileBuffer,x
9a73: e8                           inx
9a74: 88                           dey                             ;done yet?
9a75: 30 0e                        bmi     SetupCannon
9a77: a9 65                        lda     #$65                    ;if not, render middle part
9a79: 9d a1 06                     sta     MetatileBuffer,x
9a7c: e8                           inx
9a7d: 88                           dey                             ;done yet?
9a7e: 30 05                        bmi     SetupCannon
9a80: a9 66                        lda     #$66                    ;if not, render bottom until length expires
9a82: 20 7d 9b                     jsr     RenderUnderPart
9a85: ae 6a 04     SetupCannon     ldx     Cannon_Offset           ;get offset for data used by cannons and whirlpools
9a88: 20 d3 9b                     jsr     GetAreaObjYPosition     ;get proper vertical coordinate for cannon
9a8b: 9d 77 04                     sta     Cannon_Y_Position,x     ;and store it here
9a8e: ad 25 07                     lda     CurrentPageLoc
9a91: 9d 6b 04                     sta     Cannon_PageLoc,x        ;store page number for cannon here
9a94: 20 cb 9b                     jsr     GetAreaObjXPosition     ;get proper horizontal coordinate for cannon
9a97: 9d 71 04                     sta     Cannon_X_Position,x     ; and store it here
9a9a: e8                           inx
9a9b: e0 06                        cpx     #$06                    ;increment and check offset
9a9d: 90 02                        bcc     StrCOffset              ;if not yet reached sixth cannon, branch to save offset
9a9f: a2 00                        ldx     #$00                    ;otherwise initialize it
9aa1: 8e 6a 04     StrCOffset      stx     Cannon_Offset           ;save new offset and leave
9aa4: 60                           rts

                   ; -----------------------------------------------------------------------------
                   StaircaseHeightData
9aa5: 07 07 06 05+                 .bulk   $07,$07,$06,$05,$04,$03,$02,$01,$00
                   StaircaseRowData
9aae: 03 03 04 05+                 .bulk   $03,$03,$04,$05,$06,$07,$08,$09,$0a

9ab7: 20 ac 9b     StaircaseObject jsr     ChkLrgObjLength         ;check and load length
9aba: 90 05                        bcc     NextStair               ;if length already loaded, skip init part
9abc: a9 09                        lda     #$09                    ;start past the end for the bottom
9abe: 8d 34 07                     sta     StaircaseControl        ; of the staircase
9ac1: ce 34 07     NextStair       dec     StaircaseControl        ;move onto next step (or first if starting)
9ac4: ac 34 07                     ldy     StaircaseControl
9ac7: be ae 9a                     ldx     StaircaseRowData,y      ;get starting row and height to render
9aca: b9 a5 9a                     lda     StaircaseHeightData,y
9acd: a8                           tay
9ace: a9 61                        lda     #$61                    ;now render solid block staircase
9ad0: 4c 7d 9b                     jmp     RenderUnderPart

                   ; -----------------------------------------------------------------------------
9ad3: 20 bb 9b     JumpSpring      jsr     GetLrgObjAttrib
9ad6: 20 4a 99                     jsr     FindEmptyEnemySlot      ;find empty space in enemy object buffer
9ad9: 20 cb 9b                     jsr     GetAreaObjXPosition     ;get horizontal coordinate for jumpspring
9adc: 95 87                        sta     Enemy_X_Position,x      ;and store
9ade: ad 25 07                     lda     CurrentPageLoc          ;store page location of jumpspring
9ae1: 95 6e                        sta     Enemy_PageLoc,x
9ae3: 20 d3 9b                     jsr     GetAreaObjYPosition     ;get vertical coordinate for jumpspring
9ae6: 95 cf                        sta     Enemy_Y_Position,x      ;and store
9ae8: 95 58                        sta     Jumpspring_FixedYPos,x  ;store as permanent coordinate here
9aea: a9 32                        lda     #JumpspringObject
9aec: 95 16                        sta     Enemy_ID,x              ;write jumpspring object to enemy object buffer
9aee: a0 01                        ldy     #$01
9af0: 94 b6                        sty     Enemy_Y_HighPos,x       ;store vertical high byte
9af2: f6 0f                        inc     Enemy_Flag,x            ;set flag for enemy object buffer
9af4: a6 07                        ldx     $07
9af6: a9 67                        lda     #$67                    ;draw metatiles in two rows where jumpspring is
9af8: 9d a1 06                     sta     MetatileBuffer,x
9afb: a9 68                        lda     #$68
9afd: 9d a2 06                     sta     MetatileBuffer+1,x
9b00: 60                           rts

                   ; -----------------------------------------------------------------------------
                   ; $07 - used to save ID of brick object
9b01: ad 5d 07     Hidden1UpBlock  lda     Hidden1UpFlag           ;if flag not set, do not render object
9b04: f0 36                        beq     ExitDecBlock
9b06: a9 00                        lda     #$00                    ;if set, init for the next one
9b08: 8d 5d 07                     sta     Hidden1UpFlag
9b0b: 4c 19 9b                     jmp     BrickWithItem           ;jump to code shared with unbreakable bricks

9b0e: 20 36 9b     QuestionBlock   jsr     GetAreaObjectID         ;get value from level decoder routine
9b11: 4c 2c 9b                     jmp     DrawQBlk                ;go to render it

9b14: a9 00        BrickWithCoins  lda     #$00                    ;initialize multi-coin timer flag
9b16: 8d bc 06                     sta     BrickCoinTimerFlag
9b19: 20 36 9b     BrickWithItem   jsr     GetAreaObjectID         ;save area object ID
9b1c: 84 07                        sty     $07
9b1e: a9 00                        lda     #$00                    ;load default adder for bricks with lines
9b20: ac 4e 07                     ldy     AreaType                ;check level type for ground level
9b23: 88                           dey
9b24: f0 02                        beq     BWithL                  ;if ground type, do not start with 5
9b26: a9 05                        lda     #$05                    ;otherwise use adder for bricks without lines
9b28: 18           BWithL          clc                             ;add object ID to adder
9b29: 65 07                        adc     $07
9b2b: a8                           tay                             ;use as offset for metatile
9b2c: b9 e8 bd     DrawQBlk        lda     BrickQBlockMetatiles,y  ;get appropriate metatile for brick (question block
9b2f: 48                           pha                             ; if branched to here from question block routine)
9b30: 20 bb 9b                     jsr     GetLrgObjAttrib         ;get row from location byte
9b33: 4c 48 9a                     jmp     DrawRow                 ;now render the object

9b36: a5 00        GetAreaObjectID lda     $00                     ;get value saved from area parser routine
9b38: 38                           sec
9b39: e9 00                        sbc     #$00                    ;possibly residual code
9b3b: a8                           tay                             ;save to Y
9b3c: 60           ExitDecBlock    rts

                   ; -----------------------------------------------------------------------------
9b3d: 87 00 00 00  HoleMetatiles   .bulk   $87,$00,$00,$00

9b41: 20 ac 9b     Hole_Empty      jsr     ChkLrgObjLength         ;get lower nybble and save as length
9b44: 90 2d                        bcc     NoWhirlP                ;skip this part if length already loaded
9b46: ad 4e 07                     lda     AreaType                ;check for water type level
9b49: d0 28                        bne     NoWhirlP                ;if not water type, skip this part
9b4b: ae 6a 04                     ldx     Whirlpool_Offset        ;get offset for data used by cannons and whirlpools
9b4e: 20 cb 9b                     jsr     GetAreaObjXPosition     ;get proper vertical coordinate of where we're at
9b51: 38                           sec
9b52: e9 10                        sbc     #$10                    ;subtract 16 pixels
9b54: 9d 71 04                     sta     Whirlpool_LeftExtent,x  ;store as left extent of whirlpool
9b57: ad 25 07                     lda     CurrentPageLoc          ;get page location of where we're at
9b5a: e9 00                        sbc     #$00                    ;subtract borrow
9b5c: 9d 6b 04                     sta     Whirlpool_PageLoc,x     ;save as page location of whirlpool
9b5f: c8                           iny
9b60: c8                           iny                             ;increment length by 2
9b61: 98                           tya
9b62: 0a                           asl     A                       ;multiply by 16 to get size of whirlpool
9b63: 0a                           asl     A                       ;note that whirlpool will always be
9b64: 0a                           asl     A                       ; two blocks bigger than actual size of hole
9b65: 0a                           asl     A                       ; and extend one block beyond each edge
9b66: 9d 77 04                     sta     Whirlpool_Length,x      ; save size of whirlpool here
9b69: e8                           inx
9b6a: e0 05                        cpx     #$05                    ;increment and check offset
9b6c: 90 02                        bcc     StrWOffset              ;if not yet reached fifth whirlpool, branch to save offset
9b6e: a2 00                        ldx     #$00                    ;otherwise initialize it
9b70: 8e 6a 04     StrWOffset      stx     Whirlpool_Offset        ;save new offset here
9b73: ae 4e 07     NoWhirlP        ldx     AreaType                ;get appropriate metatile, then
9b76: bd 3d 9b                     lda     HoleMetatiles,x         ; render the hole proper
9b79: a2 08                        ldx     #$08
9b7b: a0 0f                        ldy     #$0f                    ;start at ninth row and go to bottom, run RenderUnderPart
                   ; 
9b7d: 8c 35 07     RenderUnderPart sty     AreaObjectHeight        ;store vertical length to render
9b80: bc a1 06                     ldy     MetatileBuffer,x        ;check current spot to see if there's something
9b83: f0 18                        beq     DrawThisRow             ;we need to keep, if nothing, go ahead
9b85: c0 17                        cpy     #$17
9b87: f0 17                        beq     WaitOneRow              ;if middle part (tree ledge), wait until next row
9b89: c0 1a                        cpy     #$1a
9b8b: f0 13                        beq     WaitOneRow              ;if middle part (mushroom ledge), wait until next row
9b8d: c0 c0                        cpy     #$c0
9b8f: f0 0c                        beq     DrawThisRow             ;if question block w/ coin, overwrite
9b91: c0 c0                        cpy     #$c0
9b93: b0 0b                        bcs     WaitOneRow              ;if any other metatile with palette 3, wait until next row
9b95: c0 54                        cpy     #$54
9b97: d0 04                        bne     DrawThisRow             ;if cracked rock terrain, overwrite
9b99: c9 50                        cmp     #$50
9b9b: f0 03                        beq     WaitOneRow              ;if stem top of mushroom, wait until next row
9b9d: 9d a1 06     DrawThisRow     sta     MetatileBuffer,x        ;render contents of A from routine that called this
9ba0: e8           WaitOneRow      inx
9ba1: e0 0d                        cpx     #$0d                    ;stop rendering if we're at the bottom of the screen
9ba3: b0 06                        bcs     ExitUPartR
9ba5: ac 35 07                     ldy     AreaObjectHeight        ;decrement, and stop rendering if there is no more length
9ba8: 88                           dey
9ba9: 10 d2                        bpl     RenderUnderPart
9bab: 60           ExitUPartR      rts

                   ; -----------------------------------------------------------------------------
9bac: 20 bb 9b     ChkLrgObjLength jsr     GetLrgObjAttrib         ;get row location and size (length if branched to from here)
                   ChkLrgObjFixedLength
9baf: bd 30 07                     lda     AreaObjectLength,x      ;check for set length counter
9bb2: 18                           clc                             ;clear carry flag for not just starting
9bb3: 10 05                        bpl     LenSet                  ;if counter not set, load it, otherwise leave alone
9bb5: 98                           tya                             ;save length into length counter
9bb6: 9d 30 07                     sta     AreaObjectLength,x
9bb9: 38                           sec                             ;set carry flag if just starting
9bba: 60           LenSet          rts

9bbb: bc 2d 07     GetLrgObjAttrib ldy     AreaObjOffsetBuffer,x   ;get offset saved from area obj decoding routine
9bbe: b1 e7                        lda     (AreaData),y            ;get first byte of level object
9bc0: 29 0f                        and     #%00001111
9bc2: 85 07                        sta     $07                     ;save row location
9bc4: c8                           iny
9bc5: b1 e7                        lda     (AreaData),y            ;get next byte, save lower nybble (length or height)
9bc7: 29 0f                        and     #%00001111              ; as Y, then leave
9bc9: a8                           tay
9bca: 60                           rts

                   ; -----------------------------------------------------------------------------
                   GetAreaObjXPosition
9bcb: ad 26 07                     lda     CurrentColumnPos        ;multiply current offset where we're at by 16
9bce: 0a                           asl     A                       ; to obtain horizontal pixel coordinate
9bcf: 0a                           asl     A
9bd0: 0a                           asl     A
9bd1: 0a                           asl     A
9bd2: 60                           rts

                   ; -----------------------------------------------------------------------------
                   GetAreaObjYPosition
9bd3: a5 07                        lda     $07                     ;multiply value by 16
9bd5: 0a                           asl     A
9bd6: 0a                           asl     A                       ;this will give us the proper vertical pixel coordinate
9bd7: 0a                           asl     A
9bd8: 0a                           asl     A
9bd9: 18                           clc
9bda: 69 20                        adc     #32                     ;add 32 pixels for the status bar
9bdc: 60                           rts

                   ; -----------------------------------------------------------------------------
                   ; $06-$07 - used to store block buffer address used as indirect
9bdd: 00           BlockBufferAddr .dd1    <Block_Buffer_1
9bde: d0                           .dd1    <Block_Buffer_2
9bdf: 05                           .dd1    >Block_Buffer_1
9be0: 05                           .dd1    >Block_Buffer_2

                   GetBlockBufferAddr
9be1: 48                           pha                             ;take value of A, save
9be2: 4a                           lsr     A                       ;move high nybble to low
9be3: 4a                           lsr     A
9be4: 4a                           lsr     A
9be5: 4a                           lsr     A
9be6: a8                           tay                             ;use nybble as pointer to high byte
9be7: b9 df 9b                     lda     BlockBufferAddr+2,y     ; of indirect here
9bea: 85 07                        sta     $07
9bec: 68                           pla
9bed: 29 0f                        and     #%00001111              ;pull from stack, mask out high nybble
9bef: 18                           clc
9bf0: 79 dd 9b                     adc     BlockBufferAddr,y       ;add to low byte
9bf3: 85 06                        sta     $06                     ;store here and leave
9bf5: 60                           rts

                   ; -----------------------------------------------------------------------------
                   ; unused space
9bf6: ff                           .dd1    $ff
9bf7: ff                           .dd1    $ff
                   ; -----------------------------------------------------------------------------
                   AreaDataOfsLoopback
9bf8: 12 36 0e 0e+                 .bulk   $12,$36,$0e,$0e,$0e,$32,$32,$32,$0a,$26,$40

                   ; -----------------------------------------------------------------------------
9c03: 20 13 9c     LoadAreaPointer jsr     FindAreaPointer         ;find it and store it here
9c06: 8d 50 07                     sta     AreaPointer
9c09: 29 60        GetAreaType     and     #%01100000              ;mask out all but d6 and d5
9c0b: 0a                           asl     A
9c0c: 2a                           rol     A
9c0d: 2a                           rol     A
9c0e: 2a                           rol     A                       ;make %0xx00000 into %000000xx
9c0f: 8d 4e 07                     sta     AreaType                ;save 2 MSB as area type
9c12: 60                           rts

9c13: ac 5f 07     FindAreaPointer ldy     WorldNumber             ;load offset from world variable
9c16: b9 b4 9c                     lda     WorldAddrOffsets,y
9c19: 18                           clc                             ;add area number used to find data
9c1a: 6d 60 07                     adc     AreaNumber
9c1d: a8                           tay
9c1e: b9 bc 9c                     lda     AreaAddrOffsets,y       ;from there we have our area pointer
9c21: 60                           rts

                   GetAreaDataAddrs
9c22: ad 50 07                     lda     AreaPointer             ;use 2 MSB for Y
9c25: 20 09 9c                     jsr     GetAreaType
9c28: a8                           tay
9c29: ad 50 07                     lda     AreaPointer             ;mask out all but 5 LSB
9c2c: 29 1f                        and     #%00011111
9c2e: 8d 4f 07                     sta     AreaAddrsLOffset        ;save as low offset
9c31: b9 e0 9c                     lda     EnemyAddrHOffsets,y     ;load base value with 2 altered MSB,
9c34: 18                           clc                             ; then add base value to 5 LSB, result
9c35: 6d 4f 07                     adc     AreaAddrsLOffset        ; becomes offset for level data
9c38: a8                           tay
9c39: b9 e4 9c                     lda     EnemyDataAddrLow,y      ;use offset to load pointer
9c3c: 85 e9                        sta     EnemyData
9c3e: b9 06 9d                     lda     EnemyDataAddrHigh,y
9c41: 85 ea                        sta     EnemyData+1
9c43: ac 4e 07                     ldy     AreaType                ;use area type as offset
9c46: b9 28 9d                     lda     AreaDataHOffsets,y      ;do the same thing but with different base value
9c49: 18                           clc
9c4a: 6d 4f 07                     adc     AreaAddrsLOffset
9c4d: a8                           tay
9c4e: b9 2c 9d                     lda     AreaDataAddrLow,y       ;use this offset to load another pointer
9c51: 85 e7                        sta     AreaData
9c53: b9 4e 9d                     lda     AreaDataAddrHigh,y
9c56: 85 e8                        sta     AreaData+1
9c58: a0 00                        ldy     #$00                    ;load first byte of header
9c5a: b1 e7                        lda     (AreaData),y
9c5c: 48                           pha                             ;save it to the stack for now
9c5d: 29 07                        and     #%00000111              ;save 3 LSB for foreground scenery or bg color control
9c5f: c9 04                        cmp     #$04
9c61: 90 05                        bcc     StoreFore
9c63: 8d 44 07                     sta     BackgroundColorCtrl     ;if 4 or greater, save value here as bg color control
9c66: a9 00                        lda     #$00
9c68: 8d 41 07     StoreFore       sta     ForegroundScenery       ;if less, save value here as foreground scenery
9c6b: 68                           pla                             ;pull byte from stack and push it back
9c6c: 48                           pha
9c6d: 29 38                        and     #%00111000              ;save player entrance control bits
9c6f: 4a                           lsr     A                       ;shift bits over to LSBs
9c70: 4a                           lsr     A
9c71: 4a                           lsr     A
9c72: 8d 10 07                     sta     PlayerEntranceCtrl      ;save value here as player entrance control
9c75: 68                           pla                             ;pull byte again but do not push it back
9c76: 29 c0                        and     #%11000000              ;save 2 MSB for game timer setting
9c78: 18                           clc
9c79: 2a                           rol     A                       ;rotate bits over to LSBs
9c7a: 2a                           rol     A
9c7b: 2a                           rol     A
9c7c: 8d 15 07                     sta     GameTimerSetting        ;save value here as game timer setting
9c7f: c8                           iny
9c80: b1 e7                        lda     (AreaData),y            ;load second byte of header
9c82: 48                           pha                             ;save to stack
9c83: 29 0f                        and     #%00001111              ;mask out all but lower nybble
9c85: 8d 27 07                     sta     TerrainControl
9c88: 68                           pla                             ;pull and push byte to copy it to A
9c89: 48                           pha
9c8a: 29 30                        and     #%00110000              ;save 2 MSB for background scenery type
9c8c: 4a                           lsr     A
9c8d: 4a                           lsr     A                       ;shift bits to LSBs
9c8e: 4a                           lsr     A
9c8f: 4a                           lsr     A
9c90: 8d 42 07                     sta     BackgroundScenery       ;save as background scenery
9c93: 68                           pla
9c94: 29 c0                        and     #%11000000
9c96: 18                           clc
9c97: 2a                           rol     A                       ;rotate bits over to LSBs
9c98: 2a                           rol     A
9c99: 2a                           rol     A
9c9a: c9 03                        cmp     #%00000011              ;if set to 3, store here
9c9c: d0 05                        bne     StoreStyle              ;and nullify other value
9c9e: 8d 43 07                     sta     CloudTypeOverride       ;otherwise store value in other place
9ca1: a9 00                        lda     #$00
9ca3: 8d 33 07     StoreStyle      sta     AreaStyle
9ca6: a5 e7                        lda     AreaData                ;increment area data address by 2 bytes
9ca8: 18                           clc
9ca9: 69 02                        adc     #$02
9cab: 85 e7                        sta     AreaData
9cad: a5 e8                        lda     AreaData+1
9caf: 69 00                        adc     #$00
9cb1: 85 e8                        sta     AreaData+1
9cb3: 60                           rts

                   ; -----------------------------------------------------------------------------
                   ; 
                   ; GAME LEVELS DATA
                   ; 
                   WorldAddrOffsets
9cb4: 00 05 0a 0e+                 .bulk   $00,$05,$0a,$0e,$13,$17,$1b,$20 ;||offsets from AreaAddrOffsets
9cbc: 25 29 c0 26+ AreaAddrOffsets .bulk   $25,$29,$c0,$26,$60     ;World1Areas
9cc1: 28 29 01 27+ World2Areas     .bulk   $28,$29,$01,$27,$62
9cc6: 24 35 20 63  World3Areas     .bulk   $24,$35,$20,$63
9cca: 22 29 41 2c+ World4Areas     .bulk   $22,$29,$41,$2c,$61
9ccf: 2a 31 26 62  World5Areas     .bulk   $2a,$31,$26,$62
9cd3: 2e 23 2d 60  World6Areas     .bulk   $2e,$23,$2d,$60
9cd7: 33 29 01 27+ World7Areas     .bulk   $33,$29,$01,$27,$64
9cdc: 30 32 21 65  World8Areas     .bulk   $30,$32,$21,$65
                   ; 
                   ; bonus area data offsets, included here for comparison purposes
                   ; 
                   ; underground bonus area  - c2
                   ; cloud area 1 (day)      - 2b
                   ; cloud area 2 (night)    - 34
                   ; water area (5-2/6-2)    - 00
                   ; water area (8-4)        - 02
                   ; warp zone area (4-2)    - 2f
                   EnemyAddrHOffsets
9ce0: 1f 06 1c 00                  .bulk   $1f,$06,$1c,$00
                   EnemyDataAddrLow
9ce4: 70                           .dd1    <E_CastleArea1
9ce5: 97                           .dd1    <E_CastleArea2
9ce6: b0                           .dd1    <E_CastleArea3
9ce7: df                           .dd1    <E_CastleArea4
9ce8: 0a                           .dd1    <E_CastleArea5
9ce9: 1f                           .dd1    <E_CastleArea6
9cea: 59                           .dd1    <E_GroundArea1
9ceb: 7e                           .dd1    <E_GroundArea2
9cec: 9b                           .dd1    <E_GroundArea3
9ced: a9                           .dd1    <E_GroundArea4
9cee: d0                           .dd1    <E_GroundArea5
9cef: 01                           .dd1    <E_GroundArea6
9cf0: 1f                           .dd1    <E_GroundArea7
9cf1: 3c                           .dd1    <E_GroundArea8
9cf2: 51                           .dd1    <E_GroundArea9
9cf3: 7b                           .dd1    <E_GroundArea10
9cf4: 7c                           .dd1    <E_GroundArea11
9cf5: a0                           .dd1    <E_GroundArea12
9cf6: a9                           .dd1    <E_GroundArea13
9cf7: ce                           .dd1    <E_GroundArea14
9cf8: f1                           .dd1    <E_GroundArea15
9cf9: fa                           .dd1    <E_GroundArea16
9cfa: fb                           .dd1    <E_GroundArea17
9cfb: 35                           .dd1    <E_GroundArea18
9cfc: 60                           .dd1    <E_GroundArea19
9cfd: 8e                           .dd1    <E_GroundArea20
9cfe: aa                           .dd1    <E_GroundArea21
9cff: b3                           .dd1    <E_GroundArea22
9d00: d8                           .dd1    <E_UndergroundArea1
9d01: 05                           .dd1    <E_UndergroundArea2
9d02: 33                           .dd1    <E_UndergroundArea3
9d03: 60                           .dd1    <E_WaterArea1
9d04: 71                           .dd1    <E_WaterArea2
9d05: 9b                           .dd1    <E_WaterArea3
                   EnemyDataAddrHigh
9d06: 9d                           .dd1    >E_CastleArea1
9d07: 9d                           .dd1    >E_CastleArea2
9d08: 9d                           .dd1    >E_CastleArea3
9d09: 9d                           .dd1    >E_CastleArea4
9d0a: 9e                           .dd1    >E_CastleArea5
9d0b: 9e                           .dd1    >E_CastleArea6
9d0c: 9e                           .dd1    >E_GroundArea1
9d0d: 9e                           .dd1    >E_GroundArea2
9d0e: 9e                           .dd1    >E_GroundArea3
9d0f: 9e                           .dd1    >E_GroundArea4
9d10: 9e                           .dd1    >E_GroundArea5
9d11: 9f                           .dd1    >E_GroundArea6
9d12: 9f                           .dd1    >E_GroundArea7
9d13: 9f                           .dd1    >E_GroundArea8
9d14: 9f                           .dd1    >E_GroundArea9
9d15: 9f                           .dd1    >E_GroundArea10
9d16: 9f                           .dd1    >E_GroundArea11
9d17: 9f                           .dd1    >E_GroundArea12
9d18: 9f                           .dd1    >E_GroundArea13
9d19: 9f                           .dd1    >E_GroundArea14
9d1a: 9f                           .dd1    >E_GroundArea15
9d1b: 9f                           .dd1    >E_GroundArea16
9d1c: 9f                           .dd1    >E_GroundArea17
9d1d: a0                           .dd1    >E_GroundArea18
9d1e: a0                           .dd1    >E_GroundArea19
9d1f: a0                           .dd1    >E_GroundArea20
9d20: a0                           .dd1    >E_GroundArea21
9d21: a0                           .dd1    >E_GroundArea22
9d22: a0                           .dd1    >E_UndergroundArea1
9d23: a1                           .dd1    >E_UndergroundArea2
9d24: a1                           .dd1    >E_UndergroundArea3
9d25: a1                           .dd1    >E_WaterArea1
9d26: a1                           .dd1    >E_WaterArea2
9d27: a1                           .dd1    >E_WaterArea3
                   AreaDataHOffsets
9d28: 00 03 19 1c                  .bulk   $00,$03,$19,$1c
9d2c: 06           AreaDataAddrLow .dd1    <L_WaterArea1
9d2d: 45                           .dd1    <L_WaterArea2
9d2e: c0                           .dd1    <L_WaterArea3
9d2f: 6b                           .dd1    <L_GroundArea1
9d30: ce                           .dd1    <L_GroundArea2
9d31: 37                           .dd1    <L_GroundArea3
9d32: 8a                           .dd1    <L_GroundArea4
9d33: 19                           .dd1    <L_GroundArea5
9d34: 8e                           .dd1    <L_GroundArea6
9d35: f3                           .dd1    <L_GroundArea7
9d36: 48                           .dd1    <L_GroundArea8
9d37: cd                           .dd1    <L_GroundArea9
9d38: 32                           .dd1    <L_GroundArea10
9d39: 3b                           .dd1    <L_GroundArea11
9d3a: 7a                           .dd1    <L_GroundArea12
9d3b: 8f                           .dd1    <L_GroundArea13
9d3c: f6                           .dd1    <L_GroundArea14
9d3d: 5b                           .dd1    <L_GroundArea15
9d3e: ce                           .dd1    <L_GroundArea16
9d3f: ff                           .dd1    <L_GroundArea17
9d40: 92                           .dd1    <L_GroundArea18
9d41: 05                           .dd1    <L_GroundArea19
9d42: 7e                           .dd1    <L_GroundArea20
9d43: d7                           .dd1    <L_GroundArea21
9d44: 02                           .dd1    <L_GroundArea22
9d45: 35                           .dd1    <L_UndergroundArea1
9d46: d8                           .dd1    <L_UndergroundArea2
9d47: 79                           .dd1    <L_UndergroundArea3
9d48: af                           .dd1    <L_CastleArea1
9d49: 10                           .dd1    <L_CastleArea2
9d4a: 8f                           .dd1    <L_CastleArea3
9d4b: 02                           .dd1    <L_CastleArea4
9d4c: 6f                           .dd1    <L_CastleArea5
9d4d: fa                           .dd1    <L_CastleArea6
                   AreaDataAddrHigh
9d4e: ae                           .dd1    >L_WaterArea1
9d4f: ae                           .dd1    >L_WaterArea2
9d50: ae                           .dd1    >L_WaterArea3
9d51: a4                           .dd1    >L_GroundArea1
9d52: a4                           .dd1    >L_GroundArea2
9d53: a5                           .dd1    >L_GroundArea3
9d54: a5                           .dd1    >L_GroundArea4
9d55: a6                           .dd1    >L_GroundArea5
9d56: a6                           .dd1    >L_GroundArea6
9d57: a6                           .dd1    >L_GroundArea7
9d58: a7                           .dd1    >L_GroundArea8
9d59: a7                           .dd1    >L_GroundArea9
9d5a: a8                           .dd1    >L_GroundArea10
9d5b: a8                           .dd1    >L_GroundArea11
9d5c: a8                           .dd1    >L_GroundArea12
9d5d: a8                           .dd1    >L_GroundArea13
9d5e: a8                           .dd1    >L_GroundArea14
9d5f: a9                           .dd1    >L_GroundArea15
9d60: a9                           .dd1    >L_GroundArea16
9d61: a9                           .dd1    >L_GroundArea17
9d62: aa                           .dd1    >L_GroundArea18
9d63: ab                           .dd1    >L_GroundArea19
9d64: ab                           .dd1    >L_GroundArea20
9d65: ab                           .dd1    >L_GroundArea21
9d66: ac                           .dd1    >L_GroundArea22
9d67: ac                           .dd1    >L_UndergroundArea1
9d68: ac                           .dd1    >L_UndergroundArea2
9d69: ad                           .dd1    >L_UndergroundArea3
9d6a: a1                           .dd1    >L_CastleArea1
9d6b: a2                           .dd1    >L_CastleArea2
9d6c: a2                           .dd1    >L_CastleArea3
9d6d: a3                           .dd1    >L_CastleArea4
9d6e: a3                           .dd1    >L_CastleArea5
9d6f: a3                           .dd1    >L_CastleArea6
                   ; 
                   ; ENEMY OBJECT DATA
                   ; 
                   ; level 1-4/6-4
9d70: 76 dd bb 4c+ E_CastleArea1   .bulk   $76,$dd,$bb,$4c,$ea,$1d,$1b,$cc,$56,$5d,$16,$9d,$c6,$1d,$36,$9d
                                    +      $c9,$1d,$04,$db,$49,$1d,$84,$1b,$c9,$5d,$88,$95,$0f,$08,$30,$4c
                                    +      $78,$2d,$a6,$28,$90,$b5
9d96: ff                           .dd1    $ff
                   ; level 4-4
9d97: 0f 03 56 1b+ E_CastleArea2   .bulk   $0f,$03,$56,$1b,$c9,$1b,$0f,$07,$36,$1b,$aa,$1b,$48,$95,$0f,$0a
                                    +      $2a,$1b,$5b,$0c,$78,$2d,$90,$b5
9daf: ff                           .dd1    $ff
                   ; level 2-4/5-4
9db0: 0b 8c 4b 4c+ E_CastleArea3   .bulk   $0b,$8c,$4b,$4c,$77,$5f,$eb,$0c,$bd,$db,$19,$9d,$75,$1d,$7d,$5b
                                    +      $d9,$1d,$3d,$dd,$99,$1d,$26,$9d,$5a,$2b,$8a,$2c,$ca,$1b,$20,$95
                                    +      $7b,$5c,$db,$4c,$1b,$cc,$3b,$cc,$78,$2d,$a6,$28,$90,$b5
9dde: ff                           .dd1    $ff
                   ; level 3-4
9ddf: 0b 8c 3b 1d+ E_CastleArea4   .bulk   $0b,$8c,$3b,$1d,$8b,$1d,$ab,$0c,$db,$1d,$0f,$03,$65,$1d,$6b,$1b
                                    +      $05,$9d,$0b,$1b,$05,$9b,$0b,$1d,$8b,$0c,$1b,$8c,$70,$15,$7b,$0c
                                    +      $db,$0c,$0f,$08,$78,$2d,$a6,$28,$90,$b5
9e09: ff                           .dd1    $ff
                   ; level 7-4
9e0a: 27 a9 4b 0c+ E_CastleArea5   .bulk   $27,$a9,$4b,$0c,$68,$29,$0f,$06,$77,$1b,$0f,$0b,$60,$15,$4b,$8c
                                    +      $78,$2d,$90,$b5
9e1e: ff                           .dd1    $ff
                   ; level 8-4
9e1f: 0f 03 8e 65+ E_CastleArea6   .bulk   $0f,$03,$8e,$65,$e1,$bb,$38,$6d,$a8,$3e,$e5,$e7,$0f,$08,$0b,$02
                                    +      $2b,$02,$5e,$65,$e1,$bb,$0e,$db,$0e,$bb,$8e,$db,$0e,$fe,$65,$ec
                                    +      $0f,$0d,$4e,$65,$e1,$0f,$0e,$4e,$02,$e0,$0f,$10,$fe,$e5,$e1,$1b
                                    +      $85,$7b,$0c,$5b,$95,$78,$2d,$90,$b5
9e58: ff                           .dd1    $ff
                   ; level 3-3
9e59: a5 86 e4 28+ E_GroundArea1   .bulk   $a5,$86,$e4,$28,$18,$a8,$45,$83,$69,$03,$c6,$29,$9b,$83,$16,$a4
                                    +      $88,$24,$e9,$28,$05,$a8,$7b,$28,$24,$8f,$c8,$03,$e8,$03,$46,$a8
                                    +      $85,$24,$c8,$24
9e7d: ff                           .dd1    $ff
                   ; level 8-3
9e7e: eb 8e 0f 03+ E_GroundArea2   .bulk   $eb,$8e,$0f,$03,$fb,$05,$17,$85,$db,$8e,$0f,$07,$57,$05,$7b,$05
                                    +      $9b,$80,$2b,$85,$fb,$05,$0f,$0b,$1b,$05,$9b,$05
9e9a: ff                           .dd1    $ff
                   ; level 4-1
9e9b: 2e c2 66 e2+ E_GroundArea3   .bulk   $2e,$c2,$66,$e2,$11,$0f,$07,$02,$11,$0f,$0c,$12,$11
9ea8: ff                           .dd1    $ff
                   ; level 6-2
9ea9: 0e c2 a8 ab+ E_GroundArea4   .bulk   $0e,$c2,$a8,$ab,$00,$bb,$8e,$6b,$82,$de,$00,$a0,$33,$86,$43,$06
                                    +      $3e,$b4,$a0,$cb,$02,$0f,$07,$7e,$42,$a6,$83,$02,$0f,$0a,$3b,$02
                                    +      $cb,$37,$0f,$0c,$e3,$0e
9ecf: ff                           .dd1    $ff
                   ; level 3-1
9ed0: 9b 8e ca 0e+ E_GroundArea5   .bulk   $9b,$8e,$ca,$0e,$ee,$42,$44,$5b,$86,$80,$b8,$1b,$80,$50,$ba,$10
                                    +      $b7,$5b,$00,$17,$85,$4b,$05,$fe,$34,$40,$b7,$86,$c6,$06,$5b,$80
                                    +      $83,$00,$d0,$38,$5b,$8e,$8a,$0e,$a6,$00,$bb,$0e,$c5,$80,$f3,$00
9f00: ff                           .dd1    $ff
                   ; level 1-1
9f01: 1e c2 00 6b+ E_GroundArea6   .bulk   $1e,$c2,$00,$6b,$06,$8b,$86,$63,$b7,$0f,$05,$03,$06,$23,$06,$4b
                                    +      $b7,$bb,$00,$5b,$b7,$fb,$37,$3b,$b7,$0f,$0b,$1b,$37
9f1e: ff                           .dd1    $ff
                   ; level 1-3/5-3
9f1f: 2b d7 e3 03+ E_GroundArea7   .bulk   $2b,$d7,$e3,$03,$c2,$86,$e2,$06,$76,$a5,$a3,$8f,$03,$86,$2b,$57
                                    +      $68,$28,$e9,$28,$e5,$83,$24,$8f,$36,$a8,$5b,$03
9f3b: ff                           .dd1    $ff
                   ; level 2-3/7-3
9f3c: 0f 02 78 40+ E_GroundArea8   .bulk   $0f,$02,$78,$40,$48,$ce,$f8,$c3,$f8,$c3,$0f,$07,$7b,$43,$c6,$d0
                                    +      $0f,$8a,$c8,$50
9f50: ff                           .dd1    $ff
                   ; level 2-1
9f51: 85 86 0b 80+ E_GroundArea9   .bulk   $85,$86,$0b,$80,$1b,$00,$db,$37,$77,$80,$eb,$37,$fe,$2b,$20,$2b
                                    +      $80,$7b,$38,$ab,$b8,$77,$86,$fe,$42,$20,$49,$86,$8b,$06,$9b,$80
                                    +      $7b,$8e,$5b,$b7,$9b,$0e,$bb,$0e,$9b,$80
                   ; end of data terminator here is also used by pipe intro area
9f7b: ff           E_GroundArea10  .dd1    $ff
                   ; level 5-1
9f7c: 0b 80 60 38+ E_GroundArea11  .bulk   $0b,$80,$60,$38,$10,$b8,$c0,$3b,$db,$8e,$40,$b8,$f0,$38,$7b,$8e
                                    +      $a0,$b8,$c0,$b8,$fb,$00,$a0,$b8,$30,$bb,$ee,$42,$88,$0f,$0b,$2b
                                    +      $0e,$67,$0e
9f9f: ff                           .dd1    $ff
                   ; cloud level used in levels 2-1 and 5-2
9fa0: 0a aa 0e 28+ E_GroundArea12  .bulk   $0a,$aa,$0e,$28,$2a,$0e,$31,$88
9fa8: ff                           .dd1    $ff
                   ; level 4-3
9fa9: c7 83 d7 03+ E_GroundArea13  .bulk   $c7,$83,$d7,$03,$42,$8f,$7a,$03,$05,$a4,$78,$24,$a6,$25,$e4,$25
                                    +      $4b,$83,$e3,$03,$05,$a4,$89,$24,$b5,$24,$09,$a4,$65,$24,$c9,$24
                                    +      $0f,$08,$85,$25
9fcd: ff                           .dd1    $ff
                   ; level 6-3
9fce: cd a5 b5 a8+ E_GroundArea14  .bulk   $cd,$a5,$b5,$a8,$07,$a8,$76,$28,$cc,$25,$65,$a4,$a9,$24,$e5,$24
                                    +      $19,$a4,$0f,$07,$95,$28,$e6,$24,$19,$a4,$d7,$29,$16,$a9,$58,$29
                                    +      $97,$29
9ff0: ff                           .dd1    $ff
                   ; level 6-1
9ff1: 0f 02 02 11+ E_GroundArea15  .bulk   $0f,$02,$02,$11,$0f,$07,$02,$11
9ff9: ff                           .dd1    $ff
                   ; warp zone area used in level 4-2
9ffa: ff           E_GroundArea16  .dd1    $ff
                   ; level 8-1
9ffb: 2b 82 ab 38+ E_GroundArea17  .bulk   $2b,$82,$ab,$38,$de,$42,$e2,$1b,$b8,$eb,$3b,$db,$80,$8b,$b8,$1b
                                    +      $82,$fb,$b8,$7b,$80,$fb,$3c,$5b,$bc,$7b,$b8,$1b,$8e,$cb,$0e,$1b
                                    +      $8e,$0f,$0d,$2b,$3b,$bb,$b8,$eb,$82,$4b,$b8,$bb,$38,$3b,$b7,$bb
                                    +      $02,$0f,$13,$1b,$00,$cb,$80,$6b,$bc
a034: ff                           .dd1    $ff
                   ; level 5-2
a035: 7b 80 ae 00+ E_GroundArea18  .bulk   $7b,$80,$ae,$00,$80,$8b,$8e,$e8,$05,$f9,$86,$17,$86,$16,$85,$4e
                                    +      $2b,$80,$ab,$8e,$87,$85,$c3,$05,$8b,$82,$9b,$02,$ab,$02,$bb,$86
                                    +      $cb,$06,$d3,$03,$3b,$8e,$6b,$0e,$a7,$8e
a05f: ff                           .dd1    $ff
                   ; level 8-2
a060: 29 8e 52 11+ E_GroundArea19  .bulk   $29,$8e,$52,$11,$83,$0e,$0f,$03,$9b,$0e,$2b,$8e,$5b,$0e,$cb,$8e
                                    +      $fb,$0e,$fb,$82,$9b,$82,$bb,$02,$fe,$42,$e8,$bb,$8e,$0f,$0a,$ab
                                    +      $0e,$cb,$0e,$f9,$0e,$88,$86,$a6,$06,$db,$02,$b6,$8e
a08d: ff                           .dd1    $ff
                   ; level 7-1
a08e: ab ce de 42+ E_GroundArea20  .bulk   $ab,$ce,$de,$42,$c0,$cb,$ce,$5b,$8e,$1b,$ce,$4b,$85,$67,$45,$0f
                                    +      $07,$2b,$00,$7b,$85,$97,$05,$0f,$0a,$92,$02
a0a9: ff                           .dd1    $ff
                   ; cloud level used in levels 3-1 and 6-2
a0aa: 0a aa 0e 24+ E_GroundArea21  .bulk   $0a,$aa,$0e,$24,$4a,$1e,$23,$aa
a0b2: ff                           .dd1    $ff
                   ; level 3-2
a0b3: 1b 80 bb 38+ E_GroundArea22  .bulk   $1b,$80,$bb,$38,$4b,$bc,$eb,$3b,$0f,$04,$2b,$00,$ab,$38,$eb,$00
                                    +      $cb,$8e,$fb,$80,$ab,$b8,$6b,$80,$fb,$3c,$9b,$bb,$5b,$bc,$fb,$00
                                    +      $6b,$b8,$fb,$38
a0d7: ff                           .dd1    $ff
                   ; level 1-2
                   E_UndergroundArea1
a0d8: 0b 86 1a 06+                 .bulk   $0b,$86,$1a,$06,$db,$06,$de,$c2,$02,$f0,$3b,$bb,$80,$eb,$06,$0b
                                    +      $86,$93,$06,$f0,$39,$0f,$06,$60,$b8,$1b,$86,$a0,$b9,$b7,$27,$bd
                                    +      $27,$2b,$83,$a1,$26,$a9,$26,$ee,$25,$0b,$27,$b4
a104: ff                           .dd1    $ff
                   ; level 4-2
                   E_UndergroundArea2
a105: 0f 02 1e 2f+                 .bulk   $0f,$02,$1e,$2f,$60,$e0,$3a,$a5,$a7,$db,$80,$3b,$82,$8b,$02,$fe
                                    +      $42,$68,$70,$bb,$25,$a7,$2c,$27,$b2,$26,$b9,$26,$9b,$80,$a8,$82
                                    +      $b5,$27,$bc,$27,$b0,$bb,$3b,$82,$87,$34,$ee,$25,$6b
a132: ff                           .dd1    $ff
                   ; underground bonus rooms area used in many levels
                   E_UndergroundArea3
a133: 1e a5 0a 2e+                 .bulk   $1e,$a5,$0a,$2e,$28,$27,$2e,$33,$c7,$0f,$03,$1e,$40,$07,$2e,$30
                                    +      $e7,$0f,$05,$1e,$24,$44,$0f,$07,$1e,$22,$6a,$2e,$23,$ab,$0f,$09
                                    +      $1e,$41,$68,$1e,$2a,$8a,$2e,$23,$a2,$2e,$32,$ea
a15f: ff                           .dd1    $ff
                   ; water area used in levels 5-2 and 6-2
a160: 3b 87 66 27+ E_WaterArea1    .bulk   $3b,$87,$66,$27,$cc,$27,$ee,$31,$87,$ee,$23,$a7,$3b,$87,$db,$07
a170: ff                           .dd1    $ff
                   ; level 2-2/7-2
a171: 0f 01 2e 25+ E_WaterArea2    .bulk   $0f,$01,$2e,$25,$2b,$2e,$25,$4b,$4e,$25,$cb,$6b,$07,$97,$47,$e9
                                    +      $87,$47,$c7,$7a,$07,$d6,$c7,$78,$07,$38,$87,$ab,$47,$e3,$07,$9b
                                    +      $87,$0f,$09,$68,$47,$db,$c7,$3b,$c7
a19a: ff                           .dd1    $ff
                   ; water area used in level 8-4
a19b: 47 9b cb 07+ E_WaterArea3    .bulk   $47,$9b,$cb,$07,$fa,$1d,$86,$9b,$3a,$87,$56,$07,$88,$1b,$07,$9d
                                    +      $2e,$65,$f0
a1ae: ff                           .dd1    $ff
                   ; 
                   ; AREA OBJECT DATA
                   ; 
                   ; level 1-4/6-4
a1af: 9b 07        L_CastleArea1   .bulk   $9b,$07
a1b1: 05 32 06 33+                 .bulk   $05,$32,$06,$33,$07,$34,$ce,$03,$dc,$51,$ee,$07,$73,$e0,$74,$0a
                                    +      $7e,$06,$9e,$0a,$ce,$06,$e4,$00,$e8,$0a,$fe,$0a,$2e,$89,$4e,$0b
                                    +      $54,$0a,$14,$8a,$c4,$0a,$34,$8a,$7e,$06,$c7,$0a,$01,$e0,$02,$0a
                                    +      $47,$0a,$81,$60,$82,$0a,$c7,$0a,$0e,$87,$7e,$02,$a7,$02,$b3,$02
                                    +      $d7,$02,$e3,$02,$07,$82,$13,$02,$3e,$06,$7e,$02,$ae,$07,$fe,$0a
                                    +      $0d,$c4,$cd,$43,$ce,$09,$de,$0b,$dd,$42,$fe,$02,$5d,$c7
a20f: fd                           .dd1    $fd
                   ; level 4-4
a210: 5b 07        L_CastleArea2   .bulk   $5b,$07
a212: 05 32 06 33+                 .bulk   $05,$32,$06,$33,$07,$34,$5e,$0a,$68,$64,$98,$64,$a8,$64,$ce,$06
                                    +      $fe,$02,$0d,$01,$1e,$0e,$7e,$02,$94,$63,$b4,$63,$d4,$63,$f4,$63
                                    +      $14,$e3,$2e,$0e,$5e,$02,$64,$35,$88,$72,$be,$0e,$0d,$04,$ae,$02
                                    +      $ce,$08,$cd,$4b,$fe,$02,$0d,$05,$68,$31,$7e,$0a,$96,$31,$a9,$63
                                    +      $a8,$33,$d5,$30,$ee,$02,$e6,$62,$f4,$61,$04,$b1,$08,$3f,$44,$33
                                    +      $94,$63,$a4,$31,$e4,$31,$04,$bf,$08,$3f,$04,$bf,$08,$3f,$cd,$4b
                                    +      $03,$e4,$0e,$03,$2e,$01,$7e,$06,$be,$02,$de,$06,$fe,$0a,$0d,$c4
                                    +      $cd,$43,$ce,$09,$de,$0b,$dd,$42,$fe,$02,$5d,$c7
a28e: fd                           .dd1    $fd
                   ; level 2-4/5-4
a28f: 9b 07        L_CastleArea3   .bulk   $9b,$07
a291: 05 32 06 33+                 .bulk   $05,$32,$06,$33,$07,$34,$fe,$00,$27,$b1,$65,$32,$75,$0a,$71,$00
                                    +      $b7,$31,$08,$e4,$18,$64,$1e,$04,$57,$3b,$bb,$0a,$17,$8a,$27,$3a
                                    +      $73,$0a,$7b,$0a,$d7,$0a,$e7,$3a,$3b,$8a,$97,$0a,$fe,$08,$24,$8a
                                    +      $2e,$00,$3e,$40,$38,$64,$6f,$00,$9f,$00,$be,$43,$c8,$0a,$c9,$63
                                    +      $ce,$07,$fe,$07,$2e,$81,$66,$42,$6a,$42,$79,$0a,$be,$00,$c8,$64
                                    +      $f8,$64,$08,$e4,$2e,$07,$7e,$03,$9e,$07,$be,$03,$de,$07,$fe,$0a
                                    +      $03,$a5,$0d,$44,$cd,$43,$ce,$09,$dd,$42,$de,$0b,$fe,$02,$5d,$c7
a301: fd                           .dd1    $fd
                   ; level 3-4
a302: 9b 07        L_CastleArea4   .bulk   $9b,$07
a304: 05 32 06 33+                 .bulk   $05,$32,$06,$33,$07,$34,$fe,$06,$0c,$81,$39,$0a,$5c,$01,$89,$0a
                                    +      $ac,$01,$d9,$0a,$fc,$01,$2e,$83,$a7,$01,$b7,$00,$c7,$01,$de,$0a
                                    +      $fe,$02,$4e,$83,$5a,$32,$63,$0a,$69,$0a,$7e,$02,$ee,$03,$fa,$32
                                    +      $03,$8a,$09,$0a,$1e,$02,$ee,$03,$fa,$32,$03,$8a,$09,$0a,$14,$42
                                    +      $1e,$02,$7e,$0a,$9e,$07,$fe,$0a,$2e,$86,$5e,$0a,$8e,$06,$be,$0a
                                    +      $ee,$07,$3e,$83,$5e,$07,$fe,$0a,$0d,$c4,$41,$52,$51,$52,$cd,$43
                                    +      $ce,$09,$de,$0b,$dd,$42,$fe,$02,$5d,$c7
a36e: fd                           .dd1    $fd
                   ; level 7-4
a36f: 5b 07        L_CastleArea5   .bulk   $5b,$07
a371: 05 32 06 33+                 .bulk   $05,$32,$06,$33,$07,$34,$fe,$0a,$ae,$86,$be,$07,$fe,$02,$0d,$02
                                    +      $27,$32,$46,$61,$55,$62,$5e,$0e,$1e,$82,$68,$3c,$74,$3a,$7d,$4b
                                    +      $5e,$8e,$7d,$4b,$7e,$82,$84,$62,$94,$61,$a4,$31,$bd,$4b,$ce,$06
                                    +      $fe,$02,$0d,$06,$34,$31,$3e,$0a,$64,$32,$75,$0a,$7b,$61,$a4,$33
                                    +      $ae,$02,$de,$0e,$3e,$82,$64,$32,$78,$32,$b4,$36,$c8,$36,$dd,$4b
                                    +      $44,$b2,$58,$32,$94,$63,$a4,$3e,$ba,$30,$c9,$61,$ce,$06,$dd,$4b
                                    +      $ce,$86,$dd,$4b,$fe,$02,$2e,$86,$5e,$02,$7e,$06,$fe,$02,$1e,$86
                                    +      $3e,$02,$5e,$06,$7e,$02,$9e,$06,$fe,$0a,$0d,$c4,$cd,$43,$ce,$09
                                    +      $de,$0b,$dd,$42,$fe,$02,$5d,$c7
a3f9: fd                           .dd1    $fd
                   ; level 8-4
a3fa: 5b 06        L_CastleArea6   .bulk   $5b,$06
a3fc: 05 32 06 33+                 .bulk   $05,$32,$06,$33,$07,$34,$5e,$0a,$ae,$02,$0d,$01,$39,$73,$0d,$03
                                    +      $39,$7b,$4d,$4b,$de,$06,$1e,$8a,$ae,$06,$c4,$33,$16,$fe,$a5,$77
                                    +      $fe,$02,$fe,$82,$0d,$07,$39,$73,$a8,$74,$ed,$4b,$49,$fb,$e8,$74
                                    +      $fe,$0a,$2e,$82,$67,$02,$84,$7a,$87,$31,$0d,$0b,$fe,$02,$0d,$0c
                                    +      $39,$73,$5e,$06,$c6,$76,$45,$ff,$be,$0a,$dd,$48,$fe,$06,$3d,$cb
                                    +      $46,$7e,$ad,$4a,$fe,$82,$39,$f3,$a9,$7b,$4e,$8a,$9e,$07,$fe,$0a
                                    +      $0d,$c4,$cd,$43,$ce,$09,$de,$0b,$dd,$42,$fe,$02,$5d,$c7
a46a: fd                           .dd1    $fd
                   ; level 3-3
a46b: 94 11        L_GroundArea1   .bulk   $94,$11
a46d: 0f 26 fe 10+                 .bulk   $0f,$26,$fe,$10,$28,$94,$65,$15,$eb,$12,$fa,$41,$4a,$96,$54,$40
                                    +      $a4,$42,$b7,$13,$e9,$19,$f5,$15,$11,$80,$47,$42,$71,$13,$80,$41
                                    +      $15,$92,$1b,$1f,$24,$40,$55,$12,$64,$40,$95,$12,$a4,$40,$d2,$12
                                    +      $e1,$40,$13,$c0,$2c,$17,$2f,$12,$49,$13,$83,$40,$9f,$14,$a3,$40
                                    +      $17,$92,$83,$13,$92,$41,$b9,$14,$c5,$12,$c8,$40,$d4,$40,$4b,$92
                                    +      $78,$1b,$9c,$94,$9f,$11,$df,$14,$fe,$11,$7d,$c1,$9e,$42,$cf,$20
a4cd: fd                           .dd1    $fd
                   ; level 8-3
a4ce: 90 b1        L_GroundArea2   .bulk   $90,$b1
a4d0: 0f 26 29 91+                 .bulk   $0f,$26,$29,$91,$7e,$42,$fe,$40,$28,$92,$4e,$42,$2e,$c0,$57,$73
                                    +      $c3,$25,$c7,$27,$23,$84,$33,$20,$5c,$01,$77,$63,$88,$62,$99,$61
                                    +      $aa,$60,$bc,$01,$ee,$42,$4e,$c0,$69,$11,$7e,$42,$de,$40,$f8,$62
                                    +      $0e,$c2,$ae,$40,$d7,$63,$e7,$63,$33,$a7,$37,$27,$43,$04,$cc,$01
                                    +      $e7,$73,$0c,$81,$3e,$42,$0d,$0a,$5e,$40,$88,$72,$be,$42,$e7,$87
                                    +      $fe,$40,$39,$e1,$4e,$00,$69,$60,$87,$60,$a5,$60,$c3,$31,$fe,$31
                                    +      $6d,$c1,$be,$42,$ef,$20
a536: fd                           .dd1    $fd
                   ; level 4-1
a537: 52 21        L_GroundArea3   .bulk   $52,$21
a539: 0f 20 6e 40+                 .bulk   $0f,$20,$6e,$40,$58,$f2,$93,$01,$97,$00,$0c,$81,$97,$40,$a6,$41
                                    +      $c7,$40,$0d,$04,$03,$01,$07,$01,$23,$01,$27,$01,$ec,$03,$ac,$f3
                                    +      $c3,$03,$78,$e2,$94,$43,$47,$f3,$74,$43,$47,$fb,$74,$43,$2c,$f1
                                    +      $4c,$63,$47,$00,$57,$21,$5c,$01,$7c,$72,$39,$f1,$ec,$02,$4c,$81
                                    +      $d8,$62,$ec,$01,$0d,$0d,$0f,$38,$c7,$07,$ed,$4a,$1d,$c1,$5f,$26
a589: fd                           .dd1    $fd
                   ; level 6-2
a58a: 54 21        L_GroundArea4   .bulk   $54,$21
a58c: 0f 26 a7 22+                 .bulk   $0f,$26,$a7,$22,$37,$fb,$73,$20,$83,$07,$87,$02,$93,$20,$c7,$73
                                    +      $04,$f1,$06,$31,$39,$71,$59,$71,$e7,$73,$37,$a0,$47,$04,$86,$7c
                                    +      $e5,$71,$e7,$31,$33,$a4,$39,$71,$a9,$71,$d3,$23,$08,$f2,$13,$05
                                    +      $27,$02,$49,$71,$75,$75,$e8,$72,$67,$f3,$99,$71,$e7,$20,$f4,$72
                                    +      $f7,$31,$17,$a0,$33,$20,$39,$71,$73,$28,$bc,$05,$39,$f1,$79,$71
                                    +      $a6,$21,$c3,$06,$d3,$20,$dc,$00,$fc,$00,$07,$a2,$13,$21,$5f,$32
                                    +      $8c,$00,$98,$7a,$c7,$63,$d9,$61,$03,$a2,$07,$22,$74,$72,$77,$31
                                    +      $e7,$73,$39,$f1,$58,$72,$77,$73,$d8,$72,$7f,$b1,$97,$73,$b6,$64
                                    +      $c5,$65,$d4,$66,$e3,$67,$f3,$67,$8d,$c1,$cf,$26
a618: fd                           .dd1    $fd
                   ; level 3-1
a619: 52 31        L_GroundArea5   .bulk   $52,$31
a61b: 0f 20 6e 66+                 .bulk   $0f,$20,$6e,$66,$07,$81,$36,$01,$66,$00,$a7,$22,$08,$f2,$67,$7b
                                    +      $dc,$02,$98,$f2,$d7,$20,$39,$f1,$9f,$33,$dc,$27,$dc,$57,$23,$83
                                    +      $57,$63,$6c,$51,$87,$63,$99,$61,$a3,$06,$b3,$21,$77,$f3,$f3,$21
                                    +      $f7,$2a,$13,$81,$23,$22,$53,$00,$63,$22,$e9,$0b,$0c,$83,$13,$21
                                    +      $16,$22,$33,$05,$8f,$35,$ec,$01,$63,$a0,$67,$20,$73,$01,$77,$01
                                    +      $83,$20,$87,$20,$b3,$20,$b7,$20,$c3,$01,$c7,$00,$d3,$20,$d7,$20
                                    +      $67,$a0,$77,$07,$87,$22,$e8,$62,$f5,$65,$1c,$82,$7f,$38,$8d,$c1
                                    +      $cf,$26
a68d: fd                           .dd1    $fd
                   ; level 1-1
a68e: 50 21        L_GroundArea6   .bulk   $50,$21
a690: 07 81 47 24+                 .bulk   $07,$81,$47,$24,$57,$00,$63,$01,$77,$01,$c9,$71,$68,$f2,$e7,$73
                                    +      $97,$fb,$06,$83,$5c,$01,$d7,$22,$e7,$00,$03,$a7,$6c,$02,$b3,$22
                                    +      $e3,$01,$e7,$07,$47,$a0,$57,$06,$a7,$01,$d3,$00,$d7,$01,$07,$81
                                    +      $67,$20,$93,$22,$03,$a3,$1c,$61,$17,$21,$6f,$33,$c7,$63,$d8,$62
                                    +      $e9,$61,$fa,$60,$4f,$b3,$87,$63,$9c,$01,$b7,$63,$c8,$62,$d9,$61
                                    +      $ea,$60,$39,$f1,$87,$21,$a7,$01,$b7,$20,$39,$f1,$5f,$38,$6d,$c1
                                    +      $af,$26
a6f2: fd                           .dd1    $fd
                   ; level 1-3/5-3
a6f3: 90 11        L_GroundArea7   .bulk   $90,$11
a6f5: 0f 26 fe 10+                 .bulk   $0f,$26,$fe,$10,$2a,$93,$87,$17,$a3,$14,$b2,$42,$0a,$92,$19,$40
                                    +      $36,$14,$50,$41,$82,$16,$2b,$93,$24,$41,$bb,$14,$b8,$00,$c2,$43
                                    +      $c3,$13,$1b,$94,$67,$12,$c4,$15,$53,$c1,$d2,$41,$12,$c1,$29,$13
                                    +      $85,$17,$1b,$92,$1a,$42,$47,$13,$83,$41,$a7,$13,$0e,$91,$a7,$63
                                    +      $b7,$63,$c5,$65,$d5,$65,$dd,$4a,$e3,$67,$f3,$67,$8d,$c1,$ae,$42
                                    +      $df,$20
a747: fd                           .dd1    $fd
                   ; level 2-3/7-3
a748: 90 11        L_GroundArea8   .bulk   $90,$11
a74a: 0f 26 6e 10+                 .bulk   $0f,$26,$6e,$10,$8b,$17,$af,$32,$d8,$62,$e8,$62,$fc,$3f,$ad,$c8
                                    +      $f8,$64,$0c,$be,$43,$43,$f8,$64,$0c,$bf,$73,$40,$84,$40,$93,$40
                                    +      $a4,$40,$b3,$40,$f8,$64,$48,$e4,$5c,$39,$83,$40,$92,$41,$b3,$40
                                    +      $f8,$64,$48,$e4,$5c,$39,$f8,$64,$13,$c2,$37,$65,$4c,$24,$63,$00
                                    +      $97,$65,$c3,$42,$0b,$97,$ac,$32,$f8,$64,$0c,$be,$53,$45,$9d,$48
                                    +      $f8,$64,$2a,$e2,$3c,$47,$56,$43,$ba,$62,$f8,$64,$0c,$b7,$88,$64
                                    +      $bc,$31,$d4,$45,$fc,$31,$3c,$b1,$78,$64,$8c,$38,$0b,$9c,$1a,$33
                                    +      $18,$61,$28,$61,$39,$60,$5d,$4a,$ee,$11,$0f,$b8,$1d,$c1,$3e,$42
                                    +      $6f,$20
a7cc: fd                           .dd1    $fd
                   ; level 2-1
a7cd: 52 31        L_GroundArea9   .bulk   $52,$31
a7cf: 0f 20 6e 40+                 .bulk   $0f,$20,$6e,$40,$f7,$20,$07,$84,$17,$20,$4f,$34,$c3,$03,$c7,$02
                                    +      $d3,$22,$27,$e3,$39,$61,$e7,$73,$5c,$e4,$57,$00,$6c,$73,$47,$a0
                                    +      $53,$06,$63,$22,$a7,$73,$fc,$73,$13,$a1,$33,$05,$43,$21,$5c,$72
                                    +      $c3,$23,$cc,$03,$77,$fb,$ac,$02,$39,$f1,$a7,$73,$d3,$04,$e8,$72
                                    +      $e3,$22,$26,$f4,$bc,$02,$8c,$81,$a8,$62,$17,$87,$43,$24,$a7,$01
                                    +      $c3,$04,$08,$f2,$97,$21,$a3,$02,$c9,$0b,$e1,$69,$f1,$69,$8d,$c1
                                    +      $cf,$26
a831: fd                           .dd1    $fd
                   ; pipe intro area
a832: 38 11        L_GroundArea10  .bulk   $38,$11
a834: 0f 26 ad 40+                 .bulk   $0f,$26,$ad,$40,$3d,$c7
a83a: fd                           .dd1    $fd
                   ; level 5-1
a83b: 95 b1        L_GroundArea11  .bulk   $95,$b1
a83d: 0f 26 0d 02+                 .bulk   $0f,$26,$0d,$02,$c8,$72,$1c,$81,$38,$72,$0d,$05,$97,$34,$98,$62
                                    +      $a3,$20,$b3,$06,$c3,$20,$cc,$03,$f9,$91,$2c,$81,$48,$62,$0d,$09
                                    +      $37,$63,$47,$03,$57,$21,$8c,$02,$c5,$79,$c7,$31,$f9,$11,$39,$f1
                                    +      $a9,$11,$6f,$b4,$d3,$65,$e3,$65,$7d,$c1,$bf,$26
a879: fd                           .dd1    $fd
                   ; cloud level used in levels 2-1 and 5-2
a87a: 00 c1        L_GroundArea12  .bulk   $00,$c1
a87c: 4c 00 f4 4f+                 .bulk   $4c,$00,$f4,$4f,$0d,$02,$02,$42,$43,$4f,$52,$c2,$de,$00,$5a,$c2
                                    +      $4d,$c7
a88e: fd                           .dd1    $fd
                   ; level 4-3
a88f: 90 51        L_GroundArea13  .bulk   $90,$51
a891: 0f 26 ee 10+                 .bulk   $0f,$26,$ee,$10,$0b,$94,$33,$14,$42,$42,$77,$16,$86,$44,$02,$92
                                    +      $4a,$16,$69,$42,$73,$14,$b0,$00,$c7,$12,$05,$c0,$1c,$17,$1f,$11
                                    +      $36,$12,$8f,$14,$91,$40,$1b,$94,$35,$12,$34,$42,$60,$42,$61,$12
                                    +      $87,$12,$96,$40,$a3,$14,$1c,$98,$1f,$11,$47,$12,$9f,$15,$cc,$15
                                    +      $cf,$11,$05,$c0,$1f,$15,$39,$12,$7c,$16,$7f,$11,$82,$40,$98,$12
                                    +      $df,$15,$16,$c4,$17,$14,$54,$12,$9b,$16,$28,$94,$ce,$01,$3d,$c1
                                    +      $5e,$42,$8f,$20
a8f5: fd                           .dd1    $fd
                   ; level 6-3
a8f6: 97 11        L_GroundArea14  .bulk   $97,$11
a8f8: 0f 26 fe 10+                 .bulk   $0f,$26,$fe,$10,$2b,$92,$57,$12,$8b,$12,$c0,$41,$f7,$13,$5b,$92
                                    +      $69,$0b,$bb,$12,$b2,$46,$19,$93,$71,$00,$17,$94,$7c,$14,$7f,$11
                                    +      $93,$41,$bf,$15,$fc,$13,$ff,$11,$2f,$95,$50,$42,$51,$12,$58,$14
                                    +      $a6,$12,$db,$12,$1b,$93,$46,$43,$7b,$12,$8d,$49,$b7,$14,$1b,$94
                                    +      $49,$0b,$bb,$12,$fc,$13,$ff,$12,$03,$c1,$2f,$15,$43,$12,$4b,$13
                                    +      $77,$13,$9d,$4a,$15,$c1,$a1,$41,$c3,$12,$fe,$01,$7d,$c1,$9e,$42
                                    +      $cf,$20
a95a: fd                           .dd1    $fd
                   ; level 6-1
a95b: 52 21        L_GroundArea15  .bulk   $52,$21
a95d: 0f 20 6e 44+                 .bulk   $0f,$20,$6e,$44,$0c,$f1,$4c,$01,$aa,$35,$d9,$34,$ee,$20,$08,$b3
                                    +      $37,$32,$43,$04,$4e,$21,$53,$20,$7c,$01,$97,$21,$b7,$07,$9c,$81
                                    +      $e7,$42,$5f,$b3,$97,$63,$ac,$02,$c5,$41,$49,$e0,$58,$61,$76,$64
                                    +      $85,$65,$94,$66,$a4,$22,$a6,$03,$c8,$22,$dc,$02,$68,$f2,$96,$42
                                    +      $13,$82,$17,$02,$af,$34,$f6,$21,$fc,$06,$26,$80,$2a,$24,$36,$01
                                    +      $8c,$00,$ff,$35,$4e,$a0,$55,$21,$77,$20,$87,$07,$89,$22,$ae,$21
                                    +      $4c,$82,$9f,$34,$ec,$01,$03,$e7,$13,$67,$8d,$4a,$ad,$41,$0f,$a6
a9cd: fd                           .dd1    $fd
                   ; warp zone area used in level 4-2
a9ce: 10 51        L_GroundArea16  .bulk   $10,$51
a9d0: 4c 00 c7 12+                 .bulk   $4c,$00,$c7,$12,$c6,$42,$03,$92,$02,$42,$29,$12,$63,$12,$62,$42
                                    +      $69,$14,$a5,$12,$a4,$42,$e2,$14,$e1,$44,$f8,$16,$37,$c1,$8f,$38
                                    +      $02,$bb,$28,$7a,$68,$7a,$a8,$7a,$e0,$6a,$f0,$6a,$6d,$c5
a9fe: fd                           .dd1    $fd
                   ; level 8-1
a9ff: 92 31        L_GroundArea17  .bulk   $92,$31
aa01: 0f 20 6e 40+                 .bulk   $0f,$20,$6e,$40,$0d,$02,$37,$73,$ec,$00,$0c,$80,$3c,$00,$6c,$00
                                    +      $9c,$00,$06,$c0,$c7,$73,$06,$83,$28,$72,$96,$40,$e7,$73,$26,$c0
                                    +      $87,$7b,$d2,$41,$39,$f1,$c8,$f2,$97,$e3,$a3,$23,$e7,$02,$e3,$07
                                    +      $f3,$22,$37,$e3,$9c,$00,$bc,$00,$ec,$00,$0c,$80,$3c,$00,$86,$21
                                    +      $a6,$06,$b6,$24,$5c,$80,$7c,$00,$9c,$00,$29,$e1,$dc,$05,$f6,$41
                                    +      $dc,$80,$e8,$72,$0c,$81,$27,$73,$4c,$01,$66,$74,$0d,$11,$3f,$35
                                    +      $b6,$41,$2c,$82,$36,$40,$7c,$02,$86,$40,$f9,$61,$39,$e1,$ac,$04
                                    +      $c6,$41,$0c,$83,$16,$41,$88,$f2,$39,$f1,$7c,$00,$89,$61,$9c,$00
                                    +      $a7,$63,$bc,$00,$c5,$65,$dc,$00,$e3,$67,$f3,$67,$8d,$c1,$cf,$26
aa91: fd                           .dd1    $fd
                   ; level 5-2
aa92: 55 b1        L_GroundArea18  .bulk   $55,$b1
aa94: 0f 26 cf 33+                 .bulk   $0f,$26,$cf,$33,$07,$b2,$15,$11,$52,$42,$99,$0b,$ac,$02,$d3,$24
                                    +      $d6,$42,$d7,$25,$23,$84,$cf,$33,$07,$e3,$19,$61,$78,$7a,$ef,$33
                                    +      $2c,$81,$46,$64,$55,$65,$65,$65,$ec,$74,$47,$82,$53,$05,$63,$21
                                    +      $62,$41,$96,$22,$9a,$41,$cc,$03,$b9,$91,$39,$f1,$63,$26,$67,$27
                                    +      $d3,$06,$fc,$01,$18,$e2,$d9,$07,$e9,$04,$0c,$86,$37,$22,$93,$24
                                    +      $87,$84,$ac,$02,$c2,$41,$c3,$23,$d9,$71,$fc,$01,$7f,$b1,$9c,$00
                                    +      $a7,$63,$b6,$64,$cc,$00,$d4,$66,$e3,$67,$f3,$67,$8d,$c1,$cf,$26
ab04: fd                           .dd1    $fd
                   ; level 8-2
ab05: 50 b1        L_GroundArea19  .bulk   $50,$b1
ab07: 0f 26 fc 00+                 .bulk   $0f,$26,$fc,$00,$1f,$b3,$5c,$00,$65,$65,$74,$66,$83,$67,$93,$67
                                    +      $dc,$73,$4c,$80,$b3,$20,$c9,$0b,$c3,$08,$d3,$2f,$dc,$00,$2c,$80
                                    +      $4c,$00,$8c,$00,$d3,$2e,$ed,$4a,$fc,$00,$d7,$a1,$ec,$01,$4c,$80
                                    +      $59,$11,$d8,$11,$da,$10,$37,$a0,$47,$04,$99,$11,$e7,$21,$3a,$90
                                    +      $67,$20,$76,$10,$77,$60,$87,$07,$d8,$12,$39,$f1,$ac,$00,$e9,$71
                                    +      $0c,$80,$2c,$00,$4c,$05,$c7,$7b,$39,$f1,$ec,$00,$f9,$11,$0c,$82
                                    +      $6f,$34,$f8,$11,$fa,$10,$7f,$b2,$ac,$00,$b6,$64,$cc,$01,$e3,$67
                                    +      $f3,$67,$8d,$c1,$cf,$26
ab7d: fd                           .dd1    $fd
                   ; level 7-1
ab7e: 52 b1        L_GroundArea20  .bulk   $52,$b1
ab80: 0f 20 6e 45+                 .bulk   $0f,$20,$6e,$45,$39,$91,$b3,$04,$c3,$21,$c8,$11,$ca,$10,$49,$91
                                    +      $7c,$73,$e8,$12,$88,$91,$8a,$10,$e7,$21,$05,$91,$07,$30,$17,$07
                                    +      $27,$20,$49,$11,$9c,$01,$c8,$72,$23,$a6,$27,$26,$d3,$03,$d8,$7a
                                    +      $89,$91,$d8,$72,$39,$f1,$a9,$11,$09,$f1,$63,$24,$67,$24,$d8,$62
                                    +      $28,$91,$2a,$10,$56,$21,$70,$04,$79,$0b,$8c,$00,$94,$21,$9f,$35
                                    +      $2f,$b8,$3d,$c1,$7f,$26
abd6: fd                           .dd1    $fd
                   ; cloud level used in levels 3-1 and 6-2
abd7: 06 c1        L_GroundArea21  .bulk   $06,$c1
abd9: 4c 00 f4 4f+                 .bulk   $4c,$00,$f4,$4f,$0d,$02,$06,$20,$24,$4f,$35,$a0,$36,$20,$53,$46
                                    +      $d5,$20,$d6,$20,$34,$a1,$73,$49,$74,$20,$94,$20,$b4,$20,$d4,$20
                                    +      $f4,$20,$2e,$80,$59,$42,$4d,$c7
ac01: fd                           .dd1    $fd
                   ; level 3-2
ac02: 96 31        L_GroundArea22  .bulk   $96,$31
ac04: 0f 26 0d 03+                 .bulk   $0f,$26,$0d,$03,$1a,$60,$77,$42,$c4,$00,$c8,$62,$b9,$e1,$d3,$06
                                    +      $d7,$07,$f9,$61,$0c,$81,$4e,$b1,$8e,$b1,$bc,$01,$e4,$50,$e9,$61
                                    +      $0c,$81,$0d,$0a,$84,$43,$98,$72,$0d,$0c,$0f,$38,$1d,$c1,$5f,$26
ac34: fd                           .dd1    $fd
                   ; level 1-2
                   L_UndergroundArea1
ac35: 48 0f                        .bulk   $48,$0f
ac37: 0e 01 5e 02+                 .bulk   $0e,$01,$5e,$02,$a7,$00,$bc,$73,$1a,$e0,$39,$61,$58,$62,$77,$63
                                    +      $97,$63,$b8,$62,$d6,$07,$f8,$62,$19,$e1,$75,$52,$86,$40,$87,$50
                                    +      $95,$52,$93,$43,$a5,$21,$c5,$52,$d6,$40,$d7,$20,$e5,$06,$e6,$51
                                    +      $3e,$8d,$5e,$03,$67,$52,$77,$52,$7e,$02,$9e,$03,$a6,$43,$a7,$23
                                    +      $de,$05,$fe,$02,$1e,$83,$33,$54,$46,$40,$47,$21,$56,$04,$5e,$02
                                    +      $83,$54,$93,$52,$96,$07,$97,$50,$be,$03,$c7,$23,$fe,$02,$0c,$82
                                    +      $43,$45,$45,$24,$46,$24,$90,$08,$95,$51,$78,$fa,$d7,$73,$39,$f1
                                    +      $8c,$01,$a8,$52,$b8,$52,$cc,$01,$5f,$b3,$97,$63,$9e,$00,$0e,$81
                                    +      $16,$24,$66,$04,$8e,$00,$fe,$01,$08,$d2,$0e,$06,$6f,$47,$9e,$0f
                                    +      $0e,$82,$2d,$47,$28,$7a,$68,$7a,$a8,$7a,$ae,$01,$de,$0f,$6d,$c5
acd7: fd                           .dd1    $fd
                   ; level 4-2
                   L_UndergroundArea2
acd8: 48 0f                        .bulk   $48,$0f
acda: 0e 01 5e 02+                 .bulk   $0e,$01,$5e,$02,$bc,$01,$fc,$01,$2c,$82,$41,$52,$4e,$04,$67,$25
                                    +      $68,$24,$69,$24,$ba,$42,$c7,$04,$de,$0b,$b2,$87,$fe,$02,$2c,$e1
                                    +      $2c,$71,$67,$01,$77,$00,$87,$01,$8e,$00,$ee,$01,$f6,$02,$03,$85
                                    +      $05,$02,$13,$21,$16,$02,$27,$02,$2e,$02,$88,$72,$c7,$20,$d7,$07
                                    +      $e4,$76,$07,$a0,$17,$06,$48,$7a,$76,$20,$98,$72,$79,$e1,$88,$62
                                    +      $9c,$01,$b7,$73,$dc,$01,$f8,$62,$fe,$01,$08,$e2,$0e,$00,$6e,$02
                                    +      $73,$20,$77,$23,$83,$04,$93,$20,$ae,$00,$fe,$0a,$0e,$82,$39,$71
                                    +      $a8,$72,$e7,$73,$0c,$81,$8f,$32,$ae,$00,$fe,$04,$04,$d1,$17,$04
                                    +      $26,$49,$27,$29,$df,$33,$fe,$02,$44,$f6,$7c,$01,$8e,$06,$bf,$47
                                    +      $ee,$0f,$4d,$c7,$0e,$82,$68,$7a,$ae,$01,$de,$0f,$6d,$c5
ad78: fd                           .dd1    $fd
                   ; underground bonus rooms area used in many levels
                   L_UndergroundArea3
ad79: 48 01                        .bulk   $48,$01
ad7b: 0e 01 00 5a+                 .bulk   $0e,$01,$00,$5a,$3e,$06,$45,$46,$47,$46,$53,$44,$ae,$01,$df,$4a
                                    +      $4d,$c7,$0e,$81,$00,$5a,$2e,$04,$37,$28,$3a,$48,$46,$47,$c7,$07
                                    +      $ce,$0f,$df,$4a,$4d,$c7,$0e,$81,$00,$5a,$33,$53,$43,$51,$46,$40
                                    +      $47,$50,$53,$04,$55,$40,$56,$50,$62,$43,$64,$40,$65,$50,$71,$41
                                    +      $73,$51,$83,$51,$94,$40,$95,$50,$a3,$50,$a5,$40,$a6,$50,$b3,$51
                                    +      $b6,$40,$b7,$50,$c3,$53,$df,$4a,$4d,$c7,$0e,$81,$00,$5a,$2e,$02
                                    +      $36,$47,$37,$52,$3a,$49,$47,$25,$a7,$52,$d7,$04,$df,$4a,$4d,$c7
                                    +      $0e,$81,$00,$5a,$3e,$02,$44,$51,$53,$44,$54,$44,$55,$24,$a1,$54
                                    +      $ae,$01,$b4,$21,$df,$4a,$e5,$07,$4d,$c7
ae05: fd                           .dd1    $fd
                   ; water area used in levels 5-2 and 6-2
ae06: 41 01        L_WaterArea1    .bulk   $41,$01
ae08: b4 34 c8 52+                 .bulk   $b4,$34,$c8,$52,$f2,$51,$47,$d3,$6c,$03,$65,$49,$9e,$07,$be,$01
                                    +      $cc,$03,$fe,$07,$0d,$c9,$1e,$01,$6c,$01,$62,$35,$63,$53,$8a,$41
                                    +      $ac,$01,$b3,$53,$e9,$51,$26,$c3,$27,$33,$63,$43,$64,$33,$ba,$60
                                    +      $c9,$61,$ce,$0b,$e5,$09,$ee,$0f,$7d,$ca,$7d,$47
ae44: fd                           .dd1    $fd
                   ; level 2-2/7-2
ae45: 41 01        L_WaterArea2    .bulk   $41,$01
ae47: b8 52 ea 41+                 .bulk   $b8,$52,$ea,$41,$27,$b2,$b3,$42,$16,$d4,$4a,$42,$a5,$51,$a7,$31
                                    +      $27,$d3,$08,$e2,$16,$64,$2c,$04,$38,$42,$76,$64,$88,$62,$de,$07
                                    +      $fe,$01,$0d,$c9,$23,$32,$31,$51,$98,$52,$0d,$c9,$59,$42,$63,$53
                                    +      $67,$31,$14,$c2,$36,$31,$87,$53,$17,$e3,$29,$61,$30,$62,$3c,$08
                                    +      $42,$37,$59,$40,$6a,$42,$99,$40,$c9,$61,$d7,$63,$39,$d1,$58,$52
                                    +      $c3,$67,$d3,$31,$dc,$06,$f7,$42,$fa,$42,$23,$b1,$43,$67,$c3,$34
                                    +      $c7,$34,$d1,$51,$43,$b3,$47,$33,$9a,$30,$a9,$61,$b8,$62,$be,$0b
                                    +      $d5,$09,$de,$0f,$0d,$ca,$7d,$47
aebf: fd                           .dd1    $fd
                   ; water area used in level 8-4
aec0: 49 0f        L_WaterArea3    .bulk   $49,$0f
aec2: 1e 01 39 73+                 .bulk   $1e,$01,$39,$73,$5e,$07,$ae,$0b,$1e,$82,$6e,$88,$9e,$02,$0d,$04
                                    +      $2e,$0b,$45,$09,$4e,$0f,$ed,$47
aeda: fd                           .dd1    $fd
                   ; -----------------------------------------------------------------------------
                   ; unused space
aedb: ff                           .dd1    $ff

                   ; -----------------------------------------------------------------------------
                   ; indirect jump routine called when $0770 is set to 1
aedc: ad 72 07     GameMode        lda     OperMode_Task
aedf: 20 04 8e                     jsr     JumpEngine

aee2: e4 8f                        .dd2    InitializeArea
aee4: 67 85                        .dd2    ScreenRoutines
aee6: 71 90                        .dd2    SecondaryGameSetup
aee8: ea ae                        .dd2    GameCoreRoutine

                   ; -----------------------------------------------------------------------------
aeea: ae 53 07     GameCoreRoutine ldx     CurrentPlayer           ;get which player is on the screen
aeed: bd fc 06                     lda     SavedJoypad1Bits,x      ;use appropriate player's controller bits
aef0: 8d fc 06                     sta     SavedJoypad1Bits        ; as the master controller bits
aef3: 20 4a b0                     jsr     GameRoutines            ;execute one of many possible subs
aef6: ad 72 07                     lda     OperMode_Task           ;check major task of operating mode
aef9: c9 03                        cmp     #$03                    ;if we are supposed to be here,
aefb: b0 01                        bcs     GameEngine              ; branch to the game engine itself
aefd: 60                           rts

aefe: 20 24 b6     GameEngine      jsr     ProcFireball_Bubble     ;process fireballs and air bubbles
af01: a2 00                        ldx     #$00
af03: 86 08        ProcELoop       stx     ObjectOffset            ;put incremented offset in X as enemy object offset
af05: 20 47 c0                     jsr     EnemiesAndLoopsCore     ;process enemy objects
af08: 20 c3 84                     jsr     FloateyNumbersRoutine   ;process floatey numbers
af0b: e8                           inx
af0c: e0 06                        cpx     #$06                    ;do these two subroutines until the whole buffer is done
af0e: d0 f3                        bne     ProcELoop
af10: 20 80 f1                     jsr     GetPlayerOffscreenBits  ;get offscreen bits for player object
af13: 20 2a f1                     jsr     RelativePlayerPosition  ;get relative coordinates for player object
af16: 20 e9 ee                     jsr     PlayerGfxHandler        ;draw the player
af19: 20 d4 be                     jsr     BlockObjMT_Updater      ;replace block objects with metatiles if necessary
af1c: a2 01                        ldx     #$01
af1e: 86 08                        stx     ObjectOffset            ;set offset for second
af20: 20 70 be                     jsr     BlockObjectsCore        ;process second block object
af23: ca                           dex
af24: 86 08                        stx     ObjectOffset            ;set offset for first
af26: 20 70 be                     jsr     BlockObjectsCore        ;process first block object
af29: 20 96 bb                     jsr     MiscObjectsCore         ;process misc objects (hammer, jumping coins)
af2c: 20 bc b9                     jsr     ProcessCannons          ;process bullet bill cannons
af2f: 20 b8 b7                     jsr     ProcessWhirlpools       ;process whirlpools
af32: 20 55 b8                     jsr     FlagpoleRoutine         ;process the flagpole
af35: 20 4f b7                     jsr     RunGameTimer            ;count down the game timer
af38: 20 e1 89                     jsr     ColorRotation           ;cycle one of the background colors
af3b: a5 b5                        lda     Player_Y_HighPos
af3d: c9 02                        cmp     #$02                    ;if player is below the screen, don't bother with the music
af3f: 10 11                        bpl     NoChgMus
af41: ad 9f 07                     lda     StarInvincibleTimer     ;if star mario invincibility timer at zero,
af44: f0 1e                        beq     ClrPlrPal               ; skip this part
af46: c9 04                        cmp     #$04
af48: d0 08                        bne     NoChgMus                ;if not yet at a certain point, continue
af4a: ad 7f 07                     lda     IntervalTimerControl    ;if interval timer not yet expired,
af4d: d0 03                        bne     NoChgMus                ; branch ahead, don't bother with the music
af4f: 20 ed 90                     jsr     GetAreaMusic            ;to re-attain appropriate level music
af52: ac 9f 07     NoChgMus        ldy     StarInvincibleTimer     ;get invincibility timer
af55: a5 09                        lda     FrameCounter            ;get frame counter
af57: c0 08                        cpy     #$08                    ;if timer still above certain point,
af59: b0 02                        bcs     CycleTwo                ; branch to cycle player's palette quickly
af5b: 4a                           lsr     A                       ;otherwise, divide by 8 to cycle every eighth frame
af5c: 4a                           lsr     A
af5d: 4a           CycleTwo        lsr     A                       ;if branched here, divide by 2 to cycle every other frame
af5e: 20 88 b2                     jsr     CyclePlayerPalette      ;do sub to cycle the palette (note: shares fire flower code)
af61: 4c 67 af                     jmp     SaveAB                  ; then skip this sub to finish up the game engine

af64: 20 9a b2     ClrPlrPal       jsr     ResetPalStar            ;do sub to clear player's palette bits in attributes
af67: a5 0a        SaveAB          lda     A_B_Buttons             ;save current A and B button
af69: 85 0d                        sta     PreviousA_B_Buttons     ; into temp variable to be used on next frame
af6b: a9 00                        lda     #$00
af6d: 85 0c                        sta     Left_Right_Buttons      ;nullify left and right buttons temp variable
af6f: ad 73 07     UpdScrollVar    lda     VRAM_Buffer_AddrCtrl
af72: c9 06                        cmp     #$06                    ;if vram address controller set to 6 (one of two $0341s)
af74: f0 1c                        beq     ExitEng                 ; then branch to leave
af76: ad 1f 07                     lda     AreaParserTaskNum       ;otherwise check number of tasks
af79: d0 14                        bne     RunParser
af7b: ad 3d 07                     lda     ScrollThirtyTwo         ;get horizontal scroll in 0-31 or $00-$20 range
af7e: c9 20                        cmp     #$20                    ;check to see if exceeded $21
af80: 30 10                        bmi     ExitEng                 ;branch to leave if not
af82: ad 3d 07                     lda     ScrollThirtyTwo
af85: e9 20                        sbc     #$20                    ;otherwise subtract $20 to set appropriately
af87: 8d 3d 07                     sta     ScrollThirtyTwo         ;and store
af8a: a9 00                        lda     #$00                    ;reset vram buffer offset used in conjunction with
af8c: 8d 40 03                     sta     VRAM_Buffer2_Offset     ; level graphics buffer at $0341-$035f
af8f: 20 b0 92     RunParser       jsr     AreaParserTaskHandler   ;update the name table with more level graphics
af92: 60           ExitEng         rts                             ;and after all that, we're finally done!

                   ; -----------------------------------------------------------------------------
af93: ad ff 06     ScrollHandler   lda     Player_X_Scroll         ;load value saved here
af96: 18                           clc
af97: 6d a1 03                     adc     Platform_X_Scroll       ;add value used by left/right platforms
af9a: 8d ff 06                     sta     Player_X_Scroll         ;save as new value here to impose force on scroll
af9d: ad 23 07                     lda     ScrollLock              ;check scroll lock flag
afa0: d0 59                        bne     InitScrlAmt             ;skip a bunch of code here if set
afa2: ad 55 07                     lda     Player_Pos_ForScroll
afa5: c9 50                        cmp     #$50                    ;check player's horizontal screen position
afa7: 90 52                        bcc     InitScrlAmt             ;if less than 80 pixels to the right, branch
afa9: ad 85 07                     lda     SideCollisionTimer      ;if timer related to player's side collision
afac: d0 4d                        bne     InitScrlAmt             ;not expired, branch
afae: ac ff 06                     ldy     Player_X_Scroll         ;get value and decrement by one
afb1: 88                           dey                             ;if value originally set to zero or otherwise
afb2: 30 47                        bmi     InitScrlAmt             ;negative for left movement, branch
afb4: c8                           iny
afb5: c0 02                        cpy     #$02                    ;if value $01, branch and do not decrement
afb7: 90 01                        bcc     ChkNearMid
afb9: 88                           dey                             ;otherwise decrement by one
afba: ad 55 07     ChkNearMid      lda     Player_Pos_ForScroll
afbd: c9 70                        cmp     #$70                    ;check player's horizontal screen position
afbf: 90 03                        bcc     ScrollScreen            ;if less than 112 pixels to the right, branch
afc1: ac ff 06                     ldy     Player_X_Scroll         ;otherwise get original value undecremented
afc4: 98           ScrollScreen    tya
afc5: 8d 75 07                     sta     ScrollAmount            ;save value here
afc8: 18                           clc
afc9: 6d 3d 07                     adc     ScrollThirtyTwo         ;add to value already set here
afcc: 8d 3d 07                     sta     ScrollThirtyTwo         ;save as new value here
afcf: 98                           tya
afd0: 18                           clc
afd1: 6d 1c 07                     adc     ScreenLeft_X_Pos        ;add to left side coordinate
afd4: 8d 1c 07                     sta     ScreenLeft_X_Pos        ;save as new left side coordinate
afd7: 8d 3f 07                     sta     HorizontalScroll        ;save here also
afda: ad 1a 07                     lda     ScreenLeft_PageLoc
afdd: 69 00                        adc     #$00                    ;add carry to page location for left
afdf: 8d 1a 07                     sta     ScreenLeft_PageLoc      ;side of the screen
afe2: 29 01                        and     #$01                    ;get LSB of page location
afe4: 85 00                        sta     $00                     ;save as temp variable for PPU register 1 mirror
afe6: ad 78 07                     lda     Mirror_PPU_CTRL_REG1    ;get PPU register 1 mirror
afe9: 29 fe                        and     #%11111110              ;save all bits except d0
afeb: 05 00                        ora     $00                     ;get saved bit here and save in PPU register 1
afed: 8d 78 07                     sta     Mirror_PPU_CTRL_REG1    ;mirror to be used to set name table later
aff0: 20 38 b0                     jsr     GetScreenPosition       ;figure out where the right side is
aff3: a9 08                        lda     #$08
aff5: 8d 95 07                     sta     ScrollIntervalTimer     ;set scroll timer (residual, not used elsewhere)
aff8: 4c 00 b0                     jmp     ChkPOffscr              ;skip this part

affb: a9 00        InitScrlAmt     lda     #$00
affd: 8d 75 07                     sta     ScrollAmount            ;initialize value here
b000: a2 00        ChkPOffscr      ldx     #$00                    ;set X for player offset
b002: 20 f6 f1                     jsr     GetXOffscreenBits       ;get horizontal offscreen bits for player
b005: 85 00                        sta     $00                     ;save them here
b007: a0 00                        ldy     #$00                    ;load default offset (left side)
b009: 0a                           asl     A                       ;if d7 of offscreen bits are set,
b00a: b0 07                        bcs     KeepOnscr               ;branch with default offset
b00c: c8                           iny                             ;otherwise use different offset (right side)
b00d: a5 00                        lda     $00
b00f: 29 20                        and     #%00100000              ;check offscreen bits for d5 set
b011: f0 1b                        beq     InitPlatScrl            ;if not set, branch ahead of this part
b013: b9 1c 07     KeepOnscr       lda     ScreenLeft_X_Pos,y      ;get left or right side coordinate based on offset
b016: 38                           sec
b017: f9 34 b0                     sbc     X_SubtracterData,y      ;subtract amount based on offset
b01a: 85 86                        sta     Player_X_Position       ;store as player position to prevent movement further
b01c: b9 1a 07                     lda     ScreenLeft_PageLoc,y    ;get left or right page location based on offset
b01f: e9 00                        sbc     #$00                    ;subtract borrow
b021: 85 6d                        sta     Player_PageLoc          ;save as player's page location
b023: a5 0c                        lda     Left_Right_Buttons      ;check saved controller bits
b025: d9 36 b0                     cmp     OffscrJoypadBitsData,y  ;against bits based on offset
b028: f0 04                        beq     InitPlatScrl            ;if not equal, branch
b02a: a9 00                        lda     #$00
b02c: 85 57                        sta     Player_X_Speed          ;otherwise nullify horizontal speed of player
b02e: a9 00        InitPlatScrl    lda     #$00                    ;nullify platform force imposed on scroll
b030: 8d a1 03                     sta     Platform_X_Scroll
b033: 60                           rts

                   X_SubtracterData
b034: 00 10                        .bulk   $00,$10
                   OffscrJoypadBitsData
b036: 01 02                        .bulk   $01,$02

                   ; -----------------------------------------------------------------------------
                   GetScreenPosition
b038: ad 1c 07                     lda     ScreenLeft_X_Pos        ;get coordinate of screen's left boundary
b03b: 18                           clc
b03c: 69 ff                        adc     #$ff                    ;add 255 pixels
b03e: 8d 1d 07                     sta     ScreenRight_X_Pos       ;store as coordinate of screen's right boundary
b041: ad 1a 07                     lda     ScreenLeft_PageLoc      ;get page number where left boundary is
b044: 69 00                        adc     #$00                    ;add carry from before
b046: 8d 1b 07                     sta     ScreenRight_PageLoc     ;store as page number where right boundary is
b049: 60                           rts

                   ; -----------------------------------------------------------------------------
b04a: a5 0e        GameRoutines    lda     GameEngineSubroutine    ;run routine based on number (a few of these routines are 
b04c: 20 04 8e                     jsr     JumpEngine              ; merely placeholders as conditions for other routines)

b04f: 31 91                        .dd2    Entrance_GameTimerSetup
b051: c7 b1                        .dd2    Vine_AutoClimb
b053: 06 b2                        .dd2    SideExitPipeEntry
b055: e5 b1                        .dd2    VerticalPipeEntry
b057: a4 b2                        .dd2    FlagpoleSlide
b059: ca b2                        .dd2    PlayerEndLevel
b05b: cd 91                        .dd2    PlayerLoseLife
b05d: 69 b0                        .dd2    PlayerEntrance
b05f: e9 b0                        .dd2    PlayerCtrlRoutine
b061: 33 b2                        .dd2    PlayerChangeSize
b063: 45 b2                        .dd2    PlayerInjuryBlink
b065: 69 b2                        .dd2    PlayerDeath
b067: 7d b2                        .dd2    PlayerFireFlower

b069: ad 52 07     PlayerEntrance  lda     AltEntranceControl      ;check for mode of alternate entry
b06c: c9 02                        cmp     #$02
b06e: f0 2b                        beq     EntrMode2               ;if found, branch to enter from pipe or with vine
b070: a9 00                        lda     #$00
b072: a4 ce                        ldy     Player_Y_Position       ;if vertical position above a certain
b074: c0 30                        cpy     #$30                    ; point, nullify controller bits and continue
b076: 90 6e                        bcc     AutoControlPlayer       ; with player movement code, do not return
b078: ad 10 07                     lda     PlayerEntranceCtrl      ;check player entry bits from header
b07b: c9 06                        cmp     #$06
b07d: f0 04                        beq     ChkBehPipe              ;if set to 6 or 7, execute pipe intro code
b07f: c9 07                        cmp     #$07                    ;otherwise branch to normal entry
b081: d0 50                        bne     PlayerRdy
b083: ad c4 03     ChkBehPipe      lda     Player_SprAttrib        ;check for sprite attributes
b086: d0 05                        bne     IntroEntr               ;branch if found
b088: a9 01                        lda     #$01
b08a: 4c e6 b0                     jmp     AutoControlPlayer       ;force player to walk to the right

b08d: 20 1f b2     IntroEntr       jsr     EnterSidePipe           ;execute sub to move player to the right
b090: ce de 06                     dec     ChangeAreaTimer         ;decrement timer for change of area
b093: d0 50                        bne     ExitEntr                ;branch to exit if not yet expired
b095: ee 69 07                     inc     DisableIntermediate     ;set flag to skip world and lives display
b098: 4c 15 b3                     jmp     NextArea                ;jump to increment to next area and set modes

b09b: ad 58 07     EntrMode2       lda     JoypadOverride          ;if controller override bits set here,
b09e: d0 0c                        bne     VineEntr                ; branch to enter with vine
b0a0: a9 ff                        lda     #$ff                    ;otherwise, set value here then execute sub
b0a2: 20 00 b2                     jsr     MovePlayerYAxis         ; to move player upwards (note $ff = -1)
b0a5: a5 ce                        lda     Player_Y_Position       ;check to see if player is at a specific coordinate
b0a7: c9 91                        cmp     #$91                    ;if player risen to a certain point (this requires pipes
b0a9: 90 28                        bcc     PlayerRdy               ; to be at specific height to look/function right) branch
b0ab: 60                           rts                             ; to the last part, otherwise leave

b0ac: ad 99 03     VineEntr        lda     VineHeight
b0af: c9 60                        cmp     #$60                    ;check vine height
b0b1: d0 32                        bne     ExitEntr                ;if vine not yet reached maximum height, branch to leave
b0b3: a5 ce                        lda     Player_Y_Position       ;get player's vertical coordinate
b0b5: c9 99                        cmp     #$99                    ;check player's vertical coordinate against preset value
b0b7: a0 00                        ldy     #$00                    ;load default values to be written to 
b0b9: a9 01                        lda     #$01                    ;this value moves player to the right off the vine
b0bb: 90 0a                        bcc     OffVine                 ;if vertical coordinate < preset value, use defaults
b0bd: a9 03                        lda     #$03
b0bf: 85 1d                        sta     Player_State            ;otherwise set player state to climbing
b0c1: c8                           iny                             ;increment value in Y
b0c2: a9 08                        lda     #$08                    ;set block in block buffer to cover hole, then 
b0c4: 8d b4 05                     sta     Block_Buffer_1+180      ; use same value to force player to climb
b0c7: 8c 16 07     OffVine         sty     DisableCollisionDet     ;set collision detection disable flag
b0ca: 20 e6 b0                     jsr     AutoControlPlayer       ;use contents of A to move player up or right, execute sub
b0cd: a5 86                        lda     Player_X_Position
b0cf: c9 48                        cmp     #$48                    ;check player's horizontal position
b0d1: 90 12                        bcc     ExitEntr                ;if not far enough to the right, branch to leave
b0d3: a9 08        PlayerRdy       lda     #$08                    ;set routine to be executed by game engine next frame
b0d5: 85 0e                        sta     GameEngineSubroutine
b0d7: a9 01                        lda     #$01                    ;set to face player to the right
b0d9: 85 33                        sta     PlayerFacingDir
b0db: 4a                           lsr     A                       ;init A
b0dc: 8d 52 07                     sta     AltEntranceControl      ;init mode of entry
b0df: 8d 16 07                     sta     DisableCollisionDet     ;init collision detection disable flag
b0e2: 8d 58 07                     sta     JoypadOverride          ;nullify controller override bits
b0e5: 60           ExitEntr        rts                             ;leave!

                   ; -----------------------------------------------------------------------------
                   ; $07 - used to hold upper limit of high byte when player falls down hole
                   AutoControlPlayer
b0e6: 8d fc 06                     sta     SavedJoypad1Bits        ;override controller bits with contents of A if executing here
                   PlayerCtrlRoutine
b0e9: a5 0e                        lda     GameEngineSubroutine    ;check task here
b0eb: c9 0b                        cmp     #$0b                    ;if certain value is set, branch to skip controller bit 
b0ed: f0 3c                        beq     SizeChk
b0ef: ad 4e 07                     lda     AreaType                ;are we in a water type area?
b0f2: d0 10                        bne     SaveJoyp                ;if not, branch
b0f4: a4 b5                        ldy     Player_Y_HighPos
b0f6: 88                           dey                             ;if not in vertical area between
b0f7: d0 06                        bne     DisJoyp                 ;status bar and bottom, branch
b0f9: a5 ce                        lda     Player_Y_Position
b0fb: c9 d0                        cmp     #$d0                    ;if nearing the bottom of the screen or
b0fd: 90 05                        bcc     SaveJoyp                ; not in the vertical area between status bar or bottom,
b0ff: a9 00        DisJoyp         lda     #$00                    ; disable controller bits
b101: 8d fc 06                     sta     SavedJoypad1Bits
b104: ad fc 06     SaveJoyp        lda     SavedJoypad1Bits        ;otherwise store A and B buttons in $0a
b107: 29 c0                        and     #%11000000
b109: 85 0a                        sta     A_B_Buttons
b10b: ad fc 06                     lda     SavedJoypad1Bits        ;store left and right buttons in $0c
b10e: 29 03                        and     #%00000011
b110: 85 0c                        sta     Left_Right_Buttons
b112: ad fc 06                     lda     SavedJoypad1Bits        ;store up and down buttons in $0b
b115: 29 0c                        and     #%00001100
b117: 85 0b                        sta     Up_Down_Buttons
b119: 29 04                        and     #%00000100              ;check for pressing down
b11b: f0 0e                        beq     SizeChk                 ;if not, branch
b11d: a5 1d                        lda     Player_State            ;check player's state
b11f: d0 0a                        bne     SizeChk                 ;if not on the ground, branch
b121: a4 0c                        ldy     Left_Right_Buttons      ;check left and right
b123: f0 06                        beq     SizeChk                 ;if neither pressed, branch
b125: a9 00                        lda     #$00
b127: 85 0c                        sta     Left_Right_Buttons      ;if pressing down while on the ground,
b129: 85 0b                        sta     Up_Down_Buttons         ; nullify directional bits
b12b: 20 29 b3     SizeChk         jsr     PlayerMovementSubs      ;run movement subroutines
b12e: a0 01                        ldy     #$01                    ;is player small?
b130: ad 54 07                     lda     PlayerSize
b133: d0 09                        bne     ChkMoveDir
b135: a0 00                        ldy     #$00                    ;check for if crouching
b137: ad 14 07                     lda     CrouchingFlag
b13a: f0 02                        beq     ChkMoveDir              ;if not, branch ahead
b13c: a0 02                        ldy     #$02                    ;if big and crouching, load y with 2
b13e: 8c 99 04     ChkMoveDir      sty     Player_BoundBoxCtrl     ;set contents of Y as player's bounding box size control
b141: a9 01                        lda     #$01                    ;set moving direction to right by default
b143: a4 57                        ldy     Player_X_Speed          ;check player's horizontal speed
b145: f0 05                        beq     PlayerSubs              ;if not moving at all horizontally, skip this part
b147: 10 01                        bpl     SetMoveDir              ;if moving to the right, use default moving direction
b149: 0a                           asl     A                       ;otherwise change to move to the left
b14a: 85 45        SetMoveDir      sta     Player_MovingDir        ;set moving direction
b14c: 20 93 af     PlayerSubs      jsr     ScrollHandler           ;move the screen if necessary
b14f: 20 80 f1                     jsr     GetPlayerOffscreenBits  ;get player's offscreen bits
b152: 20 2a f1                     jsr     RelativePlayerPosition  ;get coordinates relative to the screen
b155: a2 00                        ldx     #$00                    ;set offset for player object
b157: 20 9c e2                     jsr     BoundingBoxCore         ;get player's bounding box coordinates
b15a: 20 64 dc                     jsr     PlayerBGCollision       ;do collision detection and process
b15d: a5 ce                        lda     Player_Y_Position
b15f: c9 40                        cmp     #$40                    ;check to see if player is higher than 64th pixel
b161: 90 16                        bcc     PlayerHole              ;if so, branch ahead
b163: a5 0e                        lda     GameEngineSubroutine
b165: c9 05                        cmp     #$05                    ;if running end-of-level routine, branch ahead
b167: f0 10                        beq     PlayerHole
b169: c9 07                        cmp     #$07                    ;if running player entrance routine, branch ahead
b16b: f0 0c                        beq     PlayerHole
b16d: c9 04                        cmp     #$04                    ;if running routines $00-$03, branch ahead
b16f: 90 08                        bcc     PlayerHole
b171: ad c4 03                     lda     Player_SprAttrib
b174: 29 df                        and     #%11011111              ;otherwise nullify player's
b176: 8d c4 03                     sta     Player_SprAttrib        ; background priority flag
b179: a5 b5        PlayerHole      lda     Player_Y_HighPos        ;check player's vertical high byte
b17b: c9 02                        cmp     #$02                    ; for below the screen
b17d: 30 3b                        bmi     ExitCtrl                ;branch to leave if not that far down
b17f: a2 01                        ldx     #$01
b181: 8e 23 07                     stx     ScrollLock              ;set scroll lock
b184: a0 04                        ldy     #$04
b186: 84 07                        sty     $07                     ;set value here
b188: a2 00                        ldx     #$00                    ;use X as flag, and clear for cloud level
b18a: ac 59 07                     ldy     GameTimerExpiredFlag    ;check game timer expiration flag
b18d: d0 05                        bne     HoleDie                 ;if set, branch
b18f: ac 43 07                     ldy     CloudTypeOverride       ;check for cloud type override
b192: d0 16                        bne     ChkHoleX                ;skip to last part if found
b194: e8           HoleDie         inx                             ;set flag in X for player death
b195: a4 0e                        ldy     GameEngineSubroutine
b197: c0 0b                        cpy     #$0b                    ;check for some other routine running
b199: f0 0f                        beq     ChkHoleX                ;if so, branch ahead
b19b: ac 12 07                     ldy     DeathMusicLoaded        ;check value here
b19e: d0 06                        bne     HoleBottom              ;if already set, branch to next part
b1a0: c8                           iny
b1a1: 84 fc                        sty     EventMusicQueue         ;otherwise play death music
b1a3: 8c 12 07                     sty     DeathMusicLoaded        ;and set value here
b1a6: a0 06        HoleBottom      ldy     #$06
b1a8: 84 07                        sty     $07                     ;change value here
b1aa: c5 07        ChkHoleX        cmp     $07                     ;compare vertical high byte with value set here
b1ac: 30 0c                        bmi     ExitCtrl                ;if less, branch to leave
b1ae: ca                           dex                             ;otherwise decrement flag in X
b1af: 30 0a                        bmi     CloudExit               ;if flag was clear, branch to set modes and other values
b1b1: ac b1 07                     ldy     EventMusicBuffer        ;check to see if music is still playing
b1b4: d0 04                        bne     ExitCtrl                ;branch to leave if so
b1b6: a9 06                        lda     #$06                    ;otherwise set to run lose life routine
b1b8: 85 0e                        sta     GameEngineSubroutine    ; on next frame
b1ba: 60           ExitCtrl        rts                             ;leave

b1bb: a9 00        CloudExit       lda     #$00
b1bd: 8d 58 07                     sta     JoypadOverride          ;clear controller override bits if any are set
b1c0: 20 dd b1                     jsr     SetEntr                 ;do sub to set secondary mode
b1c3: ee 52 07                     inc     AltEntranceControl      ;set mode of entry to 3
b1c6: 60                           rts

                   ; -----------------------------------------------------------------------------
b1c7: a5 b5        Vine_AutoClimb  lda     Player_Y_HighPos        ;check to see whether player reached position
b1c9: d0 06                        bne     AutoClimb               ; above the status bar yet and if so, set modes
b1cb: a5 ce                        lda     Player_Y_Position
b1cd: c9 e4                        cmp     #$e4
b1cf: 90 0c                        bcc     SetEntr
b1d1: a9 08        AutoClimb       lda     #%00001000              ;set controller bits override to up
b1d3: 8d 58 07                     sta     JoypadOverride
b1d6: a0 03                        ldy     #$03                    ;set player state to climbing
b1d8: 84 1d                        sty     Player_State
b1da: 4c e6 b0                     jmp     AutoControlPlayer

b1dd: a9 02        SetEntr         lda     #$02                    ;set starting position to override
b1df: 8d 52 07                     sta     AltEntranceControl
b1e2: 4c 13 b2                     jmp     ChgAreaMode             ;set modes

                   ; -----------------------------------------------------------------------------
                   VerticalPipeEntry
b1e5: a9 01                        lda     #$01                    ;set 1 as movement amount
b1e7: 20 00 b2                     jsr     MovePlayerYAxis         ;do sub to move player downwards
b1ea: 20 93 af                     jsr     ScrollHandler           ;do sub to scroll screen with saved force if necessary
b1ed: a0 00                        ldy     #$00                    ;load default mode of entry
b1ef: ad d6 06                     lda     WarpZoneControl         ;check warp zone control variable/flag
b1f2: d0 17                        bne     ChgAreaPipe             ;if set, branch to use mode 0
b1f4: c8                           iny
b1f5: ad 4e 07                     lda     AreaType                ;check for castle level type
b1f8: c9 03                        cmp     #$03
b1fa: d0 0f                        bne     ChgAreaPipe             ;if not castle type level, use mode 1
b1fc: c8                           iny
b1fd: 4c 0b b2                     jmp     ChgAreaPipe             ;otherwise use mode 2

b200: 18           MovePlayerYAxis clc
b201: 65 ce                        adc     Player_Y_Position       ;add contents of A to player position
b203: 85 ce                        sta     Player_Y_Position
b205: 60                           rts

                   ; -----------------------------------------------------------------------------
                   SideExitPipeEntry
b206: 20 1f b2                     jsr     EnterSidePipe           ;execute sub to move player to the right
b209: a0 02                        ldy     #$02
b20b: ce de 06     ChgAreaPipe     dec     ChangeAreaTimer         ;decrement timer for change of area
b20e: d0 0e                        bne     ExitCAPipe
b210: 8c 52 07                     sty     AltEntranceControl      ;when timer expires set mode of alternate entry
b213: ee 74 07     ChgAreaMode     inc     DisableScreenFlag       ;set flag to disable screen output
b216: a9 00                        lda     #$00
b218: 8d 72 07                     sta     OperMode_Task           ;set secondary mode of operation
b21b: 8d 22 07                     sta     Sprite0HitDetectFlag    ;disable sprite 0 check
b21e: 60           ExitCAPipe      rts                             ;leave

b21f: a9 08        EnterSidePipe   lda     #$08                    ;set player's horizontal speed
b221: 85 57                        sta     Player_X_Speed
b223: a0 01                        ldy     #$01                    ;set controller right button by default
b225: a5 86                        lda     Player_X_Position       ;mask out higher nybble of player's
b227: 29 0f                        and     #%00001111              ; horizontal position
b229: d0 03                        bne     RightPipe
b22b: 85 57                        sta     Player_X_Speed          ;if lower nybble = 0, set as horizontal speed
b22d: a8                           tay                             ;and nullify controller bit override here
b22e: 98           RightPipe       tya                             ;use contents of Y to
b22f: 20 e6 b0                     jsr     AutoControlPlayer       ; execute player control routine with ctrl bits nulled
b232: 60                           rts

                   ; -----------------------------------------------------------------------------
                   PlayerChangeSize
b233: ad 47 07                     lda     TimerControl            ;check master timer control
b236: c9 f8                        cmp     #$f8                    ;for specific moment in time
b238: d0 03                        bne     EndChgSize              ;branch if before or after that point
b23a: 4c 55 b2                     jmp     InitChangeSize          ;otherwise run code to get growing/shrinking going

b23d: c9 c4        EndChgSize      cmp     #$c4                    ;check again for another specific moment
b23f: d0 03                        bne     ExitChgSize             ;and branch to leave if before or after that point
b241: 20 73 b2                     jsr     DonePlayerTask          ;otherwise do sub to init timer control and set routine
b244: 60           ExitChgSize     rts                             ;and then leave

                   ; -----------------------------------------------------------------------------
                   PlayerInjuryBlink
b245: ad 47 07                     lda     TimerControl            ;check master timer control
b248: c9 f0                        cmp     #$f0                    ; for specific moment in time
b24a: b0 07                        bcs     ExitBlink               ;branch if before that point
b24c: c9 c8                        cmp     #$c8                    ;check again for another specific point
b24e: f0 23                        beq     DonePlayerTask          ;branch if at that point, and not before or after
b250: 4c e9 b0                     jmp     PlayerCtrlRoutine       ;otherwise run player control routine

b253: d0 13        ExitBlink       bne     ExitBoth                ;do unconditional branch to leave
b255: ac 0b 07     InitChangeSize  ldy     PlayerChangeSizeFlag    ;if growing/shrinking flag already set
b258: d0 0e                        bne     ExitBoth                ;then branch to leave
b25a: 8c 0d 07                     sty     PlayerAnimCtrl          ;otherwise initialize player's animation frame control
b25d: ee 0b 07                     inc     PlayerChangeSizeFlag    ;set growing/shrinking flag
b260: ad 54 07                     lda     PlayerSize
b263: 49 01                        eor     #$01                    ;invert player's size
b265: 8d 54 07                     sta     PlayerSize
b268: 60           ExitBoth        rts                             ;leave

                   ; -----------------------------------------------------------------------------
                   ; $00 - used in CyclePlayerPalette to store current palette to cycle
b269: ad 47 07     PlayerDeath     lda     TimerControl            ;check master timer control
b26c: c9 f0                        cmp     #$f0                    ;for specific moment in time
b26e: b0 33                        bcs     ExitDeath               ;branch to leave if before that point
b270: 4c e9 b0                     jmp     PlayerCtrlRoutine       ;otherwise run player control routine

b273: a9 00        DonePlayerTask  lda     #$00
b275: 8d 47 07                     sta     TimerControl            ;initialize master timer control to continue timers
b278: a9 08                        lda     #$08
b27a: 85 0e                        sta     GameEngineSubroutine    ;set player control routine to run next frame
b27c: 60                           rts                             ;leave

                   PlayerFireFlower
b27d: ad 47 07                     lda     TimerControl            ;check master timer control
b280: c9 c0                        cmp     #$c0                    ;for specific moment in time
b282: f0 13                        beq     ResetPalFireFlower      ;branch if at moment, not before or after
b284: a5 09                        lda     FrameCounter            ;get frame counter
b286: 4a                           lsr     A
b287: 4a                           lsr     A                       ;divide by four to change every four frames
                   CyclePlayerPalette
b288: 29 03                        and     #$03                    ;mask out all but d1-d0 (previously d3-d2)
b28a: 85 00                        sta     $00                     ;store result here to use as palette bits
b28c: ad c4 03                     lda     Player_SprAttrib        ;get player attributes
b28f: 29 fc                        and     #%11111100              ;save any other bits but palette bits
b291: 05 00                        ora     $00                     ;add palette bits
b293: 8d c4 03                     sta     Player_SprAttrib        ;store as new player attributes
b296: 60                           rts                             ;and leave

                   ResetPalFireFlower
b297: 20 73 b2                     jsr     DonePlayerTask          ;do sub to init timer control and run player control routine
b29a: ad c4 03     ResetPalStar    lda     Player_SprAttrib        ;get player attributes
b29d: 29 fc                        and     #%11111100              ;mask out palette bits to force palette 0
b29f: 8d c4 03                     sta     Player_SprAttrib        ;store as new player attributes
b2a2: 60                           rts                             ;and leave

b2a3: 60           ExitDeath       rts                             ;leave from death routine

                   ; -----------------------------------------------------------------------------
b2a4: a5 1b        FlagpoleSlide   lda     Enemy_ID+5              ;check special use enemy slot
b2a6: c9 30                        cmp     #FlagpoleFlagObject     ;for flagpole flag object
b2a8: d0 15                        bne     NoFPObj                 ;if not found, branch to something residual
b2aa: ad 13 07                     lda     FlagpoleSoundQueue      ;load flagpole sound
b2ad: 85 ff                        sta     Square1SoundQueue       ;into square 1's sfx queue
b2af: a9 00                        lda     #$00
b2b1: 8d 13 07                     sta     FlagpoleSoundQueue      ;init flagpole sound queue
b2b4: a4 ce                        ldy     Player_Y_Position
b2b6: c0 9e                        cpy     #$9e                    ;check to see if player has slid down
b2b8: b0 02                        bcs     SlidePlayer             ; far enough, and if so, branch with no controller bits set
b2ba: a9 04                        lda     #$04                    ;otherwise force player to climb down (to slide)
b2bc: 4c e6 b0     SlidePlayer     jmp     AutoControlPlayer       ;jump to player control routine

b2bf: e6 0e        NoFPObj         inc     GameEngineSubroutine    ;increment to next routine (this may
b2c1: 60                           rts                             ; be residual code)

                   ; -----------------------------------------------------------------------------
                   Hidden1UpCoinAmts
b2c2: 15 23 16 1b+                 .bulk   $15,$23,$16,$1b,$17,$18,$23,$63

b2ca: a9 01        PlayerEndLevel  lda     #$01                    ;force player to walk to the right
b2cc: 20 e6 b0                     jsr     AutoControlPlayer
b2cf: a5 ce                        lda     Player_Y_Position       ;check player's vertical position
b2d1: c9 ae                        cmp     #$ae
b2d3: 90 0e                        bcc     ChkStop                 ;if player is not yet off the flagpole, skip this part
b2d5: ad 23 07                     lda     ScrollLock              ;if scroll lock not set, branch ahead to next part
b2d8: f0 09                        beq     ChkStop                 ;because we only need to do this part once
b2da: a9 20                        lda     #EndOfLevelMusic
b2dc: 85 fc                        sta     EventMusicQueue         ;load win level music in event music queue
b2de: a9 00                        lda     #$00
b2e0: 8d 23 07                     sta     ScrollLock              ;turn off scroll lock to skip this part later
b2e3: ad 90 04     ChkStop         lda     Player_CollisionBits    ;get player collision bits
b2e6: 4a                           lsr     A                       ;check for d0 set
b2e7: b0 0d                        bcs     RdyNextA                ;if d0 set, skip to next part
b2e9: ad 46 07                     lda     StarFlagTaskControl     ;if star flag task control already set,
b2ec: d0 03                        bne     InCastle                ; go ahead with the rest of the code
b2ee: ee 46 07                     inc     StarFlagTaskControl     ;otherwise set task control now (this gets ball rolling!)
b2f1: a9 20        InCastle        lda     #%00100000              ;set player's background priority bit to
b2f3: 8d c4 03                     sta     Player_SprAttrib        ;give illusion of being inside the castle
b2f6: ad 46 07     RdyNextA        lda     StarFlagTaskControl
b2f9: c9 05                        cmp     #$05                    ;if star flag task control not yet set
b2fb: d0 2b                        bne     ExitNA                  ; beyond last valid task number, branch to leave
b2fd: ee 5c 07                     inc     LevelNumber             ;increment level number used for game logic
b300: ad 5c 07                     lda     LevelNumber
b303: c9 03                        cmp     #$03                    ;check to see if we have yet reached level -4
b305: d0 0e                        bne     NextArea                ; and skip this last part here if not
b307: ac 5f 07                     ldy     WorldNumber             ;get world number as offset
b30a: ad 48 07                     lda     CoinTallyFor1Ups        ;check third area coin tally for bonus 1-ups
b30d: d9 c2 b2                     cmp     Hidden1UpCoinAmts,y     ; against minimum value, if player has not collected
b310: 90 03                        bcc     NextArea                ; at least this number of coins, leave flag clear
b312: ee 5d 07                     inc     Hidden1UpFlag           ;otherwise set hidden 1-up box control flag
b315: ee 60 07     NextArea        inc     AreaNumber              ;increment area number used for address loader
b318: 20 03 9c                     jsr     LoadAreaPointer         ;get new level pointer
b31b: ee 57 07                     inc     FetchNewGameTimerFlag   ;set flag to load new game timer
b31e: 20 13 b2                     jsr     ChgAreaMode             ;do sub to set secondary mode, disable screen and sprite 0
b321: 8d 5b 07                     sta     HalfwayPage             ;reset halfway page to 0 (beginning)
b324: a9 80                        lda     #Silence
b326: 85 fc                        sta     EventMusicQueue         ;silence music and leave
b328: 60           ExitNA          rts

                   ; -----------------------------------------------------------------------------
                   PlayerMovementSubs
b329: a9 00                        lda     #$00                    ;set A to init crouch flag by default
b32b: ac 54 07                     ldy     PlayerSize              ;is player small?
b32e: d0 08                        bne     SetCrouch               ;if so, branch
b330: a5 1d                        lda     Player_State            ;check state of player
b332: d0 07                        bne     ProcMove                ;if not on the ground, branch
b334: a5 0b                        lda     Up_Down_Buttons         ;load controller bits for up and down
b336: 29 04                        and     #%00000100              ;single out bit for down button
b338: 8d 14 07     SetCrouch       sta     CrouchingFlag           ;store value in crouch flag
b33b: 20 50 b4     ProcMove        jsr     PlayerPhysicsSub        ;run sub related to jumping and swimming
b33e: ad 0b 07                     lda     PlayerChangeSizeFlag    ;if growing/shrinking flag set,
b341: d0 16                        bne     NoMoveSub               ; branch to leave
b343: a5 1d                        lda     Player_State
b345: c9 03                        cmp     #$03                    ;get player state
b347: f0 05                        beq     MoveSubs                ;if climbing, branch ahead, leave timer unset
b349: a0 18                        ldy     #$18
b34b: 8c 89 07                     sty     ClimbSlideTimer         ;otherwise reset timer now
b34e: 20 04 8e     MoveSubs        jsr     JumpEngine

b351: 5a b3                        .dd2    OnGroundStateSub
b353: 76 b3                        .dd2    JumpSwimSub
b355: 6d b3                        .dd2    FallingSub
b357: cf b3                        .dd2    ClimbingSub

b359: 60           NoMoveSub       rts

                   ; -----------------------------------------------------------------------------
                   ; $00 - used by ClimbingSub to store high vertical adder
                   OnGroundStateSub
b35a: 20 8f b5                     jsr     GetPlayerAnimSpeed      ;do a sub to set animation frame timing
b35d: a5 0c                        lda     Left_Right_Buttons
b35f: f0 02                        beq     GndMove                 ;if left/right controller bits not set, skip instruction
b361: 85 33                        sta     PlayerFacingDir         ;otherwise set new facing direction
b363: 20 cc b5     GndMove         jsr     ImposeFriction          ;do a sub to impose friction on player's walk/run
b366: 20 09 bf                     jsr     MovePlayerHorizontally  ;do another sub to move player horizontally
b369: 8d ff 06                     sta     Player_X_Scroll         ;set returned value as player's movement speed for scroll
b36c: 60                           rts

                   ; -----------------------------------------------------------------------------
b36d: ad 0a 07     FallingSub      lda     VerticalForceDown
b370: 8d 09 07                     sta     VerticalForce           ;dump vertical movement force for falling into main one
b373: 4c ac b3                     jmp     LRAir                   ;movement force, then skip ahead to process left/right movement

                   ; -----------------------------------------------------------------------------
b376: a4 9f        JumpSwimSub     ldy     Player_Y_Speed          ;if player's vertical speed zero
b378: 10 13                        bpl     DumpFall                ; or moving downwards, branch to falling
b37a: a5 0a                        lda     A_B_Buttons
b37c: 29 80                        and     #A_Button               ;check to see if A button is being pressed
b37e: 25 0d                        and     PreviousA_B_Buttons     ; and was pressed in previous frame
b380: d0 11                        bne     ProcSwim                ;if so, branch elsewhere
b382: ad 08 07                     lda     JumpOrigin_Y_Position   ;get vertical position player jumped from
b385: 38                           sec
b386: e5 ce                        sbc     Player_Y_Position       ;subtract current from original vertical coordinate
b388: cd 06 07                     cmp     DiffToHaltJump          ;compare to value set here to see if player is in mid-jump
b38b: 90 06                        bcc     ProcSwim                ;or just starting to jump, if just starting, skip ahead
b38d: ad 0a 07     DumpFall        lda     VerticalForceDown       ;otherwise dump falling into main fractional
b390: 8d 09 07                     sta     VerticalForce
b393: ad 04 07     ProcSwim        lda     SwimmingFlag            ;if swimming flag not set,
b396: f0 14                        beq     LRAir                   ;branch ahead to last part
b398: 20 8f b5                     jsr     GetPlayerAnimSpeed      ;do a sub to get animation frame timing
b39b: a5 ce                        lda     Player_Y_Position
b39d: c9 14                        cmp     #$14                    ;check vertical position against preset value
b39f: b0 05                        bcs     LRWater                 ;if not yet reached a certain position, branch ahead
b3a1: a9 18                        lda     #$18
b3a3: 8d 09 07                     sta     VerticalForce           ;otherwise set fractional
b3a6: a5 0c        LRWater         lda     Left_Right_Buttons      ;check left/right controller bits (check for swimming)
b3a8: f0 02                        beq     LRAir                   ;if not pressing any, skip
b3aa: 85 33                        sta     PlayerFacingDir         ;otherwise set facing direction accordingly
b3ac: a5 0c        LRAir           lda     Left_Right_Buttons      ;check left/right controller bits (check for jumping/falling)
b3ae: f0 03                        beq     JSMove                  ;if not pressing any, skip
b3b0: 20 cc b5                     jsr     ImposeFriction          ;otherwise process horizontal movement
b3b3: 20 09 bf     JSMove          jsr     MovePlayerHorizontally  ;do a sub to move player horizontally
b3b6: 8d ff 06                     sta     Player_X_Scroll         ;set player's speed here, to be used for scroll later
b3b9: a5 0e                        lda     GameEngineSubroutine
b3bb: c9 0b                        cmp     #$0b                    ;check for specific routine selected
b3bd: d0 05                        bne     ExitMov1                ;branch if not set to run
b3bf: a9 28                        lda     #$28
b3c1: 8d 09 07                     sta     VerticalForce           ;otherwise set fractional
b3c4: 4c 4d bf     ExitMov1        jmp     MovePlayerVertically    ;jump to move player vertically, then leave

                   ; -----------------------------------------------------------------------------
b3c7: 0e 04 fc f2  ClimbAdderLow   .bulk   $0e,$04,$fc,$f2
b3cb: 00 00 ff ff  ClimbAdderHigh  .bulk   $00,$00,$ff,$ff

b3cf: ad 16 04     ClimbingSub     lda     Player_YMF_Dummy
b3d2: 18                           clc                             ;add movement force to dummy variable
b3d3: 6d 33 04                     adc     Player_Y_MoveForce      ;save with carry
b3d6: 8d 16 04                     sta     Player_YMF_Dummy
b3d9: a0 00                        ldy     #$00                    ;set default adder here
b3db: a5 9f                        lda     Player_Y_Speed          ;get player's vertical speed
b3dd: 10 01                        bpl     MoveOnVine              ;if not moving upwards, branch
b3df: 88                           dey                             ;otherwise set adder to $ff
b3e0: 84 00        MoveOnVine      sty     $00                     ;store adder here
b3e2: 65 ce                        adc     Player_Y_Position       ;add carry to player's vertical position
b3e4: 85 ce                        sta     Player_Y_Position       ;and store to move player up or down
b3e6: a5 b5                        lda     Player_Y_HighPos
b3e8: 65 00                        adc     $00                     ;add carry to player's page location
b3ea: 85 b5                        sta     Player_Y_HighPos        ;and store
b3ec: a5 0c                        lda     Left_Right_Buttons      ;compare left/right controller bits
b3ee: 2d 90 04                     and     Player_CollisionBits    ;to collision flag
b3f1: f0 2d                        beq     InitCSTimer             ;if not set, skip to end
b3f3: ac 89 07                     ldy     ClimbSlideTimer         ;otherwise check timer 
b3f6: d0 27                        bne     ExitCSub                ;if timer not expired, branch to leave
b3f8: a0 18                        ldy     #$18
b3fa: 8c 89 07                     sty     ClimbSlideTimer         ;otherwise set timer now
b3fd: a2 00                        ldx     #$00                    ;set default offset here
b3ff: a4 33                        ldy     PlayerFacingDir         ;get facing direction
b401: 4a                           lsr     A                       ;move right button controller bit to carry
b402: b0 02                        bcs     ClimbFD                 ;if controller right pressed, branch ahead
b404: e8                           inx
b405: e8                           inx                             ;otherwise increment offset by 2 bytes
b406: 88           ClimbFD         dey                             ;check to see if facing right
b407: f0 01                        beq     CSetFDir                ;if so, branch, do not increment
b409: e8                           inx                             ;otherwise increment by 1 byte
b40a: a5 86        CSetFDir        lda     Player_X_Position
b40c: 18                           clc                             ;add or subtract from player's horizontal position
b40d: 7d c7 b3                     adc     ClimbAdderLow,x         ; using value here as adder and X as offset
b410: 85 86                        sta     Player_X_Position
b412: a5 6d                        lda     Player_PageLoc          ;add or subtract carry or borrow using value here
b414: 7d cb b3                     adc     ClimbAdderHigh,x        ; from the player's page location
b417: 85 6d                        sta     Player_PageLoc
b419: a5 0c                        lda     Left_Right_Buttons      ;get left/right controller bits again
b41b: 49 03                        eor     #%00000011              ;invert them and store them while player
b41d: 85 33                        sta     PlayerFacingDir         ; is on vine to face player in opposite direction
b41f: 60           ExitCSub        rts                             ;then leave

b420: 8d 89 07     InitCSTimer     sta     ClimbSlideTimer         ;initialize timer here
b423: 60                           rts

                   ; -----------------------------------------------------------------------------
                   ; $00 - used to store offset to friction data
b424: 20 20 1e 28+ JumpMForceData  .bulk   $20,$20,$1e,$28,$28,$0d,$04
b42b: 70 70 60 90+ FallMForceData  .bulk   $70,$70,$60,$90,$90,$0a,$09
b432: fc fc fc fb+ PlayerYSpdData  .bulk   $fc,$fc,$fc,$fb,$fb,$fe,$ff
b439: 00 00 00 00+ InitMForceData  .bulk   $00,$00,$00,$00,$00,$80,$00
b440: d8 e8 f0     MaxLeftXSpdData .bulk   $d8,$e8,$f0
                   MaxRightXSpdData
b443: 28 18 10                     .bulk   $28,$18,$10
b446: 0c                           .dd1    $0c                     ;used for pipe intros
b447: e4 98 d0     FrictionData    .bulk   $e4,$98,$d0
                   Climb_Y_SpeedData
b44a: 00 ff 01                     .bulk   $00,$ff,$01
                   Climb_Y_MForceData
b44d: 00 20 ff                     .bulk   $00,$20,$ff

                   PlayerPhysicsSub
b450: a5 1d                        lda     Player_State            ;check player state
b452: c9 03                        cmp     #$03
b454: d0 23                        bne     CheckForJumping         ;if not climbing, branch
b456: a0 00                        ldy     #$00
b458: a5 0b                        lda     Up_Down_Buttons         ;get controller bits for up/down
b45a: 2d 90 04                     and     Player_CollisionBits    ;check against player's collision detection bits
b45d: f0 06                        beq     ProcClimb               ;if not pressing up or down, branch
b45f: c8                           iny
b460: 29 08                        and     #%00001000              ;check for pressing up
b462: d0 01                        bne     ProcClimb
b464: c8                           iny
b465: be 4d b4     ProcClimb       ldx     Climb_Y_MForceData,y    ;load value here
b468: 8e 33 04                     stx     Player_Y_MoveForce      ;store as vertical movement force
b46b: a9 08                        lda     #$08                    ;load default animation timing
b46d: be 4a b4                     ldx     Climb_Y_SpeedData,y     ;load some other value here
b470: 86 9f                        stx     Player_Y_Speed          ;store as vertical speed
b472: 30 01                        bmi     SetCAnim                ;if climbing down, use default animation timing value
b474: 4a                           lsr     A                       ;otherwise divide timer setting by 2
b475: 8d 0c 07     SetCAnim        sta     PlayerAnimTimerSet      ;store animation timer setting and leave
b478: 60                           rts

b479: ad 0e 07     CheckForJumping lda     JumpspringAnimCtrl      ;if jumpspring animating,
b47c: d0 0a                        bne     NoJump                  ;skip ahead to something else
b47e: a5 0a                        lda     A_B_Buttons             ;check for A button press
b480: 29 80                        and     #A_Button
b482: f0 04                        beq     NoJump                  ;if not, branch to something else
b484: 25 0d                        and     PreviousA_B_Buttons     ;if button not pressed in previous frame, branch
b486: f0 03                        beq     ProcJumping
b488: 4c 1c b5     NoJump          jmp     X_Physics               ;otherwise, jump to something else

b48b: a5 1d        ProcJumping     lda     Player_State            ;check player state
b48d: f0 11                        beq     InitJS                  ;if on the ground, branch
b48f: ad 04 07                     lda     SwimmingFlag            ;if swimming flag not set, jump to do something else
b492: f0 f4                        beq     NoJump                  ; to prevent midair jumping, otherwise continue
b494: ad 82 07                     lda     JumpSwimTimer           ;if jump/swim timer nonzero, branch
b497: d0 07                        bne     InitJS
b499: a5 9f                        lda     Player_Y_Speed          ;check player's vertical speed
b49b: 10 03                        bpl     InitJS                  ;if player's vertical speed motionless or down, branch
b49d: 4c 1c b5                     jmp     X_Physics               ;if timer at zero and player still rising, do not swim

b4a0: a9 20        InitJS          lda     #$20                    ;set jump/swim timer
b4a2: 8d 82 07                     sta     JumpSwimTimer
b4a5: a0 00                        ldy     #$00                    ;initialize vertical force and dummy variable
b4a7: 8c 16 04                     sty     Player_YMF_Dummy
b4aa: 8c 33 04                     sty     Player_Y_MoveForce
b4ad: a5 b5                        lda     Player_Y_HighPos        ;get vertical high and low bytes of jump origin
b4af: 8d 07 07                     sta     JumpOrigin_Y_HighPos    ; and store them next to each other here
b4b2: a5 ce                        lda     Player_Y_Position
b4b4: 8d 08 07                     sta     JumpOrigin_Y_Position
b4b7: a9 01                        lda     #$01                    ;set player state to jumping/swimming
b4b9: 85 1d                        sta     Player_State
b4bb: ad 00 07                     lda     Player_XSpeedAbsolute   ;check value related to walking/running speed
b4be: c9 09                        cmp     #$09
b4c0: 90 10                        bcc     ChkWtr                  ;branch if below certain values, increment Y
b4c2: c8                           iny                             ;for each amount equal or exceeded
b4c3: c9 10                        cmp     #$10
b4c5: 90 0b                        bcc     ChkWtr
b4c7: c8                           iny
b4c8: c9 19                        cmp     #$19
b4ca: 90 06                        bcc     ChkWtr
b4cc: c8                           iny
b4cd: c9 1c                        cmp     #$1c
b4cf: 90 01                        bcc     ChkWtr                  ;note that for jumping, range is 0-4 for Y
b4d1: c8                           iny
b4d2: a9 01        ChkWtr          lda     #$01                    ;set value here (apparently always set to 1)
b4d4: 8d 06 07                     sta     DiffToHaltJump
b4d7: ad 04 07                     lda     SwimmingFlag            ;if swimming flag disabled, branch
b4da: f0 08                        beq     GetYPhy
b4dc: a0 05                        ldy     #$05                    ;otherwise set Y to 5, range is 5-6
b4de: ad 7d 04                     lda     Whirlpool_Flag          ;if whirlpool flag not set, branch
b4e1: f0 01                        beq     GetYPhy
b4e3: c8                           iny                             ;otherwise increment to 6
b4e4: b9 24 b4     GetYPhy         lda     JumpMForceData,y        ;store appropriate jump/swim
b4e7: 8d 09 07                     sta     VerticalForce           ; data here
b4ea: b9 2b b4                     lda     FallMForceData,y
b4ed: 8d 0a 07                     sta     VerticalForceDown
b4f0: b9 39 b4                     lda     InitMForceData,y
b4f3: 8d 33 04                     sta     Player_Y_MoveForce
b4f6: b9 32 b4                     lda     PlayerYSpdData,y
b4f9: 85 9f                        sta     Player_Y_Speed
b4fb: ad 04 07                     lda     SwimmingFlag            ;if swimming flag disabled, branch
b4fe: f0 11                        beq     PJumpSnd
b500: a9 04                        lda     #Sfx_EnemyStomp         ;load swim/goomba stomp sound into
b502: 85 ff                        sta     Square1SoundQueue       ;square 1's sfx queue
b504: a5 ce                        lda     Player_Y_Position
b506: c9 14                        cmp     #$14                    ;check vertical low byte of player position
b508: b0 12                        bcs     X_Physics               ;if below a certain point, branch
b50a: a9 00                        lda     #$00                    ;otherwise reset player's vertical speed
b50c: 85 9f                        sta     Player_Y_Speed          ; and jump to something else to keep player
b50e: 4c 1c b5                     jmp     X_Physics               ; from swimming above water level

b511: a9 01        PJumpSnd        lda     #Sfx_BigJump            ;load big mario's jump sound by default
b513: ac 54 07                     ldy     PlayerSize              ;is mario big?
b516: f0 02                        beq     SJumpSnd
b518: a9 80                        lda     #Sfx_SmallJump          ;if not, load small mario's jump sound
b51a: 85 ff        SJumpSnd        sta     Square1SoundQueue       ;store appropriate jump sound in square 1 sfx queue
b51c: a0 00        X_Physics       ldy     #$00
b51e: 84 00                        sty     $00                     ;init value here
b520: a5 1d                        lda     Player_State            ;if mario is on the ground, branch
b522: f0 09                        beq     ProcPRun
b524: ad 00 07                     lda     Player_XSpeedAbsolute   ;check something that seems to be related
b527: c9 19                        cmp     #$19                    ;to mario's speed
b529: b0 33                        bcs     GetXPhy                 ;if =>$19 branch here
b52b: 90 18                        bcc     ChkRFast                ;if not branch elsewhere

b52d: c8           ProcPRun        iny                             ;if mario on the ground, increment Y
b52e: ad 4e 07                     lda     AreaType                ;check area type
b531: f0 12                        beq     ChkRFast                ;if water type, branch
b533: 88                           dey                             ;decrement Y by default for non-water type area
b534: a5 0c                        lda     Left_Right_Buttons      ;get left/right controller bits
b536: c5 45                        cmp     Player_MovingDir        ;check against moving direction
b538: d0 0b                        bne     ChkRFast                ;if controller bits <> moving direction, skip this part
b53a: a5 0a                        lda     A_B_Buttons             ;check for b button pressed
b53c: 29 40                        and     #B_Button
b53e: d0 19                        bne     SetRTmr                 ;if pressed, skip ahead to set timer
b540: ad 83 07                     lda     RunningTimer            ;check for running timer set
b543: d0 19                        bne     GetXPhy                 ;if set, branch
b545: c8           ChkRFast        iny                             ;if running timer not set or level type is water, 
b546: e6 00                        inc     $00                     ; increment Y again and temp variable in memory
b548: ad 03 07                     lda     RunningSpeed
b54b: d0 07                        bne     FastXSp                 ;if running speed set here, branch
b54d: ad 00 07                     lda     Player_XSpeedAbsolute
b550: c9 21                        cmp     #$21                    ;otherwise check player's walking/running speed
b552: 90 0a                        bcc     GetXPhy                 ;if less than a certain amount, branch ahead
b554: e6 00        FastXSp         inc     $00                     ;if running speed set or speed => $21 increment $00
b556: 4c 5e b5                     jmp     GetXPhy                 ; and jump ahead

b559: a9 0a        SetRTmr         lda     #$0a                    ;if b button pressed, set running timer
b55b: 8d 83 07                     sta     RunningTimer
b55e: b9 40 b4     GetXPhy         lda     MaxLeftXSpdData,y       ;get maximum speed to the left
b561: 8d 50 04                     sta     MaximumLeftSpeed
b564: a5 0e                        lda     GameEngineSubroutine    ;check for specific routine running
b566: c9 07                        cmp     #$07                    ;(player entrance)
b568: d0 02                        bne     GetXPhy2                ;if not running, skip and use old value of Y
b56a: a0 03                        ldy     #$03                    ;otherwise set Y to 3
b56c: b9 43 b4     GetXPhy2        lda     MaxRightXSpdData,y      ;get maximum speed to the right
b56f: 8d 56 04                     sta     MaximumRightSpeed
b572: a4 00                        ldy     $00                     ;get other value in memory
b574: b9 47 b4                     lda     FrictionData,y          ;get value using value in memory as offset
b577: 8d 02 07                     sta     FrictionAdderLow
b57a: a9 00                        lda     #$00
b57c: 8d 01 07                     sta     FrictionAdderHigh       ;init something here
b57f: a5 33                        lda     PlayerFacingDir
b581: c5 45                        cmp     Player_MovingDir        ;check facing direction against moving direction
b583: f0 06                        beq     ExitPhy                 ;if the same, branch to leave
b585: 0e 02 07                     asl     FrictionAdderLow        ;otherwise shift d7 of friction adder low into carry
b588: 2e 01 07                     rol     FrictionAdderHigh       ; then rotate carry onto d0 of friction adder high
b58b: 60           ExitPhy         rts                             ; and then leave

                   ; -----------------------------------------------------------------------------
                   PlayerAnimTmrData
b58c: 02 04 07                     .bulk   $02,$04,$07

                   GetPlayerAnimSpeed
b58f: a0 00                        ldy     #$00                    ;initialize offset in Y
b591: ad 00 07                     lda     Player_XSpeedAbsolute   ;check player's walking/running speed
b594: c9 1c                        cmp     #$1c                    ; against preset amount
b596: b0 15                        bcs     SetRunSpd               ;if greater than a certain amount, branch ahead
b598: c8                           iny                             ;otherwise increment Y
b599: c9 0e                        cmp     #$0e                    ;compare against lower amount
b59b: b0 01                        bcs     ChkSkid                 ;if greater than this but not greater than first, skip increment
b59d: c8                           iny                             ;otherwise increment Y again
b59e: ad fc 06     ChkSkid         lda     SavedJoypad1Bits        ;get controller bits
b5a1: 29 7f                        and     #%01111111              ;mask out A button
b5a3: f0 20                        beq     SetAnimSpd              ;if no other buttons pressed, branch ahead of all this
b5a5: 29 03                        and     #$03                    ;mask out all others except left and right
b5a7: c5 45                        cmp     Player_MovingDir        ;check against moving direction
b5a9: d0 08                        bne     ProcSkid                ;if left/right controller bits <> moving direction, branch
b5ab: a9 00                        lda     #$00                    ;otherwise set zero value here
b5ad: 8d 03 07     SetRunSpd       sta     RunningSpeed            ;store zero or running speed here
b5b0: 4c c5 b5                     jmp     SetAnimSpd

b5b3: ad 00 07     ProcSkid        lda     Player_XSpeedAbsolute   ;check player's walking/running speed
b5b6: c9 0b                        cmp     #$0b                    ;against one last amount
b5b8: b0 0b                        bcs     SetAnimSpd              ;if greater than this amount, branch
b5ba: a5 33                        lda     PlayerFacingDir
b5bc: 85 45                        sta     Player_MovingDir        ;otherwise use facing direction to set moving direction
b5be: a9 00                        lda     #$00
b5c0: 85 57                        sta     Player_X_Speed          ;nullify player's horizontal speed
b5c2: 8d 05 07                     sta     Player_X_MoveForce      ; and dummy variable for player
b5c5: b9 8c b5     SetAnimSpd      lda     PlayerAnimTmrData,y     ;get animation timer setting using Y as offset
b5c8: 8d 0c 07                     sta     PlayerAnimTimerSet
b5cb: 60                           rts

                   ; -----------------------------------------------------------------------------
b5cc: 2d 90 04     ImposeFriction  and     Player_CollisionBits    ;perform AND between left/right controller bits and collision flag
b5cf: c9 00                        cmp     #$00                    ;then compare to zero (this instruction is redundant)
b5d1: d0 08                        bne     JoypFrict               ;if any bits set, branch to next part
b5d3: a5 57                        lda     Player_X_Speed
b5d5: f0 49                        beq     SetAbsSpd               ;if player has no horizontal speed, branch ahead to last part
b5d7: 10 23                        bpl     RghtFrict               ;if player moving to the right, branch to slow
b5d9: 30 03                        bmi     LeftFrict               ;otherwise logic dictates player moving left, branch to slow

b5db: 4a           JoypFrict       lsr     A                       ;put right controller bit into carry
b5dc: 90 1e                        bcc     RghtFrict               ;if left button pressed, carry = 0, thus branch
b5de: ad 05 07     LeftFrict       lda     Player_X_MoveForce      ;load value set here
b5e1: 18                           clc
b5e2: 6d 02 07                     adc     FrictionAdderLow        ;add to it another value set here
b5e5: 8d 05 07                     sta     Player_X_MoveForce      ;store here
b5e8: a5 57                        lda     Player_X_Speed
b5ea: 6d 01 07                     adc     FrictionAdderHigh       ;add value plus carry to horizontal speed
b5ed: 85 57                        sta     Player_X_Speed          ;set as new horizontal speed
b5ef: cd 56 04                     cmp     MaximumRightSpeed       ;compare against maximum value for right movement
b5f2: 30 23                        bmi     XSpdSign                ;if horizontal speed greater negatively, branch
b5f4: ad 56 04                     lda     MaximumRightSpeed       ;otherwise set preset value as horizontal speed
b5f7: 85 57                        sta     Player_X_Speed          ;thus slowing the player's left movement down
b5f9: 4c 20 b6                     jmp     SetAbsSpd               ;skip to the end

b5fc: ad 05 07     RghtFrict       lda     Player_X_MoveForce      ;load value set here
b5ff: 38                           sec
b600: ed 02 07                     sbc     FrictionAdderLow        ;subtract from it another value set here
b603: 8d 05 07                     sta     Player_X_MoveForce      ;store here
b606: a5 57                        lda     Player_X_Speed
b608: ed 01 07                     sbc     FrictionAdderHigh       ;subtract value plus borrow from horizontal speed
b60b: 85 57                        sta     Player_X_Speed          ;set as new horizontal speed
b60d: cd 50 04                     cmp     MaximumLeftSpeed        ;compare against maximum value for left movement
b610: 10 05                        bpl     XSpdSign                ;if horizontal speed greater positively, branch
b612: ad 50 04                     lda     MaximumLeftSpeed        ;otherwise set preset value as horizontal speed
b615: 85 57                        sta     Player_X_Speed          ;thus slowing the player's right movement down
b617: c9 00        XSpdSign        cmp     #$00                    ;if player not moving or moving to the right,
b619: 10 05                        bpl     SetAbsSpd               ; branch and leave horizontal speed value unmodified
b61b: 49 ff                        eor     #$ff
b61d: 18                           clc                             ;otherwise get two's compliment to get absolute
b61e: 69 01                        adc     #$01                    ; unsigned walking/running speed
b620: 8d 00 07     SetAbsSpd       sta     Player_XSpeedAbsolute   ;store walking/running speed here and leave
b623: 60                           rts

                   ; -----------------------------------------------------------------------------
                   ; $00 - used to store downward movement force in FireballObjCore
                   ; $02 - used to store maximum vertical speed in FireballObjCore
                   ; $07 - used to store pseudorandom bit in BubbleCheck
                   ProcFireball_Bubble
b624: ad 56 07                     lda     PlayerStatus            ;check player's status
b627: c9 02                        cmp     #$02
b629: 90 43                        bcc     ProcAirBubbles          ;if not fiery, branch
b62b: a5 0a                        lda     A_B_Buttons
b62d: 29 40                        and     #B_Button               ;check for b button pressed
b62f: f0 33                        beq     ProcFireballs           ;branch if not pressed
b631: 25 0d                        and     PreviousA_B_Buttons
b633: d0 2f                        bne     ProcFireballs           ;if button pressed in previous frame, branch
b635: ad ce 06                     lda     FireballCounter         ;load fireball counter
b638: 29 01                        and     #%00000001              ;get LSB and use as offset for buffer
b63a: aa                           tax
b63b: b5 24                        lda     Fireball_State,x        ;load fireball state
b63d: d0 25                        bne     ProcFireballs           ;if not inactive, branch
b63f: a4 b5                        ldy     Player_Y_HighPos        ;if player too high or too low, branch
b641: 88                           dey
b642: d0 20                        bne     ProcFireballs
b644: ad 14 07                     lda     CrouchingFlag           ;if player crouching, branch
b647: d0 1b                        bne     ProcFireballs
b649: a5 1d                        lda     Player_State            ;if player's state = climbing, branch
b64b: c9 03                        cmp     #$03
b64d: f0 15                        beq     ProcFireballs
b64f: a9 20                        lda     #Sfx_Fireball           ;play fireball sound effect
b651: 85 ff                        sta     Square1SoundQueue
b653: a9 02                        lda     #$02                    ;load state
b655: 95 24                        sta     Fireball_State,x
b657: ac 0c 07                     ldy     PlayerAnimTimerSet      ;copy animation frame timer setting
b65a: 8c 11 07                     sty     FireballThrowingTimer   ; into fireball throwing timer
b65d: 88                           dey
b65e: 8c 81 07                     sty     PlayerAnimTimer         ;decrement and store in player's animation timer
b661: ee ce 06                     inc     FireballCounter         ;increment fireball counter
b664: a2 00        ProcFireballs   ldx     #$00
b666: 20 89 b6                     jsr     FireballObjCore         ;process first fireball object
b669: a2 01                        ldx     #$01
b66b: 20 89 b6                     jsr     FireballObjCore         ;process second fireball object, then do air bubbles
b66e: ad 4e 07     ProcAirBubbles  lda     AreaType                ;if not water type level, skip the rest of this
b671: d0 13                        bne     BublExit
b673: a2 02                        ldx     #$02                    ;otherwise load counter and use as offset
b675: 86 08        BublLoop        stx     ObjectOffset            ;store offset
b677: 20 f9 b6                     jsr     BubbleCheck             ;check timers and coordinates, create air bubble
b67a: 20 31 f1                     jsr     RelativeBubblePosition  ;get relative coordinates
b67d: 20 91 f1                     jsr     GetBubbleOffscreenBits  ;get offscreen information
b680: 20 e1 ed                     jsr     DrawBubble              ;draw the air bubble
b683: ca                           dex
b684: 10 ef                        bpl     BublLoop                ;do this until all three are handled
b686: 60           BublExit        rts                             ;then leave

                   FireballXSpdData
b687: 40                           .dd1    $40
b688: c0                           .dd1    $c0

b689: 86 08        FireballObjCore stx     ObjectOffset            ;store offset as current object
b68b: b5 24                        lda     Fireball_State,x        ;check for d7 = 1
b68d: 0a                           asl     A
b68e: b0 63                        bcs     FireballExplosion       ;if so, branch to get relative coordinates and draw explosion
b690: b4 24                        ldy     Fireball_State,x        ;if fireball inactive, branch to leave
b692: f0 5e                        beq     NoFBall
b694: 88                           dey                             ;if fireball state set to 1, skip this part and just run it
b695: f0 27                        beq     RunFB
b697: a5 86                        lda     Player_X_Position       ;get player's horizontal position
b699: 69 04                        adc     #$04                    ;add four pixels and store as fireball's horizontal position
b69b: 95 8d                        sta     Fireball_X_Position,x
b69d: a5 6d                        lda     Player_PageLoc          ;get player's page location
b69f: 69 00                        adc     #$00                    ;add carry and store as fireball's page location
b6a1: 95 74                        sta     Fireball_PageLoc,x
b6a3: a5 ce                        lda     Player_Y_Position       ;get player's vertical position and store
b6a5: 95 d5                        sta     Fireball_Y_Position,x
b6a7: a9 01                        lda     #$01                    ;set high byte of vertical position
b6a9: 95 bc                        sta     Fireball_Y_HighPos,x
b6ab: a4 33                        ldy     PlayerFacingDir         ;get player's facing direction
b6ad: 88                           dey                             ;decrement to use as offset here
b6ae: b9 87 b6                     lda     FireballXSpdData,y      ;set horizontal speed of fireball accordingly
b6b1: 95 5e                        sta     Fireball_X_Speed,x
b6b3: a9 04                        lda     #$04                    ;set vertical speed of fireball
b6b5: 95 a6                        sta     Fireball_Y_Speed,x
b6b7: a9 07                        lda     #$07
b6b9: 9d a0 04                     sta     Fireball_BoundBoxCtrl,x ;set bounding box size control for fireball
b6bc: d6 24                        dec     Fireball_State,x        ;decrement state to 1 to skip this part from now on
b6be: 8a           RunFB           txa                             ;add 7 to offset to use
b6bf: 18                           clc                             ; as fireball offset for next routines
b6c0: 69 07                        adc     #$07
b6c2: aa                           tax
b6c3: a9 50                        lda     #$50                    ;set downward movement force here
b6c5: 85 00                        sta     $00
b6c7: a9 03                        lda     #$03                    ;set maximum speed here
b6c9: 85 02                        sta     $02
b6cb: a9 00                        lda     #$00
b6cd: 20 d7 bf                     jsr     ImposeGravity           ;do sub here to impose gravity on fireball and move vertically
b6d0: 20 0f bf                     jsr     MoveObjectHorizontally  ;do another sub to move it horizontally
b6d3: a6 08                        ldx     ObjectOffset            ;return fireball offset to X
b6d5: 20 3b f1                     jsr     RelativeFireballPosition ;get relative coordinates
b6d8: 20 87 f1                     jsr     GetFireballOffscreenBits ;get offscreen information
b6db: 20 2d e2                     jsr     GetFireballBoundBox     ;get bounding box coordinates
b6de: 20 c8 e1                     jsr     FireballBGCollision     ;do fireball to background collision detection
b6e1: ad d2 03                     lda     FBall_OffscreenBits     ;get fireball offscreen bits
b6e4: 29 cc                        and     #%11001100              ;mask out certain bits
b6e6: d0 06                        bne     EraseFB                 ;if any bits still set, branch to kill fireball
b6e8: 20 d9 d6                     jsr     FireballEnemyCollision  ;do fireball to enemy collision detection and deal with collisions
b6eb: 4c de ec                     jmp     DrawFireball            ;draw fireball appropriately and leave

b6ee: a9 00        EraseFB         lda     #$00                    ;erase fireball state
b6f0: 95 24                        sta     Fireball_State,x
b6f2: 60           NoFBall         rts                             ;leave

                   FireballExplosion
b6f3: 20 3b f1                     jsr     RelativeFireballPosition
b6f6: 4c 09 ed                     jmp     DrawExplosion_Fireball

b6f9: bd a8 07     BubbleCheck     lda     PseudoRandomBitReg+1,x  ;get part of LSFR
b6fc: 29 01                        and     #$01
b6fe: 85 07                        sta     $07                     ;store pseudorandom bit here
b700: b5 e4                        lda     Bubble_Y_Position,x     ;get vertical coordinate for air bubble
b702: c9 f8                        cmp     #$f8                    ;if offscreen coordinate not set,
b704: d0 2c                        bne     MoveBubl                ;branch to move air bubble
b706: ad 92 07                     lda     AirBubbleTimer          ;if air bubble timer not expired,
b709: d0 3f                        bne     ExitBubl                ;branch to leave, otherwise create new air bubble
b70b: a0 00        SetupBubble     ldy     #$00                    ;load default value here
b70d: a5 33                        lda     PlayerFacingDir         ;get player's facing direction
b70f: 4a                           lsr     A                       ;move d0 to carry
b710: 90 02                        bcc     PosBubl                 ;branch to use default value if facing left
b712: a0 08                        ldy     #$08                    ;otherwise load alternate value here
b714: 98           PosBubl         tya                             ;use value loaded as adder
b715: 65 86                        adc     Player_X_Position       ;add to player's horizontal position
b717: 95 9c                        sta     Bubble_X_Position,x     ;save as horizontal position for airbubble
b719: a5 6d                        lda     Player_PageLoc
b71b: 69 00                        adc     #$00                    ;add carry to player's page location
b71d: 95 83                        sta     Bubble_PageLoc,x        ;save as page location for airbubble
b71f: a5 ce                        lda     Player_Y_Position
b721: 18                           clc                             ;add eight pixels to player's vertical position
b722: 69 08                        adc     #$08
b724: 95 e4                        sta     Bubble_Y_Position,x     ;save as vertical position for air bubble
b726: a9 01                        lda     #$01
b728: 95 cb                        sta     Bubble_Y_HighPos,x      ;set vertical high byte for air bubble
b72a: a4 07                        ldy     $07                     ;get pseudorandom bit, use as offset
b72c: b9 4d b7                     lda     BubbleTimerData,y       ;get data for air bubble timer
b72f: 8d 92 07                     sta     AirBubbleTimer          ;set air bubble timer
b732: a4 07        MoveBubl        ldy     $07                     ;get pseudorandom bit again, use as offset
b734: bd 2c 04                     lda     Bubble_YMF_Dummy,x
b737: 38                           sec                             ;subtract pseudorandom amount from dummy variable
b738: f9 4b b7                     sbc     Bubble_MForceData,y
b73b: 9d 2c 04                     sta     Bubble_YMF_Dummy,x      ;save dummy variable
b73e: b5 e4                        lda     Bubble_Y_Position,x
b740: e9 00                        sbc     #$00                    ;subtract borrow from airbubble's vertical coordinate
b742: c9 20                        cmp     #$20                    ;if below the status bar,
b744: b0 02                        bcs     Y_Bubl                  ;branch to go ahead and use to move air bubble upwards
b746: a9 f8                        lda     #$f8                    ;otherwise set offscreen coordinate
b748: 95 e4        Y_Bubl          sta     Bubble_Y_Position,x     ;store as new vertical coordinate for air bubble
b74a: 60           ExitBubl        rts                             ;leave

                   Bubble_MForceData
b74b: ff                           .dd1    $ff
b74c: 50                           .dd1    $50
b74d: 40           BubbleTimerData .dd1    $40
b74e: 20                           .dd1    $20

                   ; -----------------------------------------------------------------------------
b74f: ad 70 07     RunGameTimer    lda     OperMode                ;get primary mode of operation
b752: f0 4f                        beq     ExGTimer                ;branch to leave if in title screen mode
b754: a5 0e                        lda     GameEngineSubroutine
b756: c9 08                        cmp     #$08                    ;if routine number less than eight running,
b758: 90 49                        bcc     ExGTimer                ;branch to leave
b75a: c9 0b                        cmp     #$0b                    ;if running death routine,
b75c: f0 45                        beq     ExGTimer                ;branch to leave
b75e: a5 b5                        lda     Player_Y_HighPos
b760: c9 02                        cmp     #$02                    ;if player below the screen,
b762: b0 3f                        bcs     ExGTimer                ;branch to leave regardless of level type
b764: ad 87 07                     lda     GameTimerCtrlTimer      ;if game timer control not yet expired,
b767: d0 3a                        bne     ExGTimer                ;branch to leave
b769: ad f8 07                     lda     GameTimerDisplay
b76c: 0d f9 07                     ora     GameTimerDisplay+1      ;otherwise check game timer digits
b76f: 0d fa 07                     ora     GameTimerDisplay+2
b772: f0 26                        beq     TimeUpOn                ;if game timer digits at 000, branch to time-up code
b774: ac f8 07                     ldy     GameTimerDisplay        ;otherwise check first digit
b777: 88                           dey                             ;if first digit not on 1,
b778: d0 0c                        bne     ResGTCtrl               ;branch to reset game timer control
b77a: ad f9 07                     lda     GameTimerDisplay+1      ;otherwise check second and third digits
b77d: 0d fa 07                     ora     GameTimerDisplay+2
b780: d0 04                        bne     ResGTCtrl               ;if timer not at 100, branch to reset game timer control
b782: a9 40                        lda     #TimeRunningOutMusic
b784: 85 fc                        sta     EventMusicQueue         ;otherwise load time running out music
b786: a9 18        ResGTCtrl       lda     #$18                    ;reset game timer control
b788: 8d 87 07                     sta     GameTimerCtrlTimer
b78b: a0 23                        ldy     #$23                    ;set offset for last digit
b78d: a9 ff                        lda     #$ff                    ;set value to decrement game timer digit
b78f: 8d 39 01                     sta     DigitModifier+5
b792: 20 5f 8f                     jsr     DigitsMathRoutine       ;do sub to decrement game timer slowly
b795: a9 a4                        lda     #$a4                    ;set status nybbles to update game timer display
b797: 4c 06 8f                     jmp     PrintStatusBarNumbers   ;do sub to update the display

b79a: 8d 56 07     TimeUpOn        sta     PlayerStatus            ;init player status (note A will always be zero here)
b79d: 20 31 d9                     jsr     ForceInjury             ;do sub to kill the player (note player is small here)
b7a0: ee 59 07                     inc     GameTimerExpiredFlag    ;set game timer expiration flag
b7a3: 60           ExGTimer        rts                             ;leave

                   ; -----------------------------------------------------------------------------
b7a4: ad 23 07     WarpZoneObject  lda     ScrollLock              ;check for scroll lock flag
b7a7: f0 fa                        beq     ExGTimer                ;branch if not set to leave
b7a9: a5 ce                        lda     Player_Y_Position       ;check to see if player's vertical coordinate has
b7ab: 25 b5                        and     Player_Y_HighPos        ;same bits set as in vertical high byte (why?)
b7ad: d0 f4                        bne     ExGTimer                ;if so, branch to leave
b7af: 8d 23 07                     sta     ScrollLock              ;otherwise nullify scroll lock flag
b7b2: ee d6 06                     inc     WarpZoneControl         ;increment warp zone flag to make warp pipes for warp zone
b7b5: 4c 98 c9                     jmp     EraseEnemyObject        ;kill this object

                   ; -----------------------------------------------------------------------------
                   ; $00 - used in WhirlpoolActivate to store whirlpool length / 2, page location
                   ; of center of whirlpool and also to store movement force exerted on player
                   ; $01 - used in ProcessWhirlpools to store page location of right extent of
                   ; whirlpool and in WhirlpoolActivate to store center of whirlpool
                   ; $02 - used in ProcessWhirlpools to store right extent of whirlpool and in
                   ; WhirlpoolActivate to store maximum vertical speed
                   ProcessWhirlpools
b7b8: ad 4e 07                     lda     AreaType                ;check for water type level
b7bb: d0 37                        bne     ExitWh                  ;branch to leave if not found
b7bd: 8d 7d 04                     sta     Whirlpool_Flag          ;otherwise initialize whirlpool flag
b7c0: ad 47 07                     lda     TimerControl            ;if master timer control set,
b7c3: d0 2f                        bne     ExitWh                  ;branch to leave
b7c5: a0 04                        ldy     #$04                    ;otherwise start with last whirlpool data
b7c7: b9 71 04     WhLoop          lda     Whirlpool_LeftExtent,y  ;get left extent of whirlpool
b7ca: 18                           clc
b7cb: 79 77 04                     adc     Whirlpool_Length,y      ;add length of whirlpool
b7ce: 85 02                        sta     $02                     ;store result as right extent here
b7d0: b9 6b 04                     lda     Whirlpool_PageLoc,y     ;get page location
b7d3: f0 1c                        beq     NextWh                  ;if none or page 0, branch to get next data
b7d5: 69 00                        adc     #$00                    ;add carry
b7d7: 85 01                        sta     $01                     ;store result as page location of right extent here
b7d9: a5 86                        lda     Player_X_Position       ;get player's horizontal position
b7db: 38                           sec
b7dc: f9 71 04                     sbc     Whirlpool_LeftExtent,y  ;subtract left extent
b7df: a5 6d                        lda     Player_PageLoc          ;get player's page location
b7e1: f9 6b 04                     sbc     Whirlpool_PageLoc,y     ;subtract borrow
b7e4: 30 0b                        bmi     NextWh                  ;if player too far left, branch to get next data
b7e6: a5 02                        lda     $02                     ;otherwise get right extent
b7e8: 38                           sec
b7e9: e5 86                        sbc     Player_X_Position       ;subtract player's horizontal coordinate
b7eb: a5 01                        lda     $01                     ;get right extent's page location
b7ed: e5 6d                        sbc     Player_PageLoc          ;subtract borrow
b7ef: 10 04                        bpl     WhirlpoolActivate       ;if player within right extent, branch to whirlpool code
b7f1: 88           NextWh          dey                             ;move onto next whirlpool data
b7f2: 10 d3                        bpl     WhLoop                  ;do this until all whirlpools are checked
b7f4: 60           ExitWh          rts                             ;leave

                   WhirlpoolActivate
b7f5: b9 77 04                     lda     Whirlpool_Length,y      ;get length of whirlpool
b7f8: 4a                           lsr     A                       ;divide by 2
b7f9: 85 00                        sta     $00                     ;save here
b7fb: b9 71 04                     lda     Whirlpool_LeftExtent,y  ;get left extent of whirlpool
b7fe: 18                           clc
b7ff: 65 00                        adc     $00                     ;add length divided by 2
b801: 85 01                        sta     $01                     ;save as center of whirlpool
b803: b9 6b 04                     lda     Whirlpool_PageLoc,y     ;get page location
b806: 69 00                        adc     #$00                    ;add carry
b808: 85 00                        sta     $00                     ;save as page location of whirlpool center
b80a: a5 09                        lda     FrameCounter            ;get frame counter
b80c: 4a                           lsr     A                       ;shift d0 into carry (to run on every other frame)
b80d: 90 2c                        bcc     WhPull                  ;if d0 not set, branch to last part of code
b80f: a5 01                        lda     $01                     ;get center
b811: 38                           sec
b812: e5 86                        sbc     Player_X_Position       ;subtract player's horizontal coordinate
b814: a5 00                        lda     $00                     ;get page location of center
b816: e5 6d                        sbc     Player_PageLoc          ;subtract borrow
b818: 10 0e                        bpl     LeftWh                  ;if player to the left of center, branch
b81a: a5 86                        lda     Player_X_Position       ;otherwise slowly pull player left, towards the center
b81c: 38                           sec
b81d: e9 01                        sbc     #$01                    ;subtract one pixel
b81f: 85 86                        sta     Player_X_Position       ;set player's new horizontal coordinate
b821: a5 6d                        lda     Player_PageLoc
b823: e9 00                        sbc     #$00                    ;subtract borrow
b825: 4c 39 b8                     jmp     SetPWh                  ;jump to set player's new page location

b828: ad 90 04     LeftWh          lda     Player_CollisionBits    ;get player's collision bits
b82b: 4a                           lsr     A                       ;shift d0 into carry
b82c: 90 0d                        bcc     WhPull                  ;if d0 not set, branch
b82e: a5 86                        lda     Player_X_Position       ;otherwise slowly pull player right, towards the center
b830: 18                           clc
b831: 69 01                        adc     #$01                    ;add one pixel
b833: 85 86                        sta     Player_X_Position       ;set player's new horizontal coordinate
b835: a5 6d                        lda     Player_PageLoc
b837: 69 00                        adc     #$00                    ;add carry
b839: 85 6d        SetPWh          sta     Player_PageLoc          ;set player's new page location
b83b: a9 10        WhPull          lda     #$10
b83d: 85 00                        sta     $00                     ;set vertical movement force
b83f: a9 01                        lda     #$01
b841: 8d 7d 04                     sta     Whirlpool_Flag          ;set whirlpool flag to be used later
b844: 85 02                        sta     $02                     ;also set maximum vertical speed
b846: 4a                           lsr     A
b847: aa                           tax                             ;set X for player offset
b848: 4c d7 bf                     jmp     ImposeGravity           ;jump to put whirlpool effect on player vertically, do not return

                   ; -----------------------------------------------------------------------------
                   FlagpoleScoreMods
b84b: 05 02 08 04+                 .bulk   $05,$02,$08,$04,$01
                   FlagpoleScoreDigits
b850: 03 03 04 04+                 .bulk   $03,$03,$04,$04,$04

b855: a2 05        FlagpoleRoutine ldx     #$05                    ;set enemy object offset
b857: 86 08                        stx     ObjectOffset            ; to special use slot
b859: b5 16                        lda     Enemy_ID,x
b85b: c9 30                        cmp     #FlagpoleFlagObject     ;if flagpole flag not found,
b85d: d0 56                        bne     ExitFlagP               ;branch to leave
b85f: a5 0e                        lda     GameEngineSubroutine
b861: c9 04                        cmp     #$04                    ;if flagpole slide routine not running,
b863: d0 31                        bne     SkipScore               ;branch to near the end of code
b865: a5 1d                        lda     Player_State
b867: c9 03                        cmp     #$03                    ;if player state not climbing,
b869: d0 2b                        bne     SkipScore               ;branch to near the end of code
b86b: b5 cf                        lda     Enemy_Y_Position,x      ;check flagpole flag's vertical coordinate
b86d: c9 aa                        cmp     #$aa                    ;if flagpole flag down to a certain point,
b86f: b0 28                        bcs     GiveFPScr               ;branch to end the level
b871: a5 ce                        lda     Player_Y_Position       ;check player's vertical coordinate
b873: c9 a2                        cmp     #$a2                    ;if player down to a certain point,
b875: b0 22                        bcs     GiveFPScr               ;branch to end the level
b877: bd 17 04                     lda     Enemy_YMF_Dummy,x
b87a: 69 ff                        adc     #$ff                    ;add movement amount to dummy variable
b87c: 9d 17 04                     sta     Enemy_YMF_Dummy,x       ;save dummy variable
b87f: b5 cf                        lda     Enemy_Y_Position,x      ;get flag's vertical coordinate
b881: 69 01                        adc     #$01                    ;add 1 plus carry to move flag, and
b883: 95 cf                        sta     Enemy_Y_Position,x      ; store vertical coordinate
b885: ad 0e 01                     lda     FlagpoleFNum_YMFDummy
b888: 38                           sec                             ;subtract movement amount from dummy variable
b889: e9 ff                        sbc     #$ff
b88b: 8d 0e 01                     sta     FlagpoleFNum_YMFDummy   ;save dummy variable
b88e: ad 0d 01                     lda     FlagpoleFNum_Y_Pos
b891: e9 01                        sbc     #$01                    ;subtract one plus borrow to move floatey number,
b893: 8d 0d 01                     sta     FlagpoleFNum_Y_Pos      ; and store vertical coordinate here
b896: 4c ac b8     SkipScore       jmp     FPGfx                   ;jump to skip ahead and draw flag and floatey number

b899: ac 0f 01     GiveFPScr       ldy     FlagpoleScore           ;get score offset from earlier (when player touched flagpole)
b89c: b9 4b b8                     lda     FlagpoleScoreMods,y     ;get amount to award player points
b89f: be 50 b8                     ldx     FlagpoleScoreDigits,y   ;get digit with which to award points
b8a2: 9d 34 01                     sta     DigitModifier,x         ;store in digit modifier
b8a5: 20 27 bc                     jsr     AddToScore              ;do sub to award player points depending on height of collision
b8a8: a9 05                        lda     #$05
b8aa: 85 0e                        sta     GameEngineSubroutine    ;set to run end-of-level subroutine on next frame
b8ac: 20 af f1     FPGfx           jsr     GetEnemyOffscreenBits   ;get offscreen information
b8af: 20 52 f1                     jsr     RelativeEnemyPosition   ;get relative coordinates
b8b2: 20 4b e5                     jsr     FlagpoleGfxHandler      ;draw flagpole flag and floatey number
b8b5: 60           ExitFlagP       rts

                   ; -----------------------------------------------------------------------------
                   Jumpspring_Y_PosData
b8b6: 08 10 08 00                  .bulk   $08,$10,$08,$00

                   JumpspringHandler
b8ba: 20 af f1                     jsr     GetEnemyOffscreenBits   ;get offscreen information
b8bd: ad 47 07                     lda     TimerControl            ;check master timer control
b8c0: d0 40                        bne     DrawJSpr                ;branch to last section if set
b8c2: ad 0e 07                     lda     JumpspringAnimCtrl      ;check jumpspring frame control
b8c5: f0 3b                        beq     DrawJSpr                ;branch to last section if not set
b8c7: a8                           tay
b8c8: 88                           dey                             ;subtract one from frame control,
b8c9: 98                           tya                             ; the only way a poor nmos 6502 can
b8ca: 29 02                        and     #%00000010              ; mask out all but d1, original value still in Y
b8cc: d0 07                        bne     DownJSpr                ;if set, branch to move player up
b8ce: e6 ce                        inc     Player_Y_Position
b8d0: e6 ce                        inc     Player_Y_Position       ;move player's vertical position down two pixels
b8d2: 4c d9 b8                     jmp     PosJSpr                 ;skip to next part

b8d5: c6 ce        DownJSpr        dec     Player_Y_Position       ;move player's vertical position up two pixels
b8d7: c6 ce                        dec     Player_Y_Position
b8d9: b5 58        PosJSpr         lda     Jumpspring_FixedYPos,x  ;get permanent vertical position
b8db: 18                           clc
b8dc: 79 b6 b8                     adc     Jumpspring_Y_PosData,y  ;add value using frame control as offset
b8df: 95 cf                        sta     Enemy_Y_Position,x      ;store as new vertical position
b8e1: c0 01                        cpy     #$01                    ;check frame control offset (second frame is $00)
b8e3: 90 0f                        bcc     BounceJS                ;if offset not yet at third frame ($01), skip to next part
b8e5: a5 0a                        lda     A_B_Buttons
b8e7: 29 80                        and     #A_Button               ;check saved controller bits for A button press
b8e9: f0 09                        beq     BounceJS                ;skip to next part if A not pressed
b8eb: 25 0d                        and     PreviousA_B_Buttons     ;check for A button pressed in previous frame
b8ed: d0 05                        bne     BounceJS                ;skip to next part if so
b8ef: a9 f4                        lda     #$f4
b8f1: 8d db 06                     sta     JumpspringForce         ;otherwise write new jumpspring force here
b8f4: c0 03        BounceJS        cpy     #$03                    ;check frame control offset again
b8f6: d0 0a                        bne     DrawJSpr                ;skip to last part if not yet at fifth frame ($03)
b8f8: ad db 06                     lda     JumpspringForce
b8fb: 85 9f                        sta     Player_Y_Speed          ;store jumpspring force as player's new vertical speed
b8fd: a9 00                        lda     #$00
b8ff: 8d 0e 07                     sta     JumpspringAnimCtrl      ;initialize jumpspring frame control
b902: 20 52 f1     DrawJSpr        jsr     RelativeEnemyPosition   ;get jumpspring's relative coordinates
b905: 20 7d e8                     jsr     EnemyGfxHandler         ;draw jumpspring
b908: 20 7a d6                     jsr     OffscreenBoundsCheck    ;check to see if we need to kill it
b90b: ad 0e 07                     lda     JumpspringAnimCtrl      ;if frame control at zero, don't bother
b90e: f0 0d                        beq     ExJSPring               ;trying to animate it, just leave
b910: ad 86 07                     lda     JumpspringTimer
b913: d0 08                        bne     ExJSPring               ;if jumpspring timer not expired yet, leave
b915: a9 04                        lda     #$04
b917: 8d 86 07                     sta     JumpspringTimer         ;otherwise initialize jumpspring timer
b91a: ee 0e 07                     inc     JumpspringAnimCtrl      ;increment frame control to animate jumpspring
b91d: 60           ExJSPring       rts                             ;leave

                   ; -----------------------------------------------------------------------------
b91e: a9 2f        Setup_Vine      lda     #VineObject             ;load identifier for vine object
b920: 95 16                        sta     Enemy_ID,x              ;store in buffer
b922: a9 01                        lda     #$01
b924: 95 0f                        sta     Enemy_Flag,x            ;set flag for enemy object buffer
b926: b9 76 00                     lda     Block_PageLoc,y
b929: 95 6e                        sta     Enemy_PageLoc,x         ;copy page location from previous object
b92b: b9 8f 00                     lda     Block_X_Position,y
b92e: 95 87                        sta     Enemy_X_Position,x      ;copy horizontal coordinate from previous object
b930: b9 d7 00                     lda     Block_Y_Position,y
b933: 95 cf                        sta     Enemy_Y_Position,x      ;copy vertical coordinate from previous object
b935: ac 98 03                     ldy     VineFlagOffset          ;load vine flag/offset to next available vine slot
b938: d0 03                        bne     NextVO                  ;if set at all, don't bother to store vertical
b93a: 8d 9d 03                     sta     VineStart_Y_Position    ;otherwise store vertical coordinate here
b93d: 8a           NextVO          txa                             ;store object offset to next available vine slot
b93e: 99 9a 03                     sta     VineObjOffset,y         ;using vine flag as offset
b941: ee 98 03                     inc     VineFlagOffset          ;increment vine flag offset
b944: a9 04                        lda     #Sfx_GrowVine
b946: 85 fe                        sta     Square2SoundQueue       ;load vine grow sound
b948: 60                           rts

                   ; -----------------------------------------------------------------------------
                   ; $06-$07 - used as address to block buffer data
                   ; $02 - used as vertical high nybble of block buffer offset
b949: 30 60        VineHeightData  .bulk   $30,$60

                   VineObjectHandler
b94b: e0 05                        cpx     #$05                    ;check enemy offset for special use slot
b94d: d0 68                        bne     ExitVH                  ;if not in last slot, branch to leave
b94f: ac 98 03                     ldy     VineFlagOffset
b952: 88                           dey                             ;decrement vine flag in Y, use as offset
b953: ad 99 03                     lda     VineHeight
b956: d9 49 b9                     cmp     VineHeightData,y        ;if vine has reached certain height,
b959: f0 0f                        beq     RunVSubs                ;branch ahead to skip this part
b95b: a5 09                        lda     FrameCounter            ;get frame counter
b95d: 4a                           lsr     A                       ;shift d1 into carry
b95e: 4a                           lsr     A
b95f: 90 09                        bcc     RunVSubs                ;if d1 not set (2 frames every 4) skip this part
b961: a5 d4                        lda     Enemy_Y_Position+5
b963: e9 01                        sbc     #$01                    ;subtract vertical position of vine
b965: 85 d4                        sta     Enemy_Y_Position+5      ;one pixel every frame it's time
b967: ee 99 03                     inc     VineHeight              ;increment vine height
b96a: ad 99 03     RunVSubs        lda     VineHeight              ;if vine still very small,
b96d: c9 08                        cmp     #$08                    ;branch to leave
b96f: 90 46                        bcc     ExitVH
b971: 20 52 f1                     jsr     RelativeEnemyPosition   ;get relative coordinates of vine,
b974: 20 af f1                     jsr     GetEnemyOffscreenBits   ; and any offscreen bits
b977: a0 00                        ldy     #$00                    ;initialize offset used in draw vine sub
b979: 20 35 e4     VDrawLoop       jsr     DrawVine                ;draw vine
b97c: c8                           iny                             ;increment offset
b97d: cc 98 03                     cpy     VineFlagOffset          ;if offset in Y and offset here
b980: d0 f7                        bne     VDrawLoop               ;do not yet match, loop back to draw more vine
b982: ad d1 03                     lda     Enemy_OffscreenBits
b985: 29 0c                        and     #%00001100              ;mask offscreen bits
b987: f0 10                        beq     WrCMTile                ;if none of the saved offscreen bits set, skip ahead
b989: 88                           dey                             ;otherwise decrement Y to get proper offset again
b98a: be 9a 03     KillVine        ldx     VineObjOffset,y         ;get enemy object offset for this vine object
b98d: 20 98 c9                     jsr     EraseEnemyObject        ;kill this vine object
b990: 88                           dey                             ;decrement Y
b991: 10 f7                        bpl     KillVine                ;if any vine objects left, loop back to kill it
b993: 8d 98 03                     sta     VineFlagOffset          ;initialize vine flag/offset
b996: 8d 99 03                     sta     VineHeight              ;initialize vine height
b999: ad 99 03     WrCMTile        lda     VineHeight              ;check vine height
b99c: c9 20                        cmp     #$20                    ;if vine small (less than 32 pixels tall)
b99e: 90 17                        bcc     ExitVH                  ;then branch ahead to leave
b9a0: a2 06                        ldx     #$06                    ;set offset in X to last enemy slot
b9a2: a9 01                        lda     #$01                    ;set A to obtain horizontal in $04, but we don't care
b9a4: a0 1b                        ldy     #$1b                    ;set Y to offset to get block at ($04, $10) of coordinates
b9a6: 20 f0 e3                     jsr     BlockBufferCollision    ;do a sub to get block buffer address set, return contents
b9a9: a4 02                        ldy     $02
b9ab: c0 d0                        cpy     #$d0                    ;if vertical high nybble offset beyond extent of
b9ad: b0 08                        bcs     ExitVH                  ; current block buffer, branch to leave, do not write
b9af: b1 06                        lda     ($06),y                 ;otherwise check contents of block buffer at 
b9b1: d0 04                        bne     ExitVH                  ; current offset, if not empty, branch to leave
b9b3: a9 26                        lda     #$26
b9b5: 91 06                        sta     ($06),y                 ;otherwise, write climbing metatile to block buffer
b9b7: a6 08        ExitVH          ldx     ObjectOffset            ;get enemy object offset and leave
b9b9: 60                           rts

                   ; -----------------------------------------------------------------------------
b9ba: 0f           CannonBitMasks  .dd1    %00001111
b9bb: 07                           .dd1    %00000111

b9bc: ad 4e 07     ProcessCannons  lda     AreaType                ;get area type
b9bf: f0 6f                        beq     ExCannon                ;if water type area, branch to leave
b9c1: a2 02                        ldx     #$02
b9c3: 86 08        ThreeSChk       stx     ObjectOffset            ;start at third enemy slot
b9c5: b5 0f                        lda     Enemy_Flag,x            ;check enemy buffer flag
b9c7: d0 51                        bne     Chk_BB                  ;if set, branch to check enemy
b9c9: bd a8 07                     lda     PseudoRandomBitReg+1,x  ;otherwise get part of LSFR
b9cc: ac cc 06                     ldy     SecondaryHardMode       ;get secondary hard mode flag, use as offset
b9cf: 39 ba b9                     and     CannonBitMasks,y        ;mask out bits of LSFR as decided by flag
b9d2: c9 06                        cmp     #$06                    ;check to see if lower nybble is above certain value
b9d4: b0 44                        bcs     Chk_BB                  ;if so, branch to check enemy
b9d6: a8                           tay                             ;transfer masked contents of LSFR to Y as pseudorandom offset
b9d7: b9 6b 04                     lda     Cannon_PageLoc,y        ;get page location
b9da: f0 3e                        beq     Chk_BB                  ;if not set or on page 0, branch to check enemy
b9dc: b9 7d 04                     lda     Cannon_Timer,y          ;get cannon timer
b9df: f0 08                        beq     FireCannon              ;if expired, branch to fire cannon
b9e1: e9 00                        sbc     #$00                    ;otherwise subtract borrow (note carry will always be clear here)
b9e3: 99 7d 04                     sta     Cannon_Timer,y          ; to count timer down
b9e6: 4c 1a ba                     jmp     Chk_BB

b9e9: ad 47 07     FireCannon      lda     TimerControl            ;if master timer control set,
b9ec: d0 2c                        bne     Chk_BB                  ;branch to check enemy
b9ee: a9 0e                        lda     #$0e                    ;otherwise we start creating one
b9f0: 99 7d 04                     sta     Cannon_Timer,y          ;first, reset cannon timer
b9f3: b9 6b 04                     lda     Cannon_PageLoc,y        ;get page location of cannon
b9f6: 95 6e                        sta     Enemy_PageLoc,x         ;save as page location of bullet bill
b9f8: b9 71 04                     lda     Cannon_X_Position,y     ;get horizontal coordinate of cannon
b9fb: 95 87                        sta     Enemy_X_Position,x      ;save as horizontal coordinate of bullet bill
b9fd: b9 77 04                     lda     Cannon_Y_Position,y     ;get vertical coordinate of cannon
ba00: 38                           sec
ba01: e9 08                        sbc     #$08                    ;subtract eight pixels (because enemies are 24 pixels tall)
ba03: 95 cf                        sta     Enemy_Y_Position,x      ;save as vertical coordinate of bullet bill
ba05: a9 01                        lda     #$01
ba07: 95 b6                        sta     Enemy_Y_HighPos,x       ;set vertical high byte of bullet bill
ba09: 95 0f                        sta     Enemy_Flag,x            ;set buffer flag
ba0b: 4a                           lsr     A                       ;shift right once to init A
ba0c: 95 1e                        sta     Enemy_State,x           ;then initialize enemy's state
ba0e: a9 09                        lda     #$09
ba10: 9d 9a 04                     sta     Enemy_BoundBoxCtrl,x    ;set bounding box size control for bullet bill
ba13: a9 33                        lda     #BulletBill_CannonVar
ba15: 95 16                        sta     Enemy_ID,x              ;load identifier for bullet bill (cannon variant)
ba17: 4c 2d ba                     jmp     Next3Slt                ;move onto next slot

ba1a: b5 16        Chk_BB          lda     Enemy_ID,x              ;check enemy identifier for bullet bill (cannon variant)
ba1c: c9 33                        cmp     #BulletBill_CannonVar
ba1e: d0 0d                        bne     Next3Slt                ;if not found, branch to get next slot
ba20: 20 7a d6                     jsr     OffscreenBoundsCheck    ;otherwise, check to see if it went offscreen
ba23: b5 0f                        lda     Enemy_Flag,x            ;check enemy buffer flag
ba25: f0 06                        beq     Next3Slt                ;if not set, branch to get next slot
ba27: 20 af f1                     jsr     GetEnemyOffscreenBits   ;otherwise, get offscreen information
ba2a: 20 33 ba                     jsr     BulletBillHandler       ;then do sub to handle bullet bill
ba2d: ca           Next3Slt        dex                             ;move onto next slot
ba2e: 10 93                        bpl     ThreeSChk               ;do this until first three slots are checked
ba30: 60           ExCannon        rts                             ;then leave

                   ; -----------------------------------------------------------------------------
                   BulletBillXSpdData
ba31: 18 e8                        .bulk   $18,$e8

                   BulletBillHandler
ba33: ad 47 07                     lda     TimerControl            ;if master timer control set,
ba36: d0 3e                        bne     RunBBSubs               ;branch to run subroutines except movement sub
ba38: b5 1e                        lda     Enemy_State,x
ba3a: d0 2e                        bne     ChkDSte                 ;if bullet bill's state set, branch to check defeated state
ba3c: ad d1 03                     lda     Enemy_OffscreenBits     ;otherwise load offscreen bits
ba3f: 29 0c                        and     #%00001100              ;mask out bits
ba41: c9 0c                        cmp     #%00001100              ;check to see if all bits are set
ba43: f0 40                        beq     KillBB                  ;if so, branch to kill this object
ba45: a0 01                        ldy     #$01                    ;set to move right by default
ba47: 20 43 e1                     jsr     PlayerEnemyDiff         ;get horizontal difference between player and bullet bill
ba4a: 30 01                        bmi     SetupBB                 ;if enemy to the left of player, branch
ba4c: c8                           iny                             ;otherwise increment to move left
ba4d: 94 46        SetupBB         sty     Enemy_MovingDir,x       ;set bullet bill's moving direction
ba4f: 88                           dey                             ;decrement to use as offset
ba50: b9 31 ba                     lda     BulletBillXSpdData,y    ;get horizontal speed based on moving direction
ba53: 95 58                        sta     BlooperMoveSpeed,x      ;and store it
ba55: a5 00                        lda     $00                     ;get horizontal difference
ba57: 69 28                        adc     #$28                    ;add 40 pixels
ba59: c9 50                        cmp     #$50                    ;if less than a certain amount, player is too close
ba5b: 90 28                        bcc     KillBB                  ;to cannon either on left or right side, thus branch
ba5d: a9 01                        lda     #$01
ba5f: 95 1e                        sta     Enemy_State,x           ;otherwise set bullet bill's state
ba61: a9 0a                        lda     #$0a
ba63: 9d 8a 07                     sta     EnemyFrameTimer,x       ;set enemy frame timer
ba66: a9 08                        lda     #$08
ba68: 85 fe                        sta     Square2SoundQueue       ;play fireworks/gunfire sound
ba6a: b5 1e        ChkDSte         lda     Enemy_State,x           ;check enemy state for d5 set
ba6c: 29 20                        and     #%00100000
ba6e: f0 03                        beq     BBFly                   ;if not set, skip to move horizontally
ba70: 20 63 bf                     jsr     MoveD_EnemyVertically   ;otherwise do sub to move bullet bill vertically
ba73: 20 02 bf     BBFly           jsr     MoveEnemyHorizontally   ;do sub to move bullet bill horizontally
ba76: 20 af f1     RunBBSubs       jsr     GetEnemyOffscreenBits   ;get offscreen information
ba79: 20 52 f1                     jsr     RelativeEnemyPosition   ;get relative coordinates
ba7c: 20 43 e2                     jsr     GetEnemyBoundBox        ;get bounding box coordinates
ba7f: 20 53 d8                     jsr     PlayerEnemyCollision    ;handle player to enemy collisions
ba82: 4c 7d e8                     jmp     EnemyGfxHandler         ;draw the bullet bill and leave

ba85: 20 98 c9     KillBB          jsr     EraseEnemyObject        ;kill bullet bill and leave
ba88: 60                           rts

                   ; -----------------------------------------------------------------------------
                   HammerEnemyOfsData
ba89: 04 04 04 05+                 .bulk   $04,$04,$04,$05,$05,$05,$06,$06,$06
ba92: 10 f0        HammerXSpdData  .bulk   $10,$f0

ba94: ad a8 07     SpawnHammerObj  lda     PseudoRandomBitReg+1    ;get pseudorandom bits from
ba97: 29 07                        and     #$07                    ; second part of LSFR
ba99: d0 05                        bne     SetMOfs                 ;if any bits are set, branch and use as offset
ba9b: ad a8 07                     lda     PseudoRandomBitReg+1
ba9e: 29 08                        and     #%00001000              ;get d3 from same part of LSFR
baa0: a8           SetMOfs         tay                             ;use either d3 or d2-d0 for offset here
baa1: b9 2a 00                     lda     Misc_State,y            ;if any values loaded in
baa4: d0 19                        bne     NoHammer                ; $2a-$32 where offset is then leave with carry clear
baa6: be 89 ba                     ldx     HammerEnemyOfsData,y    ;get offset of enemy slot to check using Y as offset
baa9: b5 0f                        lda     Enemy_Flag,x            ;check enemy buffer flag at offset
baab: d0 12                        bne     NoHammer                ;if buffer flag set, branch to leave with carry clear
baad: a6 08                        ldx     ObjectOffset            ;get original enemy object offset
baaf: 8a                           txa
bab0: 99 ae 06                     sta     HammerEnemyOffset,y     ;save here
bab3: a9 90                        lda     #$90
bab5: 99 2a 00                     sta     Misc_State,y            ;save hammer's state here
bab8: a9 07                        lda     #$07
baba: 99 a2 04                     sta     Misc_BoundBoxCtrl,y     ;set something else entirely, here
babd: 38                           sec                             ;return with carry set
babe: 60                           rts

babf: a6 08        NoHammer        ldx     ObjectOffset            ;get original enemy object offset
bac1: 18                           clc                             ;return with carry clear
bac2: 60                           rts

                   ; -----------------------------------------------------------------------------
                   ; $00 - used to set downward force
                   ; $01 - used to set upward force (residual)
                   ; $02 - used to set maximum speed
bac3: ad 47 07     ProcHammerObj   lda     TimerControl            ;if master timer control set
bac6: d0 63                        bne     RunHSubs                ; skip all of this code and go to last subs at the end
bac8: b5 2a                        lda     Misc_State,x            ;otherwise get hammer's state
baca: 29 7f                        and     #%01111111              ;mask out d7
bacc: bc ae 06                     ldy     HammerEnemyOffset,x     ;get enemy object offset that spawned this hammer
bacf: c9 02                        cmp     #$02                    ;check hammer's state
bad1: f0 20                        beq     SetHSpd                 ;if currently at 2, branch
bad3: b0 34                        bcs     SetHPos                 ;if greater than 2, branch elsewhere
bad5: 8a                           txa
bad6: 18                           clc                             ;add 13 bytes to use
bad7: 69 0d                        adc     #$0d                    ; proper misc object
bad9: aa                           tax                             ;return offset to X
bada: a9 10                        lda     #$10
badc: 85 00                        sta     $00                     ;set downward movement force
bade: a9 0f                        lda     #$0f
bae0: 85 01                        sta     $01                     ;set upward movement force (not used)
bae2: a9 04                        lda     #$04
bae4: 85 02                        sta     $02                     ;set maximum vertical speed
bae6: a9 00                        lda     #$00                    ;set A to impose gravity on hammer
bae8: 20 d7 bf                     jsr     ImposeGravity           ;do sub to impose gravity on hammer and move vertically
baeb: 20 0f bf                     jsr     MoveObjectHorizontally  ;do sub to move it horizontally
baee: a6 08                        ldx     ObjectOffset            ;get original misc object offset
baf0: 4c 28 bb                     jmp     RunAllH                 ;branch to essential subroutines

baf3: a9 fe        SetHSpd         lda     #$fe
baf5: 95 ac                        sta     Misc_Y_Speed,x          ;set hammer's vertical speed
baf7: b9 1e 00                     lda     Enemy_State,y           ;get enemy object state
bafa: 29 f7                        and     #%11110111              ;mask out d3
bafc: 99 1e 00                     sta     Enemy_State,y           ;store new state
baff: b6 46                        ldx     Enemy_MovingDir,y       ;get enemy's moving direction
bb01: ca                           dex                             ;decrement to use as offset
bb02: bd 92 ba                     lda     HammerXSpdData,x        ;get proper speed to use based on moving direction
bb05: a6 08                        ldx     ObjectOffset            ;reobtain hammer's buffer offset
bb07: 95 64                        sta     Misc_X_Speed,x          ;set hammer's horizontal speed
bb09: d6 2a        SetHPos         dec     Misc_State,x            ;decrement hammer's state
bb0b: b9 87 00                     lda     Enemy_X_Position,y      ;get enemy's horizontal position
bb0e: 18                           clc
bb0f: 69 02                        adc     #$02                    ;set position 2 pixels to the right
bb11: 95 93                        sta     Misc_X_Position,x       ;store as hammer's horizontal position
bb13: b9 6e 00                     lda     Enemy_PageLoc,y         ;get enemy's page location
bb16: 69 00                        adc     #$00                    ;add carry
bb18: 95 7a                        sta     Misc_PageLoc,x          ;store as hammer's page location
bb1a: b9 cf 00                     lda     Enemy_Y_Position,y      ;get enemy's vertical position
bb1d: 38                           sec
bb1e: e9 0a                        sbc     #$0a                    ;move position 10 pixels upward
bb20: 95 db                        sta     Misc_Y_Position,x       ;store as hammer's vertical position
bb22: a9 01                        lda     #$01
bb24: 95 c2                        sta     Misc_Y_HighPos,x        ;set hammer's vertical high byte
bb26: d0 03                        bne     RunHSubs                ;unconditional branch to skip first routine

bb28: 20 c4 d7     RunAllH         jsr     PlayerHammerCollision   ;handle collisions
bb2b: 20 9b f1     RunHSubs        jsr     GetMiscOffscreenBits    ;get offscreen information
bb2e: 20 48 f1                     jsr     RelativeMiscPosition    ;get relative coordinates
bb31: 20 36 e2                     jsr     GetMiscBoundBox         ;get bounding box coordinates
bb34: 20 dc e4                     jsr     DrawHammer              ;draw the hammer
bb37: 60                           rts                             ;and we are done here

                   ; -----------------------------------------------------------------------------
                   ; $02 - used to store vertical high nybble offset from block buffer routine
                   ; $06 - used to store low byte of block buffer address
bb38: 20 84 bb     CoinBlock       jsr     FindEmptyMiscSlot       ;set offset for empty or last misc object buffer slot
bb3b: b5 76                        lda     Block_PageLoc,x         ;get page location of block object
bb3d: 99 7a 00                     sta     Misc_PageLoc,y          ;store as page location of misc object
bb40: b5 8f                        lda     Block_X_Position,x      ;get horizontal coordinate of block object
bb42: 09 05                        ora     #$05                    ;add 5 pixels
bb44: 99 93 00                     sta     Misc_X_Position,y       ;store as horizontal coordinate of misc object
bb47: b5 d7                        lda     Block_Y_Position,x      ;get vertical coordinate of block object
bb49: e9 10                        sbc     #$10                    ;subtract 16 pixels
bb4b: 99 db 00                     sta     Misc_Y_Position,y       ;store as vertical coordinate of misc object
bb4e: 4c 6c bb                     jmp     JCoinC                  ;jump to rest of code as applies to this misc object

bb51: 20 84 bb     SetupJumpCoin   jsr     FindEmptyMiscSlot       ;set offset for empty or last misc object buffer slot
bb54: bd ea 03                     lda     Block_PageLoc2,x        ;get page location saved earlier
bb57: 99 7a 00                     sta     Misc_PageLoc,y          ;and save as page location for misc object
bb5a: a5 06                        lda     $06                     ;get low byte of block buffer offset
bb5c: 0a                           asl     A
bb5d: 0a                           asl     A                       ;multiply by 16 to use lower nybble
bb5e: 0a                           asl     A
bb5f: 0a                           asl     A
bb60: 09 05                        ora     #$05                    ;add five pixels
bb62: 99 93 00                     sta     Misc_X_Position,y       ;save as horizontal coordinate for misc object
bb65: a5 02                        lda     $02                     ;get vertical high nybble offset from earlier
bb67: 69 20                        adc     #$20                    ;add 32 pixels for the status bar
bb69: 99 db 00                     sta     Misc_Y_Position,y       ;store as vertical coordinate
bb6c: a9 fb        JCoinC          lda     #$fb
bb6e: 99 ac 00                     sta     Misc_Y_Speed,y          ;set vertical speed
bb71: a9 01                        lda     #$01
bb73: 99 c2 00                     sta     Misc_Y_HighPos,y        ;set vertical high byte
bb76: 99 2a 00                     sta     Misc_State,y            ;set state for misc object
bb79: 85 fe                        sta     Square2SoundQueue       ;load coin grab sound
bb7b: 86 08                        stx     ObjectOffset            ;store current control bit as misc object offset 
bb7d: 20 fe bb                     jsr     GiveOneCoin             ;update coin tally on the screen and coin amount variable
bb80: ee 48 07                     inc     CoinTallyFor1Ups        ;increment coin tally used to activate 1-up block flag
bb83: 60                           rts

                   FindEmptyMiscSlot
bb84: a0 08                        ldy     #$08                    ;start at end of misc objects buffer
bb86: b9 2a 00     FMiscLoop       lda     Misc_State,y            ;get misc object state
bb89: f0 07                        beq     UseMiscS                ;branch if none found to use current offset
bb8b: 88                           dey                             ;decrement offset
bb8c: c0 05                        cpy     #$05                    ;do this for three slots
bb8e: d0 f6                        bne     FMiscLoop               ;do this until all slots are checked
bb90: a0 08                        ldy     #$08                    ;if no empty slots found, use last slot
bb92: 8c b7 06     UseMiscS        sty     JumpCoinMiscOffset      ;store offset of misc object buffer here (residual)
bb95: 60                           rts

                   ; -----------------------------------------------------------------------------
bb96: a2 08        MiscObjectsCore ldx     #$08                    ;set at end of misc object buffer
bb98: 86 08        MiscLoop        stx     ObjectOffset            ;store misc object offset here
bb9a: b5 2a                        lda     Misc_State,x            ;check misc object state
bb9c: f0 56                        beq     MiscLoopBack            ;branch to check next slot
bb9e: 0a                           asl     A                       ;otherwise shift d7 into carry
bb9f: 90 06                        bcc     ProcJumpCoin            ;if d7 not set, jumping coin, thus skip to rest of code here
bba1: 20 c3 ba                     jsr     ProcHammerObj           ;otherwise go to process hammer,
bba4: 4c f4 bb                     jmp     MiscLoopBack            ;then check next slot

                   ; -----------------------------------------------------------------------------
                   ; $00 - used to set downward force
                   ; $01 - used to set upward force (residual)
                   ; $02 - used to set maximum speed
bba7: b4 2a        ProcJumpCoin    ldy     Misc_State,x            ;check misc object state
bba9: 88                           dey                             ;decrement to see if it's set to 1
bbaa: f0 1d                        beq     JCoinRun                ;if so, branch to handle jumping coin
bbac: f6 2a                        inc     Misc_State,x            ;otherwise increment state to either start off or as timer
bbae: b5 93                        lda     Misc_X_Position,x       ;get horizontal coordinate for misc object
bbb0: 18                           clc                             ;whether its jumping coin (state 0 only) or floatey number
bbb1: 6d 75 07                     adc     ScrollAmount            ;add current scroll speed
bbb4: 95 93                        sta     Misc_X_Position,x       ;store as new horizontal coordinate
bbb6: b5 7a                        lda     Misc_PageLoc,x          ;get page location
bbb8: 69 00                        adc     #$00                    ;add carry
bbba: 95 7a                        sta     Misc_PageLoc,x          ;store as new page location
bbbc: b5 2a                        lda     Misc_State,x
bbbe: c9 30                        cmp     #$30                    ;check state of object for preset value
bbc0: d0 26                        bne     RunJCSubs               ;if not yet reached, branch to subroutines
bbc2: a9 00                        lda     #$00
bbc4: 95 2a                        sta     Misc_State,x            ;otherwise nullify object state
bbc6: 4c f4 bb                     jmp     MiscLoopBack            ;and move onto next slot

bbc9: 8a           JCoinRun        txa
bbca: 18                           clc                             ;add 13 bytes to offset for next subroutine
bbcb: 69 0d                        adc     #$0d
bbcd: aa                           tax
bbce: a9 50                        lda     #$50                    ;set downward movement amount
bbd0: 85 00                        sta     $00
bbd2: a9 06                        lda     #$06                    ;set maximum vertical speed
bbd4: 85 02                        sta     $02
bbd6: 4a                           lsr     A                       ;divide by 2 and set
bbd7: 85 01                        sta     $01                     ;as upward movement amount (apparently residual)
bbd9: a9 00                        lda     #$00                    ;set A to impose gravity on jumping coin
bbdb: 20 d7 bf                     jsr     ImposeGravity           ;do sub to move coin vertically and impose gravity on it
bbde: a6 08                        ldx     ObjectOffset            ;get original misc object offset
bbe0: b5 ac                        lda     Misc_Y_Speed,x          ;check vertical speed
bbe2: c9 05                        cmp     #$05
bbe4: d0 02                        bne     RunJCSubs               ;if not moving downward fast enough, keep state as-is
bbe6: f6 2a                        inc     Misc_State,x            ;otherwise increment state to change to floatey number
bbe8: 20 48 f1     RunJCSubs       jsr     RelativeMiscPosition    ;get relative coordinates
bbeb: 20 9b f1                     jsr     GetMiscOffscreenBits    ;get offscreen information
bbee: 20 36 e2                     jsr     GetMiscBoundBox         ;get bounding box coordinates (why?)
bbf1: 20 86 e6                     jsr     JCoinGfxHandler         ;draw the coin or floatey number
bbf4: ca           MiscLoopBack    dex                             ;decrement misc object offset
bbf5: 10 a1                        bpl     MiscLoop                ;loop back until all misc objects handled
bbf7: 60                           rts                             ;then leave

                   ; -----------------------------------------------------------------------------
                   CoinTallyOffsets
bbf8: 17 1d                        .bulk   $17,$1d
bbfa: 0b 11        ScoreOffsets    .bulk   $0b,$11
                   StatusBarNybbles
bbfc: 02 13                        .bulk   $02,$13

bbfe: a9 01        GiveOneCoin     lda     #$01                    ;set digit modifier to add 1 coin
bc00: 8d 39 01                     sta     DigitModifier+5         ; to the current player's coin tally
bc03: ae 53 07                     ldx     CurrentPlayer           ;get current player on the screen
bc06: bc f8 bb                     ldy     CoinTallyOffsets,x      ;get offset for player's coin tally
bc09: 20 5f 8f                     jsr     DigitsMathRoutine       ;update the coin tally
bc0c: ee 5e 07                     inc     CoinTally               ;increment onscreen player's coin amount
bc0f: ad 5e 07                     lda     CoinTally
bc12: c9 64                        cmp     #100                    ;does player have 100 coins yet?
bc14: d0 0c                        bne     CoinPoints              ;if not, skip all of this
bc16: a9 00                        lda     #$00
bc18: 8d 5e 07                     sta     CoinTally               ;otherwise, reinitialize coin amount
bc1b: ee 5a 07                     inc     NumberOfLives           ;give the player an extra life
bc1e: a9 40                        lda     #Sfx_ExtraLife
bc20: 85 fe                        sta     Square2SoundQueue       ;play 1-up sound
bc22: a9 02        CoinPoints      lda     #$02                    ;set digit modifier to award
bc24: 8d 38 01                     sta     DigitModifier+4         ;200 points to the player
bc27: ae 53 07     AddToScore      ldx     CurrentPlayer           ;get current player
bc2a: bc fa bb                     ldy     ScoreOffsets,x          ;get offset for player's score
bc2d: 20 5f 8f                     jsr     DigitsMathRoutine       ;update the score internally with value in digit modifier
bc30: ac 53 07     GetSBNybbles    ldy     CurrentPlayer           ;get current player
bc33: b9 fc bb                     lda     StatusBarNybbles,y      ;get nybbles based on player, use to update score and coins
bc36: 20 06 8f     UpdateNumber    jsr     PrintStatusBarNumbers   ;print status bar numbers based on nybbles, whatever they be
bc39: ac 00 03                     ldy     VRAM_Buffer1_Offset
bc3c: b9 fb 02                     lda     VRAM_Buffer1-6,y        ;check highest digit of score
bc3f: d0 05                        bne     NoZSup                  ;if zero, overwrite with space tile for zero suppression
bc41: a9 24                        lda     #$24
bc43: 99 fb 02                     sta     VRAM_Buffer1-6,y
bc46: a6 08        NoZSup          ldx     ObjectOffset            ;get enemy object buffer offset
bc48: 60                           rts

                   ; -----------------------------------------------------------------------------
bc49: a9 2e        SetupPowerUp    lda     #PowerUpObject          ;load power-up identifier into
bc4b: 85 1b                        sta     Enemy_ID+5              ;special use slot of enemy object buffer
bc4d: b5 76                        lda     Block_PageLoc,x         ;store page location of block object
bc4f: 85 73                        sta     Enemy_PageLoc+5         ;as page location of power-up object
bc51: b5 8f                        lda     Block_X_Position,x      ;store horizontal coordinate of block object
bc53: 85 8c                        sta     Enemy_X_Position+5      ;as horizontal coordinate of power-up object
bc55: a9 01                        lda     #$01
bc57: 85 bb                        sta     Enemy_Y_HighPos+5       ;set vertical high byte of power-up object
bc59: b5 d7                        lda     Block_Y_Position,x      ;get vertical coordinate of block object
bc5b: 38                           sec
bc5c: e9 08                        sbc     #$08                    ;subtract 8 pixels
bc5e: 85 d4                        sta     Enemy_Y_Position+5      ;and use as vertical coordinate of power-up object
bc60: a9 01        PwrUpJmp        lda     #$01                    ;this is a residual jump point in enemy object jump table
bc62: 85 23                        sta     Enemy_State+5           ;set power-up object's state
bc64: 85 14                        sta     Enemy_Flag+5            ;set buffer flag
bc66: a9 03                        lda     #$03
bc68: 8d 9f 04                     sta     Enemy_BoundBoxCtrl+5    ;set bounding box size control for power-up object
bc6b: a5 39                        lda     PowerUpType
bc6d: c9 02                        cmp     #$02                    ;check currently loaded power-up type
bc6f: b0 0a                        bcs     PutBehind               ;if star or 1-up, branch ahead
bc71: ad 56 07                     lda     PlayerStatus            ;otherwise check player's current status
bc74: c9 02                        cmp     #$02
bc76: 90 01                        bcc     StrType                 ;if player not fiery, use status as power-up type
bc78: 4a                           lsr     A                       ;otherwise shift right to force fire flower type
bc79: 85 39        StrType         sta     PowerUpType             ;store type here
bc7b: a9 20        PutBehind       lda     #%00100000
bc7d: 8d ca 03                     sta     Enemy_SprAttrib+5       ;set background priority bit
bc80: a9 02                        lda     #Sfx_GrowPowerUp
bc82: 85 fe                        sta     Square2SoundQueue       ;load power-up reveal sound and leave
bc84: 60                           rts

                   ; -----------------------------------------------------------------------------
                   PowerUpObjHandler
bc85: a2 05                        ldx     #$05                    ;set object offset for last slot in enemy object buffer
bc87: 86 08                        stx     ObjectOffset
bc89: a5 23                        lda     Enemy_State+5           ;check power-up object's state
bc8b: f0 5d                        beq     ExitPUp                 ;if not set, branch to leave
bc8d: 0a                           asl     A                       ;shift to check if d7 was set in object state
bc8e: 90 23                        bcc     GrowThePowerUp          ;if not set, branch ahead to skip this part
bc90: ad 47 07                     lda     TimerControl            ;if master timer control set,
bc93: d0 43                        bne     RunPUSubs               ;branch ahead to enemy object routines
bc95: a5 39                        lda     PowerUpType             ;check power-up type
bc97: f0 11                        beq     ShroomM                 ;if normal mushroom, branch ahead to move it
bc99: c9 03                        cmp     #$03
bc9b: f0 0d                        beq     ShroomM                 ;if 1-up mushroom, branch ahead to move it
bc9d: c9 02                        cmp     #$02
bc9f: d0 37                        bne     RunPUSubs               ;if not star, branch elsewhere to skip movement
bca1: 20 f9 ca                     jsr     MoveJumpingEnemy        ;otherwise impose gravity on star power-up and make it jump
bca4: 20 63 e1                     jsr     EnemyJump               ;note that green paratroopa shares the same code here 
bca7: 4c d8 bc                     jmp     RunPUSubs               ;then jump to other power-up subroutines

bcaa: 20 77 ca     ShroomM         jsr     MoveNormalEnemy         ;do sub to make mushrooms move
bcad: 20 c1 df                     jsr     EnemyToBGCollisionDet   ;deal with collisions
bcb0: 4c d8 bc                     jmp     RunPUSubs               ;run the other subroutines

bcb3: a5 09        GrowThePowerUp  lda     FrameCounter            ;get frame counter
bcb5: 29 03                        and     #$03                    ;mask out all but 2 LSB
bcb7: d0 19                        bne     ChkPUSte                ;if any bits set here, branch
bcb9: c6 d4                        dec     Enemy_Y_Position+5      ;otherwise decrement vertical coordinate slowly
bcbb: a5 23                        lda     Enemy_State+5           ;load power-up object state
bcbd: e6 23                        inc     Enemy_State+5           ;increment state for next frame (to make power-up rise)
bcbf: c9 11                        cmp     #$11                    ;if power-up object state not yet past 16th pixel,
bcc1: 90 0f                        bcc     ChkPUSte                ;branch ahead to last part here
bcc3: a9 10                        lda     #$10
bcc5: 95 58                        sta     Enemy_X_Speed,x         ;otherwise set horizontal speed
bcc7: a9 80                        lda     #%10000000
bcc9: 85 23                        sta     Enemy_State+5           ;and then set d7 in power-up object's state
bccb: 0a                           asl     A                       ;shift once to init A
bccc: 8d ca 03                     sta     Enemy_SprAttrib+5       ;initialize background priority bit set here
bccf: 2a                           rol     A                       ;rotate A to set right moving direction
bcd0: 95 46                        sta     Enemy_MovingDir,x       ;set moving direction
bcd2: a5 23        ChkPUSte        lda     Enemy_State+5           ;check power-up object's state
bcd4: c9 06                        cmp     #$06                    ;for if power-up has risen enough
bcd6: 90 12                        bcc     ExitPUp                 ;if not, don't even bother running these routines
bcd8: 20 52 f1     RunPUSubs       jsr     RelativeEnemyPosition   ;get coordinates relative to screen
bcdb: 20 af f1                     jsr     GetEnemyOffscreenBits   ;get offscreen bits
bcde: 20 43 e2                     jsr     GetEnemyBoundBox        ;get bounding box coordinates
bce1: 20 d2 e6                     jsr     DrawPowerUp             ;draw the power-up object
bce4: 20 53 d8                     jsr     PlayerEnemyCollision    ;check for collision with player
bce7: 20 7a d6                     jsr     OffscreenBoundsCheck    ;check to see if it went offscreen
bcea: 60           ExitPUp         rts                             ;and we're done

                   ; -----------------------------------------------------------------------------
                   ; $00 - used to store metatile from block buffer routine
                   ; $02 - used to store vertical high nybble offset from block buffer routine
                   ; $05 - used to store metatile stored in A at beginning of PlayerHeadCollision
                   ; $06-$07 - used as block buffer address indirect
                   BlockYPosAdderData
bceb: 04 12                        .bulk   $04,$12

                   PlayerHeadCollision
bced: 48                           pha                             ;store metatile number to stack
bcee: a9 11                        lda     #$11                    ;load unbreakable block object state by default
bcf0: ae ee 03                     ldx     SprDataOffset_Ctrl      ;load offset control bit here
bcf3: ac 54 07                     ldy     PlayerSize              ;check player's size
bcf6: d0 02                        bne     DBlockSte               ;if small, branch
bcf8: a9 12                        lda     #$12                    ;otherwise load breakable block object state
bcfa: 95 26        DBlockSte       sta     Block_State,x           ;store into block object buffer
bcfc: 20 6b 8a                     jsr     DestroyBlockMetatile    ;store blank metatile in vram buffer to write to name table
bcff: ae ee 03                     ldx     SprDataOffset_Ctrl      ;load offset control bit
bd02: a5 02                        lda     $02                     ;get vertical high nybble offset used in block buffer routine
bd04: 9d e4 03                     sta     Block_Orig_YPos,x       ;set as vertical coordinate for block object
bd07: a8                           tay
bd08: a5 06                        lda     $06                     ;get low byte of block buffer address used in same routine
bd0a: 9d e6 03                     sta     Block_BBuf_Low,x        ;save as offset here to be used later
bd0d: b1 06                        lda     ($06),y                 ;get contents of block buffer at old address at $06, $07
bd0f: 20 f6 bd                     jsr     BlockBumpedChk          ;do a sub to check which block player bumped head on
bd12: 85 00                        sta     $00                     ;store metatile here
bd14: ac 54 07                     ldy     PlayerSize              ;check player's size
bd17: d0 01                        bne     ChkBrick                ;if small, use metatile itself as contents of A
bd19: 98                           tya                             ;otherwise init A (note: big = 0)
bd1a: 90 25        ChkBrick        bcc     PutMTileB               ;if no match was found in previous sub, skip ahead
bd1c: a0 11                        ldy     #$11                    ;otherwise load unbreakable state into block object buffer
bd1e: 94 26                        sty     Block_State,x           ;note this applies to both player sizes
bd20: a9 c4                        lda     #$c4                    ;load empty block metatile into A for now
bd22: a4 00                        ldy     $00                     ;get metatile from before
bd24: c0 58                        cpy     #$58                    ;is it brick with coins (with line)?
bd26: f0 04                        beq     StartBTmr               ;if so, branch
bd28: c0 5d                        cpy     #$5d                    ;is it brick with coins (without line)?
bd2a: d0 15                        bne     PutMTileB               ;if not, branch ahead to store empty block metatile
bd2c: ad bc 06     StartBTmr       lda     BrickCoinTimerFlag      ;check brick coin timer flag
bd2f: d0 08                        bne     ContBTmr                ;if set, timer expired or counting down, thus branch
bd31: a9 0b                        lda     #$0b
bd33: 8d 9d 07                     sta     BrickCoinTimer          ;if not set, set brick coin timer
bd36: ee bc 06                     inc     BrickCoinTimerFlag      ;and set flag linked to it
bd39: ad 9d 07     ContBTmr        lda     BrickCoinTimer          ;check brick coin timer
bd3c: d0 02                        bne     PutOldMT                ;if not yet expired, branch to use current metatile
bd3e: a0 c4                        ldy     #$c4                    ;otherwise use empty block metatile
bd40: 98           PutOldMT        tya                             ;put metatile into A
bd41: 9d e8 03     PutMTileB       sta     Block_Metatile,x        ;store whatever metatile be appropriate here
bd44: 20 84 bd                     jsr     InitBlock_XY_Pos        ;get block object horizontal coordinates saved
bd47: a4 02                        ldy     $02                     ;get vertical high nybble offset
bd49: a9 23                        lda     #$23
bd4b: 91 06                        sta     ($06),y                 ;write blank metatile $23 to block buffer
bd4d: a9 10                        lda     #$10
bd4f: 8d 84 07                     sta     BlockBounceTimer        ;set block bounce timer
bd52: 68                           pla                             ;pull original metatile from stack
bd53: 85 05                        sta     $05                     ;and save here
bd55: a0 00                        ldy     #$00                    ;set default offset
bd57: ad 14 07                     lda     CrouchingFlag           ;is player crouching?
bd5a: d0 05                        bne     SmallBP                 ;if so, branch to increment offset
bd5c: ad 54 07                     lda     PlayerSize              ;is player big?
bd5f: f0 01                        beq     BigBP                   ;if so, branch to use default offset
bd61: c8           SmallBP         iny                             ;increment for small or big and crouching
bd62: a5 ce        BigBP           lda     Player_Y_Position       ;get player's vertical coordinate
bd64: 18                           clc
bd65: 79 eb bc                     adc     BlockYPosAdderData,y    ;add value determined by size
bd68: 29 f0                        and     #$f0                    ;mask out low nybble to get 16-pixel correspondence
bd6a: 95 d7                        sta     Block_Y_Position,x      ;save as vertical coordinate for block object
bd6c: b4 26                        ldy     Block_State,x           ;get block object state
bd6e: c0 11                        cpy     #$11
bd70: f0 06                        beq     Unbreak                 ;if set to value loaded for unbreakable, branch
bd72: 20 02 be                     jsr     BrickShatter            ;execute code for breakable brick
bd75: 4c 7b bd                     jmp     InvOBit                 ;skip subroutine to do last part of code here

bd78: 20 9b bd     Unbreak         jsr     BumpBlock               ;execute code for unbreakable brick or question block
bd7b: ad ee 03     InvOBit         lda     SprDataOffset_Ctrl      ;invert control bit used by block objects
bd7e: 49 01                        eor     #$01                    ; and floatey numbers
bd80: 8d ee 03                     sta     SprDataOffset_Ctrl
bd83: 60                           rts                             ;leave!

                   ; -----------------------------------------------------------------------------
                   InitBlock_XY_Pos
bd84: a5 86                        lda     Player_X_Position       ;get player's horizontal coordinate
bd86: 18                           clc
bd87: 69 08                        adc     #$08                    ;add eight pixels
bd89: 29 f0                        and     #$f0                    ;mask out low nybble to give 16-pixel correspondence
bd8b: 95 8f                        sta     Block_X_Position,x      ;save as horizontal coordinate for block object
bd8d: a5 6d                        lda     Player_PageLoc
bd8f: 69 00                        adc     #$00                    ;add carry to page location of player
bd91: 95 76                        sta     Block_PageLoc,x         ;save as page location of block object
bd93: 9d ea 03                     sta     Block_PageLoc2,x        ;save elsewhere to be used later
bd96: a5 b5                        lda     Player_Y_HighPos
bd98: 95 be                        sta     Block_Y_HighPos,x       ;save vertical high byte of player into
bd9a: 60                           rts                             ;vertical high byte of block object and leave

                   ; -----------------------------------------------------------------------------
bd9b: 20 1f be     BumpBlock       jsr     CheckTopOfBlock         ;check to see if there's a coin directly above this block
bd9e: a9 02                        lda     #Sfx_Bump
bda0: 85 ff                        sta     Square1SoundQueue       ;play bump sound
bda2: a9 00                        lda     #$00
bda4: 95 60                        sta     Block_X_Speed,x         ;initialize horizontal speed for block object
bda6: 9d 3c 04                     sta     Block_Y_MoveForce,x     ;init fractional movement force
bda9: 85 9f                        sta     Player_Y_Speed          ;init player's vertical speed
bdab: a9 fe                        lda     #$fe
bdad: 95 a8                        sta     Block_Y_Speed,x         ;set vertical speed for block object
bdaf: a5 05                        lda     $05                     ;get original metatile from stack
bdb1: 20 f6 bd                     jsr     BlockBumpedChk          ;do a sub to check which block player bumped head on
bdb4: 90 31                        bcc     ExitBlockChk            ;if no match was found, branch to leave
bdb6: 98                           tya                             ;move block number to A
bdb7: c9 09                        cmp     #$09                    ;if block number was within 0-8 range,
bdb9: 90 02                        bcc     BlockCode               ;branch to use current number
bdbb: e9 05                        sbc     #$05                    ;otherwise subtract 5 for second set to get proper number
bdbd: 20 04 8e     BlockCode       jsr     JumpEngine              ;run appropriate subroutine depending on block number

bdc0: d2 bd                        .dd2    MushFlowerBlock
bdc2: 38 bb                        .dd2    CoinBlock
bdc4: 38 bb                        .dd2    CoinBlock
bdc6: d8 bd                        .dd2    ExtraLifeMushBlock
bdc8: d2 bd                        .dd2    MushFlowerBlock
bdca: df bd                        .dd2    VineBlock
bdcc: d5 bd                        .dd2    StarBlock
bdce: 38 bb                        .dd2    CoinBlock
bdd0: d8 bd                        .dd2    ExtraLifeMushBlock

                   ; -----------------------------------------------------------------------------
bdd2: a9 00        MushFlowerBlock lda     #$00                    ;load mushroom/fire flower into power-up type
bdd4: 2c                           bit β–Ό   $02a9                   ;BIT instruction opcode
bdd5: a9 02        StarBlock       lda     #$02                    ;load star into power-up type
bdd7: 2c                           bit β–Ό   $03a9                   ;BIT instruction opcode
                   ExtraLifeMushBlock
bdd8: a9 03                        lda     #$03                    ;load 1-up mushroom into power-up type
bdda: 85 39                        sta     PowerUpType             ;store correct power-up type
bddc: 4c 49 bc                     jmp     SetupPowerUp

bddf: a2 05        VineBlock       ldx     #$05                    ;load last slot for enemy object buffer
bde1: ac ee 03                     ldy     SprDataOffset_Ctrl      ;get control bit
bde4: 20 1e b9                     jsr     Setup_Vine              ;set up vine object
bde7: 60           ExitBlockChk    rts                             ;leave

                   ; -----------------------------------------------------------------------------
                   BrickQBlockMetatiles
bde8: c1 c0 5f 60                  .bulk   $c1,$c0,$5f,$60         ;used by question blocks
                   ; these two sets are functionally identical, but look different
bdec: 55 56 57 58+                 .bulk   $55,$56,$57,$58,$59     ;used by ground level types
bdf1: 5a 5b 5c 5d+                 .bulk   $5a,$5b,$5c,$5d,$5e     ;used by other level types

bdf6: a0 0d        BlockBumpedChk  ldy     #$0d                    ;start at end of metatile data
bdf8: d9 e8 bd     BumpChkLoop     cmp     BrickQBlockMetatiles,y  ;check to see if current metatile matches
bdfb: f0 04                        beq     MatchBump               ;metatile found in block buffer, branch if so
bdfd: 88                           dey                             ;otherwise move onto next metatile
bdfe: 10 f8                        bpl     BumpChkLoop             ;do this until all metatiles are checked
be00: 18                           clc                             ;if none match, return with carry clear
be01: 60           MatchBump       rts                             ;note carry is set if found match

                   ; -----------------------------------------------------------------------------
be02: 20 1f be     BrickShatter    jsr     CheckTopOfBlock         ;check to see if there's a coin directly above this block
be05: a9 01                        lda     #Sfx_BrickShatter
be07: 9d ec 03                     sta     Block_RepFlag,x         ;set flag for block object to immediately replace metatile
be0a: 85 fd                        sta     NoiseSoundQueue         ;load brick shatter sound
be0c: 20 41 be                     jsr     SpawnBrickChunks        ;create brick chunk objects
be0f: a9 fe                        lda     #$fe
be11: 85 9f                        sta     Player_Y_Speed          ;set vertical speed for player
be13: a9 05                        lda     #$05
be15: 8d 39 01                     sta     DigitModifier+5         ;set digit modifier to give player 50 points
be18: 20 27 bc                     jsr     AddToScore              ;do sub to update the score
be1b: ae ee 03                     ldx     SprDataOffset_Ctrl      ;load control bit and leave
be1e: 60                           rts

                   ; -----------------------------------------------------------------------------
be1f: ae ee 03     CheckTopOfBlock ldx     SprDataOffset_Ctrl      ;load control bit
be22: a4 02                        ldy     $02                     ;get vertical high nybble offset used in block buffer
be24: f0 1a                        beq     TopEx                   ;branch to leave if set to zero, because we're at the top
be26: 98                           tya                             ;otherwise set to A
be27: 38                           sec
be28: e9 10                        sbc     #$10                    ;subtract $10 to move up one row in the block buffer
be2a: 85 02                        sta     $02                     ;store as new vertical high nybble offset
be2c: a8                           tay
be2d: b1 06                        lda     ($06),y                 ;get contents of block buffer in same column, one row up
be2f: c9 c2                        cmp     #$c2                    ;is it a coin? (not underwater)
be31: d0 0d                        bne     TopEx                   ;if not, branch to leave
be33: a9 00                        lda     #$00
be35: 91 06                        sta     ($06),y                 ;otherwise put blank metatile where coin was
be37: 20 4d 8a                     jsr     RemoveCoin_Axe          ;write blank metatile to vram buffer
be3a: ae ee 03                     ldx     SprDataOffset_Ctrl      ;get control bit
be3d: 20 51 bb                     jsr     SetupJumpCoin           ;create jumping coin object and update coin variables
be40: 60           TopEx           rts                             ;leave!

                   ; -----------------------------------------------------------------------------
                   SpawnBrickChunks
be41: b5 8f                        lda     Block_X_Position,x      ;set horizontal coordinate of block object
be43: 9d f1 03                     sta     Block_Orig_XPos,x       ; as original horizontal coordinate here
be46: a9 f0                        lda     #$f0
be48: 95 60                        sta     Block_X_Speed,x         ;set horizontal speed for brick chunk objects
be4a: 95 62                        sta     Block_X_Speed+2,x
be4c: a9 fa                        lda     #$fa
be4e: 95 a8                        sta     Block_Y_Speed,x         ;set vertical speed for one
be50: a9 fc                        lda     #$fc
be52: 95 aa                        sta     Block_Y_Speed+2,x       ;set lower vertical speed for the other
be54: a9 00                        lda     #$00
be56: 9d 3c 04                     sta     Block_Y_MoveForce,x     ;init fractional movement force for both
be59: 9d 3e 04                     sta     Block_Y_MoveForce+2,x
be5c: b5 76                        lda     Block_PageLoc,x
be5e: 95 78                        sta     Block_PageLoc+2,x       ;copy page location
be60: b5 8f                        lda     Block_X_Position,x
be62: 95 91                        sta     Block_X_Position+2,x    ;copy horizontal coordinate
be64: b5 d7                        lda     Block_Y_Position,x
be66: 18                           clc                             ;add 8 pixels to vertical coordinate
be67: 69 08                        adc     #$08                    ;and save as vertical coordinate for one of them
be69: 95 d9                        sta     Block_Y_Position+2,x
be6b: a9 fa                        lda     #$fa
be6d: 95 a8                        sta     Block_Y_Speed,x         ;set vertical speed...again??? (redundant)
be6f: 60                           rts

                   ; -----------------------------------------------------------------------------
                   BlockObjectsCore
be70: b5 26                        lda     Block_State,x           ;get state of block object
be72: f0 5d                        beq     UpdSte                  ;if not set, branch to leave
be74: 29 0f                        and     #$0f                    ;mask out high nybble
be76: 48                           pha                             ;push to stack
be77: a8                           tay                             ;put in Y for now
be78: 8a                           txa
be79: 18                           clc
be7a: 69 09                        adc     #$09                    ;add 9 bytes to offset (note two block objects are created
be7c: aa                           tax                             ;when using brick chunks, but only one offset for both)
be7d: 88                           dey                             ;decrement Y to check for solid block state
be7e: f0 33                        beq     BouncingBlockHandler    ;branch if found, otherwise continue for brick chunks
be80: 20 a4 bf                     jsr     ImposeGravityBlock      ;do sub to impose gravity on one block object object
be83: 20 0f bf                     jsr     MoveObjectHorizontally  ;do another sub to move horizontally
be86: 8a                           txa
be87: 18                           clc                             ;move onto next block object
be88: 69 02                        adc     #$02
be8a: aa                           tax
be8b: 20 a4 bf                     jsr     ImposeGravityBlock      ;do sub to impose gravity on other block object
be8e: 20 0f bf                     jsr     MoveObjectHorizontally  ;do another sub to move horizontally
be91: a6 08                        ldx     ObjectOffset            ;get block object offset used for both
be93: 20 59 f1                     jsr     RelativeBlockPosition   ;get relative coordinates
be96: 20 b6 f1                     jsr     GetBlockOffscreenBits   ;get offscreen information
be99: 20 53 ec                     jsr     DrawBrickChunks         ;draw the brick chunks
be9c: 68                           pla                             ;get lower nybble of saved state
be9d: b4 be                        ldy     Block_Y_HighPos,x       ;check vertical high byte of block object
be9f: f0 30                        beq     UpdSte                  ;if above the screen, branch to kill it
bea1: 48                           pha                             ;otherwise save state back into stack
bea2: a9 f0                        lda     #$f0
bea4: d5 d9                        cmp     Block_Y_Position+2,x    ;check to see if bottom block object went
bea6: b0 02                        bcs     ChkTop                  ; to the bottom of the screen, and branch if not
bea8: 95 d9                        sta     Block_Y_Position+2,x    ;otherwise set offscreen coordinate
beaa: b5 d7        ChkTop          lda     Block_Y_Position,x      ;get top block object's vertical coordinate
beac: c9 f0                        cmp     #$f0                    ;see if it went to the bottom of the screen
beae: 68                           pla                             ;pull block object state from stack
beaf: 90 20                        bcc     UpdSte                  ;if not, branch to save state
beb1: b0 1c                        bcs     KillBlock               ;otherwise do unconditional branch to kill it

                   BouncingBlockHandler
beb3: 20 a4 bf                     jsr     ImposeGravityBlock      ;do sub to impose gravity on block object
beb6: a6 08                        ldx     ObjectOffset            ;get block object offset
beb8: 20 59 f1                     jsr     RelativeBlockPosition   ;get relative coordinates
bebb: 20 b6 f1                     jsr     GetBlockOffscreenBits   ;get offscreen information
bebe: 20 d1 eb                     jsr     DrawBlock               ;draw the block
bec1: b5 d7                        lda     Block_Y_Position,x      ;get vertical coordinate
bec3: 29 0f                        and     #$0f                    ;mask out high nybble
bec5: c9 05                        cmp     #$05                    ;check to see if low nybble wrapped around
bec7: 68                           pla                             ;pull state from stack
bec8: b0 07                        bcs     UpdSte                  ;if still above amount, not time to kill block yet, thus branch
beca: a9 01                        lda     #$01
becc: 9d ec 03                     sta     Block_RepFlag,x         ;otherwise set flag to replace metatile
becf: a9 00        KillBlock       lda     #$00                    ;if branched here, nullify object state
bed1: 95 26        UpdSte          sta     Block_State,x           ;store contents of A in block object state
bed3: 60                           rts

                   ; -----------------------------------------------------------------------------
                   ; $02 - used to store offset to block buffer
                   ; $06-$07 - used to store block buffer address
                   BlockObjMT_Updater
bed4: a2 01                        ldx     #$01                    ;set offset to start with second block object
bed6: 86 08        UpdateLoop      stx     ObjectOffset            ;set offset here
bed8: ad 01 03                     lda     VRAM_Buffer1            ;if vram buffer already being used here,
bedb: d0 21                        bne     NextBUpd                ;branch to move onto next block object
bedd: bd ec 03                     lda     Block_RepFlag,x         ;if flag for block object already clear,
bee0: f0 1c                        beq     NextBUpd                ;branch to move onto next block object
bee2: bd e6 03                     lda     Block_BBuf_Low,x        ;get low byte of block buffer
bee5: 85 06                        sta     $06                     ;store into block buffer address
bee7: a9 05                        lda     #$05
bee9: 85 07                        sta     $07                     ;set high byte of block buffer address
beeb: bd e4 03                     lda     Block_Orig_YPos,x       ;get original vertical coordinate of block object
beee: 85 02                        sta     $02                     ;store here and use as offset to block buffer
bef0: a8                           tay
bef1: bd e8 03                     lda     Block_Metatile,x        ;get metatile to be written
bef4: 91 06                        sta     ($06),y                 ;write it to the block buffer
bef6: 20 61 8a                     jsr     ReplaceBlockMetatile    ;do sub to replace metatile where block object is
bef9: a9 00                        lda     #$00
befb: 9d ec 03                     sta     Block_RepFlag,x         ;clear block object flag
befe: ca           NextBUpd        dex                             ;decrement block object offset
beff: 10 d5                        bpl     UpdateLoop              ;do this until both block objects are dealt with
bf01: 60                           rts                             ;then leave

                   ; -----------------------------------------------------------------------------
                   ; $00 - used to store high nybble of horizontal speed as adder
                   ; $01 - used to store low nybble of horizontal speed
                   ; $02 - used to store adder to page location
                   MoveEnemyHorizontally
bf02: e8                           inx                             ;increment offset for enemy offset
bf03: 20 0f bf                     jsr     MoveObjectHorizontally  ;position object horizontally according to
bf06: a6 08                        ldx     ObjectOffset            ; counters, return with saved value in A,
bf08: 60                           rts                             ; put enemy offset back in X and leave

                   MovePlayerHorizontally
bf09: ad 0e 07                     lda     JumpspringAnimCtrl      ;if jumpspring currently animating,
bf0c: d0 3e                        bne     ExXMove                 ;branch to leave
bf0e: aa                           tax                             ;otherwise set zero for offset to use player's stuff
                   MoveObjectHorizontally
bf0f: b5 57                        lda     SprObject_X_Speed,x     ;get currently saved value (horizontal
bf11: 0a                           asl     A                       ; speed, secondary counter, whatever)
bf12: 0a                           asl     A                       ; and move low nybble to high
bf13: 0a                           asl     A
bf14: 0a                           asl     A
bf15: 85 01                        sta     $01                     ;store result here
bf17: b5 57                        lda     SprObject_X_Speed,x     ;get saved value again
bf19: 4a                           lsr     A                       ;move high nybble to low
bf1a: 4a                           lsr     A
bf1b: 4a                           lsr     A
bf1c: 4a                           lsr     A
bf1d: c9 08                        cmp     #$08                    ;if < 8, branch, do not change
bf1f: 90 02                        bcc     SaveXSpd
bf21: 09 f0                        ora     #%11110000              ;otherwise alter high nybble
bf23: 85 00        SaveXSpd        sta     $00                     ;save result here
bf25: a0 00                        ldy     #$00                    ;load default Y value here
bf27: c9 00                        cmp     #$00                    ;if result positive, leave Y alone
bf29: 10 01                        bpl     UseAdder
bf2b: 88                           dey                             ;otherwise decrement Y
bf2c: 84 02        UseAdder        sty     $02                     ;save Y here
bf2e: bd 00 04                     lda     SprObject_X_MoveForce,x ;get whatever number's here
bf31: 18                           clc
bf32: 65 01                        adc     $01                     ;add low nybble moved to high
bf34: 9d 00 04                     sta     SprObject_X_MoveForce,x ;store result here
bf37: a9 00                        lda     #$00                    ;init A
bf39: 2a                           rol     A                       ;rotate carry into d0
bf3a: 48                           pha                             ;push onto stack
bf3b: 6a                           ror     A                       ;rotate d0 back onto carry
bf3c: b5 86                        lda     Player_X_Position,x
bf3e: 65 00                        adc     $00                     ;add carry plus saved value (high nybble moved to low
bf40: 95 86                        sta     Player_X_Position,x     ; plus $f0 if necessary) to object's horizontal position
bf42: b5 6d                        lda     Player_PageLoc,x
bf44: 65 02                        adc     $02                     ;add carry plus other saved value to the
bf46: 95 6d                        sta     Player_PageLoc,x        ; object's page location and save
bf48: 68                           pla
bf49: 18                           clc                             ;pull old carry from stack and add
bf4a: 65 00                        adc     $00                     ; to high nybble moved to low
bf4c: 60           ExXMove         rts                             ;and leave

                   ; -----------------------------------------------------------------------------
                   ; $00 - used for downward force
                   ; $01 - used for upward force
                   ; $02 - used for maximum vertical speed
                   MovePlayerVertically
bf4d: a2 00                        ldx     #$00                    ;set X for player offset
bf4f: ad 47 07                     lda     TimerControl
bf52: d0 05                        bne     NoJSChk                 ;if master timer control set, branch ahead
bf54: ad 0e 07                     lda     JumpspringAnimCtrl      ;otherwise check to see if jumpspring is animating
bf57: d0 f3                        bne     ExXMove                 ;branch to leave if so
bf59: ad 09 07     NoJSChk         lda     VerticalForce           ;dump vertical force
bf5c: 85 00                        sta     $00
bf5e: a9 04                        lda     #$04                    ;set maximum vertical speed here
bf60: 4c ad bf                     jmp     ImposeGravitySprObj     ;then jump to move player vertically

                   ; -----------------------------------------------------------------------------
                   MoveD_EnemyVertically
bf63: a0 3d                        ldy     #$3d                    ;set quick movement amount downwards
bf65: b5 1e                        lda     Enemy_State,x           ;then check enemy state
bf67: c9 05                        cmp     #$05                    ;if not set to unique state for spiny's egg, go ahead
bf69: d0 02                        bne     ContVMove               ;and use, otherwise set different movement amount, continue on
                   MoveFallingPlatform
bf6b: a0 20                        ldy     #$20                    ;set movement amount
bf6d: 4c 94 bf     ContVMove       jmp     SetHiMax                ;jump to skip the rest of this

                   ; -----------------------------------------------------------------------------
                   MoveRedPTroopaDown
bf70: a0 00                        ldy     #$00                    ;set Y to move downwards
bf72: 4c 77 bf                     jmp     MoveRedPTroopa          ;skip to movement routine

                   MoveRedPTroopaUp
bf75: a0 01                        ldy     #$01                    ;set Y to move upwards
bf77: e8           MoveRedPTroopa  inx                             ;increment X for enemy offset
bf78: a9 03                        lda     #$03
bf7a: 85 00                        sta     $00                     ;set downward movement amount here
bf7c: a9 06                        lda     #$06
bf7e: 85 01                        sta     $01                     ;set upward movement amount here
bf80: a9 02                        lda     #$02
bf82: 85 02                        sta     $02                     ;set maximum speed here
bf84: 98                           tya                             ;set movement direction in A, and
bf85: 4c d1 bf                     jmp     RedPTroopaGrav          ; jump to move this thing

                   ; -----------------------------------------------------------------------------
                   MoveDropPlatform
bf88: a0 7f                        ldy     #$7f                    ;set movement amount for drop platform
bf8a: d0 02                        bne     SetMdMax                ;skip ahead of other value set here

                   MoveEnemySlowVert
bf8c: a0 0f                        ldy     #$0f                    ;set movement amount for bowser/other objects
bf8e: a9 02        SetMdMax        lda     #$02                    ;set maximum speed in A
bf90: d0 04                        bne     SetXMoveAmt             ;unconditional branch

                   ; -----------------------------------------------------------------------------
                   MoveJ_EnemyVertically
bf92: a0 1c                        ldy     #$1c                    ;set movement amount for podoboo/other objects
bf94: a9 03        SetHiMax        lda     #$03                    ;set maximum speed in A
bf96: 84 00        SetXMoveAmt     sty     $00                     ;set movement amount here
bf98: e8                           inx                             ;increment X for enemy offset
bf99: 20 ad bf                     jsr     ImposeGravitySprObj     ;do a sub to move enemy object downwards
bf9c: a6 08                        ldx     ObjectOffset            ;get enemy object buffer offset and leave
bf9e: 60                           rts

                   ; -----------------------------------------------------------------------------
bf9f: 06 08        MaxSpdBlockData .bulk   $06,$08

bfa1: a0 00        unref_bfa1      ldy     #$00                    ;this part appears to be residual,
bfa3: 2c                           bit β–Ό   $01a0                   ;no code branches or jumps to it...
                   ImposeGravityBlock
bfa4: a0 01                        ldy     #$01                    ;set offset for maximum speed
bfa6: a9 50                        lda     #$50                    ;set movement amount here
bfa8: 85 00                        sta     $00
bfaa: b9 9f bf                     lda     MaxSpdBlockData,y       ;get maximum speed
                   ImposeGravitySprObj
bfad: 85 02                        sta     $02                     ;set maximum speed here
bfaf: a9 00                        lda     #$00                    ;set value to move downwards
bfb1: 4c d7 bf                     jmp     ImposeGravity           ;jump to the code that actually moves it

                   ; -----------------------------------------------------------------------------
                   MovePlatformDown
bfb4: a9 00                        lda     #$00                    ;save value to stack (if branching here, execute next
bfb6: 2c                           bit β–Ό   $01a9                   ; part as BIT instruction)
bfb7: a9 01        MovePlatformUp  lda     #$01                    ;save value to stack
bfb9: 48                           pha
bfba: b4 16                        ldy     Enemy_ID,x              ;get enemy object identifier
bfbc: e8                           inx                             ;increment offset for enemy object
bfbd: a9 05                        lda     #$05                    ;load default value here
bfbf: c0 29                        cpy     #$29                    ;residual comparison, object #29 never executes
bfc1: d0 02                        bne     SetDblSpd               ; this code, thus unconditional branch here
bfc3: a9 09                        lda     #$09                    ;residual code
bfc5: 85 00        SetDblSpd       sta     $00                     ;save downward movement amount here
bfc7: a9 0a                        lda     #$0a                    ;save upward movement amount here
bfc9: 85 01                        sta     $01
bfcb: a9 03                        lda     #$03                    ;save maximum vertical speed here
bfcd: 85 02                        sta     $02
bfcf: 68                           pla                             ;get value from stack
bfd0: a8                           tay                             ;use as Y, then move onto code shared by red koopa
bfd1: 20 d7 bf     RedPTroopaGrav  jsr     ImposeGravity           ;do a sub to move object gradually
bfd4: a6 08                        ldx     ObjectOffset            ;get enemy object offset and leave
bfd6: 60                           rts

                   ; -----------------------------------------------------------------------------
                   ; $00 - used for downward force
                   ; $01 - used for upward force
                   ; $07 - used as adder for vertical position
bfd7: 48           ImposeGravity   pha                             ;push value to stack
bfd8: bd 16 04                     lda     SprObject_YMF_Dummy,x
bfdb: 18                           clc                             ;add value in movement force to contents of dummy variable
bfdc: 7d 33 04                     adc     SprObject_Y_MoveForce,x
bfdf: 9d 16 04                     sta     SprObject_YMF_Dummy,x
bfe2: a0 00                        ldy     #$00                    ;set Y to zero by default
bfe4: b5 9f                        lda     SprObject_Y_Speed,x     ;get current vertical speed
bfe6: 10 01                        bpl     AlterYP                 ;if currently moving downwards, do not decrement Y
bfe8: 88                           dey                             ;otherwise decrement Y
bfe9: 84 07        AlterYP         sty     $07                     ;store Y here
bfeb: 75 ce                        adc     SprObject_Y_Position,x  ;add vertical position to vertical speed plus carry
bfed: 95 ce                        sta     SprObject_Y_Position,x  ;store as new vertical position
bfef: b5 b5                        lda     SprObject_Y_HighPos,x
bff1: 65 07                        adc     $07                     ;add carry plus contents of $07 to vertical high byte
bff3: 95 b5                        sta     SprObject_Y_HighPos,x   ;store as new vertical high byte
bff5: bd 33 04                     lda     SprObject_Y_MoveForce,x
bff8: 18                           clc
bff9: 65 00                        adc     $00                     ;add downward movement amount to contents of $0433
bffb: 9d 33 04                     sta     SprObject_Y_MoveForce,x
bffe: b5 9f                        lda     SprObject_Y_Speed,x     ;add carry to vertical speed and store
c000: 69 00                        adc     #$00
c002: 95 9f                        sta     SprObject_Y_Speed,x
c004: c5 02                        cmp     $02                     ;compare to maximum speed
c006: 30 10                        bmi     ChkUpM                  ;if less than preset value, skip this part
c008: bd 33 04                     lda     SprObject_Y_MoveForce,x
c00b: c9 80                        cmp     #$80                    ;if less positively than preset maximum, skip this part
c00d: 90 09                        bcc     ChkUpM
c00f: a5 02                        lda     $02
c011: 95 9f                        sta     SprObject_Y_Speed,x     ;keep vertical speed within maximum value
c013: a9 00                        lda     #$00
c015: 9d 33 04                     sta     SprObject_Y_MoveForce,x ;clear fractional
c018: 68           ChkUpM          pla                             ;get value from stack
c019: f0 2b                        beq     ExVMove                 ;if set to zero, branch to leave
c01b: a5 02                        lda     $02
c01d: 49 ff                        eor     #%11111111              ;otherwise get two's compliment of maximum speed
c01f: a8                           tay
c020: c8                           iny
c021: 84 07                        sty     $07                     ;store two's compliment here
c023: bd 33 04                     lda     SprObject_Y_MoveForce,x
c026: 38                           sec                             ;subtract upward movement amount from contents
c027: e5 01                        sbc     $01                     ; of movement force, note that $01 is twice as large as $00,
c029: 9d 33 04                     sta     SprObject_Y_MoveForce,x ; thus it effectively undoes add we did earlier
c02c: b5 9f                        lda     SprObject_Y_Speed,x
c02e: e9 00                        sbc     #$00                    ;subtract borrow from vertical speed and store
c030: 95 9f                        sta     SprObject_Y_Speed,x
c032: c5 07                        cmp     $07                     ;compare vertical speed to two's compliment
c034: 10 10                        bpl     ExVMove                 ;if less negatively than preset maximum, skip this part
c036: bd 33 04                     lda     SprObject_Y_MoveForce,x
c039: c9 80                        cmp     #$80                    ;check if fractional part is above certain amount,
c03b: b0 09                        bcs     ExVMove                 ;and if so, branch to leave
c03d: a5 07                        lda     $07
c03f: 95 9f                        sta     SprObject_Y_Speed,x     ;keep vertical speed within maximum value
c041: a9 ff                        lda     #$ff
c043: 9d 33 04                     sta     SprObject_Y_MoveForce,x ;clear fractional
c046: 60           ExVMove         rts                             ;leave!

                   ; -----------------------------------------------------------------------------
                   EnemiesAndLoopsCore
c047: b5 0f                        lda     Enemy_Flag,x            ;check data here for MSB set
c049: 48                           pha                             ;save in stack
c04a: 0a                           asl     A
c04b: b0 12                        bcs     ChkBowserF              ;if MSB set in enemy flag, branch ahead of jumps
c04d: 68                           pla                             ;get from stack
c04e: f0 03                        beq     ChkAreaTsk              ;if data zero, branch
c050: 4c 82 c8                     jmp     RunEnemyObjectsCore     ;otherwise, jump to run enemy subroutines

c053: ad 1f 07     ChkAreaTsk      lda     AreaParserTaskNum       ;check number of tasks to perform
c056: 29 07                        and     #$07
c058: c9 07                        cmp     #$07                    ;if at a specific task, jump and leave
c05a: f0 0e                        beq     ExitELCore
c05c: 4c cc c0                     jmp     ProcLoopCommand         ;otherwise, jump to process loop command/load enemies

c05f: 68           ChkBowserF      pla                             ;get data from stack
c060: 29 0f                        and     #%00001111              ;mask out high nybble
c062: a8                           tay
c063: b9 0f 00                     lda     Enemy_Flag,y            ;use as pointer and load same place with different offset
c066: d0 02                        bne     ExitELCore
c068: 95 0f                        sta     Enemy_Flag,x            ;if second enemy flag not set, also clear first one
c06a: 60           ExitELCore      rts

                   ; -----------------------------------------------------------------------------
                   LoopCmdWorldNumber
c06b: 03 03 06 06+                 .bulk   $03,$03,$06,$06,$06,$06,$06,$06,$07,$07,$07
                   LoopCmdPageNumber
c076: 05 09 04 05+                 .bulk   $05,$09,$04,$05,$06,$08,$09,$0a,$06,$0b,$10
                   LoopCmdYPosition
c081: 40 b0 b0 80+                 .bulk   $40,$b0,$b0,$80,$40,$40,$80,$40,$f0,$f0,$f0

                   ExecGameLoopback
c08c: a5 6d                        lda     Player_PageLoc          ;send player back four pages
c08e: 38                           sec
c08f: e9 04                        sbc     #$04
c091: 85 6d                        sta     Player_PageLoc
c093: ad 25 07                     lda     CurrentPageLoc          ;send current page back four pages
c096: 38                           sec
c097: e9 04                        sbc     #$04
c099: 8d 25 07                     sta     CurrentPageLoc
c09c: ad 1a 07                     lda     ScreenLeft_PageLoc      ;subtract four from page location
c09f: 38                           sec                             ; of screen's left border
c0a0: e9 04                        sbc     #$04
c0a2: 8d 1a 07                     sta     ScreenLeft_PageLoc
c0a5: ad 1b 07                     lda     ScreenRight_PageLoc     ;do the same for the page location
c0a8: 38                           sec                             ; of screen's right border
c0a9: e9 04                        sbc     #$04
c0ab: 8d 1b 07                     sta     ScreenRight_PageLoc
c0ae: ad 2a 07                     lda     AreaObjectPageLoc       ;subtract four from page control
c0b1: 38                           sec                             ; for area objects
c0b2: e9 04                        sbc     #$04
c0b4: 8d 2a 07                     sta     AreaObjectPageLoc
c0b7: a9 00                        lda     #$00                    ;initialize page select for both
c0b9: 8d 3b 07                     sta     EnemyObjectPageSel      ; area and enemy objects
c0bc: 8d 2b 07                     sta     AreaObjectPageSel
c0bf: 8d 39 07                     sta     EnemyDataOffset         ;initialize enemy object data offset
c0c2: 8d 3a 07                     sta     EnemyObjectPageLoc      ;and enemy object page control
c0c5: b9 f8 9b                     lda     AreaDataOfsLoopback,y   ;adjust area object offset based on
c0c8: 8d 2c 07                     sta     AreaDataOffset          ; which loop command we encountered
c0cb: 60                           rts

c0cc: ad 45 07     ProcLoopCommand lda     LoopCommand             ;check if loop command was found
c0cf: f0 5e                        beq     ChkEnemyFrenzy
c0d1: ad 26 07                     lda     CurrentColumnPos        ;check to see if we're still on the first page
c0d4: d0 59                        bne     ChkEnemyFrenzy          ;if not, do not loop yet
c0d6: a0 0b                        ldy     #$0b                    ;start at the end of each set of loop data
c0d8: 88           FindLoop        dey
c0d9: 30 54                        bmi     ChkEnemyFrenzy          ;if all data is checked and not match, do not loop
c0db: ad 5f 07                     lda     WorldNumber             ;check to see if one of the world numbers
c0de: d9 6b c0                     cmp     LoopCmdWorldNumber,y    ; matches our current world number
c0e1: d0 f5                        bne     FindLoop
c0e3: ad 25 07                     lda     CurrentPageLoc          ;check to see if one of the page numbers
c0e6: d9 76 c0                     cmp     LoopCmdPageNumber,y     ; matches the page we're currently on
c0e9: d0 ed                        bne     FindLoop
c0eb: a5 ce                        lda     Player_Y_Position       ;check to see if the player is at the correct position
c0ed: d9 81 c0                     cmp     LoopCmdYPosition,y      ;if not, branch to check for world 7
c0f0: d0 23                        bne     WrongChk
c0f2: a5 1d                        lda     Player_State            ;check to see if the player is
c0f4: c9 00                        cmp     #$00                    ;on solid ground (i.e. not jumping or falling)
c0f6: d0 1d                        bne     WrongChk                ;if not, player fails to pass loop, and loopback
c0f8: ad 5f 07                     lda     WorldNumber             ;are we in world 7? (check performed on correct
c0fb: c9 06                        cmp     #World7                 ; vertical position and on solid ground)
c0fd: d0 23                        bne     InitMLp                 ;if not, initialize flags used there, otherwise
c0ff: ee d9 06                     inc     MultiLoopCorrectCntr    ;increment counter for correct progression
c102: ee da 06     IncMLoop        inc     MultiLoopPassCntr       ;increment master multi-part counter
c105: ad da 06                     lda     MultiLoopPassCntr       ;have we done all three parts?
c108: c9 03                        cmp     #$03
c10a: d0 1e                        bne     InitLCmd                ;if not, skip this part
c10c: ad d9 06                     lda     MultiLoopCorrectCntr    ;if so, have we done them all correctly?
c10f: c9 03                        cmp     #$03
c111: f0 0f                        beq     InitMLp                 ;if so, branch past unnecessary check here
c113: d0 07                        bne     DoLpBack                ;unconditional branch if previous branch fails

c115: ad 5f 07     WrongChk        lda     WorldNumber             ;are we in world 7? (check performed on
c118: c9 06                        cmp     #World7                 ; incorrect vertical position or not on solid ground)
c11a: f0 e6                        beq     IncMLoop
c11c: 20 8c c0     DoLpBack        jsr     ExecGameLoopback        ;if player is not in right place, loop back
c11f: 20 71 d0                     jsr     KillAllEnemies
c122: a9 00        InitMLp         lda     #$00                    ;initialize counters used for multi-part loop commands
c124: 8d da 06                     sta     MultiLoopPassCntr
c127: 8d d9 06                     sta     MultiLoopCorrectCntr
c12a: a9 00        InitLCmd        lda     #$00                    ;initialize loop command flag
c12c: 8d 45 07                     sta     LoopCommand
                   ; 
c12f: ad cd 06     ChkEnemyFrenzy  lda     EnemyFrenzyQueue        ;check for enemy object in frenzy queue
c132: f0 10                        beq     ProcessEnemyData        ;if not, skip this part
c134: 95 16                        sta     Enemy_ID,x              ;store as enemy object identifier here
c136: a9 01                        lda     #$01
c138: 95 0f                        sta     Enemy_Flag,x            ;activate enemy object flag
c13a: a9 00                        lda     #$00
c13c: 95 1e                        sta     Enemy_State,x           ;initialize state and frenzy queue
c13e: 8d cd 06                     sta     EnemyFrenzyQueue
c141: 4c 26 c2                     jmp     InitEnemyObject         ;and then jump to deal with this enemy

                   ; -----------------------------------------------------------------------------
                   ; $06 - used to hold page location of extended right boundary
                   ; $07 - used to hold high nybble of position of extended right boundary
                   ProcessEnemyData
c144: ac 39 07                     ldy     EnemyDataOffset         ;get offset of enemy object data
c147: b1 e9                        lda     (EnemyData),y           ;load first byte
c149: c9 ff                        cmp     #$ff                    ;check for EOD terminator
c14b: d0 03                        bne     ChkEndofBuffer
c14d: 4c 16 c2                     jmp     CheckFrenzyBuffer       ;if found, jump to check frenzy buffer, otherwise

c150: 29 0f        ChkEndofBuffer  and     #%00001111              ;check for special row $0e
c152: c9 0e                        cmp     #$0e
c154: f0 0e                        beq     CheckRightBounds        ;if found, branch, otherwise
c156: e0 05                        cpx     #$05                    ;check for end of buffer
c158: 90 0a                        bcc     CheckRightBounds        ;if not at end of buffer, branch
c15a: c8                           iny
c15b: b1 e9                        lda     (EnemyData),y           ;check for specific value here
c15d: 29 3f                        and     #%00111111              ;not sure what this was intended for, exactly
c15f: c9 2e                        cmp     #$2e                    ;this part is quite possibly residual code
c161: f0 01                        beq     CheckRightBounds        ; but it has the effect of keeping enemies out of
c163: 60                           rts                             ; the sixth slot

                   CheckRightBounds
c164: ad 1d 07                     lda     ScreenRight_X_Pos       ;add 48 to pixel coordinate of right boundary
c167: 18                           clc
c168: 69 30                        adc     #$30
c16a: 29 f0                        and     #%11110000              ;store high nybble
c16c: 85 07                        sta     $07
c16e: ad 1b 07                     lda     ScreenRight_PageLoc     ;add carry to page location of right boundary
c171: 69 00                        adc     #$00
c173: 85 06                        sta     $06                     ;store page location + carry
c175: ac 39 07                     ldy     EnemyDataOffset
c178: c8                           iny
c179: b1 e9                        lda     (EnemyData),y           ;if MSB of enemy object is clear, branch to check for row $0f
c17b: 0a                           asl     A
c17c: 90 0b                        bcc     CheckPageCtrlRow
c17e: ad 3b 07                     lda     EnemyObjectPageSel      ;if page select already set, do not set again
c181: d0 06                        bne     CheckPageCtrlRow
c183: ee 3b 07                     inc     EnemyObjectPageSel      ;otherwise, if MSB is set, set page select 
c186: ee 3a 07                     inc     EnemyObjectPageLoc      ; and increment page control
                   CheckPageCtrlRow
c189: 88                           dey
c18a: b1 e9                        lda     (EnemyData),y           ;reread first byte
c18c: 29 0f                        and     #$0f
c18e: c9 0f                        cmp     #$0f                    ;check for special row $0f
c190: d0 19                        bne     PositionEnemyObj        ;if not found, branch to position enemy object
c192: ad 3b 07                     lda     EnemyObjectPageSel      ;if page select set,
c195: d0 14                        bne     PositionEnemyObj        ;branch without reading second byte
c197: c8                           iny
c198: b1 e9                        lda     (EnemyData),y           ;otherwise, get second byte, mask out 2 MSB
c19a: 29 3f                        and     #%00111111
c19c: 8d 3a 07                     sta     EnemyObjectPageLoc      ;store as page control for enemy object data
c19f: ee 39 07                     inc     EnemyDataOffset         ;increment enemy object data offset 2 bytes
c1a2: ee 39 07                     inc     EnemyDataOffset
c1a5: ee 3b 07                     inc     EnemyObjectPageSel      ;set page select for enemy object data and 
c1a8: 4c cc c0                     jmp     ProcLoopCommand         ;jump back to process loop commands again

                   PositionEnemyObj
c1ab: ad 3a 07                     lda     EnemyObjectPageLoc      ;store page control as page location
c1ae: 95 6e                        sta     Enemy_PageLoc,x         ; for enemy object
c1b0: b1 e9                        lda     (EnemyData),y           ;get first byte of enemy object
c1b2: 29 f0                        and     #%11110000
c1b4: 95 87                        sta     Enemy_X_Position,x      ;store column position
c1b6: cd 1d 07                     cmp     ScreenRight_X_Pos       ;check column position against right boundary
c1b9: b5 6e                        lda     Enemy_PageLoc,x         ;without subtracting, then subtract borrow
c1bb: ed 1b 07                     sbc     ScreenRight_PageLoc     ; from page location
c1be: b0 0b                        bcs     CheckRightExtBounds     ;if enemy object beyond or at boundary, branch
c1c0: b1 e9                        lda     (EnemyData),y
c1c2: 29 0f                        and     #%00001111              ;check for special row $0e
c1c4: c9 0e                        cmp     #$0e                    ;if found, jump elsewhere
c1c6: f0 69                        beq     ParseRow0e
c1c8: 4c 50 c2                     jmp     CheckThreeBytes         ;if not found, unconditional jump

                   CheckRightExtBounds
c1cb: a5 07                        lda     $07                     ;check right boundary + 48 against
c1cd: d5 87                        cmp     Enemy_X_Position,x      ; column position without subtracting,
c1cf: a5 06                        lda     $06                     ; then subtract borrow from page control temp
c1d1: f5 6e                        sbc     Enemy_PageLoc,x         ; plus carry
c1d3: 90 41                        bcc     CheckFrenzyBuffer       ;if enemy object beyond extended boundary, branch
c1d5: a9 01                        lda     #$01                    ;store value in vertical high byte
c1d7: 95 b6                        sta     Enemy_Y_HighPos,x
c1d9: b1 e9                        lda     (EnemyData),y           ;get first byte again
c1db: 0a                           asl     A                       ;multiply by four to get the vertical
c1dc: 0a                           asl     A                       ; coordinate
c1dd: 0a                           asl     A
c1de: 0a                           asl     A
c1df: 95 cf                        sta     Enemy_Y_Position,x
c1e1: c9 e0                        cmp     #$e0                    ;do one last check for special row $0e
c1e3: f0 4c                        beq     ParseRow0e              ;(necessary if branched to $c1cb)
c1e5: c8                           iny
c1e6: b1 e9                        lda     (EnemyData),y           ;get second byte of object
c1e8: 29 40                        and     #%01000000              ;check to see if hard mode bit is set
c1ea: f0 05                        beq     CheckForEnemyGroup      ;if not, branch to check for group enemy objects
c1ec: ad cc 06                     lda     SecondaryHardMode       ;if set, check to see if secondary hard mode flag
c1ef: f0 6d                        beq     Inc2B                   ;is on, and if not, branch to skip this object completely
                   CheckForEnemyGroup
c1f1: b1 e9                        lda     (EnemyData),y           ;get second byte and mask out 2 MSB
c1f3: 29 3f                        and     #%00111111
c1f5: c9 37                        cmp     #$37                    ;check for value below $37
c1f7: 90 04                        bcc     BuzzyBeetleMutate
c1f9: c9 3f                        cmp     #$3f                    ;if $37 or greater, check for value
c1fb: 90 31                        bcc     DoGroup                 ;below $3f, branch if below $3f
                   BuzzyBeetleMutate
c1fd: c9 06                        cmp     #Goomba                 ;if below $37, check for goomba
c1ff: d0 07                        bne     StrID                   ; value ($3f or more always fails)
c201: ac 6a 07                     ldy     PrimaryHardMode         ;check if primary hard mode flag is set
c204: f0 02                        beq     StrID                   ; and if so, change goomba to buzzy beetle
c206: a9 02                        lda     #BuzzyBeetle
c208: 95 16        StrID           sta     Enemy_ID,x              ;store enemy object number into buffer
c20a: a9 01                        lda     #$01
c20c: 95 0f                        sta     Enemy_Flag,x            ;set flag for enemy in buffer
c20e: 20 26 c2                     jsr     InitEnemyObject
c211: b5 0f                        lda     Enemy_Flag,x            ;check to see if flag is set
c213: d0 49                        bne     Inc2B                   ;if not, leave, otherwise branch
c215: 60                           rts

                   CheckFrenzyBuffer
c216: ad cb 06                     lda     EnemyFrenzyBuffer       ;if enemy object stored in frenzy buffer
c219: d0 09                        bne     StrFre                  ; then branch ahead to store in enemy object buffer
c21b: ad 98 03                     lda     VineFlagOffset          ;otherwise check vine flag offset
c21e: c9 01                        cmp     #$01
c220: d0 0b                        bne     ExEPar                  ;if other value <> 1, leave
c222: a9 2f                        lda     #VineObject             ;otherwise put vine in enemy identifier
c224: 95 16        StrFre          sta     Enemy_ID,x              ;store contents of frenzy buffer into enemy identifier value
c226: a9 00        InitEnemyObject lda     #$00                    ;initialize enemy state
c228: 95 1e                        sta     Enemy_State,x
c22a: 20 6c c2                     jsr     CheckpointEnemyID       ;jump ahead to run jump engine and subroutines
c22d: 60           ExEPar          rts                             ;then leave

c22e: 4c 1b c7     DoGroup         jmp     HandleGroupEnemies      ;handle enemy group objects

c231: c8           ParseRow0e      iny                             ;increment Y to load third byte of object
c232: c8                           iny
c233: b1 e9                        lda     (EnemyData),y
c235: 4a                           lsr     A                       ;move 3 MSB to the bottom, effectively
c236: 4a                           lsr     A                       ; making %xxx00000 into %00000xxx
c237: 4a                           lsr     A
c238: 4a                           lsr     A
c239: 4a                           lsr     A
c23a: cd 5f 07                     cmp     WorldNumber             ;is it the same world number as we're on?
c23d: d0 0e                        bne     NotUse                  ;if not, do not use (this allows multiple uses
c23f: 88                           dey                             ; of the same area, like the underground bonus areas)
c240: b1 e9                        lda     (EnemyData),y           ;otherwise, get second byte and use as offset
c242: 8d 50 07                     sta     AreaPointer             ; to addresses for level and enemy object data
c245: c8                           iny
c246: b1 e9                        lda     (EnemyData),y           ;get third byte again, and this time mask out
c248: 29 1f                        and     #%00011111              ; the 3 MSB from before, save as page number to be
c24a: 8d 51 07                     sta     EntrancePage            ; used upon entry to area, if area is entered
c24d: 4c 5b c2     NotUse          jmp     Inc3B

c250: ac 39 07     CheckThreeBytes ldy     EnemyDataOffset
c253: b1 e9                        lda     (EnemyData),y
c255: 29 0f                        and     #$0f
c257: c9 0e                        cmp     #$0e
c259: d0 03                        bne     Inc2B
c25b: ee 39 07     Inc3B           inc     EnemyDataOffset
c25e: ee 39 07     Inc2B           inc     EnemyDataOffset
c261: ee 39 07                     inc     EnemyDataOffset
c264: a9 00                        lda     #$00
c266: 8d 3b 07                     sta     EnemyObjectPageSel
c269: a6 08                        ldx     ObjectOffset
c26b: 60                           rts

                   CheckpointEnemyID
c26c: b5 16                        lda     Enemy_ID,x
c26e: c9 15                        cmp     #$15
c270: b0 0d                        bcs     InitEnemyRoutines
c272: a8                           tay
c273: b5 cf                        lda     Enemy_Y_Position,x
c275: 69 08                        adc     #$08
c277: 95 cf                        sta     Enemy_Y_Position,x
c279: a9 01                        lda     #$01
c27b: 9d d8 03                     sta     EnemyOffscrBitsMasked,x
c27e: 98                           tya
                   InitEnemyRoutines
c27f: 20 04 8e                     jsr     JumpEngine

                   ; jump engine table for newly loaded enemy objects
c282: 0e c3                        .dd2    InitNormalEnemy         ;for objects $00-$0f
c284: 0e c3                        .dd2    InitNormalEnemy
c286: 0e c3                        .dd2    InitNormalEnemy
c288: 1e c3                        .dd2    InitRedKoopa
c28a: f0 c2                        .dd2    NoInitCode
c28c: 28 c3                        .dd2    InitHammerBro
c28e: f1 c2                        .dd2    InitGoomba
c290: 42 c3                        .dd2    InitBloober
c292: 6b c3                        .dd2    InitBulletBill
c294: f0 c2                        .dd2    NoInitCode
c296: 75 c3                        .dd2    InitCheepCheep
c298: 75 c3                        .dd2    InitCheepCheep
c29a: f7 c2                        .dd2    InitPodoboo
c29c: 87 c7                        .dd2    InitPiranhaPlant
c29e: d1 c7                        .dd2    InitJumpGPTroopa
c2a0: 4a c3                        .dd2    InitRedPTroopa
c2a2: 3d c3                        .dd2    InitHorizFlySwimEnemy   ;for objects $10-$1f
c2a4: 85 c3                        .dd2    InitLakitu
c2a6: a0 c7                        .dd2    InitEnemyFrenzy
c2a8: f0 c2                        .dd2    NoInitCode
c2aa: a0 c7                        .dd2    InitEnemyFrenzy
c2ac: a0 c7                        .dd2    InitEnemyFrenzy
c2ae: a0 c7                        .dd2    InitEnemyFrenzy
c2b0: a0 c7                        .dd2    InitEnemyFrenzy
c2b2: b8 c7                        .dd2    EndFrenzy
c2b4: f0 c2                        .dd2    NoInitCode
c2b6: f0 c2                        .dd2    NoInitCode
c2b8: 5c c4                        .dd2    InitShortFirebar
c2ba: 5c c4                        .dd2    InitShortFirebar
c2bc: 5c c4                        .dd2    InitShortFirebar
c2be: 5c c4                        .dd2    InitShortFirebar
c2c0: 59 c4                        .dd2    InitLongFirebar
c2c2: f0 c2                        .dd2    NoInitCode              ;for objects $20-$2f
c2c4: f0 c2                        .dd2    NoInitCode
c2c6: f0 c2                        .dd2    NoInitCode
c2c8: f0 c2                        .dd2    NoInitCode
c2ca: df c7                        .dd2    InitBalPlatform
c2cc: 12 c8                        .dd2    InitVertPlatform
c2ce: 3f c8                        .dd2    LargeLiftUp
c2d0: 45 c8                        .dd2    LargeLiftDown
c2d2: 0b c8                        .dd2    InitHoriPlatform
c2d4: 03 c8                        .dd2    InitDropPlatform
c2d6: 0b c8                        .dd2    InitHoriPlatform
c2d8: 4b c8                        .dd2    PlatLiftUp
c2da: 57 c8                        .dd2    PlatLiftDown
c2dc: 49 c5                        .dd2    InitBowser
c2de: 60 bc                        .dd2    PwrUpJmp                ;possibly dummy value
c2e0: 1e b9                        .dd2    Setup_Vine
c2e2: f0 c2                        .dd2    NoInitCode              ;for objects $30-$36
c2e4: f0 c2                        .dd2    NoInitCode
c2e6: f0 c2                        .dd2    NoInitCode
c2e8: f0 c2                        .dd2    NoInitCode
c2ea: f0 c2                        .dd2    NoInitCode
c2ec: 07 c3                        .dd2    InitRetainerObj
c2ee: 81 c8                        .dd2    EndOFEnemyInitCode

                   ; -----------------------------------------------------------------------------
c2f0: 60           NoInitCode      rts                             ;this executed when enemy object has no init code

                   ; -----------------------------------------------------------------------------
c2f1: 20 0e c3     InitGoomba      jsr     InitNormalEnemy         ;set appropriate horizontal speed
c2f4: 4c 46 c3                     jmp     SmallBBox               ;set $09 as bounding box control, set other values

                   ; -----------------------------------------------------------------------------
c2f7: a9 02        InitPodoboo     lda     #$02                    ;set enemy position to below
c2f9: 95 b6                        sta     Enemy_Y_HighPos,x       ; the bottom of the screen
c2fb: 95 cf                        sta     Enemy_Y_Position,x
c2fd: 4a                           lsr     A
c2fe: 9d 96 07                     sta     EnemyIntervalTimer,x    ;set timer for enemy
c301: 4a                           lsr     A
c302: 95 1e                        sta     Enemy_State,x           ;initialize enemy state, then jump to use
c304: 4c 46 c3                     jmp     SmallBBox               ; $09 as bounding box size and set other things

                   ; -----------------------------------------------------------------------------
c307: a9 b8        InitRetainerObj lda     #$b8                    ;set fixed vertical position for
c309: 95 cf                        sta     Enemy_Y_Position,x      ; princess/mushroom retainer object
c30b: 60                           rts

                   ; -----------------------------------------------------------------------------
c30c: f8 f4        NormalXSpdData  .bulk   $f8,$f4

c30e: a0 01        InitNormalEnemy ldy     #$01                    ;load offset of 1 by default
c310: ad 6a 07                     lda     PrimaryHardMode         ;check for primary hard mode flag set
c313: d0 01                        bne     GetESpd
c315: 88                           dey                             ;if not set, decrement offset
c316: b9 0c c3     GetESpd         lda     NormalXSpdData,y        ;get appropriate horizontal speed
c319: 95 58        SetESpd         sta     BlooperMoveSpeed,x      ;store as speed for enemy object
c31b: 4c 5a c3                     jmp     TallBBox                ;branch to set bounding box control and other data

                   ; -----------------------------------------------------------------------------
c31e: 20 0e c3     InitRedKoopa    jsr     InitNormalEnemy         ;load appropriate horizontal speed
c321: a9 01                        lda     #$01                    ;set enemy state for red koopa troopa $03
c323: 95 1e                        sta     Enemy_State,x
c325: 60                           rts

                   ; -----------------------------------------------------------------------------
                   HBroWalkingTimerData
c326: 80 50                        .bulk   $80,$50

c328: a9 00        InitHammerBro   lda     #$00                    ;init horizontal speed and timer used by hammer bro
c32a: 9d a2 03                     sta     HammerThrowingTimer,x   ;apparently to time hammer throwing
c32d: 95 58                        sta     Enemy_X_Speed,x
c32f: ac cc 06                     ldy     SecondaryHardMode       ;get secondary hard mode flag
c332: b9 26 c3                     lda     HBroWalkingTimerData,y
c335: 9d 96 07                     sta     EnemyIntervalTimer,x    ;set value as delay for hammer bro to walk left
c338: a9 0b                        lda     #$0b                    ;set specific value for bounding box size control
c33a: 4c 5c c3                     jmp     SetBBox

                   ; -----------------------------------------------------------------------------
                   InitHorizFlySwimEnemy
c33d: a9 00                        lda     #$00                    ;initialize horizontal speed
c33f: 4c 19 c3                     jmp     SetESpd

                   ; -----------------------------------------------------------------------------
c342: a9 00        InitBloober     lda     #$00                    ;initialize horizontal speed
c344: 95 58                        sta     BlooperMoveSpeed,x
c346: a9 09        SmallBBox       lda     #$09                    ;set specific bounding box size control
c348: d0 12                        bne     SetBBox                 ;unconditional branch

                   ; -----------------------------------------------------------------------------
c34a: a0 30        InitRedPTroopa  ldy     #$30                    ;load central position adder for 48 pixels down
c34c: b5 cf                        lda     Enemy_Y_Position,x      ;set vertical coordinate into location to
c34e: 9d 01 04                     sta     RedPTroopaOrigXPos,x    ; be used as original vertical coordinate
c351: 10 02                        bpl     GetCent                 ;if vertical coordinate < $80
c353: a0 e0                        ldy     #$e0                    ;if => $80, load position adder for 32 pixels up
c355: 98           GetCent         tya                             ;send central position adder to A
c356: 75 cf                        adc     Enemy_Y_Position,x      ;add to current vertical coordinate
c358: 95 58                        sta     RedPTroopaCenterYPos,x  ;store as central vertical coordinate
c35a: a9 03        TallBBox        lda     #$03                    ;set specific bounding box size control
c35c: 9d 9a 04     SetBBox         sta     Enemy_BoundBoxCtrl,x    ;set bounding box control here
c35f: a9 02                        lda     #$02                    ;set moving direction for left
c361: 95 46                        sta     Enemy_MovingDir,x
c363: a9 00        InitVStf        lda     #$00                    ;initialize vertical speed
c365: 95 a0                        sta     Enemy_Y_Speed,x         ; and movement force
c367: 9d 34 04                     sta     Enemy_Y_MoveForce,x
c36a: 60                           rts

                   ; -----------------------------------------------------------------------------
c36b: a9 02        InitBulletBill  lda     #$02                    ;set moving direction for left
c36d: 95 46                        sta     Enemy_MovingDir,x
c36f: a9 09                        lda     #$09                    ;set bounding box control for $09
c371: 9d 9a 04                     sta     Enemy_BoundBoxCtrl,x
c374: 60                           rts

                   ; -----------------------------------------------------------------------------
c375: 20 46 c3     InitCheepCheep  jsr     SmallBBox               ;set vertical bounding box, speed, init others
c378: bd a7 07                     lda     PseudoRandomBitReg,x    ;check one portion of LSFR
c37b: 29 10                        and     #%00010000              ;get d4 from it
c37d: 95 58                        sta     CheepCheepMoveMFlag,x   ;save as movement flag of some sort
c37f: b5 cf                        lda     Enemy_Y_Position,x
c381: 9d 34 04                     sta     CheepCheepOrigYPos,x    ;save original vertical coordinate here
c384: 60                           rts

                   ; -----------------------------------------------------------------------------
c385: ad cb 06     InitLakitu      lda     EnemyFrenzyBuffer       ;check to see if an enemy is already in
c388: d0 0b                        bne     KillLakitu              ; the frenzy buffer, and branch to kill lakitu if so
c38a: a9 00        SetupLakitu     lda     #$00                    ;erase counter for lakitu's reappearance
c38c: 8d d1 06                     sta     LakituReappearTimer
c38f: 20 3d c3                     jsr     InitHorizFlySwimEnemy   ;set $03 as bounding box, set other attributes
c392: 4c d9 c7                     jmp     TallBBox2               ;set $03 as bounding box again (not necessary) and leave

c395: 4c 98 c9     KillLakitu      jmp     EraseEnemyObject

                   ; -----------------------------------------------------------------------------
                   ; $01-$03 - used to hold pseudorandom difference adjusters
                   PRDiffAdjustData
c398: 26 2c 32 38                  .bulk   $26,$2c,$32,$38
c39c: 20 22 24 26                  .bulk   $20,$22,$24,$26
c3a0: 13 14 15 16                  .bulk   $13,$14,$15,$16

                   LakituAndSpinyHandler
c3a4: ad 8f 07                     lda     FrenzyEnemyTimer        ;if timer here not expired, leave
c3a7: d0 3c                        bne     ExLSHand
c3a9: e0 05                        cpx     #$05                    ;if we are on the special use slot, leave
c3ab: b0 38                        bcs     ExLSHand
c3ad: a9 80                        lda     #$80                    ;set timer
c3af: 8d 8f 07                     sta     FrenzyEnemyTimer
c3b2: a0 04                        ldy     #$04                    ;start with the last enemy slot
c3b4: b9 16 00     ChkLak          lda     Enemy_ID,y              ;check all enemy slots to see
c3b7: c9 11                        cmp     #Lakitu                 ;if lakitu is on one of them
c3b9: f0 2b                        beq     CreateSpiny             ;if so, branch out of this loop
c3bb: 88                           dey                             ;otherwise check another slot
c3bc: 10 f6                        bpl     ChkLak                  ;loop until all slots are checked
c3be: ee d1 06                     inc     LakituReappearTimer     ;increment reappearance timer
c3c1: ad d1 06                     lda     LakituReappearTimer
c3c4: c9 07                        cmp     #$07                    ;check to see if we're up to a certain value yet
c3c6: 90 1d                        bcc     ExLSHand                ;if not, leave
c3c8: a2 04                        ldx     #$04                    ;start with the last enemy slot again
c3ca: b5 0f        ChkNoEn         lda     Enemy_Flag,x            ;check enemy buffer flag for non-active enemy slot
c3cc: f0 05                        beq     CreateL                 ;branch out of loop if found
c3ce: ca                           dex                             ;otherwise check next slot
c3cf: 10 f9                        bpl     ChkNoEn                 ;branch until all slots are checked
c3d1: 30 10                        bmi     RetEOfs                 ;if no empty slots were found, branch to leave

c3d3: a9 00        CreateL         lda     #$00                    ;initialize enemy state
c3d5: 95 1e                        sta     Enemy_State,x
c3d7: a9 11                        lda     #Lakitu                 ;create lakitu enemy object
c3d9: 95 16                        sta     Enemy_ID,x
c3db: 20 8a c3                     jsr     SetupLakitu             ;do a sub to set up lakitu
c3de: a9 20                        lda     #$20
c3e0: 20 d8 c5                     jsr     PutAtRightExtent        ;finish setting up lakitu
c3e3: a6 08        RetEOfs         ldx     ObjectOffset            ;get enemy object buffer offset again and leave
c3e5: 60           ExLSHand        rts

                   ; -----------------------------------------------------------------------------
c3e6: a5 ce        CreateSpiny     lda     Player_Y_Position       ;if player above a certain point, branch to leave
c3e8: c9 2c                        cmp     #$2c
c3ea: 90 f9                        bcc     ExLSHand
c3ec: b9 1e 00                     lda     Enemy_State,y           ;if lakitu is not in normal state, branch to leave
c3ef: d0 f4                        bne     ExLSHand
c3f1: b9 6e 00                     lda     Enemy_PageLoc,y         ;store horizontal coordinates (high and low) of lakitu
c3f4: 95 6e                        sta     Enemy_PageLoc,x         ;into the coordinates of the spiny we're going to create
c3f6: b9 87 00                     lda     Enemy_X_Position,y
c3f9: 95 87                        sta     Enemy_X_Position,x
c3fb: a9 01                        lda     #$01                    ;put spiny within vertical screen unit
c3fd: 95 b6                        sta     Enemy_Y_HighPos,x
c3ff: b9 cf 00                     lda     Enemy_Y_Position,y      ;put spiny eight pixels above where lakitu is
c402: 38                           sec
c403: e9 08                        sbc     #$08
c405: 95 cf                        sta     Enemy_Y_Position,x
c407: bd a7 07                     lda     PseudoRandomBitReg,x    ;get 2 LSB of LSFR and save to Y
c40a: 29 03                        and     #%00000011
c40c: a8                           tay
c40d: a2 02                        ldx     #$02
c40f: b9 98 c3     DifLoop         lda     PRDiffAdjustData,y      ;get three values and save them
c412: 95 01                        sta     $01,x                   ;to $01-$03
c414: c8                           iny
c415: c8                           iny                             ;increment Y four bytes for each value
c416: c8                           iny
c417: c8                           iny
c418: ca                           dex                             ;decrement X for each one
c419: 10 f4                        bpl     DifLoop                 ;loop until all three are written
c41b: a6 08                        ldx     ObjectOffset            ;get enemy object buffer offset
c41d: 20 6c cf                     jsr     PlayerLakituDiff        ;move enemy, change direction, get value - difference
c420: a4 57                        ldy     Player_X_Speed          ;check player's horizontal speed
c422: c0 08                        cpy     #$08
c424: b0 0e                        bcs     SetSpSpd                ;if moving faster than a certain amount, branch elsewhere
c426: a8                           tay                             ;otherwise save value in A to Y for now
c427: bd a8 07                     lda     PseudoRandomBitReg+1,x
c42a: 29 03                        and     #%00000011              ;get one of the LSFR parts and save the 2 LSB
c42c: f0 05                        beq     UsePosv                 ;branch if neither bits are set
c42e: 98                           tya
c42f: 49 ff                        eor     #%11111111              ;otherwise get two's compliment of Y
c431: a8                           tay
c432: c8                           iny
c433: 98           UsePosv         tya                             ;put value from A in Y back to A (they will be lost anyway)
c434: 20 46 c3     SetSpSpd        jsr     SmallBBox               ;set bounding box control, init attributes, lose contents of A
c437: a0 02                        ldy     #$02
c439: 95 58                        sta     Enemy_X_Speed,x         ;set horizontal speed to zero because previous contents
c43b: c9 00                        cmp     #$00                    ; of A were lost...branch here will never be taken for
c43d: 30 01                        bmi     SpinyRte                ; the same reason
c43f: 88                           dey
c440: 94 46        SpinyRte        sty     Enemy_MovingDir,x       ;set moving direction to the right
c442: a9 fd                        lda     #$fd
c444: 95 a0                        sta     BlooperMoveCounter,x    ;set vertical speed to move upwards
c446: a9 01                        lda     #$01
c448: 95 0f                        sta     Enemy_Flag,x            ;enable enemy object by setting flag
c44a: a9 05                        lda     #$05
c44c: 95 1e                        sta     Enemy_State,x           ;put spiny in egg state and leave
c44e: 60           ChpChpEx        rts

                   ; -----------------------------------------------------------------------------
                   FirebarSpinSpdData
c44f: 28 38 28 38+                 .bulk   $28,$38,$28,$38,$28
                   FirebarSpinDirData
c454: 00 00 10 10+                 .bulk   $00,$00,$10,$10,$00

c459: 20 75 c5     InitLongFirebar jsr     DuplicateEnemyObj       ;create enemy object for long firebar
                   InitShortFirebar
c45c: a9 00                        lda     #$00                    ;initialize low byte of spin state
c45e: 95 58                        sta     FirebarSpinState_Low,x
c460: b5 16                        lda     Enemy_ID,x              ;subtract $1b from enemy identifier
c462: 38                           sec                             ; to get proper offset for firebar data
c463: e9 1b                        sbc     #$1b
c465: a8                           tay
c466: b9 4f c4                     lda     FirebarSpinSpdData,y    ;get spinning speed of firebar
c469: 9d 88 03                     sta     FirebarSpinSpeed,x
c46c: b9 54 c4                     lda     FirebarSpinDirData,y    ;get spinning direction of firebar
c46f: 95 34                        sta     DestinationPageLoc,x
c471: b5 cf                        lda     Enemy_Y_Position,x
c473: 18                           clc                             ;add four pixels to vertical coordinate
c474: 69 04                        adc     #$04
c476: 95 cf                        sta     Enemy_Y_Position,x
c478: b5 87                        lda     Enemy_X_Position,x
c47a: 18                           clc                             ;add four pixels to horizontal coordinate
c47b: 69 04                        adc     #$04
c47d: 95 87                        sta     Enemy_X_Position,x
c47f: b5 6e                        lda     Enemy_PageLoc,x
c481: 69 00                        adc     #$00                    ;add carry to page location
c483: 95 6e                        sta     Enemy_PageLoc,x
c485: 4c d9 c7                     jmp     TallBBox2               ;set bounding box control (not used) and leave

                   ; -----------------------------------------------------------------------------
                   ; $00-$01 - used to hold pseudorandom bits
                   FlyCCXPositionData
c488: 80 30 40 80                  .bulk   $80,$30,$40,$80
c48c: 30 50 50 70                  .bulk   $30,$50,$50,$70
c490: 20 40 80 a0                  .bulk   $20,$40,$80,$a0
c494: 70 40 90 68                  .bulk   $70,$40,$90,$68
c498: 0e 05 06 0e  FlyCCXSpeedData .bulk   $0e,$05,$06,$0e
c49c: 1c 20 10 0c                  .bulk   $1c,$20,$10,$0c
c4a0: 1e 22 18 14                  .bulk   $1e,$22,$18,$14
c4a4: 10 60 20 48  FlyCCTimerData  .bulk   $10,$60,$20,$48

                   InitFlyingCheepCheep
c4a8: ad 8f 07                     lda     FrenzyEnemyTimer        ;if timer here not expired yet, branch to leave
c4ab: d0 a1                        bne     ChpChpEx
c4ad: 20 46 c3                     jsr     SmallBBox               ;jump to set bounding box size $09 and init other values
c4b0: bd a8 07                     lda     PseudoRandomBitReg+1,x
c4b3: 29 03                        and     #%00000011              ;set pseudorandom offset here
c4b5: a8                           tay
c4b6: b9 a4 c4                     lda     FlyCCTimerData,y        ;load timer with pseudorandom offset
c4b9: 8d 8f 07                     sta     FrenzyEnemyTimer
c4bc: a0 03                        ldy     #$03                    ;load Y with default value
c4be: ad cc 06                     lda     SecondaryHardMode
c4c1: f0 01                        beq     MaxCC                   ;if secondary hard mode flag not set, do not increment Y
c4c3: c8                           iny                             ;otherwise, increment Y to allow as many as four onscreen
c4c4: 84 00        MaxCC           sty     $00                     ;store whatever pseudorandom bits are in Y
c4c6: e4 00                        cpx     $00                     ;compare enemy object buffer offset with Y
c4c8: b0 84                        bcs     ChpChpEx                ;if X => Y, branch to leave
c4ca: bd a7 07                     lda     PseudoRandomBitReg,x
c4cd: 29 03                        and     #%00000011              ;get last two bits of LSFR, first part
c4cf: 85 00                        sta     $00                     ; and store in two places
c4d1: 85 01                        sta     $01
c4d3: a9 fb                        lda     #$fb                    ;set vertical speed for cheep-cheep
c4d5: 95 a0                        sta     Enemy_Y_Speed,x
c4d7: a9 00                        lda     #$00                    ;load default value
c4d9: a4 57                        ldy     Player_X_Speed          ;check player's horizontal speed
c4db: f0 07                        beq     GSeed                   ;if player not moving left or right, skip this part
c4dd: a9 04                        lda     #$04
c4df: c0 19                        cpy     #$19                    ;if moving to the right but not very quickly,
c4e1: 90 01                        bcc     GSeed                   ; do not change A
c4e3: 0a                           asl     A                       ;otherwise, multiply A by 2
c4e4: 48           GSeed           pha                             ;save to stack
c4e5: 18                           clc
c4e6: 65 00                        adc     $00                     ;add to last two bits of LSFR we saved earlier
c4e8: 85 00                        sta     $00                     ;save it there
c4ea: bd a8 07                     lda     PseudoRandomBitReg+1,x
c4ed: 29 03                        and     #%00000011              ;if neither of the last two bits of second LSFR set,
c4ef: f0 07                        beq     RSeed                   ; skip this part and save contents of $00
c4f1: bd a9 07                     lda     PseudoRandomBitReg+2,x
c4f4: 29 0f                        and     #%00001111              ;otherwise overwrite with lower nybble of
c4f6: 85 00                        sta     $00                     ; third LSFR part
c4f8: 68           RSeed           pla                             ;get value from stack we saved earlier
c4f9: 18                           clc
c4fa: 65 01                        adc     $01                     ;add to last two bits of LSFR we saved in other place
c4fc: a8                           tay                             ;use as pseudorandom offset here
c4fd: b9 98 c4                     lda     FlyCCXSpeedData,y       ;get horizontal speed using pseudorandom offset
c500: 95 58                        sta     Enemy_X_Speed,x
c502: a9 01                        lda     #$01                    ;set to move towards the right
c504: 95 46                        sta     Enemy_MovingDir,x
c506: a5 57                        lda     Player_X_Speed          ;if player moving left or right, branch ahead of this part
c508: d0 12                        bne     D2XPos1
c50a: a4 00                        ldy     $00                     ;get first LSFR or third LSFR lower nybble
c50c: 98                           tya                             ;and check for d1 set
c50d: 29 02                        and     #%00000010
c50f: f0 0b                        beq     D2XPos1                 ;if d1 not set, branch
c511: b5 58                        lda     Enemy_X_Speed,x
c513: 49 ff                        eor     #$ff                    ;if d1 set, change horizontal speed
c515: 18                           clc                             ; into two's compliment, thus moving in the opposite
c516: 69 01                        adc     #$01                    ; direction
c518: 95 58                        sta     Enemy_X_Speed,x
c51a: f6 46                        inc     Enemy_MovingDir,x       ;increment to move towards the left
c51c: 98           D2XPos1         tya                             ;get first LSFR or third LSFR lower nybble again
c51d: 29 02                        and     #%00000010
c51f: f0 0f                        beq     D2XPos2                 ;check for d1 set again, branch again if not set
c521: a5 86                        lda     Player_X_Position       ;get player's horizontal position
c523: 18                           clc
c524: 79 88 c4                     adc     FlyCCXPositionData,y    ;if d1 set, add value obtained from pseudorandom offset
c527: 95 87                        sta     Enemy_X_Position,x      ; and save as enemy's horizontal position
c529: a5 6d                        lda     Player_PageLoc          ;get player's page location
c52b: 69 00                        adc     #$00                    ;add carry and jump past this part
c52d: 4c 3c c5                     jmp     FinCCst

c530: a5 86        D2XPos2         lda     Player_X_Position       ;get player's horizontal position
c532: 38                           sec
c533: f9 88 c4                     sbc     FlyCCXPositionData,y    ;if d1 not set, subtract value obtained from pseudorandom
c536: 95 87                        sta     Enemy_X_Position,x      ; offset and save as enemy's horizontal position
c538: a5 6d                        lda     Player_PageLoc          ;get player's page location
c53a: e9 00                        sbc     #$00                    ;subtract borrow
c53c: 95 6e        FinCCst         sta     Enemy_PageLoc,x         ;save as enemy's page location
c53e: a9 01                        lda     #$01
c540: 95 0f                        sta     Enemy_Flag,x            ;set enemy's buffer flag
c542: 95 b6                        sta     Enemy_Y_HighPos,x       ;set enemy's high vertical byte
c544: a9 f8                        lda     #$f8
c546: 95 cf                        sta     Enemy_Y_Position,x      ;put enemy below the screen, and we are done
c548: 60                           rts

                   ; -----------------------------------------------------------------------------
c549: 20 75 c5     InitBowser      jsr     DuplicateEnemyObj       ;jump to create another bowser object
c54c: 8e 68 03                     stx     BowserFront_Offset      ;save offset of first here
c54f: a9 00                        lda     #$00
c551: 8d 63 03                     sta     BowserBodyControls      ;initialize bowser's body controls
c554: 8d 69 03                     sta     BridgeCollapseOffset    ;and bridge collapse offset
c557: b5 87                        lda     Enemy_X_Position,x
c559: 8d 66 03                     sta     BowserOrigXPos          ;store original horizontal position here
c55c: a9 df                        lda     #$df
c55e: 8d 90 07                     sta     BowserFireBreathTimer   ;store something here
c561: 95 46                        sta     Enemy_MovingDir,x       ;and in moving direction
c563: a9 20                        lda     #$20
c565: 8d 64 03                     sta     BowserFeetCounter       ;set bowser's feet timer and in enemy timer
c568: 9d 8a 07                     sta     EnemyFrameTimer,x
c56b: a9 05                        lda     #$05
c56d: 8d 83 04                     sta     BowserHitPoints         ;give bowser 5 hit points
c570: 4a                           lsr     A
c571: 8d 65 03                     sta     BowserMovementSpeed     ;set default movement speed here
c574: 60                           rts

                   ; -----------------------------------------------------------------------------
                   DuplicateEnemyObj
c575: a0 ff                        ldy     #$ff                    ;start at beginning of enemy slots
c577: c8           FSLoop          iny                             ;increment one slot
c578: b9 0f 00                     lda     Enemy_Flag,y            ;check enemy buffer flag for empty slot
c57b: d0 fa                        bne     FSLoop                  ;if set, branch and keep checking
c57d: 8c cf 06                     sty     DuplicateObj_Offset     ;otherwise set offset here
c580: 8a                           txa                             ;transfer original enemy buffer offset
c581: 09 80                        ora     #%10000000              ;store with d7 set as flag in new enemy
c583: 99 0f 00                     sta     Enemy_Flag,y            ; slot as well as enemy offset
c586: b5 6e                        lda     Enemy_PageLoc,x
c588: 99 6e 00                     sta     Enemy_PageLoc,y         ;copy page location and horizontal coordinates
c58b: b5 87                        lda     Enemy_X_Position,x      ; from original enemy to new enemy
c58d: 99 87 00                     sta     Enemy_X_Position,y
c590: a9 01                        lda     #$01
c592: 95 0f                        sta     Enemy_Flag,x            ;set flag as normal for original enemy
c594: 99 b6 00                     sta     Enemy_Y_HighPos,y       ;set high vertical byte for new enemy
c597: b5 cf                        lda     Enemy_Y_Position,x
c599: 99 cf 00                     sta     Enemy_Y_Position,y      ;copy vertical coordinate from original to new
c59c: 60           FlmEx           rts                             ;and then leave

                   ; -----------------------------------------------------------------------------
c59d: 90 80 70 90  FlameYPosData   .bulk   $90,$80,$70,$90
                   FlameYMFAdderData
c5a1: ff 01                        .bulk   $ff,$01

c5a3: ad 8f 07     InitBowserFlame lda     FrenzyEnemyTimer        ;if timer not expired yet, branch to leave
c5a6: d0 f4                        bne     FlmEx
c5a8: 9d 34 04                     sta     Enemy_Y_MoveForce,x     ;reset something here
c5ab: a5 fd                        lda     NoiseSoundQueue
c5ad: 09 02                        ora     #Sfx_BowserFlame        ;load bowser's flame sound into queue
c5af: 85 fd                        sta     NoiseSoundQueue
c5b1: ac 68 03                     ldy     BowserFront_Offset      ;get bowser's buffer offset
c5b4: b9 16 00                     lda     Enemy_ID,y              ;check for bowser
c5b7: c9 2d                        cmp     #Bowser
c5b9: f0 31                        beq     SpawnFromMouth          ;branch if found
c5bb: 20 d9 d1                     jsr     SetFlameTimer           ;get timer data based on flame counter
c5be: 18                           clc
c5bf: 69 20                        adc     #$20                    ;add 32 frames by default
c5c1: ac cc 06                     ldy     SecondaryHardMode
c5c4: f0 03                        beq     SetFrT                  ;if secondary mode flag not set, use as timer setting
c5c6: 38                           sec
c5c7: e9 10                        sbc     #$10                    ;otherwise subtract 16 frames for secondary hard mode
c5c9: 8d 8f 07     SetFrT          sta     FrenzyEnemyTimer        ;set timer accordingly
c5cc: bd a7 07                     lda     PseudoRandomBitReg,x
c5cf: 29 03                        and     #%00000011              ;get 2 LSB from first part of LSFR
c5d1: 9d 17 04                     sta     BowserFlamePRandomOfs,x ;set here
c5d4: a8                           tay                             ;use as offset
c5d5: b9 9d c5                     lda     FlameYPosData,y         ;load vertical position based on pseudorandom offset
                   PutAtRightExtent
c5d8: 95 cf                        sta     Enemy_Y_Position,x      ;set vertical position
c5da: ad 1d 07                     lda     ScreenRight_X_Pos
c5dd: 18                           clc
c5de: 69 20                        adc     #$20                    ;place enemy 32 pixels beyond right side of screen
c5e0: 95 87                        sta     Enemy_X_Position,x
c5e2: ad 1b 07                     lda     ScreenRight_PageLoc
c5e5: 69 00                        adc     #$00                    ;add carry
c5e7: 95 6e                        sta     Enemy_PageLoc,x
c5e9: 4c 1f c6                     jmp     FinishFlame             ;skip this part to finish setting values

c5ec: b9 87 00     SpawnFromMouth  lda     Enemy_X_Position,y      ;get bowser's horizontal position
c5ef: 38                           sec
c5f0: e9 0e                        sbc     #$0e                    ;subtract 14 pixels
c5f2: 95 87                        sta     Enemy_X_Position,x      ;save as flame's horizontal position
c5f4: b9 6e 00                     lda     Enemy_PageLoc,y
c5f7: 95 6e                        sta     Enemy_PageLoc,x         ;copy page location from bowser to flame
c5f9: b9 cf 00                     lda     Enemy_Y_Position,y
c5fc: 18                           clc                             ;add 8 pixels to bowser's vertical position
c5fd: 69 08                        adc     #$08
c5ff: 95 cf                        sta     Enemy_Y_Position,x      ;save as flame's vertical position
c601: bd a7 07                     lda     PseudoRandomBitReg,x
c604: 29 03                        and     #%00000011              ;get 2 LSB from first part of LSFR
c606: 9d 17 04                     sta     Enemy_YMF_Dummy,x       ;save here
c609: a8                           tay                             ;use as offset
c60a: b9 9d c5                     lda     FlameYPosData,y         ;get value here using bits as offset
c60d: a0 00                        ldy     #$00                    ;load default offset
c60f: d5 cf                        cmp     Enemy_Y_Position,x      ;compare value to flame's current vertical position
c611: 90 01                        bcc     SetMF                   ;if less, do not increment offset
c613: c8                           iny                             ;otherwise increment now
c614: b9 a1 c5     SetMF           lda     FlameYMFAdderData,y     ;get value here and save
c617: 9d 34 04                     sta     Enemy_Y_MoveForce,x     ; to vertical movement force
c61a: a9 00                        lda     #$00
c61c: 8d cb 06                     sta     EnemyFrenzyBuffer       ;clear enemy frenzy buffer
c61f: a9 08        FinishFlame     lda     #$08                    ;set $08 for bounding box control
c621: 9d 9a 04                     sta     Enemy_BoundBoxCtrl,x
c624: a9 01                        lda     #$01                    ;set high byte of vertical and
c626: 95 b6                        sta     Enemy_Y_HighPos,x       ; enemy buffer flag
c628: 95 0f                        sta     Enemy_Flag,x
c62a: 4a                           lsr     A
c62b: 9d 01 04                     sta     Enemy_X_MoveForce,x     ;initialize horizontal movement force, and
c62e: 95 1e                        sta     Enemy_State,x           ;enemy state
c630: 60                           rts

                   ; -----------------------------------------------------------------------------
                   FireworksXPosData
c631: 00 30 60 60+                 .bulk   $00,$30,$60,$60,$00,$20
                   FireworksYPosData
c637: 60 40 70 40+                 .bulk   $60,$40,$70,$40,$60,$30

c63d: ad 8f 07     InitFireworks   lda     FrenzyEnemyTimer        ;if timer not expired yet, branch to leave
c640: d0 47                        bne     ExitFWk
c642: a9 20                        lda     #$20                    ;otherwise reset timer
c644: 8d 8f 07                     sta     FrenzyEnemyTimer
c647: ce d7 06                     dec     FireworksCounter        ;decrement for each explosion
c64a: a0 06                        ldy     #$06                    ;start at last slot
c64c: 88           StarFChk        dey
c64d: b9 16 00                     lda     Enemy_ID,y              ;check for presence of star flag object
c650: c9 31                        cmp     #StarFlagObject         ;if there isn't a star flag object,
c652: d0 f8                        bne     StarFChk                ; routine goes into infinite loop = crash
c654: b9 87 00                     lda     Enemy_X_Position,y
c657: 38                           sec                             ;get horizontal coordinate of star flag object, then
c658: e9 30                        sbc     #$30                    ;subtract 48 pixels from it and save to
c65a: 48                           pha                             ; the stack
c65b: b9 6e 00                     lda     Enemy_PageLoc,y
c65e: e9 00                        sbc     #$00                    ;subtract the carry from the page location
c660: 85 00                        sta     $00                     ; of the star flag object
c662: ad d7 06                     lda     FireworksCounter        ;get fireworks counter
c665: 18                           clc
c666: 79 1e 00                     adc     Enemy_State,y           ;add state of star flag object (possibly not necessary)
c669: a8                           tay                             ;use as offset
c66a: 68                           pla                             ;get saved horizontal coordinate of star flag - 48 pixels
c66b: 18                           clc
c66c: 79 31 c6                     adc     FireworksXPosData,y     ;add number based on offset of fireworks counter
c66f: 95 87                        sta     Enemy_X_Position,x      ;store as the fireworks object horizontal coordinate
c671: a5 00                        lda     $00
c673: 69 00                        adc     #$00                    ;add carry and store as page location for
c675: 95 6e                        sta     Enemy_PageLoc,x         ; the fireworks object
c677: b9 37 c6                     lda     FireworksYPosData,y     ;get vertical position using same offset
c67a: 95 cf                        sta     Enemy_Y_Position,x      ;and store as vertical coordinate for fireworks object
c67c: a9 01                        lda     #$01
c67e: 95 b6                        sta     Enemy_Y_HighPos,x       ;store in vertical high byte
c680: 95 0f                        sta     Enemy_Flag,x            ;and activate enemy buffer flag
c682: 4a                           lsr     A
c683: 95 58                        sta     ExplosionGfxCounter,x   ;initialize explosion counter
c685: a9 08                        lda     #$08
c687: 95 a0                        sta     ExplosionTimerCounter,x ;set explosion timing counter
c689: 60           ExitFWk         rts

                   ; -----------------------------------------------------------------------------
c68a: 01           Bitmasks        .dd1    %00000001
c68b: 02                           .dd1    %00000010
c68c: 04                           .dd1    %00000100
c68d: 08                           .dd1    %00001000
c68e: 10                           .dd1    %00010000
c68f: 20                           .dd1    %00100000
c690: 40                           .dd1    %01000000
c691: 80                           .dd1    %10000000
c692: 40 30 90 50+ Enemy17YPosData .bulk   $40,$30,$90,$50,$20,$60,$a0,$70
c69a: 0a 0b        SwimCC_IDData   .bulk   $0a,$0b

                   BulletBillCheepCheep
c69c: ad 8f 07                     lda     FrenzyEnemyTimer        ;if timer not expired yet, branch to leave
c69f: d0 6f                        bne     ExF17
c6a1: ad 4e 07                     lda     AreaType                ;are we in a water-type level?
c6a4: d0 57                        bne     DoBulletBills           ;if not, branch elsewhere
c6a6: e0 03                        cpx     #$03                    ;are we past third enemy slot?
c6a8: b0 66                        bcs     ExF17                   ;if so, branch to leave
c6aa: a0 00                        ldy     #$00                    ;load default offset
c6ac: bd a7 07                     lda     PseudoRandomBitReg,x
c6af: c9 aa                        cmp     #$aa                    ;check first part of LSFR against preset value
c6b1: 90 01                        bcc     ChkW2                   ;if less than preset, do not increment offset
c6b3: c8                           iny                             ;otherwise increment
c6b4: ad 5f 07     ChkW2           lda     WorldNumber             ;check world number
c6b7: c9 01                        cmp     #World2
c6b9: f0 01                        beq     Get17ID                 ;if we're on world 2, do not increment offset
c6bb: c8                           iny                             ;otherwise increment
c6bc: 98           Get17ID         tya
c6bd: 29 01                        and     #%00000001              ;mask out all but last bit of offset
c6bf: a8                           tay
c6c0: b9 9a c6                     lda     SwimCC_IDData,y         ;load identifier for cheep-cheeps
c6c3: 95 16        Set17ID         sta     Enemy_ID,x              ;store whatever's in A as enemy identifier
c6c5: ad dd 06                     lda     BitMFilter
c6c8: c9 ff                        cmp     #$ff                    ;if not all bits set, skip init part and compare bits
c6ca: d0 05                        bne     GetRBit
c6cc: a9 00                        lda     #$00                    ;initialize vertical position filter
c6ce: 8d dd 06                     sta     BitMFilter
c6d1: bd a7 07     GetRBit         lda     PseudoRandomBitReg,x    ;get first part of LSFR
c6d4: 29 07                        and     #%00000111              ;mask out all but 3 LSB
c6d6: a8           ChkRBit         tay                             ;use as offset
c6d7: b9 8a c6                     lda     Bitmasks,y              ;load bitmask
c6da: 2c dd 06                     bit     BitMFilter              ;perform AND on filter without changing it
c6dd: f0 07                        beq     AddFBit
c6df: c8                           iny                             ;increment offset
c6e0: 98                           tya
c6e1: 29 07                        and     #%00000111              ;mask out all but 3 LSB thus keeping it 0-7
c6e3: 4c d6 c6                     jmp     ChkRBit                 ;do another check

c6e6: 0d dd 06     AddFBit         ora     BitMFilter              ;add bit to already set bits in filter
c6e9: 8d dd 06                     sta     BitMFilter              ;and store
c6ec: b9 92 c6                     lda     Enemy17YPosData,y       ;load vertical position using offset
c6ef: 20 d8 c5                     jsr     PutAtRightExtent        ;set vertical position and other values
c6f2: 9d 17 04                     sta     Enemy_YMF_Dummy,x       ;initialize dummy variable
c6f5: a9 20                        lda     #$20                    ;set timer
c6f7: 8d 8f 07                     sta     FrenzyEnemyTimer
c6fa: 4c 6c c2                     jmp     CheckpointEnemyID       ;process our new enemy object

c6fd: a0 ff        DoBulletBills   ldy     #$ff                    ;start at beginning of enemy slots
c6ff: c8           BB_SLoop        iny                             ;move onto the next slot
c700: c0 05                        cpy     #$05                    ;branch to play sound if we've done all slots
c702: b0 0d                        bcs     FireBulletBill
c704: b9 0f 00                     lda     Enemy_Flag,y            ;if enemy buffer flag not set,
c707: f0 f6                        beq     BB_SLoop                ; loop back and check another slot
c709: b9 16 00                     lda     Enemy_ID,y
c70c: c9 08                        cmp     #BulletBill_FrenzyVar   ;check enemy identifier for
c70e: d0 ef                        bne     BB_SLoop                ; bullet bill object (frenzy variant)
c710: 60           ExF17           rts                             ;if found, leave

c711: a5 fe        FireBulletBill  lda     Square2SoundQueue
c713: 09 08                        ora     #Sfx_Blast              ;play fireworks/gunfire sound
c715: 85 fe                        sta     Square2SoundQueue
c717: a9 08                        lda     #BulletBill_FrenzyVar   ;load identifier for bullet bill object
c719: d0 a8                        bne     Set17ID                 ;unconditional branch

                   ; -----------------------------------------------------------------------------
                   ; $00 - used to store Y position of group enemies
                   ; $01 - used to store enemy ID
                   ; $02 - used to store page location of right side of screen
                   ; $03 - used to store X position of right side of screen
                   HandleGroupEnemies
c71b: a0 00                        ldy     #$00                    ;load value for green koopa troopa
c71d: 38                           sec
c71e: e9 37                        sbc     #$37                    ;subtract $37 from second byte read
c720: 48                           pha                             ;save result in stack for now
c721: c9 04                        cmp     #$04                    ;was byte in $3b-$3e range?
c723: b0 0b                        bcs     SnglID                  ;if so, branch
c725: 48                           pha                             ;save another copy to stack
c726: a0 06                        ldy     #Goomba                 ;load value for goomba enemy
c728: ad 6a 07                     lda     PrimaryHardMode         ;if primary hard mode flag not set,
c72b: f0 02                        beq     PullID                  ; branch, otherwise change to value
c72d: a0 02                        ldy     #BuzzyBeetle            ; for buzzy beetle
c72f: 68           PullID          pla                             ;get second copy from stack
c730: 84 01        SnglID          sty     $01                     ;save enemy id here
c732: a0 b0                        ldy     #$b0                    ;load default y coordinate
c734: 29 02                        and     #$02                    ;check to see if d1 was set
c736: f0 02                        beq     SetYGp                  ;if so, move y coordinate up,
c738: a0 70                        ldy     #$70                    ; otherwise branch and use default
c73a: 84 00        SetYGp          sty     $00                     ;save y coordinate here
c73c: ad 1b 07                     lda     ScreenRight_PageLoc     ;get page number of right edge of screen
c73f: 85 02                        sta     $02                     ;save here
c741: ad 1d 07                     lda     ScreenRight_X_Pos       ;get pixel coordinate of right edge
c744: 85 03                        sta     $03                     ;save here
c746: a0 02                        ldy     #$02                    ;load two enemies by default
c748: 68                           pla                             ;get first copy from stack
c749: 4a                           lsr     A                       ;check to see if d0 was set
c74a: 90 01                        bcc     CntGrp                  ;if not, use default value
c74c: c8                           iny                             ;otherwise increment to three enemies
c74d: 8c d3 06     CntGrp          sty     NumberofGroupEnemies    ;save number of enemies here
c750: a2 ff        GrLoop          ldx     #$ff                    ;start at beginning of enemy buffers
c752: e8           GSltLp          inx                             ;increment and branch if past
c753: e0 05                        cpx     #$05                    ;end of buffers
c755: b0 2d                        bcs     NextED
c757: b5 0f                        lda     Enemy_Flag,x            ;check to see if enemy is already
c759: d0 f7                        bne     GSltLp                  ; stored in buffer, and branch if so
c75b: a5 01                        lda     $01
c75d: 95 16                        sta     Enemy_ID,x              ;store enemy object identifier
c75f: a5 02                        lda     $02
c761: 95 6e                        sta     Enemy_PageLoc,x         ;store page location for enemy object
c763: a5 03                        lda     $03
c765: 95 87                        sta     Enemy_X_Position,x      ;store x coordinate for enemy object
c767: 18                           clc
c768: 69 18                        adc     #$18                    ;add 24 pixels for next enemy
c76a: 85 03                        sta     $03
c76c: a5 02                        lda     $02                     ;add carry to page location for
c76e: 69 00                        adc     #$00                    ; next enemy
c770: 85 02                        sta     $02
c772: a5 00                        lda     $00                     ;store y coordinate for enemy object
c774: 95 cf                        sta     Enemy_Y_Position,x
c776: a9 01                        lda     #$01                    ;activate flag for buffer, and
c778: 95 b6                        sta     Enemy_Y_HighPos,x       ; put enemy within the screen vertically
c77a: 95 0f                        sta     Enemy_Flag,x
c77c: 20 6c c2                     jsr     CheckpointEnemyID       ;process each enemy object separately
c77f: ce d3 06                     dec     NumberofGroupEnemies    ;do this until we run out of enemy objects
c782: d0 cc                        bne     GrLoop
c784: 4c 5e c2     NextED          jmp     Inc2B                   ;jump to increment data offset and leave

                   ; -----------------------------------------------------------------------------
                   InitPiranhaPlant
c787: a9 01                        lda     #$01                    ;set initial speed
c789: 95 58                        sta     PiranhaPlant_Y_Speed,x
c78b: 4a                           lsr     A
c78c: 95 1e                        sta     Enemy_State,x           ;initialize enemy state and what would normally
c78e: 95 a0                        sta     PiranhaPlant_MoveFlag,x ; be used as vertical speed, but not in this case
c790: b5 cf                        lda     Enemy_Y_Position,x
c792: 9d 34 04                     sta     PiranhaPlantDownYPos,x  ;save original vertical coordinate here
c795: 38                           sec
c796: e9 18                        sbc     #$18
c798: 9d 17 04                     sta     PiranhaPlantUpYPos,x    ;save original vertical coordinate - 24 pixels here
c79b: a9 09                        lda     #$09
c79d: 4c db c7                     jmp     SetBBox2                ;set specific value for bounding box control

                   ; -----------------------------------------------------------------------------
c7a0: b5 16        InitEnemyFrenzy lda     Enemy_ID,x              ;load enemy identifier
c7a2: 8d cb 06                     sta     EnemyFrenzyBuffer       ;save in enemy frenzy buffer
c7a5: 38                           sec
c7a6: e9 12                        sbc     #$12                    ;subtract 12 and use as offset for jump engine
c7a8: 20 04 8e                     jsr     JumpEngine

c7ab: a4 c3                        .dd2    LakituAndSpinyHandler
c7ad: b7 c7                        .dd2    NoFrenzyCode
c7af: a8 c4                        .dd2    InitFlyingCheepCheep
c7b1: a3 c5                        .dd2    InitBowserFlame
c7b3: 3d c6                        .dd2    InitFireworks
c7b5: 9c c6                        .dd2    BulletBillCheepCheep

                   ; -----------------------------------------------------------------------------
c7b7: 60           NoFrenzyCode    rts

                   ; -----------------------------------------------------------------------------
c7b8: a0 05        EndFrenzy       ldy     #$05                    ;start at last slot
c7ba: b9 16 00     LakituChk       lda     Enemy_ID,y              ;check enemy identifiers
c7bd: c9 11                        cmp     #Lakitu                 ; for lakitu
c7bf: d0 05                        bne     NextFSlot
c7c1: a9 01                        lda     #$01                    ;if found, set state
c7c3: 99 1e 00                     sta     Enemy_State,y
c7c6: 88           NextFSlot       dey                             ;move onto the next slot
c7c7: 10 f1                        bpl     LakituChk               ;do this until all slots are checked
c7c9: a9 00                        lda     #$00
c7cb: 8d cb 06                     sta     EnemyFrenzyBuffer       ;empty enemy frenzy buffer
c7ce: 95 0f                        sta     Enemy_Flag,x            ;disable enemy buffer flag for this object
c7d0: 60                           rts

                   ; -----------------------------------------------------------------------------
                   InitJumpGPTroopa
c7d1: a9 02                        lda     #$02                    ;set for movement to the left
c7d3: 95 46                        sta     Enemy_MovingDir,x
c7d5: a9 f8                        lda     #$f8                    ;set horizontal speed
c7d7: 95 58                        sta     Enemy_X_Speed,x
c7d9: a9 03        TallBBox2       lda     #$03                    ;set specific value for bounding box control
c7db: 9d 9a 04     SetBBox2        sta     Enemy_BoundBoxCtrl,x    ;set bounding box control then leave
c7de: 60                           rts

                   ; -----------------------------------------------------------------------------
c7df: d6 cf        InitBalPlatform dec     Enemy_Y_Position,x      ;raise vertical position by two pixels
c7e1: d6 cf                        dec     Enemy_Y_Position,x
c7e3: ac cc 06                     ldy     SecondaryHardMode       ;if secondary hard mode flag not set,
c7e6: d0 05                        bne     AlignP                  ;branch ahead
c7e8: a0 02                        ldy     #$02                    ;otherwise set value here
c7ea: 20 71 c8                     jsr     PosPlatform             ;do a sub to add or subtract pixels
c7ed: a0 ff        AlignP          ldy     #$ff                    ;set default value here for now
c7ef: ad a0 03                     lda     BalPlatformAlignment    ;get current balance platform alignment
c7f2: 95 1e                        sta     Enemy_State,x           ;set platform alignment to object state here
c7f4: 10 02                        bpl     SetBPA                  ;if old alignment $ff, put $ff as alignment for negative
c7f6: 8a                           txa                             ;if old contents already $ff, put
c7f7: a8                           tay                             ;object offset as alignment to make next positive
c7f8: 8c a0 03     SetBPA          sty     BalPlatformAlignment    ;store whatever value's in Y here
c7fb: a9 00                        lda     #$00
c7fd: 95 46                        sta     Enemy_MovingDir,x       ;init moving direction
c7ff: a8                           tay                             ;init Y
c800: 20 71 c8                     jsr     PosPlatform             ;do a sub to add 8 pixels, then run shared code here
                   ; 
                   InitDropPlatform
c803: a9 ff                        lda     #$ff
c805: 9d a2 03                     sta     PlatformCollisionFlag,x ;set some value here
c808: 4c 28 c8                     jmp     CommonPlatCode          ;then jump ahead to execute more code

                   ; -----------------------------------------------------------------------------
                   InitHoriPlatform
c80b: a9 00                        lda     #$00
c80d: 95 58                        sta     XMoveSecondaryCounter,x ;init one of the moving counters
c80f: 4c 28 c8                     jmp     CommonPlatCode          ;jump ahead to execute more code

                   ; -----------------------------------------------------------------------------
                   InitVertPlatform
c812: a0 40                        ldy     #$40                    ;set default value here
c814: b5 cf                        lda     Enemy_Y_Position,x      ;check vertical position
c816: 10 07                        bpl     SetYO                   ;if above a certain point, skip this part
c818: 49 ff                        eor     #$ff
c81a: 18                           clc                             ;otherwise get two's compliment
c81b: 69 01                        adc     #$01
c81d: a0 c0                        ldy     #$c0                    ;get alternate value to add to vertical position
c81f: 9d 01 04     SetYO           sta     YPlatformTopYPos,x      ;save as top vertical position
c822: 98                           tya
c823: 18                           clc                             ;load value from earlier, add number of pixels 
c824: 75 cf                        adc     Enemy_Y_Position,x      ; to vertical position
c826: 95 58                        sta     YPlatformCenterYPos,x   ;save result as central vertical position
                   ; 
c828: 20 63 c3     CommonPlatCode  jsr     InitVStf                ;do a sub to init certain other values 
c82b: a9 05        SPBBox          lda     #$05                    ;set default bounding box size control
c82d: ac 4e 07                     ldy     AreaType
c830: c0 03                        cpy     #$03                    ;check for castle-type level
c832: f0 07                        beq     CasPBB                  ;use default value if found
c834: ac cc 06                     ldy     SecondaryHardMode       ;otherwise check for secondary hard mode flag
c837: d0 02                        bne     CasPBB                  ;if set, use default value
c839: a9 06                        lda     #$06                    ;use alternate value if not castle or secondary not set
c83b: 9d 9a 04     CasPBB          sta     Enemy_BoundBoxCtrl,x    ;set bounding box size control here and leave
c83e: 60                           rts

                   ; -----------------------------------------------------------------------------
c83f: 20 4b c8     LargeLiftUp     jsr     PlatLiftUp              ;execute code for platforms going up
c842: 4c 48 c8                     jmp     LargeLiftBBox           ;overwrite bounding box for large platforms

c845: 20 57 c8     LargeLiftDown   jsr     PlatLiftDown            ;execute code for platforms going down
c848: 4c 2b c8     LargeLiftBBox   jmp     SPBBox                  ;jump to overwrite bounding box size control

                   ; -----------------------------------------------------------------------------
c84b: a9 10        PlatLiftUp      lda     #$10                    ;set movement amount here
c84d: 9d 34 04                     sta     Enemy_Y_MoveForce,x
c850: a9 ff                        lda     #$ff                    ;set moving speed for platforms going up
c852: 95 a0                        sta     BlooperMoveCounter,x
c854: 4c 60 c8                     jmp     CommonSmallLift         ;skip ahead to part we should be executing

                   ; -----------------------------------------------------------------------------
c857: a9 f0        PlatLiftDown    lda     #$f0                    ;set movement amount here
c859: 9d 34 04                     sta     Enemy_Y_MoveForce,x
c85c: a9 00                        lda     #$00                    ;set moving speed for platforms going down
c85e: 95 a0                        sta     Enemy_Y_Speed,x
                   ; 
c860: a0 01        CommonSmallLift ldy     #$01
c862: 20 71 c8                     jsr     PosPlatform             ;do a sub to add 12 pixels due to preset value 
c865: a9 04                        lda     #$04
c867: 9d 9a 04                     sta     Enemy_BoundBoxCtrl,x    ;set bounding box control for small platforms
c86a: 60                           rts

                   ; -----------------------------------------------------------------------------
c86b: 08 0c f8     PlatPosDataLow  .bulk   $08,$0c,$f8
c86e: 00 00 ff     PlatPosDataHigh .bulk   $00,$00,$ff

c871: b5 87        PosPlatform     lda     Enemy_X_Position,x      ;get horizontal coordinate
c873: 18                           clc
c874: 79 6b c8                     adc     PlatPosDataLow,y        ;add or subtract pixels depending on offset
c877: 95 87                        sta     Enemy_X_Position,x      ;store as new horizontal coordinate
c879: b5 6e                        lda     Enemy_PageLoc,x
c87b: 79 6e c8                     adc     PlatPosDataHigh,y       ;add or subtract page location depending on offset
c87e: 95 6e                        sta     Enemy_PageLoc,x         ;store as new page location
c880: 60                           rts                             ;and go back

                   ; -----------------------------------------------------------------------------
                   EndOFEnemyInitCode
c881: 60                           rts

                   ; -----------------------------------------------------------------------------
                   RunEnemyObjectsCore
c882: a6 08                        ldx     ObjectOffset            ;get offset for enemy object buffer
c884: a9 00                        lda     #$00                    ;load value 0 for jump engine by default
c886: b4 16                        ldy     Enemy_ID,x
c888: c0 15                        cpy     #$15                    ;if enemy object < $15, use default value
c88a: 90 03                        bcc     JmpEO
c88c: 98                           tya                             ;otherwise subtract $14 from the value and use
c88d: e9 14                        sbc     #$14                    ; as value for jump engine
c88f: 20 04 8e     JmpEO           jsr     JumpEngine

c892: e0 c8                        .dd2    RunNormalEnemies        ;for objects $00-$14
c894: 35 c9                        .dd2    RunBowserFlame          ;for objects $15-$1f
c896: 95 d2                        .dd2    RunFireworks
c898: d6 c8                        .dd2    NoRunCode
c89a: d6 c8                        .dd2    NoRunCode
c89c: d6 c8                        .dd2    NoRunCode
c89e: d6 c8                        .dd2    NoRunCode
c8a0: 47 c9                        .dd2    RunFirebarObj
c8a2: 47 c9                        .dd2    RunFirebarObj
c8a4: 47 c9                        .dd2    RunFirebarObj
c8a6: 47 c9                        .dd2    RunFirebarObj
c8a8: 47 c9                        .dd2    RunFirebarObj
c8aa: 47 c9                        .dd2    RunFirebarObj           ;for objects $20-$2f
c8ac: 47 c9                        .dd2    RunFirebarObj
c8ae: 47 c9                        .dd2    RunFirebarObj
c8b0: d6 c8                        .dd2    NoRunCode
c8b2: 65 c9                        .dd2    RunLargePlatform
c8b4: 65 c9                        .dd2    RunLargePlatform
c8b6: 65 c9                        .dd2    RunLargePlatform
c8b8: 65 c9                        .dd2    RunLargePlatform
c8ba: 65 c9                        .dd2    RunLargePlatform
c8bc: 65 c9                        .dd2    RunLargePlatform
c8be: 65 c9                        .dd2    RunLargePlatform
c8c0: 4d c9                        .dd2    RunSmallPlatform
c8c2: 4d c9                        .dd2    RunSmallPlatform
c8c4: 65 d0                        .dd2    RunBowser
c8c6: 85 bc                        .dd2    PowerUpObjHandler
c8c8: 4b b9                        .dd2    VineObjectHandler
c8ca: d6 c8                        .dd2    NoRunCode               ;for objects $30-$35
c8cc: d9 d2                        .dd2    RunStarFlagObj
c8ce: ba b8                        .dd2    JumpspringHandler
c8d0: d6 c8                        .dd2    NoRunCode
c8d2: a4 b7                        .dd2    WarpZoneObject
c8d4: d7 c8                        .dd2    RunRetainerObj

                   ; -----------------------------------------------------------------------------
c8d6: 60           NoRunCode       rts

                   ; -----------------------------------------------------------------------------
c8d7: 20 af f1     RunRetainerObj  jsr     GetEnemyOffscreenBits
c8da: 20 52 f1                     jsr     RelativeEnemyPosition
c8dd: 4c 7d e8                     jmp     EnemyGfxHandler

                   ; -----------------------------------------------------------------------------
                   RunNormalEnemies
c8e0: a9 00                        lda     #$00                    ;init sprite attributes
c8e2: 9d c5 03                     sta     Enemy_SprAttrib,x
c8e5: 20 af f1                     jsr     GetEnemyOffscreenBits
c8e8: 20 52 f1                     jsr     RelativeEnemyPosition
c8eb: 20 7d e8                     jsr     EnemyGfxHandler
c8ee: 20 43 e2                     jsr     GetEnemyBoundBox
c8f1: 20 c1 df                     jsr     EnemyToBGCollisionDet
c8f4: 20 33 da                     jsr     EnemiesCollision
c8f7: 20 53 d8                     jsr     PlayerEnemyCollision
c8fa: ac 47 07                     ldy     TimerControl            ;if master timer control set, skip to last routine
c8fd: d0 03                        bne     SkipMove
c8ff: 20 05 c9                     jsr     EnemyMovementSubs
c902: 4c 7a d6     SkipMove        jmp     OffscreenBoundsCheck

                   ; -----------------------------------------------------------------------------
                   EnemyMovementSubs
c905: b5 16                        lda     Enemy_ID,x
c907: 20 04 8e                     jsr     JumpEngine

c90a: 77 ca                        .dd2    MoveNormalEnemy         ;only objects $00-$14 use this table
c90c: 77 ca                        .dd2    MoveNormalEnemy
c90e: 77 ca                        .dd2    MoveNormalEnemy
c910: 77 ca                        .dd2    MoveNormalEnemy
c912: 77 ca                        .dd2    MoveNormalEnemy
c914: d8 c9                        .dd2    ProcHammerBro
c916: 77 ca                        .dd2    MoveNormalEnemy
c918: 89 cb                        .dd2    MoveBloober
c91a: 36 cc                        .dd2    MoveBulletBill
c91c: 34 c9                        .dd2    NoMoveCode
c91e: 4a cc                        .dd2    MoveSwimmingCheepCheep
c920: 4a cc                        .dd2    MoveSwimmingCheepCheep
c922: b0 c9                        .dd2    MovePodoboo
c924: b0 d3                        .dd2    MovePiranhaPlant
c926: f9 ca                        .dd2    MoveJumpingEnemy
c928: ff ca                        .dd2    ProcMoveRedPTroopa
c92a: 25 cb                        .dd2    MoveFlyGreenPTroopa
c92c: 28 cf                        .dd2    MoveLakitu
c92e: 77 ca                        .dd2    MoveNormalEnemy
c930: 34 c9                        .dd2    NoMoveCode              ;dummy
c932: df ce                        .dd2    MoveFlyingCheepCheep

                   ; -----------------------------------------------------------------------------
c934: 60           NoMoveCode      rts

                   ; -----------------------------------------------------------------------------
c935: 20 eb d1     RunBowserFlame  jsr     ProcBowserFlame
c938: 20 af f1                     jsr     GetEnemyOffscreenBits
c93b: 20 52 f1                     jsr     RelativeEnemyPosition
c93e: 20 43 e2                     jsr     GetEnemyBoundBox
c941: 20 53 d8                     jsr     PlayerEnemyCollision
c944: 4c 7a d6                     jmp     OffscreenBoundsCheck

                   ; -----------------------------------------------------------------------------
c947: 20 3c cd     RunFirebarObj   jsr     ProcFirebar
c94a: 4c 7a d6                     jmp     OffscreenBoundsCheck

                   ; -----------------------------------------------------------------------------
                   RunSmallPlatform
c94d: 20 af f1                     jsr     GetEnemyOffscreenBits
c950: 20 52 f1                     jsr     RelativeEnemyPosition
c953: 20 4c e2                     jsr     SmallPlatformBoundBox
c956: 20 7b db                     jsr     SmallPlatformCollision
c959: 20 52 f1                     jsr     RelativeEnemyPosition
c95c: 20 66 ed                     jsr     DrawSmallPlatform
c95f: 20 55 d6                     jsr     MoveSmallPlatform
c962: 4c 7a d6                     jmp     OffscreenBoundsCheck

                   ; -----------------------------------------------------------------------------
                   RunLargePlatform
c965: 20 af f1                     jsr     GetEnemyOffscreenBits
c968: 20 52 f1                     jsr     RelativeEnemyPosition
c96b: 20 73 e2                     jsr     LargePlatformBoundBox
c96e: 20 45 db                     jsr     LargePlatformCollision
c971: ad 47 07                     lda     TimerControl            ;if master timer control set,
c974: d0 03                        bne     SkipPT                  ; skip subroutine tree
c976: 20 82 c9                     jsr     LargePlatformSubroutines
c979: 20 52 f1     SkipPT          jsr     RelativeEnemyPosition
c97c: 20 c8 e5                     jsr     DrawLargePlatform
c97f: 4c 7a d6                     jmp     OffscreenBoundsCheck

                   ; -----------------------------------------------------------------------------
                   LargePlatformSubroutines
c982: b5 16                        lda     Enemy_ID,x              ;subtract $24 to get proper offset for jump table
c984: 38                           sec
c985: e9 24                        sbc     #$24
c987: 20 04 8e                     jsr     JumpEngine

c98a: 32 d4                        .dd2    BalancePlatform         ;table used by objects $24-$2a
c98c: d3 d5                        .dd2    YMovingPlatform
c98e: 4f d6                        .dd2    MoveLargeLiftPlat
c990: 4f d6                        .dd2    MoveLargeLiftPlat
c992: 07 d6                        .dd2    XMovingPlatform
c994: 31 d6                        .dd2    DropPlatform
c996: 3d d6                        .dd2    RightPlatform

                   ; -----------------------------------------------------------------------------
                   EraseEnemyObject
c998: a9 00                        lda     #$00                    ;clear all enemy object variables
c99a: 95 0f                        sta     Enemy_Flag,x
c99c: 95 16                        sta     Enemy_ID,x
c99e: 95 1e                        sta     Enemy_State,x
c9a0: 9d 10 01                     sta     FloateyNum_Control,x
c9a3: 9d 96 07                     sta     EnemyIntervalTimer,x
c9a6: 9d 25 01                     sta     ShellChainCounter,x
c9a9: 9d c5 03                     sta     Enemy_SprAttrib,x
c9ac: 9d 8a 07                     sta     EnemyFrameTimer,x
c9af: 60                           rts

                   ; -----------------------------------------------------------------------------
c9b0: bd 96 07     MovePodoboo     lda     EnemyIntervalTimer,x    ;check enemy timer
c9b3: d0 16                        bne     PdbM                    ;branch to move enemy if not expired
c9b5: 20 f7 c2                     jsr     InitPodoboo             ;otherwise set up podoboo again
c9b8: bd a8 07                     lda     PseudoRandomBitReg+1,x  ;get part of LSFR
c9bb: 09 80                        ora     #%10000000              ;set d7
c9bd: 9d 34 04                     sta     Enemy_Y_MoveForce,x     ;store as movement force
c9c0: 29 0f                        and     #%00001111              ;mask out high nybble
c9c2: 09 06                        ora     #$06                    ;set for at least six intervals
c9c4: 9d 96 07                     sta     EnemyIntervalTimer,x    ;store as new enemy timer
c9c7: a9 f9                        lda     #$f9
c9c9: 95 a0                        sta     BlooperMoveCounter,x    ;set vertical speed to move podoboo upwards
c9cb: 4c 92 bf     PdbM            jmp     MoveJ_EnemyVertically   ;branch to impose gravity on podoboo

                   ; -----------------------------------------------------------------------------
                   ; $00 - used in HammerBroJumpCode as bitmask
                   HammerThrowTmrData
c9ce: 30 1c                        .bulk   $30,$1c
c9d0: 00 e8 00 18  XSpeedAdderData .bulk   $00,$e8,$00,$18
c9d4: 08 f8 0c f4  RevivedXSpeed   .bulk   $08,$f8,$0c,$f4

c9d8: b5 1e        ProcHammerBro   lda     Enemy_State,x           ;check hammer bro's enemy state for d5 set
c9da: 29 20                        and     #%00100000
c9dc: f0 03                        beq     ChkJH                   ;if not set, go ahead with code
c9de: 4c e5 ca                     jmp     MoveDefeatedEnemy       ;otherwise jump to something else

c9e1: b5 3c        ChkJH           lda     HammerBroJumpTimer,x    ;check jump timer
c9e3: f0 2d                        beq     HammerBroJumpCode       ;if expired, branch to jump
c9e5: d6 3c                        dec     HammerBroJumpTimer,x    ;otherwise decrement jump timer
c9e7: ad d1 03                     lda     Enemy_OffscreenBits
c9ea: 29 0c                        and     #%00001100              ;check offscreen bits
c9ec: d0 6a                        bne     MoveHammerBroXDir       ;if hammer bro a little offscreen, skip to movement code
c9ee: bd a2 03                     lda     HammerThrowingTimer,x   ;check hammer throwing timer
c9f1: d0 17                        bne     DecHT                   ;if not expired, skip ahead, do not throw hammer
c9f3: ac cc 06                     ldy     SecondaryHardMode       ;otherwise get secondary hard mode flag
c9f6: b9 ce c9                     lda     HammerThrowTmrData,y    ;get timer data using flag as offset
c9f9: 9d a2 03                     sta     HammerThrowingTimer,x   ;set as new timer
c9fc: 20 94 ba                     jsr     SpawnHammerObj          ;do a sub here to spawn hammer object
c9ff: 90 09                        bcc     DecHT                   ;if carry clear, hammer not spawned, skip to decrement timer
ca01: b5 1e                        lda     Enemy_State,x
ca03: 09 08                        ora     #%00001000              ;set d3 in enemy state for hammer throw
ca05: 95 1e                        sta     Enemy_State,x
ca07: 4c 58 ca                     jmp     MoveHammerBroXDir       ;jump to move hammer bro

ca0a: de a2 03     DecHT           dec     HammerThrowingTimer,x   ;decrement timer
ca0d: 4c 58 ca                     jmp     MoveHammerBroXDir       ;jump to move hammer bro

                   HammerBroJumpLData
ca10: 20 37                        .bulk   $20,$37

                   HammerBroJumpCode
ca12: b5 1e                        lda     Enemy_State,x           ;get hammer bro's enemy state
ca14: 29 07                        and     #%00000111              ;mask out all but 3 LSB
ca16: c9 01                        cmp     #$01                    ;check for d0 set (for jumping)
ca18: f0 3e                        beq     MoveHammerBroXDir       ;if set, branch ahead to moving code
ca1a: a9 00                        lda     #$00                    ;load default value here
ca1c: 85 00                        sta     $00                     ;save into temp variable for now
ca1e: a0 fa                        ldy     #$fa                    ;set default vertical speed
ca20: b5 cf                        lda     Enemy_Y_Position,x      ;check hammer bro's vertical coordinate
ca22: 30 13                        bmi     SetHJ                   ;if on the bottom half of the screen, use current speed
ca24: a0 fd                        ldy     #$fd                    ;otherwise set alternate vertical speed
ca26: c9 70                        cmp     #$70                    ;check to see if hammer bro is above the middle of screen
ca28: e6 00                        inc     $00                     ;increment preset value to $01
ca2a: 90 0b                        bcc     SetHJ                   ;if above the middle of the screen, use current speed and $01
ca2c: c6 00                        dec     $00                     ;otherwise return value to $00
ca2e: bd a8 07                     lda     PseudoRandomBitReg+1,x  ;get part of LSFR, mask out all but LSB
ca31: 29 01                        and     #$01
ca33: d0 02                        bne     SetHJ                   ;if d0 of LSFR set, branch and use current speed and $00
ca35: a0 fa                        ldy     #$fa                    ;otherwise reset to default vertical speed
ca37: 94 a0        SetHJ           sty     Enemy_Y_Speed,x         ;set vertical speed for jumping
ca39: b5 1e                        lda     Enemy_State,x           ;set d0 in enemy state for jumping
ca3b: 09 01                        ora     #$01
ca3d: 95 1e                        sta     Enemy_State,x
ca3f: a5 00                        lda     $00                     ;load preset value here to use as bitmask
ca41: 3d a9 07                     and     PseudoRandomBitReg+2,x  ;and do bit-wise comparison with part of LSFR
ca44: a8                           tay                             ;then use as offset
ca45: ad cc 06                     lda     SecondaryHardMode       ;check secondary hard mode flag
ca48: d0 01                        bne     HJump
ca4a: a8                           tay                             ;if secondary hard mode flag clear, set offset to 0
ca4b: b9 10 ca     HJump           lda     HammerBroJumpLData,y    ;get jump length timer data using offset from before
ca4e: 9d 8a 07                     sta     EnemyFrameTimer,x       ;save in enemy timer
ca51: bd a8 07                     lda     PseudoRandomBitReg+1,x
ca54: 09 c0                        ora     #%11000000              ;get contents of part of LSFR, set d7 and d6, then
ca56: 95 3c                        sta     HammerBroJumpTimer,x    ;store in jump timer
                   MoveHammerBroXDir
ca58: a0 fc                        ldy     #$fc                    ;move hammer bro a little to the left
ca5a: a5 09                        lda     FrameCounter
ca5c: 29 40                        and     #%01000000              ;change hammer bro's direction every 64 frames
ca5e: d0 02                        bne     Shimmy
ca60: a0 04                        ldy     #$04                    ;if d6 set in counter, move him a little to the right
ca62: 94 58        Shimmy          sty     Enemy_X_Speed,x         ;store horizontal speed
ca64: a0 01                        ldy     #$01                    ;set to face right by default
ca66: 20 43 e1                     jsr     PlayerEnemyDiff         ;get horizontal difference between player and hammer bro
ca69: 30 0a                        bmi     SetShim                 ;if enemy to the left of player, skip this part
ca6b: c8                           iny                             ;set to face left
ca6c: bd 96 07                     lda     EnemyIntervalTimer,x    ;check walking timer
ca6f: d0 04                        bne     SetShim                 ;if not yet expired, skip to set moving direction
ca71: a9 f8                        lda     #$f8
ca73: 95 58                        sta     Enemy_X_Speed,x         ;otherwise, make the hammer bro walk left towards player
ca75: 94 46        SetShim         sty     Enemy_MovingDir,x       ;set moving direction
                   ; 
ca77: a0 00        MoveNormalEnemy ldy     #$00                    ;init Y to leave horizontal movement as-is 
ca79: b5 1e                        lda     Enemy_State,x
ca7b: 29 40                        and     #%01000000              ;check enemy state for d6 set, if set skip
ca7d: d0 19                        bne     FallE                   ; to move enemy vertically, then horizontally if necessary
ca7f: b5 1e                        lda     Enemy_State,x
ca81: 0a                           asl     A                       ;check enemy state for d7 set
ca82: b0 30                        bcs     SteadM                  ;if set, branch to move enemy horizontally
ca84: b5 1e                        lda     Enemy_State,x
ca86: 29 20                        and     #%00100000              ;check enemy state for d5 set
ca88: d0 5b                        bne     MoveDefeatedEnemy       ;if set, branch to move defeated enemy object
ca8a: b5 1e                        lda     Enemy_State,x
ca8c: 29 07                        and     #%00000111              ;check d2-d0 of enemy state for any set bits
ca8e: f0 24                        beq     SteadM                  ;if enemy in normal state, branch to move enemy horizontally
ca90: c9 05                        cmp     #$05
ca92: f0 04                        beq     FallE                   ;if enemy in state used by spiny's egg, go ahead here
ca94: c9 03                        cmp     #$03
ca96: b0 30                        bcs     ReviveStunned           ;if enemy in states $03 or $04, skip ahead to yet another part
ca98: 20 63 bf     FallE           jsr     MoveD_EnemyVertically   ;do a sub here to move enemy downwards
ca9b: a0 00                        ldy     #$00
ca9d: b5 1e                        lda     Enemy_State,x           ;check for enemy state $02
ca9f: c9 02                        cmp     #$02
caa1: f0 0c                        beq     MEHor                   ;if found, branch to move enemy horizontally
caa3: 29 40                        and     #%01000000              ;check for d6 set
caa5: f0 0d                        beq     SteadM                  ;if not set, branch to something else
caa7: b5 16                        lda     Enemy_ID,x
caa9: c9 2e                        cmp     #PowerUpObject          ;check for power-up object
caab: f0 07                        beq     SteadM
caad: d0 03                        bne     SlowM                   ;if any other object where d6 set, jump to set Y

caaf: 4c 02 bf     MEHor           jmp     MoveEnemyHorizontally   ;jump here to move enemy horizontally for <> $2e and d6 set

cab2: a0 01        SlowM           ldy     #$01                    ;if branched here, increment Y to slow horizontal movement
cab4: b5 58        SteadM          lda     Enemy_X_Speed,x         ;get current horizontal speed
cab6: 48                           pha                             ;save to stack
cab7: 10 02                        bpl     AddHS                   ;if not moving or moving right, skip, leave Y alone
cab9: c8                           iny
caba: c8                           iny                             ;otherwise increment Y to next data
cabb: 18           AddHS           clc
cabc: 79 d0 c9                     adc     XSpeedAdderData,y       ;add value here to slow enemy down if necessary
cabf: 95 58                        sta     Enemy_X_Speed,x         ;save as horizontal speed temporarily
cac1: 20 02 bf                     jsr     MoveEnemyHorizontally   ;then do a sub to move horizontally
cac4: 68                           pla
cac5: 95 58                        sta     Enemy_X_Speed,x         ;get old horizontal speed from stack and return to
cac7: 60                           rts                             ; original memory location, then leave

cac8: bd 96 07     ReviveStunned   lda     EnemyIntervalTimer,x    ;if enemy timer not expired yet,
cacb: d0 1e                        bne     ChkKillGoomba           ; skip ahead to something else
cacd: 95 1e                        sta     Enemy_State,x           ;otherwise initialize enemy state to normal
cacf: a5 09                        lda     FrameCounter
cad1: 29 01                        and     #$01                    ;get d0 of frame counter
cad3: a8                           tay                             ;use as Y and increment for movement direction
cad4: c8                           iny
cad5: 94 46                        sty     Enemy_MovingDir,x       ;store as pseudorandom movement direction
cad7: 88                           dey                             ;decrement for use as pointer
cad8: ad 6a 07                     lda     PrimaryHardMode         ;check primary hard mode flag
cadb: f0 02                        beq     SetRSpd                 ;if not set, use pointer as-is
cadd: c8                           iny
cade: c8                           iny                             ;otherwise increment 2 bytes to next data
cadf: b9 d4 c9     SetRSpd         lda     RevivedXSpeed,y         ;load and store new horizontal speed
cae2: 95 58                        sta     Enemy_X_Speed,x         ;and leave
cae4: 60                           rts

                   MoveDefeatedEnemy
cae5: 20 63 bf                     jsr     MoveD_EnemyVertically   ;execute sub to move defeated enemy downwards
cae8: 4c 02 bf                     jmp     MoveEnemyHorizontally   ;now move defeated enemy horizontally

caeb: c9 0e        ChkKillGoomba   cmp     #$0e                    ;check to see if enemy timer has reached
caed: d0 09                        bne     HKGmba                  ; a certain point, and branch to leave if not
caef: b5 16                        lda     Enemy_ID,x
caf1: c9 06                        cmp     #Goomba                 ;check for goomba object
caf3: d0 03                        bne     HKGmba                  ;branch if not found
caf5: 20 98 c9                     jsr     EraseEnemyObject        ;otherwise, kill this goomba object
caf8: 60           HKGmba          rts                             ;leave!

                   ; -----------------------------------------------------------------------------
                   MoveJumpingEnemy
caf9: 20 92 bf                     jsr     MoveJ_EnemyVertically   ;do a sub to impose gravity on green paratroopa
cafc: 4c 02 bf                     jmp     MoveEnemyHorizontally   ;jump to move enemy horizontally

                   ; -----------------------------------------------------------------------------
                   ProcMoveRedPTroopa
caff: b5 a0                        lda     Enemy_Y_Speed,x
cb01: 1d 34 04                     ora     Enemy_Y_MoveForce,x     ;check for any vertical force or speed
cb04: d0 13                        bne     MoveRedPTUpOrDown       ;branch if any found
cb06: 9d 17 04                     sta     Enemy_YMF_Dummy,x       ;initialize something here
cb09: b5 cf                        lda     Enemy_Y_Position,x      ;check current vs. original vertical coordinate
cb0b: dd 01 04                     cmp     RedPTroopaOrigXPos,x
cb0e: b0 09                        bcs     MoveRedPTUpOrDown       ;if current => original, skip ahead to more code
cb10: a5 09                        lda     FrameCounter            ;get frame counter
cb12: 29 07                        and     #%00000111              ;mask out all but 3 LSB
cb14: d0 02                        bne     NoIncPT                 ;if any bits set, branch to leave
cb16: f6 cf                        inc     Enemy_Y_Position,x      ;otherwise increment red paratroopa's vertical position
cb18: 60           NoIncPT         rts                             ;leave

                   MoveRedPTUpOrDown
cb19: b5 cf                        lda     Enemy_Y_Position,x      ;check current vs. central vertical coordinate
cb1b: d5 58                        cmp     RedPTroopaCenterYPos,x
cb1d: 90 03                        bcc     MovPTDwn                ;if current < central, jump to move downwards
cb1f: 4c 75 bf                     jmp     MoveRedPTroopaUp        ;otherwise jump to move upwards

cb22: 4c 70 bf     MovPTDwn        jmp     MoveRedPTroopaDown      ;move downwards

                   ; -----------------------------------------------------------------------------
                   ; $00 - used to store adder for movement, also used as adder for platform
                   ; $01 - used to store maximum value for secondary counter
                   MoveFlyGreenPTroopa
cb25: 20 45 cb                     jsr     XMoveCntr_GreenPTroopa  ;do sub to increment primary and secondary counters
cb28: 20 66 cb                     jsr     MoveWithXMCntrs         ;do sub to move green paratroopa accordingly, and horizontally
cb2b: a0 01                        ldy     #$01                    ;set Y to move green paratroopa down
cb2d: a5 09                        lda     FrameCounter
cb2f: 29 03                        and     #%00000011              ;check frame counter 2 LSB for any bits set
cb31: d0 11                        bne     NoMGPT                  ;branch to leave if set to move up/down every fourth frame
cb33: a5 09                        lda     FrameCounter
cb35: 29 40                        and     #%01000000              ;check frame counter for d6 set
cb37: d0 02                        bne     YSway                   ;branch to move green paratroopa down if set
cb39: a0 ff                        ldy     #$ff                    ;otherwise set Y to move green paratroopa up
cb3b: 84 00        YSway           sty     $00                     ;store adder here
cb3d: b5 cf                        lda     Enemy_Y_Position,x
cb3f: 18                           clc                             ;add or subtract from vertical position
cb40: 65 00                        adc     $00                     ; to give green paratroopa a wavy flight
cb42: 95 cf                        sta     Enemy_Y_Position,x
cb44: 60           NoMGPT          rts                             ;leave!

                   XMoveCntr_GreenPTroopa
cb45: a9 13                        lda     #$13                    ;load preset maximum value for secondary counter
                   ; 
                   XMoveCntr_Platform
cb47: 85 01                        sta     $01                     ;store value here
cb49: a5 09                        lda     FrameCounter
cb4b: 29 03                        and     #%00000011              ;branch to leave if not on
cb4d: d0 0d                        bne     NoIncXM                 ;every fourth frame
cb4f: b4 58                        ldy     XMoveSecondaryCounter,x ;get secondary counter
cb51: b5 a0                        lda     XMovePrimaryCounter,x   ;get primary counter
cb53: 4a                           lsr     A
cb54: b0 0a                        bcs     DecSeXM                 ;if d0 of primary counter set, branch elsewhere
cb56: c4 01                        cpy     $01                     ;compare secondary counter to preset maximum value
cb58: f0 03                        beq     IncPXM                  ;if equal, branch ahead of this part
cb5a: f6 58                        inc     XMoveSecondaryCounter,x ;increment secondary counter and leave
cb5c: 60           NoIncXM         rts

cb5d: f6 a0        IncPXM          inc     XMovePrimaryCounter,x   ;increment primary counter and leave
cb5f: 60                           rts

cb60: 98           DecSeXM         tya                             ;put secondary counter in A
cb61: f0 fa                        beq     IncPXM                  ;if secondary counter at zero, branch back
cb63: d6 58                        dec     XMoveSecondaryCounter,x ;otherwise decrement secondary counter and leave
cb65: 60                           rts

cb66: b5 58        MoveWithXMCntrs lda     XMoveSecondaryCounter,x ;save secondary counter to stack
cb68: 48                           pha
cb69: a0 01                        ldy     #$01                    ;set value here by default
cb6b: b5 a0                        lda     XMovePrimaryCounter,x
cb6d: 29 02                        and     #%00000010              ;if d1 of primary counter is
cb6f: d0 0b                        bne     XMRight                 ; set, branch ahead of this part here
cb71: b5 58                        lda     XMoveSecondaryCounter,x
cb73: 49 ff                        eor     #$ff                    ;otherwise change secondary
cb75: 18                           clc                             ;counter to two's compliment
cb76: 69 01                        adc     #$01
cb78: 95 58                        sta     XMoveSecondaryCounter,x
cb7a: a0 02                        ldy     #$02                    ;load alternate value here
cb7c: 94 46        XMRight         sty     Enemy_MovingDir,x       ;store as moving direction
cb7e: 20 02 bf                     jsr     MoveEnemyHorizontally
cb81: 85 00                        sta     $00                     ;save value obtained from sub here
cb83: 68                           pla                             ;get secondary counter from stack
cb84: 95 58                        sta     XMoveSecondaryCounter,x ; and return to original place
cb86: 60                           rts

                   ; -----------------------------------------------------------------------------
cb87: 3f           BlooberBitmasks .dd1    %00111111
cb88: 03                           .dd1    %00000011

cb89: b5 1e        MoveBloober     lda     Enemy_State,x
cb8b: 29 20                        and     #%00100000              ;check enemy state for d5 set
cb8d: d0 4d                        bne     MoveDefeatedBloober     ;branch if set to move defeated bloober
cb8f: ac cc 06                     ldy     SecondaryHardMode       ;use secondary hard mode flag as offset
cb92: bd a8 07                     lda     PseudoRandomBitReg+1,x  ;get LSFR
cb95: 39 87 cb                     and     BlooberBitmasks,y       ;mask out bits in LSFR using bitmask loaded with offset
cb98: d0 12                        bne     BlooberSwim             ;if any bits set, skip ahead to make swim
cb9a: 8a                           txa
cb9b: 4a                           lsr     A                       ;check to see if on second or fourth slot (1 or 3)
cb9c: 90 04                        bcc     FBLeft                  ;if not, branch to figure out moving direction
cb9e: a4 45                        ldy     Player_MovingDir        ;otherwise, load player's moving direction and
cba0: b0 08                        bcs     SBMDir                  ; do an unconditional branch to set

cba2: a0 02        FBLeft          ldy     #$02                    ;set left moving direction by default
cba4: 20 43 e1                     jsr     PlayerEnemyDiff         ;get horizontal difference between player and bloober
cba7: 10 01                        bpl     SBMDir                  ;if enemy to the right of player, keep left
cba9: 88                           dey                             ;otherwise decrement to set right moving direction
cbaa: 94 46        SBMDir          sty     Enemy_MovingDir,x       ;set moving direction of bloober, then continue on here
cbac: 20 df cb     BlooberSwim     jsr     ProcSwimmingB           ;execute sub to make bloober swim characteristically
cbaf: b5 cf                        lda     Enemy_Y_Position,x      ;get vertical coordinate
cbb1: 38                           sec
cbb2: fd 34 04                     sbc     Enemy_Y_MoveForce,x     ;subtract movement force
cbb5: c9 20                        cmp     #$20                    ;check to see if position is above edge of status bar
cbb7: 90 02                        bcc     SwimX                   ;if so, don't do it
cbb9: 95 cf                        sta     Enemy_Y_Position,x      ;otherwise, set new vertical position, make bloober swim
cbbb: b4 46        SwimX           ldy     Enemy_MovingDir,x       ;check moving direction
cbbd: 88                           dey
cbbe: d0 0e                        bne     LeftSwim                ;if moving to the left, branch to second part
cbc0: b5 87                        lda     Enemy_X_Position,x
cbc2: 18                           clc                             ;add movement speed to horizontal coordinate
cbc3: 75 58                        adc     BlooperMoveSpeed,x
cbc5: 95 87                        sta     Enemy_X_Position,x      ;store result as new horizontal coordinate
cbc7: b5 6e                        lda     Enemy_PageLoc,x
cbc9: 69 00                        adc     #$00                    ;add carry to page location
cbcb: 95 6e                        sta     Enemy_PageLoc,x         ;store as new page location and leave
cbcd: 60                           rts

cbce: b5 87        LeftSwim        lda     Enemy_X_Position,x
cbd0: 38                           sec                             ;subtract movement speed from horizontal coordinate
cbd1: f5 58                        sbc     BlooperMoveSpeed,x
cbd3: 95 87                        sta     Enemy_X_Position,x      ;store result as new horizontal coordinate
cbd5: b5 6e                        lda     Enemy_PageLoc,x
cbd7: e9 00                        sbc     #$00                    ;subtract borrow from page location
cbd9: 95 6e                        sta     Enemy_PageLoc,x         ;store as new page location and leave
cbdb: 60                           rts

                   MoveDefeatedBloober
cbdc: 4c 8c bf                     jmp     MoveEnemySlowVert       ;jump to move defeated bloober downwards

cbdf: b5 a0        ProcSwimmingB   lda     BlooperMoveCounter,x    ;get enemy's movement counter
cbe1: 29 02                        and     #%00000010              ;check for d1 set
cbe3: d0 37                        bne     ChkForFloatdown         ;branch if set
cbe5: a5 09                        lda     FrameCounter
cbe7: 29 07                        and     #%00000111              ;get 3 LSB of frame counter
cbe9: 48                           pha                             ;get 3 LSB of frame counter
cbea: b5 a0                        lda     BlooperMoveCounter,x    ;get enemy's movement counter
cbec: 4a                           lsr     A                       ;check for d0 set
cbed: b0 15                        bcs     SlowSwim                ;branch if set
cbef: 68                           pla                             ;pull 3 LSB of frame counter from the stack
cbf0: d0 11                        bne     BSwimE                  ;branch to leave, execute code only every eighth frame
cbf2: bd 34 04                     lda     Enemy_Y_MoveForce,x
cbf5: 18                           clc                             ;add to movement force to speed up swim
cbf6: 69 01                        adc     #$01
cbf8: 9d 34 04                     sta     Enemy_Y_MoveForce,x     ;set movement force
cbfb: 95 58                        sta     BlooperMoveSpeed,x      ;set as movement speed
cbfd: c9 02                        cmp     #$02
cbff: d0 02                        bne     BSwimE                  ;if certain horizontal speed, branch to leave
cc01: f6 a0                        inc     BlooperMoveCounter,x    ;otherwise increment movement counter
cc03: 60           BSwimE          rts

cc04: 68           SlowSwim        pla                             ;pull 3 LSB of frame counter from the stack
cc05: d0 14                        bne     NoSSw                   ;branch to leave, execute code only every eighth frame
cc07: bd 34 04                     lda     Enemy_Y_MoveForce,x
cc0a: 38                           sec                             ;subtract from movement force to slow swim
cc0b: e9 01                        sbc     #$01
cc0d: 9d 34 04                     sta     Enemy_Y_MoveForce,x     ;set movement force
cc10: 95 58                        sta     BlooperMoveSpeed,x      ;set as movement speed
cc12: d0 07                        bne     NoSSw                   ;if any speed, branch to leave
cc14: f6 a0                        inc     BlooperMoveCounter,x    ;otherwise increment movement counter
cc16: a9 02                        lda     #$02
cc18: 9d 96 07                     sta     EnemyIntervalTimer,x    ;set enemy's timer
cc1b: 60           NoSSw           rts                             ;leave

cc1c: bd 96 07     ChkForFloatdown lda     EnemyIntervalTimer,x    ;get enemy timer
cc1f: f0 08                        beq     ChkNeearPlayer          ;branch if expired
cc21: a5 09        Floatdown       lda     FrameCounter            ;get frame counter
cc23: 4a                           lsr     A                       ;check for d0 set
cc24: b0 02                        bcs     NoFD                    ;branch to leave on every other frame
cc26: f6 cf                        inc     Enemy_Y_Position,x      ;otherwise increment vertical coordinate
cc28: 60           NoFD            rts                             ;leave

cc29: b5 cf        ChkNeearPlayer  lda     Enemy_Y_Position,x      ;get vertical coordinate
cc2b: 69 10                        adc     #$10                    ;add sixteen pixels
cc2d: c5 ce                        cmp     Player_Y_Position       ;compare result with player's vertical coordinate
cc2f: 90 f0                        bcc     Floatdown               ;if modified vertical less than player's, branch
cc31: a9 00                        lda     #$00
cc33: 95 a0                        sta     BlooperMoveCounter,x    ;otherwise nullify movement counter
cc35: 60                           rts

                   ; -----------------------------------------------------------------------------
cc36: b5 1e        MoveBulletBill  lda     Enemy_State,x           ;check bullet bill's enemy object state for d5 set
cc38: 29 20                        and     #%00100000
cc3a: f0 03                        beq     NotDefB                 ;if not set, continue with movement code
cc3c: 4c 92 bf                     jmp     MoveJ_EnemyVertically   ;otherwise jump to move defeated bullet bill downwards

cc3f: a9 e8        NotDefB         lda     #$e8                    ;set bullet bill's horizontal speed
cc41: 95 58                        sta     Enemy_X_Speed,x         ;and move it accordingly (note: this bullet bill
cc43: 4c 02 bf                     jmp     MoveEnemyHorizontally   ; object occurs in frenzy object $17, not from cannons)

                   ; -----------------------------------------------------------------------------
                   ; $02 - used to hold preset values
                   ; $03 - used to hold enemy state
cc46: 40 80        SwimCCXMoveData .bulk   $40,$80
cc48: 04 04                        .bulk   $04,$04                 ;residual data, not used

                   MoveSwimmingCheepCheep
cc4a: b5 1e                        lda     Enemy_State,x           ;check cheep-cheep's enemy object state
cc4c: 29 20                        and     #%00100000              ;for d5 set
cc4e: f0 03                        beq     CCSwim                  ;if not set, continue with movement code
cc50: 4c 8c bf                     jmp     MoveEnemySlowVert       ;otherwise jump to move defeated cheep-cheep downwards

cc53: 85 03        CCSwim          sta     $03                     ;save enemy state in $03
cc55: b5 16                        lda     Enemy_ID,x              ;get enemy identifier
cc57: 38                           sec
cc58: e9 0a                        sbc     #$0a                    ;subtract ten for cheep-cheep identifiers
cc5a: a8                           tay                             ;use as offset
cc5b: b9 46 cc                     lda     SwimCCXMoveData,y       ;load value here
cc5e: 85 02                        sta     $02
cc60: bd 01 04                     lda     Enemy_X_MoveForce,x     ;load horizontal force
cc63: 38                           sec
cc64: e5 02                        sbc     $02                     ;subtract preset value from horizontal force
cc66: 9d 01 04                     sta     Enemy_X_MoveForce,x     ;store as new horizontal force
cc69: b5 87                        lda     Enemy_X_Position,x      ;get horizontal coordinate
cc6b: e9 00                        sbc     #$00                    ;subtract borrow (thus moving it slowly)
cc6d: 95 87                        sta     Enemy_X_Position,x      ;and save as new horizontal coordinate
cc6f: b5 6e                        lda     Enemy_PageLoc,x
cc71: e9 00                        sbc     #$00                    ;subtract borrow again, this time from the
cc73: 95 6e                        sta     Enemy_PageLoc,x         ; page location, then save
cc75: a9 20                        lda     #$20
cc77: 85 02                        sta     $02                     ;save new value here
cc79: e0 02                        cpx     #$02                    ;check enemy object offset
cc7b: 90 49                        bcc     ExSwCC                  ;if in first or second slot, branch to leave
cc7d: b5 58                        lda     CheepCheepMoveMFlag,x   ;check movement flag
cc7f: c9 10                        cmp     #$10                    ;if movement speed set to $00,
cc81: 90 16                        bcc     CCSwimUpwards           ; branch to move upwards
cc83: bd 17 04                     lda     Enemy_YMF_Dummy,x
cc86: 18                           clc
cc87: 65 02                        adc     $02                     ;add preset value to dummy variable to get carry
cc89: 9d 17 04                     sta     Enemy_YMF_Dummy,x       ;and save dummy
cc8c: b5 cf                        lda     Enemy_Y_Position,x      ;get vertical coordinate
cc8e: 65 03                        adc     $03                     ;add carry to it plus enemy state to slowly move it downwards
cc90: 95 cf                        sta     Enemy_Y_Position,x      ;save as new vertical coordinate
cc92: b5 b6                        lda     Enemy_Y_HighPos,x
cc94: 69 00                        adc     #$00                    ;add carry to page location and
cc96: 4c ac cc                     jmp     ChkSwimYPos             ;jump to end of movement code

cc99: bd 17 04     CCSwimUpwards   lda     Enemy_YMF_Dummy,x
cc9c: 38                           sec
cc9d: e5 02                        sbc     $02                     ;subtract preset value to dummy variable to get borrow
cc9f: 9d 17 04                     sta     Enemy_YMF_Dummy,x       ;and save dummy
cca2: b5 cf                        lda     Enemy_Y_Position,x      ;get vertical coordinate
cca4: e5 03                        sbc     $03                     ;subtract borrow to it plus enemy state to slowly move it upwards
cca6: 95 cf                        sta     Enemy_Y_Position,x      ;save as new vertical coordinate
cca8: b5 b6                        lda     Enemy_Y_HighPos,x
ccaa: e9 00                        sbc     #$00                    ;subtract borrow from page location
ccac: 95 b6        ChkSwimYPos     sta     Enemy_Y_HighPos,x       ;save new page location here
ccae: a0 00                        ldy     #$00                    ;load movement speed to upwards by default
ccb0: b5 cf                        lda     Enemy_Y_Position,x      ;get vertical coordinate
ccb2: 38                           sec
ccb3: fd 34 04                     sbc     CheepCheepOrigYPos,x    ;subtract original coordinate from current
ccb6: 10 07                        bpl     YPDiff                  ;if result positive, skip to next part
ccb8: a0 10                        ldy     #$10                    ;otherwise load movement speed to downwards
ccba: 49 ff                        eor     #$ff
ccbc: 18                           clc                             ;get two's compliment of result
ccbd: 69 01                        adc     #$01                    ; to obtain total difference of original vs. current
ccbf: c9 0f        YPDiff          cmp     #$0f                    ;if difference between original vs. current vertical
ccc1: 90 03                        bcc     ExSwCC                  ; coordinates < 15 pixels, leave movement speed alone
ccc3: 98                           tya
ccc4: 95 58                        sta     CheepCheepMoveMFlag,x   ;otherwise change movement speed
ccc6: 60           ExSwCC          rts                             ;leave

                   ; -----------------------------------------------------------------------------
                   ; $00 - used as counter for firebar parts
                   ; $01 - used for oscillated high byte of spin state or to hold horizontal adder
                   ; $02 - used for oscillated high byte of spin state or to hold vertical adder
                   ; $03 - used for mirror data
                   ; $04 - used to store player's sprite 1 X coordinate
                   ; $05 - used to evaluate mirror data
                   ; $06 - used to store either screen X coordinate or sprite data offset
                   ; $07 - used to store screen Y coordinate
                   ; $ed - used to hold maximum length of firebar
                   ; $ef - used to hold high byte of spinstate
                   ; 
                   ; horizontal adder is at first byte + high byte of spinstate, vertical adder is
                   ; same + 8 bytes, two's compliment if greater than $08 for proper oscillation
                   FirebarPosLookupTbl
ccc7: 00 01 03 04+                 .bulk   $00,$01,$03,$04,$05,$06,$07,$07,$08,$00,$03,$06,$09,$0b,$0d,$0e
                                    +      $0f,$10,$00,$04,$09,$0d,$10,$13,$16,$17,$18,$00,$06,$0c,$12,$16
                                    +      $1a,$1d,$1f,$20,$00,$07,$0f,$16,$1c,$21,$25,$27,$28,$00,$09,$12
                                    +      $1b,$21,$27,$2c,$2f,$30,$00,$0b,$15,$1f,$27,$2e,$33,$37,$38,$00
                                    +      $0c,$18,$24,$2d,$35,$3b,$3e,$40,$00,$0e,$1b,$28,$32,$3b,$42,$46
                                    +      $48,$00,$0f,$1f,$2d,$38,$42,$4a,$4e,$50,$00,$11,$22,$31,$3e,$49
                                    +      $51,$56,$58
                   FirebarMirrorData
cd2a: 01 03 02 00                  .bulk   $01,$03,$02,$00
                   FirebarTblOffsets
cd2e: 00 09 12 1b+                 .bulk   $00,$09,$12,$1b,$24,$2d
cd34: 36 3f 48 51+                 .bulk   $36,$3f,$48,$51,$5a,$63
cd3a: 0c 18        FirebarYPos     .bulk   $0c,$18

cd3c: 20 af f1     ProcFirebar     jsr     GetEnemyOffscreenBits   ;get offscreen information
cd3f: ad d1 03                     lda     Enemy_OffscreenBits     ;check for d3 set
cd42: 29 08                        and     #%00001000              ;if so, branch to leave
cd44: d0 74                        bne     SkipFBar
cd46: ad 47 07                     lda     TimerControl            ;if master timer control set, branch
cd49: d0 0a                        bne     SusFbar                 ; ahead of this part
cd4b: bd 88 03                     lda     FirebarSpinSpeed,x      ;load spinning speed of firebar
cd4e: 20 10 d4                     jsr     FirebarSpin             ;modify current spinstate
cd51: 29 1f                        and     #%00011111              ;mask out all but 5 LSB
cd53: 95 a0                        sta     FirebarSpinState_High,x ;and store as new high byte of spinstate
cd55: b5 a0        SusFbar         lda     FirebarSpinState_High,x ;get high byte of spinstate
cd57: b4 16                        ldy     Enemy_ID,x              ;check enemy identifier
cd59: c0 1f                        cpy     #$1f
cd5b: 90 0d                        bcc     SetupGFB                ;if < $1f (long firebar), branch
cd5d: c9 08                        cmp     #$08                    ;check high byte of spinstate
cd5f: f0 04                        beq     SkpFSte                 ;if eight, branch to change
cd61: c9 18                        cmp     #$18
cd63: d0 05                        bne     SetupGFB                ;if not at twenty-four branch to not change
cd65: 18           SkpFSte         clc
cd66: 69 01                        adc     #$01                    ;add one to spinning thing to avoid horizontal state
cd68: 95 a0                        sta     FirebarSpinState_High,x
cd6a: 85 ef        SetupGFB        sta     $ef                     ;save high byte of spinning thing, modified or otherwise
cd6c: 20 52 f1                     jsr     RelativeEnemyPosition   ;get relative coordinates to screen
cd6f: 20 8e ce                     jsr     GetFirebarPosition      ;do a sub here (residual, too early to be used now)
cd72: bc e5 06                     ldy     Enemy_SprDataOffset,x   ;get OAM data offset
cd75: ad b9 03                     lda     Enemy_Rel_YPos          ;get relative vertical coordinate
cd78: 99 00 02                     sta     Sprite_Y_Position,y     ;store as Y in OAM data
cd7b: 85 07                        sta     $07                     ;also save here
cd7d: ad ae 03                     lda     Enemy_Rel_XPos          ;get relative horizontal coordinate
cd80: 99 03 02                     sta     Sprite_X_Position,y     ;store as X in OAM data
cd83: 85 06                        sta     $06                     ;also save here
cd85: a9 01                        lda     #$01
cd87: 85 00                        sta     $00                     ;set $01 value here (not necessary)
cd89: 20 08 ce                     jsr     FirebarCollision        ;draw fireball part and do collision detection
cd8c: a0 05                        ldy     #$05                    ;load value for short firebars by default
cd8e: b5 16                        lda     Enemy_ID,x
cd90: c9 1f                        cmp     #$1f                    ;are we doing a long firebar?
cd92: 90 02                        bcc     SetMFbar                ;no, branch then
cd94: a0 0b                        ldy     #$0b                    ;otherwise load value for long firebars
cd96: 84 ed        SetMFbar        sty     $ed                     ;store maximum value for length of firebars
cd98: a9 00                        lda     #$00
cd9a: 85 00                        sta     $00                     ;initialize counter here
cd9c: a5 ef        DrawFbar        lda     $ef                     ;load high byte of spinstate
cd9e: 20 8e ce                     jsr     GetFirebarPosition      ;get fireball position data depending on firebar part
cda1: 20 bb cd                     jsr     DrawFirebar_Collision   ;position it properly, draw it and do collision detection
cda4: a5 00                        lda     $00                     ;check which firebar part
cda6: c9 04                        cmp     #$04
cda8: d0 08                        bne     NextFbar
cdaa: ac cf 06                     ldy     DuplicateObj_Offset     ;if we arrive at fifth firebar part,
cdad: b9 e5 06                     lda     Enemy_SprDataOffset,y   ; get offset from long firebar and load OAM data offset
cdb0: 85 06                        sta     $06                     ; using long firebar offset, then store as new one here
cdb2: e6 00        NextFbar        inc     $00                     ;move onto the next firebar part
cdb4: a5 00                        lda     $00
cdb6: c5 ed                        cmp     $ed                     ;if we end up at the maximum part, go on and leave
cdb8: 90 e2                        bcc     DrawFbar                ;otherwise go back and do another
cdba: 60           SkipFBar        rts

                   DrawFirebar_Collision
cdbb: a5 03                        lda     $03                     ;store mirror data elsewhere
cdbd: 85 05                        sta     $05
cdbf: a4 06                        ldy     $06                     ;load OAM data offset for firebar
cdc1: a5 01                        lda     $01                     ;load horizontal adder we got from position loader
cdc3: 46 05                        lsr     $05                     ;shift LSB of mirror data
cdc5: b0 04                        bcs     AddHA                   ;if carry was set, skip this part
cdc7: 49 ff                        eor     #$ff
cdc9: 69 01                        adc     #$01                    ;otherwise get two's compliment of horizontal adder
cdcb: 18           AddHA           clc                             ;add horizontal coordinate relative to screen to
cdcc: 6d ae 03                     adc     Enemy_Rel_XPos          ;horizontal adder, modified or otherwise
cdcf: 99 03 02                     sta     Sprite_X_Position,y     ;store as X coordinate here
cdd2: 85 06                        sta     $06                     ;store here for now, note offset is saved in Y still
cdd4: cd ae 03                     cmp     Enemy_Rel_XPos          ;compare X coordinate of sprite to original X of firebar
cdd7: b0 09                        bcs     SubtR1                  ;if sprite coordinate => original coordinate, branch
cdd9: ad ae 03                     lda     Enemy_Rel_XPos
cddc: 38                           sec                             ;otherwise subtract sprite X from the
cddd: e5 06                        sbc     $06                     ; original one and skip this part
cddf: 4c e6 cd                     jmp     ChkFOfs

cde2: 38           SubtR1          sec                             ;subtract original X from the
cde3: ed ae 03                     sbc     Enemy_Rel_XPos          ;current sprite X
cde6: c9 59        ChkFOfs         cmp     #$59                    ;if difference of coordinates within a certain range,
cde8: 90 04                        bcc     VAHandl                 ; continue by handling vertical adder
cdea: a9 f8                        lda     #$f8                    ;otherwise, load offscreen Y coordinate
cdec: d0 15                        bne     SetVFbr                 ; and unconditionally branch to move sprite offscreen

cdee: ad b9 03     VAHandl         lda     Enemy_Rel_YPos          ;if vertical relative coordinate offscreen,
cdf1: c9 f8                        cmp     #$f8                    ;skip ahead of this part and write into sprite Y coordinate
cdf3: f0 0e                        beq     SetVFbr
cdf5: a5 02                        lda     $02                     ;load vertical adder we got from position loader
cdf7: 46 05                        lsr     $05                     ;shift LSB of mirror data one more time
cdf9: b0 04                        bcs     AddVA                   ;if carry was set, skip this part
cdfb: 49 ff                        eor     #$ff
cdfd: 69 01                        adc     #$01                    ;otherwise get two's compliment of second part
cdff: 18           AddVA           clc                             ;add vertical coordinate relative to screen to 
ce00: 6d b9 03                     adc     Enemy_Rel_YPos          ; the second data, modified or otherwise
ce03: 99 00 02     SetVFbr         sta     Sprite_Y_Position,y     ;store as Y coordinate here
ce06: 85 07                        sta     $07                     ;also store here for now
                   FirebarCollision
ce08: 20 ed ec                     jsr     DrawFirebar             ;run sub here to draw current tile of firebar
ce0b: 98                           tya                             ;return OAM data offset and save
ce0c: 48                           pha                             ;to the stack for now
ce0d: ad 9f 07                     lda     StarInvincibleTimer     ;if star mario invincibility timer
ce10: 0d 47 07                     ora     TimerControl            ; or master timer controls set
ce13: d0 70                        bne     NoColFB                 ; then skip all of this
ce15: 85 05                        sta     $05                     ;otherwise initialize counter
ce17: a4 b5                        ldy     Player_Y_HighPos
ce19: 88                           dey                             ;if player's vertical high byte offscreen,
ce1a: d0 69                        bne     NoColFB                 ;skip all of this
ce1c: a4 ce                        ldy     Player_Y_Position       ;get player's vertical position
ce1e: ad 54 07                     lda     PlayerSize              ;get player's size
ce21: d0 05                        bne     AdjSm                   ;if player small, branch to alter variables
ce23: ad 14 07                     lda     CrouchingFlag
ce26: f0 09                        beq     BigJp                   ;if player big and not crouching, jump ahead
ce28: e6 05        AdjSm           inc     $05                     ;if small or big but crouching, execute this part
ce2a: e6 05                        inc     $05                     ;first increment our counter twice (setting $02 as flag)
ce2c: 98                           tya
ce2d: 18                           clc                             ;then add 24 pixels to the player's
ce2e: 69 18                        adc     #$18                    ; vertical coordinate
ce30: a8                           tay
ce31: 98           BigJp           tya                             ;get vertical coordinate, altered or otherwise, from Y
ce32: 38           FBCLoop         sec                             ;subtract vertical position of firebar
ce33: e5 07                        sbc     $07                     ; from the vertical coordinate of the player
ce35: 10 05                        bpl     ChkVFBD                 ;if player lower on the screen than firebar, 
ce37: 49 ff                        eor     #$ff                    ;skip two's compliment part
ce39: 18                           clc                             ;otherwise get two's compliment
ce3a: 69 01                        adc     #$01
ce3c: c9 08        ChkVFBD         cmp     #$08                    ;if difference => 8 pixels, skip ahead of this part
ce3e: b0 1c                        bcs     Chk20fs
ce40: a5 06                        lda     $06                     ;if firebar on far right on the screen, skip this,
ce42: c9 f0                        cmp     #$f0                    ; because, really, what's the point?
ce44: b0 16                        bcs     Chk20fs
ce46: ad 07 02                     lda     Sprite_X_Position+4     ;get OAM X coordinate for sprite #1
ce49: 18                           clc
ce4a: 69 04                        adc     #$04                    ;add four pixels
ce4c: 85 04                        sta     $04                     ;store here
ce4e: 38                           sec                             ;subtract horizontal coordinate of firebar
ce4f: e5 06                        sbc     $06                     ;from the X coordinate of player's sprite 1
ce51: 10 05                        bpl     ChkFBCl                 ;if modded X coordinate to the right of firebar
ce53: 49 ff                        eor     #$ff                    ;skip two's compliment part
ce55: 18                           clc                             ;otherwise get two's compliment
ce56: 69 01                        adc     #$01
ce58: c9 08        ChkFBCl         cmp     #$08                    ;if difference < 8 pixels, collision, thus branch
ce5a: 90 13                        bcc     ChgSDir                 ; to process
ce5c: a5 05        Chk20fs         lda     $05                     ;if value of $02 was set earlier for whatever reason,
ce5e: c9 02                        cmp     #$02                    ; branch to increment OAM offset and leave, no collision
ce60: f0 23                        beq     NoColFB
ce62: a4 05                        ldy     $05                     ;otherwise get temp here and use as offset
ce64: a5 ce                        lda     Player_Y_Position
ce66: 18                           clc
ce67: 79 3a cd                     adc     FirebarYPos,y           ;add value loaded with offset to player's vertical coordinate
ce6a: e6 05                        inc     $05                     ; then increment temp and jump back
ce6c: 4c 32 ce                     jmp     FBCLoop

ce6f: a2 01        ChgSDir         ldx     #$01                    ;set movement direction by default
ce71: a5 04                        lda     $04                     ;if OAM X coordinate of player's sprite 1
ce73: c5 06                        cmp     $06                     ; is greater than horizontal coordinate of firebar
ce75: b0 01                        bcs     SetSDir                 ; then do not alter movement direction
ce77: e8                           inx                             ;otherwise increment it
ce78: 86 46        SetSDir         stx     Enemy_MovingDir         ;store movement direction here
ce7a: a2 00                        ldx     #$00
ce7c: a5 00                        lda     $00                     ;save value written to $00 to stack
ce7e: 48                           pha
ce7f: 20 2c d9                     jsr     InjurePlayer            ;perform sub to hurt or kill player
ce82: 68                           pla
ce83: 85 00                        sta     $00                     ;get value of $00 from stack
ce85: 68           NoColFB         pla                             ;get OAM data offset
ce86: 18                           clc                             ;add four to it and save
ce87: 69 04                        adc     #$04
ce89: 85 06                        sta     $06
ce8b: a6 08                        ldx     ObjectOffset            ;get enemy object buffer offset and leave
ce8d: 60                           rts

                   GetFirebarPosition
ce8e: 48                           pha                             ;save high byte of spinstate to the stack
ce8f: 29 0f                        and     #%00001111              ;mask out low nybble
ce91: c9 09                        cmp     #$09
ce93: 90 05                        bcc     GetHAdder               ;if lower than $09, branch ahead
ce95: 49 0f                        eor     #%00001111              ;otherwise get two's compliment to oscillate
ce97: 18                           clc
ce98: 69 01                        adc     #$01
ce9a: 85 01        GetHAdder       sta     $01                     ;store result, modified or not, here
ce9c: a4 00                        ldy     $00                     ;load number of firebar ball where we're at
ce9e: b9 2e cd                     lda     FirebarTblOffsets,y     ;load offset to firebar position data
cea1: 18                           clc
cea2: 65 01                        adc     $01                     ;add oscillated high byte of spinstate
cea4: a8                           tay                             ; to offset here and use as new offset
cea5: b9 c7 cc                     lda     FirebarPosLookupTbl,y   ;get data here and store as horizontal adder
cea8: 85 01                        sta     $01
ceaa: 68                           pla                             ;pull whatever was in A from the stack
ceab: 48                           pha                             ;save it again because we still need it
ceac: 18                           clc
cead: 69 08                        adc     #$08                    ;add eight this time, to get vertical adder
ceaf: 29 0f                        and     #%00001111              ;mask out high nybble
ceb1: c9 09                        cmp     #$09                    ;if lower than $09, branch ahead
ceb3: 90 05                        bcc     GetVAdder
ceb5: 49 0f                        eor     #%00001111              ;otherwise get two's compliment
ceb7: 18                           clc
ceb8: 69 01                        adc     #$01
ceba: 85 02        GetVAdder       sta     $02                     ;store result here
cebc: a4 00                        ldy     $00
cebe: b9 2e cd                     lda     FirebarTblOffsets,y     ;load offset to firebar position data again
cec1: 18                           clc
cec2: 65 02                        adc     $02                     ;this time add value in $02 to offset here and use as offset
cec4: a8                           tay
cec5: b9 c7 cc                     lda     FirebarPosLookupTbl,y   ;get data here and store as vertica adder
cec8: 85 02                        sta     $02
ceca: 68                           pla                             ;pull out whatever was in A one last time
cecb: 4a                           lsr     A                       ;divide by eight or shift three to the right
cecc: 4a                           lsr     A
cecd: 4a                           lsr     A
cece: a8                           tay                             ;use as offset
cecf: b9 2a cd                     lda     FirebarMirrorData,y     ;load mirroring data here
ced2: 85 03                        sta     $03                     ;store
ced4: 60                           rts

                   ; -----------------------------------------------------------------------------
                   PRandomSubtracter
ced5: f8 a0 70 bd+                 .bulk   $f8,$a0,$70,$bd,$00
ceda: 20 20 20 00+ FlyCCBPriority  .bulk   $20,$20,$20,$00,$00

                   MoveFlyingCheepCheep
cedf: b5 1e                        lda     Enemy_State,x           ;check cheep-cheep's enemy state
cee1: 29 20                        and     #%00100000              ;for d5 set
cee3: f0 08                        beq     FlyCC                   ;branch to continue code if not set
cee5: a9 00                        lda     #$00
cee7: 9d c5 03                     sta     Enemy_SprAttrib,x       ;otherwise clear sprite attributes
ceea: 4c 92 bf                     jmp     MoveJ_EnemyVertically   ;and jump to move defeated cheep-cheep downwards

ceed: 20 02 bf     FlyCC           jsr     MoveEnemyHorizontally   ;move cheep-cheep horizontally based on speed and force
cef0: a0 0d                        ldy     #$0d                    ;set vertical movement amount
cef2: a9 05                        lda     #$05                    ;set maximum speed
cef4: 20 96 bf                     jsr     SetXMoveAmt             ;branch to impose gravity on flying cheep-cheep
cef7: bd 34 04                     lda     Enemy_Y_MoveForce,x
cefa: 4a                           lsr     A                       ;get vertical movement force and
cefb: 4a                           lsr     A                       ;move high nybble to low
cefc: 4a                           lsr     A
cefd: 4a                           lsr     A
cefe: a8                           tay                             ;save as offset (note this tends to go into reach of code)
ceff: b5 cf                        lda     Enemy_Y_Position,x      ;get vertical position
cf01: 38                           sec                             ;subtract pseudorandom value based on offset from position
cf02: f9 d5 ce                     sbc     PRandomSubtracter,y
cf05: 10 05                        bpl     AddCCF                  ;if result within top half of screen, skip this part
cf07: 49 ff                        eor     #$ff
cf09: 18                           clc                             ;otherwise get two's compliment
cf0a: 69 01                        adc     #$01
cf0c: c9 08        AddCCF          cmp     #$08                    ;if result or two's compliment greater than eight,
cf0e: b0 0e                        bcs     BPGet                   ;skip to the end without changing movement force
cf10: bd 34 04                     lda     Enemy_Y_MoveForce,x
cf13: 18                           clc
cf14: 69 10                        adc     #$10                    ;otherwise add to it
cf16: 9d 34 04                     sta     Enemy_Y_MoveForce,x
cf19: 4a                           lsr     A                       ;move high nybble to low again
cf1a: 4a                           lsr     A
cf1b: 4a                           lsr     A
cf1c: 4a                           lsr     A
cf1d: a8                           tay
cf1e: b9 da ce     BPGet           lda     FlyCCBPriority,y        ;load bg priority data and store (this is very likely
cf21: 9d c5 03                     sta     Enemy_SprAttrib,x       ; broken or residual code, value is overwritten before
cf24: 60                           rts                             ; drawing it next frame), then leave

                   ; -----------------------------------------------------------------------------
                   ; $00 - used to hold horizontal difference
                   ; $01-$03 - used to hold difference adjusters
cf25: 15 30 40     LakituDiffAdj   .bulk   $15,$30,$40

cf28: b5 1e        MoveLakitu      lda     Enemy_State,x           ;check lakitu's enemy state
cf2a: 29 20                        and     #%00100000              ;for d5 set
cf2c: f0 03                        beq     ChkLS                   ;if not set, continue with code
cf2e: 4c 63 bf                     jmp     MoveD_EnemyVertically   ;otherwise jump to move defeated lakitu downwards

cf31: b5 1e        ChkLS           lda     Enemy_State,x           ;if lakitu's enemy state not set at all,
cf33: f0 0b                        beq     Fr12S                   ; go ahead and continue with code
cf35: a9 00                        lda     #$00
cf37: 95 a0                        sta     LakituMoveDirection,x   ;otherwise initialize moving direction to move to left
cf39: 8d cb 06                     sta     EnemyFrenzyBuffer       ;initialize frenzy buffer
cf3c: a9 10                        lda     #$10
cf3e: d0 13                        bne     SetLSpd                 ;load horizontal speed and do unconditional branch

cf40: a9 12        Fr12S           lda     #Spiny
cf42: 8d cb 06                     sta     EnemyFrenzyBuffer       ;set spiny identifier in frenzy buffer
cf45: a0 02                        ldy     #$02
cf47: b9 25 cf     LdLDa           lda     LakituDiffAdj,y         ;load values
cf4a: 99 01 00                     sta     $0001,y                 ;store in zero page
cf4d: 88                           dey
cf4e: 10 f7                        bpl     LdLDa                   ;do this until all values are stired
cf50: 20 6c cf                     jsr     PlayerLakituDiff        ;execute sub to set speed and create spinys
cf53: 95 58        SetLSpd         sta     LakituMoveSpeed,x       ;set movement speed returned from sub
cf55: a0 01                        ldy     #$01                    ;set moving direction to right by default
cf57: b5 a0                        lda     LakituMoveDirection,x
cf59: 29 01                        and     #$01                    ;get LSB of moving direction
cf5b: d0 0a                        bne     SetLMov                 ;if set, branch to the end to use moving direction
cf5d: b5 58                        lda     LakituMoveSpeed,x
cf5f: 49 ff                        eor     #$ff                    ;get two's compliment of moving speed
cf61: 18                           clc
cf62: 69 01                        adc     #$01
cf64: 95 58                        sta     LakituMoveSpeed,x       ;store as new moving speed
cf66: c8                           iny                             ;increment moving direction to left
cf67: 94 46        SetLMov         sty     Enemy_MovingDir,x       ;store moving direction
cf69: 4c 02 bf                     jmp     MoveEnemyHorizontally   ;move lakitu horizontally

                   PlayerLakituDiff
cf6c: a0 00                        ldy     #$00                    ;set Y for default value
cf6e: 20 43 e1                     jsr     PlayerEnemyDiff         ;get horizontal difference between enemy and player
cf71: 10 0a                        bpl     ChkLakDif               ;branch if enemy is to the right of the player
cf73: c8                           iny                             ;increment Y for left of player
cf74: a5 00                        lda     $00
cf76: 49 ff                        eor     #$ff                    ;get two's compliment of low byte of horizontal difference
cf78: 18                           clc
cf79: 69 01                        adc     #$01                    ;store two's compliment as horizontal difference
cf7b: 85 00                        sta     $00
cf7d: a5 00        ChkLakDif       lda     $00                     ;get low byte of horizontal difference
cf7f: c9 3c                        cmp     #$3c                    ;if within a certain distance of player, branch
cf81: 90 1c                        bcc     ChkPSpeed
cf83: a9 3c                        lda     #$3c                    ;otherwise set maximum distance
cf85: 85 00                        sta     $00
cf87: b5 16                        lda     Enemy_ID,x              ;check if lakitu is in our current enemy slot
cf89: c9 11                        cmp     #Lakitu
cf8b: d0 12                        bne     ChkPSpeed               ;if not, branch elsewhere
cf8d: 98                           tya                             ;compare contents of Y, now in A
cf8e: d5 a0                        cmp     LakituMoveDirection,x   ;to what is being used as horizontal movement direction
cf90: f0 0d                        beq     ChkPSpeed               ;if moving toward the player, branch, do not alter
cf92: b5 a0                        lda     LakituMoveDirection,x   ;if moving to the left beyond maximum distance,
cf94: f0 06                        beq     SetLMovD                ; branch and alter without delay
cf96: d6 58                        dec     LakituMoveSpeed,x       ;decrement horizontal speed
cf98: b5 58                        lda     LakituMoveSpeed,x       ;if horizontal speed not yet at zero, branch to leave
cf9a: d0 40                        bne     ExMoveLak
cf9c: 98           SetLMovD        tya                             ;set horizontal direction depending on horizontal
cf9d: 95 a0                        sta     LakituMoveDirection,x   ;difference between enemy and player if necessary
cf9f: a5 00        ChkPSpeed       lda     $00
cfa1: 29 3c                        and     #%00111100              ;mask out all but four bits in the middle
cfa3: 4a                           lsr     A                       ;divide masked difference by four
cfa4: 4a                           lsr     A
cfa5: 85 00                        sta     $00                     ;store as new value
cfa7: a0 00                        ldy     #$00                    ;init offset
cfa9: a5 57                        lda     Player_X_Speed
cfab: f0 24                        beq     SubDifAdj               ;if player not moving horizontally, branch
cfad: ad 75 07                     lda     ScrollAmount
cfb0: f0 1f                        beq     SubDifAdj               ;if scroll speed not set, branch to same place
cfb2: c8                           iny                             ;otherwise increment offset
cfb3: a5 57                        lda     Player_X_Speed
cfb5: c9 19        LCFB5           cmp     #$19                    ;if player not running, branch
cfb7: 90 08                        bcc     ChkSpinyO
cfb9: ad 75 07                     lda     ScrollAmount
cfbc: c9 02                        cmp     #$02                    ;if scroll speed below a certain amount, branch
cfbe: 90 01                        bcc     ChkSpinyO               ; to same place
cfc0: c8                           iny                             ;otherwise increment once more
cfc1: b5 16        ChkSpinyO       lda     Enemy_ID,x              ;check for spiny object
cfc3: c9 12                        cmp     #Spiny
cfc5: d0 04                        bne     ChkEmySpd               ;branch if not found
cfc7: a5 57                        lda     Player_X_Speed          ;if player not moving, skip this part
cfc9: d0 06                        bne     SubDifAdj
cfcb: b5 a0        ChkEmySpd       lda     LakituMoveDirection,x   ;check vertical speed
cfcd: d0 02                        bne     SubDifAdj               ;branch if nonzero
cfcf: a0 00                        ldy     #$00                    ;otherwise reinit offset
cfd1: b9 01 00     SubDifAdj       lda     $0001,y                 ;get one of three saved values from earlier
cfd4: a4 00                        ldy     $00                     ;get saved horizontal difference
cfd6: 38           SPixelLak       sec                             ;subtract one for each pixel of horizontal difference
cfd7: e9 01                        sbc     #$01                    ; from one of three saved values
cfd9: 88                           dey
cfda: 10 fa                        bpl     SPixelLak               ;branch until all pixels are subtracted, to adjust difference
cfdc: 60           ExMoveLak       rts                             ;leave!!!

                   ; -----------------------------------------------------------------------------
                   ; $04-$05 - used to store name table address in little endian order
                   BridgeCollapseData
cfdd: 1a                           .dd1    $1a                     ;axe
cfde: 58                           .dd1    $58                     ;chain
cfdf: 98 96 94 92+                 .bulk   $98,$96,$94,$92,$90,$8e,$8c ;bridge
cfe6: 8a 88 86 84+                 .bulk   $8a,$88,$86,$84,$82,$80

cfec: ae 68 03     BridgeCollapse  ldx     BowserFront_Offset      ;get enemy offset for bowser
cfef: b5 16                        lda     Enemy_ID,x              ;check enemy object identifier for bowser
cff1: c9 2d                        cmp     #Bowser                 ;if not found, branch ahead,
cff3: d0 10                        bne     SetM2                   ; metatile removal not necessary
cff5: 86 08                        stx     ObjectOffset            ;store as enemy offset here
cff7: b5 1e                        lda     Enemy_State,x           ;if bowser in normal state, skip all of this
cff9: f0 1a                        beq     RemoveBridge
cffb: 29 40                        and     #%01000000              ;if bowser's state has d6 clear, skip to silence music
cffd: f0 06                        beq     SetM2
cfff: b5 cf                        lda     Enemy_Y_Position,x      ;check bowser's vertical coordinate
d001: c9 e0                        cmp     #$e0                    ;if bowser not yet low enough, skip this part ahead
d003: 90 0a                        bcc     MoveD_Bowser
d005: a9 80        SetM2           lda     #Silence                ;silence music
d007: 85 fc                        sta     EventMusicQueue
d009: ee 72 07                     inc     OperMode_Task           ;move onto next secondary mode in autoctrl mode
d00c: 4c 71 d0                     jmp     KillAllEnemies          ;jump to empty all enemy slots and then leave  

d00f: 20 8c bf     MoveD_Bowser    jsr     MoveEnemySlowVert       ;do a sub to move bowser downwards
d012: 4c 7b d1                     jmp     BowserGfxHandler        ;jump to draw bowser's front and rear, then leave

d015: ce 64 03     RemoveBridge    dec     BowserFeetCounter       ;decrement timer to control bowser's feet
d018: d0 44                        bne     NoBFall                 ;if not expired, skip all of this
d01a: a9 04                        lda     #$04
d01c: 8d 64 03                     sta     BowserFeetCounter       ;otherwise, set timer now
d01f: ad 63 03                     lda     BowserBodyControls
d022: 49 01                        eor     #$01                    ;invert bit to control bowser's feet
d024: 8d 63 03                     sta     BowserBodyControls
d027: a9 22                        lda     #$22                    ;put high byte of name table address here for now
d029: 85 05                        sta     $05
d02b: ac 69 03                     ldy     BridgeCollapseOffset    ;get bridge collapse offset here
d02e: b9 dd cf                     lda     BridgeCollapseData,y    ;load low byte of name table address and store here
d031: 85 04                        sta     $04
d033: ac 00 03                     ldy     VRAM_Buffer1_Offset     ;increment vram buffer offset
d036: c8                           iny
d037: a2 0c                        ldx     #$0c                    ;set offset for tile data for sub to draw blank metatile
d039: 20 cd 8a                     jsr     RemBridge               ;do sub here to remove bowser's bridge metatiles
d03c: a6 08                        ldx     ObjectOffset            ;get enemy offset
d03e: 20 8f 8a                     jsr     MoveVOffset             ;set new vram buffer offset
d041: a9 08                        lda     #Sfx_Blast              ;load the fireworks/gunfire sound into the square 2 sfx
d043: 85 fe                        sta     Square2SoundQueue       ; queue while at the same time loading the brick
d045: a9 01                        lda     #Sfx_BrickShatter       ; shatter sound into the noise sfx queue thus
d047: 85 fd                        sta     NoiseSoundQueue         ; producing the unique sound of the bridge collapsing 
d049: ee 69 03                     inc     BridgeCollapseOffset    ;increment bridge collapse offset
d04c: ad 69 03                     lda     BridgeCollapseOffset
d04f: c9 0f                        cmp     #$0f                    ;if bridge collapse offset has not yet reached
d051: d0 0b                        bne     NoBFall                 ; the end, go ahead and skip this part
d053: 20 63 c3                     jsr     InitVStf                ;initialize whatever vertical speed bowser has
d056: a9 40                        lda     #%01000000
d058: 95 1e                        sta     Enemy_State,x           ;set bowser's state to one of defeated states (d6 set)
d05a: a9 80                        lda     #Sfx_BowserFall
d05c: 85 fe                        sta     Square2SoundQueue       ;play bowser defeat sound
d05e: 4c 7b d1     NoBFall         jmp     BowserGfxHandler        ;jump to code that draws bowser

                   ; -----------------------------------------------------------------------------
d061: 21 41 11 31  PRandomRange    .bulk   $21,$41,$11,$31

d065: b5 1e        RunBowser       lda     Enemy_State,x           ;if d5 in enemy state is not set
d067: 29 20                        and     #%00100000              ; then branch elsewhere to run bowser
d069: f0 14                        beq     BowserControl
d06b: b5 cf                        lda     Enemy_Y_Position,x      ;otherwise check vertical position
d06d: c9 e0                        cmp     #$e0                    ;if above a certain point, branch to move defeated bowser
d06f: 90 9e                        bcc     MoveD_Bowser            ;otherwise proceed to KillAllEnemies
d071: a2 04        KillAllEnemies  ldx     #$04                    ;start with last enemy slot
d073: 20 98 c9     KillLoop        jsr     EraseEnemyObject        ;branch to kill enemy objects
d076: ca                           dex                             ;move onto next enemy slot
d077: 10 fa                        bpl     KillLoop                ;do this until all slots are emptied
d079: 8d cb 06                     sta     EnemyFrenzyBuffer       ;empty frenzy buffer
d07c: a6 08                        ldx     ObjectOffset            ;get enemy object offset and leave
d07e: 60                           rts

d07f: a9 00        BowserControl   lda     #$00
d081: 8d cb 06                     sta     EnemyFrenzyBuffer       ;empty frenzy buffer
d084: ad 47 07                     lda     TimerControl            ;if master timer control not set,
d087: f0 03                        beq     ChkMouth                ;skip jump and execute code here
d089: 4c 39 d1                     jmp     SkipToFB                ;otherwise, jump over a bunch of code

d08c: ad 63 03     ChkMouth        lda     BowserBodyControls      ;check bowser's mouth
d08f: 10 03                        bpl     FeetTmr                 ;if bit clear, go ahead with code here
d091: 4c 0f d1                     jmp     HammerChk               ;otherwise skip a whole section starting here

d094: ce 64 03     FeetTmr         dec     BowserFeetCounter       ;decrement timer to control bowser's feet
d097: d0 0d                        bne     ResetMDr                ;if not expired, skip this part
d099: a9 20                        lda     #$20                    ;otherwise, reset timer
d09b: 8d 64 03                     sta     BowserFeetCounter
d09e: ad 63 03                     lda     BowserBodyControls      ;and invert bit used
d0a1: 49 01                        eor     #%00000001              ; to control bowser's feet
d0a3: 8d 63 03                     sta     BowserBodyControls
d0a6: a5 09        ResetMDr        lda     FrameCounter            ;check frame counter
d0a8: 29 0f                        and     #%00001111              ;if not on every sixteenth frame, skip
d0aa: d0 04                        bne     B_FaceP                 ; ahead to continue code
d0ac: a9 02                        lda     #$02                    ;otherwise reset moving/facing direction every
d0ae: 95 46                        sta     Enemy_MovingDir,x       ; sixteen frames
d0b0: bd 8a 07     B_FaceP         lda     EnemyFrameTimer,x       ;if timer set here expired,
d0b3: f0 1c                        beq     GetPRCmp                ;branch to next section
d0b5: 20 43 e1                     jsr     PlayerEnemyDiff         ;get horizontal difference between player and bowser,
d0b8: 10 17                        bpl     GetPRCmp                ; and branch if bowser to the right of the player
d0ba: a9 01                        lda     #$01
d0bc: 95 46                        sta     Enemy_MovingDir,x       ;set bowser to move and face to the right
d0be: a9 02                        lda     #$02
d0c0: 8d 65 03                     sta     BowserMovementSpeed     ;set movement speed
d0c3: a9 20                        lda     #$20
d0c5: 9d 8a 07                     sta     EnemyFrameTimer,x       ;set timer here
d0c8: 8d 90 07                     sta     BowserFireBreathTimer   ;set timer used for bowser's flame
d0cb: b5 87                        lda     Enemy_X_Position,x
d0cd: c9 c8                        cmp     #$c8                    ;if bowser to the right past a certain point,
d0cf: b0 3e                        bcs     HammerChk               ; skip ahead to some other section
d0d1: a5 09        GetPRCmp        lda     FrameCounter            ;get frame counter
d0d3: 29 03                        and     #%00000011
d0d5: d0 38                        bne     HammerChk               ;execute this code every fourth frame, otherwise branch
d0d7: b5 87                        lda     Enemy_X_Position,x
d0d9: cd 66 03                     cmp     BowserOrigXPos          ;if bowser not at original horizontal position,
d0dc: d0 0c                        bne     GetDToO                 ; branch to skip this part
d0de: bd a7 07                     lda     PseudoRandomBitReg,x
d0e1: 29 03                        and     #%00000011              ;get pseudorandom offset
d0e3: a8                           tay
d0e4: b9 61 d0                     lda     PRandomRange,y          ;load value using pseudorandom offset
d0e7: 8d dc 06                     sta     MaxRangeFromOrigin      ; and store here
d0ea: b5 87        GetDToO         lda     Enemy_X_Position,x
d0ec: 18                           clc                             ;add movement speed to bowser's horizontal
d0ed: 6d 65 03                     adc     BowserMovementSpeed     ; coordinate and save as new horizontal position
d0f0: 95 87                        sta     Enemy_X_Position,x
d0f2: b4 46                        ldy     Enemy_MovingDir,x
d0f4: c0 01                        cpy     #$01                    ;if bowser moving and facing to the right, skip ahead
d0f6: f0 17                        beq     HammerChk
d0f8: a0 ff                        ldy     #$ff                    ;set default movement speed here (move left)
d0fa: 38                           sec                             ;get difference of current vs. original
d0fb: ed 66 03                     sbc     BowserOrigXPos          ; horizontal position
d0fe: 10 07                        bpl     CompDtoO                ;if current position to the right of original, skip ahead
d100: 49 ff                        eor     #$ff
d102: 18                           clc                             ;get two's compliment
d103: 69 01                        adc     #$01
d105: a0 01                        ldy     #$01                    ;set alternate movement speed here (move right)
d107: cd dc 06     CompDtoO        cmp     MaxRangeFromOrigin      ;compare difference with pseudorandom value
d10a: 90 03                        bcc     HammerChk               ;if difference < pseudorandom value, leave speed alone
d10c: 8c 65 03                     sty     BowserMovementSpeed     ;otherwise change bowser's movement speed
d10f: bd 8a 07     HammerChk       lda     EnemyFrameTimer,x       ;if timer set here not expired yet, skip ahead to
d112: d0 28                        bne     MakeBJump               ; some other section of code
d114: 20 8c bf                     jsr     MoveEnemySlowVert       ;otherwise start by moving bowser downwards
d117: ad 5f 07                     lda     WorldNumber             ;check world number
d11a: c9 05                        cmp     #World6
d11c: 90 09                        bcc     SetHmrTmr               ;if world 1-5, skip this part (not time to throw hammers yet)
d11e: a5 09                        lda     FrameCounter
d120: 29 03                        and     #%00000011              ;check to see if it's time to execute sub
d122: d0 03                        bne     SetHmrTmr               ;if not, skip sub, otherwise
d124: 20 94 ba                     jsr     SpawnHammerObj          ;execute sub on every fourth frame to spawn misc object (hammer)
d127: b5 cf        SetHmrTmr       lda     Enemy_Y_Position,x      ;get current vertical position
d129: c9 80                        cmp     #$80                    ;if still above a certain point
d12b: 90 1c                        bcc     ChkFireB                ; then skip to world number check for flames
d12d: bd a7 07                     lda     PseudoRandomBitReg,x
d130: 29 03                        and     #%00000011              ;get pseudorandom offset
d132: a8                           tay
d133: b9 61 d0                     lda     PRandomRange,y          ;get value using pseudorandom offset
d136: 9d 8a 07                     sta     EnemyFrameTimer,x       ;set for timer here
d139: 4c 49 d1     SkipToFB        jmp     ChkFireB                ;jump to execute flames code

d13c: c9 01        MakeBJump       cmp     #$01                    ;if timer not yet about to expire,
d13e: d0 09                        bne     ChkFireB                ; skip ahead to next part
d140: d6 cf                        dec     Enemy_Y_Position,x      ;otherwise decrement vertical coordinate
d142: 20 63 c3                     jsr     InitVStf                ;initialize movement amount
d145: a9 fe                        lda     #$fe
d147: 95 a0                        sta     Enemy_Y_Speed,x         ;set vertical speed to move bowser upwards
d149: ad 5f 07     ChkFireB        lda     WorldNumber             ;check world number here
d14c: c9 07                        cmp     #World8                 ;world 8?
d14e: f0 04                        beq     SpawnFBr                ;if so, execute this part here
d150: c9 05                        cmp     #World6                 ;world 6-7?
d152: b0 27                        bcs     BowserGfxHandler        ;if so, skip this part here
d154: ad 90 07     SpawnFBr        lda     BowserFireBreathTimer   ;check timer here
d157: d0 22                        bne     BowserGfxHandler        ;if not expired yet, skip all of this
d159: a9 20                        lda     #$20
d15b: 8d 90 07                     sta     BowserFireBreathTimer   ;set timer here
d15e: ad 63 03                     lda     BowserBodyControls
d161: 49 80                        eor     #%10000000              ;invert bowser's mouth bit to open
d163: 8d 63 03                     sta     BowserBodyControls      ; and close bowser's mouth
d166: 30 e1                        bmi     ChkFireB                ;if bowser's mouth open, loop back
d168: 20 d9 d1                     jsr     SetFlameTimer           ;get timing for bowser's flame
d16b: ac cc 06                     ldy     SecondaryHardMode
d16e: f0 03                        beq     SetFBTmr                ;if secondary hard mode flag not set, skip this
d170: 38                           sec
d171: e9 10                        sbc     #$10                    ;otherwise subtract from value in A
d173: 8d 90 07     SetFBTmr        sta     BowserFireBreathTimer   ;set value as timer here
d176: a9 15                        lda     #$15                    ;put bowser's flame identifier
d178: 8d cb 06                     sta     EnemyFrenzyBuffer       ; in enemy frenzy buffer
                   ; 
                   BowserGfxHandler
d17b: 20 bc d1                     jsr     ProcessBowserHalf       ;do a sub here to process bowser's front
d17e: a0 10                        ldy     #$10                    ;load default value here to position bowser's rear
d180: b5 46                        lda     Enemy_MovingDir,x       ;check moving direction
d182: 4a                           lsr     A
d183: 90 02                        bcc     CopyFToR                ;if moving left, use default
d185: a0 f0                        ldy     #$f0                    ;otherwise load alternate positioning value here
d187: 98           CopyFToR        tya                             ;move bowser's rear object position value to A
d188: 18                           clc
d189: 75 87                        adc     Enemy_X_Position,x      ;add to bowser's front object horizontal coordinate
d18b: ac cf 06                     ldy     DuplicateObj_Offset     ;get bowser's rear object offset
d18e: 99 87 00                     sta     Enemy_X_Position,y      ;store A as bowser's rear horizontal coordinate
d191: b5 cf                        lda     Enemy_Y_Position,x
d193: 18                           clc                             ;add eight pixels to bowser's front object
d194: 69 08                        adc     #$08                    ;vertical coordinate and store as vertical coordinate
d196: 99 cf 00                     sta     Enemy_Y_Position,y      ; for bowser's rear
d199: b5 1e                        lda     Enemy_State,x
d19b: 99 1e 00                     sta     Enemy_State,y           ;copy enemy state directly from front to rear
d19e: b5 46                        lda     Enemy_MovingDir,x
d1a0: 99 46 00                     sta     Enemy_MovingDir,y       ;copy moving direction also
d1a3: a5 08                        lda     ObjectOffset            ;save enemy object offset of front to stack
d1a5: 48                           pha
d1a6: ae cf 06                     ldx     DuplicateObj_Offset     ;put enemy object offset of rear as current
d1a9: 86 08                        stx     ObjectOffset
d1ab: a9 2d                        lda     #Bowser                 ;set bowser's enemy identifier
d1ad: 95 16                        sta     Enemy_ID,x              ;store in bowser's rear object
d1af: 20 bc d1                     jsr     ProcessBowserHalf       ;do a sub here to process bowser's rear
d1b2: 68                           pla
d1b3: 85 08                        sta     ObjectOffset            ;get original enemy object offset
d1b5: aa                           tax
d1b6: a9 00                        lda     #$00                    ;nullify bowser's front/rear graphics flag
d1b8: 8d 6a 03                     sta     BowserGfxFlag
d1bb: 60           ExBgfxH         rts                             ;leave!

                   ProcessBowserHalf
d1bc: ee 6a 03                     inc     BowserGfxFlag           ;increment bowser's graphics flag, then run subroutines
d1bf: 20 d7 c8                     jsr     RunRetainerObj          ;to get offscreen bits, relative position and draw bowser (finally!)
d1c2: b5 1e                        lda     Enemy_State,x
d1c4: d0 f5                        bne     ExBgfxH                 ;if either enemy object not in normal state, branch to leave
d1c6: a9 0a                        lda     #$0a
d1c8: 9d 9a 04                     sta     Enemy_BoundBoxCtrl,x    ;set bounding box size control
d1cb: 20 43 e2                     jsr     GetEnemyBoundBox        ;get bounding box coordinates
d1ce: 4c 53 d8                     jmp     PlayerEnemyCollision    ;do player-to-enemy collision detection

                   ; -----------------------------------------------------------------------------
                   ; $00 - used to hold movement force and tile number
                   ; $01 - used to hold sprite attribute data
d1d1: bf 40 bf bf+ FlameTimerData  .bulk   $bf,$40,$bf,$bf,$bf,$40,$40,$bf

d1d9: ac 67 03     SetFlameTimer   ldy     BowserFlameTimerCtrl    ;load counter as offset
d1dc: ee 67 03                     inc     BowserFlameTimerCtrl    ;increment
d1df: ad 67 03                     lda     BowserFlameTimerCtrl    ;mask out all but 3 LSB
d1e2: 29 07                        and     #%00000111              ; to keep in range of 0-7
d1e4: 8d 67 03                     sta     BowserFlameTimerCtrl
d1e7: b9 d1 d1                     lda     FlameTimerData,y        ;load value to be used then leave
d1ea: 60           ExFl            rts

d1eb: ad 47 07     ProcBowserFlame lda     TimerControl            ;if master timer control flag set,
d1ee: d0 30                        bne     SetGfxF                 ; skip all of this
d1f0: a9 40                        lda     #$40                    ;load default movement force
d1f2: ac cc 06                     ldy     SecondaryHardMode
d1f5: f0 02                        beq     SFlmX                   ;if secondary hard mode flag not set, use default
d1f7: a9 60                        lda     #$60                    ;otherwise load alternate movement force to go faster
d1f9: 85 00        SFlmX           sta     $00                     ;store value here
d1fb: bd 01 04                     lda     Enemy_X_MoveForce,x
d1fe: 38                           sec                             ;subtract value from movement force
d1ff: e5 00                        sbc     $00
d201: 9d 01 04                     sta     Enemy_X_MoveForce,x     ;save new value
d204: b5 87                        lda     Enemy_X_Position,x
d206: e9 01                        sbc     #$01                    ;subtract one from horizontal position to move
d208: 95 87                        sta     Enemy_X_Position,x      ; to the left
d20a: b5 6e                        lda     Enemy_PageLoc,x
d20c: e9 00                        sbc     #$00                    ;subtract borrow from page location
d20e: 95 6e                        sta     Enemy_PageLoc,x
d210: bc 17 04                     ldy     BowserFlamePRandomOfs,x ;get some value here and use as offset
d213: b5 cf                        lda     Enemy_Y_Position,x      ;load vertical coordinate
d215: d9 9d c5                     cmp     FlameYPosData,y         ;compare against coordinate data using $0417,x as offset
d218: f0 06                        beq     SetGfxF                 ;if equal, branch and do not modify coordinate
d21a: 18                           clc
d21b: 7d 34 04                     adc     Enemy_Y_MoveForce,x     ;otherwise add value here to coordinate and store
d21e: 95 cf                        sta     Enemy_Y_Position,x      ;as new vertical coordinate
d220: 20 52 f1     SetGfxF         jsr     RelativeEnemyPosition   ;get new relative coordinates
d223: b5 1e                        lda     Enemy_State,x           ;if bowser's flame not in normal state,
d225: d0 c3                        bne     ExFl                    ; branch to leave
d227: a9 51                        lda     #$51                    ;otherwise, continue
d229: 85 00                        sta     $00                     ;write first tile number
d22b: a0 02                        ldy     #$02                    ;load attributes without vertical flip by default
d22d: a5 09                        lda     FrameCounter
d22f: 29 02                        and     #%00000010              ;invert vertical flip bit every 2 frames
d231: f0 02                        beq     FlmeAt                  ;if d1 not set, write default value
d233: a0 82                        ldy     #$82                    ;otherwise write value with vertical flip bit set
d235: 84 01        FlmeAt          sty     $01                     ;set bowser's flame sprite attributes here
d237: bc e5 06                     ldy     Enemy_SprDataOffset,x   ;get OAM data offset
d23a: a2 00                        ldx     #$00
d23c: ad b9 03     DrawFlameLoop   lda     Enemy_Rel_YPos          ;get Y relative coordinate of current enemy object
d23f: 99 00 02                     sta     Sprite_Y_Position,y     ;write into Y coordinate of OAM data
d242: a5 00                        lda     $00
d244: 99 01 02                     sta     Sprite_Tilenumber,y     ;write current tile number into OAM data
d247: e6 00                        inc     $00                     ;increment tile number to draw more bowser's flame
d249: a5 01                        lda     $01
d24b: 99 02 02                     sta     Sprite_Attributes,y     ;write saved attributes into OAM data
d24e: ad ae 03                     lda     Enemy_Rel_XPos
d251: 99 03 02                     sta     Sprite_X_Position,y     ;write X relative coordinate of current enemy object
d254: 18                           clc
d255: 69 08                        adc     #$08
d257: 8d ae 03                     sta     Enemy_Rel_XPos          ;then add eight to it and store
d25a: c8                           iny
d25b: c8                           iny
d25c: c8                           iny
d25d: c8                           iny                             ;increment Y four times to move onto the next OAM
d25e: e8                           inx                             ;move onto the next OAM, and branch if three
d25f: e0 03                        cpx     #$03                    ; have not yet been done
d261: 90 d9                        bcc     DrawFlameLoop
d263: a6 08                        ldx     ObjectOffset            ;reload original enemy offset
d265: 20 af f1                     jsr     GetEnemyOffscreenBits   ;get offscreen information
d268: bc e5 06                     ldy     Enemy_SprDataOffset,x   ;get OAM data offset
d26b: ad d1 03                     lda     Enemy_OffscreenBits     ;get enemy object offscreen bits
d26e: 4a                           lsr     A                       ;move d0 to carry and result to stack
d26f: 48                           pha
d270: 90 05                        bcc     M3FOfs                  ;branch if carry not set
d272: a9 f8                        lda     #$f8                    ;otherwise move sprite offscreen, this part likely
d274: 99 0c 02                     sta     Sprite_Y_Position+12,y  ; residual since flame is only made of three sprites
d277: 68           M3FOfs          pla                             ;get bits from stack
d278: 4a                           lsr     A                       ;move d1 to carry and move bits back to stack
d279: 48                           pha
d27a: 90 05                        bcc     M2FOfs                  ;branch if carry not set again
d27c: a9 f8                        lda     #$f8                    ;otherwise move third sprite offscreen
d27e: 99 08 02                     sta     Sprite_Y_Position+8,y
d281: 68           M2FOfs          pla                             ;get bits from stack again
d282: 4a                           lsr     A                       ;move d2 to carry and move bits back to stack again
d283: 48                           pha
d284: 90 05                        bcc     M1FOfs                  ;branch if carry not set yet again
d286: a9 f8                        lda     #$f8                    ;otherwise move second sprite offscreen
d288: 99 04 02                     sta     Sprite_Y_Position+4,y
d28b: 68           M1FOfs          pla                             ;get bits from stack one last time
d28c: 4a                           lsr     A                       ;move d3 to carry
d28d: 90 05                        bcc     ExFlmeD                 ;branch if carry not set one last time
d28f: a9 f8                        lda     #$f8
d291: 99 00 02                     sta     Sprite_Y_Position,y     ;otherwise move first sprite offscreen
d294: 60           ExFlmeD         rts                             ;leave

                   ; -----------------------------------------------------------------------------
d295: d6 a0        RunFireworks    dec     ExplosionTimerCounter,x ;decrement explosion timing counter here
d297: d0 0c                        bne     SetupExpl               ;if not expired, skip this part
d299: a9 08                        lda     #$08
d29b: 95 a0                        sta     ExplosionTimerCounter,x ;reset counter
d29d: f6 58                        inc     ExplosionGfxCounter,x   ;increment explosion graphics counter
d29f: b5 58                        lda     ExplosionGfxCounter,x
d2a1: c9 03                        cmp     #$03                    ;check explosion graphics counter
d2a3: b0 18                        bcs     FireworksSoundScore     ;if at a certain point, branch to kill this object
d2a5: 20 52 f1     SetupExpl       jsr     RelativeEnemyPosition   ;get relative coordinates of explosion
d2a8: ad b9 03                     lda     Enemy_Rel_YPos          ;copy relative coordinates
d2ab: 8d ba 03                     sta     Fireball_Rel_YPos       ;from the enemy object to the fireball object
d2ae: ad ae 03                     lda     Enemy_Rel_XPos          ;first vertical, then horizontal
d2b1: 8d af 03                     sta     Fireball_Rel_XPos
d2b4: bc e5 06                     ldy     Enemy_SprDataOffset,x   ;get OAM data offset
d2b7: b5 58                        lda     ExplosionGfxCounter,x   ;get explosion graphics counter
d2b9: 20 17 ed                     jsr     DrawExplosion_Fireworks ;do a sub to draw the explosion then leave
d2bc: 60                           rts

                   FireworksSoundScore
d2bd: a9 00                        lda     #$00                    ;disable enemy buffer flag
d2bf: 95 0f                        sta     Enemy_Flag,x
d2c1: a9 08                        lda     #Sfx_Blast              ;play fireworks/gunfire sound
d2c3: 85 fe                        sta     Square2SoundQueue
d2c5: a9 05                        lda     #$05                    ;set part of score modifier for 500 points
d2c7: 8d 38 01                     sta     DigitModifier+4
d2ca: 4c 36 d3                     jmp     EndAreaPoints           ;jump to award points accordingly then leave

                   ; -----------------------------------------------------------------------------
                   StarFlagYPosAdder
d2cd: 00 00 08 08                  .bulk   $00,$00,$08,$08
                   StarFlagXPosAdder
d2d1: 00 08 00 08                  .bulk   $00,$08,$00,$08
                   StarFlagTileData
d2d5: 54 55 56 57                  .bulk   $54,$55,$56,$57

d2d9: a9 00        RunStarFlagObj  lda     #$00                    ;initialize enemy frenzy buffer
d2db: 8d cb 06                     sta     EnemyFrenzyBuffer
d2de: ad 46 07                     lda     StarFlagTaskControl     ;check star flag object task number here
d2e1: c9 05                        cmp     #$05                    ;if greater than 5, branch to exit
d2e3: b0 2c                        bcs     StarFlagExit
d2e5: 20 04 8e                     jsr     JumpEngine              ;otherwise jump to appropriate sub

d2e8: 11 d3                        .dd2    StarFlagExit
d2ea: f2 d2                        .dd2    GameTimerFireworks
d2ec: 12 d3                        .dd2    AwardGameTimerPoints
d2ee: 4e d3                        .dd2    RaiseFlagSetoffFworks
d2f0: a2 d3                        .dd2    DelayToAreaEnd

                   GameTimerFireworks
d2f2: a0 05                        ldy     #$05                    ;set default state for star flag object
d2f4: ad fa 07                     lda     GameTimerDisplay+2      ;get game timer's last digit
d2f7: c9 01                        cmp     #$01
d2f9: f0 0e                        beq     SetFWC                  ;if last digit of game timer set to 1, skip ahead
d2fb: a0 03                        ldy     #$03                    ;otherwise load new value for state
d2fd: c9 03                        cmp     #$03
d2ff: f0 08                        beq     SetFWC                  ;if last digit of game timer set to 3, skip ahead
d301: a0 00                        ldy     #$00                    ;otherwise load one more potential value for state
d303: c9 06                        cmp     #$06
d305: f0 02                        beq     SetFWC                  ;if last digit of game timer set to 6, skip ahead
d307: a9 ff                        lda     #$ff                    ;otherwise set value for no fireworks
d309: 8d d7 06     SetFWC          sta     FireworksCounter        ;set fireworks counter here
d30c: 94 1e                        sty     Enemy_State,x           ;set whatever state we have in star flag object
                   IncrementSFTask1
d30e: ee 46 07                     inc     StarFlagTaskControl     ;increment star flag object task number
d311: 60           StarFlagExit    rts                             ;leave

                   AwardGameTimerPoints
d312: ad f8 07                     lda     GameTimerDisplay        ;check all game timer digits for any intervals left
d315: 0d f9 07                     ora     GameTimerDisplay+1
d318: 0d fa 07                     ora     GameTimerDisplay+2
d31b: f0 f1                        beq     IncrementSFTask1        ;if no time left on game timer at all, branch to next task
d31d: a5 09                        lda     FrameCounter
d31f: 29 04                        and     #%00000100              ;check frame counter for d2 set (skip ahead
d321: f0 04                        beq     NoTTick                 ; for four frames every four frames) branch if not set
d323: a9 10                        lda     #Sfx_TimerTick
d325: 85 fe                        sta     Square2SoundQueue       ;load timer tick sound
d327: a0 23        NoTTick         ldy     #$23                    ;set offset here to subtract from game timer's last digit
d329: a9 ff                        lda     #$ff                    ;set adder here to $ff, or -1, to subtract one
d32b: 8d 39 01                     sta     DigitModifier+5         ; from the last digit of the game timer
d32e: 20 5f 8f                     jsr     DigitsMathRoutine       ;subtract digit
d331: a9 05                        lda     #$05                    ;set now to add 50 points
d333: 8d 39 01                     sta     DigitModifier+5         ;per game timer interval subtracted
d336: a0 0b        EndAreaPoints   ldy     #$0b                    ;load offset for mario's score by default
d338: ad 53 07                     lda     CurrentPlayer           ;check player on the screen
d33b: f0 02                        beq     ELPGive                 ;if mario, do not change
d33d: a0 11                        ldy     #$11                    ;otherwise load offset for luigi's score
d33f: 20 5f 8f     ELPGive         jsr     DigitsMathRoutine       ;award 50 points per game timer interval
d342: ad 53 07                     lda     CurrentPlayer           ;get player on the screen (or 500 points per
d345: 0a                           asl     A                       ; fireworks explosion if branched here from there)
d346: 0a                           asl     A                       ;shift to high nybble
d347: 0a                           asl     A
d348: 0a                           asl     A
d349: 09 04                        ora     #%00000100              ;add four to set nybble for game timer
d34b: 4c 36 bc                     jmp     UpdateNumber            ;jump to print the new score and game timer

                   RaiseFlagSetoffFworks
d34e: b5 cf                        lda     Enemy_Y_Position,x      ;check star flag's vertical position
d350: c9 72                        cmp     #$72                    ;against preset value
d352: 90 05                        bcc     SetoffF                 ;if star flag higher vertically, branch to other code
d354: d6 cf                        dec     Enemy_Y_Position,x      ;otherwise, raise star flag by one pixel
d356: 4c 65 d3                     jmp     DrawStarFlag            ; and skip this part here

d359: ad d7 06     SetoffF         lda     FireworksCounter        ;check fireworks counter
d35c: f0 38                        beq     DrawFlagSetTimer        ;if no fireworks left to go off, skip this part
d35e: 30 36                        bmi     DrawFlagSetTimer        ;if no fireworks set to go off, skip this part
d360: a9 16                        lda     #Fireworks
d362: 8d cb 06                     sta     EnemyFrenzyBuffer       ;otherwise set fireworks object in frenzy queue
                   ; 
d365: 20 52 f1     DrawStarFlag    jsr     RelativeEnemyPosition   ;get relative coordinates of star flag
d368: bc e5 06                     ldy     Enemy_SprDataOffset,x   ;get OAM data offset
d36b: a2 03                        ldx     #$03                    ;do four sprites
d36d: ad b9 03     DSFloop         lda     Enemy_Rel_YPos          ;get relative vertical coordinate
d370: 18                           clc
d371: 7d cd d2                     adc     StarFlagYPosAdder,x     ;add Y coordinate adder data
d374: 99 00 02                     sta     Sprite_Y_Position,y     ;store as Y coordinate
d377: bd d5 d2                     lda     StarFlagTileData,x      ;get tile number
d37a: 99 01 02                     sta     Sprite_Tilenumber,y     ;store as tile number
d37d: a9 22                        lda     #$22                    ;set palette and background priority bits
d37f: 99 02 02                     sta     Sprite_Attributes,y     ;store as attributes
d382: ad ae 03                     lda     Enemy_Rel_XPos          ;get relative horizontal coordinate
d385: 18                           clc
d386: 7d d1 d2                     adc     StarFlagXPosAdder,x     ;add X coordinate adder data
d389: 99 03 02                     sta     Sprite_X_Position,y     ;store as X coordinate
d38c: c8                           iny
d38d: c8                           iny                             ;increment OAM data offset four bytes
d38e: c8                           iny                             ; for next sprite
d38f: c8                           iny
d390: ca                           dex                             ;move onto next sprite
d391: 10 da                        bpl     DSFloop                 ;do this until all sprites are done
d393: a6 08                        ldx     ObjectOffset            ;get enemy object offset and leave
d395: 60                           rts

                   DrawFlagSetTimer
d396: 20 65 d3                     jsr     DrawStarFlag            ;do sub to draw star flag
d399: a9 06                        lda     #$06
d39b: 9d 96 07                     sta     EnemyIntervalTimer,x    ;set interval timer here
                   IncrementSFTask2
d39e: ee 46 07                     inc     StarFlagTaskControl     ;move onto next task
d3a1: 60                           rts

d3a2: 20 65 d3     DelayToAreaEnd  jsr     DrawStarFlag            ;do sub to draw star flag
d3a5: bd 96 07                     lda     EnemyIntervalTimer,x    ;if interval timer set in previous task
d3a8: d0 05                        bne     StarFlagExit2           ;not yet expired, branch to leave
d3aa: ad b1 07                     lda     EventMusicBuffer        ;if event music buffer empty,
d3ad: f0 ef                        beq     IncrementSFTask2        ;branch to increment task
d3af: 60           StarFlagExit2   rts                             ;otherwise leave

                   ; -----------------------------------------------------------------------------
                   ; $00 - used to store horizontal difference between player and piranha plant
                   MovePiranhaPlant
d3b0: b5 1e                        lda     Enemy_State,x           ;check enemy state
d3b2: d0 56                        bne     PutinPipe               ;if set at all, branch to leave
d3b4: bd 8a 07                     lda     EnemyFrameTimer,x       ;check enemy's timer here
d3b7: d0 51                        bne     PutinPipe               ;branch to end if not yet expired
d3b9: b5 a0                        lda     PiranhaPlant_MoveFlag,x ;check movement flag
d3bb: d0 23                        bne     SetupToMovePPlant       ;if moving, skip to part ahead
d3bd: b5 58                        lda     PiranhaPlant_Y_Speed,x  ;if currently rising, branch 
d3bf: 30 14                        bmi     ReversePlantSpeed       ;to move enemy upwards out of pipe
d3c1: 20 43 e1                     jsr     PlayerEnemyDiff         ;get horizontal difference between player and
d3c4: 10 09                        bpl     ChkPlayerNearPipe       ; piranha plant, and branch if enemy to right of player
d3c6: a5 00                        lda     $00                     ;otherwise get saved horizontal difference
d3c8: 49 ff                        eor     #$ff
d3ca: 18                           clc                             ;and change to two's compliment
d3cb: 69 01                        adc     #$01
d3cd: 85 00                        sta     $00                     ;save as new horizontal difference
                   ChkPlayerNearPipe
d3cf: a5 00                        lda     $00                     ;get saved horizontal difference
d3d1: c9 21                        cmp     #$21
d3d3: 90 35                        bcc     PutinPipe               ;if player within a certain distance, branch to leave
                   ReversePlantSpeed
d3d5: b5 58                        lda     PiranhaPlant_Y_Speed,x  ;get vertical speed
d3d7: 49 ff                        eor     #$ff
d3d9: 18                           clc                             ;change to two's compliment
d3da: 69 01                        adc     #$01
d3dc: 95 58                        sta     PiranhaPlant_Y_Speed,x  ;save as new vertical speed
d3de: f6 a0                        inc     PiranhaPlant_MoveFlag,x ;increment to set movement flag
                   SetupToMovePPlant
d3e0: bd 34 04                     lda     PiranhaPlantDownYPos,x  ;get original vertical coordinate (lowest point)
d3e3: b4 58                        ldy     PiranhaPlant_Y_Speed,x  ;get vertical speed
d3e5: 10 03                        bpl     RiseFallPiranhaPlant    ;branch if moving downwards
d3e7: bd 17 04                     lda     PiranhaPlantUpYPos,x    ;otherwise get other vertical coordinate (highest point)
                   RiseFallPiranhaPlant
d3ea: 85 00                        sta     $00                     ;save vertical coordinate here
d3ec: a5 09                        lda     FrameCounter            ;get frame counter
d3ee: 4a                           lsr     A
d3ef: 90 19                        bcc     PutinPipe               ;branch to leave if d0 set (execute code every other frame)
d3f1: ad 47 07                     lda     TimerControl            ;get master timer control
d3f4: d0 14                        bne     PutinPipe               ;branch to leave if set (likely not necessary)
d3f6: b5 cf                        lda     Enemy_Y_Position,x      ;get current vertical coordinate
d3f8: 18                           clc
d3f9: 75 58                        adc     PiranhaPlant_Y_Speed,x  ;add vertical speed to move up or down
d3fb: 95 cf                        sta     Enemy_Y_Position,x      ;save as new vertical coordinate
d3fd: c5 00                        cmp     $00                     ;compare against low or high coordinate
d3ff: d0 09                        bne     PutinPipe               ;branch to leave if not yet reached
d401: a9 00                        lda     #$00
d403: 95 a0                        sta     PiranhaPlant_MoveFlag,x ;otherwise clear movement flag
d405: a9 40                        lda     #$40
d407: 9d 8a 07                     sta     EnemyFrameTimer,x       ;set timer to delay piranha plant movement
d40a: a9 20        PutinPipe       lda     #%00100000              ;set background priority bit in sprite
d40c: 9d c5 03                     sta     Enemy_SprAttrib,x       ; attributes to give illusion of being inside pipe
d40f: 60                           rts                             ;then leave

                   ; -----------------------------------------------------------------------------
                   ; $07 - spinning speed
d410: 85 07        FirebarSpin     sta     $07                     ;save spinning speed here
d412: b5 34                        lda     FirebarSpinDirection,x  ;check spinning direction
d414: d0 0e                        bne     SpinCounterClockwise    ;if moving counter-clockwise, branch to other part
d416: a0 18                        ldy     #$18                    ;possibly residual ldy
d418: b5 58                        lda     FirebarSpinState_Low,x
d41a: 18                           clc                             ;add spinning speed to what would normally be
d41b: 65 07                        adc     $07                     ; the horizontal speed
d41d: 95 58                        sta     FirebarSpinState_Low,x
d41f: b5 a0                        lda     FirebarSpinState_High,x ;add carry to what would normally be the vertical speed
d421: 69 00                        adc     #$00
d423: 60                           rts

                   SpinCounterClockwise
d424: a0 08                        ldy     #$08                    ;possibly residual ldy
d426: b5 58                        lda     FirebarSpinState_Low,x
d428: 38                           sec                             ;subtract spinning speed to what would normally be
d429: e5 07                        sbc     $07                     ; the horizontal speed
d42b: 95 58                        sta     FirebarSpinState_Low,x
d42d: b5 a0                        lda     FirebarSpinState_High,x ;add carry to what would normally be the vertical speed
d42f: e9 00                        sbc     #$00
d431: 60                           rts

                   ; -----------------------------------------------------------------------------
                   ; $00 - used to hold collision flag, Y movement force + 5 or low byte of name
                   ; table for rope
                   ; $01 - used to hold high byte of name table for rope
                   ; $02 - used to hold page location of rope
d432: b5 b6        BalancePlatform lda     Enemy_Y_HighPos,x       ;check high byte of vertical position
d434: c9 03                        cmp     #$03
d436: d0 03                        bne     DoBPl
d438: 4c 98 c9                     jmp     EraseEnemyObject        ;if far below screen, kill the object

d43b: b5 1e        DoBPl           lda     Enemy_State,x           ;get object's state (set to $ff or other platform offset)
d43d: 10 01                        bpl     CheckBalPlatform        ;if doing other balance platform, branch to leave
d43f: 60                           rts

                   CheckBalPlatform
d440: a8                           tay                             ;save offset from state as Y
d441: bd a2 03                     lda     PlatformCollisionFlag,x ;get collision flag of platform
d444: 85 00                        sta     $00                     ;store here
d446: b5 46                        lda     Enemy_MovingDir,x       ;get moving direction
d448: f0 03                        beq     ChkForFall
d44a: 4c bb d5                     jmp     PlatformFall            ;if set, jump here

d44d: a9 2d        ChkForFall      lda     #$2d                    ;check if platform is above a certain point
d44f: d5 cf                        cmp     Enemy_Y_Position,x
d451: 90 0f                        bcc     ChkOtherForFall         ;if not, branch elsewhere
d453: c4 00                        cpy     $00                     ;if collision flag is set to same value as
d455: f0 08                        beq     MakePlatformFall        ; enemy state, branch to make platforms fall
d457: 18                           clc
d458: 69 02                        adc     #$02                    ;otherwise add 2 pixels to vertical position
d45a: 95 cf                        sta     Enemy_Y_Position,x      ; of current platform and branch elsewhere
d45c: 4c b1 d5                     jmp     StopPlatforms           ; to make platforms stop

                   MakePlatformFall
d45f: 4c 98 d5                     jmp     InitPlatformFall        ;make platforms fall

d462: d9 cf 00     ChkOtherForFall cmp     Enemy_Y_Position,y      ;check if other platform is above a certain point
d465: 90 0d                        bcc     ChkToMoveBalPlat        ;if not, branch elsewhere
d467: e4 00                        cpx     $00                     ;if collision flag is set to same value as
d469: f0 f4                        beq     MakePlatformFall        ; enemy state, branch to make platforms fall
d46b: 18                           clc
d46c: 69 02                        adc     #$02                    ;otherwise add 2 pixels to vertical position
d46e: 99 cf 00                     sta     Enemy_Y_Position,y      ; of other platform and branch elsewhere
d471: 4c b1 d5                     jmp     StopPlatforms           ;jump to stop movement and do not return

                   ChkToMoveBalPlat
d474: b5 cf                        lda     Enemy_Y_Position,x      ;save vertical position to stack
d476: 48                           pha
d477: bd a2 03                     lda     PlatformCollisionFlag,x ;get collision flag
d47a: 10 18                        bpl     ColFlg                  ;branch if collision
d47c: bd 34 04                     lda     Enemy_Y_MoveForce,x
d47f: 18                           clc                             ;add $05 to contents of moveforce, whatever they be
d480: 69 05                        adc     #$05
d482: 85 00                        sta     $00                     ;store here
d484: b5 a0                        lda     Enemy_Y_Speed,x
d486: 69 00                        adc     #$00                    ;add carry to vertical speed
d488: 30 1a                        bmi     PlatDn                  ;branch if moving downwards
d48a: d0 0c                        bne     PlatUp                  ;branch elsewhere if moving upwards
d48c: a5 00                        lda     $00
d48e: c9 0b                        cmp     #$0b                    ;check if there's still a little force left
d490: 90 0c                        bcc     PlatSt                  ;if not enough, branch to stop movement
d492: b0 04                        bcs     PlatUp                  ;otherwise keep branch to move upwards

d494: c5 08        ColFlg          cmp     ObjectOffset            ;if collision flag matches
d496: f0 0c                        beq     PlatDn                  ; current enemy object offset, branch
d498: 20 b7 bf     PlatUp          jsr     MovePlatformUp          ;do a sub to move upwards
d49b: 4c a7 d4                     jmp     DoOtherPlatform         ;jump ahead to remaining code

d49e: 20 b1 d5     PlatSt          jsr     StopPlatforms           ;do a sub to stop movement
d4a1: 4c a7 d4                     jmp     DoOtherPlatform         ;jump ahead to remaining code

d4a4: 20 b4 bf     PlatDn          jsr     MovePlatformDown        ;do a sub to move downwards
d4a7: b4 1e        DoOtherPlatform ldy     Enemy_State,x           ;get offset of other platform
d4a9: 68                           pla                             ;get old vertical coordinate from stack
d4aa: 38                           sec
d4ab: f5 cf                        sbc     Enemy_Y_Position,x      ;get difference of old vs. new coordinate
d4ad: 18                           clc
d4ae: 79 cf 00                     adc     Enemy_Y_Position,y      ;add difference to vertical coordinate of other
d4b1: 99 cf 00                     sta     Enemy_Y_Position,y      ; platform to move it in the opposite direction
d4b4: bd a2 03                     lda     PlatformCollisionFlag,x ;if no collision, skip this part here
d4b7: 30 04                        bmi     DrawEraseRope
d4b9: aa                           tax                             ;put offset which collision occurred here
d4ba: 20 21 dc                     jsr     PositionPlayerOnVPlat   ; and use it to position player accordingly
d4bd: a4 08        DrawEraseRope   ldy     ObjectOffset            ;get enemy object offset
d4bf: b9 a0 00                     lda     Enemy_Y_Speed,y         ;check to see if current platform is
d4c2: 19 34 04                     ora     Enemy_Y_MoveForce,y     ; moving at all
d4c5: f0 77                        beq     ExitRp                  ;if not, skip all of this and branch to leave
d4c7: ae 00 03                     ldx     VRAM_Buffer1_Offset     ;get vram buffer offset
d4ca: e0 20                        cpx     #$20                    ;if offset beyond a certain point, go ahead
d4cc: b0 70                        bcs     ExitRp                  ; and skip this, branch to leave
d4ce: b9 a0 00                     lda     Enemy_Y_Speed,y
d4d1: 48                           pha                             ;save two copies of vertical speed to stack
d4d2: 48                           pha
d4d3: 20 41 d5                     jsr     SetupPlatformRope       ;do a sub to figure out where to put new bg tiles
d4d6: a5 01                        lda     $01                     ;write name table address to vram buffer
d4d8: 9d 01 03                     sta     VRAM_Buffer1,x          ;first the high byte, then the low
d4db: a5 00                        lda     $00
d4dd: 9d 02 03                     sta     VRAM_Buffer1+1,x
d4e0: a9 02                        lda     #$02                    ;set length for 2 bytes
d4e2: 9d 03 03                     sta     VRAM_Buffer1+2,x
d4e5: b9 a0 00                     lda     Enemy_Y_Speed,y         ;if platform moving upwards, branch 
d4e8: 30 0d                        bmi     EraseR1                 ; to do something else
d4ea: a9 a2                        lda     #$a2
d4ec: 9d 04 03                     sta     VRAM_Buffer1+3,x        ;otherwise put tile numbers for left
d4ef: a9 a3                        lda     #$a3                    ; and right sides of rope in vram buffer
d4f1: 9d 05 03                     sta     VRAM_Buffer1+4,x
d4f4: 4c ff d4                     jmp     OtherRope               ;jump to skip this part

d4f7: a9 24        EraseR1         lda     #$24                    ;put blank tiles in vram buffer
d4f9: 9d 04 03                     sta     VRAM_Buffer1+3,x        ; to erase rope
d4fc: 9d 05 03                     sta     VRAM_Buffer1+4,x
d4ff: b9 1e 00     OtherRope       lda     Enemy_State,y           ;get offset of other platform from state
d502: a8                           tay                             ;use as Y here
d503: 68                           pla                             ;pull second copy of vertical speed from stack
d504: 49 ff                        eor     #$ff                    ;invert bits to reverse speed
d506: 20 41 d5                     jsr     SetupPlatformRope       ;do sub again to figure out where to put bg tiles
d509: a5 01                        lda     $01                     ;write name table address to vram buffer
d50b: 9d 06 03                     sta     VRAM_Buffer1+5,x        ;this time we're doing putting tiles for
d50e: a5 00                        lda     $00                     ; the other platform
d510: 9d 07 03                     sta     VRAM_Buffer1+6,x
d513: a9 02                        lda     #$02
d515: 9d 08 03                     sta     VRAM_Buffer1+7,x        ;set length again for 2 bytes
d518: 68                           pla                             ;pull first copy of vertical speed from stack
d519: 10 0d                        bpl     EraseR2                 ;if moving upwards (note inversion earlier), skip this
d51b: a9 a2                        lda     #$a2
d51d: 9d 09 03                     sta     VRAM_Buffer1+8,x        ;otherwise put tile numbers for left
d520: a9 a3                        lda     #$a3                    ; and right sides of rope in vram
d522: 9d 0a 03                     sta     VRAM_Buffer1+9,x        ;transfer buffer
d525: 4c 30 d5                     jmp     EndRp                   ;jump to skip this part

d528: a9 24        EraseR2         lda     #$24                    ;put blank tiles in vram buffer
d52a: 9d 09 03                     sta     VRAM_Buffer1+8,x        ; to erase rope
d52d: 9d 0a 03                     sta     VRAM_Buffer1+9,x
d530: a9 00        EndRp           lda     #$00                    ;put null terminator at the end
d532: 9d 0b 03                     sta     VRAM_Buffer1+10,x
d535: ad 00 03                     lda     VRAM_Buffer1_Offset     ;add ten bytes to the vram buffer offset
d538: 18                           clc                             ; and store
d539: 69 0a                        adc     #$0a
d53b: 8d 00 03                     sta     VRAM_Buffer1_Offset
d53e: a6 08        ExitRp          ldx     ObjectOffset            ;get enemy object buffer offset and leave
d540: 60                           rts

                   SetupPlatformRope
d541: 48                           pha                             ;save second/third copy to stack
d542: b9 87 00                     lda     Enemy_X_Position,y      ;get horizontal coordinate
d545: 18                           clc
d546: 69 08                        adc     #$08                    ;add eight pixels
d548: ae cc 06                     ldx     SecondaryHardMode       ;if secondary hard mode flag set,
d54b: d0 03                        bne     GetLRp                  ; use coordinate as-is
d54d: 18                           clc
d54e: 69 10                        adc     #$10                    ;otherwise add sixteen more pixels
d550: 48           GetLRp          pha                             ;save modified horizontal coordinate to stack
d551: b9 6e 00                     lda     Enemy_PageLoc,y
d554: 69 00                        adc     #$00                    ;add carry to page location
d556: 85 02                        sta     $02                     ; and save here
d558: 68                           pla                             ;pull modified horizontal coordinate
d559: 29 f0                        and     #%11110000              ; from the stack, mask out low nybble
d55b: 4a                           lsr     A                       ; and shift three bits to the right
d55c: 4a                           lsr     A
d55d: 4a                           lsr     A
d55e: 85 00                        sta     $00                     ;store result here as part of name table low byte
d560: b6 cf                        ldx     Enemy_Y_Position,y      ;get vertical coordinate
d562: 68                           pla                             ;get second/third copy of vertical speed from stack
d563: 10 05                        bpl     GetHRp                  ;skip this part if moving downwards or not at all
d565: 8a                           txa
d566: 18                           clc
d567: 69 08                        adc     #$08                    ;add eight to vertical coordinate and
d569: aa                           tax                             ; save as X
d56a: 8a           GetHRp          txa                             ;move vertical coordinate to A
d56b: ae 00 03                     ldx     VRAM_Buffer1_Offset     ;get vram buffer offset
d56e: 0a                           asl     A
d56f: 2a                           rol     A                       ;rotate d7 to d0 and d6 into carry
d570: 48                           pha                             ;save modified vertical coordinate to stack
d571: 2a                           rol     A                       ;rotate carry to d0, thus d7 and d6 are at 2 LSB
d572: 29 03                        and     #%00000011              ;mask out all bits but d7 and d6, then set
d574: 09 20                        ora     #%00100000              ; d5 to get appropriate high byte of name table
d576: 85 01                        sta     $01                     ; address, then store
d578: a5 02                        lda     $02                     ;get saved page location from earlier
d57a: 29 01                        and     #$01                    ;mask out all but LSB
d57c: 0a                           asl     A
d57d: 0a                           asl     A                       ;shift twice to the left and save with the
d57e: 05 01                        ora     $01                     ; rest of the bits of the high byte, to get
d580: 85 01                        sta     $01                     ; the proper name table and the right place on it
d582: 68                           pla                             ;get modified vertical coordinate from stack
d583: 29 e0                        and     #%11100000              ;mask out low nybble and LSB of high nybble
d585: 18                           clc
d586: 65 00                        adc     $00                     ;add to horizontal part saved here
d588: 85 00                        sta     $00                     ;save as name table low byte
d58a: b9 cf 00                     lda     Enemy_Y_Position,y
d58d: c9 e8                        cmp     #$e8                    ;if vertical position not below the
d58f: 90 06                        bcc     ExPRp                   ; bottom of the screen, we're done, branch to leave
d591: a5 00                        lda     $00
d593: 29 bf                        and     #%10111111              ;mask out d6 of low byte of name table address
d595: 85 00                        sta     $00
d597: 60           ExPRp           rts                             ;leave!

                   InitPlatformFall
d598: 98                           tya                             ;move offset of other platform from Y to X
d599: aa                           tax
d59a: 20 af f1                     jsr     GetEnemyOffscreenBits   ;get offscreen bits
d59d: a9 06                        lda     #$06
d59f: 20 11 da                     jsr     SetupFloateyNumber      ;award 1000 points to player
d5a2: ad ad 03                     lda     Player_Rel_XPos
d5a5: 9d 17 01                     sta     FloateyNum_X_Pos,x      ;put floatey number coordinates where player is
d5a8: a5 ce                        lda     Player_Y_Position
d5aa: 9d 1e 01                     sta     FloateyNum_Y_Pos,x
d5ad: a9 01                        lda     #$01                    ;set moving direction as flag for
d5af: 95 46                        sta     Enemy_MovingDir,x       ; falling platforms
d5b1: 20 63 c3     StopPlatforms   jsr     InitVStf                ;initialize vertical speed and low byte
d5b4: 99 a0 00                     sta     Enemy_Y_Speed,y         ; for both platforms and leave
d5b7: 99 34 04                     sta     Enemy_Y_MoveForce,y
d5ba: 60                           rts

d5bb: 98           PlatformFall    tya                             ;save offset for other platform to stack
d5bc: 48                           pha
d5bd: 20 6b bf                     jsr     MoveFallingPlatform     ;make current platform fall
d5c0: 68                           pla
d5c1: aa                           tax                             ;pull offset from stack and save to X
d5c2: 20 6b bf                     jsr     MoveFallingPlatform     ;make other platform fall
d5c5: a6 08                        ldx     ObjectOffset
d5c7: bd a2 03                     lda     PlatformCollisionFlag,x ;if player not standing on either platform,
d5ca: 30 04                        bmi     ExPF                    ; skip this part
d5cc: aa                           tax                             ;transfer collision flag offset as offset to X
d5cd: 20 21 dc                     jsr     PositionPlayerOnVPlat   ; and position player appropriately
d5d0: a6 08        ExPF            ldx     ObjectOffset            ;get enemy object buffer offset and leave
d5d2: 60                           rts

                   ; -----------------------------------------------------------------------------
d5d3: b5 a0        YMovingPlatform lda     Enemy_Y_Speed,x         ;if platform moving up or down, skip ahead to
d5d5: 1d 34 04                     ora     Enemy_Y_MoveForce,x     ; check on other position
d5d8: d0 15                        bne     ChkYCenterPos
d5da: 9d 17 04                     sta     Enemy_YMF_Dummy,x       ;initialize dummy variable
d5dd: b5 cf                        lda     Enemy_Y_Position,x
d5df: dd 01 04                     cmp     YPlatformTopYPos,x      ;if current vertical position => top position, branch
d5e2: b0 0b                        bcs     ChkYCenterPos           ; ahead of all this
d5e4: a5 09                        lda     FrameCounter
d5e6: 29 07                        and     #%00000111              ;check for every eighth frame
d5e8: d0 02                        bne     SkipIY
d5ea: f6 cf                        inc     Enemy_Y_Position,x      ;increase vertical position every eighth frame
d5ec: 4c fe d5     SkipIY          jmp     ChkYPCollision          ;skip ahead to last part

d5ef: b5 cf        ChkYCenterPos   lda     Enemy_Y_Position,x      ;if current vertical position < central position, branch
d5f1: d5 58                        cmp     YPlatformCenterYPos,x   ; to slow ascent/move downwards
d5f3: 90 06                        bcc     YMDown
d5f5: 20 b7 bf                     jsr     MovePlatformUp          ;otherwise start slowing descent/moving upwards
d5f8: 4c fe d5                     jmp     ChkYPCollision

d5fb: 20 b4 bf     YMDown          jsr     MovePlatformDown        ;start slowing ascent/moving downwards
d5fe: bd a2 03     ChkYPCollision  lda     HammerThrowingTimer,x   ;if collision flag not set here, branch
d601: 30 03                        bmi     ExYPl                   ; to leave
d603: 20 21 dc                     jsr     PositionPlayerOnVPlat   ;otherwise position player appropriately
d606: 60           ExYPl           rts                             ;leave

                   ; -----------------------------------------------------------------------------
                   ; $00 - used as adder to position player hotizontally
d607: a9 0e        XMovingPlatform lda     #$0e                    ;load preset maximum value for secondary counter
d609: 20 47 cb                     jsr     XMoveCntr_Platform      ;do a sub to increment counters for movement
d60c: 20 66 cb                     jsr     MoveWithXMCntrs         ;do a sub to move platform accordingly, and return value
d60f: bd a2 03                     lda     PlatformCollisionFlag,x ;if no collision with player,
d612: 30 1c                        bmi     ExXMP                   ; branch ahead to leave
                   PositionPlayerOnHPlat
d614: a5 86                        lda     Player_X_Position
d616: 18                           clc                             ;add saved value from second subroutine to
d617: 65 00                        adc     $00                     ; current player's position to position
d619: 85 86                        sta     Player_X_Position       ; player accordingly in horizontal position
d61b: a5 6d                        lda     Player_PageLoc          ;get player's page location
d61d: a4 00                        ldy     $00                     ;check to see if saved value here is positive or negative
d61f: 30 05                        bmi     PPHSubt                 ;if negative, branch to subtract
d621: 69 00                        adc     #$00                    ;otherwise add carry to page location
d623: 4c 28 d6                     jmp     SetPVar                 ;jump to skip subtraction

d626: e9 00        PPHSubt         sbc     #$00                    ;subtract borrow from page location
d628: 85 6d        SetPVar         sta     Player_PageLoc          ;save result to player's page location
d62a: 8c a1 03                     sty     Platform_X_Scroll       ;put saved value from second sub here to be used later
d62d: 20 21 dc                     jsr     PositionPlayerOnVPlat   ;position player vertically and appropriately
d630: 60           ExXMP           rts                             ;and we are done here

                   ; -----------------------------------------------------------------------------
d631: bd a2 03     DropPlatform    lda     PlatformCollisionFlag,x ;if no collision between platform and player
d634: 30 06                        bmi     ExDPl                   ; occurred, just leave without moving anything
d636: 20 88 bf                     jsr     MoveDropPlatform        ;otherwise do a sub to move platform down very quickly
d639: 20 21 dc                     jsr     PositionPlayerOnVPlat   ;do a sub to position player appropriately
d63c: 60           ExDPl           rts                             ;leave

                   ; -----------------------------------------------------------------------------
                   ; $00 - residual value from sub
d63d: 20 02 bf     RightPlatform   jsr     MoveEnemyHorizontally   ;move platform with current horizontal speed, if any
d640: 85 00                        sta     $00                     ;store saved value here (residual code)
d642: bd a2 03                     lda     PlatformCollisionFlag,x ;check collision flag, if no collision between player
d645: 30 07                        bmi     ExRPl                   ; and platform, branch ahead, leave speed unaltered
d647: a9 10                        lda     #$10
d649: 95 58                        sta     Enemy_X_Speed,x         ;otherwise set new speed (gets moving if motionless)
d64b: 20 14 d6                     jsr     PositionPlayerOnHPlat   ;use saved value from earlier sub to position player
d64e: 60           ExRPl           rts                             ;then leave

                   ; -----------------------------------------------------------------------------
                   MoveLargeLiftPlat
d64f: 20 5b d6                     jsr     MoveLiftPlatforms       ;execute common to all large and small lift platforms
d652: 4c fe d5                     jmp     ChkYPCollision          ;branch to position player correctly

                   MoveSmallPlatform
d655: 20 5b d6                     jsr     MoveLiftPlatforms       ;execute common to all large and small lift platforms
d658: 4c 71 d6                     jmp     ChkSmallPlatCollision   ;branch to position player correctly

                   MoveLiftPlatforms
d65b: ad 47 07                     lda     TimerControl            ;if master timer control set, skip all of this
d65e: d0 19                        bne     ExLiftP                 ; and branch to leave
d660: bd 17 04                     lda     Enemy_YMF_Dummy,x
d663: 18                           clc                             ;add contents of movement amount to whatever's here
d664: 7d 34 04                     adc     Enemy_Y_MoveForce,x
d667: 9d 17 04                     sta     Enemy_YMF_Dummy,x
d66a: b5 cf                        lda     Enemy_Y_Position,x      ;add whatever vertical speed is set to current
d66c: 75 a0                        adc     Enemy_Y_Speed,x         ; vertical position plus carry to move up or down
d66e: 95 cf                        sta     Enemy_Y_Position,x      ; and then leave
d670: 60                           rts

                   ChkSmallPlatCollision
d671: bd a2 03                     lda     PlatformCollisionFlag,x ;get bounding box counter saved in collision flag
d674: f0 03                        beq     ExLiftP                 ;if none found, leave player position alone
d676: 20 19 dc                     jsr     PositionPlayerOnS_Plat  ;use to position player correctly
d679: 60           ExLiftP         rts                             ;then leave

                   ; -----------------------------------------------------------------------------
                   ; $00 - page location of extended left boundary
                   ; $01 - extended left boundary position
                   ; $02 - page location of extended right boundary
                   ; $03 - extended right boundary position
                   OffscreenBoundsCheck
d67a: b5 16                        lda     Enemy_ID,x              ;check for cheep-cheep object
d67c: c9 14                        cmp     #FlyingCheepCheep       ;branch to leave if found
d67e: f0 55                        beq     ExScrnBd
d680: ad 1c 07                     lda     ScreenLeft_X_Pos        ;get horizontal coordinate for left side of screen
d683: b4 16                        ldy     Enemy_ID,x
d685: c0 05                        cpy     #HammerBro              ;check for hammer bro object
d687: f0 04                        beq     LimitB
d689: c0 0d                        cpy     #PiranhaPlant           ;check for piranha plant object
d68b: d0 02                        bne     ExtendLB                ;these two will be erased sooner than others if too far left
d68d: 69 38        LimitB          adc     #56                     ;add 56 pixels to coordinate if hammer bro or piranha plant
d68f: e9 48        ExtendLB        sbc     #72                     ;subtract 72 pixels regardless of enemy object
d691: 85 01                        sta     $01                     ;store result here
d693: ad 1a 07                     lda     ScreenLeft_PageLoc
d696: e9 00                        sbc     #$00                    ;subtract borrow from page location of left side
d698: 85 00                        sta     $00                     ;store result here
d69a: ad 1d 07                     lda     ScreenRight_X_Pos       ;add 72 pixels to the right side horizontal coordinate
d69d: 69 48                        adc     #72
d69f: 85 03                        sta     $03                     ;store result here
d6a1: ad 1b 07                     lda     ScreenRight_PageLoc
d6a4: 69 00                        adc     #$00                    ;then add the carry to the page location
d6a6: 85 02                        sta     $02                     ;and store result here
d6a8: b5 87                        lda     Enemy_X_Position,x      ;compare horizontal coordinate of the enemy object
d6aa: c5 01                        cmp     $01                     ; to modified horizontal left edge coordinate to get carry
d6ac: b5 6e                        lda     Enemy_PageLoc,x
d6ae: e5 00                        sbc     $00                     ;then subtract it from the page coordinate of the enemy object
d6b0: 30 20                        bmi     TooFar                  ;if enemy object is too far left, branch to erase it
d6b2: b5 87                        lda     Enemy_X_Position,x      ;compare horizontal coordinate of the enemy object
d6b4: c5 03                        cmp     $03                     ;to modified horizontal right edge coordinate to get carry
d6b6: b5 6e                        lda     Enemy_PageLoc,x
d6b8: e5 02                        sbc     $02                     ;then subtract it from the page coordinate of the enemy object
d6ba: 30 19                        bmi     ExScrnBd                ;if enemy object is on the screen, leave, do not erase enemy
d6bc: b5 1e                        lda     Enemy_State,x           ;if at this point, enemy is offscreen to the right, so check
d6be: c9 05                        cmp     #HammerBro              ;if in state used by spiny's egg, do not erase
d6c0: f0 13                        beq     ExScrnBd
d6c2: c0 0d                        cpy     #PiranhaPlant           ;if piranha plant, do not erase
d6c4: f0 0f                        beq     ExScrnBd
d6c6: c0 30                        cpy     #FlagpoleFlagObject     ;if flagpole flag, do not erase
d6c8: f0 0b                        beq     ExScrnBd
d6ca: c0 31                        cpy     #StarFlagObject         ;if star flag, do not erase
d6cc: f0 07                        beq     ExScrnBd
d6ce: c0 32                        cpy     #JumpspringObject       ;if jumpspring, do not erase
d6d0: f0 03                        beq     ExScrnBd                ;erase all others too far to the right
d6d2: 20 98 c9     TooFar          jsr     EraseEnemyObject        ;erase object if necessary
d6d5: 60           ExScrnBd        rts                             ;leave

                   ; -----------------------------------------------------------------------------
                   ; some unused space
d6d6: ff ff ff                     .bulk   $ff,$ff,$ff

                   ; -----------------------------------------------------------------------------
                   ; $01 - enemy buffer offset
                   FireballEnemyCollision
d6d9: b5 24                        lda     Fireball_State,x        ;check to see if fireball state is set at all
d6db: f0 56                        beq     ExitFBallEnemy          ;branch to leave if not
d6dd: 0a                           asl     A
d6de: b0 53                        bcs     ExitFBallEnemy          ;branch to leave also if d7 in state is set
d6e0: a5 09                        lda     FrameCounter
d6e2: 4a                           lsr     A                       ;get LSB of frame counter
d6e3: b0 4e                        bcs     ExitFBallEnemy          ;branch to leave if set (do routine every other frame)
d6e5: 8a                           txa
d6e6: 0a                           asl     A                       ;multiply fireball offset by four
d6e7: 0a                           asl     A
d6e8: 18                           clc
d6e9: 69 1c                        adc     #$1c                    ;then add $1c or 28 bytes to it
d6eb: a8                           tay                             ; to use fireball's bounding box coordinates 
d6ec: a2 04                        ldx     #$04
                   FireballEnemyCDLoop
d6ee: 86 01                        stx     $01                     ;store enemy object offset here
d6f0: 98                           tya
d6f1: 48                           pha                             ;push fireball offset to the stack
d6f2: b5 1e                        lda     Enemy_State,x
d6f4: 29 20                        and     #%00100000              ;check to see if d5 is set in enemy state
d6f6: d0 34                        bne     NoFToECol               ;if so, skip to next enemy slot
d6f8: b5 0f                        lda     Enemy_Flag,x            ;check to see if buffer flag is set
d6fa: f0 30                        beq     NoFToECol               ;if not, skip to next enemy slot
d6fc: b5 16                        lda     Enemy_ID,x              ;check enemy identifier
d6fe: c9 24                        cmp     #$24
d700: 90 04                        bcc     GoombaDie               ;if < $24, branch to check further
d702: c9 2b                        cmp     #$2b
d704: 90 26                        bcc     NoFToECol               ;if in range $24-$2a, skip to next enemy slot
d706: c9 06        GoombaDie       cmp     #Goomba                 ;check for goomba identifier
d708: d0 06                        bne     NoGoomba                ;if not found, continue with code
d70a: b5 1e                        lda     Enemy_State,x           ;otherwise check for defeated state
d70c: c9 02                        cmp     #$02                    ;if stomped or otherwise defeated,
d70e: b0 1c                        bcs     NoFToECol               ; skip to next enemy slot
d710: bd d8 03     NoGoomba        lda     EnemyOffscrBitsMasked,x ;if any masked offscreen bits set,
d713: d0 17                        bne     NoFToECol               ; skip to next enemy slot
d715: 8a                           txa
d716: 0a                           asl     A                       ;otherwise multiply enemy offset by four
d717: 0a                           asl     A
d718: 18                           clc
d719: 69 04                        adc     #$04                    ;add 4 bytes to it
d71b: aa                           tax                             ;to use enemy's bounding box coordinates
d71c: 20 27 e3                     jsr     SprObjectCollisionCore  ;do fireball-to-enemy collision detection
d71f: a6 08                        ldx     ObjectOffset            ;return fireball's original offset
d721: 90 09                        bcc     NoFToECol               ;if carry clear, no collision, thus do next enemy slot
d723: a9 80                        lda     #%10000000
d725: 95 24                        sta     Fireball_State,x        ;set d7 in enemy state
d727: a6 01                        ldx     $01                     ;get enemy offset
d729: 20 3e d7                     jsr     HandleEnemyFBallCol     ;jump to handle fireball to enemy collision
d72c: 68           NoFToECol       pla                             ;pull fireball offset from stack
d72d: a8                           tay                             ;put it in Y
d72e: a6 01                        ldx     $01                     ;get enemy object offset
d730: ca                           dex                             ;decrement it
d731: 10 bb                        bpl     FireballEnemyCDLoop     ;loop back until collision detection done on all enemies
d733: a6 08        ExitFBallEnemy  ldx     ObjectOffset            ;get original fireball offset and leave
d735: 60                           rts

                   BowserIdentities
d736: 06                           .dd1    Goomba
d737: 00                           .dd1    GreenKoopa
d738: 02                           .dd1    BuzzyBeetle
d739: 12                           .dd1    Spiny
d73a: 11                           .dd1    Lakitu
d73b: 07                           .dd1    Bloober
d73c: 05                           .dd1    HammerBro
d73d: 2d                           .dd1    Bowser

                   HandleEnemyFBallCol
d73e: 20 52 f1                     jsr     RelativeEnemyPosition   ;get relative coordinate of enemy
d741: a6 01                        ldx     $01                     ;get current enemy object offset
d743: b5 0f                        lda     Enemy_Flag,x            ;check buffer flag for d7 set
d745: 10 0b                        bpl     ChkBuzzyBeetle          ;branch if not set to continue
d747: 29 0f                        and     #%00001111              ;otherwise mask out high nybble and
d749: aa                           tax                             ; use low nybble as enemy offset
d74a: b5 16                        lda     Enemy_ID,x
d74c: c9 2d                        cmp     #Bowser                 ;check enemy identifier for bowser
d74e: f0 0c                        beq     HurtBowser              ;branch if found
d750: a6 01                        ldx     $01                     ;otherwise retrieve current enemy offset
d752: b5 16        ChkBuzzyBeetle  lda     Enemy_ID,x
d754: c9 02                        cmp     #BuzzyBeetle            ;check for buzzy beetle
d756: f0 6b                        beq     ExHCF                   ;branch if found to leave (buzzy beetles fireproof)
d758: c9 2d                        cmp     #Bowser                 ;check for bowser one more time (necessary if d7 of flag was clear)
d75a: d0 2d                        bne     ChkOtherEnemies         ;if not found, branch to check other enemies
d75c: ce 83 04     HurtBowser      dec     BowserHitPoints         ;decrement bowser's hit points
d75f: d0 62                        bne     ExHCF                   ;if bowser still has hit points, branch to leave
d761: 20 63 c3                     jsr     InitVStf                ;otherwise do sub to init vertical speed and movement force
d764: 95 58                        sta     Enemy_X_Speed,x         ;initialize horizontal speed
d766: 8d cb 06                     sta     EnemyFrenzyBuffer       ;init enemy frenzy buffer
d769: a9 fe                        lda     #$fe
d76b: 95 a0                        sta     Enemy_Y_Speed,x         ;set vertical speed to make defeated bowser jump a little
d76d: ac 5f 07                     ldy     WorldNumber             ;use world number as offset
d770: b9 36 d7                     lda     BowserIdentities,y      ;get enemy identifier to replace bowser with
d773: 95 16                        sta     Enemy_ID,x              ;set as new enemy identifier
d775: a9 20                        lda     #$20                    ;set A to use starting value for state
d777: c0 03                        cpy     #$03                    ;check to see if using offset of 3 or more
d779: b0 02                        bcs     SetDBSte                ;branch if so
d77b: 09 03                        ora     #$03                    ;otherwise add 3 to enemy state
d77d: 95 1e        SetDBSte        sta     Enemy_State,x           ;set defeated enemy state
d77f: a9 80                        lda     #Sfx_BowserFall
d781: 85 fe                        sta     Square2SoundQueue       ;load bowser defeat sound
d783: a6 01                        ldx     $01                     ;get enemy offset
d785: a9 09                        lda     #$09                    ;award 5000 points to player for defeating bowser
d787: d0 33                        bne     EnemySmackCore          ;unconditional branch to award points

d789: c9 08        ChkOtherEnemies cmp     #BulletBill_FrenzyVar
d78b: f0 36                        beq     ExHCF                   ;branch to leave if bullet bill (frenzy variant)
d78d: c9 0c                        cmp     #Podoboo
d78f: f0 32                        beq     ExHCF                   ;branch to leave if podoboo
d791: c9 15                        cmp     #$15
d793: b0 2e                        bcs     ExHCF                   ;branch to leave if identifier => $15
                   ShellOrBlockDefeat
d795: b5 16                        lda     Enemy_ID,x              ;check for piranha plant
d797: c9 0d                        cmp     #PiranhaPlant
d799: d0 06                        bne     StnE                    ;branch if not found
d79b: b5 cf                        lda     Enemy_Y_Position,x
d79d: 69 18                        adc     #$18                    ;add 24 pixels to enemy object's vertical position
d79f: 95 cf                        sta     Enemy_Y_Position,x
d7a1: 20 1b e0     StnE            jsr     ChkToStunEnemies        ;do yet another sub
d7a4: b5 1e                        lda     Enemy_State,x
d7a6: 29 1f                        and     #%00011111              ;mask out 2 MSB of enemy object's state
d7a8: 09 20                        ora     #%00100000              ;set d5 to defeat enemy and save as new state
d7aa: 95 1e                        sta     Enemy_State,x
d7ac: a9 02                        lda     #$02                    ;award 200 points by default
d7ae: b4 16                        ldy     Enemy_ID,x              ;check for hammer bro
d7b0: c0 05                        cpy     #HammerBro
d7b2: d0 02                        bne     GoombaPoints            ;branch if not found
d7b4: a9 06                        lda     #$06                    ;award 1000 points for hammer bro
d7b6: c0 06        GoombaPoints    cpy     #Goomba                 ;check for goomba
d7b8: d0 02                        bne     EnemySmackCore          ;branch if not found
d7ba: a9 01                        lda     #$01                    ;award 100 points for goomba
d7bc: 20 11 da     EnemySmackCore  jsr     SetupFloateyNumber      ;update necessary score variables
d7bf: a9 08                        lda     #Sfx_EnemySmack         ;play smack enemy sound
d7c1: 85 ff                        sta     Square1SoundQueue
d7c3: 60           ExHCF           rts                             ;and now let's leave

                   ; -----------------------------------------------------------------------------
                   PlayerHammerCollision
d7c4: a5 09                        lda     FrameCounter            ;get frame counter
d7c6: 4a                           lsr     A                       ;shift d0 into carry
d7c7: 90 36                        bcc     ExPHC                   ;branch to leave if d0 not set to execute every other frame
d7c9: ad 47 07                     lda     TimerControl            ;if either master timer control
d7cc: 0d d6 03                     ora     Misc_OffscreenBits      ; or any offscreen bits for hammer are set,
d7cf: d0 2e                        bne     ExPHC                   ; branch to leave
d7d1: 8a                           txa
d7d2: 0a                           asl     A                       ;multiply misc object offset by four
d7d3: 0a                           asl     A
d7d4: 18                           clc
d7d5: 69 24                        adc     #$24                    ;add 36 or $24 bytes to get proper offset
d7d7: a8                           tay                             ;for misc object bounding box coordinates
d7d8: 20 25 e3                     jsr     PlayerCollisionCore     ;do player-to-hammer collision detection
d7db: a6 08                        ldx     ObjectOffset            ;get misc object offset
d7dd: 90 1b                        bcc     ClHCol                  ;if no collision, then branch
d7df: bd be 06                     lda     Misc_Collision_Flag,x   ;otherwise read collision flag
d7e2: d0 1b                        bne     ExPHC                   ;if collision flag already set, branch to leave
d7e4: a9 01                        lda     #$01
d7e6: 9d be 06                     sta     Misc_Collision_Flag,x   ;otherwise set collision flag now
d7e9: b5 64                        lda     Misc_X_Speed,x
d7eb: 49 ff                        eor     #$ff                    ;get two's compliment of
d7ed: 18                           clc                             ; hammer's horizontal speed
d7ee: 69 01                        adc     #$01
d7f0: 95 64                        sta     Misc_X_Speed,x          ;set to send hammer flying the opposite direction
d7f2: ad 9f 07                     lda     StarInvincibleTimer     ;if star mario invincibility timer set,
d7f5: d0 08                        bne     ExPHC                   ; branch to leave
d7f7: 4c 2c d9                     jmp     InjurePlayer            ;otherwise jump to hurt player, do not return

d7fa: a9 00        ClHCol          lda     #$00                    ;clear collision flag
d7fc: 9d be 06                     sta     Misc_Collision_Flag,x
d7ff: 60           ExPHC           rts

                   ; -----------------------------------------------------------------------------
                   HandlePowerUpCollision
d800: 20 98 c9                     jsr     EraseEnemyObject        ;erase the power-up object
d803: a9 06                        lda     #$06
d805: 20 11 da                     jsr     SetupFloateyNumber      ;award 1000 points to player by default
d808: a9 20                        lda     #Sfx_PowerUpGrab
d80a: 85 fe                        sta     Square2SoundQueue       ;play the power-up sound
d80c: a5 39                        lda     PowerUpType             ;check power-up type
d80e: c9 02                        cmp     #$02
d810: 90 0e                        bcc     Shroom_Flower_PUp       ;if mushroom or fire flower, branch
d812: c9 03                        cmp     #$03
d814: f0 24                        beq     SetFor1Up               ;if 1-up mushroom, branch
d816: a9 23                        lda     #$23                    ;otherwise set star mario invincibility
d818: 8d 9f 07                     sta     StarInvincibleTimer     ; timer, and load the star mario music
d81b: a9 40                        lda     #StarPowerMusic         ; into the area music queue, then leave
d81d: 85 fb                        sta     AreaMusicQueue
d81f: 60                           rts

                   Shroom_Flower_PUp
d820: ad 56 07                     lda     PlayerStatus            ;if player status = small, branch
d823: f0 1b                        beq     UpToSuper
d825: c9 01                        cmp     #$01                    ;if player status not super, leave
d827: d0 23                        bne     NoPUp
d829: a6 08                        ldx     ObjectOffset            ;get enemy offset, not necessary
d82b: a9 02                        lda     #$02                    ;set player status to fiery
d82d: 8d 56 07                     sta     PlayerStatus
d830: 20 f1 85                     jsr     GetPlayerColors         ;run sub to change colors of player
d833: a6 08                        ldx     ObjectOffset            ;get enemy offset again, and again not necessary
d835: a9 0c                        lda     #$0c                    ;set value to be used by subroutine tree (fiery)
d837: 4c 47 d8                     jmp     UpToFiery               ;jump to set values accordingly

d83a: a9 0b        SetFor1Up       lda     #$0b                    ;change 1000 points into 1-up instead
d83c: 9d 10 01                     sta     FloateyNum_Control,x    ; and then leave
d83f: 60                           rts

d840: a9 01        UpToSuper       lda     #$01                    ;set player status to super
d842: 8d 56 07                     sta     PlayerStatus
d845: a9 09                        lda     #$09                    ;set value to be used by subroutine tree (super)
d847: a0 00        UpToFiery       ldy     #$00                    ;set value to be used as new player state
d849: 20 48 d9                     jsr     SetPRout                ;set values to stop certain things in motion
d84c: 60           NoPUp           rts

                   ; -----------------------------------------------------------------------------
                   ResidualXSpdData
d84d: 18 e8                        .bulk   $18,$e8
                   KickedShellXSpdData
d84f: 30 d0                        .bulk   $30,$d0
                   DemotedKoopaXSpdData
d851: 08 f8                        .bulk   $08,$f8

                   PlayerEnemyCollision
d853: a5 09                        lda     FrameCounter            ;check counter for d0 set
d855: 4a                           lsr     A
d856: b0 f4                        bcs     NoPUp                   ;if set, branch to leave
d858: 20 41 dc                     jsr     CheckPlayerVertical     ;if player object is completely offscreen or
d85b: b0 23                        bcs     NoPECol                 ; if down past 224th pixel row, branch to leave
d85d: bd d8 03                     lda     EnemyOffscrBitsMasked,x ;if current enemy is offscreen by any amount,
d860: d0 1e                        bne     NoPECol                 ; go ahead and branch to leave
d862: a5 0e                        lda     GameEngineSubroutine
d864: c9 08                        cmp     #$08                    ;if not set to run player control routine
d866: d0 18                        bne     NoPECol                 ; on next frame, branch to leave
d868: b5 1e                        lda     Enemy_State,x
d86a: 29 20                        and     #%00100000              ;if enemy state has d5 set, branch to leave
d86c: d0 12                        bne     NoPECol
d86e: 20 52 dc                     jsr     GetEnemyBoundBoxOfs     ;get bounding box offset for current enemy object
d871: 20 25 e3                     jsr     PlayerCollisionCore     ;do collision detection on player vs. enemy
d874: a6 08                        ldx     ObjectOffset            ;get enemy object buffer offset
d876: b0 09                        bcs     ChkForPUpCollision      ;if collision, branch past this part here
d878: bd 91 04                     lda     Enemy_CollisionBits,x
d87b: 29 fe                        and     #%11111110              ;otherwise, clear d0 of current enemy object's
d87d: 9d 91 04                     sta     Enemy_CollisionBits,x   ; collision bit
d880: 60           NoPECol         rts

                   ChkForPUpCollision
d881: b4 16                        ldy     Enemy_ID,x
d883: c0 2e                        cpy     #PowerUpObject          ;check for power-up object
d885: d0 03                        bne     EColl                   ;if not found, branch to next part
d887: 4c 00 d8                     jmp     HandlePowerUpCollision  ;otherwise, unconditional jump backwards

d88a: ad 9f 07     EColl           lda     StarInvincibleTimer     ;if star mario invincibility timer expired,
d88d: f0 06                        beq     HandlePECollisions      ; perform task here, otherwise kill enemy like
d88f: 4c 95 d7                     jmp     ShellOrBlockDefeat      ; hit with a shell, or from beneath

                   KickedShellPtsData
d892: 0a 06 04                     .bulk   $0a,$06,$04

                   HandlePECollisions
d895: bd 91 04                     lda     Enemy_CollisionBits,x   ;check enemy collision bits for d0 set
d898: 29 01                        and     #%00000001              ;or for being offscreen at all
d89a: 1d d8 03                     ora     EnemyOffscrBitsMasked,x
d89d: d0 59                        bne     ExPEC                   ;branch to leave if either is true
d89f: a9 01                        lda     #$01
d8a1: 1d 91 04                     ora     Enemy_CollisionBits,x   ;otherwise set d0 now
d8a4: 9d 91 04                     sta     Enemy_CollisionBits,x
d8a7: c0 12                        cpy     #Spiny                  ;branch if spiny
d8a9: f0 4e                        beq     ChkForPlayerInjury
d8ab: c0 0d                        cpy     #PiranhaPlant           ;branch if piranha plant
d8ad: f0 7d                        beq     InjurePlayer
d8af: c0 0c                        cpy     #Podoboo                ;branch if podoboo
d8b1: f0 79                        beq     InjurePlayer
d8b3: c0 33                        cpy     #BulletBill_CannonVar   ;branch if bullet bill
d8b5: f0 42                        beq     ChkForPlayerInjury
d8b7: c0 15                        cpy     #$15                    ;branch if object => $15
d8b9: b0 71                        bcs     InjurePlayer
d8bb: ad 4e 07                     lda     AreaType                ;branch if water type level
d8be: f0 6c                        beq     InjurePlayer
d8c0: b5 1e                        lda     Enemy_State,x           ;branch if d7 of enemy state was set
d8c2: 0a                           asl     A
d8c3: b0 34                        bcs     ChkForPlayerInjury
d8c5: b5 1e                        lda     Enemy_State,x           ;mask out all but 3 LSB of enemy state
d8c7: 29 07                        and     #%00000111
d8c9: c9 02                        cmp     #$02                    ;branch if enemy is in normal or falling state
d8cb: 90 2c                        bcc     ChkForPlayerInjury
d8cd: b5 16                        lda     Enemy_ID,x              ;branch to leave if goomba in defeated state
d8cf: c9 06                        cmp     #$06
d8d1: f0 25                        beq     ExPEC
d8d3: a9 08                        lda     #Sfx_EnemySmack         ;play smack enemy sound
d8d5: 85 ff                        sta     Square1SoundQueue
d8d7: b5 1e                        lda     Enemy_State,x           ;set d7 in enemy state, thus become moving shell
d8d9: 09 80                        ora     #%10000000
d8db: 95 1e                        sta     Enemy_State,x
d8dd: 20 05 da                     jsr     EnemyFacePlayer         ;set moving direction and get offset
d8e0: b9 4f d8                     lda     KickedShellXSpdData,y   ;load and set horizontal speed data with offset
d8e3: 95 58                        sta     Enemy_X_Speed,x
d8e5: a9 03                        lda     #$03                    ;add three to whatever the stomp counter contains
d8e7: 18                           clc                             ; to give points for kicking the shell
d8e8: 6d 84 04                     adc     StompChainCounter
d8eb: bc 96 07                     ldy     EnemyIntervalTimer,x    ;check shell enemy's timer
d8ee: c0 03                        cpy     #$03                    ;if above a certain point, branch using the points
d8f0: b0 03                        bcs     KSPts                   ; data obtained from the stomp counter + 3
d8f2: b9 92 d8                     lda     KickedShellPtsData,y    ;otherwise, set points based on proximity to timer expiration
d8f5: 20 11 da     KSPts           jsr     SetupFloateyNumber      ;set values for floatey number now
d8f8: 60           ExPEC           rts                             ;leave!!!

                   ChkForPlayerInjury
d8f9: a5 9f                        lda     Player_Y_Speed          ;check player's vertical speed
d8fb: 30 02                        bmi     ChkInj                  ;perform procedure below if player moving upwards
d8fd: d0 6a                        bne     EnemyStomped            ;or not at all, and branch elsewhere if moving downwards
d8ff: b5 16        ChkInj          lda     Enemy_ID,x              ;branch if enemy object < $07
d901: c9 07                        cmp     #Bloober
d903: 90 09                        bcc     ChkETmrs
d905: a5 ce                        lda     Player_Y_Position       ;add 12 pixels to player's vertical position
d907: 18                           clc
d908: 69 0c                        adc     #$0c
d90a: d5 cf                        cmp     Enemy_Y_Position,x      ;compare modified player's position to enemy's position
d90c: 90 5b                        bcc     EnemyStomped            ;branch if this player's position above (less than) enemy's
d90e: ad 91 07     ChkETmrs        lda     StompTimer              ;check stomp timer
d911: d0 56                        bne     EnemyStomped            ;branch if set
d913: ad 9e 07                     lda     InjuryTimer             ;check to see if injured invincibility timer still
d916: d0 3d                        bne     ExInjColRoutines        ;counting down, and branch elsewhere to leave if so
d918: ad ad 03                     lda     Player_Rel_XPos
d91b: cd ae 03                     cmp     Enemy_Rel_XPos          ;if player's relative position to the left of enemy's
d91e: 90 03                        bcc     TInjE                   ;relative position, branch here
d920: 4c f6 d9                     jmp     ChkEnemyFaceRight       ;otherwise do a jump here

d923: b5 46        TInjE           lda     Enemy_MovingDir,x       ;if enemy moving towards the left,
d925: c9 01                        cmp     #$01                    ; branch, otherwise do a jump here
d927: d0 03                        bne     InjurePlayer            ; to turn the enemy around
d929: 4c ff d9                     jmp     LInj

d92c: ad 9e 07     InjurePlayer    lda     InjuryTimer             ;check again to see if injured invincibility timer is
d92f: d0 24                        bne     ExInjColRoutines        ; at zero, and branch to leave if so
                   ; 
d931: ae 56 07     ForceInjury     ldx     PlayerStatus            ;check player's status
d934: f0 22                        beq     KillPlayer              ;branch if small
d936: 8d 56 07                     sta     PlayerStatus            ;otherwise set player's status to small
d939: a9 08                        lda     #$08
d93b: 8d 9e 07                     sta     InjuryTimer             ;set injured invincibility timer
d93e: 0a                           asl     A
d93f: 85 ff                        sta     Square1SoundQueue       ;play pipedown/injury sound
d941: 20 f1 85                     jsr     GetPlayerColors         ;change player's palette if necessary
d944: a9 0a                        lda     #$0a                    ;set subroutine to run on next frame
d946: a0 01        SetKRout        ldy     #$01                    ;set new player state
d948: 85 0e        SetPRout        sta     GameEngineSubroutine    ;load new value to run subroutine on next frame
d94a: 84 1d                        sty     Player_State            ;store new player state
d94c: a0 ff                        ldy     #$ff
d94e: 8c 47 07                     sty     TimerControl            ;set master timer control flag to halt timers
d951: c8                           iny
d952: 8c 75 07                     sty     ScrollAmount            ;initialize scroll speed
                   ExInjColRoutines
d955: a6 08                        ldx     ObjectOffset            ;get enemy offset and leave
d957: 60                           rts

d958: 86 57        KillPlayer      stx     Player_X_Speed          ;halt player's horizontal movement by initializing speed
d95a: e8                           inx
d95b: 86 fc                        stx     EventMusicQueue         ;set event music queue to death music
d95d: a9 fc                        lda     #$fc
d95f: 85 9f                        sta     Player_Y_Speed          ;set new vertical speed
d961: a9 0b                        lda     #$0b                    ;set subroutine to run on next frame
d963: d0 e1                        bne     SetKRout                ;branch to set player's state and other things

                   StompedEnemyPtsData
d965: 02 06 05 06                  .bulk   $02,$06,$05,$06

d969: b5 16        EnemyStomped    lda     Enemy_ID,x              ;check for spiny, branch to hurt player
d96b: c9 12                        cmp     #Spiny                  ; if found
d96d: f0 bd                        beq     InjurePlayer
d96f: a9 04                        lda     #Sfx_EnemyStomp         ;otherwise play stomp/swim sound
d971: 85 ff                        sta     Square1SoundQueue
d973: b5 16                        lda     Enemy_ID,x
d975: a0 00                        ldy     #$00                    ;initialize points data offset for stomped enemies
d977: c9 14                        cmp     #FlyingCheepCheep       ;branch for cheep-cheep
d979: f0 1b                        beq     EnemyStompedPts
d97b: c9 08                        cmp     #BulletBill_FrenzyVar   ;branch for either bullet bill object
d97d: f0 17                        beq     EnemyStompedPts
d97f: c9 33                        cmp     #BulletBill_CannonVar
d981: f0 13                        beq     EnemyStompedPts
d983: c9 0c                        cmp     #Podoboo                ;branch for podoboo (this branch is logically impossible
d985: f0 0f                        beq     EnemyStompedPts         ; for cpu to take due to earlier checking of podoboo)
d987: c8                           iny                             ;increment points data offset
d988: c9 05                        cmp     #HammerBro              ;branch for hammer bro
d98a: f0 0a                        beq     EnemyStompedPts
d98c: c8                           iny                             ;increment points data offset
d98d: c9 11                        cmp     #Lakitu                 ;branch for lakitu
d98f: f0 05                        beq     EnemyStompedPts
d991: c8                           iny                             ;increment points data offset
d992: c9 07                        cmp     #Bloober                ;branch if NOT bloober
d994: d0 1d                        bne     ChkForDemoteKoopa
d996: b9 65 d9     EnemyStompedPts lda     StompedEnemyPtsData,y   ;load points data using offset in Y
d999: 20 11 da                     jsr     SetupFloateyNumber      ;run sub to set floatey number controls
d99c: b5 46                        lda     Enemy_MovingDir,x
d99e: 48                           pha                             ;save enemy movement direction to stack
d99f: 20 2f e0                     jsr     SetStun                 ;run sub to kill enemy
d9a2: 68                           pla
d9a3: 95 46                        sta     Enemy_MovingDir,x       ;return enemy movement direction from stack
d9a5: a9 20                        lda     #%00100000
d9a7: 95 1e                        sta     Enemy_State,x           ;set d5 in enemy state
d9a9: 20 63 c3                     jsr     InitVStf                ;nullify vertical speed, physics-related thing,
d9ac: 95 58                        sta     Enemy_X_Speed,x         ; and horizontal speed
d9ae: a9 fd                        lda     #$fd                    ;set player's vertical speed, to give bounce
d9b0: 85 9f                        sta     Player_Y_Speed
d9b2: 60                           rts

                   ChkForDemoteKoopa
d9b3: c9 09                        cmp     #$09                    ;branch elsewhere if enemy object < $09
d9b5: 90 1d                        bcc     HandleStompedShellE
d9b7: 29 01                        and     #%00000001              ;demote koopa paratroopas to ordinary troopas
d9b9: 95 16                        sta     Enemy_ID,x
d9bb: a0 00                        ldy     #$00                    ;return enemy to normal state
d9bd: 94 1e                        sty     Enemy_State,x
d9bf: a9 03                        lda     #$03                    ;award 400 points to the player
d9c1: 20 11 da                     jsr     SetupFloateyNumber
d9c4: 20 63 c3                     jsr     InitVStf                ;nullify physics-related thing and vertical speed
d9c7: 20 05 da                     jsr     EnemyFacePlayer         ;turn enemy around if necessary
d9ca: b9 51 d8                     lda     DemotedKoopaXSpdData,y
d9cd: 95 58                        sta     Enemy_X_Speed,x         ;set appropriate moving speed based on direction
d9cf: 4c f1 d9                     jmp     SBnce                   ;then move onto something else

d9d2: 10 0b        RevivalRateData .bulk   $10,$0b

                   HandleStompedShellE
d9d4: a9 04                        lda     #$04                    ;set defeated state for enemy
d9d6: 95 1e                        sta     Enemy_State,x
d9d8: ee 84 04                     inc     StompChainCounter       ;increment the stomp counter
d9db: ad 84 04                     lda     StompChainCounter       ;add whatever is in the stomp counter
d9de: 18                           clc                             ; to whatever is in the stomp timer
d9df: 6d 91 07                     adc     StompTimer
d9e2: 20 11 da                     jsr     SetupFloateyNumber      ;award points accordingly
d9e5: ee 91 07                     inc     StompTimer              ;increment stomp timer of some sort
d9e8: ac 6a 07                     ldy     PrimaryHardMode         ;check primary hard mode flag
d9eb: b9 d2 d9                     lda     RevivalRateData,y       ;load timer setting according to flag
d9ee: 9d 96 07                     sta     EnemyIntervalTimer,x    ;set as enemy timer to revive stomped enemy
d9f1: a9 fc        SBnce           lda     #$fc                    ;set player's vertical speed for bounce
d9f3: 85 9f                        sta     Player_Y_Speed          ;and then leave!!!
d9f5: 60                           rts

                   ChkEnemyFaceRight
d9f6: b5 46                        lda     Enemy_MovingDir,x       ;check to see if enemy is moving to the right
d9f8: c9 01                        cmp     #$01
d9fa: d0 03                        bne     LInj                    ;if not, branch
d9fc: 4c 2c d9                     jmp     InjurePlayer            ;otherwise go back to hurt player

d9ff: 20 1c db     LInj            jsr     EnemyTurnAround         ;turn the enemy around, if necessary
da02: 4c 2c d9                     jmp     InjurePlayer            ;go back to hurt player

da05: a0 01        EnemyFacePlayer ldy     #$01                    ;set to move right by default
da07: 20 43 e1                     jsr     PlayerEnemyDiff         ;get horizontal difference between player and enemy
da0a: 10 01                        bpl     SFcRt                   ;if enemy is to the right of player, do not increment
da0c: c8                           iny                             ;otherwise, increment to set to move to the left
da0d: 94 46        SFcRt           sty     Enemy_MovingDir,x       ;set moving direction here
da0f: 88                           dey                             ;then decrement to use as a proper offset
da10: 60                           rts

                   SetupFloateyNumber
da11: 9d 10 01                     sta     FloateyNum_Control,x    ;set number of points control for floatey numbers
da14: a9 30                        lda     #$30
da16: 9d 2c 01                     sta     FloateyNum_Timer,x      ;set timer for floatey numbers
da19: b5 cf                        lda     Enemy_Y_Position,x
da1b: 9d 1e 01                     sta     FloateyNum_Y_Pos,x      ;set vertical coordinate
da1e: ad ae 03                     lda     Enemy_Rel_XPos
da21: 9d 17 01                     sta     FloateyNum_X_Pos,x      ;set horizontal coordinate and leave
da24: 60           ExSFN           rts

                   ; -----------------------------------------------------------------------------
                   ; $01 - used to hold enemy offset for second enemy
da25: 80           SetBitsMask     .dd1    %10000000
da26: 40                           .dd1    %01000000
da27: 20                           .dd1    %00100000
da28: 10                           .dd1    %00010000
da29: 08                           .dd1    %00001000
da2a: 04                           .dd1    %00000100
da2b: 02                           .dd1    %00000010
da2c: 7f           ClearBitsMask   .dd1    %01111111
da2d: bf                           .dd1    %10111111
da2e: df                           .dd1    %11011111
da2f: ef                           .dd1    %11101111
da30: f7                           .dd1    %11110111
da31: fb                           .dd1    %11111011
da32: fd                           .dd1    %11111101

                   EnemiesCollision
da33: a5 09                        lda     FrameCounter            ;check counter for d0 set
da35: 4a                           lsr     A
da36: 90 ec                        bcc     ExSFN                   ;if d0 not set, leave
da38: ad 4e 07                     lda     AreaType
da3b: f0 e7                        beq     ExSFN                   ;if water area type, leave
da3d: b5 16                        lda     Enemy_ID,x
da3f: c9 15                        cmp     #$15                    ;if enemy object => $15, branch to leave
da41: b0 6e                        bcs     ExitECRoutine
da43: c9 11                        cmp     #Lakitu                 ;if lakitu, branch to leave
da45: f0 6a                        beq     ExitECRoutine
da47: c9 0d                        cmp     #PiranhaPlant           ;if piranha plant, branch to leave
da49: f0 66                        beq     ExitECRoutine
da4b: bd d8 03                     lda     EnemyOffscrBitsMasked,x ;if masked offscreen bits nonzero, branch to leave
da4e: d0 61                        bne     ExitECRoutine
da50: 20 52 dc                     jsr     GetEnemyBoundBoxOfs     ;otherwise, do sub, get appropriate bounding box offset for
da53: ca                           dex                             ; first enemy we're going to compare, then decrement for second
da54: 30 5b                        bmi     ExitECRoutine           ;branch to leave if there are no other enemies
da56: 86 01        ECLoop          stx     $01                     ;save enemy object buffer offset for second enemy here
da58: 98                           tya                             ;save first enemy's bounding box offset to stack
da59: 48                           pha
da5a: b5 0f                        lda     Enemy_Flag,x            ;check enemy object enable flag
da5c: f0 4c                        beq     ReadyNextEnemy          ;branch if flag not set
da5e: b5 16                        lda     Enemy_ID,x
da60: c9 15                        cmp     #$15                    ;check for enemy object => $15
da62: b0 46                        bcs     ReadyNextEnemy          ;branch if true
da64: c9 11                        cmp     #Lakitu
da66: f0 42                        beq     ReadyNextEnemy          ;branch if enemy object is lakitu
da68: c9 0d                        cmp     #PiranhaPlant
da6a: f0 3e                        beq     ReadyNextEnemy          ;branch if enemy object is piranha plant
da6c: bd d8 03                     lda     EnemyOffscrBitsMasked,x
da6f: d0 39                        bne     ReadyNextEnemy          ;branch if masked offscreen bits set
da71: 8a                           txa                             ;get second enemy object's bounding box offset
da72: 0a                           asl     A                       ;multiply by four, then add four
da73: 0a                           asl     A
da74: 18                           clc
da75: 69 04                        adc     #$04
da77: aa                           tax                             ;use as new contents of X
da78: 20 27 e3                     jsr     SprObjectCollisionCore  ;do collision detection using the two enemies here
da7b: a6 08                        ldx     ObjectOffset            ;use first enemy offset for X
da7d: a4 01                        ldy     $01                     ;use second enemy offset for Y
da7f: 90 20                        bcc     NoEnemyCollision        ;if carry clear, no collision, branch ahead of this
da81: b5 1e                        lda     Enemy_State,x
da83: 19 1e 00                     ora     Enemy_State,y           ;check both enemy states for d7 set
da86: 29 80                        and     #%10000000
da88: d0 11                        bne     YesEC                   ;branch if at least one of them is set
da8a: b9 91 04                     lda     Enemy_CollisionBits,y   ;load first enemy's collision-related bits
da8d: 3d 25 da                     and     SetBitsMask,x           ;check to see if bit connected to second enemy is
da90: d0 18                        bne     ReadyNextEnemy          ; already set, and move onto next enemy slot if set
da92: b9 91 04                     lda     Enemy_CollisionBits,y
da95: 1d 25 da                     ora     SetBitsMask,x           ;if the bit is not set, set it now
da98: 99 91 04                     sta     Enemy_CollisionBits,y
da9b: 20 b4 da     YesEC           jsr     ProcEnemyCollisions     ;react according to the nature of collision
da9e: 4c aa da                     jmp     ReadyNextEnemy          ;move onto next enemy slot

                   NoEnemyCollision
daa1: b9 91 04                     lda     Enemy_CollisionBits,y   ;load first enemy's collision-related bits
daa4: 3d 2c da                     and     ClearBitsMask,x         ;clear bit connected to second enemy
daa7: 99 91 04                     sta     Enemy_CollisionBits,y   ;then move onto next enemy slot
daaa: 68           ReadyNextEnemy  pla                             ;get first enemy's bounding box offset from the stack
daab: a8                           tay                             ;use as Y again
daac: a6 01                        ldx     $01                     ;get and decrement second enemy's object buffer offset
daae: ca                           dex
daaf: 10 a5                        bpl     ECLoop                  ;loop until all enemy slots have been checked
dab1: a6 08        ExitECRoutine   ldx     ObjectOffset            ;get enemy object buffer offset
dab3: 60                           rts                             ;leave

                   ProcEnemyCollisions
dab4: b9 1e 00                     lda     Enemy_State,y           ;check both enemy states for d5 set
dab7: 15 1e                        ora     Enemy_State,x
dab9: 29 20                        and     #%00100000              ;if d5 is set in either state, or both, branch
dabb: d0 33                        bne     ExitProcessEColl        ; to leave and do nothing else at this point
dabd: b5 1e                        lda     Enemy_State,x
dabf: c9 06                        cmp     #$06                    ;if second enemy state < $06, branch elsewhere
dac1: 90 2e                        bcc     ProcSecondEnemyColl
dac3: b5 16                        lda     Enemy_ID,x              ;check second enemy identifier for hammer bro
dac5: c9 05                        cmp     #HammerBro              ;if hammer bro found in alt state, branch to leave
dac7: f0 27                        beq     ExitProcessEColl
dac9: b9 1e 00                     lda     Enemy_State,y           ;check first enemy state for d7 set
dacc: 0a                           asl     A
dacd: 90 0a                        bcc     ShellCollisions         ;branch if d7 is clear
dacf: a9 06                        lda     #$06
dad1: 20 11 da                     jsr     SetupFloateyNumber      ;award 1000 points for killing enemy
dad4: 20 95 d7                     jsr     ShellOrBlockDefeat      ; then kill enemy, then load
dad7: a4 01                        ldy     $01                     ; original offset of second enemy
dad9: 98           ShellCollisions tya                             ;move Y to X
dada: aa                           tax
dadb: 20 95 d7                     jsr     ShellOrBlockDefeat      ;kill second enemy
dade: a6 08                        ldx     ObjectOffset
dae0: bd 25 01                     lda     ShellChainCounter,x     ;get chain counter for shell
dae3: 18                           clc
dae4: 69 04                        adc     #$04                    ;add four to get appropriate point offset
dae6: a6 01                        ldx     $01
dae8: 20 11 da                     jsr     SetupFloateyNumber      ;award appropriate number of points for second enemy
daeb: a6 08                        ldx     ObjectOffset            ;load original offset of first enemy
daed: fe 25 01                     inc     ShellChainCounter,x     ;increment chain counter for additional enemies
                   ExitProcessEColl
daf0: 60                           rts                             ;leave!!!

                   ProcSecondEnemyColl
daf1: b9 1e 00                     lda     Enemy_State,y           ;if first enemy state < $06, branch elsewhere
daf4: c9 06                        cmp     #$06
daf6: 90 1d                        bcc     MoveEOfs
daf8: b9 16 00                     lda     Enemy_ID,y              ;check first enemy identifier for hammer bro
dafb: c9 05                        cmp     #HammerBro              ;if hammer bro found in alt state, branch to leave
dafd: f0 f1                        beq     ExitProcessEColl
daff: 20 95 d7                     jsr     ShellOrBlockDefeat      ;otherwise, kill first enemy
db02: a4 01                        ldy     $01
db04: b9 25 01                     lda     ShellChainCounter,y     ;get chain counter for shell
db07: 18                           clc
db08: 69 04                        adc     #$04                    ;add four to get appropriate point offset
db0a: a6 08                        ldx     ObjectOffset
db0c: 20 11 da                     jsr     SetupFloateyNumber      ;award appropriate number of points for first enemy
db0f: a6 01                        ldx     $01                     ;load original offset of second enemy
db11: fe 25 01                     inc     ShellChainCounter,x     ;increment chain counter for additional enemies
db14: 60                           rts                             ;leave!!!

db15: 98           MoveEOfs        tya                             ;move Y ($01) to X
db16: aa                           tax
db17: 20 1c db                     jsr     EnemyTurnAround         ;do the sub here using value from $01
db1a: a6 08                        ldx     ObjectOffset            ; then do it again using value from $08
                   ; 
db1c: b5 16        EnemyTurnAround lda     Enemy_ID,x              ;check for specific enemies
db1e: c9 0d                        cmp     #PiranhaPlant
db20: f0 22                        beq     ExTA                    ;if piranha plant, leave
db22: c9 11                        cmp     #Lakitu
db24: f0 1e                        beq     ExTA                    ;if lakitu, leave
db26: c9 05                        cmp     #HammerBro
db28: f0 1a                        beq     ExTA                    ;if hammer bro, leave
db2a: c9 12                        cmp     #Spiny
db2c: f0 08                        beq     RXSpd                   ;if spiny, turn it around
db2e: c9 0e                        cmp     #GreenParatroopaJump
db30: f0 04                        beq     RXSpd                   ;if green paratroopa, turn it around
db32: c9 07                        cmp     #$07
db34: b0 0e                        bcs     ExTA                    ;if any OTHER enemy object => $07, leave
db36: b5 58        RXSpd           lda     Enemy_X_Speed,x         ;load horizontal speed
db38: 49 ff                        eor     #$ff                    ;get two's compliment for horizontal speed
db3a: a8                           tay
db3b: c8                           iny
db3c: 94 58                        sty     Enemy_X_Speed,x         ;store as new horizontal speed
db3e: b5 46                        lda     Enemy_MovingDir,x
db40: 49 03                        eor     #%00000011              ;invert moving direction and store, then leave
db42: 95 46                        sta     Enemy_MovingDir,x       ;thus effectively turning the enemy around
db44: 60           ExTA            rts                             ;leave!!!

                   ; -----------------------------------------------------------------------------
                   ; $00 - vertical position of platform
                   LargePlatformCollision
db45: a9 ff                        lda     #$ff                    ;save value here
db47: 9d a2 03                     sta     HammerThrowingTimer,x
db4a: ad 47 07                     lda     TimerControl            ;check master timer control
db4d: d0 29                        bne     ExLPC                   ;if set, branch to leave
db4f: b5 1e                        lda     Enemy_State,x           ;if d7 set in object state,
db51: 30 25                        bmi     ExLPC                   ; branch to leave
db53: b5 16                        lda     Enemy_ID,x
db55: c9 24                        cmp     #$24                    ;check enemy object identifier for
db57: d0 06                        bne     ChkForPlayerC_LargeP    ;balance platform, branch if not found
db59: b5 1e                        lda     Enemy_State,x
db5b: aa                           tax                             ;set state as enemy offset here
db5c: 20 5f db                     jsr     ChkForPlayerC_LargeP    ;perform code with state offset, then original offset, in X
                   ; 
                   ChkForPlayerC_LargeP
db5f: 20 41 dc                     jsr     CheckPlayerVertical     ;figure out if player is below a certain point
db62: b0 14                        bcs     ExLPC                   ; or offscreen, branch to leave if true
db64: 8a                           txa
db65: 20 54 dc                     jsr     GetEnemyBoundBoxOfsArg  ;get bounding box offset in Y
db68: b5 cf                        lda     Enemy_Y_Position,x      ;store vertical coordinate in
db6a: 85 00                        sta     $00                     ; temp variable for now
db6c: 8a                           txa                             ;send offset we're on to the stack
db6d: 48                           pha
db6e: 20 25 e3                     jsr     PlayerCollisionCore     ;do player-to-platform collision detection
db71: 68                           pla                             ;retrieve offset from the stack
db72: aa                           tax
db73: 90 03                        bcc     ExLPC                   ;if no collision, branch to leave
db75: 20 bc db                     jsr     ProcLPlatCollisions     ;otherwise collision, perform sub
db78: a6 08        ExLPC           ldx     ObjectOffset            ;get enemy object buffer offset and leave
db7a: 60                           rts

                   ; -----------------------------------------------------------------------------
                   ; $00 - counter for bounding boxes
                   SmallPlatformCollision
db7b: ad 47 07                     lda     TimerControl            ;if master timer control set,
db7e: d0 37                        bne     ExSPC                   ; branch to leave
db80: 9d a2 03                     sta     PlatformCollisionFlag,x ;otherwise initialize collision flag
db83: 20 41 dc                     jsr     CheckPlayerVertical     ;do a sub to see if player is below a certain point
db86: b0 2f                        bcs     ExSPC                   ; or entirely offscreen, and branch to leave if true
db88: a9 02                        lda     #$02
db8a: 85 00                        sta     $00                     ;load counter here for 2 bounding boxes
                   ChkSmallPlatLoop
db8c: a6 08                        ldx     ObjectOffset            ;get enemy object offset
db8e: 20 52 dc                     jsr     GetEnemyBoundBoxOfs     ;get bounding box offset in Y
db91: 29 02                        and     #%00000010              ;if d1 of offscreen lower nybble bits was set
db93: d0 22                        bne     ExSPC                   ; then branch to leave
db95: b9 ad 04                     lda     BoundingBox_UL_YPos,y   ;check top of platform's bounding box for being
db98: c9 20                        cmp     #$20                    ; above a specific point
db9a: 90 05                        bcc     MoveBoundBox            ;if so, branch, don't do collision detection
db9c: 20 25 e3                     jsr     PlayerCollisionCore     ;otherwise, perform player-to-platform collision detection
db9f: b0 19                        bcs     ProcSPlatCollisions     ;skip ahead if collision
dba1: b9 ad 04     MoveBoundBox    lda     BoundingBox_UL_YPos,y   ;move bounding box vertical coordinates
dba4: 18                           clc                             ; 128 pixels downwards
dba5: 69 80                        adc     #$80
dba7: 99 ad 04                     sta     BoundingBox_UL_YPos,y
dbaa: b9 af 04                     lda     BoundingBox_DR_YPos,y
dbad: 18                           clc
dbae: 69 80                        adc     #$80
dbb0: 99 af 04                     sta     BoundingBox_DR_YPos,y
dbb3: c6 00                        dec     $00                     ;decrement counter we set earlier
dbb5: d0 d5                        bne     ChkSmallPlatLoop        ;loop back until both bounding boxes are checked
dbb7: a6 08        ExSPC           ldx     ObjectOffset            ;get enemy object buffer offset, then leave
dbb9: 60                           rts

                   ; -----------------------------------------------------------------------------
                   ProcSPlatCollisions
dbba: a6 08                        ldx     ObjectOffset            ;return enemy object buffer offset to X, then continue
                   ProcLPlatCollisions
dbbc: b9 af 04                     lda     BoundingBox_DR_YPos,y   ;get difference by subtracting the top
dbbf: 38                           sec                             ; of the player's bounding box from the bottom
dbc0: ed ad 04                     sbc     BoundingBox_UL_YPos     ; of the platform's bounding box
dbc3: c9 04                        cmp     #$04                    ;if difference too large or negative,
dbc5: b0 08                        bcs     ChkForTopCollision      ; branch, do not alter vertical speed of player
dbc7: a5 9f                        lda     Player_Y_Speed          ;check to see if player's vertical speed is moving down
dbc9: 10 04                        bpl     ChkForTopCollision      ;if so, don't mess with it
dbcb: a9 01                        lda     #$01                    ;otherwise, set vertical
dbcd: 85 9f                        sta     Player_Y_Speed          ;speed of player to kill jump
                   ChkForTopCollision
dbcf: ad af 04                     lda     BoundingBox_DR_YPos     ;get difference by subtracting the top
dbd2: 38                           sec                             ; of the platform's bounding box from the bottom
dbd3: f9 ad 04                     sbc     BoundingBox_UL_YPos,y   ; of the player's bounding box
dbd6: c9 06                        cmp     #$06
dbd8: b0 1b                        bcs     PlatformSideCollisions  ;if difference not close enough, skip all of this
dbda: a5 9f                        lda     Player_Y_Speed
dbdc: 30 17                        bmi     PlatformSideCollisions  ;if player's vertical speed moving upwards, skip this
dbde: a5 00                        lda     $00                     ;get saved bounding box counter from earlier
dbe0: b4 16                        ldy     Enemy_ID,x
dbe2: c0 2b                        cpy     #$2b                    ;if either of the two small platform objects are found,
dbe4: f0 05                        beq     SetCollisionFlag        ; regardless of which one, branch to use bounding box counter
dbe6: c0 2c                        cpy     #$2c                    ; as contents of collision flag
dbe8: f0 01                        beq     SetCollisionFlag
dbea: 8a                           txa                             ;otherwise use enemy object buffer offset
                   SetCollisionFlag
dbeb: a6 08                        ldx     ObjectOffset            ;get enemy object buffer offset
dbed: 9d a2 03                     sta     PlatformCollisionFlag,x ;save either bounding box counter or enemy offset here
dbf0: a9 00                        lda     #$00
dbf2: 85 1d                        sta     Player_State            ;set player state to normal then leave
dbf4: 60                           rts

                   PlatformSideCollisions
dbf5: a9 01                        lda     #$01                    ;set value here to indicate possible horizontal
dbf7: 85 00                        sta     $00                     ; collision on left side of platform
dbf9: ad ae 04                     lda     BoundingBox_DR_XPos     ;get difference by subtracting platform's left edge
dbfc: 38                           sec                             ; from player's right edge
dbfd: f9 ac 04                     sbc     BoundingBox_UL_XPos,y
dc00: c9 08                        cmp     #$08                    ;if difference close enough, skip all of this
dc02: 90 0d                        bcc     SideC
dc04: e6 00                        inc     $00                     ;otherwise increment value set here for right side collision
dc06: b9 ae 04                     lda     BoundingBox_DR_XPos,y   ;get difference by subtracting player's left edge
dc09: 18                           clc                             ; from platform's right edge
dc0a: ed ac 04                     sbc     BoundingBox_UL_XPos
dc0d: c9 09                        cmp     #$09                    ;if difference not close enough, skip subroutine
dc0f: b0 03                        bcs     NoSideC                 ; and instead branch to leave (no collision)
dc11: 20 4b df     SideC           jsr     ImpedePlayerMove        ;deal with horizontal collision
dc14: a6 08        NoSideC         ldx     ObjectOffset            ;return with enemy object buffer offset
dc16: 60                           rts

                   ; -----------------------------------------------------------------------------
                   PlayerPosSPlatData
dc17: 80 00                        .bulk   $80,$00

                   PositionPlayerOnS_Plat
dc19: a8                           tay                             ;use bounding box counter saved in collision flag
dc1a: b5 cf                        lda     Enemy_Y_Position,x      ; for offset
dc1c: 18                           clc                             ;add positioning data using offset to the vertical
dc1d: 79 16 dc                     adc     PlayerPosSPlatData-1,y  ; coordinate
dc20: 2c                           bit β–Ό   LCFB5                   ;BIT instruction opcode
                   ; 
                   PositionPlayerOnVPlat
dc21: b5 cf                        lda     Enemy_Y_Position,x      ;get vertical coordinate
dc23: a4 0e                        ldy     GameEngineSubroutine
dc25: c0 0b                        cpy     #$0b                    ;if certain routine being executed on this frame,
dc27: f0 17                        beq     ExPlPos                 ; skip all of this
dc29: b4 b6                        ldy     Enemy_Y_HighPos,x
dc2b: c0 01                        cpy     #$01                    ;if vertical high byte offscreen, skip this
dc2d: d0 11                        bne     ExPlPos
dc2f: 38                           sec                             ;subtract 32 pixels from vertical coordinate
dc30: e9 20                        sbc     #$20                    ; for the player object's height
dc32: 85 ce                        sta     Player_Y_Position       ;save as player's new vertical coordinate
dc34: 98                           tya
dc35: e9 00                        sbc     #$00                    ;subtract borrow and store as player's
dc37: 85 b5                        sta     Player_Y_HighPos        ; new vertical high byte
dc39: a9 00                        lda     #$00
dc3b: 85 9f                        sta     Player_Y_Speed          ;initialize vertical speed and low byte of force
dc3d: 8d 33 04                     sta     Player_Y_MoveForce      ; and then leave
dc40: 60           ExPlPos         rts

                   ; -----------------------------------------------------------------------------
                   CheckPlayerVertical
dc41: ad d0 03                     lda     Player_OffscreenBits    ;if player object is completely offscreen
dc44: c9 f0                        cmp     #$f0                    ; vertically, leave this routine
dc46: b0 09                        bcs     ExCPV
dc48: a4 b5                        ldy     Player_Y_HighPos        ;if player high vertical byte is not
dc4a: 88                           dey                             ; within the screen, leave this routine
dc4b: d0 04                        bne     ExCPV
dc4d: a5 ce                        lda     Player_Y_Position       ;if on the screen, check to see how far down
dc4f: c9 d0                        cmp     #$d0                    ; the player is vertically
dc51: 60           ExCPV           rts

                   ; -----------------------------------------------------------------------------
                   GetEnemyBoundBoxOfs
dc52: a5 08                        lda     ObjectOffset            ;get enemy object buffer offset
                   ; 
                   GetEnemyBoundBoxOfsArg
dc54: 0a                           asl     A                       ;multiply A by four, then add four
dc55: 0a                           asl     A                       ; to skip player's bounding box
dc56: 18                           clc
dc57: 69 04                        adc     #$04
dc59: a8                           tay                             ;send to Y
dc5a: ad d1 03                     lda     Enemy_OffscreenBits     ;get offscreen bits for enemy object
dc5d: 29 0f                        and     #%00001111              ;save low nybble
dc5f: c9 0f                        cmp     #%00001111              ;check for all bits set
dc61: 60                           rts

                   ; -----------------------------------------------------------------------------
                   ; $00-$01 - used to hold many values, essentially temp variables
                   ; $04 - holds lower nybble of vertical coordinate from block buffer routine
                   ; $eb - used to hold block buffer adder
                   PlayerBGUpperExtent
dc62: 20 10                        .bulk   $20,$10

                   PlayerBGCollision
dc64: ad 16 07                     lda     DisableCollisionDet     ;if collision detection disabled flag set,
dc67: d0 2e                        bne     ExPBGCol                ; branch to leave
dc69: a5 0e                        lda     GameEngineSubroutine
dc6b: c9 0b                        cmp     #$0b                    ;if running routine #11 or $0b
dc6d: f0 28                        beq     ExPBGCol                ;branch to leave
dc6f: c9 04                        cmp     #$04
dc71: 90 24                        bcc     ExPBGCol                ;if running routines $00-$03 branch to leave
dc73: a9 01                        lda     #$01                    ;load default player state for swimming
dc75: ac 04 07                     ldy     SwimmingFlag            ;if swimming flag set,
dc78: d0 0a                        bne     SetPSte                 ; branch ahead to set default state
dc7a: a5 1d                        lda     Player_State            ;if player in normal state,
dc7c: f0 04                        beq     SetFallS                ; branch to set default state for falling
dc7e: c9 03                        cmp     #$03
dc80: d0 04                        bne     ChkOnScr                ;if in any other state besides climbing, skip to next part
dc82: a9 02        SetFallS        lda     #$02                    ;load default player state for falling
dc84: 85 1d        SetPSte         sta     Player_State            ;set whatever player state is appropriate
dc86: a5 b5        ChkOnScr        lda     Player_Y_HighPos
dc88: c9 01                        cmp     #$01                    ;check player's vertical high byte for still on the screen
dc8a: d0 0b                        bne     ExPBGCol                ;branch to leave if not
dc8c: a9 ff                        lda     #$ff
dc8e: 8d 90 04                     sta     Player_CollisionBits    ;initialize player's collision flag
dc91: a5 ce                        lda     Player_Y_Position
dc93: c9 cf                        cmp     #$cf                    ;check player's vertical coordinate
dc95: 90 01                        bcc     ChkCollSize             ;if not too close to the bottom of screen, continue
dc97: 60           ExPBGCol        rts                             ;otherwise leave

dc98: a0 02        ChkCollSize     ldy     #$02                    ;load default offset
dc9a: ad 14 07                     lda     CrouchingFlag
dc9d: d0 0c                        bne     GBBAdr                  ;if player crouching, skip ahead
dc9f: ad 54 07                     lda     PlayerSize
dca2: d0 07                        bne     GBBAdr                  ;if player small, skip ahead
dca4: 88                           dey                             ;otherwise decrement offset for big player not crouching
dca5: ad 04 07                     lda     SwimmingFlag
dca8: d0 01                        bne     GBBAdr                  ;if swimming flag set, skip ahead
dcaa: 88                           dey                             ;otherwise decrement offset
dcab: b9 ad e3     GBBAdr          lda     BlockBufferAdderData,y  ;get value using offset
dcae: 85 eb                        sta     $eb                     ;store value here
dcb0: a8                           tay                             ;put value into Y, as offset for block buffer routine
dcb1: ae 54 07                     ldx     PlayerSize              ;get player's size as offset
dcb4: ad 14 07                     lda     CrouchingFlag
dcb7: f0 01                        beq     HeadChk                 ;if player not crouching, branch ahead
dcb9: e8                           inx                             ;otherwise increment size as offset
dcba: a5 ce        HeadChk         lda     Player_Y_Position       ;get player's vertical coordinate
dcbc: dd 62 dc                     cmp     PlayerBGUpperExtent,x   ;compare with upper extent value based on offset
dcbf: 90 35                        bcc     DoFootCheck             ;if player is too high, skip this part
dcc1: 20 e9 e3                     jsr     BlockBufferColli_Head   ;do player-to-bg collision detection on top of
dcc4: f0 30                        beq     DoFootCheck             ; player, and branch if nothing above player's head
dcc6: 20 a1 df                     jsr     CheckForCoinMTiles      ;check to see if player touched coin with their head
dcc9: b0 4f                        bcs     AwardTouchedCoin        ;if so, branch to some other part of code
dccb: a4 9f                        ldy     Player_Y_Speed          ;check player's vertical speed
dccd: 10 27                        bpl     DoFootCheck             ;if player not moving upwards, branch elsewhere
dccf: a4 04                        ldy     $04                     ;check lower nybble of vertical coordinate returned
dcd1: c0 04                        cpy     #$04                    ;from collision detection routine
dcd3: 90 21                        bcc     DoFootCheck             ;if low nybble < 4, branch
dcd5: 20 8f df                     jsr     CheckForSolidMTiles     ;check to see what player's head bumped on
dcd8: b0 10                        bcs     SolidOrClimb            ;if player collided with solid metatile, branch
dcda: ac 4e 07                     ldy     AreaType                ;otherwise check area type
dcdd: f0 13                        beq     MYSpd                   ;if water level, branch ahead
dcdf: ac 84 07                     ldy     BlockBounceTimer        ;if block bounce timer not expired,
dce2: d0 0e                        bne     MYSpd                   ; branch ahead, do not process collision
dce4: 20 ed bc                     jsr     PlayerHeadCollision     ;otherwise do a sub to process collision
dce7: 4c f6 dc                     jmp     DoFootCheck             ;jump ahead to skip these other parts here

dcea: c9 26        SolidOrClimb    cmp     #$26                    ;if climbing metatile,
dcec: f0 04                        beq     MYSpd                   ; branch ahead and do not play sound
dcee: a9 02                        lda     #Sfx_Bump
dcf0: 85 ff                        sta     Square1SoundQueue       ;otherwise load bump sound
dcf2: a9 01        MYSpd           lda     #$01                    ;set player's vertical speed to nullify
dcf4: 85 9f                        sta     Player_Y_Speed          ; jump or swim
dcf6: a4 eb        DoFootCheck     ldy     $eb                     ;get block buffer adder offset
dcf8: a5 ce                        lda     Player_Y_Position
dcfa: c9 cf                        cmp     #$cf                    ;check to see how low player is
dcfc: b0 60                        bcs     DoPlayerSideCheck       ;if player is too far down on screen, skip all of this
dcfe: 20 e8 e3                     jsr     BlockBufferColli_Feet   ;do player-to-bg collision detection on bottom left of player
dd01: 20 a1 df                     jsr     CheckForCoinMTiles      ;check to see if player touched coin with their left foot
dd04: b0 14                        bcs     AwardTouchedCoin        ;if so, branch to some other part of code
dd06: 48                           pha                             ;save bottom left metatile to stack
dd07: 20 e8 e3                     jsr     BlockBufferColli_Feet   ;do player-to-bg collision detection on bottom right of player
dd0a: 85 00                        sta     $00                     ;save bottom right metatile here
dd0c: 68                           pla
dd0d: 85 01                        sta     $01                     ;pull bottom left metatile and save here
dd0f: d0 0c                        bne     ChkFootMTile            ;if anything here, skip this part
dd11: a5 00                        lda     $00                     ;otherwise check for anything in bottom right metatile
dd13: f0 49                        beq     DoPlayerSideCheck       ; and skip ahead if not
dd15: 20 a1 df                     jsr     CheckForCoinMTiles      ;check to see if player touched coin with their right foot
dd18: 90 03                        bcc     ChkFootMTile            ;if not, skip unconditional jump and continue code
                   AwardTouchedCoin
dd1a: 4c 05 de                     jmp     HandleCoinMetatile      ;follow the code to erase coin and award to player 1 coin

dd1d: 20 9a df     ChkFootMTile    jsr     CheckForClimbMTiles     ;check to see if player landed on climbable metatiles
dd20: b0 3c                        bcs     DoPlayerSideCheck       ;if so, branch
dd22: a4 9f                        ldy     Player_Y_Speed          ;check player's vertical speed
dd24: 30 38                        bmi     DoPlayerSideCheck       ;if player moving upwards, branch
dd26: c9 c5                        cmp     #$c5
dd28: d0 03                        bne     ContChk                 ;if player did not touch axe, skip ahead
dd2a: 4c 0e de                     jmp     HandleAxeMetatile       ;otherwise jump to set modes of operation

dd2d: 20 bd de     ContChk         jsr     ChkInvisibleMTiles      ;do sub to check for hidden coin or 1-up blocks
dd30: f0 2c                        beq     DoPlayerSideCheck       ;if either found, branch
dd32: ac 0e 07                     ldy     JumpspringAnimCtrl      ;if jumpspring animating right now,
dd35: d0 23                        bne     InitSteP                ; branch ahead
dd37: a4 04                        ldy     $04                     ;check lower nybble of vertical coordinate returned
dd39: c0 05                        cpy     #$05                    ; from collision detection routine
dd3b: 90 07                        bcc     LandPlyr                ;if lower nybble < 5, branch
dd3d: a5 45                        lda     Player_MovingDir
dd3f: 85 00                        sta     $00                     ;use player's moving direction as temp variable
dd41: 4c 4b df                     jmp     ImpedePlayerMove        ;jump to impede player's movement in that direction

dd44: 20 c4 de     LandPlyr        jsr     ChkForLandJumpSpring    ;do sub to check for jumpspring metatiles and deal with it
dd47: a9 f0                        lda     #$f0
dd49: 25 ce                        and     Player_Y_Position       ;mask out lower nybble of player's vertical position
dd4b: 85 ce                        sta     Player_Y_Position       ; and store as new vertical position to land player properly
dd4d: 20 e8 de                     jsr     HandlePipeEntry         ;do sub to process potential pipe entry
dd50: a9 00                        lda     #$00
dd52: 85 9f                        sta     Player_Y_Speed          ;initialize vertical speed and fractional
dd54: 8d 33 04                     sta     Player_Y_MoveForce      ;movement force to stop player's vertical movement
dd57: 8d 84 04                     sta     StompChainCounter       ;initialize enemy stomp counter
dd5a: a9 00        InitSteP        lda     #$00
dd5c: 85 1d                        sta     Player_State            ;set player's state to normal
                   DoPlayerSideCheck
dd5e: a4 eb                        ldy     $eb                     ;get block buffer adder offset
dd60: c8                           iny
dd61: c8                           iny                             ;increment offset 2 bytes to use adders for side collisions
dd62: a9 02                        lda     #$02                    ;set value here to be used as counter
dd64: 85 00                        sta     $00
dd66: c8           SideCheckLoop   iny                             ;move onto the next one
dd67: 84 eb                        sty     $eb                     ;store it
dd69: a5 ce                        lda     Player_Y_Position
dd6b: c9 20                        cmp     #$20                    ;check player's vertical position
dd6d: 90 16                        bcc     BHalf                   ;if player is in status bar area, branch ahead to skip this part
dd6f: c9 e4                        cmp     #$e4
dd71: b0 28                        bcs     ExSCH                   ;branch to leave if player is too far down
dd73: 20 ec e3                     jsr     BlockBufferColli_Side   ;do player-to-bg collision detection on one half of player
dd76: f0 0d                        beq     BHalf                   ;branch ahead if nothing found
dd78: c9 1c                        cmp     #$1c                    ;otherwise check for pipe metatiles
dd7a: f0 09                        beq     BHalf                   ;if collided with sideways pipe (top), branch ahead
dd7c: c9 6b                        cmp     #$6b
dd7e: f0 05                        beq     BHalf                   ;if collided with water pipe (top), branch ahead
dd80: 20 9a df                     jsr     CheckForClimbMTiles     ;do sub to see if player bumped into anything climbable
dd83: 90 17                        bcc     ChkSideMTiles           ;if not, branch to alternate section of code
dd85: a4 eb        BHalf           ldy     $eb                     ;load block adder offset
dd87: c8                           iny                             ;increment it
dd88: a5 ce                        lda     Player_Y_Position       ;get player's vertical position
dd8a: c9 08                        cmp     #$08
dd8c: 90 0d                        bcc     ExSCH                   ;if too high, branch to leave
dd8e: c9 d0                        cmp     #$d0
dd90: b0 09                        bcs     ExSCH                   ;if too low, branch to leave
dd92: 20 ec e3                     jsr     BlockBufferColli_Side   ;do player-to-bg collision detection on other half of player
dd95: d0 05                        bne     ChkSideMTiles           ;if something found, branch
dd97: c6 00                        dec     $00                     ;otherwise decrement counter
dd99: d0 cb                        bne     SideCheckLoop           ;run code until both sides of player are checked
dd9b: 60           ExSCH           rts                             ;leave

dd9c: 20 bd de     ChkSideMTiles   jsr     ChkInvisibleMTiles      ;check for hidden or coin 1-up blocks
dd9f: f0 61                        beq     ExCSM                   ;branch to leave if either found
dda1: 20 9a df                     jsr     CheckForClimbMTiles     ;check for climbable metatiles
dda4: 90 03                        bcc     ContSChk                ;if not found, skip and continue with code
dda6: 4c 2e de                     jmp     HandleClimbing          ;otherwise jump to handle climbing

dda9: 20 a1 df     ContSChk        jsr     CheckForCoinMTiles      ;check to see if player touched coin
ddac: b0 57                        bcs     HandleCoinMetatile      ;if so, execute code to erase coin and award to player 1 coin
ddae: 20 dd de                     jsr     ChkJumpspringMetatiles  ;check for jumpspring metatiles
ddb1: 90 08                        bcc     ChkPBtm                 ;if not found, branch ahead to continue cude
ddb3: ad 0e 07                     lda     JumpspringAnimCtrl      ;otherwise check jumpspring animation control
ddb6: d0 4a                        bne     ExCSM                   ;branch to leave if set
ddb8: 4c ff dd                     jmp     StopPlayerMove          ;otherwise jump to impede player's movement

ddbb: a4 1d        ChkPBtm         ldy     Player_State            ;get player's state
ddbd: c0 00                        cpy     #$00                    ;check for player's state set to normal
ddbf: d0 3e                        bne     StopPlayerMove          ;if not, branch to impede player's movement
ddc1: a4 33                        ldy     PlayerFacingDir         ;get player's facing direction
ddc3: 88                           dey
ddc4: d0 39                        bne     StopPlayerMove          ;if facing left, branch to impede movement
ddc6: c9 6c                        cmp     #$6c                    ;otherwise check for pipe metatiles
ddc8: f0 04                        beq     PipeDwnS                ;if collided with sideways pipe (bottom), branch
ddca: c9 1f                        cmp     #$1f                    ;if collided with water pipe (bottom), continue
ddcc: d0 31                        bne     StopPlayerMove          ;otherwise branch to impede player's movement
ddce: ad c4 03     PipeDwnS        lda     Player_SprAttrib        ;check player's attributes
ddd1: d0 04                        bne     PlyrPipe                ;if already set, branch, do not play sound again
ddd3: a0 10                        ldy     #Sfx_PipeDown_Injury
ddd5: 84 ff                        sty     Square1SoundQueue       ;otherwise load pipedown/injury sound
ddd7: 09 20        PlyrPipe        ora     #%00100000
ddd9: 8d c4 03                     sta     Player_SprAttrib        ;set background priority bit in player attributes
dddc: a5 86                        lda     Player_X_Position
ddde: 29 0f                        and     #%00001111              ;get lower nybble of player's horizontal coordinate
dde0: f0 0e                        beq     ChkGERtn                ;if at zero, branch ahead to skip this part
dde2: a0 00                        ldy     #$00                    ;set default offset for timer setting data
dde4: ad 1a 07                     lda     ScreenLeft_PageLoc      ;load page location for left side of screen
dde7: f0 01                        beq     SetCATmr                ;if at page zero, use default offset
dde9: c8                           iny                             ;otherwise increment offset
ddea: b9 03 de     SetCATmr        lda     AreaChangeTimerData,y   ;set timer for change of area as appropriate
dded: 8d de 06                     sta     ChangeAreaTimer
ddf0: a5 0e        ChkGERtn        lda     GameEngineSubroutine    ;get number of game engine routine running
ddf2: c9 07                        cmp     #$07
ddf4: f0 0c                        beq     ExCSM                   ;if running player entrance routine or
ddf6: c9 08                        cmp     #$08                    ; player control routine, go ahead and branch to leave
ddf8: d0 08                        bne     ExCSM
ddfa: a9 02                        lda     #$02
ddfc: 85 0e                        sta     GameEngineSubroutine    ;otherwise set sideways pipe entry routine to run
ddfe: 60                           rts                             ; and leave

                   ; -----------------------------------------------------------------------------
                   ; $02 - high nybble of vertical coordinate from block buffer
                   ; $04 - low nybble of horizontal coordinate from block buffer
                   ; $06-$07 - block buffer address
ddff: 20 4b df     StopPlayerMove  jsr     ImpedePlayerMove        ;stop player's movement
de02: 60           ExCSM           rts                             ;leave

                   AreaChangeTimerData
de03: a0 34                        .bulk   $a0,$34

                   HandleCoinMetatile
de05: 20 1c de                     jsr     ErACM                   ;do sub to erase coin metatile from block buffer
de08: ee 48 07                     inc     CoinTallyFor1Ups        ;increment coin tally used for 1-up blocks
de0b: 4c fe bb                     jmp     GiveOneCoin             ;update coin amount and tally on the screen

                   HandleAxeMetatile
de0e: a9 00                        lda     #$00
de10: 8d 72 07                     sta     OperMode_Task           ;reset secondary mode
de13: a9 02                        lda     #$02
de15: 8d 70 07                     sta     OperMode                ;set primary mode to autoctrl mode
de18: a9 18                        lda     #$18
de1a: 85 57                        sta     Player_X_Speed          ;set horizontal speed and continue to erase axe metatile
de1c: a4 02        ErACM           ldy     $02                     ;load vertical high nybble offset for block buffer
de1e: a9 00                        lda     #$00                    ;load blank metatile
de20: 91 06                        sta     ($06),y                 ;store to remove old contents from block buffer
de22: 4c 4d 8a                     jmp     RemoveCoin_Axe          ;update the screen accordingly

                   ; -----------------------------------------------------------------------------
                   ; $02 - high nybble of vertical coordinate from block buffer
                   ; $04 - low nybble of horizontal coordinate from block buffer
                   ; $06-$07 - block buffer address
de25: f9 07        ClimbXPosAdder  .bulk   $f9,$07
de27: ff 00        ClimbPLocAdder  .bulk   $ff,$00
                   FlagpoleYPosData
de29: 18 22 50 68+                 .bulk   $18,$22,$50,$68,$90

de2e: a4 04        HandleClimbing  ldy     $04                     ;check low nybble of horizontal coordinate returned from
de30: c0 06                        cpy     #$06                    ; collision detection routine against certain values, this
de32: 90 04                        bcc     ExHC                    ; makes actual physical part of vine or flagpole thinner
de34: c0 0a                        cpy     #$0a                    ; than 16 pixels
de36: 90 01                        bcc     ChkForFlagpole
de38: 60           ExHC            rts                             ;leave if too far left or too far right

de39: c9 24        ChkForFlagpole  cmp     #$24                    ;check climbing metatiles
de3b: f0 04                        beq     FlagpoleCollision       ;branch if flagpole ball found
de3d: c9 25                        cmp     #$25
de3f: d0 39                        bne     VineCollision           ;branch to alternate code if flagpole shaft not found
                   FlagpoleCollision
de41: a5 0e                        lda     GameEngineSubroutine
de43: c9 05                        cmp     #$05                    ;check for end-of-level routine running
de45: f0 41                        beq     PutPlayerOnVine         ;if running, branch to end of climbing code
de47: a9 01                        lda     #$01
de49: 85 33                        sta     PlayerFacingDir         ;set player's facing direction to right
de4b: ee 23 07                     inc     ScrollLock              ;set scroll lock flag
de4e: a5 0e                        lda     GameEngineSubroutine
de50: c9 04                        cmp     #$04                    ;check for flagpole slide routine running
de52: f0 1f                        beq     RunFR                   ;if running, branch to end of flagpole code here
de54: a9 33                        lda     #BulletBill_CannonVar   ;load identifier for bullet bills (cannon variant)
de56: 20 16 97                     jsr     KillEnemies             ;get rid of them
de59: a9 80                        lda     #Silence
de5b: 85 fc                        sta     EventMusicQueue         ;silence music
de5d: 4a                           lsr     A
de5e: 8d 13 07                     sta     FlagpoleSoundQueue      ;load flagpole sound into flagpole sound queue
de61: a2 04                        ldx     #$04                    ;start at end of vertical coordinate data
de63: a5 ce                        lda     Player_Y_Position
de65: 8d 0f 07                     sta     FlagpoleCollisionYPos   ;store player's vertical coordinate here to be used later
                   ChkFlagpoleYPosLoop
de68: dd 29 de                     cmp     FlagpoleYPosData,x      ;compare with current vertical coordinate data
de6b: b0 03                        bcs     MtchF                   ;if player's => current, branch to use current offset
de6d: ca                           dex                             ;otherwise decrement offset to use 
de6e: d0 f8                        bne     ChkFlagpoleYPosLoop     ;do this until all data is checked (use last one if all checked)
de70: 8e 0f 01     MtchF           stx     FlagpoleScore           ;store offset here to be used later
de73: a9 04        RunFR           lda     #$04
de75: 85 0e                        sta     GameEngineSubroutine    ;set value to run flagpole slide routine
de77: 4c 88 de                     jmp     PutPlayerOnVine         ;jump to end of climbing code

de7a: c9 26        VineCollision   cmp     #$26                    ;check for climbing metatile used on vines
de7c: d0 0a                        bne     PutPlayerOnVine
de7e: a5 ce                        lda     Player_Y_Position       ;check player's vertical coordinate
de80: c9 20                        cmp     #$20                    ;for being in status bar area
de82: b0 04                        bcs     PutPlayerOnVine         ;branch if not that far up
de84: a9 01                        lda     #$01
de86: 85 0e                        sta     GameEngineSubroutine    ;otherwise set to run autoclimb routine next frame
de88: a9 03        PutPlayerOnVine lda     #$03                    ;set player state to climbing
de8a: 85 1d                        sta     Player_State
de8c: a9 00                        lda     #$00                    ;nullify player's horizontal speed
de8e: 85 57                        sta     Player_X_Speed          ;and fractional horizontal movement force
de90: 8d 05 07                     sta     Player_X_MoveForce
de93: a5 86                        lda     Player_X_Position       ;get player's horizontal coordinate
de95: 38                           sec
de96: ed 1c 07                     sbc     ScreenLeft_X_Pos        ;subtract from left side horizontal coordinate
de99: c9 10                        cmp     #$10
de9b: b0 04                        bcs     SetVXPl                 ;if 16 or more pixels difference, do not alter facing direction
de9d: a9 02                        lda     #$02
de9f: 85 33                        sta     PlayerFacingDir         ;otherwise force player to face left
dea1: a4 33        SetVXPl         ldy     PlayerFacingDir         ;get current facing direction, use as offset
dea3: a5 06                        lda     $06                     ;get low byte of block buffer address
dea5: 0a                           asl     A
dea6: 0a                           asl     A                       ;move low nybble to high
dea7: 0a                           asl     A
dea8: 0a                           asl     A
dea9: 18                           clc
deaa: 79 24 de                     adc     ClimbXPosAdder-1,y      ;add pixels depending on facing direction
dead: 85 86                        sta     Player_X_Position       ;store as player's horizontal coordinate
deaf: a5 06                        lda     $06                     ;get low byte of block buffer address again
deb1: d0 09                        bne     ExPVne                  ;if not zero, branch
deb3: ad 1b 07                     lda     ScreenRight_PageLoc     ;load page location of right side of screen
deb6: 18                           clc
deb7: 79 26 de                     adc     ClimbPLocAdder-1,y      ;add depending on facing location
deba: 85 6d                        sta     Player_PageLoc          ;store as player's page location
debc: 60           ExPVne          rts                             ;finally, we're done!

                   ; -----------------------------------------------------------------------------
                   ChkInvisibleMTiles
debd: c9 5f                        cmp     #$5f                    ;check for hidden coin block
debf: f0 02                        beq     ExCInvT                 ;branch to leave if found
dec1: c9 60                        cmp     #$60                    ;check for hidden 1-up block
dec3: 60           ExCInvT         rts                             ;leave with zero flag set if either found

                   ; -----------------------------------------------------------------------------
                   ; $00-$01 - used to hold bottom right and bottom left metatiles (in that order)
                   ; $00 - used as flag by ImpedePlayerMove to restrict specific movement
                   ChkForLandJumpSpring
dec4: 20 dd de                     jsr     ChkJumpspringMetatiles  ;do sub to check if player landed on jumpspring
dec7: 90 13                        bcc     ExCJSp                  ;if carry not set, jumpspring not found, therefore leave
dec9: a9 70                        lda     #$70
decb: 8d 09 07                     sta     VerticalForce           ;otherwise set vertical movement force for player
dece: a9 f9                        lda     #$f9
ded0: 8d db 06                     sta     JumpspringForce         ;set default jumpspring force
ded3: a9 03                        lda     #$03
ded5: 8d 86 07                     sta     JumpspringTimer         ;set jumpspring timer to be used later
ded8: 4a                           lsr     A
ded9: 8d 0e 07                     sta     JumpspringAnimCtrl      ;set jumpspring animation control to start animating
dedc: 60           ExCJSp          rts                             ; and leave

                   ChkJumpspringMetatiles
dedd: c9 67                        cmp     #$67                    ;check for top jumpspring metatile
dedf: f0 05                        beq     JSFnd                   ;branch to set carry if found
dee1: c9 68                        cmp     #$68                    ;check for bottom jumpspring metatile
dee3: 18                           clc                             ;clear carry flag
dee4: d0 01                        bne     NoJSFnd                 ;branch to use cleared carry if not found
dee6: 38           JSFnd           sec                             ;set carry if found
dee7: 60           NoJSFnd         rts                             ;leave

dee8: a5 0b        HandlePipeEntry lda     Up_Down_Buttons         ;check saved controller bits from earlier
deea: 29 04                        and     #%00000100              ; for pressing down
deec: f0 5c                        beq     ExPipeE                 ;if not pressing down, branch to leave
deee: a5 00                        lda     $00
def0: c9 11                        cmp     #$11                    ;check right foot metatile for warp pipe right metatile
def2: d0 56                        bne     ExPipeE                 ;branch to leave if not found
def4: a5 01                        lda     $01
def6: c9 10                        cmp     #$10                    ;check left foot metatile for warp pipe left metatile
def8: d0 50                        bne     ExPipeE                 ;branch to leave if not found
defa: a9 30                        lda     #$30
defc: 8d de 06                     sta     ChangeAreaTimer         ;set timer for change of area
deff: a9 03                        lda     #$03
df01: 85 0e                        sta     GameEngineSubroutine    ;set to run vertical pipe entry routine on next frame
df03: a9 10                        lda     #Sfx_PipeDown_Injury
df05: 85 ff                        sta     Square1SoundQueue       ;load pipedown/injury sound
df07: a9 20                        lda     #%00100000
df09: 8d c4 03                     sta     Player_SprAttrib        ;set background priority bit in player's attributes
df0c: ad d6 06                     lda     WarpZoneControl         ;check warp zone control
df0f: f0 39                        beq     ExPipeE                 ;branch to leave if none found
df11: 29 03                        and     #%00000011              ;mask out all but 2 LSB
df13: 0a                           asl     A
df14: 0a                           asl     A                       ;multiply by four
df15: aa                           tax                             ;save as offset to warp zone numbers (starts at left pipe)
df16: a5 86                        lda     Player_X_Position       ;get player's horizontal position
df18: c9 60                        cmp     #$60
df1a: 90 06                        bcc     GetWNum                 ;if player at left, not near middle, use offset and skip ahead
df1c: e8                           inx                             ;otherwise increment for middle pipe
df1d: c9 a0                        cmp     #$a0
df1f: 90 01                        bcc     GetWNum                 ;if player at middle, but not too far right, use offset and skip
df21: e8                           inx                             ;otherwise increment for last pipe
df22: bc f2 87     GetWNum         ldy     WarpZoneNumbers,x       ;get warp zone numbers
df25: 88                           dey                             ;decrement for use as world number
df26: 8c 5f 07                     sty     WorldNumber             ;store as world number and offset
df29: be b4 9c                     ldx     WorldAddrOffsets,y      ;get offset to where this world's area offsets are
df2c: bd bc 9c                     lda     AreaAddrOffsets,x       ;get area offset based on world offset
df2f: 8d 50 07                     sta     AreaPointer             ;store area offset here to be used to change areas
df32: a9 80                        lda     #$80
df34: 85 fc                        sta     EventMusicQueue         ;silence music
df36: a9 00                        lda     #$00
df38: 8d 51 07                     sta     EntrancePage            ;initialize starting page number
df3b: 8d 60 07                     sta     AreaNumber              ;initialize area number used for area address offset
df3e: 8d 5c 07                     sta     LevelNumber             ;initialize level number used for world display
df41: 8d 52 07                     sta     AltEntranceControl      ;initialize mode of entry
df44: ee 5d 07                     inc     Hidden1UpFlag           ;set flag for hidden 1-up blocks
df47: ee 57 07                     inc     FetchNewGameTimerFlag   ;set flag to load new game timer
df4a: 60           ExPipeE         rts                             ;leave!!!

                   ImpedePlayerMove
df4b: a9 00                        lda     #$00                    ;initialize value here
df4d: a4 57                        ldy     Player_X_Speed          ;get player's horizontal speed
df4f: a6 00                        ldx     $00                     ;check value set earlier for
df51: ca                           dex                             ; left side collision
df52: d0 0a                        bne     RImpd                   ;if right side collision, skip this part
df54: e8                           inx                             ;return value to X
df55: c0 00                        cpy     #$00                    ;if player moving to the left,
df57: 30 28                        bmi     ExIPM                   ; branch to invert bit and leave
df59: a9 ff                        lda     #$ff                    ;otherwise load A with value to be used later
df5b: 4c 66 df                     jmp     NXSpd                   ; and jump to affect movement

df5e: a2 02        RImpd           ldx     #$02                    ;return $02 to X
df60: c0 01                        cpy     #$01                    ;if player moving to the right,
df62: 10 1d                        bpl     ExIPM                   ; branch to invert bit and leave
df64: a9 01                        lda     #$01                    ;otherwise load A with value to be used here
df66: a0 10        NXSpd           ldy     #$10
df68: 8c 85 07                     sty     SideCollisionTimer      ;set timer of some sort
df6b: a0 00                        ldy     #$00
df6d: 84 57                        sty     Player_X_Speed          ;nullify player's horizontal speed
df6f: c9 00                        cmp     #$00                    ;if value set in A not set to $ff,
df71: 10 01                        bpl     PlatF                   ; branch ahead, do not decrement Y
df73: 88                           dey                             ;otherwise decrement Y now
df74: 84 00        PlatF           sty     $00                     ;store Y as high bits of horizontal adder
df76: 18                           clc
df77: 65 86                        adc     Player_X_Position       ;add contents of A to player's horizontal
df79: 85 86                        sta     Player_X_Position       ; position to move player left or right
df7b: a5 6d                        lda     Player_PageLoc
df7d: 65 00                        adc     $00                     ;add high bits and carry to
df7f: 85 6d                        sta     Player_PageLoc          ; page location if necessary
df81: 8a           ExIPM           txa                             ;invert contents of X
df82: 49 ff                        eor     #$ff
df84: 2d 90 04                     and     Player_CollisionBits    ;mask out bit that was set here
df87: 8d 90 04                     sta     Player_CollisionBits    ;store to clear bit
df8a: 60                           rts

                   ; -----------------------------------------------------------------------------
                   SolidMTileUpperExt
df8b: 10 61 88 c4                  .bulk   $10,$61,$88,$c4

                   CheckForSolidMTiles
df8f: 20 b0 df                     jsr     GetMTileAttrib          ;find appropriate offset based on metatile's 2 MSB
df92: dd 8b df                     cmp     SolidMTileUpperExt,x    ;compare current metatile with solid metatiles
df95: 60                           rts

                   ClimbMTileUpperExt
df96: 24 6d 8a c6                  .bulk   $24,$6d,$8a,$c6

                   CheckForClimbMTiles
df9a: 20 b0 df                     jsr     GetMTileAttrib          ;find appropriate offset based on metatile's 2 MSB
df9d: dd 96 df                     cmp     ClimbMTileUpperExt,x    ;compare current metatile with climbable metatiles
dfa0: 60                           rts

                   CheckForCoinMTiles
dfa1: c9 c2                        cmp     #$c2                    ;check for regular coin
dfa3: f0 06                        beq     CoinSd                  ;branch if found
dfa5: c9 c3                        cmp     #$c3                    ;check for underwater coin
dfa7: f0 02                        beq     CoinSd                  ;branch if found
dfa9: 18                           clc                             ;otherwise clear carry and leave
dfaa: 60                           rts

dfab: a9 01        CoinSd          lda     #Sfx_CoinGrab
dfad: 85 fe                        sta     Square2SoundQueue       ;load coin grab sound and leave
dfaf: 60                           rts

dfb0: a8           GetMTileAttrib  tay                             ;save metatile value into Y
dfb1: 29 c0                        and     #%11000000              ;mask out all but 2 MSB
dfb3: 0a                           asl     A
dfb4: 2a                           rol     A                       ;shift and rotate d7-d6 to d1-d0
dfb5: 2a                           rol     A
dfb6: aa                           tax                             ;use as offset for metatile data
dfb7: 98                           tya                             ;get original metatile value back
dfb8: 60           ExEBG           rts                             ;leave

                   ; -----------------------------------------------------------------------------
                   ; $06-$07 - address from block buffer routine
                   EnemyBGCStateData
dfb9: 01 01 02 02+                 .bulk   $01,$01,$02,$02,$02,$05
                   EnemyBGCXSpdData
dfbf: 10 f0                        .bulk   $10,$f0

                   EnemyToBGCollisionDet
dfc1: b5 1e                        lda     Enemy_State,x           ;check enemy state for d6 set
dfc3: 29 20                        and     #%00100000
dfc5: d0 f1                        bne     ExEBG                   ;if set, branch to leave
dfc7: 20 5b e1                     jsr     SubtEnemyYPos           ;otherwise, do a subroutine here
dfca: 90 ec                        bcc     ExEBG                   ;if enemy vertical coord + 62 < 68, branch to leave
dfcc: b4 16                        ldy     Enemy_ID,x
dfce: c0 12                        cpy     #Spiny                  ;if enemy object is not spiny, branch elsewhere
dfd0: d0 06                        bne     DoIDCheckBGColl
dfd2: b5 cf                        lda     Enemy_Y_Position,x
dfd4: c9 25                        cmp     #$25                    ;if enemy vertical coordinate < 36 branch to leave
dfd6: 90 e0                        bcc     ExEBG
dfd8: c0 0e        DoIDCheckBGColl cpy     #GreenParatroopaJump    ;check for some other enemy object
dfda: d0 03                        bne     HBChk                   ;branch if not found
dfdc: 4c 63 e1                     jmp     EnemyJump               ;otherwise jump elsewhere

dfdf: c0 05        HBChk           cpy     #HammerBro              ;check for hammer bro
dfe1: d0 03                        bne     CInvu                   ;branch if not found
dfe3: 4c 85 e1                     jmp     HammerBroBGColl         ;otherwise jump elsewhere

dfe6: c0 12        CInvu           cpy     #Spiny                  ;if enemy object is spiny, branch
dfe8: f0 08                        beq     YesIn
dfea: c0 2e                        cpy     #PowerUpObject          ;if special power-up object, branch
dfec: f0 04                        beq     YesIn
dfee: c0 07                        cpy     #$07                    ;if enemy object =>$07, branch to leave
dff0: b0 74                        bcs     ExEBGChk
dff2: 20 ae e1     YesIn           jsr     ChkUnderEnemy           ;if enemy object < $07, or = $12 or $2e, do this sub
dff5: d0 03                        bne     HandleEToBGCollision    ;if block underneath enemy, branch
                   NoEToBGCollision
dff7: 4c e2 e0                     jmp     ChkForRedKoopa          ;otherwise skip and do something else

                   ; -----------------------------------------------------------------------------
                   ; $02 - vertical coordinate from block buffer routine
                   HandleEToBGCollision
dffa: 20 b5 e1                     jsr     ChkForNonSolids         ;if something is underneath enemy, find out what
dffd: f0 f8                        beq     NoEToBGCollision        ;if blank $26, coins, or hidden blocks, jump, enemy falls through
dfff: c9 23                        cmp     #$23
e001: d0 64                        bne     LandEnemyProperly       ;check for blank metatile $23 and branch if not found
e003: a4 02                        ldy     $02                     ;get vertical coordinate used to find block
e005: a9 00                        lda     #$00                    ;store default blank metatile in that spot so we won't
e007: 91 06                        sta     ($06),y                 ; trigger this routine accidentally again
e009: b5 16                        lda     Enemy_ID,x
e00b: c9 15                        cmp     #$15                    ;if enemy object => $15, branch ahead
e00d: b0 0c                        bcs     ChkToStunEnemies
e00f: c9 06                        cmp     #Goomba                 ;if enemy object not goomba, branch ahead of this routine
e011: d0 03                        bne     GiveOEPoints
e013: 20 8e e1                     jsr     KillEnemyAboveBlock     ;if enemy object IS goomba, do this sub
e016: a9 01        GiveOEPoints    lda     #$01                    ;award 100 points for hitting block beneath enemy
e018: 20 11 da                     jsr     SetupFloateyNumber
                   ChkToStunEnemies
e01b: c9 09                        cmp     #$09                    ;perform many comparisons on enemy object identifier
e01d: 90 10                        bcc     SetStun
e01f: c9 11                        cmp     #$11                    ;if the enemy object identifier is equal to the values
e021: b0 0c                        bcs     SetStun                 ; $09, $0e, $0f or $10, it will be modified, and not
e023: c9 0a                        cmp     #$0a                    ; modified if not any of those values, note that piranha plant will
e025: 90 04                        bcc     Demote                  ; always fail this test because A will still have vertical
e027: c9 0d                        cmp     #PiranhaPlant           ; coordinate from previous addition, also these comparisons
e029: 90 04                        bcc     SetStun                 ; are only necessary if branching from $d7a1
e02b: 29 01        Demote          and     #%00000001              ;erase all but LSB, essentially turning enemy object
e02d: 95 16                        sta     Enemy_ID,x              ; into green or red koopa troopa to demote them
                   ; 
e02f: b5 1e        SetStun         lda     Enemy_State,x           ;load enemy state
e031: 29 f0                        and     #%11110000              ;save high nybble
e033: 09 02                        ora     #%00000010
e035: 95 1e                        sta     Enemy_State,x           ;set d1 of enemy state
e037: d6 cf                        dec     Enemy_Y_Position,x
e039: d6 cf                        dec     Enemy_Y_Position,x      ;subtract two pixels from enemy's vertical position
e03b: b5 16                        lda     Enemy_ID,x
e03d: c9 07                        cmp     #Bloober                ;check for bloober object
e03f: f0 07                        beq     SetWySpd
e041: a9 fd                        lda     #$fd                    ;set default vertical speed
e043: ac 4e 07                     ldy     AreaType
e046: d0 02                        bne     SetNotW                 ;if area type not water, set as speed, otherwise
e048: a9 ff        SetWySpd        lda     #$ff                    ;change the vertical speed
e04a: 95 a0        SetNotW         sta     Enemy_Y_Speed,x         ;set vertical speed now
e04c: a0 01                        ldy     #$01
e04e: 20 43 e1                     jsr     PlayerEnemyDiff         ;get horizontal difference between player and enemy object
e051: 10 01                        bpl     ChkBBill                ;branch if enemy is to the right of player
e053: c8                           iny                             ;increment Y if not
e054: b5 16        ChkBBill        lda     Enemy_ID,x
e056: c9 33                        cmp     #BulletBill_CannonVar   ;check for bullet bill (cannon variant)
e058: f0 06                        beq     NoCDirF
e05a: c9 08                        cmp     #BulletBill_FrenzyVar   ;check for bullet bill (frenzy variant)
e05c: f0 02                        beq     NoCDirF                 ;branch if either found, direction does not change
e05e: 94 46                        sty     Enemy_MovingDir,x       ;store as moving direction
e060: 88           NoCDirF         dey                             ;decrement and use as offset
e061: b9 bf df                     lda     EnemyBGCXSpdData,y      ;get proper horizontal speed
e064: 95 58                        sta     Enemy_X_Speed,x         ; and store, then leave
e066: 60           ExEBGChk        rts

                   ; -----------------------------------------------------------------------------
                   ; $04 - low nybble of vertical coordinate from block buffer routine
                   LandEnemyProperly
e067: a5 04                        lda     $04                     ;check lower nybble of vertical coordinate saved earlier
e069: 38                           sec
e06a: e9 08                        sbc     #$08                    ;subtract eight pixels
e06c: c9 05                        cmp     #$05                    ;used to determine whether enemy landed from falling
e06e: b0 72                        bcs     ChkForRedKoopa          ;branch if lower nybble in range of $0d-$0f before subtract
e070: b5 1e                        lda     Enemy_State,x
e072: 29 40                        and     #%01000000              ;branch if d6 in enemy state is set
e074: d0 57                        bne     LandEnemyInitState
e076: b5 1e                        lda     Enemy_State,x
e078: 0a                           asl     A                       ;branch if d7 in enemy state is not set
e079: 90 03                        bcc     ChkLandedEnemyState
e07b: 4c fe e0     SChkA           jmp     DoEnemySideCheck        ;if lower nybble < $0d, d7 set but d6 not set, jump here

                   ChkLandedEnemyState
e07e: b5 1e                        lda     Enemy_State,x           ;if enemy in normal state, branch back to jump here
e080: f0 f9                        beq     SChkA
e082: c9 05                        cmp     #$05                    ;if in state used by spiny's egg
e084: f0 1f                        beq     ProcEnemyDirection      ;then branch elsewhere
e086: c9 03                        cmp     #$03                    ;if already in state used by koopas and buzzy beetles
e088: b0 1a                        bcs     ExSteChk                ; or in higher numbered state, branch to leave
e08a: b5 1e                        lda     Enemy_State,x           ;load enemy state again (why?)
e08c: c9 02                        cmp     #$02                    ;if not in $02 state (used by koopas and buzzy beetles)
e08e: d0 15                        bne     ProcEnemyDirection      ;then branch elsewhere
e090: a9 10                        lda     #$10                    ;load default timer here
e092: b4 16                        ldy     Enemy_ID,x              ;check enemy identifier for spiny
e094: c0 12                        cpy     #Spiny
e096: d0 02                        bne     SetForStn               ;branch if not found
e098: a9 00                        lda     #$00                    ;set timer for $00 if spiny
e09a: 9d 96 07     SetForStn       sta     EnemyIntervalTimer,x    ;set timer here
e09d: a9 03                        lda     #$03                    ;set state here, apparently used to render
e09f: 95 1e                        sta     Enemy_State,x           ; upside-down koopas and buzzy beetles
e0a1: 20 4f e1                     jsr     EnemyLanding            ;then land it properly
e0a4: 60           ExSteChk        rts                             ;then leave

                   ProcEnemyDirection
e0a5: b5 16                        lda     Enemy_ID,x              ;check enemy identifier for goomba
e0a7: c9 06                        cmp     #Goomba                 ;branch if found
e0a9: f0 22                        beq     LandEnemyInitState
e0ab: c9 12                        cmp     #Spiny                  ;check for spiny
e0ad: d0 0e                        bne     InvtD                   ;branch if not found
e0af: a9 01                        lda     #$01
e0b1: 95 46                        sta     Enemy_MovingDir,x       ;send enemy moving to the right by default
e0b3: a9 08                        lda     #$08
e0b5: 95 58                        sta     Enemy_X_Speed,x         ;set horizontal speed accordingly
e0b7: a5 09                        lda     FrameCounter
e0b9: 29 07                        and     #%00000111              ;if timed appropriately, spiny will skip over
e0bb: f0 10                        beq     LandEnemyInitState      ;trying to face the player
e0bd: a0 01        InvtD           ldy     #$01                    ;load 1 for enemy to face the left (inverted here)
e0bf: 20 43 e1                     jsr     PlayerEnemyDiff         ;get horizontal difference between player and enemy
e0c2: 10 01                        bpl     CNwCDir                 ;if enemy to the right of player, branch
e0c4: c8                           iny                             ;if to the left, increment by one for enemy to face right (inverted)
e0c5: 98           CNwCDir         tya
e0c6: d5 46                        cmp     Enemy_MovingDir,x       ;compare direction in A with current direction in memory
e0c8: d0 03                        bne     LandEnemyInitState
e0ca: 20 24 e1                     jsr     ChkForBump_HammerBroJ   ;if equal, not facing in correct dir, do sub to turn around
                   LandEnemyInitState
e0cd: 20 4f e1                     jsr     EnemyLanding            ;land enemy properly
e0d0: b5 1e                        lda     Enemy_State,x
e0d2: 29 80                        and     #%10000000              ;if d7 of enemy state is set, branch
e0d4: d0 05                        bne     NMovShellFallBit
e0d6: a9 00                        lda     #$00                    ;otherwise initialize enemy state and leave
e0d8: 95 1e                        sta     Enemy_State,x           ;note this will also turn spiny's egg into spiny
e0da: 60                           rts

                   NMovShellFallBit
e0db: b5 1e                        lda     Enemy_State,x           ;nullify d6 of enemy state, save other bits
e0dd: 29 bf                        and     #%10111111              ;and store, then leave
e0df: 95 1e                        sta     Enemy_State,x
e0e1: 60                           rts

                   ; -----------------------------------------------------------------------------
e0e2: b5 16        ChkForRedKoopa  lda     Enemy_ID,x              ;check for red koopa troopa $03
e0e4: c9 03                        cmp     #RedKoopa
e0e6: d0 04                        bne     Chk2MSBSt               ;branch if not found
e0e8: b5 1e                        lda     Enemy_State,x
e0ea: f0 38                        beq     ChkForBump_HammerBroJ   ;if enemy found and in normal state, branch
e0ec: b5 1e        Chk2MSBSt       lda     Enemy_State,x           ;save enemy state into Y
e0ee: a8                           tay
e0ef: 0a                           asl     A                       ;check for d7 set
e0f0: 90 07                        bcc     GetSteFromD             ;branch if not set
e0f2: b5 1e                        lda     Enemy_State,x
e0f4: 09 40                        ora     #%01000000              ;set d6
e0f6: 4c fc e0                     jmp     SetD6Ste                ;jump ahead of this part

e0f9: b9 b9 df     GetSteFromD     lda     EnemyBGCStateData,y     ;load new enemy state with old as offset
e0fc: 95 1e        SetD6Ste        sta     Enemy_State,x           ;set as new state
                   ; $00 - used to store bitmask (not used but initialized here)
                   ; $eb - used in DoEnemySideCheck as counter and to compare moving directions
                   DoEnemySideCheck
e0fe: b5 cf                        lda     Enemy_Y_Position,x      ;if enemy within status bar, branch to leave
e100: c9 20                        cmp     #$20                    ; because there's nothing there that impedes movement
e102: 90 1f                        bcc     ExESdeC
e104: a0 16                        ldy     #$16                    ;start by finding block to the left of enemy ($00,$14)
e106: a9 02                        lda     #$02                    ;set value here in what is also used as
e108: 85 eb                        sta     $eb                     ;OAM data offset
e10a: a5 eb        SdeCLoop        lda     $eb                     ;check value
e10c: d5 46                        cmp     Enemy_MovingDir,x       ;compare value against moving direction
e10e: d0 0c                        bne     NextSdeC                ;branch if different and do not seek block there
e110: a9 01                        lda     #$01                    ;set flag in A for save horizontal coordinate 
e112: 20 88 e3                     jsr     BlockBufferChk_Enemy    ;find block to left or right of enemy object
e115: f0 05                        beq     NextSdeC                ;if nothing found, branch
e117: 20 b5 e1                     jsr     ChkForNonSolids         ;check for non-solid blocks
e11a: d0 08                        bne     ChkForBump_HammerBroJ   ;branch if not found
e11c: c6 eb        NextSdeC        dec     $eb                     ;move to the next direction
e11e: c8                           iny
e11f: c0 18                        cpy     #$18                    ;increment Y, loop only if Y < $18, thus we check
e121: 90 e7                        bcc     SdeCLoop                ;enemy ($00, $14) and ($10, $14) pixel coordinates
e123: 60           ExESdeC         rts

                   ChkForBump_HammerBroJ
e124: e0 05                        cpx     #$05                    ;check if we're on the special use slot
e126: f0 09                        beq     NoBump                  ; and if so, branch ahead and do not play sound
e128: b5 1e                        lda     Enemy_State,x           ;if enemy state d7 not set, branch
e12a: 0a                           asl     A                       ; ahead and do not play sound
e12b: 90 04                        bcc     NoBump
e12d: a9 02                        lda     #Sfx_Bump               ;otherwise, play bump sound
e12f: 85 ff                        sta     Square1SoundQueue       ;sound will never be played if branching from ChkForRedKoopa
e131: b5 16        NoBump          lda     Enemy_ID,x              ;check for hammer bro
e133: c9 05                        cmp     #HammerBro
e135: d0 09                        bne     InvEnemyDir             ;branch if not found
e137: a9 00                        lda     #$00
e139: 85 00                        sta     $00                     ;initialize value here for bitmask
e13b: a0 fa                        ldy     #$fa                    ;load default vertical speed for jumping
e13d: 4c 37 ca                     jmp     SetHJ                   ;jump to code that makes hammer bro jump

e140: 4c 36 db     InvEnemyDir     jmp     RXSpd                   ;jump to turn the enemy around

                   ; -----------------------------------------------------------------------------
                   ; $00 - used to hold horizontal difference between player and enemy
e143: b5 87        PlayerEnemyDiff lda     Enemy_X_Position,x      ;get distance between enemy object's
e145: 38                           sec                             ; horizontal coordinate and the player's
e146: e5 86                        sbc     Player_X_Position       ; horizontal coordinate
e148: 85 00                        sta     $00                     ;and store here
e14a: b5 6e                        lda     Enemy_PageLoc,x
e14c: e5 6d                        sbc     Player_PageLoc          ;subtract borrow, then leave
e14e: 60                           rts

                   ; -----------------------------------------------------------------------------
e14f: 20 63 c3     EnemyLanding    jsr     InitVStf                ;do something here to vertical speed and something else
e152: b5 cf                        lda     Enemy_Y_Position,x
e154: 29 f0                        and     #%11110000              ;save high nybble of vertical coordinate, and
e156: 09 08                        ora     #%00001000              ; set d3, then store, probably used to set enemy object
e158: 95 cf                        sta     Enemy_Y_Position,x      ; neatly on whatever it's landing on
e15a: 60                           rts

e15b: b5 cf        SubtEnemyYPos   lda     Enemy_Y_Position,x      ;add 62 pixels to enemy object's
e15d: 18                           clc                             ; vertical coordinate
e15e: 69 3e                        adc     #$3e
e160: c9 44                        cmp     #$44                    ;compare against a certain range
e162: 60                           rts                             ; and leave with flags set for conditional branch

e163: 20 5b e1     EnemyJump       jsr     SubtEnemyYPos           ;do a sub here
e166: 90 1a                        bcc     DoSide                  ;if enemy vertical coord + 62 < 68, branch to leave
e168: b5 a0                        lda     Enemy_Y_Speed,x
e16a: 18                           clc                             ;add two to vertical speed
e16b: 69 02                        adc     #$02
e16d: c9 03                        cmp     #$03                    ;if green paratroopa not falling, branch ahead
e16f: 90 11                        bcc     DoSide
e171: 20 ae e1                     jsr     ChkUnderEnemy           ;otherwise, check to see if green paratroopa is
e174: f0 0c                        beq     DoSide                  ; standing on anything, then branch to same place if not
e176: 20 b5 e1                     jsr     ChkForNonSolids         ;check for non-solid blocks
e179: f0 07                        beq     DoSide                  ;branch if found
e17b: 20 4f e1                     jsr     EnemyLanding            ;change vertical coordinate and speed
e17e: a9 fd                        lda     #$fd
e180: 95 a0                        sta     Enemy_Y_Speed,x         ;make the paratroopa jump again
e182: 4c fe e0     DoSide          jmp     DoEnemySideCheck        ;check for horizontal blockage, then leave

                   ; -----------------------------------------------------------------------------
e185: 20 ae e1     HammerBroBGColl jsr     ChkUnderEnemy           ;check to see if hammer bro is standing on anything
e188: f0 1d                        beq     NoUnderHammerBro
e18a: c9 23                        cmp     #$23                    ;check for blank metatile $23 and branch if not found
e18c: d0 08                        bne     UnderHammerBro
                   KillEnemyAboveBlock
e18e: 20 95 d7                     jsr     ShellOrBlockDefeat      ;do this sub to kill enemy
e191: a9 fc                        lda     #$fc                    ;alter vertical speed of enemy and leave
e193: 95 a0                        sta     Enemy_Y_Speed,x
e195: 60                           rts

e196: bd 8a 07     UnderHammerBro  lda     EnemyFrameTimer,x       ;check timer used by hammer bro
e199: d0 0c                        bne     NoUnderHammerBro        ;branch if not expired
e19b: b5 1e                        lda     Enemy_State,x
e19d: 29 88                        and     #%10001000              ;save d7 and d3 from enemy state, nullify other bits
e19f: 95 1e                        sta     Enemy_State,x           ;and store
e1a1: 20 4f e1                     jsr     EnemyLanding            ;modify vertical coordinate, speed and something else
e1a4: 4c fe e0                     jmp     DoEnemySideCheck        ;then check for horizontal blockage and leave

                   NoUnderHammerBro
e1a7: b5 1e                        lda     Enemy_State,x           ;if hammer bro is not standing on anything, set d0
e1a9: 09 01                        ora     #$01                    ; in the enemy state to indicate jumping or falling, then leave
e1ab: 95 1e                        sta     Enemy_State,x
e1ad: 60                           rts

e1ae: a9 00        ChkUnderEnemy   lda     #$00                    ;set flag in A for save vertical coordinate
e1b0: a0 15                        ldy     #$15                    ;set Y to check the bottom middle (8,18) of enemy object
e1b2: 4c 88 e3                     jmp     BlockBufferChk_Enemy    ;hop to it!

e1b5: c9 26        ChkForNonSolids cmp     #$26                    ;blank metatile used for vines?
e1b7: f0 0e                        beq     NSFnd
e1b9: c9 c2                        cmp     #$c2                    ;regular coin?
e1bb: f0 0a                        beq     NSFnd
e1bd: c9 c3                        cmp     #$c3                    ;underwater coin?
e1bf: f0 06                        beq     NSFnd
e1c1: c9 5f                        cmp     #$5f                    ;hidden coin block?
e1c3: f0 02                        beq     NSFnd
e1c5: c9 60                        cmp     #$60                    ;hidden 1-up block?
e1c7: 60           NSFnd           rts

                   FireballBGCollision
e1c8: b5 d5                        lda     Fireball_Y_Position,x   ;check fireball's vertical coordinate
e1ca: c9 18                        cmp     #$18
e1cc: 90 21                        bcc     ClearBounceFlag         ;if within the status bar area of the screen, branch ahead
e1ce: 20 9c e3                     jsr     BlockBufferChk_FBall    ;do fireball to background collision detection on bottom of it
e1d1: f0 1c                        beq     ClearBounceFlag         ;if nothing underneath fireball, branch
e1d3: 20 b5 e1                     jsr     ChkForNonSolids         ;check for non-solid metatiles
e1d6: f0 17                        beq     ClearBounceFlag         ;branch if any found
e1d8: b5 a6                        lda     Fireball_Y_Speed,x      ;if fireball's vertical speed set to move upwards,
e1da: 30 18                        bmi     InitFireballExplode     ;branch to set exploding bit in fireball's state
e1dc: b5 3a                        lda     FireballBouncingFlag,x  ;if bouncing flag already set,
e1de: d0 14                        bne     InitFireballExplode     ;branch to set exploding bit in fireball's state
e1e0: a9 fd                        lda     #$fd
e1e2: 95 a6                        sta     Fireball_Y_Speed,x      ;otherwise set vertical speed to move upwards (give it bounce)
e1e4: a9 01                        lda     #$01
e1e6: 95 3a                        sta     FireballBouncingFlag,x  ;set bouncing flag
e1e8: b5 d5                        lda     Fireball_Y_Position,x
e1ea: 29 f8                        and     #$f8                    ;modify vertical coordinate to land it properly
e1ec: 95 d5                        sta     Fireball_Y_Position,x   ;store as new vertical coordinate
e1ee: 60                           rts                             ;leave

e1ef: a9 00        ClearBounceFlag lda     #$00
e1f1: 95 3a                        sta     FireballBouncingFlag,x  ;clear bouncing flag by default
e1f3: 60                           rts                             ;leave

                   InitFireballExplode
e1f4: a9 80                        lda     #$80
e1f6: 95 24                        sta     Fireball_State,x        ;set exploding flag in fireball's state
e1f8: a9 02                        lda     #Sfx_Bump
e1fa: 85 ff                        sta     Square1SoundQueue       ;load bump sound
e1fc: 60                           rts                             ;leave

                   ; -----------------------------------------------------------------------------
                   ; $00 - used to hold one of bitmasks, or offset
                   ; $01 - used for relative X coordinate, also used to store middle screen page
                   ; location
                   ; $02 - used for relative Y coordinate, also used to store middle screen
                   ; coordinate
                   ; 
                   ; this data added to relative coordinates of sprite objects stored in order:
                   ; left edge, top edge, right edge, bottom edge
                   BoundBoxCtrlData
e1fd: 02 08 0e 20                  .bulk   $02,$08,$0e,$20
e201: 03 14 0d 20                  .bulk   $03,$14,$0d,$20
e205: 02 14 0e 20                  .bulk   $02,$14,$0e,$20
e209: 02 09 0e 15                  .bulk   $02,$09,$0e,$15
e20d: 00 00 18 06                  .bulk   $00,$00,$18,$06
e211: 00 00 20 0d                  .bulk   $00,$00,$20,$0d
e215: 00 00 30 0d                  .bulk   $00,$00,$30,$0d
e219: 00 00 08 08                  .bulk   $00,$00,$08,$08
e21d: 06 04 0a 08                  .bulk   $06,$04,$0a,$08
e221: 03 0e 0d 14                  .bulk   $03,$0e,$0d,$14
e225: 00 02 10 15                  .bulk   $00,$02,$10,$15
e229: 04 04 0c 1c                  .bulk   $04,$04,$0c,$1c

                   GetFireballBoundBox
e22d: 8a                           txa                             ;add seven bytes to offset
e22e: 18                           clc                             ; to use in routines as offset for fireball
e22f: 69 07                        adc     #$07
e231: aa                           tax
e232: a0 02                        ldy     #$02                    ;set offset for relative coordinates
e234: d0 07                        bne     FBallB                  ;unconditional branch

e236: 8a           GetMiscBoundBox txa                             ;add nine bytes to offset
e237: 18                           clc                             ; to use in routines as offset for misc object
e238: 69 09                        adc     #$09
e23a: aa                           tax
e23b: a0 06                        ldy     #$06                    ;set offset for relative coordinates
e23d: 20 9c e2     FBallB          jsr     BoundingBoxCore         ;get bounding box coordinates
e240: 4c de e2                     jmp     CheckRightScreenBBox    ;jump to handle any offscreen coordinates

                   GetEnemyBoundBox
e243: a0 48                        ldy     #$48                    ;store bitmask here for now
e245: 84 00                        sty     $00
e247: a0 44                        ldy     #$44                    ;store another bitmask here for now and jump
e249: 4c 52 e2                     jmp     GetMaskedOffScrBits

                   SmallPlatformBoundBox
e24c: a0 08                        ldy     #$08                    ;store bitmask here for now
e24e: 84 00                        sty     $00
e250: a0 04                        ldy     #$04                    ;store another bitmask here for now
                   GetMaskedOffScrBits
e252: b5 87                        lda     Enemy_X_Position,x      ;get enemy object position relative
e254: 38                           sec                             ; to the left side of the screen
e255: ed 1c 07                     sbc     ScreenLeft_X_Pos
e258: 85 01                        sta     $01                     ;store here
e25a: b5 6e                        lda     Enemy_PageLoc,x         ;subtract borrow from current page location
e25c: ed 1a 07                     sbc     ScreenLeft_PageLoc      ; of left side
e25f: 30 06                        bmi     CMBits                  ;if enemy object is beyond left edge, branch
e261: 05 01                        ora     $01
e263: f0 02                        beq     CMBits                  ;if precisely at the left edge, branch
e265: a4 00                        ldy     $00                     ;if to the right of left edge, use value in $00 for A
e267: 98           CMBits          tya                             ;otherwise use contents of Y
e268: 2d d1 03                     and     Enemy_OffscreenBits     ;preserve bitwise whatever's in here
e26b: 9d d8 03                     sta     EnemyOffscrBitsMasked,x ;save masked offscreen bits here
e26e: d0 19                        bne     MoveBoundBoxOffscreen   ;if anything set here, branch
e270: 4c 7c e2                     jmp     SetupEOffsetFBBox       ;otherwise, do something else

                   LargePlatformBoundBox
e273: e8                           inx                             ;increment X to get the proper offset
e274: 20 f6 f1                     jsr     GetXOffscreenBits       ;then jump directly to the sub for horizontal offscreen bits
e277: ca                           dex                             ;decrement to return to original offset
e278: c9 fe                        cmp     #$fe                    ;if completely offscreen, branch to put entire bounding
e27a: b0 0d                        bcs     MoveBoundBoxOffscreen   ; box offscreen, otherwise start getting coordinates
                   SetupEOffsetFBBox
e27c: 8a                           txa                             ;add 1 to offset to properly address
e27d: 18                           clc                             ; the enemy object memory locations
e27e: 69 01                        adc     #$01
e280: aa                           tax
e281: a0 01                        ldy     #$01                    ;load 1 as offset here, same reason
e283: 20 9c e2                     jsr     BoundingBoxCore         ;do a sub to get the coordinates of the bounding box
e286: 4c de e2                     jmp     CheckRightScreenBBox    ;jump to handle offscreen coordinates of bounding box

                   MoveBoundBoxOffscreen
e289: 8a                           txa                             ;multiply offset by 4
e28a: 0a                           asl     A
e28b: 0a                           asl     A
e28c: a8                           tay                             ;use as offset here
e28d: a9 ff                        lda     #$ff
e28f: 99 b0 04                     sta     EnemyBoundingBoxCoord,y ;load value into four locations here and leave
e292: 99 b1 04                     sta     EnemyBoundingBoxCoord+1,y
e295: 99 b2 04                     sta     EnemyBoundingBoxCoord+2,y
e298: 99 b3 04                     sta     EnemyBoundingBoxCoord+3,y
e29b: 60                           rts

e29c: 86 00        BoundingBoxCore stx     $00                     ;save offset here
e29e: b9 b8 03                     lda     SprObject_Rel_YPos,y    ;store object coordinates relative to screen
e2a1: 85 02                        sta     $02                     ;vertically and horizontally, respectively
e2a3: b9 ad 03                     lda     SprObject_Rel_XPos,y
e2a6: 85 01                        sta     $01
e2a8: 8a                           txa                             ;multiply offset by four and save to stack
e2a9: 0a                           asl     A
e2aa: 0a                           asl     A
e2ab: 48                           pha
e2ac: a8                           tay                             ;use as offset for Y, X is left alone
e2ad: bd 99 04                     lda     SprObj_BoundBoxCtrl,x   ;load value here to be used as offset for X
e2b0: 0a                           asl     A                       ;multiply that by four and use as X
e2b1: 0a                           asl     A
e2b2: aa                           tax
e2b3: a5 01                        lda     $01                     ;add the first number in the bounding box data to the
e2b5: 18                           clc                             ; relative horizontal coordinate using enemy object offset
e2b6: 7d fd e1                     adc     BoundBoxCtrlData,x      ; and store somewhere using same offset * 4
e2b9: 99 ac 04                     sta     BoundingBox_UL_XPos,y   ;store here
e2bc: a5 01                        lda     $01
e2be: 18                           clc
e2bf: 7d ff e1                     adc     BoundBoxCtrlData+2,x    ;add the third number in the bounding box data to the
e2c2: 99 ae 04                     sta     BoundingBox_DR_XPos,y   ; relative horizontal coordinate and store
e2c5: e8                           inx                             ;increment both offsets
e2c6: c8                           iny
e2c7: a5 02                        lda     $02                     ;add the second number to the relative vertical coordinate
e2c9: 18                           clc                             ; using incremented offset and store using the other
e2ca: 7d fd e1                     adc     BoundBoxCtrlData,x      ; incremented offset
e2cd: 99 ac 04                     sta     BoundingBox_UL_XPos,y
e2d0: a5 02                        lda     $02
e2d2: 18                           clc
e2d3: 7d ff e1                     adc     BoundBoxCtrlData+2,x    ;add the fourth number to the relative vertical coordinate
e2d6: 99 ae 04                     sta     BoundingBox_DR_XPos,y   ;and store
e2d9: 68                           pla                             ;get original offset loaded into $00 * y from stack
e2da: a8                           tay                             ;use as Y
e2db: a6 00                        ldx     $00                     ;get original offset and use as X again
e2dd: 60                           rts

                   CheckRightScreenBBox
e2de: ad 1c 07                     lda     ScreenLeft_X_Pos        ;add 128 pixels to left side of screen
e2e1: 18                           clc                             ; and store as horizontal coordinate of middle
e2e2: 69 80                        adc     #$80
e2e4: 85 02                        sta     $02
e2e6: ad 1a 07                     lda     ScreenLeft_PageLoc      ;add carry to page location of left side of screen
e2e9: 69 00                        adc     #$00                    ; and store as page location of middle
e2eb: 85 01                        sta     $01
e2ed: b5 86                        lda     SprObject_X_Position,x  ;get horizontal coordinate
e2ef: c5 02                        cmp     $02                     ;compare against middle horizontal coordinate
e2f1: b5 6d                        lda     SprObject_PageLoc,x     ;get page location
e2f3: e5 01                        sbc     $01                     ;subtract from middle page location
e2f5: 90 15                        bcc     CheckLeftScreenBBox     ;if object is on the left side of the screen, branch
e2f7: b9 ae 04                     lda     BoundingBox_DR_XPos,y   ;check right-side edge of bounding box for offscreen
e2fa: 30 0d                        bmi     NoOfs                   ; coordinates, branch if still on the screen
e2fc: a9 ff                        lda     #$ff                    ;load offscreen value here to use on one or both horizontal sides
e2fe: be ac 04                     ldx     BoundingBox_UL_XPos,y   ;check left-side edge of bounding box for offscreen
e301: 30 03                        bmi     SORte                   ; coordinates, and branch if still on the screen
e303: 99 ac 04                     sta     BoundingBox_UL_XPos,y   ;store offscreen value for left side
e306: 99 ae 04     SORte           sta     BoundingBox_DR_XPos,y   ;store offscreen value for right side
e309: a6 08        NoOfs           ldx     ObjectOffset            ;get object offset and leave
e30b: 60                           rts

                   CheckLeftScreenBBox
e30c: b9 ac 04                     lda     BoundingBox_UL_XPos,y   ;check left-side edge of bounding box for offscreen
e30f: 10 11                        bpl     NoOfs2                  ; coordinates, and branch if still on the screen
e311: c9 a0                        cmp     #$a0                    ;check to see if left-side edge is in the middle of the
e313: 90 0d                        bcc     NoOfs2                  ; screen or really offscreen, and branch if still on
e315: a9 00                        lda     #$00
e317: be ae 04                     ldx     BoundingBox_DR_XPos,y   ;check right-side edge of bounding box for offscreen
e31a: 10 03                        bpl     SOLft                   ; coordinates, branch if still onscreen
e31c: 99 ae 04                     sta     BoundingBox_DR_XPos,y   ;store offscreen value for right side
e31f: 99 ac 04     SOLft           sta     BoundingBox_UL_XPos,y   ;store offscreen value for left side
e322: a6 08        NoOfs2          ldx     ObjectOffset            ;get object offset and leave
e324: 60                           rts

                   ; -----------------------------------------------------------------------------
                   ; $06 - second object's offset
                   ; $07 - counter
                   PlayerCollisionCore
e325: a2 00                        ldx     #$00                    ;initialize X to use player's bounding box for comparison
                   SprObjectCollisionCore
e327: 84 06                        sty     $06                     ;save contents of Y here
e329: a9 01                        lda     #$01
e32b: 85 07                        sta     $07                     ;save value 1 here as counter, compare horizontal coordinates first
                   CollisionCoreLoop
e32d: b9 ac 04                     lda     BoundingBox_UL_XPos,y   ;compare left/top coordinates
e330: dd ac 04                     cmp     BoundingBox_UL_XPos,x   ; of first and second objects' bounding boxes
e333: b0 2a                        bcs     FirstBoxGreater         ;if first left/top => second, branch
e335: dd ae 04                     cmp     BoundingBox_DR_XPos,x   ;otherwise compare to right/bottom of second
e338: 90 12                        bcc     SecondBoxVerticalChk    ;if first left/top < second right/bottom, branch elsewhere
e33a: f0 42                        beq     CollisionFound          ;if somehow equal, collision, thus branch
e33c: b9 ae 04                     lda     BoundingBox_DR_XPos,y   ;if somehow greater, check to see if bottom of
e33f: d9 ac 04                     cmp     BoundingBox_UL_XPos,y   ; first object's bounding box is greater than its top
e342: 90 3a                        bcc     CollisionFound          ;if somehow less, vertical wrap collision, thus branch
e344: dd ac 04                     cmp     BoundingBox_UL_XPos,x   ;otherwise compare bottom of first bounding box to the top
e347: b0 35                        bcs     CollisionFound          ; of second box, and if equal or greater, collision, thus branch
e349: a4 06                        ldy     $06                     ;otherwise return with carry clear and Y = $0006
e34b: 60                           rts                             ;note horizontal wrapping never occurs

                   SecondBoxVerticalChk
e34c: bd ae 04                     lda     BoundingBox_DR_XPos,x   ;check to see if the vertical bottom of the box
e34f: dd ac 04                     cmp     BoundingBox_UL_XPos,x   ; is greater than the vertical top
e352: 90 2a                        bcc     CollisionFound          ;if somehow less, vertical wrap collision, thus branch
e354: b9 ae 04                     lda     BoundingBox_DR_XPos,y   ;otherwise compare horizontal right or vertical bottom
e357: dd ac 04                     cmp     BoundingBox_UL_XPos,x   ; of first box with horizontal left or vertical top of second box
e35a: b0 22                        bcs     CollisionFound          ;if equal or greater, collision, thus branch
e35c: a4 06                        ldy     $06                     ;otherwise return with carry clear and Y = $0006
e35e: 60                           rts

e35f: dd ac 04     FirstBoxGreater cmp     BoundingBox_UL_XPos,x   ;compare first and second box horizontal left/vertical top again
e362: f0 1a                        beq     CollisionFound          ;if first coordinate = second, collision, thus branch
e364: dd ae 04                     cmp     BoundingBox_DR_XPos,x   ;if not, compare with second object right or bottom edge
e367: 90 15                        bcc     CollisionFound          ;if left/top of first less than or equal to right/bottom of second
e369: f0 13                        beq     CollisionFound          ; then collision, thus branch
e36b: d9 ae 04                     cmp     BoundingBox_DR_XPos,y   ;otherwise check to see if top of first box is greater than bottom
e36e: 90 0a                        bcc     NoCollisionFound        ;if less than or equal, no collision, branch to end
e370: f0 08                        beq     NoCollisionFound
e372: b9 ae 04                     lda     BoundingBox_DR_XPos,y   ;otherwise compare bottom of first to top of second
e375: dd ac 04                     cmp     BoundingBox_UL_XPos,x   ;if bottom of first is greater than top of second, vertical wrap
e378: b0 04                        bcs     CollisionFound          ; collision, and branch, otherwise, proceed onwards here
                   NoCollisionFound
e37a: 18                           clc                             ;clear carry, then load value set earlier, then leave
e37b: a4 06                        ldy     $06                     ;like previous ones, if horizontal coordinates do not collide, we do
e37d: 60                           rts                             ; not bother checking vertical ones, because what's the point?

e37e: e8           CollisionFound  inx                             ;increment offsets on both objects to check
e37f: c8                           iny                             ; the vertical coordinates
e380: c6 07                        dec     $07                     ;decrement counter to reflect this
e382: 10 a9                        bpl     CollisionCoreLoop       ;if counter not expired, branch to loop
e384: 38                           sec                             ;otherwise we already did both sets, therefore collision, so set carry
e385: a4 06                        ldy     $06                     ;load original value set here earlier, then leave
e387: 60                           rts

                   ; -----------------------------------------------------------------------------
                   ; $02 - modified y coordinate
                   ; $03 - stores metatile involved in block buffer collisions
                   ; $04 - comes in with offset to block buffer adder data, goes out with low
                   ; nybble x/y coordinate
                   ; $05 - modified x coordinate
                   ; $06-$07 - block buffer address
                   BlockBufferChk_Enemy
e388: 48                           pha                             ;save contents of A to stack
e389: 8a                           txa
e38a: 18                           clc                             ;add 1 to X to run sub with enemy offset in mind
e38b: 69 01                        adc     #$01
e38d: aa                           tax
e38e: 68                           pla                             ;pull A from stack and jump elsewhere
e38f: 4c a5 e3                     jmp     BBChk_E

e392: 8a           unref_e392      txa
e393: 18                           clc                             ;supposedly used once to set offset for
e394: 69 0d                        adc     #$0d                    ; miscellaneous objects
e396: aa                           tax
e397: a0 1b                        ldy     #$1b                    ;supposedly used once to set offset for block buffer data
e399: 4c a3 e3                     jmp     ResJmpM                 ;probably used in early stages to do misc to bg collision detection

                   BlockBufferChk_FBall
e39c: a0 1a                        ldy     #$1a                    ;set offset for block buffer adder data
e39e: 8a                           txa
e39f: 18                           clc
e3a0: 69 07                        adc     #$07                    ;add seven bytes to use
e3a2: aa                           tax
e3a3: a9 00        ResJmpM         lda     #$00                    ;set A to return vertical coordinate
e3a5: 20 f0 e3     BBChk_E         jsr     BlockBufferCollision    ;do collision detection subroutine for sprite object
e3a8: a6 08                        ldx     ObjectOffset            ;get object offset
e3aa: c9 00                        cmp     #$00                    ;check to see if object bumped into anything
e3ac: 60                           rts

                   BlockBufferAdderData
e3ad: 00 07 0e                     .bulk   $00,$07,$0e
                   BlockBuffer_X_Adder
e3b0: 08 03 0c 02+                 .bulk   $08,$03,$0c,$02,$02,$0d,$0d,$08,$03,$0c,$02,$02,$0d,$0d,$08,$03
                                    +      $0c,$02,$02,$0d,$0d,$08,$00,$10,$04,$14,$04,$04
                   BlockBuffer_Y_Adder
e3cc: 04 20 20 08+                 .bulk   $04,$20,$20,$08,$18,$08,$18,$02,$20,$20,$08,$18,$08,$18,$12,$20
                                    +      $20,$18,$18,$18,$18,$18,$14,$14,$06,$06,$08,$10

                   BlockBufferColli_Feet
e3e8: c8                           iny                             ;if branched here, increment to next set of adders
                   BlockBufferColli_Head
e3e9: a9 00                        lda     #$00                    ;set flag to return vertical coordinate
e3eb: 2c                           bit β–Ό   $01a9                   ;BIT instruction opcode
                   BlockBufferColli_Side
e3ec: a9 01                        lda     #$01                    ;set flag to return horizontal coordinate
e3ee: a2 00                        ldx     #$00                    ;set offset for player object
                   BlockBufferCollision
e3f0: 48                           pha                             ;save contents of A to stack
e3f1: 84 04                        sty     $04                     ;save contents of Y here
e3f3: b9 b0 e3                     lda     BlockBuffer_X_Adder,y   ;add horizontal coordinate
e3f6: 18                           clc                             ; of object to value obtained using Y as offset
e3f7: 75 86                        adc     SprObject_X_Position,x
e3f9: 85 05                        sta     $05                     ;store here
e3fb: b5 6d                        lda     SprObject_PageLoc,x
e3fd: 69 00                        adc     #$00                    ;add carry to page location
e3ff: 29 01                        and     #$01                    ;get LSB, mask out all other bits
e401: 4a                           lsr     A                       ;move to carry
e402: 05 05                        ora     $05                     ;get stored value
e404: 6a                           ror     A                       ;rotate carry to MSB of A
e405: 4a                           lsr     A                       ; and effectively move high nybble to
e406: 4a                           lsr     A                       ; lower, LSB which became MSB will be
e407: 4a                           lsr     A                       ; d4 at this point
e408: 20 e1 9b                     jsr     GetBlockBufferAddr      ;get address of block buffer into $06, $07
e40b: a4 04                        ldy     $04                     ;get old contents of Y
e40d: b5 ce                        lda     SprObject_Y_Position,x  ;get vertical coordinate of object
e40f: 18                           clc
e410: 79 cc e3                     adc     BlockBuffer_Y_Adder,y   ;add it to value obtained using Y as offset
e413: 29 f0                        and     #%11110000              ;mask out low nybble
e415: 38                           sec
e416: e9 20                        sbc     #$20                    ;subtract 32 pixels for the status ba
e418: 85 02                        sta     $02                     ;store result here
e41a: a8                           tay                             ;use as offset for block buffer
e41b: b1 06                        lda     ($06),y                 ;check current content of block buffer
e41d: 85 03                        sta     $03                     ;and store here
e41f: a4 04                        ldy     $04                     ;get old contents of Y again
e421: 68                           pla                             ;pull A from stack
e422: d0 05                        bne     RetXC                   ;if A = 1, branch
e424: b5 ce                        lda     SprObject_Y_Position,x  ;if A = 0, load vertical coordinate
e426: 4c 2b e4                     jmp     RetYC                   ;and jump

e429: b5 86        RetXC           lda     SprObject_X_Position,x  ;otherwise load horizontal coordinate
e42b: 29 0f        RetYC           and     #%00001111              ;and mask out high nybble
e42d: 85 04                        sta     $04                     ;store masked out result here
e42f: a5 03                        lda     $03                     ;get saved content of block buffer
e431: 60                           rts                             ;and leave

                   ; -----------------------------------------------------------------------------
e432: ff                           .dd1    $ff                     ;unused byte
                   ; -----------------------------------------------------------------------------
                   ; $00 - offset to vine Y coordinate adder
                   ; $02 - offset to sprite data
e433: 00 30        VineYPosAdder   .bulk   $00,$30

e435: 84 00        DrawVine        sty     $00                     ;save offset here
e437: ad b9 03                     lda     Enemy_Rel_YPos          ;get relative vertical coordinate
e43a: 18                           clc
e43b: 79 33 e4                     adc     VineYPosAdder,y         ;add value using offset in Y to get value
e43e: be 9a 03                     ldx     VineObjOffset,y         ;get offset to vine
e441: bc e5 06                     ldy     Enemy_SprDataOffset,x   ;get sprite data offset
e444: 84 02                        sty     $02                     ;store sprite data offset here
e446: 20 ae e4                     jsr     SixSpriteStacker        ;stack six sprites on top of each other vertically
e449: ad ae 03                     lda     Enemy_Rel_XPos          ;get relative horizontal coordinate
e44c: 99 03 02                     sta     Sprite_X_Position,y     ;store in first, third and fifth sprites
e44f: 99 0b 02                     sta     Sprite_X_Position+8,y
e452: 99 13 02                     sta     Sprite_X_Position+16,y
e455: 18                           clc
e456: 69 06                        adc     #$06                    ;add six pixels to second, fourth and sixth sprites
e458: 99 07 02                     sta     Sprite_X_Position+4,y   ; to give characteristic staggered vine shape to
e45b: 99 0f 02                     sta     Sprite_X_Position+12,y  ; our vertical stack of sprites
e45e: 99 17 02                     sta     Sprite_X_Position+20,y
e461: a9 21                        lda     #%00100001              ;set bg priority and palette attribute bits
e463: 99 02 02                     sta     Sprite_Attributes,y     ;set in first, third and fifth sprites
e466: 99 0a 02                     sta     Sprite_Attributes+8,y
e469: 99 12 02                     sta     Sprite_Attributes+16,y
e46c: 09 40                        ora     #%01000000              ;additionally, set horizontal flip bit
e46e: 99 06 02                     sta     Sprite_Attributes+4,y   ; for second, fourth and sixth sprites
e471: 99 0e 02                     sta     Sprite_Attributes+12,y
e474: 99 16 02                     sta     Sprite_Attributes+20,y
e477: a2 05                        ldx     #$05                    ;set tiles for six sprites
e479: a9 e1        VineTL          lda     #$e1                    ;set tile number for sprite
e47b: 99 01 02                     sta     Sprite_Tilenumber,y
e47e: c8                           iny                             ;move offset to next sprite data
e47f: c8                           iny
e480: c8                           iny
e481: c8                           iny
e482: ca                           dex                             ;move onto next sprite
e483: 10 f4                        bpl     VineTL                  ;loop until all sprites are done
e485: a4 02                        ldy     $02                     ;get original offset
e487: a5 00                        lda     $00                     ;get offset to vine adding data
e489: d0 05                        bne     SkpVTop                 ;if offset not zero, skip this part
e48b: a9 e0                        lda     #$e0
e48d: 99 01 02                     sta     Sprite_Tilenumber,y     ;set other tile number for top of vine
e490: a2 00        SkpVTop         ldx     #$00                    ;start with the first sprite again
e492: ad 9d 03     ChkFTop         lda     VineStart_Y_Position    ;get original starting vertical coordinate
e495: 38                           sec
e496: f9 00 02                     sbc     Sprite_Y_Position,y     ;subtract top-most sprite's Y coordinate
e499: c9 64                        cmp     #$64                    ;if two coordinates are less than 100/$64 pixels
e49b: 90 05                        bcc     NextVSp                 ; apart, skip this to leave sprite alone
e49d: a9 f8                        lda     #$f8
e49f: 99 00 02                     sta     Sprite_Y_Position,y     ;otherwise move sprite offscreen
e4a2: c8           NextVSp         iny                             ;move offset to next OAM data
e4a3: c8                           iny
e4a4: c8                           iny
e4a5: c8                           iny
e4a6: e8                           inx                             ;move onto next sprite
e4a7: e0 06                        cpx     #$06                    ;do this until all sprites are checked
e4a9: d0 e7                        bne     ChkFTop
e4ab: a4 00                        ldy     $00                     ;return offset set earlier
e4ad: 60                           rts

                   SixSpriteStacker
e4ae: a2 06                        ldx     #$06                    ;do six sprites
e4b0: 99 00 02     StkLp           sta     Sprite_Data,y           ;store X or Y coordinate into OAM data
e4b3: 18                           clc
e4b4: 69 08                        adc     #$08                    ;add eight pixels
e4b6: c8                           iny
e4b7: c8                           iny                             ;move offset four bytes forward
e4b8: c8                           iny
e4b9: c8                           iny
e4ba: ca                           dex                             ;do another sprite
e4bb: d0 f3                        bne     StkLp                   ;do this until all sprites are done
e4bd: a4 02                        ldy     $02                     ;get saved OAM data offset and leave
e4bf: 60                           rts

                   ; -----------------------------------------------------------------------------
e4c0: 04 00 04 00  FirstSprXPos    .bulk   $04,$00,$04,$00
e4c4: 00 04 00 04  FirstSprYPos    .bulk   $00,$04,$00,$04
e4c8: 00 08 00 08  SecondSprXPos   .bulk   $00,$08,$00,$08
e4cc: 08 00 08 00  SecondSprYPos   .bulk   $08,$00,$08,$00
e4d0: 80 82 81 83  FirstSprTilenum .bulk   $80,$82,$81,$83
                   SecondSprTilenum
e4d4: 81 83 80 82                  .bulk   $81,$83,$80,$82
e4d8: 03 03 c3 c3  HammerSprAttrib .bulk   $03,$03,$c3,$c3

e4dc: bc f3 06     DrawHammer      ldy     Misc_SprDataOffset,x    ;get misc object OAM data offset
e4df: ad 47 07                     lda     TimerControl
e4e2: d0 08                        bne     ForceHPose              ;if master timer control set, skip this part
e4e4: b5 2a                        lda     Misc_State,x            ;otherwise get hammer's state
e4e6: 29 7f                        and     #%01111111              ;mask out d7
e4e8: c9 01                        cmp     #$01                    ;check to see if set to 1 yet
e4ea: f0 04                        beq     GetHPose                ;if so, branch
e4ec: a2 00        ForceHPose      ldx     #$00                    ;reset offset here
e4ee: f0 07                        beq     RdnerH                  ;do unconditional branch to rendering part

e4f0: a5 09        GetHPose        lda     FrameCounter            ;get frame counter
e4f2: 4a                           lsr     A                       ;move d3-d2 to d1-d0
e4f3: 4a                           lsr     A
e4f4: 29 03                        and     #%00000011              ;mask out all but d1-d0 (changes every four frames)
e4f6: aa                           tax                             ;use as timing offset
e4f7: ad be 03     RdnerH          lda     Misc_Rel_YPos           ;get relative vertical coordinate
e4fa: 18                           clc
e4fb: 7d c4 e4                     adc     FirstSprYPos,x          ;add first sprite vertical adder based on offset
e4fe: 99 00 02                     sta     Sprite_Y_Position,y     ;store as sprite Y coordinate for first sprite
e501: 18                           clc
e502: 7d cc e4                     adc     SecondSprYPos,x         ;add second sprite vertical adder based on offset
e505: 99 04 02                     sta     Sprite_Y_Position+4,y   ;store as sprite Y coordinate for second sprite
e508: ad b3 03                     lda     Misc_Rel_XPos           ;get relative horizontal coordinate
e50b: 18                           clc
e50c: 7d c0 e4                     adc     FirstSprXPos,x          ;add first sprite horizontal adder based on offset
e50f: 99 03 02                     sta     Sprite_X_Position,y     ;store as sprite X coordinate for first sprite
e512: 18                           clc
e513: 7d c8 e4                     adc     SecondSprXPos,x         ;add second sprite horizontal adder based on offset
e516: 99 07 02                     sta     Sprite_X_Position+4,y   ;store as sprite X coordinate for second sprite
e519: bd d0 e4                     lda     FirstSprTilenum,x
e51c: 99 01 02                     sta     Sprite_Tilenumber,y     ;get and store tile number of first sprite
e51f: bd d4 e4                     lda     SecondSprTilenum,x
e522: 99 05 02                     sta     Sprite_Tilenumber+4,y   ;get and store tile number of second sprite
e525: bd d8 e4                     lda     HammerSprAttrib,x
e528: 99 02 02                     sta     Sprite_Attributes,y     ;get and store attribute bytes for both
e52b: 99 06 02                     sta     Sprite_Attributes+4,y   ;note in this case they use the same data
e52e: a6 08                        ldx     ObjectOffset            ;get misc object offset
e530: ad d6 03                     lda     Misc_OffscreenBits
e533: 29 fc                        and     #%11111100              ;check offscreen bits
e535: f0 09                        beq     NoHOffscr               ;if all bits clear, leave object alone
e537: a9 00                        lda     #$00
e539: 95 2a                        sta     Misc_State,x            ;otherwise nullify misc object state
e53b: a9 f8                        lda     #$f8
e53d: 20 c1 e5                     jsr     DumpTwoSpr              ;do sub to move hammer sprites offscreen
e540: 60           NoHOffscr       rts                             ;leave

                   ; -----------------------------------------------------------------------------
                   ; $00-$01 - used to hold tile numbers ($01 addressed in draw floatey number
                   ; part)
                   ; $02 - used to hold Y coordinate for floatey number
                   ; $03 - residual byte used for flip (but value set here affects nothing)
                   ; $04 - attribute byte for floatey number
                   ; $05 - used as X coordinate for floatey number
                   FlagpoleScoreNumTiles
e541: f9 50                        .bulk   $f9,$50
e543: f7 50                        .bulk   $f7,$50
e545: fa fb                        .bulk   $fa,$fb
e547: f8 fb                        .bulk   $f8,$fb
e549: f6 fb                        .bulk   $f6,$fb

                   FlagpoleGfxHandler
e54b: bc e5 06                     ldy     Enemy_SprDataOffset,x   ;get sprite data offset for flagpole flag
e54e: ad ae 03                     lda     Enemy_Rel_XPos          ;get relative horizontal coordinate
e551: 99 03 02                     sta     Sprite_X_Position,y     ;store as X coordinate for first sprite
e554: 18                           clc
e555: 69 08                        adc     #$08                    ;add eight pixels and store
e557: 99 07 02                     sta     Sprite_X_Position+4,y   ; as X coordinate for second and third sprites
e55a: 99 0b 02                     sta     Sprite_X_Position+8,y
e55d: 18                           clc
e55e: 69 0c                        adc     #$0c                    ;add twelve more pixels and
e560: 85 05                        sta     $05                     ; store here to be used later by floatey number
e562: b5 cf                        lda     Enemy_Y_Position,x      ;get vertical coordinate
e564: 20 c1 e5                     jsr     DumpTwoSpr              ; and do sub to dump into first and second sprites
e567: 69 08                        adc     #$08                    ;add eight pixels
e569: 99 08 02                     sta     Sprite_Y_Position+8,y   ;and store into third sprite
e56c: ad 0d 01                     lda     FlagpoleFNum_Y_Pos      ;get vertical coordinate for floatey number
e56f: 85 02                        sta     $02                     ;store it here
e571: a9 01                        lda     #$01
e573: 85 03                        sta     $03                     ;set value for flip which will not be used, and
e575: 85 04                        sta     $04                     ; attribute byte for floatey number
e577: 99 02 02                     sta     Sprite_Attributes,y     ;set attribute bytes for all three sprites
e57a: 99 06 02                     sta     Sprite_Attributes+4,y
e57d: 99 0a 02                     sta     Sprite_Attributes+8,y
e580: a9 7e                        lda     #$7e
e582: 99 01 02                     sta     Sprite_Tilenumber,y     ;put triangle shaped tile
e585: 99 09 02                     sta     Sprite_Tilenumber+8,y   ; into first and third sprites
e588: a9 7f                        lda     #$7f
e58a: 99 05 02                     sta     Sprite_Tilenumber+4,y   ;put skull tile into second sprite
e58d: ad 0f 07                     lda     FlagpoleCollisionYPos   ;get vertical coordinate at time of collision
e590: f0 15                        beq     ChkFlagOffscreen        ;if zero, branch ahead
e592: 98                           tya
e593: 18                           clc                             ;add 12 bytes to sprite data offset
e594: 69 0c                        adc     #$0c
e596: a8                           tay                             ;put back in Y
e597: ad 0f 01                     lda     FlagpoleScore           ;get offset used to award points for touching flagpole
e59a: 0a                           asl     A                       ;multiply by 2 to get proper offset here
e59b: aa                           tax
e59c: bd 41 e5                     lda     FlagpoleScoreNumTiles,x ;get appropriate tile data
e59f: 85 00                        sta     $00
e5a1: bd 42 e5                     lda     FlagpoleScoreNumTiles+1,x
e5a4: 20 b2 eb                     jsr     DrawOneSpriteRow        ;use it to render floatey number
                   ChkFlagOffscreen
e5a7: a6 08                        ldx     ObjectOffset            ;get object offset for flag
e5a9: bc e5 06                     ldy     Enemy_SprDataOffset,x   ;get OAM data offset
e5ac: ad d1 03                     lda     Enemy_OffscreenBits     ;get offscreen bits
e5af: 29 0e                        and     #%00001110              ;mask out all but d3-d1
e5b1: f0 14                        beq     ExitDumpSpr             ;if none of these bits set, branch to leave
                   ; 
                   MoveSixSpritesOffscreen
e5b3: a9 f8                        lda     #$f8                    ;set offscreen coordinate if jumping here
e5b5: 99 14 02     DumpSixSpr      sta     Sprite_Data+20,y        ;dump A contents
e5b8: 99 10 02                     sta     Sprite_Data+16,y        ;into third row sprites
e5bb: 99 0c 02     DumpFourSpr     sta     Sprite_Data+12,y        ;into second row sprites
e5be: 99 08 02     DumpThreeSpr    sta     Sprite_Data+8,y
e5c1: 99 04 02     DumpTwoSpr      sta     Sprite_Data+4,y         ;and into first row sprites
e5c4: 99 00 02                     sta     Sprite_Data,y
e5c7: 60           ExitDumpSpr     rts

                   ; -----------------------------------------------------------------------------
                   DrawLargePlatform
e5c8: bc e5 06                     ldy     Enemy_SprDataOffset,x   ;get OAM data offset
e5cb: 84 02                        sty     $02                     ;store here
e5cd: c8                           iny                             ;add 3 to it for offset
e5ce: c8                           iny                             ; to X coordinate
e5cf: c8                           iny
e5d0: ad ae 03                     lda     Enemy_Rel_XPos          ;get horizontal relative coordinate
e5d3: 20 ae e4                     jsr     SixSpriteStacker        ;store X coordinates using A as base, stack horizontally
e5d6: a6 08                        ldx     ObjectOffset
e5d8: b5 cf                        lda     Enemy_Y_Position,x      ;get vertical coordinate
e5da: 20 bb e5                     jsr     DumpFourSpr             ;dump into first four sprites as Y coordinate
e5dd: ac 4e 07                     ldy     AreaType
e5e0: c0 03                        cpy     #$03                    ;check for castle-type level
e5e2: f0 05                        beq     ShrinkPlatform
e5e4: ac cc 06                     ldy     SecondaryHardMode       ;check for secondary hard mode flag set
e5e7: f0 02                        beq     SetLast2Platform        ;branch if not set elsewhere
e5e9: a9 f8        ShrinkPlatform  lda     #$f8                    ;load offscreen coordinate if flag set or castle-type level
                   SetLast2Platform
e5eb: bc e5 06                     ldy     Enemy_SprDataOffset,x   ;get OAM data offset
e5ee: 99 10 02                     sta     Sprite_Y_Position+16,y  ;store vertical coordinate or offscreen
e5f1: 99 14 02                     sta     Sprite_Y_Position+20,y  ; coordinate into last two sprites as Y coordinate
e5f4: a9 5b                        lda     #$5b                    ;load default tile for platform (girder)
e5f6: ae 43 07                     ldx     CloudTypeOverride
e5f9: f0 02                        beq     SetPlatformTilenum      ;if cloud level override flag not set, use
e5fb: a9 75                        lda     #$75                    ;otherwise load other tile for platform (puff)
                   SetPlatformTilenum
e5fd: a6 08                        ldx     ObjectOffset            ;get enemy object buffer offset
e5ff: c8                           iny                             ;increment Y for tile offset
e600: 20 b5 e5                     jsr     DumpSixSpr              ;dump tile number into all six sprites
e603: a9 02                        lda     #$02                    ;set palette controls
e605: c8                           iny                             ;increment Y for sprite attributes
e606: 20 b5 e5                     jsr     DumpSixSpr              ;dump attributes into all six sprites
e609: e8                           inx                             ;increment X for enemy objects
e60a: 20 f6 f1                     jsr     GetXOffscreenBits       ;get offscreen bits again
e60d: ca                           dex
e60e: bc e5 06                     ldy     Enemy_SprDataOffset,x   ;get OAM data offset
e611: 0a                           asl     A                       ;rotate d7 into carry, save remaining
e612: 48                           pha                             ;bits to the stack
e613: 90 05                        bcc     SChk2
e615: a9 f8                        lda     #$f8                    ;if d7 was set, move first sprite offscreen
e617: 99 00 02                     sta     Sprite_Y_Position,y
e61a: 68           SChk2           pla                             ;get bits from stack
e61b: 0a                           asl     A                       ;rotate d6 into carry
e61c: 48                           pha                             ;save to stack
e61d: 90 05                        bcc     SChk3
e61f: a9 f8                        lda     #$f8                    ;if d6 was set, move second sprite offscreen
e621: 99 04 02                     sta     Sprite_Y_Position+4,y
e624: 68           SChk3           pla                             ;get bits from stack
e625: 0a                           asl     A                       ;rotate d5 into carry
e626: 48                           pha                             ;save to stack
e627: 90 05                        bcc     SChk4
e629: a9 f8                        lda     #$f8                    ;if d5 was set, move third sprite offscreen
e62b: 99 08 02                     sta     Sprite_Y_Position+8,y
e62e: 68           SChk4           pla                             ;get bits from stack
e62f: 0a                           asl     A                       ;rotate d4 into carry
e630: 48                           pha                             ;save to stack
e631: 90 05                        bcc     SChk5
e633: a9 f8                        lda     #$f8                    ;if d4 was set, move fourth sprite offscreen
e635: 99 0c 02                     sta     Sprite_Y_Position+12,y
e638: 68           SChk5           pla                             ;get bits from stack
e639: 0a                           asl     A                       ;rotate d3 into carry
e63a: 48                           pha                             ;save to stack
e63b: 90 05                        bcc     SChk6
e63d: a9 f8                        lda     #$f8                    ;if d3 was set, move fifth sprite offscreen
e63f: 99 10 02                     sta     Sprite_Y_Position+16,y
e642: 68           SChk6           pla                             ;get bits from stack
e643: 0a                           asl     A                       ;rotate d2 into carry
e644: 90 05                        bcc     SLChk                   ;save to stack
e646: a9 f8                        lda     #$f8
e648: 99 14 02                     sta     Sprite_Y_Position+20,y  ;if d2 was set, move sixth sprite offscreen
e64b: ad d1 03     SLChk           lda     Enemy_OffscreenBits     ;check d7 of offscreen bits
e64e: 0a                           asl     A                       ;and if d7 is not set, skip sub
e64f: 90 03                        bcc     ExDLPl
e651: 20 b3 e5                     jsr     MoveSixSpritesOffscreen ;otherwise branch to move all sprites offscreen
e654: 60           ExDLPl          rts

                   ; -----------------------------------------------------------------------------
                   DrawFloateyNumber_Coin
e655: a5 09                        lda     FrameCounter            ;get frame counter
e657: 4a                           lsr     A                       ;divide by 2
e658: b0 02                        bcs     NotRsNum                ;branch if d0 not set to raise number every other frame
e65a: d6 db                        dec     Misc_Y_Position,x       ;otherwise, decrement vertical coordinate
e65c: b5 db        NotRsNum        lda     Misc_Y_Position,x       ;get vertical coordinate
e65e: 20 c1 e5                     jsr     DumpTwoSpr              ;dump into both sprites
e661: ad b3 03                     lda     Misc_Rel_XPos           ;get relative horizontal coordinate
e664: 99 03 02                     sta     Sprite_X_Position,y     ;store as X coordinate for first sprite
e667: 18                           clc
e668: 69 08                        adc     #$08                    ;add eight pixels
e66a: 99 07 02                     sta     Sprite_X_Position+4,y   ;store as X coordinate for second sprite
e66d: a9 02                        lda     #$02
e66f: 99 02 02                     sta     Sprite_Attributes,y     ;store attribute byte in both sprites
e672: 99 06 02                     sta     Sprite_Attributes+4,y
e675: a9 f7                        lda     #$f7
e677: 99 01 02                     sta     Sprite_Tilenumber,y     ;put tile numbers into both sprites
e67a: a9 fb                        lda     #$fb                    ; that resemble "200"
e67c: 99 05 02                     sta     Sprite_Tilenumber+4,y
e67f: 4c bd e6                     jmp     ExJcGfx                 ;then jump to leave (why not an rts here instead?)

                   JumpingCoinTiles
e682: 60 61 62 63                  .bulk   $60,$61,$62,$63

e686: bc f3 06     JCoinGfxHandler ldy     Misc_SprDataOffset,x    ;get coin/floatey number's OAM data offset
e689: b5 2a                        lda     Misc_State,x            ;get state of misc object
e68b: c9 02                        cmp     #$02                    ;if 2 or greater,
e68d: b0 c6                        bcs     DrawFloateyNumber_Coin  ; branch to draw floatey number
e68f: b5 db                        lda     Misc_Y_Position,x       ;store vertical coordinate as
e691: 99 00 02                     sta     Sprite_Y_Position,y     ; Y coordinate for first sprite
e694: 18                           clc
e695: 69 08                        adc     #$08                    ;add eight pixels
e697: 99 04 02                     sta     Sprite_Y_Position+4,y   ;store as Y coordinate for second sprite
e69a: ad b3 03                     lda     Misc_Rel_XPos           ;get relative horizontal coordinate
e69d: 99 03 02                     sta     Sprite_X_Position,y
e6a0: 99 07 02                     sta     Sprite_X_Position+4,y   ;store as X coordinate for first and second sprites
e6a3: a5 09                        lda     FrameCounter            ;get frame counter
e6a5: 4a                           lsr     A                       ;divide by 2 to alter every other frame
e6a6: 29 03                        and     #%00000011              ;mask out d2-d1
e6a8: aa                           tax                             ;use as graphical offset
e6a9: bd 82 e6                     lda     JumpingCoinTiles,x      ;load tile number
e6ac: c8                           iny                             ;increment OAM data offset to write tile numbers
e6ad: 20 c1 e5                     jsr     DumpTwoSpr              ;do sub to dump tile number into both sprites
e6b0: 88                           dey                             ;decrement to get old offset
e6b1: a9 02                        lda     #$02
e6b3: 99 02 02                     sta     Sprite_Attributes,y     ;set attribute byte in first sprite
e6b6: a9 82                        lda     #$82
e6b8: 99 06 02                     sta     Sprite_Attributes+4,y   ;set attribute byte with vertical flip in second sprite
e6bb: a6 08                        ldx     ObjectOffset            ;get misc object offset
e6bd: 60           ExJcGfx         rts                             ;leave

                   ; -----------------------------------------------------------------------------
                   ; $00-$01 - used to hold tiles for drawing the power-up, $00 also used to hold
                   ; power-up type
                   ; $02 - used to hold bottom row Y position
                   ; $03 - used to hold flip control (not used here)
                   ; $04 - used to hold sprite attributes
                   ; $05 - used to hold X position
                   ; $07 - counter
                   ; 
                   ; tiles arranged in top left, right, bottom left, right order
e6be: 76 77 78 79  PowerUpGfxTable .bulk   $76,$77,$78,$79
e6c2: d6 d6 d9 d9                  .bulk   $d6,$d6,$d9,$d9
e6c6: 8d 8d e4 e4                  .bulk   $8d,$8d,$e4,$e4
e6ca: 76 77 78 79                  .bulk   $76,$77,$78,$79
                   PowerUpAttributes
e6ce: 02 01 02 01                  .bulk   $02,$01,$02,$01

e6d2: ac ea 06     DrawPowerUp     ldy     Enemy_SprDataOffset+5   ;get power-up's sprite data offset
e6d5: ad b9 03                     lda     Enemy_Rel_YPos          ;get relative vertical coordinate
e6d8: 18                           clc
e6d9: 69 08                        adc     #$08                    ;add eight pixels
e6db: 85 02                        sta     $02                     ;store result here
e6dd: ad ae 03                     lda     Enemy_Rel_XPos          ;get relative horizontal coordinate
e6e0: 85 05                        sta     $05                     ;store here
e6e2: a6 39                        ldx     PowerUpType             ;get power-up type
e6e4: bd ce e6                     lda     PowerUpAttributes,x     ;get attribute data for power-up type
e6e7: 0d ca 03                     ora     Enemy_SprAttrib+5       ;add background priority bit if set
e6ea: 85 04                        sta     $04                     ;store attributes here
e6ec: 8a                           txa
e6ed: 48                           pha                             ;save power-up type to the stack
e6ee: 0a                           asl     A
e6ef: 0a                           asl     A                       ;multiply by four to get proper offset
e6f0: aa                           tax                             ;use as X
e6f1: a9 01                        lda     #$01
e6f3: 85 07                        sta     $07                     ;set counter here to draw two rows of sprite object
e6f5: 85 03                        sta     $03                     ;init d1 of flip control
e6f7: bd be e6     PUpDrawLoop     lda     PowerUpGfxTable,x       ;load left tile of power-up object
e6fa: 85 00                        sta     $00
e6fc: bd bf e6                     lda     PowerUpGfxTable+1,x     ;load right tile
e6ff: 20 b2 eb                     jsr     DrawOneSpriteRow        ;branch to draw one row of our power-up object
e702: c6 07                        dec     $07                     ;decrement counter
e704: 10 f1                        bpl     PUpDrawLoop             ;branch until two rows are drawn
e706: ac ea 06                     ldy     Enemy_SprDataOffset+5   ;get sprite data offset again
e709: 68                           pla                             ;pull saved power-up type from the stack
e70a: f0 2f                        beq     PUpOfs                  ;if regular mushroom, branch, do not change colors or flip
e70c: c9 03                        cmp     #$03
e70e: f0 2b                        beq     PUpOfs                  ;if 1-up mushroom, branch, do not change colors or flip
e710: 85 00                        sta     $00                     ;store power-up type here now
e712: a5 09                        lda     FrameCounter            ;get frame counter
e714: 4a                           lsr     A                       ;divide by 2 to change colors every two frames
e715: 29 03                        and     #%00000011              ;mask out all but d1 and d0 (previously d2 and d1)
e717: 0d ca 03                     ora     Enemy_SprAttrib+5       ;add background priority bit if any set
e71a: 99 02 02                     sta     Sprite_Attributes,y     ;set as new palette bits for top left and
e71d: 99 06 02                     sta     Sprite_Attributes+4,y   ;top right sprites for fire flower and star
e720: a6 00                        ldx     $00
e722: ca                           dex                             ;check power-up type for fire flower
e723: f0 06                        beq     FlipPUpRightSide        ;if found, skip this part
e725: 99 0a 02                     sta     Sprite_Attributes+8,y   ;otherwise set new palette bits  for bottom left
e728: 99 0e 02                     sta     Sprite_Attributes+12,y  ; and bottom right sprites as well for star only
                   FlipPUpRightSide
e72b: b9 06 02                     lda     Sprite_Attributes+4,y
e72e: 09 40                        ora     #%01000000              ;set horizontal flip bit for top right sprite
e730: 99 06 02                     sta     Sprite_Attributes+4,y
e733: b9 0e 02                     lda     Sprite_Attributes+12,y
e736: 09 40                        ora     #%01000000              ;set horizontal flip bit for bottom right sprite
e738: 99 0e 02                     sta     Sprite_Attributes+12,y  ;note these are only done for fire flower and star power-ups
e73b: 4c 64 eb     PUpOfs          jmp     SprObjectOffscrChk      ;jump to check to see if power-up is offscreen at all, then leave

                   ; -----------------------------------------------------------------------------
                   ; $00-$01 - used in DrawEnemyObjRow to hold sprite tile numbers
                   ; $02 - used to store Y position
                   ; $03 - used to store moving direction, used to flip enemies horizontally
                   ; $04 - used to store enemy's sprite attributes
                   ; $05 - used to store X position
                   ; $eb - used to hold sprite data offset
                   ; $ec - used to hold either altered enemy state or special value used in gfx
                   ; handler as condition
                   ; $ed - used to hold enemy state from buffer 
                   ; $ef - used to hold enemy code used in gfx handler (may or may not resemble
                   ; Enemy_ID values)
                   ; 
                   ; tiles arranged in top left, right, middle left, right, bottom left, right
                   ; order
                   vis
                   EnemyGraphicsTable
e73e: fc fc aa ab+                 .bulk   $fc,$fc,$aa,$ab,$ac,$ad ;buzzy beetle frame 1

                   vis
e744: fc fc ae af+                 .bulk   $fc,$fc,$ae,$af,$b0,$b1 ;             frame 2

                   vis
e74a: fc a5 a6 a7+                 .bulk   $fc,$a5,$a6,$a7,$a8,$a9 ;koopa troopa frame 1

                   vis
e750: fc a0 a1 a2+                 .bulk   $fc,$a0,$a1,$a2,$a3,$a4 ;             frame 2

                   vis
e756: 69 a5 6a a7+                 .bulk   $69,$a5,$6a,$a7,$a8,$a9 ;koopa paratroopa frame 1

                   vis
e75c: 6b a0 6c a2+                 .bulk   $6b,$a0,$6c,$a2,$a3,$a4 ;                 frame 2

                   vis
e762: fc fc 96 97+                 .bulk   $fc,$fc,$96,$97,$98,$99 ;spiny frame 1

                   vis
e768: fc fc 9a 9b+                 .bulk   $fc,$fc,$9a,$9b,$9c,$9d ;      frame 2

                   vis
e76e: fc fc 8f 8e+                 .bulk   $fc,$fc,$8f,$8e,$8e,$8f ;spiny's egg frame 1

                   vis
e774: fc fc 95 94+                 .bulk   $fc,$fc,$95,$94,$94,$95 ;            frame 2

                   vis
e77a: fc fc dc dc+                 .bulk   $fc,$fc,$dc,$dc,$df,$df ;bloober frame 1

                   vis
e780: dc dc dd dd+                 .bulk   $dc,$dc,$dd,$dd,$de,$de ;        frame 2

                   vis
e786: fc fc b2 b3+                 .bulk   $fc,$fc,$b2,$b3,$b4,$b5 ;cheep-cheep frame 1

                   vis
e78c: fc fc b6 b3+                 .bulk   $fc,$fc,$b6,$b3,$b7,$b5 ;            frame 2

                   vis
e792: fc fc 70 71+                 .bulk   $fc,$fc,$70,$71,$72,$73 ;goomba

                   vis
e798: fc fc 6e 6e+                 .bulk   $fc,$fc,$6e,$6e,$6f,$6f ;koopa shell frame 1 (upside-down)

                   vis
e79e: fc fc 6d 6d+                 .bulk   $fc,$fc,$6d,$6d,$6f,$6f ;            frame 2

                   vis
e7a4: fc fc 6f 6f+                 .bulk   $fc,$fc,$6f,$6f,$6e,$6e ;koopa shell frame 1 (rightsideup)

                   vis
e7aa: fc fc 6f 6f+                 .bulk   $fc,$fc,$6f,$6f,$6d,$6d ;            frame 2

                   vis
e7b0: fc fc f4 f4+                 .bulk   $fc,$fc,$f4,$f4,$f5,$f5 ;buzzy beetle shell frame 1 (rightsideup)

                   vis
e7b6: fc fc f4 f4+                 .bulk   $fc,$fc,$f4,$f4,$f5,$f5 ;                   frame 2

                   vis
e7bc: fc fc f5 f5+                 .bulk   $fc,$fc,$f5,$f5,$f4,$f4 ;buzzy beetle shell frame 1 (upside-down)

                   vis
e7c2: fc fc f5 f5+                 .bulk   $fc,$fc,$f5,$f5,$f4,$f4 ;                   frame 2

                   vis
e7c8: fc fc fc fc+                 .bulk   $fc,$fc,$fc,$fc,$ef,$ef ;defeated goomba

                   vis
e7ce: b9 b8 bb ba+                 .bulk   $b9,$b8,$bb,$ba,$bc,$bc ;lakitu frame 1

                   vis
e7d4: fc fc bd bd+                 .bulk   $fc,$fc,$bd,$bd,$bc,$bc ;       frame 2

                   vis
e7da: 7a 7b da db+                 .bulk   $7a,$7b,$da,$db,$d8,$d8 ;princess

                   vis
e7e0: cd cd ce ce+                 .bulk   $cd,$cd,$ce,$ce,$cf,$cf ;mushroom retainer

                   vis vis
e7e6: 7d 7c d1 8c+                 .bulk   $7d,$7c,$d1,$8c,$d3,$d2 ;hammer bro frame 1

                   vis
e7ec: 7d 7c 89 88+                 .bulk   $7d,$7c,$89,$88,$8b,$8a ;           frame 2

                   vis
e7f2: d5 d4 e3 e2+                 .bulk   $d5,$d4,$e3,$e2,$d3,$d2 ;           frame 3

                   vis
e7f8: d5 d4 e3 e2+                 .bulk   $d5,$d4,$e3,$e2,$8b,$8a ;           frame 4

                   vis
e7fe: e5 e5 e6 e6+                 .bulk   $e5,$e5,$e6,$e6,$eb,$eb ;piranha plant frame 1

                   vis
e804: ec ec ed ed+                 .bulk   $ec,$ec,$ed,$ed,$ee,$ee ;              frame 2

                   vis
e80a: fc fc d0 d0+                 .bulk   $fc,$fc,$d0,$d0,$d7,$d7 ;podoboo

                   vis
e810: bf be c1 c0+                 .bulk   $bf,$be,$c1,$c0,$c2,$fc ;bowser front frame 1

                   vis
e816: c4 c3 c6 c5+                 .bulk   $c4,$c3,$c6,$c5,$c8,$c7 ;bowser rear frame 1

                   vis
e81c: bf be ca c9+                 .bulk   $bf,$be,$ca,$c9,$c2,$fc ;       front frame 2

                   vis
e822: c4 c3 c6 c5+                 .bulk   $c4,$c3,$c6,$c5,$cc,$cb ;       rear frame 2

                   vis
e828: fc fc e8 e7+                 .bulk   $fc,$fc,$e8,$e7,$ea,$e9 ;bullet bill

                   vis
e82e: f2 f2 f3 f3+                 .bulk   $f2,$f2,$f3,$f3,$f2,$f2 ;jumpspring frame 1

                   vis
e834: f1 f1 f1 f1+                 .bulk   $f1,$f1,$f1,$f1,$fc,$fc ;           frame 2

                   vis
e83a: f0 f0 fc fc+                 .bulk   $f0,$f0,$fc,$fc,$fc,$fc ;           frame 3
                   EnemyGfxTableOffsets
e840: 0c 0c 00 0c+                 .bulk   $0c,$0c,$00,$0c,$0c,$a8,$54,$3c,$ea,$18,$48,$48,$cc,$c0,$18,$18
                                    +      $18,$90,$24,$ff,$48,$9c,$d2,$d8,$f0,$f6,$fc
                   EnemyAttributeData
e85b: 01 02 03 02+                 .bulk   $01,$02,$03,$02,$01,$01,$03,$03,$03,$01,$01,$02,$02,$21,$01,$02
                                    +      $01,$01,$02,$ff,$02,$02,$01,$01,$02,$02,$02
                   EnemyAnimTimingBMask
e876: 08 18                        .bulk   $08,$18
                   JumpspringFrameOffsets
e878: 18 19 1a 19+                 .bulk   $18,$19,$1a,$19,$18

e87d: b5 cf        EnemyGfxHandler lda     Enemy_Y_Position,x      ;get enemy object vertical position
e87f: 85 02                        sta     $02
e881: ad ae 03                     lda     Enemy_Rel_XPos          ;get enemy object horizontal position
e884: 85 05                        sta     $05                     ; relative to screen
e886: bc e5 06                     ldy     Enemy_SprDataOffset,x
e889: 84 eb                        sty     $eb                     ;get sprite data offset
e88b: a9 00                        lda     #$00
e88d: 8d 09 01                     sta     VerticalFlipFlag        ;initialize vertical flip flag by default
e890: b5 46                        lda     Enemy_MovingDir,x
e892: 85 03                        sta     $03                     ;get enemy object moving direction
e894: bd c5 03                     lda     Enemy_SprAttrib,x
e897: 85 04                        sta     $04                     ;get enemy object sprite attributes
e899: b5 16                        lda     Enemy_ID,x
e89b: c9 0d                        cmp     #PiranhaPlant           ;is enemy object piranha plant?
e89d: d0 0a                        bne     CheckForRetainerObj     ;if not, branch
e89f: b4 58                        ldy     PiranhaPlant_Y_Speed,x
e8a1: 30 06                        bmi     CheckForRetainerObj     ;if piranha plant moving upwards, branch
e8a3: bc 8a 07                     ldy     EnemyFrameTimer,x
e8a6: f0 01                        beq     CheckForRetainerObj     ;if timer for movement expired, branch
e8a8: 60                           rts                             ;if all conditions fail, leave

                   CheckForRetainerObj
e8a9: b5 1e                        lda     Enemy_State,x           ;store enemy state
e8ab: 85 ed                        sta     $ed
e8ad: 29 1f                        and     #%00011111              ;nullify all but 5 LSB and use as Y
e8af: a8                           tay
e8b0: b5 16                        lda     Enemy_ID,x              ;check for mushroom retainer/princess object
e8b2: c9 35                        cmp     #$35
e8b4: d0 08                        bne     CheckForBulletBillCV    ;if not found, branch
e8b6: a0 00                        ldy     #$00                    ;if found, nullify saved state in Y
e8b8: a9 01                        lda     #$01                    ;set value that will not be used
e8ba: 85 03                        sta     $03
e8bc: a9 15                        lda     #$15                    ;set value $15 as code for mushroom retainer/princess object
                   CheckForBulletBillCV
e8be: c9 33                        cmp     #BulletBill_CannonVar   ;otherwise check for bullet bill object
e8c0: d0 13                        bne     CheckForJumpspring      ;if not found, branch again
e8c2: c6 02                        dec     $02                     ;decrement saved vertical position
e8c4: a9 03                        lda     #$03
e8c6: bc 8a 07                     ldy     EnemyFrameTimer,x       ;get timer for enemy object
e8c9: f0 02                        beq     SBBAt                   ;if expired, do not set priority bit
e8cb: 09 20                        ora     #%00100000              ;otherwise do so
e8cd: 85 04        SBBAt           sta     $04                     ;set new sprite attributes
e8cf: a0 00                        ldy     #$00                    ;nullify saved enemy state both in Y and in
e8d1: 84 ed                        sty     $ed                     ; memory location here
e8d3: a9 08                        lda     #$08                    ;set specific value to unconditionally branch once
                   CheckForJumpspring
e8d5: c9 32                        cmp     #JumpspringObject       ;check for jumpspring object
e8d7: d0 08                        bne     CheckForPodoboo
e8d9: a0 03                        ldy     #$03                    ;set enemy state -2 MSB here for jumpspring object
e8db: ae 0e 07                     ldx     JumpspringAnimCtrl      ;get current frame number for jumpspring object
e8de: bd 78 e8                     lda     JumpspringFrameOffsets,x ;load data using frame number as offset
e8e1: 85 ef        CheckForPodoboo sta     $ef                     ;store saved enemy object value here
e8e3: 84 ec                        sty     $ec                     ; and Y here (enemy state -2 MSB if not changed)
e8e5: a6 08                        ldx     ObjectOffset            ;get enemy object offset
e8e7: c9 0c                        cmp     #$0c                    ;check for podoboo object
e8e9: d0 07                        bne     CheckBowserGfxFlag      ;branch if not found
e8eb: b5 a0                        lda     Enemy_Y_Speed,x         ;if moving upwards, branch
e8ed: 30 03                        bmi     CheckBowserGfxFlag
e8ef: ee 09 01                     inc     VerticalFlipFlag        ;otherwise, set flag for vertical flip
                   CheckBowserGfxFlag
e8f2: ad 6a 03                     lda     BowserGfxFlag           ;if not drawing bowser at all, skip to something else
e8f5: f0 09                        beq     CheckForGoomba
e8f7: a0 16                        ldy     #$16                    ;if set to 1, draw bowser's front
e8f9: c9 01                        cmp     #$01
e8fb: f0 01                        beq     SBwsrGfxOfs
e8fd: c8                           iny                             ;otherwise draw bowser's rear
e8fe: 84 ef        SBwsrGfxOfs     sty     $ef
e900: a4 ef        CheckForGoomba  ldy     $ef                     ;check value for goomba object
e902: c0 06                        cpy     #$06
e904: d0 1d                        bne     CheckBowserFront        ;branch if not found
e906: b5 1e                        lda     Enemy_State,x
e908: c9 02                        cmp     #$02                    ;check for defeated state
e90a: 90 04                        bcc     GmbaAnim                ;if not defeated, go ahead and animate
e90c: a2 04                        ldx     #$04                    ;if defeated, write new value here
e90e: 86 ec                        stx     $ec
e910: 29 20        GmbaAnim        and     #%00100000              ;check for d5 set in enemy object state 
e912: 0d 47 07                     ora     TimerControl            ;or timer disable flag set
e915: d0 0c                        bne     CheckBowserFront        ;if either condition true, do not animate goomba
e917: a5 09                        lda     FrameCounter
e919: 29 08                        and     #%00001000              ;check for every eighth frame
e91b: d0 06                        bne     CheckBowserFront
e91d: a5 03                        lda     $03
e91f: 49 03                        eor     #%00000011              ;invert bits to flip horizontally every eight frames
e921: 85 03                        sta     $03                     ;leave alone otherwise
                   CheckBowserFront
e923: b9 5b e8                     lda     EnemyAttributeData,y    ;load sprite attribute using enemy object
e926: 05 04                        ora     $04                     ; as offset, and add to bits already loaded
e928: 85 04                        sta     $04
e92a: b9 40 e8                     lda     EnemyGfxTableOffsets,y  ;load value based on enemy object as offset
e92d: aa                           tax                             ;save as X
e92e: a4 ec                        ldy     $ec                     ;get previously saved value
e930: ad 6a 03                     lda     BowserGfxFlag
e933: f0 30                        beq     CheckForSpiny           ;if not drawing bowser object at all, skip all of this
e935: c9 01                        cmp     #$01
e937: d0 13                        bne     CheckBowserRear         ;if not drawing front part, branch to draw the rear part
e939: ad 63 03                     lda     BowserBodyControls      ;check bowser's body control bits
e93c: 10 02                        bpl     CheckFrontSte           ;branch if d7 not set (control's bowser's mouth) 
e93e: a2 de                        ldx     #$de                    ;otherwise load offset for second frame
e940: a5 ed        CheckFrontSte   lda     $ed                     ;check saved enemy state
e942: 29 20                        and     #%00100000              ;if bowser not defeated, do not set flag
e944: f0 03                        beq     DrawBowser
e946: 8e 09 01     FlipBowserOver  stx     VerticalFlipFlag        ;set vertical flip flag to nonzero
e949: 4c 4b ea     DrawBowser      jmp     DrawEnemyObject         ;draw bowser's graphics now

e94c: ad 63 03     CheckBowserRear lda     BowserBodyControls      ;check bowser's body control bits
e94f: 29 01                        and     #$01
e951: f0 02                        beq     ChkRearSte              ;branch if d0 not set (control's bowser's feet)
e953: a2 e4                        ldx     #$e4                    ;otherwise load offset for second frame
e955: a5 ed        ChkRearSte      lda     $ed                     ;check saved enemy state
e957: 29 20                        and     #%00100000              ;if bowser not defeated, do not set flag
e959: f0 ee                        beq     DrawBowser
e95b: a5 02                        lda     $02                     ;subtract 16 pixels from
e95d: 38                           sec                             ; saved vertical coordinate
e95e: e9 10                        sbc     #$10
e960: 85 02                        sta     $02
e962: 4c 46 e9                     jmp     FlipBowserOver          ;jump to set vertical flip flag

e965: e0 24        CheckForSpiny   cpx     #$24                    ;check if value loaded is for spiny
e967: d0 11                        bne     CheckForLakitu          ;if not found, branch
e969: c0 05                        cpy     #$05                    ;if enemy state set to $05, do this,
e96b: d0 0a                        bne     NotEgg                  ; otherwise branch
e96d: a2 30                        ldx     #$30                    ;set to spiny egg offset
e96f: a9 02                        lda     #$02
e971: 85 03                        sta     $03                     ;set enemy direction to reverse sprites horizontally
e973: a9 05                        lda     #$05
e975: 85 ec                        sta     $ec                     ;set enemy state
e977: 4c ca e9     NotEgg          jmp     CheckForHammerBro       ;skip a big chunk of this if we found spiny but not in egg

e97a: e0 90        CheckForLakitu  cpx     #$90                    ;check value for lakitu's offset loaded
e97c: d0 12                        bne     CheckUpsideDownShell    ;branch if not loaded
e97e: a5 ed                        lda     $ed
e980: 29 20                        and     #%00100000              ;check for d5 set in enemy state
e982: d0 09                        bne     NoLAFr                  ;branch if set
e984: ad 8f 07                     lda     FrenzyEnemyTimer
e987: c9 10                        cmp     #$10                    ;check timer to see if we've reached a certain range
e989: b0 02                        bcs     NoLAFr                  ;branch if not
e98b: a2 96                        ldx     #$96                    ;if d6 not set and timer in range, load alt frame for lakitu
e98d: 4c 37 ea     NoLAFr          jmp     CheckDefeatedState      ;skip this next part if we found lakitu but alt frame not needed

                   CheckUpsideDownShell
e990: a5 ef                        lda     $ef                     ;check for enemy object => $04
e992: c9 04                        cmp     #$04
e994: b0 10                        bcs     CheckRightSideUpShell   ;branch if true
e996: c0 02                        cpy     #$02
e998: 90 0c                        bcc     CheckRightSideUpShell   ;branch if enemy state < $02
e99a: a2 5a                        ldx     #$5a                    ;set for upside-down koopa shell by default
e99c: a4 ef                        ldy     $ef
e99e: c0 02                        cpy     #BuzzyBeetle            ;check for buzzy beetle object
e9a0: d0 04                        bne     CheckRightSideUpShell
e9a2: a2 7e                        ldx     #$7e                    ;set for upside-down buzzy beetle shell if found
e9a4: e6 02                        inc     $02                     ;increment vertical position by one pixel
                   CheckRightSideUpShell
e9a6: a5 ec                        lda     $ec                     ;check for value set here
e9a8: c9 04                        cmp     #$04                    ;if enemy state < $02, do not change to shell, if
e9aa: d0 1e                        bne     CheckForHammerBro       ; enemy state => $02 but not = $04, leave shell upside-down
e9ac: a2 72                        ldx     #$72                    ;set right-side up buzzy beetle shell by default
e9ae: e6 02                        inc     $02                     ;increment saved vertical position by one pixel
e9b0: a4 ef                        ldy     $ef
e9b2: c0 02                        cpy     #BuzzyBeetle            ;check for buzzy beetle object
e9b4: f0 04                        beq     CheckForDefdGoomba      ;branch if found
e9b6: a2 66                        ldx     #$66                    ;change to right-side up koopa shell if not found
e9b8: e6 02                        inc     $02                     ; and increment saved vertical position again
                   CheckForDefdGoomba
e9ba: c0 06                        cpy     #Goomba                 ;check for goomba object (necessary if previously
e9bc: d0 0c                        bne     CheckForHammerBro       ; failed buzzy beetle object test)
e9be: a2 54                        ldx     #$54                    ;load for regular goomba
e9c0: a5 ed                        lda     $ed                     ;note that this only gets performed if enemy state => $02
e9c2: 29 20                        and     #%00100000              ;check saved enemy state for d5 set
e9c4: d0 04                        bne     CheckForHammerBro       ;branch if set
e9c6: a2 8a                        ldx     #$8a                    ;load offset for defeated goomba
e9c8: c6 02                        dec     $02                     ;set different value and decrement saved vertical position
                   CheckForHammerBro
e9ca: a4 08                        ldy     ObjectOffset
e9cc: a5 ef                        lda     $ef                     ;check for hammer bro object
e9ce: c9 05                        cmp     #HammerBro
e9d0: d0 0c                        bne     CheckForBloober         ;branch if not found
e9d2: a5 ed                        lda     $ed
e9d4: f0 24                        beq     CheckToAnimateEnemy     ;branch if not in normal enemy state
e9d6: 29 08                        and     #%00001000
e9d8: f0 5d                        beq     CheckDefeatedState      ;if d3 not set, branch further away
e9da: a2 b4                        ldx     #$b4                    ;otherwise load offset for different frame
e9dc: d0 1c                        bne     CheckToAnimateEnemy     ;unconditional branch

e9de: e0 48        CheckForBloober cpx     #$48                    ;check for cheep-cheep offset loaded
e9e0: f0 18                        beq     CheckToAnimateEnemy     ;branch if found
e9e2: b9 96 07                     lda     EnemyIntervalTimer,y
e9e5: c9 05                        cmp     #$05
e9e7: b0 4e                        bcs     CheckDefeatedState      ;branch if some timer is above a certain point
e9e9: e0 3c                        cpx     #$3c                    ;check for bloober offset loaded
e9eb: d0 0d                        bne     CheckToAnimateEnemy     ;branch if not found this time
e9ed: c9 01                        cmp     #$01
e9ef: f0 46                        beq     CheckDefeatedState      ;branch if timer is set to certain point
e9f1: e6 02                        inc     $02                     ;increment saved vertical coordinate three pixels
e9f3: e6 02                        inc     $02
e9f5: e6 02                        inc     $02
e9f7: 4c 29 ea                     jmp     CheckAnimationStop      ;and do something else

                   CheckToAnimateEnemy
e9fa: a5 ef                        lda     $ef                     ;check for specific enemy objects
e9fc: c9 06                        cmp     #$06
e9fe: f0 37                        beq     CheckDefeatedState      ;branch if goomba
ea00: c9 08                        cmp     #$08
ea02: f0 33                        beq     CheckDefeatedState      ;branch if bullet bill (note both variants use $08 here)
ea04: c9 0c                        cmp     #$0c
ea06: f0 2f                        beq     CheckDefeatedState      ;branch if podoboo
ea08: c9 18                        cmp     #$18                    ;branch if => $18
ea0a: b0 2b                        bcs     CheckDefeatedState
ea0c: a0 00                        ldy     #$00
ea0e: c9 15                        cmp     #$15                    ;check for mushroom retainer/princess object
ea10: d0 10                        bne     CheckForSecondFrame     ; which uses different code here, branch if not found
ea12: c8                           iny                             ;residual instruction
ea13: ad 5f 07                     lda     WorldNumber             ;are we on world 8?
ea16: c9 07                        cmp     #World8
ea18: b0 1d                        bcs     CheckDefeatedState      ;if so, leave the offset alone (use princess)
ea1a: a2 a2                        ldx     #$a2                    ;otherwise, set for mushroom retainer object instead
ea1c: a9 03                        lda     #$03                    ;set alternate state here
ea1e: 85 ec                        sta     $ec
ea20: d0 15                        bne     CheckDefeatedState      ;unconditional branch

                   CheckForSecondFrame
ea22: a5 09                        lda     FrameCounter            ;load frame counter
ea24: 39 76 e8                     and     EnemyAnimTimingBMask,y  ;mask it (partly residual, one byte not ever used)
ea27: d0 0e                        bne     CheckDefeatedState      ;branch if timing is off
                   CheckAnimationStop
ea29: a5 ed                        lda     $ed                     ;check saved enemy state
ea2b: 29 a0                        and     #%10100000              ;for d7 or d5, or check for timers stopped
ea2d: 0d 47 07                     ora     TimerControl
ea30: d0 05                        bne     CheckDefeatedState      ;if either condition true, branch
ea32: 8a                           txa
ea33: 18                           clc
ea34: 69 06                        adc     #$06                    ;add $06 to current enemy offset
ea36: aa                           tax                             ; to animate various enemy objects
                   CheckDefeatedState
ea37: a5 ed                        lda     $ed                     ;check saved enemy state
ea39: 29 20                        and     #%00100000              ;for d5 set
ea3b: f0 0e                        beq     DrawEnemyObject         ;branch if not set
ea3d: a5 ef                        lda     $ef
ea3f: c9 04                        cmp     #$04                    ;check for saved enemy object => $04
ea41: 90 08                        bcc     DrawEnemyObject         ;branch if less
ea43: a0 01                        ldy     #$01
ea45: 8c 09 01                     sty     VerticalFlipFlag        ;set vertical flip flag
ea48: 88                           dey
ea49: 84 ec                        sty     $ec                     ;init saved value here
ea4b: a4 eb        DrawEnemyObject ldy     $eb                     ;load sprite data offset
ea4d: 20 aa eb                     jsr     DrawEnemyObjRow         ;draw six tiles of data
ea50: 20 aa eb                     jsr     DrawEnemyObjRow         ; into sprite data
ea53: 20 aa eb                     jsr     DrawEnemyObjRow
ea56: a6 08                        ldx     ObjectOffset            ;get enemy object offset
ea58: bc e5 06                     ldy     Enemy_SprDataOffset,x   ;get sprite data offset
ea5b: a5 ef                        lda     $ef
ea5d: c9 08                        cmp     #$08                    ;get saved enemy object and check
ea5f: d0 03                        bne     CheckForVerticalFlip    ; for bullet bill, branch if not found
ea61: 4c 64 eb     SkipToOffScrChk jmp     SprObjectOffscrChk      ;jump if found

                   CheckForVerticalFlip
ea64: ad 09 01                     lda     VerticalFlipFlag        ;check if vertical flip flag is set here
ea67: f0 3d                        beq     CheckForESymmetry       ;branch if not
ea69: b9 02 02                     lda     Sprite_Attributes,y     ;get attributes of first sprite we dealt with
ea6c: 09 80                        ora     #%10000000              ;set bit for vertical flip
ea6e: c8                           iny
ea6f: c8                           iny                             ;increment two bytes so that we store the vertical flip
ea70: 20 b5 e5                     jsr     DumpSixSpr              ; in attribute bytes of enemy obj sprite data
ea73: 88                           dey
ea74: 88                           dey                             ;now go back to the Y coordinate offset
ea75: 98                           tya
ea76: aa                           tax                             ;give offset to X
ea77: a5 ef                        lda     $ef
ea79: c9 05                        cmp     #HammerBro              ;check saved enemy object for hammer bro
ea7b: f0 0d                        beq     FlipEnemyVertically
ea7d: c9 11                        cmp     #Lakitu                 ;check saved enemy object for lakitu
ea7f: f0 09                        beq     FlipEnemyVertically     ;branch for hammer bro or lakitu
ea81: c9 15                        cmp     #$15
ea83: b0 05                        bcs     FlipEnemyVertically     ;also branch if enemy object => $15
ea85: 8a                           txa
ea86: 18                           clc
ea87: 69 08                        adc     #$08                    ;if not selected objects or => $15, set
ea89: aa                           tax                             ; offset in X for next row
                   FlipEnemyVertically
ea8a: bd 01 02                     lda     Sprite_Tilenumber,x     ;load first or second row tiles
ea8d: 48                           pha                             ; and save tiles to the stack
ea8e: bd 05 02                     lda     Sprite_Tilenumber+4,x
ea91: 48                           pha
ea92: b9 11 02                     lda     Sprite_Tilenumber+16,y  ;exchange third row tiles
ea95: 9d 01 02                     sta     Sprite_Tilenumber,x     ; with first or second row tiles
ea98: b9 15 02                     lda     Sprite_Tilenumber+20,y
ea9b: 9d 05 02                     sta     Sprite_Tilenumber+4,x
ea9e: 68                           pla                             ;pull first or second row tiles from stack
ea9f: 99 15 02                     sta     Sprite_Tilenumber+20,y  ; and save in third row
eaa2: 68                           pla
eaa3: 99 11 02                     sta     Sprite_Tilenumber+16,y
                   CheckForESymmetry
eaa6: ad 6a 03                     lda     BowserGfxFlag           ;are we drawing bowser at all?
eaa9: d0 b6                        bne     SkipToOffScrChk         ;branch if so
eaab: a5 ef                        lda     $ef
eaad: a6 ec                        ldx     $ec                     ;get alternate enemy state
eaaf: c9 05                        cmp     #$05                    ;check for hammer bro object
eab1: d0 03                        bne     ContES
eab3: 4c 64 eb                     jmp     SprObjectOffscrChk      ;jump if found

eab6: c9 07        ContES          cmp     #Bloober                ;check for bloober object
eab8: f0 1d                        beq     MirrorEnemyGfx
eaba: c9 0d                        cmp     #PiranhaPlant           ;check for piranha plant object
eabc: f0 19                        beq     MirrorEnemyGfx
eabe: c9 0c                        cmp     #Podoboo                ;check for podoboo object
eac0: f0 15                        beq     MirrorEnemyGfx          ;branch if either of three are found
eac2: c9 12                        cmp     #Spiny                  ;check for spiny object
eac4: d0 04                        bne     ESRtnr                  ;branch closer if not found
eac6: e0 05                        cpx     #$05                    ;check spiny's state
eac8: d0 48                        bne     CheckToMirrorLakitu     ;branch if not an egg, otherwise
eaca: c9 15        ESRtnr          cmp     #$15                    ; check for princess/mushroom retainer object
eacc: d0 05                        bne     SpnySC
eace: a9 42                        lda     #$42                    ;set horizontal flip on bottom right sprite
ead0: 99 16 02                     sta     Sprite_Attributes+20,y  ;note that palette bits were already set earlier
ead3: e0 02        SpnySC          cpx     #$02                    ;if alternate enemy state set to 1 or 0, branch
ead5: 90 3b                        bcc     CheckToMirrorLakitu
ead7: ad 6a 03     MirrorEnemyGfx  lda     BowserGfxFlag           ;if enemy object is bowser, skip all of this
eada: d0 36                        bne     CheckToMirrorLakitu
eadc: b9 02 02                     lda     Sprite_Attributes,y     ;load attribute bits of first sprite
eadf: 29 a3                        and     #%10100011
eae1: 99 02 02                     sta     Sprite_Attributes,y     ;save vertical flip, priority, and palette bits
eae4: 99 0a 02                     sta     Sprite_Attributes+8,y   ; in left sprite column of enemy object OAM data
eae7: 99 12 02                     sta     Sprite_Attributes+16,y
eaea: 09 40                        ora     #%01000000              ;set horizontal flip
eaec: e0 05                        cpx     #$05                    ;check for state used by spiny's egg
eaee: d0 02                        bne     EggExc                  ;if alternate state not set to $05, branch
eaf0: 09 80                        ora     #%10000000              ;otherwise set vertical flip
eaf2: 99 06 02     EggExc          sta     Sprite_Attributes+4,y   ;set bits of right sprite column
eaf5: 99 0e 02                     sta     Sprite_Attributes+12,y  ;of enemy object sprite data
eaf8: 99 16 02                     sta     Sprite_Attributes+20,y
eafb: e0 04                        cpx     #$04                    ;check alternate enemy state
eafd: d0 13                        bne     CheckToMirrorLakitu     ;branch if not $04
eaff: b9 0a 02                     lda     Sprite_Attributes+8,y   ;get second row left sprite attributes
eb02: 09 80                        ora     #$80
eb04: 99 0a 02                     sta     Sprite_Attributes+8,y   ;store bits with vertical flip in
eb07: 99 12 02                     sta     Sprite_Attributes+16,y  ; second and third row left sprites
eb0a: 09 40                        ora     #$40
eb0c: 99 0e 02                     sta     Sprite_Attributes+12,y  ;store with horizontal and vertical flip in
eb0f: 99 16 02                     sta     Sprite_Attributes+20,y  ; second and third row right sprites
                   CheckToMirrorLakitu
eb12: a5 ef                        lda     $ef                     ;check for lakitu enemy object
eb14: c9 11                        cmp     #$11
eb16: d0 36                        bne     CheckToMirrorJSpring    ;branch if not found
eb18: ad 09 01                     lda     VerticalFlipFlag
eb1b: d0 21                        bne     NVFlak                  ;branch if vertical flip flag not set
eb1d: b9 12 02                     lda     Sprite_Attributes+16,y  ;save vertical flip and palette bits
eb20: 29 81                        and     #%10000001              ; in third row left sprite
eb22: 99 12 02                     sta     Sprite_Attributes+16,y
eb25: b9 16 02                     lda     Sprite_Attributes+20,y  ;set horizontal flip and palette bits
eb28: 09 41                        ora     #%01000001              ; in third row right sprite
eb2a: 99 16 02                     sta     Sprite_Attributes+20,y
eb2d: ae 8f 07                     ldx     FrenzyEnemyTimer        ;check timer
eb30: e0 10                        cpx     #$10
eb32: b0 30                        bcs     SprObjectOffscrChk      ;branch if timer has not reached a certain range
eb34: 99 0e 02                     sta     Sprite_Attributes+12,y  ;otherwise set same for second row right sprite
eb37: 29 81                        and     #%10000001
eb39: 99 0a 02                     sta     Sprite_Attributes+8,y   ;preserve vertical flip and palette bits for left sprite
eb3c: 90 26                        bcc     SprObjectOffscrChk      ;unconditional branch

eb3e: b9 02 02     NVFlak          lda     Sprite_Attributes,y     ;get first row left sprite attributes
eb41: 29 81                        and     #%10000001
eb43: 99 02 02                     sta     Sprite_Attributes,y     ;save vertical flip and palette bits
eb46: b9 06 02                     lda     Sprite_Attributes+4,y   ;get first row right sprite attributes
eb49: 09 41                        ora     #%01000001              ;set horizontal flip and palette bits
eb4b: 99 06 02                     sta     Sprite_Attributes+4,y   ;note that vertical flip is left as-is
                   CheckToMirrorJSpring
eb4e: a5 ef                        lda     $ef                     ;check for jumpspring object (any frame)
eb50: c9 18                        cmp     #$18
eb52: 90 10                        bcc     SprObjectOffscrChk      ;branch if not jumpspring object at all
eb54: a9 82                        lda     #$82
eb56: 99 0a 02                     sta     Sprite_Attributes+8,y   ;set vertical flip and palette bits of
eb59: 99 12 02                     sta     Sprite_Attributes+16,y  ; second and third row left sprites
eb5c: 09 40                        ora     #$40
eb5e: 99 0e 02                     sta     Sprite_Attributes+12,y  ;set, in addition to those, horizontal flip
eb61: 99 16 02                     sta     Sprite_Attributes+20,y  ; for second and third row right sprites
                   SprObjectOffscrChk
eb64: a6 08                        ldx     ObjectOffset            ;get enemy buffer offset
eb66: ad d1 03                     lda     Enemy_OffscreenBits     ;check offscreen information
eb69: 4a                           lsr     A
eb6a: 4a                           lsr     A                       ;shift three times to the right
eb6b: 4a                           lsr     A                       ; which puts d2 into carry
eb6c: 48                           pha                             ;save to stack
eb6d: 90 05                        bcc     LcChk                   ;branch if not set
eb6f: a9 04                        lda     #$04                    ;set for right column sprites
eb71: 20 c1 eb                     jsr     MoveESprColOffscreen    ; and move them offscreen
eb74: 68           LcChk           pla                             ;get from stack
eb75: 4a                           lsr     A                       ;move d3 to carry
eb76: 48                           pha                             ;;save to stack
eb77: 90 05                        bcc     Row3C                   ;branch if not set
eb79: a9 00                        lda     #$00                    ;set for left column sprites,
eb7b: 20 c1 eb                     jsr     MoveESprColOffscreen    ; move them offscreen
eb7e: 68           Row3C           pla                             ;get from stack again
eb7f: 4a                           lsr     A                       ;move d5 to carry this time
eb80: 4a                           lsr     A
eb81: 48                           pha                             ;save to stack again
eb82: 90 05                        bcc     Row23C                  ;branch if carry not set
eb84: a9 10                        lda     #$10                    ;set for third row of sprites
eb86: 20 b7 eb                     jsr     MoveESprRowOffscreen    ;and move them offscreen
eb89: 68           Row23C          pla                             ;get from stack
eb8a: 4a                           lsr     A                       ;move d6 into carry
eb8b: 48                           pha                             ;save to stack
eb8c: 90 05                        bcc     AllRowC
eb8e: a9 08                        lda     #$08                    ;set for second and third rows
eb90: 20 b7 eb                     jsr     MoveESprRowOffscreen    ;move them offscreen
eb93: 68           AllRowC         pla                             ;get from stack once more
eb94: 4a                           lsr     A                       ;move d7 into carry
eb95: 90 12                        bcc     ExEGHandler
eb97: 20 b7 eb                     jsr     MoveESprRowOffscreen    ;move all sprites offscreen (A should be 0 by now)
eb9a: b5 16                        lda     Enemy_ID,x
eb9c: c9 0c                        cmp     #Podoboo                ;check enemy identifier for podoboo
eb9e: f0 09                        beq     ExEGHandler             ;skip this part if found, we do not want to erase podoboo!
eba0: b5 b6                        lda     Enemy_Y_HighPos,x       ;check high byte of vertical position
eba2: c9 02                        cmp     #$02                    ;if not yet past the bottom of the screen, branch
eba4: d0 03                        bne     ExEGHandler
eba6: 20 98 c9                     jsr     EraseEnemyObject        ;what it says
eba9: 60           ExEGHandler     rts

ebaa: bd 3e e7     DrawEnemyObjRow lda     EnemyGraphicsTable,x    ;load two tiles of enemy graphics
ebad: 85 00                        sta     $00
ebaf: bd 3f e7                     lda     EnemyGraphicsTable+1,x
                   DrawOneSpriteRow
ebb2: 85 01                        sta     $01
ebb4: 4c 82 f2                     jmp     DrawSpriteObject        ;draw them

                   MoveESprRowOffscreen
ebb7: 18                           clc                             ;add A to enemy object OAM data offset
ebb8: 7d e5 06                     adc     Enemy_SprDataOffset,x
ebbb: a8                           tay                             ;use as offset
ebbc: a9 f8                        lda     #$f8
ebbe: 4c c1 e5                     jmp     DumpTwoSpr              ;move first row of sprites offscreen

                   MoveESprColOffscreen
ebc1: 18                           clc                             ;add A to enemy object OAM data offset
ebc2: 7d e5 06                     adc     Enemy_SprDataOffset,x
ebc5: a8                           tay                             ;use as offset
ebc6: 20 4a ec                     jsr     MoveColOffscreen        ;move first and second row sprites in column offscreen
ebc9: 99 10 02                     sta     Sprite_Data+16,y        ;move third row sprite in column offscreen
ebcc: 60                           rts

                   ; -----------------------------------------------------------------------------
                   ; $00-$01 - tile numbers
                   ; $02 - relative Y position
                   ; $03 - horizontal flip flag (not used here)
                   ; $04 - attributes
                   ; $05 - relative X position
                   DefaultBlockObjTiles
ebcd: 85 85 86 86                  .bulk   $85,$85,$86,$86

ebd1: ad bc 03     DrawBlock       lda     Block_Rel_YPos          ;get relative vertical coordinate of block object
ebd4: 85 02                        sta     $02                     ;store here
ebd6: ad b1 03                     lda     Block_Rel_XPos          ;get relative horizontal coordinate of block object
ebd9: 85 05                        sta     $05                     ;store here
ebdb: a9 03                        lda     #$03
ebdd: 85 04                        sta     $04                     ;set attribute byte here
ebdf: 4a                           lsr     A
ebe0: 85 03                        sta     $03                     ;set horizontal flip bit here (will not be used)
ebe2: bc ec 06                     ldy     Block_SprDataOffset,x   ;get sprite data offset
ebe5: a2 00                        ldx     #$00                    ;reset X for use as offset to tile data
ebe7: bd cd eb     DBlkLoop        lda     DefaultBlockObjTiles,x  ;get left tile number
ebea: 85 00                        sta     $00                     ;set here
ebec: bd ce eb                     lda     DefaultBlockObjTiles+1,x ;get right tile number
ebef: 20 b2 eb                     jsr     DrawOneSpriteRow        ;do sub to write tile numbers to first row of sprites
ebf2: e0 04                        cpx     #$04                    ;check incremented offset
ebf4: d0 f1                        bne     DBlkLoop                ;and loop back until all four sprites are done
ebf6: a6 08                        ldx     ObjectOffset            ;get block object offset
ebf8: bc ec 06                     ldy     Block_SprDataOffset,x   ;get sprite data offset
ebfb: ad 4e 07                     lda     AreaType
ebfe: c9 01                        cmp     #$01                    ;check for ground level type area
ec00: f0 08                        beq     ChkRep                  ;if found, branch to next part
ec02: a9 86                        lda     #$86
ec04: 99 01 02                     sta     Sprite_Tilenumber,y     ;otherwise remove brick tiles with lines
ec07: 99 05 02                     sta     Sprite_Tilenumber+4,y   ;and replace then with lineless brick tiles
ec0a: bd e8 03     ChkRep          lda     Block_Metatile,x        ;check replacement metatile
ec0d: c9 c4                        cmp     #$c4                    ;if not used block metatile, then
ec0f: d0 24                        bne     BlkOffscr               ; branch ahead to use current graphics
ec11: a9 87                        lda     #$87                    ;set A for used block tile
ec13: c8                           iny                             ;increment Y to write to tile bytes
ec14: 20 bb e5                     jsr     DumpFourSpr             ;do sub to dump into all four sprites
ec17: 88                           dey                             ;return Y to original offset
ec18: a9 03                        lda     #$03                    ;set palette bits
ec1a: ae 4e 07                     ldx     AreaType
ec1d: ca                           dex                             ;check for ground level type area again
ec1e: f0 01                        beq     SetBFlip                ;if found, use current palette bits
ec20: 4a                           lsr     A                       ;otherwise set to $01
ec21: a6 08        SetBFlip        ldx     ObjectOffset            ;put block object offset back in X
ec23: 99 02 02                     sta     Sprite_Attributes,y     ;store attribute byte as-is in first sprite
ec26: 09 40                        ora     #$40
ec28: 99 06 02                     sta     Sprite_Attributes+4,y   ;set horizontal flip bit for second sprite
ec2b: 09 80                        ora     #$80
ec2d: 99 0e 02                     sta     Sprite_Attributes+12,y  ;set both flip bits for fourth sprite
ec30: 29 83                        and     #$83
ec32: 99 0a 02                     sta     Sprite_Attributes+8,y   ;set vertical flip bit for third sprite
ec35: ad d4 03     BlkOffscr       lda     Block_OffscreenBits     ;get offscreen bits for block object
ec38: 48                           pha                             ;save to stack
ec39: 29 04                        and     #%00000100              ;check to see if d2 in offscreen bits are set
ec3b: f0 08                        beq     PullOfsB                ;if not set, branch, otherwise move sprites offscreen
ec3d: a9 f8                        lda     #$f8                    ;move offscreen two OAMs
ec3f: 99 04 02                     sta     Sprite_Y_Position+4,y   ; on the right side
ec42: 99 0c 02                     sta     Sprite_Y_Position+12,y
ec45: 68           PullOfsB        pla                             ;pull offscreen bits from stack
ec46: 29 08        ChkLeftCo       and     #%00001000              ;check to see if d3 in offscreen bits are set
ec48: f0 08                        beq     ExDBlk                  ;if not set, branch, otherwise move sprites offscreen
                   MoveColOffscreen
ec4a: a9 f8                        lda     #$f8                    ;move offscreen two OAMs
ec4c: 99 00 02                     sta     Sprite_Y_Position,y     ; on the left side (or two rows of enemy on either side
ec4f: 99 08 02                     sta     Sprite_Y_Position+8,y   ; if branched here from enemy graphics handler)
ec52: 60           ExDBlk          rts

                   ; -----------------------------------------------------------------------------
                   ; $00 - used to hold palette bits for attribute byte or relative X position
ec53: a9 02        DrawBrickChunks lda     #$02                    ;set palette bits here
ec55: 85 00                        sta     $00
ec57: a9 75                        lda     #$75                    ;set tile number for ball (something residual, likely)
ec59: a4 0e                        ldy     GameEngineSubroutine
ec5b: c0 05                        cpy     #$05                    ;if end-of-level routine running,
ec5d: f0 06                        beq     DChunks                 ; use palette and tile number assigned
ec5f: a9 03                        lda     #$03                    ;otherwise set different palette bits
ec61: 85 00                        sta     $00
ec63: a9 84                        lda     #$84                    ;and set tile number for brick chunks
ec65: bc ec 06     DChunks         ldy     Block_SprDataOffset,x   ;get OAM data offset
ec68: c8                           iny                             ;increment to start with tile bytes in OAM
ec69: 20 bb e5                     jsr     DumpFourSpr             ;do sub to dump tile number into all four sprites
ec6c: a5 09                        lda     FrameCounter            ;get frame counter
ec6e: 0a                           asl     A
ec6f: 0a                           asl     A
ec70: 0a                           asl     A                       ;move low nybble to high
ec71: 0a                           asl     A
ec72: 29 c0                        and     #$c0                    ;get what was originally d3-d2 of low nybble
ec74: 05 00                        ora     $00                     ;add palette bits
ec76: c8                           iny                             ;increment offset for attribute bytes
ec77: 20 bb e5                     jsr     DumpFourSpr             ;do sub to dump attribute data into all four sprites
ec7a: 88                           dey
ec7b: 88                           dey                             ;decrement offset to Y coordinate
ec7c: ad bc 03                     lda     Block_Rel_YPos          ;get first block object's relative vertical coordinate
ec7f: 20 c1 e5                     jsr     DumpTwoSpr              ;do sub to dump current Y coordinate into two sprites
ec82: ad b1 03                     lda     Block_Rel_XPos          ;get first block object's relative horizontal coordinate
ec85: 99 03 02                     sta     Sprite_X_Position,y     ;save into X coordinate of first sprite
ec88: bd f1 03                     lda     Block_Orig_XPos,x       ;get original horizontal coordinate
ec8b: 38                           sec
ec8c: ed 1c 07                     sbc     ScreenLeft_X_Pos        ;subtract coordinate of left side from original coordinate
ec8f: 85 00                        sta     $00                     ;store result as relative horizontal coordinate of original
ec91: 38                           sec
ec92: ed b1 03                     sbc     Block_Rel_XPos          ;get difference of relative positions of original - current
ec95: 65 00                        adc     $00                     ;add original relative position to result
ec97: 69 06                        adc     #$06                    ;plus 6 pixels to position second brick chunk correctly
ec99: 99 07 02                     sta     Sprite_X_Position+4,y   ;save into X coordinate of second sprite
ec9c: ad bd 03                     lda     Block_Rel_YPos+1        ;get second block object's relative vertical coordinate
ec9f: 99 08 02                     sta     Sprite_Y_Position+8,y
eca2: 99 0c 02                     sta     Sprite_Y_Position+12,y  ;dump into Y coordinates of third and fourth sprites
eca5: ad b2 03                     lda     Block_Rel_XPos+1        ;get second block object's relative horizontal coordinate
eca8: 99 0b 02                     sta     Sprite_X_Position+8,y   ;save into X coordinate of third sprite
ecab: a5 00                        lda     $00                     ;use original relative horizontal position
ecad: 38                           sec
ecae: ed b2 03                     sbc     Block_Rel_XPos+1        ;get difference of relative positions of original - current
ecb1: 65 00                        adc     $00                     ;add original relative position to result
ecb3: 69 06                        adc     #$06                    ;plus 6 pixels to position fourth brick chunk correctly
ecb5: 99 0f 02                     sta     Sprite_X_Position+12,y  ;save into X coordinate of fourth sprite
ecb8: ad d4 03                     lda     Block_OffscreenBits     ;get offscreen bits for block object
ecbb: 20 46 ec                     jsr     ChkLeftCo               ;do sub to move left half of sprites offscreen if necessary
ecbe: ad d4 03                     lda     Block_OffscreenBits     ;get offscreen bits again
ecc1: 0a                           asl     A                       ;shift d7 into carry
ecc2: 90 05                        bcc     ChnkOfs                 ;if d7 not set, branch to last part
ecc4: a9 f8                        lda     #$f8
ecc6: 20 c1 e5                     jsr     DumpTwoSpr              ;otherwise move top sprites offscreen
ecc9: a5 00        ChnkOfs         lda     $00                     ;if relative position on left side of screen,
eccb: 10 10                        bpl     ExBCDr                  ; go ahead and leave
eccd: b9 03 02                     lda     Sprite_X_Position,y     ;otherwise compare left-side X coordinate
ecd0: d9 07 02                     cmp     Sprite_X_Position+4,y   ; to right-side X coordinate
ecd3: 90 08                        bcc     ExBCDr                  ;branch to leave if less
ecd5: a9 f8                        lda     #$f8                    ;otherwise move right half of sprites offscreen
ecd7: 99 04 02                     sta     Sprite_Y_Position+4,y
ecda: 99 0c 02                     sta     Sprite_Y_Position+12,y
ecdd: 60           ExBCDr          rts                             ;leave

                   ; -----------------------------------------------------------------------------
ecde: bc f1 06     DrawFireball    ldy     FBall_SprDataOffset,x   ;get fireball's sprite data offset
ece1: ad ba 03                     lda     Fireball_Rel_YPos       ;get relative vertical coordinate
ece4: 99 00 02                     sta     Sprite_Y_Position,y     ;store as sprite Y coordinate
ece7: ad af 03                     lda     Fireball_Rel_XPos       ;get relative horizontal coordinate
ecea: 99 03 02                     sta     Sprite_X_Position,y     ;store as sprite X coordinate, then do shared code
eced: a5 09        DrawFirebar     lda     FrameCounter            ;get frame counter
ecef: 4a                           lsr     A                       ;divide by four
ecf0: 4a                           lsr     A
ecf1: 48                           pha                             ;save result to stack
ecf2: 29 01                        and     #$01                    ;mask out all but last bit
ecf4: 49 64                        eor     #$64                    ;set either tile $64 or $65 as fireball tile
ecf6: 99 01 02                     sta     Sprite_Tilenumber,y     ;thus tile changes every four frames
ecf9: 68                           pla                             ;get from stack
ecfa: 4a                           lsr     A                       ;divide by four again
ecfb: 4a                           lsr     A
ecfc: a9 02                        lda     #$02                    ;load value $02 to set palette in attrib byte
ecfe: 90 02                        bcc     FireA                   ;if last bit shifted out was not set, skip this
ed00: 09 c0                        ora     #%11000000              ;otherwise flip both ways every eight frames
ed02: 99 02 02     FireA           sta     Sprite_Attributes,y     ;store attribute byte and leave
ed05: 60                           rts

                   ; -----------------------------------------------------------------------------
ed06: 68 67 66     ExplosionTiles  .bulk   $68,$67,$66

                   DrawExplosion_Fireball
ed09: bc ec 06                     ldy     Alt_SprDataOffset,x     ;get OAM data offset of alternate sort for fireball's explosion
ed0c: b5 24                        lda     Fireball_State,x        ;load fireball state
ed0e: f6 24                        inc     Fireball_State,x        ;increment state for next frame
ed10: 4a                           lsr     A                       ;divide by 2
ed11: 29 07                        and     #%00000111              ;mask out all but d3-d1
ed13: c9 03                        cmp     #$03                    ;check to see if time to kill fireball
ed15: b0 4a                        bcs     KillFireBall            ;branch if so, otherwise continue to draw explosion
                   DrawExplosion_Fireworks
ed17: aa                           tax                             ;use whatever's in A for offset
ed18: bd 06 ed                     lda     ExplosionTiles,x        ;get tile number using offset
ed1b: c8                           iny                             ;increment Y (contains sprite data offset)
ed1c: 20 bb e5                     jsr     DumpFourSpr             ; and dump into tile number part of sprite data
ed1f: 88                           dey                             ;decrement Y so we have the proper offset again
ed20: a6 08                        ldx     ObjectOffset            ;return enemy object buffer offset to X
ed22: ad ba 03                     lda     Fireball_Rel_YPos       ;get relative vertical coordinate
ed25: 38                           sec                             ;subtract four pixels vertically
ed26: e9 04                        sbc     #$04                    ; for first and third sprites
ed28: 99 00 02                     sta     Sprite_Y_Position,y
ed2b: 99 08 02                     sta     Sprite_Y_Position+8,y
ed2e: 18                           clc                             ;add eight pixels vertically
ed2f: 69 08                        adc     #$08                    ; for second and fourth sprites
ed31: 99 04 02                     sta     Sprite_Y_Position+4,y
ed34: 99 0c 02                     sta     Sprite_Y_Position+12,y
ed37: ad af 03                     lda     Fireball_Rel_XPos       ;get relative horizontal coordinate
ed3a: 38                           sec                             ;subtract four pixels horizontally
ed3b: e9 04                        sbc     #$04                    ; for first and second sprites
ed3d: 99 03 02                     sta     Sprite_X_Position,y
ed40: 99 07 02                     sta     Sprite_X_Position+4,y
ed43: 18                           clc                             ;add eight pixels horizontally
ed44: 69 08                        adc     #$08                    ; for third and fourth sprites
ed46: 99 0b 02                     sta     Sprite_X_Position+8,y
ed49: 99 0f 02                     sta     Sprite_X_Position+12,y
ed4c: a9 02                        lda     #$02                    ;set palette attributes for all sprites, but
ed4e: 99 02 02                     sta     Sprite_Attributes,y     ; set no flip at all for first sprite
ed51: a9 82                        lda     #$82
ed53: 99 06 02                     sta     Sprite_Attributes+4,y   ;set vertical flip for second sprite
ed56: a9 42                        lda     #$42
ed58: 99 0a 02                     sta     Sprite_Attributes+8,y   ;set horizontal flip for third sprite
ed5b: a9 c2                        lda     #$c2
ed5d: 99 0e 02                     sta     Sprite_Attributes+12,y  ;set both flips for fourth sprite
ed60: 60                           rts                             ;we are done

ed61: a9 00        KillFireBall    lda     #$00                    ;clear fireball state to kill it
ed63: 95 24                        sta     Fireball_State,x
ed65: 60                           rts

                   ; -----------------------------------------------------------------------------
                   DrawSmallPlatform
ed66: bc e5 06                     ldy     Enemy_SprDataOffset,x   ;get OAM data offset
ed69: a9 5b                        lda     #$5b                    ;load tile number for small platforms
ed6b: c8                           iny                             ;increment offset for tile numbers
ed6c: 20 b5 e5                     jsr     DumpSixSpr              ;dump tile number into all six sprites
ed6f: c8                           iny                             ;increment offset for attributes
ed70: a9 02                        lda     #$02                    ;load palette controls
ed72: 20 b5 e5                     jsr     DumpSixSpr              ;dump attributes into all six sprites
ed75: 88                           dey                             ;decrement for original offset
ed76: 88                           dey
ed77: ad ae 03                     lda     Enemy_Rel_XPos          ;get relative horizontal coordinate
ed7a: 99 03 02                     sta     Sprite_X_Position,y
ed7d: 99 0f 02                     sta     Sprite_X_Position+12,y  ;dump as X coordinate into first and fourth sprites
ed80: 18                           clc
ed81: 69 08                        adc     #$08                    ;add eight pixels
ed83: 99 07 02                     sta     Sprite_X_Position+4,y   ;dump into second and fifth sprites
ed86: 99 13 02                     sta     Sprite_X_Position+16,y
ed89: 18                           clc
ed8a: 69 08                        adc     #$08                    ;add eight more pixels
ed8c: 99 0b 02                     sta     Sprite_X_Position+8,y   ;dump into third and sixth sprites
ed8f: 99 17 02                     sta     Sprite_X_Position+20,y
ed92: b5 cf                        lda     Enemy_Y_Position,x      ;get vertical coordinate
ed94: aa                           tax
ed95: 48                           pha                             ;save to stack
ed96: e0 20                        cpx     #$20                    ;if vertical coordinate below status bar,
ed98: b0 02                        bcs     ToSP                    ; do not mess with it
ed9a: a9 f8                        lda     #$f8                    ;otherwise move first three sprites offscreen
ed9c: 20 be e5     ToSP            jsr     DumpThreeSpr            ;dump vertical coordinate into Y coordinates
ed9f: 68                           pla                             ;pull from stack
eda0: 18                           clc
eda1: 69 80                        adc     #$80                    ;add 128 pixels
eda3: aa                           tax
eda4: e0 20                        cpx     #$20                    ;if below status bar (taking wrap into account)
eda6: b0 02                        bcs     BotSP                   ;then do not change altered coordinate
eda8: a9 f8                        lda     #$f8                    ;otherwise move last three sprites offscreen
edaa: 99 0c 02     BotSP           sta     Sprite_Y_Position+12,y  ;dump vertical coordinate + 128 pixels
edad: 99 10 02                     sta     Sprite_Y_Position+16,y  ; into Y coordinates
edb0: 99 14 02                     sta     Sprite_Y_Position+20,y
edb3: ad d1 03                     lda     Enemy_OffscreenBits     ;get offscreen bits
edb6: 48                           pha                             ;save to stack
edb7: 29 08                        and     #%00001000              ;check d3
edb9: f0 08                        beq     SOfs
edbb: a9 f8                        lda     #$f8                    ;if d3 was set, move first and
edbd: 99 00 02                     sta     Sprite_Y_Position,y     ; fourth sprites offscreen
edc0: 99 0c 02                     sta     Sprite_Y_Position+12,y
edc3: 68           SOfs            pla                             ;move out and back into stack
edc4: 48                           pha
edc5: 29 04                        and     #%00000100              ;check d2
edc7: f0 08                        beq     SOfs2
edc9: a9 f8                        lda     #$f8                    ;if d2 was set, move second and
edcb: 99 04 02                     sta     Sprite_Y_Position+4,y   ; fifth sprites offscreen
edce: 99 10 02                     sta     Sprite_Y_Position+16,y
edd1: 68           SOfs2           pla                             ;get from stack
edd2: 29 02                        and     #%00000010              ;check d1
edd4: f0 08                        beq     ExSPl
edd6: a9 f8                        lda     #$f8                    ;if d1 was set, move third and
edd8: 99 08 02                     sta     Sprite_Y_Position+8,y   ; sixth sprites offscreen
eddb: 99 14 02                     sta     Sprite_Y_Position+20,y
edde: a6 08        ExSPl           ldx     ObjectOffset            ;get enemy object offset and leave
ede0: 60                           rts

                   ; -----------------------------------------------------------------------------
ede1: a4 b5        DrawBubble      ldy     Player_Y_HighPos        ;if player's vertical high position
ede3: 88                           dey                             ; not within screen, skip all of this
ede4: d0 20                        bne     ExDBub
ede6: ad d3 03                     lda     Bubble_OffscreenBits    ;check air bubble's offscreen bits
ede9: 29 08                        and     #%00001000
edeb: d0 19                        bne     ExDBub                  ;if bit set, branch to leave
eded: bc ee 06                     ldy     Bubble_SprDataOffset,x  ;get air bubble's OAM data offset
edf0: ad b0 03                     lda     Bubble_Rel_XPos         ;get relative horizontal coordinate
edf3: 99 03 02                     sta     Sprite_X_Position,y     ;store as X coordinate here
edf6: ad bb 03                     lda     Bubble_Rel_YPos         ;get relative vertical coordinate
edf9: 99 00 02                     sta     Sprite_Y_Position,y     ;store as Y coordinate here
edfc: a9 74                        lda     #$74
edfe: 99 01 02                     sta     Sprite_Tilenumber,y     ;put air bubble tile into OAM data
ee01: a9 02                        lda     #$02
ee03: 99 02 02                     sta     Sprite_Attributes,y     ;set attribute byte
ee06: 60           ExDBub          rts                             ;leave

                   ; -----------------------------------------------------------------------------
                   ; $00 - used to store player's vertical offscreen bits
                   PlayerGfxTblOffsets
ee07: 20 28 c8 18+                 .bulk   $20,$28,$c8,$18,$00,$40,$50,$58,$80,$88,$b8,$78,$60,$a0,$b0,$b8

                   ; 
                   ; tiles arranged in order, 2 tiles per row, top to bottom
                   ; 
                   ; big player table
                   vis vis
                   PlayerGraphicsTable
ee17: 00 01 02 03+                 .bulk   $00,$01,$02,$03,$04,$05,$06,$07 ;walking frame 1

                   vis
ee1f: 08 09 0a 0b+                 .bulk   $08,$09,$0a,$0b,$0c,$0d,$0e,$0f ;        frame 2

                   vis
ee27: 10 11 12 13+                 .bulk   $10,$11,$12,$13,$14,$15,$16,$17 ;        frame 3

                   vis
ee2f: 18 19 1a 1b+                 .bulk   $18,$19,$1a,$1b,$1c,$1d,$1e,$1f ;skidding

                   vis
ee37: 20 21 22 23+                 .bulk   $20,$21,$22,$23,$24,$25,$26,$27 ;jumping

                   vis vis
ee3f: 08 09 28 29+                 .bulk   $08,$09,$28,$29,$2a,$2b,$2c,$2d ;swimming frame 1

                   vis
ee47: 08 09 0a 0b+                 .bulk   $08,$09,$0a,$0b,$0c,$30,$2c,$2d ;         frame 2

                   vis
ee4f: 08 09 0a 0b+                 .bulk   $08,$09,$0a,$0b,$2e,$2f,$2c,$2d ;         frame 3

                   vis
ee57: 08 09 28 29+                 .bulk   $08,$09,$28,$29,$2a,$2b,$5c,$5d ;climbing frame 1

                   vis
ee5f: 08 09 0a 0b+                 .bulk   $08,$09,$0a,$0b,$0c,$0d,$5e,$5f ;         frame 2

                   vis
ee67: fc fc 08 09+                 .bulk   $fc,$fc,$08,$09,$58,$59,$5a,$5a ;crouching

                   vis
ee6f: 08 09 28 29+                 .bulk   $08,$09,$28,$29,$2a,$2b,$0e,$0f ;fireball throwing

                   ; small player table
                   vis vis
ee77: fc fc fc fc+                 .bulk   $fc,$fc,$fc,$fc,$32,$33,$34,$35 ;walking frame 1

                   vis
ee7f: fc fc fc fc+                 .bulk   $fc,$fc,$fc,$fc,$36,$37,$38,$39 ;        frame 2

                   vis
ee87: fc fc fc fc+                 .bulk   $fc,$fc,$fc,$fc,$3a,$37,$3b,$3c ;        frame 3

                   vis
ee8f: fc fc fc fc+                 .bulk   $fc,$fc,$fc,$fc,$3d,$3e,$3f,$40 ;skidding

                   vis
ee97: fc fc fc fc+                 .bulk   $fc,$fc,$fc,$fc,$32,$41,$42,$43 ;jumping

                   vis vis
ee9f: fc fc fc fc+ SwimTiles       .bulk   $fc,$fc,$fc,$fc,$32,$33,$44,$45 ;swimming frame 1

                   vis
eea7: fc fc fc fc+                 .bulk   $fc,$fc,$fc,$fc,$32,$33,$44,$47 ;         frame 2

                   vis
eeaf: fc fc fc fc+                 .bulk   $fc,$fc,$fc,$fc,$32,$33,$48,$49 ;         frame 3

                   vis
eeb7: fc fc fc fc+                 .bulk   $fc,$fc,$fc,$fc,$32,$33,$90,$91 ;climbing frame 1

                   vis
eebf: fc fc fc fc+                 .bulk   $fc,$fc,$fc,$fc,$3a,$37,$92,$93 ;         frame 2

                   vis
eec7: fc fc fc fc+                 .bulk   $fc,$fc,$fc,$fc,$9e,$9e,$9f,$9f ;killed

                   ; used by both player sizes
                   vis
eecf: fc fc fc fc+                 .bulk   $fc,$fc,$fc,$fc,$3a,$37,$4f,$4f ;small player standing

                   vis
eed7: fc fc 00 01+                 .bulk   $fc,$fc,$00,$01,$4c,$4d,$4e,$4e ;intermediate grow frame

                   vis
eedf: 00 01 4c 4d+                 .bulk   $00,$01,$4c,$4d,$4a,$4a,$4b,$4b ;big player standing
eee7: 31 46        SwimKickTileNum .bulk   $31,$46

                   PlayerGfxHandler
eee9: ad 9e 07                     lda     InjuryTimer             ;if player's injured invincibility timer
eeec: f0 05                        beq     CntPl                   ; not set, skip checkpoint and continue code
eeee: a5 09                        lda     FrameCounter
eef0: 4a                           lsr     A                       ;otherwise check frame counter and branch
eef1: b0 40                        bcs     ExPGH                   ; to leave on every other frame (when d0 is set)
eef3: a5 0e        CntPl           lda     GameEngineSubroutine    ;if executing specific game engine routine,
eef5: c9 0b                        cmp     #$0b                    ; branch ahead to some other part
eef7: f0 47                        beq     PlayerKilled
eef9: ad 0b 07                     lda     PlayerChangeSizeFlag    ;if grow/shrink flag set
eefc: d0 3c                        bne     DoChangeSize            ; then branch to some other code
eefe: ac 04 07                     ldy     SwimmingFlag            ;if swimming flag set, branch to
ef01: f0 31                        beq     FindPlayerAction        ; different part, do not return
ef03: a5 1d                        lda     Player_State
ef05: c9 00                        cmp     #$00                    ;if player status normal,
ef07: f0 2b                        beq     FindPlayerAction        ; branch and do not return
ef09: 20 34 ef                     jsr     FindPlayerAction        ;otherwise jump and return
ef0c: a5 09                        lda     FrameCounter
ef0e: 29 04                        and     #%00000100              ;check frame counter for d2 set (8 frames every
ef10: d0 21                        bne     ExPGH                   ; eighth frame), and branch if set to leave
ef12: aa                           tax                             ;initialize X to zero
ef13: ac e4 06                     ldy     SprDataOffset           ;get player sprite data offset
ef16: a5 33                        lda     PlayerFacingDir         ;get player's facing direction
ef18: 4a                           lsr     A
ef19: b0 04                        bcs     SwimKT                  ;if player facing to the right, use current offset
ef1b: c8                           iny
ef1c: c8                           iny                             ;otherwise move to next OAM data
ef1d: c8                           iny
ef1e: c8                           iny
ef1f: ad 54 07     SwimKT          lda     PlayerSize              ;check player's size
ef22: f0 09                        beq     BigKTS                  ;if big, use first tile
ef24: b9 19 02                     lda     Sprite_Tilenumber+24,y  ;check tile number of seventh/eighth sprite
ef27: cd b5 ee                     cmp     SwimTiles+22            ; against tile number in player graphics table
ef2a: f0 07                        beq     ExPGH                   ;if spr7/spr8 tile number = value, branch to leave
ef2c: e8                           inx                             ;otherwise increment X for second tile
ef2d: bd e7 ee     BigKTS          lda     SwimKickTileNum,x       ;overwrite tile number in sprite 7/8
ef30: 99 19 02                     sta     Sprite_Tilenumber+24,y  ; to animate player's feet when swimming
ef33: 60           ExPGH           rts                             ;then leave

                   FindPlayerAction
ef34: 20 ec ef                     jsr     ProcessPlayerAction     ;find proper offset to graphics table by player's actions
ef37: 4c 45 ef                     jmp     PlayerGfxProcessing     ;draw player, then process for fireball throwing

ef3a: 20 b0 f0     DoChangeSize    jsr     HandleChangeSize        ;find proper offset to graphics table for grow/shrink
ef3d: 4c 45 ef                     jmp     PlayerGfxProcessing     ;draw player, then process for fireball throwing

ef40: a0 0e        PlayerKilled    ldy     #$0e                    ;load offset for player killed
ef42: b9 07 ee                     lda     PlayerGfxTblOffsets,y   ;get offset to graphics table
                   PlayerGfxProcessing
ef45: 8d d5 06                     sta     PlayerGfxOffset         ;store offset to graphics table here
ef48: a9 04                        lda     #$04
ef4a: 20 be ef                     jsr     RenderPlayerSub         ;draw player based on offset loaded
ef4d: 20 e9 f0                     jsr     ChkForPlayerAttrib      ;set horizontal flip bits as necessary
ef50: ad 11 07                     lda     FireballThrowingTimer
ef53: f0 25                        beq     PlayerOffscreenChk      ;if fireball throw timer not set, skip to the end
ef55: a0 00                        ldy     #$00                    ;set value to initialize by default
ef57: ad 81 07                     lda     PlayerAnimTimer         ;get animation frame timer
ef5a: cd 11 07                     cmp     FireballThrowingTimer   ;compare to fireball throw timer
ef5d: 8c 11 07                     sty     FireballThrowingTimer   ;initialize fireball throw timer
ef60: b0 18                        bcs     PlayerOffscreenChk      ;if animation frame timer => fireball throw timer skip to end
ef62: 8d 11 07                     sta     FireballThrowingTimer   ;otherwise store animation timer into fireball throw timer
ef65: a0 07                        ldy     #$07                    ;load offset for throwing
ef67: b9 07 ee                     lda     PlayerGfxTblOffsets,y   ;get offset to graphics table
ef6a: 8d d5 06                     sta     PlayerGfxOffset         ;store it for use later
ef6d: a0 04                        ldy     #$04                    ;set to update four sprite rows by default
ef6f: a5 57                        lda     Player_X_Speed
ef71: 05 0c                        ora     Left_Right_Buttons      ;check for horizontal speed or left/right button press
ef73: f0 01                        beq     SUpdR                   ;if no speed or button press, branch using set value in Y
ef75: 88                           dey                             ;otherwise set to update only three sprite rows
ef76: 98           SUpdR           tya                             ;save in A for use
ef77: 20 be ef                     jsr     RenderPlayerSub         ;in sub, draw player object again
                   PlayerOffscreenChk
ef7a: ad d0 03                     lda     Player_OffscreenBits    ;get player's offscreen bits
ef7d: 4a                           lsr     A
ef7e: 4a                           lsr     A                       ;move vertical bits to low nybble
ef7f: 4a                           lsr     A
ef80: 4a                           lsr     A
ef81: 85 00                        sta     $00                     ;store here
ef83: a2 03                        ldx     #$03                    ;check all four rows of player sprites
ef85: ad e4 06                     lda     SprDataOffset           ;get player's sprite data offset
ef88: 18                           clc
ef89: 69 18                        adc     #$18                    ;add 24 bytes to start at bottom row
ef8b: a8                           tay                             ;set as offset here
ef8c: a9 f8        PROfsLoop       lda     #$f8                    ;load offscreen Y coordinate just in case
ef8e: 46 00                        lsr     $00                     ;shift bit into carry
ef90: 90 03                        bcc     NPROffscr               ;if bit not set, skip, do not move sprites
ef92: 20 c1 e5                     jsr     DumpTwoSpr              ;otherwise dump offscreen Y coordinate into sprite data
ef95: 98           NPROffscr       tya
ef96: 38                           sec                             ;subtract eight bytes to do
ef97: e9 08                        sbc     #$08                    ; next row up
ef99: a8                           tay
ef9a: ca                           dex                             ;decrement row counter
ef9b: 10 ef                        bpl     PROfsLoop               ;do this until all sprite rows are checked
ef9d: 60                           rts                             ;then we are done!

                   ; -----------------------------------------------------------------------------
                   IntermediatePlayerData
ef9e: 58 01 00 60+                 .bulk   $58,$01,$00,$60,$ff,$04

                   DrawPlayer_Intermediate
efa4: a2 05                        ldx     #$05                    ;store data into zero page memory
efa6: bd 9e ef     PIntLoop        lda     IntermediatePlayerData,x ;load data to display player as he always
efa9: 95 02                        sta     $02,x                   ; appears on world/lives display
efab: ca                           dex
efac: 10 f8                        bpl     PIntLoop                ;do this until all data is loaded
efae: a2 b8                        ldx     #$b8                    ;load offset for small standing
efb0: a0 04                        ldy     #$04                    ;load sprite data offset
efb2: 20 dc ef                     jsr     DrawPlayerLoop          ;draw player accordingly
efb5: ad 26 02                     lda     Sprite_Attributes+36    ;get empty sprite attributes
efb8: 09 40                        ora     #%01000000              ;set horizontal flip bit for bottom-right sprite
efba: 8d 22 02                     sta     Sprite_Attributes+32    ;store and leave
efbd: 60                           rts

                   ; -----------------------------------------------------------------------------
                   ; $00-$01 - used to hold tile numbers, $00 also used to hold upper extent of
                   ; animation frames
                   ; $02 - vertical position
                   ; $03 - facing direction, used as horizontal flip control
                   ; $04 - attributes
                   ; $05 - horizontal position
                   ; $07 - number of rows to draw
                   ; 
                   ; these also used in IntermediatePlayerData
efbe: 85 07        RenderPlayerSub sta     $07                     ;store number of rows of sprites to draw
efc0: ad ad 03                     lda     Player_Rel_XPos
efc3: 8d 55 07                     sta     Player_Pos_ForScroll    ;store player's relative horizontal position
efc6: 85 05                        sta     $05                     ;store it here also
efc8: ad b8 03                     lda     Player_Rel_YPos
efcb: 85 02                        sta     $02                     ;store player's vertical position
efcd: a5 33                        lda     PlayerFacingDir
efcf: 85 03                        sta     $03                     ;store player's facing direction
efd1: ad c4 03                     lda     Player_SprAttrib
efd4: 85 04                        sta     $04                     ;store player's sprite attributes
efd6: ae d5 06                     ldx     PlayerGfxOffset         ;load graphics table offset
efd9: ac e4 06                     ldy     SprDataOffset           ;get player's sprite data offset
efdc: bd 17 ee     DrawPlayerLoop  lda     PlayerGraphicsTable,x   ;load player's left side
efdf: 85 00                        sta     $00
efe1: bd 18 ee                     lda     PlayerGraphicsTable+1,x ;now load right side
efe4: 20 b2 eb                     jsr     DrawOneSpriteRow
efe7: c6 07                        dec     $07                     ;decrement rows of sprites to draw
efe9: d0 f1                        bne     DrawPlayerLoop          ;do this until all rows are drawn
efeb: 60                           rts

                   ProcessPlayerAction
efec: a5 1d                        lda     Player_State            ;get player's state
efee: c9 03                        cmp     #$03
eff0: f0 52                        beq     ActionClimbing          ;if climbing, branch here
eff2: c9 02                        cmp     #$02
eff4: f0 3e                        beq     ActionFalling           ;if falling, branch here
eff6: c9 01                        cmp     #$01
eff8: d0 11                        bne     ProcOnGroundActs        ;if not jumping, branch here
effa: ad 04 07                     lda     SwimmingFlag
effd: d0 51                        bne     ActionSwimming          ;if swimming flag set, branch elsewhere
efff: a0 06                        ldy     #$06                    ;load offset for crouching
f001: ad 14 07                     lda     CrouchingFlag           ;get crouching flag
f004: d0 22                        bne     NonAnimatedActs         ;if set, branch to get offset for graphics table
f006: a0 00                        ldy     #$00                    ;otherwise load offset for jumping
f008: 4c 28 f0                     jmp     NonAnimatedActs         ;go to get offset to graphics table

                   ProcOnGroundActs
f00b: a0 06                        ldy     #$06                    ;load offset for crouching
f00d: ad 14 07                     lda     CrouchingFlag           ;get crouching flag
f010: d0 16                        bne     NonAnimatedActs         ;if set, branch to get offset for graphics table
f012: a0 02                        ldy     #$02                    ;load offset for standing
f014: a5 57                        lda     Player_X_Speed          ;check player's horizontal speed
f016: 05 0c                        ora     Left_Right_Buttons      ; and left/right controller bits
f018: f0 0e                        beq     NonAnimatedActs         ;if no speed or buttons pressed, use standing offset
f01a: ad 00 07                     lda     Player_XSpeedAbsolute   ;load walking/running speed
f01d: c9 09                        cmp     #$09
f01f: 90 1b                        bcc     ActionWalkRun           ;if less than a certain amount, branch, too slow to skid
f021: a5 45                        lda     Player_MovingDir        ;otherwise check to see if moving direction
f023: 25 33                        and     PlayerFacingDir         ; and facing direction are the same
f025: d0 15                        bne     ActionWalkRun           ;if moving direction = facing direction, branch, don't skid
f027: c8                           iny                             ;otherwise increment to skid offset ($03)
f028: 20 91 f0     NonAnimatedActs jsr     GetGfxOffsetAdder       ;do a sub here to get offset adder for graphics table
f02b: a9 00                        lda     #$00
f02d: 8d 0d 07                     sta     PlayerAnimCtrl          ;initialize animation frame control
f030: b9 07 ee                     lda     PlayerGfxTblOffsets,y   ;load offset to graphics table using size as offset
f033: 60                           rts

f034: a0 04        ActionFalling   ldy     #$04                    ;load offset for walking/running
f036: 20 91 f0                     jsr     GetGfxOffsetAdder       ;get offset to graphics table
f039: 4c 62 f0                     jmp     GetCurrentAnimOffset    ;execute instructions for falling state

f03c: a0 04        ActionWalkRun   ldy     #$04                    ;load offset for walking/running
f03e: 20 91 f0                     jsr     GetGfxOffsetAdder       ;get offset to graphics table
f041: 4c 68 f0                     jmp     FourFrameExtent         ;execute instructions for normal state

f044: a0 05        ActionClimbing  ldy     #$05                    ;load offset for climbing
f046: a5 9f                        lda     Player_Y_Speed          ;check player's vertical speed
f048: f0 de                        beq     NonAnimatedActs         ;if no speed, branch, use offset as-is
f04a: 20 91 f0                     jsr     GetGfxOffsetAdder       ;otherwise get offset for graphics table
f04d: 4c 6d f0                     jmp     ThreeFrameExtent        ;then skip ahead to more code

f050: a0 01        ActionSwimming  ldy     #$01                    ;load offset for swimming
f052: 20 91 f0                     jsr     GetGfxOffsetAdder
f055: ad 82 07                     lda     JumpSwimTimer           ;check jump/swim timer
f058: 0d 0d 07                     ora     PlayerAnimCtrl          ; and animation frame control
f05b: d0 0b                        bne     FourFrameExtent         ;if any one of these set, branch ahead
f05d: a5 0a                        lda     A_B_Buttons
f05f: 0a                           asl     A                       ;check for A button pressed
f060: b0 06                        bcs     FourFrameExtent         ;branch to same place if A button pressed
                   GetCurrentAnimOffset
f062: ad 0d 07                     lda     PlayerAnimCtrl          ;get animation frame control
f065: 4c d0 f0                     jmp     GetOffsetFromAnimCtrl   ;jump to get proper offset to graphics table

f068: a9 03        FourFrameExtent lda     #$03                    ;load upper extent for frame control
f06a: 4c 6f f0                     jmp     AnimationControl        ;jump to get offset and animate player object

                   ThreeFrameExtent
f06d: a9 02                        lda     #$02                    ;load upper extent for frame control for climbing
                   AnimationControl
f06f: 85 00                        sta     $00                     ;store upper extent here
f071: 20 62 f0                     jsr     GetCurrentAnimOffset    ;get proper offset to graphics table
f074: 48                           pha                             ;save offset to stack
f075: ad 81 07                     lda     PlayerAnimTimer         ;load animation frame timer
f078: d0 15                        bne     ExAnimC                 ;branch if not expired
f07a: ad 0c 07                     lda     PlayerAnimTimerSet      ;get animation frame timer amount
f07d: 8d 81 07                     sta     PlayerAnimTimer         ;and set timer accordingly
f080: ad 0d 07                     lda     PlayerAnimCtrl
f083: 18                           clc                             ;add one to animation frame control
f084: 69 01                        adc     #$01
f086: c5 00                        cmp     $00                     ;compare to upper extent
f088: 90 02                        bcc     SetAnimC                ;if frame control + 1 < upper extent, use as next
f08a: a9 00                        lda     #$00                    ;otherwise initialize frame control
f08c: 8d 0d 07     SetAnimC        sta     PlayerAnimCtrl          ;store as new animation frame control
f08f: 68           ExAnimC         pla                             ;get offset to graphics table from stack and leave
f090: 60                           rts

                   GetGfxOffsetAdder
f091: ad 54 07                     lda     PlayerSize              ;get player's size
f094: f0 05                        beq     SzOfs                   ;if player big, use current offset as-is
f096: 98                           tya                             ; for big player
f097: 18                           clc                             ;otherwise add eight bytes to offset
f098: 69 08                        adc     #$08                    ; for small player
f09a: a8                           tay                             ;go back
f09b: 60           SzOfs           rts

                   ChangeSizeOffsetAdder
f09c: 00 01 00 01+                 .bulk   $00,$01,$00,$01,$00,$01,$02,$00,$01,$02,$02,$00,$02,$00,$02,$00
                                    +      $02,$00,$02,$00

                   HandleChangeSize
f0b0: ac 0d 07                     ldy     PlayerAnimCtrl          ;get animation frame control
f0b3: a5 09                        lda     FrameCounter
f0b5: 29 03                        and     #%00000011              ;get frame counter and execute this code every
f0b7: d0 0d                        bne     GorSLog                 ; fourth frame, otherwise branch ahead
f0b9: c8                           iny                             ;increment frame control
f0ba: c0 0a                        cpy     #$0a                    ;check for preset upper extent
f0bc: 90 05                        bcc     CszNext                 ;if not there yet, skip ahead to use
f0be: a0 00                        ldy     #$00                    ;otherwise initialize both grow/shrink flag
f0c0: 8c 0b 07                     sty     PlayerChangeSizeFlag    ; and animation frame control
f0c3: 8c 0d 07     CszNext         sty     PlayerAnimCtrl          ;store proper frame control
f0c6: ad 54 07     GorSLog         lda     PlayerSize              ;get player's size
f0c9: d0 0c                        bne     ShrinkPlayer            ;if player small, skip ahead to next part
f0cb: b9 9c f0                     lda     ChangeSizeOffsetAdder,y ;get offset adder based on frame control as offset
f0ce: a0 0f                        ldy     #$0f                    ;load offset for player growing
                   GetOffsetFromAnimCtrl
f0d0: 0a                           asl     A                       ;multiply animation frame control
f0d1: 0a                           asl     A                       ; by eight to get proper amount
f0d2: 0a                           asl     A                       ; to add to our offset
f0d3: 79 07 ee                     adc     PlayerGfxTblOffsets,y   ;add to offset to graphics table
f0d6: 60                           rts                             ; and return with result in A

f0d7: 98           ShrinkPlayer    tya                             ;add ten bytes to frame control as offset
f0d8: 18                           clc
f0d9: 69 0a                        adc     #$0a                    ;this thing apparently uses two of the swimming frames
f0db: aa                           tax                             ; to draw the player shrinking
f0dc: a0 09                        ldy     #$09                    ;load offset for small player swimming
f0de: bd 9c f0                     lda     ChangeSizeOffsetAdder,x ;get what would normally be offset adder
f0e1: d0 02                        bne     ShrPlF                  ; and branch to use offset if nonzero
f0e3: a0 01                        ldy     #$01                    ;otherwise load offset for big player swimming
f0e5: b9 07 ee     ShrPlF          lda     PlayerGfxTblOffsets,y   ;get offset to graphics table based on offset loaded
f0e8: 60                           rts                             ;and leave

                   ChkForPlayerAttrib
f0e9: ac e4 06                     ldy     SprDataOffset           ;get sprite data offset
f0ec: a5 0e                        lda     GameEngineSubroutine
f0ee: c9 0b                        cmp     #$0b                    ;if executing specific game engine routine,
f0f0: f0 13                        beq     KilledAtt               ; branch to change third and fourth row OAM attributes
f0f2: ad d5 06                     lda     PlayerGfxOffset         ;get graphics table offset
f0f5: c9 50                        cmp     #$50
f0f7: f0 1e                        beq     C_S_IGAtt               ;if crouch offset, either standing offset,
f0f9: c9 b8                        cmp     #$b8                    ; or intermediate growing offset,
f0fb: f0 1a                        beq     C_S_IGAtt               ; go ahead and execute code to change
f0fd: c9 c0                        cmp     #$c0                    ; fourth row OAM attributes only
f0ff: f0 16                        beq     C_S_IGAtt
f101: c9 c8                        cmp     #$c8
f103: d0 24                        bne     ExPlyrAt                ;if none of these, branch to leave
f105: b9 12 02     KilledAtt       lda     Sprite_Attributes+16,y
f108: 29 3f                        and     #%00111111              ;mask out horizontal and vertical flip bits
f10a: 99 12 02                     sta     Sprite_Attributes+16,y  ; for third row sprites and save
f10d: b9 16 02                     lda     Sprite_Attributes+20,y
f110: 29 3f                        and     #%00111111
f112: 09 40                        ora     #%01000000              ;set horizontal flip bit for second
f114: 99 16 02                     sta     Sprite_Attributes+20,y  ; sprite in the third row
f117: b9 1a 02     C_S_IGAtt       lda     Sprite_Attributes+24,y
f11a: 29 3f                        and     #%00111111              ;mask out horizontal and vertical flip bits
f11c: 99 1a 02                     sta     Sprite_Attributes+24,y  ; for fourth row sprites and save
f11f: b9 1e 02                     lda     Sprite_Attributes+28,y
f122: 29 3f                        and     #%00111111
f124: 09 40                        ora     #%01000000              ;set horizontal flip bit for second
f126: 99 1e 02                     sta     Sprite_Attributes+28,y  ; sprite in the fourth row
f129: 60           ExPlyrAt        rts                             ;leave

                   ; -----------------------------------------------------------------------------
                   ; $00 - used in adding to get proper offset
                   RelativePlayerPosition
f12a: a2 00                        ldx     #$00                    ;set offsets for relative cooordinates
f12c: a0 00                        ldy     #$00                    ; routine to correspond to player object
f12e: 4c 42 f1                     jmp     RelWOfs                 ;get the coordinates

                   RelativeBubblePosition
f131: a0 01                        ldy     #$01                    ;set for air bubble offsets
f133: 20 a8 f1                     jsr     GetProperObjOffset      ;modify X to get proper air bubble offset
f136: a0 03                        ldy     #$03
f138: 4c 42 f1                     jmp     RelWOfs                 ;get the coordinates

                   RelativeFireballPosition
f13b: a0 00                        ldy     #$00                    ;set for fireball offsets
f13d: 20 a8 f1                     jsr     GetProperObjOffset      ;modify X to get proper fireball offset
f140: a0 02                        ldy     #$02
f142: 20 71 f1     RelWOfs         jsr     GetObjRelativePosition  ;get the coordinates
f145: a6 08                        ldx     ObjectOffset            ;return original offset
f147: 60                           rts                             ;leave

                   RelativeMiscPosition
f148: a0 02                        ldy     #$02                    ;set for misc object offsets
f14a: 20 a8 f1                     jsr     GetProperObjOffset      ;modify X to get proper misc object offset
f14d: a0 06                        ldy     #$06
f14f: 4c 42 f1                     jmp     RelWOfs                 ;get the coordinates

                   RelativeEnemyPosition
f152: a9 01                        lda     #$01                    ;get coordinates of enemy object
f154: a0 01                        ldy     #$01                    ; relative to the screen
f156: 4c 65 f1                     jmp     VariableObjOfsRelPos

                   RelativeBlockPosition
f159: a9 09                        lda     #$09                    ;get coordinates of one block object
f15b: a0 04                        ldy     #$04                    ; relative to the screen
f15d: 20 65 f1                     jsr     VariableObjOfsRelPos
f160: e8                           inx                             ;adjust offset for other block object if any
f161: e8                           inx
f162: a9 09                        lda     #$09
f164: c8                           iny                             ;adjust other and get coordinates for other one
                   VariableObjOfsRelPos
f165: 86 00                        stx     $00                     ;store value to add to A here
f167: 18                           clc
f168: 65 00                        adc     $00                     ;add A to value stored
f16a: aa                           tax                             ;use as enemy offset
f16b: 20 71 f1                     jsr     GetObjRelativePosition
f16e: a6 08                        ldx     ObjectOffset            ;reload old object offset and leave
f170: 60                           rts

                   GetObjRelativePosition
f171: b5 ce                        lda     SprObject_Y_Position,x  ;load vertical coordinate low
f173: 99 b8 03                     sta     SprObject_Rel_YPos,y    ;store here
f176: b5 86                        lda     SprObject_X_Position,x  ;load horizontal coordinate
f178: 38                           sec                             ;subtract left edge coordinate
f179: ed 1c 07                     sbc     ScreenLeft_X_Pos
f17c: 99 ad 03                     sta     SprObject_Rel_XPos,y    ;store result here
f17f: 60                           rts

                   ; -----------------------------------------------------------------------------
                   ; $00 - used as temp variable to hold offscreen bits
                   GetPlayerOffscreenBits
f180: a2 00                        ldx     #$00                    ;set offsets for player-specific variables
f182: a0 00                        ldy     #$00                    ; and get offscreen information about player
f184: 4c c0 f1                     jmp     GetOffScreenBitsSet

                   GetFireballOffscreenBits
f187: a0 00                        ldy     #$00                    ;set for fireball offsets
f189: 20 a8 f1                     jsr     GetProperObjOffset      ;modify X to get proper fireball offset
f18c: a0 02                        ldy     #$02                    ;set other offset for fireball's offscreen bits
f18e: 4c c0 f1                     jmp     GetOffScreenBitsSet     ;and get offscreen information about fireball

                   GetBubbleOffscreenBits
f191: a0 01                        ldy     #$01                    ;set for air bubble offsets
f193: 20 a8 f1                     jsr     GetProperObjOffset      ;modify X to get proper air bubble offset
f196: a0 03                        ldy     #$03                    ;set other offset for airbubble's offscreen bits
f198: 4c c0 f1                     jmp     GetOffScreenBitsSet     ;and get offscreen information about air bubble

                   GetMiscOffscreenBits
f19b: a0 02                        ldy     #$02                    ;set for misc object offsets
f19d: 20 a8 f1                     jsr     GetProperObjOffset      ;modify X to get proper misc object offset
f1a0: a0 06                        ldy     #$06                    ;set other offset for misc object's offscreen bits
f1a2: 4c c0 f1                     jmp     GetOffScreenBitsSet     ;and get offscreen information about misc object

f1a5: 07 16 0d     ObjOffsetData   .bulk   $07,$16,$0d

                   GetProperObjOffset
f1a8: 8a                           txa                             ;move offset to A
f1a9: 18                           clc
f1aa: 79 a5 f1                     adc     ObjOffsetData,y         ;add amount of bytes to offset depending on setting in Y
f1ad: aa                           tax                             ;put back in X and leave
f1ae: 60                           rts

                   GetEnemyOffscreenBits
f1af: a9 01                        lda     #$01                    ;set A to add 1 byte in order to get enemy offset
f1b1: a0 01                        ldy     #$01                    ;set Y to put offscreen bits in Enemy_OffscreenBits
f1b3: 4c ba f1                     jmp     SetOffscrBitsOffset

                   GetBlockOffscreenBits
f1b6: a9 09                        lda     #$09                    ;set A to add 9 bytes in order to get block obj offset
f1b8: a0 04                        ldy     #$04                    ;set Y to put offscreen bits in Block_OffscreenBits
                   SetOffscrBitsOffset
f1ba: 86 00                        stx     $00
f1bc: 18                           clc                             ;add contents of X to A to get
f1bd: 65 00                        adc     $00                     ; appropriate offset, then give back to X
f1bf: aa                           tax
                   GetOffScreenBitsSet
f1c0: 98                           tya                             ;save offscreen bits offset to stack for now
f1c1: 48                           pha
f1c2: 20 d7 f1                     jsr     RunOffscrBitsSubs
f1c5: 0a                           asl     A                       ;move low nybble to high nybble
f1c6: 0a                           asl     A
f1c7: 0a                           asl     A
f1c8: 0a                           asl     A
f1c9: 05 00                        ora     $00                     ;mask together with previously saved low nybble
f1cb: 85 00                        sta     $00                     ;store both here
f1cd: 68                           pla                             ;get offscreen bits offset from stack
f1ce: a8                           tay
f1cf: a5 00                        lda     $00                     ;get value here and store elsewhere
f1d1: 99 d0 03                     sta     SprObject_OffscrBits,y
f1d4: a6 08                        ldx     ObjectOffset
f1d6: 60                           rts

                   RunOffscrBitsSubs
f1d7: 20 f6 f1                     jsr     GetXOffscreenBits       ;do subroutine here
f1da: 4a                           lsr     A                       ;move high nybble to low
f1db: 4a                           lsr     A
f1dc: 4a                           lsr     A
f1dd: 4a                           lsr     A
f1de: 85 00                        sta     $00                     ;store here
f1e0: 4c 39 f2                     jmp     GetYOffscreenBits

                   ; -----------------------------------------------------------------------------
                   ; (these apply to these three subsections)
                   ; $04 - used to store proper offset
                   ; $05 - used as adder in DividePDiff
                   ; $06 - used to store preset value used to compare to pixel difference in $07
                   ; $07 - used to store difference between coordinates of object and screen edges
                   XOffscreenBitsData
f1e3: 7f 3f 1f 0f+                 .bulk   $7f,$3f,$1f,$0f,$07,$03,$01,$00,$80,$c0,$e0,$f0,$f8,$fc,$fe,$ff
                   DefaultXOnscreenOfs
f1f3: 07 0f 07                     .bulk   $07,$0f,$07

                   GetXOffscreenBits
f1f6: 86 04                        stx     $04                     ;save position in buffer to here
f1f8: a0 01                        ldy     #$01                    ;start with right side of screen
f1fa: b9 1c 07     XOfsLoop        lda     ScreenLeft_X_Pos,y      ;get pixel coordinate of edge
f1fd: 38                           sec                             ;get difference between pixel coordinate of edge
f1fe: f5 86                        sbc     SprObject_X_Position,x  ; and pixel coordinate of object position
f200: 85 07                        sta     $07                     ;store here
f202: b9 1a 07                     lda     ScreenLeft_PageLoc,y    ;get page location of edge
f205: f5 6d                        sbc     SprObject_PageLoc,x     ;subtract from page location of object position
f207: be f3 f1                     ldx     DefaultXOnscreenOfs,y   ;load offset value here
f20a: c9 00                        cmp     #$00
f20c: 30 10                        bmi     XLdBData                ;if beyond right edge or in front of left edge, branch
f20e: be f4 f1                     ldx     DefaultXOnscreenOfs+1,y ;if not, load alternate offset value here
f211: c9 01                        cmp     #$01
f213: 10 09                        bpl     XLdBData                ;if one page or more to the left of either edge, branch
f215: a9 38                        lda     #$38                    ;if no branching, load value here and store
f217: 85 06                        sta     $06
f219: a9 08                        lda     #$08                    ;load some other value and execute subroutine
f21b: 20 6d f2                     jsr     DividePDiff
f21e: bd e3 f1     XLdBData        lda     XOffscreenBitsData,x    ;get bits here
f221: a6 04                        ldx     $04                     ;reobtain position in buffer
f223: c9 00                        cmp     #$00                    ;if bits not zero, branch to leave
f225: d0 03                        bne     ExXofsBS
f227: 88                           dey                             ;otherwise, do left side of screen now
f228: 10 d0                        bpl     XOfsLoop                ;branch if not already done with left side
f22a: 60           ExXofsBS        rts

                   ; -----------------------------------------------------------------------------
                   YOffscreenBitsData
f22b: 00 08 0c 0e+                 .bulk   $00,$08,$0c,$0e,$0f,$07,$03,$01,$00
                   DefaultYOnscreenOfs
f234: 04 00 04                     .bulk   $04,$00,$04
f237: ff 00        HighPosUnitData .bulk   $ff,$00

                   GetYOffscreenBits
f239: 86 04                        stx     $04                     ;save position in buffer to here
f23b: a0 01                        ldy     #$01                    ;start with top of screen
f23d: b9 37 f2     YOfsLoop        lda     HighPosUnitData,y       ;load coordinate for edge of vertical unit
f240: 38                           sec
f241: f5 ce                        sbc     SprObject_Y_Position,x  ;subtract from vertical coordinate of object
f243: 85 07                        sta     $07                     ;store here
f245: a9 01                        lda     #$01                    ;subtract one from vertical high byte of object
f247: f5 b5                        sbc     SprObject_Y_HighPos,x
f249: be 34 f2                     ldx     DefaultYOnscreenOfs,y   ;load offset value here
f24c: c9 00                        cmp     #$00
f24e: 30 10                        bmi     YLdBData                ;if under top of the screen or beyond bottom, branch
f250: be 35 f2                     ldx     DefaultYOnscreenOfs+1,y ;if not, load alternate offset value here
f253: c9 01                        cmp     #$01
f255: 10 09                        bpl     YLdBData                ;if one vertical unit or more above the screen, branch
f257: a9 20                        lda     #$20                    ;if no branching, load value here and store
f259: 85 06                        sta     $06
f25b: a9 04                        lda     #$04                    ;load some other value and execute subroutine
f25d: 20 6d f2                     jsr     DividePDiff
f260: bd 2b f2     YLdBData        lda     YOffscreenBitsData,x    ;get offscreen data bits using offset
f263: a6 04                        ldx     $04                     ;reobtain position in buffer
f265: c9 00                        cmp     #$00
f267: d0 03                        bne     ExYOfsBS                ;if bits not zero, branch to leave
f269: 88                           dey                             ;otherwise, do bottom of the screen now
f26a: 10 d1                        bpl     YOfsLoop
f26c: 60           ExYOfsBS        rts

                   ; -----------------------------------------------------------------------------
f26d: 85 05        DividePDiff     sta     $05                     ;store current value in A here
f26f: a5 07                        lda     $07                     ;get pixel difference
f271: c5 06                        cmp     $06                     ;compare to preset value
f273: b0 0c                        bcs     ExDivPD                 ;if pixel difference >= preset value, branch
f275: 4a                           lsr     A                       ;divide by eight
f276: 4a                           lsr     A
f277: 4a                           lsr     A
f278: 29 07                        and     #$07                    ;mask out all but 3 LSB
f27a: c0 01                        cpy     #$01                    ;right side of the screen or top?
f27c: b0 02                        bcs     SetOscrO                ;if so, branch, use difference / 8 as offset
f27e: 65 05                        adc     $05                     ;if not, add value to difference / 8
f280: aa           SetOscrO        tax                             ;use as offset
f281: 60           ExDivPD         rts                             ;leave

                   ; -----------------------------------------------------------------------------
                   ; $00-$01 - tile numbers
                   ; $02 - Y coordinate
                   ; $03 - flip control
                   ; $04 - sprite attributes
                   ; $05 - X coordinate
                   DrawSpriteObject
f282: a5 03                        lda     $03                     ;get saved flip control bits
f284: 4a                           lsr     A
f285: 4a                           lsr     A                       ;move d1 into carry
f286: a5 00                        lda     $00
f288: 90 0c                        bcc     NoHFlip                 ;if d1 not set, branch
f28a: 99 05 02                     sta     Sprite_Tilenumber+4,y   ;store first tile into second sprite
f28d: a5 01                        lda     $01                     ; and second into first sprite
f28f: 99 01 02                     sta     Sprite_Tilenumber,y
f292: a9 40                        lda     #$40                    ;activate horizontal flip OAM attribute
f294: d0 0a                        bne     SetHFAt                 ; and unconditionally branch

f296: 99 01 02     NoHFlip         sta     Sprite_Tilenumber,y     ;store first tile into first sprite
f299: a5 01                        lda     $01                     ; and second into second sprite
f29b: 99 05 02                     sta     Sprite_Tilenumber+4,y
f29e: a9 00                        lda     #$00                    ;clear bit for horizontal flip
f2a0: 05 04        SetHFAt         ora     $04                     ; add other OAM attributes if necessary
f2a2: 99 02 02                     sta     Sprite_Attributes,y     ;store sprite attributes
f2a5: 99 06 02                     sta     Sprite_Attributes+4,y
f2a8: a5 02                        lda     $02                     ;now the y coordinates
f2aa: 99 00 02                     sta     Sprite_Y_Position,y     ;note because they are
f2ad: 99 04 02                     sta     Sprite_Y_Position+4,y   ; side by side, they are the same
f2b0: a5 05                        lda     $05
f2b2: 99 03 02                     sta     Sprite_X_Position,y     ;store x coordinate, then
f2b5: 18                           clc                             ; add 8 pixels and store another to
f2b6: 69 08                        adc     #$08                    ; put them side by side
f2b8: 99 07 02                     sta     Sprite_X_Position+4,y
f2bb: a5 02                        lda     $02                     ;add eight pixels to the next y
f2bd: 18                           clc                             ; coordinate
f2be: 69 08                        adc     #$08
f2c0: 85 02                        sta     $02
f2c2: 98                           tya                             ;add eight to the offset in Y to
f2c3: 18                           clc                             ; move to the next two sprites
f2c4: 69 08                        adc     #$08
f2c6: a8                           tay
f2c7: e8                           inx                             ;increment offset to return it to the
f2c8: e8                           inx                             ; routine that called this subroutine
f2c9: 60                           rts

                   ; -----------------------------------------------------------------------------
f2ca: ff ff ff ff+                 .bulk   $ff,$ff,$ff,$ff,$ff,$ff

                   ; -----------------------------------------------------------------------------
f2d0: ad 70 07     SoundEngine     lda     OperMode                ;are we in title screen mode?
f2d3: d0 04                        bne     SndOn
f2d5: 8d 15 40                     sta     SND_CHN                 ;if so, disable sound and leave
f2d8: 60                           rts

f2d9: a9 ff        SndOn           lda     #$ff
f2db: 8d 17 40                     sta     JOY2                    ;disable irqs and set frame counter mode???
f2de: a9 0f                        lda     #$0f
f2e0: 8d 15 40                     sta     SND_CHN                 ;enable first four channels
f2e3: ad c6 07                     lda     PauseModeFlag           ;is sound already in pause mode?
f2e6: d0 06                        bne     InPause
f2e8: a5 fa                        lda     PauseSoundQueue         ;if not, check pause sfx queue
f2ea: c9 01                        cmp     #$01
f2ec: d0 5d                        bne     RunSoundSubroutines     ;if queue is empty, skip pause mode routine
f2ee: ad b2 07     InPause         lda     PauseSoundBuffer        ;check pause sfx buffer
f2f1: d0 23                        bne     ContPau
f2f3: a5 fa                        lda     PauseSoundQueue         ;check pause queue
f2f5: f0 66                        beq     SkipSoundSubroutines
f2f7: 8d b2 07                     sta     PauseSoundBuffer        ;if queue full, store in buffer and activate
f2fa: 8d c6 07                     sta     PauseModeFlag           ; pause mode to interrupt game sounds
f2fd: a9 00                        lda     #$00                    ;disable sound and clear sfx buffers
f2ff: 8d 15 40                     sta     SND_CHN
f302: 85 f1                        sta     Square1SoundBuffer
f304: 85 f2                        sta     Square2SoundBuffer
f306: 85 f3                        sta     NoiseSoundBuffer
f308: a9 0f                        lda     #$0f
f30a: 8d 15 40                     sta     SND_CHN                 ;enable sound again
f30d: a9 2a                        lda     #$2a                    ;store length of sound in pause counter
f30f: 8d bb 07                     sta     Squ1_SfxLenCounter
f312: a9 44        PTone1F         lda     #$44                    ;play first tone
f314: d0 11                        bne     PTRegC                  ;unconditional branch

f316: ad bb 07     ContPau         lda     Squ1_SfxLenCounter      ;check pause length left
f319: c9 24                        cmp     #$24                    ;time to play second?
f31b: f0 08                        beq     PTone2F
f31d: c9 1e                        cmp     #$1e                    ;time to play first again?
f31f: f0 f1                        beq     PTone1F
f321: c9 18                        cmp     #$18                    ;time to play second again?
f323: d0 09                        bne     DecPauC                 ;only load regs during times, otherwise skip
f325: a9 64        PTone2F         lda     #$64                    ;store reg contents and play the pause sfx
f327: a2 84        PTRegC          ldx     #$84
f329: a0 7f                        ldy     #$7f
f32b: 20 88 f3                     jsr     PlaySqu1Sfx
f32e: ce bb 07     DecPauC         dec     Squ1_SfxLenCounter      ;decrement pause sfx counter
f331: d0 2a                        bne     SkipSoundSubroutines
f333: a9 00                        lda     #$00                    ;disable sound if in pause mode and
f335: 8d 15 40                     sta     SND_CHN                 ; not currently playing the pause sfx
f338: ad b2 07                     lda     PauseSoundBuffer        ;if no longer playing pause sfx, check to see
f33b: c9 02                        cmp     #$02                    ;if we need to be playing sound again
f33d: d0 05                        bne     SkipPIn
f33f: a9 00                        lda     #$00                    ;clear pause mode to allow game sounds again
f341: 8d c6 07                     sta     PauseModeFlag
f344: a9 00        SkipPIn         lda     #$00                    ;clear pause sfx buffer
f346: 8d b2 07                     sta     PauseSoundBuffer
f349: f0 12                        beq     SkipSoundSubroutines

                   RunSoundSubroutines
f34b: 20 1b f4                     jsr     Square1SfxHandler       ;play sfx on square channel 1
f34e: 20 7c f5                     jsr     Square2SfxHandler       ; ''  ''  '' square channel 2
f351: 20 67 f6                     jsr     NoiseSfxHandler         ; ''  ''  '' noise channel
f354: 20 94 f6                     jsr     MusicHandler            ;play music on all channels
f357: a9 00                        lda     #$00                    ;clear the music queues
f359: 85 fb                        sta     AreaMusicQueue
f35b: 85 fc                        sta     EventMusicQueue
                   SkipSoundSubroutines
f35d: a9 00                        lda     #$00                    ;clear the sound effects queues
f35f: 85 ff                        sta     Square1SoundQueue
f361: 85 fe                        sta     Square2SoundQueue
f363: 85 fd                        sta     NoiseSoundQueue
f365: 85 fa                        sta     PauseSoundQueue
f367: ac c0 07                     ldy     DAC_Counter             ;load some sort of counter 
f36a: a5 f4                        lda     AreaMusicBuffer
f36c: 29 03                        and     #%00000011              ;check for specific music
f36e: f0 07                        beq     NoIncDAC
f370: ee c0 07                     inc     DAC_Counter             ;increment and check counter
f373: c0 30                        cpy     #$30
f375: 90 06                        bcc     StrWave                 ;if not there yet, just store it
f377: 98           NoIncDAC        tya
f378: f0 03                        beq     StrWave                 ;if we are at zero, do not decrement
f37a: ce c0 07                     dec     DAC_Counter             ;decrement counter
f37d: 8c 11 40     StrWave         sty     DMC_RAW                 ;store into DMC load register (??)
f380: 60                           rts                             ;we are done here

                   ; -----------------------------------------------------------------------------
f381: 8c 01 40     Dump_Squ1_Regs  sty     SQ1_SWEEP               ;dump the contents of X and Y into square 1's control regs
f384: 8e 00 40                     stx     SQ1_VOL
f387: 60                           rts

f388: 20 81 f3     PlaySqu1Sfx     jsr     Dump_Squ1_Regs          ;do sub to set ctrl regs for square 1, then set frequency regs
f38b: a2 00        SetFreq_Squ1    ldx     #$00                    ;set frequency reg offset for square 1 sound channel
f38d: a8           Dump_Freq_Regs  tay
f38e: b9 01 ff                     lda     FreqRegLookupTbl+1,y    ;use previous contents of A for sound reg offset
f391: f0 0b                        beq     NoTone                  ;if zero, then do not load
f393: 9d 02 40                     sta     SQ1_LO,x                ;first byte goes into LSB of frequency divider
f396: b9 00 ff                     lda     FreqRegLookupTbl,y      ;second byte goes into 3 MSB plus extra bit for
f399: 09 08                        ora     #%00001000              ;length counter
f39b: 9d 03 40                     sta     SQ1_HI,x
f39e: 60           NoTone          rts

f39f: 8e 04 40     Dump_Sq2_Regs   stx     SQ2_VOL                 ;dump the contents of X and Y into square 2's control regs
f3a2: 8c 05 40                     sty     SQ2_SWEEP
f3a5: 60                           rts

f3a6: 20 9f f3     PlaySqu2Sfx     jsr     Dump_Sq2_Regs           ;do sub to set ctrl regs for square 2, then set frequency regs
f3a9: a2 04        SetFreq_Squ2    ldx     #$04                    ;set frequency reg offset for square 2 sound channel
f3ab: d0 e0                        bne     Dump_Freq_Regs          ;unconditional branch

f3ad: a2 08        SetFreq_Tri     ldx     #$08                    ;set frequency reg offset for triangle sound channel
f3af: d0 dc                        bne     Dump_Freq_Regs          ;unconditional branch

                   ; -----------------------------------------------------------------------------
                   SwimStompEnvelopeData
f3b1: 9f 9b 98 96+                 .bulk   $9f,$9b,$98,$96,$95,$94,$92,$90,$90,$9a,$97,$95,$93,$92

                   PlayFlagpoleSlide
f3bf: a9 40                        lda     #$40                    ;store length of flagpole sound
f3c1: 8d bb 07                     sta     Squ1_SfxLenCounter
f3c4: a9 62                        lda     #$62                    ;load part of reg contents for flagpole sound
f3c6: 20 8b f3                     jsr     SetFreq_Squ1
f3c9: a2 99                        ldx     #$99                    ;now load the rest
f3cb: d0 25                        bne     FPS2nd

f3cd: a9 26        PlaySmallJump   lda     #$26                    ;branch here for small mario jumping sound
f3cf: d0 02                        bne     JumpRegContents

f3d1: a9 18        PlayBigJump     lda     #$18                    ;branch here for big mario jumping sound
f3d3: a2 82        JumpRegContents ldx     #$82                    ;note that small and big jump borrow each others' reg contents
f3d5: a0 a7                        ldy     #$a7                    ;anyway, this loads the first part of mario's jumping sound
f3d7: 20 88 f3                     jsr     PlaySqu1Sfx
f3da: a9 28                        lda     #$28                    ;store length of sfx for both jumping sounds
f3dc: 8d bb 07                     sta     Squ1_SfxLenCounter      ;then continue on here
f3df: ad bb 07     ContinueSndJump lda     Squ1_SfxLenCounter      ;jumping sounds seem to be composed of three parts
f3e2: c9 25                        cmp     #$25                    ;check for time to play second part yet
f3e4: d0 06                        bne     N2Prt
f3e6: a2 5f                        ldx     #$5f                    ;load second part
f3e8: a0 f6                        ldy     #$f6
f3ea: d0 08                        bne     DmpJpFPS                ;unconditional branch

f3ec: c9 20        N2Prt           cmp     #$20                    ;check for third part
f3ee: d0 29                        bne     DecJpFPS
f3f0: a2 48                        ldx     #$48                    ;load third part
f3f2: a0 bc        FPS2nd          ldy     #$bc                    ;the flagpole slide sound shares part of third part
f3f4: 20 81 f3     DmpJpFPS        jsr     Dump_Squ1_Regs
f3f7: d0 20                        bne     DecJpFPS                ;unconditional branch outta here
                   PlayFireballThrow
f3f9: a9 05                        lda     #$05
f3fb: a0 99                        ldy     #$99                    ;load reg contents for fireball throw sound
f3fd: d0 04                        bne     Fthrow                  ;unconditional branch

f3ff: a9 0a        PlayBump        lda     #$0a                    ;load length of sfx and reg contents for bump sound
f401: a0 93                        ldy     #$93
f403: a2 9e        Fthrow          ldx     #$9e                    ;the fireball sound shares reg contents with the bump sound
f405: 8d bb 07                     sta     Squ1_SfxLenCounter
f408: a9 0c                        lda     #$0c                    ;load offset for bump sound
f40a: 20 88 f3                     jsr     PlaySqu1Sfx
                   ContinueBumpThrow
f40d: ad bb 07                     lda     Squ1_SfxLenCounter      ;check for second part of bump sound
f410: c9 06                        cmp     #$06
f412: d0 05                        bne     DecJpFPS
f414: a9 bb                        lda     #$bb                    ;load second part directly
f416: 8d 01 40                     sta     SQ1_SWEEP
f419: d0 60        DecJpFPS        bne     BranchToDecLength1      ;unconditional branch

                   Square1SfxHandler
f41b: a4 ff                        ldy     Square1SoundQueue       ;check for sfx in queue
f41d: f0 20                        beq     CheckSfx1Buffer
f41f: 84 f1                        sty     Square1SoundBuffer      ;if found, put in buffer
f421: 30 aa                        bmi     PlaySmallJump           ;small jump
f423: 46 ff                        lsr     Square1SoundQueue
f425: b0 aa                        bcs     PlayBigJump             ;big jump
f427: 46 ff                        lsr     Square1SoundQueue
f429: b0 d4                        bcs     PlayBump                ;bump
f42b: 46 ff                        lsr     Square1SoundQueue
f42d: b0 2c                        bcs     PlaySwimStomp           ;swim/stomp
f42f: 46 ff                        lsr     Square1SoundQueue
f431: b0 4a                        bcs     PlaySmackEnemy          ;smack enemy
f433: 46 ff                        lsr     Square1SoundQueue
f435: b0 7f                        bcs     PlayPipeDownInj         ;pipedown/injury
f437: 46 ff                        lsr     Square1SoundQueue
f439: b0 be                        bcs     PlayFireballThrow       ;fireball throw
f43b: 46 ff                        lsr     Square1SoundQueue
f43d: b0 80                        bcs     PlayFlagpoleSlide       ;slide flagpole
f43f: a5 f1        CheckSfx1Buffer lda     Square1SoundBuffer      ;check for sfx in buffer 
f441: f0 17                        beq     ExS1H                   ;if not found, exit sub
f443: 30 9a                        bmi     ContinueSndJump         ;small mario jump
f445: 4a                           lsr     A
f446: b0 97                        bcs     ContinueSndJump         ;big mario jump
f448: 4a                           lsr     A
f449: b0 c2                        bcs     ContinueBumpThrow       ;bump
f44b: 4a                           lsr     A
f44c: b0 1b                        bcs     ContinueSwimStomp       ;swim/stomp
f44e: 4a                           lsr     A
f44f: b0 3c                        bcs     ContinueSmackEnemy      ;smack enemy
f451: 4a                           lsr     A
f452: b0 67                        bcs     ContinuePipeDownInj     ;pipedown/injury
f454: 4a                           lsr     A
f455: b0 b6                        bcs     ContinueBumpThrow       ;fireball throw
f457: 4a                           lsr     A
f458: b0 48                        bcs     DecrementSfx1Length     ;slide flagpole
f45a: 60           ExS1H           rts

f45b: a9 0e        PlaySwimStomp   lda     #$0e                    ;store length of swim/stomp sound
f45d: 8d bb 07                     sta     Squ1_SfxLenCounter
f460: a0 9c                        ldy     #$9c                    ;store reg contents for swim/stomp sound
f462: a2 9e                        ldx     #$9e
f464: a9 26                        lda     #$26
f466: 20 88 f3                     jsr     PlaySqu1Sfx
                   ContinueSwimStomp
f469: ac bb 07                     ldy     Squ1_SfxLenCounter      ;look up reg contents in data section based on
f46c: b9 b0 f3                     lda     SwimStompEnvelopeData-1,y ; length of sound left, used to control sound's
f46f: 8d 00 40                     sta     SQ1_VOL                 ; envelope
f472: c0 06                        cpy     #$06
f474: d0 05                        bne     BranchToDecLength1
f476: a9 9e                        lda     #$9e                    ;when the length counts down to a certain point, put this
f478: 8d 02 40                     sta     SQ1_LO                  ; directly into the LSB of square 1's frequency divider
                   BranchToDecLength1
f47b: d0 25                        bne     DecrementSfx1Length     ;unconditional branch (regardless of how we got here)

f47d: a9 0e        PlaySmackEnemy  lda     #$0e                    ;store length of smack enemy sound
f47f: a0 cb                        ldy     #$cb
f481: a2 9f                        ldx     #$9f
f483: 8d bb 07                     sta     Squ1_SfxLenCounter
f486: a9 28                        lda     #$28                    ;store reg contents for smack enemy sound
f488: 20 88 f3                     jsr     PlaySqu1Sfx
f48b: d0 15                        bne     DecrementSfx1Length     ;unconditional branch
                   ContinueSmackEnemy
f48d: ac bb 07                     ldy     Squ1_SfxLenCounter      ;check about halfway through
f490: c0 08                        cpy     #$08
f492: d0 09                        bne     SmSpc
f494: a9 a0                        lda     #$a0                    ;if we're at the about-halfway point, make the second tone
f496: 8d 02 40                     sta     SQ1_LO                  ; in the smack enemy sound
f499: a9 9f                        lda     #$9f
f49b: d0 02                        bne     SmTick

f49d: a9 90        SmSpc           lda     #$90                    ;this creates spaces in the sound, giving it its distinct noise
f49f: 8d 00 40     SmTick          sta     SQ1_VOL
                   DecrementSfx1Length
f4a2: ce bb 07                     dec     Squ1_SfxLenCounter      ;decrement length of sfx
f4a5: d0 0e                        bne     ExSfx1
f4a7: a2 00        StopSquare1Sfx  ldx     #$00                    ;if end of sfx reached, clear buffer
f4a9: 86 f1                        stx     Square1SoundBuffer      ; and stop making the sfx
f4ab: a2 0e                        ldx     #$0e
f4ad: 8e 15 40                     stx     SND_CHN
f4b0: a2 0f                        ldx     #$0f
f4b2: 8e 15 40                     stx     SND_CHN
f4b5: 60           ExSfx1          rts

f4b6: a9 2f        PlayPipeDownInj lda     #$2f                    ;load length of pipedown sound
f4b8: 8d bb 07                     sta     Squ1_SfxLenCounter
                   ContinuePipeDownInj
f4bb: ad bb 07                     lda     Squ1_SfxLenCounter      ;some bitwise logic, forces the regs
f4be: 4a                           lsr     A                       ; to be written to only during six specific times
f4bf: b0 10                        bcs     NoPDwnL                 ; during which d3 must be set and d1-0 must be clear
f4c1: 4a                           lsr     A
f4c2: b0 0d                        bcs     NoPDwnL
f4c4: 29 02                        and     #%00000010
f4c6: f0 09                        beq     NoPDwnL
f4c8: a0 91                        ldy     #$91                    ;and this is where it actually gets written in
f4ca: a2 9a                        ldx     #$9a
f4cc: a9 44                        lda     #$44
f4ce: 20 88 f3                     jsr     PlaySqu1Sfx
f4d1: 4c a2 f4     NoPDwnL         jmp     DecrementSfx1Length

                   ; -----------------------------------------------------------------------------
                   ExtraLifeFreqData
f4d4: 58 02 54 56+                 .bulk   $58,$02,$54,$56,$4e,$44
                   PowerUpGrabFreqData
f4da: 4c 52 4c 48+                 .bulk   $4c,$52,$4c,$48,$3e,$36,$3e,$36,$30,$28,$4a,$50,$4a,$64,$3c,$32
                                    +      $3c,$32,$2c,$24,$3a,$64,$3a,$34,$2c,$22,$2c
f4f5: 22 1c 14                     .bulk   $22,$1c,$14             ;residual frequency data
                   PUp_VGrow_FreqData
f4f8: 14 04 22 24+                 .bulk   $14,$04,$22,$24,$16,$04,$24,$26 ;used by both
f500: 18 04 26 28+                 .bulk   $18,$04,$26,$28,$1a,$04,$28,$2a
f508: 1c 04 2a 2c+                 .bulk   $1c,$04,$2a,$2c,$1e,$04,$2c,$2e ;used by vinegrow
f510: 20 04 2e 30+                 .bulk   $20,$04,$2e,$30,$22,$04,$30,$32

f518: a9 35        PlayCoinGrab    lda     #$35                    ;load length of coin grab sound
f51a: a2 8d                        ldx     #$8d                    ; and part of reg contents
f51c: d0 04                        bne     CGrab_TTickRegL

f51e: a9 06        PlayTimerTick   lda     #$06                    ;load length of timer tick sound
f520: a2 98                        ldx     #$98                    ; and part of reg contents
f522: 8d bd 07     CGrab_TTickRegL sta     Squ2_SfxLenCounter
f525: a0 7f                        ldy     #$7f                    ;load the rest of reg contents
f527: a9 42                        lda     #$42                    ; of coin grab and timer tick sound
f529: 20 a6 f3                     jsr     PlaySqu2Sfx
                   ContinueCGrabTTick
f52c: ad bd 07                     lda     Squ2_SfxLenCounter      ;check for time to play second tone yet
f52f: c9 30                        cmp     #$30                    ;timer tick sound also executes this, not sure why
f531: d0 05                        bne     N2Tone
f533: a9 54                        lda     #$54                    ;if so, load the tone directly into the reg
f535: 8d 06 40                     sta     SQ2_LO
f538: d0 2e        N2Tone          bne     DecrementSfx2Length

f53a: a9 20        PlayBlast       lda     #$20                    ;load length of fireworks/gunfire sound
f53c: 8d bd 07                     sta     Squ2_SfxLenCounter
f53f: a0 94                        ldy     #$94                    ;load reg contents of fireworks/gunfire sound
f541: a9 5e                        lda     #$5e
f543: d0 0b                        bne     SBlasJ

f545: ad bd 07     ContinueBlast   lda     Squ2_SfxLenCounter      ;check for time to play second part
f548: c9 18                        cmp     #$18
f54a: d0 1c                        bne     DecrementSfx2Length
f54c: a0 93                        ldy     #$93                    ;load second part reg contents then
f54e: a9 18                        lda     #$18
f550: d0 7f        SBlasJ          bne     BlstSJp                 ;unconditional branch to load rest of reg contents

f552: a9 36        PlayPowerUpGrab lda     #$36                    ;load length of power-up grab sound
f554: 8d bd 07                     sta     Squ2_SfxLenCounter
                   ContinuePowerUpGrab
f557: ad bd 07                     lda     Squ2_SfxLenCounter      ;load frequency reg based on length left over
f55a: 4a                           lsr     A                       ;divide by 2
f55b: b0 0b                        bcs     DecrementSfx2Length     ;alter frequency every other frame
f55d: a8                           tay
f55e: b9 d9 f4                     lda     PowerUpGrabFreqData-1,y ;use length left over / 2 for frequency offset
f561: a2 5d                        ldx     #$5d                    ;store reg contents of power-up grab sound
f563: a0 7f                        ldy     #$7f
f565: 20 a6 f3     LoadSqu2Regs    jsr     PlaySqu2Sfx
                   DecrementSfx2Length
f568: ce bd 07                     dec     Squ2_SfxLenCounter      ;decrement length of sfx
f56b: d0 0e                        bne     EsSfx2
f56d: a2 00        EmptySfx2Buffer ldx     #$00                    ;initialize square 2's sound effects buffer
f56f: 86 f2                        stx     Square2SoundBuffer
f571: a2 0d        StopSquare2Sfx  ldx     #$0d                    ;stop playing the sfx
f573: 8e 15 40                     stx     SND_CHN
f576: a2 0f                        ldx     #$0f
f578: 8e 15 40                     stx     SND_CHN
f57b: 60           EsSfx2          rts

                   Square2SfxHandler
f57c: a5 f2                        lda     Square2SoundBuffer      ;special handling for the 1-up sound to keep it
f57e: 29 40                        and     #Sfx_ExtraLife          ; from being interrupted by other sounds on square 2
f580: d0 65                        bne     ContinueExtraLife
f582: a4 fe                        ldy     Square2SoundQueue       ;check for sfx in queue
f584: f0 20                        beq     CheckSfx2Buffer
f586: 84 f2                        sty     Square2SoundBuffer      ;if found, put in buffer and check for the following
f588: 30 3e                        bmi     PlayBowserFall          ;bowser fall
f58a: 46 fe                        lsr     Square2SoundQueue
f58c: b0 8a                        bcs     PlayCoinGrab            ;coin grab
f58e: 46 fe                        lsr     Square2SoundQueue
f590: b0 6a                        bcs     PlayGrowPowerUp         ;power-up reveal
f592: 46 fe                        lsr     Square2SoundQueue
f594: b0 6a                        bcs     PlayGrowVine            ;vine grow
f596: 46 fe                        lsr     Square2SoundQueue
f598: b0 a0                        bcs     PlayBlast               ;fireworks/gunfire
f59a: 46 fe                        lsr     Square2SoundQueue
f59c: b0 80                        bcs     PlayTimerTick           ;timer tick
f59e: 46 fe                        lsr     Square2SoundQueue
f5a0: b0 b0                        bcs     PlayPowerUpGrab         ;power-up grab
f5a2: 46 fe                        lsr     Square2SoundQueue
f5a4: b0 3c                        bcs     PlayExtraLife           ;1-up
f5a6: a5 f2        CheckSfx2Buffer lda     Square2SoundBuffer      ;check for sfx in buffer
f5a8: f0 17                        beq     ExS2H                   ;if not found, exit sub
f5aa: 30 27                        bmi     ContinueBowserFall      ;bowser fall
f5ac: 4a                           lsr     A
f5ad: b0 13                        bcs     Cont_CGrab_TTick        ;coin grab
f5af: 4a                           lsr     A
f5b0: b0 5d                        bcs     ContinueGrowItems       ;power-up reveal
f5b2: 4a                           lsr     A
f5b3: b0 5a                        bcs     ContinueGrowItems       ;vine grow
f5b5: 4a                           lsr     A
f5b6: b0 8d                        bcs     ContinueBlast           ;fireworks/gunfire
f5b8: 4a                           lsr     A
f5b9: b0 07                        bcs     Cont_CGrab_TTick        ;timer tick
f5bb: 4a                           lsr     A
f5bc: b0 99                        bcs     ContinuePowerUpGrab     ;power-up grab
f5be: 4a                           lsr     A
f5bf: b0 26                        bcs     ContinueExtraLife       ;1-up
f5c1: 60           ExS2H           rts

                   Cont_CGrab_TTick
f5c2: 4c 2c f5                     jmp     ContinueCGrabTTick

                   JumpToDecLength2
f5c5: 4c 68 f5                     jmp     DecrementSfx2Length

f5c8: a9 38        PlayBowserFall  lda     #$38                    ;load length of bowser defeat sound
f5ca: 8d bd 07                     sta     Squ2_SfxLenCounter
f5cd: a0 c4                        ldy     #$c4                    ;load contents of reg for bowser defeat sound
f5cf: a9 18                        lda     #$18
f5d1: d0 0b        BlstSJp         bne     PBFRegs

                   ContinueBowserFall
f5d3: ad bd 07                     lda     Squ2_SfxLenCounter      ;check for almost near the end
f5d6: c9 08                        cmp     #$08
f5d8: d0 8e                        bne     DecrementSfx2Length
f5da: a0 a4                        ldy     #$a4                    ;if so, load the rest of reg contents for bowser defeat sound
f5dc: a9 5a                        lda     #$5a
f5de: a2 9f        PBFRegs         ldx     #$9f                    ;the fireworks/gunfire sound shares part of reg contents here
f5e0: d0 83        EL_LRegs        bne     LoadSqu2Regs            ;this is an unconditional branch outta here

f5e2: a9 30        PlayExtraLife   lda     #$30                    ;load length of 1-up sound
f5e4: 8d bd 07                     sta     Squ2_SfxLenCounter
                   ContinueExtraLife
f5e7: ad bd 07                     lda     Squ2_SfxLenCounter
f5ea: a2 03                        ldx     #$03                    ;load new tones only every eight frames
f5ec: 4a           DivLLoop        lsr     A
f5ed: b0 d6                        bcs     JumpToDecLength2        ;if any bits set here, branch to dec the length
f5ef: ca                           dex
f5f0: d0 fa                        bne     DivLLoop                ;do this until all bits checked, if none set, continue
f5f2: a8                           tay
f5f3: b9 d3 f4                     lda     ExtraLifeFreqData-1,y   ;load our reg contents
f5f6: a2 82                        ldx     #$82
f5f8: a0 7f                        ldy     #$7f
f5fa: d0 e4                        bne     EL_LRegs                ;unconditional branch

f5fc: a9 10        PlayGrowPowerUp lda     #$10                    ;load length of power-up reveal sound
f5fe: d0 02                        bne     GrowItemRegs

f600: a9 20        PlayGrowVine    lda     #$20                    ;load length of vine grow sound
f602: 8d bd 07     GrowItemRegs    sta     Squ2_SfxLenCounter
f605: a9 7f                        lda     #$7f                    ;load contents of reg for both sounds directly
f607: 8d 05 40                     sta     SQ2_SWEEP
f60a: a9 00                        lda     #$00                    ;start secondary counter for both sounds
f60c: 8d be 07                     sta     Sfx_SecondaryCounter
                   ContinueGrowItems
f60f: ee be 07                     inc     Sfx_SecondaryCounter    ;increment secondary counter for both sounds
f612: ad be 07                     lda     Sfx_SecondaryCounter    ;this sound doesn't decrement the usual counter
f615: 4a                           lsr     A                       ;divide by 2 to get the offset
f616: a8                           tay
f617: cc bd 07                     cpy     Squ2_SfxLenCounter      ;have we reached the end yet?
f61a: f0 0c                        beq     StopGrowItems           ;if so, branch to jump, and stop playing sounds
f61c: a9 9d                        lda     #$9d                    ;load contents of other reg directly
f61e: 8d 04 40                     sta     SQ2_VOL
f621: b9 f8 f4                     lda     PUp_VGrow_FreqData,y    ;use secondary counter / 2 as offset for frequency regs
f624: 20 a9 f3                     jsr     SetFreq_Squ2
f627: 60                           rts

f628: 4c 6d f5     StopGrowItems   jmp     EmptySfx2Buffer         ;branch to stop playing sounds

                   ; -----------------------------------------------------------------------------
                   BrickShatterFreqData
f62b: 01 0e 0e 0d+                 .bulk   $01,$0e,$0e,$0d,$0b,$06,$0c,$0f,$0a,$09,$03,$0d,$08,$0d,$06,$0c

                   PlayBrickShatter
f63b: a9 20                        lda     #$20                    ;load length of brick shatter sound
f63d: 8d bf 07                     sta     Noise_SfxLenCounter
                   ContinueBrickShatter
f640: ad bf 07                     lda     Noise_SfxLenCounter
f643: 4a                           lsr     A                       ;divide by 2 and check for bit set to use offset
f644: 90 12                        bcc     DecrementSfx3Length
f646: a8                           tay
f647: be 2b f6                     ldx     BrickShatterFreqData,y  ;load reg contents of brick shatter sound
f64a: b9 ea ff                     lda     BrickShatterEnvData,y
f64d: 8d 0c 40     PlayNoiseSfx    sta     NOISE_VOL               ;play the sfx
f650: 8e 0e 40                     stx     NOISE_LO
f653: a9 18                        lda     #$18
f655: 8d 0f 40                     sta     NOISE_HI
                   DecrementSfx3Length
f658: ce bf 07                     dec     Noise_SfxLenCounter     ;decrement length of sfx
f65b: d0 09                        bne     ExSfx3
f65d: a9 f0                        lda     #$f0                    ;if done, stop playing the sfx
f65f: 8d 0c 40                     sta     NOISE_VOL
f662: a9 00                        lda     #$00
f664: 85 f3                        sta     NoiseSoundBuffer
f666: 60           ExSfx3          rts

f667: a4 fd        NoiseSfxHandler ldy     NoiseSoundQueue         ;check for sfx in queue
f669: f0 0a                        beq     CheckNoiseBuffer
f66b: 84 f3                        sty     NoiseSoundBuffer        ;if found, put in buffer
f66d: 46 fd                        lsr     NoiseSoundQueue
f66f: b0 ca                        bcs     PlayBrickShatter        ;brick shatter
f671: 46 fd                        lsr     NoiseSoundQueue
f673: b0 0b                        bcs     PlayBowserFlame         ;bowser flame
                   CheckNoiseBuffer
f675: a5 f3                        lda     NoiseSoundBuffer        ;check for sfx in buffer
f677: f0 06                        beq     ExNH                    ;if not found, exit sub
f679: 4a                           lsr     A
f67a: b0 c4                        bcs     ContinueBrickShatter    ;brick shatter
f67c: 4a                           lsr     A
f67d: b0 06                        bcs     ContinueBowserFlame     ;bowser flame
f67f: 60           ExNH            rts

f680: a9 40        PlayBowserFlame lda     #$40                    ;load length of bowser flame sound
f682: 8d bf 07                     sta     Noise_SfxLenCounter
                   ContinueBowserFlame
f685: ad bf 07                     lda     Noise_SfxLenCounter
f688: 4a                           lsr     A
f689: a8                           tay
f68a: a2 0f                        ldx     #$0f                    ;load reg contents of bowser flame sound
f68c: b9 c9 ff                     lda     BowserFlameEnvData-1,y
f68f: d0 bc                        bne     PlayNoiseSfx            ;unconditional branch here
f691: 4c 3a f7     ContinueMusic   jmp     HandleSquare2Music      ;if we have music, start with square 2 channel

                   ; -----------------------------------------------------------------------------
f694: a5 fc        MusicHandler    lda     EventMusicQueue         ;check event music queue
f696: d0 0c                        bne     LoadEventMusic
f698: a5 fb                        lda     AreaMusicQueue          ;check area music queue
f69a: d0 2c                        bne     LoadAreaMusic
f69c: ad b1 07                     lda     EventMusicBuffer        ;check both buffers
f69f: 05 f4                        ora     AreaMusicBuffer
f6a1: d0 ee                        bne     ContinueMusic
f6a3: 60                           rts                             ;no music, then leave

f6a4: 8d b1 07     LoadEventMusic  sta     EventMusicBuffer        ;copy event music queue contents to buffer
f6a7: c9 01                        cmp     #DeathMusic             ;is it death music?
f6a9: d0 06                        bne     NoStopSfx               ;if not, jump elsewhere
f6ab: 20 a7 f4                     jsr     StopSquare1Sfx          ;stop sfx in square 1 and 2
f6ae: 20 71 f5                     jsr     StopSquare2Sfx          ; but clear only square 1's sfx buffer
f6b1: a6 f4        NoStopSfx       ldx     AreaMusicBuffer
f6b3: 8e c5 07                     stx     AreaMusicBuffer_Alt     ;save current area music buffer to be re-obtained later
f6b6: a0 00                        ldy     #$00
f6b8: 8c c4 07                     sty     NoteLengthTblAdder      ;default value for additional length byte offset
f6bb: 84 f4                        sty     AreaMusicBuffer         ;clear area music buffer
f6bd: c9 40                        cmp     #TimeRunningOutMusic    ;is it time running out music?
f6bf: d0 30                        bne     FindEventMusicHeader
f6c1: a2 08                        ldx     #$08                    ;load offset to be added to length byte of header
f6c3: 8e c4 07                     stx     NoteLengthTblAdder
f6c6: d0 29                        bne     FindEventMusicHeader    ;unconditional branch

f6c8: c9 04        LoadAreaMusic   cmp     #$04                    ;is it underground music?
f6ca: d0 03                        bne     NoStop1                 ;no, do not stop square 1 sfx
f6cc: 20 a7 f4                     jsr     StopSquare1Sfx
f6cf: a0 10        NoStop1         ldy     #$10                    ;start counter used only by ground level music
f6d1: 8c c7 07     GMLoopB         sty     GroundMusicHeaderOfs
                   HandleAreaMusicLoopB
f6d4: a0 00                        ldy     #$00                    ;clear event music buffer
f6d6: 8c b1 07                     sty     EventMusicBuffer
f6d9: 85 f4                        sta     AreaMusicBuffer         ;copy area music queue contents to buffer
f6db: c9 01                        cmp     #$01                    ;is it ground level music?
f6dd: d0 0e                        bne     FindAreaMusicHeader
f6df: ee c7 07                     inc     GroundMusicHeaderOfs    ;increment but only if playing ground level music
f6e2: ac c7 07                     ldy     GroundMusicHeaderOfs    ;is it time to loopback ground level music?
f6e5: c0 32                        cpy     #$32
f6e7: d0 0c                        bne     LoadHeader              ;branch ahead with alternate offset
f6e9: a0 11                        ldy     #$11
f6eb: d0 e4                        bne     GMLoopB                 ;unconditional branch

                   FindAreaMusicHeader
f6ed: a0 08                        ldy     #$08                    ;load Y for offset of area music
f6ef: 84 f7                        sty     MusicOffset_Square2     ;residual instruction here
                   FindEventMusicHeader
f6f1: c8                           iny                             ;increment Y pointer based on previously loaded queue contents
f6f2: 4a                           lsr     A                       ;bit shift and increment until we find a set bit for music
f6f3: 90 fc                        bcc     FindEventMusicHeader
f6f5: b9 0c f9     LoadHeader      lda     MusicHeaderData-1,y     ;load offset for header
f6f8: a8                           tay
f6f9: b9 0d f9                     lda     MusicHeaderData,y       ;now load the header
f6fc: 85 f0                        sta     NoteLenLookupTblOfs
f6fe: b9 0e f9                     lda     MusicHeaderData+1,y
f701: 85 f5                        sta     MusicData
f703: b9 0f f9                     lda     MusicHeaderData+2,y
f706: 85 f6                        sta     MusicData+1
f708: b9 10 f9                     lda     MusicHeaderData+3,y
f70b: 85 f9                        sta     MusicOffset_Triangle
f70d: b9 11 f9                     lda     MusicHeaderData+4,y
f710: 85 f8                        sta     MusicOffset_Square1
f712: b9 12 f9                     lda     MusicHeaderData+5,y
f715: 8d b0 07                     sta     MusicOffset_Noise
f718: 8d c1 07                     sta     NoiseDataLoopbackOfs
f71b: a9 01                        lda     #$01                    ;initialize music note counters
f71d: 8d b4 07                     sta     Squ2_NoteLenCounter
f720: 8d b6 07                     sta     Squ1_NoteLenCounter
f723: 8d b9 07                     sta     Tri_NoteLenCounter
f726: 8d ba 07                     sta     Noise_BeatLenCounter
f729: a9 00                        lda     #$00                    ;initialize music data offset for square 2
f72b: 85 f7                        sta     MusicOffset_Square2
f72d: 8d ca 07                     sta     AltRegContentFlag       ;initialize alternate control reg data used by square 1
f730: a9 0b                        lda     #$0b                    ;disable triangle channel and reenable it
f732: 8d 15 40                     sta     SND_CHN
f735: a9 0f                        lda     #$0f
f737: 8d 15 40                     sta     SND_CHN
                   HandleSquare2Music
f73a: ce b4 07                     dec     Squ2_NoteLenCounter     ;decrement square 2 note length
f73d: d0 5f                        bne     MiscSqu2MusicTasks      ;is it time for more data?  if not, branch to end tasks
f73f: a4 f7                        ldy     MusicOffset_Square2     ;increment square 2 music offset and fetch data
f741: e6 f7                        inc     MusicOffset_Square2
f743: b1 f5                        lda     (MusicData),y
f745: f0 04                        beq     EndOfMusicData          ;if zero, the data is a null terminator
f747: 10 3d                        bpl     Squ2NoteHandler         ;if non-negative, data is a note
f749: d0 2f                        bne     Squ2LengthHandler       ;otherwise it is length data

f74b: ad b1 07     EndOfMusicData  lda     EventMusicBuffer        ;check secondary buffer for time running out music
f74e: c9 40                        cmp     #TimeRunningOutMusic
f750: d0 05                        bne     NotTRO
f752: ad c5 07                     lda     AreaMusicBuffer_Alt     ;load previously saved contents of primary buffer
f755: d0 1d                        bne     MusicLoopBack           ; and start playing the song again if there is one
f757: 29 04        NotTRO          and     #VictoryMusic           ;check for victory music (the only secondary that loops)
f759: d0 1c                        bne     VictoryMLoopBack
f75b: a5 f4                        lda     AreaMusicBuffer         ;check primary buffer for any music except pipe intro
f75d: 29 5f                        and     #%01011111
f75f: d0 13                        bne     MusicLoopBack           ;if any area music except pipe intro, music loops
f761: a9 00                        lda     #$00                    ;clear primary and secondary buffers and initialize
f763: 85 f4                        sta     AreaMusicBuffer         ; control regs of square and triangle channels
f765: 8d b1 07                     sta     EventMusicBuffer
f768: 8d 08 40                     sta     TRI_LINEAR
f76b: a9 90                        lda     #$90
f76d: 8d 00 40                     sta     SQ1_VOL
f770: 8d 04 40                     sta     SQ2_VOL
f773: 60                           rts

f774: 4c d4 f6     MusicLoopBack   jmp     HandleAreaMusicLoopB

                   VictoryMLoopBack
f777: 4c a4 f6                     jmp     LoadEventMusic

                   Squ2LengthHandler
f77a: 20 cb f8                     jsr     ProcessLengthData       ;store length of note
f77d: 8d b3 07                     sta     Squ2_NoteLenBuffer
f780: a4 f7                        ldy     MusicOffset_Square2     ;fetch another byte (MUST NOT BE LENGTH BYTE!)
f782: e6 f7                        inc     MusicOffset_Square2
f784: b1 f5                        lda     (MusicData),y
f786: a6 f2        Squ2NoteHandler ldx     Square2SoundBuffer      ;is there a sound playing on this channel?
f788: d0 0e                        bne     SkipFqL1
f78a: 20 a9 f3                     jsr     SetFreq_Squ2            ;no, then play the note
f78d: f0 03                        beq     Rest                    ;check to see if note is rest
f78f: 20 d8 f8                     jsr     LoadControlRegs         ;if not, load control regs for square 2
f792: 8d b5 07     Rest            sta     Squ2_EnvelopeDataCtrl   ;save contents of A
f795: 20 9f f3                     jsr     Dump_Sq2_Regs           ;dump X and Y into square 2 control regs
f798: ad b3 07     SkipFqL1        lda     Squ2_NoteLenBuffer      ;save length in square 2 note counter
f79b: 8d b4 07                     sta     Squ2_NoteLenCounter
                   MiscSqu2MusicTasks
f79e: a5 f2                        lda     Square2SoundBuffer      ;is there a sound playing on square 2?
f7a0: d0 1a                        bne     HandleSquare1Music
f7a2: ad b1 07                     lda     EventMusicBuffer        ;check for death music or d4 set on secondary buffer
f7a5: 29 91                        and     #%10010001              ;note that regs for death music or d4 are loaded by default
f7a7: d0 13                        bne     HandleSquare1Music
f7a9: ac b5 07                     ldy     Squ2_EnvelopeDataCtrl   ;check for contents saved from LoadControlRegs
f7ac: f0 03                        beq     NoDecEnv1
f7ae: ce b5 07                     dec     Squ2_EnvelopeDataCtrl   ;decrement unless already zero
f7b1: 20 f4 f8     NoDecEnv1       jsr     LoadEnvelopeData        ;do a load of envelope data to replace default
f7b4: 8d 04 40                     sta     SQ2_VOL                 ;based on offset set by first load unless playing
f7b7: a2 7f                        ldx     #$7f                    ;death music or d4 set on secondary buffer
f7b9: 8e 05 40                     stx     SQ2_SWEEP
                   HandleSquare1Music
f7bc: a4 f8                        ldy     MusicOffset_Square1     ;is there a nonzero offset here?
f7be: f0 5a                        beq     HandleTriangleMusic     ;if not, skip ahead to the triangle channel
f7c0: ce b6 07                     dec     Squ1_NoteLenCounter     ;decrement square 1 note length
f7c3: d0 32                        bne     MiscSqu1MusicTasks      ;is it time for more data?
                   FetchSqu1MusicData
f7c5: a4 f8                        ldy     MusicOffset_Square1     ;increment square 1 music offset and fetch data
f7c7: e6 f8                        inc     MusicOffset_Square1
f7c9: b1 f5                        lda     (MusicData),y
f7cb: d0 0f                        bne     Squ1NoteHandler         ;if nonzero, then skip this part
f7cd: a9 83                        lda     #$83
f7cf: 8d 00 40                     sta     SQ1_VOL                 ;store some data into control regs for square 1
f7d2: a9 94                        lda     #$94                    ; and fetch another byte of data, used to give
f7d4: 8d 01 40                     sta     SQ1_SWEEP               ; death music its unique sound
f7d7: 8d ca 07                     sta     AltRegContentFlag
f7da: d0 e9                        bne     FetchSqu1MusicData      ;unconditional branch

f7dc: 20 c5 f8     Squ1NoteHandler jsr     AlternateLengthNalder
f7df: 8d b6 07                     sta     Squ1_NoteLenCounter     ;save contents of A in square 1 note counter
f7e2: a4 f1                        ldy     Square1SoundBuffer      ;is there a sound playing on square 1?
f7e4: d0 34                        bne     HandleTriangleMusic
f7e6: 8a                           txa
f7e7: 29 3e                        and     #%00111110              ;change saved data to appropriate note format
f7e9: 20 8b f3                     jsr     SetFreq_Squ1            ;play the note
f7ec: f0 03                        beq     SkipCtrlL
f7ee: 20 d8 f8                     jsr     LoadControlRegs
f7f1: 8d b7 07     SkipCtrlL       sta     Squ1_EnvelopeDataCtrl   ;save envelope offset
f7f4: 20 81 f3                     jsr     Dump_Squ1_Regs
                   MiscSqu1MusicTasks
f7f7: a5 f1                        lda     Square1SoundBuffer      ;is there a sound playing on square 1?
f7f9: d0 1f                        bne     HandleTriangleMusic
f7fb: ad b1 07                     lda     EventMusicBuffer        ;check for death music or d4 set on secondary buffer
f7fe: 29 91                        and     #%10010001
f800: d0 0e                        bne     DeathMAltReg
f802: ac b7 07                     ldy     Squ1_EnvelopeDataCtrl   ;check saved envelope offset
f805: f0 03                        beq     NoDecEnv2
f807: ce b7 07                     dec     Squ1_EnvelopeDataCtrl   ;decrement unless already zero
f80a: 20 f4 f8     NoDecEnv2       jsr     LoadEnvelopeData        ;do a load of envelope data
f80d: 8d 00 40                     sta     SQ1_VOL                 ; based on offset set by first load
f810: ad ca 07     DeathMAltReg    lda     AltRegContentFlag       ;check for alternate control reg data
f813: d0 02                        bne     DoAltLoad
f815: a9 7f                        lda     #$7f                    ;load this value if zero, the alternate value
f817: 8d 01 40     DoAltLoad       sta     SQ1_SWEEP               ;if nonzero, and let's move on
                   HandleTriangleMusic
f81a: a5 f9                        lda     MusicOffset_Triangle
f81c: ce b9 07                     dec     Tri_NoteLenCounter      ;decrement triangle note length
f81f: d0 4c                        bne     HandleNoiseMusic        ;is it time for more data?
f821: a4 f9                        ldy     MusicOffset_Triangle    ;increment square 1 music offset and fetch data
f823: e6 f9                        inc     MusicOffset_Triangle
f825: b1 f5                        lda     (MusicData),y
f827: f0 41                        beq     LoadTriCtrlReg          ;if zero, skip all this and move on to noise 
f829: 10 13                        bpl     TriNoteHandler          ;if non-negative, data is note
f82b: 20 cb f8                     jsr     ProcessLengthData       ;otherwise, it is length data
f82e: 8d b8 07                     sta     Tri_NoteLenBuffer       ;save contents of A
f831: a9 1f                        lda     #$1f
f833: 8d 08 40                     sta     TRI_LINEAR              ;load some default data for triangle control reg
f836: a4 f9                        ldy     MusicOffset_Triangle    ;fetch another byte
f838: e6 f9                        inc     MusicOffset_Triangle
f83a: b1 f5                        lda     (MusicData),y
f83c: f0 2c                        beq     LoadTriCtrlReg          ;check once more for nonzero data
f83e: 20 ad f3     TriNoteHandler  jsr     SetFreq_Tri
f841: ae b8 07                     ldx     Tri_NoteLenBuffer       ;save length in triangle note counter
f844: 8e b9 07                     stx     Tri_NoteLenCounter
f847: ad b1 07                     lda     EventMusicBuffer
f84a: 29 6e                        and     #%01101110              ;check for death music or d4 set on secondary buffer
f84c: d0 06                        bne     NotDOrD4                ;if playing any other secondary, skip primary buffer check
f84e: a5 f4                        lda     AreaMusicBuffer         ;check primary buffer for water or castle level music
f850: 29 0a                        and     #%00001010
f852: f0 19                        beq     HandleNoiseMusic        ;if playing any other primary, or death or d4, go on to noise routine
f854: 8a           NotDOrD4        txa                             ;if playing water or castle music or any secondary
f855: c9 12                        cmp     #$12                    ; besides death music or d4 set, check length of note
f857: b0 0f                        bcs     LongN
f859: ad b1 07                     lda     EventMusicBuffer        ;check for win castle music again if not playing a long note
f85c: 29 08                        and     #EndOfCastleMusic
f85e: f0 04                        beq     MediN
f860: a9 0f                        lda     #$0f                    ;load value $0f if playing the win castle music and playing a short
f862: d0 06                        bne     LoadTriCtrlReg          ; note, load value $1f if playing water or castle level music or any

f864: a9 1f        MediN           lda     #$1f                    ; secondary besides death and d4 except win castle or win castle and playing
f866: d0 02                        bne     LoadTriCtrlReg          ; a short note, and load value $ff if playing a long note on water, castle

f868: a9 ff        LongN           lda     #$ff                    ; or any secondary (including win castle) except death and d4
f86a: 8d 08 40     LoadTriCtrlReg  sta     TRI_LINEAR              ;save final contents of A into control reg for triangle
                   HandleNoiseMusic
f86d: a5 f4                        lda     AreaMusicBuffer         ;check if playing underground or castle music
f86f: 29 f3                        and     #%11110011
f871: f0 51                        beq     ExitMusicHandler        ;if so, skip the noise routine
f873: ce ba 07                     dec     Noise_BeatLenCounter    ;decrement noise beat length
f876: d0 4c                        bne     ExitMusicHandler        ;is it time for more data?
                   FetchNoiseBeatData
f878: ac b0 07                     ldy     MusicOffset_Noise       ;increment noise beat offset and fetch data
f87b: ee b0 07                     inc     MusicOffset_Noise
f87e: b1 f5                        lda     (MusicData),y           ;get noise beat data, if nonzero, branch to handle
f880: d0 08                        bne     NoiseBeatHandler
f882: ad c1 07                     lda     NoiseDataLoopbackOfs    ;if data is zero, reload original noise beat offset
f885: 8d b0 07                     sta     MusicOffset_Noise       ; and loopback next time around
f888: d0 ee                        bne     FetchNoiseBeatData      ;unconditional branch
                   NoiseBeatHandler
f88a: 20 c5 f8                     jsr     AlternateLengthNalder
f88d: 8d ba 07                     sta     Noise_BeatLenCounter    ;store length in noise beat counter
f890: 8a                           txa
f891: 29 3e                        and     #%00111110              ;reload data and erase length bits
f893: f0 24                        beq     SilentBeat              ;if no beat data, silence
f895: c9 30                        cmp     #$30                    ;check the beat data and play the appropriate
f897: f0 18                        beq     LongBeat                ;noise accordingly
f899: c9 20                        cmp     #$20
f89b: f0 0c                        beq     StrongBeat
f89d: 29 10                        and     #$10
f89f: f0 18                        beq     SilentBeat
f8a1: a9 1c                        lda     #$1c                    ;short beat data
f8a3: a2 03                        ldx     #$03
f8a5: a0 18                        ldy     #$18
f8a7: d0 12                        bne     PlayBeat

f8a9: a9 1c        StrongBeat      lda     #$1c                    ;strong beat data
f8ab: a2 0c                        ldx     #$0c
f8ad: a0 18                        ldy     #$18
f8af: d0 0a                        bne     PlayBeat

f8b1: a9 1c        LongBeat        lda     #$1c                    ;long beat data
f8b3: a2 03                        ldx     #$03
f8b5: a0 58                        ldy     #$58
f8b7: d0 02                        bne     PlayBeat

f8b9: a9 10        SilentBeat      lda     #$10                    ;silence
f8bb: 8d 0c 40     PlayBeat        sta     NOISE_VOL               ;load beat data into noise regs
f8be: 8e 0e 40                     stx     NOISE_LO
f8c1: 8c 0f 40                     sty     NOISE_HI
                   ExitMusicHandler
f8c4: 60                           rts

                   AlternateLengthNalder
f8c5: aa                           tax                             ;save a copy of original byte into X
f8c6: 6a                           ror     A                       ;save LSB from original byte into carry
f8c7: 8a                           txa                             ;reload original byte and rotate three times
f8c8: 2a                           rol     A                       ;turning xx00000x into 00000xxx, with the
f8c9: 2a                           rol     A                       ;bit in carry as the MSB here
f8ca: 2a                           rol     A
                   ProcessLengthData
f8cb: 29 07                        and     #%00000111              ;clear all but the three LSBs
f8cd: 18                           clc
f8ce: 65 f0                        adc     NoteLenLookupTblOfs     ;add offset loaded from first header byte
f8d0: 6d c4 07                     adc     NoteLengthTblAdder      ;add extra if time running out music
f8d3: a8                           tay
f8d4: b9 66 ff                     lda     MusicLengthLookupTbl,y  ;load length
f8d7: 60                           rts

f8d8: ad b1 07     LoadControlRegs lda     EventMusicBuffer        ;check secondary buffer for win castle music
f8db: 29 08                        and     #EndOfCastleMusic
f8dd: f0 04                        beq     NotECstlM
f8df: a9 04                        lda     #$04                    ;this value is only used for win castle music
f8e1: d0 0c                        bne     AllMus                  ;unconditional branch

f8e3: a5 f4        NotECstlM       lda     AreaMusicBuffer
f8e5: 29 7d                        and     #%01111101              ;check primary buffer for water music
f8e7: f0 04                        beq     WaterMus
f8e9: a9 08                        lda     #$08                    ;this is the default value for all other music
f8eb: d0 02                        bne     AllMus

f8ed: a9 28        WaterMus        lda     #$28                    ;this value is used for water music and all other event music
f8ef: a2 82        AllMus          ldx     #$82                    ;load contents of other sound regs for square 2
f8f1: a0 7f                        ldy     #$7f
f8f3: 60                           rts

                   LoadEnvelopeData
f8f4: ad b1 07                     lda     EventMusicBuffer        ;check secondary buffer for win castle music
f8f7: 29 08                        and     #EndOfCastleMusic
f8f9: f0 04                        beq     LoadUsualEnvData
f8fb: b9 96 ff                     lda     EndOfCastleMusicEnvData,y ;load data from offset for win castle music
f8fe: 60                           rts

                   LoadUsualEnvData
f8ff: a5 f4                        lda     AreaMusicBuffer         ;check primary buffer for water music
f901: 29 7d                        and     #%01111101
f903: f0 04                        beq     LoadWaterEventMusEnvData
f905: b9 9a ff                     lda     AreaMusicEnvData,y      ;load default data from offset for all other music
f908: 60                           rts

                   LoadWaterEventMusEnvData
f909: b9 a2 ff                     lda     WaterEventMusEnvData,y  ;load data from offset for water music and all other event music
f90c: 60                           rts

                   ; -----------------------------------------------------------------------------
                   ; 
                   ; music header offsets
                   ; 
                   ; ||(these are single-byte offsets from MusicHeaderData; no good way to
                   ; represent these in SourceGen)
f90d: a5 59 54 64+ MusicHeaderData .bulk   $a5,$59,$54,$64,$59,$3c,$31,$4b ;event music
f915: 69 5e 46 4f+                 .bulk   $69,$5e,$46,$4f,$36,$8d,$36,$4b ;area music
f91d: 8d 69 69 6f+                 .bulk   $8d,$69,$69,$6f,$75,$6f,$7b,$6f,$75,$6f,$7b,$81,$87,$81,$8d,$69 ;ground level music layout
                                    +      $69,$93,$99,$93,$9f,$93,$99,$93,$9f,$81,$87,$81,$8d,$93,$99,$93
                                    +      $9f
                   ; 
                   ; music headers
                   ; header format is as follows: 
                   ; 1 byte - length byte offset
                   ; 2 bytes -  music data address
                   ; 1 byte - triangle data offset
                   ; 1 byte - square 1 data offset
                   ; 1 byte - noise data offset (not used by secondary music)
                   TimeRunningOutHdr
f93e: 08                           .dd1    $08
f93f: 72                           .dd1    <TimeRunOutMusData
f940: fc                           .dd1    >TimeRunOutMusData
f941: 27 18                        .bulk   $27,$18
f943: 20           Str_CloudHdr    .dd1    $20
f944: b8                           .dd1    <Star_CloudMData
f945: f9                           .dd1    >Star_CloudMData
f946: 2e 1a 40                     .bulk   $2e,$1a,$40
                   EndOfLevelMusHdr
f949: 20                           .dd1    $20
f94a: b0                           .dd1    <WinLevelMusData
f94b: fc                           .dd1    >WinLevelMusData
f94c: 3d 21                        .bulk   $3d,$21
                   ResidualHeaderData
f94e: 20                           .dd1    $20
f94f: c4 fc                        .dd2    $fcc4
f951: 3f 1d                        .bulk   $3f,$1d
                   UndergroundMusHdr
f953: 18                           .dd1    $18
f954: 11                           .dd1    <UndergroundMusData
f955: fd 00 00                     .bulk   $fd,$00,$00
f958: 08           SilenceHdr      .dd1    $08
f959: 1c                           .dd1    <SilenceData
f95a: fa                           .dd1    >SilenceData
f95b: 00                           .dd1    $00
f95c: 00           CastleMusHdr    .dd1    $00
f95d: a4                           .dd1    <CastleMusData
f95e: fb                           .dd1    >CastleMusData
f95f: 93 62                        .bulk   $93,$62
f961: 10           VictoryMusHdr   .dd1    $10
f962: c8                           .dd1    <VictoryMusData
f963: fe                           .dd1    >VictoryMusData
f964: 24 14                        .bulk   $24,$14
f966: 18           GameOverMusHdr  .dd1    $18
f967: 45                           .dd1    <GameOverMusData
f968: fc                           .dd1    >GameOverMusData
f969: 1e 14                        .bulk   $1e,$14
f96b: 08           WaterMusHdr     .dd1    $08
f96c: 52                           .dd1    <WaterMusData
f96d: fd                           .dd1    >WaterMusData
f96e: a0 70 68                     .bulk   $a0,$70,$68
f971: 08           WinCastleMusHdr .dd1    $08
f972: 51                           .dd1    <EndOfCastleMusData
f973: fe                           .dd1    >EndOfCastleMusData
f974: 4c 24                        .bulk   $4c,$24
                   GroundLevelPart1Hdr
f976: 18                           .dd1    $18
f977: 01                           .dd1    <GroundM_P1Data
f978: fa                           .dd1    >GroundM_P1Data
f979: 2d 1c b8                     .bulk   $2d,$1c,$b8
                   GroundLevelPart2AHdr
f97c: 18                           .dd1    $18
f97d: 49                           .dd1    <GroundM_P2AData
f97e: fa                           .dd1    >GroundM_P2AData
f97f: 20 12 70                     .bulk   $20,$12,$70
                   GroundLevelPart2BHdr
f982: 18                           .dd1    $18
f983: 75                           .dd1    <GroundM_P2BData
f984: fa                           .dd1    >GroundM_P2BData
f985: 1b 10 44                     .bulk   $1b,$10,$44
                   GroundLevelPart2CHdr
f988: 18                           .dd1    $18
f989: 9d                           .dd1    <GroundM_P2CData
f98a: fa                           .dd1    >GroundM_P2CData
f98b: 11 0a 1c                     .bulk   $11,$0a,$1c
                   GroundLevelPart3AHdr
f98e: 18                           .dd1    $18
f98f: c2                           .dd1    <GroundM_P3AData
f990: fa                           .dd1    >GroundM_P3AData
f991: 2d 10 58                     .bulk   $2d,$10,$58
                   GroundLevelPart3BHdr
f994: 18                           .dd1    $18
f995: db                           .dd1    <GroundM_P3BData
f996: fa                           .dd1    >GroundM_P3BData
f997: 14 0d 3f                     .bulk   $14,$0d,$3f
                   GroundLevelLeadInHdr
f99a: 18                           .dd1    $18
f99b: f9                           .dd1    <GroundMLdInData
f99c: fa                           .dd1    >GroundMLdInData
f99d: 15 0d 21                     .bulk   $15,$0d,$21
                   GroundLevelPart4AHdr
f9a0: 18                           .dd1    $18
f9a1: 25                           .dd1    <GroundM_P4AData
f9a2: fb                           .dd1    >GroundM_P4AData
f9a3: 18 10 7a                     .bulk   $18,$10,$7a
                   GroundLevelPart4BHdr
f9a6: 18                           .dd1    $18
f9a7: 4b                           .dd1    <GroundM_P4BData
f9a8: fb                           .dd1    >GroundM_P4BData
f9a9: 19 0f 54                     .bulk   $19,$0f,$54
                   GroundLevelPart4CHdr
f9ac: 18                           .dd1    $18
f9ad: 74                           .dd1    <GroundM_P4CData
f9ae: fb                           .dd1    >GroundM_P4CData
f9af: 1e 12 2b                     .bulk   $1e,$12,$2b
f9b2: 18           DeathMusHdr     .dd1    $18
f9b3: 72                           .dd1    <DeathMusData
f9b4: fb                           .dd1    >DeathMusData
f9b5: 1e 0f 2d                     .bulk   $1e,$0f,$2d
                   ; -----------------------------------------------------------------------------
                   ; MUSIC DATA
                   ; 
                   ; square 2/triangle format
                   ; d7 - length byte flag (0-note, 1-length)
                   ; if d7 is set to 0 and d6-d0 is nonzero:
                   ;  d6-d0 - note offset in frequency look-up table (must be even)
                   ; if d7 is set to 1:
                   ;  d6-d3 - unused
                   ;  d2-d0 - length offset in length look-up table
                   ; value of $00 in square 2 data is used as null terminator, affects all sound
                   ; channels
                   ; value of $00 in triangle data causes routine to skip note
                   ; 
                   ; square 1 format
                   ; d7-d6, d0 - length offset in length look-up table (bit order is d0,d7,d6)
                   ; d5-d1 - note offset in frequency look-up table
                   ; value of $00 in square 1 data is flag alternate control reg data to be loaded
                   ; 
                   ; noise format
                   ; d7-d6, d0 - length offset in length look-up table (bit order is d0,d7,d6)
                   ; d5-d4 - beat type (0 - rest, 1 - short, 2 - strong, 3 - long)
                   ; d3-d1 - unused
                   ; value of $00 in noise data is used as null terminator, affects only noise
                   ; 
                   ; all music data is organized into sections (unless otherwise stated): square 2,
                   ; square 1, triangle, noise
f9b8: 84 2c 2c 2c+ Star_CloudMData .bulk   $84,$2c,$2c,$2c,$82,$04,$2c,$04,$85,$2c,$84,$2c,$2c,$2a,$2a,$2a
                                    +      $82,$04,$2a,$04,$85,$2a,$84,$2a,$2a,$00
f9d2: 1f 1f 1f 98+                 .bulk   $1f,$1f,$1f,$98,$1f,$1f,$98,$9e,$98,$1f,$1d,$1d,$1d,$94,$1d,$1d
                                    +      $94,$9c,$94,$1d
f9e6: 86 18 85 26+                 .bulk   $86,$18,$85,$26,$30,$84,$04,$26,$30,$86,$14,$85,$22,$2c,$84,$04
                                    +      $22,$2c
f9f8: 21 d0 c4 d0+                 .bulk   $21,$d0,$c4,$d0,$31,$d0,$c4,$d0,$00
fa01: 85 2c 22 1c+ GroundM_P1Data  .bulk   $85,$2c,$22,$1c,$84,$26,$2a,$82,$28,$26,$04,$87,$22,$34,$3a,$82
                                    +      $40,$04,$36,$84,$3a,$34,$82,$2c,$30,$85,$2a
fa1c: 00           SilenceData     .dd1    $00
fa1d: 5d 55 4d 15+                 .bulk   $5d,$55,$4d,$15,$19,$96,$15,$d5,$e3,$eb,$2d,$a6,$2b,$27,$9c,$9e
                                    +      $59,$85,$22,$1c,$14,$84,$1e,$22,$82,$20,$1e,$04,$87,$1c,$2c,$34
                                    +      $82,$36,$04,$30,$34,$04,$2c,$04,$26,$2a,$85,$22
fa49: 84 04 82 3a+ GroundM_P2AData .bulk   $84,$04,$82,$3a,$38,$36,$32,$04,$34,$04,$24,$26,$2c,$04,$26,$2c
                                    +      $30,$00,$05,$b4,$b2,$b0,$2b,$ac,$84,$9c,$9e,$a2,$84,$94,$9c,$9e
                                    +      $85,$14,$22,$84,$2c,$85,$1e,$82,$2c,$84,$2c,$1e
fa75: 84 04 82 3a+ GroundM_P2BData .bulk   $84,$04,$82,$3a,$38,$36,$32,$04,$34,$04,$64,$04,$64,$86,$64,$00
                                    +      $05,$b4,$b2,$b0,$2b,$ac,$84,$37,$b6,$b6,$45,$85,$14,$1c,$82,$22
                                    +      $84,$2c,$4e,$82,$4e,$84,$4e,$22
fa9d: 84 04 85 32+ GroundM_P2CData .bulk   $84,$04,$85,$32,$85,$30,$86,$2c,$04,$00,$05,$a4,$05,$9e,$05,$9d
                                    +      $85,$84,$14,$85,$24,$28,$2c,$82,$22,$84,$22,$14,$21,$d0,$c4,$d0
                                    +      $31,$d0,$c4,$d0,$00
fac2: 82 2c 84 2c+ GroundM_P3AData .bulk   $82,$2c,$84,$2c,$2c,$82,$2c,$30,$04,$34,$2c,$04,$26,$86,$22,$00
                                    +      $a4,$25,$25,$a4,$29,$a2,$1d,$9c,$95
fadb: 82 2c 2c 04+ GroundM_P3BData .bulk   $82,$2c,$2c,$04,$2c,$04,$2c,$30,$85,$34,$04,$04,$00,$a4,$25,$25
                                    +      $a4,$a8,$63,$04
                   ; triangle data used by both sections of third part
faef: 85 0e 1a 84+                 .bulk   $85,$0e,$1a,$84,$24,$85,$22,$14,$84,$0c
faf9: 82 34 84 34+ GroundMLdInData .bulk   $82,$34,$84,$34,$34,$82,$2c,$84,$34,$86,$3a,$04,$00,$a0,$21,$21
                                    +      $a0,$21,$2b,$05,$a3,$82,$18,$84,$18,$18,$82,$18,$18,$04,$86,$3a
                                    +      $22
                   ; noise data used by lead-in and third part sections
fb1a: 31 90 31 90+                 .bulk   $31,$90,$31,$90,$31,$71,$31,$90,$90,$90,$00
fb25: 82 34 84 2c+ GroundM_P4AData .bulk   $82,$34,$84,$2c,$85,$22,$84,$24,$82,$26,$36,$04,$36,$86,$26,$00
                                    +      $ac,$27,$5d,$1d,$9e,$2d,$ac,$9f,$85,$14,$82,$20,$84,$22,$2c,$1e
                                    +      $1e,$82,$2c,$2c,$1e,$04
fb4b: 87 2a 40 40+ GroundM_P4BData .bulk   $87,$2a,$40,$40,$40,$3a,$36,$82,$34,$2c,$04,$26,$86,$22,$00,$e3
                                    +      $f7,$f7,$f7,$f5,$f1,$ac,$27,$9e,$9d,$85,$18,$82,$1e,$84,$22,$2a
                                    +      $22,$22,$82,$2c,$2c,$22,$04
fb72: 86 04        DeathMusData    .bulk   $86,$04                 ;death music share data with fourth part c of ground level music 
fb74: 82 2a 36 04+ GroundM_P4CData .bulk   $82,$2a,$36,$04,$36,$87,$36,$34,$30,$86,$2c,$04,$00
fb81: 00 68 6a 6c+                 .bulk   $00,$68,$6a,$6c,$45     ;death music only
fb86: a2 31 b0 f1+                 .bulk   $a2,$31,$b0,$f1,$ed,$eb,$a2,$1d,$9c,$95
fb90: 86 04                        .bulk   $86,$04                 ;death music only
fb92: 85 22 82 22+                 .bulk   $85,$22,$82,$22,$87,$22,$26,$2a,$84,$2c,$22,$86,$14
                   ; noise data used by fourth part sections
fb9f: 51 90 31 11+                 .bulk   $51,$90,$31,$11,$00
fba4: 80 22 28 22+ CastleMusData   .bulk   $80,$22,$28,$22,$26,$22,$24,$22,$26,$22,$28,$22,$2a,$22,$28,$22
                                    +      $26,$22,$28,$22,$26,$22,$24,$22,$26,$22,$28,$22,$2a,$22,$28,$22
                                    +      $26,$20,$26,$20,$24,$20,$26,$20,$28,$20,$26,$20,$28,$20,$26,$20
                                    +      $24,$20,$26,$20,$24,$20,$26,$20,$28,$20,$26,$20,$28,$20,$26,$20
                                    +      $24,$28,$30,$28,$32,$28,$30,$28,$2e,$28,$30,$28,$2e,$28,$2c,$28
                                    +      $2e,$28,$30,$28,$32,$28,$30,$28,$2e,$28,$30,$28,$2e,$28,$2c,$28
                                    +      $2e,$00
fc06: 04 70 6e 6c+                 .bulk   $04,$70,$6e,$6c,$6e,$70,$72,$70,$6e,$70,$6e,$6c,$6e,$70,$72,$70
                                    +      $6e,$6e,$6c,$6e,$70,$6e,$70,$6e,$6c,$6e,$6c,$6e,$70,$6e,$70,$6e
                                    +      $6c,$76,$78,$76,$74,$76,$74,$72,$74,$76,$78,$76,$74,$76,$74,$72
                                    +      $74
fc37: 84 1a 83 18+                 .bulk   $84,$1a,$83,$18,$20,$84,$1e,$83,$1c,$28,$26,$1c,$1a,$1c
fc45: 82 2c 04 04+ GameOverMusData .bulk   $82,$2c,$04,$04,$22,$04,$04,$84,$1c,$87,$26,$2a,$26,$84,$24,$28
                                    +      $24,$80,$22,$00,$9c,$05,$94,$05,$0d,$9f,$1e,$9c,$98,$9d,$82,$22
                                    +      $04,$04,$1c,$04,$04,$84,$14,$86,$1e,$80,$16,$80,$14
                   TimeRunOutMusData
fc72: 81 1c 30 04+                 .bulk   $81,$1c,$30,$04,$30,$30,$04,$1e,$32,$04,$32,$32,$04,$20,$34,$04
                                    +      $34,$34,$04,$36,$04,$84,$36,$00,$46,$a4,$64,$a4,$48,$a6,$66,$a6
                                    +      $4a,$a8,$68,$a8,$6a,$44,$2b,$81,$2a,$42,$04,$42,$42,$04,$2c,$64
                                    +      $04,$64,$64,$04,$2e,$46,$04,$46,$46,$04,$22,$04,$84,$22
fcb0: 87 04 06 0c+ WinLevelMusData .bulk   $87,$04,$06,$0c,$14,$1c,$22,$86,$2c,$22,$87,$04,$60,$0e,$14,$1a
                                    +      $24,$86,$2c,$24,$87,$04,$08,$10,$18,$1e,$28,$86,$30,$30,$80,$64
                                    +      $00,$cd,$d5,$dd,$e3,$ed,$f5,$bb,$b5,$cf,$d5,$db,$e5,$ed,$f3,$bd
                                    +      $b3,$d1,$d9,$df,$e9,$f1,$f7,$bf,$ff,$ff,$ff,$34
fcec: 00                           .dd1    $00                     ;unused byte
fced: 86 04 87 14+                 .bulk   $86,$04,$87,$14,$1c,$22,$86,$34,$84,$2c,$04,$04,$04,$87,$14,$1a
                                    +      $24,$86,$32,$84,$2c,$04,$86,$04,$87,$18,$1e,$28,$86,$36,$87,$30
                                    +      $30,$30,$80,$2c
                   ; square 2 and triangle use the same data, square 1 is unused
                   UndergroundMusData
fd11: 82 14 2c 62+                 .bulk   $82,$14,$2c,$62,$26,$10,$28,$80,$04,$82,$14,$2c,$62,$26,$10,$28
                                    +      $80,$04,$82,$08,$1e,$5e,$18,$60,$1a,$80,$04,$82,$08,$1e,$5e,$18
                                    +      $60,$1a,$86,$04,$83,$1a,$18,$16,$84,$14,$1a,$18,$0e,$0c,$16,$83
                                    +      $14,$20,$1e,$1c,$28,$26,$87,$24,$1a,$12,$10,$62,$0e,$80,$04,$04
                                    +      $00
                   ; noise data directly follows square 2 here unlike in other songs
fd52: 82 18 1c 20+ WaterMusData    .bulk   $82,$18,$1c,$20,$22,$26,$28,$81,$2a,$2a,$2a,$04,$2a,$04,$83,$2a
                                    +      $82,$22,$86,$34,$32,$34,$81,$04,$22,$26,$2a,$2c,$30,$86,$34,$83
                                    +      $32,$82,$36,$84,$34,$85,$04,$81,$22,$86,$30,$2e,$30,$81,$04,$22
                                    +      $26,$2a,$2c,$2e,$86,$30,$83,$22,$82,$36,$84,$34,$85,$04,$81,$22
                                    +      $86,$3a,$3a,$3a,$82,$3a,$81,$40,$82,$04,$81,$3a,$86,$36,$36,$36
                                    +      $82,$36,$81,$3a,$82,$04,$81,$36,$86,$34,$82,$26,$2a,$36,$81,$34
                                    +      $34,$85,$34,$81,$2a,$86,$2c,$00
fdba: 84 90 b0 84+                 .bulk   $84,$90,$b0,$84,$50,$50,$b0,$00
fdc2: 98 96 94 92+                 .bulk   $98,$96,$94,$92,$94,$96,$58,$58,$58,$44,$5c,$44,$9f,$a3,$a1,$a3
                                    +      $85,$a3,$e0,$a6,$23,$c4,$9f,$9d,$9f,$85,$9f,$d2,$a6,$23,$c4,$b5
                                    +      $b1,$af,$85,$b1,$af,$ad,$85,$95,$9e,$a2,$aa,$6a,$6a,$6b,$5e,$9d
fdf2: 84 04 04 82+                 .bulk   $84,$04,$04,$82,$22,$86,$22,$82,$14,$22,$2c,$12,$22,$2a,$14,$22
                                    +      $2c,$1c,$22,$2c,$14,$22,$2c,$12,$22,$2a,$14,$22,$2c,$1c,$22,$2c
                                    +      $18,$22,$2a,$16,$20,$28,$18,$22,$2a,$12,$22,$2a,$18,$22,$2a,$12
                                    +      $22,$2a,$14,$22,$2c,$0c,$22,$2c,$14,$22,$34,$12,$22,$30,$10,$22
                                    +      $2e,$16,$22,$34,$18,$26,$36,$16,$26,$36,$14,$26,$36,$12,$22,$36
                                    +      $5c,$22,$34,$0c,$22,$22,$81,$1e,$1e,$85,$1e,$81,$12,$86,$14
                   EndOfCastleMusData
fe51: 81 2c 22 1c+                 .bulk   $81,$2c,$22,$1c,$2c,$22,$1c,$85,$2c,$04,$81,$2e,$24,$1e,$2e,$24
                                    +      $1e,$85,$2e,$04,$81,$32,$28,$22,$32,$28,$22,$85,$32,$87,$36,$36
                                    +      $36,$84,$3a,$00
fe75: 5c 54 4c 5c+                 .bulk   $5c,$54,$4c,$5c,$54,$4c,$5c,$1c,$1c,$5c,$5c,$5c,$5c,$5e,$56,$4e
                                    +      $5e,$56,$4e,$5e,$1e,$1e,$5e,$5e,$5e,$5e,$62,$5a,$50,$62,$5a,$50
                                    +      $62,$22,$22,$62,$e7,$e7,$e7,$2b
fe9d: 86 14 81 14+                 .bulk   $86,$14,$81,$14,$80,$14,$14,$81,$14,$14,$14,$14,$86,$16,$81,$16
                                    +      $80,$16,$16,$81,$16,$16,$16,$16,$81,$28,$22,$1a,$28,$22,$1a,$28
                                    +      $80,$28,$28,$81,$28,$87,$2c,$2c,$2c,$84,$30
fec8: 83 04 84 0c+ VictoryMusData  .bulk   $83,$04,$84,$0c,$83,$62,$10,$84,$12,$83,$1c,$22,$1e,$22,$26,$18
                                    +      $1e,$04,$1c,$00
fedc: e3 e1 e3 1d+                 .bulk   $e3,$e1,$e3,$1d,$de,$e0,$23,$ec,$75,$74,$f0,$f4,$f6,$ea,$31,$2d
feec: 83 12 14 04+                 .bulk   $83,$12,$14,$04,$18,$1a,$1c,$14,$26,$22,$1e,$1c,$18,$1e,$22,$0c
                                    +      $14
                   ; unused space
fefd: ff ff ff                     .bulk   $ff,$ff,$ff
                   FreqRegLookupTbl
ff00: 00 88 00 2f+                 .bulk   $00,$88,$00,$2f,$00,$00,$02,$a6,$02,$80,$02,$5c,$02,$3a,$02,$1a
                                    +      $01,$df,$01,$c4,$01,$ab,$01,$93,$01,$7c,$01,$67,$01,$53,$01,$40
                                    +      $01,$2e,$01,$1d,$01,$0d,$00,$fe,$00,$ef,$00,$e2,$00,$d5,$00,$c9
                                    +      $00,$be,$00,$b3,$00,$a9,$00,$a0,$00,$97,$00,$8e,$00,$86,$00,$77
                                    +      $00,$7e,$00,$71,$00,$54,$00,$64,$00,$5f,$00,$59,$00,$50,$00,$47
                                    +      $00,$43,$00,$3b,$00,$35,$00,$2a,$00,$23,$04,$75,$03,$57,$02,$f9
                                    +      $02,$cf,$01,$fc,$00,$6a
                   MusicLengthLookupTbl
ff66: 05 0a 14 28+                 .bulk   $05,$0a,$14,$28,$50,$1e,$3c,$02,$04,$08,$10,$20,$40,$18,$30,$0c
                                    +      $03,$06,$0c,$18,$30,$12,$24,$08,$36,$03,$09,$06,$12,$1b,$24,$0c
                                    +      $24,$02,$06,$04,$0c,$12,$18,$08,$12,$01,$03,$02,$06,$09,$0c,$04
                   EndOfCastleMusicEnvData
ff96: 98 99 9a 9b                  .bulk   $98,$99,$9a,$9b
                   AreaMusicEnvData
ff9a: 90 94 94 95+                 .bulk   $90,$94,$94,$95,$95,$96,$97,$98
                   WaterEventMusEnvData
ffa2: 90 91 92 92+                 .bulk   $90,$91,$92,$92,$93,$93,$93,$94,$94,$94,$94,$94,$94,$95,$95,$95
                                    +      $95,$95,$95,$96,$96,$96,$96,$96,$96,$96,$96,$96,$96,$96,$96,$96
                                    +      $96,$96,$96,$96,$95,$95,$94,$93
                   BowserFlameEnvData
ffca: 15 16 16 17+                 .bulk   $15,$16,$16,$17,$17,$18,$19,$19,$1a,$1a,$1c,$1d,$1d,$1e,$1e,$1f
                                    +      $1f,$1f,$1f,$1e,$1d,$1c,$1e,$1f,$1f,$1e,$1d,$1c,$1a,$18,$16,$14
                   BrickShatterEnvData
ffea: 15 16 16 17+                 .bulk   $15,$16,$16,$17,$17,$18,$19,$19,$1a,$1a,$1c,$1d,$1d,$1e,$1e,$1f
                   ; 
fffa: 82 80                        .dd2    NonMaskableInterrupt    ;NMI vector
fffc: 00 80                        .dd2    Start                   ;reset vector
fffe: f0 ff                        .dd2    BrickShatterEnvData+6   ;IRQ vector (unused)
                                   .adrend ↑ $8000

                   ; 
                   ; CHR block.  This is not directly addressable on the 6502.
                   ; 
                   ; The label ("CHR_ROM") is used by the visualizer.  Don't rename it.
                   ; 
                   vis
                                   .addrs  NA
0000: 03 0f 1f 1f+ CHR_ROM         .bulk   $03,$0f,$1f,$1f,$1c,$24,$26,$66,$00,$00,$00,$00,$1f,$3f,$3f,$7f
0010: e0 c0 80 fc+                 .bulk   $e0,$c0,$80,$fc,$80,$c0,$00,$20,$00,$20,$60,$00,$f0,$fc,$fe,$fe
0020: 60 70 18 07+                 .bulk   $60,$70,$18,$07,$0f,$1f,$3f,$7f,$7f,$7f,$1f,$07,$00,$1e,$3f,$7f
0030: fc 7c 00 00+                 .bulk   $fc,$7c,$00,$00,$e0,$f0,$f8,$f8,$fc,$fc,$f8,$c0,$c2,$67,$2f,$37
0040: 7f 7f ff ff+                 .bulk   $7f,$7f,$ff,$ff,$07,$07,$0f,$0f,$7f,$7e,$fc,$f0,$f8,$f8,$f0,$70
0050: fd fe b4 f8+                 .bulk   $fd,$fe,$b4,$f8,$f8,$f9,$fb,$ff,$37,$36,$5c,$00,$00,$01,$03,$1f
0060: 1f 3f ff ff+                 .bulk   $1f,$3f,$ff,$ff,$fc,$70,$70,$38,$08,$24,$e3,$f0,$f8,$70,$70,$38
0070: ff ff ff 1f+                 .bulk   $ff,$ff,$ff,$1f,$00,$00,$00,$00,$1f,$1f,$1f,$1f,$00,$00,$00,$00
0080: 00 00 01 07+                 .bulk   $00,$00,$01,$07,$0f,$0f,$0e,$12,$00,$00,$00,$00,$00,$00,$0f,$1f
0090: 00 00 f0 e0+                 .bulk   $00,$00,$f0,$e0,$c0,$fe,$40,$60,$00,$00,$00,$10,$30,$00,$f8,$fe
00a0: 13 33 30 18+                 .bulk   $13,$33,$30,$18,$04,$0f,$1f,$1f,$1f,$3f,$3f,$1f,$07,$08,$17,$17
00b0: 00 10 7e 3e+                 .bulk   $00,$10,$7e,$3e,$00,$00,$c0,$e0,$ff,$ff,$fe,$fe,$fc,$e0,$40,$a0
00c0: 3f 3f 3f 1f+                 .bulk   $3f,$3f,$3f,$1f,$1f,$1f,$1f,$1f,$37,$27,$23,$03,$01,$00,$00,$00
00d0: f0 f0 f0 f8+                 .bulk   $f0,$f0,$f0,$f8,$f8,$f8,$f8,$f8,$cc,$ff,$ff,$ff,$ff,$70,$00,$08
00e0: ff ff ff fe+                 .bulk   $ff,$ff,$ff,$fe,$f0,$c0,$80,$00,$f0,$f0,$f0,$f0,$f0,$c0,$80,$00
00f0: fc fc f8 78+                 .bulk   $fc,$fc,$f8,$78,$78,$78,$7e,$7e,$10,$60,$80,$00,$78,$78,$7e,$7e
0100: 00 03 0f 1f+                 .bulk   $00,$03,$0f,$1f,$1f,$1c,$24,$26,$00,$00,$00,$00,$00,$1f,$3f,$3f
0110: 00 e0 c0 80+                 .bulk   $00,$e0,$c0,$80,$fc,$80,$c0,$00,$00,$00,$20,$60,$00,$f0,$fc,$fe
0120: 66 60 30 18+                 .bulk   $66,$60,$30,$18,$0f,$1f,$3f,$3f,$7f,$7f,$3f,$1f,$00,$16,$2f,$2f
0130: 20 fc 7c 00+                 .bulk   $20,$fc,$7c,$00,$00,$e0,$e0,$f0,$fe,$fc,$fc,$f8,$c0,$60,$20,$30
0140: 3f 3f 3f 3f+                 .bulk   $3f,$3f,$3f,$3f,$3f,$3f,$3f,$1f,$2f,$2f,$2f,$0f,$07,$03,$00,$00
0150: f0 90 00 08+                 .bulk   $f0,$90,$00,$08,$0c,$1c,$fc,$f8,$10,$f0,$f0,$f0,$f0,$e0,$c0,$e0
0160: 0f 0f 07 07+                 .bulk   $0f,$0f,$07,$07,$07,$0f,$0f,$03,$01,$03,$01,$04,$07,$0f,$0f,$03
0170: f8 f0 e0 f0+                 .bulk   $f8,$f0,$e0,$f0,$b0,$80,$e0,$e0,$f8,$f0,$e0,$70,$b0,$80,$e0,$e0
0180: 03 3f 7f 19+                 .bulk   $03,$3f,$7f,$19,$09,$09,$28,$5c,$00,$30,$70,$7f,$ff,$ff,$f7,$f3
0190: f8 e0 e0 fc+                 .bulk   $f8,$e0,$e0,$fc,$26,$30,$80,$10,$00,$18,$10,$00,$f8,$f8,$fe,$ff
01a0: 3e 1e 3f 38+                 .bulk   $3e,$1e,$3f,$38,$30,$30,$00,$3a,$e7,$0f,$0f,$1f,$1f,$1f,$0f,$07
01b0: 78 1e 80 fe+                 .bulk   $78,$1e,$80,$fe,$7e,$7e,$7f,$7f,$ff,$fe,$fc,$c6,$8e,$ee,$ff,$ff
01c0: 3c 3f 1f 0f+                 .bulk   $3c,$3f,$1f,$0f,$07,$3f,$21,$20,$03,$00,$00,$0e,$07,$3f,$3f,$3f
01d0: ff ff ff fe+                 .bulk   $ff,$ff,$ff,$fe,$fe,$fe,$fc,$70,$ff,$7f,$3f,$0e,$c0,$c0,$e0,$e0
01e0: 0f 9f cf ff+                 .bulk   $0f,$9f,$cf,$ff,$7f,$3f,$1e,$0e,$00,$80,$c8,$fe,$7f,$3f,$1e,$0e
01f0: 20 c0 80 80+                 .bulk   $20,$c0,$80,$80,$00,$00,$00,$00,$e0,$00,$00,$00,$00,$00,$00,$00
0200: 00 00 03 0f+                 .bulk   $00,$00,$03,$0f,$1f,$1f,$1c,$24,$00,$00,$00,$00,$00,$00,$1f,$3f
0210: 00 04 e6 e0+                 .bulk   $00,$04,$e6,$e0,$ff,$ff,$8f,$83,$0e,$1f,$1f,$1f,$1f,$03,$ff,$ff
0220: 26 26 60 78+                 .bulk   $26,$26,$60,$78,$18,$0f,$7f,$ff,$3f,$3f,$7f,$7f,$1f,$00,$7e,$ff
0230: 01 21 fe 7a+                 .bulk   $01,$21,$fe,$7a,$06,$fe,$fc,$fc,$ff,$ff,$fe,$fe,$fe,$de,$5c,$6c
0240: ff cf 87 07+                 .bulk   $ff,$cf,$87,$07,$07,$0f,$1f,$1f,$ff,$ff,$fe,$fc,$f8,$b0,$60,$00
0250: f8 f8 f0 b8+                 .bulk   $f8,$f8,$f0,$b8,$f8,$f9,$fb,$ff,$28,$30,$18,$40,$00,$01,$03,$0f
0260: 1f ff ff ff+                 .bulk   $1f,$ff,$ff,$ff,$ff,$fe,$c0,$80,$10,$ec,$e3,$e0,$e0,$e0,$c0,$80
0270: ff ff ff 3f+                 .bulk   $ff,$ff,$ff,$3f,$00,$00,$00,$00,$0f,$0f,$0f,$0f,$00,$00,$00,$00
0280: 13 33 30 18+                 .bulk   $13,$33,$30,$18,$04,$0f,$1f,$1f,$1f,$3f,$3f,$1f,$07,$09,$13,$17
0290: 00 10 7e 30+                 .bulk   $00,$10,$7e,$30,$e0,$f0,$f0,$e0,$ff,$ff,$fe,$ff,$fe,$fc,$f8,$e0
02a0: 1f 1f 0f 0f+                 .bulk   $1f,$1f,$0f,$0f,$0f,$1f,$1f,$1f,$17,$17,$03,$00,$00,$00,$00,$00
02b0: f0 f0 f8 f8+                 .bulk   $f0,$f0,$f8,$f8,$b8,$f8,$f8,$f8,$d0,$90,$18,$08,$40,$00,$00,$00
02c0: 3f ff ff ff+                 .bulk   $3f,$ff,$ff,$ff,$f6,$c6,$84,$00,$30,$f0,$f0,$f1,$f6,$c6,$84,$00
02d0: f0 e0 80 00+                 .bulk   $f0,$e0,$80,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
02e0: 1f 1f 3f 3f+                 .bulk   $1f,$1f,$3f,$3f,$1f,$0f,$0f,$1f,$1f,$1f,$3f,$3e,$7c,$78,$f0,$e0
02f0: f0 f0 f8 f8+                 .bulk   $f0,$f0,$f8,$f8,$b8,$f8,$f8,$f0,$b0,$90,$18,$08,$40,$00,$00,$00
0300: e0 f0 f0 f0+                 .bulk   $e0,$f0,$f0,$f0,$f0,$f0,$f8,$f0,$c0,$e0,$fc,$fe,$ff,$7f,$03,$00
0310: 1f 1f 1f 3f+                 .bulk   $1f,$1f,$1f,$3f,$3e,$3c,$38,$18,$00,$00,$10,$38,$3e,$3c,$38,$18
0320: 00 03 07 07+                 .bulk   $00,$03,$07,$07,$0a,$0b,$0c,$00,$00,$00,$00,$07,$0f,$0f,$0f,$03
0330: 00 e0 fc 20+                 .bulk   $00,$e0,$fc,$20,$20,$10,$3c,$00,$00,$00,$00,$f0,$fc,$fe,$fc,$f8
0340: 07 07 07 1f+                 .bulk   $07,$07,$07,$1f,$1f,$3e,$21,$01,$07,$0f,$1b,$18,$10,$30,$21,$01
0350: e0 e0 e0 f0+                 .bulk   $e0,$e0,$e0,$f0,$f0,$e0,$c0,$e0,$a8,$fc,$f8,$00,$00,$00,$c0,$e0
0360: 07 0f 0e 14+                 .bulk   $07,$0f,$0e,$14,$16,$18,$00,$3f,$00,$00,$0f,$1f,$1f,$1f,$07,$3c
0370: c0 f8 40 40+                 .bulk   $c0,$f8,$40,$40,$20,$78,$00,$c0,$00,$00,$e0,$f8,$fc,$f8,$f0,$c0
0380: 3f 0e 0f 1f+                 .bulk   $3f,$0e,$0f,$1f,$3f,$7c,$70,$38,$fc,$ed,$c0,$00,$00,$60,$70,$38
0390: f0 f8 e4 fc+                 .bulk   $f0,$f8,$e4,$fc,$fc,$7c,$00,$00,$7e,$1e,$04,$0c,$0c,$0c,$00,$00
03a0: 07 0f 0e 14+                 .bulk   $07,$0f,$0e,$14,$16,$18,$00,$0f,$00,$00,$0f,$1f,$1f,$1f,$07,$0d
03b0: 1f 1f 1f 1c+                 .bulk   $1f,$1f,$1f,$1c,$0c,$07,$07,$07,$1e,$1c,$1e,$0f,$07,$00,$07,$07
03c0: e0 60 f0 70+                 .bulk   $e0,$60,$f0,$70,$e0,$e0,$f0,$80,$60,$90,$00,$80,$00,$e0,$f0,$80
03d0: 07 1f 3f 12+                 .bulk   $07,$1f,$3f,$12,$13,$08,$1f,$31,$00,$10,$3f,$7f,$7f,$3f,$03,$0f
03e0: c0 f0 40 00+                 .bulk   $c0,$f0,$40,$00,$30,$18,$c0,$f8,$00,$00,$e0,$f8,$fc,$f8,$b0,$38
03f0: 31 39 1f 1f+                 .bulk   $31,$39,$1f,$1f,$0f,$5f,$7e,$3c,$1f,$07,$00,$0e,$0f,$53,$7c,$3c
0400: f8 f8 f0 e0+                 .bulk   $f8,$f8,$f0,$e0,$e0,$c0,$00,$00,$f8,$f8,$f0,$00,$00,$80,$00,$00
0410: 00 e0 fc 27+                 .bulk   $00,$e0,$fc,$27,$27,$11,$3e,$04,$07,$07,$03,$f7,$ff,$ff,$fe,$fc
0420: 3f 7f 3f 0f+                 .bulk   $3f,$7f,$3f,$0f,$1f,$3f,$7f,$4f,$3e,$7f,$ff,$e2,$50,$38,$70,$40
0430: f8 f9 f9 b7+                 .bulk   $f8,$f9,$f9,$b7,$ff,$ff,$e0,$00,$e8,$71,$01,$4b,$03,$03,$00,$00
0440: 07 07 0f 3f+                 .bulk   $07,$07,$0f,$3f,$3f,$3f,$26,$04,$05,$03,$01,$30,$30,$30,$26,$04
0450: f0 f0 f0 e0+                 .bulk   $f0,$f0,$f0,$e0,$c0,$00,$00,$00,$fe,$fc,$e0,$00,$00,$00,$00,$00
0460: 07 07 0f 1f+                 .bulk   $07,$07,$0f,$1f,$3f,$0f,$1c,$18,$05,$03,$01,$10,$30,$0c,$1c,$18
0470: e0 e0 e0 e0+                 .bulk   $e0,$e0,$e0,$e0,$c0,$80,$00,$00,$c0,$e0,$f0,$78,$18,$08,$00,$00
0480: 07 0f 1f 0f+                 .bulk   $07,$0f,$1f,$0f,$3f,$0f,$1c,$18,$07,$0f,$3e,$7c,$30,$0c,$1c,$18
0490: e0 e0 e0 40+                 .bulk   $e0,$e0,$e0,$40,$c0,$80,$00,$00,$60,$60,$60,$80,$00,$00,$00,$00
04a0: 7f ff ff fb+                 .bulk   $7f,$ff,$ff,$fb,$0f,$0f,$0f,$1f,$73,$f3,$f0,$f4,$f0,$f0,$70,$60
04b0: 3f 7e 7c 7c+                 .bulk   $3f,$7e,$7c,$7c,$3c,$3c,$fc,$fc,$00,$00,$00,$00,$3c,$3c,$fc,$fc
04c0: 60 70 18 08+                 .bulk   $60,$70,$18,$08,$0f,$1f,$3f,$7f,$7f,$7f,$1f,$07,$0b,$1b,$3b,$7b
04d0: fc 7c 00 20+                 .bulk   $fc,$7c,$00,$20,$f0,$f8,$fc,$fe,$fc,$fc,$f8,$e0,$d0,$d8,$dc,$de
04e0: 0b 0f 1f 1e+                 .bulk   $0b,$0f,$1f,$1e,$3c,$3c,$3c,$7c,$c4,$e0,$e0,$40,$00,$3c,$3c,$7c
04f0: 1f 3f 0d 07+                 .bulk   $1f,$3f,$0d,$07,$0f,$0e,$1c,$3c,$1d,$3c,$3a,$38,$30,$00,$1c,$3c
0500: 00 00 00 00+                 .bulk   $00,$00,$00,$00,$00,$00,$00,$00,$22,$55,$55,$55,$55,$55,$77,$22
0510: 00 07 1f ff+                 .bulk   $00,$07,$1f,$ff,$07,$1f,$0f,$06,$00,$00,$00,$00,$00,$00,$00,$00
0520: 3f ff ff ff+                 .bulk   $3f,$ff,$ff,$ff,$ff,$ff,$fb,$76,$00,$00,$cf,$07,$7f,$00,$00,$00
0530: 20 f8 ff c3+                 .bulk   $20,$f8,$ff,$c3,$fd,$fe,$f0,$40,$00,$00,$3c,$fc,$fe,$e0,$00,$00
0540: 40 e0 40 40+                 .bulk   $40,$e0,$40,$40,$41,$41,$4f,$47,$40,$e0,$40,$3f,$3e,$3e,$30,$38
0550: 00 00 00 00+                 .bulk   $00,$00,$00,$00,$00,$00,$e0,$c0,$00,$00,$00,$f8,$f8,$f8,$18,$38
0560: 43 46 44 40+                 .bulk   $43,$46,$44,$40,$40,$40,$40,$40,$3c,$39,$3b,$3f,$00,$00,$00,$00
0570: 80 c0 40 00+                 .bulk   $80,$c0,$40,$00,$00,$00,$00,$00,$78,$38,$b8,$f8,$00,$00,$00,$00
0580: 31 30 38 7c+                 .bulk   $31,$30,$38,$7c,$7f,$ff,$ff,$fb,$3f,$3f,$0f,$77,$77,$f7,$f7,$f7
0590: 10 7e 3e 00+                 .bulk   $10,$7e,$3e,$00,$1e,$fe,$ff,$ff,$ff,$fe,$fe,$fe,$fa,$fa,$f3,$e7
05a0: ff ff e3 c3+                 .bulk   $ff,$ff,$e3,$c3,$87,$48,$3c,$fc,$f0,$f8,$fc,$7c,$78,$38,$3c,$fc
05b0: 00 ff c3 83+                 .bulk   $00,$ff,$c3,$83,$83,$ff,$ff,$ff,$ff,$00,$c3,$81,$81,$c3,$ff,$00
05c0: 1f 1f 0f 07+                 .bulk   $1f,$1f,$0f,$07,$01,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
05d0: f0 fb ff ff+                 .bulk   $f0,$fb,$ff,$ff,$fe,$3e,$0c,$04,$00,$0b,$1f,$1f,$1e,$3e,$0c,$04
05e0: 1f 1f 0f 0f+                 .bulk   $1f,$1f,$0f,$0f,$07,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
05f0: fb ff ff ff+                 .bulk   $fb,$ff,$ff,$ff,$ff,$00,$00,$00,$03,$0f,$0f,$0f,$0f,$00,$00,$00
0600: 00 18 3c 7e+                 .bulk   $00,$18,$3c,$7e,$6e,$df,$df,$df,$00,$18,$3c,$7e,$76,$fb,$fb,$fb
0610: 00 18 18 3c+                 .bulk   $00,$18,$18,$3c,$3c,$3c,$3c,$1c,$00,$10,$10,$20,$20,$20,$20,$20
0620: 00 08 08 08+                 .bulk   $00,$08,$08,$08,$08,$08,$08,$00,$00,$08,$08,$08,$08,$08,$08,$08
0630: 00 08 08 04+                 .bulk   $00,$08,$08,$04,$04,$04,$04,$04,$00,$10,$10,$38,$38,$38,$38,$38
0640: 3c 7e 77 fb+                 .bulk   $3c,$7e,$77,$fb,$9f,$5f,$8e,$20,$00,$18,$3c,$0e,$0e,$04,$00,$00
0650: 5c 2e 8f 3f+                 .bulk   $5c,$2e,$8f,$3f,$7b,$77,$7e,$3c,$00,$00,$04,$06,$1e,$3c,$18,$00
0660: 13 4f 3f bf+                 .bulk   $13,$4f,$3f,$bf,$3f,$7a,$f8,$f8,$00,$00,$01,$0a,$17,$0f,$2f,$1f
0670: 00 08 05 0f+                 .bulk   $00,$08,$05,$0f,$2f,$1d,$1c,$3c,$00,$00,$00,$00,$05,$07,$0f,$07
0680: 00 00 00 00+                 .bulk   $00,$00,$00,$00,$02,$0b,$07,$0f,$00,$00,$00,$00,$00,$00,$01,$03
0690: 00 00 00 00+                 .bulk   $00,$00,$00,$00,$00,$08,$04,$04,$00,$60,$f0,$f8,$7c,$3e,$7e,$7f
06a0: 02 02 02 05+                 .bulk   $02,$02,$02,$05,$71,$7f,$7f,$7f,$3f,$5f,$7f,$3e,$0e,$0a,$51,$20
06b0: 00 00 00 00+                 .bulk   $00,$00,$00,$00,$00,$00,$00,$04,$00,$00,$00,$00,$00,$00,$0e,$1f
06c0: 02 02 00 01+                 .bulk   $02,$02,$00,$01,$13,$3f,$7f,$7f,$3f,$7f,$7f,$fe,$ec,$ca,$51,$20
06d0: 00 40 60 70+                 .bulk   $00,$40,$60,$70,$73,$27,$0f,$1f,$00,$40,$63,$77,$7c,$38,$f8,$e4
06e0: 00 00 00 00+                 .bulk   $00,$00,$00,$00,$03,$07,$0f,$1f,$00,$00,$03,$07,$0c,$18,$f8,$e4
06f0: 7f 7f 3f 3f+                 .bulk   $7f,$7f,$3f,$3f,$1f,$1f,$0f,$07,$03,$44,$28,$10,$08,$04,$03,$04
0700: 03 07 0f 1f+                 .bulk   $03,$07,$0f,$1f,$3f,$77,$77,$f5,$03,$07,$0f,$1f,$27,$7b,$78,$fb
0710: c0 e0 f0 f8+                 .bulk   $c0,$e0,$f0,$f8,$fc,$ee,$ee,$af,$c0,$e0,$f0,$f8,$e4,$de,$1e,$df
0720: f1 ff 78 00+                 .bulk   $f1,$ff,$78,$00,$00,$18,$1c,$0e,$ff,$ff,$7f,$0f,$0f,$07,$03,$00
0730: 8f ff 1e 00+                 .bulk   $8f,$ff,$1e,$00,$0c,$3e,$7e,$7c,$ff,$ff,$fe,$f0,$f0,$c0,$80,$00
0740: 00 00 00 00+                 .bulk   $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$18,$24,$24,$18,$00,$00
0750: 00 02 41 41+                 .bulk   $00,$02,$41,$41,$61,$33,$06,$3c,$3c,$7e,$ff,$ff,$ff,$ff,$7e,$3c
0760: 03 07 0f 1f+                 .bulk   $03,$07,$0f,$1f,$3f,$7f,$7f,$ff,$03,$07,$0f,$1f,$3f,$63,$41,$c1
0770: c0 e0 f0 f8+                 .bulk   $c0,$e0,$f0,$f8,$fc,$fe,$fe,$ff,$c0,$80,$00,$00,$8c,$fe,$fe,$f3
0780: ff ff ff 78+                 .bulk   $ff,$ff,$ff,$78,$00,$00,$00,$00,$c1,$e3,$ff,$47,$0f,$0f,$0f,$07
0790: ff ff ff 1e+                 .bulk   $ff,$ff,$ff,$1e,$00,$20,$20,$40,$f1,$f9,$ff,$e2,$f0,$f0,$f0,$e0
07a0: 16 1f 3f 7f+                 .bulk   $16,$1f,$3f,$7f,$3d,$1d,$3f,$1f,$16,$1f,$00,$00,$05,$0d,$3f,$1f
07b0: 80 80 c0 e0+                 .bulk   $80,$80,$c0,$e0,$f0,$f0,$f0,$f8,$80,$80,$00,$00,$00,$a0,$a0,$e0
07c0: 3c fa b1 72+                 .bulk   $3c,$fa,$b1,$72,$f2,$db,$df,$5f,$00,$04,$4e,$8c,$0c,$7f,$ff,$ff
07d0: 00 00 00 01+                 .bulk   $00,$00,$00,$01,$01,$01,$06,$1e,$00,$00,$00,$00,$00,$00,$01,$01
07e0: 00 00 00 00+                 .bulk   $00,$00,$00,$00,$00,$00,$00,$00,$ff,$7f,$3f,$1f,$0f,$07,$03,$01
07f0: 00 7c d6 92+                 .bulk   $00,$7c,$d6,$92,$ba,$ee,$fe,$38,$ff,$83,$29,$6d,$45,$11,$01,$c7
0800: 00 15 3f 62+                 .bulk   $00,$15,$3f,$62,$5f,$ff,$9f,$7d,$08,$08,$02,$1f,$22,$02,$02,$00
0810: 00 00 00 00+                 .bulk   $00,$00,$00,$00,$00,$00,$00,$00,$08,$08,$08,$08,$08,$08,$08,$08
0820: 2f 1e 2f 2f+                 .bulk   $2f,$1e,$2f,$2f,$2f,$15,$0d,$0e,$10,$1e,$10,$50,$10,$08,$00,$00
0830: 00 00 00 00+                 .bulk   $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$fe,$00,$00,$00,$00
0840: 1c 3e 7f ff+                 .bulk   $1c,$3e,$7f,$ff,$ff,$fe,$7c,$38,$1c,$2a,$77,$ee,$dd,$aa,$74,$28
0850: 00 ff ff ff+                 .bulk   $00,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$fe,$fe,$00,$ef,$ef,$ef,$00
0860: ff ff ff ff+                 .bulk   $ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$fe,$fe,$fe,$00,$ef,$ef,$ef,$00
0870: 7f ff ff ff+                 .bulk   $7f,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$00,$7f,$5f,$7f,$7f,$7f,$7f,$7f
0880: 68 4e e0 e0+                 .bulk   $68,$4e,$e0,$e0,$e0,$f0,$f8,$fc,$b8,$9e,$80,$c0,$e0,$f0,$f8,$7c
0890: 3f 5c 39 3b+                 .bulk   $3f,$5c,$39,$3b,$bb,$f9,$fc,$fe,$00,$23,$57,$4f,$57,$27,$c3,$21
08a0: c0 f0 f0 f0+                 .bulk   $c0,$f0,$f0,$f0,$f0,$e0,$c0,$00,$00,$30,$70,$70,$f0,$e0,$c0,$00
08b0: fe fc 61 0f+                 .bulk   $fe,$fc,$61,$0f,$ff,$fe,$f0,$e0,$13,$0f,$1e,$f0,$fc,$f8,$f0,$e0
08c0: 6e 40 e0 e0+                 .bulk   $6e,$40,$e0,$e0,$e0,$e0,$e0,$c0,$be,$90,$80,$c0,$c0,$80,$00,$00
08d0: 01 01 03 03+                 .bulk   $01,$01,$03,$03,$07,$7f,$7f,$3f,$01,$01,$03,$03,$07,$7f,$7d,$3d
08e0: 06 07 3f 3c+                 .bulk   $06,$07,$3f,$3c,$19,$7b,$7f,$3f,$06,$04,$30,$23,$06,$64,$60,$00
08f0: 3f 7f 7f 1f+                 .bulk   $3f,$7f,$7f,$1f,$3f,$3f,$07,$06,$00,$60,$60,$00,$20,$30,$04,$06
0900: 03 07 0f 0f+                 .bulk   $03,$07,$0f,$0f,$0f,$0f,$07,$03,$00,$01,$01,$00,$00,$00,$00,$00
0910: f8 f8 f8 a0+                 .bulk   $f8,$f8,$f8,$a0,$e1,$ff,$ff,$ff,$fe,$ff,$ff,$40,$01,$03,$03,$03
0920: 0f 0f 0f 1f+                 .bulk   $0f,$0f,$0f,$1f,$1f,$1f,$0f,$07,$01,$01,$00,$00,$00,$00,$00,$00
0930: e0 f8 f8 f8+                 .bulk   $e0,$f8,$f8,$f8,$ff,$fe,$f0,$c0,$e0,$fe,$ff,$7f,$03,$02,$00,$00
0940: 01 0f 0f 1f+                 .bulk   $01,$0f,$0f,$1f,$39,$33,$37,$7f,$01,$0d,$08,$00,$36,$2c,$08,$60
0950: 7f 3f 3f 3f+                 .bulk   $7f,$3f,$3f,$3f,$1f,$0f,$0f,$01,$60,$00,$20,$30,$00,$08,$0d,$01
0960: 00 00 03 03+                 .bulk   $00,$00,$03,$03,$47,$67,$77,$77,$01,$01,$03,$43,$67,$77,$7b,$78
0970: 00 00 00 00+                 .bulk   $00,$00,$00,$00,$88,$98,$f8,$f0,$00,$00,$80,$84,$cc,$dc,$bc,$3c
0980: 7e 7f ff 1f+                 .bulk   $7e,$7f,$ff,$1f,$07,$30,$1c,$0c,$33,$07,$07,$e3,$38,$3f,$1c,$0c
0990: 7e 38 f6 ed+                 .bulk   $7e,$38,$f6,$ed,$df,$38,$70,$60,$98,$c7,$c8,$92,$30,$f8,$70,$60
09a0: 00 00 00 03+                 .bulk   $00,$00,$00,$03,$03,$47,$67,$77,$00,$01,$01,$03,$43,$67,$77,$7b
09b0: 00 00 00 00+                 .bulk   $00,$00,$00,$00,$00,$88,$98,$f8,$00,$00,$00,$80,$84,$cc,$dc,$bc
09c0: 77 7e 7f ff+                 .bulk   $77,$7e,$7f,$ff,$1f,$07,$70,$f0,$78,$33,$07,$07,$e3,$38,$7f,$f0
09d0: f0 7e 38 f6+                 .bulk   $f0,$7e,$38,$f6,$ed,$df,$38,$3c,$3c,$98,$c7,$c8,$92,$30,$f8,$3c
09e0: 03 07 0a 1a+                 .bulk   $03,$07,$0a,$1a,$1c,$1e,$0b,$08,$00,$10,$7f,$7f,$7f,$1f,$0f,$0f
09f0: 1c 3f 3f 3d+                 .bulk   $1c,$3f,$3f,$3d,$3f,$1f,$00,$00,$03,$33,$39,$3a,$38,$18,$00,$00
0a00: 00 00 04 4c+                 .bulk   $00,$00,$04,$4c,$4e,$4e,$46,$6f,$10,$38,$3c,$74,$76,$76,$7e,$7d
0a10: 00 1f 3f 3f+                 .bulk   $00,$1f,$3f,$3f,$4f,$5f,$7f,$7f,$00,$00,$11,$0a,$34,$2a,$51,$20
0a20: 7f 67 a3 b0+                 .bulk   $7f,$67,$a3,$b0,$d8,$de,$dc,$c8,$7f,$67,$63,$70,$38,$3e,$7c,$b8
0a30: 7f 7f 7f 1f+                 .bulk   $7f,$7f,$7f,$1f,$47,$70,$70,$39,$51,$0a,$04,$ea,$79,$7f,$70,$39
0a40: e8 e8 e0 c0+                 .bulk   $e8,$e8,$e0,$c0,$10,$70,$e0,$c0,$58,$38,$10,$30,$f0,$f0,$e0,$c0
0a50: 00 00 00 20+                 .bulk   $00,$00,$00,$20,$66,$66,$66,$62,$00,$08,$1c,$3c,$7a,$7a,$7a,$7e
0a60: 00 00 1f 3f+                 .bulk   $00,$00,$1f,$3f,$7f,$4f,$5f,$7f,$00,$00,$00,$11,$0a,$34,$2a,$51
0a70: 77 7f 3f b7+                 .bulk   $77,$7f,$3f,$b7,$b3,$db,$da,$d8,$7f,$7d,$3f,$37,$33,$3b,$3a,$78
0a80: 7f 7f 7f 7f+                 .bulk   $7f,$7f,$7f,$7f,$1f,$07,$70,$f0,$20,$51,$0a,$04,$ea,$39,$7f,$f0
0a90: cc e8 e8 e0+                 .bulk   $cc,$e8,$e8,$e0,$c0,$18,$7c,$3e,$bc,$58,$38,$10,$30,$f8,$fc,$3e
0aa0: 03 0f 1f 3f+                 .bulk   $03,$0f,$1f,$3f,$3b,$3f,$7f,$7f,$00,$00,$00,$06,$0e,$0c,$00,$00
0ab0: 80 f0 f8 fc+                 .bulk   $80,$f0,$f8,$fc,$fe,$fe,$ff,$fe,$00,$00,$00,$00,$00,$00,$0f,$18
0ac0: 7f 7f 7f 7f+                 .bulk   $7f,$7f,$7f,$7f,$ff,$0f,$03,$00,$00,$00,$00,$00,$f8,$3e,$3b,$18
0ad0: fe fb ff ff+                 .bulk   $fe,$fb,$ff,$ff,$f6,$e0,$c0,$00,$10,$14,$10,$10,$38,$78,$f8,$30
0ae0: 00 03 0f 1f+                 .bulk   $00,$03,$0f,$1f,$3f,$3b,$3f,$7f,$00,$00,$00,$00,$06,$0e,$0c,$00
0af0: 00 c0 f0 f8+                 .bulk   $00,$c0,$f0,$f8,$fc,$fe,$fe,$ff,$00,$00,$00,$00,$00,$00,$00,$0f
0b00: 7f 7f 7f 7f+                 .bulk   $7f,$7f,$7f,$7f,$7f,$ff,$0f,$03,$00,$00,$00,$00,$00,$f8,$7e,$f3
0b10: fe fe fb ff+                 .bulk   $fe,$fe,$fb,$ff,$ff,$f6,$e0,$c0,$18,$10,$14,$10,$10,$38,$7c,$de
0b20: 00 01 01 01+                 .bulk   $00,$01,$01,$01,$01,$00,$00,$08,$00,$0d,$1e,$1e,$1e,$1f,$0f,$07
0b30: 78 f0 f8 e4+                 .bulk   $78,$f0,$f8,$e4,$c0,$ca,$ca,$c0,$78,$f0,$00,$1a,$3f,$35,$35,$3f
0b40: 0f 1f 9f ff+                 .bulk   $0f,$1f,$9f,$ff,$ff,$7f,$74,$20,$00,$00,$80,$e0,$e0,$70,$73,$21
0b50: e4 ff fe fc+                 .bulk   $e4,$ff,$fe,$fc,$9c,$1e,$00,$00,$1a,$07,$0c,$18,$78,$fe,$fc,$f0
0b60: 00 01 03 03+                 .bulk   $00,$01,$03,$03,$07,$03,$01,$00,$00,$01,$02,$00,$38,$7c,$7e,$3f
0b70: 00 5f 7f 7f+                 .bulk   $00,$5f,$7f,$7f,$3f,$3f,$14,$00,$3f,$40,$60,$60,$20,$30,$13,$01
0b80: c0 e0 f0 30+                 .bulk   $c0,$e0,$f0,$30,$38,$3c,$3c,$fc,$c0,$e0,$30,$d0,$d0,$d0,$d0,$00
0b90: 07 0f 1f 22+                 .bulk   $07,$0f,$1f,$22,$20,$25,$25,$1f,$07,$0f,$02,$1d,$1f,$1a,$1a,$02
0ba0: fe fe 7e 3a+                 .bulk   $fe,$fe,$7e,$3a,$02,$01,$41,$41,$38,$7c,$fc,$fc,$fc,$fe,$be,$be
0bb0: 1f 3f 7e 5c+                 .bulk   $1f,$3f,$7e,$5c,$40,$80,$82,$82,$1c,$3e,$3f,$3f,$3f,$7f,$7d,$7d
0bc0: 82 80 a0 44+                 .bulk   $82,$80,$a0,$44,$43,$40,$21,$1e,$7d,$7f,$5f,$3b,$3c,$3f,$1e,$00
0bd0: 1c 3f 3e 3c+                 .bulk   $1c,$3f,$3e,$3c,$40,$80,$82,$82,$1c,$3e,$3f,$1f,$3f,$7f,$7d,$7d
0be0: 00 00 80 80+                 .bulk   $00,$00,$80,$80,$92,$9d,$c7,$ef,$00,$00,$00,$60,$62,$65,$3f,$1f
0bf0: 00 23 33 3f+                 .bulk   $00,$23,$33,$3f,$3f,$7f,$7f,$7f,$70,$3c,$3c,$18,$00,$00,$02,$07
0c00: fe f8 a0 00+                 .bulk   $fe,$f8,$a0,$00,$00,$00,$80,$80,$cf,$7a,$5a,$10,$00,$00,$c0,$80
0c10: 7e 7f 7d 3f+                 .bulk   $7e,$7f,$7d,$3f,$1e,$8f,$8f,$19,$85,$84,$86,$c6,$e7,$73,$73,$e1
0c20: e0 0e 73 f3+                 .bulk   $e0,$0e,$73,$f3,$f9,$f9,$f8,$70,$80,$4e,$77,$f3,$fb,$f9,$fa,$78
0c30: 0e 66 e2 f6+                 .bulk   $0e,$66,$e2,$f6,$ff,$ff,$1f,$98,$11,$39,$7d,$39,$00,$00,$e0,$e7
0c40: 00 00 00 04+                 .bulk   $00,$00,$00,$04,$0f,$0f,$1f,$07,$00,$00,$07,$07,$16,$10,$00,$38
0c50: f3 e7 ee ec+                 .bulk   $f3,$e7,$ee,$ec,$cd,$cf,$cf,$df,$cf,$1f,$17,$10,$33,$30,$30,$20
0c60: 27 3f 3f 78+                 .bulk   $27,$3f,$3f,$78,$3c,$1f,$1f,$73,$38,$30,$40,$c7,$07,$66,$e0,$6c
0c70: 9f 3e 7c fc+                 .bulk   $9f,$3e,$7c,$fc,$f8,$f8,$c0,$40,$60,$c0,$80,$04,$9e,$ff,$f0,$f8
0c80: 7f 7e 78 01+                 .bulk   $7f,$7e,$78,$01,$07,$1f,$3c,$7c,$24,$01,$07,$fe,$ff,$7f,$3f,$7f
0c90: fc f8 a0 fe+                 .bulk   $fc,$f8,$a0,$fe,$fc,$f0,$80,$00,$cf,$7a,$0a,$fe,$fc,$00,$00,$00
0ca0: 7e 7f 7f 3f+                 .bulk   $7e,$7f,$7f,$3f,$1f,$8f,$8f,$18,$85,$86,$83,$c3,$e1,$70,$70,$e0
0cb0: 9f 3e 7c f8+                 .bulk   $9f,$3e,$7c,$f8,$f8,$3c,$18,$f8,$60,$c0,$80,$00,$98,$fc,$fe,$ff
0cc0: 7f 7f 78 01+                 .bulk   $7f,$7f,$78,$01,$07,$13,$f1,$03,$24,$00,$07,$fe,$ff,$7f,$ff,$03
0cd0: 00 00 1c 1d+                 .bulk   $00,$00,$1c,$1d,$1b,$c3,$e3,$e1,$03,$0f,$23,$62,$64,$3c,$1c,$1e
0ce0: e0 cd 1d 4f+                 .bulk   $e0,$cd,$1d,$4f,$ee,$ff,$3f,$3f,$1f,$3d,$6d,$4f,$ee,$f3,$20,$03
0cf0: 3f 3f 00 00+                 .bulk   $3f,$3f,$00,$00,$70,$b8,$fc,$fc,$07,$07,$1f,$3f,$0f,$47,$03,$00
0d00: 07 0f 1f 3f+                 .bulk   $07,$0f,$1f,$3f,$3e,$7c,$78,$78,$00,$00,$03,$07,$0f,$0f,$1f,$1f
0d10: 3f 5c 39 3b+                 .bulk   $3f,$5c,$39,$3b,$bf,$ff,$fe,$fe,$00,$23,$57,$4f,$57,$2f,$df,$21
0d20: c0 c0 80 80+                 .bulk   $c0,$c0,$80,$80,$80,$80,$00,$00,$00,$00,$00,$00,$80,$80,$00,$00
0d30: fe fc 61 0f+                 .bulk   $fe,$fc,$61,$0f,$7f,$3f,$1f,$1e,$23,$0f,$1e,$f0,$1c,$3f,$1f,$1e
0d40: f0 78 e4 c8+                 .bulk   $f0,$78,$e4,$c8,$cc,$be,$be,$3e,$00,$80,$18,$30,$34,$fe,$fe,$fe
0d50: 00 01 00 07+                 .bulk   $00,$01,$00,$07,$07,$07,$07,$1f,$00,$00,$01,$04,$06,$06,$07,$07
0d60: 00 00 0f 3f+                 .bulk   $00,$00,$0f,$3f,$3f,$0f,$00,$00,$0f,$3f,$7f,$f8,$f8,$7f,$3f,$0f
0d70: 78 7c 7e 7f+                 .bulk   $78,$7c,$7e,$7f,$3f,$3f,$1b,$09,$1f,$1f,$1f,$0b,$01,$01,$00,$00
0d80: 0c 00 00 00+                 .bulk   $0c,$00,$00,$00,$07,$7f,$7c,$00,$03,$1f,$3f,$3f,$78,$00,$03,$ff
0d90: 01 e1 71 79+                 .bulk   $01,$e1,$71,$79,$3d,$3d,$1f,$03,$00,$00,$00,$00,$00,$00,$00,$00
0da0: 3f 3f 1f 1b+                 .bulk   $3f,$3f,$1f,$1b,$36,$30,$7f,$3f,$23,$27,$1f,$07,$0f,$1f,$7f,$3f
0db0: f8 f8 f8 b8+                 .bulk   $f8,$f8,$f8,$b8,$18,$d8,$d8,$b8,$e0,$80,$80,$40,$e0,$e0,$e0,$c0
0dc0: 01 02 04 04+                 .bulk   $01,$02,$04,$04,$08,$08,$10,$10,$03,$07,$0f,$1f,$3f,$7f,$ff,$1f
0dd0: 00 0f 13 0d+                 .bulk   $00,$0f,$13,$0d,$0d,$13,$0c,$20,$1f,$10,$0c,$12,$12,$2c,$3f,$3f
0de0: 00 24 00 24+                 .bulk   $00,$24,$00,$24,$00,$04,$00,$00,$37,$36,$36,$36,$16,$16,$12,$02
0df0: 0f 41 00 88+                 .bulk   $0f,$41,$00,$88,$00,$44,$00,$00,$10,$7e,$ff,$ff,$f6,$76,$3a,$1a
0e00: 38 7c fe fe+                 .bulk   $38,$7c,$fe,$fe,$3b,$03,$03,$03,$00,$00,$38,$04,$00,$00,$00,$00
0e10: 03 33 7b 7f+                 .bulk   $03,$33,$7b,$7f,$ff,$fb,$03,$03,$00,$00,$00,$38,$40,$00,$00,$00
0e20: dc c0 e0 e0+                 .bulk   $dc,$c0,$e0,$e0,$e0,$e0,$e0,$c0,$fc,$a0,$80,$80,$00,$00,$00,$00
0e30: 3f 5f 3f 3f+                 .bulk   $3f,$5f,$3f,$3f,$bb,$f8,$fe,$fe,$07,$27,$57,$4f,$57,$27,$c1,$21
0e40: 1f 0f 0f 1f+                 .bulk   $1f,$0f,$0f,$1f,$1f,$1e,$38,$30,$1d,$0f,$0f,$1f,$1f,$1e,$38,$30
0e50: 00 20 60 60+                 .bulk   $00,$20,$60,$60,$70,$f0,$f8,$f8,$00,$00,$38,$10,$4c,$18,$86,$24
0e60: f8 fc fc 7e+                 .bulk   $f8,$fc,$fc,$7e,$7e,$3e,$1f,$07,$00,$42,$0a,$40,$10,$02,$08,$02
0e70: 00 c0 70 b8+                 .bulk   $00,$c0,$70,$b8,$f4,$f2,$f5,$7b,$00,$00,$80,$40,$08,$0c,$0a,$84
0e80: 00 df 10 ff+                 .bulk   $00,$df,$10,$ff,$df,$ff,$ff,$f9,$00,$00,$cf,$20,$20,$20,$26,$2e
0e90: 1f 1f 3e fc+                 .bulk   $1f,$1f,$3e,$fc,$f8,$f0,$c0,$00,$e0,$e0,$c0,$00,$00,$00,$00,$00
0ea0: f8 fc fe ff+                 .bulk   $f8,$fc,$fe,$ff,$ff,$df,$df,$00,$2f,$23,$21,$20,$20,$00,$00,$00
0eb0: c1 f1 79 7d+                 .bulk   $c1,$f1,$79,$7d,$3d,$3f,$1f,$03,$c1,$b1,$59,$6d,$35,$3b,$1f,$03
0ec0: 02 06 0e 0e+                 .bulk   $02,$06,$0e,$0e,$1e,$1e,$3e,$3e,$00,$02,$00,$08,$02,$00,$28,$00
0ed0: 3e 3e 3e 3e+                 .bulk   $3e,$3e,$3e,$3e,$1e,$1e,$0e,$02,$04,$10,$02,$10,$04,$00,$0a,$00
0ee0: c1 f1 79 7d+                 .bulk   $c1,$f1,$79,$7d,$3d,$3f,$1f,$03,$c1,$b1,$59,$6d,$35,$3b,$1f,$03
0ef0: 7c 00 00 ff+                 .bulk   $7c,$00,$00,$ff,$c3,$7f,$1f,$03,$00,$0f,$1f,$ff,$fc,$63,$1f,$03
0f00: ff ff 7c 00+                 .bulk   $ff,$ff,$7c,$00,$00,$7c,$ff,$ff,$00,$00,$fe,$c6,$c6,$fe,$00,$00
0f10: ff ff 00 04+                 .bulk   $ff,$ff,$00,$04,$0c,$18,$30,$00,$00,$00,$06,$06,$0c,$18,$70,$60
0f20: ff ff 00 04+                 .bulk   $ff,$ff,$00,$04,$04,$04,$08,$08,$00,$00,$06,$06,$04,$04,$08,$08
0f30: 08 10 10 00+                 .bulk   $08,$10,$10,$00,$00,$10,$10,$08,$08,$10,$30,$30,$30,$30,$10,$08
0f40: 7f 3f 3f 3e+                 .bulk   $7f,$3f,$3f,$3e,$1f,$0f,$03,$00,$00,$00,$01,$03,$01,$00,$00,$00
0f50: 03 0f ff 7f+                 .bulk   $03,$0f,$ff,$7f,$7f,$7f,$7f,$7f,$03,$0e,$f8,$00,$00,$00,$00,$00
0f60: 00 00 00 00+                 .bulk   $00,$00,$00,$00,$00,$00,$00,$00,$22,$65,$25,$25,$25,$25,$77,$72
0f70: 00 00 00 00+                 .bulk   $00,$00,$00,$00,$00,$00,$00,$00,$62,$95,$15,$25,$45,$85,$f7,$f2
0f80: 00 00 00 00+                 .bulk   $00,$00,$00,$00,$00,$00,$00,$00,$a2,$a5,$a5,$a5,$f5,$f5,$27,$22
0f90: 00 00 00 00+                 .bulk   $00,$00,$00,$00,$00,$00,$00,$00,$f2,$85,$85,$e5,$15,$15,$f7,$e2
0fa0: 00 00 00 00+                 .bulk   $00,$00,$00,$00,$00,$00,$00,$00,$62,$95,$55,$65,$b5,$95,$97,$62
0fb0: 00 00 00 00+                 .bulk   $00,$00,$00,$00,$00,$00,$00,$00,$20,$50,$50,$50,$50,$50,$70,$20
0fc0: 00 00 00 00+                 .bulk   $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
0fd0: 00 00 00 00+                 .bulk   $00,$00,$00,$00,$00,$00,$00,$00,$66,$e6,$66,$66,$66,$67,$f3,$00
0fe0: 00 00 00 00+                 .bulk   $00,$00,$00,$00,$00,$00,$00,$00,$5e,$59,$59,$59,$5e,$d8,$98,$00
0ff0: 00 00 00 00+                 .bulk   $00,$00,$00,$00,$00,$7c,$38,$00,$00,$00,$00,$00,$00,$04,$08,$00
1000: 38 4c c6 c6+                 .bulk   $38,$4c,$c6,$c6,$c6,$64,$38,$00,$00,$00,$00,$00,$00,$00,$00,$00
1010: 18 38 18 18+                 .bulk   $18,$38,$18,$18,$18,$18,$7e,$00,$00,$00,$00,$00,$00,$00,$00,$00
1020: 7c c6 0e 3c+                 .bulk   $7c,$c6,$0e,$3c,$78,$e0,$fe,$00,$00,$00,$00,$00,$00,$00,$00,$00
1030: 7e 0c 18 3c+                 .bulk   $7e,$0c,$18,$3c,$06,$c6,$7c,$00,$00,$00,$00,$00,$00,$00,$00,$00
1040: 1c 3c 6c cc+                 .bulk   $1c,$3c,$6c,$cc,$fe,$0c,$0c,$00,$00,$00,$00,$00,$00,$00,$00,$00
1050: fc c0 fc 06+                 .bulk   $fc,$c0,$fc,$06,$06,$c6,$7c,$00,$00,$00,$00,$00,$00,$00,$00,$00
1060: 3c 60 c0 fc+                 .bulk   $3c,$60,$c0,$fc,$c6,$c6,$7c,$00,$00,$00,$00,$00,$00,$00,$00,$00
1070: fe c6 0c 18+                 .bulk   $fe,$c6,$0c,$18,$30,$30,$30,$00,$00,$00,$00,$00,$00,$00,$00,$00
1080: 7c c6 c6 7c+                 .bulk   $7c,$c6,$c6,$7c,$c6,$c6,$7c,$00,$00,$00,$00,$00,$00,$00,$00,$00
1090: 7c c6 c6 7e+                 .bulk   $7c,$c6,$c6,$7e,$06,$0c,$78,$00,$00,$00,$00,$00,$00,$00,$00,$00
10a0: 38 6c c6 c6+                 .bulk   $38,$6c,$c6,$c6,$fe,$c6,$c6,$00,$00,$00,$00,$00,$00,$00,$00,$00
10b0: fc c6 c6 fc+                 .bulk   $fc,$c6,$c6,$fc,$c6,$c6,$fc,$00,$00,$00,$00,$00,$00,$00,$00,$00
10c0: 3c 66 c0 c0+                 .bulk   $3c,$66,$c0,$c0,$c0,$66,$3c,$00,$00,$00,$00,$00,$00,$00,$00,$00
10d0: f8 cc c6 c6+                 .bulk   $f8,$cc,$c6,$c6,$c6,$cc,$f8,$00,$00,$00,$00,$00,$00,$00,$00,$00
10e0: fe c0 c0 fc+                 .bulk   $fe,$c0,$c0,$fc,$c0,$c0,$fe,$00,$00,$00,$00,$00,$00,$00,$00,$00
10f0: fe c0 c0 fc+                 .bulk   $fe,$c0,$c0,$fc,$c0,$c0,$c0,$00,$00,$00,$00,$00,$00,$00,$00,$00
1100: 3e 60 c0 ce+                 .bulk   $3e,$60,$c0,$ce,$c6,$66,$3e,$00,$00,$00,$00,$00,$00,$00,$00,$00
1110: c6 c6 c6 fe+                 .bulk   $c6,$c6,$c6,$fe,$c6,$c6,$c6,$00,$00,$00,$00,$00,$00,$00,$00,$00
1120: 7e 18 18 18+                 .bulk   $7e,$18,$18,$18,$18,$18,$7e,$00,$00,$00,$00,$00,$00,$00,$00,$00
1130: 1e 06 06 06+                 .bulk   $1e,$06,$06,$06,$c6,$c6,$7c,$00,$00,$00,$00,$00,$00,$00,$00,$00
1140: c6 cc d8 f0+                 .bulk   $c6,$cc,$d8,$f0,$f8,$dc,$ce,$00,$00,$00,$00,$00,$00,$00,$00,$00
1150: 60 60 60 60+                 .bulk   $60,$60,$60,$60,$60,$60,$7e,$00,$00,$00,$00,$00,$00,$00,$00,$00
1160: c6 ee fe fe+                 .bulk   $c6,$ee,$fe,$fe,$d6,$c6,$c6,$00,$00,$00,$00,$00,$00,$00,$00,$00
1170: c6 e6 f6 fe+                 .bulk   $c6,$e6,$f6,$fe,$de,$ce,$c6,$00,$00,$00,$00,$00,$00,$00,$00,$00
1180: 7c c6 c6 c6+                 .bulk   $7c,$c6,$c6,$c6,$c6,$c6,$7c,$00,$00,$00,$00,$00,$00,$00,$00,$00
1190: fc c6 c6 c6+                 .bulk   $fc,$c6,$c6,$c6,$fc,$c0,$c0,$00,$00,$00,$00,$00,$00,$00,$00,$00
11a0: 7c c6 c6 c6+                 .bulk   $7c,$c6,$c6,$c6,$de,$cc,$7a,$00,$00,$00,$00,$00,$00,$00,$00,$00
11b0: fc c6 c6 ce+                 .bulk   $fc,$c6,$c6,$ce,$f8,$dc,$ce,$00,$00,$00,$00,$00,$00,$00,$00,$00
11c0: 78 cc c0 7c+                 .bulk   $78,$cc,$c0,$7c,$06,$c6,$7c,$00,$00,$00,$00,$00,$00,$00,$00,$00
11d0: 7e 18 18 18+                 .bulk   $7e,$18,$18,$18,$18,$18,$18,$00,$00,$00,$00,$00,$00,$00,$00,$00
11e0: c6 c6 c6 c6+                 .bulk   $c6,$c6,$c6,$c6,$c6,$c6,$7c,$00,$00,$00,$00,$00,$00,$00,$00,$00
11f0: c6 c6 c6 ee+                 .bulk   $c6,$c6,$c6,$ee,$7c,$38,$10,$00,$00,$00,$00,$00,$00,$00,$00,$00
1200: c6 c6 d6 fe+                 .bulk   $c6,$c6,$d6,$fe,$fe,$ee,$c6,$00,$00,$00,$00,$00,$00,$00,$00,$00
1210: c6 ee 7c 38+                 .bulk   $c6,$ee,$7c,$38,$7c,$ee,$c6,$00,$00,$00,$00,$00,$00,$00,$00,$00
1220: 66 66 66 3c+                 .bulk   $66,$66,$66,$3c,$18,$18,$18,$00,$00,$00,$00,$00,$00,$00,$00,$00
1230: fe 0e 1c 38+                 .bulk   $fe,$0e,$1c,$38,$70,$e0,$fe,$00,$00,$00,$00,$00,$00,$00,$00,$00
1240: 00 00 00 00+                 .bulk   $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
1250: ff ff ff ff+                 .bulk   $ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$00,$00,$00,$00,$00,$00,$00,$00
1260: 00 00 00 00+                 .bulk   $00,$00,$00,$00,$00,$00,$00,$00,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff
1270: ff ff ff ff+                 .bulk   $ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff
1280: 00 00 00 7e+                 .bulk   $00,$00,$00,$7e,$7e,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
1290: 00 00 44 28+                 .bulk   $00,$00,$44,$28,$10,$28,$44,$00,$00,$00,$00,$00,$00,$00,$00,$00
12a0: ff ff ff ff+                 .bulk   $ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$7f,$7f,$7f,$7f,$7f,$7f,$7f,$7f
12b0: 18 3c 3c 3c+                 .bulk   $18,$3c,$3c,$3c,$18,$18,$00,$18,$00,$00,$00,$00,$00,$00,$00,$00
12c0: ff 7f 7f 7f+                 .bulk   $ff,$7f,$7f,$7f,$7f,$ff,$e3,$c1,$ff,$80,$80,$80,$80,$00,$1c,$3e
12d0: 80 80 80 c1+                 .bulk   $80,$80,$80,$c1,$e3,$ff,$ff,$ff,$7f,$7f,$7f,$3e,$1c,$00,$00,$ff
12e0: 38 7c 7c 7c+                 .bulk   $38,$7c,$7c,$7c,$7c,$7c,$38,$00,$08,$04,$04,$04,$04,$04,$08,$00
12f0: 03 06 0c 0c+                 .bulk   $03,$06,$0c,$0c,$08,$08,$04,$03,$03,$05,$0b,$0b,$0f,$0f,$07,$03
1300: 01 02 04 08+                 .bulk   $01,$02,$04,$08,$10,$20,$40,$80,$01,$03,$07,$0f,$1f,$3f,$7f,$ff
1310: 00 00 00 00+                 .bulk   $00,$00,$00,$00,$00,$07,$38,$c0,$00,$00,$00,$00,$00,$07,$3f,$ff
1320: 00 00 00 00+                 .bulk   $00,$00,$00,$00,$00,$e0,$1c,$03,$00,$00,$00,$00,$00,$e0,$fc,$ff
1330: 80 40 20 10+                 .bulk   $80,$40,$20,$10,$08,$04,$02,$01,$80,$c0,$e0,$f0,$f8,$fc,$fe,$ff
1340: 04 0e 0e 0e+                 .bulk   $04,$0e,$0e,$0e,$6e,$64,$60,$60,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff
1350: 07 0f 1f 1f+                 .bulk   $07,$0f,$1f,$1f,$7f,$ff,$ff,$7f,$07,$08,$10,$00,$60,$80,$80,$40
1360: 03 07 1f 3f+                 .bulk   $03,$07,$1f,$3f,$3f,$3f,$79,$f7,$03,$04,$18,$20,$20,$20,$46,$88
1370: c0 e0 f0 f4+                 .bulk   $c0,$e0,$f0,$f4,$fe,$bf,$df,$ff,$c0,$20,$10,$14,$0a,$41,$21,$01
1380: 90 b8 f8 fa+                 .bulk   $90,$b8,$f8,$fa,$ff,$ff,$ff,$fe,$90,$a8,$48,$0a,$05,$01,$01,$02
1390: 3b 1d 0e 0f+                 .bulk   $3b,$1d,$0e,$0f,$07,$00,$00,$00,$24,$12,$09,$08,$07,$00,$00,$00
13a0: ff bf 1c c0+                 .bulk   $ff,$bf,$1c,$c0,$f3,$ff,$7e,$1c,$00,$40,$e3,$3f,$0c,$81,$62,$1c
13b0: bf 7f 3d 83+                 .bulk   $bf,$7f,$3d,$83,$c7,$ff,$ff,$3c,$40,$80,$c2,$7c,$38,$00,$c3,$3c
13c0: fc fe ff fe+                 .bulk   $fc,$fe,$ff,$fe,$fe,$f8,$60,$00,$04,$02,$01,$00,$06,$98,$60,$00
13d0: c0 20 10 10+                 .bulk   $c0,$20,$10,$10,$10,$10,$20,$c0,$c0,$e0,$f0,$f0,$f0,$f0,$e0,$c0
13e0: 00 00 00 00+                 .bulk   $00,$00,$00,$00,$3f,$7f,$e0,$c0,$00,$00,$00,$00,$00,$00,$1c,$3e
13f0: 88 9c 88 80+                 .bulk   $88,$9c,$88,$80,$80,$80,$80,$80,$7f,$7f,$7f,$3e,$1c,$00,$00,$00
1400: fe fe fe fe+                 .bulk   $fe,$fe,$fe,$fe,$fe,$fe,$fe,$fe,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff
1410: 08 14 24 c4+                 .bulk   $08,$14,$24,$c4,$03,$40,$a1,$26,$00,$08,$18,$38,$fc,$bf,$5e,$d9
1420: ff ff ff ff+                 .bulk   $ff,$ff,$ff,$ff,$7f,$7f,$7f,$7f,$81,$81,$81,$81,$81,$81,$81,$81
1430: ff ff ff ff+                 .bulk   $ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$01,$01,$01,$01,$01,$01,$01,$01
1440: 7f 80 80 98+                 .bulk   $7f,$80,$80,$98,$9c,$8c,$80,$80,$00,$7f,$7f,$67,$67,$7f,$7f,$7f
1450: ff 01 01 ff+                 .bulk   $ff,$01,$01,$ff,$10,$10,$10,$ff,$00,$ff,$ff,$ff,$ff,$ff,$ff,$ff
1460: 80 80 80 80+                 .bulk   $80,$80,$80,$80,$80,$80,$80,$80,$7f,$7f,$7f,$7f,$7f,$7f,$7f,$7f
1470: 01 01 01 ff+                 .bulk   $01,$01,$01,$ff,$10,$10,$10,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff
1480: ff 00 00 00+                 .bulk   $ff,$00,$00,$00,$00,$00,$00,$00,$00,$ff,$ff,$ff,$ff,$ff,$ff,$ff
1490: fe 01 01 19+                 .bulk   $fe,$01,$01,$19,$1d,$0d,$01,$01,$00,$ff,$ff,$e7,$e7,$ff,$ff,$ff
14a0: 01 01 01 01+                 .bulk   $01,$01,$01,$01,$01,$01,$01,$01,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff
14b0: 3f 7f 7f ff+                 .bulk   $3f,$7f,$7f,$ff,$ff,$ff,$ff,$ff,$3f,$60,$40,$c0,$80,$80,$80,$80
14c0: ff ff ff ff+                 .bulk   $ff,$ff,$ff,$ff,$ff,$ff,$7e,$3c,$80,$80,$80,$80,$80,$81,$42,$3c
14d0: ff ff ff ff+                 .bulk   $ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$00,$00,$00,$00,$00,$00,$00
14e0: ff ff ff ff+                 .bulk   $ff,$ff,$ff,$ff,$ff,$ff,$fe,$7c,$00,$00,$00,$00,$00,$01,$82,$7c
14f0: ff ff ff ff+                 .bulk   $ff,$ff,$ff,$ff,$ff,$ff,$fe,$7c,$00,$00,$00,$00,$00,$01,$83,$ff
1500: f8 fc fe fe+                 .bulk   $f8,$fc,$fe,$fe,$ff,$ff,$ff,$ff,$f8,$04,$02,$02,$01,$01,$01,$01
1510: ff ff ff ff+                 .bulk   $ff,$ff,$ff,$ff,$ff,$ff,$7e,$3c,$01,$01,$01,$01,$01,$81,$42,$3c
1520: 00 08 08 08+                 .bulk   $00,$08,$08,$08,$10,$10,$10,$00,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff
1530: 00 7f 7f 78+                 .bulk   $00,$7f,$7f,$78,$73,$73,$73,$7f,$7f,$80,$a0,$87,$8f,$8e,$8e,$86
1540: 00 ff ff 3f+                 .bulk   $00,$ff,$ff,$3f,$9f,$9f,$9f,$1f,$fe,$01,$05,$c1,$e1,$71,$71,$f1
1550: 7e 7e 7f 7e+                 .bulk   $7e,$7e,$7f,$7e,$7e,$7f,$7f,$ff,$81,$81,$80,$81,$81,$a0,$80,$ff
1560: 7f 7f ff 7f+                 .bulk   $7f,$7f,$ff,$7f,$7f,$ff,$ff,$ff,$f1,$c1,$c1,$81,$c1,$c5,$01,$ff
1570: 7f 80 a0 80+                 .bulk   $7f,$80,$a0,$80,$80,$80,$80,$80,$7f,$ff,$ff,$ff,$ff,$ff,$ff,$ff
1580: fe 01 05 01+                 .bulk   $fe,$01,$05,$01,$01,$01,$01,$01,$fe,$ff,$ff,$ff,$ff,$ff,$ff,$ff
1590: 80 80 80 80+                 .bulk   $80,$80,$80,$80,$80,$a0,$80,$7f,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$7f
15a0: 01 01 01 01+                 .bulk   $01,$01,$01,$01,$01,$05,$01,$fe,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$fe
15b0: 00 00 00 00+                 .bulk   $00,$00,$00,$00,$fc,$fe,$07,$03,$00,$00,$00,$00,$00,$00,$38,$7c
15c0: 11 39 11 01+                 .bulk   $11,$39,$11,$01,$01,$01,$01,$01,$fe,$fe,$fe,$7c,$38,$00,$00,$00
15d0: ef 28 28 28+                 .bulk   $ef,$28,$28,$28,$28,$28,$ef,$00,$20,$e7,$e7,$e7,$e7,$e7,$ef,$00
15e0: fe 82 82 82+                 .bulk   $fe,$82,$82,$82,$82,$82,$fe,$00,$02,$7e,$7e,$7e,$7e,$7e,$fe,$00
15f0: 80 80 80 98+                 .bulk   $80,$80,$80,$98,$9c,$8c,$80,$7f,$7f,$7f,$7f,$67,$67,$7f,$7f,$7f
1600: ff ff 83 f3+                 .bulk   $ff,$ff,$83,$f3,$f3,$f3,$f3,$f3,$ff,$80,$fc,$8c,$8c,$8c,$8c,$8c
1610: ff ff f0 f6+                 .bulk   $ff,$ff,$f0,$f6,$f6,$f6,$f6,$f6,$ff,$00,$0f,$09,$09,$09,$09,$09
1620: ff ff 00 00+                 .bulk   $ff,$ff,$00,$00,$00,$00,$00,$00,$ff,$00,$ff,$ff,$ff,$ff,$ff,$ff
1630: ff ff 01 57+                 .bulk   $ff,$ff,$01,$57,$2f,$57,$2f,$57,$ff,$01,$ff,$a9,$d1,$a9,$d1,$a9
1640: f3 f3 f3 f3+                 .bulk   $f3,$f3,$f3,$f3,$f3,$f3,$ff,$3f,$8c,$8c,$8c,$8c,$8c,$8c,$ff,$3f
1650: f6 f6 f6 f6+                 .bulk   $f6,$f6,$f6,$f6,$f6,$f6,$ff,$ff,$09,$09,$09,$09,$09,$09,$ff,$ff
1660: 00 00 00 00+                 .bulk   $00,$00,$00,$00,$00,$00,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff
1670: 2f 57 2f 57+                 .bulk   $2f,$57,$2f,$57,$2f,$57,$ff,$fc,$d1,$a9,$d1,$a9,$d1,$a9,$ff,$fc
1680: 3c 3c 3c 3c+                 .bulk   $3c,$3c,$3c,$3c,$3c,$3c,$3c,$3c,$23,$23,$23,$23,$23,$23,$23,$23
1690: fb fb fb fb+                 .bulk   $fb,$fb,$fb,$fb,$fb,$fb,$fb,$fb,$04,$04,$04,$04,$04,$04,$04,$04
16a0: bc 5c bc 5c+                 .bulk   $bc,$5c,$bc,$5c,$bc,$5c,$bc,$5c,$44,$a4,$44,$a4,$44,$a4,$44,$a4
16b0: 1f 20 40 40+                 .bulk   $1f,$20,$40,$40,$80,$80,$80,$81,$1f,$3f,$7f,$7f,$ff,$ff,$ff,$fe
16c0: ff 80 80 c0+                 .bulk   $ff,$80,$80,$c0,$ff,$ff,$fe,$fe,$ff,$7f,$7f,$3f,$00,$00,$01,$01
16d0: ff 7f 7f ff+                 .bulk   $ff,$7f,$7f,$ff,$ff,$07,$03,$03,$ff,$80,$80,$00,$00,$f8,$fc,$fc
16e0: ff 00 00 00+                 .bulk   $ff,$00,$00,$00,$00,$81,$c3,$ff,$ff,$ff,$ff,$ff,$ff,$7e,$3c,$00
16f0: f8 fc fe fe+                 .bulk   $f8,$fc,$fe,$fe,$e3,$c1,$81,$81,$f8,$04,$02,$02,$1d,$3f,$7f,$7f
1700: 83 ff ff ff+                 .bulk   $83,$ff,$ff,$ff,$ff,$ff,$7f,$1f,$fc,$80,$80,$80,$80,$80,$60,$1f
1710: fc fc fc fc+                 .bulk   $fc,$fc,$fc,$fc,$fe,$fe,$ff,$ff,$03,$03,$03,$03,$01,$01,$00,$ff
1720: 01 01 01 01+                 .bulk   $01,$01,$01,$01,$03,$03,$07,$ff,$fe,$fe,$fe,$fe,$fc,$fc,$f8,$ff
1730: ff ff ff ff+                 .bulk   $ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$00,$00,$00,$00,$00,$00,$00,$ff
1740: 81 c1 e3 ff+                 .bulk   $81,$c1,$e3,$ff,$ff,$ff,$ff,$fe,$7f,$3f,$1d,$01,$01,$01,$03,$fe
1750: ff ff ff ff+                 .bulk   $ff,$ff,$ff,$ff,$ff,$fb,$b5,$ce,$80,$80,$80,$80,$80,$84,$ca,$b1
1760: ff ff ff ff+                 .bulk   $ff,$ff,$ff,$ff,$ff,$df,$ad,$73,$01,$01,$01,$01,$01,$21,$53,$8d
1770: 77 77 77 77+                 .bulk   $77,$77,$77,$77,$77,$77,$77,$77,$00,$00,$00,$00,$77,$ff,$ff,$ff
1780: 00 00 00 00+                 .bulk   $00,$00,$00,$00,$00,$00,$00,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff
1790: 77 77 77 77+                 .bulk   $77,$77,$77,$77,$00,$00,$00,$00,$ff,$ff,$ff,$77,$77,$77,$77,$77
17a0: 01 01 01 19+                 .bulk   $01,$01,$01,$19,$1d,$0d,$01,$fe,$ff,$ff,$ff,$e7,$e7,$ff,$ff,$fe
17b0: 20 78 7f fe+                 .bulk   $20,$78,$7f,$fe,$fe,$fe,$fe,$fe,$00,$21,$21,$41,$41,$41,$41,$41
17c0: 04 9a fa fd+                 .bulk   $04,$9a,$fa,$fd,$fd,$fd,$fd,$fd,$00,$80,$80,$80,$80,$80,$80,$80
17d0: 7e 38 21 00+                 .bulk   $7e,$38,$21,$00,$01,$00,$01,$00,$21,$21,$01,$01,$01,$01,$01,$01
17e0: fa 8a 84 80+                 .bulk   $fa,$8a,$84,$80,$80,$80,$80,$80,$80,$80,$80,$80,$80,$80,$80,$80
17f0: 02 04 00 10+                 .bulk   $02,$04,$00,$10,$00,$40,$80,$00,$01,$01,$06,$08,$18,$20,$20,$c0
1800: 0b 0b 3b 0b+                 .bulk   $0b,$0b,$3b,$0b,$fb,$0b,$0b,$0a,$04,$04,$c4,$f4,$f4,$04,$04,$05
1810: 90 10 1f 10+                 .bulk   $90,$10,$1f,$10,$1f,$10,$10,$90,$70,$f0,$f0,$ff,$ff,$f0,$f0,$70
1820: 3f 78 e7 cf+                 .bulk   $3f,$78,$e7,$cf,$58,$58,$50,$90,$c0,$87,$18,$b0,$e7,$e7,$ef,$ef
1830: b0 fc e2 c1+                 .bulk   $b0,$fc,$e2,$c1,$c1,$83,$8f,$7e,$6f,$43,$5d,$3f,$3f,$7f,$7f,$ff
1840: fe 03 0f 91+                 .bulk   $fe,$03,$0f,$91,$70,$60,$20,$31,$03,$ff,$f1,$6e,$cf,$df,$ff,$ff
1850: 3f 3f 1d 39+                 .bulk   $3f,$3f,$1d,$39,$7b,$f3,$86,$fe,$fd,$fb,$fb,$f7,$f7,$0f,$7f,$ff
1860: ff ff ff ff+                 .bulk   $ff,$ff,$ff,$ff,$ff,$80,$80,$ff,$ff,$80,$80,$80,$80,$ff,$ff,$80
1870: fe ff ff ff+                 .bulk   $fe,$ff,$ff,$ff,$ff,$03,$03,$ff,$fe,$03,$03,$03,$03,$ff,$ff,$03
1880: 00 ff ff ff+                 .bulk   $00,$ff,$ff,$ff,$ff,$ff,$00,$00,$00,$ff,$00,$00,$00,$00,$ff,$ff
1890: 3c fc fc fc+                 .bulk   $3c,$fc,$fc,$fc,$fc,$fc,$04,$04,$23,$f3,$0b,$0b,$0b,$07,$ff,$ff
18a0: ff ff ff ff+                 .bulk   $ff,$ff,$ff,$ff,$80,$ff,$ff,$ff,$80,$80,$80,$80,$ff,$80,$80,$80
18b0: ff ff ff ff+                 .bulk   $ff,$ff,$ff,$ff,$03,$ff,$ff,$ff,$03,$03,$03,$03,$ff,$03,$03,$03
18c0: ff ff ff ff+                 .bulk   $ff,$ff,$ff,$ff,$ff,$00,$ff,$ff,$00,$00,$00,$00,$00,$ff,$00,$00
18d0: fc fc fe fe+                 .bulk   $fc,$fc,$fe,$fe,$fe,$02,$fe,$fe,$07,$07,$03,$03,$03,$ff,$03,$03
18e0: ff 80 80 80+                 .bulk   $ff,$80,$80,$80,$80,$80,$80,$80,$80,$ff,$ff,$ff,$ff,$ff,$ff,$ff
18f0: ff 03 03 03+                 .bulk   $ff,$03,$03,$03,$03,$03,$03,$03,$03,$ff,$ff,$ff,$ff,$ff,$ff,$ff
1900: 02 02 02 02+                 .bulk   $02,$02,$02,$02,$02,$02,$04,$04,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff
1910: 80 80 aa d5+                 .bulk   $80,$80,$aa,$d5,$aa,$ff,$ff,$ff,$ff,$ff,$d5,$aa,$d5,$80,$80,$ff
1920: 03 03 ab 57+                 .bulk   $03,$03,$ab,$57,$ab,$ff,$ff,$fe,$ff,$ff,$57,$ab,$57,$03,$03,$fe
1930: 00 55 aa 55+                 .bulk   $00,$55,$aa,$55,$ff,$ff,$ff,$00,$ff,$aa,$55,$aa,$00,$00,$ff,$00
1940: 04 54 ac 5c+                 .bulk   $04,$54,$ac,$5c,$fc,$fc,$fc,$3c,$ff,$af,$57,$ab,$0b,$0b,$f3,$23
1950: 3f 3f 3f 3f+                 .bulk   $3f,$3f,$3f,$3f,$00,$00,$00,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff
1960: 7e 7c 7c 78+                 .bulk   $7e,$7c,$7c,$78,$00,$00,$00,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff
1970: 1f 0f 0f 07+                 .bulk   $1f,$0f,$0f,$07,$00,$00,$00,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff
1980: fe fc fc f8+                 .bulk   $fe,$fc,$fc,$f8,$00,$00,$00,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff
1990: 00 00 00 00+                 .bulk   $00,$00,$00,$00,$ff,$ff,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
19a0: 18 18 18 18+                 .bulk   $18,$18,$18,$18,$18,$18,$18,$18,$00,$00,$00,$00,$00,$00,$00,$00
19b0: 07 1f 3f ff+                 .bulk   $07,$1f,$3f,$ff,$7f,$7f,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff
19c0: e1 f9 fd ff+                 .bulk   $e1,$f9,$fd,$ff,$fe,$fe,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff
19d0: f0 10 10 10+                 .bulk   $f0,$10,$10,$10,$10,$10,$10,$ff,$00,$e0,$e0,$e0,$e0,$e0,$e0,$e0
19e0: 1f 10 10 10+                 .bulk   $1f,$10,$10,$10,$10,$10,$10,$ff,$00,$0f,$0f,$0f,$0f,$0f,$0f,$0f
19f0: 92 92 92 fe+                 .bulk   $92,$92,$92,$fe,$fe,$00,$00,$00,$48,$48,$6c,$00,$00,$00,$fe,$00
1a00: 0a 0a 3a 0a+                 .bulk   $0a,$0a,$3a,$0a,$fb,$0b,$0b,$0b,$05,$05,$c5,$f5,$f4,$04,$04,$04
1a10: 90 90 9f 90+                 .bulk   $90,$90,$9f,$90,$9f,$90,$90,$90,$70,$70,$70,$7f,$7f,$70,$70,$70
1a20: 01 01 01 01+                 .bulk   $01,$01,$01,$01,$01,$01,$01,$01,$00,$00,$00,$00,$00,$00,$00,$00
1a30: 80 80 80 80+                 .bulk   $80,$80,$80,$80,$80,$80,$80,$80,$00,$00,$00,$00,$00,$00,$00,$00
1a40: 08 88 91 d1+                 .bulk   $08,$88,$91,$d1,$53,$53,$73,$3f,$ff,$ff,$ff,$ff,$ff,$fe,$be,$ce
1a50: 00 00 07 0f+                 .bulk   $00,$00,$07,$0f,$0c,$1b,$1b,$1b,$00,$00,$00,$00,$03,$04,$04,$04
1a60: 00 00 e0 f0+                 .bulk   $00,$00,$e0,$f0,$f0,$f8,$f8,$f8,$00,$00,$60,$30,$30,$98,$98,$98
1a70: 1b 1b 1b 1b+                 .bulk   $1b,$1b,$1b,$1b,$1b,$0f,$0f,$07,$04,$04,$04,$04,$04,$03,$00,$00
1a80: f8 f8 f8 f8+                 .bulk   $f8,$f8,$f8,$f8,$f8,$f0,$f0,$e0,$98,$98,$98,$98,$98,$30,$30,$60
1a90: f1 11 11 1f+                 .bulk   $f1,$11,$11,$1f,$10,$10,$10,$ff,$0f,$ef,$ef,$ef,$ef,$ef,$ef,$e0
1aa0: 1f 10 10 f0+                 .bulk   $1f,$10,$10,$f0,$10,$10,$10,$ff,$e0,$ef,$ef,$ef,$ef,$ef,$ef,$0f
1ab0: 7f bf df ef+                 .bulk   $7f,$bf,$df,$ef,$f0,$f0,$f0,$f0,$80,$40,$20,$10,$0f,$0f,$0f,$0f
1ac0: f0 f0 f0 f0+                 .bulk   $f0,$f0,$f0,$f0,$ff,$ff,$ff,$ff,$0f,$0f,$0f,$0f,$1f,$3f,$7f,$ff
1ad0: ff ff ff ff+                 .bulk   $ff,$ff,$ff,$ff,$0f,$0f,$0f,$0f,$01,$03,$07,$0f,$ff,$ff,$ff,$ff
1ae0: 0f 0f 0f 0f+                 .bulk   $0f,$0f,$0f,$0f,$f7,$fb,$fd,$fe,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff
1af0: 00 00 00 00+                 .bulk   $00,$00,$00,$00,$00,$00,$18,$18,$00,$00,$00,$00,$00,$00,$00,$00
1b00: 1f 3f 7f 7f+                 .bulk   $1f,$3f,$7f,$7f,$7f,$ff,$ff,$ff,$1f,$20,$40,$40,$40,$80,$82,$82
1b10: ff ff ff 7f+                 .bulk   $ff,$ff,$ff,$7f,$7f,$7f,$3f,$1e,$82,$80,$a0,$44,$43,$40,$21,$1e
1b20: f8 fc fe fe+                 .bulk   $f8,$fc,$fe,$fe,$fe,$ff,$ff,$ff,$f8,$04,$02,$02,$02,$01,$41,$41
1b30: ff ff ff fe+                 .bulk   $ff,$ff,$ff,$fe,$fe,$fe,$fc,$78,$41,$01,$05,$22,$c2,$02,$84,$78
1b40: 7f 80 80 80+                 .bulk   $7f,$80,$80,$80,$80,$80,$80,$80,$80,$7f,$7f,$7f,$7f,$7f,$7f,$7f
1b50: de 61 61 61+                 .bulk   $de,$61,$61,$61,$71,$5e,$7f,$61,$61,$df,$df,$df,$df,$ff,$c1,$df
1b60: 80 80 c0 f0+                 .bulk   $80,$80,$c0,$f0,$bf,$8f,$81,$7e,$7f,$7f,$ff,$3f,$4f,$71,$7f,$ff
1b70: 61 61 c1 c1+                 .bulk   $61,$61,$c1,$c1,$81,$81,$83,$fe,$df,$df,$bf,$bf,$7f,$7f,$7f,$7f
1b80: 00 00 03 0f+                 .bulk   $00,$00,$03,$0f,$1f,$3f,$7f,$7f,$00,$00,$03,$0c,$10,$20,$40,$40
1b90: 00 00 c0 f0+                 .bulk   $00,$00,$c0,$f0,$f8,$fc,$fe,$fe,$00,$00,$c0,$30,$08,$04,$02,$02
1ba0: ff ff ff ff+                 .bulk   $ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$80,$80,$80,$80,$80,$80,$80,$80
1bb0: ff ff ff ff+                 .bulk   $ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$01,$01,$01,$01,$01,$01,$01,$01
1bc0: 7f 7f 7f 3f+                 .bulk   $7f,$7f,$7f,$3f,$3f,$1f,$0f,$07,$40,$40,$40,$20,$30,$1c,$0f,$07
1bd0: fe fe fe fc+                 .bulk   $fe,$fe,$fe,$fc,$fc,$f8,$f0,$f0,$02,$02,$02,$04,$0c,$38,$f0,$f0
1be0: 0f 0f 0f 0f+                 .bulk   $0f,$0f,$0f,$0f,$0f,$0f,$07,$0f,$08,$08,$08,$08,$08,$0c,$05,$0a
1bf0: f0 f0 f0 f0+                 .bulk   $f0,$f0,$f0,$f0,$f0,$f0,$e0,$f0,$10,$50,$50,$50,$50,$30,$a0,$50
1c00: 81 c1 a3 a3+                 .bulk   $81,$c1,$a3,$a3,$9d,$81,$81,$81,$00,$41,$22,$22,$1c,$00,$00,$00
1c10: e3 f7 c1 c1+                 .bulk   $e3,$f7,$c1,$c1,$c1,$c1,$f7,$e3,$e3,$14,$3e,$3e,$3e,$3e,$14,$e3
1c20: 00 00 07 0f+                 .bulk   $00,$00,$07,$0f,$0c,$1b,$1b,$1b,$ff,$ff,$f8,$f0,$f0,$e0,$e0,$e0
1c30: 00 00 e0 f0+                 .bulk   $00,$00,$e0,$f0,$f0,$f8,$f8,$f8,$ff,$ff,$7f,$3f,$3f,$9f,$9f,$9f
1c40: 1b 1b 1b 1b+                 .bulk   $1b,$1b,$1b,$1b,$1b,$0f,$0f,$07,$e0,$e0,$e0,$e0,$e0,$f3,$f0,$f8
1c50: f8 f8 f8 f8+                 .bulk   $f8,$f8,$f8,$f8,$f8,$f0,$f0,$e0,$9f,$9f,$9f,$9f,$9f,$3f,$3f,$7f
1c60: e0 ff ff ff+                 .bulk   $e0,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$00,$70,$1f,$10,$70,$7f,$7f,$7f
1c70: 07 ff ff ff+                 .bulk   $07,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$00,$03,$f8,$00,$03,$fb,$fb,$fb
1c80: ff ff ff ff+                 .bulk   $ff,$ff,$ff,$ff,$ff,$fe,$ff,$ef,$7c,$7b,$76,$75,$75,$77,$17,$67
1c90: ff df ef af+                 .bulk   $ff,$df,$ef,$af,$af,$6f,$ef,$e7,$3b,$fb,$7b,$fb,$fb,$f3,$f8,$f3
1ca0: 1f 1f 3f 3f+                 .bulk   $1f,$1f,$3f,$3f,$70,$63,$e7,$e5,$0f,$0f,$1f,$1f,$3f,$3c,$78,$7a
1cb0: f0 f0 f8 f8+                 .bulk   $f0,$f0,$f8,$f8,$0c,$c4,$e4,$a6,$f8,$f8,$fc,$fc,$fe,$3e,$1e,$5f
1cc0: e9 e9 e9 ef+                 .bulk   $e9,$e9,$e9,$ef,$e2,$e3,$f0,$ff,$76,$76,$76,$70,$7d,$7c,$7f,$7f
1cd0: 96 96 96 f6+                 .bulk   $96,$96,$96,$f6,$46,$c6,$0e,$fe,$6f,$6f,$6f,$0f,$bf,$3f,$ff,$ff
1ce0: 00 00 00 00+                 .bulk   $00,$00,$00,$00,$00,$00,$7e,$3c,$3c,$7e,$7e,$ff,$ff,$ff,$42,$00
1cf0: 3c 42 99 a1+                 .bulk   $3c,$42,$99,$a1,$a1,$99,$42,$3c,$00,$00,$00,$00,$00,$00,$00,$00
1d00: 0f 1f 1f 3f+                 .bulk   $0f,$1f,$1f,$3f,$3f,$7f,$7f,$7f,$f0,$e0,$e0,$c0,$c0,$80,$80,$80
1d10: f0 f8 f8 fc+                 .bulk   $f0,$f8,$f8,$fc,$fc,$fe,$fe,$fe,$0f,$07,$07,$03,$03,$01,$01,$01
1d20: 7f 7f 3f 3f+                 .bulk   $7f,$7f,$3f,$3f,$3f,$3f,$1f,$1f,$80,$80,$c0,$c0,$e0,$f8,$fe,$ff
1d30: fe ff ff ff+                 .bulk   $fe,$ff,$ff,$ff,$fc,$fc,$fe,$fe,$ff,$7f,$1f,$07,$03,$03,$01,$81
1d40: 7f 7f 7f 3f+                 .bulk   $7f,$7f,$7f,$3f,$3f,$3f,$3f,$1f,$80,$80,$80,$c0,$c0,$e0,$e0,$f0
1d50: fe fe ff ff+                 .bulk   $fe,$fe,$ff,$ff,$ff,$ff,$ff,$fe,$01,$01,$01,$03,$03,$07,$07,$0f
1d60: 1f 0f 0f 07+                 .bulk   $1f,$0f,$0f,$07,$00,$00,$00,$00,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff
1d70: fe fc fc f8+                 .bulk   $fe,$fc,$fc,$f8,$00,$00,$00,$00,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff
1d80: 7e 7e 7e 7e+                 .bulk   $7e,$7e,$7e,$7e,$7f,$7f,$7f,$7f,$81,$81,$81,$81,$81,$81,$81,$81
1d90: ff ff ff ff+                 .bulk   $ff,$ff,$ff,$ff,$ff,$ff,$ff,$fe,$01,$01,$01,$03,$03,$07,$07,$0f
1da0: fe fe fe fe+                 .bulk   $fe,$fe,$fe,$fe,$ff,$ff,$ff,$ff,$01,$01,$01,$01,$01,$01,$01,$01
1db0: 7f 7f 7f 7f+                 .bulk   $7f,$7f,$7f,$7f,$7f,$7f,$7f,$7f,$81,$81,$81,$81,$81,$81,$81,$81
1dc0: ff ff ff ff+                 .bulk   $ff,$ff,$ff,$ff,$fc,$fe,$fe,$7e,$ff,$03,$03,$03,$03,$03,$03,$ff
1dd0: ff ff ff ff+                 .bulk   $ff,$ff,$ff,$ff,$00,$00,$00,$00,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff
1de0: 7f 7f 7f 7f+                 .bulk   $7f,$7f,$7f,$7f,$7f,$7f,$7f,$7f,$80,$80,$80,$80,$80,$80,$80,$80
1df0: ff ff ff ff+                 .bulk   $ff,$ff,$ff,$ff,$ff,$ff,$ff,$fe,$01,$01,$01,$03,$07,$03,$01,$01
1e00: 7e 7e 7f 7f+                 .bulk   $7e,$7e,$7f,$7f,$7f,$7f,$7f,$7f,$81,$81,$81,$81,$81,$81,$81,$81
1e10: 3f 3f 3f 3f+                 .bulk   $3f,$3f,$3f,$3f,$00,$00,$00,$00,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff
1e20: 7e 7c 7c 78+                 .bulk   $7e,$7c,$7c,$78,$00,$00,$00,$00,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff
1e30: fe fe ff ff+                 .bulk   $fe,$fe,$ff,$ff,$7f,$7f,$7f,$7f,$81,$81,$81,$81,$81,$81,$81,$81
1e40: 7f 7f 3f 3f+                 .bulk   $7f,$7f,$3f,$3f,$3f,$3f,$1f,$1f,$80,$80,$c0,$c0,$e0,$f8,$fe,$ff
1e50: 3f bf ff ff+                 .bulk   $3f,$bf,$ff,$ff,$fc,$fc,$fe,$fe,$ff,$7f,$1f,$07,$03,$03,$01,$81
1e60: 7f 7f 7e 7e+                 .bulk   $7f,$7f,$7e,$7e,$7f,$7f,$7f,$7f,$81,$81,$81,$81,$81,$81,$81,$81
1e70: 7e 7e 7e 7e+                 .bulk   $7e,$7e,$7e,$7e,$7f,$7f,$7f,$7f,$81,$81,$81,$81,$81,$81,$81,$81
1e80: 81 c3 c3 e7+                 .bulk   $81,$c3,$c3,$e7,$e7,$ff,$ff,$ff,$7e,$3c,$3c,$18,$18,$00,$00,$00
1e90: 0f 43 5b 53+                 .bulk   $0f,$43,$5b,$53,$31,$19,$0f,$07,$f2,$fe,$fe,$ff,$ff,$ef,$f7,$f8
1ea0: c1 c3 c6 84+                 .bulk   $c1,$c3,$c6,$84,$fc,$fc,$0e,$02,$bf,$be,$bd,$7b,$7b,$07,$f3,$fd
1eb0: 10 20 22 ba+                 .bulk   $10,$20,$22,$ba,$e6,$e1,$c0,$c0,$ff,$ff,$ff,$67,$59,$9e,$bf,$bf
1ec0: 20 a6 54 26+                 .bulk   $20,$a6,$54,$26,$20,$c6,$54,$26,$20,$e6,$54,$26,$21,$06,$54,$26
1ed0: 20 85 01 44+                 .bulk   $20,$85,$01,$44,$20,$86,$54,$48,$20,$9a,$01,$49,$20,$a5,$c9,$46
1ee0: 20 ba c9 4a+                 .bulk   $20,$ba,$c9,$4a,$20,$a6,$0a,$d0,$d1,$d8,$d8,$de,$d1,$d0,$da,$de
1ef0: d1 20 c6 0a+                 .bulk   $d1,$20,$c6,$0a,$d2,$d3,$db,$db,$db,$d9,$db,$dc,$db,$df,$20,$e6
1f00: 0a d4 d5 d4+                 .bulk   $0a,$d4,$d5,$d4,$d9,$db,$e2,$d4,$da,$db,$e0,$21,$06,$0a,$d6,$d7
1f10: d6 d7 e1 26+                 .bulk   $d6,$d7,$e1,$26,$d6,$dd,$e1,$e1,$21,$26,$14,$d0,$e8,$d1,$d0,$d1
1f20: de d1 d8 d0+                 .bulk   $de,$d1,$d8,$d0,$d1,$26,$de,$d1,$de,$d1,$d0,$d1,$d0,$d1,$26,$21
1f30: 46 14 db 42+                 .bulk   $46,$14,$db,$42,$42,$db,$42,$db,$42,$db,$db,$42,$26,$db,$42,$db
1f40: 42 db 42 db+                 .bulk   $42,$db,$42,$db,$42,$26,$21,$66,$46,$db,$21,$6c,$0e,$df,$db,$db
1f50: db 26 db df+                 .bulk   $db,$26,$db,$df,$db,$df,$db,$db,$e4,$e5,$26,$21,$86,$14,$db,$db
1f60: db de 43 db+                 .bulk   $db,$de,$43,$db,$e0,$db,$db,$db,$26,$db,$e3,$db,$e0,$db,$db,$e6
1f70: e3 26 21 a6+                 .bulk   $e3,$26,$21,$a6,$14,$db,$db,$db,$db,$42,$db,$db,$db,$d4,$d9,$26
1f80: db d9 db db+                 .bulk   $db,$d9,$db,$db,$d4,$d9,$d4,$d9,$e7,$21,$c5,$16,$5f,$95,$95,$95
1f90: 95 95 95 95+                 .bulk   $95,$95,$95,$95,$95,$97,$98,$78,$95,$96,$95,$95,$97,$98,$97,$98
1fa0: 95 7a 21 ed+                 .bulk   $95,$7a,$21,$ed,$0e,$cf,$01,$09,$08,$05,$24,$17,$12,$17,$1d,$0e
1fb0: 17 0d 18 22+                 .bulk   $17,$0d,$18,$22,$4b,$0d,$01,$24,$19,$15,$0a,$22,$0e,$1b,$24,$10
1fc0: 0a 16 0e 22+                 .bulk   $0a,$16,$0e,$22,$8b,$0d,$02,$24,$19,$15,$0a,$22,$0e,$1b,$24,$10
1fd0: 0a 16 0e 22+                 .bulk   $0a,$16,$0e,$22,$ec,$04,$1d,$18,$19,$28,$22,$f6,$01,$00,$23,$c9
1fe0: 56 55 23 e2+                 .bulk   $56,$55,$23,$e2,$04,$99,$aa,$aa,$aa,$23,$ea,$04,$99,$aa,$aa,$aa
1ff0: 00 ff ff ff+                 .bulk   $00,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff
                                   .adrend ↑ NA

Symbol Table

EnemyGraphicsTable$e73e
NonMaskableInterrupt$8082
PlayerGraphicsTable$ee17
Start$8000