               INCLUDE HPFIXUPS
               TITLE "DISKCMD1"
***************************************************************************************************
***************************************************************************************************
***                                                                                             ***
***            DISKCMD1 - DISK SYSTEM TRANSFER FUNCTION SUBSIDIARY SUBROUTINES                  ***
***                                                                                             ***
***************************************************************************************************
***************************************************************************************************
;
NEG_EXT        EQU     0FFFFFF00H      ;USE IN MOVEQ INSTRUCTIONS WHERE ARG IS
                                       ;80H OR LARGER - HP XASM DOES NOT HANDLE
                                       ;SIGN-EXTEND CORRECTLY.  COSMETIC, KEEPS
                                       ;ACTUAL BYTE VALUE CLEARER.
;
               INCLUDE EQUATES         ;HDW ADDR AND CONSTANT DEFS, ABS_SHORT DIRECTIVE.
;
               INCLUDE S_BLK_EQU       ;SOUND CONTROL BLOCK DEFINITIONS.
;
               INCLUDE DISKDEFS        ;DISK SYSTEM DEFINITIONS, INCLUDING
                                       ;MODEL 2000 SOUND BLOCK DEFINITIONS.
;
               GLB     RETRY,QUIET_RETRY,SEL_SIDE_0,SEL_SIDE_1
               GLB     INDICATE,LOOK_FOR_ADDR
               GLB     READ_DESCRIPTOR,WRITE_DESCRIPTOR
               GLB     SET_RAM_INTFC,SET_IFC_SIDE_DOOR,SET_IFC_BACK_DOOR
               GLB     ADVANCE_REC,DISP_XFR_SCREEN
               GLB     MOVE_SECTOR_5,SECTOR_5_RECOVER
               GLB     MOVE_SEQ_DIRECTORY,RCVR_SEQ_DIRECTORY
               GLB     MOVE_SEQ_BLOCK_LIST,RCVR_SEQ_BLOCK_LIST
               GLB     MOVE_SONG_LIST,RCVR_SONG_LIST
               GLB     MOVE_CUE_LIST,RCVR_CUE_LIST
               GLB     MOVE_MIDI_BLOCK,MOVE_SEQ_SYS_BLOCK
               GLB     MOVE_SMPTE_BLOCK
               GLB     MOVE_DESCRIPTOR
               GLB     SOUND_PARAMS_MOVE,MOVE_PAD_PARAMS,MOVE_PADS_ASAP
               GLB     SAMPLE_MOVE
               GLB     MOVE_SEQ_DATA,SEQ_DATA_RECOVER
;
               EXTERNAL  TO_TRK_00          ;EXTERNAL ROM.
               EXTERNAL  BLIND_SEEK
               EXTERNAL  RE_SEEK
               EXTERNAL  CHECK_SPEED
               EXTERNAL  ADDR_READ
               EXTERNAL  SECTOR_READ
               EXTERNAL  CORP_ID_STR
               EXTERNAL  READ_UPWARD
               EXTERNAL  WRITE_UPWARD
               EXTERNAL  DISP_SCREEN
               EXTERNAL  DLY_20_MSEC
               EXTERNAL  SECTOR_VER
               EXTERNAL  SECTOR_WRITE
               EXTERNAL  QUERY
               EXTERNAL  STEP_INWARD
               EXTERNAL  VER_12_BIT
               EXTERNAL  READ_12_BIT
               EXTERNAL  WRITE_12_BIT
               EXTERNAL  READ_HD_DESCRIPTOR,WRITE_HD_DESCRIPTOR
               EXTERNAL  NOTNAMED_STRING
;
               EXTERNAL  Q_NAME             ;SEQUENCE DIRECTORY DEFINITIONS.
               EXTERNAL  Q_BLOCK_SIZE
;
               EXTERNAL  RETRIES            ;RAM.
               EXTERNAL  CURRENT_TRACK
               EXTERNAL  CURRENT_SIDE
               EXTERNAL  MISC_OUT_STAT
               EXTERNAL  LED_OUT_STAT
               EXTERNAL  ADDR_BUF
               EXTERNAL  BEGIN_TRUNC
               EXTERNAL  CUR_XFR_ADDR
               EXTERNAL  DISK_OP_CODE
               EXTERNAL  CURRENT_REC
               EXTERNAL  CURRENT_SEC
               EXTERNAL  SECTOR_OFFSET
               EXTERNAL  WASTELAND_2
               EXTERNAL  DIRECTORY_BUF
               EXTERNAL  FINAL_REC
               EXTERNAL  FIN_REC_BYTES
               EXTERNAL  SEQUENCE_RAM
               EXTERNAL  SEQ_DIRECTORY
               EXTERNAL  SEQ_BLOCK_LIST
               EXTERNAL  SONG_LIST
               EXTERNAL  SONG_UNIT_SEL
               EXTERNAL  CURRENT_SONG
               EXTERNAL  CUELIST_BLOCK
               EXTERNAL  CUE_BLK_SIZE
               EXTERNAL  SMPTE_BLOCK
               EXTERNAL  SMPTE_BLK_SIZE
               EXTERNAL  MIDI_BLOCK
               EXTERNAL  MIDI_BLK_SIZE
               EXTERNAL  SEQ_SYS_BLOCK
               EXTERNAL  SEQ_BLK_SIZE
               EXTERNAL  BYTE_LENGTH
               EXTERNAL  S_BLK_00
               EXTERNAL  PAD_SOUNDS
               EXTERNAL  FIN_REC_WORDS
               EXTERNAL  BEG_REC_WORDS
               EXTERNAL  BEG_REC_BYTES
               EXTERNAL  TRUNC_BYTES
               EXTERNAL  DRIVE_SEL
               EXTERNAL  FD_DESCR_BUF
               EXTERNAL  FD_MODEL_ID
               EXTERNAL  FD_FIRMWR_REV
               EXTERNAL  FD_DISK_TYPE
               EXTERNAL  FD_QFILE_STAT
               EXTERNAL  FD_DESCR_LEN
               EXTERNAL  CUR_MODEL_ID
               EXTERNAL  CUR_FIRMWR_REV
               EXTERNAL  CUR_FILE_TYPE
               EXTERNAL  CUR_WRT_PROT
               EXTERNAL  CUR_QFILE_STAT
               EXTERNAL  CUR_BANK_NAME
               EXTERNAL  FD_DISK_NAME
               SKIP
;VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV
;
; SET UP FOR RETRY OF A FAILED DISKLOWx OPERATION (FLOPPY ONLY) -
; WHEN CALLED, D0 CONTAINS ERROR CODE RETURNED BY THE DISKLOWx ROUTINE.
;
; TESTS VALUE OF RETRIES (.W) -
; IF = 5:  RETURNS WITH Z FLAG FALSE, SAME ERROR CODE IN D0.
; IF = 4:  INCREMENTS IT, MOVES HEAD TO TRACK 00, BACK TO CURRENT_TRACK.
; IF = 0-3: INCREMENTS IT, CALLS RE_SEEK (STEP AWAY 1 TRACK AND RETURN).
;
; QUIET_RETRY IS SAME, BUT WON'T TO RECALIBRATE TO TRACK 00 ON LAST
; RETRY - INSTEAD, DOES SAME AS IS DONE FOR FIRST FOUR ATTEMPTS.
;
; IF RE_SEEK IS DONE, RETURNS WITH Z FLAG TRUE IF SEEK WAS SUCCESSFUL -
; ELSE RETURNS Z FLAG FALSE AND SEEK ERROR CODE IN D0.
; USES/DESTROYS D0-D1.
;
;
QUIET_RETRY
               CMP     #5,RETRIES           ;HOW MANY RETRIES OF THIS OPERATION SO FAR?
               BCS.S   RETRY_20             ;BRANCH IF LESS THAN FIVE, DO ANOTHER.
;
;
RETRY
               CMP     #5,RETRIES           ;HOW MANY RETRIES OF THIS OPERATION SO FAR?
               BCS.S   RETRY_10             ;BRANCH IF LESS THAN FIVE, DO ANOTHER.
               TST     D0                   ;FIVE RETRIES FAILED - UPDATE Z FLAG FOR D0 ERROR CODE,
               BRA.S   RETRY_EXIT           ;THEN EXIT.
RETRY_10
               CMP     #4,RETRIES           ;DONE FOUR YET?
               BCS.S   RETRY_20             ;BRANCH IF NOT -
               BSR     TO_TRK_00            ;ELSE, STEP HEAD OUT TO TRACK 00.
               BNE.S   RETRY_EXIT           ;EXIT IF WE DIDN'T MAKE IT.
               ADDQ    #1,RETRIES           ;MADE IT - BUMP THE RETRY TALLY UP BY ONE.
               MOVE    CURRENT_TRACK,D0     ;NOW RETURN TO CURRENT_TRACK.
               BSR     BLIND_SEEK
               BRA.S   RETRY_EXIT           ;RETURN THROUGH WITH COMPLETION CODES FROM BLIND_SEEK.
RETRY_20
               ADDQ    #1,RETRIES           ;TALLY UP ANOTHER RETRY.
               BSR     RE_SEEK              ;JAM HEAD OUT TO TRACK 0, THEN BACK TO WHERE IT WAS.
                                            ;PASS RE_SEEK RETURN CODE BACK AS RETRY RETURN CODE.
RETRY_EXIT
               RTS
;
;AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
               SKIP
;VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV
;
; FLOPPY DISK DRIVE SIDE SELECT -
; USE TO GUARANTEE SYNCHRONIZATION BETWEEN SIDE SELECTED IN HARDWARE AND
; THE VALUE OF CURRENT_SIDE (WHICH REPRESENTS THAT STATUS IN SOFTWARE).
; NO REGISTERS USED.
;
SEL_SIDE_0
               CLR     CURRENT_SIDE
               BCLR    #2,MISC_OUT_STAT
               MOVE.B  MISC_OUT_STAT,MISC_OUT
               RTS
;
;
SEL_SIDE_1
               MOVE    #1,CURRENT_SIDE
               BSET    #2,MISC_OUT_STAT
               MOVE.B  MISC_OUT_STAT,MISC_OUT
               RTS
;
;
;AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
;
;
;
;VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV
;
; LIGHT A KIT/BANK LED FOR CURRENT SECTOR OR TRACK AS PASSED IN D0 -
; USE MODULO 8, NATCH.
; ALL EVERYTHING PRESERVED - NEW LED STATUS IS NOT SAVED ANYWHERE.
; (ASSUMES BACKGROUND OUT OF THE PICTURE, SO AS NOT TO STEP ON THIS.)
;
INDICATE
               MOVEM.L D0-D1,-(A7)          ;SAVE US, SAVE US.
               AND     #7,D0
               MOVE    LED_OUT_STAT,D1      ;YAH, WHY NOT USE UPPER BYTE STATUS.
               MOVE.B  INDICATE_TABLE(PC,D0),D1  ;GETTEN DER BITTEN PATTERNEN.
               NOT     D1                   ;WHY NOT?  BECAUSE LED CONTROL IS INVERTED.
               MOVE    D1,LED_OUTPUT
               MOVEM.L (A7)+,D0-D1
               RTS
;
;
INDICATE_TABLE
               DC.B    00000001B
               DC.B    00000010B
               DC.B    00000100B
               DC.B    00001000B
               DC.B    00010000B
               DC.B    00100000B
               DC.B    01000000B
               DC.B    10000000B
;
;AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
               SKIP
;VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV
;
; "IS ANYTHING THERE" TEST FOR FLOPPY DISK -
; TRY TO DETECT AN ADDRESS ID MARK ON CURRENT TRACK, SIDE.
; IF ONE IS FOUND, READ IT INTO ADDR_BUF AND COMPARE ITS TRACK AND SIDE NUMBERS
; AGAINST CURRENT_TRACK, CURRENT_SIDE.
; WHEN A VALID ADDRESS ID HAS BEEN READ, THE FULL ADDR_BUF FORMAT IS:
;              0 -  TRACK #
;              1 -  SIDE #
;              2 -  SECTOR #
;              3 -  SECTOR SIZE CODE
;              4 -  ID CRC 1
;              5 -  ID CRC 2
; RETURNS ERROR CODE IN D0, Z FLAG CLEAR IF A MATCHING SECTOR ID
; IS NOT FOUND WITHIN 1.25 DISK REVOLUTIONS -
; ELSE RETURNS D0 CLEAR, Z FLAG SET.
; USES/DESTROYS D0-D3, A0.
;
LOOK_FOR_ADDR
               CLR     RETRIES               ;TRY TO DETECT AN ADDRESS ID MARK ON CURRENT TRACK.
LK_ADDR_1
               BSR     ADDR_READ            ;BUFFER ANY ID FOUND INTO ADDR_BUF (6 BYTES TOTAL) -
                                            ;RETURNS WHEN AN ID MARK IS READ OR AFTER 1.25 REVS.
               BEQ.S   LK_ADDR_2            ;IF AN ADDRESS MARK WAS READ WITHOUT ERRS, INSPECT IT.
               BSR     RETRY                ;ELSE SET UP FOR RETRY OF ADDRESS MARK READ.
               BEQ     LK_ADDR_1            ;BRANCH IF (ANOTHER) RETRY OK, ELSE TEST ERROR CODE.
               CMP.B   #DRQ_TIMEOUT,D0      ;THIS ERROR CODE INDICATES NO ADDRESS MARK WAS FOUND.
               BEQ.S   LK_ADDR_3
               CMP.B   #NO_SECTOR,D0        ;SO DOES THIS ONE, BUT SHOULDN'T GET A CHANCE TO OCCUR.
               BEQ.S   LK_ADDR_3
               BRA.S   LK_ADDR_4            ;FOR ANY OTHER ERROR CODE, RETURN GENERIC ERROR CODE.
;
LK_ADDR_2
                                            ;ADDRESS MARK WAS READ:
               MOVE.B  ADDR_BUF,D0          ;COMPARE TRACK # READ FROM DISK WITH EXPECTED VALUE.
               CMP.B   CURRENT_TRACK+1,D0
               BNE.S   LK_ADDR_5            ;INVALID FORMAT IF THEY AREN'T MATCHED.
               MOVE.B  ADDR_BUF+1,D0        ;COMPARE SIDE NUMBER FROM DISK WITH EXPECTED VALUE.
               CMP.B   CURRENT_SIDE+1,D0
               BNE.S   LK_ADDR_5            ;INVALID FORMAT IF THEY AREN'T MATCHED.
               CLR     D0                   ;IF HERE, A VALID ADDR MARK WITH CORRECT SIDE AND TRACK
               BRA.S   LK_ADDR_EXIT         ;NUMBERS WAS READ - RETURN WITH "NO ERROR" STATUS.
;
LK_ADDR_3
               MOVEQ   #NO_FORMAT,D0
               BRA.S   LK_ADDR_EXIT
LK_ADDR_4
               MOVEQ   #GENERIC_ERROR,D0
               BRA.S   LK_ADDR_EXIT
LK_ADDR_5
               MOVEQ   #INVAL_FORMAT,D0
LK_ADDR_EXIT
               RTS
;
;AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
               SKIP
;VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV
;
; READ DESCRIPTOR(S) FROM DISK (FLOPPY OR SCSI) -
; IF FOUND, TRANSFER CERTAIN INFO TO COMMON LOCATIONS FOR TESTING.
; THIS IS A PRELIMINARY STEP IN EVERY DISK ACCESS.
;
; DRIVE_SEL DETERMINES WHETHER FLOPPY OR SCSI DISK IS ACCESSED.
; IF USING SCSI DRIVE, BANK_SEL DETERMINES WHICH BANK TO ACCESS.
;
; RETURNS D0 = 0, Z FLAG TRUE IF VALID DESCRIPTOR FOUND,
; ELSE RETURNS ERROR CODE IN D0 AND Z FLAG FALSE.
; NOTE:  THIS IS IN CONTRAST TO MOST DISK SYSTEM ROUTINES, WHICH RETURN
; Z FLAG TRUE BUT D0 UNDEFINED IF NO ERRORS OCCURRED.
;
; INFO WHICH IS PROVIDED IN EITHER CASE:
; CUR_MODEL_ID:        MODEL # STRING FOR MACHINE WHICH WROTE DISK -
;                      VALID FOR ALL SEQUENTIAL DISKS.
; THE FOLLOWING ARE PROVIDED ONLY FOR 440 FLOPPY/SCSI DISKS:
; CUR_FIRMWR_REV:      REVISION CODE INDICATING FORMAT ON DISK.
; CUR_FILE_TYPE:       TYPE OF DATA IN DISK OR BANK BEING ACCESSED.
; CUR_WRT_PROT:        BANK WRITE-PROTECT STATUS (VALID FOR SCSI ONLY).
; CUR_QFILE_STAT:      STATUS OF CUELIST FILE IN DISK OR BANK.
; PROPHET 2000/2002 FLOPPY DISKS LEAVE OTHER INFO IN FD_DESCR_BUF -
; REFER TO TRANSFER_2000 OR RAM_440 FOR DETAILS.
;
; PROCEDURE FOR FLOPPY DISK:
; ALWAYS CLEARS CUR_WRT_PROT (SINCE WE DON'T KNOW UNTIL WE TRY WRITING).
; ASSUMES READ/WRITE HEAD IS POSITIONED OVER TRACK 00 -
; EITHER SIDE IS OK, IT WILL SELECT SIDE 0 AS FIRST STEP.
; DESCRIPTOR RECORD IS IN SECTOR 5, TRACK 00, SIDE 0 -
; IF FOUND, READS IT INTO FD_DESCR_BUF AND INSPECTS CONTENTS.
; SPECIFICALLY, LOOK FOR '(C)SEQUENTIAL' STRING AT START OF DESCRIPTOR -
; THE '-1986' (OR '1985' WHICH IS FOUND ON A 2000 DISK) IS IGNORED.
; IF THIS STRING IS THERE, THEN DESCRIPTOR IS CONSIDERED VALID AND OTHER
; INFO IS TRANSFERRED TO COMMON DESCRIPTOR INFO LOCATIONS.
; DESTROYS D0-D3, A0-A1, PROBABLY A6 - WHO KNOWS, AND WHY TAKE CHANCES.
;
; PROCEDURE FOR SCSI HARD DISK:
; OUTPUT AND RETURN CONVENTIONS ARE SIMILAR, BUT DETAILS ARE QUITE
; DIFFERENT - REFER TO SCSI MODULES, SPECIFICALLY READ_HD_DESCRIPTOR.
;
READ_DESCRIPTOR
               CLR.L   CUR_MODEL_ID         ;WIPE OUT WHATEVER WAS ALREADY THERE.
               TST     DRIVE_SEL            ;WHAT DISK ARE WE LOOKING AT?
               BPL     READ_HD_DESCRIPTOR   ;BRANCH IF USING SCSI HARD DISK - SEPARATE PROCEDURE.
;
               CLR     CUR_WRT_PROT         ;FLOPPY - ASSUME NO WRITE-PROTECT UNTIL FURTHER NOTICE.
               BSR     SEL_SIDE_0           ;FLOPPY DESCRIPTOR RECORD IS ON DISK SIDE 0.
               CLR     CURRENT_TRACK        ;ON TRACK 00, THAT IS.
               BSR     LOOK_FOR_ADDR        ;FIRST MAKE SURE THERE IS A VALID FORMAT ON DISK -
               BNE     RD_DES_EXIT          ;EXIT WITH ERROR CODE IF NOT FOUND.
;
               CLR     RETRIES              ;SO FAR SO GOOD - TRY TO READ DESCRIPTOR SECTOR.
RD_DES_10
               MOVEQ   #5,D0                ;SET UP SECTOR NUMBER.
               MOVE    #FD_DESCR_LEN,D2     ;READ ONLY THE DEFINED PORTION OF THE SECTOR.
               MOVE    #FD_DESCR_BUF,A0     ;HERE'S WHERE TO PUT IT.
               CLR.B   BEGIN_TRUNC          ;READ FROM BEGINNING, NO DATA SKIPPAGE.
               BSR     SECTOR_READ
               BEQ.S   RD_DES_20            ;IF NO ERRORS DURING DATA READ, INSPECT THE DATA.
               BSR     RETRY                ;ELSE SET UP FOR RETRY OF DESCRIPTOR SECTOR READ.
               BEQ     RD_DES_10            ;BRANCH IF (ANOTHER) RETRY CAN BE DONE,
               MOVEQ   #INVAL_FORMAT,D0     ;ELSE RETURN INVALID FORMAT ERROR CODE.
               BNE.S   RD_DES_EXIT
RD_DES_20
               MOVE    #FD_DESCR_BUF,A0     ;LOOK FOR CORP_ID_STR IN THIS PART OF DESCR_BUF -
               MOVE.L  #CORP_ID_STR,A1      ;COMPARE IT AGAINST ROM STRING USED IN FORMATTING.
               MOVEQ   #13,D0               ;CHECK ONLY FOR '(C)SEQUENTIAL' - IGNORE DATE, MODEL.
RD_DES_30
               CMPM.B  (A0)+,(A1)+
               BNE.S   RD_DES_90            ;EXIT IF MISMATCH OCCURS.
               SUBQ    #1,D0                ;MATCHED - KNOCK DOWN BYTE-COMPARE COUNT,
               BNE     RD_DES_30            ;LOOP BACK IF NOT DONE.
;
                                            ;LOOKS LIKE A SEQUENTIAL KINDA DISK HERE:
               MOVE.L  #30343430H,D0        ;WAS IT A 440 MACHINE BROUGHT IT TO LIFE?
               MOVE.L  FD_MODEL_ID,D1
               CMP.L   D0,D1
               BNE.S   RD_DES_40            ;BRANCH IF NOT, SEE IF IT WAS A 2000 MACHINE.
               MOVE.L  D0,CUR_MODEL_ID                ;ELSE, SET CUR_MODEL_ID TO '0440' -
               MOVE    FD_FIRMWR_REV,CUR_FIRMWR_REV   ;SET UP OTHER PERTINENT INFO AS WELL.
               MOVE    FD_DISK_TYPE,CUR_FILE_TYPE
               MOVE    FD_QFILE_STAT,CUR_QFILE_STAT
               CMP.B   #'/',FD_DISK_NAME+4  ;LOOK FOR OLD FLOPPY (BEFORE DISK NAMING AVAILABLE) -
               BNE.S   RD_DES_80            ;IF WE DON'T SEE THIS, NAME'S PROBABLY FOR REAL - EXIT.
               MOVE.L  #NOTNAMED_STRING,A0  ;ELSE, STICK IN THE DEFAULT FLOPPY DISK NAME STRING.
               MOVE.L  (A0)+,FD_DISK_NAME
               MOVE.L  (A0)+,FD_DISK_NAME+4
               BRA.S   RD_DES_80            ;EXIT WITH Z FLAG TRUE, D0 = 0.
;
RD_DES_40
               MOVE.B  FD_MODEL_ID-1,D1     ;SEE IF WE CAN SEE ALL CHARS FROM '2000' MODEL STRING.
               CMP.L   #30303032H,D1        ;OUT OF ORDER HERE, WE SHOULD NOW HAVE '0002' -
               BNE.S   RD_DES_90            ;BRANCH IF NOT, TELL 'EM WE DON'T RELATE.
               ROR.L   #8,D1                ;ELSE, SET CUR_MODEL_ID = '2000'.
               MOVE.L  D1,CUR_MODEL_ID
                                            ;AND NOW, BEGONE WITH Z FLAG TRUE, D0 = 0.
;
RD_DES_80
               CLR     D0                   ;EXIT WITH D0 CLEAR, Z FLAG SET IF ALL CHARS MATCHED.
               BRA.S   RD_DES_EXIT
;
RD_DES_90
               MOVEQ   #INVAL_FORMAT,D0     ;IF ID STRING NOT PERFECTLY MATCHED, OR IF WE CANNOT
                                            ;MAKE SENSE OF MODEL NUMBER, FORMAT IS INVALID.
RD_DES_EXIT
               RTS
;
;AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
               SKIP
;VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV
;
; WRITE (UPDATED) INFO TO FLOPPY DISK OR SCSI BANK DESCRIPTOR -
; DRIVE_SEL DETERMINES WHETHER FLOPPY DISK OR SCSI DISK IS INVOLVED.
; IF USING SCSI DRIVE, BANK_SEL DETERMINES WHICH BANK TO ACCESS.
;
; CALLED DURING SAVE ALL SOUNDS, SAVE ALL SEQS, SAVE CUELIST FILE -
; I.E., WHENEVER DISK FILE STATUS IS SUBJECT TO CHANGE.
; INFO FROM MASTER DESCRIPTOR IS COPIED INTO THE FLOPPY DISK DESCRIPTOR
; BUFFER OR THE SCSI BANK DESCRIPTOR BUFFER - THIS INCLUDES THE CURRENT
; SOUND OR SEQUENCE BANK NAME, EXCEPT FOR CUELIST SAVES WHICH DO NOT
; EFFECT A NAME CHANGE.
;
; IMPORTANT NOTE:  MOVE_DESCRIPTOR (FOR FLOPPY DISK) USES DISK_OP_CODE
; TO ASCERTAIN ITS DATA TRANSFER DIRECTION, SO MAKE SURE NOT TO CALL
; HERE UNLESS DISK_OP_CODE IS SET UP FOR A SAVE OPERATION.
;
; RETURNS Z FLAG TRUE IF TRANSFER IS SUCCESSFUL,
; ELSE RETURNS Z FLAG FALSE AND ERROR CODE IN D0.
; FLOPPY VERSION DESTROYS D0-D3, A0-A1, PROBABLY A6 - WHO KNOWS,
; AND WHY TAKE CHANCES?
; REFER TO SCSI MODULES FOR THE SCSI SIDE OF THE STORY.
;
WRITE_DESCRIPTOR
               TST     DRIVE_SEL            ;WE BE USING FLOPPY OR SCSI DISK?
               BPL     WRITE_HD_DESCRIPTOR  ;BRANCH IF IT BE SCSI, THINGS DONE ELSEWHERE.
;
               MOVE    CUR_FIRMWR_REV,FD_FIRMWR_REV   ;SET UP PARAMS IN FLOPPY DISK DESCRIPTOR BUF.
               MOVE    CUR_FILE_TYPE,FD_DISK_TYPE
               MOVE    CUR_QFILE_STAT,FD_QFILE_STAT
               MOVE    DISK_OP_CODE,D0      ;ARE WE SAVING TO CUELIST ONLY?
               BTST    #CUELIST_BIT,D0
               BNE.S   WR_DES_20            ;BRANCH IF YES, DON'T MESS WITH FLOPPY NAME.
               TST     CUR_FILE_TYPE        ;ELSE - WHAT KIND OF FILE ARE WE SAVING?
               BEQ.S   WR_DES_10            ;BRANCH IF SOUND FILE, USE SOUND BANK NAME.
               MOVE.L  CUR_BANK_NAME+8,FD_DISK_NAME   ;ELSE, USE SEQUENCE BANK NAME.
               MOVE.L  CUR_BANK_NAME+12,FD_DISK_NAME+4
               BRA.S   WR_DES_20
WR_DES_10
               MOVE.L  CUR_BANK_NAME,FD_DISK_NAME     ;USE SOUND BANK NAME.
               MOVE.L  CUR_BANK_NAME+4,FD_DISK_NAME+4
WR_DES_20
               BSR     MOVE_DESCRIPTOR      ;WELL, WE'RE ALL SET - LET'S DO IT.
                                            ;PASS RETURN STATUS THROUGH.
WR_DESCR_EXIT
               RTS
;
;AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
               SKIP
;VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV
;
; SET UP SAMPLE RAM INTERFACE FOR READING OR WRITING PER CURRENT DISK OPERATION.
; CUR_XFR_ADDR CONTAINS STARTING ADDRESS FOR THE TRANSFER -
; SINCE SAMPLE LOADS FROM DISK ARE ALWAYS SENT INTO THE FREE RAM AREA,
; FINAL ADDRESS DEFAULTS TO = 80000H (TOP OF SAMPLE RAM, 512K).
; BUT, WHO KNOWS?  MAY SOMEDAY WANT TO SEND IT OTHER ADDRESSES ....
; HENCE, THE SIDE DOOR AND BACK DOOR ENTRANCES.
; USES/DESTROYS D0-D2.
;
SET_RAM_INTFC
               MOVE.L  #80000H,D1           ;DEFAULT UPPER ADDRESS TO TOP OF SAMPLE RAM.
SET_IFC_SIDE_DOOR
               MOVE.L  CUR_XFR_ADDR,D0
SET_IFC_BACK_DOOR
               MOVE    DISK_OP_CODE,D2
               BTST    #LOAD_BIT,D2
               BNE.S   SET_IFC_30           ;BRANCH IF LOAD, SET UP FOR WRITE TO RAM.
                ABS_LONG
               JSR     READ_UPWARD          ;FOR SAVE OR VERIFY, SET UP FOR READ FROM RAM.
                ABS_SHORT
               BRA.S   SET_IFC_EXIT
SET_IFC_30
                ABS_LONG
               JSR     WRITE_UPWARD
                ABS_SHORT
SET_IFC_EXIT
               RTS
;
;AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
;
;
;
;VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV
;
; ADVANCE LOGICAL AND PHYSICAL SAMPLE RECORD POINTERS TO NEXT LOGICAL
; RECORD OF A SAMPLE-DATA OR SEQUENCE-DATA FILE (FLOPPY DISKS ONLY).
; SECTOR-SLIP ALGORITHM (OFFSET ONE PER TRACK) IS IMPLEMENTED HERE.
; USES/DESTROYS D0.
;
ADVANCE_REC
               ADDQ    #1,CURRENT_REC        ;ADVANCE LOGICAL RECORD POINTER.
               MOVE    CURRENT_SEC,D0        ;SET UP CURRENT_TRACK, CURRENT_SEC, SECTOR_OFFSET FOR
               CMP     #4,D0                 ;NEXT LOGICAL RECORD OF CURRENT SAMPLE FILE/SUB-FILE.
               BNE.S   ADV_REC_D
               CLR     D0                    ;AFTER SECTOR 4, WRAP AROUND TO ZERO -
               BRA.S   ADV_REC_E             ;SECTOR 5 NOT USED FOR SAMPLE DATA STORAGE.
ADV_REC_D
               ADDQ    #1,D0                 ;OTHERWISE, JUST INCREMENT SECTOR NUMBER.
ADV_REC_E
               CMP     SECTOR_OFFSET,D0      ;5 SECTORS DONE ON THIS TRACK?
               BEQ.S   ADV_REC_F             ;BRANCH IF YES.
               MOVE    D0,CURRENT_SEC        ;NO - STORE NEW SECTOR NUMBER, STAY ON SAME TRACK.
               BRA.S   ADV_REC_EXIT
ADV_REC_F
               CMP     #4,D0                 ;MOVING TO NEXT TRACK - SET NEW SECTOR OFFSET
               BNE.S   ADV_REC_G             ;(INDICATES FIRST SECTOR TO BE ACCESSED ON NEW TRACK).
               CLR     D0
               BRA.S   ADV_REC_H
ADV_REC_G
               ADDQ    #1,D0
ADV_REC_H
               MOVE    D0,SECTOR_OFFSET
               MOVE    D0,CURRENT_SEC
               ADDQ    #1,CURRENT_TRACK
ADV_REC_EXIT
               RTS
;
;AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
               SKIP
;VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV
;
; DISPLAY SCREEN INDICATING TYPE OF TRANSFER IN PROGRESS -
; SIMPLISTIC, PROBABLY TO BE EXPANDED LATER.
; PRESERVES ALL REGISTERS.
;
DISP_XFR_SCREEN
               MOVEM.L D0/A1,-(A7)
               TST     DRIVE_SEL            ;ARE WE USING EXTERNAL SCSI DISK?
               BPL.S   DXSCR_08             ;BRANCH IF YES, NO NEED TO CHECK MODEL_ID - ELSE,
;
               CMP.L   #32303030H,CUR_MODEL_ID   ;SEE IF WE GOT A MODEL 2000/2002 FLOPPY DISK HERE.
               BNE.S   DXSCR_08             ;BRANCH IF MISMATCH - TREAT THIS AS A 440 DISK.
               MOVE.L  #LOAD_2000_SCRN,A1   ;ELSE, PUT UP SCREEN FOR LOAD FROM 2000 DISK.
               BRA.S   DXSCR_30
;
DXSCR_08
               MOVE    DISK_OP_CODE,D0
               BTST    #SAVE_BIT,D0
               BNE.S   DXSCR_10
               BTST    #VERIFY_BIT,D0
               BNE.S   DXSCR_20
               MOVE.L  #LOADING_SCREEN,A1
               BRA.S   DXSCR_30
DXSCR_10
               MOVE.L  #SAVING_SCREEN,A1
               BRA.S   DXSCR_30
DXSCR_20
               MOVE.L  #VERIFYING_SCREEN,A1
DXSCR_30
                ABS_LONG
               JSR     DISP_SCREEN
                ABS_SHORT
;
               MOVEM.L (A7)+,D0/A1
DXSCR_EXIT
               RTS
;
;
SAVING_SCREEN
               ASC     "  SAVING DATA   "
               ASC     "  TO DISK ....  "
VERIFYING_SCREEN
               ASC     " VERIFYING DATA "
               ASC     "   ON DISK .... "
LOADING_SCREEN
               ASC     " LOADING DATA   "
               ASC     " FROM DISK .... "
LOAD_2000_SCRN
               ASC     " LOADING FROM   "
               ASC     " 2000 DISK .... "
;
;AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
               SKIP
;VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV
;
; GENERIC FLOPPY DISK SECTOR-5 FILE TRANSFER ROUTINE -
; FOR SEQUENCE DIRECTORY, SEQUENCE BLOCK LIST, CUE LIST, SONG LIST, ETC.
; TYPE OF TRANSFER (SAVE, LOAD, VERIFY) IS CONTROLLED BY DISK_OP_CODE.
; (NOTE - IF DIR_BIT IS SET IN DISK_OP_CODE, IT IS ASSUMED THAT A SONG
; OR SEQUENCE DIRECTORY IS TO BE EXTRACTED INTO WASTELAND.)
;
; EXPECTS DISK SIDE SELECTED BEFORE CALLING HERE, NOTHING ELSE ASSUMED.
; IF SIDE 0 SELECTED, STEPS INWARD BY ONE TRACK FOR EACH NEW RECORD -
; IF SIDE 1, STEPS OUTWARD BY ONE TRACK FOR EACH NEW RECORD.
; APART FROM STEP DIRECTION, ALL OTHER ASPECTS OF SAVE/VERIFY ARE THE
; SAME ON BOTH DISK SIDES (FOR LOAD THEY DIFFER SLIGHTLY - SEE BELOW).
; THIS IS THE IMPLEMENTATION OF REDUNDANT SEQUENCE DATA STORAGE -
; ASSUMING THAT DISK ERRORS ARE MORE LIKELY ON INNER TRACKS, WE MAKE
; CERTAIN THAT NO PORTION OF THE DATA GETS RECORDED ON THE INNER TRACKS
; ON BOTH SIDES OF THE DISK.
;
; UPON ENTRY, STARTING TRACK NUMBER MUST BE IN D0 - HOWEVER, IT IS NOT
; NECESSARY TO HAVE PRE-POSITIONED THE HEAD OVER THIS TRACK.
; WE USE IT TO SET CURRENT_TRACK UPON ARRIVING HERE.
; STARTING RECORD IS TAKEN AS RECORD 0, D1 CONTAINS THE NUMBER OF
; THE FINAL RECORD TO TRANSFER - WE TEMP-STORE IT IN FINAL_REC.
; (NOTE THAT THE RECORD NUMBERS USED HERE ARE RELATIVE TO THE TRANSFER
; START RECORD - IN THE NORMAL CASE OF A FULL-FILE TRANSFER, THEY ARE
; ALSO EQUAL TO ABSOLUTE FILE RECORD NUMBERS, WHICH ALWAYS START AT 0).
; D2 CONTAINS THE NUMBER OF BYTES TO TRANSFER TO/FROM THE FINAL RECORD -
; WE TEMP-STORE IT IN FIN_REC_BYTES UPON ARRIVING.
; FOR ALL OTHER RECORDS, TRANSFER LENGTH IS 256 BYTES.
; A0 CONTAINS STARTING RAM TRANSFER ADDRESS -
; WE TEMP-STORE IT IN CUR_XFR_ADDR (.L), UPDATE IT AS WE GO.
; FINALLY, A6 POINTS TO THE AREA OF RAM IN WHICH A BAD-RECORD REPORT
; IS TO BE COMPILED (SIDE 0 LOAD ONLY) - MORE ON THIS BELOW.
;
; QUIET_RETRY IS USED DURING ERROR-RECOVERY PROCESS TO MINIMIZE THE TIME
; TAKEN UP BY THE RECOVERY PROCESS, AS WELL AS ITS VISIBILITY.
;
; DURING LOAD OPERATION ON SIDE 0, A LIST IS BUILT (SOMEWHERE IN
; WASTELAND_2, AS DIRECTED BY A6 ENTRY VALUE) OF THE RECORDS WHICH
; FAILED TO TRANSFER CORRECTLY AFTER THE MAXIMUM NUMBER OF RETRIES -
; FILE TRANSFER PROCEEDS WITHOUT USER QUERY WHILE DOING THIS.
; UPON RETURN, THE INITIAL A6 ADDRESS CONTAINS THE BAD-RECORD COUNT,
; WHILE BAD RECORD LIST (IF ANY) APPEARS IN SUBSEQUENT WORD LOCATIONS.
; THIS LIST CAN SUBSEQUENTLY BE USED TO LOAD MISSING DATA FROM MATCHING
; RECORDS ON DISK SIDE 1 - BUT, DISCREETLY, MAN.
;
MOVE_SECTOR_5
               MOVE    D0,CURRENT_TRACK     ;STASH TRANSFER PARAMETERS ASIDE.
               MOVE    D1,FINAL_REC
               MOVE    D2,FIN_REC_BYTES
               MOVE    DISK_OP_CODE,D1      ;ER .... BEFORE WE STORE THIS LAST ONE -
               BTST    #DIR_BIT,D1          ;ARE WE DOING DIRECTORY EXTRACTION?
               BEQ.S   SECTOR5_08           ;NO?  OK - NEVER MIND.
               MOVE    #WASTELAND_2,A0      ;ELSE, BUFFER DIRECTORY RECORDS HERE FOR NAME-EXTRACT.
SECTOR5_08
               MOVE.L  A0,CUR_XFR_ADDR
               CLR     CURRENT_REC          ;FIRST TRANSFER RECORD IS NUMBER 0.
               CLR     (A6)                 ;KEEP BAD-RECORD COUNT HERE - CLEAR IT OUT.
                                            ;START LISTING BAD RECORD NUMBERS ONE WORD UP.
;
SECTOR5_10
               MOVE    CURRENT_TRACK,D0     ;FETCH CURRENT TRACK NUMBER,
               BSR     INDICATE             ;PUT IT UP IN (LITTLE RED) LIGHTS.
               BSR     BLIND_SEEK           ;HEAD FOR THIS TRACK,
               BSR     DLY_20_MSEC          ;LET HEAD SETTLE ONTO IT.
               CLR     RETRIES              ;START WITH CLEAN SLATE PER RECORD.
;
SECTOR5_30
               MOVEQ   #5,D0                ;SECTOR 5 - ALWAYS.
               MOVE.L  CUR_XFR_ADDR,A0      ;FETCH CURRENT RAM TRANSFER ADDRESS.
               SF      BEGIN_TRUNC          ;SKIP NO DATA ANYWHERE.
               MOVE    #256,D2              ;NORMALLY TRANSFER ENTIRE SECTOR AS ONE RECORD -
               MOVE    FINAL_REC,D1         ;IS THIS THE LAST RECORD?
               CMP     CURRENT_REC,D1
               BNE.S   SECTOR5_34           ;BRANCH IF NOT, TRANSFER LENGTH CORRECT.
               MOVE    FIN_REC_BYTES,D2     ;USE SPECIFIED TRANSFER LENGTH FOR FINAL RECORD.
SECTOR5_34
               MOVE    DISK_OP_CODE,D1      ;LET'S REMIND OURSELVES WHAT WE ARE DOING -
               BTST    #DIR_BIT,D1
               BNE.S   SECTOR5_40           ;BRANCH IF DOING DIRECTORY EXTRACTION.
               BTST    #SAVE_BIT,D1
               BNE.S   SECTOR5_50           ;BRANCH IF SAVING TO DISK.
               BTST    #VERIFY_BIT,D1
               BNE.S   SECTOR5_58           ;BRANCH IF VERIFY DATA ON DISK.
                                            ;IF NONE OF ABOVE, ASSUME LOAD FROM DISK.
SECTOR5_40
               BSR     SECTOR_READ
               BRA.S   SECTOR5_60
SECTOR5_50
               BSR     SECTOR_WRITE
               BRA.S   SECTOR5_60
SECTOR5_58
               BSR     SECTOR_VER
SECTOR5_60
               BEQ.S   SECTOR5_80           ;BRANCH IF NO ERROR OCCURRED DURING TRANSFER.
               CMP.B   #PROTECTD_DISK,D0    ;WAS THERE A WRITE-PROTECT ERROR?
               BNE.S   SECTOR5_70           ;BRANCH IF NOT, GO INTO RETRY SEQUENCE.
               TST     D0                   ;ELSE, RESTORE Z FLAG PER D0 ERROR CODE,
               BRA     SECTOR5_EXIT         ;EXIT WITH ERROR STATUS.
SECTOR5_70
               BSR     QUIET_RETRY          ;SET UP FOR A RETRY OF SECTOR TRANSFER.
               BEQ     SECTOR5_30           ;BRANCH IF (ANOTHER) RETRY IS POSSIBLE.
               TST     CURRENT_SIDE         ;IF NOT - ARE WE ON SIDE 1?
               BNE.S   SECTOR5_78           ;BRANCH IF YES, DO NORMAL USER QUERY THING.
               MOVE    DISK_OP_CODE,D1      ;WE'RE ON SIDE 0,
               BTST    #LOAD_BIT,D1         ;SO SEE IF WE'RE DOING A LOAD -
               BNE.S   SECTOR5_74           ;BRANCH IF YES, SPECIAL HANDLING APPLIES.
               BTST    #DIR_BIT,D1          ;NOT LOADING - HOWSABOUT DIRECTORY EXTRACTION?
               BEQ.S   SECTOR5_78           ;BRANCH IF NOT, NORMAL USER QUERY TIME.
SECTOR5_74
               BSR     CHECK_SPEED          ;SIDE 0 READ - WAS ERROR CAUSED BY DISK REMOVAL?
               BNE     SECTOR5_EXIT         ;SINCE NO QUERY ON ERROR, THIS IS THE ONLY WAY TO STOP!
               ADDQ    #2,(A6)              ;DISK STILL THERE, SO INCREMENT BAD-RECORD COUNT,
               MOVE    (A6),D1              ;FETCH COUNT FOR USE AS BAD-RECORD LIST OFFSET,
               MOVE    CURRENT_REC,0(A6,D1) ;STORE THE RECORD NUMBER AT THE END OF THE LIST.
               BRA.S   SECTOR5_80           ;PROCEED TO NEXT RECORD WITHOUT BOTHERING USER.
SECTOR5_78
               CMP.B   #VERIFY_ERR,D0       ;ARE WE DEALING WITH A DATA COMPARE ERROR?
               BEQ.S   SECTOR5_7A           ;BRANCH IF YES, SPELL IT OUT STRAIGHT -
               MOVEQ   #GENERIC_ERROR,D0    ;ELSE SET GENERIC-ERROR STATUS,
SECTOR5_7A
               BSR     QUERY                ;ASK USER WHAT-ALL TO DO ABOUT THIS.
               BNE.S   SECTOR5_EXIT         ;BRANCH IF ERROR-ABORT (E.G., DISK REMOVAL).
               BCS.S   SECTOR5_EXIT         ;BRANCH IF USER SAID "GIVE IT UP."
               BSR     DISP_XFR_SCREEN      ;USER SAID "KEEP GOING" - RESTORE TRANSFER SCREEN.
;
SECTOR5_80
               MOVE    DISK_OP_CODE,D1      ;ARE WE DOING DIRECTORY EXTRACTION?
               BTST    #DIR_BIT,D1
               BEQ.S   SECTOR5_88           ;BRANCH IF NOT - HEAD STRAIGHT TO NEXT RECORD.
               MOVE    CURRENT_REC,D0       ;YES - WE'RE GONNA NEED THIS.
               BTST    #SONG_BIT,D1         ;SO - ARE WE DOING SONGS DIRECTORY?
               BNE.S   SECTOR5_82           ;BRANCH IF YES, ELSE ASSUME SEQUENCE DIRECTORY -
               LSL     #6,D0                ;RECORD NUMBER DETERMINES WHERE NAMES GO IN LIST.
               MOVEQ   #7,D1                ;EIGHT ENTRIES PER RECORD, HENCE EIGHT NAMES, HEY.
               BRA.S   SECTOR5_84
SECTOR5_82
               ADD     D0,D0                ;SONGS DIRECTORY - ONE NAME PER FOUR SONG RECORDS.
               CLR     D1                   ;STOP AFTER EXTRACTING ONE NAME.
               ADDQ    #3,CURRENT_REC       ;A-AND, SKIP NEXT THREE RECORDS (REST OF THIS SONG).
               ADDQ    #3,CURRENT_TRACK     ;THIS ROUTINE SIDE 0 ONLY FOR DIRECTORY EXTRACTION.
SECTOR5_84
               EXT.L   D0
               MOVE.L  D0,A0                ;COPY OFFSET INTO DIRECTORY BEING COMPILED -
               ADD.L   #DIRECTORY_BUF,A0    ;DIRECTORY IS COMPILED IN DIRECTORY_BUF.
               MOVE    #WASTELAND_2,A1      ;THIS IS WHERE DISK RECORD IS BUFFERED Y'KNOW.
SECTOR5_86
               MOVE.L  (A1),(A0)+
               MOVE.L  4(A1),(A0)+
               ADD     #Q_BLOCK_SIZE,A1
               DBRA    D1,SECTOR5_86        ;YEH, LITTLE BIT O' SLOP IN LAST RECORD - WHO ASKED YA?
               BRA.S   SECTOR5_8A           ;SKIP TRANSFER ADDRESS UPDATE, GO ON TO NEXT RECORD.
SECTOR5_88
               ADD.L   #256,CUR_XFR_ADDR    ;UPDATE CURRENT TRANSFER ADDRESS.
SECTOR5_8A
               MOVE    FINAL_REC,D1         ;DID WE JUST TRANSFER LAST RECORD OF FILE?
               CMP     CURRENT_REC,D1
               BEQ.S   SECTOR5_EXIT         ;BRANCH IF YES, EXIT WITH NO-ERROR STATUS.
               ADDQ    #1,CURRENT_REC       ;ELSE, ADVANCE TO NEXT RECORD.
               TST     CURRENT_SIDE         ;STEP TO NEW TRACK PER DISK SIDE WE ARE ON -
               BNE.S   SECTOR5_90           ;BRANCH IF SIDE 1, WE GO DOWN BY ONE TRACK.
               ADDQ    #1,CURRENT_TRACK     ;FOR SIDE 0, GO UP BY ONE TRACK.
               BRA     SECTOR5_10
SECTOR5_90
               SUBQ    #1,CURRENT_TRACK
               BRA     SECTOR5_10
;
SECTOR5_EXIT
               RTS
;
;AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
               SKIP
;VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV
;
; DATA RECOVERY PROCEDURE FOR SECTOR-FIVE FILES -
; SEQUENCE DIRECTORY AND BLOCK LIST, SONG LIST, CUE LIST.
;
; A6 POINTS TO A BAD-RECORD COUNT FOLLOWED BY THE LIST OF BAD RECORD
; NUMBERS COMPILED DURING A READ FROM SIDE 0 OF ONE OF THE ABOVE FILES.
; ATTEMPTS TO READ CORRESPONDING RECORDS FROM REDUNDANT FILE ON SIDE 1,
; SELECTS SIDE 1 AS FIRST STEP WHEN WE GET HERE.
;
; D0 CONTAINS THE TRACK NUMBER AT WHICH THE CORRESPONDING REDUNDANT
; FILE BEGINS ON SIDE 1 - WE TEMP-STORE IT ON THE STACK.
; A0.L CONTAINS RAM ADDRESS AT WHICH THE FILE (FIRST RECORD) RESIDES -
; WE TEMP-STORE IT IN CUR_XFR_ADDR (IT STAYS PUT DURING THIS PROCEDURE).
; D1 INDICATES THE FINAL RECORD NUMBER OF THIS FILE, AS THE TRANSFER
; LENGTH FOR THIS RECORD IS SOMETIMES SOMETHING OTHER THAN 256 BYTES -
; D2 INDICATES THE TRANSFER LENGTH FOR THE FINAL RECORD, WHETHER 256
; BYTES OR NOT.  THESE ARE TEMP-STORED IN FINAL_REC, FIN_REC_BYTES.
;
; NORMAL RETRY AND USER QUERY UPON HARD ERROR IS USED HERE, AS OPPOSED
; TO SIDE 0 READ IN WHICH QUIET_RETRY AND NO USER QUERY SERVE TO LEND
; A SOMEWHAT LOWER PROFILE TO THE ERROR-RECOVERY PROCEDURE.
;
SECTOR_5_RECOVER
               BSR     SEL_SIDE_1           ;TO BE SURE.
               MOVE    D0,-(A7)             ;SAVE SIDE 1 FILE STARTING TRACK NUMBER.
               MOVE    D1,FINAL_REC         ;SAVE FILE FINAL RECORD NUMBER.
               MOVE    D2,FIN_REC_BYTES     ;SAVE FINAL RECORD BYTE TRANSFER COUNT.
               MOVE.L  A0,CUR_XFR_ADDR      ;SAVE FILE START ADDRESS.
               MOVE    (A6)+,-(A7)          ;STORE BAD-RECORD COUNT, STEP TO FIRST BAD REC NUMBER.
;
SEC5REC_20
               MOVE    (A6),D0              ;FETCH BAD-RECORD NUMBER - WE STEP OUT BY THAT NUMBER
               NEG     D0                   ;OF TRACKS FROM INITIAL FILE TRACK (ONE RECORD PER).
               ADD     2(A7),D0             ;THAT'S WHERE WE PUT INITIAL TRACK, YOU REMEMBER.
               MOVE    D0,CURRENT_TRACK     ;SAVE IT IN CASE WE NEED TO DO RETRY,
               BSR     INDICATE             ;PUT IT UP IN LIGHTS, TOO.
               BSR     BLIND_SEEK           ;GO FOR IT,
               BSR     DLY_20_MSEC          ;GET SETTLED ONTO IT.
               CLR     RETRIES              ;START WITH A CLEAN SLATE PER RECORD.
SEC5REC_40
               MOVE    #WASTELAND_2,A0      ;SET TRANSFER ADDRESS USED FOR DIRECTORY EXTRACTION -
               MOVE    DISK_OP_CODE,D1      ;SEE IF THAT'S WHAT WE'RE DOING.
               BTST    #DIR_BIT,D1
               BNE.S   SEC5REC_44           ;WE ARE, SO TRANSFER ADDRESS IS SET.
               MOVE    (A6),D0              ;ELSE - FETCH BAD-RECORD NUMBER,
               MULU    #256,D0              ;USE IT TO COMPUTE RECORD TRANSFER ADDRESS.
               ADD.L   CUR_XFR_ADDR,D0      ;OFFSET FROM FILE START ADDRESS.
               MOVE.L  D0,A0
SEC5REC_44
               SF      BEGIN_TRUNC          ;SKIP NO DATA ANYWHERE.
               MOVEQ   #5,D0                ;SECTOR 5, OF COURSE.
               MOVE    #256,D2              ;DEFAULT TO 256-BYTE TRANSFER LENGTH.
               MOVE    (A6),D1              ;FETCH RECORD NUMBER AGAIN -
               CMP     FINAL_REC,D1         ;IS IT THE LAST RECORD IN FILE?
               BNE.S   SEC5REC_60           ;BRANCH IF NOT, USE DEFAULT TRANSFER LENGTH -
               MOVE    FIN_REC_BYTES,D2     ;ELSE USE FINAL-RECORD LENGTH.
SEC5REC_60
               BSR     SECTOR_READ          ;READ THE SECTOR, EH?
               BEQ.S   SEC5REC_80           ;BRANCH IF SECTOR WAS READ WITHOUT ERROR.
               BSR     RETRY                ;ELSE, SET UP FOR A RETRY OF SECTOR TRANSFER.
               BEQ     SEC5REC_40           ;BRANCH IF (ANOTHER) RETRY IS POSSIBLE.
               MOVEQ   #UNRECOVERABLE,D0    ;ELSE SET UNRECOVERABLE READ ERROR STATUS,
               BSR     QUERY                ;ASK USER WHAT-ALL TO DO ABOUT THIS.
               BNE.S   SEC5REC_A0           ;BRANCH IF ERROR-ABORT (E.G., DISK REMOVAL).
               BCS.S   SEC5REC_A0           ;BRANCH IF USER SAID "GIVE IT UP."
               BSR     DISP_XFR_SCREEN      ;USER SAID "KEEP GOING" - RESTORE TRANSFER SCREEN.
;
SEC5REC_80
               MOVE    DISK_OP_CODE,D1      ;ARE WE DOING A DIRECTORY EXTRACTION?
               BTST    #DIR_BIT,D1
               BEQ.S   SEC5REC_90           ;BRANCH IF NOT, GO STRAIGHT TO NEXT RECORD.
               MOVE    (A6),D0              ;YES - FETCH RECORD NUMBER, WE'RE GONNA NEED IT.
               BTST    #SONG_BIT,D1         ;SO - ARE WE DOING SONGS DIRECTORY?
               BNE.S   SEC5REC_82           ;BRANCH IF YES, ELSE ASSUME SEQUENCE DIRECTORY -
               LSL     #6,D0                ;RECORD NUMBER DETERMINES WHERE NAMES GO IN LIST.
               MOVEQ   #7,D1                ;EIGHT ENTRIES PER RECORD, HENCE EIGHT NAMES, HEY.
               BRA.S   SEC5REC_84
SEC5REC_82
               ADD     D0,D0                ;SONGS DIRECTORY - ONE NAME PER FOUR SONG RECORDS.
               CLR     D1                   ;STOP AFTER EXTRACTING ONE NAME.
SEC5REC_84
               EXT.L   D0
               MOVE.L  D0,A0                ;COPY OFFSET INTO DIRECTORY BEING COMPILED -
               ADD.L   #DIRECTORY_BUF,A0    ;DIRECTORY IS COMPILED IN DIRECTORY_BUF.
               MOVE    #WASTELAND_2,A1      ;THIS IS WHERE DISK RECORD IS BUFFERED Y'KNOW.
SEC5REC_86
               MOVE.L  (A1),(A0)+
               MOVE.L  4(A1),(A0)+
               ADD     #Q_BLOCK_SIZE,A1     ;THIS OF COURSE APPLIES ONLY TO SEQ DIR EXTRACTION.
               DBRA    D1,SEC5REC_86        ;YEH, LITTLE BIT O' SLOP IN LAST RECORD - WHO ASKED YA?
;
SEC5REC_90
               SUBQ    #2,(A7)              ;DECREMENT RECORDS-TO-RECOVER COUNT -
               BEQ.S   SEC5REC_A0           ;BRANCH IF WE DONE 'EM ALL, EXIT.
               ADDQ    #2,A6                ;ELSE STEP BAD-RECORD LIST POINTER UP AND DO IT AGAIN.
               BRA     SEC5REC_20
;
SEC5REC_A0
               LEA     4(A7),A7             ;CLEAN UP STACK DAMAGE WITHOUT WASTING CONDITION CODES.
;
SEC5REC_EXIT
               RTS
;
;AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
               SKIP
;VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV
;
; TRANSFER SEQUENCE DIRECTORY - ALL-SEQUENCES TRANSFER.
; SEQUENCE DIRECTORY IS STORED IN SECTOR 5 ONLY ON 13 CONTIGUOUS TRACKS.
;
; EXPECTS DISK SIDE SELECTED BEFORE CALLING HERE, NOTHING ELSE ASSUMED.
; IF SIDE 0 SELECTED, MAKES A PASS FROM TRACK 04 THROUGH TRACK 16 -
; IF SIDE 1, MAKES A PASS FROM TRACK 75 THROUGH TRACK 63.
;
; FURTHER COMMENTS PER MOVE_SECTOR_5 (ABOVE).
;
MOVE_SEQ_DIRECTORY
               MOVE.L  #SEQ_DIRECTORY,A0    ;START AT BOTTOM OF SEQUENCE DIRECTORY.
               MOVEQ   #4,D0                ;ASSUME SIDE 0 - WE'D START ON TRACK 04.
               MOVEQ   #12,D1               ;TRANSFER RECORDS 0-12.
               MOVE    #128,D2              ;FOR RECORD 12, TRANSFER 128 BYTES - FOR OTHERS, 256.
               MOVE    #WASTELAND_2+200H,A6 ;BUILD BAD-RECORD LIST HERE (SIDE 0 LOAD ONLY).
               TST     CURRENT_SIDE         ;WHICH SIDE ARE WE ON, ANYWAY?
               BEQ.S   SEQ_DIR_10           ;BRANCH IF SIDE 0, OK TO START ON TRACK 04.
               MOVEQ   #75,D0               ;ELSE START ON TRACK 75 AND WORK OUT TOWARDS TRACK 63.
SEQ_DIR_10
               BRA     MOVE_SECTOR_5        ;BRANCH, RETURN THROUGH.
;
;AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
;
;
;
;VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV
;
; DATA RECOVERY PROCEDURE FOR SEQUENCE DIRECTORY -
;
; A6 POINTS TO A BAD-RECORD COUNT FOLLOWED BY THE LIST OF BAD RECORD
; NUMBERS COMPILED DURING A READ FROM SIDE 0 OF THE PRIMARY FILE.
; ATTEMPTS TO READ CORRESPONDING RECORDS FROM REDUNDANT FILE ON SIDE 1.
; FOR FURTHER INFO, SEE SECTOR_5_RECOVER (ABOVE).
;
RCVR_SEQ_DIRECTORY
               MOVE.L  #SEQ_DIRECTORY,A0    ;ADDRESS AT WHICH FILE RESIDES IN RAM.
               MOVEQ   #75,D0               ;SIDE 1 FILE STARTING TRACK.
               MOVEQ   #12,D1               ;NUMBER OF THE FINAL FILE RECORD.
               MOVE    #128,D2              ;FOR RECORD 12, TRANSFER 128 BYTES - FOR OTHERS, 256.
               BRA     SECTOR_5_RECOVER     ;RETURN THROUGH THE GENERIC DATA-RECOVERY ROUTINE.
;
;AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
               SKIP
;VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV
;
; TRANSFER SEQUENCE BLOCK LIST - ALL-SEQUENCES TRANSFER.
; SEQUENCE BLOCK LIST IS STORED IN SECTOR 5 ONLY ON 4 CONTIGUOUS TRACKS.
;
; EXPECTS DISK SIDE SELECTED BEFORE CALLING HERE, NOTHING ELSE ASSUMED.
; IF SIDE 0 SELECTED, MAKES A PASS FROM TRACK 17 THROUGH TRACK 20 -
; IF SIDE 1, MAKES A PASS FROM TRACK 62 THROUGH TRACK 59.
;
; FURTHER COMMENTS PER MOVE_SECTOR_5 (ABOVE).
;
MOVE_SEQ_BLOCK_LIST
               MOVE    #SEQ_BLOCK_LIST,A0   ;START AT BOTTOM OF SEQUENCE BLOCK LIST.
               MOVEQ   #17,D0               ;ASSUME SIDE 0 - WE'D START ON TRACK 17.
               MOVEQ   #3,D1                ;TRANSFER RECORDS 0-3.
               MOVEQ   #32,D2               ;FOR RECORD 3, TRANSFER 32 BYTES - FOR OTHERS, 256.
               MOVE    #WASTELAND_2+220H,A6 ;BUILD BAD-RECORD LIST HERE (SIDE 0 LOAD ONLY).
               TST     CURRENT_SIDE         ;WHICH SIDE ARE WE ON, ANYWAY?
               BEQ.S   SEQ_BLK_10           ;BRANCH IF SIDE 0, OK TO START ON TRACK 17.
               MOVEQ   #62,D0               ;ELSE START ON TRACK 62 AND WORK OUT TOWARDS TRACK 59.
SEQ_BLK_10
               BRA     MOVE_SECTOR_5        ;BRANCH, RETURN THROUGH.
;
;AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
;
;
;
;VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV
;
; DATA RECOVERY PROCEDURE FOR SEQUENCE BLOCK LIST -
;
; A6 POINTS TO A BAD-RECORD COUNT FOLLOWED BY THE LIST OF BAD RECORD
; NUMBERS COMPILED DURING A READ FROM SIDE 0 OF THE PRIMARY FILE.
; ATTEMPTS TO READ CORRESPONDING RECORDS FROM REDUNDANT FILE ON SIDE 1.
; FOR FURTHER INFO, SEE SECTOR_5_RECOVER (ABOVE).
;
RCVR_SEQ_BLOCK_LIST
               MOVE.L  #SEQ_BLOCK_LIST,A0   ;ADDRESS AT WHICH FILE RESIDES IN RAM.
               MOVEQ   #62,D0               ;SIDE 1 FILE STARTING TRACK.
               MOVEQ   #3,D1                ;NUMBER OF THE FINAL FILE RECORD.
               MOVEQ   #32,D2               ;TRANSFER LENGTH FOR FINAL RECORD, IN CASE WE NEED IT.
               BRA     SECTOR_5_RECOVER     ;RETURN THROUGH THE GENERIC DATA-RECOVERY ROUTINE.
;
;AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
               SKIP
;VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV
;
; TRANSFER SONG LIST -
; SONG LIST IS STORED IN SECTOR 5 ONLY ON 48 CONTIGUOUS TRACKS.
; SINCE ALL ONE-SONG TRANSFERS (INCL. SAVE, VERIFY) ARE SUPPORTED,
; THEY ARE SPECIAL-HANDLED HERE INSTEAD OF AT DISKCMD2 LEVEL.
;
; EXPECTS DISK SIDE SELECTED BEFORE CALLING HERE, NOTHING ELSE ASSUMED.
; FOR A FULL-FILE TRANSFER:
; IF SIDE 0 SELECTED, MAKES A PASS FROM TRACK 21 THROUGH TRACK 68 -
; IF SIDE 1, MAKES A PASS FROM TRACK 58 THROUGH TRACK 11.
; SINGLE-SONG TRANSFERS ARE CONFINED TO THE APPROPRIATE FOUR RECORDS.
; FURTHER COMMENTS PER MOVE_SECTOR_5 (ABOVE).
;
MOVE_SONG_LIST
               MOVE.L  #SONG_LIST,A0        ;IF FULL-FILE MOVE, WE START AT BOTTOM OF SONG LIST.
               MOVE    #WASTELAND_2+230H,A6 ;BUILD BAD-RECORD LIST HERE (SIDE 0 LOAD ONLY).
               MOVE    #256,D2              ;TRANSFER 256 BYTES FOR ALL RECORDS INCLUDING LAST.
               MOVEQ   #21,D0               ;ASSUME SIDE 0 - WE'D START ON TRACK 21.
               TST     CURRENT_SIDE         ;WHICH SIDE ARE WE ON, ANYWAY?
               BEQ.S   MOVSONG_10           ;BRANCH IF SIDE 0, OK TO START ON TRACK 21.
               MOVEQ   #58,D0               ;ELSE START ON TRACK 58 AND WORK OUT TOWARDS TRACK 11.
MOVSONG_10
               MOVE    DISK_OP_CODE,D1      ;SEE IF WE BE DOING DIRECTORY EXTRACTION -
               BTST    #DIR_BIT,D1
               BNE.S   MOVSONG_70           ;BRANCH IF YES, SCAN ENTIRE FILE.
               BTST    #MOV_ALL_BIT,D1      ;ELSE - ARE WE DOING A ONE-SONG TRANSFER?
               BNE.S   MOVSONG_70           ;BRANCH IF NOT - IT'S A FULL-FILE TRANSFER.
               MOVE    CURRENT_SONG,D1      ;ELSE, COMPUTE RAM TRANSFER ADDRESS -
               MULU    #1024,D1             ;1K BYTE PER SONG.
               ADD.L   D1,A0                ;OFFSET FROM BOTTOM OF SONG LIST.
               MOVE    SONG_UNIT_SEL,D1     ;NOW FIGGEROUT WHICH DISK RECORDS WE WANT -
               ADD     D1,D1                ;FOUR RECORDS PER SONG.
               ADD     D1,D1
               TST     CURRENT_SIDE         ;ARE WE WORKING THE SIDE 0 BEAT?
               BEQ.S   MOVSONG_20           ;BRANCH IF YES - POSITIVE OFFSET FROM STARTING TRACK.
               NEG     D1                   ;NEGATIVE OFFSET FOR SIDE 1.
MOVSONG_20
               ADD     D1,D0
               MOVEQ   #3,D1                ;ONE-SONG TRANSFER - RECORDS 0-3 (RELATIVE TO FIRST).
               BRA.S   MOVSONG_80
MOVSONG_70
               MOVEQ   #47,D1               ;FULL-FILE MOVE - TRANSFER RECORDS 0-47.
MOVSONG_80
               BRA     MOVE_SECTOR_5        ;BRANCH, RETURN THROUGH.
;
;AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
;
;
;
;VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV
;
; DATA RECOVERY PROCEDURE FOR SONG LIST -
;
; A6 POINTS TO A BAD-RECORD COUNT FOLLOWED BY THE LIST OF BAD RECORD
; NUMBERS COMPILED DURING A READ FROM SIDE 0 OF THE PRIMARY FILE.
; ATTEMPTS TO READ CORRESPONDING RECORDS FROM REDUNDANT FILE ON SIDE 1.
; FOR FURTHER INFO, SEE SECTOR_5_RECOVER (ABOVE).
;
RCVR_SONG_LIST
               MOVE.L  #SONG_LIST,A0        ;ADDRESS AT WHICH FILE RESIDES IN RAM.
               MOVEQ   #58,D0               ;SIDE 1 FILE STARTING TRACK.
               MOVEQ   #47,D1               ;NUMBER OF THE FINAL FILE RECORD.
               MOVE    #256,D2              ;TRANSFER LENGTH FOR FINAL RECORD, IN CASE WE NEED IT.
               MOVE    DISK_OP_CODE,D3      ;SEE IF WE BE DOING DIRECTORY EXTRACTION.
               BTST    #DIR_BIT,D3
               BNE.S   RCVSONG_40           ;BRANCH IF YES, SCAN ENTIRE FILE.
               BTST    #MOV_ALL_BIT,D3      ;ELSE - ARE WE DOING A ONE-SONG TRANSFER?
               BNE.S   RCVSONG_40           ;BRANCH IF NOT - IT'S A FULL-FILE TRANSFER.
               MOVE    CURRENT_SONG,D3      ;ELSE, COMPUTE RAM TRANSFER ADDRESS -
               MULU    #1024,D3             ;1K BYTE PER SONG.
               ADD.L   D3,A0                ;OFFSET FROM BOTTOM OF SONG LIST.
               MOVE    SONG_UNIT_SEL,D3     ;NOW FIGGEROUT WHICH DISK RECORDS WE WANT -
               ADD     D3,D3                ;FOUR RECORDS PER SONG.
               ADD     D3,D3
               NEG     D3                   ;NEGATIVE OFFSET FOR SIDE 1.
               ADD     D3,D0
RCVSONG_40
               BRA     SECTOR_5_RECOVER     ;RETURN THROUGH THE GENERIC DATA-RECOVERY ROUTINE.
;
;AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
               SKIP
;VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV
;
; TRANSFER SMPTE CUE LIST -
; CUE LIST IS STORED IN SECTOR 5 ONLY ON 11 CONTIGUOUS TRACKS.
;
; EXPECTS DISK SIDE SELECTED BEFORE CALLING HERE, NOTHING ELSE ASSUMED.
; IF SIDE 0 SELECTED, MAKES A PASS FROM TRACK 69 THROUGH TRACK 79 -
; IF SIDE 1, MAKES A PASS FROM TRACK 10 THROUGH TRACK 00.
;
; FURTHER COMMENTS PER MOVE_SECTOR_5 (ABOVE).
;
MOVE_CUE_LIST
               MOVE    #CUELIST_BLOCK,A0    ;START AT BOTTOM OF CUE LIST BLOCK.
               MOVEQ   #69,D0               ;ASSUME SIDE 0 - WE'D START ON TRACK 69.
               MOVEQ   #10,D1               ;TRANSFER RECORDS 0-10.
               MOVE    #CUE_BLK_SIZE-2560,D2     ;ACTUAL CUE LIST IS 256 10-BYTE BLOCKS -
                                                 ;THERE'S SOME EXCESS AT THE END, THOUGH.
               MOVE    #WASTELAND_2,A6      ;BUILD BAD-RECORD LIST HERE (SIDE 0 LOAD ONLY).
               TST     CURRENT_SIDE         ;WHICH SIDE ARE WE ON, ANYWAY?
               BEQ.S   MOV_CUE_10           ;BRANCH IF SIDE 0, OK TO START ON TRACK 69.
               MOVEQ   #10,D0               ;ELSE START ON TRACK 10 AND WORK OUT TOWARDS TRACK 00.
MOV_CUE_10
               BRA     MOVE_SECTOR_5        ;BRANCH, RETURN THROUGH.
;
;AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
;
;
;
;VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV
;
; DATA RECOVERY PROCEDURE FOR SEQUENCE BLOCK LIST -
;
; A6 POINTS TO A BAD-RECORD COUNT FOLLOWED BY THE LIST OF BAD RECORD
; NUMBERS COMPILED DURING A LOAD FROM SIDE 0 OF THE PRIMARY FILE.
; ATTEMPTS TO LOAD CORRESPONDING RECORDS FROM REDUNDANT FILE ON SIDE 1.
; FOR FURTHER INFO, SEE SECTOR_5_RECOVER (ABOVE).
;
RCVR_CUE_LIST
               MOVE.L  #CUELIST_BLOCK,A0    ;ADDRESS AT WHICH FILE RESIDES IN RAM.
               MOVEQ   #10,D0               ;SIDE 1 FILE STARTING TRACK.
               MOVEQ   #10,D1               ;NUMBER OF THE FINAL FILE RECORD.
               MOVE    #CUE_BLK_SIZE-2560,D2     ;TRANSFER LENGTH FOR FINAL RECORD, IN CASE NEEDED.
               BRA     SECTOR_5_RECOVER     ;RETURN THROUGH THE GENERIC DATA-RECOVERY ROUTINE.
;
;AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
               SKIP
;VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV
;
; TRANSFER DISK DESCRIPTOR RECORD -
; THIS BLOCK IS STORED ON SIDE 0, TRACK 00, SECTOR 5.
;
; FURTHER COMMENTS PER MOVE_SECTOR_5 (ABOVE) -
; HOWEVER, THIS BLOCK IS NOT PART OF THE REDUNDANT-STORAGE SET AND
; APPEARS ONLY ON SIDE 0 OF THE DISK - IT IS ASSUMED THAT SIDE 0
; IS ALREADY SELECTED WHEN WE GET HERE.
;
MOVE_DESCRIPTOR
               MOVE    #FD_DESCR_BUF,A0     ;ADDRESS OF DESCRIPTOR RECORD BUFFER.
               CLR     D0                   ;ZERO BE THE TRACK, MATE-Y.
               CLR     D1                   ;TRANSFER RECORD 0 ONLY.
               MOVE    #FD_DESCR_LEN,D2     ;THIS BE HOW MANY BYTES IN THE ONLY RECORD.
               MOVE    #WASTELAND_2,A6      ;WE DON'T USE THIS, BUT MAKE SURE IT'S IN SAFE AREA.
               BRA     MOVE_SECTOR_5        ;BRANCH, RETURN THROUGH.
;
;AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
;
;
;
;VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV
;
; TRANSFER SYSTEM CONFIGURATION BLOCK - MIDI CONFIG.
; THIS BLOCK IS STORED ON SIDE 0, TRACK 01, SECTOR 5.
;
; FURTHER COMMENTS PER MOVE_SECTOR_5 (ABOVE) -
; HOWEVER, THIS BLOCK IS NOT PART OF THE REDUNDANT-STORAGE SET AND
; APPEARS ONLY ON SIDE 0 OF THE DISK - HENCE, WE SELECT SIDE 0 UPON
; ARRIVING HERE.
;
MOVE_MIDI_BLOCK
               BSR     SEL_SIDE_0           ;GOTTA HAVE IT.
               MOVE    #MIDI_BLOCK,A0       ;START AT BOTTOM OF MIDI BLOCK.
               MOVEQ   #1,D0                ;THIS IS THE TRACK THAT IT'S ON.
               CLR     D1                   ;TRANSFER RECORD 0 ONLY.
               MOVE    #MIDI_BLK_SIZE,D2    ;THIS BE HOW MANY BYTES IN THE ONLY RECORD.
               MOVE    #WASTELAND_2,A6      ;WE DON'T USE THIS, BUT MAKE SURE IT'S IN SAFE AREA.
               BRA     MOVE_SECTOR_5        ;BRANCH, RETURN THROUGH.
;
;AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
;
;
;
;VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV
;
; TRANSFER SYSTEM CONFIGURATION BLOCK - SEQUENCER CONFIG.
; THIS BLOCK IS STORED ON SIDE 0, TRACK 02, SECTOR 5.
;
; FURTHER COMMENTS PER MOVE_SECTOR_5 (ABOVE) -
; HOWEVER, THIS BLOCK IS NOT PART OF THE REDUNDANT-STORAGE SET AND
; APPEARS ONLY ON SIDE 0 OF THE DISK - HENCE, WE SELECT SIDE 0 UPON
; ARRIVING HERE.
;
MOVE_SEQ_SYS_BLOCK
               BSR     SEL_SIDE_0           ;GOTTA HAVE IT.
               MOVE    #SEQ_SYS_BLOCK,A0    ;START AT BOTTOM OF SEQUENCER CONFIG BLOCK.
               MOVEQ   #2,D0                ;THIS IS THE TRACK THAT IT'S ON.
               CLR     D1                   ;TRANSFER RECORD 0 ONLY.
               MOVE    #SEQ_BLK_SIZE,D2     ;THIS BE HOW MANY BYTES IN THE ONLY RECORD.
               MOVE    #WASTELAND_2,A6      ;WE DON'T USE THIS, BUT MAKE SURE IT'S IN SAFE AREA.
               BRA     MOVE_SECTOR_5        ;BRANCH, RETURN THROUGH.
;
;AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
;
;
;VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV
;
; TRANSFER SYSTEM CONFIGURATION BLOCK - SMPTE CONFIG.
; THIS BLOCK IS STORED ON SIDE 0, TRACK 03, SECTOR 5.
;
; FURTHER COMMENTS PER MOVE_SECTOR_5 (ABOVE) -
; HOWEVER, THIS BLOCK IS NOT PART OF THE REDUNDANT-STORAGE SET AND
; APPEARS ONLY ON SIDE 0 OF THE DISK - HENCE, WE SELECT SIDE 0 UPON
; ARRIVING HERE.
;
MOVE_SMPTE_BLOCK
               BSR     SEL_SIDE_0           ;GOTTA HAVE IT.
               MOVE    #SMPTE_BLOCK,A0      ;START AT BOTTOM OF SMPTE BLOCK.
               MOVEQ   #3,D0                ;THIS IS THE TRACK THAT IT'S ON.
               CLR     D1                   ;TRANSFER RECORD 0 ONLY.
               MOVE    #SMPTE_BLK_SIZE,D2   ;THIS BE HOW MANY BYTES IN THE ONLY RECORD.
               MOVE    #WASTELAND_2,A6      ;WE DON'T USE THIS, BUT MAKE SURE IT'S IN SAFE AREA.
               BRA     MOVE_SECTOR_5        ;BRANCH, RETURN THROUGH.
;
;AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
               SKIP
;VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV
;
; TRANSFER SAMPLE CONTROL BLOCK DATA BETWEEN DISK AND CPU RAM -
; SELECTS DISK SIDE 0, POSITIONS HEAD ON TRACK 00 -
; NO PRE-POSITIONING NECESSARY.
;
; SOUND BLOCK SECTOR ACCESS SEQUENCE:
;      TRACK 00 - SECS 3,4,0,1,2.
;      TRACK 01 - SECS 4,0.
; EACH SECTOR EXCEPT THE LAST CONTAINS FIVE SOUND CONTROL BLOCKS -
; THE LAST ONE CONTAINS TWO SOUND CONTROL BLOCKS.
;
; NOTE: LOAD_ONE_SOUND HAS ITS OWN CORRESPONDING PROCEDURE BUILT IN,
; DOESN'T CALL HERE.
;
SOUND_PARAMS_MOVE
               BSR     SEL_SIDE_0           ;HEAD FOR TRACK 00, SIDE 0.
               BSR     TO_TRK_00
               BNE     SND_PRM_EXIT         ;JUST IN CASE WE DIDN'T MAKE IT TO TRACK 00 ....
;
               MOVE.L  #DIRECTORY_BUF,-(A7) ;IF COMPILING SOUND DIR, DO IT IN DIRECTORY_BUF -
                                            ;RENT SPACE AT TOP OF STACK FOR TEMP COMPILE POINTER.
;
               CLR     CURRENT_TRACK        ;AHEM - WE START ON TRACK 00.
               MOVE    #3,CURRENT_SEC       ;SET FIRST SECTOR TO BE TRANSFERRED.
               MOVE    #5*S_BLOCK_SIZE,BYTE_LENGTH    ;SET INITIAL SECTOR TRANSFER LENGTH.
;
               MOVE    #S_BLK_00,CUR_XFR_ADDR    ;SET TRANSFER ADDRESS ASSUMING SOUND TRANSFER.
               MOVE    DISK_OP_CODE,D1      ;SO JUST WHAT ARE WE DOING?
               BTST    #DIR_BIT,D1          ;I.E., ARE WE READING DIRECTORY?
               BEQ.S   SND_PRM_20           ;BRANTCH IF WE IZNT - EXISTING TRANSFER LENGTH IS OK.
               MOVE    #WASTELAND_2,CUR_XFR_ADDR      ;ELSE BUFFER DATA HERE FOR DIR EXTRACTION.
SND_PRM_20
               CLR     RETRIES              ;START WITH CLEAN RECORD PER SECTOR.
SND_PRM_40
               MOVE    CURRENT_SEC,D0       ;SECTOR BEING TRANSFERRED.
               BSR     INDICATE             ;FLASH AN LED ABOUT THIS BIT OF INFO.
               MOVE    CUR_XFR_ADDR,A0      ;FETCH CURRENT RAM TRANSFER ADDRESS.
               MOVE    BYTE_LENGTH,D2       ;FETCH NUMBER OF BYTES TO TRANSFER TO/FROM THIS SECTOR.
               SF      BEGIN_TRUNC          ;NO SKIPPO ANY BYTE-OS DURING READ-O.
               MOVE    DISK_OP_CODE,D1      ;HAVE A FRESH LOOK - WHAT WAY WE TRANSFER?
               BTST    #DIR_BIT,D1          ;DIRECTORY ACCESS - READ-ONLY.
               BNE.S   SND_PRM_60
               BTST    #SAVE_BIT,D1
               BNE.S   SND_PRM_70           ;BRANCH IF SAVING TO DISK.
               BTST    #VERIFY_BIT,D1
               BNE.S   SND_PRM_80           ;BRANCH IF VERIFYING DATA ON DISK.
                                            ;IF NONE OF ABOVE, ASSUME LOAD - FALL THROUGH.
;
SND_PRM_60
               BSR     SECTOR_READ
               BRA.S   SND_PRM_A0
SND_PRM_70
               BSR     SECTOR_WRITE
               BRA.S   SND_PRM_A0
SND_PRM_80
               BSR     SECTOR_VER
SND_PRM_A0
               BEQ.S   SND_PRM_E0           ;BRANCH IF SECTOR WAS TRANSFERRED WITHOUT ERROR.
               CMP.B   #PROTECTD_DISK,D0    ;WAS THERE A WRITE-PROTECT ERROR?
               BNE.S   SND_PRM_C0           ;BRANCH IF NOT, GO INTO RETRY SEQUENCE.
               TST     D0                   ;ELSE, RESTORE Z FLAG PER ERROR CODE,
               BRA     SND_PRM_P0           ;EXIT.
SND_PRM_C0
               BSR     RETRY                ;SET UP FOR A RETRY OF SECTOR TRANSFER.
               BEQ     SND_PRM_40           ;BRANCH IF (ANOTHER) RETRY IS POSSIBLE.
               CMP.B   #VERIFY_ERR,D0       ;ARE WE DEALING WITH A DATA COMPARE ERROR?
               BEQ.S   SND_PRM_C4           ;BRANCH IF YES, SPELL IT OUT STRAIGHT -
               MOVEQ   #GENERIC_ERROR,D0    ;ELSE SET GENERIC-ERROR STATUS,
SND_PRM_C4
               BSR     QUERY                ;ASK USER WHAT TO DO ABOUT THIS.
               BNE     SND_PRM_P0           ;BRANCH IF ERROR-ABORT (E.G. USER REMOVED DISK).
               BCS     SND_PRM_P0           ;BRANCH IF USER SAID "GIVE IT UP."
                                            ;ELSE, ACT AS IF NO ERROR OCCURRED - STEP PAST IT -
               BSR     DISP_XFR_SCREEN      ;REDISPLAY TRANSFER SCREEN AND CONTINUE.
SND_PRM_E0
               MOVE    DISK_OP_CODE,D1      ;SECTOR READ - ARE WE READING DIRECTORY?
               BTST    #DIR_BIT,D1
               BEQ.S   SND_PRM_F0           ;BRANCH IF NOT, GO SELECT NEXT SECTOR.
               MOVE    #WASTELAND_2,A0      ;YES - POINT TO DATA JUST READ FROM SECTOR.
               MOVE.L  (A7),A1              ;POINT TO WHERE LATEST DIRECTORY ENTRIES WILL GO.
               MOVEQ   #4,D0                ;READ 5 NAMES (YES, GARBAGE FOR SOUNDS 33-35 - SUE ME).
SND_PRM_E8
               MOVE.L  (A0)+,(A1)+          ;COPY A NAME FROM BUFFERED SOUND CONTROL BLOCK.
               MOVE.L  (A0)+,(A1)+
               ADD     #S_BLOCK_SIZE-8,A0   ;POINT TO NEXT BUFFERED CONTROL BLOCK IF ANY.
               DBRA    D0,SND_PRM_E8        ;LOOP UNTIL FIVE NAMES READ.
               MOVE.L  A1,(A7)              ;WE'RE DONE? REMEMBER WHERE WE LEFT OFF IN DIR COMPILE.
;
SND_PRM_F0
                                            ;SELECT NEXT SECTOR TO TRANSFER, IF ANY:
               TST     CURRENT_TRACK        ;ARE WE ON TRACK 00?
               BNE.S   SND_PRM_I0           ;BRANCH IF NOT, WE BE ON TRACK 01.
               CMP     #4,CURRENT_SEC       ;TRACK 00 - DID WE JUST DO SECTOR 4?
               BNE.S   SND_PRM_G0           ;NO - SEE IF WE'RE DONE WITH TRACK 00.
               CLR     CURRENT_SEC          ;YES, WRAP BACK TO SECTOR 0 ON SAME TRACK.
               BRA.S   SND_PRM_M0           ;GO UPDATE RAM TRANSFER ADDRESS AND PROCEED.
SND_PRM_G0
               CMP     #2,CURRENT_SEC       ;LAST SECTOR WE'LL READ ON TRACK 00 - DID WE JUST?
               BNE.S   SND_PRM_K0           ;BRANCH IF NOT - STEP TO NEXT SEC, UPDATE RAM XFR ADDR.
               ADDQ    #2,CURRENT_SEC       ;YES - HEAD FOR SECTOR 4, TRACK 01.
               ADDQ    #1,CURRENT_TRACK
               BSR     STEP_INWARD          ;MOVE THE HEAD IN BY ONE TRACK.
               BRA.S   SND_PRM_M0           ;GO UPDATE RAM TRANSFER ADDRESS AND PROCEED.
SND_PRM_I0
               TST     CURRENT_SEC          ;TRACK 01, SEC 0 LAST SECTOR WE'LL READ - DID WE JUST?
               BEQ.S   SND_PRM_P0           ;BRANCH IF YAH, WE'RE DONE - NOTE NO-ERROR RETURN
                                            ;WITH Z FLAG SET, CARRY FLAG CLEAR.
               MOVE    #2*S_BLOCK_SIZE,BYTE_LENGTH    ;THAT WASN'T IT, SO THIS IS - READ A BIT LESS
                                                      ;DATA, TO WIT: ONLY TWO SOUND CONTROL BLOCKS.
;
               CLR     CURRENT_SEC          ;AND WE GO TO SECTOR 0 FOR THE FINALE.
               BRA.S   SND_PRM_M0
SND_PRM_K0
               ADDQ    #1,CURRENT_SEC       ;FOR SEQUENTIAL STEP TO NEXT SECTOR, SAME TRACK.
SND_PRM_M0
               MOVE    DISK_OP_CODE,D1      ;ARE WE READING DIRECTORY?
               BTST    #DIR_BIT,D1
               BNE.S   SND_PRM_N0           ;BRANCH IF YES, TRANSFER ADDRESS STAYS WHERE IT IS.
               ADD     #3C0H,CUR_XFR_ADDR   ;ELSE, UPDATE RAM TRANSFER ADDRESS.
SND_PRM_N0
               BRA     SND_PRM_20           ;LOOP BACK, MOVE ANOTHER SECTOR.
;
SND_PRM_P0
               LEA     4(A7),A7             ;GIVE UP THE LEASE ON THE SPACE WE RENTED FOR
                                            ;DIRECTORY-COMPILE POINTER.
SND_PRM_EXIT
               RTS
;
;AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
               SKIP
;VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV
;
; TRANSFER PAD/KIT ARRAY DATA BETWEEN DISK AND CPU RAM -
; SELECTS DISK SIDE 0, POSITIONS HEAD ON TRACK 01 -
; NO PRE-POSITIONING NECESSARY.
; IF ALREADY PRE-POSITIONED (AS IN ALL-SOUNDS TRANSFER),
; CALL MOVE_PADS_ASAP TO AVOID UNNECESSARY DELAY.
;
; MOVES 512 BYTES TO/FROM BEGINNING OF SECTOR 1, SIDE 0, TRACK 01 -
; PRECISELY THE NUMBER OF BYTES IN ONE SET OF PAD AND KIT ARRAYS.
;
; NORMALLY CALLED DURING FULL-DISK TRANSFER,
; ALSO CALLED FOR PAD/KIT ARRAYS-ONLY TRANSFER.
;
MOVE_PAD_PARAMS
               BSR     SEL_SIDE_0           ;GO FOR SIDE 0,
               MOVEQ   #1,D0                ;SET TRACK NUMBER,
               MOVE    D0,CURRENT_TRACK
               BSR     BLIND_SEEK           ;MOVE HEAD TO THIS TRACK.
               BSR     DLY_20_MSEC          ;ALLOW HEAD TO SETTLE ON TRACK.
MOVE_PADS_ASAP
               CLR     RETRIES              ;START WITH CLEAN RECORD.
MOV_PAD_40
               MOVEQ   #1,D0                ;SECTOR BEING TRANSFERRED.
               BSR     INDICATE             ;FLASH AN LED ABOUT THIS BIT OF INFO.
               MOVE    #PAD_SOUNDS,A0       ;FETCH CURRENT RAM TRANSFER ADDRESS.
               MOVE    #512,D2              ;FETCH NUMBER OF BYTES TO TRANSFER TO/FROM THIS SECTOR.
               SF      BEGIN_TRUNC          ;NO SKIPPO ANY BYTE-OS DURING READ-O.
               MOVE    DISK_OP_CODE,D1      ;HAVE A FRESH LOOK - WHAT WAY WE TRANSFER?
               BTST    #SAVE_BIT,D1
               BNE.S   MOV_PAD_80           ;BRANCH IF SAVING TO DISK.
               BTST    #VERIFY_BIT,D1
               BNE.S   MOV_PAD_90           ;BRANCH IF VERIFYING DATA ON DISK.
               BSR     SECTOR_READ          ;WHAT'S LEFT?  LOAD.
               BRA.S   MOV_PAD_A0
MOV_PAD_80
               BSR     SECTOR_WRITE
               BRA.S   MOV_PAD_A0
MOV_PAD_90
               BSR     SECTOR_VER           ;WHAT'S LEFT?  VERIFY.
MOV_PAD_A0
               BEQ.S   MOV_PAD_EXIT         ;EXIT IF NO ERROR OCCURRED DURING SECTOR TRANSFER.
;
               CMP.B   #PROTECTD_DISK,D0    ;WAS THERE A WRITE-PROTECT ERROR?
               BNE.S   MOV_PAD_C0           ;BRANCH IF NOT, GO INTO RETRY SEQUENCE.
               TST     D0                   ;ELSE, RESTORE Z FLAG PER ERROR CODE,
               BRA.S   MOV_PAD_EXIT         ;EXIT.
MOV_PAD_C0
               BSR     RETRY                ;SET UP FOR A RETRY OF SECTOR TRANSFER.
               BEQ     MOV_PAD_40           ;BRANCH IF (ANOTHER) RETRY IS POSSIBLE.
               CMP.B   #VERIFY_ERR,D0       ;ARE WE DEALING WITH A DATA COMPARE ERROR?
               BEQ.S   MOV_PAD_C4           ;BRANCH IF YES, SPELL IT OUT STRAIGHT -
               MOVEQ   #GENERIC_ERROR,D0    ;ELSE SET GENERIC-ERROR STATUS,
MOV_PAD_C4
               BSR     QUERY                ;ASK USER WHAT TO DO ABOUT THIS -
                                            ;IN ANY CASE, WE'VE SHOT OUR WAD HERE ....
MOV_PAD_EXIT
               RTS
;
;AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
               SKIP
;VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV
;
; PERFORM A TRANSFER OF SAMPLE DATA BETWEEN FLOPPY DISK AND SAMPLE RAM.
;
; DESIRED DISK SIDE MUST HAVE ALREADY BEEN SELECTED - NO HEAD PRE-POSITIONING REQUIRED.
; DATA TRANSFER IS LIMITED TO A SINGLE SUB-FILE PER CALL -
; TRANSFERS WHICH SPAN MULTIPLE SUB-FILES ARE EXECUTED VIA MULTIPLE CALLS.
;
;
; SAMPLE_MOVE IS CALLED BY TRANSFER, WHICH SETS UP THE FOLLOWING VARIABLES FOR IT TO USE:
;
; CUR_XFR_ADDR  - RAM ADDRESS FOR CURRENT RECORD - GETS UPDATED AS EACH RECORD IS TRANSFERRED.
;   IF ERRORS ARE OVERRIDDEN BY USER DURING TRANSFER OF A SAMPLE DATA RECORD,
;   CUR_XFR_ADDR IS UPDATED AS THOUGH NO ERROR OCCURRED, AND THE RAM INTERFACE
;   IS RESYNCHRONIZED TO WIPE OUT THE EFFECT OF THE ERROR ON ACTUAL TRANSFER ADDRESS.
;   HENCE, IF SAMPLE_MOVE IS NOT ABORTED BY USER, CUR_XFR_ADDR POINTS ONE WORD PAST
;   TRANSFERRED BLOCK WHEN SAMPLE_MOVE TERMINATES - IT ALSO REFLECTS RAM INTERFACE
;   STATUS AT THAT POINT.  THIS IS DONE BOTH TO MINIMIZE DAMAGE CAUSED BY ISOLATED
;   ERRORS AND TO FACILITATE MULTI-SUBFILE TRANSFER ADDRESS ACCOUNTING.
;
;         NOTE - RAM INTERFACE IS INITIALIZED USING ABOVE ADDRESSES BEFORE CALLING HERE -
;         SAMPLE_MOVE WILL REINITIALIZE IT ONLY AS PART OF ERROR-RECOVERY PROCEDURE.
;
; CURRENT_TRACK - TRACK ON WHICH TRANSFER STARTS.
;
; CURRENT_SEC   - SECTOR AT WHICH TO START.
;
; SECTOR_OFFSET - VALUE FOR STARTING TRACK - INDICATES FIRST SECTOR TO READ ON ANY GIVEN TRACK.
;
; CURRENT_REC   - NUMBER OF FIRST LOGICAL RECORD BEING TRANSFERRED FROM CURRENT SUB-FILE.
;
;         NOTE -  THE ABOVE FOUR VARIABLES GET UPDATED AS EACH RECORD IS TRANSFERRED.
;
; FINAL_REC     - NUMBER OF FINAL LOGICAL RECORD BEING TRANSFERRED FROM CURRENT SUB-FILE.
;
; FIN_REC_BYTES - SETS NUMBER OF BYTES TO BE READ FROM FINAL RECORD ( = FIN_REC_WORDS * 1.5 ).
;
; FIN_REC_WORDS - INDICATES NUMBER OF WORDS TO BE READ FROM FINAL RECORD - USED FOR ACCOUNTING,
;                 TO UPDATE CUR_XFR_ADDR IN CASE TRANSFER WILL CONTINUE INTO ANOTHER SUB-FILE.
;
; BEGIN_TRUNC   - IF NOT = 0, THE CURRENT RECORD WILL BE READ STARTING FROM SOMEWHERE PAST THE
;                 BEGINNING - OCCURS ONLY ON FIRST RECORD OF 1-SAMPLE LOAD, IS CLEARED AFTERWARD.
;
; THE NEXT THREE VARIABLES APPLY ONLY WHEN A 1-SAMPLE LOAD REQUIRES A BEGINNING-TRUNCATED TRANSFER
; FROM THE FIRST RECORD (I.E., BEGIN_TRUNC > 0) - THEY APPLY ONLY TO THE FIRST RECORD TRANSFERRED:
;
; TRUNC_BYTES   - SETS NUMBER OF BYTES TO SKIP IN FIRST RECORD BEFORE STORAGE OF READ DATA BEGINS.
;
; BEG_REC_BYTES - SETS NUMBER OF BYTES TO STORE AFTER DATA-SKIP (= #SAM_REC_BYTES - TRUNC_BYTES).
;
; BEG_REC_WORDS - INDICATES NUMBER OF WORDS TO BE STORED AFTER DATA SKIP - USED FOR ACCOUNTING,
;                 TO CORRECTLY UPDATE CUR_XFR_ADDR AFTER THE FIRST RECORD IS TRANSFERRED.
;
; USES/DESTROYS D0-D4, D7, A0.
               SKIP
;
SAMPLE_MOVE
;
SAM_MOV_1
               MOVE    CURRENT_TRACK,D0     ;HEAD FOR CURRENT TRANSFER TRACK.
               BSR     BLIND_SEEK
               BSR     DLY_20_MSEC          ;ALLOW TIME FOR HEAD TO SETTLE ON NEW TRACK.
SAM_MOV_E
               CLR     RETRIES              ;NOW AT CURRENT TRANSFER TRK, TRANSFER CURRENT RECORD.
SAM_MOV_2
               TST.B   BEGIN_TRUNC          ;BEGINNING-TRUNCATED TRANSFER?
               BNE.S   SAM_MOV_4            ;BRANCH IF YES, RECORD MOVE LENGTH IS IN BEG_REC_WORDS.
               MOVE.L  #SAM_REC_WORDS,D7    ;ELSE ASSUME MOVE LENGTH (WORDS) = SAMPLE REC NOMINAL.
               MOVE.W  #SAM_REC_BYTES,D2    ;SAME APPLIES TO BYTE MOVE LENGTH.
               MOVE    CURRENT_REC,D0       ;BUT WAIT - IS THIS THE FINAL RECORD OF THE TRANSFER?
               CMP     FINAL_REC,D0
               BNE.S   SAM_MOV_7            ;BRANCH IF NO, LENGTHS ARE CORRECT.
               MOVE.L  FIN_REC_WORDS,D7     ;ELSE SET TRANSFER LENGTHS INDICATED FOR FINAL RECORD.
               MOVE    FIN_REC_BYTES,D2
               BRA.S   SAM_MOV_7
SAM_MOV_4
               MOVE.L  BEG_REC_WORDS,D7          ;BEGINNING-TRUNCATED READ - WORD MOVE LENGTH.
               MOVE    BEG_REC_BYTES,BYTE_LENGTH ;NUMBER OF BYTES TO READ AFTER DATA SKIP.
               MOVE    TRUNC_BYTES,D2            ;SET BEGINNING-TRUNCATION (DATA SKIP) LENGTH.
SAM_MOV_7
               MOVE    CURRENT_SEC,D0       ;SET SECTOR FOR TRANSFER.
               BSR     INDICATE             ;FLASH DEM RED LIGHT.
               MOVE    DISK_OP_CODE,D1      ;1-SAMPLE LOAD OR FILE TRANSFER?
               BTST    #MOV_ALL_BIT,D1
               BEQ.S   SAM_MOV_8            ;BRANCH IF 1-SAMPLE LOAD - DISK LOAD IMPLIED.
;
                                            ;FULL DISK TRANSFER, WHAT TYPE?
               BTST    #SAVE_BIT,D1
               BNE.S   SAM_MOV_9            ;BRANCH IF SAVE.
               BTST    #VERIFY_BIT,D1
               BNE.S   SAM_MOV_94           ;BRANCH IF VERIFY.
                                            ;ELSE - WELL, WHAT'S LEFT?
SAM_MOV_8
               BSR     READ_12_BIT          ;READ A SAMPLE RECORD.
               BRA.S   SAM_MOV_A            ;GO CHECK COMPLETION STATUS.
SAM_MOV_9
               BSR     WRITE_12_BIT         ;WRITE A SAMPLE RECORD.
               BRA.S   SAM_MOV_A            ;GO CHECK COMPLETION STATUS.
SAM_MOV_94
               BSR     VER_12_BIT           ;VERIFY A SAMPLE DATA RECORD.
SAM_MOV_A
               BEQ.S   SAM_MOV_D            ;BRANCH IF RECORD TRANSFERRED WITHOUT ERROR.
               BSR     RETRY                ;ELSE SET UP FOR A RETRY OF SAMPLE RECORD TRANSFER.
               BEQ.S   SAM_MOV_C            ;BRANCH IF (ANOTHER) RETRY CAN BE DONE.
               CMP.B   #VERIFY_ERR,D0       ;ARE WE DEALING WITH A DATA COMPARE ERROR?
               BEQ.S   SAM_MOV_A4           ;BRANCH IF YES, SPELL IT OUT STRAIGHT -
               MOVEQ   #GENERIC_ERROR,D0    ;ELSE SET GENERIC ERROR STATUS FOR USER QUERY,
SAM_MOV_A4
               BSR     QUERY                ;ASK MR. YOOSER WHAT HE WANTS TO DO ABOUT THIS THEN?
               BNE.S   SAM_MOV_EXIT         ;ABORT IF RETURN IS WITH DRIVE STATUS ERROR
                                            ;(E.G., DISK WAS REMOVED FROM DRIVE).
               BCS.S   SAM_MOV_EXIT         ;ABORT IF USER RESPONSE WAS "CANCEL".
               ADD.L   D7,CUR_XFR_ADDR      ;ELSE, UPDATE RAM TRANSFER ADDRESS TO WHAT IT SHOULD
               BSR     SET_RAM_INTFC        ;HAVE BEEN WITHOUT ERROR, RE-SYNC THE RAM INTERFACE,
               BSR     DISP_XFR_SCREEN      ;REDISPLAY TRANSFER SCREEN AND CONTINUE.
               BRA.S   SAM_MOV_F
SAM_MOV_C
               BSR     SET_RAM_INTFC        ;JAM RAM ADDRESS BACK TO CUR_XFR_ADDR FOR RETRY.
               BRA     SAM_MOV_2            ;ATTEMPT SAME RECORD XFER BUT DON'T CLEAR RETRY COUNT.
;
SAM_MOV_D
                                            ;WE ARE NOW HEADING FOR NEXT SAMPLE RECORD (IF ANY).
               ADD.L   D7,CUR_XFR_ADDR      ;UPDATE RAM TRANSFER ADDRESS.  NOTE - JUST ACCOUNTING,
                                            ;DOES NOT AFFECT THE RAM INTERFACE ITSELF, WHICH IS
                                            ;ASSUMED TO BE IN SYNC WITH OUR ACCOUNTING PROCEDURE.
SAM_MOV_F
               CLR.B   BEGIN_TRUNC          ;AFTER FIRST RECORD, NO BEGIN-TRUNCATED RECORD READS.
               MOVE    CURRENT_REC,D0       ;WAS THE FINAL RECORD JUST TRANSFERRED?
               CMP     FINAL_REC,D0
               BEQ.S   SAM_MOV_EXIT         ;IF YES, TRANSFER IS COMPLETE - EXIT.
               MOVE    CURRENT_TRACK,D1     ;NO - SAVE CURRENT TRACK #, ADVANCE RECORD POINTERS -
               BSR     ADVANCE_REC          ;CURRENT_REC,CURRENT_TRACK,CURRENT_SEC,SECTOR_OFFSET.
               CMP     CURRENT_TRACK,D1     ;COMPARE PREVIOUS AND UPDATED TRACK NUMBERS -
                                            ;WAS CURRENT_TRACK CHANGED?
               BNE     SAM_MOV_1            ;YES - BRANCH TO TRACK SEEK POINT, MOVE ANOTHER RECORD.
               BRA     SAM_MOV_E            ;NO - SKIP TRACK SEEK (BUT CLEAR RETRY COUNT).
;
SAM_MOV_EXIT
               RTS
;
;AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
               SKIP
;VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV
;
; TRANSFER SEQUENCE DATA TO/FROM FLOPPY DISK - ALL-SEQUENCES TRANSFER.
;
; EXPECTS DISK SIDE SELECTED BEFORE CALLING HERE, NOTHING ELSE ASSUMED.
; IF SIDE 0 SELECTED, MAKES A PASS FROM TRACK 00 THROUGH TRACK 79 -
; IF SIDE 1, MAKES A PASS FROM TRACK 79 THROUGH TRACK 00.
; APART FROM DIRECTION OF PASS, ALL OTHER ASPECTS OF TRANSFER ARE
; IDENTICAL ON BOTH DISK SIDES.
;
; THIS IS THE IMPLEMENTATION OF REDUNDANT SEQUENCE DATA STORAGE -
; ASSUMING THAT DISK ERRORS ARE MORE LIKELY ON INNER TRACKS, WE MAKE
; CERTAIN THAT NO PORTION OF THE DATA GETS RECORDED ON THE INNER TRACKS
; ON BOTH SIDES OF THE DISK.
;
; QUIET_RETRY IS USED DURING ERROR-RECOVERY PROCESS TO MINIMIZE THE TIME
; TAKEN UP BY THE RECOVERY PROCESS, AS WELL AS ITS VISIBILITY.
;
; DURING LOAD OPERATION ON SIDE 0, A LIST IS BUILT IN WASTELAND_2 OF
; THE SEQUENCE RECORD NUMBERS WHICH FAILED TO TRANSFER CORRECTLY
; AFTER THE MAXIMUM NUMBER OF RETRIES -
; FILE TRANSFER PROCEEDS WITHOUT USER QUERY IN THIS CIRCUMSTANCE.
; UPON RETURN, A6 POINTS TO THE WORD FOLLOWING THE END OF THE LIST
; (THUS LIST IS EMPTY IF A6 = #WASTELAND_2 AT THIS POINT).
; THIS LIST CAN SUBSEQUENTLY BE USED TO LOAD MISSING DATA FROM MATCHING
; RECORDS ON DISK SIDE 1 - BUT, DISCREETLY, MAN.
;
; ****  WAIT! - A LATE-BREAKING NEWS FLASH:  HE WHO CALLS US (NAMELY,
; SEQUENCES_MOVE:DISKCMD2) HAS PREPARED FOR US, IN DIRECTORY_BUF, A MAP
; OF WHICH SEQUENCE DATA RECORDS ARE ACTUALLY USED, ACCORDING TO CURRENT
; DIRECTORY AND BLOCK-LIST INFORMATION (REGARDLESS OF WHETHER LOADING
; OR SAVING, DISK AND MEMORY DIRECTORIES SHOULD CONTAIN IDENTICAL INFO
; BY THE TIME WE ARE CALLED).  TO SAVE PILES OF FRIENDLY USER'S TIME,
; WE DON'T BOTHER WITH TRANSFERRING RECORDS WHICH ARE NOT IN THIS MAP.
; THE MAP FORMAT, BY THE WAY, IS:
;     IF BYTE (n) IN DIRECTORY_BUF = 0, THEN RECORD n IS UNUSED.
;     IF BYTE (n) IN DIRECTORY_BUF = 0FFH, THEN RECORD n CONTAINS DATA.
;
MOVE_SEQ_DATA
               CLR     CURRENT_SEC          ;LINE UP EVEN TO BEGIN.
               CLR     SECTOR_OFFSET
               CLR     CURRENT_REC
               MOVE    #WASTELAND_2,A6      ;INITIALIZE ERRORED-RECORD LIST WRITE POINTER.
               MOVE.L  #SEQUENCE_RAM,CUR_XFR_ADDR     ;START AT BOTTOM OF SEQUENCE DATA RAM.
;
               CLR     CURRENT_TRACK        ;ASSUME SIDE 0 - WE'D START ON TRACK 00.
               TST     CURRENT_SIDE         ;WHICH SIDE ARE WE ON, ANYWAY?
               BEQ.S   SEQ_DAT_10           ;BRANCH IF SIDE 0, OK TO START ON TRACK 00.
               MOVE    #79,CURRENT_TRACK    ;ELSE START ON TRACK 79 AND WORK OUT TOWARDS TRACK 00.
;
SEQ_DAT_10
               MOVE    CURRENT_TRACK,D0     ;FETCH CURRENT TRACK NUMBER,
               BSR     BLIND_SEEK           ;HEAD FOR THIS TRACK,
               BSR     DLY_20_MSEC          ;LET HEAD SETTLE ONTO IT.
               TST     CURRENT_REC          ;FIRST TIME THROUGH, RECORD 0?
               BNE.S   SEQ_DAT_20           ;BRANCH IF NOT, CONTINUE.
                ABS_LONG
               TST.B   DIRECTORY_BUF        ;YES - IS THIS RECORD SHOWN AS "USED" IN RECORD MAP?
                ABS_SHORT
               BEQ     SEQ_DAT_80           ;BRANCH IF NOT, DON'T TRANSFER IT - GO FIND NEXT REC.
;
SEQ_DAT_20
               CLR     RETRIES              ;START WITH CLEAN SLATE PER RECORD.
;
SEQ_DAT_30
               MOVE    CURRENT_SEC,D0       ;SECTOR BEING TRANSFERRED.
               TST     CURRENT_SIDE
               BNE.S   SEQ_DAT_32           ;REVERSE LED PATTERN DIRECTION FOR SIDE 1 TRANSFER.
               BSR     INDICATE             ;SIDE 0 VERSION - PUT IT UP IN (LITTLE RED) LIGHTS.
               BRA.S   SEQ_DAT_34
SEQ_DAT_32
               MOVE    D0,D1                ;SAVE SECTOR NUMBER,
               NEG     D0                   ;CREATE REVERSED NUMBER,
               ADDQ    #4,D0
               BSR     INDICATE             ;USE IT TO SET AN LED,
               MOVE    D1,D0                ;RECOVER SECTOR NUMBER.
SEQ_DAT_34
               MOVE.L  CUR_XFR_ADDR,A0      ;FETCH CURRENT RAM TRANSFER ADDRESS.
               MOVE    #1024,D2             ;ALWAYS TRANSFER ENTIRE SECTOR FOR SEQUENCE RECORD.
               SF      BEGIN_TRUNC          ;SKIP NO DATA ANYWHERE.
               MOVE    DISK_OP_CODE,D1      ;LET'S REMIND OURSELVES WHAT WE ARE DOING -
               BTST    #SAVE_BIT,D1
               BNE.S   SEQ_DAT_50           ;BRANCH IF SAVING TO DISK.
               BTST    #VERIFY_BIT,D1
               BNE.S   SEQ_DAT_58           ;BRANCH IF VERIFYING DATA ON DISK.
               BSR     SECTOR_READ          ;EH?  WHAT'S LEFT, THEN?
               BRA.S   SEQ_DAT_60
SEQ_DAT_50
               BSR     SECTOR_WRITE
               BRA.S   SEQ_DAT_60
SEQ_DAT_58
               BSR     SECTOR_VER
SEQ_DAT_60
               BEQ.S   SEQ_DAT_80           ;BRANCH IF NO ERROR OCCURRED DURING TRANSFER.
               CMP.B   #PROTECTD_DISK,D0    ;WAS THERE A WRITE-PROTECT ERROR?
               BNE.S   SEQ_DAT_70           ;BRANCH IF NOT, GO INTO RETRY SEQUENCE.
               TST     D0                   ;ELSE, RESTORE Z FLAG PER D0 ERROR CODE,
               BRA.S   SEQ_DAT_EXIT         ;EXIT WITH ERROR STATUS.
SEQ_DAT_70
               BSR     QUIET_RETRY          ;SET UP FOR A RETRY OF SECTOR TRANSFER.
               BEQ     SEQ_DAT_34           ;BRANCH IF (ANOTHER) RETRY IS POSSIBLE.
               TST     CURRENT_SIDE         ;IF NOT - ARE WE ON SIDE 1?
               BNE.S   SEQ_DAT_78           ;BRANCH IF YES, DO NORMAL USER QUERY THING.
               MOVE    DISK_OP_CODE,D1      ;WE'RE ON SIDE 0,
               BTST    #LOAD_BIT,D1         ;SO SEE IF WE'RE DOING A LOAD -
               BEQ.S   SEQ_DAT_78           ;BRANCH IF NOT, NORMAL USER QUERY TIME.
               BSR     CHECK_SPEED          ;SIDE 0 LOAD - WAS ERROR CAUSED BY DISK REMOVAL?
               BNE.S   SEQ_DAT_EXIT         ;SINCE NO QUERY ON ERROR, THIS IS THE ONLY WAY TO STOP!
               MOVE    CURRENT_REC,(A6)+    ;DISK STILL THERE - ADD BAD-RECORD NUMBER ONTO LIST,
               BRA.S   SEQ_DAT_80           ;PROCEED TO NEXT RECORD WITHOUT BOTHERING USER.
SEQ_DAT_78
               CMP.B   #VERIFY_ERR,D0       ;ARE WE DEALING WITH A DATA COMPARE ERROR?
               BEQ.S   SEQ_DAT_7A           ;BRANCH IF YES, SPELL IT OUT STRAIGHT -
               MOVEQ   #GENERIC_ERROR,D0    ;ELSE SET GENERIC-ERROR STATUS,
SEQ_DAT_7A
               BSR     QUERY                ;ASK USER WHAT-ALL TO DO ABOUT THIS.
               BNE.S   SEQ_DAT_EXIT         ;BRANCH IF ERROR-ABORT (E.G., DISK REMOVAL).
               BCS.S   SEQ_DAT_EXIT         ;BRANCH IF USER SAID "GIVE IT UP."
               BSR     DISP_XFR_SCREEN      ;USER SAID "KEEP GOING" - RESTORE TRANSFER SCREEN.
;
SEQ_DAT_80
               MOVE    CURRENT_TRACK,D1     ;MOVED ONE MORE RECORD - SAVE TRACK NUMBER WE WERE ON.
SEQ_DAT_84
               MOVE    CURRENT_TRACK,D2     ;SAVE (NEW) TRIAL NEXT-TRACK NUMBER ASIDE.
               ADD.L   #1024,CUR_XFR_ADDR   ;UPDATE CURRENT TRANSFER ADDRESS.
               BSR     ADVANCE_REC          ;ADVANCE RECORD POINTERS (PER SAMPLE DATA TRANSFER).
               CMP     #400,CURRENT_REC     ;DID WE JUST TRANSFER THE LAST RECORD OF SEQUENCE DATA?
               BEQ.S   SEQ_DAT_EXIT         ;BRANCH IF YES, EXIT WITH NO-ERROR STATUS.
               CMP     CURRENT_TRACK,D2     ;DID TRIAL NEXT-TRACK NUMBER GET CHANGED?
               BEQ.S   SEQ_DAT_88           ;NO, FORJ AHED.
               TST     CURRENT_SIDE         ;TRACK NUMBER CHANGED - ARE WE DOING SIDE 0 TRANSFER?
               BEQ.S   SEQ_DAT_88           ;BRANCH IF YES - TRACK GOT INCREMENTED, WHICH WE WANT.
               SUBQ    #2,CURRENT_TRACK     ;ELSE, SIDE 1 - ADJUST TRACK CHANGE TO NET DECREMENT.
SEQ_DAT_88
               MOVE    CURRENT_REC,A0       ;SEE IF THIS RECORD IS IN THE "USED RECORDS" MAP.
               ADD.L   #DIRECTORY_BUF,A0
               TST.B   (A0)
               BEQ.S   SEQ_DAT_84           ;LOOP BACK IF UNUSED - STEP TO NEXT RECORD, TRY AGAIN.
;
               CMP     CURRENT_TRACK,D1     ;GOT OUR NEXT RECORD - DID TRACK NUMBER GET CHANGED?
               BEQ     SEQ_DAT_20           ;BRANCH IF NOT, RESUME DATA TRANSFER ON SAME TRACK.
               BRA     SEQ_DAT_10           ;TRACK CHANGED - RESUME TRANSFER ON NEW TRACK.
;
SEQ_DAT_EXIT
               RTS
;
;AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
               SKIP
;VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV
;
; SEQUENCE DATA RECOVERY PROCEDURE FOR ALL-SEQUENCES LOAD -
; WE'VE JUST GOTTEN THROUGH LOADING FROM SIDE 0, AND SOME RECORDS WERE
; UNREADABLE - THE LIST OF BAD RECORDS IS IN WASTELAND_2, A6 POINTS ONE
; WORD PAST THE END OF THE LIST.
; ATTEMPTS TO LOAD CORRESPONDING RECORDS FROM REDUNDANT FILE ON SIDE 1,
; SELECTS SIDE 1 AS FIRST STEP IN PROCEDURE.
;
; NORMAL RETRY AND USER QUERY UPON HARD ERROR IS USED HERE, AS OPPOSED
; TO SIDE 0 LOAD IN WHICH QUIET_RETRY AND NO USER QUERY SERVE TO LEND
; A SOMEWHAT LOWER PROFILE TO THE ERROR-RECOVERY PROCEDURE.
;
SEQ_DATA_RECOVER
               BSR     SEL_SIDE_1           ;FIRST, GO TO THE OTHER SIDE.
               MOVE    -(A6),FINAL_REC      ;STORE LAST RECORD NUMBER IN THE LIST, WE STOP THERE.
               MOVE    #WASTELAND_2,A6      ;THIS IS WHERE LIST BEGINS.
;
SEQRECOV_20
               CLR.L   D0
               MOVE    (A6),D0              ;FETCH BAD-RECORD NUMBER FROM LIST,
               MOVE.L  D0,D1                ;COPY IT AND COMPUTE RECORD PHYSICAL ADDRESS.
               DIVU    #5,D0                ;FIVE RECORDS PER TRACK, IN REVERSE -
               EXT.L   D0                   ;THIS WOULD BE IT IF TRACKS WEREN'T REVERSED -
               MOVE.L  D0,D2                ;OFF REMAINDER, SAVE FOR SECTOR COMPUTATION.
               NEG     D0
               ADD     #79,D0
               MOVE    D0,CURRENT_TRACK     ;SO - THIS IS THE TRACK WE WANT.
               ADD     D1,D2                ;RECORD SEQUENCE ROTATES BY ONE PER TRACK,
               DIVU    #5,D2
               SWAP    D2
               MOVE    D2,CURRENT_SEC       ;SO THIS IS THE SECTOR WE WANT.
               MULU    #1024,D1             ;1K BYTE PER RECORD,
               ADD.L   #SEQUENCE_RAM,D1     ;STARTING HERE -
               MOVE.L  D1,CUR_XFR_ADDR      ;THIS IS WHERE THIS RECORD LOADS TO IN RAM.
               BSR     BLIND_SEEK           ;NOW SEEK TO TRACK WHOSE NUMBER BE IN D0.
               BSR     DLY_20_MSEC          ;LET THINGS STOP SHAKING ABOUT.
               CLR     RETRIES              ;START WITH CLEAN SLATE PER RECORD.
SEQRECOV_40
               MOVE    CURRENT_SEC,D0       ;FETCH SECTOR NUMBER,
               BSR     INDICATE             ;PUT IT UP IN LIGHTS.
               MOVE.L  CUR_XFR_ADDR,A0      ;FETCH RAM TRANSFER ADDRESS,
               MOVE    #1024,D2             ;READ THIS NUMBER OF BYTES.
               SF      BEGIN_TRUNC          ;WE DON'T SKIP NO DATA, NO WE DON'T.
               BSR     SECTOR_READ          ;READ, FUCKFACE!!
               BEQ.S   SEQRECOV_60          ;BRANCH IF SECTOR WAS READ WITHOUT ERROR.
               BSR     RETRY                ;ELSE, SET UP FOR A RETRY OF SECTOR TRANSFER.
               BEQ     SEQRECOV_40          ;BRANCH IF (ANOTHER) RETRY IS POSSIBLE.
               MOVEQ   #UNRECOVERABLE,D0    ;ELSE SET UNRECOVERABLE READ ERROR STATUS,
               BSR     QUERY                ;ASK USER WHAT-ALL TO DO ABOUT THIS.
               BNE.S   SEQRECOV_EXIT        ;BRANCH IF ERROR-ABORT (E.G., DISK REMOVAL).
               BCS.S   SEQRECOV_EXIT        ;BRANCH IF USER SAID "GIVE IT UP."
               BSR     DISP_XFR_SCREEN      ;USER SAID "KEEP GOING" - RESTORE TRANSFER SCREEN.
;
SEQRECOV_60
               MOVE    FINAL_REC,D1         ;DID WE JUST TRANSFER LAST RECORD IN BAD-RECORD LIST?
               CMP     (A6),D1
               BEQ.S   SEQRECOV_EXIT        ;BRANCH IF YES, EXIT WITH NO-ERROR STATUS.
               ADDQ    #2,A6                ;ELSE STEP BAD-RECORD LIST POINTER TO NEXT RECORD,
               BRA     SEQRECOV_20          ;GO GIT IT.
;
SEQRECOV_EXIT
               RTS
;
;AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
