// BFS.D -- Basic File System for Diablo disk controller// 	Origial design by Butler Lampson// 	Elaborated by Bob Sproull, David Boggs, and Ed Taft// Copyright Xerox Corporation 1979// Last modified December 31, 1979  4:49 PM by Boggs// Must be preceded by:// get "AltoFileSys.d"// get "Disks.d"manifest[// Shape of a Diablo diskBFSmNDisks = 1BFS31NTracks = 203BFS44NTracks = 406BFSmNHeads = 2BFSmNSectors = 12BFSlnWordsPerPage = 8BFSwordsPerPage = 256BFSmaxDDPage = 17	// 1 for the KDH + 16 for the bit table// Defined in AltoDefs.d:// diskCommand = 521b// diskStatus = 522b// diskAddress = 523b]// used by Assign/ReleaseDiskPage to compute bit locations//----------------------------------------------------------------------------structure VDA://----------------------------------------------------------------------------[wordNum bit 12 =	// word index in whole file   [   pageNum bit 12-BFSlnWordsPerPage   wordNumInPage bit BFSlnWordsPerPage   ]bitNum bit 4		// bit index]//----------------------------------------------------------------------------structure DST:		// Disk Status.  See Alto Hardware Manual//----------------------------------------------------------------------------[sector bit 4done bit 4seekFail bitseeking bitnotReady bitdataLate bitnoTransfer bitchecksumError bitfinalStatus bit 2]manifest[// disk status bitsdone = 7400BseekFail = 200Bseeking = 100BnotReady = 40BdataLate = 20BnoTransfer = 10BchecksumError = 4// final status valuesbadSector = 3checkError = 2hardwareError = 1// goodStatus = 0DSTdoneBits = doneDSTerrorBits = seekFail + notReady + dataLate + checksumError + badSectorDSTgoodStatusMask = DSTerrorBits % DSTdoneBitsDSTgoodStatus = doneDSTfreeStatus = 400BDSTfakeError = done + hardwareError]// Header, Label, and Data formats on disk//----------------------------------------------------------------------------structure DA:		// Disk Address (real)//----------------------------------------------------------------------------[sector bit 4track bit 9		// misnamed.  really cylinder addresshead bit 1disk bit 1restore bit 1]//----------------------------------------------------------------------------structure DH:		// Disk Header//----------------------------------------------------------------------------[packID word		// must be 0diskAddress @DA]//----------------------------------------------------------------------------structure FID:		// File Identifier (used only on a disk label)//----------------------------------------------------------------------------[version wordserialNumber @SN]manifest lFID = size FID/16//----------------------------------------------------------------------------structure DL:		// Disk Label. *=set by DoDiskCommand//----------------------------------------------------------------------------[next word		// disk address of next file page, or eofDAprevious word		// disk address of previous file page, or eofDAblank wordnumChars word		// between 0 and charsPerPage inclusive.			// ne charsPerPage only on last pagepageNumber word		// * leader is page 0, first data page is page 1fileId @FID		// *]manifest lDL = size DL/16// Note: the big disks on D0 and Dorado are partitioned into a number// of simulated Diablo disks.  The partitions are numbered 1 through 7;// partition 0 refers to the current "default" partition known about// by the microcode.  A BFSDSK object for a particular partition may// be constructed by passing the partition number embedded in the// driveNumber argument of BFSInit or BFSNewDisk.  The partition is// passed to the microcode embedded in the command block seal.//----------------------------------------------------------------------------structure DriveNumber:	// interpretation of BFSDSK.driveNumber cell//----------------------------------------------------------------------------[blank bit 12partition bit 3drive bit 1]//----------------------------------------------------------------------------structure DC:		// disk command//----------------------------------------------------------------------------[seal bit 8 =		// must be 110B on an Alto   [			// for simulated multiple disks on D0 and Dorado:   shortSeal bit 5	// must be 11B   partition bit 3	// 0: default; 1-7: specific partition number   ]action bit 8 =   [   headerAction bit 2   labelAction bit 2   dataAction bit 2   seekOnly bit 1   exchangeDisks bit 1	// controller inverts KCB.diskAddress if set   ]]manifest[// disk commands as full-word constantscommandSeal = 44000BreadHLD = 44000B	// Read  Header, Read  Label, Read  DatareadLD = 44100B		// Check Header, Read  Label, Read  DatareadD = 44120B		// Check Header, Check Label, Read  DatawriteHLD = 44250B	// Write Header, Write Label, Write DatawriteLD = 44150B	// Check Header, Write Label, Write DatawriteD = 44130B		// Check Header, Check Label, Write DataseekOnly = 44002B	// no transfer]// disk command block.//	*=set by DoDiskCommand,//	$=defaulted by DoDiskCommand if 0//----------------------------------------------------------------------------structure KCB://----------------------------------------------------------------------------[link word		// * -> next KCB or 0 if end of chainstatus @DST		// set when command is completedcommand @DC		// *headerAddress word	// * memory addresses for header recordlabelAddress word	// $ memory addresses for label recorddataAddress word	// * memory addresses for data recordnormalWakeups word	// $errorWakeups word	// $header @DH =   [   blank word   diskAddress @DA	// * if DA argument ne fillInDA   ]]manifest lKCB = size KCB/16// BFS specialization of the Disk CBZ//----------------------------------------------------------------------------structure BFSCBZ://----------------------------------------------------------------------------[@CBZ =			// standard -- see Disks.d   [			// see comment below   blank word offset CBZ.errorCount/16   sawCheckError bit 1   bfsErrorCount bit 15   ]CBs word 0		// * as many CBs as will fit start here]manifest lBFSCBZ = size BFSCBZ/16	// fixed part of CBZ// The high bit of CBZ.errorCount is borrowed by the BFS and used// as a flag to record the occurance of a check error.  This permits// BFSDoDiskCommand to tell BFSActOnPages that an error was a check error.// This makes the returnOnCheckError argument work.// each CBZ contains a CB for each possible transfer enqueued// the KCB must come first followed by the label (for chaining)// a free CB must have status = DSTfreeStatus (initialization does that)// *=initialized by InitializeCbStorage; everything else is zeroed//----------------------------------------------------------------------------structure CB://----------------------------------------------------------------------------[// The KCB must come first@KCB			// * free CB must have status = DSTgoodStatuslabel @DLtruePageNumber word// remaining words are not zeroed by BfsGetCbcbz word		// * -> CBZ which owns this cbnextCB word		// * -> next CB on CBZ queue]manifest[lCB = size CB/16lVarCB = offset CB.cbz/16CBzoneLength = lBFSCBZ+3*lCB  // 3 CBs required to run disk at full speed]//---------------------------------------------------------------------------structure BFSDSK:	// Extended version of the DSK structure//---------------------------------------------------------------------------[@DSK			// standard -- see Disks.d@KDH			// standard -- see AltoFileSys.dinitmode word		// nonzero if permitted to create/delete fileszone word		// zone from which this DSK was allocatedddMgr word		// -> disk descriptor managerlastPageAlloc word	// last VDA allocated -- for biasing searchfpBFSSysDirblk word lFP	// storage for FPfpBFSDDblk word lFP	// storage for FPfpBFSWDblk word lFP	// storage for FPWDNameblk word maxLengthFnInWords  // storage for workingDir nameVDAdiskDD^1,BFSmaxDDPage word	// VDAs of the data part of DD]manifest lBFSDSK = size BFSDSK/16// 'DiskDescriptor' contains a KDH (16 words) followed by a variable// number of pages containing the bit table.  The number of valid// words in the bit table is given in KDH.diskBTsize.manifest[// Used by Assign/ReleaseDiskPage to skip over the KDH which// comes before the bit table in the DiskDescriptor file.bitTableBias = lKDHeader lshift 4// Error codes registered in Sys.errors:ecUnRecovDiskError = 1101ecDiskFull = 1102ecBadAction = 1103ecBfsQueue = 1104ecNoCreationAbility = 1105ecEssentialFile = 1106ecBadAssignPage = 1107ecBadBtPage = 1108]