//D1SimMem.bcpl	23 May 1983

//SimMemory checks consistency of memory section signals.  Code in this
//file simulates MemC and some MemX stuff and calls SimMemD and SimMemX
//to simulate other stuff.  Returns the value of Hold as its result.

get "d1simmi.d"
manifest [ get "d1dmux.d" ]

external [
// MINIT0
	@MBlock

// D1I0
	@DMuxTab; @OldDMuxTab; HaveIFU

// D1SimMemD
	SimMemD

// Defined here
	SimMemory; MapWaitDx
]


//T1FFfunc eq 0 when FFok is false
let SimMemory(Tn,Correct,Tneven,FFmem,asel,gMD,gMDI,T2RepeatCur,SWx,
	oldFFmem,oldasel,oldgMD,oldgMDI,oldSWx,oldoldgMD,
	T1FFfunc,HoldReq,Hold,oldHold) = valof
[
	let PAIR = DMuxTab!dPAIR xor 21061B	//All hi-true
	let EcHasA = DMuxTab>>MC.bEcHasA
	let EcWantsA = DMuxTab>>MX2.EcWantsAa
	let AwasFreex = DMuxTab>>MC.AwasFreex
	let PairFullx = DMuxTab>>MC.PairFullx
	let VicInPair = not DMuxTab>>MC.VicInPairx
	let FSinPair = not DMuxTab>>MC.FSinPairx
	let IfuRefInA = DMuxTab>>MC.IfuRefInA
	let PrivRefInPair = DMuxTab>>MC.PrivRefInPair
	let WantProcRef = asel < 4
	let CurTask = DMuxTab>>MX0.CurTask
	let EmuOrFT = (CurTask eq 0) % (CurTask eq 17B)
	let RefHoldx = DMuxTab>>MC.RefHoldx
	let BLretry = DMuxTab>>MC.BLretry
	let Hit = DMuxTab>>MC.Hita
	let WantCHdlyx = DMuxTab>>MC.WantCHdlyx
	let ProcSrn = DMuxTab>>MX0.ProcSrn

	let oldProcrefs = 21000B	//No reference in pair
	let oldPAIR = OldDMuxTab!dPAIR xor 21061B
	let oldEcHasA = OldDMuxTab>>MC.bEcHasA
	let oldEcWantsA = OldDMuxTab>>MX2.EcWantsAa
	let oldIfuRefInA = OldDMuxTab>>MC.IfuRefInA
	let oldKillIfuRef = OldDMuxTab>>MC.KillIfuRef
	let oldDbusy = OldDMuxTab>>MC.Dbusy
	let oldDbufBusy = OldDMuxTab>>MC.DbufBusy
	let oldEmuOrFT = OldDMuxTab>>MX0.CurTask
	oldEmuOrFT = (oldEmuOrFT eq 0) % (oldEmuOrFT eq 17B)
	let oldWantProcRef = oldasel < 4

	let T1DTab,T1gMDx,T1gMDIx = nil,nil,nil
	let T1asel,T1FFmem = nil,nil
	let T2DTab,T2Hold = nil,nil
	test Tneven
	ifso
	[ T1DTab,T1gMDx,T1gMDIx = OldDMuxTab,not oldgMD,not oldgMDI
	  T1asel,T1FFmem = oldasel,oldFFmem
	  T2DTab,T2Hold = DMuxTab,Hold
	]
	ifnot
	[ T1DTab,T1gMDx,T1gMDIx = DMuxTab,not gMD,not gMDI
	  T1asel,T1FFmem = asel,FFmem
	  T2DTab,T2Hold = OldDMuxTab,oldHold
	]

//These are needed for call of SimMemX or SimMemD
	let T2FastDgDbuf,T2MakeMDgD,T2StartMap = nil,nil,nil

//Initialize simulated values of some terms to actual values;
//then modify in cases where values can be computed.
	let cRefHoldx = RefHoldx
	let cBLretry = BLretry

	let cInPair,cIfuRefInA = nil,nil


//**Simulation of t1 signals dependent upon t0 and t1 signals**
//Names beginning with "T1" are values of T0 signals just prior to the
//previous T1.
	if Tn ge 1 do
	[ let T1PAIR = T1DTab!dPAIR xor 21061B	//Convert all to hi-true
	  let T1VicOrFSInPairx = (T1PAIR & 60B) eq 0
	  let T1EcHasA = T1DTab>>MC.bEcHasA
	  let T1EcWantsA = T1DTab>>MX2.EcWantsAa
	  let T1WantProcRef = T1asel < 4
	  let T1Dbusy = T1DTab>>MC.Dbusy
	  let T1CacheRefInA = T1DTab>>MC.CacheRefInA
	  let T1WantCR = T1WantProcRef & ((T1asel ge 2) % (T1FFmem ge 2))

//**Simulation of T0 signals derived from values prior to T0**
	  if Tn ge 2 do
	  [ let T2BLretry = T2DTab>>MC.BLretry
	    let T2Hit = T2DTab>>MC.Hita
	    let oldVicIfMiss = ((oldPAIR & 6420B) ne 0) & not oldEcHasA
	    let oldIoStoreInA = OldDMuxTab>>MC.IoStoreInA
	    let oldSTfreex = OldDMuxTab>>MX0.STfreex

	    let oldAwantsDifHit = (oldPAIR & 2400B) ne 0
	    let oldVicOrFS1C = ((oldPAIR & 60B) ne 0) &
		(not OldDMuxTab>>MC.AwasFreex) //& (not oldEcHasA)
//RfshSqWave always high during simulation because EnRefreshPeriod is off
	    let oldAcanHaveMap = OldDMuxTab>>MX0.MapFree
	    let oldAwantsMapFSx = OldDMuxTab>>MC.AwantsMapFSx
	    let oldAbusyForSure =
		((not oldAwantsMapFSx) & not oldAcanHaveMap) %
		(oldIoStoreInA & oldSTfreex & not OldDMuxTab>>MC.AtookST)
	    let T2Afreex = (oldEcHasA ne 0 ? not OldDMuxTab>>MC.PairFullx,
		oldAbusyForSure % oldVicOrFS1C % T2BLretry %
		(T2Hit eq 0 ? oldVicIfMiss & not oldAcanHaveMap,
		  oldAwantsDifHit & not OldDMuxTab>>MX1.AcanHaveD)) & 1
	    Correct>>MC.AwasFreex = T2Afreex

	    let T2Transport = (OldDMuxTab>>MX1.MakeTransport & 5) ne 0
	    Correct>>MC.Dbusy = T2Transport
	    Correct>>MD.DadHgx = T2Transport
	    Correct>>MC.bEcHasA = oldEcWantsA
	    Correct>>MX1.EcHasA = oldEcWantsA

//oldStartSTduringAx omits the T2Afree term (= AwasFree)
	    let oldStartSTduringAx = oldSTfreex %
		((not oldIoStoreInA) & not
		 (MapWaitDx(OldDMuxTab) &
		  (not OldDMuxTab>>MC.VicInPairx) &
		  (not oldEcHasA)
		 )
		)
	    Correct>>MC.AtookST = AwasFreex &
		((oldStartSTduringAx & 1) ne 0 ? OldDMuxTab>>MC.AtookST,1)

	    let T2NoRef = T2DTab>>MC.NoRef
//F←D is double-clocked
	    let TLastMakeFgD = (((T1DTab!dPEEC & 7) eq 5) &
		T1DTab>>MX0.IFURefInEc2) %
		((not T1Dbusy) & (not T2BLretry) &
			T1DTab>>MC.IfuRefInA & T2Hit)
	    Correct>>MD.FgD = TLastMakeFgD
	    let T1oldgMD = nil
	    test Tn eq 3
	    ifso	//Tn eq 3
	    [ T1oldgMD = oldgMD
//No check of IfuRefInA at T3 unless EcHasA forces it to 0.
	      cIfuRefInA = IfuRefInA
	    ]
//WantIfuRef only valid T0 to T1, so can only check UseAsrn and IfuRefInA
//at Tn eq 2.
	    ifnot	//Tn eq 2
	    [ let T1WantIfuRef = not OldDMuxTab>>IFU0.WantIfuRefx
	      let IfuAck = Hit & T1WantIfuRef & WantCHdlyx
//WantProcRef is forced false at b.p.'s so don't use the following:
//	      let cUseAsrn = IfuAck %
//		(((not PrivRefInPair) & (not PairFullx) & (not EcWantsA)) &
//			not (WantProcRef & RefHoldx)) %
//		((not Hold) & WantProcRef & not
//		 (EmuOrFT & ((asel+FFmem) ne 0)))
	      Correct>>MX0.UseAsrn = IfuAck %
		((not PrivRefInPair) & (not PairFullx) & (not EcWantsA))

	      let T2UseAsrn = IfuAck %
		(((not oldEcWantsA) & ((oldPAIR & 101B) eq 1)) &
			not (RefHoldx & oldWantProcRef)) %
		((not Hold) & oldWantProcRef & not
			(oldEmuOrFT & ((oldasel+oldFFmem) ne 0)))
	      let T2PEsrn = oldEcWantsA ne 0 ?
		OldDMuxTab>>MX2.Ec1Srn,ProcSrn
	      Correct>>MC.PipeAd = (T2UseAsrn & 1) ne 0 ?
		OldDMuxTab>>MX0.ASrn,T2PEsrn

	      Correct>>MC.gPrVArow = (not T1EcWantsA) &
		(not (T1WantProcRef & not Hold)) & (not IfuAck)

//We could predict with the muffler signal for KillIfuRef at T1 or T3,
//but not at T2.
	      cIfuRefInA = IfuAck & (not T2DTab>>IFU1.Testing) & not
		(OldDMuxTab>>IFU0.RefOutstanding & not TLastMakeFgD)

	      T1oldgMD = oldoldgMD

	      Correct>>MC.MiscPCHPx =	//T2UseAsrn % oldXWantsPipe
		(not ((not OldDMuxTab>>MX0.MapWantsPipe) &
		  OldDMuxTab>>MX2.EcWantsPipe4x)) % T2UseAsrn

	      if HaveIFU & (T2DTab>>IFU1.Testing eq 0) then
		Correct>>IFU0.NewF = T2DTab>>IFU1.TestMakeFgD %
		  TLastMakeFgD
	    ]

	    Correct>>MX0.ProcSrn = OldDMuxTab>>MX1.ProcSrngx eq 0 ?
		T1DTab!dMAPBUF,OldDMuxTab>>MX0.ProcSrn

//ProcVA simulated when no clock
//**Should be only Tn eq 2 if commented out parts are implemented somehow
	    test (T1VicOrFSInPairx & (T1DTab>>MC.AwasFreex xor 1)) ne 0
	    ifso	//Got LdProcVA clock
//	      if (OldDMuxTab>>MC.DisBR ne 0) & not oldoldIFetch do
//	      [ Correct!dPVAL = not OldDMuxTab!dMAR
//		Correct!dPVAH = oldT1LFetch ? OldDMuxTab!dALUB & #7777,0
//	      ]
	      [
	      ]
	    ifnot	//No LdProcVA clock
	    [ MBlock(Correct+dPVAH,OldDMuxTab+dPVAH,2)
	    ]

	    let T2ForceDirtyMiss = T2DTab>>MC.ForceDirtyMiss
	    let T2AfreeOrEc = oldEcHasA  % (not AwasFreex)

//Simulate processor reference that might have been loaded into Pair.
//Store← also affects dDbufBusy. Align bits with PAIR.
	    if oldasel < 4 then oldProcrefs = (oldEmuOrFT ?
		table [ 025000B	//PreFetch←
			001100B	//Map←
			021500B	//LongFetch←
			121500B	//Store←
			021100B	//DummyRef←
			031100B	//Flush←
			021500B	//IFetch←
			021500B	//Fetch←
			121500B	//Store←
			121500B	//Store←
			121500B	//Store←
			121500B	//Store←
			021500B	//Fetch←
			021500B	//Fetch←
			021500B	//Fetch←
			021500B	//Fetch←
		] ,
		table [	025000B	//PreFetch←
			020000B	//IoFetch←
			021400B	//LongFetch←
			121400B	//Store←
			021000B	//DummyRef←
			060000B	//IoStore←
			021400B	//IFetch←
			021400B	//Fetch←
			121400B	//Store←
			121400B	//Store←
			121400B	//Store←
			121400B	//Store←
			021400B	//Fetch←
			021400B	//Fetch←
			021400B	//Fetch←
			021400B	//Fetch←
		] ) ! ((oldasel lshift 2)+oldFFmem)

	    let cProcTagInPair,cAtask = nil,nil
	    test AwasFreex eq 0
	    ifso	//Got LdPair clock--know that oldEcHasA
			//was false because Afree was true enabling the
			//clock
	    [ cInPair = (T2Hold & 1) ne 0 ?
	        021000B,	//All of the processor references shut off.
	        oldProcrefs	//Propagate processor references into Pair
	      cProcTagInPair =
		OldDMuxTab>>MX1.Ptag xor ((cInPair & 400B) ne 0)
	      cAtask = OldDMuxTab!dCTASK
//cIfuRefInA derived above for T2, or copied from DMuxTab for T3.
//Can't predict VicInPair when WantVic is true unless ForceDirtyMiss
//is also true because DirtyVicOrAB is unknown.
//old CacheRefInA % PrefetchInA % FSinPair % IfuRefInA
	      let T2WantVic = (not T2Hit) & (not oldEcHasA) & oldVicIfMiss
	      let cVicInPairx =
		not (T2WantVic & (T2ForceDirtyMiss % VicInPair))
//	      let T2DirtyVicOrAB = (not oldVictimInA) & T2AfreeOrEcx &
//		Dirty[Victim]
//	      let cVicInPairx = not (T2WantVic & (T2ForceDirtyMiss %
//		T2DirtyVicOrAB))
	      let cFSinPairx =
		not (T2DTab>>MC.HitColDirty & OldDMuxTab>>MC.FlushInA)
	      let cPairFullx = cFSinPairx & cVicInPairx & not
		((oldWantProcRef & not T2Hold) % cIfuRefInA)
	      cInPair = cInPair+((cVicInPairx & 1) lshift 5)+
		((cFSinPairx & 1) lshift 4)+(cPairFullx & 1)
	    ]
	    ifnot	//Didn't get LdPair clock--if oldEcHasA was
			//true, then InA signals were shut off, so copy
			//values from DMuxTab, else InA eq oldInA
	    [ cInPair = oldEcHasA ?
		(OldDMuxTab!dPAIR & #20161)+(DMuxTab!dPAIR & #155400),
		OldDMuxTab!dPAIR & #175561
	      cIfuRefInA = oldEcHasA ? IfuRefInA,oldIfuRefInA
	      cProcTagInPair = OldDMuxTab>>MX0.ProcTagInA
	      cAtask = OldDMuxTab>>MX1.Atask
	    ]
	    Correct!dPAIR = (Correct!dPAIR & 000216B)+cInPair
	    Correct>>MC.IfuRefInA = cIfuRefInA
	    Correct>>MX1.CacheRefInPairx = (cInPair & 400B) eq 0
	    Correct>>MX0.ProcTagInA = cProcTagInPair
	    Correct>>MX1.Atask = cAtask

	    let T1ForceMissx = 1 & T1VicOrFSInPairx &
		(not OldDMuxTab>>MC.ForceDirtyMiss) & (not T1EcHasA)
	    if T1ForceMissx eq 0 do
	    [ Correct>>MC.Hita = 0
	    ]

//RefHold--simulated unless Miss with ForceMiss makes it unpredictable.
	    test (T1gMDIx & T1gMDx & (not T1WantProcRef) & 1) ne 0
	    ifso cRefHoldx = 1
	    ifnot
	    [ test WantCHdlyx eq 0
	      ifso cRefHoldx = 0
	      ifnot if (Hit % T1ForceMissx) ne 0 then cRefHoldx = Hit
	    ]


//MiscHold--MD conflict term first
	    let cMiscHoldx = not (T1oldgMD & (not T1gMDIx) & (not oldHold))
	    let T1DbufHold = (not T1DTab>>MC.StoregInA) &
		  ((T1asel & 1) eq 0) & T1WantCR & T1DTab>>MC.DbufBusy
//T1PairFull % T1EcWantsA % T1EcHasA % XWantsPipe % MiscPCHP'
	    let T1prePipeHoldx = (not T1EcWantsA) & ((T1PAIR & 11B) eq 0) &
	       (not T1DTab>>MX0.MapWantsPipe) & T1DTab>>MX2.EcWantsPipe4x &
		not T1DTab>>MC.MiscPCHPx
	    if ((T1DbufHold % (not T1DTab>>MC.SomeExtHoldx) %
	      ( ((T1FFfunc & 370B) eq 160B) & not T1prePipeHoldx)
	      ) & 1) ne 0 then
		cMiscHoldx = 0

//MDhold
	    let cMDholdx = (not T1DTab>>MX1.DdataGoodx) %
	      (T1DTab>>MX0.ProcTag xor T1DTab>>MX0.MDMtagx) %
		(T1gMDIx & (
		  ((not T1DTab>>MX0.AteqCurtx) & T1CacheRefInA &
			(not T1Dbusy)
		  ) %
		  EcDcomingForCt(T1DTab) %
		  (T1gMDx & not (
			T1WantProcRef & ((T1asel ge 2) % (T1FFmem ge 2))
		  ))
		))

//If at t1 not (CacheRefInA % PrefetchInA % FSinA % IfuRefInA % FlushInA %
//IoStoreInA) then BLretry should be 0.
	    if (((T1PAIR & 56420B) eq 0) % T1EcHasA) ne 0 do
	    [ cBLretry = 0
	    ]

	    if (OldDMuxTab>>MC.DisHold+DMuxTab>>MC.DisHold) ne 0 do
	    [ cRefHoldx,cMDholdx,cMiscHoldx,cBLretry = -1,-1,-1,0
	    ]
	    Correct>>MC.RefHoldx = cRefHoldx
	    Correct>>MC.MiscHoldx = cMiscHoldx
	    Correct>>MC.MDholdx = cMDholdx
	    Correct>>MC.BLretry = cBLretry

//MCR--everything except Victim and NextV predicted
//**Also want to do LoadTestSyndrome on MemD (FF=125B) & ←FaultInfoDly on
//**MemX (FF=160B).
//Bug**: want oldT1FFfunc but don't have it, so can only do this at t3.
//	    Correct!dMCR = (((oldT1FFfunc eq 126B) & not oldHold) ?
//		((not OldDMuxTab!dMAR) & 160740B)+(OldDMuxTab!dALUB & 7B),
//		(OldDMuxTab!dMCR & 160747B))+(DMuxTab!dMCR & 17030B)

	    T2FastDgDbuf = (not oldDbusy) & (not T2BLretry) &
		(oldPAIR < 0) & T2Hit
	    Correct>>MC.DbufBusy = ((oldProcrefs < 0) & (not T2Hold)) %
		(oldDbufBusy & (not T2NoRef) &
		 (not OldDMuxTab>>MX2.MakeDgDbuf) &
		 not T2FastDgDbuf)

//ColVic = (EcHasA % Hit % ←Pipe5 % old←Pipe5) ? Col,
//	Victim % Col [Col unmuffled]
//Col(term1) = T1ForceMiss ? 0,(Hit ? (T1Dbusy ? unknown hit col,Dad[0:1]),0)
//Col(term2) = T1EcHasA ? T1PipeCol (unmuffled),
//			(T1VicInPair % olddVA←Vic ? oldVictim,0)
//
//oldVicInCol = olddVA←Vic ? oldVictim,0
//Col = T1EcHasA ? T1PipeCol (unmuffled), (T1VicInPair ? oldVictim,
//	oldVicInCol % (Hit ? (T1Dbusy ? unknown hit col,Dad[0:1]),0))
//The fact that dVA←Vic is not in ForceMiss seems to be a hardware bug.

	    let oldVictim = OldDMuxTab>>MC.Victim
	    let ColVic = DMuxTab>>MC.ColVic
	    let cColVic = T1EcHasA ne 0 ? ColVic,
	      ((T1PAIR & #40) ne 0 ? oldVictim,
		(OldDMuxTab>>MC.dVAgVic ne 0 ? oldVictim,0) %
		(Hit ne 0 ? (T1Dbusy ne 0 ? ColVic,
			DMuxTab>>MD.Dad rshift 11),0))
//Note: When FFmem .eq. #160, the ←Pipe5 term won't happen if T1XWantsPipe %
//oldT1XWantsPipe % oldT1UseAsrn % T1EcHasA % T1EcWantsA % T1PairFull
//disables the clock.  However, oldVictim is already in cColVic when
//T1PairFull and (?) oldVictim eq Victim in this case; EcHasA eq 0 implies
//T1EcWantsA eq 0.  This means that only T1XWantsPipe is a problem.
//At T0, T1←Pipe5 is all that matters; at T1, both ←Pipe5 and old←Pipe5 would
//force HitOrEc=true, but this simulation is only done at Tn eq 2.
//***Incomplete simulation here.
	    if (EcHasA eq 0) & (Hit eq 0) //& ((T1FFmem ne #160) % true)
		then cColVic = cColVic % (DMuxTab>>MC.Victim & ColVic)
	    Correct>>MC.ColVic = cColVic

	    let T2AWordRefToD = (not OldDMuxTab>>MX1.CacheRefInPairx) &
		T2Hit & T2AfreeOrEc
	    let T2DcomingForCt = EcDcomingForCt(OldDMuxTab) %
		(T2AWordRefToD & not OldDMuxTab>>MX0.AteqCurtx)
	    Correct>>MX2.MakeMDMgDx =
		(not T2AWordRefToD) & (not OldDMuxTab>>MX1.EcWordRefToD)
	    let oldCacheRef = ((oldProcrefs & 400B) ne 0) & not T2Hold
	    Correct>>MX1.DdataGoodx =
		not (T2DcomingForCt & (not oldCacheRef) & oldSWx)
	    T2MakeMDgD = (oldSWx % (oldgMD & not T2Hold)) & T2DcomingForCt

//T2StartMap = MapRfsh % (NoRef' & AfreeOrEc & (WantVic % AwantsMapFS)).
//WantVic = HitOrEc' & VicIfMiss = Hit' & EcHasA' & VicIfMiss.
//Both AwantsMapFS and VicIfMiss imply EcHasA', so this becomes
//MapRfsh % (NoRef' & AfreeOrEc & ((VicIfMiss & Hit') % AwantsMapFS)).
//When oldEcHasA=0, T2AfreeOrEc = AwasFree
	    T2StartMap = OldDMuxTab>>MX1.MapRfsh %
		((not T2NoRef) & (not AwasFreex) &
		 ((not oldAwantsMapFSx) % ((not T2Hit) & oldVicIfMiss))
		)
	  ]

	  let T1IfuRefInA = T1DTab>>MC.IfuRefInA

//**Can probably improve this by looking at BLretry when DisHold false
//= if at t1 AwantsMapFS % FSinPair % FlushInA % EcWantsA % (PairFull &
//EcHasA) % (Dbusy & (CacheRefInA % IfuRefInA) then ...
	  if ((((T1PAIR & 31060B) ne 0) % T1EcWantsA %
		((T1PAIR & 11B) eq 11B) %
		(T1Dbusy & (T1CacheRefInA % T1IfuRefInA))) & 1) ne 0 then
		Correct>>MC.WantCHdlyx = 0

//StkError from the processor (= PrHoldReq) & CHoldReq & IfuHoldReq
//(computed on ContA) are contained in the HoldReq argument;
//assuming no sources to ExtHoldReq (?), only the hold simulator is
//missing from the term.
	  if HoldReq ne 0 then Correct>>MC.SomeExtHoldx = 0

	  Correct>>MX1.ProcSrngx = T1FFfunc ne 127B

//Doing this here avoids T1DTab in d1simmemx.
	  Correct>>MX0.MapRfshDly = T1DTab>>MX1.MapRfsh
	]

//**Simulate signals derived from other signals without intervening flops**
	let CacheRefInA = DMuxTab>>MC.CacheRefInA
	let Dbusy = DMuxTab>>MC.Dbusy
	let DbufBusy = DMuxTab>>MC.DbufBusy

	Correct>>MX1.sHold = Hold
	Correct>>MX0.PrivRefinPair = PrivRefInPair
	Correct>>MX0.PairFull = not PairFullx
	Correct>>MC.AwantsMapFSx = EcHasA % ((PAIR & #21040) eq 0)

	Correct>>MC.KillIfuRef =
		(not DMuxTab>>MX2.MakeFgD) & DMuxTab>>IFU0.RefOutstanding

	let Ec2State = DMuxTab!dPEEC & 7
	Correct>>MX2.MakeDgDbuf =
		(Ec2State eq 4) & not DMuxTab>>MX0.StoregInEc2x
	Correct>>MX2.MakeFgD =
		((Ec2State eq 5) & DMuxTab>>MX0.IFURefInEc2) %
		((not Dbusy) & (not BLretry) & IfuRefInA & Hit)
	Correct>>MX1.ChkLastPh6 = (Ec2State eq 2) & not Tneven
	Correct>>MX1.EcWordRefToD =
		(Ec2State eq 5) & DMuxTab>>MX0.CacheRefInEc2

//If EcHasA is true, then all terms making up AfreeOrEc' are off except for
//BLretry, which will be off after t1 but is uncertain after t0. If EcHasA
//is false, then AfreeOrEc can be backwards predicted from Afree.
	let AfreeOrEc = nil
	test EcHasA ne 0
	ifso
	[ AfreeOrEc = not BLretry
	  Correct>>MC.Afreex = BLretry % not PairFullx
	]
	ifnot
	[ AfreeOrEc = not DMuxTab>>MC.Afreex
	]

	if Hit eq 0 do
	[ Correct>>MC.HitColDirty = 0
	  Correct>>MC.HitColVApar = 0
	]

//VicIfMiss = CacheRefInA % PrefetchInA % FSinA % IfuRefInA
	let VicIfMiss = ((PAIR & 6420B) ne 0) & not EcHasA
	Correct>>MC.StartMapx = (not DMuxTab>>MX1.MapRfsh) &
		not (AfreeOrEc & (not DMuxTab>>MC.NoRef) &
		((VicIfMiss & (not Hit)) % (not DMuxTab>>MC.AwantsMapFSx)))
	if EcHasA ne 0 do
	[ Correct!dPAIR =
	    (Correct!dPAIR & 020377B) % 1000B	//Turn off ..InA
	]
	Correct>>MX0.VictimInA = VicInPair & (not EcHasA)

	let Dtask = DMuxTab>>MX0.Dtask
	let Atask = DMuxTab>>MX1.Atask
	Correct>>MX0.AteqCurtx = Atask ne CurTask
	Correct>>MX0.DteqCurtx = Dtask ne CurTask
	let Ptag = DMuxTab>>MX1.Ptag
	let CacheRefInPair = not DMuxTab>>MX1.CacheRefInPairx
	let AteqCurt = not DMuxTab>>MX0.AteqCurtx
	Correct>>MX0.ProcTag = (AteqCurt & CacheRefInPair) % Ptag
	if (AteqCurt & CacheRefInPair & 1) ne 0 then Correct>>MX0.MDMtagx = -1
	Correct>>MX0.MDMtagAd = Tneven ? CurTask,Dtask
	Correct>>MX0.CurTask = DMuxTab!dCTASK
	let AWordRefToD = DMuxTab>>MX0.AWordRefToD
	Correct>>MX2.MakeMDgD = (SWx % (gMD & not Hold)) &
		(EcDcomingForCt(DMuxTab) % (AteqCurt & AWordRefToD))
	Correct>>MX0.AWordRefToD = CacheRefInPair & Hit & AfreeOrEc
	Correct>>MX0.Transporta = DMuxTab>>MX1.MakeTransport ne 0
//RfshPeriod is high during simulation.
	Correct>>MX1.NeedRfsh = DMuxTab>>MX1.WantRfsh & PairFullx

	Correct>>MX1.LoadFltSrn = DMuxTab>>MX1.ReportFault &
		((not DMuxTab>>MX1.Faults) % DMuxTab>>MX1.LoadFltSrn)

	Correct>>MX1.ReportFault = DMuxTab>>MX1.ChkLastPh6 &
	  not (DMuxTab>>MX0.MemErrorx & DMuxTab>>MX2.ValidMapFltInEc2x &
	    (not (DMuxTab>>MC.WakeOnCL & not DMuxTab>>MX2.CacheLoadx)) &
	    (DMuxTab>>MX0.ECFaultx % DMuxTab>>MC.ReportSEx))

	Correct>>MX2.PEsrn = EcWantsA ne 0 ?
		DMuxTab>>MX2.Ec1Srn,ProcSrn

	SimMemD(Tn,Correct,T1DTab,Tneven,Hold,T2RepeatCur,oldHold,
		oldProcrefs < 0,oldgMD,T2FastDgDbuf,T2MakeMDgD)

	resultis T2StartMap
]


and MapWaitDx(DTab) =
	(DTab>>MX1.RefUsesDInMem +
	DTab>>MX0.RefUsesDinEc1 +
	DTab>>MX1.MapWaitEc2 +
	DTab>>MX2.EcWantsAa) eq 0


and EcDcomingForCt(DTab) =
	(not DTab>>MX0.DteqCurtx) & DTab>>MX1.EcWordRefToD