diff options
Diffstat (limited to 'audio/engine_3.asm')
-rw-r--r-- | audio/engine_3.asm | 1115 |
1 files changed, 584 insertions, 531 deletions
diff --git a/audio/engine_3.asm b/audio/engine_3.asm index cf435740..f329c0c3 100644 --- a/audio/engine_3.asm +++ b/audio/engine_3.asm @@ -3,7 +3,7 @@ Audio3_UpdateMusic:: ld c, Ch1 .loop - ld b, $0 + ld b, 0 ld hl, wChannelSoundIDs add hl, bc ld a, [hl] @@ -19,7 +19,7 @@ Audio3_UpdateMusic:: jr nz, .nextChannel set 7, a ld [wMuteAudioAndPauseMusic], a - xor a + xor a ; disable all channels' output ld [rNR51], a ld [rNR30], a ld a, $80 @@ -36,18 +36,12 @@ Audio3_UpdateMusic:: ; this routine checks flags for music effects currently applied ; to the channel and calls certain functions based on flags. -; known flags for wChannelFlags1: -; 0: toggleperfectpitch has been used -; 1: call has been used -; 3: a toggle used only by this routine for vibrato -; 4: pitchbend flag -; 6: dutycycle flag Audio3_ApplyMusicAffects: ld b, $0 ld hl, wChannelNoteDelayCounters ; delay until next note add hl, bc ld a, [hl] - cp $1 ; if delay is 1, play next note + cp $1 ; if the delay is 1, play next note jp z, Audio3_PlayNextNote dec a ; otherwise, decrease the delay timer ld [hl], a @@ -63,36 +57,36 @@ Audio3_ApplyMusicAffects: .startChecks ld hl, wChannelFlags1 add hl, bc - bit 6, [hl] ; dutycycle + bit BIT_ROTATE_DUTY_CYCLE, [hl] jr z, .checkForExecuteMusic - call Audio3_ApplyDutyCycle + call Audio3_ApplyDutyCyclePattern .checkForExecuteMusic - ld b, $0 + ld b, 0 ld hl, wChannelFlags2 add hl, bc - bit 0, [hl] - jr nz, .checkForPitchBend + bit BIT_EXECUTE_MUSIC, [hl] + jr nz, .checkForPitchSlide ld hl, wChannelFlags1 add hl, bc - bit 2, [hl] - jr nz, .disablePitchBendVibrato -.checkForPitchBend + bit BIT_NOISE_OR_SFX, [hl] + jr nz, .skipPitchSlideVibrato +.checkForPitchSlide ld hl, wChannelFlags1 add hl, bc - bit 4, [hl] ; pitchbend + bit BIT_PITCH_SLIDE_ON, [hl] jr z, .checkVibratoDelay - jp Audio3_ApplyPitchBend + jp Audio3_ApplyPitchSlide .checkVibratoDelay - ld hl, wChannelVibratoDelayCounters ; vibrato delay + ld hl, wChannelVibratoDelayCounters add hl, bc ld a, [hl] and a ; check if delay is over jr z, .checkForVibrato dec [hl] ; otherwise, dec delay -.disablePitchBendVibrato +.skipPitchSlideVibrato ret .checkForVibrato - ld hl, wChannelVibratoExtents ; vibrato rate + ld hl, wChannelVibratoExtents add hl, bc ld a, [hl] and a @@ -105,33 +99,35 @@ Audio3_ApplyMusicAffects: ld a, [hl] and $f and a - jr z, .vibratoAlreadyDone - dec [hl] ; apply vibrato pitch change + jr z, .applyVibrato + dec [hl] ; decrement counter ret -.vibratoAlreadyDone +.applyVibrato ld a, [hl] swap [hl] or [hl] - ld [hl], a ; reset the vibrato value and start again + ld [hl], a ; reload the counter ld hl, wChannelFrequencyLowBytes add hl, bc ld e, [hl] ; get note pitch ld hl, wChannelFlags1 add hl, bc - bit 3, [hl] ; this is the only code that sets/resets bit three so - jr z, .unset ; it continuously alternates which path it takes - res 3, [hl] +; This is the only code that sets/resets the vibrato direction bit, so it +; continuously alternates which path it takes. + bit BIT_VIBRATO_DIRECTION, [hl] + jr z, .unset + res BIT_VIBRATO_DIRECTION, [hl] ld a, d and $f ld d, a ld a, e sub d jr nc, .noCarry - ld a, $0 + ld a, 0 .noCarry jr .done .unset - set 3, [hl] + set BIT_VIBRATO_DIRECTION, [hl] ld a, d and $f0 swap a @@ -140,63 +136,66 @@ Audio3_ApplyMusicAffects: ld a, $ff .done ld d, a - ld b, $3 - call Audio3_7d8ac + ld b, REG_FREQUENCY_LO + call Audio3_GetRegisterPointer ld [hl], d ret ; this routine executes all music commands that take up no time, -; like tempo changes, duty changes etc. and doesn't return +; like tempo changes, duty cycle changes etc. and doesn't return ; until the first note is reached Audio3_PlayNextNote: +; reload the vibrato delay counter ld hl, wChannelVibratoDelayCounterReloadValues add hl, bc ld a, [hl] ld hl, wChannelVibratoDelayCounters add hl, bc ld [hl], a + ld hl, wChannelFlags1 add hl, bc - res 4, [hl] - res 5, [hl] - call Audio3_endchannel + res BIT_PITCH_SLIDE_ON, [hl] + res BIT_PITCH_SLIDE_DECREASING, [hl] + call Audio3_sound_ret ret -Audio3_endchannel: +Audio3_sound_ret: call Audio3_GetNextMusicByte ld d, a - cp $ff ; is this command an endchannel? - jp nz, Audio3_callchannel ; no - ld b, $0 ; yes + cp $ff ; is this command a sound_ret? + jp nz, Audio3_sound_call ; no + ld b, 0 ld hl, wChannelFlags1 add hl, bc - bit 1, [hl] + bit BIT_SOUND_CALL, [hl] jr nz, .returnFromCall ld a, c cp Ch4 jr nc, .noiseOrSfxChannel - jr .asm_7d2b3 + jr .disableChannelOutput .noiseOrSfxChannel - res 2, [hl] + res BIT_NOISE_OR_SFX, [hl] ld hl, wChannelFlags2 add hl, bc - res 0, [hl] + res BIT_EXECUTE_MUSIC, [hl] cp Ch7 - jr nz, .notSfxChannel3 + jr nz, .skipSfxChannel3 +; restart hardware channel 3 (wave channel) output ld a, $0 ld [rNR30], a ld a, $80 ld [rNR30], a -.notSfxChannel3 - jr nz, .asm_7d296 +.skipSfxChannel3 + jr nz, .dontDisable ld a, [wDisableChannelOutputWhenSfxEnds] and a - jr z, .asm_7d296 + jr z, .dontDisable xor a ld [wDisableChannelOutputWhenSfxEnds], a - jr .asm_7d2b3 -.asm_7d296 - jr .asm_7d2bc + jr .disableChannelOutput +.dontDisable + jr .afterDisable .returnFromCall res 1, [hl] ld d, $0 @@ -216,45 +215,45 @@ Audio3_endchannel: inc de ld a, [de] ld [hl], a ; loads channel address to return to - jp Audio3_endchannel -.asm_7d2b3 - ld hl, Unknown_7db93 + jp Audio3_sound_ret +.disableChannelOutput + ld hl, Audio3_HWChannelDisableMasks add hl, bc ld a, [rNR51] and [hl] ld [rNR51], a -.asm_7d2bc +.afterDisable ld a, [wChannelSoundIDs + Ch5] - cp $14 - jr nc, .asm_7d2c5 - jr .asm_7d2e2 -.asm_7d2c5 + cp CRY_SFX_START + jr nc, .maybeCry + jr .skipCry +.maybeCry ld a, [wChannelSoundIDs + Ch5] - cp $86 - jr z, .asm_7d2e2 - jr c, .asm_7d2d0 - jr .asm_7d2e2 -.asm_7d2d0 + cp CRY_SFX_END + jr z, .skipCry + jr c, .cry + jr .skipCry +.cry ld a, c cp Ch5 - jr z, .asm_7d2d9 - call Audio3_7d73b + jr z, .skipRewind + call Audio3_GoBackOneCommandIfCry ret c -.asm_7d2d9 +.skipRewind ld a, [wSavedVolume] ld [rNR50], a xor a ld [wSavedVolume], a -.asm_7d2e2 +.skipCry ld hl, wChannelSoundIDs add hl, bc ld [hl], b ret -Audio3_callchannel: - cp $fd ; is this command a callchannel? - jp nz, Audio3_loopchannel ; no - call Audio3_GetNextMusicByte ; yes +Audio3_sound_call: + cp $fd ; is this command a sound_call? + jp nz, Audio3_sound_loop ; no + call Audio3_GetNextMusicByte push af call Audio3_GetNextMusicByte ld d, a @@ -285,27 +284,27 @@ Audio3_callchannel: ld b, $0 ld hl, wChannelFlags1 add hl, bc - set 1, [hl] ; set the call flag - jp Audio3_endchannel + set BIT_SOUND_CALL, [hl] ; set the call flag + jp Audio3_sound_ret -Audio3_loopchannel: - cp $fe ; is this command a loopchannel? - jp nz, Audio3_notetype ; no - call Audio3_GetNextMusicByte ; yes +Audio3_sound_loop: + cp $fe ; is this command a sound_loop? + jp nz, Audio3_note_type ; no + call Audio3_GetNextMusicByte ld e, a and a jr z, .infiniteLoop - ld b, $0 + ld b, 0 ld hl, wChannelLoopCounters add hl, bc ld a, [hl] cp e jr nz, .loopAgain - ld a, $1 ; if no more loops to make + ld a, $1 ; if no more loops to make, ld [hl], a call Audio3_GetNextMusicByte ; skip pointer call Audio3_GetNextMusicByte - jp Audio3_endchannel + jp Audio3_sound_ret .loopAgain ; inc loop count inc a ld [hl], a @@ -324,13 +323,13 @@ Audio3_loopchannel: pop af ld [hli], a ld [hl], b - jp Audio3_endchannel + jp Audio3_sound_ret -Audio3_notetype: +Audio3_note_type: and $f0 - cp $d0 ; is this command a notetype? - jp nz, Audio3_toggleperfectpitch ; no - ld a, d ; yes + cp $d0 ; is this command a note_type? + jp nz, Audio3_toggle_perfect_pitch ; no + ld a, d and $f ld b, $0 ld hl, wChannelNoteSpeeds @@ -345,15 +344,15 @@ Audio3_notetype: cp Ch3 jr z, .musicChannel3 cp Ch7 - jr nz, .notChannel3 + jr nz, .skipChannel3 ld hl, wSfxWaveInstrument - jr .sfxChannel3 + jr .channel3 .musicChannel3 ld hl, wMusicWaveInstrument -.sfxChannel3 +.channel3 ld a, d and $f - ld [hl], a ; store low nibble of param as duty + ld [hl], a ; store low nibble of param as wave instrument ld a, d and $30 sla a @@ -362,31 +361,31 @@ Audio3_notetype: ; if channel 3, store high nibble as volume ; else, store volume (high nibble) and fade (low nibble) -.notChannel3 - ld b, $0 +.skipChannel3 + ld b, 0 ld hl, wChannelVolumes add hl, bc ld [hl], d .noiseChannel - jp Audio3_endchannel + jp Audio3_sound_ret -Audio3_toggleperfectpitch: +Audio3_toggle_perfect_pitch: ld a, d - cp $e8 ; is this command a toggleperfectpitch? + cp $e8 ; is this command a toggle_perfect_pitch? jr nz, Audio3_vibrato ; no - ld b, $0 ; yes + ld b, 0 ld hl, wChannelFlags1 add hl, bc ld a, [hl] xor $1 ld [hl], a ; flip bit 0 of wChannelFlags1 - jp Audio3_endchannel + jp Audio3_sound_ret Audio3_vibrato: cp $ea ; is this command a vibrato? - jr nz, Audio3_pitchbend ; no - call Audio3_GetNextMusicByte ; yes - ld b, $0 + jr nz, Audio3_pitch_slide ; no + call Audio3_GetNextMusicByte + ld b, 0 ld hl, wChannelVibratoDelayCounters add hl, bc ld [hl], a ; store delay @@ -395,9 +394,16 @@ Audio3_vibrato: ld [hl], a ; store delay call Audio3_GetNextMusicByte ld d, a + +; The high nybble of the command byte is the extent of the vibrato. +; Let n be the extent. +; The upper nybble of the channel's byte in the wChannelVibratoExtents +; array will store the extent above the note: (n / 2) + (n % 2). +; The lower nybble will store the extent below the note: (n / 2). +; These two values add to the total extent, n. and $f0 swap a - ld b, $0 + ld b, 0 ld hl, wChannelVibratoExtents add hl, bc srl a @@ -405,7 +411,13 @@ Audio3_vibrato: adc b swap a or e - ld [hl], a ; store rate as both high and low nibbles + ld [hl], a + +; The low nybble of the command byte is the rate of the vibrato. +; The high and low nybbles of the channel's byte in the wChannelVibratoRates +; array are both initialised to this value because the high nybble is the +; counter reload value and the low nybble is the counter itself, which should +; start at its value upon reload. ld a, d and $f ld d, a @@ -413,17 +425,18 @@ Audio3_vibrato: add hl, bc swap a or d - ld [hl], a ; store depth as both high and low nibbles - jp Audio3_endchannel + ld [hl], a -Audio3_pitchbend: - cp $eb ; is this command a pitchbend? - jr nz, Audio3_duty ; no - call Audio3_GetNextMusicByte ; yes - ld b, $0 - ld hl, wChannelPitchBendLengthModifiers + jp Audio3_sound_ret + +Audio3_pitch_slide: + cp $eb ; is this command a pitch_slide? + jr nz, Audio3_duty_cycle ; no + call Audio3_GetNextMusicByte + ld b, 0 + ld hl, wChannelPitchSlideLengthModifiers add hl, bc - ld [hl], a ; store first param + ld [hl], a call Audio3_GetNextMusicByte ld d, a and $f0 @@ -431,39 +444,39 @@ Audio3_pitchbend: ld b, a ld a, d and $f - call Audio3_7d8cc - ld b, $0 - ld hl, wChannelPitchBendTargetFrequencyHighBytes + call Audio3_CalculateFrequency + ld b, 0 + ld hl, wChannelPitchSlideTargetFrequencyHighBytes add hl, bc - ld [hl], d ; store unknown part of second param - ld hl, wChannelPitchBendTargetFrequencyLowBytes + ld [hl], d + ld hl, wChannelPitchSlideTargetFrequencyLowBytes add hl, bc - ld [hl], e ; store unknown part of second param - ld b, $0 + ld [hl], e + ld b, 0 ld hl, wChannelFlags1 add hl, bc - set 4, [hl] ; set pitchbend flag + set BIT_PITCH_SLIDE_ON, [hl] call Audio3_GetNextMusicByte ld d, a - jp Audio3_notelength + jp Audio3_note_length -Audio3_duty: - cp $ec ; is this command a duty? +Audio3_duty_cycle: + cp $ec ; is this command a duty_cycle? jr nz, Audio3_tempo ; no - call Audio3_GetNextMusicByte ; yes + call Audio3_GetNextMusicByte rrca rrca and $c0 - ld b, $0 - ld hl, wChannelDuties + ld b, 0 + ld hl, wChannelDutyCycles add hl, bc - ld [hl], a ; store duty - jp Audio3_endchannel + ld [hl], a ; store duty cycle + jp Audio3_sound_ret Audio3_tempo: cp $ed ; is this command a tempo? - jr nz, Audio3_stereopanning ; no - ld a, c ; yes + jr nz, Audio3_stereo_panning ; no + ld a, c cp Ch5 jr nc, .sfxChannel call Audio3_GetNextMusicByte @@ -487,20 +500,20 @@ Audio3_tempo: ld [wChannelNoteDelayCountersFractionalPart + 6], a ld [wChannelNoteDelayCountersFractionalPart + 7], a .musicChannelDone - jp Audio3_endchannel + jp Audio3_sound_ret -Audio3_stereopanning: - cp $ee ; is this command a stereopanning? +Audio3_stereo_panning: + cp $ee ; is this command a stereo_panning? jr nz, Audio3_unknownmusic0xef ; no - call Audio3_GetNextMusicByte ; yes + call Audio3_GetNextMusicByte ld [wStereoPanning], a ; store panning - jp Audio3_endchannel + jp Audio3_sound_ret ; this appears to never be used Audio3_unknownmusic0xef: cp $ef ; is this command an unknownmusic0xef? - jr nz, Audio3_dutycycle ; no - call Audio3_GetNextMusicByte ; yes + jr nz, Audio3_duty_cycle_pattern ; no + call Audio3_GetNextMusicByte push bc call Audio3_PlaySound pop bc @@ -512,124 +525,141 @@ Audio3_unknownmusic0xef: xor a ld [wChannelSoundIDs + Ch8], a .skip - jp Audio3_endchannel + jp Audio3_sound_ret -Audio3_dutycycle: - cp $fc ; is this command a dutycycle? +Audio3_duty_cycle_pattern: + cp $fc ; is this command a duty_cycle_pattern? jr nz, Audio3_volume ; no - call Audio3_GetNextMusicByte ; yes - ld b, $0 - ld hl, wChannelDutyCycles + call Audio3_GetNextMusicByte + ld b, 0 + ld hl, wChannelDutyCyclePatterns add hl, bc - ld [hl], a ; store full cycle - and $c0 - ld hl, wChannelDuties + ld [hl], a ; store full pattern + and %11000000 + ld hl, wChannelDutyCycles add hl, bc - ld [hl], a ; store first duty + ld [hl], a ; store first duty cycle ld hl, wChannelFlags1 add hl, bc - set 6, [hl] ; set duty flag - jp Audio3_endchannel + set BIT_ROTATE_DUTY_CYCLE, [hl] + jp Audio3_sound_ret Audio3_volume: cp $f0 ; is this command a volume? - jr nz, Audio3_executemusic ; no - call Audio3_GetNextMusicByte ; yes + jr nz, Audio3_execute_music ; no + call Audio3_GetNextMusicByte ld [rNR50], a ; store volume - jp Audio3_endchannel + jp Audio3_sound_ret -Audio3_executemusic: - cp $f8 ; is this command an executemusic? +Audio3_execute_music: + cp $f8 ; is this command an execute_music? jr nz, Audio3_octave ; no - ld b, $0 ; yes + ld b, $0 ld hl, wChannelFlags2 add hl, bc - set 0, [hl] - jp Audio3_endchannel + set BIT_EXECUTE_MUSIC, [hl] + jp Audio3_sound_ret Audio3_octave: and $f0 cp $e0 ; is this command an octave? - jr nz, Audio3_sfxnote ; no - ld hl, wChannelOctaves ; yes - ld b, $0 + jr nz, Audio3_sfx_note ; no + ld hl, wChannelOctaves + ld b, 0 add hl, bc ld a, d and $f ld [hl], a ; store low nibble as octave - jp Audio3_endchannel + jp Audio3_sound_ret -; sfxnote is either squarenote or noisenote depending on the channel -Audio3_sfxnote: - cp $20 ; is this command an sfxnote? - jr nz, Audio3_pitchenvelope ; no +; sfx_note is either square_note or noise_note depending on the channel +Audio3_sfx_note: + cp $20 ; is this command a sfx_note? + jr nz, Audio3_pitch_sweep ld a, c cp Ch4 ; is this a noise or sfx channel? - jr c, Audio3_pitchenvelope ; no - ld b, $0 + jr c, Audio3_pitch_sweep ; no + ld b, 0 ld hl, wChannelFlags2 add hl, bc - bit 0, [hl] - jr nz, Audio3_pitchenvelope ; no - call Audio3_notelength ; yes + bit BIT_EXECUTE_MUSIC, [hl] ; is execute_music being used? + jr nz, Audio3_pitch_sweep ; yes + call Audio3_note_length + +; This code seems to do the same thing as what Audio3_ApplyDutyCycleAndSoundLength +; does below. ld d, a - ld b, $0 - ld hl, wChannelDuties + ld b, 0 + ld hl, wChannelDutyCycles add hl, bc ld a, [hl] or d ld d, a - ld b, $1 - call Audio3_7d8ac + ld b, REG_DUTY_SOUND_LEN + call Audio3_GetRegisterPointer ld [hl], d + call Audio3_GetNextMusicByte ld d, a - ld b, $2 - call Audio3_7d8ac + ld b, REG_VOLUME_ENVELOPE + call Audio3_GetRegisterPointer ld [hl], d call Audio3_GetNextMusicByte ld e, a ld a, c cp Ch8 - ld a, $0 - jr z, .sfxNoiseChannel ; only two params for noise channel + ld a, 0 + jr z, .skip +; Channels 1 through 3 have 2 registers that control frequency, but the noise +; channel a single register (the polynomial counter) that controls frequency, +; so this command has one less byte on the noise channel. push de call Audio3_GetNextMusicByte pop de -.sfxNoiseChannel +.skip ld d, a push de - call Audio3_7d69d - call Audio3_7d66c + call Audio3_ApplyDutyCycleAndSoundLength + call Audio3_EnableChannelOutput pop de - call Audio3_7d6bf + call Audio3_ApplyWavePatternAndFrequency ret -Audio3_pitchenvelope: +Audio3_pitch_sweep: ld a, c cp Ch5 jr c, Audio3_note ; if not a sfx ld a, d - cp $10 ; is this command an pitchenvelope? + cp $10 ; is this command a pitch_sweep? jr nz, Audio3_note ; no ld b, $0 ld hl, wChannelFlags2 add hl, bc - bit 0, [hl] + bit BIT_EXECUTE_MUSIC, [hl] jr nz, Audio3_note ; no - call Audio3_GetNextMusicByte ; yes + call Audio3_GetNextMusicByte ld [rNR10], a - jp Audio3_endchannel + jp Audio3_sound_ret Audio3_note: ld a, c cp Ch4 - jr nz, Audio3_notelength ; if not noise channel + jr nz, Audio3_note_length ; if not noise channel ld a, d and $f0 cp $b0 ; is this command a dnote? - jr z, Audio3_dnote ; yes - jr nc, Audio3_notelength ; no + jr z, .dnote + jr nc, Audio3_note_length ; no + + ; this executes when on the noise channel and + ; the command id is less than $b0 + ; in this case, the upper nybble is used as the noise instrument ($1-$a) + ; and the lower nybble is the length minus 1 (0-15) + ; however, this doesn't work for instrument #2 because the command id + ; is captured by the noise_note command (command id $2x) + ; this essentially acts like a dnote command that is only 1 byte + ; instead of 2 and can only be used with instruments 1 and 3 through 10 + ; this is unused by the game swap a ld b, a ld a, d @@ -638,38 +668,38 @@ Audio3_note: ld a, b push de push bc - jr asm_7d571 + jr .playDnote -Audio3_dnote: +.dnote ld a, d and $f push af push bc call Audio3_GetNextMusicByte ; get dnote instrument -asm_7d571 +.playDnote ld d, a ld a, [wDisableChannelOutputWhenSfxEnds] and a - jr nz, .asm_7d57c + jr nz, .skipDnote ld a, d call Audio3_PlaySound -.asm_7d57c +.skipDnote pop bc pop de -Audio3_notelength: +Audio3_note_length: ld a, d push af and $f inc a - ld b, $0 + ld b, 0 ld e, a ; store note length (in 16ths) ld d, b ld hl, wChannelNoteSpeeds add hl, bc ld a, [hl] ld l, b - call Audio3_7d8bb + call Audio3_MultiplyAdd ld a, c cp Ch5 jr nc, .sfxChannel @@ -683,20 +713,20 @@ Audio3_notelength: ld e, $0 cp Ch8 jr z, .skip ; if noise channel - call Audio3_7d707 + call Audio3_SetSfxTempo ld a, [wSfxTempo] ld d, a ld a, [wSfxTempo + 1] ld e, a .skip - ld a, l - ld b, $0 + ld a, l ; a = note_length * note_speed + ld b, 0 ld hl, wChannelNoteDelayCountersFractionalPart add hl, bc ld l, [hl] - call Audio3_7d8bb + call Audio3_MultiplyAdd ld e, l - ld d, h + ld d, h ; de = note_delay_frac_part + (note_length * note_speed * tempo) ld hl, wChannelNoteDelayCountersFractionalPart add hl, bc ld [hl], e @@ -706,192 +736,198 @@ Audio3_notelength: ld [hl], a ld hl, wChannelFlags2 add hl, bc - bit 0, [hl] - jr nz, Audio3_notepitch + bit BIT_EXECUTE_MUSIC, [hl] + jr nz, Audio3_note_pitch ld hl, wChannelFlags1 add hl, bc - bit 2, [hl] - jr z, Audio3_notepitch + bit BIT_NOISE_OR_SFX, [hl] + jr z, Audio3_note_pitch pop hl ret -Audio3_notepitch: +Audio3_note_pitch: pop af and $f0 cp $c0 ; compare to rest jr nz, .notRest ld a, c cp Ch5 - jr nc, .sfxChannel + jr nc, .next +; If this isn't an SFX channel, try the corresponding SFX channel. ld hl, wChannelSoundIDs + Ch5 add hl, bc ld a, [hl] and a - jr nz, .quit + jr nz, .done ; fall through -.sfxChannel +.next ld a, c cp Ch3 - jr z, .musicChannel3 + jr z, .channel3 cp Ch7 - jr nz, .notSfxChannel3 -.musicChannel3 - ld b, $0 - ld hl, Unknown_7db93 + jr nz, .notChannel3 +.channel3 + ld b, 0 + ld hl, Audio3_HWChannelDisableMasks add hl, bc ld a, [rNR51] and [hl] - ld [rNR51], a - jr .quit -.notSfxChannel3 - ld b, $2 - call Audio3_7d8ac - ld a, $8 + ld [rNR51], a ; disable hardware channel 3's output + jr .done +.notChannel3 + ld b, REG_VOLUME_ENVELOPE + call Audio3_GetRegisterPointer + ld a, $8 ; fade in sound ld [hli], a inc hl - ld a, $80 + ld a, $80 ; restart sound ld [hl], a -.quit +.done ret .notRest swap a - ld b, $0 + ld b, 0 ld hl, wChannelOctaves add hl, bc ld b, [hl] - call Audio3_7d8cc - ld b, $0 + call Audio3_CalculateFrequency + ld b, 0 ld hl, wChannelFlags1 add hl, bc - bit 4, [hl] - jr z, .asm_7d62c - call Audio3_7d803 -.asm_7d62c + bit BIT_PITCH_SLIDE_ON, [hl] + jr z, .skipPitchSlide + call Audio3_InitPitchSlideVars +.skipPitchSlide push de ld a, c cp Ch5 - jr nc, .skip ; if sfx Channel + jr nc, .sfxChannel ; if sfx channel +; If this isn't an SFX channel, try the corresponding SFX channel. ld hl, wChannelSoundIDs + Ch5 - ld d, $0 + ld d, 0 ld e, a add hl, de ld a, [hl] and a - jr nz, .done - jr .skip -.done + jr nz, .noSfx + jr .sfxChannel +.noSfx pop de ret -.skip - ld b, $0 +.sfxChannel + ld b, 0 ld hl, wChannelVolumes add hl, bc ld d, [hl] - ld b, $2 - call Audio3_7d8ac + ld b, REG_VOLUME_ENVELOPE + call Audio3_GetRegisterPointer ld [hl], d - call Audio3_7d69d - call Audio3_7d66c + call Audio3_ApplyDutyCycleAndSoundLength + call Audio3_EnableChannelOutput pop de ld b, $0 ld hl, wChannelFlags1 add hl, bc - bit 0, [hl] ; has toggleperfectpitch been used? - jr z, .skip2 - inc e ; if yes, increment the pitch by 1 - jr nc, .skip2 + bit BIT_PERFECT_PITCH, [hl] ; has toggle_perfect_pitch been used? + jr z, .skipFrequencyInc + inc e ; if yes, increment the frequency by 1 + jr nc, .skipFrequencyInc inc d -.skip2 +.skipFrequencyInc ld hl, wChannelFrequencyLowBytes add hl, bc ld [hl], e - call Audio3_7d6bf + call Audio3_ApplyWavePatternAndFrequency ret -Audio3_7d66c: - ld b, $0 - ld hl, Unknown_7db9b +Audio3_EnableChannelOutput: + ld b, 0 + ld hl, Audio3_HWChannelEnableMasks add hl, bc ld a, [rNR51] - or [hl] + or [hl] ; set this channel's bits ld d, a ld a, c cp Ch8 - jr z, .sfxNoiseChannel + jr z, .noiseChannelOrNoSfx cp Ch5 jr nc, .skip ; if sfx channel +; If this isn't an SFX channel, try the corresponding SFX channel. ld hl, wChannelSoundIDs + Ch5 add hl, bc ld a, [hl] and a jr nz, .skip -.sfxNoiseChannel +.noiseChannelOrNoSfx +; If this is the SFX noise channel or a music channel whose corresponding +; SFX channel is off, apply stereo panning. ld a, [wStereoPanning] - ld hl, Unknown_7db9b + ld hl, Audio3_HWChannelEnableMasks add hl, bc and [hl] ld d, a ld a, [rNR51] - ld hl, Unknown_7db93 + ld hl, Audio3_HWChannelDisableMasks add hl, bc - and [hl] - or d + and [hl] ; reset this channel's output bits + or d ; set this channel's output bits that enabled in [wStereoPanning] ld d, a .skip ld a, d ld [rNR51], a ret -Audio3_7d69d: - ld b, $0 - ld hl, wChannelNoteDelayCounters +Audio3_ApplyDutyCycleAndSoundLength: + ld b, 0 + ld hl, wChannelNoteDelayCounters ; use the note delay as sound length add hl, bc ld d, [hl] ld a, c cp Ch3 - jr z, .channel3 ; if music channel 3 + jr z, .skipDuty ; if music channel 3 cp Ch7 - jr z, .channel3 ; if sfx channel 3 + jr z, .skipDuty ; if sfx channel 3 +; include duty cycle (except on channel 3 which doesn't have it) ld a, d and $3f ld d, a - ld hl, wChannelDuties + ld hl, wChannelDutyCycles add hl, bc ld a, [hl] or d ld d, a -.channel3 - ld b, $1 - call Audio3_7d8ac +.skipDuty + ld b, REG_DUTY_SOUND_LEN + call Audio3_GetRegisterPointer ld [hl], d ret -Audio3_7d6bf: +Audio3_ApplyWavePatternAndFrequency: ld a, c cp Ch3 jr z, .channel3 cp Ch7 - jr nz, .notSfxChannel3 + jr nz, .notChannel3 ; fall through .channel3 push de ld de, wMusicWaveInstrument cp Ch3 - jr z, .musicChannel3 + jr z, .next ld de, wSfxWaveInstrument -.musicChannel3 +.next ld a, [de] add a - ld d, $0 + ld d, 0 ld e, a ld hl, Audio3_WavePointers add hl, de ld e, [hl] inc hl ld d, [hl] - ld hl, $ff30 + ld hl, $ff30 ; wave pattern RAM ld b, $f - ld a, $0 + ld a, $0 ; stop hardware channel 3 ld [rNR30], a .loop ld a, [de] @@ -901,152 +937,155 @@ Audio3_7d6bf: dec b and a jr nz, .loop - ld a, $80 + ld a, $80 ; start hardware channel 3 ld [rNR30], a pop de -.notSfxChannel3 +.notChannel3 ld a, d - or $80 - and $c7 + or $80 ; use counter mode (i.e. disable output when the counter reaches 0) + and $c7 ; zero the unused bits in the register ld d, a - ld b, $3 - call Audio3_7d8ac - ld [hl], e + ld b, REG_FREQUENCY_LO + call Audio3_GetRegisterPointer + ld [hl], e ; store frequency low byte inc hl - ld [hl], d - call Audio3_7d729 + ld [hl], d ; store frequency high byte + call Audio3_ApplyFrequencyModifier ret -Audio3_7d707: - call Audio3_7d759 - jr nc, .asm_7d71f - ld d, $0 +Audio3_SetSfxTempo: + call Audio3_IsCry + jr nc, .notCry + ld d, 0 ld a, [wTempoModifier] add $80 - jr nc, .asm_7d716 + jr nc, .next inc d -.asm_7d716 +.next ld [wSfxTempo + 1], a ld a, d ld [wSfxTempo], a - jr .asm_7d728 -.asm_7d71f + jr .done +.notCry xor a ld [wSfxTempo + 1], a ld a, $1 ld [wSfxTempo], a -.asm_7d728 +.done ret -Audio3_7d729: - call Audio3_7d759 - jr nc, .asm_7d73a +Audio3_ApplyFrequencyModifier: + call Audio3_IsCry + jr nc, .done +; if playing a cry, add the cry's frequency modifier ld a, [wFrequencyModifier] add e - jr nc, .asm_7d735 + jr nc, .noCarry inc d -.asm_7d735 +.noCarry dec hl ld e, a ld [hl], e inc hl ld [hl], d -.asm_7d73a +.done ret -Audio3_7d73b: - call Audio3_7d759 - jr nc, .asm_7d756 +Audio3_GoBackOneCommandIfCry: + call Audio3_IsCry + jr nc, .done ld hl, wChannelCommandPointers ld e, c - ld d, $0 + ld d, 0 sla e rl d add hl, de ld a, [hl] - sub $1 + sub 1 ld [hl], a inc hl ld a, [hl] - sbc $0 + sbc 0 ld [hl], a scf ret -.asm_7d756 +.done scf ccf ret -Audio3_7d759: +Audio3_IsCry: +; Returns whether the currently playing audio is a cry in carry. ld a, [wChannelSoundIDs + Ch5] - cp $14 - jr nc, .asm_7d762 - jr .asm_7d768 -.asm_7d762 - cp $86 - jr z, .asm_7d768 - jr c, .asm_7d76b -.asm_7d768 + cp CRY_SFX_START + jr nc, .next + jr .no +.next + cp CRY_SFX_END + jr z, .no + jr c, .yes +.no scf ccf ret -.asm_7d76b +.yes scf ret -Audio3_ApplyPitchBend: +Audio3_ApplyPitchSlide: ld hl, wChannelFlags1 add hl, bc - bit 5, [hl] - jp nz, .asm_7d7b4 - ld hl, wChannelPitchBendCurrentFrequencyLowBytes + bit BIT_PITCH_SLIDE_DECREASING, [hl] + jp nz, .frequencyDecreasing +; frequency increasing + ld hl, wChannelPitchSlideCurrentFrequencyLowBytes add hl, bc ld e, [hl] - ld hl, wChannelPitchBendCurrentFrequencyHighBytes + ld hl, wChannelPitchSlideCurrentFrequencyHighBytes add hl, bc ld d, [hl] - ld hl, wChannelPitchBendFrequencySteps + ld hl, wChannelPitchSlideFrequencySteps add hl, bc ld l, [hl] ld h, b add hl, de ld d, h ld e, l - ld hl, wChannelPitchBendCurrentFrequencyFractionalPart + ld hl, wChannelPitchSlideCurrentFrequencyFractionalPart add hl, bc push hl - ld hl, wChannelPitchBendFrequencyStepsFractionalPart + ld hl, wChannelPitchSlideFrequencyStepsFractionalPart add hl, bc ld a, [hl] pop hl add [hl] ld [hl], a - ld a, $0 + ld a, 0 adc e ld e, a - ld a, $0 + ld a, 0 adc d ld d, a - ld hl, wChannelPitchBendTargetFrequencyHighBytes + ld hl, wChannelPitchSlideTargetFrequencyHighBytes add hl, bc ld a, [hl] cp d - jp c, .asm_7d7fa - jr nz, .asm_7d7e7 - ld hl, wChannelPitchBendTargetFrequencyLowBytes + jp c, .reachedTargetFrequency + jr nz, .applyUpdatedFrequency + ld hl, wChannelPitchSlideTargetFrequencyLowBytes add hl, bc ld a, [hl] cp e - jp c, .asm_7d7fa - jr .asm_7d7e7 -.asm_7d7b4 - ld hl, wChannelPitchBendCurrentFrequencyLowBytes + jp c, .reachedTargetFrequency + jr .applyUpdatedFrequency +.frequencyDecreasing + ld hl, wChannelPitchSlideCurrentFrequencyLowBytes add hl, bc ld a, [hl] - ld hl, wChannelPitchBendCurrentFrequencyHighBytes + ld hl, wChannelPitchSlideCurrentFrequencyHighBytes add hl, bc ld d, [hl] - ld hl, wChannelPitchBendFrequencySteps + ld hl, wChannelPitchSlideFrequencySteps add hl, bc ld e, [hl] sub e @@ -1054,7 +1093,7 @@ Audio3_ApplyPitchBend: ld a, d sbc b ld d, a - ld hl, wChannelPitchBendFrequencyStepsFractionalPart + ld hl, wChannelPitchSlideFrequencyStepsFractionalPart add hl, bc ld a, [hl] add a @@ -1065,129 +1104,140 @@ Audio3_ApplyPitchBend: ld a, d sbc b ld d, a - ld hl, wChannelPitchBendTargetFrequencyHighBytes + ld hl, wChannelPitchSlideTargetFrequencyHighBytes add hl, bc ld a, d cp [hl] - jr c, .asm_7d7fa - jr nz, .asm_7d7e7 - ld hl, wChannelPitchBendTargetFrequencyLowBytes + jr c, .reachedTargetFrequency + jr nz, .applyUpdatedFrequency + ld hl, wChannelPitchSlideTargetFrequencyLowBytes add hl, bc ld a, e cp [hl] - jr c, .asm_7d7fa -.asm_7d7e7 - ld hl, wChannelPitchBendCurrentFrequencyLowBytes + jr c, .reachedTargetFrequency +.applyUpdatedFrequency + ld hl, wChannelPitchSlideCurrentFrequencyLowBytes add hl, bc ld [hl], e - ld hl, wChannelPitchBendCurrentFrequencyHighBytes + ld hl, wChannelPitchSlideCurrentFrequencyHighBytes add hl, bc ld [hl], d - ld b, $3 - call Audio3_7d8ac + ld b, REG_FREQUENCY_LO + call Audio3_GetRegisterPointer ld a, e ld [hli], a ld [hl], d ret -.asm_7d7fa +.reachedTargetFrequency +; Turn off pitch slide when the target frequency has been reached. ld hl, wChannelFlags1 add hl, bc - res 4, [hl] - res 5, [hl] + res BIT_PITCH_SLIDE_ON, [hl] + res BIT_PITCH_SLIDE_DECREASING, [hl] ret -Audio3_7d803: - ld hl, wChannelPitchBendCurrentFrequencyHighBytes +Audio3_InitPitchSlideVars: + ld hl, wChannelPitchSlideCurrentFrequencyHighBytes add hl, bc ld [hl], d - ld hl, wChannelPitchBendCurrentFrequencyLowBytes + ld hl, wChannelPitchSlideCurrentFrequencyLowBytes add hl, bc ld [hl], e ld hl, wChannelNoteDelayCounters add hl, bc ld a, [hl] - ld hl, wChannelPitchBendLengthModifiers + ld hl, wChannelPitchSlideLengthModifiers add hl, bc sub [hl] - jr nc, .asm_7d81b - ld a, $1 -.asm_7d81b + jr nc, .next + ld a, 1 +.next ld [hl], a - ld hl, wChannelPitchBendTargetFrequencyLowBytes + ld hl, wChannelPitchSlideTargetFrequencyLowBytes add hl, bc ld a, e sub [hl] ld e, a ld a, d sbc b - ld hl, wChannelPitchBendTargetFrequencyHighBytes + ld hl, wChannelPitchSlideTargetFrequencyHighBytes add hl, bc sub [hl] - jr c, .asm_7d837 + jr c, .targetFrequencyGreater ld d, a - ld b, $0 + ld b, 0 ld hl, wChannelFlags1 add hl, bc - set 5, [hl] - jr .asm_7d85a -.asm_7d837 - ld hl, wChannelPitchBendCurrentFrequencyHighBytes + set BIT_PITCH_SLIDE_DECREASING, [hl] + jr .next2 +.targetFrequencyGreater +; If the target frequency is greater, subtract the current frequency from +; the target frequency to get the absolute difference. + ld hl, wChannelPitchSlideCurrentFrequencyHighBytes add hl, bc ld d, [hl] - ld hl, wChannelPitchBendCurrentFrequencyLowBytes + ld hl, wChannelPitchSlideCurrentFrequencyLowBytes add hl, bc ld e, [hl] - ld hl, wChannelPitchBendTargetFrequencyLowBytes + ld hl, wChannelPitchSlideTargetFrequencyLowBytes add hl, bc ld a, [hl] sub e ld e, a + +; Bug. Instead of borrowing from the high byte of the target frequency as it +; should, it borrows from the high byte of the current frequency instead. +; This means that the result will be 0x200 greater than it should be if the +; low byte of the current frequency is greater than the low byte of the +; target frequency. ld a, d sbc b ld d, a - ld hl, wChannelPitchBendTargetFrequencyHighBytes + + ld hl, wChannelPitchSlideTargetFrequencyHighBytes add hl, bc ld a, [hl] sub d ld d, a - ld b, $0 + ld b, 0 ld hl, wChannelFlags1 add hl, bc - res 5, [hl] -.asm_7d85a - ld hl, wChannelPitchBendLengthModifiers + res BIT_PITCH_SLIDE_DECREASING, [hl] + +.next2 + ld hl, wChannelPitchSlideLengthModifiers add hl, bc -.asm_7d85e +.divideLoop inc b ld a, e sub [hl] ld e, a - jr nc, .asm_7d85e + jr nc, .divideLoop ld a, d and a - jr z, .asm_7d86c + jr z, .doneDividing dec a ld d, a - jr .asm_7d85e -.asm_7d86c - ld a, e + jr .divideLoop +.doneDividing + ld a, e ; a = remainder - dividend add [hl] - ld d, b - ld b, $0 - ld hl, wChannelPitchBendFrequencySteps + ld d, b ; d = quotient + 1 + ld b, 0 + ld hl, wChannelPitchSlideFrequencySteps add hl, bc - ld [hl], d - ld hl, wChannelPitchBendFrequencyStepsFractionalPart + ld [hl], d ; store quotient + 1 + ld hl, wChannelPitchSlideFrequencyStepsFractionalPart add hl, bc - ld [hl], a - ld hl, wChannelPitchBendCurrentFrequencyFractionalPart + ld [hl], a ; store remainder - dividend + ld hl, wChannelPitchSlideCurrentFrequencyFractionalPart add hl, bc - ld [hl], a + ld [hl], a ; store remainder - dividend ret -Audio3_ApplyDutyCycle: - ld b, $0 - ld hl, wChannelDutyCycles +Audio3_ApplyDutyCyclePattern: + ld b, 0 + ld hl, wChannelDutyCyclePatterns add hl, bc ld a, [hl] rlca @@ -1195,8 +1245,8 @@ Audio3_ApplyDutyCycle: ld [hl], a and $c0 ld d, a - ld b, $1 - call Audio3_7d8ac + ld b, REG_DUTY_SOUND_LEN + call Audio3_GetRegisterPointer ld a, [hl] and $3f or d @@ -1204,7 +1254,7 @@ Audio3_ApplyDutyCycle: ret Audio3_GetNextMusicByte: - ld d, $0 + ld d, 0 ld a, c add a ld e, a @@ -1221,9 +1271,10 @@ Audio3_GetNextMusicByte: ld [hl], d ret -Audio3_7d8ac: +Audio3_GetRegisterPointer: +; hl = address of hardware sound register b for software channel c ld a, c - ld hl, Unknown_7db8b + ld hl, Audio3_HWChannelBaseAddresses add l jr nc, .noCarry inc h @@ -1235,13 +1286,14 @@ Audio3_7d8ac: ld h, $ff ret -Audio3_7d8bb: - ld h, $0 +Audio3_MultiplyAdd: +; hl = l + (a * de) + ld h, 0 .loop srl a - jr nc, .noCarry + jr nc, .skipAdd add hl, de -.noCarry +.skipAdd sla e rl d and a @@ -1250,8 +1302,9 @@ Audio3_7d8bb: .done ret -Audio3_7d8cc: - ld h, $0 +Audio3_CalculateFrequency: +; return the frequency for note a, octave b in de + ld h, 0 ld l, a add hl, hl ld d, h @@ -1263,14 +1316,14 @@ Audio3_7d8cc: ld d, [hl] ld a, b .loop - cp $7 + cp 7 jr z, .done sra d rr e inc a jr .loop .done - ld a, $8 + ld a, 8 add d ld d, a ret @@ -1278,14 +1331,15 @@ Audio3_7d8cc: Audio3_PlaySound:: ld [wSoundID], a cp $ff - jp z, Audio3_7daa8 - cp $c2 - jp z, Audio3_7d9c2 - jp c, Audio3_7d9c2 + jp z, .stopAllAudio + cp MAX_SFX_ID_3 + jp z, .playSfx + jp c, .playSfx cp $fe - jr z, .asm_7d901 - jp nc, Audio3_7d9c2 -.asm_7d901 + jr z, .playMusic + jp nc, .playSfx + +.playMusic xor a ld [wUnusedC000], a ld [wDisableChannelOutputWhenSfxEnds], a @@ -1294,53 +1348,53 @@ Audio3_PlaySound:: ld [wSfxWaveInstrument], a ld d, $8 ld hl, wChannelReturnAddresses - call FillAudioRAM3 + call .FillMem ld hl, wChannelCommandPointers - call FillAudioRAM3 + call .FillMem ld d, $4 ld hl, wChannelSoundIDs - call FillAudioRAM3 + call .FillMem ld hl, wChannelFlags1 - call FillAudioRAM3 - ld hl, wChannelDuties - call FillAudioRAM3 + call .FillMem ld hl, wChannelDutyCycles - call FillAudioRAM3 + call .FillMem + ld hl, wChannelDutyCyclePatterns + call .FillMem ld hl, wChannelVibratoDelayCounters - call FillAudioRAM3 + call .FillMem ld hl, wChannelVibratoExtents - call FillAudioRAM3 + call .FillMem ld hl, wChannelVibratoRates - call FillAudioRAM3 + call .FillMem ld hl, wChannelFrequencyLowBytes - call FillAudioRAM3 + call .FillMem ld hl, wChannelVibratoDelayCounterReloadValues - call FillAudioRAM3 + call .FillMem ld hl, wChannelFlags2 - call FillAudioRAM3 - ld hl, wChannelPitchBendLengthModifiers - call FillAudioRAM3 - ld hl, wChannelPitchBendFrequencySteps - call FillAudioRAM3 - ld hl, wChannelPitchBendFrequencyStepsFractionalPart - call FillAudioRAM3 - ld hl, wChannelPitchBendCurrentFrequencyFractionalPart - call FillAudioRAM3 - ld hl, wChannelPitchBendCurrentFrequencyHighBytes - call FillAudioRAM3 - ld hl, wChannelPitchBendCurrentFrequencyLowBytes - call FillAudioRAM3 - ld hl, wChannelPitchBendTargetFrequencyHighBytes - call FillAudioRAM3 - ld hl, wChannelPitchBendTargetFrequencyLowBytes - call FillAudioRAM3 + call .FillMem + ld hl, wChannelPitchSlideLengthModifiers + call .FillMem + ld hl, wChannelPitchSlideFrequencySteps + call .FillMem + ld hl, wChannelPitchSlideFrequencyStepsFractionalPart + call .FillMem + ld hl, wChannelPitchSlideCurrentFrequencyFractionalPart + call .FillMem + ld hl, wChannelPitchSlideCurrentFrequencyHighBytes + call .FillMem + ld hl, wChannelPitchSlideCurrentFrequencyLowBytes + call .FillMem + ld hl, wChannelPitchSlideTargetFrequencyHighBytes + call .FillMem + ld hl, wChannelPitchSlideTargetFrequencyLowBytes + call .FillMem ld a, $1 ld hl, wChannelLoopCounters - call FillAudioRAM3 + call .FillMem ld hl, wChannelNoteDelayCounters - call FillAudioRAM3 + call .FillMem ld hl, wChannelNoteSpeeds - call FillAudioRAM3 + call .FillMem ld [wMusicTempo], a ld a, $ff ld [wStereoPanning], a @@ -1348,7 +1402,7 @@ Audio3_PlaySound:: ld [rNR50], a ld a, $8 ld [rNR10], a - ld a, $0 + ld a, 0 ld [rNR51], a xor a ld [rNR30], a @@ -1356,12 +1410,12 @@ Audio3_PlaySound:: ld [rNR30], a ld a, $77 ld [rNR50], a - jp Audio3_7db03 + jp .playSoundCommon -Audio3_7d9c2: +.playSfx ld l, a ld e, a - ld h, $0 + ld h, 0 ld d, h add hl, hl add hl, de @@ -1376,13 +1430,13 @@ Audio3_7d9c2: rlca rlca ld c, a -.asm_7d9db +.sfxChannelLoop ld d, c ld a, c add a add c ld c, a - ld b, $0 + ld b, 0 ld a, [wSfxHeaderPointer] ld h, a ld a, [wSfxHeaderPointer + 1] @@ -1391,32 +1445,32 @@ Audio3_7d9c2: ld c, d ld a, [hl] and $f - ld e, a - ld d, $0 + ld e, a ; software channel ID + ld d, 0 ld hl, wChannelSoundIDs add hl, de ld a, [hl] and a - jr z, .asm_7da17 + jr z, .playChannel ld a, e - cp $7 - jr nz, .asm_7da0e + cp Ch8 + jr nz, .notNoiseChannel ld a, [wSoundID] - cp $14 - jr nc, .asm_7da07 + cp NOISE_INSTRUMENTS_END + jr nc, .notNoiseInstrument ret -.asm_7da07 +.notNoiseInstrument ld a, [hl] - cp $14 - jr z, .asm_7da17 - jr c, .asm_7da17 -.asm_7da0e + cp NOISE_INSTRUMENTS_END + jr z, .playChannel + jr c, .playChannel +.notNoiseChannel ld a, [wSoundID] cp [hl] - jr z, .asm_7da17 - jr c, .asm_7da17 + jr z, .playChannel + jr c, .playChannel ret -.asm_7da17 +.playChannel xor a push de ld h, d @@ -1439,10 +1493,10 @@ Audio3_7d9c2: ld hl, wChannelFlags1 add hl, de ld [hl], a - ld hl, wChannelDuties + ld hl, wChannelDutyCycles add hl, de ld [hl], a - ld hl, wChannelDutyCycles + ld hl, wChannelDutyCyclePatterns add hl, de ld [hl], a ld hl, wChannelVibratoDelayCounters @@ -1460,28 +1514,28 @@ Audio3_7d9c2: ld hl, wChannelVibratoDelayCounterReloadValues add hl, de ld [hl], a - ld hl, wChannelPitchBendLengthModifiers + ld hl, wChannelPitchSlideLengthModifiers add hl, de ld [hl], a - ld hl, wChannelPitchBendFrequencySteps + ld hl, wChannelPitchSlideFrequencySteps add hl, de ld [hl], a - ld hl, wChannelPitchBendFrequencyStepsFractionalPart + ld hl, wChannelPitchSlideFrequencyStepsFractionalPart add hl, de ld [hl], a - ld hl, wChannelPitchBendCurrentFrequencyFractionalPart + ld hl, wChannelPitchSlideCurrentFrequencyFractionalPart add hl, de ld [hl], a - ld hl, wChannelPitchBendCurrentFrequencyHighBytes + ld hl, wChannelPitchSlideCurrentFrequencyHighBytes add hl, de ld [hl], a - ld hl, wChannelPitchBendCurrentFrequencyLowBytes + ld hl, wChannelPitchSlideCurrentFrequencyLowBytes add hl, de ld [hl], a - ld hl, wChannelPitchBendTargetFrequencyHighBytes + ld hl, wChannelPitchSlideTargetFrequencyHighBytes add hl, de ld [hl], a - ld hl, wChannelPitchBendTargetFrequencyLowBytes + ld hl, wChannelPitchSlideTargetFrequencyLowBytes add hl, de ld [hl], a ld hl, wChannelFlags2 @@ -1498,35 +1552,35 @@ Audio3_7d9c2: add hl, de ld [hl], a ld a, e - cp $4 - jr nz, .asm_7da9f + cp Ch5 + jr nz, .skipSweepDisable ld a, $8 - ld [rNR10], a -.asm_7da9f + ld [rNR10], a ; sweep off +.skipSweepDisable ld a, c and a - jp z, Audio3_7db03 + jp z, .playSoundCommon dec c - jp .asm_7d9db + jp .sfxChannelLoop -Audio3_7daa8: +.stopAllAudio ld a, $80 - ld [rNR52], a - ld [rNR30], a + ld [rNR52], a ; sound hardware on + ld [rNR30], a ; wave playback on xor a - ld [rNR51], a - ld [rNR32], a + ld [rNR51], a ; no sound output + ld [rNR32], a ; mute channel 3 (wave channel) ld a, $8 - ld [rNR10], a - ld [rNR12], a - ld [rNR22], a - ld [rNR42], a + ld [rNR10], a ; sweep off + ld [rNR12], a ; mute channel 1 (pulse channel 1) + ld [rNR22], a ; mute channel 2 (pulse channel 2) + ld [rNR42], a ; mute channel 4 (noise channel) ld a, $40 - ld [rNR14], a + ld [rNR14], a ; counter mode ld [rNR24], a ld [rNR44], a ld a, $77 - ld [rNR50], a + ld [rNR50], a ; full volume xor a ld [wUnusedC000], a ld [wDisableChannelOutputWhenSfxEnds], a @@ -1537,11 +1591,11 @@ Audio3_7daa8: ld [wSfxWaveInstrument], a ld d, $a0 ld hl, wChannelCommandPointers - call FillAudioRAM3 + call .FillMem ld a, $1 ld d, $18 ld hl, wChannelNoteDelayCounters - call FillAudioRAM3 + call .FillMem ld [wMusicTempo], a ld [wSfxTempo], a ld a, $ff @@ -1549,7 +1603,7 @@ Audio3_7daa8: ret ; fills d bytes at hl with a -FillAudioRAM3: +.FillMem ld b, d .loop ld [hli], a @@ -1557,11 +1611,11 @@ FillAudioRAM3: jr nz, .loop ret -Audio3_7db03: +.playSoundCommon ld a, [wSoundID] ld l, a ld e, a - ld h, $0 + ld h, 0 ld d, h add hl, hl add hl, de @@ -1581,31 +1635,31 @@ Audio3_7db03: ld b, c inc b inc de - ld c, $0 -.asm_7db25 + ld c, 0 +.commandPointerLoop cp c - jr z, .asm_7db2d + jr z, .next inc c inc hl inc hl - jr .asm_7db25 -.asm_7db2d + jr .commandPointerLoop +.next push hl push bc push af - ld b, $0 + ld b, 0 ld c, a ld hl, wChannelSoundIDs add hl, bc ld a, [wSoundID] ld [hl], a pop af - cp $3 - jr c, .asm_7db46 + cp Ch4 + jr c, .skipSettingFlag ld hl, wChannelFlags1 add hl, bc - set 2, [hl] -.asm_7db46 + set BIT_NOISE_OR_SFX, [hl] +.skipSettingFlag pop bc pop hl ld a, [de] ; get channel pointer @@ -1620,52 +1674,53 @@ Audio3_7db03: and a ld a, [de] inc de - jr nz, .asm_7db25 + jr nz, .commandPointerLoop ld a, [wSoundID] - cp $14 - jr nc, .asm_7db5f - jr .asm_7db89 -.asm_7db5f + cp CRY_SFX_START + jr nc, .maybeCry + jr .done +.maybeCry ld a, [wSoundID] - cp $86 - jr z, .asm_7db89 - jr c, .asm_7db6a - jr .asm_7db89 -.asm_7db6a + cp CRY_SFX_END + jr z, .done + jr c, .cry + jr .done +.cry ld hl, wChannelSoundIDs + Ch5 ld [hli], a ld [hli], a ld [hli], a ld [hl], a - ld hl, wChannelCommandPointers + Ch7 * 2 ; sfx noise channel pointer - ld de, Noise3_endchannel + ld hl, wChannelCommandPointers + Ch7 * 2 ; sfx wave channel pointer + ld de, Audio3_CryRet ld [hl], e inc hl - ld [hl], d ; overwrite pointer to point to endchannel + ld [hl], d ; overwrite pointer to point to sound_ret ld a, [wSavedVolume] and a - jr nz, .asm_7db89 + jr nz, .done ld a, [rNR50] ld [wSavedVolume], a ld a, $77 - ld [rNR50], a -.asm_7db89 + ld [rNR50], a ; full volume +.done ret -Noise3_endchannel: +Audio3_CryRet: sound_ret -Unknown_7db8b: - db $10, $15, $1A, $1F ; channels 0-3 - db $10, $15, $1A, $1F ; channels 4-7 +Audio3_HWChannelBaseAddresses: +; the low bytes of each HW channel's base address + db HW_CH1_BASE, HW_CH2_BASE, HW_CH3_BASE, HW_CH4_BASE ; channels 0-3 + db HW_CH1_BASE, HW_CH2_BASE, HW_CH3_BASE, HW_CH4_BASE ; channels 4-7 -Unknown_7db93: - db $EE, $DD, $BB, $77 ; channels 0-3 - db $EE, $DD, $BB, $77 ; channels 4-7 +Audio3_HWChannelDisableMasks: + db HW_CH1_DISABLE_MASK, HW_CH2_DISABLE_MASK, HW_CH3_DISABLE_MASK, HW_CH4_DISABLE_MASK ; channels 0-3 + db HW_CH1_DISABLE_MASK, HW_CH2_DISABLE_MASK, HW_CH3_DISABLE_MASK, HW_CH4_DISABLE_MASK ; channels 4-7 -Unknown_7db9b: - db $11, $22, $44, $88 ; channels 0-3 - db $11, $22, $44, $88 ; channels 4-7 +Audio3_HWChannelEnableMasks: + db HW_CH1_ENABLE_MASK, HW_CH2_ENABLE_MASK, HW_CH3_ENABLE_MASK, HW_CH4_ENABLE_MASK ; channels 0-3 + db HW_CH1_ENABLE_MASK, HW_CH2_ENABLE_MASK, HW_CH3_ENABLE_MASK, HW_CH4_ENABLE_MASK ; channels 4-7 Audio3_Pitches: dw $F82C ; C_ @@ -1680,5 +1735,3 @@ Audio3_Pitches: dw $FB58 ; A_ dw $FB9B ; A# dw $FBDA ; B_ - - |