DIRECTORY DDC USING [Base, DataBlock, FieldOperation, FinishBlock, HeaderBlock, IOCB, LabelBlock, MiscCommandBlock, ParameterBlock, SeekBlock, SeekType, TransferBlock, TransferType], SA4000Face USING [Command, Operation]; SA4000HeadDLionConstants: DEFINITIONS = BEGIN OPEN DDC; nil: DDC.Base RELATIVE POINTER = LOOPHOLE[0]; zeroIOCB: PRIVATE POINTER TO IOCB = LOOPHOLE[0]; zeroOp: PRIVATE POINTER TO SA4000Face.Operation = @zeroIOCB.operation; clientHeaderOffset: PRIVATE CARDINAL = LOOPHOLE[@zeroOp.clientHeader]; diskHeaderOffset: PRIVATE CARDINAL = LOOPHOLE[@zeroOp.diskHeader]; statusAddr: PRIVATE WORD = LOOPHOLE[@zeroOp.deviceStatus--.a--]; zeroSB: PRIVATE POINTER TO SeekBlock = @zeroIOCB.seekCommand; entryOffset: PUBLIC CARDINAL = LOOPHOLE[@zeroSB.sendWaitCmd]; negDistanceAddr: PRIVATE CARDINAL = LOOPHOLE[@zeroSB.negDistance]; sendCtl1Addr: PRIVATE CARDINAL = LOOPHOLE[@zeroSB.sendCtl1]; sendCtl2Addr: PRIVATE CARDINAL = LOOPHOLE[@zeroSB.sendCtl2]; zeroTC: PRIVATE POINTER TO TransferBlock = @zeroIOCB.transferCommand; finishTransferAddr: PRIVATE CARDINAL = LOOPHOLE[@zeroTC.finishTransfer]; loadParmsCmdAddr: PRIVATE CARDINAL = LOOPHOLE[@zeroTC.loadParmsCmd]; zeroTP: PRIVATE POINTER TO ParameterBlock = @zeroIOCB.transferParm; sectorCountAddr: PRIVATE CARDINAL = LOOPHOLE[@zeroTP.sectorCount]; labelOffset: PRIVATE CARDINAL = LOOPHOLE[@zeroIOCB.label]; IOCBDone: PRIVATE FinishBlock = [ finishCmd: 6, nextIOCB: nil, transferMask: 0, stopCmd: 2000B, statusAddr: statusAddr]; HeaderOperation: ARRAY SA4000Face.Command OF FieldOperation = [ verify, -- vv verify, -- vvr verify, -- vvw verify, -- vvv verify, -- vw verify, -- vww verify, -- vr verify, -- vrr verify, -- vrw verify, -- vrv read, -- rv read, -- rvr read, -- rvw - illegal read, -- rvv read, -- rw - illegal read, -- rww - illegal read, -- rr read, -- rrr read, -- rrw - illegal read, -- rrv write, -- w write -- www ]; LabelOperation: ARRAY SA4000Face.Command OF FieldOperation = [ verify, -- vv verify, -- vvr verify, -- vvw verify, -- vvv write, -- vw write, -- vww read, -- vr read, -- vrr read, -- vrw read, -- vrv verify, -- rv verify, -- rvr verify, -- rvw - illegal verify, -- rvv write, -- rw - illegal write, -- rww - illegal read, -- rr read, -- rrr read, -- rrw - illegal read, -- rrv write, -- w write -- www ]; DataOperation: PACKED ARRAY SA4000Face.Command OF FieldOperation = [ noop, -- vv read, -- vvr write, -- vvw verify, -- vvv noop, -- vw write, -- vww noop, -- vr read, -- vrr write, -- vrw verify, -- vrv noop, -- rv read, -- rvr write, -- rvw - illegal verify, -- rvv noop, -- rw - illegal write, -- rww - illegal noop, -- rr read, -- rrr write, -- rrw - illegal verify, -- rrv write, -- w write -- www ]; headerOpBlock: ARRAY FieldOperation OF HeaderBlock = [ [headerCmd: 2060B, headerCnt: 1, headerAddr: clientHeaderOffset, headerQuitMsk: 0, headerLoopMsk: 0], [headerCmd: 2060B, headerCnt: 2, headerAddr: diskHeaderOffset, headerQuitMsk: 36B, headerLoopMsk: 0], [headerCmd: 2073B, headerCnt: 2, headerAddr: clientHeaderOffset, headerQuitMsk: 34B, headerLoopMsk: 0], [headerCmd: 2062B, headerCnt: 1, headerAddr: clientHeaderOffset, headerQuitMsk: 34B, headerLoopMsk: 3]]; labelOpBlock: ARRAY FieldOperation OF LabelBlock = [ [labelCmd: 2062B, labelCnt: 11, labelAddr: labelOffset, labelMsk: 0], [labelCmd: 2060B, labelCnt: 12, labelAddr: labelOffset, labelMsk: 36B], [labelCmd: 2073B, labelCnt: 12, labelAddr: labelOffset, labelMsk: 34B], [labelCmd: 2062B, labelCnt: 11, labelAddr: labelOffset, labelMsk: 37B]]; dataOpBlock: ARRAY FieldOperation OF DataBlock = [ [dataCmd: 2062B, dataCnt: 255, dataPgNum: 0, dataMsk: 0], [dataCmd: 2060B, dataCnt: 256, dataPgNum: 0, dataMsk: 36B], [dataCmd: 2073B, dataCnt: 256, dataPgNum: 0, dataMsk: 34B], [dataCmd: 2062B, dataCnt: 255, dataPgNum: 0, dataMsk: 37B]]; miscCmdBlock: ARRAY BOOLEAN OF MiscCommandBlock = [ [freezeCmd: 2140B, findSectMkCmd: 2046B], -- find sector mark on SA400x type drive [freezeCmd: 2140B, findSectMkCmd: 2040B]]; -- no sector mark on SA100x type drive seekCmdBlock: ARRAY SeekType OF SeekBlock = [ [negDistance: -1, sendWaitCmd: 100000B, -- send control word op code waitCmd: 2042B, -- wait for Seek complete sendCtl1: 100000B, -- send control word op code controlWd1: 2040B, -- controller just keeps FirmwareEnable sendCtl2: 100000B, -- send control word op code controlWd2: 2040B, inrNegDistance: 0, negDistanceAddr: negDistanceAddr, jumpToStep: 2, sendCtlAddr: 0, -- should never take this branch since -1 +1=0 initRegsCmd: 7, -- puts ICOBDone bit into UField and clears UStatus initRegsParm: 0, -- a dummy parameter finishSeek: IOCBDone], [negDistance: 0, -- negative of number of cylinders to cross, sendWaitCmd: 100000B, -- send control word op code waitCmd: 2042B, -- wait for Seek complete sendCtl1: 100000B, -- send control word op code controlWd1: 2240B, -- word to raise step line, direction filled in later sendCtl2: 100000B, -- send control word op code controlWd2: 2040B, -- word to lower step line, direction filled in later inrNegDistance: 0, -- incr and skip if zero op code negDistanceAddr: negDistanceAddr, -- this distance filled in later (when IOCB built) jumpToStep: 2, -- jump op code, only used when more step pulses sendCtlAddr: sendCtl1Addr, -- address of sendCtl1 word initRegsCmd: 7, -- puts ICOBDone bit into UField and clears UStatus initRegsParm: 0, -- a dummy parameter finishSeek: IOCBDone], -- all pulses sent, so finish up [negDistance: -1, -- negative of number of cylinders to cross sendWaitCmd: 100000B, -- send control word op code waitCmd: 2042B, -- wait for Seek complete sendCtl1: 100000B, -- send control word op code controlWd1: 2240B, -- word to raise step line, direction filled in later sendCtl2: 100000B, -- send control word op code controlWd2: 2042B, -- word to lower step line and wait for inrNegDistance: 0, -- incr and skip if zero op code negDistanceAddr: negDistanceAddr, -- this distance filled in later (when IOCB built) jumpToStep: 2, -- jump op code, only used when more step pulses sendCtlAddr: sendCtl1Addr, -- address of sendCtl1 word initRegsCmd: 7, -- puts ICOBDone bit into UField and clears UStatus initRegsParm: 0, -- a dummy parameter finishSeek: IOCBDone], -- all pulses sent, so finish up [negDistance: -27, -- negative of number of cylinders to cross sendWaitCmd: 100000B, -- send control word op code waitCmd: 2042B, -- wait for Seek complete sendCtl1: 100000B, -- send control word op code controlWd1: 2044B, -- word to find index mark sendCtl2: 100000B, -- send control word op code controlWd2: 2046B, -- word to find the next sector mark inrNegDistance: 0, -- incr and skip if zero op code negDistanceAddr: negDistanceAddr, -- this count initialized above to -27 jumpToStep: 2, -- jump op code, only used when more sectors sendCtlAddr: sendCtl2Addr, -- address of sendCtl2 word initRegsCmd: 2, -- has side effect of clearing UStatus initRegsParm: loadParmsCmdAddr, -- jump to start of transfer block of instructions finishSeek: [0, nil, 0, 0, 0]], [negDistance: 0, -- not used sendWaitCmd: 100000B, -- send control word op code waitCmd: 2042B, -- wait for Seek complete sendCtl1: 100000B, -- send control word op code controlWd1: 2044B, -- word to find index mark sendCtl2: 2, -- jump op code controlWd2: loadParmsCmdAddr, -- jump to start of transfer block now inrNegDistance: 0, negDistanceAddr: 0, jumpToStep: 0, sendCtlAddr: 0, initRegsCmd: 0, initRegsParm: 0, finishSeek: [0, nil, 0, 0, 0]], [negDistance: 0, -- not used sendWaitCmd: 100000B, -- send control word op code waitCmd: 2042B, -- wait for Seek complete sendCtl1: 2, -- jump op code controlWd1: loadParmsCmdAddr, -- jump to start of transfer block now sendCtl2: 0, controlWd2: 0, inrNegDistance: 0, negDistanceAddr: 0, jumpToStep: 0, sendCtlAddr: 0, initRegsCmd: 0, initRegsParm: 0, finishSeek: [0, nil, 0, 0, 0]]]; transferCmdBlock: ARRAY TransferType OF TransferBlock = [ -- postStep/noPostStep [loadParmsCmd: 5, -- load transfer paramters from parameter block parmBlockAddr: sectorCountAddr, -- base of parameter block, must be 16 word aligned transferCmd: 4000B, -- transfer run of pages op code jumpFinishCmd: 2, -- jump op code finishAddr: finishTransferAddr, -- finish command addr, execute this when error sendStepCmd1: 2, -- jump op code stepCmdWd1: finishTransferAddr, -- finish command addr, execute when xfr flawless sendStepCmd2: 0, stepCmdWd2: 0, finishTransfer: IOCBDone], [loadParmsCmd: 5, -- load transfer paramters from parameter block parmBlockAddr: sectorCountAddr, -- base of parameter block, must be 16 word aligned transferCmd: 4000B, -- transfer run of pages op code jumpFinishCmd: 2, -- jump op code finishAddr: finishTransferAddr, -- address of finish command sendStepCmd1: 100000B, -- send control word op code stepCmdWd1: 2340B, -- raise the step line, direction=In sendStepCmd2: 100000B, -- send control word op code stepCmdWd2: 2140B, -- lower the step line, direction=In finishTransfer: IOCBDone]]; SA4000SectorDistance: ARRAY [0..28) OF INTEGER = [ -27, -28, -1, -2, -3, -4, -5, -6, -7, -8, -9, -10, -11, -12, -13, -14, -15, -16, -17, -18, -19, -20, -21, -22, -23, -24, -25, -26]; END. RSA4000HeadDLionConstants.mesa - Prototype IOCBs, etc. Copyright c 1985 by Xerox Corporation. All rights reserved. DDavies: June 18, 1980 12:55 PM Forrest: February 11, 1981 2:12 PM Russ Atkinson (RRA) February 19, 1985 3:31:00 pm PST Doug Wyatt, February 22, 1985 5:06:27 pm PST various offsets into the IOCB's are needed zeroIOCB is used to caculate them The offsets have to be caculated in two stages due to a compiler bug. Note; deviceStatus.b is set to GetHardwareBits[] during Poll Array Constants used to find the header operation in the command given in the IOCB (packing this increases the code size) used to find the label operation in the command given in the IOCB used to find the data operation in the command given in the IOCB used to compose the header portion of the IOCB parameter block noop the header = read, ignore errors read the header write the header verify the header used to compose the label portion of the IOCB parameter block noop the label = verify, ignore errors read the label write the label verify the label used to compose the data portion of the IOCB parameter block noop the data = verify, ignore errors read the data write the data verify the data stop controller between fields, leave directionIn set in case a post-step is needed dummyIOCB - This is needed if there is nothing to do in this IOCB except send an interrupt back to the calling mesa process. For uniformity, we make this like a step IOCB except the control words sent cause no action in the controller. A benefit of this is that both the Incr-Skip-if-zero and TstStatus op codes are executed. The first has the needed side effect of clearing the microcode's UField status register which both initializes it and clears any old field numbers. The second has the side effect of clearing the UStatus register of old error flags. In this way, the final deviceStatus posted will reflect the status of this operation only. and service request on IOCB to do a real seek command filled in when built to be sent step over one cylinder, used when recalibrating SeekComplete, direction filled in later to be sent series of commands used to find sector zero for the SA4000. It finds the index mark, then counts 27 sectors from there. The 28th sector coming up next will be sector zero. The SA1000 version just finds the index mark. to be found find sector zero for the SA1000. This is quite simple in that we simply find the index mark and return. This is not sufficient for the SA4000 since its index and sector marks are coincident this is the seek command used when only a transfer is to be done. It does nothing but wait for a SeekComplete before starting the transfer this are the two types of generic transfer blocks. The first is used when a run of pages continues on the next cylinder and a step command is needed. The second is used when either this transfer completes the run or the the run continues on this cylinder (it may have been broken because of file page label boundry). this type of transfer block is used when the heads must be moved after the transfer to set up the next transfer (the run crossed a cylinder boundry) Sector counts to use when formatting SA4000's Only tracks can be formated on the SA1000, but on 4000 individual pages can be done. The command sets up a wait for index mark, then counts n-1 sector marks. To format sector 0 or 1 one has to go all the way around Ê ˜codešœ5™5Kšœ Ïmœ1™KšœŸ˜ KšœŸ˜KšœŸ˜KšœŸ˜KšœŸ˜ KšœŸ˜ KšœŸ˜ KšœŸ˜ KšœŸ˜ KšœŸ˜ KšœŸ˜ KšœŸ˜KšœŸ˜KšœŸ˜KšœŸ˜KšœŸ˜KšœŸ˜ KšœŸ˜ KšœŸ˜KšœŸ˜ KšœŸ˜ KšœŸ˜ Kšœ˜K˜—Kšœ@™@šœžœžœžœ˜DKšœŸ˜ KšœŸ˜ KšœŸ˜ KšœŸ˜KšœŸ˜ KšœŸ˜ KšœŸ˜ KšœŸ˜ KšœŸ˜ KšœŸ˜KšœŸ˜ KšœŸ˜ KšœŸ˜KšœŸ˜KšœŸ˜KšœŸ˜KšœŸ˜ KšœŸ˜ KšœŸ˜KšœŸ˜KšœŸ˜ KšœŸ˜ Kšœ˜K˜—Kšœ>™>šœžœžœ˜6Kšœ%™%˜@K˜$—Kšœ™˜>K˜&—Kšœ™˜@K˜&—Kšœ™˜@K˜'K˜——Kšœ=™=šœžœžœ˜4Kšœ&™&K˜EKšœ™K˜GKšœ™K˜GKšœ™K˜HK˜K˜—Kšœ<™<šœ žœžœ˜2Kšœ%™%K˜9Kšœ ™ K˜;Kšœ™K˜;Kšœ™K˜KšœŸ3˜CKšœŸ˜%K˜K˜——šœ™šœŸ,˜=Kšœ™KšœŸ˜2KšœŸ˜)KšœŸ˜/KšœŸ5˜HKšœŸ˜/KšœŸ5˜HKšœŸ ˜3Kšœ"Ÿ2˜TšœŸ0˜?Kšœ ™ —KšœŸ˜6KšœŸ3˜CKšœŸ˜%KšœŸ ˜7K˜—Kšœ/™/šœŸ+˜=KšœŸ˜2KšœŸ˜)KšœŸ˜/KšœŸ5˜HKšœŸ˜/šœŸ'˜:Kšœ'™'—KšœŸ ˜3Kšœ"Ÿ2˜TšœŸ0˜?Kšœ ™ —KšœŸ˜6KšœŸ3˜CKšœŸ˜%KšœŸ ˜7K˜—KšœO™OKšœ)™)KšœL™LKšœ™šœŸ+˜>KšœŸ˜2KšœŸ˜)KšœŸ˜/KšœŸ˜-KšœŸ˜/KšœŸ$˜7KšœŸ ˜3Kšœ"Ÿ&˜HšœŸ,˜;Kšœ ™ —KšœŸ˜6KšœŸ&˜6Kšœ Ÿ2˜RK˜K˜—KšœH™HKšœK™KKšœ)™)šœŸ ˜KšœŸ˜2KšœŸ˜)KšœŸ˜/KšœŸ˜-Kšœ Ÿ˜KšœŸ&˜DK˜‹K˜—KšœR™RKšœ8™8šœŸ ˜KšœŸ˜2KšœŸ˜)Kšœ Ÿ˜KšœŸ&˜DK˜£K˜——Kšœ¾™¾K˜šœžœžœŸ˜PšœŸ/˜AKšœ Ÿ3˜SKšœŸ ˜4KšœŸ˜!Kšœ Ÿ/˜OKšœŸ˜ Kšœ Ÿ1˜QK˜K˜K˜—KšœV™VKšœ=™=šœŸ/˜AKšœ Ÿ3˜SKšœŸ ˜4KšœŸ˜!Kšœ Ÿ˜