%RDCDefs.mcinserted 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.