%
Page Numbers: Yes First Page: 1
Heading:
DORADO:memSubrsA.mcJune 9, 1981 11:14 AM%
%
June 9, 1981 11:15 AM
Add iMemState to init sTestReg from IM.
May 14, 1981 4:33 PM
add rlinkRet, etc. to reduce size of add/remove/only ??board tests
June 27, 1979 7:06 PM
Make orMemFlags, andMemFlags, and xorMemFlags global to save IM space.
May 7, 1979 4:04 PM
Fix register clobber bug in memory simulator task.
April 19, 1979 12:57 PM
Initialize memory simulator task’s membase, baseregisters.
April 17, 1979 10:43 PM
Cause memSim code to notice that taskSimulation is disabled (make holdSim independent of task sim).
January 17, 1979 9:35 AM
sInterference test calls sUseDefaultMcr (saSetMcr now defunct).
January 13, 1979 12:39 PM
diddles to get mema to place
January 13, 1979 2:45 AM
comment-out "breakpoint" in midas subroutines: microD can’t place memA
January 13, 1979 12:50 AM
Add comments describing how to patch out stores in memory task simulator.
%
title[memSubrsA];
top level;
branch[memSubrsADone];

getAsubrScr: subroutine;
RBASE ← rbase[aSubrScr];
return, t ← aSubrScr, RBASE ← rbase[defaultRegion];
getAmakingFaults: subroutine;
RBASE ← rbase[aMakingFaults];
return, t ← aMakingFaults, RBASE ← rbase[defaultRegion];
rlinkRet:
returnUsing[rlink];

* May 7, 1979 4:04 PM
%
Task Simulator Code for Memory Storage Diagnostic
This code runs when the Dorado task simulator awakens task 17. Its purpose is to cause multi-task memory activity during the memory storage test. The storage diagnostics continually cause misses, and this code is set up to fetch & store from a roving pointer (increment can be patched to zero). There is a delay loop to prevent the diagnostics from spending too long in hold in the task simulation code.
The place where the delay register is initialized and where the address is incremented is shown in bold. These values can be patched using Midas; changing the delay constant will modify the amount of time the memory task spends being held by its fetches, and changing the address increment may modify the row selected by the memory task during its fetches. Note that only one row is touched by the memory task with an increment of cdMaxVa.
simScr0 The address that we fetch
simScr1 The data obtained from MD when this task woke up
simScr2 Used as a scratch register to remember the current hold vaule, also loaded with a loop constant for the memSimL1 loop. The memSimL1 loop prevents task 17 from using all the machine by doing references that always hold. The smaller the constant (see memSimSetDelay), the more frequently task 17 makes memory references when it runs.
memSimStore The address to patch into a noop to remove STOREs from the memory task simulator.
memSimSetDelay The address to patch to change the delay constant for the task simulator.
memSimIncAddr The address to patch to change the increment applied to the current address.
%
top level;
set[xtask, 1];* non emulator code
memSimInit:
t ← q,at[memSimInitLoc];
hold&tasksim ← t;* zero hold if that is what is happening
t ← t and (sim.taskMask);* do nothing if not tasking (allow hold sim)
skpif[alu#0];* see if we are really supposed to run
block;* no, just turning off hold
RBASE ← rbase[defaultRegion];
call[setMbase],t←12C;* set memBase, BR for this task
t ← rscr ← t-t;
call[setBR], rscr2←t;
RBASE ← rbase[simScr0];
t ← q;* restore t = holdValue
branch[memSimFetchNextTime], FETCH ← simScr0;

memSimL1:* top of delay loop
simScr2 ← (simScr2) - 1;* we’ll make memory references only after
skpif[alu>=0];* waiting a while. This enables the relatively
branch[memSimFetchNextTime];* slow memory diagnostics to make progress.
hold&tasksim ← t;* otherwise, most real time is spent w/ memory
noop;* task being held.
branch[memSimL1], block;* Still waiting.
memSimFetchNextTime:
hold&tasksim ← t;
fetch ← simScr0;* remember 1st instr. after hold← doesn’t count
block;
memSimFetchMD:
simScr1 ← MD;* fetch the memory data waiting for us
simScr2 ← t;* save t, our hold value, for future use

FETCH ← simScr0;* fetch it again in preparation for storing it
t ← MD;* get data for our store
memSimStore:
STORE ← simScr0, DBuf ← t;* store the data we just read

t ← simScr2;* restore hold value in T
memSimSetDelay:
simScr2 ← 25c;* reset the delay counter

hold&tasksim ← t;* remember 1st instr. after hold← doesn’t count
noop;
memSimIncAddr:
branch[memSimL1], simScr0 ← (simScr0) + (cdMaxVa), block;* selects
* a different addr without changing the row!
knowRbase[defaultRegion];
set[xtask, 0];* emulator code

* May 14, 1981 4:29 PM
orMemFlagsAndExit:
call[orMemFlags];
branch[rlinkRet];

andMemFlagsAndExit:
call[andMemFlags];
branch[rlinkRet];

addCboardTest: subroutine;
saveReturn[rlink];
branch[orMemFlagsAndExit], t ← memFlags.Cboard;
removeCboardTest: subroutine;
saveReturn[rlink];
branch[andMemFlagsAndExit], t ← not(memFlags.Cboard);
onlyCboardTest: subroutine;
saveReturn[rlink];
call[andMemFlags], t ← t - t;* remove all other tests
branch[orMemFlagsAndExit], t ← memFlags.Cboard;* add Cboard test

addXboardTest: subroutine;
saveReturn[rlink];
branch[orMemFlagsAndExit], t ← memFlags.Xboard;
removeXboardTest: subroutine;
saveReturn[rlink];
branch[andMemFlagsAndExit], t ← not(memFlags.Xboard);
onlyXboardTest: subroutine;
saveReturn[rlink];
call[andMemFlags], t ← t - t;* remove all other tests
branch[orMemFlagsAndExit], t ← memFlags.Xboard;* add Xboard test

addDboardTest: subroutine;
saveReturn[rlink];
branch[orMemFlagsAndExit], t ← memFlags.Dboard;
removeDboardTest: subroutine;
saveReturn[rlink];
branch[andMemFlagsAndExit], t ← not(memFlags.Dboard);
onlyDboardTest: subroutine;
saveReturn[rlink];
call[andMemFlags], t ← t - t;* remove all other tests
branch[orMemFlagsAndExit], t ← memFlags.Dboard;* add Dboard test

addSboardTest: subroutine;
saveReturn[rlink];
branch[orMemFlagsAndExit], t ← memFlags.Sboard;
removeSboardTest: subroutine;
saveReturn[rlink];
branch[andMemFlagsAndExit], t ← not(memFlags.Sboard);
onlySboardTest: subroutine;
saveReturn[rlink];
call[andMemFlags], t ← t - t;* remove all other tests
branch[orMemFlagsAndExit], t ← memFlags.Sboard;* add Sboard test

addAboardTest: subroutine;
saveReturn[rlink];
branch[orMemFlagsAndExit], t ← memFlags.Aboard;
removeAboardTest: subroutine;
saveReturn[rlink];
branch[andMemFlagsAndExit], t ← not(memFlags.Aboard);
onlyAboardTest: subroutine;
saveReturn[rlink];
call[andMemFlags], t ← t - t;* remove all other tests
branch[orMemFlagsAndExit], t ← memFlags.Aboard;* add Aboard test

addAllTests: subroutine;
saveReturn[rlink];
t ← memFlags.default0;
t ← t + (memFlags.default1);
branch[orMemFlagsAndExit];

removeAllTests: subroutine;
saveReturn[rlink];
branch[andMemFlagsAndExit], t ← t-t;

orMemFlags: subroutine;* save the bits to xor
sSubrScr ← t, global;
t ← link;
top level;
Srlink ← t;
t ← memFlagsLocC;* get current flag bits
call[getIMRH];
call[getsSubrScr], rscr ← t;* re-fetch bits to xor
rscr ← t OR (rscr);* xor the bits
t ← memFlagsLocC;
call[putIMRH];* save new bit values
returnUsing[Srlink];

andMemFlags: subroutine;* save the bits to xor
sSubrScr ← t, global;
t ← link;
top level;
Srlink ← t;
t ← memFlagsLocC;* get current flag bits
call[getIMRH];
call[getsSubrScr], rscr ← t;* re-fetch bits to xor
rscr ← t AND (rscr);* xor the bits
t ← memFlagsLocC;
call[putIMRH];* save new bit values
returnUsing[Srlink];

xorMemFlags: subroutine;* save the bits to xor
sSubrScr ← t, global;
t ← link;
top level;
Srlink ← t;
t ← memFlagsLocC;* get current flag bits
call[getIMRH];
call[getsSubrScr], rscr ← t;* re-fetch bits to xor
rscr ← t # (rscr);* xor the bits
t ← memFlagsLocC;
call[putIMRH];* save new bit values
returnUsing[Srlink];

* October 1, 1978 4:13 PM
* turn on error correction during memS testing. doesn’t take effect until begining
* execution at "BEGIN"
*
ECon: subroutine;
saveReturn[Arlink];
call[getMemState];
t ← t OR (memState.useTestSyn);
call[putMemState];
returnUsing[Arlink];

* October 2, 1978 8:22 AM
* turn off error correction during memS testing. doesn’t take effect until begining
* execution at "BEGIN"

ECoff: subroutine;
saveReturn[Arlink];
call[getMemState];
rscr ← not(memState.useTestSyn);
call[putMemState], t ← (rscr) and t;* mask out useTestSyn
returnUsing[Arlink];

* October 2, 1978 8:23 AM
* turn on memState.usingOneColumn. This is an information bit provided by the
* diagnostics to indicate whether or not memS has set MCR to use only one cache column.

usingOneColOn: subroutine;
saveReturn[Arlink];
call[getMemState];
rscr ← (memState.usingOneColumn);
call[putMemState], t ← (rscr) OR t;* OR in usingOneColumn
returnUsing[Arlink];

* October 2, 1978 8:24 AM
* turn off memState.usingOneColumn. This is an information bit provided by the
* diagnostics to indicate whether or not memS has set MCR to use only one cache column.

usingOneColOff: subroutine;
saveReturn[Arlink];
call[getMemState];
rscr ← not(memState.usingOneColumn);
call[putMemState],t ← (rscr) AND t;* mask out usingOneColumn
returnUsing[Arlink];

* April 26, 1978 12:55 PM
* turn loopOnError: for those tests that are so implemented, this bit causes the
* test to enter a loop if an error occurs, the loop reexecutes the sequence that caused
* the error.

loopOnErrorOn: subroutine;* set memState.loopOnError
saveReturn[Arlink];

call[getMemState];
t ← t OR (memState.loopOnError);* OR in the bit
call[putMemState];
returnUsing[Arlink];

* August 19, 1978 2:18 AM
* turn on memstate.noWake. The value of this bit is the value for mcr.noWake used by sUseDefaultMcr.

saNoWakeOn: subroutine;* set memState.loopOnError
saveReturn[Arlink];

call[getMemState];
t ← t OR (memState.noWake);* OR in the bit
call[putMemState];
returnUsing[Arlink];

* October 2, 1978 8:25 AM
* turn off memstate.noWake. The value of this bit is the value for mcr.noWake used by sUseDefaultMcr.

saNoWakeOff: subroutine;* set memState.loopOnError
saveReturn[Arlink];

call[getMemState];
rscr ← not(memState.noWake);
call[putMemState], t ← t AND (rscr);* remove the bit
returnUsing[Arlink];

* October 1, 1978 4:16 PM
* turn on memstate.FIOtest. FIOtest only runs if this bit is true.

FIOtestOn: subroutine;* set memState.loopOnError
saveReturn[Arlink];

call[getMemState];
t ← t OR (memState.FIOtest);* OR in the bit
call[putMemState];
RBASE ← rbase[Arlink];
link ← Arlink;
breakpoint, RBASE ← rbase[defaultRegion];
* October 2, 1978 8:25 AM
* turn off memstate.FIOtest. FIOtest only runs if this bit is true.

FIOtestOff: subroutine;* set memState.loopOnError
saveReturn[Arlink];

call[getMemState];
rscr ← not(memState.FIOtest);
call[putMemState], t ← t AND (rscr);* remove the bit
RBASE ← rbase[Arlink];
link ← Arlink;
breakpoint, RBASE ← rbase[defaultRegion];
* August 19, 1978 2:25 AM
* compose value for mcr:
* enter with t = mcr bits
* exit w/ t = mcr bits OR (correct value for mcr.noWake)
* the correct value of mcr.noWake is the current value of memState.noWake

saOrMcrWake: subroutine;
saveReturnAndT[sRlink, sSubrScr];* note: using sRlink, sSubrScr
call[checkMemState], t ← memState.noWake;
skpif[alu=0], rscr ← t-t;
rscr ← mcr.noWake;
call[getsSubrScr];
t ← t OR (rscr);
returnUsing[sRlink];

* April 26, 1978 12:55 PM
* turn off loopOnError: for those tests that are so implemented, this bit would cause the
* test to enter a loop if an error occured, the loop reexecutes the sequence that caused
* the error.

loopOnErrorOff: subroutine;* set memState.loopOnError
saveReturn[Arlink];

call[getMemState];
rscr ← not (memState.loopOnError);
t ← t AND (rscr);* remove in the bit
call[putMemState];
returnUsing[Arlink];

* April 26, 1978 1:46 PM
loopErrorOccured: subroutine;* SET memState.loopErrorOccured
saveReturn[Arlink];* this bit remembers an error so that the
t ← memFlagsLocC;* appropriate test will continue to loop even
call[getIMLH];* tho the error may be intermittent
t ← t OR (memState.loopErrorOccured);
call[putMemState];
returnUsing[Arlink];

* January 5, 1979 12:07 AM
checkMemState: subroutine;
saveReturnAndT[Arlink, AsubrScr];
call[getMemState];
call[getAsubrScr], rscr ← t;
t ← t and (rscr);* mask the bits
returnAndBranch[Arlink, t];

* June 9, 1981 11:09 AM
iMemState: subroutine;
saveReturn[AsubrScr];
t← memFlagsLocC;
call[getIMLH];
sTestFlags←t;
returnUsing[AsubrScr];
getMemState: subroutine;
RBASE ← rbase[sTestFlags];
return, t ← sTestFlags, RBASE ← rbase[defaultRegion];
putMemState: subroutine;
saveReturnAndT[AsubrScr, rscr];
t ← rscr;
sTestFlags ← t;* KEEP SHADOW OF MEMSTATE IN RM
t ← memFlagsLocC;
call[putIMLH];
returnUsing[AsubrScr];

* January 5, 1979 11:54 AM
%
multi task storage diagnostic: Midas subroutine
This test presumes that the memory task runs and creates interference. The user is responsible for invoking xorTaskSim() to cause task simulation to be enabled.

unique ← 0;
sUseCacheColumn[getSmcrVictim[]];
* use only one column in cache if required.
WHILE true DO
-- This is the write portion, broken into two loops, one for each munch
FOR x IN [0..15] DO
va ← x + unique;
mem[va] ← va;
ENDLOOP;
unique ← unique + 1000B;* doesn’t change the row selected
FOR x IN [0..15] DO
va ← x + unique;
mem[va] ← va;
ENDLOOP;
-- This is the read/check portion, broken into two loops, one for each munch
unique ← unique - 1000B;
FOR x IN [0..15] DO
va ← x + unique;
IF mem[va] # va THEN ERROR;
ENDLOOP;
unique ← unique + 1000B;
FOR x IN [0..15] DO
va ← x + unique;
IF mem[va] # va THEN ERROR;
ENDLOOP;
unique ← (unique + 1000B) AND (7000B);
ENDLOOP;
%
top level;
sInterferenceTest:
call[sUseDefaultMcr];* Cause MCR to have "default" value.
call[enableConditionalTask];
q ← r0;* use this for "unique"
IsInterfereW1:
sva ← t-t;
cnt ← 17s;* once for each word in the munch
sInterfereWL1:* top of write loop
t ← (sva) + (q);* t ← sva + unique
STORE ← t, DBuf ← t;* mem[sva] ← sva + j
loopuntil[cnt=0&-1, sInterfereWL1], sva ← (sva) + 1;
IsInterfereW2:
t ← q;
t ← t + (cdMaxVa);* Increment unique by a number that won’t
q ← t;* change the row index
sva ← t-t;
cnt ← 17s;
sInterfereWL2:* top of write loop
t ← (sva) + (q);* t ← sva + unique
STORE ← t, DBuf ← t;* mem[sva] ← sva + j
loopuntil[cnt=0&-1, sInterfereWL2], sva ← (sva) + 1;

IsInterfereR1:
t ← q;
t ← t - (cdMaxVa);* decrement unique to its old value
q ← t;
sva ← t-t;
cnt ← 17s;* once for each word in the munch
sInterfereRL1:
t ← (sva) + (q);* t ← sva + unique
FETCH ← t;
rscr2 ← MD;* rscr2 ← mem[sva]
t # (rscr2);
skpif[alu=0];
sInterfereR1Err:
breakpoint;* mem[sva] # (sva+j)
loopuntil[cnt=0&-1, sInterfereRL1], sva ← (sva) + 1;

IsInterfereR2:
t ← q;
t ← t + (cdMaxVa);* increment unique to its second value
q ← t;
sva ← t-t;
cnt ← 17s;* once for each word in the munch
sInterfereRL2:
t ← (sva) + (q);* t ← sva + unique
FETCH ← t;
rscr2 ← MD;* rscr2 ← mem[sva]
t # (rscr2);
skpif[alu=0];
sInterfereR2Err:
breakpoint;* mem[sva] # (sva+j)
loopuntil[cnt=0&-1, sInterfereRL2], sva ← (sva) + 1;

t ← q;
t ← t + (cdMaxVa);* new value for unique
rscr ← 7c;* construct a mask that affects only
rscr ← lsh[rscr, skipCacheShift];* cacheA bits in address:
t ← t AND (rscr);* don’t let it change to much! This facilitates
q ← t;* more "collisions" in memory task
sva ← t-t;
branch[IsInterfereW1];
* September 25, 1978 5:14 PM
%
aHaltTask17
Set tpc[17]←7777C. We depend upon midas keeping a breakpoint in IM at this location. Thus if task 17 gets awakened, it will immediatel cause the machine to halt with a breakpoint.

Clobber rscr, rscr2, t
%
aHaltTask17: subroutine;
rscr2 ← link;
top level;
t ← 17c;
rscr ← 7777C;
subroutine;
link ← rscr;
top level;
LdTpc ← t;
taskingOn;
subroutine;
link ← rscr2;
return;

* October 3, 1978 5:13 PM
aChkPipeFlt: subroutine;* check pipe2 to see if there’s been a fault
saveReturn[Arlink];* IF NOT return w/ alu=0 fast branch condition
t← rscr2 ← not(Pipe2’[]);
rscr ← pipe2.nFaults;* IF faults THEN procsrn ← firstFault, return
t ← t AND (rscr);* with alu#0 fast branch condition
t ← t # (rscr);
branch[aChkPipeFltXit, ALU=0], rscr ← t;* nFaults=nFaults mask ==> no faults
rscr2 ← (rscr2) AND (pipe2.faultSrn);
PROCSRN ← rscr2;
rscr ← t;* t has (nFaults#mask) which must be #0 to be here
achkPipeFltXit:
returnAndBranch[Arlink, rscr];
top level;
memSubrsADone: branch[afterSubrs];