?login_element?

Subversion Repositories NedoOS

Rev

Rev 231 | Blame | Compare with Previous | Last modification | View Log | Download

  1. ;читает:
  2. ;OperMode (0=выключить звук и не играть)
  3. ;EventMusicQueue (номер джингла типа TimeRunningOutMusic, EndOfCastleMusic) - при вызове плейера он это копирует в EventMusicBuffer и зануляет
  4. ;AreaMusicQueue (номер музыки) - при вызове плейера он это копирует в AreaMusicBuffer и зануляет
  5. ;PauseSoundQueue (1=доигрываем звук паузы и выключаем звук - как туда попадает 1???)
  6. ;Square1SoundQueue (jump, flagpole sound и др.)
  7. ;Square2SoundQueue (1-up sound, fireworks/gunfire)
  8. ;      lda Square2SoundQueue
  9. ;      oran ++Sfx_Blast            ;play fireworks/gunfire sound
  10. ;      sta Square2SoundQueue
  11. ;NoiseSoundQueue (brick shatter sound)
  12. ;        lda NoiseSoundQueue
  13. ;        oran ++Sfx_BowserFlame        ;load bowser's flame sound into queue
  14. ;        sta NoiseSoundQueue
  15.  
  16. ;возвращает:
  17. ;EventMusicBuffer (0=музыкальный эффект кончился)
  18.  
  19. SoundEngine_noint
  20. ;play sound logically (for end of level music)
  21.         if 1==0
  22. EventMusicQueue_noint=$+1
  23.         ld hl,0
  24.         ld a,h
  25.         or l
  26.         ret z
  27.         dec hl
  28.         ld (EventMusicQueue_noint),hl
  29.         endif
  30.         ret
  31.  
  32.  
  33. SoundEngine:
  34.          lda OperMode              ;are we in title screen mode?
  35.          checka
  36.          bne SndOn
  37.          sta SND_MASTERCTRL_REG    ;if so, disable sound and leave
  38.          rts
  39. SndOn:   ldan ++$ff
  40.          sta JOYPAD_PORT2          ;disable irqs and set frame counter mode???
  41.          ldan ++$0f
  42.          sta SND_MASTERCTRL_REG    ;enable first four channels
  43.          lda PauseModeFlag         ;is sound already in pause mode?
  44.          checka
  45.          bne InPause
  46.          lda PauseSoundQueue       ;if not, check pause sfx queue    
  47.          cmpn ++$01
  48.          bne RunSoundSubroutines   ;if queue is empty, skip pause mode routine
  49. InPause: lda PauseSoundBuffer      ;check pause sfx buffer
  50.          checka
  51.          bne ContPau
  52.          lda PauseSoundQueue       ;check pause queue
  53.          checka
  54.          beq SkipSoundSubroutines
  55.          sta PauseSoundBuffer      ;if queue full, store in buffer and activate
  56.          sta PauseModeFlag         ;pause mode to interrupt game sounds
  57.          ldan ++$00                  ;disable sound and clear sfx buffers
  58.          sta SND_MASTERCTRL_REG
  59.          sta Square1SoundBuffer
  60.          sta Square2SoundBuffer
  61.          sta NoiseSoundBuffer
  62.          ldan ++$0f
  63.          sta SND_MASTERCTRL_REG    ;enable sound again
  64.          ldan ++$2a                  ;store length of sound in pause counter
  65.          sta Squ1_SfxLenCounter
  66. PTone1F: ldan ++$44                  ;play first tone
  67.          checka
  68.          bne PTRegC                ;unconditional branch
  69. ContPau: lda Squ1_SfxLenCounter    ;check pause length left
  70.          cmpn ++$24                  ;time to play second?
  71.          beq PTone2F
  72.          cmpn ++$1e                  ;time to play first again?
  73.          beq PTone1F
  74.          cmpn ++$18                  ;time to play second again?
  75.          bne DecPauC               ;only load regs during times, otherwise skip
  76. PTone2F: ldan ++$64                  ;store reg contents and play the pause sfx
  77. PTRegC:  ldxn ++$84
  78.          ldyn ++$7f
  79.          jsr PlaySqu1Sfx
  80. DecPauC: deci Squ1_SfxLenCounter    ;decrement pause sfx counter
  81.          bne SkipSoundSubroutines
  82.          ldan ++$00                  ;disable sound if in pause mode and
  83.          sta SND_MASTERCTRL_REG    ;not currently playing the pause sfx
  84.          lda PauseSoundBuffer      ;if no longer playing pause sfx, check to see
  85.          cmpn ++$02                  ;if we need to be playing sound again
  86.          bne SkipPIn
  87.          ldan ++$00                  ;clear pause mode to allow game sounds again
  88.          sta PauseModeFlag
  89. SkipPIn: ldan ++$00                  ;clear pause sfx buffer
  90.          sta PauseSoundBuffer
  91.          checka
  92.          beq SkipSoundSubroutines ;unconditional???
  93.  
  94. RunSoundSubroutines:
  95.          jsr Square1SfxHandler  ;play sfx on square channel 1
  96.          jsr Square2SfxHandler  ; ''  ''  '' square channel 2
  97.          jsr NoiseSfxHandler    ; ''  ''  '' noise channel
  98.          jsr MusicHandler       ;play music on all channels
  99.          ldan ++$00               ;clear the music queues
  100.          sta AreaMusicQueue
  101.          sta EventMusicQueue
  102.  
  103. SkipSoundSubroutines:
  104.           ldan ++$00               ;clear the sound effects queues
  105.           sta Square1SoundQueue
  106.           sta Square2SoundQueue
  107.           sta NoiseSoundQueue
  108.           sta PauseSoundQueue
  109.           ldy DAC_Counter        ;load some sort of counter
  110.           lda AreaMusicBuffer
  111.           andn ++%00000011         ;check for specific music
  112.           beq NoIncDAC
  113.           inci DAC_Counter        ;increment and check counter
  114.           cpyn ++$30
  115.               cmpcy
  116.           bcc StrWave            ;if not there yet, just store it
  117. NoIncDAC: tya
  118.          checka
  119.           beq StrWave            ;if we are at zero, do not decrement
  120.           deci DAC_Counter        ;decrement counter
  121. StrWave:  sty SND_DELTA_REG+1    ;store into DMC load register (??)
  122.           rts                    ;we are done here
  123.  
  124. ;--------------------------------
  125.  
  126. Dump_Squ1_Regs:
  127.       sty SND_SQUARE1_REG+1  ;dump the contents of X and Y into square 1's control regs
  128.       stx SND_SQUARE1_REG
  129.       rts
  130.      
  131. PlaySqu1Sfx:
  132.       jsr Dump_Squ1_Regs     ;do sub to set ctrl regs for square 1, then set frequency regs
  133.  
  134. SetFreq_Squ1:
  135. ;out: Z=NoTone
  136.       ldxn ++$00               ;set frequency reg offset for square 1 sound channel
  137.  
  138. Dump_Freq_Regs:
  139. ;out: Z=NoTone
  140.         tay
  141.         lday FreqRegLookupTbl+1,y  ;use previous contents of A for sound reg offset
  142.          checka
  143.         beq NoTone                ;if zero, then do not load
  144.         stax SND_REGISTER+2,x      ;first byte goes into LSB of frequency divider
  145.         lday FreqRegLookupTbl,y    ;second byte goes into 3 MSB plus extra bit for
  146.         oran ++%00001000            ;length counter
  147.         stax SND_REGISTER+3,x
  148.        
  149.         if Z80
  150. ;write to SND_REGISTER+3 causes counter loading from a table
  151.         rra
  152.         rra
  153.         rra
  154.         and 0x1f
  155.         ld hl,tcounterload
  156.         add a,l
  157.         ld l,a
  158.         adc a,h
  159.         sub l
  160.         ld h,a
  161.         ld a,(hl) ;читает 5, а на слух надо примерно 0x10 для музыки, для флага больше, только эффекты покороче
  162.         add a,a
  163.         ;jr $
  164.         stax SND_COUNTER,x
  165. ;Only a write out to $4003/$4007/$400F will reset the current envelope decay counter to a known state (to $F, the maximum volume level) for the appropriate channel's envelope decay hardware.
  166.         ld a,0x0f
  167.         stax SND_DECAYVOL,x
  168.         endif
  169.        
  170. NoTone: rts
  171.  
  172. Dump_Sq2_Regs:
  173.       stx SND_SQUARE2_REG    ;dump the contents of X and Y into square 2's control regs
  174.       sty SND_SQUARE2_REG+1
  175.       rts
  176.  
  177. PlaySqu2Sfx:
  178.       jsr Dump_Sq2_Regs      ;do sub to set ctrl regs for square 2, then set frequency regs
  179.  
  180. SetFreq_Squ2:
  181. ;out: Z=NoTone
  182.       ldxn ++$04               ;set frequency reg offset for square 2 sound channel
  183.          checkx
  184.       bne Dump_Freq_Regs     ;unconditional branch
  185.  
  186. SetFreq_Tri:
  187. ;out: Z=NoTone
  188.       ldxn ++$08               ;set frequency reg offset for triangle sound channel
  189.          checkx
  190.       bne Dump_Freq_Regs     ;unconditional branch
  191.  
  192. ;--------------------------------
  193.  
  194. SwimStompEnvelopeData:
  195.       .db $9f, $9b, $98, $96, $95, $94, $92, $90
  196.       .db $90, $9a, $97, $95, $93, $92
  197.  
  198. PlayFlagpoleSlide:
  199.        ldan ++$40               ;store length of flagpole sound
  200.        sta Squ1_SfxLenCounter
  201.        ldan ++$62               ;load part of reg contents for flagpole sound
  202.        jsr SetFreq_Squ1
  203.        ldxn ++$99               ;now load the rest
  204.          checkx
  205.        bne FPS2nd ;unconditional???
  206.  
  207. PlaySmallJump:
  208.        ldan ++$26               ;branch here for small mario jumping sound
  209.          checka
  210.        bne JumpRegContents ;unconditional???
  211.  
  212. PlayBigJump:
  213.        ldan ++$18               ;branch here for big mario jumping sound
  214.  
  215. JumpRegContents:
  216.        ldxn ++$82               ;note that small and big jump borrow each others' reg contents
  217.        ldyn ++$a7               ;anyway, this loads the first part of mario's jumping sound
  218.        jsr PlaySqu1Sfx
  219.        ldan ++$28               ;store length of sfx for both jumping sounds
  220.        sta Squ1_SfxLenCounter ;then continue on here
  221.  
  222. ContinueSndJump:
  223.           lda Squ1_SfxLenCounter ;jumping sounds seem to be composed of three parts
  224.           cmpn ++$25               ;check for time to play second part yet
  225.           bne N2Prt
  226.           ldxn ++$5f               ;load second part
  227.           ldyn ++$f6
  228.          checky
  229.           bne DmpJpFPS           ;unconditional branch
  230. N2Prt:    cmpn ++$20               ;check for third part
  231.           bne DecJpFPS
  232.           ldxn ++$48               ;load third part
  233. FPS2nd:   ldyn ++$bc               ;the flagpole slide sound shares part of third part
  234. DmpJpFPS: jsr Dump_Squ1_Regs
  235.           bne DecJpFPS           ;unconditional branch outta here ;???
  236.  
  237. PlayFireballThrow:
  238.         ldan ++$05
  239.         ldyn ++$99                 ;load reg contents for fireball throw sound
  240.          checky
  241.         bne Fthrow               ;unconditional branch
  242.  
  243. PlayBump:
  244.           ldan ++$0a                ;load length of sfx and reg contents for bump sound
  245.           ldyn ++$93
  246. Fthrow:   ldxn ++$9e                ;the fireball sound shares reg contents with the bump sound
  247.           sta Squ1_SfxLenCounter
  248.           ldan ++$0c                ;load offset for bump sound
  249.           jsr PlaySqu1Sfx
  250.  
  251. ContinueBumpThrow:    
  252.           lda Squ1_SfxLenCounter  ;check for second part of bump sound
  253.           cmpn ++$06  
  254.           bne DecJpFPS
  255.           ldan ++$bb                ;load second part directly
  256.           sta SND_SQUARE1_REG+1
  257.          checka
  258. DecJpFPS: bne BranchToDecLength1  ;unconditional branch
  259.  
  260.  
  261. Square1SfxHandler:
  262.        ldy Square1SoundQueue   ;check for sfx in queue
  263.          checky
  264.        beq CheckSfx1Buffer
  265.        sty Square1SoundBuffer  ;if found, put in buffer
  266.          ;checky ;???
  267.        bmi PlaySmallJump       ;small jump
  268.        lsri Square1SoundQueue
  269.        bcs PlayBigJump         ;big jump
  270.        lsri Square1SoundQueue
  271.        bcs PlayBump            ;bump
  272.        lsri Square1SoundQueue
  273.        bcs PlaySwimStomp       ;swim/stomp
  274.        lsri Square1SoundQueue
  275.        bcs PlaySmackEnemy      ;smack enemy
  276.        lsri Square1SoundQueue
  277.        bcs PlayPipeDownInj     ;pipedown/injury
  278.        lsri Square1SoundQueue
  279.        bcs PlayFireballThrow   ;fireball throw
  280.        lsri Square1SoundQueue
  281.        bcs PlayFlagpoleSlide   ;slide flagpole
  282.  
  283. CheckSfx1Buffer:
  284.        lda Square1SoundBuffer   ;check for sfx in buffer
  285.          checka
  286.        beq ExS1H                ;if not found, exit sub
  287.        bmi ContinueSndJump      ;small mario jump
  288.        lsr
  289.        bcs ContinueSndJump      ;big mario jump
  290.        lsr
  291.        bcs ContinueBumpThrow    ;bump
  292.        lsr
  293.        bcs ContinueSwimStomp    ;swim/stomp
  294.        lsr
  295.        bcs ContinueSmackEnemy   ;smack enemy
  296.        lsr
  297.        bcs ContinuePipeDownInj  ;pipedown/injury
  298.        lsr
  299.        bcs ContinueBumpThrow    ;fireball throw
  300.        lsr
  301.        bcs DecrementSfx1Length  ;slide flagpole
  302. ExS1H: rts
  303.  
  304. PlaySwimStomp:
  305.       ldan ++$0e               ;store length of swim/stomp sound
  306.       sta Squ1_SfxLenCounter
  307.       ldyn ++$9c               ;store reg contents for swim/stomp sound
  308.       ldxn ++$9e
  309.       ldan ++$26
  310.       jsr PlaySqu1Sfx
  311.  
  312. ContinueSwimStomp:
  313.       ldy Squ1_SfxLenCounter        ;look up reg contents in data section based on
  314.       lday SwimStompEnvelopeData-1,y ;length of sound left, used to control sound's
  315.       sta SND_SQUARE1_REG           ;envelope
  316.       cpyn ++$06  
  317.       bne BranchToDecLength1
  318.       ldan ++$9e                      ;when the length counts down to a certain point, put this
  319.       sta SND_SQUARE1_REG+2         ;directly into the LSB of square 1's frequency divider
  320.          checka
  321.  
  322. BranchToDecLength1:
  323.       bne DecrementSfx1Length  ;unconditional branch (regardless of how we got here)
  324.  
  325. PlaySmackEnemy:
  326.       ldan ++$0e                 ;store length of smack enemy sound
  327.       ldyn ++$cb
  328.       ldxn ++$9f
  329.       sta Squ1_SfxLenCounter
  330.       ldan ++$28                 ;store reg contents for smack enemy sound
  331.       jsr PlaySqu1Sfx
  332.       bne DecrementSfx1Length  ;unconditional branch ;??? если выход из PlaySqu1Sfx по NoTone, то перехода не будет!!!
  333.  
  334. ContinueSmackEnemy:
  335.         ldy Squ1_SfxLenCounter  ;check about halfway through
  336.         cpyn ++$08
  337.         bne SmSpc
  338.         ldan ++$a0                ;if we're at the about-halfway point, make the second tone
  339.         sta SND_SQUARE1_REG+2   ;in the smack enemy sound
  340.         ldan ++$9f
  341.          checka
  342.         bne SmTick ;unconditional???
  343. SmSpc:  ldan ++$90                ;this creates spaces in the sound, giving it its distinct noise
  344. SmTick: sta SND_SQUARE1_REG
  345.  
  346. DecrementSfx1Length:
  347.       deci Squ1_SfxLenCounter    ;decrement length of sfx
  348.       bne ExSfx1
  349.  
  350. StopSquare1Sfx:
  351.         ldxn ++$00                ;if end of sfx reached, clear buffer
  352.         stx Square1SoundBuffer;SCRATCHPAD+$f1                 ;and stop making the sfx
  353.         ldxn ++$0e
  354.         stx SND_MASTERCTRL_REG
  355.         ldxn ++$0f
  356.         stx SND_MASTERCTRL_REG
  357. ExSfx1: rts
  358.  
  359. PlayPipeDownInj:  
  360.       ldan ++$2f                ;load length of pipedown sound
  361.       sta Squ1_SfxLenCounter
  362.  
  363. ContinuePipeDownInj:
  364.          lda Squ1_SfxLenCounter  ;some bitwise logic, forces the regs
  365.          lsr                     ;to be written to only during six specific times
  366.          bcs NoPDwnL             ;during which d3 must be set and d1-0 must be clear
  367.          lsr
  368.          bcs NoPDwnL
  369.          andn ++%00000010
  370.          beq NoPDwnL
  371.          ldyn ++$91                ;and this is where it actually gets written in
  372.          ldxn ++$9a
  373.          ldan ++$44
  374.          jsr PlaySqu1Sfx
  375. NoPDwnL: jmp DecrementSfx1Length
  376.  
  377. ;--------------------------------
  378.  
  379. ExtraLifeFreqData:
  380.       .db $58, $02, $54, $56, $4e, $44
  381.  
  382. PowerUpGrabFreqData:
  383.       .db $4c, $52, $4c, $48, $3e, $36, $3e, $36, $30
  384.       .db $28, $4a, $50, $4a, $64, $3c, $32, $3c, $32
  385.       .db $2c, $24, $3a, $64, $3a, $34, $2c, $22, $2c
  386.  
  387. ;residual frequency data
  388.       .db $22, $1c, $14
  389.  
  390. PUp_VGrow_FreqData:
  391.       .db $14, $04, $22, $24, $16, $04, $24, $26 ;used by both
  392.       .db $18, $04, $26, $28, $1a, $04, $28, $2a
  393.       .db $1c, $04, $2a, $2c, $1e, $04, $2c, $2e ;used by vinegrow
  394.       .db $20, $04, $2e, $30, $22, $04, $30, $32
  395.  
  396. PlayCoinGrab:
  397.         ldan ++$35             ;load length of coin grab sound
  398.         ldxn ++$8d             ;and part of reg contents
  399.          checkx
  400.         bne CGrab_TTickRegL
  401.  
  402. PlayTimerTick:
  403.         ldan ++$06             ;load length of timer tick sound
  404.         ldxn ++$98             ;and part of reg contents
  405.  
  406. CGrab_TTickRegL:
  407.         sta Squ2_SfxLenCounter
  408.         ldyn ++$7f                ;load the rest of reg contents
  409.         ldan ++$42                ;of coin grab and timer tick sound
  410.         jsr PlaySqu2Sfx
  411.  
  412. ContinueCGrabTTick:
  413.         lda Squ2_SfxLenCounter  ;check for time to play second tone yet
  414.         cmpn ++$30                ;timer tick sound also executes this, not sure why
  415.         bne N2Tone
  416.         ldan ++$54                ;if so, load the tone directly into the reg
  417.         sta SND_SQUARE2_REG+2
  418.          checka
  419. N2Tone: bne DecrementSfx2Length ;unconditional???
  420.  
  421. PlayBlast:
  422.         ldan ++$20                ;load length of fireworks/gunfire sound
  423.         sta Squ2_SfxLenCounter
  424.         ldyn ++$94                ;load reg contents of fireworks/gunfire sound
  425.         ldan ++$5e
  426.          checka
  427.         bne SBlasJ ;unconditional???
  428.  
  429. ContinueBlast:
  430.         lda Squ2_SfxLenCounter  ;check for time to play second part
  431.         cmpn ++$18
  432.         bne DecrementSfx2Length
  433.         ldyn ++$93                ;load second part reg contents then
  434.         ldan ++$18
  435.          checka
  436. SBlasJ: bne BlstSJp             ;unconditional branch to load rest of reg contents
  437.  
  438. PlayPowerUpGrab:
  439.         ldan ++$36                    ;load length of power-up grab sound
  440.         sta Squ2_SfxLenCounter
  441.  
  442. ContinuePowerUpGrab:  
  443.         lda Squ2_SfxLenCounter      ;load frequency reg based on length left over
  444.         lsr                         ;divide by 2
  445.         bcs DecrementSfx2Length     ;alter frequency every other frame
  446.         tay
  447.         lday PowerUpGrabFreqData-1,y ;use length left over / 2 for frequency offset
  448.         ldxn ++$5d                    ;store reg contents of power-up grab sound
  449.         ldyn ++$7f
  450.  
  451. LoadSqu2Regs:
  452.         jsr PlaySqu2Sfx
  453.  
  454. DecrementSfx2Length:
  455.         deci Squ2_SfxLenCounter   ;decrement length of sfx
  456.         bne ExSfx2
  457.  
  458. EmptySfx2Buffer:
  459.         ldxn ++$00                ;initialize square 2's sound effects buffer
  460.         stx Square2SoundBuffer
  461.  
  462. StopSquare2Sfx:
  463.         ldxn ++$0d                ;stop playing the sfx
  464.         stx SND_MASTERCTRL_REG
  465.         ldxn ++$0f
  466.         stx SND_MASTERCTRL_REG
  467. ExSfx2: rts
  468.  
  469. Square2SfxHandler:
  470.         lda Square2SoundBuffer ;special handling for the 1-up sound to keep it
  471.         andn ++Sfx_ExtraLife     ;from being interrupted by other sounds on square 2
  472.         bne ContinueExtraLife
  473.         ldy Square2SoundQueue  ;check for sfx in queue
  474.          checky
  475.         beq CheckSfx2Buffer
  476.         sty Square2SoundBuffer ;if found, put in buffer and check for the following
  477.          ;checky ;???
  478.         bmi PlayBowserFall     ;bowser fall
  479.         lsri Square2SoundQueue
  480.         bcs PlayCoinGrab       ;coin grab
  481.         lsri Square2SoundQueue
  482.         bcs PlayGrowPowerUp    ;power-up reveal
  483.         lsri Square2SoundQueue
  484.         bcs PlayGrowVine       ;vine grow
  485.         lsri Square2SoundQueue
  486.         bcs PlayBlast          ;fireworks/gunfire
  487.         lsri Square2SoundQueue
  488.         bcs PlayTimerTick      ;timer tick
  489.         lsri Square2SoundQueue
  490.         bcs PlayPowerUpGrab    ;power-up grab
  491.         lsri Square2SoundQueue
  492.         bcs PlayExtraLife      ;1-up
  493.  
  494. CheckSfx2Buffer:
  495.         lda Square2SoundBuffer   ;check for sfx in buffer
  496.          checka
  497.         beq ExS2H                ;if not found, exit sub
  498.         bmi ContinueBowserFall   ;bowser fall
  499.         lsr
  500.         bcs Cont_CGrab_TTick     ;coin grab
  501.         lsr
  502.         bcs ContinueGrowItems    ;power-up reveal
  503.         lsr
  504.         bcs ContinueGrowItems    ;vine grow
  505.         lsr
  506.         bcs ContinueBlast        ;fireworks/gunfire
  507.         lsr
  508.         bcs Cont_CGrab_TTick     ;timer tick
  509.         lsr
  510.         bcs ContinuePowerUpGrab  ;power-up grab
  511.         lsr
  512.         bcs ContinueExtraLife    ;1-up
  513. ExS2H:  rts
  514.  
  515. Cont_CGrab_TTick:
  516.         jmp ContinueCGrabTTick
  517.  
  518. JumpToDecLength2:
  519.         jmp DecrementSfx2Length
  520.  
  521. PlayBowserFall:    
  522.          ldan ++$38                ;load length of bowser defeat sound
  523.          sta Squ2_SfxLenCounter
  524.          ldyn ++$c4                ;load contents of reg for bowser defeat sound
  525.          ldan ++$18
  526.          checka
  527. BlstSJp: bne PBFRegs ;unconditional???
  528.  
  529. ContinueBowserFall:
  530.           lda Squ2_SfxLenCounter   ;check for almost near the end
  531.           cmpn ++$08
  532.           bne DecrementSfx2Length
  533.           ldyn ++$a4                 ;if so, load the rest of reg contents for bowser defeat sound
  534.           ldan ++$5a
  535. PBFRegs:  ldxn ++$9f                 ;the fireworks/gunfire sound shares part of reg contents here
  536.          checkx
  537. EL_LRegs: bne LoadSqu2Regs         ;this is an unconditional branch outta here
  538.  
  539. PlayExtraLife:
  540.         ldan ++$30                  ;load length of 1-up sound
  541.         sta Squ2_SfxLenCounter
  542.  
  543. ContinueExtraLife:
  544.           lda Squ2_SfxLenCounter  
  545.           ldxn ++$03                  ;load new tones only every eight frames
  546. DivLLoop: lsr
  547.           bcs JumpToDecLength2      ;if any bits set here, branch to dec the length
  548.           dex
  549.           bne DivLLoop              ;do this until all bits checked, if none set, continue
  550.           tay
  551.           lday ExtraLifeFreqData-1,y ;load our reg contents
  552.           ldxn ++$82
  553.           ldyn ++$7f
  554.          checky
  555.           bne EL_LRegs              ;unconditional branch
  556.  
  557. PlayGrowPowerUp:
  558.         ldan ++$10                ;load length of power-up reveal sound
  559.          checka
  560.         bne GrowItemRegs ;unconditional???
  561.  
  562. PlayGrowVine:
  563.         ldan ++$20                ;load length of vine grow sound
  564.  
  565. GrowItemRegs:
  566.         sta Squ2_SfxLenCounter  
  567.         ldan ++$7f                  ;load contents of reg for both sounds directly
  568.         sta SND_SQUARE2_REG+1
  569.         ldan ++$00                  ;start secondary counter for both sounds
  570.         sta Sfx_SecondaryCounter
  571.  
  572. ContinueGrowItems:
  573.         inci Sfx_SecondaryCounter  ;increment secondary counter for both sounds
  574.         lda Sfx_SecondaryCounter  ;this sound doesn't decrement the usual counter
  575.         lsr                       ;divide by 2 to get the offset
  576.         tay
  577.         cpyi Squ2_SfxLenCounter    ;have we reached the end yet?
  578.         beq StopGrowItems         ;if so, branch to jump, and stop playing sounds
  579.         ldan ++$9d                  ;load contents of other reg directly
  580.         sta SND_SQUARE2_REG
  581.         lday PUp_VGrow_FreqData,y  ;use secondary counter / 2 as offset for frequency regs
  582.         jsr SetFreq_Squ2
  583.         rts
  584.  
  585. StopGrowItems:
  586.         jmp EmptySfx2Buffer       ;branch to stop playing sounds
  587.  
  588. ;--------------------------------
  589.  
  590. BrickShatterFreqData:
  591.         .db $01, $0e, $0e, $0d, $0b, $06, $0c, $0f
  592.         .db $0a, $09, $03, $0d, $08, $0d, $06, $0c
  593.  
  594. PlayBrickShatter:
  595.         ldan ++$20                 ;load length of brick shatter sound
  596.         sta Noise_SfxLenCounter
  597.  
  598. ContinueBrickShatter:
  599.         lda Noise_SfxLenCounter  
  600.         lsr                         ;divide by 2 and check for bit set to use offset
  601.         bcc DecrementSfx3Length
  602.         tay
  603.         ldxy BrickShatterFreqData,y  ;load reg contents of brick shatter sound
  604.         lday BrickShatterEnvData,y
  605.  
  606. PlayNoiseSfx:
  607.         sta SND_NOISE_REG        ;play the sfx
  608.         stx SND_NOISE_REG+2
  609.         ldan ++$18
  610.         sta SND_NOISE_REG+3
  611.         if Z80
  612.         call wrnoise3
  613.         endif
  614.  
  615. DecrementSfx3Length:
  616.         deci Noise_SfxLenCounter  ;decrement length of sfx
  617.         bne ExSfx3
  618.         ldan ++$f0                 ;if done, stop playing the sfx
  619.         sta SND_NOISE_REG
  620.         ldan ++$00
  621.         sta NoiseSoundBuffer
  622. ExSfx3: rts
  623.  
  624. NoiseSfxHandler:
  625.         ldy NoiseSoundQueue   ;check for sfx in queue
  626.          checky
  627.         beq CheckNoiseBuffer
  628.         sty NoiseSoundBuffer  ;if found, put in buffer
  629.         lsri NoiseSoundQueue
  630.         bcs PlayBrickShatter  ;brick shatter
  631.         lsri NoiseSoundQueue
  632.         bcs PlayBowserFlame   ;bowser flame
  633.  
  634. CheckNoiseBuffer:
  635.         lda NoiseSoundBuffer      ;check for sfx in buffer
  636.          checka
  637.         beq ExNH                  ;if not found, exit sub
  638.         lsr
  639.         bcs ContinueBrickShatter  ;brick shatter
  640.         lsr
  641.         bcs ContinueBowserFlame   ;bowser flame
  642. ExNH:   rts
  643.  
  644. PlayBowserFlame:
  645.         ldan ++$40                    ;load length of bowser flame sound
  646.         sta Noise_SfxLenCounter
  647.  
  648. ContinueBowserFlame:
  649.         lda Noise_SfxLenCounter
  650.         lsr
  651.         tay
  652.         ldxn ++$0f                    ;load reg contents of bowser flame sound
  653.         lday BowserFlameEnvData-1,y
  654.          checka
  655.         bne PlayNoiseSfx            ;unconditional branch here
  656.  
  657. ;--------------------------------
  658.  
  659. ContinueMusic:
  660.         jmp HandleSquare2Music  ;if we have music, start with square 2 channel
  661.  
  662. MusicHandler:
  663.         lda EventMusicQueue     ;check event music queue
  664.          checka
  665.         bne LoadEventMusic
  666.         lda AreaMusicQueue      ;check area music queue
  667.          checka
  668.         bne LoadAreaMusic
  669.         lda EventMusicBuffer    ;check both buffers
  670.         orai AreaMusicBuffer
  671.         bne ContinueMusic
  672.         rts                     ;no music, then leave
  673.  
  674. LoadEventMusic:
  675.         if 1==0
  676.         cp EndOfLevelMusic
  677.         jr nz,noendlevelmusicpatch
  678.         ld hl,0xffff
  679.         ld (EventMusicQueue_noint),hl
  680. noendlevelmusicpatch
  681.         endif
  682.            sta EventMusicBuffer      ;copy event music queue contents to buffer
  683.            cmpn ++DeathMusic           ;is it death music?
  684.            bne NoStopSfx             ;if not, jump elsewhere
  685.            jsr StopSquare1Sfx        ;stop sfx in square 1 and 2
  686.            jsr StopSquare2Sfx        ;but clear only square 1's sfx buffer
  687. NoStopSfx: ldx AreaMusicBuffer
  688.            stx AreaMusicBuffer_Alt   ;save current area music buffer to be re-obtained later
  689.            ldyn ++$00
  690.            sty NoteLengthTblAdder    ;default value for additional length byte offset
  691.            sty AreaMusicBuffer       ;clear area music buffer
  692.            cmpn ++TimeRunningOutMusic  ;is it time running out music?
  693.            bne FindEventMusicHeader
  694.            ldxn ++$08                  ;load offset to be added to length byte of header
  695.            stx NoteLengthTblAdder
  696.          checkx
  697.            bne FindEventMusicHeader  ;unconditional branch
  698.  
  699. LoadAreaMusic:
  700.          cmpn ++$04                  ;is it underground music?
  701.          bne NoStop1               ;no, do not stop square 1 sfx
  702.          jsr StopSquare1Sfx
  703. NoStop1: ldyn ++$10                  ;start counter used only by ground level music
  704. GMLoopB: sty GroundMusicHeaderOfs
  705.  
  706. HandleAreaMusicLoopB:
  707.          ldyn ++$00                  ;clear event music buffer
  708.          sty EventMusicBuffer
  709.          sta AreaMusicBuffer       ;copy area music queue contents to buffer
  710.          cmpn ++$01                  ;is it ground level music?
  711.          bne FindAreaMusicHeader
  712.          inci GroundMusicHeaderOfs  ;increment but only if playing ground level music
  713.          ldy GroundMusicHeaderOfs  ;is it time to loopback ground level music?
  714.          cpyn ++$32
  715.          bne LoadHeader            ;branch ahead with alternate offset
  716.          ldyn ++$11
  717.          checky
  718.          bne GMLoopB               ;unconditional branch
  719.  
  720. FindAreaMusicHeader:
  721.         ldyn ++$08                   ;load Y for offset of area music
  722.         sty MusicOffset_Square2    ;residual instruction here
  723.  
  724. FindEventMusicHeader:
  725.         iny                       ;increment Y pointer based on previously loaded queue contents
  726.         lsr                       ;bit shift and increment until we find a set bit for music
  727.         bcc FindEventMusicHeader
  728.  
  729. LoadHeader:
  730.         lday MusicHeaderOffsetData,y  ;load offset for header
  731.         tay
  732.         lday MusicHeaderData,y        ;now load the header
  733.         sta NoteLenLookupTblOfs
  734.         lday MusicHeaderData+1,y
  735.         sta MusicDataLow
  736.         lday MusicHeaderData+2,y
  737.         sta MusicDataHigh
  738.         lday MusicHeaderData+3,y
  739.         sta MusicOffset_Triangle
  740.         lday MusicHeaderData+4,y
  741.         sta MusicOffset_Square1
  742.         lday MusicHeaderData+5,y
  743.         sta MusicOffset_Noise
  744.         sta NoiseDataLoopbackOfs
  745.         ldan ++$01                     ;initialize music note counters
  746.         sta Squ2_NoteLenCounter
  747.         sta Squ1_NoteLenCounter
  748.         sta Tri_NoteLenCounter
  749.         sta Noise_BeatLenCounter
  750.         ldan ++$00                     ;initialize music data offset for square 2
  751.         sta MusicOffset_Square2
  752.         sta AltRegContentFlag        ;initialize alternate control reg data used by square 1
  753.         ldan ++$0b                     ;disable triangle channel and reenable it
  754.         sta SND_MASTERCTRL_REG
  755.         ldan ++$0f
  756.         sta SND_MASTERCTRL_REG
  757.  
  758. HandleSquare2Music:
  759.         deci Squ2_NoteLenCounter  ;decrement square 2 note length
  760.         bne MiscSqu2MusicTasks   ;is it time for more data?  if not, branch to end tasks
  761.         ldy MusicOffset_Square2  ;increment square 2 music offset and fetch data
  762.         inci MusicOffset_Square2
  763.         ldayindirect (MusicData),y
  764.          checka
  765.         beq EndOfMusicData       ;if zero, the data is a null terminator
  766.         bpl Squ2NoteHandler      ;if non-negative, data is a note
  767.         bne Squ2LengthHandler    ;otherwise it is length data
  768.  
  769. EndOfMusicData:
  770.         lda EventMusicBuffer     ;check secondary buffer for time running out music
  771.         cmpn ++TimeRunningOutMusic
  772.         bne NotTRO
  773.         lda AreaMusicBuffer_Alt  ;load previously saved contents of primary buffer
  774.          checka
  775.         bne MusicLoopBack        ;and start playing the song again if there is one
  776. NotTRO: andn ++VictoryMusic        ;check for victory music (the only secondary that loops)
  777.         bne VictoryMLoopBack
  778.         lda AreaMusicBuffer      ;check primary buffer for any music except pipe intro
  779.         andn ++%01011111
  780.         bne MusicLoopBack        ;if any area music except pipe intro, music loops
  781.         ldan ++$00                 ;clear primary and secondary buffers and initialize
  782.         sta AreaMusicBuffer      ;control regs of square and triangle channels
  783.         sta EventMusicBuffer
  784.         sta SND_TRIANGLE_REG
  785.         ldan ++$90    
  786.         sta SND_SQUARE1_REG
  787.         sta SND_SQUARE2_REG
  788.         rts
  789.  
  790. MusicLoopBack:
  791.         jmp HandleAreaMusicLoopB
  792.  
  793. VictoryMLoopBack:
  794.         jmp LoadEventMusic
  795.  
  796. Squ2LengthHandler:
  797.         jsr ProcessLengthData    ;store length of note
  798.         sta Squ2_NoteLenBuffer
  799.         ldy MusicOffset_Square2  ;fetch another byte (MUST NOT BE LENGTH BYTE!)
  800.         inci MusicOffset_Square2
  801.         ldayindirect (MusicData),y
  802.  
  803. Squ2NoteHandler:
  804.           ldx Square2SoundBuffer     ;is there a sound playing on this channel?
  805.          checkx
  806.           bne SkipFqL1
  807.           jsr SetFreq_Squ2           ;no, then play the note ;out: Z=NoTone
  808.           beq Rest                   ;check to see if note is rest
  809.           jsr LoadControlRegs        ;if not, load control regs for square 2
  810. Rest:     sta Squ2_EnvelopeDataCtrl  ;save contents of A
  811.           jsr Dump_Sq2_Regs          ;dump X and Y into square 2 control regs
  812. SkipFqL1: lda Squ2_NoteLenBuffer     ;save length in square 2 note counter
  813.           sta Squ2_NoteLenCounter
  814.  
  815. MiscSqu2MusicTasks:
  816.            lda Square2SoundBuffer     ;is there a sound playing on square 2?
  817.          checka
  818.            bne HandleSquare1Music
  819.            lda EventMusicBuffer       ;check for death music or d4 set on secondary buffer
  820.            andn ++%10010001             ;note that regs for death music or d4 are loaded by default
  821.            bne HandleSquare1Music
  822.            ldy Squ2_EnvelopeDataCtrl  ;check for contents saved from LoadControlRegs
  823.          checky
  824.            beq NoDecEnv1
  825.            deci Squ2_EnvelopeDataCtrl  ;decrement unless already zero
  826. NoDecEnv1: jsr LoadEnvelopeData       ;do a load of envelope data to replace default
  827.            sta SND_SQUARE2_REG        ;based on offset set by first load unless playing
  828.            ldxn ++$7f                   ;death music or d4 set on secondary buffer
  829.            stx SND_SQUARE2_REG+1
  830.  
  831. HandleSquare1Music:
  832.         ldy MusicOffset_Square1    ;is there a nonzero offset here?
  833.          checky
  834.         beq HandleTriangleMusic    ;if not, skip ahead to the triangle channel
  835.         deci Squ1_NoteLenCounter    ;decrement square 1 note length
  836.         bne MiscSqu1MusicTasks     ;is it time for more data?
  837.  
  838. FetchSqu1MusicData:
  839.         ldy MusicOffset_Square1    ;increment square 1 music offset and fetch data
  840.         inci MusicOffset_Square1
  841.         ldayindirect (MusicData),y
  842.          checka
  843.         bne Squ1NoteHandler        ;if nonzero, then skip this part
  844.         ldan ++$83
  845.         sta SND_SQUARE1_REG        ;store some data into control regs for square 1
  846.         ldan ++$94                   ;and fetch another byte of data, used to give
  847.         sta SND_SQUARE1_REG+1      ;death music its unique sound
  848.         sta AltRegContentFlag
  849.          checka
  850.         bne FetchSqu1MusicData     ;unconditional branch
  851.  
  852. Squ1NoteHandler:
  853.            jsr AlternateLengthHandler
  854.            sta Squ1_NoteLenCounter    ;save contents of A in square 1 note counter
  855.            ldy Square1SoundBuffer     ;is there a sound playing on square 1?
  856.          checky
  857.            bne HandleTriangleMusic
  858.            txa
  859.            andn ++%00111110             ;change saved data to appropriate note format
  860.            jsr SetFreq_Squ1           ;play the note ;out: Z=NoTone
  861.            beq SkipCtrlL
  862.            jsr LoadControlRegs
  863. SkipCtrlL: sta Squ1_EnvelopeDataCtrl  ;save envelope offset
  864.            jsr Dump_Squ1_Regs
  865.  
  866. MiscSqu1MusicTasks:
  867.               lda Square1SoundBuffer     ;is there a sound playing on square 1?
  868.          checka
  869.               bne HandleTriangleMusic
  870.               lda EventMusicBuffer       ;check for death music or d4 set on secondary buffer
  871.               andn ++%10010001
  872.               bne DeathMAltReg
  873.               ldy Squ1_EnvelopeDataCtrl  ;check saved envelope offset
  874.          checky
  875.               beq NoDecEnv2
  876.               deci Squ1_EnvelopeDataCtrl  ;decrement unless already zero
  877. NoDecEnv2:    jsr LoadEnvelopeData       ;do a load of envelope data
  878.               sta SND_SQUARE1_REG        ;based on offset set by first load
  879. DeathMAltReg: lda AltRegContentFlag      ;check for alternate control reg data
  880.          checka
  881.               bne DoAltLoad
  882.               ldan ++$7f                   ;load this value if zero, the alternate value
  883. DoAltLoad:    sta SND_SQUARE1_REG+1      ;if nonzero, and let's move on
  884.  
  885. HandleTriangleMusic:
  886.         lda MusicOffset_Triangle
  887.         deci Tri_NoteLenCounter    ;decrement triangle note length
  888.         bne HandleNoiseMusic      ;is it time for more data?
  889.         ldy MusicOffset_Triangle  ;increment square 1 music offset and fetch data
  890.         inci MusicOffset_Triangle
  891.         ldayindirect (MusicData),y
  892.          checka
  893.         beq LoadTriCtrlReg        ;if zero, skip all this and move on to noise
  894.         bpl TriNoteHandler        ;if non-negative, data is note
  895.         jsr ProcessLengthData     ;otherwise, it is length data
  896.         sta Tri_NoteLenBuffer     ;save contents of A
  897.         ldan ++$1f
  898.         sta SND_TRIANGLE_REG      ;load some default data for triangle control reg
  899.         ldy MusicOffset_Triangle  ;fetch another byte
  900.         inci MusicOffset_Triangle
  901.         ldayindirect (MusicData),y
  902.          checka
  903.         beq LoadTriCtrlReg        ;check once more for nonzero data
  904.  
  905. TriNoteHandler:
  906.           jsr SetFreq_Tri
  907.           ldx Tri_NoteLenBuffer   ;save length in triangle note counter
  908.           stx Tri_NoteLenCounter
  909.           lda EventMusicBuffer
  910.           andn ++%01101110          ;check for death music or d4 set on secondary buffer
  911.           bne NotDOrD4            ;if playing any other secondary, skip primary buffer check
  912.           lda AreaMusicBuffer     ;check primary buffer for water or castle level music
  913.           andn ++%00001010
  914.           beq HandleNoiseMusic    ;if playing any other primary, or death or d4, go on to noise routine
  915. NotDOrD4: txa                     ;if playing water or castle music or any secondary
  916.           cmpn ++$12                ;besides death music or d4 set, check length of note
  917.               cmpcy
  918.           bcs LongN
  919.           lda EventMusicBuffer    ;check for win castle music again if not playing a long note
  920.           andn ++EndOfCastleMusic
  921.           beq MediN
  922.           ldan ++$0f                ;load value $0f if playing the win castle music and playing a short
  923.          checka
  924.           bne LoadTriCtrlReg ;unconditional???     ;note, load value $1f if playing water or castle level music or any
  925. MediN:    ldan ++$1f                ;secondary besides death and d4 except win castle or win castle and playing
  926.          checka
  927.           bne LoadTriCtrlReg ;unconditional???     ;a short note, and load value $ff if playing a long note on water, castle
  928. LongN:    ldan ++$ff                ;or any secondary (including win castle) except death and d4
  929.  
  930. LoadTriCtrlReg:          
  931.         sta SND_TRIANGLE_REG      ;save final contents of A into control reg for triangle
  932.  
  933. HandleNoiseMusic:
  934.         lda AreaMusicBuffer       ;check if playing underground or castle music
  935.         andn ++%11110011
  936.         beq ExitMusicHandler      ;if so, skip the noise routine
  937.         deci Noise_BeatLenCounter  ;decrement noise beat length
  938.         bne ExitMusicHandler      ;is it time for more data?
  939.  
  940. FetchNoiseBeatData:
  941.         ldy MusicOffset_Noise       ;increment noise beat offset and fetch data
  942.         inci MusicOffset_Noise
  943.         ldayindirect (MusicData),y           ;get noise beat data, if nonzero, branch to handle
  944.          checka
  945.         bne NoiseBeatHandler
  946.         lda NoiseDataLoopbackOfs    ;if data is zero, reload original noise beat offset
  947.         sta MusicOffset_Noise       ;and loopback next time around
  948.          checka
  949.         bne FetchNoiseBeatData      ;unconditional branch
  950.  
  951. NoiseBeatHandler:
  952.         jsr AlternateLengthHandler
  953.         sta Noise_BeatLenCounter    ;store length in noise beat counter
  954.         txa
  955.         andn ++%00111110              ;reload data and erase length bits
  956.         beq SilentBeat              ;if no beat data, silence
  957.         cmpn ++$30                    ;check the beat data and play the appropriate
  958.         beq LongBeat                ;noise accordingly
  959.         cmpn ++$20
  960.         beq StrongBeat
  961.         andn ++%00010000  
  962.         beq SilentBeat
  963.         ldan ++$1c        ;short beat data
  964.         ldxn ++$03
  965.         ldyn ++$18
  966.          checky
  967.         bne PlayBeat ;unconditional???
  968.  
  969. StrongBeat:
  970.         ldan ++$1c        ;strong beat data
  971.         ldxn ++$0c
  972.         ldyn ++$18
  973.          checky
  974.         bne PlayBeat ;unconditional???
  975.  
  976. LongBeat:
  977.         ldan ++$1c        ;long beat data
  978.         ldxn ++$03
  979.         ldyn ++$58
  980.          checky
  981.         bne PlayBeat ;unconditional???
  982.  
  983. SilentBeat:
  984.         ldan ++$10        ;silence
  985.  
  986. PlayBeat:
  987.         sta SND_NOISE_REG    ;load beat data into noise regs
  988.         stx SND_NOISE_REG+2
  989.         sty SND_NOISE_REG+3
  990.         if Z80
  991. ;write to SND_REGISTER+3 causes counter loading from a table
  992.         ld a,e
  993. wrnoise3
  994.         rra
  995.         rra
  996.         rra
  997.         and 0x1f
  998.         ld hl,tcounterload
  999.         add a,l
  1000.         ld l,a
  1001.         adc a,h
  1002.         sub l
  1003.         ld h,a
  1004.         ld a,(hl) ;читает 5, а на слух надо примерно 0x10 для музыки, для флага больше, только эффекты покороче
  1005.         add a,a
  1006.         ld (SND_COUNTER+12),a
  1007. ;Only a write out to $4003/$4007/$400F will reset the current envelope decay counter to a known state (to $F, the maximum volume level) for the appropriate channel's envelope decay hardware.
  1008.         ld a,0x0f
  1009.         ld (SND_DECAYVOL+12),a
  1010.         endif
  1011.  
  1012. ExitMusicHandler:
  1013.         rts
  1014.  
  1015. AlternateLengthHandler:
  1016.         tax            ;save a copy of original byte into X
  1017.         ror            ;save LSB from original byte into carry
  1018.         txa            ;reload original byte and rotate three times
  1019.         rol            ;turning xx00000x into 00000xxx, with the
  1020.         rol            ;bit in carry as the MSB here
  1021.         rol
  1022.  
  1023. ProcessLengthData:
  1024.         andn ++%00000111              ;clear all but the three LSBs
  1025.         clc
  1026.         adci NoteLenLookupTblOfs;SCRATCHPAD+$f0                     ;add offset loaded from first header byte
  1027.         adci NoteLengthTblAdder      ;add extra if time running out music
  1028.         tay
  1029.         lday MusicLengthLookupTbl,y  ;load length
  1030.         rts
  1031.  
  1032. LoadControlRegs:
  1033.            lda EventMusicBuffer  ;check secondary buffer for win castle music
  1034.            andn ++EndOfCastleMusic
  1035.            beq NotECstlM
  1036.            ldan ++$04              ;this value is only used for win castle music
  1037.          checka
  1038.            bne AllMus            ;unconditional branch
  1039. NotECstlM: lda AreaMusicBuffer
  1040.            andn ++%01111101        ;check primary buffer for water music
  1041.            beq WaterMus
  1042.            ldan ++$08              ;this is the default value for all other music
  1043.          checka
  1044.            bne AllMus
  1045. WaterMus:  ldan ++$28              ;this value is used for water music and all other event music
  1046. AllMus:    ldxn ++$82              ;load contents of other sound regs for square 2
  1047.            ldyn ++$7f
  1048.            rts
  1049.  
  1050. LoadEnvelopeData:
  1051.         lda EventMusicBuffer           ;check secondary buffer for win castle music
  1052.         andn ++EndOfCastleMusic
  1053.         beq LoadUsualEnvData
  1054.         lday EndOfCastleMusicEnvData,y  ;load data from offset for win castle music
  1055.         rts
  1056.  
  1057. LoadUsualEnvData:
  1058.         lda AreaMusicBuffer            ;check primary buffer for water music
  1059.         andn ++%01111101
  1060.         beq LoadWaterEventMusEnvData
  1061.         lday AreaMusicEnvData,y         ;load default data from offset for all other music
  1062.         rts
  1063.  
  1064. LoadWaterEventMusEnvData:
  1065.         lday WaterEventMusEnvData,y     ;load data from offset for water music and all other event music
  1066.         rts
  1067.