home *** CD-ROM | disk | FTP | other *** search
Text File | 1993-03-30 | 31.4 KB | 1,475 lines |
- ;*** Z207 DEVICE DRIVER
- ;
-
- ;** DRIVER ENTRY JUMP VECTORS
- ;
-
- DRVR207:
- JMP SEL207 ;SELECT
- JMP RDT207 ;READ TRACK
- JMP WRT207 ;WRITE TRACK
- JMP MNT207 ;MOUNT
- JMP FMT207 ;FORMAT
- JMP WPC207 ;WRITE PROTECT CHECK
-
-
-
-
- ;** INITIALIZE DRIVE TABLES
- ;
- ; ENTRY: NONE
- ; EXIT: NONE
- ; USES: ALL
- ;
-
- IN207:
-
- ;* RESTORE THE HEAD ON EACH DRIVE TO DETERMINE IF IT EXISTS
-
- MOV CX,4 ;# OF Z207 DRIVES
- LEA BP,DPEBASE ;START ADDRESS OF Z207 DPE'S
- ADD BP,BBIOS
- OR DSKOP,DSKOPI ;INDICATE INIT IN PROGRESS
-
- IN2071:
- PUSH CX
- CALL DS207 ;SELECT DRIVE
- CALL RST207 ;RESTORE HEAD
- TEST AL,FDSTK0 ;Q. TRACK 0 INDICATION
- JNZ IN2073 ; BR IF YES
-
- OR DPEFLG2[BP],DPEIMG ;FLAG DRIVE AS IMAGINARY
-
- IN2073:
- TEST DPEUNIT[BP],CONDS8 ;Q. 8" DRIVE
- JNZ IN2074 ; BR IF YES
- IN AL,FDAS ;DETERMINE IF 5 1/4" DRIVE IS
- TEST AL,AS96T ; 48 OR 96 TPI AND INDICATE THIS
- JZ IN2074 ; IN TABLE
- OR DPEFLAG[BP],DPE96T
-
- IN2074:
- ADD BP,DPEL ;BUMP TO NEXT DRIVE TABLE
- POP CX
- LOOP IN2071 ;LOOP AND CHECK ALL DRIVES
-
- AND DSKOP,NOT DSKOPI ;INDICATE INIT DONE
- CALL DONE207 ;TURN OFF DRIVES
-
- ;* DO DRIVE MAPPING & REAL/IMAGINARY TABLE INITIALIZATION
-
- PUSH ES
- MOV ES,.MTRDSEG ;GET ADDRESS OF MONITOR DATA AREA
- MOV CL,ES: MTRBU ;GET BOOT DEVICE UNIT #
- MOV AL,ES: MTRBI ;GET BOOT DEVICE INDEX #
- POP ES
-
- CMP AL,1 ;Q. BOOT DEVICE WAS 8" DRIVE
- JE IN2076 ; BR IF YES
-
- ; BOOT DEVICE WAS 5 1/4" DRIVE; BUILD 5 1/4" TABLES THEN 8" TABLES
-
- MOV CH,2 ;# DRIVE TABLES
- MOV DH,0 ;START OF 5 1/4" TABLES
- CALL CBTFIL ;FILL IN TABLES
-
- MOV CL,0 ;UNIT #
- MOV CH,2 ;# DRIVE TABLES
- MOV DH,2 ;START OF 8" TABLES
- CALL CBTFIL ;FILL IN TABLES
-
- RET
-
- ; BOOT DEVICE WAS 8" DRIVE; BUILD 8" TABLES THEN 5 1/4" TABLES
-
- IN2076:
- MOV CH,2 ;# DRIVE TABLES
- MOV DH,2 ;START OF 8" TABLES
- CALL CBTFIL ;FILL IN TABLES
-
- MOV CL,0 ;UNIT #
- MOV CH,2 ;# DRIVE TABLES
- MOV DH,0 ;START OF 5 1/4" TABLES
- CALL CBTFIL ;FILL IN TABLES
-
- RET
-
-
-
-
- ;** SELECT DRIVE FOR 1ST LOGIN
- ;
- ; ENTRY: 'PHYDPE'=ADDRESS OF DPE FOR DRIVE
- ; (BX)=POINTER TO BUFFER HEADER INFO
- ; 'XLATES'=ADDRESS OF XLATE TABLE ADDRESSES
- ; EXIT: 'PHYDPE'=STATUS
- ; 0=ERROR , OTHERWISE SAME AS ON ENTRY
- ; USES: AX,CX,BP,SI,DI
- ;
-
- SEL207:
- OR DSKOP,DSKOPS ;INDICATE SELECT OPERATION IN PROGRESS
-
- MOV BP,BUFDPE[BX]
- MOV DPETRK[BP],DPEUNK ;INDICATE DRIVE HEAD POSITION UNKNOWN
-
- TEST DPEUNIT[BP],CONDS8 ;Q. 8" DRIVE
- JZ $+5
- JMP SEL2075 ; BR IF 8" DRIVE
-
- ;* SELECT ROUTINE FOR 5 1/4" DRIVES
-
- ; READ LABEL
-
- MOV PHYTRK,0 ;LABEL IS ON TRACK 0
- MOV PHYSID,0 ; SIDE 0
- MOV PHYSEC,0 ; 1ST SECTOR
- CALL RDY2070 ;READY CHECK
- CMP BUFERR[BX],0 ;Q. DRIVE NOT READY
- ; JE SEL2079 ; BR IF NOT READY
- JNE $+5
- JMP SEL2079
- MOV BUFERR[BX],0 ;CLEAR ERROR FLAG
- CALL DS207 ;SELECT DRIVE
- CALL RST207 ;RESTORE HEAD
- MOV COUNT,1024 ;MAXIMUM SECTOR LENGTH
- MOV DI,BUFBUF[BX] ;USE HOST BUFFER
- CALL RDS207 ;TRY READING LABEL AT DENSITY
- TEST AL,AL ; CURRENTLY INDICATED IN TABLES
- JZ SEL2072 ; BR IF ABLE TO READ LABEL SECTOR
-
- XOR DEVCTL,CONSD ;UNABLE TO READ LABEL SECTOR
- MOV AL,DEVCTL ; CHANGE TO OTHER DENSITY
- OUT FDCON,AL
- MOV DI,BUFBUF[BX] ;TRY TO READ LABEL SECTOR AGAIN
- CALL RDS207
- TEST AL,AL
- ; JNZ SEL2079 ; BR IF ERROR
- JZ $+5
- JMP SEL2079
-
- SEL2072:
- MOV SI,BUFBUF[BX] ;CHECK CHECKSUM OF LABEL
- ADD SI,LABEL
- CALL CHKLAB
- ; JNZ SEL2079 ; BR IF ERROR
- JZ $+5
- JMP SEL2079
-
- ; MOVE LABEL INFO TO DPE'S HEATH EXTENSIONS
-
- MOV SI,BUFBUF[BX]
-
- AND DPEFLAG[BP],DPETYPE+DPE96T
- MOV AL,LABHTH+(OFFSET DPEFLAG)-(OFFSET DPEHTH) [SI]
- AND AL,DPEDD+DPE2S
- OR DPEFLAG[BP],AL ;FLAG BYTE #1
-
- MOV AL,LABHTH+(OFFSET DPERPS)-(OFFSET DPEHTH) [SI]
- MOV DPERPS[BP],AL ;CP/M RECORDS PER PHYSICAL SECTOR
-
- MOV AL,LABHTH+(OFFSET DPERPAB)-(OFFSET DPEHTH) [SI]
- MOV DPERPAB[BP],AL ;CP/M RECORDS PER ALLOCATION BLOCK
-
- AND DPEFLG2[BP],NOT DPE96TM
- MOV AL,LABHTH+(OFFSET DPEFLG2)-(OFFSET DPEHTH) [SI]
- AND AL,DPE96TM
- OR DPEFLG2[BP],AL ;FLAG BYTE #2
-
- ; IF LABEL INDICATES THAT THE MEDIA IS DOUBLE SIDED, THEN
- ; CHECK OUT THE DRIVE FOR DOUBLE SIDED CAPABILITY
-
- TEST DPEFLAG[BP],DPE2S ;Q. DOUBLE SIDED MEDIA
- JZ SEL2073 ; BR IF NOT
-
- MOV PHYSID,FDFSS1 ;TRY TO READ A SECTOR HEADER
- LEA DI,RDABUF ; ON 2ND SIDE
- CALL RDA207
- TEST AL,AL
- ; JNZ SEL2079 ; BR IF ERROR
- JZ $+5
- JMP SEL2079
-
- CMP RDABUF+FDRASID,1 ;CHECK SIDE INFO
- ; JNE SEL2079 ; BR IF NOT 2ND SIDE
- JE $+5
- JMP SEL2079
-
- ; STEP IN 2 TRACKS, READ ADDRESS, AND STEP BACK OUT 2 TRACKS.
- ; IF READ ADDRESS FINDS TRACK 1 INSTEAD OF TRACK 2,
- ; THEN ASSUME 48 TPI MEDIA GENERATED
- ; ON A 48 TPI DRIVE WAS INSERTED INTO THE 96 TPI DRIVE; THEREFOR,
- ; USE AS A R/O DISK WITH DOUBLE STEPPING.
- ;
- ; THERE ARE TWO 48 TPI MEDIA FORMATS THAT ARE SUPPORTED ON
- ; A 96 TPI DRIVE.
- ; 1) MEDIA WAS FORMATTED ON A 96 TPI DRIVE AND ONLY USES
- ; THE FIRST HALF OF THE DISK SURFACE. (E.G. A 48 TPI MEDIA
- ; IS DUPLICATED ONTO MEDIA IN A 96 TPI DRIVE)
- ; 2) MEDIA WAS FORMATTED ON A 48 TPI DRIVE. THE HARDWARE
- ; GROUP HAS INFORMED ME THAT THE 96 TPI DRIVE CAN RELIABLY
- ; READ SUCH MEDIA BUT CANNOT WRITE ON IT. TO GO BETWEEN
- ; TRACKS IT IS NECESSARY TO DOUBLE THE NUMBER OF STEPS.
- ;
- ; THE FOLLOWING ARE THE POSSIBLE OUTCOMES OF THE READ ADDRESS
- ; MEDIA DRIVE DRIVE OUTCOME
- ; FORMAT GENERATED ON INSERTED IN TRACK
- ; ------ ------------ ----------- -------
- ; 48 TPI 48 TPI 48 TPI 2
- ; 48 TPI 48 TPI 96 TPI 1
- ; 48 TPI 96 TPI 48 TPI ERROR
- ; 48 TPI 96 TPI 96 TPI 2
- ; 96 TPI 96 TPI 48 TPI ERROR
- ; 96 TPI 96 TPI 96 TPI 2
- ;
-
- SEL2073:
- MOV PHYTRK,2 ;STEP IN TWO TRACKS
- CALL SDT207
-
- MOV PHYSID,0 ;DO READ ADDRESS
- LEA DI,RDABUF
- CALL RDA207
- TEST AL,AL
- ; JNZ SEL2079 ; BR IF ERROR
- JZ $+5
- JMP SEL2079
-
- CMP RDABUF+FDRATRK,2 ;CHECK IF TRACK 2
- JE SEL2073A ; BR IF YES
- ; 1) 48 TPI MEDIA GENERATED ON 48 TPI
- ; DRIVE INSERTED INTO 48 TPI DRIVE
- ; 2) 48 TPI MEDIA GENERATED ON 96 TPI
- ; DRIVE INSERTED INTO 96 TPI DRIVE
- ; 3) 96 TPI MEDIA INSERTED IN 96 TPI
-
- CMP RDABUF+FDRATRK,1 ;CHECK IF TRACK 1
- ; JNE SEL2079 ; BR IF NOT (ERROR)
- JE $+5
- JMP SEL2079
-
- OR DPEFLAG[BP],DPE48RO ;SET FLAG TO INDICATE 48 TPI MEDIA
- ; GENERATED ON 48 TPI DRIVE INSERTED
- ; INTO 96 TPI DRIVE. THE MEDIA
- ; IS TREATED AS R/O
-
- SEL2073A:
- CALL RST207 ;STEP OUT TWO TRACKS BY DOING RESTORE
-
- ; MOVE LABEL INFO TO DISK PARAMETER BLOCK
-
- MOV SI,BUFBUF[BX]
- ADD SI,LABDPB
- MOV DI,DPEDPB[BP]
- MOV CX,DPBL
- CLD
- REP MOVSB
-
- JMP SEL2078
-
- ;* SELECT FOR 8" DRIVE
-
- SEL2075:
- MOV PHYTRK,2 ;ATTEMPT TO READ ADDRESS HEADER
- MOV PHYSID,0 ; ON PHYSICAL TRACK #2 SIDE 0
- CALL DS207 ; AT THE CURRENT DENSITY IN
- CALL RST207 ; THE DRIVE'S DPE
- CALL SDT207
- LEA DI,RDABUF
- CALL RDA207
- TEST AL,AL
- JZ SEL2076 ;BR IF ABLE TO READ
-
- XOR DPEFLAG[BP],DPEDD ;CHANGE TO OTHER DENSITY
- XOR DEVCTL,CONSD
- MOV AL,DEVCTL
- OUT FDCON,AL
-
- LEA DI,RDABUF ;ATTEMPT TO READ ADDRESS HEADER
- CALL RDA207 ; AT OTHER DENSITY
- TEST AL,AL
- JNZ SEL2079 ;BR IF ERROR
-
- ; UPDATE REST OF DPE
-
- SEL2076:
- AND DPEFLAG[BP],0FFH-DPE2S ;# OF SIDES
- IN AL,FDAS ;ASK DRIVE HOW MANY SIDES
- TEST AL,AS2S
- JZ SEL2076A
- OR DPEFLAG[BP],DPE2S
-
- SEL2076A:
- MOV SI,DPEDD+DPE2S ;COMPUTE ADDRESS OF TABLE CONTAINING
- AND SI,WORD PTR DPEFLAG[BP] ; INFO FOR UPDATE
- IF (DPEDD NE 2) OR (DPE2S NE 1)
- %: DPEDD MUST BE 2 AND DPE2S MUST BE 1
- ENDIF
- SHL SI,1
- SHL SI,1
- XOR AH,AH
- MOV AL,RDABUF+FDRASL
- ADD SI,AX
- SHL SI,1
- MOV SI,TBL207[SI] ;GET ADDRESS OF UPDATE INFO
- TEST SI,SI ;CHECK FOR NOT SUPPORTED FORMAT
- JZ SEL2079 ; BR IF NOT SUPPORTED
-
- XOR AH,AH ;XLATE TABLE ADDRESS
- LODSB
- SHL AX,1
- MOV DI,XLATES
- ADD DI,AX
- MOV AX,ES:[DI]
- MOV DPEXLT[BP],AX
-
- LODSB ;CP/M RECORDS PER PHYSICAL SECTOR
- MOV DPERPS[BP],AL
-
- LODSB ;CP/M RECORDS PER ALLOCATION BLOCK
- MOV DPERPAB[BP],AL
-
- MOV DI,DPEDPB[BP] ;DPB
- MOV CX,DPBL
- CLD
- REP MOVSB
-
- ;* DONE WITH SELECT OPERATION
-
- SEL2078:
- AND DSKOP,NOT DSKOPS ;INDICATE DONE WITH SELECT OPERATION
- JMP DONE207 ;RETURN VIA 'DONE207'
-
- ;* ERROR OCCURRED
-
- SEL2079:
- MOV PHYDPE,0 ;INDICATE ERROR
- JMPS SEL2078
-
-
-
-
- ;** READ TRACK
- ;
- ; ENTRY: (BX)=POINTER TO BUFFER HEADER INFO
- ; EXIT: 'BUFERR[BX]'=STATUS
- ; 0=NO ERROR , 1=ERROR
- ; USES: AX,DI
- ;
-
- RDT207:
- CALL SET207 ;SETUP
- CALL SDT207 ;SEEK DESIRED TRACK
- CALL S1S207 ;SET 1ST SECTOR TO READ
- MOV DI,BUFBUF[BX] ;BUFFER ADDRESS
- ADD DI,AX
-
- RDT2071:
- CMP PREREAD,0 ;Q. DOING PREREAD
- JNE RDT2072 ; BR IF YES
- CMP BUFERR[BX],0 ;Q. ABORT
- JNE RDT2073 ; BR IF YES
-
- RDT2072:
- CALL RDS207 ;READ NEXT SECTOR
-
- RDT2073:
- ADD DI,COUNT ;BUMP BUFFER POINTER
- INC PHYSEC ;BUMP PHYSICAL SECTOR #
- MOV AL,BYTE PTR PHYSEC ;CHECK IF SECTOR # WRAPAROUND
- CMP AL,SECCNT
- JB RDT2074 ; BR IF NOT
- XOR AX,AX ; OTHERWISE START AT BEGINNING
- MOV PHYSEC,AX
- MOV DI,BUFBUF[BX]
-
- RDT2074:
- CMP AL,SEC1ST ;CHECK IF ALL OF TRACK READ
- JNE RDT2071 ; BR IF NOT
-
- JMP DONE207 ;RETURN THRU 'DONE207'
-
-
-
-
-
- ;** WRITE TRACK
- ;
- ; ENTRY: (BX)=POINTER TO BUFFER HEADER INFO
- ; EXIT: 'BUFERR[BX]'=STATUS
- ; 0=NO ERROR , 1=ERROR
- ; USES: AX,SI,DI
- ;
-
- WRT207:
- CALL SET207 ;SETUP
- CALL SDT207 ;SEEK DESIRED TRACK
- CALL S1S207 ;SET 1ST SECTOR TO WRITE
- MOV SI,BUFBUF[BX] ;BUFFER ADDRESS
- ADD SI,AX
-
- WRT2071:
- MOV DI,BUFSECF[BX] ;CHECK IF PHYSICAL SECTOR IS DIRTY
- ADD DI,PHYSEC
- TEST BYTE PTR [DI],1
- JZ WRT2073 ; BR IF IT IS NOT
-
- MOV BYTE PTR [DI],0 ;CLEAR DIRTY SECTOR FLAG
- CMP BUFERR[BX],0 ;Q. ABORT
- JNE WRT2073 ; BR IF YES -- SKIP PHYSICAL WRITE
- CALL WRS207 ;WRITE SECTOR
-
- WRT2073:
- ADD SI,COUNT ;SKIP BUFFER POINTER TO NEXT SECTOR
- INC PHYSEC ;BUMP PHYSICAL SECTOR #
- MOV AL,BYTE PTR PHYSEC ;CHECK IF SECTOR # WRAPAROUND
- CMP AL,SECCNT
- JB WRT2074 ; BR IF NOT
- XOR AX,AX ; OTHERWISE SET TO START
- MOV PHYSEC,AX
- MOV SI,BUFBUF[BX]
-
- WRT2074:
- CMP AL,SEC1ST ;CHECK IF ALL OF TRACK WRITTEN
- JNE WRT2071 ; BR IF NOT
-
- CALL WBS207 ;WAIT FOR WRITE GATE TURN OFF
-
- JMP DONE207 ;RETURN THRU 'DONE207'
-
-
-
-
- ;** MOUNT
- ;
- ; ENTRY: (BX)=POINTER TO BUFFER HEADER INFO
- ; EXIT: NONE
- ; USES: DI
- ;
-
- MNT207:
- MOV DI,BUFDPE[BX] ;SET TRACK POSITION TO UNKNOWN
- MOV DPETRK[DI],DPEUNK
-
- RET
-
-
-
-
-
- ;** FORMAT TRACK
- ;
- ; ENTRY: (BX)=POINTER TO BUFFER HEADER INFO
- ; 'FVFLG'=VERIFY FLAG
- ; 'DMAPTR'=ADDRESS OF TRACK IMAGE
- ; EXIT: 'ERROR'=ERROR STATUS
- ; USES: AX,CX,DX,SI
- ;
-
- FMT207:
- CALL SET207 ;SETUP
- CALL SDT207 ;SEEK DESIRED TRACK
-
- OR DSKOP,DSKOPF ;INDICATE FORMAT OPERATION IN PROGRESS
- CALL SRC207 ;SET RETRY COUNTER
-
- TEST DPEUNIT[BP],CONDS8 ;Q. TIME FOR SPECIAL CHECK
- JZ FMT2071 ; IF 8" DRIVE
- CMP PHYTRK,0 ; TRACK 0
- JNE FMT2071 ;
- CMP PHYSID,FDFSS1 ; SIDE 1
- JNE FMT2071 ; BR IF NOT
- IN AL,FDAS ;Q. IS DOUBLE SIDED DISKETTE INSERTED
- TEST AL,AS2S
- JNZ FMT2071 ; BR IF YES
- MOV AL,FDSNRD ; ELSE -- FLAGS AS NOT READY ERROR
- JMPS FMT2072
-
- FMT2071:
- MOV AL,PHYSID ;GET SIDE SELECT FLAG
- OR AL,FDCWRT ; OR IN COMMAND
- OR AL,HLDDLYF ; OR IN DELAY FLAG
- MOV HLDDLYF,0 ;ZERO DELAY FLAG FOR NEXT I/O
- MOV SI,DMAPTR ;GET ADDRESS OF TRACK IMAGE
- MOV CX,12000 ;USE LARGE COUNT
- MOV DX,ES ;DATA SEGMENT TO USE
- CALL WR207 ;USE LOW LEVEL WRITE ROUTINE
- TEST AL,AL ;Q. ERROR
- JZ FMT2073 ; BR IF NOT
-
- CALL WBS207 ;WAIT BEFORE STEPPING
-
- FMT2072:
- CALL ERR207 ;Q. SHOULD I RETRY
- JNC FMT2071 ; BR IF YES
- AND DSKOP,NOT DSKOPF ; OTHERWISE EXIT
- JMP FMT2074
-
- FMT2073:
- AND DSKOP,NOT DSKOPF ;INDICATE FORMAT OPERATION OVER
- CMP FVFLG,0 ;Q. SHOULD I VERIFY
- JZ FMT2074 ; BR IF NOT
- MOV PREREAD,0
- CALL RDT207 ;TRY READING TRACK
-
- FMT2074:
- JMP DONE207
-
-
-
-
- ;** WRITE PROTECT CHECK
- ;
- ; ENTRY: (BX)=ADDRESS OF BUFFER HEADER INFO
- ; EXIT: 'BUFERR[BX]'=STATUS
- ; 0=R/W , 1=R/O
- ; USES: AL,BP
- ;
-
- WPC207:
- MOV BP,BUFDPE[BX] ;GET ADDRESS OF DPE
- OR DSKOP,DSKOPWP ;INDICATE WRITE PROTECT OPERATION
- CALL DS207 ;SELECT DRIVE
-
- MOV AL,FDCFI+FDFINI ;FORCE TYPE 1 STATUS
- OUT FDCMD,AL
- PUSH AX
- MOV AX,(60+3)/4
- CALL WDLY
- POP AX
- WPC2071:
- IN AL,FDSTA ;WAIT FOR CONTROLLER NOT BUSY
- TEST AL,FDSBSY
- JNZ WPC2071
-
- AND AL,FDSWPV ;ISOLATE WRITE PROTECT BIT
- MOV AL,0 ;ASSUME R/W
- JZ WPC2072 ; BR IF R/W
- MOV AL,1 ;INDICATE R/O
-
- WPC2072:
- MOV BUFERR[BX],AL ;RETURN VALUE
-
- AND DSKOP,NOT DSKOPWP ;INDICATE WRITE PROTECT OP DONE
- JMP DONE207 ;RET VIA 'DONE207'
-
-
-
-
- ;** READY CHECK
- ;
- ; ENTRY: (BX)=ADDRESS OF BUFFER HEADER
- ; EXIT: 'BUFERR[BX]'=STATUS (0=NOT READY , 1=READY)
- ; USES: AL,DX,BP
- ;
-
- RDY207:
- MOV BP,BUFDPE[BX] ;GET ADDRESS OF DPE
- CALL RDY2070
- JMP DONE207
-
- RDY2070:
- MOV BUFERR[BX],0 ;ASSUME NOT READY
- OR DSKOP,DSKOPRD ;INDICATE READY CHECK IN PROGRESS
- CALL DS207 ;SELECT DRIVE
-
- MOV DX,5000/TINTRVL+1 ;COMPUTE TIMEOUT COUNT (5 SEC)
- ADD DX,TICCNT
-
- MOV AL,FDCFI+FDFII2 ;WAIT FOR INDEX HOLE TRANSITION
- OUT FDCMD,AL
- PUSH AX
- MOV AX,(60+3)/4
- CALL WDLY
- POP AX
-
- RDY2071:
- CMP DX,TICCNT ;Q. TIMEOUT
- JE RDY2073 ; BR IF YES
- IN AL,FDAS ;Q. INDEX HOLE FOUND
- TEST AL,ASIRQ
- JZ RDY2071 ; BR IF NOT
-
- RDY2072:
- IN AL,FDSTA ;WAIT FOR 1797 TO GO NOT BUSY
- TEST AL,FDSBSY
- JNZ RDY2072
-
- MOV BUFERR[BX],1 ;INDICATE DRIVE READY
-
- RDY2073:
- AND DSKOP,NOT DSKOPRD ;INDICATE READY CHECK DONE
-
- RET
-
-
-
-
-
- ;* READ SECTOR
- ;
- ; ENTRY: 'PHYSEC'=SECTOR #
- ; (DI)=BUFFER POINTER
- ; EXIT: (AL)=CONTROLLER STATUS
- ; USES: AL,CX
- ;
-
- RDS207:
- OR DSKOP,DSKOPR ;INDICATE READ OPERATION IN PROGRESS
- CALL SRC207 ;SET RETRY COUNTER
- MOV HSTPTR,DI ;SAVE BUFFER POINTER
-
- MOV AL,BYTE PTR PHYSEC ;GET SECTOR #
- INC AL ;PUT INTO RANGE 1 TO SPT
- OUT FDSEC,AL ;TELL CONTROLLER
-
- RDS2071:
- MOV AL,PHYSID ;GET SIDE SELECT VALUE
- OR AL,FDCRDS+FDFSLF ;FORM COMMAND
- OR AL,HLDDLYF ; OR IN DELAY FLAG
- MOV HLDDLYF,0 ;ZERO DELAY FOR NEXT I/O
- MOV CX,COUNT ;GET COUNT
- MOV DI,HSTPTR ;GET BUFFER POINTER
- CALL RD207 ;USE LOW LEVEL READ ROUTINE
- AND AL,NOT FDSRTE ;MASK ERROR CODE
- TEST AL,AL ;CHECK FOR ERROR
- JZ RDS2073 ; BR IF NO ERROR
-
- CALL ERR207 ;CHECK IF I SHOULD DO RETRY
- JNC RDS2071 ; BR IF YES
-
- CMP PREREAD,0 ;Q. IS THIS A PREREAD OPERATION
- JNE RDS2074 ; BR IF YES
- CALL ABTIGN ;HANDLE ABORT/IGNORE
-
- RDS2074:
- MOV AL,ERRTYP ;RESTORE ERROR CODE
-
- RDS2073:
- MOV DI,HSTPTR ;RESTORE BUFFER POINTER
- AND DSKOP,NOT DSKOPR ;INDICATE READ OPERATION DONE
- RET
-
-
-
-
- ;* LOW LEVEL READ ROUTINE
- ;
- ; ENTRY: (AL)=COMMAND
- ; (DI)=BUFFER POINTER
- ; (CX)=COUNT
- ; EXIT: (AL)=CONTROLLER STATUS
- ; USES: AX,CX,DI
- ;
-
- RD207:
- MOV AH,AL ;SAVE COMMAND
- IN AL,FDDAT ;CLEAR ANY PENDING DRQ
-
- IF WAIT
- MOV AL,DEVCTL ;ENABLE WAIT STATE I/O
- OR AL,CONWE
- OUT FDCON,AL
- ENDIF
-
- CLD ;FORWARD DIRECTION
- CALL EXDSES ;NEED ES: TO POINT TO MY BANK
-
- PUSHF ;DISABLE INTERRUPTS
- CLI
-
- MOV AL,AH ;RESTORE COMMAND
- OUT FDCMD,AL ;ISSUE COMMAND
-
- RD2071:
- IF NOT WAIT
- IN AL,FDAS ;WAIT FOR DRQ OR IRQ
- TEST AL,ASDRQ+ASIRQ
- JZ RD2071
- ENDIF
- IN AL,FDDAT ;GET DATA
- STOSB ;STORE IN BUFFER
- LOOP RD2071 ;LOOP AND READ
-
- POPF ;RESTORE INTERRUPT STATUS
-
- CALL EXDSES ;RESTORE DS: AND ES:
- CALL WAIT2071 ;WAIT FOR COMMAND COMPLETION
-
- IF WAIT
- MOV AH,AL ;SAVE CONTROLLER STATUS
- MOV AL,DEVCTL ;DISABLE WAIT STATE I/O
- OUT FDCON,AL
- MOV AL,AH ;RESTORE CONTROLLER STATUS
- ENDIF
-
- RET
-
-
-
-
- ;* RDA207 - READ ADDRESS
- ;
- ; ENTRY: (DI)=BUFFER ADDRESS
- ; EXIT: (AL)=CONTROLLER STATUS
- ; USES: AL,CX,DI
- ;
-
- RDA207:
- OR DSKOP,DSKOPRA ;SHOW READ ADDR OP IN PROGRESS
- MOV HSTPTR,DI ;SAVE BUFFER POINTER
-
- RDA2071:
- MOV AL,PHYSID ;GET SIDE FLAG VALUE
- OR AL,FDCRDA ; OR IN COMMAND
- OR AL,HLDDLYF ; OR IN DELAY FLAG
- MOV HLDDLYF,0 ;ZERO DELAY FOR NEXT I/O
- MOV CX,FDRAL ;COUNT
- MOV DI,HSTPTR ;GET BUFFER POINTER
- CALL RD207 ;USE LOW LEVEL READ ROUTINE
-
- AND DSKOP,NOT DSKOPRA ;INDICATE READ ADDRESS OP DONE
- RET
-
-
-
-
- ;* S1S - SET 1ST SECTOR
- ;
- ; ENTRY: NONE
- ; EXIT: (AX)=BUFFER DISPLACEMENT
- ; 'PHYSEC','SEC1ST'=1ST SECTOR #
- ; USES: AX,DI
- ;
-
- S1S207:
- LEA DI,RDABUF ;USE READ ADDRESS BUFFER
- CALL RDA207 ; TO DO READ ADDRESS OPERATION
- LEA DI,RDABUF ;GET ADDR OF READ ADDRESS INFO
- TEST AL,AL ;CHECK IF READ ADDRESS RETURN ERROR
- JZ S1S2071 ; BR IF NO ERROR
- MOV BYTE PTR FDRASEC[DI],0 ; OTHERWISE 0
-
- S1S2071:
- MOV AL,FDRASEC[DI] ;GET SECTOR #
- CMP AL,SECCNT ;CHECK IF LAST SECTOR ON TRACK
- JB S1S2072 ; BR IF NOT
- XOR AL,AL ; OTHERWISE 0
-
- S1S2072:
- MOV SEC1ST,AL ;SAVE AS 1ST SECTOR #
- CBW ;SET 'PHYSEC'
- MOV PHYSEC,AX
-
- MUL COUNT ;COMPUTE DISPLACEMENT
-
- RET
-
-
-
-
- ;* WRS207 - WRITE SECTOR
- ;
- ; ENTRY: 'PHYSEC'=SECTOR #
- ; (SI)=BUFFER POINTER
- ; EXIT: (AL)=CONTROLLER STATUS
- ; USES: AL,CX,DX
- ;
-
- WRS207:
- OR DSKOP,DSKOPW ;INDICATE WRITE OPERATION IN PROGRESS
- CALL SRC207 ;SET RETRY COUNTER
- MOV HSTPTR,SI ;SAVE BUFFER POINTER
-
- MOV AL,BYTE PTR PHYSEC ;GET SECTOR #
- INC AL ;PUT INTO RANGE 1 TO SPT
- OUT FDSEC,AL ;TELL CONTROLLER
-
- WRS2071:
- MOV AL,PHYSID ;GET SIDE SELECT VALUE
- OR AL,FDCWRS+FDFSLF ;FORM COMMAND
- OR AL,HLDDLYF ; OR IN DELAY FLAG
- MOV HLDDLYF,0 ;ZERO DELAY FOR NEXT I/O
- MOV CX,COUNT ;GET COUNT
- MOV SI,HSTPTR ;GET BUFFER POINTER
- MOV DX,DS ;DATA SEGMENT
- CALL WR207 ;USE LOW LEVEL WRITE ROUTINE
- TEST AL,AL ;CHECK FOR ERROR
- JZ WRS2073 ; BR IF NO ERROR
-
- CALL WBS207 ;WAIT FOR WRITE GATE TURN OFF
- CALL ERR207 ;CHECK IF I SHOULD DO RETRY
- JNC WRS2071 ; BR IF YES
- CALL ABTIGN ;ASK ABOUT ABORTING
- MOV AL,ERRTYP ;RESTORE ERROR CODE
-
- WRS2073:
- MOV SI,HSTPTR ;RESTORE BUFFER POINTER
- AND DSKOP,NOT DSKOPW ;INDICATE WRITE OP DONE
- RET
-
-
-
-
- ;* WR207 - LOW LEVEL WRITE ROUTINE
- ;
- ; ENTRY: (AL)=COMMAND
- ; (SI)=BUFFER POINTER
- ; (CX)=COUNT
- ; EXIT: (AL)=CONTROLLER STATUS
- ; USES: AX,CX,SI
- ;
-
- WR207:
- MOV AH,AL ;SAVE COMMAND
-
- MOV AL,FDSWPV ;ASSUME WRITE PROTECT VIOLATION
- TEST DPEFLAG[BP],DPE48RO ;CHECK FOR 48 TPI R/O DISK
- JNZ WR2072 ; BR IF IT IS
-
- IN AL,FDDAT ;CLEAR ANY PENDING DRQ
-
- IF WAIT
- MOV AL,DEVCTL ;ENABLE WAIT STATE I/O
- OR AL,CONWE
- OUT FDCON,AL
- ENDIF
-
- PUSHF ;DISABLE INTERRUPTS
- CLI
-
- CLD ;FORWARD DIRECTION
- PUSH DS ;GET DATA SEGMENT
- MOV DS,DX
-
- MOV AL,AH
- OUT FDCMD,AL ;ISSUE COMMAND
-
- WR2071:
- IF NOT WAIT
- IN AL,FDAS ;WAIT FOR DRQ OR IRQ
- TEST AL,ASDRQ+ASIRQ
- JZ WR2071
- ENDIF
- LODSB ;GET DATA
- OUT FDDAT,AL ;SEND TO DISK
- LOOP WR2071 ;LOAD AND WRITE
-
- POP DS ;RESTORE DATA SEGMENT
- POPF ;RESTORE INTERRUPT STATUS
-
- CALL WAIT2071 ;WAIT FOR COMMAND COMPLETION
-
- IF WAIT
- MOV AH,AL ;SAVE CONTROLLER STATUS
- MOV AL,DEVCTL ;DISABLE WAIT STATE I/O
- OUT FDCON,AL
- MOV AL,AH ;RESTORE CONTROLLER STATUS
- ENDIF
-
- WR2072:
- RET
-
-
-
-
-
- ;* DONE WITH 207
- ;
- ; ENTRY: NONE
- ; EXIT: NONE
- ; USES: AL
- ;
-
- DONE207:
- MOV AL,PHYSID ;SAVE SIDE SELECT VALUE
- CMP BUFERR[BX],0 ;Q. DID ERROR OCCUR
- JZ DONE2071 ; BR IF NOT
- MOV AL,FDFSS1
- DONE2071:
- MOV SIDE207,AL
-
- XOR AL,AL ;DESELECT DRIVE
- OUT FDCON,AL
- MOV DEVCTL,AL
-
- TEST DPEFLG2[BP],DPEHLS ;Q. DRIVE HAS HEAD LOAD SELONOID
- JZ DONE2072 ; BR IF NOT
- PUSH AX
- MOV AX,35*250 ;WAIT DRIVE DESELECT TIME
- CALL WDLY
- POP AX
-
- DONE2072:
- RET
-
-
-
-
- ;* SET UP DEVICE
- ;
- ; ENTRY: (BX)=POINTER TO BUFFER HEADER INFO
- ; EXIT: (BP)=ADDRESS OF DPE
- ; 'PHYTRK'=PHYSICAL TRACK #
- ; 'PHYSID'=PHYSICAL SIDE #
- ; 'SECCNT'=# SECTORS PER TRACK
- ; 'COUNT'=# BYTES PER SECTOR
- ; DRIVE IS SELECTED
- ; USES: AX,BP,SI
- ;
-
- SET207:
- MOV BP,BUFDPE[BX] ;GET ADDRESS OF DPE
-
- ; COMPUTE PHYSICAL TRACK AND SIDE VALUES
-
- MOV AL,BYTE PTR BUFTRK[BX] ;GET CP/M TRACK #
- MOV PHYSID,0 ;ASSUME SIDE 0
- MOV PHYSIDN,0
- TEST DPEFLAG[BP],DPE2S
- JZ SET2071A ;BR IF NOT DOUBLE SIDED MEDIA
- SHR AL,1 ;DIVIDE TRACK # BY 2
- JNC SET2071A ;EVEN TRACKS ON SIDE 0
- MOV PHYSID,FDFSS1 ; ODD TRACKS ON SIDE 1
- MOV PHYSIDN,1
- SET2071A:
- MOV PHYTRK,0 ;INSURE HIGH ORDER BYTE IS 0
- MOV BYTE PTR PHYTRK,AL ;SAVE PHYSICAL TRACK #
-
- ; CHECK FOR SPECIAL CASE OF 8" DRIVE, TRACK 0, SIDE 0
-
- CMP BYTE PTR PHYTRK,0 ;CHECK IF TRACK 0
- JNE SET2072 ; BR IF NOT
- CMP PHYSID,0 ;CHECK IF SIDE 0
- JNE SET2072 ; BR IF NOT
- TEST DPEFLAG[BP],DPET0SD ;CHECK IF TRACK 0 SINGLE DENSITY
- JZ SET2072 ; BR IF NOT
-
- MOV SECCNT,26 ;26 PHYSICAL SECTORS PER TRACK
- MOV COUNT,128 ;128 BYTES PER PHYSICAL SECTOR
- JMPS SET2073
-
- ; COMPUTE NUMBER OF SECTORS PER TRACK
-
- SET2072:
- MOV SI,DPEDPB[BP]
- MOV AX,DPBSPT[SI]
- DIV DPERPS[BP]
- MOV SECCNT,AL
-
- ; COMPUTE NUMBER OF BYTES PER SECTOR
-
- MOV AL,128
- MUL DPERPS[BP]
- MOV COUNT,AX
-
- ;
-
- SET2073:
- CALL DS207 ;SELECT DRIVE
-
- ; SET TRACK REGISTER IN CONTROLLER
-
- MOV AL,DPETRK[BP] ;GET TRACK POSITION
- OUT FDTRK,AL ;SET TRACK REGISTER
- TEST AL,DPEUNK ;CHECK IF UNKNOWN
- JZ SET2074 ; BR IF KNOWN
- CALL RST207 ;RESTORE HEAD
-
- ;
-
- SET2074:
- RET
-
-
-
-
-
- ;* SET I/O RETRY COUNTER
- ;
- ; ENTRY: NONE
- ; EXIT: 'RETRIES' SET
- ; USES: NONE
- ;
-
- SRC207:
- MOV RETRIES,12 ;ASSUME 12
- TEST DSKOP,DSKOPRA+DSKOPS ;CHECK IF SPECIAL CASE
- JZ SRC2071 ; BR IF NOT
- MOV RETRIES,4 ;ALLOW ONLY 4 RETRIES
- SRC2071:
- RET
-
-
-
-
-
- ;* DRIVE SELECT
- ;
- ; ENTRY: NONE
- ; EXIT: DRIVE SELECTED AND UP TO SPEED
- ; USES: AX,CX
- ;
-
- DS207:
- MOV HLDDLYF,0 ;ASSUME ZERO DELAY
-
- ; FORM CONTROL WORD
-
- MOV AL,DPEUNIT[BP] ;GET UNIT SELECT FROM DPE
- OR AL,CONDSEN ;DRIVE SELECT ENABLE
- TEST DPEFLAG[BP],DPEDD ;Q. DOUBLE DENSITY
- JZ DS2070 ; BR IF NOT
-
- CMP BYTE PTR PHYTRK,0 ;CHECK FOR SPECIAL CASE
- JNE DS2071 ; WHERE TRACK 0 SIDE 0
- CMP PHYSID,0 ; SINGLE DENSITY WHILE THE
- JNE DS2071 ; REST IS DOUBLE DENSITY
- TEST DPEFLAG[BP],DPET0SD
- JZ DS2071 ;BR IF NOT SPECIAL CASE
-
- DS2070:
- OR AL,CONSD ;SET FOR SINGLE DENSITY
-
- ;
-
- DS2071:
- MOV AH,AL ;(AH)=NEW CONTROL WORD
-
- TEST DPEFLG2[BP],DPEHLS ;Q. DRIVE HAS HEAD LOAD SELONOID
- JZ DS2071A ; BR IF NOT
- AND AL,CONDSEN+CONDS8+CONDS ;ISOLATE DRIVE SELECT BITS IN NEW
- MOV CL,DEVCTL ;ISOLATE DRIVE SELECT
- AND CL,CONDSEN+CONDS8+CONDS ; BITS IN OLD CONTROL WORD
- CMP AL,CL ;Q. SAME DRIVE STILL SELECTED
- JE DS2071A ; BR IF YES
-
- IN AL,FDTRK ;NEW DRIVE SELECTED - CAUSE 1797
- OUT FDDAT,AL ; TO RESET HEAD LOAD DELAY TIMER
- MOV AL,FDCSEK ; BY DOING ZERO LENGTH SEEK WITH
- CALL WAIT207 ; HEAD UNLOADED
- MOV HLDDLYF,FDFDLF ;USE DELAY FOR NEXT I/O
-
- DS2071A:
- TEST AH,CONDS8 ;CHECK IF SELECTING 8" DRIVE
- JNZ DS2075 ; BR IF 8"
-
- ; SELECT 5 1/4" DRIVE
-
- AND AH,NOT CONPC ;ASSUME PRE-COMP
- TEST DPEFLAG[BP],DPE96T ;Q. 96 TPI DRIVE
- JNZ DS2072 ; BR IF YES
- CMP BYTE PTR PHYTRK,23 ;Q. TRACK >= 23 ON 48 TPI DRIVE
- JAE DS2072 ; BR IF YES
- OR AH,CONPC ;DON'T USE PRE-COMP
- DS2072:
-
- MOV AL,AH ;SELECT DRIVE
- OUT FDCON,AL
-
- ; HANDLE MOTOR START UP DELAY FOR 5 1/4" DRIVE
-
- TEST DSKOP,DSKOPWP+DSKOPI ;Q. WAIT FOR MOTOR UP TO SPEED
- ; JNZ DS2079 ; BR IF NO
- JZ $+5
- JMP DS2079
- MOV AL,DEVCTL ;CHECK IF A 5 1/4" DRIVE
- AND AL,CONDSEN+CONDS8 ; IS ALREADY SELECTED
- CMP AL,CONDSEN
- ; JE DS2079 ; BR IF YES
- JNE $+5
- JMP DS2079
- IN AL,FDAS ;SEE IF MOTOR STILL RUNNING
- TEST AL,ASMO
- ; JNZ DS2079 ; BR IF IT IS
- JZ $+5
- JMP DS2079
-
- MOV CX,250/TINTRVL+1 ;WAIT FOR 250 mS
- TEST DPESEK[BP],DPEMO ;CHECK IF FAST MOTOR UP TO SPEED
- JNZ DS2073 ; BR IF YES
- MOV CX,1000/TINTRVL+1 ;WAIT FOR 1 SEC
- DS2073:
- ADD CX,TICCNT
- DS2073A:
- CMP CX,TICCNT
- JNE DS2073A
-
- JMPS DS2079
-
- ; SELECT 8" DRIVE
- ;
- ; SINCE THE 1797 CHECKS THE DRIVE READY STATUS LINE BEFORE PLACING
- ; THE VALUE OF THE SIDE SELECT ON ITS OUTPUT PIN, IT MAY BE NECESSARY
- ; TO FORCE THE 1797 TO PLACE A SIDE SELECT VALUE ACCEPTABLE TO THE
- ; DRIVE BEFORE PRECEDING. THIS SITUATION ARISES WHEN
- ; 1. A PREVIOUS 1797 COMMAND SELECTED SIDE 1
- ; 2. THE MEDIA IS NOT DOUBLE SIDED
- ; WHAT HAPPENS IS SOME DRIVES INDICATE DRIVE READY AS
- ; 1. MEDIA INSERTED
- ; 2. DOOR CLOSED
- ; 3. SIDE SELECTED IS AVAILABLE
-
- DS2075:
- MOV AL,AH ;SELECT DRIVE
- OUT FDCON,AL
-
- TEST DSKOP,DSKOPWP+DSKOPI+DSKOPRD ;Q. SKIP
- JNZ DS2079 ; BR IF YES
-
- CMP PHYSID,FDFSS1 ;Q. WISH TO USE SIDE 1
- JE DS2078
-
- IN AL,FDAS ;CHECK IF DOUBLE SIDED MEDIA
- TEST AL,AS2S
- JNZ DS2078 ; BR IF DOUBLE SIDED MEDIA
-
- CMP SIDE207,FDFSS1 ;CHECK IF SIDE 1 SELECTED PREVIOUSLY
- JNE DS2078 ; BR IF NOT
-
- XOR AL,AL ;DESELECT DRIVE
- OUT FDCON,AL
-
- PUSH AX
- MOV AL,FDCRDA+FDFDLF ;USE READ ADDRESS COMMAND
- OUT FDCMD,AL ; TO FORCE SIDE 0 SELECT
- MOV AX,(60+3)/4 ;DELAY TO GIVE STATUS A CHANCE
- CALL WDLY
- DS2076:
- IN AL,FDSTA ;WAIT UNTIL 1797 GOES BUSY
- TEST AL,FDSBSY
- JZ DS2076
- MOV AL,FDCFI+FDFINI ;TERMINATE COMMAND
- OUT FDCMD,AL
- MOV AX,(60+3)/4 ;DELAY TO GIVE STATUS A CHANCE
- CALL WDLY
- DS2077:
- IN AL,FDSTA ;WAIT UNTIL 1797 GOES NOT BUSY
- TEST AL,FDSBSY
- JNZ DS2077
- IN AL,FDDAT ;FLUSH ANY DATA IN 1797
-
- POP AX
- MOV AL,AH ;RESELECT DRIVE
- OUT FDCON,AL
-
- ; WAIT FOR MOTOR UP TO SPEED. DRIVE WILL INDICATE READY WHEN
- ; UP TO SPEED. THIS IS DONE TO ACCOMODATE DRIVES WITH DC MOTORS.
-
- DS2078:
- PUSH AX
- MOV AL,FDCFI+FDFINI ;FORCE TYPE 1 STATUS
- OUT FDCMD,AL
- MOV AX,(60+3)/4 ;DELAY TO GIVE STATUS A CHANCE
- CALL WDLY
- DS2078A:
- IN AL,FDSTA ;WAIT UNITL 1797 GOES NOT BUSY
- TEST AL,FDSBSY
- JNZ DS2078A
-
- MOV CX,1000/TINTRVL+1 ;WAIT 1 SEC MAX
- ADD CX,TICCNT
-
- DS2078B:
- CMP CX,TICCNT ;Q. TIME UP
- JE DS2078C ; BR IF YES
- IN AL,FDSTA
- TEST AL,FDSNRD ;Q. DRIVE READY
- JNZ DS2078B ; BR IF NOT
-
- DS2078C:
- POP AX
-
- ;
-
- DS2079:
- MOV DEVCTL,AH ;SAVE CONTROL REGISTER IMAGE
-
- RET
-
-
-
-
- ;* ISSUE COMMAND AND WAIT FOR I/O COMPLETION
- ;
- ; ENTRY: (AL)=COMMAND
- ; EXIT: (AL)=CONTROLLER STATUS
- ; USES: AL
- ;
-
- WAIT207:
- OUT FDCMD,AL ;ISSUE COMMAND
- PUSH AX ;WAIT AT LEAST 60uS
- MOV AX,(60+3)/4 ; BEFORE CHECKING STATUS
- CALL WDLY
- POP AX
-
- WAIT2071:
- IN AL,FDAS ;WAIT FOR IRQ
- TEST AL,ASIRQ
- JZ WAIT2071
-
- WAIT2073:
- IN AL,FDSTA ;GET CONTROLLER STATUS
- TEST AL,FDSBSY ;WAIT FOR NOT BUSY
- JNZ WAIT2073
-
- RET
-
-
-
-
- ;* CHECK IF TO DO RETRIES
- ;
- ; ENTRY: (AL)=CONTROLLER STATUS
- ; 'RETRIES'=RETRY COUNTER
- ; EXIT: PSW/C=RETRY STATUS (0=RETRY , 1=NO RETRY)
- ; USES: AL,DI
- ;
- ; I/O RECOVERY PROCEDURE:
- ; 1) RETRY I/O OPERATION
- ; 2) STEP HEAD IN/OUT 1 TRACK, THEN RETRY I/O OPERATION
- ; 3) RETRY I/O OPERATION
- ; 4) STEP HEAD OUT/IN 1 TRACK, THEN RETRY I/O OPERATION
- ; 5) RETRY I/O OPERATION
- ; 6) RESTORE HEAD/RE-SEEK, THEN RETRY I/O OPERATION
- ; 7) RETRY I/O OPERATION
- ; 8) STEP HEAD IN/OUT 1 TRACK, THEN RETRY I/O OPERATION
- ; 9) RETRY I/O OPERATION
- ; 10) STEP HEAD OUT/IN 1 TRACK, THEN RETRY I/O OPERATION
- ; 11) RETRY I/O OPERATION
- ; 12) FLAG AS HARD ERROR
- ;
-
- ERR207:
- MOV ERRTYP,AL ;SAVE CONTROLLER STATUS AS ERROR TYPE
-
- TEST AL,FDSNRD+FDSWPV ;CHECK FOR NOT READY OR WRITE PROTECT
- JNZ ERR2079 ; BR IF YES - NO RETRIES
-
- TEST DSKOP,DSKOPS ;IF NOT DOING A SELECT OPERATION
- JNZ ERR2071
- MOV DI,BBIOS ; BUMP SOFT ERROR COUNTER
- INC SECNT[DI]
-
- ERR2071:
- DEC RETRIES ;UPDATE RETRY COUNTER
- JZ ERR2079 ; BR IF EXHAUSTED RETRIES
-
- MOV AL,RETRIES
- CMP AL,6
- JA ERR2072
- SUB AL,6
- ERR2072:
- JNZ ERR2073 ;BR IF NOT TIME TO DO RESTORE HEAD
- CALL RST207 ;RESTORE HEAD BEFORE TRYING AGAIN
- JMPS ERR2077
-
- ERR2073:
- CMP AL,4 ;CHECK IF TIME TO STEP OUT
- JNE ERR2074 ; BR IF NOT
- DEC BYTE PTR PHYTRK ;DECREMENT TO NEXT TRACK
- JS ERR2073A ; BR IF BEFORE TRACK 0
- CALL SDT207 ; OTHERWISE STEP OUT
- ERR2073A:
- INC BYTE PTR PHYTRK ;RESTORE DESIRED TRACK
- JMPS ERR2077
-
- ERR2074:
- CMP AL,2 ;CHECK IF TIME TO STEP IN
- JNE ERR2078 ; BR IF NOT
- MOV AL,NTRK837-1 ;GET MAXIMUM TRACK #
- TEST DPEUNIT[BP],CONDS8
- JNZ ERR2074A
- MOV AL,NTRKD37-1
- TEST DPEFLAG[BP],DPE96T
- JNZ ERR2074A
- MOV AL,NTRKS37-1
- ERR2074A:
- INC BYTE PTR PHYTRK ;INCREMENT TO NEXT TRACK
- CMP AL,BYTE PTR PHYTRK ;CHECK IF MAX TRACK # >= NEXT TRACK
- JB ERR2074B ; BR IF IT IS
- CALL SDT207 ; OTHERWISE STEP IN
- ERR2074B:
- DEC BYTE PTR PHYTRK ;RESTORE DESIRED TRACK
-
- ERR2077:
- CALL SDT207 ;SEEK DESIRED TRACK
-
- ERR2078:
- CLC ;INDICATE TRY AGAIN
- RET
-
- ERR2079:
- MOV BUFERR[BX],1 ;SET ERROR FLAG
- MOV AL,ERRTYP ;RECOVER CONTROLLER STATUS
-
- TEST DSKOP,DSKOPR+DSKOPW ;IF DOING READ OR WRITE OPERATION
- JZ ERR2079B
- MOV DI,BUFERRF[BX] ; PLACE IN ERROR ARRAY
- ADD DI,PHYSEC
- MOV [DI],AL
- JMPS ERR2079D
-
- ERR2079B:
- TEST DSKOP,DSKOPF ;Q. FORMAT OPERATION
- JZ ERR2079C ; BR IF NO
- TEST DEVCTL,CONDS8 ;Q. 8" DRIVE
- JZ ERR2079C ; BR IF NOT
- CMP PHYTRK,0 ;Q. TRACK 0
- JNE ERR2079C ; BR IF NOT
- CMP PHYSID,FDFSS1 ;Q. SIDE 1
- JNE ERR2079C ; BR IF NOT
- CMP ERRTYP,FDSNRD ;Q. NOT READY ERROR
- JE ERR2079E ; BR IF YES
-
- ERR2079C:
- CALL ERRRPT ; OTHERWISE REPORT ERROR IMMEDIATELY
-
- ERR2079D:
- TEST DSKOP,DSKOPS ;IF NOT DOING A SELECT OPERATION
- JNZ ERR2079E
- MOV DI,BBIOS ; COUNT HARD ERROR
- INC HECNT[DI]
-
- ERR2079E:
- STC ;INDICATE DON'T TRY AGAIN
- RET
-
-
-
-
- ;* RESTORE HEAD
- ;
- ; ENTRY: NONE
- ; EXIT: (AL)=CONTROLLER STATUS
- ; USES: AX
- ;
-
- RST207:
- MOV DPETRK[BP],0 ;INDICATE TRACK # 0
-
- TEST DPESEK[BP],DPEFS ;Q. CAN DRIVE FAST STEP
- JZ RST2071 ; BR IF NOT
- MOV AL,DEVCTL ;SET UP FAST STEP
- OR AL,CON5FS
- OUT FDCON,AL
-
- RST2071:
- MOV AL,DPESEK[BP] ;GET STEP RATE
- AND AL,FDFSRM
- OR AL,FDCRST ;RESTORE HEAD COMMAND
- CALL WAIT207 ;DO RESTORE
- PUSH AX ;WAIT FOR MECHANICAL DELAY
- MOV AX,15*250
- CALL WDLY
- POP AX
- TEST DSKOP,DSKOPI ;Q. INIT OPERATION
- JZ RST2072 ; BR IF NOT
- TEST AL,FDSTK0 ;Q. AT TRACK 0
- JZ RST2073 ; BR IF NOT
-
- RST2072:
- MOV AL,10 ;STEP IN 10 TRACKS
- CALL SDT2077
-
- MOV AL,FDCRST+FDFHLB+FDFS30 ;RESTORE HEAD COMMAND
- CALL WAIT207 ;DO RESTORE
- PUSH AX ;WAIT FOR MECHANICAL DELAY
- MOV AX,15*250
- CALL WDLY
- POP AX
-
- RST2073:
- MOV AH,AL ;SAVE CONTROLLER STATUS
- MOV AL,DEVCTL ;TURN OFF FAST STEP
- OUT FDCON,AL
- MOV AL,AH ;RESTORE CONTROLLER STATUS
-
- MOV HLDDLYF,FDFDLF ;USE DELAY FOR NEXT I/O
- RET
-
-
-
-
- ;* SEEK DESIRED TRACK
- ;
- ; ENTRY: 'PHYTRK'=TRACK #
- ; EXIT: NONE
- ; USES: AL
- ;
-
- SDT207:
- MOV AL,DPETRK[BP] ;GET CURRENT TRACK
- CMP AL,BYTE PTR PHYTRK ;CHECK AGAINST DESIRED TRACK
- JE SDT2072 ;ALREADY AT DESIRED TRACK
-
- TEST DPESEK[BP],DPEFS ;CHECK FOR FAST STEP
- JZ SDT2070 ; BR IF NOT
- MOV AL,DEVCTL ;ENABLE FAST STEP
- OR AL,CON5FS
- OUT FDCON,AL
-
- SDT2070:
- CALL SDT2076 ;DO SEEK
-
- TEST DPEFLAG[BP],DPE48RO ;CHECK IF 48TPI R/O MEDIA
- JZ SDT2071 ; BR IF NOT -- NO NEED TO DOUBLE STEP
-
- MOV AL,DPETRK[BP] ;GO THROUGH SEEK PROCEDURE AGAIN A SECOND TIME
- OUT FDTRK,AL ;RESET CONTROLLER'S TRACK REG
- CALL SDT2076 ;DO 2ND SEEK
-
- SDT2071:
- MOV AL,BYTE PTR PHYTRK ;OUTPUT DESIRED TRACK TO TRACK REG
- OUT FDTRK,AL ; THIS IS DONE IN CASE SEEK ABORTED
- ; WHEN IT TRIED TO STEP TO NEGATIVE
- ; TRACK LEAVING TRACK REGISTER
- ; CONTAINING 0
-
- MOV DPETRK[BP],AL ;UPDATE IN MEMORY TRACK VALUE
-
- MOV AL,DEVCTL ;RESTORE CONTROL REGISTER
- OUT FDCON,AL ; INCASE I WAS FAST STEPPING
-
- SDT2072:
- MOV HLDDLYF,FDFDLF ;USE DELAY FOR NEXT I/O
- RET
-
- ; DO SEEK
-
- SDT2076:
- MOV AL,BYTE PTR PHYTRK ;TELL CONTROLLER DESIRED TRACK
- SDT2077:
- OUT FDDAT,AL
-
- MOV AL,DPESEK[BP] ;GET STEP RATE
- AND AL,FDFSRM
- OR AL,FDCSEK+FDFHLB ; OR IN COMMAND
- CALL WAIT207 ;DO I/O
-
- PUSH AX ;WAIT FOR MECHANICAL DELAY
- MOV AX,15*250
- CALL WDLY
- POP AX
-
- RET
-
-
-
-
- ;* WAIT ~1.5 mS BEFORE STEPPING
- ;
- ; ENTRY: NONE
- ; EXIT: NONE
- ; USES: NONE
- ;
-
- WBS207:
- PUSH AX
- MOV AX,250*3/2+1
- CALL WDLY
- POP AX
- RET
-