%RDCDefs.mc inserted by both RDC.Mc (PilotD0 and Initial) and SA4000Loader.Mc (Initial) Ed Fiala 3 June 1983: Replace RecalSeekLimitHi/Lo by the integer RecalSeekLimit; remove Bravo formatting; use RV2 and RV4. Ev Neely October 24, 1980: Fix RecalSeekLimit. Ev Neely 10 July 1980: Put definition of RdcIOCBclientLabel back in defs and restore original name of RdcIOCBdisk because SA4000Loader.mc uses them. Ev Neely 30 June 1980: Changes in support of 48 bit processor-ID and miscellaneous IOCB format changes. Ev Neely 19 June 1980: Added constant in support of counting servicelates for test purposes. Ev Neely 13 June 1980: Fix for AR4320 uses previously unused register for RdcRecalSeekCount, defines RdcRecalSeekLimit and RdcRecalError. Jim Frandeen 16 February 1980: Use two banks of registers to improve performance. Jim Frandeen 20 January 1980: for new D0Lang. Jim Frandeen 25 December 25 1979: for runs of pages and Version5 of D0Lang. % SetTask[RdcTask]; *currently 10b = 8d *Register definitions for the RDC task. Set[RdcRegBase,And[60,LShift[RdcTask,4]]]; *Registers 0 and 1 are destroyed by NotifyInterrupt on sector wakeups. RV[RdcTemp,Add[RdcRegBase,0]]; *HeadSettleCount counts sectors until the heads settle after a seek. RV[RdcHeadSettleCount,Add[RdcRegBase,1]]; *The next two registers are loaded together from the CSB. NextIOCB points to *the IOCB of the current command. Deferring will be -1 if an error has been *reported that has not yet been processed by the client. We stop processing *IOCBs until Poll sets this back to zero. RV2[RdcNextIOCB,RdcDeferring,Add[RdcRegBase,2]]; *These four are loaded-from/stored-in the IOCB together. DataPtr (in x and x) *points to the data specified in the IOCB. IncrementDataPtrFlag is loaded *from the operation-command word of the IOCB. If negative, DataPtr must be *incremented after each page transferred. PageCount contains the number of *pages in the run. RV4[RdcDataPtr,RdcDataPtr1,RdcIncrementDataPtrFlag,RdcPageCount,Add[RdcRegBase,4]]; *The following two registers must be together and QUADWORD aligned. They are *loaded together from the IOCB and stored into the IOCB with a PStore4. *Cylinder contains the cylinder address for the current command. HeadSector *contains the head and sector address of the current command. RV2[RdcCylinder,RdcHeadSector,Add[RdcRegBase,10]]; *Command is the command to be executed. RV[RdcCommand,Add[RdcRegBase,12]]; *RecalSeekCount limits the number of seeks during Recals. RV[RdcRecalSeekCount,Add[RdcRegBase,13]]; *These four are loaded together from the IOCB. RdcFileFlags contains 3 flag *bits which must be cleared in computing the next page label for runs of *pages. FilePageLo is used to increment the file page number in the label *when one IOCB is used for multiple page accesses. RdcPackedLabel7 and *RdcPackedLabel8 are loaded from the packed label to permit a PStore4 at *RdGoodCompletion. RV4[RdcFileFlags,RdcFilePageLo,RdcPackedLabel7,RdcPackedLabel8,Add[RdcRegBase,14]]; *IOCBptr points to the IOCB of the current command. It is used with ZeroBase *as a base register to address the first 16 words of the IOCB. *ZeroBase is used for memory commands to fetch and store data in the CSB and *the IOCB. Since these control blocks are always in low memory, T is used as *the address. Since this is an odd base register, ZeroBase OR 1 is the same *register. RV2[RdcIOCBptr,RdcZeroBase,Add[RdcRegBase,20]]; *IOCB16Ptr is used with the next register as a base register to address the *second 16 word block of the IOCB. RV2[RdcIOCB16Ptr,RdcIOCB16ZeroBase,Add[RdcRegBase,22]]; *DiskAddressPtr points to CSB.diskAddress[current drive]. It is used to *update CSB.diskAddress when the drive changes and also to see if the drive *has changed since the last command. It is used as a base register with the *next register. RV2[RdcDiskAddressPtr,RdcDiskAddressZeroBase,Add[RdcRegBase,24]]; *CSBptr points to the Controller Status Block. RV2[RdcCSBptr,RdcCSBzeroBase,Add[RdcRegBase,26]]; *These two are stored together into the IOCB. RdcDiskStatus contains the *state of the Controller. It is Input at each sector wakeup and when an *error is detected. CompletionCode is one of the IOCB states described below. *At RdStoreErrorStatus they are formed into a single word in RdcDiskStatus *and RdcCompletionCode is set to 0 to convert it into the two word status *needed by the head. RV2[RdcDiskStatus,RdcCompletionCode,Add[RdcRegBase,30]]; *CurrentCylinder contains the cylinder address of the selected drive; -1 *means this drive must be recalibrated. RV[RdcCurrentCylinder,Add[RdcRegBase,32]]; *DriveHead is used to select the drive and head of the current drive. RV[RdcDriveHead,Add[RdcRegBase,33]]; *SectorTimeOutCount is used to count sectors until timeout for states *DriveChange, SeekWait, and SectorWait. RV[RdcSectorTimeOutCount,Add[RdcRegBase,34]]; *NewCylinder will be -1 if we have to seek one cylinder after a page transfer *during a run of pages; otherwise it will be zero. RV[RdcNewCylinder,Add[RdcRegBase,35]]; *CurrentSector contains the current sector number of the current drive *selected. It is updated at each sector wakeup. RV[RdcCurrentSector,Add[RdcRegBase,36]]; *SeekCommand is only used to contain the command for seeking. RV[RdcSeekCommand,Add[RdcRegBase,37]]; *Constants MC[RdcAllowTask,100000]; *To allow task when returning from NotifyInterrupt MC[RdcBit0,100000]; MC[RdcHead7,3400]; *Head 7 in disk address MC[RdcSectorsPerTrack,33]; *The following definitions are for the Controller registers: Set[RdcAddr,LShift[RdcTask,4]]; *The device address of the RDC Set[RdcGeneralReset,0]; *General Reset Set[RdcStatus,1]; *Controller and drive status Set[RdcInputBuffer,17]; *This register presents Buffer[RdcMemBuffAdr]. Set[RdcInput,Add[RdcAddr,17]]; *Complete device address for above. Set[RdcDrive/Head,1]; *Drive in bits 12-13 (10-11D), Head in bits 14-17 (12-15D) Set[RdcErrorReset,2]; *Error Reset (data is ignored) Set[RdcDevOp,3]; *Disk commands and allow wake bit Set[RdcOutputBuffer,4]; *Data loaded into Buffer[RdcMemBufAddr]. Set[RdcOutput,Add[RdcAddr,4]]; *Complete device address for above. Set[RdcMemBuffAdr,6]; *Current pointer into the RDC's data buffer. Set[RdcPrimeIData,7]; *This register must be accessed by OUTPUT before *reading the first word of each sector from the *RdcBuffer. *The following definitions are for the DevOpReg: MC[RdcAllowWake,4000]; *Allow wake bit must be set at each Output if wakeups *are to be enabled. MC[RdcAllowWakeAndSeekDirection,5000]; MC[RdcSeekBits,3000]; *Seek command bits 5-6 MC[RdcReadWriteBits,377]; *Read-write bits 10-17 MC[RdcSeek-D,6000]; *Seek command in negative direction (outward toward *lower track numbers) plus allow wake. MC[RdcSeek+D,7000]; *Seek command in positive direction (inward toward *higher track numbers) plus allow wake. MC[RdcWriteHeader,200]; *Write header MC[RdcDataWriteOrVerify,5]; MC[RdcLabelReadOrVerify,30]; MC[RdcReadData,2]; *The following definitions are for the RdcStatus word: MC[RdcDevSelOK,20]; *Device is selected and ready. MC[RdcSeekComplete,40]; MC[RdcTrack0,100]; MC[RdcServiceLate,2000]; MC[RdcRateError,400]; MC[RdcSector0,200]; *Physical sector 0 MC[RdcErrorBitsHigh,400]; *RateError MC[RdcErrorBitsLow,17]; *BufErr, RdErr, WriteFault, Ofault *The following definitions are for offsets in the IOCB: *Microcode needs the IOCB to be on a 16 word boundary: *Microcode needs this to be first in the IOCB: *Beginning of operation within IOCB: *Disk address specified by client used for the initial seek address. It *almost always duplicates RdcIOCBClientHeader below, which is sent to the *disk for verification. The head sometimes makes them different during an *attempt to clarify the nature of errors. MC[RdcIOCBoperationClientHeader,0]; MC[RdcIOCBLabelPtr,2]; *Ptr to label *Microcode needs these together and on a quadword boundary: MC[RdcIOCBdataPtr,4]; *dataPtr: LONG POINTER MC[RdcIOCBdataPtr1,5]; *dataPtr: LONG POINTER, high order MC[RdcIOCBoperationCommand,6]; *enumerated Command and incrementDataPtr flag specified by client MC[RdcIOCBpageCount,7]; *Number of pages this IOCB. *Microcode needs these together and on a quadword boundary: MC[RdcIOCBdeviceStatus,10]; *completion: Status 2 words MC[RdcIOCBdiskHeader,12]; *header read from the disk MC[RdcIOCBdisk,14]; *disk handle. Cleared by SA4000Loader. *End of operation within IOCB: MC[RdcIOCBserviceLateRetryCount,15]; *retries to be executed by microcode MC[RdcIOCBcontrollerCommand,16]; *Command in the format needed by the controller. MC[RdcIOCBnext,17]; *next: IOCBLink *Microcode needs this on a 16 word boundary: MC[RdcIOCBClientHeader,20]; *client disk address, sent to the disk for *verification; updated during runs-of-pages. MC[RdcIOCBClientLabel,24]; *packed label formed from client's label and *sent to the disk for verification. *Microcode needs these on a quadword boundary: MC[RdcIOCBFileFlags,30]; *file flags. Must be zeroed on runs-of-pages. MC[RdcIOCBFilePageLo,31]; *filePageLo. Must be incremented on runs-of-pages. *Microcode needs these on a quadword boundary: MC[RdcIOCBdiskLabel,34]; *label read from the disk MC[RdcIOCBdiskLabel+4,40]; *label read from the disk MC[RdcIOCBrateErrorRetryCount,44]; *retries to be executed by microcode *The following definition specifies the mask for the IOCB file flags which *must be cleared in the label of subsequent pagesd in a run-of-pages: MC[RdcMaskFileFlags,7]; *Mask for file flags. *The following definitions are for offsets in the CSB (Controller Status Block): MC[RdcCSBdiskAddress,0]; *diskAddress: ARRAY[0..3] contains cylinder *address only. -1 is for recalibrate. MC[RdcCSBnext,4]; *next IOCB to process. MC[RdcCSBdeferring,5]; *-1 if error encountered. Stop processing *IOCBs until Poll sets this back to zero. MC[RdcCSBtail,6]; *Points to last IOCB in the queue. Used only *by Initiate procedure in Head. MC[RdcCSBtransferMask,7]; *Transfer mask to schedule Mesa processes at *end of operation. MC[RdcCSBserviceLateCount,10]; *This supports counting ServiceLates during *performance testing. *The following are times (in sector wakeups) loaded into SectorTimeOutCount: MC[RdcHeadSettlingTimeWakeUps,37]; *No. wakeups for head to settle after *seek complete (20 msec or 1 disk revolution). MC[RdcSeekTimeOutWakeUps,1000]; *No. wakeups until seek time out. MC[RdcDriveChangeTimeWakeUps,2]; *No. wakeups after drive change. MC[RdcSectorTimeOutWakeUps,100]; *No. wakeups until sector timeout *in state SectorWait. *No. negative one track seeks to try before giving up on trying to find track0 *during a Recal must be loaded into the RdcRecalSeekCount register. 300d *(454B) is comfortably more than the maximum seeks. Unfortunately, it *doesn't fit into 8 bits. Set[RdcRecalSeekLimit,454]; *The following definitions are for the CompletionCode: MC[RdcGoodCompletion,1]; *Enter this state from state DataTransfer if any error is detected. *Bits in the Status word indicate the problem. MC[RdcDataError,2]; *IOAtten while reading the label field; error bits indicate problem. MC[RdcLabelError,3]; *IOAtten occurred while reading the label field, and no error bits are set. MC[RdcLabelCheck,4]; MC[RdcSeekTimeOut,5]; *A time out occurred while doing a seek. MC[RdcSectorTimeOut,6]; *The sector was not found on the track. MC[RdcNotReady,7]; *When changing drives, timed out before drive ready. MC[RdcHeaderError,10]; *IOAtten in the Header field. This could be *wrongSector, wrongCylinder, or wrongHead. TheFace *will have to figure out which it is. HeaderError *corresponds to code wrongSector. MC[RdcRecalError,5]; *Unable to reach or see track0 while doing a Recal. *Note: on 11 June 1980, same as a seek timeout. *Soon a new set of codes from Paul McJones will *include a recalibrate error.(1792)