% File: RDCDefs.mc

Edit by Ev Neely October 24, 1980 5:28 PM. Fix RecalSeekLimit.
Edit by Ev Neely July 10, 1980 17:55 . Put definition of RdcIOCBclientLabel back in defs and restore original name of RdcIOCBdisk because SA4000Loader.mc uses them.
Edit by Ev Neely June 30, 1980 12:58 . Changes in support of 48 bit processor-ID and miscellaneous IOCB format changes.
Edit by Ev Neely June 19, 1980 10:58 . Added constant in support of counting servicelates for test purposes.
Ev Neely June 13, 1980 5:26 PM. Fix for AR4320 uses previously unused register for RdcRecalSeekCount, defines RdcRecalSeekLimit and RdcRecalError.
Edit by Jim Frandeen February 16, 1980 12:54 PM Use two banks of registers to improve performance.
Edit by Jim Frandeen January 20, 1980 9:44 AM for new D0Lang.
Edit by Jim Frandeen December 25, 1979 8:27 PM for runs of pages and Version5 of D0Lang.
%
SET TASK[RdcTask];*currently 10b = 8d
*The following are definitions for the registers that belong to the RDC microprogram task.
SET[RdcRegBase,AND[60,LSHIFT[RdcTask,4]]];
*Register 0 is destroyed by DoInt across sector wakeups.
RV[RdcTemp, ADD[RdcRegBase, 0]];
*Register 1 is destroyed by DoInt across sector wakeups. HeadSettleCount is used to count sectors until the heads settle after a seek.
RV[RdcHeadSettleCount, ADD[RdcRegBase, 1]];
*The next two registers must be together and doubleword aligned. They 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.
RV[RdcNextIOCB, ADD[RdcRegBase, 2]];
RV[RdcDeferring, ADD[RdcRegBase, 3]];
*The following four registers must be together and quadword aligned. They 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.
RV[RdcDataPtr, ADD[RdcRegBase, 4]];
RV[RdcDataPtr1, ADD[RdcRegBase, 5]];
RV[RdcIncrementDataPtrFlag, ADD[RdcRegBase,6]];
RV[RdcPageCount, ADD[RdcRegBase,7]];
*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.
RV[RdcCylinder, ADD[RdcRegBase, 10]];
RV[RdcHeadSector, ADD[RdcRegBase,11]];
*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]];
*The following four registers must be together and quadword aligned. They 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.
RV[RdcFileFlags, ADD[RdcRegBase, 14]];
RV[RdcFilePageLo, ADD[RdcRegBase, 15]];
RV[RdcPackedLabel7, ADD[RdcRegBase, 16]];
RV[RdcPackedLabel8, ADD[RdcRegBase, 17]];
*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.
RV[RdcIOCBptr, ADD[RdcRegBase, 20]];
*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.
Rv[RdcZeroBase,ADD[RdcRegBase,21]];
*IOCB16Ptr is used with the next register as a base register to address the second 16 word block of the IOCB.
RV[RdcIOCB16Ptr, ADD[RdcRegBase, 22]];
RV[RdcIOCB16ZeroBase, ADD[RdcRegBase, 23]];
*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.
RV[RdcDiskAddressPtr, ADD[RdcRegBase,24]];
RV[RdcDiskAddressZeroBase, ADD[RdcRegBase,25]];
*CSBptr points to the Controller Status Block. It is used as a base register with the next register.
RV[RdcCSBptr, ADD[RdcRegBase, 26]];
RV[RdcCSBzeroBase, ADD[RdcRegBase, 27]];
*The following two registers must be together and be doubleword aligned. They 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.
RV[RdcDiskStatus, ADD[RdcRegBase, 30]];
RV[RdcCompletionCode, ADD[RdcRegBase, 31]];
*CurrentCylinder contains the cylinder address of the drive currently selected. -1 means this drive must be recalibrated.
RV[RdcCurrentCylinder, ADD[RdcRegBase, 32]];
*DriveHead is used to select the driveand 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 DoInt.
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 (currently 220B).
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 is in bits 12-13 (10-11D), Head is 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 this register is written into Buffer[RdcMemBufAddr].
SET[RdcOutput, ADD[RdcAddr,4]];*Complete device address for above.
SET[RdcMemBuffAdr, 6];*This register holds the 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:
MC[RdcIOCBoperationClientHeader, 0];*disk address specified by client. This is used for the initial seek address. Almost always it is a duplicate of 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[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];*disk address specified by client. This is sent to the disk for verification. It is updated during runs-of-pages.
MC[RdcIOCBClientLabel, 24];*packed label formed from that specified by client. This is 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 serviselates during performance testing.
*The following are timing definitions that are loaded into SectorTimeOutCount:
MC[RdcHeadSettlingTimeWakeUps, 37];*Number of sector wakeups for head to settle after seek complete (20 miliseconds, or one disk revolution).
MC[RdcSeekTimeOutWakeUps, 1000];*Number of sector wakeups to wait until seek time out.
MC[RdcDriveChangeTimeWakeUps, 2];*Number of sector wakeups to wait after drive change.
MC[RdcSectorTimeOutWakeUps, 100];*Number of sector wakeups to wait until sector time out when in state SectorWait.
*Number of negative one track seeks to try before giving up on trying to find track0 during a Recal must be loaded into the RdcRecalSeekCount register. 300 decimal (454B) is comfortably more than the maximum seeks. Unfortunately, it doesn’t fit into 8 bits.
MC[RdcRecalSeekLimitHi, 400];
MC[RdcRecalSeekLimitLo, 54];
*The following definitions are for the CompletionCode:
MC[RdcGoodCompletion, 1];
MC[RdcDataError, 2];
*Enter this state from state DataTransfer if any error is detected. Bits in the Status word indicate the problem.
MC[RdcLabelError, 3];
*IOAtten occurred while reading the label field. Error bits indicate the problem.
MC[RdcLabelCheck, 4];
*IOAtten occurred while reading the label field, and no error bits are set.
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, a timeout occurred before the drive came 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: currently, 11June1980, same as a seek timeout. Soon a new set of codes from Paul McJones will include a recalibrate error.