               INCLUDE HPFIXUPS
               TITLE "VINITSUBS"
***************************************************************************************************
***************************************************************************************************
***                                                                                             ***
***            VINITSUBS - BACKGROUND / REALTIME VOICE-PARAMETER INITIALIZATION SUBROUTINES     ***
***                                                                                             ***
***************************************************************************************************
***************************************************************************************************
;
NEG_EXT        EQU     0FFFFFF00H      ;USE IN MOVEQ INSTRUCTIONS WHERE ARG IS
                                       ;80H OR LARGER - HP XASM DOES NOT HANDLE
                                       ;SIGN-EXTEND CORRECTLY.  COSMETIC, KEEPS
                                       ;ACTUAL BYTE VALUE CLEARER.
;
               ABS_SHORT
;
               INCLUDE S_BLK_EQU       ;SOUND CONTROL BLOCK DEFINITIONS.
;
               GLB     V_INIT_START_ADDR,N_INIT_START_ADDR
               GLB     V_INIT_BEND_LEVEL,N_INIT_BEND_LEVEL
               GLB     V_INIT_BEND_RATE,N_INIT_BEND_RATE
               GLB     V_INIT_F_RELEASE,N_INIT_F_RELEASE
               GLB     V_INIT_F_TIME,N_INIT_F_TIME
               GLB     V_INIT_F_LEVEL,N_INIT_F_LEVEL
               GLB     V_INIT_F_ATTACK,N_INIT_F_ATTACK
               GLB     V_INIT_A_RELEASE,N_INIT_A_RELEASE
               GLB     V_INIT_A_TIME,N_INIT_A_TIME
               GLB     V_INIT_A_LEVEL,N_INIT_A_LEVEL
               GLB     V_INIT_A_ATTACK,N_INIT_A_ATTACK
               GLB     INIT_PITCH_PAN
               GLB     INIT_FIN_PITCH
               GLB     INIT_CUTOFF
;
               EXTERNAL  VCA_FWD_ATTACK,VCA_REV_ATTACK,VCA_SUSTAIN
               EXTERNAL  VCF_ATTACK,VCF_SUSTAIN
               EXTERNAL  BEND_SUSTAIN,BEND_RELEASE
               EXTERNAL  NOTHINGNESS
               EXTERNAL  X_DEC_TBL,X_GRO_TBL,X_TIME_TBL,LEVEL_TABLE
               EXTERNAL  CUTOFF_TABLE,VCF_RATE_TABLE,SUSTAIN_TABLE
               EXTERNAL  MAX_TUNE_INDEX,MIN_TUNE_INDEX
;
               EXTERNAL  V_LEVEL
               EXTERNAL  V_VELOCITY
               EXTERNAL  V_START_ADDR
               EXTERNAL  V_BEND_VECTOR
               EXTERNAL  V_BEND_LEVEL
               EXTERNAL  V_A_SUS_LEVEL
               EXTERNAL  V_A_SUS_TIME
               EXTERNAL  V_A_REL_RATE
               EXTERNAL  V_VCF_VECTOR
               EXTERNAL  V_F_SUS_LEVEL
               EXTERNAL  V_F_SUS_TIME
               EXTERNAL  V_F_REL_RATE
               EXTERNAL  V_FIN_PITCH
               EXTERNAL  V_PAN
               EXTERNAL  V_PITCH_PAN
               EXTERNAL  V_PITCH_DELTA
               EXTERNAL  V_F_CUTOFF
               EXTERNAL  V_VCA_VECTOR
;
               EXTERNAL  MASTER_TUNE
               SKIP
;VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV
;
; THIS MODULE CONTAINS THE SUBROUTINES TO INITIALIZE INDIVIDUAL VOICE-BLOCK PARAMETERS OR SMALL
; GROUPS OF VOICE-BLOCK PARAMETERS - THEY ARE DESIGNED TO BE RE-ENTRANT AND EXECUTABLE FROM EITHER
; THE BACKGROUND OR REALTIME INITIALIZATION PROCEDURES (OR EVEN BOTH AT ONCE - PRETTY SLICK HUH?)
; TO ACCOMPLISH THIS, THE SUBROUTINES ARE "CALLED" VIA DIRECT BRANCH WITH "RETURN" ADDRESS IN AN
; ADDRESS REGISTER, AND RETURN RESULTS IN DESIGNATED DATA REGISTERS (NO DIRECT VOICE-BLOCK STORES
; ARE DONE HERE).  "RETURN" IS TAKEN VIA A BRANCH RELATIVE TO THE RETURN ADDRESS PROVIDED,
; DEPENDING UPON THE SIZE OF THE RESULT BEING RETURNED - DIRECTLY IF RETURNING A WORD RESULT,
; PLUS TWO IF RETURNING A LONG-WORD RESULT, PLUS FOUR IF RETURNING A WORD BLOCK (WHICH, BY THE WAY,
; IS THE MAIN REASON FOR NOT USING SIMPLE BSR-RTS - THE OTHER REASON BEING SPEED).
;
; INIT ROUTINES BEGINNING WITH "V_" INCORPORATE VELOCITY-MOD INTO THE INIT CALCULATIONS -
; THESE ARE CALLED BY VELOCITY-INIT PROCEDURES (BKGND/RT_VEL_INT), ONLY WHEN THERE IS A NON-ZERO
; VELOCITY-MOD SETTING FOR THE GIVEN PARAMETER.
; INIT ROUTINES BEGINNING WITH "N_" ARE THE CORRESPONDING INIT ROUTINES WITHOUT ANY PROVISION
; FOR VELOCITY MOD - THESE ARE CALLED BY NON-VEL INIT PROCEDURES (BKGND/RT_NON_VEL_INIT), FOR THOSE
; PARAMETERS WHOSE VELOCITY-MOD IS SET TO ZERO.
; INIT ROUTINES WHICH BEGIN WITH "INIT_" AND NO "V_" OR "N_" PREFIX
; ARE FOR THOSE PARAMETERS WHICH DO NOT EVER HAVE VELOCITY-MOD -
; THEY ARE ALSO CALLED BY THE NON-VEL INIT PROCEDURES.
;
; THE FULL STORY ON REGISTER UTILIZATION:
;
; INPUTS:
;    A0  -   "RETURN" POINTER - ALLOWS BRANCH BACK TO BACKGROUND OR REALTIME INIT PROCEDURE.
;    A1  -   VOICE COMMON BLOCK POINTER.
;    A2  -   VOICE IDLE SUB-BLOCK POINTER.
;    A3  -   SOUND COMMON BLOCK POINTER.
;    A4  -   SOUND SUB-BLOCK POINTER.
; OUTPUTS:
;    D1  -   DATA RETURN REGISTER - DATA (SINGLE WORD / LONG-WORD), OR BLOCK SIZE (# WORDS - 1).
;    D2  -   ADDRESS RETURN REGISTER - INDEX INTO VOICE SUB-BLOCK FOR RESULT STORE.
; OTHER:
;    D0  -   INITIALIZATION INDEX - WHICH PARAMETER OR PARAM GROUP IS BEING INITIALIZED.
;            THIS IS RELEVANT ONLY TO VINITMAIN, SINCE IT CALLS THE VINITSUBS ROUTINES DIRECTLY -
;            HOWEVER, IT MUST NOT GET TRASHED BY ANY OF THE VINITSUBS ROUTINES.
;
; REGISTERS USED AS INPUTS ARE NOT TO BE TAMPERED WITH BY ANY OF THE VINITSUBS ROUTINES.
; REGISTERS NOT MENTIONED ABOVE (EXCEPT A7) CAN BE DAMAGED AT WILL (SPECIFICALLY, A5-A6/D3-D7).
;
;AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
               SKIP
;VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV
;
; INITIALIZE SAMPLE PLAYBACK START ADDRESS - NO VELOCITY-MOD.
;
N_INIT_START_ADDR
               BTST    #5,S_LOOP_TYPE(A4)   ;TEST DIRECTION BIT OF SELECTE SOUND SUB-BLOCK.
               BNE.S   N_I_START_20         ;BRANCH IF REVERSE,
               MOVE.L  S_START(A4),D1       ;ELSE RETURN START ADDRESS UNMODIFIED.
               BRA.S   N_I_START_40
N_I_START_20
               MOVE.L  S_END(A4),D1         ;FOR REVERSE PLAY, RETURN END ADDRESS AS START ADDRESS.
N_I_START_40
               MOVE    #V_START_ADDR,D2     ;FETCH OFFSET OF THIS PARAMETER IN VOICE SUB-BLOCK.
               JMP     2(A0)                ;RETURN TO LONG-WORD STORE POINT.
;
;AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
;
;
;
;VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV
;
; INITIALIZE SAMPLE PLAYBACK START ADDRESS INCLUDING VELOCITY-MOD.
; IN SOOTH, WE'LL NOT BE GETTIN' THRU THIS WAY IF VEL-SENSITIVITY BE 0,
; SO WE'LL NOT BE BOTHR'D TO TEST FOR THIS.
;
V_INIT_START_ADDR
               MOVE    V_VELOCITY(A1),D4    ;FETCH EVENT VELOCITY (1-31).
               MOVE.B  S_VEL_START(A4),D3   ;FETCH START ADDR VEL-SENSITIVITY SETTING.
               EXT.W   D3                   ;EXTEND TO WORD FOR SCALE OPERATION -
               BPL.S   V_START_20           ;BRANCH IF VEL-SENS POSITIVE,
               SUB     #32,D4               ;ELSE ADJUST VEL FOR NEGATIVE VEL-SENS (-31 TO -1).
V_START_20
               MULS    D3,D4                ;SCALE VELOCITY AGAINST VEL-SENS SETTING.
               MULU    #15H,D4              ;FUDGE FACTOR FOR INTERMEDIATE PRODUCT.
;
               BTST    #5,S_LOOP_TYPE(A4)   ;TEST DIRECTION BIT OF SELECTE SOUND SUB-BLOCK.
               BNE.S   V_START_80           ;BRANCH IF REVERSE,
               MOVE.L  S_START(A4),D1       ;ELSE FETCH START ADDRESS AS JUMPING-OFF POINT.
               BTST    #7,S_LOOP_TYPE(A4)   ;IS LOOP ENABLED?
               BNE.S   V_START_40           ;BRANCH IF YES,
               MOVE.L  S_END(A4),D2         ;ELSE FETCH END ADDRESS AS FAR LIMIT.
               BRA.S   V_START_60
V_START_40
               MOVE.L  S_LOOP_END(A4),D2    ;IF LOOPING, USE LOOP END AS FAR LIMIT.
V_START_60
               SUB.L   D1,D2                ;TAKE DIFFERENCE - THIS IS THE RANGE TO VEL-MOD OVER.
               BRA.S   V_START_D0
V_START_80
               MOVE.L  S_END(A4),D1         ;FOR REVERSE PLAY, END ADDRESS IS JUMPING-OFF POINT.
               BTST    #7,S_LOOP_TYPE(A4)   ;IS LOOP ENABLED?
               BNE.S   V_START_A0           ;BRANCH IF YES,
               MOVE.L  S_START(A4),D2       ;ELSE FETCH START ADDRESS AS FAR LIMIT.
               BRA.S   V_START_C0
V_START_A0
               MOVE.L  S_LOOP_START(A4),D2  ;IF LOOPING, USE LOOP START AS FAR LIMIT.
V_START_C0
               SUB.L   D1,D2                ;TAKE DIFFERENCE - THIS IS THE RANGE TO VEL-MOD OVER.
               NEG.L   D2                   ;AH YEAH, WE NEED A POSITIVE DELTOID HERE.
V_START_D0
               MOVE.L  D2,D3                ;COPY DELTA-START RANGE,
               SWAP    D2                   ;SET UP AND PERFORM TWO-WORD MULTIPLY -
               MULU    D4,D2                ;M.S.PRODUCT,
               MULU    D4,D3                ;L.S.PRODUCT.
               CLR     D3                   ;COMBINE L.S.PRODUCT WITH M.S.PRODUCT.
               SWAP    D3
               ADD.L   D3,D2
;
               BTST    #5,S_LOOP_TYPE(A4)   ;AGAIN - FORWARD OR REVERSE PLAY?
               BEQ.S   V_START_E0           ;BRANCH FOR FORWARD PLAY,
               NEG.L   D2                   ;ELSE MAKE SCALED ADDRESS DELTA NEGATIVE.
V_START_E0
               ADD.L   D2,D1                ;TACK ADDRESS DELTA ONTO JUMPING-OFF POINT - THAT'S IT.
V_START_F0
               MOVE    #V_START_ADDR,D2     ;FETCH OFFSET OF THIS PARAMETER IN VOICE SUB-BLOCK.
               JMP     2(A0)                ;RETURN TO LONG-WORD STORE POINT.
;
;AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
               SKIP
;VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV
;
; INITIALIZE PITCH ENVELOPE AMOUNT - NO VELOCITY MOD.
;
N_INIT_BEND_LEVEL
               MOVE.B  S_B_PEAK(A4),D1      ;FETCH BEND DEPTH SETTING.
               EXT.W   D1                   ;IT'S BIPOLAR, SIGN-EXTEND IT.
               MULS    #6AABH,D1            ;I GUESS THAT SHOULD  .... YEAH  .... WELL ....
               LSL.L   #5,D1                ;NO, AHHHH -
               SWAP    D1                   ;NOW WE'RE HOME.
               MOVE    #V_BEND_LEVEL,D2     ;FETCH OFFSET OF THIS PARAMETER IN VOICE SUB-BLOCK.
               JMP     (A0)                 ;RETURN TO WORD-STORE POINT.
;
;AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
;
;
;
;VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV
;
; INITIALIZE PITCH ENVELOPE AMOUNT INCLUDING VELOCITY MOD.
;
V_INIT_BEND_LEVEL
               MOVE.B  S_B_PEAK(A4),D1      ;FETCH BEND DEPTH SETTING.
               EXT.W   D1                   ;IT'S BIPOLAR, SIGN-EXTEND IT.
               MULS    #11DH,D1             ;FUDGE-SCALE FOR INTERMEDIATE PRODUCT.
               MOVE    V_VELOCITY(A1),D2    ;FETCH EVENT VELOCITY (1-31).
               MOVE.B  S_B_VEL_PEAK(A4),D3  ;FETCH PITCH BEND ENV AMOUNT VEL-SENSITIVITY SETTING.
               EXT.W   D3                   ;EXTEND TO WORD FOR SCALE OPERATION -
               BMI.S   V_B_LEV_20           ;BRANCH IF VEL-SENS NEGATIVE,
               SUB     #32,D2               ;ELSE ADJUST VEL FOR POSITIVE VEL-SENS (-31 TO -1).
V_B_LEV_20
               MULS    D3,D2                ;SCALE VELOCITY AGAINST VEL-SENS SETTING.
               ADD     #0BFDH,D2            ;ADD (NEGATIVE) SCALING PRODUCT TO PEAK POSITIVE VALUE.
               MULS    D2,D1                ;SCALE INTERMEDIATE PRODUCT BY VEL-MOD RESULT.
               SWAP    D1                   ;RESULT IS IN M.S.WORD, SWOP IT DOWN.
               MOVE    #V_BEND_LEVEL,D2     ;FETCH OFFSET OF THIS PARAMETER IN VOICE SUB-BLOCK.
               JMP     (A0)                 ;RETURN TO WORD-STORE POINT.
;
;AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
               SKIP
;VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV
;
; INITIALIZE PITCH-BEND (RELEASE) RATE INCLUDING VELOCITY MOD.
; IN SOOTH, WE'LL NOT BE GETTIN' THRU THIS WAY IF VEL-SENSITIVITY BE 0,
; SO WE'LL NOT BE BOTHR'D TO TEST FOR THIS.
;
V_INIT_BEND_RATE
               MOVE    V_VELOCITY(A1),D3    ;FETCH EVENT VELOCITY (1-31).
               MOVE.B  S_B_VEL_RATE(A4),D4  ;FETCH BEND RATE VEL-SENSITIVITY SETTING.
               EXT.W   D4                   ;EXTEND TO WORD FOR SCALE OPERATION -
               BMI.S   V_B_RATE_20          ;BRANCH IF VEL-SENS NEGATIVE,
               SUB     #32,D3               ;ELSE ADJUST VEL FOR POSITIVE VEL-SENS (-31 TO -1).
V_B_RATE_20
               MULS    D4,D3                ;SCALE VELOCITY AGAINST VEL-SENS SETTING.
               ADD     #0BFDH,D3            ;ADD (NEGATIVE) SCALING PRODUCT TO PEAK POSITIVE VALUE.
               MULU    #0AAD6H,D3           ;FUDGE FACTOR FOR INTERMEDIATE PRODUCT.
               SWAP    D3                   ;THIS IS THE PART WE WANT.
               MOVE.B  S_B_RATE(A4),D4      ;FETCH INITIAL PITCH-BEND RELEASE RATE SETTING.
               EXT.W   D4                   ;EXTEND TO WORD (IT'S NOT SIGNED, THOUGH),
               MULU    D4,D3                ;SCALE RATE SETTING BY PRODUCTO INTER-MEEDO.
               LSL.L   #5,D3                ;COMPLETE THE DAMAGE TO GET A 0 TO +99 RESULT.
               SWAP    D3
               BRA.S   N_B_RATE_20          ;FROM HERE, SAME AS NON-VEL INIT (PITCH TRACK, ETC).
;
;AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
;
;
;
;VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV
;
; INITIALIZE PITCH-BEND (RELEASE) RATE - NO VELOCITY MOD.
; COMING FROM V_INIT_BEND_RATE, WE ENTER PARTWAY THROUGH WITH VEL-MODDED
; RATE SETTING (INDEX) IN D3.
; ALSO SETS INITIAL BEND VECTOR PER GATE MODE SETTING AND FINAL BEND RATE.
;
N_INIT_BEND_RATE
               MOVE.B  S_B_RATE(A4),D3      ;FETCH UN-VEL-MODDED RATE SETTING FROM SOUND SUB-BLOCK.
               EXT.W   D3                   ;IT'S NOT SIGNED, BUT EXTEND TO WORD FOR COMPUTATION.
N_B_RATE_20
                                            ;ENTER HERE FROM V_INIT_BEND_RATE.
;
               MOVE.B  S_B_PITCH_RATE(A4),D1     ;FETCH BEND RATE PITCH-TRACK SETTING.
               EXT.W   D1                   ;EXTEND IT TO WORD (YAH, IT'S SIGNED),
               BEQ.S   N_B_RATE_30          ;BRANCH IF ZERO, SKIP PITCH-TRACK COMPUTATION.
               MOVE    D1,D2                ;ELSE, MOVE IT OVER HYAR,
               MOVE    V_PITCH_DELTA(A1),D1 ;FETCH DELTA FROM NOMINAL PITCH INTO D1.
               BEQ.S   N_B_RATE_30          ;AGAIN - BRANCH IF ZERO, SKIP PITCH-TRACK COMPUTATION.
               MULS    D2,D1                ;ELSE - DO THE BASIC SCALING,
               MULS    #093CH,D1            ;THEN DO THE SCALING ARBITRAIRE -
               SWAP    D1                   ;THIS IS THE PART WE WANT.
N_B_RATE_30
               TST.B   S_B_GATE(A4)         ;SEE WHETHER BEND ENVELOPE IS UNDER GATE CONTROL.
               BNE.S   N_B_RATE_40          ;BRANCH IF YES,
               MOVE    #BEND_RELEASE,D4     ;ELSE FETCH RELEASE VECTOR.
               BRA.S   N_B_RATE_60
N_B_RATE_40
               MOVE    #BEND_SUSTAIN,D4     ;FOR GATE CONTROL, BEND STARTS IN SUSTAIN PHASE.
N_B_RATE_60
               ADD     D1,D3                ;THROW PITCH-DELTA ONTO BASIC/VEL SETTING,
               BGT.S   N_B_RATE_80          ;LIMIT FINAL VALUE TO 0-99.
               CLR     D3
               BRA.S   N_B_RATE_A0
N_B_RATE_80
               CMP     #99,D3
               BLT.S   N_B_RATE_A0
               MOVEQ   #99,D3
               MOVE    #NOTHINGNESS,D4      ;IF BEND RATE = 99, NULL BEND VECTOR (INFINITE TIME).
N_B_RATE_A0
               MOVE    D4,D1                ;COPY INITIAL BEND VECTOR,
               SWAP    D1                   ;PUT IT INTO M.S.WORD FOR RETURN.
               LSL     #2,D3                ;CONVERT FINAL RESULT INTO LONG-WORD INDEX,
               MOVE.L  #X_DEC_TBL,A5        ;MOOCH OFF OF VCA RELEASE FOR BEND RATE FACTOR.
               MOVE    0(A5,D3),D1          ;FETCH RATE FACTOR FROM TABLE -
                                            ;BUT NOTICE, ONLY M.S.WORD USED.
               MOVE    #V_BEND_VECTOR,D2    ;FETCH OFFSET OF BEND VECTOR IN VOICE SUB-BLOCK.
               JMP     2(A0)                ;RETURN TO LONG-WORD STORE POINT.
;
;AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
               SKIP
;VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV
;
; INITIALIZE VCF RELEASE RATE INCLUDING VELOCITY MOD.
; IN SOOTH, WE'LL NOT BE GETTIN' THRU THIS WAY IF VEL-SENSITIVITY BE 0,
; SO WE'LL NOT BE BOTHR'D TO TEST FOR THIS.
;
V_INIT_F_RELEASE
               MOVE    V_VELOCITY(A1),D3    ;FETCH EVENT VELOCITY (1-31).
               MOVE.B  S_F_VEL_REL(A4),D4   ;FETCH VCF RELEASE RATE VEL-SENSITIVITY SETTING.
               EXT.W   D4                   ;EXTEND TO WORD FOR SCALE OPERATION -
               BMI.S   V_F_REL_20           ;BRANCH IF VEL-SENS NEGATIVE,
               SUB     #32,D3               ;ELSE ADJUST VEL FOR POSITIVE VEL-SENS (-31 TO -1).
V_F_REL_20
               MULS    D4,D3                ;SCALE VELOCITY AGAINST VEL-SENS SETTING.
               ADD     #0BFDH,D3            ;ADD (NEGATIVE) SCALING PRODUCT TO PEAK POSITIVE VALUE.
               MULU    #0AAD6H,D3           ;FUDGE FACTOR FOR INTERMEDIATE PRODUCT.
               SWAP    D3                   ;THIS IS THE PART WE WANT.
               MOVE.B  S_F_INIT_REL(A4),D4  ;FETCH INITIAL VCF RELEASE RATE SETTING.
               EXT.W   D4                   ;EXTEND TO WORD (IT'S SIGNED),
               MULS    D4,D3                ;SCALE RATE SETTING BY PRODUCTO INTER-MEEDO.
               LSL.L   #5,D3                ;COMPLETE THE DAMAGE TO GET A -99 TO +99 RESULT.
               SWAP    D3
               BRA.S   N_F_REL_20           ;FROM HERE, SAME AS NON-VEL INIT (PITCH TRACK, ETC).
;
;AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
;
;
;
;VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV
;
; INITIALIZE VCF RELEASE RATE - NO VELOCITY MOD.
; COMING FROM V_INIT_F_RELEASE, WE ENTER PARTWAY THROUGH WITH VEL-MODDED
; RELEASE RATE SETTING (INDEX) IN D3.
;
N_INIT_F_RELEASE
               MOVE.B  S_F_INIT_REL(A4),D3  ;FETCH UN-VEL-MODDED RELEASE RATE FROM SOUND SUB-BLOCK.
               EXT.W   D3                   ;IT'S SIGNED, SO EXTEND IT.
N_F_REL_20
                                            ;ENTER HERE FROM V_INIT_F_RELEASE.
;
               MOVE.B  S_F_PITCH_REL(A4),D1 ;FETCH RELEASE PITCH-TRACK SETTING.
               EXT.W   D1                   ;EXTEND IT TO WORD (YAH, IT'S SIGNED),
               BEQ.S   N_F_REL_30           ;BRANCH IF ZERO, SKIP PITCH-TRACK COMPUTATION.
               MOVE    D1,D2                ;ELSE, MOVE IT OVER HYAR,
               MOVE    V_PITCH_DELTA(A1),D1 ;FETCH DELTA FROM NOMINAL PITCH INTO D1.
               BEQ.S   N_F_REL_30           ;AGAIN - BRANCH IF ZERO, SKIP PITCH-TRACK COMPUTATION.
               MULS    D2,D1                ;ELSE - DO THE BASIC SCALING,
               MULS    #093CH,D1            ;THEN DO THE SCALING ARBITRAIRE -
               SWAP    D1                   ;THIS IS THE PART WE WANT.
N_F_REL_30
               ADD     D1,D3                ;THROW PITCH-DELTA ONTO BASIC/VEL SETTING,
               BGE.S   N_F_REL_80           ;LIMIT FINAL VALUE TO 0-99.
               CLR     D3
               BRA.S   N_F_REL_A0
N_F_REL_80
               CMP     #99,D3
               BLE.S   N_F_REL_A0
               MOVEQ   #99,D3
N_F_REL_A0
               ADD     D3,D3                ;CONVERT FINAL RESULT INTO WORD INDEX,
               MOVE.L  #VCF_RATE_TABLE,A5   ;POINT TO VCF ENVELOPE RATE TABLE,
               MOVE    0(A5,D3),D1          ;FETCH THE SELECTED RATE DELTA FROM TABLE.
               MOVE    #V_F_REL_RATE,D2     ;FETCH OFFSET OF THIS PARAMETER IN VOICE SUB-BLOCK.
               JMP     (A0)                 ;RETURN TO WORD STORE POINT.
;
;AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
               SKIP
;VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV
;
; INITIALIZE VCF SUSTAIN TIME INCLUDING VELOCITY MOD.
; UNTIL FURTHER NOTICE, UTILIZES X_DEC_TBL (SAME AS ATTACK/RELEASE)
; TO COMPUTE SUSTAIN TIME - SO SUSTAIN TIME AND ATTACK/RELEASE RATE
; SETTINGS SHOULD CORRESPOND PRETTY CLOSELY.
; WHAT'S THAT?  THEY DON'T?  SIR, PLEASE GO SHOOT YOURSELF.
; IN SOOTH, WE'LL NOT BE GETTIN' THRU THIS WAY IF VEL-SENSITIVITY BE 0,
; SO WE'LL NOT BE BOTHR'D TO TEST FOR THIS.
;
V_INIT_F_TIME
               MOVE.B  S_F_INIT_TIME(A4),D3 ;FETCH VCF SUSTAIN TIME SETTING.
               EXT.W   D3                   ;IT'S SIGNED - SORT OF.
               BMI     N_F_TIME_C0          ;IF SETTING IS NEGATIVE, SET UP FOR GATE MODE.
               BNE.S   V_F_TIME_20          ;IF SETTING NOT = 0, COMPUTE VEL-MODDED TIME SETTING.
               BRA.S   N_F_TIME_20          ;IF = 0, VEL-MOD IRRELEVANT - BUT DO PITCH TRACK.
V_F_TIME_20
               MOVE    V_VELOCITY(A1),D5    ;FETCH EVENT VELOCITY (1-31).
               MOVE.B  S_F_VEL_TIME(A4),D4  ;FETCH VCF SUSTAIN TIME VEL-SENSITIVITY SETTING.
               EXT.W   D4                   ;EXTEND TO WORD FOR SCALE OPERATION -
               BMI.S   V_F_TIME_40          ;BRANCH IF VEL-SENS NEGATIVE,
               SUB     #32,D5               ;ELSE ADJUST VEL FOR POSITIVE VEL-SENS (-31 TO -1).
V_F_TIME_40
               MULS    D4,D5                ;SCALE VELOCITY AGAINST VEL-SENS SETTING.
               ADD     #0BFDH,D5            ;ADD (NEGATIVE) SCALING PRODUCT TO PEAK POSITIVE VALUE.
               MULU    #0AAD6H,D5           ;FUDGE FACTOR FOR INTERMEDIATE PRODUCT.
               SWAP    D5                   ;THIS IS THE PART WE WANT.
               MULU    D5,D3                ;SCALE TIME SETTING (D3, YES?) BY PRODUCTO INTER-MEEDO.
               LSL.L   #5,D3                ;COMPLETE THE DAMAGE TO GET A -99 TO +99 RESULT.
               SWAP    D3
               BRA.S   N_F_TIME_20          ;FROM HERE, SAME AS NON-VEL INIT (PITCH TRACK, ETC).
;
;AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
;
;
;
;VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV
;
; INITIALIZE VCF SUSTAIN TIME - NO VELOCITY MOD.
; UNTIL FURTHER NOTICE, UTILIZES X_DEC_TBL (SAME AS ATTACK/RELEASE)
; TO COMPUTE SUSTAIN TIME - SO SUSTAIN TIME AND ATTACK/RELEASE RATE
; SETTINGS SHOULD CORRESPOND PRETTY CLOSELY.
; COMING FROM V_INIT_F_TIME, WE ENTER PARTWAY THROUGH WITH VEL-MODDED
; SUSTAIN TIME SETTING (INDEX) IN D3.
;
N_INIT_F_TIME
               MOVE.B  S_F_INIT_TIME(A4),D3 ;FETCH VCF SUSTAIN TIME SETTING.
               EXT.W   D3                   ;IT'S SIGNED - SORT OF.
               BMI.S   N_F_TIME_C0          ;IF SETTING IS NEGATIVE, SET UP FOR GATE MODE.
N_F_TIME_20
                                            ;ENTER HERE FROM V_INIT_F_TIME.
;
               MOVE.B  S_F_PITCH_TIME(A4),D1     ;FETCH SUSTAIN TIME PITCH-TRACK SETTING.
               EXT.W   D1                        ;EXTEND IT TO WORD (YAH, IT'S SIGNED),
               BEQ.S   N_F_TIME_30               ;BRANCH IF ZERO, SKIP PITCH-TRACK COMPUTATION.
               MOVE    D1,D2                ;ELSE, MOVE IT OVER HYAR,
               MOVE    V_PITCH_DELTA(A1),D1 ;FETCH DELTA FROM NOMINAL PITCH INTO D1.
               BEQ.S   N_F_TIME_30          ;AGAIN - BRANCH IF ZERO, SKIP PITCH-TRACK COMPUTATION.
               MULS    D2,D1                ;DO THE BASIC SCALING,
               MULS    #093CH,D1            ;THEN DO THE SCALING ARBITRAIRE -
               SWAP    D1                   ;THIS IS THE PART WE WANT.
               ADD     D1,D3                ;ADD PITCH-TRACK DELTA TO BASIC/VEL SETTING.
N_F_TIME_30
               TST     D3                   ;LIMIT FINAL VALUE TO 0-99.
               BPL.S   N_F_TIME_40
               CLR     D3
               BRA.S   N_F_TIME_60
N_F_TIME_40
               CMP     #99,D3
               BLE.S   N_F_TIME_60
               MOVEQ   #99,D3
N_F_TIME_60
               ADD     D3,D3                ;CREATE WORD OFFSET,
               MOVE    D3,A5
               ADD.L   #SUSTAIN_TABLE,A5    ;BUMP UP INTO SUSTAIN-TIME TABLE,
               MOVE    (A5),D1              ;FETCH THAT COUNT.
;
               BRA.S   N_F_TIME_E0
N_F_TIME_C0
               MOVEQ   #-1,D1               ;NEGATIVE VALUE INDICATES GATE MODE.
N_F_TIME_E0
               MOVE    #V_F_SUS_TIME,D2     ;FETCH OFFSET OF THIS PARAMETER IN VOICE SUB-BLOCK.
               JMP     (A0)                 ;RETURN TO WORD-STORE POINT.
;
;AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
               SKIP
;VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV
;
; INITIALIZE VCF ENVELOPE LEVEL - NO VELOCITY MOD.
;
N_INIT_F_LEVEL
               CLR     D1
               MOVE.B  S_F_ENV_AMT(A4),D1
               MULU    #295H,D1             ;I GUESS THAT SHOULD  .... YEAH  .... WELL ....
               ADD     #50H,D1              ;COMPENSATE FOR TRUNCATION ERROR, OPEN VCF ALL THE WAY.
               MOVE    #V_F_SUS_LEVEL,D2    ;FETCH OFFSET OF THIS PARAMETER IN VOICE SUB-BLOCK.
               JMP     (A0)                 ;RETURN TO WORD-STORE POINT.
;
;AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
;
;
;
;VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV
;
; INITIALIZE VCF ENVELOPE LEVEL INCLUDING VELOCITY MOD.
;
V_INIT_F_LEVEL
               MOVE    V_VELOCITY(A1),D1    ;FETCH EVENT VELOCITY (1-31).
               MOVE.B  S_F_VEL_ENV(A4),D2   ;FETCH VCF ENVELOPE AMOUNT VEL-SENSITIVITY SETTING.
               EXT.W   D2                   ;EXTEND TO WORD FOR SCALE OPERATION -
               BMI.S   V_F_LEV_20           ;BRANCH IF VEL-SENS NEGATIVE,
               SUB     #32,D1               ;ELSE ADJUST VEL FOR POSITIVE VEL-SENS (-31 TO -1).
V_F_LEV_20
               MULS    D2,D1                ;SCALE VELOCITY AGAINST VEL-SENS SETTING.
               ADD     #0BFDH,D1            ;ADD (NEGATIVE) SCALING PRODUCT TO PEAK POSITIVE VALUE.
               MULU    #3735H,D1            ;FUDGE FACTOR - FOR INTERMEDIATE SCALING RESULT -
               SWAP    D1                   ;SWAP IT DOWN INTO PLACE FOR US TO USE.
               CLR     D2                   ;NOW SCALE AGIN BY VCF ENVELOPE AMOUNT SETTING -
               MOVE.B  S_F_ENV_AMT(A4),D2
               MULU    D2,D1
               ADD     #50H,D1              ;COMPENSATE FOR TRUNCATION ERROR, OPEN VCF ALL THE WAY.
               MOVE    #V_F_SUS_LEVEL,D2    ;FETCH OFFSET OF THIS PARAMETER IN VOICE SUB-BLOCK.
               JMP     (A0)                 ;RETURN TO WORD-STORE POINT.
;
;AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
               SKIP
;VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV
;
; INITIALIZE VCF ATTACK RATE INCLUDING VELOCITY MOD.
; IN SOOTH, WE'LL NOT BE GETTIN' THRU THIS WAY IF VEL-SENSITIVITY BE 0,
; SO WE'LL NOT BE BOTHR'D TO TEST FOR THIS.
;
V_INIT_F_ATTACK
               MOVE    V_VELOCITY(A1),D3    ;FETCH EVENT VELOCITY (1-31).
               MOVE.B  S_F_VEL_ATT(A4),D4   ;FETCH VCF ATTACK RATE VEL-SENSITIVITY SETTING.
               EXT.W   D4                   ;EXTEND TO WORD FOR SCALE OPERATION -
               BMI.S   V_F_ATT_20           ;BRANCH IF VEL-SENS NEGATIVE,
               SUB     #32,D3               ;ELSE ADJUST VEL FOR POSITIVE VEL-SENS (-31 TO -1).
V_F_ATT_20
               MULS    D4,D3                ;SCALE VELOCITY AGAINST VEL-SENS SETTING.
               ADD     #0BFDH,D3            ;ADD (NEGATIVE) SCALING PRODUCT TO PEAK POSITIVE VALUE.
               MULU    #0AAD6H,D3           ;FUDGE FACTOR FOR INTERMEDIATE PRODUCT.
               SWAP    D3                   ;THIS IS THE PART WE WANT.
               MOVE.B  S_F_INIT_ATT(A4),D4  ;FETCH INITIAL VCF ATTACK RATE SETTING.
               EXT.W   D4                   ;EXTEND TO WORD (IT'S SIGNED),
               MULS    D4,D3                ;SCALE RATE SETTING BY PRODUCTO INTER-MEEDO.
               LSL.L   #5,D3                ;COMPLETE THE DAMAGE TO GET A -99 TO +99 RESULT.
               SWAP    D3
               BRA.S   N_F_ATT_20           ;FROM HERE, SAME AS NON-VEL INIT (PITCH TRACK, ETC).
;
;AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
;
;
;
;VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV
;
; INITIALIZE VCF ATTACK RATE - NO VELOCITY MOD.
; ALSO INITIALIZES VCF VECTOR AND RAW VCF ENVELOPE POINT,
; WITH PROVISION FOR INSTANT-ON ATTACK.
; COMING FROM V_INIT_F_ATTACK, WE ENTER PARTWAY THROUGH WITH VEL-MODDED
; ATTACK RATE SETTING (INDEX) IN D3.
;
N_INIT_F_ATTACK
               MOVE.B  S_F_INIT_ATT(A4),D3  ;FETCH UN-VEL-MODDED ATTACK RATE FROM SOUND SUB-BLOCK.
               EXT.W   D3                   ;IT'S SIGNED, SO EXTEND IT.
N_F_ATT_20
                                            ;ENTER HERE FROM V_INIT_F_ATTACK.
               MOVEQ   #30H,D4              ;INITIAL RAW VCF ENV POINT FOR NON-INSTANT-ON ATTACK.
               MOVE    #VCF_ATTACK,D5       ;INITIAL VCF VECTOR FOR NON-INSTANT-ON ATTACK.
;
               MOVE.B  S_F_PITCH_ATT(A4),D1 ;FETCH ATTACK PITCH-TRACK SETTING.
               EXT.W   D1                   ;EXTEND IT TO WORD (YAH, IT'S SIGNED),
               BEQ.S   N_F_ATT_30           ;BRANCH IF ZERO, SKIP PITCH-TRACK COMPUTATION.
               MOVE    D1,D2                ;ELSE, MOVE IT OVER HYAR,
               MOVE    V_PITCH_DELTA(A1),D1 ;FETCH DELTA FROM NOMINAL PITCH INTO D1.
               BEQ.S   N_F_ATT_30           ;AGAIN - BRANCH IF ZERO, SKIP PITCH-TRACK COMPUTATION.
               MULS    D2,D1                ;ELSE - DO THE BASIC SCALING,
               MULS    #093CH,D1            ;THEN DO THE SCALING ARBITRAIRE -
               SWAP    D1                   ;THIS IS THE PART WE WANT.
N_F_ATT_30
               ADD     D1,D3                ;THROW PITCH-DELTA ONTO BASIC/VEL SETTING,
               BGT.S   N_F_ATT_80           ;LIMIT FINAL VALUE TO 0-98.
               CLR     D3                   ;IF NOT > 1, SET TO 0 (INSTANT-ON) -
               MOVE    #VCF_SUSTAIN,D5      ;SKIP ATTACK PHASE AND START VCF OUT IN SUSTAIN PHASE,
               MOVEQ   #NEG_EXT+0F0H,D4     ;SET ENVELOPE POINT (0FFFH, 12 BITS) FOR USE BY
               BRA.S   N_F_ATT_A0           ;RELEASE VECTOR AFTER SUSTAIN PHASE ENDS.
N_F_ATT_80
               CMP     #99,D3
               BLT.S   N_F_ATT_A0           ;IF LESS THAN 99, TRES COULE -
               MOVEQ   #98,D3               ;ELSE, SET RATE = 98 (NO INFINITE ATTACK TIME).
;
N_F_ATT_A0
               ADD     D3,D3                ;CONVERT FINAL RATE RESULT INTO WORD INDEX,
               MOVE.L  #VCF_RATE_TABLE,A5   ;SET POINTER TO VCF ATTACK/RELEASE RATE TABLE,
               MOVE    0(A5,D3),-(A7)       ;FETCH RATE DELTA FROM TABLE ONTO STACK.
               MOVE    D4,-(A7)             ;STASH INITIAL RAW VCF ENVELOPE POINT ON STACK.
               MOVE    D5,-(A7)             ;STASH INITIAL VCF VECTOR ON STACK.
               MOVEQ   #2,D1                ;INDICATE BLOCK OF THREE WORDS BEING PASSED.
               MOVE    #V_VCF_VECTOR,D2     ;FETCH OFFSET OF FIRST PARAMETER IN THIS WORD-BLOCK.
               JMP     4(A0)                ;RETURN TO WORD-BLOCK STORE POINT.
;
;AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
               SKIP
;VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV
;
; INITIALIZE VCA RELEASE RATE INCLUDING VELOCITY MOD.
; IN SOOTH, WE'LL NOT BE GETTIN' THRU THIS WAY IF VEL-SENSITIVITY BE 0,
; SO WE'LL NOT BE BOTHR'D TO TEST FOR THIS.
;
V_INIT_A_RELEASE
               MOVE    V_VELOCITY(A1),D3    ;FETCH EVENT VELOCITY (1-31).
               MOVE.B  S_A_VEL_REL(A4),D4   ;FETCH VCA RELEASE RATE VEL-SENSITIVITY SETTING.
               EXT.W   D4                   ;EXTEND TO WORD FOR SCALE OPERATION -
               BMI.S   V_A_REL_20           ;BRANCH IF VEL-SENS NEGATIVE,
               SUB     #32,D3               ;ELSE ADJUST VEL FOR POSITIVE VEL-SENS (-31 TO -1).
V_A_REL_20
               MULS    D4,D3                ;SCALE VELOCITY AGAINST VEL-SENS SETTING.
               ADD     #0BFDH,D3            ;ADD (NEGATIVE) SCALING PRODUCT TO PEAK POSITIVE VALUE.
               MULU    #0AAD6H,D3           ;FUDGE FACTOR FOR INTERMEDIATE PRODUCT.
               SWAP    D3                   ;THIS IS THE PART WE WANT.
               MOVE.B  S_A_INIT_REL(A4),D4  ;FETCH INITIAL VCA RELEASE RATE SETTING.
               EXT.W   D4                   ;EXTEND TO WORD (IT'S SIGNED),
               MULS    D4,D3                ;SCALE RATE SETTING BY PRODUCTO INTER-MEEDO.
               LSL.L   #5,D3                ;COMPLETE THE DAMAGE TO GET A -99 TO +99 RESULT.
               SWAP    D3
               BRA.S   N_A_REL_20           ;FROM HERE, SAME AS NON-VEL INIT (PITCH TRACK, ETC).
;
;AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
;
;
;
;VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV
;
; INITIALIZE VCA RELEASE RATE - NO VELOCITY MOD.
; COMING FROM V_INIT_A_RELEASE, WE ENTER PARTWAY THROUGH WITH VEL-MODDED
; RELEASE RATE SETTING (INDEX) IN D3.
;
; NOTE:  HOOKS FOR REVERSE RELEASE ARE PRESENT, CARRIED OVER FROM ATTACK
; INITIALIZATION ROUTINES, BUT ELSEWHERE THIS IS NOT YET IMPLEMENTED.
; CHANGES WOULD BE REQ'D IN DYNAMIC_ASSIGN (TWO DIFFERENT RELEASE
; VECTORS TO CHECK FOR), AS WELL AS IN VOICE_GATE_OFF (DETERMINING WHICH
; RELEASE VECTOR TO USE AT GATE-OFF TIME).
;
N_INIT_A_RELEASE
               MOVE.B  S_A_INIT_REL(A4),D3  ;FETCH UN-VEL-MODDED RELEASE RATE FROM SOUND SUB-BLOCK.
               EXT.W   D3                   ;IT'S SIGNED, SO EXTEND IT.
N_A_REL_20
                                            ;ENTER HERE FROM V_INIT_A_RELEASE.
;
               MOVE.B  S_A_PITCH_REL(A4),D1 ;FETCH RELEASE PITCH-TRACK SETTING.
               EXT.W   D1                   ;EXTEND IT TO WORD (YAH, IT'S SIGNED),
               BEQ.S   N_A_REL_30           ;BRANCH IF ZERO, SKIP PITCH-TRACK COMPUTATION.
               MOVE    D1,D2                ;ELSE, MOVE IT OVER HYAR,
               MOVE    V_PITCH_DELTA(A1),D1 ;FETCH DELTA FROM NOMINAL PITCH INTO D1.
               BEQ.S   N_A_REL_30           ;AGAIN - BRANCH IF ZERO, SKIP PITCH-TRACK COMPUTATION.
               MULS    D2,D1                ;ELSE - DO THE BASIC SCALING,
               MULS    #093CH,D1            ;THEN DO THE SCALING ARBITRAIRE -
               SWAP    D1                   ;THIS IS THE PART WE WANT.
N_A_REL_30
               TST     D3                   ;IS RELEASE RATE SETTING NEGATIVE (REVERSE RELEASE)?
               BPL.S   N_A_REL_40           ;BRANCH IF NOT, GO DEAL WITH FORWARD RELEASE.
               MOVE.L  #X_GRO_TBL,A5        ;ELSE POINT TO EXPONENTIAL-GROWTH RATE TABLE,
               NEG     D3                   ;BRING RATE SETTING BACK INTO POSITIVELAND -
               BRA.S   N_A_REL_60           ;GO ADD IT ALL UP AND DO LIMIT CHECK.
N_A_REL_40
               MOVE.L  #X_DEC_TBL,A5        ;FORWARD REL, POINT TO EXPONENTIAL-DECAY RATE TABLE.
N_A_REL_60
               ADD     D1,D3                ;THROW PITCH-DELTA ONTO BASIC/VEL SETTING,
               BGE.S   N_A_REL_80           ;LIMIT FINAL VALUE TO 0-99.
               CLR     D3
               BRA.S   N_A_REL_A0
N_A_REL_80
               CMP     #99,D3
               BLE.S   N_A_REL_A0
               MOVEQ   #99,D3
N_A_REL_A0
               ADD     D3,D3                ;CONVERT FINAL RESULT INTO WORD OFFSET,
               MOVE    D3,-(A7)             ;STASH IT FOR STORE TO BLOCK (WE'LL NEED IT FOR ANY
                                            ;LATER MODULATION OF RELEASE RATE ON THE FLY).
               MOVE.L  #X_TIME_TBL,A6
               MOVE    0(A6,D3),-(A7)       ;NOW FETCH THE ACTUAL TIME VALUE, STASH IT TOO.
               ADD     D3,D3                ;CONVERT FINAL RESULT INTO LONG-WORD INDEX,
               MOVE.L  0(A5,D3),-(A7)       ;FETCH RATE FACTOR FROM THE SELECTED TABLE.
               MOVEQ   #3,D1                ;INDICATE BLOCK OF FOUR WORDS TO UNSTACK AND STORE.
               MOVE    #V_A_REL_RATE,D2     ;FETCH OFFSET OF THIS PARAMETER IN VOICE SUB-BLOCK.
               JMP     4(A0)                ;RETURN TO BLOCK STORE POINT.
;
;AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
               SKIP
;VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV
;
; INITIALIZE VCA SUSTAIN TIME INCLUDING VELOCITY MOD.
; UNTIL FURTHER NOTICE, UTILIZES X_DEC_TBL (SAME AS ATTACK/RELEASE)
; TO COMPUTE SUSTAIN TIME - SO SUSTAIN TIME AND ATTACK/RELEASE RATE
; SETTINGS SHOULD CORRESPOND PRETTY CLOSELY.
; WHAT'S THAT?  THEY DON'T?  SIR, SHOOT YOURSELF.
; IN SOOTH, WE'LL NOT BE GETTIN' THRU THIS WAY IF VEL-SENSITIVITY BE 0,
; SO WE'LL NOT BE BOTHR'D TO TEST FOR THIS.
;
V_INIT_A_TIME
               MOVE.B  S_A_INIT_TIME(A4),D3 ;FETCH VCA SUSTAIN TIME SETTING.
               EXT.W   D3                   ;IT'S SIGNED - SORT OF.
               BMI     N_A_TIME_C0          ;IF SETTING IS NEGATIVE, SET UP FOR GATE MODE.
               BNE.S   V_A_TIME_20          ;IF SETTING NOT = 0, COMPUTE VEL-MODDED TIME SETTING.
               BRA.S   N_A_TIME_20          ;IF = 0, VEL-MOD IRRELEVANT - BUT DO PITCH TRACK.
V_A_TIME_20
               MOVE    V_VELOCITY(A1),D5    ;FETCH EVENT VELOCITY (1-31).
               MOVE.B  S_A_VEL_TIME(A4),D4  ;FETCH VCA SUSTAIN TIME VEL-SENSITIVITY SETTING.
               EXT.W   D4                   ;EXTEND TO WORD FOR SCALE OPERATION -
               BMI.S   V_A_TIME_40          ;BRANCH IF VEL-SENS NEGATIVE,
               SUB     #32,D5               ;ELSE ADJUST VEL FOR POSITIVE VEL-SENS (-31 TO -1).
V_A_TIME_40
               MULS    D4,D5                ;SCALE VELOCITY AGAINST VEL-SENS SETTING.
               ADD     #0BFDH,D5            ;ADD (NEGATIVE) SCALING PRODUCT TO PEAK POSITIVE VALUE.
               MULU    #0AAD6H,D5           ;FUDGE FACTOR FOR INTERMEDIATE PRODUCT.
               SWAP    D5                   ;THIS IS THE PART WE WANT.
               MULU    D5,D3                ;SCALE TIME SETTING (D3, YES?) BY PRODUCTO INTER-MEEDO.
               LSL.L   #5,D3                ;COMPLETE THE DAMAGE TO GET A -99 TO +99 RESULT.
               SWAP    D3
               BRA.S   N_A_TIME_20          ;FROM HERE, SAME AS NON-VEL INIT (PITCH TRACK, ETC).
;
;AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
;
;
;
;VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV
;
; INITIALIZE VCA SUSTAIN TIME - NO VELOCITY MOD.
; UNTIL FURTHER NOTICE, UTILIZES X_DEC_TBL (SAME AS ATTACK/RELEASE)
; TO COMPUTE SUSTAIN TIME - SO SUSTAIN TIME AND ATTACK/RELEASE RATE
; SETTINGS SHOULD CORRESPOND PRETTY CLOSELY.
; COMING FROM V_INIT_A_TIME, WE ENTER PARTWAY THROUGH WITH VEL-MODDED
; SUSTAIN TIME SETTING (INDEX) IN D3.
;
N_INIT_A_TIME
               MOVE.B  S_A_INIT_TIME(A4),D3 ;FETCH VCA SUSTAIN TIME SETTING.
               EXT.W   D3                   ;IT'S SIGNED - SORT OF.
               BMI.S   N_A_TIME_C0          ;IF SETTING IS NEGATIVE, SET UP FOR GATE MODE.
N_A_TIME_20
                                            ;ENTER HERE FROM V_INIT_A_TIME.
;
               MOVE.B  S_A_PITCH_TIME(A4),D1     ;FETCH SUSTAIN TIME PITCH-TRACK SETTING.
               EXT.W   D1                        ;EXTEND IT TO WORD (YAH, IT'S SIGNED),
               BEQ.S   N_A_TIME_30               ;BRANCH IF ZERO, SKIP PITCH-TRACK COMPUTATION.
               MOVE    D1,D2                ;ELSE, MOVE IT OVER HYAR,
               MOVE    V_PITCH_DELTA(A1),D1 ;FETCH DELTA FROM NOMINAL PITCH INTO D1.
               BEQ.S   N_A_TIME_30          ;AGAIN - BRANCH IF ZERO, SKIP PITCH-TRACK COMPUTATION.
               MULS    D2,D1                ;DO THE BASIC SCALING,
               MULS    #093CH,D1            ;THEN DO THE SCALING ARBITRAIRE -
               SWAP    D1                   ;THIS IS THE PART WE WANT.
               ADD     D1,D3                ;ADD PITCH-TRACK DELTA TO BASIC/VEL SETTING.
N_A_TIME_30
               TST     D3                   ;LIMIT FINAL VALUE TO 0-99.
               BPL.S   N_A_TIME_40
               CLR     D3
               BRA.S   N_A_TIME_60
N_A_TIME_40
               CMP     #99,D3
               BLE.S   N_A_TIME_60
               MOVEQ   #99,D3
N_A_TIME_60
               ADD     D3,D3                ;CREATE WORD OFFSET,
               MOVE    D3,A5
               ADD.L   #SUSTAIN_TABLE,A5    ;BUMP UP INTO SUSTAIN-TIME TABLE,
               MOVE    (A5),D1              ;FETCH THAT COUNT.
;
               BRA.S   N_A_TIME_E0
N_A_TIME_C0
               MOVEQ   #-1,D1               ;NEGATIVE VALUE INDICATES GATE MODE.
N_A_TIME_E0
               MOVE    #V_A_SUS_TIME,D2     ;FETCH OFFSET OF THIS PARAMETER IN VOICE SUB-BLOCK.
               JMP     (A0)                 ;RETURN TO WORD-STORE POINT.
;
;AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
               SKIP
;VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV
;
; INITIALIZE VCA LEVEL (VOLUME) - NO VELOCITY MOD.
;
N_INIT_A_LEVEL
               MOVE    V_LEVEL(A1),D1       ;FETCH VOLUME SETTING FOR THIS EVENT.
               ADD     D1,D1                ;CONVERT TO WORD OFFSET FOR LEVEL TABLE.
               MOVE.L  #LEVEL_TABLE,A5      ;SET POINTER TO LEVEL TABLE.
               MOVE    0(A5,D1),D1          ;FETCH LEVEL COEFFICIENT FOR THIS VOLUME SETTING.
               CLR     D2                   ;FETCH SOUND LEVEL SETTING (NOT EVENT LEVEL SETTING!)
               MOVE.B  S_A_LEVEL(A4),D2     ;THIS IS ALSO 0-31 -
;
;06DEC;
;06DEC               BNE.S   N_A_LEV_10           ;IF NOT = 0, DO A LEVEL_TABLE LOOKUP -
;06DEC               CLR     D1                   ;ELSE, RETURN V_A_SUS_LEVEL = 0 TO ALLOW COMPLETE
;06DEC               BRA.S   N_A_LEV_20           ;SILENCING OF A SOUND (E.G. IN A SEQUENCE REMIX).
;06DECN_A_LEV_10
;06DEC;                ZERO S_A_LEVEL TRAPPED BY VOICE_ASSIGN, WE WON'T EVER SEE IT.
;
               ADD     D2,D2                ;CONVERT IT TO WORD OFFSET,
               MULU    0(A5,D2),D1          ;WELL UM I GUESS THATS IT
               SWAP    D1                   ;NO NOW THATS IT
N_A_LEV_20
               MOVE    #V_A_SUS_LEVEL,D2    ;FETCH OFFSET OF THIS PARAMETER IN VOICE SUB-BLOCK.
               JMP     (A0)                 ;RETURN TO WORD-STORE POINT.
;
;AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
;
;
;
;VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV
;
; INITIALIZE VCA LEVEL (VOLUME) INCLUDING VELOCITY MOD.
; IN SOOTH, WE'LL NOT BE GETTIN' THRU THIS WAY IF VEL-SENSITIVITY BE 0,
; SO WE'LL NOT BE BOTHR'D TO TEST FOR THIS.
;
V_INIT_A_LEVEL
               MOVE    V_VELOCITY(A1),D1    ;FETCH EVENT VELOCITY (1-31).
               MOVE.B  S_A_VEL_LEVEL(A4),D2 ;FETCH SOUND LEVEL VEL-SENSITIVITY SETTING.
               EXT.W   D2                   ;EXTEND TO WORD FOR SCALE OPERATION -
               BMI.S   V_A_LEV_20           ;BRANCH IF VEL-SENS NEGATIVE,
               SUB     #32,D1               ;ELSE ADJUST VEL FOR POSITIVE VEL-SENS (-31 TO -1).
V_A_LEV_20
               MULS    D2,D1                ;SCALE VELOCITY AGAINST VEL-SENS SETTING.
               ADD     #0BFDH,D1            ;ADD (NEGATIVE) SCALING PRODUCT TO PEAK POSITIVE VALUE.
               MULS    #296H,D1             ;FUDGE FACTOR - M.S.WORD SHOULD NOW BE 1-31 -
               SWAP    D1                   ;USE IT TO INDEX INTO LEVEL_TABLE,
               ADD     D1,D1                ;IN THE FORM OF A WORD OFFSET -
               MOVE.L  #LEVEL_TABLE,A5      ;FETCH PEAK UNSCALED LEVEL VALUE PER VELOCITY*SENS.
               MOVE    0(A5,D1),D1
;
               MOVE    V_LEVEL(A1),D2       ;FETCH EVENT LEVEL SETTING,
               ADD     D2,D2                ;CONVERT IT TO WORD OFFSET,
               MULU    0(A5,D2),D1          ;SCALE (VEL)(VEL-SENS) PRODUCT BY EVENT LEVEL SETTING.
               SWAP    D1                   ;BACK - TO THE M.S.WORD OF PRODUCT.
               CLR     D2                   ;FETCH SOUND LEVEL SETTING (NOT EVENT LEVEL SETTING!)
               MOVE.B  S_A_LEVEL(A4),D2     ;THIS IS ALSO 0-31, LIKE VELOCITY AND EVENT LEVEL -
;
;06DEC;
;06DEC               BNE.S   V_A_LEV_40           ;IF NOT = 0, DO A LEVEL_TABLE LOOKUP -
;06DEC               CLR     D1                   ;ELSE, RETURN V_A_SUS_LEVEL = 0 TO ALLOW COMPLETE
;06DEC               BRA.S   V_A_LEV_80           ;SILENCING OF A SOUND (E.G. IN A SEQUENCE REMIX).
;06DECV_A_LEV_40
;06DEC;                ZERO S_A_LEVEL TRAPPED BY VOICE_ASSIGN, WE WON'T EVER SEE IT.
;
               ADD     D2,D2                ;CONVERT IT TO WORD OFFSET,
               MULU    0(A5,D2),D1          ;WELL UM I GUESS THATS IT
               SWAP    D1                   ;NO NOW THATS IT
;
;03DEC               CMP     #510H,D1             ;MAINTAIN LEVEL ABOVE LIMIT OF AUDIBILITY -
;03DEC               BCC.S   V_A_LEV_80           ;ALSO ABOVE LIMIT OF S-H/VCA FLAKY-NESS.
;03DEC               MOVE    #510H,D1             ;THIS IS BARELY AUDIBLE, POOTY MUSH.
;              NOTE - VCA FLOOR LEVEL IMPOSED VIA NON-PRIO ROUTINES AND V_CUR_VCA.
               CMP     #000H,D1             ;BOGUS LIMIT TO ALLOW EMULATOR TWEAKS.
               BCC.S   V_A_LEV_80
               MOVE    #510H,D1
;
V_A_LEV_80
               MOVE    #V_A_SUS_LEVEL,D2    ;FETCH OFFSET OF THIS PARAMETER IN VOICE SUB-BLOCK.
               JMP     (A0)                 ;RETURN TO WORD-STORE POINT.
;
;AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
               SKIP
;VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV
;
; INITIALIZE VCA ATTACK RATE INCLUDING VELOCITY MOD.
; IN SOOTH, WE'LL NOT BE GETTIN' THRU THIS WAY IF VEL-SENSITIVITY BE 0,
; SO WE'LL NOT BE BOTHR'D TO TEST FOR THIS.
;
V_INIT_A_ATTACK
               MOVE    V_VELOCITY(A1),D3    ;FETCH EVENT VELOCITY (1-31).
               MOVE.B  S_A_VEL_ATT(A4),D4   ;FETCH VCA ATTACK RATE VEL-SENSITIVITY SETTING.
               EXT.W   D4                   ;EXTEND TO WORD FOR SCALE OPERATION -
               BMI.S   V_A_ATT_20           ;BRANCH IF VEL-SENS NEGATIVE,
               SUB     #32,D3               ;ELSE ADJUST VEL FOR POSITIVE VEL-SENS (-31 TO -1).
V_A_ATT_20
               MULS    D4,D3                ;SCALE VELOCITY AGAINST VEL-SENS SETTING.
               ADD     #0BFDH,D3            ;ADD (NEGATIVE) SCALING PRODUCT TO PEAK POSITIVE VALUE.
               MULU    #0AAD6H,D3           ;FUDGE FACTOR FOR INTERMEDIATE PRODUCT.
               SWAP    D3                   ;THIS IS THE PART WE WANT.
               MOVE.B  S_A_INIT_ATT(A4),D4  ;FETCH INITIAL VCA ATTACK RATE SETTING.
               EXT.W   D4                   ;EXTEND TO WORD (IT'S SIGNED),
               MULS    D4,D3                ;SCALE RATE SETTING BY PRODUCTO INTER-MEEDO.
               LSL.L   #5,D3                ;COMPLETE THE DAMAGE TO GET A -99 TO +99 RESULT.
               SWAP    D3
               BRA.S   N_A_ATT_20           ;FROM HERE, SAME AS NON-VEL INIT (PITCH TRACK, ETC).
;
;AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
;
;
;
;VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV
;
; INITIALIZE VCA ATTACK RATE - NO VELOCITY MOD.
; ALSO INITIALIZES VCA VECTOR AND RAW VCA ENVELOPE POINT,
; WITH PROVISION FOR INSTANT-ON ATTACK.
; COMING FROM V_INIT_A_ATTACK, WE ENTER PARTWAY THROUGH WITH VEL-MODDED
; ATTACK RATE SETTING (INDEX) IN D3.
;
N_INIT_A_ATTACK
               MOVE.B  S_A_INIT_ATT(A4),D3  ;FETCH UN-VEL-MODDED ATTACK RATE FROM SOUND SUB-BLOCK.
               EXT.W   D3                   ;IT'S SIGNED, SO EXTEND IT.
N_A_ATT_20
                                            ;ENTER HERE FROM V_INIT_A_ATTACK.
;
               MOVE.B  S_A_PITCH_ATT(A4),D1 ;FETCH ATTACK PITCH-TRACK SETTING.
               EXT.W   D1                   ;EXTEND IT TO WORD (YAH, IT'S SIGNED),
               BEQ.S   N_A_ATT_30           ;BRANCH IF ZERO, SKIP PITCH-TRACK COMPUTATION.
               MOVE    D1,D2                ;ELSE, MOVE IT OVER HYAR,
               MOVE    V_PITCH_DELTA(A1),D1 ;FETCH DELTA FROM NOMINAL PITCH INTO D1.
               BEQ.S   N_A_ATT_30           ;AGAIN - BRANCH IF ZERO, SKIP PITCH-TRACK COMPUTATION.
               MULS    D2,D1                ;ELSE - DO THE BASIC SCALING,
               MULS    #093CH,D1            ;THEN DO THE SCALING ARBITRAIRE -
               SWAP    D1                   ;THIS IS THE PART WE WANT.
N_A_ATT_30
;
               MOVE.L  #3000000H,D4         ;INITIAL VCA VALUE - THIS IS THE FIRST POINT OF
                                            ;ATTACK ENVELOPE (ASSUMING NON-INSTANT-ON RATE).
               TST     D3                   ;HAVAGANDA AT ATTACK RATE SETTING - NEGATIVE OR WHAT?
               BEQ.S   N_A_ATT_90           ;BRANCH IF ZERO, MEANS INSTANT-ON ATTACK.
               BPL.S   N_A_ATT_40           ;BRANCH IF POSITIVE, GO DEAL WITH FORWARD ATTACK.
               MOVE.L  #X_GRO_TBL,A5        ;ELSE POINT TO EXPONENTIAL-GROWTH RATE TABLE,
               MOVE    #VCA_REV_ATTACK,D5   ;SET UP FOR VCA REVERSE ATTACK VECTOR,
               NEG     D3                   ;BRING RATE SETTING BACK INTO POSITIVELAND -
               BRA.S   N_A_ATT_60           ;GO ADD IT ALL UP AND DO LIMIT CHECK.
N_A_ATT_40
               MOVE.L  #X_DEC_TBL,A5        ;FORWARD ATTACK, POINT TO EXPONENTIAL-DECAY RATE TABLE.
               MOVE    #VCA_FWD_ATTACK,D5   ;SET UP FOR VCA FORWARD ATTACK VECTOR.
N_A_ATT_60
               ADD     D1,D3                ;THROW PITCH-DELTA ONTO BASIC/VEL SETTING,
               BGT.S   N_A_ATT_80           ;LIMIT FINAL VALUE TO 1-99.
               MOVEQ   #1,D3                ;IF IT WENT NEGATIVE, SET IT = 1.
               BRA.S   N_A_ATT_88
N_A_ATT_80
               CMP     #99,D3
               BLT.S   N_A_ATT_88           ;IF LESS THAN 99, ALL COOL -
               MOVEQ   #98,D3               ;"MAX"ED-OUT - SET RATE = 98 (NO INFINITE ATTACK TIME).
N_A_ATT_88
               MOVE.L  #X_TIME_TBL,A6       ;FETCH ATTACK TIME VALUE -
               ADD     D3,D3                ;CONVERT FINAL RATE RESULT INTO WORD OFFSET,
               MOVE    0(A6,D3),D6          ;FOTCH TIME VALUE INTA D6.
               BRA.S   N_A_ATT_A0
;
N_A_ATT_90
               MOVE    #VCA_SUSTAIN,D5      ;INSTANT ATTACK - SKIP ATTACK PHASE, START IN SUSTAIN.
;
;03DEC               MOVE.L  #0FFF00000H,D4       ;SET VCA RAW ENVELOPE POINT FOR USE BY RELEASE VECTOR
;03DEC                                            ;AFTER SUSTAIN PHASE IS EXITED.
               MOVE.L  #0FAE00000H,D4       ;SET VCA RAW ENVELOPE POINT FOR USE BY RELEASE VECTOR
                                            ;AFTER SUSTAIN PHASE IS EXITED (NOTE - REDUCED VALUE TO
                                            ;ALLOW FOR VCA FLOOR LEVEL IN NON_PRIO VCA ROUTINES).
;
               ADD     D3,D3                ;FOR FORM'S SAKE - STAY IN SYNC WITH NON-INSTANT PATH.
               CLR     D6                   ;NO ATTACK, HENCE NO ATTACK TIME.
N_A_ATT_A0
               MOVE    D6,-(A7)             ;STASH ATTACK TIME VALUE.
               ADD     D3,D3                ;CONVERT RATE WORD OFFSET INTO LONG-WORD OFFSET,
               MOVE.L  0(A5,D3),-(A7)       ;FETCH RATE FACTOR FROM THE SELECTED TABLE ONTO STACK,
               MOVE.L  D4,-(A7)             ;STASH INITIAL VCA ENVEOPE POINT VALUE ON STACK,
               MOVE    D5,-(A7)             ;STASH INITIAL VCA VECTOR ON STACK.
               MOVEQ   #5,D1                ;INDICATE BLOCK OF SIX WORDS BEING PASSED.
               MOVE    #V_VCA_VECTOR,D2     ;FETCH OFFSET OF FIRST PARAMETER IN THIS WORD-BLOCK.
               JMP     4(A0)                ;RETURN TO WORD-BLOCK STORE POINT.
;
;AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
               SKIP
;VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV
;
; INITIALIZE PAN VALUE AFTER PITCH-TRACK ADJUSTMENT.
;
INIT_PITCH_PAN
               MOVE.B  S_PAN_VS_PITCH(A4),D1     ;FETCH PAN PITCH-TRACK AMOUNT SETTING,
               EXT.W   D1                        ;EXTEND TO WORD SIZE -
               BEQ.S   I_PAN_10                  ;BRANCH IF = 0, SKIP PITCH-TRACK COMPUTATION.
               MOVE    D1,D2                ;ELSE, MOVE IT OVER HERE,
               MOVE    V_PITCH_DELTA(A1),D1 ;FETCH DELTA FROM NOMINAL PITCH INTO D1.
               BEQ.S   I_PAN_10             ;AGAIN - BRANCH IF = 0, SKIP PITCH-TRACK COMPUTATION.
               MULS    D2,D1
               MULS    #14B0H,D1            ;SCALE TO ALLOW FULL PAN SWING ON +-2 SEMITONE SWING.
               SWAP    D1                   ;THIS IS THE PITCH-DERIVED PAN SETTING DELTA AMOUNT -
I_PAN_10
               ADD     V_PAN(A1),D1         ;COMBINE WITH PAN SETTING FOR THIS EVENT.
               BPL.S   I_PAN_20             ;LIMIT TO 0-31 RANGE, CLIPPING AT X-TREEMS.
               CLR     D1
               BRA.S   I_PAN_40
I_PAN_20
               CMP     #31,D1
               BLE.S   I_PAN_40
               MOVEQ   #31,D1
I_PAN_40
               NEG     D1                   ;INVERT THE RANGE FOR PROPER PAN DIRECTION.
               ADD     #31,D1
               ROR     #5,D1                ;CONVERT 0-31 TO 0-F800H -
               CMP     #8000H,D1            ;AT AND ABOVE THE HALFWAY POINT,
               BCS.S   I_PAN_50
               ADD     #7FFH,D1             ;KICK 'EM UP SO MAX VALUE IS 0FFFFH.
I_PAN_50
               MOVE    #V_PITCH_PAN,D2      ;FETCH OFFSET OF THIS PARAMETER IN VOICE SUB-BLOCK.
               JMP     (A0)                 ;RETURN TO WORD-STORE POINT.
;
;AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
               SKIP
;VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV
;
; INITIALIZE FINAL PITCH INDEX AFTER PITCH-BEND ENVELOPE DIES.
; ALSO INITIALIZE RAW PITCH ENVELOPE VALUE (THOUGH IT MAY NOT BE USED).
;
INIT_FIN_PITCH
               MOVE    V_PITCH_DELTA(A1),D1 ;FETCH DELTA FROM NOMINAL PITCH INTO D1.
               MULS    #-15,D1              ;SCALE SEMITONE OFFSET UP TO TUNE TABLE UNIT (NOT WORD)
                                            ;OFFSET FROM ROOT PITCH TUNING AT EFFECTIVE RATE -
                                            ;(USE NEGATIVE SCALE FACTOR - HIGHER PITCH YIELDS LOWER
                                            ;TUNE TABLE OFFSET).
               CLR     D2                   ;FETCH SAMPLE RATE, CONVERT TO WORD OFFSET.
               MOVE.B  S_RATE(A3),D2
               ADD     D2,D2
               ADD     RATE_TUNE_TABLE(PC,D2),D1 ;ADD IN THE UNIT TUNE TABLE OFFSET OF ROOT PITCH
                                                 ;AT THE EFFECTIVE SAMPLE RATE WITH RESPECT TO ROOT
                                                 ;PITCH TUNING AT 31KHz (viz., #ROOT_TUNE).
;
;
;
               MOVE.B  S_FINE_TUNE(A4),D3   ;TOSS IN THE FINE-TUNE SETTING FROM SELECTED SUB-BLOCK.
               EXT.W   D3
               SUB     D3,D1
               SUB     MASTER_TUNE,D1       ;DON'T NOW BE FORGETFUL OF MASTER TUNING.
               ADD     D1,D1                ;AND OF COURSE, WHAT WE REALLY WANT IS A WORD OFFSET.
;
               CMP     #MAX_TUNE_INDEX,D1   ;SEE THAT WE STAY WITHIN BOUNDS OF TUNE TABLE REALITY.
               BLE.S   I_F_PIT_20
               MOVE    #MAX_TUNE_INDEX,D1
               BRA.S   I_F_PIT_40
I_F_PIT_20
               CMP     #MIN_TUNE_INDEX,D1
               BGE.S   I_F_PIT_40
               MOVE    #MIN_TUNE_INDEX,D1
I_F_PIT_40
;
               SWAP    D1                   ;SWAP FINAL PITCH INDEX RESULT INTO M.S.WORD,
               MOVE    #0FFFFH,D1           ;PUT INITIAL RAW PITCH ENVELOPE POINT INTO L.S.WORD.
               MOVE    #V_FIN_PITCH,D2      ;FETCH OFFSET OF FINAL PITCH INDEX IN VOICE SUB-BLOCK.
               JMP     2(A0)                ;RETURN TO LONG-WORD STORE POINT.
;
;
RATE_TUNE_TABLE
               DC.W    12*15                ;TUNE TABLE UNIT OFFSET FOR 16KHz SAMPLE RATE.
               DC.W    0                    ;TUNE TABLE UNIT OFFSET FOR 31KHz SAMPLE RATE.
               DC.W    -5*15                ;TUNE TABLE UNIT OFFSET FOR 42KHz SAMPLE RATE.
;
;AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
               SKIP
;VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV
;
; INITIALIZE NON-ENVELOPED VCF LEVEL INCLUDING PITCH-TRACK ADJUST.
;
INIT_CUTOFF
               MOVE.B  S_F_PITCH_CUT(A4),D1 ;FETCH CUTOFF PITCH-TRACK SETTING.
               EXT.W   D1                   ;EXTEND IT TO WORD (YAH, IT'S SIGNED),
               BEQ.S   I_CUT_10             ;BRANCH IF ZERO, SKIP PITCH-TRACK COMPUTATION.
               MOVE    D1,D2                ;ELSE, MOVE IT OVER HYAR,
               MOVE    V_PITCH_DELTA(A1),D1 ;FETCH DELTA FROM NOMINAL PITCH INTO D1.
               BEQ.S   I_CUT_10             ;AGAIN - BRANCH IF ZERO, SKIP PITCH-TRACK COMPUTATION.
               MULS    D2,D1                ;ELSE - DO THE BASIC SCALING,
               MULS    #093CH,D1            ;THEN DO THE SCALING ARBITRAIRE -
               SWAP    D1                   ;THIS IS THE PART WE WANT.
I_CUT_10
               CLR     D3                   ;FETCH CUTOFF SETTING ITSELF.
               MOVE.B  S_F_CUTOFF(A4),D3
               ADD     D1,D3                ;ADD IN THE PITCH-TRACK DELTA, IF ANY.
               BPL.S   I_CUT_20             ;CHECK FOR VALID CUTOFF_TABLE INDEX VALUE.
               CLR     D3
               BRA.S   I_CUT_40
I_CUT_20
               CMP     #99,D3
               BLE.S   I_CUT_40
               MOVEQ   #99,D3
I_CUT_40
               ADD     D3,D3                ;CONVERT TO WORD OFFSET FOR CUTOFF TABLE.
               MOVE.L  #CUTOFF_TABLE,A5     ;POINT TO DAT TABLE,
               MOVE    0(A5,D3),D1          ;GET DAT CUTOFF.
               MOVE    #V_F_CUTOFF,D2       ;FETCH OFFSET OF THIS PARAMETER IN VOICE SUB-BLOCK.
               JMP     (A0)                 ;RETURN TO WORD-STORE POINT.
;
;AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
