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 BEQ :NONOTE ; No note playing
DEC CHANTIMES,X DEC CHANTIMES,X
BRA :NEXT 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 BCS :NEXT ; Nothing in queue
; NOTE: A contains HS byte of &HSFC ; NOTE: A contains HS byte of &HSFC
AND #$0F ; Mask out hold nybble 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 :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 * Handle envelope tick counter
* On entry: X is audio channel # * On entry: X is audio channel #
* On return: CS if this cycle is an envelope tick, CC otherwise. * 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 BEQ :DECAY ; Decay, encoded as 1
CMP #$02 CMP #$02
BEQ :SUSTAIN ; Sustain, encoded as 2 BEQ :SUSTAIN ; Sustain, encoded as 2
* TODO: RELEASE logic here CMP #$03
RTS BEQ :RELEASE ; Release, encoded as 3
RTS ; Otherwise nothing to do
:ATTACK LDY #ENVAA ; Parm: attack change/step :ATTACK LDY #ENVAA ; Parm: attack change/step
LDA (A1L),Y ; Get value of parm LDA (A1L),Y ; Get value of parm
PHA PHA
@@ -588,8 +600,18 @@ ADSRENV LDA CHANENV,X ; Get envelope number
LDA #$00 ; Target level zero LDA #$00 ; Target level zero
JSR ADSRPHASE ; Generic ADSR phase handler JSR ADSRPHASE ; Generic ADSR phase handler
RTS 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 :NEXTSECT INC AMPSECT,X ; Next section
RTS RTS
:FINISH LDA #$FF ; Finished with envelope
STA CHANENV,X
RTS
* Handle any individual phase of the ADSR envelope. Called by ADSRENV. * 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 ADSRPHASE STX OSCNUM
STA :TARGET ; Stash target level for later STA :TARGET ; Stash target level for later
CPY #$00 ; Check sign of change/step CPY #$00 ; Check sign of change/step
BEQ :DONE ; If change/step is zero BEQ :DONE ; Change/step is zero
BMI :DESCEND ; Descending amplitude BMI :DESCEND ; Descending amplitude
:ASCEND CMP CURRAMP,X ; Compare tgt with current level :ASCEND CMP CURRAMP,X ; Compare tgt with current level
BNE :S1 ; Not equal to target, keep going BNE :S1 ; Not equal to target, keep going