.ApplyEnvelopeSQ2 LDA applyVolumeSQ2 ; If applyVolumeSQ2 = 0 then we do not apply the volume BEQ muss2 ; envelope, so jump to muss2 to move on to the pitch ; envelope LDX volumeEnvelopeSQ2 ; Set X to the number of the volume envelope to apply LDA volumeEnvelopeLo,X ; Set soundAddr(1 0) to the address of the data for STA soundAddr ; volume envelope X from the (i.e. volumeEnvelope0 for LDA volumeEnvelopeHi,X ; envelope 0, volumeEnvelope1 for envelope 1, and so on) STA soundAddr+1 LDY #0 ; Set volumeRepeatSQ2 to the first byte of envelope LDA (soundAddr),Y ; data, which contains the number of times to repeat STA volumeRepeatSQ2 ; each entry in the envelope LDY volumeIndexSQ2 ; Set A to the byte of envelope data at the index in LDA (soundAddr),Y ; volumeIndexSQ2, which we increment to move through the ; data one byte at a time BMI muss1 ; If bit 7 of A is set then we just fetched the last ; byte of envelope data, so jump to muss1 to skip the ; following DEC volumeCounterSQ2 ; Decrement the counter for this envelope byte BPL muss1 ; If the counter is still positive, then we haven't yet ; done all the repeats for this envelope byte, so jump ; to muss1 to skip the following ; Otherwise this is the last repeat for this byte of ; envelope data, so now we reset the counter and move ; on to the next byte LDX volumeRepeatSQ2 ; Reset the repeat counter for this envelope to the STX volumeCounterSQ2 ; first byte of envelope data that we fetched above, ; which contains the number of times to repeat each ; entry in the envelope INC volumeIndexSQ2 ; Increment the index into the volume envelope so we ; move on to the next byte of data in the next iteration .muss1 AND #%00001111 ; Extract the low nibble from the envelope data, which ; contains the volume level ORA dutyLoopEnvSQ2 ; Set the high nibble of A to dutyLoopEnvSQ2, which gets ; set via command byte $FA and which contains the duty, ; loop and NES envelope settings to send to the APU STA sq2Volume ; Set sq2Volume to the resulting volume byte so it gets ; sent to the APU via SQ2_VOL .muss2 ; We now move on to the pitch envelope LDX pitchEnvelopeSQ2 ; Set X to the number of the pitch envelope to apply LDA pitchEnvelopeLo,X ; Set soundAddr(1 0) to the address of the data for STA soundAddr ; pitch envelope X from the (i.e. pitchEnvelope0 for LDA pitchEnvelopeHi,X ; envelope 0, pitchEnvelope1 for envelope 1, and so on) STA soundAddr+1 LDY pitchIndexSQ2 ; Set A to the byte of envelope data at the index in LDA (soundAddr),Y ; pitchIndexSQ2, which we increment to move through the ; data one byte at a time CMP #$80 ; If A is not $80 then we just fetched a valid byte of BNE muss3 ; envelope data, so jump to muss3 to process it ; If we get here then we just fetched a $80 from the ; pitch envelope, which indicates the end of the list of ; envelope values, so we now loop around to the start of ; the list, so it keeps repeating LDY #0 ; Set pitchIndexSQ2 = 0 to point to the start of the STY pitchIndexSQ2 ; data for pitch envelope X LDA (soundAddr),Y ; Set A to the byte of envelope data at index 0, so we ; can fall through into muss3 to process it .muss3 INC pitchIndexSQ2 ; Increment the index into the pitch envelope so we ; move on to the next byte of data in the next iteration CLC ; Set sq2Lo = sq2LoCopy + A ADC sq2LoCopy ; STA sq2Lo ; So this alters the low byte of the pitch that we send ; to the APU via SQ2_LO, altering it by the amount in ; the byte of data we just fetched from the pitch ; envelope RTS ; Return from the subroutineName: ApplyEnvelopeSQ2 [Show more] Type: Subroutine Category: Sound Summary: Apply volume and pitch changes to the SQ2 channel Deep dive: Music in NES EliteContext: See this subroutine in context in the source code References: This subroutine is called as follows: * MakeMusic calls ApplyEnvelopeSQ2
[X]
Variable applyVolumeSQ2 in workspace WP
A flag that determines whether to apply the volume envelope to the SQ2 channel
[X]
Variable dutyLoopEnvSQ2 in workspace WP
The high nibble to use for SQ2_VOL, when setting the following for the SQ2 channel
[X]
Label muss1 is local to this routine
[X]
Label muss2 is local to this routine
[X]
Label muss3 is local to this routine
[X]
Label pitchEnvelopeHi in variable pitchEnvelope
[X]
Label pitchEnvelopeLo in variable pitchEnvelope
[X]
Variable pitchEnvelopeSQ2 in workspace WP
The number of the pitch envelope to be applied to the current tune on channel SQ2
[X]
Variable pitchIndexSQ2 in workspace WP
The index of the entry within the pitch envelope to be applied to the current tune on channel SQ2
[X]
Variable volumeCounterSQ2 in workspace WP
A counter for keeping track of repeated bytes from the volume envelope on channel SQ2
[X]
Label volumeEnvelopeHi in variable volumeEnvelope
[X]
Label volumeEnvelopeLo in variable volumeEnvelope
[X]
Variable volumeEnvelopeSQ2 in workspace WP
The number of the volume envelope to be applied to the current tune on channel SQ2
[X]
Variable volumeIndexSQ2 in workspace WP
The index into the volume envelope data of the next volume byte to apply to channel SQ2
[X]
Variable volumeRepeatSQ2 in workspace WP
The number of repeats to be applied to each byte in the volume envelope on channel SQ2