postamble.mcMay 18, 1981 2:09 PM %1TITLE[POSTAMBLE];TOP LEVEL;%May 18, 1981 1:37 PMFix random number generator to use a better algorithm. Modify restart code, and the varioussubroutines associated with random numbers. Add setRandV, cycleRandV.February 1, 1980 6:24 PMFix goto[preBegin], described below, into goto[restartDiagnostic]. Postamble already definesand uses preBegin.February 1, 1980 11:52 AMFix restart to goto[preBegin]. This allows each diagnostic to perform whatever initializationit wants.September 19, 1979 9:18 PMFix another editing bug in chkSimulating, used the wrong bit to check for flags.conditionOK --just did it wrong.September 19, 1979 9:08 PMFix bug in chkSimulating wherein an edit lost a carriage return and a statment became part of acomment. Unfortunately, automatic line breaks made the statement look as if it were still thererather than making it look like part of the comment line.September 19, 1979 4:23 PMFix placement errors associated with bumming locations from makeholdvalue and fromchecksimulating.September 19, 1979 3:48 PMBum locations to fit postamble with current os/microD: reallyDone, checkFlags global, makecheckFlags callers exploit FF, eliminate noCirculate label, make others shorter..September 19, 1979 10:41 AMchange callers of getIM*, putIM* to use FF field when calling them.September 19, 1979 10:18 AMCreate zeroHoldTRscr which loops to zero hold-- called by routines that invoke resetHold whenthe hold simulator may be functioning. Make getIM*, putIM* routines global.September 16, 1979 1:27 PMBum code to fix storage full problem that occurs because OS 16/6 is bigger than OS 15/5: removekernel specific patch locations (patch*).August 1, 1979 3:28 PMAdd scopeTrigger.June 17, 1979 4:48 PMMove IM data locations around to accommodate Ifu entry pointsApril 26, 1979 11:03 AMMake justReturn global.April 19, 1979 5:03 PMRemove calls to incTask/HoldFreq from enable/disableConditionalTask.April 18, 1979 3:24 PMRemove DisplayOff from postamble.April 18, 1979 11:11 AMRename chkTaskSim, chkHoldSim, simControl to incTaskFreq, incHoldFreq, makeHoldValue; clean upsetHold.April 17, 1979 10:51 PMSimControl now masks holdFreq and taskFreq & shifts them w/ constants defined in Postamble.April 11, 1979 3:49 PMAdd breakpoint to "done", and fix, again, a bug associated with task simulation. SetdefaultFlagsP (when postamble defines it) to force taskSim and holdSim.March 7, 1979 11:42 PMSet RBASE to defaultRegion upon entry to postamble. thnx to Roger.February 16, 1979 2:54 PMModify routines that read IM to invert the value returned in link if b1 from that value =1 (thisimplies the whole value was inverted).January 25, 1979 10:41 AMChange taskCirculate code to accommodate taskSim wakeups for task 10D, 12BJanuary 18, 1979 5:13 PMModify checkTaskNum to use the RM value, currentTaskNum, and modify taskCircInc to keep the copyin currentTaskNum.!gp +N bAq a _9 ]n\1\ ZF Y)W] V TS^ Rh PO`^ N# LXK_ I` H9 FER DZ BAR[ @Q >J= C ;A:] 8L 651_ 3) 2)0 /!-= ,* )'D & $! #!^  }[ uU 8G m0B e(` &  p q6  gp q1p q * r D]postamble.mcMay 18, 1981 2:09 PM %2January 15, 1979 1:25 PMadd justReturn, a subroutine that just returnsJanuary 9, 1979 12:07 PMbreakpoint on xorTaskSimXit to avoid midas bug%%*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++TABLE of CONTENTS, by order of Occurencedonelocation where diagnostics go when they are finished --gives control topostamble code the increments iterations, implements hold and task simulation and task circulation.reallyDoneLocation where postamble inits 2 rm locations then performs "GoTo BEGIN"restartReinit diagnostic state, then restart the diagnostic.incTaskFreqIncrement the task frequency counterincHoldFreqIncrement the hold frequency countermakeHoldValueCounstruct the "Hold&TaskSim" value from holdFreq and taskFreq, given thateach is enabled in FlagschkRunSimulatorsCause Hold or Task sim to happen, if requiredchkSimulatingReturn ALU#0 if some sort of simulating occuringtaskCirculateImplement task circulationincIterationsIncrement iterations counter (>16 bits)resetHoldReset Hold&TaskSim to its previous value.setHoldSet hold&task sim, notifying task simulator to do it.simInitEntry point for initialization in task simulator codetestTaskSimSubroutine that tests task simulatorfixSimRun Hold&TaskSim given current holdFreq and taskFreqreadByte3Return byte 3 of an IM locationgetIMRHReturn right half of an IM locationgetIMLHReturn left half of an IM locationputIMRHWrite Right half of an IM locationputIMLHWrite Left half aof an IM locationcheckFlagsReturn Alu result & t based on entry mask & current flagscheckTaskNumReturn "currentTaskNum" # expectedTaskNumnotifyTaskAwaken take in TtopLvlPostRtnCode that returns through mainPostRtnscopeTriggerGlobal subroutine that performs TIOA_0,TIOA_177777justReturnglobal subroutine that returns onlyrandomreturn random numbers, used w/ getRand[] macro.saveRandStateSave random number generator's staterestoreRandStateRestore old state to random number generatorgetRandVPart of random number linkagexorFlagsXor Flags w/ txorTaskCirctoggle flags.taskCircxorHoldSimtoggle flags.holdSimxorTaskSimtoggle flags.taskSimdisableConditionalTaskdisable conditional taskingenableConditionalTaskenable conditional taskingERRglobal label where ERROR macro gives controlIMdatabeginning of Postamble's FLAGS, et c.%*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++IM[ILC,0];%*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++This code presumes R0=0 and uses RSCR, RSCR2, T, and Q. It uses a number of other registers ina different RM region.When Postamble gets control of the processor at "Done", bits in "Flags", a word in IM determinewhich of Postamble's functions will occur when it runs. At the least, Postamble inrements at 32 bitnumber in IM called Iterations. If flags.taskSim is true, the task simulator started. The tasksimulator awakens after a software controllable number of clocks has occured. The microcode thatwakes up must reset the task simulator before it (the microcode) blocks to cause a task wakeup tooccur again. The first time a program runs (ie., the time before it gives control to "done") the tasksimulator and the hold simulator (discussed below) are inactive. Running the task simulator forcestask specific hardware functions to effect the state of the machine.When flags.holdSim is set, Postamble sets the hold simulator to a non-zero value. The 8 bit "holdvalue" enters a circulating shift register where occurence of a "1" bit at b[0] causes an externalhold. This exercises the hold hardware.The body of postamble contains a number of procedures for user programs, including routines to readand write IM, a routine to return a random number, and routines to initialize a task's pc and tonotify it.!gp +N bAqap q _^. ]K [:L Y)p( WqG Uc Tp qH S_pq5 R"p q$ Pp q$ Op qJ Ni M,pq- Kp q0 Jp q Isp q' H6pq) Fpq5 Epq5 D}p q$ C@pq4 Bpq @pq# ?pq" >Jpq" = pq" ;p q9 :p q) 9Tp q 8p q% 6p q2 5p q# 4^pq/ 3 p q$ 1pq, 0pq /hpq .*p q ,p q +p q *rpq )4pq 'pq, &pq% $L #j "-L _ _ d Ra a a f \c D  b c ( c D`   E3](postamble.mcMay 18, 1981 2:09 PM %3%*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++done:!gp +N bAqL apv _3hpostamble.mcMay 18, 1981 2:09 PM %4* June 17, 1979 4:49 PMPOSTAMBLE CONSTANTSset[randomTloc, 620];* random number generator may have to* be moved to "global" call location if extensively used!set[flagsLoc, 1000];mc[flagsLocC, flagsLoc];set[taskFreqLoc, 1400];mc[taskFreqLocC, taskFreqLoc];set[holdFreqLoc, 2000];mc[holdFreqLocC, holdFreqLoc];set[nextTaskLoc, 2400];mc[nextTaskLocC, nextTaskLoc];set[itrsLoc, 3000];mc[itrsLocC, itrsLoc];* holdValueLoc defined in preamble!set[preBeginLoc, 4000];mc[preBeginLocC, preBeginLoc];set[initTloc, 4400];mc[initTlocC, initTloc];ifdef[simInitLocC,,mc[simInitLocC, initTloc] ];* define the bmux constant for the*address of the task simulator code. If its already been defined, leave it as is.* flags.taskSim defined in preamble!* flags.holdSim defined in preamble!* flags.simulating defined in preamble!mc[flags.testTasks, b13];* than 8 flags (since READIM rtns a BYTE)mc[flags.conditional, flags.conditionalP];* allow simulating iff flags.simulating* AND flags.conditionOKmc[flags.conditionOK, flags.conditionOKp];* enable conditional simulating%*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++This portion of the kernel code encapsulates the microdiagnostic with an outer loop. This outerloop has several features that it implements:task simulationhold simulationtask switchingTask simulation refers to the taskSim register in the hardware. It is 4 bits wide; taskSim[0] enablesthe task simulator and taskSim[1:3] form a counter that determines the number of cycles before a taskwakeup occurs.Hold simulation is similar: holdSim is an 8-bit recirculating shift register in which the presence ofa 1 in bit 7 causes HOLD two instructions later.Task switching determines which task will run the microdiagnostics.These features are controlled by the flags word in IM. If the appropriate bits are set to one, theassociated feature will function. The bits are defined above (flags.taskSim, flags.holdSim,flags.testTasks).%*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++rmRegion[rmForKernelRtn];knowRbase[rmForKernelRtn];rv[setHoldRtn, 0];rv[oldt, 0];* save t, rscr, rscr2, rtn link for resetHoldrv[oldrscr, 0];rv[oldrscr2, 0];rv[resetHoldRtn, 0];rv[xorFlagsRtn,0];rv[flagSubrsRtn, 0];rv[mainPostRtn, 0];knowRbase[rm2ForKernelRtn];* defined in preamble because of macros* that reference randV, randXknowRbase[defaultRegion];!gp +N bAq+_+% ^9[:+Y+X+W+VD+ U!S+R+P/0Z" NP LX" K" I%H+)Gb*-'+F$D*- BlL@[_ ?-=<;e 8e 7e 6o 3e 20 0;C -b ,[ +E *L&%|#! +- H R+'  n DVpostamble.mcMay 18, 1981 2:09 PM %5* February 1, 1980 6:24 PMPOSTAMBLE CONTROL CODERBASE _ rbase[defaultRegion], breakpoint;* set RBASE incase user's is different.call[incTaskFreq];call[incHoldFreq];call[makeHoldValue];call[taskCirculate];call[incIterations];call[checkFlags]t_flags.testTasks;* bookkeeping is done. switch tasks if requiredskpif[ALU#0];branch[preBegin];* xit if not running other taskstaskCircInit:* now that bookkeeping is done, switch tasks ifrequirednoop;* for placement.call[checkTaskNum];rscr _ t;* rscr _ nextTaskt _ preBeginLocC;* link _ t _ preBeginLocsubroutine;taskCirc:zeroHold[rscr2];* turn off hold-task sim during LdTpc_, wakeuplink _ t;t _ rscr;top level;ldTPC _ t;* tpc[nextTask] _ preBeginLoccall[notifyTask];* wakeup nextTask: task num in tset[xtask, 1];block;set[xtask, 0];preBegin: noop,at[preBeginLoc];call[chkRunSimulators];* check for simulator conditions and run if requiredreallyDone:* LOOP TO BEGINt_RSCR_a1;goto[begin], RSCR2_t;restart:* restart diagnostics from "initial" staterndm0 _ t-t;* restart random number generatorrandX _ t-t;rscr _ t-t;* restart hold/task simulator stuffcall[putIMRH], t _ holdFreqLocC;rscr _ t-t;call[putIMRH], t_taskFreqLocC;rscr _ t-t;call[putIMRH], t _ holdValueLocC;rscr _ t-t;* restart iterations countcall[putIMRH], t _ itrsLocC;branch[restartDiagnostic];* special entry point so each diagnostic* can perform whatever special initialization that it wants to perform!gp +N bAq+_)+'^]K\ZYW"+/U T+ R"p +q/ PO+NiM,+J+Is H6pFq+.ED}C@ B +@+ ? >J = :pq+9T+4 6p +p5qx 4^x 1p+q*0 +!/h , +#+*r )4' &!$> +# +( HF BJ#postamble.mcMay 18, 1981 2:09 PM %6* January 18, 1978 1:51 PM%*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++This code sets the taskSim value with the next value if flags.testTasks is true. Otherwise 0 isused.IF flags.taskSim THENBEGIN-- when hardware counts to 17 it awakenstaskFreq _ (taskFreq + 1) or 10b;-- simTaskIF taskFreq > 15 THEN taskFreq _ 12;-- always wait min=2 cyclesENDELSE taskFreq _ 0;IF flags.holdSim THENBEGINholdFreq _ holdFreq+1;IF holdFreq >376 THEN holdFreq _ 0;END;ELSE holdFreq _ 0;%*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++incTaskFreq: subroutine;t _ link;mainPostRtn _ t;top level;call[checkFlags], t_flags.taskSim;* see if taskSim enabledbranch[writeTaskSim, alu=0],t_r0;* use 0 if not enabledt_taskFreqLocC;* incrment next taskSimcall[readByte3];t_(r1)+(t);t-(156C);* Use [1..156). 156 => max wait,skpif[alu<0];* 1 = > min wait. Beware infinite hold!t_r1;* see discussion at simInit, simSet codenoop;writeTaskSim:rscr _ t;call[putIMRH], t_taskFreqLocC;* update IM locationtaskSimRtn:goto[topLvlPostRtn];incHoldFreq: subroutine;* see if holdSim enabledt _ link;mainPostRtn _ t;top level;call[checkFlags], t_flags.holdSim;branch[noHoldSim, alu=0],t_r0;* use zero if hold not enabledt_holdFreqLocC;call[readByte3];t_t+(r1);t-(377c);* IF holdFreq >376skpif[alu<0];t_r1;* THEN holdFreq _ 1;noop;* here for placementnoHoldSim:rscr _ t;* rewrite IMcall[putIMRH], t _ holdFreqLocC;holdSimRtn:goto[topLvlPostRtn];!gp +N bAq _L]_ \w YX+(W!+ VD$+US RQNPN#MK I L Gp q FEQD A"+@[!+?+=< ;e+:' +'8+(7 51p q32+ 0;p .q +p q +*r)4' %|"$>+#! H+ ++ Rpq+  \p q DIVpostamble.mcMay 18, 1981 2:09 PM %7* April 17, 1979 10:51 PM%*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++This code actually controls the task and hold loading. It is responsible for initializing T for thetask at simTaskLevel, and it is responsible for initializing HOLD.The code proceeds by constructing the current value to be loaded into hold and placing it in IMat holdValueLoc. Kernel loads HOLD as its last act before looping to BEGIN.hold&tasksim_ requires hold value in left byte, task counter value in right byte.%*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++makeHoldValue: subroutine;* construct holdValuesaveReturn[mainPostRtn];call[chkSimulating];skpif[alu#0];branch[simCtrl0];t_holdFreqLocC;* rscr2 _ holdFreqcall[readByte3], t_holdFreqLocC;rscr2 _ t;call[readByte3], t_taskFreqLocC;* t _ taskFreqt_lsh[t, sim.taskShift];* position hold and task valuest_t and (sim.taskMask);rscr2 _ lsh[rscr2, sim.holdShift];rscr2 _ (rscr2) and (sim.holdMask);rscr2 _ (rscr2) and (377c);rscr2 _ (t) + (rscr2);* taskFreq,,holdFreqrscr _ rscr2;% now, save combined taskSim, holdSim values in IM. Last thing done before exiting postamble is to setHOLD if simulating.%simCtrlWHold:* may branch here from simCtrl0call[putIMRH], t _ holdValueLocC;* write holdValue into holdValueLocbranch[simCtrlRtn];simCtrl0:branch[simCtrlWHold], rscr _ t-t;* write zero into holdValueLocsimCtrlRtn:goto[topLvlPostRtn];!gp +N bAq aL ^c ]B[:_ YK WQ VDL Up q +SQNP NLX+KI Gb+ D+CBl"A.#?=v+<8 : 9e 8 7B 6p +q4!+#3 1p/q!+ -Vp ,q )D>&postamble.mcMay 18, 1981 2:09 PM %8* September 19, 1979 9:09 PM%*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++IF chkSimulating[] THEN fixSimulator[];* cause hold or task simulator to run, if required%*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++chkRunSimulators: subroutine;saveReturn[chkRunSimRtn];call[chkSimulating];dblBranch[chkRunsimXit, chkRunSimDoIt, alu=0];chkRunSimDoIt:* run the simulatornoop;call[fixSim];noop;chkRunSimXit:returnUsing[chkRunSimRtn];* September 19, 1979 9:19 PM%*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++chkSimulating: PROCEDURE RETURNS[weAreSimulating: BOOLEAN] =BEGINweAreSimulating _ FALSE;IF flags.Simulating THENIF ~(flags.Conditional) OR (flags.Conditional AND flags.ConditionOK) THENweAreSimulating _ TRUE;END;%*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++chkSimulating: subroutine;saveReturn[chkSimulatingRtn];call[checkFlags], t_flags.simulating;* check for taskSim OR holdSimbranch[chkSimNo, alu=0];t _ flags.conditional;* We're simulating. checkcall[checkFlags], t _ flags.conditional;dblbranch[chkSimYes, chkSimCond, alu=0];chkSimCond:* conditional simulation. check for okt _ flags.conditionOK;call[checkFlags];skpif[alu=0];branch[chkSimYes];* conditionOK is set, do it!branch[chkSimNo];chkSimYes:* run the simulatort _ (r0)+1;* rtn w/ alu#0chkSimRtn:returnAndBranch[chkSimulatingRtn, t];chkSimNo:branch[chkSimRtn], t _ r0;* rtn w/ alu=0!gp +N bAq _L^' \w2 [:L Wpq VUpT3. Rp +qQPz O= Lp Kq G FL EQp q.DBA@[I?= ;L :p q 9T8%+65+4^(3 ( 1p +q&0/h.* ,++ *rp +q)4 + 'p &q% %|p$>q+  "9E-postamble.mcMay 18, 1981 2:09 PM %9* January 25, 1979 10:44 AM%This code controls task circulation for the diagnostics: when flags.testTasks is set, postamblecauses successive tasks to execute the diagnostic code when the current task has completed. Ifflags.taskSim is true the diagnostic is using the taskSimulator to periodically awaken the simulatortask; consequently, that task (simTaskLevel) must not execute the diagnostic -- otherwise theadvantage of the simulator for testing the effects of task switching will be lost.IF ~flags.testTasks THEN RETURN;temp _ getTaskNum[] + 1;-- increment the current numberIF flags.taskSim THENIF temp = simTaskLevel THEN temp _ temp+1;IF temp > maxTaskLevel THEN temp _ 0;putTaskNum[temp];-- remember it in IM%taskCirculate: subroutine;saveReturn[mainPostRtn];call[checkFlags], t _ flags.testTasks;branch[taskCircRtn, ALU=0];* Don't bother if not task circulating.noop;call[checkTaskNum];* Increment the current task number.t _ t + (r1);* Current value came back in t.q _ t;* Remember incremented value in Q.call[checkFlags], t _ flags.taskSim;skpif[ALU#0], t _ q;* Now, see if using task simulator.branch[taskCircChk];* If not task simulating, check for max size.t - (simTaskLevelC);* Since we're task simulating, avoidskpif[ALU#0];* we must avoid simTaskLevel.t _ t+1;* Increment over simTask if required.noop;taskCircChk:t - (20C);* See if tasknum is too big.skpif[ALU#0];t _ t-t;* We wraparound to zero.currentTaskNum _ t;* keep it in both RM and IMrscr _ t;call[putIMRH], t _ nextTaskLocC;noop;* for placementtaskCircRtn:goto[topLvlPostRtn];!gp +N bAq a_9_ ]_ \d [r q2 ZCR Xx W;+ UT3* Rh% Q++ O Np q MrL5&J+'IG?+$F +D+"BI$A +#?+-=S+$< +:+%9 7p 5q +4 3g+0+/.q-3+ *p ){q8 (DI?postamble.mcMay 18, 1981 2:09 PM %10* January 18, 1978 1:57 PMincIterations: subroutine;* maintain double precision count at incItrsLoct _ link;mainPostRtn _ t;top level;call[getIMRH], t _ itrsLocC;* increment iteration count at tableloc+1rscr _ (t)+1;rscr2 _ rscr;* copy new itrsrscr2 _ (t) #(rscr);* see if new b0 # old b0rscr2 _ (rscr2) AND (b0);skpif[alu#0];branch[incItrs2], q _ r0;* new b0 = old b0. remember in q and writet and (B0);* see if b0 went from 0 to 1 or 1 to 0 (carry)skpif[alu=0], q_r0;* skpif old b0 = 0q _ r1;incItrs2:call[putIMRH], t _ itrsLocC;* T = addr, rscr = valuerscr2 _ q;branch[incItrsRtn,alu=0];* goto incItrsRtn if no carryincItersHi16:link _ t;* read hi byte of hi 16 bitscall[getIMLH];rscr _ (t)+1;call[putIMLH], t _ itrsLocC;* T = addr, rscr = valuenoop;* help the instruction placer.incItrsRtn:goto[topLvlPostRtn];!gp +N bAq _p q +/^]K\ Y+)XU U +T+R"P O+*Ni +.M,+K JpH6q+F E+ C@p qB+@ ? >J+= + :p 9TqT 7?0postamble.mcMay 18, 1981 2:09 PM %11* March 20, 1978 1:51 PM KERNEL - COMMON SUBROUTINESresetHold: subroutine;* special subroutine called by IM manipulating* code. This subr saves t, rscr, rscr2 and causes hold to be initialized to the value in* holdValueLocC. It restores the RM and T values before returning.oldT _ t;t _ link;resetHoldRtn _ t;top level;t _ rscr;oldrscr _ t;t _ rscr2;oldrscr2 _ t;* link, t, rscr, and rscr2 are now saved.t _ HoldValueLocC;* READ RIGHT HALF, HoldValueLocCsubroutine;link _ t;top level;readim[3];* read low order bytesubroutine;t _ link;* low byte in tt and (b1);* see if the data is inverted. If so, b1 willskpif[ALU=0];* 1, and we must reinvert the data.t _ not(t);t _ t and (getIMmask);* isolate the byterscr _ HoldValueLocC;subroutine;link _ rscr;top level;readim[2];* read hi order bytesubroutine;rscr2 _ link;* hi byte in rscr2(rscr2) and (b1);* see if the data is inverted. If so, b1 willskpif[ALU=0];* 1, and we must reinvert the data.rscr2 _ not(rscr2);rscr2 _ (rscr2) and (getIMmask);* isolate the bytetop level;noop;rscr2 _ lsh[rscr2, 10];* left shift hi bytet _ t and (377C);* isolate low bytet _ t OR (rscr2);* add hi bytecall[setHold];knowRbase[rmForKernelRtn];* restore link, t, rscr, rscr2, then returnRBASE _ rbase[rmForKernelRtn];t _ oldrscr;rscr _ t;t _ oldrscr2;rscr2 _ t;subroutine;link _ resetHoldRtn;return, t _ oldt, RBASE _ rbase[defaultRegion];!gp +N bAq+ _p q +. ^Y ]KB\ZYXU WU T S_ +)P+O NiM, K +J Is+H6 +-F +#E D}+B@ ? >J = +; : +9T+-8 +#65+3 10+/h+.*+ , *r++)4' &%| $> # ! / %>Hpostamble.mcMay 18, 1981 2:09 PM %12* June 23, 1978 10:22 AMsetHold: subroutine;* ENTER w/ T = HOLD value* clobber t, rscr, rscr2zeroHold[rscr2];* kill hold-task sim before polyphas instrs xqtrscr2 _ q;* SAVE Qq _ t;* save hold value, then save rtn linkt _ link;setHoldRtn _ t;taskingon;t _ simInitLocC;* defined w/ postamble constants OR in* some user specific code (eg., memSubrsA where RM values are defined). This* convention allows users to specify their own code to run when the simulator task runs.link _ t;* cause task taskSimLevel to puttop level;ldTPC _ simTaskLevelC;* proper hold value in T for refreshnotify[simTaskLevel];* after task switch occurs. Remember* taskSim is a counter. refresh it!noop;* wakeup will happen soonnoop;rbase _ RBASE[rmForKernelRtn];t_ setHoldRtn, rbase _ RBASE[defaultRegion];Q _ rscr2;* restore Qsubroutine;link _ t;return;* This code actually causes T to be set properly and branches to the code that sets HOLD.set[xtask, 1];simInit:t _ q,at[initTloc];simSet:hold&tasksim_t;* T init'd at simInitnoop;* this noop doesn't cause hold to countsimBlock:branch[simSet], block;* count hold, block%Note: if t = 14, then hold = 16 when the simulator blocks. The preempted task will execute oneinstruction, then the task simulator will waken the simulator task.%set[xtask, 0];* November 6, 1978 12:07 PMMIDAS SUBROUTINE for testing the task simulatortestTaskSim: subroutine;rscr _ link;* save return in case we later want ittop level;t _ lsh[t, 10];* ENTER w/ T = task sim val NOT shiftedq _ t;* simInit expects q = hold valuesubroutine;t _ initTlocC;link _ t;top level;LDTPC _ simTaskLevelC;notify[simTaskLevel];noop;t _ t - t;* t _ 0branch[., alu=0], t_t;* this shouldn't changetestTaskErr:branch[.], breakpoint;subroutine;link _ rscr;return;fixSim: subroutine;t_link;* save return in fixSimRtn!gp +N bAq apq + _]K+/\ +Z+%YXUU T+&S_LR"XP+O Ni+$M,+$+K#J+IsH6F,E + D} C@B ?Y= :pq9T+ 8pq6+5+' 4^pq3 + 1 0^ /hC .*+ )4+/ 'p q & +&%| $>+'#+ H   R +\+ p qf )   ppq  3+( ?](postamble.mcMay 18, 1981 2:09 PM %13fixSimRtn _ t;top level;call[makeHoldValue];* compose holdValue and set hardwarecall[getIMRH], t _ holdValueLocC;call[setHold];returnUsing[fixSimRtn];zeroHoldTRscr: subroutine;t_4c;rscr_a0;zeroHoldTRscrL:Hold&TaskSim_rscr;t_t-1, Hold&TaskSim_rscr;loopUntil[alu<0, zeroHoldTRscrL];return;!gp +NbAq a ^+$]K!\ Y Wp q UT S_p qR"PO!NiD K8(@Npostamble.mcMay 18, 1981 2:09 PM %14* January 18, 1979 5:18 PM* READ/WRITE IM%The subroutines that read and write IM turn OFF hold simulator before touching IM. Before theyreturn to the caller, the invoke "resetHold" to reset the hold register to the contents of"holdValueLoc". By convention, the current value of the two simulator registers is kept in"holdValueLoc" for this express purpose. Zeroing and resetting hold is done because of hardwarerestrictions: hold and polyphase instructions don't mix.ReadIM[] instructions are followed by a mask operation with getIMmask because of the interactionbetween DWATCH (Midas facility) and LINK[0].%readByte3: subroutine;* CLOBBER T, RSCR!zeroHold[rscr];rscr _ link;* this routine assumes t points to IMlink _ t;* it reads the least significan byte in IMtop level;* read byte 3readim[3];subroutine;t_link;* t = byte3t and (b1);* see if the data is inverted. If so, b1 willskpif[ALU=0];* 1, and we must reinvert the data.t _ not(t);t _ t and (getIMmask);* isolate the bytetop level;* reset value of hold and returncall[resetHold];subroutine;link _ rscr;return;* return w/ byte in tgetIMRH: subroutine, global;* CLOBBER T, RSCR, RSCR2!zeroHold[rscr];* disable task/hold Sim before touching IMrscr _ link;* ENTER w/ T pointing to IM locationlink _ t;top level;* read hi byte of right halfreadim[2];subroutine;rscr2 _ link;* rscr2 = high byte(rscr2) and (b1);* see if the data is inverted. If so, b1 willskpif[ALU=0];* 1, and we must reinvert the data.rscr2 _ not(rscr2);rscr2 _ (rscr2) and (getIMmask);* isolate the bytelink _ t;* read low byte of right halftop level;readim[3];subroutine;t _ link;* t = low byte, rscr2 = hi bytet and (b1);* see if the data is inverted. If so, b1 willskpif[ALU=0];* 1, and we must reinvert the data.t _ not(t);t _ t and (getIMmask);* isolate the byterscr2 _ lsh[rscr2, 10];t _ t + (rscr2);* RETURN w/ T = IMRHtop level;call[resetHold];subroutine;link _ rscr;return;!gp +N bAq+ a_^ ^Z ]KZ \_ Z8XU` W, U S_pq +R"O +%Ni+*K + J Is H6+ F +-E +#D} C@+@ +?>J = ;+ 9Tpq+8+*5 +$4^1 +0 /h .* +,+-+ +#*r)4+&+%| $> # !+ +-H +# +R+ \   CDWpostamble.mcMay 18, 1981 2:09 PM %15getIMLH: subroutine, global;* CLOBBER T, RSCR, RSCR2!zeroHold[rscr];* disable task/hold Sim before touching IMrscr _ link;* ENTER w/ T pointing to IM locationlink _ t;top level;* read hi byte of left halfreadim[0];subroutine;rscr2 _ link;* rscr2 = hi byte(rscr2) and (b1);* see if the data is inverted. If so, b1 willskpif[ALU=0];* 1, and we must reinvert the data.rscr2 _ not(rscr2);rscr2 _ (rscr2) and (getIMmask);* isolate the bytelink _ t;* read low byte of left halftop level;readim[1];subroutine;* CLOBBER T, RSCR, RSCR2!t _ link;* t = low byte, rscr2 = hi bytet and (b1);* see if the data is inverted. If so, b1 willskpif[ALU=0];* 1, and we must reinvert the data.t _ not(t);t _ t and (getIMmask);* isolate the byterscr2 _ lsh[rscr2, 10];t _ t + (rscr2);* RETURN w/ T = IMLHtop level;call[resetHold];subroutine;link _ rscr;return;putIMRH: subroutine, global;* T = addr, RSCR = value, clobberr RSCR2rscr2 _ link;link _ t;zeroHold[t];* disable task/hold Sim before touching IMtop level;t _ rscr;IMRHB'POK _ t;call[resetHold];subroutine;link _ rscr2;return;putIMLH: subroutine, global;* T = addr, RSCR = value, Clobber RSCR2rscr2 _ rscr;rscr _ link;link _ t;zeroHold[t];* disable task/hold Sim before touching IMtop level;t _ rscr2;IMLHR0'POK _ t;call[resetHold];subroutine;link _ rscr;return;!gp +N bAq+a+*^ +$]KZ +Y XU W +U+-T +#S_R"+O+Ni M, K +J+Is +-H6 +#F E+C@B+? >J= ; : 8pq+(6 53 +*0 /h.* +*r )4 ' %|pq+'$> # !H +*  R \ 6 >4UMpostamble.mcMay 18, 1981 2:09 PM %16checkFlags: subroutine, global;* CLOBBER T, RSCR, RSCR2rscr _ link;* this routine assumes t has a bit maskzeroHold[rscr2];* disable task/hold Sim before touching IMrscr2 _ flagsLocC;* it reads the flags word in IMlink _ rscr2;* and performs t_tANDflagtop level;readim[3];subroutine;rscr2 _ link;(rscr2) and (b1);* see if the data is inverted. If so, b1 willskpif[ALU=0];* 1, and we must reinvert the data.rscr2 _ not(rscr2);rscr2 _ (rscr2) and (getIMmask);* isolate the bytetop level;call[resetHold];subroutine;link _ rscr;return, t _ t AND(rscr2);* returnee can do alu=0 fast branchcheckTaskNum: subroutine;* enter: T=expected task num,rscr_t, RBASE _ rbase[currentTaskNum];* return: T=current task num, branch conditiont _ currentTaskNum, RBASE _ rbase[defaultRegion];* clobber rscr, rscr2return, t#(rscr);* rtn w/ branch condition, t=current task* number, rscr = expected task number.!gp +N bA q+a +'^+*\+Z +Y XU W U T+-S_ +#R"P+Ni M,K J Is+# Fp q +E&+.D}12B+) @& ?d>(postamble.mcMay 18, 1981 2:09 PM %17* August 1, 1979 3:30 PMother, miscellaneous subroutinesnotifyTask: subroutine;rscr_ link;bigBDispatch_t;top level;branch[dispatchTbl];set[nloc, 6600];dispatchTbl:branch[nxit], notify[0],at[nloc,0];branch[nxit], notify[1],at[nloc,1];branch[nxit], notify[2],at[nloc,2];branch[nxit], notify[3],at[nloc,3];branch[nxit], notify[4],at[nloc,4];branch[nxit], notify[5],at[nloc,5];branch[nxit], notify[6],at[nloc,6];branch[nxit], notify[7],at[nloc,7];branch[nxit], notify[10],at[nloc,10];branch[nxit], notify[11],at[nloc,11];branch[nxit], notify[12],at[nloc,12];branch[nxit], notify[13],at[nloc,13];branch[nxit], notify[14],at[nloc,14];branch[nxit], notify[15],at[nloc,15];branch[nxit], notify[16],at[nloc,16];branch[nxit], notify[17],at[nloc,17];branch[.], breakpoint,at[nloc,20];branch[.], breakpoint,at[nloc,21];subroutine;nxit:link _ rscr;return;topLvlPostRtn:RBASE _ rbase[mainPostRtn];link _ mainPostRtn;return, RBASE _ rbase[defaultRegion];scopeTrigger: subroutine;t _ a0, global;TIOA _ t, T_a1;return, TIOA_t;justReturn: * this subroutine ONLY RETURNS. Calling justReturn forces the instructionreturn, global;* (logically) after the call to occur in thephysically* next location after the call. This is a way of reserving a noop that can ALWAYS be* safely patched with a "call".!gp +N bAq+ ap q _ ^]K \ Z Y XU+ W+ U+ T+ S_+ R"+ P+ O+ Ni+ M,+ K+ J+ Is+ H6+ F+ E+ D}+ C@+ @ ?pq>J =  :p 9Tq86% 4^p q 3 10 .*p qM,+- + *rU )4( '>@7postamble.mcMay 18, 1981 2:09 PM %18* April 24, 1978 6:51 PMknowRbase[randomRM];random:T_ LSH[rndm0, 11];* T_ 2^9 * RT_ T+(rndm0);* (2^9 + 2^0)* RT_ LSH[T, 2];* (2^11 + 2^2)* RT_ T+(rndm0);* (2^11 + 2^2 + 2^0)* RT_ T+(33000C);T_ rndm0_ T+(31C), Return;* +13849 (= 33031B)goto[random1], t _ rndm0, RBASE _ rbase[randV],at[randomTloc,0];knowRbase[randomRM];goto[random1], t _ rndm1, RBASE _ rbase[randV],at[randomTloc,1];knowRbase[randomRM];goto[random1], t _ rndm2, RBASE _ rbase[randV],at[randomTloc,2];knowRbase[randomRM];goto[random1], t _ rndm3, RBASE _ rbase[randV],at[randomTloc,3];knowRbase[randomRM];goto[random1], t _ rndm4, RBASE _ rbase[randV],at[randomTloc,4];knowRbase[randomRM];goto[random1], t _ rndm5, RBASE _ rbase[randV],at[randomTloc,5];knowRbase[randomRM];goto[random1], t _ rndm6, RBASE _ rbase[randV],at[randomTloc,6];knowRbase[randomRM];goto[random1], t _ rndm7, RBASE _ rbase[randV],at[randomTloc,7];random1:return, t _ randV _ (randV)+t;knowRbase[defaultRegion];* code below modified to save/restore/use rndm0 rather than randV.saveRandState: subroutine;* remember random number seedRBASE _ rbase[randV];oldRandV _ rndm0;oldRandX _ randX;return, RBASE _ rbase[defaultRegion];restoreRandState: subroutine;* restore remembered random number seedRBASE _ rbase[randV];rndm0 _ oldRandV;randX _ oldRandX;return, RBASE _ rbase[defaultRegion];getRandV: subroutine;RBASE _ rbase[randV];RETURN, t _ rndm0, RBASE _ rbase[defaultRegion];setRandV: subroutine;RETURN, rndm0_ t;cycleRandV: subroutine;RBASE_ rbase[randV];rndm0_ (rndm0)+1, RETURN, RBASE_ rbase[defaultRegion];!gp +N bAqa _p^q0Z ]K 0Z\ 0ZZ 0ZY XU+U/0Z=pT/0Z=pS_/0Z=pR"/0Z=pP/0Z=pO/0Z=pNi/0Z=pM,/0Z JpIsqH6 EB D}p q +C@B@?% = pq +';:9T8% 5pq 4^3 0 1pq 0 /hp q .*,62 *O?)=postamble.mcMay 18, 1981 2:09 PM %19* January 20, 1978 3:04 PM'FLAGS' manipulating codexorFlags: subroutine;* T = value to XOR into flags* CLOBBER RSCR, RSCR2, Trscr2 _ t;* save bitst _ link;xorFlagsRtn _ t;top level;t _ flagsLocC;call[readByte3];t _ t # (rscr2);* xor new bitsrscr _ t;* put new value back into IMcall[putIMRH], t _ flagsLocC;returnUsing[xorFlagsRtn];xorTaskCirc: subroutine;* xor the flags.testTasks bit in FLAGS* CLOBBER RSCR, RSCR2, TsaveReturn[flagSubrsRtn];t _ flags.testTasks;call[xorFlags];noop;returnUsing[flagSubrsRtn];xorHoldSim: subroutine;* xor the flags.holdSim bit in FLAGSsaveReturn[flagSubrsRtn];t _ flags.holdSim;call[xorFlags];rscr_a0;* whether off or on, clear holdFreqLoccall[putIMRH], t _ holdFreqLocC;* holdFreq _ 0call[fixSim];xorHoldSimXit:noop, breakpoint;returnUsing[flagSubrsRtn];xorTaskSim: subroutine;* xor the flags.taskSim bit in FLAGSsaveReturn[flagSubrsRtn];t _ flags.taskSim;call[xorFlags];rscr_a0;* whether off or on, clear taskFreqLoccall[putIMRH], t _ taskFreqLocC;* taskFreq _ 0call[fixSim];* fix the holdValueLoc, set hardwarexorTaskSimXit:breakpoint, noop;returnUsing[flagSubrsRtn];top level;* June 22, 1978 10:15 AM%This code supports the conditional simulation mechanism. disableConditionalTask is a subroutinethat requires no parameters. It clears flags.conditionOK and sets flags.conditional. It also turns offthe hold simulator.enableConditionalTask sets flags.conditionOK and flags.conditional, then it calls makeHoldValue toforce the hold simulator into working.%disableConditionalTask: subroutine;saveReturn[flagSubrsRtn];call[checkFlags], t _ (r0)-1;* use mask = -1 to force a read of all the bitsrscr _ not (flags.conditionOK);rscr _ t and (rscr);rscr _ (rscr) or (flags.conditional);rscr _ (rscr) and (377C);* isolate lower byte!gp +N bAq+p _q + ^]K + \ZY W UT+ R"+PNi Kp q +& JIsH6FEC@ @p q +$?>J= :+&9T+ 6 5p 4^q1 /hp q +$.*,+)4+&'+ %| +$ #p !q H  R9pq f  \b &  pq f)+/   p% 3+ E3] postamble.mcMay 18, 1981 2:09 PM %20call[putIMRH], t _ flagsLocC;call[makeHoldValue];* compose a new hold value from task and* hold simulator sub valuescall[zeroHoldTRscr];* stop holdcall[resetHold];* jam the hold register w/ holdValuereturnUsing[flagSubrsRtn];enableConditionalTask: subroutine;saveReturn[flagSubrsRtn];call[checkFlags], t _ (r0)-1;* use mask = -1 to force a read of all the bitsnoop;* make placement easierrscr _ t or (flags.conditionOK);rscr _ (rscr) or (flags.conditional);noop;* make placement easiercall[putIMRH], t _ flagsLocC;* write the new valuecall[makeHoldValue];* compose a new hold value from task and* hold simulator sub valuescall[zeroHoldTRscr];* stop holdcall[resetHold];* jam the hold register w/ holdValuereturnUsing[flagSubrsRtn];top level;* ERRORs come here!branch[err];SET[ERRLOC,400];ERR:BREAKPOINT,GLOBAL, AT[ERRLOC];GOTO[.],BREAKPOINT, AT[ERRLOC,1];GOTO[.], AT[ERRLOC,2];* DATA HELD IN IMIMdata:ifdef[defaultFlagsP,,set[defaultFlagsP,add[flags.taskSim!, flags.holdSim!]]];*define default flags if undefineddata[(Flags: lh[0] rh[defaultFlagsP], at[flagsLoc])];* CONTROL FLAGSdata[(taskFreq: lh[0] rh[0], at[taskFreqLoc])];* task sim valuedata[(holdFreq: lh[0] rh[0], at[holdFreqLoc])];* hold sim valuedata[(nextTask: lh[0] rh[0], at[nextTaskLoc])];* next task valuedata[(holdValue: lh[0] rh[0], at[holdValueLoc])];* current hold valuedata[(iterations: lh[0] rh[0], at[itrsLoc])];* iteration countpostDone: noop;!gp +NbAq_+(+^]K+ \+$Z XUpq WU+/T+S_R"%P+O+M,+(+KJ+ Is+$H6F C@pBq @ ?pq>J= !; 9Tp 6q5MK 4^!15C0/3/h/3.*/3,1;+-3 )4pq )B>MODEL 1: preamble.mcMay 18, 1981 1:29 PM%1%May 18, 1981 1:29 PMFix getRandom to use a new random number generatorFebruary 5, 1981 1:20 PMAdapt to current d1lang.mcSeptember 19, 1979 10:42 AMTry undoing zeroHold fix -- found a different bug that probably accounts for the behavior.September 18, 1979 5:55 PMTry to make zeroHold more reliable: apparently 3 in a row is not enough.June 17, 1979 5:11 PMChange holdValueLoc to accommodate ifu entry pointsApril 17, 1979 10:45 PMAdd sim.holdMask, sim.taskMask, sim.holdShift, sim.taskShift.January 25, 1979 11:05 AMChange simTaskLevel to 12B.January 18, 1979 5:10 PMAdd currentTaskNum.%TITLE[PREAMBLE];%NAMING CONVENTIONS:LABELS BEGIN W/ THE OPERATION BEING TESTED:Aplus1cntFcnaluLT0lsh => Left shiftrsh => Right shiftlcy => Left Cyclercy => Right CycleRegister Read/write tests are suffixed with RW:cntRWshcRWLOOP LABELS ARE SUFFIXED AS INNER (IL) AND OUTER(OL) LOOPS (L).cntFcnIL* INNER LOOPcntFcnOL* OUTER LOOPcntFcnXITIL* LABEL FOR EXITING INNER LOOPcntFcnXITOL* LABEL FOR EXITING OUTER LOOPAplus1L* ONLY LOOP%RMREGION[DEFAULTREGION];rv[r0,0];rv[r1,1];rv[rm1,177777];rv[r01,52525];rv[r10,125252];rv[rhigh1,100000];rv[rscr,0];rv[rscr2,0];rv[rscr3,0];rv[rscr4,0];rv[stackPAddr, 0];rv[stackPTopBits, 0];rv[klink, 0];rv[hack0,0];rv[hack1, 0];rv[hack2,0];rvrel[rmx0, 0];rvrel[rmx1, 1];rvrel[rmx2, 2];rvrel[rmx3, 3];rvrel[rmx4, 4];rvrel[rmx5, 5];rvrel[rmx6, 6];rvrel[rmx7, 7];rvrel[rmx10, 10];* Constants from FFnsp[PNB0,100000];nsp[PNB1,40000];nsp[PNB2,20000];nsp[PNB3,10000];nsp[PNB4,4000];nsp[PNB5,2000];nsp[PNB6,1000];nsp[PNB7,400];nsp[PNB8,200];nsp[PNB9,100];nsp[PNB10,40];nsp[PNB11,20];nsp[PNB12,10];nsp[PNB13,4];nsp[PNB14,2];nsp[PNB15,1];mc[B0,100000];mc[B1,40000];mc[B2,20000];mc[B3,10000];mc[B4,4000];mc[B5,2000];mc[B6,1000];mc[B7,400];mc[B8,200];mc[B9,100];mc[B10,40];mc[B11,20];mc[B12,10];mc[B13,4];mc[B14,2];mc[B15,1];mc[NB0,PNB0];mc[NB1,PNB1];mc[NB2,PNB2];mc[NB3,PNB3];mc[NB4,PNB4];mc[NB5,PNB5];mc[NB6,PNB6];mc[NB7,PNB7];mc[NB8,PNB8];mc[NB9,PNB9];mc[NB10,PNB10];mc[NB11,PNB11];mc[NB12,PNB12];mc[NB13,PNB13];mc[NB14,PNB14];mc[NB15,PNB15];mc[CM1,177777];mc[C77400,77400]; mc[C377,377];mc[CM2,-2];mc[getIMmask, 377];* isolate IM data after getIm[]!m[noop, BRANCH[.+1]];m[skip, BRANCH[.+2]];m[error, ILC[(BRANCH[ERR])]];m[skiperr, ILC[(BRANCH[.+2])] ILC[(BRANCH[ERR])]];m[skpif, BRGO@[TS@] JMP@[.+2,#1,#2] ];m[skpUnless, BRGO@[TS@] DBL@[.+1,.+2,#1,#2] ];m[loopChk, BRGO@[TS@] DBL@[#1,.+1,#2,#3] ];m[loopUntil, BRGO@[TS@] DBL@[.+1,#2,#1,#3]];* if #1 then goto .+1 else goto #2m[loopWhile, BRGO@[TS@] DBL@[#2,.+1,#1,#3]];* if #1 then goto #2 else goto .+1gp->zN bAq a_2 ^]K \ZZ YXUH WU3 TS_= R"P ONi M, e db`+#_#^e#]([ZYoX2U/#Ty#S<P?#O3 #NF3 #M 3#K 3#J3 IP F Epqpq+pq DZpqpq+pq Cpqpq+pq Apqp q+p q @pq + ?d <pqpq+pq ;pqpq+pq :npqpq+pq 7 5xpq 4:pqpq+pq 2pqpq+pq 1pqpq+pq 0pqpq+pq /Dpqpq+pq ,pq +pqpq+pq *Npqpq+pq )pqpqpq 'pqpqpq &pqpqpq $pq "pqpq+pq !pqpq+pq bpqpq+pq %pqpq+pq pqpq+pq lpq pq pqpq /pq pq vpq 9pq pq) pq pq# Cpq" pqC pqC 6 gDw[CMODEL 1: preamble.mcMay 18, 1981 1:29 PM%2* May 18, 1981 1:36 PMrmRegion[rm2ForKernelRtn];knowRbase[rm2ForKernelRtn];rv[chkSimulatingRtn, 0];rv[fixSimRtn, 0];rv[chkRunSimRtn, 0];rv[currentTaskNum, 0];rmRegion[randomRM];knowRbase[randomRM];rv[rndm0, 134134];rv[rndm1, 054206];rv[rndm2, 036711];rv[rndm3, 103625];rv[rndm4, 117253];rv[rndm5,154737];rv[rndm6, 041344];rv[rndm7, 006712];* rm below not used for simple random number generator.rv[randV,0];* current value from random number generatorrv[randX,0];* current index into random number jump tablerv[oldRandV,0];* saved valuerv[oldRandX,0];* saved valueknowRbase[defaultRegion];mp[flags.conditionalP, 200];* bit that indicates conditional simulatingmp[flags.conditionOKp, 100];* bit that indicates conditional simulating is okset[holdValueLoc, 3400];mc[holdValueLocC, holdValueLoc];mc[flags.taskSim, b15];* NOTE: The "flags" manipulation codemc[flags.holdSim, b14];* works only so long as there are no moremc[flags.simulating, flags.taskSim, flags.holdSim];set[simTaskLevel, 12]; mc[simTaskLevelC, simTaskLevel];mc[sim.holdMask, 377]; set[sim.holdShift, 0];mc[sim.taskMask, 177400]; set[sim.taskShift, 10];m[lh, byt0[ and[rshift[#1,10], 377] ] byt1[ and[#1, 377]]];* assemble data for left half of IMm[rh, byt2[ and[rshift[#1,10], 377] ] byt3[ and[#1, 377]]];* assemble data for right half of IMm[zeroHold, ilc[(#1 _ A0)]ilc[(hold&tasksim _ #1)]ilc[(hold&tasksim _ #1)]ilc[(hold&tasksim _ #1)]];gp->zN bAq_^\pqZpqYp qXUp qWUS_pq #pq R"pq #pq Ppq #pqOpq #pq Ni7M,pq#,Kpq#-Jpq# Ispq# FD}pq++C@pq+1@p q+?p q#%>Jp q#)= pqp q;p q p q9Tp q p q8p qp q 5pq44^# 3 pq41$ /hpq.*,+*r )@>MODEL 1: preamble.mcMay 18, 1981 1:29 PM%3* December 11, 1978 3:20 PM%subroutine entry/exit macros%m[saveReturn, ilc[(t _ link)]top level[]ilc[(#1 _ t)]];m[saveReturnAndT, ilc[(#2 _ t)]ilc[(t _ link)]top level[]ilc[(#1 _ t)]];m[returnUsing, subroutine[]ilc[(RBASE _ rbase[#1])]ilc[(link _ #1)]ilc[(return, RBASE _ rbase[defaultRegion])]];m[returnAndBranch, subroutine[]ilc[(RBASE_rbase[#1])]ilc[(link_#1)]ilc[(RBASE_rbase[defaultRegion])]ilc[(return, PD_#2)]];m[pushReturn, subroutine[]ilc[(stkp+1)]top level[]ilc[(stack _ link)]];* notice that this macro doesn't clobber T !!!m[pushReturnAndT, subroutine[]ilc[(stkp+1)]ilc[(stack&+1 _ link)]top level[]ilc[(stack_t)]];m[returnP, subroutine[]ilc[(link_(stack&-1))]ilc[(return)]];m[pReturnP,ilc[(stkp-1)]subroutine[]ilc[(link_(stack&-1))]ilc[(return)]];m[returnPAndBranch, subroutine[]ilc[(link_(stack&-1))]ilc[(return, PD_#1)]];m[pReturnPAndBranch, subroutine[]ilc[(stkp-1)]ilc[(link_(stack&-1))]ilc[(return, PD_#1)]];*m[getRandom, ilc[(RBASE _ rbase[randX])]*ilc[(randX _ (randX)+1, Bdispatch _ randX)]*ilc[(call[random], RBASE _ rbase[rndm0])]*ilc[(RBASE _ rbase[defaultRegion])]*];* Returns random number in T, leaves RBASE= defaultRegionm[getRandom, ilc[(RBASE_ rbase[rndm0])]ilc[(call[random])]ilc[(RBASE_ rbase[defaultRegion])]];knowRbase[defaultRegion];gp->zN bAq a_ ^ ]Kp q\ Z Y Wp qUT S_ R" Op q NiM,K+J Ispq H6F E!D}C@ Bp q @ ? >J= . ;pq : 9T8 6 5 4^pq 3 1 0 /hp.*q , +*r )4 'pq &%|$> #pq !  H  pq R+ ) # : \pq" )" 6ZC GACHAGACHAGACHA w !T%.)6.l15;=C GxJ"N%SY4] fjoYY74 MTraps.cm.YY#Mopcodes.mesa.YY" Mopcodes.bcd.Z Y! MiscOps.mesa.ZY  MiscOps.bcd.ZCZ MiscDefs.mesa.[hX''ZDZZ YYYYYYYYYYYrYbYUYGY7Y'YZQZ{ MiscDefs.bcd.Z`ZCxMiscAlpha.mesa.ZoZQqMiscAlpha.bcd. Z|Z`j/rp^UPreAndPostamble.pressmcdanielw22-Jun-81 8:31:33 PDTp