DIRECTORY --Basics USING [], DragOpsCross USING [XopBase, TrapBase, TrapWidthBytes, bytesPerWord, TrapIndex, Word, ProcessorRegister, IFUStackIndex], --XopBase, TrapBase, TrapWidthBytes, Inst, wordsPerPage, bytesPerWord, charsPerWord, bitsPerByte, bitsPerCharacter, bitsPerWord, logWordsPerPage, logBitsPerByte, logBitsPerChar, logBytesPerWord, logCharsPerWord, logBitsPerWord, logBytesPerPage, PageCount, PageNumber, maxPagesInVM, SixBitIndex, FiveBitIndex, Word, TwoWords, FourBitIndex, Half, ThreeBitIndex, FourHalves, TwoHalves, Byte, ZerosByte, OnesByte, EightBytes, FourBytes, ByteIndex, BytesPerWord, TwoBytes, Comparison, ByteAddress, WordAddress, FieldDescriptor, TrapWidthWords, KernalLimit, TrapIndex, StackUnderflowTrap, IFUPageFaultTrap, ResetTrap, IFUStackOverflowTrap, EUStackOverflowTrap, RescheduleTrap, ALUCondOver, ALUCondBC, ALUCondIL, ALUCondDO, EUPageFault, EUWriteFault, AUFault, euStack, euJunk, euMAR, euField, euConstant, euAux, euBogus, euLast, ifuXBus, ifuStatus, ifuSLimit, ifuYoungestL, ifuYoungestPC, ifuEldestL, ifuEldestPC, ifuBogus, ifuL, ifuS, ifuPC, ifuLast, IFUStatusRec, IFUStackIndex, IFUStackSize, IFUOverflow, EUStackIndex, EUStackSize, EULocalIndex, EULocals, EUAuxIndex, EUAuxRegs, EUConstIndex, EUConstants, IOLocation, ioRescheduleRequest, ioResetRequest DragOpsCrossUtils USING [CardToWord], --BytePCToWordAddress, WordAddressToBytePC, IOOperandToCard, CardToIOOperand, FieldDescriptorToCard, CardToFieldDescriptor, StatusToWord, WordToStatus, BytesToWord, BytesToHalf, WordToBytes, HalfToBytes, HalvesToWord, WordToHalves, HighHalf, LowHalf, LeftHalf, RightHalf, SwapHalves, WordToInt, IntToWord, WordToCard, HalfToCard, ByteToCard, CardToWord, CardToHalf, CardToByte, DragAnd, DragOr, DragXor, DragNot, VanillaAdd, VanillaSub, AddDelta, HalfNot, HalfAnd, HalfOr, HalfXor, HalfShift, DoubleWordShiftLeft, SingleWordShiftLeft, SingleWordShiftRight, TrapIndexToBytePC, XopToBytePC HandCoding, --Has opcode and register defs. HandCodingPseudos, --GenLabel, GenLabelHere, SetLabel, Halt, Pause, MakeLabelGlobal, UseLabel8B, UseLabel16, UseLabel32, ProcedureEntry, ProcedureExit, EnableTraps, IndexedJump, SetupField, ExtractField, ShiftLeft, LoadProcessorReg, StoreProcessorReg, DisableTraps, CauseReschedule, CauseReset, GetSPLimit, SetSPLimit, GetL, SetL, GetYoungestPC, GetYoungestL, GetEldestPC, GetEldestL, SetYoungestPC, SetYoungestL, SetEldestPC, SetEldestL HandCodingSupport; --Area, GetCurrentArea, ReserveData, SetOutputPC, GetProc, PutProc, ProcList, NewArea, GenWithArea, Gen1WithArea, ForceOut, GetOutputPC, WordAlign, OutputByte, OutputOneByte, OutputAlphaBeta, OutputAlphaBetaGammaDelta, OutputWord GenReg: CEDAR PROGRAM IMPORTS DragOpsCrossUtils, HandCoding, HandCodingPseudos, HandCodingSupport = BEGIN OPEN DragOpsCrossUtils, HandCoding, HandCodingPseudos, HandCodingSupport; Word: TYPE = DragOpsCross.Word; ProcessorRegister: TYPE = DragOpsCross.ProcessorRegister; IFUStackIndex: TYPE = DragOpsCross.IFUStackIndex; ifuSLimit: CARDINAL = LOOPHOLE[ProcessorRegister.ifuSLimit, CARDINAL]; ifuEldestPC: CARDINAL = LOOPHOLE[ProcessorRegister.ifuEldestPC, CARDINAL]; ifuEldestL: CARDINAL = LOOPHOLE[ProcessorRegister.ifuEldestL, CARDINAL]; ifuYoungestPC: CARDINAL = LOOPHOLE[ProcessorRegister.ifuYoungestPC, CARDINAL]; ifuYoungestL: CARDINAL = LOOPHOLE[ProcessorRegister.ifuYoungestL, CARDINAL]; ifuStatus: CARDINAL = LOOPHOLE[ProcessorRegister.ifuStatus, CARDINAL]; All: PROC = { FillXop: PROC [inst: CARDINAL, dest: Label] = { SetOutputPC[inst * DragOpsCross.TrapWidthBytes + DragOpsCross.XopBase * DragOpsCross.bytesPerWord]; drJDB[UseLabel16[dest]]; }; FillTrap: PROC [tx: DragOpsCross.TrapIndex, dest: Label] = { SetOutputPC[LOOPHOLE[tx, CARDINAL] * DragOpsCross.TrapWidthBytes + DragOpsCross.TrapBase * DragOpsCross.bytesPerWord]; drJDB[UseLabel16[dest]]; }; GenRegWrite: PROC [reg: CARDINAL, val: LONG CARDINAL] ~ { drLIQB[CardToWord[val]]; drSIP[reg]; }; GenRegRead: PROC [reg: CARDINAL, val: LONG CARDINAL] ~ { rdOK: Label = GenLabel[]; drLIP[reg]; drLIQB[CardToWord[val]]; drRJEBJ[popSrc, belowSrcPop, UseLabel8B[rdOK]]; Pause[]; SetLabel[rdOK]; }; area: Area = GetCurrentArea[]; savePC: LONG CARDINAL; start: Label = GenLabel[]; dummy: Label = GenLabel[]; initL: Label = GenLabel[]; enterEUSLTest: Label = GenLabel[]; enterIFUSLTest: Label = GenLabel[]; GenEUSL: PROC = { testVal: LONG CARDINAL; SetLabel[enterEUSLTest]; testVal _ 8; GenRegWrite[0, 1]; FOR I: CARDINAL IN [3..127] DO GenRegWrite[I, testVal]; testVal _ IF testVal = 20000000000B THEN 1 ELSE testVal + testVal; ENDLOOP; FOR I: CARDINAL IN [130..131] DO GenRegWrite[I, testVal]; testVal _ IF testVal = 20000000000B THEN 1 ELSE testVal + testVal; ENDLOOP; FOR I: CARDINAL IN [133..159] DO GenRegWrite[I, testVal]; testVal _ IF testVal = 20000000000B THEN 1 ELSE testVal + testVal; ENDLOOP; testVal _ 8; GenRegRead[0, 1]; FOR I: CARDINAL IN [3..127] DO GenRegRead[I, testVal]; testVal _ IF testVal = 20000000000B THEN 1 ELSE testVal + testVal; ENDLOOP; FOR I: CARDINAL IN [130..131] DO GenRegRead[I, testVal]; testVal _ IF testVal = 20000000000B THEN 1 ELSE testVal + testVal; ENDLOOP; FOR I: CARDINAL IN [133..159] DO GenRegRead[I, testVal]; testVal _ IF testVal = 20000000000B THEN 1 ELSE testVal + testVal; ENDLOOP; drASL[4]; --S _ 5 GenRegWrite[1, 2]; GenRegWrite[2, 4]; GenRegRead[1, 2]; GenRegRead[2, 4]; drASL[255]; --S _ 0 again testVal _ 37777777767B; GenRegWrite[0, 37777777776B]; FOR I: CARDINAL IN [3..127] DO GenRegWrite[I, testVal]; testVal _ IF testVal = 17777777777B THEN 37777777776B ELSE testVal + testVal + 1; ENDLOOP; FOR I: CARDINAL IN [130..131] DO GenRegWrite[I, testVal]; testVal _ IF testVal = 17777777777B THEN 37777777776B ELSE testVal + testVal + 1; ENDLOOP; FOR I: CARDINAL IN [133..159] DO GenRegWrite[I, testVal]; testVal _ IF testVal = 17777777777B THEN 37777777776B ELSE testVal + testVal + 1; ENDLOOP; testVal _ 37777777767B; GenRegRead[0, 37777777776B]; FOR I: CARDINAL IN [3..127] DO GenRegRead[I, testVal]; testVal _ IF testVal = 17777777777B THEN 37777777776B ELSE testVal + testVal + 1; ENDLOOP; FOR I: CARDINAL IN [130..131] DO GenRegRead[I, testVal]; testVal _ IF testVal = 17777777777B THEN 37777777776B ELSE testVal + testVal + 1; ENDLOOP; FOR I: CARDINAL IN [133..159] DO GenRegRead[I, testVal]; testVal _ IF testVal = 17777777777B THEN 37777777776B ELSE testVal + testVal + 1; ENDLOOP; drASL[4]; --S _ 5 GenRegWrite[1, 37777777775B]; GenRegWrite[2, 37777777773B]; GenRegRead[1, 37777777775B]; GenRegRead[2, 37777777773B]; drASL[255]; --S _ 0 again }; GenIFUSL: PROC = { GenCallTest: PROC [dest: Label, lVal, rVal: CARDINAL] ~ { drLFC[UseLabel16[dest]]; GenRegRead[ifuYoungestL, rVal]; drRETN[]; Pause[]; SetLabel[dest]; GenRegWrite[ifuYoungestL, lVal]; }; testPCVal, testLVal: LONG CARDINAL; SetLabel[enterIFUSLTest]; testPCVal _ 1; testLVal _ 4; GenRegWrite[ifuSLimit, 0]; FOR I: CARDINAL IN IFUStackIndex DO GenRegWrite[ifuEldestPC, testPCVal]; testPCVal _ IF testPCVal = 20000000000B THEN 1 ELSE testPCVal + testPCVal; GenRegWrite[ifuEldestL, testLVal]; testLVal _ IF testLVal = 100B THEN 1 ELSE testLVal + testLVal; ENDLOOP; GenRegRead[ifuSLimit, 0]; FOR I: CARDINAL IN IFUStackIndex DO testLVal _ IF testLVal = 1 THEN 100B ELSE testLVal / 2; GenRegRead[ifuEldestL, testLVal]; testPCVal _ IF testPCVal = 1 THEN 20000000000B ELSE testPCVal / 2; GenRegRead[ifuEldestPC, testPCVal]; ENDLOOP; testPCVal _ 37777777776B; testLVal _ 173B; GenRegWrite[ifuSLimit, 177B]; FOR I: CARDINAL IN IFUStackIndex DO GenRegWrite[ifuEldestPC, testPCVal]; testPCVal _ IF testPCVal = 17777777777B THEN 37777777776B ELSE testPCVal + testPCVal + 1; GenRegWrite[ifuEldestL, testLVal]; testLVal _ IF testLVal = 77B THEN 176B ELSE testLVal + testLVal + 1 - 200B; ENDLOOP; GenRegRead[ifuSLimit, 177B]; FOR I: CARDINAL IN IFUStackIndex DO testLVal _ IF testLVal = 176B THEN 77B ELSE testLVal / 2 + 100B; GenRegRead[ifuEldestL, testLVal]; testPCVal _ IF testPCVal = 37777777776B THEN 17777777777B ELSE testPCVal / 2 + 20000000000B; GenRegRead[ifuEldestPC, testPCVal]; ENDLOOP; testPCVal _ 200000B; testLVal _ 1; FOR I: CARDINAL IN IFUStackIndex DO youngCall: Label = GenLabel[]; drLFC[UseLabel16[youngCall]]; SetLabel[youngCall]; GenRegWrite[ifuYoungestPC, testPCVal]; testPCVal _ IF testPCVal = 20000000000B THEN 1 ELSE testPCVal + testPCVal; GenRegWrite[ifuYoungestL, testLVal]; testLVal _ IF testLVal = 100B THEN 1 ELSE testLVal + testLVal; ENDLOOP; testPCVal _ 200000B; testLVal _ 1; FOR I: CARDINAL IN IFUStackIndex DO GenRegRead[ifuEldestL, testLVal]; testLVal _ IF testLVal = 100B THEN 1 ELSE testLVal + testLVal; GenRegRead[ifuEldestPC, testPCVal]; testPCVal _ IF testPCVal = 20000000000B THEN 1 ELSE testPCVal + testPCVal; ENDLOOP; { Call1: Label = GenLabel[]; Call2: Label = GenLabel[]; Call3: Label = GenLabel[]; Call4: Label = GenLabel[]; Call5: Label = GenLabel[]; Call6: Label = GenLabel[]; Call7: Label = GenLabel[]; Call8: Label = GenLabel[]; Call9: Label = GenLabel[]; Call10: Label = GenLabel[]; Call11: Label = GenLabel[]; Call12: Label = GenLabel[]; Call13: Label = GenLabel[]; Call14: Label = GenLabel[]; Call15: Label = GenLabel[]; EndCallTest: Label = GenLabel[]; drLFC[UseLabel16[Call1]]; drJDB[UseLabel16[EndCallTest]]; SetLabel[Call1]; GenRegWrite[ifuYoungestL, 1]; GenCallTest[Call2, 2, 1]; GenCallTest[Call3, 3, 2]; GenCallTest[Call4, 4, 3]; GenCallTest[Call5, 5, 4]; GenCallTest[Call6, 6, 5]; GenCallTest[Call7, 7, 6]; GenCallTest[Call8, 8, 7]; GenCallTest[Call9, 9, 8]; GenCallTest[Call10, 10, 9]; GenCallTest[Call11, 11, 10]; GenCallTest[Call12, 12, 11]; GenCallTest[Call13, 13, 12]; GenCallTest[Call14, 14, 13]; GenCallTest[Call15, 15, 14]; GenRegRead[ifuYoungestL, 15]; drRETN[]; SetLabel[EndCallTest]; }; }; ProcedureEntry[dummy, 0]; ProcedureExit[0]; savePC _ GetOutputPC[area]; FillTrap[ResetTrap, start]; FillXop[0, dummy]; FillXop[377B, dummy]; SetOutputPC[savePC]; ProcedureEntry[initL, 0]; drLIB[1]; SetYoungestL[]; -- L _ 1 on return --drLIB[128-16-1]; --SetSPLimit[]; ProcedureExit[0]; WordAlign[area]; SetLabel[start]; --Simulator execution begins here on a Reset. drLFC[UseLabel16[initL]]; --We use this method to initialize L to 1 drASL[255]; --When there is nothing on the stack, S should be at L-1 GenEUSL[]; GenIFUSL[]; Halt[177777B]; --Terminate here at the end of the program }; END. HGenReg.mesa Copyright c 1984, 1985 by Xerox Corporation. All rights reserved. Edward Fiala February 7, 1986 2:59:57 pm PST McCreight, January 7, 1986 3:52:02 pm PST This diagnostic tests EU and IFU registers using LIP and SIP and (in a limited way) using LFC and RETN. It presumes that LIQB and RJEBJ have been thoroughly tested by GenLICJ. When successfully executed it halts at instruction 2162, cycle 4975, PC 4031055B. Xops trap at opcode*TrapWidthBytes + xopBase*bytesPerWord = 4,000,000B + 20B * opcode. A trap's location is TrapIndex*TrapWidthBytes + TrapBase*bytesPerWord = 4,002,000B + 20B * TrapIndex. TrapIndex definitions are in DragOpsCross. GenEUSL tests all EU registers except const0 using LIQB and SIP to consecutively write different values in all registers, then LIP, LIQB, and RJEB to read back and check all values. This test will catch addressing errors which cause the write of one register to wind up in another as well as storage failures. Register descriptions are in DragOpsCross.mesa. Skip over euJunk = 128 and 129; test euMar = 130 and euField = 131. euMar is a dumping place for memory addresses on address faults; it is (??) a regular register. euField is both a normal register and a collection of other logic to control the field unit; this test covers the register part of it; the other control logic can only be tested indirectly by noting whether or not the field unit performs correctly for values in euField. Read and compare; must skip registers 1 and 2 which have been smashed by the various pushes during writing and reading. Finally, go back and test registers 1 and 2. Write with inverse values. Read and compare, skipping registers 1 and 2 smashed by stack operations. Finally, go back and test registers 1 and 2. GenIFUSL tests all IFU registers except ifuXBus (untestable) and ifuStatus using LIQB and SIP to consecutively write different values in all registers, then LIP, LIQB, and RJEB to read back and check all values. The IFU stack is tested both when writing it with ifuEldestL/PC and when writing it with ifuYoungestL/PC and changing the stack depth with LFC/RETN. This test will catch addressing errors which cause the write of one register to wind up in another, and it checks the manipulation of the IFU stack and L register by LFC and RETN. The description of the funny IFU registers is in DragOpsCross.mesa. Current values of L, S, and PC cannot be read; the stack covers only previous frames. In normal operation, ifuEldestL/PC are written on IFU stack underflow when previous frames are restored to the registers, and read on IFU or EU stack overflow to remove frames from the registers. One test below operates the IFU stack by reading and writing ifuEldestL/PC. Another test below writes the IFU stack by doing a LFC to push the stack, then using SIP on ifuYoungestL/PC; then it reads the stack back by doing RET and LIP to read values. ifuXBus = base for IFU regs = 240 can't be tested. ifuStatus = 241 is not tested here. ifuSLimit = stack limit register = 242; 7-bit register. This register is written and read by GenIFUSL, but its function as a stack limit register is not tested. IFUStackSize = 15. ifuYoungestL = youngest L in IFU stack = 243. ifuYoungestPC = youngest PC in IFU stack = 244. ifuEldestL = eldest L in IFU stack = 245. ifuEldestPC = eldest PC in IFU stack = 246 (read removes, write adds). Test with single 1-bit cycled left 1 position each time. Test with single 0-bit cycled left 1 position each time (i.e., inverse of first test). Test the ifu stack with LFC and ifuYoungestL/PC used to push and to write, and ifuEldestL/PC used to read and pop. Test the ifu stack with LFC used to push and to write PC, ifuYoungestL to write, and RETN used to read and pop. This test will malfunction unless L and PC are correctly manipulated by LFC and RETN. Note that only 15 calls can be made here because, even though there are 16 levels in the ifu stack, only 15 are usable by call and return; if a 16th LFC is given, then its RETN results in a stack underflow trap. Opcodes 0 and 377B are intercepted by the simulator, but make them trap to dummy here anyway. spLimit is set with room for 17 overflow words (just in case). A stack overflow trap occurs when S is in [spLimit..spLimit + 16). Since this diagnostic program never enables the trap, it is not necessary to execute the code here. At this point, L = 1, S = 0. Κ V–81.25 in leftMargin 1.25 in rightMargin 6.0 in lineLength˜codešœ ™ Kšœ Οmœ7™BK™,K™)K™K™ƒ—K˜šΟk ˜ Kšœ žœ˜Kšœ žœgΟcύ˜φ KšœžœŸΛ˜ρKšœ Ÿ˜+KšœŸ’˜΅KšœŸε˜ψK˜—šœžœž˜KšžœD˜KKšœžœžœE˜QK˜K–20 sp tabStopsšœžœ˜K–20 sp tabStops˜K–20 sp tabStopsšœžœ"˜9K–20 sp tabStopsšœžœ˜1K–20 sp tabStopsšœ žœžœžœ˜FK–20 sp tabStopsšœ žœžœ žœ˜JK–20 sp tabStopsšœ žœžœžœ˜HK–20 sp tabStopsšœžœžœ"žœ˜NK–20 sp tabStopsšœžœžœ!žœ˜LK–20 sp tabStopsšœ žœžœžœ˜FK–20 sp tabStops˜šΟnœžœ˜ K˜KšœV™Vš œžœžœ˜/Kšœc˜cKšœ˜K˜K˜—Kšœ‘™‘š œžœ.˜Kšžœ˜—K˜Kšœ˜šžœžœžœž˜#Kšœ žœžœžœ˜7K˜!Kšœ žœžœžœ˜BKšœ#˜#Kšžœ˜—K˜KšœV™VKšœ˜K˜Kšœ˜šžœžœžœž˜#Kšœ$˜$Kšœ žœžœžœ˜YK˜"Kšœ žœžœžœ ˜KKšžœ˜—K˜Kšœ˜šžœžœžœž˜#Kšœ žœžœžœ˜@K˜!Kšœ žœžœžœ˜\Kšœ#˜#Kšžœ˜—K˜Kšœr™rKšœ˜Kšœ ˜ šžœžœžœž˜#Kšœ˜Kšœ˜Kšœ˜Kšœ&˜&Kšœ žœžœžœ˜JK˜$Kšœ žœžœžœ˜>Kšžœ˜—K˜Kšœ˜Kšœ ˜ šžœžœžœž˜#K˜!Kšœ žœžœžœ˜>Kšœ#˜#Kšœ žœžœžœ˜JKšžœ˜—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šœ˜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˜Kšœ˜Kšœ˜K˜K˜K˜ KšœŸ˜#Kšœη™ηKšœ˜Kšœ˜K˜J˜Kšœ˜KšœŸ-˜>K˜KšœŸ)˜CKšœ Ÿ8˜DKšœ™K˜K˜ Jšœ ˜ JšœŸ*˜9˜K˜——Kšžœ˜—K˜—…—(LDκ