memA.mc (mem-ALL)February 1, 1980 8:52 PM%1title[memA];top level;* December 19, 1977 8:11 AM%ABOUT SOURCE FILE MAINTENANCEThe sources live on memAllSource.dm and diagnosticSubrs.dm. By loading those filesthe user acquires all the files necessary to assemble a new version of memAll:memA.cm// assemble and place memAll.mcmemA.mc// control filesee "insert" commands below for the subroutine files used by this programmemA.midas// set up midas contextmemAtoIfs.cm// make new:[ifs]memASource.dm,memAll.dmmemA.files// list of memAll files put in memASource.dmpreamble.mc// preamble code that that preceeds memAllpostamble.mc// postamble code that that follows memAllkernelalu.mc// defines alu ops for this diagnosticTo make a new version of memA:ftp maxc load memASource.dm, load diagnosticSubrs.dm@memA.cm// assemble and place the microcode@memAToIFS.cm// move the sources, .mb file to maxc%%February 1, 1980 8:52 PMadd restartDiagnostic label and code.June 25, 1979 2:10 PMresetIfu inside initMemTest.%afterSubrs:restartDiagnostic:t_1c;stkp_t;begin:call[initMemTest];;* now tpc[17] _ 7777C. midas puts a breakpoint in this address. anywakeups* are probably errors -- unless specifically managed by the code* call[aHaltTask17];call[disableConditionalTask];call[beginCtest];afterCtest:call[initMemTest];call[beginXtest];afterXtest:call[initMemTest];call[beginDtest];afterDtest:call[initMemTest];call[beginStest];afterStest:%call[initMemTest];insert[memPipeAndFaultA]call[initMemTest];goto[beginFIOtest];afterFIOtest:%afterTest:call[initMemTest];branch[done];initMemTest: subroutine;RBASE _ rbase[defaultRegion];rscr _link;top level;t _ r0 _ t-t, ifuReset;gp+>zN bAq a _ ^$X\p [:qf YN XU+ W+ TI R" + P + O* Ni +, M, +* K +* J +& IsH6HFE+#D} +% C@ A ?>% = ; :' 6p q 5p4^q3  1pq0 /hJ .*@ ,p*rq)4 'p &q%| $>p #q! p Hq  p qR \p q p qf )p q    p  3 E3]&memA.mc (mem-ALL)February 1, 1980 8:52 PM%2rm1 _ cm1;r1 _ t + 1;rhigh1 _ 100000C;r01 _ not(r10);t _ (r0)+1;stkp _ t;ProcSRN_r0;returnUsing[rscr];gp+>zNbAq a _^]K \Z Y X2"4memA.mc (mem-ALL)February 1, 1980 8:52 PM%3* November 29, 1977 10:31 AM* CODE for midas debuggingtop level;set[dbgTbls,100];l1: branch[l1],at[dbgTbls,0];l2:noop,at[dbgTbls,1];branch[l2],at[dbgTbls,2];l3:noop,at[dbgTbls,3];noop,at[dbgTbls,4];branch[l3],at[dbgTbls,5];l4:noop,at[dbgTbls,6];noop,at[dbgTbls,7];noop,at[dbgTbls,10];branch[l4],at[dbgTbls,11];l5:noop,at[dbgTbls,12];noop,at[dbgTbls,13];noop,at[dbgTbls,14];noop,at[dbgTbls,15];branch[l5],at[dbgTbls,16];l6:noop,at[dbgTbls,17];noop,at[dbgTbls,20];noop,at[dbgTbls,21];noop,at[dbgTbls,22];noop,at[dbgTbls,23];branch[l6],at[dbgTbls,24];branch[begin];END;gp+>zN bAq a_ ^ ]Kpq + \pq+ Z + Ypq+ XU+ W + Upq+ T+ S_+R" + Ppq+O+Ni+M,+K + Jpq+Is+H6+F+E+D} + B ?d =* *NmemMisc.mc (Miscellaneous)June 23, 1981 9:20 AM%1title[MemMisc];top level;* May 29, 1981 10:44 AM%ABOUT SOURCE FILE MAINTENANCEThe sources live on memMiscSource.dm and diagnosticSubrs.dm. By loadingthose files the user acquires all the files necessary to assemble a new version of memAll:memMisc.cm// assemble and place memAll.mcmemMisc.mc// control filesee "insert" commands below for the subroutine files used by this programmemMisc.midas// set up midas contextmemMisctoIfs.cm// make new: [ivy]memASource.dm,memAll.dmmemA.files// list of memAll files put in memASource.dmpreamble.mc// preamble code that that preceeds memAllpostamble.mc// postamble code that that follows memAllkernelalu.mc// defines alu ops for this diagnosticmemAtoMaxc.cm// temprorary expedient only for use when IFS downTo make a new version of memA:ftp maxc load memASource.dm, load diagnosticSubrs.dm@memMisc.cm// assemble and place the microcode@memAToIVY.cm// move the sources, .mb file to maxcJune 23, 1981 9:20 AMCall aProcShifterJune 17, 1981 8:55 AMAdd call to aMapTestMay 29, 1981 10:44 AMAdd restartDiagnostic label.%afterSubrs:restartDiagnostic:t_ 1c;StkP_ t;begin:call[initMemTest];call[aProcShifter];call[aMapTest];call[initMemTest];call[disableConditionalTask];goto[fioTest];afterFiotest:call[initMemTest];call[iMemState];* fioTest may clobber sTestFlags registercall[aPipeTestCtrl];afterTest:call[initMemTest];branch[done];initMemTest: subroutine;RBASE _ rbase[defaultRegion];rscr _link;top level;t _ r0 _ t-t;rm1 _ cm1;r1 _ t + 1;rhigh1 _ 100000C;r01 _ not(r10);t _ (r0)+1;stkp _ t;ProcSRN_r0;returnUsing[rscr];gp/@~N bAq a _ ^$X\p [:qc YZXU !W !TIR" !P!@O !,Ni !*M, !*K !&J !2 I GHFEQ +#D +% @? =< ;e:' 8 7Bp q 6p4q3 2Lpq1/.-V,* )p (`q'#+)% #jp "-q p q t7   ~ A  K  oC/XmemMisc.mc (Miscellaneous)June 23, 1981 9:20 AM%2* November 29, 1977 10:31 AM* CODE for midas debuggingtop level;set[dbgTbls,100];l1: branch[l1],at[dbgTbls,0];l2:noop,at[dbgTbls,1];branch[l2],at[dbgTbls,2];l3:noop,at[dbgTbls,3];noop,at[dbgTbls,4];branch[l3],at[dbgTbls,5];l4:noop,at[dbgTbls,6];noop,at[dbgTbls,7];noop,at[dbgTbls,10];branch[l4],at[dbgTbls,11];l5:noop,at[dbgTbls,12];noop,at[dbgTbls,13];noop,at[dbgTbls,14];noop,at[dbgTbls,15];branch[l5],at[dbgTbls,16];l6:noop,at[dbgTbls,17];noop,at[dbgTbls,20];noop,at[dbgTbls,21];noop,at[dbgTbls,22];noop,at[dbgTbls,23];branch[l6],at[dbgTbls,24];branch[begin];END;gp/@~N bAq a_ ^ ]Kpq + \pq+ Z + Ypq+ XU+ W + Upq+ T+ S_+R" + Ppq+O+Ni+M,+K + Jpq+Is+H6+F+E+D} + B ?j =* *NmemAfio.mcJune 9, 1981 10:19 AM%1title[memAfio];top level;beginFIOtest:* September 19, 1978 4:17 PM%*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ROUTINEDESCRIPTIONfioTestEntry point for fio testfioTestCodeCode that runs in test taskfioStestCode that tests storagefioTesterResetReset the fio jig, clobbers rmx7setFIOtesterSet fio jig for t = task num, rscr = subtaskfioSetFIOtesterSet fio jig for current subask, taskiaSubTaskInitialize subtask variableaNextSubTaskReturn the next subtask valueaGetSubTaskReturn current subtask valueaGetSTvaReturns effective address for a subtaskfioIMemInitialize Storae as required for fio testfioStorageWrite identity into storage (mem[va] _ va)%*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++%*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++May 16, 1979 1:49 PMAnother incompatibility: since rstk is wider, the old assumptions about which bits are unchangedby subtasking are incorrect.May 16, 1979 11:51 AMFix more model0/model1 incompatability problems: numberous mem subroutines save their return onthe stack & must not be called from non-emulator tasks.May 15, 1979 4:03 PMFix model0/model1 incompatability: stack no longer shared w/ RM means that the initialization codecan't write into RM via stkp manipulations.May 4, 1979 2:27 PMConstruct model1 version of code from model0 version.%*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++%*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++here's how it works:TIOA 300 stores what the devise believes is its task number and its subtask number.Top 4 bits task, next 2 subtask, next two magic (see below)When an IOfetch or IOstore is done by the task and subtask stored in TIOA 300,The device does the right thing BUT ONLY TWICE, i.e., it is two munches big.The microcode should first set TIOA 300 to the apprpriate task and subtask number,then do (in that task and subtask) TWO IOfetches, then two IOstores, and see ifwhat it got back is the same a s what it sent. All subtasks should be verified.Bits 06 and 07 of TIOA 300 should be ZERO for now. They are wire-oredto the parity bits of the FIN bus to inject ST parity errors.Reminders about the TestingThe emulator can have subtasks, too! First, for every task, make surethat membase and rbase get the appropriate bits or'd into them bythe current subtask:(things to do1) choose addresses other than 0..37B to make sure the subtask bitsarrive early enough for base register arithmetic2) check all the bits on the fast io bus3) don't forget to check rstk bits4) worry about what portion of te test to run during task switching andholds. verify w/ dough that taskswitching and holds will be ok.5) remember, for subtsks, RBase[2:3] _ RBase[2:3] OR Subtask[0:1].6) subtask[0:1] are or'd w/ memBase[2:3] during memory references.7) don't forget to exit with subtask = 08) Initialize the Base registers such that when the membase is zero and the subtask bits get or'd into bgp );N bAq a _p ^q ]KB@\+ @Zp-q@Yp +q@XUp+q@Wp +q@Up +q,@Tp+q$@S_p+q@R"p +q@Pp +q@Op+q'@Nip+q*@M,p +q* KB H6B F1E` D} C@1B_ @7 ?1>Jb = + ;1:5 9TB 5B 4^ 3 S 1; 0N /hL ,R +O *rP )4F '=1%| #E !A  H  C 0 R( " \G ? B )B ( 3f E3]memAfio.mcJune 9, 1981 10:19 AM%2membase, the resulting base register used by the processor will have a unique value in it that enablesthe test to make sure the subtask bits really got or'd in. In particular, we initialize as follows:BR[i] _ i*1000B. This results in a situation where "vm 0" for subtask i should REALLY be vm (i *10000B). This fact relates to which bits get or'd into memBase. bgp );N bAqf ad _a ^@ ](E3 (memAfio.mcJune 9, 1981 10:19 AM%3* June 5, 1981 4:16 PMFioControl: TYPE = MACHINE DEPENDENT RECORD[Task: TaskN,subTask: SubTaskN];TaskN: CARDINAL[0..17];subTaskN: CARDINAL[0..3];FOR task IN [0..17] DOFOR subTask IN subTaskN DOiMem[];NOTIFY[task, @fioTestCode];--awaken task to xqt the testENDLOOP;-- subTask loopENDLOOP;-- Task loop;ioReset[];OUTPUT _ fioTester;END;fioTestCode: PROCEDURE =BEGINFIOtestRbase[Task, subTask];FOR i IN Va DO mem[i] _ i;clearCacheFlags[];setFIOtester[task, subTask];IOFetch _ 0;IOFetch _ 20B;IOStore _ 0;IOStore _ 20B;ioReset[];-- could substitute setFIOtester[0,0];FOR i IN [0..37B] DOexpectAddr _ i + BITSHIFT[subTask, subTaskMemShift];IF mem[expect] #NOT(expectAddr)THEN ERROR;ENDLOOP;FOR i IN [0..37B] DOexpect _ i + BITSHIFT[subtask, subTaskMemShift]mem[expectAddr] _ i;ENDLOOP;setFIOtester[task, subTask];IOFetch _ 0;IOFetch _ 20B;IOStore _ 0C;IOStore _ 20B;ioReset[];FOR i IN [0..37] DOexpectAddr _ i + BITSHIFT[subTask, subTaskMemShift];IF mem[expectAddr] #NOT(expectAddr)THEN ERROR;ENDLOOP;ENDFIOtestRbase: PROCEDURE[Task: TaskN, subTask:subTaskN] =BEGIN-- subTask.0 gets or'd into RBASE.3 while subTask.1 gets or'd-- into subtask.1. If RBASE = 0, rstk = 0 then--subtask 0 refs effective RBASE[0]--subtask 1 refs effective RBASE[1]--subtask 2 refs effective RBASE[2]--subtask 3 refs effective RBASE[3]-- To test the fio tester we must set the first 20B RM locations to known-- values then, reference and store from RM while under the influence of-- the task/subtask mechanism of the fastio tester.ioReset[];FOR xRM in [0..77B] DO RM[xRM]_ xRM; ENDLOOP;setFIOtester[task, subTask];T _ R0;R0 _ 100C;ioReset[]; bgp );N bAq _,1^ 1]K1\ Z Y W1UTS_$R"1P O Ni M, Kp q J1Is1H61F1E1D} 1C@ 1B 1@ 1? &1= ;4:*9T165/4^3 1110 1/h 1.* 1, 1+ 1)4'4&.%| $> 8 H  = . 1! R1! 1! 1! I \H 3  f-   p 3 p 1 ]memAfio.mcJune 9, 1981 10:19 AM%4expect_ LSHIFT[subTask, 4];IF t # expect THEN ERROR;RBASE_ subTAsk;t_ r0;RBASE_ RBASE[defaultRegion];%*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ bgp );N aq _ ^ ]K \ ZB Yp,W.memAfio.mcJune 9, 1981 10:19 AM%5* June 9, 1981 10:19 AMmc[fioWaitC, 60]rvrel[rmx11, 11];rvrel[rmx12, 12];rvrel[rmx13, 13];rvrel[rmx14, 14];rvrel[rmx15, 15];rvrel[rmx16, 16];rvrel[rmx17, 17];fioTest:call[fioTesterReset];* perform full init incase we're runningcall[getMemState];t AND (memState.FIOtest);* see if our test is enabledbranch[FIOtestDone, ALU=0];noop;call[EcOn];* remove this when nolonger debugging fio jigcall[iSboard];* this test from Midas & interrupting at* arbitrary places.call[initBrs];fioIBrL:* init the brs for all the membases so thatcall[nextBr];* the BR for memBase i contains i left shiftedskpif[ALU#0];* by fio.subTaskBrShift (= i * 1000C)branch[fioIBrXit]; * Note: subtask 0 ors no bits into memBase,noop;* (placement 'cause of branch)call[setMbase];* subTask 1 or's 2 into memBase, subTask 2rscr2 _ t;* or's 4 into memBase and subTask3 or'snoop;* 6 into memBase. Thus, for subTask 3, va = 0rscr2 _ lsh[rscr2, fio.subTaskBrShift];* will really reference 6000B sincecall[setBr], rscr _ t-t;* we init base register 6 to contain 6000B.branch[fioIBrL];fioIBrXit:call[iapTestTask]; bgp );N bAq apq _+; ^+ \pq1Z(1XU1W1U1T1R"p -1Pq (1O1M, Jp'q+1Is .1H6 %1F+1E'1D}*1C@ '1B'-1@')z#1?+1>J ;p 1:qR 91;k.memAfio.mcJune 9, 1981 10:19 AM%6* June 9, 1981 10:04 AM%*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++This is the main loop. Each time the test passes through here, it increments the current test task.Ie., it proceeds to test the next task.%*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++call[fioIMem];fioTaskL:call[apNextTestTask];* top of task loopskpif[ALU#0];branch[fioTaskXit];noop;call[iaSubTask];%*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++This is the sub-loop. Each time the test passes through here, it increments the current test Sub-Task. Ie., it proceeds to test the next sub-task for the current task.%*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++fioSubTaskL:call[aNextSubTask];* top of subtask loopskpif[ALU#0];branch[fioSubTaskXit];noop;* for placement* initialize first 20B RM locations to be 0..20B BEWARE! This code clobbers RM locations* used by various subroutines! Use subroutines that change RBASE or store into different* regions with care.* Restore first 64K of storage.call[fioRestoreMem];* Awaken the task we're currently testingrscr _ fioTestLoc0C;rscr _ (rscr) + (fioTestLoc1C);call[apGetTestTask];* return t = next task to run = apNextTaskXtaskingOff;subroutine;link _ rscr;top level;LdTPC _ t;* TPC[apNextTaskX] _ fioTestLoctaskingOn;call[notifyTask];* awaken the code that really does the testfioEmuWait:noop;* give it time to awaken;branch[fioSubTaskL];fioSubTaskXit:branch[fioTaskL];fioTaskXit:branch[afterFIOtest]; bgp );N bAqp _qB ^d ]K' \B1Y XUpq1W1U 1T1S_1P NiB M,b KG JB H6p q@F+@E @D}@C@+ @X ?X >J ;@: 8)@5@4^@3 ++@1 @0 @/h @.* @, +@+ @*r++ )4p @'q+@& $>p q@# p q@H DJ#memAfio.mcJune 9, 1981 10:19 AM%7* June 5, 1981 4:27 PM%*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++This code runs as different tasks and exercises the fio test jig.The basic idea is to background RM[0..77] w/ [0..77B] ie., each rm locationwill contain its address. THEN proceed as follows:Set fio jig to select current subtaskSet RBASE to 0(Now, rm references are under influence of subtask logic)t_ rmx0 (rstk=0, rbase = current value or'd w/ subtask)rmx0_ 100c;Reset fio test jig (get rid of subtask influence)Check that t contains correct value for rmx0Check that correct rmx0 contains 100C.%*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++fioRmTest:set[xtask, 1];top level;taskingOn, at[fioTestLoc];call[fioTesterReset];* do it early for paranoiaRBASE _ rbase[defaultRegion];call[setMbase], t _ a0;* use BR0call[fioInitRM], t_a0;* background RM Region 0call[fioInitRM], t_1c;* background RM Region 1call[fioInitRM], t_2c;* background RM Region 2call[fioInitRM], t_3c;* background RM Region 3* Begin by checking the oring of bits into RBASE, RSTKcall[fioSetFIOtester];* Automatically sets tester w/ current* task, subtask value. When this subroutine returns, the subtask logic is enabled! BEWARE!!!RBASE _ 0s;t_rmx0;* read rmx0 and write it while under influence oftesterrmx0 _ 100c;call[fioTesterReset];* clear out the testerrscr _ t;* rscr = value from RM during influence of subtaskcall[aGetSubTask];q_t;RBASE_t;* save SubTask in Qt_ rmx0, RBASE_ rbase[defaultRegion];rscr2_ t;* rscr2 = "rmx0" for the rm regiont_ q;* selected by the subtask. Computet_ lsh[t, 4];* expected value = address of "rmx0"t # (rscr);skpif[ALU=0];fioRmRMX0Err:* value we read when performing t_rmx0error;* doesn't match what we expect. Subtask* logic didn't work????(rscr2)#(100c);* rscr2=value in RMX0 that should haveskpif[ALU=0];* been written w/ 100c while under thefioRMRMX0Err2:* the influence of the subtask logicerror; bgp );N bAq aB1_A ]KK \31Z%1Y 1XU91W71U 1T11R",1P& OB M,pq@K @J @Is@H6+@F@E+@C@+@B+@@+@?+ = 6@:+& 9T^@6 @4^+1 3 @1 @0+p@.*q+2@,@+@*r+@)4%@&+"@$>+#@# +$@! @ Hp +q&@ +(+@R+&@ +& p +q$@ 9ARmemAfio.mcJune 9, 1981 10:19 AM%8* June 9, 1981 9:40 AM%*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ fioStestTest the use of IOfetch, IOstore. This test depends upon the proper initialization of the baseregisters and of storage. For a given subtask, specific bits will be or'd into memBase, and thatcauses known base registers to be used during storage references. (The Default base register is 0.)Each base register that corresponds to a subtask has the unique value, subTaskNumber*10000B. Thus areference to vm 0 in subtask 0 will reference virtual location 0; however, a reference to vm 0 insubtask 2 will reference vm 20000, etc. This is how the test can check that fetches and stores from agiven subtask behave properly.There are 3 tests. The first test simply checks that IOfetch_0, IOfetch_20, IOstore_0, IOstore_20leaves storage correct. The second test writes into "subtask location 0" and "subtask location 20".Then it performs the two IOfetch, IOstore operations. Storage must be correct at the end of thisoperation (it must have the new, dirty values). The third, more complex test performs the two IOfetchoperations (which will need to take munches from the cache because they will be dirty), writes into"subtask location 0" and then performs two IOstores. The two IO stores should overwrite the datawritten into the cache by the processor.%*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++fioStest:call[aHaltTask17];* cause task 17 to hit brkpt if it runscall[fioSetFIOtester];%*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++This is the first test. It merely performs two IOfetches followed by a delay and two IOstores. Theprogram checks the data of both munches.%*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++fioSdoIO1:rscr _ 20c;* beware of subtask influence on RBASE!call[fioIOFetch2],t_a0;* IOfetch & store the first two munches of* memory, then check that storage is correct.t _ a0;IOstore _ t;IOstore _ rscr;FETCH _ rscr;B_MD;* wait for last fastio operation to completecall[fioTesterReset];* before we change our fastio device!* now we check that storage is correctt _ 37c;cnt _ t;* two munchescall[iSvaCtrl];fioScheck1L:noop;call[nextSva];* returns va in tskpif[ALU#0];branch[fioScheck1Xit];noop;* (placement 'cause of branch)call[aGetSTva], sva _ t;* t = current, subtask relative va; rtns t = subtask'sreal vaFETCH _ T;rscr _ MD;t # (rscr);* compare addr w/ valueskpif[ALU=0];fioSerr1:* current subtask should have referenced & notclobbered word in location terror;* mem[t] should be tloopUntil[CNT=0&-1, fioScheck1L];fioScheck1Xit:call[aChkPipeFlt];skpif[alu=0];fioSerr1b:* there was some sort of error left in the pipe!error;* examine the pipe using midas%*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++This is the second test. It checks to see that IOfetch gets dirty munches from the cache. It checksonly the dirty words in the munch.%*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++call[aGetSTva], t _ a0;* in subtask relative locations 0 and 20 storerscr _ not(t);* NOT( their contents) bgp );N bAq aB+_p ^q_ ]Ka \c Zd Ya XUf W Tb S_d R"` Pf Oc Nia M,( KB Jp@Isq+'@H6 EB D}d C@( BB @p @?q +p'@>Jq+* = -@:@9T @8@5 @4^+,@3 +% 0'@/h@.*+ @, +p @*rq@)4 +@' @&@%|+@$>+6 #@! @ @H +@ p+q. @R+@! p @q@\ p +q0@+ fB )e " B@ p+rq@ 3 + D E3];memAfio.mcJune 9, 1981 10:19 AM%9STORE_t, DBuf _ rscr;t _ t + (20c);rscr _ not(t);STORE _ t, DBuf _ rscr;call[fioSetFIOtester];* fetch and store the first two munches ofB _ MD;* hold as required for stores to completefioSdoIO2:rscr_20c;* beware of subtask influence on RBASE !call[fioIOFetch2], t_a0;* memory. check that our modified words are* still modified.t _ a0;IOstore _ t;IOstore _ rscr;FETCH _ rscr;* wait for last fastio op to finish before weB_MD;* modify our fastio device !call[fioTesterReset];call[aGetSTva], t _ a0;rscr2 _ (FETCH _ t);* save correct address in rscr2rscr _ (MD);t _ not(rscr2);* should have read not(address)t # (rscr);skpif[ALU=0];* fastio device should have gotten the dirtyfioSerr2a:* munch that was in the cache.error;* rscr2 = va, rscr = MD, t = expected valueSTORE_rscr2, DBuf_rscr2;* fix up our dirty & different locationrscr2 _ t _ (rscr2) + (20c);* check the next munch. save addr in rscr2FETCH _ t;rscr _ (MD);t _ not(t);* should have read not(address)t # (rscr);skpif[alu=0];fioSerr2b:error;* rscr2 = va, rscr=MD, t = expected valueSTORE_rscr2, DBuf_rscr2;* fix up our dirty & different locationcall[aChkPipeFlt];skpif[alu=0];fioSerr2c:* there was some sort of error left in the pipe!error;* examine the pipe using midas%*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++This is the third test. Note that munches w/ va0, va20 are dirty! This was caused by fioSDoIO2. TheIOfetches below will take data from the cache. The longWait that occurs after the two IOfetchesprevents the processor from writing into the munch for Va 0 before the fio jig has fetched the data.Remember it takes a while for the IOfetch to run to completion!%*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++fioSDoIO3:call[fioSetFIOtester];* dirty a munch after fio tester has fetched it.B _ MD;* hold as required for stores to completerscr_20c;* beware of subtask influence on RBASE !call[fioIOFetch2],t_a0;RBASE _ 0s;* set word "zero" to -1t _ cm1;rmx7 _ t-t;STORE_rmx7, DBuf _ t;* make word (subtask relative) 0 dirtyIOstore _ rmx7;t _ 20c;IOstore _ t;RBASE _ rbase[defaultRegion];FETCH _ t;* wait for last fastio op to finish before weB_MD;* modify our fastio device !call[FIOtesterReset]; bgp );N@bAq@_ @^ @]K@Z+*@Y+) XUp @Wq+p&@Uq++ T@R"@P @O@M, +-@K+@J@H6@F+@E @D}+@C@ @B +, @p +q@?++@>J+'@;+*@: @9T @8 +@6 @5 4^p @3 q+)@0+'@/h@.* ,p +q0@++ )4B 'e &` %|? #B p @Hq+0@ +)@+p&@q@ +@@ @\+ rq@@@f @)@ +-@ +@ p D]4memAfio.mcJune 9, 1981 10:19 AM%10call[aGetSTva], t_r0;FETCH _ t;rscr _ MD;t # (rscr);* see if mem[i] = iskpif[ALU=0];fioSerr3:* dirty data in cache interfered w/ storingerror;* proper data in fioTester. rscr = MD, t = expectedvalue,*t = address referenced.call[aChkPipeFlt];skpif[alu=0];fioSerr3b:* there was some sort of error left in the pipe!error;* examine the pipe using midasfioStestBlock:block;* RETURN TO EMULATOR! bgp );N@bAq@a @_ @^ +@]K \p+q+@Z+3 Y XU@@W@U Tp +q0@S_+ Op @Niq+p M B`memAfio.mcJune 9, 1981 10:19 AM%11* June 9, 1981 9:11 AM%*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++fioTesterResetsetFIOtesterfioSetFIOtesteriaSubTaskaNextSubTaskaGetSTvafioTesterResetUse rmx17 and reset (zero) FIO testersetFIOtesterUse rmx17, t, rscr & set FIO testerfioSetFIOtesterSet FIO tester according to current task, subtaskiaSubTaskInitialize aSubTaskXaNextSubTaskReturn next value of aSubTaskXaGetSubTaskReturn current value of aSubTaskXaGetSTvaReturn "real" va seen by current subtask%*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++fioTesterReset: subroutine;* use last rm location in this region* CLOBBERS RMX17!!!!rmx17 _ fioTestAddrC;TIOA _ rmx17;rmx17 _ (rmx17) - (rmx17);* wait 1 instruction after resetting deviceOUTPUT _ rmx17;* before returning -- so device has time toreturn, RBASE_ rbase[defaultRegion];* stop oring bits into membase, rstk, & rbase!setFIOtester: subroutine;* enter w/ t= task num, rscr = subtask num, both*right justified. CLOBBER T, RSCR, RSCR2q _ link;top level;t _ lsh[t, 14];* left justify 4 bit task field (20B-4)rscr _lsh[rscr, 12];* position 2 bit subtask next to task fieldt _ t or (rscr);rscr _ fioTestAddrC;TIOA _ rscr;OUTPUT _ t;* t = task, subt task control for fio testersubroutine;link _ q;return;fioSetFIOtester: subroutine;q _ link;* beware subtask RM addressing influencetop level;call[aGetSubTask];call[apGetTestTask], rscr _ t;* expand setFIOtester because once we've started subtasking, we can't access any return links we storeinto an rm location.t _ lsh[t, 14];* left justify 4 bit task field (20B-4)rscr _lsh[rscr, 12];* position 2 bit subtask next to task fieldt _ t or (rscr);rscr _ fioTestAddrC;TIOA _ rscr;OUTPUT _ t;* t = task, subt task control for fio testersubroutine;link _ q;return;iaSubTask: subroutine;t _ cm1;return, aSubTaskX _ t;aNextSubTask: subroutine;saveReturn[aRlink];RBASE _ rbase[aSubTaskX];t _ aSubTaskX _ (aSubTaskX) + 1;RBASE _ rbase[defaultRegion];rscr _ t - (maxSubTaskC);returnAndBranch[Arlink, rscr];aGetSubTask: subroutine;RBASE _ rbase[aSubTaskX];return, t _ aSubTaskX, RBASE _ rbase[defaultRegion]; bgp );N bAq aB)b_p *^ ) ]K+\*Z +fY XU q% Wp q# Upq1 Tpq S_p q R"p q! Ppq( OB Nip q +% M,p@Kq@J @Is++@H6++@F$+. D}p q +0 C@+(@B@@ @?+'@>J++@= @;@: @9T +,@8 @6@5 3 pq @1+(@0 @/h@.* +f *r@'+'@&++@%|@$>@# @! +,@ @H@  pq @R@ p q @\@@@@f@) p q @ p@ 34V E3]@memAfio.mcJune 9, 1981 10:19 AM%12aGetSTva: subroutine;* given t = va & aGetSubTask returns the currentsubtask number, construct the va (and return it in T) as seen by the subTask, also given fioTest'sinitialization of the base registers.saveReturnAndT[Arlink, rscr2];* save the va in rscr2call[aGetSubTask];* get the current subtTask number into Tnoop;* wait for rm to settle downt _ lsh[t, fio.subTaskMemShift];* position subtask number properlyt _ t OR (rscr2);* construct the proper vareturnUsing[Arlink]; bgp );N aq +0 _b ^%@]K+@\+(@Z+@Y+"@XU+@W UBTGmemAfio.mcJune 9, 1981 10:19 AM%13* May 4, 1979 2:30 PMfioIMem: subroutine;saveReturn[fioIMemRtn];call[setMbase], t_r0;call[fioIStorage];* do it twice to make sure clearing cache flagscall[fioIStorage];* doesn't leave dirty munches in cachecall[clearCacheFlags];* clear cache for first testwaitOnMapBusy[rscr2];call[sUseDefaultMcr];rscr2 _ t-t;call[setBr], rscr _ t-t;t _ not(FaultInfo'[]);* clear out any pipe faultsreturnUsing[fioIMemRtn];* June 9, 1981 9:40 AM%*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++fioIStorageInitialize memory to contain "self". Ie., mem[i] = i. This routine may be called twice in a rowto force all the data munches to storage (required if, for example, clearCacheFalgs gets calledimmediately after calling this routine).%*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++fioIStorage: subroutine;saveReturn[fioIStorageRtn];call[iSvaCtrl];fioIMemL:call[nextSva];skpif[alu#0];branch[fioIMemXit];branch[fioImemL], STORE _ t, DBuf _ t;fioIMemXit:returnUsing[fioIStorageRtn];fioRestoreMem: subroutine;t_ 177777C;cnt_t;loopUntil[CNT=0&-1,.], t_ (Store_t)-1, DBuf_t;return;fioIOFetch2: subroutine;* IOFetch_t, IOFetch_rscr, wait a whilerscr2_ link;top level;IOFetch_t;IOFetch_ rscr;t_ FioWaitC;call[longWait];returnUsing[rscr2];FIOtestDone:goto[afterFIOtest];fioInitRM: subroutine;* enter w/ t= RM region.* This subroutine initializes an RM region w/ its address. IE. RM 22 has 22, RM 3 has 3, etc.RBASE_t;* t=rbase.t_ lsh[t, 4];* Now t=high bits of RM address (remember that rstk isfour bits wide).rmx0 _ t; rmx1 _ t+1; rmx2 _ t+(2c); rmx3 _ t+(3c);rmx4 _ t+(4c); rmx5 _ t+(5c); rmx6 _ t+(6c); rmx7 _ t+(7c);rmx10 _t+(10c); rmx11 _ t+(11c);rmx12 _ t+(12c); rmx13 _ t+(13c);rmx14 _ t+(14c); rmx15 _ t+(15c);rmx16 _ t+(16c); rmx17 _ t+(17c);return, RBASE_ rbase[defaultRegion]; bgp );N bAq apq @_@^@]K+/@\+&@Z+@Y@XU@U @T@S_+@R" O NiB1M,p 1Kq` J_ Is( H6B Fp q @E@D} Bp@@q @? @>J@= & :p @9Tq 6p q @5 @4^@3 .@1 .*p q +'@, @+ @*r @)4 @' @&@%| #p q@!  p q + ^@R+ @ +6 @\3@;@@!@f!@)!@ $0 MD\DORADO:memChaosS.mcJune 25, 1979 11:33 PM%1title[memChaosS];%Table of Contents by order of occurencesChaosTestmain program for chaos testsetChaosCodepatch vartious locations in IMchaosSimInitStart up the task simulatorstartChaosStart up a pass of entire chaos testcheckErrorreturn ALU#0 if (loopOnError) and (errorOccured)chaosErrorlocation that handles chaos errors. when at breakpoint, t = "error number"iChaosScopeLoopremembers that an error has occured if loopOnError is true.%%September 14, 1979 3:40 PMmove sChaosChkAddrs into memSubrsCkhaos to help with micro STORAGE FULL problem. moveisChaosMem and iSavedHoldValue, too.June 25, 1979 11:33 PMfix incomplete edit to the loop control of sChaosTest (sChaosTop).June 25, 1979 10:48 PMCause startChaos to use getChaosTaskFreq, fix old, old bug in chaosError (called getSubrScrinstead of getsSubrScr), add comments.June 25, 1979 2:34 PMMake chaostest into subroutine called from memRWs.mcJune 25, 1979 8:34 AMChange placement locations to accommodate ifu entry points.April 18, 1979 11:36 AMMove iChaosCache, iChaosCode into memChaosSubrs.mcApril 18, 1979 10:06 AMRemove sMainChaosRtn, perform _FaultInfo[] before temporarily enabling the conditional task.February 28, 1979 11:07 AMMove actual test code into memChaosSubrs.mcJanuary 16, 1979 3:18 PMFix code init so that the random addresses selected occur in sChaosRow0, sChaosRow1. Renameconstants for clarity. Reset mcr after cache init so that it no longer restricts the cache to one rowonly.January 13, 1979 12:23 AMShorten maximum interval before Task simulator starts up. Max longWait delay set to 37B.%top level;gp# -?N aq _ ^p' ]K q \p q Zp q Yp q$ XUp q0 Wp qK Upq; T S_ R"PV O$ NiM,B KJ[ Is& H6F4 ED}; C@B2 @?\ >J= + ;:\ 9Tf 8 65X 4^ 1 f 0E37DORADO:memChaosS.mcJune 25, 1979 11:33 PM%2* January 16, 1979 3:22 PM%CHAOSMixed Timing and Memory-Op TestGoal: Test memory by generating random memory operations that are delayed by random amounts of time.The memory operations will be executed by two different tasks to increase the storage traffic andoccurence of odious boundary conditions.Generating the Environment and Memory-OpsThe test scans two different rows of the cache (8 munches). Random numbers determine which row, whichmunch, which word will be referenced. This requires one bit of row address, four bits of word address(in the munch), two bits of munch address (the "addressing" of munches is encoded in the address bitsoutside the cache), and one bit of shadow address. The shadow address bit provides an extra collectionof virtual addresses that map into the same two rows of the cache and consequently prevent the cachefrom containing all the munches of interest.Cache Row0 and Row1 are the two cache rows tested. The address bits that encode (columnNumber lshiftskipCacheShift) select columns zero through three respectively. The shadow bit, encoded by 4 lshiftskipCacheShift, provides enough address space to overflow the cache.Chaos uses the following structure:General InitializationBackground storage with known values (mem[va] _ va)Run Chaos testUse the random number generator to select the munches that will be present in thecache. Randomly set cflags.Dirty.Randomly select one of the four possible test patterns for task 0 and for task 17. Atest pattern is a pair of references separated by a delay (eg., fetch, delay, store, orstore, delay, store).Randomly select both the addresses referenced by task 0 and task 17, and the delaybetween those references.Run the test.Check that the interesting values are correctBegin againRandom Selection of Munches in the CacheThe test must know which addresses to make present in each column of the first two rows of the cache,and it needs the value for the cache flag dirty bit.Actually, the test needs only two random bits for cache initialization:one bit selects cflags.dirty (or not)The other bit selects the shadow bit.For code initialization four fields are used in each random number:wordX which selects which word in the munchrowX which selects which of the two possible rows will be selectedcolX which selects which column will be addresseddelay which selects the parameter to longWait which the code invokes after the first memoryreference during the test.%gp# -?N bAq a,h_p#^ \qd Za Y( Wp) Tqf S_f R"e Pf Od Ni, KQr J qMr Is q6 F#ED}3C@ BQ@!?T>JW= ;R:9T 8-6 4^p( 1qe 04 .*G,%+% *rC)4+'B&1%|[$> # cE3GDORADO:memChaosS.mcJune 25, 1979 11:33 PM%3* June 25, 1979 11:34 PM%codeRandThese constants and shifts describe the format applied to random numbers to decide which addresses thechaos test code will reference and to decide how long the delay will be after the first memoryreference.%mc[codeRand.store, 40];mc[codeRand.wordX, 17];mc[codeRand.rowX, 20];set[codeRand.colSize, 2];* mc[codeRand.colX, 300];set[codeRand.colShift, 6];set[codeRand.delaySize, 5];* mc[codeRand.delay, 17400]set[codeRand.delayShift, 10];mc[addr.shadowBit, lshift[4,skipCacheShift]];* va bit for shadow address* addrRand is a two bit nibble selected from the current two lsb of a random number.* the test uses addrRand to determine how to initialize each column of the two rows* in the cache.mc[addrRand.dirty, 1];* mask bit for address template.mc[addrRand.shadow, 2];* mask bit for address templatemc[instr.jcnLongJumpC, 0];mc[instr.ffMask,177400];set[instr.ffShift, 10];mc[instr.jcn4thru7C, 17];set[instr.notJcn4Thru7Shift, 4];* rt justify portion of an IM address not encoded byset[instr.notJcn4Thru7Size, 10];* the jcn[4:7] bits. also define size constant -- for ldfset[chaosTestBase, 7000]; mc[chaosTestBaseC, chaosTestBase];*++duplicated inmemSubrsChaos.mc+++++set[chaosDelayBase, 7400]; mc[chaosDelayBaseC, chaosDelayBase];*++duplicated inmemSubrsChaos.mc+++++set[chaosStage0Loc, 5400]; mc[chaosStage0locC, chaosStage0Loc];set[chaosStageSimLoc, 6000]; mc[chaosStageSimLocC, chaosStageSimLoc];set[chaosSimInitLoc, 6440];mc[chaosSimInitLoc0C, and[chaosSimInitLoc, 7400]];mc[chaosSimInitLoc1C, and[chaosSimInitLoc, 377]];sChaosTest:pushReturn[];checkMtest[memFlags.sChaos, sChaosDone];t _ flags.taskSim;* don't bother to execute unlesscall[checkFlags];* task simulating is enabledskpif[alu#0];branch[sChaosDone];* no tasking, no chaosnoop;call[isChaosMem];* init memory so that mem[va] = va.call[iSchaosX];sChaosTop:call[nextChaosX];* see if its time for another testskpif[alu#0];branch[sChaosTopXit];* check all sva for consistency, then exitnoop;call[iSavedHoldValue];* perform task simulator initcall[saveRandState];chaosScopeLoop:call[iChaosCache];* select cache addresses and flagsnoop;* for placement.call[isChaosCode];* init RM for chaos test, WRITE delay constantsChaosStart:call[startChaos];* run the test with both tasks runningcall[checkError];* see if an scope loop error occured in the pastskpif[alu=0];branch[ichaosScopeLoop];* perform scope loopgp# -?N bAq a_p ^qf ]K^ \ Z XUp q Wp q Up q Tpq# S_pq R"pq# Ppq Nip q+ KT JS Is H6p q Fpq D}pq C@p q @p q ?pq >Jpq#4 = pq#9 :p q p q; 9T 8p q pq; 6 4^p q pq 3 pq pq 1pq0pq/hpq +p *rq )4('+&+%| $>+# +#H  p q+" R+*+\ pq+"+f+. )p  q+& +0 p  3+ E3]^DORADO:memChaosS.mcJune 25, 1979 11:33 PM%4branch[sChaosTop];sChaosTopXit:call[sChaosChkAddrs];sChaosDone:call[disableConditionalTask];returnP[];gp# -?NbAq _p ^q ]Kp \qZ X2$1DORADO:memChaosS.mcJune 25, 1979 11:33 PM%5* January 8, 1979 11:00 PM%Set Chaos CodePatch the delay constant and staging locations in the chaos test as required by the current randomnumber values. When the test executes, a branch must be made to the proper location in IM to performthe pair of memory ops and the intervening delay. setChaosCode initializes the jump to that test andit initializes the B-mux constant that provides the delay between the two operations.Enter with T = 0 or 4 (task 0 or task sim, an offset into some tables), rscr2 = the last random numberused, and sChaosRandV the current random number in use. The concatenation of the two store bits fromthese two pseudo random numbers provides an index into a table of IM locations. These locations pointto the starting point of the proper test in the chaosTestBase table, and point to the address of theB-mux constant in the chaosDelayBase table. The contents of these tables are actual instructions, soaddressing them is a matter of adding the constructed constant to a base value. The offset in Taddress the simTask locations. For example:ChaosTestBase + 000beginning of fetch-fetch test+ 001beginning of fetch-store test+ 010beginning of store-fetch test+ 011begining of store-store test+ 111beginning of fetch-fetch (sim task)+ 101beginning of fetch-store (sim task)+ 110beginning of store-fetch (sim task)+ 111beginning of store-store (sim task)setChaosCode: PROCEDURE[taskOffset, oldRandomV, currentRandomV] =BEGINindex _ IF oldRandomV.store THEN 2 ELSE 0;index _ index +IF currentRandomV.store THEN 1 ELSE 0;index _ index + offset;gotoAddr _ index + ChaosTestBase;gotoInstrRightHalf _ 120B;-- jc = 1, jn[0:1] = 01gotoInstrRightHalf _ gotoInstrRightHalf + (gotoLoc AND 17B);-- jn[2:5]gotoLoc _ [ (gotoLoc AND (NOT 17B) -- isolate remaining bits--) LSHIFT 4];-- position forFF constantgotoInstrRightHalf _ gotoInstrRightHalf + gotoLoc;IF index = 0 THEN IMRH[chaosStage0Loc] _ gotoInstrRightHalfELSE IMRH[chaosStageSimLoc] _ gotoInstrRightHalf;ffConstant _ currentRandomV AND ffCountstantMask;-- isolate delay fieldffConstant _ ffConstant LSHIFT ffConstantShift;-- position for micro instructioncodeLoc _ ChaosDelayTable + offset;instr _ IMRH[codeLoc];instr _ instr ANd (not ffConstantMask);-- isolate rest of instructioninstr _ instr OR ffConstant;-- add our new ff constantIMRH[codeLoc] _ ffConstant;END;%gp# -?N bAq a)b_p ^qb ]Kd \2p q& ZU XUf Wd Ue Td S_d R"_ P+ O+Ni+M,+K+J+#Is+#H6+#F+# D}p q4C@B*@5?= !;+:<: 9TKEJ8 634^;3 1012/h/2!,#+*r'+)4+'& %| N $E3CDORADO:memChaosS.mcJune 25, 1979 11:33 PM%6* January 16, 1979 3:48 PMsetChaosCode: subroutine;* T = task offset (0=> task 0, 4 =>simTask)*rscr2 = old random number, sChaosRandV = current random numbersaveReturnAndT[sRlink, sSubrScr];(rscr2) AND (codeRand.store);* see if store bit is setskpif[alu=0], t _ t-t;t _ 2c;(sChaosRandV) AND (codeRand.store);* see if store bit is setskpif[alu=0], rscr _ t;* copy current value into rscrrscr _ t + 1;* rscr = indexcall[getSsubrScr];* restore task offset into Tt _ t + (rscr);* t _ offset + indexsSubrScr _ t;* save complete index in sSubrScrsetChaosCodeJump:%The format for a long jump is that jcn[4:7] contains the low 4 bits of the target address, andFF[0:7] contains the remaining 8 bits of the target address. In the code below, instr.jcnLongJumpC isa constant that properly sets the other bits of jcn.%rscr _ (instr.jcnLongJumpC);* encode long jumpt _ rscr2 _ t + (chaosTestBaseC);* generate address to jump tot _ t AND (instr.jcn4thru7C);* add low order bits of addressrscr _ (rscr) + t;%Now finish constructing the long jump to the target address. First right justify the remainingbits of the address (ie., those bits not encoded in jcn[4:7]), then left shift those bits into the FFfield of the microinstruction.%rscr2 _ ldf[rscr2, instr.notJcn4Thru7size, instr.notJcn4Thru7Shift];rscr2 _ lsh[rscr2, instr.ffShift];t _ rscr2;rscr _ (rscr) + t;* this is right half of the micro instructioncall[getSsubrScr];* choose between task0 stage location andt _ t AND (4C);* simulator stage locationskpif[alu=0], t _ chaosStage0LocC;t _ chaosStageSimLocC;call[putIMRH];* Write the GOTO[properTest]setChaosCodeConstant:call[getSsubrScr];* get address of instruction whose B-muxt _ t + (chaosDelayBaseC);* constant (FF) must be initializedcall[getIMRH];rscr2 _ not(instr.ffMask);* remove the current FF bitst _ t and (rscr2);rscr _ t;t _ ldf[sChaosRandV, codeRand.delaySize, codeRand.delayShift];* rt. justify delayt _ lsh[t, instr.ffShift];* position delay for ff constantrscr _ t OR (rscr);* rscr = new instructioncall[getSsubrScr];t _ t + (ChaosDelayBaseC);call[putIMRH];* write the delay constantreturnUsing[sRlink];gp# -?N bAq _p q ++ ^>]K!Z+YXUW#+U+T + R"+P+O +! M,p KqJ^ Isf H64 FE+D}!+C@+B ?>J_ = e ; :9TD8"6 5+-3 +)1+0"/h, + *rp)4q+('+#& $>+#!H>: ++R +p 9E3RDORADO:memChaosS.mcJune 25, 1979 11:33 PM%7* April 24, 1978 3:01 PM%Chaos Simulator Initialization CodeSet Q to zero upon entry (the sim code sets q to 1 when it is done). ChaosSimStageit has beeninitialized with a long branch to the proper test sequence by setChaosCode.Task 0 maintains responsibility for checking the consistency of the results.This code does not "return" to caller because chaosSimStageIt has been patched witha branch to test code that explicitly (via goto) returns to the chaos checking code.%top level;chaosSimInit:t _ q,at[chaosSimInitLoc];* hold value passed in QRBASE _ rbase[defaultRegion];q _ r0;rscr _ t-t;* zero the current membasecall[setBR], rscr2 _ t-t;RBASE _ rbase[rm10];* initialize rbase and branch to the testtop level;noop;* allow pc to get off pagechaosSimStageit:noop,at[chaosStageSimLoc];* patched by setChaosCode !!error;* should never get here% should branch to code that looks like,hold _ t, block;branch[chaosSimXit];%set[xtask,1];chaosSimXit:t _ 0c;t _ t + 1, hold&tasksim _ t;noop;* 1st instr after hold&tasksim_ doesnt countq _ t, block;branch[.], breakpoint;* should never get hereset[xtask,0];gp# -?N bAq a"T_p# ^q] ]K>p q \L Y.pq XUT WU Tp S_q+:POM, +KIs+)H6 F+ D}pC@q+: p qB+ @(?>J=  ;: 9Tp 8q65+,4^ 3 +1  0A7DORADO:memChaosS.mcJune 25, 1979 11:33 PM%8* June 25, 1979 10:49 PM%Start Chaos CodeStart up the chaos simulator and proceed with the current memory test. This code checks that all therelevant memory locations are correct.%knowRbase[defaultRegion];startChaos: subroutine;pushReturn[];call[setMCR], t _ r0;rscr _ t-t;* zero the current membasecall[setBR], rscr2 _ t-t;call[getChaosTaskFreq];* construct hold valueq_t;taskingOn;t _ (chaosSimInitLoc0C);t _ t + (chaosSimInitLoc1C);subroutine;link _ t;top level;ldTPC _ simTaskLevelC;notify[simTaskLevel];noop;RBASE _ rbase[rm00];chaos0Stageit:goto[.+1],at[chaosStage0Loc];error;chaosAfterChk0:* arrive here via explicit goto from task0 test.* Perform an exhaustive test of RM and storage valuest _ q;* see if sim task is donebranch[., alu=0], t _ q;t _ rm01;t _ t # (rm00);skpif[alu=0];sChaosErr01:* rm00 # rm01branch[chaosError], t _ 1c;fetch _ rm00;t _ md;rm01 _ t;t _ t # (rm00);skpif[alu=0];sChaosErr02:* mem[rm00] # rm00branch[chaosError], t _ 2c;* rm01 = MDt _ rm03;t _ t # (rm02);skpif[alu=0];sChaosErr03:* rm02 # rm03branch[chaosError], t _ 3c;FETCH _ rm02;rm03 _ MD;t _ rm03;t _ t # (rm02);skpif[alu=0];sChaosErr04:* mem[rm02] # rm02branch[chaosError], t _ 4c;* rm03 = MD* TEST Chaos SimTask registers and locationst _ rm11;t _ t # (rm10);skpif[alu=0];sChaosErr11:* rm10 # rm11gp# -?N bAq a(_p ]Kqd \& ZX Wp q VD SQN +PM+LXI HGbF$ DC BlA.?> =vp <8q +: 8p+q0 7B56+42L1/ .p +q -V* )(`'#% $p +q#j+  t 7p +q ~ A  Kp +q + ,U  p +q 8 yC]DORADO:memChaosS.mcJune 25, 1979 11:33 PM%9branch[chaosError], t _ 5c;fetch _ rm10;t _ md;rm01 _ t;t _ t # (rm10);skpif[alu=0];sChaosErr12:* mem[rm10] # rm10branch[chaosError], t _ 6c;* rm11 = MD, t = bad bitst _ rm13;t _ t # (rm12);skpif[alu=0];sChaosErr13:* rm02 # rm13branch[chaosError], t _ 7c;FETCH _ rm12;rm13 _ MD;t _ rm13;t _ t # (rm12);skpif[alu=0];sChaosErr14:* mem[rm12] # rm12branch[chaosError], t _ 10c;* rm13 = MDreturnP[];gp# -?NbAq_ ^]K\Z Yp +qXU+UTS_ R"p +q PNi M, KJIs H6p +qF+ E  DZ0#qDORADO:memChaosS.mcJune 25, 1979 11:33 PM%10* April 27, 1978 3:19 PM%Chaos Error: breakpoint or scope loop%knowRbase[defaultRegion];checkError: subroutine;* return alu#0 if (loopOnError) AND (error occured)saveReturn[Srlink];t _ memState.loopOnError;* see if we carecall[checkMemState];skpif[alu#0];* presume no errorsbranch[checkErrorRtn], t _ r0;* don't loop so return w/ alu=0t _ memState.loopErrorOccured;call[checkMemState];skpif[alu=0], t _ r0;t _ (r0) + 1;checkErrorRtn:returnAndBranch[Srlink, t];top level;chaosError:RBASE _ rbase[defaultRegion];sSubrScr _ t;* remember error valuet _ (memState.loopOnError);call[checkMemState];skpif[alu=0];branch[chaosErr1];* do the scope loopcall[getsSubrScr];* get the error number into t. See code afterstartChaoserror;* to decode significance of error number.chaosErr1:call[loopErrorOccured];* now fall thru to iChaosScopeLoopiChaosScopeLoop:call[loopErrorOccured];* remember that err occured for future ref.call[restoreRandState];branch[chaosScopeLoop];set[xtask,0];knowRbase[defaultRegion];gp# -?N bAq a!^p% \q[ Zfp q +3Y)W+VUp +T3+RQPzO= Mp LqJG I p GqF +DBA @[+=+. < ;e+) 8p 7q+" 51p3q++21y. - ,`B-;DORADO: MemDefs.mcJune 23, 1981 8:59 AM%1%June 23, 1981 8:59 AMAdd memState.aProcShiftJune 15, 1981 11:29 AMRemove TaskContinueLoc from MemA stuff; make Fiotest default false, add aMapTestJune 9, 1981 10:14 AMProvide for default initialization of memState (lh of memFlags word)June 2, 1981 10:22 AMRemoving more old defns associated w/ memMisc: memPipeAndFaultA.June 1, 1981 2:23 PMRemove old defns associated with memMisc: memPipeAndFaultAFebruary 9, 1981 9:55 AMMove defn. of xPageXLo, xEndPageLo, xPageXHi, xEndPageHi to rbase where they fit.February 5, 1981 5:59 PMRename brx to cBrx to accommodate d1lang.August 13, 1979 5:55 PMFix discrepancy between number of pseudorandom number patterns for cache data test and for storagetest.August 13, 1979 4:48 PMAdd patterns 3-4 for cache data test.June 28, 1979 11:13 AMChange memFlags location, again, to accommodate ifu entry point locations.June 26, 1979 4:39 PMAdd SBrHi and SbrLoJune 25, 1979 8:26 AMChange memSimInitLoc to accommodate changes in postamble locations due to changes for ifu entrypoint locations.June 17, 1979 4:51 PMChange value of memFlagsLoc to accommodate ifu entry point locations.May 7, 1979 2:13 PMChange config definitions to accommodate Rev C's encoding for icType and the encoding formapDirtyb, MapParityJanuary 25, 1979 5:38 PMAdd pipe2.nFaultsSize.January 25, 1979 11:06 AMRemove simTaskLevel definition since taskSimulator now awakens 12B.January 16, 1979 2:22 PMadd memState.mcrVictim, memState.mcrVictimShift (real sMCRvictim lives in memstate) -- code maychange sMCRvictim at will, yet the value used by the tests a whole won't be clobbered.January 13, 1979 12:47 AMadd sChaosRow0, sChaosRow1January 12, 1979 4:59 PMremove sGetConfigRtn, sCountModulesRtn, sGetICtypeRtn. add xMapBase. fix sPat3EndCJanuary 11, 1979 9:57 AMadd memFlags.sFlush%TITLE[memDefs];%January 25, 1979 5:39 PM%* MCR values (not Bmux constants)set[mcr.mcrVshift, 13];* left shift "column" for position in mcrset[mcr.mcrNVshift, 11];* left shift "column" for position in mcr* MCR bmux constantsmc[mcr.dPipeVa,b0];* read load pipeVA w/ cache victimmc[mcr.fdMiss,b1];* force dirty miss references ==>store victimmc[mcr.useMcrV,b2];* use mcrV as victim and mcrNV as next vicitm in cache missesmc[mcr.disBr, b7];* disable base registersmc[mcr.disCF, b8];* disable cache flagsmc[mcr.disHold, b9];* disable holdmc[mcr.noRef, b10];* don't make memory referencemc[mcr.noRefHold, b9,b10];* disable hold and memory referencesmc[mcr.WMiss, b13];* wakeup fault task after every missmc[mcr.noSEwake, b14];* no single error wakeupsmc[mcr.noWake, b15];* never awaken fault taskgp,h=N bAq a _ ^ ]KP \ ZD Y XU@ W U: T S_Q R" P) O Nib M, K J% Is H6J F E D} C@` B @ ?E >J = Y ; : 9T 8 6C 5 4^1rq* 3 V 1 / - ,S *r )4 ' %| $> # Hp q pq#)p q+) Rpqpq#"pq#-\pq#=pq#pq#pq# fpq#)pq +$ pq#$ pq# ppq# R D]ADORADO: MemDefs.mcJune 23, 1981 8:59 AM%2* PIPE2 B mux constants and Valuesmc[pipe2.refType, b0,b1];* type of referenceset[pipe2.refTypeShift, 16];mc[pipe2.subtask, b2,b3];* subtask that made referenceset[pipe2.subTaskShift, 14];mc[pipe2.task, b4,b5,b6,b7];* task that made referenceset[pipe2.taskShift, 10];mc[pipe2.emuFault, b8];* emulator made a faultset[pipe2.emuFaultShift, 7];mc[pipe2.nFaults, b9,b10,b11];* nFaults-1 at time pipe readset[pipe2.nFaultsSize, 4];set[pipe2.nFaultsShift, 4];mc[pipe2.faultSrn, b12,b13,b14,b15];* SRN of first fault* PIPE3 (_Map) B mux constantsmc[pipe3.realPageMask,177777];* PIPE4 (_Errors) B mux constants and Valuesmc[pipe4.ref, b0];mc[pipe4.Mfault, b1];mc[pipe4.wProtect, b2];mc[pipe4.dirty, b3];set[pipe4.dirtyShift, 14]mc[pipe4.memErr, b4];mc[pipe4.ecFault, b5];mc[pipe4.quadWordMask,1400];set[pipe4.quadWordShift, 10];mc[pipe4.syndrome,377];mc[pipe4.syndromeWdX, b12,b13,b14];set[pipe4.syndromeWdXShift, 1];mc[pipe4.sexChange0, b1,b4,b5];mc[pipe4.sexChange1, b12,b13,b14];* PIPE5 B mux Constants and valuesmc[pipe5.colBit1,b7];* bit 0 of column fieldmc[pipe5.colBit0,b6];* bit 0 (left to right) of column fieldset[pipe5.colShift, 10];* amt to shift "col" to allign w/ PIPE5 fieldmc[pipe5.MbufBusy,b0];* map buf busymc[pipe5.flushStore, b1];mc[pipe5.tag, b2];* cache tag bitmc[pipe5.store, b4];* store' bitmc[pipe5.ifuRef, b5];* ifu referencemc[pipe5.dirty, b8];* cache entry is dirtymc[pipe5.vacant, b9];* cache entry is vacantmc[pipe5.wProtect, b10];* cache entry write protectedmc[pipe5.beingLoaded, b11];* cache entry being loadedmc[pipe5.flagsMask, 360];* mask to isolate cache flags* FaultINFO B mux constants and Valuesmc[faultInfo.Asrn, b4,b5,b6,b7];* current Asrn used by hardwareset[faultInfo.AsrnShift, 10];mc[faultInfo.emuFault, b8];* emulator made a faultset[faultInfo.emuFaultShift,7];mc[faultInfo.nFaults, b9,b10,b11];* nFaults at time pipe readset[faultInfo.nFaultsShift, 4];mc[faultInfo.faultSRN, b12,b13,b14,b15];* SRN of first faultmc[faultInfo.faultMask, 377];* B8 thru B15gp,h=N bA"_qpq+^]Kpq+\Zpq+YXUpq#WUpq +TS_R"pq3 NipKqp q Isp*FqpqEpqD}pqC@pqB@pq?pq>Jp q= ;pq:p q 9T pq6p q 5p q 3 p0qpq#/hpq#', pq+-*rpq# )4p q'pq#&pq# %|pq#$>pq##pq#!pq+ p q+Hpq+ p&Rq pq+ pq+\ pq + pq3f pq+  C>;WRDORADO: MemDefs.mcJune 23, 1981 8:59 AM%3* CFLAGS constants and valuesmc[cflags.dirty, b8];mc[cflags.vacant, b9];mc[cflags.wProtect, b10];mc[cflags.beingLoaded, b11];mc[cflags.mask, b8,b9,b10,b11];set[cflags.lshift, 4];*May 7, 1979 2:14 PMMEMORY CONFIGURATION definitionsset[config.modSZ, 4];mc[config.modSZC, config.modSZ];set[config.modPOS,4];set[config.icTypeSZ, 2];set[config.icTypePOS, 2];mc[config.m0, b8];mc[config.m1, b9];mc[config.m2, b10];mc[config.m3, b11];mc[config.mapDirtyb, b14];mc[config.mapParity, b15];mc[config.Asrn, b4,b5,b6,b7];* current Asrn value used by hardwareset[config.AsrnShift, 10];* June 23, 1981 9:02 AMmemFLAGS bit definitions: control which tests executeset[memFlagsLoc, 310];mc[memFlagsLocC, memFlagsLoc];mc[memFlags.cPipeVA, b0];* check pipe va bitsmc[memFlags.cBR, b1];* check base register bitsmc[memFlags.cAmem, b2];* check cache Amemory bitsmc[memFlags.cComprs, b3];* check cache comparatorsmc[memFlags.cFlags, b4];* check cache addressing mechanismmc[memFlags.cAddr, b5];* check cache addressing mechanismmc[memFlags.Cboard, b0, b1, b2, b3, b4, b5];mc[memFlags.mRW, b6];* check Map read/writemc[memFlags.mAddr, b7];* check map addressingmc[memFlags.Xboard, b6,b7];mc[memFlags.dRW, b8];* check cache Data bits (read/write)mc[memFlags.dAddr, b9];* check cache Data addressingmc[memFlags.dHold, b10];* check HOLD logicmc[memFlags.Dboard, b8,b9,b10];mc[memFlags.sRW, b11];* check Storage bits (read/write)mc[memFlags.sFlush, b12];* check Flush_mc[memFlags.sAddr, b13];* check storage addressing mechanismmc[memFlags.sChaos, b14];* multi task, multi op interference testmc[memFlags.Sboard, b11,b12,b13, b14];mc[memFlags.aPipeAndFault, b15];* test pipe and fault mechanismmc[memFlags.Aboard, b15];mc[memFlags.default0, memFlags.Cboard, memFlags.Xboard];mc[memFlags.default1, memFlags.Dboard, memFlags.Sboard];set[defaultMemFlags, ADD[ memFlags.default0!, memFlags.default1! ] ];* MEMSTATE definitions: these bits live in LEFT HALF of memFlags wordmc[memState.usingOneColumn, b0];* use only one column of cachemc[memState.mcrVictim, b1,b2,b3];* column to use if usingOneColumnset[memState.mcrVictimShift, 14];* position a column number to mcrVictimmc[memState.useTestSyn, b15];* turn on error correctionmc[memState.loopOnError, b14];* loop on occurence of errorsmc[memState.loopErrorOccured, b13];* at least one error has occuredmc[memState.noWake, b12];* value of mcr.noWake bitmc[memState.PipeTest, b11];mc[memState.FIOtest, b10];mc[memState.aMapTest, b7];mc[memState.aProcShift, b6];gp,h=N aqp^q pq]K pq\ pqZ p qY pqXU pq U#pS_q pq#R" pqP pqO pqNi pqM, pqK pqJ pqIs pqH6 pqF pq+%E pq C@#pq@p q#>J pq+= pq#; pq#: pq+9T pq+"8 pq#"6 pq4^ pq#3 pq#1 pq/h pq#$.* pq#, pq++ pq )4 pq#!' pq+ & pq+$%| pq+($> pq! p q+ pq pq$ pq$pq2 pq/ p q+\ pq +! p q+' p q+ p q+f pq+) pq+ pq pq p pq 3 p q ;]DORADO: MemDefs.mcJune 23, 1981 8:59 AM%4mc[memState.noErrs, b9];* don't look for storage errorsset[defaultMemFlagsLeft, ADD[memState.aMapTest!, memState.PipeTest!,memState.aProcShift!]];* Set defaultFlagsP to notify the task simulation mechanism not to run unless* flags.conditionalOK is true.sp[defaultFlagsP, flags.conditionalP];gp,h=NbAq pq+_D ^ \p q: ZXUp qN U6[T6DORADO: MemDefs.mcJune 23, 1981 8:59 AM%5* June 26, 1979 4:38 PM* MEMORY oriented MACROS, and Memory RM definitionsm[waitOnMapBusy, ilc[(#1 _ pipe5)]ilc[(#1 _ (#1) and (pipe5.MbufBusy))]ilc[(dblbranch[.+1, .-2, alu=0])]];m[shortMemWait,ilc[(#1 _ cnt)]ilc[(t _ 12c)]ilc[(call[longWait])]ilc[(cnt _ #1)]];* save cnt, call[longWait],t_12c; restore cnt* Check to see if memory test is enabled* eg., checkMtest[memFlags.cAmem, cAmemDone];m[checkMtest,ilc[(t _ #1)]ilc[(call[checkMemFlags])]ilc[(dblbranch[.+1, .+2, alu=0])]ilc[(branch[#2])]ilc[(noop)]];* RM definitions FOR CACHE tests: MemCRM[col,IP[RHIGH1]];* use va from cachedata = r01rm[flagsV, IP[RM1]];* RM definitions for CACHE DATA tests: MemD* USE "col" from CACHE TEST definitionRM[va, IP[r01]];RM[CData, IP[RM1]];* RM definitions FOR MAP tests: MemXRM[Mrow, IP[RHIGH1]];RM[Mcol, IP[R01]]1;RM[MpatHi, IP[R10]];RM[MpatLow, IP[RM1]];RM[mcrBits, IP[R1]];* RM definitions for STORAGE tests: MemSRM[sva, IP[va]];RM[sva1, IP[va]];* use "col" from memC definitionsRM[sChaosRandV, IP[RM1]];* hold current random number for chaos testRM[Sva2, IP[r10]];RM[sExpected, IP[r10]];* pattern we expected back from memoryRM[Swait, IP[RM1]];RM[Smcr1, IP[stackPAddr]];RM[Smcr2, IP[rscr3]];RM[SBrHi, IP[stackPTopBits]];RM[SBrLo, IP[klink]];RM[stsyn, IP[rscr4]];RM[Sdata1, IP[hack0]];RM[Sdata2, IP[hack1]];RM[Sxor, IP[hack2]];* RM definitions for All of memoryRM[aUseSrn, IP[R01]];* presume svagp,h=N bAq _3 ]Kp q\%Z!Y Wp qUT S_R"P- M,( K- Isp qH6 FE!D}C@ B >J&;pq :9Tpq 6+4^&3 pq 1pq .*$+pq *rpq )4pq 'pq &pq $>(!pq  pq H! p q ++pq pq #&Rpq pqpq pq\pq pq pq pq fpq " ppq  3  <]DORADO: MemDefs.mcJune 23, 1981 8:59 AM%6gp,h=N* b DORADO: MemDefs.mcJune 23, 1981 8:59 AM%7* MEMC Definitions* February 5, 1981 5:59 PM Cache Subroutines: Loop controlrmRegion[rmForLoops];knowRbase[rmForLoops];rv[cBrx,0];* base register indexrv[patX,0];* pattern indexrv[rowx,0];* row indexrv[colx,0];* column indexrv[col2x,0];* column indexrv[curPattern,0];* current patternrv[subrScr,0];* subroutines' scratch regrv[rlink,0];* return linkrv[flagsVal,0];* current flags valuerv[cva, 0];* copy of varv[cflagsv, 0];* copy of a flags valuerv[cBrCacheABits, 0];* copy of "CacheA bits in BR" value*rv[cXX,0];* 4 unused rm locations*mc[BrHiEndC, 1000];* maximum value+1 for br himc[BrHiEndC, 400];* maximum value+1 for br himc[brEndC, 40];* maximum br index +1mc[colEndC, 4];* maximum column index +1mc[rowEndC,100];* maximum row index +1mc[pat1EndC, 17];* [0..pat1EndC)mc[pat2EndC, 36];* [pat1EndC..pat2EndC)mc[pat3EndC, 37];* [pat2EndC..pat3EndC)mc[lastPatC, 37];* no more patternsmc[flagsEndC,400];* flagsV_20B,flagsV+20B UNTIL 400B* flags are 4 bits wide, left shifted from the right by 4set[cacheShift, 4];set[nBitsInRow, 6];*set[nBitsInCache, 17];* use fewer bits whie we wait for alu chips*set[CABitsInPipe0, 11];*mc[CABitsInPipe0Mask, 777];set[nBitsInCache, 16];set[CABitsInPipe0, 10];mc[CABitsInPipe0Mask, 377];set[CABitsInPipe1, 6];mc[CABitsInPipe1Mask, 176000];set[CABitsInPipe1Shift, 12];set[skipCacheShift, add[cacheShift,nBitsInRow] ];*mc[cacheRowMask, 1760];* mask to isolate the cache bits in a vamc[cacheRowMask0, AND[1760,177400] ];mc[cacheRowMask1, AND[1760,377] ];*mc[CABitsMaskC, 77777];* mask to isolate the CacheA bits in a mc[CABitsMaskC, 37777];* mask to isolate the CacheA bits in a patterngp,h=N( a ^q+ \ ZXUpq+Wpq+Upq+ Tpq+ S_pq+ R"p q+Ppq+Opq+ Nipq+M,pq+ Kpq+Jp q+# Isp + Fqpq+Epq+D}pq+C@pq+Bpq+@pq+?pq+>Jpq+= pq+;pq+":98p q6p q 5p q+r+ 4^qp q 3 pq1p q0p q/hpq.*p q,pq +pq*rp q )4p q+('p q&p q %|p q+& $>p q+. !>FkQDORADO: MemDefs.mcJune 23, 1981 8:59 AM%8* MEMD* August 13, 1979 5:54 PM* Cache Data Board:Loop Control MechanismsrmRegion[rmForMemDloops];knowRbase[rmForMemDloops];rv[cMunchVa,0];* current cache munch addressrv[cMunchEnd,0];* last + 20B munch addressrv[cdVa, 0];* current varv[cdVaEnd, 0];* last va +1rv[curCDpattern,1];* current patternrv[CDpatx,1];* current pattern indexrv[DsubrScr,0];* subroutines' scratch regrv[Drlink,0];* return linkrv[pcFlags,0];* kludge place to keep presetCacherv[pcHi8,0];* local variables!* rv[cdXX,0];* 6 unused registersmc[CDpat1EndC, 20];mc[CDpat2EndC, 40];mc[CDpat3EndC, 60];mc[CDpat4EndC, 64];mc[CDlastPatC, 64];mc[cdMaxVa, lshift[rowEndC!,6] ];* 6 = 4 addr bits in munch + 2 addr bits implied* by the four columnsgp,h=N,a _q ^+ \ Z XUpq+ Wpq+ Upq+ Tpq+ S_p q+ R"pq+ Ppq+ Opq+ Nipq+" M,pq+ Kp + Isqp q H6p q Fp q Ep q D}p q C@pq+0 B @@)'iDORADO: MemDefs.mcJune 23, 1981 8:59 AM%9* MEMS* January 13, 1979 12:46 AM STORAGE TEST SUBROUTINES: LOOP CONTROL MECHANISMSrmRegion[rmForStoreLoops];knowRbase[rmForStoreLoops];rv[SpatX,0];* pattern indexrv[curSPattern,0];* current pattern valuerv[svaX,0];* low 16 bits of VArv[sVaHiX,0];* hi 8 bits of varv[sMaxBrHi, 0];* max BRHI+1rv[sNmodules,0];* num storage modulesrv[sSubrScr,0];* scratch registerrv[Srlink, 0];* keeps return link for loop control guysrv[sTestFlags,0];* shadow copy of memState kept in RM for speed.rv[xPageXLo, 0];* low 16 bits of current page numberrv[xPageXHi, 0];* hi 16 bits of current page numberrv[xEndPageLo,0];* low bits of current last page+1rv[xEndPageHi,0];* hi 16 bits of current last page+1rv[xChipEndRasCas,0];* last ras/cas addr+1 in map ics*rv[sXX,0];* 2 unused registers: MemX uses 5 registersrmRegion[rm2ForStoreLoops];knowRbase[rm2ForStoreLoops];rv[sVaHiOld, 0];* used by diagnostics NOT by loop mechanismrv[sVaXold, 0];* used by diagnostics NOT by loop mechanismrv[sMCRvictim, 7];* cache column to use during storage tests IF* dirty misses and storage read/writes are to be incouraged by using MCR to force* the same column as victim. IF sMCRvictim >3 THEN setMCR[defaultMCR] ELSE* setMCR[ makeUseMcrV[sMCRvictim]]rv[simScr0, 0];rv[simScr1, 0];rv[simScr2, 0];rv[sChaosX,0];* current index in Chaos testrv[sSavedHoldValue, 0];* currend hold/task sim valuerv[pingPongRtn, 0];rv[iapFltTskRtn, 0];* formerly sGetICtypeRtn, but that's no longer neededrv[incSvaRtn, 0];rv[zeroMemoryRtn, 0];rv[saSetMcrRtn, 0];rv[sChaosRow0, 0];rv[sChaosRow1, 1];*rv[sXX,0];* One unused register.rm[saOrMcrNoWakeRtn, IP[pingPongRtn] ];* NOTE: The Chaos test shares RM locations* with the Cache Data subroutine RM locations. Exercise Caution!! Chaos must not call* subroutines that execute in the context of the cache Data tests!!!rm[rm00, ip[cMunchVa]];* RM for chaos, task 0rm[rm01, ip[cMunchEnd]];rm[rm02, ip[cdVa]];rm[rm03, ip[cdVaEnd]];rm[rm10,ip[curCDpattern]];* RM for chaos, simulator taskrm[rm11, ip[CDpatX]];rm[rm12, ip[dSubrScr]];rm[rm13, ip[dRlink]];* LOOP and other Constantsmc[Spat1EndC, 20];* [0..pat1EndC), cycled 1mc[Spat2EndC, 40];* [pat1EndC..pat2EndC), cycled 0mc[Spat3EndC, 64];* [pat2EndC..pat3EndC), cycled vamc[Spat4EndC, 100];* [pat2EndC..pat3EndC), randommc[SlastPatC, 100];* no more patternsmc[SchaosEndC, 10000];* number of Chaos iterationsgp,h=N,bA aq#1 ^ ]K\pq#Zp q#YpqXUpq#Wpq# Upq#Tpq#S_pq#)R"p q#/ Ppq$ Opq# Nip q! M,p q# Kp q Jp , H6q FD}pq#+C@pq#+Bp q#-@Q?J>J"= pq;pq:pq9Tpq#8pq#6p q5p q#54^pq3 p q1p q0p q/hp q ,pq*rpq '* &U %|D#pq#!pq pq Hpqpq+pq Rpqpq \##f#!)# # # X M>k\DORADO: MemDefs.mcJune 23, 1981 8:59 AM%10* MEMA* June 15, 1981 11:29 AM%The mema rm definitions must not occur as the las set of definitions: the fio test clobbers RM IN[0..17B) and the last two rm regions defined may well have those values.%rmRegion[rmForAsubrs];knowRbase[rmForAsubrs];rv[aTestTaskX, 0];rv[aNfaultsX, 0];rv[aSrnX,0];rv[aNfaultsX2, 0];rv[aMakingFaults,0];rv[aSubrScr, 0];rv[aRlink, 0];*rv[aXX,0];* 8 unused registersknowRbase[defaultRegion];*rm[iapFltTaskRtn, IP[sgetICtypeRtn] ];* steal rm from midas subroutine* now iapFltTskRtn is defined directly in one of memSubrsS's regionsrm[apSaveT0TpcRtn, IP[simScr0] ];* more RM stealingrm[apSavedT0Tpc, IP[simScr1] ];rm[apSetTpcRtn, IP[simScr2] ];set[memSimInitLoc, 5000];mc[memSimInitLocC, memSimInitLoc];mc[simInitLocC, memSimInitLoc];* define the IM location that setHold should know about!mc[fioTestLoc0C, 377];mc[fioTestLoc1c, 3000];set[fioTestLoc, add[fioTestLoc0C!, fioTestLoc1c!]];mc[fioTestAddrC, 140000];* Address of fioTestCode (xqts for each task)set[fio.subTaskBrShift, 11];* shift memBase index to correspond to bits in BRset[fio.subTaskMemShift, 12];* shift subTask index to corresponds to bits in BRrm[aSubTaskX, IP[aNfaultsX] ];rm[fioIStorageRtn, IP[aSrnX]];rm[fioIMemRtn, IP[iapFltTskRtn] ];mc[maxSubTaskC, 4];* subTasks IN [0..maxSubTaskC)gp,h=N,bA aq _p ^a ]KH \ Zq YXUp qWpqUpqTp qS_p qR"pqPpq Op  Niq M,p q3 KDJp q+Isp qH6p q E#" D}p#q8 B @ ?p q% = p q #- ;pq#1 :pq#2 8pq 6p q 5p q 3 , /EA8DORADO: MemDefs.mcJune 23, 1981 8:59 AM%11* MEMX* February 10, 1981 9:55 AM MAP TEST SUBROUTINES: LOOP CONTROL MECHANISMSrmRegion[rmForMapLoops];knowRbase[rmForMapLoops];rv[MpatX,0];* pattern indexrv[Mrowx,0];* row indexrv[Mcolx,0];* column indexrv[curMPatHi,0];* current high 2 bits of map patternrv[curMPatLow,1];* current low 16 bits of map patternrv[curMWait,1];* current wait between write and checkrv[MsubrScr,0];* subroutines' scratch regrv[Mrlink,0];* return linkrv[MpageX,0];* page numberrv[MwriteVal, 0];* registers for xBoardLoop stuffrv[Maddr1, 0];rv[Mwait, 24];rv[Maddr2, 1];rv[Mread1, 125252];rv[Mread2, 125252];rv[xMapBase, 0];* first real page of storage* rv[xXX,0];* 1 unused register.*rmRegion[rmForStoreLoops];* SEE MEMS section!*knowRbase[rmForStoreLoops];*rv[xPageXLo, 0];* low 16 bits of current page number*rv[xPageXHi, 0];* hi 16 bits of current page number*rv[xPageEndLo,0];* low bits of current last page+1*rv[xPageEndHi,0];* hi 16 bits of current last page+1*rv[xChipEndRasCas,0];* last ras/cas addr+1 in map ics*rmRegion[defaultRegion];*knowRbase[defaultRegion];mc[MwaitEndC,60000];mc[MwaitIncrC, 20000];mc[Mpat1EndC, 21];* [0..pat1EndC)mc[Mpat2EndC, 22];* [pat1EndC..pat2EndC)mc[MlastPatC, 22];* no more patternsset[nBitsInPage, 10]knowRbase[defaultRegion];gp,h=N,bA _q+- ]K \ Ypq+ XUpq+ Wpq+ Upq+$ Tp q+$ S_pq+& R"pq+ Ppq+ Nipq+ M,pq+ Kpq Jpq Ispq H6pq Fpq Epq+ D}p+ Bq+p @q ?pq+$ >Jpq+# = p q+! ;p q+# :p q+ 9T 8 4^pq 3 p q 0pq+ /hpq+ .*pq+ +p q ' '>%@7memDesperateA.mcJune 17, 1981 9:30 AM%1title[MemDesperateA];top level;%June 17, 1981 9:29 AMCreate this file from old contents of memSubrsS.mcA FEW RULESSubroutines clobber rscr, rscr2 and T unless otherwise specified at both point of call and insubroutine description. Subroutines return single values in T, and they accept single values in T. Twoparameter subroutines accept their values in rscr and rscr2.Global values for S boardAbbreviations used hereiniInitMMapcolColumnSStorageaAllpPipeapAllPipe (test pipe, use all of memory system)nextFooincrements foo loop variable, returns with fast branchcondition to check for done w/ loopgetFooreturns current value of loop variable, foogetFooRtnsubroutine that returns in T the saved value of foo'sreturn linkiFooCtrlinitialize foo loop control%^gp+="N bAq a ]K \Z2*dXUp Uq] Tf S_< R" ONip+qM,p+qKp+qJp+qIsp+qH6p+qFp+q-Ep+q6D}#C@p+q+Bp+q5@ ?p+q >J p #q+!+  /0ZZ %=yHmemDesperateA.mcJune 17, 1981 9:30 AM%3* May 20, 1981 5:24 PMsppBounce:* In an infinite loop do the following:* read a different va into the selected column. This will flush the test-munch to storage.* read the test munch and test the va. this brings it back into the cache.t _ a1;cnt _ t;call[getCurSpattern];rscr2 _ t;* keep curSpattern in rscr2t _ sva;* write curSpattern into SVAstore _ t, DBuf _ rscr2;sppRL:t _ (sva) # (b0);STORE _ t, DBuf _ t;* force a different munch into this cache columnFETCH _ sva;* read and check svat _ MD;t _ t # (rscr2);* check MD w/ curSpattern (its in rscr2)skpif[alu=0];error;* contents of sva # curSpatternloopuntil[cnt=0&-1, sppRL], t_a1;* t used below.sppInfiniteL:branch[sppRL], cnt _ t;sppRtn:returnUsing[pingPongRtn];*%*commented out! REMOVE first * to really comment it out^gp+="N bAq ap +q' _Z ^JZYXUW +U+T S_pR"qP+0O +NiM,+(K J+Is0 H6p Fq D}pC@q B +(2 @@)'imemDesperateA.mcJune 17, 1981 9:30 AM%4* June 25, 1979 10:36 AM%Dirty Write LoopThis is a MIDAS subroutine to help debug the memory. Begin execution at "dirtyWriteLoop". When abreakpoint occurs, the map has been initialized. At that point the user should place a virtual addressin the register sva, and then proceed.The code sets the cache Amemory for the appropriate row to four different values that are sva+2000,sva+10000B, etc. The code also sets the cflags to vacant. When this is done, a store is performedfollowd by a long wait. At the end of the wait the test loops to the point where it sets the cacheAmemory again.dirtyWriteLoop: PROCEDURE[sva: Virtual Address] =BEGINpresetMap[];victimColumn _ 0;breakPoint;-- at this point, user sets sva appropriately (maychange victim column, too)WHILE true DOcol _ 0;FOR CNT _ -3, CNT _ CNT + 1, UNTIL CNT >0 DOsva _ sva + 2000B;setCAmem[sva, col];setCflags[sva, col, Vacant];col _ col+1;ENDLOOP;sva _ sva - 4000B;setBR[0,0];setMCR[useMcrv, mcrV=victimColumn];MD _ 0, STORE _ sva;ENDLOOP;END;%*%*commented out! REMOVE first * to really comment it outdirtyWriteLoop: top level;call[presetMap];col2X _ t-t;* init victim columnbreakpoint;* SET sva HEREdwMainLoop:cnt _ 3s, col _ t-t;* init cnt and colidwL:* initialize the Amemory and the Cflagssva _ (sva) + (2000C);call[setCAmem];* set Mmemory to svarscr _ cflags.vacant;* set Cflags to vacantcall[setCflags], t _ sva;loopUntil[cnt=0&-1, idwL], col _ (col)+1;* choose next column and loopsva _ (sva) - (4000C);* reset sva to original valuerscr _ t-t;call[setBR], rscr2 _ t-t;* zero base registerscall[getCol2];call[makeUseMcrV];* set mcrv to select col2xt _ t or (mcr.noWake);call[setMCR], ;* set mcrnoop;* noop for patches if you want onedwStore:DBuf _ t, STORE _ sva;* HEREs the store!!t _62C;call[longWait];branch[dwMainLoop];*%*commented out! REMOVE first * to really comment it out^gp+="N bAq a(_p ^q` ]Kf \& Yc XUa Wb U S_pq"R"P ONi +2M,K JIs,H6FED} C@B@ ?#>J= ;-: 8 +( 6pq 54^ +3 + 0p /hq+ ,pq'+*r+)4+'&)+$>+# !+ H+ ++" pq+\  +(^ E3VmemDesperateA.mcJune 17, 1981 9:30 AM%5* July 1, 1979 3:43 PM%Storage checkout code.sva1 = address 1 default = 0sva2 = address 2 default = 2000swait = long wait value default = 100smcr1 = mcr value default = noWake+UseMCRVsmcr2 = mcr value + VNV=Column3sdata1 = pattern to utilize default = 0sdata2 = pattern to utilize default = 0sxor = xor pattern default = 177777stsyn = test syndrome value default = 0rscr = scratch value default = ?rscr2 = scratch value default = ?br0 = base register 0 default = ?SBrHi = value for BrHi default = 0SBrLo = value for BrLow default = 0This code is useful for checking out storage boards. It consists of a series of initializationinstructions followed by an infinite loop that writes the munch specified by sva1 then the munchspecified by sva2. There is a second infinite loop which reads sva1 followed by sva2. That loop willnot exedcute unless the operator changes the instruction at scoF into a noop. Doing this will enablethe second loop after the code has written the two munches specified by sva1 and sva2.%top level;doScheckOut:RBASE _ rbase[defaultRegion];t _ 1c;stkp _ t;call[iSboard];* initialize the entire memory system.sva1 _ t-t;sva2 _ 2000c;swait _ 100c;smcr1 _ 0c;* leave from for patchingsmcr1 _ (smcr1) or (mcr.noWake);call[scoAddMcrVNV], t _ smcr1;smcr1 _t;smcr2 _ t;sdata1 _ t-t;sdata2 _ t-t;sxor _ 177777c;stsyn _ t-t;* test synmemBase _ 0s;sBrHi _ 0c;* default br = 0sBrLo _ t _ 0c;rscr _ SBrHi;call[setBR], rscr2 _ sBrLo;sCheckOut:t _ (smcr1) or (mcr.disHold);call[setMCR];t _ stsyn;store _ r0, DBuf _ t;loadTestSyndrome[t];call[longWait], t _ swait;scoInit: noop, breakpoint;call[xVacateCacheRow], t _ sva1;t _ mcr.noWake;* set mcr.noWake (and reenable BRs)call[setMCR];* so that loading Brs can actually happen.rscr _ SBrHi;* restore BR, which xVacateCacheRowrscr2 _ SBrLo;* clobbered.call[setBR];scoS:t _ cm1;* scope trigger if you wishTIOA _ t, rscr _ a0;TIOA _ rscr;call[setMCR], t _ smcr1;* initialize 1st munch^gp+="N bAq a _^pq + ]Kpq +\pq+ Zpq +Ypq +2 XUpq+ Wpq+ Upq +Tpq+ S_pq+ R"pq+ Ppq+ Opq+ Nipq+ J_ Is` H6f FJT= &T: T9T T8 T6 .T5T4^T3 T1 T0 T/h T.*T,  T+ T*r .T)4T' T& $>p T#qT! T THT T RpqTT#T *T #T  T )pT q.T T p T 3  E3]NmemDesperateA.mcJune 17, 1981 9:30 AM%6rscr _ sdata1;call[scoLoadMunch], t _ sva1;call[setMCR], t _ smcr2;noop;scoFlush1:fetch _ sva2;;* 1st munch to storage, fetch 2nd munchcall[longWait], t _ swait;call[setMCR], t _ smcr1;* initialize 2nd munchrscr _ sdata2;call[scoLoadMunch], t _ sva2;call[setMCR], t _ smcr2;noop;scoFlush2:fetch _ sva1;;* 2nd munch to storage, fetch 1st munchcall[longWait], t _ swait;scoF:branch[sCos];* noop for read transportsscoL:t _ cm1;* scope trigger if you wishTIOA _ t, rscr _ a0;TIOA _ rscr;fetch _ sva1;* fetch first munchcall[longWait], t _ swait;call[xGetPipe4];* get pipe4 value into trscr _ pipe4.memErr;rscr _ (rscr) or (pipe4.ecFault);t and (rscr);* mask all but error indicatorsskpif[ALU=0];breakpoint;scoGo:noop;fetch _ sva2;* fetch second munchcall[longWait], t _ swait;noop;branch[scoL];* loop for read only transports^gp+="NTbAq TaT^T]K \p TZq 'TYTXU TW TUTS_TR" Pp TOq 'TNi Kpq jr IspTH6q.TFTE TD} TC@TBjT@T?!T>J T= T; :pT9TqT8 T6T5T4^ ^ 2'I5memDesperateA.mcJune 17, 1981 9:30 AM%7* June 25, 1979 10:26 AM%Subroutines for the storage checkout code.%scoLoadMunch: subroutine;* enter w/ t = va, rscr = patternrscr2 _ t;t _ rscr;scoLML:DBuf _ t, rscr2 _ (Store _ rscr2) + 1;t _ t # (sxor);(rscr2) and (17c);* see if done w/ munchloopUntil[ALU=0, scoLML];return;scoAddMcrVNV: subroutine;* enter w/ t = initial mcr value. add:* mcr.useMcrV, mcr.useMcrNV, set victim, next victim columns to 3.* Return mcr value in t, clobber rscr.t _ t or (mcr.useMcrV);rscr _ 3c;* victim = column 3rscr _ lsh[rscr, mcr.mcrVshift];t _ t or (rscr);rscr _ 3c;* next victim = column 3rscr _ lsh[rscr, mcr.mcrNVshift];return, t _ t or (rscr);^gp+="N bAq aT_* ^ \p q !TZ TY XUpTWq&TUTTjTS_TR" Op q & NiB M,&TJTIs .TH6TFTE .TD}!TC@ @,W'izmemMapA.mcJune 16, 1981 4:18 PM%1title[MemMapA];top level;%June 15, 1981 10:50 AMCreate this fileA FEW RULESSubroutines clobber rscr, rscr2 and T unless otherwise specified at both point of call and insubroutine description. Subroutines return single values in T, and they accept single values in T. Twoparameter subroutines accept their values in rscr and rscr2.Global values for S boardAbbreviations used hereiniInitMMapcolColumnSStorageaAllpPipeapAllPipe (test pipe, use all of memory system)nextFooincrements foo loop variable, returns with fast branchcondition to check for done w/ loopgetFooreturns current value of loop variable, foogetFooRtnsubroutine that returns in T the saved value of foo'sreturn linkiFooCtrlinitialize foo loop control% bgp );N bAq a ]K \Z*dYp Wq] Uf T< S_ POp+qNip+qM,p+qKp+qJp+qIsp+qH6p+q-Fp+q6E#D}p+q+C@p+q5B @p+q ? >'E3)memMapA.mcJune 16, 1981 4:18 PM%2* June 16, 1981 4:18 PM%Memory Map test using all of memory systemaMapTest: PROCEDURE =-- This test checks the map reference bit and thatvarious faults cause wakeups. The only way to set the ref bit in the map is to make a memoryreference!BEGINIF ~memState.aMapTest THEN RETURN;FOR x IN [0..lastMapPage] DOoldM_ readMap[x];setMap[oldM];-- setting map will clear ref bitt_ readMap[x];IF t.ref=1 THEN ERROR;-- ref bit non zeroxSetBRforPage[x];-- set BR to ref page xPreFetch[0];-- prefetch will set ref bitt_ readMap[x];IF ~t.ref THEN ERROR;-- ref bit should be onet.wp_ TRUE;-- set write protect bitwriteMap[x, t];xSetBRforPage[x];-- setup BR againaMakingFaults_TRUE;-- tell fault task we're making faultsfaultInfo_0;-- task 17 will set this w/ hardware valueStore_0, DBuf_ 0;-- this should cause a write protect faultIF faultInfo.nFaults#0 THEN ERROR;-- remember 0 means 1 fault...-- set ProcSrn to address the pipe entryProcSrn_ faultInfo.firstSrn;-- with the error in itIF ~pipe.wp THEN ERROR;-- wp should be set in pipeProcSrn_0;-- correct ProcSrnt.wp_ t.dirty_ TRUE;-- now test that touching vacant map entrieswriteMap[x,t];-- causes the right sort of errorfaultInfo_0;-- task 17 will set this w/ hardware valueFetch_ 0;t_ MD;aMakingFaults_ FALSE;ProcSrn_ faultInfo.firstSrn;IF ~pipe.pageFault THEN ERROR;ProcSrn_0;setMap[x,oldM];ENDLOOP;END% bgp );N bAq a_p* ^q +2 ]K] \ ZY"XUWU +!T S_+R"+P +O Ni+K +JIs+H6#&F +*E+*D}"3C@(B3@+? += #,; +!: +*9T8654^3 10/h ,f +B-<memMapA.mcJune 16, 1981 4:18 PM%3* June 16, 1981 4:18 PM%aMapTestThis test checks parts of the map that require all the boards of the memory system.Check the ref bit (only set when a page is actually referenced)Check that wp (write protect) bit causes page faultsRSCR3= original contents of current map entryRSCR4= current page in Map%aMapTest:pushReturn[];call[disableConditionalTask];* don't run HOLD simulatorcall[iSboard];* init Sboard in case its not happened alreadycall[getMemState];t AND (memState.aMapTest);* see if our test is enabledbranch[aMapTestXit, ALU=0];noop;call[iapFltTask];call[iMapPageCtrl];aMapL:* This code keeps rscr4=current page,* rscr3=map entry we readcall[nextMPage];skpif[alu#0], rscr4_t;* save current map page in rscr4branch[aMapXitL];noop;call[xReadMapPage];rscr3_ t;* save current map entry in RSCR3call[xSetBRforPage], t_ rscr4;* make current BR point to current map pagerscr2_ rscr3;* rscr2=mapBuf data=real pagecall[writeMap], rscr_a0;* rscr= tioa bitscall[xReadMapPage], t_ rscr4;* rtns w/ t= real page num, rscr= pipe4(rscr)and(pipe4.ref);* after setting map, ref bit should be zeroskpif[ALU=0];aMapErr0:* ref bit still set!error;call[xSetBrForPage], t_ rscr4;t_a0;PreFetch_t;call[longWait], t_ 100c;call[xReadMapPage], t_ rscr4;(rscr)AND(pipe4.ref);skpif[ALU#0];* preFetch should cause page to be referencedaMapErr1:error;* ref bit (rscr=pipe4) not set!noop;* for placementcall[xSetBRforPage], t_rscr4;rscr2_ rscr3;call[writeMap], rscr_ a0;call[xReadMapPage], t_ rscr4;* now we see if we zeroed the ref bit(rscr) and (pipe4.ref);skpif[ALU=0];aMapErr2:* we didn't succeed in clearing the ref biterror;* for page in rscr4.call[xSetBRforPage], t_rscr4;call[aMapClearMunch],t_ a0;* must clear our target munch from cacherscr2_ rscr3;call[writeMap], rscr_ 2c;* set write protect bitt_1c;aMakingFaults_t;t_a0; bgp );N bAq a+f_p ^qS \? Z4 XU- W U S_pR"q P+O +.NiM,+KJH6F D}p+q% C@@?+>J= :9T+!6++5 +4^+1+'0++/h .*p+q,*r)4' &%|$># +- !p q+H+ R+% \p+q++f+()  +  p 36 >]memMapA.mcJune 16, 1981 4:18 PM%4Store_t, DBuf_t;call[longWait], t_100c;aMakingFaults_a0;t_Q;* fault task put FaultInfo in Qt AND (FaultInfo.nFaults);* nFaults=0 => 1 fault occured.skpif[ALU=0];* should have one fault.aMapErr3:* no fault or too many faultserror;t_ Q;t_ t and (FaultInfo.faultSRN);ProcSRN_t;t_a0;ProcSRN_t;t_ not(Pipe4');t AND (Pipe4.wProtect);skpif[ALU#0];* write protect should be set!aMapErr4:error;t AND (Pipe4.Mfault);skpif[ALU=0];* should set mapTrouble when writingaMapErr5:* into a write protected. (low true val)error;noop;* for placementcall[xSetBRforPage], t_ rscr4;call[aMapClearMunch],t_ a0;* must clear our target munch from cacherscr2_ rscr4;call[writeMap], rscr_ 3c;* marking it dirty and write protected makes it vacantt_ 1c;aMakingFaults_ t;t_ a0;Fetch_t;Pd_ (Md);aMakingFaults_ a0;t_ Q;* fault task left q = FaultInfot_ t AND (FaultInfo.faultSRN);ProcSRN_ t;t_ not(Pipe4');rscr_a0;ProcSRN_rscr;t AND (Pipe4.wProtect);* wp should still be onskpif[ALU#0];aMapErr6:error;t AND (Pipe4.Mfault);skpif[ALU=0];* map trouble should be (low) trueaMapErr7:error;t AND (Pipe4.memErr);skpif[alu#0];* NOT a memory error...its a page faultaMapErr8:* memErr is low trueerror;noop;* for placementcall[xSetBRforPage], t_rscr4;call[aMapClearMunch],t_ a0;* must clear our target munch from cacherscr2_ rscr3;call[writeMap], rscr_a0;* map to old valuebranch[aMapL];* try the next SrnaMapXitL:noop;aMapTestXit:returnP[];aMapClearMunch: subroutine;* performs Flush_t bgp );NbAqa_^+]K+\ + Zp+qYWUT S_R" PONi + M,pKqIsH6 +$ Fp+q(ED}+B@+(? >J+6= ;:9T864^+3 1 0/h.* ,++ *rp)4q&%| +" $>p#q H +'  p+q++(\ + + pqf p q 3pq + D1]'memMapA.mcJune 16, 1981 4:18 PM%5Pd_ Md;Flush_ t;* so that the map's flags get usedreturn, Pd_Md; bgp );NbAqa+"_ b ^f6 %memPipeAndFaultA.mcJune 17, 1981 8:49 AM%1title[memPipeAndFaultA];top level;%June 17, 1981 8:20 AMadd iapMap to make it easy to cause faults -- they occurred by chance before.June 16, 1981 5:22 PMChange apMakeNFlts to avoid reusing same address and yet to stay in same cache row.June 16, 1981 4:07 PMChange faulttask to wait one more cycle after B_FaultInfo before blocking.June 15, 1981 11:28 AMChange faultTasks to save FaultInfo in Q. Remove faultTaskContinueLoc.June 1, 1981 3:07 PMMore fixes to pipe for model 1.May 29, 1981 11:12 AMRemove comments around various pieces of code -- they were commented-outto accommodate MicroD placement. This is first step in rejuvenating this test.May 4, 1979 5:11 PMChange code to use WriteMap instead of defunct xWriteMap, and change it to use sUseDefaultMcrinstead of defunct saSetMcr.May 4, 1979 3:40 PMConvert to model 1 from model 0 sources.%%A FEW RULESSubroutines clobber rscr, rscr2 and T unless otherwise specified at both point of call and insubroutine description. Subroutines return single values in T, and they accept single values in T. Twoparameter subroutines accept their values in rscr and rscr2.Global values for S boardAbbreviations used hereiniInitMMapcolColumnSStorageaAllpPipeapAllPipe (test pipe, use all of memory system)nextFooincrements foo loop variable, returns with fast branchcondition to check for done w/ loopgetFooreturns current value of loop variable, foogetFooRtnsubroutine that returns in T the saved value of foo'sreturn linkiFooCtrlinitialize foo loop control%\gp,>$N bAq a ]K \ZM YXUS WUJ TS_G R"P ONiH M,O KJ] Is H6F( E D}*dC@p @q] ?f >J< =  :9Tp+q8p+q6p+q5p+q4^p+q3 p+q1p+q-0p+q6/h#.*p+q+,p+q5+ *rp+q )4 'E3@7memPipeAndFaultA.mcJune 17, 1981 8:49 AM%2* June 19, 1978 5:59 PM%Memory Pipe And Fault TesttestPipeAndFault: PROCEDURE =BEGINinitFaultTask[];FOR testTask IN [1..14] DOFOR srn IN [ 1..15] DOsetUpMemory[];-- mem[0..17] in cache, cache row1 dirty, mem[20..37] absent.TPC[testTask] _ @pipeTaskCode;NOTIFY[testTask, srn];ENDLOOP;ENDLOOP:disableFaultTask[];ENDpipeTaskCode: PROCEDURE[taskX, srn: CARDINAL]; =BEGIN--check RefType: 0 =>undefined, 1 =>storage read, 2 => storage write, 3 => map or non-storageop-- check task, subtask, nFaults, faultSRNsetRBASE[defaultRegion];taskingOn[];aSetAsrnForWrite[srn];* since this code makes faults it must xqt as taskX for faultTaskto do right thingt_ FaultInfo[];* this clears the faultInfo data in the pipeSETBR[0,0];t _ mem[0];-- ref 0aIncAsrn[];mem[1] _ 1;-- ref 1aIncAsrn[];t _ 20c;-- ref 2: miss & force storage write (see setUpMemory)FETCH _ t;t _ MD;useSrn _ srn;FOR i IN [0..2] DOsetPROCSRN[useSRN];myPipe2 _ PIPE2[];refType _ IF i = 2 THEN 2 ELSE 1;IF myPipe2.ref # refType THEN SIGNAL[pipe2.refTypeErr, myPipe2, refType];IF myPipe.subTask#0 THEN SIGNAL[pipe2.SubTaskErr, myPipe2, 0];IF myPipe2.task # taskX THEN SIGNAL[pipe2.taskErr, myPipe2, taskX];IF myPipe2.emuFault THEN SIGNAL[pipe2.emuFaultErr, myPipe2, 0];myPipe4 _ PIPE4[];IF myPipe4.ref #1 THEN SIGNAL[pipe4.refErr, 1];myFaultInfo _ FAULTINFO[];IF myFaultInfo.emuFault THEN SIGNAL[faultInfo.emuFaultErr, myPipe, 0];IF myFaultInfo.nFaults # 7 THEN SIGNAL[faultInfo.nFaultsErr, myPipe, i];useSRN _ incSRN[useSrn];ENDLOOP;FOR nFlts IN [1..6] DOaSetAsrnForWrite[srn];useSrn _ srn;makeNfaults[nFlts];FOR i IN [1..nFlts] DOsetProcSRN[useSrn];myPipe2 _ Pipe2;IF myPipe2.emulatorFault THEN SIGNAL[pipe2.emuFaultErr, myPipe2,0];IF myPipe2.nFaults # nflts THEN SIGNAL[pipe2.nFaultsErr, myPipe2, i];IF myPipe2.FaultSRN #srn THEN SIGNAL[pipe2.FaultSrnErr, myPipe2, useSRN];myPipe_ FaultInfo[];IF myFaultInfo.emuFault THEN SIGNAL[faultInfo.emuFaultErr, myPipe, 0];IF myFaultInfo.nFaults # nflts THEN SIGNAL[faultInfo.nFaultsErr, myPipe, i];IF myFaultInfo.FaultSRN #srn THEN SIGNAL[faultInfo.faultSrnErr, myPipe, useSrn];useSrn _ incSRN[useSrn];ENDLOOP;\gp,>$N bAq a%Z_p ^q ]K\ZYXU #=WUTS_R"P Op q# NiM,]KJ)H6F E#AD}C@,B @ ? >J = ;6: 9T8 654^3 !1I0>/hC.*?,+/*r)4F'H&%|$>#!  H CREIF\MPd ?aVmemPipeAndFaultA.mcJune 17, 1981 8:49 AM%3ENDLOOP;RETURN;END;initFaultTask: PROCEDURE =BEGINnoWakeOff[];-- default = allow memory wakeupssaSetMcr[getSMcrVictim[] ] ;-- set mcr for diagnosticTPC[faultTaskX] _ @faultCode;NOTIFY[faultTaskX];RETURN;faultCode:-- This code executes when a memory fault occurstaskingOn[];setRBASE[rbaseOf[makingFaults]];DOBLOCK;-- wait here for next fault to occurIF aMakingFaults = 1 THENBEGINTPC[testTask] _ @makeNfaultsContinueEND;ELSE IF aMakingFaults = 2 THENBEGINTPC[testTask] _ @aSetAsrnContinue;END;ELSE ERROR[];-- awakened unexpectedlyENDLOOP;END;disableFaultTask: PROCEDURE=BEGINfaultInfo _ FAULTINFO[];-- clear out waiting wakeupsnoWakeOn[]saSetMcr[getSMcrVictim[] ];TPC[faultTaskX] _ 7776B;END;makeNfaults: PROCEDURE[n] =BEGINsetBR[377B, 0];aMakingFaults _ 1;-- global value visible to fault handlerFOR i IN [1..n] DOt _ mem[i];makeNfaultsContinue:-- fault task will force us to continue hereENDLOOP;makingFaults _ FALSE;END;setUpMemory: PROCEDURE=BEGIN-- This procedure forces mem[0..17B] into the cache, and backgrounds row 1 of the cache w/munches that don't include mem[20B..37B]. This enables the test to make a reference that isguaranteed to cause a miss and a dirty write. Recall that 20B addresses the first row of thecache and that increments of 1000B will not change the row address.FOR i IN [0..17B] DO mem[i] _ i; ENDLOOP;FOR i _ 10020B, i + 1000B UNTIL 20000B DOmem[i] _ i;ENDLOOP;END;incSrn: PROCEDURE[oldSrn] RETURNS[newSrn] =BEGINnewSrn _ oldSrn + 1;IF newSrn > 15 THEN newSrn _ 1;RETURN;aSetAsrnForWrite: PROCEDURE[srn] =BEGINaMakingFaults _ 2;setBR[-1,0];UNTIL config.Asrn = srn DOFETCH _ 0;T _ MD;aSetAsrnContinue:ENDLOOP;aMakingFaults _ 0;setBR[0,0];END;\gp,>$NbAqa_ ^p q ]K\ #!Z+YXUWUp q0T S_R"P#$ONiM,$KJIsH6"FE #D}C@ Bpq @?+>J = ;: 9Tp q865#(4^3 1pq,0/h.* ,p q +*rZ)4['\&C$>)#)!  H  pq$R pq\  f)   p  3 >{]3memPipeAndFaultA.mcJune 17, 1981 8:49 AM%4aIncAsrn: PROCEDURE=BEGINxWriteMap[0,0];-- write the map w/ virtual page 0 mapped-- onto real page 0 (default state for diagnostics). Map writes cause Asrn to increment.IF aMakingFaults # 0 THEN setBR[377B,0] ELSE setBR[0,0];-- a side effect of xWriteMap is toclobber the current BR, so it must be regenerated.END;%\gp,>$N bAq a_+*^X\884#Z2XU Uh Tz?;memPipeAndFaultA.mcJune 17, 1981 8:49 AM%5* June 9, 1981 10:22 AM%Pipe testThis code runs in different tasks and causes various sorts of memory references: Three normal memoryreferences and a series of references that cause faults. The point of the t est is to fill the pipewith different sorts of entries and to make sure that the pipe data reporting logic really works. Thetest has two phases. In the first phase three normal references occur and the data in the pipe getschecked. In the second phase a series of faults occur and then all the entries in the pipe arechecked.The "main program" for this test iterates through the various tasks and the various srn values. Itsets up the pc for the correct task and causes it to run. The code at apPipeTest actually makes thereferences and checks the pipe.%aPipeTestCtrl:pushReturn[];call[disableConditionalTask];* don't run HOLD simulatorcall[iSboard];* init Sboard in case its not happened alreadycall[getMemState];t AND (memState.PipeTest);* see if our test is enabledbranch[apTestCtrlXit, ALU=0];noop;call[iapMap];* setup map for making page faults convenientlycall[iapFltTask];call[iapTestTask];apTestCtrlL:call[apNextTestTask];skpif[alu#0];branch[apTestCtrlXit];noop;call[iapSrn];apCtrlL2:call[apNextSrn];skpif[alu#0];branch[apTestCtrlL];noop;call[apGetTestGo];rscr_link;call[apGetTestTask];subroutine;link _ rscr;top level;LdTPC _ t;call[notifyTask];noop;* give it time to awakenbranch[apCtrlL2];* try the next SrnapTestCtrlXit:returnP[];apGetTestGo:subroutine;coreturn;branch[apTest];\gp,>$N bAq a+_p ^qd ]Kc \e Zc Y^ XU Wc UFp q T S_ Pp Oq Ni+M, +.KJ+IsH6E +/D}C@ @p ?q>J = ;: 8p6q5 4^3 10 /h.* , + *r )4'+&+ $>p q# p q H  DKamemPipeAndFaultA.mcJune 17, 1981 8:49 AM%6* June 4, 1981 2:07 PMapTest: * This code runs at various task levels.set[xtask, 1];top level;RBASE _ rbase[defaultRegion];* init task specific thingstaskingOn;call[setMbase], t_a0;* use BR 0rscr _ a0;* set BR 0 to zerocall[setBR], rscr2 _ a0;call[iapMemory];* init cache in case it has changedcall[apGetSrn];call[aSetAsrnForWrite];* Since this routine makes faults to cause Asrn tohave the proper value, it must execute at the aTestTaskX level.noop;* for MicroDt _ FaultInfo'[];* clear out faultInfocall[setMcr],t_mcr.noSeWake;rscr _ a0;* set current BR to zerocall[setBR], rscr2_ a0;t _ a0;FETCH _ t;* ref 0rscr _ MD, t _ t+1;call[apGetSrn];aUseSrn_ProcSRN_t;rscr_ a0;* no faultsrscr2_ 1c;* reftype=1apTest1:call[apChkPipe2];* rscr=numFaults=7=none, rscr2=ref type=1* check procSrn for correctness, keep FaultInfo in rscrrscr_ not(FaultInfo');apTest2:call[apChkProcSrn], rscr2_ aUseSrn;call[apChkAsrn], rscr2_ aUseSrn;call[apChkFaults], rscr2_ a0;* no faultst_ a0;ProcSRN_ t;t _ 20c;* ref 2: cause dirty miss (see iapMemory)FETCH _ t;rscr_ MD;rscr_a0;rscr2_1c;* ref type=1=read missing munchProcSRN_ aUseSrn;apTest3:call[apChkPipe2];rscr_ not(FaultInfo');apTest4:call[apChkProcSrn], rscr2_ aUseSrn;call[apIncSrn], t_ aUseSrn;* must increment aSrn twicecall[apIncSrn];* since dirty miss writes two entriesapTest5:call[apChkAsrn], rscr2_ t;call[apChkFaults], rscr2_ a0;call[apIncSrn],t_ aUseSrn;ProcSRN_ t;rscr_ a0;* no faultsrscr2_ 2c;* storage type=2=write dirty munchcall[apChkPipe2];ProcSRN_r0;\gp,>$N bAq _pq+(^ ]K Z+Y XU+ W +UT+#R"P+2 O?M,p+ Kq+JH6 +FD}C@ +B?>J;+ : + 9Tp8q+) 573  1p0q#/h.*+ +*r )4+)' &$>#+! pHq  pq#R++% pq\ f+ ) +"  p  B-]memPipeAndFaultA.mcJune 17, 1981 8:49 AM%7* June 4, 1981 12:59 PM* Now cause a series of faults and check the pipe* CHECK OTHER PIPE VALUES, TOO!noop;* for placement.call[setMcr], t_mcr.noWake;cnt_10s;* clear-out row 0 so that page faultst_1000c;* won't get any dirty victims in the cacheloopUntil[CNT=0&-1, .], t_ (Fetch_t)+t;* thereby avoid problems computing* expected value of ASRN.call[iapNFlts];apFltL:call[apNextFltX];skpif[alu#0], t_a0;branch[apFltXitL];ProcSRN_ t;* cause nFaults to appear in the pipe beginningcall[apGetSrn];* begin faulting at proper place in pipecall[aSetAsrnForWrite];* IE. firstFaultSrn= this valuecall[apGetFltX];* make aNfaultsX errorscall[apMakeNFlts];noop;* for MicroDcall[apGetSrn];* point to right place in pipe to readaUseSrn_ ProcSrn_ t;* Check FaultInfo values. Remember that _FaultInfo resets nFaults to 7rscr_not(FaultInfo');* check code needs rscr=faultInforscr2_ aUseSrn;apFltsP1:call[apChkProcSrn];call[apGetFltX];t_ t-1;cnt_t, call[apGetSrn];noop;* for placement.call[apIncSrn];* proper Asrn=(starting Asrn+nFlts)loopUntil[CNT=0&-1, .-2];apFltsP2:call[apChkAsrn], rscr2_ t;call[apGetFltX];call[apGetSrn], rscr2_t;* t_ firstFaultSRNapFltsP3:call[apChkFaults], t_ aUseSrn;call[iapNflts2];* FOR i IN [1..nFaults] check EACH pipe entryapFltChkL:noop;* here for placement problemscall[apNextFlt2];skpif[alu#0];branch[apFltL];* try outer, nFlts, loop againprocSRN _ aUseSrn;rscr_a0;* nfaultsrscr2_ 1c;* refType=readapFltsP4: call[apChkPipe2], t_ aUseSrn;call[apIncSrn], t _ aUseSrn;aUseSrn _ t;branch[apFltChkL];apFltXitL:call[setMcr], t_mcr.noSeWake;ProcSRN_ t;* reset ProcSrn to zerobranch[.], block;* done w/ current test. allow emulator to run.\gp,>$N bAq a1 _p]Kq+\Y+%XU+*W'+" US_ R"pPqONiM, J/Is+(H6+E+D}C@p+ Bq+&@ >JG;+!: 9Tpq8654^1+0+#/h ,pq+)4'+ &pq%|#+- !p  q+H +R+ + p \qf ) p  q p + 3+. >]memPipeAndFaultA.mcJune 17, 1981 8:49 AM%8set[xtask, 0];\gp,>$NbAq : _!shmemPipeAndFaultA.mcJune 17, 1981 8:49 AM%9* June 3, 1981 5:46 PM%This subroutine checks to see if the contents of Pipe2 are correct:numFaults, firstFaultSRN, refType, subTask (must be 0), task (mustbe current task), EmuFault (must be 0)ENTRY:rscr=numFaults we expectrscr2=refType we expectt=firstFaultSRN (if numFaults #7)on ERROR:Arlink points to the caller of this subroutineUSE:T, rscr, rscr2, rscr3, Arlink, Q%apChkPipe2: subroutine;* rscr=numFaults, rscr2=ref type, t=1st FaultSRNrscr3_t;* save firstFaultSRN for a whileSaveReturn[Arlink];t_ not(Pipe2');* Check nFaults for correctnesst_t and (pipe2.nFaults);rscr_ (rscr)-1;* mem system keeps nFaults-1 in piperscr_ (rscr)AND (7c);* so we decrement and mask to do samerscr_ lsh[rscr, pipe2.nFaultsShift];t # (rscr);skpif[ALU=0];apChkP2Err1:* nFaults in Pipe2 does not match expectederror;* value. See caller of subroutine.* IF nFaults=7 (same as mask value) then we don't check firstFaultSRNt # (pipe2.nFaults);branch[apChkP2Cont, ALU=0], t_ not(Pipe2');t_ t and (pipe2.faultSrn);t # (rscr3);* rscr3=expected value of firstFaultSRNskpif[ALU=0];apChkP2Err2:* firstFaultSRN does not match expectederror;* value. See caller of subroutine.t_not(Pipe2');apChkP2Cont:rscr3_ t;* copy Pipe2 into rscr3.* check task=current taskcall[apGetTestTask];rscr_ lsh[t, pipe2.taskShift];* we're done w/ numFaults so rscr is freet_ (rscr3) and (pipe2.task);(rscr)#t;skpif[ALU=0];apChkP2Err3:* Expected task (rscr, shifted) is noterror;* same as one in Pipe2 (t). See caller of subroutine.* Check subtask=0;t_ (rscr3) AND (pipe2.subTask);skpif[ALU=0];apChkP2Err4:* Subtask should always be zero inerror;* memPipeAndFaultA. See caller of subroutine.* Check refType= rscr2;t_ (rscr3) AND (pipe2.refType);rscr2_ lsh[rscr2, pipe2.refTypeShift];t#(rscr2);skpif[ALU=0];apChkP2Err5:* ref type (rscr2, shifted) does not match\gp,>$N bAq a _C^B]K& ZYXUW! TS_. PO Ni Kp q +0J+IsH6 EC@B+$@+%?$>J = ;p +q*:+" 8E54^+3 1 +'0 /hp +q'.*+#, *rp )4q+ &$>#+)! H  p +q&+6 R \p +q"+. ) &  p 3p +q*B D1]memPipeAndFaultA.mcJune 17, 1981 8:49 AM%10error;* value in Pipe2.* Check EmuFault=0t_ (rscr3) AND (pipe2.emuFault);skpif[ALU=0];apChkP2Err6:* Emulator fault bit is true, should be false.error;* see caller of subroutine.returnUsing[Arlink];\gp,>$NbAq+ _]K\ Zp +q.Y+W U>T8memPipeAndFaultA.mcJune 17, 1981 8:49 AM%11* June 3, 1981 5:46 PM%Check FaultInfoThese routines check the values in faultInfo. ALL OF THEM ASSUME rscr=FaultInfo. Examine subroutinecaller to determine how error was invoked.apChkProcSrn checks that rscr2=expected ProcSrn= faultInfo.procSrnapChkAsrn checks that rscr2=expected Asrn=faultInfo.asrnapChkFaults checksrscr2=numFaults=faultInfo.numFaultst=firstFaultSRN=faultInfo.firstFaultSRN (if numFaults#7)emuFault is 0%mc[faultInfo.ProcSrn, b0,b1,b2,b3];set[faultInfo.ProcSrnShift, 14];apChkProcSrn: subroutine;* ENTER: rscr=FaultInfo, rscr2=expected ProcSrnsaveReturn[Arlink];rscr2_ lsh[rscr2, faultInfo.ProcSrnShift];t_ (rscr) AND (faultInfo.ProcSRN);t # (rscr2);skpif[ALU=0];apChkProcSrnErr:* ProcSRN should be same as expected val.error;* see caller of subroutine.returnUsing[Arlink];apChkAsrn: subroutine;* rscr=faultInfo, rscr2=expected AsrnsaveReturn[Arlink];rscr2_ lsh[rscr2, faultInfo.asrnShift];t_ (rscr) and (faultInfo.asrn);t#(rscr2);skpif[ALU=0];apChkAsrnErr:* expected ASrn (rscr2, shifted) not sameerror;* as one in FaultInfo (t). See caller of subroutine;returnUsing[Arlink];apChkFaults: subroutine;* rscr=faultInfo, rscr2=numFaults, t=rscr3_t;* SRN for first fault. NOTE: if numFaultssaveReturn[Arlink];* is 7 (means no faults) then don't check* firstFaultSRNrscr2_ (rscr2)-1;* Memsystem uses nFaults-1, so we dorscr2_ (rscr2) and (7c);* the same thing!rscr2_ lsh[rscr2, FaultInfo.nFaultsShift];t_ (rscr) AND (faultInfo.nFaults);t # (rscr2);skpif[ALU=0];apChkFaultsErr1:* expected num faults (rscr2, shifted)error;* doesn't match faultInfo (t). See caller ofsubroutine.(rscr2) # (faultInfo.nFaults);* if nfaults=mask value, then don'tbranch[apChkFaultsCont, ALU=0];* check value of firstFaultSRN.t_ (rscr) AND (faultInfo.faultSrn);t # (rscr3);skpif[ALU=0];apChkFaultsErr2:* expected first fault srn doesn't matcherror;* fault info. See caller of subroutine.noop;* for placement limitationapChkFaultsCont:t_ (rscr) and (faultInfo.emuFault);skpif[ALU=0];apChkFaultsErr3:* don't expect emulator faultserror;returnUsing[Arlink];\gp,>$N bAq a _ ]Ke \* YB XU8 WU#T8S_ P Ni# M, Jp q +/IsH6*F"E D} C@p+q)B+? = p q +%;:'9T8 6 5p +q)4^+51 /hp q +%.*+*,+)++*r+$)4+'*&"%| $> #p+q&!+-  +#+R#  p+q(\+'+ pqf#) p+q  30 D]&memPipeAndFaultA.mcJune 17, 1981 8:49 AM%12\gp,>$N, `!s*memPipeAndFaultA.mcJune 17, 1981 8:49 AM%13*August 24, 1978 3:18 PM%iapMemoryForce the munch containing mem[0:17B] into the cache and remove the mucnch containing mem[20B:37B]from the cache. Remember that increments of 1000B do not change the row address in the cache for amemory location.%iapMemory: subroutine;saveReturn[Arlink];cnt _ 17s, t_a0;iapMemL1:loopUntil[CNT=0&-1, .], t _ (Store_t)+1, DBuf_ t;cnt _ 10s;t _ 20c;noop;* for MicroDt _ t + (1000c);iapMemL2:STORE _ t, DBuf _ t;loopUntil[CNT=0&-1, iapMemL2], t _ t + (1000c);returnUsing[Arlink];\gp,>$N bAq a+_p ^qb ]Kb \ Z Yp q XUW UpTq1R" POp+ Niq KpJqIs/H6* FB!6hmemPipeAndFaultA.mcJune 17, 1981 8:49 AM%14* June 16, 1981 4:07 PM%iapFltTaskThis subroutine initializes the fault task for the memory pipe and fault diagnostics. The fault taskcode examines makingFaults, an RM flag set by the diagnostics to determine what to do if there's beena fault.IF makingFaults is true, tpc[testTask]_@testTaskContinueLoc; otherwise, there's been an error. Thefault task uses the aMakingFaults Rbase.%iapFltTask: subroutine;saveReturn[iapFltTskRtn];t _ FaultInfo'[];* clear any waiting wakeupscall[setMcr],t_mcr.noSeWake;* set mcr for wakeupscall[getFaultTaskLoc];subroutine;* link _ code loc from getFaultTaskLoct _ 17c;* the fault task is task 17top level;LdTPC _ t;noop;* for microDcall[notifyTask];* t = task to notify;noop;* wait to assure it has runreturnUsing[iapFltTskRtn];getFaultTaskLoc: subroutine;coreturn;branch[faultTask];set[xtask, 1];top level;faultTask:RBASE _ rbase[aMakingFaults];taskingOn;apFltTaskL:block;(aMakingFaults)-1;* see if apMakeNfaults caused this faultbranch[apFltTask1, alu=0];error;* AWAKENED WHEN aMakingFaults NOT valid !!!!apFltTask1:* come here if apMakeNfaultst _ not(FaultInfo');* block won't work until we do thisQ_t;branch[apFltTaskL];* wait extra cycle before blockingset[xtask, 0];knowRbase[defaultRegion];\gp,>$N bAq a*_p ^qd ]Ke \ Zb Y( XU Tp q S_R"+P+ONi +&M,+K J Is+ H6+F+E C@pq B@>J = ;p :q9T 6p 5q4^+(3 0+, .*p +q,+#+*r+"' & %YDBmemPipeAndFaultA.mcJune 17, 1981 8:49 AM%15* June 17, 1981 8:49 AM%apMakeNFltsMake a series of faults in the pipe. Enter with T = the number of faults to make. ENTER W/MCR.noWake!!! Once the fault task wakes up because of a memory wakeup, it cannot go to sleep againwithout performing _FaultInfo,and THAT will reset nFaults which screws up the diagnostics.%mc[largerThanCacheC, 4000];* this value should be larger than the cacheapMakeNFlts: subroutine;saveReturnAndT[Arlink, AsubrScr];rscr_ t_ 1c;call[setBR], rscr2_ t;* set BR to 1,,1 to cause faults on our refsaMakingFaults _ t;* aMakingFaults _ 1, to notify fault task* that our faults are ok.call[getAsubrScr];t _ t - 1;* remove one 'cause we test at end of loopcnt _ t;apmakeNFltsL:FETCH _ t;* this reference causes a faultrscr _ MD;t_ t+ (largerThanCacheC);,loopUntil[CNT=0&-1, apMakeNFltsL];rscr_a0;call[setBR], rscr2_a0;* reset BR to usual valueaMakingFaults _ a0;* disalow further faultsreturnUsing[Arlink];iapMap: subroutine;pushReturn[];* This emulator subroutine sets up the map so thatpages w/ BRHI=1 are vacant. This makes is easy to guarantee that apMakeNFlts will cause faultsrscr2_a0, cnt_ 17s;iapMapL:rscr_1c;call[setBR];* rscr=brHi, rscr2=brLOrscr_3c;* wp+dirty means vacantcall[writeMap];* leaves rscr2 as it isloopUntil[CNT=0&-1, iapMapL], rscr2_ (rscr2)+(largerThanCacheC);returnP[];\gp,>$N bAq a*d_p ^q[ ]Kc \ Z< Y XU+, Wp q U!T S_+,P+) OM,J +*Is H6p Fq +E D}C@"@?+>J+=  :pq 9T +2 8`5 3 p1q0 +/h+.*+,@*r R )C/>memPipeAndFaultA.mcJune 17, 1981 8:49 AM%16* June 2, 1981 10:18 AM%loop controls, misc subroutines%mc[maxTestTaskC, 16];iapTestTask: subroutine;return, aTestTaskX _a0;apNextTestTask: subroutine;saveReturn[Arlink];RBASE _ rbase[aTestTaskX];t _ aTestTaskX _ (aTestTaskX) + 1, RBASE _ rbase[defaultRegion];noop;* for MicroDrscr _ t - (maxTestTaskC);returnAndBranch[Arlink, rscr];apGetTestTask: subroutine;RBASE _ rbase[aTestTaskX];return, t _ aTestTaskX, RBASE _ rbase[defaultRegion];mc[maxNfaultsC, 7];* nFaults IN [0..maxNfaultsC)iapNFlts: subroutine;return, aNfaultsX _ a0;apNextFltX: subroutine;saveReturn[Arlink];RBASE _ rbase[aNfaultsX];t _ aNfaultsX _ (aNfaultsX)+1, RBASE _ rbase[defaultRegion];noop;* for MicroDrscr _ t - (maxNfaultsC);returnAndBranch[Arlink, rscr];apGetFltX: subroutine;RBASE _ rbase[aNfaultsX];return, t _ aNfaultsX, RBASE _ rbase[defaultRegion];iapNFlts2: subroutine;return, aNfaultsX2 _ a0;apNextFlt2: subroutine;saveReturn[Arlink];RBASE _ rbase[aNfaultsX2];t _ aNfaultsX;rscr _ t+1;t _ aNfaultsX2 _ (aNfaultsX2)+1, RBASE _ rbase[defaultRegion];rscr _ t - (rscr);returnAndBranch[Arlink, rscr];apGetFlt2: subroutine;RBASE _ rbase[aNfaultsX2];return, t _ aNfaultsX2, RBASE _ rbase[defaultRegion];\gp,>$N bAq a#_p ^q ]Kp q \p q Z XUpq WUT@S_p+ R"qP Op q NiM,5 Jp q+ H6pq F Ep q D}C@B<@p+ ?q>J = p q ;:4 8p q 6 5p q 4^3 1 0 /h>.*, *rp q )4'5 &3eAumemPipeAndFaultA.mcJune 17, 1981 8:49 AM%17* June 3, 1981 11:52 AMmc[maxSrnC, 20];* Asrn IN [1..20)set[xtask, 1];aSetAsrnForWrite: subroutine;saveReturnAndT[Arlink, AsubrScr];t_ lshift[300,10]C;TIOA_t, t_a0;aSetAsrnL:IOFetch_t;rscr _ not(Config');rscr _ (rscr) and (config.Asrn);* isolate and rt justify current asrn valuecall[getAsubrScr];noop;* for MicroDrscr _ rsh[rscr, config.AsrnShift];(rscr) - t;loopUntil[alu=0, aSetAsrnL], t_a0;* gets incremented before it gets used againreturnUsing[Arlink];* June 2, 1981 10:19 AMaIncAsrn: subroutine;* cause Asrn to increment. Accomplish this* by writing the map. The subroutine that writes the map also clobbers BR so this routine mustregenerate BR as well.t_ lshift[300,10]C;TIOA_ t;IOFetch_ t;RETURN;iapSrn: subroutine;t _ (r0)+1;return, aSrnX _ t;apNextSrn: subroutine;saveReturn[Arlink];RBASE _ rbase[aSrnX];t _ aSrnX _ (aSrnX) + 1;RBASE _ rbase[defaultRegion];rscr _ t - (maxSrnC);returnAndBranch[Arlink, rscr];apGetSrn: subroutine;RBASE _ rbase[aSrnX];return, t _ aSrnX, RBASE _ rbase[defaultRegion];apIncSrn: subroutine;* Increment an Srn value. wraparound to 2t _ t+1;* when new srn>17B. Note: enter w/ T =t-(20c);* current srn valueskpif[alu#0];t _ 2c;return;apDecSrn: subroutine;* decrement an Srn value. wraparound to 17t _ t-1;* when new srn=1. Note: enter w/ T =Pd_ t-1;* current srn valueskpif[alu#0];t _ 17c;return;\gp,>$N bAq apq+_ ^pq ]K!\Z XUp Wq UT++S_R"p+ Pq#O Ni"+,K Is H6pq F* E^ D}TC@TBT@ T? = pq T; T: 9Tp q T8T6T5T4^T3 T1 0pq T/hT.*0 +pq j)T*r.&T)4.T' T&T%| $>pq j*T#.$T!.T THT d m?LmemPipeAndFaultA.mcJune 17, 1981 8:49 AM%18* August 27, 1978 7:51 PM* apSaveT0Tpc* Save tpc[0] in apSavedT0Tpc so that a non emulator task can briefly* "run" as the emulator (so it can perform map_ operations).* apRestoreT0Tpc*Restore tpc[0] that is stored in apSavedT0Tpc* apSetTpc*t = task, rscr = locationapSaveT0Tpc: subroutine;saveReturn[apSaveT0TpcRtn];zeroHold[rscr2];RdTpc _ r0;t _ link;apSavedT0Tpc _ t;* we've stashed tpc[0] into apSavedT0Tpccall[resetHold];returnUsing[apSaveT0TpcRtn];apRestoreT0Tpc: subroutine;saveReturn[apSaveT0TpcRtn]; noop;* for MicroDRBASE _ rbase[apSavedT0Tpc];t _ apSavedT0Tpc, RBASE _ rbase[defaultRegion];rscr _ t;call[apSetTpc], t _ r0;noop;* for MicroDreturnUsing[apSaveT0TpcRtn];apSetTpc: subroutine;* t = task number, rscr = IM locationsaveReturnAndT[apSetTpcRtn, rscr2];noop;* for MicroDzeroHold[t];t _ rscr2;subroutine;link _ rscr;top level;LdTpc _ t;noop;* for MicroDcall[resetHold];returnUsing[apSetTpcRtn];\gp,>$N bAq _ ^TC ]K< Z YT- W UT S_p q TR"TPTO TNiTM,j(TKTJ H6pq TF ET TC@TB/T@T?T>J T; 9Tpq j%T8#T6 T4^ T3 T1 T0 T/h T.* T, T+T)4 '/@7memProcA.mcJune 17, 1981 11:08 AM%1title[MemProcA];top level;%June 17, 1981 11:08 AMCreate this fileA FEW RULESSubroutines clobber rscr, rscr2 and T unless otherwise specified at both point of call and insubroutine description. Subroutines return single values in T, and they accept single values in T. Twoparameter subroutines accept their values in rscr and rscr2.Global values for S boardAbbreviations used hereiniInitMMapcolColumnSStorageaAllpPipeapAllPipe (test pipe, use all of memory system)nextFooincrements foo loop variable, returns with fast branchcondition to check for done w/ loopgetFooreturns current value of loop variable, foogetFooRtnsubroutine that returns in T the saved value of foo'sreturn linkiFooCtrlinitialize foo loop control%gp );N bAq a ]K \Z*dYp Wq] Uf T< S_ POp+qNip+qM,p+qKp+qJp+qIsp+qH6p+q-Fp+q6E#D}p+q+C@p+q5B @p+q ? >'E3)memProcA.mcJune 17, 1981 11:08 AM%2* June 17, 1981 11:08 AM%Test MD path in shifter/maskerThe Shifter/masker allows the processor to deposit an arbitrary sized field into a word coming fromMD. This test checks that these things all work. We assume that kernel's shifter test has alreadyrun. That test assures that the shifter works properly.This test checks that the MD data paths associated witht he shifter work%* June 17, 1981 11:16 AM%aProcShifterThis test checks parts of the map that require all the boards of the memory system.Check the ref bit (only set when a page is actually referenced)Check that wp (write protect) bit causes page faultsRSCR3= original contents of current map entryRSCR4= current page in Map%aProcShifter:pushReturn[];call[disableConditionalTask];* don't run HOLD simulatorcall[iSboard];* init Sboard in case its not happened alreadycall[getMemState];t AND (memState.aProcShift);* see if our test is enabledbranch[aProcShifterXit, ALU=0];noop;rscr_a0;call[setBR], rscr2_ a0;Store_rscr, DBuf_rscr, t_ a1;Store_1s, DBuf_ t;Fetch_ 0s;* get md=zerot_ DpF[t,1,0,Md];* isolate 1 bit (b15) in t and add to Mdt # (1C);skpif[ALU=0];aProcShiftErr1:* we expect all zeros becauseerror;* Md is zero and the field was 0 lengtht_a1;t_ DpF[t, 1,17, Md];* isolate 1 bit (b0) in t and add to Mdt # (100000C);skpif[ALU=0];aProcShiftErr2:error;Fetch_1s, t_ a0;t_ DpF[t, 1,0, Md];* isolate one zero bit (b15) and add to Md(t) # (177776C);;skpif[ALU=0];* we expect all ones becauseaProcShiftErr3:* Md is all ones and the field was 0 lengtherror;t_ DpF[t, 1,17, Md];* isolate one zero bit (b0) and add to Md(t) # (77777C);skpif[ALU=0];* we expect all ones becauseaProcShiftErr4:* Md is all ones and the field was 0 lengtherror;noop;aProcShifterXit:returnP[];gp );N bAq a$_p ^qc ]Kc \8 ZH XU W U*Tp S_qS P? O4 M,- K J H6p Fq E+D} +.C@B+@?= ;:9T8 + 5+(4^3 1p+q0+'.*,+'+ *r )4p'q%|$>+*#! + p+q+H+)R + p+q+ pq  C/YMODEL 1: memrwC.mcFebruary 5, 1981 5:57 PM%1title[memrwC];top level;%February 5, 1981 5:57 PMAdd toplevel decl to singleStep to satisfy micro.September 19, 1979 6:23 PMMove beginCTest to beginning of file, call disableConditionalTask from beginCtest, addtable of contents, remove surplus code from cacheComprTest. Add lost mods that constructed and usedccColWrite (to save space & simplify the logic) -- changed cacheAddr and cacheCompr.%%*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++TABLE OF CONTENTS, by order of OccurencebeginCtestControl subroutine that calls the tests in thi filecPipeVA:Test the low 16 bits of the pipecBRrwTest:Test all the bits of the base registerscacheAddr:Test the Cache A-MemorycacheCompr:Test the cache comparatorsccColWrite:Subroutine to write Cache A.cFlagsTest:Test cache flags memorycacheAddrTest:Cache A addressing testsetCAAF:Set current cache location and cache flags to all onesresadCurrentCFlags:Read "current" value of CFlagsreadOldCflags:Read "old" value of CFlagsreadCurrentCAmem:Read current Cache AmemoryreadOldCAmem:Read "old" value of CacheA memory%*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++Zgp+?&N bAq a _ ^]K1 \ZV Yd XUT W UP Tp( S_ q3 R"pq Pp q' Op q Nip q M,p q Kp q Jp q Ispq6 H6pq Fp q Epq D}p q! C@P AC&,MODEL 1: memrwC.mcFebruary 5, 1981 5:57 PM%2* September 19, 1979 7:14 PMbeginCtest: top level;* FIRST TEST IN MEMRWCpushReturn[];call[disableConditionalTask];call[cPipeVa];* test pivpe vacall[cBRrwTest];* test base registerscall[cacheAddr];call[cacheCompr];call[cFlagsTest];call[cacheAddrTest];returnP[];Zgp+?&N bAq `p q +p_\q ^\ +[+ZfY)WVUp 4 T.GMODEL 1: memrwC.mcFebruary 5, 1981 5:57 PM%3* February 5, 1981 5:57 PMset[xtask,1];* NON EMULATOR!!!set[sslocC,210]; mc[ssloc,sslocC];singleStep:* INIT SINGLE STEP CODEtaskingon;t_mcr.disBr;* turn off base registers, cache flagst_t+(mcr.disCF);loadmcr[t,t];t_ssloc;link _ t; toplevel;ldtpc _ r1;notify[1];noop;noop;branch[emulMem];ssHere:rbase _ 17s, at[sslocC];* init our rbasebreakpoint,t_r1;* begin single step. t controls blocking* set t to zero when donememAsel:*map _ r01;* ASEL=0, FF[0:1]=0. FF OK (emulator)set[xtask, 0];store_ID;* ASEL=0, FF[0:1]=1. FF OKset[xtask, 1];store _ t;* ASEL=0, FF[0:1]=2. FF OKstore _ r01;* ASEL=0, FF[0:1]=3. FF OKmemAsel1:preFetch_r01;* ASEL=1, FF[0:1]=0. FF OKset[xtask, 0];fetch _ ID;* ASEL=1, FF[0:1]=1. FF OKset[xtask, 1];fetch _ t;* ASEL=1, FF[0:1]=2. FF OKfetch _ r01;* ASEL=1, FF[0:1]=3. FF OKmemAsel2:*ioStore_t;* ASEL=2, FF[0:1]=2. FF OK (emulator)ioStore_r01;* ASEL=2, FF[0:1]=3. FF OKmemAsel3:set[xtask, 0];dummyRef_r01;* ASEL=2, FF[0:1]=0. FF OKFetch_ID;* ASEL=2, FF[0:1]=1. FF OKset[xtask, 1];ioFetch_t;* ASEL=2, FF[0:1]=2. FF OKioFetch_r01;* ASEL=2, FF[0:1]=3. FF OKmemAselNotOK:store_r01, t_1c;* ASEL=0, FF not OKfetch_r01, t_1c;* ASEL=1, FF not OKt_t;* test to see if we should blockskpif[alu#0];tsk1quit:goto[.],block;branch[memAsel];* EMULATOR ASEL CHECKOUT COMES HEREset[xtask,0];emulMem:map _ r01;* ASEL=0, FF[0:1]=0. FF OKFlush_r01;* ASEL=2, FF[0:1]=0. FF OKbranch[emulMem];afterSingleStep:Zgp+?&N bAq _ + ^" ]Kp q+\ Z +&YXU WU TS_ R" PONi M,pqK+J+( Is H6pq F +%E D}+C@ B +@ + ?pq>J += ; +: 9T +8 + 5pq 4^ +%3 + 0pq/h .* +,++ *r +)4 + &p q%|+$>+#+! pqH   # R pq + +\ pq :UM-MODEL 1: memrwC.mcFebruary 5, 1981 5:57 PM%4* September 13, 1979 4:37 PM% CHECK PIPE VA BITS!!!First disable base registers and init cnt to allow 20B iterations.Then perform a dummyRef once for every bit on marMux (1, 2, 4, 10, etc). Note that the value storedwith dummyRef is kept in rscr, the value read from pipe1 is kept in rscr2. This code need not besingle stepped.%cpipeVA:pushReturn[];checkMtest[memFlags.cPipeVA, cPipeVaDone];cnt _ 17s;* loop control: once for each bitrscr _ r1;* RSCR begins w/ 1T_mcr.disBr;T_T+(mcr.disCf);t _ t OR (mcr.noRef);call[setMCR];* DISABLE BASE REGISTERScpipeVAl:dummyRef _ rscr;* RSCR goes to pipenoop;t_pipe1;rscr2_t;* rscr2 gets pipeVAt_t#(rscr);* t _ pipeVA xor RSCRskpif[alu=0];cPipeVAerr:* t = bad bits, rscr = value we wrote intoERROR;* pipe, rscr2 = value from pipeloopuntil[cnt=0&-1, cPipeVAl], rscr_(rscr)+(rscr);* shift left test value by onecPipeVaDone:returnP[];Zgp+?&N bAq a _]KB \c Z` Y XU UpqT S_*R" +!P +O NiM,K + IspqH6+FED}+C@ +B @p +q*?+= 22 :p 9Tq  7C/0MODEL 1: memrwC.mcFebruary 5, 1981 5:57 PM%5* March 17, 1978 8:32 AM% CHECK BASE REGISTER BITSFOR BR IN [0..31] DO-- once for every base registerFOR brhi _ 1,brhi+brhi UNTIL brhi = BrHiEndC DO-- once for each bitFOR brlo _ 1, brlo+brlo UNTIL brlo = 0 DO-- once for each bitwriteBR[br, brhi, brlo];IF pipe1 # brlo THEN ERROR;if pipe0.va # brhi THEN ERROR;ENDLOOP; ENDLOOP;ENDLOOP;%cBRrwTest:pushReturn[];checkMtest[memFlags.cBR, cBRdone];Q _r0;* Q = base register being testedt_(37c);cnt _ t;* cnt controls Q-loopt_rscr _ r1;* rscr = brHIrscr2 _ t;* rscr2 = brLOt_mcr.disCf;t _ t OR (mcr.noRef);call[setMCR];* reenable base registersbrL:noop;call[setMbase],t_q;noop;brWriteHiL:* come here from incrementing brHi=rscrbranch[brWriteLoL];* instruction for placementbrWriteLoL:* come here from incrementing brLo=rscr2branch[brl2];brl2:CALL[setBR];* rscr =>brhi, rscr2 => brlodummyref _ r0;* force pipe entrynoop;t _ pipe1;* pipe1 = VA[8:23] = low 16 bitst _ t #(rscr2);skpif[alu=0];cbrLow16ER:* rscr2=value written into BrLo, t=bad bitserror;* q = current base register being testedt_pipe0;t_t and(CABitsInPipe0Mask);t_t#(rscr);skpif[alu=0];* rscr = value written into brhi. t = badcbrHi8ER:* bits that came back.error;* q = current base register being testedbrLoopCtrl:t_(rscr2)+(rscr2);* increment and check brloloopuntil[alu=0, brWriteLoL],rscr2 _ t;rscr2 _ r1;* reset brlo, increment and check brhit_(rscr)+(rscr);t#(BrHiEndC);loopuntil[alu=0,brWriteHiL],rscr_t;rscr _ r1;* reset brhi, increment and check BRt_(r1)+(q);loopuntil[cnt=0&-1, brL],q_t;cBRdone:returnP[];Zgp+?&N bAq a _ ]K+\/0ZZ)+YXUWU T S_ PpqO Ni"M,+KJ+Is + H6 + F ED} + C@pqB@? >Jp q+'= + ;p q+(: 9Tpq8 +6 +54^ +3 1 0p q++/h+(,+*r )4 +) 'pq+&+( $>p q#+!'H +&  # +$  pq  J+!;:9T+ 6P 5` 4^e 3 b 1) 0P/h.*,++ *rp+q$)4+ & $>p #q!= H pq Rpq p q r 9DRMODEL 1: memrwC.mcFebruary 5, 1981 5:57 PM%12* September 19, 1979 6:57 PMccColWrite:% Write current (col) column with current pattern inthe row specified by Q. We xor (rscr) with the current pattern. This produces the current patternwhen rescr=0 an, the complement of the current pattern when rscr=-1, and (probably) a bug otherwise.%pushReturnAndT[];t_mcr.fdMiss;t_t OR (mcr.noRef);call[mcrForCol];* set up mcr for current column, other flags aredefaulted by mcrForColcall[getCPattern];* knows about Q, SHC, current patterncall[setBrCacheAbits], t_(stack&-1)#t;* get CPattern retukrned value in Tcall[vaForRow], t_q;DBuf_r0, Store_t;* write proper cache entryreturnP[];Zgp+?&N bAq `p +q4 _\c ^d \wZY XUW+0 US_+%R"&+#ONi+M,  KaC[MODEL 1: memrwC.mcFebruary 5, 1981 5:57 PM%13* November 30, 1977 10:04 AM%TEST CACHE FLAGS: TREAT THEM LIKE A MEMORYFor each column and row entry in the cache, test all the possible cache flag values. The enigmaticmethod for reading and writing the cache flags reflects the fact that the flags weren't designed to beread and written like a memory.Basically, write the cache flags as follows:Turn on fdMiss, disHold, enable the flags and the base registers. Use useMcrV to select thecurrent column. PRESUME the cflags value has been left shifted by four to allign it with theproper position in the cache.Let va = vaForRow[row] - flagsValue, and write the low 16 bits of the current base registerwith va. Now write the value as follows:dummyREF _ flagsValue;CFLAGS _ flagsValue;To read the flags, the current contents of the A memory must be known and there must not betwo hits in the cach when the reference occurs:Disable hold, enable the flags, use UseMcrv to force a different column for the victim.Perform,dummyREF _ va; pipe5 _ pipe5[];where the pipe5[] occurs in the next instruction and va[0:14] are known to be in the A memoryof the cache. Check that col = the column that should have matched and not the column that waschosen as victim.FOR flagsV _ 0, flagsV+20B UNTIL 1000B DO -- generate vals properly positionedFOR row IN Row DOuseFlags _ flagsV;FOR col IN Col DO-- first, initialize the current row so that subsequent efforts to read the cache flagsthat have been written will not result in two hits in the cachesetBr[0];va _ vaForRow[row];setMcrForCol[fdMiss, disHold, col2];va _ va+1000B;DBuf_0,STORE_va;setMcrForCol[fdMiss, disHold, useMcrv, mcrv=col2];-- now write a different flags pattern into the current column so that each column ofthe row will have a different value, a value not same as the one being testedsetBr[va-useFlags];dummyRef _ useFlags;CFLAGS _ useFlags;useFlags _ useFlags+minFlagVal;IF useFlags > maxFlags THEN useFlags _ minFlagVal;ENDLOOP;-- now check ituseFlags _ flagsV;FOR col IN Col DOsetMcr[disHold, useMcrv, mcrv:~col];va _ vaForRow[row] + col *1000B;setBR[va];dummyRef _ 0;pipe5 _ pipe5;IF pipe5.col#col THEN ERROR;fval _ pipe5 AND cFlagsMask;IF (fval # useFlags) # 0 THEN ERROR;useFlags _ useFlags+minFlagVal;IF useFlags > maxFlags THEN useFlags _ minFlagVal;ENDLOOP;-- end col loopENDLOOP;-- end row loopENDLOOP;-- end flagsV loop%Zgp+?&N bAq a_\p* \wqb [:f Y XU,V[Up\T3R[QN(ONiL\K/IWHFEQ]D^B A.N?=<:W9?865$4^ 3 120;U.M-V,*)(`2'#$>!Y t$7  ~ A$K2 +f++  N ME3\MODEL 1: memrwC.mcFebruary 5, 1981 5:57 PM%14* March 14, 1978 11:16 AM* INIT cache flags read/write testcFlagsTest:* read and write cache flagspushReturn[];checkMtest[memFlags.cFlags, cfTestDone];call[setMbase],t_r0;* MEMBASE _ 0call[initFlagsCtrl];cfL:* MAIN outer LOOPcall[nextCFlag];branch[cfTestDone,alu=0];flagsV _ t;call[initRowCtrl];cfRowL:* top of row loopcall[getCflag];* restore flagsV since cfColReadLflagsV _ t;* clobbers itcall[nextRow];* check for next rowskpif[alu#0];branch[cfl];* try next set of flagsq_t;* keep row in QcfColInitL:* top of column loopcall[initColCtrl];cfColWL:* top of row write loopcall[nextCol];branch[cfBeginCheck, alu=0],col_t;rscr _ col;call[cVaForCrowCol], t _ q;* get unique va for this row/colva _ t;call[setCAmem];* va = addr, col = columnrscr _ flagsv;call[setCFlags], t _ va;* set the flags for this col/rowcall[incFlagsV];* get unique flags for each columnbranch[cfColWL];cfBeginCheck:call[initColCtrl];* init column loop controlcall[getCflag];* reset flagsV to current valueflagsV _ t;cfColReadL:* top of column read/check loopcall[nextCol];skpif[alu#0], col_t;branch[cfRowL];* no more cols, try next rowrscr _ col;call[cVaForCrowCol], t _ q;* get unique va for this row/colva _ t;* save the varscr2 _ col;call[readCflags], rscr _ t;* returns w/ pipe5 in T%*------------------------------------------------------------------------------membase+va = the address we referenced. The value in va selects the cache row, and the value inmembase gets us to the correct column in the row (because the cache row has been written with uniqueaddresses for each column). Q=current row, col = current column (both in the cache). FlagsV containsthe value we wrote into the cache flags for the current row and column.%*------------------------------------------------------------------------------rscr _ t;call[chkPipe5Col], t _ col;* expects rscr = pipe5, t = colskpif[alu=0];* bad column. bad bits in T, pipe5 in rscrcfBadCol:error;* expected val in colcall[chkCflags],t_flagsV;* check for proper cflags in rscrskpif[alu=0];* t = bad bits, flagsV = expected bits,cfBadFlags:error;* rscr = pipe5call[incFlagsV];* adjust for unique flagsV for each colbranch[cfColReadL];incFlagsV: subroutine;FlagsV _ (FlagsV) + (cflags.beingLoaded);* better be least signf. bit!Zgp+?&N bAq+# ap +q_ ^(]K+ \ Zp+qYXUW U S_p+qR"+!P + O +Ni M, +K+p Is +qH6 Fp+qE D}"C@ B+@?+>J = +;+": 8p 6q+5+4^ 1p +q0 /h.*++ *r+)4+ ' &+ $>P #` !d f HG  P+R +* pq+\+! +' p q+ )+'  pp q  3)+ E3]EMODEL 1: memrwC.mcFebruary 5, 1981 5:57 PM%15FlagsV _ (FlagsV) AND (cflags.mask);skpif[alu#0];FlagsV _ (cflags.beingLoaded);return;top level;cfTestDone:returnP[];Zgp+?&NbAq$a _^]K \p Zq Yp#w2MODEL 1: memrwC.mcFebruary 5, 1981 5:57 PM%16* February 21, 1978 6:53 PM%Cache Addressing TestThis test checks that the addressing mechanism (as opposed to the bits that hold cache address values)works. The algorithm works as follows:Zero the amemory and the cacheAscend thru the amemory and cach flags: check that the current value is zero and then set itto -1. If the current value is not zero, an earlier store clobbered this entry. In this caseperform the "find UP" check test.Zero the amemory and the cache flagsDescend thru the amemory and cache flags: check that the current value is zero and then set itto -1. If the current value is not zero, an earlier store clobbered this entry. In this caseperform the "findDOWN" check testOtherwise, the addressing works.Find UP: zero the amemory and the cache flags.Ascend thru the amemory and cache flags: before setting the current location to -1 check thatthe earlier clobbered location is still zero. If it is not zero, the previous store clobberedthat location.FindDown: same as findUP except descend thru the amemory and cache flagsZeroCacheAndFlags[];FOR row IN Row DOFOR col IN Col DOIF cache[row,col] #0 THEN findErrUp[row,col];IF cacheFlags[row,col] #0 THEN findErrUP[row, col];cache[row,col] _ -1;cacheFlags[row,col] _ -1;ENDLOOP;ENDLOOP:zeroCacheAndFlags[];FOR Row DESCENDING IN Row DOFOR col IN Col DOIF cache[row,col] #0 THEN findErrUp[row,col];IF cacheFlags[row,col] #0 THEN findErrUP[row, col];cache[row,col] _ -1;cacheFlags[row,col] _ -1;ENDLOOP;ENDLOOP:-- These are subroutines used in the "addressing test" shown above.findErrUp: PROCEDURE[r: Row, c: Col] =BEGINzeroCacheAndFlags[];FOR row IN Row DOFOR col IN Col DOIF cache[r,c] #0 THEN Signal CacheAddrUp[r,c, row-1, col-1];IF cacheFlags[r,c] #0 THEN Signal CacheAddrUp[r,c,row-1, col-1];cache[row,col] _ -1;cacheFlags[row,col _ -1;ENDLOOP:ENDLOOP:END:findErrDown: PROCEDURE[r: Row, c: Col] =BEGINzeroCacheAndFlags[];FOR row DESCENDING IN Row DOFOR col IN Col DOIF cache[r,c] #0 THEN Signal CacheAddrUp[r,c, row-1, col-1];IF cacheFlags[r,c] #0 THEN Signal CacheAddrUp[r,c,row-1, col-1];cache[row,col] _ -1;cacheFlags[row,col _ -1;ENDLOOP:ENDLOOP:END:%Zgp+?&N bAq a'_p ^qf ]K&\Z\Y\XU!W$U^T\S_!R"O.Ni]M,]K JH Is H6FE-D}3C@B@? >J = ;:-9T38654^ 1C 0&/h.*,+*r<)4@'&%|$># !( H <R@\ ~ E3W^MODEL 1: memrwC.mcFebruary 5, 1981 5:57 PM%17* March 14, 1978 11:17 AMcacheAddrTest:pushReturn[];checkMtest[memFlags.cAddr, catDone];call[zeroCacheAndFlags];call[initRowCtrl];catRowUpL:call[nextRow];* see if done going upskpif[alu#0];branch[catUpXit];* time to descend thru addressesq _ t;* KEEP ROW IN Qcall[initColCtrl];catColUpL:call[nextCol];* check if done w/ colsskpif[alu#0];branch[catRowUpL];* try next rowcol _ t;call[readCurrentCflags];skpif[alu=0];branch[catFindUpF];* flags were clobberedcall[readCurrentCAmem];skpif[alu=0];branch[catFindUpAd];* amem clobberedcall[setCAAF];* set amem and flags to -1branch[catColUpL];catUpXit:* ascending stores did not causes a detectableaddressing error. Try the same approach w/ descending addresses.call[zeroCacheAndFlags];call[initRowDown];catRowDownL:call[nextRowDown];skpif[alu#0];branch[catDone];q_t;* KEEP ROW IN Qcall[initColCtrl];catColDownL:call[nextCol];skpif[alu#0];branch[catRowDownL];col _ t;col _ t;call[readCurrentCflags];skpif[alu=0];branch[catFindDownF];* flags were clobberedcall[readCurrentCAmem];skpif[alu=0];branch[catFindDownAd];* amem clobberedcall[setCAAF];* set amem and flags to -1branch[catRowDownL];Zgp+?&N bAq ap _q ^$]K\ Yp XUq +W U+T+R" Pp Oq +Ni M,+ JIsH6 F+ED} C@+@ +? = p+q$p ;q@:9T 6p 5q4^ 3 1+/h .*p ,q + *r)4&%|$> #+! H+ +R ?OMODEL 1: memrwC.mcFebruary 5, 1981 5:57 PM%18* December 13, 1978 9:57 AMset[catPackShift, 3];* left shift the row value this much to make room forthe column (all in a "packed" va).catFindDownF:catFindDownAD:va _ q;* PACK row,,col INTO VAt _ col;va _ lsh[va, catPackShift];va _ (va) OR t;call[zeroCacheAndFlags];call[initRowDown];catRowFindDL:call[nextRowDown];skpif[alu#0];branch[catDone];q_t;* KEEP ROW IN Qcall[initColCtrl];catColFindDL:call[nextCol];skpif[alu#0];branch[catRowFindDL];col _ t;%*------------------------------------------------------------------------------These two errors indicate that the last time we wrote the cache A memory or the flags there was anaddressing error. Unfortunately this means the reader must determine what the address was "last time".Q = current row and col = current column. Subtract one from the column number to determine the lastaddress. If the column number goes negative, then the last column was 3 and the last row was currentrow +1 (this loop scans "down" the possible cache addresses). The packed va, contained in "va" may bedecoded as follows: The 3 least significant bits are the column number of the address that gotclobbered and the remaining bits are the row number. Hence, if va = 132, the clobbered address is row13 column 2.%*------------------------------------------------------------------------------call[readOldCflags];skpif[alu=0];catDownCFerr:* q=current row, col = current column,*va = packed, old, clobbered row,columnerror;* flags were clobberedcall[readOldCAmem];skpif[alu=0];catDownAmemErr:* q=current row, col = current column,*va = packed, old, clobbered row,columnerror;* amem clobberedcall[setCAAF];* set amem and flags to -1branch[catRowFindDL];Zgp+?&N bAq _p q+5 ^" \p Z Yq+XUWUS_R" Op NiqM, KJ+H6 Fp Eq D} C@B @P ?r6q >Jf = *pq1 ;d :pq_ 9T_ 8e 6 5P4^3 1p +q& 0&/h+,+ *rp+q& )4&'+%| +# !EFkMODEL 1: memrwC.mcFebruary 5, 1981 5:57 PM%19* December 13, 1978catFindUpF:catFindUpAD:va _ q;* PACK row,,col INTO VAt _ col;va _ lsh[va, catPackShift];va _ (va) OR t;* VA = row,,col of clobbered location.call[zeroCacheAndFlags];call[initRowCtrl];catRowFindUpL:call[nextRow];skpif[alu#0];branch[catDone];q_t;* KEEP ROW IN Qcall[initColCtrl];catColFindUpL:call[nextCol];skpif[alu#0];branch[catRowFindUpL];col _ t;%*------------------------------------------------------------------------------These two errors indicate that the last time we wrote the cache A memory or the flags there was anaddressing error. Unfortunately this means the reader must determine what the address was "last time".Q = current row and col = current column. Subtract one from the column number to determine the lastaddress. If the column number goes negative, then the last column was 3 and the last row was currentrow -1 (this loop scans "up" the possible cache addresses). The packed va, contained in "va" may bedecoded as follows: The 3 least significant bits are the column number of the address that gotclobbered and the remaining bits are the row number. Hence, if va = 132, the clobbered address is row13 column 2.%*------------------------------------------------------------------------------call[readOldCflags];skpif[alu=0];catUpCFerr:* q=current row, col = current column,*va = packed, old, clobbered row,columnerror;* flags were clobberedcall[readOldCAmem];skpif[alu=0];catUpAddrErr:* q=current row, col = current column,*va = packed, old, clobbered row,columnerror;* amem clobberedcall[setCAAF];* set amem and flags to -1branch[catRowFindUpL];Zgp+?&N bAq ap _ ^q+]K\Z+p$qXUW Tp S_q R" PO+M, Kp Jq Is H6F D}P C@r6q Bf @*pq1 ?d >Jpq] = _ ;e : 9TP86 5p +q& 4^&3 +0/h .*p +q& ,&++)4 +&d $ECMODEL 1: memrwC.mcFebruary 5, 1981 5:57 PM%20* December 5, 1978 12:18 PMsetCAAF: subroutine;* set current cache location and cache flags to allonespushReturn[];t _ q;call[vaForRow];rscr _ t;t _ col;rscr2 _ t;t _ rscr;rscr _ cm1;call[putCAmem];* t = va, rscr = brHi15, rscr2 = colt _ q;call[vaForRow];rscr _ t;t _ col;rscr2 _ t;t _ rscr;rscr _ (cflags.mask);call[putCFmem];* t = va, rscr = flags, rscr2 = colreturnP[];readCurrentCFlags: subroutine;pushReturn[];t _ q;call[vaForRow];rscr _ t;rscr2 _ col;call[readCflags];* rscr = va, rscr2 = colt _ t AND (cflags.mask);* isolate flags from other pipe5 stuffreturnPAndBranch[t];readOldCflags: subroutine;pushReturn[];t _ rsh[va, catPackShift];;call[vaForRow];rscr _ t;t _ (va) AND (3c);* isolate colcall[readCflags], rscr2 _ t;* rscr = va, rscr2 = colt _ t AND (cflags.mask);* isolate flags from other pipe5 stuffreturnPAndBranch[t];readCurrentCAmem: subroutine;* the cache address memory requires destructive read.Therefore, read the memory w/ the value we expect to find!pushReturn[];t _ (mcr.dPipeVa);t _ t OR (mcr.noRef);call[mcrForCol];call[setBrCacheABits], t _ r0;call[vaForRow], t _ q;rscr2 _ t;* save va since shortMemWait clobbers tDBuf _ r0, STORE _ t;* TAG bits now screwedshortMemWait[rscr];call[getPipeCacheABits];* does not clobber rscr2rscr _ t;* save hi 15 bits of va in rscrt _ rscr2;* restore vaDBuf _ r0, STORE _ t;* fix TAG bitsshortMemWait[rscr2];t _ rscr;returnPAndBranch[t];readOldCAmem: subroutine;* the cache address memory requires destructive read.Therefore, read the memory w/ the value we expect to find!pushReturn[];t _ q;rscr _ va;* SWAP "va state"va _ lsh[t, catPackShift];t _ (col) AND (3c);va _ (va) OR t;* va = packed copy of "current" statet _ (rscr) AND (3c);col _ t;t _ rsh[rscr, catPackShift];q _ t;* now, q = old row, col = old colZgp+?&N bAq apq +3 _^ ]K\ZYXU WU T+$S_R"PONi M,KJ+#Is Fpq E D}C@B@ ?+>J+&=  :p q 9 87B64+ 3+2L+&1 .*pq +5 ,:+ *r)4'&%|$> +'#+! +H+ + + R p q +5 :\  +f)+%   p 3+! D@]=MODEL 1: memrwC.mcFebruary 5, 1981 5:57 PM%21t _ (mcr.dPipeVa);t _ t OR (mcr.noRef);call[mcrForCol];call[setBrCacheABits], t _ r0;call[vaForRow], t _ q;rscr2 _ t;* save va since shortMemWait clobbers tDBuf _ r0, STORE _ t;* TAG bits now screwedshortMemWait[rscr];call[getPipeCacheABits];* does not clobber rscr2rscr _ t;* save hi 15 bits of va in rscrt _ rscr2;* restore vaDBuf _ r0, STORE _ t;* fix TAG bitsshortMemWait[rscr2];t _ q;noop;t _ lsh[t, catPackShift];t _ t OR (col);rscr2 _ t;* rscr2 = original value of packed vat _ (va) and (3c);col _ t;* "current" col restoredva _ rsh[va, catPackShift];q _ va;* "current" row restoredt _ rscr2;va _ rscr2;* "old" packed va restoredt _ rscr;* return w/ Amem in TreturnPAndBranch[t];CATdone: noop;returnP[];Zgp+?&Naq_^]K\Z +'Y+XUW+U+T + S_+ R"ONiM,KJ +%H6F+ED}+C@ B +@+? >Jpq=  ::,.MODEL 1:memrwd.mcMay 26, 1981 9:50 AM%1title[memRWd];top level;%A FEW RULESSubroutines clobber rscr, rscr2 and T unless otherwise specified at both point of call and insubroutine description. Subroutines return single values in T, and they accept single values in T. Twoparameter subroutines accept their values in rscr and rscr2. Subroutines may use the global variablesMrow, Mcol, etc.Global values for D boardAbbreviations used hereiniInitMMapcolColumnCCacheDcacheDatanextFooincrements foo loop variable, returns with fast branchcondition to check for done w/ loopgetFooreturns current value of loop variable, foogetFooRtnsubroutine that returns in T the saved value of foo'sreturn linkiFooCtrlinitialize foo loop control%%May 26, 1981 9:50 AMInvert the order of GallPat test and HoldTest-- hold test sets mcr.May 21, 1981 3:47 PMAdd GallPat test for cache data.September 19, 1979 7:16 PMAdd call to disableConditionalTask to beginDtest.September 13, 1979 4:46 PMChange control structure so that a single subroutine invokes each dboard test. Last previousmod on 28Dec78.%gp% ->qN bAq a _*d^p Zq] Yf XUf W T POp+qNip+qM,p+qKp+qJp+qIsp+q6H6#Fp+q+Ep+q5D} C@p+q B @ ?>JC = ; :9T1 86] 5 4^: 2E35MODEL 1:memrwd.mcMay 26, 1981 9:50 AM%2* May 22, 1981 10:54 AMbeginDtest:pushReturn[];call[disableConditionalTask];call[cDataTest1];call[cdaTest];call[cdGallPat];call[cdHoldTest];returnP[];gp% ->qN bAq ap _q ^]K\ ZYXU V" ;MODEL 1:memrwd.mcMay 26, 1981 9:50 AM%3%To test the D-board cache data by reading and writing it:TESTSYNDROME _ 0;-- initialize the D-board--For the first set of tests, disable the cache flags and the base registerstest1MCR _ [ disHold];SetMCR[test1MCR];FOR va _ 0, va _ va + 20b UNTIL va >= 1000B DOcol _ colFromVa[va];SetMcr[test1MCR OR useMcrV OR (mcrV:col)];store _ va, MD _ 0;ENDLOOP;-- end of initialization sequenceFOR patX IN PatX DO-- begin testing current vaFOR va IN [0..4000) DOpattern _ getPat[patX, va];md _ pattern, store _ va;ENDLOOP;-- end of data writing loopFOR va IN [0..4000) DOpattern _ getPat[patX, va];FETCH _ va;x1 _ MDI;x2 _ MD;IF x1 #x2 THEN ERROR;IF x1 # pattern THEN ERROR;ENDLOOP;-- end of check loopENDLOOP;-- end of pattern loopSetCFlags: PROCEDURE[baseRegs, va, cacheFlags, column] =BEGINrealBR _ make24BitBR[baseRegs];mcrValue _ [useMcrV, mcrv: col, noRef, disHold];SetBR[realBR-cacheFlags];dummyRef _ va;CFLAGS _ cacheFlags;END;%gp% ->qN bAqa9 ^+ ]KL \ Z Y.XUW*UT+! R"+PONiM,+KJIs H6FED}C@+B+ ?8>J= ;0:9T 86 5 4;33MODEL 1:memrwd.mcMay 26, 1981 9:50 AM%4* March 20, 1978 1:59 PMcDataTest1:pushReturn[];call[iDboard];checkMtest[memFlags.dRW, cdXit];t_rscr_(rscr)-(rscr);* BRHI = va = 0call[presetCache],rscr2 _ t;* cache flags=0call[setMCR], t _ r0;cd1PatI:call[iCDpatCtrl];cd1PatL:call[nextCDpat];skpif[alu#0];branch[cdXit];noop;cd1wVaI:call[iCDvaCtrl], t _ r0;* init cache beginning w/ va=0cd1wVaL:call[nextVa];* sets va directlyskpif[alu#0];branch[cd1rVa];* go read what we've writtennoop;call[getCDpat];* knows about vaDBuf _ t, store _ va;branch[cd1wVaL];cd1rVa:call[iCDvaCtrl], t _ r0;* init cache beginning w/ va=0cd1rVaL:* top of read/check loopcall[nextVa];skpif[alu#0];branch[cd1PatL];* no more to check. try next patternfetch _ va;noop;t _ (r0) + (md);* removed: + (r0); for a whileCData _ md;* try both immediate and regular md%*------------------------------------------------------------------------------Perform two tests on cache data. First (cd1rerr1), make sure the values from MD and from MDI are thesame. Second (cd1rerr2), make sure the value we got from the cache is the same as the one we wrote.In both cases, CData contains the value from the cache, and va is the current cache address.%*------------------------------------------------------------------------------t#(CData);* T contains cache data from MD,skpif[alu=0];* CData contains cache data from MDIcd1rerr1:* va is the address we referenced.error;* two reads of mem data don't macthcall[getCDpat];* put current pattern in rscrrscr _ t;t _ t # (CData);* compare current pattern, cache dataskpif[alu=0];* t = bad bits, CDdata = val from cachecd1Rerr2:* va is the address we referenced.error;* and rscr = expected databranch[cd1rVaL];cdXit:returnP[];gp% ->qN bAq ap q_ ^ ]K\+Z+Y WpqU S_pqR"P O Ni KpqJ+ IspqH6 +F E+D}C@+B@ >Jpq= + :pq+9T 8 6+$4^ 3 1+0 +# .*P ,d +c *r\ )4P' +& +$ %|pq+"$>+#!+ H+% +' pq+"+R pq  9CRMODEL 1:memrwd.mcMay 26, 1981 9:50 AM%5* January 12, 1978 10:20 AM%Exhaustive test of Cache AddressingPerform exhaustive test of cache addressing mechanism:zeroCache[];FOR va IN [0..cdMaxVa) DO-- catch bad stores ahead of vaIF cache[va] # 0 THEN FindErrUP[];cache[va] _ -1;ENDLOOP;zeroCache[];FOR va DECREASING IN [0..cdMaxVa) DO-- catch bad stores below vaIF cache[i] # 0 THEN FindErrDown[];cach[i] _ -1;ENDLOOP;FindErrUP: PROCEDURE[va] =BEGINzeroCache[];FOR va2 IN [0..cdMaxVa) DOIF cache[va] # 0 THEN ERROR;-- store at va2-1 cloobbered vacache[va2] _ -1;ENDLOOP;addrGhosts _ addrGhosts + 1;END;FindErrDown: PROCEDURE[va] =BEGINzeroCache[];FOR va2 DECREASING IN [0..cdMaxVa) DOIF cache[va] # 0 THEN ERROR;-- store at va2-1 cloobbered vacache[va2] _ -1;ENDLOOP;END;%* December 28, 1978 1:47 PMcdaTest:* cache data addressing testpushReturn[];checkMtest[memFlags.dAddr, cdaTestXit];call[zeroCache0];* zero cache. Begin at va=0call[iCDvaCtrl], t_r0;cdaUpL:* FOR va IN [0..cdMaxVa) DOcall[nextVa];skpif[alu#0],t_cm1;branch[cdaUpXit];* try decreasing va nowfetch _ va;* rscr = last vaCData _ md;CData _ CData;skpif[alu=0];branch[cdaUpErr];* see which store caused the problembranch[cdaUpL], store_va, DBuf_t;* cache[va] _ -1cdaUpXit:* try the same test w/ decreasing vacall[zeroCache0];call[iCDvaCtrl], t_r0;cdaDownL:* FOR va DECREASING IN [0..cdMaxVa) DOcall[nextVa];skpif[alu#0];* nextVa writes directly into vabranch[cdaTestXit];t _ cdMaxVa;* cdMaxVa = last address + 1t _ t-1;* max valid address into tva _ t-(va);* make va Decrease!fetch _ va;CData _ md;CData _ CData;skpif[alu=0];branch[cdaDownErr];* see which write caused the failuret _ cm1;branch[cdaDownL],DBuf_t, store_va;* cache[va]_-1gp% ->qN bAq a"T_p# ^q6 ]K \+Z"YXU W U$+T#S_ R" PONi M,K+JIsH6F ED}C@ B%@+?>J=  ; : 9Tp+q8 6'5+4^ 1p-q0 /h.*++ +*r )4 ' &+$$>!+ !p+q$ H p+q& R + +\+ +  f )  +$ p 3"+  9q]/MODEL 1:memrwd.mcMay 26, 1981 9:50 AM%6gp% ->qN( b" MODEL 1:memrwd.mcMay 26, 1981 9:50 AM%7cdaUpErr:* va-1 = last address used for a store.* We know that a store in the interval [0..va) has clobbered location va. Loop again* and check location va after each store. KEEP (at entry) Va IN R1r1 _ va;* TEMPRORARY EXPEDIENTcall[zeroCache0];call[iCdVaCtrl], t_r0;cdaUpErrL:* FOR va2 IN [0..cdMaxVa) DOcall[nextVa];skpif[alu#0];branch[cdaUpNoFind];fetch _ r1;CData _ md;CData _ CData;skpif[alu=0];* CData = bad valuecdaUpError:* r1 = clobbered address.error;* va-1 = addr whose store clobbered r1 addrt_va;* see if we are about to write the locationt-(r1);* that was clobbered earlier. If so, skip itskpif[alu#0];* --its a transient problem. Continue testingbranch[cdaUpErrL];* since we might find another problemt _cm1;branch[cdaUpErrL], store_va, DBuf_t;* cache[va2] _ -1cdaUpNoFind:error;* This suggests a transient error.cdaDownErr:* va-1=last address used for a store.* We know that a store in the interval [0..va) has clobbered location va. Loop again* and check location va after each store.r1 _ va;* KEEP clobbered Addr in R1!!call[zeroCache0];call[iCDvaCtrl], t_r0;cdaDownErrL:* FOR va2 DECREASING IN [0..cdMaxVa) DOcall[nextVa];skpif[alu#0];branch[cdaDownNoFind];t _ cdMaxVa;t_t-1;* make va DECREASING from lastva _ t-(va);* valid addressfetch _ r1;CData _ md;CData _ CData;skpif[alu=0];cdaDownError:* CData = bad value, r1 = clobbered addresserror;* va+1 = addr whose store clobbered r1 addrt _ rscr _ (va);* remember this va for next timet-(r1);* see if we are about to write the locationskpif[alu#0];* that was clobbered earlier. If so, skip itbranch[cdaDownErrL];* --its a transient problem. Continue testing* since we might find another problemt _ cm1;branch[cdaDownErrL], DBuf_t, store_va;* cache[va2] _ -1;cdaDownNoFind:* This suggests a transient error.error;cdaTestXit:r1 _ 1c;* just in case we continued from MidasreturnP[];gp% ->qN bA+q' aT _B]K+\Z XUp +qW U TR" P O Ni + M,p +qK++Is++H6+,F +-E+%C@B$+ ?p >Jq+" ;p +q% :U 9T)8+64^ 3 p +q'1 0 /h, ++*r +' & %| $> #p +q+!++H+++ +,R+-+%&+ p +q" fp )q+& ` M>%\"MODEL 1:memrwd.mcMay 26, 1981 9:50 AM%8* December 27, 1978 11:00 AM%TEST HOLD, MD, MDI INTERACTIONSFetch known values under different timing circumstances to make sure the memory system returns thecorrect value. These tests try to retrieve a known value w/ zero, one or two noops between fetch_ and_md. Both md and mdi are tested. The test calls cdHoldReset to force a zero into md.%cdHoldTest:* init some valuespushReturn[];checkMtest[memFlags.dHold, afterCDhold];t _ mcr.noWake;call[setMCR];DBuf _ r0, STORE _ r0;* cacheData[0] _ 0rscr _ t _ cm1;DBuf _ t, store _ r1;* cacheData[1] _ 177777bcall[cdHoldReset];t _ fetch _ r1;t _ md;* zero noopst _ t # (rscr);skpif[alu=0];cdHoldErr0:error;* t=bad bits, rscr = expected value, r1=addrcall[cdHoldReset];t _ fetch _ r1;noop;* one noopt _ md;t _ t # (rscr);skpif[alu=0];cdHoldErr1:error;* t=bad bits, rscr = expected value, r1=addrcall[cdHoldReset];t _ fetch _ r1;noop;* two noopsnoop;t _ md;t _ t # (rscr);skpif[alu=0];cdHoldErr2:error;* t=bad bits, rscr = expected value, r1=addrcall[cdHoldReset];t _ fetch _ r1;t _ (md) + (r0);* zero noops, use mdit _ t # (rscr);skpif[alu=0];cdHoldMdiErr0:error;* t=bad bits, rscr = expected value, r1=addrcall[cdHoldReset];t _ fetch _ r1;noop;* one noopt _ (md) + (r0);* use mdit _ t # (rscr);skpif[alu=0];cdHoldMdiErr1:error;* t=bad bits, rscr = expected value, r1=addrcall[cdHoldReset];t _ fetch _ r1;noop;* two noopsnoop;t _ (md) + (r0);* use mdit _ t # (rscr);skpif[alu=0];cdHoldMdiErr2:error;* t=bad bits, rscr = expected value, r1=addrbranch[afterCDhold];gp% ->qN bAq a#_p \wqb [:e YT X Wp +qVD U(SR QN+PN+LXKI+ HGb F$p Dq+,BlA.?+ >=v<8 :p 9q+,7B64+ 32L1/ .p -Vq+,*)(`+'#% $p #jq+, t+ 7+ ~p Aq+,K+  +U p  q+,  yD])MODEL 1:memrwd.mcMay 26, 1981 9:50 AM%9*This subroutine forces a zero into md.cdHoldReset:subroutine;fetch _ r0;t _ md;return;top level;afterCDhold:returnP[];gp% ->qN aq& _p ^q ]K \ZY XUp Wq U" T>MODEL 1:memrwd.mcMay 26, 1981 9:50 AM%10* May 26, 1981 10:31 AM%cdGallPat:Traditional gallpat test: zero memory then write each cell of the memory.After each write, read all of the memory to see if any other cell has been effected by the write%cdGallPat:pushReturn[];call[cdDoGallPat], t_a0;* background with zeroscall[cdDoGallPat], t_a1;* background with onesreturnP[];cdDoGallPat:pushReturnAndT[];call[setCache0], t_ Stack;call[iCdVaCtrl],t_a0;* Start va at zerocdGallPatL:* Top of MAIN LOOPcall[nextVa];skpif[alu#0];branch[cdGallPatXit];t_ cdMaxVa;call[cdCheckVaRange],rscr_a0;* cache[0..cdMaxVa) should be =stackcdGallPat2:t_ not(stack);Pd_ (Store_ va)-1, DBuf_ t;branch[cdNoChk, ALU<0];rscr_ a0;* placement requires instr herecall[cdCheckVaRange], t_ (va)-1;* check the interval [0..va)rscr_ (va)+1;call[cdCheckVaRange], t_ cdMaxVa;* check the interval (va..cdMaxVa)noop;* for placement.cdNoChk:Fetch_va;t_ not(stack);t#(Md);skpif[ALU=0], t_ (va)+1;cdGallPErr2:* can't find the value (not(stack)) weerror;* just wrote!cdGall3:t_va;Store_t, DBuf_ stack;* restore it to original valuet_SUB[cdMaxVa!,1]C;cdGall4L:Fetch_t;(md)#(stack);skpif[ALU=0], t_ t-1;cdGallErr3:* storing Stack into va clobbered locationerror;* at t+1branch[cdGall4L, ALU>=0];branch[cdGallPatL];cdGallPatXit:pReturnP[];gp% ->qN bAq _ ^p ]KqJ \` Z XUp Wq U+T+S_ Pp OqNiK+ Jp +qIs H6 FE D}+$ Bp @q ?>J= +;+: 9T!+"8+ 5p4^q3 10 /hp +q&.*+ +p*rq)4+& %|p$>q# ! p +q*H+  Rp q  @PWMODEL 1:memrwd.mcMay 26, 1981 9:50 AM%11* May 26, 1981 10:11 AMcdCheckVaRange: subroutine;* Enter w/ t=lastva+1, rscr=1st va, stack=expectedvalue.Q_ Stack&+1;* Keep expected value in QStack_ link;* Save return linktop level;(rscr)-t;branch[.+2, alu<0];branch[cdCheckVaXit], link_ stack&-1;noop;* for placementcdChkVaRangeL:rscr_ (Fetch_rscr)+1;* fetch current value and increment va(Md)#(Q);skpif[alu=0], (rscr)#t;cdChkErr:* cache[RSCR+1] is not same as Qerror;* see return link on STACK to find*where this problem has occured. This subroutine is called from cdGallpat.loopWhile[ALU#0, cdChkVaRangeL];subroutine;link_ stack&-1;cdCheckVaXit:return;gp% ->qN bAq _pq +2 ^\ +Z +Y XUWU%T+ R"p Pq+&ONi M,p+qK+" JKH6F E D}p C@q ?dB-(|DORADO: MemRWsMay 19, 1981 1:00 PM %1%*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++May 19, 1981 11:23 AMChange addressing test to take a parameter=value to background memory with.Then change the test to run once w/ 0, once w/ 177777B.February 6, 1981 10:34 AMChange main r/w test to use prefetch.September 19, 1979 10:39 PMCause sFlushTest, sMiscTest to do _MD to wait for any activity to finish that should finish beforemanipulating the cache flags.September 13, 1979 4:52 PMMake beginStest into a subroutine that invokes all the other storage board tests.September 7, 1979 6:23 PMChange, again, the order of the tests so that the sDtest happens before the addressing test.June 28, 1979 8:36 AMFix bug in svarpipe2resume -- resumes at wrong label -- change name to sVaPipeResume, too.June 27, 1979 6:52 PMFix bug in sDbufMdTest (wrong sex on skip), make sLongFetch reset BRs when done.June 27, 1979 11:46 AMFix placement problem with afterStest, iLongFetchMem.June 27, 1979 11:23 AMAdd sLongFetchTest.June 25, 1979 3:02 PMMake each test in memRWs into a subroutine; add sMiscTest.June 8, 1979 10:12 AMSave and restore random number generator seed in sDataTest -- to aid patching the code.April 18, 1979 3:18 PMChange branch at end of sAddrTest to branch to sDtest rather than sChaosTest (this caused memAto skip the storage data test!).April 18, 1979 9:36 AMRemove conditionalTasks from Flush test because it reads CFlags and this leaves memory in statethat can't handle references from arbittrary task wakeups.April 17, 1979 10:41 PMBracket the flush test w/ calls to enableConditionalTask, disableConditionalTask.April 12, 1979 8:53 AMMove the storage addressing test to be first in the sequence of storage tests.April 11, 1979 3:47 PMAdded breakpoint at end of read/check loop so operator can tell when the diagnostic has made onecomplete pass over the memory storage.January 16, 1979 3:55 PMInvoke sRestoreMcrVictim at end of sFlushTest -- to allow entire cache to be used if it isenabled.January 15, 1979 5:43 PMfix sFlushTest to guarantee no hits in a column not selected by sMCRvictimJanuary 15, 1979 10:55 AMmore comments about patching, force microD to cause to instrs to occur sequentially in IM.January 12, 1979 11:55 PMcomments that describe how to avoid conditional tasking during sDtest's write loopJanuary 11, 1979 9:15 AMadd Flush_ test, fix missing "sVa_t" in addressing test's find error sections, add flush_ toaddressing test.%*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++title[memrwS];top level;* September 7, 1979 6:23 PMbeginStest:pushReturn[];checkMtest[memFlags.sBoard, doneStest];* skip everything if requiredcall[disableConditionalTask];* prevent task simulator from runningcall[iSboard];* find out mem configuration, size, etccall[sdTest];* data testcall[sAddrTest];* addressing testcall[sFlushTest];* flush_ testcall[sMiscTest];* miscellaneous testscall[sChaosTest];* chaos (random operations) testdoneStest:returnP[];* done%A FEW RULESSubroutines clobber rscr, rscr2 and T unless otherwise specified at both point of call and in gp,N bAqB a1_K ^7 ]K1\% Z1Yb XU W1UQ T1S_\ R"1P[ O1NiP M,1K5 JIs H6F: ED}W C@B^ @ ?>J_ = : ;:Q 9T8N 65` 4^& 3 1Z 0 /h.*K ,1+Z *r1)4R '1&\ %| $>B ! H  p q '+R+% +' + \++ ++ fp )q + *d p 3q] 4 D]+DORADO: MemRWsMay 19, 1981 1:00 PM %2subroutine description. Subroutines return single values in T, and they accept single values in T. Twoparameter subroutines accept their values in rscr and rscr2.Global values for S boardAbbreviations used hereiniInitMMapcolColumnSStoragenextFooincrements foo loop variable, returns with fast branchcondition to check for done w/ loopgetFooreturns current value of loop variable, foogetFooRtnsubroutine that returns in T the saved value of foo'sreturn linkiFooCtrlinitialize foo loop control% gp,N bAqf a< _ ]K\p+qZp+qYp+qXUp+qWp+q6U#Tp+q+S_p+q5R" Pp+q O NFE3fDORADO: MemRWsMay 19, 1981 1:00 PM %3* May 19, 1981 11:20 AM%*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++Storage Addressing TestNOTE: The Addressing test has been rewritten so that it runs once backgrounding memory w/ 0. Then itruns again and backgrounds memory w/ 177777B. The test was changed to accommodate this new subroutineparameter (the background value). Otherwise, the algorithms are the same.Background memory w/ 0 then write -1 into ascending addresses. Before the write,check that the word that is about to be written is still zero. Suppose it is non zero.Then there was an addressing error. Remember the address of the non zero word, background memory withzeros again and proceed writing -1s. This time, check thepreviously clobbered address each time before writing the -1. This approach will catch the referencethat clobbers the known location. The same algorithm can be applied fordescending addresses, mutatis mutandi, to finish a complete check of the addressing logic.sAddrCheck: PROCEDURE=BEGINzeroMem: PROCEDUREBEGINFOR munch _ 0, munch _ munch+20B UNTIL maxMunch DOFOR i IN [0..20B) DOmem[munch+i] _ 0;-- microcode implementation will be fast!ENDLOOP:ENDLOOP:END;findErrUp: PROCEDURE [clobbered: VA] =BEGINzeroMem[];FOR i IN VA DOIF mem[clobbered]#0 THEN SIGNAL ErrUp[i-1, clobbered];mem[i] _ -1;ENDLOOP:SIGNAL IntermittentErrUp[clobbered];END:findErrDown: PROCEDURE [clobbered: VA] =BEGINzeroMem[];FOR i DECREASING IN VA DOIF mem[clobbered] #0 THEN SIGNAL ErrDown[i+1, clobbered];mem[i] _ -1;ENDLOOP;SIGNAL IntermittentErrDown[clobbered];END;-- this is the programzeroMem[];FOR i IN VA DOIF mem[i] # 0 THEN FindErrUp[i];mem[i] _ -1;ENDLOOP;zeroMem[];FOR i DECREASING IN VA DOIF mem[i] # 0 THEN FindErrDown[i];mem[i] _ -1;ENDLOOP;END;%*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ gp,N bAq aB&\_p ]Kqe \f ZJ XUP WV Ue T9 S_d R"G PZ Nip q M,Kpq JIs2H6F+)ED}C@Bp q@? >J = 6; :9T$86p q54^ 3 190 /h.*&,+*r )4 '& %|$> #!" H  B: mE3LDORADO: MemRWsMay 19, 1981 1:00 PM %4* May 19, 1981 1:00 PMsAddrTest:pushReturn[];checkMtest[memFlags.sAddr, sAddrTestDone];t_a0;* for MicroDcall[sDoAddressTest], t_a0;* address test w/ background = 0t_a1;* for MicroDcall[sDoAddressTest], t_a1;* address test w/ background = 1sAddrTestDone:pReturnP[];sDoAddressTest:* This address test backgrounds memory with the value we were passed in T. Keepthat value on the stack.pushReturnAndT[];call[enableConditionalTask];call[setMemory], t_stack;call[iSvaCtrl];sAddrUpL:call[nextSva];branch[sAddrLxit, alu=0], Sva _ t;fetch _ t, t_stack;rscr _ md;(rscr) # t;* is memory same value as we stored there?skpif[alu=0], t _ not(stack);branch[sAddrUpFindErr];branch[sAddrUpL], DBuf _ t, store _ Sva;sAddrLxit:noop;call[setMemory], t_stack;call[iSvaDownCtrl];sAddrDownL:call[nextSvaDown];branch[sDoAddrTestDone, alu=0], sva _ t;fetch _ t, t_ stack;rscr _ md;(rscr)#t;* is memory same value as we stored there?skpif[alu=0], t _ not(stack);branch[sAddrDownFindErr];branch[sAddrDownL], DBuf _t, store _ Sva; gp,N bAq ap 1_q 1^*1]K& 1\" 1Z& 1Y"  XUp 1Wq TpqP S_1P1O1Ni1M, Jp1Isq 1H6"1E1D} 1C@ *1B1@1>J( ;p 1:q19T18 5p 14^q13 (101/h 1.**1,1+1)4) &BAuDORADO: MemRWsMay 19, 1981 1:00 PM %5* May 19, 1981 11:19 AM%*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++sAddrUpFindErrREMEMBER: Stack contains the background value for this test.This test tries to isolate the reference that clobbered the location (denote it the target location)that was detected by the sAddrUpL loop. The test proceeds as before except that as it ascends memoryit continually checks to see if the target location has been clobbered yet. Use Flush_ to force thetarget munch out of the cache.%*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++sAddrUpFindErr:call[saveMemAddr];* save addr of clobbered locationcall[setMemory], t_stack;call[fetchMemAddr];* returns w/ rscr = brHi, rscr2 = low 16t _ rscr2;call[setBR], rscr2 _ t-t;fetch _ t, rscr3_t;t_stack;rscr2 _ md;(rscr2)#t;skpif[alu=0];* error implies setMemory didn't worksAddrUpErr1:error;* rscr3 = low 16 bits of addr, rscr = hi 8 bits, rscr2= MD valuesaueFlush1:Flush _ rscr3;* remove target munch from cachecall[iSvaCtrl];sAddrUpFindL:call[nextSva];branch[sAddrUpNoFind, alu=0], sVA _ t;noop;call[restoreBrHi];* we clobbered it to check clobbered mem locationt _ not(stack);* perform next reference before we check for clobbereddatastore _ Sva, DBuf _ t;call[fetchMemAddr];* returns rscr= brhi, rscr2 = low 16 bits of vat _ rscr2;call[setBR], rscr2 _ t-t;fetch _ t, rscr3_t;* save low 16 bits of addr in rscr3t _ md;(t)#(stack);skpif[alu=0];* error => last reference clobbered the location atsAddrUpErr2:error;* rscr,,rscr3. bad bits are in rscr2. Last referenceat sVaHi,,sVaXsaufeFlush2:Flush _ rscr3;* remove target munch from cachebranch[sAddrUpFindL];sAddrUpNoFind:error;* intermittent error; gp,N bAq aB)b_p ^q< \Trq ZpqD Y$rq1 XU WB TpS_q+!R"P+(O NiM,KJ Is H6 +% Fp Eq+6 D} C@p Bq +? >Jp = q ;&9T8+16+6 54^1+/0 /h.*+#,+ *r +3 )4p 'q+4 & %|p $>q +! Hp q + DKaDORADO: MemRWsMay 19, 1981 1:00 PM %6* May 19, 1981 11:18 AM%*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++sAddrDownFindErrREMEMBER: Stack contains the background value for this test.This test tries to isolate the reference that clobbered the location (denote it the target location)that was detected by the sAddrDownL loop. The test proceeds as before except that as it descendsmemory it continually checks to see if the target location has been clobbered yet. Use Flush_ toforce the target munch out of the cache.%*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++sAddrDownFindErr:call[saveMemAddr];* save address of clobbered locationcall[setMemory], t_ stack;call[fetchMemAddr];* return w/ rscr = brhi, rscr2 = low 16 bitst _ rscr2;call[setBR], rscr2 _ t-t;* make sure target word is zerofetch _ t, rscr3_t;t _ md;(t)#(stack);skpif[alu=0];* failure implies setMemory didn't worksAddrDownErr1:error;* rscr = brHI, rscr3 = low 16 bits of va, rscr2 = mdsadfeFlush1:Flush _ rscr3;* remove target munch from cachecall[iSvaDownCtrl];sAddrDownFindL:rscr2 _ Sva;call[nextSvaDown];branch[sAddrDownNoFind, alu=0], sVA _ t;noop;call[restoreBrHi];* we clobbered it to check clobbered mem locationt _ not(stack);store_sva, DBuf _ t;call[fetchMemAddr];* returns w/ rscr = brhi, rscr2 = low a6 bitst _ rscr2;call[setBR], rscr2 _ t-t;fetch _ t, rscr3_t;t _ md;(t)#(stack);skpif[alu=0];sAddrDownErr2:error;* ref at sVaHi,,sVaX clobbered rscr,,rscr3sadfeFlush2:Flush _ rscr3;* remove target munch from cachebranch[sAddrDownFindL];sAddrDownNoFind:error;* intermittent error;sDoAddrTestDone:call[disableConditionalTask];pReturnP[]; gp,N bAq aB(_p ^q< \Trq Zp q> Y+rq' XU( WB TpS_q+$R"P+,O Ni+M,KJ Is +' H6p Fq+4 Ep D}q +B @p?q >J= (:9T+1864^+-3 10/h.* , +p *rq+* 'p &q + %| #p!q+ pHq v CKaDORADO: MemRWsMay 19, 1981 1:00 PM %7* February 6, 1981 10:52 AM%*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++Storage Data TestFOR patX IN PatX DOFOR va IN VA DOmem[va] _ getPattern[patX, va];ENDLOOP:FOR munch IN [MunchVa] DOFOR i IN [0..17] DOva _ munch+va;got _ mem[va];expect _ getPattern[patX, va];IF ~sChkNoErrs[] THEN-- sChkNoErrs turns OFF checkingT _ expect xor got;IF T # 0 THEN SIGNAL memErr[va, expect, got];ENDLOOP;-- check the pipe after we've read the entire munchIF ~ sChkNoErrs[] THEN-- sChkNoErrs turns OFF checkingIF aChkPipeFlt[] THENBEGIN;myPipe4 _ PIPE4[];num1Bits _ Count1Bits[myPipe4.syndrome];IF num1Bits = 1 THEN SIGNAL checkBitFailure[myPipe4];IF myPipe4.syndrome = 0 AND (num1Bits AND 1) = 0) THENSIGNAL doubleError[myPipe4];synWdX _ myPipe4.syndromeWdX;IF (synWdX=3) OR (synWdX=5) OR (synWdX=6) THENSIGNAL singleError[myPipe4];SIGNAL unknownError[myPipe2];END;ENLOOP;ENDLOOP;%%sNoErrsOn() is a midas subroutine that will cause the sdTest to avoid ALL error checkingsNoErrsOff() is a midas subroutine that reenables sdTest error checkingsdNoDataErrs is the location of the branch that skips error checking within the data check of sdTest.Patch out this branch to allow data checking and to disalow pipe checking when sNoErrsOn is in effect.Notice the note below.sdNoPipeErrs is the location of a branch that skips error checking of the pipe within the read loop ofthe sdTest. Patch out this branch to allow pipe error checking when sNoErrsON is in effect. Noticethe note above.sdOffCTask is the location of a call to enable conditional task that occurs just before the write loopportion of sdTest. Patch out this call to disallow the memory task simulator's memory referencesduring the sdTest. Notice the note below.sdOnCtask is the location of a noop that may be patched into a call on the enableConditionalTasksubroutine to cause the memory task simulator to run during the checking portion of the sdTest.Notice the note above.sVaTryNextPat is the location of the branch that causes the diagnostic to write a new pattern intomemory after the current pattern has been checked. Patch this location to into a branch[sdBeginCheck]to force the diagnostic into an infinite loop that always checks the current pattern.%*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++sDtest:pushReturn[];checkMtest[memFlags.sRW, sdTestDone];sdOffCTask: * Comment-OUT this instruction to avoid conditional tasking duringcall[enableConditionalTask];* the sdTest write loop.call[iSPatCtrl];sDpatL:call[nextSPat];* top of pattern loopskpif[alu#0];branch[sDtestDone];noop; gp,N bAq aB(`_p ^q]K\ZYXUW U TS_+R"P-ONi3M,+KJIsH6(F5E6$D}C@B.$@?>J= ; : 9T 7Bp qM 51p q; 3 p qY 1rqrq+ 0 .p qZ -V&rq9 , *p q\ (+rq. '* %|pqBp $>q_ # p qU Rp tqU 7B p~q A% p qD+  pq+U    < yE]"DORADO: MemRWsMay 19, 1981 1:00 PM %8call[saveRandState];call[iSmunchCtrl];sVaWMunchL:* top of write loop; get here once/munch.call[nextSmunch];skpif[alu#0], Sva _ t;branch[sVaWxit];* no more vas. Now Read itt_ t+(20C);rscr_ (PreFetch_ t)-t;* speed-up the test; rscr_0 cnt_ 17s;sVaWL:* For this munch: mem[Sva]_curPatternnoop;* for placement.call[getSPat], t _ Sva;loopuntil[cnt=0&-1, sVaWL], DBuf _ t, Sva_(Store _ Sva)+1;branch[sVaWMunchL];sVaWxit: gp,NbAqa _p +q)^]K\+Y XU+ W Up+q&T+S_R":P Op NF;uYDORADO: MemRWsMay 19, 1981 1:00 PM %9* February 6, 1981 10:51 AMsdOnCTask: * Patch this location into a call oncall[justReturn];* enableConditionalTask, if desired.sdBeginCheck:call[iSmunchCtrl];call[restoreRandState];B _ FaultInfo'[];sVaRmunchL:call[nextSmunch];* top of munch loopskpif[alu#0], Sva _ t;sVaTryNextPat:branch[sDpatL], breakpoint;t_t+(20C);rscr_ (PreFetch_ t)-t;* speed-up the test; rscr_0cnt _ 17s;* inner loop to zero current munchsVaRL:* top of word read/check loopFETCH _ sva;call[getSPat], t _ Sva;sExpected _ t;* copy current pattern into sExpectedrscr2 _ MD;* (avoid bypass)call[sChkNoErrs];skpif[ALU=0];sdNoDataErrs: * Patch out this branch to allow data error checking during sdTest whenbranch[svaRresume];* sNoErrsOn is in effect.t _ sExpected;* retrieve sExpected into tt _ t # (rscr2);* t _ cur t xor mdskpif[alu=0];* error => bad data from memory. Sva = addrsvaRErr:* sExpected = expected valueerror;* t = bad bits, rscr2 = MDsvaRresume:noop;* placement for microDloopuntil[cnt=0&-1, svaRL], sva _ (sva) +1;* now check pipe 2noop;* placement for microDcall[sChkNoErrs];skpif[ALU=0];sdNoPipeErrs: * Patch out this branch to allow pipe error checking in sdTest whenbranch[sVaRmunchL];* sNoErrsOn is in effect.noop;call[aChkPipeFlt];skpif[alu#0];branch[sVaRmunchL];* no errors; try next munch* Pipe checking code on next page. gp,N bAq _p q+$^+$ \p ZqYXU Wp Uq+T S_p R"qO Ni+M, +" Kp+qJ IsH6 +%F +D}C@ Bp qrq'@+>J += +; ++ :p+q9T+ 8p 6q+5+ 3 1+0/h .*p qrq#,++)4' &+$>"L "check bit error. See midas forerror;* PERRS 20, PVA 20, etcnoop;* for placementcall[xGetPipe4];skpif[r even], rscr;* double errs only w/ even paritybranch[sVaChkSingleErr];rscr _ (t) AND (pipe4.syndrome);* check for nonzero syndromeskpif[alu#0];branch[sVaChkSingleErr];sVaDblErr:* syndrome # 0 and syndrome parity evenerror;* means there was a double errorsVaChkSingleErr:t _ t AND (pipe4.syndromeWdX);* put encoded word index in tnoop;t _ rsh[t, pipe4.syndromeWdXShift];t-(3c);* corresponds to word zeroskpif[ALU#0];branch[sVaSingleErr];* error in word zero of quadwordt - (5c);* corresponds to word oneskpif[ALU#0];branch[sVaSingleErr];* error in word one of quadwordt - (6c);* corresponds to word twoskpif[ALU#0];branch[sVaSingleErr];* error in word two of quadwordt - (7c);* corresponds to word threeskpif[ALU=0];branch[sVaUnknown];sVaSingleErr:* double error. see PVA 20, PERRS 20error;* using midas. t = encoded word indexsVaUnknown:* diagnostic is confused. Use Midas toerror;* examine the pipe to see what happened.sVaPipeResume:branch[sVaRmunchL];sDtestDone:call[disableConditionalTask];returnP[]; gp,N bAq _B1^` ]KG1\r^ Z8 YqBXU +.WU T++S_ R"p PqONiM,"JIs+, H6p +q,F+E+D}B+!@?+>J =  ;p +q':+ 8p5q+4^3 #1+0 /h+.*+, ++*r+)4 '+&+%| $> #p +q$!+rq Hp +q& +( p q Rp q  wCQDORADO: MemRWsMay 19, 1981 1:00 PM %11* April 17, 1979 10:41 PM%*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++Flush_Test the Flush_ function of the memory system. Read the cache to determine if Flush_ really worked.The test forces the memory system to use only one column during the checking phase; this makes iteasier to determine what is happening. This test disables conditional tasking because it readsCFLAGS.For each column:Set CacheA to all zeros (works on all columns)Set All CFLAGS to vacant (works on all columns)Zero the memory (works on current column, only)For each munch (works on current column, only)Dirty the munchFlush that vaRead the cache for the appropriate row to make sure the munch is vacantReread the munch to assure the dirty data is really there%*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++sFlushTest:pushReturn[];checkMtest[memFlags.sFlush, afterSflush];call[disableConditionalTask];call[initCol2Ctrl];* we use "col2" because some of the cache* manipulating subroutines we call clobber "col".sFlushColL:* top of the column loopcall[nextCol2];skpif[ALU#0];branch[sFlushColXit];T_MD;* force Hold, if required.call[ZeroCacheAndFlags];* set cacheA to all zeros(including CFLAGS)call[clearCacheFlags];* set all cache to vacantcall[getCol2];sMCRvictim _ t;call[sUseDefaultMcr];* use current column of cache, only.call[zeroMemory];* background the memory w/ zeroscall[iSmunchCtrl];sFlushMunchL:* top of munch write loopcall[nextSmunch];skpif[ALU#0], sVa _ t;branch[sFlushMunchXit];noop;* for placement* readCflags, which we call below, clobbers Mcr, so we must reset Mcr each time thru the loop.t_cm1;STORE_sVa, DBuf _ t;* fetch current munch (storage access), dirty itB_MD;* wait for memory system if requiredFlush_sVa;* FLUSH it!t _ 100c;call[longWait];* wait for memory system if requiredrscr _ sVa;* rscr _ sVa, rscr2 _ columncall[getCol2];call[readCflags], rscr2 _ t;* read the cflagst _ t and (pipe5.flagsMask);rscr _ t # (cflags.vacant);* only the vacant bit should be setskpif[ALU=0];sFlushErr1:* the munchd at sVa didn't flush!error;* t = cflags, rscr = bad bits in cflagscall[sUseDefaultMcr];* use current column of cache, only.FETCH _ sVa;* make sure our dirty munch is reallyt _ MD;* in storage.sExpected _ cm1;t # (sExpected);skpif[ALU=0];sFlushErr2:* the flush didn't cause our dirtyerror;* munch to go to storage. t = md,* sExpected = value we expected gp,N bAqp aqB,_p ^qd ]Ka \_ Z YXU.W/U/T.S_R" PGO9 NiB M,p Kq J)IsH6+) F1 Ep +qD}C@ B@+>J++= +: 9T8+$5+3  1p +q0/h.*,+ *rp qR)4'+0&+$%| + #!+$ +H  +R+# p +q!+'+$ +%+ f) p +q" p+! 3 C];DORADO: MemRWsMay 19, 1981 1:00 PM %12branch[sFlushMunchL];sFlushMunchXit:branch[sFlushColL];sFlushColXit:afterSflush:call[disableConditionalTask];call[sRestoreMcrVictim];returnP[]; gp,Naq ^p]Kq \p Z YqXUW U%T4DORADO: MemRWsMay 19, 1981 1:00 PM %13* September 19, 1979 10:41 PM%*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++sMiscTestMiscellaneous memory tests:make sure Dbuf_ doesn't clobber MDtest the bits of MD*%*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++sMiscTest:pushReturn[];T_MD;* force Hold, if required.call[sDbufMdTest];noop;* for placementcall[sLongFetchTest];returnP[];* June 27, 1979 6:56 PM%*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++Check that MD is valid after writing into Dbuf, and check that we can read the value stored into DBuf.The approach is to write one known value into memory then to fetch a different, known value frommemory. Then check that MD and DBuf are as expected.%*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++sDbufMdTest:pushReturn[];t _ a0;store _ t, DBuf _ t;* initialize location 0 w/ 0fetch _ t;rscr _ MD;* fill MD with 0srscr2 _ cm1;store _ t, DBuf _ rscr2;* fill DBuf with -1rscr2 _ MD;PD _ (rscr2);skpif[ALU=0];* see if storing into dbuf seemssDbufMdErr0:* to clobber MD.error;* Expected 0 in MD, got rscr2.t _ DBuf;t # (cm1);skpif[ALU=0];sDbufMdErr1:* expected -1 in Dbuf,error;* t = value read from DBuf.t _ a0;fetch _ t;rscr _ md;* this should fetch the -1 we stored earlierStore _ t, DBuf _ 0c;* Write 0 into Dbufrscr2 _ MD;(rscr2) # (cm1);skpif[ALU=0];* see if storing all zeros into DBufsDbufMdErr2:* clobbred the bits of MDerror;* expected all one bits, got rscr2.t _ PD _ DBuf;skpif[ALU=0];sDbufMdErr3:* expected 0 in Dbuf,error;* t = value read from DBuf.returnP[]; gp,N bAq aB+_p ^q]K"\ ZB Yp XUq W+UT+S_R" O NiB M,f K` J5 IsB Fp @Eq @D}@C@+@B @@ +@? @>J+@= @; @: + 9Tp +q@8+@5@4^ @3 1p +q@0+@.*@, @+ +,@*r+@)4 @'@& +$ %|p +q@$>+#@! @ Hp +q@ +@ < mELDORADO: MemRWsMay 19, 1981 1:00 PM %14* June 27, 1979 11:39 AMsLongFetchTest:pushReturn[];%*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++Test long fetch: (B[4:15],,Mar[0:15]) + BR = actual 28 bit va used by memory system.We'll initialize the 1st 65 K words so that mem[va] = va. Then set BrHi to various values and performlong fetches to cause the values to wrap around into the 1st 65K. Check both the data and pipeVa.%*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++rscr _ a0;call[setBR], rscr2 _ a0;call[iSlongFetchMem];rscr _ (r0)+1;call[setBr], rscr2 _ a0;t _ 7777C;* t = long fetch bitsLongFetch _ rscr2, B _ t;* va = 7777,,0 + 1,,0 = 0rscr _ MD;PD _ rscr;skpif[ALU=0];sLongFetchErr0:* should have wrapped around to 0error;* pipe 0 shows va, rscr = MD, expected 0.t _ pipe0;t _ t and (7777C);skpif[ALU=0];* VA high bits should be zerosLongFetchErr1:* t = actual value of bitserror;t _ PD _ pipe1;skpif[ALU=0];sLongFetchErr2:* VA low bits should be zeroerror;* t = actual bitsrscr _ 2c;call[setBR], rscr2 _ a0;* BR = 2,,0t _ (and[7776,177400]C);t _ t or (and[7776,377]C);* t = 7776 = long fetch bitsrscr _ 34c;* arbitrary word to fetch in 1st 65KLongFetch _ rscr, B _ t;* va = 7776,,34 + 2,,0 = 0rscr2 _ MD;(rscr2) # (34c);skpif[ALU=0];sLongFetchErr3:* Expected to pick up word at location 34error;* Expected value = 34B, got rscr2t _ pipe0;t _ t and (7777C);skpif[ALU=0];sLongFetchErr4:* Br hi bits should be zero!error;* got value in tt _ pipe1;t # (34C);skpif[ALU=0];sLongFetchErr5:* expected BrLo bits = 34Berror;* got value in t.rscr _ a0;call[setBR], rscr2 _ a0;returnP[];iSlongFetchMem:pushReturn[];t _ rscr _ a0;iSlongFetchMemL:cnt _ 17s;prefetch _ rscr;loopUntil[CNT=0&-1, .], t _ (Store_t)+1, DBuf _ t;loopUntil[ALU=0, iSlongFetchMemL], rscr _ t + (40c);returnP[]; gp,N bAq _p1^q ]KB \U Zf Yb XUBW UTS_ R"P +O+Ni M, K Jp+q!Is+)F ED} + C@p+qB?>J = p+q;+9T 8+ 54^+3 +$1+0 /h.* ,p+q)++!)4 '& %|p+q$>+!  H  p+q+ R p\q  pq f)2 4  ME3\"DORADO:memrwX.mcMay 14, 1981 2:25 PM%1title[mapReadWriteX];%*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++TABLE of Contents, by Order of OccurencebeginXtestmain subroutine that calls the tests in this filemapSingleStepsingle step code for midas debuggingmapRWtestRead and write the mapmapAddrTestMap addressing testmapRWtest2Map read write test that checks timing margins -- does not execute unlessoperator patches code. It takes more than 20 minutes to execute.%*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++%May 14, 1981 4:49 PMskip xboard tests if memFlags.xBoard not true (avoid problemes w/ xGetMapIcs)September 19, 1979 7:16 PMMove beginXtest to beginning of listing, add call to disableConditionalTask.September 14, 1979 9:54 AMAdd table of contents, fix typo in beginXtest.September 13, 1979 4:41 PMadd code that calls each x-board test as a subroutine.January 25, 1979 4:52 PMAdd check for pipe2.nfaults =7.January 25, 1979 3:41 PMAdd checking to see if pipe4.mFault is set dukring mapRWtest.%egp$-a>N bAq aD _p( ^ q1 ]Kp q$ \pq Zp q Yp qI XUA WD T S_R"M POL NiM,. KJ6 IsH6 FE= D} CC$DORADO:memrwX.mcMay 14, 1981 2:25 PM%2* May 14, 1981 2:05 PMbeginXtest: 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 operatorpatches the code at the entry to this subroutine. This test checks the timing margins of the mapchips and requires about 20 minutes or more to execute.%endXTest:returnP[];top level;* December 20, 1977 3:16 PM%A FEW RULESMrow IN [0..mRowEndC)Mcol IN [0..mColEndC)Subroutines clobber rscr, rscr2 and T unless otherwise specified at both point of call and insubroutine description. Subroutines return single values in T, and they accept single values in T. Twoparameter subroutines accept their values in rscr and rscr2. Subroutines may use the global variablesMrow, Mcol, etc.Global values for X boardMrowmap rowMcolmap columnmcrBitsmcr bits for map manipulationMpatcurrent pattern valueAbbreviations used hereiniInitMMapXfor X board, error prefixcolColumnnextFooincrements foo loop variable, returns with fast branchcondition to check for done w/ loopgetFooreturns current value of loop variable, fooiFooCtrlinitialize foo loop control%egp$-a>N bAq ap q _ ^]K&\+ZYXU+6 Wa U7 T S_pqR" O Ni M,*dKp Isq H6 E] D}f C@f B ?>Jp+q= p+q ;p+q:p+q 86p+q5p+q4^p+q3 p+q1p+q60#/hp+q+.*p+q , +E3<DORADO:memrwX.mcMay 14, 1981 2:25 PM%3%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 DOFOR col IN Col DOFOR row in Row DOpat _ getPattern[patX, row, col];setMap[row, col, pat];ENDLOOP;FOR row IN Row DOpat _ getPattern[pat, row, col];found _ readMap[row, col];IF found # pat THEN ERROR;ENDLOOP-- end of row check loopENDLOOP;-- end of cclumn loopENDLOOP;-- end of column loopsetMap: PROCEDURE[row: MapRow, col: MapCol, pat: UNSPECIFIED] =BEGINlowBits _ IF ODD[row] THEN 100000B + col] ELSE col;hiBits _ BITSHIFT[row, -1];setBR[hiBits, lowBits];WHILE MAP[].mapMBufBusy DO ;-- loop while busyMAP _ 0, STORE _ pat;END;readMap: PROCEDURE[row: MapRow, col: MapCol] RETURNS[found: UNSPECIFIED] =BEGINcacheRowBits _ vaFromMapRowCol[row, col];vacateCacheRow[cacheRowBits];setBrforMap[row,col];FETCH _ 0;WHILE mapBusy[] DO;found _ MAP;END;vacateCacheRow[cacheVa]=BEGINEND;testMap: PROCEDURE[r:Row, c:Column, p:Pattern, c:NumCycles] =BEGINresetMap[];setBrForMap[r,c];map _ 0, B _ p;t _ t - 80;-- subtract time readMapIF NOT ((t _ t-80) <=0) THEN WHILE t>0 DO t _ t-1;[pipe3,pipe4] _ readMap[r,c]; -- readMap takes about 80 cyclesIF pipe3 # p THEN ERROR;END;%egp$-a>N bAqa* ^Z ]K \ZY!XUWUTS_R"P+O+Ni+ K?JIs3H6FE+D}C@ @J?>J)= ;9T 86 5 3 10 /h=.*, +*r)4 +'2&>%|$> # !N bAq _p ]K\q ZY + WpqU TS_R" P1aJEDORADO:memrwX.mcMay 14, 1981 2:25 PM%5* September 13, 1979 4:42 PM%Read and Write the Map%mapRWtest:* read and write the mappushReturn[];checkMtest[memFlags.mRW, mapRWdone];call[clearCacheFlags];* just incase beingLoaded is setcall[iMpatCtrl];mapMainL:* MAIN, OUTER LOOPcall[nextMpat];skpif[alu#0];branch[mapRWdone];noop;call[iMcolCtrl];* init column controlmapRWcolL:call[nextMcol];* returns w/ fast br indicating exit conditionskpif[alu#0];branch[mapMainL];* column loop done; try next hi-order bit of vaMcol _ t;call[resetMap];* fix arbitrary initial map states, remove any faults.call[iMrowCtrl];mapRWrowL:* the INNER WRITE loop. most complete in < 2 mscall[nextMrow];* this subr SETS Mrow itself!skpif[alu#0];branch[mapRWchk];noop;call[getMpat];* make sure MpatHi, MpatLow correctcall[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%egp$-a>N bAq a&_p ]Kq Zp +qY XU$W+U Tp+qS_R" POM,+ Kp Jq+.Is H6+/FD}+6C@ Bp +q/@+? >J= ; +#:865 +) 4^p3 q0 /h.*+*rp,&\)4<'G &X %YD1BDORADO:memrwX.mcMay 14, 1981 2:25 PM%6* February 10, 1981 9:54 AM* now that we have written the map, lets check it!mapRWchk:call[iMrowCtrl];mapRWchkL:* INNER CHECK loopcall[nextMrow];* this subr SETS Mrow itself!skpif[alu#0];branch[mapRWcolL];noop;call[getMpat];call[readMap];* rtn w/ rscr=pipe3, rscr2=pipe4Q _ rscr2;* copy pipe 4 for future reference.t _ rscr;* remember pipe3 in rscr for a whilet _ t # (MpatLow);* compare pipe3 w/ expected valueskpif[alu=0];* bad bits in T, expected val in MpatXrwPipe3Er:error;* map value in rscr. See pipe for VAt _ ldf[rscr2, 2, pipe4.dirtyShift];* rt justify the diry, wprotect bits fromt#(MpatHi);* the copy of Pipe4 that is in rscr2.skpif[ALU=0];* T= wprotect,dirty from pipe4, MpatHiXrwPipe4Er:* 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 parityerror;* 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 maperror;* 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 isinteresting because reading is implemented by using the write logic and turning off the write signalat the last minute.Mrow_ t_ 10c;* write map w/ row=col=10Bcall[setBRforMap], Mcol_t;rscr_ a1;call[writeMap], rscr2_ a1;* write it w/ all onescall[readMap];(rscr)#(177777C);* rscr= map value. should be -1skpif[alu=0];xRWreadBad:error;call[readMap];* see if last time we read map it(rscr)#(cm1);* clobbered this locationskpif[alu=0];xRWreadBad2:error;* rscr= map value. should be -1noop;returnP[];egp$-a>N bAq a2 ^pq]K \pq+Z+Y XUWU T +S_ +#R"+$P+!O +% Nip M,q+pJq$+)Is +%H6 +' Fp +q*E+(D}B+@ ?p+q*>J+&= H;+9T86 5p+q'4^+!3 :0 /hp .*qc ,d +)4 +'&%|+$> #+! p qH +! + Rp q+  9CR%DORADO:memrwX.mcMay 14, 1981 2:25 PM%7* September 13, 1979 4:43 PM%mapAddrTestTest the addressing mechanism of the map. This testfollows 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 exactlywhich 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 descentaddressing test, otherwise proceed to step 1.(Descent test) Zero the memory, then proceed as in the ascent test, except we descend through thememory (decrement) rather than ascend (increment).(Ascent error routine) Denote the "error address" as the clobbered address discovered in the ascenttest. The ascent error routine proceeds by zeroing the memory, then ascending thru the memory asfollows:1) If the error address is nonzero, the last store which the ascent error routine madeclobbered 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 anintermittent 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 setcall[xZeroMap];call[iMapPageCtrl];xUpL:call[nextMpage];* rtns w/ t = next page, fast br conditionskpif[ALU#0];* tells if we're done w/ loop.branch[xUpXit];noop;* for placementcall[xReadMapPage];* current address should still be zeroPD _ t;skpif[ALU=0];branch[xErrUp];* a previous store clobbered current addrcall[getMpage];* get current addr into t againcall[xWriteMapPage], rscr _ cm1;* set current addr to all onesbranch[xUpL];xUpXit:call[xZeroMap];call[iMpageDownCtrl];xDownL:call[nextMpageDown];* rtns w/ t = next page, fast br conditionskpif[ALU#0];* tells if we're done w/ loop.branch[xDownXit];noop;* for placementcall[xReadMapPage];* current address should still be zeroPD _ t;skpif[ALU=0];branch[xErrDown];* a previous store clobbered current addrcall[getMpage];* get current addr into t againcall[xWriteMapPage], rscr _ cm1;* set current addr to all onesbranch[xDownL];xDownXit:returnP[];top level;egp$-a>N bAq a _p +q3 ^J \wp q4Zf^Y)\W#V4Up[T3- R"p qT P2 NpqO M` LXJGWI \G%F3EQ\D0 AI @[ ?p =q <%+;e+!:'8 7p6oq+*51 +32+0;+&.- ,+)*+(+' &Op%q# !Yp q+* +c++&m 0+)+w+: p q  D  C]((DORADO:memrwX.mcMay 14, 1981 2:25 PM%8* December 25, 1978 11:09 AMxErrUp:* The ascent test has discovered a clobbered locationin 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 mapcall[iMapPageCtrl];* loop initcall[xReadMapPage], t _ r0;* make sure we succeeded in zeroing thePD _ t;* first location of the mapskpif[ALU=0];xUpErr1:* first entry in map is non zero. this suggests thatxZeroMaperror;* didn't worknoop;* for placementxErrUpL: * Top of loop that ascends memory looking for the store that clobbers the errorcall[nextMpage];* location (held in stack).skpif[ALU#0];* intermittent error if no more map pagesbranch[xErrUpIntermittent];noop;* for placementcall[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 sincecall[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 placementbranch[xErrUpL];xErrUpIntermittent: * Can't find error ascent test found (entry at "stack" gets clobbered).error;xErrDown:* The descent test has discovered a clobbered locationin the map. Now we proceed to determine which store clobbers that location.call[getMpage];stack&+1 _ t;* stack = map page that clobberedcall[xZeroMap];call[iMPageDownCtrl];xErrDownL:* top of loop that descends the map memorycall[nextMpageDown];skpif[ALU#0];* intermittent error if no more map pagesbranch[xErrDownIntermittent];noop;* for placementcall[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 anintermittent failue since* the descent test discovered that errror address was clobbered by a store we've* already performed. Sigh.call[xWriteMapPage], rscr _ cm1;* WRITE mapbranch[xErrDownL];xErrDownIntermittent: * Can't find error descent test found (entry at "stack" clobbered).error;egp$-a>N bAq ap+q5 _L^]K +&\+Z+ Y+'XU+W Up+q4 TS_+ R"+ OpqPNi+M, +)KJ+Is+(H6F Epq<D}B+,@ +%? +&>J+ = P;;:+9T 8pqH6 4^p+q6 3 K10 +!/h.* +p +q**r)4 +)'&+$>+(#! p qEH +%R +1 P\+  pqDf t DY;DORADO:memrwX.mcMay 14, 1981 2:25 PM%9* December 28, 1977 8:59 AM%Test MAP TIMING ATTRIBUTESFOR cycles _0,cycles _ cycles+20000B UNTIL cycles >=60000B DOFOR patx IN PatX DOFOR hi2BRbits IN[0..3] DOFOR row IN Row DOFOR col IN Column DOpat _ 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 PMmapRWtest2: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 waitcall[nextMwait];skpif[alu#0];branch[map2RWdone];* wait loop done. try next hi order bitnoop;* throw away result. we'll get it again.call[iMpatCtrl];map2PatternL:* LOOP: Pattern Controlcall[nextMpat];skpif[alu#0];branch[map2CyclesL];* have used all patterns. try next wait valuenoop;call[iMrowCtrl];map2RWrowL:* LOOP: Map Rowcall[nextMrow];* this subr SETS Mrow itself!skpif[alu#0];branch[map2PatternL];* rows done. try next high order Va bit valuenoop;call[iMcolCtrl];* init column controlmap2RWcolL:call[nextMcol];* returns w/ fast br indicating exit conditionskpif[alu#0];branch[map2RWrowL];* column loop done; try next rowMcol _ t;call[getMpat];call[getMwait];rscr _ t;* assumes rscr = cycles to wait.rscr2 _ r0;* dont call resetMapcall[testMap];* test current branch[map2RWcolL];map2RWdone:returnP[];egp$-a>N bAq a%Z_p ^q=]K\ZY$XU!$W'$UTS_R" P NiX M, K Isp 1H6q 1FC1E1D} C@p q"1B1@ 1?'1>J'(1; :p q19T18 16-1513  1p q101/h 1.*-1,1*r )4p 1'q.1& 1%|1$>1# 1!1 1H 1 %1 p 1Rq  /? MDORADO:memSubrsA.mcJune 9, 1981 11:14 AM%1%June 9, 1981 11:15 AMAdd iMemState to init sTestReg from IM.May 14, 1981 4:33 PMadd rlinkRet, etc. to reduce size of add/remove/only ??board testsJune 27, 1979 7:06 PMMake orMemFlags, andMemFlags, and xorMemFlags global to save IM space.May 7, 1979 4:04 PMFix register clobber bug in memory simulator task.April 19, 1979 12:57 PMInitialize memory simulator task's membase, baseregisters.April 17, 1979 10:43 PMCause memSim code to notice that taskSimulation is disabled (make holdSim independent of tasksim).January 17, 1979 9:35 AMsInterference test calls sUseDefaultMcr (saSetMcr now defunct).January 13, 1979 12:39 PMdiddles to get mema to placeJanuary 13, 1979 2:45 AMcomment-out "breakpoint" in midas subroutines: microD can't place memAJanuary 13, 1979 12:50 AMAdd 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]; gp#_ . ?sN bAq `0^' ]\wB ZfY)F WU2 SR: PzO=] M KJ? HGb EQDF B@I > ; : 9T 6p q 54^3 3 pq 108 /hp.*q ,B;ADORADO:memSubrsA.mcJune 9, 1981 11:14 AM%2* May 7, 1979 4:04 PM%Task Simulator Code for Memory Storage DiagnosticThis code runs when the Dorado task simulator awakens task 17. Its purpose is to cause multi-taskmemory activity during the memory storage test. The storage diagnostics continually cause misses, andthis code is set up to fetch & store from a roving pointer (increment can be patched to zero). Thereis 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 inbold. These values can be patched using Midas; changing the delay constant will modify the amount oftime the memory task spends being held by its fetches, and changing the address increment may modifythe row selected by the memory task during its fetches. Note that only one row is touched by thememory task with an increment of cdMaxVa.simScr0 The address that we fetchsimScr1 The data obtained from MD when this task woke upsimScr2 Used as a scratch register to remember the current hold vaule, also loaded with a loopconstant for the memSimL1 loop. The memSimL1 loop prevents task 17 from using all the machine by doingreferences that always hold. The smaller the constant (see memSimSetDelay), the more frequently task17 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 codememSimInit:t _ q,at[memSimInitLoc];hold&tasksim _ t;* zero hold if that is what is happeningt _ t and (sim.taskMask);* do nothing if not tasking (allow hold sim)skpif[alu#0];* see if we are really supposed to runblock;* no, just turning off holdRBASE _ rbase[defaultRegion];call[setMbase],t_12C;* set memBase, BR for this taskt _ rscr _ t-t;call[setBR], rscr2_t;RBASE _ rbase[simScr0];t _ q;* restore t = holdValuebranch[memSimFetchNextTime], FETCH _ simScr0;memSimL1:* top of delay loopsimScr2 _ (simScr2) - 1;* we'll make memory references only afterskpif[alu>=0];* waiting a while. This enables the relativelybranch[memSimFetchNextTime];* slow memory diagnostics to make progress.hold&tasksim _ t;* otherwise, most real time is spent w/ memorynoop;* task being held.branch[memSimL1], block;* Still waiting.memSimFetchNextTime:hold&tasksim _ t;fetch _ simScr0;* remember 1st instr. after hold_ doesn't countblock;memSimFetchMD:simScr1 _ MD;* fetch the memory data waiting for ussimScr2 _ t;* save t, our hold value, for future useFETCH _ simScr0;* fetch it again in preparation for storing itt _ MD;* get data for our storememSimStore:STORE _ simScr0, DBuf _ t;* store the data we just readt _ simScr2;* restore hold value in TmemSimSetDelay:simScr2 _ 25c;* reset the delay counterhold&tasksim _ t;* remember 1st instr. after hold_ doesn't countnoop;memSimIncAddr:branch[memSimL1], simScr0 _ (simScr0) + (cdMaxVa), block;* selects gp#_ . ?sN bAq a^1 \b [e Zfd Y)f Wb Ud Td S_` R") Ppq Npq2 MpqX LXf Kd I( Gp qS Ep qK Cp qN @? >J + = p ;q+:+(9T+,8 +&6+54^+3 10/h+.*- +p+q*r+))4 +.'++&+.%|+$>+ #p!q +/H  p q +& +(+.+ p \q+ + pfp + q+/  pp  3p984 : E3]FDORADO:memSubrsA.mcJune 9, 1981 11:14 AM%3* a different addr without changing the row!knowRbase[defaultRegion];set[xtask, 0];* emulator code gp#_ . ?sN+bAq,a_ + ^f=y 'DORADO:memSubrsA.mcJune 9, 1981 11:14 AM%4* May 14, 1981 4:29 PMorMemFlagsAndExit: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 testsbranch[orMemFlagsAndExit], t _ memFlags.Cboard;* add Cboard testaddXboardTest: 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 testsbranch[orMemFlagsAndExit], t _ memFlags.Xboard;* add Xboard testaddDboardTest: 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 testsbranch[orMemFlagsAndExit], t _ memFlags.Dboard;* add Dboard testaddSboardTest: 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 testsbranch[orMemFlagsAndExit], t _ memFlags.Sboard;* add Sboard testaddAboardTest: 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 testsbranch[orMemFlagsAndExit], t _ memFlags.Aboard;* add Aboard testaddAllTests: subroutine;saveReturn[rlink];t _ memFlags.default0;t _ t + (memFlags.default1);branch[orMemFlagsAndExit];removeAllTests: subroutine;saveReturn[rlink]; gp#_ . ?sN bAq ap_q^ \pqZY Wp q UT/ S_pq R"P5 Opq NiM,+K/0Z Isp q H6F/ Epq D}C@5 Bpq @?+>J/0Z ;p q :9T/ 8pq 655 4^pq 3 1+0/0Z .*p q ,+/ *rpq )4'5 &pq %|$>+#/0Z p q H / pq R5 pq +\/0Z p q f)  ppq  34 0]2DORADO:memSubrsA.mcJune 9, 1981 11:14 AM%5branch[andMemFlagsAndExit], t _ t-t;orMemFlags: subroutine;* save the bits to xorsSubrScr _ t, global;t _ link;top level;Srlink _ t;t _ memFlagsLocC;* get current flag bitscall[getIMRH];call[getsSubrScr], rscr _ t;* re-fetch bits to xorrscr _ t OR (rscr);* xor the bitst _ memFlagsLocC;call[putIMRH];* save new bit valuesreturnUsing[Srlink];andMemFlags: subroutine;* save the bits to xorsSubrScr _ t, global;t _ link;top level;Srlink _ t;t _ memFlagsLocC;* get current flag bitscall[getIMRH];call[getsSubrScr], rscr _ t;* re-fetch bits to xorrscr _ t AND (rscr);* xor the bitst _ memFlagsLocC;call[putIMRH];* save new bit valuesreturnUsing[Srlink];xorMemFlags: subroutine;* save the bits to xorsSubrScr _ t, global;t _ link;top level;Srlink _ t;t _ memFlagsLocC;* get current flag bitscall[getIMRH];call[getsSubrScr], rscr _ t;* re-fetch bits to xorrscr _ t # (rscr);* xor the bitst _ memFlagsLocC;call[putIMRH];* save new bit valuesreturnUsing[Srlink]; gp#_ . ?sNbAq$ _p q +^]K\ Z Y+XU W+U+ TS_ +R" Op q +NiM,K J Is+H6 F+E+ D}C@ +B ?p q +>J= ; : 9T+8 6+5+ 4^3 +1 0/]7DORADO:memSubrsA.mcJune 9, 1981 11:14 AM%6* 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 useTestSynreturnUsing[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 usingOneColumnreturnUsing[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 usingOneColumnreturnUsing[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.loopOnErrorsaveReturn[Arlink];call[getMemState];t _ t OR (memState.loopOnError);* OR in the bitcall[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.loopOnErrorsaveReturn[Arlink];call[getMemState];t _ t OR (memState.noWake);* OR in the bitcall[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 gp#_ . ?sN bAq aR _ ^ ]Kpq \ZYXUW T S_S R" Opq NiM,KJ$+Is F EM D}W Bp q @?>J!= 9; 9T 8N 6W 4^pq 3 10$/h#+.* + *rP )4W ' %|p q +$>! +H   Rd p q ++f  e 3p q +~ C]DORADO:memSubrsA.mcJune 9, 1981 11:14 AM%7saveReturn[Arlink];call[getMemState];rscr _ not(memState.noWake);call[putMemState], t _ t AND (rscr);* remove the bitreturnUsing[Arlink];* October 1, 1978 4:16 PM* turn on memstate.FIOtest. FIOtest only runs if this bit is true.FIOtestOn: subroutine;* set memState.loopOnErrorsaveReturn[Arlink];call[getMemState];t _ t OR (memState.FIOtest);* OR in the bitcall[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.loopOnErrorsaveReturn[Arlink];call[getMemState];rscr _ not(memState.FIOtest);call[putMemState], t _ t AND (rscr);* remove the bitRBASE _ 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.noWakesaOrMcrWake: subroutine;saveReturnAndT[sRlink, sSubrScr];* note: using sRlink, sSubrScrcall[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.loopOnErrorsaveReturn[Arlink];call[getMemState];rscr _ not (memState.loopOnError);t _ t AND (rscr);* remove in the bitcall[putMemState];returnUsing[Arlink];* April 26, 1978 1:46 PMloopErrorOccured: subroutine;* SET memState.loopErrorOccuredsaveReturn[Arlink];* this bit remembers an error so that thet _ memFlagsLocC;* appropriate test will continue to loop evencall[getIMLH];* tho the error may be intermittentt _ t OR (memState.loopErrorOccured);call[putMemState];returnUsing[Arlink];* January 5, 1979 12:07 AMcheckMemState: subroutine;saveReturnAndT[Arlink, AsubrScr]; gp#_ . ?sNbAq_^]K$+\ Y XUB Up q +TR"P+ONiM, K) J IsC Fp q +EC@B@$+?>J = ) ; : 9T 88 6I 4^p q 3 !+p1q)0/h.*,+ )4 'Y &X %| #pq +!H "+R  pq +\+)+- +#%f)  pp q  3!, >%]DORADO:memSubrsA.mcJune 9, 1981 11:14 AM%8call[getMemState];call[getAsubrScr], rscr _ t;t _ t and (rscr);* mask the bitsreturnAndBranch[Arlink, t];* June 9, 1981 11:09 AMiMemState: 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 RMt _ memFlagsLocC;call[putIMLH];returnUsing[AsubrScr]; gp#_ . ?sNbAqa_+^ \ Zp q YXUW U T S_p q R"P5 Op q NiM,K+JIs H6" F4!6mDORADO:memSubrsA.mcJune 9, 1981 11:14 AM%9* January 5, 1979 11:54 AM%multi task storage diagnostic: Midas subroutineThis test presumes that the memory task runs and creates interference. The user is responsible forinvoking 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 munchFOR x IN [0..15] DOva _ x + unique;mem[va] _ va;ENDLOOP;unique _ unique + 1000B;* doesn't change the row selectedFOR x IN [0..15] DOva _ x + unique;mem[va] _ va;ENDLOOP;-- This is the read/check portion, broken into two loops, one for each munchunique _ unique - 1000B;FOR x IN [0..15] DOva _ x + unique;IF mem[va] # va THEN ERROR;ENDLOOP;unique _ unique + 1000B;FOR x IN [0..15] DOva _ 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 munchsInterfereWL1:* top of write loopt _ (sva) + (q);* t _ sva + uniqueSTORE _ t, DBuf _ t;* mem[sva] _ sva + jloopuntil[cnt=0&-1, sInterfereWL1], sva _ (sva) + 1;IsInterfereW2:t _ q;t _ t + (cdMaxVa);* Increment unique by a number that won'tq _ t;* change the row indexsva _ t-t;cnt _ 17s;sInterfereWL2:* top of write loopt _ (sva) + (q);* t _ sva + uniqueSTORE _ t, DBuf _ t;* mem[sva] _ sva + jloopuntil[cnt=0&-1, sInterfereWL2], sva _ (sva) + 1;IsInterfereR1:t _ q;t _ t - (cdMaxVa);* decrement unique to its old valueq _ t;sva _ t-t;cnt _ 17s;* once for each word in the munchsInterfereRL1:t _ (sva) + (q);* t _ sva + uniqueFETCH _ t; gp#_ . ?sN bAq a^0 \b Z= XU W!++ U TVGSQPW OM+!LXJI HYFLEDZBA@[>=<:98&6 2L1 /p.q+$-V,+ *p )q (` +! '#p +q%+$+#j4 "-p  q+)t+7  p +q~+A+4 p Kq +# U +! p  q+  yB]&DORADO:memSubrsA.mcJune 9, 1981 11:14 AM%10rscr2 _ 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 valueq _ t;sva _ t-t;cnt _ 17s;* once for each word in the munchsInterfereRL2:t _ (sva) + (q);* t _ sva + uniqueFETCH _ 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 uniquerscr _ 7c;* construct a mask that affects onlyrscr _ lsh[rscr, skipCacheShift];* cacheA bits in address:t _ t AND (rscr);* don't let it change to much! This facilitatesq _ t;* more "collisions" in memory tasksva _ t-t;branch[IsInterfereW1]; gp#_ . ?sNbAq +a _ ^p]Kq +\4 Yp XUqW+&UT S_ +! R"p Pq+O Ni +M, K JpIsq +H64ED}+C@ +$B!+@+/?+">J = > ;?},_DORADO:memSubrsA.mcJune 9, 1981 11:14 AM%11* September 25, 1978 5:14 PM%aHaltTask17Set tpc[17]_7777C. We depend upon midas keeping a breakpoint in IM at this location. Thus iftask 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 PMaChkPipeFlt: subroutine;* check pipe2 to see if there's been a faultsaveReturn[Arlink];* IF NOT return w/ alu=0 fast branch conditiont_ rscr2 _ not(Pipe2'[]);rscr _ pipe2.nFaults;* IF faults THEN procsrn _ firstFault, returnt _ t AND (rscr);* with alu#0 fast branch conditiont _ t # (rscr);branch[aChkPipeFltXit, ALU=0], rscr _ t;* nFaults=nFaults mask ==> no faultsrscr2 _ (rscr2) AND (pipe2.faultSrn);PROCSRN _ rscr2;rscr _ t;* t has (nFaults#mask) which must be #0 to be hereachkPipeFltXit:returnAndBranch[Arlink, rscr];top level;memSubrsADone: branch[afterSubrs]; gp#_ . ?sN bAq a_p ^q\ ]KV Z Y XUp q W U TS_ R" P O Ni M, K J Is F Ep q +,D}+.C@B+-@+"?>J(+$= %;:+2 9Tp8q6 5p q 4;BE3MODEL 1: memSubrsC.mcJune 9, 1981 10:35 AM%1%*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++Table of Contents byOrder of OccurenceTESTDESCRIPTIONinitBrsInitialize base register loop controlinitCPatternsInitialize cache pattern loop controlinitRowCtrl:Init cache row loop controlinitRowDownInit cache row Descending loop controlinitColCtrlInit cache column loop controlinitCol2CtrlInit second cache column loop controlinitFlagsCtrlInit cflags pattern loop controlgetCvaReturn current value of cvagetSubrScrReturn current value of subrScrgetcBrCacheABitsreturn current value of cBrCacheAbitsnextBrReturn value of next BRnextColReturn value of next columnnextCol2Return value of next column2 (ther's two loop variables, col & col2).getCol2Return current value of column2nextRowReturn value of next cache rownextRowDownReturn next value of row, descending loop controlgetCrowReturn current value for cache rownextCFlagReturn next value for CFlagsgetCflagReturn current value of flagsValnextCPatternGenerate next cache pattern. Return ALU=0 when no moregetCPatternGenerate current pattern based on currnet pattern index (changed by nextCPattern)mcrForColSet mcr for current column, extra flags passed in tvaForRowReturn in T a va that matches row in T upon entrycRowForVaReturn cache row in T for va in T upon entrycVaForCrowColReturn va that matches row in T, col in rscr.makeUseMcrVConstruct mcr value and forces useMcrV for column in TsetBrCacheABitsSet hi 15 bits of memory base registersetBrBrLo _ rscr2, BrHi _ rscr15 bits of memory base registersetBrBrLo _ rscr2, BrHi _ rscrsetMCRmcr _ tlongWaitWait number of cycles in T where T = 0 or T>3. Count doesn't include call andreturn overheadcheckMemFlagsSubroutine that returns w/ ALU#0 if any memflags in T are setsetMbaseSet current memBase to TclearCacheFlagsSet entire cache to vacantsetCAmemSet cacheA memory w/ va = addr to write, col = column selectsetCflagsSet cache flags for T = va, rscr = pattern, col = columnputCFmemSet cache flags t = va, rscr = flags, rscr2 = columnputCAmemSet CacheA memory: t = va, rscr = brhi15, rscr2 = columnzeroCacheAndFlagsZero cacheAmem and zero cache flagsreadCflagsread flags for rscr = va, rscr2 = columngetPipeCacheABitsreturn h 15 bits of pipe VA in TchkPipeRowEnter w/ t = row, check that pipe1.row = t (ALU#0 if false)chkPipe5ColRTN ALU#0 if pipe5.col # TchkCflagsRTN T #0 if (rscr.cflags) # tsetRegs0(rscr,rscr2,t) _ (RM 0, RM 1, RM 2) midas subroutinesetRegs1(rscr,rscr2,t) _ (RM 3, RM 4, RM 5) midas subroutinesetRegs2(rscr,rscr2,t) _ (RM 6, RM 7, RM 10) midas subroutine%*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++%June 9, 1981 10:35 AMAccommodate default values for memState (left half of memFlags)May 21, 1981 4:32 PMFix setMbase to use bmux rather than bdispatchFebruary 5, 1981 6:02 PMRemove forceRbase because d1lang now accommodates our need. Change brx to cBrX toaccommodate change in memdefs required by changes to d1lang.Trying to find obscure problem, posibly related to some debugging instructions' not beingHeld. add '_MD' to zeroCacheAndFlagsJuly 1, 1979 2:39 PMAdd table of contents, cause cRowForVa to use ldf rather than two constants & clobberrscr2.May 29, 1979 11:07 AMModify clearCacheFlags to use putCFmem.%gp-j>N bAqB'^ap( _ ]Kq Zp q% Yp  q% XUp  q Wp  q& Up  q Tp  q% S_p  q R"p q Pp  q Op q% Nip q M,p q Kp qE Jp q Isp q H6p  q1 Fp q" Ep q D}p q C@p  q6 Bp  qQ @p q3 ?p q1 >Jp q, = p  q- ;p  q6 :p q& 9Tp q8 8p q 6p q 5p qM 4^ 3 p  q= 1p q 0p q /hp q= .*p q8 ,p q4 +p q8 *rp q# )4p  q( 'p q &p  q< %|p  q $>p q #p q4 !p q4 p q5 HB  ? R. R \<Y % f)U   p' 3 Dw]MODEL 1: memSubrsC.mcJune 9, 1981 10:35 AM%2title[memSubrsC];top level;subroutine;* February 5, 1981 6:07 PMinitBrs:t _ cm1;return, cBrX _ t;initCPatterns:RBASE_ rbase[patX];t_patX _ cm1;curPattern _ t;return, RBASE_ rbase[defaultRegion];initRowCtrl:t _ cm1;return, rowx _ t;initRowDown:t _ rowEndC;return, rowx _ t;initColCtrl:t _ cm1;return, colx _ t;initCol2Ctrl:t _ cm1;return, col2x _ t;initFlagsCtrl:RBASE_ rbase[flagsVal];flagsVal _ (flagsVal)-(flagsVal);flagsVal _ (flagsVal)-(20c);* first val returned will be zeroreturn, RBASE_ rbase[defaultRegion];getCva: subroutine;RBASE _ rbase[cVa];return, t _ cVa, RBASE _ rbase[defaultRegion];getSubrScr: subroutine;RBASE _ rbase[subrScr];return, t _ subrScr, RBASE _ rbase[defaultRegion];getcBrCacheABits: subroutine;RBASE _ rbase[cBrCacheAbits];return, t _ cBrCacheAbits, RBASE _ rbase[defaultRegion];nextBr:* compute mem base reg; return it in T* January 1, 1979 3:04 PMRBASE_ rbase[cBrX];* compute end of base regs as branch conditiont_cBrX_(cBrX)+1;RBASE_ rbase[defaultRegion];return,t-(brEndC);nextCol:* compute next column; return it in TRBASE_ rbase[colx];* compute end of columns as branch conditiont_colx_(colx)+1;RBASE_ rbase[defaultRegion];return,t-(colEndC);nextCol2:* compute next column; return it in TRBASE_ rbase[col2x];* compute end of columns as branch conditiont_col2x_(col2x)+1;RBASE_ rbase[defaultRegion];return,t-(colEndC);getCol2:* return current row in TRBASE_ rbase[col2x];return, t_col2x, RBASE _ rbase[defaultRegion];nextRow:* compute next row; return it in TRBASE_ rbase[rowx];* compute end of row as branch conditiongp-j>N aq _ ^ ]K ZpYqXU Up TqS_ R"P$ Op NiqM, Kp Jq Is H6p FqE D}p C@qB ?p >Jq= !;+!:$ 8pq 65. 3 p q 102 .*pq ,+8 )4p+q& '&+.%|$># p+q%H+,  p+q%+,\ p+qf). pp+q" 3+(@ >]MODEL 1: memSubrsC.mcJune 9, 1981 10:35 AM%3t_rowx_(rowx)+1;RBASE_ rbase[defaultRegion];return,t-(rowEndC);nextRowDown:* compute next row(descending); return it in TRBASE_ rbase[rowx];* compute end of row as branch conditiont_rowx_(rowx)-1;RBASE_ rbase[defaultRegion];return,t-(cm1);getCrow:* return current row in TRBASE_ rbase[rowx];return, t_rowx, RBASE _ rbase[defaultRegion];nextCFlag:* return next cache flag value in TRBASE _ rbase[flagsVal];* return w/ fast branch conditiont _ flagsVal _ (flagsVal)+(20C);RBASE _ rbase[defaultRegion];return,t-(flagsEndC);getCflag:* return current row in TRBASE_ rbase[flagsVal];return, t_flagsVal, RBASE _ rbase[defaultRegion];gp-j>NbAqa_ ^p +q.]K+(\ZY Wp+qUT- R"p +q#P+!ONiM, Kp+qJIs1 H>nMODEL 1: memSubrsC.mcJune 9, 1981 10:35 AM%4* December 26, 1978 11:16 AM%Cache Pattern loop control: There are three sets of patterns. The first is a left cycled, single onebit. The second is a left cycled, single zero bit, and the third is a composite number = (current rowlshift 3)+ current column. This routine returns an ALU result upon exit whose zero result means thereare no more valid patterns. To obtain the actual pattern, the diagnostics use the subroutinegetCpattern.nextCPattern: PROCEDURE RETURNS[morePatterns: BOOLEAN] =BEGINpatX _ patX + 1;SELECT patX FROMIN [0..Pat1EndC) => curPattern _ doPat1[patX, curPattern];IN [Pat1EndC..Pat2EndC) => curPattern _ doPat2[patX, curPattern];IN [Pat2EndC..Pat3EndC) => curPattern _ doPat3[patX, curPattern];ENDCASE => NULL;morePatterns _ patX >= LastPatCEND%nextCPattern:* compute next pattern index; return in tRBASE_ rbase[patx];* compute end of patterns as branch conditionpushReturn[];* save return linktop level;t_patx_(patx)+1;* keep patX in Tt-(pat1EndC);* see if IN [0..pat1EndC)branch[nxtPat2, alu>=0],t_t;* goto[nextPat2, ~IN [0..pat1EndC)]* IN [0..pat1EndC)skpif[alu#0];* see if just initializedskip, curPattern _ 1c;* patX=0 ==> begin with onecurPattern_(curPattern)+(curPattern);branch[nxtPatXit];nxtPat2:* see if IN[pat1EndC..pat2EndC)t-(pat2EndC);branch[nxtPat3, alu>=0];* goto[nextPat3, ~IN[pat1EndC..pat2EndC)]* IN [pat1EndC..pat2EndC)curPattern _ lcy[curPattern, curPattern, 1];t - (pat1EndC);* If first time thru pattern 2, initskpif[ALU#0];* curPattern for left cycled zero pattern.curPattern _ not(b15);branch[nxtPatXit];nxtPat3:* are we IN [pat3EndC..lastPat) ??t - (pat3EndC);branch[nxtPat4, alu>=0];curPattern _ (curPattern)-(curPattern);* Zero it since getCPattern constructsbranch[nxtPatXit];* each value separately.nxtPat4:branch[nxtPatXit];* add code here for another pattern.nxtPatXit:link _ stack&-1;* restore return link, fix up rbase,subroutine;RBASE_ rbase[defaultRegion];return,t-(lastPatC);* return w/ proper branch conditiongp-j>N bAq a _d ^e ]Ke \\ Z XUp q+ W U TS_:R"APAO Ni M, K Jp +q)Is+-H6 +F E+D} +C@+# @? +>J+= %; 9Tp+q8 6+) 4^3 ,1+$0 +*/h.* +p+q"*r)4''+&&+ $>p#q+$ !p  q+$H  +# mDLMODEL 1: memSubrsC.mcJune 9, 1981 10:35 AM%5* December 25, 1978 11:53 AMCache Test General SubroutinesgetCPattern:* compute next pattern; return it in T%Currently there are three sets of patterns. The first set consists of a cycled one. The secodpattern is a cycled zero, and the third is a series of unique values based on row and column.pattern1 and pattern2: maintained by the nextPattern code -- it changes when "next pattern" is called.pattern3 changes more frequently (for every column!)pattern3: OR the quantity (row lshift 3) + column into curPattern.Eg., if curPattern = 0, row = 22, col = 3 THEN result = 223%RBASE_ rbase[patx];pushReturn[];top level;(patx)-(pat2EndC);* see which pattern we are usingbranch[getCP2,alu>=0];branch[getCPXit], t_(curPattern) and (CABitsMaskC);* handle BOTH pattern1, pattern2 heregetCP2:* return pattern 2 or greater(patx)-(pat3EndC);branch[getCP4, alu>=0];subrScr _ q;* ROW kept in Q!!!RBASE _ rbase[defaultRegion];* fetch value of colt _ col;RBASE _ rbase[rmForLoops];subrScr _ lsh[subrScr, 3];t_t OR (curPattern);* curPattern,,columnbranch[getCPXit], t_t OR (subrScr);* curPattern,,row,,columngetCP4:* add code for pattern 3 herebranch[getCPXit];getCPXit:RBASE_rbase[defaultRegion];returnP[];knowRbase[defaultRegion];gp-j>N bAq+ _p +q& ^]K] \] Zf Y4 XUB W; UTS_ R" P+ONi32% Kp+qJIsH6 +F+ED}C@B+@#+ >Jpqp+q=  :p9Tq8 5 4;D3MODEL 1: memSubrsC.mcJune 9, 1981 10:35 AM%6* December 7, 1978 3:04 PMmcrForCol: subroutine;* set mcr for current column%extra falgs to set are passed in T.This code uses an array of four mcr values that is stored in IM at caMcrLoc..caMcrLoc+3. There is anmcr value for each column, plus bits for useMcrV, disCF, and disHold.%rscr _ mcr.useMcrV;rscr _ (rscr) OR (mcr.disCF);rscr _ (rscr) OR (mcr.disHold);rscr _ (rscr) OR (mcr.noWake);rscr _ (rscr) or t;* Or in the extra bitst _ lsh[col, mcr.mcrVshift];* position the column for mcrt _ t or (rscr);noop;* assure there's 8 cycles from time ofloadMcr[t,t];* last memory referencereturn;vaForRow:* construct va that matches row in T* clobber T and rscr2t _ lsh[t, cacheShift];rscr2 _ cacheRowMask0;rscr2 _ (rscr2) OR (cacheRowMask1);return, t_tAND(rscr2);* isolate bits of rowcRowForVa:* t = va. return the cache row. CLOBBER t, rscr2return, t _ ldf[t, nBitsInRow, cacheShift];cVaForCrowCol:* t = row, rscr = column. RETURN va* CLOBBER T, RSCR, RSCR2t _ lsh[t, cacheShift];rscr _ lsh[rscr, skipCacheShift];return, t _ t or (rscr);makeUseMcrV:* construct an mcr value* that specifies mcr.useMcrV, and selects contents of T as column for victim* clobber T and rscr2t_tAND(3c);* just for paranoiat_lsh[t, mcr.mcrVshift];return, t_t OR (mcr.useMcrV);* rtn w/ t= mcr valuesetBrCacheABits:* set hi 15 bits of memory base reg* Enter w/ T = 15 bit value to use. clobber T, rscr, and rscr2rscr _ rsh[t, CABitsInPipe1];rscr _ (rscr) and (CABitsInPipe0Mask);rscr2 _ lsh[t, CABitsInPipe1Shift];rscr2 _ (rscr2) and (CABitsInPipe1Mask);BrHi _ rscr;return, BrLo _ rscr2;setBR:* rscr2 = brLO, rscr = brHIbrlo _ rscr2;brhi _ rscr;return;setMCR:noop; noop; noop; noop;*NOTE: Hardware constraints require minimumnoop; noop; noop;* of 8 cycles between memops and setting mcr.loadmcr[t,t];* set MCR w/ Tnoop;* wait for MCR to settle downreturn;* December 4, 1978 5:38 PMlongWait: subroutine;* wait (T + 2) cycles where T >3, not counting call orreturn! SPECIAL KLUDGE: IF T=0, return almost immediately (ie. total delay = 2 cycles + call + return)PD_t;* CLOBBER TloopUntil[ALU=0, .], t _ t-1;gp-j>N bAq ap q + _# ^d ]KE \YXUWUT+S_+R"P+&O +Ni Kp+q$ JH6FE#D}+ C@p +q0B+ ?p +q# >J;:!8 5p +q 4^L 3 0 +/h.*+ +p+q# *r>'&&%|#$>(# ! Hpq+   Rpq+++-\ + + f pq +"r q_ p+  3L D]$MODEL 1: memSubrsC.mcJune 9, 1981 10:35 AM%7return;* December 4, 1978 5:39 PMcheckMemFlags: subroutine;* T = memory flags to check* return w/ fast branch condition for flags ON in memFLAGSpushReturnAndT[];t _ memFlagsLocC;call[getIMRH];* get flags into Tt _ t and (stack);* isolate 1 bits in tpReturnPAndBranch[t];* rtn w/ branch condition. bits in tgp-j>NbAq _ ^p q + ]K:ZYXU +W+U+$` S<8BMODEL 1: memSubrsC.mcJune 9, 1981 10:35 AM%8* May 21, 1981 4:32 PM%Set MemBase to value in t.%subroutine;setMbase:* t = value to useMemBase_t, RETURN;gp-j>N bAq a_ ^]K \p+qZ Yp,4MODEL 1: memSubrsC.mcJune 9, 1981 10:35 AM%9* May 29, 1979 11:07 AM%Clear Cache FlagsclearCacheFlags: PROCEDURE =BEGINFOR rowX IN CacheRowX DOt _ getVaForRow[rowX] - cflags.vacant;FOR col IN Column DOmakeUniqueAmemEntryAtRowCol[rowX, col];setBR[0,t];mcrV _ MakeUseMcrV[col];mcrV _ BitOR[mcrV, mcr.fdMiss, mcr.disHold];setMcr[mcrV];dummyRef _ cflags.vacant;CFLAGS _ cflags.vacant;ENDLOOP;ENDLOOP;END;This subroutine causes the entire cache to be cacant. It clobbers MCR, BR%clearCacheFlags:pushReturn[];call[initRowCtrl];clrCacheFrowL:* loop for all the rows of the cachecall[nextRow];skpif[alu#0];branch[clrCacheXit];noop;* for placementcall[initColCtrl];clrCacheFcolL:* loop for the columns in this rowcall[nextCol];skpif[alu#0];branch[clrCacheFrowL];col _ t;* col is the current columncall[getCrow], rscr _ t;* return w/ t = rowXcall[cVaForCrowCol];* t = row, rscr = col, return t = vacall[setCAmem], va _ t;* enter w/ t = va, col = columnrscr2 _ col;rscr _ cflags.vacant;call[putCFmem], t _ va;branch[clrCacheFcolL];clrCacheXit:returnP[];gp-j>N bAq a(`_p ^q ]K\Z&YXU'W UT,S_ R"PONiM, JI Is H6pFq D} C@p +q$B @ ?= +: 9Tp +q"8 6 53 +0+/h+$.*+, +*r)4 &p %|q  $8CMODEL 1: memSubrsC.mcJune 9, 1981 10:35 AM%10* December 4, 1978 5:41 PMsetCAmem:* yet another way to set Amemory* ENTER w/ va = addr to write, col = column to select* CLOBBER T, rscr, rscr2pushReturn[];t _ col;rscr2 _ t;t _ va;call[putCAmem], rscr _ t-t;* call w/ t = va, rscr = brHi15, rscr2 =colreturnP[];setCflags:* T = va, rscr =pattern, col = columnpushReturnAndT[];t _ stack;call[putCFmem], rscr2 _ col;pReturnP[];putCFmem: subroutine;* t = va, rscr=flags, rscr2 = colcva _ t;pushReturn[];t _ rscr;* save flags valuecflagsV _ t;call[makeUseMcrV], t _ rscr2;t _ t OR (mcr.fdMiss);t _ t OR (mcr.noRefHold);call[setMCR];call[getCva];rscr2 _ t;* rscr2 _ cvat _ not(rscr);* t _ cflagst _ t and (cflags.mask);* invert only the cflags bitsrscr2 _ (rscr2)-t;* rscr2 _ cva - flagscall[setBR], rscr _ t-t;dummyRef _ t;CFLAGS _ t;returnP[];putCAmem: subroutine;* t = va, rscr = brhi15, rscr2 = col;cva _ t;pushReturn[];t _ rscr;cBrCacheAbits _ t;t _ col;subrScr _ t;col _ rscr2;t _ (mcr.fdMiss);t _ t OR (mcr.noRef);call[mcrForCol];* no extra flags, use rscr2 as victimcall[getcBrCacheABits];call[setBrCacheAbits];call[getCva];rscr2 _ t;DBuf _ r0, STORE _ T;shortMemWait[rscr];t _ rscr2;* restore t; shortMemWait used itDBuf _ r0, STORE _ T;shortMemWait[rscr];call[getSubrScr];col _ t;returnP[];gp-j>N bAq _p+q ^5 ]K\ ZY XUW++U S_p +q%R"P ONi Kpq +!JIs H6+F ED}C@B @ ? + >J + = +;+:9T 8 6 5pq +%4^3 10.*, *r )4'&+%%|$># !  H +!  9N bAq _pq +! ^]K \+-Z YpXUq W UT+R" PpOq Ni M,KJIsF+$ED} C@B+$?>J+&=  :p9Tq  5x>%2MODEL 1: memSubrsC.mcJune 9, 1981 10:35 AM%12* December 7, 1978 3:11 PMPIPE reading routinesreadCflags:* rscr = va, rscr2 = column* clobber T, rscr, rscr2. Return all the bits from PIPE5 in TpushReturn[];top level;* Set MCR for appropriate column, fdMiss, dPipeVA, disHold (use disBR for convenience)call[makeUseMcrV],t _ rscr2;* setup mcr. RSCR ~clobbered !t _ t OR (mcr.fdMiss);t _ t OR (mcr.dPipeVa);t _ t OR (mcr.disBR);* convenience: needn't load BR!t_tOR (mcr.noRefHold);* mcr.noRef + mcr.disHoldcall[setMCR];dummyRef _ rscr;noop;t _ PIPE5;* now read and remember flags%notice that we don't invert the bits for cflags. To write a set of flags F, the processor must firstinvert F (F'), and then proceed. However, when reading the flags the bitvalues have their "true" sex.%returnP[];* return w/ flag bits in TgetPipeCacheABits: subroutine;* return hi 15 bits of pipe VA in T.* leave rscr2 untouched.* clobber T, rscrt_pipe0;t _ t and (CABitsInPipe0Mask);rscr _ pipe1;rscr _ (rscr) AND (CABitsInPipe1Mask);t_lsh[t, CABitsInPipe1];* hi bits of VA from pipe 0rscr_rsh[rscr, CABitsInPipe1Shift];* isolate mid bits of VA from pipe 1t_t OR (rscr);* add them together and maskreturn, t_t AND (CABitsMaskC);* return: t= hi15 bits of VA rt. justifiedgp-j>N bAq+ ap +q _=]K \ ZVY+XUWU+T+S_ PONi + M, Kd JH Is H6F + D}pq +$ C@ B?>J= ;&:+9T#+$8 +6+* 2C5MODEL 1: memSubrsC.mcJune 9, 1981 10:35 AM%13* December 7, 1978 5:17 PMCache RESULT TESTING subroutineschkPipeRow: subroutine;* enter with T = row. check that pipe1.row = t* clobber T, rscr, rscr2rscr _ (cacheRowMask0);rscr _ (rscr) OR (cacheRowMask1);* construct row bits maskrscr2 _ PIPE1;* NOW CHECK ROW=CACHE BITS. t=ROWt _ lsh[t, cacheShift];T _ (rscr2) # (t);return, T _ (rscr) AND (t);* use row bits onlychkPipe5Col: subroutine;* T=expected col, rscr =PIPE5 value* return w/ T=bad bits, rscr= PIPE5 val. return w/ fast branch condition* CLOBBER rscr2,tt _ t and (3c);* mask for paranoiat _ lsh[t, pipe5.colShift];* position column fieldt_t#(rscr);rscr2 _ pipe5.colBit0;* construct mask to isolate col fieldrscr2 _ (rscr2) + (pipe5.colBit1);return, t_t and (rscr2);* return w/ fast branch conditionchkCflags: subroutine;* T = expected flags, rscr = PIPE5 value* return w/ T=bad bits, rscr = PIPE5 val. return w/ fast branch condition* clobber rscr2, tt_t#(rscr);* isolate different bitsrscr2 _ pipe5.flagsMask;return, t_t and (pipe5.flagsMask);* return w/ fast branch conditiongp-j>N bAq+ _p q +. ^\Z!+Y +!XUWU+ S_p q +# R"H PNi+M,+K J+%Is"H6+! Ep q +( D}I C@@ +?>J"+!> <>+"MODEL 1: memSubrsC.mcJune 9, 1981 10:35 AM%14* February 5, 1981 6:02 PM% subroutines for midas level degbuggingThis code sets rscr, rscr2, and T from RM0 thru RM10%top level;call[setRegs0];* these calls assure that the namedcall[setRegs1];* subroutines really get loaded onto callcall[setRegs2];* locations.noop;* sigh. here for placement.setRegs0: subroutine;RBASE _ 0s;t _ rmx0;rscr _ t;t _ rmx1;rscr2 _ t;return, t _ rmx2, RBASE _ rbase[defaultRegion];setRegs1: subroutine;RBASE _ 0s;t _ rmx3;rscr _ t;t _ rmx4;rscr2 _ t;return, t _ rmx5, RBASE _ rbase[defaultRegion];setRegs2: subroutine;RBASE _ 0s;t _ rmx6;rscr _ t;t _ rmx7;rscr2 _t;return, t _ rmx10, RBASE _ rbase[defaultRegion];data[(memFlags: lh[defaultMemFlagsLeft], rh[defaultMemFlags], at[memFlagsLoc])];gp-j>N bAq a( ^4 ]KT\ TZ#TY)TXU TW Upq TT TS_TR"TPTO TNi/ Kpq TJ TIsTH6TFTE TD}/ Bpq T@ T?T>JT= T;T:0 8pqA 651UDORADO:memSubrsChaos.mcSeptember 14, 1979 3:37 PM%1title[memSubrsChaos];%*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++table of contents by order of occurenceNameDescriptioniChaosCacheInitialize the 4 columns of the 2 rows chaos uses.sChaosChkAddrssubrutine to verify validity of all of vm after chaos test is doneisChaosMeminitialize mem[va] _ vaiSavedHoldValuesave current holdValue (postamble uses it to drive task/hold simulator)getSchaosRow0Addrreturn current value of sChaosRow0 shifted into an addressgetSchaosRow1Addrreturn current value of sChaosRow1 shifted into an addresssShadowBitToVaset addr.shadowBit in sVa if the current two bit nibble in our random numberindicates that this munch should have the shadow bit set.CFlagsFromTemplateset cflags.dirty for the value for the current munch's CFLAGS if the currenttwo bit nibble in our random number indicates this munch should be dirty.iSchaosCodeInitialize the random rm values, patch IM as required by pseudo randomnumber generator.sChaosAddrFromRandVGenerate an address for "row0" or for "row1" based upon current sChaosRandVgetChaosTaskFreqReturn 7 bit random number to put into task portion of hold&tasksim.get1Randsubroutine to get a random numberchaosTskTsti=0 means task 0, i=1 means simulator task, j IN [0..3]. This is the codethat gets patched based on pseudorandom numbers. It's execution is the chaos test.%*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++%September 14, 1979 3:37 PMMake some of the code shorter to help with micro's storage full problems. Add sChaosCkhkAddrs.Add isChaosMem and iSavedHoldValue, too.June 25, 1979 11:09 PMAdd get1Rand because mema won't place due to the way "getRandom[]" works.June 25, 1979 10:32 PMadd getChaosTaskFrq.June 25, 1979 8:33 AMChange placement declarations to accommodate ifu entry points.April 18, 1979 11:44 AMMoved iChaosCache, iChaosCode into here from memChaosS.mc%* This code duplicated in memChaosS.mc!mc[codeRand.store, 40];mc[codeRand.wordX, 17];mc[codeRand.rowX, 20];set[codeRand.colSize, 2];* mc[codeRand.colX, 300];set[codeRand.colShift, 6];set[codeRand.delaySize, 5];* mc[codeRand.delay, 17400]set[codeRand.delayShift, 10];mc[addr.shadowBit, lshift[4,skipCacheShift]];* va bit for shadow address* addrRand is a two bit nibble selected from the current two lsb of a random number.* the test uses addrRand to determine how to initialize each column of the two rows* in the cache.mc[addrRand.dirty, 1];* mask bit for address template.mc[addrRand.shadow, 2];* mask bit for address templategp Y-ByN aq _L ^p' ]Kp \ q2 Zp qB Yp q XUpqG Wpq: Upq: Tp qL S_9 R"pqL PI Op qF Ni M,pqK KpqD Jpq! IspqJ H6Arq FL E D}C@_ B( @?I >J=  ;:> 9T89 6 4^' 1p q 0p q /hp q .*pq+ ,pq +pq+ *rpq 'p q+ %|T $>S # !p q+ pq+  DJ#DORADO:memSubrsChaos.mcSeptember 14, 1979 3:37 PM%2* January 16, 1979 7:26 PM%iChaosCacheThis code initializes all four columns of two rows of the cache. Eight two-bit nibbles in a randomnumber determine for each column-row munch whether that munch is dirty and whether that munch belongsto the "shadow" address. Remember that eight addresses (munch addresses) are not enough to causecache misses for two rows worth of data. Consequently there is an extra "shadow" bit that may set inthe cache address, and that bit provides enough address space to cause misses in the cache.Obtain the two row addresses from sChaosRow0 and sChaosRow1. These are row numbers, not addresses!%iChaosCache: subroutine;pushReturn[];call[getSchaosRow0Addr];call[xVacateCacheRow];* clear cache "row 0"call[getSchaosRow1Addr];call[xVacateCacheRow];* clear cache "row 1"call[get1Rand];sChaosRandV _ t;t _ cm1;* quit row loop when we see -1stack+1 _ t;* push the two row values onto the stackcall[getSchaosRow0Addr];stack+1 _ t;call[getSchaosRow1Addr];stack+1 _ t;isChaosCRowL:* top of loop that inits row zero, then rowcol _ cm1;* addr.row1cnt _ 3s;isChaosColL:col _ (col) + 1;* move to next column, select it as the current victimrscr _ t-t;call[setBR],rscr2_a0;* init BR to zero each time putCFmem clobbers itcall[makeUseMcrv],t _ col;* and perform a reference that will force thecall[setMCR];* desired address into the cache.call[sShadowBitToVa];* returns after va _ shadowBitt _ lsh[col, skipCacheShift];sVa _ (sVa) OR t;* into the munch selection position in the vat _ stack;* get row address.sVa _ t or (sVa);* OR the current row into the vaFETCH _ sVa;call[cFlagsFromTemplate];* get cflags value into RSCR based uponrscr2 _ col;* sChaosRandV, then write Cflags into cache.t _ MD;* don't forget to synchronize w/ memorycall[putCFmem], t _ sVa;* t = va, rscr2 = column, rscr = "cflags"t _ 100c;* wait for cache to settle downcall[longWait];sChaosRandV _ rsh[sChaosRandV, 2];* move on to next column...loopUntil[cnt=0&-1, isChaosColL];stkp-1;t _ stack;t # (cm1);branch[isChaosCacheXit, ALU=0];* quit when we see -1branch[isChaosCRowL];isChaosCacheXit:noop;* for placementcall[sRestoreMcrVictim];pReturnP[];* pop the -1 off the stack before returninggp Y-ByN bAq a^p \qc [f Zfa Y)e W[ U"p qp q( T R"p q P ONi+M,K+IsH6E+D} +(C@B @? = p +q+; + : 8p 6q+65 4^+03 +-1 +!/h+.*,+-+ +*r+)4 &+'%| +,$>+'#+)!+  "+!R  +\ pq+f ++ E3Y DORADO:memSubrsChaos.mcSeptember 14, 1979 3:37 PM%3* June 25, 1979 2:38 PM%sChaosChkAddrsThis code runs at the end of the chaos test. It reads vm to see that mem[va] = va for all the locationin the memory. If this isn't true, some earlier action of the chaos test clobbered the location thatnow has the incorrect value. Due to the time consumption of this check it does not run at the end ofeach chaos "run".%sChaosChkAddrs:* scan all of vm to see that its still correctpushReturn[];call[iSvaCtrl];sChaosChkAddrsL:call[nextSva];skpif[alu#0], rscr2 _ t;* remember sva in rscr2branch[sChaosChkAddrsXit];* everything was okFETCH _ t;rscr _ MD;t _ t # (rscr);* compare sva w/ mem[sva]skpif[alu=0];sChaosAddrsErr:* t = bad bits, rscr = md, rscr2 = expectederror;* value from memorybranch[sChaosChkAddrsL];* try next valuesChaosChkAddrsXit:returnP[];* June 25, 1979 2:40 PM* init memorsy so that mem[va] = vaisChaosMem:pushReturn[];call[iSvaCtrl];iSchaosL:* background memory w/ "self"call[nextSva];skpif[alu#0];branch[sChaosFlush];branch[isChaosL], store _ t, DBuf _ t;* mem[va] _ va;sChaosFlush:* there are dirty munches left in the cacherscr _ 20000c;* cycle thru the cache to make sure we forcesChaosFlushL:STORE _ rscr, DBuf _ rscr;* dirty munches to storagerscr _ (rscr) -1;loopuntil[alu<0, sChaosFlushL];noop;returnP[];* January 13, 1979 12:29 AM* Init sSavedHoldValue which we use for starting the Hold simulator.* Prevent the maximum delay from being longer than 200B - 150BiSavedHoldValue: subroutine;* fire-up task simulator long enough topushReturn[];* save the hold value in sSavedHoldValuemc[taskFreqLocC, 302];* UGH! Yes, this is a DUPLICATE definition.t _ taskFreqLocC;* It copies the one in postamble.mccall[getIMRH];t - (150c);branch[ishOK, ALU>=0];* the current value of holdFreq is too small. set it to our minimum = 150rscr _ 150c;t _ taskFreqLocC;call[putIMRH];noop;ishOK:B_FaultInfo'[];* remove any lurking memroy errorscall[enableConditionalTask];* HACK. FORCE postamble to maket _ holdValueLocC;* a new value for hold simulator.call[getIMRH];* Then we remember its value forsSavedHoldValue _ t;* future use -- and we diable thecall[disableConditionalTask];* to prevent task sim's memory refsgp Y-ByN bAq _^p ]Kqf \d Ze Y XU Up+q.T S_ R"pPq O+Ni+M, K J+Is H6p+q+F+E+ C@pBq ? >J# = p ;q : 9Tp+q8 6 54^&+ 3 p +q+1 +, 0p /hq+.*,+*r ' &D %|> #pq +'! +( p q++H+#   I \  pfq+")+pq +! + p+! 3+# E3]@DORADO:memSubrsChaos.mcSeptember 14, 1979 3:37 PM%4* from screwing up the cache.returnP[];gp Y-ByN bAqa \ _*h!DORADO:memSubrsChaos.mcSeptember 14, 1979 3:37 PM%5* January 13, 1979 2:32 AM%getSchaosRow0Addr return current value of sChaosRow0 shifted into an addressgetSchaosRow1Addr return current value of sChaosRow1 shifted into an addresssShadowBitToVaset addr.shadowBit in sVa if the current two bit nibble in our random numberindicates that this munch should have the shadow bit set.CFlagsFromTemplateset cflags.dirty for the value for the current munch's CFLAGS if the currenttwo bit nibble in our random number indicates this munch should be dirty.%subroutine;getSchaosRow0Addr:RBASE _ rbase[sChaosRow0];t _ sChaosRow0, RBASE _ rbase[defaultRegion];return, t_ lsh[t, cacheShift];getSchaosRow1Addr:RBASE _ rbase[sChaosRow1];t _ sChaosRow1, RBASE _ rbase[defaultRegion];return, t_ lsh[t, cacheShift];sShadowBitToVa:(sChaosRandV) AND (addrRand.shadow);* see if shadow bit is set in templateskpif[alu=0], sva _ t-t;sva _ (sva) OR (addr.shadowBit);* add shadow bit to vareturn;CFlagsFromTemplate:* set rscr _ cflags based upon template dirty bitnoop;(sChaosRandV) AND (addrRand.dirty);skpif[alu=0], rscr _ t-t;rscr _ cflags.dirty;return;gp Y-ByN bAq a ^p6q; \p6q; Zp 6qL Y9 Wp6qL VDI US QNpPqN-M KpIqH-Gb DpCq$+&BlA.+? =vp+q1<8:#987Bj 5E;2)DORADO:memSubrsChaos.mcSeptember 14, 1979 3:37 PM%6* January 16, 1979 4:47 PM%isChaosCodeInitialize the chaos code. The code immediately below initializes the eight registers rm00-rm03 andrm10-rm13. The emulator level code uses the first group of four and the simulator task uses the lastgroup of four.Call the subroutine setChaosCode twice, once for the emulator code and once for the simulator taskcode. That subroutine initializes the FF constants and long jumps used by the chaos code. Noticethis requires writing valid instructions into IM.%iSchaosCode: subroutine;pushReturn[];* TASK 0 RM and Code Initcall[get1Rand];sChaosRandV _ t;sSubrScr _ t;* save currend random valuecall[sChaosAddrFromRandV];* init rm for first memop of task 0rm00 _ t;rm01 _ t;call[get1Rand];sChaosRandV _ t;call[sChaosAddrFromRandV];* init rm for second memop of task 0rm02 _ t;rm03 _ t;call[getsSubrScr];rscr2 _ t;call[setChaosCode], t _ r0;* set-up pointer to proper code, init delay* Sim Task RM and Code Initcall[get1Rand];sChaosRandV _ t;sSubrScr _ t;* save currend random valuecall[sChaosAddrFromRandV];* init rm for first memop of task 17rm10 _ t;rm11 _ t;rscr2 _ sChaosRandV;call[get1Rand];sChaosRandV _ t;call[sChaosAddrFromRandV];* init rm for second memop of task 17RM12 _ t;rm13 _ t;call[getsSubrScr];rscr2 _ t;call[setChaosCode], t _ 4c;* set-up pointer to proper code, init delayreturnP[];sChaosAddrFromRandV:pushReturn[];(sChaosRandV) and (codeRand.rowX);branch[scaRow0, ALU=0];* this addr should use "row0"scaRow1:* this addr should use "row1"noop;call[getSchaosRow1Addr];scaMakeAddr:stack+1 _ t;* remember row address in stackt _ (sChaosRandV) and (codeRand.wordX);stack _ t or (stack);* OR row, word bitst _ ldf[sChaosRandV, codeRand.colSize, codeRand.colShift];t _ lsh[t, skipCacheShift];t _ t or (stack&-1);* or column into the addr, pop stackreturnP[];scaRow0: top level;* current address should come from "row0"call[getSchaosRow0Addr];branch[scaMakeAddr];gp Y-ByN bAq a_p ^qc ]Ke \ Yp qB Xb W1 VD Up q S QNPNM +LX+#KIGbF$D+$CBlA.? >++ :987B +6+$432L/.-V+%,*)(` '#++% #jp"-q  "+ tp+q7 p ~q +A'+:K+$ pq +)U  D\T DORADO:memSubrsChaos.mcSeptember 14, 1979 3:37 PM%7* June 25, 1979 10:42 PMgetChaosTaskFreq:pushReturn[];gctfL:noop;* for placementcall[get1Rand];t _ t and (177C);t _ t - (77C);* don't want to wait more than 77 cyclesloopUntil[ALU>=0, gctfL];t _ lsh[t, sim.taskShift];returnP[];* June 25, 1979 11:08 PMget1Rand:pushReturn[];noop;* maximize placement advantagegetRandom[];returnP[];gp Y-ByN bAq ap_q ^p]Kq+\ZY +(XUWU S_ R"pqP O+Ni M,  K:@`DORADO:memSubrsChaos.mcSeptember 14, 1979 3:37 PM%8* April 24, 1978 1:50 AM%Chaos Test CodeOne of these code segments executes for the task 0 test and one of them executes for the task 17 test.iSchaosCode inits the RM values and writes the appropriate delay constant into IM (as an FF constant).There are four basic tests:Test 0:fetch, delay, fetch:00Test 1:fetch, delay, store:01Test 2:store, delay, fetch:10Test 3:store, delay, store:11The Simulator task's test code is similar except for RM selection and conventions associated withnotifying task0 that the simulator code is done.%set[chaosTestBase, 7000]; mc[chaosTestBaseC, chaosTestBase];*++duplicated in memChaosS.mc+++++set[chaosDelayBase, 7400]; mc[chaosDelayBaseC, chaosDelayBase];*++duplicated in memChaosS.mc+++++knowRbase[rm00];top level;* FETCH, Delay, FETCHchaosTsk0Tst0:FETCH _ rm00,at[chaosTestBase, 0];noop;t _ 0c,at[chaosDelayBase,0];* this gets patched each timecall[longWait];rm01 _ MD;* rm01 _ mem[rm00]FETCH _ rm02;rm03 _ MD;* rm03 _ mem[rm02]branch[chaosAfterChk0];* proceed to check task 17 results* FETCH, Delay, STOREchaosTsk0Tst1:FETCH _ rm00,at[chaosTestBase, 1];t _ 0c,at[chaosDelayBase,1];* gets patched each timecall[longWait];rm01 _ MD;* rm01 _ mem[rm00]STORE _ rm02, DBuf _ rm02;* mem[rm02] _ rm02branch[chaosAfterChk0];* proceed to check task 17 results* STORE, Delay, STOREchaosTsk0Tst2:STORE _ rm00, DBuf _ rm00,at[chaosTestBase, 3];* mem[rm00] _ rm00t _ 0c,at[chaosDelayBase,3];* gets patched each timecall[longWait];FETCH _ rm02;rm03 _ MD;branch[chaosAfterChk0];* proceed to check task 17 results* Store, Delay, FETChchaosTsk0Tst3:STORE _ rm00, DBuf _ rm00,at[chaosTestBase, 2];* mem[rm00] _ rm00t _ 0c,at[chaosDelayBase,2];* gets patched each timecall[longWait];STORE _ rm02, DBuf _ rm02;* mem[rm02] _ rm02branch[chaosAfterChk0];* proceed to check task 17 resultsgp Y-ByN bAq a) _p ^qf ]Kf \Z+Y+XU+W+ Ua T0 S_ Pp q p q5" Op q pq84"M,K J Isp H6q +FE+:D}C@ +B @ +?+"=  ;p :q +9T+:86 +5+3 +"0 /hp ,q+:++-*r)4 ' %|+"# !p  q+:H+: +R+"@ /E3MDORADO:memSubrsChaos.mcSeptember 14, 1979 3:37 PM%9%CHAOS Task Code%set[xtask, 1];chaosTsk1Tst0:hold&tasksim _ t,at[chaosTestBase, 4];* awakened by the simulatornoop;* 1st instr after hold&tasksim_ doesnt countblock;FETCH _ rm10;t _ 0c,at[chaosDelayBase,4];* this gets patched each timecall[longWait];rm11 _ MD;* rm11 _ mem[rm10]FETCH _ rm12;rm13 _ MD;* rm13 _ mem[rm12]branch[chaosSimXit];* proceed to check task 17 resultschaosTsk1Tst1:hold&tasksim _ t,at[chaosTestBase, 5];* awakened by the simulatornoop;* 1st instr after hold&tasksim_ doesnt countblock;FETCH _ rm10;t _ 0c,at[chaosDelayBase,5];* gets patched each timecall[longWait];rm11 _ MD;* rm11 _ mem[rm10]STORE _ rm12, DBuf _ rm12;* mem[rm12] _ rm12branch[chaosSimXit];* proceed to check task 17 resultschaosTsk1Tst2:hold&tasksim _ t,at[chaosTestBase,6];* awakened by the simulatornoop;* 1st instr after hold_ doesnt countblock;STORE _ rm10, DBuf _ rm10;* mem[rm10] _ rm10t _ 0c,at[chaosDelayBase,6];* gets patched each timecall[longWait];FETCH _ rm12;rm13 _ MD;branch[chaosSimXit];* proceed to check task 17 resultschaosTsk1Tst3:* STORE, Delay, FETCHhold&tasksim _ t,at[chaosTestBase,7];* awakened by the simulatornoop;* 1st instr after hold_ doesnt countblock;STORE _ rm10, DBuf _ rm10;* mem[rm10] _ rm10t _ 0c,at[chaosDelayBase,7];* gets patched each timecall[longWait];STORE _ rm12, DBuf _ rm12;* mem[rm12] _ rm12branch[chaosSimXit];* proceed to check task 17 resultsgp Y-ByN bAq) ap _q^ ]Kp \q+:Z+,YW U+:TS_ +R" P +Ni+" Isp H6q+:F+,EC@ B+:@? +>J+;+" 8p 6q+:5+$4^1+0+:/h.* , *r+" &p +q$>+:#+$!H+ +:++" BOMODEL 1:memSubrsD.mcMay 21, 1981 11:46 AM %1title[memSubrsD];top level;%*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++RoutineDescriptioniMunchCtrl:Initialize cache munch counteriCDvaCtrl:Initialize cache va controliCDpatCtrl:Initialize cache data pattern controlnextVa:Return next cache va in "va"nextMunch:Return next munch addr in "va"nextCDpat:Return next cache data patterngetCDpat:Return current cache data patterniDboard:Initialize the D-boardcdRead:Read a word from va = t, result in rscr2cdWrite:Write a word w/ t = va, rscr = datacolForVa:Return t = column for a va (not general purpose)cacheAforVa:Return "midas" cache addr for a va in tpresetCache:Set all cache flags cache addrspcSetCflags:Set CFlags; private subr for presetCachepcSetAmemory:Set cacheA, private subr for presetCachezeroCache0:For va IN cacheAddrs DO cache[va]_0setCache0:FOR va IN cacheAddrs DO cach[va]_tpcGetHi8B:Return current pcHi8pcGetCflags:Return current pcFlags%*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++%May 21, 1981 11:46 AMAdd setCache0 -- a modification of zeroCache0August 13, 1979 6:06 PMCause iCDpatCtrl to initialize memory storage patterns, too.August 13, 1979 5:23 PMOld getCDpat, nextCDpat assumed RBASE=rmForMemDLoops, new implementation uses RBASE =defaultregion; fix the discrepancy.August 13, 1979 3:28 PMAdd new patterns for cacheData testing.May 4, 1979 5:14 PMRemove branch[afterDtest].%SUBROUTINE;knowRbase[rmForMemDloops];iMunchCtrl:RBASE _ rbase[cMunchVa];cMunchVa _ t - (20c);t _ (t)+(cdMaxVa);return, cMunchEnd _ t, rbase _ rbase[defaultRegion];iCDvaCtrl:* init next va control. T = begin addr.* va IN [beginAddr..beginAddr+4000B)RBASE _ rbase[cdVa];cdVa _ t - 1;* initial value -1t _ (t)+(cdMaxVa);cdVaEnd _ t;* last value +1return, cdVaEnd _ t, rbase _ rbase[defaultRegion];iCDpatCtrl:t_cm1;CDpatx _ t;SpatX _ t;curSPattern _ t;return, curCDpattern _ t;Zgp$X /qNp bAq a _B^+ ]Kp +q\p +qZp +q%Yp+qXUp +qWp +qUp+q!Tp+qS_p+q(R"p+q#Pp+q0Op +q'Nip +qM,p +q(Kp +q(Jp +q#Isp +q"H6p +qFp +q EB D} C@B- @?< >J= U ;# :9T' 86 5 3 0 .*p ,q+*r)44 &p +q' %|$#! + H + 2 p Rq  \| @)T0MODEL 1:memSubrsD.mcMay 21, 1981 11:46 AM %2* December 22, 1977 10:20 AMnextVa:* WRITE NEXTVA DIRECTLY INTO "VA"RBASE _ rbase[cdVa];t _ cdVa _ (cdVa)+1, ;va _ t;* write it into caller's rbaset _ cdVaEnd;RBASE _ rbase[defaultRegion];return, (va)-(t);nextMunch:* WRITE next munch DIRECTLY INTO VArbase _ rbase[cMunchVa];t _ cMunchVa _ (cMunchVa) + (20C);va _ t;t _ cMunchEnd;RBASE _ rbase[defaultRegion];return, (va)-(t);* ugh. return w/ fast branch conditionZgp$X /qNp bAq ap+q!_^]K+\ ZY Wp +q#UT"S_R" PO+& NF9qZMODEL 1:memSubrsD.mcMay 21, 1981 11:46 AM %3* August 13, 1979 5:26 PMnextCDpat:* compute next pattern index; return in t%This routine increments CDpatx, the pattern control variable that determines which pattern the routinegetCDPat will generate. For simple patterns like cycled 1 and cycled 0, nextCDpat also generates thevalue for the current pattern. The routine getCDPat computes the values for the more complicatedpatterns.pattern1 IN [0..pat1EndC)= cycled 1pattern2 IN [CDpat1EndC..CDpat2EndC)= cycled 0pattern3 IN [CDpat2EndC..CDpat3EndC)= cycled vapattern4 IN [CDpat3EndC..CDpat4EndC)= pseudo random numbers%RBASE_ rbase[CDpatx];* compute end of patterns as branch conditionDrlink _ link;* save return linktop level;t_CDpatx_(CDpatx)+1;RBASE _ rbase[defaultRegion];* keep it simple.t-(CDpat2EndC);* see if IN [0..pat1EndC)branch[nxtCDPat3, alu>=0];* goto[nextPat3, ~IN [0..pat2EndC)]* IN Pattern1 or Pattern2. We'll use nextSpat to do the work.call[nextSpat];branch[nxtCDPatXit];nxtCDPat3:* This pattern also gets generated% by the nextSpat code. However, we're not interested in the full and glorious alternatives ofpattern 3 (it is a left cycled va which gets left cycled 28 times).%t - (CDpat3EndC);* if we're done with the localbranch[nxtCDPat4, ALU>=0];* version of pattern 3, try next onenoop;call[nextSpat];branch[nxtCDPatXit];nxtCDPat4:* this pattern consists of pseudo randoms% that are generated by nextSpat, getSpat. So far, this subroutine has "secretely" called nextSpatand everything worked. Unfortunately there more pattern3 values for the nextSpat than nextCDpatreally needs. Consequently, here we notice if we've just begun nextCDpat's pattern4. In that case,we set nextSpat's SpatX to the proper value to begin pattern 4.%t - (CDpat4EndC);* see if we've just entered pattern4skpif[ALU#0], t _ Spat3EndC;SpatX _ t;* diddle nextSpat's index. ugly.noop;* for placementcall[nextSpat];branch[nxtCDPatXit];nxtCDPatXit:subroutine;RBASE _ rbase[Drlink];link _ Drlink;* restore return link, fix up rbase,t _ CDpatX, RBASE _ rbase[defaultRegion];return,t-(CDlastPatC);* return w/ proper branch conditionZgp$X /qNp bAq ap +q) _ ^f ]Kd \a Z Y+ XU$+ W$+ U$+ TR"+-P +O NiM,+K+J+# H6>FE C@p +q" B_ @C ?>J+= +$;:9T 6p +q) 5c 4^` 3 d 1? 0/h+$.*, +!++*r)4 &p %|q $># +$!) +#R E3J#MODEL 1:memSubrsD.mcMay 21, 1981 11:46 AM %4* August 13, 1979 5:25 PMCACHE DATA pattern generatorgetCDPat:* compute next pattern; return it in T%This code actually does much of it's work by calling getSpat, the storage pattern generator. Itwas easier (and less microcode) to do it this way. However, nextSpat's pattern3 left cycles a 28 bitvirtual address and uses that cycled value as a pattern. Naturally the cache test is not interestedin doing things that way, consequently we depend upon nextCDpat to change nextSpat's value in SpatX.%RBASE_ rbase[CDpatx];Drlink _ link;top level;t _ CDpatX, RBASE _ rbase[defaultRegion];t-(CDpat4EndC);* see which pattern we are usingbranch[getCDP5,alu>=0];noop;* for placementcall[getSpat];branch[getCDPxit];getCDP5:* add code for pattern 5 herebranch[getCDPXit];getCDPXit:RBASE _ rbase[Drlink];link _ Drlink;subroutine;return, RBASE_ rbase[defaultRegion];Zgp$X /qNp bAq+ _p+q& ^]K` \f Zd Y7pq% XUWU T S_)R"+PO+Ni M, Isp+qH6 Ep D}qC@ B @$ J#+= +";.: 8p +q(6 5 4^ +3 1 +/h .*p,q++ +*r)4&%|#+ p Hq+& + p +q#+( +%\ +*+++ f)  p 3+| >%]/MODEL 1:memSubrsD.mcMay 21, 1981 11:46 AM %7t _ (va) - t;* compute value for BRrscr2 _ t;call[setBR], rscr _ (rscr)-(rscr);* BRLO = va-cflags, BRHI = 0call[pcGetCFlags];* now set the cache flagst _ t # (cflags.mask);* invert only the cflags bitsdummyRef _ t;CFLAGS _ t;subroutine;returnUsing[Drlink];pcSetAmemory:* private subroutine to presetCachet _ link;* inits cache A memory to "contain" specificDrlink _ t;* va. Sets BRHI to value of pcHi8! This subrtop level;* MUST NOT CALL another subr that stores* link in Drlink!call[colForVa],t_va;* set MCR for current column.col _ t;t _ mcr.fdMiss;t _ t OR (mcr.noRef);call[mcrForCol];call[pcGetHi8];rscr _ t;call[setBR], rscr2 _ (rscr2) - (rscr2);* init BRHI = pcGetHi8t _ r0;* perform the referenceSTORE _ va, DBuf _ t;subroutine;returnUsing[Drlink];%Zero the cache. presume it has been init'd for va IN [0..3777B]Clobber T (that all!)%* May 21, 1981 11:44 AM This routine was modified to provide for setting the cache to an arbitraryvalue.zeroCache0:pushReturn[];top level;branch[setCache], t_ a0;setCache0:stkp+1;stack_ link;setCache:rscr_ t;* value to use is in rscrcall[iCDvaCtrl], t_r0;zcVaL:* FOR va IN [0..3777B] DOcall[nextVa];skpif[alu#0], t_rscr;* exit if required. setup t=0branch[zcXit];branch[zcVaL],DBuf _t,store_va;* cache[va] _ valuezcXit:returnP[];Zgp$X /qNpbAq +a _"+]K+\+Z Y W U S_p +q#R"+,P +,O +(+NiK+JIsH6FD}C@B'+?+>J; : 86? 5 4^ 3 e 1 /hp .*q , + )4p 'q& $>p#q+  Hp+q + + p\q ( DTMODEL 1:memSubrsD.mcMay 21, 1981 11:46 AM %8* October 14, 1978 3:13 PMsubroutine;pcGetHi8:RBASE _ rbase[pcHi8];return, t _ pcHi8, RBASE _ rbase[defaultRegion];pcGetCflags:RBASE _ rbase[pcFlags];return, t _ pcFlags, RBASE _ rbase[defaultRegion];knowRbase[defaultRegion];top level;memSubrsDDone:;Zgp$X /qNp bAqa _p^q]K0 Zp YqXU2 UT R"p +q* P%aJFDORADO:memSubrsS.mcJune 17, 1981 9:31 AM %1title[memSubrsS];top level;subroutine;%*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++RoutineDescriptioniSmunchCtrlInitialize 24 bit va loop control for munch addrsiSvaCtrlInitialize 24 bit va control for simple addrs.iSvaDownCtrlInitialize 24 bit va control going downiSmunchDownCtrlInitialize 24 bit va control going down for munchesrestoreBrHirestores current BrHi to value indicated by SvaHiXiSpatCtrlInit storage patternsisChaosXInit chaos loop controlnextChaosXReturn next chaos indexgetSsubrScrReturn current value of sSubrScrgetSsavedHoldValueReturn current value of SsavedHoldValueiSboardInitialize the c,x,d,s boards for storage diagnosticsgetSmcrVictimReturn current sMCRvictimsRestoreMcrVictimSet sMcrVictim from memState, then set defaultMcrsUseMcrVictimSEts Mcr to use indicated victim in cachesUseDefaultMcrSet Mcr w/ sUseMcrsaOrMcrNoWakeORs more bits into a Mcr value + mcr.noWakesChkNoErrsrtn memState.noErrs bitsNoErrsOnTurn on error checking in storage diagnosticsNoErrsOffTurn off error checking in storage diagnoticnextSvaReturn next sva valuenextSvaDownReturn next (decreasig) sva valuenextSMunchReturn next munch addressincSvaIncrement current sva by indicated amountnextSpatReturn next pattern indexgetSPatReturn current pattern valuezeroMemoryZero all available storagesetMemorySet all available storage to given valuesaveMemAddrSave (sVaHi,,sVaX) in sVaHiXold,, sVaXoldfetchMemAddrReturn sVaHiOld,,sVaXoldgetSvaXoldReturn sVaXOld%*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++%June 17, 1981 9:31 AMMove sPingPong, dirtyWriteLoop and doScheckOut into memMisc's memDesperateA.mcJune 16, 1981 10:59 AMAdd call to xGetMapICs in iSboardJune 9, 1981 11:12 AMInit memState from within iSboard.May 20, 1981 5:18 PMFix problems in sPingPongMay 18, 1981 2:12 PMChange nextSPat to cycle random number seed.May 14, 1981 4:51 PMMiscellaneous fixes to make microcode smaller.July 1, 1979 3:39 PMCause doScheckOut to set mcr.noWake before it tries to load Brs.July 1, 1979 3:04 PMFix doScheckOut to vacate the cache where required (code was buggy) & add scope loops.June 28, 1979 11:20 AMMove sGetConfig into memSubrsX and rename it.June 27, 1979 6:59 PMForce sBrHi and sBrLo to be zero as default in doSCheckout, remove mcr.disCF from default mcrvalue.June 26, 1979 4:43 PMMake another change to doScheckOut.June 25, 1979 10:14 AMChange doScheckOut as per requests (fixes several bugs, thnx to k pier).June 7, 1979 2:07 PMFix bug in sex of skip instruction in sGetICtype.May 7, 1979 2:16 PMUpdate sGetICtype to Rev C standards for Config.January 17, 1979 9:12 AMremove saSetMcr entirely: setting mcr now independent of setting sMCRvictimJanuary 16, 1979 2:32 PMchange MCRvictim handling: sMCRvictim may be set by any routine and that value becomes the oneelp$X /Ng bAq a _ ^B]K+ \p $ q1Zp$ q.Yp $ q'XUp$ q3Wp $ q2Up$ qTp$ qS_p $ qR"p $ qPp$ q'Op$ q5Nip $ qM,p$ q1Kp $ q)Jp $ qIsp $ q+H6p $ qFp$ q,Ep $ q,D}p$ qC@p $ q!Bp $ q@p$ q)?p$ q>Jp$ q= p $ q;p$ q(:p $ q)9Tp $ q8p $ q 6B 4^ 3 1N 0/h! .*," +*r )4', &%|. $>#@ ! V H - ] R # \H 1 f0 ) K  pq p qrq 0 C]KDORADO:memSubrsS.mcJune 17, 1981 9:31 AM %2sUseDefaultMcr uses (ie., really causes it to occur in MCR). However, the test-wide value (ie., theone set by program default or by the operator) is kept in a separate place, and that value may berestored by calling sRestoreMcrVictim.January 15, 1979 2:58 PMreenable dirtyWriteLoop, sPingPongJanuary 13, 1979 12:43 PMprocSRN_r0 inside iSboard, remove dirtyWriteLoop, sPingPong: get memA to placeJanuary 12, 1979 3:17 PMnew sGetConfig that notices that storage begins w/ Module 1,2, or 3, pattern3 diddles%knowRbase[defaultRegion];elp$X /Ng bA qV aPrq _pq ]\p qp ZqYpqp qpq XxW;p qG U REB PC'RDORADO:memSubrsS.mcJune 17, 1981 9:31 AM %3* April 23, 1978 9:56 PMiSmunchCtrl: subroutine;* initialize 24 bit va loop control* CLOBBER T, RSCR, RSCR2saveReturn[Srlink];* NOTE: this code (down ctrl, too) won't* work properly when va[0:1]#0. THAT* requires rewriting the Map as well AND thatsVaHiX _ t_ a1;* may present other problemst _ (r0)-(20c);* begin w/ 0-munchSizesvaX _ t;rscr _ (rscr) - (rscr);call[setBR], rscr2 _ (rscr2) - (rscr2);returnUsing[Srlink];iSvaCtrl: subroutine;* initialize 24 bit va loop control* CLOBBER T, RSCR, RSCR2saveReturn[Srlink];* NOTE: this code (down ctrl, too) won't* work properly when va[0:1]#0. THAT* requires rewriting the Map as well AND thatsVaHiX _ t_ a1;* may present other problemssvaX _ t;rscr _ (rscr) - (rscr);call[setBR], rscr2 _ (rscr2) - (rscr2);returnUsing[Srlink];iSvaDownCtrl: subroutine;saveReturn[Srlink];RBASE _ rbase[sMaxBrHi];t_sMaxBrHi;svaX _ t-t;sVaHiX _ t, RBASE _ rbase[defaultRegion];rscr _ t;call[setBR], rscr2 _ t-t;returnUsing[Srlink];iSmunchDownCtrl: subroutine;saveReturn[Srlink];t _ (r0)-(20c);svaX _ t;RBASE _ rbase[sMaxBrHi];t_sMaxBrHi;sVaHiX _ t, RBASE _ rbase[defaultRegion];rscr _ t;call[setBR], rscr2 _ t-t;returnUsing[Srlink];restoreBrHi: subroutine;* restore current BRHI after its been clobberedsaveReturn[Srlink];RBASE _ rbase[sVaHiX];t _ sVaHiX, RBASE _ rbase[defaultRegion];rscr _ t;call[setBR], rscr2 _ t-t;returnUsing[Srlink];iSpatCtrl: subroutine;Spatx _ t_ a1;return, curSPattern _ t;isChaosX: subroutine;return, sChaosX _ t_ a1;nextChaosX: subroutine;RBASE _ rbase[sChaosX];t _ sChaosX _(sChaosX) + 1, RBASE _ rbase[defaultRegion];return, t - (sChaosEndC);* alu=0 IF last patterngetSsubrScr: subroutine;RBASE _ rbase[sSubrScr];return, t _ sSubrScr, RBASE _ rbase[defaultRegion];elp$X /Ng bAq _p q +# ^\+(+Z$ Y-XU+W+UTS_'R" Nipq +# M,J+(+Is$ H6-F+ED}C@'B ?p q >J= ; : 9T)865 3 pq 10/h.*, +)*r)4' %|p q +/$>#!) H  p q R  pq \ p q f9)+ p q  p 33 ?}]DORADO:memSubrsS.mcJune 17, 1981 9:31 AM %4getSsavedHoldValue: subroutine;RBASE _ rbase[SsavedHoldValue];return, t _ SsavedHoldValue, RBASE _ rbase[defaultRegion];elp$X /Ng aq _^: ](* %DORADO:memSubrsS.mcJune 17, 1981 9:31 AM %5* June 16, 1981 10:58 AM%Initialize the Storage BoardsInit the storage boards in preparation for storage diagnostics. Turn on or off error correction asrequired by memState.useTestSyn. Simulate a cache w/ only one column, as required by sMCRvictim (RMlocation). This subroutine also presets the map, clears the cache flags and determines the currentmemory configuration.%iSboard: subroutine;saveReturn[Srlink];t _ FaultInfo'[];* remove any waiting wakeupscall[iMemState];call[xGetConfig];call[xGetMapICs];call[clearCacheFlags];* make the cache vacantcall[presetMap];* initialize the mapcall[clearCacheFlags];* make the cache vacantt _ memState.useTestSyn;call[checkMemState];skpif[alu=0], t _ t-t;* don't use error correctiont _ (200c);* use error correctioncall[setTestSyn];* causes cache to be non-vacantcall[clearCacheFlags];* make the cache vacantrscr _ t-t;* set our base register to zerocall[setBR], rscr2 _ t-t;call[saNoWakeOn];* default = set mcr.noWakecall[sRestoreMcrVictim];* get MCRvictim (>3 => set MCR w/ 0)procSRN _ r0;returnUsing[Srlink];elp$X /Ng bAq a$X_p ^qb ]Kc \b Z Y Wpq US_+PNiM,K+J+Is+FED}+C@ +B+@+>J += :+9T+$8 6L 5xC/2DORADO:memSubrsS.mcJune 17, 1981 9:31 AM %6* January 17, 1979 9:31 AM%getSmcrVictimreturns t = sMCRvictimsRestoreMcrVictimresets sMCRvictim from memState, sets MCRsUseMcrVictimsets sMCRvictim, memStatesUseDefaultMcrsets MCR w/ current sMCRvictim%getSmcrVictim: subroutine;RBASE _ rbase[sMCRvictim];return, t _ sMCRvictim, RBASE _ rbase[defaultRegion];sRestoreMcrVictim: subroutine;* rtn restored victim value in TpushReturn[];* read value of sMCRvictim as stored incall[getmemState];* memState, and set sMCRvictim withrscr _ rsh[t, memState.mcrVictimShift];* that value.t and (memState.usingOneColumn);skpif[ALU=0];* see if we use all the cacheskip, t _ (rscr) and (3c);* Using one column: use value from memstate.t _ 7c;* impossible cache column => use all the cachesMCRvictim _ t;call[sUseDefaultMcr];returnP[];%sUseMcrVictimThis routine "permanently" sets the mcrVictim used the the diagnostics. This means that every timeiSboard gets called or every timethe operator invokes sRestoreMcrVictim, sMCRvictim will be set toselect the indicated column of the cache (or to allow full use of the cache). Any given piece of codemay change the value of sMCRvictim, an r-register, to temporarily cause the cache to behave as if itwere only one column wide. Once that code has done this, that value of sMCRvictim will continue to beused by sUseDefaultMcr until sRestoreMcrVictim gets called.%sUseMcrVictim: subroutine;pushReturnAndT[];* Enter w/ t = new victim.(stack) and (not[3]C);* see if impossible cache columnskpif[ALU=0];branch[sUseMcrVicOff];* set sMCRvictim with a "non-null" value. This means we set it to a value IN [0..3]t _ (stack) and (3c);t _ lsh[t, memState.mcrVictimShift];rscr _ t or (memState.usingOneColumn);sUseMcrVicSet:* set both sMCRvictim and memStatet _ (stack);sMCRvictim _ t;* set sMCRvictim w/ our inputt _ rscr;* now save our new addition for memStatestack+1 _ t;call[getMemState];* rtns t=current memStaterscr _ (add[memState.usingOneColumn!, memState.mcrVictim!]C);rscr _ not(rscr);* Remove "current" mcr stuff fromt _ t and (rscr);* memState so we can add our newt _ t or (stack&-1);* mcr stuff. Pop stack, toocall[putMemState];pReturnP[];sUseMcrVicOff:rscr _ t-t;branch[sUseMcrVicSet];sUseDefaultMcr: subroutine;pushReturn[];*BEWARE: uses Srlink; clobbers rscr, rscr2, tcall[getSmcrVictim];* get MCRvictim (>3 => set MCR w/ 0)t and (not[3]C);* see if we're using a victimdblBranch[sUseDefaultVic, sUseDefaultAll, ALU=0];sUseDefaultAll:branch[sUseDefaultSet], t _ t-t;sUseDefaultVic:noop;* for placement.call[makeUseMcrV];* enter w/ t = column, rtns t = mcr valuesUseDefaultSet:call[saOrMcrNoWake];* OR proper noWake into current mcr val.call[setMCR];elp$X /Ng bAq a _p qp ^q) ]Kp q \p +q Z Yp q XUW5 Upq +T +'S_+#R"'+ PO +Ni+,M,+.KJIs H6Fp Eqc D}pq/pqp q C@f Bp qB @Hp q ?p qpq >J ;p q :+9T+8 6 4^T3 1$0& /hp +q".* ,+++(*r )4+'=&+!%|+$>+#! p Hq   pq R +-+$+1 pq fp)q+ +) p pq+( 3 | E3]bDORADO:memSubrsS.mcJune 17, 1981 9:31 AM %7returnP[];elp$X /Ngaq 6 _"hDORADO:memSubrsS.mcJune 17, 1981 9:31 AM %8* January 16, 1979 3:08 PM* enter w/ t = mcr bits* return w/ t = mcr bits OR (correct value for mcr.noWake -- same as memState.noWake)saOrMcrNoWake: subroutine;saveReturnAndT[saOrMcrNoWakeRtn, sSubrScr];call[checkMemState], t _ (memState.noWake);skpif[alu=0], rscr _ t-t;rscr _ mcr.noWake;call[getsSubrScr];t _ t or (rscr);returnUsing[saOrMcrNoWakeRtn];* January 5, 1979 2:34 AM* RTN ALU#0 IF error checking is turned off* applies to storage data testsChkNoErrs: subroutine;saveReturn[sRlink];call[checkMemState], t _ memState.noErrs;returnAndBranch[sRlink, t];sNoErrsOn: subroutine;saveReturn[sRlink];call[getMemState];t _ t OR (memState.noErrs);call[putMemState];returnUsing[sRlink];sNoErrsOff: subroutine;saveReturn[sRlink];call[getMemState];rscr _ not(memState.noErrs);call[putMemState], t _ t and (rscr);returnUsing[sRlink];elp$X /Ng bAq _ ^U ]Kp q \+Z+YXUWUT R" P+ O Nip q M,K)J Isp q H6FED}C@ Bp q @?>J= $;l 919.DORADO:memSubrsS.mcJune 17, 1981 9:31 AM %9* January 27, 1978 11:30 AM%nextSva: PROCEDURE RETURNS [va: Low16BitsOfVa, validity: BOOLEAN]BEGINRETURN[incSva[inc: 1]];END;nextSvaDown: PROCEDURE RETURNS[va: Low16BitsOfVa, validity: BOOLEAN]=BEGINRETURN[ incSva[inc: -1] ];END;nextSmunch: PROCEDURE RETURNS [va: Low16BitsOfVa, validity: BOOLEAN] =BEGINRETURN[incSva[inc: 16]];END;incSva: PROCEDURE[increment: CARDINAL] RETURNS[va: Low16BitsOfVa, validity: BOOLEAN] =BEGINoldLow _ low;low _ low + increment;signChange _ (oldLow xor low) AND (b0);IF signChange THENIF increment >0 AND (( low BITAND b0) = 0) THEN-- overflow if msb is zerohiVa _ hiVa + 1;IF hiVa = lastVa THEN RETURN[nil, FALSE];SetBr[hiVa, 0];END;IF increment <0 AND ((low BITAND b0) # 0) THEN-- underflow if msb is 1hiVa _ hiVa -1;IF hiVa <0 THEN RETURN[nil, FALSE];SetBR[hiVa,0];END;RETURN[low, TRUE];END;%elp$X /Ng bAq a _pq9^]K\ Zp q9YXUW Up q;TS_R" PpqOONi M,K'JIs/H6FE)D}C@B.@?>J#= ;:9T 8f 691UDORADO:memSubrsS.mcJune 17, 1981 9:31 AM %10* October 16, 1978 10:06 AMknowRbase[defaultRegion];nextSva: subroutine;* return t = low 16 bits of next va.* automatically set BRHI. Clobber T, RSCR, RSCR2saveReturn[Srlink];t _ 1c;call[incSva];* REMEMBERED the ALU=0 condition in rscrreturnAndBranch[Srlink, rscr];* use Srlink for return, use val of rscr for fastbrnextSmunch: subroutine;* return t = low 16 bits of next va.* automatically set BRHI. Clobber T, RSCR, RSCR2saveReturn[Srlink];t _ 20c;call[incSva];* REMEMBERED the ALU=0 condition in rscrreturnAndBranch[Srlink, rscr];* use Srlink for return, use val of rscr for fastbrnextSvaDown: subroutine;* return t = low 16 bits of next va.* automatically set BRHI. Clobber T, RSCR, RSCR2saveReturn[Srlink];t _ cm1;call[incSva];* REMEMBEREDED the ALU=0 condition in rscrreturnAndBranch[Srlink, rscr];* use Srlink for return, use val of rscr for fastbrincSva: subroutine;* Enter w/ T = increment to sVaX* return t = low 16 bits of next Sva, alu=0 result in rscr* is fast branch condition, clobber T, RSCR, RSCR2. call setBR if required.saveReturnAndT[incSvaRtn, SsubrScr];RBASE _ rbase[sSubrScr];t _ sSubrScr;SvaX _ (SvaX)+t;* increment SvaXt _ (SvaX)-t;* compute signChanget _ t # (SvaX);t _ t and (B0);branch[incNormal,alu=0], sSubrScr _ sSubrScr;* IF signChange THEN ...branch[incOverFlChk, alu>=0];* IF increment >=0 THENincUnderFlChk:(SvaX) and (b0);skpif[alu#0];* IF SvaX AND b0 =0branch[incNormal];t _ sVaHiX _ (sVaHiX) -1;* THEN decrement sVaHiXdblbranch[incRtnDone, incSetBr, alu<0];incOverFlChk:(SvaX) and (b0);skpif[alu=0];* IF SvaX AND b0 # 0branch[incNormal];t _ sVaHiX _ (sVaHiX)+1;* THEN increment sVaHiXt-(sMaxBrHi);dblbranch[incRtnDone, incSetBr, alu=0];incSetBr:RBASE _ rbase[defaultRegion];rscr _ t;call[setBR], rscr2 _ (rscr2) - (rscr2);* set BRHinoop;incNormal:subroutine;RBASE _ rbase[incSvaRtn];link _ incSvaRtn;RBASE _ rbase[svaX];t _ svaX, RBASE _ rbase[defaultRegion];return, rscr _ r1;* return w/ t=lowva, alu result #0elp$X /Ng bAq a _pq +$ ^0]K\Z +(XU+3 Up q +$ T0S_R"P +(Ni+3 Kp q +$ J0IsH6F +*D}+3 Bpq + @: ?K= $:9T 8+5 +4^3 1-0Z0+ /hp .*q, ++)4+'' %|p $>q# +!H+ ' Rpq'+ \ p q f)  ' p+" B-]DORADO:memSubrsS.mcJune 17, 1981 9:31 AM %11incRtnDone:subroutine;RBASE _ rbase[incSvaRtn];link _ incSvaRtn;t _ t-1, RBASE _ rbase[defaultRegion];* return w/ t undefined,return, rscr _ t-t;* return w/ t undefined, alu result =0elp$X /Ng bA aq _^]K&+\+& Yp9q4DORADO:memSubrsS.mcJune 17, 1981 9:31 AM %12* May 18, 1981 2:11 PMnextSpat:* compute next pattern index; return in t%This routine increments SpatX, the pattern control variable that determines which pattern the routinegetSPat will generate. For simple patterns like cycled 1 and cycled 0, nextSpat also generates thevalue for the current pattern. The routine getSPat computes the values for the more complicatedpatterns.%* pattern1 IN [0..pat1EndC)= cycled 1* pattern2 IN [Spat1EndC..Spat2EndC)= cycled 0* pattern3 IN [Spat2EndC..Spat3EndC)= cycled 32 bit va (only 16 bits returned)* pattern4 IN [Spat3EndC..Spat4EndC)= pseudo random numbers* Return w/ end of patterns as branch condition ("ALU=0" means end of patterns)RBASE_ rbase[rmForStoreLoops];SRlink _ link;* save return linktop level;t_Spatx_(Spatx)+1;* SpatX in T while finding current patternt-(Spat1EndC);* see if IN [0..pat1EndC)branch[nxtSPat2, alu>=0],t_t;* goto[nextPat2, ~IN [0..Spat1EndC)]* IN [0..pat1EndC)skpif[alu#0];* see if just initializedskip, curSPattern _ 1c;* patX=0 ==> begin with onecurSPattern_(curSPattern)+(curSPattern);branch[nxtSPatXit],t_Spatx;nxtSPat2:t-(Spat2EndC);branch[nxtSPat3, alu>=0];* goto[nxtSPat3, ~IN [0..Spat2EndC)* IN [Spat1EndC..Spat2EndC)* pattern2 = left cycled 0curSPattern _ lcy[curSPattern, curSPattern, 1];t - (Spat1EndC);* If first time thru pattern 2, initskpif[ALU#0];* curSPattern for left cycled zero pattern.curSPattern _ not(b15);* curspattern _ 177776 on first time thrubranch[nxtSPatXit];nxtSPat3:t - (Spat3EndC);branch[nxtSpat4, alu>=0];* goto[nxtSPat4, ~IN[0..Spat3EndC) ]* IN [Spat2EndC..Spat3EndC)* pattern3 = cycled 32bit va (use low 16 bits)branch[nxtSpatXit];* pattern3 (cycled va) done by getSPat.nxtSPat4:t - (Spat4EndC);branch[nxtSpatXit, alu>=0];* IN [Spat3EndC..Spat4EndC)* pattern4 = pseudo random numbersnoop;call[cycleRandV];RBASE_ rbase[SRLink];* pattern4 (random numbers) done by getSpatbranch[nxtSpatXit];nxtSPatXit:link _ SRlink;* restore return link, fix up rbase,subroutine;RBASE_ rbase[defaultRegion];return,t-(SlastPatC);* return w/ proper branch conditionelp$X /Ng bAq ap+q) _ ^e ]Kb \` Z Y XU+ W$+ U$+* T$+ R"OONi +M, K+*J +Is+$ FE +D}+C@(B ?p>Jq = +# : 9T8/6+$5 ++4^+)3  0p/hq.*+$ + *r.)4+' &p%|q$> ! "H ++ p q +$ \+#2 DUMDORADO:memSubrsS.mcJune 17, 1981 9:31 AM %13* January 12, 1979 6:38 PMSTORAGE Test General SubroutinesgetSPat:* Enter w/ T = VA. rtn w/ next pattern in T%Currently there are four sets of patterns:pattern1left cycled 1 bitpattern2left cycled 0 bitpattern3left cycled vapattern4random numbersPattern1 and pattern2 return the same value every time getSPat is called, given a constant value forSpatX. Ie., the range for SpatX in pattern 1 is [0..Spat1EndC), and when SpatX is zero, getSPatalways returns 1, when SpatX is one, getSPat always returns 2, etc.Pattern2 is similar to pattern1 except that it is a bitwise complement, ie., a single zero bit withthe remaining bits all ones.Pattern3 returns the current va (treated as a 32 bit number) left cycled. The calling programprovides the current va (low 16 bits only) in T. The first time pattern3 is in effect, it returns thecurrent va. The next time nextSpat is called, the cycle count for pattern 3 increments and getSpatreturns the va left cycled 1, etc. When the current va is even, it returns the low 16 bits ofsvaHiX,,currentSva (appropriately cycled) and when it is odd it returns the low 16 bits ofcurrentSva,,sVaHiX (appropriately cycled).Pattern4 returns a random number.%mc[shc.AisT, b2];mc[shc.BisT, b3];set[shc.countShift, 10];mc[shc.maskShiftCount, b4,b5,b6,b7]mc[shc.rmt, shc.BisT!];* deal w/ rm,,tRBASE_ rbase[rmForStoreLoops];SRlink _ link;top level;(Spatx)-(Spat1EndC);* see which pattern we are usingbranch[getSP2,ALU>=0];* IN [0..Spat1EndC)* pattern 1 returns a cycled 1 bit.branch[getSPXit], t_curSPattern;* nextSpat did our workgetSP2:* return pattern 2 or greater(Spatx)-(Spat2EndC);branch[getSP3, ALU>=0];* IN [Spat1EndC..Spat2EndC)* pattern 1 returns a cycled 0 bit.branch[getSPXit], t _ curSPattern;* nextSpat did our workelp$X /Ng bAq+ _p+q+ ^]K*\+Z+Y+ XU+ VDpqpqO U` SC Qpq[ Pz NipqV M,f Kpq9p Jq^ IsZ H6* F$pq D Cpq Blpq A.p q ?pq >pq +<8: 9 8+7B 6 4#3+ 1p+q/. -V ,#*"+ ){E3>DORADO:memSubrsS.mcJune 17, 1981 9:31 AM %14* January 12, 1979 6:48 PMgetSP3:(SpatX) - (Spat3EndC);branch[getSP4, ALU>=0];* IN [Spat2EndC..Spat3EndC)%Pattern3 returns a cycled version of the current va.If current va is even,return the left cycle of sVaHix,,currentVa;otherwise,return the left cycle of currentVa,,sVaHiX.Begin by moving the current va into curSpattern, and then construct a shifter control value thatwill provide the correct cycle value. Always construct a SHC value that cycles rm,,t.%curSpattern _ t;* ENTERED W/ T = low 16 bits of vat _ shc.rmt;* construct SHC constant that willsSubrScr _ SpatX;* left cycle rm,,t by the correct amountsSubrScr _ (sSubrScr) - (Spat2EndC);* Spat2EndC is the first valid index for this patternsSubrScr _ lsh[sSubrScr, shc.countShift];sSubrScr _ (sSubrScr) and (shc.maskShiftCount);t _ t or (sSubrScr);* now we have the correct shc valueSHC _ t;t _ curSpattern;* we'll cycle rm,,tt _ shiftNoMask, sVaHiX;* = lcy[sVaHiX, t, ]branch[getSPxit], curSpattern _ t;skpif[R ODD], curSpattern;* decide which half of a cycled va to usebranch[getSP3even];getSP3odd: * lcy[currentVa,,sVaHix, ]t _ sVahiX;t _ shiftNoMask, curSpattern;* lcy[rm,,t, ];branch[getSPxit], curSpattern _ t;getSP3even: * lcy[sVaHiX,,currentVa, ]t _ curSpattern;t _ shiftNoMask, sVaHix;* t _ lcy[rm,,t, ]branch[getSPxit], curSpattern _ t;getSP4:(SpatX) - (Spat4EndC);branch[getSPXit, ALU>=0];* IN [Spat3EndC..Spat4EndC)* pattern4 returns pseudo ranom numbersnoop;getRandom[];* IN [Spat2EndC..Spat3EndC) (random numbers)RBASE _ rbase[SpatX];branch[getSPXit], curSpattern _ t;getSPXit:link _ SRlink;subroutine;return, RBASE_ rbase[defaultRegion];getCurSpattern: subroutine;* return curSPattern in TsaveReturn[Srlink];RBASE _ rbase[curSPattern];t _ curSPattern;returnUsing[Srlink];elp$X /Ng bAq ap_q^ ]K \1Y41WV+1Up T3+1R"` PV OTNij"TK "TJj(TIs$(5TH6)TF/TE#TD}TBjT@ )T?"T=  )T; 9Tp q1T8 T6#DT5" 3 p q1T1T0 !T/h" ,pT+qT*r )4 ''T&T%| ,T$>T#" pTHq T T$ Rpq TTTT\` CUMDORADO:memSubrsS.mcJune 17, 1981 9:31 AM %15* May 19, 1981 11:28 AMzeroMemory: subroutine;* zero contents of memory. clobber T, RSCR, RSCR2q_ t;saveReturn[zeroMemoryRtn];branch[doSetMemory], t_q;setMemory: subroutine;q_t;saveReturn[zeroMemoryRtn];doSetMemory:call[iSmunchCtrl];setMemL:call[nextSmunch];* returns t = next svaskpif[alu#0];branch[setMemLxit];cnt _ 17s;* inner loop to zero current munchrscr _ q;setMemIL:store _ t, DBuf _ rscr;loopuntil[cnt=0&-1, setMemIL], t _ t +1;branch[setMemL];setMemLxit:setMemLRtn:returnUsing[zeroMemoryRtn];saveMemAddr: subroutine;* save SvaHi, SvaXt _ Sva, RBASE _ rbase[SvaHiX];sVaXold _ t;t _ SvaHiX;SvaHiOld _ t;return, RBASE _ rbase[defaultRegion];fetchMemAddr: subroutine;* return SvaXold, SvaHiOld in rscr2, rscrsaveReturn[Srlink];RBASE _ rbase[SvaHiOld];t _ SvaXold;rscr2 _ t;t _ SvaHiOld;rscr _ t;returnUsing[Srlink];getSvaXold: * return value of SvaXold in TsaveReturn[Srlink];RBASE _ rbase[SvaXold];t _ SvaXold;returnUsing[Srlink];elp$X /Ng bAq ap q j1T_T^T]K Zp q TYTXU Wp TTq S_pTR"qjTP TOTM, ."TK JpTIsqTH6(TE C@p B T@q >Jp q T= T; T: T9T T8% 5p q )T4^T3 T1 T0 T/h T.*T, *rp q.T)4T'T& T%| $0CMODEL 1:memSubrsX.mcMay 14, 1981 3:14 PM%1title[memSubrsX];%*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++Table Of ContentsbyOrder of OccurenceROUTINEDESCRIPTIONiMRowCtrlInitialize map row loop controliMcolCtrlInitialize map column loop controliMpatCtrlInitialize map wait loop controliMwaitCtrlInitialize map wait loop controliMapPageCtrlInitialize map page loop controliMpageDownCtrlInitialize map page control for decrementing addressesnextMcolReturn t=next map columnnextMrowReturn t=next map rownextMwaitReturn t = next map wait valuenextMpage:Return t = next map pagenextMpageDownReturn t = next map page, decrementing addressesgetMpageReturn t = current map pagenextMpatReturn t = next map pattern, ALU=0 means no more patternsgetMpat:Return t = current map pattern.resetMapInitialize the hardware mapsetTestSynSet testsyndrome from TpresetMapInitialize map beginning at page 0getXmapBaseReturn t = xMapBasetestMapMidas subroutine for testing the mapresetTagKick start the tag bitsxVacateCacheRowVacate cache row for t = vareadMapRead map entrywriteMapWrite a map entrywaitForMapTwait for mapbuf busy to go away. Clobber TsetBrforMap:Set Br to reference a map entry, given Mrow and McolxSetBRforPageSet BR to point to map page in TxWriteMapPageWrite an entry into map, t = virtual page index, rscr = real pagexZeroMapZero the entire mapxGetConfigGet current memory system configuration.xGetMapICsInit xPageEndHi, xPageEndLo, 32bit lastpage valXgetSnModulesReturn sNmodulesxGetICtypeReturn t = icType = BrHi offset per modulexCountModulesReturn t = num storage modules; set sNmodules, toogetMsubrScrsReturn t = mSubrScrxGetPipe4:return pipe4 with all inverted bits hi truexBoardLoopMidas subroutine to exercise mapxRWDmuxWrite and read a dmux value, rtn t=ALUFM value =PD(branches will work)%*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++%*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++May 14, 1981 4:52 PMMisc changes to make code smaller.February 10, 1981 11:30 AMFix bugs in setBrForMap; fix bugs in nexMpage, nextMpageDown.February 9, 1981 9:52 AMChange map Page iterators to handle 64K, 256K ics, add xGetMapICs to read mufflers and findout mapIC size. Change getMPat to keep row,,col in separate bytes rather than a field = size of ras addr.July 1, 1979 2:50 PMchange xVacateCacheRow to use putCFmem, cause WriteMap to keep its data on Bmux one cycle earlier.June 28, 1979 11:17 AMMove sGetConfig into this file -- to centralize location of proceedures required for memorysystem initialization. Add table of contentsMay 29, 1979 2:39 PMSet mcr w/ disHold, noWake during xZeroMap.January 26, 1979 3:17 PMAdd B_FaultInfo' to resetMap to turn off any faults that may have occured.January 25, 1979 5:41 PMAdd xGetPipe2, xGetNumFlts.January 12, 1979 5:05 PMcause presetMap to add xMapBase to the real page number when writing map (handle situation whereinthere's no module 0, etc.)%*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++SUBROUTINE; gp$ .?sN bAq aB(`_p-j^( ]K Zq Ypq XUpq" Wpq Up q Tp q S_p q6 R"pq Ppq Opq Nip q M,p q0 Kpq Jpq9 Ispq H6pq Fp q Epq" D}p q C@pq$ Bpq @pq ?pq >Jpq = p q+ ;p q4 :p q 9Tp qA 8pq 6p q( 5p q/ 4^p q 3 p q* 1p q2 0p q /hp q+ .*p q ,pqF +B )4B '1&" %|1$>= #1!b c H1 b [ R- + \J  1fb ) B p D]MODEL 1:memSubrsX.mcMay 14, 1981 3:14 PM%2knowRbase[defaultRegion];iMrowCtrl:return, MrowX _ t_ a1;iMcolCtrl:return, Mcolx _ t_ a1;iMpatCtrl:t_cm1;Mpatx _ t;t _ curMpatLow _ t-t;return, curMPatHi _ t;iMwaitCtrl:t _ (r0)-(MwaitIncrC);return, curMWait _ t;iMapPageCtrl:xPageXLo_ t_ a1;return, xPageXHi_t;iMpageDownCtrl:RBASE_ rbase[xEndPageLo];xPageXLo _ xEndPageLo;xPageXHi _ xEndPageHi;return, RBASE_rbase[rscr]; gp$ .?sN bAq _p ^q ]Kp \q Zp YqXU WU Tp S_qR" Pp OqNi M,pKqJIsH6 F$!6jMODEL 1:memSubrsX.mcMay 14, 1981 3:14 PM%3* February 10, 1981 4:24 PMknowRbase[rmForMapLoops];nextMcol: subroutine;* compute next column; return it in T* Mcol IN [0..McolEndC)RBASE_ rbase[Mcolx];* compute end of columns as branch conditiont_Mcolx_(Mcolx)+1, RBASE_ rbase[xChipEndRasCas];return, t-(xChipEndRasCas), RBASE_ rbase[defaultRegion];nextMrow: subroutine;* compute next row; return it in T* MrowX IN [0..MrowEndC). Mrow _ MrowX.*WRITE DIRECTLY INTO DESTIN REGISTER, Mrow.* use this hack 'cause we can't switch rbase and then perform the exit testRBASE_ rbase[rmForMapLoops];* compute end of row as branch conditiont _ Mrowx_(Mrowx)+1;Mrow _ t;* WRITE DIRECTLY INTO Mrowt _ Mrowx, RBASE_ rbase[xChipEndRasCas];* sigh. put loop ctrl where we can access it.return, t-(xChipEndRasCas), RBASE_ rbase[defaultRegion];nextMwait: subroutine;* compute next wait return it in T* curMWait IN [0..MwaitEndC), incremented by MwaitIncrCRBASE_ rbase[rmForMapLoops];* compute end of columns as branch conditiont_ curMWait _ (curMwait) + (MwaitIncrC);RBASE_ rbase[defaultRegion];return,t-(MwaitEndC);nextMpage: subroutine;* compute next map page (increment by 1)RBASE _ rbase[xPageXLo];t _ xPageXLo _ (xPageXLo) + 1;* increment page numbert-(xEndPageLo), RBASE_ rbase[defaultRegion];skpif[ALU=0], FreezeBC;return, FreezeBC;* return w/ fast branch conditionRBASE_ rbase[xPageXHi];* must increment hi value.t_ xPageXHi_ (xPageXHi)+1;* check for done, too.t-(xEndPageHi);t_ xPageXLo, FreezeBC;skpif[ALU=0], RBASE_ rbase[defaultRegion];return, PD_ a1;* more to do, alu#0return, PD_ a0;* done. alu=0nextMpageDown: subroutine;* rtn w/ ALU=0 => no more pages.RBASE _ rbase[xPageXLo];t _ xPageXLo _ (xPageXLo) - 1;t # (cm1);* stop when underflow taskes us to -1??skpif[ALU=0];return, PD_ a1, RBASE _ rbase[defaultRegion];knowRbase[xPageXLo];xPageXHi_ (xPageXHi)-1, RBASE_ rbase[defaultRegion];skpif[alu<0];return, PD_ a1;return, PD_ t-t;* rtn ALU=0 => no more pages to writegetMpage: subroutine;* return current map page without incrementingRBASE _ rbase[xPageXLo];return, t _ xPageXLo, RBASE _ rbase[defaultRegion]; gp$ .?sN bAq _ ]Kpq +% \Y+,XU0W8 Tpq +" S_' R"+ PKNi+(M,K+Is)+-H68 Ep q +" D}7B+,@(?>J ;p q +(:9T+8,65+!3 +1+0/h.**,+++ )4p q +'&%| +'$> #. H4 +% pq +.\38 >TMODEL 1:memSubrsX.mcMay 14, 1981 3:14 PM%4* February 9, 1981 10:20 AMnextMpat: subroutine;* compute next pattern index; return in t* pattern1 IN [0..pat1EndC)= cycled 1* pattern2 IN [Mpat1EndC..Mpat2EndC)= function of current Mrow, McolpushReturn[];* compute end of patterns as branch conditionRBASE _ rbase[MpatX];t_Mpatx_(Mpatx)+1;t-(Mpat1EndC);* see if IN [0..pat1EndC)branch[nxtMPat2, alu>=0],t_t;* goto[nextPat2, ~IN [0..pat1EndC)]* IN [0..pat1EndC)skpif[alu#0];* see if just initializedskip, t _ curMPatLow _ 1c;* patX=0 ==> begin with onet _ curMPatLow _ (curMPatLow) lsh 1;MpatLow _ t;(MpatX) - (20c);* see if we've overflowed into hi bitsskpif[ALU#0], t _ curMpatHi _ (curMpatHi) lsh 1;* left shift current MpatHit _ curMpatHi _ 1c;* we've been left shifting zero. set it to 1MpatHi _ t;branch[nxtMPatXit], t _ MpatX;nxtMPat2:* see if IN[pat1EndC..pat2EndC)t-(Mpat2EndC);branch[nxtMPat3, alu>=0];* goto[nextPat3, ~IN[pat1EndC..pat2EndC)]* IN [Mpat1EndC..Mpat2EndC)curMPatHi _ t-t;branch[nxtMPatXit], curMPatLow _ t-t;* Zero itnxtMPat3:* code for next patter goes herebranch[nxtMPatXit];nxtMPatXit:link _ stack&-1;* restore return link, fix up rbase,subroutine;RBASE_ rbase[defaultRegion];return,t-(MlastPatC);* return w/ proper branch condition gp$ .?sN bAq apq +) _+ ^$+\ +-ZYXU +W+# TS_ +R"+P$O Ni+&M,00ZK+,J Is Fp+qE D}+) B@?%+ = p+q; 9Tp 8q+$6 54^+# 2>%5MODEL 1:memSubrsX.mcMay 14, 1981 3:14 PM%5* December 13, 1978 1:16 PMMAP Test General SubroutinesgetMPat:* compute current pattern; return low bits in T%Currently there are two sets of patterns. The first set consists of a cycled one. The secodpattern produces unique values based on row and column.pattern1: maintained by the nextPattern code -- it changes when "next pattern"is called. pattern2 changes more frequently (for every column!)pattern2: OR the quantity (row lshift 3) + column into curPattern.Eg., if curPattern = 0, row = 22, col = 3 THEN result = 223%pushReturn[];RBASE _ rbase[MpatX];(Mpatx)-(Mpat1EndC);* see which pattern we are usingbranch[getMP2,alu>=0];t _ curMpatHi;MpatHi _ t;t _ curMpatLow;branch[getMPxit], MpatLow _ t;getMP2:* return pattern 2 or greater(Mpatx)-(mpat2EndC);branch[getMP3, alu>=0];t _ curMpatHi;RBASE _ rbase[defaultRegion];* fetch value of Mrow, Mcol from defaultRegionMpatHi _ t;t _ Mrow;MsubrScr _ t;t _ Mcol, RBASE _ rbase[rmForMapLoops];MsubrScr _ lsh[MsubrScr, 10];* Mrow, Mcol separate bytest_t OR (curMpatLow);* curPattern,,columnt_t OR (MsubrScr);* curPattern,,row,,columnbranch[getMPxit], MpatLow _ t;getMP3:* add code for pattern 3 herebranch[getMPXit];getMPXit:link _ stack&-1;subroutine;return, RBASE_ rbase[defaultRegion];getMwait:* return current value of map Wait in TRBASE _ rbase[rmForMapLoops];return, t _ curMwait, RBASE _ rbase[defaultRegion]; gp$ .?sN bAq+ _p+q/ ^]K[ \7 YN XU? UB T; S_R" PO+NiM, K JIs Fp+qED}C@ @+.? >J= ;'9T+8+6+5 3 p+q1 /hp.*q, +$ )4p+q''&3 %YABMODEL 1:memSubrsX.mcMay 14, 1981 3:14 PM%6* January 26, 1979 3:18 PMresetMap:* when the machine powers up, the* map may be in an arbitrary state.* kick-start the automata by performing two fetches. Cope w/ "tag" bit by* performing a reference that hits and then punch on the map 8 times to wake it up.pushReturn[];set[xmcrv, OR[mcr.fdMiss!, mcr.disHold!, mcr.disCF!, mcr.disBR!, mcr.noWake!]];t_AND[xmcrv, 177400]C;* init MCR w/ virtually everything turned offt _ t OR (AND[xmcrv, 377]C);call[setMCR];fetch _ r0;* perform the two fetches, separated by waitst _ 40C;call[longWait];fetch _ r0;t _ 40C;call[longWait];call[resetTag], t_r0;* reset our tag bit. use va=0cnt _ 10s;* punch on the map a bunch of timesresetML:noop;rscr _ t-t;call[writeMap], rscr2 _ t-t;loopWhile[cnt#0&-1, resetML];t _ mcr.disHold;* reset mcr for further map testing:t _ t OR (mcr.noWake);* use disHold, noWakecall[setMCR];B_FaultInfo';returnP[];* January 1, 1979 3:11 PMsetTestSyn:saveReturnAndT[Drlink, rscr];t _ 62c;call[longWait];t _ mcr.noWake;call[setMCR];t _ rscr;* retrieve original value of trscr _ t-t;rscr2 _ t-t;call[setBR];STORE _ r0, DBuf _ t;loadTestSyndrome[t];t _ 62c;call[longWait];t_ FaultInfo';returnUsing[Drlink];* February 9, 1981 9:50 AMpresetMap:* initialize map beginning at page 0pushReturn[];call[resetMap];t _ FaultInfo';* clear any pending wakeupscall[clearCacheFlags];* assure beingLoaded not set in cachecall[setMCR], t_t-t;* clear mcrcall[iMapPageCtrl];pmL:call[nextMpage];* get next page numberbranch[pmLxit, alu=0];noop;call[xSetBRforPage];* expects t = page numbercall[getMpage];* get page number in tcall[getXmapBase], rscr2 _ t; gp$ .?sN bAq ap+q! _# ^I ]KSZ YOW+-UT R" +-PONi M,KIs+F +# EpqD}C@ B@>J+$= +; : 8 5 4^p 3 q0/h.*, ++*r )4 ' &%|$>#!     p +q$ R++%+  pq+f) + p+ 3l >%]MODEL 1:memSubrsX.mcMay 14, 1981 3:14 PM%7rscr2 _ t + (rscr2);* Construct offset for situation whererscr _ t-t;* there's no module 0. xMapBase is set bycall[writeMap];* sGetConfig. Write map w/ page number.branch[pml];pmLxit:returnP[];getXmapBase: subroutine;RBASE _ rbase[xMapBase];return, t _ xMapBase, RBASE _ rbase[defaultRegion]; gp$ .?sNbAq+&a +)_+(^ \pZq XUp q WU3P Tz;uDMODEL 1:memSubrsX.mcMay 14, 1981 3:14 PM%8* February 9, 1981 9:43 AMtestMap:* Mcol = column, Mrow = row, Mpat = pattern,* RSCR = cycles to wait, RSCR2 #0 => call resetMappushReturn[];* params and return link are saved. proceed...q _ rscr;* save cycles to wait in Q for a whilerscr2 _ rscr2;skpif[alu=0];* see if we should call resetMapcall[resetMap];* reset and write the mapcall[setBRforMap];rscr _ MpatHi;rscr2 _ MpatLow;call[writeMap];rscr2 _ q;* now wait if required. retrieve wait countrscr2 _ (rscr2) - (120C);* subtract 80 cycles for cost of readMapskpif[alu>=0];branch[testMapChk];rscr2 _ (rscr2) + 1;* fast branch might be zero -- fix itbranch[., alu#0],rscr2 _ (rscr2) -1;* WAIT LOOPtestMapChk:call[readMap];t _ MpatLow;t _ t # (rscr);skpif[alu=0];xTestMapErr3:* Mrow,Mcol = address. Q = time waitederror;* Mpat = expected, rscr = pipe3t _ ldf[rscr2, 2, pipe4.dirtyShift];* rt justify the diry, wprotect bits fromt#(MpatHi);* the copy of Pipe4 that is in rscr2.skpif[ALU=0];* T= wprotect,dirty from pipe4, MpatHixTestMapErr4:* is value of those bits as we wrote them.error;* rscr2 contains a copy of pipe4, w/ low* true bits inverted.returnP[];resetTag:* kick start the tag bit for our task.* T = address to reference.pushReturn[];rscr _ t;set[xmcrv, OR[mcr.noRef!, mcr.disHold!, mcr.disCF!, mcr.disBR!, mcr.noWake!]];t _ AND[xmcrv,177400]C;t_t or (AND[xmcrv, 377]C);* set MCR w/ noRef, disHold, disCF, disBRcall[setMCR];DBuf _ rscr, STORE _ rscr;* write and read to cause a hitcall[longWait], t _ 10C;fetch _ rscr;returnP[]; gp$ .?sN bAq ap+q, _2^ +.\+&Z Y +XU+WU TS_P ++O+(Ni M,J+%Is$+ Fp qE D} C@B @p q+&?+= $+); +%: +' 9Tp +q*8+(64^ 1p+q& 0.* ,+N*r)4+)' %|+$>#   %>HMODEL 1:memSubrsX.mcMay 14, 1981 3:14 PM%9* July 1, 1979 2:47 PMxVacateCacheRow:* T = va. Cause all the columns of the cache entry forva to be vacant by setting the vacant bit. Use useMcrV to write each column in succession by usingCFLAGS_.pushReturnAndT[];cnt _ 3s;xVacateCacheRowL:rscr _ cflags.vacant;rscr2 _ cnt;call[putCFmem], t _ stack;loopUntil[CNT=0&-1, xvacateCacheRowL];pReturnP[]; gp$ .?sN bAq _pq+6 ^b ]K\Z YpXUqW UT&S_  QD JMODEL 1:memSubrsX.mcMay 14, 1981 3:14 PM%10* May 14, 1981 3:12 PM%Read the map for position row, column and return with rscr = pipe3 and rscr2 = pipe4.To read the map, vacate the cache entiries for the cache row that the va represents. There isone bit of overlap, va[15] , between the va bits that address the map column, va[9:15] and the bitsthat address the cache row, va[15:19]. Pass that bit as a parameter to the vacate CachRow procedure.Set the BR appropriately?READ MAP TAKES ABOUT 80 CYCLES%readMap:pushReturn[];t _ mcr.disHold;call[setMcr],t_t OR (mcr.noWake);* no wakeups pleasecall[setBrforMap];* read map for current row, columnRMap _ r0, call[waitForMapT];* don't try to get data until it's stable.rscr _ not(Pipe3');call[xGetPipe4];* use subroutine since pipe4' is complicatedrscr2 _ t;returnP[];writeMap: subroutine;* ENTER w/ rscr = 2 bits for tio, rt justified, rscr2= MapBuf datapushReturn[];call[waitForMapT];rscr _ lsh[rscr, 16];tioa _ rscr;t _ t-t;writeMapX:B_rscr2;* keept it on bmux earlymap_t, MapBuf_rscr2;call[waitForMapT];returnP[];waitForMapT: subroutine;* wait for mapbuf busy to go away.noop;t_ pipe5;* clobber Tt_ t and (pipe5.MbufBusy);branch[.-2, alu#0];return; gp$ .?sN bAq a _U]K] \c Zd Y W T S_pqR" PO!+M,+"K+*IsH6+,E D} Bpq +5 @ ? >J= ; : 9Tp 8q+653 0p q +"/h.*+ ,+*r )D1>MODEL 1:memSubrsX.mcMay 14, 1981 3:14 PM%11* February 10, 1981 5:18 PMsetBrforMap:* given Mrow and Mcol, construct a va and put it inthe current base register. note that Mrow and Mcol contain up to 9 bits of VA apiece. This code is soarbitraryk because the choice of which bits in the VA map into the map ras/cas bits is rathercomplicated. The code reverses that mapping; ie., given ras and cas it generates the va. Naturallyas the page size changes the mapping of the bits changes, too. See the diagram "Dorado Addressing" byClark and McDaniel. Use a color printer.mc[storagePageSize, 400];mc[pageIs256C, 400];mc[pageIs1KC, 1000];mc[pageIs4KC, 4000];mc[Mrow.b0, b7];mc[Mrow.b1, b8];mc[Mrow.2thru8, b7,377 ];mc[Mcol.b0, b7];mc[Mcol.b1, b8];mc[Mcol.b5, b12];mc[Mcol.b6, b13];mc[Mcol.b7, b14];mc[Mcol.b8, b15];mc[Mcol.78, b14,b15 ];mc[Mcol.2thru8, 177 ];mc[Mcol.2thru4, b9,b10,b11 ];mc[Mcol.2thru6, b9,b10,b11,b12,b13 ];set[ras.b0justify, 10];set[ras.b1justify, 7];pushReturn[];* with a drawing of the correspondancet _ storagePageSize;* between various Dorado addresses, thist - (pageIs256C);* might be understandable.skpif[ALU=0];branch[setBrForMap2];* This code works for 256K map chips. Mrow.b0 and Mcol.b0 are always 0 unless we are using 256K mapchips. Mrow.b1 and Mcol.b1 are always 0 unless we're using 64Kk map chips. Mrow.b2thru8,Mcol.b2thru8 always contain legitimate map ras/cas values.t_ ldf[Mrow, 1, ras.b0justify];* bit 0 of map row for 256K chipsrscr_ lsh[t, 11];* position in BrHi.t_ ldf[Mrow, 1, ras.b1justify];* bit 1 of map row for 256K and 64K chipst_ lsh[t, 7];* position it correctly and add to BrHirscr_ (rscr) or t;* value we are constructingt_ ldf[Mrow, 6, 1];* all map chips use this range of valuesrscr_ t or (rscr);t_ ldf[Mcol, 1, ras.b0justify];* 256K chips's cas contributes this bitt_ lsh[t, 10];t_ t or (rscr);t_ ldf[Mcol, 1, ras.b1justify];* bit 1 of map row for 256K and 64K chipst_ lsh[t, 6];* position it correctly and add to BrHit_ t or (rscr); * BrHi is done. Whew!rscr2 _ t-t;* compute BrLoskpif[r even], Mrow;* add va[16] if requiredrscr2 _ 100000C;t _ (Mcol) and (Mcol.2thru8);* isolate low 6 bits of columnt _ lsh[t, 10];* correspnd to va[17:23];branch[setBrForMapDoIt], rscr2 _ t or (rscr2);setBrForMap2: * February 10, 1981 10:20 AM I don't believe this works.t _ storagePageSize;t - (pageIs1Kc);skpif[ALU=0];branch[setBrForMap3];t _ (Mrow) and (Mrow.b0);rscr _ lsh[t, 3];* corresponds to va[4]t _ (Mrow) and (Mrow.b1);rscr _ (rscr) or t;* correspondsk to va[8];t _ ldf[Mrow, 6, 1];rscr _ (rscr) or t;* correspond to va[10:15] gp$ .?sN bAq ap q+3 _f ^] ]Kf \f Z) XUpq Wp q Upq Tpq S_pq R"pq Pp q Opq Nipq M,pq Kpq Jpq Ispq H6pq Fp q Ep q D}p q C@p q Bp q? +p&>Jq+p)= q+p;q : 8d 6Z 5:3 +!1+0+)/h +'.*+++(*r'+'& %|$>+)# +'!+H +  ++R+. p q>\ f)+  + p 3+  E3]ZMODEL 1:memSubrsX.mcMay 14, 1981 3:14 PM%12t _ (Mcol) and (Mcol.b0);t _ lsh[t, 2];* corresponds to va[5];rscr _ (rscr) or t;t _ (Mcol) and (Mcol.78);t _ lsh[t, 10];* correspond to va[6:7]rscr _ (rscr) or t;t _ (Mcol) and (Mcol.b1);t _ t rsh 1;rscr _ (rscr) or t;* corresponds to va[9]rscr2 _ t-t;skpif[r even], Mrow;rscr2 _ 100000c;* corresponds to va[16]t _ (Mcol) and (Mcol.2thru6);t _ lsh[t, 10];* correspond to va[17:21]branch[setBrForMapDoIt], rscr2 _ (rscr2) or t;setBrForMap3:t _ storagePageSize;t - (pageIs4Kc);skpif[ALU=0];error;* impossible configuration (neither 256 wd nor 1k nor4k)t _ ldf[Mrow, 6, 1];rscr _ t;* correspond to va[10:15]t _ (Mrow) and (Mrow.b1);rscr _ (rscr) or t;* corresponds to va[8]t _ (Mcol) and (Mcol.b8);t _ lsh[t, 13];* corresponds to va[4]rscr _ (rscr) or t;t _ (Mcol) and (Mcol.b5);t _ lsh[t, 7];* corresponds to va[5]rscr _ (rscr) or t;t _ (Mcol) and (Mcol.b7);t _ lsh[t, 10];* corresponds to va[6]rscr _ (rscr) or t;t _ (Mcol) and (Mcol.b6);t _ lsh[t, 6];* corresponds to va[7]rscr _ (rscr) or t;t _ (Mcol) and (Mcol.b1);t _ t rsh 1;* corresponds to va[9]rscr _ (rscr) or t;t _ (Mcol) and (Mcol.2thru4);rscr2 _ lsh[t, 10];* correspond to va[17:19]skpif[r even], Mrow;rscr2 _ (rscr2) or (100000c);* corresponds to va[16]noop;setBrForMapDoIt:call[setBR];returnP[]; gp$ .?sNbAqa +_^]K+\ZY XU+U TS_+R"P+O. M,p KqJIs H6+5 FD}C@+B@+?>J+= ;: +9T86+54^3 +10/h +.*+*r+)4'+& $>p#q !  cD1GMODEL 1:memSubrsX.mcMay 14, 1981 3:14 PM%13* December 13, 1978 6:40 PMxSetBRforPage:* given t = page number, set BR so that va=0* will reference that virtual page. Assume 256 words/ page. CLOBBER T, rscr, rscr2pushReturn[];rscr _ t;rscr2 _ t;rscr _ rsh[rscr, 10];* rscr _ brHI = top 8 bits of page numrscr2 _ lsh[rscr2, 10];* rscr2 _ brLO = (low 8 bits of page num) lsh 8call[setBR];* rscr = brHI, rscr2 = brLOreturnP[];* December 13, 1978 2:59 PM%xWriteMapPageWrite an entry into the map: Enter with t = virtual page index and with rscr = the real page thatcorresponds to that virtual page.Clobber BR!%xWriteMapPage: subroutine;pushReturn[];rscr2 _ t;* move real page into MsubrScrt _ rscr;MsubrScr _ t;%a virtual page index maps into BR values by performing a left shift of 8. The high order 8 bits of theindex shift into BrHi and the low order bits of the index shift into the high order 8 bits of BrLO%t _ rsh[rscr2, nBitsInPage];rscr _ t;rscr2 _ lsh[rscr2, nBitsInPage];call[setBR];* setup BR so that addr "0" references virtual pagecall[getMsubrScr];rscr _ t-t;call[writeMap], rscr2 _ t;returnP[];xReadMapPage: subroutine;* enter w/ t = page number, exit w/ t =pushReturn[];* real page number, rscr = pipe4 (w/ all hi true bits)call[xSetBrForPage];call[waitForMapT];RMap _ r0;call[waitForMapT];rscr _ not(Pipe3');call[xGetPipe4];rscr2 _ t;* save pipe 4 till we can get it into rscrt _ rscr;* t _ real page numberrscr _ rscr2;* rscr _ pipe4 (w/bits properly inverted)returnP[]; gp$ .?sN bAq ap +q, _R^ ]K\ Z+&Y+/XU +U T S_)R"p Pqa O! M, K Jp q Is H6 +FE D} C@f Bb @>J= ;: +39T8 64^ 1p q +'0 +6/h.*, +*r)4' +*&+%| +)$>  "E3E-MODEL 1:memSubrsX.mcMay 14, 1981 3:14 PM%14* May 29, 1979 2:39 PM%xZeroMapWrite zero into all the entries of the map (ignore wp,dirty)%xZeroMap:pushReturn[];t _ (OR[mcr.disHold!,mcr.noWake!]C);B_FaultInfo'[];call[setMCR];call[iMapPageCtrl];xZeroMapL:call[nextMpage];skpif[ALU#0];branch[xZeroMapXit];rscr _ t-t;call[xWriteMapPage];branch[xZeroMapL];xZeroMapXit:returnP[]; gp$ .?sN bAq a _p+q6 ^ ]K \pZq Y$XUW T R"p PqO NiM, KJ Isp H6q t ED"sgMODEL 1:memSubrsX.mcMay 14, 1981 3:14 PM%15* June 28, 1979 1:13 PMxGetConfig: subroutine;* return w/ t = maxBrHi.%Set sMaxBrHi, a register that contains the last valid BrHi +1.Set xMapBase, a register that contains the offset that PresetMap adds to real page numbers wheninitializing the map. xMapBase enables the storage diagnostics to run with contiguous storage modulesthat need not begin with module 0.%pushReturn[];call[xCountModules];sNmodules _ t;skpif[alu#0];error;* no modules!!!noop;call[XgetSnModules];* initialize sNmodulescall[xGetICtype];* T: 1=>4K, 4=>16K, 16=>64K%Note: the "ic type" is a number that happens to be the correct value for sMaxBrHi, given onlyone module of that type. Ie., If there are 3 modules, sMaxBrHi _ 3 * icType. Remember that sMaxBrHiis one greater than the last valid value for BrHi in this configuration.%xConfigBrHi:call[XgetSnModules], rscr _ t;* Remember icTyp in rscr.t _ t-1;* begin w/ nModules-1cnt _ t;* rscr contains our increment for sMaxBrHit _ t-t;loopUntil[cnt=0&-1, .], t _ t + (rscr);* multiply by addingsMaxBrHi _ t;* Set sMaxBrHi.%(set xMapBase) Now we must find the real page number for the first page in storage. Usually themap initialization code sets map[i] _ i. However, if we are missing modules this won't work.Furthermore, this code only works when the installed modules are contiguous. Ie., M2, M3 is a validconfiguration while M0, M3 is not valid (where Mi referes to memory module i). The restriction tocontiguous modules occurs because the presetMap code doesn't recognize when it crosses a "moduleboundary" when it writes the map. At module boundaries it should check to see if the module reallyexists!%xConfigMapBase:t _ rscr;* remember, rscr contains the ictyperscr2 _ t-t;* now right shift ictype,,0 by the numbert _ rcy[t,rscr2, nBitsInPage];* of address bits in a map page. This givesrscr _ t;* the "map increment" for missing modules.rscr2 _ not(Config');t _ (rscr2) and (config.m0);skpif[ALU=0];branch[xConfigMBxit], t _ r0;* Module 0 is in place(rscr2) and (config.m1);skpif[ALU=0];branch[xConfigMBxit], t _ rscr;* missing only one module(rscr2) and (config.m2);skpif[ALU=0];branch[xConfigMBxit], t _ (rscr) + (rscr);* missing module 0, module 1(rscr2) and (config.m3);skpif[ALU=0], t _ (rscr) + (rscr);* t _ 2 * mapIncrementbranch[xConfigMBxit], t _ t + (rscr);* t _ t + mapIncrementerror;* can't find any modules. There's been a seriouserror.xConfigMBxit:xMapBase _ t;* Set xMapBase.RBASE _ rbase[sMaxBrHi];t _ sMaxBrHi, RBASE _ rbase[defaultRegion];xGetCLXit:ReturnP[]; gp$ .?sN bAq ap q + _ ^pqrq ]KpqS \f Z" YXU UT S_ R"+PNi+M,+ KJ rqK Isd H6rq: F Ep D}q+C@+B+*@?'+>J +p q = ;_ :] 9Td 8b 6` 5c 4^ 3 1p0q+$/h +).*++,+*+*r)4 '+%|$> #+ H  *-R"+%++0 \ p q +p q) + p  pq E3]>MODEL 1:memSubrsX.mcMay 14, 1981 3:14 PM%16* February 9, 1981 10:14 AM% xGetMapICsThis routine initializes the RM locations xPageEndHi,,xPageEndLo so that the loop routines will work properly for the current map ic size.Assume 1510=DMUX address for three consecutive muffler values that define the signals, MapIs16K,MapIs64K, MapIs256K.EXIT w/xEndPageHi,,xEndPageLoIC size0,,4000016K1,,064K4,,0256K%set[MapIs16K, 1510];* assume this address muffler correctly.xGetMapICs:pushReturn[];t_ AND[MapIs16K, 177400]C;call[xRWDmux], rscr2_ t_ t or (AND[MapIs16K, 377]C);branch[xMapIs16K, ALU<0];noop;* for placementcall[xRWDmux], rscr2_ t_ (rscr2)+1;branch[xMapIs64K, ALU<0];noop;* for placementcall[xRWDmux], rscr2_ t_ (rscr2)+1;skpif[alu<0];xGetMapICErr:* none of the muffler values weerror;* tried was non-zero.* Map is 256KxEndPageLo_a0;t_4c;xEndPageHi_t;t_ 1000c;xChipEndRasCas_ t;xGetMapICRtn:returnP[];xMapIs16K:xEndPageHi_ a0;t_ 40000c;xEndPageLo_ t;t_ 200C;branch[xGetMapICRtn], xChipEndRasCas_ t;xMapIs64K:t_ xEndPageLo_ a0;xEndPageHi_ t+1;t_ 400C;branch[xGetMapICRtn], xChipEndRasCas_ t; gp$ .?sN bAq ap +q6 _T ]K` \ YXU+W+U+T+ S_ P+( Nip M,q KJ4IsH6+F#ED}+C@#B @p +q?+ = ; :9T 86 4^p 3 q 0p /hq.* , +*r( 'p &q%|$>#(D cDGMODEL 1:memSubrsX.mcMay 14, 1981 3:14 PM%17* June 7, 1979 2:07 PM%XgetSnModulesreturn sNmodulesxGetICtypereturn t = icType = BrHi offset per modulexCountModulesreturn t = num storage modules, set sNmodules, too.%XgetSnModules: subroutine;RBASE _ rbase[rmForStoreLoops];return, t _ sNmodules, RBASE _ rbase[defaultRegion];%This routine uses Config to determine the chip size used in the storage boards. The value it returnsdescribes the maximum BrHi +1 for a single module of the storage boards, given the chip size. Ie.,If there are 3 modules, 3 * (number returned in T from calling this routine) is the maximum BrHi +1for the current memory configuration.%xGetICtype: subroutine;* RETURN T =(1=>4k, 4=>16K, 16=64K, 64 =>256K)pushReturn[];rscr _ not(Config');rscr _ ldf[rscr, config.icTypeSZ, config.icTypePos];PD _ rscr;skpif[ALU#0], (rscr) # (1c);* test against 1 incase it's not zerobranch[xGetIcRtn], t _ 1c;* config.icType=0 ==> 4K chipsskpif[ALU#0], (rscr) # (2c);* test against 2 incase it's not zerobranch[xGetIcRtn], t _ 4c;* config.icType=1 ==> 16K chipsskpif[ALU#0], t _ 64c;* set to 256K chips herebranch[xGetIcRtn], t _ 16c;* reset to 64K chips if config.icType=2xGetIcRtn:returnP[];* January 12, 1979 3:22 PMxCountModules: subroutine;* return T=num storage modules. set sNmodules!pushReturn[];rscr _ not(Config');noop;rscr _ ldf[rscr, config.modSZ, config.modPOS];* modules rt justifiedt _ config.modSZC;* set cnt to (num bits in module field) -1cnt _ t;t _ t-t;xCountML:skpif[r even], rscr;t _ t + 1;rscr _ (rscr) rsh 1;loopuntil[cnt=0&-1, xCountML];sNmodules _ t;returnP[];* January 25, 1979 5:42 PM%Code for returning values in T.%getMsubrScr: subroutine;RBASE _ rbase[mSubrScr];return, t _ MsubrScr, RBASE _ rbase[defaultRegion];xGetPipe4: subroutine;* return Pipe4 with all inverted bitst _ not(pipe4');* fixed up such that a '1' bit impliest _ t # (pipe4.sexChange0);* the "true" conditionreturn, t _ t # (pipe4.sexChange1); gp$ .?sN bAq a _p q ^p q* ]Kp q3 \ Zp q YXU4 T S_e R"d Pc O% Ni Kp q +.J H6E4D} C@+%B+?+%>J+;+:+' 8p 6q 4^ 1p q +.0 .*,*r.0Z'++&$> #p!q H  R  \  p q f3 p q +% +& p+ 3# D]MODEL 1:memSubrsX.mcMay 14, 1981 3:14 PM%18xGetPipe2: subroutine;return, t _ not(pipe2');xGetNumFlts: subroutine;t _ not(pipe2');return, t _ ldf[t, pipe2.nFaultsSize, pipe2.nFaultsShift]; gp$ .?sN bA q a _p q ^]K: [* .MODEL 1:memSubrsX.mcMay 14, 1981 3:14 PM%19* December 18, 1978 10:20 AM% exerciser for map: to be used when bringing up new boards%xBoardLoop: top level;RBASE _ rbase[defaultRegion];call[setMbase], t _ r0;rscr _ t-t;call[setBR], rscr2 _ t-t;t _ mcr.disHold;t _ t OR (mcr.noWake);call[setMCR];t _ 1c;stkp _ t;xBdL:call[xUp];branch[.-1];xUp: subroutine;pushReturn[];RBASE _ rbase[Mwait];call[longWait], t _ Mwait;t _ MwriteVal;Map _ Maddr1, MapBuf _ t;call[longWait], t _ Mwait;t _ not(MwriteVal);Map _ Maddr2, MapBuf _ t;noop;xup2:call[longWait], t _ Mwait;RMap _ Maddr1;call[longWait], t _ Mwait;Mread1 _ not(Pipe3');noop;RMap _ Maddr2;call[longWait], t _ Mwait;Mread2 _ not(Pipe3');RBASE _ rbase[defaultRegion];returnP[];* February 6, 1981 2:06 PMxRWDmux: pushReturn[];rscr_ 14C;xDmuxL:T_ T+(MidasStrobe_ T);* Shift address bit from B[4]Noop;rscr_ (rscr)-1;Branch[xDmuxL, ALU#0];T_ ALUFMem, rscr, Branch[.+2, R>=0]; * T_ DMuxDataUseDMD;returnPandBranch[t];knowRbase[defaultRegion];top level;mapSubrsDone: noop; gp$ .?sN bAq a; _ ]Kp q \ZY XUWUT S_R" PpOq Ni Kpq J IsH6F ED}C@B@ ?p>Jq= ;:9T8 654^3 0 .*pq, +pq*r-)4'&%|2$>#   Rp q+ 5OGACHAGACHAGACHAJ J$&V*1.3 <CELNTCY5_fhnuIy~Jj[/jzSj,' !#&5*?.42 6J9j<B`FHMhPVCZn]b`eohnqw~%,mQ_  M  }/21#)18=eA JLSAV]dgm`pTt S}Y:oYoidft!a$*,3%8=9@wHJQIU;Y_afhJltx#|~-%BZ:Z:Z=KZ!B:Z:Z9aZ"*i^ \Z  :# 5:#:; :#:+iH :#::C:#=[#B"9B":;:C:#:B :#PP* :K 9Z:# *i^:':+i :#:?"iN:;Z :?Z :#:C:# 9:C :#:;:'i :?Z  q!R* :#:;B " :  Z  Z :Z :Z":B9dZ"*ia Z  ":B Z Z Z 9NZ"*iI Z j/_MemoryDiagnostics.pressmcdaniel23-Jun-81 12:56:11 PDT