ER[DGISDM];

%DIAGNOSTIC FOR INSTRUCTION, SCRATCH, DISPATCH, AND MAP MEMORIES

THIS FILE IS INCLUDED BY "DGIML" AND "DGIMH" WHICH TEST, RESPECTIVELY, HIGH
AND LOW REGIONS OF IM.  FOR SCOPING, VARIABLES "RLOOK" (READING IM)
AND "WLOOK" (WRITING IM) CAN BE LOADED WITH AN ADDRESS AND SIGNOVA
WILL OCCUR JUST BEFORE THE READ/WRITE OF THE DESIGNATED ADDRESS.
DATA COMPARE CAN BE MASKED BY "LMASK" AND "RMASK".
RANGE OF IM ADDRESSES TESTED IS FROM "LADDR" TO "HADDR" INCLUSIVE.  THE DATA
PATTERNS USED BEGIN AT "LADDR" WITH EACH OF THE 72 PATTERNS CONSISTING OF A
SINGLE 0 IN A FIELD OF 1'S AND EACH OF THE 72 PATTERNS CONSISTING OF A SINGLE 1
IN A FIELD OF 0'S.  SUBSEQUENT WORDS RECEIVE THE PREVIOUS WORD'S DATA LCY 1.

RANDOM NO. PATTERNS ARE USED TO TEST DM, SM, MAP, AND IM AFTER THE 144
FIXED PATTERNS FOR IM ARE EXHAUSTED.

TO TEST ONLY IM, START AT "TIM".

TO TEST ONLY MP, START AT "TMP".

TO TEST ONLY SM, START AT "TSM".

ON MAXC2, P← PROVOKES SLOW CHIP FAILURESS BECAUSE P HAS A VERY EARLY WRITE
ENABLE.  Q← IS NOT AS GOOD ON EITHER MAXC1 OR MAXC2 BECAUSE IT HAS A LATE
WRITE ENABLE.

ON MAXC2 PARITY CHECKING CAN BE TURNED ON BY SETTING "PARITY" TO THE PROPER
VALUE--SEE THE COMMENT AT THE BOTTOM OF THIS PAGE.
%

SM[SLC,20]; RM[RLC,0]; LM[LLC,10];

RV[X0,7654321];
RV[X1,76543210];
RV[X2,765432100];
RV[X3,7654321000];
RV[X4,76543210000];
RV[X5,765432100000];
RV[X6,654321000007];
RV[X7,543210000076];

LVN[RAN]; LVN[RRAN]; LVN[XRAN]; LVN[COUNT];

LVN[LTEMP]; RVN[RTEMP]; RVN[ICOUNT];

LVN[LDATA]; LVN[LDATA1]; RV[LMASK,777777 777777]; LVN[LBASE];
RVN[RDATA]; RVN[RDATA1]; LV[RMASK,777777 777777]; RVN[RBASE];
RV[WLOOK,0]; RV[RLOOK,0];
SVN[ADDR]; RV[AINC,1];

RV[SMMASK,777777 777777];

RV[MPMASK,777777]; SVN[FSET];

LV[PARITY,0];	*400 000000	ENABLES IM PE HALT
		*200 000000	ENABLES SM/DM/DM1/DM2 PE HALT
		*100 000000	ENABLES MP PE HALT


MCYCLE:	BRKP[1], COUNT←P+1, GOTO[LOOP];

START:	ARM←Y←NULL, INHINT;
	IRET, INHINT, COUNT←A0, GOTO[INITL];

PQCOMP:	P#Q;
AZT:	RETURN[ALU=0];
	BRKP[1];			*IN CASE SINGLE STEPPING
	BRKP[1], RETURN;

RETN:	RETURN;

*INITIALIZE SM, MAP, DM, DM1, AND DM2 LOCATIONS BEFORE ARMING PARITY
*(ONLY SM INIT NECESSARY NOW--MP INIT NECESSARY IF SWITCH TO NEW BIPOLAR
*BOARD ON MP.)
INITL:
*~ MAXC2 ONLY
	SY←MAP←NULL;
	D←NULL;
	D1←NULL;
	D2←NULL, INCY, GOTO[.-3,Y>=0];
	SY←MAP←NULL;
	D←NULL;
	D1←NULL;
	D2←NULL, INCY, Q←PARITY, GOTO[.-3,Y<0];
	ARM←Q, DGOTO[7], Q←X7;		*INITIALIZE RANDOM NO. GEN.
*~
*! MAXC1 ONLY
	DGOTO[7], Q←X7;
*!
	X←NPC, RAN←Q, GOTO[.+1];
	CALL[IMCYCT];		*CYCLED 1 AND CYCLED 0 TEST ONCE ONLY

LOOP:	CALL[TSTIM];
	CALL[TSTMP];
	CALL[TSTSM];
	P←COUNT, GOTO[MCYCLE];

TSTIM:	CALL[IMRANT];
	RETURN;

TSTMP:	CALL[MPRT1];		*RANDOM DATA, SEQUENTIAL ADDRESSES
	CALL[MPRT2];		*RANDOM DATA, SEQUENTIAL ADDRESSES
	P←A1, SAMASK[12];
	ICOUNT←P-1, CALL[MPRT3];	*RANDOM DATA, RANDOM ADDRESS IN MP
TSTMPL:	P←ICOUNT;
	ICOUNT←P-1;
	RETURN[ALU<0];
	CALL[MPRT3L];		*Q/ CORRECT VALUE, P/ MP[Y]
	GOTO[TSTMPL];		*MPRT3S;G TO LOOP ON FAILURE


TSTSM:	CALL[SMDMT1];		*RANDOM DATA, SEQUENTIAL ADDRESSES

	P←A1, SAMASK[12], GOTO[SDR1];
SDRLP:	CALL[SMT2];		*RANDOM DATA, RANDOM ADDRESS IN SM
	CALL[DMT2];		*Q/ CORRECT VALUE, P,MDR/ DM[Y]
*~ MAXC2 ONLY
	CALL[DM1T2];		*Q/ CORRECT VALUE, P, MDR/ DM1[Y]
	CALL[DM2T2];		*Q/ CORRECT VALUE, P, MDR/ DM2[Y]
	CALL[SDM1B];
*~
	P←ICOUNT;
SDR1:	ICOUNT←P-1, DGOTO[SDRLP];
	RETURN[ALU<0];

*START HERE TO TEST ONLY IM
TIM:	COUNT←A0;
TIMLP:	CALL[TSTIM];
	P←COUNT;
	COUNT←P+1, GOTO[TIMLP];

*START HERE TO TEST ONLY THE MAP
TMAP:	COUNT←A0;
TMAPLP:	CALL[TSTMP];
	P←COUNT;
	COUNT←P+1, GOTO[TMAPLP];

*START HERE TO TEST ONLY SM, DM, DM1, AND DM2
TSM:	COUNT←A0;
TSMLP:	CALL[TSTSM];
	P←COUNT;
	COUNT←P+1, GOTO[TSMLP];

%"NIRGEN" IS THE SAME AS "RGEN" BELOW EXCEPT THAT IT LOOPS
TO GENERATE THE NEXT RANDOM NUMBER WHENEVER THE BUS SOURCE OR BUS
DESTINATION FIELDS SELECTS IM.  THIS BYPASSES A HARDWARE BUG.
%
NIRG1:	Q←RAN, RETURN[ALU#0];
NIRGEN:
*! MAXC1 ONLY BUG
	P←RAN, Q←RX, GOTO[NIRG2,X>=0];
	Q←X7, DGOTO[6];
	X←NPC, RAN←X7←Q←P+Q, GOTO[.+1];
NIRG3:	P←1634 000000L;
	Q←P#Q, P←7600 000000L;
	P AND Q, P←174 000000L, DGOTO[NIRG1]; *BS=IM=7?
	P AND Q, GOTO[NIRGEN,ALU=0]; *BD=IM=7?

NIRG2:	RX←RAN←Q←P+Q, DECX, GOTO[NIRG3];
*!

*RETURN RANDOM NO. IN Q (USES X WHICH MUST NOT BE CLOBBERED), CLOBBERS P
RGEN:	P←RAN, Q←RX, GOTO[RGEN1,X>=0];
	DGOTO[6], Q←X7;
	X←NPC, RAN←X7←Q←P+Q, RETURN;

RGEN1:	RX←RAN←Q←P+Q, DECX, RETURN;

*SAVE RANDOM NO. GEN. STATE IN LM FOR RESTORATION LATER.  RETURN RANDOM NO. IN Q.
RMARK:	P←X, DGOTO[7], Q←RAN;
	X←NPC, GOTO[.+1], RRAN←Q;
	Q←RX, GOTO[.+2,X<0], XRAN←P;
	LX←Q, DECX, GOTO[.-1];
PXRET:	X←P, Q←RAN, GOTO[NIRGEN];

*RESTORE RANDOM NO. GEN FROM LM
RREST:	P←RRAN, DGOTO[7];
	X←NPC, RAN←P, GOTO[.+1];
	Q←LX, GOTO[PXRET,X<0];
	RX←Q, P←XRAN, DECX, GOTO[.-1];

MPCOMP:	LTEMP←Q←P, P←Q, SAMASK[22];		*P←CORRECT VALUE, Q←VALUE READ
	RTEMP←P;
	P←P#Q, Q←MPMASK;
	P AND Q, P←LTEMP, Q←RTEMP, GOTO[AZT];

MPSMON:	FSET←Q;
	CLEARF[FSET], GOTO[RGEN];	*CLEAR CUM TO MAKE MONITOR MODE

%TEST MP USING RANDOM NUMBERS, SEQUENTIAL ADDRESSES.  IN THIS FIRST TEST, THE
ADDRESSES HAVE MORE THAN ONE CYCLE SETUP AND CHANGE AT THE END OF THE CYCLE,
SO HARD STORAGE FAILURES, WRITE FAILURES PROVOKED BY ADDRESS GOING AWAY TOO
SOON, AND ADDRESS LATCHING PROBLEMS ARE PROVOKED.
%
MPRT1:	Q←A1, CALL[MPSMON];		*START WITH MONITOR MAP
	Y←NULL, CALL[RMARK];		*SAVE STATE OF RANDOM NO. GEN.
	MAP←Q, INCY, CALL[RGEN];
	GOTO[.-1,Y>=0];
	MAP←Q, INCY, CALL[RGEN];
	GOTO[.-1,Y<0];
	Y←NULL, SETF[FSET], CALL[RETN];	*NOW USER MAP (DELAY AFTER SETF[CUM])
	MAP←Q, INCY, CALL[RGEN];
	GOTO[.-1,Y>=0];
	MAP←Q, INCY, CALL[RGEN];
	GOTO[.-1,Y<0];
*NOW READ AND COMPARE
MPRT1C:	Y←NULL, CLEARF[FSET], CALL[RREST];
	P←MDR←MAP, CALL[MPCOMP];		*Q/ CORRECT VALUE, P/ MP[Y]
	INCY, CALL[RGEN];
	GOTO[.-2,Y>=0];
	P←MDR←MAP, CALL[MPCOMP];		*Q/ CORRECT VALUE, P/ MP[Y]
	INCY, CALL[RGEN];
	GOTO[.-2,Y<0];
	Y←NULL, SETF[FSET], CALL[RETN];
	P←MDR←MAP, CALL[MPCOMP];		*Q/ CORRECT VALUE, P/ MP[Y]
	INCY, CALL[RGEN];
	GOTO[.-2,Y>=0];
	P←MDR←MAP, CALL[MPCOMP];		*Q/ CORRECT VALUE, P/ MP[Y]
	INCY, CALL[RGEN];
	GOTO[.-2,Y<0];
	RETURN;


%TEST MP USING RANDOM NUMBERS, SEQUENTIAL ADDRESSES.  ADDRESSES CHANGE IN THE
CYCLE BEFORE READS OR THE CYCLE AFTER WRITES, SO HARD STORAGE FAILURES,
ADDRESS LATCHING PROBLEMS, AND SLOW CHIP FAILURES ARE PROVOKED.
%
MPRT2:	Q←A1, CALL[MPSMON];		*START WITH MONITOR MAP
	Y←NULL, CALL[RMARK];		*SAVE STATE OF RANDOM NO. GEN.
	MAP←Q, INCY, CALL[RGEN];
	GOTO[.-1,Y>=0];
	MAP←Q, INCY, CALL[RGEN];
	GOTO[.-1,Y<0];
	SETF[FSET], CALL[RETN];		*NOW USER MAP (DELAY AFTER SETF[CUM])
	MAP←Q, INCY, CALL[RGEN];
	GOTO[.-1,Y>=0];
	MAP←Q, INCY, CALL[RGEN];
	GOTO[.-1,Y<0];
*NOW READ AND COMPARE
MPRT2C:	Y←NULL, CLEARF[FSET], CALL[RREST];
	P←MDR←MAP, CALL[MPCOMP];		*Q/ CORRECT VALUE, P/ MP[Y]
	CALL[RGEN];
	INCY, GOTO[.-2,Y>=0];
	P←MDR←MAP, CALL[MPCOMP,Y<0];		*Q/ CORRECT VALUE, P/ MP[Y]
	CALL[RGEN];
	INCY, GOTO[.-2,Y<0];
	Y←NULL, SETF[FSET], GOTO[.+3];
	P←MDR←MAP, CALL[MPCOMP];		*Q/ CORRECT VALUE, P/ MP[Y]
	CALL[RGEN];
	INCY, GOTO[.-2,Y>=0];
	P←MDR←MAP, CALL[MPCOMP,Y<0];		*Q/ CORRECT VALUE, P/ MP[Y]
	CALL[RGEN];
	INCY, GOTO[.-2,Y<0];
	RETURN;

%TEST MP USING RANDOM ADDRESSES AND RANDOM DATA.  TWO RANDOM ADDRESSES ARE
GENERATED AND RANDOM DATA.  Y CHANGES FROM THE FIRST RANDOM ADDRESS TO THE
SECOND IN THE CYCLE BEFORE THE READ/WRITE.
%
MPRT3:	Q←A1, CALL[MPSMON];
	FSET←Q;				*RANDOM CUM
MPRT3L:	SETF[FSET], CALL[RGEN];
	RDATA←Q, CALL[RGEN];		*RDATA/ RANDOM DATA
	ADDR←FSPLIT←Q;			*ADDR[0,8]/ PREVIOUS ADDRESS
	Y←ADDR, Q←RDATA;		*ADDR[27,35]/ ADDRESS WRITTEN-READ
	MAP←Q;
	FSPLIT←ADDR;
	Y←ADDR;
	Q←RDATA, P←MDR←MAP, GOTO[MPCOMP]; *COMPARE AND RETURN


*SCOPE LOOP TO USE AFTER FAILURES OF MPRT3L
MPRT3S:	FSPLIT←ADDR, Q←RDATA;
	Y←ADDR, Q←RDATA;
	MAP←Q;
	FSPLIT←ADDR;
	Y←ADDR, DGOTO[MPRT3S];
	Q←RDATA, P←MDR←MAP, CALL[MPCOMP];

SMCOMP:	RTEMP←P;
	LTEMP←Q;
	P←P#Q, Q←SMMASK;
	P AND Q, P←RTEMP, Q←LTEMP, GOTO[AZT];


%TEST SM/DM USING RANDOM DATA, SEQUENTIAL ADDRESSES.  THE ADDRESS CHANGES IN
THE CYCLE BEFORE EACH READ OR AFTER EACH WRITE TO CATCH SLOW TIMING PATHS.
**A SLOWER DEVELOPMENT OF THE ADDRESS WOULD BE TO LOAD Y FROM A SLOW SOURCE
**IN THE CYCLE BEFORE THE READ.
%
SMDMT1:	CALL[RGEN];
	Y←NULL, CALL[RMARK];
SMDML1:	D←Q, INCY, Q←NOT Q;
*~ MAXC2 ONLY
	D1←Q, INCY, Q←NOT Q;
	D2←Q, DECY, Q←NOT Q;
*~
	SY←Q, DECY, CALL[RGEN];
	INCY;
	GOTO[SMDML1,Y>=0];
SMDML2:	D←Q, Q←NOT Q, INCY;
*~ MAXC2 ONLY
	D1←Q, Q←NOT Q, INCY;
	D2←Q, Q←NOT Q, DECY;
*~
	SY←Q, DECY, CALL[RGEN];
	INCY;
	GOTO[SMDML2,Y<0];

	Y←A1, CALL[RREST];	*RESTORE ORIG. RANDOM NO. STATE
SMDMC1:	INCY;
	P←MDR←D, CALL[SMCOMP];	*Q/ CORRECT VALUE, P/ DM[Y]
	Q←NOT Q, INCY;
*~ MAXC2 ONLY
	P←MDR←D1, CALL[SMCOMP];	*Q/ CORRECT VALUE, P/ DM1[Y]
	Q←NOT Q, INCY;
	P←MDR←D2, CALL[SMCOMP];	*Q/ CORRECT VALUE, P/ DM2[Y]
	Q←NOT Q, DECY;
*~
	P←MDR←SY, CALL[SMCOMP];	*Q/ CORRECT VALUE, P/ SM[Y]
	CALL[RGEN];
	DECY, GOTO[SMDMC1,Y>=0];
SMDMC2:	INCY;
	P←MDR←D, CALL[SMCOMP];	*Q/ CORRECT VALUE, P/ DM[Y]
	Q←NOT Q, INCY;
*~ MAXC2 ONLY
	P←MDR←D1, CALL[SMCOMP];	*Q/ CORRECT VALUE, P/ DM1[Y]
	Q←NOT Q, INCY;
	P←MDR←D2, CALL[SMCOMP];	*Q/ CORRECT VALUE, P/ DM2[Y]
	Q←NOT Q, DECY;
*~
	P←MDR←SY, CALL[SMCOMP];
	CALL[RGEN];
	DECY, GOTO[SMDMC2,Y<0];
	RETURN;

%TEST SM USING RANDOM ADDRESSES AND RANDOM DATA.  TWO RANDOM ADDRESSES ARE
GENERATED AND RANDOM DATA.  Y CHANGES FROM THE FIRST RANDOM ADDRESS TO THE
SECOND IN THE CYCLE BEFORE THE READ/WRITE.
%
SMT2:	CALL[RGEN];
	RDATA←Q, CALL[RGEN];		*RDATA/ RANDOM DATA
	LDATA←FSPLIT←P←Q;		*LDATA[0,8]/ PREVIOUS ADDRESS
	Y←P, Q←RDATA;			*LDATA[27,35]/ ADDRESS WRITTEN-READ
	SY←Q, P←LDATA, INCY;
	FSPLIT←P;
	Y←P;
	Q←RDATA, P←MDR←SY, GOTO[SMCOMP];	*COMPARE AND RETURN

*SCOPE LOOP TO USE AFTER FAILURES OF SMT2
SMTS:	P←LDATA;
	FSPLIT←P;
	Y←P, Q←RDATA;
	SY←Q;
	P←LDATA;
	FSPLIT←P;
	Y←P, DGOTO[SMTS];
	Q←RDATA, P←MDR←SY, CALL[SMCOMP];

*~ MAXC2 ONLY
%TEST SM, DM, DM1, DM2 TRYING TO PROVOKE FAILURES CAUSED BY FREQUENT SWITCHING
OF THE CHIP SELECTS.
%
SDM1B:	CALL[RGEN];
	RDATA←Q, CALL[RGEN];
	LDATA←Q, CALL[RGEN];
	RDATA1←Q, CALL[RGEN];
	LDATA1←Y←Q;
	FSPLIT←Q;		*Y CHANGING BEFORE WRITE
	SY←Y←Q, Q←RDATA1;	*AND AFTER WRITE OF SM
	D1←Q, Q←LDATA, NEGY;	*CHIP SELECT CHANGES HERE
	D←Q, Q←RDATA, NEGY;	*AND HERE
	D2←Q, Q←LDATA1, NEGY;	*AND HERE
	FSPLIT←Q;
	P←Y←SY, CALL[SMCOMP];			*P/ SM[LDATA1[0,8]], Q/ SHOULD BE
	Q←RDATA1, P←D1, NEGY, CALL[SMCOMP];	*P/ DM1[-Y], Q/ SHOULD BE
	Q←LDATA, P←D, NEGY, CALL[SMCOMP];	*P/ DM[-Y], Q/ SHOULD BE
	Q←RDATA, P←D2, NEGY, CALL[SMCOMP];	*P/ DM2[-Y], Q/ SHOULD BE
	RETURN;
*~

%TEST DM USING RANDOM ADDRESSES AND RANDOM DATA.  TWO RANDOM ADDRESSES ARE
GENERATED AND RANDOM DATA.  Y CHANGES FROM THE FIRST RANDOM ADDRESS TO THE
SECOND IN THE CYCLE BEFORE THE READ/WRITE.
%
DMT2:	CALL[RGEN];
	RDATA←Q, CALL[RGEN];		*RDATA/ RANDOM DATA
	LDATA←FSPLIT←P←Q;		*LDATA[0,8]/ PREVIOUS ADDRESS
	Y←P, Q←RDATA;			*LDATA[27,35]/ ADDRESS WRITTEN-READ
	D←Q, P←LDATA, INCY;
	FSPLIT←P;
	Y←P;
	Q←RDATA, P←MDR←D, GOTO[SMCOMP];	*COMPARE AND RETURN

*SCOPE LOOP TO USE AFTER FAILURES OF DMT2
DMTS:	P←LDATA;
	FSPLIT←P;
	Y←P, Q←RDATA;
	D←Q;
	P←LDATA;
	FSPLIT←P;
	Y←P, DGOTO[DMTS];
	Q←RDATA, P←MDR←D, CALL[SMCOMP];


%TEST DM1 USING RANDOM ADDRESSES AND RANDOM DATA.  TWO RANDOM ADDRESSES ARE
GENERATED AND RANDOM DATA.  Y CHANGES FROM THE FIRST RANDOM ADDRESS TO THE
SECOND IN THE CYCLE BEFORE THE READ/WRITE.
%
*~ MAXC2 ONLY
DM1T2:	CALL[RGEN];
	RDATA←Q, CALL[RGEN];		*RDATA/ RANDOM DATA
	LDATA←FSPLIT←P←Q;		*LDATA[0,8]/ PREVIOUS ADDRESS
	Y←P, Q←RDATA;			*LDATA[27,35]/ ADDRESS WRITTEN-READ
	D1←Q, P←LDATA, INCY;
	FSPLIT←P;
	Y←P;
	Q←RDATA, P←MDR←D1, GOTO[SMCOMP];	*COMPARE AND RETURN

*SCOPE LOOP TO USE AFTER FAILURES OF DM1T2
DM1TS:	P←LDATA;
	FSPLIT←P;
	Y←P, Q←RDATA;
	D1←Q;
	P←LDATA;
	FSPLIT←P;
	Y←P, DGOTO[DM1TS];
	Q←RDATA, P←MDR←D1, CALL[SMCOMP];

%TEST DM2 USING RANDOM ADDRESSES AND RANDOM DATA.  TWO RANDOM ADDRESSES ARE
GENERATED AND RANDOM DATA.  Y CHANGES FROM THE FIRST RANDOM ADDRESS TO THE
SECOND IN THE CYCLE BEFORE THE READ/WRITE.
%
DM2T2:	CALL[RGEN];
	RDATA←Q, CALL[RGEN];		*RDATA/ RANDOM DATA
	LDATA←FSPLIT←P←Q;		*LDATA[0,8]/ PREVIOUS ADDRESS
	Y←P, Q←RDATA;			*LDATA[27,35]/ ADDRESS WRITTEN-READ
	D2←Q, P←LDATA, INCY;
	FSPLIT←P;
	Y←P;
	Q←RDATA, P←MDR←D2, GOTO[SMCOMP];	*COMPARE AND RETURN

*SCOPE LOOP TO USE AFTER FAILURES OF DM2T2
DM2TS:	P←LDATA;
	FSPLIT←P;
	Y←P, Q←RDATA;
	D2←Q;
	P←LDATA;
	FSPLIT←P;
	Y←P, DGOTO[DM2TS];
	Q←RDATA, P←MDR←D2, CALL[SMCOMP];
*~

*WRITE IM[ADDR] WITH RDATA AND LDATA.  ADDR#WLOOK THRU ALU AT CALL.
*! MAXC1 ONLY
WIM:	GOTO[.+2,ALU#0];
	SIGNOVA;
	P←NPC←ADDR, Q←RDATA;
	I←Q,DGOTO[.+1];  *2 CYCLES AFTER SIGNOVA
	INHINT, GOTO[.+1];
	P←NPC←ADDR, GOTO[.+1], Q←LDATA;
	I←Q, DGOTO[.+1], Q←AINC, INHINT;  *5 CYCLES AFTER SIGNOVA
	INHINT, GOTO[.+1];
	P←HADDR, Q←P+Q, RETURN;
*!
*~ MAXC2 ONLY
WIM:	Q←RDATA, GOTO[.+2,ALU=0];
	B←Q, GOTO[.+2];
	B←Q, SIGNOVA;
	NPC←ADDR, FRZBALUBC;	*FREEZE EREG
	P←I←EREG, DGOTO[.+1]; *2 CYCLES AFTER SIGNOVA IM[36,71]
	P#Q, Q←LDATA;
	B←Q, GOTO[.+2,ALU=0];
	BRKP[1];		*EREG WRONG AFTER IM WRITE
	NPC←ADDR, FRZBALUBC;
	P←I←EREG, INHINT, DGOTO[.+1];
	P#Q, P←ADDR, Q←AINC;	*6 CYCLES AFTER SIGNOVA IM[0,35]
	P←HADDR, Q←P+Q, RETURN[ALU=0];
	BRKP[1];		*EREG WRONG AFTER IM WRITE
*~

*READ IM[ADDR], MASK IT WITH LMASK AND RMASK, AND COMPARE TO LDATA AND RDATA.
*ADDR#RLOOK THRU ALU AT CALL.
RIM:	GOTO[.+2,ALU#0];
	SIGNOVA;
	NPC←ADDR;
*! MAXC1 ONLY
	P←I, DGOTO[.+1], Q←RMASK;  *2 CYCLES AFTER SIGNOVA
	INHINT, GOTO[.+1];
*!
*~ MAXC2 ONLY
	I, Q←RMASK, DGOTO[.+1];
	MDR←P←EREG, GOTO[.+1];
*~
	LTEMP←P AND Q, GOTO[.+1], P←RDATA;
	P←P AND Q, Q←LTEMP, CALL[PQCOMP];
*RIGHT HALF OF IM ENTRY [ADDR] MASKED BY [RMASK] SHOULD HAVE BEEN P 
*BUT WAS Q
	NPC←ADDR;
*! MAXC1 ONLY
	P←I, INHINT, DGOTO[.+1], Q←LMASK;  *9 CYCLES AFTER SIGNOVA
	INHINT, GOTO[.+1];
*!
*~ MAXC2 ONLY
	I, INHINT, Q←LMASK, DGOTO[.+1];
	MDR←P←EREG, GOTO[.+1];
*~
	RTEMP←P AND Q, GOTO[.+1], P←LDATA;
	P←P AND Q, Q←RTEMP, CALL[PQCOMP];
*LEFT HALF OF IM ENTRY [ADDR] MASKED BY [LMASK] SHOULD HAVE BEEN P
*BUT WAS Q
	P←ADDR, Q←AINC;
	Q←P+Q, P←HADDR, RETURN;

*LOOP TO REPEAT "WIM" AFTER PARITY ERRORS
*~ MAXC2 ONLY
WIMREP:	Q←RDATA;
	B←Q, SIGNOVA;
	NPC←ADDR, FRZBALUBC;	*FREEZE EREG
	P←I←EREG, DGOTO[.+1];
	P#Q, Q←LDATA;
	B←Q, GOTO[.+2,ALU=0];
	BRKP[1];		*EREG WRONG
	NPC←ADDR, FRZBALUBC;
	P←I←EREG, INHINT, DGOTO[.+1];
	P#Q, P←ARM, Q←17700 000000L;
	P AND Q, GOTO[.+2,ALU=0];
	BRKP[1];		*EREG WRONG
	Q←PARITY, GOTO[WIMREP,ALU=0];
	BRKP[1], ARM←Q, GOTO[WIMREP];
*~

DCYCLE:	PQ LCY [1],FRZBALUBC, Q←LDATA;
	LDATA←P, P←RDATA, FRZBALUBC;
	PQ LCY [1], FRZBALUBC, RETURN, Q←ADDR;

*STARTING WITH THE 72 BIT NUMBER <LBASE,RBASE>, WRITE FROM ADDRESS
*LADDR TO HADDR SEQUENTIALLY LEFT CYCLED PATTERNS
RWT1:	P←LBASE,Q←RBASE;
	RDATA←Q, Q←LADDR;
	LDATA←P, P←WLOOK;
RWT2:	P#Q, ADDR←Q, CALL[WIM];
	P-Q, ADDR←Q, P←LDATA, Q←RDATA, CALL[DCYCLE];
	RDATA←P, FRZBALUBC;
	P←WLOOK, GOTO[RWT2,ALU>=0];
*NOW READ AND COMPARE
	P←LBASE, Q←RBASE;
	RDATA←Q, Q←LADDR;
	LDATA←P, P←RLOOK;
RWT3:	P#Q, ADDR←Q, CALL[RIM];
	P-Q, ADDR←Q, P←LDATA, Q←RDATA, CALL[DCYCLE];
	RDATA←P, FRZBALUBC, DGOTO[RWT3];
	RETURN[ALU<0], P←RLOOK;


*TEST IM USING 72 PATTERNS OF SINGLE 0 IN FIELD OF 1'S AND 72 PATTERNS
*OF SINGLE 1 IN FIELD OF 0'S
IMCYCT:	LBASE←P←A0;
	RBASE←P+1,CALL[RWT1];
IMRWT1:	P←LBASE, Q←RBASE;
	PQ LCY [1],Q←LBASE;
	LBASE←P,P←RBASE;
	PQ LCY [1];
	RBASE←P;
	DGOTO[IMRWT1,ALU>=0];
	CALL[RWT1];
*RETURN HERE WHEN 72 PATTERNS OF A SINGLE 1 IN A FIELD OF 0'S ARE EXHAUSTED
	LBASE←P←A1;
	RBASE←2P,CALL[RWT1];
IMRWT2:	P←LBASE,Q←RBASE;
	PQ LCY [1],Q←LBASE;
	LBASE←P,P←RBASE;
	PQ LCY [1];
	RBASE←P;
	DGOTO[IMRWT2,ALU<0];
	CALL[RWT1];
	RETURN;


*NOW TEST IM USING RANDOM NO.'S
IMRANT:	Q←LADDR, DGOTO[WRANIM];
	ADDR←Q, CALL[RMARK];

WRANE:	ADDR←Q, CALL[NIRGEN];
WRANIM:	RDATA←Q, CALL[RGEN];
	LDATA←Q, Q←ADDR, P←HADDR, DGOTO[WRANE];
	P-Q, P←WLOOK, CALL[.+1];
	P#Q, GOTO[WIM,ALU>=0];
*NOW READ AND COMPARE
	Q←LADDR, POP, DGOTO[RRANIM];
	ADDR←Q, CALL[RREST];

RRANE:	ADDR←Q, CALL[NIRGEN];
RRANIM:	RDATA←Q, CALL[RGEN];
	LDATA←Q, Q←ADDR, P←HADDR, DGOTO[RRANE];
	P-Q, P←RLOOK, CALL[.+1];
	P#Q, GOTO[RIM,ALU>=0];
	POP;
	RETURN;