               INCLUDE HPFIXUPS
               TITLE "BACKGROUND - MAIN LOOP"
***************************************************************************************************
***************************************************************************************************
***                                                                                             ***
***            BACKGROUN - MODEL 440 BACKGROUND SERVICING ROUTINES                              ***
***                                                                                             ***
***************************************************************************************************
***************************************************************************************************
;
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.
;
               INCLUDE EQUATES         ;HDW ADDR AND CONSTANT DEFS, ABS_SHORT DIRECTIVE.
;
               INCLUDE Q_BLK_EQU       ;SEQUENCE DIRECTORY DEFINITIONS.
;
               INCLUDE SEQDEFS         ;SEQUENCER CONSTANT DEFINITIONS.
;
               GLB     BACK_HANDLER,PROCESS_DATA_POT,LED_DIRECT
               GLB     SUB_INST_VERT
;
               EXTERNAL  V_PRIO_TIME        ;VOICE BLOCK ELEMENTS.
;
               EXTERNAL  TAP_STOP
               EXTERNAL  XMIT_OLD_P_ONS,I_CALC_FPB
               EXTERNAL  XMIT_OLD_M_ONS
               EXTERNAL  XMIT_OLD_P_OFFS,XMIT_OLD_M_OFFS
               EXTERNAL  TAP_IN_PLAY,TAP_IN_UNPAUSE
               EXTERNAL  FAST_WIND_PLAY
               EXTERNAL  PRO_PADS_ON,PRO_PADS_OFF,PAD_ON_TRANSMIT
               EXTERNAL  PRO_FTPADS_ON,PRO_FTPADS_OFF
               EXTERNAL  BKGND_NON_VEL_INIT
               EXTERNAL  VOICE_RELEASER,VOICE_TABLE
               EXTERNAL  PRO_MIDI,PRO_TC,PRO_CLICK,XMIT_VOLUME
               EXTERNAL  STEP_SPP_CUE
               EXTERNAL  REAL_TIMER
               EXTERNAL  SWITCH_BOY,SWITCH_HITTER
               EXTERNAL  INSTALL_SUBFUNCTION,WRITE_PARAMETER
               EXTERNAL  WRITE_ALL_FIELDS,INSTALL_EDIT_FIELD
               EXTERNAL  DISP_BUFFER,UPDATE_CURSOR
               EXTERNAL  DISP_PARAM_FIELD,DISP_FIELD
               EXTERNAL  MODE_4_OUT_SUB,RECORD_TAP_SUB
               EXTERNAL  MOVE_UNIT_SUB
               EXTERNAL  MUTE_SUB
               EXTERNAL  SEQ_ERASE_SUB,SEQ_ERASE_SUB_2
               EXTERNAL  SEQ_VEL_SCALE_SUB
               EXTERNAL  TRANSPOSE_SUB
               EXTERNAL  SDS_OUT_SUB
               EXTERNAL  SDS_REQ_SUB
               EXTERNAL  SEQ_BOUNCE_SUB
               EXTERNAL  INITIAL_PAN_SUB
               EXTERNAL  KIT_REPLACE_SUB
               EXTERNAL  GATE_A_VOICE_OFF
               EXTERNAL  ZERO_THIS_CHIP
               EXTERNAL  TAPPING_SUB
               EXTERNAL  FOOTSW_OFF_BOY
               EXTERNAL  SEQ_CHANGE_SUB
               EXTERNAL  COPY_KIT_TO_PADS
               EXTERNAL  PRO_TRIGGER,TEMPO_CHANGE_SUB
               EXTERNAL  GUIDO_WRITES,DUMP_GUIDO,PLAY_LED_SOLID
               EXTERNAL  BUILD_SONG_SUB,BUILD_SONG_SUB2,BUILD_SONG_SUB3
               EXTERNAL  SEQ_ERROR_DAEMON,RECORD_DAEMON
               .IMPORT SDS_REQ_CHECK
               .import copypro_check
;
               EXTERNAL  PLAY_BLINK_TIMER,SONG_UNBUILD_FLAG
               EXTERNAL  FTSW1_SCROLL,NOW_NUMERATOR
               EXTERNAL  FTSW2_SCROLL
               EXTERNAL  TAP_DIV_FLAG
               EXTERNAL  LAST_TAP_TIME,AUTO_PADS_ON
               EXTERNAL  FORMER_MUTED,NO_POT_CLEAR
               EXTERNAL  SAFE_MUTED
               EXTERNAL  TAP_TRACK_ON_FLAG
               EXTERNAL  NEW_PADS_ON,REAL_LONG_TIME
               EXTERNAL  MA_RCV_CNT
               EXTERNAL  TC_RCV_COUNT,NEW_MUTE_TRACK,TRACKS_MUTED
               EXTERNAL  NEW_PADS_OFF
               EXTERNAL  SPINE_COUNT
               EXTERNAL  SCRN_DM_TIMER
               EXTERNAL  SCRN_DM_PERIOD
               EXTERNAL  SHOWING_TEMPO
               EXTERNAL  CUR_FUN_INDEX
               EXTERNAL  SWITCH_HIT
               EXTERNAL  DEBOUNCE_TIMER
               EXTERNAL  SWITCH_MASK
               EXTERNAL  SWITCH_STAT
               EXTERNAL  SWITCHES_ON
               EXTERNAL  FOOTSW_OFF
               EXTERNAL  SUBFUN_INSTALL
               EXTERNAL  LED_EXTINGUISH
               EXTERNAL  LED_STEADY
               EXTERNAL  LED_SLOW_FLASH
               EXTERNAL  LED_FAST_FLASH
               EXTERNAL  SLOW_LED_TIMER
               EXTERNAL  SLOW_LED_STAT
               EXTERNAL  FAST_LED_TIMER
               EXTERNAL  FAST_LED_STAT
               EXTERNAL  LED_OUT_STAT
               EXTERNAL  CURSOR_TIMER
               EXTERNAL  CURSOR_ENABLE
               EXTERNAL  CURSOR_STAT
               EXTERNAL  POT_VALUE
               EXTERNAL  POT_THRESH
               EXTERNAL  POT_CHANGE_VEC
               EXTERNAL  POT_DIVISIONS
               EXTERNAL  DIVIDED_POT
               EXTERNAL  UPDATE_LCD
               EXTERNAL  REDISP_FIELD
               EXTERNAL  CUR_FLD_BLOCK
               EXTERNAL  CUR_SUB_BLOCK
               EXTERNAL  POSITION_CURS
               EXTERNAL  NON_VEL_INIT
               EXTERNAL  VOICES_TO_OFF
               EXTERNAL  VOICES_TO_REL
               EXTERNAL  CHIPS_TO_ZERO
               EXTERNAL  CURRENT_SOUND,DEL_REC_SOUND
               EXTERNAL  LAST_CUR_SOUND
               EXTERNAL  POT_CHK_INDEX
               EXTERNAL  CURRENT_VOLUME
               EXTERNAL  VOLUME_OUT_VAL
               EXTERNAL  CURRENT_PITCH
               EXTERNAL  CURRENT_LEVEL
               EXTERNAL  CURRENT_PAN
               EXTERNAL  VOLUME_CHANGE
               EXTERNAL  PITCH_CHANGE
               EXTERNAL  LEVEL_CHANGE
               EXTERNAL  PAN_CHANGE
               EXTERNAL  PAD_HIT_FLAG
               EXTERNAL  PAD_JUST_HIT
               EXTERNAL  LAST_PAD_HIT
               EXTERNAL  BUILD_KIT_FLAG
               EXTERNAL  PAD_SOUNDS
               EXTERNAL  KIT_SOUNDS
               EXTERNAL  PAD_PITCHES
               EXTERNAL  PAD_LEVELS
               EXTERNAL  PAD_PANS
               EXTERNAL  CUR_PADS_ON
               EXTERNAL  CUR_FTPADS_ON
               EXTERNAL  FTSW1_ACTION
               EXTERNAL  FTSW1_KIT
               EXTERNAL  FTSW2_ACTION
               EXTERNAL  FTSW2_KIT
               EXTERNAL  KIT_INDEX
               EXTERNAL  EDIT_KIT_INDEX
               EXTERNAL  KITS_EDITED
               EXTERNAL  PAD_XMIT_PEND
               EXTERNAL  PAD_VEL_AVAIL
               EXTERNAL  ALT_PARAM_FLAG
               EXTERNAL  LAST_ALT_PARAM
               EXTERNAL  PAD_CTRL_STAT
               EXTERNAL  MA_RUN_STATUS,MB_RUN_STATUS
               EXTERNAL  REAL_TIME,OLD_REALTIME
               EXTERNAL  WR_FIELDS_FLAG
               EXTERNAL  INST_EDIT_FLAG
               EXTERNAL  CURRENT_SEQUENCE,FORMER_SEQUENCE
               EXTERNAL  RAW_DENOMINATOR
               EXTERNAL  CUE_NEW_SEQ
               EXTERNAL  XPORT_STATE
               EXTERNAL  CUR_TEMPO_BPM,INIT_TEMPO_BPM
               EXTERNAL  DATA_TYPE
               EXTERNAL  CHAN_NUM
               EXTERNAL  BNC_TRK_NUM
               EXTERNAL  LAST_MIDI
               EXTERNAL  OLD_LAST_MIDI,NOW_SEQ_STATUS
               EXTERNAL  TAP_TIME_START
               EXTERNAL  SHOWING_FF_RW
               EXTERNAL  FAST_WIND_TIMER
               EXTERNAL  CLICKS_PENDING
               EXTERNAL  NEW_FTPADS_ON
               EXTERNAL  NEW_FTPADS_OFF
               EXTERNAL  AUTO_FTPADS_ON
               EXTERNAL  NEW_TRIG_ON
               EXTERNAL  TRIG_XMT_PEND
               EXTERNAL  TRIG_TRANSMIT
               EXTERNAL  TRIGGER_VALUE
               EXTERNAL  PENDING_MUTE,MUTE_OFF_TIMER
               EXTERNAL  CLICK_TIME_START,TAP_CLICKS_LEFT
               EXTERNAL  MISC_OUT_STAT,METRO_TONE,LAST_TAP_LENGTH
               EXTERNAL  ED_BLOCK_TIMER
               EXTERNAL  GUIDO_IS_AWAKE
               EXTERNAL  GUIDO_TIMER
               EXTERNAL  GUIDO_FLD_STAT,COUNT_IN_METHOD,LCD_TIMER
               EXTERNAL  SCREEN_BUFFER,ERASING,INT_ERASE_MAP
               EXTERNAL  REPEAT_COUNT
               EXTERNAL  NOW_REPEATING
               EXTERNAL  CLOCK_IN_MODE
               EXTERNAL  CUEING_TO_SPP
               .IMPORT SDS_OUT_NUM
               .IMPORT SDS_REQ_NUM
;
               TITLE   "MAIN BACKGROUND LOOP"
;VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV
;
; MAIN 'LOOP'.  THIS IS A PRIORITIZED BACKGROUND HANDLER - HIGH PRIORITY ITEMS ARE
;  CHECKED FIRST AND THE ONE OF HIGHEST PRIORITY IS SERVICED.  FAILING THAT,  THE
;  LOW-PRIORITY BACKGROUND MAINTENACE ROUTINES ARE ROTATED THROUGH.
;
; IT IS IMPORTANT TO NOTE THAT EACH BACKGROUND ROUTINE, AFTER COMPLETION, JUMPS
;  BACK TO THE TOP, AS OPPOSED TO FALLING THROUGH TO THE NEXT TASK (THUS, THIS IS
;  NOT REALLY A 'LOOP').  THIS WAY, THE HIGH-PRIORITY ITEMS ARE ALWAYS BEING
;  CHECKED AND SERVICED AS QUICKLY AS POSSIBLE.
;
; ALL HIGH-PRIORITY ROUTINES ARE IN THEIR OWN MODULES.  MOST LOW-PRIORITY ROUTINES
;  ARE IN THIS MODULE.
;
; QUESTIONS OF WHICH REGISTERS AND VARIABLES WE USE AND DESTROY ARE IRRELEVANT -
;  WE ARE THE WORLD; EVERYTHING ELSE IS EITHER AN INT OR A SUBROUTINE, AND THEY
;  ARE THE ONES THAT HAVE TO WATCH THEMSELVES.  NOT US.  WE'RE BAD.
;
;
;
; CHECK THE PRIORITY ITEMS FIRST, IN ORDER.
;
BACK_HANDLER
                                            ;OF THE UTMOST PRIORITY - "STOP" SWITCH MUST ALWAYS
                                            ;BE ABLE TO GET THROUGH TO US, EVEN IF BACKGROUND IS
                                            ;SWAMPED TO THE POINT THAT NORMAL SWITCH HANDLER IS NOT
                                            ;GETTING EXECUTED:
               BTST    #5,SWITCH_INPUT+0BH  ;SO - IS ANYONE UP THERE POUNDING ON US?
               BEQ.S   BACKHAND_10          ;BRANCH IF WE DON'T SEE ANYONE, HEAD TO OTHER TESTS.
               TST.B   XPORT_STATE          ;STOP SWITCH DEPRESSED - IS SEQUENCER ENABLED TO PLAY?
               BEQ.S   BACKHAND_10          ;MOVE ON IF NOT (WHY SO DEPRESSED?)
               BSET    #5,SWITCH_STAT+5     ;ELSE - MAKE SWITCH_SCAN THINK IT ALREADY SAW THIS,
               MOVE    #46,SWITCH_HIT       ;SET UP CODE FOR SWITCH-ON HANDLER,
                ABS_LONG
               JMP     SWITCH_HITTER        ;GO STRAIGHT TO THE SWITCH-ON HANDLER.
                ABS_SHORT
BACKHAND_10
;
               TST     TC_RCV_COUNT         ;ANY MESSAGES FROM THE 6803 TIMING CHIP RECENTLY?
               BNE     PRO_TC               ;BRANCH IF YES, GO CHECK 'EM OUT.
;
               TST.B   CUEING_TO_SPP        ;ARE WE ENGAGED IN RESPONDING TO A MIDI SONG-POINTER?
               BNE     STEP_SPP_CUE         ;BRANCH IF YES, STEP LIVELY - NOTE THAT THIS LOCKS OUT
                                            ;ANY LOWER PRIORITY BACKGROUND EXECUTION UNTIL STOPPED,
                                            ;WHICH MIGHT HAPPEN VIA A MESSAGE COMING IN VIA 6803 -
                                            ;AMONG OTHER POSSIBILITIES INCLUDING STOP SWITCH.
                                            ;HENCE, SPP-CUE REQUEST HAS LOWER PRIORITY THAN THESE
                                            ;OTHER THINGS.
;
               TST     MA_RCV_CNT           ;ANY MIDI COME IN RECENTLY?
               BNE     PRO_MIDI             ;IF SO, THEN PROCESS.
;
               TST.B   NEW_PADS_ON          ;ANY FRONT PANEL PADS HIT RECENTLY?
               BNE     PRO_PADS_ON          ;IF SO, THEN PROCESS.
;
               TST.B   NEW_FTPADS_ON        ;ANY FOOTSWITCH "PADS" HIT RECENTLY?
               BNE     PRO_FTPADS_ON        ;IF SO, THEN PROCESS.
;
               TST.B   NEW_TRIG_ON          ;AUDIO TRIGGER INPUT GONE ACTIVE?
               BEQ.S   BACKHAND_30          ;BRANCH IF NOT,
               SF      NEW_TRIG_ON          ;ELSE ACKNOWLEDGE IT,
               BRA     PRO_TRIGGER          ;GO GIT IT.
BACKHAND_30
;
               MOVE.B  PAD_XMIT_PEND,D4     ;ANY PAD-TO-MIDI/MTC/SEQ NOTE-ONS AWAITING PAD VEL?
               BEQ.S   BACKHAND_50          ;SKIP IF NOT -
               AND.B   PAD_VEL_AVAIL,D4     ;ELSE, SEE IF PAD VELOCITY AVAILABLE FOR ANY OF THEM -
               BEQ.S   BACKHAND_50          ;BRANCH IF NO MATCHES, NOTHING TO DO HERE.
               EOR.B   D4,PAD_XMIT_PEND     ;ELSE - ACKNOWLEDGE THE MATCHED BIT(S), WE'RE GONNA GO
               BRA     PAD_ON_TRANSMIT      ;PLUG IN VELOCITY AND SEND NOTE-ON EVENTS AS REQUIRED.
BACKHAND_50
;
               MOVE.B  TRIG_XMT_PEND,D4     ;ANY MIDI/MTC/SEQ EVENTS AWAITING TRIG-IN VELOCITY?
               BEQ.S   BACKHAND_70          ;BRANCH IF NOT.
               MOVE    TRIGGER_VALUE,D4     ;YES - WE GOT A TRIG-IN VELOCITY VALUE YET?
               BEQ.S   BACKHAND_70          ;BRANCH IF NOT.
               SF      TRIG_XMT_PEND        ;YES - STOP PENDING ALREADY,
               BRA     TRIG_TRANSMIT        ;GET THINGS GOING.
BACKHAND_70
;
               TST.B   NON_VEL_INIT         ;ANY VOICES NEED EVENT INITIALIZATION FROM BACKGROUND?
               BNE     BKGND_NON_VEL_INIT   ;IF YES, GO DO ONE - START WITH NON-VEL-DEPENDENT STUF.
;
               TST     CLICKS_PENDING       ;ANY 24 PPQN CLICKS HIT RECENTLY?
               BEQ.S   BACKHAND_80          ;BRANCH IF NOT, MOVE ON DOWN THE LINE -
               BSR     PRO_CLICK            ;ELSE, GO PROCESS ONE CLICK-SERVICE REQUEST.
               BRA     BACK_HANDLER         ;THEN, START AGAIN AT TOP OF PRIORITY CHECKLIST.
                                            ;(17SEP - PRO_CLICK IS NOW ACCESSED AS A SUBROUTINE.)
;
                                            ;PLEASE NOTE THAT THIS CHECK MUST GO AFTER MIDI OR TC
                                            ; PROCESSING, CUZ WE MAY BE HOLDING OFF ON PROCESSING
                                            ; CLICKS UNTIL WE HAVE FINISHED RECEIVING A MESSAGE
                                            ; (ie. SYSEX) OR ARE CATCHING UP TO THE OUTSIDE WORLD
                                            ; (SMPTE CHASE OR SONG_POSITION_POINTER).
;
BACKHAND_80
               MOVE.B  NEW_PADS_OFF,D4      ;ANY FRONT PANEL PADS RELEASED RECENTLY?
               BEQ.S   BACKHAND_90          ;BRANCH IF NOT - GO FORWARD - MOVE AHEAD.
               CLR.B   NEW_PADS_OFF         ;ELSE - ACKNOWLEDGE 'EM HERE.
               MOVE.B  AUTO_PADS_ON,D3      ;HANDLE THOSE WHICH DON'T HAVE PENDING AUTOREPEAT-OFF -
               NOT.B   D3                   ;OTHERWISE ALLOW AUTOREPEAT TO FOLLOW THROUGH.
               AND.B   D3,D4
               BNE     PRO_PADS_OFF         ;IF ALL NOT WIPED OUT, PROCESS THOSE WHICH REMAIN.
BACKHAND_90
;
               MOVE.B  NEW_FTPADS_OFF,D4    ;ANY FOOTSWITCH "PADS" RELEASED RECENTLY?
               BEQ.S   BACKHAND_B0          ;BRANCH IF NOT - GO FORWARD - MOVE AHEAD.
               CLR.B   NEW_FTPADS_OFF       ;ELSE - ACKNOWLEDGE 'EM HERE.
               MOVE.B  AUTO_FTPADS_ON,D3    ;HANDLE THOSE WHICH DON'T HAVE PENDING AUTOREPEAT-OFF -
               NOT.B   D3                   ;OTHERWISE ALLOW AUTOREPEAT TO FOLLOW THROUGH.
               AND.B   D3,D4
               BNE     PRO_FTPADS_OFF       ;IF ALL NOT WIPED OUT, PROCESS THOSE WHICH REMAIN.
BACKHAND_B0
;
               TST.B   VOICES_TO_OFF        ;ANY PENDING REQUESTS FOR VOICE-SPECIFIC GATE-OFF?
               BNE     GATE_A_VOICE_OFF     ;IF YES, GO GATE ONE OFF.
;
               TST.B   VOICES_TO_REL        ;ANY VOICES WAITING TO BE PUT INTO RELEASE PHASE?
               BNE     VOICE_RELEASER       ;GO FOR IT IF YAH.
;
;
; NOTE: NEXT FEW LINES NOT APPLICABLE TO CURRENT 440 REALITY,
;       BUT ARE ENTERTAINING ENOUGH TO LEAVE IN ....
; OF MEDIUM PRIORITY IS PROCESSING DATA NEEDED TO FIRE AN INTERNAL VOICE.  WE BREAK IT UP INTO
;  TASKS, TO ALLOW PRIORITY ROUTINES MORE CHANCES TO GET SERVICED.  IF WE DON'T FINISH BY THE
;  TIME THE REALTIME (LEVEL 3) INT HITS TO ACTUALLY FIRE SAID VOICES, IT FINISHES UP THE
;  CALCULATIONS (I MEAN, TIME BE TIME, YA KNOW, MON?  IF I AND I DO'NA FINISH, JAH WILL TAKE
;  CARE OF US.  JAH; JAH LOVE, MON).   (Realtime is GOD.)
;
;  ANYWAY .... WELCOME.  WELCOME! .... TO LOW-PRIORITY ROTATION-VILLE.
;
;  MOLTI IMPORTANTI: NOBODY IN THIS LIST SHOULD TAKE "TOO LONG" TO RUN,
;  AS HIGH-PRIORITY BACKGROUND ROUTINES MUST WAIT FOR LOW-PRIORITY ONES
;  TO FINISH BEFORE THEY HAVE A CHANCE TO EXECUTE.  SOME SUBFUN-INSTALL
;  ROUTINES, REQUIRING MORE CPU TIME THAN IS ALLOWED BY THIS CONSTRAINT,
;  DEAL WITH THIS BY DIRECTING ROTATION BACK AT THEMSELVES REPEATEDLY
;  UNTIL SATISFIED, BY NOTCHING THE VALUE OF SPINE_COUNT DOWNWARD BEFORE
;  RETURNING - THIS MAINTAINS THE ILLUSION OF A LOT OF WORK GETTING DONE
;  WITHIN THE SPACE OF A SINGLE ROTATION STEP, WITHOUT HAMPERING HIGH-
;  PRIORITY BACKGROUND EXECUTION OR FUCKING UP ORDER-DEPENDENCIES.
;
;  ELSEWHERE, OTHER MAGIC IS PERFORMED!
;
;  FOR THESE REASONS IT BE IMPORTANT NOT TO ALTER THE ADD-4-THEN-TEST
;  NATURE OF ROTATING SPINE, AS TOTAL CONFUSION WOULD NO DOUBT ENSUE.
;  IN SUE?  INN SIOUX?  THIN STEW?
;
ROTATING_SPINE
               MOVE    SPINE_COUNT,D0       ;LOAD UP INDEX OF WHICH ROUTINE WAS SERVICED LAST.
               ADDQ    #4,D0                ;INCREMENT TO NEXT ROUTINE IN LONG-WORD JUMP TABLE.
               CMP.W   #VERTEBRAE,D0        ;OFF END OF TABLE?
               BLT.S   R_S_1                ;BRANCH IF NOT, GO TO IT.
               CLR     D0                   ;ELSE, CLEAR JUMP TABLE INDEX.
R_S_1
               MOVE    D0,SPINE_COUNT       ;SAVE NEW INDEX,
               JMP     SPINAL_TAP(PC,D0)    ;PERFORM NEXT MAINTENANCE ROUTINE.
;
;AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
               TITLE "BACKGROUND - MAINTENANCE ROUTINES JUMP TABLE"
;VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV
;
; LOW-PRIORITY BACKGROUND ROTATION BRANCH TABLE:
; NOTE - MUST USE FORWARD OR EXTERNAL (IE, .W) BRANCH ONLY !!!
; (SHORT BRANCHES OR LONG JUMPS WOULD FOUL UP THE TABLE INDEXING -
; IF LONG JUMPS BECOME NECESSARY, MUST REDO WHOLE TABLE TO USE THEM.)
;
SPINAL_TAP
;
               BRA     FAST_WIND_DAEMON     ;YEAH - WHATEVER.
;
               BRA     SWITCH_SCAN          ;KEEP US TOGETHER, IN THIS ORDER.
               BRA     FOOTSW_OFF_CHECK
               BRA     FTSW_SCROLL_DAEMON
               BRA     SWITCH_BOY           ;OR YOU'LL NEVER SEE YOUR LITTLE GIRL AGAIN!
               BRA     SWITCH_HITTER        ;THESE ARE PRIMARY PARAMETER-EDIT AND SUBFUN_INSTALL
               BRA     POT_CHANGE_CHECK     ;GENERATORS.
;
               BRA     MIDI_CHANGE_CHECK    ;ALL OF THESE CAN SET SUBFUN_INSTALL,
               BRA     PAD_HIT_CHECK        ;SOME IN RESPONSE TO CHANGES WROUGHT BY THE PRIMARY
               BRA     PAD_EDIT_CHECK       ;GROUP ABOVE - WE HIT THEM AFTER HITTING PRIMARY GROUP,
               BRA     PAD_CHANGE_CHECK     ;ON THE WAY TO SUBFUN INSTALL CHECK, TO MINIMIZE
               BRA     KIT_CHANGE_DAEMON
               BRA     KIT_EDIT_DAEMON
               BRA     SEQUENCE_CHANGE_DEMON     ;BACKING UP AND FLAGGING CUED SEQUENCES.
               BRA     SOUND_CHANGE_CHECK   ;THESE COME LAST, SINCE OTHERS IN THE SECONDARY GROUP
               BRA     ALT_CHANGE_CHECK     ;CAN TRIGGER THEM (E.G., KIT_CHANGE).
;
               BRA     VOL_CHANGE_CHECK     ;THIS COULD GO PRETTY MUCH ANYWHERE.
;
               BRA     RUNNING_STATUS_SPLATTER   ;ASSORTED DAEMONS.
               BRA     UPDATE_INIT_TEMPO
               BRA     TAP_DEMON_1
               BRA     TAP_DEMON_2
               BRA     TAP_DEMON_3
               BRA     SCREEN_DAEMON
               BRA     MUTE_OFF_DEMON
               BRA     DEAF_MUTE
               BRA     CHIP_ZERO_CHECK
               BRA     MET_COUNT_IN_DEMON
               BRA     ERASE_MASK_BLAST
               BRA     PLAY_LED_BLINK
               BRA     BACKLIGHT_DEMON
               BRA     SONG_BUILD_GUARD
               BRA     BOGUS_REC_CHECK
               BRA     SEQ_ERROR_CHECK
               BRA     DO_SDS_REQ_CHECK
               .if     copypro_enable
               bra     do_copypro_check
               .endif

;
                                            ;THE SUBFUNCTION INSTALLATION TEAM - GOTTA HANG TIGHT.
SUB_INST_VERT  EQU     *-SPINAL_TAP-4       ;IN CASE WE GOTTA GET HERE IN A HURRY.
               BRA     SUBFUN_INST_CHECK    ;UNDER NO CONDITIONS REARRANGE US.
               BRA     WR_FIELDS_CHECK      ;FUCKIN' HEY, NO!
               BRA     INST_EDIT_CHECK
;
                                            ;DISPLAY MAINTENANCE GROUP:
               BRA     LCD_UPDATE_CHECK     ;KEEP ME AT END OF THE LIST!
               BRA     ES_EL_GUIDO_BLINKO   ;MAKE DECIMAL KEYPAD ENTRIES DANCE BEFORE YOUR EYES.
               BRA     POS_CURSOR_CHECK     ;(Just make sure I'm between these two bozos, ok?)
               BRA     RED_FLD_CHECK        ;NO, KEEP ME AT THE END OF THE LIST!
               BRA     RED_FLD_DISP         ;AND NEVER, EVER MOVE ME AWAY FROM MY BROTHER!
               BRA     LED_FLASH            ;ACTUALLY, COMPLETE BACKGROUND LED MAINTENANCE.
               BRA     CURSOR_BLINK         ;THIS IS WHAT MAKES IT GO ON AND OFF.
;
VERTEBRAE      EQU     *-SPINAL_TAP    ;MARKS THE END OF LOW-PRIORITY ROTATION BRANCH TABLE.
;
;AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
               TITLE "BACKGROUND - MAINTENANCE ROUTINES"
;VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV
;
; WE'RE HERE TO WATCH FOR FLAGS PUT UP BY ANY OF THE DIAGNOSTIC ROUTINES
; EMBEDDED IN VARIOUS PLACES THROUGHOUT THE SEQUENCER.
; WE PUT A MESSAGE IN THE LCD IF AN ERROR FLAG IS DETECTED - FOR MORE
; INFO, SEE SOFTDIAG:FRANK (OR ERROR CODE DEFINITIONS IN SEQDEFS:FRANK).
;
SEQ_ERROR_CHECK
                ABS_LONG
               JSR     SEQ_ERROR_DAEMON
                ABS_SHORT
               BRA     BACK_HANDLER
;
;AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
;
;
;VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV
;
; WE'RE HERE TO WATCH FOR ACTIVITY IN THE RECORD OR ERASE STATUS FLAGS
; IN THE ABSENCE OF ASSOCIATED XPORT_STATE ENABLE BITS - OR, FOR
; SIMULTANEOUS RECORD AND ERASE STATUS.
; WE PUT A MESSAGE IN THE LCD IF AN ILLEGAL STATE IS DETECTED - FOR MORE
; INFO, SEE SOFTDIAG:FRANK (OR ERROR CODE DEFINITIONS IN SEQDEFS:FRANK).
;
BOGUS_REC_CHECK
                ABS_LONG
               JSR     RECORD_DAEMON
                ABS_SHORT
               BRA     BACK_HANDLER
;
;AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA


















;VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV
;
;
; Branch to subroutine call, later to be eradicated.
;
;
DO_SDS_REQ_CHECK
               JSR     SDS_REQ_CHECK
               BRA     BACK_HANDLER
;
;
;AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA


















;VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV
;
;
; calls routine to see if now is the time for copy protection test.
; subroutine normally returns almost immediately -
; test is performed only once, some time after user starts hitting buttons.
; successful test also returns normally -
; failed test hangs permanently, never returns from this call.
;
;
do_copypro_check
;
       jsr     copypro_check
       bra     BACK_HANDLER
;
;AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA


















;VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV
;
; VERY SIMPLE - EVERY SECOND (WHEN REALTIME WRAPS), RESET THE
; RUNNING STATUS BYTES.  NO FUSS, NO MUSS, NO SLOPPY, GOOEY MESS.
;
RUNNING_STATUS_SPLATTER
               MOVE    REAL_TIME,D0         ;GET WOT TIME IT IS NOW
               AND     #3FFH,D0             ; (DO EVERY SECOND - 1025 msec)
               CMP     OLD_REALTIME,D0      ;COMPARE TO OLD.  IF TIME WRAPPED 64K->0, THEN THIS IS NEG
               BCC.S   EVOLUTION_1          ;    IF NOT, FORGET
               CLR.B   MA_RUN_STATUS
               CLR.B   MB_RUN_STATUS
EVOLUTION_1
               MOVE    D0,OLD_REALTIME
               BRA     BACK_HANDLER         ;BACK TO THE ZONE
;
;AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
;
;VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV
;
;             IF NO LONGER/NOT ERASING
;                      THEN CLEAR PAD ERASE MASKS
;
ERASE_MASK_BLAST
               TST.B   ERASING              ;IF ERASING
               BNE     BACK_HANDLER         ;    THEN LEAVE MASK ALONE
               CLR.L   INT_ERASE_MAP        ;         ELSE, CLEAR OUT SOUNDS-TO-ERASE MAPS
               CLR.L   INT_ERASE_MAP+4      ;         (GET ALT_PARAM VERSIONS TOO)
               BRA     BACK_HANDLER
;
;AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
;
;VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV
;
;             IF THE CURRENT_TEMPO IS CHANGED WHILST NOT PLAYING, MAKE THIS THE NEW INITIAL_TEMPO.
;
UPDATE_INIT_TEMPO
               BTST    #3,XPORT_STATE       ;IF PLAYING
               BNE     BACK_HANDLER         ;    THEN LEAVE BE - NOT 'INIT' ANYMORE
               TST     NOW_SEQ_STATUS       ;IF CURRENT_SEQUENCE NOT ALLOCATED
               BEQ     BACK_HANDLER         ;    THEN LEAVE BE
                                            ;         ELSE, SEE IF CHANGE 'TWEEN TWO.
               MOVE    CUR_TEMPO_BPM,D0     ;GET NOW_TEMPO
               CMP     INIT_TEMPO_BPM,D0    ; SEE IF DIFF THAN INIT_TEMPO
               BEQ     BACK_HANDLER         ;    IF SAME, LEAVE BE
               MOVE    D0,INIT_TEMPO_BPM    ;         ELSE, UPDATE INIT_TEMPO
                ABS_LONG
               JSR     I_CALC_FPB           ;HAVE IN BPM - CONVERT TO ALL OTHER FORMS, TELL TC
                ABS_SHORT
;
               CMP.L   #TEMPO_CHANGE_SUB,CUR_SUB_BLOCK     ;ARE WE DISPLAYING INITIAL TEMPO?
               BNE     BACK_HANDLER                        ;BRANCH IF NOT, EXIT -
               ST      SUBFUN_INSTALL       ;ELSE, REQUEST REDISPLAY TO SHOW TEMPO CHANGE.
               BRA     BACK_HANDLER
;
;AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
;
;
;VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV
;
;             THE PURISTS IN THE CROWD WILL HATE THIS ONE - IF WE ARE FIRST ENTERING THE SONG BUILD
;              FUNCTION, NEED TO EXECUTE A THING CALLED 'UNBUILD_EVENT' TO DISPLAY THE PARAMETERS OF
;              THE CURRENT SONG & SONG STEP.  THIS DUDE THEN ALSO TELLS US WHAT SUB_SUBFUNCTION TO
;              BE IN.  HOWEVER, AFTER THAT, ONLY WANT EDITS TO EXECUTE IT - AND REINSTALLS SHOULD
;              NOT, ELSE THEY WILL OSCILLATE US 'TWEEN SUB_SUBFUNCTIONS.  THERFORE, THE VERY FIRST
;              TIME WE ENTER, WE DO A DISPLAY+TAILOR TO UNBUILD_EVENT, AND SET A FLAG SAYING
;              'NEVER AGAIN'.  THEN, UPON LEAVING (WHICH IS A STATE WE DETECT), THAT FLAG GETS
;              CLEARED, SO THAT THE PROCESS MAY START FROM SCRATCH UNPON REENTRY.
;
;              Awww .... that warn't so bad.
;
SONG_BUILD_GUARD
               CMP.L   #BUILD_SONG_SUB,CUR_SUB_BLOCK  ;CHECK THE 3 VALID SUB_SUBFUNCTIONS
               BEQ     BACK_HANDLER         ;IF IN ONE, COOL
               CMP.L   #BUILD_SONG_SUB2,CUR_SUB_BLOCK
               BEQ     BACK_HANDLER
               CMP.L   #BUILD_SONG_SUB3,CUR_SUB_BLOCK
               BEQ     BACK_HANDLER
               SF      SONG_UNBUILD_FLAG    ;    ELSE, CLEAR FLAG FOR REENTRY.
               BRA     BACK_HANDLER
;
;AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
               SKIP
;VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV
;
; TAP_DEMON_1 - IF IN CORRECT SUBFUNCTION, AND DENOMINATOR IS VALID (2, 4, OR 8 ARE
;  ONLY VALID DENOMINATORS FOR TAP TRACKING), THEN SET FLAG THAT THIS IS SO!!!  THIS
;  ALTERS THE FUNCTION OF THE TRANSPORT AND TAP BUTTONS.
;
TAP_DEMON_1
               CMP.L   #TAPPING_SUB,CUR_SUB_BLOCK     ;SEE IF IN ONE OF THE MAGIC FUNCTIONS
               BEQ.S   T_D_10
               CMP.L   #RECORD_TAP_SUB,CUR_SUB_BLOCK
               BNE.S   CLEAR_TAP_FLAG       ;    IF NOT, KWALSH FLAG
;
T_D_10
; WE HAVE OUR LIMITS - IF DENOMINATOR = 2, 4, OR 8, TAP TRACKING IS NO
; PROBLEM.  IF DENOM IS 8, ONLY ALLOWED TAP DIVISION IS EIGHTH NOTES (NO QUARTER TAPPING TO A 7/8
; TIME, FOR INSTANCE).  IF DENOM NOT ONE OF THESE, NO TAP TRACKING ALLOWED.
               CMP     #0,RAW_DENOMINATOR   ;IF DENOM = 2's
               BEQ.S   T_D_11               ;    THEN COOL
               CMP     #1,RAW_DENOMINATOR   ;IF DENOM = 4's
               BEQ.S   T_D_11               ;    THEN COOL
               CMP     #3,RAW_DENOMINATOR   ;IF DO NOT PASS ABOVE, AND DENOM <> 8
               BNE     CLEAR_TAP_FLAG       ;    THEN TAPPING NOT ALLOWED
               BTST    #0,NOW_NUMERATOR+1   ;IF EIGHTHS AND EVEN NUMERATOR
               BEQ.S   T_D_11               ;    THEN COOL
               TST     TAP_DIV_FLAG         ;IF EIGHTHS, ODD NUMERATOR, AND QUARTER TAPS
               BEQ     BACK_HANDLER         ;    THEN UNCOOL
T_D_11                                      ;         ELSE...
               TST.B   TAP_TRACK_ON_FLAG    ;IF THE FLAG WAS PREVIOUSLY ON
               BNE     BACK_HANDLER         ;    THEN ALL IS COOL AND GROOVY
               BTST    #3,XPORT_STATE       ;IF PLAYING WHEN ENTERING THIS DEMON/DESIRE
               BNE     BACK_HANDLER         ;    THEN DO NOT!!! SET FLAG - WILL BLOW UP UPON
                                            ;     LEAVING SUBFUNCTION (DOES THE OFF_CHECK BELOW,
                                            ;     AND EXECUTES TAP_STOP - VERY MESSY REULTS.
               ST      TAP_TRACK_ON_FLAG    ;         ELSE, SET IT!!!
               BRA     BACK_HANDLER
;
CLEAR_TAP_FLAG
               TST.B   TAP_TRACK_ON_FLAG    ;PREVIOUSLY ON?
               BEQ     BACK_HANDLER         ;    IF NOT, JUST GIT
                ABS_LONG
               JSR     TAP_STOP             ;         ELSE, STOP PROCESS
                ABS_LONG
               SF      TAP_TRACK_ON_FLAG    ;         AND CLEAR FLAG
               BRA     BACK_HANDLER
;
;AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
;
;
;
;VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV
;
; TAP_DEMON_2 - IF IN TAP TRACK RECORD MODE, AND TOO LONG 'TWEEN TAPS,
;  THEN HALT THE OPERATION - PUT IN PAUSE, ETC.
;
TAP_DEMON_2
               TST     TAP_TRACK_ON_FLAG    ;ARE WE EVEN IN THIS MODE?
               BEQ.S   EXIT_TAP_DEMONS      ;    IF NOT, OF COURSE, LEAVE.
               BTST    #1,XPORT_STATE       ;IF NOT IN A STATE OF RECORDING THE TAP, SPLIT
               BEQ.S   EXIT_TAP_DEMONS
;
               MOVE.L  #1500,D0             ;LONGEST QUARTER-TAP ALLOWED IS 1.5 SECONDS
               TST     TAP_DIV_FLAG         ; IF EIGHTH-NOTE TAPS, HALF THIS TIME ALLOWED, OF COURSE
               BEQ.S   TAP_D_2_1
               LSL     #1,D0
TAP_D_2_1
               ADD.L   LAST_TAP_TIME,D0     ;  ADD IN TIME USER LAST TAPPED
               CMP.L   REAL_LONG_TIME,D0    ;   COMPARE TO TIME IT IS NOW
               BCC.S   EXIT_TAP_DEMONS      ;    IF USER STILL HAS TIME TO TAP, LEAVE HIM ALONE
;
               BSET    #6,XPORT_STATE       ;PAUSE BUTTON ON
               BSET    #4,LED_STEADY        ;PAUSE LED ON
               BCLR    #4,LED_SLOW_FLASH
               BCLR    #4,LED_FAST_FLASH
EXIT_TAP_DEMONS
               BRA     BACK_HANDLER
;
;AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
;
;
;
;VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV
;
;             TAP DEMON 3 - USER IS TAPPING IN A START.  EXPECTS TO TAP THE 440 FOR, SAY,
;              '1,2,3,4....' AND FOR THE 440 TO START ON THE NEXT IMPLIED '1'.  WE DO THAT HERE.
;
TAP_DEMON_3
               MOVE.L  TAP_TIME_START,D0    ;GET TIME WE ARE SUPPOSED TO START (SET UP IN file:TEMPO)
               BEQ     BACK_HANDLER         ;    IF DORMANT, SPLIT
               CMP.L   REAL_LONG_TIME,D0    ;         ELSE, TIME YET?
               BCC     BACK_HANDLER         ;              IF NOT, WAIT...
               CLR.L   TAP_TIME_START       ;                   ELSE, KILL TIMEOUT
                                            ;                   AND START !!!!
;
               TST     CLOCK_IN_MODE        ;ARE WE UNDER INTERNAL TIMEBASE?
               BNE     BACK_HANDLER         ;EXIT IF NOT, WE ARE POINTLESS.
;
               CMP     #1,COUNT_IN_METHOD   ;IS COUNT-IN START ENABLED?
               BNE.S   TODD_1               ;BRANCH IF NOT, THIS MUST BE TAP-IN.
;
               TST.B   XPORT_STATE          ;IF USER STOPPED XPORT 'FORE WE EXECUTED
               BEQ     BACK_HANDLER         ;    THEN JUST BUG OFF WITHOUT A SOUND.
                                            ;ALTHOUGH, SHOULD HAVE KILLED US DIRECTLY ....
;
TODD_1
               BTST    #PAUSE_BIT,XPORT_STATE    ;ARE WE PAUSED? (NORMAL FOR COUNT-IN)
               BEQ.S   DO_TAP_IN_PLAY            ;BRANCH IF NOT, MUST BE TAP-IN - GO HIT "PLAY"
                                                 ;VIA SPECIAL TAP-IN PATH.
;
                                                 ;WE'RE PAUSED:
               BTST    #PLAY_BIT,XPORT_STATE     ;IS "PLAY" ENABLED?
               BNE.S   RUBYCON_1                 ;IF YES, JUST UNPAUSE (ALSO NORMAL FOR COUNT-IN).
               JSR     TAP_IN_UNPAUSE            ;ELSE, MUST BE TAP-IN - TOGGLE PAUSE OFF, THEN ...
;
DO_TAP_IN_PLAY
               JSR     TAP_IN_PLAY               ;HIT "PLAY" SWITCH VIA SPECIAL ENTRY.
               BRA     BACK_HANDLER
;
RUBYCON_1
               JSR     TAP_IN_UNPAUSE
               BRA     BACK_HANDLER
;
;AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
               SKIP
;VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV
;
;             DEMON TO DO AN AUDIBLE METRONOME 'CLICK, CLICK, CLICK' COUNT IN, IF ORDERED.
;
MET_COUNT_IN_DEMON
               MOVE.L  CLICK_TIME_START,D0  ;GET TIME WE ARE SUPPOSED TO CLICK
               BEQ     BACK_HANDLER         ;    IF DORMANT, SPLIT
               CMP.L   REAL_LONG_TIME,D0    ;         ELSE, TIME YET?
               BCC     BACK_HANDLER         ;              IF NOT, WAIT...
               CLR.L   CLICK_TIME_START     ;                   ELSE, KILL TIMEOUT
                                            ;                   AND CLICK !!!!
               MOVE    #2700H,SR            ;BLOCK INTS WHILE DOING THIS
;
               BSET    #6,MISC_OUT_STAT     ;RESET
               BCLR    #5,MISC_OUT_STAT     ;SET LOGIC FOR MET HIT
;
                ABS_LONG
               MOVE.B  MISC_OUT_STAT,MISC_OUT    ;HIT THE METRONOME CIRCUIT
                ABS_SHORT
;
               MOVEQ   #15,D0
               ADD     METRO_TONE,D0        ;SET UP A USER-DEFINED TIMEOUT
UNCLUCK_LOOP
               DBRA    D0,UNCLUCK_LOOP
               BSET    #5,MISC_OUT_STAT   ;CLEAR MET
                ABS_LONG
               MOVE.B  MISC_OUT_STAT,MISC_OUT
                ABS_SHORT
;
               MOVE    #2000H,SR            ;UNBLOCK INTS
;
               MOVE.L  REAL_LONG_TIME,D0    ;GET NOW
               ADD.L   LAST_TAP_LENGTH,D0   ; ADD WHEN NEXT CLICK WOULD IDEALLY HAPPEN
               SUBQ    #1,TAP_CLICKS_LEFT   ;  ONE LESS CLICK TO SOUND
               BEQ.S   START_ON_NEXT_ONE    ;    IF NONE LEFT, THEN START REAL SOON NOW
               MOVE.L  D0,CLICK_TIME_START  ;         ELSE, TIMEOUT ANOTHER CLICK
               BRA     BACK_HANDLER
;
START_ON_NEXT_ONE
               MOVE.L  D0,TAP_TIME_START    ;(IF REAY TO GO NEXT 'TAP', MAKE IT LOOK LIKE A TAP IN)
               BRA     BACK_HANDLER
;
;AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
               SKIP
;VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV
;
; DAEMON TO FLIP THE PLAY LED BACK ON AFTER IT HAS BEEN TEMPORARILY
; SNUFFED TO SIGNAL PLAY THROUGH VERY BEGINNING OF SEQUENCE OR LOOP.
;
PLAY_LED_BLINK
               MOVE    #PLAY_BLINK_TIMER,A0 ;SET POINTER TO TIMER WORD -
               TST     (A0)                 ;IS TIMER RUNNING?
               BEQ     BACK_HANDLER         ;EXIT IF NOT.
               MOVE    #150,D0              ;ELSE - SEE IF 150 MSEC (APPROX) HAVE GONE BY -
                ABS_LONG
               JSR     REAL_TIMER
                ABS_SHORT
               BCS     BACK_HANDLER         ;NOPE - NOT YET.
;
               BTST    #PLAY_BIT,XPORT_STATE     ;IT'S TIME - BUT IS IT TOO LATE?
               BEQ     BACK_HANDLER              ;EXIT IF YES (TRANSPORT IS DEAD), LEAVE LED OFF.
               TST     CLOCK_IN_MODE             ;ARE WE RUNNING STAND-ALONE, TIME-WIZE?
               BEQ.S   PLB_20                    ;BRANCH IF YES, JUST FUCKIN' GO FOR IT.
               CMP     #3,CLOCK_IN_MODE          ;LIKEWISE FOR CLICK SYNC - WE'RE STILL IN CONTROL,
               BEQ.S   PLB_20                    ;MORE THAN NOT ....
               BTST    #PAUSE_BIT,XPORT_STATE    ;EXTERNAL CONTROL - DID THEY HAPPEN TO PAUSE US
                                                 ;RIGHT AT THE CRITICAL MOMENT?
               BNE     BACK_HANDLER              ;EXIT IF YES, DON'T INTERFERE WITH THEIR PLANS -
PLB_20
               .ALONG
               JSR     PLAY_LED_SOLID            ;ELSE, ON IT GOES.
               .AWORD
               BRA     BACK_HANDLER
;
;AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
;
;
;
;
;VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV
;
;             WHENEVER REAL_LONG_TIME IS GREATER THAN LCD_TIMER + 5 MINUTES, TURN OFF BACKLIGHT
;
;             THIS TIMER IS UPDATED TO REAL_LONG_TIME WHENEVER THE LCD WANTS TO CHANGE A MESSAGE
;              (TRIGGERED OFF A SUBFUN_INSTALL) OR A PAD IS HIT.
;
BACKLIGHT_DEMON
               MOVE.L  LCD_TIMER,D0         ;GET TIMER
               ADD.L   #307200,D0           ; ADD 5 MINUTES (5 * 60 * 1.024 msec)
               CMP.L   REAL_LONG_TIME,D0    ;    IF NOT THAT LATE YET
               BCC.S   BACKLIGHT_ON         ;         THEN KEEP ON/PUT BACK ON
BACKLIGHT_OFF
               BCLR    #4,PAD_CTRL_STAT     ;         ELSE, TURN OFF (SAVE THAT SUCKER)
               BRA     BACK_HANDLER
BACKLIGHT_ON
               BSET    #4,PAD_CTRL_STAT     ;         (UH, LIKE I SAID ABOVE - KEEP/PUT ON)
               BRA     BACK_HANDLER
;
;AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
               SKIP
;VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV
;
; SEQ CHANGE DEMON - IF SEQUENCE NUMBER CHANGE, CHECK IT OUT.
;
;    - IF WE ARE RECORDING, IGNORE NUMBER CHANGE
;    - IF WE ARE PLAYING, CUE UP NUMBER CHANGE TO HAPPEN AFTER THIS ONE DONE
;    -     ELSE, LOAD NEW SEQ PARAMETERS
;
SEQUENCE_CHANGE_DEMON
               MOVE    CURRENT_SEQUENCE,D0  ;GET WHERE 'HE' WANTS US TO BE
               CMP     FORMER_SEQUENCE,D0   ;    DIFFERENT THAN LAST TIME THROUGH?
               BNE.S   THOR_1               ;         IF YES, THEN GO THROUGH CONTORTIONS
;;;;;;;;       SF      CUE_NEW_SEQ          ;              ELSE, KILL ANY PENDING CUE (DEBATABLE)
               BRA     BACK_HANDLER         ;              AND RETURN TO OTHER ACTIONS
;
THOR_1
               TST     REPEAT_COUNT         ;HEY - ARE WE PLAYING BACK IN AN INFINITE REPEAT THING?
               BPL.S   RPTS_HANDLED         ;WELL - HEY, I GUESS NOT ...
               MOVE    #1,REPEAT_COUNT      ;ELSE - THIS COULD BE THE LAST TIME, THIS COULD BE THE
                                            ;LAST TIME, MAYYYY, BEEEE, THE LAST TIME, AH DON' KNOW,
                                            ;(Well ACTUALLY I do know).
               TST.B   NOW_REPEATING        ;AH, BUT ARE WE ACTUALLY IN REPEAT PLAYBACK YET?
               BNE.S   RPTS_HANDLED         ;IF YES, WE WANT REPEAT_COUNT = 1 FOR FINAL PASS -
               CLR     REPEAT_COUNT         ;IF NOT, NEED ZERO - SO WE DON'T EVER GET INTO LOOP.
RPTS_HANDLED
;
               BTST    #3,XPORT_STATE       ;PLAYING?
               BEQ.S   CLEAN_SEQ_CHG        ;    IF NOT, GO AHEAD AND INSTALL NEW SEQUENCE
               ST      CUE_NEW_SEQ          ;         ELSE, SAY TO PLAY CURRENT_SEQ WHEN THIS ONE DONE
               BRA     BACK_HANDLER
;
;
               ABS_LONG
CLEAN_SEQ_CHG  JSR     SEQ_CHANGE_SUB
               ABS_SHORT
;
               CMP     #8,CUR_FUN_INDEX     ;IF WE'RE IN SOME SEQUENCE-RELATED SCREEN,
               BLT.S   SEQ_CHG_EXIT         ;REINSTALL IT - ELSE LEAVE WELL ENOUGH ALONE.
               CMP     #15,CUR_FUN_INDEX    ;CRITERION:  WE'RE UNDER ONE OF THE SEQUENCER
               BHI.S   SEQ_CHG_EXIT         ;FUNCTION SWITCHES.
               ST      SUBFUN_INSTALL       ;REINSTALL - CHANCES ARE GOOD WE CHANGED OTHERS IN OUR SCREEN
               ST      NO_POT_CLEAR         ; LEAVE POT ALONE - MAY HAVE BEEN MOVING DURING THIS
SEQ_CHG_EXIT
               BRA     BACK_HANDLER
;
DENOM_DECODE           ;TIME SIG DENOM - 2,4,6,8,12,16,24,32
               HEX     2,4,6,8,0C,10,18,20
;
DENOM_CLICKS           ;CLICKS PER ABOVE DENOMS - 48,24,16,12,8,6,4,2
               HEX     30,18,10,0C,8,6,4,2
;
;AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
               TITLE   "FAST-WIND DAEMON"
;VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV
;
; FAST-WIND DAEMON -
; SEE WHETHER A DELAY SINCE USER LAST RELEASED FAST-FORWARD OR REWIND
; SWITCH IS ABOUT TO TIME OUT - IF SO, CUE TO THE SELECTED BAR AND GO.
;
FAST_WIND_DAEMON
               MOVE    #FAST_WIND_TIMER,A0  ;SET POINTER TO TIMER WORD,
               TST     (A0)                 ;SEE IF TIMER IS RUNNING -
               BEQ     BACK_HANDLER         ;EXIT IF NOT, GET ON WITH LIFE ALREADY.
               MOVE    #1024,D0             ;TIMER'S RUNNING - LOAD INTERVAL WE ARE TIMING OUT,
                ABS_LONG
               JSR     REAL_TIMER           ;SEE IF TIME'S UP YET -
                ABS_SHORT
               BCS     BACK_HANDLER         ;EXIT IF NOT, GET BACK TO IT LATER.
               BSR     FAST_WIND_PLAY       ;ELSE - SET THE WHEELS OF INDUSTRY IN MOTION,
               BRA     BACK_HANDLER         ;DISAPPEAR INTO THE CROWD ....
;
;AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
               SKIP
;VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV
;
;             DEMON TO CHACK CHANGES IN MUTED TRACKS.  REFERS TO NOTES_CURRENTLY_ON LISTS,
;              CALLS TO TURN OFF THOSE JUST MUTED, TURN ON THOSE UNMUTED.
;
DEAF_MUTE
               MOVE.B  TRACKS_MUTED,D0      ;GET MASK OF TRACKS MUTED
               CMP.B   FORMER_MUTED,D0      ; COMPARE TO THOSE PREVIOUSLY MUTED
               BEQ     BACK_HANDLER         ;  IF NO CHANGE THEN CONTINUE WITH OTHER TASKS
;
               MOVE.B  D0,SAFE_MUTED        ;    ELSE, SAVE OFF NEW STATE...
               OR.B    FORMER_MUTED,D0      ;     MASK ON 'THOSE WHO WERE' TO SEE ALL WE'RE DEALING WITH
               MOVE.L  D0,-(A7)             ;      MAKE A COPY
;
               MOVE.B  FORMER_MUTED,D2      ;RESOLVE WHO JUST WENT ON
               EOR     D2,D0
               EOR     #0FFH,D0             ;FLIP MASK
;
               MOVE.B  D0,PENDING_MUTE      ;WILL KILL OFF STUFF LATER - DO THIS TO NOT XMIT OFFS
                                            ; BEFORE POSSIBLY PENDING ONS (REMEMBER PRE-FETCH AND
                                            ; PRE-LOADING OF UART BUFFERS).  SET UP DEMON TO DO SUCH.
               MOVE.L  REAL_LONG_TIME,MUTE_OFF_TIMER
               ADD.L   #140,MUTE_OFF_TIMER  ; (DELAY FOR 40 BPM w/ SMPTE AT HALF-SPEED)
;
;28NOV               MOVE.B  D0,TRACKS_MUTED
;28NOV                ABS_LONG
;28NOV               JSR     XMIT_OLD_P_OFFS      ;TURN THIS TRACK'S LINGERING PADS OFF
;28NOV               JSR     XMIT_OLD_M_OFFS      ; DO SAME FAVOR FOR MIDI
;28NOV                ABS_SHORT
;
               MOVE.L  (A7)+,D0             ;RECOVER MASK OF ALL INVOLVED
               MOVE.B  SAFE_MUTED,D2        ;GET WHO ALL WENT ON (UNMUTED)
               EOR     D2,D0
               EOR     #0FFH,D0             ;FLIP MASK
               MOVE.B  D0,TRACKS_MUTED
                ABS_LONG
               JSR     XMIT_OLD_P_ONS       ;TURN THIS TRACK'S HIDDEN PADS ON
               JSR     XMIT_OLD_M_ONS       ; DO SAME FAVOR FOR MIDI
                ABS_SHORT
               MOVE.B  SAFE_MUTED,TRACKS_MUTED   ;STORE REAL CONDITION
               MOVE.B  SAFE_MUTED,FORMER_MUTED
               BRA     BACK_HANDLER
;
;AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
               SKIP
;VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV
;
;             MUTE_OFF_DEMON - MUTE STATUS CHANGED; HAVE BEEN WAITING TO KILL OFF NOTES ON TRACK(S)
;              JUST MUTED.  (AND NOW, AT LAST, WE GET TO KILL THEM....)
;
MUTE_OFF_DEMON
               MOVE.L  MUTE_OFF_TIMER,D0    ;LOAD UP REAL_LONG_TIME WE ARE SUPPOSED TO LEAP
               BEQ     BACK_HANDLER         ;    IF WE BE DORMANT, SPLIT
               CMP.L   REAL_LONG_TIME,D0    ;         ELSE, ACTIVE - READY YET?
               BCC     BACK_HANDLER         ;              IF NOT, WAIT IT OUT - USER MAY BE CHANGING BAR
                                            ;                   ELSE, JUMP INTO ACTION!!!
               CLR.L   MUTE_OFF_TIMER       ;MAKE US DORMANT AGAIN
;
               MOVE.B  TRACKS_MUTED,SAFE_MUTED   ;SAVE VALID TRACK_MUTE_MASK
               MOVE.B  PENDING_MUTE,TRACKS_MUTED ; REPLACE WITH OUR VERSION TO MUTE OFF NOW
                ABS_LONG
               JSR     XMIT_OLD_P_OFFS      ;TURN THIS TRACK'S LINGERING PADS OFF
               JSR     XMIT_OLD_M_OFFS      ; DO SAME FAVOR FOR MIDI
                ABS_SHORT
               MOVE.B  SAFE_MUTED,TRACKS_MUTED
;
               BRA     BACK_HANDLER
;
;AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
               SKIP
;VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV
;
; WIPE OUT TEMPORARY LCD MESSAGE AFTER A DELAY -
; INVOKED BY RELEASE OF TEMPO SWITCHES (AMONG POSSIBLE OTHERS).
; CAUSES RETURN TO MOST RECENT SUBFUNCTION SCREEN,
; UNLESS SOMEONE (SOMETHING?) HITS ANOTHER FUNCTION SWITCH FIRST.
;
SCREEN_DAEMON
               MOVE    #SCRN_DM_TIMER,A0
               TST     (A0)                 ;IS THE DAEMON DREAMIN'?
               BEQ.S   SCRN_DM_EXIT         ;NO - HE'S ON VACATION, FORGET HIM.
               MOVE    SCRN_DM_PERIOD,D0    ;YA - FETCH HIS DAEMON-TIME,
               ABS_LONG
               JSR     REAL_TIMER           ;SEE IF IT'S UP -
               ABS_SHORT
               BCS.S   SCRN_DM_EXIT         ;NOT UP, SO BYE 'TILL LATER.
;
               SF      SHOWING_TEMPO        ;TIME UP - CLEAR ANY DAEMONIC FLAGS
                                            ;(SO FAR, ONLY TEMPO UP/DOWN FUNCTION).
               ST      SUBFUN_INSTALL       ;REINSTALL SCREEN PER EXISTING CUR_SUB_BLOCK POINTER.
;
SCRN_DM_EXIT
               BRA     BACK_HANDLER
;
;AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
               SKIP
;VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV
;
; CHECK FOR PENDING REQUEST(S) TO FORCE A VOICE CHIP TO THE
; PLAYBACK ZERO LEVEL ADDRESS - OCCURS WHEN VOICE IS IDLE,
; IN HOPES OF ERADICATING "RING AROUND THE SAMPLER."
; THOSE DIRTY RINGS!   (a.k.a. SOUND BLEEDTHROUGH).
; ONLY ONE VOICE HANDLED PER PASS THROUGH HERE.
;
CHIP_ZERO_CHECK
               TST.B   CHIPS_TO_ZERO        ;ANY REQUESTS PENDING?
               BEQ.S   CHPZCHK_EXIT         ;NO-NO-NO-NO-NO-NO-NO, SO GO, JOE.
               MOVEQ   #7,D0                ;YAH, CHECK UP TO EIGHT BITS TO FIND OUR VOICE.
CHPZCHK_20
               BCLR    D0,CHIPS_TO_ZERO     ;SIMULTANEOUS TEST AND CLEAR.
               DBNE    D0,CHPZCHK_20        ;ASSUME WE'LL FIND ONE - REALTIME MAY ADD TO THE LIST
                                            ;WHILE WE'RE CHECKING, BUT CAN'T REMOVE ANYTHING.
               ADD     D0,D0                ;GOT ONE - SET A0 AS VOICE COMMON BLOCK POINTER.
               MOVE    D0,A0
               MOVE    VOICE_TABLE(A0),A0
               MOVE    #2300H,SR            ;BLOCK REALTIME INTERRUPT.
               BSR     ZERO_THIS_CHIP       ;USE PRIORITY SEQUENCE ROUTINE.
               MOVE    #0,V_PRIO_TIME(A0)   ;ZERO_THIS_CHIP SETS UP NEXT PRIORITY VECTOR -
                                            ;THIS BLOCKS IT FROM EXECUTING.
               MOVE    #2000H,SR            ;INTERRUPTS - AWAKE!
;
CHPZCHK_EXIT
               BRA     BACK_HANDLER
;
;AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
               SKIP
;VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV
;
; SWITCH-SCAN ROUTINE -
; MAINTAINS IMAGES OF CURRENT SWITCH STATUS AND OF NEW SWITCH CLOSURES -
; FOR PROGRAMMABLE FOOTSWITCHES, ALSO MAINTAINS A MINI-MAP OF NEW
; SWITCH-RELEASE EVENTS, IN FOOTSW_OFF(.B) -
; ALL SWITCHES ARE SCANNED ON EACH PASS THROUGH HERE.
; SWITCH_MASK (AN IMAGE OF ENABLED SWITCHES) ALLOWS SWITCHES TO BE
; SELECTIVELY IGNORED - THEY'RE HELD IN THE "OFF" STATE.
; UPON ANY CHANGE IN SWITCH STATUS, SCANNING IS INHIBITED FOR A DEBOUNCE
; PERIOD OF 20 MSEC - NOTE!! THIS PERIOD IS KEYED OFF OF REALTIME
; INTERRUPT, WILL GET STUCK IF REALTIME INTERRUPT IS DISABLED.
;
SWITCH_SCAN
               MOVE    #DEBOUNCE_TIMER,A0   ;ARE WE IN DEBOUNCE PERIOD?
               TST     (A0)
               BEQ.S   SW_SCAN_10           ;BRANCH IF NOT, DO A SCAN.
               MOVEQ   #19,D0               ;ELSE, GET A TIME UPDATE AGAINST 10 MSEC PERIOD,
               ABS_LONG
               JSR     REAL_TIMER
               ABS_SHORT
               BRA.S   SW_SCAN_EXIT         ;CHECK BACK NEXT TIME.
SW_SCAN_10
               MOVEQ   #7,D0                ;SCAN SEVEN ROWS OF MATRIX, PLUS FOOTSWITCHES.
               MOVE.L  #SWITCH_INPUT,A0     ;SWITCH_INPUT POINTER.
               MOVE    #SWITCH_MASK,A1      ;POINTER TO SWITCH MASK-OFF IMAGE.
               MOVE    #SWITCH_STAT,A2      ;PREVIOUS SWITCH STATUS IS STORED HERE.
               MOVE    #SWITCHES_ON,A3      ;NEW SWITCH CLOSURES ARE RECORDED HERE.
SW_SCAN_20
               MOVE    (A0)+,D1             ;READ SWITCH MATRIX INTO LOW BYTE, BUMP POINTER BY TWO.
               TST     D0                   ;LAST PASS THROUGH LOOP?
               BNE.S   SW_SCAN_30           ;BRANCH IF NOT - STILL IN MATRIX.
               LSR     #8,D1                ;ELSE, SHIFT FOOTSWITCH BITS INTO L.S.BYTE,
               NOT     D1                   ;INVERT THEM TO MATCH SENSE OF MATRIX SWITCHES,
               AND     #7,D1                ;MASK OUT THE NON-SWITCH BITS.
               MOVE.B  (A2),D3              ;COPY CURRENT FOOTSWITCH STATUS FOR SWITCH-OFF TEST.
SW_SCAN_30
                                                 ;SWITCH-ON CHECKING:
               AND.B   (A1)+,D1                  ;MASK OUT ANY UNWANTED SWITCHES.
               MOVE    D1,D2                     ;COPY THE MASKED SWITCH ROW IMAGE.
               EOR.B   D2,(A2)                   ;LOOK FOR CHANGES IN THIS ROW SINCE LAST SCAN.
               BEQ.S   SW_SCAN_40                ;BRANCH IF NO CHANGES,
               MOVE    REAL_TIME,DEBOUNCE_TIMER  ;ELSE TURN ON DEBOUNCE DELAY -
               BSET    #0,DEBOUNCE_TIMER+1       ;VALUE OF 0 NOT COOL HERE.
SW_SCAN_40
               AND.B   (A2),D2              ;WE ONLY CARE ABOUT SWITCHES CLOSING -
               OR.B    D2,(A3)+             ;COMBINE THEM (IF ANY) WITH PREVIOUS CLOSURES.
               MOVE.B  D1,(A2)+             ;SAVE NEW MASKED SWITCH STATUS FOR THIS ROW.
;
               TST     D0                   ;ARE WE LOOKING AT FOOTSWITCHES?
               BNE.S   SW_SCAN_60           ;BRANCH IF NOT, GO FOR NEXT SET OF SWITCHES.
               NOT     D1                   ;ELSE, LOOK FOR RELEASE OF PROGRAMMABLE FOOTSWITCHES -
               AND     D3,D1                ;THOSE WHICH WERE ON LAST TIME, "NOT" ON NOW -
               AND     #3,D1                ;IGNORE THE PLAY/STOP FOOTSWITCH HERE.
               BEQ.S   SW_SCAN_60           ;SKIP OUT IF NO CHANGES NOTED -
               OR.B    D1,FOOTSW_OFF        ;ELSE, DROP CHANGE(S) ONTO FLAG BYTE,
               MOVE    REAL_TIME,DEBOUNCE_TIMER  ;TURN ON DEBOUNCE DELAY -
               BSET    #0,DEBOUNCE_TIMER+1       ;VALUE OF 0 NOT COOL HERE.
SW_SCAN_60
               DBRA    D0,SW_SCAN_20        ;REPEAT UNTIL ALL ROWS READ - THEN,
SW_SCAN_EXIT
               BRA     BACK_HANDLER         ;BACK TO THE ZONE.
;
;AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
               SKIP
;VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV
;
; LOOK FOR PROGRAMMABLE FOOTSWITCH RELEASE:
;
FOOTSW_OFF_CHECK
               TST.B   FOOTSW_OFF           ;ANY?
               BEQ.S   FTSW_OFF_EXIT        ;NONE.
                ABS_LONG
               JSR     FOOTSW_OFF_BOY       ;GIDDY-AP!
                ABS_SHORT
;
FTSW_OFF_EXIT
               BRA     BACK_HANDLER
;
;AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
;
;
;
;VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV
;
; LOOK FOR ACTIVE PROGRAMMABLE FOOTSWITCH ROUTED TO
; AN AUTOSCROLLED FRONT-PANEL SWITCH -
; IF ANY, FUDGE THE CONDITIONS NECESSARY TO INVOKE/SUSTAIN AUTOSCROLL.
; ALSO DETECT AND HANDLE RELEASE OF A FOOTSWITCH WITH SUCH ROUTING.
;
; NOTE - INC/DEC ROUTING DISABLED IF IN FOOTSWITCH EDITING SCREEN
; TO AVOID MASS CONFUSION - WE WON'T SEE ANY ACTION HERE IN THOSE CASES.
;
FTSW_SCROLL_DAEMON
               MOVE    FTSW1_SCROLL,D0      ;SEE WHAT IS ACTION ON FOOTSWITCH 1 -
               BEQ.S   FTSW_DM_40           ;NONE, SEE ABOUT FOOTSWITCH 2.
               BTST    #1,SWITCH_STAT+7     ;ACTION - IS THE FOOTSWITCH INDEED ON?
               BNE.S   FTSW_DM_20           ;BRANCH IF YES, DO OUR THING.
               CLR     FTSW1_SCROLL         ;ELSE, ERASE ALL TRACE OF ACTION - SCROLL MUST DIE.
               BRA.S   FTSW_DM_40           ;NOW GO SEE ABOUT FOOTSWITCH 2.
FTSW_DM_20
               BSR.S   DO_FTSW_SCROLL       ;THIS BE OUR SUB-THING.
;
FTSW_DM_40
               MOVE    FTSW2_SCROLL,D0      ;SEE WHAT IS ACTION ON FOOTSWITCH 2 -
               BEQ.S   FTSW_DM_EXIT         ;NONE, SO BYE-BYE.
               BTST    #0,SWITCH_STAT+7     ;ACTION - IS THE FOOTSWITCH INDEED ON?
               BNE.S   FTSW_DM_60           ;BRANCH IF YES, DO OUR THING.
               CLR     FTSW2_SCROLL         ;ELSE, ERASE ALL TRACE OF ACTION - SCROLL MUST DIE.
               BRA.S   FTSW_DM_EXIT         ;AND, BYEs (TWO, TO BE EXACT - OR ONE GOOD ONE).
FTSW_DM_60
               BSR.S   DO_FTSW_SCROLL       ;THIS BE OUR SUB-THING.
;
FTSW_DM_EXIT
               BRA     BACK_HANDLER
;
;
DO_FTSW_SCROLL
                                            ;D0 CONTAINS NUMBER OF TARGET SWITCH:
               MOVE    D0,D1                ;MAKE-UM COPY.
               LSR     #3,D1                ;D1 INDEXES TO ROW IN SWITCH MATRIX,
               MOVE    D1,A0
               BSET    D0,SWITCH_STAT(A0)   ;D0 (MOD 8) GETS US TO THE BIT WE WANT -
               RTS                          ;VIA STRATEGIC POSITIONING IN ROTATING BACKGROUND,
                                            ;WE MAKE TARGET SWITCH APPEAR TO BE HELD ON AS LONG AS
                                            ;THE FOOTSWITCH ROUTED TO IT IS HELD ON.
;
;AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
               SKIP
;VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV
;
; CHECK TO SEE IF A SUBFUNCTION INSTALLATION REQUEST IS PENDING.
;
SUBFUN_INST_CHECK
               TST.B   SUBFUN_INSTALL       ;IS OUR ATTENTION REQUESTED?
               BEQ     BACK_HANDLER         ;BRANCH IF NOT, TAKE A HIKE.
               SF      SUBFUN_INSTALL       ;ELSE, ACKNOWLEDGE REQUEST.
               TST.B   SHOWING_FF_RW        ;BUT, IGNORE IT IF FAST-FORWARD/REWIND SCREEN IS UP -
               BNE.S   SUBIN_CHK_EXIT
               TST.B   SHOWING_TEMPO        ;SO, TOO, IF TEMPO UP/DOWN SCREEN IS ON DISPLAY.
               BNE.S   SUBIN_CHK_EXIT
                ABS_LONG
               JMP     INSTALL_SUBFUNCTION  ;AND GET TO IT.
                ABS_SHORT
SUBIN_CHK_EXIT
               BRA     BACK_HANDLER
;
;AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
;
;
;
;VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV
;
; ARE WE TO DISPLAY THE SETTINGS IN ALL FIELDS OF A NEW SUBFUNCTION?
; SUBSIDIARY TO INSTALL_SUBFUNCTION - INVOKED BY IT, IN FACT.
; THEREFORE, IF SUBFUN_INSTALL REQUEST FLAG IS SET, WE WON'T EXECUTE -
; WE'D JUST B WASTING R TIME.
; WE DON'T CLEAR OUR OWN FLAG, SINCE WRITE_ALL_FIELDS REQUIRES MANY
; PASSES IN ORDER TO COMPLETE - IT HANGS ITSELF UP WHEN DONE.
;
WR_FIELDS_CHECK
               TST.B   SUBFUN_INSTALL       ;MORE YET TO COME?
               BNE.S   WR_FLCHK_EXIT        ;YOU BET, SO OFF WE GO.
               TST.B   WR_FIELDS_FLAG       ;NOTHING IN THE WAY - ARE WE REQUESTED?
               BEQ.S   WR_FLCHK_EXIT        ;NAH - LATER DUDE.
               ABS_LONG
               JSR     WRITE_ALL_FIELDS     ;AWAYWEGO.
               ABS_SHORT
WR_FLCHK_EXIT
               BRA     BACK_HANDLER
;
;AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
;
;
;
;VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV
;
; ARE WE TO INSTALL THE EDIT FIELD OF A NEW SUBFUNCTION?
; SUBSIDIARY TO WRITE_ALL_FIELDS - INVOKED BY IT, OR BY SCROLL SWITCHES.
; IF SUBFUN_INSTALL REQUEST FLAG IS SET, WE WON'T EXECUTE -
; WE'D JUST B WASTING R TIME.
; WE DON'T CLEAR OUR OWN FLAG, SINCE INSTALL_EDIT_FIELD REQUIRES MANY
; PASSES IN ORDER TO COMPLETE - IT HANGS ITSELF UP WHEN DONE.
;
INST_EDIT_CHECK
               TST.B   SUBFUN_INSTALL       ;MORE YET TO COME?
               BNE.S   INS_ECHK_EXIT        ;YOU BET, SO OFF WE GO.
               TST.B   INST_EDIT_FLAG       ;NOTHING IN THE WAY - ARE WE REQUESTED?
               BEQ.S   INS_ECHK_EXIT        ;NAH - LATER DUDE.
               ABS_LONG
               JSR     INSTALL_EDIT_FIELD   ;AWAYWEGO.
               ABS_SHORT
INS_ECHK_EXIT
               BRA     BACK_HANDLER
;
;AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
               SKIP
;VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV
;
; LED MAINTENANCE ROUTINE FOR LEDs IN LED_OUTPUT GROUP -
; A/B AND AUTOREPEAT LEDs ARE NOT INCLUDED IN THIS.
; PERIODIC UPDATE OF LED STATES -
; TURN OFF LEDs PER BITS SET IN LED_EXTINGUISH.
; FLASH LEDs AS INDICATED BY BITS IN LED_SLOW_FLASH, LED_FAST_FLASH.
; MAINTAIN STEADY ILLUMINATION OF LEDs PER BITS SET IN LED_STEADY.
; UPDATE LED_OUT_STAT TO REFLECT INSTANTANEOUS STATUS OF ALL LEDs.
; ROUTINE RUNS CONTINUOUSLY REGARDLESS OF WHETHER OR NOT ANY LEDs ARE FLASHING,
; SO THAT LED_TIMERs STAY CORRECTLY IN SYNC WITH REAL_TIME -
; CONSEQUENTLY, LEDs IN THE LED_OUTPUT GROUP ARE PERIODICALLY UPDATED BY THIS ROUTINE
; AND MAY BE CHANGED WITHOUT DIRECTLY ACCESSING THE LED_OUTPUT REGISTER.
;
LED_FLASH
               BSR.S   LED_DIRECT
               BRA     BACK_HANDLER
;
;
; PROVIDED AS A SUBROUTINE SO THAT IT MAY BE CALLED TO PROVIDE IMMEDIATE
; LED EDITING RESPONSE FOR ROUTINES WHICH HALT BACKGROUND, OR TO AVOID
; LEAVING CONFLICTING ON/EXTINGUISH EDITS TO BE PICKED UP BY BACKGROUND.
; I-SERVES DEM REGISTER.
;
LED_DIRECT
               MOVEM.L D0-D1/A0,-(A7)
               MOVE    LED_EXTINGUISH,D0         ;FIRST ORDA BIZNISS - ACKNOWLEDGE REQUESTS TO
               NOT     D0                        ;TURN OFF LEDs (KILLS 'EM REGARDLESS OF MODE).
               AND     D0,LED_STEADY
               AND     D0,LED_SLOW_FLASH
               AND     D0,LED_FAST_FLASH
               CLR     LED_EXTINGUISH
;
               MOVE    #SLOW_LED_TIMER,A0
               MOVE    #300,D0                   ;SLOW FLASH - APPROX. 300 MSEC ON, OFF.
                ABS_LONG
               JSR     REAL_TIMER
                ABS_SHORT
               BCS.S   LED_DIR_10                ;BRANCH IF NOT TIME YET,
               MOVE    REAL_TIME,(A0)            ;ELSE RESTART TIMER,
               NOT.B   SLOW_LED_STAT             ;TOGGLE STATUS OF THE SLOW FLASH GROUP.
LED_DIR_10
               MOVE    #FAST_LED_TIMER,A0
               MOVEQ   #50,D0                    ;FAST FLASH - APPROX. 50 MSEC ON, OFF.
                ABS_LONG
               JSR     REAL_TIMER
                ABS_SHORT
               BCS.S   LED_DIR_20                ;BRANCH IF NOT TIME YET -
               MOVE    REAL_TIME,(A0)            ;ELSE RESTART TIMER,
               NOT.B   FAST_LED_STAT             ;TOGGLE STATUS OF THE FAST FLASH GROUP.
LED_DIR_20
               MOVE    LED_STEADY,D1             ;ACCESS THE STATUS OF NON-FLASHING LEDs.
               TST.B   SLOW_LED_STAT             ;SLOW FLASH LEDs ON?
               BEQ.S   LED_DIR_30                ;BRANCH IF NOT,
               OR      LED_SLOW_FLASH,D1         ;ELSE THROW THEM IN.
LED_DIR_30
               TST.B   FAST_LED_STAT             ;FAST FLASH LEDs ON?
               BEQ.S   LED_DIR_40                ;BRANCH IF NOT,
               OR      LED_FAST_FLASH,D1         ;ELSE THROW THEM IN.
LED_DIR_40
               MOVE    D1,LED_OUT_STAT           ;SAVE NEW LED STATUS,
               NOT     D1                        ;OUTPUT IT TO LEDs - CONTROL INVERTED.
                ABS_LONG
               MOVE    D1,LED_OUTPUT
                ABS_SHORT
;
               MOVEM.L (A7)+,D0-D1/A0
LED_DIR_EXIT
               RTS
;
;AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
               SKIP
;VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV
;
; UPDATE ALT_PARAM_FLAG STATUS, TRACK ANY CHANGES -
; REFLECT ANY CHANGES INTO LED, ALSO LCD WHERE APPROPRIATE.
;
ALT_CHANGE_CHECK
               MOVE    #PAD_SOUNDS,A0       ;NORMALLY FOLLOW STATUS OF PAD ARRAY CELL -
               TST.B   BUILD_KIT_FLAG       ;"NORMALLY" MEANING NOT IN KIT-BUILD SCREEN/MODE ....
               BEQ.S   ALT_CHK_10           ;BRANCH IF SITUATION "NORMAL".
               MOVE    #KIT_SOUNDS,A0       ;IN KIT-BUILD MODE WE LOOK AT PRESET ARRAYS INSTEAD.
ALT_CHK_10
               MOVE    EDIT_KIT_INDEX,D0    ;USE EDIT-KIT - FETCH PERF SETTINGS OF LAST LIVE EVENT,
                                            ;OR OF KIT-EDIT CELL (OR BOTH, AS THE CASE MAY BE).
               LSL     #3,D0                ;CONVERT KIT INDEX TO ARRAY CELL OFFSET,
               ADD     PAD_JUST_HIT,D0      ;INDEX TO CELL FOR PAD JUST HIT,
               MOVE.B  0(A0,D0),D0          ;FETCH SOUND NUMBER / ALT-PARAMS SETTING THERE,
               MOVE    D0,D1                ;ISOLATE SOUND NUMBER IN D0 -
               LSR     #1,D0
               AND     #1FH,D0
               CMP     CURRENT_SOUND,D0     ;LAST LIVE-EVENT SOUND SAME AS CURRENT_SOUND?
;
;19DEC;
;19DEC               BNE.S   ALT_CHK_50           ;NO - CURRENT_SOUND HAS BEEN EDITED DIRECTLY,
;19DEC                                            ;DON'T CHANGE ALT_PARAM_FLAG STATUS.
;19DEC               AND     #1,D1                ;YES - ISOLATE LAST LIVE-EVENT ALT-PARAMS BIT IN D1 -
;19DEC;
;
               BEQ.S   ALT_CHK_18           ;BRANCH IF YES, USE WHAT WE EXTRACTED FROM KIT ARRAY.
               MOVE    ALT_PARAM_FLAG,D1    ;ELSE - CURRENT_SOUND HAS BEEN EDITED DIRECTLY, DON'T
                                            ;CHANGE IT HERE - BUT ALLOW CHANGES DONE BY ALT-PARAMS
                                            ;SWITCH TO BE ACKNOWLEDGED THROUGH HERE FOR LCD UPDATE.
ALT_CHK_18
               AND     #1,D1                ;ISOLATE ALT-PARAMS BIT IN D1.
;19DEC;
;
               CMP     LAST_ALT_PARAM,D1    ;COMPARE AGIN THAT WHICH WE, AS BACKGROUND, LAST SAW -
               BEQ.S   ALT_CHK_50           ;SAME?  FORGET THIS.
               MOVE    D1,ALT_PARAM_FLAG    ;ELSE, UPDATE OUR RECORDS.
               MOVE    D1,LAST_ALT_PARAM
               CMP     #8,CUR_FUN_INDEX     ;ARE WE IN A SOUND-EDITING SCREEN?
               BCS.S   ALT_CHK_40           ;BRANCH IF YES, REQUEST SUBFUNCTION REINSTALL.
;890402               CMPI.W  #17,CUR_FUN_INDEX    ; ah so for MIDI 2 (sample dump).
;890402               BEQ.S   ALT_CHK_40
;890402                nope, this method no good, since INDEX = -1 ....
               TST.B   BUILD_KIT_FLAG       ;LIKEWISE IF WE'RE IN KIT-BUILD SCREEN -
               BNE.S   ALT_CHK_40
;
               MOVE.L  CUR_SUB_BLOCK,D7     ;CHECK FOR A NUMBER OF SCREENS NOT IN SOUND-EDIT GROUP:
               CMPI.L  #SDS_OUT_SUB,D7      ; Ah so for sample dump function.
               BEQ.S   ALT_CHK_40
               CMPI.L  #SDS_REQ_SUB,D7      ; Ah so for sample request function.
               BEQ.S   ALT_CHK_40
               CMP.L   #SEQ_ERASE_SUB,D7    ;ARE WE IN ONE OF THE SEQUENCE-ERASE EDIT SCREENS?
               BEQ.S   ALT_CHK_20           ;BRANCH IF YES, GOT SOME SETTING UPDATING TO DO.
               CMP.L   #SEQ_ERASE_SUB_2,D7
               BEQ.S   ALT_CHK_20
               CMP.L   #SEQ_VEL_SCALE_SUB,D7     ;LIKEWISE FOR SEQUENCE VELOCITY-SCALE SCREEN.
               BEQ.S   ALT_CHK_20
               CMP.L   #TRANSPOSE_SUB,D7
               BNE.S   ALT_CHK_50           ;IF NONE OF ABOVE, NO REDISPLAY - GO UPDATE LED.
;
ALT_CHK_20
                                            ;NOW - COMPUTE NEW SETTING FOR SEQUENCE-ERASE SCREENS:
               LSL     #1,D0                ;TAKE SOUND NUMBER * 2 (ALT-PARAMS OFF/ON PER SOUND),
               ADDQ    #2,D0                ;OFFSET BY 2 FOR "ALL" AND "ALL DRUMS" SETTINGS,
               ADD     D1,D0                ;FIGURE IN ALT-PARAMS SETTING OBTAINED ABOVE.
;
                                            ;SEQ-ERASE SELECT - DON'T WIPE OUT "NOTES ABOVE/BELOW":
               MOVE    DATA_TYPE,D1         ;FETCH THE ERASE DATA-TYPE SETTING.
               CMP     #67,D1               ;"NOTES BELOW xxx"?
               BEQ.S   ALT_CHK_30           ;BRANCH IF YES, LEAVE AS IS.
               CMP     #68,D1               ;"NOTES ABOVE xxx"?
               BEQ.S   ALT_CHK_30           ;BRANCH IF YES, LEAVE AS IS.
               MOVE    D0,DATA_TYPE         ;ELSE SET DATA TYPE TO "DRum XXa" PER SOUND/ALT ABOVE.
ALT_CHK_30
               ADD     #31,D0               ;SET DATA CATEGORY FOR SEQUENCE VELOCITY SCALE FUNCTION
               MOVE    D0,CHAN_NUM          ;PER ABOVE SOUND NUMBER / ALT-PARAMS SETTING - SIMILAR
                                            ;TO ERASE SETTING, PLUS STEP ABOVE SETTINGS FOR 32 MIDI
                                            ;CHANNELS PLUS "ALL CHANNELS" SETTING - THEN DOWN BY 2
                                            ;AS "ALL DRUMS" AND "ALL" SETTINGS ARE AT TOP OF RANGE.
;
ALT_CHK_40
               TST     SCRN_DM_TIMER        ;WE HAVE REASON TO REDISPLAY, BUT - IF DAEMON IS ALIVE,
               BNE.S   ALT_CHK_50           ;DON'T PISS HIM OFF.
               ST      SUBFUN_INSTALL       ;ALT-PARAMS BEING DISPLAYED, SO DISPLAY CHANGED STATE.
;
ALT_CHK_50
               TST     ALT_PARAM_FLAG       ;KEEP LED UP TO DATE EVEN IF WE SAW NO CHANGE -
               BNE.S   ALT_CHK_70           ;JUST TO BE SURE WE DON'T MISS ANY ACTION.
               BSET    #7,PAD_CTRL_STAT     ;ALT_PARAM_FLAG OFF - SET BIT TO TURN OFF LED.
               BRA.S   ALT_CHK_EXIT
ALT_CHK_70
               BCLR    #7,PAD_CTRL_STAT     ;ALT_PARAM_FLAG ON - CLEAR BIT TO TURN ON LED.
;
                                            ;PAD_CONTROL LATCH IS UPDATED FROM RAM BY REALTIME -
                                            ;THIS IS ALL WE NEED TO DO TO UPDATE ALT-PARAMS LED.
ALT_CHK_EXIT
               BRA     BACK_HANDLER
;
;AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
;
;
;
;VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV
;
; TOGGLE BLINKING LCD CURSOR (IF IT'S TIME) -
; IF CURSOR_ENABLE = 0, KILL CURSOR ALTOGETHER
; (BUT ALLOW TIMER TO KEEP RUNNING, HEY).
;
CURSOR_BLINK
               MOVE    #CURSOR_TIMER,A0
               MOVE    #200,D0              ;BLINK PERIOD APPROX. 200 MSEC ON, 200 MSEC OFF.
                ABS_LONG
               JSR     REAL_TIMER
                ABS_SHORT
               BCS.S   CURS_BLNK_EXIT       ;BRANCH IF NOT TIME YET - EXIT.
               MOVE    REAL_TIME,(A0)       ;IT'S TIME - RESTART TIMER.
               TST.B   CURSOR_ENABLE        ;IS BLINKING CURSOR ENABLED?
               BNE.S   CURS_BLNK_10         ;BRANCH IF YES, TOGGLE STATUS.
               SF      CURSOR_STAT          ;ELSE, TURN IT OFF.
               BRA.S   CURS_BLNK_20
CURS_BLNK_10
               NOT.B   CURSOR_STAT          ;TOGGLE STATUS OF THE CURSOR,
CURS_BLNK_20
                ABS_LONG
               JSR     UPDATE_CURSOR        ;SET NEW CURSOR STATUS IN LCD.
                ABS_SHORT
CURS_BLNK_EXIT
               BRA     BACK_HANDLER
;
;AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
               SKIP
;VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV
;
; CHECK FOR CHANGES ON ALL POTS - ONE ONLY PER PASS THROUGH HERE.
; I.E., LOOK AT VALUES PLACED IN POT_VALUE ARRAY BY REALTIME.
;
; HYSTERESIS ALGORITHM USED AT THE RAW POT LEVEL:
; ABSOLUTE VALUE OF (POT_VALUE) - (POT_THRESH) MUST BE GREATER THAN OR
; EQUAL TO 2 IN ORDER FOR A CHANGE TO BE ACKNOWLEDGED AS REAL.
; WHEN CHANGE IS ACKNOWLEDGED, A NEW VALUE IS SET FOR POT_THRESH:
;      (POT_VALUE) + 1 .... IF (POT_VALUE) - (POT_THRESH) WAS NEGATIVE.
;      (POT_VALUE) - 1 .... IF (POT_VALUE) - (POT_THRESH) WAS POSITIVE.
; AMONG OTHER THINGS, THIS ALLOWS BOTH ENDS OF THE RANGE TO BE HIT.
;
; IF A "REAL" CHANGE IS DETECTED AT THE RAW POT LEVEL, RAW LEVEL IS THEN
; SCALED AS BEFITZ - SCALING IS DIFFERENT FOR MASTER VOLUME, DATA ENTRY.
;
; FURTHER RESPONSE IS MADE ONLY TO POST-SCALING CHANGES:
;    FOR DATA SLIDER - THE CURRENT POT_CHANGE_VEC IS EXECUTED.
;    FOR OTHERS - CURRENT_xxx IS UPDATED WITH NEW SCALED VALUE,
;                 AND ASSOCIATED xxx_CHANGE FLAG IS SET -
;                 FLAG IS RESPONDED TO ELSEWHERE IN BACKGROUN.
;
POT_CHANGE_CHECK
               MOVE    #POT_VALUE,A0        ;A0 POINTS TO RAW POT VALUE ARRAY.
               MOVE    #POT_THRESH,A1       ;A1 POINTS TO ARRAY OF HYSTERESIS THRESHOLD VALUES.
               MOVE    POT_CHK_INDEX,D1     ;D1 INDICATES WHICH POT TO BE CONCERNED WITH -
               MOVE    0(A0,D1),D0          ;FETCH MR. RAW INTO D0,
               SUB     0(A1,D1),D0          ;TAKE HIS DIFFERENCE FROM THRESHOLD -
               BMI.S   POT_CHK_10           ;BRANCH FOR NEGATIVE DIFFERENCE.
               CMP     #2,D0                ;POSITIVE DIFFERENCE > 1 ?
               BLT     POT_CHK_70           ;BRANCH IF NOT, ACT AS IF NOTHING IS HAPPENING.
               MOVE    0(A0,D1),0(A1,D1)    ;ELSE - SET NEW THRESHOLD,
               SUBQ    #1,0(A1,D1)
               BRA.S   POT_CHK_20           ;GO PROCESS THE RAW VALUE AS APPROPRIATE.
POT_CHK_10
               CMP     #-2,D0               ;NEGATIVE DIFFERENCE < -1 ?
               BGT.S   POT_CHK_70           ;BRANCH IF NOT, ACT AS IF NOTHING IS HAPPENING.
               MOVE    0(A0,D1),0(A1,D1)    ;ELSE - SET NEW THRESHOLD,
               ADDQ    #1,0(A1,D1)
                                            ;FALL THROUGH AND PROCESS RAW VALUE AS APPROPRIATE.
;
POT_CHK_20
                                            ;SCALE A NEW RAW POT VALUE:
               TST     D1                   ;ARE WE LOOKING AT DATA POT?
               BEQ.S   POT_CHK_60           ;BRANCH IF YAH, HE'S GOT HIS OWN SCENE.
               MOVE    0(A0,D1),D0          ;ELSE FETCH RAW VALUE INTO D0 AGAIN.
               CMP     #2,D1                ;ARE WE LOOKING AT MASTER VOLUME?
               BEQ.S   POT_CHK_50           ;BRANCH IF YES, MASTER'S SCALING IS DIFFERENT.
               LSR     #3,D0                ;ELSE IT'S PAN/PITCH/LEVEL - CHOP IT DOWN TO 5 BITS.
               CMP     #4,D1                ;WHO IS THIS?  THIS IS VALUE FOR PAN KNOB ....
               BEQ.S   POT_CHK_30           ;BRANCH IF PAN.
               CMP     #6,D1
               BEQ.S   POT_CHK_40           ;BRANCH IF PITCH.
               CMP     CURRENT_LEVEL,D0     ;ELSE, IT'S LEVEL CONTROL - SCALED VALUE CHANGED?
               BEQ.S   POT_CHK_70           ;BRANCH IF NOT, NO ACTION FOR THIS POT.
               MOVE    D0,CURRENT_LEVEL     ;ELSE, SAVE NEW LEVEL SETTING,
               ST      LEVEL_CHANGE         ;SET FLAG TO INDICATE CHANGE IN SETTING.
               BRA.S   POT_CHK_70           ;UPDATE POT_CHK_INDEX, EXIT.
POT_CHK_30
               CMP     CURRENT_PAN,D0       ;CHANGE IN PAN SETTING?
               BEQ.S   POT_CHK_70           ;BRANCH IF NOT, NO ACTION FOR THIS POT.
               MOVE    D0,CURRENT_PAN       ;ELSE, STORE NEW PAN SETTING,
               ST      PAN_CHANGE           ;SET CHANGE FLAG.
               BRA.S   POT_CHK_70           ;UPDATE POT_CHK_INDEX, EXIT.
POT_CHK_40
               CMP     CURRENT_PITCH,D0     ;CHANGE IN PITCH SETTING?
               BEQ.S   POT_CHK_70           ;BRANCH IF NOT, NO ACTION FOR THIS POT.
               MOVE    D0,CURRENT_PITCH     ;ELSE, SAVE NEW PITCH SETTING,
               ST      PITCH_CHANGE         ;SET FLAG TO INDICATE CHANGE IN SETTING.
               BRA.S   POT_CHK_70           ;UPDATE POT_CHK_INDEX, EXIT.
;
POT_CHK_50
               LSR     #1,D0                ;CHOP RAW VOL VALUE TO 7 BITS (MIDI COMPATIBILITY).
               CMP     CURRENT_VOLUME,D0    ;CHANGE IN VOLUME SETTING?
               BEQ.S   POT_CHK_70           ;BRANCH IF NOT, NO ACTION FOR THIS POT.
               MOVE    D0,CURRENT_VOLUME    ;ELSE, SAVE NEW VOLUME SETTING,
               ST      VOLUME_CHANGE        ;SET FLAG TO INDICATE CHANGE IN SETTING.
               BRA.S   POT_CHK_70           ;UPDATE POT_CHK_INDEX, EXIT.
;
;
POT_CHK_60
                                            ;X-TRA SPESHL FOR THE DATA SLIDER:
               BSR.S   PROCESS_DATA_POT     ;CALL VARIABLE-SCALING ROUTINE, UPDATE DIVIDED_POT -
               BEQ.S   POT_CHK_70           ;BRANCH IF DIVIDED_POT DID NOT CHANGE - NOTHING TO DO.
               TST.B   GUIDO_IS_AWAKE       ;GOT A CHANGE TO HANDLE - ARE WE IN MID-KEYPAD-ENTRY?
               BEQ.S   POT_CHK_64           ;BRANCH IF NOT, FOLLOW VECTOR PATHWAY TO NERVE ANNA.
                ABS_LONG
               JSR     DUMP_GUIDO           ;ELSE, KNOCK OUR BOY OUT OF THE PICTURE FIRST.
                ABS_SHORT
POT_CHK_64
               MOVE.L  POT_CHANGE_VEC,A0    ;DIVIDED_POT VALUE CHANGED - DO SOMETHING WITH IT.
               JSR     (A0)
                                            ;FALL THROUGH TO UPDATE POT_CHK_INDEX, EXIT.
;
POT_CHK_70
               MOVE    POT_CHK_INDEX,D1     ;FETCH THE POT INDEX ANEW,
               ADDQ    #2,D1                ;SET UP NEXT VALUE.
               CMP     #10,D1               ;WRAP FROM 8 BACK TO ZERO.
               BLT.S   POT_CHK_80
               CLR     D1
POT_CHK_80
               MOVE    D1,POT_CHK_INDEX     ;D-UH, STORE DA NEW INDECKS VAL-U!
POT_CHK_EXIT
               BRA     BACK_HANDLER
;
;
;
; DATA POT SCALING PROCEDURE -
; RETURNS Z FLAG CLEAR IF DIVIDED_POT VALUE IS CHANGED,
; ELSE RETURNS Z FLAG SET TO INDICATE NO CHANGE.
;
; WARNING - IF YE WOULD MODIFY THIS, KNOW YE THAT IT BE CALLED DURING
; EDIT FIELD INSTALLATION, TO AVERT SPONTANEOUS EDITS - FUCK IT UP NOT.
;
; DESTROYS D0.
;
PROCESS_DATA_POT
               MOVE    POT_VALUE,D0         ;FETCH NEW UNSCALED POT VALUE.
               MULU    POT_DIVISIONS,D0     ;SCALE BY THE NUMBER OF DIVISIONS,
               LSR     #8,D0                ;DROP BACK INTO THE UNITS RANGE -
               CMP     DIVIDED_POT,D0       ;IS THIS DIFFERENT FROM LAST DIVIDED_POT VALUE?
               BEQ.S   PRO_DPOT_EXIT        ;BRANCH IF NOT, RETURN Z FLAG SET TO INDICATE SUCH.
               MOVE    D0,DIVIDED_POT       ;ELSE UPDATE DIVIDED_POT VALUE,
               MOVEQ   #1,D0                ;CLEAR Z FLAG TO SIGNAL CHANGE.
PRO_DPOT_EXIT
               RTS
;
;AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
               SKIP
;VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV
;
; PROCESS MASTER VOLUME CHANGES -
;
; CONTINUOUSLY CONVERTS THE (MIDI-COMPATIBLE) 0-7FH VALUE IN CURRENT_VOLUME
; INTO A VOLUME_OUT_VAL THAT THE MASTER VOLUME S/H CAN USE DIRECTLY -
; DOESN'T CARE WHETHER CURRENT_VOLUME CAME FROM MIDI OR OUR VOLUME POT.
;
; IF VOLUME_CHANGE FLAG IS SET, MEANING A LOCAL VOLUME CHANGE OCCURRED,
; WE CALL XMIT_VOLUME TO TELL THE (MIDI) WORLD ABOUT IT.
;
VOL_CHANGE_CHECK
               TST.B   VOLUME_CHANGE        ;ANYONE TWIST OUR KNOB, LATELY?
               BEQ.S   VOL_CHK_10           ;BRANTCH IF KNOT, DO VALUE CONVERSION FOR LOCAL USE.
               SF      VOLUME_CHANGE        ;ELSE ACKNOWLEDGE THE CHANGE,
               BSR     XMIT_VOLUME          ;SPRED THE NUZE.
VOL_CHK_10
               MOVE    CURRENT_VOLUME,D0    ;CONVERT VOLUME SETTING TO CONTROL VALUE -
               BEQ.S   VOL_CHK_20           ;IF SETTING IS ZERO, PUT OUT 000H AS CONTROL VALUE.
               ROR     #7,D0                ;ELSE SHIFT THE 7-BIT VALUE INTO DAC-WRITE POSITION,
               ADD     #1F0H,D0             ;FILL OUT THE LOW-ORDER BITS TO ALLOW FULL-SCALE ....
VOL_CHK_20
               MOVE    D0,VOLUME_OUT_VAL    ;THIS IS WHAT REALTIME PUTS OUT FOR MASTER VOLUME.
VOL_CHK_EXIT
               BRA     BACK_HANDLER
;
;
;AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
;
;
;
;VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV
;
; IF SOMETHING NEW'S COOKING IN THE SCREEN BUFFER,
; LET'S SEE IT - BY THE WAY, LEAVES CURSOR OFF-SCREEN.
; WE DON'T EXECUTE IF SUBFUN_INSTALL FLAG IS SET - IF IT IS,
; WE'LL BE BACK HERE AGAIN REAL SOON WITH NEW SCREEN DATA,
; SO WHY BOTHER OURSELVES OR USER WITH SCREEN-POO?
;
LCD_UPDATE_CHECK
               TST.B   SUBFUN_INSTALL       ;AS DISCUSSED ABOVE.
               BNE.S   LCD_UPCHK_EXIT
               TST.B   UPDATE_LCD           ;ZO?
               BEQ.S   LCD_UPCHK_EXIT       ;NEIN.
               SF      UPDATE_LCD           ;JA - KLIEREN FLAGGEN,
                ABS_LONG
               JSR     DISP_BUFFER          ;PUTTEN OUTEN DAS NEUE BYTTEN.
                ABS_LONG
LCD_UPCHK_EXIT
               BRA     BACK_HANDLER
;
;AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
               SKIP
;VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV
;
; I'M THE ONE WHO MAKETH THE INCOMPLETE DECIMAL KEYPAD ENTRIES
; UNTO FLASH - BY GUM!
;
ES_EL_GUIDO_BLINKO
               MOVE    #GUIDO_TIMER,A0      ;SET POINTER TO BLINKO-TIMER.
               TST.B   GUIDO_IS_AWAKE       ;ARE WE IN THE MIDDLE OF SUMPIN' HERE?
               BNE.S   GUID_BL_10           ;BRANCH IF DECIMAL KEYPAD ENTRY IN PROGRESS -
               CLR     (A0)                 ;ELSE STOP THE BLINKO-TIMER,
               BRA.S   GUID_BL_EXIT         ;GET OUTA HER.  OOOPS - HERE, I MEAN.
GUID_BL_10
               TST     (A0)                 ;BLINKO-TIMER RUNNING?
               BNE.S   GUID_BL_20           ;BRANCH IF YES, SEE WHAT BLINKO-TIME IT IS.
               ST      GUIDO_FLD_STAT       ;NO - JUST STARTED KEYPAD ENTRY - FLAG "FIELD IS ON",
               BRA.S   GUID_BL_60           ;RESTART BLINKO-TIMER, EXIT.
;
GUID_BL_20
               MOVE.L  CUR_FLD_BLOCK,A1     ;FETCH FIELD POSITION/LENGTH SPEC,
               MOVE    (A1),D1
               TST.B   GUIDO_FLD_STAT       ;IS TEXT ON, OR GONE?
               BNE.S   GUID_BL_30           ;BRANCH IF ON -
               MOVEQ   #100,D0              ;"OFF" INTERVAL IS 100 MSEC,
                ABS_LONG
               JSR     REAL_TIMER           ;SEE IF TIME'S UP.
                ABS_SHORT
               BCS.S   GUID_BL_EXIT         ;NO, SO BLOW OUT OF HERE.
               ST      GUIDO_FLD_STAT       ;YES - FLAG "FIELD IS ON",
                ABS_LONG
               JSR     GUIDO_WRITES         ;REDISPLAY THE INCOMPLETE DECIMAL KEYPAD ENTRY,
                ABS_SHORT
               BRA.S   GUID_BL_50           ;DISPLAY FIELD, RESTART BLINKO-TIMER, EXIT.
;
GUID_BL_30
               MOVE    #200,D0              ;"ON" INTERVAL IS 200 MSEC,
                ABS_LONG
               JSR     REAL_TIMER           ;SEE IF TIME'S UP.
                ABS_SHORT
               BCS.S   GUID_BL_EXIT         ;NO, SO BLOW OUT OF HERE.
               SF      GUIDO_FLD_STAT       ;YES - FLAG "FIELD IS OFF",
;
;04DEC               MOVE.L  CUR_FLD_BLOCK,A1     ;FETCH FIELD POSITION/LENGTH SPEC,
;04DEC               MOVE    (A1),D1
;
               MOVE    D1,D2                ;ISOLATE FIELD POSITION IN D2.
               LSR     #8,D2
               MOVE    D2,A2                ;SET A2 AS POINTER INTO SCREEN_BUFFER.
               ADD     #SCREEN_BUFFER,A2
               MOVE.B  D1,D2                ;COPY LENGTH SPEC, D2 IS FIELD-CLEAR COUNTER/OFFSET.
               SUBQ    #1,D2
GUID_BL_40
               MOVE.B  #' ',0(A2,D2)        ;FILL ENTIRE FIELD WITH BLANKS.
               DBRA    D2,GUID_BL_40
GUID_BL_50
                ABS_LONG
               JSR     DISP_FIELD           ;NOW, COPY SCREEN_BUFFER DATA (THIS FIELD ONLY) TO LCD,
                ABS_SHORT
                                            ;FALL THROUGH TO RESTART BLINKO-TIMER.
;
GUID_BL_60
               MOVE    REAL_TIME,(A0)       ;START BLINKO-TIMER RUNNING.
               BSET    #0,1(A0)
;
GUID_BL_EXIT
               BRA     BACK_HANDLER         ;DONE, FOR NOW.   DONE FOR, NOW.  DUNNESFEAOUXREGNIAUX.
;
;AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
               SKIP
;VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV
;
; LOOK FOR REQUEST TO REPOSITION CURSOR IN CURRENT LCD FIELD -
; NORMALLY INVOKED AS LAST STEP OF EDIT-FIELD INSTALLATION,
; ALSO USED AFTER MIN_STRNG/MAX_STRNG WRITE IN PARAMETER FIELD.
;
; WE DON'T EXECUTE IF SUBFUN_INSTALL FLAG IS SET - IF IT IS,
; WE'LL BE BACK HERE AGAIN REAL SOON WITH NEW SCREEN DATA,
; SO WHY BOTHER OURSELVES OR USER WITH SCREEN-POO?
;
; NEW ADDITION: WE POSTPONE EXECUTION IF REDISP_FIELD FLAG IS SET, SINCE
; FIELD REDISPLAY WOULD UNDO WHAT WE DO HERE.  MAINLY TO SAVE ROM SPACE,
; THE NAME-EDITING FUNCTIONS HAVE BEEN RESTRUCTURED TO DEAL WITH NAMES
; AS A SINGLE FIELD RATHER THAN EIGHT SEPARATE FIELDS, MEANING THAT IT
; IS NECESSARY TO BE ABLE TO POSITION THE CURSOR ARBITRARILY WITHIN THAT
; FIELD.  THUS:  IF POSITION_CURS = 0FFH, WE DO NORMAL POSITIONING AT
; THE RIGHT END OF THE CURRENT FIELD (PER FIELD POSITION/LENGTH SPEC AT
; WHICH CUR_FLD_BLOCK IS CURRENTLY POINTING) - ELSE WE POSITION CURSOR
; AT (POSITION_CURS)-1 CHARACTER WITH RESPECT TO LEFT END OF FIELD.
;
POS_CURSOR_CHECK
               TST.B   SUBFUN_INSTALL       ;AS DISCUSSED ABOVE.
               BNE.S   POS_CUR_EXIT
               TST.B   REDISP_FIELD         ;LIKEWISE.
               BNE.S   POS_CUR_EXIT
               MOVE.B  POSITION_CURS,D0     ;IS REQUESTED?
               BEQ.S   POS_CUR_EXIT         ;NO - SO GO.
               SF      POSITION_CURS        ;YES - ACK REQ (AS THEY SAY),
               MOVE.L  CUR_FLD_BLOCK,A1     ;FETCH POINTER TO CURRENT FIELD BLOCK,
               MOVE.B  (A1)+,D1             ;FETCH FIELD POSITION.
               TST.B   D0                   ;RIGHT-END OR INDEXED CURSOR POSITIONING?
               BPL.S   POS_CUR_20           ;BRANCH FOR INDEXED POSITIONING.
               ADD.B   (A1),D1              ;NORMAL POSITIONING - ADD FIELD LENGTH TO POSITION.
               BRA.S   POS_CUR_40
POS_CUR_20
               ADD.B   D0,D1                ;INDEXED POSITIONING - ADD 1-REL INDEX TO POSITION.
POS_CUR_40
               SUBQ.B  #1,D1                ;BACK OFF BY ONE FOR BOTH POSITIONING MODES,
               LSL     #8,D1                ;PASS POSITION WITH LENGTH OF ZERO FOR CURSOR-SET ONLY.
                ABS_LONG
               JSR     DISP_FIELD           ;THIS WOULD DO IT, THEN ....
                ABS_SHORT
POS_CUR_EXIT
               BRA     BACK_HANDLER
;
;AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
;
;
;
;VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV
;
; LOOK FOR REQUEST TO REDISPLAY SETTING IN CURRENT LCD FIELD -
; NORMALLY INVOKED BY EDIT OF A NON-LINKED PARAMETER FIELD.
;
; SPLIT INTO TWO PARTS WHICH RUN IN TANDEM (DON'T YOU HATE THIS SHIT?) -
; THE FIRST PART IS WHERE FLAGS ARE TESTED/ACKNOWLEDGED, AND IF WE'RE
; RIPE FOR IT, WHERE DATA IS WRITTEN TO SCREEN_BUFFER VIA DISPLAY HOOKS.
; THE SECOND PART IS WHERE DATA GETS COPIED FROM SCREEN_BUFFER TO LCD -
; THE SECOND PART OCCURS NORMALLY IN ROTATION, UNLESS THE FIRST PART
; CAUSES IT TO BE SKIPPED OVER (WHICH IS THE NORMAL CASE, IN FACT).
; WHY ALL THIS FUSS?  TO CHOP EXECUTION TIME INTO PIECES, IS WHY.
;
; WE DON'T EXECUTE IF SUBFUN_INSTALL FLAG IS SET - IF IT IS, WE'LL BE
; BACK HERE AGAIN REAL SOON WITH NEW SCREEN, SO WHY BOTHER OURSELVES OR
; USER WITH SCREEN-POO?  REDISP_FIELD FLAG IS SWALLOWED IN THIS CASE.
;
; ALSO, WE POSTPONE OUR EXECUTION IF UPDATE_LCD FLAG IS SET -
; FIELD REDISPLAY IS USED BY EDITING SYSTEM TO POSITION CURSOR ON A
; FIELD, AND LCD_UPDATE WOULD TRASH THAT IF ALLOWED TO HAPPEN AFTERWARD.
; WE DO EXECUTE EVENTUALLY - REDISP_FIELD FLAG IS LEFT HANGING.
;
; WE DON'T ACTUALLY WRITE TO LCD IF SUBFUN_INSTALL FLAG IS SET -
; IF IT IS, WE'LL BE BACK HERE AGAIN REAL SOON WITH NEW SCREEN DATA,
; SO WHY BOTHER OURSELVES OR USER WITH SCREEN-POO?
; HOWEVER, THE DISPLAY VECTOR CALL PERFORMS A KEY FUNCTION IN KEEPING
; EDITING SYSTEM UP TO DATE FOLLOWING PARAMETER EDIT ARRANGEMENTS IN
; WHICH DISPLAY VECTOR IS USED TO MODIFY THE FETCHED VALUE IN SOME WAY -
; HENCE, WE ALWAYS DO THIS PART REGARDLESS OF SUBFUN_INSTALL STATUS.
;
RED_FLD_CHECK
                                            ;THE "FIRST" PART:
               TST.B   REDISP_FIELD         ;IS REQUESTED?
               BEQ.S   RED_FLD_SKIP         ;NO - SO GO.
               TST.B   UPDATE_LCD           ;YES - BUT IS FULL-SCREEN REFRESH ALSO IN THE WORKS?
               BNE.S   RED_FLD_SKIP         ;BRANCH IF YES, LEAVE FLAG HANGING UNTIL LATER.
               SF      REDISP_FIELD         ;NO - ACK REQ (AS THEY SAY),
               TST.B   SUBFUN_INSTALL       ;AS PER ABOVE - NO FURTHER ACTION IF THIS FLAG SET.
               BNE.S   RED_FLD_SKIP
               MOVE.L  CUR_FLD_BLOCK,A1     ;FETCH POINTER TO CURRENT FIELD BLOCK,
                ABS_LONG
               JSR     WRITE_PARAMETER      ;WRITE DISPLAY INTO SCREEN_BUFFER,
                ABS_SHORT
               BRA.S   RED_FLD_EXIT
RED_FLD_SKIP
               ADDQ    #4,SPINE_COUNT       ;NOT REDISPLAYING, SO SKIP THE SECOND PART.
               BRA.S   RED_FLD_EXIT
;
RED_FLD_DISP
;03DEC                                            ;THE "SECOND" PART:
;03DEC               TST.B   SUBFUN_INSTALL       ;AS DISCUSSED ABOVE - NO LCD WRITE IF THIS FLAG SET.
;03DEC               BNE.S   RED_FLD_SKIP
               MOVE.L  CUR_FLD_BLOCK,A1     ;FETCH POINTER TO CURRENT FIELD BLOCK,
                ABS_LONG
               JSR     DISP_PARAM_FIELD     ;TRANSFER BUFFER FIELD TO LCD.
                ABS_SHORT
;
RED_FLD_EXIT
               BRA     BACK_HANDLER
;
;AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
               SKIP
;VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV
;
; SEE IF CURRENT_SOUND HAS CHANGED LATELY FROM WHAT WE REMEMBERED -
; IF IT HAS, SEE IF THIS MEANS WE SHOULD UPDATE THE LCD DISPLAY.
; HOWSOEVER, WE WILL NOT WALK UPON A SCREEN_DAEMON DISPLAY FOR THIS.
;
SOUND_CHANGE_CHECK
               MOVE    CURRENT_SOUND,D0     ;WHAT IT IS ....
               CMP     LAST_CUR_SOUND,D0    ;AND WHAT IT WAS ....
               BEQ     SND_CHG_EXIT         ;BRANCH IF NO CHANGE - MAINTAIN.
               MOVE    D0,LAST_CUR_SOUND    ;CHANGED - LET'S BRING OUR SHELVES UP TO DATE.
               MOVE    D0,DEL_REC_SOUND     ;ALSO UPDATE SOUND NUMERO TO DELETE/RECOVER.
               MOVE.B  D0,SDS_OUT_NUM       ; ah so for sample dump numbers.
               MOVE.B  D0,SDS_REQ_NUM
;
               MOVE.L  REAL_LONG_TIME,LCD_TIMER  ;GOOD ENUF REASON TO REFRESH THE LCD BACKLIGHT TIMEOUT
;
               CMP     #8,CUR_FUN_INDEX     ;ARE WE IN A SOUND EDIT SUBFUNCTION?
               BCS     SND_CHG_40           ;BRANCH IF YES, REINSTALL THE CURRENT SUBFUNCTION.
;890402               CMPI.W  #17,CUR_FUN_INDEX    ; ah so for MIDI 2 (sample dump).
;890402               BEQ     SND_CHG_40
;890402                nope, this method no good, since INDEX = -1 ....
               MOVE.L  CUR_SUB_BLOCK,D7     ;CHECK FOR A NUMBER OF SCREENS NOT IN SOUND-EDIT GROUP:
               CMP.L   #MODE_4_OUT_SUB,D7   ;MIGHT BE DOING MIDI MAPPING ....
               BEQ     SND_CHG_40           ;BRANCH IF INDEED WE ARE.
               CMP.L   #MOVE_UNIT_SUB,D7    ;COULD BE IN THE LOAD-ONE-SOUND SCREEN ....
               BEQ     SND_CHG_40           ;BRANCH IF WE ARE.
               CMP.L   #KIT_REPLACE_SUB,D7  ;THEN THERE'S ALWAYS THE KIT SOUND-REPLACE SCREEN ....
               BEQ     SND_CHG_40           ;YOU KNOW THE SCORE.
               CMPI.L  #SDS_OUT_SUB,D7      ; Ah so for sample dump function.
               BEQ     SND_CHG_40
               CMPI.L  #SDS_REQ_SUB,D7      ; Ah so for sample request function.
               BEQ.S   SND_CHG_40
;
               CMP.L   #SEQ_ERASE_SUB,D7    ;ARE WE IN ONE OF THE SEQUENCE-ERASE EDIT SCREENS?
               BEQ.S   SND_CHG_10           ;BRANCH IF YES, GOT SOME SETTING UPDATING TO DO.
               CMP.L   #SEQ_ERASE_SUB_2,D7
               BEQ.S   SND_CHG_10
               CMP.L   #SEQ_VEL_SCALE_SUB,D7     ;LIKEWISE FOR SEQUENCE VELOCITY-SCALE SCREEN.
               BEQ.S   SND_CHG_10
               CMP.L   #TRANSPOSE_SUB,D7
               BNE.S   SND_CHG_EXIT              ;IF NONE OF ABOVE, NO REDISPLAY - EXIT.
;
SND_CHG_10
                                            ;DETERMINE WHERE TO GET ALT-PARAMS STATUS FOR UPDATING
                                            ;SELECT SETTINGS IN SEQUENCE ERASE, VEL-SCALE SCREENS:
                                            ;(WHY ALL THIS HASSLE JUST TO READ ALT_PARAM_FLAG?
                                            ;BECAUSE, IF CURRENT_SOUND WAS CHANGED BY A LIVE EVENT,
                                            ;THEN ALT_PARAM_FLAG MAY NOT HAVE CAUGHT UP TO IT YET.)
               MOVE    EDIT_KIT_INDEX,D1    ;IF CURRENT_SOUND WAS LAST CHANGED BY LIVE EVENT OR
               LSL     #3,D1                ;KIT-SELECT, WE CAN EXPECT TO FIND SAME SOUND NUMBER AT
               ADD     PAD_JUST_HIT,D1      ;EDIT-TARGET POINT IN PAD/PRESET ARRAY -
               MOVE    #PAD_SOUNDS,A0       ;LOOK IN PAD ARRAY IF NOT IN KIT-BUILD SCREEN/MODE,
               MOVE.B  0(A0,D1),D2          ;FETCH SOUND NUMBER / ALT-PARAMS OF LAST LIVE EVENT.
               MOVE    D2,D3                ;ISOLATE ALT-PARAMS BIT IN D3.
               AND     #1,D3
               LSR     #1,D2                ;ISOLATE SOUND NUMBER IN D2 -
               AND     #1FH,D2
               CMP.B   D2,D0                ;SAME AS OUR NEW CURRENT_SOUND?
               BEQ.S   SND_CHG_20           ;YES - ASSUME LIVE CHANGE, USE ITS ALT-PARAMS SETTING.
               MOVE    ALT_PARAM_FLAG,D3    ;ELSE ASSUME DIRECT EDIT OF CURRENT_SOUND -
                                            ;USE EXISTING ALT_PARAM_FLAG STATUS.
SND_CHG_20
                                            ;NOW - COMPUTE NEW SETTING FOR SEQUENCE-ERASE SCREENS:
               LSL     #1,D0                ;TAKE SOUND NUMBER * 2 (ALT-PARAMS OFF/ON PER SOUND),
               ADDQ    #2,D0                ;OFFSET BY 2 FOR "ALL" AND "ALL DRUMS" SETTINGS,
               ADD     D3,D0                ;FIGURE IN ALT-PARAMS SETTING OBTAINED ABOVE.
;
                                            ;SEQ-ERASE SELECT - DON'T WIPE OUT "NOTES ABOVE/BELOW":
               MOVE    DATA_TYPE,D1         ;FETCH THE ERASE DATA-TYPE SETTING.
               CMP     #67,D1               ;"NOTES BELOW xxx"?
               BEQ.S   SND_CHG_30           ;BRANCH IF YES, LEAVE AS IS.
               CMP     #68,D1               ;"NOTES ABOVE xxx"?
               BEQ.S   SND_CHG_30           ;BRANCH IF YES, LEAVE AS IS.
               MOVE    D0,DATA_TYPE         ;ELSE SET DATA TYPE TO "DRum XXa" PER SOUND/ALT ABOVE.
SND_CHG_30
               CMP.L   #SEQ_ERASE_SUB,D7    ;ARE WE IN ONE OF THE SEQUENCE-ERASE EDIT SCREENS?
               BEQ.S   SND_CHG_40           ;BRANCH IF YES, DONT CHANGE CHAN_NUM
               CMP.L   #SEQ_ERASE_SUB_2,D7
               BEQ.S   SND_CHG_40
               ADD     #31,D0               ;SET DATA CATEGORY FOR SEQUENCE VELOCITY SCALE FUNCTION
               MOVE    D0,CHAN_NUM          ;PER ABOVE SOUND NUMBER / ALT-PARAMS SETTING - SIMILAR
                                            ;TO ERASE SETTING, PLUS STEP ABOVE SETTINGS FOR 32 MIDI
                                            ;CHANNELS PLUS "ALL CHANNELS" SETTING - THEN DOWN BY 2
                                            ;AS "ALL DRUMS" AND "ALL" SETTINGS ARE AT TOP OF RANGE.
;
SND_CHG_40
               TST     SCRN_DM_TIMER        ;WE HAVE REASON TO REDISPLAY, BUT - IF DAEMON IS ALIVE,
               BNE.S   SND_CHG_EXIT         ;DON'T PISS HIM OFF.
               ST      SUBFUN_INSTALL       ;ELSE, REINSTALL THE CURRENT SUBFUNCTION THE NEXT
                                            ;TIME AROUND THE LOOP - THIS'LL TAKE CARE OF EV'THIN.
SND_CHG_EXIT
               BRA     BACK_HANDLER
;
;AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
;
;
;
;VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV
;
; ACKNOWLEDGE PAD_HIT_FLAG IF SET -
; TAKE ANY ACTION WHICH SEEMS APPROPRIATE UNDER THE CIRCUMSTANCES.
;
PAD_HIT_CHECK
               TST.B   PAD_HIT_FLAG
               BEQ.S   PAD_HIT_EXIT         ;WELL IF WE'RE ASLEEP, WHAT THE HELL ....
               SF      PAD_HIT_FLAG         ;ELSE, SAY "I HURD DAT",
;
               MOVE.L  REAL_LONG_TIME,LCD_TIMER  ;GOOD ENUF REASON TO REFRESH THE LCD BACKLIGHT TIMEOUT
;
               MOVE.L  CUR_SUB_BLOCK,D0     ;CHECK FOR BEING IN SCREENS WITH PAD-INPUT INTERFACE -
;
               CMP.L   #SEQ_ERASE_SUB,D0    ;ARE WE IN ONE OF THE SEQUENCE-ERASE EDIT SCREENS?
               BEQ.S   LOVE_IS_THE_DRUG     ;BRANCH IF YES, GOT SOME SETTING UPDATING TO DO.
               CMP.L   #SEQ_ERASE_SUB_2,D0
               BEQ.S   LOVE_IS_THE_DRUG
               CMP.L   #SEQ_VEL_SCALE_SUB,D0     ;LIKEWISE FOR SEQUENCE VELOCITY-SCALE SCREEN.
               BEQ.S   LOVE_IS_THE_DRUG
               CMP.L   #TRANSPOSE_SUB,D0
               BNE.S   NATURALS_NOT_IN_IT        ;IF NONE OF ABOVE, NO REDISPLAY - EXIT.
LOVE_IS_THE_DRUG
               MOVE    #-1,LAST_CUR_SOUND        ;    ELSE, FORCE AN APPARENT SOUND NUMBER CHANGE -
                                                 ;     THIS WILL NICELY UPDATE THESE SCREENS IF YOU
                                                 ;     HAPPEN TO REENTER THEM AND HIT THE SAME PAD AS
                                                 ;     YOU DID LAST.
NATURALS_NOT_IN_IT
               CMP.L   #MUTE_SUB,D0         ;ARE WE IN TRACK-MUTE SUBFUNCTION?
               BNE.S   PAD_HIT_20                     ;BRANCH IF NOT,
               MOVE    PAD_JUST_HIT,NEW_MUTE_TRACK    ;ELSE TRANSFER INDEX OF PAD JUST HIT,
               BRA     PAD_HIT_1000                   ;GO REDISPLAY.
PAD_HIT_20
               CMP.L   #SEQ_BOUNCE_SUB,D0   ;ARE WE IN SEQUENCE BOUNCE FUNCTION?
               BEQ.S   PAD_HIT_999          ;BRANCH IF WE ARE -
               CMP.L   #BUILD_SONG_SUB2,D0  ;HOW ABOUT SONG TRACK-MUTE EDIT SCREEN?
               BNE.S   PAD_HIT_EXIT         ;BRANCH IF NOT.
PAD_HIT_999
               MOVE    PAD_JUST_HIT,BNC_TRK_NUM  ;ELSE TRANSFER PAD-HIT INDEX AND REDISPLAY.
;
PAD_HIT_1000
               ST      SUBFUN_INSTALL
;
PAD_HIT_EXIT
               BRA     BACK_HANDLER         ;THEN REALIZE WE CAN'T COMPREHEND THE CIRCUMSTANCES,
                                            ;LET ALONE DECIDE WHAT ACTION SEEMS APPROPRIATE ....
;
;AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
;
;
;
;VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV
;
; LOOK FOR CHANGE IN PAD_JUST_HIT STATUS (NUMBER OF MOST RECENTLY HIT PAD) -
; TAKE ANY ACTION WHICH SEEMS APPROPRIATE UNDER THE CIRCUMSTANCES.
;
PAD_CHANGE_CHECK
               MOVE    PAD_JUST_HIT,D0      ;FETCH NUMBER OF MOST RECENTLY HIT PAD,
               CMP     LAST_PAD_HIT,D0      ;COMPARE IT WITH THE ONE LAST SEEN BY BACKGROUND -
               BEQ.S   PAD_CHG_EXIT         ;WELL IF WE'RE ASLEEP, WHAT THE HELL ....
               MOVE    D0,LAST_PAD_HIT      ;ELSE, SAY "I HURD DAT", THINK OF THINGS TO DO ....
               TST.B   BUILD_KIT_FLAG       ;ARE WE IN KIT EDITING SCREEN?
               BNE.S   PAD_CHG_20           ;BRANCH IF YAH, WE GONNA REINSTALL SUBFUNCTION.
               CMP.L   #INITIAL_PAN_SUB,CUR_SUB_BLOCK ;NO - WE BE IN INITIAL PAN SCREEN?
               BNE.S   PAD_CHG_EXIT                   ;NUH-UH, SO GIT - OTHER SOUND EDIT SCREENS
                                                      ;ARE REDISPLAYED AUTOMATICALLY IF CURRENT
                                                      ;SOUND OR ALT-PARAMS STATUS CHANGES -
                                                      ;OTHERWISE NO NEED TO REDISPLAY, EH?
PAD_CHG_20
               ST      SUBFUN_INSTALL       ;REDISPLAY SETTINGS FOR NEW PAD -
;
PAD_CHG_EXIT
               BRA     BACK_HANDLER
;
;AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
               SKIP
;VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV
;
; EXECUTE ANY PENDING PERFORMANCE PARAMETER EDITS (PITCH, LEVEL, PAN) -
; HOWEVER, DO THIS ONLY IF ONE OR MORE PADS CURRENTLY ON,
; OR IF IN KIT-BUILD SCREEN (OR INITIAL PAN SCREEN, FOR PAN EDITS ONLY).
; OTHERWISE, THESE EDITS REMAIN PENDING UNTIL A PAD IS HIT,
; THEN ARE APPLIED TO THAT PAD (BY PRO_PADS_ON OR EQUIVALENT PAD-POSEUR
; EVENT HANDLER).
; OH, AND, HEY - IF ED_BLOCK_TIMER WAS ACTIVATED BY SOMEONE, SWALLOW ALL
; PENDING PERFORMANCE EDITS WITHOUT A TRACE FOR THE DURATION - THIS IS
; HOW WE PREVENT SPONTANEOUS EDITS FOLLOWING A DISK OPERATION, ETC.
;
PAD_EDIT_CHECK
               MOVE    #ED_BLOCK_TIMER,A0   ;HEY - HAVE WE GOT "EDITOR'S BLOCK"?
               TST     (A0)                 ;SEE IF EDIT-BLOCK TIMER IS RUNNING -
               BEQ.S   PAD_ED_20            ;BRANCH IF NOT, OK TO RESPOND TO PENDING EDITS.
               MOVE    #1000,D0             ;OTHERWISE, WE ALLOW APPROX. 1 SEC OF IGNORE TIME -
                ABS_LONG
               JSR     REAL_TIMER           ;SEE IF THAT TIME IS UP YET.
                ABS_SHORT
               BCS     PAD_ED_ZZ            ;BRANCH IF NOT, WHOMP ANY PENDING-EDIT FLAGS AND EXIT.
;
PAD_ED_20
               TST.B   BUILD_KIT_FLAG       ;ARE WE IN KIT-BUILD SCREEN?
               BNE.S   JUST_HIT_10          ;BRANCH IF YES - IMMEDIATELY HANDLE ANY PENDING EDITS.
               CMP.L   #INITIAL_PAN_SUB,CUR_SUB_BLOCK ;SAME FOR PAN EDITS ONLY, IF IN THIS SCREEN -
               BNE.S   PAD_ED_80                      ;IF NOT, EDIT ONLY PAD(S) CURRENTLY ON.
               TST.B   PAN_CHANGE           ;WE'RE IN INITIAL PAN SCREEN - IS A PAN EDIT PENDING?
               BEQ.S   PAD_ED_80            ;BRANCH IF NOT, EFFECT ANY OTHER EDITS FOR PAD(S) ON.
               BRA.S   JUST_HIT_40          ;ELSE - EDIT PAN ONLY, LAST PAD HIT (LIVE PAD ARRAY).
;
JUST_HIT_10
                                            ;APPLY PENDING EDITS TO LAST-HIT PAD:
               TST.B   PITCH_CHANGE         ;WE GOT A PITCH CHANGE?
               BEQ.S   JUST_HIT_20          ;BRANCH IF NO -
               MOVE.B  CURRENT_PITCH+1,D5   ;IF YES, EDIT MOST RECENTLY HIT PAD -
               MOVE    #PAD_PITCHES,A2
               BSR.S   DO_JUST_HIT_EDIT
               SF      PITCH_CHANGE         ;ACKNOWLEDGE THE CHANGE.
JUST_HIT_20
               TST.B   LEVEL_CHANGE         ;WE GOT A LEVEL CHANGE?
               BEQ.S   JUST_HIT_40          ;BRANCH IF NO -
               MOVE.B  CURRENT_LEVEL+1,D5   ;IF YES, EDIT MOST RECENTLY HIT PAD -
               MOVE    #PAD_LEVELS,A2
               BSR.S   DO_JUST_HIT_EDIT
               SF      LEVEL_CHANGE         ;ACKNOWLEDGE THE CHANGE.
JUST_HIT_40
               TST.B   PAN_CHANGE           ;WE GOT A PAN CHANGE?
               BEQ     PAD_ED_EXIT          ;BRANCH IF NO - WE GOT NO MO'CHANGE.  SO WHAT?
               MOVE.B  CURRENT_PAN+1,D5     ;IF YES, EDIT MOST RECENTLY HIT PAD -
               MOVE    #PAD_PANS,A2
               BSR.S   DO_JUST_HIT_EDIT
               SF      PAN_CHANGE           ;ACKNOWLEDGE THE CHANGE.
               BRA     PAD_ED_EXIT          ;OUR WORK HERE?  IT'S FINISHED.
;
;
DO_JUST_HIT_EDIT
                                            ;PAD ARRAY POINTER IS IN A2, NEW SETTING IN D5.B -
               ST      SUBFUN_INSTALL       ;THIS PATH IMPLIES SETTINGS VISIBLE - REDISPLAY THEM.
               MOVE    PAD_JUST_HIT,D0      ;DO EDITS WITH RESPECT TO MOST RECENTLY HIT PAD ONLY.
               BRA     DO_PAD_KIT_EDIT      ;RETURN THROUGH DO_PAD_KIT_EDIT.
;
;
; ----------------------------------------------------------------------
;
;
PAD_ED_80
               MOVE.B  CUR_PADS_ON,D1       ;ARE ANY PADS CURRENTLY ON?
               BEQ.S   PAD_ED_E0            ;BRANCH IF NOT - MAYBE PAD-FOOTSWITCHES .... ?
;
               TST.B   PITCH_CHANGE         ;WE GOT A PITCH CHANGE?
               BEQ.S   CUR_PADS_A0          ;BRANCH IF NO -
               MOVE.B  CURRENT_PITCH+1,D5   ;YES - EDIT ALL PADS CURRENTLY.
               MOVE    #PAD_PITCHES,A2
               BSR.S   DO_CUR_PADS_EDIT
CUR_PADS_A0
               TST.B   LEVEL_CHANGE         ;WE GOT A LEVEL CHANGE?
               BEQ.S   CUR_PADS_C0          ;BRANCH IF NO -
               MOVE.B  CURRENT_LEVEL+1,D5   ;YES - EDIT ALL PADS CURRENTLY.
               MOVE    #PAD_LEVELS,A2
               BSR.S   DO_CUR_PADS_EDIT
CUR_PADS_C0
               TST.B   PAN_CHANGE           ;WE GOT A PAN CHANGE?
               BEQ.S   PAD_ED_E0            ;BRANCH IF NO - WE GO HOME NOW.
               MOVE.B  CURRENT_PAN+1,D5     ;YES - EDIT ALL PADS CURRENTLY.
               MOVE    #PAD_PANS,A2
               BSR.S   DO_CUR_PADS_EDIT
;
               BRA.S   PAD_ED_E0            ;NOW GO CHECK FOR PAD-FOOTSWITCHES.
;
;
DO_CUR_PADS_EDIT
                                            ;ENTER WITH COPY OF CUR_PADS_ON IN D1.B,
                                            ;PAD ARRAY POINTER IN A2 AND NEW SETTING IN D5.B -
               MOVEQ   #7,D0                ;DOES EDITS WITH RESPECT TO ALL PADS CURRENTLY ON.
DO_CP_ED_20
               BTST    D0,D1
               BEQ.S   DO_CP_ED_40          ;BRANCH OVER EDIT CALL IF THIS PAD NOT ON.
               BSR.S   DO_PAD_KIT_EDIT      ;EDIT THE INDICATED PAD ARRAY.
DO_CP_ED_40
               DBRA    D0,DO_CP_ED_20       ;CHECK FOR OTHER PADS ON,
               RTS                          ;RETURN WHEN ALL PADS CHECKED.
;
;
; ----------------------------------------------------------------------
;
;
PAD_ED_E0
               MOVE.B  CUR_FTPADS_ON,D3     ;ANY PAD-FOOTSWITCHES ON?
               BEQ.S   PAD_ED_Z0            ;NO - CLEAR FLAGS IF ANY EDITS WERE DONE, THEN EXIT.
               BTST    #1,D3                ;YES - WE BE DOING FOOTSWITCH 1 THEN?
               BEQ.S   PAD_ED_F0            ;AHHH - NO.
               MOVE    FTSW1_ACTION,D0      ;YES - GET FOOTSWITCH ACTION CODE (IMPLIES PAD NUMBER),
               MOVE    FTSW1_KIT,D2         ;A-AND, KIT TOO (NOT NECESSARILY SAME AS KIT_INDEX).
               BSR.S   DO_CUR_FTSW_EDIT     ;APPLY PENDING EDITS TO THIS "PAD".
PAD_ED_F0
               BTST    #0,D3                ;YES - WE BE DOING FOOTSWITCH 1 THEN?
               BEQ.S   PAD_ED_Z0            ;AHHH - NO.  SKRAMOUTAHERE.
               MOVE    FTSW2_ACTION,D0      ;YES - GET FOOTSWITCH ACTION CODE (IMPLIES PAD NUMBER),
               MOVE    FTSW2_KIT,D2         ;A-AND, KIT TOO (NOT NECESSARILY SAME AS KIT_INDEX).
               BSR.S   DO_CUR_FTSW_EDIT     ;APPLY PENDING EDITS TO THIS "PAD".
               BRA.S   PAD_ED_Z0            ;NOW - CLEAR FLAGS IF ANY EDITS WERE DONE, THEN EXIT.
;
;
DO_CUR_FTSW_EDIT
               SUB     #38,D0               ;CONVERT FOOTSWITCH ACTION CODE TO PAD NUMBER.
               TST.B   PITCH_CHANGE         ;WE GOT A PITCH CHANGE?
               BEQ.S   CUR_FTSW_10          ;BRANCH IF NO -
               MOVE.B  CURRENT_PITCH+1,D5   ;YES - EDIT THIS FOOTSWITCH "PAD".
               MOVE    #PAD_PITCHES,A2
               BSR.S   DO_THAT_EDIT
CUR_FTSW_10
               TST.B   LEVEL_CHANGE         ;WE GOT A LEVEL CHANGE?
               BEQ.S   CUR_FTSW_20          ;BRANCH IF NO -
               MOVE.B  CURRENT_LEVEL+1,D5   ;YES - EDIT THIS FOOTSWITCH "PAD".
               MOVE    #PAD_LEVELS,A2
               BSR.S   DO_THAT_EDIT
CUR_FTSW_20
               TST.B   PAN_CHANGE           ;WE GOT A PAN CHANGE?
               BEQ.S   CUR_FTSW_EXIT        ;BRANCH IF NO - WE GO HOME NOW.
               MOVE.B  CURRENT_PAN+1,D5     ;YES - EDIT THIS FOOTSWITCH "PAD".
               MOVE    #PAD_PANS,A2
               BSR.S   DO_THAT_EDIT
CUR_FTSW_EXIT
               RTS
;
;
; ----------------------------------------------------------------------
;
;
PAD_ED_Z0
               OR.B    D3,D1                ;END OF PADS-ON EDIT PATH - WERE ANY ON?
               BEQ.S   PAD_ED_EXIT          ;EXIT IF NOT, LEAVE PENDING EDITS PENDING FOR PAD HIT.
PAD_ED_ZZ
               SF      PITCH_CHANGE         ;CLEAR ALL EDIT-PENDING FLAGS - WE DID PADS-ON EDITS,
               SF      LEVEL_CHANGE         ;OR WE'RE IN EDIT-BLOCK TIMEOUT.
               SF      PAN_CHANGE
;
;
PAD_ED_EXIT
               BRA     BACK_HANDLER         ;THERE, THAT SH .... SHOULD BE ....
;
;
; ----------------------------------------------------------------------
;
;
DO_PAD_KIT_EDIT
                                            ;PAD NUMBER FOR EDIT IS IN D0, NEW SETTING IN D5(.B) -
                                            ;A2 CONTAINS POINTER TO ONE OF THE PAD ARRAY BLOCKS.
               MOVE    KIT_INDEX,D2         ;GENERATE OFFSET INTO PAD OR KIT ARRAY -
               TST.B   BUILD_KIT_FLAG       ;ARE WE DOING USER KIT EDIT IN KIT-BUILD SCREEN?
               BEQ.S   DO_THAT_EDIT         ;BRANCH IF NOT, INDEX USING KIT_INDEX INTO PAD ARRAYS.
               MOVE    EDIT_KIT_INDEX,D2    ;ELSE INDEX USING EDIT_KIT_INDEX INTO PRESET ARRAYS.
               ADD     #256,A2              ;THIS GETS US FROM PAD ARRAYS TO PRESET ARRAYS.
               BSET    D2,KITS_EDITED       ;MARK THIS KIT AS HAVING BEEN EDITED.
;
DO_THAT_EDIT
                                            ;ENTER HERE WITH D2/A2 ALREADY RESOLVED.
               LSL     #3,D2
               ADD     D0,D2
               MOVE.B  D5,0(A2,D2)          ;STORE NEW SETTING INTO ARRAY.
               RTS
;
;AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
               SKIP
;VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV
;
; TRACK AND HANDLE CHANGES IN KIT_INDEX AND/OR EDIT_KIT_INDEX:
;
KIT_CHANGE_DAEMON
               TST.B   BUILD_KIT_FLAG       ;ARE WE IN KIT-BUILD SCREEN?
               BEQ.S   KP_DM_10             ;BRANCH IF NO - SEE IF WE'RE IN INITIAL PAN SCREEN.
               MOVE    #KIT_SOUNDS,A0       ;YES - WE'LL GET NEW CURRENT_SOUND FROM PRESET ARRAY.
               BRA.S   KP_DM_20
KP_DM_10
               CMP.L   #INITIAL_PAN_SUB,CUR_SUB_BLOCK ;HOW ABOUT "KIT-BUILD WEST"?
               BNE.S   KP_DM_40                       ;NEITHER OF ABOVE - JUST CHECK LEDs.
               MOVE    #PAD_SOUNDS,A0                 ;FOR PAN SCREEN GET NEW CURRENT_SOUND
                                                      ;FROM LIVE PAD ARRAY (NOT PRESET ARRAY).
KP_DM_20
               MOVE    EDIT_KIT_INDEX,D0    ;IN ONE OF THE KIT-BUILD TYPE SCREENS -
               CMP     KIT_INDEX,D0         ;HAS EDIT KIT INDEX CHANGED LATELY?
               BEQ.S   KP_DM_40             ;BRANCH IF NOT - SCREEN INFO SHOULD BE UP TO DATE.
               ST      SUBFUN_INSTALL       ;KIT CHANGED - REDISPLAY SETTINGS FOR NEW KIT,
               MOVE    D0,KIT_INDEX         ;UPDATE KIT_INDEX (TRACKS EDIT KIT IN KIT-BUILD MODE),
               LSL     #3,D0                ;FIND ARRAY CELL FOR PAD_JUST_HIT IN NEW KIT,
               ADD     PAD_JUST_HIT,D0
               MOVE.B  0(A0,D0),D0          ;LOAD SOUND NUMBER / ALT PARAMS BIT.
               LSR     #1,D0                ;SCRAPE OFF THE ALT BIT,
               MOVE    D0,CURRENT_SOUND     ;PRESTO - NEW CURRENT SOUND STATUS TOO.
KP_DM_40
               MOVE    KIT_INDEX,D0         ;ARE KIT/BANK LEDs DOING WHAT THEY SHOULD BE?
               SF      LED_STEADY+1         ;WELL, LET'S MAKE 'EM!
               BSET    D0,LED_STEADY+1      ;WANT ONLY THIS KIT/BANK LED LIT.
               BRA     BACK_HANDLER         ;DAT BE ALL, FOAX.
;
;AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
;
;
;
;VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV
;
; UPDATE PAD ARRAYS FOR ANY KITS WHICH WERE EDITED
; WHEN LAST WE WERE IN KIT-BUILD MODE (ONE KIT PER PASS):
;
KIT_EDIT_DAEMON
               TST.B   BUILD_KIT_FLAG       ;ARE WE YET IN KIT-BUILD SCREEN/MODE?
               BNE.S   KIT_ED_DM_EXIT       ;BRANCH IF SOOTH, WE ACT NOT AT THIS JUNK-CHURE.
               TST.B   KITS_EDITED          ;NOT IN KIT-BUILD - FETCH BIT-MAP OF KITS EDITED WHEN
               BEQ.S   KIT_ED_DM_EXIT       ;WE WERE IN KIT-BUILD .... EXIT IF NONE.
               MOVEQ   #7,D0                ;IF ANY, FIND ONE AND COPY KIT ONTO ITS PAD ARRAYS.
KIT_ED_DM_10
               BCLR    D0,KITS_EDITED       ;SIMULTANEOUS TEST AND CLEAR ....
               BNE.S   KIT_ED_DM_20         ;JUMP OUTTA LOOP IF WE FOUND ONE, GO UPDATE PADS.
               DBRA    D0,KIT_ED_DM_10      ;LOOP IF WE AIN'T FOUND ONE YET.
               BRA.S   KIT_ED_DM_EXIT       ;LET'S PLAY IT SAFE - STOP AFTER TESTING ALL BITS ONCE.
KIT_ED_DM_20
                ABS_LONG
               JSR     COPY_KIT_TO_PADS     ;MOVE THE INFO OVER WITHOUT DISTURBING ANYONE -
                                            ;D0 SAYS WHO TO DO.
                ABS_SHORT
KIT_ED_DM_EXIT
               BRA     BACK_HANDLER
;
;AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
                SKIP
;VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV
;
; CHECKS TO SEE IF LAST MIDI KEY ON HAS CHANGED AND REINSTALLS IF IN SEQUENCE ERASE FUNCTION.
;
;
MIDI_CHANGE_CHECK
               MOVE    LAST_MIDI,D0             ;GET LAST MIDI KEY
               CMP     OLD_LAST_MIDI,D0         ;SEE IF IT HAS CHANGED
               BEQ.S   MIDI_CHG_EXIT            ;IF NO CHANGE SPLIT
               MOVE    D0,OLD_LAST_MIDI         ;UPDATE OLD LAST MIDI KEY
               MOVE.L  CUR_SUB_BLOCK,D0         ;SEE IF WERE IN SEQUENCE ERASE FUNCTION
               CMP.L   #SEQ_ERASE_SUB_2,D0
               BNE.S   MIDI_CHG_EXIT            ;IF NOT DONT REINSTALL
               ST      SUBFUN_INSTALL
MIDI_CHG_EXIT  BRA     BACK_HANDLER
;
;AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
