FORMAT
.Page
;++
; Format
;
;--
; REGISTERS
; IN
; All = Any value
; OUT
; All = Destroyed
;
; CALLS
; ClrBuf Clears 524 byte buffer and other variables
; SelSide Selects side
; Recall Recalibrates disk to optical index sensor
; WriTrk Write no. of sectors in TempSec
; VerTrk Verifies no. of sectors in TempSec
; SeekAlt Seeks the teack in IIob+Track and sets speed
; WrSynTrk Writes bitslip FF's and A9's then sector 0
; WArd16 Write sector x, both header and data fields
; RdAdr Reads sector header
; Read16 Reads data fields
; VfyCksum Verifies checksum that was read
; PreNib Prenibblizes certain bytes for timing purposes
;
;++
.Page
Format .Equ * ; Format entry point
FormTrk .Equ *
Jsr ClrBuf ; Clear the buffer to be written
Lda #7
Sta FmtGap
Jsr RecalMtr ; Turn on motor & start from a known point (Track 0 )
Bcs FormRts ; Abort upon error from Recal
FormTop Jsr SeekAlt ; Go to othe track in IIob+Track & set speed
Ldy CurClass
Lda SecPrtTrk,y ; Fetch number of sectors in current track
Sta TempSec ; Save it for WriTrk
Jsr WriTrk ; Write a track full of sectors
Lda IIob+Command ; If a format track
Cmp #FrmTrk ; Then we're done-exit the routine
Beq VT00 ; Command = FormatTrack (5)
Lda Iob+NoSides ; 1 = single side, 2 = double side
Cmp #2
Bne $39 ; if <> 2 then go to incr to next track
Lda #20
Sta IIob+Side
Jsr WriTrk ; Now write second side
Lda #00
Sta IIob+Side ; Restore to side 0
$39 Inc IIob+Track
Lda IIob+Track
Cmp #MaxTrack+1
Bcc FormTop ; Until we run out of tracks
Dec IIob+Track
Bne VT00 ; Skip tunring the motor on
Verify .Equ * ; Verify entry point
Lda #MaxTrack
Sta IIob+Track ; From inside of disk to outer edge
VerTrk .Equ *
Jsr RecalMtr ; Turn on motor & start from a know point ( track 0 )
Bcs FormRts ; Abort upon error from Recal
VT00 .Equ *
Jsr SeekAlt ; Go to track in IIob+Track & set speed
Ldy CurClass
Lda SecPrTrk,y ; Fetch the number of sectors in current track
Sta TempSec ; Save it for WriTrk routine
Jsr VerTrk
Bcs FormErr ; Error, exit from routine
Lda IIob+Command ; If a verify track
Cmp #FrmtTrk ; Then we're done-exit the routine
Bcs $41 ; Command = FormatTrack (5) or VerifyTrack (6)
Lda Iob+NoSides ; 1 = Single side, 2 = double side
Cmp #2
Bne $39
Lda #20
Sta IIob+Side
Jsr VerTrk ; Now verify side 1, track x
Bcs FormErr ; Error, exit from routine
Lda #00
Sta IIob+Side
$39 Dec IIob+Track
Bpl VT00
$41 Clc
Rts
FormErr Lda IIob+Track ; Current track number
Sta Trkjl0dNumb ; Save for host's usage
Lda IIob+Side ; Current side
And #20 ; leave bit 5 -- side bit
Beq $17
Lda #1
$17 Sta SideNumb ; Save for host's usage
Lda #SErrFrmt ; Format error code
FormRts Rts
TooSml .Equ *
.Byte 0., 5., 10., 15. ; Not used
.Byte 20., 25., 30., 35. ; 4:7
.Byte 40., 45., 50., 55. ; 8:11
.Byte 60., 65., 70., 75. ; 12:15
JustRit .Equ *
.Byte 108., 99., 90., 81., 72. ; Sectors in class * 9 bytes per sector
;++
; WriTrk will physically format a disk in a 2:1 interleave. It will
; write sector 0, sector x, sector 1, sector y, etc.
;--
WriTrk .Equ ; Entry for writing a track of 524 byte sectors
Jsr SelSide ; Select proper side
Lda TempSec ; Total number of sectors on current track
Sta TotCnt ; Init total number of sectors on current track
Lsr A ; Divide by 2 and put remainder into carry
Adc #0 ; Round up by adding carry
Sta HihCnt ; Init counter for high sector values
Lda #00
Sta CntPtr ; Init pointer for which count to use
Sta LowCnt ; For counting up from Sector 0
Sta IIob+Sector ; Start w/ sector 0
Jsr WrSynTrk ; Write 20 usec nibbles and A9's before sector 0
Dec TotCnt ; Subtract 1 from total sector count
Inc LowCnt ; Increment value to next low sector (1)
$23 Ldx CntPtr ; Pointer to which cnt to use -- low or high
Beq $35 ; If = 0 then increment to 1
Ldx #0FF ; If = 1 then decrement to 0
$35 Inx
Stx CntPtr
Lda LowCnt,x ; Fetch sector number
Sta IIob+Sector
Inc LowCnt,x ; Increment to next sector number
Jsr WAdr16 ; Write address and data fields
Dec TotCnt ; Decrement total sector count
Bne $23 ; When = 0 then all sectors are written
Lda #00
Sta IIob+Sector
Jsr RdAdrTmt ; If = then less than 256 bytes were counted
Bne IncrG1 ; >256 bytes so increase inter-sector gap
Ldy FmtGap
Lda TooSml,y
Cmp RangeL
Bcs DecrG1 ; a > normal cnt with current Gap amount
Ldy CurClass
Adc JustRit,y
Cmp RangeL
Bcs WrTkDone ; A > range so all OK
IncrG1 Lda #14.
Cmp FmtGap ; Limit to 14. self-sync groups of five
Beq WrTkDone
Inc FmtGap ; incr count for next track
WrTkDone .Equ *
Rts
DecrG1 .Equ *
Lda #4.
Cmp FmtGap
Beq WrTkDone ; Minimum gap is 4 counts of 5 20 usec bytes
;++
;
;--
VerTrk .Equ *
Jsr SelSide ; Select proper side
Lda #00
Sta IIob+Sector
Sta ScTrCnt
VfyTrk1 Lda MaxRetry
Sta RetryCnt
VfyTrk2 Jsr RdAdr ; Read sector address field
Bcs VfyErr
Jsr Read16 ; Read sector data
Bcs VfyErr
Jsr VfyCksum ; Verify the checksum
Bcs VfyErr ; Must Be zero
VfRtry Inc IIob+Sector
Lda IIob+Sector
Cmp TempSec
Bne VfyTrk1 ; If equal then carry will be set
Lda SctrCnt
Bne $74
Clc
$74 Rts
VfyErr Dec RetryCnt
Bne VfyTrk2
Ldy SctrCnt
Lda IIob+Sector ; Current Sector Number
Sta SctrSav,y ; Save for host usage
Inc SctrCnt
Bne VfrTry ; Go to next sector and try again
ClrBuf .Equ *
Lda #00 ; Clear the total buffer area
Tay
$05 Sta Page02,y ; Zero part of the data buffer
Sta Page03,y ; Zero the rest of the data buffer
Iny
Bne $05
Ldy #Bufr12SZ ; For 12 bytes header buffer
$10 Sta Bufr12,y
Dey
Bpl $10
Sta Cksum1 ; Clear the three checksum butes
Sta Cksum2
Sta Cksum3
Jmp PreNib ; Create 5 composite bytes & return to caller