Implement ADSR release phase.

This commit is contained in:
Bobbi Webber-Manners 2022-10-25 15:47:27 -04:00
parent 911424173b
commit 2af37adc82
2 changed files with 31 additions and 9 deletions

Binary file not shown.

View File

@ -354,13 +354,10 @@ ENSQISR INC COUNTER+0 ; Increment centisecond timer
BEQ :NONOTE ; No note playing
DEC CHANTIMES,X
BRA :NEXT
:NONOTE LDA #$FF ; $FF means 'no envelope'
STA CHANENV,X
LDY #$00 ; Zero volume
LDA #$00 ; Zero freq
JSR ENSQNOTE ; Silence channel Y
JSR PEEKAUDIO ; Inspect byte at head of queue
:NONOTE JSR NONOTE ; Handle end note / release phase
:PEEK JSR PEEKAUDIO ; Inspect byte at head of queue
BCS :NEXT ; Nothing in queue
; NOTE: A contains HS byte of &HSFC
AND #$0F ; Mask out hold nybble
@ -439,6 +436,20 @@ ENSQISR INC COUNTER+0 ; Increment centisecond timer
:CNT DB $05 ; Used to determine 20Hz cycles
* Helper function for ENSQISR - called when no note playing
* On entry: X is audio channel #
NONOTE LDA CHANENV,X ; See if envelope is in effect
CMP #$FF
BNE :RELEASE ; Has envelope, start release phase
LDY #$00 ; Zero volume
LDA #$00 ; Zero freq
JSR ENSQNOTE ; Silence channel Y
RTS
:RELEASE LDA #3 ; Phase 3 is release phase
STA AMPSECT,X ; Force release phase
RTS
* Handle envelope tick counter
* On entry: X is audio channel #
* On return: CS if this cycle is an envelope tick, CC otherwise.
@ -562,8 +573,9 @@ ADSRENV LDA CHANENV,X ; Get envelope number
BEQ :DECAY ; Decay, encoded as 1
CMP #$02
BEQ :SUSTAIN ; Sustain, encoded as 2
* TODO: RELEASE logic here
RTS
CMP #$03
BEQ :RELEASE ; Release, encoded as 3
RTS ; Otherwise nothing to do
:ATTACK LDY #ENVAA ; Parm: attack change/step
LDA (A1L),Y ; Get value of parm
PHA
@ -588,8 +600,18 @@ ADSRENV LDA CHANENV,X ; Get envelope number
LDA #$00 ; Target level zero
JSR ADSRPHASE ; Generic ADSR phase handler
RTS
:RELEASE LDY #ENVAR ; Parm: attack change/step
LDA (A1L),Y ; Get value of parm
TAY
LDA #$00 ; Target level zero
JSR ADSRPHASE ; Generic ADSR phase handler
BCS :FINISH ; Level is zero
RTS
:NEXTSECT INC AMPSECT,X ; Next section
RTS
:FINISH LDA #$FF ; Finished with envelope
STA CHANENV,X
RTS
* Handle any individual phase of the ADSR envelope. Called by ADSRENV.
@ -598,7 +620,7 @@ ADSRENV LDA CHANENV,X ; Get envelope number
ADSRPHASE STX OSCNUM
STA :TARGET ; Stash target level for later
CPY #$00 ; Check sign of change/step
BEQ :DONE ; If change/step is zero
BEQ :DONE ; Change/step is zero
BMI :DESCEND ; Descending amplitude
:ASCEND CMP CURRAMP,X ; Compare tgt with current level
BNE :S1 ; Not equal to target, keep going