PAGE * * * * * ************************* * * * * *** DISK DRIVER *** * * * * ************************* * * VERSION: 78.10.04 * * * EQUATES * * * * CONTROLLER PORTS * STAPT EQU 0F0H STATUS INPUT PORT TRAPT EQU 0F1H TRANSFER COMMAND PORT BYTLO EQU 0F3H LOW BYTE COUNT PORT BYTHI EQU 0F4H HIGH BYTE COUNT PORT ADRLO EQU 0F5H LOW TRANSFER ADDRESS PORT ADRHI EQU 0F6H HIGH TRANSFER ADDRESS PORT COMPT EQU 0F7H COMMAND OUTPUT PORT * * TRANSFER COMMANDS * RDATA EQU 3 READ DATA COMMAND WDATA EQU 1 WRITE DATA COMMAND READH EQU 7 READ HEADER COMMAND WRITH EQU 5 WRITE HEADER COMMAND * * BIT MASKS * TRCOM EQU 1 TRANSFER COMPLETE SREDY EQU 2 CONTROLLER READY ABERR EQU 4 ABORT FLAG CCERR EQU 8 CRC ERROR FLAG CKCOM EQU 16 CRC CHECK COMPLETE DREDY EQU 32 SELECTED DRIVE READY SKCOM EQU 64 SEEK COMPLETE FLAG INDEX EQU 128 INDEX MARK * * ERROR CODES * SIZER EQU ERBSC SIZE CONFLICT FIDER EQU ERFIC FILE ID CONFLICT SECER EQU ERSCC SECTOR CONFLICT FORER EQU ERCFS FORMAT ERROR (CAN'T FIND SECTOR) TRIER EQU ERCRC ABORTS AND CRCC'S TRKER EQU ERCFT CAN'T FIND TRACK RWERR EQU ERRBC READ AFTER WRITE ERROR LOCER EQU ERLOK SYSTEM LOCKED * * MISC * HELEN EQU 13 LENGTH OF HEADER * PAGE ************************ * * * * * ENTRY POINTS FOR READ AND WRITE DATA * * * * ON CALL: TDAD HAS TRANSFER DESCRIPTOR * RETURNS: CALL+1 FOR NORMAL * ERRL0 FOR ERRORS * DRIVE NOT READY HAS SPECIAL TRAP * * * WRITE DISK BLOCK * WDSK CALL LKCHK CHECK WRITE LOCK AND SET OPERATION JMP WDSK1 * * * READ DISK BLOCK * RDSK MVI A,RDATA READ OPERATION CALL OPSE1 SET OPERATION AND CLEAR INT STUFF * WDSK1 DI . NO INTERRUPTS * * * LOOP TO THESE ENTRIES UNTIL SUCCESFUL TRANSFER OR * TAKE ERROR RETURN. * DATRN CALL DATNS CLEAR ERROR CONTROL FLAGS * DOVER CALL HDVER CLEAR HEADER ATTEMPT COUNT * DATAOP DI . NO INTERRUPTS THROUGH HERE CALL HDATOP READ NEXT HEADER JC TKERR ON WRONG TRACK JNZ DATER PROCESS THE ERROR * * REG "C" HAS DESIRED TRACK, "B" HAS DESIRED SECTOR * LDA IHSEC GET THE READ IN SECTOR CMP B JNZ NOSEC FOUND WRONG ONE, GO TRY SOME MORE * * * TEST HEADER PARAMETERS * LXI H,TBCNT POINT TO TRANSFER DESCRIPTOR LDA IHSIZ GET SPECIFIED SIZE CMP M IS IT THE SAME? JNZ BLKER INX H LDA IHSIZ+1 OTHER PORTION GETS TESTED NOW CMP M JNZ BLKER * * BYTE COUNT IS OK NOW CHECK FILE ID * INX H LDA IHFID CMP M JNZ FIERR INX H LDA IHFID+1 CMP M JNZ FIERR * * WE EVEN CHECK THE SECTOR COUNT * LDA OHPRO GET PROTECT WORD ANI 15 STRIP OFF HIGH BIT MOV B,A LDA IHPRO GET READ IN VALUE ANI 15 CMP B JNZ SZCON IF NOT THE SAME * * ALL SYSTEMS GO!!! 5,4,3....... * LHLD DRLEN = LENGTH OF TRANSFER XCHG . TO DE FOR OUTPUT LHLD TBUF = TRANSFER ADDRESS IN STAPT ANI ABERR+CCERR+SREDY JNZ DATER CALL CTOUT GIVE ADDRESSES TO CONTROLER LDA DOPER THE OPERATION READ OR WRITE OUT TRAPT GIVE THE COMMAND * * * NOW FIND OUT WHERE TO WAIT FOR TRANSFER * LDA DOPER GET THE OPERATION CPI WDATA TEST IF WRITE JNZ RCCHK CHECK FOR READ COMPLETE CALL WFCHK CHECK FOR WRITE COMPLETE JNZ DATER WE HAVE AN ERROR * * OPERATION IS COMPLETE, CHECK FOR VERIFY * LDA SWRBC ARE WE IN VERIFY MODE? ORA A JNZ VERCK IF SO * * * * THIS CODE FINISHES THE OPERATION * DDONE DI . NOT FOR THESE CYCLES MVI A,1 STA IFLG2 TELL THE WORLD WE ARE DONE LXI D,0 TELLS INTDK NOT TO COME BACK CALL INTST INTDN IF TASKER, INTD0 OTHERWISE * ****************** * * * HERE WE RETURN TO THE SYSTEM * INTD0 DI . NO INTERRUPT XRA A STA IFLG2 SAY WE ARN'T DONE BECAUSE WE WERE LXI H,0 CLEAN HOUSE SHLD INRET BE VERY SURE SHLD INTRT EVERY ONE IS CLEAR SHLD DRVRT EVEN HIM LHLD DSKRT GET BACK SYSTEM STACK SPHL . NORMAL AGAIN OUT ADRLO RESET CONTROLLER FLAGS * * TEST IF INTERRUPTS SHOULD BE RE-ENABLED AND DO SO IF * TSTEI LDA IFLG1 ORA A RZ . NOPE EI . YUP RET * * ***************************************** * * * * THIS ENTRY POINT IS FROM DDONE IF A TASK HANDLER * WAS PRESENT. THE HANDLER CALLS HERE WHEN IFLG2 IS * <0>. * INTDN LHLD INTRT SEE IF A TASKER STACK IS LAYING AROUND MOV A,H ORA L JNZ INTD0 SEEMS LEGAL?? * * BAD, BAD, BAD * INTD4 CALL ERRL0 DB ERIDA ILLEGAL DRIVER ACCESS * * ****************** * * * CODE FOR VERIFY MODE * VERCK STA NOERR SET FLAG IN CASE OF ERROR MVI A,RDATA CHANGE OVER TO READ OPERATION STA DOPER LXI H,0 READ...ERROR FLAGS ONLY!!! SHLD DRLEN JMP DATRN NOW READ THE DATA AND RETURN * ****************** * * ROUTINE TO DELAY FOR A MS OR SO AND TEST FOR ABORTS * AND OR CRC ERRORS * TMCHK MVI C,1 LXI D,150 CALL DELY1 IN STAPT RET * * ****************** * * * * TEST READ OPERATION * RCCHK CALL RFCHK JNZ DATER * * LOOP HERE FOR CHECK COMPLETE * RCCHA IN STAPT ANI CKCOM+CCERR+ABERR JZ RCCHA * THEN LOOP FOR SREDY OR ERROR FOR EXIT RCCHB IN STAPT ANI CCERR+ABERR JNZ DATER ERROR EXIT HERE IN STAPT ANI SREDY JZ RCCHB CALL TMCHK ANI ABERR+CCERR JNZ DATER JMP DDONE WE'RE DONE WHEN SREDY * PAGE ********************** * * * * ERROR HANDLING ROUTINES * * * THREE ROUTINES FOR READ AND WRITE DATA * * ABORT OR CRC REPORT * DATER CALL ERRPR PROCESS THE ERROR JMP DOVER SUCCESSFUL RETURN * * * ON WRONG TRACK * TKERR CALL TERRP PROCESS THE TRACK ERROR JMP DOVER AND RETURN * * * NOT THE RIGHT SECTOR AS YET * NOSEC CALL SCTER PROCESS THE COUNT JMP DATAOP RETURNS HERE IF OK * * * THREE ROUTINES FOR WRITE HEADER * CRCER CALL ERRPR PROCESS THE ERROR JMP HOVER AND DO IT OVER * * HTERR CALL TERRP PROCESS THE TRACK ERROR JMP HOVER * * HNSEC CALL SCTER PROCESS THE COUNT JMP HEADD RETURNS HERE IF OK * ***************** * * * DATA ERROR FOUND...PROCESS COUNT * ERRPR MVI A,0FFH CANCEL ANY PREVIOUS COMMAND OUT TRAPT * ERRP1 CALL WAITI WAIT FOR SREDY LDA TTRK MOV C,A KEEP IN C LDA DTRIES GET NUMBER OF ATTEMPTS CPI 44 TWO MORE THAN COULD BE ON THE TRACK (WITH PATCH BELOW) JNC ERRN DONE 49.. GO SEEK INR A STA DTRIES MVI C,2 DELAY FOR 4 MS * * DELAY FOR C*2 MS * DELAY LXI D,167 A 2 MS LOOP DELY1 DCX D MOV A,D ORA E JNZ DELY1 DCR C DOUBLE LOOP JNZ DELAY RET * * * * PROCESS TRACK ERROR * TERRP CALL WAITI WAIT FOR SREADY LDA TTRK MOV C,A KEEP DESIRED TRACK IN C LDA DTERR INR A STA DTERR INCREMENT THE COUNT JZ SEEK0 RESTORE AND RETURN IF THE FIRST TIME DCR A JZ IFIND IF SECOND THEN WAIT FOR INDEX * * TERP1 CPI 15 RC . WAIT FOR 15 TRIES BEFORE SLEWING BACK AND FORTH CPI 25 JUST 25-15 TIMES JNC ERTRK GIVE UP IF MORE RRC . EVEN OR ODD SWITCH JC FIDWN SEEK OUT 2 * * MOVE IN 2 TRACKS * FIUP MOV A,C ADI 2 STEP UP TWO TRACKS CPI 77 JC SEEKT MVI A,76 NO MORE OUT THAN 76 JMP SEEKT * *********************** * * * ROUTINE TO SEEK TRACK ZERO AND RESET THE * TRACK COUNTER. * SEEK0 LDA CUNIT GET CURRENT UNIT CALL USET GET PROPER COMMAND OUT COMPT SELECT THE DRIVE ANI 0EFH SET RESTORE LOW OUT COMPT NEXT SEEK WILL CLEAR THE RESTORE XRA A CALL SETU1 KEEP THE TRACK COUNTER PROPER XRA A MOV M,A IN THE TABLE TOO CALL SKDON WAIT FOR SEEK COMPLETE, THEN, SINCE OLD DRIVES LIE, CALL IFIND DELAY BY WAITING FOR 2 INDEXES. FALL THROUGH FOR 2. * * * WAIT FOR INDEX AND RETURN * IFIND IN STAPT RLC . TEST THE HIGH BIT JC IFIND RET . GOT IT * *********************** * * * PROCESS THE ABORT AND CRC ERRORS * ERRN XRA A STA DTRIES RESTORE TRIES LDA DNERR GET SWITCH INR A STA DNERR JZ FIUP FIRST ONE DIRECTION DCR A SEE IF IT IS > 1 JNZ TRYER GIVE UP THIS IS THE THIRD TIME THROUGH * * MOVE DOWN 2 TRACKS * FIDWN MOV A,C SUI 2 BACK DOWN TWO TRACKS JP SEEKT XRA A DON'T GO LOWER THAN ZERO JMP SEEKT SEEK TO THIS TRACK AND RETRY OPERATION * ****************** * * * SET UP FOR HEADER SEARCH * HDVER XRA A STA DSECN SET NO SECTORS TRIED * * * THIS ROUTINE SEEKS TO THE TRACK GIVEN IN TTRK * * SECHK CALL DRLOP GET DRIVE STATUS LDA TTRK GET DESIRED TRACK SEEKT MOV C,A WE KEEP IT HERE * * COME HERE WITH "C"= TRACK TO GO TO * LDA CTRCK GET CURRENT TRACK SUB C THE DIFFERENCE RZ . ALL DONE IF EQUAL DI . WE HAVE TO DO THIS FAST JP SECH1 THE SIGN FLAG TELLS DIRECTION TO STEP * * GO UP IN TRACK NUMBERS * CMA . DO THE COMPLEMENT FOR NEGATIVE RESULTS INR A MOV B,A "B" HAS NUMBER TO MOVE LDA RUNIT GET PROPER COMMAND ANI 0FDH BIT "1" LOW JMP SECH2 * * * GO DOWN IN TRACK NUMBERS * SECH1 MOV B,A LDA RUNIT THE PROPER ONE * SECH2 OUT COMPT SET THE DIRECTION ANI 0FEH TURN ON THE STEP BIT * * GIVE "B" COUNT STEPS TO THE CONTROLLER * SECH3 OUT COMPT GIVE THE STEPS DCR B JNZ SECH3 GIVE B STEPS MOV A,C GET TRACK CALL SETU1 MAKE IT THE CURRENT ONE MOV M,C IN THE TABLE TOO * * WAIT HERE FOR SEEK COMPLETE * SKDON LXI D,SKDO2 TASK WILL RETURN HERE CALL INTST SEE IF TASKER * SKDO1 IN STAPT WAIT FOR SEEK COMPLETE ANI SKCOM JNZ SKDO1 WHEN FINISHED WAIT FOR AN INDEX MARK MVI C,1 CALL DELAY WAIT FOR 2 MS (DW 2/2/79) RET . DON'T WAIT FOR INDEX TEST 8-28-78 * * * SEEK COMPLETE PROCESS FOR INTERUPT HANDLING * SKDO2 IN STAPT GET STATUS ANI SKCOM TEST IF US JMP RETIN CONTROL GOES TO SKDO1 IF SO * ******************** * * * ERROR FLAG SET UP USED BY RDSKH & WDSKH * DATNS XRA A START WITH NO TRIES STA DTRIES CMA STA DNERR SET IN/OUT SEEK SWITCH STA DTERR MINUS TRACK ERRORS RET * ****************** * * * * READ NEXT HEADER * * * ON CALL: REG "A" HAS READ OR WRITE COMMAND * ON RETURN: THE HEADER IS IN IHEAD * CARRY IS SET IF TRACK ERROR * FLAG NZ = READ ERROR * B HAS DESIRED SECTOR, C HAS DESIRED TRACK * HDATOP CALL WAITS BE SURE CONTROLLER IS READY LXI H,IHEAD -> HEADER BUFFER LXI D,HELEN -> LENGTH OF HEADER CALL CTOUT GIVE THE COMMANDS MVI A,READH READ HEADER COMMAND OUT TRAPT THE TRANSFER COMMAND CALL DLOPS GET ERROR REPORTS RNZ . REPORT THE ERROR.....LOOP EXIT LXI H,TDAD THE TRANSFER DESCRIPTOR MOV B,M SECTOR TO REG B INX H MOV C,M TRACK TO REG C * IN STAPT GET STATUS ANI ABERR+CCERR+SREDY SREADY IS ERROR WITH HEADERS RNZ . ANOTHER ERROR EXIT * LDA IHTRK GET READ IN TRACK CMP C STC . IN CASE OF RETURN RNZ . NOT ON PROPER TRACK XRA A CLEAR THE FLAGS RET * PAGE **************** * * * * INTERRUPT PROCESSING ROUTINES * * * THIS ROUTINE TESTS FOR AND PROCESSES "TASKER" BRANCH * ADDRESSES. * * ON CALL: DE HAS INTERRUPT TEST ADDRESS * EITHER BRANCH RETURNS TO CALL+1 * INTST LHLD BDSK1 GET TASK HANDLER ADDRESS INTS1 INX H SPECIAL ENTRY FOR BDSK2 MOV A,H ORA L SEE IF IT WAS -1 JZ TSTEI IF SO LET THE CALLER PROCESS, WITH INTERRUPTS * INTS3 DCX H MAKE THE ADDRESS VALID XCHG . GET INTERNAL ADDRESS SHLD INRET SAVE IT FOR RETIN LXI H,0 DAD SP SAVE DRIVER STACK LOCATION SHLD DRVRT IT STAYS HERE LHLD INTRT GET INTERRUPT STACK MOV A,L ORA H JNZ INTS2 WE ARE PROCESSING ONE ALREADY LXI SP,-1 RUIN STACK IN CASE SOME IDIOT IS OUT THERE * WHAT GOOD DOES IT DO IF THERE IS AN IDIOT??? XCHG . GET BRANCH PCHL . AND GO....HERE WE COME YOU IDIOT * *********************** * * * WE ARE DONE WITH THIS PHASE AND READY FOR MORE WAITS * GO BACK TO TASK HANDLER, HL HAS THEIR STACK * INTS2 STC . FLAG FOR THEM SPHL . RESTORE HANDLERS STACK RET . GO BACK TO TASKER * * * * * THE EXTERNAL TASK ROUTINE COMES HERE THROUGH THE ENTRY * POINT AREA TO SEE IF WE CAUSED AN INTERRUPT. IF WE * DID THEN CONTROL RETURNS TO THE INTST CALL. IF NOT * THEN CONTROL RETURNS TO THE INTERRUPT HANDLER. * INTDK DI . JUST IN CASE LHLD INRET WAS IT US? MOV A,H ORA L RZ . COULDN'T BE US...WE'RE NOT HERE!!! PCHL . GO FIND OUT IF WE DID * ******************* * * * * THIS ROUTINE TESTS IF INTERRUPT WAS CAUSED BY * "ANY" CONTROLLER TRANSFER FLAG. * RFCH1 IN STAPT GET CONTROLLER STATUS ANI ABERR+SREDY+TRCOM TEST FOR ANY FLAGS * * * GENERAL ROUTINE TO TEST FOR INTERRUPT RETURN * RETIN JNZ RETI1 NZ ==> PROCESS THE INTERRUPT INFR2 XRA A CLEAR ALL FLAGS RET . WASN'T US, GO BACK TO THE TASK AT HAND * RETI1 LXI H,0 SHLD INRET CLEAR THE RETURN DAD SP GET TASK STACK SHLD INTRT SAVE IT LHLD DRVRT GET OUR STACK SPHL . WE HAVE IT RET . TO INTST CALLER * **************** * * * READ FLAG CHECK ROUTINES (SECOND LEVEL INTERRUPT) * RFCHK LXI D,RFCH1 PROCESS ADDRESS CALL INTST SEE IF INT PROCESSING IS WANTED * DLOPS IN STAPT THE STATUS ANI CCERR+ABERR+SREDY+TRCOM JZ DLOPS ANI CCERR+ABERR TEST FOR ERRORS RET . NZ TELLS THE TALE * ******************** * * * WRITE FLAG CHECK ROUTINES (SECOND LEVEL AGAIN) * WFCHK LXI D,RFCH1 THIS WILL DO CALL INTST TEST FOR INTERRUPT PROCESSING * * CONTINUE * WFCH1 IN STAPT GET STATUS ANI ABERR+SREDY+TRCOM JZ WFCH1 LOOP UNTIL ONE IS SET * WFCH2 IN STAPT ANI ABERR RNZ IN STAPT ANI SREDY JZ WFCH2 LOOP FOR SREADY OR ABORT CALL TMCHK ANI ABERR RET . FLAGS SET * ***************** * * * GIVE SEQUENCE OF COMMANDS TO CONTROLLER * CTOUT MOV A,L OUTPUT ADDRESS OUT ADRLO LOW BYTE RESETS CONTROLLER TOO MOV A,H OUT ADRHI * NOW THE COUNT MOV A,E OUT BYTLO MOV A,D OUT BYTHI RET . DONE QUICKLY * PAGE * * ******************* * * * * * WRITE DISK HEADER (AND DATA) WDSKH *** * * * OHEAD IS SET UP BY CALLER * * WRITE HEADER FOLLOWED BY DATA BLOCK * WDSKH LHLD OHFID OUTGOING FILE ID SHLD TFID SET THE TRANSFER DESCRIPTOR CALL LKCHK CHECK FOR WRITE LOCK AND SET OPERATION * * SET UP THE HEADER * LXI H,OHEAD LDA TSEC GET SECTOR MOV M,A MOV B,A KEEP IN "B" ALSO LDA TTRK INX H MOV M,A PUT IN THE TRACK * * CHECK FOR WRITE OVER INDEX * LDA OHPRO NUMBER OF SECTORS REQUIRED BY TRANSFER ANI 15 STRIP OFF HIGH BIT ADD B THE DESIRED SECTOR CPI 17 15 WITH 1 IS 16 JNC SZCON ERROR...WOULD TRY TO WRITE OVER INDEX * * * NOW FIND THE SECTOR BEFORE THE DESIRED ONE * CALL DATNS HERE WE GO, SET FIELDS HOVER CALL HDVER HEADD DI . NO INTERRUPTS THROUGH HERE CALL HDATOP READ THE NEXT HEADER JC HTERR WRONG TRACK JNZ CRCER ERROR FLAG * * NOW CHECK HEADER VALUES * LDA IHPRO NUMBER OF SECTORS ANI 15 MOV E,A SAVE IN E * * CHECK FOR DIREC TRACK (SECTOR HANDLING IS SPECIAL) * MOV A,C DESIRED TRACK IS IN C CPI DIRDT JZ ONFIN PROCESS SPECIAL IF DIRECTORY TRACK LDA IHSEC GET READ IN SECTOR ADD E CALCULATE NEXT SECTOR ANI 15 MASK OFF 16 CARRY * SECOM CMP B IS IT THE ONE WE WANT? JNZ HNSEC IF NOT TRY AGAIN * *************** * * * WRITE THE HEADER * DI . NO INTERRUPTS FOR A BIT LXI H,OHEAD HERE'S WHERE WE GET IT FROM LXI D,HELEN HOW MANY CALL CTOUT THE CONTROLLER GETS THEM MVI A,WRITH WRITE HEADER COMMAND OUT TRAPT GIVE IT * CALL WFCHK WAIT FOR TRANSFER JNZ CRCER ERROR JMP DATRN ALL DONE GO WRITE DATA * ****************** * * * PROCESS CALCULATION FOR TRACK ONE * * SECTORS ARE WRITTEN IN A 0,8,1,9,2,10,3....SEQUENCE * ONFIN LDA TSEC GET DESIRED SECTOR CPI 8 TEST IF ADD OR SUBTRACT JNC OVER8 EXIT WITH TSEC-8 (eg. 9 LOOKS FOR 1) ORA A TEST IF SECTOR ZERO JNZ UNDR8 EXIT WITH TSEC+7 (eg. 1 LOOKS FOR 8) MVI A,8 WE'LL EXIT WITH 15 TO FIND 0 * UNDR8 ADI 7+8 WE'LL ADD SEVEN HERE OVER8 SUI 8 DONE!! ONFI1 MOV B,A SAVE NEW DESIRED VALUE LDA IHSEC GET READ IN SECTOR JMP SECOM AND DO COMPARE * **************** * * * TEST IF SYSTEM IS LOCKED * * ERROR THROUGH ERRL0 * NORMAL SET OPERATION AND RETURN * LKCHK LDA SWLOK TEST IF WRITE LOCKED RRC JC LOKER YES, SWITCH IS SET MVI A,WDATA * * SAVE OPERATION AND CLEAR THE TASK AND INTERRUPT * STUFF * OPSE1 STA DOPER SET OPERATION FOR LATER XRA A STA NOERR FOR VERIFY OPTION LXI H,0 SET UP STACK FOR RETURN POP D GET THIS CALL OFF STACK DAD SP GET SYSTEM RETURN WITH STACK SHLD DSKRT PUSH D OUR CALL GOES BACK ON CALL BLKLN SET UP TRANSFER PARAMETERS *