mirror of
https://github.com/elliotnunn/mac-rom.git
synced 2024-12-28 16:31:01 +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.
1012 lines
41 KiB
Plaintext
1012 lines
41 KiB
Plaintext
;
|
|
; File: SonyUtil.a
|
|
;
|
|
; Contains: This file contains various utility routines used by the
|
|
; disk driver. It includes the powerup/powerdown logic, wakeup timing,
|
|
; seek, eject, recal, and speed determination.
|
|
;
|
|
; Written by: Larry Kenyon
|
|
;
|
|
; Copyright: © 1982-1990, 1992-1993 by Apple Computer, Inc., all rights reserved.
|
|
;
|
|
; Change History (most recent first):
|
|
;
|
|
; <SM10> 12/13/93 PN Roll in KAOs and Horror changes to support Malcom and AJ
|
|
; machines
|
|
; <SM9> 12/14/92 RC Restore to Before PDM D2 Build with Horror Roll-in
|
|
; <SM6> 12/7/92 rab Roll in Horror changes. Comments followÉ
|
|
; <H6> 7/8/92 CMP Do BSR to CkEjectPatch instead of BRA. This was causing the
|
|
; rest of CkEjSw to not get executed, which in turn caused the VBL
|
|
; task to always post eject events for 800k drives.
|
|
; <H5> 3/18/92 SWC Reversed branch polarity in chip existance check in DiskVBLTask.
|
|
; <H4> 11/14/91 SWC Removed the patch to SetIWMMode since it won't be called except
|
|
; on an IWM, or SWIM in IWM mode. Changed the CkDCDExist patch to
|
|
; use more of the existing code. Check if a disk controller is
|
|
; installed in DiskVBLTask. Don't check the eject switch on
|
|
; SuperDrives. Converted SCC polling code to a macro to make it
|
|
; easier to overpatch.
|
|
; <H2> 10/18/91 CMP Overpatched SetIWMMode and CkDCDExist for SWIM2 support.
|
|
; Also, changed drive disable to not depend on MotorOn gating the
|
|
; enable lines.
|
|
; <SM5> 12/02/92 HY Added hasPwrControls conditionals.
|
|
; <SM4> 10/18/92 CCH Added nop's for systems with non-serial writes to IO space.
|
|
; <12> 7/14/92 CSS Fixed the comment below so an exact version of this
|
|
; file could be copied into SuperMario.
|
|
; <11> 4/27/92 JSM Get rid of conditionals: supportsPWM, supportsDCD, and
|
|
; has3rdFloppy are always false, forROM, supportsMFM, 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.
|
|
; <10> 1/17/91 GMR Added additional 15 µs delay to Wait100 after step goes high
|
|
; (per Sonys request) so the time between steps is not less than
|
|
; 72 µs.
|
|
; <9> 9/25/90 GMR Changed Recal to use fast (with handshake) step pulses for the
|
|
; new Buddy Lite SuperDrive.
|
|
; <8> 9/21/90 BG Removed <7>. 040s are behaving more reliably now.
|
|
; <7> 6/18/90 CCH Added NOPs for flaky 68040's.
|
|
; <6> 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.
|
|
; <5> 4/26/90 GMR Backed out previous change (there was a recursive problem with
|
|
; it).
|
|
; <4> 2/2/90 GMR Modified ReCal to support low cost 800K drives (and low cost
|
|
; Superdrives) by using Seek to do the stepping (without 6/12msec
|
|
; delays), unless it's a 400K drive.
|
|
; <3> 1/16/90 MSH Roll in Portable changes from Fiction.
|
|
; <2> 1/15/90 MSH Prepare comment header for conversion.
|
|
; <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 Added VIA accesses during Pulse to waste some time to ensure
|
|
; adequate pulse width of LSTRB. Added VIA accesses in DiskSel to
|
|
; kill some time.
|
|
; <2.0> 12/15/88 GGD Added short delay loop in Seek loop to fix problem with seek
|
|
; errors on fast processors (like Cobra2). 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 WC Made drive translation table stuff conditional for everyone
|
|
; but onMac.
|
|
; <1.7> 8/16/88 GGD Changed ref to DBase in FigTrkSpeed to use low mem loc IWM
|
|
; instead.
|
|
; <1.6> 7/15/88 GGD For HcMac, don't turn off drive power while ejecting.
|
|
; <1.5> 6/15/88 GGD No changes to this file, entire Sony Driver is checked out and
|
|
; in as a group.
|
|
; <1.4> 5/25/88 GGD No changes to this file, entire Sony Driver is checked out and
|
|
; in as a group.
|
|
; <1.3> 5/24/88 GGD No changes to this file, entire Sony Driver is checked out and
|
|
; in as a group.
|
|
; <1.2> 5/3/88 GGD No changes, entire sony driver checked out and in as a group.
|
|
; <1.1> 4/18/88 GGD Merged in MFM support <C437> by Steve Christensen Change WakeUp
|
|
; to use the TimeMgr when forRAM too. Change LoadPWMBuf to use
|
|
; PWMBuf1 when forRAM too. Added conditional code based upon
|
|
; onMacPPpatch=1 to add code to WakeUp and DiskSelect to only jump
|
|
; to the patch if it starts with a NOP, because those two routines
|
|
; are patched in the system disk 5.0 patches, and executing those
|
|
; patches with the new SuperDrive roms would cause the system to
|
|
; crash. Fixed Seek to check mfmMode instead of mfmDisk before
|
|
; calling SetParams (causes problems with 800K format on 1440K
|
|
; media)
|
|
; 3/28/88 GGD Fixed Seek to check mfmMode instead of mfmDisk before calling
|
|
; SetParams (causes problems with 800K format on 1440K media)
|
|
; 2/26/88 SWC PowerUp: wait an additional 600ms on writes (and formats) if the
|
|
; motor had to be turned on to guarantee motor speed within ±1.5%.
|
|
; <1.0> 2/12/88 BBM Adding file for the first time into EASEÉ
|
|
; <C437> 1/28/88 SWC Changed PowerUp so that if a MFM<->GCR drive mode switch is
|
|
; being made, it will force a wait even if the drive is powered
|
|
; up.
|
|
; <C437> 12/15/87 SWC Swapped usage of D2 & D5 in Seek because WakeUp was trashing D2
|
|
; when seeking on 400K disks.
|
|
; <C437> 12/8/87 SWC Added a call to SetParams in Seek if an MFM disk is installed.
|
|
; <C907> 10/8/87 MSH Port to HcMac (Laguna).
|
|
; <A855> 5/27/87 CSL Fixed the performance problem of the upper internal drive.
|
|
; <C511> 12/12/86 TJ Ints off in WakeUp to prevent convoluted path from PrimeTime
|
|
; back into WakeUp/WakeSetUp.
|
|
; <A351> 11/5/86 TJ Cleaned up the text, added ejects. Separated SetIWMMode from
|
|
; Recal; Fixed bug in SetIWMMode that destroyed D1 (but was never
|
|
; executed??)
|
|
; <A302> 10/30/86 TJ For old 400K drive support, rearm T2 to interrupt immediately,
|
|
; to avoid loss of TimeMgr interrupts. (FigTrkSpd keeps ints off
|
|
; for so long any T2 int has long since gone by ...)
|
|
; <A216> 10/17/86 TJ Upped Sony VBL task interrupt level from 1 (VBL) to 3 so that
|
|
; AppleTalk cant get in; fileserver activity can initiate disk
|
|
; access, which get messed up because the VBL task is fiddling
|
|
; down there ... this really needs to get handled in some
|
|
; reasonable way, like Active(SonyVars) used as a non-reentrancy
|
|
; flag or something ... but then AppleTalk would have to "back
|
|
; out" ... etc.
|
|
; <C123> 9/3/86 TJ Added Eject Button polling in VBL task.
|
|
; <C97> 7/24/86 TJ Repaired WakeUp & WakeGo to set up for the interrupt before
|
|
; enabling it, eliminating the "I'll be ready before the interrupt
|
|
; happens" (but was not) case, ie. AppleTalk interrupt taking
|
|
; longer than the WakeUp delay time. Added logical to physical
|
|
; drive translation in GetDrive(), plus added GetRDrive, that does
|
|
; not translate.
|
|
; <C1> 4/25/86 RDC Added changes for new 68020 Reno project (NuMac) - Changed
|
|
; setting of IWM mode
|
|
; <C437> 3/19/86 SWC Patched Recal to call SetChipMode instead of SetIWMMode if a
|
|
; SWIM is installed so that the appropriate registers will be
|
|
; initialized. Seek: moved the "set direction" out of and cleaned
|
|
; up the step loop. Patched PowerUp to switch a SuperDrive into
|
|
; either constant or variable speed mode for MFM or GCR,
|
|
; respectively. Made MFM mode patches to AdrDisk, Sense, Pulse,
|
|
; DiskSelect, and a few other places so that the SWIM HW is
|
|
; accessed correctly.
|
|
; 10/25/85 LAK PowerDown sets up TimeOutDrive. DiskSelect calls PowerDown if
|
|
; TimeOut nonzero and TimeOutDrive is not Drive. Vectored
|
|
; DiskSelect for ROM. Use NewIntf rather than Sides to determine
|
|
; whether drive has new interface. Split WakeUp into WakeSetUp and
|
|
; WakeGo for RWT fix.
|
|
; 10/24/85 LAK WakeUp now uses new timer routines. Added routine InvalTrkCache.
|
|
; 7/29/85 RDC Added changes for MidMac: - changed interrupt level settings to
|
|
; use equates - removed DCD code - changed VIA timer and timing
|
|
; loops to use equates - adjusted tach frequency tables - replaced
|
|
; make speed table routine w/ 800 ms delay
|
|
;
|
|
;_______________________________________________________________________
|
|
;
|
|
; Routines: GetDrive, GetDrv1, AdrAndSense, AdrAndStrb, AdrDisk, Pulse, Sense,
|
|
; SetSpeed, SetASpeed, Eject, Seek, Seek1, WakeUp, Recal, SetIWMMode,
|
|
; PowerDown, PowerUp, DiskSelect, MakeSpdTbl, FigTrkSpeed,
|
|
; DiskVBLTask.
|
|
;
|
|
; Register Conventions:
|
|
; A3,A4: used for return addresses, highest level (MakeSpdTbl)
|
|
; also use D3-D4 to keep values, may trash all other regs
|
|
; A5,A6: used for return addresses, lowest level (Seek, Recal)
|
|
; also use D5,D6,D7 to keep values, must preserve A3-A4/D3-D4.
|
|
; DskRtnAdr: used by RdAddr,RdData,WrData,WakeUp to store return address.
|
|
; Utility routines must preserve registers D3-D7/A3-A6 (though many
|
|
; preserve all regs except D0).
|
|
;_______________________________________________________________________
|
|
|
|
eject ; <A351/05nov86>
|
|
;_______________________________________________________________________
|
|
;
|
|
; Routine: GetDrive,GetDrv1,GetRDrive
|
|
; Arguments: A1 (output) -- pointer to driver variables
|
|
; D1 (output) -- word offset of current drive's specific vars
|
|
; A0 (output) -- IWM base ptr
|
|
; A2 (output) -- VIA base ptr
|
|
; Called By: (GetDrive): AdrDisk,WakeUp,WakeRcvr,DiskSelect,
|
|
; Check4Disk
|
|
; (GetDrv1): SetSpeed(2x),SetASpeed,Seek1(2x),PowerUp,
|
|
; PowerDown,MakeSpdTbl,EmptyPD,CkDrvNum
|
|
; (GetRDrive): DiskOpen
|
|
; Function: Get much-used values into D1,A0,A1, and A2.
|
|
;
|
|
;Note: This is called with Drive(A1) set to maxDrvNum + 1 in DiskOpen;
|
|
; this is for determining the presences of the passThru function
|
|
; on DCDs. To avoid problems GetDrvx bounds the drive number to
|
|
; maxDrvNum.
|
|
;_______________________________________________________________________
|
|
|
|
|
|
BLANKS ON
|
|
STRING ASIS
|
|
|
|
DrvVarOS DC.W Drive1 ; offsets into SonyVars <C97/28jul86>
|
|
DC.W Drive2 ; one for each drive <C97/28jul86>
|
|
|
|
;
|
|
;Return the stuff, but do not translate the drive number.
|
|
;
|
|
GetRDrive move.l IWM,A0 ;set up hardware pointers <C97/28jul86>
|
|
move.l VIA,A2 ; <C97/28jul86>
|
|
bsr.s GetDrv2 ; <C97/28jul86>
|
|
move.w DrvVarOS-2(D1),D1 ;untranslated drive vars <C97/28jul86>
|
|
rts ; <C97/28jul86>
|
|
;
|
|
; Return the stuff, but logically translate the drive number.
|
|
;
|
|
GetDrive MOVE.L IWM,A0 ;set up pointers to hardware
|
|
MOVE.L VIA,A2
|
|
|
|
GetDrv1
|
|
bsr.s GetDrv2 ;get basic setup stuff, <C97/28jul86>
|
|
|
|
move.w DrvVarOS-2(D1),D1 ;driver vars offset <C97/28jul86>
|
|
rts ; <C97/28jul86>
|
|
|
|
GetDrv2 move.l SonyVars,A1 ; <C97/28jul86>
|
|
move.w Drive(A1),D1 ;logical drive number, <C97/28jul86>
|
|
cmp.w #maxDrvNum,D1 ;if > max drive # <C115/13aug86>
|
|
BLS.S GetDrv3 ;bound to max (passThru test) <C437/28sep87>
|
|
MOVEQ #maxDrvNum,D1 ; <C437/28sep87>
|
|
GetDrv3 add.w D1,D1 ;make word ptr <C97/28jul86>
|
|
rts ; <C97/28jul86>
|
|
eject ; <A351/05nov86>
|
|
|
|
;_______________________________________________________________________
|
|
;
|
|
; Routine: AdrAndSense, AdrAndStrb, AdrDisk, Pulse, Sense
|
|
; Arguments: A1 (output) -- pointer to driver variables (input for GetOther)
|
|
; D1 (output) -- word offset of current drive's specific vars
|
|
; A0 (output) -- IWM base ptr
|
|
; A2 (output) -- VIA base ptr
|
|
; Called By:(AdrDisk): RdAddrSetup,AdrAndSense,AdrAndStrb,FigTrkSpeed,Eject
|
|
; (AdrAndStrb): Seek,Recal,PowerDown,Check4Disk
|
|
; (AdrAndSense): Seek,Recal(2x),PowerUp,Check4Disk(3x),CkInstll(2x),
|
|
; CkDIP(2x),CkWrProt
|
|
; (Pulse): AdrAndStrb,Seek,Recal,PowerUp
|
|
; (Sense): AdrAndSense
|
|
; Function: Utility routines used in addressing and configuring disk.
|
|
;_______________________________________________________________________
|
|
|
|
; D0 is 'address' (ca1-ca0-sel-ca2)
|
|
|
|
AdrDisk BSR.S GetDrive ; setup A0,A1,A2,D1
|
|
|
|
TST.B mfmMode(A1) ;Are we in MFM mode? <C437/25feb87>
|
|
BMI mAdrDisk ;-> yes, set phases SWIM style <C437/25feb87>
|
|
|
|
TST.B Ph0H(A0) ; when changing SEL from 1 to 0,
|
|
TST.B Ph1H(A0) ; CA0=CA1=1 must be true
|
|
|
|
LSR.B #1,D0 ; CA2 state
|
|
BCC.S @0
|
|
TST.B Ph2H(A0) ; set high
|
|
BRA.S @1
|
|
@0 TST.B Ph2L(A0) ; set low
|
|
|
|
@1 LSR.B #1,D0 ; SEL state
|
|
BCC.S @2
|
|
BSET #VHeadSel,VBufD(A2) ; set high
|
|
if NonSerializedIO then
|
|
nop ; force write to complete <SM4>
|
|
endif
|
|
BRA.S @3
|
|
@2 BCLR #VHeadSel,VBufD(A2) ; set low
|
|
if NonSerializedIO then
|
|
nop ; force write to complete
|
|
endif
|
|
|
|
@3 LSR.B #1,D0 ; CA0 state
|
|
BCS.S @4
|
|
;TST.B Ph0L(A0)
|
|
TST.B (A0)
|
|
|
|
@4 LSR.B #1,D0 ; CA1 state
|
|
BCS.S @5
|
|
TST.B Ph1L(A0)
|
|
|
|
@5 RTS
|
|
|
|
AdrAndSense BSR.S AdrDisk
|
|
Sense
|
|
TST.B mfmMode(A1) ;Are we in MFM mode? <C437/25feb87>
|
|
BMI mSense ;-> yes, read sense SWIM style <C437/25feb87>
|
|
|
|
MOVE SR,-(SP)
|
|
ORI #HiIntMask,SR ; no interrupts <29Jul85>
|
|
TST.B Q6H(A0) ; get into sense mode
|
|
MOVE.B Q7L(A0),D0 ; sense it
|
|
TST.B Q6L(A0) ; back to read mode
|
|
MOVE (SP)+,SR
|
|
TST.B D0
|
|
RTS
|
|
|
|
AdrAndStrb BSR.S AdrDisk
|
|
Pulse
|
|
TST.B mfmMode(A1) ;Are we in MFM mode? <C437/25feb87>
|
|
BMI mPulse ;-> yes, pulse LSTRB SWIM style <C437/25feb87>
|
|
|
|
MOVE SR,-(SP)
|
|
ORI #HiIntMask,SR ; no interrupts <29Jul85>
|
|
TST.B Ph3H(A0) ; pulse it high, then low
|
|
MOVE.B VBufD(A2),VBufD(A2) ; access VIA to kill some time <2.1>
|
|
if NonSerializedIO then
|
|
nop ; force write to complete
|
|
endif
|
|
TST.B Ph3L(A0)
|
|
MOVE (SP)+, SR
|
|
RTS
|
|
|
|
eject ; <A351/05nov86>
|
|
;_______________________________________________________________________
|
|
;
|
|
; Routine: Seek,Seek1
|
|
; Arguments: D6.W (input) -- track to seek to (bit 11=1 means side 1)
|
|
; D0 (output) -- result code
|
|
; Disk speed is set appropriately for the track.
|
|
; A3-A4/D3-D4 are preserved. D6, bit 11 is cleared.
|
|
; All other registers are clobbered
|
|
; This routine returns to one level above the caller during
|
|
; the seek (unless no seek is required).
|
|
; Seek1 is used when the speed table is not valid.
|
|
; Called By: (Seek1): MakeSpdTbl
|
|
; (Seek): ReSeek (in RWT logic)
|
|
; Function: Seek to a track.
|
|
;_______________________________________________________________________
|
|
|
|
Seek BCLR #11,D6 ; clear side bit (for now . . .)
|
|
|
|
Seek1 MOVE.L JSeek,-(SP)
|
|
RTS
|
|
|
|
jtSeek MOVE.L (SP)+,A6 ; save caller's address
|
|
|
|
; D6 holds the track sought . .
|
|
|
|
BSR GetDrv1
|
|
MOVE.W Track(A1,D1),D7 ; current track
|
|
BPL.S SeekLp ; br if curTrack is valid
|
|
|
|
BSR ReCal ; recal to get into a known state
|
|
MOVE.W D0,D7 ; current track
|
|
BRA.S SeekEnd ; exit after recal to avoid slipped cog
|
|
|
|
SeekLp MOVEQ #DirLAdr,D0 ;Assume step in <C437/17jun87>
|
|
MOVE.W D6,D5 ;Calculate the number of steps to take <C437/15dec87>
|
|
SUB.W D7,D5 ;Already there? <C437/15dec87>
|
|
BEQ.S SeekEnd1 ;-> yes, don't wait head settle time <C437/17jun87>
|
|
BGT.S @1 ; <C437/17jun87>
|
|
MOVEQ #DirHAdr,D0 ;We're stepping out <C437/17jun87>
|
|
NEG.W D5 ; so make the step count positive <C437/15dec87>
|
|
@1 BSR AdrAndStrb ;Set the stepper direction <C437/17jun87>
|
|
|
|
MOVEQ #cantStepErr,D7 ;Assume one of the steps will fail <C437/17jun87>
|
|
SUBQ.W #1,D5 ;Adjust count for DBRA <C437/15dec87>
|
|
SeekLp1 MOVEQ #StepLAdr,D0 ;Make sure /STEP starts out high <C437/17jun87>
|
|
BSR AdrAndSense ; <C437/17jun87>
|
|
BPL.S SeekEnd ;-> it wasn't, so exit with error <C437/17jun87>
|
|
BSR Pulse ;Then set it low <C437/17jun87>
|
|
BSR.S Wait100 ; and wait a while for it to go high <C437/17jun87>
|
|
DBRA D5,SeekLp1 ; <C437/15dec87>
|
|
MOVE.W D6,D7 ;Successful seek so update curr track <C437/17jun87>
|
|
|
|
SeekEnd BSR GetDrv1
|
|
MOVE.W D7,Track(A1,D1) ; update current track
|
|
|
|
TST.B mfmMode(A1) ;Are we in MFM mode? <C437/08dec87><1.1/28mar88>
|
|
BPL.S @00 ; <C437/08dec87>
|
|
BSR SetParams ;Yes, setup RAM parms for this disk zone<C437/08dec87>
|
|
BEQ.S @00 ; <C437/08dec87>
|
|
MOVE.W D0,D7 ;Error, so save the result code <C437/08dec87>
|
|
@00 ; <C437/08dec87>
|
|
|
|
MOVE.W HeadSettle(A1),D0 ; wait head settle time or until ready (new drive)
|
|
MOVEQ #5,D2 ; wait 500usec first time
|
|
BSR.S WaitReady ; <C437>
|
|
IF isUniversal THEN ; <H35>
|
|
TestFor hwCbPwrMgr ; is this a powerbook? <H35>
|
|
BEQ.W SeekEnd1 ; -> no, skip around artificial delay <H35>
|
|
MOVE.W #500,D0 ; need to wait 50 msec for drive to settle <H35>
|
|
BSR.W Wakeup ; just detecting /READY isn't enough <H35>
|
|
ENDIF ; <H35>
|
|
|
|
SeekEnd1 MOVE.W Wait(A1),D0 ; wait any speed change, power-on time
|
|
MOVEQ #0,D2 ; wait 0 time, first time
|
|
BSR.S WaitReady ; <C437>
|
|
|
|
MOVE.W D7,D0 ; positive value = success
|
|
SeekExit JMP (A6) ; A6 has return address
|
|
|
|
Wait100 MOVE.W SeekTime(A1),D0 ; wait 12 ms for old drive
|
|
BSR.S CheckNew ; go to WakeUp for the old interface
|
|
MOVEQ #80, D2 ; wait until step goes hi or timeout <C437/15dec87>
|
|
@1 MOVEQ #StepLAdr,D0
|
|
BSR AdrAndSense
|
|
DBMI D2, @1 ; <C437/15dec87>
|
|
|
|
; There appears to be an undocumented timing restriction related to sending step
|
|
; pulses to the drive. When /Step goes high, the spec indicates that you may immediatly
|
|
; set it low again to send the next pulse, however it appears that if you attempt to
|
|
; set it low within 18µsec of when it went high, it will not accept the step pulse,
|
|
; and will remain high. This will lead to seek errors, and is most noticable on
|
|
; processors that run at high clock rates (faster than the Mac IIx). If this is for
|
|
; a RAM based version of the MacPlus driver, we don't include it, since timeDBRA
|
|
; is not available on the MacPlus (but if we build a new MacPlus ROM we should support
|
|
; timeDBRA and this wait loop).
|
|
|
|
MOVE.W TimeDBRA,D2 ; 1000 µsec <2.0>
|
|
LSR.W #5,D2 ; 31.25 µsec (1000/32) <2.0><10>
|
|
@wait DBRA D2,@wait ; kill 31.25 µsec <2.0>
|
|
|
|
RTS
|
|
|
|
CheckNew TST.B NewIntf(A1,D1) ; new drive interface? <25Oct85>
|
|
BMI.S @1 ;-> yes (don't use wakeup) <C437/24nov86>
|
|
ADDQ #4, SP ; discard local return address <C437/24nov86>
|
|
TST.W D0 ; any time to wait? <C437/24nov86>
|
|
BNE.S WakeUp ; br if so <C437/24nov86>
|
|
@1 RTS ; <C437/24nov86>
|
|
|
|
waitReady BSR.S CheckNew ; go to WakeUp for the old interface
|
|
MOVE.L (SP)+, A4 ; get return address
|
|
MOVE.W #1000, D5 ; timeout (1 sec max to ready, any case)
|
|
|
|
MOVE.W D2, D0 ; first time wait
|
|
BEQ.S @2 ; check ready immediately if 0
|
|
|
|
@1 BSR.S WakeUp ; wait D0 * 100usec
|
|
@2 MOVEQ #ReadyAdr, D0 ; /Ready sense address
|
|
BSR AdrAndSense
|
|
BPL.S @3 ; br if /Ready asserted
|
|
MOVEQ #10,D0 ; check every millisec? - tune for seek
|
|
DBRA D5, @1 ; if we timeout, we must be ready?? Sony won't gate
|
|
; writes off if not ready (in case of bouncy ready line . . .)
|
|
@3 CLR.W Wait(A1) ; no extra wait time
|
|
JMP (A4)
|
|
eject ; <A351/05nov86>
|
|
|
|
;_______________________________________________________________________
|
|
;
|
|
; Routine: WakeUp,WakeSetUp,WakeGo
|
|
; Arguments: D0 (input) -- number of 100 usec intervals to wait (<65536)
|
|
; registers A3-A5 and D3-D7 are preserved.
|
|
; Called By: (WakeUp): Seek(3x),Eject,Recal,PowerUp
|
|
; (WakeSetUp,WakeGo): GotSect(RWT),WrgSectAdr(RWT)
|
|
; Function: Saves the return address in DskRtnAdr; it will call this
|
|
; routine after the timer interrupt in which the count is
|
|
; exhausted. Since the timer ticks away at 780 KHz,
|
|
; there are 78 timer ticks in each 100 microsecond interval.
|
|
; For MidMac timer ticks at 1.57 MHz so timer ticks = 157.
|
|
;_______________________________________________________________________
|
|
|
|
WakeUp
|
|
MOVE.L JWakeUp,-(SP)
|
|
RTS
|
|
|
|
jtWakeUp MOVEM.L D3-D7/A3-A6,SaveRegs(A1); save caller's regs first <C97/24jul86>
|
|
MOVE.L (SP)+,DskRtnAdr ; save return address next <C97/24jul86>
|
|
BSR.S WakeSetUp ; configure timer for D0 wait <25Oct85>
|
|
bra.s WakeRet ; go execute it. <C97/24jul86>
|
|
|
|
WakeGo MOVEM.L D3-D7/A3-A6,SaveRegs(A1); save caller's regs first <C97/24jul86>
|
|
MOVE.L (SP)+,DskRtnAdr ; save return address next <25Oct85>
|
|
WakeRet MOVEQ #0,D0 ; go back to user with no err
|
|
ANDI #$F8FF,SR ; and VIA interrupts enabled
|
|
RTS
|
|
|
|
WakeSetUp ; New WakeUp uses T2 Timer manager <25Oct85>
|
|
MOVE.L SonyVars,A1 ; <27Oct85>
|
|
|
|
SUB.W D0,Wait(A1) ; decrement any Wait time . . .
|
|
BGT.S @1 ;
|
|
CLR.W Wait(A1) ; pin at 0
|
|
|
|
@1 LEA TimeQEl(A1),A0 ; point at queue element
|
|
LEA GoWakeIt,A1 ; <27Oct85>
|
|
MOVE.L A1,tmAddr(A0) ; want to come here first <27Oct85>
|
|
AND.L #$0000FFFF,D0 ; clear high word of D0
|
|
CMP.W #10,D0 ; need to pin D0 to 10 (100usec intervals)
|
|
BCC.S @2
|
|
MOVEQ #10,D0
|
|
@2 DIVU #10,D0 ; divide by ten for msec
|
|
EXT.L D0 ; PrimeTime takes count in D0 long
|
|
|
|
MOVE.L jPrimeTime,A1 ; use dispatch table vector
|
|
JSR (A1) ; to start the timer (pass A0=TimeQEl ptr)
|
|
|
|
BRA GetDrv1 ; restore A1/D1 (and return) <27Oct85><C437/28jan88>
|
|
|
|
GoWakeIt MOVEM.L D0-D7/A0-A6,-(SP) ; save ALL regs
|
|
BSR GetDrive ;
|
|
MOVEM.L SaveRegs(A1),D3-D7/A3-A6 ; get back regs we saved
|
|
MOVEQ #0,D0 ; D0 = for RWT-MakeSpdTbl new intf path <25Oct85>
|
|
BSR DskRtn ; call DskRtnAdr
|
|
MOVEM.L (SP)+,D0-D7/A0-A6 ; restore registers
|
|
RTS ; we're done with it!
|
|
|
|
eject ; <A351/05nov86>
|
|
|
|
;_______________________________________________________________________
|
|
;
|
|
; Routine: Recal
|
|
; Arguments:
|
|
; D0 (output) -- result code
|
|
; This routine returns to one level above the caller during
|
|
; the recal (unless no seek is required).
|
|
; Called By: (Recal): Seek,DiskPrime,DoRecal
|
|
; Function: Recal to track 0. Leaves drive powered up. Sets IWM mode
|
|
; register.
|
|
;_______________________________________________________________________
|
|
|
|
Recal MOVE.L JRecal,-(SP) ; use RAM vector <03Mar85>
|
|
RTS ; <03Mar85>
|
|
|
|
jtRecal MOVE.L (SP)+,A5 ; save return address
|
|
BSR GetDrive
|
|
BSR InvalTrkCache ; invalidate track cache <A351/05nov86><24Oct85>
|
|
|
|
BSR SetChipMode ;Initialize appropriate register set<C437/19mar87>
|
|
|
|
bne.s RecalExit ; couldn't set IWM Mode <A351/05nov86>
|
|
BSR RWPowerUp ;Re-enable the interface <C437/19mar87>
|
|
MOVEQ #80,D7 ; maximum number of steps needed
|
|
|
|
MOVEQ #DirHAdr,D0 ;Set direction out (toward track 0) <C437/17jun87>
|
|
BSR AdrAndStrb ; <C437/17jun87>
|
|
|
|
TST.B NewIntf(A1,D1) ; new drive interface? <9>
|
|
BPL.S SlowLoop ; br if not (use slow step time) <9>
|
|
|
|
SUBQ #1,D7 ;Adjust count for DBRA <9>
|
|
@SeekLoop MOVEQ #StepLAdr,D0 ;Make sure /STEP starts out high <9>
|
|
BSR AdrAndSense ; <9>
|
|
BPL.S RecalFail ;-> it wasn't, so exit with error <9>
|
|
BSR Pulse ;Then set it low <9>
|
|
BSR.S Wait100 ;and wait a while for it to go high <9>
|
|
DBRA D7,@SeekLoop ;count track <9>
|
|
BRA.S ReCalled ;done 80 steps, exit... <9>
|
|
|
|
|
|
SlowLoop MOVE.W SeekTime(A1),D0 ; wait 12 ms <9>
|
|
BSR WakeUp
|
|
|
|
MOVEQ #Tk0Adr,D0 ;
|
|
BSR AdrAndSense ;
|
|
BPL.S ReCalled ; keep going until track 0 is true
|
|
|
|
MOVEQ #StepLAdr,D0 ; set step low
|
|
BSR AdrAndSense ; address it
|
|
BPL.S RecalFail ; can't recal (won't step, isn't at tk 0)
|
|
|
|
MOVEQ #tk0BadErr,D0 ; assume error
|
|
SUBQ.W #1,D7 ; reached maximum step count?
|
|
BEQ.S RecalExit ; exit if so
|
|
|
|
BSR Pulse ; then set it low
|
|
BRA.S SlowLoop ;
|
|
|
|
RecalFail MOVEQ #cantStepErr,D0 ; no track
|
|
BRA.S RecalExit
|
|
|
|
ReCalled MOVEQ #0,D0 ; track 0
|
|
RecalExit MOVE.W D0,Track(A1,D1)
|
|
JMP (A5)
|
|
eject ; <A351/05nov86>
|
|
;_______________________________________________________________________
|
|
;
|
|
; Routine: SetIWMMode
|
|
; Arguments:
|
|
; D0 (output) -- result code
|
|
; Called By: Recal,Seek,DiskPrime,DoRecal
|
|
; Function: Set the mode register of the IWM in case it glitched out (or first time).
|
|
; It no longer re-powers up the drive. <C437/08dec86>
|
|
;_______________________________________________________________________
|
|
|
|
SetIWMMode TST.B Q6H(A0) ; set IWM to sense mode
|
|
MOVEQ #$1F,D0 ;(mask for mode bits) <C437/20may87>
|
|
AND.B Q7L(A0),D0 ; sense the mode register <C437/20may87>
|
|
TST.B Q6L(A0) ; and back to read mode
|
|
CMP.B #IWMMode,D0 ; see if correct mode is set <A351/05nov86>
|
|
BEQ.S @2 ; br if so <C437/20may87>
|
|
|
|
MOVEQ #OneSecConst,D2 ; loop timeout count <29Jul85>
|
|
SWAP D2 ; should be about a second
|
|
|
|
@1 MOVEQ #initIWMErr,D0 ; assume timeout error
|
|
SUBQ.L #1,D2 ; decrement timeout loop
|
|
BMI.S @3 ; exit on error ... <A351/05nov86>
|
|
|
|
TST.B MtrOff(A0) ; change the IWM mode now
|
|
TST.B Q6H(A0) ; set IWM to sense state
|
|
MOVEQ #$3F,D0 ;(mask for sense, mode bits) <C437/20may87>
|
|
AND.B Q7L(A0),D0 ; sense the mode register <C437/20may87>
|
|
BCLR #5,D0 ; interface should be disabled <C437/20may87>
|
|
BNE.S @1 ; keep waiting
|
|
|
|
cmp.b #IWMMode,D0 ; see if low bits match <A351/05nov86>
|
|
BEQ.S @2 ; if so, we are done
|
|
|
|
MOVE.B #IWMMode,Q7H(A0) ; set to sony mode <A351/05nov86>
|
|
if NonSerializedIO then
|
|
nop ; force write to complete
|
|
endif
|
|
TST.B Q7L(A0) ; set IWM back to sense state
|
|
BRA.S @1 ; loop back just to check
|
|
|
|
@2 TST.B Q6L(A0) ; and back to read mode...
|
|
moveq #0,D0 ; repower the drive ... <A351/05nov86>
|
|
@3 rts ; <A351/05nov86>
|
|
eject ; <A351/05nov86>
|
|
;_______________________________________________________________________
|
|
;
|
|
; Routine: PowerDown,RWPowerDown
|
|
; Arguments: D0 (input) -- power-down time
|
|
; TimeOut (out) -- set to D0 input value
|
|
; TimeOutDrive (out) -- set to Drive if D0 nonzero
|
|
; Called By: DiskControl(Eject,KillIO calls),DskOff(RWT),DiskSelect
|
|
; Function: Does VBL task stuff; just powers off current drive if D0=0.
|
|
;_______________________________________________________________________
|
|
|
|
PowerDown BSR GetDrv1 ;
|
|
MOVE.W D0,TimeOut(A1) ; set up timeout
|
|
BEQ.S @1 ; branch if immediate power-down
|
|
MOVE.W Drive(A1),TimeOutDrive(A1) ; remember drive with timeout <25Oct85>
|
|
RTS
|
|
|
|
@1 MOVEQ #MtrOffAdr,D0
|
|
BSR AdrAndStrb ; turn it off both ways: PAL
|
|
|
|
MOVE.B #$86,wZeroes(A0) ;Kill the drive enable SWIM2 style <H2><SM6>
|
|
if NonSerializedIO then
|
|
nop ; force write to complete
|
|
endif
|
|
|
|
TST.B MtrOff(A0) ; cut the enable to power it down
|
|
RTS
|
|
|
|
;_______________________________________________________________________
|
|
;
|
|
; Routine: InvalTrkCache
|
|
; Arguments:
|
|
; A1 (input) -- SonyVars ptr
|
|
; D0 trashed
|
|
; Called By: Recal, Eject
|
|
; Function: Invalidates the track cache if it holds data for the current
|
|
; drive.
|
|
;_______________________________________________________________________
|
|
|
|
InvalTrkCache
|
|
MOVE.W TCDrive(A1),D0 ; get current track-cache drive <24Oct85>
|
|
CMP.W Drive(A1),D0 ; this drive? <24Oct85>
|
|
BNE.S @1 ; br if not <24Oct85>
|
|
CLR.W TCDrive(A1) ; invalidate it if so <24Oct85>
|
|
@1 RTS
|
|
|
|
;_______________________________________________________________________
|
|
;
|
|
; Routine: RWPowerUp,PowerUp
|
|
; Arguments: D0 (input) -- power-up time
|
|
; Timeout, Power, Wait, Drive
|
|
; Sets interrupt level 0 if powers up; uses A0-A2,D0-D2 (by wakeup) .
|
|
; 'Active' should be true when this routine is called.
|
|
; Called By: (RWPowerUp): RWPower,SetIWMMode
|
|
; (Fast Power): DiskControl(Eject call),DiskPrime
|
|
; Function: PowerUp is called to power up a disk drive. Waits out D0 time
|
|
; unless disk is already powered . . .
|
|
;_______________________________________________________________________
|
|
|
|
FastPower MOVEQ #0,D0
|
|
BRA.S PowerUp
|
|
|
|
RWPowerUp MOVE.W PwrOnTime(A1),D0
|
|
|
|
PowerUp MOVE.W D0,D2 ; save wait time
|
|
BSR.S DiskSelect ; go enable the interface
|
|
|
|
MOVE.B mfmDrive(A1,D1),D5 ;Is this a SuperDrive? <C437/28jan88>
|
|
BPL.S @1 ;-> no, don't have to set drive mode<C437/24nov86>
|
|
MOVEQ #GCRModeAdr,D0 ;find out which way the drive is set<C437/04feb88>
|
|
BSR AdrAndSense ; <C437/04feb88>
|
|
MOVE.B D0,-(SP) ; and save the state (bit7=1: MFM) <C437/04feb88>
|
|
MOVEQ #GCRModeAdr,D0 ;Assume we're in GCR mode <C437/24nov86>
|
|
MOVE.B mfmDisk(A1,D1),D5 ;Are we? <C437/28jan88>
|
|
BPL.S @0 ; <C437/24nov86>
|
|
MOVEQ #MFMModeAdr,D0 ;No, select MFM drive mode <C437/24nov86>
|
|
@0 BSR AdrAndStrb ;set the drive mode as desired <C437/04feb88>
|
|
MOVE.B (SP)+,D0 ;get the previous drive mode <C437/08feb88>
|
|
EOR.B D0,D5 ;bit 7=1 if the mode has changed <C437/04feb88>
|
|
@1 ; <C437/24nov86>
|
|
|
|
MOVEQ #MtrOnAdr,D0
|
|
BSR AdrAndSense ; is it already powered up?
|
|
|
|
OR.B D5,D0 ;or we just did a mode change? <C437/28jan88>
|
|
|
|
BPL.S @2 ; br if so <C437/28jan88>
|
|
BSR Pulse ; turn power on
|
|
|
|
MOVE.W D2,D0 ; get back wait time
|
|
MOVE #750,D2 ; wait at least 75ms the first time
|
|
MOVE.L (SP)+,D4 ;(jump up a stack level) <C437/26feb88>
|
|
BSR waitReady ; <C437/26feb88>
|
|
MOVE.L D4,-(SP) ;(restore stack level--rtn addr) <C437/26feb88>
|
|
|
|
CMP.B #ARdCmd,Command+1(A1) ; is it a read? <C437/26feb88>
|
|
BEQ.S @2 ;-> yes, all done <C437/26feb88>
|
|
MOVE.W #600*10,D0 ;for writes, we need to wait about <C437/26feb88>
|
|
BRA WakeUp ; 600ms after /READY for speed ±1.5%<C437/26feb88>
|
|
|
|
@2 RTS ; return <C437/28jan88>
|
|
|
|
eject ; <A351/05nov86>
|
|
;_______________________________________________________________________
|
|
;
|
|
; Routine: DiskSelect,DiskSel1
|
|
; Arguments: Drive -- drive to enable
|
|
; D1,A0,A1,A2 set up per GetDrive
|
|
; Clobbers D0.
|
|
; TimeOut cleared and TimeOutDrive powered off if not Drive.
|
|
; DiskSel1 is a quick entry for DiskSense
|
|
; Called By: (DiskSelect): PowerUp,DiskPrime,DiskOpen(2x),DiskControl,
|
|
; DCDStatus(Format/Verify),DCDHardReset.
|
|
; (DiskSel1): Ck4Disk
|
|
; Function: Assert the IWM enable to a drive. For DCDs, this is functionally
|
|
; equivalent to PowerOn since that function is not called. Whenever
|
|
; the enable to a floppy drive is cut, it is powered down automatically.
|
|
;
|
|
;_______________________________________________________________________
|
|
|
|
DiskSelect BSR GetDrive
|
|
|
|
DiskSel1
|
|
MOVE.L JDiskSel,-(SP) ; vector this routine
|
|
RTS
|
|
jtDiskSel
|
|
|
|
TST.W TimeOut(A1) ; timeout pending? <25Oct85>
|
|
BEQ.S @0 ; br if not <25Oct85>
|
|
MOVE.W TimeOutDrive(A1),D0 ; see if it's us <25Oct85>
|
|
CMP.W Drive(A1),D0 ; ? <25Oct85>
|
|
BEQ.S @0 ; br if so <25Oct85>
|
|
MOVEQ #0,D0 ; turn it off immediately <25Oct85>
|
|
BSR PowerDown ; (it will still be selected) <25Oct85>
|
|
|
|
@0 CLR.W TimeOut(A1) ; clear pending timeout <11Jun85>
|
|
|
|
TST.B mfmMode(A1) ;Are we in MFM mode? <C437/19mar87>
|
|
BMI mDiskSelect ;-> yes, do the MFM version <C437/19mar87>
|
|
|
|
CMP.W #drive1,D1 ; if Drive=1, it's internal
|
|
BNE.S @1 ; br if not
|
|
|
|
TST.B IntDrive(A0) ; select internal drive
|
|
TST.B MtrOn(A0) ; assert /enb
|
|
RTS
|
|
|
|
@1 TST.B Ph2H(A0) ; we may already be enabled in
|
|
TST.B Ph1H(A0) ; state 2, so go safely thru 6
|
|
TST.B Ph0H(A0) ; to state 7 (Ph0=Ph1=Ph2=1)
|
|
BCLR #vHeadSel,VBufD(A2) ; set HdSel low (/Exists addr)
|
|
if NonSerializedIO then
|
|
nop ; force write to complete
|
|
endif
|
|
|
|
@2 TST.B ExtDrive(A0) ; select the external
|
|
|
|
TST.B MtrOn(A0) ; and enable the disk, IWM style
|
|
RTS
|
|
|
|
eject ; <A351/05nov86>
|
|
;_______________________________________________________________________
|
|
;
|
|
; Routine: MakeSpdTbl,GetFreq1
|
|
; Arguments: Drive (input) -- current drive
|
|
; D0 (output) -- error code (-1 = drive not installed)
|
|
; all registers are used.
|
|
; current drive is powered up and recal'ed.
|
|
; Called By: (MakeSpdTbl) CheckDIP,DoRecal
|
|
; (GetFreq1) RWT, Format
|
|
; Function: Makes a speed table for the current drive.
|
|
;
|
|
; Note: Drive must spin at speed codes 128 and 256 for this routine
|
|
; to work.
|
|
;
|
|
; Note: Speed variation has three major factors, temperature drift, speed
|
|
; drift, and load variation. Temperature drift occurs as the drive gets
|
|
; warmer and generally? is a negative factor (drive slows) accounting for
|
|
; up tp 6%? of speed variation. Speed drift occurs during
|
|
; the first minute the drive is powered and is a negative factor accounting
|
|
; for less than 1/2 of 1% of speed variation. Load is a factor which
|
|
; varies between inside and outside tracks of a drive: the inner tracks
|
|
; present less loading to the head than the outer tracks; speed variation
|
|
; due to loading may be as much as 1%.
|
|
;
|
|
; The main read/write track logic adjusts for speed drift by periodically
|
|
; checking the disk speed and adjusting the speed code if the speed is off
|
|
; by more than 2% using a speed code delta figured out by this routine: this
|
|
; should also catch any speed drift problems, depending upon the period
|
|
; of the check.
|
|
;
|
|
; We ignore loading variation since it is only 1% max and we will recheck
|
|
; each speed class when we first seek to it. Temperature and speed drift
|
|
; are not as easy to compensate for, but since they are both negative factors,
|
|
; this routine rounds to higher speed values.
|
|
;
|
|
;_______________________________________________________________________
|
|
|
|
MakeSpdTbl MOVE.L JMakeSpdTbl,-(SP)
|
|
RTS
|
|
|
|
jtMakeSpdTbl
|
|
|
|
MOVE.W #8000,D0 ; delay for 800 ms on new drive <29Jul85>
|
|
BRA WakeUp ; (to seat diskette correctly) <25Oct85>
|
|
|
|
eject ; <A351/05nov86>
|
|
;_______________________________________________________________________
|
|
;
|
|
; Routine: FigTrkSpeed,DskRtn
|
|
; Arguments: D0 (output) -- -1=timeout reached or long VIA count for one rev
|
|
; Called By: (FigTrkSpeed): MakeSpdTBL
|
|
; (DskRtn): WrData,RdAddr,RdData,GoWakeIt(WakeUp)
|
|
; Function: This routine measures the time (in VIA counts) it takes
|
|
; for the disk to revolve .25 times; this test looks for the tach
|
|
; pulse which occurs 60 times per rev. VIA timer 2 is used; if
|
|
; 15 tach pulses are not seen in 78 msec, this routine
|
|
; will time out and take the error exit.
|
|
;
|
|
; The drive should be powered when this is called. Speeds as
|
|
; low as 192 RPM may be measured.
|
|
;_______________________________________________________________________
|
|
|
|
FigTrkSpeed MOVE.L JFigTrkSpd,-(SP)
|
|
RTS
|
|
|
|
jtFigTrkSpd MOVEQ #-1,D0 ; no PWM, don't use timer
|
|
RTS
|
|
|
|
DskRtn MOVE.L DskRtnAdr,-(SP)
|
|
TST.W D0 ; set CCR
|
|
RTS
|
|
eject ; <A351/05nov86>
|
|
|
|
;_______________________________________________________________________
|
|
;
|
|
; Routine: DiskVBLTask
|
|
; Arguments: A0.L (input) -- disk VBL queue block ptr
|
|
; This routine MUST preserve A4-A6 and D4-D7 (like any VBL task)
|
|
; TimeOut non-zero, positive value if power-down is pending
|
|
; DiskInPlace drive variable
|
|
; Power drive variable
|
|
;
|
|
; Function: This VBL task handles disk power-down delays and checks for
|
|
; diskette-inserted and disk-eject-switch when both drives are
|
|
; powered down.
|
|
;
|
|
; - on power-down delays, add a check for a flag which says "call flush volume
|
|
; first . . ."; this could be the paranoia bit . . .
|
|
;_______________________________________________________________________
|
|
|
|
DiskVBLTask
|
|
MOVE SR,-(SP)
|
|
MOVE.L SonyVars,A1
|
|
MOVE.W DskVBLTime(A1),VBLCount(A0) ; reset VBL task
|
|
|
|
IF hasPwrControls THEN ; <SM5>
|
|
TestFor hwCbPwrMgr
|
|
BEQ.S @pmgrdone
|
|
|
|
BSR TurnIWMon ; IWM needed now <C907><v2.3>
|
|
@pmgrdone
|
|
ENDIF ; <SM5>
|
|
|
|
MOVE.B isSWIM(A1),D0 ; see if the IWM/SWIM/... is installed <H15><SM6>
|
|
SUBQ.B #1,D0 ; <H15><SM6>
|
|
BNE.S @Done ; -> yes, just return <H15><SM6>
|
|
CLR.W TimeOut(A1) ; clear any pending timeouts <SM6>
|
|
CLR.W LastDrive(A1) ; and show no last drive <SM6>
|
|
@Done ; <SM6>
|
|
BEQ.S DiskVBLExit ; -> no IWM/SWIM/... chip installed <H5><SM6>
|
|
|
|
ORI #HiIntMask,SR ; no VBL & AppleTalk (fileserver) <A351/05nov86><A216/17oct86><29Jul85>
|
|
|
|
TST.B Active(A1) ; any active requests?
|
|
BNE.S DiskVBLExit ; exit if so
|
|
|
|
TST.W TimeOut(A1) ; timeout pending?
|
|
BEQ.S @1
|
|
|
|
@0 SUBQ.W #1,TimeOut(A1) ; wait for it to go to zero <C907>
|
|
BNE.S DiskVBLExit ; exit if there is a powered-up disk
|
|
|
|
; we timed out, so turn off the power (turn out the lights)
|
|
|
|
MOVEQ #MtrOffAdr,D0
|
|
BSR AdrAndStrb ; turn it off both ways: PAL
|
|
|
|
@1 MOVEQ #1,D3 ; start with drive 1
|
|
|
|
@2 BSR.S Check4Disk ; check for disk-in-place
|
|
ADDQ #1, D3
|
|
|
|
CMP.W #maxDrvNum, D3 ; 2 drives max for MidMac <29Jul85>
|
|
BLE.S @2 ; <C37/3Jun86>
|
|
|
|
@3
|
|
|
|
MOVE.B #$86,wZeroes(A0) ;Kill the drive enable SWIM2 style <H2><SM6>
|
|
if NonSerializedIO then
|
|
nop ; force write to complete
|
|
endif
|
|
|
|
TST.B MtrOff(A0) ; cut IWM enable (new drive fix)
|
|
|
|
IF hasPwrControls THEN ; <SM5>
|
|
TestFor hwCbPwrMgr
|
|
BEQ.S @pmgrdone2
|
|
|
|
tst.l d3 ; see if any drives ejecting? <1.6>
|
|
bmi.s DiskVBLExit ; if so, don't turn off drive power <1.6>
|
|
MOVE (SP), SR ; Re-enable interrupts <v2.3>
|
|
BSR TurnIWMoff ; IWM not needed now <C907>
|
|
@pmgrdone2
|
|
ENDIF ; <SM5>
|
|
|
|
DiskVBLExit MOVE (SP)+, SR
|
|
RTS
|
|
;
|
|
;Check up on drive #(D3); post DiskInPlace:0 events if a diskette is
|
|
;inserted, and post DiskInPlace:X events if the Eject switch is pressed.
|
|
;
|
|
Check4Disk
|
|
MOVE.W D3,Drive(A1)
|
|
BSR GetDrive ; set up A0,A1,D1
|
|
TST.B Installed(A1,D1) ; is there a drive attached?
|
|
BMI CkExit ; exit if not
|
|
|
|
TST.B DiskInPlace(A1,D1) ; if a diskette is in place, <C123/03sep86>
|
|
bgt.s CkEject ; go check for eject <C123/03sep86>
|
|
beq.s CkDIP ; else go check for one inserted <C123/03sep86>
|
|
|
|
IF hasPwrControls THEN ; <SM5>
|
|
TestFor hwCbPwrMgr
|
|
BEQ.S @pmgrdone
|
|
|
|
ADDQ.B #1,DiskInPlace(A1,D1) ; else if waiting for eject complete
|
|
bpl.s CkDIP ; when done, go check for a disk <1.6>
|
|
bset.l #31,d3 ; indicate drive is ejecting <1.6>
|
|
bra.s CkInval ; wait until eject timeout done <1.6>
|
|
@pmgrdone
|
|
ENDIF ; <SM5>
|
|
|
|
ADDQ.B #1,DiskInPlace(A1,D1) ; else if waiting for eject complete
|
|
bmi.s CkInval ; decrement until 0 <C123/03sep86>
|
|
bra.s CkDIP ; then go check for a disk <C123/03sep86>
|
|
;
|
|
;There is a disk in place; check to see if the eject switch was pushed, and
|
|
;if so, post a DiskInsertEvt:Eject event.
|
|
;
|
|
CkEject
|
|
bsr DiskSel1 ; select the drive, <C123/03sep86>
|
|
bsr.s CkEjSw ; go read the eject switch, <C123/03sep86>
|
|
bpl.s CkExit ; if not pressed do nothing <C123/03sep86>
|
|
MOVEQ #-1,D0 ; upper D0 = eject (-1) <C123/03sep86><C437>
|
|
move.w Drive(A1),D0 ; lower D0 = drive number <C123/04sep86>
|
|
move.w #DiskInsertEvt,A0 ; <C123/03sep86>
|
|
_PostEvent ; post the event <C123/03sep86>
|
|
bra.s CkExit ; any error is ignored <C123/03sep86>
|
|
;
|
|
;There is no disk in place; read the drive interface to see if one was inserted,
|
|
;and if so, post a DiskInsertEvt:DIP.
|
|
;
|
|
CkDIP bsr DiskSel1 ; select the disk, <C123/03sep86>
|
|
|
|
@1 moveq #DIPAdr,D0 ; for Sony drives, <C123/03sep86>
|
|
bsr AdrAndSense ; check DIP at the drive, <C123/03sep86>
|
|
bmi.s CkExit ; exit if none <C123/03sep86>
|
|
|
|
@2 bsr.s CkEjSw ; read, reset & ignore Eject Switch <C123/03sep86>
|
|
MOVEQ #DiskInsertEvt,D0 ; upper D0 = DIP (0) <C123/03sep86><C437>
|
|
MOVEA.L D0,A0 ; A0 = event type, <C123/03sep86><C437>
|
|
move.w Drive(A1),D0 ; lower D0 = drive number <C123/04sep86><C437>
|
|
_PostEvent ; post the event <C123/03sep86>
|
|
BNE.S CkInval ; br if not posted (probably boot time)
|
|
ADDQ.B #1,DiskInPlace(A1,D1) ; unclamped disk-in-place = 1
|
|
|
|
CkInval ST Track(A1,D1) ; mark current track invalid
|
|
MOVEA.L IWM,A0 ; restore IWM ptr
|
|
|
|
CkExit RTS
|
|
;
|
|
;See if the Eject Switch is pressed on the selected drive and
|
|
;reset the latched status bit. Returns BMI if switch pressed.
|
|
;
|
|
CkEjSw tst.b sides(a1,d1) ; just exit if 400K drive <1.2/26apr88>
|
|
BPL.S @DontEject ; <SM6>
|
|
MOVE.B mfmDrive(A1,D1),D0 ; is this drive a SuperDrive? <SM6>
|
|
NOT.B D0 ; BPL if so, BMI if not <SM6>
|
|
@DontEject ; any error is ignored <SM6>
|
|
bpl.s @1 ; because there's no eject switch <1.2/26apr88>
|
|
moveq #EjectLAdr,D0 ; eject latch address, <C123/04sep86>
|
|
bsr AdrAndSense ; go sample it, <C123/04sep86>
|
|
bpl.s @1 ; exit if no switch pressed, <C123/04sep86>
|
|
moveq #RdDta1Adr,D0 ; else reset the switch latch <C123/04sep86>
|
|
bsr AdrAndStrb ; by reading some damn thing <C123/04sep86>
|
|
MOVEQ #-1,D0 ; return BMI <C123/04sep86><C437>
|
|
@1 rts ; <C123/04sep86>
|
|
|
|
|
|
|
|
|