(FILECREATED "12-Jun-85 13:17:10" {ERIS}<LISPCORE>SOURCES>LFPILOTFILE.;10 55128  

      changes to:  (FNS DISPLAYWORDS \PFTransferPage \PFTransferPageNoSwap \PFCreateVols 
			\PFFindPageAddr \PFFetchString \PFReplaceString \PFNewPages \PFTrimHelper 
			\PFCurrentVol)
		   (VARS LFPILOTFILECOMS PILOTFILECOMPILECOMS)
		   (RESOURCES label)
		   (RECORDS DLDISK.STATUS)

      previous date: "15-May-85 11:59:29" {ERIS}<LISPCORE>SOURCES>LFPILOTFILE.;9)


(* Copyright (c) 1985 by Xerox Corporation. All rights reserved.)

(PRETTYCOMPRINT LFPILOTFILECOMS)

(RPAQQ LFPILOTFILECOMS [(COMS (FNS \PFFetchString \PFReplaceString)
			      (DECLARE: EVAL@COMPILE DONTCOPY (COMS * PILOTFILECOMPILECOMS))
			      (DECLARE: (LOCALVARS . T)
					(IGNOREDECL . T))
			      (INITRECORDS PageGroup FileDescriptor))
			(COMS (* Load pilot file system modules)
			      (FILES LFFILEMAP LFALLOCATIONMAP)
			      (* Load other file system modules)
			      (FILES DSKDISPLAY))
			[COMS (* * These functions transfer pages to and from the disk)
			      (FNS \PFGetPhysicalVolumePage)
			      (FNS \PFGetLogicalVolumePage \PFPutLogicalVolumePage)
			      (FNS \PFGetMarkerPage \PFPutMarkerPage)
			      (FNS \PFCreateFreePage)
			      (FNS \PFGetAllocationMapPage \PFPutAllocationMapPage)
			      (FNS \PFGetFileMapPage \PFPutFileMapPage)
			      (FNS \PFGetPage \PFPutPage \PFCreatePage)
			      (FNS \PFTransferFilePage)
			      (FNS \PFTransferPage \PFTransferPageNoSwap)
			      (RESOURCES label \PFio)
			      (DECLARE: DONTEVAL@LOAD (P (\LOCKFN (QUOTE \PFTransferPage))
							 (\LOCKFN (QUOTE \PFTransferPageNoSwap]
			[COMS (* * File Descriptor pool for system files)
			      (FNS \PFCreateFileDescriptors \PFInitFileDescriptors)
			      (GLOBALVARS \PFLogicalVolumeFileD \PFMarkerFileD \PFFreeFileD 
					  \PFAllocationMapFileD \PFFileMapFileD)
			      (DECLARE: DONTEVAL@LOAD DOCOPY (P (\PFCreateFileDescriptors]
			[COMS (* * Physical volume interface)
			      (FNS \PFCreatePhysicalVolume)
			      (GLOBALVARS \PhysVolumePage)
			      (DECLARE: DONTEVAL@LOAD DOCOPY (P (\PFCreatePhysicalVolume]
			(COMS (* * Interface to logical volumes,)
			      (FNS \PFCreateVols \PFInitializeVols \PFGetVols \PFGetVol 
				   \PFVolumeNumber)
			      (GLOBALVARS \DFSLogicalVolumes \DFSLogicalVolumeHash)
			      (DECLARE: DONTEVAL@LOAD DOCOPY (P (\PFCreateVols)))
			      (FNS \PFGetLVPage))
			(COMS (* * Pilot integrity)
			      (FNS \PFVersionOK \PFPilotVolumeP))
			[COMS (* * Pilot initialization)
			      (FNS \PFEnsureInitialized)
			      (GLOBALVARS \PFInitialized)
			      (INITVARS (\PFInitialized NIL))
			      (ADDVARS (\SYSTEMCACHEVARS \PFInitialized))
			      (DECLARE: DONTEVAL@LOAD DOCOPY (P (\PFEnsureInitialized]
			(COMS (* * Root directory management)
			      (FNS \PFFindDirectoryID \PFInsertDirectoryID \PFRemoveDirectoryID)
			      (FNS \PFFindRootDirEntry \PFFindRootDirEntryNum \PFAddRootDirEntry 
				   \PFRemoveRootDirEntry)
			      (FNS \PFGetRootDirectory \PFPutRootDirectory \PFCreateRootDirectory 
				   \PFPurgeRootDirectory)
			      (FNS \GetRootDirectoryType \PFPutRootDirectoryType))
			(COMS (* * Pilot file management)
			      (FNS \PFNewPages \PFTrimHelper \PFFindPageAddr \PFFindFileSize 
				   \PFFreeDiskPages \PFSaveBuffers))
			(COMS (* * Lisp vmem)
			      (FNS \PFCurrentVol \PFVMemFileID \PFVMemFileSize \PFExtendVMem))
			(COMS (* * Display stub; real volume display stuff is implemented on a 
				 library package called DSKDISPLAY)
			      (P (MOVD? (QUOTE NILL)
					(QUOTE \PFDsplyVolumes])
(DEFINEQ

(\PFFetchString
  [DLAMBDA (startLoc lengthLoc
            (maxLength SMALLP)
            (RETURNS STRINGP))
                                                             (* bvm: "12-Jun-85 12:36")

          (* * Returns a string containing (@ lengthLoc) characters read starting from startLoc)


    (\GETBASESTRING startLoc 0 (IMIN (\GETBASE lengthLoc 0)
				     maxLength))])

(\PFReplaceString
  [DLAMBDA (startLoc lengthLoc
            (maxLength SMALLP)
            (newString (ONEOF STRINGP ATOM))
            (RETURNS STRINGP))
                                                             (* bvm: "12-Jun-85 12:43")

          (* * Writes out newString beginning at startLoc, and indicates the length in the word beginning at lengthLoc.)


    (LET ((STR newString)
       (LENGTH (NCHARS newString)))
      (COND
	((GREATERP LENGTH maxLength)
	  (SETQ STR (SUBSTRING STR 1 maxLength))
	  (SETQ LENGTH maxLength)))
      (\PUTBASESTRING startLoc 0 STR)
      (\PUTBASE lengthLoc 0 LENGTH))
    newString])
)
(DECLARE: EVAL@COMPILE DONTCOPY 

(RPAQQ PILOTFILECOMPILECOMS ((* * Assorted system constants)
			     (CONSTANTS (pilotVersion 8)
					(pilotVolume 0)
					(nonPilotVolume 3))
			     (CONSTANTS (maxPagesPerFile 8388607)
					(lastPageNumber (SUB1 maxPagesPerFile))
					(nullVolumePage 0)
					(maxLogicalVolumes 10))
			     (CONSTANTS (hardMicrocode 0))
			     (* * File types. Interlisp has been assigned the file types in the 
				closed-open interval 10048..10078 (see AR 3112))
			     (CONSTANTS (tUnassigned 0)
					(tPhysicalVolumeRootPage 1)
					(tSubVolumeMarkerPage 4)
					(tLogicalVolumeRootPage 5)
					(tFreePage 6)
					(tVolumeAllocationMap 7)
					(tVolumeFileMap 8)
					(tRootDirectory 18)
					(tLispDirectory 10048)
					(tLispFile 10049)
					(tDiagnosticMicrocode 65535))
			     (* * Logical volume page, physical volume page, and marker page types)
			     (FILES MESATYPES)
			     (CONSTANTS (logicalVolumeSeal 45771))
			     (RECORDS Page RandomPage FileID VolumeID DiskFileID LVBootFiles 
				      RootFileArray LogicalVolumeDescriptor)
			     (CONSTANTS (physicalVolumeSeal 41610))
			     (RECORDS PVBootFiles SubVolumeDesc SubVolumeArray 
				      PhysicalVolumeDescriptor)
			     (RECORDS LogicalSubVolumeMarker SubVolumeMarkerPage)
			     (MACROS FetchAtom ReplaceAtom)
			     (MACROS LVEqual SwapIn&Dirty LvBasePageAddr MarkerPageAddr)
			     (* * Root directory stuff)
			     (CONSTANTS (rootDirSeal 30167)
					(rootDirVersion 2)
					(rootDirMaxEntries 84))
			     (RECORDS RootDirEntry RootDirEntryArray RootDirectory)
			     (* * Miscellaneous records)
			     (RECORDS PageGroup FileDescriptor)
			     (RECORDS Label)
			     (RECORDS \PFDiskIO)
			     (* * The following are for diagnostic purposes.)
			     (FNS DISPLAYWORDS DISPLAYLABEL DISPLAYPAGE)
			     (FILES (LOADCOMP)
				    DISKDLION)
			     (* Get DLDISK.STATUS record for \PFTransferPage)))
(* * Assorted system constants)

(DECLARE: EVAL@COMPILE 

(RPAQQ pilotVersion 8)

(RPAQQ pilotVolume 0)

(RPAQQ nonPilotVolume 3)

(CONSTANTS (pilotVersion 8)
	   (pilotVolume 0)
	   (nonPilotVolume 3))
)
(DECLARE: EVAL@COMPILE 

(RPAQQ maxPagesPerFile 8388607)

(RPAQ lastPageNumber (SUB1 maxPagesPerFile))

(RPAQQ nullVolumePage 0)

(RPAQQ maxLogicalVolumes 10)

(CONSTANTS (maxPagesPerFile 8388607)
	   (lastPageNumber (SUB1 maxPagesPerFile))
	   (nullVolumePage 0)
	   (maxLogicalVolumes 10))
)
(DECLARE: EVAL@COMPILE 

(RPAQQ hardMicrocode 0)

(CONSTANTS (hardMicrocode 0))
)
(* * File types. Interlisp has been assigned the file types in the closed-open interval 
10048..10078 (see AR 3112))

(DECLARE: EVAL@COMPILE 

(RPAQQ tUnassigned 0)

(RPAQQ tPhysicalVolumeRootPage 1)

(RPAQQ tSubVolumeMarkerPage 4)

(RPAQQ tLogicalVolumeRootPage 5)

(RPAQQ tFreePage 6)

(RPAQQ tVolumeAllocationMap 7)

(RPAQQ tVolumeFileMap 8)

(RPAQQ tRootDirectory 18)

(RPAQQ tLispDirectory 10048)

(RPAQQ tLispFile 10049)

(RPAQQ tDiagnosticMicrocode 65535)

(CONSTANTS (tUnassigned 0)
	   (tPhysicalVolumeRootPage 1)
	   (tSubVolumeMarkerPage 4)
	   (tLogicalVolumeRootPage 5)
	   (tFreePage 6)
	   (tVolumeAllocationMap 7)
	   (tVolumeFileMap 8)
	   (tRootDirectory 18)
	   (tLispDirectory 10048)
	   (tLispFile 10049)
	   (tDiagnosticMicrocode 65535))
)
(* * Logical volume page, physical volume page, and marker page types)

(FILESLOAD MESATYPES)
(DECLARE: EVAL@COMPILE 

(RPAQQ logicalVolumeSeal 45771)

(CONSTANTS (logicalVolumeSeal 45771))
)
[DECLARE: EVAL@COMPILE 

(RECORD Page NIL (CREATE (NCREATE (QUOTE VMEMPAGEP)))
		 (TYPE? (TYPENAMEP DATUM (QUOTE VMEMPAGEP))))

(RECORD RandomPage NIL (TYPE? (EQ (fetch (POINTER WORDINPAGE) of DATUM)
				  0)))

(MESATYPE FileID (2 WORD))

(MESATYPE VolumeID (5 WORD))

(MESARECORD DiskFileID ((fID SWAPPEDFIXP)
			(NIL 3 WORD)
			(firstPage SWAPPEDFIXP)
			(da SWAPPEDFIXP))                    (* Booting information)
		       )

(MESAARRAY LVBootFiles ((0 5))
		       DiskFileID                            (* Booting information)
		       )

(MESAARRAY RootFileArray ((6 14))
			 FileID)

(MESARECORD LogicalVolumeDescriptor ((seal WORD)             (* Validation ; absolutely must be first field)
				     (version WORD)          (* must be 2nd field)
				     (vID VolumeID)          (* ID of This Volume)
				     (labelLength WORD)      (* Length of th ASCII name of this volume)
				     (label 40 BYTE)         (* Volume name in AScII)
				     (type WORD)
				     (volumeSize SWAPPEDFIXP)
                                                             (* Number of pages in this volume)
				     (bootingInfo LVBootFiles)
                                                             (* Defines 6 PILOT file types)
				     (NIL WORD)
				     (NIL BITS 15)
				     (changing FLAG)         (* Change field decls from here on only)
                                                             (* boolean ← T)
				     (freePageCount SWAPPEDFIXP)
                                                             (* Number of free pages remaining)
				     (vamStart SWAPPEDFIXP)
				     (vfmStart SWAPPEDFIXP)
                                                             (* Relative address of the start of the volume file 
							     map)
				     (lowerBound SWAPPEDFIXP)
				     (volumeRootDirectory SWAPPEDFIXP)
				     (rootFileID RootFileArray)
				     (lastIDAllocated SWAPPEDFIXP)

          (* Highest numbered File.ID given out on this volume. We reserve the first set of IDs for Pilot's own use.
	  In particular, files of type IN PilotRootFileType may have their ID the same as their File.Type.)


				     (scavengerLogVolume VolumeID)
				     (lastTimeOpendForWrite SWAPPEDFIXP)
				     (NIL 131 WORD)
				     (checksum WORD)         (* Must be the last field)
				     )
				    (ACCESSFNS (LVlabel (\PFFetchString (LOCF (fetch (
LogicalVolumeDescriptor label) of DATUM))
									(LOCF (fetch (
LogicalVolumeDescriptor labelLength) of DATUM))
									40)
							(\PFReplaceString (LOCF (fetch (
LogicalVolumeDescriptor label) of DATUM))
									  (LOCF (fetch (
LogicalVolumeDescriptor labelLength) of DATUM))
									  40 NEWVALUE)))
				    (CREATE (PROG ((lv (create Page)))
					          (replace (LogicalVolumeDescriptor seal)
						     of lv with logicalVolumeSeal)
					          (RETURN lv)))
				    (TYPE? (AND (type? Page DATUM)
						(EQ (fetch (LogicalVolumeDescriptor seal)
						       of DATUM)
						    logicalVolumeSeal))))
]
(DECLARE: EVAL@COMPILE 

(RPAQQ physicalVolumeSeal 41610)

(CONSTANTS (physicalVolumeSeal 41610))
)
[DECLARE: EVAL@COMPILE 

(MESAARRAY PVBootFiles ((0 3))
		       DiskFileID)

(MESARECORD SubVolumeDesc ((lvID VolumeID)
			   (lvSize SWAPPEDFIXP)
			   (lvPage SWAPPEDFIXP)
			   (pvPage SWAPPEDFIXP)
			   (nPages SWAPPEDFIXP)))

(MESAARRAY SubVolumeArray ((0 9))
			  SubVolumeDesc)

(MESARECORD PhysicalVolumeDescriptor ((seal WORD)            (* Validation)
				      (version WORD)
				      (labelLength WORD)
				      (pvID VolumeID)
				      (bootingInfo PVBootFiles)
                                                             (* Defines 4 PILOT file types)
				      (label 40 BYTE)        (* Ascii name of the volume)
				      (subVolumeCount WORD)
				      (subVolumeMarkerID VolumeID)
                                                             (* Marker pages belong to this Pseudo File)
				      (badPageCount SWAPPEDFIXP)
				      (maxBadPages SWAPPEDFIXP)
				      (onLineCount WORD)
				      (subVolumes SubVolumeArray)
                                                             (* See SubVolumeDesc record for description of each of 
							     six entries stored here)
				      (NIL 47 WORD)
				      (localTimeParametersValid WORD)
				      (localTimeParameters 2 WORD)
				      (checksum WORD))
				     (ACCESSFNS (PVlabel (\PFFetchString (LOCF (fetch (
PhysicalVolumeDescriptor label) of DATUM))
									 (LOCF (fetch (
PhysicalVolumeDescriptor labelLength) of DATUM))
									 40)
							 (\PFReplaceString
							   (LOCF (fetch (PhysicalVolumeDescriptor
									  label)
								    of DATUM))
							   (LOCF (fetch (PhysicalVolumeDescriptor
									  labelLength)
								    of DATUM))
							   40 NEWVALUE)))
				     (CREATE (PROG ((physicalVol (create Page)))
					           (replace (PhysicalVolumeDescriptor seal)
						      of physicalVol with physicalVolumeSeal)
					           (RETURN physicalVol)))
				     (TYPE? (AND (type? Page DATUM)
						 (EQ (fetch (PhysicalVolumeDescriptor seal)
							of DATUM)
						     physicalVolumeSeal))))
]
[DECLARE: EVAL@COMPILE 

(MESARECORD LogicalSubVolumeMarker ((seal WORD)
				    (version WORD)
				    (labelLength BITS 6)
				    (type BITS 2)
				    (NIL BITS 8)
				    (label 20 WORD)
				    (bootingInfo LVBootFiles)
				    (volumeRootDirectory SWAPPEDFIXP)))

(MESARECORD SubVolumeMarkerPage ((logical LogicalSubVolumeMarker)
                                                             (* Incomplete)
				 )
				(CREATE (create Page))
				(TYPE? (type? Page DATUM)))
]
(DECLARE: EVAL@COMPILE 
[PUTPROPS FetchAtom MACRO ((start length)
	   (U-CASE (PACKC (for pos from 0 to (SUB1 (\GETBASE length 0))
			       collect
			       (\GETBASEBYTE start pos]
(PUTPROPS ReplaceAtom MACRO [LAMBDA (startLoc lengthLoc maxLength newAtom)
				    (PROG ((chars (CHCON (MKATOM newAtom)))
					   length)
					  (SETQ length (MIN (LENGTH chars)
							    maxLength))
					  (* * Output characters)
					  (for char in chars as pos from 0 to (SUB1 length)
					       do
					       (\PUTBASEBYTE startLoc pos char))
					  (* * Output length of atom)
					  (\PUTBASE lengthLoc 0 length))
				    newAtom])
)
(DECLARE: EVAL@COMPILE 
(PUTPROPS LVEqual MACRO ((a b)
	   (MESAEQUAL (fetch (LogicalVolumeDescriptor vID)
			     of a)
		      (fetch (LogicalVolumeDescriptor vID)
			     of b)
		      VolumeID)))
[PUTPROPS SwapIn&Dirty MACRO (OPENLAMBDA (page)
					 (\PUTBASE page 0 (\GETBASE page 0]
[PUTPROPS LvBasePageAddr MACRO ((vol)
	   (fetch (SubVolumeDesc pvPage)
		  of
		  (FMESAELT (fetch (PhysicalVolumeDescriptor subVolumes)
				   of \PhysVolumePage)
			    SubVolumeArray vol]
[PUTPROPS MarkerPageAddr MACRO ((vol)
	   (fetch (SubVolumeDesc nPages)
		  of
		  (FMESAELT (fetch (PhysicalVolumeDescriptor subVolumes)
				   of \PhysVolumePage)
			    SubVolumeArray
			    (OR (FIXP vol)
				(\PFVolumeNumber vol]
)
(* * Root directory stuff)

(DECLARE: EVAL@COMPILE 

(RPAQQ rootDirSeal 30167)

(RPAQQ rootDirVersion 2)

(RPAQQ rootDirMaxEntries 84)

(CONSTANTS (rootDirSeal 30167)
	   (rootDirVersion 2)
	   (rootDirMaxEntries 84))
)
[DECLARE: EVAL@COMPILE 

(MESARECORD RootDirEntry ((type WORD)
			  (file SWAPPEDFIXP)))

(MESAARRAY RootDirEntryArray ((0 rootDirMaxEntries))
			     RootDirEntry)

(MESARECORD RootDirectory ((seal WORD)
			   (version WORD)
			   (maxEntries WORD)
			   (countEntries WORD)
			   (entries RootDirEntryArray))
			  (CREATE (PROG ((rootDir (create Page)))
				        (replace (RootDirectory seal) of rootDir with rootDirSeal)
				        (replace (RootDirectory version) of rootDir with 
										   rootDirVersion)
				        (replace (RootDirectory maxEntries) of rootDir with 
										rootDirMaxEntries)
				        (RETURN rootDir)))
			  (TYPE? (AND (type? Page DATUM)
				      (EQ (fetch (RootDirectory seal) of DATUM)
					  rootDirSeal))))
]
(* * Miscellaneous records)

[DECLARE: EVAL@COMPILE 

(DATATYPE PageGroup ((filePage SWAPPEDFIXP)
		     (volumePage SWAPPEDFIXP)
		     (nextFilePage SWAPPEDFIXP)))

(DATATYPE FileDescriptor (fileID                             (* Can be either a FIXP or a pointer to a VolumeID)
				 (volNum FIXP)               (* 0..9)
				 (type WORD)                 (* Pilot file type)
				 (size FIXP)                 (* Current number of (Pilot) pages allocated to this 
							     file)
				 (PAGEGROUP POINTER)         (* Caches the last PageGroup found for this file)
				 ))
]
(/DECLAREDATATYPE (QUOTE PageGroup)
		  (QUOTE (SWAPPEDFIXP SWAPPEDFIXP SWAPPEDFIXP))
		  (QUOTE ((PageGroup 0 SWAPPEDFIXP)
			  (PageGroup 2 SWAPPEDFIXP)
			  (PageGroup 4 SWAPPEDFIXP)))
		  (QUOTE 6))
(/DECLAREDATATYPE (QUOTE FileDescriptor)
		  (QUOTE (POINTER FIXP WORD FIXP POINTER))
		  (QUOTE ((FileDescriptor 0 POINTER)
			  (FileDescriptor 2 FIXP)
			  (FileDescriptor 4 (BITS . 15))
			  (FileDescriptor 5 FIXP)
			  (FileDescriptor 8 POINTER)))
		  (QUOTE 10))
[DECLARE: EVAL@COMPILE 

(MESARECORD Label ((fileID SWAPPEDFIXP)                      (* valid in label of every page)
		   (NIL 3 WORD)
		   (filePageLo WORD)
		   (filePageHi BITS 7)                       (* 23 bit page number, valid in label of every page)
                                                             (* always zero)
		   (pageZeroAttributes BITS 9)               (* valid only in label of page 0)
		   (attributesInAllPages WORD)               (* valid in label of every page)
		   (dontCare 2 WORD))
		  (ACCESSFNS (filePage (\MAKENUMBER (fetch (Label filePageHi) of DATUM)
						    (fetch (Label filePageLo) of DATUM))
				       (PROGN (replace (Label filePageHi) of DATUM
						 with (\HINUM NEWVALUE))
					      (replace (Label filePageLo) of DATUM
						 with (\LONUM NEWVALUE))
					      NEWVALUE)))
		  [TYPE? (OR (type? ARRAYBLOCK DATUM)
			     (AND (GETD (QUOTE \BLOCKDATAP))
				  (\BLOCKDATAP DATUM])
]
[DECLARE: EVAL@COMPILE 

(MESARECORD \PFDiskIO ((absoluteDiskAddress FIXP)
		       (buffer POINTER)
		       (mode POINTER)))
]
(* * The following are for diagnostic purposes.)

(DEFINEQ

(DISPLAYWORDS
  [LAMBDA (Start Number)                                     (* bvm: "12-Jun-85 12:24")
    [for I from 0 to (SUB1 Number)
       do (PRIN1 (\GETBASE Start I))
	  (PRIN1 " ")
	  (COND
	    ((EQ (IREMAINDER (ADD1 I)
			     7)
		 0)
	      (TERPRI]
    (TERPRI])

(DISPLAYLABEL
  [LAMBDA (vol volumePageNumber)                             (* hts: " 5-Jan-85 16:14")

          (* * comment)


    (PROG ((L (create Label)))
          (if (type? LogicalVolumeDescriptor vol)
	      then (SETQ vol (\PFVolumeNumber vol)))
          (\PFTransferPage (IPLUS (LvBasePageAddr vol)
				  volumePageNumber)
			   (create Page)
			   (QUOTE VRR)
			   L)
          (DISPLAYWORDS L 10])

(DISPLAYPAGE
  [LAMBDA (vol volumePageNumber)                             (* hts: " 5-Jan-85 16:14")
    (PROG ((P (create Page)))
          (if (type? LogicalVolumeDescriptor vol)
	      then (SETQ vol (\PFVolumeNumber vol)))
          (\PFTransferPage (IPLUS (LvBasePageAddr vol)
				  volumePageNumber)
			   P
			   (QUOTE VRR)
			   (create Label))
          (DISPLAYWORDS P WORDSPERPAGE])
)
(FILESLOAD (LOADCOMP)
	   DISKDLION)



(* Get DLDISK.STATUS record for \PFTransferPage)

)
(DECLARE: 
(DECLARE: DOEVAL@COMPILE DONTCOPY

(LOCALVARS . T)
)

(DECLARE: DOEVAL@COMPILE DONTEVAL@LOAD DONTCOPY 
(RESETSAVE COMPILEIGNOREDECL (QUOTE T))
)
)
(/DECLAREDATATYPE (QUOTE PageGroup)
		  (QUOTE (SWAPPEDFIXP SWAPPEDFIXP SWAPPEDFIXP))
		  (QUOTE ((PageGroup 0 SWAPPEDFIXP)
			  (PageGroup 2 SWAPPEDFIXP)
			  (PageGroup 4 SWAPPEDFIXP)))
		  (QUOTE 6))
(/DECLAREDATATYPE (QUOTE FileDescriptor)
		  (QUOTE (POINTER FIXP WORD FIXP POINTER))
		  (QUOTE ((FileDescriptor 0 POINTER)
			  (FileDescriptor 2 FIXP)
			  (FileDescriptor 4 (BITS . 15))
			  (FileDescriptor 5 FIXP)
			  (FileDescriptor 8 POINTER)))
		  (QUOTE 10))



(* Load pilot file system modules)

(FILESLOAD LFFILEMAP LFALLOCATIONMAP)



(* Load other file system modules)

(FILESLOAD DSKDISPLAY)
(* * These functions transfer pages to and from the disk)

(DEFINEQ

(\PFGetPhysicalVolumePage
  [LAMBDA (buffer)                                           (* hts: " 5-Jan-85 16:14")
    (\PFTransferPage 0 buffer (QUOTE VRR)
		     (create Label])
)
(DEFINEQ

(\PFGetLogicalVolumePage
  [LAMBDA (vol frame)                                        (* hts: "28-Nov-84 16:41")

          (* * comment)


    (\PFGetPage (ELT \PFLogicalVolumeFileD (OR (FIXP vol)
					       (\PFVolumeNumber vol)))
		0 0 frame])

(\PFPutLogicalVolumePage
  [LAMBDA (vol frame)                                        (* hts: "28-Nov-84 16:41")

          (* * comment)


    (\PFPutPage (ELT \PFLogicalVolumeFileD (OR (FIXP vol)
					       (\PFVolumeNumber vol)))
		0 0 frame])
)
(DEFINEQ

(\PFGetMarkerPage
  [LAMBDA (vol frame)                                        (* hts: "29-Nov-84 12:26")

          (* * comment)


    (OR (FIXP vol)
	(SETQ vol (\PFVolumeNumber vol)))
    (\PFGetPage (ELT \PFMarkerFileD vol)
		(IPLUS (LvBasePageAddr vol)
		       (MarkerPageAddr vol))
		(MarkerPageAddr vol)
		frame])

(\PFPutMarkerPage
  [LAMBDA (vol frame)                                        (* hts: "29-Nov-84 12:27")

          (* * comment)


    (OR (FIXP vol)
	(SETQ vol (\PFVolumeNumber vol)))
    (\PFPutPage (ELT \PFMarkerFileD vol)
		(IPLUS (LvBasePageAddr vol)
		       (MarkerPageAddr vol))
		(MarkerPageAddr vol)
		frame])
)
(DEFINEQ

(\PFCreateFreePage
  [LAMBDA (vol volumePageNumber frame)                       (* hts: "30-Nov-84 18:42")

          (* * comment)


    (\PFCreatePage (ELT \PFFreeFileD (OR (FIXP vol)
					 (\PFVolumeNumber vol)))
		   volumePageNumber volumePageNumber frame])
)
(DEFINEQ

(\PFGetAllocationMapPage
  [LAMBDA (vol volumePageNumber frame)                       (* hts: "29-Nov-84 12:39")

          (* * comment)


    (\PFGetPage (ELT \PFAllocationMapFileD (OR (FIXP vol)
					       (\PFVolumeNumber vol)))
		volumePageNumber volumePageNumber frame])

(\PFPutAllocationMapPage
  [LAMBDA (vol volumePageNumber frame)                       (* hts: "29-Nov-84 12:29")

          (* * comment)


    (OR (FIXP vol)
	(SETQ vol (\PFVolumeNumber vol)))
    (\PFPutPage (ELT \PFAllocationMapFileD vol)
		volumePageNumber volumePageNumber frame])
)
(DEFINEQ

(\PFGetFileMapPage
  [LAMBDA (vol volumePageNumber frame)                       (* hts: "29-Nov-84 12:32")

          (* * comment)


    (OR (FIXP vol)
	(SETQ vol (\PFVolumeNumber vol)))
    (\PFGetPage (ELT \PFFileMapFileD vol)
		volumePageNumber volumePageNumber frame])

(\PFPutFileMapPage
  [LAMBDA (vol volumePageNumber frame)                       (* hts: "29-Nov-84 12:32")

          (* * comment)


    (OR (FIXP vol)
	(SETQ vol (\PFVolumeNumber vol)))
    (\PFPutPage (ELT \PFFileMapFileD vol)
		volumePageNumber volumePageNumber frame])
)
(DEFINEQ

(\PFGetPage
  [LAMBDA (file filePageNumber volumePageNumber frame)       (* hts: "28-Nov-84 15:10")

          (* * file: FileDescriptor, filePageNumber: FIXP, volumePageNumber: FIXP, frame: Page)



          (* * Reads a page from the disk into frame)


    (\PFTransferFilePage file filePageNumber volumePageNumber frame (QUOTE VVR])

(\PFPutPage
  [LAMBDA (file filePageNumber volumePageNumber frame)       (* hts: "28-Nov-84 15:10")

          (* * file: FileDescriptor, filePageNumber: FIXP, volumePageNumber: FIXP, frame: Page)



          (* * Writes the page in frame onto the disk and checks the label of the disk page)


    (\PFTransferFilePage file filePageNumber volumePageNumber frame (QUOTE VVW])

(\PFCreatePage
  [LAMBDA (file filePageNumber volumePageNumber frame)       (* hts: "28-Nov-84 15:10")

          (* * file: FileDescriptor, filePageNumber: FIXP, volumePageNumber: FIXP, frame: Page)



          (* * Writes the page in frame onto the disk and writes a new label for it)


    (\PFTransferFilePage file filePageNumber volumePageNumber frame (QUOTE VWW])
)
(DEFINEQ

(\PFTransferFilePage
  [LAMBDA (file filePageNumber volumePageNumber frame operation)
                                                             (* hts: " 5-Jan-85 16:14")

          (* * file: FileDescriptor, filePageNumber: FIXP, volumePageNumber: FIXP, frame: Page, operation: 
	  (VVR VVW VWW))



          (* * Transfers a page to or from the disk as necessary.)


    (WITH-RESOURCE label 

          (* * Build label)


		   (if (FIXP (fetch (FileDescriptor fileID) of file))
		       then (replace (Label fileID) of label with (fetch (FileDescriptor fileID)
								     of file))
		     else 

          (* * Logical volume pages, marker pages, and physical volume pages have a 5-word volume ID for their fileID in a 
	  label. This is essentially a loophole to get around the normal declaration of the Label datatype, which expects a 
	  2-word ID)


			  (MESASETQ label (fetch (FileDescriptor fileID) of file)
				    VolumeID))
		   (replace (Label attributesInAllPages) of label with (fetch (FileDescriptor type)
									  of file))
		   (replace (Label filePage) of label with filePageNumber)

          (* * Transfer page)


		   (\PFTransferPage (IPLUS (LvBasePageAddr (fetch (FileDescriptor volNum)
							      of file))
					   volumePageNumber)
				    frame operation label))
    NIL])
)
(DEFINEQ

(\PFTransferPage
  [DLAMBDA ((absoluteDiskAddress FIXP)
            (buffer (ONEOF Page RandomPage))
            (mode (MEMQ VRR VVR VVW VWW VRW))
            (label Label))
                                                             (* bvm: "12-Jun-85 13:04")

          (* * Transfers a page and label to or from the disk.)



          (* * Make sure everything is swapped in to prevent page faulting in low-level disk routines.
	  In addition, buffer must be dirty for disk microcode to treat it right.)


    (SwapIn&Dirty buffer)
    (SwapIn&Dirty label)

          (* * Call the page reading/writing routine in a special stack environment which will not page fault on frame 
	  extension. Note \MISCAPPLY* will take only two args.)


    [WITH-RESOURCE \PFio (replace (\PFDiskIO absoluteDiskAddress) of \PFio with absoluteDiskAddress)
		   (replace (\PFDiskIO buffer) of \PFio with buffer)
		   (replace (\PFDiskIO mode) of \PFio with mode)
		   (PROG ((status (\MISCAPPLY* (FUNCTION \PFTransferPageNoSwap)
					       \PFio label)))

          (* * Check status for label verification errors)


		         (COND
			   ((AND (NEQ status T)
				 (fetch VERIFYERR of status))
			     (DiskError "HARD DISK ERROR"]])

(\PFTransferPageNoSwap
  [LAMBDA (diskIO label)                                     (* bvm: "12-Jun-85 12:29")

          (* * Called only in the Misc context, where we can guarantee no stack overflow will occur and cause unexpected page 
	  faults)


    (\DL.TRANSFERPAGE (fetch (\PFDiskIO absoluteDiskAddress) of diskIO)
		      (fetch (\PFDiskIO buffer) of diskIO)
		      (fetch (\PFDiskIO mode) of diskIO)
		      label])
)
(DECLARE: EVAL@COMPILE 
[PUTDEF (QUOTE label)
	(QUOTE RESOURCES)
	(QUOTE (NEW (create Label)
		    GET
		    (if \label.GLOBALRESOURCE then (PROG1 \label.GLOBALRESOURCE (\CLEARWORDS
							    \label.GLOBALRESOURCE
							    (MESASIZE Label))
							  (SETQ \label.GLOBALRESOURCE NIL))
			else
			(NEWRESOURCE label]
[PUTDEF (QUOTE \PFio)
	(QUOTE RESOURCES)
	(QUOTE (NEW (create \PFDiskIO]
)
(DECLARE: DONTEVAL@LOAD 
(\LOCKFN (QUOTE \PFTransferPage))
(\LOCKFN (QUOTE \PFTransferPageNoSwap))
)
(* * File Descriptor pool for system files)

(DEFINEQ

(\PFCreateFileDescriptors
  [LAMBDA NIL                                                (* hts: " 7-Jan-85 15:15")

          (* * Sets up the file descriptors for system files. Should be run at load time (or at least the first time you wake 
	  up on a dlion, and before running \PFInitFileDescriptors))


    (if [NOT (AND (BOUNDP (QUOTE \PFLogicalVolumeFileD))
		  (BOUNDP (QUOTE \PFMarkerFileD))
		  (BOUNDP (QUOTE \PFFreeFileD))
		  (BOUNDP (QUOTE \PFAllocationMapFileD))
		  (BOUNDP (QUOTE \PFFileMapFileD]
	then (SETQ \PFInitialized NIL) 

          (* * Logical volume descriptors)


	     (SETQ \PFLogicalVolumeFileD (ARRAY maxLogicalVolumes NIL NIL 0))
	     (for volNum from 0 to (SUB1 maxLogicalVolumes)
		do (SETA \PFLogicalVolumeFileD volNum
			 (create FileDescriptor
				 volNum ← volNum
				 type ← tLogicalVolumeRootPage
				 size ← 1)))

          (* * Marker pages)


	     (SETQ \PFMarkerFileD (ARRAY maxLogicalVolumes NIL NIL 0))
	     (for volNum from 0 to (SUB1 maxLogicalVolumes)
		do (SETA \PFMarkerFileD volNum
			 (create FileDescriptor
				 volNum ← volNum
				 type ← tSubVolumeMarkerPage
				 size ← 1)))

          (* * Free pages)


	     (SETQ \PFFreeFileD (ARRAY maxLogicalVolumes NIL NIL 0))
	     (for volNum from 0 to (SUB1 maxLogicalVolumes)
		do (SETA \PFFreeFileD volNum
			 (create FileDescriptor
				 fileID ← tFreePage
				 volNum ← volNum
				 type ← tFreePage)))

          (* * Volume allocation map pages)


	     (SETQ \PFAllocationMapFileD (ARRAY maxLogicalVolumes NIL NIL 0))
	     (for volNum from 0 to (SUB1 maxLogicalVolumes)
		do (SETA \PFAllocationMapFileD volNum
			 (create FileDescriptor
				 fileID ← tVolumeAllocationMap
				 volNum ← volNum
				 type ← tVolumeAllocationMap)))

          (* * Volume file map pages)


	     (SETQ \PFFileMapFileD (ARRAY maxLogicalVolumes NIL NIL 0))
	     (for volNum from 0 to (SUB1 maxLogicalVolumes)
		do (SETA \PFFileMapFileD volNum
			 (create FileDescriptor
				 fileID ← tVolumeFileMap
				 volNum ← volNum
				 type ← tVolumeFileMap])

(\PFInitFileDescriptors
  [LAMBDA NIL                                                (* hts: "30-Nov-84 13:44")

          (* * Fills in the fileID for the system file descriptors whose fileID changes depending on what disk you're running 
	  on. This routine should be run every time you wake up on a DLion, but run after you've read in the physical volume 
	  page.)


    (PROG [(lastVolNum (SUB1 (fetch (PhysicalVolumeDescriptor subVolumeCount) of \PhysVolumePage]

          (* * Logical volume descriptors)


          (for volNum from 0 to lastVolNum do (replace (FileDescriptor fileID)
						 of (ELT \PFLogicalVolumeFileD volNum)
						 with (MESASETQ (create VolumeID)
								(fetch (SubVolumeDesc lvID)
								   of (FMESAELT (fetch (
PhysicalVolumeDescriptor subVolumes) of \PhysVolumePage)
										SubVolumeArray volNum)
								       )
								VolumeID)))

          (* * Marker pages)


          (for volNum from 0 to lastVolNum do (replace (FileDescriptor fileID)
						 of (ELT \PFMarkerFileD volNum)
						 with (MESASETQ (create VolumeID)
								(fetch (PhysicalVolumeDescriptor
									 subVolumeMarkerID)
								   of \PhysVolumePage)
								VolumeID])
)
(DECLARE: DOEVAL@COMPILE DONTCOPY

(GLOBALVARS \PFLogicalVolumeFileD \PFMarkerFileD \PFFreeFileD \PFAllocationMapFileD \PFFileMapFileD)
)
(DECLARE: DONTEVAL@LOAD DOCOPY 
(\PFCreateFileDescriptors)
)
(* * Physical volume interface)

(DEFINEQ

(\PFCreatePhysicalVolume
  [LAMBDA NIL                                                (* hts: " 7-Jan-85 15:15")
    (if (NOT (AND (BOUNDP (QUOTE \PhysVolumePage))
		  (type? PhysicalVolumeDescriptor \PhysVolumePage)))
	then (SETQ \PFInitialized NIL)
	     (SETQ \PhysVolumePage (create PhysicalVolumeDescriptor)))
    NIL])
)
(DECLARE: DOEVAL@COMPILE DONTCOPY

(GLOBALVARS \PhysVolumePage)
)
(DECLARE: DONTEVAL@LOAD DOCOPY 
(\PFCreatePhysicalVolume)
)
(* * Interface to logical volumes,)

(DEFINEQ

(\PFCreateVols
  [LAMBDA NIL                                                (* bvm: "12-Jun-85 12:25")

          (* * Creates an array of logical volume page frames. Also creates a hash table which maps logical volumes 
	  descriptors onto volume numbers. Both these data structures share logical volume page frames, so only one 
	  (the array) need be updated. The conditional ensures that loading a new version of the file system will not smash 
	  the logical volume information, unless the data structures are incompatible.)


    (COND
      ((NOT (AND (BOUNDP (QUOTE \DFSLogicalVolumes))
		 (type? ARRAYP \DFSLogicalVolumes)
		 (EQ (ARRAYORIG \DFSLogicalVolumes)
		     0)
		 (EQ maxLogicalVolumes (ARRAYSIZE \DFSLogicalVolumes))
		 (BOUNDP (QUOTE \DFSLogicalVolumeHash))
		 (HASHARRAYP \DFSLogicalVolumeHash)))
	(SETQ \DFSLogicalVolumes (ARRAY maxLogicalVolumes NIL NIL 0))
	(SETQ \DFSLogicalVolumeHash (HASHARRAY maxLogicalVolumes))
	(bind vol for volNum from 0 to (SUB1 maxLogicalVolumes)
	   do (SETQ vol (create LogicalVolumeDescriptor))
	      (SETA \DFSLogicalVolumes volNum vol)
	      (PUTHASH vol volNum \DFSLogicalVolumeHash))
	(SETQ \PFInitialized NIL)))
    NIL])

(\PFInitializeVols
  [LAMBDA NIL                                                (* hts: "29-Nov-84 12:19")
    (for volNum from 0 to (SUB1 (fetch (PhysicalVolumeDescriptor subVolumeCount) of \PhysVolumePage))
       do (\PFGetLogicalVolumePage volNum (\PFGetVol volNum])

(\PFGetVols
  [LAMBDA NIL                                                (* hts: "11-Oct-84 17:19")
    (for volNum from 0 to (SUB1 (fetch (PhysicalVolumeDescriptor subVolumeCount) of \PhysVolumePage))
       collect (\PFGetVol volNum])

(\PFGetVol
  [LAMBDA (volNum)                                           (* hts: "11-Oct-84 15:12")
    (ELT \DFSLogicalVolumes volNum])

(\PFVolumeNumber
  [LAMBDA (vol)                                              (* hts: "26-Nov-84 11:52")

          (* * vol: LogicalVolumeDescriptor; RETURNS: FIXP in 0..9)



          (* Converts vol into a logical volume number, becuase the page reading and writing routines expect a logical volume 
	  number rather than the logical volume itself.)


    (GETHASH vol \DFSLogicalVolumeHash])
)
(DECLARE: DOEVAL@COMPILE DONTCOPY

(GLOBALVARS \DFSLogicalVolumes \DFSLogicalVolumeHash)
)
(DECLARE: DONTEVAL@LOAD DOCOPY 
(\PFCreateVols)
)
(DEFINEQ

(\PFGetLVPage
  [LAMBDA (lvName)                                           (* hts: " 9-Jan-85 16:28")

          (* * Returns the logical volume page for the volume whose name is lvName. Returns NIL if there is no such volume.)


    (SETQ lvName (MKATOM (U-CASE lvName)))
    (for vol in (\PFGetVols) thereis (EQ lvName (MKATOM (U-CASE (fetch (LogicalVolumeDescriptor
									 LVlabel)
								   of vol])
)
(* * Pilot integrity)

(DEFINEQ

(\PFVersionOK
  [LAMBDA NIL                                                (* hts: " 6-Jan-85 18:49")

          (* * Checks to see that the disk you are attempting to run on is partitioned in a way the file system can 
	  understand)


    (for vol in (\PFGetVols) always (EQ pilotVersion (fetch (LogicalVolumeDescriptor version)
							of vol])

(\PFPilotVolumeP
  [DLAMBDA ((vol LogicalVolumeDescriptor)
            (RETURNS BOOL))
                                                             (* mjs " 6-Mar-85 22:54")

          (* * Tells whether the volume in question is a pilot or non-pilot volume.)



          (* * any volume which is not of type non-Pilot is considered a Pilot volume <normal, debugger, debuggerdebugger, 
	  etc.>)


    (NEQ (fetch (LogicalVolumeDescriptor type) of vol)
	 nonPilotVolume)])
)
(* * Pilot initialization)

(DEFINEQ

(\PFEnsureInitialized
  [DLAMBDA ((FORCEINITIALIZATION BOOL)
            (RETURNS BOOL))
                                                             (* hts: "16-Feb-85 19:55")
    (SETQ \PFInitialized (SELECTQ (MACHINETYPE)
				  ((DANDELION DOVE)
				    (if (OR FORCEINITIALIZATION (NOT \PFInitialized))
					then 

          (* * initialize physical volume page cache)


					     (\PFGetPhysicalVolumePage \PhysVolumePage) 

          (* * Use physical volume page to set up disk-specific system file descriptors (for logical volume pages and marker 
	  pages))


					     (\PFInitFileDescriptors) 

          (* * initialize logical volume page cache;)


					     (\PFInitializeVols)
					     (if (\PFVersionOK)
						 then 

          (* * Initialize volume file map and volume allocation map)


						      (\VAMInit)
						      (\VFMInit) 

          (* * Note that this routine has been run)


						      (\PFDsplyVolumes)
						      T
					       else NIL)
				      else \PFInitialized))
				  NIL))])
)
(DECLARE: DOEVAL@COMPILE DONTCOPY

(GLOBALVARS \PFInitialized)
)

(RPAQ? \PFInitialized NIL)

(ADDTOVAR \SYSTEMCACHEVARS \PFInitialized)
(DECLARE: DONTEVAL@LOAD DOCOPY 
(\PFEnsureInitialized)
)
(* * Root directory management)

(DEFINEQ

(\PFFindDirectoryID
  [LAMBDA (vol type)                                         (* hts: "18-Dec-84 16:45")

          (* * If on vol there is a directory associated with the specified file type, returns the fileID associated with that
	  directory; else returns NIL)


    (PROG ((rootDir (create RootDirectory)))
          (RETURN (if (\PFGetRootDirectory vol rootDir)
		      then (\PFFindRootDirEntry type rootDir)
		    else NIL])

(\PFInsertDirectoryID
  [LAMBDA (vol type directoryID)                             (* hts: "18-Dec-84 16:43")

          (* * comment)


    (PROG ((rootDir (create RootDirectory)))

          (* * get root directory page if there is one. Else make place for one.)


          (if (NOT (\PFGetRootDirectory vol rootDir))
	      then (\PFCreateRootDirectory vol rootDir))

          (* * Add specified (type directoryID) pair)


          (\PFAddRootDirEntry type directoryID rootDir)

          (* * write out modified root directory)


          (\PFPutRootDirectory vol rootDir])

(\PFRemoveDirectoryID
  [LAMBDA (vol type)                                         (* mjs "15-May-85 11:52")
    (PROG ((rootDir (create RootDirectory)))
          (if (\PFGetRootDirectory vol rootDir)
	      then (\PFRemoveRootDirEntry type rootDir)
		   (if (LESSP (fetch (RootDirectory countEntries) of rootDir)
			      1)
		       then (\PFPurgeRootDirectory vol rootDir)
		     else (\PFPutRootDirectory vol rootDir])
)
(DEFINEQ

(\PFFindRootDirEntry
  [LAMBDA (type rootDir)                                     (* mjs "15-May-85 11:54")

          (* * Find the directoryFileID that corresponds to type, if any.)


    (LET ((entryNum (\PFFindRootDirEntryNum type rootDir)))
      (AND (SMALLP entryNum)
	   (fetch (RootDirEntry file) of (MESAELT (fetch (RootDirectory entries) of rootDir)
						  RootDirEntryArray entryNum])

(\PFFindRootDirEntryNum
  [LAMBDA (type rootDir)                                     (* mjs "15-May-85 11:57")

          (* * look through registered directories to find the desired one. Stored as an array of (type directoryFileID) 
	  pairs.)


    (bind directories first (SETQ directories (fetch (RootDirectory entries) of rootDir))
       for entryNum from 0 to (SUB1 (fetch (RootDirectory countEntries) of rootDir))
       thereis (EQ (fetch (RootDirEntry type) of (MESAELT directories RootDirEntryArray entryNum))
		   type])

(\PFAddRootDirEntry
  [LAMBDA (type directoryID rootDir)                         (* mjs "15-May-85 11:56")

          (* * Add specified (type directoryID) pair)


    (UNINTERRUPTABLY
        (PROG ((entryNum (fetch (RootDirectory countEntries) of rootDir)))
	      (MESASETA (fetch (RootDirectory entries) of rootDir)
			RootDirEntryArray entryNum (create RootDirEntry
							   type ← type
							   file ← directoryID))
	      (replace (RootDirectory countEntries) of rootDir with (ADD1 entryNum))))])

(\PFRemoveRootDirEntry
  [LAMBDA (type rootDir)                                     (* mjs "15-May-85 11:57")
    (UNINTERRUPTABLY
        [PROG ((nuke (\PFFindRootDirEntryNum type rootDir)))
	      (if nuke
		  then (bind directories first (SETQ directories (fetch (RootDirectory entries)
								    of rootDir))
			  for entryNum from (ADD1 nuke) to (SUB1 (fetch (RootDirectory countEntries)
								    of rootDir))
			  do (MESASETA directories RootDirEntryArray (SUB1 entryNum)
				       (MESAELT directories RootDirEntryArray entryNum)))
		       (replace (RootDirectory countEntries) of rootDir
			  with (SUB1 (fetch (RootDirectory countEntries) of rootDir])])
)
(DEFINEQ

(\PFGetRootDirectory
  [LAMBDA (vol rootDir)                                      (* hts: " 5-Jan-85 16:26")

          (* * Reads in and returns the root directory for the specified volume, provided that it is there;
	  else returns NIL)


    (if (NEQ (\GetRootDirectoryType vol)
	     tRootDirectory)
	then NIL
      else (PROG ((fileD (create FileDescriptor
				 fileID ← tRootDirectory
				 volNum ←(\PFVolumeNumber vol)
				 type ← tRootDirectory
				 size ← 1))
		  where)

          (* * find location of root directory page)


	         (SETQ where (\VFMGetPageGroup vol fileD 0))
	         (OR where (RETURN NIL))

          (* * read in root directory page)


	         (\PFGetPage fileD 0 (fetch (PageGroup volumePage) of where)
			     rootDir)
	         (RETURN T])

(\PFPutRootDirectory
  [LAMBDA (vol rootDir)                                      (* edited: "20-Jan-85 16:01")

          (* * comment)


    (PROG ((fileD (create FileDescriptor
			  fileID ← tRootDirectory
			  volNum ←(\PFVolumeNumber vol)
			  type ← tRootDirectory
			  size ← 1))
	   where)

          (* * find location of root directory page)


          (SETQ where (\VFMGetPageGroup vol fileD 0))
          (OR where (DiskError "HARD DISK ERROR" "Can't find volume root directory"))

          (* * read in root directory page)


          (\PFPutPage fileD 0 (fetch (PageGroup volumePage) of where)
		      rootDir])

(\PFCreateRootDirectory
  [DLAMBDA ((vol LogicalVolumeDescriptor)
            (rootDir RootDirectory)
            (RETURNS NIL))
                                                             (* hts: "16-Feb-85 18:18")

          (* * Allocates a disk page for the root directory.)


    (UNINTERRUPTABLY
        (PROG ((fileD (create FileDescriptor
			      fileID ← tRootDirectory
			      volNum ←(\PFVolumeNumber vol)
			      type ← tRootDirectory
			      size ← 0)))
	      (\PFNewPages vol fileD (create PageGroup
					     filePage ← 0
					     nextFilePage ← 1))
	      (\PFPutRootDirectory vol rootDir)
	      (\PFPutRootDirectoryType vol tRootDirectory)
	      (\PFSaveBuffers vol)))])

(\PFPurgeRootDirectory
  [LAMBDA (vol rootDir)                                      (* hts: " 5-Jan-85 16:15")

          (* * comment)


    (UNINTERRUPTABLY
        (PROG ((fileD (create FileDescriptor
			      fileID ← tRootDirectory
			      volNum ←(\PFVolumeNumber vol)
			      type ← tRootDirectory
			      size ← 1)))
	      (\PFPutRootDirectoryType vol tUnassigned)
	      (\PFTrimHelper vol fileD 0)))])
)
(DEFINEQ

(\GetRootDirectoryType
  [LAMBDA (vol)                                              (* hts: "18-Dec-84 21:55")

          (* * comment)


    (fetch (LogicalVolumeDescriptor volumeRootDirectory) of vol])

(\PFPutRootDirectoryType
  [LAMBDA (vol directoryID)                                  (* hts: "18-Dec-84 19:16")

          (* * comment)


    (replace (LogicalVolumeDescriptor volumeRootDirectory) of vol with directoryID)
    (\PFPutLogicalVolumePage vol vol)
    (PROG ((markerPage (create SubVolumeMarkerPage)))
          (\PFGetMarkerPage vol markerPage)
          (replace (LogicalSubVolumeMarker volumeRootDirectory) of markerPage with directoryID)
          (\PFPutMarkerPage vol markerPage])
)
(* * Pilot file management)

(DEFINEQ

(\PFNewPages
  [DLAMBDA ((vol LogicalVolumeDescriptor)
            (file FileDescriptor)
            (group PageGroup)
            (RETURNS (LISTP OF PageGroup)))
                                                             (* bvm: "12-Jun-85 12:59")

          (* * Allocates the specified group of pages for file)


    (bind currentGroup until (IEQP (fetch (FileDescriptor size) of file)
				   (fetch (PageGroup nextFilePage) of group))
       collect 

          (* * Build the group to attempt to allocate next)


	       (SETQ currentGroup (create PageGroup
					  filePage ←(fetch (FileDescriptor size) of file)
					  volumePage ← 0
					  nextFilePage ←(fetch (PageGroup nextFilePage) of group)))

          (* * Allocate as many pages of the desired group as possible)


	       (\VAMAllocPageGroup vol file currentGroup) 

          (* * Stick the newly allocated group into the volume file map BTree)


	       (\VFMInsertPageGroup vol file currentGroup) 

          (* * Record the newly-increased size of the file)


	       (replace (FileDescriptor size) of file with (fetch (PageGroup nextFilePage)
							      of currentGroup))
	       (BLOCK)
	       currentGroup
       finally (\PFDsplyVolumes))])

(\PFTrimHelper
  [LAMBDA (vol filePtr targetFileSize)                       (* bvm: "12-Jun-85 13:00")

          (* * Shortens or deletes a file by taking entries out of the BTree and out of the allocation map Removes the pages 
	  of the file between targetFileSize & actualFileSize)


    (COND
      ((NOT (IEQP targetFileSize (fetch (FileDescriptor size) of filePtr)))
	(bind (group ←(create PageGroup
			      filePage ← targetFileSize
			      volumePage ← nullVolumePage
			      nextFilePage ←(fetch (FileDescriptor size) of filePtr)))
	   until [PROGN (\VFMDeletePageGroup vol filePtr group)
			(\VAMFreePageGroup vol filePtr group)
			(replace (FileDescriptor size) of filePtr with (fetch (PageGroup filePage)
									  of group))
			(COND
			  ((EQ (fetch (PageGroup filePage) of group)
			       0)
			    (replace (PageGroup nextFilePage) of group with 0)
			    (\VFMDeletePageGroup vol filePtr group)
			    (\VAMFreePageGroup vol filePtr group)
			    T)
			  (T (IEQP (fetch (PageGroup filePage) of group)
				   targetFileSize]
	   do (replace (PageGroup nextFilePage) of group with (fetch (PageGroup filePage)
								 of group))
	      (replace (PageGroup filePage) of group with targetFileSize)
	      (BLOCK))
	(\PFDsplyVolumes])

(\PFFindPageAddr
  [LAMBDA (file filePage)                                    (* bvm: "12-Jun-85 12:25")

          (* * vol: LogicalVolumeDescriptor, file: FileDescriptor, filePage: FIXP; returns FIXP)



          (* * Tells where page filePage of file is located on the disk)



          (* * Caches the last pageGroup for the file)


    (PROG ((PAGEGROUP (fetch (FileDescriptor PAGEGROUP) of file)))
          (COND
	    ((OR (NOT (FIXP PAGEGROUP))
		 (LESSP filePage (fetch (PageGroup filePage) of PAGEGROUP))
		 (GEQ filePage (fetch (PageGroup nextFilePage) of PAGEGROUP)))

          (* * Page group we are after is not in cache; we will have to look it up in the volume file map)



          (* GetPageGroup returns a dotted pair whose CAR is NIL iff the fileID was not found, and whose CDR contains a 
	  PageGroup indicating the desired pages. Gives a zero volume page iff the fileID is found, but the page specified 
	  isn't.)


	      (SETQ PAGEGROUP (\VFMGetPageGroup (\PFGetVol (fetch (FileDescriptor volNum)
							      of file))
						file filePage))
	      (OR (AND PAGEGROUP (NEQ (fetch (PageGroup volumePage) of PAGEGROUP)
				      0))
		  (DiskError "HARD DISK ERROR" "Can't find file page"))
	      (replace (FileDescriptor PAGEGROUP) of file with PAGEGROUP)))
          (RETURN (IPLUS (fetch (PageGroup volumePage) of PAGEGROUP)
			 filePage
			 (IMINUS (fetch (PageGroup filePage) of PAGEGROUP])

(\PFFindFileSize
  [DLAMBDA ((file FileDescriptor)
            (RETURNS FIXP))
                                                             (* hts: " 9-Jan-85 20:33")

          (* * Finds the number of pages in the specified file, as recorded in the volume file map.)


    (fetch (PageGroup filePage) of (\VFMGetPageGroup (\PFGetVol (fetch (FileDescriptor volNum)
								   of file))
						     file MAX.FIXP))])

(\PFFreeDiskPages
  [DLAMBDA ((vol LogicalVolumeDescriptor)
            (recompute BOOL)
            (RETURNS FIXP))
                                                             (* hts: " 8-Jan-85 14:54")

          (* * Returns the free page count for the specified volume.)


    (if recompute
	then (\VAMRecomputeFreePageCount vol)
	     (\PFDsplyVolumes))
    (fetch (LogicalVolumeDescriptor freePageCount) of vol)])

(\PFSaveBuffers
  [DLAMBDA ((VOL LogicalVolumeDescriptor)
            (RETURNS NIL))
                                                             (* hts: "16-Feb-85 18:04")

          (* * Saves out dirty buffers.)


    (\PFPutLogicalVolumePage VOL VOL)
    (\VAMBufferSave)
    (\VFMSaveBuffer)])
)
(* * Lisp vmem)

(DEFINEQ

(\PFCurrentVol
  [LAMBDA NIL                                                (* bvm: "12-Jun-85 13:00")

          (* * Returns the logical volume page of the volume which contains the currently running virtual memory)


    (for vol in (\PFGetVols) thereis (IEQP (fetch (DiskFileID da) of (FMESAELT (fetch (
PhysicalVolumeDescriptor bootingInfo) of \PhysVolumePage)
									       PVBootFiles 
									       hardMicrocode))
					   (fetch (DiskFileID da) of (FMESAELT (fetch (
LogicalVolumeDescriptor bootingInfo) of vol)
									       LVBootFiles 
									       hardMicrocode])

(\PFVMemFileID
  [DLAMBDA ((RETURNS FIXP))
                                                             (* hts: "16-Feb-85 15:13")

          (* * Returns the file ID of the currently running vmem.)


    (fetch (DiskFileID fID) of (FMESAELT (fetch (PhysicalVolumeDescriptor bootingInfo) of 
										  \PhysVolumePage)
					 PVBootFiles hardMicrocode))])

(\PFVMemFileSize
  [DLAMBDA ((RETURNS FIXP))
                                                             (* hts: "16-Feb-85 15:32")

          (* * Returns the size of the currently running virtual memory backing file.)


    (\PFFindFileSize (create FileDescriptor
			     fileID ←(\PFVMemFileID)
			     volNum ←(\PFVolumeNumber (\PFCurrentVol))
			     type ← tDiagnosticMicrocode))])

(\PFExtendVMem
  [DLAMBDA ((NPAGES FIXP)
            (RETURNS (LISTP OF PageGroup)))
                                                             (* hts: "16-Feb-85 15:43")

          (* * Extends the currently-running vmem backing file by the specified number of pages. Returns a list of PageGroups 
	  which tell which new pages were allocated. If there is not enough space, it will error out with 
	  "file system resources exceeded: {DSK}<VOLUMENAME>". So the caller is obliged to check first to see if there is 
	  enough room.)


    [PROG ((currentVol (\PFCurrentVol))
	   (oldSize (\PFVMemFileSize)))
          (RETURN (\PFNewPages currentVol (create FileDescriptor
						  fileID ←(\PFVMemFileID)
						  volNum ←(\PFVolumeNumber currentVol)
						  type ← tDiagnosticMicrocode
						  size ← oldSize)
			       (create PageGroup
				       filePage ← oldSize
				       volumePage ← 0
				       nextFilePage ←(PLUS oldSize NPAGES]])
)
(* * Display stub; real volume display stuff is implemented on a library package called 
DSKDISPLAY)

(MOVD? (QUOTE NILL)
       (QUOTE \PFDsplyVolumes))
(PUTPROPS LFPILOTFILE COPYRIGHT ("Xerox Corporation" 1985))
(DECLARE: DONTCOPY
  (FILEMAP (NIL (3575 4673 (\PFFetchString 3585 . 3988) (\PFReplaceString 3990 . 4671)) (18944 20221 (
DISPLAYWORDS 18954 . 19293) (DISPLAYLABEL 19295 . 19767) (DISPLAYPAGE 19769 . 20219)) (21159 21369 (
\PFGetPhysicalVolumePage 21169 . 21367)) (21370 21942 (\PFGetLogicalVolumePage 21380 . 21659) (
\PFPutLogicalVolumePage 21661 . 21940)) (21943 22679 (\PFGetMarkerPage 21953 . 22314) (
\PFPutMarkerPage 22316 . 22677)) (22680 22986 (\PFCreateFreePage 22690 . 22984)) (22987 23631 (
\PFGetAllocationMapPage 22997 . 23306) (\PFPutAllocationMapPage 23308 . 23629)) (23632 24264 (
\PFGetFileMapPage 23642 . 23951) (\PFPutFileMapPage 23953 . 24262)) (24265 25434 (\PFGetPage 24275 . 
24635) (\PFPutPage 24637 . 25036) (\PFCreatePage 25038 . 25432)) (25435 26898 (\PFTransferFilePage 
25445 . 26896)) (26899 28701 (\PFTransferPage 26909 . 28226) (\PFTransferPageNoSwap 28228 . 28699)) (
29246 32895 (\PFCreateFileDescriptors 29256 . 31568) (\PFInitFileDescriptors 31570 . 32893)) (33133 
33517 (\PFCreatePhysicalVolume 33143 . 33515)) (33686 36182 (\PFCreateVols 33696 . 35015) (
\PFInitializeVols 35017 . 35331) (\PFGetVols 35333 . 35609) (\PFGetVol 35611 . 35758) (\PFVolumeNumber
 35760 . 36180)) (36324 36803 (\PFGetLVPage 36334 . 36801)) (36832 37741 (\PFVersionOK 36842 . 37232) 
(\PFPilotVolumeP 37234 . 37739)) (37775 38910 (\PFEnsureInitialized 37785 . 38908)) (39151 40778 (
\PFFindDirectoryID 39161 . 39644) (\PFInsertDirectoryID 39646 . 40287) (\PFRemoveDirectoryID 40289 . 
40776)) (40779 43173 (\PFFindRootDirEntry 40789 . 41226) (\PFFindRootDirEntryNum 41228 . 41836) (
\PFAddRootDirEntry 41838 . 42395) (\PFRemoveRootDirEntry 42397 . 43171)) (43174 45930 (
\PFGetRootDirectory 43184 . 44051) (\PFPutRootDirectory 44053 . 44737) (\PFCreateRootDirectory 44739
 . 45479) (\PFPurgeRootDirectory 45481 . 45928)) (45931 46724 (\GetRootDirectoryType 45941 . 46164) (
\PFPutRootDirectoryType 46166 . 46722)) (46759 52382 (\PFNewPages 46769 . 48116) (\PFTrimHelper 48118
 . 49551) (\PFFindPageAddr 49553 . 51145) (\PFFindFileSize 51147 . 51598) (\PFFreeDiskPages 51600 . 
52056) (\PFSaveBuffers 52058 . 52380)) (52405 54887 (\PFCurrentVol 52415 . 53064) (\PFVMemFileID 53066
 . 53450) (\PFVMemFileSize 53452 . 53872) (\PFExtendVMem 53874 . 54885)))))
STOP