% *** Revision 1.1 May 3, 1980 *** **************************************************************************************** *** EDField.mc : microcode to test the Mesa field selection operations RF, WFA, WFB *** Purpose : This test simulates the RF, WFA, and WFB operations without using the cycler-masker and then compares the results with the actual executions of the corresponding operations. *** Hardware Configuration : Standard 4 CPU boards. *** IMPORTANT NOTE : ON VIRGIN SYSTEMS RUN EDFIELD BEFORE EDCYM. This EDField test checks hardware that must work properly for EDCym to be useful. *** Approximate run time : twenty seconds. *** Written by : Tom Horsley, Dec. 13, 1977 *** Modified by : Bill Kennedy, March 10, 1978 Took code off of Page 0. *** Modified by : Bill Kennedy, April 24, 1978 Now uses Maintenance Panel. *** Modified by : C. Thacker, (date unknown) Improved readability. *** Modified by : C. Thacker, August 22, 1978 Made XB = -1 always. *** Rewritten by : J. Kellman, March 6, 1980 Eliminated all cycler-masker functions from both the simulated field selection operations and random number generators, as well as standardizing the program format. *** Modified by : C. Thacker, Use cym.cm to assemble, converted for new d0lang. **************************************************************************************** **************************************************************************************** * SubTest Description: * SubTest 0: (not really a test) generates and decodes a Mesa Field descriptor. * SubTest 1: simulates and then executes the RF operation (Mesa Read-Field) and compares the results. * SubTest 2: simulates and then executes the WFA operation (Mesa Write-Field A) and compares the results. * SubTest 3: simulates and then executes the WFB operation (Mesa Write-Field B) and compares the results. **************************************************************************************** * Subroutine Description: * LeftCycle: uses ALU additions to simulate the LCycle function without using the cycler-masker. * LeftShift: uses ALU additions to simulate the LShift function without using the cycler-masker. **************************************************************************************** * Breakpoints: * RFBAD: actual RF result failed to agree with simulated RF result * WFABAD: actual WFA result failed to agree with simulated WFA result * WFBBAD: actual WFB result failed to agree with simulated WFB result * Passed-EDField-Test: the system passed thru all the passes of EDField **************************************************************************************** * Breakpoint Logic Analyzer Sync Points: * RFBAD: Control Store address 457 * WFABAD: Control Store address 451 * WFBBAD: Control Store address 441 * Passed-EDField-Test: Control Store address 401 **************************************************************************************** **************************************************************************************** * Special Register Definitions: * LoopWithin: At any breakpoint the user may change the value of LoopWithin. Setting LoopWithin to the nonzero value N will cause EDField to loop endlessly within the subtest N (when it gets to this subtest). If LoopWithin is zero (the default) then the program goes straight through all the tests as normal. * RandFlag: At any breakpoint the user may change the value of RandFlag to 1, which will cause CurrentPattern to take on random values. If RandFlag is zero (the default) then CurrentPattern will be set to a 16-bit word of all ones during each execution of subtest 0. * XA and XB: The two random numbers held in these registers XA and XB are used to choose field descriptor (FDescr) and CurrentPattern values as follows: FDescr ← XA[0:7] CurrentPattern ← XB (only if RandFlag = 1) * InnerLoopCounter: This register contains the number of passes through the mainloop. The mainloop is simply the set of all of the subtests. When InnerLoopCounter = (2**16) - 1, all of the possibilities that are tested by EDField have been tested exactly once. * PassCount: This register displays the number of the current pass of the entire EDField test (2**16 iterations of the mainloop). The maintenance panel shows the number of the currently running pass. * MaxPass: This register determines how many times the entire EDField test will repeat. **************************************************************************************** % **************************************************************************************** * INITIALIZATION: TITLE[MesaFieldTest]; ********** R-registers: ************* RV[Revision,1,1]; * revision number is 1 for this program RV[Run-Time,2,24]; * run time for this test is twenty seconds RV[PassCount,3]; * pass count for this program RV[MaxPass,4,2]; * maximum number of passes for this run RV[SubTest,5]; * current location of test RV[InnerLoopCounter,6]; * inner loop counter RV[LoopWithin,10,0]; * set to N to loop on subtest n RV[RandFlag,11,0]; * 0 => CurrentPattern always 177777, 1 => random pattern RV[CurrentPattern,12]; * holds the argument for the RF, WFA, and WFB operations RV[CA,13]; * used in random number generation, A*XA + CA RV[XA,14]; * random number generated via A*XA + CA RV[CB,15]; * used in random number generation, A*XB + CB RV[XB,16]; * random number generated via A*XB + CB RV[FDescr,17]; * Mesa field descriptor RV[StartBit,20]; * start field of mesa field descriptor (first 4 bits) RV[EndBit,21]; * last bit of mesa field RV[Length,22]; * actual length of mesa field from descriptor (last 4 bits plus 1) RV[ShiftIndex,23]; * index register in LeftCycle and LeftShift RV[ShiftSize,24]; * number of bits to be shifted in simulated shift (or cycle) RV[ShiftValue,25]; * holds word to be shifted in simulated shift (or cycle) RV[Mask,26]; * the mask used in simulating the RF, WFA, and WFB operations RV[SimResult,27]; * result of simulated operations RV[Result,30]; * holds the hardware result of current operation **************************************************************************************** *** MAIN routine: SET[MainPage,1]; * set label for Main Program page ONPAGE[MainPage]; go: start: * Initialize random generator registers: XA ← 123, CA ← 33031 XA ← AND[0377, 123]C; XA ← (XA) OR (AND[177400, 123]C); CA ← AND[0377, 33031]C; CA ← (CA) OR (AND[177400, 33031]C); * Initialize random generator registers: XB ← 456, CB ← 33035 XB ← AND[0377, 456]C; XB ← (XB) OR (AND[177400, 456]C); CB ← AND[0377, 33035]C; CB ← (CB) OR (AND[177400, 33035]C); CLEARMPANEL; InnerLoopCounter ← 0C; * Initialize inner loop counter PassCount ← 0C; * Initialize outer loop counter bigLoop: t ← PassCount ← (PassCount) + 1; LU ← (MaxPass) - (t); GOTO [.+2, ALU >= 0]; Passed-EDField-Test: BREAKPOINT, goto[go]; INCMPANEL; *** SUBTEST 0 *** mainLoop: SubTest ← 0C; LU ← (LoopWithin); GOTO [ExtractFDescr, ALU # 0]; * Do next pattern value? InnerLoopCounter ← (InnerLoopCounter) + 1; GOTO [bigLoop, CARRY]; * Random (4005*XA + CA mod 2**16) t ← XA; ShiftValue ← t; ShiftSize ← 2C; * left shift old XA by 2 bits CALL [LeftShift]; t ← ShiftValue; XA ← (XA) + t; * add shifted value to XA ShiftSize ← 11C; * left shift original old XA by a total of 13C bits CALL [LeftShift]; t ← ShiftValue; t ← (XA) + t; * add shifted value to subtotal t ← (CA) + t; * add CA XA ← t; * result is new XA * Random (4005*XB + CB mod 2**16) t ← XB; ShiftValue ← t; ShiftSize ← 2C; * left shift old XB by 2 bits CALL [LeftShift]; t ← ShiftValue; XB ← (XB) + t; * add shifted value to XB ShiftSize ← 11C; * left shift original old XB by a total of 13C bits CALL [LeftShift]; t ← ShiftValue; t ← (XB) + t; * add shifted value to subtotal t ← (CB) + t; * add CB XB ← t; * result is new XB LU ← RandFlag; DBLGOTO [PatternAllOnes, PatternRandom, ALU = 0]; PatternAllOnes: CurrentPattern ← (ZERO) - 1, goto[ExtractFDescr]; PatternRandom: CurrentPattern ← t, goto[ExtractFDescr]; ExtractFDescr: t ← XA; * XA will yield the field descriptor for this test ShiftValue ← t; * we extract all our descriptor values by * ALU-simulated cycling and masking * (to avoid using the cycler-masker) ShiftSize ← 10C; * simulate an eight-bit left cycle CALL [LeftCycle]; t ← ShiftValue; FDescr ← t; FDescr ← (FDescr) and (377C); * mask to get entire field descriptor DecodeFDescr: t ← FDescr; * now decode this FDescr ShiftValue ← t; ShiftSize ← 14C; * simulate a twelve-bit left cycle CALL [LeftCycle]; t ← ShiftValue; StartBit ← t; StartBit ← (StartBit) and (17C); * mask to get field start bit index ShiftSize ← 4C; * simulate a further four-bit left cycle CALL [LeftCycle]; t ← ShiftValue; Length ← t; Length ← (Length) and (17C); * mask to get length field Length ← (Length) + 1; * adjust length value to actual length t ← (Length) - 1; t ← (StartBit) + t; EndBit ← t; * proper end bit index calculated LU ← (EndBit) - (20C); * check if end bit makes sense GOTO [EndBitPastEnd, ALU >= 0]; GOTO [RFTest]; EndBitPastEnd: GOTO [mainLoop]; *** SUBTEST 1 *** RFTest: SubTest ← 1C; * first simulate RF ShiftValue ← (ZERO) - 1; * form Mask t ← Length; ShiftSize ← t; CALL [LeftShift]; t ← (ShiftValue) xnor (0C); Mask ← t; t ← CurrentPattern; * left cycle current pattern by (Startbit + Length) bits ShiftValue ← t; t ← Length; t ← (StartBit) + t; ShiftSize ← t; CALL [LeftCycle]; t ← Mask; * apply Mask to left-cycled CurrentPattern t ← (ShiftValue) and t; SimResult ← t; CYCLECONTROL ← FDescr; * now do real RF t ← RF[CurrentPattern]; Result ← t; lu ← (LoopWithin) - (1C); * loop within this test? GOTO [.+2, ALU # 0]; GOTO [RFTest]; LU ← (SimResult) - (t); * compare RF results GOTO[WFATest, ALU = 0]; RFBAD: BREAKPOINT, goto[RFTest]; *** SUBTEST 2 *** WFATest: SubTest ← 2C; * first simulate WFA ShiftValue ← (ZERO) - 1; * form Mask t ← Length; ShiftSize ← t; CALL [LeftShift]; ShiftValue ← (ShiftValue) xnor (0C); t ← (StartBit) - (20C); t ← (Length) + t; ShiftSize ← (ZERO) - t; CALL [LeftShift]; t ← ShiftValue; Mask ← t; t ← CurrentPattern; * left cycle CurrentPattern by 20C - (StartBit + Length) bits ShiftValue ← t; CALL [LeftCycle]; t ← Mask; * apply Mask to left-cycled CurrentPattern t ← (ShiftValue) and t; SimResult ← t; CYCLECONTROL ← FDescr; * now do real WFA t ← WFA[CurrentPattern]; Result ← t; lu ← (LoopWithin) - (2C); * loop within this test? GOTO [.+2, ALU # 0]; GOTO [WFATest]; LU ← (SimResult) - (t); * compare WFA results GOTO[WFBTest, ALU = 0]; WFABAD: BREAKPOINT,goto[WFATest]; *** SUBTEST 3 *** WFBTest: SubTest ← 3C; * first simulate WFB ShiftValue ← (ZERO) - 1; * form Mask t ← Length; ShiftSize ← t; CALL [LeftShift]; ShiftValue ← (ShiftValue) xnor (0C); t ← (StartBit) - (20C); t ← (Length) + t; ShiftSize ← (ZERO) - t; CALL [LeftShift]; t ← ShiftValue; Mask ← t; t ← CurrentPattern; * apply inverse Mask to CurrentPattern SimResult ← t; t ← Mask; SimResult ← (SimResult) andnot t; t ← Mask; * insert masked CurrentPattern into XB's pattern t ← (XB) and t; SimResult ← (SimResult) or t; CYCLECONTROL ← FDescr; * now do real WFB t ← (WFB[CurrentPattern]) OR t; * register t still holds XB and Mask Result ← t; lu ← (LoopWithin) - (3C); * loop within this test? GOTO [.+2, ALU # 0]; GOTO [WFBtest]; LU ← (SimResult) - (t); * compare WFB results GOTO[.+2, ALU = 0]; WFBBAD: BREAKPOINT,goto[wfbtest]; GOTO[mainLoop]; ********* SUBROUTINE: LeftCycle ********* * * (to simulate LCycle without using the cycler-masker) * This subroutine left cycles ShiftValue by ShiftSize bits. LeftCycle: ShiftIndex ← 1C; CycleLoop: t ← (ShiftSize); LU ← (ShiftIndex) - (t) -1; GOTO[CycleEnd, ALU >= 0]; * done with cycles yet? t ← ShiftValue; * ShiftValue holds the value to be left cycled ShiftValue ← (ShiftValue) + t; * simulate a left shift by adding to self GOTO[.+2, NOCARRY]; * bit shifted out left comes back into right side ShiftValue ← (ShiftValue) + 1; ShiftIndex ← (ShiftIndex) + 1; GOTO[CycleLoop]; CycleEnd: RETURN; ********* SUBROUTINE: LeftShift ********* * * (to simulate LShift without using the cycler-masker) * This subroutine left shifts ShiftValue by ShiftSize bits. LeftShift: ShiftIndex ← 1C; ShiftLoop: t ← (ShiftSize); LU ← (ShiftIndex) - (t) - 1; GOTO[ShiftEnd, ALU >= 0]; * done with shifts yet? t ← ShiftValue; * ShiftValue holds the value to be left cycled ShiftValue ← (ShiftValue) + t; * simulate a left shift by adding to self ShiftIndex ← (ShiftIndex) + 1; GOTO[ShiftLoop]; ShiftEnd: RETURN; END;