; HOME THE HEADS TO TRACK 0 HOME: LD A,(HSTWRT) ; CHECK WRITE PENDING DATA IN BUFFER OR A JR NZ,HOMED ; IF WRITE DATA PENDING THEN SKIP LD (HSTACT),A HOMED: XOR A LD (SEKTRK),A ; RESET SEEK TRACK TO ZERO RET ; DISK SELECT ENTRY ROUTINE ; ACCEPTS: C = DRIVE SELECT (WITH C=0 FOR SELECT DRIVE"A") ; RETURNS: HL = DPB POINTER OF DRIVE SELECT (IF C=VALID DRIVE NUMBER) ; HL = 0H IF (C=INVALID DRIVE NUMBER) SELDSK: LD HL,0 ; SET HL = ERROR RETURN CODE LD A,C LD (SEKDSK),A ; SAVE DRIVE NUMBER CP MAXDRV+1 ; CHECK FOR VALID DRIVE RET NC ; EXIT WITH HL = 0H ; DRIVE NUMBER IS IN PROPER RANGE LD L,A LD H,0 ADD HL,HL ADD HL,HL ADD HL,HL ADD HL,HL ; MULTIPLY BY 16 LD DE,DPBASE ; BASE OF PARAMETER BLOCK ADD HL,DE ; HL=.DPB(CURDSK) RET ; SETTRK -- SET READ/WRITE TRACK ; ACCEPTS: C = TRACK NUMBER SETTRK: LD A,C LD (SEKTRK),A RET ; SETSEC -- SET READ/WRITE SECTOR ; ACCEPTS: C = SECTOR NUMBER SETSEC: LD A,C LD (SEKSEC),A RET ; SETDMA -- SET READ/WRITE DMA BUFFER ADDRESS SETDMA: LD (DMAADR),BC RET ; SECTRAN -- TRANSLATE SECTOR ; ACCEPTS: BC = LOGICAL SECTOR ; DE = TRANSLATIN TABLE ADDRESS ; RETURNS: HL = PHYSICAL SECTOR SECTRN: LD H,B LD L,C RET ; READ CP/M SECTOR ENTRY POINT ; THIS ROUTINE READ THE SELECTED CP/M SECTOR ; INTO SELECTED DMA BUFFER POINTER READ: XOR A LD (UNACNT),A LD A,1 LD (READOP),A ; SET READ OPERATION LD (RSFLAG),A ; MUST READ DATA LD A,WRUAL LD (WRTYPE),A ; TREAT AS UNALLOC JP RDWTCM ; PERFORM THE READ ; WRITE ROUTINE ENTRY POINT ; THIS ROUTINE WRITE THE SELECTED DMA BUUFER POINTER ; INTO SELECTED CP/M SECTOR WRITE: XOR A LD (READOP),A ; SET OPERATION TO WRITE LD A,C ; SAVE WRITE TYPE LD (WRTYPE),A CP WRUAL ; WRITE UNALLOCATED? JR NZ,WRIT10 ; CHECK FOR UNALLOC ; WRITING TO AN UNALLOCATED BLOCK LD A,BLKSIZ/128 ; NUMBER OF SECTORS/BLOCK LD (UNACNT),A ; UNALLOCATED SECTORS REMAINING LD A,(SEKDSK) ; CP/M DRIVE. LD (UNADSK),A ; TO UNALLOCATED DISK LD A,(SEKTRK) ; CP/M TRACK NO. LD (UNATRK),A LD A,(SEKSEC) ; CP/M SECTOR NO. LD (UNASEC),A ; CHECK FOR WRITE TO UNALLOCATED SECTOR WRIT10: LD A,(UNACNT) ; ANY UNALLOCATED SECTOR REMAIN? OR A JR Z,WRIT30 ; SKIP IF NOT ; MORE UNALLOCATED SECTORS IN THIS BLOCK DEC A ; UNACNT = UNACNT-1 LD (UNACNT),A LD A,(SEKDSK) ; GET SEEK DISK INTO A LD HL,UNADSK CP (HL) ; SEEK.DSK = UNALL.DSK? JR NZ,WRIT30 ; SKIP IF NOT ; DISKS ARE THE SAME LD A,(SEKTRK) ; CP/M TRACK NO. LD HL,UNATRK ; UNALLOCATED TRACK NO. CP (HL) ; SEEK.TRK = UNALL.TRK? JR NZ,WRIT30 ; SKIP IF NOT ; TRACKS ARE THE SAME LD A,(SEKSEC) ; GET SEEK SECTOR INTO A LD HL,UNASEC CP (HL) ; SEEK.SEC = UNALL.SEC? JR NZ,WRIT30 ; SKIP IF NOT ; MATCH, MOVE "UNASEC" TO NEXT SECTOR FOR FUTURE REF. INC (HL) ; UNASEC = UNASEC+1 LD A,(HL) CP CPMSPT ; CHECK END OF SECTOR IN CUR.TRACK? JR C,WRIT20 ; SKIP IF NO OVERFLOW ; OVERFLOW TO NEXT TRACK LD (HL),0 ; RESET SECTOR LD A,(UNATRK) INC A LD (UNATRK),A ; UNATRK = UNATRK+1 ; MATCH FOUND, MARK AS UNNECESSARY READ WRIT20: XOR A LD (RSFLAG),A ; SET PRE-READ FLAG = NO JR RDWTCM ; PERFORM WRITE CP/M SECTOR ; NOT AN UNALLOCATED SECTOR, REQUIRES PRE-READ WRIT30: XOR A LD (UNACNT),A ; RESET UNALLOC. COUNTER = 0 INC A LD (RSFLAG),A ; SET PRE-READ FLAG = YES. ; COMMON CODE FOR READ AND WRITE ROUTINE RDWTCM: XOR A LD (ERFLAG),A ; RESET ERROR FLAG LD A,(SEKSEC) ; CONVERT SEEEK SECTOR TO HOST SECTOR OR A ; CLEAR CARRY FLAG RRA LD (SEKHST),A ; TEMPORARY SECTOR NO. ; ACTIVE HOST SECTOR? LD HL,HSTACT LD A,(HL) LD (HL),1 ; ALWAY BECOMES 1 OR A JR Z,RDWT20 ; FILL BUFFER IN ACTIVE FLAG = 0 ; HOST BUFFER ACTIVE, SAME AS SEEK BUFFER? LD A,(SEKDSK) LD HL,HSTDSK CP (HL) ; SAME DISK? JR NZ,RDWT10 ; SKIP IF NOT MATCH ; SAME DISK, SAME TRACK? LD A,(SEKTRK) LD HL,HSTTRK CP (HL) ; SAME TRACK? JR NZ,RDWT10 ; SKIP IF NOT MATCH ; SAME DISK, SAME TRACK, SAME BUFFER? LD A,(SEKHST) LD HL,HSTSEC CP (HL) JR Z,RDWT40 ; SKIP IF MATCH ; PROPER DISK, BUT NOT CORRECT SECTOR RDWT10: LD A,(HSTWRT) ; WRITE DATA PENDING IN BUFFER? OR A JR Z,RDWT20 ; NO NEED TO FLUSH BUFFER CALL WRITEHST ; IF YES, THEN WRITE DATA TO DISK JP NZ,RDWT60 ; ERROR IN WRITING TO DISK ; MAY HAVE TO PRE-READ DATA TO HOST BUFFER RDWT20: LD A,(SEKDSK) LD (HSTDSK),A LD A,(SEKTRK) LD (HSTTRK),A LD A,(SEKHST) LD (HSTSEC),A LD A,(RSFLAG) ; CHECK BUFFER REQUIRES PRE-READ OR A JR Z,RDWT30 ; NO PRE-READ REQUIRED CALL READHST ; IF YES, THEN READ DATA FROM DISK JR Z,RDWT30 ; IF NO ERROR, JUMP TO PROCEED XOR A LD (HSTACT),A ; INDICATE DATA IN BUFFER IS NO GOOD JP RDWT60 ; DISK FUNCTION COMPLETE WITH ERROR RDWT30: XOR A ; INTO BUFFER LD (HSTWRT),A ; RESET PENDING WRITE FLAG ; COPY DATA TO OR FROM BUFFER RDWT40: LD A,(SEKSEC) ; COMPUTE RELATIVE HOST BUFFER ADDRESS AND SECMSK LD H,A LD L,0 SRL H RR L ; HL = ((SEKSEC)&SECMSK)*128 ; HL HAS RELATIVE HOST BUFFER ADDRESS LD DE,HSTBUF ADD HL,DE LD DE,(DMAADR) ; GET/PUT CP/M DATA BUFFER POINTER LD BC,128 ; SET BC = LENGTH TO MOVE LD A,(READOP) ; WHICH WAY? OR A JR NZ,RDWT50 ; SKIP IF READ OPERATION ; WRITE OPERATION, MARK AND SWITCH DIRECTION LD A,1 LD (HSTWRT),A ; SET WRITE PENDING FLAG ON EX DE,HL ; SOURCE/DESTINATION POINTERS SWAP ; BC INITIALLY 128, DE DESTINATION, HL IS SOURCE POINTER RDWT50: LDIR ; DATA HAS BEEN MOVE TO/FROM HOST BUFFER LD A,(WRTYPE) ; CHECK WRITE TYPE OPERATION CP WRDIR ; DIRECTORY WRITE? JR NZ,RDWT60 ; IF NOT A DIRECTORY WRITE THEN EXIT ; ALWAYS FLUSH A DIRECTORY BUFFER XOR A LD (HSTWRT),A ; RESET WRITE PENDING FLAG CALL WRITEHST RDWT60: LD A,FDTOUT LD (FDTIME),A LD A,(ERFLAG) OR A RET ; HERE ARE THE SECTOR READ/WRITE FUNCTIONS. WE ; WANT TO READ/WRITE TO DISK USING THE PARAMETERS ; SECTOR, TRACK, DMA ADDRESS. READHST: LD A,RDSCMD ; FDC READ COMMAND LD HL,RDSTAB ; DMA INITIALIZATION TABLE JR RWHSEC ; CODE COMMON TO READ AND WRITE WRITEHST: LD A,WTSCMD ; FDC WRITE COMMAND LD HL,WTSTAB ; DMA INITIALIZATION TABLE FOR WRITE RWHSEC: LD (COMAND),A LD (DMATAB),HL LD HL,FDTIME LD (HL),0 ; DISABLE MOTOR INC HL LD A,(HL) ; CHECK FLOPPY DISK MOTOR LD (HL),1 ; INDICATE FLOPPY DISK MOTOR IS ON OR A LD A,(FDDBYT) OUT (FDD),A ; NOW TURN ON FLOPPY JR NZ,RWHS02 ; JUMP IF MOTOR ALREADY ON ; WAIT 250 MS FOR MOTOR TO GET SPEED (38461 EXACT) LD HL,38500 RWHS01: DEC HL LD A,H OR L JR NZ,RWHS01 RWHS02: LD A,(HSTDSK) LD HL,DRIVE ; CURRENT DRIVE CP (HL) ; SAME DRIVE? CALL NZ,SELDRV ; NO, HARDWARE SELECT THE DRIVE CALL SELSID ; SELECT THE PROPER SIDE ; READY TO READ OR WRITE A PHYSICAL SECTOR LD A,NOTRYS ; NO. OF RETRIES LD (RETRY),A ; ON DISK I/O OPERATION RWHS10: LD HL,(DMATAB) ; GET DMA INITIALIZE PARAMETER POINTER CALL PRTINI ; DO DMA INITIALIZATION. CALL SEEK ; SEEK THE USER DEFINED TRACK JR NZ,RWHS20 ; ADJUST RETRY COUNTER LD A,(COMAND) ; SET UP FDC OUT (FDCCMD),A ; COMMAND REGISTER CALL WAIT ; WAIT FOR CONTROLLER NOT BUSY JR NZ,RWHS20 ; ERROR ON READ/WRITE LD A,(ERFLAG) ; RETURN CODE OR A ; SET/CLEAR Z FLAG RET ; DISK I/O SUCCESSFUL ; WE HAD AN ERROR ON READ/WRITE OPERATION RWHS20: CALL RESDMA ; RESET THE DMA ON ABORT LD A,(ERFLAG) ; IF DRIVE NOT READY, BIT FDCRDY,A ; DON'T BOTHER WITH RETRIES RET NZ ; RETURN ERROR FLAG IN A LD HL,RETRY ; MORE RETRIES LEFT? LD A,(HL) DEC (HL) ; BUMP DOWN COUNT OR A JR Z,RWHS30 ; ALL DONE, WE FAILED. CALL RESTOR ; SEEK TRACK 0. JR RWHS10 ; LOOP BACK FOR ANOTHER SHOT. RWHS30: CALL ERRPRT ; PRINT DETAILED ERROR MESSAGE LD A,(ERFLAG) ; RETURN ERROR OR A ; SET/CLEAR Z FLAG. RET ; END OF 802FDISK.MAC