mirror of
https://github.com/elliotnunn/supermario.git
synced 2024-11-29 05:49:19 +00:00
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
|
||
|