// Tfs.d - definitions file for driving the Trident with TFS // Copyright Xerox Corporation 1979, 1980 // Last modified January 31, 1980 4:43 PM by Taft // Format of file DiskDescriptor: // Data Page 1: This is mostly empty. First lTFSKDHeader words have the // initial portion of the TFSKD structure recorded -- remainder empty // Data Pages 2 through n (n is at most 5). These have bit table // (KDH.diskBTSize total words). // The virtual disk addresses of all data pages are kept in the // TFSKD structure (VDAdiskDD) so they can be referenced directly. manifest [ // low memory cells of interest DAstart = #420 // display location // disk accessing constants (same for BFS and TFS) lFID = 3 // length of a FID // TFS file-related constants TFSmNDisks=1 // possible number of disks per bit table TFSmNTracks=815 // number of tracks (cylinders) T300mNVTracks = 383 // max number of tracks addressable on T-300 // using virtual disk addresses T80mNHeads=5 // number of heads on T-80 T300mNHeads = 19 // number of heads on T-300 TFSmNSectors=9 // number of sectors TFSwordsPerPage = 1024 // words in data block of sector TFSlnWordsPerPage = 10 // maximum number of virtual pages in a file system T80mNVPages = TFSmNTracks*T80mNHeads*TFSmNSectors T300mNVPages = T300mNVTracks*T300mNHeads*TFSmNSectors packID = 0 // part of FID // definitions for bit table format lengthTFSDDpreamble = 2 // num pages in Disk Descriptor ahead of BT lengthTFSBT = (T300mNVPages-1) rshift (TFSlnWordsPerPage+4) +1 // max length of TFS Bit Table (pages) ] //used by disk bit table routines to compute bit locations structure VDA: // Virtual Disk Address [ wordNum bit 12 = // word index in whole file [ pageNum bit 12-TFSlnWordsPerPage wordNumInPage bit TFSlnWordsPerPage ] bitNum bit 4 // bit index ] // Operations defined on a Disk Descriptor Manager (DDMgr) object. // See TfsDDMgr.bcpl for details. structure DDMgrOperations: [ OpenDD word // Call0 LockDD word // Call1 ReadDDPage word // Call2 UnlockDD word // Call3 FlushDD word // Call4 CloseDD word // Call5 DestroyDDMgr word // Call6 ] //Trident disk hardware-related definitions manifest [ KBLK = #640 // Trident controller CB address dcbID = #122645 // disk command seal // Mask bits for status word DSTrestoreBits=#160100 DSTerrorBits=#177717 // ignore ReadOnly and Offset // Status word values DSTfreeStatus=#17 // init state set by software DSTgoodStatus=1 // set by microcode after transfer // Hardware command bit assignments CheckData = #4000 WriteBit = #200 ReadBit = #100 HeadSelect = #4 ReZero = #12 CheckReset = #10 // Extended memory bank selection in command word selectBank0 = #0 selectBank1 = #40000 selectBank2 = #100000 selectBank3 = #140000 // Hardware disk commands used in conjunction with above diskRead = ReadBit + HeadSelect diskWrite = WriteBit + HeadSelect diskCheck = CheckData + ReadBit + HeadSelect diskReset = CheckReset diskRestore = ReZero diskNoop = HeadSelect // Special disk command for verifying free labels: DCreadLnD=diskMagic+8 //Check header, read label, no data DCreadnD=diskMagic+9 //Check header, check label, no data DCwriteLnD=diskMagic+10 //check header, write label, no data ] // Disk status word. See hardware manual for detailed definitions structure DST: [ Status word = [ Errors bit 10 = [ // * = may require a restore to clear SeekInc bit // 100000 * CylOvfl bit // 40000 -misnamed, really bad head # DeviceCk bit // 20000 * NotSelected bit // 10000 NotOnLine bit // 4000 NotReady bit // 2000 SecOvfl bit // 1000 DataLate bit 2 = [ WrLate bit // 400 RdLate bit // 200 ] CompErr bit // 100 ] ReadOnly bit // 40 Offset bit // 20 ECCerror bit = // 10 -- reported only in CB Sector bit 4 // -- reported only in #643 ] ] // Trident Controller Control Block format structure KBLK: [ ptr word // KBLK+0 = #640 = pointer to command block drive word // KBLK+1 = #641 = number of currently selected drive track word // KBLK+2 = #642 = track number in last command @DST // KBLK+3 = #643 = status at last sector pulse aborted word // KBLK+4 = non-zero if a command was aborted ] //Header,Label,Data formats on disk // Hardware disk address - same as disk address used in the KCB structure DA: [ track word head byte sector byte ] // Disk header - must be the same as DA structure DH: @DA manifest lDH = size DH/16 // Disk label. // The last two words must be the next sector address in DH format // (used for chaining operations) // *=set by DoDiskCommand // #=constant for all pages structure DL: [ fileId word lFID // #* packID word // #* numChars word // between 0 and charsPerPage inclusive. // ne charsPerPage only on last page pageNumber word // * page number in file of this page previous @DH // disk address of previous file page, or eofDA next @DH // disk address of next file page, or eofDA ] manifest lDL=size DL/16 // Disk command block. // one for each sector transfer structure KCB: [ diskAddress @DH = @DH // +0 + 1 drive word // +2 nextKCB word // +3 ID word // +4 command seal CommH word // +5 header command block CountH word // +6 AddrH word // +7 ECC0H word // +10 ECC1H word // +11 StatusH @DST // +12 CommL word // +13 label command block CountL word // +14 AddrL word // +15 ECC0L word // +16 ECC1L word // +17 StatusL @DST // +20 CommD word // +21 data command block CountD word // +22 AddrD word // +23 ECC0D word // +24 ECC1D word // +25 StatusD @DST // +26 endWord word // +27 blank word // +30 interrupt bits when implemented normalWakeups word // +31 errorWakeups word // +32 ] manifest lKCB=size KCB/16 // Command format for each block within a sector // used to fill in CB structure KCBblock : [ Comm word Count word Addr word ECC0 word ECC1 word Status word ] manifest lKCBbl=size KCBblock/16 // TFS specialization of the Disk CBZ structure TFSCBZ: [ @CBZ // standard part CBs word 0 // * as many CBs as will fit start here ] manifest lTFSCBZ = size TFSCBZ/16 // fixed part of CBZ // each CBZ contains a CB for each possible transfer enqueued // the label must come first followed by the DCB (for chaining) // a free CB must have status=DSTfreeStatus (initialization does that) // *=initialized by InitializeCbStorage; everything else is zeroed structure CB: [ label @DL // label (10 words) @KCB // hardware oriented control block (27 words) truePageNumber word // 'variable' part of the cb ends here // remaining words are not zeroed by TFSGetCb cbz word // * vDiskAddress word // VDA for this xfer (offset = 38.) nextCB word // * pointer to next CB on CBZ queue ] manifest [ lCB = size CB/16 lVarCB = offset CB.cbz/16 CBzoneLength = lTFSCBZ+6*lCB //6 CBs required to run at disk speed ] // DSK structure for Trident // First, the local definitions for Trident only: // first lTFSKDHeader words are read in from disk at normal startup manifest TFSKDversion=2 structure TFSKD: [ @KDH // standard 1st part version word // version number of this DiskDescriptor model word // disk model (80 = T-80, 300 = T-300) packID word // field setup when disk initialized VDAdiskDD↑1,lengthTFSBT+1 word // VDAs of the data part of DD firstVTrack word // first track used in file system nVTracks word // number of tracks used in file system nTransfers word 2 // total number of transfers on this disk nErrors word 2 // total number of errors -- see TfsGetCb nECCErrors word 2 // total number of ECC errors encountered nECCFixes word 2 // total number of times recovery successful nRestores word 2 // number of "restore" operations done nUnRecov word 2 // number of unrecoverable errors nBTErrors word 2 // number of bit table discrepancies lastPageAlloc word // last VDA allocated -- for biasing search // words beyond here are not saved on the disk initmode word // nonzero if permitted to create new files zone word // zone of this DSK ddMgr word // pointer to DiskDescriptor Manager object fpTFSSysDirblk word lFP // storage for FP fpTFSDDblk word lFP // storage for FP fpTFSWDblk word lFP // storage for FP WDNameblk word maxLengthFnInWords // storage for name ] manifest lTFSKDHeader = (offset TFSKD.initmode/16) // extended version of the disk structure structure TFSDSK: [ @DSK @TFSKD ] manifest lTFSDSK = size TFSDSK/16 // TFSDSK offsets known to TfsA.Asm compileif offset TFSDSK.nHeads/16 ne 26 % offset TFSDSK.nSectors/16 ne 27 % offset TFSDSK.firstVTrack/16 ne 48 % offset TFSDSK.nVTracks/16 ne 49 then [ Barf("TFSDSK offsets wrong") ] // bad page list (on physical page 0 of pack) structure BPL: [ seal word // indicates presence of bad page list nBadPages word // number of bad pages da↑0,0 @DA // real disk addresses of bad pages ] manifest bplSeal = #123456 // error codes manifest [ ecOsVersion = 2403 ecTfsQueue = 2404 ecNoCreationAbility = 2405 ecBadAction = 2406 ecBadBtPage = 2407 ecEssentialFile = 2408 ecBadAssignPage = 2409 ecReadOnly = 2410 ecDriveHung = 2411 ecUnRecovDiskError = 2412 ecDiskFull=2413 ]