|
|
|
@ -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) |
|
|
|
; |
|
|
|
|