*----------------------------------------------------------- Title[PilotDiskDefs.mc...February 12, 1983 1:23 PM...Taft]; * Definitions for Dorado disk microcode for Pilot *----------------------------------------------------------- * Note: the default initializations in the following record definitions * indicate values that must be supplied by the software. * CSB: LONG POINTER TO ControllerStatusBlock = LOOPHOLE[177520B]; * ControllerStatusBlock: TYPE = MACHINE DEPENDENT RECORD [ * next is interpreted only if it is odd. When an error occurs, microcode * makes next even, such that (next+1) points to the IOCB that suffered * the error. Disk activity thus freezes until the software resets next. MC[CSB.next, 177520]; * next: POINTER TO IOCB, MC[CSB.interruptMask, 177521]; * interruptMask: CARDINAL, MC[CSB.drive, 177522]; * drive: CARDINAL, -- most recently accessed * If cylinder is negative, the next command will initiate a restore. MC[CSB.cylinder, 177523]; * cylinder: CARDINAL, -- emulated * ... ]; -- Other stuff not used by microcode * -- IOCBs must be odd-word aligned! * IOCB: TYPE = MACHINE DEPENDENT RECORD [ MC[IOCB.next, 0]; * next: POINTER TO IOCB, * seal is zeroed when command is done; this is how software detects completion MC[IOCB.seal, 1]; * seal: CARDINAL ← 125377B, MC[IOCBSealValue, 125377]; MC[IOCB.drive, 2]; * drive: CARDINAL, * pageCount is decremented after each page successfully transferred. * Thus pageCount=0 upon completion indicates that no errors occurred. MC[IOCB.pageCount, 3]; * pageCount: CARDINAL, MC[IOCB.command, 4]; * command: DiskCommand: * diskAddress is incremented after each page successfully transferred, and * copied into diskHeader for checking purposes. After a header read, * diskHeader contains the header read from the disk. MC[IOCB.diskAddress, 5]; * diskAddress: DiskAddress, MC[IOCB.diskHeader, 7]; * diskHeader: DiskAddress, MC[IOCB.headerPtr, 11]; * headerPtr: LONG POINTER ← @iocb.diskHeader, MC[IOCB.headerECC, 13]; * headerECC: LONG CARDINAL, MC[IOCB.headerStatus, 15]; * headerStatus: DiskStatus, * labelPtr should point to IOCB.diskLabel when checking or writing so that * updated values are used during runs of pages. During checking, the first * 8 words of the label are checked and the last 2 are read. MC[IOCB.labelPtr, 16]; * labelPtr: LONG POINTER ← @iocb.diskLabel, MC[IOCB.labelECC, 20]; * labelECC: LONG CARDINAL, MC[IOCB.labelStatus, 22]; * labelStatus: DiskStatus, * dataPtr is incremented by 400B after each page successfully transferred, * if command.incrementDataPointer = TRUE. MC[IOCB.dataPtr, 23]; * dataPtr: LONG POINTER, MC[IOCB.dataECC, 25]; * dataECC: LONG CARDINAL, MC[IOCB.dataStatus, 27]; * dataStatus: DiskStatus, * Microcode updates this copy of the label after each page successfully * transferred. IOCB.labelPtr should point here during checking and writing. MC[IOCB.diskLabel, 30]; * diskLabel: PilotDisk.Label ]; MC[sizeIOCB, 42]; * Pilot standard disk address * DiskAddress: TYPE = MACHINE DEPENDENT RECORD [ * cylinder: CARDINAL, * head, sector: [0..377B]]; * Dorado disk command (hardware format except for incrementDataPtr) * Action: TYPE = {none, write, check, read}; * DiskCommand: TYPE = MACHINE DEPENDENT RECORD [ * incrementDataPtr: BOOLEAN, * unused: [0..177B] ← 0, * header: Action, * label: Action, * data: Action, * unused: Action ← none ]; * DiskStatus: TYPE = MACHINE DEPENDENT RECORD [ * -- following are hardware conditions reported directly from the controller: * * seekInc: BOOLEAN, * * headOvfl: BOOLEAN, * * devCheck: BOOLEAN, * * notSelected: BOOLEAN, * * notOnLine: BOOLEAN, * * notReady: BOOLEAN, MC[DS.sectorOvfl, 1000]; * sectorOvfl: BOOLEAN, * * fifoUnderflow: BOOLEAN, * * fifoOverflow: BOOLEAN, MC[DS.checkErr, 100]; * checkErr: BOOLEAN, -- = ReadDataErr * * readOnly: BOOLEAN, * * cylOffset: BOOLEAN, * * iobParityErr: BOOLEAN, * * fifoParityErr: BOOLEAN, * -- following are microcode-detected conditions: MC[DS.eccErr, 2]; * eccErr: BOOLEAN, MC[DS.sectorSearchErr, 1]; * sectorSearchErr: BOOLEAN ]; * Excerpt from Pilot Label record, showing fields that must be * modified by the microcode during runs of pages. * Label: TYPE = MACHINE DEPENDENT RECORD [ * * fileID: File.ID, MC[Lab.filePageLo, 5]; * filePageLo: CARDINAL ], -- increment this MC[Lab.filePageHi, 6]; * filePageHi: [0..177B], * * pad1: [0..77B], MC[Lab.fileFlags, 7]; * fileFlags: [0..7B], -- zero these * * type: File.type, MC[Lab.bootChainLink, 10]; * bootChainLink: DiskAddress]; MC[sizeHeader, 2]; MC[sizeLabel, 12]; MC[sizeData, 400]; % The Dorado Trident disk is formatted as 815 cylinders, 5 heads, 28 sectors. We use only 28 of the usable 29 sectors, because addressing the 29th is somewhat tricky. For compatibility with partitioning of Dorado disks for Alto emulation (one partition on each surface of the disk), we emulate a disk that has a different shape from the real disk: 4075 (=5*815) cylinders, 1 head, 28 sectors. This is so that a partition occupies a contiguous interval of virtual addresses under Pilot's virtual-to-real disk address mapping, which increments heads before cylinders. Thus: real cylinder = emulated cylinder MOD 815 real head = emulated cylinder / 815 real sector = emulated sector Note that the head number in the emulated disk address is ignored. Note: the foregoing applies only to drive 0. For drives other than 0, the cylinder, head, and sector are used as-is in the conventional way. However, since the microcode does not know whether the drive is a T-80 or a T-300, it never increments the cylinder number; software must either avoid issuing commands for runs that cross cylinder boundaries or be prepared to handle the error reported by the drive when the head number becomes too large. The reason the microcode has to know about all this garbage is that it needs to be able to increment the disk address during runs of pages. % * Disk format parameters: MC[nCylinders, 1457]; * = 815 MC[nSectors, 34]; * = 28 Set[staggerSectors, 1]; * Stagger sectors on adjacent cylinders * (done only on drive 0)