;******************************************************** ;* * ;* DISK I/O DRIVER FOR BETTERBOARD 24-JUNE-82 * ;* * ;******************************************************** ; ; ; EQUATES FOR DISK CONTROLLER PORTS AND COMMAND CODES ; STSREG EQU WD179X+0 ;STATUS REGISTER CMDREG EQU WD179X+0 ;COMMAND REGISTER TRKREG EQU WD179X+1 ;TRACK REGISTER SECREG EQU WD179X+2 ;SECTOR REGISTER DATREG EQU WD179X+3 ;DATA REGISTER ; ; RDCMD EQU 10001000B ;READ COMMAND RIDCMD EQU 11000000B ;READ ID COMMAND WRTCMD EQU 10101000B ;WRITE COMMAND SKCMD EQU 00011100B ;SEEK COMMAND RSTCMD EQU 00001000B ;RESTORE COMMAND FINCMD EQU 11010000B ;FORCE INTERRUPT COMMAND STEPOUT EQU 01100000B ;STEP OUT COMMAND STEPIN EQU 01000000B ;STEP IN COMMAND ; ; ; ; SELECT: LD A,C ;GET UNIT# PASSED IN C AND CP 4 ; CHECK FOR MAXIMUM VALID# RET NC ;ERROR IF UNIT# > 3 CALL DSEL ;DERRIVE NEW DRIVE SELECT BIT PATTERN CALL READY ;EMIT NEW SELECT BITS AND TEST READY JR NZ,SELX ;JUMP IF DRIVE NOT READY LD HL,UNIT LD D,0 LD E,(HL) ;LOAD DE WITH LAST SELECTED DRIVE UNIT# LD (HL),C ;THEN STORE NEW UNIT# PASSED IN C LD HL,TRKTAB ADD HL,DE ;INDEX INTO HEAD POSITION TABLE LD A,(TRACK) LD (HL),A ;STORE PREVIOUS DRIVE'S TRACK NUMBER LD E,4 ADD HL,DE ;NOW INDEX TO DENSITY BYTE FOR UNIT LD A,(DSKTYP) AND 00000001B LD (HL),A ;REMEMBER CURRENT DENSITY CONTROL BIT LD HL,TRKTAB LD E,C ;INDEX INTO TABLE TO GET LAST KNOWN ADD HL,DE ; HEAD POSITION OF NEW DRIVE LD A,(HL) OUT (TRKREG),A ;OUTPUT THE DRIVE'S CURRENT HEAD LD (TRACK),A ; POSITION TO THE 179X AND SAVE LD E,4 ADD HL,DE ;INEDX TO NEW DRIVE'S DENSITY SETTING LD A,(DSKTYP) AND 11111110B ;MERGE IN NEW DENSITY CONTROL BIT OR (HL) CALL SETDENS ;SET DENSITY CONTROLS XOR A ;INDICATE SELECT WAS SUCCESSFUL SELX: CALL SETTIMER ;RESET DRIVE TURN-OFF TIMER RET ; ; ; ; DSEL: LD HL,SELTAB ;POINT TO DRIVE SELECT BITS TABLE AND 00000011B LD D,0 LD E,A ADD HL,DE ;ADD UNIT# TO HL TO INDEX INTO TABLE LD A,(HL) LD (SELCPY),A ;STORE NEW STATE OF SELECT/MUX PORT RET SELTAB: DEFB 10001010B ;BITS FOR UNIT #0 DEFB 01001010B ;BITS FOR UNIT #1 DEFB 00101010B ;BITS FOR UNIT #2 DEFB 00011010B ;BITS FOR UNIT #3 ; ; ; ; ; HOME: LD C,0 ;TREAT HOME AS SEEK TO TRACK ZERO SEEK: CALL READY JR NZ,SEEKX ;EXIT IF DRIVE NOT READY LD A,(TRACK) SUB C ;TEST IF ALREADY AT DESIRED TRACK JR Z,SEEKX ;EXIT WITH ACC=0 IF SO LD A,(TRACK) ;GET CURRENT TRACK# INTO ACC CP 255 ;TEST IF HEAD POSITION IS JR NZ,SEEK2 ; KNOWN GOOD AND JUMP IF SO LD A,RSTCMD+3 CALL DISKOP ;EXECUTE RESTORE AT SLOWEST STEP SPEED XOR 00000100B ;COMPLIMENT TRK0 STATUS BIT AND 10000101B JR NZ,SEEKX ;EXIT IF RESTORE CANNOT BE DONE SEEK2: LD B,A ;PUT STARTING TRACK# INTO B CALL FINDTRK ;GO LOOKING FOR TRACK# IN C PUSH AF LD A,C LD (TRACK),A ;STORE FINAL TRACK# (C=255 IF ERROR) OUT (TRKREG),A ;ALSO PUT IN 179X TRACK REGISTER POP AF SEEKX: CALL SETTIMER ;RESET DRIVE TURN-OFF TIMER RET ;RETURN WITH COMPLETION STATUS IN ACC ; ; ; ; FINDTRK: LD A,7 LD (FNDTRY),A ;SET RETRY COUNT FOR HEAD POSITIONING FTRK2: PUSH BC CALL STEP ;HAVE A GO AT STEPPING TO TRACK IN C POP BC JR NZ,FTRK4 ;JUMP IF READY/NOT FOUND/CRC/BUSY ERROR IN A,(SECREG) LD B,A ;PUT ACTUAL CURRENT TRACK# INTO B SUB C ;COMPARE IF WE GOT THERE THIS TIME RET Z ;EXIT WITH ACC=0 IF TRACK# VERIFIED LD A,(FNDTRY) CP 7 JR Z,FTRK3 ;JUMP IF ON FIRST OR SECOND RETRY LD HL,SPEED INC (HL) ;ELSE REDUCE STEP SPEED BY 1 MILLISEC FTRK3: DEC A LD (FNDTRY),A ;DECREMENT SEEK RETRY COUNT AND KEEP JR NZ,FTRK2 ; TRYING OVER (POSSIBLY AT SLOWER RATE) LD A,00010000B ;INDICATE PERMANENT SEEK ERROR OR A FTRK4: LD C,255 ;SET C=255 AS BAD TRACK INDICATOR RET ;RETURN WITH SEEK ERROR STATUS IN A ; ; ; ; ; ; ; STEP FROM TRACK# IN B TOWARDS TRACK# IN C ; STEP: LD D,STEPOUT ;D WILL CARRY STEP OUT/IN COMMAND LD A,B SUB C ;GET DIFFERENCE BETWEEN TRACK NUMS JR NC,STEP2 ;JUMP IF SEEK TOWARDS OUTER TRACKS LD D,STEPIN LD A,C SUB B ;ELSE SWAP DIRECTION AND DIFFERENCE STEP2: JR Z,STEP4 ;GO DO VERIFY IF NO STEPS NEEDED LD (STPCNT),A ;ELSE STORE STEP COUNT AND STEP IN/OUT LD A,D ; COMMAND BYTE CARRIED IN D LD (STPCMD),A LD A,1 LD (STPDLY),A LD HL,DOSTEP ;START STEPPER FINITE STATE MACHINE LD (STPVEC),HL LD A,(SELCPY) RES 3,A ;MAKE 179X TEST INPUT LOW TO DISABLE OUT (SELMUX),A ; INTERNAL OPERATION TIME DELAYS LD A,10000001B OUT (CTCB2),A ;START CTC 1 MILLISECOND INTERRUPT STEP3: LD A,(STPCNT) OR A JR NZ,STEP3 ;LOOP UNTIL STEP COUNTER REACHES ZERO LD A,(SELCPY) SET 3,A ;TAKE 179X TEST PIN BACK HIGH OUT (SELMUX),A STEP4: CALL VERIFY ;ELSE READ AN ID-MARK TO VERIFY SEEK STEPX: RET ; ; ; ; .... ROUTINES FOR INTERRUPT DRIVEN SEEK FUNCTION .... ; DOSTEP: LD HL,STPDLY DEC (HL) ;DECREMENT STEP SPEED DELAY COUNT RET NZ ;EXIT IF NOT TIME TO ISSUE STEP CMD LD A,(STPCMD) OUT (CMDREG),A ;OUTPUT STEP IN/OUT COMMAND TO 179X LD A,(STPCNT) DEC A ;DECREMENT STEP COUNT JR Z,DOSTP2 ;JUMP IF LAST STEP TO BE DONE LD (STPCNT),A ;ELSE STORE DECREMENTED COUNT LD A,(SPEED) LD (HL),A ;STORE STEP SPEED FOR NEXT OPERATION RET ; DOSTP2: LD A,(SETTLE) LD (HL),A ;STORE HEAD SETTLING TIME PARAMETER LD HL,DOSETTLE LD (STPVEC),HL ;DO SETTLING DELAY ON NEXT INTERRUPT RET ; ; ; DOSETTLE: LD HL,STPDLY DEC (HL) ;DECREMENT SETTLING TIME DELAY COUNT RET NZ XOR A LD (STPCNT),A ;SET STEP COUNT TO ZERO WHEN FINISHED LD HL,SEEKX LD (STPVEC),HL ;PUT SEEK FSM TO SLEEP LD A,00000001B OUT (CTCB2),A ;STOP 1 MILLISECOND INTERRUPT RET ; ; ; ; VERIFY: LD A,RIDCMD CALL DISKOP ;READ NEXT ID-MARK TO VERIFY SEEK AND 10011001B JR Z,VERFY2 ;JUMP IF ID MARK READ SUCCESSFULLY CALL FLIPDENS ;ELSE SWITCH DISK DENSITY CONFIGURATION LD A,RIDCMD CALL DISKOP ;TRY AGAIN IN NEW DENSITY AND 10011001B VERFY2: PUSH AF ;SAVE STATUS OF READ-ID CALL FORCE ;CLEAR OVERRUN AND DRQ BITS IN 179X POP AF RET Z ;EXIT IF AN ID MARK WAS FOUND PUSH AF CALL FLIPDENS ;ELSE GO BACK TO ORIGINAL DENSITY POP AF RET ;RETURN WITH ERROR INDICATED ; ; ; ; FLIPDENS: LD A,(DSKTYP) XOR 00000001B ;COMPLIMENT DENSITY BIT OF DRIVE TYPE SETDENS: LD (DSKTYP),A AND 00000011B LD B,0 LD C,A LD HL,SMCTAB ADD HL,BC ;INDEX INTO SMC DATA SEPARATOR CONTROL ADD HL,BC ; BYTE TABLE FOR NEW DENSITY SETTING ADD HL,BC LD B,3 LD C,PORT0 OTIR ;OUTPUT 3 BYTES TO SET DISK DENSITY RET SMCTAB: DEFB SMC1+ON ;8 INCH SINGLE DENSITY DEFB SMC2+OFF DEFB DDEN+ON DEFB SMC1+OFF ;8 INCH DOUBLE DENSITY DEFB SMC2+OFF DEFB DDEN+OFF DEFB SMC1+OFF ;5 INCH SINGLE DENSITY DEFB SMC2+ON DEFB DDEN+ON DEFB SMC1+ON ;5 INCH DOUBLE DENSITY DEFB SMC2+OFF DEFB DDEN+OFF ; ; ; ; ; READID: CALL READY ;CLEAR DISK CONTROLLER JR NZ,RDIDX ;EXIT IF DRIVE NOT READY LD B,RIDCMD CALL RDWRT ;READ ID RECORD INTO BUFFER (HL) JR NZ,RDIDX ;EXIT IF DISK ERROR LD HL,(IOPTR) LD DE,6 ADD HL,DE ;POINT TO 7TH BYTE AFTER ID RECORD LD A,(DSKTYP) LD (HL),A ;STORE DISK TYPE BYTE THERE XOR A RDIDX: CALL SETTIMER ;RESET DRIVE TURN-OFF TIMER RET ; ; ; ; WRITE: CALL READY ;CLEAR THE DISK CONTROLLER JR NZ,WRITEX ;EXIT IF DRIVE NOT READY BIT 6,A JR NZ,WRITEX ;EXIT IF DISK IS WRITE-PROTECTED LD B,WRTCMD CALL RDWRT WRITEX: CALL SETTIMER ;RESET DISK TIMER RET ; ; ; ; READ: CALL READY ;CLEAR DISK CONTROLLER JR NZ,READX ;EXIT IF DRIVE NOT READY LD B,RDCMD CALL RDWRT READX: CALL SETTIMER ;RESET DISK TIMER RET ; ; ; ; ; RDWRT: LD (IOPTR),HL ;STORE DISK I/O DATA POINTER LD A,C LD (SECTOR),A ;STORE SECTOR# FOR READ/WRITE LD A,B LD (CMDTYP),A ;STORE READ/WRITE/READID COMMAND BYTE LD A,(MAXRWT) LD (RWTRY),A ;SET DISK OPERATION RE-TRY COUNT RW1: LD A,(SECTOR) ;OUTPUT SECTOR NUMBER FOR READ/WRITE OUT (SECREG),A LD HL,DMAPGM ;PREPARE TO OUTPUT DMA INITIALIZATION LD B,8 LD C,DMA OTIR ;FIRST 6 BYTES ARE DMA RESETS LD DE,(BLKSIZ) OUT (C),E ;NEXT TWO BYTES ARE MAX DMA BLOCKCOUNT OUT (C),D LD B,3 OTIR ;NEXT 3 BYTES ARE CONSTANTS LD DE,(IOPTR) OUT (C),E ;NEXT 2 BYTES ARE TRANSFER ADDRESS OUT (C),D OUTI ;NEXT BYTE SETS READY/WAIT/RESTART LD B,4 LD A,(CMDTYP) ;GET READ OR WRITE COMMAND BYTE CP WRTCMD JR Z,RW2 ;JUMP IF DISK OPERATION IS A WRITE INC HL INC HL ;ELSE SKIP NEXT TWO BYTES IN DMA PGM LD B,2 RW2: OTIR ;OUTPUT LAST OF DMA PROGRAM BYTES CALL DISKOP ;DO 179X COMMAND AND LOOP TILL INTRQ LD B,4 OTIR ;DISABLE DMA AND INITIATE READ SEQUENCE IN L,(C) IN H,(C) ;READ BYTECOUNT INTO HL AND 10011111B ;MASK READY/RNF/CRC/OVERRUN/DRQ/BUSY RET Z ;RETURN IF NO DISK I/O ERRORS LD (ERRTYP),A CALL RECOVER ;DO READ/WRITE ERROR RECOVERY ROUTINE JR NZ,RW3 ;SKIP RETRY IF IRRECOVERABLE ERROR LD HL,RWTRY DEC (HL) JR NZ,RW1 ;ELSE DECREMENT RETRY COUNT TILL=0 RW3: LD A,(ERRTYP) OR A RET ;RETURN ORIGINAL ERROR CONDITION IN ACC ; ; ; ; RECOVER: LD B,A AND 10000111B ;ISOLATE READY/OVERRUN/DRQ/BUSY ERRORS JR Z,RECOV1 ; AND JUMP IF NONE OF THOSE IS SET CALL FORCE ;CLEAR ERROR FLAGS IN 179X STATUS REG LD A,B OR A ;RETURN ERROR STATUS IN ACC RET ; ; ARRIVE HERE IF CRC OR RECORD-NOT-FOUND ERROR ; RECOV1: BIT 4,B JR NZ,RECOV3 ;JUMP IF SECTOR ID RECORD NOT FOUND ; ; ERROR IS DUE TO BAD CRC IN DATA OR ID FIELD ; RECOV2: LD A,(RWTRY) LD HL,MAXRWT SUB (HL) ;TEST IF THIS IS FIRST CRC ERROR RETRY RET Z ;IF SO EXIT AND ALLOW RETRY TO BE DONE IN A,(TRKREG) ;ELSE PREPARE TO WIGGLE BACK AND FORTH LD B,A ; TO AN ADJACENT TRACK TO RE-CALIBRATE OR A ; AND REMOVE POSSIBLE MEDIA CONTAMINANT JR NZ,RCOV2A LD C, 1 ;STEP TO TRACK#1 IF ON TRACK# 0 JR RCOV2B ; RCOV2A: DEC A ;STEP TO NEXT OUTER TRACK LD C,A RCOV2B: PUSH BC CALL STEP ;STEP HEAD TO ADJACENT TRACK POP DE LD B,E ;EXCHANGE CONTENTS OF B AND C LD C,D CALL STEP ;STEP BACK TO ORIGINAL TRACK RET ; ; ARRIVE HERE IF RECORD-NOT-FOUND ERROR ; RECOV3: LD A,(DSKTYP) ;SAVE DENSITY CONTROL BYTE BEFORE PUSH AF ; CALLING TRACK VERIFY ROUTINE CALL VERIFY ;DO A READ-ID COMMAND TO SEE IF ANY POP DE ; SECTOR ON THIS TRACK CAN BE READ RET NZ ;ERROR IF NO ID MARK FOUND LD A,(CMDTYP) CP RIDCMD ;BYPASS TRACK# CHECK IF DOING READ-ID JR Z,RECOV4 IN A,(SECREG) ;TEST IF CONTENTS OF TRACK REGISTER LD B,A ; MATCHES TRACK# FROM ID MARK JUST IN A,(TRKREG) ; READ (179X PUTS TRK# IN SECTOR REG) LD C,A CP B JR Z,RECOV4 ;JUMP IF HEAD IS ON CORRECT TRACK CP 255 ;ERROR IF TRKREG SET TO 255 PREVIOUSLY JR Z,RECOV5 CALL FINDTRK ;ELSE GO TO TRACK=C FROM TRACK=B PUSH AF LD A,C ;PUT FINAL TRACK# IN 179X TRACK OUT (TRKREG),A ; REGISTER (C=255 IF SEEK ERROR) POP AF RET ;RETURN COMPLETION STATUS IN ACC ; ; ERROR IS DUE TO NON-EXISTENT SECTOR# OR BEING IN WRONG DENSITY ; RECOV4: LD A,(DSKTYP) CP D ;SEE IF DENSITY WAS CHANGED BY 'VERIFY' JR Z,RECOV5 ; AND EXIT WITH RNF ERROR IF NOT XOR A ;CLEAR ACC TO INDICATE RETRY SHOULD RET ; BE DONE NOW THAT DENSITY IS SET RIGHT ; RECOV5: LD A,00010000B OR A ;INDICATE ERROR DUE TO NON-EXISTENT RET ; SECTOR OR INDETERMINATE TRACK# ; ; ; ; DMAPGM: DEFB 11000011B ;DMA RESET COMMAND DEFB 11000011B DEFB 11000011B DEFB 11000011B DEFB 11000011B DEFB 11000011B DEFB 01101101B ;XFER A->B, PORT A AND BYTCNT FOLLOWS DEFB DATREG DEFB 00101100B ;PORT A IS I/O, FIXED ADDRESS DEFB 00010000B ;PORT B IS MEMORY, INCREMENTING ADDRESS DEFB 10001101B ;SINGLE BYTE MODE, PORT B FOLLOWS DEFB 10001010B ;HIGH=RDY, /CE NOT MUXED, NO RESTART DEFB 11001111B ;LOAD DESTINATION ADDRESS DEFB 00000001B ;XFER B->A, NOTHING FOLLOWS DEFB 11001111B ;LOAD SOURCE ADDRESS DEFB 10000111B ;ENABLE DMA DEFB 10000011B ;DISABLE DMA DEFB 10111011B ;READ MASK FOLLOWS DEFB 00000110B ;MASK FOR BYTECOUNT HIGH/LOW DEFB 10100111B ;INITIATE READ SEQUENCE ; ; ; ; ; DISKOP: CALL CMDOUT XOR A ;RESET SECONDS-NOT-READY COUNT FOR LD (RDYCNT),A ; FOR USE AS LOOP EXIT TIMER DSKOP2: IN A,(STSREG) BIT 0,A ;TEST DISK CONTROLLER BUSY STATUS BIT RET Z ;EXIT IF BUSY BIT GOES AWAY LD A,(RDYCNT) ;ELSE TEST IF NOT-READY COUNTER HAS OR A ; BEEN BUMPED BY BACKGROUND SCAN JR Z,DSKOP2 ;KEEP LOOKING IF STILL READY CALL FORCE ;ELSE ABORT DISK COMMAND LD A,00000001B OR A ;RETURN WITH 179X BUSY ERROR INDICATED RET ; ; ; ; CMDOUT: OUT (CMDREG),A ;OUTPUT DISK CONTROLLER COMMAND BYTE LD A,12 COUT2: DEC A JR NZ,COUT2 ;DELAY 50 MICROSECONDS RET ; ; ; ; FORCE: LD A,FINCMD ;LOAD FORCE-INTERRUPT-IMMEDIATE CMD CALL CMDOUT ;CLEAR 179X AND LATCH READY/HLD/TK0 ETC IN A,(STSREG) ;READ STATUS REGISTER CONTENTS RET ; ; ; ; ; READY: LD A,1 LD (INUSE),A ;SET DISKS-ACTIVE FLAG FOR BACKGROUND LD A,(SELCPY) OUT (SELMUX),A ;OUTPUT CURRENT DRIVE SELECT/MUX BITS LD A,(DSKCNT) OR A ;TEST IF BACKGROUND TIMER EQUALS ZERO JR Z,READY2 ;JUMP IF DRIVES HAVE BEEN STOPPED CALL FORCE ;CLEAR CONTROLLER AND TEST DRIVE READY BIT 7,A RET Z ;EXIT IF READY READY2: CALL SPINUP ;ELSE START THE DRIVES AND CHECK READY RET NZ ;EXIT IF NOT RUNNING UP TO SPEED CALL FORCE BIT 7,A ;ELSE TEST THE DRIVE READY STATUS RET ; AND RETURN TYPE 1 STATUS IN ACC ; ; ; ; SETTIMER: PUSH AF ;SAVE COMPLETION STATUS CARRIED IN ACC LD A,(NSTOP) LD (DSKCNT),A ;SET INDEX COUNTER FOR DISK TIMEOUT XOR A LD (INUSE),A ;CLEAR DISKS-ACTIVE FLAG FOR BACKGROUND POP AF RET ; ; ; ; SPINUP: PUSH BC LD A,MOTOR+ON OUT (PORT0),A ;TURN ON THE MOTOR CONTROL LINE LD A,HLDTIM+ON OUT (PORT0),A ;ACTIVATE THE HEAD LOAD SOLENOIDS IN A,(CTCA1) LD C,A ;PUT CURRENT INDEX PULSE COUNT IN C LD A,(NREVS) LD B,A ;PUT REVS-TO-READY PARAM INTO B XOR A LD (RDYCNT),A ;CLEAR SECONDS-NOT-READY COUNTER CALL FORCE ;RESET 179X SO READY CAN BE TESTED SPIN2: LD A,(RDYCNT) CP 4 ;TEST IF DRIVES HAVE BEEN NOT-READY JR NC,SPIN4 ; FOR MORE THAT 4 SECONDS IN A,(STSREG) BIT 7,A JR NZ,SPIN2 ;STAY IN INNER LOOP TILL DRIVE READY IN A,(CTCA1) ;READ INDEX PULSE COUNT FROM CTC SUB C ;COMPUTE CHANGE IN INDEX COUNTER CTC NEG ;RESULT IS NEGATIVE, SO SWITCH IT CP B JR C,SPIN2 ;LOOP UNTIL SPECIFIED NUMBER OF REVS XOR A JR SPIN5 ;EXIT WITH DRIVE READY INDICATED ; SPIN4: LD A,10000000B ;INDICATE DRIVE-NOT-READY ERROR SPIN5: POP BC OR A ;RETURN DRIVE READY STATUS IN A RET ; ; ; ; .... BACKGROUND DISK ACTIVITY MONITOR .... ; DISKTEST: LD HL,OLDCTC ;POINT TO LAST INDEX COUNTER VALUE IN A,(CTCA1) ;READ INDEX PULSE COUNT FROM CTC LD C,(HL) LD (HL),A ;LOAD C WITH LAST COUNT AND STORE NEW LD A,(INUSE) ;TEST STATE OF DISK ACTIVITY FLAG OR A JR Z,DTST2 ;DO DRIVE TURN-OFF STUFF IF NOT IN-USE ; ; ; ARRIVE HERE IF DISK I/O IS CURRENTLY BEING DONE ; LD A,(HL) CP C ;TEST IF ANY INDEX PULSES IN LAST SEC RET NZ ;EXIT IF DISK IS STILL ROTATING LD HL,RDYCNT INC (HL) ;BUMP SECONDS-NOT-READY COUNT RET ; ; ; ARRIVE HERE IF NO DISK OPERATIONS ARE GOING ON ; DTST2: LD A,C SUB (HL) ;COMPUTE PULSES SINCE LAST INTERRUPT JR Z,DTST3 ;TURN DRIVES OFF IF NO INDEX PULSES LD B,A LD A,(DSKCNT) SUB B ;SUBTRACT COUNT DIFFERENCE FROM TIMER JR C,DTST3 ;JUMP IF DISK TIMEOUT JR Z,DTST3 LD (DSKCNT),A ;ELSE STORE UPDATED VALUE FOR NEXT TIME RET ; DTST3: LD A,1 ;SET FLAG TO STOP ANY FURTHER ACCESS TO LD (INUSE),A ; THIS POINT UNTIL NEXT DISK OPERATION XOR A LD (DSKCNT),A ;CLEAR COUNTER TO INDICATE DRIVES-OFF LD A,MOTOR+OFF OUT (PORT0),A ;TURN OFF THE MOTOR CONTROL LINE LD A,HLDTIM+OFF OUT (PORT0),A ;DEACTIVATE THE HEAD LOAD LINE LD A,(SELCPY) ;GET CURRENT DATA AT SELECT/MUX PORT, AND 00001111B ; MASK ALL DRIVE SELECT BITS TO ZEROS OUT (SELMUX),A ;AND RE-OUTPUT TO DESELECT DRIVES RET ; ; ; ; ;