(FILECREATED " 2-Dec-85 12:50:40" {ERIS}<LISPCORE>SOURCES>LISPOTHELLO.;1 30176  

      changes to:  (FNS \PV.DiskFileIDOfBootFile \LV.FileDescriptorForBootFile 
			\LV.LeaderPageForBootFile)

      previous date: " 8-Nov-85 19:00:53" {ERIS}<LISPCORE>DOVE>LISPOTHELLO.;8)


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

(PRETTYCOMPRINT LISPOTHELLOCOMS)

(RPAQQ LISPOTHELLOCOMS [(COMS (* Othello-like utility for Lisp)
				(DECLARE: DONTCOPY (FILES (LOADCOMP)
							  LOCALFILE))
				(CONSTANTS * BootFileTypes)
				(CONSTANTS * DiskPageSeals)
				(INITVARS (\LispOthello.FileDescriptor (NCREATE (QUOTE FileDescriptor)
										))
					  (\LispOthello.LeaderPage (NCREATE (QUOTE VMEMPAGEP)))
					  (\LispOthello.Label (NCREATE (QUOTE VMEMPAGEP)))
					  (\LispOthello.PhysicalVolumeRootPage (NCREATE (QUOTE 
											VMEMPAGEP)))
					  (\LispOthello.MarkerPage (NCREATE (QUOTE VMEMPAGEP)))
					  (\LispOthello.BadPageTable))
				(GLOBALVARS \LispOthello.LeaderPage \LispOthello.FileDescriptor 
					    \LispOthello.Label \LispOthello.PhysicalVolumeRootPage 
					    \LispOthello.MarkerPage BootFileTypes DiskPageSeals))
	[COMS (* Physical volume functions)
	      (FNS ShowVMemRunTable \PV.DiskFileIDOfBootFile \PV.DiskPageNumber 
		   \PV.FetchSubMarkerLabel \PV.LVDescFromDiskAddress \PV.LVDescFromPageNumber 
		   \PV.LeaderPageForBootFile \PV.MapSubVolumes \PV.ReadBadPageTable 
		   \PV.ReadPVRootPage \PV.SetPVBootFile \PV.UpdateMarkerPages \PV.WriteBadPageTable 
		   \PV.WritePVRootPage)
	      (DECLARE: DONTCOPY (EXPORT (MACROS SwapFIXP \PV.SubVolumeDescFromVol#)
					 (RECORDS MarkerPage PhysicalVolumeSubMarker PilotDiskAddress 
						  PilotLeaderPage]
	[COMS (* Logical volume functions)
	      (FNS \LV.DiskFileIDOfBootFile \LV.DescriptorFromName \LV.FileDescriptorForBootFile 
		   \LV.LeaderPageForBootFile \LV.RenameVolume \LV.ReplaceSubMarkerLabel 
		   \VFMGenerateAllFileIDs)
	      (DECLARE: DONTCOPY (EXPORT (MACROS \LVDescFromNumber \LV.FetchSubMarkerLabel 
						 \LV.NameFromLeaderPage)
					 (RECORDS LogicalVolumeSubMarker Index Interval Key]
	(COMS (* User functions)
	      (FNS DescribePhysicalVolume LispOthelloEventFN PrintLVBootFiles PrintPVBootFiles 
		   RenameVolume SetPVBootFiles ShowBootFileLayout MakePageBad UnmakePageBad 
		   ListBadPages)
	      (ADDVARS (AROUNDEXITFNS LispOthelloEventFN)))
	(COMS (P (\PV.ReadPVRootPage])



(* Othello-like utility for Lisp)

(DECLARE: DONTCOPY 
(FILESLOAD (LOADCOMP)
	   LOCALFILE)
)

(RPAQQ BootFileTypes ((bftDiagnosticMicrocode 0)
			(bftEmulatorMicrocode 1)
			(bftGerm 2)
			(bftPilotBootFile 3)))
(DECLARE: EVAL@COMPILE 

(RPAQQ bftDiagnosticMicrocode 0)

(RPAQQ bftEmulatorMicrocode 1)

(RPAQQ bftGerm 2)

(RPAQQ bftPilotBootFile 3)

(CONSTANTS (bftDiagnosticMicrocode 0)
	   (bftEmulatorMicrocode 1)
	   (bftGerm 2)
	   (bftPilotBootFile 3))
)

(RPAQQ DiskPageSeals ((\PV.RootSeal 41610)
			(\PV.SMSeal 49932)
			(\LV.RootSeal 45771)
			(\LV.SMSeal 54093)))
(DECLARE: EVAL@COMPILE 

(RPAQQ \PV.RootSeal 41610)

(RPAQQ \PV.SMSeal 49932)

(RPAQQ \LV.RootSeal 45771)

(RPAQQ \LV.SMSeal 54093)

(CONSTANTS (\PV.RootSeal 41610)
	   (\PV.SMSeal 49932)
	   (\LV.RootSeal 45771)
	   (\LV.SMSeal 54093))
)

(RPAQ? \LispOthello.FileDescriptor (NCREATE (QUOTE FileDescriptor)))

(RPAQ? \LispOthello.LeaderPage (NCREATE (QUOTE VMEMPAGEP)))

(RPAQ? \LispOthello.Label (NCREATE (QUOTE VMEMPAGEP)))

(RPAQ? \LispOthello.PhysicalVolumeRootPage (NCREATE (QUOTE VMEMPAGEP)))

(RPAQ? \LispOthello.MarkerPage (NCREATE (QUOTE VMEMPAGEP)))

(RPAQ? \LispOthello.BadPageTable )
(DECLARE: DOEVAL@COMPILE DONTCOPY

(GLOBALVARS \LispOthello.LeaderPage \LispOthello.FileDescriptor \LispOthello.Label 
	    \LispOthello.PhysicalVolumeRootPage \LispOthello.MarkerPage BootFileTypes DiskPageSeals)
)



(* Physical volume functions)

(DEFINEQ

(ShowVMemRunTable
  (LAMBDA NIL                                                (* ejs: " 8-Nov-85 19:00")
    (LET ((LINKBASE (LOCF (fetch (IOCBPAGE DLVMEMFILEINFO) of \IOCBPAGE))))
         (printout T "File Page Numbers  =>  Disk Page Numbers" T)
         (bind (VP ← 0)
		 RunList DiskAddress EndOfRunDiskAddress EndOfRunVP
	    eachtime (SETQ DiskAddress (IPLUS (fetch (DLVMEMRUN DLVMSECTOR) of LINKBASE)
						    (ITIMES (fetch (DLVMEMRUN DLVMHEAD)
								 of LINKBASE)
							      \DLDISKSHAPE.SECTORSPERHEAD)
						    (ITIMES (fetch (DLVMEMRUN DLVMCYL)
								 of LINKBASE)
							      \DLDISKSHAPE.SECTORSPERCYLINDER)))
	    while (NEQ 0 (fetch (DLVMEMRUN DLFIRSTFILEPAGE) of (fetch (DLVMEMRUN DLNEXTRUN)
									  of LINKBASE)))
	    do (SETQ EndOfRunVP (SUB1 (fetch (DLVMEMRUN DLFIRSTFILEPAGE)
					       of (fetch (DLVMEMRUN DLNEXTRUN) of LINKBASE))))
		 (SETQ EndOfRunDiskAddress (IPLUS DiskAddress (IDIFFERENCE EndOfRunVP VP)))
		 (printout T "[" VP ".." EndOfRunVP "]  =>  [" DiskAddress ".." EndOfRunDiskAddress 
			   "]")
		 (COND
		   ((SOME RunList (FUNCTION (LAMBDA (previousAddressRange)
				(AND (IGEQ DiskAddress (CAR previousAddressRange))
				       (ILEQ DiskAddress (CDR previousAddressRange))))))
		     (printout T " <= Entirely bogus VMem run!" T))
		   ((NOT (EQP (IDIFFERENCE EndOfRunVP VP)
				  (IDIFFERENCE EndOfRunDiskAddress DiskAddress)))
		     (printout T " <= VMem run length doesn't match disk run length!" T))
		   (T (TERPRI T)))
		 (push RunList (CONS DiskAddress EndOfRunDiskAddress))
		 (SETQ VP (fetch (DLVMEMRUN DLFIRSTFILEPAGE) of (fetch (DLVMEMRUN DLNEXTRUN)
									 of LINKBASE)))
		 (SETQ LINKBASE (fetch (DLVMEMRUN DLNEXTRUN) of LINKBASE))
	    finally (SETQ EndOfRunVP (fetch (IFPAGE DLLastVmemPage) of \InterfacePage))
		      (printout T "[" VP ".." EndOfRunVP "]  =>  [" DiskAddress ".."
				(IPLUS DiskAddress (IDIFFERENCE EndOfRunVP VP))
				"]" T)))))

(\PV.DiskFileIDOfBootFile
  [LAMBDA (N)                                                (* amd " 2-Dec-85 12:31")
    (MESAELT (fetch (PhysicalVolumeDescriptor bootingInfo) of \LispOthello.PhysicalVolumeRootPage)
	     PVBootFiles N])

(\PV.DiskPageNumber
  (LAMBDA (PilotDiskAddress)                                 (* ejs: " 9-Sep-85 23:03")

          (* * Returns the disk page number for the Pilot disk address)


    (IPLUS (ITIMES (fetch (PilotDiskAddress Cylinder) of PilotDiskAddress)
		   \DLDISKSHAPE.SECTORSPERCYLINDER)
	   (ITIMES (fetch (PilotDiskAddress Head) of PilotDiskAddress)
		   \DLDISKSHAPE.SECTORSPERHEAD)
	   (fetch (PilotDiskAddress Sector) of PilotDiskAddress))))

(\PV.FetchSubMarkerLabel
  (LAMBDA (labelBase Length MaxChars)                        (* ejs: "11-Sep-85 00:05")

          (* * Return a string from the physical or logical subvolume marker label)


    (LET ((NewString (ALLOCSTRING (IMIN Length MaxChars))))
         (\MOVEBYTES labelBase 0 (fetch (STRINGP BASE) of NewString)
		     (fetch (STRINGP OFFST) of NewString)
		     (fetch (STRINGP LENGTH) of NewString))
     NewString)))

(\PV.LVDescFromDiskAddress
  [LAMBDA (PilotDiskAddress)                                 (* amd " 6-Nov-85 16:21")
    (\PV.LVDescFromPageNumber (\PV.DiskPageNumber PilotDiskAddress])

(\PV.LVDescFromPageNumber
  [LAMBDA (DiskPageNumber)                                   (* amd " 6-Nov-85 16:46")
    (\PV.MapSubVolumes (FUNCTION (LAMBDA (SVDesc LVDesc)
			     (LET* [(FirstPage (fetch (SubVolumeDesc pvPage) of SVDesc))
				    (LastPage (IPLUS FirstPage (fetch (SubVolumeDesc nPages)
								    of SVDesc]
			           (COND
				     ((AND (IGEQ DiskPageNumber FirstPage)
					     (ILEQ DiskPageNumber LastPage))
				       (RETFROM (QUOTE \PV.LVDescFromPageNumber)
						  LVDesc])

(\PV.LeaderPageForBootFile
  (LAMBDA (BootFileType)                                     (* ejs: "10-Sep-85 00:22")

          (* * Find the logical volume of the boot file of type BootFileType. Return the leader page for that file)


    (LET* ((DiskFileID (\PV.DiskFileIDOfBootFile BootFileType))
	   (FileID (\GETBASE DiskFileID 0))
	   (PilotDiskAddress (fetch (DiskFileID da) of DiskFileID))
	   (LVDesc (COND
		     ((NEQ PilotDiskAddress 0)
		       (\PV.LVDescFromDiskAddress PilotDiskAddress))))
	   (vol# (COND
		   (LVDesc (GETHASH LVDesc \DFSLogicalVolumeHash)))))
          (COND
	    (vol# (replace (FileDescriptor fileID) of \LispOthello.FileDescriptor with FileID)
		  (replace (FileDescriptor volNum) of \LispOthello.FileDescriptor with vol#)
		  (replace (FileDescriptor type) of \LispOthello.FileDescriptor with 
									     tDiagnosticMicrocode)
		  (\PFGetPage \LispOthello.FileDescriptor 0 (\PFFindPageAddr 
								      \LispOthello.FileDescriptor 0)
			      \LispOthello.LeaderPage)
		  (CONS \LispOthello.LeaderPage LVDesc))))))

(\PV.MapSubVolumes
  (LAMBDA (FUNCTION)                                         (* ejs: "10-Sep-85 17:32")
    (bind SVDesc for SVIndex from 0 to (SUB1 (fetch (PhysicalVolumeDescriptor subVolumeCount)
						of \LispOthello.PhysicalVolumeRootPage))
       eachtime (SETQ SVDesc (\PV.SubVolumeDescFromVol# SVIndex)) do (APPLY* FUNCTION SVDesc
									     (ELT \DFSLogicalVolumes 
										  SVIndex)
									     SVIndex))))

(\PV.ReadBadPageTable
  [LAMBDA NIL                                                (* amd " 6-Nov-85 15:49")
    (LET [(BUF (NCREATE (QUOTE VMEMPAGEP]
         (if (\PFTransferPage 1 BUF (QUOTE VRR)
				  \LispOthello.Label 1)
	     then (SETQ \LispOthello.BadPageTable (for i from 0
							 to (SUB1 (fetch (
PhysicalVolumeDescriptor badPageCount) of \LispOthello.PhysicalVolumeRootPage))
							 collect (\MAKENUMBER
								     (GETBASE BUF
									      (ADD1 (ITIMES
											i 2)))
								     (GETBASE BUF (ITIMES i 2])

(\PV.ReadPVRootPage
  (LAMBDA NIL                                                (* ejs: "10-Sep-85 23:49")
    (\PFTransferPage 0 \LispOthello.PhysicalVolumeRootPage (QUOTE VRR)
		     \LispOthello.Label)
    (COND
      ((NEQ (fetch (PhysicalVolumeDescriptor seal) of \LispOthello.PhysicalVolumeRootPage)
	    \PV.RootSeal)
	(ERROR "Physical volume root page seal is invalid!" (fetch (PhysicalVolumeDescriptor seal)
							       of \LispOthello.PhysicalVolumeRootPage)
	       ))
      (T \LispOthello.PhysicalVolumeRootPage))))

(\PV.SetPVBootFile
  (LAMBDA (LVDesc I)                                         (* ejs: "10-Sep-85 00:50")

          (* * set the Ith boot file from the logical volume specified by LVDesc to be the Ith physical volume boot file)


    (\BLT (\PV.DiskFileIDOfBootFile I)
	  (\LV.DiskFileIDOfBootFile LVDesc I)
	  (MESASIZE DiskFileID))))

(\PV.UpdateMarkerPages
  (LAMBDA NIL                                                (* ejs: "10-Sep-85 23:44")

          (* * Update each of the PhysicalVolumeSubMarkers at the end of each logical volume)


    (\PV.MapSubVolumes (FUNCTION (LAMBDA (SVDesc LVDesc svNumber)
			   (\PFGetMarkerPage svNumber \LispOthello.MarkerPage)
			   (COND
			     ((NEQ (fetch (PhysicalVolumeSubMarker seal) of (fetch (MarkerPage 
											 physical)
									       of 
									  \LispOthello.MarkerPage))
				   \PV.SMSeal)
			       (ERROR "Physical volume submarker seal is invalid!"
				      (fetch (PhysicalVolumeSubMarker seal)
					 of (fetch (MarkerPage physical) of \LispOthello.MarkerPage)))
			       ))
			   (\BLT (fetch (PhysicalVolumeSubMarker bootingInfo)
				    of (fetch (MarkerPage physical) of \LispOthello.MarkerPage))
				 (fetch (PhysicalVolumeDescriptor bootingInfo) of 
							      \LispOthello.PhysicalVolumeRootPage)
				 (CONSTANT (MESASIZE PVBootFiles)))
			   (\MOVEBYTES (LOCF (fetch (PhysicalVolumeDescriptor label) of 
							      \LispOthello.PhysicalVolumeRootPage))
				       0
				       (LOCF (fetch (PhysicalVolumeSubMarker label)
						of (fetch (MarkerPage physical) of 
									  \LispOthello.MarkerPage)))
				       0
				       (fetch (PhysicalVolumeDescriptor labelLength) of 
							      \LispOthello.PhysicalVolumeRootPage))
			   (replace (PhysicalVolumeSubMarker labelLength) of (fetch (MarkerPage
										      physical)
										of 
									  \LispOthello.MarkerPage)
			      with (fetch (PhysicalVolumeDescriptor labelLength) of 
							      \LispOthello.PhysicalVolumeRootPage))
			   (\PFPutMarkerPage svNumber \LispOthello.MarkerPage))))))

(\PV.WriteBadPageTable
  [LAMBDA NIL                                                (* amd " 6-Nov-85 15:58")
    (LET [(BUF (NCREATE (QUOTE VMEMPAGEP]
         (for page in \LispOthello.BadPageTable as i from 0
	    do (PUTBASE BUF (ITIMES i 2)
			  (\LONUM page))
		 (PUTBASE BUF (ADD1 (ITIMES i 2))
			  (\HINUM page)))
         (\PFTransferPage 1 BUF (QUOTE VRW)
			    \LispOthello.Label 1)
         (replace (PhysicalVolumeDescriptor badPageCount) of \LispOthello.PhysicalVolumeRootPage
	    with (LENGTH \LispOthello.BadPageTable))
         (\PV.WritePVRootPage])

(\PV.WritePVRootPage
  (LAMBDA NIL                                                (* ejs: "10-Sep-85 17:26")
    (\PFTransferPage 0 \LispOthello.PhysicalVolumeRootPage (QUOTE VWW)
		     \LispOthello.Label)
    (\PV.UpdateMarkerPages)))
)
(DECLARE: DONTCOPY 
(* FOLLOWING DEFINITIONS EXPORTED)


(DECLARE: EVAL@COMPILE 
[DEFMACRO SwapFIXP (N)
	  (BQUOTE (\MAKENUMBER (\LONUM , N)
			       (\HINUM , N]
[DEFMACRO \PV.SubVolumeDescFromVol# (vol#)
	  (BQUOTE (\ADDBASE (fetch (PhysicalVolumeDescriptor subVolumes)
				   of \LispOthello.PhysicalVolumeRootPage)
			    (TIMES , vol# (MESASIZE SubVolumeDesc]
)
[DECLARE: EVAL@COMPILE 

(MESARECORD MarkerPage ((logical 128 WORD)
			  (physical 128 WORD)))

(MESARECORD PhysicalVolumeSubMarker ((seal WORD)           (* Must be first field)
				       (version WORD)        (* Must be second field)
                                                             (* Information mainly describing the system volume)
				       (pvID VolumeID)
				       (label 40 BYTE)
				       (bootingInfo PVBootFiles)
				       (maxBadPages SWAPPEDFIXP)
                                                             (* bad page table for the physical volume)
				       (labelLength BITS 6)
                                                             (* Length of the label name)
                                                             (* Information for describing the preceding subvolume)
				       (NIL BITS 5)
				       (lvShouldBeScavenged FLAG)
				       (svNumber BITS 4)     (* subvolume ordinal number)
				       (descriptor SubVolumeDesc)))

(BLOCKRECORD PilotDiskAddress ((Head BYTE)
				 (Sector BYTE)
				 (Cylinder WORD)))

(BLOCKRECORD PilotLeaderPage ((seal WORD)
				(nameLength WORD)
				(name BYTE 100)))
]


(* END EXPORTED DEFINITIONS)

)



(* Logical volume functions)

(DEFINEQ

(\LV.DiskFileIDOfBootFile
  (LAMBDA (LVDesc N)                                         (* ejs: "10-Sep-85 00:10")

          (* * Return a pointer to the DiskFileID for the Nth boot file on the logical volume identified by LVDesc)


    (\ADDBASE (fetch (LogicalVolumeDescriptor bootingInfo) of LVDesc)
	      (ITIMES N (MESASIZE DiskFileID)))))

(\LV.DescriptorFromName
  (LAMBDA (volName)                                          (* ejs: "10-Sep-85 00:30")

          (* * returns the lv descriptor for the named lv)


    (bind LVDesc for I from 0 to (SUB1 (ARRAYSIZE \DFSLogicalVolumes))
       do (SETQ LVDesc (ELT \DFSLogicalVolumes I))
	  (COND
	    ((STRING-EQUAL (MKSTRING volName)
			   (fetch (LogicalVolumeDescriptor LVlabel) of LVDesc))
	      (RETURN LVDesc))))))

(\LV.FileDescriptorForBootFile
  [LAMBDA (volName BootFileType)                             (* amd " 2-Dec-85 12:39")

          (* * Find the logical volume of the boot file of type BootFileType. Return the leader page for that file)


    (LET* [(LVDesc (\LV.DescriptorFromName volName))
	   (DiskFileID (\LV.DiskFileIDOfBootFile LVDesc BootFileType))
	   (FileID (fetch (DiskFileID fID) of DiskFileID))
	   (PilotDiskAddress (fetch (DiskFileID da) of DiskFileID))
	   (vol# (COND
		   ((NEQ 0 FileID)
		     (GETHASH LVDesc \DFSLogicalVolumeHash]
          (COND
	    (vol# (replace (FileDescriptor fileID) of \LispOthello.FileDescriptor with FileID)
		  (replace (FileDescriptor volNum) of \LispOthello.FileDescriptor with vol#)
		  (replace (FileDescriptor type) of \LispOthello.FileDescriptor with 
									     tDiagnosticMicrocode)
		  \LispOthello.FileDescriptor])

(\LV.LeaderPageForBootFile
  [LAMBDA (LVDesc BootFileType)                              (* amd " 2-Dec-85 12:42")

          (* * Find the logical volume of the boot file of type BootFileType. Return the leader page for that file)


    (LET* [(DiskFileID (\LV.DiskFileIDOfBootFile LVDesc BootFileType))
	   (FileID (fetch (DiskFileID fID) of DiskFileID))
	   (PilotDiskAddress (fetch (DiskFileID da) of DiskFileID))
	   (vol# (COND
		   ((NEQ 0 FileID)
		     (GETHASH LVDesc \DFSLogicalVolumeHash]
          (COND
	    (vol# (replace (FileDescriptor fileID) of \LispOthello.FileDescriptor with FileID)
		  (replace (FileDescriptor volNum) of \LispOthello.FileDescriptor with vol#)
		  (replace (FileDescriptor type) of \LispOthello.FileDescriptor with 
									     tDiagnosticMicrocode)
		  (\PFGetPage \LispOthello.FileDescriptor 0 (\PFFindPageAddr 
								      \LispOthello.FileDescriptor 0)
				\LispOthello.LeaderPage)
		  \LispOthello.LeaderPage])

(\LV.RenameVolume
  (LAMBDA (LVDesc NewName)                                   (* ejs: "11-Sep-85 00:25")

          (* * Renames an existing logical volume--not even Pilot's Othello lets you do this!)


    (\PFGetMarkerPage LVDesc \LispOthello.MarkerPage)
    (COND
      ((NEQ (fetch (LogicalVolumeSubMarker seal) of (fetch (MarkerPage logical) of 
									  \LispOthello.MarkerPage))
	    \LV.SMSeal)
	(ERROR "LogicalVolumeSubMarker seal is invalid" (fetch (LogicalVolumeSubMarker seal)
							   of (fetch (MarkerPage logical)
								 of \LispOthello.MarkerPage)))))
    (replace (LogicalVolumeDescriptor LVlabel) of LVDesc with NewName)
    (replace (LogicalVolumeSubMarker LVlabel) of (fetch (MarkerPage logical) of 
									  \LispOthello.MarkerPage)
       with NewName)
    (\PFPutLogicalVolumePage LVDesc LVDesc)
    (\PFPutMarkerPage LVDesc \LispOthello.MarkerPage)))

(\LV.ReplaceSubMarkerLabel
  (LAMBDA (LVSubMarker Length MaxChars NewString)            (* ejs: "11-Sep-85 00:31")
    (SETQ NewString (MKSTRING NewString))
    (\MOVEBYTES (fetch (STRINGP BASE) of NewString)
		(fetch (STRINGP OFFST) of NewString)
		(LOCF (fetch (LogicalVolumeSubMarker label) of LVSubMarker))
		0
		(replace (LogicalVolumeSubMarker labelLength) of LVSubMarker with (IMIN Length 
											MaxChars)))
    NewString))

(\VFMGenerateAllFileIDs
  (LAMBDA (vol)                                              (* ejs: " 9-Sep-85 20:53")

          (* * Returns a list of the fileIDs of all the keys in the BTree with type = desiredType)


    (WITH.MONITOR \VFMmonitor (UNINTERRUPTABLY
                                  (\VFMContextSet vol)
				  (bind (currentKey ←(create Key))
				     until (PROGN (replace (Key filePage) of currentKey with MAX.FIXP)
						  (MESASETQ currentKey (fetch (Interval nextKey)
									  of (\VFMGet currentKey 0))
							    Key)
						  (EQP (fetch (Key fileID) of currentKey)
						       \VFMmaxID))
				     collect (CONS (fetch (Key fileID) of currentKey)
						   (fetch (Key type) of currentKey)))))))
)
(DECLARE: DONTCOPY 
(* FOLLOWING DEFINITIONS EXPORTED)


(DECLARE: EVAL@COMPILE 
(DEFMACRO \LVDescFromNumber (N)
	  (BQUOTE (ELT \DFSLogicalVolumes , N)))
(PUTPROPS \LV.FetchSubMarkerLabel DMACRO (= . \PV.FetchSubMarkerLabel))
(DEFMACRO \LV.NameFromLeaderPage (PilotLeaderPage)
	  (BQUOTE (\PFFetchString (LOCF (fetch (PilotLeaderPage name)
					       of , PilotLeaderPage))
				  (LOCF (fetch (PilotLeaderPage nameLength)
					       of , PilotLeaderPage))
				  100)))
)
[DECLARE: EVAL@COMPILE 

(MESARECORD LogicalVolumeSubMarker ((seal WORD)            (* Must be 1st field)
				      (version WORD)         (* Must be 1st field)
				      (labelLength BITS 6)
				      (type BITS 2)
				      (NIL BYTE)
				      (label 40 BYTE)
				      (bootingInfo LVBootFiles)
                                                             (* There's more after this, but we don't care for now)
				      )
				     (ACCESSFNS (LVlabel (\LV.FetchSubMarkerLabel
							     (LOCF (fetch (LogicalVolumeSubMarker
									      label)
								      of DATUM))
							     (fetch (LogicalVolumeSubMarker 
										      labelLength)
								of DATUM)
							     40)
							   (\LV.ReplaceSubMarkerLabel DATUM
											(NCHARS
											  NEWVALUE)
											40 NEWVALUE)))
)

(MESARECORD Index ((key Key)
		     (volumePage SWAPPEDFIXP)))

(MESARECORD Interval ((key Key)
			(volumePage SWAPPEDFIXP)
			(nextKey Key)))

(MESARECORD Key ((fileID SWAPPEDFIXP)
		   (filePage SWAPPEDFIXP)
		   (type WORD)))
]


(* END EXPORTED DEFINITIONS)

)



(* User functions)

(DEFINEQ

(DescribePhysicalVolume
  (LAMBDA NIL                                                (* ejs: " 9-Sep-85 23:16")
    (\PV.MapSubVolumes (FUNCTION (LAMBDA (SVDesc LVDesc)
			   (COND
			     ((NEQ 0 (fetch (SubVolumeDesc nPages) of SVDesc))
			       (printout T "Logical volume " (fetch (LogicalVolumeDescriptor LVlabel)
								of LVDesc)
					 " is "
					 (fetch (SubVolumeDesc nPages) of SVDesc)
					 " pages long ["
					 (fetch (SubVolumeDesc pvPage) of SVDesc)
					 ".."
					 (IPLUS (fetch (SubVolumeDesc pvPage) of SVDesc)
						(fetch (SubVolumeDesc nPages) of SVDesc))
					 "]" T))))))))

(LispOthelloEventFN
  (LAMBDA (EVENT)                                            (* ejs: "10-Sep-85 17:29")
    (SELECTQ EVENT
	     ((NIL AFTERMAKESYS AFTERLOGOUT AFTERSYSOUT AFTERSAVEVM)
	       (\PV.ReadPVRootPage))
	     NIL)))

(PrintLVBootFiles
  (LAMBDA (volName)                                          (* ejs: "10-Sep-85 00:37")

          (* * Print the currently existing boot files on the specified logical volume)


    (LET ((LVDesc (\LV.DescriptorFromName volName)))
         (COND
	   (LVDesc (bind LeaderPage for I from 0 to 3 do (COND
							   ((SETQ LeaderPage (
								 \LV.LeaderPageForBootFile LVDesc I))
							     (PRINTCONSTANT I BootFileTypes T)
							     (printout T ": " (\LV.NameFromLeaderPage
									 LeaderPage)
								       T)))))))))

(PrintPVBootFiles
  (LAMBDA NIL                                                (* ejs: "10-Sep-85 00:41")
    (bind LeaderAndLV for I from 0 to 3 do (COND
					     ((SETQ LeaderAndLV (\PV.LeaderPageForBootFile I))
					       (PRINTCONSTANT I BootFileTypes T)
					       (printout T " (" (fetch (LogicalVolumeDescriptor
									 LVlabel)
								   of (CDR LeaderAndLV))
							 "): "
							 (\LV.NameFromLeaderPage (CAR LeaderAndLV))
							 T))))))

(RenameVolume
  (LAMBDA (OldVolume)                                        (* ejs: "11-Sep-85 00:29")

          (* * Prompts to rename an existing volume)


    (LET ((NewName (PROMPTFORWORD (CONCAT "Rename " OldVolume " to be: ")))
	  (LVDesc (\LV.DescriptorFromName OldVolume)))
         (COND
	   (LVDesc (COND
		     ((AND NewName (EQ (QUOTE Y)
				       (ASKUSER NIL NIL "Are you sure?")))
		       (\LV.RenameVolume LVDesc NewName))))
	   (T (printout T OldVolume " not found!" T))))))

(SetPVBootFiles
  (LAMBDA (volName)                                          (* ejs: "10-Sep-85 01:44")

          (* * Print the currently existing boot files on the specified logical volume)


    (LET ((LVDesc (\LV.DescriptorFromName volName))
	  DidOne)
         (COND
	   (LVDesc (bind LeaderPage for I from 0 to 3
		      do (COND
			   ((SETQ LeaderPage (\LV.LeaderPageForBootFile LVDesc I))
			     (printout T T (\LV.NameFromLeaderPage LeaderPage)
				       T)
			     (COND
			       ((EQ (QUOTE Y)
				    (ASKUSER NIL NIL (CONCAT "Set " (SELECTC I
									     (bftDiagnosticMicrocode
									       
							      "Interlisp or diagnostic microcode")
									     (bftEmulatorMicrocode
									       "Emulator microcode")
									     (bftGerm "germ")
									     (bftPilotBootFile 
										"Pilot boot file")
									     "?? file")
							     " from " volName "? ")))
				 (\PV.SetPVBootFile LVDesc I)
				 (SETQ DidOne T))))))
		   (COND
		     (DidOne (COND
			       ((EQ (QUOTE Y)
				    (ASKUSER NIL NIL "Are you sure? "))
				 (\PV.WritePVRootPage))
			       (T (\PV.ReadPVRootPage))))))
	   (T (printout T "No such volume: " volName T))))))

(ShowBootFileLayout
  (LAMBDA (volName BootFileType)                             (* ejs: " 7-Nov-85 23:39")
    (LET* ((FileDesc (\LV.FileDescriptorForBootFile volName BootFileType))
	   (StartingPage (\PV.DiskPageNumber (fetch (DiskFileID da) of (
									 \LV.DiskFileIDOfBootFile
									       (
									   \LV.DescriptorFromName
										 volName)
									       BootFileType))))
	   (BootFileSize (SUB1 (\PFFindFileSize FileDesc)))
	   (Buffer (NCREATE (QUOTE VMEMPAGEP))))
          (printout T "File pages   --->    Disk pages" T)
          (WITH-RESOURCE label
			 (bind (DiskPage ← StartingPage)
				 (vRunStart ← 0)
				 (pRunStart ← StartingPage) for BootFilePage# from 0
			    to (SUB1 BootFileSize)
			    do 

          (* * Read the next page of the disk)


				 (COND
				   ((EQ (QUOTE OK)
					  (\PFTransferPage DiskPage Buffer (QUOTE VRR)
							     label 1 T))
				     (COND
				       ((AND (EQ 0 (fetch (PilotDiskLabel BootLinkA)
							  of label))
					       (EQ 0 (fetch (PilotDiskLabel BootLinkB)
							  of label)))

          (* * No boot link. We're still in a run)


					 (add DiskPage 1))
				       (T 

          (* * End of a run)


					  (printout T "[" vRunStart ".." BootFilePage# "] --> [" 
						    pRunStart ".." DiskPage "]" T)
					  (COND
					    ((AND (EQ -1 (fetch (PilotDiskLabel BootLinkB)
								of label))
						    (EQ -1 (fetch (PilotDiskLabel BootLinkA)
								of label)))
					      (RETURN)))
					  (SETQ vRunStart (ADD1 BootFilePage#))
					  (SETQ pRunStart (SETQ DiskPage
					      (\PV.DiskPageNumber (\MAKENUMBER
								      (fetch (PilotDiskLabel 
											BootLinkB)
									 of label)
								      (fetch (PilotDiskLabel 
											BootLinkA)
									 of label))))))))
				   (T (ERROR "Bad disk read"))))))))

(MakePageBad
  [LAMBDA (physicalPage)                                     (* amd " 6-Nov-85 16:36")
    (LET ((countBad (fetch (PhysicalVolumeDescriptor badPageCount) of 
							      \LispOthello.PhysicalVolumeRootPage)))
         (if (ILESSP countBad (fetch (PhysicalVolumeDescriptor maxBadPages) of 
							      \LispOthello.PhysicalVolumeRootPage))
	     then (if (MEMB physicalPage (\PV.ReadBadPageTable))
			then "Already in bad page table"
		      else (MERGEINSERT physicalPage \LispOthello.BadPageTable)
			     (\PV.WriteBadPageTable)
			     (printout PROMPTWINDOW "You should scavenge " (fetch (
LogicalVolumeDescriptor LVlabel) of (\PV.LVDescFromPageNumber physicalPage))
				       T)
			     physicalPage)
	   else "Bad page table full!"])

(UnmakePageBad
  [LAMBDA (physicalPage)                                     (* amd " 6-Nov-85 16:43")
    (if (MEMB physicalPage (\PV.ReadBadPageTable))
	then (SETQ \LispOthello.BadPageTable (REMOVE physicalPage \LispOthello.BadPageTable))
	       (\PV.WriteBadPageTable)
	       (printout PROMPTWINDOW "You should scavenge " (fetch (LogicalVolumeDescriptor 
											  LVlabel)
								of (\PV.LVDescFromPageNumber
								       physicalPage))
			 T)
	       physicalPage
      else "Not in bad page table."])

(ListBadPages
  [LAMBDA NIL                                                (* amd " 6-Nov-85 16:43")
    (\PV.ReadBadPageTable])
)

(ADDTOVAR AROUNDEXITFNS LispOthelloEventFN)
(\PV.ReadPVRootPage)
(PUTPROPS LISPOTHELLO COPYRIGHT ("Xerox Corporation" 1985))
(DECLARE: DONTCOPY
  (FILEMAP (NIL (3905 14085 (ShowVMemRunTable 3915 . 6081) (\PV.DiskFileIDOfBootFile 6083 . 6332) (
\PV.DiskPageNumber 6334 . 6836) (\PV.FetchSubMarkerLabel 6838 . 7334) (\PV.LVDescFromDiskAddress 7336
 . 7534) (\PV.LVDescFromPageNumber 7536 . 8100) (\PV.LeaderPageForBootFile 8102 . 9258) (
\PV.MapSubVolumes 9260 . 9746) (\PV.ReadBadPageTable 9748 . 10359) (\PV.ReadPVRootPage 10361 . 10936) 
(\PV.SetPVBootFile 10938 . 11299) (\PV.UpdateMarkerPages 11301 . 13169) (\PV.WriteBadPageTable 13171
 . 13825) (\PV.WritePVRootPage 13827 . 14083)) (15728 20933 (\LV.DiskFileIDOfBootFile 15738 . 16111) (
\LV.DescriptorFromName 16113 . 16615) (\LV.FileDescriptorForBootFile 16617 . 17579) (
\LV.LeaderPageForBootFile 17581 . 18631) (\LV.RenameVolume 18633 . 19615) (\LV.ReplaceSubMarkerLabel 
19617 . 20120) (\VFMGenerateAllFileIDs 20122 . 20931)) (22554 30024 (DescribePhysicalVolume 22564 . 
23240) (LispOthelloEventFN 23242 . 23489) (PrintLVBootFiles 23491 . 24094) (PrintPVBootFiles 24096 . 
24610) (RenameVolume 24612 . 25157) (SetPVBootFiles 25159 . 26447) (ShowBootFileLayout 26449 . 28476) 
(MakePageBad 28478 . 29313) (UnmakePageBad 29315 . 29880) (ListBadPages 29882 . 30022)))))
STOP