%
Page Numbers: Yes First Page: 1
Heading:
DORADO:memrwX.mcMay 14, 1981 2:25 PM%
title[mapReadWriteX];
%*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
TABLE of Contents, by Order of Occurence
beginXtestmain subroutine that calls the tests in this file
mapSingleStepsingle step code for midas debugging
mapRWtestRead and write the map
mapAddrTestMap addressing test
mapRWtest2Map read write test that checks timing margins -- does not execute unless operator patches code. It takes more than 20 minutes to execute.
%*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
%
May 14, 1981 4:49 PM
skip xboard tests if memFlags.xBoard not true (avoid problemes w/ xGetMapIcs)
September 19, 1979 7:16 PM
Move beginXtest to beginning of listing, add call to disableConditionalTask.
September 14, 1979 9:54 AM
Add table of contents, fix typo in beginXtest.
September 13, 1979 4:41 PM
add code that calls each x-board test as a subroutine.
January 25, 1979 4:52 PM
Add check for pipe2.nfaults =7.
January 25, 1979 3:41 PM
Add checking to see if pipe4.mFault is set dukring mapRWtest.
%

* May 14, 1981 2:05 PM
beginXtest: subroutine;
pushReturn[];
call[disableConditionalTask];
checkMtest[memFlags.xBoard, endXtest];
call[xGetMapICs];* init xChipRasCas, etc.
call[mapRWtest];
call[mapAddrTest];
call[mapRWtest2];% this test doesn’t really do anything unless operator patches the code at the entry to this subroutine. This test checks the timing margins of the map chips and requires about 20 minutes or more to execute.
%
endXTest:
returnP[];

top level;
* December 20, 1977 3:16 PM
%
A FEW RULES

Mrow IN [0..mRowEndC)
Mcol IN [0..mColEndC)

Subroutines clobber rscr, rscr2 and T unless otherwise specified at both point of call and in subroutine description. Subroutines return single values in T, and they accept single values in T. Two parameter subroutines accept their values in rscr and rscr2. Subroutines may use the global variables Mrow, Mcol, etc.

Global values for X board
Mrowmap row
Mcolmap column
mcrBitsmcr bits for map manipulation
Mpatcurrent pattern value

Abbreviations used herein
iInit
MMap
Xfor X board, error prefix
colColumn
nextFooincrements foo loop variable, returns with fast branch condition to check for done w/ loop
getFooreturns current value of loop variable, foo
iFooCtrlinitialize foo loop control
%

%
To test the map by reading and writing it:

To avoid refresh problem, touch each row of the map at least once every two milliseconds..
FOR patX IN PatX DO
FOR col IN Col DO
FOR row in Row DO
pat ← getPattern[patX, row, col];
setMap[row, col, pat];
ENDLOOP;
FOR row IN Row DO
pat ← getPattern[pat, row, col];
found ← readMap[row, col];
IF found # pat THEN ERROR;
ENDLOOP
-- end of row check loop
ENDLOOP;-- end of cclumn loop
ENDLOOP;-- end of column loop

setMap: PROCEDURE[row: MapRow, col: MapCol, pat: UNSPECIFIED] =
BEGIN
lowBits ← IF ODD[row] THEN 100000B + col] ELSE col;
hiBits ← BITSHIFT[row, -1];
setBR[hiBits, lowBits];
WHILE MAP[].mapMBufBusy DO ;-- loop while busy
MAP ← 0, STORE ← pat;
END;

readMap: PROCEDURE[row: MapRow, col: MapCol] RETURNS[found: UNSPECIFIED] =
BEGIN
cacheRowBits ← vaFromMapRowCol[row, col];
vacateCacheRow[cacheRowBits];
setBrforMap[row,col];

FETCH ← 0;
WHILE mapBusy[] DO;
found ← MAP;
END;

vacateCacheRow[cacheVa]=
BEGIN
END;
testMap: PROCEDURE[r:Row, c:Column, p:Pattern, c:NumCycles] =
BEGIN
resetMap[];
setBrForMap[r,c];
map ← 0, B ← p;
t ← t - 80;
-- subtract time readMap
IF NOT ((t ← t-80) <=0) THEN WHILE t>0 DO t ← t-1;
[pipe3,pipe4] ← readMap[r,c]; -- readMap takes about 80 cycles
IF pipe3 # p THEN ERROR;
END;
%

* December 14, 1978 12:04 PM

mapSinglStep:

mSSfetch:
fetch ← r0;
noop;
branch[.];* you get what you ask for

mSSfetch2:
fetch ← r0;
noop;
branch[.,cnt#0&-1];
branch[mSSfetch2];

* September 13, 1979 4:42 PM
%
Read and Write the Map

%
mapRWtest:* read and write the map
pushReturn[];
checkMtest[memFlags.mRW, mapRWdone];
call[clearCacheFlags];* just incase beingLoaded is set
call[iMpatCtrl];
mapMainL:* MAIN, OUTER LOOP
call[nextMpat];
skpif[alu#0];
branch[mapRWdone];
noop;

call[iMcolCtrl];* init column control
mapRWcolL:
call[nextMcol];* returns w/ fast br indicating exit condition
skpif[alu#0];
branch[mapMainL];* column loop done; try next hi-order bit of va
Mcol ← t;

call[resetMap];* fix arbitrary initial map states, remove any faults.
call[iMrowCtrl];
mapRWrowL:* the INNER WRITE loop. most complete in < 2 ms
call[nextMrow];* this subr SETS Mrow itself!
skpif[alu#0];
branch[mapRWchk];
noop;
call[getMpat];* make sure MpatHi, MpatLow correct
call[setBRforMap];

call[xGetNumFlts];
t # (7c);
skpif[ALU=0];* Mrow = current row, Mcol = current col.
XrwPipeFlts1Err:
error;

rscr ← MpatHi;
rscr2 ← MpatLow;
call[writeMap];

branch[mapRWrowL];
%NOTE: we can’t check the ref bit explicitly!
It can’t be set to one.
Test must be written to set it implicitly and then to check the results
%
* February 10, 1981 9:54 AM
* now that we have written the map, lets check it!

mapRWchk:
call[iMrowCtrl];
mapRWchkL:* INNER CHECK loop
call[nextMrow];* this subr SETS Mrow itself!
skpif[alu#0];
branch[mapRWcolL];
noop;
call[getMpat];
call[readMap];* rtn w/ rscr=pipe3, rscr2=pipe4
Q ← rscr2;* copy pipe 4 for future reference.
t ← rscr;* remember pipe3 in rscr for a while
t ← t # (MpatLow);* compare pipe3 w/ expected value
skpif[alu=0];* bad bits in T, expected val in Mpat
XrwPipe3Er:
error;* map value in rscr. See pipe for VA

t ← ldf[rscr2, 2, pipe4.dirtyShift];* rt justify the diry, wprotect bits from
t#(MpatHi);* the copy of Pipe4 that is in rscr2.
skpif[ALU=0];* T= wprotect,dirty from pipe4, MpatHi
XrwPipe4Er:* is value of those bits as we wrote them.
error;* rscr2 contains a copy of pipe4, w/ low
* true bits inverted.

t ← (rscr2) and (pipe4.mFault);* see if map fault bit is set.
skpif[ALU=0];
XrwPipeMfltErr:* pipe4.mFault is set. Suggests map parity
error;* error (tho, data read back was good)
* rscr3 = value wrote, rscr2 = pipe4, MrowX, McolX = map row and column,
* current BR shows VA used to read the map.

call[xGetNumFlts];
t # (7c);
skpif[ALU=0];
XrwPipeFlt2Err:* Pipe2.nfaults is set. the current map
error;* read caused the fault to occur.
* T = num faults; see above error for other register info.

branch[mapRWchkL];
mapRWdone:
*this is a one time only check to see if reading the map might clobber the same map entry! this is interesting because reading is implemented by using the write logic and turning off the write signal at the last minute.

Mrow← t← 10c;* write map w/ row=col=10B
call[setBRforMap], Mcol←t;
rscr← a1;
call[writeMap], rscr2← a1;* write it w/ all ones
call[readMap];
(rscr)#(177777C);* rscr= map value. should be -1
skpif[alu=0];
xRWreadBad:
error;
call[readMap];* see if last time we read map it
(rscr)#(cm1);* clobbered this location
skpif[alu=0];
xRWreadBad2:
error;* rscr= map value. should be -1
noop;
returnP[];

* September 13, 1979 4:43 PM
%
mapAddrTestTest the addressing mechanism of the map. This test follows the same pattern as the addressing tests for C, D, and S boards:
(Ascent Test)Zero the memory, then ascend the memory as follows:
1) If the current location is non zero, there was an addressing error (a previous store to an "earlier" location clobbered the "current" location). Invoke the routine that finds exactly which store that caused this error.
2) Otherwise, set the current location to all ones.
3) Increment the current address; if all addresses have been tested proceed to the descent addressing test, otherwise proceed to step 1.
(Descent test) Zero the memory, then proceed as in the ascent test, except we descend through the memory (decrement) rather than ascend (increment).
(Ascent error routine) Denote the "error address" as the clobbered address discovered in the ascent test. The ascent error routine proceeds by zeroing the memory, then ascending thru the memory as follows:
1) If the error address is nonzero, the last store which the ascent error routine made clobbered that location (storing into the "current address -1" clobbered the "error address" that was detected by the ascent test.
2) Otherwise, set the current location to all ones.
3) Increment the current address; if all addresses have been tested, there must have been an intermittent error, otherwise proceed to step 1.

The descent error routine is similar to the ascent error in the same way.
%
mapAddrTest:
pushReturn[];
checkMtest[memFlags.mAddr, xDownXit];* see if this test enabled.
call[clearCacheFlags];* just incase being loaded is set
call[xZeroMap];
call[iMapPageCtrl];
xUpL:
call[nextMpage];* rtns w/ t = next page, fast br condition
skpif[ALU#0];* tells if we’re done w/ loop.
branch[xUpXit];
noop;* for placement

call[xReadMapPage];* current address should still be zero
PD ← t;
skpif[ALU=0];
branch[xErrUp];* a previous store clobbered current addr

call[getMpage];* get current addr into t again
call[xWriteMapPage], rscr ← cm1;* set current addr to all ones
branch[xUpL];
xUpXit:
call[xZeroMap];
call[iMpageDownCtrl];

xDownL:
call[nextMpageDown];* rtns w/ t = next page, fast br condition
skpif[ALU#0];* tells if we’re done w/ loop.
branch[xDownXit];
noop;* for placement

call[xReadMapPage];* current address should still be zero
PD ← t;
skpif[ALU=0];
branch[xErrDown];* a previous store clobbered current addr

call[getMpage];* get current addr into t again
call[xWriteMapPage], rscr ← cm1;* set current addr to all ones
branch[xDownL];

xDownXit:
returnP[];
top level;

* December 25, 1978 11:09 AM
xErrUp:* The ascent test has discovered a clobbered location in the map. Now we proceed to determine whgich store clobbers that location.
call[getMpage];
stack&+1 ← t;* stack = map page that got clobbered.
call[xZeroMap];* clear the map
call[iMapPageCtrl];* loop init
call[xReadMapPage], t ← r0;* make sure we succeeded in zeroing the
PD ← t;* first location of the map
skpif[ALU=0];
xUpErr1:* first entry in map is non zero. this suggests that xZeroMap
error;* didn’t work
noop;* for placement

xErrUpL: * Top of loop that ascends memory looking for the store that clobbers the error
call[nextMpage];* location (held in stack).
skpif[ALU#0];* intermittent error if no more map pages
branch[xErrUpIntermittent];
noop;* for placement
call[xReadMapPage], t ← stack;* see if "error location" clobbered yet.
PD ← t;
skpif[ALU=0];
xErrUp2: * the previous map write clobbered the map entry at "stack"
error;

call[getMpage];* set "current location" to all ones, except
(stack) # t;* don’t write into the error address.
skpif[ALU=0];* Skip if an intermittent failue since
call[xWriteMapPage], rscr ← cm1;* (WRITE map)
* the descent test discovered that errror address was clobbered by a store we’ve
* already performed. Sigh. Keep going to see what happens.
noop;* for placement
branch[xErrUpL];
xErrUpIntermittent: * Can’t find error ascent test found (entry at "stack" gets clobbered).
error;

xErrDown:* The descent test has discovered a clobbered location in the map. Now we proceed to determine which store clobbers that location.
call[getMpage];
stack&+1 ← t;* stack = map page that clobbered
call[xZeroMap];
call[iMPageDownCtrl];

xErrDownL:* top of loop that descends the map memory
call[nextMpageDown];
skpif[ALU#0];* intermittent error if no more map pages
branch[xErrDownIntermittent];
noop;* for placement

call[xReadMapPage], t ← stack;* see if "error location" clobbered yet.
PD ← t;
skpif[ALU=0];
xDownErr2: * The previous write (MpageX+1) clobbered the error address (stack).
error;

call[getMpage];
t # (stack);* don’t write into the error address.
skpif[ALU=0];* if we’ve come this far, there must have been an intermittent failue since
* the descent test discovered that errror address was clobbered by a store we’ve
* already performed. Sigh.
call[xWriteMapPage], rscr ← cm1;* WRITE map
branch[xErrDownL];

xErrDownIntermittent: * Can’t find error descent test found (entry at "stack" clobbered).
error;

* December 28, 1977 8:59 AM
%
Test MAP TIMING ATTRIBUTES
FOR cycles ←0,cycles ← cycles+20000B UNTIL cycles >=60000B DO
FOR patx IN PatX DO
FOR hi2BRbits IN[0..3] DO
FOR row IN Row DO
FOR col IN Column DO
pat ← getPattern[patX, row, col];
testMap[row,col,hi2BRbits,pat, cycles];
ENDLOOP;
ENDLOOP;
ENDLOOP:
ENDLOOP;
ENDLOOP;

Note: This test checks every column for a particular row before it proceeds to next row.
%
* December 14, 1978 12:04 PM
mapRWtest2:
pushReturn[];
branch[map2RWdone];* must patch this test explicitly. It takes over 20 minutes to run.
call[iMWaitCtrl];
call[resetMap];
map2CyclesL:* MAIN, OUTER LOOP: Cycles to wait
call[nextMwait];
skpif[alu#0];
branch[map2RWdone];* wait loop done. try next hi order bit
noop;* throw away result. we’ll get it again.

call[iMpatCtrl];
map2PatternL:* LOOP: Pattern Control
call[nextMpat];
skpif[alu#0];
branch[map2CyclesL];* have used all patterns. try next wait value
noop;

call[iMrowCtrl];
map2RWrowL:* LOOP: Map Row
call[nextMrow];* this subr SETS Mrow itself!
skpif[alu#0];
branch[map2PatternL];* rows done. try next high order Va bit value
noop;

call[iMcolCtrl];* init column control
map2RWcolL:
call[nextMcol];* returns w/ fast br indicating exit condition
skpif[alu#0];
branch[map2RWrowL];* column loop done; try next row
Mcol ← t;
call[getMpat];
call[getMwait];
rscr ← t;* assumes rscr = cycles to wait.
rscr2 ← r0;* dont call resetMap
call[testMap];* test current <row,col,pattern,wait>
branch[map2RWcolL];
map2RWdone:
returnP[];