% ******************************************************************************************** *** EDPackets.mc: Ethernet Board Exerciser microcode *** REVISION 1.1 *** *** Purpose: Sends random/contant data, variable/constant length packets in loopback mode *** Also test Overflow, UnderRun, and PurgeMode. EtherNet board can be in any slot. *** Can handle stitchweld and PC device IDs. *** *** Hardware Configuration: Standard 4 CPU boards, 96k Basic memory, D0Ethernet module. *** System in a 8-G Configuration. *** Approximate Run Time : 176D seconds. *** *** Written by: Bob Garner, Aug. 2, 1978 *** Modified by: Roy Ogus, June 26, 1979 *** Modified by: C. Thacker, June 29, 1979 *** Modified by: F. Itami/P.Hardjadinata, January 24, 1980 *** Standardize title page ,code format, and labels. *** Modified by: P. Hardjadinata, March 13, 1980 Implement looping. Modify the programs to make it work both in the Etch 1 and Etch 2 version board. *** Modified by: C. Thacker, May 3, 1980 Standardized assembly with packets.cm, fixed for new d0lang ******************************************************************************************** ********************************* SubTest Description: *********************************** * SUBTEST 0: Initialize Registers.(page 8) * SUBTEST 1: Check the Input ID.(page 8) * SUBTEST 2: Check the Output ID.(page 9) * SUBTEST 3: Check the State Register.(page 9) * SUBTEST 4: Check the State Register by enabling the Input and setting the Purge Mode. (page 9) * SUBTEST 5: Initialize Registers.(page 9) * SUBTEST 6: Verify Output WakeUp.(page 10) * SUBTEST 7: Check if there was an Output WakeUp, then if no wait for some time and task. (page 10) * SUBTEST 10: Check if there was an Output WakeUp, then set timer and wait for second WU. (page 10) * SUBTEST 11: UnderRun test.(page 15) * SUBTEST 12: Initialize registers and do some checkings in the beginning of LoopTest. (page 11) * SUBTEST 13: Set Up Base Pointers to read data from Input Buffer.(page 18) * SUBTEST 14: Preparing for LoopBack mode, and then notify to SUBTEST 17.(page 11) * SUBTEST 15: Preparing for Output Test Only, and then notify to SUBTEST 17.(page 13) * SUBTEST 16: No Input/Output WakeUp, so set the timer and wait for the wakeup.(page 11) * SUBTEST 17: Write data into memory, preparing to send data into Output Buffer.(page 16) * SUBTEST 20: Output data to the Output Buffer, and do some checkings.(page 16) * SUBTEST 21: Check the Output Status.(page 17) * SUBTEST 22: For Output Only Test, waiting until output is finished.(page 13) * SUBTEST 23: Read the Input Buffer, and do some checkings.(page 18) * SUBTEST 24: Check whether Purge Mode or OverRun Mode and branch accordingly.(page 19) * SUBTEST 25: Verify the data read from the Input Buffer with the data sent to the Output Buffer. (page 14) * SUBTEST 26: Wait until the Output is finished.(page 14) *************************** Subroutine Description: *************************************** BSetup: To set up XWPtr and XWCount for single-word transfers. . . *************************** Special Reg. Definition: ************************************** LoopMode: Bit 16 and 17 are used to control the type of hardwareloopback. Bit 16: Loopback path control = 0 - Loopback through controller = 1 - Loopback through transceiver Bit 17:Input hardware control = 0 - Loopback through input = 1 - Input disabled Thus the LoopBack modes are set up as follows: LoopMode = 0: Loopback through input, Loopback through controller (Default Case) LoopMode = 1: Input disabled, Loopback through controller LoopMode = 2: Loopback through input,Loopback through transceiver LoopMode = 3: Input disabled , Loopback through transceiver. MAXPASS: This register is used to control the number of times the packets data stream is loopbacked through the hardware before ending a program pass. The default case is set for 1000B but can be changed by entering via Midas a value of 1 through 1000 octal into MAXPASS. SizeData: Packet size/data format control flag. Bit 16: Size control = 0 - constant size = 1 - variable size (1 through 1000 packets) Bit 17: Data control = 0 - constant data = 1 - random data Thus the packet size/data modes are set up as follows: SizeData = 0: Constant data, constant length packets SizeData = 1: Random data, constant length packets SizeData = 2: Constant data, varying length packets SizeData = 3: Random data, varying length packets (Default Case) If constant packet size and/or constant data is desired the following instructions apply. The packet size is set up by entering via Midas a value of 1 through 1000 octal into PKTSIZE A constant data word is set up by entering via Midas any 16 bit value(in octal) into VM 210 RepeatMode: At any breakpoint, the user has the choice of setting RepeatMode to a 1 to loop on the current mode. During the Repeat Mode, the user can modify the type of data by changing the SizeData register. 1, the current test will loop repeatedly for trouble shooting 0, no looping in current mode TestFlag: PurgeMode and OverRun Test Flags. Bit 0: Purge Mode test = 1 Bit 17: Overrun test = 1 Thus the Test Flag modes are set up as follows: Test Flag = 0: Neither test (Default Case) Test Flag = 1: OverRun test. Data is loaded into OutputBuffer in LoopBack mode such that whenever the Input Buffer is full, data is still being sent to the Output Buffer. At this point, overrun happens and OverRun bit is tested. Test Flag = 100000: PurgeMode test. During this mode, reading the Input Buffer is disabled. Hence, at this mode after sending data to the Output Buffer, we shouldn't get any input wakeup. DATADIFFERENCE: The result of comparing a received data word with a tranmitted data word is place here. HOSTADDR: Host address is read from the switch register on the D0Ethernet board and is displayed in register HOSTADDR Control Block Memory locations. VM 203 - Amount actually used in input buffer for received packets VM 204 - Size of input buffer. VM 205 - Pointer to start of input buffer. VM 206 - Size of output buffer VM 207 - Pointer to start of output buffer VM 210 - Datum to be used for constant-data packets Packets Memory buffers. MM 1000-1777 - Output buffers used to store current packets data. MM 3000-4007 - Input buffers used to store current packets data. ************************************* THEORY OF OPERATION *************************************** 1. CAddr Test The first test is to find the Ethernet board in the system. The Ethernet board is unsual in that it has two CAddr registers, one for each Output and Input tasks. The algorithm assumes the next board in the chain is the Ethernet board and it transmits two CAddr for the Input and Output tasks. Then it attempts to read it back; and if unsuccessful, it tries again. It repeats this process ten times and if the board is not found, then a breakpoint is encountered and a message "BoardNotFound" is displayed. The test to determine if the Ethernet board is present is to read the board identification or ID. The Ethernet has two ID's, one for the Original stitchweld and one for the etch. There is only one official ID and all the original stitchwelded boards will be retrofitted to the new ID. Whenever there is an Output ID error, then a breakpoint is encountered and a message is diplayed, "OutIDWrong" for the old board and "OutIDNewWrong" for the new board. This test is done twice, once for the Input ID and again for the Output ID. 2. State Test Once the board is found, the state registers are verified to be operational. They are loaded and the contents are read and verified. If there is no match, then the program will break. Again, the display will indicate the reasons for the breakpoint with a variety of messages such as "StateNotZero", "StateNotSet", or "StateNotReset". 3. Output WakeUp Test The next test verifies the Output WakeUp function. The functions to verify the Output WakeUp are Output, Loopback, and Jam. If the Output WakeUp is functioning properly, then many wakeups are generated at the proper time until the Output Buffer has more than eleven words. Conversely, if the Output WakeUp is not functioning properly, one of the following three breakpoints can be expected: "BadOutTask" - There is a wakeup when none is expected "NoOutWakeUp" - There is no Output WakeUp when it was expected "NoTransmit" - The Output WakeUp did not occur because there was no transmission from the Output to the Input Buffer 4. UnderRun Test Whenever the data tranmission is to end, there is a control word transmitted which indicates the end of transmission (End of Ouput Packets). Without this control word, whenever the Output Buffer receiving data from the D0 is empty, an UnderRun flag is set. The D0 is notified by the IOAttention line that there was an unusual status or that the UnderRun flag is set. The status word is read and the UnderRun bit is checked. For the UnderRun test, this bit should be set, and if it is not, then a breakpoint occurs and the message "NoUnderRun" is displayed. 5. Loop Test The actual data transfer test starts from the LoopTest. First the registers will be initialized and certain conditions are checked. Next Upsize is executed and depending upon the LoopMode and SizeData registers, the Operation Mode, Packets Size, and random or fixed data type are set. The Purge Mode is only tested once during the loop when the PktCount is equal to 63B. Similarly, the OverRun test is executed but once each loop when the PktCount equals 137B and the packet size is greater than 25B. Once the parameters are set, the data pattern as determined by SizeData register are generated and written into the memory starting from address location 1000B up to 1777B. Data are written in blocks as determined by the packets size. When the quantity of data as determined by the packets size is written into the buffer, a buffer full is indicated. Then the data are transferred from this buffer to the Output Buffer on the Ethernet board. If the loopback and input are enabled, whenever there is an Input WakeUp, data would be read back to the memory starting from memory location 3000B up to 4007B. Finally, with the data in memory, the original and returned data are compared to verify the integrity of the loop. The process repeats from the Loop label in program. ************************************** TEST STRATEGY ******************************************** As a guide, use the section 5 of "Test Sequence" from The Ethernet/Xerox Wire Test Microprogram written by Roy Ogus (file under [ISIS]EDPackets.dmdoc). In general, the steps would be the same as using the new EDPackets microprogram. Below are the differences: - For LoopForEver feature, you can either use the EDPacketsLog.midas, by typing "EDPACKETSLOG" at the Input Text Line and bug "Read-Cmds", or select RepeatMode = 1 from Midas display. - If you have an error in Loopback test (Section 5.2.2), select RepeatMode by setting the value to 1. Then try to use constant data and a fixed length of Packets by selecting the SizeData register equal to 0. Constant data used in this test have to be selected by loading the value into VM 210. The length of the packets has to be selected by setting the value in PktSize register. Then by bugging continue, you can now trace the problem since the program will loop forever. - Registers used would be depend on the current TASK running. For example XWTemp is a base register for TASK 0, XWOTemp for TASK 2(Output Task) and XWITemp for TASK 3(Input Task). When you read the registers value from the midas display, be sure that you read the correct registers. The best way is by looking at CTASK register first to determine the running TASK. Then look on the screen to verify that this particular register has different name for each TASK. ************************************** BREAKPOINT TABLE: **************************************** BadDataCompare: The input data word (in XWTemp) does not equal the corresponding transmitted word (SUBTEST= 25) (in XWTEmp1). The address of the received word can be seen in T 20. BadInCount: Received packet size (MM 203) does not equal the transmitted packet size (MM 206) (SUBTEST= 25) BadInStatus: A packet was received with bad input status. The status (input and output) (SUBTEST= 23) can be seen in register XWTemp + 60. BadOutStatus: A bad output status was detected during execution of the inner loop. (SUBTEST= 20) The output status can be seen in register XWTemp + 40. BadOutStatusEOP: A bad output status was detected after the end of the packet. (SUBTEST= 21) The output status can be seen in register XWTemp + 40. BoardNotFound: D0 Ethernet board not found in the machine. (SUBTEST= 1) InOutHang: Input or output is hung up. (SUBTEST= 16) InRanAgain1: Input task ran again after it was disabled. (SUBTEST= 24) InPacketSize: The received packet too large for the input buffer. (SUBTEST= 23) NoOutAttn: At the end of the packet, the Attn line should be set. (SUBTEST= 21) NoOverRun: The overrun status bit not set after the overrun test. (SUBTEST= 23) BadOutTask: Output occured when it was not expected. (SUBTEST= 7) NoOutWakeup: Output task didn't wakeup after it had tasked. (SUBTEST= 10) NoTransmit: The output section is trying to transmit a packet, but cannot. (SUBTEST= 11) NoUnderRun: On the underrun test, the underrun bit in the output status was not set. (SUBTEST= 6) OutIDNewWrong: Output Device ID wrong (New board) (SUBTEST= 2) OutIDWrong: Input device ID correct but Output Device ID wrong (SUBTEST= 2) OutRanAgain: Output Task ran again after it was disabled. (SUBTEST= 21) Passed-EDPACKETS-Test: Test completed, no errors encountered. (For default case, SUBTEST= 10100) (SUBTEST= 12) StateNotReset: State register not all zeroes. (SUBTEST= 5) StateNotSet: State Register not all ones. (SUBTEST= 4) StateNotZero: State and Status registers nonzero when they should be zero. (SUBTEST= 3) ********************************************************************************** Logic Analyzer Sync Points at Control Store Address: Control Store Address: 512 UpSize % ****************************** INITIALIZATION: ********************************** TITLE[EDPackets]; *ED Acceptance test for Ethernet boards IMRESERVE[0,0,100]; *Reserve space used by the kernel IMRESERVE[0,100,20]; SET TASK[0]; ******************************* Tasks: ******************************************* Set[EITask, 3]; *Input task Set[EOTask, 2]; *Output task Set[EINotifyTask, LSHIFT[EITask,14]]; *Input task for notify Set[EONotifyTask, LSHIFT[EOTask,14]]; *Output task for notify ******************************* XWC I/O Address Registers: *********************** Set[XIData, 3]; *Input data Set[XWStatus, 2]; *Status/State register Set[XOData, 1]; *Output data Set[XWReadState, 2]; Set[XWWriteState, 0]; ******************************* Macro Constants: ********************************* MC[XWRState, OR[LSHIFT[EITask,4],2]]; *State register read MC[XWWIState, OR[LSHIFT[EITask,4],0]]; *Input State register write MC[XWWOState, OR[LSHIFT[EOTask,4],0]]; *Output State register write MC[XWRHost, OR[LSHIFT[EITask,4],1]]; *Host address read MC[XIDevID, OR[LSHIFT[EITask,4],0]]; *Input Device ID register MC[XODevID, OR[LSHIFT[EOTask,4],0]]; *Output Device ID register **************************** R-registers for Tasks 0: **************************** RV[XWBase, 0]; *Base register for first 64K space RV[XWBaseHi, 1]; *Base register for first 64K space RV[XWPTR, 2]; *Buffer base register RV[XWPTRHI, 3]; *Buffer base register RV[XWCount,4]; *Main loop counter RV[XWTEMP,5]; *Temporary registers RV[XWTEMP1,6]; RV[XWTEMP2,7]; RV[XWPTR1,10]; *Alternate Buffer base register RV[XWPTRHi1,11]; *Alternate Buffer base register *************************** R-registers for Task 2:****************************** RV[XWOBase, 40]; *Base register for first 64K space RV[XWOBaseHi, 41]; *Base register for first 64K space RV[XWOPTR, 42]; *Buffer base register RV[XWOPTRHI, 43]; *Buffer base register RV[XWOCount,44]; *Main loop counter RV[XWOTEMP,45]; *Temporary registers RV[XWOTEMP1,46]; RV[XWOTEMP2,47]; RV[XWOPTR1,50]; *Alternate Buffer base register RV[XWOPTRHi1,51]; *Alternate Buffer base register RV[XA,54,123]; *Random number generator register RV[CA,55,33031]; *Random number generator register RV[SizeData,56,3]; *Points to task 2 reg 16B RV[XWIRan,57]; *Points to task 2 reg 17B *************************** R-registers for Task 3:*************************** RV[XWIBase, 60]; *Base register for first 64K space RV[XWIBaseHi, 61]; *Base register for first 64K space RV[XWIPTR, 62]; *Buffer base register RV[XWIPTRHI, 63]; *Buffer base register RV[XWICount,64]; *Main loop counter RV[XWITEMP,65]; *Temporary registers RV[XWITEMP1,66]; RV[XWITEMP2,67]; RV[XWIPTR1,70]; *Alternate Buffer base register RV[XWIPTRHi1,71]; *Alternate Buffer base register RV[TestFlag,76]; *Points to task 3 reg 16B *************************** Global R-registers: ***************************** RV[PktSize,15]; *Current Size of packet RV[PktCount, 20]; *Number of current packets RV[XOFlag, 21]; *Output done Flag RV[PassCount, 22,0]; *Down-Counter for number of times packets is looped back * in the outer output packets loop RV[MaxPass, 23,1000]; *Used to set the maximum number of times packets is looped * back in outer output packets loop (set up for 512D times) RV[RepeatMode, 24,0]; *Used to select looping in the same mode (RepeatMode=1) * or normal mode (RepeatMode=0) RV[HostAddr, 25]; *Ethernet host address....HIGH BYTE/LOW BYTE, RV[LoopMode, 26, 0]; *Flags used to control the type of hardware loopback RV[SUBTEST,27,0]; *A register used to indicate the MaintPanel Count * when the program is halted. RV[IOS4Cnt,30]; *Number of IOStore4's done by input main loop RV[DataDifference,31]; *Data difference between transmitted and received RV[REVISION,32,1]; *Used to show EDPackets REVISION level on Midas screen RV[RUN-TIME,33,260]; *Used to indicate how long in 260B sec. (176 Decimal) * it takes to run the default case of EDPackets ************************** Control block addresses (relative to 200): ************* MC[XWDelayLOC, 2]; *Delay value between output packets (OutOnly test) MC[XWELOC, 3]; *Ending word count MC[XWICLOC, 4]; *Input count MC[XWIPLOC, 5]; *Input pointer MC[XWOCLOC, 6]; *Output count MC[XWOPLOC, 7]; *Output pointer MC[XWDataLOC, 10]; *Constant word to be outputed ************************** Status masks (Ethernet): ******************************* MC[EStatusMask, 177400]; *Status mask MC[EOStatusMask, 53000]; *Output status mask MC[EIStatusMask, 124400]; *Input status mask MC[EUnderRunMask, 40000]; *underrun status mask MC[EOVRBadMask, 20400]; *overrun, bad alignment status mask MC[EOVRMask, 20000]; *overrun status mask ************************** Miscellaneous: **************************************** MC[DisableInputOutput, 300]; *Disable input and output MC[XWCAddr, AND[NOT[OR[LSHIFT[EOTask,4],EITask]],377]]; ************************** Stitchweld boards device IDs: ************************* MC[ENIDHi, 2400]; *Ethernet ID word high part MC[EIIDLo, 2]; *Ethernet ID word (low input) MC[EOIDLo, 1]; *Ethernet ID word (low output) ************************** PC boards device IDs: ********************************** MC[EIIDNew, 3400]; *Ethernet ID word (input) (New ID) MC[EOIDNew, 3000]; *Ethernet ID word (output) (New ID) M@[$Size, LDF[#1, 7, 11]]; *Mask for maximum size of packet (1000) M@[SKIPON, GOTO[.+2,#1]]; *Skip Macro ************************** AT locations: ****************************************** Set [TestPage, 1]; *Page for driver code Set [OutPage, 2]; *Page for output code Set [InPage, 2]; *Page for input code Set[RS1Loc, OR[LSHIFT[TestPage,10], 10]]; *Address of RS1 Set[LoopTestLoc, OR[LSHIFT[TestPage,10], 14]]; *Address of LoopTest Set[VerifyLoc, OR[LSHIFT[4,10], 2]]; *Address of Verify Set[POBuzzLoc, OR[LSHIFT[4,10], 6]]; *Address of POBuzz loop (on same page as Verify) Set[OStartLoc, OR[LSHIFT[OutPage,10], 4]]; *Address of OStart Set[OBeginLoc, OR[LSHIFT[OutPage,10], 6]]; *Address of OBegin Set[IStartLoc, OR[LSHIFT[InPage,10], 2]]; *Address of IStart *************************************************************************************************** *** RESTART: * This program is used to switch into TASK 0 and goto Start in the Main routine. * ON PAGE[TestPage]; RV[R0, 0]; RS: T _ R0; R0 _ AND[0377, RS1Loc]C; *Notify into task 0 at RS1Loc, usually from other task R0 _ (R0) OR (AND[007400, RS1Loc]C); APC&APCTask _ R0; RETURN, R0 _ T; *Restore R0 *************************************************************************************************** *** MAIN routine: * * ******************************************* TASK 0 ********************************************** * *** SUBTEST 0 *** GO: Start: SUBTEST _ 0C, AT [RS1Loc]; *To simulate maintance panel. ClearMPanel; XWBaseHi _ 0C; *Initialize base registers, pointers XWBase _ 200C; XWPtrHi _ 300C; XWPtrHi1 _ T _ 377c; ZapDevices: Output[XWPtrHi]; *Send #300 to all devices (Ethernet zap) XWPtrHi1 _ T _ (XWPtrHi1) - 1; goto[ZapDevices,ALU>=0]; XWPtrHi _ 0c; XWPtrHi1 _ T _ 377c; ZapDevicesX: Output[XWPtrHi]; *send 0 to all devices XWPtrHi1 _ T _ (XWPtrHi1) - 1; goto[ZapDevicesX,ALU>=0]; XWPtrHi1 _ 0c; TASK; * After tasking, will return to TASK 0 *** SUBTEST 1 *** InitPktCnt:SUBTEST _ 1C; PktCount _ 144C; *count every 100 packets T _ XWTemp _ 0C; *CAddr gets 1's XWTemp1 _ 100C; *generate 16*4B SR Clocks SetCAddr: XWTemp1 _ (XWTemp1) - 1, GENSRCLOCK; GOTO [SetCAddr,ALU#0]; XWTemp _ 12C; SetMPanel: *PANEL = 10D IncMPanel; nop; XWTemp _ (XWTemp) -1; goto[SetMPanel, ALU#0]; T _ XWTemp _ XWCAddr; *Load Input & Output CAddr of the first 2 devices XWTemp1 _ 10C; *generate 8 SRClock's LdCAddr:XWTemp1 _ (XWTemp1) - 1, GENSRCLOCK; GOTO [LdCAddr,ALU#0], T _ XWTemp _ RSH [XWTemp, 1]; XWTemp1 _ 12C; *check the Board ID # 10 times Call[FindUs], T _ XIDevID; *Read the input ID T _ XWTemp; *Save ID in case new board(PC Board) XWTemp _ (XWTemp) XOR (ENIDHi); XWTemp _ (XWTemp) XOR (EIIDLo); GOTO[IFoundIt,ALU=0],XWTemp2 _ 0C; *Is Input ID of SW board found ?If yes, goto IFoundIt XWTemp _ T; *Not found, so check the ID for PC board XWTemp _ (XWTemp) XOR (EIIDNew); GOTO[IFoundIt1,ALU=0],XWTemp2 _ 100000C;*Input ID of new-ID board found SKIPON[R>=0], XWTemp1 _ (XWTemp1) - 1; *Did we try 10 times ? BoardNotFound: BREAKPOINT, GOTO[RS]; *If yes, BREAK - EtherNet board not found T _ XIDevID; *Load again the Input CAddr to the device XWTemp _ 2C; GENSRCLOCK; GOTO[.-1,R>=0], XWTemp _ (XWTemp) - 1; FindUs: Input[XWTemp]; RETURN; *** SUBTEST 2 *** IFoundIt1:NOP; IFoundIt:SUBTEST _ 2C; IncMPanel; *PANEL = 11D T _ XODevID; *Read Output Device ID INPUT [XWTemp]; GOTO [NewBoard, R<0], LU _ XWTemp2; *Is this a PC board ? If yes, goto NewBoard XWTemp _ (XWTemp) XOR (ENIDHi); *Check the output device ID XWTemp _ (XWTemp) XOR (EOIDLo); SKIPON[ALU=0]; *Skip if the ID is correct OutIDWrong: BREAKPOINT, GOTO[RS]; *BREAK - Output Device ID wrong GOTO [ReadHost1], T _ XWRHost; *ID is correct , so goto ReadHost1 NewBoard: XWTemp _ (XWTemp) XOR (EOIDNew); *Check output ID of PC board SKIPON[ALU=0]; OutIDNewWrong: BREAKPOINT, GOTO[RS]; *BREAK - Output Device ID wrong (New board) ReadHost: T _ XWRHost; ReadHost1: INPUT [HostAddr]; * Read host address in switches T _ XWTemp2; *Set high bit if new board HostAddr _ (HostAddr) OR (T); XWTemp _ DisableInputOutput; T _ XWWIState; OUTPUT [XWTemp]; T _ XWWOState; OUTPUT [XWTemp]; *Clear State Register XWTemp _ XWTemp; *wait for Output *** SUBTEST 3 *** SUBTEST _ 3C; IncMPanel; *PANEL = 12D T _ XWRState; INPUT [XWTemp]; *read state LU _ XWTemp; SKIPON[ALU=0]; *skip if State-Status=0 StateNotZero: BREAKPOINT, GOTO[RS]; *BREAK - Zero State & Status read *** SUBTEST 4 *** StateTest:SUBTEST _ 4C; IncMPanel; *PANEL = 13D XWTemp _ 310c; T _ XWWIState; OUTPUT [XWTemp]; *Reset Input and enable Loopback T _ XWWOState; OUTPUT [XWTemp]; *don't EnableOuput XWTemp _ 335C; *EnableInput, Loopback OUTPUT [XWTemp]; T _ XWWIState; OUTPUT [XWTemp]; XWTemp _ 375C; OUTPUT [XWTemp]; *Now set PurgeMode T _ XWWOState; OUTPUT [XWTemp]; XWTemp _ T _ XWRState; *Abort on OUTPUT instr INPUT [XWTemp]; *Read back set value XWTemp _ LDF[XWTemp,12,6]; *Extract state field XWTemp _ (XWTemp) XOR (75C); *reverse set value(EnableOut=0) SKIPON[ALU = 0]; *Skip if bits set correctly StateNotSet: BREAKPOINT, GOTO[RS]; *BREAK - State Reg not set *** SUBTEST 5 *** SUBTEST _ 5C; IncMPanel; *PANEL = 14D XWTemp _ DisableInputOutput; T _ XWWIState; OUTPUT [XWTemp]; T _ XWWOState; OUTPUT [XWTemp]; *Clear State Register XWTemp _ T _ XWRState; *Abort on OUTPUT instr INPUT [XWTemp]; *Read back zero value XWTemp _ LDF [XWTemp,12, 6]; *Extract state field SKIPON[ALU = 0]; *Skip if bits reset correctly StateNotReset: BREAKPOINT, GOTO[RS]; *BREAK - State not reset *** SUBTEST 6 *** VerifyOW:SUBTEST _ 6C; *Verify output WakeUp IncMPanel; *PANEL = 15D XWIRan _ 0C; XWTemp _ AND[0377, OStartLoc]C; *Notify into OutputTask and goto OStart XWTemp _ (XWTemp) OR (OR[EONotifyTask,AND[007400, OStartLoc]]C); CALL[CompLoopRet], APC&APCTASK _ XWTemp; *** *** Should go to TASK 2, OStart,on page15. *** ******************************************* TASK 0 ********************************************** * *** SUBTEST 7 *** CkOutTask:SUBTEST _ 7C; *Check the Output WakeUp XWTemp _ 313C; *Enable Output, LoopBack, and Jam T _ XWWIState; OUTPUT [XWTemp]; T _ XWWOState; OUTPUT [XWTemp]; IncMPanel; *PANEL = 16D XWIRan _ (XWIRan) XOR (1C); SKIPON[ALU=0]; *skip if Task2 ran and then tasked BadOutTask: BREAKPOINT, GOTO[RS]; *BREAK - OutWake when it shouldn't be XWTemp _ 4C; *Wait for WakeOutTimer to expire GOTO[.,R>=0], XWTemp _ (XWTemp) - 1; NOP; TASK; *See if there is an Output WakeUp NOP; *If yes, goto Task2 *** *** If there is no wakeup, then continue in TASK 0 *** If there is an Output wakeup, then goto OutTask, page 15, in TASK 2 *** *** SUBTEST 10B *** CheckTask:SUBTEST _ 10C; *Check that the hardware caused output *task to run this time IncMPanel; *PANEL = 17D XWIRan _ (XWIRan) XOR (1C); SKIPON[ALU=0]; *skip if output task ran and then tasked NoOutWakeup: BREAKPOINT, GOTO[RS]; *BREAK - output task didn't wakeup IncMPanel; *PANEL = 18D CALL[WaitUnBuzz], XWTemp _ 77400C; * Wait for underrun test to complete. *Timeout if it takes too long. WaitUnBuzz: SKIPON[R<0], XWTemp _ (XWTemp) -1; retxz: RETURN; *** *** If there is no wakeup, then continue in TASK 0 *** If there is an Output wakeup, then goto TwelveOut, page 15, in TASK 2 *** NoTransmit: BREAKPOINT, GOTO[RS]; *BREAK - Output is hung up ******************************************* TASK 0 ********************************************** * *** SUBTEST 12B *** LoopTest:SUBTEST _ 12C, AT [LoopTestLoc]; PassCount _ 0C; *Set up PassCount ClearMPanel; XWTemp _ 6C; *Allow for a delay GOTO[ ., R>=0], XWTemp _ (XWTemp) - 1; XWTemp _ 1400C; XWTemp _ (XWTemp) OR (350C); SetMPanelA: *Set MaintPanel into 1000 IncMpanel; call[retxz]; XWTemp _ (XWTemp) - 1; GOTO[SetMPanelA , ALU#0]; NOP; Loop: GOTO[UpSize,R>=0], PktCount _ (PktCount) - 1; *Is it still in LoopBack test ? PktCount _ 143C; *if no, initialize the PktCount again IncMpanel; NOP; PassCount _ (PassCount) + 1; T _ (PassCount) + 1; LU _ (MaxPass) - T; GOTO[UpSize1, ALU >= 0]; *Has MaxPass been reached ? If not, goto UpSize1 Passed-EDPACKETS-Test: BREAKPOINT, GOTO[RS]; *Test successful; Completed all passes UpSize1:NOP; *Update packet size, if specified by SizeData flag UpSize: T _ LDF [SizeData, 16, 1], AT [512]; *bit 16 is size control PktSize _ ($Size[PktSize]) + (T); PStore1 [XWBase, PktSize,XWOCLOC!]; CheckOutOnly: *Check whether an output only test (LoopMode[17] = 1) SKIPON[R EVEN], LU _ LoopMode; *If LoopMode[17]=0 then skip to SetFlag GOTO [XWOutLoop]; SetFlag: *Set TestFlag to 1 to indicate Overrun test, 100000C for PurgeMode test LU _ (PktCount) XOR (137c); *Packet 137 gets overrun test GOTO [CheckPM, ALU#0], LU _ (PktCount) XOR (63c); *Packet 63 gets Purge Mode test LU _ (PktSize) - (25C); *Only do Overrun test if size > 25 SKIPON [ALU<0]; GOTO [NotifyIn], TestFlag _ 1C; *Set bit 17 indicating Overrun Test GOTO [NotifyIn], TestFlag _ 0C; *Neither test, set TestFlag to zero CheckPM:SKIPON [ALU#0], TestFlag _ 0C; *Neither test, set TestFlag to zero TestFlag _ 100000C; *Set bit 0 indicating Purge Mode Test NotifyIn:XWTemp _ AND[0377, IStartLoc]C; *Notify the input task Code at IStart XWTemp _ (XWTemp) OR (OR[EINotifyTask,AND[007400, IStartLoc]]C); CALL[CompLoopRet], APC&APCTASK _ XWTemp;*This task is necessary *** *** Go to TASK 3, IStart on page 18. *** *** SUBTEST 14B *** NotifyOut:SUBTEST _ 14C; *Check bit 16 in LoopMode to determine whether in *local loopback mode or not LU _ LDF[LoopMode, 16, 1]; SKIPON[ALU#0], XWTemp _ 300C; *Set or clear loopback, to avoid glitch XWTemp _ (XWTemp) OR (10C); *Bit 16 = 0 => OR in Loopback bit T _ XWWIState; OUTPUT[XWTemp]; T _ XWWOState; OUTPUT[XWTemp]; XWTemp _ (XWTemp) or (23c); *Enable Input, Output, Jam OUTPUT[XWTemp]; T _ XWWIState; OUTPUT[XWTemp]; XWTemp _ AND[0377, OBeginLoc]C;* Notify the output Code at OBegin (init it's TPC entry) XWTemp _ (XWTemp) OR (OR[EONotifyTask,AND[007400, OBeginLoc]]C); CALL[CompLoopRet], APC&APCTASK _ XWTemp;*This task is necessary *** *** Go to TASK 2, OBegin on page 16. *** *** SUBTEST 16B *** Buzz0: SUBTEST _ 16C; * Wait until Input or Output WakeUp comes up, or the timer is off XWIRan _ 77400C; CALL[Buzz], XOFlag _ 0C; *Clear output done flag Buzz: SKIPON[R<0], XWIRan _ (XWIRan) -1; RETURN; RepeatMode _ RepeatMode, goto[.+2, R EVEN]; * Looping if RepeatMode is selected goto[UpSize]; InOutHang: BREAKPOINT, GOTO[RS]; *BREAK - Input or output is hung up RepeatMode _ RepeatMode, goto[.+2, R EVEN]; * Looping if RepeatMode is selected goto[UpSize]; ******************************************* TASK 0 ********************************************** * XWOutLoop: * Notify the input task Code at IStart XWTemp _ AND[0377, IStartLoc]C; XWTemp _ (XWTemp) OR (OR[EINotifyTask,AND[007400, IStartLoc]]C); CALL[CompLoopRet], APC&APCTASK _ XWTemp; *** *** Go To TASK 3, IStart on page 18 *** *** SUBTEST 15B *** *Check bit 16 in LoopMode to determine whether in local loopback mode or not NotifyOutOnly: SUBTEST _ 15C; LU _ LDF[LoopMode, 16, 1]; SKIPON[ALU#0], XWTemp _ 303C; *Enable Output, Jam XWTemp _ (XWTemp) OR (10C); *Bit 16 = 0 => OR in Loopback bit T _ XWWIState; OUTPUT[XWTemp]; T _ XWWOState; OUTPUT[XWTemp]; XWTemp _ AND[0377, OBeginLoc]C; * Notify the output Code at OBegin (init it's TPC entry) XWTemp _ (XWTemp) OR (OR[EONotifyTask,AND[007400, OBeginLoc]]C); CALL[CompLoopRet], APC&APCTASK _ XWTemp; *** *** Go to TASK 2, OBegin on page 16. *** *** SUBTEST 22B *** OutputFinish: * Wait for output to finish. SUBTEST _ 22C; XWIRan _ 0C; CALL[OutOnlyBuzz], XOFlag _ 0C; *Clear output done flag OutOnlyBuzz: SKIPON[R ODD], LU _ XOFlag; RETURN, XWIRan _ (XWIRan) + 1; T _ XWDelayLOC; * Now delay before starting again PFetch1[XWBase,XWTemp]; *Set delay time Buzz1: XWTemp1 _ 100C; Buzz2: NOP; *Inner count down loop TASK; XWIRan _ (XWIRan) + 1; *Count how often Task 0 runs GOTO[Buzz2,R>=0], XWTemp1 _ (XWTemp1) - 1; GOTO[Buzz1,R>=0], XWTemp _ (XWTemp) - 1;* Outer count down loop RepeatMode _ RepeatMode, goto[.+2, R EVEN]; * Looping if RepeatMode is selected GOTO[UpSize]; GOTO[LOOP]; CompLoopRet: RETURN; * Control returns here from the input task to check the data. We then go back to Loop to do * it again (i.e., send another packet). Verify that ELOC = OCLOC (number of words sent = * number received). * Note: Task's should not occur on the next 3 PFetch1's since the INPUT at NoMore+3 might run * A situation which currently a MEMORY BUG. ******************************************* TASK 0 ********************************************** * *** SUBTEST 25B *** ON PAGE[4]; Verify: SUBTEST _ 25C, AT[VerifyLoc]; PFetch1[XWBase, XWTemp,XWOCLOC!]; NOP; PFetch1[XWBase, XWCount,XWELOC!]; *Fetch input count T _ XWCount; LU _ (XWTemp) XOR (T); *Is number oftransmitted words equal received words ? GOTO[GoodInCount,ALU=0]; *Skip if counts compare GOTO[.+1]; RepeatMode _ RepeatMode, goto[.+2, R EVEN]; * Looping if RepeatMode is selected GOTO[ToUpSize]; BadInCount: BREAKPOINT; *BREAK - Counts don't compare RepeatMode _ RepeatMode, goto[.+2, R EVEN]; * Looping if RepeatMode is selected GOTO[ToUpSize]; LoadPage[TestPage]; GOTOP[RS]; GoodInCount: PFetch1[XWBase, XWPtr1, XWOPLOC!]; *Locate beginnings of memory buffers NOP; PFetch1 [XWBase, XWPtr, XWIPLOC!]; T _ (XWCount) - 1; XWPtr1 _ (XWPtr1) + (T); *Adjust Ouput Pointer XWPtr _ (XWPtr) + (T); *Adjust Input Pointer CALL[CompLoop],XWCount _ (ZERO) - (T) - 1; *XWCount _ - Count CompLoop: *Verify that the transmitted data equals received data GOTO [.+2, R>=0], T _ XWCount _ (XWCount) + 1; *Have we finished comparing data? *If yes, goto Loop GOTO[.+2]; GOTO[ToLoop]; PFetch1 [XWPtr, XWTemp]; *Fetch received word NOP; PFetch1 [XWPtr1, XWTemp1]; *Fetch transmitted word T _ XWTemp; T _ (XWTemp1) XOR (T); GOTO [CompLoopRet1, ALU=0]; *Skip if data words equal DataDifference _ T; T _ XWCount; *Put address of input word in T T _ (XWPtr) + (T); RepeatMode _ RepeatMode, goto[.+2, R EVEN]; * Looping if RepeatMode is selected GOTO[ToUpSize]; BadDataCompare: BREAKPOINT; *BREAK - Data doesn't compare RepeatMode _ RepeatMode, goto[.+2, R EVEN]; * Looping if RepeatMode is selected GOTO[ToUpSize]; GOTO[.+1]; CompLoopRet1: RETURN; * Get here after purge mode or Overrun test notify from input task microcode. * Don't check packet, wait for output to complete. *** SUBTEST 26B *** SUBTEST _ 26C, AT [POBuzzLoc]; CALL[POBuzz]; POBuzz: SKIPON[R ODD], LU _ XOFlag; RETURN, XWIRan _ (XWIRan) + 1; ToLoop: RepeatMode _ RepeatMode, goto[.+2, R EVEN]; * Looping if RepeatMode is selected GOTO[ToUpSize]; LoadPage[TestPage]; GOTOP[Loop]; ToUpSize:LoadPage[TestPage]; GOTOP[UpSize]; ******************************************* TASK 2 ********************************************** * ON PAGE [OutPage]; RSInOut: LoadPage[TestPage]; goto[RS]; OStart: * First Notify wakeup comes here XWIRan _ (XWIRan) + 1, AT[OStartLoc]; *This must be 3 instructions minimum. TASK; NOP; *** *** If no Output wakeup, then GoTo TASK 0, CkOutTask on page 10 *** If there is an Output wakeup, then continue in TASK 2 *** OutTask: * First hardware wakeup comes here XWIRan _ (XWIRan) + 1; TASK; *** *** Normally once we get an Output WakeUp we will get more, hence continue in TASK 2 *** * Second hardware wakeup comes here (Set up base pointers) SecondTask: XWOBaseHi _ 0C; XWOBase _ 200C; XWOPtrHi _ 0C; CALL[TwelveOut], XWOTemp _ 2C; TwelveOut: *Test for UnderRun NOP; *Minimum size loop = 3. SKIPON[R<0], XWOTemp _ (XWOTemp) - 1; RETURN, IOFetch4[XWOBase,XOData,0]; NOP; CALL[UnBuzz]; * Wait for UnderRun *** SUBTEST 11B *** UnBuzz: SUBTEST _ 11C; *UnderRun test NOP; *Can't test IOAttn. on first inst. after wakeup SKIPON[IOAtten]; RETURN; INPUT[XWOTemp,XWStatus]; * Read Underrun status LU _ (XWOTemp) AND (EUnderRunMask); SKIPON[ALU#0], XWOTemp _ (XWOTemp) AND (EOStatusMask); *Skip if underrun set NoUnderRun: BREAKPOINT, GOTO[RSInOut]; *BREAK - UnderRun not set XWOTemp _ 300C; OUTPUT[XWOTemp,XWWriteState]; *Reset hardware XWOTemp _ AND[0377, LoopTestLoc]C; XWOTemp _ (XWOTemp) OR (AND[007400, LoopTestLoc]C); CALL[OutTaskRet], APC&APCTASK _ XWOTemp; *go back to LoopTest for loopback tests *** *** Go to TASK 0, LoopTest on page 11. *** ******************************************* TASK 2 ********************************************** * *** SUBTEST 17B *** OBegin: SUBTEST _ 17C, AT[OBeginLoc]; *Set up XWPtr and XWCount CALL[BSetup], T _ XWOCLOC; PFetch1[XWOBase,XWOTemp, XWDataLOC!]; CALL [FillLoop]; *Set return address for fill loop * Fill the Main Memory Output Buffer * Generate next random number from: XA _ 4005*XA + CA * Initial seed XA = 123, CA = 33031 FillLoop: T _ XA; T _ (LSH[XA, 2]) + (T); T _ (LSH[XA, 13]) + (T); T _ (CA) + (T); XA _ T; GOTO [OBufFull, R>=0], T _ XWOCount _ (XWOCount) + 1; SKIPON [R ODD], LU _ SizeData; *Check constant or random data RETURN, PStore1 [XWOPtr, XWOTemp]; * Bit 17 = 0 (constant data) RETURN, PStore1 [XWOPtr, XA]; * Bit 17 = 1 (random data) * Set up XWPtr and XWCount for single word transfers. * Compute how many singles before first quadword, and form loop counter in XWTemp1. * Address: x00 => no singles,loop count =-1 * Address: x01 => 3 singles, loop count = 2 * Address: x10 => 2 singles, loop count = 1 * Address: x11 => 1 singles, loop count = 0 *** SUBTEST 20B *** OBufFull:SUBTEST _ 20C; T _ XWOTemp2; *Put original XWCount in T XWOCount _ T; * and XWCount (this is unnecessary) T _ (XWOPtr) + (T) + 1; *Form start address in T XWOTemp1 _ (ZERO) - (T); *Complement, increment CALL [OAlign], XWOTemp1 _ (LDF[XWOTemp1, 16, 2]) - 1; OAlign: GOTO [OQuad, R<0], XWOTemp1 _ (XWOTemp1) - 1; GOTO [NoMore1, R>=0], T _ XWOCount _ (XWOCount) + 1; PFetch1 [XWOPtr, XWOTemp]; LU _ XWOTemp; *Abort * RETURN, OUTPUT [XWTemp, XOData]; *This line of code was commented out *in the original packets.mc file. * !!FUDGE!! for OUTPUT memory bug GOTO[OutRet], OUTPUT [XWOTemp, XOData]; OQuad: XWOCount _ (XWOCount) + (3C); *Now start quadword output CALL [OutLoop], XWOPtr _ (XWOPtr) - (6C); *Set return address for out loop OutLoop: *Output from the Main Memory Output Buffer to the Hardware Output Buffer GOTO [OBufEmpty, R>=0], T _ XWOCount _ (XWOCount) + (4C); GOTO [OAbort, IOATTEN]; RETURN, IOFetch4 [XWOPtr, XOData]; * We arrive here after an IOAttn is detected in the ouput loop. OAbort: INPUT [XWOTemp, XWStatus]; *Get bad status XWOTemp _ (XWOTemp) AND (EOStatusMask); RepeatMode _ RepeatMode, goto[.+3, R EVEN]; * Looping if RepeatMode is selected LoadPAGE[TestPage]; GOTOP[UpSize]; BadOutStatus: BREAKPOINT; *BREAK - Bad status in OB fill RepeatMode _ RepeatMode, goto[.+3, R EVEN]; * Looping if RepeatMode is selected LoadPAGE[TestPage]; GOTOP[UpSize]; GOTO[RSInOut]; * Normal exit from Output Loop is here * 7 - XWOCount = number of singles remaining * T is set up for next location. OBufEmpty: XWOCount _ (XWOCount) XOR (7C); CALL[OSingles], XWOCount _ (XWOCount) - 1; OSingles: GOTO [NoMore, R<0], XWOCount _ (XWOCount) - 1; PFetch1 [XWOPtr, XWOTemp]; T _ (ZERO) + (T) + 1, XWOTemp; *Abort GOTO[OutRet], OUTPUT [XWOTemp, XOData]; NoMore1:NOP; *We're done outputing words NoMore: XWOTemp _ 106C; * Set OutputEOP OUTPUT[XWOTemp,XWWriteState]; CALL[OutTaskRet]; *!!FUDGE!! for OUTPUT memory bug *** *** Output wakeup: Go to TASK 2, CheckOutStat on page 17. *** *** SUBTEST 21B *** CheckOutStat: *Should be woken up here after hardware's done sending packet or an error INPUT [XWOTemp, XWStatus]; *Read Status GOTO[OutAttn,IOATTEN]; GOTO[.+1]; RepeatMode _ RepeatMode, goto[.+3, R EVEN]; * Looping if RepeatMode is selected LoadPAGE[TestPage]; GOTOP[UpSize]; NoOutAttn: BREAKPOINT; *BREAK - Attn should be high RepeatMode _ RepeatMode, goto[.+3, R EVEN]; * Looping if RepeatMode is selected LoadPAGE[TestPage]; GOTOP[UpSize]; GOTO[RSInOut]; OutAttn:XWOTemp _ (XWOTemp) AND (EOStatusMask); *Select Output Status bits GOTO[NotBadOutEOP,ALU=0]; *Skip if bad status GOTO[.+1]; RepeatMode _ RepeatMode, goto[.+3, R EVEN]; * Looping if RepeatMode is selected LoadPAGE[TestPage]; GOTOP[UpSize]; BadOutStatusEOP: BREAKPOINT; *BREAK - Bad output status RepeatMode _ RepeatMode, goto[.+3, R EVEN]; * Looping if RepeatMode is selected LoadPAGE[TestPage]; GOTOP[UpSize]; GOTO[RSInOut]; NotBadOutEOP: XOFlag _ 1C; *Indicate output completed XWOTemp _ 101C; *Disable Ouput and Clear OutputEOP OUTPUT[XWOTemp, XWWriteState]; CALL[OutTaskRet]; *!!FUDGE!! for OUTPUT memory bug OutRanAgain: RepeatMode _ RepeatMode, goto[.+3, R EVEN]; * Looping if RepeatMode is selected LoadPAGE[TestPage]; GOTOP[UpSize]; OutRanAgain1: BREAKPOINT; *BREAK - Output Task ran *Hardware error. RepeatMode _ RepeatMode, goto[.+3, R EVEN]; * Looping if RepeatMode is selected LoadPAGE[TestPage]; GOTOP[UpSize]; GOTO[RSInOut]; ******************************************* TASK 3 ********************************************** * ON PAGE[InPage]; *** SUBTEST 13B *** IStart: SUBTEST _ 13C,AT[IStartLoc]; XWIBaseHi _ 0C; * Set up base pointers XWIBase _ 200C; CALL[OutTaskRet], XWIPtrHi _ 0C; *Return to task 0 *** SUBTEST 23B *** *Hardware Wakeup comes here (Check whether Overrun test) ICheckOVR: SUBTEST _ 23C; GOTO [ICheckPM, R EVEN], LU _ TestFlag; XWITemp _ 10000C; * Delay to insure overrun. CALL [IWait]; IWait: GOTO [IBegin, R<0], XWITemp _ (XWITemp) - 1; RETURN; ICheckPM: *Check whether Purge Mode Test. GOTO [IPurge, R<0], LU _ TestFlag; NOP; IBegin: T _ XWICLOC; *Here for placement CALL [BSetup]; *Set Up XWPtr T _ XWITemp2; T _ (XWIPtr) + (T) + 1; *Form start address in T IOS4Cnt _ 0c; *Initialize count of IOStore4's done by inner loop XWITemp1 _ (ZERO) - (T); *Complement, increment CALL [IAlign], XWITemp1 _ (LDF[XWITemp1, 16, 2]) - 1; IAlign: GOTO [IQuad, R<0], XWITemp1 _ (XWITemp1) - 1; GOTO [IBufFull1, R>=0], T _ XWICount _ (XWICount) + 1; INPUT [XWITemp, XIData]; LU _ XWITemp; *Abort RETURN, PStore1 [XWIPtr, XWITemp]; IQuad: XWICount _ (XWICount) + (3C); *Adjust XWPtr and XWCount for 4-word transfers. CALL [InLoop], XWIPtr _ (XWIPtr) - (6C); *Set return address for out loop InLoop: GOTO [IBufFull, R>=0], T _ XWICount _ (XWICount) + (4C); GOTO[IAttn, IOATTEN]; IOS4Cnt _ (IOS4Cnt) + 1; RETURN, IOStore4[XWIPtr, XIData]; *Read the Hardware Input Buffer IBufFull1:NOP; *We come here if there's no more room in *Main Memory In Buffer IBufFull:RepeatMode _ RepeatMode, goto[.+3, R EVEN]; * Looping if RepeatMode is selected LoadPAGE[TestPage]; GOTOP[UpSize]; InPacketSize: BREAKPOINT; *BREAK - In packet too big RepeatMode _ RepeatMode, goto[.+3, R EVEN]; * Looping if RepeatMode is selected LoadPAGE[TestPage]; GOTOP[UpSize]; GOTO[RSInOut]; IAttn:INPUT[XWITemp, XWStatus]; *Read status GOTO [NoOvTest, R EVEN], LU _ TestFlag; *Overrun test? XWITemp _ (XWITemp) AND (EOVRBadMask); *Mask Overrun and BadAlignment bits LU _ (XWITemp) XOR (EOVRMask); SKIPON[ALU=0]; *skip if Ov bit set, BadAlign not set GOTO[.+2]; GOTO[IPurge]; RepeatMode _ RepeatMode, goto[.+3, R EVEN]; * Looping if RepeatMode is selected LoadPAGE[TestPage]; GOTOP[UpSize]; NoOverRun: BREAKPOINT; *BREAK - Overrun bit not set RepeatMode _ RepeatMode, goto[.+3, R EVEN]; * Looping if RepeatMode is selected LoadPAGE[TestPage]; GOTOP[UpSize]; GOTO [IPurge]; NoOvTest: T _ LDF[XWITemp, 10,2]; *Isolate Excess Count XWITemp _ (XWITemp) AND (EStatusMask); *Mask status bits LU _ (XWITemp) AND (EIStatusMask); *Mask input status bits GOTO[GoodInStatus, ALU=0]; *Skip if Good packet GOTO[.+1]; RepeatMode _ RepeatMode, goto[.+3, R EVEN]; * Looping if RepeatMode is selected LoadPAGE[TestPage]; GOTOP[UpSize]; BadInStatus: BREAKPOINT; *BREAK - Bad input status RepeatMode _ RepeatMode, goto[.+3, R EVEN]; * Looping if RepeatMode is selected LoadPAGE[TestPage]; GOTOP[UpSize]; GOTO [RSInOut]; GoodInStatus:XWICount _ (XWICount) - (T); *Subtract excess count T _ (XWITemp2) + (7C); *Get saved XWCount and correct XWICount _ (XWICount) - (T) - 1; *Don't count CRC PStore1[XWIBase, XWICount, XWELOC!], call[OutTaskRet]; NOP; *** SUBTEST 24B *** *Check bit 16 in LoopMode to determine whether in local loopback mode or not IPurge: SUBTEST _ 24C; LU _ LDF[LoopMode, 16, 1]; SKIPON[ALU#0], XWITemp _ 260C; *Enable Input, purge mode XWITemp _ (XWITemp) OR (10C); *Bit 16 = 0 => OR in Loopback bit OUTPUT[XWITemp,XWWriteState]; LU _ TestFlag; *TestFlag=0 => go to Verify SKIPON [ALU=0], XWITemp _ AND[0377, VerifyLoc]C;*Notify back to Task 0 XWITemp _ AND[0377, POBuzzLoc]C; *Go to POBuzz loop *** *** In PurgeMode or OverRunMode should go to TASK 0, POBuzz on page 14. *** If problem, go to TASK 3, InRanAgain on page 19. *** XWITemp _ (XWITemp) OR (AND[007400, VerifyLoc]C);*Go to Verify CALL[OutTaskRet], APC&APCTASK _ XWITemp; *This task is necessary *** *** TASK 0. Normal LoopBack Mode go to Verify on page 14. *** TASK 3. If problem, go to Input task, InRanAgain on page 19. *** InRanAgain: RepeatMode _ RepeatMode, goto[.+3, R EVEN]; * Looping if RepeatMode is selected LoadPAGE[TestPage]; GOTOP[UpSize]; InRanAgain1: BREAKPOINT; *BREAK - input Task ran RepeatMode _ RepeatMode, goto[.+3, R EVEN]; * Looping if RepeatMode is selected LoadPAGE[TestPage]; GOTOP[UpSize]; GOTO[RSInOut]; * * * * * * * * * * * * * * * SUBROUTINE: BSetup * * * * * * * * * * * * * * * * * * * *** Set up XWPtr and XWCount for single-word transfers. *** On entry T has pointer to XWICLOC or XWOCLOC. *** Subroutine returns with: *** XWPtr = Buffer Pointer + Count - 1 *** T = XWCount = XWTemp2 = - Count *** The appropriate input or output pointer and count locations are used. *** Registers used would be depend on Current TASK, when doing PFetch or PStore. *** This is a bug in the programs, look at the D0 Microprogrammers guide for detail. BSetup: PFetch1 [XWBase, XWCount]; *Fetch count NOP; T _ (ZERO) + (T) + 1; *Point to XWxPLOC PFetch1 [XWBase, XWPtr]; *Fetch pointer T _ (XWCount) - 1; XWPtr _ (XWPtr) + (T); *Ptr _ Ptr + count - 1 XWTemp2 _ (ZERO) - (T) - 1; *Count _ - Count RETURN, XWCount _ T _ (ZERO) - (T) - 1; * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *** Used for tasking (input and output task) OutRet: NOP; OutTaskRet: RETURN; **************** Fault handler: To allow reading of the memory error pipe **************** RV[RXPPB,73]; *Page, parity, bootreason register in kernel RV[RDATA,67]; *Register holding data to be sent to Midas *(we use it as a temp) RV[FFAULT,66]; *Zero means send all faults to Midas, negative means *return on memory errors RV[RXSTK,72]; *Stackpointer save in kernel ONPAGE[0]; *We get to 120 if PARITY#0 and FFAULT<0. We do a more thorough check, looking for a *memory error. If there is one, we read the pipe entry. If not, we send control to *Midas at 7512. Midas will sent #101 to the Kernel. FAULTxx: lu _ LDF[RXPPB,7,1], AT[120]; goto[MemErr, alu#0]; *Error was not a memory error MidasFault: RData _ 177400c; *Notify kernel at 7512b RData _ (RData) OR (112C); APC&APCTASK _ RData; RETURN; MemErr: RData _ 100c; Stkp _ RData; ReadPipe[STACK]; *Read A pipe into RM 100-RM 105 RData _ 110c; Stkp _ RData; ReadPipe[STACK], ResetMemErrs; *Read B pipe into RM 110-115 goto[MidasFault]; End; *To end the MAIN program * * * * * * * * * * * * * * * End Of EDPackets.mc * * * * * * * * * * * * (1270)\f7 1f0 4177ubi23U10u9UBI4243b12B4b11B7b13B424b10B46b11B53b10B666b10B78i8I85i6I1115i4I156b13B7b41B181b11B726b6B25b6B2b7B5b6B18b7B5b6B9632b6B4697b6B71b6B1504b6B2009b6B732b6B573b6B266b6B584b6B1119b6B2270b6B295b6B75b6B170b6B988b6B75b6B3148b6B1582b6B3815b6B44b6B171b7B53b7B