               INCLUDE HPFIXUPS
               TITLE "PRO_PADS"
***************************************************************************************************
***************************************************************************************************
***                                                                                             ***
***            PRO_PADS - PAD-ON, PAD-OFF BACKGROUND HANDLERS                                   ***
***                                                                                             ***
***************************************************************************************************
***************************************************************************************************
;
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
;
               GLB     PRO_PADS_ON,PRO_PADS_OFF
               GLB     PADS_ON_BOY,PADS_OFF_BOY,PAD_ON_TRANSMIT
               GLB     PAD_ON_AUTOREPEAT,PAD_OFF_AUTOREPEAT
               GLB     PAD_EVENT_ID_TBL,FTSW_EVENT_ID_TBL
               GLB     LIVE_ERASE_SETUP
;
               EXTERNAL  BACK_HANDLER
               EXTERNAL  VOICE_ASSIGN,VOICE_GATE_OFF
               EXTERNAL  LIVE_VOICES_OFF
               EXTERNAL  XMIT_LIVE
               EXTERNAL  PAD_VEL_TBL
               EXTERNAL  LOG_IN_NEW_PAD
               EXTERNAL  LOG_OUT_NEW_PAD
               EXTERNAL  FTPADS_ON_BOY
               EXTERNAL  SEQ_BOUNCE_SUB,BUILD_SONG_SUB2,MUTE_SUB
;
               EXTERNAL  SAMPLED_SOUNDS
               EXTERNAL  PAD_LEVELS
               EXTERNAL  PAD_PITCHES
               EXTERNAL  PAD_PANS
               EXTERNAL  PAD_SOUNDS
               EXTERNAL  NEW_PADS_ON
               EXTERNAL  CUR_PADS_ON
               EXTERNAL  AUTO_PADS_ON
               EXTERNAL  NEW_FTPADS_ON
               EXTERNAL  CUR_FTPADS_ON
               EXTERNAL  KIT_INDEX
               EXTERNAL  EDIT_KIT_INDEX
               EXTERNAL  PAD_VALUE
               EXTERNAL  BUILD_KIT_FLAG
               EXTERNAL  PAD_JUST_HIT
               EXTERNAL  PAD_HIT_FLAG
               EXTERNAL  RECORDING
               EXTERNAL  AUTORPT_FLAG
               EXTERNAL  ASSIGN_BLOCK
               EXTERNAL  CURRENT_SOUND
               EXTERNAL  LEVEL_CHANGE
               EXTERNAL  CURRENT_LEVEL
               EXTERNAL  PITCH_CHANGE
               EXTERNAL  CURRENT_PITCH
               EXTERNAL  PAN_CHANGE
               EXTERNAL  CURRENT_PAN
               EXTERNAL  PAD_XMIT_BUF
               EXTERNAL  PAD_SEQ_BUF
               EXTERNAL  PAD_XMIT_PEND
               EXTERNAL  SEQ_WR_PTR
;
;30SEP               EXTERNAL  PAD_REC_PARSE
;30SEP               EXTERNAL  NOTE_OFF_PARSE
;30SEP               EXTERNAL  WASTE_WR_PTR
               EXTERNAL  PAD_ON_WRITE
               EXTERNAL  NOTE_OFF_WRITE
               EXTERNAL  WASTELAND_PTR
;
               EXTERNAL  NOW_TRACK
               EXTERNAL  ERASING
               EXTERNAL  PAD_ERASE_BUF
               EXTERNAL  FTPAD_ERAS_BUF
               EXTERNAL  INT_ERASE_MAP
               EXTERNAL  FTSW1_OLD_ALT
               EXTERNAL  FTSW2_OLD_ALT
               EXTERNAL  CUR_SUB_BLOCK
               SKIP
;VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV
;
; ENTRY FOR VOICE ASSIGNMENT IN RESPONSE TO PAD EVENTS.
; WE CAME HERE BECAUSE ONE OR MORE BITS WAS SET IN NEW_PADS_ON -
; ONE SUCH BIT WILL BE CLEARED BEFORE WE EXIT, PERHAPS ONE VOICE ASSIGNED.
; NO OTHER INPUTS - ASSUME EVERYTHING DESTROYED, REG-WISE, TO AVOID DISAPPOINTMENT.
;
PRO_PADS_ON
               MOVEQ   #7,D0                ;FUST, WE GOTS TO FIND THE BITCH -
PRO_PON_10
               BCLR    D0,NEW_PADS_ON       ;NOTE SIMULTANEOUS TEST AND CLEAR -
               DBNE    D0,PRO_PON_10        ;LOOP IF THIS IS NOT IT - WE'LL FIND IT YET.
               BSR.S   PADS_ON_BOY          ;ELSE, GIVE IT TO THE BOY,
               BRA     BACK_HANDLER         ;GET BACK TO THE GROUND.
;
;AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
;
;
;
;VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV
;
; AUTOREPEAT PAD-ON EVENT GENERATOR -
; WE COME HERE AT JUST THAT CERTAIN TIME ....
; DETERMINE WHICH PADS ARE ON BY READING PAD_VALUE ARRAY -
; WE USE A FAIRLY HIGH THRESHOLD VALUE FOR THIS TEST, TO AVOID ANY
; POSSIBILTY OF PAD SELF-TRIGGERING, EVEN AFTER HOURS OF THERMAL DRIFT -
; HOWEVER, IF YOU CLOSELY EXAMINE THE BEHAVIOR OF THE PAD VELOCITY
; SENSING SYSTEM, YOU'LL SEE THAT THERE'S LITTLE NET EFFECT OF THE HIGH
; THRESHOLD ON THE END RESULT (MIDI/INTERNAL EVENT VELOCITIES), 'COS THE
; PADS ARE PRETTY DAMNED TOUCHY TO BEGIN WITH.  SO THERE.
; SAVE "ON" PADS BIT MAP IN AUTO_PADS_ON FOR USE BY PAD_OFF_AUTOREPEAT,
; AS WELL AS IN CUR_PADS_ON TO ENABLE INSTANT PERFORMANCE PARAM EDITS.
; PASS THE PAD-ON BIT MAP THROUGH PAD-ON HANDLER TO MAKE THINGS HAPPEN.
;
; NOTE: SEQUENCE-ERASE AND AUTOREPEAT SHOULD NOT BE ALLOWED TO
; EXIST SIMULTANEOUSLY!
;
PAD_ON_AUTOREPEAT
               TST.B   AUTORPT_FLAG         ;BUT - ARE WE IN AUTOREPEAT MODE?
               BEQ.S   PADONAUT_EXIT        ;EXIT IF NOT - WHAT ARE WE DOING HERE?
               CLR     D1                   ;BUILD PAD-ON BIT MAP IN D1.B -
               MOVEQ   #7,D0                ;THIS IS PAD TEST INDEX/COUNT.
               MOVE    #PAD_VALUE+16,A0     ;POINT PAST PAD_VALUE ARRAY FOR PRE-DECREMENT TEST.
PADONAUT_10
               CMP     #40,-(A0)            ;THIS PAD ON AT THE MOMENT?  (ALLOW FOR SOME ADC SLOP)
               BLT.S   PADONAUT_20          ;BRANCH IF NOT,
               BSET    D0,D1                ;ELSE SET HIS BIT, Y'KNOW -
PADONAUT_20
               DBRA    D0,PADONAUT_10       ;LOOP UNTIL ALL PADS TESTED.
;
               MOVE.B  D1,AUTO_PADS_ON      ;SAVE RESULTING PADS-ON BIT MAP.
               MOVE.B  D1,CUR_PADS_ON
               BEQ.S   PADONAUT_EXIT        ;EXIT IF NONE ARE ON.
;
               MOVEQ   #7,D0                ;PAD(S) ON - PASS (ONE AT A TIME) TO PAD ON HANDLER.
PADONAUT_30
               BTST    D0,D1                ;THIS ONE ON?
               BEQ.S   PADONAUT_40          ;SKIP AHAID IF NOT -
               MOVEM   D0-D1,-(A7)          ;ELSE REMEMBER WHERE WE ARE,
               BSR.S   PADS_ON_BOY          ;WAKE UP BOY,
               MOVEM   (A7)+,D0-D1          ;RECALL OUR POSITION.
PADONAUT_40
               DBRA    D0,PADONAUT_30       ;LOOPUNTILWELOOKEDATALLPADS.
;
               MOVE    D1,D4                ;COPY PADS-ON BIT MAP,
               BSR     PAD_XMT_BOY          ;TRANSMIT MIDI/MTC/SEQ EVENTS.
;
PADONAUT_EXIT
               RTS                          ;NOWEBEGON.
;
;AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
               SKIP
;VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV
;
; HANDS-ON, DUMBFUCK PAD-ON HANDLER -
; PAD INDEX IS IN D0, PRESENTED BY EITHER NORMAL PAD-ON DUDE OR HIS
; AUTOREPEAT-TYPE COUSIN.
; WE ALSO CALL HERE WHEN ERASE MODE COMES ON, TO DEAL WITH PADS THAT
; ARE BEING HELD DOWN PRIOR TO ERASE PUNCH-IN (FOR THOSE DIFFICULT-TO-
; HIT EVENTS ON THE FIRST DOWNBEAT).
; NOTE!! IF AUTOREPEATING, DON'T BE ERASING, AND VICE-VERSA ....
; EXPECT PRACTICALLY ALL REGISTERS DESTROYED -
; MAYBE SOMEDAY I'LL GET MORE SPECIFIC ABOUT THIS.
; WELL! - IF IN ERASE MODE, EXPECT TO LOSE D1-D3/A0.
; IF NOT, KISS OFF D1-D7/A0-A2 - AND A LOT MORE TIME, TO BOOT.
; HOWEVER - D0 (PAD INDEX) WILL BE LEFT ALONE, FOR BENEFIT OF ROUTINES
; WHICH CALL FROM A LOOP ON D0.
;
PADS_ON_BOY
                                            ;D0 CONTAINS NUMBER OF PAD BEING ACKNOWLEDGED -
               MOVE    D0,PAD_JUST_HIT      ;RECORD PAD NUMBER OF MOST RECENT PAD HIT.
               ST      PAD_HIT_FLAG         ;SET FLAG TO NOTIFY ANYONE WHO CARES THAT PAD WAS HIT.
               MOVE.L  CUR_SUB_BLOCK,D1     ;MAY BE IN A SCREEN WHICH USES PADS AS EDITING INPUTS:
               CMP.L   #MUTE_SUB,D1         ;ARE WE IN SEQUENCE TRACK MUTE SCREEN?
               BEQ     PADS_ON_EXIT         ;IF SO, PADS ARE MUTED - EXIT W/O EVENT GENERATION.
               CMP.L   #SEQ_BOUNCE_SUB,D1   ;ARE WE IN SEQUENCE BOUNCE-TRACKS SCREEN?
               BEQ     PADS_ON_EXIT         ;IF SO, PADS ARE MUTED - EXIT W/O EVENT GENERATION.
               CMP.L   #BUILD_SONG_SUB2,D1  ;ARE WE IN SONG TRACK-MUTE CHANGE EVENT EDITING SCREEN?
               BEQ     PADS_ON_EXIT         ;IF SO, PADS ARE MUTED - EXIT W/O EVENT GENERATION.
PADS_ON_20
               TST.B   BUILD_KIT_FLAG       ;ARE WE IN KIT-BUILD SCREEN?
               BEQ.S   PADS_ON_24           ;BRANCH IF NOT, PLAY/EDIT SELECTED LIVE PAD ARRAY.
               MOVE    EDIT_KIT_INDEX,D1    ;KIT-BUILD - PLAY/EDIT EDIT-TARGET KIT (DISPLAYED KIT).
               ADD     #32,D1               ;ADD OFFSET SO WE ACCESS PRESET, NOT LIVE PAD, ARRAYS.
               BRA.S   PADS_ON_26
PADS_ON_24
               MOVE    KIT_INDEX,D1         ;NOT KIT-BUILD MODE - USE SELECTED LIVE PAD ARRAY.
               MOVE    D1,EDIT_KIT_INDEX    ;WHEN NOT IN KIT-BUILD MODE, EDIT_KIT_INDEX TRACKS KIT
                                            ;FROM WHICH LAST LIVE EVENT WAS PLAYED.
PADS_ON_26
               ASL     #3,D1                ;(8*KIT_INDEX) GETS SELECTED PAD/KIT ARRAY,
               ADD     D0,D1                ;STEP UP BY PAD NUMBER TO GET SELECTED PAD'S CELL.
               MOVE    D1,A0                ;A0 IS NOW THE PAD PARAMETER INDEX -
               CLR     D1                   ;CLEAR OUT D1 (ESPECIALLY HIGH BYTE),
               MOVE.B  PAD_SOUNDS(A0),D1    ;FETCH SOUND NUMBER (L.S.BIT = ALT PARAMS SETTING).
;
               MOVE    D1,D2                ;PRESERVE SOUND NUMBER / ALT PARAM BIT IN D1,
               MOVE    D1,D3                ;SPLIT SOUND NUMBER AND ALT PARAMS BIT FROM EACH OTHER,
               LSR     #1,D2                ;UPDATE CURRENT_SOUND,
               MOVE    D2,CURRENT_SOUND
               AND     #1,D3                ;ISOLATE ALT-PARAMS SETTING.
;
               TST.B   ERASING              ;ARE WE IN ERASE MODE?
               BEQ.S   PADS_ON_30           ;BRANCH IF NOT, PROCEED WITH NORMAL EVENT PROCESSING.
               MOVE    D0,A0                ;ELSE STORE SOUND NUMBER / ALT BIT IN PAD ERASE BUFFER.
               MOVE.B  D1,PAD_ERASE_BUF(A0)
               BTST    #0,D1                ;IS ALT PARAMS BIT SET FOR THIS PAD?
               BNE.S   PADS_ON_2E           ;BRANCH IF YES, EDIT ERASE-MAP UPPER LONG-WORD.
               MOVE.L  INT_ERASE_MAP,D3     ;ELSE EDIT LOWER LONG-WORD.
               BSET    D2,D3                ;SET BIT CORRESPONDING TO SOUND NUMBER (SANS ALT BIT).
               MOVE.L  D3,INT_ERASE_MAP
               BRA     PADS_ON_EXIT         ;THAT'S ALL WE DO DURING ERASE.
PADS_ON_2E
               MOVE.L  INT_ERASE_MAP+4,D3   ;FOR ALT-PARAMS SOUNDS, EDIT UPPER LONG-WORD.
               BSET    D2,D3                ;SET BIT CORRESPONDING TO SOUND NUMBER (SANS ALT BIT).
               MOVE.L  D3,INT_ERASE_MAP+4
               BRA     PADS_ON_EXIT         ;THAT'S ALL WE DO DURING THE RACE.
;
PADS_ON_30
;
; LOOK FOR AND EXECUTE ANY PENDING PERFORMANCE PARAMETER EDITS:
; NORMALLY, EDITS REMAIN PENDING UNTIL PAD IS HIT, THEN ARE APPLIED TO
; THAT PAD BY THE FOLLOWING CODE (LIVE PAD ARRAYS ONLY).
;
; THE FOLLOWING CONDITIONS PREEMPT PAD-HANDLER EDITS - EDITS ARE
; INSTEAD GRABBED BY BACKGROUND (PAD_EDIT_CHECK), WE NEVER SEE 'EM:
;
; IF IN KIT-BUILD SCREEN, EDITS ARE IMMEDIATELY APPLIED TO LAST PAD HIT,
; IN PRESET ARRAYS OF THE EDIT-TARGET KIT (EDIT_KIT_INDEX) RATHER THAN
; THE KIT INDICATED BY KIT_INDEX.
;
; IF IN INITIAL PAN SCREEN, PAN CHANGES (ONLY) ARE HANDLED IMMEDIATELY,
; IN ARRAYS INDICATED BY KIT_INDEX (LIVE ARRAYS ONLY).
;
; IF NEITHER OF ABOVE CONDITIONS OBTAINS BUT PAD(S) ARE ON WHEN AN EDIT
; IS GENERATED, THE EDIT IS APPLIED IMMEDIATELY TO THOSE PADS, IN ARRAYS
; INDICATED BY KIT_INDEX (AGAIN, LIVE ARRAYS ONLY) - THIS INCLUDES ANY
; FOOTSWITCHES WHICH ARE SET UP AS PAD TRIGGERS.
;
; IN SUMMARY - EDITS DONE HERE ONLY IF NOT IN KIT-BUILD SCREEN/MODE AND
; NO OTHER PADS (OR PAD-FOOTSWITCHES) ARE ON AT THIS TIME.
;
               TST.B   BUILD_KIT_FLAG       ;JUST TO MAKE SURE NOTHING SLIPS THROUGH THE CRACKS ...
               BNE.S   PADS_ON_80           ;SKIP EDIT TESTS IF IN KIT-BUILD SCREEN.
               MOVE.B  CUR_PADS_ON,D4       ;DEFER EDITS TO PAD_EDIT_CHECK IF MULTIPLE PADS ARE ON.
               BCLR    D0,D4                ;THIS IS MAINLY TO GUARANTEE CONSISTENT EDIT ACTION
               OR.B    CUR_FTPADS_ON,D4     ;WHILE IN AUTOREPEAT MODE - DON'T WANT ONE PAD TO GRAB
               BNE.S   PADS_ON_80           ;THE EDIT IF MULTIPLE PADS ARE BEING AUTOREPEATED.
                                            ;(CUR_FTPADS THING IS FOR FOOTSWITCHES ROUTED TO PADS).
;
                                            ;ELSE, PERFORM ANY PENDING EDITS:
PAD_EDIT
               TST.B   LEVEL_CHANGE         ;SOUND LEVEL -
               BEQ.S   PADEDIT_10
               MOVE.B  CURRENT_LEVEL+1,PAD_LEVELS(A0)
PADEDIT_10
               TST.B   PITCH_CHANGE         ;SOUND PITCH -
               BEQ.S   PADEDIT_20
               MOVE.B  CURRENT_PITCH+1,PAD_PITCHES(A0)
PADEDIT_20
               TST.B   PAN_CHANGE           ;SOUND PAN -
               BEQ.S   PADEDIT_30
               MOVE.B  CURRENT_PAN+1,PAD_PANS(A0)
PADEDIT_30
;
;
PADS_ON_60
               SF      LEVEL_CHANGE         ;ACKNOWLEDGE ANY AND ALL PERFORMANCE PARAMETER EDITS.
               SF      PITCH_CHANGE
               SF      PAN_CHANGE
;
;
;
PADS_ON_80
               MOVE.L  SAMPLED_SOUNDS,D4    ;DONE DIDDLING PADS - IS THIS SOUND SAMPLED?
               BTST    D2,D4
               BEQ.S   PADS_ON_A0           ;BRANCH IF NOT - DON'T BOTHER MR.VOICE_ASSIGN.
                                            ;ELSE, SET UP ASSIGN_BLOCK FOR HIM TO CHEW ON -
               MOVE    #2,ASSIGN_BLOCK+0    ;SET ORIGIN CODE TO IDENTIFY THIS AS A PAD EVENT.
               MOVE    D2,ASSIGN_BLOCK+2    ;INSTALL SOUND NUMBER FOR THIS EVENT.
               MOVE    D3,ASSIGN_BLOCK+4    ;INSTALL ALT PARAMS STATUS FOR THIS EVENT.
               CLR.B   ASSIGN_BLOCK+6       ;ASSIGN WITH VEL = 0 (UNLESS IN AUTOREPEAT MODE).
               MOVE.B  PAD_PITCHES(A0),ASSIGN_BLOCK+7 ;INSTALL PERFORMANCE PARAMETERS.
               MOVE.B  PAD_LEVELS(A0),ASSIGN_BLOCK+9
               MOVE.B  PAD_PANS(A0),ASSIGN_BLOCK+11
               MOVE    D0,ASSIGN_BLOCK+12   ;INSTALL PAD NUMBER.
               TST.B   AUTORPT_FLAG         ;ARE WE IN THE AUTOREPEAT WAY?
               BEQ.S   PADS_ON_90           ;BRANCH IF NOT, LEAVE VELOCITY BYTE = 0 FOR ASSIGN.
               MOVE    D0,A1                ;ELSE FETCH CURRENT PAD PRESSURE AS EVENT VELOCITY -
               ADD     A1,A1                ;PRESENT IT TO VOICE_ASSIGN IN GENERIC 5-BIT FORMAT.
               MOVE    PAD_VALUE(A1),D5     ;(FETCH FULL WORD).
               LSR     #1,D5                ;TRANSFORM RAW VELOCITY VIA TABLE LOOKUP,
               BEQ.S   PADS_ON_88           ;TREATING ZEROS AS ONES BY NOT SUBTRACTING 1 FROM THEM,
               SUBQ    #1,D5                ;AND ALL TO STAY IN THE 0-126 OFFSET RANGE FOR TABLE.
PADS_ON_88
               MOVE.L  #PAD_VEL_TBL,A1           ;SET POINTER TO TABLE,
               MOVE.B  0(A1,D5),ASSIGN_BLOCK+6   ;NOW FETCH DOT VALOSSIDY.
;
PADS_ON_90
               MOVE    D0,D5                ;INDEX ON PAD NUMBER INTO PAD EVENT IDENTITY TABLE,
               LSL     #2,D5
               MOVE.L  #PAD_EVENT_ID_TBL,A1      ;SET POINTER TO THE TABLE,
               MOVE.L  0(A1,D5),ASSIGN_BLOCK+14  ;COPY THE STEREOTYPED ID INTO ASSIGN_BLOCK.
               BSR     VOICE_ASSIGN         ;ASSIGN_BLOCK IS COMPLETELY SET UP -
                                            ;GET VOICE PLAY (IF ANY) UNDERWAY.
;
;
;
PADS_ON_A0
;
; AT THIS POINT:
;    D0 CONTAINS EVENT PAD NUMBER.
;    D1 CONTAINS EVENT COMBINED SOUND NUMBER / ALT PARAMS BIT.
;    D2 CONTAINS EVENT SOUND NUMBER.
;    D3 CONTAINS EVENT ALT PARAMS BIT.
;    D4 CONTAINS SAMPLED_SOUNDS MAP.
;    A0 IS PAD/KIT ARRAY INDEX FOR FURTHER ACCESS TO PERFORMANCE PARAMS.
; FOR WHAT IT'S WORTH .....
;
;
;
; SO - IT BE TIME TO KICK DON MIDI AND SIR MTC IN THE BUTT - ALMOST ....
; BAZE-ICLY, WE BUILD AND SAVE THE NOTE-OFF EVENT, THEN SET A BIT FLAG
; TO DENOTE PENDING MIDI/MTC NOTE-ON TRANSMISSION FOR SUCH-AND-SUCH PAD.
; WHEN PAD VEL BECOMES AVAILABLE, SOMEONE IN HIGH-PRIO BACKGROUND COPIES
; THE NOTE-OFF EVENT FROM WHERE WE HAVE SAVED IT, PLUGS IN THE NOTE-ON
; VELOCITY AND HANDS IT TO DR. MIDI / MR. MTC.
;
               MOVE    #PAD_XMIT_BUF,A2     ;A2 POINTS TO ARRAY WHICH HOLDS PAD EVENTS IN
                                            ;READY-FOR-XMIT_LIVE FORMAT, FOR USE BY PRO_PADS_OFF -
               MOVE    D0,D5                ;INDEX ON PAD NUMBER INTO PAD EVENT TABLE.
               ADD     D5,D5
               ADD     D5,D5
               ADD     D5,D5                ;NOW WE ARE 8 * PAD NUMBER -
               ADD     D5,A2                ;POINT TO APPROPRIATE 8-BYTE CELL IN ARRAY -
                                            ;D5 SAVED FOR (POSSIBLE) USE BELOW - SEQ EVENT GEN.
;
               MOVE    D0,(A2)+             ;STORE EVENT PAD NUMBER.
               MOVE    D1,(A2)+             ;STORE EVENT COMBINED SOUND NUMBER / ALT PARAMS BIT.
               MOVE.B  #0,(A2)+             ;DON'T YET KNOW VELOCITY, LEAVE IT = 00.
               MOVE.B  PAD_PITCHES(A0),(A2)+     ;STORE EVENT PITCH SETTING.
               MOVE.B  PAD_PANS(A0),(A2)+   ;STORE EVENT PAN SETTING.
               MOVE.B  PAD_LEVELS(A0),(A2)  ;STORE EVENT LEVEL SETTING.
;
;
;
; THE FOLLOWING PROCEDURE IS ANALOGOUS TO THE ABOVE,
; BUT APPLIES TO GENERATION OF EVENT FOR THE SEQUENCER?  YEAH - THAT'S
; IT - EVENT IS SET UP (SANS VELOCITY) IN AN EVENT ARRAY.  WHEN VELOCITY
; ARRIVES, IT IS PLUGGED INTO EVENT, AND EVENT IS PASSED TO SEQUENCER -
; THIS IS DONE BY SAME ROUTINE WHICH TRANSMITS PAD EVENTS TO MIDI/MTC,
; HAPPENS AT THE SAME TIME IN RESPONSE TO SAME FLAG BIT (PAD_XMIT_PEND
; IF WE'RE NOT IN AUTOREPEAT MODE, OR AUTO_PADS_ON IF WE ARE).
; WHEN PAD-OFF IS DETECTED, FIRST TWO WORDS OF EVENT ARE REGROOMED WITH
; SEQUENCE INTERNAL NOTE-OFF EVENT ID TAG AND PASSED AGAIN TO SEQUENCER.
; OF COURSE, NONE OF THIS HAPPENS IF WE ARE NOT IN NORMAL RECORD MODE.
;
; SEQUENCER FORMAT FOR INTERNAL NOTE-ON EVENT:
;              WORD 0 -  P-P-P S-S-S-S-S A T-T-T 0 0 0 1
;              WORD 1 -  X H-H-H-H-H N-N-N-N-N V-V-V-V-V
;              WORD 2 -  X X X X X X X X X X X L-L-L-L-L
;
; SEQUENCER FORMAT FOR INTERNAL NOTE-OFF EVENT:
;              WORD 0 -  P-P-P S-S-S-S-S A T-T-T 0 0 1 0
;              WORD 1 -  X H-H-H-H-H N-N-N-N-N V-V-V-V-V
;
;                   G = GATE STATUS BIT.
;                   P-P-P = PAD NUMBER.
;                   S-S-S-S-S = SOUND NUMBER.
;                   A = ALT-PARAMS STATUS.
;                   T-T-T = TRACK NUMBER.
;                   H-H-H-H-H = EVENT PITCH.
;                   N-N-N-N-N = EVENT PAN.
;                   V-V-V-V-V = EVENT VELOCITY.
;                   X = UNDEFINED.
;                   L-L-L-L-L = EVENT LEVEL.
;
;
               TST.B   RECORDING            ;ARE WE IN NORMAL-KINDA SEQUENCE-RECORD MODE?
               BEQ.S   PADS_ON_B0           ;BRANCH IF NOT - DON'T BOTHER GENERATING SEQ EVENT.
                                            ;ELSE, GENERATE AN EVENT FOR SEQUENCER -
               MOVE    #PAD_SEQ_BUF,A2      ;SET POINTER TO ARRAY OF PAD-GENERATED SEQ EVENTS.
               ADD     D5,A2                ;OFFSET INTO ARRAY, 8 BYTES PER PAD NUMBER -
                                            ;FOR STREAMLINING, EVEN THOUGH WE ONLY NEED 6 BYTES.
                                            ;(D5 = 8 * PAD NUMBER, FROM MIDI EVENT GEN ABOVE).
               MOVE    D0,D5                ;COPY PAD NUMBER FOR EVENT GENERATION.
               LSL     #6,D5                ;SHIFT PAD NUMBER OVER, MAKE ROOM FOR SOUND#/ALT BIT.
               OR      D1,D5                ;THERE IT GOES.
               LSL     #3,D5                ;STEP ASIDE, MAKE WAY FER TRACK NUMMA -
               OR      NOW_TRACK,D5
               LSL     #4,D5                ;NOW MAKE WAY FOR NOTE-ON EVENT ID -
               BSET    #0,D5                ;EVENT ID = 0001 FOR INTERNAL NOTE-ON EVENT.
               CLR     D6                   ;BUILD PITCH/PAN/VELOCITY WORD IN D6:
               MOVE.B  PAD_PITCHES(A0),D6   ;PITCH GOES IN LEFTMOST,
               LSL     #5,D6
               OR.B    PAD_PANS(A0),D6      ;FOLLOWED BY PAN -
               LSL     #5,D6                ;WE DON'T KNOW VELOCITY YET, SO JUST LEAVE ROOM FOR IT.
               CLR     D7                   ;EVENT LEVEL IS DANGLING OFF IN A WORD OF ITS OWN ....
               MOVE.B  PAD_LEVELS(A0),D7
               MOVEM   D5-D7,(A2)           ;DONE - PUMP 'EM ALL OUT THERE (PAD SEQ EVENT ARRAY).
;
PADS_ON_B0
               TST.B   AUTORPT_FLAG         ;ARE WE A-DOIN' OTTO-RE-PETE?
               BNE.S   PADS_ON_EXIT         ;BRANCH IF YES, NOTHING MORE WE NEED TO DO.
               BSET    D0,PAD_XMIT_PEND     ;ELSE SET FLAG TO INDICATE PAD HAS MIDI/MTC NOTE-ON
                                            ;EVENTS TO TRANSMIT, PENDING READ OF PAD VELOCITY.
;
PADS_ON_EXIT
               RTS
;
;AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
               SKIP
;VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV
;
; PAD-OFF EVENT HANDLER - NON-AUTOREPEAT MODE.
; D4.B CONTAINS BIT-MAP OF PADS NEEDING PAD-OFF SERVICING -
; HANDLES ALL OF 'EM ON A SINGLE PASS THROUGH.
;
; NO BIT FLAGS CLEARED HERE - SOMEONE ELSE'S JOB, MAN.
;
; EXCEPT WHEN IN SEQUENCE-ERASE MODE:
; BLINDLY ASSUMES THAT EACH PAD-ON PLAYED A VOICE, TRIES TO GATE IT OFF.
; PASSES EVENTS TO MIDI/MTC TRANSMIT ROUTINE - IF IN NORMAL RECORD MODE,
; PASSES EVENTS TO SEQUENCER RECORD INPUT PROCESS AS WELL.
;
PRO_PADS_OFF
               BSR.S   PADS_OFF_BOY         ;HAND THIS TO THE BOY,
               BRA     BACK_HANDLER         ;GET BACK HOME.
;
;AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
;
;
;
;VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV
;
; AUTOREPEAT PAD-OFF HANDLER -
; JUST CALL HERE WHEN IT'S TIME.
;
; NOTE: SEQUENCE-ERASE AND AUTOREPEAT SHOULD NOT BE ALLOWED TO
; EXIST SIMULTANEOUSLY!
;
PAD_OFF_AUTOREPEAT
               MOVE.B  AUTO_PADS_ON,D4      ;ANY AUTOREPEAT-PLAYED PADS ON?
               BEQ.S   PADOFAUT_EXIT        ;RETURN ASAP IF NOT,
               SF      AUTO_PADS_ON         ;ELSE ACKNOWLEDGE THEM HERE,
               BSR.S   PADS_OFF_BOY         ;HAND-UM "OFF" TO "BOY."
PADOFAUT_EXIT
               RTS
;
;AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
               SKIP
;VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV
;
; HANDS-ON, DIM-BULB PAD-OFF HANDLER -
; AUTOREPEAT COMES HERE FOR PAD-OFF PROCESSING VIA PAD_OFF_AUTOREPEAT,
; NORMAL MODE PAD-OFF GETS HERE VIA PRO_PADS_OFF.
;
; D4.B CONTAINS BIT-MAP OF PADS NEEDING PAD-OFF SERVICING -
; HANDLES ALL OF 'EM ON A SINGLE PASS THROUGH.
;
; NO BIT FLAGS CLEARED HERE - SOMEONE ELSE'S JOB, MAN.
;
; EXCEPT WHEN ERASING:
; BLINDLY ASSUMES THAT EACH PAD-ON PLAYED A VOICE, TRIES TO GATE IT OFF.
; PASSES EVENTS TO MIDI/MTC TRANSMIT ROUTINE - IF IN NORMAL RECORD MODE,
; PASSES EVENTS TO SEQUENCER RECORD INPUT PROCESS AS WELL.
;
; NOTE!! IF AUTOREPEATING, DON'T BE ERASING, AND VICE-VERSA ....
;
; REGISTER CRUSHAGE:
; IF IN ERASE MODE - D1-D3/A0.
; IF NOT ERASING OR RECORDING - D0-D3/A0 AND D7.
; IF RECORDING - D0-D3/A2-A3 AND A0, A6, D7 (PLUS ANYTHING - ? - WHOMPED
; BY PAD EVENT PARSING AND LOG-OUT HANDLERS).
;
PADS_OFF_BOY
               MOVEQ   #7,D3                ;WALK BACKWARDS THROUGH ARRAYS, BITS FOR EIGHT PADS.
               TST.B   ERASING              ;ARE WE DOING SEQUENCE ERASE?
               BEQ.S   PADS_OFF_0E          ;BRANCH IF NOT - POP DOWN TO EVENT HANDLER STUFF.
               MOVE    #PAD_ERASE_BUF,A0    ;ELSE, THINGS ARE SIMPLER - A0 POINTS TO ERASE BUFFER,
                                            ;WHICH CONTAINS SOUND # / ALT BIT FOR "ON" PADS.
PADS_OFF_02
               BTST    D3,D4                ;WE GOTS A PAD-OFF HERE?
               BEQ.S   PADS_OFF_0C          ;BRANCH IF WE DOESN'T, GO ON TO NEXT PAD IF ANY.
               MOVE.B  0(A0,D3),D1          ;WE DO - SO GET THE SOUND/ALT BIT STORED BY PAD-ON -
               BMI.S   PADS_OFF_0C          ;HO! WAIT A MINUTE - THIS CAN'T BE FOR REAL -
                                            ;MEANS NO "ON" FROM THIS PAD SINCE WE WENT INTO ERASE.
               ROR.B   #1,D1                ;ROTATE ALT BIT INTO BIT 7, SOUND NUMBER DOWN TO 4-0 -
               BMI.S   PADS_OFF_04          ;BRANCH IF ALT BIT SET, EDIT ERASE MAP UPPER WORD.
               MOVE.L  INT_ERASE_MAP,D2     ;ALT BIT NOT SET, WE WANT ERASE MAP LOWER WORD.
               BCLR    D1,D2                ;REMOVE THIS SOUND/ALT-BIT FROM ERASE LIST.
               MOVE.L  D2,INT_ERASE_MAP
               BRA.S   PADS_OFF_0C          ;HEAD FOR NEXT PAD BIT IF ANY.
PADS_OFF_04
               MOVE.L  INT_ERASE_MAP+4,D2   ;ALT BIT SET, WE WANT ERASE MAP UPPER WORD.
               BCLR    D1,D2                ;REMOVE THIS SOUND/ALT-BIT FROM ERASE LIST.
               MOVE.L  D2,INT_ERASE_MAP+4
PADS_OFF_0C
               DBRA    D3,PADS_OFF_02       ;LOOP UNTIL ALL PAD BITS CHECKED.
               BRA.S   PADS_OFF_EXIT        ;THEN, WE'RE GONE.
;
;
PADS_OFF_0E
                                            ;NO, WE'RE NOT ERASING:
               MOVEQ   #28,D2               ;LET D2 BE THE LONG-WORD OFFSET REGISTER,
               MOVE    #56,A0               ;LET A0 BE THE 8-BYTE OFFSET REGISTER.
               TST.B   RECORDING            ;ARE WE RECORDING?
               BEQ.S   PADS_OFF_10          ;BRANCH IF NOT,
               MOVE.L  SEQ_WR_PTR,A6        ;ELSE LOAD WRITE POINTERS FOR SEQUENCE RECORD,
               MOVE    WASTELAND_PTR,A3
;15JAN               MOVE.L  PAD_REC_PARSE,A2     ;ALSO FETCH CURRENT PAD EVENT RECORD-INPUT VECTOR.
               MOVE    NOTE_OFF_WRITE,A2
;
PADS_OFF_10
               BTST    D3,D4                ;IS THIS ONE ONE OF THE ONES?
               BEQ.S   PADS_OFF_20          ;BRANCH IF NOT, STEP TO NEXT ONE IF THERE IS ONE.
;
                                            ;WE GOT ONE! -
;
                                                      ;VOICE GATE-OFF:
               MOVE.L  PAD_EVENT_ID_TBL(PC,D2),D0     ;FETCH VOICE ID VALUE FOR THIS PAD.
               BSR     VOICE_GATE_OFF                 ;THIS ROUTINE WILL FIND HIM AND KILL HIM.
;
                                                 ;MIDI/MTC TRANSMIT:
               MOVE.L  PAD_XMIT_BUF(A0),D0       ;FETCH PAD#/SOUND#/ALT-PARAMS WORD FROM ARRAY.
               MOVE.L  PAD_XMIT_BUF+4(A0),D1     ;FETCH VEL (=0) / PITCH / PAN / LEVEL WORD.
               BSR     XMIT_LIVE                 ;THIS ROUTINE COVERS BOTH MIDI AND MTC TRANSMIT.
;
               TST.B   RECORDING            ;ARE WE IN NORMAL-LIKE RECORD MODE?
               BEQ.S   PADS_OFF_20          ;BRANCH IF NOT - STEP TO NEXT PAD IF ANY.
;
                                            ;SEQUENCE EVENT RECORD:
               MOVE    PAD_SEQ_BUF(A0),D7   ;FETCH FIRST WORD,
               BSET    #1,D7                ;DRESS IT UP AS A NOTE-OFF EVENT HEADER -
               BCLR    #0,D7                ;I.E., L.S.NIBBLE = 0010B.
               JSR     (A2)                 ;PASS IT TO SEQUENCE RECORD INPUT VECTOR.
               SWAP    D7
               MOVE    PAD_SEQ_BUF+2(A0),D7 ;NOW DO THAT OTHER WORD - OK AS IS.
               JSR     (A2)
                ABS_LONG
               JSR     LOG_OUT_NEW_PAD      ;LOG OUT OF CURRENTLY_ON HANDLER
                ABS_SHORT
;
PADS_OFF_20
               SUBQ    #4,D2                ;STEP OFFSET REGISTERS DOWN.
               SUBQ    #8,A0
               DBRA    D3,PADS_OFF_10       ;LOOP UNTIL ALL PADS CHECKED.
;
               TST.B   RECORDING            ;ARE WE RECORDING?
               BEQ.S   PADS_OFF_EXIT        ;EXIT IF NOT,
               MOVE.L  A6,SEQ_WR_PTR        ;ELSE UPDATE SEQUENCE RECORD POINTERS.
               MOVE    A3,WASTELAND_PTR
;
PADS_OFF_EXIT
               RTS
;
;AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
               SKIP
;VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV
;
; V_IDENTITY VALUES FOR PAD EVENTS -
; THEY COME OUT OF ROM, SINCE ALL WE NEED IS PAD NUMBER TO MATCH A VOICE.
; BIT 31 = 1 IDENTIFIES LIVE EVENT, BIT 15 = 0 IDENTIFIES PAD EVENT -
; BIT 30 = 1 TO SIGNIFY GATE ON, PAD NUMBER IS WEDGED INTO BITS 29-27,
; AND THAT'S ALL WE NEED TO DISTINGUISH THESE PUPS FROM THE OTHERS -
; NAMELY MIDI AND SEQUENCER EVENTS.
; THE "PAD" EVENT CATEGORY INCLUDES EVENTS GENERATED BY TRIGGER INPUT
; AND PROGRAMMABLE FOOTSWITCHES, AS WELL AS GENUINE PADS - THE DIAGRAM
; BELOW INDICATES HOW V_IDENTITY VALUES FOR THESE OTHER EVENT TYPES ARE
; DIFFERENT FROM "REAL" PAD EVENT VOICE ID TAG.  THESE EVENTS ARE
; TREATED IDENTICALLY AT ASSIGN AND SEQUENCE-RECORD LEVEL - THE MINOR
; ID DIFFERENCES MINIMIZE CONFUSION AT VOICE GATE-OFF TIME, AS WELL AS
; DIRECTING THE VOICE-SETUP ROUTINE TO THE CORRECT SOURCE FOR DELAYED
; VELOCITY (I.E., EITHER TRIGGER_VALUE OR A CELL IN PAD_VALUE ARRAY).
;
;
;                      BIT 15                       BIT 0
;                        |                             |
;                        V                             V
; PAD EVENT V_IDENTITY:
;              WORD 0 -  1 G P-P-P 0 0 0 0 0 0 0 0 0 0 0
;              WORD 2 -  0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
;
;                   G = GATE STATUS BIT.
;                   P-P-P = PAD NUMBER.
;
; FOOTSWITCH "PAD" EVENT V_IDENTITY:
;              WORD 0 -  1 G 0 0 0 0 0 0 0 0 0 0 0 0 0 0
;              WORD 2 -  0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 F
;
;                   G = GATE STATUS BIT.
;                   F = 0 FOR FOOTSWITCH 1 "PAD" EVENT,
;                       1 FOR FOOTSWITCH 2 "PAD" EVENT.
;
; TRIGGER "PAD" EVENT V_IDENTITY:
;              WORD 0 -  1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
;              WORD 2 -  0 0 0 0 0 0 0 0 1 1 1 1 0 0 0 0
;
;                   NOTE: NO GATE-ON STATE FOR TRIGGER-PAD EVENTS.
;                         NO TABLE - IMMEDIATE CONSTANT USED.
;
;
PAD_EVENT_ID_TBL
               DC.L    0C0000000H      ;PAD 0.
               DC.L    0C8000000H      ;PAD 1.
               DC.L    0D0000000H      ;PAD 2.
               DC.L    0D8000000H      ;PAD 3.
               DC.L    0E0000000H      ;PAD 4.
               DC.L    0E8000000H      ;PAD 5.
               DC.L    0F0000000H      ;PAD 6.
               DC.L    0F8000000H      ;PAD 7.
;
;
FTSW_EVENT_ID_TBL
               DC.L    0C000000EH      ;FOOTSWITCH 1.
               DC.L    0C000000FH      ;FOOTSWITCH 2.
;
;AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
               SKIP
;VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV
;
; PASS PAD NOTE-ON EVENT TO MIDI / MTC HANDLER -
; IF IN NORMAL RECORD MODE, PASS NOTE-ON TO SEQUENCER INPUT AS WELL.
; D4.B CONTAINS BIT MAP OF PADS WHICH ARE TO RECEIVE TRANSMIT SERVICE -
; ALL ACTIVE PADS ARE SERVICED DURING A SINGLE PASS THROUGH HERE.
;
; THE ACTIVE-PADS BIT MAP IS DERIVED IN ONE OF TWO WAYS:
;
; IF NOT IN AUTOREPEAT MODE, WE COME HERE BECAUSE MATCHING BITS WERE SET
; IN PAD_VEL_AVAIL AND IN PAD_XMIT_PEND, MEANING PAD VEL IS AVAILABLE TO
; PLUG INTO OTHERWISE COMPLETE NOTE-ON EVENT(S) WAITING FOR IT.
;
; IF WE ARE DOING AUTOREPEAT, WE COME HERE BECAUSE IT'S THAT TIME AGAIN,
; AND WE FIND THAT YES, PADS ARE ON (BIT-MAPPED IN AUTO_PADS_ON) -
; WHEN WE GET HERE, TRANSMIT-READY EVENTS ARE PRESENT IN BUFFERS,
; HAVING BEEN PLACED THERE BY PASSES THROUGH PRO_PADS_ON.
; AT REPEAT TIME, WE FETCH PRESSURE VALUES FOR ACTIVE PADS AND GO.
;
; EITHER WAY, IT ALL LOOKS THE SAME FROM HERE - THIS ROUTINE DESTROYS
; D0-D4/A0-A3, D7 AND A6, BUT CLEARS NO FLAGS ANYWHERE IN RAM -
; THAT'S NOT ITS JOB.
;
PAD_ON_TRANSMIT
               BSR.S   PAD_XMT_BOY          ;ENTREE FOR NON-AUTOREPEAT BRANCH FROM BACK_HANDLER.
               BRA     BACK_HANDLER
;
PAD_XMT_BOY
               MOVE.L  SEQ_WR_PTR,A6        ;LOAD WRITE POINTERS FOR SEQUENCE RECORD PROCESSES,
               MOVE    WASTELAND_PTR,A3     ;EVEN THOUGH WE MAY NOT NEED THEM.
               MOVE    PAD_ON_WRITE,A2      ;LIKEWISE FOR CURRENT PAD EVENT RECORD-INPUT VECTOR.
               MOVEQ   #7,D3                ;GO THROUGH ALL 8 BITS, PROCESS ALL ACTIVE PADS.
PAD_XMT_20
               BTST    D3,D4
               BEQ.S   PAD_XMT_80           ;SKIP IF WE DIDN'T JUST HIT AN ACTIVE BIT.
;
               MOVE    D3,A0                ;COPY ACTIVE PAD NUMBER.
               ADD     A0,A0                ;GENERATE WORD OFFSET INTO PAD_VALUE ARRAY,
               CLR.L   D1                   ;NOW LET ME MAKE THIS PERFECTLY CLEAR ....
               MOVE    PAD_VALUE(A0),D1     ;FETCH RAW PAD VELOCITY.
               MOVE    D1,D2                ;SAVE THIS - MAY NEED FOR SEQUENCER EVENT.
               LSR     #1,D1                ;SCALE IT DOWN TO 0-7F RANGE -
               BSET    #0,D1                ;MAKE SURE WE DON'T TRANSMIT ZERO VELOCITY.
               ROR.L   #8,D1                ;POSITION IT AS REQ'D FOR MIDI EVENT FORMAT.
               ADD     A0,A0                ;NOW NEED 8-BYTE OFFSET INTO PAD EVENT TRANSMIT ARRAY -
               ADD     A0,A0
               MOVE.L  PAD_XMIT_BUF(A0),D0       ;RETRIEVE PAD # / SOUND # / ALT PARAMS BIT.
               OR.L    PAD_XMIT_BUF+4(A0),D1     ;DROP EVENT PITCH/PAN/LEVEL IN ON TOP OF VELOCITY,
               BSR     XMIT_LIVE                 ;GIVE IT TO THE MIDI/MTC HANDLER.
;
;
               TST.B   RECORDING            ;ARE WE IN NORMAL RECORD MODE?
               BEQ.S   PAD_XMT_80           ;BRANCH IF NOT - LOOP UNTIL ALL PAD BITS CHECKED.
;
;22OCT               MOVE    PAD_TABLE_SEL,D0     ;RECORDING - WHAT PAD CHARACTERISTIC ARE WE USING?
;22OCT               BNE.S   PAD_XMT_40           ;BRANCH IF NON-LINEAR - DO TABLE LOOKUP.
;22OCT               LSR     #3,D2                ;ELSE PERFORM LINEAR PAD-VALUE-TO-VEL CONVERSION,
;22OCT               BNE.S   PAD_XMT_70           ;ALLOWING ONLY NON-ZERO VALUES TO PASS,
;22OCT               MOVEQ   #1,D2
;22OCT               BRA.S   PAD_XMT_70           ;YAH 'N' KEEP MARCHIN'
;22OCT;
;22OCTPAD_XMT_40
;22OCT               LSR     #1,D2                ;TRANSFORM RAW VELOCITY VIA TABLE LOOKUP,
;22OCT               BEQ.S   PAD_XMT_60           ;TREATING ZEROS AS ONES BY NOT SUBTRACTING 1 FROM THEM,
;22OCT               SUBQ    #1,D2                ;AND ALL TO STAY IN THE 0-126 OFFSET RANGE FOR TABLES.
;22OCTPAD_XMT_60
;22OCT               MOVE.L  #PAD_VEL_TABLES,A1   ;SET POINTER TO TABLE OF TABLES,
;22OCT               SUBQ    #1,D0                ;REMOVE OFFSET FROM SELECT SETTING,
;22OCT               ADD     D0,D0                ;FETCH POINTER TO SELECTED TABLE.
;22OCT               ADD     D0,D0
;22OCT               MOVE.L  0(A1,D0),A1
;22OCT               MOVE.B  0(A1,D2),D2          ;NOW FETCH DOT VALOSSIDY.
;22OCTPAD_XMT_70
;
               LSR     #1,D2                ;TRANSFORM RAW VELOCITY VIA TABLE LOOKUP,
               BEQ.S   PAD_XMT_60           ;TREATING ZEROS AS ONES BY NOT SUBTRACTING 1 FROM THEM,
               SUBQ    #1,D2                ;AND ALL TO STAY IN THE 0-126 OFFSET RANGE FOR TABLE.
PAD_XMT_60
               MOVE.L  #PAD_VEL_TBL,A1      ;SET POINTER TO TABLE,
               MOVE.B  0(A1,D2),D2          ;NOW FETCH DOT VALOSSIDY.
;
               OR      D2,PAD_SEQ_BUF+2(A0) ;DROP CONTOURED VELOCITY INTO PRE-FAB SEQ EVENT.
               MOVE.L  PAD_SEQ_BUF(A0),D7   ;LOAD SEQ EVENT FOR TRANSFER TO RECORD MODULE.
               SWAP    D7
               JSR     (A2)                 ;HERE GOES FIRST WORD ....
               SWAP    D7
               JSR     (A2)                 ;THIS WOULD BE THE SECOND ....
                ABS_LONG
               JSR     LOG_IN_NEW_PAD       ;LOG IN TO CURRENTLY ON BUFFER
                ABS_SHORT
               MOVE    PAD_SEQ_BUF+4(A0),D7
               JSR     (A2)                 ;LAST AND PROBABLY LEAST.
;
PAD_XMT_80
               DBRA    D3,PAD_XMT_20        ;LOOP BACK IF WE HAVEN'T CHECKED ALL PAD BITS.
;
               MOVE.L  A6,SEQ_WR_PTR        ;DONE - SAVE POINTERS FOR SEQUENCE RECORD PROCESSES,
               MOVE    A3,WASTELAND_PTR     ;EVEN THOUGH WE MAY NOT HAVE USED THEM.
;
PAD_XMT_EXIT
               RTS
;
;AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
               SKIP
;VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV
;
; DO LIVE-ERASE SETUP -
; CALLED AT ACTUAL ERASE PUNCH-IN TIME.
; COVERS HANGING VOICES, ERASE MAP AND BUFFER INITIALIZATION,
; AND PROCESSING OF PADS ALREADY ON INTO ERASE MAP -
; DOESN'T DEAL WITH AUTOREPEAT QUELCH OR WITH NOTE-OFF EVENT MATCHING
; REQUIRED AT RECORD-TO-ERASE TRANSITION.
; PRESERVES ALL REGISTERS - WILL TEMPORARILY BLOCK LEVEL 3 INTERRUPT,
; LEAVES INTERRUPT LEVEL = 0 UPON EXIT.
;
LIVE_ERASE_SETUP
               MOVEM.L D0-D7/A0,-(A7)       ;COVER REGISTERS USED BY PADS_ON_BOY, FTPADS_ON_BOY.
               MOVE    #2300H,SR            ;GATE OFF ALL LIVE VOICES CURRENTLY GATED ON,
               JSR     LIVE_VOICES_OFF      ;SINCE NOTE-OFF HANDLERS ARE NOW DETOURED AND
               MOVE    #2000H,SR            ;NOTE-OFFS MAY NOT GET TO THE VOICE HANDLER.
;
;05DEC;
;05DEC               CLR.L   INT_ERASE_MAP        ;CLEAR INTERNAL-SOUND ERASE MAP - 32 NON-ALT SOUNDS,
;05DEC               CLR.L   INT_ERASE_MAP+4      ;32 ALTERNATE SOUNDS.
;05DEC;        NO - LET IT BE, SO MIDI "PADS" DON'T GET BOOTED OUT EACH TIME THROUGH RECORD LOOP -
;05DEC;        THERE IS NOW A BACKGROUND DAEMON TO CLEAR THE MAP WHEN WE'RE NOT IN ERASE MODE.
;
               MOVE.L  #-1,PAD_ERASE_BUF    ;WIPE THE PAD ERASE BUFFER CLEAN - IF PAD WAS ALREADY
               MOVE.L  #-1,PAD_ERASE_BUF+4  ;ON WHEN ERASE CAME ON, PAD-OFF WILL USE WHATEVER IS
                                            ;IN BUFFER - MAKE SURE IT'S NOT RANDOM LEFTOVERS.
               MOVE    #-1,FTPAD_ERAS_BUF   ;SAME FOR FOOTSWITCH VERSION OF "PAD" ERASE BUFFER.
;
               SF      NEW_PADS_ON          ;JUST IN CASE - WHOMP 'EM TO AVOID REDUNDANT EXECUTION.
               MOVE.B  CUR_PADS_ON,D4       ;IF ANY PADS ARE ON, ACTIVATE ERASE FOR THEIR SOUNDS.
               BEQ.S   LVERSET_60           ;IF NONE ARE ON AT THE MOMENT, WE BE COOL.
;
               MOVEQ   #7,D0                ;FIND AND PROCESS "ON" PADS.
LVERSET_20
               BTST    D0,D4                ;TEST A PAD BIT,
               BEQ.S   LVERSET_40           ;BRANCH IF THIS PAD NOT CURRENTLY ON,
               BSR     PADS_ON_BOY          ;ELSE GIVE IT TO THE BOY (INDEX IN D0).
LVERSET_40
               DBRA    D0,LVERSET_20        ;LOOP UNTIL 8 PAD BITS CHECKED.
LVERSET_60
;
                                            ;NOW, ONTO FOOTSWITCH "PADS":
               SF      NEW_FTPADS_ON        ;JUST IN CASE - WHOMP 'EM TO AVOID REDUNDANT EXECUTION.
               MOVE.B  CUR_FTPADS_ON,D4     ;IF ANY "PADS" ARE ON, ACTIVATE ERASE FOR THEIR SOUNDS.
               BEQ.S   LVERSET_C0           ;IF NONE ARE ON AT THE MOMENT, WE BE COOL.
               MOVE    FTSW1_OLD_ALT,-(A7)  ;IF WE DOING IT, DON'T ALLOW SAVED ORIGINAL ALT-PARAMS
               MOVE    FTSW2_OLD_ALT,-(A7)  ;SETTING (IF ANY WAS REPLACED BY FOOTSWITCH-ON) TO BE
                                            ;WIPED OUT THIS TIME THROUGH - SAVE IT ...
;
               MOVEQ   #1,D0                ;FIND AND PROCESS "ON" PAD-FOOTSWITCHES -
LVERSET_80
               BTST    D0,D4                ;TEST A PAD-FOOTSWITCH BIT,
               BEQ.S   LVERSET_A0           ;BRANCH IF THIS ONE NOT CURRENTLY ON,
               MOVE    D0,-(A7)             ;ELSE SAVE OUR INDEX ("BOY" WILL DESTROY),
               BSR     FTPADS_ON_BOY        ;GIVE IT TO THE BOY (I.E., D0).
               MOVE    (A7)+,D0             ;GET BACK OUR INDEX.
LVERSET_A0
               DBRA    D0,LVERSET_80        ;LOOP UNTIL 8 PAD BITS CHECKED.
;
               MOVE    (A7)+,FTSW2_OLD_ALT  ;NOW PUT BACK WHATEVER-ALL IT WAS ....
               MOVE    (A7)+,FTSW1_OLD_ALT
;
LVERSET_C0
               MOVEM.L (A7)+,D0-D7/A0
LVERSET_EXIT
               RTS
;
;AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
