ER[DGMR];	*RANDOM NO. TEST FOR MAIN MEMORY TO FIND BAD CHIPS

%TO ASSEMBLE:	MICRO/L LANG DGMR
TO RUN:		MIDAS RDGMR
		SET "MLOW" AND "MHIGH" TO BRACKET THE MEMORY REGION
		SET "RLOOK" (READS) AND "WLOOK" (WRITES) TO CAUSE "SIGNOVA"
		SET "AINC" TO THE ADDRESS INCREMENT
		START;G

"DGMR" TESTS SEQUENTIAL ADDRESSES FROM "MLOW" TO "MHIGH" USING RANDOM
DATA IN TOP 36 BITS AND COMPLEMENT OF THAT IN LOW 4 BITS.  "SIGNOVA"
IS GENERATED ON WRITES WHEN "WLOOK" = "ADDR" AND F2[3] ON READS WHEN
"RLOOK" = "ADDR".  "MASK" AND "MASKL" DETERMINE THE BITS CHECKED ON
DATA COMPARISON.  AT ERRORS, "MAR" CONTAINS THE ADDRESS, "MDR" AND "MDRL"
THE DATA READ, AND "DATA" AND "DATAL" THE EXPECTED DATA VALUES.
WHEN "AINC" # 1, BE SURE THAT "MHIGH" POINTS TO THE LARGEST ADDRESS
ACTUALLY WRITTEN (NOT IN THE GAP BETWEEN ADDRESSES).

"DGM" SHOULD WORK BEFORE THIS IS TRIED.

THE NORMAL ENTRY "START" USES THE PROCESSOR MEMORY INTERFACE FOR TESTING.
ALTERNATE ENTRY "KSTART" USES THE DISK MEMORY INTERFACE FOR TESTING.
%

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[DATA]; LV[MASK,777777 777777]; RVN[DATAL]; RV[MASKL,17];
LV[WLOOK,10000000]; LV[RLOOK,10000000];
LV[MHIGH,777777]; LV[MLOW,0]; SVN[ADDR]; SVN[COUNT]; RV[AINC,1];

TARGET[ILC];

REPEAT[20,ILC[(BRKP[1]FRZBALUBC)]];

MCYCLE:	BRKP[1], Q←P+1, RETURN;

START:	COUNT←ARM←NULL, INHINT;
	IRET, INHINT, CALL[INIRAN];
	Q←COUNT, GOTO[LOOP];

PQZT:	P AND Q, GOTO[.+2];
PQCOMP:	P#Q;
	RETURN[ALU=0];
	BRKP[1], RETURN;

RETN:	RETURN;

*INITIALIZE RANDOM NO. GEN.
INIRAN:	DGOTO[7], Q←X7;
	X←NPC, RAN←Q, RETURN;

*SAVE RANDOM NO. GEN. STATE IN LM FOR RESTORATION LATER
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, RETURN;

*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];

*SEQUENCE THAT USES PROCESSOR'S MEMORY INTERFACE FOR TESTING.
LOOP:	COUNT←Q, CALL[RGEN];
	Q←MLOW;
	ADDR←Q, CALL[RMARK];	*SAVE INITIAL STATE OF RANDOM NO. GEN.
	CALL[RGEN];
WRANM:	MDR←Q, DATAL←NOT Q;
	WRITE←Q←ADDR, P←WLOOK, INHINT;
	P#Q, Q←DATAL, INHINT;
	MDRL←Q, GOTO[.+2,ALU#0];
	SIGNOVA, P←ADDR, Q←MHIGH, GOTO[.+2]; *SCOPE TRIGGER FOR ADDR=WLOOK
	P←ADDR, Q←MHIGH;
	P-Q, Q←AINC;
	Q←P+Q, DGOTO[WRANM,ALU<0];
	ADDR←Q, CALL[RGEN];

*NOW READ AND COMPARE
	Q←MLOW;
	ADDR←Q, CALL[RREST];
	CALL[RGEN];
RRANM:	DATA←Q;
	READ←P←ADDR, DATAL←NOT Q, Q←RLOOK;
	P#Q, Q←MHIGH;
	P-Q, Q←AINC, GOTO[.+2,ALU#0];
	FRZBALUBC, F2[3];	*SCOPE TRIGGER FOR ADDR=RLOOK IS F2[3]
	Q←P+Q, DGOTO[RRANM,ALU<0];
	ADDR←Q, CALL[.+3];
	DGOTO[LOOP];
	P←COUNT, CALL[MCYCLE];
	Q←MDR, P←DATA;
	P←P#Q, Q←MASK, CALL[PQZT];	*TOP 36 BITS WRONG
	Q←MDRL, P←DATAL;
	P←P#Q, Q←MASKL, CALL[PQZT];	*LOW 4 BITS WRONG

*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;

*SEQUENCE THAT USES THE DISK MEMORY INTERFACE FOR TESTING.

KSTART:	COUNT←ARM←NULL, INHINT;
	IRET, INHINT, CALL[INIRAN];
	Q←COUNT, GOTO[KLOOP];

KLOOP:	COUNT←Q, CALL[RGEN];
	Q←MLOW;
	ADDR←Q, CALL[RMARK];	*SAVE INITIAL STATE OF RANDOM NO. GEN.
	CALL[RGEN];
KWRANM:	MDR←Q, DATAL←NOT Q;
	WRITE←Q←ADDR, P←WLOOK, INHINT;
	P#Q, Q←DATAL, INHINT;
	MDRL←Q, GOTO[.+2,ALU#0];
	SIGNOVA, P←ADDR, Q←MHIGH, GOTO[.+2]; *SCOPE TRIGGER FOR ADDR=WLOOK
	P←ADDR, Q←MHIGH;
	P-Q, Q←AINC;
	Q←P+Q, DGOTO[KWRANM,ALU<0];
	ADDR←Q, CALL[RGEN];

*NOW READ AND COMPARE
	Q←MLOW;
	ADDR←Q, CALL[RREST];
	CALL[RGEN];
KRRANM:	DATA←Q;
	READ←P←ADDR, DATAL←NOT Q, Q←RLOOK;
	P#Q, Q←MHIGH;
	P-Q, Q←AINC, GOTO[.+2,ALU#0];
	FRZBALUBC, F2[3];	*SCOPE TRIGGER FOR ADDR=RLOOK IS F2[3]
	Q←P+Q, DGOTO[KRRANM,ALU<0];
	ADDR←Q, CALL[.+3];
	DGOTO[KLOOP];
	P←COUNT, CALL[MCYCLE];
	Q←MDR, P←DATA;
	P←P#Q, Q←MASK, CALL[PQZT];	*TOP 36 BITS WRONG
	Q←MDRL, P←DATAL, DGOTO[RGEN];
	P←P#Q, Q←MASKL, CALL[PQZT];	*LOW 4 BITS WRONG