READ

.Page
;++
;
;		Read
;
; Read will read a sector from Drive/Side/Track/Sector, doing offtrack
; stepping if neccessary to find the data.  It will also verify the
; checksum found if commanded to do so.
;
; REGISTERS
;  IN
;	All =	Any value
;  OUT
;	All =	Destroyed
;
; CALLS
;	Seek	Seeks to Drive/Track/Side
;	RdAdr	Read address header field
;	Read16	Reads data and checksum
;	VfyCkSum	Verifies checksum that was read
;	BadAddr	Handles all errors during read
;++

ReadBf	.Equ *				; Read w/o checksum verify entry point
	Lda	#0FF
	Bne	Read01

Read	.Equ *
	Lda	#00
Read01	Sta	RwCsmFlg			; Save in global flag
	Jsr	Seek			; Seek to track, zero error cnts, init retry
Read1	Jsr	RdAdr			; Find Sector
	Bcs	Read3			; Error, go and check it
	Jsr	Read16			; Read the sector
	Bcs	Read3
	Ldx	RwCsmFlg			; Fetch the checksum flag
	Bne	Read4			; If <> 0 then ignore checksum verify
	Jsr	VfyCkSum			; Verify the checksum
	Bcc	Read4			; If carry clear, then all is fine
	Inc	CSError			; Increment the checksum error counter

Read3	Jsr	BadAddr			; Find out what went wrong ( ccC = 1)
	Bcc	Read1			; Try once more
	Lda	#SErrRd			; No goog, signal read error
Read4	Rts
.Page
;++
;		BadAddr
;--
;
; REGISTERS
;  IN
;	All =	Any value
;  OUT
;	All =	Destroyed
;	Carry =	Retry status (=Clear, don't retry; =Set, please retry)
;
; CALLS
;	Recalbrt	Recalibrate the drive
;	SeekAlt	Seek to Track/Side
;--
.Page
BadAddr	.Equ *				; Entry point of BadAddr (ccC =1)
	Dec	RetryCnt			; If we've tried enough times to find data
	Beq	BadAddr2
	Clc
	Lda	RaStrt			; Or we can't find start bitslip
	Adc	RaTrk			; Or we're on the wrong trk
	Beq	BadGood			; Try again
	Cmp	RecalCnt			; if >= recalibration count then abort
	Beq	BadBad			; ccC = 1 when A = memory
	Cmp	RtyFlg			; See if new RaStrt or RaTrk error
	Beq	BadGood			; If equal then no change from last time
	Sta	RtyFlg			; a change -- save new error count
	Bne	BadAddr4			; Recalibrate head location
BadAddrd2	Dec	RecalCnt
	Beq	BadBad			; abort upon timeout (ccC still = 1)

BadAddr4	Jsr	Recalbrt			; But don't bother with spd errors at this time
	Jsr	SeekAlt			; And get back to where we were on target track
	Lda	MaxRetry			; Pick up fresh maximum number of retrys count
	Sta	RetryCnt			; and refresh the counter
BadGood	Clc				; We're trying again mate!
BadBad	Rts