               INCLUDE HPFIXUPS
               TITLE "SCSICMDS"
***************************************************************************************************
***************************************************************************************************
***                                                                                             ***
***            SCSICMDS - MODEL 440 HARD DISK SYSTEM MIDDLE-MANAGEMENT                          ***
***                                                                                             ***
***************************************************************************************************
***************************************************************************************************
;
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         ;HARDWARE ADDRESSES AND DEFINITIONS.
;
               INCLUDE S_BLK_EQU       ;SOUND CONTROL BLOCK DEFINITIONS.
;
               INCLUDE DISKDEFS        ;DISK SYSTEM DEFINITIONS.
;
               include trapdefs        ; system function access definitions.
;
               include lcd_funs        ; LCD/SCREEN_BUFFER system function defs.
;
               .aword
;
               GLB     SCSI_MULTIPLE_CONF
               GLB     INIT_SCSI_DIR,PARK_THE_HEADS,READ_DATA_BUFFER
               GLB     SET_NEW_SCSI_ID
               GLB     BANK_SEL_TEST
               GLB     READ_HD_DESCRIPTOR,WRITE_HD_DESCRIPTOR
               GLB     SCSI_ALL_SND_MOVE,SCSI_ALL_SEQ_MOVE
               GLB     SCSI_CONFIG_MOVE,SCSI_SND_CTRL_MOVE
               GLB     SCSI_KITS_MOVE,SCSI_CUELIST_MOVE
               GLB     SCSI_SONGLIST_MOVE,SCSI_SEQ_DIR_MOVE
               GLB     SCSI_ALL_BANKS_DIR,SCSI_WRITE_PROTECT
               GLB     SCSI_BLOCKLIST_MOVE,SCSI_SEQ_BLOCK_MOVE
               GLB     SCSI_SAMPLE_MOVE
;
               EXTERNAL  Q_BLOCK_SIZE       ;SEQUENCE DIRECTORY BLOCK DEFINITIONS.
;
                                            ;EXTERNAL ROM, JOHNSON.
               EXTERNAL  SELECT_DEVICE
               EXTERNAL  RESET_SCSI
               EXTERNAL  SIX_BYTE_CMD
               EXTERNAL  SCSI_RAM_WRITE
               EXTERNAL  SCSI_RAM_READ
               EXTERNAL  SCSI_RAM_VERIFY
               EXTERNAL  FINISH_SCSI_SEQ
               EXTERNAL  READ_STATUS
               EXTERNAL  READ_MESSAGE
               EXTERNAL  CHECK_STATUS
               EXTERNAL  REQUEST_SENSE
               EXTERNAL  SET_RAM_INTFC,INDICATE,DISP_XFR_SCREEN
               EXTERNAL  SCSI_SAM_WRITE
               EXTERNAL  SCSI_SAM_READ
               EXTERNAL  SCSI_SAM_VERIFY
               EXTERNAL  WRITE_SCREEN,DISP_SCREEN,DISP_BUFFER
               EXTERNAL  INIT_DIR_SCRN
               EXTERNAL  WORD_BIN_TO_BCD
               EXTERNAL  ALT_QUERY,WAIT_A_SECOND,WAIT_TWO_SECS
               .import read_capacity
               .import test_unit_ready
		.import	filler_command_byte
;
                                            ;RAM-A, LAM-A, DING-DONG.
               EXTERNAL  CUELIST_BLOCK
               EXTERNAL  CUE_BLK_SIZE
               EXTERNAL  CUE_BLK_XTRA
               EXTERNAL  MIDI_BLOCK
               EXTERNAL  MIDI_BLK_SIZE
               EXTERNAL  MIDI_BLK_XTRA
               EXTERNAL  SEQ_SYS_BLOCK
               EXTERNAL  SEQ_BLK_SIZE
               EXTERNAL  SEQ_BLK_XTRA
               EXTERNAL  SMPTE_BLOCK
               EXTERNAL  SMPTE_BLK_SIZE
               EXTERNAL  SMPTE_BLK_XTRA
               EXTERNAL  SONG_LIST
               EXTERNAL  SEQ_DIRECTORY
               EXTERNAL  SEQ_BLOCK_LIST
               EXTERNAL  SEQUENCE_RAM
               EXTERNAL  S_BLK_00
               EXTERNAL  PAD_SOUNDS
               EXTERNAL  BANK_SEL
               EXTERNAL  SCSI_CMD_BUF
               EXTERNAL  DISK_OP_CODE
               EXTERNAL  TARG_SENSE_KEY
               EXTERNAL  CUR_XFR_ADDR
               EXTERNAL  SCSI_VER_FLAG
               EXTERNAL  HD_DESCR_BUF
               EXTERNAL  HD_DESCR_LEN
               EXTERNAL  HD_DESCR_XTRA
               EXTERNAL  BANK_DESCR_BUF
               EXTERNAL  BANK_DESCR_LEN
               EXTERNAL  BANK_DESCR_XTRA
               EXTERNAL  BCD_DIGITS
               EXTERNAL  HD_MODEL_ID
               EXTERNAL  HD_FIRMWR_REV
               EXTERNAL  BANK_WRT_PROT
               EXTERNAL  BANK_TYPE
               EXTERNAL  BANK_QFIL_STAT
               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  WASTELAND
               EXTERNAL  WASTELAND_2
               EXTERNAL  DIRECTORY_BUF
               EXTERNAL  BANK_TYPE_BUF
               EXTERNAL  HD_CAPACITY
               EXTERNAL  PROTECT_SEL
               EXTERNAL  SCREEN_BUFFER
               EXTERNAL  DRIVE_SEL
               EXTERNAL  SND_UNIT_SEL
               EXTERNAL  DSK_FIL_ADDR
               EXTERNAL  DSK_FIL_LENGTH
               EXTERNAL  CURRENT_REC
               EXTERNAL  FINAL_REC
               EXTERNAL  CURRENT_SONG
               EXTERNAL  SONG_UNIT_SEL
               EXTERNAL  SEQ_UNIT_SEL
               EXTERNAL  NEW_SCSI_ID
               EXTERNAL  HD_DRIVE_TYPE
               EXTERNAL  CUR_OMTI_REV
;900424               EXTERNAL  NEW_DRIVE_SIZE
               EXTERNAL  VALID_HD_DESCR
               .import new_drive_type
               SKIP
;VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV
;
; POST-RESET SETUP FOR DATAFRAME DISK DRIVES -
;
; IF NECESSARY, SEND DISK PARAMETER LIST TO THE DATAFRAME CONTROLLER
; (APPLIES ONLY TO DATAFRAME20 WITH STOCK OMTI 3100 CONTROLLER),
; THEN ATTEMPT TO READ MAIN DISK DESCRIPTOR RECORD - THIS SERVES A DUAL
; PURPOSE:
; - INITIAL READ VIA 3100 FOLLOWING RESET INCLUDES IMPLIED RECALIBRATE
; WHICH OCCURS ONE STEP AT A TIME - IF HEADS WERE IN PARKED POSITION,
; THERE IS A LONG ( APPROX 22 SECONDS) LATENCY PERIOD WHICH IS TAKEN IN
; STRIDE BY SPECIAL LOOP.  SUBSEQUENT SEEKS OCCUR AT MUCH HIGHER SPEED.
; - HEAD-PARKING REQUIRES KNOWLEDGE OF DRIVE CAPACITY IN ORDER TO MOVE
; HEADS TO THE SHIPPING ZONE - WE CAN LEARN THIS AUTOMATICALLY ONLY BY
; READING MAIN DISK DESCRIPTOR (IF PRESENT) - OTHERWISE HEAD PARKING
; IS NOT ATTEMPTED ON THE CURRENT DRIVE.
; FINALLY, WE PARK HEADS IN THE SHIPPING ZONE (AS BEST WE ARE ABLE).
;
; WE GO AFTER THE DEVICE INDICATED BY THE CURRENT VALUE OF DRIVE_SEL.
;
; ASSUMES THAT CUR_OMTI_REV HAS BEEN SET (PROBABLY BY READ_DATA_BUFFER)
; TO REFLECT THE CONTROLLER IN THE DRIVE BEING CONFIGURED.
;
; RETURNS WITH Z FLAG TRUE IF CONFIGURATION WAS COMPLETED SUCCESSFULLY,
; ELSE RETURNS WITH Z FLAG FALSE, ERROR CODE IN D0.
;
CONFIG_DATAFRAME
               BSR.S   DISP_CONFIG_SCREEN   ;TELL THE WORLD WUZ HABNIN.
;
               CMP     #3030H,CUR_OMTI_REV  ;IS THIS A DATAFRAME20 WITH OMTI 3100 CONTROLLER?
               BNE.S   CNFG_DF_20           ;BRANCH IF NOT, WE DON'T NEED TO TELL IT ANYTHING.
;
               BSR     ASSIGN_DF20_PARAMS   ;ELSE, TELL DATAFRAME20 INTERNAL CONTROLLER ABOUT
                                            ;THE DISK IT IS CONTROLLING.
               BNE.S   CNFG_DF_EXIT         ;BRANCH IF THERE WAS ANY PROBLEM, DEAL WITH ERROR.
;
CNFG_DF_20
                                            ;DATAFRAME INTERNAL CONTROLLER NOW KNOWS HOW FAR IT MAY
                                            ;HAVE TO GO - TELL IT TO READ MAIN DESCRIPTOR RECORD:
               CLR.L   HD_DESCR_BUF         ;WIPE OUT PART OF "SEQUENTIAL" ID STRING, MAKE SURE WE
                                            ;DON'T END UP TESTING LEFTOVERS LATER ON.
               SF      VALID_HD_DESCR       ;LIKEWISE, INDICATE WE HAVEN'T SEEN VALID DESCR YET.
               BSR     SELECT_DEVICE        ;TRY TO SELECT HIM TARGET.
               BNE.S   CNFG_DF_EXIT         ;EXIT IF SELECTION ATTEMPT FAILED.
               MOVE.L  #DF_BASE_REC+08000000H,SCSI_CMD_BUF      ;OPERATION CODE AND BLOCK ADDRESS.
               MOVE    #0100H,SCSI_CMD_BUF+4                    ;TRANSFER LENGTH, CONTROL BYTE.
               BSR     SIX_BYTE_CMD         ;ISSUE THE READ COMMAND TO TARGET.
               BNE.S   CNFG_DF_EXIT         ;BRANCH IF COMMAND NOT ISSUED SUCCESSFULLY.
;
               MOVEQ   #056,D4              ;COMMAND ISSUED.  DATA WILL APPEAR, EVENTUALLY -
                                            ;D4 COUNTS ATTEMPTS TO READ THE DATA.
                                            ;UNLESS SCSI_RAM_READ ROUTINE IS MODIFIED THIS IS
                                            ;ROUGHLY A 25-SEC TIMEOUT.  ON DATAFRAME 20, INITIAL
                                            ;POST-RESET SEEK TO TRACK 000 FROM HEAD-PARK POSITION
                                            ;TAKES ABOUT 22 SECONDS.
;
CNFG_DF_40
                                            ;SET UP TRANSFER PARAMETERS AT EACH NEW ATTEMPT:
               MOVEQ   #DAT_IN_PHASE,D0     ;EXPECTING A DATA-IN PHASE.
               CLR     D1                   ;SKIP NO DATA AT BEGINNING.
               MOVE.L  #HD_DESCR_LEN,D2     ;READ AND STORE THIS NUMBER OF BYTES.
               MOVE    #HD_DESCR_XTRA,D3    ;READ AND DISCARD THIS NUMBER OF SUBSEQUENT BYTES.
               MOVE    #HD_DESCR_BUF,A0     ;STORE DATA HERE.
               BSR     SCSI_RAM_READ        ;GIVE IT SHOT, MON.
               BEQ.S   CNFG_DF_60           ;WE GOT IT, YAH, OFF WE GO.
               DBRA    D4,CNFG_DF_40        ;WE DON' GOT IT, MAYBE TRY AGAIN -
               BRA.S   CNFG_DF_EXIT         ;MAYBE NOT - EXIT WITH ERROR CODE IN D0.
CNFG_DF_60
               BSR     FINISH_SCSI_SEQ      ;WRAPPET UP CHOLLY.
               BNE.S   CNFG_DF_EXIT         ;EXIT STRAIGHTAWAY, IF ALL NOT COOLTH.
               BSR     CHECK_HD_ID_STRING   ;SEE IF DESCRIPTOR DATA LOOKS REASONABLE -
               BNE.S   CNFG_DF_80           ;BRANCH IF IT DIDN'T,
               ST      VALID_HD_DESCR       ;ELSE SET FLAG THAT SAYS AS MUCH.
CNFG_DF_80
               BSR     PARK_THE_HEADS       ;NOW, WHIP THE HEADS OUT TO THE SHIPPING ZONE,
                                            ;OR SOMETHING LIKE IT - PASS RETURN STATUS THROUGH.
CNFG_DF_EXIT
               RTS
;
;
DISP_CONFIG_SCREEN
;900425               MOVE.L  #CONF_SCSI_SCRN,A1   ;MAY BE A WHILE ON A GIVEN DRIVE - POST A MESSAGE.
               lea.l   CONF_SCSI_SCRN(pc),A1     ;MAY BE A WHILE ON A GIVEN DRIVE - POST A MESSAGE.
;900424                ABS_LONG
;900424               JSR     WRITE_SCREEN
;900424                ABS_SHORT
               CALL    LCD_FUNS,WR_SCRN
               MOVE    DRIVE_SEL,D0         ;AS A FRIENDLY TOUCH - DISPLAY SCSI CHANNEL NUMBER.
;900424                ABS_LONG
;900424               JSR     WORD_BIN_TO_BCD
;900424                ABS_SHORT
               CALL    LCD_FUNS,WRD_BIN_2_BCD
               MOVE.B  BCD_DIGITS+7,SCREEN_BUFFER+30
;900424                ABS_LONG
;900424               JMP     DISP_BUFFER
;900424                ABS_SHORT
               JUMP    LCD_FUNS,DSP_BUF
;
;
CONF_SCSI_SCRN
               ASC     " CONFIGURATION: "
               ASC     " SCSI CHANNEL   "
;
;AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
               SKIP
;20APR;VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV
;20APR;
;20APR; CONFIGURE ALL SCSI DRIVES -
;20APR; CALLED DURING POWER-UP PROCEDURE AND BY "RESET SCSI DISKS" UTILITY.
;20APR;
;20APR; AT PRESENT, ASSUMES DATAFRAMES ONLY - RESETS THE SCSI BUS, THEN
;20APR; WALKS THROUGH EACH OF SCSI CHANNELS 0 THROUGH 6, DOING THE FOLLOWING:
;20APR;   -  EXECUTES READ_DATA_BUFFER ROUTINE.  THIS IS A WAY TO DETERMINE
;20APR;      WHETHER ANYTHING IS PRESENT ON A CHANNEL.  IF ROUTINE RESPONDS
;20APR;      WITH #SELECT_FAILED, WE ASSUME NOTHING THERE AND MOVE ON.
;20APR;   -  IF A DATAFRAME DRIVE IS PRESENT, THIS COMMAND TELLS US (VIA VALUE
;20APR;      IN CUR_OMTI_REV) WHAT KIND OF CONTROLLER IT HAS.  IF CONTROLLER
;20APR;      IS A 3100, WE EXECUTE CONFIG_DATAFRAME TO TELL CONTROLLER ABOUT
;20APR;      THE DISK, PERFORM INITIAL RECALIBRATION (WITH ATTENDANT, POSSIBLY
;20APR;      VERY LONG DELAY), AND THEN PARK THE HEADS.
;20APR;   -  PRESUMABLY, IF ANY OTHER TYPE OF DEVICE IS OUT THERE, WE GET AN
;20APR;      ERROR RESPONSE FROM IT (IT PROBABLY DOESN'T RECOGNIZE THE READ
;20APR;      DATA BUFFER COMMAND) - WE EXIT AT ONCE WITH AN ERROR MESSAGE.
;20APR;
;20APR; USES BANK_SEL ARRAY (AS BYTES, HOWEVER) TO KEEP TRACK OF THE RESULTS -
;20APR; IN OTHER WORDS, DESTROYS WHATEVER SETTINGS WERE ALREADY THERE.
;20APR;
;20APR; ASSUMING NO FATAL ERROR OCCURS, WE RETURN WITH Z FLAG TRUE AND
;20APR; DRIVE_SEL SET TO THE LOWEST SCSI CHANNEL ON WHICH A DRIVE WAS SEEN,
;20APR; OR TO -1 (SELECTS FLOPPY) IF NO SCSI DRIVE WAS SEEN ON ANY CHANNEL.
;20APR; ALSO, ALL BANK_SEL CELLS (.W, NOW) ARE CLEARED TO 0 (BANK 001).
;20APR;
;20APR; NOTE: (ALWAYS A NOTE) - DATAFRAMES WITH 3103/3105 CONTROLLERS ARE
;20APR; SOMEWHAT MORE SELF-CONFIGURING THAN THE OLD DATAFRAME WITH 3100 - THEY
;20APR; OBTAIN DRIVE PARAMETERS FROM THE DISK ITSELF UPON RESET (EQUIVALENT TO
;20APR; THOSE WE SEND OUT IN THE ASSIGN_DF20_PARAMS COMMAND).  IN THE PROCESS,
;20APR; SINCE THE PARAMETERS ARE EMBEDDED IN TRACK 000, THESE DRIVES TAKE CARE
;20APR; OF THE INITIAL RECALIBRATION, THUS THE INITIAL DATA ACCESS COMMAND IS
;20APR; NOT SUBJECT TO ANY SIGNIFICANT LATENCY PERIOD AS WITH THE DF20_3100.
;20APR; WONDERFUL, YOU SAY - BUT, THERE IS A CATCH .... DURING THE TIME THAT
;20APR; RECALIBRATION IS IN PROGRESS, THE 3103/5 DRIVES DO NOT RESPOND TO ANY
;20APR; ATTEMPT TO SELECT THEM OVER THE BUS, PRESUMABLY BECAUSE THEY DON'T YET
;20APR; KNOW WHAT THEIR SCSI ID IS, AS IT IS READ FROM THE DISK (A PRETTY DUMB
;20APR; ARRANGEMENT IF YOU WANT MY OPINION - OR EVEN IF YOU DON'T).  OF COURSE
;20APR; THIS MEANS THAT SCSI_MULTIPLE_CONF THINKS NOTHING IS OUT THERE, WHICH
;20APR; HAS TWO MAIN CONSEQUENCES:  ONE, HEAD-PARKING DOES NOT OCCUR AT THIS
;20APR; POINT (NO BIG DEAL, SINCE IT WOULD OCCUR AFTER ANY SUBSEQUENT COMMAND)
;20APR; AND TWO, THE 440 CANNOT DECIDE AUTOMATICALLY TO OPERATE FROM SUCH A
;20APR; SCSI DRIVE AND WILL PROBABLY REVERT TO FLOPPY OPERATION.  KIND OF A
;20APR; PAIN, NO?  THE ONLY READILY APPARENT SOLUTION (WHICH I WENT FOR IT,
;20APR; WHAT THE HEY) IS TO WAIT ..... WAIT ..... WAAAAIIT......... FOLLOWING
;20APR; BUS RESET, LONG ENOUGH FOR ANY OF THESE DRIVES TO GATHER THEIR WITS.
;20APR; THIS MEANS THAT WE (USER, ACTUALLY) MUST ENDURE A DELAY FOR THIS
;20APR; PURPOSE WHENEVER THE MACHINE IS TURNED ON, EVEN IF NO SCSI DRIVES ARE
;20APR; BEING USED - BUT HELL, IT'S NOT EVEN ENOUGH TIME TO CUT UP A COUPLE OF
;20APR; LINES, SO WHY SHOULD I BE WORRIED ANYWAY?   OKAY, OKAY!  IT SUCKS, AND
;20APR; YOU'RE RIGHT - SO, EVEN BEFORE WE INITIALLY RESET THE BUS, WE STEP
;20APR; THROUGH ALL SCSI CHANNELS WITH A REQUEST_SENSE COMMAND JUST TO SEE IF
;20APR; ANYBODY'S OUT THERE AT ALL - WE PROCEED FURTHER ONLY IF WE GET SOME
;20APR; RESPONSE ON AT LEAST ONE CHANNEL, ELSE WE DEFAULT TO FLOPPY DRIVE.
;20APR;
;20APRSCSI_MULTIPLE_CONF
;20APR               MOVE.L  #SCSI_SCAN_SCRN,A1   ;TELL 'EM WHAT WE'RE UP TO.
;20APR                ABS_LONG
;20APR               JSR     DISP_SCREEN
;20APR                ABS_SHORT
;20APR               MOVE    #6,DRIVE_SEL         ;CHECK ALL CHANNELS FOR ANY SIGN OF LIFE.
;20APRSC_MLCF_20
;20APR               BSR     REQUEST_SENSE        ;JUST TRY FOR ANY RESPONSE AT ALL ON CURRENT CHANNEL -
;20APR               BEQ.S   SC_MLCF_30           ;THIS IS AS GOOD A SIGN AS ANY, EXIT FROM LOOP.
;20APR               CMP.B   #SELECT_FAILED,D0    ;WAS THERE REALLY NOTHING, OR JUST A SCSI ERROR?
;20APR               BNE.S   SC_MLCF_30           ;SOME KIND OF ERROR - BLAST THE BUS AND PROCEED.
;20APR               SUBQ    #1,DRIVE_SEL         ;REALLY NOTHING THERE - STEP DOWN TO NEXT SCSI CHANNEL.
;20APR               BPL.S   SC_MLCF_20           ;LOOP AGAIN IF WE DIDN'T GET THROUGH ALL OF THEM.
;20APR               MOVE.L  #NO_SCSI_SCRN,A1     ;ELSE, TELL 'EM WE DI'NT SEE NUTTIN' OUT DERE,
;20APR                ABS_LONG
;20APR               JSR     DISP_SCREEN
;20APR                ABS_SHORT
;20APR               BSR     WAIT_TWO_SECS        ;GIVE 'EM A CHANCE TO READ THE NEWS, OH BOY.
;20APR                                            ;NOW, EXIT WITH DRIVE_SEL = -1 (FLOPPY DRIVE) -
;20APR               CLR     D0                   ;EXIT WITH Z FLAG TRUE - THIS IS PROBABLY OKAY, EH?
;20APR               BRA.S   SC_MLCF_EXIT
;20APR;
;20APRSC_MLCF_30
;20APR               BSR     RESET_SCSI           ;FLATTEN THE SCSI BUS - FOR DATAFRAME DRIVES, THIS ALSO
;20APR                                            ;CAUSES CONTROLLER ID INFO TO BE COPIED INTO DRIVE
;20APR                                            ;INTERNAL DATA BUFFERS.
;20APR;
;20APR               BSR.S   SCSI_RECAL_DELAY     ;NOW, WAIT WAIT WAIT - ENTERTAIN USER BETIMES ....
;20APR;
;20APR               CLR     DRIVE_SEL            ;START ON SCSI CHANNEL 0.
;20APR;
;20APRSC_MLCF_40
;20APR               BSR     DISP_CONFIG_SCREEN   ;TELL THE WORLD WUZ HABNIN.
;20APR               BSR     READ_DATA_BUFFER     ;OBTAIN CONTROLLER TYPE, IF ANY - SET CUR_OMTI_REV.
;20APR               BEQ.S   SC_MLCF_60           ;BRANCH IF WE DIDIT - CONFIGGER SUMORE.
;20APR               CMP.B   #SELECT_FAILED,D0    ;WE DIDN'T - WAS ANYTHING OUT THERE?
;20APR               BNE.S   SC_MLCF_EXIT         ;BRANCH IF YES - THIS MEANS TROUBLE, LET'S BOOGIE.
;20APR               CLR     D1                   ;NOTHING THERE - CLEAR ASSOCIATED BANK_SEL CELL,
;20APR               BRA.S   SC_MLCF_80           ;DON'T BOTHER WITH FURTHER EFFORT ON THIS CHANNEL.
;20APRSC_MLCF_60
;20APR               BSR     CONFIG_DATAFRAME     ;SET UP DRIVE PER CUR_OMTI_REV OBTAINED ABOVE.
;20APR               BNE.S   SC_MLCF_EXIT         ;EXIT IF ANYTHING DIDN'T WORK OUT AS EXPECTED.
;20APR               MOVEQ   #0FFH,D1             ;ELSE, SET FLAG TO INDICATE SUCCESSFUL CONFIGURE.
;20APRSC_MLCF_80
;20APR               MOVE    DRIVE_SEL,D0         ;SET POINTER TO BANK_SEL CELL,
;20APR               MOVE    D0,A0
;20APR               MOVE.B  D1,BANK_SEL(A0)      ;STORE STATUS FLAG.
;20APR               ADDQ    #1,D0                ;NEXT CHANNEL, PLEEZ -
;20APR               CMP     #7,D0                ;ARE WE AT THE END OF THE LINE?
;20APR               BCC.S   SC_MLCF_A0           ;YES - GO TAKE STOCK OF THE SITUATION.
;20APR               MOVE    D0,DRIVE_SEL         ;ELSE, STORE NEW SCSI CHANNEL NUMBER, LOOP AGAIN.
;20APR               BRA.S   SC_MLCF_40
;20APR;
;20APRSC_MLCF_A0
;20APR               MOVE    #BANK_SEL,A0         ;SET POINTER TO BANK_SEL ARRAY.
;20APR               MOVEQ   #-1,D0               ;SET DEFAULT DRIVE_SEL VALUE (FOR FLOPPY).
;20APR               MOVE    D0,DRIVE_SEL
;20APR                                            ;FALL INTO DRIVE STATUS POLL LOOP.
;20APRSC_MLCF_C0
;20APR               ADDQ    #1,D0                ;NEXT SCSI CHANNEL, IF ANY -
;20APR               CMP     #7,D0
;20APR               BCC.S   SC_MLCF_E0           ;EXIT IF WE TRIED 'EM ALL, STICK WITH FLOPPY.
;20APR               TST.B   0(A0,D0)             ;DRIVE CONFIGURED ON THIS CHANNEL?
;20APR               BEQ     SC_MLCF_C0           ;LOOP AGAIN IF NOT -
;20APR               MOVE    D0,DRIVE_SEL         ;ELSE SET THIS CHANNEL AS CURRENT OPERATING CHANNEL.
;20APRSC_MLCF_E0
;20APR               CLR.L   (A0)+                ;NOW CLEAR 7 WORDS IN BANK_SEL ARRAY, THEN EXIT.
;20APR               CLR.L   (A0)+
;20APR               CLR.L   (A0)+
;20APR               CLR     (A0)
;20APRSC_MLCF_EXIT
;20APR               RTS
;20APR;
;20APR;
;20APRSCSI_RECAL_DELAY
;20APR               MOVE.L  #SCSI_RECAL_SCRN,A1
;20APR                ABS_LONG
;20APR               JSR     WRITE_SCREEN
;20APR                ABS_SHORT
;20APR               MOVEQ   #24,D0               ;ALLOW 24 SECONDS, TO BE SAFE NOT SLOPPY.
;20APRSC_WAKE_10
;20APR               MOVE    D0,-(A7)             ;SAVE TIMER VALUE,
;20APR                ABS_LONG
;20APR               JSR     WORD_BIN_TO_BCD      ;CONVERT TO ASCII,
;20APR                ABS_SHORT
;20APR               MOVE    BCD_DIGITS+6,SCREEN_BUFFER+28       ;STIKIT INTO SCREEN,
;20APR                ABS_LONG
;20APR               JSR     DISP_BUFFER          ;PUT THE SCREEN OUT THERE.
;20APR                ABS_SHORT
;20APR               BSR     WAIT_A_SECOND        ;NOW JUST WAIT A SECOND.
;20APR               MOVE    (A7)+,D0             ;RETRIEVE TIMER VALUE,
;20APR               SUBQ    #1,D0                ;BUMPET DOWN,
;20APR               BNE     SC_WAKE_10           ;LOOP AGAIN IF TIME REMAINS.
;20APR               RTS
;20APR;
;20APR;
;20APRSCSI_SCAN_SCRN
;20APR               ASC     "SCANNING FOR    "
;20APR               ASC     "SCSI DEVICES...."
;20APR;
;20APRNO_SCSI_SCRN
;20APR               ASC     "NO SCSI DEVICES "
;20APR               ASC     " WERE DETECTED  "
;20APR;
;20APRSCSI_RECAL_SCRN
;20APR               ASC     " RECALIBRATION  "
;20APR               ASC     " PERIOD:    25  "
;20APR;
;20APR;AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
               SKIP
;900424;VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV
;900424;
;900424; CONFIGURE ALL SCSI DRIVES -
;900424; CALLED DURING POWER-UP PROCEDURE AND BY "RESET SCSI DISKS" UTILITY.
;900424; AT PRESENT, ASSUMES DATAFRAMES ONLY.
;900424;
;900424; FIRST WE POLL CHANNELS 0-6 TO SEE WHICH ONES HAVE DRIVES ON THEM.
;900424; THIS INFO IS STORED IN A MAP FOR USE DURING CONFIGURATION LOOP.
;900424;
;900424; NEXT, WE RESET THE BUS - THIS CAUSES ALL DRIVES TO REINITIALIZE,
;900424; WHICH PER THE OMTI CONTROLLER SPEC MEANS THAT WE WILL THEN BE ABLE TO
;900424; READ THE CONTROLLER FIRMWARE MODEL NUMBER VIA THE READ_DATA_BUFFER
;900424; COMMAND.  THIS PIECE OF INFO LETS US KNOW WHAT THE SPECIAL SETUP NEEDS
;900424; OF EACH DRIVE ARE, AND WHAT KIND OF RESPONSES TO EXPECT.
;900424;
;900424; NOW WE ENTER A LOOP IN WHICH THE CHANNELS WHICH SHOWED DRIVES PRESENT
;900424; ARE ROTATED THROUGH, WITH ATTEMPTS MADE ON EACH TO SELECT THE DRIVE.
;900424; SOME BACKGROUND HERE:  OLDER OMTI 3100 READS ITS SCSI ID FROM HARDWARE
;900424; JUMPERS FOLLOWING RESET AND IS CAPABLE OF RESPONDING TO SELECTION
;900424; SOON AFTER RESET.  BUS RESET DOES NOT TRIGGER RECALIBRATION BY ITSELF.
;900424; NEWER 3103/5 OBTAIN SCSI ID AND OTHER INFO FROM THE ID FIELD OF SECTOR
;900424; 0 OF THE DISK ITSELF.  BEFORE THIS READ CAN OCCUR, THE CONTROLLER MUST
;900424; RECALIBRATE THE DRIVE - TAKES A WHILE IF THE HEADS WERE IN PARKED
;900424; POSITION, BUT TAKES ALMOST NO TIME IF THE DRIVE WAS JUST POWERED UP.
;900424; IN THE MEANTIME, THE CONTROLLER DOES NOT KNOW ITS OWN ID AND WILL NOT
;900424; RESPOND TO SELECTION ATTEMPTS - IT'LL SEEM TO HAVE VANISHED FROM BUS.
;900424; HENCE, THE NEED FOR THE ROTATIONAL POLLING PROCEDURE.
;900424; UPON RECEIVING RESPONSE ON A GIVEN CHANNEL, THAT CHANNEL'S DRIVE IS
;900424; CONFIGURED (VIA CONFIG_DATAFRAME), THE CHANNEL IS REMOVED FROM THE
;900424; POLL LIST (LEAVING ONLY THOSE CHANNELS WHICH HAVE NOT YET RESPONDED),
;900424; AND SAME CHANNEL IS ADDED TO THE "CONFIGURED" LIST.  THE POLL LOOP IS
;900424; EXITED WHEN THE POLL LIST IS EMPTY (OR TIMEOUT OCCURS).
;900424;
;900424; WHEN ALL DETECTED DRIVES HAVE BEEN CONFIGURED, THE "CONFIGURED" LIST
;900424; IS INSPECTED AND THE LOWEST-NUMBERED CHANNEL IS SELECTED AS THE
;900424; CURRENT WORKING DRIVE CHANNEL.
;900424;
;900424; OCCURRENCE OF DRIVE OR SCSI ERROR AT ANY TIME CAUSES PROCESS TO BE
;900424; ABORTED - DRIVE_SEL IS LEFT ON THE CHANNEL ON WHICH ERROR OCCURRED.
;900424;
;900424; USES CELLS IN BANK_SEL ARRAY TO TRACK PROGRESS AT VARIOUS POINTS -
;900424; IN OTHER WORDS, DESTROYS WHATEVER SETTINGS WERE ALREADY THERE.
;900424;
;900424; ASSUMING NO FATAL ERROR OCCURS, WE RETURN WITH Z FLAG TRUE AND
;900424; DRIVE_SEL SET TO THE LOWEST SCSI CHANNEL ON WHICH A DRIVE WAS SEEN,
;900424; OR TO -1 (SELECTS FLOPPY) IF NO SCSI DRIVE WAS SEEN ON ANY CHANNEL.
;900424; ALSO, ALL BANK_SEL CELLS ARE CLEARED TO 0 (BANK 001).
;900424;
;900424;
;900424SCSI_MULTIPLE_CONF
;900424               MOVE.L  #SCSI_SCAN_SCRN,A1   ;TELL 'EM WHAT WE'RE UP TO.
;900424                ABS_LONG
;900424               JSR     DISP_SCREEN
;900424                ABS_SHORT
;900424               SF      BANK_SEL             ;BANK_SEL(0).B MAPS DETECTED DRIVES - EMPTY AT START.
;900424               MOVE    #6,DRIVE_SEL         ;CHECK ALL CHANNELS FOR ANY SIGN OF LIFE.
;900424SC_MLCF_20
;900424               BSR     REQUEST_SENSE        ;JUST TRY FOR ANY RESPONSE AT ALL ON CURRENT CHANNEL -
;900424               BEQ.S   SC_MLCF_24           ;THIS IS AS GOOD A SIGN AS ANY, SET FLAG FOR THIS CHAN.
;900424               CMP.B   #SELECT_FAILED,D0    ;WAS THERE REALLY NOTHING, OR JUST A SCSI ERROR?
;900424               BEQ.S   SC_MLCF_28           ;REALLY NOTHING - MOVE ON TO NEXT CHANNEL.
;900424SC_MLCF_24
;900424               MOVE    DRIVE_SEL,D0         ;SET FLAG TO INDICATE DRIVE DETECTED ON THIS CHANNEL.
;900424               BSET    D0,BANK_SEL
;900424SC_MLCF_28
;900424               SUBQ    #1,DRIVE_SEL         ;DONE LOOKING THERE - STEP DOWN TO NEXT SCSI CHANNEL.
;900424               BPL.S   SC_MLCF_20           ;LOOP AGAIN IF WE DIDN'T GET THROUGH ALL OF THEM.
;900424;
;900424               TST.B   BANK_SEL             ;LOOKED EVERYWHERE - WHAT DID WE FIND?
;900424               BNE.S   SC_MLCF_30           ;WE FOUND SOMEONE OUT THERE - KEEP ON GOING.
;900424;
;900424               MOVE.L  #NO_SCSI_SCRN,A1     ;ELSE, TELL 'EM WE DI'NT SEE NUTTIN' OUT DERE,
;900424                ABS_LONG
;900424               JSR     DISP_SCREEN
;900424                ABS_SHORT
;900424               BSR     WAIT_TWO_SECS        ;GIVE 'EM A CHANCE TO READ THE NEWS, OH BOY.
;900424                                            ;NOW, EXIT WITH DRIVE_SEL = -1 (FLOPPY DRIVE) -
;900424               CLR     D0                   ;EXIT WITH Z FLAG TRUE - THIS IS PROBABLY OKAY, EH?
;900424               BRA.S   SC_MLCF_Z0
;900424;
;900424SC_MLCF_30
;900424               BSR     RESET_SCSI           ;FLATTEN THE SCSI BUS - FOR DATAFRAME DRIVES, THIS ALSO
;900424                                            ;CAUSES CONTROLLER ID INFO TO BE COPIED INTO DRIVE
;900424                                            ;INTERNAL DATA BUFFERS.
;900424;
;900424               BSR     DISP_RECAL_SCREEN    ;TELL 'EM WHAT, IF ANYTHING, THEY'RE WAITING FOR.
;900424;
;900424               MOVE    #100,BANK_SEL+2      ;BANK_SEL(2).W IS POLL LOOP TIMEOUT COUNTER (~25 SEC).
;900424               SF      BANK_SEL+1           ;BANK_SEL(1).B IS MAP OF CONFIGURED DRIVES - NONE YET.
;900424               CLR     DRIVE_SEL            ;JUMP IN ON SCSI CHANNEL 0.
;900424;
;900424SC_MLCF_40
;900424               TST.B   BANK_SEL             ;ANY NON-R.S.V.P. DRIVES REMAINING?
;900424               BEQ.S   SC_MLCF_A0           ;NO - WE'VE CONFIGURED ALL WE FOUND, GO SELECT ONE.
;900424               MOVE    DRIVE_SEL,D0         ;YES - IS THIS THE CHANNEL FOR ONE OF THEM?
;900424               BTST    D0,BANK_SEL
;900424               BEQ.S   SC_MLCF_90           ;NO - GO ON TO ANOTHER CHANNEL, TRY AGAIN.
;900424;
;900424                                            ;YES - DRIVE SHOULD BE HERE - SEE IF ANYONE HOME ....
;900424               BSR     READ_DATA_BUFFER     ;OBTAIN CONTROLLER TYPE, IF ANY - SET CUR_OMTI_REV.
;900424               BEQ.S   SC_MLCF_60           ;BRANCH IF WE DIDIT - CONFIGGER SUMORE.
;900424               CMP.B   #SELECT_FAILED,D0    ;WE DIDN'T - WAS ANYTHING OUT THERE?
;900424               BNE.S   SC_MLCF_Z0           ;BRANCH IF YES - THIS MEANS TROUBLE, LET'S BOOGIE.
;900424               SUBQ    #1,BANK_SEL+2        ;NO RESPONSE YET, HOW'S THE TIMEOUT COMING?
;900424               BEQ.S   SC_MLCF_A0           ;IT'S GONE - LET'S JUST FORGET THOSE LATECOMERS.
;900424               BRA.S   SC_MLCF_90           ;STILL TIME LEFT - COME BACK TO THIS CHANNEL LATER.
;900424;
;900424SC_MLCF_60
;900424               BSR     CONFIG_DATAFRAME     ;SET UP DRIVE PER CUR_OMTI_REV OBTAINED ABOVE.
;900424               BNE.S   SC_MLCF_Z0           ;EXIT IF ANYTHING DIDN'T WORK OUT AS EXPECTED.
;900424               MOVE    DRIVE_SEL,D0         ;ELSE, SET FLAG TO INDICATE SUCCESSFUL CONFIGURE.
;900424               BSET    D0,BANK_SEL+1
;900424               BCLR    D0,BANK_SEL          ;PLUS, TAKE THIS CHANNEL OUT OF NON-R.S.V.P. LIST.
;900424               BSR.S   DISP_RECAL_SCREEN    ;AND, REMIND THEM WHAT'S (STILL) GOING ON.
;900424;
;900424SC_MLCF_90
;900424               ADDQ    #1,D0                ;NEXT CHANNEL, PLEEZ -
;900424               CMP     #7,D0                ;ARE WE AT THE END OF THE LINE?
;900424               BCS.S   SC_MLCF_94           ;NO - D0 CONTAINS NEXT CHANNEL TO BE POLLED.
;900424               CLR     D0                   ;ELSE - BACK TO THE BEGINNING, AGAIN.
;900424SC_MLCF_94
;900424               MOVE    D0,DRIVE_SEL         ;STORE NEW CHANNEL NUMBER, LOOP AGAIN (POLL S'MORE).
;900424               BRA.S   SC_MLCF_40
;900424;
;900424;
;900424SC_MLCF_A0
;900424                                            ;SO MUCH FOR ALL THAT:
;900424               MOVEQ   #-1,D0               ;SET DEFAULT DRIVE_SEL VALUE (FOR FLOPPY).
;900424               MOVE    D0,DRIVE_SEL         ;START AT BOTTOM TO LOOK FOR CONFIGURED DRIVE.
;900424SC_MLCF_C0
;900424               ADDQ    #1,D0                ;NEXT SCSI CHANNEL, IF ANY -
;900424               CMP     #7,D0
;900424               BCC.S   SC_MLCF_D0           ;EXIT IF WE TRIED 'EM ALL, STICK WITH FLOPPY.
;900424               BTST    D0,BANK_SEL+1        ;DRIVE CONFIGURED ON THIS CHANNEL?
;900424               BEQ     SC_MLCF_C0           ;LOOP AGAIN IF NOT -
;900424               MOVE    D0,DRIVE_SEL         ;ELSE SET THIS CHANNEL AS CURRENT OPERATING CHANNEL.
;900424SC_MLCF_D0
;900424               CLR     D0                   ;EXIT THIS WAY WITH NO-ERROR STATUS.
;900424;
;900424SC_MLCF_Z0
;900424               MOVE    #BANK_SEL,A0         ;NOW CLEAR 7 WORDS IN BANK_SEL ARRAY, THEN EXIT.
;900424               CLR.L   (A0)+
;900424               CLR.L   (A0)+
;900424               CLR.L   (A0)+
;900424               CLR     (A0)
;900424               TST.B   D0                   ;REFRESH CONDITION BITS PER VALUE IN D0.B.
;900424SC_MLCF_EXIT
;900424               RTS
;900424;
;900424;
;900424;
;900424DISP_RECAL_SCREEN
;900424               MOVE.L  #SCSI_RECAL_SCRN,A1
;900424                ABS_LONG
;900424               JMP     DISP_SCREEN
;900424                ABS_SHORT
;900424;
;900424;
;900424SCSI_SCAN_SCRN
;900424               ASC     "SCANNING FOR    "
;900424               ASC     "SCSI DEVICES...."
;900424;
;900424NO_SCSI_SCRN
;900424               ASC     "NO SCSI DEVICES "
;900424               ASC     " WERE DETECTED  "
;900424;
;900424SCSI_RECAL_SCRN
;900424               ASC     " AWAITING DRIVE "
;900424               ASC     " RECALIBRATION -"
;900424;
;900424;AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA


















;VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV
;
; CONFIGURE ALL SCSI DRIVES -
; CALLED DURING POWER-UP PROCEDURE AND BY "RESET SCSI DISKS" UTILITY.
; AT PRESENT, ASSUMES DATAFRAMES ONLY.
;
; FIRST WE POLL CHANNELS 0-6 TO SEE WHICH ONES HAVE DRIVES ON THEM.
; THIS INFO IS STORED IN A MAP FOR USE DURING CONFIGURATION LOOP.
; Additional special escape condition - if at any time during
; this scan loop we detect a BUS_NOT_FREE error condition,
; we skip out of the loop and proceed directly to reset the bus.
; This has the ultimate effect of bypassing all SCSI drive configuration
; and selecting the floppy drive as the active storage device,
; because device-present and device-configured maps remain empty.
;
; Normally, however ....
; NEXT, WE RESET THE BUS - THIS CAUSES ALL DRIVES TO REINITIALIZE,
; WHICH PER THE OMTI CONTROLLER SPEC MEANS THAT WE WILL THEN BE ABLE TO
; READ THE CONTROLLER FIRMWARE MODEL NUMBER VIA THE READ_DATA_BUFFER
; COMMAND.  THIS PIECE OF INFO LETS US KNOW WHAT THE SPECIAL SETUP NEEDS
; OF EACH DRIVE ARE, AND WHAT KIND OF RESPONSES TO EXPECT.
;
; NOW WE ENTER A LOOP IN WHICH THE CHANNELS WHICH SHOWED DRIVES PRESENT
; ARE ROTATED THROUGH, WITH ATTEMPTS MADE ON EACH TO SELECT THE DRIVE.
; SOME BACKGROUND HERE:  OLDER OMTI 3100 READS ITS SCSI ID FROM HARDWARE
; JUMPERS FOLLOWING RESET AND IS CAPABLE OF RESPONDING TO SELECTION
; SOON AFTER RESET.  BUS RESET DOES NOT TRIGGER RECALIBRATION BY ITSELF.
; NEWER 3103/5 OBTAIN SCSI ID AND OTHER INFO FROM THE ID FIELD OF SECTOR
; 0 OF THE DISK ITSELF.  BEFORE THIS READ CAN OCCUR, THE CONTROLLER MUST
; RECALIBRATE THE DRIVE - TAKES A WHILE IF THE HEADS WERE IN PARKED
; POSITION, BUT TAKES ALMOST NO TIME IF THE DRIVE WAS JUST POWERED UP.
; IN THE MEANTIME, THE CONTROLLER DOES NOT KNOW ITS OWN ID AND WILL NOT
; RESPOND TO SELECTION ATTEMPTS - IT'LL SEEM TO HAVE VANISHED FROM BUS.
; HENCE, THE NEED FOR THE ROTATIONAL POLLING PROCEDURE.
; UPON RECEIVING RESPONSE ON A GIVEN CHANNEL, THAT CHANNEL'S DRIVE IS
; CONFIGURED (VIA CONFIG_DATAFRAME), THE CHANNEL IS REMOVED FROM THE
; POLL LIST (LEAVING ONLY THOSE CHANNELS WHICH HAVE NOT YET RESPONDED),
; AND SAME CHANNEL IS ADDED TO THE "CONFIGURED" LIST.  THE POLL LOOP IS
; EXITED WHEN THE POLL LIST IS EMPTY (OR TIMEOUT OCCURS).
;
; Further interesting background as of CCS compatibility update -
; the above loop uses the READ_DATA_BUFFER command routine.
; This is a non-standard command recognized only by Dataframe drives.
; A non-error response to this command indicates the presence of a
; Dataframe drive which may need configuring via CONFIG_DATAFRAME,
; which uses the CUR_OMTI_REV parameter obtained by READ_DATA_BUFFER.
; As discussed above, a "select failed" error response to this command
; is a probable indicator of a Dataframe which is still recalibrating itself.
; Any other type of error response is a probable indicator of a non-Dataframe
; drive which does not recognize the READ_DATA_BUFFER command.
; For now, we assume this to indicate a CCS drive which needs no setup,
; and handle it as a Dataframe which has already been configured.
; A more rigorous check would test the error code returned by READ_DATA_BUFFER
; (should be #STATUS_ERROR), and would issue a REQUEST_SENSE command
; to confirm the specific error (should be "Illegal Request"),
; but this is probably unnecessary.
; 921008-04:10pm
; there's even a bit more to this - see the new documentation
; with the read_data_buffer routine.
;
; 921008-04:32pm
; also - syquest drives behave rather badly if accessed with
; any command other than test unit ready when not ready (ie,
; no cartridge inserted).  there is new code in here to 
; prevent this from occurring.  it's now hard to say whether
; this routine works entirely correctly with dataframes,
; but this is no longer very important ....
;
; WHEN ALL DETECTED DRIVES HAVE BEEN CONFIGURED, THE "CONFIGURED" LIST
; IS INSPECTED AND THE LOWEST-NUMBERED CHANNEL IS SELECTED AS THE
; CURRENT WORKING DRIVE CHANNEL.
;
; OCCURRENCE OF DRIVE OR SCSI ERROR AT ANY TIME CAUSES PROCESS TO BE
; ABORTED - DRIVE_SEL IS LEFT ON THE CHANNEL ON WHICH ERROR OCCURRED.
; That is, for errors other than those discussed above.
;
; USES CELLS IN BANK_SEL ARRAY TO TRACK PROGRESS AT VARIOUS POINTS -
; IN OTHER WORDS, DESTROYS WHATEVER SETTINGS WERE ALREADY THERE.
;
; ASSUMING NO FATAL ERROR OCCURS, WE RETURN WITH Z FLAG TRUE AND
; DRIVE_SEL SET TO THE LOWEST SCSI CHANNEL ON WHICH A DRIVE WAS SEEN,
; OR TO -1 (SELECTS FLOPPY) IF NO SCSI DRIVE WAS SEEN ON ANY CHANNEL.
; ALSO, ALL BANK_SEL CELLS ARE CLEARED TO 0 (BANK 001).
;
;
SCSI_MULTIPLE_CONF
;
;900425               MOVE.L  #SCSI_SCAN_SCRN,A1   ;TELL 'EM WHAT WE'RE UP TO.
               lea.l   SCSI_SCAN_SCRN(pc),A1     ;TELL 'EM WHAT WE'RE UP TO.
;900424                ABS_LONG
;900424               JSR     DISP_SCREEN
;900424                ABS_SHORT
               CALL    LCD_FUNS,DSP_SCRN
               SF      BANK_SEL             ;BANK_SEL(0).B MAPS DETECTED DRIVES - EMPTY AT START.
               MOVE    #6,DRIVE_SEL         ;CHECK ALL CHANNELS FOR ANY SIGN OF LIFE.
SC_MLCF_20
;
;921008-04:14pm               BSR     REQUEST_SENSE        ;JUST TRY FOR ANY RESPONSE AT ALL ON CURRENT CHANNEL -
;921008-04:15pm               BEQ.S   SC_MLCF_24           ;THIS IS AS GOOD A SIGN AS ANY, SET FLAG FOR THIS CHAN.
;
		bsr	test_unit_ready		; try for any response on this chan.
               beq.s   SC_MLCF_24           ; cool - go set flag for this chan.
		bsr	test_unit_ready		; once again, just for fun ....
							; maybe there was unit attention.
               beq.s   SC_MLCF_24           ; cool - go set flag for this chan.
;
               cmpi.b  #BUS_NOT_FREE,d0     ; someone squatting on the bus?
               beq.s   SC_MLCF_30           ; br if yes, kick him in the nuts.
               CMP.B   #SELECT_FAILED,D0    ;WAS THERE NOTHING, OR A SCSI ERROR?
               BEQ.S   SC_MLCF_28           ;REALLY NOTHING - MOVE ON TO NEXT CHANNEL.
SC_MLCF_24
               MOVE    DRIVE_SEL,D0         ;SET FLAG TO INDICATE DRIVE DETECTED ON THIS CHANNEL.
               BSET    D0,BANK_SEL
SC_MLCF_28
               SUBQ    #1,DRIVE_SEL         ;DONE LOOKING THERE - STEP DOWN TO NEXT SCSI CHANNEL.
               BPL.S   SC_MLCF_20           ;LOOP AGAIN IF WE DIDN'T GET THROUGH ALL OF THEM.
;
               TST.B   BANK_SEL             ;LOOKED EVERYWHERE - WHAT DID WE FIND?
               BNE.S   SC_MLCF_30           ;WE FOUND SOMEONE OUT THERE - KEEP ON GOING.
;
;900425               MOVE.L  #NO_SCSI_SCRN,A1     ;ELSE, TELL 'EM WE DI'NT SEE NUTTIN' OUT DERE,
               lea.l   NO_SCSI_SCRN(pc),A1  ;ELSE, TELL 'EM WE DI'NT SEE NUTTIN' OUT DERE,
;900424                ABS_LONG
;900424               JSR     DISP_SCREEN
;900424                ABS_SHORT
               CALL    LCD_FUNS,DSP_SCRN
               BSR     WAIT_TWO_SECS        ;GIVE 'EM A CHANCE TO READ THE NEWS, OH BOY.
                                            ;NOW, EXIT WITH DRIVE_SEL = -1 (FLOPPY DRIVE) -
               CLR     D0                   ;EXIT WITH Z FLAG TRUE - THIS IS PROBABLY OKAY, EH?
               BRA     SC_MLCF_Z0
;
;
SC_MLCF_30
               BSR     RESET_SCSI           ;FLATTEN THE SCSI BUS - FOR DATAFRAME DRIVES, THIS ALSO
                                            ;CAUSES CONTROLLER ID INFO TO BE COPIED INTO DRIVE
                                            ;INTERNAL DATA BUFFERS.
;
               BSR     DISP_RECAL_SCREEN    ;TELL 'EM WHAT, IF ANYTHING, THEY'RE WAITING FOR.
;
               MOVE    #100,BANK_SEL+2      ;BANK_SEL(2).W IS POLL LOOP TIMEOUT COUNTER (~25 SEC).
               SF      BANK_SEL+1           ;BANK_SEL(1).B IS MAP OF CONFIGURED DRIVES - NONE YET.
               CLR     DRIVE_SEL            ;JUMP IN ON SCSI CHANNEL 0.
;
SC_MLCF_40
               TST.B   BANK_SEL             ;ANY NON-R.S.V.P. DRIVES REMAINING?
               BEQ.S   SC_MLCF_A0           ;NO - WE'VE CONFIGURED ALL WE FOUND, GO SELECT ONE.
               MOVE    DRIVE_SEL,D0         ;YES - IS THIS THE CHANNEL FOR ONE OF THEM?
               BTST    D0,BANK_SEL
               BEQ.S   SC_MLCF_90           ;NO - GO ON TO ANOTHER CHANNEL, TRY AGAIN.
;
                                            ;YES - DRIVE SHOULD BE HERE - SEE IF ANYONE HOME ....
;
                                            ; 921008-04:26pm
							; this section traps syquest or 
							; other ccs drives in not-ready
							; state, prevents any further scsi
							; commands from being issued, since
							; in the syquest case this results
							; in a hung target.
		bsr	test_unit_ready		; try for any response on this chan.
               beq.s   SC_MLCF_44           ; cool - go configure this chan.
		bsr	test_unit_ready		; once again, just for fun ....
							; maybe there was unit attention.
               beq.s   SC_MLCF_44           ; cool - go configure this chan.
               cmp.b   #SELECT_FAILED,d0    ; anybody responding?
		bne.s	SC_MLCF_80			; yes, and they are not happy.
							; assume it's not a dataframe -
							; go log it, and leave it alone.
SC_MLCF_44
;
                                            ; 921008-04:30pm
							; here, we know device is ready, but
							; don't know if it is a dataframe.
               BSR     READ_DATA_BUFFER     ;OBTAIN CONTROLLER TYPE, IF ANY - SET CUR_OMTI_REV.
               BEQ.S   SC_MLCF_60           ;BRANCH IF WE DIDIT - this means we
                                            ; have got a Dataframe to configure.
               CMP.B   #SELECT_FAILED,D0    ;WE DIDN'T - WAS ANYTHING OUT THERE?
;
;900424               BNE.S   SC_MLCF_Z0           ;BRANCH IF YES - THIS MEANS TROUBLE, LET'S BOOGIE.
;
;900425               BNE.S   SC_MLCF_80           ; branch if yes - assume this to
;900425                                            ; mean we have a non-Dataframe drive
;900425                                            ; which didn't recognize command,
;900425                                            ; doesn't need to be configured -
;900425                                            ; go log it.
;
               bne.s   SC_MLCF_50           ; branch if someone responded with
                                            ; an error of some sort - assume
                                            ; it is a non-Dataframe drive which
                                            ; didn't recognize read buf command
                                            ; or is in Unit Attention condition,
                                            ; go clear up the misunderstanding.
;
                                            ; otherwise, assume a Dataframe
                                            ; still recalibrating itself:
               SUBQ    #1,BANK_SEL+2        ;NO RESPONSE YET, HOW'S THE TIMEOUT COMING?
               BEQ.S   SC_MLCF_A0           ;IT'S GONE - LET'S JUST FORGET THOSE LATECOMERS.
               BRA.S   SC_MLCF_90           ;STILL TIME LEFT - COME BACK TO THIS CHANNEL LATER.
;
SC_MLCF_50
                                            ; response from non-Dataframe drive:
               bsr     REQUEST_SENSE        ; clear any Unit Attention condition
                                            ; which may be lingering, to avoid
                                            ; error on first user drive access.
                                            ; however, this condition, which
                                            ; arises from bus reset, is normally
                                            ; cleared by any subsequent command,
                                            ; including one such as the read
                                            ; data buffer command above, which
                                            ; itself prompts Check Condition
                                            ; because it is unrecognized.
                                            ; request sense command in response
                                            ; to Check Condition not mandatory,
                                            ; sense data is simply lost if some
                                            ; other command is issued instead -
                                            ; and we don't especially care about
                                            ; the sense data we read here.
                                            ; in other words, this whole step is
                                            ; basically completely unnecessary.
               bra.s   SC_MLCF_80
;
SC_MLCF_60
                                            ; for Dataframes only:
               BSR     CONFIG_DATAFRAME     ;SET UP DRIVE PER CUR_OMTI_REV OBTAINED ABOVE.
               BNE.S   SC_MLCF_Z0           ;EXIT IF ANYTHING DIDN'T WORK OUT AS EXPECTED.
;
SC_MLCF_80
               MOVE    DRIVE_SEL,D0         ; set flag to log on-line drive.
               BSET    D0,BANK_SEL+1
               BCLR    D0,BANK_SEL          ;PLUS, TAKE THIS CHANNEL OUT OF NON-R.S.V.P. LIST.
               BSR.S   DISP_RECAL_SCREEN    ;AND, REMIND THEM WHAT'S (STILL) GOING ON.
;
SC_MLCF_90
               move.w  DRIVE_SEL,d0         ; fetch channel we were looking at.
               ADDQ    #1,D0                ;NEXT CHANNEL, PLEEZ -
               CMP     #7,D0                ;ARE WE AT THE END OF THE LINE?
               BCS.S   SC_MLCF_94           ;NO - D0 CONTAINS NEXT CHANNEL TO BE POLLED.
               CLR     D0                   ;ELSE - BACK TO THE BEGINNING, AGAIN.
SC_MLCF_94
               MOVE    D0,DRIVE_SEL         ;STORE NEW CHANNEL NUMBER, LOOP AGAIN (POLL S'MORE).
               BRA.S   SC_MLCF_40
;
;
SC_MLCF_A0
                                            ;SO MUCH FOR ALL THAT:
               MOVEQ   #-1,D0               ;SET DEFAULT DRIVE_SEL VALUE (FOR FLOPPY).
               MOVE    D0,DRIVE_SEL         ;START AT BOTTOM TO LOOK FOR CONFIGURED DRIVE.
SC_MLCF_C0
               ADDQ    #1,D0                ;NEXT SCSI CHANNEL, IF ANY -
               CMP     #7,D0
               BCC.S   SC_MLCF_D0           ;EXIT IF WE TRIED 'EM ALL, STICK WITH FLOPPY.
               BTST    D0,BANK_SEL+1        ;DRIVE CONFIGURED ON THIS CHANNEL?
               BEQ     SC_MLCF_C0           ;LOOP AGAIN IF NOT -
               MOVE    D0,DRIVE_SEL         ;ELSE SET THIS CHANNEL AS CURRENT OPERATING CHANNEL.
SC_MLCF_D0
               CLR     D0                   ;EXIT THIS WAY WITH NO-ERROR STATUS.
;
SC_MLCF_Z0
               MOVE    #BANK_SEL,A0         ;NOW CLEAR 7 WORDS IN BANK_SEL ARRAY, THEN EXIT.
               CLR.L   (A0)+
               CLR.L   (A0)+
               CLR.L   (A0)+
               CLR     (A0)
               TST.B   D0                   ;REFRESH CONDITION BITS PER VALUE IN D0.B.
SC_MLCF_EXIT
               RTS
;
;
;
DISP_RECAL_SCREEN
;900425               MOVE.L  #SCSI_RECAL_SCRN,A1
               lea.l   SCSI_RECAL_SCRN(pc),A1
;900424                ABS_LONG
;900424               JMP     DISP_SCREEN
;900424                ABS_SHORT
               JUMP    LCD_FUNS,DSP_SCRN
;
;
SCSI_SCAN_SCRN
               ASC     "SCANNING FOR    "
               ASC     "SCSI DEVICES...."
;
NO_SCSI_SCRN
               ASC     "NO SCSI DEVICES "
               ASC     " WERE DETECTED  "
;
SCSI_RECAL_SCRN
               ASC     " AWAITING DRIVE "
               ASC     " RECALIBRATION -"
;
;AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA


















;VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV
;
; ASSIGN DISK PARAMETERS TO DATAFRAME 20 -
; APPLIES ONLY TO DATAFRAME 20 WITH OMTI 3100 CONTROLLER, SINCE LATER
; MODELS 3101/3105 OBTAIN THIS INFO AUTOMATICALLY FROM DISK TRACK 000.
; PART OF POST-RESET INITIALIZATION, MOST IMPORTANT FOR LETTING THE
; 3100 KNOW THE FULL EXTENT OF DRIVE STORAGE CAPACITY.
; WE GO AFTER THE DEVICE INDICATED BY THE CURRENT VALUE OF DRIVE_SEL.
; RETURNS Z FLAG TRUE IF COMMAND SUCCESSFULLY COMPLETED,
; ELSE RETURNS Z FLAG FALSE AND ERROR CODE IN D0 -
; ALL OTHER REGISTERS PRESERVED.
; NOTE: TRIGGERS A COMPLETE SCSI BUS SEQUENCE.
;
ASSIGN_DF20_PARAMS
               MOVEM.L D1-D3/A0,-(A7)
               BSR     SELECT_DEVICE        ;TRY TO GET THE ATTENTION OF DESIRED TARGET.
               BNE.S   ASDP_Z0              ;EXIT IF SELECTION ATTEMPT FAILED.
               MOVE    #0C200H,SCSI_CMD_BUF ;TARGET RESPONDED, SET UP COMMAND DESCRIPTOR BLOCK.
               CLR.L   SCSI_CMD_BUF+2
               BSR     SIX_BYTE_CMD         ;ISSUE COMMAND TO TARGET.
               BNE.S   ASDP_Z0              ;EXIT IF COMMAND NOT SUCCESSFULLY ISSUED.
               MOVEQ   #DAT_OUT_PHASE,D0    ;COMMAND ACCEPTED - SET UP TRANSFER OF PARAMETER LIST.
               MOVEQ   #10,D2               ;PARAMETER LIST IS 10 BYTES LONG.
               MOVEQ   #1,D3                ;SEEMS TO NEED ONE EXTRA BYTE FOLLOWING PARAMETER LIST.
;900425               MOVE.L  #DATAFR_20_PARAMS,A0 ;THIS IS WHERE THE LIST IS.
               lea.l   DATAFR_20_PARAMS(pc),A0   ;THIS IS WHERE THE LIST IS.
               BSR     SCSI_RAM_WRITE       ;OKAY, OKAY - IT'S ROM, NOT RAM - FUCK OFF.
               BNE.S   ASDP_Z0              ;EXIT IF PARAMETER LIST NOT SUCCESSFULLY TRANSFERRED.
               BSR     FINISH_SCSI_SEQ      ;GET COMPLETION STATUS, RETURN THROUGH WITH RESULTS.
;
ASDP_Z0
               MOVEM.L (A7)+,D1-D3/A0
ASDP_EXIT
               RTS
;
;
DATAFR_20_PARAMS
               DC.B    04H             ;STEP PULSE WIDTH (1.2 USEC).
               DC.B    01H             ;STEP PULSE PERIOD (6.8 USEC).
               DC.B    00H             ;STEP MODE - MUST BE ZERO.
               DC.B    03H             ;NUMBAH HEADS MINUS ONE.
               DC.W    640             ;MAXIMUM CYLINDER ADDRESS (NOTE:  ACTUAL MAXIMUM ADDRESS FOR
                                       ;DATA OPS IS 612, BUT HEADS ARE PARKED ON CYLINDER 635 -
                                       ;EXTRA RANGE PREVENTS ERROR DURING RECALIBRATE COMMAND).
                                       ;(POST-SCRIPT, 16-APR-87: WE CHANGED HEAD PARK CYLINDER TO
                                       ;615, BUT IT DOESN'T HURT TO USE 640 AS THE MAX VALUE HERE.)
               DC.W    8000H           ;WSI/PRECOMP CYLINDER (80H) - MOLTO MYSTERIOSO, NO?
               DC.B    16              ;SECTORS PER TRACK MINUS ONE.
               DC.B    00H             ;BLOCK SIZE (DEFAULT PER JUMPERS).
;
;AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
               SKIP
;VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV
;
; SEND SPECIFIERS TO DATAFRAME DRIVE -
; APPLIES ONLY TO DATAFRAMES WITH OMTI 3103/3105 CONTROLLERS, SINCE THE
; SPECIFIER AUTO-READ-ON-RESET FEATURE IS NOT SUPPORTED BY 3100.
;
; USED MAINLY TO SET NEW SCSI DEVICE ID - 3103/3105 CONTROLLERS DO NOT
; PROVIDE JUMPERS FOR SETTING SCSI ID (SUCH AS ARE FOUND ON THE 3100).
; ALSO USED AS PART OF THE "FORMATTING" PROCEDURE (INIT_SCSI_DIR), TO
; EXTEND THE DEFAULT MAXIMUM CYLINDER ADDRESS FROM 612/615 TO 640, SO
; THAT WE CAN SEEK TO CYLINDER 635 (FOR HEAD PARKING) WITHOUT ERRORS.
;
; SIMILAR IN OVERALL FORM TO THE ASSIGN_DF20_PARAMS COMMAND, BUT EXTRA
; BIT IN COMMAND STRING ORDERS CONTROLLER TO REFORMAT TRACK 00, DURING
; WHICH THE SPECIFIER INFO IS WEDGED INTO THE ID FIELD OF RECORD 0
; (and you thought WE were doing gross kludgey things, WELL ....) -
; THE 3103/3105 CONTROLLERS LOOK FOR IT THERE AUTOMATICALLY FOLLOWING
; RESET, TELLS 'EM WHAT THE ASSIGN_DF20_PARAMS COMMAND TELLS THE 3100.
;
; IN ORDER TO AVOID HAVING TO GET DRIVE SIZE OUT OF THE USER FOR THIS
; (YES, NUMBER OF HEADS IS ONE OF THE SPECIFIER PARAMETERS - YUCKO),
; WE ALLOW THIS PROCEDURE ONLY WITH DISKS CONTAINING A VALID SEQUENTIAL
; DISK DESCRIPTOR, WHICH TELLS US ALL WE NEED TO KNOW.
;
; AS FURTHER STUFF JUST FOR YOU TO READ - SPECIFIER PARAMETER LIST IS
; THE SAME FOR ALL DATAFRAME DRIVES, EXCEPT:
; -  3100 STEP MODE BYTE IS REDEFINED AS SCSI ID FOR 3103/3105.
; -  40-MEG DRIVES HAVE EIGHT HEADS, AS OPPOSED TO FOUR ON 20-MEGGERS.
; -  ACTUAL MAXIMUM CYLINDER ADDRESS IS 612 FOR 20 MEG, 615 FOR 40 MEG -
;    BUT ALL PARK HEADS ON CYLINDER 635, SO WE GIVE THE CONTROLLER SOME
;    EXTRA "HEADROOM" (SORRY) AND TELL IT MAX CYL ADDR IS 640 FOR ALL.
;
; WE GO AFTER THE DEVICE INDICATED BY THE CURRENT VALUE OF DRIVE_SEL.
; RETURNS Z FLAG TRUE IF COMMAND SUCCESSFULLY COMPLETED,
; ELSE RETURNS Z FLAG FALSE AND ERROR CODE IN D0 -
; ALL OTHER REGISTERS PRESERVED.
; NOTE: TRIGGERS A COMPLETE SCSI BUS SEQUENCE.
;
SEND_SPECIFIERS
               MOVEM.L D1-D3/A0-A1,-(A7)
               BSR     SELECT_DEVICE        ;TRY TO GET THE ATTENTION OF DESIRED TARGET.
               BNE.S   SNDSPC_Z0            ;EXIT IF SELECTION ATTEMPT FAILED.
               MOVE    #0C200H,SCSI_CMD_BUF ;TARGET RESPONDED, SET UP COMMAND DESCRIPTOR BLOCK.
               CLR.L   SCSI_CMD_BUF+2
               MOVE.B  #20H,SCSI_CMD_BUF+5  ;THIS IS THE MUCH-VAUNTED "F"-BIT.
               BSR     SIX_BYTE_CMD         ;ISSUE COMMAND TO TARGET.
               BNE.S   SNDSPC_Z0            ;EXIT IF COMMAND NOT SUCCESSFULLY ISSUED.
               MOVEQ   #DAT_OUT_PHASE,D0    ;COMMAND ACCEPTED - SET UP TRANSFER OF PARAMETER LIST.
               MOVEQ   #10,D2               ;PARAMETER LIST IS 10 BYTES LONG.
               MOVEQ   #1,D3                ;SEEMS TO NEED ONE EXTRA BYTE FOLLOWING PARAMETER LIST.
;900425               MOVE.L  #DATAFR_20_PARAMS+10,A1   ;PICK UP DATAFRAME 20 DISK PARAMETER LIST,
               lea.l   DATAFR_20_PARAMS+10(pc),A1     ;PICK UP DATAFRAME 20 DISK PARAMETER LIST,
               MOVE    #WASTELAND+10,A0          ;PLOP IT INTO WASTELAND SO WE CAN DIDDLE IT -
               MOVE.L  -(A1),-(A0)
               MOVE.L  -(A1),-(A0)
               MOVE    -(A1),-(A0)
               MOVE.B  NEW_SCSI_ID+1,2(A0)       ;SET DESIRED NEW SCSI ID FOR DRIVE WE'RE TICKLING.
               CMP     #DF40_3103,HD_DRIVE_TYPE  ;IF WE GOT A 40 MEG DRIVE, GOTTA CHANGE SPEC BYTE
               BEQ.S   SNDSPC_20                 ;FOR NUMBER OF HEADS.
               CMP     #DF40_3105,HD_DRIVE_TYPE
               BNE.S   SNDSPC_40
SNDSPC_20
               MOVE.B  #7,3(A0)                  ;SAY IT BE EIGHT HEADS, NOT FOUR.
SNDSPC_40
               BSR     SCSI_RAM_WRITE       ;OKAY, NOW JAM-UM PARAMETERS.
               BNE.S   SNDSPC_Z0            ;EXIT IF PARAMETER LIST NOT SUCCESSFULLY TRANSFERRED.
               BSR     FINISH_SCSI_SEQ      ;GET COMPLETION STATUS, RETURN THROUGH WITH RESULTS.
;
SNDSPC_Z0
               MOVEM.L (A7)+,D1-D3/A0-A1
SNDSPC_EXIT
               RTS
;
;AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
               SKIP
;VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV
;
; PARK HARD DISK HEADS OUT IN THE SHIPPING ZONE - DATAFRAMES ONLY.
; WE LEAVE 'EM THERE AFTER EACH USE, SINCE WE HAVE NO SHUT-DOWN COMMAND.
; THIS WAY, SPACE-SHOT USER NEED NOT REMEMBER TO DO THIS HIM/HERSELF.
; WE GO AFTER THE DEVICE INDICATED BY THE CURRENT VALUE OF DRIVE_SEL.
; FOR ALL DATAFRAMES - WE USE SEEK TO CYLINDER 635 (DECIMAL), WHICH IS
; AT LEAST TWENTY CYLINDERS BEYOND AREAS WHICH MIGHT CONTAIN DATA,
; BASED ON SUPERMAC'S STATED SPEC THAT 612/615 IS THE MAXIMUM CYLINDER
; ADDRESS FOR DATAFRAME 20/40 RESPECTIVELY.
;
; For "standard" SCSI drives, read no further -
; this type of head parking does not apply.
; If disk descriptor indicates this type of drive,
; we return without action (no-error return).
;
; UNFORTUNATELY, DATAFRAME SEEK COMMAND IS DONE IN TERMS OF LOGICAL
; BLOCK ADDRESS, SUCH THAT DIFFERENT ADDRESSES MUST BE USED TO HIT CYL
; 635 DEPENDING UPON DRIVE CAPACITY (NUMBER OF HEADS).  SINCE THIS PIECE
; OF DATA CAN BE RELIABLY AUTOMATICALLY OBTAINED ONLY FROM OUR MAIN DISK
; DESCRIPTOR (IN THE GUISE OF HD_DRIVE_TYPE OR HD_CAPACITY), THE HEAD
; PARK COMMAND IS NOT GUARANTEED TO WORK WITH DRIVES WHICH HAVE NOT HAD
; A 440-STYLE DIRECTORY WRITTEN ON THEM - DRAG BUMMER.  AS A COP-OUT
; KINDA SOLUTION TO THIS PROBLEM, WE CHECK VALID_HD_DESCR FLAG TO SEE IF
; WE CAN BELEIVE WHAT'S CURRENTLY IN MAIN DISK DESCRIPTOR - IF NOT, WE
; DON'T BOTHER TRYING TO PARK (BETTER FOR OUR PURPOSES TO LEAVE HEADS
; OVER TRACK 000 RATHER THAN SOMEWHERE OVER THE MIDDLE OF THE DISK).
;
; SOME FURTHER BACKGROUND ON THE WHOLE TOPIC OF DRIVE UTILIZATION AND
; HEAD PARKING:
;    FIRST 32 TRACKS ARE RESERVED FOR ALTERNATE-TRACK ASSIGNMENT (BY THE
;    "REAL" FORMATTING ROUTINE WHICH WE DON'T DO) - HANDS OFF!  THIS IS
;    TRACKS, NOT CYLINDERS - AT 17 RECORDS PER, A TOTAL OF 544 RECORDS.
;    RECORD #544 (#DF_BASE_REC) IS OUR MAIN DISK DESCRIPTOR RECORD.
;    EACH BANK TAKES UP 1559 RECORDS (AT LEAST, AT THIS WRITING .... ) -
;    WITH 612 CYLINDERS * 17 SECTORS/TRACK * 4 OR 8 HEADS, TOTAL BLOCK
;    CAPACITY IS  612*17*4/8 - 545 = 41616/83232-545 = 41071/82687 FOR
;    20MEG/40MEG DRIVES, RESPECTIVELY - THE CORRESPONDING BANK CAPACITY
;    IS 41071/1559 = 26 FOR 20MEG, OR 82687/1559 = 53 FOR 40MEG.
;    LOGICAL BLOCK ADDRESS FOR HEAD PARKING IS OBTAINED BY CALCULATING
;    (CYL) 635 * 17 (SECTORS/TRACK) * 4 OR 8 (HEADS, PER DRIVE SIZE),
;    = 43180/86360 OR 0A8ACH/15158H FOR 20MEG/40MEG.
;
; BUT WAIT - IT GETS WORSE .... SEEMS THAT DATAFRAMES MAY CONTAIN DRIVES
; FROM A VARIETY OF MANUFACTURERS.  FOR MOST OF THEM, THE PROCEDURE LAID
; OUT ABOVE IS JUST FINE, THANKS, BUT WITH A LAPINE DRIVE (WHICH HAS
; AUTOMATICAL-TYPE POWER-DOWN HEAD LIFTERS, ANYWAY), A SEEK TO ANY TRACK
; ABOVE 616 CAUSES A "NO SEEK-COMPLETE" STATUS FROM THE DRIVE - WHICH,
; IT MUST BE ASSUMED (SINCE NO ONE WANTS TO SAY FOR CERTAIN), IS ECHOED
; BACK VIA THE CONTROLLER, CAUSING ERROR MESSAGES, CONSTERNATION, ANGER
; AND ULTIMATELY, AIRBORNE ELECTRONICS (THE DATAFRAME, 440, ETC).
; SINCE THERE IS NO EASY WAY TO FIGURE OUT WHAT KIND OF DRIVE IS INSIDE
; ANY GIVEN DATAFRAME (SHORT OF OPENING IT UP AND LOOKING), THE SAFEST
; WAY AROUND THIS SITUATION IS SIMPLY TO NOT HAVE IT COME UP AT ALL.
; SO - WORK THROUGH THE SAME SERIES OF COMPUTATIONS DONE ABOVE, ONLY
; THIS TIME SAY WE'RE GONNA PARK ON CYLINDER 615, AND NOT USE ANY
; CYLINDER ABOVE #595 FOR DATA STORAGE.  YOUR RESULTS SHOULD BE:
;    BANK CAPACITY IS 25/51 FOR 20MEG/40MEG.
;    PARK ADDRESS IS 41820/83640 (0A35CH/146B8H) FOR 20MEG/40MEG.
;
; LOOK! - DON'T BITCH.  I WANTED TO TEST THIS.  REALLY.  DO YOU HAVE ANY
; IDEA WHAT A HASSLE IT IS TRYING TO GET ANYTHING OUT OF THOSE GUYS UP
; AT SUPERMAC?  DO YOU WANT TO DEAL WITH A RASH OF PHONE CALLS FROM
; IRATE CUSTOMERS WHO BOUGHT USED DATAFRAMES TO SAVE A FEW *** DINEROS,
; ONLY TO BE CONFRONTED WITH "SENSE KEY = 02H" AT EVERY TURN?
; DO YOU HAVE ANY BETTER WAYS OF DEALING WITH THIS?  WHAT?  YOU DO?
; WELL GET ON WITH IT THEN, AND GET OUT OF MY LIFE - AND FURTHERMORE,
; WHERE DO YOU GET OFF DOING LEISURE READING ON COMPANY TIME???!!!
;
; ALLRIGHT.  I'M SORRY.  REALLY, THAT WAS UNFAIR, UN-CALLED-FOR.
; THE GUYS AT SUPERMAC WERE QUITE HELPFUL, GIVEN A FAIR CHANCE.
; THEY FOUND ME A LAPINE DRIVE, SET IT UP FOR ME, AND I TESTED IT.
; WHILE THE 440 DID NOT HANG UP IN ALL SORTS OF WEIRD ERROR MESSAGES
; AFTER EVERY DISK OPERATION, IT DID BOG DOWN CONSIDERABLY WHILE THE
; LAPINE DRIVE RANDOMLY RECALIBRATED ITSELF AND SO FORTH.
; HENCE, THE CHANGES STICK.
;
; RETURNS Z FLAG TRUE IF OPERATION COMPLETED SUCCESSFULLY,
; ELSE RETURNS Z FLAG FALSE AND ERROR CODE IN D0.
; DESTROYS D0, PRESERVES ALL OTHER REGISTERS.
; NOTE:  TRIGGERS A COMPLETE SCSI BUS SEQUENCE.
;
;
PARK_THE_HEADS
               TST.B   VALID_HD_DESCR       ;CAN WE FIGURE OUT HOW BIG THE DRIVE IS, WHERE TO PARK?
               BEQ.S   PRK_HDS_EXIT         ;BRANCH IF NO - FORGET IT.
               cmpi.w  #std_ccs,HD_DRIVE_TYPE    ; got a "standard" SCSI drive?
               beq.s   PRK_HDS_EXIT              ; exit if yes - no parking.
;
               MOVEM.L D1/A1,-(A7)
               BSR     SELECT_DEVICE        ;TRY TO GET A RISE OUT OF SELECTED TARGET DEVICE.
               BNE.S   PRK_HDS_Z0           ;BRANCH IF SELECTION ATTEMPT FAILED, RETURN ERROR CODE.
;16APR               MOVE.L  #0A8ACH,D0                ;TARGET RESPONDED - SET UP SEEK COMMAND (SEEK TO
;16APR               CMP     #DF40_3103,HD_DRIVE_TYPE  ;LOGICAL BLOCK ADDRESS WHICH IMPLIES CYL 635).
               MOVE.L  #0A35CH,D0                ;TARGET RESPONDED - SET UP SEEK COMMAND (SEEK TO
               CMP     #DF40_3103,HD_DRIVE_TYPE  ;LOGICAL BLOCK ADDRESS WHICH IMPLIES CYL 615).
               BEQ.S   PRK_HDS_20                ;FOR 40MEG DRIVE, MUST DOUBLE THE ADDRESS IN ORDER
               CMP     #DF40_3105,HD_DRIVE_TYPE  ;TO GET AT SAME CYLINDER (635).
               BNE.S   PRK_HDS_40
PRK_HDS_20
               ADD.L   D0,D0
PRK_HDS_40
               MOVE.L  D0,SCSI_CMD_BUF      ;STORE TARGET LOGICAL BLOCK ADDRESS IN COMMAND BUFFER,
               MOVE.B  #0BH,SCSI_CMD_BUF    ;IMPLANT OPERATION CODE FOR SEEK OPERATION.
               CLR     SCSI_CMD_BUF+4       ;MAKE IT REST OF THE WAY OKAY.
               BSR     SIX_BYTE_CMD         ;ISSUE THE SEEK COMMAND TO TARGET.
               BNE.S   PRK_HDS_Z0           ;BRANCH IF COMMAND NOT ISSUED SUCCESSFULLY.
               BSR     FINISH_SCSI_SEQ      ;GET COMPLETION STATUS, RETURN THROUGH WITH RESULTS.
;
PRK_HDS_Z0
               MOVEM.L (A7)+,D1/A1
PRK_HDS_EXIT
               RTS
;
;AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
               SKIP
;921008-11:04am;VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV
;921008-11:04am;
;921008-11:04am; READ CONTENTS OF DATAFRAME DATA BUFFER -
;921008-11:04am; COMMAND APPLICABLE ONLY TO SUPERMAC DATAFRAME DRIVES.
;921008-11:04am;
;921008-11:04am; FOLLOWING POWER-ON OR BUS RESET, BUFFER CONTAINS INFO DESCRIBING
;921008-11:04am; INTERNAL CONTROLLER - MOST IMPORTANTLY, THE MODEL NUMBER.
;921008-11:04am; WE DON'T DO RESET HERE, BUT WE DO ASSUME THAT RESET HAS BEEN ISSUED
;921008-11:04am; AND THAT NO OTHER COMMAND HAS SINCE BEEN ISSUED TO THE CURRENT DRIVE -
;921008-11:04am; IF THIS IS NOT THE CASE, DATA BUFFER CONTAINS RANDOM GA-BARGE, SO ....
;921008-11:04am;
;921008-11:04am; FOR NOW:
;921008-11:04am; WE READ ALL DATA (512 BYTES, PER BLOCK SIZE FOR THESE DRIVES) INTO
;921008-11:04am; WASTELAND, THEN PICK OUT WHAT WE NEED.
;921008-11:04am; WE CARE ONLY ABOUT BYTES 2-3 (FROM 0), WHICH ARE THE "yy" IN THE
;921008-11:04am; "31yy" CONTROLLER MODEL ID STRING - 3100/3103/3105.
;921008-11:04am; WE READ ONLY THESE TWO CHARACTERS INTO CUR_OMTI_REV(.W).
;921008-11:04am;
;921008-11:04am; LATER:
;921008-11:04am; SOUGHT-AFTER CHARACTERS ARE READ DIRECTLY INTO DESTINATION VARIABLE,
;921008-11:04am; ALL OTHER BYTES ARE IGNORED.
;921008-11:04am;
;921008-11:04am; WE GO AFTER THE DEVICE INDICATED BY THE CURRENT VALUE OF DRIVE_SEL.
;921008-11:04am; RETURNS Z FLAG TRUE IF BUFFER DATA IS SUCCESSFULLY READ,
;921008-11:04am; ELSE RETURNS Z FLAG FALSE AND ERROR CODE IN D0.
;921008-11:04am; NOTE:  TRIGGERS A COMPLETE SCSI SEQUENCE.
;921008-11:04am;
;921008-11:04am; Note that this routine is called as part of configuration loop in
;921008-11:04am; SCSI_MULTIPLE_CONF, and therefore may issue read-data-buffer command
;921008-11:04am; to non-Dataframe drives which do not recognize this command -
;921008-11:04am; also, this occurs (in this case) as the first command following bus reset,
;921008-11:04am; at which point many non-Dataframe drives respond to any command
;921008-11:04am; with a Unit Attention condition.
;921008-11:04am; Either way, the result is that data-in phase is bypassed by the
;921008-11:04am; non-Dataframe drive, and the drive goes directly into status phase.
;921008-11:04am; The procedure here has been modified to respond to a WRONG_PHASE error
;921008-11:04am; following command phase by proceeding to read status and message bytes,
;921008-11:04am; so that the device in question is not left hanging -
;921008-11:04am; the FINISH_SCSI_SEQ procedure will cause us to correctly return
;921008-11:04am; an error code indicating Check Condition status returned by the drive,
;921008-11:04am; which is interpreted by the configuration procedure as indicating
;921008-11:04am; that the drive is not a Dataframe and doesn't need Dataframe configuring.
;921008-11:04am; Our assumptions locally are that the above-mentioned WRONG_PHASE error
;921008-11:04am; will not occur with a properly-functioning Dataframe, and will be
;921008-11:04am; precisely the error which occurs with a properly-functioning non-Dataframe.
;921008-11:04am;
;921008-11:04am; DESTRAUIZE D0, PRESERVES OTHEREGISTERS.
;921008-11:04am;
;921008-11:04am;
;921008-11:04amREAD_DATA_BUFFER
;921008-11:04am               MOVEM.L D1-D3/A0,-(A7)
;921008-11:04am               CLR     CUR_OMTI_REV         ;HEH HEH HEH HEH HEH HEH HEH, WIPEOUT.
;921008-11:04am               BSR     SELECT_DEVICE        ;TRY TO SELECT TARGET DEVICE.
;921008-11:04am               BNE.S   RD_DATBUF_Z0         ;EXIT IF SELECTION UNSUCCESSFUL.
;921008-11:04am;
;921008-11:04am                                            ;TARGET RESPONDED TO SELECTION -
;921008-11:04am               CLR.L   SCSI_CMD_BUF         ;SET UP COMMAND DESCRIPTOR BLOCK.
;921008-11:04am               CLR     SCSI_CMD_BUF+4
;921008-11:04am               MOVE.B  #0ECH,SCSI_CMD_BUF
;921008-11:04am               BSR     SIX_BYTE_CMD         ;ISSUE READ-DATA-BUFFER COMMAND TO TARGET.
;921008-11:04am               BNE.S   RD_DATBUF_Z0         ;EXIT IF COMMAND NOT ISSUED SUCCESSFULLY.
;921008-11:04am;
;921008-11:04am                                            ;SET UP TO READ 512 DATA BYTES INTO WASTELAND:
;921008-11:04am               MOVEQ   #DAT_IN_PHASE,D0     ;WE'RE EXPECTING DATA-IN PHASE FOR THIS.
;921008-11:04am               CLR     D1                   ;SKIP NONE OF THE INCOMING DATA.
;921008-11:04am               MOVE.L  #512,D2              ;READ 512 DATA BYTES.
;921008-11:04am               CLR     D3                   ;NO EXCESS BYTES TO DISCARD.
;921008-11:04am               MOVE    #WASTELAND,A0        ;PUT DATA BYTES INTO WASTELAND.
;921008-11:04am               BSR     SCSI_RAM_READ        ;GET DEM BYTE.
;921008-11:04am;900425               BNE.S   RD_DATBUF_Z0         ;EXIT IF DATA READ WAS UNSUCCESSFUL.
;921008-11:04am               beq.s   RD_DATBUF_80         ; branch if data read successful.
;921008-11:04am               cmpi.b  #WRONG_PHASE,d0      ; else - change to unexpected phase?
;921008-11:04am               bne.s   RD_DATBUF_Z0         ; exit if not - error cause unknown.
;921008-11:04am                                            ; else, assume non-Dataframe drive -
;921008-11:04amRD_DATBUF_80
;921008-11:04am               BSR     FINISH_SCSI_SEQ      ;GET/INSPECT COMPLETION STATUS -
;921008-11:04am               BNE.S   RD_DATBUF_Z0         ;EXIT IF BAD COMPLETION STATUS.
;921008-11:04am               MOVE    WASTELAND+2,CUR_OMTI_REV  ;COOL - COPY CONTROLLER MODEL ID CHARACTERS,
;921008-11:04am               CLR     D0                        ;EXIT WITH NO-ERROR STATUS.
;921008-11:04am;
;921008-11:04amRD_DATBUF_Z0
;921008-11:04am               MOVEM.L (A7)+,D1-D3/A0
;921008-11:04amRD_DATBUF_EXIT
;921008-11:04am               RTS
;921008-11:04am;
;921008-11:04am;AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA


















;VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV
;
; READ CONTENTS OF DATAFRAME DATA BUFFER -
; COMMAND APPLICABLE ONLY TO SUPERMAC DATAFRAME DRIVES.
;
; FOLLOWING POWER-ON OR BUS RESET, BUFFER CONTAINS INFO DESCRIBING
; INTERNAL CONTROLLER - MOST IMPORTANTLY, THE MODEL NUMBER.
; WE DON'T DO RESET HERE, BUT WE DO ASSUME THAT RESET HAS BEEN ISSUED
; AND THAT NO OTHER COMMAND HAS SINCE BEEN ISSUED TO THE CURRENT DRIVE -
; IF THIS IS NOT THE CASE, DATA BUFFER CONTAINS RANDOM GA-BARGE, SO ....
;
; FOR NOW:
; WE READ ALL DATA (512 BYTES, PER BLOCK SIZE FOR THESE DRIVES) INTO
; WASTELAND, THEN PICK OUT WHAT WE NEED.
; WE CARE ONLY ABOUT BYTES 2-3 (FROM 0), WHICH ARE THE "yy" IN THE
; "31yy" CONTROLLER MODEL ID STRING - 3100/3103/3105.
; WE READ ONLY THESE TWO CHARACTERS INTO CUR_OMTI_REV(.W).
;
; LATER:
; SOUGHT-AFTER CHARACTERS ARE READ DIRECTLY INTO DESTINATION VARIABLE,
; ALL OTHER BYTES ARE IGNORED.
;
; WE GO AFTER THE DEVICE INDICATED BY THE CURRENT VALUE OF DRIVE_SEL.
; RETURNS Z FLAG TRUE IF BUFFER DATA IS SUCCESSFULLY READ,
; ELSE RETURNS Z FLAG FALSE AND ERROR CODE IN D0.
; NOTE:  TRIGGERS A COMPLETE SCSI SEQUENCE.
;
; this stuff is from mid-1990:
; Note that this routine is called as part of configuration loop in
; SCSI_MULTIPLE_CONF, and therefore may issue read-data-buffer command
; to non-Dataframe drives which do not recognize this command -
; also, this occurs (in this case) as the first command following bus reset,
; at which point many non-Dataframe drives respond to any command
; with a Unit Attention condition.
; Either way, the result is that data-in phase is bypassed by the
; non-Dataframe drive, and the drive goes directly into status phase.
; The procedure here has been modified to respond to a WRONG_PHASE error
; following command phase by proceeding to read status and message bytes,
; so that the device in question is not left hanging -
; the FINISH_SCSI_SEQ procedure will cause us to correctly return
; an error code indicating Check Condition status returned by the drive,
; which is interpreted by the configuration procedure as indicating
; that the drive is not a Dataframe and doesn't need Dataframe configuring.
; Our assumptions locally are that the above-mentioned WRONG_PHASE error
; will not occur with a properly-functioning Dataframe, and will be
; precisely the error which occurs with a properly-functioning non-Dataframe.
;
; 921008-11:05am
; that last assumption turns out to be incorrect, at least with the 
; syquest drive i'm using these days - maybe chris meyer's old one was
; different.  what's happening now is that the syquest wants more than six 
; command bytes when it sees the read_data_buffer command code, and so is
; still stuck in command phase after only six command bytes have gone out.
; the stuck_phase error which arises is not handled correctly here,
; and the syquest is left hanging.  we fix this now by adding a special 
; loop which is activated by a stuck_phase error, and spoon-feeds additional
; zero command bytes one at a time to the target until a phase change is 
; detected in the form of a wrong_phase error relative to command phase.
; at this time we go back into assumption mode and pick up where we left off
; two years ago.
;
; DESTRAUIZE D0, PRESERVES OTHEREGISTERS.
;
;
READ_DATA_BUFFER
;921008-11:25am               MOVEM.L D1-D3/A0,-(A7)
               movem.l d1-d4/a0,-(a7)
               CLR     CUR_OMTI_REV         ;HEH HEH HEH HEH HEH HEH HEH, WIPEOUT.
               BSR     SELECT_DEVICE        ;TRY TO SELECT TARGET DEVICE.
               BNE.S   RD_DATBUF_Z0         ;EXIT IF SELECTION UNSUCCESSFUL.
;
                                            ;TARGET RESPONDED TO SELECTION -
               CLR.L   SCSI_CMD_BUF         ;SET UP COMMAND DESCRIPTOR BLOCK.
               CLR     SCSI_CMD_BUF+4
               MOVE.B  #0ECH,SCSI_CMD_BUF
               BSR     SIX_BYTE_CMD         ;ISSUE READ-DATA-BUFFER COMMAND TO TARGET.
               BNE.S   RD_DATBUF_Z0         ;EXIT IF COMMAND NOT ISSUED SUCCESSFULLY.
;
                                            ;SET UP TO READ 512 DATA BYTES INTO WASTELAND:
               MOVEQ   #DAT_IN_PHASE,D0     ;WE'RE EXPECTING DATA-IN PHASE FOR THIS.
               CLR     D1                   ;SKIP NONE OF THE INCOMING DATA.
               MOVE.L  #512,D2              ;READ 512 DATA BYTES.
               CLR     D3                   ;NO EXCESS BYTES TO DISCARD.
               MOVE    #WASTELAND,A0        ;PUT DATA BYTES INTO WASTELAND.
               BSR     SCSI_RAM_READ        ;GET DEM BYTE.
;900425               BNE.S   RD_DATBUF_Z0         ;EXIT IF DATA READ WAS UNSUCCESSFUL.
               beq.s   RD_DATBUF_80         ; branch if data read successful.
;921008-11:16am               cmpi.b  #WRONG_PHASE,d0      ; else - change to unexpected phase?
;921008-11:16am               bne.s   RD_DATBUF_Z0         ; exit if not - error cause unknown.
;921008-11:16am                                            ; else, assume non-Dataframe drive -
               cmpi.b  #WRONG_PHASE,d0      ; else - change to unexpected phase?
               beq.s   RD_DATBUF_80         ; branch if yes - assume a non-
							; dataframe drive ready to respond
							; to an illegal request.
               cmpi.b  #STUCK_PHASE,d0      ; else - still in command phase?
               bne.s   RD_DATBUF_Z0         ; exit if not - error cause unknown.
;
                                            ; else, assume non-Dataframe drive  
							; not yet done accepting command
							; string for an illegal request:
		moveq	#6,d4				; send up to 7 more cmd bytes.
rd_datbuf_44
		bsr	filler_command_byte	; feed it one more 00 command byte.
		dbne	d4,rd_datbuf_44		; if it took that one, give it
							; another, unless limit reached.
               cmpi.b  #WRONG_PHASE,d0      ; change to new phase, finally?
               bne.s   RD_DATBUF_Z0         ; exit if not - error cause unknown.
                                            ; else, assume a non-Dataframe drive 
							; now ready to respond to an illegal 
							; request ....
;
RD_DATBUF_80
               BSR     FINISH_SCSI_SEQ      ;GET/INSPECT COMPLETION STATUS -
               BNE.S   RD_DATBUF_Z0         ;EXIT IF BAD COMPLETION STATUS.
               MOVE    WASTELAND+2,CUR_OMTI_REV  ;COOL - COPY CONTROLLER MODEL ID CHARACTERS,
               CLR     D0                        ;EXIT WITH NO-ERROR STATUS.
;
RD_DATBUF_Z0
;921008-11:26am               MOVEM.L (A7)+,D1-D3/A0
               movem.l (a7)+,d1-d4/a0
RD_DATBUF_EXIT
               RTS
;
;AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA


















;900424;VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV
;900424;
;900424; INITIALIZE DIRECTORIES ON SCSI HARD DISK INDICATED BY DRIVE_SEL -
;900424; NO ACTUAL FORMATTING IS PERFORMED.
;900424; ASSUMES DATAFRAME DRIVE, PARTICULARLY WITH RESPECT TO AUTOMATIC STEPS
;900424; TO ASCERTAIN CONTROLLER TYPE AND THEN SET HD_DRIVE_TYPE, AS WELL AS
;900424; (POSSIBLY) WRITING DRIVE SPECS ONTO TRACK 000 FOR CONTROLLER'S FUTURE
;900424; REFERENCE.
;900424;
;900424INIT_SCSI_DIR
;900424               MOVE.L  #DISCON_OTHER_SCRN,D0     ;GIVE THE USER SOME GOOD PROCEDURAL ADVICE.
;900424               BSR     ALT_QUERY
;900424               BCS     ISD_EXIT                  ;EXIT IF HE DON'T LIKE OUR ADVICE.
;900424;
;900424               MOVE.L  #ISD_WARNING_SCRN,D0      ;NOW GIVE HIM SOMETHING HEAVY TO THINK ABOUT.
;900424               BSR     ALT_QUERY
;900424               BCS     ISD_EXIT                  ;EXIT IF WE INTIMIDATED HIM OUT OF IT.
;900424;
;900424               MOVE.L  #LAST_CHANCE_SCRN,D0      ;SO HE WANNA PLAY?  LET HIM KNOW THE SCORE.
;900424               BSR     ALT_QUERY
;900424               BCS     ISD_EXIT                  ;EXIT IF WE SUCCESSFULLY PREYED UPON INSECURITY.
;900424;
;900424                                            ;OKAY, THEN:
;900424;
;900424               BSR     RESET_SCSI           ;FLATTEN THE SCSI BUS - FOR DATAFRAME DRIVES, THIS ALSO
;900424                                            ;CAUSES CONTROLLER ID INFO TO BE COPIED INTO DRIVE
;900424                                            ;INTERNAL DATA BUFFERS.
;900424;
;900424               MOVEQ   #8,D0                ;SET TIMEOUT FOR RECALIBRATION DELAY - SINCE AT THIS
;900424                                            ;POINT THE HEADS SHOULD BE HOVERING OVER TRACK 032
;900424                                            ;WHICH IS CYLINDER 4 OR 8, THIS TWO-SECOND TIMEOUT
;900424                                            ;SHOULD BE QUITE A-PLENTY.
;900424               BSR     PUT_BANK_SEL         ;USE THIS CHANNEL'S BANK_SEL AS TEMP STORAGE FOR TIMER.
;900424ISD_08
;900424               BSR     READ_DATA_BUFFER     ;OBTAIN CONTROLLER TYPE, IF ANY - SET CUR_OMTI_REV.
;900424               BEQ.S   ISD_0E               ;BRANCH IF WE DIDIT - CONFIGGER THE DARN THING.
;900424               CMP.B   #SELECT_FAILED,D0    ;WE DIDN'T - WAS ANYTHING OUT THERE?
;900424               BNE     ISD_Z0               ;BRANCH IF YES - THIS MEANS TROUBLE, LET'S BOOGIE.
;900424               BSR     GET_BANK_SEL         ;NO RESPONSE YET, HOW'S THE TIMEOUT COMING?
;900424               SUBQ    #1,D0
;900424               BEQ.S   ISD_0C               ;IT'S GONE - LET'S JUST FORGET IT, OK?
;900424               BSR     PUT_BANK_SEL         ;STILL TIME LEFT - SAVE NEW TIMEOUT COUNTER VALUE,
;900424               BRA     ISD_08               ;TRY AGAIN TO GET DRIVE'S ATTENTION.
;900424ISD_0C
;900424               MOVEQ   #SELECT_FAILED,D0
;900424               BRA     ISD_Z0
;900424;
;900424ISD_0E
;900424               BSR     CONFIG_DATAFRAME     ;ENSURE ACCESS TO FULL DATA CAPACITY, ET CETERA.
;900424               BNE     ISD_Z0               ;EXIT IF ERROR DURING CONFIGURE OPERATION.
;900424;
;900424;16APR               MOVEQ   #26,D0               ;ASSUME 20 MEG DRIVE, 26 BANK CAPACITY -
;900424               MOVEQ   #25,D0               ;ASSUME 20 MEG DRIVE, 25 BANK CAPACITY -
;900424               MOVEQ   #DF20_3100,D1        ;ALSO ASSUME DATAFRAME 20 WITH OMTI 3100 CONTROLLER.
;900424               MOVE    CUR_OMTI_REV,D2      ;FETCH CONTROLLER MODEL ID STRING FOR TESTING.
;900424               TST     NEW_DRIVE_SIZE       ;SEE HOW BIG A DRIVE WE ARE DIRECTORY-FYING.
;900424               BNE.S   ISD_10               ;BRANCH IF NOT 20 MEG, GO CHANGE OUR STYLE.
;900424               CMP     #3030H,D2            ;3100 CONTROLLER?
;900424               BEQ.S   ISD_1C               ;YOU BETCHA, DRIVE_TYPE VALUE IN D1 IST KOOLE.
;900424               MOVEQ   #DF20_3103,D1        ;NOT 3100, HOW AOUT 3103?
;900424               CMP     #3033H,D2
;900424               BEQ.S   ISD_1C               ;THASS RIGHT, GIT GO.
;900424               MOVEQ   #DF20_3105,D1        ;ONLY ONE LEFT IS 3105, SO OFF WE GOES.
;900424               BRA.S   ISD_1C
;900424ISD_10
;900424;
;900424;16APR               MOVEQ   #53,D0               ;SET UP FOR 40 MEG, 53-BANK DIRECTORY.
;900424               MOVEQ   #51,D0               ;SET UP FOR 40 MEG, 51-BANK DIRECTORY.
;900424               MOVEQ   #DF40_3103,D1        ;ASSUME 3103 CONTROLLER, SEE WHAT'S WHAT.
;900424               CMP     #3033H,D2            ;TEST CONTROLLER MODEL ID STRING.
;900424               BEQ.S   ISD_1C               ;BRANCH IF IT IS A 3103, WE'RE SET.
;900424               MOVEQ   #DF40_3105,D1        ;ELSE, 3105 IS ONLY OTHER POSSIBILITY.
;900424ISD_1C
;900424               MOVE    D0,HD_CAPACITY       ;STORE BANK-CAPACITY AND DRIVE TYPE VALUES -
;900424               MOVE    D1,HD_DRIVE_TYPE     ;THESE WILL GO INTO MAIN DISK DESCRIPTOR.
;900424;
;900424               MOVE.L  #INIT_DIR_SCRN,A1    ;TELL 'EM WHAT WE'RE UP TO NOW.
;900424                ABS_LONG
;900424               JSR     DISP_SCREEN
;900424                ABS_SHORT
;900424               MOVE    #BANK_DESCR_BUF,A0   ;SET UP BANK DESCRIPTOR TEMPLATE.
;900424                ABS_LONG
;900424               MOVE.L  EMPTYBANK_STRING,(A0)+    ;DEFAULT BANK NAME.
;900424               MOVE.L  EMPTYBANK_STRING+4,(A0)+
;900424                ABS_SHORT
;900424               CLR     (A0)+                ;INITIALIZE BANK WRITE-PROTECT SWITCH TO "UNPROTECTED".
;900424               MOVE    #-1,(A0)+            ;INITIALIZE BANK TYPE TO "NULL".
;900424               MOVEQ   #15,D0               ;INITIALIZE ALL FILE STATUS FLAGS TO "DELETED".
;900424ISD_20
;900424               MOVE    #DELETED,(A0)+
;900424               DBRA    D0,ISD_20
;900424;
;900424               CLR     D0                   ;RESET BANK COUNTER.
;900424               BSR     PUT_BANK_SEL
;900424ISD_40
;900424               MOVE    #SAVE_MASK,D0        ;SET CONTROL CODE FOR WRITE TO DISK.
;900424               BSR     BANK_DESCR_MOVE      ;WRITE DESCRIPTOR FOR CURRENT BANK.
;900424               BNE.S   ISD_Z0               ;EXIT IF WRITE WAS NOT SUCCESSFUL.
;900424               BSR     GET_BANK_SEL         ;STEP TO NEXT BANK -
;900424               ADDQ    #1,D0
;900424               CMP     HD_CAPACITY,D0       ;ARE WE DONE?
;900424               BCC.S   ISD_80               ;BRANCH IF YES, GO WRITE MAIN DISK DESCRIPTOR.
;900424               BSR     PUT_BANK_SEL         ;ELSE - SAVE NEW BANK NUMBER,
;900424               ADDQ    #1,D0                ;MAKE IT 1-RELATIVE FOR APPEARANCES' SAKE,
;900424                ABS_LONG
;900424               JSR     WORD_BIN_TO_BCD      ;MAKE AN ASCII STRING OUT OF IT,
;900424                ABS_SHORT
;900424               MOVE.B  BCD_DIGITS+5,BANK_DESCR_BUF+5  ;COPY THREE ASCII BCD DIGITS INTO DESCR BUF.
;900424               MOVE    BCD_DIGITS+6,BANK_DESCR_BUF+6
;900424               BRA     ISD_40                         ;LOOP AGAIN, WRITE NEXT BANK DESCRIPTOR.
;900424;
;900424ISD_80
;900424               CLR     D0                   ;DONE WITH BANK DESCRIPTORS - LEAVE 'EM AT BANK 0.
;900424               BSR     PUT_BANK_SEL
;900424;
;900424               MOVE    #HD_DESCR_BUF,A0          ;SET UP MAIN DISK DESCRIPTOR:
;900424               MOVE.L  #HD_CORP_ID_STRING,A1     ;START WITH SEQUENTIAL MODEL 440 ID STUFF AND
;900424               MOVEQ   #15,D0                    ;DISK SYSTEM REVISION CODE.
;900424ISD_90
;900424               MOVE.B  (A1)+,(A0)+
;900424               DBRA    D0,ISD_90
;900424;
;900424                                            ;HD_DRIVE_TYPE AND HD_CAPACITY ARE ALREADY SET.
;900424;
;900424               MOVE    #SAVE_MASK,D0        ;SET CONTROL CODE FOR WRITE TO DISK.
;900424               BSR     DISK_DESCR_MOVE      ;WRITE MAIN DISK DESCRIPTOR.
;900424               BNE.S   ISD_Z0               ;EXIT IF SOME BAD NEWS, BUM-OUT OR OTHER MIS-HAP.
;900424;
;900424               CMP     #DF20_3100,HD_DRIVE_TYPE  ;SO - WAS THIS A DATAFRAME20 WITH 3100 CONTROLLER?
;900424               BEQ.S   ISD_EXIT                  ;EXIT IF YES, NOTHING MORE TO DO HERE.
;900424;
;900424                                                 ;ELSE, MUST WRITE NEW SPECIFIERS TO DRIVE (ESP. AS
;900424                                                 ;REGARDS MAXIMUM CYLINDER ADDRESS, SO WE CAN DO
;900424                                                 ;HEAD PARKING WITHOUT SPURIOUS ERRORS:
;900424               MOVE    DRIVE_SEL,NEW_SCSI_ID     ;DON'T CHANGE DRIVE SCSI ID IN THE PROCESS!
;900424               BSR     SEND_SPECIFIERS           ;DO THE THING, PASS RETURN STATUS THROUGH.
;900424;
;900424ISD_Z0
;900424                                            ;UNSTACK REGISTERS?
;900424ISD_EXIT
;900424               RTS
;900424;
;900424;
;900424DISCON_OTHER_SCRN
;900424               ASC     " DISCONNECT ALL "
;900424               ASC     "OTHER SCSI DISKS"
;900424;
;900424ISD_WARNING_SCRN
;900424               ASC     "ALL DATA ON DISK"
;900424               ASC     " WILL BE LOST!! "
;900424;
;900424LAST_CHANCE_SCRN
;900424               ASC     " LAST CHANCE TO "
;900424               ASC     " BAIL OUT ....! "
;900424;
;900424;
;900424EMPTYBANK_STRING
;900424               ASC     "empty001"
;900424;
;900424;
;900424HD_CORP_ID_STRING
;900424               ASC     "SEQUENTIAL0440"     ;COMPANY NAME, MODEL NUMBER (HD_MODEL_ID).
;900424               DC.W    REV_1                ;HD_FIRMWR_REV (ACTUALLY, DISK FORMAT CODE).
;900424;
;900424;AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA


















;VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV
;
; INITIALIZE DIRECTORIES ON SCSI HARD DISK INDICATED BY DRIVE_SEL -
; NO ACTUAL FORMATTING IS PERFORMED.
;
; If value of new_drive_type.w = 0, user is indicating that a "standard"
; SCSI drive is to be initialized.
; We attempt to read the capacity from the drive itself and
; set HD_CAPACITY accordingly - HD_DRIVE_TYPE is set to #std_ccs.
;
; Otherwise, user is indicating some type of Dataframe 20 or 40 -
; (no, we still can't handle any other type of Dataframe).
; We take necessary steps to ascertain the type of controller it has,
; and set HD_DRIVE_TYPE based on this info - for these drives,
; HD_CAPACITY is implied by the drive type indicated by the user.
;
; Following this, empty banks and the main disk descriptor are created.
;
; For Dataframes only -
; Depending upon the type of controller which is found in the drive,
; we may also write some drive specs onto track 000 of the drive
; for use by the drive's controller during its own power-up initialization
; (ie, if it is one of those that obtains drive parameters from the drive).
; If this is done, it happens after all other initialization is complete.
;
;
INIT_SCSI_DIR
               MOVE.L  #DISCON_OTHER_SCRN,D0     ;GIVE THE USER SOME GOOD PROCEDURAL ADVICE.
               BSR     ALT_QUERY
               BCS     ISD_EXIT                  ;EXIT IF HE DON'T LIKE OUR ADVICE.
;
               MOVE.L  #ISD_WARNING_SCRN,D0      ;NOW GIVE HIM SOMETHING HEAVY TO THINK ABOUT.
               BSR     ALT_QUERY
               BCS     ISD_EXIT                  ;EXIT IF WE INTIMIDATED HIM OUT OF IT.
;
               MOVE.L  #LAST_CHANCE_SCRN,D0      ;SO HE WANNA PLAY?  LET HIM KNOW THE SCORE.
               BSR     ALT_QUERY
               BCS     ISD_EXIT                  ;EXIT IF WE SUCCESSFULLY PREYED UPON INSECURITY.
;
                                            ;OKAY, THEN:
               tst.w   new_drive_type       ; initializing a "standard" drive?
               bne.s   ISD_04               ; branch if not, do up a Dataframe.
;
                                            ; "standard" CCS drive init:
               bsr     read_capacity        ; ask it how big it is -
               bne     ISD_Z0               ; exit if it wouldn't tell us.
                                            ; else, d1.l is number of logical
                                            ; records on drive, minus one -
               subi.l  #DF_BASE_REC-1,d1    ; remove capacity corresponding to
                                            ; Dataframe No Man's Land, less one.
               divu    #1559,d1             ; divide by number of records per
                                            ; storage bank -
               move.w  d1,d0                ; use integer portion of result
                                            ; as drive capacity (banks).
               moveq   #std_ccs,d1          ; indicate "standard" drive type.
               bra.s   ISD_60               ; go do some initialization.
;
;
                                            ; all of this stuff, we do only for
                                            ; Dataframe drives:
ISD_04
               BSR     RESET_SCSI           ;FLATTEN THE SCSI BUS - FOR DATAFRAME DRIVES, THIS ALSO
                                            ;CAUSES CONTROLLER ID INFO TO BE COPIED INTO DRIVE
                                            ;INTERNAL DATA BUFFERS.
;
               MOVEQ   #8,D0                ;SET TIMEOUT FOR RECALIBRATION DELAY - SINCE AT THIS
                                            ;POINT THE HEADS SHOULD BE HOVERING OVER TRACK 032
                                            ;WHICH IS CYLINDER 4 OR 8, THIS TWO-SECOND TIMEOUT
                                            ;SHOULD BE QUITE A-PLENTY.
               BSR     PUT_BANK_SEL         ;USE THIS CHANNEL'S BANK_SEL AS TEMP STORAGE FOR TIMER.
ISD_08
               BSR     READ_DATA_BUFFER     ;OBTAIN CONTROLLER TYPE, IF ANY - SET CUR_OMTI_REV.
               BEQ.S   ISD_0E               ;BRANCH IF WE DIDIT - CONFIGGER THE DARN THING.
               CMP.B   #SELECT_FAILED,D0    ;WE DIDN'T - WAS ANYTHING OUT THERE?
               BNE     ISD_Z0               ;BRANCH IF YES - THIS MEANS TROUBLE, LET'S BOOGIE.
               BSR     GET_BANK_SEL         ;NO RESPONSE YET, HOW'S THE TIMEOUT COMING?
               SUBQ    #1,D0
               BEQ.S   ISD_0C               ;IT'S GONE - LET'S JUST FORGET IT, OK?
               BSR     PUT_BANK_SEL         ;STILL TIME LEFT - SAVE NEW TIMEOUT COUNTER VALUE,
               BRA     ISD_08               ;TRY AGAIN TO GET DRIVE'S ATTENTION.
ISD_0C
               MOVEQ   #SELECT_FAILED,D0
               BRA     ISD_Z0
;
ISD_0E
               BSR     CONFIG_DATAFRAME     ;ENSURE ACCESS TO FULL DATA CAPACITY, ET CETERA.
               BNE     ISD_Z0               ;EXIT IF ERROR DURING CONFIGURE OPERATION.
;
;16APR               MOVEQ   #26,D0               ;ASSUME 20 MEG DRIVE, 26 BANK CAPACITY -
               MOVEQ   #25,D0               ;ASSUME 20 MEG DRIVE, 25 BANK CAPACITY -
               MOVEQ   #DF20_3100,D1        ;ALSO ASSUME DATAFRAME 20 WITH OMTI 3100 CONTROLLER.
               MOVE    CUR_OMTI_REV,D2      ;FETCH CONTROLLER MODEL ID STRING FOR TESTING.
;900424               TST     NEW_DRIVE_SIZE       ;SEE HOW BIG A DRIVE WE ARE DIRECTORY-FYING.
               cmp.w   #1,new_drive_type    ; Dataframe 20 or Dataframe 40?
               BNE.S   ISD_10               ;BRANCH IF NOT 20 MEG, GO CHANGE OUR STYLE.
               CMP     #3030H,D2            ;3100 CONTROLLER?
               BEQ.S   ISD_1C               ;YOU BETCHA, DRIVE_TYPE VALUE IN D1 IST KOOLE.
               MOVEQ   #DF20_3103,D1        ;NOT 3100, HOW AOUT 3103?
               CMP     #3033H,D2
               BEQ.S   ISD_1C               ;THASS RIGHT, GIT GO.
               MOVEQ   #DF20_3105,D1        ;ONLY ONE LEFT IS 3105, SO OFF WE GOES.
               BRA.S   ISD_1C
ISD_10
;
;16APR               MOVEQ   #53,D0               ;SET UP FOR 40 MEG, 53-BANK DIRECTORY.
               MOVEQ   #51,D0               ;SET UP FOR 40 MEG, 51-BANK DIRECTORY.
               MOVEQ   #DF40_3103,D1        ;ASSUME 3103 CONTROLLER, SEE WHAT'S WHAT.
               CMP     #3033H,D2            ;TEST CONTROLLER MODEL ID STRING.
               BEQ.S   ISD_1C               ;BRANCH IF IT IS A 3103, WE'RE SET.
               MOVEQ   #DF40_3105,D1        ;ELSE, 3105 IS ONLY OTHER POSSIBILITY.
ISD_1C
;
;
ISD_60
               MOVE    D0,HD_CAPACITY       ;STORE BANK-CAPACITY AND DRIVE TYPE VALUES -
               MOVE    D1,HD_DRIVE_TYPE     ;THESE WILL GO INTO MAIN DISK DESCRIPTOR.
;
               MOVE.L  #INIT_DIR_SCRN,A1    ;TELL 'EM WHAT WE'RE UP TO NOW.
;900424                ABS_LONG
;900424               JSR     DISP_SCREEN
;900424                ABS_SHORT
               CALL    LCD_FUNS,DSP_SCRN
               MOVE    #BANK_DESCR_BUF,A0   ;SET UP BANK DESCRIPTOR TEMPLATE.
;900424                ABS_LONG
;900424               MOVE.L  EMPTYBANK_STRING,(A0)+    ;DEFAULT BANK NAME.
;900424               MOVE.L  EMPTYBANK_STRING+4,(A0)+
;900424                ABS_SHORT
               MOVE.L  EMPTYBANK_STRING(pc),(A0)+     ;DEFAULT BANK NAME.
               MOVE.L  EMPTYBANK_STRING+4(pc),(A0)+
               CLR     (A0)+                ;INITIALIZE BANK WRITE-PROTECT SWITCH TO "UNPROTECTED".
               MOVE    #-1,(A0)+            ;INITIALIZE BANK TYPE TO "NULL".
               MOVEQ   #15,D0               ;INITIALIZE ALL FILE STATUS FLAGS TO "DELETED".
ISD_64
               MOVE    #DELETED,(A0)+
               DBRA    D0,ISD_64
;
               CLR     D0                   ;RESET BANK COUNTER.
               BSR     PUT_BANK_SEL
ISD_68
               MOVE    #SAVE_MASK,D0        ;SET CONTROL CODE FOR WRITE TO DISK.
               BSR     BANK_DESCR_MOVE      ;WRITE DESCRIPTOR FOR CURRENT BANK.
               BNE.S   ISD_Z0               ;EXIT IF WRITE WAS NOT SUCCESSFUL.
               BSR     GET_BANK_SEL         ;STEP TO NEXT BANK -
               ADDQ    #1,D0
               CMP     HD_CAPACITY,D0       ;ARE WE DONE?
               BCC.S   ISD_80               ;BRANCH IF YES, GO WRITE MAIN DISK DESCRIPTOR.
               BSR     PUT_BANK_SEL         ;ELSE - SAVE NEW BANK NUMBER,
               ADDQ    #1,D0                ;MAKE IT 1-RELATIVE FOR APPEARANCES' SAKE,
;900424                ABS_LONG
;900424               JSR     WORD_BIN_TO_BCD      ;MAKE AN ASCII STRING OUT OF IT,
;900424                ABS_SHORT
               CALL    LCD_FUNS,WRD_BIN_2_BCD
               MOVE.B  BCD_DIGITS+5,BANK_DESCR_BUF+5  ;COPY THREE ASCII BCD DIGITS INTO DESCR BUF.
               MOVE    BCD_DIGITS+6,BANK_DESCR_BUF+6
               BRA     ISD_68                         ;LOOP AGAIN, WRITE NEXT BANK DESCRIPTOR.
;
ISD_80
               CLR     D0                   ;DONE WITH BANK DESCRIPTORS - LEAVE 'EM AT BANK 0.
               BSR     PUT_BANK_SEL
;
               MOVE    #HD_DESCR_BUF,A0          ;SET UP MAIN DISK DESCRIPTOR:
;900425               MOVE.L  #HD_CORP_ID_STRING,A1     ;START WITH SEQUENTIAL MODEL 440 ID STUFF AND
               lea.l   HD_CORP_ID_STRING(pc),A1  ;START WITH SEQUENTIAL MODEL 440 ID STUFF AND
               MOVEQ   #15,D0                    ;DISK SYSTEM REVISION CODE.
ISD_90
               MOVE.B  (A1)+,(A0)+
               DBRA    D0,ISD_90
;
                                            ;HD_DRIVE_TYPE AND HD_CAPACITY ARE ALREADY SET.
;
               MOVE    #SAVE_MASK,D0        ;SET CONTROL CODE FOR WRITE TO DISK.
               BSR     DISK_DESCR_MOVE      ;WRITE MAIN DISK DESCRIPTOR.
               BNE.S   ISD_Z0               ;EXIT IF SOME BAD NEWS, BUM-OUT OR OTHER MIS-HAP.
;
;
                                            ; again, special Dataframe stuff:
;
               cmpi.w  #std_ccs,HD_DRIVE_TYPE    ; "standard" SCSI drive?
               beq.s   ISD_Z0                    ; exit if yes - we're done.
               CMP     #DF20_3100,HD_DRIVE_TYPE  ;SO - WAS THIS A DATAFRAME20 WITH 3100 CONTROLLER?
               BEQ.S   ISD_Z0                    ;EXIT IF YES, NOTHING MORE TO DO HERE.
;
                                                 ;ELSE, MUST WRITE NEW SPECIFIERS TO DRIVE (ESP. AS
                                                 ;REGARDS MAXIMUM CYLINDER ADDRESS, SO WE CAN DO
                                                 ;HEAD PARKING WITHOUT SPURIOUS ERRORS:
               MOVE    DRIVE_SEL,NEW_SCSI_ID     ;DON'T CHANGE DRIVE SCSI ID IN THE PROCESS!
               BSR     SEND_SPECIFIERS           ;DO THE THING, PASS RETURN STATUS THROUGH.
;
ISD_Z0
                                            ;UNSTACK REGISTERS?
ISD_EXIT
               RTS
;
;
DISCON_OTHER_SCRN
               ASC     " DISCONNECT ALL "
               ASC     "OTHER SCSI DISKS"
;
ISD_WARNING_SCRN
               ASC     "ALL DATA ON DISK"
               ASC     " WILL BE LOST!! "
;
LAST_CHANCE_SCRN
               ASC     " LAST CHANCE TO "
               ASC     " BAIL OUT ....! "
;
;
EMPTYBANK_STRING
               ASC     "empty001"
;
;
HD_CORP_ID_STRING
               ASC     "SEQUENTIAL0440"     ;COMPANY NAME, MODEL NUMBER (HD_MODEL_ID).
               DC.W    REV_1                ;HD_FIRMWR_REV (ACTUALLY, DISK FORMAT CODE).
;
;AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA


















;VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV
;
; SET NEW DEVICE ID FOR A DATAFRAME DRIVE -
; APPLIES TO MODELS WITH 3103/3105 CONTROLLERS, WHICH FOR SOME PERVERSE
; REASON REQUIRE SCSI COMMAND SEQUENCE IN ORDER TO EFFECT CHANGE OF ID.
;
; BECAUSE THIS PROCEDURE INVOLVES SENDING SPECIFIER BYTES TO THE DRIVE
; WHICH INCLUDE SPEC FOR NUMBER OF HEADS (RELATED TO DRIVE SIZE), WE
; ALLOW THIS COMMAND ONLY WITH DRIVES WHICH HAVE A VALID SEQUENTIAL-TYPE
; DESCRIPTOR AND DIRECTORY WRITTEN ON THE DISK - THIS WAY, WE CAN FIND
; OUT WHAT THE DRIVE SIZE IS WITHOUT ASKING THE USER TO TELL US (WHICH
; MIGHT SEEM KIND OF STRANGE TO HAVE TO DO, FROM USER'S STANDPOINT).
; That is, command execution only gets here if the disk descriptor
; has already been successfully read.
;
; OLDER DATAFRAME 20 WITH 3100 CONTROLLER HAS JUMPERS WHICH THE USER
; SETS BY HAND TO CHANGE DEVICE ID - IF WE SEE ONE OF THESE, WE TELL THE
; USER TO GO DO IT HIM/HER/ITSELF (by way of error-code return).
;
; Also, if a "standard" SCSI drive (Common Command Set compatible) is detected,
; we issue a similar message and abort (also by way of error code return),
; since standard SCSI devices don't indulge in this sort of stupidity.
;
;
SET_NEW_SCSI_ID
               cmpi.w  #std_ccs,HD_DRIVE_TYPE    ; "standard" SCSI drive?
               beq.s   SNSI_10                   ; br if yes, get outta here.
               CMP     #DF20_3100,HD_DRIVE_TYPE  ;IS THIS ONE OF THEM OLD DOGS?
               BNE.S   SNSI_20                   ;BRAINTCH IF NAUT, OFF WE GO.
SNSI_10
               MOVEQ   #SET_JUMPERS,D0           ;ELSE, TELL USER WHERE TO GO.
               BRA.S   SNSI_EXIT
;
SNSI_20
               MOVE.L  #DISCON_OTHER_SCRN,D0     ;GIVE THE USER SOME GOOD PROCEDURAL ADVICE.
               BSR     ALT_QUERY
               BCS     ISD_EXIT                  ;EXIT IF HE DON'T LIKE OUR ADVICE.
;
;900425               MOVE.L  #CHANGING_ID_SCRN,A1      ;POST THE ALWAYS-NEEDED BUTTON-RESPONSE MESSAGE.
               lea.l   CHANGING_ID_SCRN(pc),A1   ;POST THE ALWAYS-NEEDED BUTTON-RESPONSE MESSAGE.
;900424                ABS_LONG
;900424               JSR     DISP_SCREEN
;900424                ABS_SHORT
               CALL    LCD_FUNS,DSP_SCRN
;
               MOVE    DRIVE_SEL,-(A7)           ;SAVE CURRENT SCSI OPERATING CHANNEL,
               MOVE    NEW_SCSI_ID,DRIVE_SEL     ;SEE IF ANYTHING PRESENT ON DESIRED NEW CHANNEL.
               BSR     REQUEST_SENSE             ;NOMINAL NO-OP SORTA THING ....
               BEQ.S   SNSI_40                   ;IF NO ERROR, SOMETHING THERE - EXIT.
               CMP.B   #SELECT_FAILED,D0         ;IF ERROR, THIS IS THE ONE WE WANT -
               BEQ.S   SNSI_60                   ;BRANCH IF WE GOT IT, MEANS EMPTY CHANNEL.
SNSI_40
               MOVE    (A7)+,DRIVE_SEL      ;RESTORE DRIVE_SEL SETTING,
               MOVEQ   #SCSI_ID_USED,D0     ;EXIT WITH ERROR MESSAGE.
               BRA.S   SNSI_EXIT
;
SNSI_60
               MOVE    (A7)+,DRIVE_SEL      ;RESTORE DRIVE_SEL SETTING, CONTNUE.
               BSR     SEND_SPECIFIERS      ;WAVE MAGIC SCSI WAND TO CHANGE DRIVE ID.
               BNE.S   SNSI_EXIT            ;EXIT IF ANY ERROR OCCURRED.
               MOVE    NEW_SCSI_ID,DRIVE_SEL     ;JUMP TO NEW SCSI CHANNEL.
               MOVE    #3035H,CUR_OMTI_REV       ;SET CONTROLLER ID TO SOMETHING BESIDES 3100,
               BSR     CONFIG_DATAFRAME          ;RE-ORIENT THE DRIVE TO ITS NEW REALITY -
                                                 ;PASS RETURN STATUS THROUGH.
;
SNSI_EXIT
               RTS
;
;
CHANGING_ID_SCRN
               ASC     "   PERFORMING   "
               ASC     "   ID CHANGE    "
;
;AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA


















;VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV
;
; READ SCSI DISK DESCRIPTOR AND BANK DESCRIPTOR -
; TRANSFER CERTAIN INFO TO COMMON LOCATIONS FOR LATER REFERENCE.
; THIS IS A PRELIMINARY STEP IN EVERY SCSI DISK ACCESS.
;
; DRIVE_SEL DETERMINES WHICH DRIVE WE LOOK AT - IF READING BANK
; DESCRIPTOR, BANK_SEL DETERMINES WHICH BANK WE ACCESS.
;
; DISK DESCRIPTOR IS RECORD #DF_BASE_REC ON SEQUENTIAL-FORMATTED DRIVE -
; WE READ THIS RECORD INTO HD_DESCR_BUF AND CHECK IT OUT.
; IF THE FIRST 14 BYTES ARE 'SEQUENTIAL0440' THEN WE'RE IN BUSINESS -
; WE SET UP CUR_MODEL_ID AND CUR_FIRMWR_REV (DESCRIBE DISK AT LARGE).
; WE THEN READ THE APPROPRIATE BANK DESCRIPTOR INTO BANK_DESCR_BUF -
; EXCEPT IN CERTAIN CASES (FOR UTILITIES WHERE THIS INFO IS IRRELEVANT,
; OR WHERE AN OUT-OF-RANGE BANK_SEL VALUE WOULD TRIGGER A DEVICE ERROR).
; FROM THIS WE OBTAIN CUR_FILE_TYPE, CUR_WRT_PROT AND CUR_QFILE_STAT.
; DEPENDING UPON THE OPERATION BEING CARRIED OUT, WE MAY ALSO READ A
; BANK_NAME FROM BANK_DESCR_BUF INTO ONE HALF OF CUR_BANK_NAME -
; BUT THIS WILL BE DONE LATER ELSEWHERE, NOT HERE AND NOW.
;
; RETURNS D0 CLEAR, 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.
; ALSO NOTE THAT ERROR CODE MAY BE A SCSI BUS ERROR CODE - IF WE ARE NOT
; ABLE TO READ THE LOGICAL RECORDS CONTAINING DESCRIPTOR INFO.
; DESTROYS D0, OTHER REGISTERS PRESERVED.
;
; 921008-12:53pm
; new addition here - a test unit ready command is issued point-blank as
; the first action.  this should thereby stand as the first scsi access
; to occur as part of any normal scsi disk function (ie, apart from 
; bus reset and such).  the purpose of this is to clear any pending
; unit attention condition in the target device being accessed.
; therefore, the results of the test unit ready command are not checked.
; umm, no, actually they are checked - on the second shot, which can
; thus catch any "real" error conditions, such as device not ready,
; since unit attention, if any, has already been eradicated.
;
;
READ_HD_DESCRIPTOR
;
		bsr	test_unit_ready		; safely snuff unit attention
							; if pending - don't sweat the
							; results of this command.
;
		bsr	test_unit_ready		; once again, just for fun ....
		bne.s	RD_DES_EXIT		; if bomb-o, go report an error -
							; typically device not ready.
;
               CLR.L   HD_DESCR_BUF         ;WIPE OUT PART OF "SEQUENTIAL" ID STRING, MAKE SURE WE
                                            ;DON'T END UP TESTING LEFTOVERS LATER ON.
               SF      VALID_HD_DESCR       ;LIKEWISE, INDICATE WE HAVEN'T SEEN VALID DESCR YET.
               MOVE    #LOAD_MASK,D0        ;READ MAIN DISK DESCRIPTOR FROM SELECTED DRIVE.
               BSR     DISK_DESCR_MOVE
               BNE.S   RD_DES_EXIT          ;EXIT IF DISK DESCRIPTOR READ WAS UNSUCCESSFUL.
               BSR.S   CHECK_HD_ID_STRING   ;WE READ IT - SEE IF IT STARTS WITH "SEQUENTIAL0440".
               BNE.S   RD_DES_EXIT          ;SO - EXIT IF IT DOESN'T START WITH THAT STRING.
               ST      VALID_HD_DESCR            ;IF OK, THEN SAY SO -
               MOVE.L  HD_MODEL_ID,CUR_MODEL_ID  ;THEN, SET UP MODEL ID, FIRMWARE REV.
               MOVE    HD_FIRMWR_REV,CUR_FIRMWR_REV
;
               MOVE    DISK_OP_CODE,D0      ;SO, WHAT WE UP TO?
               BTST    #HD_UTIL_BIT,D0      ;EXECUTING A SPECIAL DISK UTILITY?
               BEQ.S   RD_DES_40            ;BRANCH IF NOT - GO TEST BANK_SEL VALUE FOR VALIDITY.
               BTST    #SAVE_BIT,D0         ;YES - IS IT THE BANK WRITE-PROTECT UTILITY?
               BEQ.S   RD_DES_50            ;BRANCH IF NOT - DON'T NEED BANK INFO, SKIP OUT NOW.
RD_DES_40
               BSR.S   BANK_SEL_TEST        ;SEE IF BANK NUMBER IS VALID FOR SELECTED DRIVE.
               BNE.S   RD_DES_50            ;EXIT IF NOT, DON'T TRY TO READ BANK DESCRIPTOR.
               MOVE    #LOAD_MASK,D0        ;ELSE, READ BANK DESCRIPTOR FOR SELECTED BANK.
               BSR     BANK_DESCR_MOVE
               BNE.S   RD_DES_EXIT               ;EXIT IF BANK DESCRIPTOR READ WAS UNSUCESSFUL,
               MOVE    BANK_TYPE,CUR_FILE_TYPE   ;ELSE SET UP FILE DESCRIPTOR PARAMETERS.
               MOVE    BANK_WRT_PROT,CUR_WRT_PROT
               MOVE    BANK_QFIL_STAT,CUR_QFILE_STAT
;
RD_DES_50
               CLR     D0                        ;NO-ERROR EXIT - Z FLAG TRUE, D0 = 0.
;
RD_DES_EXIT
               RTS
;
;
;
; DEEZYAH DISTROY D0.
;
CHECK_HD_ID_STRING
                                            ;WELL, WE READ MAIN DESCRIPTOR RECORD - WHAT WAS IN IT?
               MOVEM.L A0-A1,-(A7)
;900425               MOVE.L  #HD_CORP_ID_STRING,A0     ;SHOULD LOOK LIKE THIS.
               lea.l   HD_CORP_ID_STRING(pc),A0  ;SHOULD LOOK LIKE THIS.
               MOVE    #HD_DESCR_BUF,A1          ;SHOULD BE HERE.
               MOVEQ   #13,D0                    ;WE LOOK AT A 14-CHARACTER STRING.
CHK_ID_10
               CMPM.B  (A0)+,(A1)+
               BNE.S   CHK_ID_20            ;EXIT COMPARE LOOP IF ANY MISMATCH.
               DBRA    D0,CHK_ID_10         ;LOOP UNTIL ENTIRE STRING COMPARED.
               CLR     D0                   ;FULL STRING MATCH, PASS Z FLAG TRUE AND D0 = 0.
               BRA.S   CHK_ID_30
CHK_ID_20
               MOVEQ   #INVAL_FORMAT,D0     ;MISMATCH - PASS Z FLAG FALSE, ERROR CODE IN D0.
CHK_ID_30
               MOVEM.L (A7)+,A0-A1
CHK_ID_EXIT
               RTS
;
;AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
               SKIP
;VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV
;
; TEST BANK NUMBER SETTING AGAINST BANK RANGE VALUE IN DISK DESCRIPTOR -
; ASSUMES MAIN SCSI DISK DESCRIPTOR HAS BEEN READ AND IS VALID.
; RETURN Z FLAG TRUE IF BANK NUMBER IS IN RANGE,
; ELSE RETURN Z FLAG FALSE, D0 = #NO_SUCH_BANK.
; NOTE: APPLICABLE ONLY TO SCSI DRIVE, NO ERROR IF USING FLOPPY DRIVE.
;
BANK_SEL_TEST
               TST     DRIVE_SEL            ;ARE WE USING SCSI DRIVE?
               BMI.S   BANK_SEL_IS_COOL     ;RETURN NO-ERROR STATUS IF NOT.
               BSR.S   GET_BANK_SEL         ;ELSE - SEE WHAT BANK WE'RE SUPPOSED TO ACCESS,
               CMP     HD_CAPACITY,D0       ;SEE IF IT EXISTS ON THE DRIVE WE'RE USING -
               BCS.S   BANK_SEL_IS_COOL     ;RETURN NO-ERROR STATUS IF IT EXISTS,
               MOVEQ   #NO_SUCH_BANK,D0     ;ELSE RETURN ERROR CODE.
               BRA.S   BANK_SEL_TEST_EXIT
;
BANK_SEL_IS_COOL
               CLR     D0                   ;NO-ERROR RETURN PATH.
;
BANK_SEL_TEST_EXIT
               RTS
;
;AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
;
;
;
;VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV
;
; ROUTINES FOR ACCESSING BANK_SEL ARRAY -
; INDEXING PER CURRENT VALUE OF DRIVE_SEL.
; VALUE IS FETCHED INTO / STORED FROM D0 - "GET" ROUTINE PRESERVES ALL
; OTHER REGISTERS, "PUT" ROUTINE PRESERVES ALL REGISTERS.
; RETURNED CONDITION CODES REFLECT VALUE LOADED/SAVED.
;
GET_BANK_SEL
               MOVEM.L A0,-(A7)
               MOVE    DRIVE_SEL,A0         ;FETCH CURRENT DRIVE CHANNEL NUMBER,
               ADD     A0,A0                ;CONVERT IT TO WORD OFFSET,
               MOVE    BANK_SEL(A0),D0      ;FETCH CURRENT BANK SELECTION FOR THIS DRIVE.
               MOVEM.L (A7)+,A0
               RTS
;
;
PUT_BANK_SEL
               MOVEM.L A0,-(A7)
               MOVE    DRIVE_SEL,A0         ;FETCH CURRENT DRIVE CHANNEL NUMBER,
               ADD     A0,A0                ;CONVERT IT TO WORD OFFSET,
               MOVE    D0,BANK_SEL(A0)      ;STORE NEW BANK SELECTION FOR THIS DRIVE.
               MOVEM.L (A7)+,A0
               RTS
;
;AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
               SKIP
;VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV
;
; WRITE (UPDATED) DESCRIPTOR INFO TO SCSI BANK DESCRIPTOR RECORD -
; DRIVE_SEL, BANK_SEL DETERMINE DRIVE AND BANK RESPECTIVELY.
;
; CALLED DURING SAVE ALL SOUNDS/ALL SEQS/CUELIST, SET/CLEAR PROTECT -
; I.E., WHENEVER SCSI DISK FILE STATUS IS SUBJECT TO CHANGE.
; INFO FROM MASTER DESCRIPTOR IS COPIED INTO THE SCSI BANK DESCRIPTOR
; BUFFER - THIS INCLUDES THE CURRENT SOUND OR SEQUENCE BANK NAME, EXCEPT
; FOR CUELIST SAVES AND BANK WRITE-PROTECT SWITCH CHANGES, WHICH DO NOT
; EFFECT A CHANGE OF BANK NAME.
;
; RETURNS Z FLAG TRUE IF TRANSFER IS SUCCESSFUL,
; ELSE RETURNS Z FLAG FALSE AND ERROR CODE IN D0.
; DESTROYS D0, OTHER REGISTERS PRESERVED.
;
WRITE_HD_DESCRIPTOR
               MOVE    CUR_FILE_TYPE,BANK_TYPE   ;SET UP PARAMS IN SCSI BANK DESCRIPTOR BUFFER.
               MOVE    CUR_WRT_PROT,BANK_WRT_PROT
               MOVE    CUR_QFILE_STAT,BANK_QFIL_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 BANK NAME.
               CMP     #HD_UTIL_MASK+SAVE_MASK,D0     ;LIKEWISE IF CHANGING WRITE-PROTECT STATUS.
               BEQ.S   WR_DES_20
               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,BANK_DESCR_BUF ;ELSE, USE SEQUENCE BANK NAME.
               MOVE.L  CUR_BANK_NAME+12,BANK_DESCR_BUF+4
               BRA.S   WR_DES_20
WR_DES_10
               MOVE.L  CUR_BANK_NAME,BANK_DESCR_BUF   ;USE SOUND BANK NAME.
               MOVE.L  CUR_BANK_NAME+4,BANK_DESCR_BUF+4
WR_DES_20
               MOVE    #SAVE_MASK,D0        ;WELL, WE'RE ALL SET - LET'S DO IT.
               BSR     BANK_DESCR_MOVE
                                            ;PASS RETURN STATUS THROUGH.
WR_DESCR_EXIT
               RTS
;
;AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
               SKIP
;VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV
;
; HARD-WIRED TRANSFER SUBROUTINES FOR VARIOUS DATA STRUCTURES
; RESIDENT IN CPU RAM -
; DISK_OP_CODE CONTROLS THE TRANSFER TYPE (LOAD, SAVE, VERIFY) EXCEPT
; FOR DESCRIPTOR RECORD TRANSFERS, IN WHICH D0 POSES AS DISK_OP_CODE.
; BANK_SEL INDICATES WHICH DISK BANK IS TO BE USED (EXCEPT FOR TRANSFERS
; TO/FROM MAIN DISK DESCRIPTOR - ONLY ONE ON A DISK, NOT IN ANY BANK).
; DRIVE_SEL INDICATES WHICH DISK TO USE (ASSUMED SCSI, NOT FLOPPY).
; ALL RETURN Z FLAG TRUE IF TRANSFER IS SUCCESSFUL, OR RETURN
; Z FLAG FALSE AND AN ERROR CODE IN D0.
; D0 IS DESTROYED, OTHER REGISTERS ARE PRESERVED.
; NOTE: EACH CALL TRIGGERS EXECUTION OF A COMPLETE SCSI SEQUENCE
; OR MULTIPLE COMPLETE SCSI SEQUENCES.
;
;
; TRANSFER SMPTE CUE LIST:
;
SCSI_CUELIST_MOVE
               MOVEM.L D1-D5/A0,-(A7)
               MOVEQ   #1,D4                ;RECORD OFFSET WITHIN BANK.
               MOVEQ   #6,D5                ;NUMBER OF DISK RECORDS TO TRANSFER.
               MOVE    #CUELIST_BLOCK,A0    ;RAM LOCATION FOR THIS DATA STRUCTURE.
               CLR     D1                   ;INITIAL DATA-SKIP LENGTH (0 = RIGHT FROM BEGINNING).
               MOVE.L  #CUE_BLK_SIZE,D2     ;NUMBER OF DATA BYTES TO TRANSFER.
               MOVE    #CUE_BLK_XTRA,D3     ;NUMBER OF RECORD-FILLER BYTES FOLLOWING ACTUAL DATA.
               BRA     SCSI_CPU_MOVE
;
;
;
; TRANSFER MIDI PORTION OF SYSTEM CONFIGURATION INFO:
;
SCSI_MIDI_MOVE
               MOVEM.L D1-D5/A0,-(A7)
               MOVEQ   #7,D4                ;RECORD OFFSET WITHIN BANK.
               MOVEQ   #1,D5                ;NUMBER OF DISK RECORDS TO TRANSFER.
               MOVE    #MIDI_BLOCK,A0       ;RAM LOCATION FOR THIS DATA STRUCTURE.
               CLR     D1                   ;INITIAL DATA-SKIP LENGTH (0 = RIGHT FROM BEGINNING).
               MOVE.L  #MIDI_BLK_SIZE,D2    ;NUMBER OF DATA BYTES TO TRANSFER.
               MOVE    #MIDI_BLK_XTRA,D3    ;NUMBER OF RECORD-FILLER BYTES FOLLOWING ACTUAL DATA.
               BRA     SCSI_CPU_MOVE
;
;
;
; TRANSFER SEQUENCER, ETC. PORTION OF SYSTEM CONFIGURATION INFO:
;
SCSI_SEQ_SYS_MOVE
               MOVEM.L D1-D5/A0,-(A7)
               MOVEQ   #8,D4                ;RECORD OFFSET WITHIN BANK.
               MOVEQ   #1,D5                ;NUMBER OF DISK RECORDS TO TRANSFER.
               MOVE    #SEQ_SYS_BLOCK,A0    ;RAM LOCATION FOR THIS DATA STRUCTURE.
               CLR     D1                   ;INITIAL DATA-SKIP LENGTH (0 = RIGHT FROM BEGINNING).
               MOVE.L  #SEQ_BLK_SIZE,D2     ;NUMBER OF DATA BYTES TO TRANSFER.
               MOVE    #SEQ_BLK_XTRA,D3     ;NUMBER OF RECORD-FILLER BYTES FOLLOWING ACTUAL DATA.
               BRA     SCSI_CPU_MOVE
;
;
;
; TRANSFER SMPTE PORTION OF SYSTEM CONFIGURATION INFO:
;
SCSI_SMPTE_MOVE
               MOVEM.L D1-D5/A0,-(A7)
               MOVEQ   #9,D4                ;RECORD OFFSET WITHIN BANK.
               MOVEQ   #1,D5                ;NUMBER OF DISK RECORDS TO TRANSFER.
               MOVE    #SMPTE_BLOCK,A0      ;RAM LOCATION FOR THIS DATA STRUCTURE.
               CLR     D1                   ;INITIAL DATA-SKIP LENGTH (0 = RIGHT FROM BEGINNING).
               MOVE.L  #SMPTE_BLK_SIZE,D2   ;NUMBER OF DATA BYTES TO TRANSFER.
               MOVE    #SMPTE_BLK_XTRA,D3   ;NUMBER OF RECORD-FILLER BYTES FOLLOWING ACTUAL DATA.
               BRA     SCSI_CPU_MOVE
;
;
;
; TRANSFER SOUND CONTROL BLOCK INFORMATION -
; COVERS NORMAL TRANSFERS, DIRECTORY EXTRACTION, ONE-SOUND LOAD:
;
SCSI_SND_CTRL_MOVE
               MOVEM.L D1-D5/A0,-(A7)
               MOVEQ   #10,D4               ;RECORD OFFSET WITHIN BANK.
               MOVE    DISK_OP_CODE,D0      ;ARE WE EXTRACTING A SOUND DIRECTORY?
               BTST    #DIR_BIT,D0
               BNE.S   SCSI_SND_DIR_XTRACT  ;BRANCH IF YES, PROCEDURE IS DIFFERENT.
                                            ;ELSE CONTINUE AS IF TRANSFERRING ALL CONTROL BLOCKS:
               MOVEQ   #12,D5               ;NUMBER OF DISK RECORDS TO TRANSFER.
               MOVE    #S_BLK_00,A0         ;RAM LOCATION FOR THIS DATA STRUCTURE.
               CLR     D1                   ;INITIAL DATA-SKIP LENGTH (0 = RIGHT FROM BEGINNING).
               MOVE.L  #0C0H*32,D2          ;NUMBER OF DATA BYTES TO TRANSFER.
               CLR     D3                   ;NUMBER OF RECORD-FILLER BYTES FOLLOWING ACTUAL DATA.
;
               AND     #LOAD_MASK+SAM_MASK+MOV_ALL_MASK,D0 ;ARE WE IN FACT DOING ONE-SOUND LOAD?
               CMP     #LOAD_MASK+SAM_MASK,D0              ;IF SO, SHOULD SEE ONLY THESE TWO BITS -
               BNE     SCSI_CPU_MOVE             ;BRANCH IF NOT, FOREGOING SETUP IS WHAT WE NEEDED.
               MOVE    #WASTELAND,A0        ;ELSE - BUFFER ONE SOUND CONTROL BLOCK INTO WASTELAND.
               MOVE    SND_UNIT_SEL,D0      ;WE'LL STILL READ ALL SOUND CONTROL RECORDS,
               MOVE    D0,D1                ;BUT WE'LL IGNORE MOST OF WHAT WE READ -
               MOVE.L  #0C0H,D2             ;TO WIT:  NUMBER OF BYTES WE WILL ACTUALLY STORE.
               MULU    D2,D1                ;WE'LL SKIP THIS MANY TO REACH DESIRED CONTROL BLOCK.
               MOVEQ   #31,D3
               SUB     D0,D3
               MULU    D2,D3                ;WE'LL TOSS THIS MANY AFTER READING DESIRED BLOCK.
               BRA     SCSI_CPU_MOVE        ;NOW, WE'RE SET.
;
;
;
; EXTRACT SOUND DIRECTORY FROM SOUND CONTROL BLOCKS IN CURRENT BANK:
; D4 CONTAINS OFFSET WITHIN BANK OF FIRST RECORD OF THIS DATA.
; NOTE:  D1-D5/A0 WERE ALREADY PUSHED ONTO STACK BEFORE COMING HERE.
;
SCSI_SND_DIR_XTRACT
               MOVE    #S_BLOCK_SIZE,D1     ;SIZE OF DIRECTORY BLOCK WHICH CONTAINS EACH NAME.
               MOVEQ   #15,D2               ;EXTRACT 16 NAMES PER BUFFERING PASS.
               MOVEQ   #1,D3                ;MAKE TWO BUFFERING PASSES, 32 NAMES TOTAL.
               MOVEQ   #6,D5                ;BUFFER SIX LOGICAL BLOCKS PER PASS.
               BRA     BANK_DIR_EXTRACT     ;WE GOT A GENERAL ROUTINE FOR THIS.
;
;
;
; TRANSFER PAD/PRESET KITS AND BANKS:
;
SCSI_KITS_MOVE
               MOVEM.L D1-D5/A0,-(A7)
               MOVEQ   #22,D4               ;RECORD OFFSET WITHIN BANK.
               MOVEQ   #1,D5                ;NUMBER OF DISK RECORDS TO TRANSFER.
               MOVE    #PAD_SOUNDS,A0       ;RAM LOCATION FOR THIS DATA STRUCTURE.
               CLR     D1                   ;INITIAL DATA-SKIP LENGTH (0 = RIGHT FROM BEGINNING).
               MOVE.L  #512,D2              ;NUMBER OF DATA BYTES TO TRANSFER.
               CLR     D3                   ;NUMBER OF RECORD-FILLER BYTES FOLLOWING ACTUAL DATA.
               BRA     SCSI_CPU_MOVE
;
;
;
; TRANSFER SEQUENCER SONG LIST INFORMATION -
; COVERS NORMAL AND ONE-SONG TRANSFERS, SONG DIRECTORY EXTRACTION:
;
SCSI_SONGLIST_MOVE
               MOVEM.L D1-D5/A0,-(A7)
               MOVEQ   #10,D4               ;RECORD OFFSET WITHIN BANK.
               MOVE    DISK_OP_CODE,D0      ;ARE WE EXTRACTING A SONG DIRECTORY?
               BTST    #DIR_BIT,D0
               BNE.S   SCSI_SONG_DIR_XTRACT ;BRANCH IF YES, PROCEDURE IS DIFFERENT.
                                            ;ELSE, CONTINUE AS IF TRANSFERRING FULL SONGLIST -
               MOVEQ   #24,D5               ;NUMBER OF DISK RECORDS TO TRANSFER.
               MOVE.L  #SONG_LIST,A0        ;RAM LOCATION FOR THIS DATA STRUCTURE.
               CLR     D1                   ;INITIAL DATA-SKIP LENGTH (0 = RIGHT FROM BEGINNING).
               MOVE.L  #24*512,D2           ;NUMBER OF DATA BYTES TO TRANSFER.
               CLR     D3                   ;NUMBER OF RECORD-FILLER BYTES FOLLOWING ACTUAL DATA.
;
               AND     #SONG_MASK+MOV_ALL_MASK,D0     ;ARE WE IN FACT DOING ONE-SONG TRANSFER?
               CMP     #SONG_MASK,D0                  ;IF SO, SHOULD NOW SEE ONLY THIS BIT -
               BNE     SCSI_CPU_MOVE             ;BRANCH IF NOT, FOREGOING SETUP IS WHAT WE NEEDED.
                                                 ;ELSE, ALTER SETUP AS REQUIRED PER SOURCE/TARGET:
               MOVE.L  #1024,D2             ;RESET THE DATA BYTE TRANSFER COUNT FOR ONE SONG.
               MOVE    CURRENT_SONG,D0      ;COMPUTE RAM TRANSFER ADDRESS FOR TARGET SONG -
               MULU    D2,D0                ;1K BYTE PER SONG.
               ADD.L   D0,A0                ;OFFSET FROM BOTTOM OF SONG LIST (ADDRESS IS IN A0).
               MOVE    SONG_UNIT_SEL,D0     ;NOW FIGGEROUT WHICH DISK RECORDS WE WANT -
               ADD     D0,D0                ;TWO RECORDS PER SONG, OFFSET INTO SONG FILE,
               ADD     D0,D4                ;TACKUM ONTO BANK RECORD-OFFSET OF SONG FILE (IN D4).
               MOVEQ   #2,D5                ;RESET LOGICAL RECORD TRANSFER COUNT FOR ONE SONG.
               BRA     SCSI_CPU_MOVE        ;NOW, TIME TO DOOT - TOOT.
;
;
;
; EXTRACT SONG DIRECTORY FROM SONG LIST BLOCKS IN CURRENT BANK:
; D4 CONTAINS OFFSET WITHIN BANK OF FIRST RECORD OF THIS DATA.
; NOTE:  D1-D5/A0 WERE ALREADY PUSHED ONTO STACK BEFORE COMING HERE.
;
SCSI_SONG_DIR_XTRACT
               MOVE    #1024,D1             ;SIZE OF DIRECTORY BLOCK WHICH CONTAINS EACH NAME.
               MOVEQ   #3,D2                ;EXTRACT 4 NAMES PER BUFFERING PASS.
               MOVEQ   #2,D3                ;MAKE THREE BUFFERING PASSES, 12 NAMES TOTAL.
               MOVEQ   #8,D5                ;BUFFER EIGHT LOGICAL BLOCKS PER PASS.
               BRA.S   BANK_DIR_EXTRACT     ;WE GOT A GENERAL ROUTINE FOR THIS.
;
;
;
; TRANSFER SEQUENCE DIRECTORY INFORMATION -
; COVERS NORMAL TRANSFERS, DIRECTORY EXTRACTION, ONE-SEQUENCE LOAD:
;
SCSI_SEQ_DIR_MOVE
               MOVEM.L D1-D5/A0,-(A7)
               MOVEQ   #34,D4               ;RECORD OFFSET WITHIN BANK.
               MOVE    DISK_OP_CODE,D0      ;ARE WE EXTRACTING A SEQUENCE DIRECTORY?
               BTST    #DIR_BIT,D0
               BNE.S   SCSI_SEQ_DIR_XTRACT  ;BRANCH IF YES, PROCEDURE IS DIFFERENT.
                                            ;ELSE, CONTINUE AS IF TRANSFERRING ENTIRE DIRECTORY:
               MOVEQ   #7,D5                ;NUMBER OF DISK RECORDS TO TRANSFER.
               MOVE.L  #SEQ_DIRECTORY,A0    ;RAM LOCATION FOR THIS DATA STRUCTURE.
               CLR     D1                   ;INITIAL DATA-SKIP LENGTH (0 = RIGHT FROM BEGINNING).
               MOVE.L  #3200,D2             ;NUMBER OF DATA BYTES TO TRANSFER.
               MOVE    #384,D3              ;NUMBER OF RECORD-FILLER BYTES FOLLOWING ACTUAL DATA.
;
               AND     #LOAD_MASK+SEQ_MASK+MOV_ALL_MASK,D0 ;ARE WE IN FACT DOING ONE-SEQUENCE LOAD?
               CMP     #LOAD_MASK+SEQ_MASK,D0              ;IF SO, SHOULD SEE ONLY THESE TWO BITS -
               BNE     SCSI_CPU_MOVE             ;BRANCH IF NOT, FOREGOING SETUP IS WHAT WE NEEDED.
               MOVE    #WASTELAND_2,A0      ;ELSE - BUFFER ONE SEQUENCE DIR BLOCK INTO WASTELAND_2.
               MOVE    SEQ_UNIT_SEL,D0      ;WE'LL STILL READ ALL SEQUENCE DIRECTORY RECORDS,
               MOVE    D0,D1                ;BUT WE'LL IGNORE MOST OF WHAT WE READ -
               MOVEQ   #32,D2               ;TO WIT:  NUMBER OF BYTES WE WILL ACTUALLY STORE.
               MULU    D2,D1                ;SKIP THIS MUCH DATA TO REACH DESIRED DIRECTORY BLOCK.
               MOVEQ   #99,D3
               SUB     D0,D3
               MULU    D2,D3                ;WE'LL TOSS THIS MUCH DATA AFTER READING DESIRED BLOCK,
               ADD     #384,D3              ;PLUS GARBAGE LINGERING IN THE LAST DIRECTORY RECORD.
               BRA     SCSI_CPU_MOVE        ;NOW, WE'RE SET.
;
;
;
; EXTRACT SEQUENCE DIRECTORY FROM SEQ DIRECTORY BLOCKS IN CURRENT BANK:
; D4 CONTAINS OFFSET WITHIN BANK OF FIRST RECORD OF THIS DATA.
; NOTE:  D1-D5/A0 WERE ALREADY PUSHED ONTO STACK BEFORE COMING HERE.
;
SCSI_SEQ_DIR_XTRACT
               MOVE    #Q_BLOCK_SIZE,D1     ;SIZE OF DIRECTORY BLOCK WHICH CONTAINS EACH NAME.
               MOVEQ   #99,D2               ;EXTRACT 100 NAMES PER BUFFERING PASS.
               MOVEQ   #0,D3                ;MAKE ONE BUFFERING PASS - ALL WE NEED.
               MOVEQ   #7,D5                ;BUFFER SIX LOGICAL BLOCKS PER PASS (ALL THERE ARE).
                                            ;FALL THROUGH INTO GENERAL ROUTINE FOR THIS.
;
;
;
; GENERAL DIRECTORY-EXTRACTION ROUTINE FOR BANK-STORED DATA:
; NOTE: SEQ-NAMES VERSION FALLS IN FROM ABOVE, CAREFUL IF YOU MOVE US.
; DATA IS BUFFERED (POSSIBLY IN MULTIPLE PASSES) INTO WASTELAND AND ITS
; NEIGHBOR WASTELAND_2, NAMES ARE EXTRACTED INTO DIRECTORY_BUF.
; UPON ENTRY:
; D1 INDICATES SIZE OF DIRECTORY BLOCK WHICH CONTAINS INDIVIDUAL NAME.
; D2 = NUMBER OF NAMES TO EXTRACT ON EACH BUFFERING PASS (MINUS 1).
; D3 = TOTAL NUMBER OF BUFFERING PASSES REQUIRED (MINUS 1).
; D4 = BANK RECORD OFFSET OF START OF RELEVANT DATA STRUCTURE.
; D5 = NUMBER OF 512-BYTE LOGICAL BLOCKS READ ON EACH BUFFERING PASS.
; D1-D5/A0 HAVE ALREADY BEEN PUSHED ONCE ONTO STACK - NOT NECESSARILY
; WITH THE SAME VALUES THAT THEY CONTAIN UPON ARRIVING HERE.
; UPON RETURN:
; WE UNSTACK D1-D5/A0 TO BALANCE STACK BEFORE RETURNING.
; WE RETURN WITH Z FLAG TRUE IF ALL BUFFERING PASSES WERE SUCCESSFUL,
; ELSE WE RETURN WITH Z FLAG FALSE AND ERROR CODE IN D0.
; ALL REGISTERS OTHER THAN D0 ARE PRESERVED (WITH REFERENCE TO THE POINT
; BEFORE COMING HERE AT WHICH THEY WERE PUSHED ONTO THE STACK, THAT IS).
;
BANK_DIR_EXTRACT
               MOVEM.L A1,-(A7)             ;SET UP DIRECTORY-COMPILE POINTER.
               MOVE.L  #DIRECTORY_BUF,A1
BK_DIR_X_20
               MOVEM.L D1-D3/A1,-(A7)       ;SAVE PARAMS AND COMPILE-POINTER WHILE BUFFERING DATA.
               CLR     D1                   ;SKIP NO DATA AT EITHER END OF BUFFERING PASS.
               CLR     D3
               MOVE    D5,D2                ;COMPUTE BYTE TRANSFER COUNT FROM RECORD XFR COUNT.
               MULU    #512,D2
               MOVE    #WASTELAND,A0        ;BUFFER THE DISK DATA HERE.
               BSR     SCSI_GENL_BANK_ACC   ;GET DATA FROM DA DISSSK (EXPECT ALL REGS PRESERVED).
               MOVEM.L (A7)+,D1-D3/A1       ;RESTORE PARAMETERS AND COMPILE-POINTER.
               BNE.S   BK_DIR_X_Z0          ;PEEL OUT IF DATA TRANSFER WAS BUNKOID.
               MOVEM.L D1-D2,-(A7)          ;SAVE EXTRACTION PARAMS WHILE EXTRACTING NAME DATA.
BK_DIR_X_40
               MOVE.L  (A0),(A1)+           ;EXTRACT ONE NAME FROM DISK BUFFER INTO DIRECTORY_BUF -
               MOVE.L  4(A0),(A1)+          ;ALL NAMES ARE AT HEAD OF THEIR RESPECTIVE DATA BLOCKS.
               ADD     D1,A0                ;STEP TO NEXT DATA BLOCK IN BUFFER (IF ANY).
               DBRA    D2,BK_DIR_X_40       ;LOOP IF MORE NAMES TO EXTRACT ON THIS BUFFERING PASS.
               MOVEM.L (A7)+,D1-D2          ;RESTORE STASHED EXTRACTION PARAMS.
               ADD     D5,D4                ;SET RECORD OFFSET FOR NEXT BUFFERING PASS (IF ANY).
               DBRA    D3,BK_DIR_X_20       ;LOOP IF ANY MORE BUFFERING PASSES TO DO.
               CLR     D0                   ;DONE - EXIT WITH Z FLAG TRUE.
;
BK_DIR_X_Z0
               MOVEM.L (A7)+,A1             ;DISCARD DIRECTORY-COMPILE POINTER.
               MOVEM.L (A7)+,D1-D5/A0       ;RESTORE ALL OTHER STACKED REGISTERS.
BK_DIR_X_EXIT
               RTS
;
;
;
; TRANSFER SEQUENCE MEMORY BLOCK LIST:
;
SCSI_BLOCKLIST_MOVE
               MOVEM.L D1-D5/A0,-(A7)
               MOVEQ   #41,D4               ;RECORD OFFSET WITHIN BANK.
               MOVEQ   #2,D5                ;NUMBER OF DISK RECORDS TO TRANSFER.
               MOVE    #SEQ_BLOCK_LIST,A0   ;RAM LOCATION FOR THIS DATA STRUCTURE.
               CLR     D1                   ;INITIAL DATA-SKIP LENGTH (0 = RIGHT FROM BEGINNING).
               MOVE.L  #800,D2              ;NUMBER OF DATA BYTES TO TRANSFER.
               MOVE    #224,D3              ;NUMBER OF RECORD-FILLER BYTES FOLLOWING ACTUAL DATA.
               BRA     SCSI_CPU_MOVE
;
;
;
; TRANSFER (PRESUMABLY, LOAD) ONE BLOCK OF SEQUENCE DATA (1024 BYTES) -
; CUR_XFR_ADDR (.L) CONTAINS TARGET RAM ADDRESS FOR TRANSFER,
; CURRENT_REC CONTAINS THE SEQUENCE DATA BLOCK NUMBER (0-399):
;
SCSI_SEQ_BLOCK_MOVE
               MOVEM.L D1-D5/A0,-(A7)
               MOVEQ   #43,D4               ;RECORD OFFSET WITHIN BANK OF SEQUENCE DATA BLOCKS.
               ADD     CURRENT_REC,D4       ;OFFSET THIS BY TWO DISK RECORDS PER SEQ DATA BLOCK.
               ADD     CURRENT_REC,D4
               MOVEQ   #2,D5                ;SET RECORD TRANSFER LENGTH TO 2.
               MOVE.L  CUR_XFR_ADDR,A0      ;SET RAM ADDRESS FOR TRANSFER.
               CLR     D1                   ;INITIAL DATA-SKIP LENGTH (0 = RIGHT FROM BEGINNING).
               MOVE.L  #1024,D2             ;TOTAL NUMBER OF DATA BYTES TO TRANSFER.
               CLR     D3                   ;NUMBER OF RECORD-FILLER BYTES FOLLOWING ACTUAL DATA.
               BRA     SCSI_CPU_MOVE
;
;
;
; TRANSFER ALL SEQUENCE DATA:
;
SCSI_SEQ_DATA_MOVE
               MOVEM.L D1-D6/A0,-(A7)
               CLR     D6                   ;SEGMENT COUNTER - TRANSFER DATA IN EIGHT SEGMENTS.
SC_SQ_DM_20
               MOVE    D6,D0                ;LIGHT AN LED PER SEGMENT BEING TRANSFERRED.
               BSR     INDICATE
               MOVEQ   #100,D5              ;TRANSFER 100 DISK RECORDS PER SEGMENT.
               MOVEQ   #43,D4               ;RECORD OFFSET WITHIN BANK OF SEQUENCE DATA BLOCKS.
               MOVEQ   #100,D3              ;ADJUST THIS OFFSET PER SEGMENT NUMBER.
               MULU    D6,D3
               ADD     D3,D4
               MULU    #512,D3              ;BYTE OFFSET OF THIS SEGMENT IN SEQUENCE RAM.
               MOVE.L  #SEQUENCE_RAM,A0     ;RAM LOCATION FOR SEQUENCE DATA -
               ADD.L   D3,A0                ;ADJUST PER SEGMENT BEING TRANSFERRED.
               CLR     D1                   ;INITIAL DATA-SKIP LENGTH (0 = RIGHT FROM BEGINNING).
               MOVE.L  #51200,D2            ;NUMBER OF DATA BYTES TO TRANSFER PER SEGMENT.
               CLR     D3                   ;NUMBER OF RECORD-FILLER BYTES FOLLOWING ACTUAL DATA.
               BSR.S   SCSI_GENL_BANK_ACC   ;TRANSFER ONE SEGMENT OF SEQUENCE DATA.
               BNE.S   SC_SQ_DM_Z0          ;EXIT IF ANY ERROR OCCURRED.
               ADDQ    #1,D6                ;BUMP SEGMENT COUNTER -
               CMP     #8,D6                ;ARE WE DONE YET?
               BNE     SC_SQ_DM_20          ;LOOPAGHENN IF NOT, ELSE RETURN Z FLAG TRUE.
SC_SQ_DM_Z0
               MOVEM.L (A7)+,D1-D6/A0
SC_SQ_DM_EXIT
               RTS
;
;
;
; TRANSFER SCSI DISK DESCRIPTOR TO/FROM HD_DESCR_BUF:
;
DISK_DESCR_MOVE
               MOVEM.L D1-D5/A0,-(A7)
               MOVE    D0,D4                ;COPY SUBSTITUTE DISK_OP_CODE VALUE.
               BSR     SELECT_DEVICE        ;TRY TO SELECT TARGET DEVICE.
               BNE     SCM_Z0               ;EXIT IF SELECTION UNSUCCESSFUL.
               MOVE.L  #DF_BASE_REC,D0      ;ACCESS FIRST AVAILABLE LOGICAL BLOCK ON SELECTED DRIVE
                                            ;(SEE DEFINITION IN DISKDEFS FOR FULL EXPLANATION).
               MOVEQ   #1,D5                ;NUMBER OF DISK RECORDS TO TRANSFER.
               MOVE    #HD_DESCR_BUF,A0     ;RAM LOCATION FOR THIS DATA STRUCTURE.
               CLR     D1                   ;INITIAL DATA-SKIP LENGTH (0 = RIGHT FROM BEGINNING).
               MOVE.L  #HD_DESCR_LEN,D2     ;NUMBER OF DATA BYTES TO TRANSFER.
               MOVE    #HD_DESCR_XTRA,D3    ;NUMBER OF RECORD-FILLER BYTES FOLLOWING ACTUAL DATA.
               BRA.S   SCM_SIDE_ENTRY
;
;
;
; TRANSFER SCSI DISK BANK DESCRIPTOR TO/FROM BANK_DESCR_BUF:
;
BANK_DESCR_MOVE
               MOVEM.L D1-D5/A0,-(A7)
               MOVE    D0,D5                ;COPY SUBSTITUTE DISK_OP_CODE VALUE.
               BSR     SELECT_DEVICE        ;TRY TO SELECT TARGET DEVICE.
               BNE     SCM_Z0               ;EXIT IF SELECTION UNSUCCESSFUL.
               MOVEQ   #0,D4                ;SET RECORD OFFSET WITHIN BANK,
               BSR.S   SCM_LOG_ADDR         ;COMPUTE LOGICAL BLOCK ADDRESS IN D0.L.
               MOVE    D5,D4                ;SHUFFLE SUBSTITUTE DISK_OP_CODE VALUE INTO PLACE.
               MOVEQ   #1,D5                ;NUMBER OF DISK RECORDS TO TRANSFER.
               MOVE    #BANK_DESCR_BUF,A0   ;RAM LOCATION FOR THIS DATA STRUCTURE.
               CLR     D1                   ;INITIAL DATA-SKIP LENGTH (0 = RIGHT FROM BEGINNING).
               MOVE.L  #BANK_DESCR_LEN,D2   ;NUMBER OF DATA BYTES TO TRANSFER.
               MOVE    #BANK_DESCR_XTRA,D3  ;NUMBER OF RECORD-FILLER BYTES FOLLOWING ACTUAL DATA.
               BRA.S   SCM_SIDE_ENTRY
;
;
;
; FOR GENERAL ACCESS TO BANK-STORED DATA:
; PASS PARAMS HERE IN D1-D5/A0 - TRANSFER WILL BE DONE, REGS PRESERVED.
; RETURN CODE IN D0 AND Z FLAG AS ALWAYS.
;
SCSI_GENL_BANK_ACC
               MOVEM.L D1-D5/A0,-(A7)       ;PUSH THESE REGISTERS FIRST FOR PROPER STACK BALANCE.
               BRA.S   SCSI_CPU_MOVE        ;TRANSFER, PASS RETURN STATUS THROUGH.
;
;
;
; LOGICAL BLOCK ADDRESS COMPUTATION FOR BANK-STORED DATA STRUCTURES:
;
SCM_LOG_ADDR
               BSR     GET_BANK_SEL         ;BASE RECORD NUMBER FOR SELECTED BANK:
               MULU    #1559,D0             ;BANK INDEX * NUMBER OF RECORDS PER BANK.
               EXT.L   D4                   ;MAKE SURE BANK RECORD OFFSET IS VALID TO .L LENGTH,
               ADD.L   D4,D0                ;ADD RECORD OFFSET OF DATA BEING TRANSFERRED.
               ADD.L   #DF_BASE_REC+1,D0    ;ADD OFFSET FOR DISK DESCRIPTOR RECORD, ET CETERA
                                            ;(SEE DEFINITION IN DISKDEFS FOR FULL EXPLANATION).
               RTS
;
;
;
; THE ROUTINE THAT DOES ALL OF THE ACTUAL "WORK" -
; WE BRANCH HERE WITH REGISTERS STACKED, SO WE UNSTACKUM AT END.
;
SCSI_CPU_MOVE
               BSR     SELECT_DEVICE        ;TRY TO SELECT TARGET DEVICE.
               BNE.S   SCM_Z0               ;EXIT IF SELECTION UNSUCCESSFUL.
;
                                            ;TARGET RESPONDED TO SELECTION -
                                            ;SET UP COMMAND DESCRIPTOR BLOCK FOR THIS OPERATION:
               BSR     SCM_LOG_ADDR         ;USE BANK_SEL, D4 TO PUT ADDRESS IN D0.L.
               MOVE    DISK_OP_CODE,D4      ;THIS'LL TELL US WHAT WE OUGHT TO BE DOING.
;
;
SCM_SIDE_ENTRY                              ;THIS IS ENTRY POINT FOR DESCRIPTOR TRANSFERS:
                                            ;DEVICE IS ALREADY SELECTED,
                                            ;D0.L CONTAINS LOGICAL BLOCK ADDRESS,
                                            ;D4 CONTAINS SUBSTITUTE DISK_OP_CODE VALUE,
                                            ;OTHER REGISTER PARAMS (D1-D3/D5/A0) USED NORMALLY.
;
               MOVE.L  D0,SCSI_CMD_BUF      ;STORE BEGINNING LOGICAL BLOCK ADDRESS.
               MOVEQ   #08H,D0              ;ASSUME LOAD/VERIFY - FETCH READ OPERATION CODE -
               BTST    #SAVE_BIT,D4
               BEQ.S   SCM_10               ;BRANCH IF LOAD/VERIFY,
               MOVEQ   #0AH,D0              ;ELSE ASSUME SAVE AND FETCH WRITE OPERATION CODE.
SCM_10
               MOVE.B  D0,SCSI_CMD_BUF      ;STORE OPERATION CODE.
               MOVE.B  D5,SCSI_CMD_BUF+4    ;SET TRANSFER LENGTH = ?? BLOCKS.
               SF      SCSI_CMD_BUF+5       ;(VENDOR UNIQUE),(RESERVED) = 0.  FLAG/LINK = 0/0.
;
               BSR     SIX_BYTE_CMD         ;COMMAND BLOCK DONE, ISSUE COMMAND TO TARGET DEVICE.
               BNE.S   SCM_Z0               ;EXIT IF COMMAND NOT ISSUED SUCCESSFULLY.
;
               MOVEQ   #DAT_IN_PHASE,D0     ;COMMAND ISSUED - FETCH PHASE CODE FOR LOAD/VERIFY.
               SF      SCSI_VER_FLAG        ;(CAN ONLY BE SET BY COMPARE ERRORS IN VERIFY ROUTINE.)
               BTST    #DIR_BIT,D4          ;NOW, WHAT ARE WE DOING AGAIN?
               BNE.S   SCM_20               ;BRANCH IF DOING A DIRECTORY EXTRACTION.
               BTST    #VERIFY_BIT,D4
               BNE.S   SCM_30               ;BRANCH IF DOING A COMPARE.
               BTST    #SAVE_BIT,D4
               BNE.S   SCM_38               ;BRANCH IF SAVING.
                                            ;IF NONE OF ABOVE, ASSUME LOAD - FALL THROUGH.
SCM_20
               BSR     SCSI_RAM_READ        ;LOAD FROM DISK.
               BRA.S   SCM_40
SCM_30
               BSR     SCSI_RAM_VERIFY      ;COMPARE TO DISK.
               BRA.S   SCM_40
SCM_38
               MOVEQ   #DAT_OUT_PHASE,D0    ;FOR SAVE - MUST USE DIFFERENT PHASE CODE.
               BSR     SCSI_RAM_WRITE
SCM_40
               BNE.S   SCM_Z0               ;EXIT IF THE DATA TRANSFER WAS NOT SUCCESSFUL.
               BSR     FINISH_SCSI_SEQ      ;GET COMPLETION STATUS.
               BNE.S   SCM_Z0               ;EXIT IF STATUS OTHER THAN "GOOD" WAS RETURNED.
               TST.B   SCSI_VER_FLAG        ;IF VERIFYING, THIS FLAG MAY HAVE BEEN SET FOR ERRORS -
               BEQ.S   SCM_Z0               ;BRANCH IF NOT, RETURN Z FLAG TRUE.
               MOVEQ   #VERIFY_ERR,D0       ;ELSE, RETURN Z FLAG FALSE WITH CODE FOR VERIFY ERROR.
;
SCM_Z0
               MOVEM.L (A7)+,D1-D5/A0
SCM_EXIT
               RTS
;
;AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
               SKIP
;VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV
;
; COMPILE ALL-BANKS DIRECTORY FOR SELECTED SCSI DRIVE -
; ASSUMES WE'VE ALREADY PASSED ALL NECESSARY DESCRIPTOR TESTS.
; RETURNS Z FLAG TRUE IF ALL GOES WELL,
; ELSE RETURNS Z FLAG FALSE AND ERROR CODE IN D0.
; PRESERVES ALL REGISTERS OTHER THAN D0.
;
SCSI_ALL_BANKS_DIR
               MOVEM.L D1-D5/A0-A2,-(A7)    ;BUREAU OF REGISTER CONSERVATION.
               BSR     DISP_XFR_SCREEN      ;TELL 'EM WE'RE HARD AT WORK (RATHER BE HARD AT HOME).
               BSR     GET_BANK_SEL         ;REMEMBER WHAT BANK WAS SELECTED WHEN WE GOT HERE -
               MOVE    D0,-(A7)
               CLR     D0                   ;WE'RE GONNA GO THROUGH ALL ON THIS DISK.
               BSR     PUT_BANK_SEL
               MOVE.L  #DIRECTORY_BUF,A1    ;INITIALIZE DIRECTORY COMPILE POINTERS - ONE FOR NAMES,
               MOVE.L  #BANK_TYPE_BUF,A2    ;ONE FOR BANK TYPES.
SC_ABD_40
               MOVEM.L A1-A2,-(A7)          ;MAKE SURE WE DON'T LOSE DIR-COMPILE POINTERS.
               MOVE    #WASTELAND,A0        ;BUFFER BANK DESCRIPTOR DATA HERE.
               CLR     D1                   ;DON'T SKIP ANY DATA AT BEGINNING OF BANK DESCRIPTOR,
               CLR     D3                   ;DON'T FRET ABOUT READING EXCESS DATA AT END.
               MOVE.L  #512,D2              ;SO, THIS BE NUMBAH BYTES TO READ.
               CLR     D4                   ;BANK DESCRIPTOR IS FIRST RECORD IN EACH BANK.
               MOVEQ   #1,D5                ;YES YES YES JUST READ THIS ONE RECORD THENK YEW.
               BSR     SCSI_GENL_BANK_ACC   ;THIS GONNA DO IT (AND WE EXPECT D1-D5/A0 PRESERVED).
               MOVEM.L (A7)+,A1-A2          ;OK TO BRING THESE GUYS BACK NOW.
               BNE.S   SC_ABD_Z0            ;EXIT IF THERE WAS A SCSI TRANSFER ERROR.
               MOVE.L  (A0)+,(A1)+          ;LIKE, NO PROBLEM - COPY BANK NAME INTO DIRECTORY_BUF,
               MOVE.L  (A0)+,(A1)+
               MOVE    2(A0),D0             ;THEN FETCH BANK_TYPE (DESCRIBES TYPE OF DATA IN BANK),
               ADDQ    #1,D0                ;OFFSET IT FOR DISPLAY REASONS (YOU GOTS TO BELIEVE),
               MOVE.B  D0,(A2)+             ;PUT THIS CODE INTO BANK_TYPE_BUF.
;
               BSR     GET_BANK_SEL         ;OKAY THEN - STEP UP TO THE NEXT BANK (IF ANY) -
               ADDQ    #1,D0
               BSR     PUT_BANK_SEL
                                            ;ARE THERE ANY MORE BANKS TO POKE ON THIS DRIVE?
               CMP     HD_CAPACITY,D0       ;(INFO IN MAIN DISK DESCRIPTOR LETS US KNOW.)
               BCS     SC_ABD_40            ;LOOP IF MORE TO GO -
               CLR     D0                   ;ELSE, EXIT WITH Z FLAG TRUE.
;
SC_ABD_Z0
               MOVE    D0,D1                ;PUSH RETURN CODE OUT OF THE WAY FOR A SEC -
               MOVE    (A7)+,D0             ;RESTORE ORIGINAL BANK_SEL VALUE.
               BSR     PUT_BANK_SEL
               MOVE    D1,D0                ;BRING RETURN CODE BACK INTO D0 (WHERE IT BELONGS).
               MOVEM.L (A7)+,D1-D5/A0-A2    ;ET CETERA.
               TST     D0                   ;REFRESH Z FLAG RETURN STATUS.
SC_ABD_EXIT
               RTS
;
;AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
;
;
;
;VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV
;
; SET, CLEAR OR CHECK STATUS OF WRITE-PROTECT SWITCH IN SELECTED BANK -
; RESPOND WITH CATCH-ALL STATUS MESSAGE (IF NO ERROR MESSAGES NEEDED).
; ASSUMES DESCRIPTORS HAVE BEEN READ AND INFO COPIED INTO MASTER BUFFER.
;
; NOTE: IF NO ERRORS OCCUR, WE RETURN Z FLAG FALSE AND D0 = 0 IN ORDER
; TO KEEP OUR STATUS MESSAGE IN THE LCD FROM BEING OVERWRITTEN.
;
SCSI_WRITE_PROTECT
               MOVE    PROTECT_SEL,D0       ;WHAT DO WE NEED TO DO ABOUT WRITE-PROTECT SWITCH?
               BEQ.S   SC_WRPRT_60          ;BRANCH IF JUST DISPLAYING STATUS FOR SELECTED BANK.
               CMP     #1,D0
               BEQ.S   SC_WRPRT_20          ;BRANCH TO SET WRITE-PROTECT SWITCH FOR SELECTED BANK.
               CLR     CUR_WRT_PROT         ;ELSE - CLEAR SWITCH STATUS IN MASTER DESCRIPTOR BUF,
               BRA.S   SC_WRPRT_40          ;GO WRITE NEW STATUS OUT TO DISK.
SC_WRPRT_20
               CMP     #0FFFFH,CUR_FILE_TYPE     ;IF BANK IS EMPTY, DISALLOW WRITE-PROTECTION.
               BNE.S   SC_WRPRT_30
               MOVEQ   #NOT_ALLOWED,D0
               BRA.S   SC_WRPRT_EXIT
SC_WRPRT_30
               MOVE    #0FFFFH,CUR_WRT_PROT ;SET PROTECT SWITCH IN MASTER DESCRIPTOR BUFFER.
SC_WRPRT_40
               BSR     WRITE_HD_DESCRIPTOR  ;WAAYYYLL, THIS OWWW-TA DEWIT.
               BNE.S   SC_WRPRT_EXIT        ;EXIT IF ANYTHING FUCKED UP.
;
SC_WRPRT_60
;900425               MOVE.L  #PROT_STAT_SCRN,A1   ;OK - TIME TO TELL IT LIKE IT SEEMS TO BE ....
               lea.l   PROT_STAT_SCRN(pc),A1     ;OK - TIME TO TELL IT LIKE IT SEEMS TO BE ....
;900424                ABS_LONG
;900424               JSR     WRITE_SCREEN
;900424                ABS_SHORT
               CALL    LCD_FUNS,WR_SCRN
               TST     CUR_WRT_PROT         ;IS PROTECT SWITCH NOW ON OR OFF?
               BEQ.S   SC_WRPRT_80          ;BRANCH IF OFF, SCREEN_BUFFER DATA IS ALREADY CORRECT -
               MOVE.L  #204F4E20H,SCREEN_BUFFER+16    ;ELSE DROP IN AN " ON " STRING AND GO -
SC_WRPRT_80
;900424                ABS_LONG
;900424               JSR     DISP_BUFFER          ;SCREEN_BUFFER COMPLETE, PUT IT OUT TO LCD.
;900424                ABS_SHORT
               CALL    LCD_FUNS,DSP_BUF
               CLR     D0                   ;NOW RETURN WITH D0 = 0,
               MOVEQ   #1,D1                ;Z FLAG FALSE.
;
SC_WRPRT_EXIT
               RTS
;
;
PROT_STAT_SCRN
               ASC     "WRITE-PROTCT NOW"
               ASC     "OFF IN THIS BANK"
;
;AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
               SKIP
;VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV
;
; TRANSFER SAMPLE MEMORY VIA 6-BYTE COMMANDS -
; MAY REQUIRE MULTIPLE ITERATIONS OF THE SCSI SEQUENCE OWING TO LIMITED
; TRANSFER LENGTH OF THE 6-BYTE SCSI COMMANDS.
;
; DISK_OP_CODE SELECTS LOAD/SAVE/VERIFY ALL SAMPLES OR LOAD ONE SAMPLE -
; IF DOING ONE-SAMPLE LOAD, DSK_FIL_ADDR (.L) CONTAINS THE WORD ADDRESS
; OF THE SAMPLE BEING LOADED RELATIVE TO ITS DISK SAMPLE FILE,
; DSK_FIL_LENGTH(.L) HOLDS THE WORD LENGTH OF THE SAMPLE TO BE LOADED,
; AND CUR_XFR_ADDR(.L) CONTAINS THE MEMORY ADDRESS AT WHICH TO STORE IT.
;
; BANK_SEL SELECTS A SPECIFIC FLOPPY-IMAGE BANK.
; DRIVE_SEL INDICATES WHICH SCSI DRIVE TO USE.
; RETURNS Z FLAG TRUE IF OPERATION SUCCESSFUL,
; ELSE RETURNS Z FLAG FALSE AND ERROR CODE IN D0.
;
; NOTE:  TRIGGERS MULTIPLE COMPLETE SCSI SEQUENCES.
; DESTROYS D0.
;
SCSI_SAMPLE_MOVE
               MOVEM.L D1-D5,-(A7)
               MOVE    DISK_OP_CODE,D5      ;D5 TELLS US WHAT WE SHOULD BE DOING, THROUGHOUT.
               BTST    #MOV_ALL_BIT,D5      ;TRANSFERRING ALL SAMPLE DATA?
               BNE.S   SSM_20               ;BRANCH IF YAH -
               MOVE.L  DSK_FIL_ADDR,D0      ;ELSE, COMPUTE LOGICAL RECORD LIMITS FOR ONE SAMPLE -
               MOVE.L  D0,D1                ;RECORD NUMBERS RELATIVE TO DISK SAMPLE FILE.
               ADD.L   DSK_FIL_LENGTH,D1
               DIVU    #1024,D0
               MULU    #3,D0                ;THIS IS STARTING RECORD NUMBER,
               DIVU    #1024,D1
               MULU    #3,D1                ;THIS IS FINAL RECORD NUMBER PLUS 1.
               BRA.S   SSM_30
;
SSM_20
                                            ;TRANSFERRING A FULL SAMPLE-MEMORY IMAGE:
               CLR.L   CUR_XFR_ADDR         ;WE STARTS AT ZEE-RO, AND GOES.
               CLR     D0                   ;STARTING RECORD NUMBER = 0 (RELATIVE TO SAMPLE FILE),
               MOVE    #1536,D1             ;FINAL REC # IS LAST SAMPLE DATA RECORD PLUS ONE.
;
SSM_30
               MOVE    D0,CURRENT_REC       ;STORE SAMPLE-FILE-RELATIVE RECORD NUMBERS.
               MOVE    D1,FINAL_REC
               BSR     SET_RAM_INTFC        ;INITIALIZE SAMPLE RAM INTERFACE PER CUR_XFR_ADDR.
;
                                            ;"THE LOOP" - UP TO 192 LOGICAL RECORDS PER ITERATION:
SSM_60
               MOVE    CURRENT_REC,D0       ;LIGHT AN LED FOR THIS SEGMENT OF DATA TRANSFER.
               EXT.L   D0
               MOVE.L  D0,D1                ;SAVE .L CURRENT_REC COPY FOR BELOW.
               DIVU    #192,D0
               BSR     INDICATE
;
               BSR     SELECT_DEVICE        ;TRY TO SELECT TARGET DEVICE.
               BNE     SSM_Z0               ;EXIT IF SELECTION UNSUCCESSFUL.
;
                                            ;TARGET RESPONDED TO SELECTION -
                                            ;SET UP COMMAND DESCRIPTOR BLOCK FOR THIS OPERATION:
               BSR     GET_BANK_SEL         ;BASE RECORD NUMBER FOR SELECTED BANK:
               MULU    #1559,D0             ;BANK INDEX * NUMBER OF RECORDS PER BANK.
               ADD.L   #DF_BASE_REC+24,D0   ;ADD RECORD OFFSET OF SAMPLE DATA BLOCK WITHIN BANK,
                                            ;PLUS OFFSET FOR DISK DESCRIPTOR RECORD, ET CETERA
                                            ;(SEE DEFINITION IN DISKDEFS FOR FULL EXPLANATION).
               ADD.L   D1,D0                ;TOSS IN THE CURRENT_REC .L VALUE SAVED ABOVE.
               MOVE.L  D0,SCSI_CMD_BUF      ;STORE BEGINNING LOGICAL BLOCK ADDRESS.
               MOVE    FINAL_REC,D2         ;FETCH FINAL SAMPLE RECORD NUMBER,
               SUB     D1,D2                ;TAKE DIFFERENCE FROM WHERE WE ARE NOW -
               CMP     #192,D2              ;MORE THAN 192 RECORDS LEFT TO GO HERE?
               BLS.S   SSM_70               ;BRANCH IF NOT -
               MOVE    #192,D2              ;ELSE, SET TRANSFER LENGTH TO 192 RECORDS.
SSM_70
               MOVE.B  D2,SCSI_CMD_BUF+4    ;STORE TRANSFER LENGTH FOR THIS PASS.
               ADD     D2,CURRENT_REC       ;BUMP TRANSFER COUNTER UP TO MARK PROGRESS.
               EXT.L   D2                   ;MAKE SURE HE LONG ENOUGH TO DIVIDE,
               DIVU    #3,D2                ;SET SAMPLE WORD TRANSFER COUNT FOR THIS PASS - RECORD
               MULU    #1024,D2             ;COUNT SHOULD BE A MULTIPLE OF 3, AT 1K WORD PER GROUP
                                            ;OF THREE 512-BYTE RECORDS.
;
               MOVEQ   #08H,D0              ;ASSUME LOAD/VERIFY - FETCH READ OPERATION CODE -
               BTST    #SAVE_BIT,D5         ;ARE WE DOING SAVE?
               BEQ.S   SSM_80               ;BRANCH IF NOT - ASSUME LOAD/VERIFY.
               MOVEQ   #0AH,D0              ;ELSE, SAVE - FETCH WRITE OPERATION CODE.
SSM_80
               MOVE.B  D0,SCSI_CMD_BUF      ;STORE OPERATION CODE.
               SF      SCSI_CMD_BUF+5       ;(VENDOR UNIQUE),(RESERVED) = 0.  FLAG/LINK = 0/0.
;
               BSR     SIX_BYTE_CMD         ;COMMAND BLOCK DONE, ISSUE COMMAND TO TARGET DEVICE.
               BNE.S   SSM_Z0               ;EXIT IF COMMAND NOT ISSUED SUCCESSFULLY.
;
                                            ;COMMAND ISSUED - FINISH SET UP, DECIDE WHAT TO DO:
               SF      SCSI_VER_FLAG        ;(CAN ONLY BE SET BY COMPARE ERRORS IN VERIFY ROUTINE.)
               MOVEQ   #DAT_IN_PHASE,D0     ;FETCH PHASE CODE FOR LOAD/VERIFY.
               BTST    #LOAD_BIT,D5         ;NOW, WHAT ARE WE DOING AGAIN?
               BNE.S   SSM_A0               ;BRANCH IF DOING A LOAD FROM DISK.
               BTST    #VERIFY_BIT,D5
               BNE.S   SSM_C0               ;BRANCH IF DOING A COMPARE.
               MOVEQ   #DAT_OUT_PHASE,D0    ;NEITHER OF ABOVE, MUST BE SAVE - CORRECT PHASE CODE.
               BSR     SCSI_SAM_WRITE       ;WRITE 10000H WORDS TO DISK.
               BRA.S   SSM_E0
SSM_A0
               BSR     SCSI_SAM_READ        ;LOAD FROM DISK - D2.L INDICATES NUMBER OF WORDS.
               BRA.S   SSM_E0
SSM_C0
               BSR     SCSI_SAM_VERIFY      ;COMPARE 10000H WORDS AGAINST DISK.
SSM_E0
               BNE.S   SSM_Z0               ;EXIT IF THE DATA TRANSFER WAS NOT SUCCESSFUL.
               BSR     FINISH_SCSI_SEQ      ;GET COMPLETION STATUS.
               BNE.S   SSM_Z0               ;EXIT IF STATUS OTHER THAN "GOOD" WAS RETURNED.
               TST.B   SCSI_VER_FLAG        ;IF VERIFYING, THIS FLAG MAY HAVE BEEN SET FOR ERRORS -
               BEQ.S   SSM_X0               ;BRANCH IF NOT, PROCEED TO NEXT BLOCK OF TRANSFER.
               MOVEQ   #VERIFY_ERR,D0       ;ELSE, RETURN Z FLAG FALSE WITH CODE FOR VERIFY ERROR.
               BRA.S   SSM_Z0
;
SSM_X0
               MOVE    CURRENT_REC,D0       ;SO - DID THIS PASS TAKE CARE OF IT, OR MORE TO GO?
               CMP     FINAL_REC,D0
               BCS     SSM_60               ;LOOP AGAIN IF WE'RE STILL DOING IT.
               CLR     D0                   ;ELSE, RETURN WITH Z FLAG TRUE (NO ERRORS).
;
SSM_Z0
               MOVEM.L (A7)+,D1-D5
SSM_EXIT
               RTS
;
;AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
               SKIP
;VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV
;
; MULTI-STRUCTURE TRANSFER ROUTINES -
; MOVE ALL SOUNDS (INCLUDING SOUND CONTROLS), ALL SEQUENCES (INCLUDING
; SEQ DIRECTORY AND BLOCK LIST).
; IN ADDITION, SOUNDS MOVE MAY BE ACCOMPANIED BY KITS MOVE, AND
; SEQUENCES MOVE MAY BE ACCOMPANIED BY SONGS MOVE -
; FURTHERMORE, ALL OF THE ABOVE MAY BE ACCOMPANIED BY SYS CONFIG MOVE
; (WHICH IN TURN CONSISTS OF THREE SEPARATE RECORD TRANSFERS ....).
; FOR MORE DETAIL SEE SOUNDS_MOVE AND SEQUENCES_MOVE IN DISKCMD2.
;
;
SCSI_CONFIG_MOVE
               BSR     SCSI_MIDI_MOVE       ;MOVE MIDI SYS-CONFIG BLOCK.
               BNE.S   SCSI_CFG_MV_EXIT     ;EXIT IF ANYTHING WENT WRONG.
               BSR     SCSI_SEQ_SYS_MOVE    ;MOVE SEQUENCER SYS-CONFIG BLOCK.
               BNE.S   SCSI_CFG_MV_EXIT     ;EXIT IF ANYTHING WENT WRONG.
               BSR     SCSI_SMPTE_MOVE      ;MOVE SMPTE SYS-CONFIG BLOCK.
                                            ;PASS RETURN STATUS THROUGH.
SCSI_CFG_MV_EXIT
               RTS
;
;
;
SCSI_ALL_SEQ_MOVE
               MOVE    DISK_OP_CODE,D1      ;SHOULD WE BE TRANSFERRING SYS CONFIG STUFF?
               BTST    #SYSTEM_BIT,D1
               BEQ.S   SC_SEQMOV_20         ;BRANCH IF NOT, ELSE ....
               BSR     SCSI_CONFIG_MOVE     ;MOVE ALL SYS-CONFIG BLOCKS.
               BNE.S   SC_SEQMOV_EXIT       ;EXIT IF ANYTHING WENT WRONG.
SC_SEQMOV_20
               MOVE    DISK_OP_CODE,D1      ;SHOULD WE BE TRANSFERRING SONGS?
               BTST    #SONG_BIT,D1
               BEQ.S   SC_SEQMOV_40         ;BRANCH IF NOT, ELSE ....
               BSR     SCSI_SONGLIST_MOVE   ;MOVE SEQUENCER SONG LIST.
               BNE.S   SC_SEQMOV_EXIT       ;EXIT IF ANYTHING WENT WRONG.
SC_SEQMOV_40
               BSR     SCSI_SEQ_DIR_MOVE    ;MOVE SEQUENCE DIRECTORY.
               BNE.S   SC_SEQMOV_EXIT       ;EXIT IF ANYTHING WENT WRONG.
               BSR     SCSI_BLOCKLIST_MOVE  ;MOVE SEQUENCE BLOCK LIST.
               BNE.S   SC_SEQMOV_EXIT       ;EXIT IF ANYTHING WENT WRONG.
               BSR     SCSI_SEQ_DATA_MOVE   ;MOVE ALL SEQUENCE DATA.
                                            ;PASS RETURN STATUS THROUGH.
SC_SEQMOV_EXIT
               RTS
;
;
;
SCSI_ALL_SND_MOVE
               MOVE    DISK_OP_CODE,D1      ;SHOULD WE BE TRANSFERRING SYS CONFIG STUFF?
               BTST    #SYSTEM_BIT,D1
               BEQ.S   SC_SNDMOV_20         ;BRANCH IF NOT, ELSE ....
               BSR     SCSI_CONFIG_MOVE     ;MOVE ALL SYS-CONFIG BLOCKS.
               BNE.S   SC_SNDMOV_EXIT       ;EXIT IF ANYTHING WENT WRONG.
SC_SNDMOV_20
               BSR     SCSI_SND_CTRL_MOVE   ;MOVE SOUND CONTROL BLOCKS.
               BNE.S   SC_SNDMOV_EXIT       ;EXIT IF ANYTHING WENT WRONG.
               MOVE    DISK_OP_CODE,D1      ;SHOULD WE BE TRANSFERRING PAD KITS/BANKS?
               BTST    #KIT_BIT,D1
               BEQ.S   SC_SNDMOV_40         ;BRANCH IF NOT, ELSE ....
               BSR     SCSI_KITS_MOVE       ;MOVE PAD AND KIT ARRAYS.
               BNE.S   SC_SNDMOV_EXIT       ;EXIT IF ANYTHING WENT WRONG.
SC_SNDMOV_40
               BSR     SCSI_SAMPLE_MOVE     ;MOVE ALL SAMPLE DATA.
                                            ;PASS RETURN STATUS THROUGH.
SC_SNDMOV_EXIT
               RTS
;
;AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
