;================================================================================================
; Read physical sector from host
;================================================================================================
read:
PUSH AF
PUSH BC
PUSH HL
LD A,$0A ; 10 retries on failed read
LD (err_count),A
rdlp:
CALL CF_CMD_RDY
CALL setLBAaddr
LD A,CF_READ_SEC
OUT (CF_COMMAND),A
; Error checking
CALL CF_DAT_RDY
IN A,(CF_STATUS) ; Read status
AND 00000001b ; Mask off error bit
JP Z,rdcont ; Continue if no error
DJNZ rdlp ; Try again if attempts remain
; Error out
CALL printInline ; Out of lives - show an error
.DB CR,LF
.TEXT "Error reading sector!"
.DB 0
LD A,$01 ; Return to BDOS with error code 1 - Unrecoverable error
LD (erflag),A
POP HL
POP BC
POP AF
RET
rdcont:
CALL CF_DAT_RDY
LD A,(dmaBank)
CALL selmem ; could avoid this if dmaBank == 0
LD B,0 ; 256 bytes at a time
LD C,CF_DATA
LD HL,(dmaAddr)
INIR ; do 256 bytes
INIR ; do another 256 bytes = 512
XOR A ; back to Bank 0...
CALL selmem ; could avoid this if dmaBank == 0
POP HL
POP BC
POP AF
XOR A
LD (erflag),A
RET
;================================================================================================
; Write physical sector to host
;================================================================================================
err_count: .ds 1 ; Write error counter
write:
PUSH AF
PUSH BC
PUSH HL
LD A,$0A ; 10 retries on failed write
LD (err_count),A
whst:
CALL CF_CMD_RDY
CALL setLBAaddr
; Issue write command
LD A,CF_WRITE_SEC
OUT (CF_COMMAND),A
CALL CF_DAT_RDY
LD A,(dmaBank)
CALL selmem ; could avoid this if dmaBank == 0
LD B,0 ; 256 bytes at a time
LD C,CF_DATA
LD HL,(dmaAddr)
OTIR ; do 256 bytes
OTIR ; do another 256 bytes = 512
XOR A ; back to Bank 0...
CALL selmem ; could avoid this if dmaBank == 0
; Error checking
CALL CF_WAIT
IN A,(CF_STATUS) ; Read status
AND 00000001b ; Mask off error bit
JP NZ,werr ; Jump to werr if error
POP HL
POP BC
POP AF
XOR A
LD (erflag),A
RET
; Error - loop if retries remain
werr:
LD A,(err_count)
DEC A
LD (err_count),A
JP NZ,whst ; Try again
; Error handling
CALL printInline ; Out of lives - show an error
.DB CR,LF
.TEXT "Write error!"
.DB 0
LD A,$01 ; Return to BDOS with error code 1 - Unrecoverable error
LD (erflag),A
RET
;------------------------------------------------------------------------------
; Wait for disk to be ready (BUSY=0, READY=1)
;------------------------------------------------------------------------------
CF_WAIT:
PUSH AF
cfWait1:
IN A,(CF_STATUS) ; Read status
AND 10000000b ; Mask BUSY bit (7)
JP NZ,cfWait1 ; Still BUSY? Loop...
POP AF
RET
;------------------------------------------------------------------------------
; CF_CMD_RDY
; Loops until status register bit 7 (BUSY) is 0 and bit 6 (DRVRDY) is 1
;------------------------------------------------------------------------------
CF_CMD_RDY:
IN A,(CF_STATUS) ; Read status
AND 11000000b ; Mask off BUSY and DRVRDY bits
XOR 01000000b ; We want BUSY(7) to be 0 and DRVRDY(6) to be 1
JP NZ,CF_CMD_RDY
RET
;------------------------------------------------------------------------------
; CF_DAT_RDY
; Loops until status register bit 7 (BUSY) is 0 and DRQ(3) is 1
;------------------------------------------------------------------------------
CF_DAT_RDY:
IN A,(CF_STATUS) ; Read status
AND 10001000b ; Mask off BUSY and DRQ bits
XOR 00001000b ; We want BUSY(7) to be 0 and DRQ(3) to be 1
JP NZ,CF_DAT_RDY
RET