; ; File: SonyFormat.a ; ; Contains: Sony Format/Verify routines ; ; Written by: Larry Kenyon, Steve C, Gary D, ... ; ; Copyright: © 1982-1990, 1992 by Apple Computer, Inc., all rights reserved. ; ; Change History (most recent first): ; ; 1/10/93 RC Added nop for Smurf ; 12/14/92 RC Restore Pre-PDM D2 With Horror Roll in ; 12/9/92 rab Fixed a bug I introduced rolling in DoFormatEndPatch. Was ; branching back into the SWIM code instead of doing an RTS. ; 12/7/92 rab Roll in Horror changes. Comments followÉ ; <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. ; 12/02/92 HY Added hasPwrControls conditionals. ; 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Õ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 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É ; 11/18/87 SWC Check to see if the disk is write-protected on a Format request, ; and if so, return an error. ; 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. ; 11/21/86 SWC Patched Format and Verify to jump to their MFM counterparts if ; we're running in MFM mode. ; 11/5/86 TJ Text cleanup. ; 10/30/86 TJ Removed IWM absolute address references. ; 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 ; TestFor hwCbPwrMgr BEQ.S @pmgrdone BSR TurnIWMon ; Turn IWM on with pmgr call <1.1/01mar88> @pmgrdone ENDIF ; MOVE.W csParam(A0),D4 ;Use current format? BEQ.S @0 ;-> yes, don't change anything MOVEQ #numSDFmts-1,D3 ;Assume no SWIM or SuperDrive MOVE.B isSWIM(A1),D0 ;Is a SWIM connected AND AND.B mfmDrive(A1,D1),D0 ; is this a SuperDrive? BPL.S @00 ; MOVEQ #numSDFmts,D3 ;Yes, we can do MFM!! TST.B twoMegFmt(A1,D1) ;Is this a double-density disk? BPL.S @00 ; MOVEQ #numDDFmts,D3 ;Yes, it must be 1440K @00 ; MOVEQ #paramErr,D0 ;Assume format type is outta range CMP.W D3,D4 ;Well, is it? BHI FmtVerExit ;-> yep, just exit CMPI.W #NumSDFmts,D4 ;(thanks, Mr. Davidian, sir) SEQ D0 ;MFM format if it's the last SD one OR.B twoMegFmt(A1,D1),D0 ; or it's double-density? SMI mfmDisk(A1,D1) ; @0 TST.B isSWIM(A1) ;Is a SWIM installed? BPL.S @01 ;-> no, skip BSR SetChipMode ;Set up the mode for MFM or GCR BNE FmtVerExit ;-> couldn't initialize the chip @01 ; BSR DiskSelect ;Re-select the interface TST.B mfmDisk(A1,D1) ;Are we in MFM mode? SMI TwoSided(A1) ; BMI.S @1 ;-> yes, we're 2-sided 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 SUBQ.W #1,D4 ; <21Jun85> format 2-sided as 1-sided? BNE.S @1 ; <21Jun85> br if not CLR.B TwoSided(A1) ; <21Jun85> force one-sided @1 TST.B TwoSided(A1) ; <21Jun85> so, 1-sided or 2-sided? 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? BSR AdrAndSense ; BMI.S @11 ;-> nope, onward! MOVEQ #wPrErr,D0 ;Return a write-protect error BRA.S FmtVerExit ;someone OBVIOUSLY wasn't checking-- @11 ;(massive finger pointing--Scott?) 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 @2 MOVEQ #27-1,D1 ; 27 bytes per sector MOVE.L A1,A2 ; point A2 to blank image @3 MOVE.B (A2)+,(A0)+ ; DBRA D1,@3 ; DBRA D0,@2 ; 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 ; TST.B mfmDisk(A1,D1) ;Are we in MFM mode? BPL.S @00 ;-> no, do the regular format BSR mFmtTrack ;Format the track (MFM style) BRA.S @0 ; @00 ; 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 ;(sets up the power down time) eject ; ;_______________________________________________________________________ ; ; 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 ; ;_______________________________________________________________________ ; ; 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) 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 eject ; ;_____________________________________________________________________ ; ; 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 lea Q6H(A4),A3 ; set up Q6H pointer (do Q6L later) 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? LEA SyncTbl,A1 ; BPL.S @NotSWIM2 ; -> no, it's either an IWM or SWIM

LEA wData(A4),A3 ; point to the write data and LEA rHandshake(A4),A4 ; handshake registers for speed TST.B rError-wData(A3) ; clear the error register MOVE.B #$18,wZeroes-wData(A3) ; clear the write and action bits MOVE.B #$10,wOnes-wData(A3) ; set the write bit MOVE.B #$01,wOnes-wData(A3) ; toggle the clFIFO bit to clear out MOVE.B #$01,wZeroes-wData(A3) ; any data in the FIFO TST.B rError-wData(A3) ; clear the error register again MOVE.B D3,(A3) ; write garbage to FIFO MOVE.B #$08,wOnes-wData(A3); turn on the action bit: GO! BRA.W WrStrtSync ;

@NotSWIM2 TST.B (A3) ; first byte written is a bit wierd move.b D3,Q7H(A4) ; write garbage to start if NonSerializedIO then nop ; force write to complete endif lea Q6L(A4),A4 ; set up Q6L pointer 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 endif MOVE.B (A2)+,D4 ; prefetch _PollSCC ; poll the SCC modem port
@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 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 endif _PollSCC ; poll the SCC modem port
@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 endif _PollSCC ; poll the SCC modem port
@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 endif _PollSCC ; poll the SCC modem port
@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 endif DBRA D2,@8 SUBQ.W #1,D0 BGT.S WrNxtSect ; write all sectors MOVEA.L SonyVars,A1 ; TST.B mfmMode(A1) ; are we in ISM mode? BPL.S @NotSWIM2 ; -> no, it's either an IWM or SWIM

MOVEQ #3-1,D2 ; now write out three more gap bytes to fully clear the FIFO @11 TST.B (A4) ; check write handshake BPL.S @11 ; MOVE.B #$FF,(A3) ; write out next gap nibble DBRA D2,@11 ; MOVE.B (A4),D0 ; read write handshake reg for status MOVEQ #0,D2 ; assume no underrun BTST #5,D0 ; any errors? BEQ.S @12 ; branch if no underrun was detected MOVEQ #WrUnderRun,D0 ; underrun error BRA.S @13 ; @12 MOVEQ #0,D0 ; no errors @13 ; MOVE.B #$18,wZeroes-wData(A3) ;Clear the write and action bits if NonSerializedIO then nop ; force write to complete endif MOVE.L DskRtnAdr,-(SP) ; push DoFormat's return address TST.W D0 ; set CCR RTS ; @NotSWIM2 ; 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 ; of garbage nibble is written MOVE.L DskRtnAdr,-(SP) TST.W D0 ; set CCR RTS eject ; ;_____________________________________________________________________ ; ; 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 ; ;_______________________________________________________________________ ; ; 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 ; TestFor hwCbPwrMgr BEQ.S @pmgrdone BSR TurnIWMon ; Turn IWM on with pmgr call <1.1/01mar88> @pmgrdone ENDIF ; TST.B isSWIM(A1) ;Is a SWIM installed? BPL.S @00 ;-> no, skip BSR SetChipMode ;Initialize the chip's registers BNE FmtVerExit ;-> couldn't do it @00 ; 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 ; TST.B mfmDisk(A1,D1) ;Are we in MFM mode? BPL.S @00 ;-> no, do a regular verify BSR mVerTrack ;Verify the track (MFM style) BRA.S @0 ; @00 ; BSR.S VerTrack ; verify the track (GCR) @0 BNE.S @1 ; exit on errors SUBQ.W #1,D6 ; next track DBRA D3,NxtVTrk ; end of speed class? DBRA D2,NxtVClass ; move to next speed class @1 BRA FmtVerExit ; 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