mirror of
https://github.com/elliotnunn/mac-rom.git
synced 2024-12-29 07:29:15 +00:00
4325cdcc78
Resource forks are included only for .rsrc files. These are DeRezzed into their data fork. 'ckid' resources, from the Projector VCS, are not included. The Tools directory, containing mostly junk, is also excluded.
939 lines
38 KiB
Plaintext
939 lines
38 KiB
Plaintext
;
|
|
; File: SonyRWT.a
|
|
;
|
|
; Contains: Sony 3.5" Floppy Disk Driver Read/Write Track Logic
|
|
;
|
|
; Written by: Larry Kenyon 05-May-83
|
|
;
|
|
; Copyright: © 1983-1993 by Apple Computer, Inc. All rights reserved.
|
|
;
|
|
; Change History (most recent first):
|
|
;
|
|
; <SM9> 12/13/93 PN Roll in KAOs and Horror changes to support Malcom and AJ
|
|
; machines
|
|
; <SM8> 1/10/93 RC Added Nop for Smurf
|
|
; <SM7> 12/14/92 RC Restore Pre-PDM D2 with Horror Roll-in
|
|
; <SM5> 12/7/92 rab Roll in Horror changes. Comments followÉ
|
|
; <H4> 2/13/92 CMP Patched AdrDtaErr to check if retries are disabled before
|
|
; attempting them.
|
|
; <H2> 10/18/91 CMP Overpatch for SWIM2 support. Also, changed the way the drives are
|
|
; disabled since those signals are no longer gated by MotorOn.
|
|
; <SM1> 12/02/92 HY Put back hasPwrControls conditional (for LC930, non-universal)
|
|
; and fix a branch out of range.
|
|
; <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, supportsDCD, and
|
|
; hasHarpoVIA are always false, forROM, supportsMFM, forDiskDup,
|
|
; isUniversal, hasPowerMgr, and hasPwrControls 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> 1/21/91 SWC Cleaned up header comments.
|
|
; <2> 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.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 Fixed bugs in GotSect, was using (a1,d6), but d6 may be invalid,
|
|
; use (a1,d1) instead, since GetDrv1 has been called. Let new
|
|
; interface drives (800K/SuperDrive) attempt 1 to 1 writes, since
|
|
; it will always work in MFM, and should usually work in GCR.
|
|
; Changed bit number of SCC/VIA direction bit save in chipState.
|
|
; <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.8> 8/19/88 SWC Save the format byte returned by RdAddr if for disk duplicator.
|
|
; <1.7> 8/16/88 GGD Restored VIA Buf B Direction bit in EmptyPD for HcMac
|
|
; <1.7> 8/9/88 GGD Restored VIA Buf B Direction bit in EmptyPD for HcMac
|
|
; <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/23/88 GGD No changes, entire sony driver 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
|
|
; <C437> 3/28/88 SWC GotSect: made 1-sector-wait on writes for GCR disks only (MFM
|
|
; does 1-1).
|
|
; <C437> 2/22/88 SWC OnTrack1: restored drive vars offset to D6 after RdData trashes
|
|
; it.
|
|
; <1.0> 2/12/88 BBM Adding file for the first time into EASEÉ
|
|
; 2/4/88 SWC DiskPrime: moved the SetChipMode and DiskSelect calls to before
|
|
; the branch to the DCD code (this was duplicated but now removed
|
|
; from SonyDCD).
|
|
; <C907> 10/13/87 MSH Port to HcMac (Laguna).
|
|
; 10/8/87 SWC Decrement the sector number for MFM disks when calculating cache
|
|
; offsets since MFM disks start with sector 1.
|
|
; 9/30/87 SWC Don't call SetChipMode if an IWM is installed and SetIWMMode
|
|
; wouldn't have been called anyway.
|
|
; <C437> 12/4/86 SWC Check disk format on entry if the disk is unclamped. Patched
|
|
; GetTrack to jump to mGetTrack (SonyMFM.a) if we're running in
|
|
; MFM mode (different sector layout). Set sector time to 7.5ms for
|
|
; MFM disks in OnTrack since the track format has fixed sector
|
|
; spacing.
|
|
; <C115> 8/22/86 TJ Made 400K Sony drive support conditional under 'supportsPWM';
|
|
; not supported on nuMac.
|
|
; <C97> 8/5/86 TJ Disabled some cache code so that writes update the disk, and
|
|
; hence the tags. (Tags were not in sync w/ sector data.)
|
|
; <C1> 5/5/86 RDC Changed old onMidmac conditional to onNuMac
|
|
; 11/3/85 LAK Fixed bug in last fix (track cacheing was always turned off).
|
|
; 10/31/85 LAK Turn off cache if RDData hook has been replaced (attempt to get
|
|
; other copy-protection schemes to work).
|
|
; 10/29/85 LAK Turn off cache on read errors (attempt to get Jazz copy
|
|
; protection to work reasonably).
|
|
; 10/25/85 LAK Skip thermal drift adjust for new drive (still check it). Use
|
|
; NewIntf rather than Sides to determine whether drive has new
|
|
; interface. Increment DriveErrs for address and data errors. On
|
|
; RWT waits, set up timer first before calling EmptyPD for more
|
|
; accurate waits (use TimeSetUp and TimeGo).
|
|
; 10/24/85 LAK Added support for track caching. Open up all ints after r/w of a
|
|
; sector to see if this fixes keyboard.
|
|
; 10/22/85 LAK Use CurSector to store sector number we are reading/writing
|
|
; instead of using TagData low-memory var which is overwritten on
|
|
; reads. For writes, don't allow retries before reseek for bad
|
|
; addrmark errors (should reduce the likelihood off-track
|
|
; trashing).
|
|
; 9/2/85 LAK Give an early warning for two-sided diskettes in old drives (new
|
|
; file system doesn't catch it as quickly).
|
|
; 8/14/85 LAK Don't overwrite TagData+10 with Time on writes.
|
|
; 7/29/85 RDC Added changes for MidMac: - changed interrupt level settings to
|
|
; use equates - removed DCD code - skip track speed checking
|
|
; 1/15/85 JTC Converted to MDS
|
|
; 11/10/84 LAK Cut enable to drive if no DIP at prime: try to prevent drive
|
|
; tick.
|
|
; 11/2/84 LAK Sped up logical block mapping.
|
|
; 10/26/84 LAK Patched Got1Sect to make 2-1 write possible; interrupts are
|
|
; always enabled now after every sector and 1-1 writes are always
|
|
; prevented.
|
|
; 8/20/83 LAK Added support of SpdAdjErr, SeekErr, SectNFErr (D0 did not
|
|
; necessarily have an error code in these cases).
|
|
; 8/20/83 LAK Added test of DskWr11 boolean before giving up on 1-1 writing.
|
|
; 8/15/83 LAK Verify mode bit is bit 6 now; added Andy's optimizations.
|
|
; 8/11/83 LAK Removed statistics; added support for 2-sided drives.
|
|
; 8/6/83 LAK Added support for read/verify mode. Increments RndSeed when
|
|
; wrong sector passes by . . .
|
|
; 7/24/83 LAK Fixed bug in EmptyPD (serial driver trashes A1 . . .) by
|
|
; reverting to ROM 3.1 code.
|
|
; 7/21/83 LAK If TagBufStrt drive variable is non-zero, tag data is now
|
|
; stripped from the data stream and read/written to/from the
|
|
; separate buffer.
|
|
; 7/10/83 LAK Fixed bug in thermal-drift compensation code.
|
|
; 6/23/83 LAK Updated to compensate for speed thermal drift! Subroutined the
|
|
; 'drive exist' and 'disk-in-place' checks to share with the disk
|
|
; VBL task.
|
|
; 5/27/83 LAK Changed for new 5-speed class format
|
|
; 5/11/83 LAK MakeSpdTbl no longer trashes A1 on error path (in DoRecal).
|
|
; 5/5/83 LAK Adapted from twiggy driver for 3-1/2 inch drive . . .
|
|
;
|
|
title 'File: SonyRWT.a'
|
|
;_______________________________________________________________________
|
|
;
|
|
; This is the mainline of the disk driver. It processes
|
|
; the request parameter block a track at a time.
|
|
;
|
|
; Arguments: A0 (input) -- pointer to request parameter block
|
|
; A1 (input) -- pointer to disk DCE
|
|
;_______________________________________________________________________
|
|
|
|
|
|
; Here is the prime routine, which gets reads and writes going.
|
|
|
|
BLANKS ON
|
|
STRING ASIS
|
|
|
|
DiskPrime MOVE.L JDiskPrime,-(SP)
|
|
RTS
|
|
|
|
jtDiskPrime ORI #VIAIntMask,SR ; exclude VBL interrupts <29Jul85>
|
|
|
|
MOVE.W IOTrap(A0),D3 ; save I/O command
|
|
BTST #6,IOPosMode+1(A0) ; check for read verify mode
|
|
SNE DskVerify ; note for later
|
|
|
|
BSR.S CkDrvNum ; check for valid drive number and setup
|
|
BNE DiskErr ; exit if bad drive error
|
|
MOVE.W D3,Command(A1) ; note I/O command
|
|
|
|
; ok, we should already know what's connected out there . . .
|
|
; if nothing, then just exit. . . otherwise, select the drive
|
|
; and continue . . .
|
|
|
|
MOVEQ #NoDriveErr,D0 ; assume no drive installed <03Mar85>
|
|
TST.B Installed(A1,D1) ; 1=installed, $FF=not <03Mar85>
|
|
BMI DiskErr ; exit if nothing connected <03Mar85><C437/14sep87>
|
|
|
|
IF hasPwrControls THEN ; <SM1>
|
|
TestFor hwCbPwrMgr
|
|
BEQ.S @pmgrdone
|
|
|
|
BSR TurnIWMon ; Turn IWM on with pmgr call <C907>
|
|
@pmgrdone
|
|
ENDIF ; <SM1>
|
|
|
|
TST.B isSWIM(A1) ;Is a SWIM installed? <C437/30sep87>
|
|
BPL.S @00 ;-> no, skip <C437/30sep87>
|
|
BSR SetChipMode ;Make sure the chip is set up OK <C437/14sep87>
|
|
@00 ; <C437/30sep87>
|
|
|
|
BSR DiskSelect ; select the appropriate interface
|
|
|
|
; check disk-in-place at the drive . . . (may have been manually ejected)
|
|
|
|
MOVEQ #DIPAdr,D0 ;
|
|
BSR AdrAndSense ; sets up A0,A1,A2,D1
|
|
BPL.S @1 ; br if disk in place
|
|
|
|
CLR.B DiskInPlace(A1,D1) ; no diskette here
|
|
|
|
MOVE.B #$86,wZeroes(A0) ;Cut drive enable (SWIM2 style) <2><CMP><SM2>
|
|
if NonSerializedIO then
|
|
nop ; force write to complete <SM5>
|
|
endif
|
|
|
|
TST.B MtrOff(A0) ; cut enable to drive to prevent ticking
|
|
MOVEQ #OffLinErr,D0 ; report it as no DIP . . .
|
|
BRA DiskErr ; <SM1>
|
|
|
|
@1 CMP.B #2,DiskInPlace(A1,D1) ; is it already clamped?
|
|
BEQ.S CkWrProt ; br if so
|
|
|
|
|
|
CLR.B mfmDisk(A1,D1) ;Make sure we're in GCR mode on <C437/17jun87>
|
|
; powerup for proper disk chucking <C437/17jun87>
|
|
TST.B isSWIM(A1) ;Is a SWIM installed? <C437/30sep87>
|
|
BPL.S @10 ;-> no, skip <C437/30sep87>
|
|
BSR SetChipMode ;switch the SWIM chip to IWM mode <C437/17jun87>
|
|
@10 ; <C437/30sep87>
|
|
|
|
BSR FastPower ; power-on drive (no wait cause we'll
|
|
BSR Recal ; call MakeSpdTbl) and recal
|
|
BMI.S DskImmOff ; exit on errors
|
|
|
|
BSR MakeSpdTbl ; figure speeds out via tach
|
|
BNE.S DskImmOff ; exit on errors
|
|
|
|
MOVEQ #WrProtAdr,D0 ; once we recal it should be safe
|
|
BSR AdrAndSense ; to check write protect . . .
|
|
SPL WriteProt(A1,D1) ; write-protect sense (FF=writeprot)
|
|
|
|
CLR.B TwoSideFmt(A1,D1) ; assume one-sided disk format at first
|
|
MOVE.B #2,DiskInPlace(A1,D1) ; note that we have recal'ed
|
|
|
|
BRA ChkDiskType ;Find out how the disk's formatted <C437/04dec86>
|
|
|
|
; check for write-protected diskette and a write
|
|
|
|
CkWrProt BSR CheckRead ; is it a read?
|
|
BEQ.S RWPower ; br if so
|
|
|
|
MOVE.W TagData+8,FirstFSeq(A1) ; save the first file sequence number
|
|
TST.B WriteProt(A1,D1) ; FF=writeprotected
|
|
BPL.S RWPower ; branch if not
|
|
MOVEQ #WPrErr,D0 ; diskette write-protected!
|
|
|
|
DskRWOff MOVE.W PwrOffTime(A1),D2 ; read/write power-down time
|
|
BRA.S POffExit ; speed determine errors
|
|
|
|
DskImmOff MOVEQ #0,D2 ; immediate power-down for recal and
|
|
|
|
; The following exit is shared by the Format/Verify control routines
|
|
|
|
POffExit MOVE.W D0,-(SP) ; save error code
|
|
MOVE.W D2,D0 ; power-down time
|
|
BSR PowerDown ; initiate powerdown
|
|
MOVE.W (SP)+,D0 ; restore error code
|
|
|
|
; here we handle the disk priming errors
|
|
|
|
DiskErr ANDI #$F8FF,SR ; open up interrupts
|
|
BRA DiskDone ; tell the OS about it
|
|
|
|
; make sure the drive is powered and start going for the data . . .
|
|
|
|
RWPower MOVE.W Track(A1,D1),D6 ; set speed for last track read . . .
|
|
BSR RWPowerUp ; turn on drive and delay until powered
|
|
eject ; <A351/05nov86>
|
|
;_______________________________________________________________________
|
|
;
|
|
; Routine: GetTrack
|
|
; Arguments: (input): disk is powered and selected
|
|
; (output): SideTrack - set to next track to process
|
|
; FirstSect - first sector on that track we need
|
|
; SectMap - bit map of sectors on that track we need
|
|
; FBlksDone - number of blocks done prior to this track
|
|
; DiskBuffer - points to point in buffer 4 this track
|
|
; RecalCnt - initialized to number of recals per trk
|
|
; Called By: this is really DiskPrime, part II
|
|
; Function: This code is executed before reading or writing the data
|
|
; on a single track.
|
|
;_______________________________________________________________________
|
|
|
|
GetTrack MOVE.L DiskUnitPtr(A1),A2 ; Device Ctl Entry ptr
|
|
MOVE.L DCtlQHead(A2),A0 ; current request ptr
|
|
MOVE.L DCtlPosition(A2),D0 ; current byte position
|
|
MOVEQ #9,D7 ;
|
|
LSR.L D7,D0 ; convert to block number (div by 512)
|
|
|
|
; at this point:
|
|
; A0 = user request parameter blk ptr
|
|
; A1 = disk locals ptr
|
|
; A2 = disk driver DCE ptr
|
|
; D1 = drive locals offset
|
|
; D0 = absolute diskette block number
|
|
; D7 = 9 (2^9=512)
|
|
;
|
|
; now figure out the next track number we need, the first sector number we want
|
|
; on this track and the bitmap of sectors we want from this track/side . . .
|
|
|
|
TST.B mfmDisk(A1,D1) ;Is this an MFM disk? <C437/04dec86>
|
|
BMI mGetTrack ;-> yes, sector layout is different <C437/04dec86>
|
|
|
|
MOVEQ #0,D4 ; 0 = 1-sided format = side 0
|
|
TST.B TwoSideFmt(A1,D1) ;
|
|
BEQ.S @1 ;
|
|
MOVEQ #1,D4 ; 1 = 2-sided format = side 1
|
|
|
|
@1 MOVEQ #100,D2 ;
|
|
LSL #3,D2 ; D2 = 800
|
|
LSL D4,D2 ; block #, end of disk
|
|
|
|
CMP.L D2,D0 ; block number past end of disk block?
|
|
BLT.S NxtClass ; br if not
|
|
|
|
DskParmErr MOVEQ #ParamErr,D0 ; disk position parameter too high
|
|
ToDRWOff BRA.S DskRWOff ; exit, activating power-down task
|
|
|
|
NxtClass MOVEQ #7,D3 ; 8 blks/track in last speed class
|
|
LSL #4,D3 ; 128 blks/side in last speed class
|
|
LSL D4,D3 ; blks in last speed class
|
|
|
|
MOVEQ #16,D5
|
|
LSL D4,D5 ; next speed class has 16-32 more blks
|
|
|
|
@1 ADD D5,D3 ; next lower speed class has more blks
|
|
SUB.L D3,D2 ; first blk #, this spd class
|
|
CMP.L D2,D0 ;
|
|
BLT.S @1 ; br if blk in a lower speed class
|
|
|
|
NxtTrack LSR #4,D3 ; blks/cylinder
|
|
MOVEQ #-1,D5 ; will hold trk offset, this speed class
|
|
|
|
@1 ADD D3,D2 ; first blk # next track
|
|
ADDQ #1,D5 ;
|
|
CMP D2,D0 ;
|
|
BGE.S @1 ; loop until past track
|
|
|
|
LSR D4,D3 ; blks per track, this speed class
|
|
MOVEQ #12,D6 ;
|
|
SUB D3,D6 ;
|
|
LSL #4,D6 ; first track this speed class
|
|
ADD D6,D5 ; the track we're on!
|
|
|
|
MOVE.L D4,D6 ; side
|
|
SUB D3,D2 ; first blk#, this track
|
|
CMP.L D2,D0 ;
|
|
BGE.S @2 ; br if on this track
|
|
SUB D3,D2 ; must be side 0 of 2-sided cylinder
|
|
MOVEQ #0,D6 ;
|
|
|
|
@2
|
|
gtResume ;This is where mGetTrack returns <C437/04dec86>
|
|
|
|
TST.B D6 ; side 1 or side 0?
|
|
BEQ.S @3 ; br if side 0
|
|
BSET #11,D5 ; set for side 1
|
|
TST.B Sides(A1,D1) ; do we have a 2-sided drive?
|
|
BNE.S @3 ; br if so
|
|
MOVEQ #twosideErr,D0 ; can't read it on a 1-sided drive
|
|
BRA.S ToDRWOff ; exit, activating power-down task
|
|
|
|
@3 MOVE.W D5,SideTrack(A1) ; side/track we want to be on
|
|
|
|
SUB D2, D0 ; first sector this track
|
|
SUB D0, D3 ; sectors left this track
|
|
MOVE.W D0,FirstSect(A1) ;
|
|
|
|
MOVE.L IOByteCount(A0),D5 ; get # of bytes requested
|
|
MOVE.L IONumDone(A0),D2 ; get # of bytes already done
|
|
SUB.L D2,D5 ; minus the ones we processed already
|
|
LSR.L D7,D5 ; round down to nearest sector
|
|
BEQ.S DskParmErr ; uneven parameter error . . .
|
|
|
|
; D5 = number of sectors (blocks) we have to go
|
|
; D3 = number of sectors still left on this track
|
|
|
|
CMP.W D5,D3 ; want all remaining sectors this trk?
|
|
SLT D6 ; D6=$00 if it's the last track to do <24Oct85>
|
|
BLE.S @4 ; branch if so
|
|
MOVE.W D5,D3 ; number of sectors to get this track
|
|
|
|
; at this point:
|
|
; A0 = ptr to user request parameter blk
|
|
; (A1,D1) = ptr to drive locals
|
|
; A2 = ptr to disk driver DCE
|
|
; D0 = first 'track sector' to get this track
|
|
; D2 = IONumDone
|
|
; D3 = number of sectors to get this track
|
|
; D6 = $00 if this is the last track we have to do <24Oct85>
|
|
; D7 = 9
|
|
; FirstSect = first sequential sector number we want this track
|
|
|
|
@4 MOVEQ #0,D5 ; sector bit map
|
|
MOVE.W D0,D4 ; save 1st sector number and sector <24Oct85>
|
|
MOVE.W D3,-(SP) ; count for cache check <24Oct85>
|
|
|
|
@5 BSET D0,D5 ; one bit is always set for FirstSect
|
|
ADDQ.W #1,D0 ; incr to next sector number
|
|
SUBQ.W #1,D3 ; decr number of sectors needed
|
|
BNE.S @5
|
|
|
|
MOVE.W (SP)+,D3 ; restore sector count <24Oct85>
|
|
MOVE.L D5,SectMap(A1) ; keep sector bitmap around
|
|
|
|
MOVE.L IOBuffer(A0),A3 ; get pointer to user buffer <24Oct85>
|
|
ADD.L D2,A3 ; add IONumDone <24Oct85>
|
|
MOVE.L A3,DiskBuffer(A1) ; start buf addr, 1st sector this trk <24Oct85>
|
|
LSR.L D7,D2 ; figure file blocks done so far
|
|
MOVE.W D2,FBlksDone(A1) ; and save (for file tag writes)
|
|
MOVE.B RecalInit(A1),RecalCnt(A1) ; one recal per track
|
|
|
|
; OK, it's time to check whether our track cache (if any) has the blocks we need
|
|
;
|
|
; A0 = ptr to user request parameter blk
|
|
; (A1,D1) = ptr to drive locals
|
|
; A2 = ptr to disk driver DCE
|
|
; A3 = start buf addr for 1st sector this track
|
|
; D3 = sector count this track
|
|
; D4 = first 'track sector' to get this track
|
|
; D5 = bitmap of needed track sectors
|
|
; D6 = $00 if this is the last track we have to do <24Oct85>
|
|
; D7 = 9
|
|
; FirstSect = first sequential sector number we want this track
|
|
|
|
CheckCache
|
|
|
|
; cache cache
|
|
; valid read installed action
|
|
;
|
|
; dc dc no reset TCRdEnable (TCRdEnable,TCInstalled both zero)
|
|
; no no yes reset TCRdEnable (preserve cache for a different track)
|
|
; no yes yes if sync call and no sectors needed on another track,
|
|
; set TCRdEnable and init cache for this drive/track/side.
|
|
; yes no yes reset TCRdEnable invalidate cache for written sectors
|
|
; yes yes yes get appropriate sectors from cache; if sync call,
|
|
; and no sectors needed on another track, set TCRdEnable.
|
|
; If verify, skip cache always.
|
|
|
|
CLR.B TCRdEnable(A1) ; assume we won't be caching this RWT <24Oct85>
|
|
BSR CheckRead ; is this a read call?
|
|
BEQ.S readCache ; br if so
|
|
BSR CacheValid ; do we have a valid cache?
|
|
BNE.S toReSeek ; continue with RWT if not
|
|
|
|
MOVE.L D5,D0 ; get bitmap of sectors we are writing
|
|
NOT.L D0 ; form bitmap of those we aren't writing
|
|
AND.L D0,TCSectMap(A1) ; invalidate those sectors we write
|
|
; BSR TCRdEnbChk ; reads into cache if sync call, last trk <C115/05aug86>
|
|
toReSeek BRA ReSeek ; continue with RWT (MIGHT WANT TO ENABLE CACHE READS?)
|
|
|
|
readCache TST.B DskVerify ; read-verify? <25Oct85>
|
|
BNE.S toReSeek ; skip caching if so <25Oct85>'
|
|
BSR CacheValid ; do we have a valid cache?
|
|
BNE rdCacheNV ; br if not
|
|
|
|
MOVE.L D5,D2 ; get bitmap of sectors we are reading
|
|
AND.L TCSectMap(A1),D2 ; see if we have any currently cached
|
|
BEQ rc_Cont ; br if not . . . <C437/08oct87>
|
|
|
|
MOVEQ #2,D7 ; number of bytes/sector
|
|
ASL.L #8,D7 ; (cheap way to make 512)
|
|
|
|
MOVE.W D4,D0 ; first sector needed this track
|
|
|
|
TST.B mfmDisk(A1,D1) ;Is this an MFM disk? <C437/08oct87>
|
|
BPL.S @00 ; <C437/08oct87>
|
|
SUBQ.W #1,D0 ;Yes, the buggers start with sector 1 <C437/08oct87>
|
|
@00 ; not sector zero!!! <C437/08oct87>
|
|
|
|
MULU #524,D0 ; offset into cache buffer
|
|
MOVE.L TCBuffer(A1),A4 ; get track cache buffer ptr
|
|
ADD D0,A4 ; track cache buffer for first sector
|
|
|
|
rc_Loop BTST D4,D2 ; do we have and need this sector?
|
|
BEQ.S @3 ; br if not
|
|
BCLR D4,D5 ; mark it got in sector map
|
|
|
|
MOVEM.L A0-A1,-(SP) ; preserve regs over blockmove
|
|
|
|
TST.L TagBufPtr(A1) ; do we have a separate tag buffer?
|
|
BEQ.S @1 ; br if not (transfer to low-mem)
|
|
|
|
MOVE.W D4,D0 ; current sector
|
|
SUB.W FirstSect(A1),D0 ; relative sector number this track
|
|
ADD.W FBlksDone(A1),D0 ; blocks done so far
|
|
MULU #12,D0 ; offset into caller's tag buffer
|
|
MOVE.L TagBufPtr(A1),A1 ; separate tag buffer
|
|
ADD.L D0,A1 ; ptr into it
|
|
BRA.S @2 ; transfer the tags
|
|
|
|
@1 LEA TagData+2,A1 ; copy them to low-memory
|
|
|
|
@2 MOVE.L A4,A0 ; track cache
|
|
|
|
MOVE.L (A0)+,(A1)+ ; transfer tags
|
|
MOVE.L (A0)+,(A1)+
|
|
MOVE.L (A0)+,(A1)+
|
|
|
|
MOVE.L A3,A1 ; user buffer address
|
|
MOVE.L D7,D0 ; 512-byte blockmove
|
|
_BlockMove ; transfer data
|
|
MOVEM.L (SP)+,A0-A1
|
|
|
|
ADDQ.W #1,TCNumUsed(A1) ; increment cache usage count <25Oct85>
|
|
ADD.L D7,DCtlPosition(A2) ; bump position (not accurate until done)
|
|
ADD.L D7,IONumDone(A0) ; bump number done
|
|
|
|
@3 ADD.L D7,A3 ; bump user buffer address
|
|
ADD.L D7,A4 ; bump track cache buffer address
|
|
ADD #12,A4 ; (track cache includes tags)
|
|
ADDQ.W #1,D4 ; incr to next sector number
|
|
SUBQ.W #1,D3 ; decr number of sectors needed
|
|
BNE.S rc_Loop ; go again if not done
|
|
|
|
MOVE.L D5,SectMap(A1) ; update sector bitmap
|
|
BNE.S rc_Cont ; br if not finished with this track
|
|
|
|
MOVE.L IONumDone(A0),D0 ; bytes done so far
|
|
CMP.L IOByteCount(A0),D0 ; more to do?
|
|
BLT GetTrack ; loop if more to do
|
|
MOVEQ #0,D0 ; success!
|
|
BRA DskRWOff ; sayonara
|
|
|
|
rc_Cont BSR.S TCRdEnbChk ; enable reads into cache if sync call, last track
|
|
BRA.S ReSeek ; continue with RWT
|
|
|
|
rdCacheNV BSR.S TCRdEnbChk ; enable reads into cache if sync call, last track
|
|
BNE.S ReSeek ; continue with RWT if not
|
|
|
|
MOVE.W Drive(A1),TCDrive(A1) ; initialize cache
|
|
MOVE.W SideTrack(A1),TCSideTrack(A1) ; current side and track
|
|
CLR.L TCSectMap(A1) ; no sectors so far
|
|
BRA.S ReSeek ; and on to RWT
|
|
|
|
; TCRdEnbChk checks whether this is a synchronous call and we're on the last track
|
|
|
|
TCRdEnbChk ; <22Oct85>
|
|
TST.B TCInstalled(A1) ; installed and enabled?
|
|
BEQ.S @2 ; exit if not
|
|
BTST #AsyncTrpBit,Command(A1) ; async bit on?
|
|
BNE.S @1 ; br if so
|
|
TST.B D6 ; more sectors needed on another track?
|
|
@1 SEQ TCRdEnable(A1) ; activate reads into cache if sync, last track
|
|
RTS ; BEQ for sync, last track, enabled
|
|
@2 MOVEQ #1,D6 ; force NE
|
|
BRA.S @1
|
|
|
|
; CacheValid checks to see if the cache is valid for current drive/side/track
|
|
|
|
CacheValid ; <22Oct85>
|
|
TST.B TCInstalled(A1) ; installed and enabled?
|
|
BEQ.S @1 ; exit if not
|
|
MOVE.W TCDrive(A1),D0 ; get cache drive
|
|
BEQ.S @1 ; br if not valid
|
|
CMP.W Drive(A1),D0 ; same drive?
|
|
BNE.S @1 ; br if not
|
|
MOVE.W SideTrack(A1),D0 ; get track side/track
|
|
SUB.W TCSideTrack(A1),D0 ; current side and track match?
|
|
BEQ.S @2 ; br if cache is set up
|
|
|
|
@1 MOVEQ #-1,D0 ; not valid
|
|
@2 RTS ; BEQ for valid
|
|
|
|
eject ; <A351/05nov86>
|
|
;_______________________________________________________________________
|
|
;
|
|
; Routine: ReSeek
|
|
; Arguments: (input): disk is powered and selected
|
|
; SideTrack - set to next track to process
|
|
; FirstSect - first sector on that track we need
|
|
; SectMap - bit map of sectors on that track we need
|
|
; FBlksDone - number of blocks done prior to this track
|
|
; DiskBuffer - points to point in buffer 4 this track
|
|
; RecalCnt - initialized to number of recals per trk
|
|
; (output): nothing
|
|
; Called By: this is DiskPrime, part III
|
|
; Function: Seek to the desired track; check the speed at the track if
|
|
; it's time, and adjust it if necessary.
|
|
;_______________________________________________________________________
|
|
|
|
ReSeek MOVE.L JReSeek,-(SP)
|
|
RTS
|
|
|
|
jtReSeek MOVE.B BadSpdInit(A1),BadSpdCnt(A1)
|
|
|
|
; seek (asynchronously) to get to the right track (seek handles the case where
|
|
; we are already at the right track . . .)
|
|
|
|
ReSeek1 MOVE.W SideTrack(A1),D6 ; seek . . .
|
|
BSR Seek
|
|
BMI.S toDoRecal ; (to DoRecal) recal on errors <25Oct85>
|
|
MOVE.B ReadErrInit(A1),ReadErrCnt(A1)
|
|
|
|
BRA.S OnTrack ; skip track speed check for NuMac <C1/5May86>
|
|
|
|
toDoRecal BRA DoRecal ; recal eventually . . . <25Oct85>
|
|
|
|
eject ; <A351/05nov86>
|
|
;_______________________________________________________________________
|
|
;
|
|
; Routine: OnTrack
|
|
; Arguments: (input): disk is powered and selected
|
|
; SideTrack - set to next track to process
|
|
; FirstSect - first sector on that track we need
|
|
; SectMap - bit map of sectors on that track we need
|
|
; FBlksDone - number of blocks done prior to this track
|
|
; DiskBuffer - points to point in buffer 4 this track
|
|
; RecalCnt - initialized to number of recals per trk
|
|
; (A1,D1) - points at drive variables
|
|
; (output): DCtlPosition - updated by bytes processed
|
|
; IONumDone - updated by bytes processed
|
|
; SectMap - cleared
|
|
; Called By: this is DiskPrime, part IV
|
|
; Function: Read each address mark as it passes under the head; if that
|
|
; sector is needed, read or write it as desired and pass any
|
|
; poll data on to the serial driver.
|
|
;
|
|
; Note: as a sector passes over the r/w head, the current file block and
|
|
; tag buffer pointers are figured so:
|
|
;
|
|
; current file block = FirstFSeq + FBlksDone + (sector-FirstSect)
|
|
; tag buffer pointer = [FBlksDone + (sector-FirstSect)] * 12
|
|
;_______________________________________________________________________
|
|
|
|
OnTrack MOVE.B WrgSectInit(A1),WrgSectCnt(A1) ; addr mark misses we tolerate
|
|
|
|
; At this point, we should be on the right track. Read the next
|
|
; address mark to see where we are. RdAddr sets interrupt level 3.
|
|
|
|
OnTrack1 MOVE.W D1,D6 ; preserve drive offset <24Oct85>
|
|
BSR RdAddrSetup ; set up for and call RdAddr
|
|
BMI AdrDtaErr ; process stack data, go to AdrDtaErr <24Oct85>
|
|
|
|
CMP.W SideTrack(A1),D1 ; are we on the right track and side?
|
|
BNE WrgSideTrk ; <24Oct85>
|
|
|
|
MOVE.B D3,gcrFmtByte(A1) ; save format byte for the duplicator <1.8>
|
|
|
|
MOVE.W D2,CurSector(A1) ; save the sector number <22Oct85>
|
|
MOVE.W D2,TagData ; set up TagData+1 for writes
|
|
MOVE.L SectMap(A1),D0 ; sector bitmap of needed sectors
|
|
BTST D2,D0 ; do we need this sector?
|
|
BNE OTSetUp ; br if so . . . normal r/w path <24Oct85>
|
|
|
|
TST.B TCRdEnable(A1) ; are we reading into a cache? <22Oct85>
|
|
BEQ WrgSectAdr ; go to WrgSectAdr if not <24Oct85>
|
|
MOVE.L TCSectMap(A1),D0 ; see if we have it in the cache yet <24Oct85>
|
|
BTST D2,D0 ; <24Oct85>
|
|
@toWrgSectAdr ; <H6>
|
|
BNE WrgSectAdr ; go to WrgSectAdr if so <24Oct85>
|
|
|
|
LEA jtRdData,A0 ; no, use the normal rdData routine <H2><SM2>
|
|
CMP.B #-2,isSWIM(A1) ; Check for presence of SWIM2 <H2><SM2>
|
|
BNE.S @NotSWIM2 ; <H2><SM2>
|
|
LEA jtISMRdData,A0 ; yes, use the SWIM2 rdData routine <H2><SM2>
|
|
@NotSWIM2 ; <H2><SM2>
|
|
CMP.L JRdData,A0 ; has been replaced or prefixed --- <03Nov85>
|
|
SNE TCRdEnable(A1) ; i.e., this is a copy-protection <31Oct85>
|
|
BNE WrgSectAdr ; check . . . skip cache if so <31Oct85>
|
|
|
|
MOVE.W D2,D1 ; sector number <24Oct85>
|
|
|
|
TST.B mfmDisk(A1,D6) ;Is this an MFM disk? <C437/08oct87>
|
|
BPL.S @00 ; <C437/08oct87>
|
|
SUBQ.W #1,D2 ;Yes, the buggers start with sector 1 <C437/08oct87>
|
|
; not sector zero!!! <C437/08oct87>
|
|
BMI.S @toWrgSectAdr ; don't cache sector zero!! <H6>
|
|
@00 ; <C437/08oct87>
|
|
|
|
MULU #524,D2 ; tag/data offset into track cache buf <24Oct85>
|
|
MOVE.L TCBuffer(A1),A0 ; buffer start <24Oct85>
|
|
ADD.L D2,A0 ; add in offset to tag/data <24Oct85>
|
|
ADD #12,A0 ; skip over tags to data <24Oct85>
|
|
|
|
BSR RdData ; read the data mark <24Oct85>
|
|
|
|
BSR GetDrv1 ;get A1,D1 back <C437/22feb88>
|
|
MOVE.W D1,D6 ; and save the drive vars offset in D6 <C437/22feb88>
|
|
TST.W D0 ;reset the CCR with RdData's result <C437/11mar88>
|
|
|
|
SPL TCRdEnable(A1) ; turn off cache this trk on errors <29Oct85>
|
|
BMI.S @1 ; ignore errors (may be copy-prot sect) <24Oct85>
|
|
|
|
ADDQ.W #1,TCNumCached(A1) ; increment cache activity count <25Oct85>
|
|
MOVE.W CurSector(A1),D2 ; get sector number we read <24Oct85>
|
|
MOVE.L TCBuffer(A1),A0 ; buffer start <24Oct85>
|
|
MOVE.W D2,D1 ; sector number <24Oct85>
|
|
|
|
TST.B mfmDisk(A1,D6) ;Is this an MFM disk? <C437/08oct87>
|
|
BPL.S @01 ; <C437/08oct87>
|
|
SUBQ.W #1,D1 ;Yes, the buggers start with sector 1 <C437/08oct87>
|
|
@01 ; not sector zero!!! <C437/08oct87>
|
|
|
|
MULU #524,D1 ; tag offset into track cache buffer <24Oct85>
|
|
ADD.L D1,A0 ; add in offset to tag/data this sect <24Oct85>
|
|
|
|
LEA TagData+2,A2 ; <24Oct85>
|
|
MOVE.L (A2)+,(A0)+ ; transfer tag data from low memory <24Oct85>
|
|
MOVE.L (A2)+,(A0)+ ; <24Oct85>
|
|
MOVE.L (A2)+,(A0)+ ; <24Oct85>
|
|
|
|
MOVE.L TCSectMap(A1),D4 ; get the cache sector map <24Oct85>
|
|
BSET D2,D4 ; flag it as valid <24Oct85>
|
|
MOVE.L D4,TCSectMap(A1) ; update the map <24Oct85>
|
|
|
|
@1 BSET #7,IntFlag ; do we need to open up ints for <24Oct85>
|
|
BNE.S @2 ; AppleTalk? br if not . . . <24Oct85>
|
|
MOVE.W SectTime(A1),D0 ; set up timer for 1 sector time <25Oct85>
|
|
|
|
TST.B mfmDisk(A1,D6) ;Are we in MFM mode? <C437/04dec86>
|
|
BPL.S @11 ;-> no <C437/04dec86>
|
|
MOVEQ #MFMSectTime,D0 ;MFM sectors have a fixed gap size <C437/04dec86>
|
|
@11 ; <C437/04dec86>
|
|
|
|
BSR WakeSetUp ; return immediately <25Oct85>
|
|
BSR EmptyPD ; process stack data <25Oct85>
|
|
BSR WakeGo ; do the wait (and enable ints) <25Oct85>
|
|
BRA.S @3
|
|
|
|
@2 BSR EmptyPD ; process stack data <24Oct85>
|
|
ANDI #$F8FF,SR ; open for SCC/VIA ints <24Oct85>
|
|
|
|
@3 BRA OnTrack ; now try for the real data <24Oct85>
|
|
|
|
OTSetUp CMP.B #$1F,D3 ; set format type
|
|
SGT TwoSideFmt(A1,D6) ; and save it to distinguish 2-sided disks
|
|
SUB.W FirstSect(A1),D2 ; relative sector number this track
|
|
MOVE.W D2,D1
|
|
ASL.L #8,D1
|
|
ADD.L D1,D1 ; sector # times 512
|
|
ADD.L DiskBuffer(A1),D1 ; add in buffer start
|
|
MOVE.L D1,A0 ; data buffer pointer
|
|
|
|
MOVE.W FBlksDone(A1),D1 ; blocks done so far
|
|
ADD.W D2,D1 ; relative block number
|
|
MOVE.W D1,D0 ; save for write case
|
|
ADD.W D1,D1 ; double
|
|
ADD.W D0,D1 ; x3
|
|
ASL.W #2,D1 ; x12 gives us offset into buffer
|
|
MOVE.W D1,TagBufOS(A1) ; save in case of read
|
|
|
|
BSR CheckRead ; is it a read?
|
|
BEQ.S OTRead ; br if so
|
|
|
|
; it was a write request so call write data mark
|
|
|
|
OTWrite MOVE.L TagBufPtr(A1),D3 ; tag buffer start
|
|
BEQ.S @1 ; br if no separate buffer
|
|
MOVE.L D3,A1 ; tag buffer start
|
|
ADD.W D1,A1 ; point to appropriate tag
|
|
LEA TagData+2,A2
|
|
MOVE.L (A1)+,(A2)+
|
|
MOVE.L (A1)+,(A2)+
|
|
MOVE.L (A1)+,(A2)+ ; fill it in
|
|
BRA.S @2 ; and do the write
|
|
|
|
@1 ADD.W FirstFSeq(A1),D0 ; figure relative file block number
|
|
MOVE.W D0,TagData+8 ; so we can write it out in tag field
|
|
|
|
@2 BSR WrData ; WrData timestamps it
|
|
BMI AdrDtaErr ; go to AdrDtaErr on errors
|
|
BRA.S GotSect ;
|
|
|
|
; it was a read request so call read data mark
|
|
|
|
OTRead BSR RdData ; read the data mark
|
|
BMI AdrDtaErr ; go to AdrDtaErr on errors
|
|
|
|
MOVE.L SonyVars,A1
|
|
MOVE.L TagBufPtr(A1),D0 ; do we have a separate tag buffer?
|
|
BEQ.S GotSect ; br if not
|
|
MOVE.L D0,A0 ; point to tag buffer start
|
|
ADD.W TagBufOS(A1),A0 ; and then to appropriate entry
|
|
LEA TagData+2,A2
|
|
MOVE.L (A2)+,(A0)+
|
|
MOVE.L (A2)+,(A0)+
|
|
MOVE.L (A2)+,(A0)+ ; transfer tag data from low memory
|
|
|
|
; We got the sector so flag it as gotten, update our counts and
|
|
; then try for the next one
|
|
|
|
GotSect BSR GetDrv1 ; get A1, D1 <25Oct85>
|
|
MOVE.L SectMap(A1),D4 ; get the map
|
|
MOVE.W CurSector(A1),D2 ; get r/w sector number <22Oct85>
|
|
BCLR D2,D4 ; flag it as gotten
|
|
MOVE.L D4,SectMap(A1) ; update the map
|
|
|
|
MOVE.L DiskUnitPtr(A1),A2 ; get pointer to DCE
|
|
MOVE.L DCtlQHead(A2),A0 ; get pointer to user request block
|
|
MOVEQ #2,D3 ; number of bytes/sector
|
|
ASL.L #8,D3 ; (cheap way to make 512)
|
|
ADD.L D3,DCtlPosition(A2) ; bump position (not accurate until done)
|
|
ADD.L D3,IONumDone(A0) ; bump number done <24Oct85>
|
|
|
|
MOVE.L IOByteCount(A0),D3 ; original request <24Oct85>
|
|
SUB.L IONumDone(A0),D3 ; D3 = 0 if we're done (save for later) <24Oct85>
|
|
|
|
; done r/w NewIntf Atalk action <2.1>
|
|
;
|
|
; dc dc dc yes 10 ms sector wait
|
|
; yes read dc no continue (to next track)
|
|
; no read dc no continue (may get 1-1)
|
|
; yes write dc no 700 us wait for erase head off
|
|
; no write yes no continue (may get 1-1)
|
|
; no write no no 10 ms sector wait (1-1 not possible)
|
|
|
|
BSET #7,IntFlag ; do we need to open up ints for <24Oct85>
|
|
BEQ.S @1 ; AppleTalk? br if so . . . <24Oct85>
|
|
BSR.S CheckRead ; is it a read? <24Oct85>
|
|
BEQ.S @2 ; br if so <24Oct85>
|
|
|
|
TST.L D4 ; last sector on this track/side? <24Oct85>
|
|
BNE.S @0 ;-> no <C437/28mar88><2.1>
|
|
BSR.S EmptyPD ; process stack data <25Oct85><C437/10feb88>
|
|
MOVEQ #7,D0 ; wait 700 usec after last sector write <24Oct85>
|
|
BSR WakeUp ; wake up when it's over <24Oct85>
|
|
BRA.S @3 ; <25Oct85>
|
|
|
|
@0 TST.B NewIntf(A1,D1) ; is this a new interface drive <C437/28mar88><2.1>
|
|
BMI.S @2 ;-> yes, no waiting (we might do 1-1) <C437/28mar88><2.1>
|
|
|
|
@1 MOVE.W SectTime(A1),D0 ; set up timer for 1 sector time <25Oct85>
|
|
|
|
TST.B mfmDisk(A1,D1) ;Are we in MFM mode? <C437/04dec86><2.1>
|
|
BPL.S @11 ;-> no <C437/04dec86>
|
|
MOVEQ #MFMSectTime,D0 ;MFM sectors have a fixed spacing <C437/04dec86>
|
|
@11 ; <C437/04dec86>
|
|
|
|
BSR WakeSetUp ; return immediately <25Oct85>
|
|
BSR.S EmptyPD ; process stack data <25Oct85><C437/10feb88>
|
|
BSR WakeGo ; do the wait (and enable ints) <25Oct85>
|
|
BRA.S @3 ; then continue <25Oct85>
|
|
|
|
@2 BSR.S EmptyPD ; process stack data <25Oct85><C437/10feb88>
|
|
ANDI #$F8FF,SR ; open for SCC/VIA ints <25Oct85>
|
|
|
|
@3 MOVE.L D4,D0 ; sector map (set D0=0 for exit case) <25Oct85>
|
|
BNE OnTrack ; br if there's more on this track
|
|
|
|
; we're all done with this track. See if there is anything else to do
|
|
|
|
TST.L D3 ; bytes to go <24Oct85>
|
|
BGT GetTrack ; loop if more to do <24Oct85>
|
|
|
|
TST.B TwoSideFmt(A1,D1) ; 2-sided format? <02Sep85>
|
|
BEQ.S ToDskRWOff ; br if not <02Sep85>
|
|
TST.B Sides(A1,D1) ; we better have a 2-sided drive? <02Sep85>
|
|
BNE.S ToDskRWOff ; br if so <02Sep85>
|
|
MOVEQ #twoSideErr,D0 ; give an early warning! <02Sep85>
|
|
|
|
ToDskRWOff BRA DskRWOff ; jump to IODone to tell the OS we're finished.
|
|
|
|
CheckRead CMP.B #ARdCmd,Command+1(A1) ; is it a read?
|
|
RTS
|
|
eject ; <A351/05nov86>
|
|
;______________________________________________________________________________;
|
|
;
|
|
; routine to call polldata process procedure if there is one,
|
|
; or reset the stack if there isn't . . .
|
|
;______________________________________________________________________________;
|
|
|
|
EmptyPD MOVE.L (SP)+,A4 ; save return address
|
|
PEA @2 ; this routine's return address
|
|
MOVE.L PollProc,-(SP) ; is there a proc to process poll data?
|
|
BEQ.S @1 ; br if not
|
|
MOVE.L SonyVars,A1
|
|
MOVEM.L D0/D2-D3/A0/A4,SaveRegs(A1) ; save some regs
|
|
RTS ; go to it!
|
|
|
|
@2 BSR GetDrv1
|
|
MOVEM.L SaveRegs(A1),D0/D2-D3/A0/A4
|
|
JMP (A4)
|
|
|
|
@1 MOVE.L PollStack,SP ; otherwise, throw away any data
|
|
BSR GetDrv1
|
|
|
|
JMP (A4)
|
|
;______________________________________________________________________________;
|
|
;
|
|
; Here is the exception handling code . . . these routines are branched to from
|
|
; OnTrack with interrupts disabled and data possibly on the stack.
|
|
;______________________________________________________________________________;
|
|
|
|
AdrDtaErr BSR.S EmptyPD ; process stack data <24Oct85><C437/10feb88>
|
|
ANDI #$F8FF,SR ; restore interrupts
|
|
ADDQ.W #1,DiskErrs(A1) ; increment global soft-error count <H11><SM2>
|
|
TST.B DisableRetries(A1) ; are we supposed to do retries? <H11><SM2>
|
|
BEQ.S @Done ; -> yes <H11><SM2>
|
|
CLR.B ReCalCnt(A1) ; perform no recals <H11><SM2>
|
|
CLR.B ReadErrCnt(A1) ; or read retries <H11><SM2>
|
|
@Done ; <H11><SM2>
|
|
ADDQ.W #1,DriveErrs(A1,D1) ; increment drive soft-error count <25Oct85>
|
|
TST.B ReCalCnt(A1) ; down to last recal? <22Oct85>
|
|
BEQ.S @1 ; br if so (retry rather than fail) <22Oct85>
|
|
BSR.S CheckRead ; write? <22Oct85><C437/10feb88>
|
|
BNE.S DoRecal ; br if so (may be slightly off-track) <22Oct85>
|
|
@1 SUBQ.B #1,ReadErrCnt(A1) ; bad addr, data mk - decrement error cnt
|
|
BPL OnTrack ; try for another
|
|
BRA.S DoRecal ; <24Oct85>
|
|
|
|
; we don't need this one so figure out how long it will take for one we do need
|
|
; to pass under the head and give the time back to the user
|
|
; (for now, just wait for most of this sector to pass)
|
|
|
|
WrgSectAdr MOVE.L SonyVars,A1 ; get A1 <25Oct85>
|
|
MOVE.W SectTime(A1),D0 ; set up timer for 1 sector time <25Oct85>
|
|
|
|
TST.B mfmDisk(A1,D6) ;Are we in MFM mode? <C437/04dec86>
|
|
BPL.S @1 ;-> no <C437/04dec86>
|
|
MOVEQ #MFMSectTime,D0 ;MFM sectors have a fixed gap size <C437/04dec86>
|
|
@1 ; <C437/04dec86>
|
|
|
|
BSR WakeSetUp ; return immediately <25Oct85>
|
|
BSR.S EmptyPD ; process stack data <25Oct85><C437/10feb88>
|
|
BSR WakeGo ; do the wait (and enable ints) <25Oct85>
|
|
|
|
ADDQ.L #1,RndSeed ; bump our random seed
|
|
MOVEQ #SectNFErr,D0 ; in case we run out of recals <24Oct85>
|
|
SUBQ.B #1,WrgSectCnt(A1) ; enough already?
|
|
BMI.S DoRecal ; if so, recal
|
|
BRA OnTrack1 ; then continue search
|
|
|
|
WrgSideTrk BSR.S EmptyPD ; process stack data <24Oct85><C437/10feb88>
|
|
MOVEQ #SeekErr,D0 ; in case we run out of recals <24Oct85>
|
|
; fall through to DoRecal <24Oct85>
|
|
;______________________________________________________________________________;
|
|
;
|
|
; if we can't get an address mark (with retries) we must try to recalibrate
|
|
; DoRecal recals to track 0 and then refigure speed codes.
|
|
;______________________________________________________________________________;
|
|
|
|
DoRecal ANDI #$F8FF,SR ; restore interrupts
|
|
SUBQ.B #1,ReCalCnt(A1) ; did we recal yet?
|
|
BLE.S @1 ; if so, give up
|
|
BSR Recal ; recal to track 0
|
|
BMI.S @1 ; exit on errors
|
|
BSR MakeSpdTbl ; and redetermine speeds
|
|
BPL ReSeek
|
|
@1 BRA.S ToDskRWOff ; we ran out of retries so give up and
|
|
; return an error
|
|
|