mac-rom/Drivers/Sony/SonyFormat.a

738 lines
27 KiB
Plaintext
Raw Normal View History

;
; File: SonyFormat.a
;
; Contains: Sony Format/Verify routines
;
; Written by: Larry Kenyon, Steve C, Gary D, ...
;
; Copyright: <09> 1982-1990, 1992 by Apple Computer, Inc., all rights reserved.
;
; Change History (most recent first):
;
; <SM10> 1/10/93 RC Added nop for Smurf
; <SM9> 12/14/92 RC Restore Pre-PDM D2 With Horror Roll in
; <SM7> 12/9/92 rab Fixed a bug I introduced rolling in DoFormatEndPatch. Was
; branching back into the SWIM code instead of doing an RTS.
; <SM6> 12/7/92 rab Roll in Horror changes. Comments follow<6F>
; <5> 11/14/91 SWC Shortened the DoFormat patches for SWIM2 to save patch space.
; Converted the SCC polling code to a macro so it's easier to
; overpatch.
; <SM5> 12/02/92 HY Added hasPwrControls conditionals.
; <SM4> 10/18/92 CCH Added nop's for systems with non-serial writes to IO space.
; <5> 7/14/92 CSS Fixed the comment below so an exact version of this
; file could be copied into SuperMario.
; <4> 4/27/92 JSM Get rid of conditionals: supportsPWM is always false,
; hasPowerMgr, hasPwrControls, supportsMFM, and isUniversal are
; always true (although hasPowerMgr currently isn<73>t for the ROM,
; it will be and was always ORed with hasPwrControls here anyway).
; This file now has no conditionals.
; <3> 5/11/90 MSH Converted all onHcMac or hasPowerMgr conditionals to universal
; versions. Test is based on the existence of the power manager
; bit in the config word.
; <2> 2/2/90 GMR Fixed Format bugs where it used DskErr as a completion flag when
; making synchronous calls to DiskSel,PowerUp.
; <2.4> 5/23/89 GGD No changes to this file, entire Sony Driver is checked out and
; in as a group.
; <2.3> 4/29/89 GGD No changes to this file, entire Sony Driver is checked out and
; in as a group.
; <2.2> 4/10/89 gmr No changes to this file, entire Sony Driver is checked out and
; in as a group.
; <2.1> 2/21/89 GGD Increased default GapSync from 7 to 8, to allow more optimal
; sector spacing, and more margin if 1 to 1 writes are attempted.
; <2.0> 12/15/88 GGD Changed some machine based conditionals to feature based.
; <1.1> 11/11/88 CCH Fixed Header.
; <1.0> 11/9/88 CCH Adding to EASE.
; <1.9> 9/29/88 GGD No changes to this file, entire Sony Driver is checked out and
; in as a group.
; <1.8> 9/19/88 GGD No changes to this file, entire Sony Driver is checked out and
; in as a group.
; <1.7> 8/16/88 GGD No changes to this file, entire Sony Driver is checked out and
; in as a group.
; <1.6> 7/15/88 GGD No changes to this file, entire Sony Driver is checked out and
; in as a group.
; <1.5> 6/15/88 GGD No changes to this file, entire Sony Driver is checked out and
; in as a group.
; <1.4> 5/25/88 GGD No changes to this file, entire Sony Driver is checked out and
; in as a group.
; <1.3> 5/24/88 GGD No changes to this file, entire Sony Driver is checked out and
; in as a group.
; <1.2> 5/3/88 GGD No changes, entire sony driver checked out and in as a group.
; <1.1> 4/18/88 GGD Merged in MFM support <C437> by Steve Christensen Turned IWM on
; earlier in Format for HcMac
; <1.0> 2/12/88 BBM Adding file for the first time into EASE<53>
; 11/18/87 SWC Check to see if the disk is write-protected on a Format request,
; and if so, return an error.
; <C907> 10/12/87 MSH For HcMac: Add call to turn on IWM upon entry.
; 10/8/87 SWC Fixed check for 720K disks.
; 9/30/87 SWC Don't call SetChipMode if an IWM is installed and SetIWMMode
; wouldn't have been called anyway.
; 5/1/87 SWC Patched Format to support the format version numbers returned by
; the Passport/InterFile/... status call.
; <C437> 11/21/86 SWC Patched Format and Verify to jump to their MFM counterparts if
; we're running in MFM mode.
; <A351> 11/5/86 TJ Text cleanup.
; <A302> 10/30/86 TJ Removed IWM absolute address references.
; <C1> 4/25/86 RDC Deleted tach frequency table for old MidMac project
; 10/30/85 LAK Fixed bug in read-verify (wasn't getting rid of poll stack data
; when it saw a sector it already had).
; 10/25/85 LAK Skip speed check for 2-sided drives. Use NewIntf rather than
; Sides to determine whether drive has new interface.
; 7/29/85 RDC Added changes for MidMac: - changed interrupt level settings to
; use equates - adjusted frequency count table - assume no speed
; errors for now
;
;_______________________________________________________________________
;
; Routine: CtlFormat
; Arguments: A0.L (in) -- param block ptr
; A1.L (in) -- driver locals ptr
; D1.W (in) -- drive vars offset
; Drive (in) -- set to correct drive
; D0.W (out) -- result code (0 if correctly formatted)
;_______________________________________________________________________
BLANKS ON
STRING ASIS
SyncTbl
AdrMkTbl
DC.B $FF,$3F,$CF,$F3,$FC,$FF ; self-sync pattern
DC.B $D5,$AA,$96,$00,$00,$00,$00 ; addr mk skeleton
DC.B $00,$DE,$AA,$FF
DC.B $FF,$3F,$CF,$F3,$FC,$FF ; self-sync pattern
DC.B $D5,$AA,$AD,$00,$00 ; data mark header
CtlFormat SUB #512,SP ; get space for buffers we need off stack
MOVE.L SP,DiskBuffer(A1) ; StackBuf for mark, block buffer
IF hasPwrControls THEN ; <SM5>
TestFor hwCbPwrMgr
BEQ.S @pmgrdone
BSR TurnIWMon ; Turn IWM on with pmgr call <1.1/01mar88>
@pmgrdone
ENDIF ; <SM5>
MOVE.W csParam(A0),D4 ;Use current format? <C437/25aug87>
BEQ.S @0 ;-> yes, don't change anything <C437/25aug87>
MOVEQ #numSDFmts-1,D3 ;Assume no SWIM or SuperDrive <C437/25aug87>
MOVE.B isSWIM(A1),D0 ;Is a SWIM connected AND <C437/25aug87>
AND.B mfmDrive(A1,D1),D0 ; is this a SuperDrive? <C437/25aug87>
BPL.S @00 ; <C437/25aug87>
MOVEQ #numSDFmts,D3 ;Yes, we can do MFM!! <C437/25aug87>
TST.B twoMegFmt(A1,D1) ;Is this a double-density disk? <C437/25aug87>
BPL.S @00 ; <C437/25aug87>
MOVEQ #numDDFmts,D3 ;Yes, it must be 1440K <C437/25aug87>
@00 ; <C437/25aug87>
MOVEQ #paramErr,D0 ;Assume format type is outta range <C437/25aug87>
CMP.W D3,D4 ;Well, is it? <C437/25aug87>
BHI FmtVerExit ;-> yep, just exit <C437/25aug87>
CMPI.W #NumSDFmts,D4 ;(thanks, Mr. Davidian, sir) <C437/08oct87>
SEQ D0 ;MFM format if it's the last SD one <C437/25aug87>
OR.B twoMegFmt(A1,D1),D0 ; or it's double-density? <C437/25aug87>
SMI mfmDisk(A1,D1) ; <C437/25aug87>
@0 TST.B isSWIM(A1) ;Is a SWIM installed? <C437/30sep87>
BPL.S @01 ;-> no, skip <C437/30sep87>
BSR SetChipMode ;Set up the mode for MFM or GCR <C437/25aug87>
BNE FmtVerExit ;-> couldn't initialize the chip <C437/25aug87>
@01 ; <C437/30sep87>
BSR DiskSelect ;Re-select the interface <C437/25aug87>
TST.B mfmDisk(A1,D1) ;Are we in MFM mode? <C437/25aug87>
SMI TwoSided(A1) ; <C437/25aug87>
BMI.S @1 ;-> yes, we're 2-sided <C437/25aug87>
TST.B Sides(A1,D1) ; for now, format according to drive
SMI TwoSided(A1) ; $00 for 1-sided format
BPL.S @1 ; <21Jun85> br if one-sided <C437/25aug87>
SUBQ.W #1,D4 ; <21Jun85> format 2-sided as 1-sided?<C437/25aug87>
BNE.S @1 ; <21Jun85> br if not <C437/25aug87>
CLR.B TwoSided(A1) ; <21Jun85> force one-sided
@1 TST.B TwoSided(A1) ; <21Jun85> so, 1-sided or 2-sided? <C437/25aug87>
SNE TwoSideFmt(A1,D1) ; <21Jun85> update it for future
; interested parties . . .
MOVE.W #8,GapSync(A1) ; start with 8 sync groups before sector <2.1>
BSR FVPowerUp ; start up the drive (synchronously)
MOVEQ #WrProtAdr,D0 ;Is the disk write-protected? <C437/18nov87>
BSR AdrAndSense ; <C437/18nov87>
BMI.S @11 ;-> nope, onward! <C437/18nov87>
MOVEQ #wPrErr,D0 ;Return a write-protect error <C437/18nov87>
BRA.S FmtVerExit ;someone OBVIOUSLY wasn't checking--<C437/18nov87>
@11 ;(massive finger pointing--Scott?) <C437/18nov87>
MOVE.L SonyVars,A1 ;
MOVE.L DiskBuffer(A1),A0 ; now fill stack buffer with blank marks
LEA AdrMkTbl,A1
MOVEQ #12-1,D0 ; marks for 12 sectors <C437/25aug87>
@2 MOVEQ #27-1,D1 ; 27 bytes per sector <C437/25aug87>
MOVE.L A1,A2 ; point A2 to blank image
@3 MOVE.B (A2)+,(A0)+ ; <C437/25aug87>
DBRA D1,@3 ; <C437/25aug87>
DBRA D0,@2 ; <C437/25aug87>
BSR GetDrv1
CLR.W SideTrack(A1) ; start with track 0
TrackLoop
BSR.S SpdSeek ; seek to track and adjust speed if needed
BNE.S FmtVerExit ; exit on errors
BSR GetDrv1 ; <C437/21nov86>
TST.B mfmDisk(A1,D1) ;Are we in MFM mode? <C437/21nov86>
BPL.S @00 ;-> no, do the regular format <C437/21nov86>
BSR mFmtTrack ;Format the track (MFM style) <C437/21nov86>
BRA.S @0 ; <C437/21nov86>
@00 ; <C437/21nov86>
BSR FormatTrack ; format the track
@0 BNE.S FmtVerExit ; exit on errors
BSR GetDrv1
BCLR #3,SideTrack(A1) ; clear 'side' bit
ADDQ #1,SideTrack(A1) ; go on to the next track
CMP #80,SideTrack(A1) ; until we're done with all 80
BLT.S TrackLoop
FmtVerOK MOVEQ #0,D0 ; successful exit
FmtVerExit ADD #512,SP ; clean up the stack
BRA DskRWOff ;Share SonyRWT exit routine <C437/20aug87>
;(sets up the power down time) <C437/20aug87>
eject ; <A351/05nov86>
;_______________________________________________________________________
;
; Routine: SpdSeek
; Arguments: A1,D1 (input) -- ptr to drive vars
; D0.W (output) -- result code (0 if speed ok)
; Function: This routine seeks to a track and checks speed if changing
; track speed class boundary.
;_______________________________________________________________________
; table of frequency counts for 15 tach pulses, each of the 5 speed classes
SpdSeek MOVE.B BadSpdInit(A1),BadSpdCnt(A1)
CkDrift MOVE.W SideTrack(A1),D6 ; seek . . . synchronously
BSR FmtVerSeek ; seek to desired track
BSR GetDrv1
MOVE.W Track(A1,D1),D6 ; track is negative on seek errors
BMI.S SpdSeekXit ; exit on seek errors
SpdSeekOK MOVEQ #0,D0
SpdSeekXit RTS
eject ; <A351/05nov86>
;_______________________________________________________________________
;
; Routine: FormatTrack
; Arguments: D0.W (output) -- result code (0 if format ok)
; Function: This routine formats a track (both sided for double-sided
; disks), verifying that sync is evenly spread between the
; sectors.
;_______________________________________________________________________
FormatTrack BSR GetDrv1
MOVE.W SideTrack(A1),D6 ; current side/track
MOVE.W D6,D1
BCLR #11,D1 ; clear side bit
LSR.W #4,D1 ; speed class
MOVEQ #12,D0 ; 12 sectors in outside tracks
SUB.W D1,D0 ; reduce by 1 per speed class inward
MOVE.W D0,SectCnt(A1) ; save for later
BSR FillInMarks ; update mark buffer for this track/side
; (pass D0=sector count,D6=side/track)
FmtTrk1
BSR.S DoFormat ; format the track (disables interrupts) <C437/10feb88>
BEQ.S @1 ; br if ok
BSR toEmptyPD ; get rid of poll data
ANDI #$F8FF,SR ; open up interrupts
BRA FTExit ; exit immediately for write errors
; now we check the intersector gap (keep poll data on the stack . . .)
@1 BSR RdAddr ; get next address mark
BMI.S @2 ; br if error
TST.B D2 ; should be sector 0
BEQ.S @2
MOVEQ #Fmt1Err,D0 ; set "not sector 0" error otherwise
@2 BSR toEmptyPD ; get rid of poll data (preserves D0)
ANDI #$F8FF,SR ; open up interrupts
LEA GapSync(A1),A0 ; useful addr
TST.W D0 ; check error code <2>
BMI.S DecrSn1 ; br on error (change amt of sync in case
; erase turn-off glitched us out or not
; sector 0 - wrote too much sync)
MOVE.L #MustFindCt+4,D2 ; nibble must find count, adjusted
SUB.W D0,D2 ; nybble gap before sector 0
DIVU #5,D2 ; sync group count
MOVE.W #Fmt2Err,DskErr ; assume "not enuf sync"
SUB.W (A0),D2 ; groups more than the standard GapSync
BMI.S DecrSync ; br if too little
EXT.L D2
DIVU SectCnt(A1),D2 ; divide by groups per sector
BEQ.S FTExitOK ; br if ok
SUBQ.W #1,D2 ; don't increase if only by 1
BEQ.S FTExitOK
ADDQ.W #1,(A0) ; increase GapSync by 1 only
FTExitOK BSR GetDrv1 ; set A1,D1 to point to drive vars
BSET #3,SideTrack(A1) ; are we on the second side already?
BNE.S @1 ; br if so
TST.B TwoSided(A1) ; format two-sides?
BNE FormatTrack ; br if so and format the other side
@1 CLR.W DskErr ; success!
FTExit MOVE.W DskErr,D0
RTS
DecrSync
ADDQ.W #1,D2 ; if only one, don't worry
BEQ.S FTExitOK
DecrSn1
SUBQ.W #1,(A0) ; decrement GapSync
CMP.W #minSync,(A0) ; not below the minimum tho
BLT.S FTExit
BRA.S FmtTrk1 ; otherwise, go again <C437/10feb88>
eject ; <A351/05nov86>
;_____________________________________________________________________
;
; Routine: DoFormat
; Arguments:
; A5.L (input) --
; A6.L (input) --
; Function: Formats the current track; the disk is assumed to be up
; to speed and correctly positioned, and interrupts disabled.
;
; write 200 sync groups (get something on the disk)
; start with sector 0: do 2-1 soft interleave
;
; loop: intersector gap sync groups
; 10 $A9 nybbles (only before sector 0)
; 1 sync group (6)
; D5 AA 96 trk sec side vol cksum DE AA FF (11)
; 1 sync group (6)
; D5 AA AD sec (4)
;
; 703 96 nibbles
; DE AA FF
; loop for all sectors
;_____________________________________________________________________
adrBytCnt EQU 27 ; bytes in buffer for a sector adr mark
syncBytCnt EQU 6 ; bytes in a sync group
dataBytCnt EQU 703 ; number of $96 nibbles in an address mk
strtSync EQU 200 ; number of sync groups to initially write
DoFormat
MOVE.L (SP)+,DskRtnAdr ; strip return address
MOVEQ #RdDtaAdr,D0 ; PAL address for side 0
MOVE.L SonyVars,A1
TST.B TwoSided(A1)
BEQ.S @1
BTST #11,D6 ; side 1?
BEQ.S @1 ; br if not
MOVEQ #RdDta1Adr,D0
@1 BSR AdrDisk
MOVEQ #4,D0
BSR SetUpPoll ; set up A5,A6, PollStack
move.l IWM,A4 ; initially A4 is IWM <A302/30oct86>
lea Q6H(A4),A3 ; set up Q6H pointer (do Q6L later) <A302/30oct86>
MOVE.L DiskBuffer(A1),A0 ; point to nibble buffer
MOVE.W SectCnt(A1),D0 ; number of sectors to write here
;_______________________________________________________________________
;
; D7 = A7 = stack (where poll data is pushed)
; D6 = A6 = ptr to SCC chan A data reg
; D5 = A5 = ptr to 6522 A-reg
; D4 = scratch A4 = ptr to Q6L (initially IWM)
; D3 = scratch A3 = ptr to Q6H
; D2 = working buffer count A2 = working buffer pointer
; D1 = sync group count A1 = pointer to sync group, data mk slip
; D0 = sector count A0 = pointer to mark buffer
;_______________________________________________________________________
MOVE.W GapSync(A1),D1 ; set up D1 now
SUBQ.W #2,D1 ; adjust for DBRA and adr mk sync
MOVE.W #strtSync-1,D3
TST.B mfmMode(A1) ; are we in ISM mode? <SM6>
LEA SyncTbl,A1 ; <SM6>
BPL.S @NotSWIM2 ; -> no, it's either an IWM or SWIM <H4><SM6>
LEA wData(A4),A3 ; point to the write data and <SM6>
LEA rHandshake(A4),A4 ; handshake registers for speed <SM6>
TST.B rError-wData(A3) ; clear the error register <SM6>
MOVE.B #$18,wZeroes-wData(A3) ; clear the write and action bits <SM6>
MOVE.B #$10,wOnes-wData(A3) ; set the write bit <SM6>
MOVE.B #$01,wOnes-wData(A3) ; toggle the clFIFO bit to clear out<SM6>
MOVE.B #$01,wZeroes-wData(A3) ; any data in the FIFO <SM6>
TST.B rError-wData(A3) ; clear the error register again <SM6>
MOVE.B D3,(A3) ; write garbage to FIFO <SM6>
MOVE.B #$08,wOnes-wData(A3); turn on the action bit: GO! <SM6>
BRA.W WrStrtSync ; <H4><SM6>
@NotSWIM2
TST.B (A3) ; first byte written is a bit wierd
move.b D3,Q7H(A4) ; write garbage to start <A302/30oct86>
if NonSerializedIO then
nop ; force write to complete <SM4>
endif
lea Q6L(A4),A4 ; set up Q6L pointer <A302/30oct86>
WrStrtSync MOVE.L A1,A2 ; write a sync group
MOVEQ #(syncBytCnt/2)-1,D2 ;
WSS1 MOVE.B (A2)+,D4 ; prefetch
@0 TST.B (A4) ; check write handshake
BPL.S @0 ;
MOVE.B D4,(A3) ; write out next header nibble
if NonSerializedIO then
nop ; force write to complete <SM4>
endif
MOVE.B (A2)+,D4 ; prefetch
_PollSCC ; poll the SCC modem port <H5><SM6>
@2 TST.B (A4) ; check write handshake
BPL.S @2 ;
MOVE.B D4,(A3) ; write out next header nibble
if NonSerializedIO then
nop ; force write to complete <SM4>
endif
DBRA D2,WSS1
DBRA D3,WrStrtSync
WrNxtSect MOVE.W D1,D3 ; number of sync groups - 1
@1 MOVE.L A1,A2 ; write a sync group
MOVEQ #syncBytCnt-1,D2
@2 TST.B (A4) ; check write handshake
BPL.S @2 ;
MOVE.B (A2)+,(A3) ; write out next gap nibble
if NonSerializedIO then
nop ; force write to complete <SM4>
endif
_PollSCC ; poll the SCC modem port <H5><SM6>
@3 DBRA D2,@2
DBRA D3,@1
MOVEQ #adrBytCnt-1,D2
@4 TST.B (A4) ; check write handshake
BPL.S @4 ;
MOVE.B (A0)+,(A3) ; write out next adr mk nibble
if NonSerializedIO then
nop ; force write to complete <SM4>
endif
_PollSCC ; poll the SCC modem port <H5><SM6>
@5 DBRA D2,@4
MOVE.W #dataBytCnt-1,D2
@6 TST.B (A4) ; check write handshake
BPL.S @6 ;
MOVE.B #$96,(A3) ; write out next data mk nibble
if NonSerializedIO then
nop ; force write to complete <SM4>
endif
_PollSCC ; poll the SCC modem port <H5><SM6>
@7 DBRA D2,@6
MOVEQ #3,D2
ADDQ #8,A2 ; point to bit slip marks . . .
@8 TST.B (A4) ; check write handshake
BPL.S @8 ;
MOVE.B (A2)+,(A3) ; write out next bit slip nibble
if NonSerializedIO then
nop ; force write to complete <SM4>
endif
DBRA D2,@8
SUBQ.W #1,D0
BGT.S WrNxtSect ; write all sectors
MOVEA.L SonyVars,A1 ; <SM6>
TST.B mfmMode(A1) ; are we in ISM mode? <SM6>
BPL.S @NotSWIM2 ; -> no, it's either an IWM or SWIM <H4><SM6>
MOVEQ #3-1,D2 ; now write out three more gap bytes to fully clear the FIFO <SM6>
@11 TST.B (A4) ; check write handshake <SM6>
BPL.S @11 ; <SM6>
MOVE.B #$FF,(A3) ; write out next gap nibble <SM6>
DBRA D2,@11 ; <SM6>
MOVE.B (A4),D0 ; read write handshake reg for status <SM6>
MOVEQ #0,D2 ; assume no underrun <SM6>
BTST #5,D0 ; any errors? <SM6>
BEQ.S @12 ; branch if no underrun was detected<SM6>
MOVEQ #WrUnderRun,D0 ; underrun error <SM6>
BRA.S @13 ; <SM6>
@12 MOVEQ #0,D0 ; no errors <SM6>
@13 ; <SM6>
MOVE.B #$18,wZeroes-wData(A3) ;Clear the write and action bits<SM6>
if NonSerializedIO then
nop ; force write to complete <SM5>
endif
MOVE.L DskRtnAdr,-(SP) ; push DoFormat's return address <SM6>
TST.W D0 ; set CCR <SM6>
RTS ; <SM7>
@NotSWIM2 ; <SM6>
MOVE.B (A4),D0 ; read write handshake reg for status
MOVEQ #0,D2 ; assume no underrun
BTST #6,D0 ; any errors?
BNE.S @9 ; branch if no underrun was detected
MOVEQ #WrUnderRun,D0 ; underrun error
BRA.S @10
@9 MOVEQ #0,D0 ; no errors
@10 tst.b Q7L-Q6H(A3) ; get out of write mode after half <A351/05nov86><A302/30oct86>
; of garbage nibble is written
MOVE.L DskRtnAdr,-(SP)
TST.W D0 ; set CCR
RTS
eject ; <A351/05nov86>
;_____________________________________________________________________
;
; Routine: FillInMarks
; Arguments: A0.L (input) -- buffer pointer (must be 27*number of sectors)
; D0.W (input) -- number of sectors
; D6.W (input) -- side - track
; all registers are preserved
; Function: Fills in the buffer with the address marks (buffer is already
; filled with appropriate sync bytes . . .)
;
; 1 sync group (6)
; D5 AA 96 trk sec side vol cksum DE AA FF (11)
; 1 sync group (6)
; D5 AA AD sec (4)
;
;_____________________________________________________________________
TrkOffset EQU 9
SecOffset EQU 10
SidOffset EQU 11
VolOffset EQU 12
CkSumOffset EQU 13
DSecOffset EQU 26
FillInMarks
MOVEM.L A0-A1/D0-D7,-(SP)
MOVE.L SonyVars,A1
MOVE.L DiskBuffer(A1),A0 ; stack buffer
MOVEQ #FmtByte,D3 ; 1-sided format byte
TST.B TwoSided(A1) ; use 2-sided format?
BEQ.S @0 ; br if 1-sided
MOVEQ #Fmt2Byte,D3 ; 2-sided format byte
@0 MOVE.L NiblTbl,A1 ; nibble code table
MOVE.B 0(A1,D3),D7 ; D7 holds encoded volume byte
MOVE.B D3,D5 ; start checksum
MOVEQ #$3F,D3 ; 6-bit mask
AND.B D6,D3 ; get track low 6 bits
MOVE.B 0(A1,D3),D2 ; D2 holds encoded track number
EOR.B D3,D5 ; add it to checksum
LSR.W #6,D6 ; get track high bits/side
EOR.B D6,D5 ; add it to checksum
MOVE.B 0(A1,D6),D6 ; D6 holds encoded side/trk
MOVE.W D0,D1 ; number of sectors
SUBQ.W #1,D1
LSR.W #1,D1
ADDQ.W #1,D1 ; second sector number
SWAP D1
CLR.W D1 ; first sector number is always zero . . .
@1 MOVE.B 0(A1,D1),D3 ; D1 = next sector number
MOVEQ #0,D4 ; zero high byte
MOVE.B D5,D4 ; checksum minus sector nibble
EOR.B D1,D4 ; add it in
ADD #TrkOffset,A0 ; bump to track
MOVE.B D2,(A0)+ ; encoded track
MOVE.B D3,(A0)+ ; encoded sector
MOVE.B D6,(A0)+ ; encoded side
MOVE.B D7,(A0)+ ; encoded volume
MOVE.B 0(A1,D4),(A0)+ ; checksum
ADD #12,A0 ; point to data mark sector nibble
MOVE.B D3,(A0)+
ADDQ.W #1,D1 ; bump to next even/odd sector
SWAP D1 ; toggle between odd and even
SUBQ.W #1,D0
BNE.S @1
MOVEM.L (SP)+,A0-A1/D0-D7
RTS
eject ; <A351/05nov86>
;_______________________________________________________________________
;
; Routine: CtlVerify
; Arguments: A0.L (in) -- param block ptr
; A1.L (in) -- driver locals ptr
; D1.W (in) -- drive vars offset
; Drive (in) -- set to correct drive
; D0.W (out) -- result code (0 if correctly formatted)
; Function: This routine reads all sectors on the newly formatted
; diskette to verify correct format.
;_______________________________________________________________________
; change to work with 2-sided drives . . . allow to miss a couple sectors
; first spin (in case of serial data coming in . . .)
CtlVerify ; (add vector??)
SUB #512,SP ; get space for buffers we need off stack
MOVE.L SP,DiskBuffer(A1) ; StackBuf for mark, block buffer
IF hasPwrControls THEN ; <SM5>
TestFor hwCbPwrMgr
BEQ.S @pmgrdone
BSR TurnIWMon ; Turn IWM on with pmgr call <1.1/01mar88>
@pmgrdone
ENDIF ; <SM5>
TST.B isSWIM(A1) ;Is a SWIM installed? <C437/30sep87>
BPL.S @00 ;-> no, skip <C437/30sep87>
BSR SetChipMode ;Initialize the chip's registers <C437/21nov86>
BNE FmtVerExit ;-> couldn't do it <C437/21nov86>
@00 ; <C437/30sep87>
BSR FVPowerUp ; make sure we're powered (synchronously)
MOVEQ #4,D2 ; 5 speed classes
MOVE.W #$007F,D4 ; sector map track 79 (almost)
MOVEQ #79,D6 ; and track number 79
NxtVClass LSL.W #1,D4 ; sectors map this track speed class
ADDQ #1,D4 ; set low bit
MOVEQ #15,D3 ; tracks this speed class
NxtVTrk MOVEM.L D2-D6,-(SP)
BSR FmtVerSeek ; seek to desired track (synchronous)
MOVEM.L (SP)+,D2-D6
BSR GetDrv1
MOVE.W Track(A1,D1),D0
BMI.S @1 ; <C437/21nov86>
TST.B mfmDisk(A1,D1) ;Are we in MFM mode? <C437/21nov86>
BPL.S @00 ;-> no, do a regular verify <C437/21nov86>
BSR mVerTrack ;Verify the track (MFM style) <C437/21nov86>
BRA.S @0 ; <C437/21nov86>
@00 ; <C437/21nov86>
BSR.S VerTrack ; verify the track (GCR)
@0 BNE.S @1 ; exit on errors <C437/21nov86>
SUBQ.W #1,D6 ; next track
DBRA D3,NxtVTrk ; end of speed class?
DBRA D2,NxtVClass ; move to next speed class
@1 BRA FmtVerExit ; <C437/21nov86>
VerTrack MOVEM.L D2-D6,-(SP)
ORI #HiIntMask,SR ; no interrupts <29Jul85>
LEA SectMapSave(A1),A0 ; [map side 0][max tries][map side 1][max tries]
MOVE.W D4,(A0) ; save sector map
MOVEQ #12,D3
SUB D2,D3 ; sectors this track
LSL.W #2,D3 ; allow some slop (may not get 1-1) <25Oct85>
MOVE.W D3,2(A0)
MOVE.L (A0)+,(A0)+ ; duplicate for side 1
BCLR #3,SideTrack(A1) ; go for side 0
VTLoop MOVE.L D1,D6 ; <21Jun85> save drive offset
BSR RdAddrSetup ; get next address mark
BPL.S @1 ; br if ok
BSR.S toEmptyPD ; get rid of poll data
ANDI #$F8FF,SR ; open up interrupts
BRA.S VTExit
@1 LEA SectSave(A1),A0
MOVE.W D2,(A0)+ ; save sector number
MOVE.W (A0)+,D0 ; sector map
BCLR D2,D0 ; did we get this sector already?
BNE.S @2 ; br if not
BSR.S toEmptyPD ; get rid of poll data <30Oct85>
ANDI #$F8FF,SR ; open up interrupts <30Oct85>
LEA SectMapSave+2(A1),A0 ; point to max retries <30Oct85>
BRA.S @3 ; rejoin RdData for loop timeout check <30Oct85>
@2 CMP.B #$1F,D3 ; <21Jun85> check format type
SGT TwoSideFmt(A1,D6) ; <21Jun85> to determine 2-sided
; check track, side??
MOVE.L DiskBuffer(A1),A0 ; get someplace to stick data
CLR.B DskVerify ; never verify for this one
BSR RdData ; read in a sector
BSR.S toEmptyPD ; get rid of data
TST.W D0 ; read ok?
BNE.S VTExit
LEA SectSave(A1),A0
MOVE.W (A0)+,D2 ; sector we just read
MOVE.W (A0),D0 ; sector map
BCLR D2,D0 ; mark this sector gotten
MOVE.W D0,(A0)+ ; stash bitmap back
BEQ.S VTExitOK ; exit if now zero
@3 SUBQ.W #1,(A0) ; decrement sector count <30Oct85>
BNE.S VTLoop ; loop until done
MOVEQ #VerErr,D0 ; should get 1-1 ok reads
BRA.S VTExit
VTExitOK BSR GetDrv1 ; <21Jun85>
TST.B TwoSideFmt(A1,D1) ; <21Jun85> two-sided format?
BEQ.S @1 ; br if not
BSET #3,SideTrack(A1) ; just finished second side?
BNE.S @1 ; br if so
ADDQ #2,A0 ; point to sectmap/count copy
MOVE.L (A0),-(A0) ; and copy it back
BRA.S VTLoop ; and go for side 1
@1 MOVEQ #0,D0
VTExit ANDI #$F8FF,SR
MOVEM.L (SP)+,D2-D6
TST.W D0
RTS
toEmptyPD MOVE.W D0,DskErr ; save error code
BRA EmptyPD
FmtVerSeek LEA Seek,A0 ; a synchronous seek
SyncCall subq.b #1,Active(a1) ; use this to flag seek done . . . <2>
BSR.S @2
@1 cmpi.b #$FF,Active(a1) ; done? <2>
bne.s @1 ; br if not <2>
RTS
@2 JSR (A0)
addq.b #1,Active(a1) ; when we get back here we are done . . . <2>
RTS
FVPowerUp LEA RWPowerUp,A0 ; do the RW powerup trip synchronously
BRA.S SyncCall