// 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 22, 1979 1:17 AM 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 + dataLate ] // 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 ]