               INCLUDE HPFIXUPS
               TITLE "SEQSUBS"
***************************************************************************************************
***************************************************************************************************
***                                                                                             ***
***            SEQSUBS - MODEL 440 SEQUENCE MANAGEMENT/UTILITY ROUTINES                         ***
***                                                                                             ***
***************************************************************************************************
***************************************************************************************************
;
NEG_EXT        EQU     0FFFFFF00H      ;USE IN MOVEQ INSTRUCTIONS WHERE ARG IS
                                       ;80H OR LARGER - HP XASM DOES NOT HANDLE
                                       ;SIGN-EXTEND CORRECTLY.  COSMETIC, KEEPS
                                       ;ACTUAL BYTE VALUE CLEARER.
;
               ABS_SHORT
;
               INCLUDE SEQDEFS              ;SEQUENCER CONSTANT DEFINITIONS.
;
               GLB     SEQ_MEM_INIT
               GLB     SEQ1_DSTR_READ,SEQ1_DRD_SETUP
               GLB     SEQ_NDSTR_READ,SEQ_NDRD_SETUP
               GLB     SEQX_NDRD_SETUP
               GLB     SEQ_WRITE,TIMED_SEQ_WRITE
               GLB     SEQ_TURNAROUND,SEQ_CONSOLIDATE,UPDATE_SEQ_SIZE
               GLB     GET_SEQ_DIR_PTR,GET_CUR_SEQ_DIR
               GLB     SEQ1_RMW_EATER
               GLB     SEQ_NDRMW_EATER
               GLB     SEQ_NDRD_EATER
               GLB     SEQ1_DRD_EATER
               GLB     TIMED_WASTE_WRITE
               GLB     WASTELAND_WRITE
               GLB     INIT_WASTE_RECORD
               GLB     SET_WASTE_RECORD
               GLB     ZERO_WASTE_RECORD
               GLB     WASTELAND_COPY
               GLB     ND_SEARCH_EDIT_BAR
               GLB     D_SEARCH_EDIT_BAR
               GLB     SEQ_CHANGE_SUB
;
               EXTERNAL  Q_START_BLK        ;SEQUENCE DIRECTORY ELEMENTS.
               EXTERNAL  Q_BLOCK_SIZE
               EXTERNAL  Q_MEM_USED
               EXTERNAL  Q_STATUS
               EXTERNAL  Q_XS_BEATS
               EXTERNAL  Q_TOTAL_BARS
               EXTERNAL  Q_TIME_NUM
               EXTERNAL  Q_TIME_DENOM
               EXTERNAL  Q_INIT_TEMPO
               EXTERNAL  Q_RPT_COUNT
               EXTERNAL  Q_RPT_START
               EXTERNAL  Q_RPT_END
               EXTERNAL  Q_NAME
;
                                            ;EXTERNAL ROM.
               EXTERNAL  WRITE_TO_TC
               EXTERNAL  SEQ_MEM_STAT_SUB
               EXTERNAL  USER_STALL
               EXTERNAL  DISP_SCREEN
               EXTERNAL  SEQ_MEM_CHECK
;
                                            ;LIKE, RAM.
               EXTERNAL  SEQ1_DRD_BLK
               EXTERNAL  SEQ1_DRD_PTR
               EXTERNAL  SEQ1_DRD_CNT
               EXTERNAL  SEQ_NDRD_BLK
               EXTERNAL  SEQ_NDRD_PTR
               EXTERNAL  SEQ_NDRD_CNT
               EXTERNAL  SEQ_WR_BLK
               EXTERNAL  SEQ_WR_PTR
               EXTERNAL  SEQ_WR_CNT
               EXTERNAL  PREV_WR_BLK
               EXTERNAL  SEQUENCE_RAM
               EXTERNAL  SEQ_RAM_END
               EXTERNAL  SEQ_DIRECTORY
               EXTERNAL  SEQ_BLOCK_LIST
               EXTERNAL  CURRENT_SEQUENCE
               EXTERNAL  SEQ_DIR_99
               EXTERNAL  LAST_FREE_BLK
               EXTERNAL  NEXT2LAST_FREE
               EXTERNAL  SEQ_MEM_FULL
               EXTERNAL  WASTELAND
               EXTERNAL  WASTELAND_DEPTH
               EXTERNAL  WROTE_NEW_TIME
               EXTERNAL  END_OF_WASTELAND
               EXTERNAL  NOW_CLICK
               EXTERNAL  MIDI_ON_WRITE
               EXTERNAL  PAD_ON_WRITE
               EXTERNAL  NOTE_OFF_WRITE
               EXTERNAL  NON_NOTE_WRITE
               EXTERNAL  WASTELAND_PTR
               EXTERNAL  OTRA_BAR_CHORES
               EXTERNAL  CUE_BAR,CUE_START
               EXTERNAL  FORMER_SEQUENCE,NOW_NUMERATOR,NOW_SEQ_STATUS,NOW_LAST_BAR,NOW_DENOMINATOR
               EXTERNAL  RAW_DENOMINATOR
               EXTERNAL  CUE_NEW_SEQ
               EXTERNAL  INIT_TEMPO_USEC
               EXTERNAL  REF_TEMPO_USEC
               EXTERNAL  CUR_TEMPO_USEC
               EXTERNAL  USEC_TO_ALL
               EXTERNAL  CUR_TEMPO_FPB,INIT_TEMPO_FPB
               EXTERNAL  CUR_TEMPO_BPM,INIT_TEMPO_BPM
               EXTERNAL  TOTAL_BARS,NOW_BAR,EDIT_BAR,EDIT_CLICK,EDIT_BEAT
               EXTERNAL  CLICKS_THIS_BAR
               EXTERNAL  RESET_PUNCHES
               EXTERNAL  UPDATE_REPEATS,BG_TEMP_1_B
               EXTERNAL  TRACKS_MUTED
               EXTERNAL  CUR_SUB_BLOCK
               EXTERNAL  SUBFUN_INSTALL
               EXTERNAL  SONG_SEL_ENABLE
               EXTERNAL  XMIT_TEMP_1
               EXTERNAL  SETUP_STATE
               EXTERNAL  CONSOL_STATE
               EXTERNAL  TURNAR_STATE
               EXTERNAL  UPDATE_STATE
               EXTERNAL  LAST_SETUP_SEQ
               EXTERNAL  SEQ_ERROR_FLAG
               SKIP
;VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV
;
; GENERAL REMARKS ON SEQUENCE MEMORY STRATEGY -
;
;     BOTH PLAYBACK AND RECORD INVOLVE COPYING SEQUENCE DATA FROM AN INPUT STREAM TO AN OUTPUT
; STREAM, BOTH STREAMS MAINTAINED IN 1K-BYTE BLOCKS - WHEN RECORDING, THE MAIN DIFFERENCE IS THE
; ADDITION OF AN INPUT STREAM OF NEW EVENTS WHICH IS MERGED WITH THE EXISTING INPUT STREAM OF DATA
; PREVIOUSLY RECORDED IN THE SEQUENCE - DURING PLAYBACK, ONLY THE LATTER INPUT STREAM IS ACTIVE,
; HOWEVER THE DATA-COPYING PROCESS IS KEPT ACTIVE TO FACILITATE RANDOM PUNCH-IN RECORDING.
; BOTTOM LINE IN EITHER CASE - EXISTING SEQUENCE DATA IS REARRANGED.
;
;     WHILE SEQUENCER IS RUNNING, DATA-STREAM MANAGEMENT IS HANDLED BY SEQ1_DSTR_READ (PREVIOUSLY-
; RECORDED SEQUENCE DATA ONLY) AND SEQ_WRITE (WHICH HANDLES THE COMBINED OLD/NEW OUTPUT STREAM).
; THE "DSTR" IN SEQ1_DSTR_READ SIGNIFIES THAT THIS ROUTINE PERFORMS A DESTRUCTIVE READ OF EXISTING
; SEQUENCE DATA - THE ASSUMPTION IS THAT NEW DATA MAY GET MERGED IN WITH THE EXISTING SEQUENCE,
; THUS REQUIRING THAT ALL DATA WILL HAVE TO BE COPIED ELSEWHERE ANYWAY - I.E., BY SEQ_WRITE.
; BOTH ROUTINES TRANSFER ONE WORD OF SEQUENCE DATA PER CALL EITHER INTO OR OUT OF THE SEQUENCER.
; FOR SPEED, THESE ROUTINES ASSUME THAT A GIVEN ADDRESS REGISTER CONTAINS AN ABSOLUTE-LONG POINTER
; TO THE NEXT READ OR WRITE LOCATION (ONE FOR EACH) - THESE POINTERS ARE SET UP OR RECALLED UPON
; ENTERING SEQUENCE-PARSING ROUTINES (TYPICALLY AT CLICK-SERVICE TIME) AND THE REGISTERS ARE
; DEDICATED TO THAT USE UNTIL THOSE ROUTINES ARE EXITED, AT WHICH POINT THE NEW POINTER VALUES ARE
; SAVED FOR LATER RECALL (I.E., WHEN NEXT CLICK IS SERVICED).
;
;     IN THE SEQUENCE-EDITING ENVIRONMENT, ONE ADDITIONAL SEQUENCE-READ ROUTINE MAY BE USED:
; SEQ_NDSTR_READ IS SIMILAR TO SEQ1_DSTR_READ, BUT DOES NON-DESTRUCTIVE READING OF A SEQUENCE -
; IT IS USED FOR THINGS SUCH AS TRANSPOSE, ETC. WHERE NO DATA IS ADDED TO OR REMOVED FROM SEQUENCE.
; MODIFIED SEQUENCE DATA ARE WRITTEN BACK TO THE SAME PLACE FROM WHICH THEY WERE READ, USING THE
; SAME POINTER WHICH IS USED FOR READING.
;
;     ALL OF THE ABOVE ROUTINES TRANSPARENTLY DETERMINE WHEN THE END OF A READ OR WRITE BLOCK HAS
; BEEN ENCOUNTERED, AND MANAGE THE DETAIL WORK OF FINDING AND PLUGGING-IN THE NEXT BLOCK,
; WHILE DISPOSING OF THE ONE JUST RETIRED AS APPROPRIATE.  LINK POINTERS IN THE SEQUENCE MEMORY
; BLOCK LIST ARE LIKEWISE UPDATED AS NECESSARY.  NONE OF THE ROUTINES ARE DEPENDENT IN ANY WAY UPON
; THE CONTEXT IN WHICH THEY ARE BEING USED (I.E., SEQUENCE PLAY/RECORD OR SEQUENCE EDIT).
;
;     SEQUENCE #99 IS DESIGNATED AS THE "NULL SEQUENCE", WHICH CANNOT BE RECORDED INTO OR EDITED
; AND IS USED TO MAINTAIN ALL FREE MEMORY BLOCKS IN A SINGLE LINKED LIST.  IN ALL OTHER RESPECTS,
; INCLUDING THE FORMAT OF ITS DIRECTORY ENTRY, IT IS IDENTICAL TO ANY OTHER SEQUENCE.
; #SEQ_DIR_99 POINTS DIRECTLY TO THE DIRECTORY ENTRY FOR THIS SEQUENCE.
; GENERAL STRATEGY REGARDING FREE MEMORY IS TO ALWAYS MAINTAIN AT LEAST ONE FREE BLOCK, THEREFORE
; TO FORBID RECORDING IF ONLY ONE FREE BLOCK REMAINS (THIS INCLUDES HALTING RECORD IF THE FREE
; BLOCK COUNT DROPS TO 1 WHILE IN RECORD MODE), AND LIKEWISE TO FORBID CREATION OF A NEW SEQUENCE
; WHEN THIS WOULD LEAVE ONLY ONE FREE BLOCK, AS WELL AS MODIFICATIONS OF EXISTING SEQUENCES WHEN
; THIS WOULD REQUIRE PERMANENT ALLOCATION OF THE LAST REMAINING FREE BLOCK.
;
;AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
               SKIP
;VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV
;
; INITIALIZE SEQUENCE DIRECTORY AND SEQUENCE RAM BLOCK LIST -
; LET'S AIM TO ACHIEVE THAT PRISTINE, VIRGINAL, NO-SEQUENCES STATE:
;
SEQ_MEM_INIT
               MOVE.L  #SEQ_DIRECTORY,A0    ;SEQUENCE DIRECTORY IS OUTSIDE SHORT-ADDRESS AREA -
               MOVEQ   #100,D0              ;101 ENTRIES INCLUDING NULL SEQUENCE AND WORK LOOP.
SEQ_INIT_10
               MOVE.L  #EMPTYSEQ_STRING,A1  ;CALL 'EM "emptyseq" UNTIL FURTHER NOTICE.
               MOVE.L  (A1)+,Q_NAME(A0)
               MOVE.L  (A1),Q_NAME+4(A0)
               MOVE    #-1,Q_START_BLK(A0)  ;NULL START-BLOCK INDEX - NOTHING THERE.
               MOVE    #22727,Q_INIT_TEMPO(A0)   ;NOMINALLY 100 BPM.
               MOVE    #4,Q_TIME_NUM(A0)         ;AS ALWAYS IN WESTERN MUSIC, START IN 4/4.
               MOVE    #1,Q_TIME_DENOM(A0)       ;(TRANSLATES TO "4" - FROM RAW FORM = 1).
               CLR     Q_TOTAL_BARS(A0)     ;NO BARS,
               CLR     Q_XS_BEATS(A0)       ;NO BEATS,
               CLR     Q_MEM_USED(A0)       ;NO MEMORY,
               SF      Q_RPT_COUNT(A0)      ;NO REPEATS,
               CLR     Q_RPT_END(A0)        ;NO LOOP END,
               CLR     Q_RPT_START(A0)      ;NO LOOP START.
               CLR     Q_STATUS(A0)         ;Q_STATUS = 0 TO INDICATE EMPTY SEQ.
               LEA     Q_BLOCK_SIZE(A0),A0  ;STEP UP TO NEXT BLOCK, IF ANY.
               DBRA    D0,SEQ_INIT_10       ;FIRST-PASS - MAKE 'EM ALL LOOK THE SAME.
;
               MOVE.L  #SEQ_DIR_99,A0       ;ONE'S DIFFERENT - THE NULL SEQUENCE ....
               MOVE.L  #NULLSEQ_STRING,A1   ;WE CALL IT WHAT IT IS (FOR LACK OF BETTER IDEA ....)
               MOVE.L  (A1)+,Q_NAME(A0)
               MOVE.L  (A1),Q_NAME+4(A0)
               CLR     Q_START_BLK(A0)      ;(FREE SEQ RAM) STARTS AT SEQ RAM BLOCK 000.
               MOVE    #400,Q_MEM_USED(A0)  ;INITIALLY, ALL SEQ RAM BELONGS TO NULL SEQ.
               MOVE    #-1,Q_STATUS(A0)     ;THIS SEQUENCE IS NOT (EVER!) EMPTY.
;
                                            ;INITIALIZE SEQUENCE RAM BLOCK LIST:
               MOVE.L  #SEQ_BLOCK_LIST,A0   ;LINK ALL SEQ RAM BLOCKS TOGETHER IN FREE BLOCK LIST.
               MOVEQ   #1,D0                ;BLOCK 0 LINKS TO BLOCK 1, ETC.
SEQ_INIT_20
               MOVE    D0,(A0)+
               ADDQ    #1,D0
               CMP     #400,D0
               BLT     SEQ_INIT_20          ;BLOCKS 0-398 LINK TO THE NEXT BLOCK UP,
               MOVE    #-1,(A0)             ;BLOCK 399 DOES NOT LINK TO ANY ONE - HE'S THE END.
               MOVE    #399,LAST_FREE_BLK   ;WE GEN'RALLY WANNA KNOW WHERE LAST FREE BLOCK IS.
               MOVE    #398,NEXT2LAST_FREE  ;ALSO, WE WANNA KNOW THE NEXT-TO-LAST FREE BLOCK.
;
               SF      SETUP_STATE          ;INITIALIZE SEQUENCER STATE FLAGS - NOT RD/WR SETUP,
               SF      CONSOL_STATE         ;NOT CONSOLIDATED,
               SF      TURNAR_STATE         ;NOT TURNED-AROUND,
               ST      UPDATE_STATE         ;BUT DEFINITELY UPDATED.
;
SEQ_INIT_EXIT
               RTS
;
;
;
EMPTYSEQ_STRING
               ASC     "emptyseq"
;
NULLSEQ_STRING
               ASC     "null seq"
;
;AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
               SKIP
;VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV
;
; SEQUENCE DESTRUCTIVE READ SETUP -
; SETS UP THE SEQ1_DSTR_RD AND SEQ_WRITE APPARATUS FOR DESTRUCTIVE READ
; AND COPY OF CURRENT_SEQUENCE.
;
; SEQUENCE START BLOCK BECOMES THE INITIAL SEQ1 READ BLOCK -
; ITS BLOCK INDEX IS COPIED INTO SEQ1_DRD_BLK.
; THE ABSOLUTE ADDRESS OF THE BEGINNING OF THIS BLOCK IS LOADED INTO A5,
; AND IS COPIED INTO SEQ1_DRD_PTR (WHERE IT LIVES WHEN NOT IN USE).
; SEQ1_DRD_CNT IS SET TO 512, TO INDICATE WE'VE ONLY JUST BEGUN -
; - NOT QUITE - READING THIS BLOCK, THAT IS.
;
; NULL SEQUENCE START BLOCK BECOMES INITIAL WRITE BLOCK -
; ITS INDEX IS COPIED INTO SEQ_WR_BLK.
; THE ABSOLUTE ADDRESS OF THE BEGINNING OF THIS BLOCK IS LOADED INTO A6,
; AND IS COPIED INTO SEQ_WR_PTR (WHERE IT LIVES WHEN NOT IN USE).
; SEQ_WR_CNT IS SET TO 512, TO INDICATE THAT WE'VE ONLY JUST BEGUN -
; - NOT QUITE - TO WRITE INTO THIS BLOCK, THAT IS.
;
; THE SOURCE SEQUENCE IS LINKED ONTO THE END OF THE NULL SEQUENCE - THIS
; ELIMINATES NEED TO REWRITE LINKS EACH TIME A READ BLOCK IS EXHAUSTED.
;
; HEY - DON'T BUG ME IF SOURCE SEQUENCE IS EMPTY - THIS I DO NOT NEED.
; AND DON'T TRY TO ENTER RECORD MODE WITH ONLY ONE FREE BLOCK LEFT, HUH?
;
; THE NUMBER OF THE SEQUENCE WE SET UP IS COPIED INTO LAST_SETUP_SEQ -
; SEQ_CONSOLIDATE, SEQ_TURNAROUND AND UPDATE_SEQ_SIZE AUTOMATICALLY
; OPERATE ON THE SAME SEQUENCE, AS A MEASURE OF BULLETPROOFING.
;
; PRESERVES ALL REGISTERS ASIDE FROM A5-A6.
; (SING, BIRD OF PREY - BEAUTY BEGINS AT THE FOOT OF YOU ....)
;
SEQ1_DRD_SETUP
                                            ;SAFEGUARD AGAINST UNFORESEEN SOFTWARE FUCK-UPS:
               TST.B   SETUP_STATE          ;ARE WE IN SETUP STATE ALREADY?
               BNE.S   SEQ1_DRSET_00        ;BRANCH IF YES - ERROR CONDITION.
               TST.B   CONSOL_STATE         ;ARE WE IN CONSOLIDATE STATE?
               BEQ.S   SEQ1_DRSET_10        ;BRANCH IF NOT, PROCEED WITH NORMAL OPERATION.
               MOVE.B  #SET_FOL_CONS,SEQ_ERROR_FLAG   ;ELSE, SET AN ERROR FLAG,
               BRA.S   SEQ1_DRSET_EXIT                ;EXIT WITHOUT ACTION.
SEQ1_DRSET_00
               MOVE.B  #SET_FOL_SET,SEQ_ERROR_FLAG    ;SETUP FOLLOWING SETUP - NONE TOO COOL.
               BRA.S   SEQ1_DRSET_EXIT                ;EXIT WITHOUT ACTION.
;
SEQ1_DRSET_10
               ST      SETUP_STATE          ;WE'RE OKAY, SO SET/CLEAR STATE FLAGS ACCORDINGLY.
               SF      CONSOL_STATE
               SF      TURNAR_STATE
               SF      UPDATE_STATE
;
               MOVEM.L D0/A0,-(A7)
               BSR     GET_CUR_SEQ_DIR      ;A0 POINTS TO CURRENT_SEQUENCE DIRECTORY ENTRY -
               MOVE    CURRENT_SEQUENCE,LAST_SETUP_SEQ     ;RECORD THIS SEQUENCE NUMBER FOR LATER
                                                           ;USE BY SEQ-MEMORY MANAGEMENT ROUTINES.
;
;871013                                            ;FIRST, SOME STONE-BLIND BULLETPROOFING -
;871013                                            ;DON'T ALLOW SETUP IF IN SETUP OR CONSOLIDATED STATE:
;871013               TST.B   SETUP_STATE          ;ARE WE IN SETUP STATE ALREADY?
;871013               BNE.S   SEQ1_DRSET_40        ;BRANCH IF YES - ERROR CONDITION, SO EXIT.
;871013               TST.B   CONSOL_STATE         ;ARE WE IN CONSOLIDATED STATE?
;871013               BNE.S   SEQ1_DRSET_40        ;BRANCH IF YES - ERROR CONDITION, SO EXIT.
;871013;
;871013               ST      SETUP_STATE          ;WE'RE OKAY, SO SET/CLEAR STATE FLAGS ACCORDINGLY.
;871013               SF      CONSOL_STATE
;871013               SF      TURNAR_STATE
;871013               SF      UPDATE_STATE
;
               MOVE    Q_START_BLK(A0),D0   ;FETCH SEQUENCE START BLOCK INDEX.
               MOVE    D0,SEQ1_DRD_BLK      ;SET START BLOCK AS INITIAL READ BLOCK,
               MULU    #1024,D0             ;THEN GENERATE THE ADDRESS OF THE BLOCK ITSELF IN A5.
               MOVE.L  D0,A5
               ADD.L   #SEQUENCE_RAM,A5
               MOVE.L  A5,SEQ1_DRD_PTR      ;SAVE THE VALUE OF THIS POINTER - READING BEGINS HERE.
               MOVE    #512,SEQ1_DRD_CNT    ;SAY - "NOT HAVE READ FROM BLOCK ANY WORD YET."
;
               MOVE.L  #SEQ_DIR_99,A6       ;FETCH NULL SEQUENCE START BLOCK INDEX.
               MOVE    Q_START_BLK(A6),D0   ;THIS IS IT -
               MOVE    D0,SEQ_WR_BLK        ;SET THIS BLOCK UP AS INITIAL WRITE BLOCK
               MOVE    D0,PREV_WR_BLK       ;(ALSO = PREVIOUS WRITE BLOCK - BOUNDARY CORRECTNESS),
               MULU    #1024,D0             ;THEN GENERATE ADDRESS OF THE BLOCK ITSELF IN A6.
               MOVE.L  D0,A6
               ADD.L   #SEQUENCE_RAM,A6
               MOVE.L  A6,SEQ_WR_PTR        ;SAVE THE VALUE OF THIS POINTER - WRITING BEGINS HERE.
               MOVE    #512,SEQ_WR_CNT      ;SAY - "NOT HAVE WRITE TO BLOCK, ANY WORD YET."
;
               MOVE    LAST_FREE_BLK,A0     ;SET LINK POINTER OF LAST FREE BLOCK TO LINK TO
               ADD     A0,A0                ;THE SOURCE SEQUENCE START BLOCK.
               MOVE    SEQ1_DRD_BLK,SEQ_BLOCK_LIST(A0)
;
SEQ1_DRSET_40
               MOVEM.L (A7)+,D0/A0
;
SEQ1_DRSET_EXIT
               RTS
;
;AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
               SKIP
;VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV
;
; SEQUENCE NON-DESTRUCTIVE READ SETUP -
; SETS UP THE SEQ_NDSTR_READ APPARATUS FOR NON-DESTRUCTIVE READ OF
; CURRENT_SEQUENCE.
; ALTERNATIVELY, PUT SEQUENCE NUMBER IN D0 AND ENTER AT SEQX_NDRD_SETUP.
;
; SEQUENCE START BLOCK BECOMES THE INITIAL READ BLOCK -
; ITS BLOCK INDEX IS COPIED INTO SEQ_NDRD_BLK.
; THE ADDRESS OF THE BEGINNING OF THIS BLOCK MINUS 2 IS LOADED INTO A4
; (SINCE THE NON-DESTRUCTIVE READ ALGORITHM USES INCREMENT-BEFORE-READ),
; AND IS COPIED INTO SEQ_NDRD_PTR (WHERE IT LIVES WHEN NOT IN USE).
; SEQ_NDRD_CNT IS SET TO 512, TO INDICATE WE'VE ONLY JUST BEGUN -
; - NOT QUITE - READING THIS BLOCK, THAT IS.
;
; PRESERVES ALL REGISTERS ASIDE FROM A4.
; (AS A MOVEMENT REGAINED AND REGARDED BOTH THE SAME ....)
;
SEQ_NDRD_SETUP
               MOVEM.L D0/A0,-(A7)
               BSR     GET_CUR_SEQ_DIR      ;A0 POINTS TO CURRENT_SEQUENCE DIRECTORY ENTRY -
               BRA.S   SEQ_NDRSET_20
;
SEQX_NDRD_SETUP
               MOVEM.L D0/A0,-(A7)
               BSR     GET_SEQ_DIR_PTR      ;A0 POINTS TO SEQUENCE (D0) DIRECTORY ENTRY -
;
SEQ_NDRSET_20
               MOVE    Q_START_BLK(A0),D0   ;FETCH SEQUENCE START BLOCK INDEX.
               MOVE    D0,SEQ_NDRD_BLK      ;SET START BLOCK AS INITIAL READ BLOCK,
               MULU    #1024,D0             ;THEN GENERATE THE ADDRESS OF THE BLOCK ITSELF.
               MOVE.L  D0,A4
               ADD.L   #SEQUENCE_RAM-2,A4   ;OFFSET -2 BECAUSE OF INCREMENT BEFORE READ.
               MOVE.L  A4,SEQ_NDRD_PTR      ;SAVE THE VALUE OF THIS POINTER - READING BEGINS HERE.
               MOVE    #512,SEQ_NDRD_CNT    ;SAY - "NOT HAVE READ FROM BLOCK ANY WORD YET."
;
               MOVEM.L (A7)+,D0/A0          ;RESTORE REGS, LEAVING Z FLAG AS IS.
;
SEQ_NDRSET_EXIT
               RTS
;
;AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
               SKIP
;VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV
;
; DESTRUCTIVE SEQUENCE-READ -
; FETCH NEXT WORD FROM CURRENT PLAYBACK BLOCK OR PRIMARY-SOURCE EDIT
; BLOCK (I.E., SEQ1_DRD_BLK) - RETURNS THE WORD IN D7.
;
; IF NECESSARY, FINDS AND SETS UP NEXT BLOCK IN SEQUENCE LIST.
; WHEN THIS IS DONE, THE EXPENDED READ BLOCK IS DESIGNATED AS THE NEW
; LAST FREE BLOCK (IT'S ALREADY LINKED TO THE END OF THE NULL SEQUENCE),
; WHILE THE PREVIOUS LAST FREE BLOCK IS NOW DESIGNATED AS THE NEXT-TO-
; LAST FREE BLOCK (NEEDED IN CASE WE ARE IN RECORD OR SOME SUCH MODE IN
; WHICH NEW DATA IS BEING MERGED INTO THE SEQUENCE - THE NEXT-TO-LAST
; BLOCK IS THE LAST ONE WE ARE ALLOWED TO USE IN THOSE CASES).
;
; ASSUMES A5 IS ALREADY SET UP AS THE SEQUENCE READ POINTER,
; AND SEQ1_DRD_CNT HOLDS THE NUMBER OF WORDS REMAINING IN SEQ1_DRD_BLK
; (THE GENERIC 1K BYTE BLOCK, END-OF-SEQUENCE NOTWITHSTANDING) -
; A5 IS ALWAYS LEFT POINTING AT THE NEXT WORD TO BE READ,
; AND SEQ1_DRD_CNT IS LIKEWISE KEPT UPDATED.
;
; JUST FOR THE HECK OF IT - RETURNS Z FLAG TRUE UNLESS WE HIT THE
; END OF THE LAST BLOCK IN THE SEQUENCE LIST.  WHEN THIS OCCURS,
; SEQ1_DRD_CNT IS LEFT = 0 AND SEQ1_DRD_BLK IS NOT CHANGED.
; I DON'T KNOW WHY THAT MIGHT BE IMPORTANT.  DON'T BUG ME.
; AH .... WELL.  IT COULD HAVE IMPACT ON ACCOUNTING FOR LOCATIONS OF
; LAST_FREE_BLK AND NEXT2LAST_FREE - THAT MIGHT BE IMPORTANT.  I DUNNO.
;
; ASIDE FROM D7/A5, OTHER REGISTERS CONSERVED.
; (AS WE CROSS FROM SIDE TO SIDE WE HEAR THE TOTAL MASS RETAIN ....)
;
SEQ1_DSTR_READ
               MOVE    (A5)+,D7             ;THE MAIN EVENT.
               SUBQ    #1,SEQ1_DRD_CNT      ;UPDATE BLOCK READ COUNT -
               BNE.S   SEQ1_DRD_80          ;BRANCH IF NOT LAST WORD - SET Z FLAG TRUE, EXIT.
;
               MOVEM.L D6-D7,-(A7)          ;GOTTA LINE UP NEW READ BLOCK - STASH SEQ WORD, ET AL.
;
               MOVE    #SEQ_BLOCK_LIST,A5   ;FETCH INDEX OF NEW READ BLOCK:
               MOVE    LAST_FREE_BLK,NEXT2LAST_FREE   ;FIRST BUMP CURRENT LAST FREE BLOCK UP INTO
                                                      ;THE NEXT-TO-LAST FREE BLOCK SLOT.
               MOVE    SEQ1_DRD_BLK,D7      ;NOW, TAKE INDEX OF CURRENT READ BLOCK -
               MOVE    D7,LAST_FREE_BLK     ;ESTABLISH THIS BLOCK AS NEW LAST FREE BLOCK, THEN
               ADD     D7,D7                ;CONVERT ITS INDEX INTO WORD OFFSET INTO BLOCK LIST -
               MOVE    0(A5,D7),D6          ;ITS ENTRY IS THE INDEX OF THE BLOCK IT LINKS TO,
                                            ;TO WIT, OUR NEXT READ BLOCK.
               TST     D6                   ;HMMMM - DID WE HIT THE END OF THE SEQUENCE?
               BMI.S   SEQ1_DRD_60          ;EXIT IF OLD READ BLOCK WAS LAST IN SEQUENCE LIST.
               MOVE    D6,SEQ1_DRD_BLK      ;ELSE - PLUG IN NEW READ BLOCK INDEX,
               MULU    #1024,D6             ;GENERATE OFFSET OF THIS BLOCK INTO SEQUENCE_RAM.
               MOVE.L  D6,A5                ;SET UP THE POINTER (AS ALWAYS) IN A5.
               ADD.L   #SEQUENCE_RAM,A5
               MOVE    #512,SEQ1_DRD_CNT    ;AND, LAST BUT NOT FIRST, RESTART THE BLOCK READ COUNT.
               CLR     D6                   ;NORMAL EXIT - SET Z FLAG TRUE.
;
SEQ1_DRD_60
               MOVEM.L (A7)+,D6-D7          ;RESTORE REDGE-OS, INCLUDING NEW SEQUENCE WORD (D7).
               BRA.S   SEQ1_DRD_EXIT        ;EXIT, LEAVING Z FLAG ALONE.
;
SEQ1_DRD_80
               CMP     D7,D7                ;NORMAL EXIT - SET Z FLAG TRUE.
;
SEQ1_DRD_EXIT
               RTS
;
;AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
               SKIP
;VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV
;
; NON-DESTRUCTIVE SEQUENCE-READ -
; FETCH NEXT WORD FROM CURRENT SEQUENCE-EDIT OR LOOPED-PLAYBACK BLOCK
; (I.E., SEQ_NDRD_BLK) - RETURNS THE WORD IN D7.
;
; IF NECESSARY, FINDS AND SETS UP NEXT BLOCK IN LINKED LIST.
; AS OPPOSED TO DESTRUCTIVE READ ROUTINES, THIS ONE DOES NOT REARRANGE
; THE EXISTING SEQUENCE BLOCK LIST IN ANY WAY.
;
; ASSUMES A4 IS ALREADY SET UP AS THE SEQUENCE READ POINTER -
; IT POINTS TO THE LAST WORD READ FROM THE SEQUENCE.
; SEQ_NDRD_CNT HOLDS THE NUMBER OF WORDS NOT YET READ IN SEQ_NDRD_BLK
; (THE GENERIC 1K BYTE BLOCK, END-OF-SEQUENCE NOTWITHSTANDING).
; A4 IS ALWAYS LEFT POINTING AT THE WORD JUST READ, IN ORDER TO ALLOW
; SUBSEQUENT WRITE BACK TO THE SAME LOCATION BY READ-MODIFY-WRITE EDIT
; UTILITIES SUCH AS TRANSPOSE, WHICH DO NOT CHANGE THE SEQUENCE SIZE.
; SEQ_NDRD_CNT IS LIKEWISE KEPT UPDATED.
;
; JUST FOR THE HECK OF IT - RETURNS Z FLAG TRUE UNLESS WE HIT THE
; END OF THE LAST BLOCK IN THE SEQUENCE LIST.
;
; ASIDE FROM D7/A4, OTHER REGISTERS CONSERVED.
; (REACH OUT AS FORWARD TASTES BEGIN TO ENTER YOU ....)
;
SEQ_NDSTR_READ
               SUBQ    #1,SEQ_NDRD_CNT      ;UPDATE BLOCK READ COUNT -
               BPL.S   SEQ_NDRD_80          ;BRANCH IF THERE IS STILL DATA TO READ FROM THIS BLOCK.
;
                                            ;READ BLOCK EXHAUSTED - FIND NEXT READ BLOCK:
               MOVE    #SEQ_BLOCK_LIST,A4   ;FETCH INDEX OF NEW READ BLOCK:
               MOVE    SEQ_NDRD_BLK,D7      ;TAKE INDEX OF CURRENT READ BLOCK,
               ADD     D7,D7                ;CONVERT TO WORD OFFSET INTO BLOCK LIST -
               MOVE    0(A4,D7),D7          ;ITS ENTRY IS THE INDEX OF THE BLOCK IT LINKS TO.
               BMI.S   SEQ_NDRD_EXIT        ;BRANCH IF OLD BLOCK WAS LAST IN SEQUENCE LIST - EXIT.
               MOVE.L  D7,-(A7)             ;SAVE HI ORDER WORD OF D7
               MOVE    D7,SEQ_NDRD_BLK      ;ELSE - SET NEW READ BLOCK INDEX,
               MULU    #1024,D7             ;GENERATE OFFSET OF THIS BLOCK INTO SEQUENCE_RAM.
               MOVE.L  D7,A4                ;SET UP THE POINTER (AS ALWAYS) IN A4.
               ADD.L   #SEQUENCE_RAM,A4
               MOVE.L  (A7)+,D7             ;
               MOVE    (A4),D7              ;FETCH AND RETURN THE FIRST WORD IN NEW READ BLOCK.
               MOVE    #511,SEQ_NDRD_CNT    ;NOT LAST BUT NOT FIRST, RESTART THE BLOCK READ COUNT,
                                            ;TAKING INTO ACCOUNT THE WORD WE JUST READ.
               CMP     D7,D7                ;NORMAL EXIT - RETURN Z FLAG TRUE.
               BRA.S   SEQ_NDRD_EXIT
;
SEQ_NDRD_80
               ADDQ    #2,A4                ;STEP TO NEXT WORD IN CURRENT READ BLOCK.
               MOVE    (A4),D7              ;THE MAIN EVENT.
               CMP     D7,D7                ;NORMAL EXIT - SET Z FLAG TRUE.
;
SEQ_NDRD_EXIT
               RTS
;
;AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
               SKIP
;VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV
;
; WRITE A WORD INTO CURRENT SEQUENCE WRITE BLOCK (SEQ_WR_BLK) -
; EXPECTS THE SEQUENCE WORD IN D7.
;
; IF NECESSARY, MOVES TO NEXT BLOCK IN THE FREE BLOCK LIST.
;
; ASSUMES A6 IS ALREADY SET UP AS THE SEQUENCE WRITE POINTER, AND
; SEQ_WR_CNT HOLDS THE NUMBER OF FREE WORDS REMAINING IN SEQ_WR_BLK.
; A6 IS ALWAYS LEFT POINTING AT THE NEXT LOCATION TO BE WRITTEN TO,
; AND SEQ_WR_CNT IS LIKEWISE KEPT UPDATED.
;
; A CALL HERE WILL SET THE SEQ_MEM_FULL(.B) FLAG IF WE START WRITING
; DATA INTO THE NEXT-TO-LAST FREE BLOCK - IF WE ARE IN RECORD MODE
; OR OTHERWISE ADDING NEW DATA TO SEQUENCE MEMORY, THIS IS OUR SIGNAL
; TO STOP (I.E., BEFORE ATTEMPT IS MADE TO USE THE LAST FREE BLOCK).
;
; ASIDE FROM A6, ALL REGISTERS CONSERVED - INCLUDING WRITE WORD (D7.L).
; (SUDDEN CALL SHOUDLN'T TAKE AWAY THE STARTLED MEMORY ....)
;
; TIMED_SEQ_WRITE IS USED IN CASES WHERE A CURRENT TIME MARKER MUST
; PRECEDE ANY NEW EVENT BEING WRITTEN BY SEQ_WRITE OR WASTELAND_WRITE.
; IF A TIME MARKER HAS BEEN CREATED AND WRITTEN DURING THE CURRENT
; SEQUENCER CLOCK PERIOD (OR IF AN EXISTING ONE HAS BEEN TRANSFERRED),
; THE FLAG WRITE_NEW_TIME(.B) HAS BEEN SET, INDICATING THAT NO NEW TIME
; MARKER NEED BE GENERATED BY US.  IF NOT, WE CREATE AND WRITE THE TIME
; MARKER (PER CURRENT VALUE OF NOW_CLICK), SET WROTE_NEW_TIME, AND LAST
; BUT NOT LEAST, WRITE THE WORD WE WERE GIVEN TO WRITE.
;
TIMED_SEQ_WRITE
               TST.B   WROTE_NEW_TIME       ;HAVE WE SEEN/MADE A TIME MARKER DURING THIS CLOCK?
               BNE.S   SEQ_WRITE            ;BRANCH IF YES, GO WRITE THE WORD WE'VE BEEN GIVEN.
               MOVE    D7,-(A7)             ;ELSE - SET OUR DATA WORD ASIDE,
               MOVE    NOW_CLICK,D7         ;CREATE AND WRITE AN APPROPRIATE TIME MARKER.
               LSL     #4,D7
               OR      #9,D7
               BSR.S   SEQ_WRITE            ;USE OUR OWN SELF TO WRITE THE TIME MARKER.
               MOVE    (A7)+,D7             ;RECOVER THE WORD CAME HERE WITH,
               ST      WROTE_NEW_TIME       ;TELL 'EM WE WROTE A TIME MARKER FOR THE CURRENT CLOCK.
;
SEQ_WRITE
               MOVE    D7,(A6)+             ;WHAT'S MOST IMPORTANT ....
               SUBQ    #1,SEQ_WR_CNT        ;DECREMENT COUNT OF SPACE LEFT IN SEQ_WR_BLK,
               BNE.S   SEQ_WR_80            ;BRANCH IF THERE STILL BE SPACE IN THIS BLOCK - EXIT.
;
;
               MOVE.L  D6,-(A7)             ;GOTTA FIND NEXT WRITE BLOCK - STASH HIM.
;
               MOVE    #SEQ_BLOCK_LIST,A6   ;CURRENT WRITE BLOCK LINKS TO NEXT WRITE BLOCK -
               MOVE    SEQ_WR_BLK,D6        ;JUST FOLLOW THE LINK PATH TO FIND IT.
               MOVE    D6,PREV_WR_BLK       ;STORE CURRENT WRITE BLOCK INDEX AS "PREVIOUS".
               ADD     D6,D6                ;(WORD-OFFSETSVILLE FOR LINK LIST ....)
               MOVE    0(A6,D6),D6          ;THIS IS OUR NEW BLOCK INDEX ....
               MOVE    D6,SEQ_WR_BLK        ;AND NOW .... ESTABLISH NEW WRITE BLOCK AS SEQ_WR_BLK,
               MULU    #1024,D6             ;GENERATE ABSOLUTE POINTER TO NEW WRITE BLOCK.
               MOVE.L  D6,A6
               ADD.L   #SEQUENCE_RAM,A6
               MOVE    #512,SEQ_WR_CNT      ;START WITH 1K BYTE OF FREE SPACE IN NEW WRITE BLOCK.
;
               MOVE    SEQ_WR_BLK,D6        ;IS OUR NEW WRITE BLOCK THE NEXT-TO-LAST FREE BLOCK?
               CMP     NEXT2LAST_FREE,D6
               BNE.S   SEQ_WR_20            ;BRANCH IF NOT THE NEXT-TO-LAST FREE BLOCK, WE COO'.
               MOVE    LAST_FREE_BLK,NEXT2LAST_FREE   ;ELSE BUMP NEXT-TO-LAST INDEX TO THE END -
                                                      ;THEY'LL BE EQUAL UNTIL MORE MEM IS FREED UP.
               ST      SEQ_MEM_FULL
               BRA.S   SEQ_WR_40
;
SEQ_WR_20
               CLR     D6                   ;1 OR MORE FREE BLOCKS REMAINING, RETURN Z FLAG TRUE.
SEQ_WR_40
               MOVEM.L (A7)+,D6             ;RESTORE REGISTERS, LEAVING Z FLAG ALONE.
               BRA.S   SEQ_WR_EXIT
;
SEQ_WR_80
               CMP     D7,D7                ;RETURN Z FLAG TRUE IF WE DIDN'T HOOK IN A NEW BLOCK.
;
SEQ_WR_EXIT
               RTS
;
;AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
               TITLE   "WASTELAND RECORD-BUFFERING SETUP UTILITIES"
;VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV
;
; SET UP FOR BUFFERING OF NEWLY-RECORDED EVENTS INTO WASTELAND -
; THIS IS DONE WHEN PLAYBACK IS STARTED, IN CASE WE ARE COMING IN WITH
; PAUSED RECORD TO FACILITATE RECORDING ON THE DOWNBEAT, OR AT ANY OTHER
; TIME WHEN RECORD IS ENABLED AND NO EVENTS HAVE YET BEEN COPIED FROM
; THE EXISTING SEQUENCE TO THE NEW WRITE BLOCK (SUCH AS THE RECORD-LOOP
; INTER-SEQUENCE PERIOD) - WE DON'T WANT TO WRITE SEQUENCE EVENTS AHEAD
; OF THE FIRST BAR-MARKER!
; (NOTE THAT THIS ROUTINE DOES NOT CLEAR OUT THE WASTELAND BUFFER -
; IN THE RECORD-LOOPING CASE THIS WOULD BE INAPPROPRIATE,
; SINCE EVENTS THAT WE WANT MAY BE IN THERE ALREADY.)
;
SET_WASTE_RECORD
               MOVE    #WASTELAND_WRITE,A0  ;VECTOR FOR RECORDING EVENTS INTO WASTELAND -
               MOVE    A0,MIDI_ON_WRITE     ;MIDI NOTE-ONS GO THERE.
               MOVE    A0,NOTE_OFF_WRITE    ;MIDI/PAD NOTE-OFFS GO THERE.
               MOVE    A0,PAD_ON_WRITE      ;PAD NOTE-ONS GO THERE.
               MOVE    A0,NON_NOTE_WRITE    ;EVERYTHING ELSE GOES THERE.
               RTS
;
;
;
; COMING IN FROM SCRATCH, SET UP FOR RECORDING ALL DATA INTO WASTELAND.
; IN THE PROCESS (NATURALLY) WE CLEAR THE WASTE-RECORD COUNT/POINTER.
; (NOTE: THIS IS NOT APPROPRIATE FOR RECORD LOOPING, IN WHICH WE MAY
; WANT TO USE ANY EVENTS WHICH ARE ALREADY IN WASTELAND.)
;
INIT_WASTE_RECORD
               BSR     SET_WASTE_RECORD     ;POINT ALL RECORD VECTORS AT WASTELAND -
                                            ;FALL THROUGH INTO ZERO_WASTE_RECORD,
                                            ;CLEAR WASTELAND RECORD-BUFFER INDICES.
;
;
;
; WASTELAND IS ALSO USED FOR NORMAL RECORD AND PLAYBACK IN CONJUNCTION
; WITH REAL-TIME AUTOCORRECT - NEW EVENTS ARE HELD THERE BEFORE THE
; AUTOCORRECT POINT (WHILE OLD EVENTS ARE COPIED ACROSS BACK INTO THE
; SEQUENCE), AND OLD EVENTS ARE HELD THERE AFTER THE AUTOCORRECT POINT
; (WHILE NEW EVENTS ARE COPIED INTO THE SEQUENCE AT THE AUTOCORRECT
; POINT).  THUS, WHEN PERIODICALLY THE EVENTS BUFFERED IN WASTELAND ARE
; COPIED INTO THE SEQUENCE,THE WASTE-WRITE COUNT AND POINTER MUST BE
; CLEARED, WITHOUT ANY SPECIFIC IMPLIED EFFECT ON RECORD VECTORS.
; IN ADDITION, SINCE THE ROUTINES WHICH DO THIS (E.G. PRO_CLICK) TEND
; TO MAINTAIN THE CURRENT WASTE-WRITE POINTER IN A3 WHILE ACTIVE, WE
; FOLLOW SUIT BY RETURNING WITH A3 POINTING TO THE START OF WASTELAND.
; (NOTE - INIT_WASTE_RECORD FALLS THROUGH INTO US ....)
;
ZERO_WASTE_RECORD
               MOVE    #WASTELAND,A3        ;LOAD ZEROED WRITE POINTER INTO ITS NATIVE REGISTER,
               MOVE    A3,WASTELAND_PTR     ;STORE ZEROED VALUE IN POINTER SAFE-DEPOSIT BOX.
               CLR     WASTELAND_DEPTH      ;ZERO THE COUNT OF WORDS BUFFERED UNDER THIS SYSTEM.
               RTS
;
;AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
               TITLE   "WASTELAND RECORD-BUFFERING UTILITIES"
;VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV
;
; WRITE THE WORD (PRESUMED PART OR WHOLE OF A SEQUENCE EVENT) INTO
; WASTELAND, WHICH IS BEING USED AT THE MOMENT TO BUFFER SUCH THINGS.
; A3 POINTS TO THE PRECISE LOCATION TO WHICH WE WILL WRITE -
; WHEN NOT IN USE, THIS POINTER LIVES IN WASTELAND_PTR(.W).
;
; TIMED_WASTE_WRITE IS USED IN CASES WHERE A CURRENT TIME MARKER MUST
; PRECEDE ANY NEW EVENT BEING WRITTEN BY SEQ_WRITE OR WASTELAND_WRITE.
; IF A TIME MARKER HAS BEEN CREATED AND WRITTEN DURING THE CURRENT
; SEQUENCER CLOCK PERIOD (OR IF AN EXISTING ONE HAS BEEN TRANSFERRED),
; THE FLAG WRITE_NEW_TIME(.B) HAS BEEN SET, INDICATING THAT NO NEW TIME
; MARKER NEED BE GENERATED BY US.  IF NOT, WE CREATE AND WRITE THE TIME
; MARKER (PER CURRENT VALUE OF NOW_CLICK), SET WROTE_NEW_TIME, AND LAST
; BUT NOT LEAST, WRITE THE WORD WE WERE GIVEN TO WRITE.
;
TIMED_WASTE_WRITE
               TST.B   WROTE_NEW_TIME       ;HAVE WE SEEN/MADE A TIME MARKER DURING THIS CLOCK?
               BNE.S   WASTELAND_WRITE      ;BRANCH IF YES, GO WRITE THE WORD WE'VE BEEN GIVEN.
               MOVE    D7,-(A7)             ;ELSE - SET OUR DATA WORD ASIDE,
               MOVE    NOW_CLICK,D7         ;CREATE AND WRITE AN APPROPRIATE TIME MARKER.
               LSL     #4,D7
               OR      #9,D7
               BSR.S   WASTELAND_WRITE      ;USE OUR OWN SELF TO WRITE THE TIME MARKER.
               MOVE    (A7)+,D7             ;RECOVER THE WORD CAME HERE WITH,
               ST      WROTE_NEW_TIME       ;TELL 'EM WE WROTE A TIME MARKER FOR THE CURRENT CLOCK.
;
WASTELAND_WRITE
;
;871013               MOVE    D7,(A3)+             ;WRITE WORD TO SLOT, INC POINTER
;871013               ADDQ    #1,WASTELAND_DEPTH   ; INC COUNT OF WORDS IN HERE
;871013               CMP.W   #END_OF_WASTELAND,A3 ;  TEST IF OUT OF BUFFER MEMORY
;871013               RTS                          ;   RET WITH RESULT ABOVE LEFT IN STATUS FLAGS (Z = FUCKED)
;
               CMP.W   #END_OF_WASTELAND,A3 ;HAVE WE ALREADY FILLED THE BUFFER?
               BNE.S   WASTE_WR_20          ;BRANCH IF NOT, CONTINUE.
               MOVE.B  #WASTE_OVERFLOW,SEQ_ERROR_FLAG ;ELSE - SET FLAG TO INDICATE WHAT HAPPENED,
               MOVE    D0,-(A7)             ;SAVE A COUPLA ENDANGERED REGISTERS
               MOVE    D7,-(A7)             ;(INCLUDING THE WORD WE WERE SUPPOSED TO WRITE),
               BSR.S   WASTELAND_COPY       ;AND, WHAT THE HELL - FUNNEL THE BUFFERED DATA BACK
                                            ;INTO THE MAIN WRITE STREAM.
               MOVE    (A7)+,D7             ;BRING-UM BACK REGISTERS, CONTINUE.
               MOVE    (A7)+,D0
WASTE_WR_20
               MOVE    D7,(A3)+             ;WRITE THE DATA WORD, ADVANCE POINTER.
               ADDQ    #1,WASTELAND_DEPTH   ;INCREMENT THE COUNT OF WORDS STORED IN THE BUFFER.
               RTS
;
;AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
;
;VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV
;
; COPY SEQUENCE EVENTS (IF ANY) BEING HELD IN WASTELAND TO NEW SEQUENCE
; WRITE BLOCK (USES SEQ_WRITE - ASSUMES A6 VALID AS SEQ_WR_PTR).
; RETURNS THROUGH ZERO_WASTE_RECORD, WHICH CLEARS ALL WASTELAND RECORD
; INDICES (A3/WASTELAND_PTR = #WASTELAND, WASTELAND_DEPTH = 0).
; NOTE - NO EFFECT ON SEQUENCE RECORD VECTORS!
; BUT, WILL WASTE D0 AND D7.
;
WASTELAND_COPY
               MOVE    WASTELAND_DEPTH,D0   ;FETCH COUNT OF WORDS (NOT EVENTS!) IN BUFFER -
               BEQ     ZERO_WASTE_RECORD    ;IF BUFFER EMPTY, TAKE THE RETURN PATH RIGHT NOW.
               SUBQ    #1,D0                ;ELSE - PRE-DECREMENT COUNT FOR DBRA COPY LOOP,
               MOVE    #WASTELAND,A3        ;SET POINTER TO START OF BUFFER.
WC_20
               MOVE    (A3)+,D7             ;FETCH A WORD, POINT TO NEXT.
               BSR     SEQ_WRITE            ;WRITE IT HOME.
               BSR     SEQ_MEM_CHECK        ;TEST FOR MEMORY FULL DURING RECORD - PUNCH OUT IF SO.
               DBRA    D0,WC_20             ;DO MORE, IF MORE TO DO.
;
               BRA     ZERO_WASTE_RECORD    ;RESET WASTE-WRITE COUNT/POINTERS, RETURN THROUGH.
;
;AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
               TITLE   "END-OF-SEQ MEMORY STRING RECONNECTION"
;VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV
;
; SEQUENCE DESTRUCTIVE READ HAS HIT END OF SOURCE SEQUENCE -
; THIS ROUTINE TURNS THINGS BACK AROUND, MEMORY-WISE, TO ALLOW FOR
; BAIL-OUT AT THIS POINT, OR START AGAIN FROM TOP (LOOPING RECORD).
;
; UPDATES DIRECTORY INFO FOR NULL SEQUENCE AND LAST_SETUP_SEQ,
; REGARDING START BLOCK INDEXES -
; BLOCK LIST LINK IS CUT WHERE NEW SEQUENCE-END JOINS FREE MEMORY.
; INDEXES OF LAST FREE BLOCK AND NEXT-TO-LAST FREE BLOCK ARE UPDATED.
;
; NOTES:
; TO CONTINUE WITH LOOPING RECORD IT IS NECESSARY TO CALL SEQ1_DRD_SETUP
; AFTER GETTING THROUGH HERE.
; IF BAILING OUT, NEED TO CALL UPDATE_SEQ_SIZE (COVERS CURRENT_SEQUENCE
; AND THE NULL SEQUENCE) TO BRING MEMORY-USAGE FIGURES UP TO DATE.
; YOU WILL DO ONE OR THE OTHER - NOT BOTH!
;
; ALL REGISTERS PRESERVED.
;
SEQ_TURNAROUND
                                            ;SAFEGUARD AGAINST UNFORESEEN SOFTWARE FUCK-UPS:
               TST.B   TURNAR_STATE         ;ARE WE IN TURNAROUND STATE ALREADY?
               BNE.S   SEQ_TURN_00          ;BRANCH IF YES - ERROR CONDITION.
               TST.B   UPDATE_STATE         ;ARE WE IN UPDATE STATE?
               BEQ.S   SEQ_TURN_10          ;BRANCH IF NOT, PROCEED WITH NORMAL OPERATION.
               MOVE.B  #TURN_FOL_UPD,SEQ_ERROR_FLAG   ;ELSE - HOIST FLAG FOR THIS ERROR,
               BRA.S   SEQ_TURN_EXIT                  ;EXIT WITHOUT ACTION.
SEQ_TURN_00
               MOVE.B  #TURN_FOL_TURN,SEQ_ERROR_FLAG  ;TURNAROUND FOLLOWING TURNAROUND - N.F.G.
               BRA.S   SEQ_TURN_EXIT                  ;EXIT WITHOUT ACTION.
;
SEQ_TURN_10
               ST      TURNAR_STATE         ;WE'RE OKAY, SO SET/CLEAR STATE FLAGS ACCORDINGLY.
               SF      CONSOL_STATE
               SF      SETUP_STATE
               SF      UPDATE_STATE
;
;
;
;871013                                            ;FIRST, SOME STONE-BLIND BULLETPROOFING -
;871013                                            ;TURNAROUND NOT LEGAL IF IN TURNAROUND OR UPDATE STATE:
;871013               TST.B   TURNAR_STATE         ;ARE WE IN TURNAROUND STATE ALREADY?
;871013               BNE.S   SEQ_TURN_EXIT        ;BRANCH IF YES - ERROR CONDITION, SO EXIT.
;871013               TST.B   UPDATE_STATE         ;ARE WE IN UPDATE STATE?
;871013               BNE.S   SEQ_TURN_EXIT        ;BRANCH IF YES - ERROR CONDITION, SO EXIT.
;871013;
;871013               ST      TURNAR_STATE         ;WE'RE OKAY, SO SET/CLEAR STATE FLAGS ACCORDINGLY.
;871013               SF      CONSOL_STATE
;871013               SF      SETUP_STATE
;871013               SF      UPDATE_STATE
;
               MOVEM.L A0-A1/D0,-(A7)
;
               MOVE    LAST_SETUP_SEQ,D0    ;FETCH THE NUMBER OF SEQUENCE LAST SET UP FOR READ,
               BSR     GET_SEQ_DIR_PTR      ;SET A0 AS POINTER TO ITS DIRECTORY ENTRY.
;
               TST     SEQ1_DRD_CNT         ;DID WE READ THROUGH THE END OF THE LAST SEQ BLOCK?
               BEQ.S   SEQ_TURN_30          ;BRANCH IF YES - LAST/NEXT-TO-LAST FREE INDEXES OK.
               MOVE    LAST_FREE_BLK,NEXT2LAST_FREE   ;ELSE FORMER LAST FREE IS NOW NEXT-TO-LAST,
               MOVE    SEQ1_DRD_BLK,LAST_FREE_BLK     ;LAST READ BLOCK IS NOW LAST FREE BLOCK -
;
SEQ_TURN_30
               MOVE.L  #SEQ_DIR_99,A1       ;SET A1 AS POINTER TO DIRECTORY ENTRY FOR NULL SEQ.
               MOVE    Q_START_BLK(A1),Q_START_BLK(A0)     ;NEW SEQ START BLK = OLD FREE START BLK.
               CMP     #512,SEQ_WR_CNT      ;DID WE STOP WRITING ON A BLOCK BOUNDARY?
               BNE.S   SEQ_TURN_40          ;BRANCH IF NOT - INCLUDE CURRENT WRITE BLOCK IN SEQ.
                                                      ;ELSE, CURRENT WRITE BLOCK HAS NOT BEEN USED:
               MOVE    SEQ_WR_BLK,Q_START_BLK(A1)     ;FREE MEM START BLK = CURRENT WRITE BLOCK.
               MOVE    PREV_WR_BLK,A1                 ;CUT LINK FOLLOWING PREVIOUS WRITE BLOCK -
               ADD     A1,A1                          ;IT'S AT THE END OF THE SEQUENCE.
               MOVE    #-1,SEQ_BLOCK_LIST(A1)
               BRA.S   SEQ_TURN_80
SEQ_TURN_40
               MOVE    SEQ_WR_BLK,A0        ;CURRENT WRITE BLOCK IS LAST IN SEQUENCE -
               ADD     A0,A0                ;BLOCK IT LINKS TO IS NEW FREE MEM START BLOCK.
               MOVE    SEQ_BLOCK_LIST(A0),Q_START_BLK(A1)
               MOVE    #-1,SEQ_BLOCK_LIST(A0)    ;CUT THE LINK FOLLOWING CURRENT WRITE BLOCK -
                                                 ;IT'S AT THE END OF THE SEQUENCE.
;
SEQ_TURN_80
               MOVEM.L (A7)+,A0-A1/D0
;
SEQ_TURN_EXIT
               RTS
;
;AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
               TITLE   "CONSOLIDATION OF DIVIDED SEQUENCE"
;VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV
;
; BAIL-OUT FROM DESTRUCTIVE SOMETHING OR OTHER IN MID-SEQUENCE -
; SEQUENCE MAY NOW BE TWO PIECES, THIS ROUTINE CONSOLIDATES THE DATA.
;
; FUDGES PLAY-THROUGH TO END OF SEQUENCE, READIES ALL PARAMETERS FOR
; SUBSEQUENT (MANDATORY) CALL TO SEQ_TURNAROUND, ET CET'RA, ET CET'RA.
;
; UTILIZES CURRENT VALUES OF SEQ_WRITE AND SEQ1_DSTR_READ PARAMETERS -
; INCLUDING A5-A6 AS READ AND WRITE POINTERS, RESPECTIVELY.
; ASSUMES NO DATA IS STILL "FLOATING AROUND" IN THE SEQUENCER ITSELF,
; NO EVENT STRADDLING THE READ/WRITE BOUNDARY.
;
; LET'S SAY THAT AGAIN, SINCE CHRIS MISSED IT AND TRIPPED UP ON IT BAD -
; WE ASSUME THAT THE READ IS  N O T  IN THE MIDDLE OF AN EVENT, BUT
; POISED AT THE START - THIS IS BECAUSE SEQ_EATERS MAY BE USED TO RUN
; THROUGH THE DATA, AND THEY START ON THE FIRST WORD ON AN EVENT (SO AS
; TO READ EVENT TYPE).  CONSEQUENCE OF NOT DOING SO IS THE READ/COPY
; GETTING OUT OF STEP, AND SOME UNKNOWN AMOUNT OF DATA BEING TRANSFERED.
;
; IF READ AND WRITE ARE IN STEP WITH RESPECT TO BLOCK BOUNDARIES
; (AS WOULD BE THE CASE DURING PLAYBACK), THE CONSOLIDATION IS PERFORMED
; MAINLY BY MEANS OF LINK-POINTER JUGGLING, TO OPTIMIZE SPEED.
; OTHERWISE, ACTUALLY MOVES ALL DATA WORD BY WORD TO COMPENSATE FOR DATA
; ADDED TO OR REMOVED FROM SEQUENCE DURING WHATEVER IT WAS - BUT DOES IT
; AS FAST AS 68000-LY POSSIBLE .... COPIES THROUGH END-OF-SEQ MARKER.
; DURING THIS PROCEDURE ONLY, ALL INTERRUPTS ARE DISABLED TO SAVE TIME.
;
; DOES NOT UPDATE DIRECTORY INFORMATION !!!!
; (HANDLED BY SUBSEQUENT CALLS TO SEQ_TURNAROUND, UPDATE_SEQ_SIZE).
; DON'T COME HERE IF YOU'RE ALREADY AT END OF SEQUENCE !!!!
; DON'T BOTHER ME AGAIN UNTIL AFTER NEW YEAR'S DAY !!!!!!!!!!!!!!!!!!!
;
; AHEM - POSSIBLY APART FROM A5-A6, ALL REGISTERS PRESERVED.
;
SEQ_CONSOLIDATE
               MOVEM.L D0-D2,-(A7)
;
                                            ;SAFEGUARD AGAINST UNFORESEEN SOFTWARE FUCK-UPS:
               TST.B   CONSOL_STATE         ;ARE WE IN CONSOLIDATE STATE ALREADY?
               BNE.S   SEQ_CONS_00          ;BRANCH IF YES - ERROR CONDITION.
               TST.B   TURNAR_STATE         ;ARE WE IN TURNAROUND STATE ALREADY?
               BNE.S   SEQ_CONS_04          ;BRANCH IF YES - ERROR CONDITION.
               TST.B   UPDATE_STATE         ;ARE WE IN UPDATE STATE?
               BEQ.S   SEQ_CONS_10          ;BRANCH IF NOT, PROCEED WITH NORMAL OPERATION.
               MOVEQ   #CONS_FOL_UPD,D0     ;ELSE - HOIST FLAG FOR THIS ERROR,
               BRA.S   SEQ_CONS_ERROR       ;EXIT WITHOUT ACTION.
SEQ_CONS_00
               MOVEQ   #CONS_FOL_CONS,D0    ;CONSOLIDATE FOLLOWING CONSOLIDATE - UH-UH.
               BRA.S   SEQ_CONS_ERROR       ;EXIT WITHOUT ACTION.
SEQ_CONS_04
               MOVEQ   #CONS_FOL_TURN,D0    ;CONSOLIDATE FOLLOWING TURNAROUND - FUCK NO!
                                            ;EXIT WITHOUT ACTION.
SEQ_CONS_ERROR
               MOVE.B  D0,SEQ_ERROR_FLAG    ;TRIGGER AN ERROR CODE DISPLAY,
               BRA     SEQ_CONS_Z0          ;EXIT WITHOUT ACTION.
;
;
SEQ_CONS_10
               ST      CONSOL_STATE         ;WE'RE OKAY, SO SET/CLEAR STATE FLAGS ACCORDINGLY.
               SF      SETUP_STATE
               SF      TURNAR_STATE
               SF      UPDATE_STATE
;
;871013                                            ;FIRST, SOME STONE-BLIND BULLETPROOFING -
;871013                                            ;CONSOLIDATE IS LEGAL ONLY IF IN SETUP STATE:
;871013               TST.B   CONSOL_STATE         ;ARE WE IN CONSOLIDATE STATE ALREADY?
;871013               BNE     SEQ_CONS_EXIT        ;BRANCH IF YES - ERROR CONDITION, SO EXIT.
;871013               TST.B   TURNAR_STATE         ;ARE WE IN TURNAROUND STATE ALREADY?
;871013               BNE     SEQ_CONS_EXIT        ;BRANCH IF YES - ERROR CONDITION, SO EXIT.
;871013               TST.B   UPDATE_STATE         ;ARE WE IN UPDATE STATE?
;871013               BNE     SEQ_CONS_EXIT        ;BRANCH IF YES - ERROR CONDITION, SO EXIT.
;871013;
;871013               ST      CONSOL_STATE         ;WE'RE OKAY, SO SET/CLEAR STATE FLAGS ACCORDINGLY.
;871013               SF      SETUP_STATE
;871013               SF      TURNAR_STATE
;871013               SF      UPDATE_STATE
;
               CMP     #512,SEQ1_DRD_CNT    ;IS READ COUNT IN THE 0-512 RANGE?
               BLS.S   SEQ_CONS_12          ;BRANCH IF YES, CONTINUE.
               MOVEQ   #DRD_CNT_OVRUN,D0    ;IF READ COUNT > 512, SOMETHING VERY WRONG -
               BRA     SEQ_CONS_ERROR       ;SET ERROR FLAG AND EXIT WITHOUT ACTION.
SEQ_CONS_12
               CMP     #512,SEQ_WR_CNT      ;IS WRITE COUNT ALSO IN THE VALID RANGE?
               BLS.S   SEQ_CONS_14          ;BRANCH IF YES, CONTINUE.
               MOVEQ   #WR_CNT_OVRN,D0      ;ELSE, SET ERROR FLAG AND GET THE HELL OUT.
               BRA     SEQ_CONS_ERROR
;
SEQ_CONS_14
               MOVE    SEQ1_DRD_CNT,D0      ;FETCH REMAINING READ COUNT FOR CURRENT READ BLOCK -
               CMP     #512,D0              ;IF WE HAPPEN TO BE AT BEGINNING OF BOTH READ AND
                                            ;WRITE BLOCKS, WE CAN GO STRAIGHT TO LINK-SWAP ....
               BNE.S   SEQ_CONS_20          ;NOT AT START OF READ BLOCK, GO LOOK AT WRITE COUNT.
;
               CMP     SEQ_WR_CNT,D0        ;IS WRITE COUNT SAME AS READ COUNT (I.E., BOTH = 512)?
               BEQ     SEQ_CONS_E0          ;BRANCH IF YES - GO STRAIGHT FOR LINK-SWAP.
;
SEQ_CONS_20
                                            ;GONNA HAFTA MOVE SOME DATA DIRECTLY -
               CMP.L   #SEQUENCE_RAM,A5     ;FIRST, MAKE SURE READ AND WRITE POINTERS NOT BONGOED:
               BCC.S   SEQ_CONS_22          ;READ POINTER NOT BELOW SEQUENCE_RAM - CONTINUE.
SEQ_CONS_21
               MOVEQ   #DRD_PTR_LOW,D0      ;ELSE, SET FLAG AND EXIT WITHOUT ACTION.
               BRA     SEQ_CONS_ERROR
;
SEQ_CONS_22
               CLR.L   D1                   ;COULD READ PTR ESCAPE FROM SEQ RAM WITHIN READ COUNT?
               MOVE    D0,D1                ;(THIS IS READ COUNT)....
               ADD.L   A5,D1
               CMP.L   #SEQ_RAM_END,D1
               BLS.S   SEQ_CONS_24          ;NOT A PROBLEM, KEEP GOING.
SEQ_CONS_23
               MOVEQ   #DRD_PTR_HIGH,D0     ;U-BET, THIS A PROB'LM - SET FLAG, EXIT WITHOUT ACTION.
               BRA     SEQ_CONS_ERROR
;
SEQ_CONS_24
               CMP.L   #SEQUENCE_RAM,A6     ;READ POINTER CHECKS OUT - HOW ABOUT WRITE POINTER?
               BCC.S   SEQ_CONS_26          ;WRITE POINTER NOT TOO LOW, CONTINUE.
SEQ_CONS_25
               MOVEQ   #WR_PTR_LOW,D0       ;IF WRITE POINTER NOT IN SEQ RAM, SET FLAG AND EXIT.
               BRA     SEQ_CONS_ERROR
;
SEQ_CONS_26
               CLR.L   D1                   ;COULD WRITE PTR ESCAPE FROM SEQ RAM WITHIN WR COUNT?
               MOVE    SEQ_WR_CNT,D1        ;ADD WRITE COUNT TO WRITE POINTER -
               ADD.L   A6,D1
               CMP.L   #SEQ_RAM_END,D1      ;COMPARE -
               BLS.S   SEQ_CONS_28          ;NOT A PROBLEM, KEEP GOING.
SEQ_CONS_27
               MOVEQ   #WR_PTR_HIGH,D0      ;U-BET, THIS A PROB'LM - SET FLAG AND EXIT.
               BRA     SEQ_CONS_ERROR
;
SEQ_CONS_28
               CMP     SEQ_WR_CNT,D0        ;NOT BOTH AT BLOCK START - ARE THEY AT SAME POSITION?
               BNE.S   SEQ_CONS_60          ;BRANCH IF NOT - GONNA HAFTA MOVE IT ALL ....
;
SEQ_CONS_40
                                            ;THEY'RE PARALLEL - COMPLETE COPY OF CURRENT BLOCK,
                                            ;THEN DO LINK-SWAP FOR REMAINDER -
;
               MOVE    (A5)+,(A6)+          ;OKAY - COMPLETE COPY OF CURRENT BLOCK.
               SUBQ    #1,D0
               BNE     SEQ_CONS_40
;
               MOVE    SEQ_WR_BLK,A5        ;DON'T FORGET TO UPDATE BLOCK INDEXES:
               MOVE    A5,PREV_WR_BLK       ;SAVE INDEX OF PREVIOUS WRITE BLOCK,
               ADD     A5,A5                ;FIND NEXT WRITE BLOCK.
               MOVE    SEQ_BLOCK_LIST(A5),SEQ_WR_BLK
               MOVE    #512,SEQ_WR_CNT      ;RESTART WRITE COUNT (FOR CORRECTNESS IN CASE WE EXIT).
               CLR     SEQ1_DRD_CNT         ;ZERO READ COUNT - IN CASE THIS WAS LAST READ BLOCK,
                                            ;SIGNALS SEQ_TURNAROUND NOT TO REPEAT LAST_FREE_BLK,
                                            ;NEXT2LAST_FREE UPDATE WHICH IS DONE HERE.
               MOVE    SEQ1_DRD_BLK,A5      ;FIND NEXT READ BLOCK IF ANY -
               MOVE    LAST_FREE_BLK,NEXT2LAST_FREE   ;FORMER LAST FREE BLOCK NOW NEXT-TO-LAST,
               MOVE    A5,LAST_FREE_BLK               ;FORMER READ BLOCK NOW LAST FREE BLOCK.
               ADD     A5,A5
               MOVE    SEQ_BLOCK_LIST(A5),SEQ1_DRD_BLK
               BMI.S   SEQ_CONS_B0          ;IF NO NEXT READ BLOCK, WE'RE DONE - SKRAMBL.
               BRA.S   SEQ_CONS_E0          ;ELSE - IT'S LINK-SWAPPIN' TIME.
;
;
SEQ_CONS_60
                                            ;WE HAVE NO CHOICE BUT TO CHEW OUR WAY THROUGH ENTIRE
                                            ;SEQUENCE UNTIL WE SEE THE SEQUENCE END-MARKER:
               MOVE    #2700H,SR            ;DISABLE ALL INTERRUPTS TO SPEED THE PROCESS.
               BSR     SEQ1_DSTR_READ       ;READ FIRST WORD OF NEXT EVENT FROM SEQUENCE,
               BRA.S   SEQ_CONS_80          ;SEE WHAT WE GOT.
SEQ_CONS_70
               CMP.L   #SEQ_RAM_END,A5      ;QUICKIE CHECK - MAKE SURE READ AND WRITE POINTERS
               BHI     SEQ_CONS_23          ;HAVE NOT WANDERED ABOVE SEQUENCE_RAM_END -
               CMP.L   #SEQ_RAM_END,A6      ;IF THEY HAVE, MUST BAIL OUT - OH WELL.
               BHI     SEQ_CONS_27
               CMP.L   #SEQUENCE_RAM,A5     ;FOR THAT MATTER - THEY SHOULD NOT HAVE GOTTEN BELOW
               BCS     SEQ_CONS_21          ;SEQUENCE_RAM EITHER -
               CMP.L   #SEQUENCE_RAM,A6     ;IF THEY HAVE, MUST BAIL OUT - OH WELL.
               BCS     SEQ_CONS_25
               MOVE    D7,D0                ;MR. EATER NEEDS EVENT TYPE ID ISOLATED IN D0.
               AND     #0FH,D0
               BSR     SEQ1_RMW_EATER       ;HE GIVES US THIS OUR NEXT EVENT IN D7.
SEQ_CONS_80
               CMP     #000FH,D7            ;IZZIT END-MARKER ALREDDY?
               BNE     SEQ_CONS_70          ;BRANCH IF NOT, GOTTA KEEP CHOMPING OUR WAY THROUGH.
               BSR     SEQ_WRITE            ;ELSE WRITE IT OUT AND SKOOT, HEY.
SEQ_CONS_90
               MOVE    #2000H,SR            ;DON'T FORGET DEM INTERRUPT.
;
SEQ_CONS_B0
               BRA     SEQ_CONS_Z0
;
;
;
; LINK-SWAP CONSOLIDATION -
; ASSUMES READ COUNT AND WRITE COUNT BOTH = 512, READ AND WRITE BLOCK
; MARKER VALUES ARE CURRENT, READ HAS NOT GONE PAST LAST BLOCK IN SEQ.
; UMMM - PREV_WR_BLK, LAST_FREE_BLK VALUES SHOULD ALSO BE CURRENT, YES.
; AS IS OUR DUTY, WE SEEK ONLY TO RESTRUCTURE THINGS TO APPEAR AS THOUGH
; PLAY-THROUGH TO END OF SEQUENCE OCCURRED.
;
SEQ_CONS_E0
               MOVE    #399,D2              ;SAFEGUARD - TRACE NO MORE THAN 400 LINKS, SINCE THAT'S
                                            ;THE NUMBER OF SEQUENCE MEMORY BLOCKS THERE ARE.
;
               MOVE    SEQ_WR_BLK,D1        ;EXTREME CASE - DID WE NOT MOVE ANY DATA?
               CMP     PREV_WR_BLK,D1       ;NO, IF THESE ARE EQUAL (SINCE RD, WR BOTH AT BLK BEG).
               BEQ.S   SEQ_CONS_I0          ;BRANCH IF SO, PROCEDURE IS DIF'RENT.
;
               MOVE    PREV_WR_BLK,A5       ;LAST-USED WRITE BLOCK -
               ADD     A5,A5                ;SET IT TO LINK TO CURRENT READ BLOCK,
               MOVE    SEQ1_DRD_BLK,D0      ;THEREBY UNIFYING SEQUENCE DATA STRING.
               MOVE    D0,SEQ_BLOCK_LIST(A5)
;
SEQ_CONS_G0
               CMP     #400,D0              ;IS LINK VALUE VALID?
               BCS.S   SEQ_CONS_G4          ;BRANCH IF YES, GO ON.
               MOVEQ   #INVALID_LINK,D0     ;ELSE, SET ERROR FLAG AND EXIT.
               BRA.S   SEQ_CONS_P0
SEQ_CONS_G4
               MOVE    D0,A5                ;FIND END-OF-SEQ BLOCK (TRACE FROM CURRENT READ BLK):
               MOVE    D0,PREV_WR_BLK       ;COPY BLOCK INDEXES AS WE TRACE - WHEN WE EXIT LOOP,
               ADD     A5,A5                ;PREV_WR_BLK WILL POINT AT ORIG SEQ END BLK, WHICH WILL
               MOVE    SEQ_BLOCK_LIST(A5),D0     ;LOOK LIKE IT WAS THE LAST ONE WRITTEN INTO.
               BMI.S   SEQ_CONS_G8          ;BRANCH IF WE HIT END-OF-STRING, EXIT THIS LOOP.
               DBRA    D2,SEQ_CONS_G0       ;LOOP AGAIN IF WE HAVEN'T DONE IT TOO MANY TIMES.
               MOVEQ   #LINK_OVRUN,D0       ;ELSE, SET ERROR FLAG AND EXIT AT ONCE.
               BRA.S   SEQ_CONS_P0
;
SEQ_CONS_G8
               MOVE    SEQ_WR_BLK,SEQ_BLOCK_LIST(A5)  ;SEQ END BLOCK LINKS TO WHAT IS NOW FIRST
                                                      ;FREE BLK, AS THOUGH ALL BLOCKS COPIED OVER.
               BRA.S   SEQ_CONS_M0          ;CUT LINK FOLLOWING LAST FREE BLOCK, EXIT.
;
;
SEQ_CONS_I0
                                            ;NO DATA GOT MOVED (EG, STOPPED BEFORE UNPAUSING) -
                                            ;WE GOTS TO MAKE IT LOOK LIKE SOMETHING HAPPENED:
               MOVE.L  #SEQ_DIR_99,A5       ;FUDGE SEQUENCE SHIFTED TO FREE MEMORY AS IF PLAYED -
               MOVE    SEQ1_DRD_BLK,D0
               MOVE    D0,Q_START_BLK(A5)
;
SEQ_CONS_K0
               CMP     #400,D0              ;IS LINK VALUE VALID?
               BCS.S   SEQ_CONS_K4          ;BRANCH IF YES, GO ON.
               MOVEQ   #INVALID_LINK,D0     ;ELSE, SET ERROR FLAG AND EXIT.
               BRA.S   SEQ_CONS_P0
SEQ_CONS_K4
               MOVE    D0,D1                ;SAVE TEST INDEX,
               MOVE    D0,A5                ;TRACE FROM CURRENT READ BLOCK TO END OF SEQUENCE.
               ADD     A5,A5
               MOVE    SEQ_BLOCK_LIST(A5),D0
               BMI.S   SEQ_CONS_G8          ;BRANCH IF WE HIT END-OF-STRING, EXIT THIS LOOP.
               DBRA    D2,SEQ_CONS_K0       ;LOOP AGAIN IF WE HAVEN'T DONE IT TOO MANY TIMES.
               MOVEQ   #LINK_OVRUN,D0       ;ELSE, SET ERROR FLAG AND EXIT AT ONCE.
               BRA.S   SEQ_CONS_P0
;
SEQ_CONS_K8
               MOVE    SEQ_WR_BLK,SEQ_BLOCK_LIST(A5)  ;SEQ END BLOCK LINKS TO WHAT IS NOW FIRST
               MOVE    D1,PREV_WR_BLK                 ;FREE BLOCK, AND POSES AS PREVIOUS WR BLK -
                                                      ;AS THOUGH ENTIRE SEQUENCE WAS COPIED OVER.
;
SEQ_CONS_M0
               MOVE    LAST_FREE_BLK,A5     ;COPY INDEX OF LAST FREE BLOCK TO INDEX OF CURRENT READ
               MOVE    A5,SEQ1_DRD_BLK      ;BLOCK, MAKE IT LOOK LIKE WE READ ALL THE WAY THROUGH.
               ADD     A5,A5                ;CUT THE LINK FROM LAST FREE BLOCK, MAKE IT LOOK LIKE
               MOVE    #-1,SEQ_BLOCK_LIST(A5)    ;IT WAS THE FORMER SEQUENCE END BLOCK.
                                                 ;ASSUMING LAST_FREE_BLK AND NEXT2LAST_FREE HAVE
                                                 ;BEEN MAINTAINED UP TO THIS POINT, WE NEED NOT
                                                 ;DIDDLE THEM IN ANY WAY NOW.
               BRA.S   SEQ_CONS_Z0               ;OUT WE GO.
;
SEQ_CONS_P0
               MOVE.B  D0,SEQ_ERROR_FLAG    ;TRIGGER AN ERROR CODE DISPLAY,
                                            ;EXIT WITHOUT FURTHER ACTION.
;
SEQ_CONS_Z0
               MOVEM.L (A7)+,D0-D2
;
SEQ_CONS_EXIT
               RTS
;
;AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
               SKIP
;VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV
;
; UPDATE SEQUENCE MEMORY-USAGE FIGURES (Q_MEM_USED) -
; FOR LAST_SETUP_SEQ, ALSO FOR NULL SEQUENCE (FREE MEMORY).
;
; ALSO REFRESHES SEQ_MEM_FULL(.B) FLAG AND FREE-MEMORY STRING END
; TRACKING VARIABLES LAST_FREE_BLK AND NEXT2LAST_FREE.
; HOWEVER, SINCE THESE THINGS THEORETICALLY REMAIN CURRENT AND VALID
; ON THEIR OWN WHILE THE SEQUENCER IS RUNNING, AND THE MEMORY-USAGE
; FIGURES ARE MAINLY FOR THE BENEFIT OF THE USER, IT IS NOT REALLY
; NECESSARY TO CALL HERE WHILE THE SEQUENCER IS RUNNING, WHICH COULD
; SAVE SOME TIME AND IMPROVE LOOPING/SONG-MODE PERFORMANCE.
;
; IF CURRENTLY IN SEQUENCE MEMORY STATUS SCREEN, SETS SUBFUN_INSTALL TO
; CAUSE REDISPLAY OF SCREEN WITH NEW STATUS.
;
; ASSUMES SEQUENCE IS CONSOLIDATED AND TURNED-AROUND (SEE ABOVE),
; START BLOCK POINTERS AND ALL LINK POINTERS ARE HUNKI-DORIFIED.
; WHOMPS ON ANY SEQUENCE WHICH APPEARS TO BE EMPTY -
; BY ZEROING-OUT Q_MEM_USED AND Q_STATUS IN ITS DIRECTORY ENTRY.
;
; ALL REGISTERS PRESERVED.
;
UPDATE_SEQ_SIZE
               MOVEM.L D0-D1/A0-A1,-(A7)
;
               TST.B   SETUP_STATE          ;ARE WE IN SETUP STATE?
               BNE.S   UP_SQ_SIZ_00         ;BRANCH IF YES - ERROR CONDITION.
               TST.B   CONSOL_STATE         ;ARE WE IN CONSOLIDATE STATE?
               BEQ.S   UP_SQ_SIZ_10         ;BRANCH IF NOT, PROCEED WITH NORMAL OPERATION.
               MOVEQ   #UPD_FOL_CONS,D0     ;ELSE - SET ERROR FLAG, EXIT WITHOUT ACTION.
               BRA.S   UP_SQ_SIZ_04
UP_SQ_SIZ_00
               MOVEQ   #UPD_FOL_SET,D0      ;UPDATE FOLLOWING SETUP - NOT CRIKIT.
UP_SQ_SIZ_04
               BRA     UP_SQ_SIZ_Y0         ;EXIT WITHOUT FURTHER ACTION.
;
UP_SQ_SIZ_10
               ST      UPDATE_STATE         ;WE'RE OKAY, SO SET/CLEAR STATE FLAGS ACCORDINGLY.
               SF      SETUP_STATE
               SF      CONSOL_STATE
               SF      TURNAR_STATE
;
;
;
;871013                                            ;FIRST, SOME STONE-BLIND BULLETPROOFING -
;871013                                            ;UPDATE NOT LEGAL IF IN SETUP OR CONSOLIDATE STATE:
;871013               TST.B   SETUP_STATE          ;ARE WE IN SETUP STATE?
;871013               BNE     UP_SQ_SIZ_EXIT       ;BRANCH IF YES - ERROR CONDITION, SO EXIT.
;871013               TST.B   CONSOL_STATE         ;ARE WE IN CONSOLIDATE STATE?
;871013               BNE     UP_SQ_SIZ_EXIT       ;BRANCH IF YES - ERROR CONDITION, SO EXIT.
;871013;
;871013               ST      UPDATE_STATE         ;WE'RE OKAY, SO SET/CLEAR STATE FLAGS ACCORDINGLY.
;871013               SF      SETUP_STATE
;871013               SF      CONSOL_STATE
;871013               SF      TURNAR_STATE
;
;
               MOVE    LAST_SETUP_SEQ,D0    ;FETCH THE NUMBER OF SEQUENCE LAST SET UP FOR READ,
               BSR     GET_SEQ_DIR_PTR      ;SET A0 AS POINTER TO ITS DIRECTORY ENTRY.
               MOVE    #399,D1              ;SET A LIMIT FOR LINK TRACING.
;
               CLR     Q_MEM_USED(A0)       ;START WITH A ZERO COUNT FOR BLOCKS USED.
               MOVE    Q_START_BLK(A0),D0   ;FETCH SEQUENCE START BLOCK INDEX.
               BPL.S   UP_SQ_SIZ_20         ;BRANCH IF SOMEONE THERE,
               CLR     Q_STATUS(A0)         ;ELSE CHOP-CHOP, SAVVY?
               BRA.S   UP_SQ_SIZ_30         ;NOW HANDLE NULL SEQUENCE.
;
UP_SQ_SIZ_20
               CMP     #400,D0              ;IS LINK VALUE VALID?
               BCS.S   UP_SQ_SIZ_24         ;BRANCH IF YES, GO ON.
               MOVEQ   #INVALID_LINK,D0     ;ELSE, SET ERROR FLAG AND EXIT.
               BRA.S   UP_SQ_SIZ_Y0
UP_SQ_SIZ_24
               ADDQ    #1,Q_MEM_USED(A0)    ;REGISTER (ANOTHER) BLOCK ON LINE HERE,
               MOVE    D0,A1                ;LOOK FOR NEXT BLOCK IF ANY.
               ADD     A1,A1
               MOVE    SEQ_BLOCK_LIST(A1),D0
               BMI.S   UP_SQ_SIZ_30         ;BRANCH IF WE HIT END-OF-STRING, EXIT THIS LOOP.
               DBRA    D1,UP_SQ_SIZ_20      ;LOOP AGAIN IF WE HAVEN'T DONE IT TOO MANY TIMES.
               MOVEQ   #LINK_OVRUN,D0       ;ELSE, SET ERROR FLAG AND EXIT AT ONCE.
               BRA.S   UP_SQ_SIZ_Y0
;
UP_SQ_SIZ_30
               MOVE    #399,D1              ;SET A LIMIT FOR LINK TRACING IN THE NULL SEQUENCE.
               MOVE.L  #SEQ_DIR_99,A0       ;REPEAT PROCEDURE FOR NULL SEQUENCE.
               CLR     Q_MEM_USED(A0)       ;START WITH A ZERO COUNT FOR BLOCKS USED.
               ST      SEQ_MEM_FULL         ;LIKEWISE - SEQ MEMORY IS FULL UNTIL WE FIND OTHERWISE.
               MOVE    Q_START_BLK(A0),D0   ;FETCH SEQUENCE START BLOCK INDEX.
               BPL.S   UP_SQ_SIZ_34         ;BRANCH IF NOT NEGATIVE, GO ON -
               MOVEQ   #NULL_SEQ_EMPTY,D0   ;ELSE, FLAG AN ERROR CONDITION AND EXIT DIRECTLY.
               BRA.S   UP_SQ_SIZ_Y0
;
UP_SQ_SIZ_34
               MOVE    D0,LAST_FREE_BLK     ;INITIALIZE, INITIALIZE ....
               MOVE    D0,NEXT2LAST_FREE    ;LIKE SO, IN CASE ONLY ONE FREE BLOCK REMAINS.
;871013               BMI.S   UP_SQ_SIZ_50         ;AH SO - IF NO BLOCKS IN NULL SEQ, QUIT NOW AND
;871013                                            ;AVERT IMMEDIATE PROGRAM CRASH.
               ADDQ    #1,Q_MEM_USED(A0)    ;WELL, WE GOT ONE, SO COME ON MISTAH TALLY MAN ....
;
UP_SQ_SIZ_40
               CMP     #400,D0              ;IS THIS BLOCK NUMBER VALID?
               BCS.S   UP_SQ_SIZ_44         ;BRANCH IF YES, CONTINUE.
               MOVEQ   #INVALID_LINK,D0     ;ELSE - OH SHIT, WE IN BIG TROUBLE -
               BRA.S   UP_SQ_SIZ_Y0         ;SET ERROR FLAG AND EXIT WITH NO FURTHER ACTION.
;
UP_SQ_SIZ_44
               ADD     D0,D0                ;FOLLOW LINK PATH TO THE END OF FREE MEM STRING.
               MOVE    D0,A1                ;FETCH INDEX OF NEXT BLOCK -
               MOVE    SEQ_BLOCK_LIST(A1),D0
               BMI.S   UP_SQ_SIZ_50         ;IF THAT WAS THE LAST ONE, WE BE DONE.
               SF      SEQ_MEM_FULL         ;SOON'S WE SEEN MORE'N ONE, MEM-AW-WEE AIN'T FULL -
               MOVE    LAST_FREE_BLK,NEXT2LAST_FREE   ;SO SAVE THAT BLOCK AS NEXT-TO-LAST FREE,
               MOVE    D0,LAST_FREE_BLK               ;STORE NEXT-BLOCK INDEX AS YOU-KNOW-WHO.
               ADDQ    #1,Q_MEM_USED(A0)              ;AND COME ON MISTAH TALLY MAN, TALLY ME RAM -
               DBRA    D1,UP_SQ_SIZ_40      ;LOOP AGAIN IF WE HAVEN'T DONE IT TOO MANY TIMES.
               MOVEQ   #LINK_OVRUN,D0       ;ELSE, SET ERROR FLAG AND EXIT AT ONCE.
               BRA.S   UP_SQ_SIZ_Y0
;
UP_SQ_SIZ_50
               CMP.L   #SEQ_MEM_STAT_SUB,CUR_SUB_BLOCK     ;ARE WE IN SEQ MEMORY STATUS SCREEN?
               BNE.S   UP_SQ_SIZ_Z0                        ;BRANCH IF NOT, EXIT -
               ST      SUBFUN_INSTALL                      ;ELSE REDISPLAY SCREEN WITH NEW STATUS.
               BRA.S   UP_SQ_SIZ_Z0
;
UP_SQ_SIZ_Y0
               MOVE.B  D0,SEQ_ERROR_FLAG    ;SET FLAG FOR ERROR CONDITION DETECTED ABOVE.
;
UP_SQ_SIZ_Z0
               MOVEM.L (A7)+,D0-D1/A0-A1
;
UP_SQ_SIZ_EXIT
               RTS
;
;AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
               SKIP
;VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV
;
; UTILITIES FOR POINTING TO A SEQUENCE'S DIRECTORY -
;
; CALL GET_CUR_SEQ_DIR (ENTER w/ NOTHING) TO GET THE CURRENT SEQUENCE'S,
; PUT THE ONE YOU'RE INTERESTED IN IN D0 AND CALL GET_SEQ_DIR_PTR IF YOU
; WANT SOMEONE ELSE'S.
; RETURNS WITH THE ADDRESS OF THE DIRECTORY ENTRY IN A0 -
; D0 IS ALWAYS PRESERVED.
;
GET_CUR_SEQ_DIR
               MOVE.L  D0,-(A7)
               MOVE    CURRENT_SEQUENCE,D0
               BRA.S   GET_SEQ_DIR_10
;
GET_SEQ_DIR_PTR
               MOVE.L  D0,-(A7)
GET_SEQ_DIR_10
               MOVE.L  #SEQ_DIRECTORY,A0
               MULU    #Q_BLOCK_SIZE,D0
               ADD.L   D0,A0
               MOVE.L  (A7)+,D0
               RTS
;
;AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
               TITLE   "SEQUENCE PARSING UTILITIES"
;VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV
;
; DESIGNED TO SKIP OVER EVENTS WHILE DOING SEQUENCE READ.
;  ASSUMES THE USER HAS ALREADY READ THE FIRST WORD OF THE LATEST PIECE OF DATA, ISOLATED ITS
;  ID NUMBER IN D0, AND DECIDED THAT YOU DIDN'T WANT IT.  EATS THE REST OF WHATEVER
;  SEQUENCE TYPE THAT WAS, AND PULLS THE NEXT WORD (IN D7) - WITH ID NUMBER ISOLATED
;  IN D0 - FOR THE USER'S PERUSAL.
;
; THERE ARE FOUR VARIATIONS OF SEQ_EATER, USED FOR DIFFERENT PURPOSES:
;
;  SEQ1_RMW_EATER - READ DESTRUCTIVELY FROM SEQ1.  WRITE TO FREE BLOCK THE D7 IT
;          ENTERED WITH, PLUS THE REMAINDER OF THAT MESSAGE IT READ.  DOES NOT WRITE
;          THE NEW FIRST WORD IT RETURNS IN D7.
;
;  SEQ_NDRMW_EATER - DOES A NON-DESTRUCTIVE READ, WRITES.  BEST FOR COPY ROUTINES.
;
;  SEQ_NDRD_EATER - DOES NON-DESTRUCTIVE READ FROM CHOSEN SEQUENCE, WRITES NOTHING.
;
;  SEQ1_DRD_EATER - DOES A DESTRUCTIVE READ FROM SEQ1, DOES NOT WRITE ANYTHING.
;
;
; ASSUMES YOU ENTER w/ ID IN D0, AND HAVE DONE THE NEEDED SET-UP (SEQ1_DRD_SETUP,
;  ETC.).  IF YOU DO A READ/MODIFY/WRITE, ALSO ASSUMES THAT YOU HAVE KEPT THE ORIGINAL
;  D7 INTACT WHEN CALLING (WRITES THAT SUCKER BACK).
;
; MODIFIES D0, D7 AND WHATEVER ADDRESS REGISTERS THE VARIOUS READ/WRITES USE (A4/5/6).
;
SEQ1_RMW_EATER
               BSR     SEQ_WRITE            ;FIRST - WRITE HEAD WORD LAST FETCHED.
               ADD     D0,D0                ;MAKE EVENT ID INTO A BRANCH TABLE OFFSET,
               JMP     SEQ1_RMW_EAT_JMP_TBL(PC,D0)    ;BRANCH INTO TABLE.
;
SEQ1_RMW_EAT_JMP_TBL
               BRA.S   EAT1_RMW_0      ;TYPE 0 - NULL, 1 WORD LONG
               BRA.S   EAT1_RMW_2      ; "   1 - INTERNAL ON, 3 WORDS
               BRA.S   EAT1_RMW_1      ; "   2 - INTERNAL OFF, 2 WORDS
               BRA.S   EAT1_RMW_1      ; "   3 - MIDI ON
               BRA.S   EAT1_RMW_1      ; "   4 - MIDI OFF
               BRA.S   EAT1_RMW_1      ; "   5 - OTHER MIDI
               BRA.S   EAT1_RMW_SYSEX  ; "   6 - SYSTEM EXCLUSIVE - VARIABLE LENGTH
               BRA.S   EAT1_RMW_0      ; "   7 - undefined
               BRA.S   EAT1_RMW_1      ; "   8 - BAR MARKER
               BRA.S   EAT1_RMW_0      ; "   9 - TIME MARKER
               BRA.S   EAT1_RMW_1      ; "  10 - TAP TIME OFFSET
               BRA.S   EAT1_RMW_1      ; "  11 - A/R MARKER
               BRA.S   EAT1_RMW_0      ; "  12 - UART TIMING SHIFT
               BRA.S   EAT1_RMW_0      ; "  13 - undefined
               BRA.S   EAT1_RMW_0      ; "  14 - undefined
               BRA.S   EAT1_RMW_0      ; "  15 - undefined
               BRA.S   EAT1_RMW_0      ; "  16 - END OF SEQUENCE
;
EAT1_RMW_2
               BSR     SEQ1_DSTR_READ       ;READ....
               BSR     SEQ_WRITE            ;    ....AND WRITE
EAT1_RMW_1
               BSR     SEQ1_DSTR_READ       ;READ....
               BSR     SEQ_WRITE            ;    ....AND WRITE
EAT1_RMW_0
               BSR     SEQ1_DSTR_READ       ;READ
               MOVE    D7,D0                ;WANT TO ISOLATE THE ID IN D0
               AND     #0FH,D0
               CMP     D0,D0                ;SET Z FLAG TRUE TO SHOW WE HAD ROOM
SEQ1_EAT_FULL
               RTS
;
;
EAT1_RMW_SYSEX      ; GOTTA KEEP EATING 'TILL WE SEE AN EOX (F7) IN ONE OF THE BYTES IN THE NEXT WORD
               BSR     SEQ1_DSTR_READ       ;GRAB NEXT WORD
               BSR     SEQ_WRITE            ;WRITE
               CMP.B   #0F7H,D7             ;EOX IN LOWER BYTE?
               BEQ     EAT1_RMW_0           ;    IF SO, DONE
               LSL     #8,D7                ;         ELSE, SEE IF IN UPPER BYTE
               CMP.B   #0F7H,D7
               BNE     EAT1_RMW_SYSEX       ;         IF NO, KEEP LOOKING
               BRA     EAT1_RMW_0           ;              ELSE, DONE.
;
;AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
               SKIP
;VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV
;
SEQ_NDRMW_EATER
               BSR     SEQ_WRITE            ;FIRST - WRITE HEAD WORD LAST FETCHED
               ADD     D0,D0                ;MAKE EVENT ID INTO A TABLE OFFSET
               JMP     SEQ_NDRMW_EAT_JMP_TBL(PC,D0)
;
SEQ_NDRMW_EAT_JMP_TBL
               BRA.S   EAT_NDRMW_0     ;TYPE 0 - NULL, 1 WORD LONG
               BRA.S   EAT_NDRMW_2     ; "   1 - INTERNAL ON, 3 WORDS
               BRA.S   EAT_NDRMW_1     ; "   2 - INTERNAL OFF, 2 WORDS
               BRA.S   EAT_NDRMW_1     ; "   3 - MIDI ON
               BRA.S   EAT_NDRMW_1     ; "   4 - MIDI OFF
               BRA.S   EAT_NDRMW_1     ; "   5 - OTHER MIDI
               BRA.S   EAT_NDRMW_SYSEX ; "   6 - SYSTEM EXCLUSIVE - VARIABLE LENGTH
               BRA.S   EAT_NDRMW_0     ; "   7 - undefined
               BRA.S   EAT_NDRMW_1     ; "   8 - BAR MARKER
               BRA.S   EAT_NDRMW_0     ; "   9 - TIME MARKER
               BRA.S   EAT_NDRMW_1     ; "  10 - TAP TIME OFFSET
               BRA.S   EAT_NDRMW_1     ; "  11 - A/R MARKER
               BRA.S   EAT_NDRMW_0     ; "  12 - UART TIMING SHIFT
               BRA.S   EAT_NDRMW_0     ; "  13 - undefined
               BRA.S   EAT_NDRMW_0     ; "  14 - undefined
               BRA.S   EAT_NDRMW_0     ; "  15 - undefined
               BRA.S   EAT_NDRMW_0     ; "  16 - END OF SEQUENCE
;
EAT_NDRMW_2
               BSR     SEQ_NDSTR_READ       ;READ....
               BSR     SEQ_WRITE            ;    ....AND WRITE
EAT_NDRMW_1
               BSR     SEQ_NDSTR_READ       ;READ....
               BSR     SEQ_WRITE            ;    ....AND WRITE
EAT_NDRMW_0
               BSR     SEQ_NDSTR_READ       ;READ
               MOVE    D7,D0                ;WANT TO ISOLATE THE ID IN D0
               AND     #0FH,D0
               CMP     D0,D0                ;SET Z FLAG TRUE TO SHOW WE HAD ROOM
SEQ0_EAT_FULL
               RTS
;
;
EAT_NDRMW_SYSEX      ; GOTTA KEEP EATING 'TILL WE SEE AN EOX (F7) IN ONE OF THE BYTES IN THE NEXT WORD
               BSR     SEQ_NDSTR_READ       ;GRAB NEXT WORD
               BSR     SEQ_WRITE            ;WRITE
               CMP.B   #0F7H,D7             ;EOX IN LOWER BYTE?
               BEQ     EAT_NDRMW_0           ;    IF SO, DONE
               LSL     #8,D7                ;         ELSE, SEE IF IN UPPER BYTE
               CMP.B   #0F7H,D7
               BNE     EAT_NDRMW_SYSEX       ;         IF NO, KEEP LOOKING
               BRA     EAT_NDRMW_0           ;              ELSE, DONE.
;
;AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
               SKIP
;VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV
;
SEQ_NDRD_EATER
               ADD     D0,D0                ;MAKE EVENT ID INTO A TABLE OFFSET
               JMP     SEQ_NDRD_EAT_JMP_TBL(PC,D0)
;
SEQ_NDRD_EAT_JMP_TBL
               BRA.S   EAT_NDRD_0      ;TYPE 0 - NULL, 1 WORD LONG
               BRA.S   EAT_NDRD_2      ; "   1 - INTERNAL ON, 3 WORDS
               BRA.S   EAT_NDRD_1      ; "   2 - INTERNAL OFF, 2 WORDS
               BRA.S   EAT_NDRD_1      ; "   3 - MIDI ON
               BRA.S   EAT_NDRD_1      ; "   4 - MIDI OFF
               BRA.S   EAT_NDRD_1      ; "   5 - OTHER MIDI
               BRA.S   EAT_NDRD_SYSEX  ; "   6 - SYSTEM EXCLUSIVE - VARIABLE LENGTH
               BRA.S   EAT_NDRD_0      ; "   7 - undefined
               BRA.S   EAT_NDRD_1      ; "   8 - BAR MARKER
               BRA.S   EAT_NDRD_0      ; "   9 - TIME MARKER
               BRA.S   EAT_NDRD_1      ; "  10 - TAP TIME OFFSET
               BRA.S   EAT_NDRD_1      ; "  11 - A/R MARKER
               BRA.S   EAT_NDRD_0      ; "  12 - UART TIMING SHIFT
               BRA.S   EAT_NDRD_0      ; "  13 - undefined
               BRA.S   EAT_NDRD_0      ; "  14 - undefined
               BRA.S   EAT_NDRD_0      ; "  15 - undefined
               BRA.S   EAT_NDRD_0      ; "  16 - END OF SEQUENCE
;
EAT_NDRD_2
               BSR     SEQ_NDSTR_READ
EAT_NDRD_1
               BSR     SEQ_NDSTR_READ
EAT_NDRD_0
               BSR     SEQ_NDSTR_READ
               MOVE    D7,D0                ;WANT TO ISOLATE THE ID IN D0
               AND     #0FH,D0
               RTS
;
;
EAT_NDRD_SYSEX      ; GOTTA KEEP EATING 'TILL WE SEE AN EOX (F7) IN ONE OF THE BYTES IN THE NEXT WORD
               BSR     SEQ_NDSTR_READ       ;GRAB NEXT WORD, IN D7
;
               CMP.B   #0F7H,D7             ;EOX IN LOWER BYTE?
               BEQ     EAT_NDRD_0                ;    IF SO, DONE
               LSL     #8,D7                ;         ELSE, SEE IF IN UPPER BYTE
               CMP.B   #0F7H,D7
               BNE     EAT_NDRD_SYSEX            ;         IF NO, KEEP LOOKING
               BRA     EAT_NDRD_0                ;              ELSE, DONE.
;
;AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
               SKIP
;VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV
;
SEQ1_DRD_EATER
               ADD     D0,D0                ;MAKE EVENT ID INTO A TABLE OFFSET
               JMP     SEQ1_DRD_EAT_JMP_TBL(PC,D0)
;
SEQ1_DRD_EAT_JMP_TBL
               BRA.S   EAT1_DRD_0      ;TYPE 0 - NULL, 1 WORD LONG
               BRA.S   EAT1_DRD_2      ; "   1 - INTERNAL ON, 3 WORDS
               BRA.S   EAT1_DRD_1      ; "   2 - INTERNAL OFF, 2 WORDS
               BRA.S   EAT1_DRD_1      ; "   3 - MIDI ON
               BRA.S   EAT1_DRD_1      ; "   4 - MIDI OFF
               BRA.S   EAT1_DRD_1      ; "   5 - OTHER MIDI
               BRA.S   EAT1_DRD_SYSEX  ; "   6 - SYSTEM EXCLUSIVE - VARIABLE LENGTH
               BRA.S   EAT1_DRD_0      ; "   7 - undefined
               BRA.S   EAT1_DRD_1      ; "   8 - BAR MARKER
               BRA.S   EAT1_DRD_0      ; "   9 - TIME MARKER
               BRA.S   EAT1_DRD_1      ; "  10 - TAP TIME OFFSET
               BRA.S   EAT1_DRD_1      ; "  11 - A/R MARKER
               BRA.S   EAT1_DRD_0      ; "  12 - UART TIMING SHIFT
               BRA.S   EAT1_DRD_0      ; "  13 - undefined
               BRA.S   EAT1_DRD_0      ; "  14 - undefined
               BRA.S   EAT1_DRD_0      ; "  15 - undefined
               BRA.S   EAT1_DRD_0      ; "  16 - END OF SEQUENCE
;
EAT1_DRD_2
               BSR     SEQ1_DSTR_READ       ;READ (DESTRUCTIVELY) A WORD
EAT1_DRD_1
               BSR     SEQ1_DSTR_READ       ; "          "        "   "
EAT1_DRD_0
               BSR     SEQ1_DSTR_READ       ; "          "        "   " , PLACE IN D7
               MOVE    D7,D0                ;WANT TO ISOLATE THE ID IN D0
               AND     #0FH,D0
               RTS
;
;
EAT1_DRD_SYSEX      ; GOTTA KEEP EATING 'TILL WE SEE AN EOX (F7) IN ONE OF THE BYTES IN THE NEXT WORD
               BSR     SEQ1_DSTR_READ       ;GET THE NEXT WORD
;
               CMP.B   #0F7H,D7             ;EOX IN LOWER BYTE?
               BEQ     EAT1_DRD_0                ;    IF SO, DONE
               LSL     #8,D7                ;         ELSE, SEE IF IN UPPER BYTE
               CMP.B   #0F7H,D7
               BNE.S   EAT1_DRD_SYSEX            ;         IF NO, KEEP LOOKING
               BRA     EAT1_DRD_0                ;              ELSE, DONE.
;
;AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
               SKIP
;VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV
;
;             SUBROUTINES TO SPEED UP TO EDIT_BAR.  STOPS AT THE WORD WRITE AFTER THAT
;              BAR_MARKER (NEED TO PERFORM A READ TO SEE THAT NEXT WORD).  PRESERVES ALL
;              REGISTERS; UPDATES & SAVES READ/WRITE POINTERS.
;
;             ONE DOES A NON-DESTRUCTIVE READ AND NO WRITES, OTHER DOES DESTRUCTIVE READ AND
;              WRITES (AND THERFORE NEEDS A _CONSOLIDATE AFTERWARDS, WHEN FINALLY DONE).
;
D_SEARCH_EDIT_BAR
               MOVEM.L D0-D7/A0-A6,-(A7)
               BSR     SEQ1_DRD_SETUP       ;SET UP READ & WRITE
               MOVE.L  SEQ_WR_PTR,A6        ;LOAD UP READ & WRITE POINTERS
               MOVE.L  SEQ1_DRD_PTR,A5
               BSR     SEQ1_DSTR_READ       ;KICK-START - READ FIRST EVENT
D_RUN_LOOP
               BSR     SEQ_WRITE            ; WRITE WORD WE JUST EXAMINED
               SWAP    D7                   ;  (KNOW IT IS A BAR_MARKER - TWO WORDS, NOMBRE IN SECOND)
               BSR     SEQ1_DSTR_READ       ;   GET SECOND WORD
               BSR     SEQ_WRITE
               CMP     EDIT_BAR,D7          ;    IS THIS THE BAR WE'RE LOOKING FOR?
               BEQ.S   FOUND_SELECTED_BAR   ;         IF SO, GIT
               BSR     SEQ1_DSTR_READ       ;              ELSE, KEEP LOOKING
               MOVE    D7,D0                ;ISOLATE ID NUMBER OF NEXT EVETNT
               AND     #0FH,D0
D_EAT_SLUDGE
               CMP     #8,D0                ; FOUND A BAR_MARKER?
               BEQ.S   D_RUN_LOOP           ;    IF SO, COPY, DECODE, AND SEE IF ONE WE WANT
               CMP     #0FH,D0              ; END OF SEQUENCE?
               BEQ.S   D_HIT_END            ;    IF SO, WRAP UP (PLEASE ENTER W/ GOOD DATA - AVOID THIS!)
               BSR     SEQ1_RMW_EATER       ;         ELSE, EAT REMAINDER, GO ON TO NEXT
               BRA     D_EAT_SLUDGE
;
D_HIT_END
               BSR     SEQ_WRITE            ;WRITE LAST WORD WE LOOKED AT (END_OF_SEQ)
               BSR     SEQ_TURNAROUND       ; WRAP UP NICELY
               BSR     UPDATE_SEQ_SIZE
               MOVE.L  A6,SEQ_WR_PTR        ;  RESAVE POINTERS
               MOVE.L  A5,SEQ1_DRD_PTR
               MOVEQ   #1,D0                ;   SET 'NOT-Z' FLAG TO SIGNAL WOT HAPPENED
               BRA.S   EXIT_D_SEARCH_EDIT
;
FOUND_SELECTED_BAR
               MOVE.L  A6,SEQ_WR_PTR        ;  RESAVE POINTERS
               MOVE.L  A5,SEQ1_DRD_PTR
               CMP     D0,D0                ;   SET 'Z' FLAG THAT WE WERE SUCCESSFUL
EXIT_D_SEARCH_EDIT
               MOVEM.L (A7)+,D0-D7/A0-A6
               RTS
;
;
ND_SEARCH_EDIT_BAR
               MOVEM.L D0-D7/A0-A6,-(A7)
               BSR     SEQ_NDRD_SETUP      ;SET UP READ
               MOVE.L  SEQ_NDRD_PTR,A4      ;LOAD UP READ & WRITE POINTERS
               BSR     SEQ_NDSTR_READ       ;KICK-START - READ FIRST EVENT
ND_RUN_LOOP
               BSR     SEQ_NDSTR_READ       ; KNOW A BAR MARKER - GET 2nd WORD (HAS BAR NOMBRE)
               CMP     EDIT_BAR,D7          ;    IS THIS THE BAR WE'RE LOOKING FOR?
               BEQ.S   N_FOUND_SELECTED_BAR ;         IF SO, GIT
               BSR     SEQ_NDSTR_READ       ;              ELSE, KEEP LOOKING
               MOVE    D7,D0                ;ISOLATE ID NUMBER OF NEXT EVETNT
               AND     #0FH,D0
ND_EAT_SLUDGE
               CMP     #8,D0                ; FOUND A BAR_MARKER?
               BEQ.S   ND_RUN_LOOP          ;    IF SO, COPY, DECODE, AND SEE IF ONE WE WANT
               CMP     #0FH,D0              ; END OF SEQUENCE?
               BEQ.S   ND_HIT_END           ;    IF SO, WRAP UP (PLEASE ENTER W/ GOOD DATA - AVOID THIS!)
               BSR     SEQ_NDRD_EATER       ;         ELSE, EAT REMAINDER, GO ON TO NEXT
               BRA     ND_EAT_SLUDGE
;
ND_HIT_END
               MOVE.L  A4,SEQ_NDRD_PTR      ;  RESAVE POINTERS
               MOVEQ   #1,D0                ;   SET 'NOT-Z' FLAG TO SIGNAL WOT HAPPENED
               BRA.S   EXIT_ND_SEARCH_EDIT
;
N_FOUND_SELECTED_BAR
               MOVE.L  A4,SEQ_NDRD_PTR      ;  RESAVE POINTERS
               CMP     D0,D0                ;   SET 'Z' FLAG THAT WE WERE SUCCESSFUL
EXIT_ND_SEARCH_EDIT
               MOVEM.L (A7)+,D0-D7/A0-A6
               RTS
;
;AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
                SKIP
;VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV
;
; FORMERLY PART OF THE BACKGROUND, THIS SUBROUTINE HANDLES THE CHORES OF
; SWITCHING TO ANOTHER SEQUENCE - NAMELY, CURRENT_SEQUENCE.
;
SEQ_CHANGE_SUB
               MOVE    CURRENT_SEQUENCE,D0  ;SIGNAL CHANGEOVER (DE-ALERT BKGND).
               MOVE    D0,FORMER_SEQUENCE
;
               TST     SONG_SEL_ENABLE      ;LAST TASK - XMIT SONG SELECT OVER MIDI
               BEQ.S   SPLIT_THIS_MESS
               CMP     #99,D0               ;(NULL SEQ XMITTED AS 00)
               BNE.S   JIMI_3
               MOVEQ   #-1,D0
JIMI_3
               ADDQ    #1,D0                ;DO A 1-RELATIVE OFFSET FOR XMISSION
               MOVE    D0,BG_TEMP_1_B       ;(HAVE IN BYTEized FORMAT)
               MOVEQ   #NEG_EXT+0F1H,D0     ;TELL TIMING CHIP WE WANT A DIRECT-CONNECT
               JSR     WRITE_TO_TC
               MOVEQ   #NEG_EXT+0F3H,D0     ; XMIT SONG_SELECT SYSTEM COMMON STATUS BYTE
               JSR     WRITE_TO_TC
               MOVE    BG_TEMP_1_B,D0       ;  THE NUMBER
               JSR     WRITE_TO_TC
               MOVEQ   #NEG_EXT+0FFH,D0     ;   DISCONNECT
               JSR     WRITE_TO_TC
SPLIT_THIS_MESS
;
               BSR     GET_CUR_SEQ_DIR                ;SET A0 AS POINTER TO SEQUENCE DIR BLK.
               MOVE    Q_START_BLK(A0),SEQ1_DRD_BLK   ;SET FIRST BLOCK AS CURRENT READ/PLAY BLOCK.
KLUDGE_5
               MOVE    Q_TOTAL_BARS(A0),TOTAL_BARS    ;OFFLOAD TOTAL BARS
               MOVE    TOTAL_BARS,NOW_LAST_BAR
               MOVE    Q_STATUS(A0),NOW_SEQ_STATUS
               CMP     #99,CURRENT_SEQUENCE ;IDIOM - IF NOT NULL_SEQUENCE
               BNE     ITS_LATE_1           ;    THEN FINE
               CLR     NOW_SEQ_STATUS       ;         ELSE, NOT REALLY ALLOCATED - DO NOT PLAY
ITS_LATE_1
;
               MOVEQ   #1,D0
               MOVE    D0,NOW_BAR           ;PLAYBACK BACK TO BAR 1.
               MOVE    D0,EDIT_BAR          ;EDITING (SEQFUNS2) BACK TO BAR 1.
               MOVE    D0,CUE_BAR           ;CUED-START POSITION BACK TO BAR 1.
;
               MOVEQ   #0,D0
               MOVE    D0,EDIT_BEAT         ;EDITING (SEQFUNS2) BACK TO BEAT 0, CLICK 0.
               MOVE    D0,EDIT_CLICK
;
               SF      CUE_START            ;FORGET ABOUT CUED-START UNTIL TOLD OTHERWISE.
;
               MOVE    Q_TIME_NUM(A0),D1    ;OFFLOAD INITIAL TIME SIG
               MOVE    Q_TIME_DENOM(A0),D0
               MOVE    D1,NOW_NUMERATOR
               EXT     D0
               MOVE    D0,RAW_DENOMINATOR
               LSL     #1,D0                ;(TURN RAW DENOM INTO TABLE OFFSET)
               MOVE    DENOM_DECODE(PC,D0),NOW_DENOMINATOR ;GET CODED DENOM VALUE
               MOVE    DENOM_CLICKS(PC,D0),D0    ;GET CLICKS THIS DENOM
               MULU    NOW_NUMERATOR,D0     ;FIND CLICKS THIS BAR
               MOVE    D0,CLICKS_THIS_BAR
               MOVE    Q_INIT_TEMPO(A0),D0  ;DOWNLOAD NEW INIT TEMPO
               MOVE    D0,INIT_TEMPO_USEC
               MOVE    D0,REF_TEMPO_USEC    ; SET AS CURRENT AND REFERENCE TEMPOS
               MOVE    D0,CUR_TEMPO_USEC
                ABS_LONG
               JSR     USEC_TO_ALL          ;CONVERT TO ALL OTHER MEASURES OT TEMPO (PB, ETC) & TELL TC
                ABS_SHORT
               MOVE    CUR_TEMPO_FPB,INIT_TEMPO_FPB   ;SINCE USEC_TO_ALL WAS KIND ENOUGH TO FIND
               MOVE    CUR_TEMPO_BPM,INIT_TEMPO_BPM   ; TYPES, COPY THEM FORR INIT_'s USE.
;
                ABS_LONG
               JSR     RESET_PUNCHES        ;RESET PUNCH IN/OUT POINTS
                ABS_SHORT
               JSR     OTRA_BAR_CHORES      ;RESET PHASE, METRONOME COUNT, ETC.
               BSR     UPDATE_REPEATS
               CLR.B   TRACKS_MUTED         ;CLEAR OUT TRACK MUTING
               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
;
;AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
