%

********************************************************************************************
*** 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]<EDMod>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 * * * * * * * * * * * *