//D1SimMemD.bcpl
//	Last edited: 17 July 1979

//SimMemD is called by SimMemory to check consistency of signals muffled
//on the MemD board.

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

external [
// D1I0
	@DMuxTab; @OldDMuxTab

// Defined here
	SimMemD
]


let SimMemD(Tn,Correct,T1DTab,Tneven,Hold,T2RepeatCur,
	oldHold,oldStore,oldgMD,T2FastDgDbuf,T2MakeMDgD) be
[	let Dbusy = DMuxTab>>MC.Dbusy
	let BLretry = DMuxTab>>MC.BLretry
	let StoregInA = DMuxTab>>MC.StoregInA
	let Hit = DMuxTab>>MC.Hita
	Correct>>MD.bFastDgDbuf = (not Dbusy) & (not BLretry) & StoregInA &
		Hit & (not Tneven)
	let Transport = DMuxTab>>MX0.Transporta
	let oldTransport = DMuxTab>>MD.DadHgx
	let T1Transport = Tneven ? oldTransport,Transport
	let DadHg = not oldTransport
	Correct>>MD.DontLoad1 = Transport & not DadHg
	Correct>>MD.MakeMDMgDx = DMuxTab>>MX2.MakeMDMgDx
	Correct>>MD.StartEcGenx = Tneven % DMuxTab>>MX0.EnEcGenx
	Correct>>MD.StartEcChkx = Tneven %
		((DMuxTab>>MX2.Ec1FnState & 7) ne 0)
//**Complete prediction of WordInError is complicated, maybe impossible.
	if DMuxTab>>MD.DisableEcx eq 0 then Correct>>MD.WordInErrorx = true
	let Dad = DMuxTab>>MD.Dad xor 3770B
//Modify Dad predictions in situations when result is known.
	let cDad,cDad1 = Dad,DMuxTab>>MD.Dad1
	let EnableBothChips = DMuxTab>>MD.DgCD

	if Tn ge 1 do
	[ let cDbufg,cMDgD = 0,0	//0 after t1 or t3
	  let cWriteD1 = 0	//0 after t1 or t3
	  if Tn ge 2 do
	  [ let oldDbusy = OldDMuxTab>>MC.Dbusy
	    let oldStoregInA = OldDMuxTab>>MC.StoregInA
	    let oldDgDbuf = OldDMuxTab>>MD.DgDbuf
	    let oldDgCD = OldDMuxTab>>MD.DgCD
	    let oldDad = OldDMuxTab>>MD.Dad xor 3770B
	    if oldDgCD then EnableBothChips = 1
	    let cWriteD0 = nil
	    let cMDMad = nil

	    test Tn eq 3
	    ifso	//Tn eq 3
	    [ cWriteD0 = oldDgCD
	      cMDMad = OldDMuxTab>>MX0.Dtask
//Dad[10:13] might count??? but other bits of Dad frozen when Dbusy
	      if Dbusy then cDad = (oldDad & 17770B)+(cDad & 7B)
	    ]
	    ifnot	//Tn eq 2
	    [ cDbufg = oldStore & not Hold
	      cMDgD = (not oldDgDbuf) & T2MakeMDgD & (not T2FastDgDbuf)
	      cWriteD0 = T2FastDgDbuf % oldDgDbuf
	      cWriteD1 = cWriteD0 % oldDgCD
	      cMDMad = (T2RepeatCur % (oldgMD & not Hold)) ?
		OldDMuxTab>>MX0.CurTask,OldDMuxTab!dNEXT
//Can only do total prediction of DontWriteMDM at T2 when oldD←Dbuf eq
//T2D←Dbufdly.
	      Correct>>MD.DontWriteMDM = oldDgDbuf % T2FastDgDbuf
	    ]
//GenPh is a double-clocked 4-bit circular shift register initialized
//to 1 at T2 following EnEcGen at T0.  It then circulates until the next
//EnEcGen.  Hence, its low bit GenPh1 is 1 at T2 and 0 at T3 following
//EnEcGen at T0, else unknown.  Similar for ChkPh.
	    if OldDMuxTab>>MX0.EnEcGenx eq 0 then
		Correct>>MD.GenPh1 = Tneven
	    let oldpreEnEc = (OldDMuxTab>>MX2.Ec1FnState & 7) eq 0
	    if oldpreEnEc ne 0 then Correct>>MD.ChkPh1 = Tneven
	    Correct>>MD.WriteD0xe = not cWriteD0
	    Correct>>MD.MDMadx = cMDMad xor 17B
	  ]
	  let T1DadHg = T1DTab>>MD.DadHgx eq 0
//If we got the ProcVA and Dad clocks at T1 & EcHasA was false then
//Dad[2:13] = ProcVA[20:31] and Dad[0:1] = col. of hit or victim
	  if ((not T1DTab>>MC.bEcHasA) & (not T1DTab>>MC.AwasFreex) &
	    T1DTab>>MC.FSinPairx & T1DTab>>MC.VicInPairx & T1DadHg) ne 0 do
	  [ cDad = ((DMuxTab!dPVAL & 7777B) rshift 1)+(cDad & #14000)
	    cDad1 = cDad & 7B
	  ]
	  if (T1Transport & T1DadHg) ne 0 do	//Have ClearWA
	  [ cDad,cDad1 = cDad & 17770B,0
	  ]
	  Correct>>MD.Dbufgx = not cDbufg
	  Correct>>MD.WriteD1xd = not cWriteD1
//Signals dependent only upon "T1xx" and "xx" terms are predicted here

//The following signals are double-clocked and depend upon T0 signals
	  Correct>>MD.DgDbuf = T1DTab>>MX2.MakeDgDbuf
	  Correct>>MD.SoutgD = T1DTab>>MX1.MakeSoutgD
	  Correct>>MD.FoutgD = T1DTab>>MX2.MakeFoutgD
	  Correct>>MD.DgCD = T1DTab>>MX2.MakeDgCD
	  Correct>>MD.MDgD = cMDgD

	]

	Correct>>MD.Dad = cDad xor 3770B
	Correct>>MD.Dad1 = cDad1
//Always predict two of the four chip enables.  Predict the other two
//when D←CD or D←CDdlydly is true or when (Tn ge 2) & T1Transport is true.
	let mask1,mask2 = nil,nil
	test (Dad & 10B) ne 0
	ifso
	[ mask1,mask2 = 12B,5B
	]
	ifnot
	[ mask1,mask2 = 5B,12B
	]
	Correct>>MD.DCExc = EnableBothChips ne 0 ? mask1,
		mask1+(((T1Transport & (Tn ge 2)) ne 0 ?
		Tneven xor (mask2 & 3),DMuxTab>>MD.DCExc) & mask2)
]