%
*** *** *** *** <D0Diag>Rev-1>EDSmallMem.mc Revision 1.1 May 3, 1980 *** *** *** ***

****************************************************************************************
*** EDSmallMem.mc : Small Memory Exerciser microcode
*** Purpose : This test exhaustively exercises the control store as a 4K x 36 bit memory,
except for locations occupied by the program or the kernel;
and the T registers, except for T[16] and T[17].
*** Minimum Hardware : Standard 4 CPU boards.
*** Approximate Run Time : 30 seconds.
*** Written by : Tom Horsley,
January 3, 1978
note: since this test tests all of control store except Page 0, the main program has
been left on Page 0. March 10, 1978 1:39 PM Bill Kennedy
*** Modified by : Bill Kennedy,
April 20, 1978
to re-initialize Control Store
*** Modified by : Chuck Thacker,
December 12, 1978
to force CS reads and writes in RCSLoop to be on even locations.
*** Modified by : Chuck Thacker,
June 14,1979
to avoid R0, R11-17, CS pages 16 and 17, tasks 16 and 17.
*** Modified by : T. Henning,
November 5, 1979
to standardize title page and code format, add looping and additional patterns.
*** Modified by : Chuck Thacker,
May 3, 1980
to standardize assembly with smallmem.cm, fix for new d0lang.
****************************************************************************************


****************************************************************************************
*SubTest Description:
* SubTest 0: The test has stopped at an unexpected place, something else is
interfering with this test.
* SubTest 1: Confirm that the value written (Pattern) into Control Store bits 0 to 15
is the one read out (Result).
* SubTest 2: Confirm that the value written (Pattern) into Control Store bits 16 to 31
is the one read out (Result).
* SubTest 3: Confirm that the value written (Pattern) into Control Store bits 32 to 35
is the one read out (Result).
* SubTest 4: Before writing a t-register confirm that it contains its index.
If it doesn’t then possibly the wrong register has been accessed.
Also, confirm that the value written (Pattern) into the T register is the one
read out (Result).

****************************************************************************************
*BreakPoints:
* PATTERNERROR: Result read did not match Pattern written.
* BADT: Index read from the current T register was not correct in SubTest 4.
* BAD-MEMADDR: MemAddr is beyond allowed values, legal ranges are:
SubTest 1: 400 to 6777 (StartWord to EndWord)
SubTest 1: 400 to 6777 (StartWord to EndWord)
SubTest 1: 400 to 6777 (StartWord to EndWord)
SubTest 1: 0 to 15 (tasks 16, 17 disallowed for Timer and Kernel)
* PASSED-EDSMALLMEM-TEST: Passed all tests, and all passes.

****************************************************************************************
* ShortLoop Logic Analyzer Sync Points at Control Store address:
* PATTERNERROR: Control Store address 145 at MAINLOOP.
* BADT: Control Store address 145 at MAINLOOP.

****************************************************************************************
*Special Reg. Definition:

* ShortLoop: At any breakpoint, the user has the choice of setting ShortLoop to a 1 to
loop on the current test. During the short loop, the user can modify the address
and data to the Control Store at will by changing MemAddr and Pattern. For the
T register test in subtest 4, the T register and the test pattern can also be
changed at will.

1, the current test will loop repeatedly for trouble shooting
0, no looping in current test

* PatternChoice:

Bit 15 - all zeros pattern, enable by 1, disable by 0
Bit 14 - all ones pattern, enable by 1, disable by 0
Bit 13 - checker pattern, enable by 1, disable by 0
Bit 12 - random pattern, enable by 1, disable by 0

Example: PatternChoice=1 enables the all zeros pattern only
PatternChoice=2 enables the all ones pattern only
PatternChoice=4 enables the checker pattern only
PatternChoice=10 enables the random pattern only
PatternChoice=17 enables all four of the patterns
PatternChoice=11 enables the random and all zeros patterns

****************************************************************************************
*Subroutine Description:
* ReInitCS: zeros out Control Store and puts in correct parity.
****************************************************************************************
%

****************************************************************************************
*INITIALIZATION:

TITLE[SmallMemoriesTester]; * Exhaustively exercises various small memories
SET[MainPage, 0]; * set tag for Main Program page
ONPAGE[MainPage];

********** R-Registers: **********

RV[PassCount,20];*outer loop counter
RV[MaxPass,21,10];*number of times big loop is to repeat before breakpointing
RV[SubTest,22];* current location of test
RV[TestCounter,23];* inner loop counter

RV[CA,24];*used in random number generation, A*XA + CA
RV[XA,25];*random number generated via A*XA + CA
RV[CurrentXA,26];*value of XA to be used (usually XA, sometimes OldXA)
RV[OldXA,27];*last valueof XA

RV[CS0Test,30];*number of test iterations
RV[CS1Test,31];*number of test iterations
RV[CS2Test,32];*number of test iterations

RV[StartWord,33, 400];* beginning of control store to be tested
RV[Endword,34, 6777];*end of control store to be tested

RV[RepeatCounter,35];*number of test repeats
RV[TmemTest,36];*number of test iterations
RV[CS0,37];* temporary register used in re-initializing Control Store
RV[CS1,40];* temporary register used in re-initializing Control Store
RV[CS2,41];* temporary register used in re-initializing Control Store

RV[NewTask,42];*used in task switching
RV[Tmp,43];* temporary register

SET[wordLoc, 44];*address of register ’MemAddr’
RV[MemAddr, wordLoc];*address of memory cell to be tested
MC[wordAddress, wordLoc];*address of register ’MemAddr’
RV[Pattern, ADD[wordLoc, 1]];*pattern to be stuffed into word
RV[Result, ADD[wordLoc, 2]];*result of memory read

RV[PatternChoice,47,17];*enable all patterns at program start
RV[CurrentPattern,50,1];*initialize to all zeros pattern
RV[PatternTry,51,1];*initialize to all zeros pattern
RV[Ones,52,177777];*define ones to be 177777
RV[Checker1,53,125252];*checker pattern register
RV[Checker0,54,052525];*checker pattern register
RV[Toggle,55,0];*checker toggle register

RV[ShortLoop,56,0];* 1 => loop on current test, 0 => continue on next test

RV[Revision,57,1];*REVISION 1
RV[Run-Time,60,36];*Run-Time is 36b or 30D seconds

********** Task Entry Points: **********

SET[higherTaskLoc, 40];*entry point to higher task
MC[higherTaskEntry, higherTaskLoc];*entry point to higher task

SET[lowerTaskLoc, 50];*entry point to task 0
MC[lowerTaskEntry, lowerTaskLoc];*entry point to task 0

SET[higherTaskLoc1, 60];*entry point to higher task
MC[higherTaskEntry1, higherTaskLoc1];*entry point to higher task

SET[lowerTaskLoc1, 70];*entry point to task 0
MC[lowerTaskEntry1, lowerTaskLoc1];*entry point to task 0

SET[testSwitch, 20];*location of main switch
SET[MainPageBase,LSHIFT[MainPage,10]];

****************************************************************************************
*** MAIN routine:

go:
start:
XA ← 123c;*Load 16 Bits (XA ← 123)

CA ← AND[0377, 33031]C;*Load 16 Bits (CA ← 33031)
CA ← (CA) OR (AND[177400, 33031]C);

CLEARMPANEL;
TestCounter ← 0C;
PassCount ← 0C;
CS0Test ← 0C;
CS1Test ← 0C;
CS2Test ← 0C;
TmemTest ← 0C;
RepeatCounter ← 0C;
t ← 20000C;*set up CurrentXA so that it contains valid address
t ← (LSH[StartWord, 1]) OR (t);
CurrentXA ← t;

t ← (1C);*Initialize task registers to their task index
MemAddr ← t;
IndexT: t ← (17C);
LU ← (MemAddr) - (t) - 1;
GOTO[IndexTDone, ALU >= 0];

t ← LSH[MemAddr, 14];
NewTask ← t;

NewTask ← (NewTask) OR (higherTaskEntry1);
APCTASK&APC ← (NewTask);
RETURN;

Tmp ← wordAddress, AT[higherTaskLoc1];*write value into t register
STKP ← Tmp;
t ← STACK;

Tmp ← lowerTaskEntry1;*return to task 0
APCTASK&APC ← (Tmp);
RETURN;

NOP, AT[lowerTaskLoc1];

MemAddr ← (MemAddr) + 1;*Increment FOR loop counter
GOTO[IndexT];

IndexTDone:
nop;

bigLoop: t ← (PatternTry) and not (17C);
*what pattern to use?
goto[WhatPattern,alu=0];*exhausted all four pattern types?
PatternTry ← 1C;*yes, select the zero pattern again
Toggle ← 0C;*reset checker pattern toggle
INCMPANEL;
PassCount← t ←(PassCount)+1;*increment pass count
lu ← (MaxPass) - (t);
goto[EndTest, alu<0];*finished all passes?
nop;
WhatPattern: t ← PatternChoice;
*determine what pattern to use
t ← (PatternTry) AND (t);
goto[NextPattern,alu=0];*do we want to use this pattern?
ThisPattern: CurrentPattern ← t, goto[mainLoop];
*yes, use this pattern
NextPattern: PatternTry ← LSH[PatternTry,1], goto[bigLoop];
*no, try the next pattern

EndTest:
CALL[ReInitCS];* go re=initialize control store
Passed-EDSmallMem-Test: BREAKPOINT, goto[go];

* SUBTEST 0
mainLoop:
SubTest ← 0C, AT[145];*nail down scope trigger point
ShortLoop ← ShortLoop, GOTO[decipherXA, R ODD];*ShortLoop selected?

TestCounter ← (TestCounter) + 1;
GOTO[.+2, NOCARRY];
PatternTry ← LSH[PatternTry,1], goto[bigLoop];*use next pattern

t ← (CurrentXA);
OldXA ← t;

t ← XA, TASK;*task so that Midas can mouse halt
t ← (LSH[XA, 2]) + t;*Random (4005*XA + CA mod 2**16)
t ← (LSH[XA, 13]) + t;
t ← (CA) + t;
XA ← t;
t ← (XA);
CurrentXA ← t;

t ← (CurrentPattern) AND (1C);
goto[Try1,alu=0];*want the zeros pattern?
Pattern ← 0C, goto[decipherXA];*yes
Try1:
t ← (CurrentPattern) AND (2C);*no, try the ones pattern
goto[Try2,alu=0];*want the ones pattern?
t ← Ones; *yes
Pattern ← t, goto[decipherXA];
Try2:
t ← (CurrentPattern) AND (4C);*no, try the checker pattern
goto[Try3,alu=0];*want the checker pattern?
Toggle ← Toggle, goto[Checker01,R ODD];*yes
t ← Checker1; *1010101010101010 pattern
Pattern ← t;
Toggle ← (Toggle) + 1, goto[decipherXA];*toggle checker pattern
Checker01: t ← Checker0;
*0101010101010101 pattern
Pattern ← t;
Toggle ← (Toggle) + 1, goto[decipherXA];*toggle checker pattern
Try3:
t ← (CurrentPattern) AND (10C);*no, try the random pattern
goto[bigLoop,alu=0];*want the random pattern?
t ← (CurrentXA);*yes
Pattern ← t;
t ← PassCount;
Pattern ← (Pattern) + (t);

decipherXA:
SET[Switch0, TestSwitch];*pick memory to be tested
DISPATCH[CurrentXA, 0, 3];
DISP[SwitchTab0];
SwitchTab0:
GOTO[Case0], AT[Switch0, 0];
GOTO[Case1], AT[Switch0, 1];
GOTO[Case2], AT[Switch0, 2];
GOTO[Case3], AT[Switch0, 3];
GOTO[Case4], AT[Switch0, 4];
GOTO[Case5], AT[Switch0, 5];
GOTO[Case6], AT[Switch0, 6];
GOTO[Case7], AT[Switch0, 7];

* SUBTEST 1
Case0:

SubTest ← 1C;*CS0 Memory

t ← LDF[CurrentXA, 3, 14];
ShortLoop ← ShortLoop, GOTO[.+2, R ODD];*ShortLoop selected?
MemAddr ← t;

t ← MemAddr;
LU ← (StartWord) - (t) - 1;
GOTO[Range1, ALU < 0];*Check Range
GOTO[OutRange];

Range1:
LU ← (EndWord) - (t);
GOTO[Range2, ALU >= 0];
GOTO[OutRange];

Range2:
LU ← (Pattern);*write the pattern
APCTASK&APC ← (MemAddr);
WriteCS0&2;

t ← 0C;*read the word
APCTASK&APC ← (MemAddr);
READCS;
t ← CSData;
Result ← t;

CS0Test ← (CS0Test) + 1;
GOTO[Endswitch0];

* SUBTEST 2
Case1:

SubTest ← 2C;*CS1 Memory

t ← LDF[CurrentXA, 3, 14];
ShortLoop ← ShortLoop, GOTO[.+2, R ODD];*ShortLoop selected?
MemAddr ← t;

t ← MemAddr;
LU ← (StartWord) - (t) - 1;
GOTO[Range3, ALU < 0];*Check Range
GOTO[OutRange];

Range3:
LU ← (EndWord) - (t);
GOTO[Range4, ALU >= 0];
GOTO[OutRange];

Range4:
LU ← (Pattern);*write the pattern
APCTASK&APC ← (MemAddr);
WriteCS1;

t ← 1C;*read the word
APCTASK&APC ← (MemAddr);
READCS;
t ← CSData;
Result ← t;

CS1Test ← (CS1Test) + 1;
GOTO[Endswitch0];

* SUBTEST 3
Case2:

SubTest ← 3C;*CS2 Memory

t ← LDF[CurrentXA, 3, 14];
ShortLoop ← ShortLoop, GOTO[.+2, R ODD];*ShortLoop selected?
MemAddr ← t;

t ← MemAddr;
LU ← (StartWord) - (t) - 1;
GOTO[Range5, ALU < 0];*Check Range
GOTO[OutRange];

Range5:
LU ← (EndWord) - (t);
GOTO[Range6, ALU >= 0];
GOTO[OutRange];

Range6:
t ← (Pattern);*write the pattern
LU ← 0C;*This shouldn’t be necessary?!!!!!
APCTASK&APC ← (MemAddr);
WriteCS0&2;

t ← 3C;*read the word
APCTASK&APC ← (MemAddr);
READCS;
t ← CSData;
Result ← t;
Result ← LDF[Result, 0, 4];

Pattern ← LDF[Pattern, 14, 4];*abreviate expected result

CS2Test ← (CS2Test) + 1;
GOTO[Endswitch0];

* SUBTEST 4
Case3:

Subtest ← 4C;*t Memory

t ← LDF[CurrentXA, 3, 4];
ShortLoop ← ShortLoop, GOTO[.+2, R ODD];*ShortLoop selected?
MemAddr ← t;

MemAddr ← (MemAddr) AND (17C);*use the LSB 4 bits for T(task) to be tested
T ← (MemAddr) and (16C);*don’t do tasks 16 or 17
Tmp ← T;
lu ← (Tmp) xor (16C);
goto[.+2, alu#0];
goto[OutRange];

t ← LSH[MemAddr, 14];*enter higher task
NewTask ← t;

NewTask ← (NewTask) OR (higherTaskEntry);
t ← 0C;
APCTASK&APC ← (NewTask);
RETURN;

Tmp ← wordAddress, AT[higherTaskLoc];*check to ascertain correct t-register
STKP ← Tmp;
Tmp ← t;
LU ← (STACK&+1) - (t);
GOTO[EndT, ALU = 0];

ShortLoop ← ShortLoop, GOTO[BADT, R EVEN];*ShortLoop for troubleshooting?
goto[EndT];
BADT: BREAKPOINT;

EndT:
t ← STACK&+1;*t ← Pattern
STACK ← t;*Result ← t
t ← Tmp;*restore task number in t
Tmp ← lowerTaskEntry;*return to task 0
APCTASK&APC ← (Tmp);
RETURN;

TmemTest ← (TmemTest) + 1, AT[lowerTaskLoc];
GOTO[Endswitch0];

Case4:

GOTO[OutRange];*Repeat the last test, i.e., hit the last memory location again

Case5:

GOTO[OutRange];*Repeat the last test, i.e., hit the last memory location again

Case6:

GOTO[OutRange];*Repeat the last test, i.e., hit the last memory location again

Case7:

GOTO[OutRange];*Repeat the last test, i.e., hit the last memory location again

Endswitch0:
tests:
TASK;*enable mouse halt
t ← Result;
LU ← (Pattern) - (t);
GOTO[Endif0, ALU = 0];

ShortLoop ← ShortLoop, GOTO[PATTERNERROR, R EVEN];*ShortLoop for troubleshooting?
goto[Endif0];
PATTERNERROR:
BREAKPOINT;

Endif0:
GOTO[mainLoop];

OutRange:
ShortLoop ← ShortLoop, GOTO[.+2, R EVEN];*ShortLoop for troubleshooting?
Bad-MemAddr:
breakpoint;
goto[mainloop];
*
t ← (OldXA);
*
CurrentXA ← t;

*
RepeatCounter ← (RepeatCounter) + 1;
*
GOTO[decipherXA];

********** SUBROUTINE: ReInitCS **********
*
*
Puts zeros into the Control Store from StartWord
*
to EndWord and also puts in the correct parity.

ONPAGE[MainPage];
ReInitCS:
CS0 ← ZERO;* zero what’s to be written into CS
CS1 ← ZERO;* zero what’s to be written into CS
CS2 ← ZERO;* zero what’s to be written into CS
t ← StartWord;* Write control store from ’StartWord’ to ’EndWord’
NewTask ← t;
t ← CS0;*WriteCS (write control store location ’NewTask’)
Tmp ← t;*put CS0 in the temp. reg.
t ← CS1;*get CS1
Tmp ← t ← (Tmp) XOR (t);*xor first two CS words
t ← (LDF[CS2,14,4]) XOR (t);*xor third CS word with the result
Tmp ← t ← (LDF[Tmp,0,10]) XOR (t);*start halfing process to get parity
Tmp ← t ← (LDF[Tmp,10,4]) XOR (t);
Tmp ← t ← (LDF[Tmp,14,2]) XOR (t);
Tmp ← t ← (LDF[Tmp,16,1]) XNOR (t);*Do last part and complement it
t ← (LDF[Tmp,17,1]);*put parity bit in the t-register
CS1 ← (CS1) XOR (t);*exclusive or parity bit into bit 31 of CS (15 of CS1)
RCSLoop:
t ← (CS2);
LU ← (CS0);
APCTASK&APC ← (NewTask);
WriteCS0&2;
LU ← (CS1), at[MainPageBase,340];*force WriteCS to have JA.7=1
APCTASK&APC ← (NewTask);
WriteCS1;
t ← NewTask ← (NewTask) + 1, at[MainPageBase,350];
*increment address - Force WriteCS1’s JA.7=0
LU ← (EndWord) - (t) - 1;* see if done yet
GOTO[RCSLoop, CARRY];
RETURN;

END;