;*** Z217 DEVICE DRIVER ; ; * * * N O T E * * * ; ; THIS DRIVE ASSUMES A CELL SIZE OF 512 BYTES WITH 18 SECTORS PER TRACK. ; ; ONLY UNIT 0 IS HANDLED. ; ; ALTHOUGH THE CONTROLLER PROVIDES FOR 21 BIT LOGICAL SECTOR NUMBERS, ; THIS DRIVER ONLY HANDLES 16 BIT LOGICAL SECTOR NUMBERS. THEREFORE, ; THE MAXIMUM SIZE OF DISK IS 65536 SECTORS (0-FFFFH). ; NOLIST ; ; RESTRICTED RIGHTS LEGEND ; ------------------------ ; ; "Use, duplication, or disclosure by the ; government is subject to restrictions as set forth ; in paragraph (b) (3) (B) of the Rights in Technical ; Data and Computer Software clause in DAR ; 7-104.9(a). Contractor/manufacturer is Zenith ; Data Systems Corporation of Hilltop Road, St. ; Joseph, Michigan 49085. ; LIST ;** DRIVER ENTRY JUMP VECTORS ; DRVR217: JMP SEL217 ;SELECT JMP RDT217 ;READ TRACK JMP WRT217 ;WRITE TRACK JMP MNT217 ;MOUNT JMP FMT217 ;FORMAT JMP WPC217 ;WRITE PROTECT CHECK ;** INITIALIZE DRIVE TABLES ; ; ENTRY: NONE ; EXIT: NONE ; USES: ALL ; IN217: ; FILL IN COMMAND BLOCK LEA DI,Z217BLK ;ADDRESS OF NEXT COMMAND MOV AX,DS MOV ES,AX CALL TMA217 MOV AL,Z217BLK+OFFSET WI01HT MOV Z217BLK+OFFSET WI01HN,AL MOV AL,Z217BLK+OFFSET WI01MT MOV Z217BLK+OFFSET WI01MN,AL MOV AL,Z217BLK+OFFSET WI01LT MOV Z217BLK+OFFSET WI01LN,AL ; CHECK IF CONTROLLER IS PRESENT LEA DI,Z217BLK ;ATTEMPT TO ISSUE SETUP COMMAND MOV AX,DS MOV ES,AX CALL SUP217 JC IN2174 ; BR IF ERROR ; READ SBC AND SET DRIVE PARAMETERS LES DI,DWORD PTR HEADER+OFFSET BUFBUF ;GET BUFFER ADDRESS CALL TMA217 CALL WAIT2171 ;EXECUTE READ COMMAND TEST AL,WISERR ;Q. ERROR JNZ IN2174 ; BR IF ERROR LES DI,DWORD PTR HEADER+OFFSET BUFBUF ;ADDRESS OF SET DRIVE ADD DI,OFFSET SBCSDP ; PARAMETERS COMMAND CALL SUP217 JC IN2174 ; BR IF ERROR CALL WAIT2171 ;EXECUTE COMMAND TEST AL,WISERR ;Q. ERROR JNZ IN2174 ; BR IF ERROR LEA DI,Z217BLK ;ADDRESS FOR REST OF DRIVER MOV AX,DS MOV ES,AX CALL SUP217 JNC IN2175 ; BR IF NO ERROR ; MARK DRIVE AS IMAGINARY IN2174: MOV CX,2 ;# OF Z217 DRIVES LEA BP,DPEBASE+DPEL*4 ;START ADDRESS OF Z217 DPE'S IN21741: OR DPEFLG2[BP],DPEIMG ;FLAG DRIVE AS IMAGINARY ADD BP,DPEL ;BUMP POINTER LOOP IN21741 ;LOOP AND MARK ALL DRIVES ; FILL IN DPE TABLES / DISK MAP TABLE IN2175: MOV CH,2 ;# DRIVES MOV CL,0 ;STARTING UNIT # MOV DH,4 ;STARTING DRIVE MAP # CALL CBTFIL ;DO FILL ; ASSIGN PARTITION IF BOOT UNIT XOR AX,AX MOV ES,AX MOV ES,ES: .MTRDSEG ;GET ADDRESS OF MONITOR DATA AREA CMP ES: MTRBI,2 ;Q. Z217 BOOTED JNE IN2176 ; BR IF NOT LEA BP,DPEBASE+4*DPEL ;GET ADDRESS OF 1ST DPE FOR Z217 OR DPEFLAG[BP],DPEASGN ;SHOW PARTITION ASSIGNED MOV AX,Z217BP MOV WORD PTR DPETRK[BP],AX ;SET BEGINNING SECTOR OF PARTITION MOV AX,Z217EP MOV WORD PTR DPEUPB[BP],AX ;SET LAST SECTOR # OF PARTITION IN2176: RET ;** SELECT DRIVE FOR 1ST LOGIN ; ; ENTRY: 'PHYDPE'=ADDRESS OF DPE FOR DRIVE ; (BX)=POINTER TO BUFFER HEADER INFO ; EXIT: 'PHYDPE'=STATUS ; 0=ERROR , OTHERWISE SAME AS ON ENTRY ; USES: SI,DI ; SEL217: OR DSKOP,DSKOPS ;INDICATE SELECT OP IN PROGRESS MOV BUFTRK[BX],0 ;READ LABEL CALL SET217 LES DI,DWORD PTR BUFBUF[BX] CALL RDS217 CMP BUFERR[BX],0 ;Q. ERROR JNZ SET2179 ; BR IF YES LES SI,DWORD PTR BUFBUF[BX] ;CHECK CHECKSUM OF LABEL ADD SI,LABEL CALL CHKLAB JNZ SET2179 ; BR IF ERROR LES SI,DWORD PTR BUFBUF[BX] ;CHECK IF LABEL'S BEGINNING OF MOV DI,ES: WORD PTR LABHTH+(OFFSET DPETRK)-(OFFSET DPEHTH) [SI] CMP DI,WORD PTR DPETRK[BP] ;PARTITION SECTOR # MATCHES DRIVE TABLE JNE SET2179 ; BR IF NOT MOV DI,ES: WORD PTR LABHTH+(OFFSET DPEUPB)-(OFFSET DPEHTH) [SI] CMP DI,WORD PTR DPEUPB[BP] ;CHECK IF LABEL'S LAST SECTOR # OF ; PARTITION MATCHES DRIVE TABLE JNE SET2179 ; BR IF NOT MOV AL,ES: LABHTH+(OFFSET DPERPAB)-(OFFSET DPEHTH) [SI] MOV DPERPAB[BP],AL ;CP/M RECORDS PER ALLOCATION BLOCK ADD SI,OFFSET LABDPB ;UPDATE DISK PARAMETER BLOCK VALUES MOV DI,DPEDPB[BP] MOV CX,DPBL CLD CALL EXDSES REP MOVSB CALL EXDSES SET2178: AND DSKOP,NOT DSKOPS ;INDICATE SELECT OP COMPLETE RET SET2179: MOV PHYDPE,0 ;INDICATE ERROR JMPS SET2178 ;** READ TRACK ; ; ENTRY: (BX)=POINTER TO BUFFER HEADER INFO ; EXIT: 'BUFERR[BX]=STATUS ; 0=NO ERROR , 1=ERROR ; USES: DI ; RDT217: CALL SET217 ;SETUP LES DI,DWORD PTR BUFBUF[BX] ;BUFFER ADDRESS RDT2171: CMP PREREAD,0 ;Q. DOING PREREAD JNE RDT2172 ; BR IF YES CMP BUFERR[BX],0 ;Q. ABORT JNE RDT2173 ; BR IF YES RDT2172: CALL RDS217 ;READ NEXT SECTOR RDT2173: ADD DI,WICSZ ;BUMP BUFFER POINTER INC PHYSEC ;BUMP 'PHYSEC' CMP PHYSEC,WINSPT ;Q. ALL SECTORS READ JNE RDT2171 ; BR IF NOT RET ;** WRITE TRACK ; ; ENTRY: (BX)=POINTER TO BUFFER HEADER INFO ; EXIT: 'BUFERR[BX]'=STATUS ; 0=NO ERROR , 1=ERROR ; USES: AX,SI,DI ; WRT217: CALL SET217 ;SETUP LES DI,DWORD PTR BUFBUF[BX] ;BUFFER ADDRESS WRT2171: MOV SI,BUFSECF[BX] ;CHECK IF PHYSICAL SECTOR IS DIRTY ADD SI,PHYSEC TEST BYTE PTR [SI],1 JZ WRT2173 ; BR IF IT IS NOT MOV BYTE PTR [SI],0 ;CLEAR DIRTY SECTOR FLAG CMP BUFERR[BX],0 ;Q. ABORT JNE WRT2173 ; BR IF YES CALL WRS217 ;WRITE SECTOR WRT2173: ADD DI,WICSZ ;BUMP BUFFER POINTER TO NEXT SECTOR INC PHYSEC ;BUMP PHYSICAL SECTOR # CMP PHYSEC,WINSPT ;Q. ALL TRACK WRITTEN JNE WRT2171 ; BR IF NOT RET ;** MOUNT ; ; ENTRY: (BX)=POINTER TO BUFFER HEADER INFO ; EXIT: NONE ; USES: NONE ; MNT217: RET ;** FORMAT TRACK ; ; ENTRY: NONE ; EXIT: NONE ; USES: NONE ; FMT217: RET ;** WRITE PROTECT CHECK ; ; ENTRY: (BX)=ADDRESS OF BUFFER HEADER INFO ; EXIT: 'BUFERR[BX]'=STATUS ; 0=R/W , 1=R/O ; USES: NONE ; WPC217: MOV BUFERR[BX],0 ;ALWAYS R/W RET ;* READ SECTOR ; ; ENTRY: 'PHYSEC'=PHYSICAL SECTOR # ; 'SEC217'=STARTING LOGICAL SECTOR # OF TRACK ; (DI),(ES)=BUFFER POINTER ; EXIT: NONE ; USES: AL ; RDS217: OR DSKOP,DSKOPR ;INDICATE READ OP IN PROGRESS MOV HSTPTR,DI ;SAVE BUFFER POINTER MOV HSTPTR+2,ES MOV Z217BLK+OFFSET WI01OP,WIRDL ;READ LOGICAL OP CODE CALL CLS217 ;CALCULATE LOGICAL SECTOR # JC RDS2172 ; BR IF ERROR CALL TMA217 ;CALCULATE DATA TMA ADDRESS CALL WAIT217 ;DO I/O TEST AL,WISERR ;Q. ERROR JZ RDS2173 ; BR IF NO ERROR RDS2172: CALL ERR217 ;REPORT ERROR CMP PREREAD,0 ;Q. IS THIS A PREREAD OPERATION JNE RDS2173 ; BR IF YES CALL ABTIGN ;HANDLE ABORT/IGNORE RDS2173: LES DI,DWORD PTR HSTPTR ;RESTORE BUFFER POINTER AND DSKOP,NOT DSKOPR ;INDICATE READ OP DONE RET ;* WRITE SECTOR ; ; ENTRY: 'PHYSEC'=PHYSICAL SECTOR # ; 'SEC217'=STARTING LOGICAL SECTOR # OF TRACK ; (DI),(ES)=BUFFER POINTER ; EXIT: NONE ; USES: AL ; WRS217: OR DSKOP,DSKOPW ;INDICATE WRITE OP IN PROGRESS MOV HSTPTR,DI ;SAVE BUFFER POINTER MOV HSTPTR+2,ES MOV Z217BLK+OFFSET WI01OP,WIWRL ;WRITE LOGICAL OP CODE CALL CLS217 ;CALCULATE LOGICAL SECTOR # JC WRS2172 ; BR IF ERROR CALL TMA217 ;CALCULATE DATA TMA ADDRESS CALL WAIT217 ;DO I/O TEST AL,WISERR ;Q. ERROR JZ WRS2173 ; BR IF NO ERROR WRS2172: CALL ERR217 ;REPORT ERROR CALL ABTIGN ;HANDLE ABORT/IGNORE WRS2173: LES DI,DWORD PTR HSTPTR ;RESTORE BUFFER POINTER AND DSKOP,NOT DSKOPW ;INDICATE WRITE OP DONE RET ;* EXECUTE COMMAND AND WAIT FOR I/O COMPLETION ; ; ENTRY: 'Z217BLK'=COMMAND BLOCK ; EXIT: (AL)=CONTROLLER HARDWARE STATUS ; USES: AL ; WAIT217: TEST DPEFLAG[BP],DPEASGN ;Q. PARTITION ASSIGNED JNZ WAIT2171 ; BR IF YES TEST DPEFLAG[BP],DPELSIO ;Q. LOGICAL SECTOR I/O JNZ WAIT2171 ; BR IF YES MOV AL,WISERR ;INDICATE ERROR MOV Z217BLK+OFFSET WI01EEC,WIEPNA RET WAIT2171: MOV AL,WIEXEC ;ISSUE EXECUTE COMMAND OUT WIPCMD,AL WAIT2172: IN AL,WIPSTAT ;WAIT FOR CONTROLLER TO BE DONE TEST AL,WISDONE JZ WAIT2172 RET ;* CALCULATE LOGICAL SECTOR # AND PLACE IN COMMAND BLOCK ; ; ENTRY: 'PHYSEC'=PHYSICAL SECTOR # FOR TRACK ; 'PHYTRK'=LOGICAL SECTOR # OF 1ST SECTOR OF TRACK ; EXIT: 'Z217BLK'=COMMAND BLOCK CONTAINS LOGICAL SECTOR # ; 'C' = 0 NO ERROR , 1=ERROR ; USES: AX ; ; LOGICAL SECTOR # = 'PHYTRK' + 'PHYSEC' ; CLS217: MOV AX,PHYTRK ADD AX,PHYSEC TEST DPEFLAG[BP],DPELSIO ;Q. LOGICAL SECTOR I/O JNZ CLS2171 ; BR IF YES CMP AX,WORD PTR DPETRK[BP] ;Q. SECTOR # WITHIN PARTITION JB CLS2172 ; BR IF NOT CMP AX,WORD PTR DPEUPB[BP] JA CLS2172 ; BR IF NOT CLC CLS2171: MOV Z217BLK+OFFSET WI01LS,AL MOV Z217BLK+OFFSET WI01MS,AH RET CLS2172: STC ;INDICATE ERROR MOV Z217BLK+OFFSET WI01EEC,WIESNWP MOV Z217BLK+OFFSET WI01EMS,AH MOV Z217BLK+OFFSET WI01ELS,AL RET ;* CALCULATE DATA TMA ADDRESS ; ; ENTRY: (ES)=DATA SEGMENT ; (DI)=DATA OFFSET ; EXIT: 'Z217BLK'=COMMAND BLOCK CONTAINS DATA TMA ADDRESS ; USES: AX,DL ; ; DATA TMA ADDRESS = (ES)*16 + (DI) ; TMA217: MOV AX,ES XOR DL,DL SHL AX,1 RCL DL,1 SHL AX,1 RCL DL,1 SHL AX,1 RCL DL,1 SHL AX,1 RCL DL,1 ADD AX,DI ADC DL,0 MOV Z217BLK+OFFSET WI01HT,DL MOV Z217BLK+OFFSET WI01MT,AH MOV Z217BLK+OFFSET WI01LT,AL RET ;* COMMON SETUP ROUTINE ; ; ENTRY: (BX)=ADDRESS OF BUFFER HEADER INFO ; EXIT: 'PHYTRK'=LOGICAL SECTOR # OF 1ST SECTOR OF TRACK ; 'PHYSEC'=0 ; USES: AX,DX ; SET217: MOV BP,BUFDPE[BX] ;GET ADDRESS OF DPE MOV AX,BUFTRK[BX] ;CALCULATE LOGICAL SECTOR # MOV DX,WINSPT ; OF 1ST SECTOR ON TRACK MUL DX TEST DPEFLAG[BP],DPELSIO ;Q. LOGICAL SECTOR I/O JNZ SET2171 ; BR IF YES ADD AX,WORD PTR DPETRK[BP] ;ADJUST FOR BEGINING OF PARTITION SET2171: MOV PHYTRK,AX MOV PHYSEC,0 RET ;* ISSUE SETUP COMMAND TO CONTROLLER ; ; ENTRY: (DI),(ES)=COMMAND BLOCK ADDRESS ; EXIT: PSW/C 0=OK , 1=ERROR ; USES: AX ; SUP217: CALL TMA217 ;CONVERT ADDRESS TO 24 BITS MOV AX,10*250 ;SET MAXIMUM TIME FOR ALL TO HAPPEN CALL NWDLY ; TO 10 mS MOV AL,WISETUP ;ISSUE SETUP COMMAND OUT WIPCMD,AL SUP2172: CMP TIMEFLG,0 ;Q. TIME UP JNE SUP2174 ; BR IF YES IN AL,WIPSTAT ;INPUT HARDWARE STATUS TEST AL,WISBUSY ;Q. CONTROLLER BUSY JZ SUP2172 ; BR IF NOT MOV AL,Z217BLK+OFFSET WI01HT ;SEND HIGH ADDRESS BYTE OUT WIPCMD,AL MOV AL,Z217BLK+OFFSET WI01MT ;SEND MIDDLE ADDRESS BYTE OUT WIPCMD,AL MOV AL,Z217BLK+OFFSET WI01LT ;SEND LOW ADDRESS BYTE OUT WIPCMD,AL SUP2173: CMP TIMEFLG,0 ;Q. TIME UP JNE SUP2174 ; BR IF YES IN AL,WIPSTAT ;INPUT HARDWARE STATUS TEST AL,WISBUSY ;Q. STILL BUSY JNZ SUP2173 ; BR IF YES TEST AL,WISDONE ;Q. I/O DONE JZ SUP2173 ; BR IF NOT DONE ; RET ; SUP2174: STC ;INDICATE ERROR RET ;* ERROR REPORTING ; ; ENTRY: 'Z217BLK' CONTAINS ERROR INFORMATION ; EXIT: NONE ; USES: AL,CX,SI,DI ; ERR217: MOV BUFERR[BX],1 ;INDICATE ERROR MOV AL,Z217BLK+OFFSET WI01EEC ;GET ERROR CODE TEST DSKOP,DSKOPR+DSKOPW ;IF DOING READ OR WRITE OPERATION JZ ERR2177 MOV DI,BUFERRF[BX] ; PLACE IN ERROR ARRAY ADD DI,PHYSEC MOV [DI],AL JMPS ERR2178 ERR2177: CALL ERRRPT ; OTHERWISE REPORT ERROR IMMEDIATELY ERR2178: TEST DSKOP,DSKOPS ;Q. DOING 1ST TIME SELECT JNZ ERR2179 ; BR IF YES INC HECNT ;COUNT HARD ERROR ERR2179: RET ;* LOCAL DATA AREA FOR DRIVER WIX1 EQU OFFSET $ DSEG ORG WIX1 Z217BLK RB 0 ;COMMAND BLOCK DB WIRDL ; OP CODE DB 0 ; UNIT SELECT DB 0,0 ; LOGICAL SECTOR # DB 1 ; SECTOR COUNT DB 0,0,0 ; TMA ADDRESS DB 0,0,0 ; NEXT COMMAND ADDRESS DB 0 ; FLAGS DB 0,0,0,0 ; ERROR RETURN INFO IF (OFFSET $ - OFFSET Z217BLK) NE WI01BKL %: Z217BLK IS NOT CORRECT LENGTH ENDIF Z217BP RW 1 ;BEGINNING OF BOOT PARTITION Z217EP RW 1 ;END OF BOOT PARTITION ; WIX2 EQU OFFSET $ CSEG ORG WIX2