Browse Source

Floppy Driver Updates

Minor fixes in fd.asm.
pull/31/head
Wayne Warthen 7 years ago
parent
commit
35d3408ab6
  1. 281
      Source/HBIOS/fd.asm

281
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) CP 080H ; LOOKING FOR RQM=1, DIO=0 (FDC READY FOR A BYTE)
JR Z,FOP_CMD6 ; GOOD, GO TO SEND BYTE JR Z,FOP_CMD6 ; GOOD, GO TO SEND BYTE
CP 0C0H ; HMMMM... RQM=1 & DIO=1, FDC WANTS TO SEND US DATA, UNEXPECTED 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 DJNZ FOP_CMD4 ; LOOP TILL COUNTER EXHAUSTED
JP FOP_TOSNDCMD ; COUNTER EXHAUSTED, TIMEOUT / EXIT JP FOP_TOSNDCMD ; COUNTER EXHAUSTED, TIMEOUT / EXIT
@ -1407,28 +1407,149 @@ FOP_CMD6: ; SEND NEXT BYTE
FOP_X1: FOP_X1:
LD A,(FCP_CMD) LD A,(FCP_CMD)
LD HL,FOP_RES
PUSH HL
CP CFD_READ CP CFD_READ
JP Z,FXR_READ
JR Z,FXR_READ
CP CFD_WRITE CP CFD_WRITE
JP Z,FXR_WRITE
JR Z,FXR_WRITE
CP CFD_READID 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: FOP_RES:
LD HL,FRB ; POINT TO RECEIVE BUFFER LD HL,FRB ; POINT TO RECEIVE BUFFER
FOP_RES0: FOP_RES0:
LD B,0 ; B IS LOOP COUNTER
LD BC,$7000 ; LOOP COUNTER, $7000 * 16us = ~458ms
FOP_RES1: FOP_RES1:
CALL DELAY ; FDC MAY TAKE UP TO 12us TO UPDATE MSR 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 JR Z,FOP_RES2 ; GOOD, GO TO RECEIVE BYTE
CP 080H ; CHECK FOR RQM=1, DIO=0 (NOTHING LEFT) CP 080H ; CHECK FOR RQM=1, DIO=0 (NOTHING LEFT)
JR Z,FOP_EVAL ; IF NOTHING LEFT, ALL DONE, GO TO EOD/EXIT 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 JR FOP_TOGETRES ; OTHERWISE TIMEOUT ERROR
FOP_RES2: ; PROCESS NEXT PENDING BYTE FOP_RES2: ; PROCESS NEXT PENDING BYTE
@ -1577,133 +1703,6 @@ FOP_EXIT:
CALL FC_PRTRESULTS CALL FC_PRTRESULTS
#ENDIF #ENDIF
JP FD_RETRC 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) #IF (FDTRACE > 0)
; ;

Loading…
Cancel
Save