From 35d3408ab6b22cbec7bafef554bfc65ada73d9cb Mon Sep 17 00:00:00 2001 From: Wayne Warthen Date: Sat, 16 Mar 2019 16:41:37 -0700 Subject: [PATCH] Floppy Driver Updates Minor fixes in fd.asm. --- Source/HBIOS/fd.asm | 281 ++++++++++++++++++++++---------------------- 1 file changed, 140 insertions(+), 141 deletions(-) diff --git a/Source/HBIOS/fd.asm b/Source/HBIOS/fd.asm index a200c443..dc3d7f9a 100644 --- a/Source/HBIOS/fd.asm +++ b/Source/HBIOS/fd.asm @@ -1391,7 +1391,7 @@ FOP_CMD4: ; START OF STATUS LOOP, WAIT FOR FDC TO BE READY FOR BYTE CP 080H ; LOOKING FOR RQM=1, DIO=0 (FDC READY FOR A BYTE) JR Z,FOP_CMD6 ; GOOD, GO TO SEND BYTE CP 0C0H ; HMMMM... RQM=1 & DIO=1, FDC WANTS TO SEND US DATA, UNEXPECTED - JR Z,FOP_RES ; GO IMMEDIATELY TO RESULTS??? + JP Z,FOP_RES ; GO IMMEDIATELY TO RESULTS??? DJNZ FOP_CMD4 ; LOOP TILL COUNTER EXHAUSTED JP FOP_TOSNDCMD ; COUNTER EXHAUSTED, TIMEOUT / EXIT @@ -1407,28 +1407,149 @@ FOP_CMD6: ; SEND NEXT BYTE FOP_X1: LD A,(FCP_CMD) - LD HL,FOP_RES - PUSH HL - CP CFD_READ - JP Z,FXR_READ + JR Z,FXR_READ CP CFD_WRITE - JP Z,FXR_WRITE + JR Z,FXR_WRITE CP CFD_READID - JP Z,FXR_NULL - RET ; RET ACTUALLY JUST JUMPS RIGHT TO FOP_RES + JR Z,FXR_NULL + JP FOP_RES +;; +;; EXECUTION ROUTINES +;; ; -; RESULTS PHASE +; NULL EXECUTION, NO DATA TO READ/WRITE (USED BY SPECIFY, READID, ETC.) +; +; DO NOTHING, BUT WAIT FOR EXEC B IT TO CLEAR FDC READY. +; LOOP NEEDS TO ALLOW FOR 2 FULL ROTATIONS OF THE DISK +; WHICH IS 400ms AT 300RPM +; +FXR_NULL: + LD BC,$7000 ; LOOP COUNTER, $7000 * 16us = ~485ms +FXR_NULL1: + CALL DELAY ; FDC MAY TAKE UP TO 12us TO UPDATE MSR + IN A,(FDC_MSR) ; GET MSR + AND 0E0H ; ISOLATE RQM/DIO/NDM + CP 0C0H ; WE WANT RQM=1,DIO=1,NDM=0 (READY TO READ A BYTE W/ EXEC INACTIVE) + JP Z,FOP_RES ; EXEC DONE, EXIT CLEAN W/O PULSING TC + ;JP Z,FXR_NULL2 ; *DEBUG* + DEC BC ; DECREMENT COUNTER (16 BIT) + LD A,B ; CHECK FOR ZERO + OR C ; " + JR NZ,FXR_NULL1 ; NOT ZERO YET, KEEP CHECKING + JP FOP_TOEXEC ; TIMEOUT EXIT +;FXR_NULL2: ; *DEBUG* +; CALL PRTHEXBYTE +; CALL PRTHEXWORD +; JP FOP_RES +; +; READ DATA +; +FXR_READ: + HB_DI ; TIME CRITICAL , INTERRUPTS WILL CAUSE I/O ERRS + LD HL,(FD_DSKBUF) ; POINT TO SECTOR BUFFER START + LD DE,(FCD_SECSZ) + ; TIMEOUT COUNTER IS CPU MHZ / 4 (MAKING SURE IT IS AT LEAST 1) +; LD A,(CPUMHZ + 3) / 4 + LD A,(CB_CPUMHZ) ; GET CPU SPEED IN MHZ + ADD A,3 ; ROUND UP + SRL A ; SHIFT RIGHT TWICE + ;SRL A ; ... TO DIVIDE BY 4 + ;INC A ; MAKE SURE RESULT IS AT LEAST 1 + LD (FCD_TO),A ; INIT TIMEOUT COUNTER +FXRR1 LD C,0 ; OUTER LOOP TIMEOUT COUNTER +FXRR2: LD B,0 ; SETUP FOR 256 ITERATIONS +FXRR3: IN A,(FDC_MSR) ; GET MSR + CP 0F0H ; WE WANT RQM=1,DIO=1,NDM=1,BUSY=1 (READY TO RECEIVE A BYTE W/ EXEC ACTIVE) + JR Z,FXRR4 ; GOT IT, DO BYTE READ + DJNZ FXRR3 ; NOT READY, LOOP IF COUNTER NOT ZERO + JR FXRR5 ; COUNTER ZERO, GO TO OUTER LOOP LOGIC + +FXRR4: IN A,(FDC_DATA) ; GET PENDING BYTE + LD (HL),A ; STORE IT IN BUFFER + INC HL ; INCREMENT THE BUFFER POINTER + DEC DE ; DECREMENT BYTE COUNT + LD A,D + OR E + JR NZ,FXRR2 ; IF NOT ZERO, REPEAT LOOP + JR FXR_END ; CLEAN EXIT + +FXRR5: ; OUTER LOOP, REALLY ONLY HAPPENS WHEN WAITING FOR FIRST BYTE OR ABORTED + AND 0E0H ; ISOLATE RQM/DIO/NDM + CP 0C0H ; IF RQM=1, DIO=1, NDM=0 (EXECUTION ABORTED) + JR Z,FXR_ABORT ; BAIL OUT TO ERR ROUTINE, FIX: GO TO SPECIFIC ROUTINE FOR THIS??? + DEC C + JR NZ,FXRR2 ; IF NOT ZERO, LOOP SOME MORE + LD A,(FCD_TO) + DEC A + LD (FCD_TO),A + JR NZ,FXRR1 + JR FXR_TO ; OTHERWISE, TIMEOUT ERROR ; -; 1) CHECK FST_RC AND BAIL OUT IF SET??? -; 2) COMPARE MSR CHECKING TO FXR_NULL (WHICH IS RIGHT?) -; 3) WHEN DUMPING FRB, USE THE RECORDED LENGTH??? +; WRITE DATA +; +FXR_WRITE: + HB_DI ; TIME CRITICAL , INTERRUPTS WILL CAUSE I/O ERRS + LD HL,(FD_DSKBUF) ; POINT TO SECTOR BUFFER START + LD DE,(FCD_SECSZ) + ; TIMEOUT COUNTER IS CPU MHZ / 4 (MAKING SURE IT IS AT LEAST 1) +; LD A,(CPUMHZ + 3) / 4 + LD A,(CB_CPUMHZ) ; GET CPU SPEED IN MHZ + ADD A,3 ; ROUND UP + SRL A ; SHIFT RIGHT TWICE + ;SRL A ; ... TO DIVIDE BY 4 + ;INC A ; MAKE SURE RESULT IS AT LEAST 1 + LD (FCD_TO),A +FXRW1 LD C,0 ; OUTER LOOP TIMEOUT COUNTER +FXRW2: LD B,0 ; SETUP FOR 256 ITERATIONS +FXRW3: IN A,(FDC_MSR) ; GET MSR + CP 0B0H ; WE WANT RQM=1,DIO=0,NDM=1,BUSY=1 (READY TO SEND A BYTE W/ EXEC ACTIVE) + JR Z,FXRW4 ; GOT IT, DO BYTE WRITE + DJNZ FXRW3 ; NOT READY, LOOP IF COUNTER NOT ZERO + JR FXRW5 ; COUNTER ZERO, GO TO OUTER LOOP LOGIC +FXRW4: LD A,(HL) ; GET NEXT BYTE TO WRITE + OUT (FDC_DATA),A ; WRITE IT + INC HL ; INCREMENT THE BUFFER POINTER + DEC DE ; DECREMENT LOOP COUNTER + LD A,D + OR E + JR NZ,FXRW2 ; IF NOT ZERO, REPEAT LOOP + JR FXR_END ; CLEAN EXIT +FXRW5: ; OUTER LOOP, REALLY ONLY HAPPENS WHEN WAITING FOR FIRST BYTE OR ABORTED + AND 0E0H ; ISOLATE RQM/DIO/NDM + CP 0C0H ; IF RQM=1, DIO=1, NDM=0 (EXECUTION ABORTED) + JR Z,FXR_ABORT ; BAIL OUT TO ERR ROUTINE + DEC C + JR NZ,FXRW2 ; IF NOT ZERO, LOOP SOME MORE + LD A,(FCD_TO) + DEC A + LD (FCD_TO),A + JR NZ,FXRW1 + JR FXR_TO ; OTHERWISE, TIMEOUT ERROR +; +; COMMON COMPLETION CODE FOR ALL EXECUTION ROUTINES +; +FXR_TO: ; TIMEOUT + HB_EI ; INTERRUPTS OK AGAIN + JP FOP_TOEXEC ; EXEC TIMEOUT +; +FXR_ABORT: ; EXECUTION ABORTED + HB_EI ; INTERRUPTS OK AGAIN + JR FOP_RES ; GET RSEULTS, NO NEED TO PULSE TC +; +FXR_END: ; EXECUTION COMPLETED NORMALLY + HB_EI ; INTERRUPTS OK AGAIN +FXR_END2: + CALL FC_PULSETC ; PULSE TC TO END EXECUTION + JR FOP_RES ; GET RSEULTS +; +; RESULTS PHASE ; FOP_RES: LD HL,FRB ; POINT TO RECEIVE BUFFER FOP_RES0: - LD B,0 ; B IS LOOP COUNTER + LD BC,$7000 ; LOOP COUNTER, $7000 * 16us = ~458ms FOP_RES1: CALL DELAY ; FDC MAY TAKE UP TO 12us TO UPDATE MSR @@ -1438,7 +1559,12 @@ FOP_RES1: JR Z,FOP_RES2 ; GOOD, GO TO RECEIVE BYTE CP 080H ; CHECK FOR RQM=1, DIO=0 (NOTHING LEFT) JR Z,FOP_EVAL ; IF NOTHING LEFT, ALL DONE, GO TO EOD/EXIT - DJNZ FOP_RES1 ; LOOP TILL COUNTER EXHAUSTED + DEC BC ; DECREMENT COUNTER (16 BIT) + LD A,B ; CHECK FOR ZERO + OR C ; "" + JR NZ,FOP_RES1 ; LOOP TILL COUNTER EXHAUSTED + ;IN A,(FDC_MSR) ; *DEBUG* + ;CALL PRTHEXBYTE ; *DEBUG* JR FOP_TOGETRES ; OTHERWISE TIMEOUT ERROR FOP_RES2: ; PROCESS NEXT PENDING BYTE @@ -1577,133 +1703,6 @@ FOP_EXIT: CALL FC_PRTRESULTS #ENDIF JP FD_RETRC -; -; EXECUTION ROUTINES -; -FXR_NOP: - RET -; -; NULL EXECUTION, NO DATA TO READ/WRITE (USED BY READID) -; -; DO NOTHING, BUT WAIT FOR FDC READY. LOOP NEEDS TO ALLOW FOR -; 2 FULL ROTATIONS OF THE DISK WHICH IS 400ms AT 300RPM -; -FXR_NULL: - LD BC,$4000 ; LOOP COUNTER, $4000 * 25us = 410ms -FXR_NULL1: - CALL DELAY ; FDC MAY TAKE UP TO 12us TO UPDATE MSR - IN A,(FDC_MSR) ; GET MSR - AND 0E0H ; ISOLATE RQM/DIO/NDM - CP 0C0H ; WE WANT RQM=1,DIO=1,NDM=0 (READY TO READ A BYTE W/ EXEC INACTIVE) - RET Z ; GOT IT, EXIT CLEAN W/O PULSING TC - DEC BC ; DECREMENT COUNTER (16 BIT) - LD A,B ; CHECK FOR ZERO - OR C ; " - JR NZ,FXR_NULL1 ; NOT ZERO YET, KEEP CHECKING - JP FXR_TO ; OTHERWISE, TIMEOUT ERROR - RET -; -; READ DATA -; -FXR_READ: - HB_DI ; TIME CRITICAL , INTERRUPTS WILL CAUSE I/O ERRS - LD HL,(FD_DSKBUF) ; POINT TO SECTOR BUFFER START - LD DE,(FCD_SECSZ) - ; TIMEOUT COUNTER IS CPU MHZ / 4 (MAKING SURE IT IS AT LEAST 1) -; LD A,(CPUMHZ + 3) / 4 - LD A,(CB_CPUMHZ) ; GET CPU SPEED IN MHZ - ADD A,3 ; ROUND UP - SRL A ; SHIFT RIGHT TWICE - SRL A ; ... TO DIVIDE BY 4 - ;INC A ; MAKE SURE RESULT IS AT LEAST 1 - LD (FCD_TO),A ; INIT TIMEOUT COUNTER -FXRR1 LD C,0 ; OUTER LOOP TIMEOUT COUNTER -FXRR2: LD B,0 ; SETUP FOR 256 ITERATIONS -FXRR3: IN A,(FDC_MSR) ; GET MSR - CP 0F0H ; WE WANT RQM=1,DIO=1,NDM=1,BUSY=1 (READY TO RECEIVE A BYTE W/ EXEC ACTIVE) - JR Z,FXRR4 ; GOT IT, DO BYTE READ - DJNZ FXRR3 ; NOT READY, LOOP IF COUNTER NOT ZERO - JR FXRR5 ; COUNTER ZERO, GO TO OUTER LOOP LOGIC - -FXRR4: IN A,(FDC_DATA) ; GET PENDING BYTE - LD (HL),A ; STORE IT IN BUFFER - INC HL ; INCREMENT THE BUFFER POINTER - DEC DE ; DECREMENT BYTE COUNT - LD A,D - OR E - JR NZ,FXRR2 ; IF NOT ZERO, REPEAT LOOP - JR FXR_END ; CLEAN EXIT - -FXRR5: ; OUTER LOOP, REALLY ONLY HAPPENS WHEN WAITING FOR FIRST BYTE OR ABORTED - CP 0C0H ; IF RQM=1, DIO=1, NDM=0 (EXECUTION ABORTED) - JR Z,FXR_ABORT ; BAIL OUT TO ERR ROUTINE, FIX: GO TO SPECIFIC ROUTINE FOR THIS??? - DEC C - JR NZ,FXRR2 ; IF NOT ZERO, LOOP SOME MORE - LD A,(FCD_TO) - DEC A - LD (FCD_TO),A - JR NZ,FXRR1 - JR FXR_TO ; OTHERWISE, TIMEOUT ERROR -; -; WRITE DATA -; -FXR_WRITE: - HB_DI ; TIME CRITICAL , INTERRUPTS WILL CAUSE I/O ERRS - LD HL,(FD_DSKBUF) ; POINT TO SECTOR BUFFER START - LD DE,(FCD_SECSZ) - ; TIMEOUT COUNTER IS CPU MHZ / 4 (MAKING SURE IT IS AT LEAST 1) -; LD A,(CPUMHZ + 3) / 4 - LD A,(CB_CPUMHZ) ; GET CPU SPEED IN MHZ - ADD A,3 ; ROUND UP - SRL A ; SHIFT RIGHT TWICE - SRL A ; ... TO DIVIDE BY 4 - ;INC A ; MAKE SURE RESULT IS AT LEAST 1 - LD (FCD_TO),A -FXRW1 LD C,0 ; OUTER LOOP TIMEOUT COUNTER -FXRW2: LD B,0 ; SETUP FOR 256 ITERATIONS -FXRW3: IN A,(FDC_MSR) ; GET MSR - CP 0B0H ; WE WANT RQM=1,DIO=0,NDM=1,BUSY=1 (READY TO SEND A BYTE W/ EXEC ACTIVE) - JR Z,FXRW4 ; GOT IT, DO BYTE WRITE - DJNZ FXRW3 ; NOT READY, LOOP IF COUNTER NOT ZERO - JR FXRW5 ; COUNTER ZERO, GO TO OUTER LOOP LOGIC -FXRW4: LD A,(HL) ; GET NEXT BYTE TO WRITE - OUT (FDC_DATA),A ; WRITE IT - INC HL ; INCREMENT THE BUFFER POINTER - DEC DE ; DECREMENT LOOP COUNTER - LD A,D - OR E - JR NZ,FXRW2 ; IF NOT ZERO, REPEAT LOOP - JR FXR_END ; CLEAN EXIT -FXRW5: ; OUTER LOOP, REALLY ONLY HAPPENS WHEN WAITING FOR FIRST BYTE OR ABORTED - CP 0C0H ; IF RQM=1, DIO=1, NDM=0 (EXECUTION ABORTED) - JR Z,FXR_ABORT ; BAIL OUT TO ERR ROUTINE - DEC C - JR NZ,FXRW2 ; IF NOT ZERO, LOOP SOME MORE - LD A,(FCD_TO) - DEC A - LD (FCD_TO),A - JR NZ,FXRW1 - JR FXR_TO ; OTHERWISE, TIMEOUT ERROR -; -FXR_TO: - LD A,FRC_TOEXEC - JR FXR_ERR - -FXR_ABORT: - LD A,FRC_ABORT - JR FXR_ERR -; -; COMMON COMPLETION CODE FOR ALL EXECUTION ROUTINES -; -FXR_ERR: - HB_EI ; INTERRUPTS OK AGAIN - LD (FST_RC),A - RET - -FXR_END: - HB_EI ; INTERRUPTS OK AGAIN - CALL FC_PULSETC - RET #IF (FDTRACE > 0) ;