               INCLUDE HPFIXUPS
               TITLE "PRO_CLICK"
***************************************************************************************************
***************************************************************************************************
***                                                                                             ***
***            PRO_CLICK - HOW TO MOVE ON DOWN THE ROAD                                         ***
***                                                                                             ***
***************************************************************************************************
***************************************************************************************************
;
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 SEQDEFS         ;SEQUENCER CONSTANT DEFINITIONS.
;
               GLB     PRO_CLICK
               GLB     SEQ_MEM_CHECK
               GLB     TRACK_MUTE_CHECK
               GLB     BAR_MARKER_HANDLER,OTRA_BAR_CHORES
               GLB     BEAT_DISPLAY_BOY
               GLB     CHECK_FOR_A_R_MARK
               GLB     REPEAT_SNAPSHOT,REPEAT_REPLAY
               GLB     PHASE_0,PHASE_1,PHASE_2,PHASE_3,PHASE_4
;
               EXTERNAL  START_ACC_RIT,UPDATE_ACC_RIT
               EXTERNAL  SNGL_STEP_PAUSE
               EXTERNAL  SEQ_ON_INTERNAL,SEQ_OFF_INTERNAL
               EXTERNAL  PAD_ON_AUTOREPEAT,PAD_OFF_AUTOREPEAT
               EXTERNAL  FTPAD_ON_AUTORPT,FTPAD_OFF_AUTORPT
               EXTERNAL  AUTO_OFF_MIDI,AUTORPT_MIDI
               EXTERNAL  LOAD_A_SEQ,LOAD_B_SEQ
               EXTERNAL  SEND_MIDI_CONTINUE,SEND_MIDI_STOP
               EXTERNAL  SEND_6803_CONTINUE
               EXTERNAL  MANUAL_PUNCH_OUT
               EXTERNAL  SEQ1_DSTR_READ
               EXTERNAL  LOG_IN_OLD_PAD
               EXTERNAL  TYPE_1_XMIT
               EXTERNAL  LOG_OUT_OLD_PAD
               EXTERNAL  TYPE_2_XMIT
               EXTERNAL  LOG_IN_OLD_MIDI
               EXTERNAL  TYPE_3_XMIT
               EXTERNAL  LOG_OUT_OLD_MIDI
               EXTERNAL  TYPE_4_XMIT
               EXTERNAL  TYPE_5_XMIT
               EXTERNAL  TYPE_6_XMIT
               EXTERNAL  TAP_TIME_OFFSET
               EXTERNAL  SEQ_END_HANDLER
               EXTERNAL  WASTELAND_WRITE,TIMED_SEQ_WRITE,TIMED_WASTE_WRITE,SEQ_WRITE
               EXTERNAL  WASTELAND_COPY
               EXTERNAL  SEQ_NDSTR_READ
               EXTERNAL  ERASE_SEEK
               EXTERNAL  SEQ_PLAYBACK_SUB
               EXTERNAL  SONG_PLAYBACK_SUB
               EXTERNAL  REC_TIME_SIG_SUB
               EXTERNAL  USEC_TO_ALL
               EXTERNAL  STASH_OLD_MIDI_ONS,STASH_OLD_PAD_ONS
               EXTERNAL  M_WIPE_AND_FLUSH,P_WIPE_AND_FLUSH
               EXTERNAL  MIDI_UNSTASH,PADS_UNSTASH
               EXTERNAL  XMIT_1_PA_SEQ
               EXTERNAL  XMIT_1_PB_SEQ
               EXTERNAL  PUNCH_IN_NOW
               EXTERNAL  SMPTE_PIN_SUB
               EXTERNAL  SMPTE_POUT_SUB
               EXTERNAL  AUTO_PUNCH_OUT
               EXTERNAL  PLAY_LED_OFF
               EXTERNAL  STOP_TC
               EXTERNAL  SYNC_PLAY_RESTART
;
                                            ;RAM, AND SUTCH:
               EXTERNAL  XMIT_TEMP_1
               EXTERNAL  NEW_PHASE_LEN,NOW_BEAT
               EXTERNAL  NEW_PHASE_LIST,CLICKS_THIS_DENOM,PROCESSED_TAP
;
               EXTERNAL  MIDI_ON_WRITE
               EXTERNAL  PAD_ON_WRITE
               EXTERNAL  NOTE_OFF_WRITE
               EXTERNAL  NON_NOTE_WRITE
               EXTERNAL  OLD_SEQ_WRITE
               EXTERNAL  WASTELAND_PTR
;
               EXTERNAL  NOW_PHASE,NOW_CLICK,NOW_BAR,NOW_NUMERATOR,NOW_DENOMINATOR
               EXTERNAL  PHASE_LIST,PHASE_LEN,RAW_DENOMINATOR
               EXTERNAL  RECORDING,SYSEX_COMING,MET_COUNT,MET_COUNT_DOWN,RAW_MET
               EXTERNAL  SHOWING_FF_RW,SHOWING_TEMPO
               EXTERNAL  MISC_OUT_STAT,SINGLE_STEP
               EXTERNAL  METRO_TONE,NOW_MET_COUNT,XPORT_STATE
               EXTERNAL  CLICKS_PENDING,CLICKS_THIS_BAR
               EXTERNAL  REAL_TIME
               EXTERNAL  NEXT_TIME
               EXTERNAL  MA_SEQ_ADVANCE
               EXTERNAL  MB_SEQ_ADVANCE
               EXTERNAL  MA_XMIT_SEQ_TIME
               EXTERNAL  MB_XMIT_SEQ_TIME
               EXTERNAL  MA_XMIT_SEQ_GATE
               EXTERNAL  MB_XMIT_SEQ_GATE
               EXTERNAL  MA_TIME_BUFF
               EXTERNAL  MB_TIME_BUFF
               EXTERNAL  WROTE_NEW_TIME
               EXTERNAL  OVERALL_CLICK
               EXTERNAL  HOLDING_EVENT,NEXT_EVENT_TIME
               EXTERNAL  BG_TEMP_1_B,BG_TEMP_3_B,BG_TEMP_5_B
               EXTERNAL  TRACKS_MUTED,RECORD_LOOPING
               EXTERNAL  WASTELAND_DEPTH
               EXTERNAL  SEQ_WR_PTR,SEQ1_DRD_PTR,SEQ_NDRD_PTR
               EXTERNAL  BAR_OR_SMPTE_FLAG
               EXTERNAL  PUNCH_IN_BAR
               EXTERNAL  SMPTE_NOW_HR,SMPTE_P_I_HR
               EXTERNAL  ERASING
               EXTERNAL  PUNCH_OUT_BAR
               EXTERNAL  SMPTE_P_O_HR
               EXTERNAL  SEQ_XMIT_EVENT
               EXTERNAL  NOW_TRACK
               EXTERNAL  AUTORPT_FLAG
               EXTERNAL  INT_ERASE_MAP
               EXTERNAL  SUBFUN_INSTALL,CUR_SUB_BLOCK
               EXTERNAL  SEQ_MEM_FULL
               EXTERNAL  MUTE_OFF_TIMER
               EXTERNAL  READY_TO_RPT
               EXTERNAL  NOW_REPEATING
               EXTERNAL  RPT_START_BLK
               EXTERNAL  RPT_START_CNT
               EXTERNAL  RPT_START_PTR
               EXTERNAL  REPEAT_START
               EXTERNAL  REPEAT_END
               EXTERNAL  REPEAT_COUNT
               EXTERNAL  SEQ_WR_BLK
               EXTERNAL  SEQ_WR_CNT
               EXTERNAL  SEQ_NDRD_BLK
               EXTERNAL  SEQ_NDRD_CNT
               EXTERNAL  PENDING_MUTE
               EXTERNAL  RP_ST_CUR_TEMP,CUR_TEMPO_USEC
               EXTERNAL  RP_ST_CUR_T_8,CUR_T_BPM_8
               EXTERNAL  RP_ST_REF_TEMP,REF_TEMPO_USEC
               EXTERNAL  RP_ST_AR_B_LFT,ACCEL_RIT_B_LEFT
               EXTERNAL  RP_ST_AR_DELTA,ACCEL_RIT_DELTA
               EXTERNAL  RP_ST_AR_REM,ACCEL_RIT_REM
               EXTERNAL  RP_ST_MA_ADV
               EXTERNAL  RP_ST_MB_ADV
               EXTERNAL  PLAY_BLINK_TIMER
               EXTERNAL  SMPTE_SYNC,CLOCK_IN_MODE
;15MAY               EXTERNAL  CLICK_ASSIGN
               EXTERNAL  LAST_PHASE
               EXTERNAL  AC_TYPE
               EXTERNAL  CONTINUE_TIMER
               EXTERNAL  CHASING_SMPTE
               EXTERNAL  PLAYED_TO_END
               EXTERNAL  LED_EXTINGUISH
               EXTERNAL  USER_PUNCHED
               EXTERNAL  NOW_SEQ_STATUS
               EXTERNAL  NOW_LAST_BAR
;
               TITLE   "SEQUENCER REAL-TIME GESTALT"
;VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV
;
; BACKGROUND PROCESSING OF SEQUENCER CLOCKS -
; SEQUENCER CLOCK INTERRUPT HANDLER LEAVES A PROCESSING REQUEST FOR US
; BY INCREMENTING CLICKS_PENDING -
; WE BALANCE OUT BY DECREMENTING CLICKS_PENDING EACH TIME THROUGH -
; UNLESS CONDITIONS ARE SUCH THAT CLICK PROCESSING IS INHIBITED.
;
; SEQUENCE PLAYBACK OPERATES IN A ONE-CLICK PRE-FETCH MODE:
; EVENTS WHICH ARE SUPPOSED TO PLAY AT A CERTAIN POINT ARE PARSED FROM
; THE SEQUENCE ONE CLOCK IN ADVANCE.
; MIDI EVENTS ARE LOADED INTO BUFFERS TO AWAIT TRANSMISSION - INTERNAL
; SOUND EVENTS ARE PASSED TO VOICE HANDLER, WHICH BEGINS THE PROCESS OF
; VOICE-ASSIGNMENT AND SETUP FOR PLAY.
; BOTH PROCESS ARE GIVEN A TIMEOUT APPROXIMATING THE TIME AT WHICH NEXT
; SEQUENCER CLOCK IS PROJECTED TO HIT (OF COURSE, WE DON'T KNOW FOR
; CERTAIN) - OUR INTERNAL REAL-TIME INTERRUPT FIRES THEM OFF.
;
; IN GENERAL TERMS, WE:
;
;    *  FETCH SEQUENCE READ/WRITE POINTERS.
;
;    *  UPDATE METRONOME - MAKE IT GO "POP" IF THE TIME IS RIGHT,
;       AND DO IT NOWWW!!  BEFORE WE GET BOGGED DOWN IN THE FOLLOWING:
;
;    *  DO PUNCH-IN/PUNCH-OUT TESTS (IF BASED ON BAR/CLICK, NOT SMPTE).
;
;    *  FETCH AND EXECUTE THE CURRENT PHASE VECTOR - IT TAKES CARE OF
;       MERGING INTO THE SEQUENCE WRITE STREAM ANY NEW OR EXISTING EVENT
;       DATA WHICH HAS BEEN BUFFERED ELSEWHERE, IF THE TIME IS RIGHT.
;       IT THEN DICTATES WHERE VARIOUS TYPES OF NEW AND OLD EVENT DATA
;       IS TO BE STORED DURING THE FOLLOWING CLOCK PERIOD -
;       IN SHORT, PHASE VECTORS IMPLEMENT REALTIME AUTOCORRECT RECORD.
;       THEY ALSO ACTUATE AUTOREPEAT PLAY AT THE APPROPRIATE TIMES.
;       FINALLY, THE NEXT PHASE VECTOR IS CUED UP FOR EXECUTION AT THE
;       NEXT CLICK-PROCESSING TIME - THE VECTOR SEQUENCE IS DETERMINED
;       BY AN ARCANE COMBINATION OF TIME SIGNATURE, AUTOCORRECT SETTING,
;       SWING SETTING AND AUTOCORRECT SHIFT - THE WISDOM OF WHICH HAS
;       BEEN CODIFIED INTO MASSIVE TABLES IN THE MODULE "PHASES".
;
;    *  ADVANCE RUNNING CLICK COUNTS - SEE IF IT'S TIME TO PRE-FETCH.
;       IF TIME TO PRE-FETCH:
;       PARSE SEQUENCE DATA THROUGH NEXT TIME-MARKER OR BAR-MARKER,
;       SETTING UP MIDI NOTES TO BE TRANSMITTED AND INTERNAL VOICES TO
;       BE FIRED AT THE TIME PROJECTED FOR THE NEXT CLICK, AND HANDLING
;       OTHER TYPES OF EVENT (E.G., A-R MARK) AS APPROPRIATE.
;       NOTE THE TIME INDICATED BY THE NEXT TIMING EVENT AS THE TIME AT
;       WHICH NEXT PRE-FETCH SHOULD BE DONE (TIME IN SEQUENCER CLOCKS).
;       IF IT WAS A BAR MARKER:
;       TEST TO SEE IF WE'RE AT BEGINNING OF A PLAYBACK REPEAT LOOP, AND
;       IF SUCH LOOPING IS ENABLED - IF ALL GO (AND NOT ALREADY LOOPING)
;       CAPTURE ALL NECESSARY STATUS TO BE RESTORED WHEN LOOP END HIT.
;       ALTERNATIVELY, IF LOOP END REACHED, DETERMINE WHETHER TO ENTER
;       OR EXIT PLAYBACK REPEAT-LOOP MODE.
;       DOWNLOAD THE NEW TIME SIGNATURE AND ANY
;       PENDING EDITS OF AUTOCORRECT, SWING AND AUTOCORRECT SHIFT,
;       RESYNCHRONIZE THE METRONOME AND THE PHASE VECTOR SEQUENCE,
;       CLEAR THE RUNNING COUNT OF CLICKS INTO THE CURRENT BAR (USED
;       TO DETERMINE PRE-FETCH TIMES AND CREATE NEW TIME MARKERS).
;
;     * ON THE WAY OUT:
;       STASH SEQUENCE READ/WRITE POINTERS UNTIL NEXT CLICK-PROCESSING
;       SESSION (IN THE MEANTIME THEY MAY GET USED BY RECORD VECTORS).
;       UPDATE ANY ACCELERANDO/RITARDANDO CURRENTLY IN PROGRESS.
;       PLACE END-OF-CLICK MARKERS INTO MIDI BUFFERS FOR USE BY MIDI
;       TRANSMIT-INTERRRUPT HANDLERS (TELLS 'EM WHEN TO STOP, IN CASE
;       MIDI SEQUENCE DATA TRANSMISSION SOMEHOW GETS BACKLOGGED).
;       IF AT END OF SEQUENCE, DETERMINE WHETHER TO DO RECORD-LOOPING -
;       TAKE ANY APPROPRIATE ACTION.
;       USE FORECAST OF NEXT CLOCK TIME IN TERMS OF REAL-TIME INTERRUPTS
;       FROM RIGHT NOW (AS PROVIDED BY THE SEQUENCER CLOCK INTERRUPT
;       HANDLER) TO SET TIME AT WHICH REAL-TIME INTERRUPT WILL UNLEASH
;       TRANSMISSION OF MIDI EVENTS JUST PARSED FROM SEQUENCE INTO MIDI
;       BUFFERS (SIMILAR MECHANISM FOR INTERNAL VOICES IS WIRED DIRECTLY
;       INTO VOICE HANDLER FOR PLAYBACK OF SEQUENCE SOUND EVENTS).
;
; IT MUST BE POINTED OUT THAT IN ORDER TO GET AHEAD BY ONE CLOCK, WE
; MUST EXECUTE THE EQUIVALENT OF TWO CLICK-SERVICE CALLS UPON PROCESSING
; THE FIRST CLOCK OF A SEQUENCE.  THIS FIRST CLICK SERVICE SKIPS THE
; CLICK-COUNT ADVANCE AND PRE-FETCH TEST STEPS, AND WHEN DONE, RE-ENTERS
; NEAR THE TOP FOR A SECOND, "NORMAL" CLICK SERVICE.
;
;AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
               TITLE   "ENTRANCE, STATUS CHECKING - SHOULD I STAY OR SHOULD I GO?"
;VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV
;
; STICK IT IN, STICK IT OUT ....
;
PRO_CLICK
;
                                            ;CHECK FOR VARIOUS BLOCK/POSTPONE CONDITIONS:
;
               TST.B   XPORT_STATE          ;IS TRANSPORT ACTUALLY COMPLETELY DEAD?
               BEQ.S   CLEAR_CLKS_EXIT      ;IF YES, THIS CLOCK IS A MISTAKE - NAIL IT.
;
               TST.B   SHOWING_FF_RW        ;ARE WE AWAITING FAST-WIND TARGET CUE BAR?
               BNE.S   CLEAR_CLKS_EXIT      ;EXIT IF YES, FORGET ANY CLOCKS WHICH MAY COME IN -
                                            ;THEY'LL GET IN THE WAY OF FAST-WIND SCROLLING.
;
               TST.B   SYSEX_COMING         ;ARE WE BLOCKED BY A SYSTEM EXCLUSIVE BEING RECORDED?
               BNE.S   ACCUM_CLKS_EXIT      ;IF YES, WAIT UNTIL ALL IN - KEEP TRACK OF CLOCKS.
;
               TST.B   CHASING_SMPTE        ;ARE WE DOING HI-SPEED SMPTE CHASE AT THE MOMENT?
               BNE.S   CLEAR_CLKS_EXIT      ;IF YES, FORGET ALL CLOCKS RECEIVED BEFORE CAUGHT UP.
;
;11JUN               TST.B   CUEING_TO_SPP        ;ARE WE DOING HI-SPEED CUE TO MIDI SONG POINTER?
;11JUN               BNE.S   ACCUM_CLKS_EXIT      ;IF YES, TRACK ALL CLOCKS RECEIVED BEFORE WE GET CUED.
;         NO PROBLEM - THIS FLAG KEEPS US OUT OF PRO_CLICK ANYWAY,
;         ON THE BASIS OF HIGHER PRIORITY IN BACKGROUND EXECUTION.
;
               TST.B   PLAYED_TO_END        ;ARE WE PLAYED/CUED PAST END OF SEQUENCE OR SONG,
                                            ;AWAITING COMMAND TO START OR RE-CUE?  (MIDI/SMPTE)
               BNE.S   CLEAR_CLKS_EXIT      ;IF YES, FORGET ALL CLOCKS RECEIVED BEFORE WE RESTART.
;
               MOVE    CLOCK_IN_MODE,D0     ;SOME TESTS BASED ON CLOCK-IN MODE:
               CMP     #1,CLOCK_IN_MODE     ;ARE WE IN MTC SYNC MODE?
               BEQ.S   CHECK_SMPTE_SYNC     ;BRANCH IF YES, CHECK FOR SMPTE SYNC STATUS.
               CMP     #4,D0                ;ARE WE IN SMPTE SYNC MODE?
               BNE.S   GO_FOR_IT_DUDE       ;BRANCH IF NOT, SMPTE SYNC STATUS IS IRRELEVANT, AND -
                                            ;WE PASSED ALL OF THE TESTS!
CHECK_SMPTE_SYNC
               TST.B   SMPTE_SYNC           ;WE NEED SIMTY-SINK FOR THE CURRENT CLOCK-IN MODE -
               BNE.S   GO_FOR_IT_DUDE       ;RI-I-IGHT O-O-ON, DU-U-UDE, WE GOT IT!
                                            ;ELSE, FALL THROUGH TO CLEAR CLOCK COUNT AND EXIT.
;
;
CLEAR_CLKS_EXIT
               CLR     CLICKS_PENDING       ;WE DON'T CARE TO KEEP TRACK ....
;
ACCUM_CLKS_EXIT
               RTS
;
;
;
; ELSE, CONTINUE WITH DA CLICK...!
;
GO_FOR_IT_DUDE
               SUBQ    #1,CLICKS_PENDING    ;KNOCK ONE CLOCK OFF THE BLOCK, JOCK.
               BPL.S   FAR_OUT_DUDE         ;ACCENTUATE THE POSITIVE -
               CLR     CLICKS_PENDING       ;BANISH ANY NEGATIVE CLOCK COUNT.
;
FAR_OUT_DUDE
               BSR     MET_HANDLER          ;PUMP THE METRONOME ALONG.
;
               MOVE.L  SEQ_WR_PTR,A6        ;SET UP ADDRESS POINTERS FOR VARIOUS READ/WRITE SUBS
               MOVE.L  SEQ1_DRD_PTR,A5
               MOVE.L  SEQ_NDRD_PTR,A4
               MOVE    WASTELAND_PTR,A3
;
               TST     HOLDING_EVENT        ;ARE WE AT THE VERY BEGINNING OF THE SEQUENCE?
               BNE.S   EXEC_PHASE_VEC       ;IF NOT, BUSINESS AS USUAL -
;
                                            ;ELSE, FALL THROUGH:
                                            ;READ FIRST BAR-MARKER, HAND-EXECUTE
                                            ;A RECORDING PHASE SO AS TO COPY EVENTS HIT
                                            ;'FORE WE STARTED, AND TO COPY THE FIRST
                                            ;CLICK'S EVENTS TO THE PROPER PLACE.  THEN,
                                            ;JUMP STRAIGHT TO NORM_PREF_LOOP, PROCESS THE
                                            ;FIRST CLICK'S EVENTS, BOOT THEM OUT THE DOOR,
                                            ;AND START PRE-FETCHING THE NEXT CLICK.
;
;
;AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
               TITLE   "SPECIAL PATH FOR BEGINNING OF SEQUENCE"
;VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV
;
; PLAYING FIRST CLICK IN A SEQUENCE -
; WE FELL IN FROM ABOVE ......
;
               CMP     #1,NOW_BAR           ;IF WE ARE NOT ON BAR ONE (ie. FF, CUE, ETC.), DON'T
               BNE.S   NOT_HERE_DAD         ;BOTHER CHECKING FOR PLAYBACK LOOP START ON BAR 1.
;
                                            ;WE BE ON BAR 1, HEY -
;
               BSR     AUTO_BAR_PUNCH       ;PUNCH-IN RECORD/ERASE IF APPROPRIATE.
;
               CMP     #1,REPEAT_START           ;ARE WE SET TO START REPEAT LOOP ON BAR 1?
               BNE.S   NOT_HERE_DAD              ;BRANCH IF NOT -
               BTST    #ERASE_BIT,XPORT_STATE    ;YES, BUT ARE WE LOOKING AT ERASE MODE?
               BNE.S   NOT_HERE_DAD              ;BRANCH IF YES, CAN'T GO LOOPING IN SUCH A CASE.
               BTST    #RECORD_BIT,XPORT_STATE   ;SAME IS TRUE IF WE'RE LOOKING AT RECORD MODE.
               BNE.S   NOT_HERE_DAD
                                            ;ELSE - FREEZE-FRAME SEQUENCER STATUS AT THIS POINT,
               BSR     REPEAT_SNAPSHOT      ;SO THAT WE CAN RETURN TO IT FOR REPEATS -
                                            ;THIS PUTS US IN READY_TO_RPT STATE.
                                            ;AT THE RISK OF "REPEATING" MYSELF (SORRY!) - THE CALL
                                            ;TO REPEAT_SNAPSHOT MUST BE DONE BEFORE WE COPY ANY
                                            ;PART OF THE BAR-MARKER OVER TO WRITE BLOCK, SO THAT IT
                                            ;IS POSSIBLE TO SAVE THE ADDRESS AT WHICH IT WILL BE
                                            ;WRITTEN, AND REPEAT_REPLAY CAN FIND IT AGAIN LATER -
                                            ;AFTER COPY-OVER, WE CANNOT EASILY DETERMINE WHERE THE
                                            ;DAMN THING WENT.
;
NOT_HERE_DAD
               BSR     SEQ1_DSTR_READ       ;READ FIRST WORD - know IT IS A BAR MARKER.
               BSR     SEQ_WRITE            ;COPY IT OVER TO THE SEQUENCE WRITE BLOCK.
               SWAP    D7                   ;SWAP FIRST WORD OFF TO THE OTHER END.
               BSR     SEQ1_DSTR_READ       ;READ SECOND WORD (BAR NUMBER),
               BSR     SEQ_WRITE            ;COPY IT OVER LIKEWISE.
               ST      WROTE_NEW_TIME       ;TELL PHASE VECTORS WE'VE WRITTEN TIME FOR THIS CLICK.
;
               BSR     BAR_MARKER_HANDLER   ;PROCESS THE BAR MARKER - SET NOW_BAR, CLEAR NOW_CLICK,
                                            ;SET CLICKS_THIS_BAR AND OTHER TIME-SIGNATURE-RELATED
                                            ;STUFF, RE-SYNC PHASE VECTORS AND METRONOME COUNT.
;
               BSR     CHECK_FOR_A_R_MARK   ;A-R MARKER (IF ANY) IMMEDIATELY FOLLOWS BAR-MARKER:
                                            ;IF ONE IS THERE, COPY IT OVER AND START IT UP.
;
               MOVE    NOW_PHASE,D0         ;EXECUTE FIRST-CLICK PHASE VECTOR HERE - IT DETERMINES
                                            ;INITIAL VECTORS FOR WRITING OF OLD AND NEW SEQ DATA,
                                            ;AND WRITES ANY EVENTS ACCUMULATED IN THE PRE-RECORD
                                            ;BUFFER.
;
; -------------------------------------------------------------------
;
;05OCT               LSL     #2,D0                ;GET CORRECT STEP OUT OF TABLE
;05OCT               MOVE.L  PHASE_LIST,A0        ; (PHASE_LIST HOLDS ADDRESS OF CORRECT TABLE)
;05OCT               MOVE.L  0(A0,D0),A0          ;  A0 -> PHASE TO EXECUTE
;
; ***********  NOTE: PHASE VECTORS CHANGED FROM .L TO .W  ************
;
               ADD     D0,D0                ;CONVERT IT TO OFFSET INTO PHASE TABLE.
               MOVE.L  PHASE_LIST,A0        ;THIS IS A POINTER TO THE TABLE WE'RE CURRENTLY USING -
               MOVE    0(A0,D0),A0          ;FROM THAT TABLE, FETCH ADDRESS OF PHASE ROUTINE TO
                                            ;BE EXECUTED AT THIS POINT IN SEQUENCE.
;
; -------------------------------------------------------------------
;
               JSR     (A0)                 ;EXECUTE FIRST PHASE VECTOR.
;
;
               MOVE    OLD_SEQ_WRITE,A2     ;FETCH INITIAL WRITE VECTOR FOR EXISTING SEQ EVENTS.
;
               SF      RECORD_LOOPING       ;STARTING FRESH - KILL FLAG THAT SEZ WE WERE AT THE
                                            ; END OF RECORD LOOP (WHETHER IT WAS SET OR NOT - YOU
                                            ; THINK BOMBS ASK IF ANYONE'S ALIVE BEFORE EXPLODING?).
;
               BRA     NORM_PREF_LOOP       ;BAR-MARKER (AND A-R MARK, IF ANY) FULLY DISPATCHED -
                                            ;READY TO GO AHEAD AND START FETCHING CURRENT CLICK'S
                                            ;EVENTS - AND WE KNOW WE AREN'T IN REPEAT-LOOP MODE,
                                            ;SO USE THE "NORMAL" VERSION OF THIS.
;
;AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
               TITLE   "PHASE VECTOR EXECUTION AND SEQUENCING, CLICK-COUNT ADVANCE"
;VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV
;
; EXECUTE CURRENT PHASE VECTOR, THEN CUE UP THE NEXT ONE IN SEQUENCE -
; SEE IF WE SHOULD DO (BAR/CLICK-BASED) AUTO-PUNCH-IN/OUT AT THIS POINT.
; WHILE WE'RE AT IT, ADVANCE TIMING CHAIN.
; FOR MORE DETAIL, REFER TO DOCUMENTATION AT START OF FILE.
;
; NOTE - RE-ENTER PRO_CLICK HERE FOR SECOND PART OF
; DOUBLE CLICK-SERVICE AT BEGINNING OF SEQUENCE:
;
EXEC_PHASE_VEC
               MOVE    NOW_PHASE,D0         ;FETCH CURRENT STEP IN PHASE SEQUENCE -
;
; -------------------------------------------------------------------
;
;30SEP               LSL     #2,D0                ;CONVERT IT TO OFFSET INTO PHASE TABLE.
;30SEP               MOVE.L  PHASE_LIST,A0        ;THIS IS A POINTER TO THE TABLE WE'RE CURRENTLY USING -
;30SEP               MOVE.L  0(A0,D0),A0          ;FROM THAT TABLE, FETCH ADDRESS OF PHASE ROUTINE TO
;30SEP                                            ;BE EXECUTED AT THIS POINT IN SEQUENCE.
;30SEP;
;30SEP               LSR     #2,D0                ;PUT STEP NUMBER BACK TOGETHER,
;
; ***********  NOTE: PHASE VECTORS CHANGED FROM .L TO .W  ************
;
               ADD     D0,D0                ;CONVERT IT TO OFFSET INTO PHASE TABLE.
               MOVE.L  PHASE_LIST,A0        ;THIS IS A POINTER TO THE TABLE WE'RE CURRENTLY USING -
               MOVE    0(A0,D0),A0          ;FROM THAT TABLE, FETCH ADDRESS OF PHASE ROUTINE TO
                                            ;BE EXECUTED AT THIS POINT IN SEQUENCE.
;
               LSR     #1,D0                ;PUT STEP NUMBER BACK TOGETHER,
;
; -------------------------------------------------------------------
;
               ADDQ    #1,D0                ;STEP IT UP BY ONE -
               CMP     PHASE_LEN,D0         ;BEYOND THE NUMBER OF STEPS IN CURRENT PHASE TABLE?
               BNE.S   EXEC_PHS_20          ;BRANCH IF NOT, WE'RE COOL -
               CLR     D0                   ;ELSE, WRAP BACK TO BEGINNING OF TABLE.
EXEC_PHS_20
               MOVE    D0,NOW_PHASE         ;SAVE NEW STEP NUMBER,
               JSR     (A0)                 ;EXECUTE PHASE ROUTINE WHOSE ADDRESS WE OBTAINED ABOVE.
;
;
                                            ;BEFORE WE KISS THIS CLICK GOODBYE .... PUNCH-IN/OUT?
               TST.B   NOW_REPEATING        ;ARE WE IN NON-DESTRUCTIVE LOOP PLAYBACK MODE?
               BNE.S   EXEC_PHS_40          ;BRANCH IF YES, DON'T BOTHER WITH PUNCH-IN/OUT TESTS -
               BSR     AUTO_BAR_PUNCH       ;ELSE - GO CHECK IT OUT, ACT IF NECESSARY.
EXEC_PHS_40
;
;
               ADDQ    #1,NOW_CLICK         ;INCREMENT THE CLICK-WITHIN-CURRENT BAR VALUE.
                                            ;(REMINDER - THIS IS THE L.S.WORD OF NOW_BAR.L)
               ADDQ.L  #1,OVERALL_CLICK     ;INCREMENT THE CLICKS-FROM-START-OF-PLAY VALUE.
;
                                            ;NOTE - THESE NEW CLICK VALUES CORRESPOND TO
                                            ;THE CLICK WE ARE ABOUT TO PRE-FETCH.
;
;
; FALL THROUGH INTO PRE-FETCH PROCEDURE ....
;
;
;AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
               TITLE   "TEST FOR / INITIATION OF CURRENT-CLICK PRE-FETCH"
;VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV
;
; SEE WHETHER NOW IS THE TIME TO EXECUTE A PRE-FETCH LOOP:
; IT'S TIME, IF NOW_CLICK (WHICH SAYS HOW FAR TIME HAS ADVANCED IN THE
; CURRENT BAR) IS EQUAL TO (OR GREATER THAN!) NEXT_EVENT_TIME, WHICH IS
; THE BAR-RELATIVE CLOCK VALUE OF THE LAST TIME MARKER OR BAR MARKER
; AT WHICH WE STOPPED PARSING DURING THE LAST PRE-FETCH LOOP.
; IF NOT - SKIP OVER THE PRE-FETCH LOOP STUFF, GO ON TO THE PER-CLICK
; MAINTENANCE STUFF WHICH WE ALWAYS DO, PRE-FETCH OR NO.
;
; LET ME SEE IF I CAN ACTUALLY MAKE THIS COMPREHENSIBLE .... BY THE TIME
; WE GET HERE, WE'VE ALREADY PASSED THROUGH EXEC_PHASE_VEC, WHEREIN THE
; CURRENT NOW_CLICK VALUE GETS INCREMENTED, MEANING THAT THE VALUE OF
; NOW_CLICK AT THIS POINT IS ONE CLOCK BEYOND THE VALUE WHICH REALLY
; CORRESPONDS TO ACTUAL "NOW".  THIS IS THE BASIS OF PRE-FETCH.  IF WE
; DO A PRE-FETCH LOOP "NOW", THE SOUND AND MIDI EVENTS WHICH WE PARSE
; WILL BE TIMED TO OCCUR ONE CLOCK FROM "NOW" - THAT IS, AT THE ACTUAL
; TIME TO WHICH THE PRESENT NOW_CLICK VALUE CORRESPONDS.
;
; FULL IMPLICATIONS:  RIGHT "NOW", EVEN WHILE WE ARE IN MID-PRE-FETCH,
; THE REALTIME AND MIDI INTERRUPTS MAY BE STEPPING IN AND PLAYING SOUNDS
; OR TRANSMITTING MIDI NOTES - IF SO, THESE EVENTS WERE PRE-FETCHED ON
; THE LAST PASS THROUGH PRO_CLICK (NOMINALLY ONE CLOCK BEFORE "NOW").
; AND, ONE CLOCK FROM "NOW", WHILE THE EVENTS (IF ANY) PRE-FETCHED "NOW"
; ARE BEING PUMPED OUT, WE WILL BE MAKING A SIMILAR "TO BE OR NOT TO BE"
; DECISION ABOUT THE CLOCK TWO CLOCKS FROM "NOW".
;
; OTHER IMPORTANT DETAILS:  PRE-FETCH ALWAYS RUNS UNTIL THE NEXT TIME OR
; BAR MARKER IS ENCOUNTERED - ALL EVENTS PARSED BEFORE THAT POINT ARE
; CONSIDERED TO OCCUR AT THE TIME OF THE BAR OR TIME MARKER WHICH THEY
; FOLLOW.  THE LAST WORD READ DURING A PRE-FETCH LOOP (EITHER THE NEXT
; TIME MARKER IN ITS ENTIRETY, OR THE FIRST WORD OF THE NEXT BAR MARKER)
; IS PLACED ASIDE IN HOLDING_EVENT.  AT THE NEXT PRE-FETCH TIME, IT IS
; USED TO DETERMINE WHICH OF THE TWO TYPES OF MARKER WAS READ, AND
; WHETHER ANOTHER WORD NEEDS TO BE READ TO COMPLETE THE MARKER READ.
; IN ADDITION, IT DETERMINES WHETHER LOOPING TESTS AND BRANCHES WILL BE
; MADE, SINCE SEQUENCE LOOPING IS DONE AT BAR BOUNDARIES (THAT'S MAINLY
; WHAT WE DEAL WITH HERE, IN FACT).  FINALLY, IF THE SEQUENCER IS
; STOPPED, HOLDING_EVENT IS USED TO DETERMINE WHETHER SEQUENCE PARSING
; WAS EVER ACTUALLY BEGUN, AND IF SO, WHAT FURTHER READS MUST BE DONE
; IN ORDER TO PUT THE SEQUENCE BACK TOGETHER.
;
; NEW TIME MARKERS MUST BE CREATED AND INSERTED INTO THE SEQUENCE AHEAD
; OF NEWLY-RECORDED EVENTS, BUT ONLY IF NO TIME MARKER WAS ALREADY
; PRESENT FOR THAT POINT IN THE SEQUENCE.  HENCE, WROTE_NEW_TIME IS
; CLEARED AT THE START OF EACH CLOCK SERVICE.  IF PRE-FETCH IS DONE,
; THIS FLAG IS IMMEDIATELY SET TO INDICATE THAT NO NEW MARKER NEED BE
; CREATED IF ANY NEW EVENTS ARE RECORDED DURING THE CURRENT CLOCK.
; ELSE, THE FLAG REMAINS CLEAR, INDICATING THAT IF NEW EVENTS ARE
; RECORDED, A TIME MARKER MUST BE CREATED FOR THEM IN THE SEQUENCE.
;
; THERE ARE TWO MODES OF SEQUENCE PARSING:  NORMAL (DESTRUCTIVE) MODE
; WHICH ALLOWS RECORDING/ERASING AND RANDOM PUNCH-IN, AND PLAYBACK-ONLY
; (NON-DESTRUCTIVE) REPEAT LOOPING, WHICH ALLOWS NO DATA MODIFICATION
; BUT PERMITS ARBITRARY SECTIONS OF THE SEQUENCE TO BE PLAYBACK-LOOPED.
; IF WE DECIDE TO DO PRE-FETCH, WE MUST ALSO DETERMINE WHICH FORM OF
; PRE-FETCH WE SHOULD BE DOING, AND ENTER THE APPROPRIATE LOOP.
;
; FINALLY - A SORT OF ARBITRARY RULE SAYS THAT ACCELERANDO/RITARDANDO
; MARKERS, IF PRESENT, MUST IMMEDIATELY FOLLOW BAR MARKERS WITH NO OTHER
; EVENTS IN BETWEEN.  SO, NATURALLY ENOUGH, IF WE DO PRE-FETCH STARTING
; FROM A BAR-MARKER, WE CHECK FOR AND HANDLE A-R MARKERS BEFORE WE JUMP
; INTO THE ACTUAL PRE-FETCH LOOP.
;
PRE_FETCH_CHECK
               SF      WROTE_NEW_TIME       ;STARTING A NEW CLICK - NO TIME/BAR-MARK WRITTEN YET.
               SF      PROCESSED_TAP        ;LIKEWISE, NO TAP-TEMPO EVENT SEEN YET ON THIS CLICK.
;
               MOVE    NOW_CLICK,D0         ;IS IT ACTUALLY TIME FOR US TO PRE-FETCH YET?
               CMP     NEXT_EVENT_TIME,D0
               BCS     END_OF_CLICK         ;BRANCH IF NOT, HEAD FOR END-OF-CLICK CUSTODIAL SHIT -
                                            ;BUT JUST FOR THE HELL OF IT, IF SOMETHING FUCKED UP
                                            ;AND WE SOMEHOW MANAGED TO MISS OUR PRE-FETCH TIME,
                                            ;LET'S GET A MOVE ON (OTHERWISE WE'LL JUST SIT HERE
                                            ;COUNTING BEATS FOREVER, WAITING FOR A TIME THAT'LL
                                            ;NEVER COME AGAIN ....)
                                            ;IN REALITY, THIS SHOULD SET OFF SOME KIND OF ALARM -
                                            ;IT'S A SERIOUS ERROR CONDITION.
;
;
;
; TIME FOR ANOTHER ROUND OF PRE-FETCH:
;
               MOVE    HOLDING_EVENT,D7     ;RETRIEVE WORD AT WHICH PRE-FETCH ENDED LAST TIME.
               MOVE    D7,D0                ;ISOLATE ITS TYPE - BAR- OR TIME-MARKER - IN D0.
               AND     #0FH,D0
;
               TST.B   NOW_REPEATING        ;ARE WE IN NON-DESTRUCTIVE LOOP PLAYBACK MODE?
               BNE     RPT_PREF_START       ;BRANCH IF YES - THAT'S A DIFFERENT SCENE ....
;
;
;
; WE'RE DOING NORMAL (DESTRUCTIVE READ/WRITE) PLAYBACK:
;
               MOVE    OLD_SEQ_WRITE,A2     ;SET UP VECTOR FOR WRITING "OLD" SEQUENCE EVENTS PARSED
                                            ;FROM THE SEQUENCE DURING THIS PRE-FETCH.
;
               CMP     #8,D0                ;HAVE WE GOT A BAR-MARKER HERE?
               BEQ.S   NORM_BAR_MARK        ;BRANCH IF YES, GOT SOME THINGS TO DO WITH IT.
;
               JSR     (A2)                 ;ELSE, TIME-MARKER - JUST COPY IT TO NEW WRITE BLOCK.
               ST      WROTE_NEW_TIME       ;TELL 'EM THAT A TIME EVENT WAS WRITTEN FOR THIS CLICK,
                                            ;SO PHASE VECTORS WON'T WRITE ANOTHER ON SAME CLICK.
               BRA.S   NORM_PREF_LOOP       ;GO PRE-FETCH THE EVENTS WHICH FOLLOW IT.
;
NORM_BAR_MARK
               SWAP    D7                   ;DAS IST BAR MARKER - SWAP FIRST WORD OUT OF THE WAY,
               BSR     SEQ1_DSTR_READ       ;FETCH SECOND (BAR NUMBER) -
               TST     REPEAT_COUNT         ;IS PLAYBACK LOOP ENABLED (VIA NON-ZERO REPEAT COUNT)?
               BEQ.S   NOT_THE_LOOP         ;BRANCH IF REPEAT_COUNT = 0, NO GONNA LOOP.
               MOVE.B  XPORT_STATE,D0       ;IS "ERASE" OR "RECORD" ENABLED?
               AND.B   #RECORD_MASK+ERASE_MASK,D0
               BNE.S   NOT_THE_LOOP         ;BRANCH IF EITHER ENABLED, WE REFUSE TO PLAYBACK-LOOP.
               TST.B   USER_PUNCHED         ;ARE WE IN MANUAL PUNCH-IN MODE (USER MAY AT ANY TIME)?
               BNE.S   NOT_THE_LOOP         ;BRANCH IF YES, LIKEWISE KEEP THINGS OPEN FOR PUNCH-IN.
;
                                            ;IF NONE OF THE ABOVE ....
               TST.B   READY_TO_RPT         ;CONDITION GREEN, HAVE WE PASSED LOOP START POINT?
               BNE.S   SEEK_LOOP_END        ;BRANCH IF YES, WE SEEK THE END OF THE REPEAT LOOP.
               CMP     REPEAT_START,D7      ;SO - IS THIS BAR THE REPEAT LOOP START POINT?
               BNE.S   NOT_THE_LOOP         ;BRANCH IF NOT, KEEP ON IN THIS DESTRUCTIVE FASHION.
               BSR     REPEAT_SNAPSHOT      ;ELSE, DO A SEQUENCER STATUS FREEZE-FRAME AT THIS POINT
                                            ;'CAUSE WE'LL BE COMING BACK HERE WHEN WE HIT LOOP END.
                                            ;AT THE RISK OF "REPEATING" MYSELF (SORRY!) - THE CALL
                                            ;TO REPEAT_SNAPSHOT MUST BE DONE BEFORE WE COPY ANY
                                            ;PART OF THE BAR-MARKER OVER TO WRITE BLOCK, SO THAT IT
                                            ;IS POSSIBLE TO SAVE THE ADDRESS AT WHICH IT WILL BE
                                            ;WRITTEN, AND REPEAT_REPLAY CAN FIND IT AGAIN LATER -
                                            ;AFTER COPY-OVER, WE CANNOT EASILY DETERMINE WHERE THE
                                            ;DAMN THING WENT.
               BRA.S   NOT_THE_LOOP         ;NOW WE'RE READY_TO_RPT, BUT STILL DESTRUCTIVE - GO ON.
;
SEEK_LOOP_END
               SWAP    D7                   ;COPY THE BAR MARKER OVER TO SEQUENCE WRITE BLOCK -
               JSR     (A2)                 ;IF IT MARKS OUR LOOP END, WE'LL NEED IT TO BE THERE.
               SWAP    D7
               JSR     (A2)
                                            ;NOW, A SIMPLE TEST TO SEE WHETHER WE WILL NEED TO USE
                                            ;NON-DESTRUCTIVE PLAYBACK MODE WHEN WE START LOOPING:
               CMP     #1,REPEAT_START      ;SINCE WE'RE HERE, WE MUST BE ENABLED TO REPEAT-LOOP -
               BNE.S   SEEK_END_10          ;BRANCH IF LOOP START NOT AT BAR 1 - WE NEED NON-DESTR.
               MOVE    NOW_LAST_BAR,D0      ;LOOP STARTS AT BAR 1 - DOES IT END AT LAST BAR OF SEQ?
               CMP     REPEAT_END,D0        ;WE MUST ASSUME SO, IF REPEAT_END > NOW_LAST_BAR -
               BCS.S   LOOP_EXIT_POINT      ;BRANCH IF SO - IF WE'RE GONNA LOOP THE ENTIRE SEQUENCE
                                            ;ANYWAY, WE WON'T NEED TO USE NON-DESTRUCTIVE PLAYBACK
                                            ;MODE - BY AVOIDING IT, WE LEAVE THE DOOR OPEN FOR USER
                                            ;TO PUNCH IN AT ANY TIME (SEQ_END_HANDLER IN TRANSPORT
                                            ;WILL PICK UP THE BALL FOR US AT END OF THE SEQUENCE,
                                            ;SINCE WE WILL NOT HAVE THE PRIVELEGE OF HANDLING THE
                                            ;END-OF-SEQUENCE MARK OURSELVES ....)
;
SEEK_END_10
                                            ;NOT LOOPING ENTIRE SEQUENCE, WILL NEED NON-DESTR MODE:
               CMP     REPEAT_END,D7        ;SO - WAS THIS THE REPEAT LOOP END BAR?
               BEQ     RPT_LOOP_START       ;BRANCH IF YES, OFF WE GO INTO NON-DESTRUCTIVE-LAND.
               BRA.S   LOOP_EXIT_POINT      ;ELSE WE ARE STILL IN THE DESTRUCTIVE WAY.
;
;
NOT_THE_LOOP
               SWAP    D7                   ;COPY THE BAR MARKER OVER TO SEQUENCE WRITE BLOCK -
               JSR     (A2)                 ;BEING AS HOW WE'RE NOT GOING INTO SOME WEIRD MODE NOW.
               SWAP    D7
               JSR     (A2)
;
;
;
; THIS IS WHERE WE COME WHEN MAKING THE TRANSITION FROM REPEAT-LOOP
; TO "NORMAL" PLAYBACK MODE:
;
LOOP_EXIT_POINT
               BSR     BAR_MARKER_HANDLER   ;PROCESS THE BAR MARKER - SET NOW_BAR, CLEAR NOW_CLICK,
                                            ;SET CLICKS_THIS_BAR AND OTHER TIME-SIGNATURE-RELATED
                                            ;STUFF, RE-SYNC PHASE VECTORS AND METRONOME COUNT.
               ST      WROTE_NEW_TIME       ;TELL 'EM THAT A TIME EVENT WAS WRITTEN FOR THIS CLICK,
                                            ;SO PHASE VECTORS WON'T WRITE ANOTHER ON SAME CLICK.
               BSR     CHECK_FOR_A_R_MARK   ;A-R MARKER (IF ANY) IMMEDIATELY FOLLOWS BAR-MARKER:
                                            ;IF ONE IS THERE, COPY IT OVER AND START IT UP.
;
; NOW FALL THRU INTO NORM_PREF_LOOP,
; GO PRE-FETCH THIS CLICK'S EVENTS.
;
;AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
               TITLE   "EVENT PRE-FETCH LOOP FOR NORMAL (NON-REPEAT-LOOP) PLAYBACK"
;VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV
;
; LOOP TO PRE-FETCH THE CURRENT CLICK'S EVENTS, "NORMAL" STYLE:
; TIME-MARKER OR BAR-MARKER WHICH PRECEDS THEM HAS ALREADY BEEN HANDLED.
; WE BRANCH TO END_OF_CLICK UPON HITTING THE NEXT TIME-MARKER,
; BAR-MARKER, OR END-OF-SEQUENCE MARKER.
;
NORM_PREF_LOOP
               BSR     SEQ1_DSTR_READ       ;GET NEXT WORD
               MOVE    D7,D0                ; ISOLATE TYPE ID
               AND     #0FH,D0
               LSL     #2,D0                ;  TURN INTO A TABLE OFFSET
               JMP     NORM_BRA_TBL(PC,D0)  ;   HANDLE ACCORDING TO TYPE
;
NORM_BRA_TBL
               BRA.W   NORM_PREF_LOOP       ;TYPE 0 - deleted event - lose
               BRA.W   PAD_ON               ; "   1 - PAD GOING ON
               BRA.W   PAD_OFF              ; "   2 -  "    "   OFF
               BRA.W   MIDI_ON              ; "   3 - MIDI NOTE ON
               BRA.W   MIDI_OFF             ; "   4 -  "    "   OFF
               BRA.W   OTHER_MIDI           ; "   5 - OTHER MIDI EVENT
               BRA.W   MIDI_SYSEX           ; "   6 - MIDI SYSTEM EXCLUSIVE
               BRA.W   NORM_PREF_LOOP       ; "   7 - undefined
               BRA.W   NEW_BAR_MARK         ; "   8 - BAR MARKER
               BRA.W   NEW_TIME_MARK        ; "   9 - TIME MARKER
               BRA.W   NEW_TAP_TIME         ; "  10 - TAP TIME OFFSET
               BRA.W   NORM_PREF_LOOP       ; "  11 - A/R MARKER (HANDLED ALONG WITH BAR-MARKER)
               BRA.W   NEW_UART_TIMING      ; "  12 - UART ADVANCE/DELAY
               BRA.W   NORM_PREF_LOOP       ; "  13 - undefined
               BRA.W   NORM_PREF_LOOP       ; "  14 - undefined
               BRA.W   END_OF_SEQUENCE      ; "  15 - END_OF_SEQUENCE MARKER
;
;AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
               TITLE   "INITIATION OF CURRENT-CLICK PRE-FETCH FOR REPEAT-LOOP PLAYBACK"
;VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV
;
; START PRE-FETCH OF THE CURRENT CLICK'S EVENTS, REPEAT-LOOP STYLE:
; WE COME HERE WITH TIME-MARKER OR FIRST WORD OF BAR-MARKER IN D7
; (OBTAINED FROM HOLDING_EVENT), AND MARKER TYPE ID ISOLATED IN D0.
;
RPT_PREF_START
                                            ;WE'RE IN NON-DESTRUCTIVE LOOP PLAYBACK MODE:
               CMP     #9,D0                ;HAVE WE GOT A TIME MARKER HERE?
               BEQ.S   RPT_PREF_LOOP        ;YES - JUST PRE-FETCH NEXT CLICK.
;
                                            ;ELSE, GOT A BAR MARKER (OR MAYBE A BAR MITZVAH?) -
               SWAP    D7                   ;SWAP FIRST WORD OUT OF THE WAY,
               BSR     SEQ_NDSTR_READ       ;GET 2nd WORD OF MARKER - IT'S THE BAR NUMBER.
               CMP     REPEAT_END,D7        ;HAVE WE HIT THE END OF THE LOOP?
               BNE.S   NOT_NOW_DAD          ;BRANCH IF NOT - KEEP ON IN SAME DIRECTION.
               TST     REPEAT_COUNT         ;YES - ARE WE DOING INFINITE REPEAT?
               BMI.S   RPT_LOOP_AGAIN       ;YOU BET WE ARE, SO LOOP AND LEAVE REPEAT_COUNT ALONE.
               SUBQ    #1,REPEAT_COUNT      ;NO - THIS COULD BE THE LAST TIME ....
               BGT.S   RPT_LOOP_AGAIN       ;WELL, IT'S NOT THE LAST TIME - LOOP AGAIN.
               SF      READY_TO_RPT         ;LAST TIME - KILL LOOPING FLAGS,
               SF      NOW_REPEATING
               MOVE    OLD_SEQ_WRITE,A2     ;SET UP VECTOR FOR WRITING "OLD" SEQUENCE EVENTS PARSED
                                            ;FROM THE SEQUENCE DURING THIS PRE-FETCH.
               BRA     LOOP_EXIT_POINT      ;PASS BACK INTO DESTRUCTIVE PLAYBACK AT THIS POINT.
;
RPT_LOOP_AGAIN
               BSR     PLAY_LED_OFF                   ;RESTART OF REPEAT LOOP, NOT THE FIRST TIME:
               MOVE    REAL_TIME,PLAY_BLINK_TIMER     ;BLINK THE "PLAY" LED OFF TO SHOW THIS.
               BSET    #0,PLAY_BLINK_TIMER+1          ;BACKGROUND WILL TURN IT BACK ON SOON.
;
;
;
; THIS IS WHERE WE COME IN WHEN MAKING THE TRANSITION FROM "NORMAL" TO
; REPEAT-LOOP PLAYBACK MODE:
;
RPT_LOOP_START
               BSR     REPEAT_REPLAY        ;LOOPING AGAIN - REINSTATE LOOP-START SEQUENCER STATE.
NOT_NOW_DAD
               BSR     BAR_MARKER_HANDLER   ;DECODE, FINISH BAR CHORES.
;
; FALL THROUGH INTO RPT_PREF_LOOP, PRE-FETCH INFO FOLLOWING THIS MARKER.
;
;AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
               TITLE   "EVENT PRE-FETCH LOOP FOR REPEAT-LOOP PLAYBACK"
;VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV
;
; LOOP TO PRE-FETCH THE CURRENT CLICK'S EVENTS, REPEAT-LOOP STYLE:
; TIME-MARKER OR BAR-MARKER WHICH PRECEDS THEM HAS ALREADY BEEN HANDLED.
; WE BRANCH TO END_OF_CLICK UPON HITTING THE NEXT TIME-MARKER,
; BAR-MARKER, OR END-OF-SEQUENCE MARKER - JUST LIKE WE DO IN "NORMAL"
; PLAYBACK, HENCE WE SHARE "NORMAL" PARSING ROUTINES FOR THESE EVENTS.
;
RPT_PREF_LOOP
               BSR     SEQ_NDSTR_READ       ;GET NEXT WORD INTO D7,
               MOVE    D7,D0                ;ISOLATE TYPE ID IN D0.
               AND     #0FH,D0
               LSL     #2,D0                ;TURN INTO A TABLE OFFSET,
               JMP     RPT_BRA_TBL(PC,D0)   ;HANDLE ACCORDING TO TYPE.
;
RPT_BRA_TBL
               BRA.W   RPT_PREF_LOOP        ;TYPE 0 - deleted event - lose
               BRA.W   RPT_PAD_ON           ; "   1 - PAD GOING ON
               BRA.W   RPT_PAD_OFF          ; "   2 -  "    "   OFF
               BRA.W   RPT_MIDI_ON          ; "   3 - MIDI NOTE ON
               BRA.W   RPT_MIDI_OFF         ; "   4 -  "    "   OFF
               BRA.W   RPT_OTHER_MIDI       ; "   5 - OTHER MIDI EVENT
               BRA.W   RPT_MIDI_SYSEX       ; "   6 - MIDI SYSTEM EXCLUSIVE
               BRA.W   RPT_PREF_LOOP        ; "   7 - undefined
               BRA.W   NEW_BAR_MARK         ; "   8 - BAR MARKER
               BRA.W   NEW_TIME_MARK        ; "   9 - TIME MARKER
               BRA.W   RPT_NEW_TAP_TIME     ; "  10 - TAP TIME OFFSET
               BRA.W   RPT_NEW_A_R_MARK     ; "  11 - A/R MARKER
               BRA.W   RPT_NEW_UART_TIMING  ; "  12 - UART ADVANCE/DELAY
               BRA.W   RPT_PREF_LOOP        ; "  13 - undefined
               BRA.W   RPT_PREF_LOOP        ; "  14 - undefined
               BRA.W   END_OF_SEQUENCE      ; "  15 - END_OF_SEQUENCE MARKER
;
;AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
               TITLE   "INDIVIDUAL EVENT PRE-FETCH ACTIONS, \"NORMAL\" PLAYBACK"
;VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV
;
;             VARIOUS SEQUENCE DATA UNPACKING ROUTINES. TAKE FIRST WORD IN D7, TYPE ID IN D0, AND
;              WHERE TO WRITE IT TO IN A2.  TAKE APROPOS ACTION (SEND OVER MIDI, WRITE, CHANGE TEMPO,
;              ETC.).  ALSO HANDLE TRACK MUTING HEREIN - MEANS WRITING, BUT NOT SENDING OVER MIDI,
;              IF AN EVENT'S TRACK HAS BEEN MUTED.
;
;             HERE'S WHAT EACH EVENT LOOKS LIKE:
;
;             TYPE 0 - undefined - ignore
;
;             TYPE 1 - PAD ON
;              aaa bbbbb c ddd 0001    aaa = PADNUM, bbbbb = SOUNDNUM, c = ALT PARAM, ddd = TRACKNUM
;              0 eeeee fffff ggggg     eeeee = PITCH, fffff = PAN, ggggg = VELOCITY
;              00000000000 hhhhh       hhhhh = LEVEL
;
;             TYPE 2 - PAD OFF
;              aaa bbbbb c ddd 0010    aaa = PADNUM, bbbbb = SOUNDNUM, c = ALT PARAM, ddd = TRACKNUM
;              0 eeeee fffff ggggg     eeeee = PITCH, fffff = PAN, ggggg = VELOCITY (OF NOTE ON)
;
;             TYPE 3 - MIDI NOTE ON
;              1001 aaaa b ccc 0011    aaaa = CHANNEL, b = UART, ccc = TRACKNUM
;              0 ddddddd 0 eeeeeee     ddddddd = KEYNUM, eeeeeee = VELOCITY
;
;             TYPE 4a - MIDI NOTE OFF
;              1001 aaaa b ccc 0100    aaaa = CHANNEL, b = UART, ccc = TRACKNUM
;              0 ddddddd 00000000      ddddddd = KEYNUM
;
;             TYPE 4b - MIDI NOTE OFF
;              1000 aaaa b ccc 0100    aaaa = CHANNEL, b = UART, ccc = TRACKNUM
;              0 ddddddd 0 eeeeeee     ddddddd = KEYNUM, eeeeeee = VELOCITY
;
;             TYPE 5a - OTHER MIDI
;              aaaa bbbb c ddd 0101    aaaa = STAT BYTE, bbbb = CHANNEL, c = UART, ddd = TRACKNUM
;              0 eeeeeee 0 fffffff     eeeeeee = DATA BYTE #1, fffffff = DATA BYTE # 2
;
;             TYPE 5b - MIDI SYSTEM
;              1111 aaaa b ccc 0101    aaaa = CHANNEL, b = UART, ccc = TRACKNUM
;              0 ddddddd 0 eeeeeee     ddddddd = DATA BYTE #1, eeeeeee = DATA BYTE # 2
;
;             TYPE 6 - MIDI SYSTEM EXCLUSIVE
;              11110000 a bbb 0110     a = UART, bbb = TRACKNUM
;             (0 ccccccc 0 ddddddd)    ccccccc, ddddddd = DATA BYTES x as many as needed
;              0 cdcdcdc 11110111
;
;             TYPE 7 - undefined
;
;             TYPE 8 - BAR MARKER
;              aaaaaaaa 0 bbb 1000     aaaaaaaa = TIME SIG NUMERATOR, bbb = 'RAW' TIME SIG DENOMINATOR
;              cccccccccccccccc        cccccccccccccccc = BAR NUMBER
;
;             TYPE 9 - TIME MARKER
;              aaaaaaaaaaaa 1001       aaaaaaaaaaaa = CLICK NUMBER IN THIS BAR
;
;             TYPE 10 - TAP TIME OFFSET
;              a bbbbbbbbbbb 1010      a = SIGN OF TEMPO OFFSET, bbbbbbbbbbb = REFERNCE TEMPO (BPM*10-40)
;              cccccccccccccccc        cccccccccccccccc = DELTA AGAINST REF TEMPO (IN usec/CLICK)
;
;             TYPE 11 - A/R MARKER
;              00 aaaaaaaaaa 1011      aaaaaaaaaa = # BEATS IT EXTENDS OVER
;              bbbbbbbbbbbbbbbb        bbbbbbbbbbbbbbbb = CHANGE IN BPM*10 (SIGN-EXTENDED)
;
;             TYPE 12 - UART TIMING ADVANCE/DELAY
;              a bbbbb c ddddd 1100     a = 1 = NO CHANGE ON A; bbbbb = +/- msec CHANGE ON UART A
;                                       c = 1 = NO CHANGE ON B; ddddd = +/- msec CHANGE ON UART B
;
;             TYPE 13 - undefinded
;
;             TYPE 14 - undefinded
;
;             TYPE 15 - END OF SEQUENCE
;              0000000000001111
;
;;;;;;;;;;
PAD_ON
               MOVE    D7,BG_TEMP_1_B       ;SAVE FOR UNPACKING & XMITTING OVER MIDI
               TST.B   ERASING              ;ARE WE IN LIVE-ERASE MODE?
               BEQ.S   PAD_ON_NO_ERASE      ;BRANCH IF NOT, CONTINUE.
               BSR.S   INT_ERASE_TEST       ;ERASING - HOW'S ABOUT THIS EVENT?
               BNE.S   ERASE_HIM_FELLA      ;BRANCH IF THIS ONE SHOULD BE ZORCHED.
;
PAD_ON_NO_ERASE
               SWAP    D7                   ; HIDE AWAY UPPER WORD
               BSR     SEQ1_DSTR_READ       ;  GET MIDDLE WORD
               MOVE    D7,BG_TEMP_3_B       ;   ALSO SAVE FOR UNPACKING & XMITTING OVER MIDI
                ABS_LONG
               JSR     LOG_IN_OLD_PAD       ;    SHOVE IN NOTES_CURRENTLY_ON LIST
                ABS_SHORT
               BEQ.S   PAD_ON_BUT_NO_ROOM   ;         IF NO ROOM, THIN OUT BY THROWING AWAY.
               SWAP    D7                   ;              ELSE, WRITE
               JSR     (A2)                 ;              (UPPER WORD)
               SWAP    D7
               JSR     (A2)                 ;              (MIDDLE WORD)
               BSR     SEQ1_DSTR_READ       ;               GET LAST WORD
               MOVE    D7,BG_TEMP_5_B       ;                SAVE FOR MIDI XMISSION
               JSR     (A2)                 ;                 WRITE
;
;*****DO SEQ_FULL CHECK, ACTION
               BSR     SEQ_MEM_CHECK
;
               BSR     TRACK_MUTE_CHECK     ;SEE IF THIS TRACK MUTED - BRANCH TO PLAY_CLICK IF YES.
               BNE     NORM_PREF_LOOP       ;    IF MUTED, FORGET PLAYING
;15MAY               CMP.B   #0FFH,CLICK_ASSIGN   ;HAS SEQUENCER EATEN ALL VOICES DURING THIS CLICK?
;15MAY               BEQ.S   PAD_VOICES_FULL      ;BRANCH IF YES - DON'T BOTHER PLAYING ANY MORE SOUNDS.
;15MAY            MAY PUT THIS BACK IN IF SEQUENCER PHASES ARE REARRANGED
;15MAY            TO PUT OLD EVENTS BEHIND NEW ONES ON THE AUTOCORRECT CLICK.
;
               BSR     SEQ_ON_INTERNAL      ;IF NOT, PASS EVENT TO SEQ INTERNAL NOTE-ON HANDLER,
;15MAY;
;15MAYPAD_VOICES_FULL
;15MAY;
               ST      SEQ_XMIT_EVENT       ; SET FLAG TO PLOP IN MIDI SEQ BUFFER
               BSR     TYPE_1_XMIT          ;  AND XMIT OVER MIDI.
               BRA     NORM_PREF_LOOP       ;DEAL WITH NEXT EVENT.
;
;
ERASE_HIM_FELLA
               BSR     SEQ1_DSTR_READ       ;ERASING - EAT SECOND WORD,
                                            ;FALL THRU TO EAT THIRD AND GET BACK TO TOP.
;
;
PAD_ON_BUT_NO_ROOM
;
; NOTES-CURRENTLY-ON LIST FULL, OR WE'RE ERASING EVENT AND
; FELL THROUGH FROM ABOVE - EITHER WAY, WE MUST:
;
               BSR     SEQ1_DSTR_READ       ;EAT THE THIRD WORD,
               BRA     NORM_PREF_LOOP       ;DEAL WITH NEXT EVENT.
;
;
;
; INTERNAL EVENT ERASE TEST -
; HEY, DON'T COME AROUND IF NOT IN AN ERASUAL MODALITY.
; D7 (.W) CONTAINS FIRST WORD OF INTERNAL NOTE-ON EVENT,
; WHICH IS ALSO ASSUMED TO HAVE BEEN STORED AT BG_TEMP_1_B.
; RETURNS Z FLAG FALSE IF EVENT SHOULD BE ERASED.
; PRESERVES D7, DESTROYS D0-D1.
;
INT_ERASE_TEST
               MOVE    D7,D0                ;COPY EVENT FIRST WORD.
               AND     #0070H,D0            ;FIRST SEE IF EVENT IS ON THE RIGHT TRACK -
               LSR     #4,D0
               CMP     NOW_TRACK,D0
               BEQ.S   INT_ERS_10           ;BRANCH IF TRACK NUMBER MATCHES - DO ERASE TEST.
               CLR     D0                   ;ELSE, NO ERASE - RETURN Z FLAG TRUE.
               RTS
INT_ERS_10
               MOVE.B  BG_TEMP_1_B,D0       ;TRACK MATCHES, FETCH EVENT SOUND NUMBER.
               TST.B   D7                   ;IS ALT-PARAM BIT SET (IT'S IN BIT 7)?
               BMI.S   INT_ERS_30           ;BRANCH IF YES, CHECK IN UPPER HALF OF MAP.
               MOVE.L  INT_ERASE_MAP,D1     ;ELSE WE WANT TO LOOK IN LOWER-ADDRESSED HALF OF MAP.
               BTST    D0,D1                ;IS OUR BIT SET?  THE Z FLAG TELLS ALL ....
               RTS                          ;IF SO, WE WILL REQUEST ERASURE - ELSE WE WON'T.
INT_ERS_30
               MOVE.L  INT_ERASE_MAP+4,D1   ;FOR ALT-PARAMS BIT SET - USE OTHER HALF OF ERASE MAP.
               BTST    D0,D1                ;JUST LIKE ABOVE.
               RTS
;
;
;
;;;;;;;;;;
PAD_OFF
               MOVE    D7,BG_TEMP_1_B       ;SAVE FIRST WORD FOR MIDI UNPACKING, XMISSION
               SWAP    D7                   ; STOW AWAY
               BSR     SEQ1_DSTR_READ       ;  GET LOWER WORD
               MOVE    D7,BG_TEMP_3_B       ;   SAVE FOR MIDI UNPACKING & XMISSON
                ABS_LONG
               JSR     LOG_OUT_OLD_PAD      ;    ATTEMPT TO PULL OUT OF NOTES-CURRENTLY-ON LIST
                ABS_SHORT
               BEQ     NORM_PREF_LOOP       ;         IF COULD NOT FIND, THEN NO ON - FORGET THE OFF.
               SWAP    D7                   ;              ELSE, GO AHEAD & WRITE
               JSR     (A2)                 ;              (UPPER WORD)
               SWAP    D7
               JSR     (A2)                 ;              (LOWER WORD)
;
;*****DO SEQ_FULL CHECK, TAKE ACTION
               BSR     SEQ_MEM_CHECK
;
               BSR     TRACK_MUTE_CHECK     ;SEE IF THIS TRACK MUTED - BRANCH TO PLAY_CLICK IF YES.
               BNE.S   INDIAN_1             ;    IF MUTED, SPLIT
INDIAN_2
               BSR     SEQ_OFF_INTERNAL     ;IF NOT, PASS EVENT TO SEQ INTERNAL NOTE-OFF HANDLER,
               ST      SEQ_XMIT_EVENT       ; SET FLAG TO PLOP IN MIDI SEQ BUFFER
               BSR     TYPE_2_XMIT          ;THEN CODIFY AND SEND OUT OVER MIDI.
               BRA     NORM_PREF_LOOP       ; HANDLE NEXT EVENT
;
INDIAN_1       ;ONE OTHER CHANCE - JUST MUTED, BUT OUR DELAYED XMISSION OF OFFS HAS NOT TAKEN PLACE
; YET.  LOOK AT TIMEOUT TO SEE IF SUCH A TRANSMISSION IS PENDING, AND IF SO, LET THOSE TRACKS'
; WORTH ALSO PLAY/XMIT.
               TST.L   MUTE_OFF_TIMER       ;AN XMIT_OLD_OFF PENDING VIA MUTE?
               BEQ     NORM_PREF_LOOP       ;    IF NOT, SPLIT
               BSR     PENDING_MUTE_CHECK   ;         ELSE, SEE IF THIS IS ONE WE'RE ABOUT TO TURN OFF
               BNE     NORM_PREF_LOOP       ;         IF NOT, GIT
               BRA     INDIAN_2             ;              ELSE, XMIT & PLAY
;
;
;;;;;;;;;;
MIDI_ON
               SWAP    D7                   ;PROTECT HIGH WORD
               BSR     SEQ1_DSTR_READ       ; GET LOWER WORD
;
               TST.B   ERASING              ;WELL - ARE WE?
               BEQ.S   TAGG_1               ;    IF NOT, CONTINUE...
               BSR     ERASE_SEEK           ;         ELSE, SEE IF TO ERASE THIS EVENT
               BNE     NORM_PREF_LOOP       ;         IF TO ERASE, DO NOT COPY TO LIST
TAGG_1
                ABS_LONG
               JSR     LOG_IN_OLD_MIDI      ;  ADD TO THE NOTES_CURRENTLY_ON LIST
                ABS_SHORT
               BEQ     NORM_PREF_LOOP       ;    IF NO ROOM, KICK OUT & GO FOR NEXT EVENT
               SWAP    D7                   ;         ELSE, WRITE
               JSR     (A2)                 ;         (HIGH WORD FIRST)
               SWAP    D7
               JSR     (A2)                 ;         (THEN LOW WORD)
;
;*****DO SEQ_FULL CHECK, TAKE ACTION
               BSR     SEQ_MEM_CHECK
;
               BSR     TRACK_MUTE_CHECK     ;SEE IF THIS TRACK MUTED
               BNE     NORM_PREF_LOOP
               ST      SEQ_XMIT_EVENT       ; SET FLAG TO PLOP IN MIDI SEQ BUFFER
               BSR     TYPE_3_XMIT          ;    IF NOT, XMIT OVER MIDI
               BRA     NORM_PREF_LOOP       ;DO ANOTHER EVENT
;
;
;;;;;;;;;;
MIDI_OFF
               SWAP    D7                   ;PROTECT HIGH WORD
               BSR     SEQ1_DSTR_READ       ; GET LOWER WORD
                ABS_LONG
               JSR     LOG_OUT_OLD_MIDI     ;  LOOK FOR MATCHING NOTE-ON TO REMOVE FROM NOTES_CUR_ON
                ABS_SHORT
               BEQ     NORM_PREF_LOOP       ;    IF CAN'T FIND, KICK OUT & GO FOR NEXT EVENT
               SWAP    D7                   ;         ELSE, WRITE
               JSR     (A2)                 ;         (HIGH WORD FIRST)
               SWAP    D7
               JSR     (A2)                 ;         (THEN LOW WORD)
;
;*****DO SEQ_FULL CHECK, TAKE ACTION
               BSR     SEQ_MEM_CHECK
;
               BSR     TRACK_MUTE_CHECK     ;SEE IF THIS TRACK MUTED
               BNE     INDIAN_3
INDIAN_4
               ST      SEQ_XMIT_EVENT       ; SET FLAG TO PLOP IN MIDI SEQ BUFFER
               BSR     TYPE_4_XMIT          ;    IF NOT, XMIT OVER MIDI
               BRA     NORM_PREF_LOOP       ;DO ANOTHER EVENT
;
INDIAN_3       ;ONE OTHER CHANCE - JUST MUTED, BUT OUR DELAYED XMISSION OF OFFS HAS NOT TAKEN PLACE
; YET.  LOOK AT TIMEOUT TO SEE IF SUCH A TRANSMISSION IS PENDING, AND IF SO, LET THOSE TRACKS'
; WORTH ALSO PLAY/XMIT.
               TST.L   MUTE_OFF_TIMER       ;AN XMIT_OLD_OFF PENDING VIA MUTE?
               BEQ     NORM_PREF_LOOP       ;    IF NOT, SPLIT
               BSR     PENDING_MUTE_CHECK   ;         ELSE, SEE IF THIS IS ONE WE'RE ABOUT TO TURN OFF
               BNE     NORM_PREF_LOOP       ;         IF NOT, GIT
               BRA     INDIAN_4             ;              ELSE, XMIT & PLAY
;
;
;;;;;;;;;;
OTHER_MIDI
               SWAP    D7                   ;PROTECT HIGH WORD
               BSR     SEQ1_DSTR_READ       ; GET LOW ORDER WORD
               SWAP    D7
               JSR     (A2)                 ;  WRITE (HIGH ORDER WORD FIRST)
               SWAP    D7
               JSR     (A2)                 ;  (LOW ORDER WORD)
;
;*****DO SEQ_FULL CHECK, ACTION
               BSR     SEQ_MEM_CHECK
;
               BSR     TRACK_MUTE_CHECK     ;SEE IF ALLOWED TO XMIT THIS TRACK
               BNE     NORM_PREF_LOOP
               ST      SEQ_XMIT_EVENT       ; SET FLAG TO PLOP IN MIDI SEQ BUFFER
               BSR     TYPE_5_XMIT          ;    IF YES, DO SO (ELSE, KICKE OUT TO PLAY_CLICK)
               BRA     NORM_PREF_LOOP       ;HANDLE NEXT EVENT
;
;
;;;;;;;;;;
MIDI_SYSEX
               ST      SEQ_XMIT_EVENT       ; SET FLAG TO PLOP IN MIDI SEQ BUFFER
               BSR     TYPE_6_XMIT          ;DEFER TO ROUTINE IN SEQ_MIDI.  A SYSTEM EXCLUSIVE
                                            ; MESSAGE IS A VARIABLE NUMBER OF BYTES LONG - DOES
                                            ; DECODING (INCLUDING TRACK MUTE CHECK) THERE.
               BRA     NORM_PREF_LOOP       ;HANDLE NEXT EVENT
;
;
;;;;;;;;;;
NEW_BAR_MARK
               MOVE    D7,HOLDING_EVENT     ;HANG ON TO THIS WORD FOR LATER PROCESSING
               MOVE    CLICKS_THIS_BAR,NEXT_EVENT_TIME     ;WANT TO OPERATE ON NEXT BAR WHEN
                                                           ; CURRENT ONE FINISHED.
               BRA     END_OF_CLICK         ;DONE WITH THIS CLICK'S EVENTS
;
;
;;;;;;;;;;
NEW_TIME_MARK
               MOVE    D7,HOLDING_EVENT     ;SAVE TO PROCESS WHEN READY
               LSR     #4,D7                ; DECODE CLICK NUMBER WHEN THISIS SUPPOSED TO HAPPEN
;
               CMP     CLICKS_THIS_BAR,D7   ;STOP-GAP CRASH PREVENTION - DISALLOW NEXT_EVENT_TIME
               BLS.S   NEW_TM_20            ;LATER THAN END OF CURRENT BAR.
               MOVE    CLICKS_THIS_BAR,D7   ;IF BOGUS TIME VALUE, PRE-FETCH IS PROBABLY LOST -
                                            ;SCHEDULE FOR THE END OF THE CURRENT BAR.
NEW_TM_20
;
               MOVE    D7,NEXT_EVENT_TIME   ;  SAVE
               BRA     END_OF_CLICK         ;DONE FETCHING THIS CLICK'S EVENTS.
;
;
;;;;;;;;;;
NEW_TAP_TIME
               SWAP    D7                   ;HIDE HIGH WORD
               BSR     SEQ1_DSTR_READ       ; GET SECOND
;
               TST.B   PROCESSED_TAP        ;SEE IF ALREADY GOT ONE THIS CLICK - THE FIRST ONE
               BNE     NORM_PREF_LOOP       ; THIS CLICK IS THE MOST RECENTLY RECORDED.  BY IGNORING
                                            ; POSSIBLE FOLLOWING TAPS, GIVE USER THE ILLUSION THAT
               ST      PROCESSED_TAP        ; S/HE OVERWROTE THE OLD TAP TRACK BY TAPPING AGAIN.
;
               SWAP    D7                   ;    ELSE, OKAY.  WRITE HIGH WORD
               JSR     (A2)
               SWAP    D7                   ;    UNSWAP TO WRITE LOW WORD
               JSR     (A2)
;
;*****DO SEQ_FULL CHECK, ACTION
               BSR     SEQ_MEM_CHECK
;
                ABS_LONG
               JSR     TAP_TIME_OFFSET      ; NEXT - GO TO ROUTINE IN TEMPO WHO PROCESSES IT
                ABS_SHORT
               BRA     NORM_PREF_LOOP       ;GET NEXT EVENT
;
;
;09JUN;;;;;;;;;;
;09JUNNEW_A_R_MARK
;09JUN               JSR     (A2)                 ;WRITE THIS WORD
;09JUN               SWAP    D7
;09JUN               BSR     SEQ1_DSTR_READ       ;GET SECOND WORD
;09JUN               JSR     (A2)                 ; WRITE
;09JUN;
;09JUN;*****DO SEQ_FULL CHECK, ACTION
;09JUN               BSR     SEQ_MEM_CHECK
;09JUN;
;09JUN                ABS_LONG
;09JUN               JSR     ACCEL_RIT            ;GET 2nd WORD, DEAL WITH (LOOK IN 'TEMPO')
;09JUN                ABS_SHORT
;09JUN               BRA     NORM_PREF_LOOP       ;CONTINUE ON WITH CLICK
;
;  A-R MARKERS HANDLED ALONG WITH BAR-MARKERS IN "NORMAL" PLAYBACK MODE,
;  THIS CODE WOULD NEVER GET EXECUTED.
;
;
;;;;;;;;;;
NEW_UART_TIMING
               JSR     (A2)                 ;FIRST - WRITE
;
;*****DO SEQ_FULL CHECK, ACTION
               BSR     SEQ_MEM_CHECK
;
               BTST    #15,D7               ;IF 'A' IS INACTIVE
               BNE.S   WAVE_0               ;    THEN IGNORE; MOVE ON TO B
               MOVE    D7,D6                ;         ELSE, PROCESS
               LSL     #1,D6                ;ROTATE OFF 'ACTIVITY' BIT
               ASR     #8,D6                ; ROTATE, SIGN-EXTENDED, INTO A WORD VALUE
               ASR     #3,D6
               MOVE    D6,MA_SEQ_ADVANCE    ;  SAVE
WAVE_0
               BTST    #9,D7                ;IF 'B' IS INACTIVE
               BNE.S   WAVE_1               ;    THEN COOL - DONE
               MOVE    D7,D6                ;         ELSE, PROCESS
               LSR     #1,D6                ;GET SO THAT BUISNESS PART ON BYTE BOUNDRY
               ASR.B   #3,D6                ; SIGN-EXTEND INTO A BYTE
               EXT     D6                   ;  SIGN-EXTEND INTO A WORD
               MOVE    D6,MB_SEQ_ADVANCE    ;   SAVE
WAVE_1
               BRA     NORM_PREF_LOOP
;
;
;;;;;;;;;;
END_OF_SEQUENCE
               JSR     SEQ_END_HANDLER      ;DEAL WITH A COMPLEX SET OF ISSUES -
               BRA     END_OF_CLICK         ;HEAD ON DOWN FOR FINAL DETERMINATION, IF ANY.
;
;
;
;
;;;;;;;;;;
;
; UTILITY TO TAKE FIRST WORD OF EVENT IN D7, AND SEE IF ITS TRACK IS
; BEING MUTED AT THIS POINT.  IF YES, RETURNS Z FLAG FALSE.
;
TRACK_MUTE_CHECK
               SWAP    D7                   ;(TRACKNUM IN HIGH ORDER WORD)
               MOVE    D7,D0                ;MAKE COPY TO WORK ON
               SWAP    D7
               AND     #0070H,D0            ; MASK TO JUST TRACKNUM
               LSR     #4,D0                ;  ROTATE DOWN TO STRIGHT NOMBRE
               BTST    D0,TRACKS_MUTED      ;   SEE IF THAT PARTICULAR TRACK IS SET TO BE MUTED
                                            ;    IF YES,THEN ON WITH NEXT EVENT (NOT-Z FLAG)
               RTS                          ;         ELSE, RETURN AND DO WHAT YOU WILL.
;
;
;
;;;;;;;;;;
;
; AS ABOVE, 'CEPT USING THE MASK 'PENDING MUTE' - THE ONLY TRACK UNMUTED
; IN THIS MASK IS THE ONE WE'RE ABOUT TO DO AN XMIT_OLD_x_OFFS FOR.
;
PENDING_MUTE_CHECK
               SWAP    D7                   ;(TRACKNUM IN HIGH ORDER WORD)
               MOVE    D7,D0                ;MAKE COPY TO WORK ON
               SWAP    D7
               AND     #0070H,D0            ; MASK TO JUST TRACKNUM
               LSR     #4,D0                ;  ROTATE DOWN TO STRIGHT NOMBRE
               BTST    D0,PENDING_MUTE      ;   SEE IF THAT PARTICULAR TRACK SI SET TO BE MUTED
                                            ;    IF YES,THEN ON WITH NEXT EVENT (NOT-Z FLAG)
               RTS                          ;         ELSE, RETURN AND DO WHAT YOU WILL.
;
;AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
               SKIP
;VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV
;
; THIS STUFF SHOULD LOOK PRETTY FAMILIAR - YOU JUST SAW IT UPSTAIRS -
; IT'S SEQUENCE DATA UNPACKING ROUTINES, NON-DESTRUCTIVE STYLE-Y ....
; FOR USE WHILE IN A PLAYBACK REPEAT LOOP.
; WE'RE TALKING ABOUT A SET OF ROUTINES, SEE, THAT DO EX-ACT-LY WHAT THE
; NORMAL PLAYBACK COUNTERPART ROUTINES DO, EX-CEPT THAT AB-SO-LUTE-LY NO
; REARRANGEMENT OF ANY SEQUENCE DATA OCCURS - NO ERASE, NO COPY-OVER
; FROM READ BLOCK TO WRITE BLOCK (SINCE THAT'S ALREADY BEEN DONE ON THE
; FIRST (I.E., PRE-REPEAT) PASS THROUGH THE REPEAT LOOP SECTION, NO NEW
; DATA BE GETTIN' IN FUM ANY-WHAH, NO NUFFIN' AT ALL.
; SO:  NO ERASE TEST, NO MEMORY-FULL TEST, NO BUFFER-FULL TEST ....
;
; WE GET IN HERE, D7 CONTAINS THE EVENT FIRST WORD.
;
; NOTES AND COMMENT:  BAR-MARKER AND TIME-MARKER EVENT COPY-OVER IS NOT
; DONE IN THE PLAY_CLICK LOOP, HENCE THE HANDLING OF THESE EVENTS WITHIN
; THIS LOOP IS THE SAME FOR BOTH NORMAL AND REPEAT PLAYBACK, AND THE
; SAME ROUTINES ARE USED BY BOTH PLAY_CLICK AND RPT_PLAY_CLICK LOOPS.
; SIMILAR SITUATION AS REGARDS MIDI SYSTEM-EXCLUSIVE MESSAGES:  THE DATA
; COPY-OVER DOES OCCUR WITHIN THIS LOOP, BUT THE ROUTINE WHICH ACTUALLY
; DOES IT IS LOCATED ELSEWHERE - ALL WE DO HERE IS CALL IT, SAME WAY FOR
; EITHER NORMAL OR REPEAT PLAYBACK - IT KNOWS THE RIGHT THING TO DO.
; END-OF-SEQUENCE MARK SHOULD NEVER BE ENCOUNTERED BY REPEAT PLAYBACK
; PARSER, HENCE THERE IS NO ROUTINE HERE TO HANDLE IT.
;
; YOU MAY OBSERVE A PRE-PON-DERANCE OF SEMI-COL-ONS HEREABOUTS ....
;
; WANNA KNOW WHAT EACH EVENT LOOKS LIKE?
; LOOK AROUND IN THIS FILE - YOU'LL SEE IT (IF YOU'RE NOT A BLIND FUCK).
;
RPT_PAD_ON
               MOVE    D7,BG_TEMP_1_B       ;SAVE FOR UNPACKING & XMITTING OVER MIDI -
               SWAP    D7                   ;UPPER WORD OUTA THE WAY,
               BSR     SEQ_NDSTR_READ       ;GET MIDDLE WORD -
               MOVE    D7,BG_TEMP_3_B       ;ALSO SAVE FOR UNPACKING & XMITTING OVER MIDI.
                ABS_LONG
               JSR     LOG_IN_OLD_PAD       ;SHOVE IN NOTES_CURRENTLY_ON LIST.
                ABS_SHORT
               BSR     SEQ_NDSTR_READ       ;GET LAST WORD,
               MOVE    D7,BG_TEMP_5_B       ;SAVE FOR MIDI XMISSION.
;
               BSR     TRACK_MUTE_CHECK     ;SEE IF THIS TRACK MUTED -
               BNE     RPT_PREF_LOOP        ;IF MUTED, FORGET PLAYING IT.
;15MAY               CMP.B   #0FFH,CLICK_ASSIGN   ;HAS SEQUENCER EATEN ALL VOICES DURING THIS CLICK?
;15MAY               BEQ.S   RPT_PAD_VOICES_FULL  ;BRANCH IF YES - DON'T BOTHER PLAYING ANY MORE SOUNDS.
;15MAY            MAY PUT THIS BACK IN IF SEQUENCER PHASES ARE REARRANGED
;15MAY            TO PUT OLD EVENTS BEHIND NEW ONES ON THE AUTOCORRECT CLICK.
;
               BSR     SEQ_ON_INTERNAL      ;IF NOT, PASS EVENT TO SEQ INTERNAL NOTE-ON HANDLER,
;15MAY;
;15MAYRPT_PAD_VOICES_FULL
;15MAY;
               ST      SEQ_XMIT_EVENT       ;SET FLAG TO PLOP IN MIDI SEQ BUFFER,
               BSR     TYPE_1_XMIT          ;AND XMIT OVER MIDI.
               BRA     RPT_PREF_LOOP        ;DEAL WITH NEXT EVENT.
;
;
;
RPT_PAD_OFF
               MOVE    D7,BG_TEMP_1_B       ;SAVE FIRST WORD FOR MIDI UNPACKING, XMISSION -
               SWAP    D7                   ;UPPER WORD OUTA THE WAY,
               BSR     SEQ_NDSTR_READ       ;GET LOWER WORD -
               MOVE    D7,BG_TEMP_3_B       ;SAVE FOR MIDI UNPACKING & XMISSON.
                ABS_LONG
               JSR     LOG_OUT_OLD_PAD      ;ATTEMPT TO PULL OUT OF NOTES-CURRENTLY-ON LIST -
                                            ;IF WE DIDN'T FIND IT, WHO CARES ANYWAY.
                ABS_SHORT
;
               BSR     TRACK_MUTE_CHECK     ;SEE IF THIS TRACK MUTED -
               BEQ.S   RPADOFF_20           ;IF NOT, IT'S PLAY-TIME.
               TST.L   MUTE_OFF_TIMER       ;MUTED - IS THERE AN XMIT_OLD_OFF PENDING VIA MUTE?
               BEQ     RPT_PREF_LOOP        ;IF NOT, SPLIT.
               BSR     PENDING_MUTE_CHECK   ;ELSE, SEE IF THIS IS ONE WE'RE ABOUT TO TURN OFF -
               BNE     RPT_PREF_LOOP        ;IF NOT, GIT.
RPADOFF_20
               BSR     SEQ_OFF_INTERNAL     ;ELSE - PASS EVENT TO SEQ INTERNAL NOTE-OFF HANDLER,
               ST      SEQ_XMIT_EVENT       ;SET FLAG TO PLOP IN MIDI SEQ BUFFER,
               BSR     TYPE_2_XMIT          ;THEN CODIFY AND SEND OUT OVER MIDI.
               BRA     RPT_PREF_LOOP        ;HANDLE NEXT EVENT, HEY.
;
;
;
RPT_MIDI_ON
               SWAP    D7                   ;PROTECT HIGH WORD,
               BSR     SEQ_NDSTR_READ       ;GET LOWER WORD.
                ABS_LONG
               JSR     LOG_IN_OLD_MIDI      ;ADD TO THE NOTES_CURRENTLY_ON LIST.
                ABS_SHORT
;
               BSR     TRACK_MUTE_CHECK     ;SEE IF THIS TRACK MUTED -
               BNE     RPT_PREF_LOOP        ;IF YES, BEGONE.
               ST      SEQ_XMIT_EVENT       ;ELSE, SET FLAG TO PLOP IN MIDI SEQ BUFFER,
               BSR     TYPE_3_XMIT          ;XMIT OVER MIDI.
               BRA     RPT_PREF_LOOP        ;HANDLE NEXT EVENT.
;
;
;
RPT_MIDI_OFF
               SWAP    D7                   ;PROTECT HIGH WORD,
               BSR     SEQ_NDSTR_READ       ;GET LOWER WORD.
                ABS_LONG
               JSR     LOG_OUT_OLD_MIDI     ;LOOK FOR MATCHING NOTE-ON TO REMOVE FROM NOTES_CUR_ON.
                                            ;IF NOT THERE, NO SWEAT REALLY.
                ABS_SHORT
;
               BSR     TRACK_MUTE_CHECK     ;SEE IF THIS TRACK MUTED -
               BEQ.S   RMIDOFF_20           ;BRANCH IF NOT, IT'S PLAY-TIME.
               TST.L   MUTE_OFF_TIMER       ;MUTED - IS THERE AN XMIT_OLD_OFF PENDING VIA MUTE?
               BEQ     RPT_PREF_LOOP        ;IF NOT, SPLIT.
               BSR     PENDING_MUTE_CHECK   ;ELSE, SEE IF THIS IS ONE WE'RE ABOUT TO TURN OFF -
               BNE     RPT_PREF_LOOP        ;IF YES, WE DON'T MAKE NO MIDI NOISE WITH IT.
RMIDOFF_20
               ST      SEQ_XMIT_EVENT       ;ELSE, SET FLAG TO PLOP IN MIDI SEQ BUFFER,
               BSR     TYPE_4_XMIT          ;XMIT OVER MIDI.
               BRA     RPT_PREF_LOOP        ;DO NEXT EVENT.
;
;
;
RPT_OTHER_MIDI
               SWAP    D7                   ;PROTECT HIGH WORD,
               BSR     SEQ_NDSTR_READ       ;GET LOW ORDER WORD.
;
               BSR     TRACK_MUTE_CHECK     ;SEE IF ALLOWED TO XMIT THIS TRACK -
               BNE     RPT_PREF_LOOP        ;SKIP ON OUT IF NOT.
               ST      SEQ_XMIT_EVENT       ;ELSE, SET FLAG TO PLOP IN MIDI SEQ BUFFER,
               BSR     TYPE_5_XMIT          ;DO IT TO IT.
               BRA     RPT_PREF_LOOP        ;HANDLE NEXT EVENT.
;
;
;;;;;;;;;;
RPT_MIDI_SYSEX
               ST      SEQ_XMIT_EVENT       ; SET FLAG TO PLOP IN MIDI SEQ BUFFER
               BSR     R_TYPE_6_XMIT        ; USE COPY OF ROUTINE IN SEQ_MIDI.  A SYSTEM EXCLUSIVE
                                            ; MESSAGE IS A VARIABLE NUMBER OF BYTES LONG - DOES
                                            ; DECODING (INCLUDING TRACK MUTE CHECK) THERE.
               BRA     RPT_PREF_LOOP        ;HANDLE NEXT EVENT
;
;
;
;;;;;;;;;;
R_TYPE_6_XMIT          ; SYSTEM EXCLUSIVE MESSAGE TO XMIT - PASSED FIRST WORD IN D7.  ALSO HAS
; TRACKNUM BYTE - NEED TO RUN A TRACK_MUTED TEST.  IF TRACK INDEED MUTED, NEED TO READ & WRITE,
; BUT DO NOT XMIT.
               BTST    #7,D7                ;RIGHT UP FRONT - WHICH UART?
               BNE     RYSEX_B
;
RYSEX_A
               MOVE    D7,D0                ;MAKE COPY TO WORK ON
               AND     #0070H,D0            ; MASK TO JUST TRACKNUM
               LSR     #4,D0                ;  ROTATE DOWN TO STRAIGHT NOMBRE
               BTST    D0,TRACKS_MUTED      ;   SEE IF THAT PARTICULAR TRACK SI SET TO BE MUTED
               BNE     RYSEX_A_MUTED        ;    IF YES, READ & WRITE, BUT DO NOT XMIT
                                            ;         ELSE, CONTINUE
               MOVEQ   #NEG_EXT+0F0H,D0     ;WELL, KNOW WHAT THE FIRST BYTE WILL BE...
               BSR     LOAD_A_SEQ           ; XMIT
;
RMPLIFIER_A
               BSR     SEQ_NDSTR_READ       ;GET NEXT WORD FROM SEQUENCER
               MOVE.B  D7,XMIT_TEMP_1       ;LOAD UP 2nd BYTE TO XMIT
               BMI.S   RINE_2_SYSEX_A       ; ANY STATUS BYTE MEANS EOX
               LSR     #8,D7                ;GET AT 1st DATA BYTE
               MOVE.B  D7,D0
               BMI.S   RINE_SYSEX_A         ;    AGAIN - EOX?
;
               BSR     XMIT_1_PA_SEQ        ;XMIT
               BRA     RMPLIFIER_A          ; GO AGAIN 'TILL DONE
;
RINE_2_SYSEX_A         ; DATA BYTE & AN EOX TO FINISH UP
               MOVE    D7,D0
               LSR     #8,D0                ;ROTATE DOWN THAT DATA BYTE
               BSR     LOAD_A_SEQ
RINE_SYSEX_A           ; FINISH UP WITH AN EOX
               MOVEQ   #NEG_EXT+0F7H,D0
               BSR     LOAD_A_SEQ
               RTS
;
;
RYSEX_A_MUTED
               BSR     SEQ_NDSTR_READ       ;GET NEXT WORD FROM SEQUENCER
               TST     D7                   ;LOOK AT SYSEX DATA - TEST UPPER BYTE
               BMI.S   RUTED_FINE_A         ; UPPER BIT SET MEANS EOX - DONE
               BTST    #7,D7                ;  LOOK AT LOWER DATA BYTE
               BEQ.S   RYSEX_A_MUTED        ;   IF UPPER BIT CLEAR, DATA - KEEP GOING
                                            ;    ELSE, EOX - DONE
RUTED_FINE_A           ; SAW AN EOX IN LATEST WORD FETCHED - DONE HERE
               RTS
;
;
;;;;;;;;;;
RYSEX_B
               MOVE    D7,D0                ;MAKE COPY TO WORK ON
               AND     #0070H,D0            ; MASK TO JUST TRACKNUM
               LSR     #4,D0                ;  ROTATE DOWN TO STRAIGHT NOMBRE
               BTST    D0,TRACKS_MUTED      ;   SEE IF THAT PARTICULAR TRACK SI SET TO BE MUTED
               BNE     RYSEX_B_MUTED        ;    IF YES, READ & WRITE, BUT DO NOT XMIT
                                            ;         ELSE, CONTINUE
               MOVEQ   #NEG_EXT+0F0H,D0     ;WELL, KNOW WHAT THE FIRST BYTE WILL BE...
               BSR     LOAD_B_SEQ           ; XMIT
;
RMPLIFIER_B
               BSR     SEQ_NDSTR_READ       ;GET NEXT WORD FROM SEQUENCER
               MOVE.B  D7,XMIT_TEMP_1       ;LOAD UP 2nd BYTE TO XMIT
               BMI.S   RINE_2_SYSEX_B       ; ANY STATUS BYTE MEANS EOX
               LSR     #8,D7                ;GET AT 1st DATA BYTE
               MOVE.B  D7,D0
               BMI.S   RINE_SYSEX_B         ;    AGAIN - EOX?
;
               BSR     XMIT_1_PB_SEQ        ;XMIT
               BRA     RMPLIFIER_B          ; GO AGAIN 'TILL DONE
;
RINE_2_SYSEX_B         ; DATA BYTE & AN EOX TO FINISH UP
               MOVE    D7,D0
               LSR     #8,D0                ;ROTATE DOWN THAT DATA BYTE
               BSR     LOAD_B_SEQ
RINE_SYSEX_B           ; FINISH UP WITH AN EOX
               MOVEQ   #NEG_EXT+0F7H,D0
               BSR     LOAD_B_SEQ
               RTS
;
;
RYSEX_B_MUTED
               BSR     SEQ_NDSTR_READ       ;GET NEXT WORD FROM SEQUENCER
               TST     D7                   ;LOOK AT SYSEX DATA - TEST UPPER BYTE
               BMI.S   RUTED_FINE_B         ; UPPER BIT SET MEANS EOX - DONE
               BTST    #7,D7                ;  LOOK AT LOWER DATA BYTE
               BEQ.S   RYSEX_B_MUTED        ;   IF UPPER BIT CLEAR, DATA - KEEP GOING
                                            ;    ELSE, EOX - DONE
RUTED_FINE_B           ; SAW AN EOX IN LATEST WORD FETCHED - DONE HERE
               RTS
;
;
;
RPT_NEW_TAP_TIME
               SWAP    D7                   ;HIDE HIGH WORD,
               BSR     SEQ_NDSTR_READ       ;GET SECOND.
               TST.B   PROCESSED_TAP        ;SEE IF ALREADY GOT ONE THIS CLICK - THE FIRST ONE THIS
                                            ; CLICK IS THE MOST RECENTLY RECORDED ONE.  BY IGNORING
                                            ; POSSIBLE FOLLOWING TAPS, GIVE USER THE ILLUSION THAT
                                            ; S/HE OVERWROTE THE OLD TAP TRACK BY TAPPING AGAIN.
               BNE     RPT_PREF_LOOP        ;ALREADY GOT ONE, SO BE IGNORING OF THIS ONE.
               ST      PROCESSED_TAP        ;FIRST ONE, THIS CLICK - FLAGGIT.
                ABS_LONG
               JSR     TAP_TIME_OFFSET      ;NEXT - GO TO ROUTINE IN TEMPO WHO PROCESSES IT.
                ABS_SHORT
               BRA     RPT_PREF_LOOP        ;GET NEXT EVENT - ALWAYS NEXT EVENT - ARG ....
;
;
;
RPT_NEW_A_R_MARK
               SWAP    D7                   ;PUT FIRST WORD OUTEN DA WAY LEFT,
               BSR     SEQ_NDSTR_READ       ;GET T'OTHER ONE -
                ABS_LONG
               JSR     START_ACC_RIT        ;THEN ALL WE DO IS, DEAL WITH (LOOK IN 'TEMPO').
                ABS_SHORT
               BRA     RPT_PREF_LOOP        ;CONTINUE ON WITH CLICK - THAT "NEXT" KINDA EVENT.
;
;
;
RPT_NEW_UART_TIMING
               MOVE    D7,D6                ;MAKE A COPY FOR UNPARSING.
               ASR     #2,D6                ;GET TWO UARTS STRADDLING BYTE BORDER -
               TST     D6                   ;IF UPPER BIT OF UPPER BYTE SET,
               BMI.S   RPT_NR_END_1         ;THEN IGNORE FOR UART A -
                                            ;ELSE, PROCESS:
               LSL     #1,D7                ;ROTATE OFF 'ACTIVITY' BIT,
               ASR     #3,D7                ;ROTATE DOWN INTO A SIGN-EXTENDED WORD -
               ASR     #8,D7
               MOVE    D7,MA_SEQ_ADVANCE    ;UPDATE OUR MR. A. CONTROL WORD.
RPT_NR_END_1
               TST.B   D6                   ;IF UPPER BIT OF LOWER BYTE SET,
               BMI     RPT_PREF_LOOP        ;THEN NO CHANGE FOR UART B -
                                            ;ELSE, PROCESS:
               LSL     #1,D6                ;MOVE ACTIVITY BIT OUT OF WAY (INTO UPPER BYTE),
               ASR.B   #3,D6                ;ROTATE OFF ID -
               EXT     D6                   ;MAKE A SIGN-EXTENDED WORD,
               MOVE    D6,MB_SEQ_ADVANCE    ;UPDATE OUR MR. B. CONTROL WORD.
               BRA     RPT_PREF_LOOP        ;YOU GOT IT - HEAD FOR NEXT EVENT.
;
;AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
               TITLE   "TURNING AROUND AT END OF CLICK"
;VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV
;
; BRANCH HERE WHEN TIME MARKER OR END-OF-SEQUENCE MARKER IS PARSED -
; WE'RE AT THE END OF PROCESSING EXISTING SEQUENCE EVENTS FOR THIS CLICK
; AND MUST DO THE THINGS THAT ONE DOES AT THIS TIME.
;
END_OF_CLICK
               MOVE.L  A6,SEQ_WR_PTR        ;SAVE UPDATED POINTERS FOR READ/WRITE PROCESSES.
               MOVE.L  A5,SEQ1_DRD_PTR
               MOVE.L  A4,SEQ_NDRD_PTR
               MOVE    A3,WASTELAND_PTR
;
;871008                                            ;BEFORE WE KISS THIS CLICK GOODBYE .... PUNCH-IN/OUT?
;871008               TST.B   NOW_REPEATING        ;ARE WE IN NON-DESTRUCTIVE LOOP PLAYBACK MODE?
;871008               BNE.S   EOC_10               ;BRANCH IF YES, DON'T BOTHER WITH PUNCH-IN/OUT TESTS -
;871008               BSR     AUTO_BAR_PUNCH       ;ELSE - GO CHECK IT OUT, ACT IF NECESSARY.
;871008EOC_10
;              NOTE: MOVED TO THE BEGINNING OF CLICK SERVICE, SO IT GETS
;              DONE BEFORE HANDLING AN END-OF-SEQUENCE MARK - WHICH WILL
;              RESULT IN PUNCH-OUT IF DOING SINGLE-PASS RECORDING.  THIS
;              PREVENTS US FROM INADVERTENTLY REVERSING THE PUNCH-OUT
;              JUST BEFORE STOPPING.
;
;
                ABS_LONG
               JSR     UPDATE_ACC_RIT       ;UPDATE ANY ACCELRANDO/RITARDANDO IN PROGRESS,
                                            ;PUT NEW TEMPO OUT TO 6803.
                ABS_SHORT
;
;
;15MAY               SF      CLICK_ASSIGN         ;NOW THAT WE'RE OUTA HERE, CLEAR ALL RECORD OF WHICH
;15MAY                                            ;VOICES WERE ASSIGNED TO THIS CLICK'S SEQ EVENTS.
;15MAY             MAY PUT THIS BACK IN IF SEQUENCER PHASES ARE REARRANGED
;15MAY             TO PUT OLD EVENTS BEHIND NEW ONES ON THE AUTOCORRECT CLICK.
;
               TST     CONTINUE_TIMER       ;IS A PENDING MIDI "CONTINUE" TRANSMISSION TIMING DOWN?
               BEQ.S   EOC_20               ;BRANCH IF NOT -
               SUBQ    #1,CONTINUE_TIMER    ;IF SO, IS IT TIME NOW?
               BNE.S   EOC_20               ;BRANCH IF NOT - MAYBE NEXT TIME.
               BSR     SEND_6803_CONTINUE   ;IT'S TIME - SEND CONTINUE VIA 6803 UART,
               BSR     SEND_MIDI_CONTINUE   ;WRITE SAME BYTE TO "A" AND "B" UARTS AS APPROPRIATE.
EOC_20
;
               MOVEQ   #NEG_EXT+0F8H,D0     ;CAP INFO WITH A MIDI CLOCK BYTE TO DEMARCATE THE END
               BSR     LOAD_A_SEQ           ;OF THE SET OF BUFFERED EVENTS ASSOCIATED WITH THIS
               MOVEQ   #NEG_EXT+0F8H,D0     ;CLICK - THE CLOCK BYTE IS NOT ACTUALLY TRANSMITTED.
               BSR     LOAD_B_SEQ
;
               CMP.L   #10000H,NOW_BAR      ;ARE WE AT VERY BEGINNING OF CURRENT SEQUENCE?
               BNE.S   EOC_40               ;BRANCH IF NOT, CONTINUE.
               BSR     PLAY_LED_OFF                   ;ELSE, SNUFF "PLAY" LED TO LET 'EM ALL KNOW -
               MOVE    REAL_TIME,PLAY_BLINK_TIMER     ;SET TIMER WHICH WILL TURN IT BACK ON SOON.
               BSET    #0,PLAY_BLINK_TIMER+1          ;TIMER WORD MUST BE NON-ZERO TO ACTIVATE IT.
EOC_40
;
               BSR     BEAT_DISPLAY_BOY     ;WHAT ABOUT THAT BEAT NUMBER?  REQUEST UPDATE OF LCD IF
                                            ;IT CHANGED, AND IF WE WOULD SEE IT IN CURRENT SCREEN.
;
;
; WELL, WHAT NEXT?  STOP, CONTINUE NORMALLY -
; OR KICK OUT ANOTHER CLICK-SERVICE BEFORE EXITING ....
;
               TST.B   PLAYED_TO_END        ;THIS IS SET WHEN WE'VE PLAYED AS FAR AS WE CAN GO -
               BEQ.S   EOC_A0               ;BRANCH IF NOT THE CASE, CHECK OTHER POSSIBILITIES.
               MOVE    CLOCK_IN_MODE,D0     ;SELF-STOPPING - ACTION DEPENDS ON CLOCK-IN MODE:
               BEQ.S   KILL_IT_DEAD         ;IF INTERNAL TIMEBASE, SEQUENCER DIES THE DEATH -
               CMP     #3,D0                ;IF CLICK SYNC, LIKEWISE KILL SEQUENCER COMPLETELY -
               BEQ.S   KILL_IT_DEAD         ;USER WILL HAVE TO HIT "PLAY" TO REV IT UP AGAIN.
               TST     NOW_SEQ_STATUS       ;FOR EXTERNAL CONTROL MODES - DID WE HIT A DEAD-END?
               BEQ.S   KILL_IT_DEAD         ;BRANCH IF UNPLAYABLE SEQUENCE CUED - DO A FULL STOP,
                                            ;TAKE US OFF-LINE - USER'S DIRECT INTERVENTION REQ'D.
                                            ;(NOTE - FORMER_SEQUENCE SHOULD STILL REFLECT SEQUENCE
                                            ;JUST ENDED - BACKGROUND'LL CATCH NEW CURRENT_SEQUENCE
                                            ;AND COMPLETE "INSTALLATION" OF THE NEW NON-SEQUENCE
                                            ;WHEN IT SEES THAT TRANSPORT IS DEAD.)
;
                                            ;OTHERWISE, WANT TO REMAIN OPEN TO EXTERNAL CONTROL -
               BSR     SYNC_PLAY_RESTART    ;JUST RE-CUE TO BEGINNING AND STAY ON-LINE WAITING FOR
                                            ;EXTERNAL CONTROL TO START US UP OR CUE US AGAIN.
               BRA     PRO_CLICK_EXIT       ;FORGET MIDI BUFFER DUMPING - IT'S ALL GONE.
;
EOC_A0
               TST.B   RECORD_LOOPING       ;THIS FLAG MEANS WE HAVE JUST CROSSED OVER THE LINE
                                            ;BETWEEN END OF ONE SEQUENCE AND THE BEGINNING OF
                                            ;ANOTHER (OR EVEN THE SAME ONE) BY VIRTUE OF LOOPING
                                            ;RECORD, SONG MODE, OR HAND-CUE OF A NEW SEQUENCE -
               BEQ.S   EOC_C0               ;BRANCH AND CONTINUE NORMALLY IF NOT SET - CONTINUE ON
                                            ;TO TEST FOR FIRST-CLOCK DOUBLE PRE-FETCH.
               SF      RECORD_LOOPING       ;ELSE - EVEN THOUGH WE'RE SURELY AT BAR 1, CLOCK 0 OF
                                            ;THE NEW SEQUENCE, WE DON'T WANT OR NEED TO DO A SECOND
                                            ;PRE-FETCH - THIS IS BECAUSE WE GOT HERE VIA PRE-FETCH
                                            ;OF THE LAST CLICK IN THE PREVIOUS SEQUENCE, AND ARE
                                            ;STILL ONE CLOCK AWAY FROM THE TIME WHEN NEW SEQUENCE
                                            ;IS TO BEGIN - SO JUST GET THE FLAG OUT OF THE WAY,
               BRA.S   SET_MIDI_TIMEOUT     ;MOVE ON NORMALLY - ON THE NEXT CLOCK, DOUBLE PRE-FETCH
                                            ;WILL BE DONE JUST AS THOUGH THE "PLAY" SWITCH HAD JUST
                                            ;BEEN HIT ....
;
EOC_C0
                                            ;NOT ON THE CUSP OF A RECORD-LOOPING STYLE CUE:
               CMP.L   #10000H,NOW_BAR      ;ARE WE AT THE VERY BEGINNING OF THE SEQUENCE?
               BNE.S   SET_MIDI_TIMEOUT     ;BRANCH IF NOT, NO OCCASION FOR DOUBLE-CLICK SERVICE.
;
               TST.B   NOW_REPEATING        ;SO WE'RE AT VERY START?  SO WHAT?
               BNE.S   SET_MIDI_TIMEOUT     ;IF IN A PLAYBACK REPEAT LOOP WHICH STARTS HERE,
                                            ;STILL DON' WAN' DO NUH FIRST-CLICK DUB'L CLICK-EY ....
;
;
;
; ELSE .... WE'RE STARTING INTO THE SEQUENCE, WE'RE ON THE FIRST CLICK.
; GET THE FIRST CLICK OUT ASAP, LOOP BACK AND DO ANOTHER RIGHT OFF:
;
               MOVE    #2300H,SR            ;BLOCK LEVEL 3 INTERRUPT WHILE WE CHANGE ITS ORDERS.
               MOVE    MA_SEQ_ADVANCE,D0    ;ARE WE SUPPOSED TO DELAY UART "A" SEQ EVENT XMIT?
               BGT.S   START_SLOW_1         ;BRANCH IF NOT, ELSE SET IT FOR IMMEDIATE DETONATION -
               MOVEQ   #1,D0                ;TO WIT: NEXT REALTIME INTERRUPT WILL COUNT THIS DOWN
                                            ;TO ZERO AND TRIGGER XMISSION OF THIS CLICK'S EVENTS.
START_SLOW_1
               MOVE    D0,MA_XMIT_SEQ_TIME  ;REALTIME FIRES UART "A" AFTER THIS NUMBER OF INTRPTS.
;
               MOVE    MB_SEQ_ADVANCE,D0    ;DO SAME THING FOR UART "B" ....
               BGT.S   START_SLOW_2
               MOVEQ   #1,D0
START_SLOW_2
               MOVE    D0,MB_XMIT_SEQ_TIME
               MOVE    #2000H,SR            ;WHEN DONE, RE-ENABLE LEVEL 3 INTERRUPT AND LET RIP.
;
;
               MOVE.L  SEQ_WR_PTR,A6        ;SET UP ADDRESS POINTERS FOR VARIOUS READ/WRITE SUBS,
               MOVE.L  SEQ1_DRD_PTR,A5
               MOVE.L  SEQ_NDRD_PTR,A4
               MOVE    WASTELAND_PTR,A3
;
               MOVE    NOW_MET_COUNT,MET_COUNT_DOWN   ;PROPERLY PREPARE METERDOME,
;
               BRA     EXEC_PHASE_VEC       ;AND HEAD BACK TO DEAL WITH NEXT CLICK RIGHT NOW.
;
;
;
;
;
; SEQUENCER SELF-STOP UNDER INTERNAL TIMEBASE OR CLICK SYNC:
; KILL IT DEAD - USER WILL HAVE TO HAND-START IT AGAIN.
;
KILL_IT_DEAD
               SF      XPORT_STATE               ;ERASE ALL SIGNS OF LIFE HERE.
               MOVE    #0F000H,LED_EXTINGUISH    ;THE LIGHTS ARE GOING OUT ....
               BSR     STOP_TC                   ;STOP DA CLOCKS (6803 SENDS MIDI "STOP").
               BSR     SEND_MIDI_STOP            ;SEND "STOP" VIA MIDI UARTS ENABLED FOR CLOCK-OUT.
               SF      PLAYED_TO_END             ;FORGET "ENDED" STATUS - NEXT TIME WE SEE THE
                                                 ;LIGHT OF DAY, WE'LL BE BORN-AGAINS ....
;
                                                 ;WE'RE DEAD, BUT MAY NEED TO TWITCH ONCE MORE -
                                                 ;FALL THRU TO SET TIMEOUT FOR MIDI EVENTS PARSED
                                                 ;DURING FINAL CLOCK PERIOD AND WAITING TO BE SENT.
;
;
;
;
;
; ON THE WAY OUT, (HONEY,) TELL REALTIME INTERRUPT WHEN EACH OF THE
; MIDI UARTS SHOULD BE LAUNCHED INTO TRANSMITTING THE DATA WE'VE LOADED
; INTO ITS TRANSMIT BUFFER DURING THIS CLOCK-SERVICE.
; BASICALLY WE USE THE AMOUNT OF TIME FROM NOW (PER OUR REALTIME CLOCK)
; AT WHICH THE NEXT LEVEL 2 INTERRUPT IS PROJECTED TO HIT, OFFSET BY ANY
; PER-UART TRANSMIT ADVANCE/DELAY SETTINGS IN EFFECT.
;
; UNDER NORMAL CONDITIONS IT IS POSSIBLE FOR US TO BE DOING THIS WHILE
; THE PREVIOUS CLICK'S MIDI BUFFER TIMEOUT IS STILL RUNNING.  THIS IS
; MOST LIKELY AT THE BEGINNING OF THE SEQUENCE, WHERE A RAPID-FIRE
; DOUBLE CLICK-SERVICE IS PERFORMED.  IN THIS CASE, THE TIMEOUT ALREADY
; RUNNING IS JAMMED TO MINIMUM SO THAT IT WILL END ON THE NEXT REALTIME
; INTERRUPT, WHILE THE NEW TIMEOUT (MINUS 1, TO COMPENSATE FOR THE
; DELAY) IS LEFT IN A BUFFER CELL WHERE IT CAN BE RETRIEVED AND PLUGGED
; IN AT THAT TIME BY THE REALTIME INTERRUPT HANDLER.
;
; UNDER ABNORMAL CONDITIONS (SUCH AS IN THE PRESENCE OF HUGE WADS OF
; MIDI DATA IN THE SEQUENCE, OR WHO KNOWS WHAT), CLICK SERVICE MAY GET
; BACKLOGGED TO THE POINT THAT, IN THE PROCESS OF GETTING CAUGHT UP TO
; WHERE IT SHOULD BE, THERE ARE MULTIPLE COLLISIONS OF SUCCESSIVE MIDI
; BUFFER TIMEOUTS.  IN THIS CASE - WHICH REPRESENTS SEVERE AND PROBABLY
; VERY NOTICEABLE OVERLOAD - THE ADDITIONAL TIMEOUTS ARE CONVERTED
; DIRECTLY INTO ADDITIONAL BUFFER DUMP REQUESTS, BYPASSING THE TIMEOUTS
; ALTOGETHER.  THIS GUARANTEES THAT NO BUFFER DUMPS GET MISSED.  AT THIS
; POINT, QUESTIONS OF PRECISE TIMING ARE IRRELEVANT - ONCE THE OVERLOAD
; IS PAST, EVERYTHING SHOULD FALL BACK INTO LINE.
;
; THERE'S BEEN SOME DISAGREEMENT OVER WHETHER A POSITIVE UART ADVANCE
; VALUE MEANS EVENTS HAPPEN SOONER OR LATER.  INITIALLY, THE LATTER WAS
; TRUE FOR THE 440, ALTHOUGH NOT SPECIFIED ANYWHERE IN ENGLISH (SUCH AS
; THE OPERATIONS MANUAL).  ALONG ABOUT VERSION 1.90, IN MY INFINITE
; ARROGANCE, I DECIDED THAT THIS WAS BACKWARDS, AND CHANGED IT.  NOBODY
; REALLY SEEMED TO MIND, OR EVEN TO NOTICE, THIS CHANGE.  AT LEAST, NOT
; THAT I HEARD ABOUT.  IF YOU'RE FEELING ARROGANT AND RIGHTEOUS TODAY,
; WHY NOT CHANGE IT AGAIN?  BEAR IN MIND THAT PERHAPS SOMEDAY THE 440
; WILL GET CHANGED TO A 96 PPQN SYSTEM, IN WHICH CASE THIS FEATURE WILL
; PRETTY MUCH BE OUT THE WINDOW ANYWAY (BASED, AS IT IS, UPON EXISTING
; RATHER LARGE 24 PPQN CLOCK INTERVALS).
;
SET_MIDI_TIMEOUT
               MOVE    #2700H,SR            ;BLOCK UARTS AND REALTIME INTERRUPT FROM USING AND
                                            ;CHANGING THESE VALUES WHILE WE'RE SETTING THEM UP.
;
;871008               MOVE    NEXT_TIME,D0         ;REALTIME PROJECTION OF NEXT SEQ CLOCK (LEVEL 2 INT)
;871008               SUB     REAL_TIME,D0         ;MINUS TIME RIGHT NOW TELLS US HOW LONG 'TILL THEN -
;871008               MOVE    D0,D1                ;SET UP A VALUE FOR EACH UART.
;871008               SUB     MA_XMIT_SEQ_TIME,D0  ;SUBTRACT ANY TIMEOUT CURRENTLY IN PROGRESS FOR EACH
;871008               SUB     MB_XMIT_SEQ_TIME,D1  ;UART, SINCE IT WILL BE THAT LONG BEFORE NEW TIMEOUTS
;871008                                            ;START RUNNING (THEY GET IN LINE BEHIND CURRENT ONES).
;871008;
;871008               SUB     MA_SEQ_ADVANCE,D0    ;SUBTRACT TRANSMIT-ADVANCE SETTINGS -
;871008               BGT.S   SMT_10               ;BRANCH IF RESULT IS POSITIVE - THAT'S LATER THAN NOW.
;871008               MOVEQ   #1,D0                ;ELSE, WE'RE RUNNING LATE - GET 'EM OFF NEXT REALTIME.
;871008SMT_10
;871008               SUB     MB_SEQ_ADVANCE,D1    ;SAME, FOR UART "B".
;871008               BGT.S   SMT_20
;871008               MOVEQ   #1,D1
;871008SMT_20
;871008;
;871008               TST     MA_XMIT_SEQ_TIME     ;IS ANOTHER BUFFER TIMEOUT IN LINE AHEAD OF US?
;871008                                            ;(NORMAL ON FIRST CLICK, BECAUSE OF DOUBLE-FETCH.)
;871008               BNE.S   SMT_30               ;BRANCH IF YES, PUT THIS TIMEOUT INTO QUEUE.
;871008               MOVE    D0,MA_XMIT_SEQ_TIME  ;ELSE, PUT IT INTO EFFECT RIGHT NOW.
;871008               BRA.S   SMT_40
;871008SMT_30
;871008               MOVE    D0,MA_TIME_BUFF
;871008;
;871008SMT_40
;871008               TST     MB_XMIT_SEQ_TIME     ;SAME, FOR UART "B".
;871008               BNE.S   SMT_50
;871008               MOVE    D1,MB_XMIT_SEQ_TIME
;871008               BRA.S   SMT_60
;871008SMT_50
;871008               MOVE    D1,MB_TIME_BUFF
;871008SMT_60
;
;
               MOVE    NEXT_TIME,D0         ;REALTIME PROJECTION OF NEXT SEQ CLOCK (LEVEL 2 INT)
               SUB     REAL_TIME,D0         ;MINUS TIME RIGHT NOW TELLS US HOW LONG 'TILL THEN -
               MOVE    D0,D1                ;SET UP A VALUE FOR EACH UART.
;
               SUB     MA_SEQ_ADVANCE,D0    ;SUBTRACT TRANSMIT-ADVANCE SETTING -
               BGT.S   SMT_20               ;BRANCH IF RESULT IS POSITIVE - THAT'S LATER THAN NOW.
               MOVEQ   #1,D0                ;ELSE, RUNNING LATE - GET IT OFF AT NEXT REALTIME.
SMT_20
               TST     MA_XMIT_SEQ_TIME     ;IS A PREVIOUS BUFFER DUMP TIMEOUT STILL RUNNING?
                                            ;(NORMAL ON FIRST CLICK, BECAUSE OF DOUBLE-FETCH.)
               BNE.S   SMT_40               ;BRANCH IF YES, MAKE SPECIAL ARRANGEMENTS FOR NEW ONE.
               MOVE    D0,MA_XMIT_SEQ_TIME  ;ELSE - THIS IS IT, START IT UP.
               BRA.S   SMT_A0               ;GO ON AND DEAL WITH UART "B" TIMEOUT.
;
SMT_40
               MOVE    #1,MA_XMIT_SEQ_TIME  ;ACCELERATE THE PREVIOUS BUFFER DUMP TIMEOUT.
               TST     MA_TIME_BUFF         ;ARE TWO PREVIOUS TIMEOUTS RUNNING ON THIS UART?
               BNE.S   SMT_80               ;BRANCH IF YES - SEVERE OVERLOAD, DUMP EVERYTHING ASAP.
               SUBQ    #1,D0                ;ELSE - ADJUST NEW TIMEOUT FOR PREVIOUS TIMEOUT DELAY,
               BGT.S   SMT_60               ;MAKE SURE IT DIDN'T GO TO ZERO,
               MOVEQ   #1,D0
SMT_60
               MOVE    D0,MA_TIME_BUFF      ;STORE THE NEW TIMEOUT FOR PICKUP BY REALTIME.
               BRA.S   SMT_A0               ;GO ON AND DEAL WITH UART "B" TIMEOUT.
;
SMT_80
               MOVE    #1,MA_TIME_BUFF      ;ACCELERATE SECONDARY BUFFER DUMP TIMEOUT,
               ADDQ    #1,MA_XMIT_SEQ_GATE  ;PUMP ONE DUMP REQUEST THRU ONTO THE "TIMED-OUT" PILE.
                                            ;FALL THROUGH AND DEAL WITH UART "B" TIMEOUT.
;
;
                                            ;CORRESPONDING PROCEDURE FOR UART "B":
SMT_A0
;
               SUB     MB_SEQ_ADVANCE,D1    ;SUBTRACT TRANSMIT-ADVANCE SETTING -
               BGT.S   SMT_C0               ;BRANCH IF RESULT IS POSITIVE - THAT'S LATER THAN NOW.
               MOVEQ   #1,D1                ;ELSE, RUNNING LATE - GET IT OFF AT NEXT REALTIME.
SMT_C0
               TST     MB_XMIT_SEQ_TIME     ;IS A PREVIOUS BUFFER DUMP TIMEOUT STILL RUNNING?
                                            ;(NORMAL ON FIRST CLICK, BECAUSE OF DOUBLE-FETCH.)
               BNE.S   SMT_E0               ;BRANCH IF YES, MAKE SPECIAL ARRANGEMENTS FOR NEW ONE.
               MOVE    D1,MB_XMIT_SEQ_TIME  ;ELSE - THIS IS IT, START IT UP.
               BRA.S   SMT_K0               ;GET ON OUTA HERE.
;
SMT_E0
               MOVE    #1,MB_XMIT_SEQ_TIME  ;ACCELERATE THE PREVIOUS BUFFER DUMP TIMEOUT.
               TST     MB_TIME_BUFF         ;ARE TWO PREVIOUS TIMEOUTS RUNNING ON THIS UART?
               BNE.S   SMT_I0               ;BRANCH IF YES - SEVERE OVERLOAD, DUMP EVERYTHING ASAP.
               SUBQ    #1,D1                ;ELSE - ADJUST NEW TIMEOUT FOR PREVIOUS TIMEOUT DELAY,
               BGT.S   SMT_G0               ;MAKE SURE IT DIDN'T GO TO ZERO,
               MOVEQ   #1,D1
SMT_G0
               MOVE    D1,MB_TIME_BUFF      ;STORE THE NEW TIMEOUT FOR PICKUP BY REALTIME.
               BRA.S   SMT_K0               ;GO ON AND GET LOST.
;
SMT_I0
               MOVE    #1,MB_TIME_BUFF      ;ACCELERATE SECONDARY BUFFER DUMP TIMEOUT,
               ADDQ    #1,MB_XMIT_SEQ_GATE  ;PUMP ONE DUMP REQUEST THRU ONTO THE "TIMED-OUT" PILE.
                                            ;FALL THROUGH AND BEGONE.
;
;
SMT_K0
;
;
               MOVE    #2000H,SR            ;UNBLOCK ALL INTERRUPTS, BACK OUT INTO TRAFFIC.
;
;
PRO_CLICK_EXIT
               RTS
;
;AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
               TITLE   "BAR-MARKER PROCESSING"
;VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV
;
; PLAYBACK PARSING HAS ENCOUNTERED A BAR-MARKER:
; IT SENDS US A FULL COPY IN D7(.L) TO DECODE AND DECANT.
; BASIC TASK-OLOGY:
;    *  -  DETERMINE NEW TIME SIGNATURE, PLUG IT IN.
;    *  -  DETERMINE TOTAL NUMBER OF CLOCKS IN THIS BAR, POST NOTICE.
;    *  -  DOWNLOAD ANY PENDING EDITS TO AUTOCORRECT STATE.
;    *  -  RESYNCHRONIZE RECORDING PHASE VECTOR SEQUENCE.
;    *  -  RESYNCHRONIZE AND RESTART METRONOME COUNTER.
;
; A BAR MARKER LOOKS LIKE THIS:
;
;              nnnn nnnn xddd 1000 bbbb bbbb bbbb bbbb
;
;            nnnnnnnn =    TIME SIGNATURE NUMERATOR (1-64 LEGAL).
;                 ddd =    TIME SIGNATURE DENOMINATOR -
;                          VALUES: 2-4-6-8-12-16-24-32 ENCODED AS 0-7.
;    bbbbbbbbbbbbbbbb =    BAR NUMBER (1-RELATIVE).
;
; NOTE - WE DO NOT PRESERVE D7!
;
BAR_MARKER_HANDLER
               MOVE    D7,NOW_BAR           ;UPDATE BAR NUMBER
;
               SWAP    D7                   ;GET AT UPPER WORD - ACTION WORD, AS FAR AS WE'RE CONCERNED
               MOVE    D7,D0                ; MAKE COPY
;
               LSR     #8,D0                ;ISOLATE NUMERATOR
               MOVE    D0,NOW_NUMERATOR
;
               AND     #0070H,D7            ;ISOLATE RAW DENOMINATOR
               LSR     #4,D7                ; POSITION...
               MOVE    D7,RAW_DENOMINATOR   ; ...AND SAVE
;
               LSL     #1,D7                ;CONVERT RAW_DENOM INTO A TABLE OFFSET
               MOVE    DENOM_DECODE(PC,D7),NOW_DENOMINATOR ;GET CODED DENOM VALUE
               MOVE    DENOM_CLICKS(PC,D7),D1    ;GET CLICKS THIS DENOM
               MOVE    D1,CLICKS_THIS_DENOM
               MULU    D0,D1                ;FIND CLICKS THIS BAR
               MOVE    D1,CLICKS_THIS_BAR
;
;
;
; THINGS WHICH OUGHT BE DONE WHEN LINING UP AT BEGINNING OF A BAR,
; EVEN THOUGH NO ACTUAL BAR-MARKER MAY BE INVOLVED -
; FOR EXAMPLE, WHEN STARTING/RESTARTING PLAYBACK, CUEING, WHAT-HAVE-YOU.
; TO WIT:  DOWNLOAD ANY PENDING EDITS TO AUTOCORRECT PARAMETERS (WHICH
; SHOULD OF COURSE NOT HAPPEN IN MID-BAR), RESYNCHRONIZE RECORDING PHASE
; VECTOR SEQUENCE, RESYNC/RESTART METRONOME.
;
OTRA_BAR_CHORES
               MOVE    NEW_PHASE_LEN,PHASE_LEN   ;COPY MOST RECENTLY SELECTED AUTOCORRECTS
               MOVE.L  NEW_PHASE_LIST,PHASE_LIST
;
;23JUN               MOVE    OFFSET_INDEX,NOW_PHASE    ;OTRA CHORES - RESET RECORDING PHASE STATE
               CLR     NOW_PHASE            ;METHINKS, AUTOCORRECT OFFSET IS ASKING A BIT MUCH ....
;
               CLR     NOW_CLICK            ;UPDATE CLICK NOMBRE
               MOVE    #1,MET_COUNT_DOWN    ;RESET METRONOME COUNTDOWN TO SOUND NEXT CLICK
               MOVE    MET_COUNT,NOW_MET_COUNT
               RTS
;
;
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 "BAR/BEAT DISPLAY MAINTENANCE"
;VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV
;
; COMPUTE CURRENT BEAT NUMBER - REQUEST SCREEN UPDATE IF CHANGE OCCURRED
; SINCE LAST CLICK.  DOES WHOMPERS ON D0.
;
BEAT_DISPLAY_BOY
               MOVE    NOW_CLICK,D0         ;COMPUTE NOW_BEAT AS NOW_CLICK/CLICKS_THIS_DENOM -
               BNE.S   BEATS_ME             ;BRANCH IF NOT CLICK 0 -
               MOVE    D0,NOW_BEAT          ;IF THIS BE CLICK 0, WHY THEN, MUST BE BEAT ONE -
               BRA.S   BEAT_UNO             ;THIS MINOR HOKUM GUARANTEES UPDATE, NO MATTER WHAT.
BEATS_ME
               SUBQ    #1,D0                ;ELSE - COMPENSATE FOR ALWAYS BEING ONE CLICK AHEAD OF
               EXT.L   D0                   ;AUDIBLE REALITY, THEN DO THE BEAT-COMPUTE THING -
               DIVU    CLICKS_THIS_DENOM,D0
BEAT_UNO
               ADDQ    #1,D0                ;BEATS COUNT UP FROM 1 (NOT 0), GET WITH THE PROGRAM.
               CMP     NOW_BEAT,D0          ;HAS BEAT NUMBER CHANGED SINCE LAST CLICK?
               BEQ.S   BEAT_OFF             ;IF NOT, DON'T UPDATE BEAT NUMBER OR DISPLAY.
               MOVE    D0,NOW_BEAT          ;ELSE, UPDATE VARIABLE (It's the NOW beat!) -
               TST.B   SHOWING_TEMPO        ;NONETHELESS, IF SHOWING TEMPO ....
               BNE.S   BEAT_OFF
               TST.B   SHOWING_FF_RW        ;.... OR DOING FAST_WIND, DON'T UPDATE DISPLAY.
               BNE.S   BEAT_OFF
                                            ;AGAIN, DON'T UPDATE DISPLAY IF WE WOULDN'T SEE IT -
                                            ;THE FOLLOWING ARE THE ONLY SCREENS IN WHICH WE WOULD:
               MOVE.L  CUR_SUB_BLOCK,D0
               CMP.L   #REC_TIME_SIG_SUB,D0
               BEQ.S   BEAT_ME_UP
               CMP.L   #SEQ_PLAYBACK_SUB,D0
               BEQ.S   BEAT_ME_UP
               CMP.L   #SONG_PLAYBACK_SUB,D0
               BNE.S   BEAT_OFF
BEAT_ME_UP
               ST      SUBFUN_INSTALL       ;BROOT FORCE DISPLAY UPDATE IN CASE BAR NUMBER ALSO
                                            ;CHANGED (SOMEDAY, GO DIRECT AND SAVE CPU TIME).
BEAT_OFF
               RTS
;
;AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
               TITLE   "METRONOME HANDLER"
;VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV
;
;             METRONOME HANDLER
;
MET_HANDLER
               SUBQ    #1,MET_COUNT_DOWN    ;CONTINUE COUNTDOWN TO NEXT CLICK
               BNE.S   EXIT_MET             ;IF NOT READY FOR ANOTHER, DONE FOR NOW
;
               MOVE    NOW_MET_COUNT,MET_COUNT_DOWN   ;REFRESH MET COUNTDOWN
;
               TST     RAW_MET              ;IF METRONOME OFF, FUCK OFF
               BEQ.S   EXIT_MET
;
               BTST    #RECORD_BIT,XPORT_STATE   ;IF NOT RECORDING, FUCK OFF
               BNE.S   METS_RULE
               BTST    #ERASE_BIT,XPORT_STATE    ;AHEM - OR ERASING ....
               BEQ.S   EXIT_MET
;
METS_RULE
               MOVE    #2700H,SR            ;BLOCK INTS WHILE DOING THIS
               BSET    #6,MISC_OUT_STAT
               TST     NOW_CLICK            ;IF FIRST CLICK, HEAVY MET ACCENT
               BNE.S   SOFT_CLICK
HARD_CLICK
               BCLR    #6,MISC_OUT_STAT     ;SET BIT FOR HARD MET HIT
SOFT_CLICK
               BCLR    #5,MISC_OUT_STAT     ;SET LOGIC FOR MET HIT
;
               MOVE.B  MISC_OUT_STAT,MISC_OUT    ;HIT THE METRONOME CIRCUIT
;
               MOVEQ   #15,D0
               ADD     METRO_TONE,D0        ;SET UP A USER-DEFINED TIMEOUT
UNCLICK_LOOP
               DBRA    D0,UNCLICK_LOOP
               BSET    #5,MISC_OUT_STAT     ;CLEAR MET
               MOVE.B  MISC_OUT_STAT,MISC_OUT
               MOVE    #2000H,SR            ;UNBLOCK INTS
;
EXIT_MET
               RTS
;
;AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
               TITLE   "ACCELERANDO/RITARDANDO EVENT-HANDLING - 'NORMAL' PLAYBACK"
;VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV
;
; CHECK FOR AN ACCELERANDO/RITARDANDO EVENT IMMEDIATELY FOLLOWING
; THE BAR-MARKER WE'VE JUST PROCESSED DURING PLAYBACK OR CUEING -
; IF THERE'S ONE IN THIS BAR, THIS IS WHERE IT'LL BE (SINCE EDITING OF
; A-R MARKS IMPOSES THIS REQUIREMENT, AND AFTER ALL, THEY DO NEED TO BE
; HARD BY THE BEGINNING OF THE BAR, SINCE THEY ARE IMPLEMENTED PER BAR).
;
; IF WE SEE ONE, WE COPY IT OVER TO THE NEW SEQUENCE BLOCK AND THEN
; PLUG IT IN TO TEMPO MACHINERY - WHERE A-R MAINTENANCE CALLS WILL
; NUDGE IT ALONG.
;
; NEED I STATE THE OBVIOUS?  WE'RE IN SOME SORT OF SEQUENCE-PARSING
; CONTEXT WHEN WE COME HERE - REGISTERS MUST BE HANDLED WITH ALL DUE
; RESPECT AND CARE, SEQUENCE-PARSING PARK RULES MUST BE OBSERVED -
; WE DON'T TRY TO PRESERVE REGISTERS, THAT WOULD BE UNFRIENDLY.
;
CHECK_FOR_A_R_MARK
               MOVE    0(A5),D0             ;SEE IF NEXT EVENT IS AN ACCELRANDO/RITARDANDO -
               AND     #0FH,D0              ;PREVIEW IT WITHOUT ADVANCING SEQUENCE READ PROCESS.
               CMP     #0BH,D0              ;WELL?
               BNE.S   CHK_A_R_EXIT         ;BRANCH IF NOT, GET THE HELL OUTA HERE.
;
               BSR     SEQ1_DSTR_READ       ;COPY A-R MARK OVER RIGHT NOW - A-R EDITING ASSUMES
               BSR     SEQ_WRITE            ;THAT ANY A-R WILL APPEAR RIGHT BEHIND ITS BAR MARKER.
               SWAP    D7                   ;SHIFT FIRST WORD ASIDE, READ AND TRANSFER SECOND WORD.
               BSR     SEQ1_DSTR_READ
               BSR     SEQ_WRITE
                ABS_LONG
               JSR     START_ACC_RIT        ;PUT THIS A-R INTO EFFECT RIGHT AWAY, GET GOING.
                ABS_SHORT
;
CHK_A_R_EXIT
               RTS
;
;AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
               TITLE   "PLAYBACK REPEAT-LOOP START REMEMBER/RESTORE"
;VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV
;
; FREEZE-FRAME FOR SEQUENCER STATUS AT START OF PLAYBACK REPEAT LOOP:
; SAVE EVERYTHING WE NEED TO BE ABLE TO EXACTLY REPRODUCE CONDITIONS AT
; THE START OF THE REPEAT LOOP WHEN WE SKIP BACK TO IT.
;
; AT THE RISK OF "REPEATING" MYSELF (SORRY!) - THE CALL
; TO REPEAT_SNAPSHOT MUST BE DONE BEFORE WE COPY ANY
; PART OF THE BAR-MARKER OVER TO WRITE BLOCK, SO THAT IT
; IS POSSIBLE TO SAVE THE ADDRESS AT WHICH IT WILL BE
; WRITTEN, AND REPEAT_REPLAY CAN FIND IT AGAIN LATER -
; AFTER COPY-OVER, WE CANNOT EASILY DETERMINE WHERE THE
; DAMN THING WENT.
;
REPEAT_SNAPSHOT
               MOVE    CUR_TEMPO_USEC,RP_ST_CUR_TEMP       ;STASH CURRENT TEMPO,
               MOVE    CUR_T_BPM_8,RP_ST_CUR_T_8           ;STASH HIGH-RES VERSION OF SAME,
               MOVE    REF_TEMPO_USEC,RP_ST_REF_TEMP       ;STASH CURRENT REFERENCE TEMPO.
               MOVE    ACCEL_RIT_B_LEFT,RP_ST_AR_B_LFT     ;STASH CURRENT ACCELERANDO/RITARDANDO
               MOVE    ACCEL_RIT_DELTA,RP_ST_AR_DELTA      ;WALK BACK INTO THE MIDDLE OF AN A/R IF
               MOVE    ACCEL_RIT_REM,RP_ST_AR_REM          ;ONE EXTENDS ACROSS LOOP START BOUNDARY.
               MOVE    MA_SEQ_ADVANCE,RP_ST_MA_ADV         ;STASH MIDI-OUT UART ADVANCE SETTINGS.
               MOVE    MB_SEQ_ADVANCE,RP_ST_MB_ADV
;
                                                 ;RECORD SEQUENCE MEMORY LOOP PLAYBACK START POINT:
               MOVE    SEQ_WR_BLK,RPT_START_BLK  ;STASH SEQ_WRITE PARAMETERS -
               MOVE    SEQ_WR_CNT,RPT_START_CNT  ;THIS IS WHERE REPEAT-START BAR MARKER WILL GO.
               MOVE.L  A6,RPT_START_PTR          ;A6 CONTAINS CURRENT WRITE POINTER (SEQ_WR_PTR),
                                                 ;SINCE WE'RE IN  MID-CLICK -
               SUBQ.L  #2,RPT_START_PTR     ;NOTCH THE POINTER DOWN, SINCE NON-DESTRUCTIVE READ
                                            ;INCREMENTS POINTER BEFORE READING DATA.
;
                ABS_LONG
               JSR     STASH_OLD_MIDI_ONS   ;TAKE A SNAPSHOT OF SEQUENCER MIDI NOTES CURRENTLY ON.
               JSR     STASH_OLD_PAD_ONS    ;TAKE A SNAPSHOT OF SEQUENCER PAD NOTES CURRENTLY ON.
                ABS_SHORT
;
               ST      READY_TO_RPT         ;FLAG "READY TO REPEAT" STATUS.
               RTS
;
;AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
;
;
;
;VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV
;
; REPLAY ROUTINE - BACK TO THE START OF THE PLAYBACK REPEAT LOOP:
; RESTORE ALL STATUS WHICH WAS IN EFFECT AT THE TIME WE FIRST CROSSED
; LOOP START BOUNDARY.
;
REPEAT_REPLAY
               MOVE    RP_ST_CUR_TEMP,CUR_TEMPO_USEC       ;RESTORE TEMPO VARIABLES.
               MOVE    RP_ST_CUR_T_8,CUR_T_BPM_8
               MOVE    RP_ST_REF_TEMP,REF_TEMPO_USEC
               MOVE    RP_ST_AR_B_LFT,ACCEL_RIT_B_LEFT     ;RESTORE ACCEL/RITARD VARIABLES.
               MOVE    RP_ST_AR_DELTA,ACCEL_RIT_DELTA
               MOVE    RP_ST_AR_REM,ACCEL_RIT_REM
               MOVE    RP_ST_MA_ADV,MA_SEQ_ADVANCE         ;RESTORE MIDI-OUT UART ADVANCE SETTINGS.
               MOVE    RP_ST_MB_ADV,MB_SEQ_ADVANCE
                ABS_LONG
               JSR     USEC_TO_ALL                         ;UPDATE ALL OTHER TEMPO VARIABLES.
                ABS_SHORT
;
                ABS_LONG
               JSR     M_WIPE_AND_FLUSH     ;TRANSMIT "OFFS" FOR ALL SEQUENCER MIDI NOTE-ONS,
                                            ;FLUSH THEM OUT OF THE NOTES-ON BUFFER.
               JSR     P_WIPE_AND_FLUSH     ;TRANSMIT "OFFS" FOR ALL SEQUENCER PAD NOTE-ONS,
                                            ;TURN OFF THE VOICES VIA VOICE HANDLER,
                                            ;FLUSH THEM OUT OF THE NOTES-ON BUFFER.
               JSR     MIDI_UNSTASH         ;REACTIVATE MIDI NOTE-ONS STASHED AT REPEAT LOOP START.
               JSR     PADS_UNSTASH         ;REACTIVATE PAD NOTE-ONS STASHED AT REPEAT LOOP START.
                ABS_SHORT
;
                                                      ;RESTORE SEQUENCE MEMORY PLAYBACK POINTER:
               MOVE    RPT_START_BLK,SEQ_NDRD_BLK     ;AIM NON-DESTRUCTIVE READ AT LOOP-START
               MOVE    RPT_START_CNT,SEQ_NDRD_CNT     ;BAR-MARKER,
               MOVE.L  RPT_START_PTR,A4
               BSR     SEQ_NDSTR_READ                 ;PULL THAT BAR MARKER INTO D7.L -
               SWAP    D7                             ;BE READY FOR BAR_MARKER_HANDLER.
               BSR     SEQ_NDSTR_READ
;
               ST      NOW_REPEATING        ;FLAG NON-DESTRUCTIVE PLAYBACK NOW IN PROGRESS.
               RTS
;
;AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
               TITLE   "AUTOMATED BAR/CLICK-BASED PUNCH-IN/OUT WHILE SEQUENCER RUNNING"
;VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV
;
; BAR/CLICK-BASED TESTS FOR PUNCH-IN/PUNCH-OUT WHILE SEQUENCER RUNNING -
; I.E., THIS IS INTENDED FOR USE BY PRO_CLICK.
; NOTE:  YOU COULD GET AWAY WITH CALLING HERE FROM ELSEWHERE -
; AS LONG AS SEQUENCE READ/WRITE POINTERS HAVE BEEN STORED BACK TO RAM
; BEFORE CALLING HERE (THIS IS WHAT PRO_CLICK DOES ....)
;
; NOTE - USER MANUAL PUNCH-IN/OUT WHILE RUNNING SETS USER_PUNCHED(.B),
; DEFEATING ALL AUTOMATED PUNCH-IN/OUT UNTIL SEQUENCER IS STOPPED.
;
; IF WE PASS ALL TESTS AND PUNCH-IN IS ACTUALLY DONE, THE SMPTE-FORMAT
; PUNCH-IN TIME IS UPDATED TO EQUAL OUR CURRENT INTERNAL SMPTE TIME.
; THE CORRESPONDING ACTION IS TAKEN WITH RESPECT TO PUNCH-OUT TIME.
; THIS ALLOWS THE EFFECTIVE PUNCH-IN/OUT POINTS TO REMAIN UNCHANGED IN
; THE EVENT THAT USER SWITCHES TO SMPTE-BASED PUNCH-IN/OUT.
; IT ALSO MEANS THAT THE 440 CAN PROVIDE A DIRECT READOUT OF SMPTE TIME
; EQUIVALENT TO ANY GIVEN BAR/CLICK VALUE IN THE SEQUENCE, BY SETTING
; PUNCH-IN TO THE SPECIFIC BAR/CLICK, ROLLING THROUGH THAT POINT WITH
; RECORD OR ERASE ENABLED, AND THEN VIEWING THE NEW SMPTE PUNCH-IN TIME.
; THIS VALUE IS ACCURATE ONLY TO THE FRAME LEVEL, HOWEVER.
; NOTE THAT THIS TIME TRANSCRIPTION IS NOT DONE IF THE 440 IS SYNC'ED TO
; MIDI OR CLICKS, SINCE SMPTE TIME IS UNDEFINED IN THESE MODES.
; ALSO NOTE THAT OVERALL SYSTEM LIMITS FOR THE SETTING OF SMPTE-TIME
; PUNCH-IN/OUT POINTS REFLECT THE POSSIBILITY OF 24 FRAME/SEC SMPTE -
; WE STICK TO THEM HERE FOR BREVITY'S SAKE.
;
; MAJOR IMPORTANT WARNING:  IMPLICIT IN THE FOLLOWING ROUTINES IS THAT
; PUNCH-OUT POINT IS ALWAYS LATER THAN PUNCH-IN POINT - EVEN BEING EQUAL
; IS TO BE CONSIDERED UNCOOL (MAJOR UNCOOL) - DON'T LET IT HAPPEN!
;
; ALWAYS DESTROYS D0-D1, PLUS POSSIBLE OTHERS IF PUNCH-IN/OUT IS DONE.
;
AUTO_BAR_PUNCH
               TST.B   USER_PUNCHED         ;USER PUNCHED-IN/OUT BY HAND RECENTLY?
               BNE     AUTO_BP_EXIT         ;EXIT IF YES, IGNORE PUNCH-IN/OUT POINTS.
               MOVE.B  XPORT_STATE,D0                 ;SEE WHAT'S GOING ON UP THERE -
               AND     #RECORD_MASK+ERASE_MASK,D0     ;IS RECORD OR ERASE ENABLED?
               BEQ     AUTO_BP_EXIT                   ;EXIT WITHOUT ACTION IF NEITHER ENABLED.
;
               TST.B   BAR_OR_SMPTE_FLAG    ;TEST BASED ON BAR/CLICK OR SMPTE TIME?
               BNE     AUTO_BP_EXIT         ;RETURN IF PUNCH-IN/OUT KEYED TO SMPTE TIME.
;
               MOVE.L  NOW_BAR,D0           ;LOAD CURRENT BAR/CLICK.
               MOVE.B  RECORDING,D1         ;SEE IF WE'RE ALREADY PUNCHED IN -
               OR.B    ERASING,D1
               BNE.S   AUTO_BP_20           ;YES WE ARE, GO DO PUNCH-OUT TESTS.
;
               CMP.L   PUNCH_IN_BAR,D0      ;PUNCH-IN TEST - HOW DOES "NOW" STACK UP TO "WHEN"?
               BNE     AUTO_BP_EXIT         ;EXIT IF NOT MATCHED - WE'RE EITHER BEFORE PUNCH-IN
                                            ;POINT, OR PAST BOTH PUNCH-IN AND PUNCH-OUT POINTS.
               CMP     #2,CLOCK_IN_MODE     ;PERFECT MATCH, GONNA PUNCH IN - WHAT'S CLOCK-IN MODE?
               BEQ     PUNCH_IN_NOW         ;BRANCH IF MIDI CLOCK IN, SMPTE TIME IS UNDEFINED.
               CMP     #3,CLOCK_IN_MODE     ;NOT MIDI SYNC, HOW ABOUT CLICK SYNC?
               BEQ     PUNCH_IN_NOW         ;BRANCH IF YES, SMPTE TIME UNDEFINED IN THIS MODE ALSO.
;
               CMP.L   #SMPTE_PIN_SUB,CUR_SUB_BLOCK   ;ELSE, SMPTE PUNCH-IN TIME WILL BE UPDATED -
               BNE.S   AUTO_BP_10                     ;BRANCH IF CHANGE NOT IMMEDIATELY VISIBLE,
               ST      SUBFUN_INSTALL                 ;ELSE REQUEST SCREEN UPDATE.
AUTO_BP_10
               MOVE.L  SMPTE_NOW_HR,D0      ;UPDATE SMPTE PUNCH-IN TIME TO "NOW".
               MOVE.L  D0,SMPTE_P_I_HR
               CMP.L   SMPTE_P_O_HR,D0      ;NEW SMPTE PUNCH-IN LATER THAN CURRENT SMPTE PUNCH-OUT?
               BCS     PUNCH_IN_NOW         ;CLEARLY NOT - WE'RE COOL, JUST GO PUNCH IN.
               MOVE.L  #173B3B17H,SMPTE_P_O_HR   ;ELSE, SET SMPTE PUNCH-OUT TIME TO MAXIMUM -
                                                 ;NAMELY, 23:59:59:23 - THE END OF THIS DAY.
               CMP.L   SMPTE_P_O_HR,D0      ;NEW SMPTE PUNCH-IN EARLIER THAN NEW PUNCH-OUT?
               BCS     PUNCH_IN_NOW         ;BRANCH IF YES, SYS REQUIREMENTS MET - GO PUNCH IN.
               MOVE.L  #173B3B16H,SMPTE_P_I_HR   ;ELSE, SET SMPTE PUNCH-IN ONE FRAME BELOW MAX -
                                                 ;NAMELY, 23:59:59:22 - ALMOST THE END OF THIS DAY.
               BRA     PUNCH_IN_NOW              ;NOW GO PUNCH IN.
;
;
;
AUTO_BP_20
               CMP.L   PUNCH_OUT_BAR,D0     ;PUNCH-OUT TEST - HOW DOES "NOW" STACK UP TO "WHEN"?
               BNE.S   AUTO_BP_EXIT         ;EXIT IF NOT MATCHED - WE'RE EITHER BEFORE PUNCH-OUT
                                            ;POINT, OR ELSE WE - OOPS! - MISSED PUNCH-OUT POINT.
               CMP     #2,CLOCK_IN_MODE     ;PERFECT MATCH, GONNA PUNCH OUT - WHAT'S CLOCK-IN MODE?
               BEQ.S   AUTO_BP_OUT          ;BRANCH IF MIDI CLOCK IN, SMPTE TIME IS UNDEFINED.
               CMP     #3,CLOCK_IN_MODE     ;NOT MIDI SYNC, HOW ABOUT CLICK SYNC?
               BEQ.S   AUTO_BP_OUT          ;BRANCH IF YES, SMPTE TIME UNDEFINED IN THIS MODE ALSO.
;
               CMP.L   #SMPTE_POUT_SUB,CUR_SUB_BLOCK  ;ELSE, SMPTE PUNCH-OUT TIME WILL BE UPDATED -
               BNE.S   AUTO_BP_30                     ;BRANCH IF CHANGE NOT IMMEDIATELY VISIBLE,
               ST      SUBFUN_INSTALL                 ;ELSE REQUEST SCREEN UPDATE.
AUTO_BP_30
               MOVE.L  SMPTE_NOW_HR,D0      ;ELSE, UPDATE SMPTE PUNCH-OUT TIME TO "NOW".
               MOVE.L  D0,SMPTE_P_O_HR      ;STORE PROVISIONAL NEW SMPTE PUNCH-OUT TIME -
               CMP.L   SMPTE_P_I_HR,D0      ;IS THIS TIME LATER THAN CURRENT SMPTE PUNCH-IN TIME?
                                            ;(REMEMBER - AT HIGH TEMPI, UP TO FOUR CLICKS MAY OCCUR
                                            ;WITHIN THE SPACE OF ONE SMPTE FRAME ....)
               BHI.S   AUTO_BP_OUT          ;BRANCH IF YES, GAW HAID AND PUNCH OUT.
               ADDQ.B  #1,D0                ;ELSE, MANICURE IT - BUMP FRAMES UP BY ONE.
               CMP.B   #24,D0               ;TOO HIGH (FOR 24 FRAMES/SEC)?
               BCC.S   AUTO_BP_40           ;BRANCH IF YES, THE SAGA CONTINUES ....
               MOVE.B  D0,SMPTE_P_O_HR+3    ;NO - SAME SECOND, STORE NEW FRAME AND GO PUNCH OUT.
               BRA.S   AUTO_BP_OUT
AUTO_BP_40
               SF      SMPTE_P_O_HR+3       ;WRAP FRAME NUMBER,
               ADDQ.B  #1,SMPTE_P_O_HR+2    ;BUMP SECONDS -
               CMP.B   #60,SMPTE_P_O_HR+2   ;TOO HIGH?
               BCS.S   AUTO_BP_OUT          ;BRANCH IF NOT, GO PUNCH OUT.
               SF      SMPTE_P_O_HR+2       ;ELSE - WRAP SECONDS,
               ADDQ.B  #1,SMPTE_P_O_HR+1    ;BUMP MINUTES -
               CMP.B   #60,SMPTE_P_O_HR+1   ;TOO HIGH?
               BCS.S   AUTO_BP_OUT          ;BRANCH IF NOT, GO PUNCH OUT.
               SF      SMPTE_P_O_HR+1       ;ELSE - WRAP MINUTES,
               ADDQ.B  #1,SMPTE_P_O_HR      ;BUMP HOURS - ASSUME A VALID HOUR (IT'S GETTING LATE!).
                                            ;NOW FALL THROUGH AND PUNCH OUT, ALREADY.
;
AUTO_BP_OUT
               BSR     AUTO_PUNCH_OUT       ;DO THE "OUT" THING.
;
AUTO_BP_EXIT
               RTS
;
;AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
               TITLE   "SEQUENCE-MEMORY-FULL TEST/HANDLING"
;VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV
;
; TEST TO SEE IF SEQUENCE MEMORY IS FULL -
; CALL AFTER EVERY WRITE OF A WORD (NEW OR OLD) INTO SEQUENCE, NATURALLY
; NOT INCLUDING PLAYBACK REPEAT LOOPING FOR WHICH RECORD IS NOT ALLOWED.
;
; ACTUALLY, TESTS SEQ_MEM_FULL FLAG, WHICH COMES ON WHEN WE ARE DOWN TO
; ONE FREE MEMORY BLOCK - SINCE ALMOST EVERYTHING WE DO WITH A SEQUENCE
; DEPENDS UPON HAVING AT LEAST ONE FREE BLOCK.
; IF FLAG IS SET AND RECORD MODE IS ACTIVE, WE KILL RECORD MODE.
;
SEQ_MEM_CHECK
               TST.B   SEQ_MEM_FULL         ;FULL, MEEBEEE?
               BEQ.S   SMC_EXIT             ;IF NOT, RETURN WITHOUT MUCH ADO.  NONE, ACTUALLY.
               TST.B   RECORDING            ;SO WE'RE FULL.  ARE WE RECORDING?
               BEQ.S   SMC_EXIT             ;IF NOT, WE DON'T GIVE A PHCUK.  PHUCK, I MEAN.
               MOVE.L  A4,SEQ_NDRD_PTR      ;WHOOPS, GOTTA STOP - STORE ALL READ/WRITE POINTERS.
               MOVE.L  A5,SEQ1_DRD_PTR
               MOVE.L  A6,SEQ_WR_PTR
               MOVEM.L D0-D7/A0-A3,-(A7)    ;PROTECT ALL OTHER REGISTERS.
               BSR     MANUAL_PUNCH_OUT     ;GO STRAIGHT FOR THE THROAT - NO MR. NICE-GUY SHIT.
               MOVEM.L (A7)+,D0-D7/A0-A3    ;BRING REGISTERS BACK,
               MOVE.L  SEQ_NDRD_PTR,A4      ;RESTORE READ/WRITE POINTERS (PROBABLY CHANGED),
               MOVE.L  SEQ1_DRD_PTR,A5
               MOVE.L  SEQ_WR_PTR,A6
                                            ;GO ON AS IF NOTHING EVER HAPPENED .... HEH HEH ....
SMC_EXIT
               RTS
;
;AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
               TITLE   "SEQUENCE RECORD PHASE VECTOR ROUTINES"
;VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV
;
; THE PHASE VECTORS, THEMSELVES.
;
; LEMME MAKE THIS CLEAR, RIGHT UP FRONT - PHASE VECTOR TABLES IN THE
; MODULE CALLED PHASES (WHAT ELSE?) ARE BUILT FROM WORD-LENGTH ENTRIES,
; ASSUMING THAT PHASE VECTORS ARE IN THE ABS_SHORT RANGE - GOT IT?
; OKAY, BACK TO YOU, CHRIS ....
;
; LET ME EXPLAIN PHASES.  THERE ARE 5, AND THEY DESCRIBE THE ACTIONS THE SEQUENCE
;  RECORDER DOES PER CLICK:
;
;  PHASE 0 - COPY ANY BUFFERED EVENTS TO NEW MEMORY BLOCK, PRECEEDED BY A TIME MARK
;          (IF NEEDED).  SET UP FOLLOWING OLD EVENTS TO GO TO THE NEW BLOCK.  IF ANYTHING
;          NEW COMES IN, COPY THEM TO THE HOLDING PEN.
;
;  PHASE 1 - pre-correct.  DIRECT OLD EVENTS AND NEW NON-NOTES TO THE NEW BLOCK.
;          DIRECT NEW NOTES TO THE BUFFER (HOLDING FOR THE AUTOCORRECT INTERVAL).
;
;  PHASE 2 - correct.  IF ANYTHING BUFFERED, COPY TIME MARK AND THESE EVENTS TO THE
;          NEW MEMORY BLOCK.  AFTERWARDS, COPY ANY OLD EVENTS AND ANY NEW NON-NOTES
;          TO THE BUFFER, AND NEW NOTES TO THE NEW BLOCK (STUFFING ALL WITHIN THE
;          AUTOCORRECT WINDOW TO THE SAME POINT IN TIME).
;
;  PHASE 3 - post-correct.  COPY OLD EVENTS AND ANY NEW NON-NOTES TO THE BUFFER (WITH
;          TIME MARKS).  COPY ANY NEW NOTES TO THE NEW BLOCK - WE ARE PILING STUFF UP
;          ON AN AUTOCORRECT BOUNDRY.
;
;  PHASE 4 - clean-up.  COPY BUFFER TO NEW MEM BLOCK.  AFTERWARDS, COPY OLD EVENTS
;          AND ANY NEW NON-NOTES TO THE NEW BLOCK, AND ANY NEW NOTES TO THE BUFFER.
;
; THERE IS A SLIGHT MENTAL TWIST INVOLVED, IN THAT OLD EVENTS ARE PRE-FETCHED BY A
;  CLICK.  THAT MEANS A PHASE SETS UP WHAT HAPPENS TO THE OLD EVENTS ON THE NEXT
;  CLICK.
;
; IN GENERAL, THE PHASES HAVE BEEN SET UP TO BE SLIGHTLY MORE FORGIVING IF THE USER
;  IS BEHIND THE BEAT (WE ARE IN CALIFORNIA, AFTER ALL).
;
; MAIN ACTIONS OF PHASES INCLUDE COPYING STUFF OVER, LOADING THE VECTORS NOTE_REC_PARSE
;  AND OTRA_REC_PARSE FOR TELLING MIDI DATA WHERE TO GO, AND THE VECTOR PAD_REC_PARSE
;  TO TELL PAD HITS WHERE TO GO.
;
; WHAT WE DO HERE IS ANY LIST-COPYING NEEDED, AND SETTING UP VECTORS OF WHERE THE
;  VARIOUS INFORMATION GETS STORED.
;
; LATE ADDITION (WAY LATE) - IF CURRENTLY IN THE NON-DESTRUCTIVE READ
; MODE OF REPEAT-LOOP PLAYBACK (AS INDICATED BY FLAG NOW_REPEATING),
; ALL DATA-MOVEMENT FUNCTIONS OF THE PHASE ROUTINES ARE SUPPRESSED -
; IN FACT, IN THIS CONTEXT PHASE ROUTINES SERVE MAINLY TO SUPPORT
; AUTOREPEAT FUNCTIONS - HOWEVER, WE KEEP THE VECTORS THEMSELVES CURRENT
; OUT OF WHAT AMOUNTS TO A SORT OF DUMB, BRUTE, ANIMAL FEAR ....
;
;AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
;
;
;
PHASE_0        ;jam
               CLR     LAST_PHASE           ;SAY WHAT PHASE WE BE IN.
               TST.B   NOW_REPEATING        ;ARE WE IN NON-DESTRUCTIVE LOOP PLAYBACK MODE?
               BNE.S   PINK_1               ;IF SO, SKIP DATA MOVE STUFF, GO VISIT THE PINK ONE.
               TST     WASTELAND_DEPTH      ;ELSE, SEE IF ANY BUFFERED EVENTS NEED COPYING -
               BEQ.S   PINK_1               ;    IF NOT, JUST CHANGE PHASE VECTORS
               TST.B   WROTE_NEW_TIME       ;         ELSE, COPY - NEED A TIME MARK?
               BNE.S   PINK_2               ;         IF WROTE SOME FORM OF TIME_MARKER WHEN PRE-
               MOVE    NOW_CLICK,D7         ;CREATE OUR OWN TIME_MARKER
               LSL     #4,D7
               OR      #9,D7
               BSR     SEQ_WRITE            ;WRITE NEW TIME-MARKER TO PROCEED NEW DATA
               ST      WROTE_NEW_TIME
PINK_2
               BSR     WASTELAND_COPY       ;COPY BUFFERED EVENTS TO NEW BLOCK
PINK_1
               MOVE    #SEQ_WRITE,OLD_SEQ_WRITE  ;EXISTING EVENTS ARE COPIED DIRECTLY OVER.
;
               MOVE    #WASTELAND_WRITE,MIDI_ON_WRITE ;MIDI NOTE-ONS ARE BUFFERED.
;
               MOVE    #TIMED_WASTE_WRITE,NON_NOTE_WRITE   ;NEW NON-NOTES ALSO GO TO THE BUFFER,
                                                           ; WITH A TIME MARKER IF NO OLD EVENTS
                                                           ; THIS CLICK.
;
               MOVE    #TIMED_WASTE_WRITE,NOTE_OFF_WRITE   ;NOTE OFFS TREATED LIKE NOTE ONS
               MOVE    #TIMED_SEQ_WRITE,PAD_ON_WRITE       ;LIE TO PADS - AUTOCORRECT WRITES DIFFERENTLY
               MOVE.L  A6,SEQ_WR_PTR        ;SAVE ADDRESS POINTERS FOR VARIOUS READ/WRITE SUBS
               MOVE.L  A5,SEQ1_DRD_PTR
               MOVE    A3,WASTELAND_PTR
;
               BSR     PAD_OFF_AUTOREPEAT   ;AUTO OFF (DON'T CHECK AUTORPT_FLAG FIRST - USER MAY HAVE
               BSR     AUTO_OFF_MIDI        ; TURNED OFF BEFORE WE PERFORMED THE OFFS FOR ONS EARLIER).
               BSR     FTPAD_OFF_AUTORPT    ;DON'T FORGET FOOTSWITCHES, HEY.
;
               MOVE.L  SEQ_WR_PTR,A6        ;SET UP ADDRESS POINTERS FOR VARIOUS READ/WRITE SUBS
               MOVE.L  SEQ1_DRD_PTR,A5
               MOVE    WASTELAND_PTR,A3
               MOVE    #WASTELAND_WRITE,PAD_ON_WRITE  ;SET UP FOR NEW PADS TO BE BUFFERED 'TILL AUTO-C
;
               TST.B   SINGLE_STEP          ;ARE WE SINGLE STEPPING?
               BEQ.S   EXIT_PHASE_0         ;BRANCH IF NOT, WE'RE THROUGH -
               BSR     SNGL_STEP_PAUSE      ;ELSE INVOKE PAUSE VIA SPECIAL SINGLE-STEP HOOK.
;
EXIT_PHASE_0
               RTS
;
;
;
;
;
PHASE_1        ;pre-correct
               MOVE    #1,LAST_PHASE             ;SAY WHAT PHASE WE BE IN.
               MOVE    #SEQ_WRITE,OLD_SEQ_WRITE  ;SET UP FOR NEXT OLD EVENTS TO GO TO NEW BLOCK TO
;
               MOVE    #TIMED_SEQ_WRITE,NON_NOTE_WRITE     ;NEW NON-NOTES TO THE NEW BLOCK, WITH
                                                           ; THE DISTINCTION THAT THEY GET A TIME
                                                           ; MARK IF NO OLD EVENTS THIS CLICK.
;
               MOVE    #WASTELAND_WRITE,A0  ;SET UP FOR NEW NOTES TO BE BUFFERED 'TILL AUTOCORRECT
               MOVE    A0,MIDI_ON_WRITE
               MOVE    A0,PAD_ON_WRITE
               MOVE    A0,NOTE_OFF_WRITE    ;NOTE OFFS BEFORE INTERVAL GET MOVED TO INTERVAL
               RTS
;
;
;
;
;
; PHASE 2:  NOTE - MUST HAVE A TIME_ OR BAR_MARKER WRITTEN HERE, 'CAUSE NEW STUFF COMING IN ON
;  LATER CLICKS WILL BE WRITTEN STRAIGHT TO NEW RAM.  THUSLY, PLACE ONE IF ONE NOT WRITTEN.
;  RUNNING ACROSS A TIME_MARKER WITH NOTHING BEHIND IT WILL NOT KILL US, AND WILL NOT CHEW UP RAM
;  TOO MAJORLY.
;
PHASE_2        ;correct
               MOVE    #2,LAST_PHASE        ;SAY WHAT PHASE WE BE IN.
               TST.B   NOW_REPEATING        ;ARE WE IN NON-DESTRUCTIVE LOOP PLAYBACK MODE?
               BNE.S   PINK_3               ;IF SO, SKIP DATA MOVE STUFF, GO VISIT THE PINK THREE.
               TST.B   WROTE_NEW_TIME       ;         ELSE, COPY - NEED A TIME MARK?
               BNE.S   PINK_4               ;         IF WROTE SOME FORM OF TIME_MARKER WHEN PRE-
                                            ;         FETCHING THIS CLICK (ALST TIME THROUGH), DON'T
               MOVE    NOW_CLICK,D7         ;              ELSE, CREATE OUR OWN TIME_MARKER
               LSL     #4,D7
               OR      #9,D7
               BSR     SEQ_WRITE            ;WRITE NEW TIME-MARKER TO PROCEED NEW DATA
               ST      WROTE_NEW_TIME
PINK_4
               BSR     WASTELAND_COPY       ;COPY BUFFERED EVENTS TO NEW BLOCK
PINK_3
               MOVE    #SEQ_WRITE,A0        ;AFTERWARDS, NEW NOTES TO THE NEW BLOCK
               MOVE    A0,MIDI_ON_WRITE
               MOVE    A0,PAD_ON_WRITE
;
;
               MOVE    #WASTELAND_WRITE,OLD_SEQ_WRITE
               MOVE    #TIMED_WASTE_WRITE,NON_NOTE_WRITE   ;NEW NON-NOTES ALSO TO THE BUFFER, WITH
                                                           ; TIME MARKS (IF NO OLD EVENTS ON THE CLICK
                                                           ; ON WHICH THEY COME IN).
               MOVE    #TIMED_WASTE_WRITE,A0 ;NOTE OFFS AFTER INTERVAL DO NOT GET SHIFTED
               TST     AC_TYPE              ;IF AUTOCORRECTING EVERYTHING
               BEQ.S   GNOME_1
               MOVE    #SEQ_WRITE,A0        ;    THEN DO AS NOTE ONS
GNOME_1
               MOVE    A0,NOTE_OFF_WRITE
;
               TST.B   AUTORPT_FLAG         ;WELLL, DUDES - AUTOREPEATING?
               BEQ.S   HAMMOND_1            ;    IF NOT, OTRA THINGS TO DO
               TST     HOLDING_EVENT        ;HOWABOUT - ARE WE ON FIRST CLICK OF A BAR?
               BEQ.S   HAMMOND_1            ;BRANCH IF YES - WE'LL BE BACK REAL SOON NOW TO
                                            ;EXECUTE THIS VERY SAME PHASE VECTOR - DON' PLAY ANY
                                            ;AUTOREPEAT RIGHT NOW (DON'T NEED NO TWO-FER-ONE).
                                            ;         ELSE....
               MOVE.L  A6,SEQ_WR_PTR        ;SAVE ADDRESS POINTERS FOR VARIOUS READ/WRITE SUBS
               MOVE.L  A5,SEQ1_DRD_PTR
               MOVE    A3,WASTELAND_PTR
;
               BSR     PAD_ON_AUTOREPEAT    ;AUTOREP THOSE PADS
               BSR     AUTORPT_MIDI         ;AUTOREP THEM MIDIES
               BSR     FTPAD_ON_AUTORPT     ;AUTOREP THEM FOOTSIES
;
               MOVE.L  SEQ_WR_PTR,A6        ;SET UP ADDRESS POINTERS FOR VARIOUS READ/WRITE SUBS
               MOVE.L  SEQ1_DRD_PTR,A5
               MOVE    WASTELAND_PTR,A3
HAMMOND_1
               TST.B   SINGLE_STEP          ;ARE WE SINGLE STEPPING?
               BEQ.S   EXIT_PHASE_2         ;BRANCH IF NOT, WE'RE THROUGH -
               BSR     SNGL_STEP_PAUSE      ;ELSE INVOKE PAUSE VIA SPECIAL SINGLE-STEP HOOK.
EXIT_PHASE_2
               RTS
;
;
;
;
;
PHASE_3        ;post-correct
               MOVE    #3,LAST_PHASE        ;SAY WHAT PHASE WE BE IN.
               MOVE    #SEQ_WRITE,A0        ;NEW NOTES TO THE NEW BLOCK (PILE UP ON E-CORRECT INTERVAL)
               MOVE    A0,MIDI_ON_WRITE
               MOVE    A0,PAD_ON_WRITE
;
               MOVE    #WASTELAND_WRITE,OLD_SEQ_WRITE ;OLD EVENTS TO THE BUFFER (WITH THEIR TIME MARKS)
;
               MOVE    #TIMED_WASTE_WRITE,NON_NOTE_WRITE   ;NEW NON-NOTES ALSO TO THE BUFFER, WITH
                                                           ; TIME MARKS (IF NO OLD EVENTS ON THE CLICK
                                                           ; ON WHICH THEY COME IN).
               MOVE    #TIMED_WASTE_WRITE,A0 ;NOTE OFFS AFTER INTERVAL DO NOT GET SHIFTED
               TST     AC_TYPE              ;IF AUTOCORRECTING EVERYTHING
               BEQ.S   GNOME_2
               MOVE    #SEQ_WRITE,A0        ;    THEN DO AS NOTE ONS
GNOME_2
               MOVE    A0,NOTE_OFF_WRITE
;
               RTS
;
;
;
;
;
PHASE_4        ;clean-up
               MOVE    #4,LAST_PHASE        ;SAY WHAT PHASE WE BE IN.
               TST.B   NOW_REPEATING        ;ARE WE IN NON-DESTRUCTIVE LOOP PLAYBACK MODE?
               BNE.S   PINK_5               ;IF SO, SKIP DATA MOVE STUFF, GO VISIT THE PINK FIVE.
               TST     WASTELAND_DEPTH      ;SEE IF ANY BUFFERED EVENTS NEED COPYING
               BEQ.S   PINK_5               ;    IF NOT, JUST CHANGE PHASE VECTORS
PINK_6
               BSR     WASTELAND_COPY       ;COPY BUFFERED EVENTS TO NEW BLOCK
PINK_5
               MOVE    #SEQ_WRITE,OLD_SEQ_WRITE  ;AFTERWARDS, OLD EVENTS TO THE NEW BLOCK
;
               MOVE    #TIMED_SEQ_WRITE,NON_NOTE_WRITE     ;NEW NON-NOTES TO THE NEW BLOCK, WITH
                                                           ; THE DISTINCTION THAT THEY GET A TIME
                                                           ; MARK IF NO OLD EVENTS THIS CLICK.
               MOVE    #WASTELAND_WRITE,NOTE_OFF_WRITE
;
               MOVE    #WASTELAND_WRITE,MIDI_ON_WRITE      ;SET UP FOR NEW NOTES TO BE BUFFERED 'TILL AUTOCORRECT
;
               MOVE    #TIMED_SEQ_WRITE,PAD_ON_WRITE       ;LIE TO PADS - AUTOCORRECT WRITES DIFFERENTLY
               MOVE.L  A6,SEQ_WR_PTR        ;SAVE ADDRESS POINTERS FOR VARIOUS READ/WRITE SUBS
               MOVE.L  A5,SEQ1_DRD_PTR
               MOVE    A3,WASTELAND_PTR
;
               BSR     PAD_OFF_AUTOREPEAT   ;AUTO OFF (DON'T CHECK AUTORPT_FLAG FIRST - USER MAY HAVE
               BSR     FTPAD_OFF_AUTORPT    ;DON'T FORGET FOOTSWITCHES, HEY.
               BSR     AUTO_OFF_MIDI        ; TURNED OFF BEFORE WE PERFORMED THE OFFS FOR ONS EARLIER).
;
               MOVE.L  SEQ_WR_PTR,A6        ;SET UP ADDRESS POINTERS FOR VARIOUS READ/WRITE SUBS
               MOVE.L  SEQ1_DRD_PTR,A5
               MOVE    WASTELAND_PTR,A3
               MOVE    #WASTELAND_WRITE,PAD_ON_WRITE  ;SET UP FOR NEW PADS TO BE BUFFERED 'TILL AUTOCORRECT
;
               RTS
;
;AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
