mirror of
https://github.com/elliotnunn/mac-rom.git
synced 2025-01-21 18:35:32 +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.
1993 lines
79 KiB
Plaintext
1993 lines
79 KiB
Plaintext
;
|
|
; File: TFS.a
|
|
;
|
|
; Contains: This file is the controlling file for the Macintosh Turbo file
|
|
; system. It contains initialization code and the file system's
|
|
; queueing and dispatch routines.
|
|
;
|
|
; Roots: This system exploits the dispatching mechanism used by the earlier
|
|
; Macintosh file system written by Larry Kenyon et al. Relevant
|
|
; code was taken from that system and modified as appropriate.
|
|
;
|
|
; Copyright: © 1982-1993 by Apple Computer, Inc. All rights reserved.
|
|
;
|
|
; Change History (most recent first):
|
|
;
|
|
; <SM9> 8/27/93 BH Made DSAlertRect bigger for the disk-switch alert in
|
|
; manual-eject systems to keep it the same size as the various
|
|
; manual-eject alerts, which have also been enlarged.
|
|
; <SM8> 8/3/93 BH Rewrote DSHook for manual-eject drive support.
|
|
; <SM7> 6/7/93 kc Roll in missing part of DSHookPatch from reality that sets the fsNoAllocate bits.
|
|
; <SM6> 11/12/92 PN Get rid of ³ 020 conditionals
|
|
; <SM5> 10/29/92 SWC Changed SCSIEqu.a->SCSI.a.
|
|
; <SM4> 9/15/92 RB #1042050,#1042640,#Fixed a bug in DSHook where the PostUpdate
|
|
; routine was not duplicating a rectangle pointer in the stack
|
|
; correctly. This caused a bomb after a disk had been asked for
|
|
; and it got inserted in the drive. The satck was trashed 4 bytes.
|
|
; <SM3> 5/21/92 kc Append "Trap" to the names of
|
|
; OpenWD,CloseWD,GetWDInfo,OpenDF,UnMountVol,FlushVol,OpenWD,Close
|
|
; WD,GetWDInfo,ReName,OpenRF,OpenDF,GetFPos,SetFPos,GetEOF,SetEOF,
|
|
; Eject,SetVol,GetVolTrap,Enqueue and Dequeue to avoid name
|
|
; conflict with the glue.
|
|
; <SM2> 5/18/92 CS Fix bug in OpenCall that I (kc) introduced in the patch roll in.
|
|
; <SM1> 4/1/92 kc Rolled in HFSDispHook from FileMgrPatches.a.
|
|
; Moved the stub dispatch handlers (VolumeCall,
|
|
; RefNumCall,OpenCall and UnknownCall) and copied the
|
|
; routines InstallVectors, FSGrowPatchInit,
|
|
; QMInit, CountFCBs, OpenAttemptHook, AllocateFCBs, DoFSCleanUp
|
|
; Rolled in patches to DSHook.
|
|
; include FileMgrHooks.a till someone rolls it in.
|
|
; ¥ Pre-SuperMario comments follow ¥
|
|
; <4> 9/27/91 JSM DonÕt use hasCQD conditional, all future ROMs will have color
|
|
; QuickDraw.
|
|
; <3> 9/12/91 JSM Cleanup header.
|
|
; <2> 6/12/91 LN Changed #include 'HardwareEqu.a' to 'HardwarePrivateEqu.a'
|
|
; <2.6> 6/12/89 GGD Fixed bugs in <C150 09sep86> which intended to allow
|
|
; cmd-shift-0/1/2 to eject disks during a disk switch dialog, but
|
|
; never worked. (ESPRIT SHOULD ALSO GET THIS FIX)
|
|
; <2.5> 5/25/89 GGD Deleted 4 extra lines of code that were accidently pasted in the
|
|
; wrong place, in the Switcher Table initialization code. This
|
|
; would cause a random long word (whose address is a function of
|
|
; the number of FCBs from the boot blocks) in the system heap to
|
|
; get trashed. This fixes problems noticed in Aurora B1 ROMs, and
|
|
; needs to be fixed in Esprit also.
|
|
; <2.4> 5/23/89 DAF Corrected color updates in DSHook
|
|
; <2.3> 4/13/89 dnf Completed export
|
|
; <2.2> 4/13/89 DNF Exported vFileRead, vFileWrite, and vFileClose
|
|
; <2.0> 3/27/89 DNF =
|
|
; <2.1> 3/27/89 DNF This comment documents the change from V1.7 to V1.8/V1.9/V2.0.
|
|
; There have been node real code changes since V1.7. V1.8 Added
|
|
; forROM conditionals around the disk-switch code, since it jumps
|
|
; to other spots in the ROM. Note that the comment in V1.6 is no
|
|
; longer true; RAM versions use the ROM's disk switch code. The
|
|
; overridden V1.8, V1.9, the accidentally commentless V2.0 and
|
|
; this file all contain the same code.
|
|
; <¥1.9> 3/27/89 DNF whoops. v1.8 was checked in from the wrong directory. Here's the
|
|
; right one.
|
|
; <¥1.7> 3/20/89 CCH Added Export of FSQueueSync and CmdDone for CacheControl.a.
|
|
; <1.6> 3/2/89 DNF removed references to forROM; HFS now builds identically for ram
|
|
; or rom
|
|
; <1.5> 2/20/89 rwh changed from CPU-based to feature-based conditionals.
|
|
; <1.4> 1/16/89 GGD Added a scratch register parameter to the BigJSR macro calls
|
|
; since it will be needed when they change to use PC relative
|
|
; addressing.
|
|
; <1.3> 11/21/88 CCH Replaced references to forRAM with ÒNOT forROM.Ó
|
|
; <1.2> 11/17/88 GGD Moved file system initialization code from StartBoot into TFS.a,
|
|
; Changed BigJsr's into Jsr, since they now reach.
|
|
; <1.1> 11/10/88 CCH Fixed Header.
|
|
; <1.0> 11/9/88 CCH Adding to EASE.
|
|
; <¥1.1> 9/23/88 CCH Got rid of inc.sum.d and empty nFiles
|
|
; <1.0> 2/11/88 BBM Adding file for the first time into EASEÉ
|
|
; 11/10/87 JB (C957) Rolled in changes from patches S084, PM120, PP227, &
|
|
; PM289. Fixed CmdDone logic for "NoMacDskErr". Instead of special
|
|
; casing here, disk format package (PACK 2) will be modified to
|
|
; accept "ExtFSErr" as a legitimate format request.
|
|
; <C914> 10/19/87 rwh Port to Modern Victorian
|
|
; 10/16/87 MSH Added nHardwareEqu.a to INCLUDES for Laguna support.
|
|
; 6/10/87 EHB Added INCLUDEs for colorEqu.a and nsysequ.a again.
|
|
; 6/2/87 DAF Added INCLUDEs for colorEqu.a and nsysequ.a. Added 020 asm
|
|
; directive if on numac.
|
|
; 5/12/87 DAF Rolled in DSHook patch to not save bits behind dialog when on
|
|
; CQD-equipped system and in >1-bit mode.
|
|
; 3/3/87 BB Modified CmdDone to call external file systems if "NoMacDskErr"
|
|
; is returned from MountVol.
|
|
; 2/19/87 BB Added EXPORTs for vectored MtCheck, CheckReMount, FindDrive,
|
|
; DtrmV2, FClose, and FlushMDB.
|
|
; 10/27/86 BB Added EXPORTs for vectored CkExtFS, DtrmV3, TstMod, and BMChk
|
|
; routines.
|
|
; 9/25/86 BB Updated to use new MPW equate files.
|
|
; <C150> 9/9/86 TJ Added vDoEject vector for access by other system routines that
|
|
; need to handle manual diskette ejection. Extended to accept
|
|
; Command-Shift-0 for drive #3.
|
|
; 1/20/86 LAK Added .DEF of FindDrive for BTAlloc usage in updating alternate
|
|
; MDB.
|
|
; 11/3/85 LAK One more tweak to disk-switch: if we get a non-memfull error on
|
|
; our mount (e.g., IOErr because double-sided disk was inserted
|
|
; into 1-sided drive), we eject that disk and reenter our wait
|
|
; loop. Also fixed bug when remounting an offline volume (D3 not
|
|
; set up).
|
|
; 11/2/85 LAK Call DoEject for cmd-shift-1 or 2 during disk switch DIP wait.
|
|
; In case user has inserted needed 2-sided disk into his old
|
|
; external 1-sided drive (removes need for paper clip eject).
|
|
; 10/29/85 LAK Added Defs for vectored routines.
|
|
; 10/22/85 PWD Fixed CmdDone to check PMSP for traps w. TFS bit set but
|
|
; DirID=0.
|
|
; 10/16/85 PWD Added _LockRng and _UnlockRng dispatches
|
|
; 10/14/85 PWD Added _ReadWDCB dispatch (trap 15)
|
|
; 10/8/85 LAK Added .Def of vLg2Phys (for ROM vector).
|
|
; 10/2/85 LAK Added debug code at CmdDone to check for a non-released buffer.
|
|
; (may want to take this out since it is time-consuming).
|
|
; 10/1/85 LAK Added .Ref of MarkA5Block. Add .Def of Lg2Phys for Cache.
|
|
; Convert positive internal errors to FSDSIntErr at CmdDone. Cut
|
|
; out Queue code convert drive numbers to VRefNums (this is now
|
|
; handled by GetVCBDrv in TFSCommon). Added Refs of
|
|
; CacheWrIP,CacheRdIP. Added Def of TFSVCBTst. Set up global
|
|
; asynchronicity flag, FSCallAsync, at FSDispatch. Patched
|
|
; disk-switch hook for ROM to look for cmd-. abort and return
|
|
; VolOffLinErr for that case (let's see how it goes).
|
|
; 9/26/85 PWD Added SetupDef entry point dispatch for external FS support.
|
|
; 9/25/85 PWD Changed to allow SkipPMSP to come on in mid-parse in CmdDone
|
|
; path
|
|
; 9/20/85 LAK Added .Ref of TrashFBlocks.
|
|
; 9/8/85 LAK Added Def of MarkVCBTime. Added Ref of UpdateFree.
|
|
; 9/5/85 LAK Clear CacheFlag on exit.
|
|
; 9/5/85 LAK ParamErr instead of IOErr if D0 parameter to $Ax60 trap is out
|
|
; of range.
|
|
; 9/2/85 LAK Added .Ref of MarkBlock.
|
|
; 8/30/85 LAK Added .Ref of TrashVBlks. Removed .Ref of RelCache.
|
|
; 8/27/85 LAK Why waste a word in _FSControl? Remunged dispatch a bit, too.
|
|
; 8/22/85 PWD Added _SetUpWDCB trap dispatch
|
|
; 7/31/85 PWD Added _FSControl trap
|
|
; 7/27/85 PWD Added Poor Man's Search Path mechanism
|
|
; 7/17/85 PWD Changed TFSDispatch to store trap index in ioTrap for use by
|
|
; ext. FS and volume switch re-trap (TrapAgain)
|
|
; 6/14/85 PWD Added EXT.L to make error codes into longs at CmdDone
|
|
; 5/1/85 PWD Expanded dispatch table to accomodate new TFS traps
|
|
; 4/22/85 PWD Fixed dispatcher table indexing to use word offsets
|
|
; consistently.
|
|
; 3/13/85 PWD Added TFS trap dispatcher
|
|
; 2/8/85 PWD Added .Include of ToolEqu for TIOCore use.
|
|
; 2/5/85 PWD Changed to use Tlasm- equates (including TFSEqu)
|
|
; 9/24/84 GSS Added include of RAM version trap install code, and def for
|
|
; Offline call
|
|
; 8/5/84 GSS New today. (taken from Larry Kenyon's Mac File System)
|
|
;
|
|
|
|
;_______________________________________________________________________
|
|
;
|
|
; External Routines: Enqueue,Dequeue,InitQueue
|
|
;
|
|
; Internal Routines: FSQueue,FSQueueSync
|
|
;
|
|
;_______________________________________________________________________
|
|
|
|
|
|
BLANKS ON
|
|
STRING ASIS
|
|
|
|
MACHINE MC68020
|
|
|
|
SonyNonPortable EQU 1
|
|
|
|
PRINT OFF
|
|
LOAD 'StandardEqu.d'
|
|
INCLUDE 'HardwarePrivateEqu.a'
|
|
INCLUDE 'SonyEqu.a'
|
|
INCLUDE 'Processes.a'
|
|
INCLUDE 'MFPrivate.a'
|
|
INCLUDE 'FileMgrPrivate.a'
|
|
INCLUDE 'SCSI.a'
|
|
INCLUDE 'SCSIPriv.a'
|
|
INCLUDE 'GestaltEqu.a'
|
|
INCLUDE 'InternalMacros.a'
|
|
INCLUDE 'SysPrivateEqu.a'
|
|
INCLUDE 'BTreeEqu.a'
|
|
PRINT ON
|
|
|
|
PRINT NOGEN
|
|
|
|
|
|
;_______________________________________________________________________
|
|
;
|
|
; Routine: TFSDispatch
|
|
;
|
|
; Arguments: D0.W = TFS trap index
|
|
; D1.W = Trap ($Ax60)
|
|
; A0.L = Parameter Block Pointer
|
|
;
|
|
; Called by: EMT1010
|
|
;
|
|
; Function: Dispatch routine for the _HFSDispatch trap.
|
|
;
|
|
; The deal with $A060 trap numbers:
|
|
; $00-$1f HFS calls
|
|
; $20-$2f Desktop Manager Calls
|
|
; $30-$3f AppleShare calls (owned by AppleShare group)
|
|
; $40-$4f More appleshare calls
|
|
; $60-$7f More HFS calls
|
|
;
|
|
; Modification History:
|
|
;
|
|
; 13-Mar-85 PWD New today.
|
|
; <25Sep85> PWD Added SetPMSP (trap 12): bumped _SetupWDCB to index 13.
|
|
; <14Oct85> PWD Added _ReadWDCB dispatch (trap 15)
|
|
;_______________________________________________________________________
|
|
|
|
MaxTrapNum Equ $70
|
|
|
|
|
|
TFSDispatch Proc Export
|
|
Import UnknownCall
|
|
|
|
tst.w d0 ; check lower bound of selector
|
|
blt.l UnknownCall ; negative traps are no good
|
|
cmp.w #MaxTrapNum,d0 ; check upper bound of selector
|
|
bge.l UnknownCall ; off the deep end
|
|
|
|
move.w d1,ioTrap(a0) ; save the unmunged trap
|
|
andi.w #$0F00,ioTrap(a0) ; leave only modifiers (Async etc.)
|
|
move.b d0,ioTrap+1(a0) ; save the trap selector
|
|
|
|
lea TFSTrpTbl,a2 ; address of the dispatch table
|
|
adda.l (a2,d0.w*4),a2 ; add the routine offset
|
|
jmp (a2) ; jump to the routine
|
|
|
|
macro
|
|
DispatchEntry &where
|
|
import &where
|
|
dc.l &where-TFSTrpTbl
|
|
endm
|
|
|
|
TFSTrpTbl ; pc relative data
|
|
|
|
DispatchEntry FSControl ; $00 Special control entry point
|
|
DispatchEntry OpenWDTrap ; $01 Open a working directory
|
|
DispatchEntry CloseWDTrap ; $02 Close a working directory
|
|
DispatchEntry SetDir ; $03 Set a default directory
|
|
DispatchEntry GetDir ; $04 Get default directory information
|
|
DispatchEntry TFMove ; $05 Move a CNode into another directory
|
|
DispatchEntry CreateDir ; $06 Create a directory CNode
|
|
DispatchEntry GetWDInfoTrap ; $07 Get WDCB infomation
|
|
DispatchEntry GetFCBInfo ; $08 Get FCB information
|
|
DispatchEntry GetCatInfo ; $09 Get expanded file/dir information
|
|
DispatchEntry SetCatInfo ; $0A Change CNode information
|
|
DispatchEntry SetVolInfo ; $0B Change volume information
|
|
DispatchEntry SetPMSP ; $0C Set up PMSP hook and enable/disable PMSP
|
|
DispatchEntry SetUpWDCB ; $0D Set up WDCB [raw internal call only]
|
|
DispatchEntry SetUpDef ; $0E Set up default vol&dir [raw internal]
|
|
DispatchEntry ReadWDCB ; $0F Get WDCB information [raw internal]
|
|
DispatchEntry LockRng ; $10 Lock a byte range
|
|
DispatchEntry UnLockRng ; $11 Unlock a byte range
|
|
|
|
DispatchEntry UnknownCall ; $12
|
|
DispatchEntry UnknownCall ; $13
|
|
DispatchEntry CreateFileIDRef ; $14
|
|
DispatchEntry DeleteFileIDRef ; $15
|
|
DispatchEntry ResolveFileIDRef ; $16
|
|
DispatchEntry PBHExchangeFiles ; $17
|
|
DispatchEntry CMCatSearch ; $18
|
|
DispatchEntry CheckCSPB ; $19
|
|
DispatchEntry OpenDFTrap ; $1A
|
|
DispatchEntry MakeFSSpec ; $1B
|
|
DispatchEntry UnknownCall ; $1C
|
|
DispatchEntry UnknownCall ; $1D
|
|
DispatchEntry UnknownCall ; $1E
|
|
DispatchEntry UnknownCall ; $1F
|
|
|
|
DispatchEntry DTGetPath ; $20
|
|
DispatchEntry DTCloseDown ; $21
|
|
DispatchEntry DTAddIcon ; $22
|
|
DispatchEntry DTGetIcon ; $23
|
|
DispatchEntry DTGetIconInfo ; $24
|
|
DispatchEntry DTAddAPPL ; $25
|
|
DispatchEntry DTRemoveAPPL ; $26
|
|
DispatchEntry DTGetAPPL ; $27
|
|
DispatchEntry DTSetComment ; $28
|
|
DispatchEntry DTRemoveComment ; $29
|
|
DispatchEntry DTGetComment ; $2a
|
|
DispatchEntry DTFlush ; $2b
|
|
DispatchEntry DTReset ; $2c
|
|
DispatchEntry DTGetInfo ; $2d
|
|
DispatchEntry DTOpenInform ; $2e
|
|
DispatchEntry DTDelete ; $2f
|
|
|
|
DispatchEntry GetVolParms ; $30 GetVolParms
|
|
DispatchEntry VolumeCall ; $31 GetLogInInfo
|
|
DispatchEntry VolumeCall ; $32 GetDirAccess
|
|
DispatchEntry VolumeCall ; $33 SetDirAccess
|
|
DispatchEntry VolumeCall ; $34 MapID
|
|
DispatchEntry VolumeCall ; $35 MapName
|
|
DispatchEntry VolumeCall ; $36 CopyFile
|
|
DispatchEntry VolumeCall ; $37 MoveRename
|
|
DispatchEntry OpenCall ; $38 OpenDeny
|
|
DispatchEntry OpenCall ; $39 OpenRFDeny
|
|
DispatchEntry VolumeCall ; $3A Reserved for future use
|
|
DispatchEntry VolumeCall ; $3B Reserved for future use
|
|
DispatchEntry VolumeCall ; $3C Reserved for future use
|
|
DispatchEntry VolumeCall ; $3D Reserved for future use
|
|
DispatchEntry VolumeCall ; $3E Reserved for future use
|
|
|
|
DispatchEntry VolumeCall ; $3F GetVolMountInfoSize
|
|
DispatchEntry VolumeCall ; $40 GetVolMountInfo
|
|
DispatchEntry UnknownCall ; $41 VolumeMount
|
|
DispatchEntry VolumeCall ; $42 Share
|
|
DispatchEntry VolumeCall ; $43 UnShare
|
|
DispatchEntry UnknownCall ; $44 GetUGEntry
|
|
DispatchEntry UnknownCall ; $45 ServerControl
|
|
DispatchEntry UnknownCall ; $46 ServerStartup
|
|
DispatchEntry UnknownCall ; $47 Reserved for future use
|
|
DispatchEntry UnknownCall ; $48 Reserved for future use
|
|
DispatchEntry UnknownCall ; $49 Reserved for future use
|
|
DispatchEntry UnknownCall ; $4A Reserved for future use
|
|
DispatchEntry UnknownCall ; $4B Reserved for future use
|
|
DispatchEntry UnknownCall ; $4C Reserved for future use
|
|
DispatchEntry UnknownCall ; $4D Reserved for future use
|
|
DispatchEntry UnknownCall ; $4E Reserved for future use
|
|
DispatchEntry UnknownCall ; $4F Reserved for future use
|
|
|
|
DispatchEntry GetParallelFCBFromRefnum ; $50
|
|
DispatchEntry RefNumCall ; $51 Reserved for future use
|
|
DispatchEntry RefNumCall ; $52 Reserved for future use
|
|
DispatchEntry RefNumCall ; $53 Reserved for future use
|
|
DispatchEntry RefNumCall ; $54 Reserved for future use
|
|
DispatchEntry RefNumCall ; $55 Reserved for future use
|
|
DispatchEntry RefNumCall ; $56 Reserved for future use
|
|
DispatchEntry RefNumCall ; $57 Reserved for future use
|
|
DispatchEntry RefNumCall ; $58 Reserved for future use
|
|
DispatchEntry RefNumCall ; $59 Reserved for future use
|
|
DispatchEntry RefNumCall ; $5A Reserved for future use
|
|
DispatchEntry RefNumCall ; $5B Reserved for future use
|
|
DispatchEntry RefNumCall ; $5C Reserved for future use
|
|
DispatchEntry RefNumCall ; $5D Reserved for future use
|
|
DispatchEntry RefNumCall ; $5E Reserved for future use
|
|
DispatchEntry RefNumCall ; $5F Reserved for future use
|
|
|
|
DispatchEntry VolumeCall ; $60 GetAltPrivs
|
|
DispatchEntry VolumeCall ; $61 SetAltPrivs
|
|
DispatchEntry DoFSCleanUp ; $62 FSCleanUp
|
|
DispatchEntry AllocateFCBs ; $63 AllocateFCBs
|
|
DispatchEntry VolumeCall ; $64 Reserved for future use
|
|
DispatchEntry VolumeCall ; $65 Reserved for future use
|
|
DispatchEntry VolumeCall ; $66 Reserved for future use
|
|
DispatchEntry VolumeCall ; $67 Reserved for future use
|
|
DispatchEntry VolumeCall ; $68 Reserved for future use
|
|
DispatchEntry VolumeCall ; $69 Reserved for future use
|
|
DispatchEntry VolumeCall ; $6A Reserved for future use
|
|
DispatchEntry VolumeCall ; $6B Reserved for future use
|
|
DispatchEntry VolumeCall ; $6C Reserved for future use
|
|
DispatchEntry VolumeCall ; $6D Reserved for future use
|
|
DispatchEntry VolumeCall ; $6E Reserved for future use
|
|
DispatchEntry VolumeCall ; $6F Reserved for future use
|
|
|
|
EndProc
|
|
|
|
TurboFS PROC EXPORT
|
|
|
|
Export UNLOCKRNG,LOCKRNG,READWDCB,SETUPDEF,SETUPWDCB,SETPMSP,FSCONTROL
|
|
Export ALLOCATEFCBS,DOFSCLEANUP,GTNXTMATCH,GT1STMATCH,GETVOLPARMS
|
|
Export FLUSHVFILES,FCLOSE,REFNUMCHECK,PUSHCNAME,CVFLGS,POPCNAME
|
|
Export ExtOffLinCk,FNDFILNAME,DTRMV3,GT1STFCB,GTNXTFCB,FSQUEUE
|
|
|
|
EXPORT vDoEject ; <C150/09sep86>
|
|
EXPORT DivUp,RoundAlloc,Lg2Phys,TFSVCBTst ; <01Oct85>
|
|
EXPORT FInitQueue
|
|
EXPORT MountVol,UnMountVolTrap,FlushVolTrap,MarkVCB,MarkVCBTime,FlushMDB ; <08Sep85>
|
|
EXPORT OpenWDTrap,CloseWDTrap,SetDir,GetDir,GetWDInfoTrap
|
|
EXPORT FileOpen,FileClose
|
|
EXPORT FileRead,FileWrite
|
|
EXPORT FSQueueSync, CmdDone
|
|
EXPORT CreateDir,FileCreate,FileDelete,ReNameTrap,TFMove,OpenRFTrap,OpenDFTrap
|
|
EXPORT GetFPosTrap,SetFPosTrap,FileAlloc
|
|
EXPORT GetEOFTrap,SetEOFTrap,FlushFile
|
|
EXPORT GetFCBInfo
|
|
EXPORT GetFileInfo,SetFileInfo,SetFilType,RstFilLock,SetFilLock
|
|
EXPORT GetCatInfo,SetCatInfo
|
|
EXPORT GetVCBRfn,GetVolInfo,SetVolInfo,EjectTrap,Offline
|
|
EXPORT SetVolTrap,GetVolTrap
|
|
EXPORT DoEject,MakeStkPB,FindDrive ;<20Jan86>
|
|
EXPORT vDtrmV1,vFileOpen,vPermssnChk,vFndFilName,vRfNCall,vAdjEOF ;<29Oct85>
|
|
EXPORT vCkExtFS,vDtrmV3,vTstMod,vBMChk ;<27Oct86>
|
|
EXPORT vMtCheck,vCheckReMount,vFindDrive,vDtrmV2,vFClose,vFlushMDB ;<19Feb87>
|
|
EXPORT vLg2Phys ; <08Oct85>
|
|
EXPORT DSHook
|
|
EXPORT vFileRead, vFileWrite, vFileClose ;<dnf v2.2,v2.3>
|
|
EXPORT InitFS ;<1.2>
|
|
|
|
IF hasManEject THEN ; <SM8> <BH 03Aug93>
|
|
EXPORT SwitchDisk ; for Desk Mgr
|
|
EXPORT CleanDSErr ; for Eject patch in FileMgrHooks (ExtFSHookPatch)
|
|
ENDIF
|
|
|
|
IMPORT AllocFakeRgns
|
|
IMPORT EnqueueTrap,DequeueTrap,InitQueue
|
|
IMPORT InitCache,GetBlock,RelBlock,FlushCache,TrashBlocks,TrashVBlks
|
|
IMPORT MarkBlock,MarkA5Block,TrashFBlocks ; <01Oct85>
|
|
IMPORT CacheWrIP,CacheRdIP ; <01Oct85>
|
|
IMPORT MapFBlock,ExtendFile,TruncateFile,DeallocFile,BlkChk,UpdateFree ; <08Sep85>
|
|
IMPORT BTOpen,BTFlush,BTClose,FXMKeyCmp,CMKeyCmp
|
|
IMPORT BTSearch,BTGetRecord,BTUpdate
|
|
IMPORT CMCreateCN,CMGetCN,CMDeleteCN,CMGetOff,CMMoveCN,CMRenameCN
|
|
IMPORT CMUpdateCN
|
|
IMPORT WDCBSwOS ; <C152><1.2>
|
|
IMPORT PMSPSwOS ; <C152><1.2>
|
|
IMPORT DTDBMgrInit,QMInit,CheckDesktopSupport,DesktopCloseDownProc ; from DTDBMgr.a
|
|
|
|
IMPORT vSyncWait ; from FileMgrHooks.a
|
|
IMPORT vAfterFSQHook ; from FileMgrHooks.a
|
|
IMPORT fsGeneralWakeUp ; from FileMgrHooks.a
|
|
IMPORT fsSCSIFreeHookProc ; from FileMgrHooks.a
|
|
IMPORT ProcessMgrExists ; from FileMgrHooks.a
|
|
|
|
|
|
;________________________________________________________________________________
|
|
;
|
|
; Routine: Stub dispatch handlers
|
|
;
|
|
; Function: Pass a call to the external File System if it refers to an
|
|
; external File System volume.
|
|
;
|
|
; VolumeCall handles calls defined to take a vRefnum/ioNamePtr
|
|
; RefNumCall handles calls which take an FCB refnum
|
|
; OpenCall handles all forms of Open (which need to set up an FCB in d1)
|
|
; UnknownCall handles call for which there isn't yet a definition
|
|
;
|
|
; Inputs: A0 = Parameter block
|
|
; Output: D0 = error code, RfNumErr or zero.
|
|
;________________________________________________________________________________
|
|
|
|
ExtFSErrExit:
|
|
moveq.l #ExtFSErr,d0 ; Good news!
|
|
bra.l CmdDone
|
|
|
|
ParamErrExit:
|
|
moveq.l #paramErr, d0 ; It's an unknown trap for a local volume
|
|
bra.l CmdDone
|
|
|
|
;________________________________________________________________________________
|
|
;
|
|
; Routine: VolumeCall
|
|
;
|
|
; Function: Handles calls defined to take a vRefnum/ioNamePtr. If
|
|
; the call refers to an External File System's volume,
|
|
; the call is passed to the external FS. Otherwise,
|
|
; a #paramErr is returned to the caller.
|
|
;________________________________________________________________________________
|
|
|
|
entry VolumeCall
|
|
VolumeCall:
|
|
jsr FSQueue ; Patiently wait our turn
|
|
jsr DtrmV3 ; Determine the volume being referred to
|
|
bne CmdDone ; Punt at the slightest hint of trouble
|
|
|
|
move.l a2,ReqstVol ; Point to the volume being referred to
|
|
tst.w VCBFSID(a2) ; External FS?
|
|
bne ExtFSErrExit ; Branch if it's not a local FS
|
|
bra ParamErrExit
|
|
|
|
;________________________________________________________________________________
|
|
;
|
|
; Routine: RefNumCall
|
|
;
|
|
; Function: Handle a refNum-based call. If the call refers to an External
|
|
; File System's volume, the call is passed to the external FS.
|
|
; Otherwise, a #paramErr is returned to the caller.
|
|
;________________________________________________________________________________
|
|
|
|
entry RefNumCall
|
|
RefNumCall:
|
|
jsr FSQueue ; chill in line
|
|
move.w ioRefNum(a0),d0 ; Pick up the refNum
|
|
jsr RefNumCheck ; Check the refNum supplied
|
|
bne CmdDone ; Punt at first hint of trouble
|
|
|
|
movea.l FCBsPtr,a1 ; Point to the FCB table
|
|
move.w ioRefNum(a0),d1 ; Pick up the specified refNum
|
|
movea.l FCBVPtr(a1,d1),a1 ; Point to the VCB for this volume
|
|
move.l a1, ReqstVol ; In case it's #extFSErr
|
|
tst.w VCBFSID(a1) ; Local FS?
|
|
bne.s ExtFSErrExit ; No - let external file systems have it
|
|
bra.s ParamErrExit ; Local doesn't implement this call
|
|
|
|
;________________________________________________________________________________
|
|
;
|
|
; Routine: OpenCall
|
|
;
|
|
; Function: Open a fork with specific Deny modes; pass the call to the External;
|
|
; file system if it's for an Ext. FS volume.
|
|
;________________________________________________________________________________
|
|
;
|
|
entry OpenCall
|
|
OpenCall:
|
|
jsr FSQueue ; Wait our turn
|
|
jsr DtrmV3 ; Determine the volume being referred to
|
|
bne CmdDone ; Punt at the slightest hint of trouble
|
|
|
|
move.l a2,ReqstVol ; Point to the volume being referred to
|
|
tst.w VCBFSID(a2) ; External FS?
|
|
beq.s ParamErrExit ; It's an unknown trap for a local volume
|
|
|
|
bsr OpenAttemptHook ; let ourselves know we're trying <38>
|
|
jsr Gt1stFCB ; get (A1,D1) pointing to first FCB
|
|
@1 tst.l FCBFlNm(a1,d1) ; FCB unused
|
|
beq.s @90 ; br if so
|
|
jsr GtNxtFCB ; get next one until we run out
|
|
bcs.s @1
|
|
|
|
moveq.l #TMFOErr,d0 ; too many files open
|
|
clr.w IORefNum(a0) ; make refnum invalid
|
|
bra CmdDone
|
|
|
|
@90 add.l a1,d1 ; Point to the FCB
|
|
bra.s ExtFSErrExit ; ... and pass it along
|
|
|
|
;________________________________________________________________________________
|
|
;
|
|
; Routine: UnknownCall
|
|
;
|
|
; Function: Pass a call to the external File System. This routine is called for
|
|
; call selectors that are unknown to HFS and the Desktop Manager, but
|
|
; which might be implemented for External File Systems.
|
|
;________________________________________________________________________________
|
|
;
|
|
entry UnknownCall
|
|
UnknownCall:
|
|
jsr FSQueue ; Wait our turn
|
|
movea.l VCBQHdr+qHead, a2 ; Pick up pointer to first VCB
|
|
move.l a2, ReqstVol ; Point someplace semi-innocuous
|
|
bra.s ExtFSErrExit ; ... and pass it along
|
|
|
|
;_______________________________________________________________________
|
|
;
|
|
; Routine: FSControl
|
|
; Arguments: D1 = trap
|
|
; A0 = parameter list pointer
|
|
;
|
|
; Function: The FSControl entry point is provided in part to allow a
|
|
; program to sync up with the file system - the completion
|
|
; routine is called with exclusive access to all file system
|
|
; data structures...
|
|
;
|
|
;_______________________________________________________________________
|
|
|
|
FSControl:
|
|
BSR.S FSQueue ; Wait out turn (sync up with FS)
|
|
MOVE.L #FSVrsn,ioFSVrsn(A0); Return the current version of TFS <27Aug85>
|
|
MOVEQ #0,D0 ; Indicate success
|
|
BRA CmdDone ; And call it a day
|
|
|
|
;________________________________________________________________________________
|
|
;
|
|
; Routine: RefNumCheck
|
|
;
|
|
; Function: Check the refNum supplied to make sure it's a real file RefNum.
|
|
;
|
|
; Inputs: d0 = refnum
|
|
; Output: d0 = error code, RfNumErr or noErr
|
|
;
|
|
; Note:
|
|
; This routine is called by the desktop manager and the UnTagFCB _Close patch.
|
|
;________________________________________________________________________________
|
|
; This routine was rolled into into the file TFS.a. <SM1>
|
|
RefNumCheckRegs reg a1/d1
|
|
entry RefNumCheck
|
|
RefNumCheck
|
|
movem.l RefNumCheckRegs, -(sp)
|
|
moveq.l #0, d1 ; clear high word
|
|
move.w d0, d1 ; make a copy of the refnum
|
|
bmi.s @RefNumErrExit ; no negative refnums
|
|
|
|
divu FSFCBLen,d1 ; Divide by the FCB size
|
|
swap d1 ; Get remainder in low word
|
|
subq.w #2,d1 ; Is the remainder 2?
|
|
bne.s @RefNumErrExit ; If not, no way this could be a refnum
|
|
|
|
move.l FCBSPtr, a1 ; point to length word of FCB array
|
|
cmp.w (a1), d0 ; check against size of FCB array
|
|
bgt.s @RefNumErrExit ; Too high? Too bad.
|
|
|
|
moveq.l #noErr, d0 ; No pwobwem!
|
|
bra.s @Exit
|
|
|
|
@RefNumErrExit:
|
|
moveq.l #RfNumErr,d0 ; Indicate a bad refNum
|
|
@Exit:
|
|
movem.l (sp)+, RefNumCheckRegs
|
|
tst.w d0 ; Set condition codes
|
|
rts
|
|
|
|
;_______________________________________________________________________
|
|
;
|
|
; Routine: FSQueueSync
|
|
; Arguments: D1 = trap
|
|
; A0 = parameter list pointer
|
|
; Calls: calling routine
|
|
; Called by: File system routines which must be executed synchronously
|
|
; (MountVol,UnMountVol).
|
|
;
|
|
; Function: This entry point waits until the file system queue is
|
|
; empty, and then calls the calling routine, ensuring
|
|
; synchronous (with other file system calls) execution of
|
|
; the file system routine at user-level (memory manager calls
|
|
; are ok). The called routine calls CmdDon when through.
|
|
;
|
|
; Modification History:
|
|
;
|
|
; 02 Dec 82 LAK New today.
|
|
;
|
|
;_______________________________________________________________________
|
|
|
|
FSQueueSync
|
|
BCLR #AsyncTrpBit,D1 ; ensure async bit is not on
|
|
; fall thru to FSSync
|
|
;_______________________________________________________________________
|
|
;
|
|
; Routine: FSQueue,CmdDone
|
|
; Arguments: D1 = trap
|
|
; A0 = parameter list pointer
|
|
; Calls: FSQue dispatches to the calling routine unless the call is
|
|
; asynchronous and the file system queue is not empty. Pascal
|
|
; register save conventions are observed.
|
|
; Called by: All file system routines when they may be executed asynchronously
|
|
; (i.e., they don't call the memory manager).
|
|
;
|
|
; Function: This entry point determines whether a call is synchronous
|
|
; or asynchronous; it queues up the call, then, if async and
|
|
; there is a command already executing, returns immediately.
|
|
; Otherwise, it enters the sync wait routine, then goes to
|
|
; command dispatch.
|
|
;
|
|
; All of these commands finish by branching to CmdDone; this
|
|
; routine calls any completion routine and dispatches the
|
|
; next queued command, if any . . .
|
|
;
|
|
; Modification History:
|
|
;
|
|
; 05 Aug 84 GSS New today (taken from Larry Kenyon's Mac File System)
|
|
; 24 Sep 84 GSS Removed JSR Enqueue and put in a trap
|
|
; 10-Feb-85 PWD Re-inserted JSR to Enqueue (now directly accessible again)
|
|
; 13-Mar-85 PWD Added code to set up A6 stack for async context storage\
|
|
; 26-Jul-85 PWD Changed to restore ioTrap to $Ax60 and D0 to TFS trap index
|
|
; before going off to external file system hook.
|
|
; 25-Sep-85 PWD Changed to allow SkipPMSP to come on in mid-parse
|
|
; 22-Oct-85 PWD Fixed to check PMSP for traps w. TFS bit set but DirID=0.
|
|
;
|
|
; Do async calls have to be forced synchronous if the file system is not busy?
|
|
; Make sure interrupts are disabled at this time, though, so another request
|
|
; issued at interrupt time doesn't interfere.
|
|
;_______________________________________________________________________
|
|
|
|
FSQueue
|
|
MOVE.L FSQueueHook,D2 ; queue hook?
|
|
BLE.S @0 ; br if not . . .
|
|
MOVE.L D2,A1
|
|
JSR (A1) ; D2 and A1 are expendable
|
|
|
|
@0 MOVE.W #1,IOResult(A0) ; set IOResult to "in process"
|
|
MOVE.W D1,IOTrap(A0) ; save the trap number
|
|
CMP.B #$60,D1 ; TFS trap dispatch?
|
|
BNE.S @2 ; If not, leave ioTrap alone
|
|
|
|
AND.B #$0F,ioTrap(A0) ; Leave only modifier bits <27Aug85>
|
|
MOVE.B D0,ioTrap+1(A0) ; Store trap index in low byte <27Aug85>
|
|
|
|
@2 MOVE.L (SP)+,IOCmdAddr(A0) ; save address to go to when ready
|
|
MOVE.W #FSQType,IOType(A0) ; say its a file system queueing element
|
|
|
|
BTST #AsyncTrpBit,D1 ; async bit on?
|
|
BEQ.S @3 ; br if not
|
|
|
|
TST.B FrcSync ; force it synchronous?
|
|
BEQ.S FSAsync ; if not, do it async
|
|
BRA.S @4
|
|
|
|
@3 CLR.L IOCompletion(A0) ; no completion routines for sync calls
|
|
@4 MOVE.L A0,-(SP) ; save parameter block ptr
|
|
BSR.S FSAsync ; queue it up (and maybe call it)
|
|
MOVE.L (SP)+,A0
|
|
|
|
SyncWait MOVE.W IOResult(A0),D0 ; get the result code into D0
|
|
BGT.S SyncWait ; done when result is zero or negative
|
|
|
|
EXT.L D0 ; ALWAYS return a long error code.
|
|
|
|
CMP.W #VolOffLinErr,D0 ; volume off-line error? (detected by file
|
|
BNE.S @1 ; system) br if not
|
|
MOVE.L DskSwtchHook,-(SP) ; OffLineVol points to VCB, A0 to request
|
|
BGT.S @1 ; br if there is a hook proc
|
|
ADDQ #4,SP ; otherwise, just return
|
|
|
|
IF ForROM THEN ; <27Mar89 V1.8>
|
|
BTST #7, DSAlertRect ; already in our proc? <06Mar85>
|
|
BNE DSHook ; br if not <06Mar85>
|
|
ENDIF ; <27Mar89 V1.8>
|
|
|
|
@1 RTS ; return to caller
|
|
|
|
FSAsync LEA FSQHdr,A1 ; get pointer to file system queue
|
|
MOVE SR,-(SP) ; only allow level 3
|
|
ORI #HiIntMask,SR ; interrupts for debugging
|
|
JSR EnqueueTrap ; queue up the request
|
|
|
|
ToFSDispatch
|
|
BSET #0,FSBusy ; is a request already executing?
|
|
BEQ.S FSDispatch ; if not, just call it
|
|
|
|
; The file system is busy so we're done for now. We'll get to it when
|
|
; CmdDone is called. (maybe check here for async call with off-line vols,
|
|
; since only eject will force something off-line . . .)
|
|
|
|
MOVEQ #0,D0 ; no errors (yet)
|
|
MOVE.W (SP)+,SR ; re-enable interrupts and return
|
|
RTS
|
|
|
|
; dispatch the next request (also called by CmdDon)
|
|
|
|
FSDispatch
|
|
MOVE (SP)+,SR ; re-enable interrupts
|
|
MOVE.L FSQHead,A0 ; get first parameter block
|
|
MOVE.L IOCmdAddr(A0),A1 ; get address to call
|
|
MOVEM.L D3-D7/A2-A6,-(SP) ; observe Pascal regsave conventions
|
|
|
|
; Just before the initial dispatch into the routine,
|
|
; clear the Poor Man's Search Path:
|
|
|
|
MOVEA.L PMSPPtr,A6 ; Point to the PMSP table
|
|
CLR.W PMSPIndx(A6) ; No entries used yet
|
|
|
|
BTST #AsyncTrpBit,ioTrap(A0) ; set the flavor for this trap <01Oct85>
|
|
IF HFSDebug THEN
|
|
ST FSCallAsync ; If we're debugging, always do async <27Oct85>
|
|
ELSE
|
|
SNE FSCallAsync ; if sync, we'll do our I/O synchronous <01Oct85>
|
|
ENDIF ;<HFSDebug>
|
|
|
|
MOVEA.L HFSStkTop,A6 ; Set up A6 for use as stack pointer
|
|
JSR (A1) ;
|
|
MOVEM.L (SP)+,D3-D7/A2-A6 ; restore registers
|
|
RTS ; and return (all commands finish by
|
|
; jumping to CmdDone)
|
|
|
|
toDSFSErr MOVEQ #DSFSErr,D0
|
|
_SysError
|
|
|
|
CmdDone
|
|
IF HFSDebug THEN
|
|
BRA.S @3 ; check to see if cache is cool <02Oct85>
|
|
|
|
@0 MOVEA.L A3,A4 ; start at top of queue <02Oct85>
|
|
|
|
@1 MOVEA.L CBHFlink(A4),A4 ; position to next buffer <02Oct85>
|
|
CMPA.L A3,A4 ; back to top of queue ? <02Oct85>
|
|
BEQ.S @2 ; yes -> <02Oct85>
|
|
|
|
BTST #CBHinuse,CBHFlags(A4) ; buffer in-use? <02Oct85>
|
|
BEQ.S @1 ; no, continue search -> <02Oct85>
|
|
_HFSDebug $500 ; trap if we exit FS with a buf in-use <02Oct85>
|
|
@2 RTS ; 02Oct85
|
|
|
|
@3 MOVEM.L A3-A4,-(SP) ; save registers <02Oct85>
|
|
|
|
MOVEA.L SysCtlCPtr,A3 ; A3 = ptr(control cache header) <02Oct85>
|
|
BSR.S @0 ; check out the control cache <02Oct85>
|
|
MOVEA.L SysBMCPtr,A3 ; <02Oct85>
|
|
BSR.S @0 ; check out the alloc map cache <02Oct85>
|
|
MOVEA.L SysVolCPtr,A3 ; <02Oct85>
|
|
BSR.S @0 ; check out the volume cache <02Oct85>
|
|
|
|
MOVEM.L (SP)+,A3-A4 ; restore registers <02Oct85>
|
|
|
|
RealCmdDone
|
|
ENDIF
|
|
|
|
CLR.B CacheFlag ; we're always clean here . . . <05Sep85>
|
|
|
|
EXT.L D0 ; Make a long of it <14Jun85>
|
|
BLE.S @0 ; If zero or negative, we're OK <01Oct85>
|
|
MOVE.W D0,HFSDSErr ; Save internal error for debug <01Oct85>
|
|
MOVEQ #FSDSIntErr,D0 ; 1-127 codes are internal errors <01Oct85>
|
|
|
|
@0 MOVE.L FSQHead,A0 ; A0 -> current request
|
|
CMP #FSQType,IOType(A0) ; it better be an I/O queue element
|
|
BNE.S toDSFSErr ; or else die
|
|
|
|
CMP.W #FNFErr,D0 ; File not found error?
|
|
BNE.S cd_CkExtFS ; If not, we're gone.
|
|
BTST #HFSBit,ioTrap(A0) ; Use of HFSBit (=9) is OK on high byte ref.
|
|
BEQ.S @2 ; If clear, consider the next entry on the PMSP <22Oct85>
|
|
TST.L ioDirID(A0) ; TFS trap: was DidID specified? <22Oct85>
|
|
BNE.S cd_CkExtFS ; Yes - there's no search path to consider <22Oct85>
|
|
|
|
@2 BTST #NoPMSP,HFSFlags ; PMSP disabled? <25Sep85>
|
|
BNE.S cd_CkExtFS ; If set, don't search any other directories <25Sep85>
|
|
|
|
BTST #SkipPMSP,HFSFlags ; Don't bother with PMSP for this operation? <22Aug85>
|
|
BNE.S cd_CkExtFS ; If flag isn't set, give it a chance <22Aug85>
|
|
|
|
MOVEA.L PMSPPtr,A1 ; Point to the search path list
|
|
MOVEM.L D1/A2,-(SP) ; Save them across the offline check
|
|
MOVE.W PMSPIndx(A1),D1 ; Pick up the index
|
|
|
|
@3 ADDQ.W #SPEntLen,D1 ; Advance to the next entry
|
|
CMP.W (A1),D1 ; Index outside table yet?
|
|
BGE.S @5 ; Yes - give up.
|
|
MOVE.W SPVRefNum(A1,D1),D0 ; Pick up the VRefNum
|
|
BEQ.S @5 ; If there isn't one, give up.
|
|
BSR GetVCBRfn ; Find the VCB
|
|
BNE.S @5 ; Punt on errors
|
|
MOVE.W vcbDrvNum(A2),D0 ; Volume on-line?
|
|
BLE.S @3 ; No - try next entry.
|
|
|
|
@5 MOVE.W D1,PMSPIndx(A1) ; Point to this entry
|
|
MOVE.W D1,D0 ; Save the index
|
|
|
|
MOVEM.L (SP)+,D1/A2 ; Restore scratch registers
|
|
CMP.W (A1),D0 ; Exceeded PMSP table limits?
|
|
BGE.S @10 ; Yes - punt.
|
|
TST.W SPVRefNum(A1,D0) ; Was a new default volume found?
|
|
BEQ.S @10 ; Nope - give up.
|
|
MOVEQ #0,D0 ; Clear high 3 bytes
|
|
MOVE.B ioTrap+1(A0),D0 ; Pick up the TFS trap index again, too
|
|
MOVEA.L ioCmdAddr(A0),A1 ; Pick up the CmdAddr from FSQueue
|
|
JMP (A1) ; Repeat the trap with a different default
|
|
|
|
@10 MOVEQ #FNFErr,D0 ; Restore error code
|
|
|
|
cd_CkExtFS BCLR #SkipPMSP,HFSFlags ; Don't skip PMSP now that this trap's done <25Sep85>
|
|
MOVE.L ExtFSHook,D2 ; queue hook?
|
|
BLE.S @1 ; br if not . . .
|
|
MOVE.L D2,A1 ; (external fs, debug)
|
|
JSR (A1) ; leave CmdDone address on the stack
|
|
@1
|
|
move.l toExtFS,d2 ; Any external file systems defined? <10Nov87>
|
|
ble.s cd_DeQueue ; Xfer if not... <10Nov87>
|
|
move.l d2,a1 ; Else, point to first proc in chain <10Nov87>
|
|
|
|
cmp.w #ExtFSErr,d0 ; Pass request on to external FS's? <10Nov87>
|
|
beq.s @2 ; Xfer if so... <10Nov87>
|
|
cmp.w #NoMacDskErr,d0 ; Did a MountVol call fail? <10Nov87>
|
|
bne.s cd_DeQueue ; Xfer if not... <10Nov87>
|
|
clr.l ReqstVol ; Force 'No VCB' for this call <10Nov87>
|
|
@2
|
|
MOVE.L FSQHead,A0 ; A0 -> current request
|
|
CMP #FSQType,IOType(A0) ; it better be an I/O queue element
|
|
BNE toDSFSErr ; or else die
|
|
|
|
MOVEQ #ExtFSErr,D0 ; Code to ExtFS's unless an $Ax60 call <03Mar87>
|
|
TST.W ioTrap(A0) ; Check trap word:
|
|
BLT.S @3 ; If it's negative ($A...), go ahead <27Aug85>
|
|
|
|
MOVEQ #0,D0 ; Clear high 3 bytes <27Aug85>
|
|
MOVE.B ioTrap+1(A0),D0 ; Pick up the TFS trap index <27Aug85>
|
|
CLR.B ioTrap+1(A0) ; and restore original trap <27Aug85>
|
|
ORI.W #$A060,ioTrap(A0) ; keeping modifier bits <27Aug85>
|
|
@3
|
|
JSR (A1) ; leave CmdDone address on the stack <25Jan85>
|
|
|
|
cd_DeQueue MOVE SR,-(SP) ; save interrupt state <27Aug85>
|
|
ORI #HiIntMask,SR ; only debug interrupts allowed
|
|
CLR.W FSBusy ; clear file system busy boolean
|
|
|
|
; delete the current request from the queue and post any completion routines
|
|
|
|
MOVE.L FSQHead,A0 ; A0 -> current request
|
|
CMP #FSQType,IOType(A0) ; it better be an I/O queue element
|
|
BNE toDSFSErr ; or else die
|
|
MOVE.L QLink(A0),FSQHead ; get next request, if any
|
|
BNE.S cd_CallComp ; branch if queue not empty <27Aug85>
|
|
CLR.L FSQTail ; clear tail ptr, too
|
|
|
|
cd_CallComp ; <27Aug85>
|
|
MOVE (SP)+,SR ; restore interrupt state
|
|
MOVE.W D0,IOResult(A0) ; post error code
|
|
|
|
MOVE.L IOCompletion(A0),D1 ; is there a completion routine?
|
|
BEQ.S cd_DispNext ; skip if there's not <27Aug85>
|
|
|
|
MOVE.L D1,A1 ; get the completion routine address
|
|
TST.W D0 ; test result code
|
|
JSR (A1) ; call it
|
|
|
|
; check if there's anything else for this driver to do
|
|
|
|
cd_DispNext ; <27Aug85>
|
|
MOVE SR,-(SP) ; save interrupt state
|
|
ORI #HiIntMask,SR ; only debug interrupts allowed
|
|
TST.L FSQHead ; is a command pending?
|
|
BNE ToFSDispatch ; if so, launch new command
|
|
MOVE.W (SP)+,SR ; restore rupt state and return
|
|
RTS
|
|
|
|
;_______________________________________________________________________
|
|
;
|
|
; Routine: FInitQueue
|
|
; Arguments: none
|
|
; Calls:
|
|
; Function: Clear the queue of all pending commands except for the one
|
|
; running (if there is one . . .).
|
|
;
|
|
; Modification History:
|
|
;
|
|
; 05 Aug 84 New today. Taken directly from LAK's FS code
|
|
;
|
|
;_______________________________________________________________________
|
|
|
|
FInitQueue
|
|
MOVE SR,-(SP) ; save interrupt state
|
|
ORI #HiIntMask,SR ; only debug interrupts
|
|
MOVE.L FSQHead,D0 ; any commands?
|
|
BEQ.S @1 ; if not, we are done
|
|
MOVE.L D0,A0 ; get pointer to the current routine
|
|
CLR.L IOLink(A0) ; get rid of any others
|
|
MOVE.L A0,FSQTail ; only this one
|
|
@1 MOVEQ #0,D0 ; this routine has no errors
|
|
MOVE.W (SP)+, SR
|
|
RTS
|
|
|
|
;_______________________________________________________________________
|
|
;
|
|
; Routine: DSHook
|
|
; Arguments: none
|
|
; Calls:
|
|
; Function: Implements disk-switch recovery.
|
|
;
|
|
; 29 Jan 85 LAK Doubled amount of stack slop needed.
|
|
;
|
|
; To Do:
|
|
; - be smarter about number of bytes to save of rectangle (compute from
|
|
; rectangle).
|
|
;
|
|
; There was a bug in the DSHook code used to force updates that is used when there is insufficient
|
|
; room on the stack to save the room behind the disk switch dialog. We now use the new global,
|
|
; SysErrorUpdateRect, instead. See the patch to GetNextEvent that uses SysErrorUpdateRect for more
|
|
; information
|
|
;_______________________________________________________________________
|
|
|
|
DSHook
|
|
MOVEM.L A0-A3/A6/D0-D7,-(SP) ; save registers
|
|
|
|
LEA TrapAgain,A1 ; fill in the trap now
|
|
MOVE.W IOTrap(A0),(A1)+ ; Set up the trap to be retried...
|
|
MOVE.W #$4E75,(A1) ; Follow it with an RTS
|
|
|
|
; first try mounting the volume in case it was forced off-line due to mem-full:
|
|
|
|
IF NOT hasManEject THEN ; if man-eject, defer this a bit <SM8> <BH 03Aug93>
|
|
BSR MakeStkPB ; get a parameter block off the stack . .
|
|
MOVE.L A0,D7 ; remember it in D7
|
|
ENDIF
|
|
|
|
MOVE.L ReqstVol,A2 ; VCB for requested volume
|
|
MOVE.W VCBDRefNum(A2),D3 ; Original drive
|
|
BPL.S TellUser ; br if ejected-offline
|
|
NEG.W D3 ; negative means non-ejected offline
|
|
|
|
IF hasManEject THEN ; <SM8> <BH 03Aug93>
|
|
BSR MakeStkPB ; get a parameter block off the stack . .
|
|
MOVE.W D3,ioDrvNum(A0) ; remount this drive
|
|
MOVE.L FSVarsPtr,A1
|
|
BSET.B #fsNoAllocate,FSVars.fsFlags(A1) ; inform _Mount that it can't allocate memory
|
|
_MountVol
|
|
BCLR.B #fsNoAllocate,FSVars.fsFlags(A1)
|
|
ADDA.L #IOVQElSize,SP ; goodbye paramblock
|
|
TST ioResult(A0) ; success?
|
|
BEQ.S DSExit
|
|
TellUser MOVE.W #dsReinsert,D4 ; err code for SwitchDisk
|
|
BSR.S SwitchDisk ; ask for the disk
|
|
; CCR: Z set if disk received, clear if request aborted
|
|
DSExit
|
|
|
|
ELSE ; if NOT hasManEject, here's the old DSHook, most of which resides in
|
|
; SwitchDisk for the manual-eject case. <SM8> <BH 03Aug93>
|
|
MOVE.W D3,IODrvNum(A0) ; so just remount (reload the buffers)
|
|
MOVE.L FSVarsPtr,A2 ; <SM7>
|
|
BSET.B #fsNoAllocate,FSVars.fsFlags(A2) ; inform _Mount that it can't allocate memory <SM7>
|
|
_MountVol ; <SM7>
|
|
BCLR.B #fsNoAllocate,FSVars.fsFlags(A2); <SM7>
|
|
TST ioResult(A0) ; <SM7>
|
|
BNE.S TellUser ; ?? tell user something ?? <03Nov85> LAK
|
|
|
|
MOVEQ #0,D3 ; yes, retry the fs call <03Nov85> LAK
|
|
BRA DSExit ; exit . . . <03Nov85> LAK
|
|
|
|
TellUser MOVE.L #$00500078,DSAlertRect ; use alternate alert rect
|
|
MOVE.L #$00980195,DSAlertRect+4 ;(high bit is also flag)
|
|
|
|
; the code the saved the screen behind the dialog has been removed. <SM1>
|
|
|
|
MOVEQ #DSReInsert,D0 ; ask for diskette back
|
|
_SysError
|
|
|
|
EjectCurDisk
|
|
MOVE.L DrvQHdr+QHead,D0 ; figure out if this drive has a disk-in-place
|
|
@0 BEQ.S WaitForDsk
|
|
MOVE.L D0,A1
|
|
CMP.W DQDrive(A1),D3 ; find queue element for this drive
|
|
BEQ.S @1
|
|
MOVE.L QLink(A1),D0
|
|
BRA.S @0
|
|
|
|
@1 MOVE.B -3(A1),D0 ; DiskInPlace
|
|
CMP.B #1,D0 ;
|
|
BEQ.S @2
|
|
CMP.B #2,D0
|
|
BNE.S WaitForDsk ; just wait for disk-insert if no DIP
|
|
|
|
@2 MOVE.W D3,D1 ; disk to eject
|
|
|
|
EjectMtDisk ; <03Nov85> LAK
|
|
MOVEQ #2,D2 ; a disk-switch eject <03Nov85> LAK
|
|
BSR DoEject
|
|
|
|
WaitForDsk
|
|
SUB #EvtBlkSize,SP ; get event buffer space off the stack
|
|
|
|
@0 MOVE.W #128+8,D0 ; only disk-inserted/key down events interest us
|
|
MOVE.L SP,A0 ; event buffer
|
|
_GetOSEvent
|
|
BNE.S @0 ; loop until we get one . . .
|
|
|
|
MOVE.L evtMessage(SP),D0 ; drive number/key
|
|
MOVE.W evtNum(SP),D3 ; event
|
|
MOVE.W evtMeta(SP),D1 ; meta keys (for command bit)
|
|
ADD #EvtBlkSize,SP ; free up event buffer space
|
|
|
|
SUBQ #diskInsertEvt,D3 ; disk-insert event?
|
|
BEQ.S @3 ; br if so <02Nov85> LAK
|
|
CMP.B #$2E,D0 ; period?
|
|
BEQ.S @2 ; br if so <02Nov85> LAK
|
|
|
|
MOVEQ #$0B,D2 ; seek cmd, shift, not alphaLock, and option <02Nov85> LAK
|
|
LSR.W #8,D1 ; get high byte of meta-key info, clear D1.W hi byte <02Nov85> LAK
|
|
AND.B D1,D2 ; high byte of meta word contains mod bits <02Nov85> LAK
|
|
SUBQ.B #$03,D2 ; want cmd AND shift BUT NOT option <02Nov85> LAK
|
|
BNE.S WaitForDsk ; if not so, no FKey action! <02Nov85> LAK
|
|
|
|
moveq.l #-'3',d1 ; prepare to convert ascii to binary <2.6>
|
|
add.b d0,d1 ; keyCode - '3' <2.6>
|
|
addq.b #3,d1 ; convert key to drivenum, range check <2.6>
|
|
bhs.s WaitForDsk ; if >= '3', or < '0', not an eject req <2.6>
|
|
ext.w d1 ; drive number in D1.W <C150/10sep86><2.6>
|
|
bne.s @1 ; 1, 2 handled as is, <C150/10sep86>
|
|
moveq #3,D1 ; 0 becomes 3 (drive #3) <C150/10sep86><2.6>
|
|
@1 moveq #1,D2 ; flag from keyboard, <C150/10sep86>
|
|
move.l jDoEject,A0 ; <C150/10sep86>
|
|
jsr (A0) ; eject the diskette <C150/10sep86>
|
|
BRA.S WaitForDsk ; keep waiting for Disk-In-Place <02Nov85> LAK
|
|
|
|
@2 BTST #cmdKey,D1 ; command-. for abort? <02Nov85> LAK
|
|
BEQ.S WaitForDsk ; keep waiting if not
|
|
BRA.S PostUpdate ; otherwise, let the user beware!
|
|
; D3 non-zero denotes abort . . .
|
|
@3 MOVE.L D7,A0 ; point to the I/O block <02Nov85> LAK
|
|
MOVE.W D0,IODrvNum(A0) ; drive to mount
|
|
MOVE.W D0,D1 ; save in case we have to eject it <03Nov85> LAK
|
|
MOVE.L FSVarsPtr,A2 ; <SM7>
|
|
BSET.B #fsNoAllocate,FSVars.fsFlags(A2) ; inform _Mount that it can't allocate memory <SM7>
|
|
_MountVol ; <SM7>
|
|
BCLR.B #fsNoAllocate,FSVars.fsFlags(A2) ; <SM7>
|
|
TST ioResult(A0) ; <SM7>
|
|
BEQ.S PostUpdate ; cruise on if ok <03Nov85> LAK
|
|
|
|
CMP.W #MemFullErr,D0 ; memory full?
|
|
BNE.S EjectMtDisk ; br if not - eject it and wait some more <03Nov85> LAK
|
|
|
|
MOVEQ #-1,D3 ; make it an abort (avoid DS) <01Oct85>
|
|
|
|
; OK, we're basically done with the disk switched stuff.
|
|
; The code the saved the screen behind the dialog has been removed. <SM1>
|
|
PostUpdate ; <SM1>
|
|
CLR.B DSWndUpdate ; flag GNE to remove the alert . . . <SM1>
|
|
PEA DSAlertRect ; union this in <SM1>
|
|
MOVE.L ExpandMem,a0 ; <SM1>
|
|
PEA ExpandMemRec.SysErrorUpdateRect(a0) ; into this rect <SM1>
|
|
move.l (sp),-(sp) ; do it in place <SM1> <SM4> rb
|
|
_UnionRect ; <SM1>
|
|
|
|
DSExit BSET #7, DSAlertRect ; return to old DS rect (also clears exclusion) <06Mar85>
|
|
; <removed reinstall of DskSwHook> <06Mar85>
|
|
ADD #IOVQElSize,SP ; clean up stack
|
|
TST.W D3 ; zero for non-abort . . . <01Oct85>
|
|
ENDIF ; hasManEject--the manual-eject and non-manual-eject threads rejoin here
|
|
|
|
MOVEM.L (SP)+,A0-A3/A6/D0-D7 ; restore registers
|
|
BEQ.S @1 ; br for retry <01Oct85>
|
|
|
|
MOVEQ #VolOffLinErr,D0 ; well, not much else to do . . . <01Oct85>
|
|
RTS ; <01Oct85>
|
|
|
|
@1 MOVE.W ioTrap(A0),D0 ; Pick up trap word again <01Oct85>
|
|
|
|
BLE.S FlushTrapAgain ; Go re-execute the original I/O trap <2> rb <SM1>
|
|
; (should we be using a signed branch?) <SM1>
|
|
; <SM1>
|
|
; Repeat a TFS trap: the word in ioTrap (copied into TrapAgain by now) usually <SM1>
|
|
; looks like 0mxx, where m contains the modifiers (,ASYNC and ,IMMED for TFS) <SM1>
|
|
; and xx is the TFS trap dispatch. TrapAgain must be changed to Ay60 and D0 <SM1>
|
|
; to $00xx. <SM1>
|
|
; <SM1>
|
|
TFSAgain: OR.B #$A0,TrapAgain ; Set up top nibble <SM1>
|
|
MOVE.B #$60,TrapAgain+1 ; Overwrite lower bytes w. TFS trap <SM1>
|
|
AND.W #$00FF,D0 ; Remove modifier bits from saved index <SM1>
|
|
; <SM1>
|
|
FlushTrapAgain ; <SM1>
|
|
MOVE.L D1,-(SP) ; save D1 for 020/030's <2> rb <SM1>
|
|
JSR ([jCacheFlush]) ; flush the cache <2> rb <SM1>
|
|
MOVE.L (SP)+,D1 ; restore D1 <2> rb <SM1>
|
|
JMP TrapAgain ; Go re-execute the original I/O trap <2> rb <SM1>
|
|
|
|
|
|
IF hasManEject THEN ; <SM8> <BH 03Aug93>
|
|
; This is now a subroutine so it can be used by the Desk Manager to get back dirty
|
|
; disks that have been manually ejected. It largely duplicates the old code.
|
|
; Inputs: A2 -> VCB of desired volume
|
|
; D4 == DS err ID for alert to be displayed
|
|
SwitchDisk
|
|
MOVEM.L D1-D3/A0-A1/A3-A4,-(SP) ; save regs
|
|
BSR MakeStkPB ; get ioPB space on stack
|
|
MOVEA.L A0,A3 ; A3 -> paramblock
|
|
SUBA.L #EvtBlkSize,SP ; stack space for evt record
|
|
MOVEA.L SP,A4 ; A4 -> evt buffer
|
|
MOVE.L #$004B006A,DSAlertRect ; set up alternate sys alert rect
|
|
MOVE.L #$00A50196,DSAlertRect+4 ; (high bit is also flag)
|
|
; all NEW, all BIGGER DSAlertRect! <SM9> <BH 27Aug93>
|
|
MOVEA.L FSVarsPtr,A0
|
|
BSET.B #fsNoAllocate,FSVars.fsFlags(A0) ; prevent new mounts
|
|
LEA vcbVN(A2),A1
|
|
MOVE.L A1,FSVars.dsRecoverNamePtr(A0) ; vol name for DS code
|
|
MOVEQ #1,D3 ; first time through, do draw alert at @getdisk
|
|
MOVEQ #2,D2 ; prepare disk-switch eject
|
|
MOVE.W vcbDrvNum(A2),D1 ; try to get the drive in which the vol was last seen
|
|
BNE.S @freeDrive
|
|
MOVE.W vcbDRefNum(A2),D1 ; offline vol's drive num is in DRefNum field
|
|
BPL.S @freeDrive ; positive if ejected-offline
|
|
NEG.W D1 ; negative if only offline
|
|
|
|
@freeDrive ; eject the disk in drive number D1, if any. D2 has "message" for EjectNotify--
|
|
; 1 for an FKEY eject, 2 for disk-switch.
|
|
MOVEA.L DrvQHdr+qHead,A0 ; Find drive queue element: get the first
|
|
@chkdrv CMP.W dqDrive(A0),D1 ; match?
|
|
BEQ.S @gotdrv ; yes: go check it out
|
|
MOVEA.L qLink(A0),A0 ; no: get next drive
|
|
MOVE.L A0,D0 ; any more?
|
|
BEQ.S @getdisk ; can't find the drive
|
|
BRA.S @chkdrv
|
|
|
|
@gotdrv BTST #dqManEjBit,dqInstall(A0) ; is this a manual eject drive?
|
|
BEQ.S @0 ; if so, the "Insert the disk" dialog will need to be
|
|
MOVEQ #1,D3 ; redrawn after ejection--set D3 to indicate this
|
|
@0 MOVEA.L jDoEject,A0
|
|
JSR (A0)
|
|
|
|
@getdisk TST.W D3 ; does the dialog need to be drawn?
|
|
BEQ.S @getevt
|
|
MOVE.W D4,D0 ; get DS code
|
|
_SysError ; draw it
|
|
MOVEQ #0,D3 ; flag it drawn
|
|
|
|
@getevt MOVE.W #128+8,D0 ; only disk-inserted/key down events interest us
|
|
MOVE.L A4,A0 ; event buffer
|
|
_GetOSEvent
|
|
BNE.S @getevt ; loop until we get one . . .
|
|
|
|
MOVE.L evtMessage(A4),D0 ; drive number or key
|
|
CMPI.W #diskInsertEvt,evtNum(A4) ; disk-insert event?
|
|
BEQ.S @dievt ; br if so <02Nov85> LAK
|
|
|
|
MOVE.W evtMeta(A4),D1 ; meta keys (for command bit)
|
|
CMP.B #$2E,D0 ; period?
|
|
BEQ.S @chkabort ; br if so <02Nov85> LAK
|
|
|
|
MOVEQ #$0B,D2 ; seek cmd, shift, not alphaLock, and option <02Nov85> LAK
|
|
LSR.W #8,D1 ; get high byte of meta-key info, clear D1.W hi byte <02Nov85> LAK
|
|
AND.B D1,D2 ; high byte of meta word contains mod bits <02Nov85> LAK
|
|
SUBQ.B #$03,D2 ; want cmd AND shift BUT NOT option <02Nov85> LAK
|
|
BNE.S @getevt ; if not so, no FKey action! <02Nov85> LAK
|
|
|
|
moveq.l #-'3',d1 ; prepare to convert ascii to binary <2.6>
|
|
add.b d0,d1 ; keyCode - '3' <2.6>
|
|
addq.b #3,d1 ; convert key to drivenum, range check <2.6>
|
|
bhs.s @getevt ; if >= '3', or < '0', not an eject req <2.6>
|
|
ext.w d1 ; drive number in D1.W <C150/10sep86><2.6>
|
|
bne.s @1 ; 1, 2 handled as is, <C150/10sep86>
|
|
moveq #3,D1 ; 0 becomes 3 (drive #3) <C150/10sep86><2.6>
|
|
@1 moveq #1,D2 ; flag from keyboard, <C150/10sep86>
|
|
BRA.S @freeDrive
|
|
|
|
@chkabort BTST #cmdKey,D1 ; command-. for abort? <02Nov85> LAK
|
|
BEQ.S @getevt ; keep waiting if not
|
|
BRA.S @aborted ; otherwise, let the user beware!
|
|
; D0 non-zero denotes abort . . .
|
|
@dievt MOVE.L D0,D1 ; get drive num in D1.W
|
|
SWAP D0
|
|
TST.W D0 ; is this a genuine insert event?
|
|
BNE.S @ejectevt ; no: it's some sort of ejection
|
|
MOVEA.L A3,A0 ; yes: get mountvol paramblock
|
|
MOVE.W D1,ioDrvNum(A0) ; drive to mount
|
|
_MountVol
|
|
BEQ.S @exitok ; success!
|
|
MOVEQ #2,D2 ; going to be a disk-switch eject
|
|
BRA.S @freeDrive ; wrong disk--go eject it and try again
|
|
|
|
@ejectevt CMP.W #-1,D0 ; is this an ejection request?
|
|
BEQ.S @1 ; yes: treat it like an FKEY
|
|
CMP.W vcbDRefNum(A2),D1 ; no: manual eject--is it the drive we expected the vol in?
|
|
BEQ.S @getevt ; yes: probably spurious, so drop it...that drive should be empty
|
|
; no: hmm, what to do...repost, deal with it later
|
|
SWAP D0 ; restore message
|
|
MOVEA.W #DiskInsertEvt,A0 ; event type
|
|
_PostEvent ; post it
|
|
BRA.S @getevt ; go back for another
|
|
|
|
@aborted MOVEQ #1,D3
|
|
BRA.S PostUpdate
|
|
@exitok MOVEQ #0,D3
|
|
; OK, we're basically done with the disk switched stuff.
|
|
; The code the saved the screen behind the dialog has been removed. <SM1>
|
|
PostUpdate ; <SM1>
|
|
BSR.S CleanDSErr ; cleanup code now a subroutine, for sharing
|
|
CLR.W DSErrCode ; don't freak out the Process Mgr
|
|
MOVEA.L FSVarsPtr,A0
|
|
BCLR.B #fsNoAllocate,FSVars.fsFlags(a0) ; new mounts are OK again
|
|
MOVE.W D3,D0 ; get result, set CC
|
|
ADDA.L #EvtBlkSize+IOVQElSize,SP ; clean that stack
|
|
MOVEM.L (SP)+,D1-D3/A0-A1/A3-A4 ; restore those registers
|
|
RTS
|
|
|
|
; Clean up the disk-switch error box--now a subroutine for sharing purposes.
|
|
; It is called from CmdDone after _Eject has been called for a manual-eject
|
|
; drive; CmdDone uses a DS alert to tell the user to take the disk out of the
|
|
; drive.
|
|
CleanDSErr
|
|
CLR.B DSWndUpdate ; flag GNE to remove the alert . . . <SM1>
|
|
PEA DSAlertRect ; union this in <SM1>
|
|
MOVE.L ExpandMem,a0 ; <SM1>
|
|
PEA ExpandMemRec.SysErrorUpdateRect(a0) ; into this rect <SM1>
|
|
move.l (sp),-(sp) ; do it in place <SM1> <SM4> rb
|
|
_UnionRect ; <SM1>
|
|
BSET #7, DSAlertRect ; return to old DS rect (also clears exclusion) <06Mar85>
|
|
; <removed reinstall of DskSwHook> <06Mar85>
|
|
RTS
|
|
ENDIF ; <SM8> <BH 03Aug93>
|
|
|
|
|
|
;
|
|
;________________________________________________________________
|
|
;
|
|
; Routine: vDoEject,DoEject
|
|
; Arguments:
|
|
; D1 = drive # to eject
|
|
; D2 = 1 for keyboard/eject button source,
|
|
; 2 for Disk Switch code hook
|
|
;
|
|
; calls EjectNotify function as:
|
|
;
|
|
; Function EjectNotify(drive:int;caller:int):boolean;
|
|
;
|
|
; if false is returned, the disk is not ejected;
|
|
; caller=1 for eject key, caller=2 for DS hook
|
|
;_______________________________________;
|
|
|
|
vDoEject ;this label for export only
|
|
DoEject
|
|
BSR MakeStkPB ; get a parameter block
|
|
MOVE.W D1,IODrvNum(A0)
|
|
|
|
MOVE.L EjectNotify,D0 ; notify proc?
|
|
BLE.S @1 ; br if not
|
|
|
|
MOVEM.L D2/A0-A2,-(SP)
|
|
CLR.W -(SP)
|
|
MOVE.W D1,-(SP) ; pass eject drive
|
|
MOVE.W D2,-(SP) ; 1=fkey eject, 2=ds hook eject
|
|
MOVE.L D0,A0 ; procedure pointer
|
|
JSR (A0) ; call it (it should preserve Pascal regs)
|
|
TST.B (SP)+ ; still want to eject?
|
|
MOVEM.L (SP)+,D2/A0-A2
|
|
BEQ.S @2 ; br if not
|
|
|
|
@1 _Eject ; get rid of it . . .
|
|
BEQ.S @2
|
|
|
|
MOVE.W #8,-(SP)
|
|
_SysBeep ; make a beep
|
|
|
|
@2 ADD #IOVQElSize,SP ; clean up stack and return
|
|
RTS
|
|
|
|
;-----------------------------------------------------------------
|
|
; Initialize the file system.
|
|
;
|
|
; D0 -> number of FCBs to allocate.
|
|
;
|
|
;-----------------------------------------------------------------
|
|
|
|
InitFS TST.W FSFCBLen ; are we in already?
|
|
BPL FSInitOK ; br if so
|
|
|
|
; first, announce the presence of TFS by publishing the FCB size:
|
|
|
|
MOVE.W #FCBEntLen,FSFCBLen ; Store size of TFS FCB there; non- -1 value means TFS is in
|
|
|
|
; next, zero the low-memory file system area
|
|
|
|
LEA FileVars,A0 ; initialize our lomem vars to 0
|
|
MOVEQ #(FSClrWdLen/2)-1,D1 ; esp. VCB, FS queue hdrs, params, FSBusy
|
|
@1 CLR.W (A0)+
|
|
DBRA D1,@1
|
|
|
|
MOVE.W #StrtDir,DRMstrBlk ; set up master block address
|
|
|
|
; get some memory for the FCBs
|
|
|
|
CMP.W #2,MemTop ; 128K machine? <25Oct85>
|
|
BLE.S @2 ; no multiplier for 128K <22Oct85>
|
|
LSL.W #2,D0 ; mult by 4 for 512K+ <25Oct85>
|
|
|
|
@2 MOVE D0,D2 ; save for WDCB allocation <25Oct85>
|
|
MULU #FCBEntLen,D0 ; number of bytes needed for FCBs <25Oct85>
|
|
ADDQ.W #2,D0 ; and 2 for length prefix <25Oct85>
|
|
MOVE.W D0,D1 ; and save in D1 <25Oct85>
|
|
_NewPtr ,SYS,CLEAR ; get buffer with D0 bytes in it.
|
|
BNE FSInitErr ; Stop execution on any errors
|
|
|
|
MOVE.W D1,(A0) ; first word is FCB part length
|
|
MOVE.L A0,FCBSPtr ; set the FCB pointer
|
|
|
|
; Set up a WDCB array with the same number of entries as the FCB array:
|
|
|
|
MULU #WDCBLen,D2 ; number of bytes needed for WDCBs <25Oct85>
|
|
MOVE.L D2,D0 ; <25Oct85>
|
|
ADDQ.W #2,D0 ; and 2 for length prefix <08Aug85>
|
|
MOVE.W D0,D1 ; and save in D1 <11Apr85>
|
|
_NewPtr ,SYS,CLEAR ; Allocate room for the WDCB array <11Apr85>
|
|
BNE FSInitErr ; Crash and burn on errors <11Apr85>
|
|
|
|
MOVE.W D1,(A0) ; Store length of WDCB array <11Apr85>
|
|
MOVE.L A0,WDCBsPtr ; Store pointer in lomem <11Apr85>
|
|
|
|
BigLEA WDCBSwOS,A2 ; point to offset to the WDCB entry <1.2>
|
|
MOVE.W (A2),A2 ; Get the offset to the WDCB entry <1.2>
|
|
ADD.L SwitcherTPtr,A2 ; Index into Switcher Table <1.2>
|
|
MOVE.L A0,(A2) ; Fill in entry for WDCB switch <A271><27Oct86><1.2>
|
|
NOT.L (A2)+ ; ... complement for long addresses <A271><27Oct86><1.2>
|
|
MOVE.W D1,(A2) ; <A271><27Oct86><1.2>
|
|
|
|
; Allocate a File System Stack:
|
|
|
|
MOVE.L #(HFSStkLen+HFSTmpSize),D0 ; Size of stack area <26Aug85><C206>
|
|
_NewPtr ,SYS,CLEAR ; Allocate space in system heap <11Apr85>
|
|
BNE FSInitErr ; Stop execution on any errors <11Apr85>
|
|
ADD #HFSStkLen,A0 ; Point beyond the end of the stack <25Oct85><C206>
|
|
MOVE.L A0,HFSStkTop ; Store pointer in lo-mem <11Apr85><C206>
|
|
|
|
MOVEQ #PMSPSize,D0 ; Size of Poor Man's Search Path <18Aug85>
|
|
_NewPtr ,SYS,CLEAR ; Allocate space for it <18Aug85>
|
|
BNE FSInitErr ; Punt on errors <18Aug85>
|
|
|
|
BigLEA PMSPSwOS,A2 ; point to offset to the PMSP entry <C152><1.2>
|
|
MOVE.W (A2),A2 ; Get the offset to the PMSP entry <C152><1.2>
|
|
ADD.L SwitcherTPtr,A2 ; Index into Switcher Table <C152><1.2>
|
|
MOVE.L A0,(A2) ; Fill in entry for PMSP hook switch <A271><27Oct86><1.2>
|
|
NOT.L (A2) ; ... complement for long addresses <A271><27Oct86><1.2>
|
|
ADDQ.L #SPHdrSize,A0 ; Point beyond PMSP header <18Aug85>
|
|
MOVEQ #(PMSPSize-SPHdrSize),D0 ; Get length of remaining table <18Aug85>
|
|
MOVE.W D0,(A0) ; Stash it at the start of the table <18Aug85>
|
|
MOVE.L A0,PMSPPtr ; Set up the lo-mem pointer <18Aug85>
|
|
|
|
; Set up the lomem system cache pointers: (hack in until new cache arrives . . .)
|
|
|
|
MOVE.W #512,D1 ; Set up cache block size <26Aug85>
|
|
|
|
MOVEQ #1,D0 ; Allocate 1-block bitmap cache <26Aug85>
|
|
Jsr InitCache ; Set up the cache <26Aug85><1.2>
|
|
BNE.S FSInitErr ; <26Aug85>
|
|
MOVE.L A1,SysBMCPtr ; Bitmap cache pointer. <26Aug85>
|
|
|
|
MOVEQ #1,D0 ; Allocate a 1-block volume cache <20Sep85>
|
|
CMP.W #2,MemTop ; 128K machine? <20Sep85>
|
|
BLE.S @4 ; br if so <20Sep85>
|
|
MOVEQ #2,D0 ; Allocate a 2-block volume cache <20Sep85>
|
|
@4 Jsr InitCache ; Set up the cache <20Sep85><1.2>
|
|
BNE.S FSInitErr ; <26Aug85>
|
|
MOVE.L A1,SysVolCPtr ; Volume cache pointer <26Aug85>
|
|
|
|
MOVEQ #4,D0 ; Allocate a small B*-Tree cache <04Nov85>
|
|
CMP.W #2,MemTop ; 128K machine? <27Aug85>
|
|
BLE.S @5 ; br if so <27Aug85>
|
|
MOVEQ #16,D0 ; Allocate a LARGE B*-Tree cache <20Sep85>
|
|
@5 Jsr InitCache ; Create a new cache <26Aug85><1.2>
|
|
BNE.S FSInitErr ; <26Aug85>
|
|
MOVE.L A1,SysCtlCPtr ; B*-Tree Control cache pointer <26Aug85>
|
|
|
|
; Set up a disk switch hook
|
|
|
|
LEA DSHook,A0 ; Point to the disk switch code <22Jul85>
|
|
MOVE.L A0,DskSwtchHook ; Make it available for use <22Jul85>
|
|
|
|
; Begin SuperMario
|
|
; allocate our file system variable block <SM1> FM
|
|
|
|
move.l FSVarsPtr,D0 ; has this been initialized?
|
|
cmp.l #-1,D0 ; $FFFF FFFF if not
|
|
bne.s FSInitOK ; initialized
|
|
|
|
|
|
move.l #FSVars.size, d0 ; d0 = size of file system variable block
|
|
_NewPtr sys, clear ; go get the block
|
|
bne FSInitErr ; die horribly if we don't get it
|
|
move.l a0, FSVarsPtr ; stash the address in lomem
|
|
move.w #FSVars.size, FSVars.length(a0) ; store length of block in 1st word
|
|
|
|
jsr FSGrowPatchInit ; FCBs, WDCBs and vectors
|
|
jsr QMInit ; initialize the Queue Manager
|
|
jsr DTDBMgrInit ; initialize desktop DB manager
|
|
jsr InstallVectors ; install the vectors that hang off ExpandMem
|
|
|
|
; End of SuperMario patch roll inÉ <SM@> FM
|
|
|
|
FSInitOK MOVEQ #0,D0 ; success!
|
|
RTS
|
|
|
|
FSInitErr MOVEQ #-1,D0 ; we failed
|
|
RTS
|
|
|
|
;_____________________________________________________________________________________
|
|
; <38>
|
|
; CountFCBs
|
|
;
|
|
; Function:
|
|
; Return the number of free FCBs
|
|
; Return the total number of FCBs
|
|
;
|
|
; Use d0 as a max number to count, to allow for callers to check for a
|
|
; specific quantity of free FCBs.
|
|
;
|
|
; Input:
|
|
; d0.w - requested # of free FCBs
|
|
;
|
|
; Output:
|
|
; d0.w - number of free FCBs (clipped to input value of d0)
|
|
; d1.w - total number of FCBs
|
|
;
|
|
; ccr - Z set if requested number were free
|
|
; Z clear if not
|
|
;
|
|
; Note: When called with d0.w = #-1, the output in d1 is the total number
|
|
; of FCBs that exist.
|
|
;
|
|
;_____________________________________________________________________________________
|
|
; This routine was copied FileMgrPatches.a <SM1>
|
|
|
|
CountFCBs
|
|
@Regs reg d2/a0/a1
|
|
movem.l @Regs,-(sp)
|
|
move.l FCBSPtr,a1 ; point to base of FCB array
|
|
moveq.l #0,d1 ; clear high word
|
|
move.w (a1),d1 ; grab length of the array
|
|
lea.l 2(a1),a0 ; point to base of 1st FCB
|
|
add.w d1,a1 ; point to end of FCB array
|
|
divu FSFCBLen,d1 ; d1 = number of FCBs
|
|
move.w d0,d2 ; copy limit value
|
|
|
|
@loop:
|
|
suba.w FSFCBLen,a1 ; point to beginning of previous FCB
|
|
tst.l (a1) ; is it free?
|
|
bne.s @notFree
|
|
subq.w #1,d2 ; tally the free FCB
|
|
beq.s @enough ; hit our quota?
|
|
@notFree:
|
|
cmpa.l a0,a1 ; are we done with the array?
|
|
bhi.s @loop ; as long as we're above the bottom now
|
|
@enough:
|
|
sub.w d2,d0 ; d0 = number of free FCBs
|
|
tst.w d2 ; d2 is zero if we hit our target
|
|
movem.l (sp)+,@Regs
|
|
rts
|
|
|
|
|
|
;_____________________________________________________________________________________
|
|
; <38>
|
|
; OpenAttemptHook
|
|
;
|
|
; Function:
|
|
; This procedure is called each time some sort of Open call (one that allocates
|
|
; an FCB) is attempted. We're here to schedule the FCB allocator if
|
|
; necessary. The FCB allocator is now run after the sync wait loop (on failed
|
|
; opens) and at _SynchIdleTime, although it could be run anytime moving memory
|
|
; is cool.
|
|
;
|
|
; Optimization:
|
|
; Since counting the number of free FCBs is time consuming, we use fsFCBCounter
|
|
; to hold the approximate number of free FCBs in excess of the fsFCBBurst amount.
|
|
; We conservatively assume that each time we attempt an open we use up an FCB. This
|
|
; is obviously wrong, since some opens fail and _Close frees up FCBs, but this
|
|
; will allow us to avoid our more expensive check most of the time. When the counter
|
|
; does hit zero we count the array and set fsFCBCounter back up. We also might set
|
|
; the fsNeedsFCBs value if there are too few FCBs around.
|
|
;
|
|
; Input:
|
|
; a0 - pointer to caller's PB
|
|
;
|
|
; Output:
|
|
; none
|
|
;_____________________________________________________________________________________
|
|
; This routine was copied FileMgrPatches.a <SM1>
|
|
OpenAttemptHook:
|
|
@regs reg d0/d1/a1
|
|
movem.l @regs,-(sp)
|
|
|
|
move.l FSVarsPtr,a1
|
|
with FSVars
|
|
|
|
btst.b #fsNoFCBExpansion,fsFlags(a1) ; are we in the ballgame?
|
|
bne.s @exit
|
|
|
|
sub.w #1,fsFCBCounter(a1) ; see if we need to check
|
|
bgt.s @exit ; no need to check if we're > 0
|
|
|
|
moveq.l #-1,d0 ; we want to know about all FCBs
|
|
bsr CountFCBs ; see how many there are
|
|
|
|
sub.w fsFCBBurst(a1),d0 ; do we have enough headroom?
|
|
bls.s @needMore ; need more if (#free) <= (burst amount)
|
|
|
|
move.w d0,fsFCBCounter(a1) ; remember the amount of slack
|
|
bra.s @exit
|
|
|
|
@needMore:
|
|
bset.b #fsNeedFCBs,fsFlags(a1) ; remind ourselves of our need
|
|
clr.w fsFCBCounter(a1) ; and make sure we check next time
|
|
|
|
@exit:
|
|
movem.l (sp)+,@regs
|
|
rts
|
|
|
|
;_____________________________________________________________________________________
|
|
; <38>
|
|
; AllocateFCBs
|
|
;
|
|
; Function:
|
|
; This is a private queued file system call which returns information
|
|
; about the FCB array and can allocate more FCBs.
|
|
;
|
|
; If a request for more FCBs is being made then AllocateFCBs must be
|
|
; called only when moving memory is legal. If the call is made for
|
|
; information only it can be made anytime.
|
|
;
|
|
; parameter block:
|
|
; ioFCBBurst offset $20, word, input requested burst headroom
|
|
; ioFCBGrow offset $22 word, input requested free if allocation triggered
|
|
; ioTotalFCBs offset $24 word, output returns number of FCBs present
|
|
; ioTotalFreeFCBs offset $26 word, output returns number of free FCBs
|
|
; ioFCBsAdded offset $2A, word, output returns number allocated this time
|
|
;
|
|
; Input:
|
|
; a0.l - pointer to PB
|
|
;
|
|
; Output:
|
|
; d0.w - #noErr if at least one FCB is free on exit.
|
|
; - #tmfoErr if no FCBs are free on exit
|
|
;
|
|
; AllocateFCBs always counts the total number of FCBs and the total number free. If there
|
|
; are ioFCBBurst FCBs free, no other work is performed. If there are fewer than ioFCBBurst
|
|
; FCBs free then AllocateFCBs will attempt to allocate enough new ones so that ioFCBGrow
|
|
; are free.
|
|
;
|
|
; ioFCBBurst and ioFCBGrow work together. ioFCBBurst is the number of opens that we'd
|
|
; like to be able to perform between visits to sync time. ioFCBGrow is the number that
|
|
; we'd like to have available when we go to the trouble of growing the array. ioFCBBurst
|
|
; must always be <= ioFCBGrow.
|
|
;
|
|
;_____________________________________________________________________________________
|
|
; This routine was copied FileMgrPatches.a <SM1>
|
|
AllocateFCBs
|
|
import MoreFCBs
|
|
|
|
bsr.s FSQueue ; Wait out turn
|
|
|
|
moveq.l #-1,d0 ; more FCBs than we'll ever have
|
|
bsr CountFCBs ; count all of them
|
|
move.w d0,ioTotalFreeFCBs(a0) ; remember how many are free
|
|
move.w d1,ioTotalFCBs(a0) ; remember how many there are
|
|
|
|
movea.l FSVarsPtr,a1
|
|
with FSVars
|
|
move.w ioFCBBurst(a0),d2 ; get the # we'd like to keep free
|
|
cmp.w d2,d0 ; see if we have that many free
|
|
bhs.s @noAllocate
|
|
|
|
move.w ioFCBGrow(a0),d2 ; d2 = the number of free FCBs we'd like to grow to
|
|
sub.w d0,d2 ; d2 = the number we need to grow to there
|
|
|
|
move.w fsFCBMax(a1),d3 ; d3 = the most FCBs we can have
|
|
sub.w d1,d3 ; d3 = the most we can grow
|
|
beq.s @noAllocate ; bail if we're out of array room
|
|
cmp.w d2,d3 ; can we grow as much as we want to?
|
|
bhs.s @grow ; if (most we can grow) >= (amount desired), we're OK
|
|
move.w d3,d2 ; otherwise, just grow as much as we can
|
|
|
|
@grow:
|
|
bsr MoreFCBs ; try to get the FCBs
|
|
beq.s @gotSome ; leave with a smile
|
|
|
|
asr.w #1,d2 ; try to get half that many
|
|
beq.s @noAllocate ; if we're down to zero, bail
|
|
bra.s @grow
|
|
|
|
@gotSome:
|
|
add.w d2,ioTotalFCBs(a0) ; update the total count
|
|
add.w d2,ioTotalFreeFCBs(a0) ; update the free count
|
|
move.w d2,ioFCBsAdded(a0) ; note the number added
|
|
bra.s @done
|
|
|
|
@noAllocate:
|
|
clr.w ioFCBsAdded(a0) ; we didn't add any new ones
|
|
|
|
@done:
|
|
tst.w ioTotalFreeFCBs(a0) ; check the number that are free now
|
|
beq.s @noFCBsAvailable ; if none are left, report the problem
|
|
moveq.l #noErr,d0 ; if some are left, we're happy
|
|
|
|
@exit: bra CmdDone ; And call it a day
|
|
|
|
@noFCBsAvailable:
|
|
moveq.l #tmfoErr,d0
|
|
bra.s @exit
|
|
endwith
|
|
|
|
;________________________________________________________________________________
|
|
; Routine: File System cleanup routine <2.7>
|
|
; Function: Closes all open files belong to the process upon process termination.
|
|
; The process serial number in the Ext. FCB is cleared.
|
|
;
|
|
; By: Kenny Tung
|
|
; Copyright © 1989 Apple Computer, Inc.
|
|
; Input: D1 = trap, A0 = parameter block pointer
|
|
; HFS call requires an ioPB, but in this call no parameter is passed in.
|
|
; However, A0 is used to make the PBClose call within the routine. (Therefore
|
|
; it should be at least 26 bytes long).
|
|
; Revision History:
|
|
; 26Sep89 KSCT New today (from TFSDir1.a)
|
|
;________________________________________________________________________________
|
|
DoFSCleanUp ; serial ID is 64 bits
|
|
FSCleanupRegs REG A2-A3/D2-D6
|
|
MOVEM.L FSCleanupRegs,-(SP)
|
|
|
|
; ask the Process Mgr which process is current
|
|
MOVE.L A0,-(SP) ; save needed, but volatile, register
|
|
LEA -10(SP),SP ; get current PSN and verify it's for us
|
|
PEA 2(SP) ; push address of PSN
|
|
_GetCurrentProcess ; call the OS
|
|
MOVE.W (SP)+,D0 ; save result
|
|
MOVE.L (SP)+,D6 ; D6 = process ID1
|
|
MOVE.L (SP)+,D2 ; D2 = process ID2
|
|
MOVEA.L (SP)+,A0 ; restore volatile register
|
|
TST.W D0 ; check result now that stack restored
|
|
BLT CleanupDone ; if so, we can do nothing
|
|
|
|
MOVEA.L FSVarsPtr,A1
|
|
MOVEa.L FSVars.fcbPBuf(A1),A2 ; A2=parallel array
|
|
MOVE cbPBufCount(A2),D3 ; D3=number of FCBs
|
|
SUBQ #1,D3 ; for DBcc
|
|
MOVE cbPBufULen(A2),D4 ; D4=ext. FCB unit size
|
|
LEA fcbPBufData(A2),A2 ; A2=ext. fcb array
|
|
MOVE FSFCBLen,D5 ; D5=FCB len
|
|
jsr Gt1stFCB ; A1=FCB, D1=1st RefNum
|
|
|
|
; First close all the open files belong to this process:
|
|
; A1=FCBptr, A2=Ext. FCBptr, D1.W=RefNum, D2=id2, D3.W=loop index,
|
|
; D4.W=ext FCBlen, D5.W=original FCBlen, D6=id1 (not D1!)
|
|
@cleanLoop MOVE.L xFCBPid2(A2),D0 ; do the 2nd one first
|
|
CMP.L D0,D2 ; FCB belongs to this process?
|
|
BNE.S @3 ; no->
|
|
MOVE.L xFCBPid1(A2),D0
|
|
CMP.L D0,D6 ; FCB belongs to this process?
|
|
BNE.S @3 ; no->
|
|
;; close the file only if it is open and not a system file.
|
|
MOVE.L fcbFlNm(A1,D1),D0 ; file open?
|
|
BEQ.S @2 ; not open -> invalidate PIDs
|
|
CMP.L #FSUsrCNID,D0 ; Is it a system control file?
|
|
BLO.S @2 ; yes, don't touch it
|
|
|
|
;; this open path belongs to this proc, let's close it
|
|
BSR clearPB ; clear iopb in A0
|
|
MOVE D1,ioRefNum(A0) ; close this access path
|
|
MOVEM.L A1/D1/D2,-(SP) ; these registers are trashed
|
|
_Close ,Async ; close the file ASYNCly (to avoid deadlock)
|
|
;; but we will wait synchronously until it's done .....
|
|
@wait TST ioResult(A0)
|
|
BGT.S @wait
|
|
MOVEM.L (SP)+,A1/D1/D2
|
|
BNE.S @3 ; if error don't clear IDs
|
|
@2 CLR.L xFCBPid1(A2) ; clear procID 1
|
|
CLR.L xFCBPid2(A2) ; clear procID 2
|
|
@3 ADDA D4,A2 ; go to next ext.FCB
|
|
ADD.W D5,D1 ; go to next FCB RefNum
|
|
DBF D3,@cleanLoop ; process them all É
|
|
|
|
;; Then close all the working direstories: D2.L/D6.L=procID, others are free
|
|
MOVEA.L FSVarsPtr,A1 ; FSVars
|
|
MOVEA.L FSVars.WDCBPBuf(A1),A2
|
|
MOVE cbPBufCount(A2),D3 ; D3=number of WDCBs
|
|
SUBQ #1,D3 ; for DBcc
|
|
MOVE cbPBufULen(A2),D4 ; D4=ext. WDCB unit size
|
|
LEA wdcbPBufData(A2),A2 ; A2=1st ext. WDCB array
|
|
MOVE #WDCBLen,D5 ; D5 = old WDCB len
|
|
jsr Gt1stWDCB ; A1=WDCB array, D1=WDRefNum
|
|
;; A1=WDCBptr, A2=Ext WDCB, D1.W=WD RefNum, D2=id2, D3.W=loop index,
|
|
;; D4.W=ext wdcblen, D5.W= orginal WDCBlen, D6=id1
|
|
@WDLoop MOVE.L xWDCBPid2(A2),D0
|
|
CMP.L D0,D2 ; same process?
|
|
BNE.S @6 ; no->
|
|
MOVE.L xWDCBPid1(A2),D0
|
|
CMP.L D0,D6 ; WDCB belongs to this process?
|
|
BNE.S @6 ; no->
|
|
TST.L WDVCBPtr(A1,D1) ; WD open?
|
|
BEQ.S @5 ; no-> already closed
|
|
|
|
BSR.S clearPB ; clear iopb
|
|
MOVEM.L A1/D1/D2,-(SP) ; these registers are trashed
|
|
ADD.W #WDRfnMin,D1 ; Offset the index to make a WDRefNum (-32767)
|
|
MOVE D1,ioVRefNum(A0) ; close this WD
|
|
_CloseWD
|
|
MOVEM.L (SP)+,A1/D1/D2
|
|
BNE.S @6 ; if error don't clear IDs
|
|
@5 CLR.L xWDCBPid1(A2) ; clear procID 1
|
|
CLR.L xWDCBPid2(A2) ; clear procID 2
|
|
@6 ADDA D4,A2 ; go to next ext.WDCB
|
|
ADD.W D5,D1 ; go to next WDCB RefNum
|
|
DBF D3,@WDLoop ; process them all É
|
|
|
|
BSR.S clearPB ; all done, return a clear PB
|
|
|
|
CleanupDone
|
|
MOVEM.L (SP)+,FSCleanupRegs
|
|
MOVEQ #0,D0 ; happy ending
|
|
RTS
|
|
|
|
|
|
; clear iopb in A0 up to ioRefnum. (28 bytes), A3 is free
|
|
clearPB MOVEA.L A0,A3 ; A3=A0=iopb
|
|
MOVEQ #(fscPBLen/4)-1,D0 ; iopb len in long -1
|
|
@2 CLR.L (A3)+
|
|
DBRA D0,@2 ; clear 28 bytes
|
|
RTS
|
|
|
|
; __________________________________________________________________________________
|
|
; InstallVectors
|
|
;
|
|
; Function:
|
|
; Attach ourselves to the appropriate vectors.
|
|
;
|
|
; For fsQueueHook, ExtFSHook and jFileOpen we selfishly insist that
|
|
; we're the first piece of code hooked in so that we can assume
|
|
; that we're the last one called.
|
|
;
|
|
; __________________________________________________________________________________
|
|
InstallVectors
|
|
|
|
; slam onto fsQueueHook, ExtFSHook and jFileOpen
|
|
Import fsQueueHookPatch,ExtFSHookPatch
|
|
|
|
Lea fsQueueHookPatch, a0 ; our patch address
|
|
move.l a0, fsQueueHook ; be the first ones
|
|
|
|
Lea ExtFSHookPatch, a0 ; our patch address <38>
|
|
move.l a0, ExtFSHook ; be the first ones <38>
|
|
|
|
; install some vectors:
|
|
move.l ExpandMem, a1
|
|
lea vSyncWait, a0 ; get addr of syncwait (in this fsQueueHook patch)
|
|
move.l a0, ExpandMemRec.jSyncWait(a1)
|
|
lea vAfterFSQHook, a0 ; get addr just past call to fsQueueHook (in fsQueueHook patch)
|
|
move.l a0, ExpandMemRec.jAfterFSQHook(a1)
|
|
|
|
lea CmdDone, a0 ; get addr of CmdDone
|
|
move.l a0, ExpandMemRec.jCmdDone(a1)
|
|
lea fsGeneralWakeUp, a0 ; get addr of general purpose File System kickstart
|
|
move.l a0, ExpandMemRec.jDispatchNext(a1)
|
|
|
|
lea fsSCSIFreeHookProc, a0 ; get addr of File System SCSI Busy deferral completion
|
|
move.l a0, ExpandMemRec.jSCSIFreeHook(a1)
|
|
|
|
rts
|
|
|
|
;__________________________________________________________________________________
|
|
;
|
|
; Initialize FCB expansion patch, WDCB expansions patch, and vectors
|
|
;__________________________________________________________________________________
|
|
; Roll into SuperMario <SM1> fm
|
|
FSGrowPatchInit:
|
|
; allocate the FCB parallel array
|
|
movea.L FCBSPtr,a1 ; a1 = address of main FCB array
|
|
moveq #0,d0 ; clear d0 for long calc
|
|
move.w (a1),d0 ; bytes in FCB array and header
|
|
divu.w FSFCBLen,d0 ; divide by element size to get count of FCBs
|
|
andi.l #$FFFF,d0 ; clear d0 top word set by divu
|
|
move.w d0,d1 ; Save # of FCBs in d1
|
|
lsl #L2ExtFCBLen,d0 ; d0 = total size of the parallel array
|
|
addq #fcbPBufData,d0 ; include info words
|
|
_NewPtr sys, clear ; Allocate buffer for FCBs
|
|
bne.s GrowErrExit ; Any errors are fatal
|
|
|
|
; initialize parallel FCB array header and install the array in FSVars
|
|
move.w d1,cbPBufCount(a0) ; first word = count
|
|
move.w #ExtFCBLen,cbPBufULen(a0) ; second word = unit size
|
|
movea.L FSVarsPtr,a1 ; save array address in FSVars
|
|
move.l a0,FSVars.FCBPBuf(a1) ; now we're ready to record file opens!
|
|
|
|
; allocate the WDCB parallel array
|
|
move.l WDCBSPtr,a1 ; a1 = address of main WDCB array
|
|
moveq #0,d0 ; clear d0 for long calc
|
|
move.w (a1),d0 ; length of WDCB array
|
|
divu.w #WDCBLen,d0 ; divide by element size to get count of WDCBs
|
|
andi.l #$FFFF,d0 ; clear d0 top word
|
|
move.w d0,d1 ; Save # of WDCBs in d1
|
|
lsl #L2ExtWDCBLen,d0 ; d0 = total size of the parallel array
|
|
addq #wdcbPBufData,d0 ; include info words
|
|
_NewPtr sys, clear ; Allocate buffer for FCBs
|
|
bne.s GrowErrExit ; Any errors are fatal
|
|
|
|
; initialize parallel WDCB array header and install the array in FSVars
|
|
move.w d1,cbPBufCount(a0) ; first word = count
|
|
move.w #ExtWDCBLen,cbPBufULen(a0) ; second word = unit size
|
|
movea.L FSVarsPtr,a1 ; save array address in FSVars
|
|
move.l a0,FSVars.WDCBPBuf(a1) ; now we're ready to record _OpenWDs!
|
|
|
|
; initialize FCB expansion mechanism <38>
|
|
movea.l FSVarsPtr,a1
|
|
move.w #fsDesiredFCBBurst,FSVars.fsFCBBurst(a1)
|
|
move.w #fsDesiredFCBFree,FSVars.fsFCBGrow(a1)
|
|
clr.w FSVars.fsFCBCounter(a1) ; make us check on the next open
|
|
move.w #$7fff,d0 ; max signed int is all we can have for the FCB array
|
|
ext.l d0 ; divide takes a long input
|
|
divs fsFCBLen,d0 ; d0 = max # of FCBs
|
|
move.w d0,FSVars.fsFCBMax(a1)
|
|
|
|
rts
|
|
GrowErrExit:
|
|
MOVEQ #dsMemFullErr,D0 ; no mem
|
|
_SysError
|
|
|
|
|
|
|
|
;________________________________________________________________________________
|
|
;
|
|
; Routine: GetVolParms
|
|
;
|
|
; Input: a0 - pointer to user's param block
|
|
; Output: d0 - result code
|
|
;
|
|
; Function: Return a version 2 GetVolParms param block
|
|
;
|
|
; Interesting problems with GetVolParms (which aren't important enough to cause
|
|
; us to make a change this close to 7.0 final. Obviously, if you're reading this
|
|
; after 7.0 final, please make these changes for the good of humanity. You should find
|
|
; these written up in the BRC).
|
|
; 2) The suba.w @VolParmsBufferSize,a6 instruction needs to be changed to a long subtract.
|
|
; What happens now is that zero is subtracted from a6, but the size of the saved registers
|
|
; happens to be bigger than the buffer, so there's enough room on the stack. Since the File
|
|
; Manager happens to save registers before dispatching, the fact that GetVolParms trashes
|
|
; the registers is unimportant. Thus, the three parallel changes are to get rid of the
|
|
; regster save/restore, change the suba.w to a suba.l, and add an adda.l at the bottom of
|
|
; the routine to deallocate the buffer.
|
|
;
|
|
;________________________________________________________________________________
|
|
; Roll in for SuperMario. Fix up the
|
|
GetVolParms:
|
|
@GetVolRegs reg d2/d3/a1-a4
|
|
|
|
; <SM1> FM bclr #asyncTrpBit, ioTrap(a0) ; force synchronous (wrong. See note, above)
|
|
jsr FSQueue ; Patiently wait our turn in line
|
|
; <SM1> FM movem.l @GetVolRegs, -(a6) ; save regs on FS stack
|
|
suba.l @VolParmsBufferSize, a6 ; <SM1> FM allocate a GetVolParms buffer on the stack
|
|
;
|
|
; Find the VCB in question:
|
|
;
|
|
jsr DtrmV3 ; find vol using ioNamePtr & ioVRefNum (D023/A234 trashed)
|
|
bne.s @GetVolParmsExit ; (DtrmV3 puts VCBPtr in A2)
|
|
|
|
tst.w vcbFSID(a2) ; Check: external file system? (¥¥ TFSVCBTst?)
|
|
beq.s @ForUs ; If zero, it's HFS.
|
|
;
|
|
; This call is for an External File System volume:
|
|
;
|
|
moveq #extFSErr, d0 ; Tell the world
|
|
bra.s @GetVolParmsExit ; and let them worry about it
|
|
;
|
|
; This call is for us. First, make a modifiable copy of the return buffer.
|
|
;
|
|
@ForUs:
|
|
movea.l a0, a4 ; move user's pb to a safe register
|
|
move.l @VolParmsBufferSize, d0 ; d0 = size of GetVolParms' ioBuffer
|
|
movea.l a6, a1 ; onto our stack buffer
|
|
lea.l @HFSVolParmsBuffer, a0 ; copy the static values for HFS volumes
|
|
cmp.w #SigWord,vcbSigWord(a2) ; is this an MFS volume?
|
|
bne.s @notMFS ; no, skip the following
|
|
lea.l @MFSVolParmsBuffer, a0 ; copy the static values for MFS volumes
|
|
@notMFS:
|
|
_BlockMove
|
|
|
|
bsr CheckDesktopSupport ; returns zero clear if support, set if none
|
|
beq.s @NoDTSupport ; z set means no support
|
|
|
|
move.l vmAttrib(a6), d0 ; get the attributes word
|
|
bset.l #bHasDesktopMgr, d0 ; set the bit indicating support
|
|
move.l d0, vmAttrib(a6) ; put the modified word back in the buffer
|
|
@noDTSupport:
|
|
|
|
;
|
|
; The buffer on the stack reflects the correct values for this volume.
|
|
; Copy back as much of it as the caller gave us room.
|
|
;
|
|
move.l ioReqCount(a4), d0 ; get user's buffer size
|
|
cmp.l @VolParmsBufferSize, d0 ; is it smaller than our buffer?
|
|
bls.s @NoClip ; then just return that amount
|
|
|
|
move.l @VolParmsBufferSize, d0 ; clip the return to just the size of our data
|
|
|
|
@noClip:
|
|
move.l d0, ioActCount(a4) ; tell'em how much we're copying
|
|
move.l a6, a0 ; copy from our stack buffer
|
|
move.l ioBuffer(a4), a1 ; copy into the user's pb buffer
|
|
_BlockMove
|
|
|
|
@GetVolParmsExit:
|
|
adda.l @VolParmsBufferSize, a6 ; <SM1> FM deallocate a GetVolParms buffer on the stack
|
|
;<SM1> fm movem.l (a6)+, @GetVolRegs ; restore regs
|
|
jmp CmdDone ; Go home
|
|
|
|
; This buffer contains the appropriate values for local HFS volumes.
|
|
@HFSVolParmsBuffer:
|
|
dc.w 2 ; this is a version 2 getvolparms
|
|
dc.l localvMAttribs ; static set of local attribute bits
|
|
dc.l 0 ; no local window handle
|
|
dc.l 0 ; no server address
|
|
dc.l localVolGrade ; standard volume grade
|
|
dc.w 0 ; local volumes don't support alt priv models
|
|
@VolParmsBufferSize:
|
|
dc.l *-@HFSVolParmsBuffer
|
|
|
|
; This buffer contains the appropriate values for local MFS volumes.
|
|
@MFSVolParmsBuffer:
|
|
dc.w 2 ; this is a version 2 getvolparms
|
|
dc.l 0 ; no optional calls supported for MFS volumes
|
|
dc.l 0 ; no local window handle
|
|
dc.l 0 ; no server address
|
|
dc.l localVolGrade ; standard volume grade
|
|
dc.w 0 ; local volumes don't support alt priv models
|
|
|
|
|
|
; .NoList
|
|
INCLUDE 'TFSCommon.a' ; Common subroutines w. TFSUtil
|
|
INCLUDE 'TFSVol.a' ; TFS volume level routines
|
|
INCLUDE 'MFSVol.a' ; MFS-specific volume level stuff
|
|
INCLUDE 'TFSDir1.a' ; include routines using filenames
|
|
INCLUDE 'MFSDir1.a' ;
|
|
INCLUDE 'TFSDir2.a' ;
|
|
INCLUDE 'MFSDir2.a' ;
|
|
INCLUDE 'TFSDir3.a' ;
|
|
INCLUDE 'MFSDir3.a' ;
|
|
|
|
INCLUDE 'TFSRfN1.a' ; include routines using refnums
|
|
INCLUDE 'MFSRfN1.a' ;
|
|
INCLUDE 'TFSRfN2.a' ;
|
|
INCLUDE 'MFSRfN2.a' ;
|
|
INCLUDE 'TFSRfN3.a' ;
|
|
INCLUDE 'MFSRfN3.a' ;
|
|
|
|
******************************************************************************************
|
|
* some lucky person gets to roll the following file into the rest of the sources
|
|
|
|
INCLUDE 'FileMgrHooks.a'
|
|
|
|
******************************************************************************************
|
|
|
|
|
|
END
|
|
|
|
|
|
|
|
|
|
|