//D1SimDec.bcpl
//	Last edited: 4 June 1981

get "d1.d"
get "d1sim.d"
manifest [ get "d1dmux.d" ]

external [
// OS
	Zero

// MINIT0
	@MBlock

// MASM
	LCycle; GetField

// D1ASM
	MIRtoIM; IMtoMIR

// D1I0
	@DMuxTab; @OldDMuxTab; DChecked; DWrong

// D1CONFIG
	HaveMemC; HaveIFU

// D1SimCon
	SimControl

// D1SimAsm
	SimALU

// D1SimMem
	SimMemory

// D1SimMemX
	SimMemX

// D1SimIfu
	SimIfu

// Defined here
	DSimulate; oldoldFFfunc
]

static [ oldoldFFfunc ];

//DSimulate checks the consistency of the signals read from the DMux after
//a particular clock.  Only signal values predictable from other DMux
//(i.e., passive) signals are checked.  The arguments are:
//  Tn		Clock after which DMux was read (0, 1, 2, or 3)
//  MIRvec	Pointer to vector that was loaded into MIR by SimTest
//		for checking (argument not supplied by SimGo)
//Detected errors are left in DWrong, and a count of errors detected is
//returned.

//When called by SimTest or SimGo, Tn is 2 and the checking includes
//signals propagated from the prevous T0, for which DMuxTab was saved.
//In these cases, RunRefresh is false.

//**HOW THE SIMULATOR IS ORGANIZED**

//Names beginning "old" are signal values at Tn-2.  "T1" names are values
//of T0-clocked signals just prior to the previous T1 (available for
//Tn ge 1).  "T2" names are values of T1-clocked signals prior to the
//previous T0 (available for Tn ne 1).  Names with no prefix are current
//(Tn) signals.  The program arranges to get the "T1xx" and "T2xx" signal
//values from either DMuxTab or OldDMuxTab according to the value of Tn.

//In other words, to predict the output of a T1-clocked flipflop whose
//input is some logic function of input signals, the name "T1xx" would be
//used for an input term "xx" clocked at T0, "oldxx" for an input clocked
//at the previous T1.  Similarly, the output of a T0-clocked flipflop
//would be predicted from terms named "oldxx" (T0-clocked input), "T2xx"
//(T1-clocked input).

//When a signal is only valid or only predictable during one-half of the
//cycle, then the simulator only predicts it when Tn is appropriate.
//Double-clocked signals are an instance of this.  Many other complications
//result in conditional prediction, normally commented.


let UnpackInstr(DVec,DTab,lvrstk) be
[	MIRtoIM(DVec,DTab+dSaveMIR)
	let rstk,aluf,bsel,lc,asel = nil,nil,nil,nil,nil
	let block,ff,jcn = nil,nil,nil
	let FFok,FFfunc,BExt = nil,nil,nil
	let Hold,gMD,gMDI,SWx,NextMacro = nil,nil,nil,nil,nil
	rstk = GetField(0,4,DVec)
	aluf = GetField(4,4,DVec)
	bsel = GetField(10B,3,DVec)
	lc = GetField(13B,3,DVec)
	asel = GetField(16B,3,DVec)
	block = GetField(21B,1,DVec)
	ff = GetField(22B,10B,DVec)
	jcn = GetField(32B,10B,DVec)
//**It would be better to use the independently mufflered values of
//**FFok' on ProcH, ProcL, and ContA.  Consequence of using the predicted
//**value is that if any FFok' signal should fail, some extraneous errors
//**are produced
	FFok = (bsel < 4) & (jcn ge 20B)
	FFfunc = (asel < 4 ? ff & 77B,ff) & FFok
	BExt = DTab>>P1.BgExt ne 0
	Hold = HaveMemC ? (DTab!dHOLD & #7000) ne #7000,DTab>>P0.Holda
	gMD = DTab>>P1.gMD
	gMDI = DTab>>P1.gMDI
	SWx = DTab>>C.bSWdx
	NextMacro = DTab>>P1.NextMacro
	MBlock(lvrstk,lv rstk,16)
]


//**Should check MIR against IMOUT on SimGo call of DSimulate.

and DSimulate(Tn,IMvec; numargs NA) = valof
[	let Correct,T = DWrong,nil
//Initialize Correct to values read from the hardware.  If a particular
//bit is not checked this time, then that bit in Correct is not modified,
//so no error is produced.
	MBlock(Correct,DMuxTab,200B)
	let Tneven = (Tn & 1) eq 0
	let DVec = vec 4
//Check MIR against load on SimTest.
	if NA > 1 do
	[ IMtoMIR(DVec,IMvec)
	  MBlock(Correct+dSaveMIR,DVec,4)
	]

//Instruction fields from MIR are a foundation for much of the checking
	let rstk,aluf,bsel,lc,asel = nil,nil,nil,nil,nil
	let block,ff,jcn,FFok,FFfunc = nil,nil,nil,nil,nil
	let BExt,Hold,gMD,gMDI = nil,nil,nil,nil
	let SWx,NextMacro = nil,nil
	UnpackInstr(DVec,DMuxTab,lv rstk)

//This stuff is irrelevant but harmless for Tn < 2.
	let oldrstk,oldaluf,oldbsel,oldlc,oldasel = nil,nil,nil,nil,nil
	let oldblock,oldff,oldjcn,oldFFok,oldFFfunc = nil,nil,nil,nil,nil
	let oldBExt,oldHold,oldgMD,oldgMDI = nil,nil,nil,nil
	let oldSWx,oldNextMacro = nil,nil
	UnpackInstr(DVec,OldDMuxTab,lv oldrstk)

	let T1aluf,T1bsel,T1asel = nil,nil,nil
	let T1ff,T1FFok,T1FFfunc,T1BExt = nil,nil,nil,nil
	let T1DTab = nil
	let T2DTab,HoldDly = nil,nil
	test Tneven
	ifso
	[ T1aluf,T1bsel,T1asel = oldaluf,oldbsel,oldasel
	  T1ff,T1FFok,T1FFfunc,T1BExt = oldff,oldFFok,oldFFfunc,oldBExt
	  T1DTab = OldDMuxTab
	  T2DTab,HoldDly = DMuxTab,Hold
	]
	ifnot
	[ T1aluf,T1bsel,T1asel = aluf,bsel,asel
	  T1ff,T1FFok,T1FFfunc,T1BExt = ff,FFok,FFfunc,BExt
	  T1DTab = DMuxTab
	  T2DTab,HoldDly = OldDMuxTab,oldHold
	]

//HoldReq will consist of StkError on the processor, the TaskingOff
//term on ContA (computed by SimControl), the IfuHoldReq term on ContA
//(computed by SimIfu), the hold simulator (not computed), and
//external hold requests (presently none).
	let HoldReq = DMuxTab>>P1.StkError
	let T2DoCBr,T2RepeatCur = nil,nil
	let RepeatCur = SimControl(Tn,Correct,T1DTab,T2DTab,Tneven,
		block,ff,jcn,FFfunc,oldblock,oldjcn,oldFFfunc,
		lv T2RepeatCur,lv T2DoCBr,lv HoldReq)

//Have to disable memory and IFU simulation for Tn ge 2 when doing
//multiphase instructions, so
	let MemIfuTn = (oldjcn & 347B) eq 147B ? Tn & 1,Tn
	let cIfuMARvalx = HaveIFU ?
	    SimIfu(MemIfuTn,Correct,Tneven,FFfunc,asel,
		oldNextMacro & not T2DoCBr,
		OldDMuxTab>>P1.NextDatax xor 1,HoldDly,oldFFfunc,
		T1DTab,T1FFfunc,T2DTab,lv HoldReq,NextMacro),
	    DMuxTab!dMAR

	let cMBBypass = NextMacro
	let RBaseWriteEnx = DMuxTab>>P1.RBaseWriteEnx
	let CurreqNextx = DMuxTab>>P0.CurreqNextx
	let NoSwitchOrHold = (not CurreqNextx) & (not Hold)
	let cSelRBaseWadrx = RepeatCur % (NoSwitchOrHold &
		(not RBaseWriteEnx) & (not Tneven))
	Correct>>P1.SelRBaseWadrx = cSelRBaseWadrx

//The following simulation is only done for Tn ge 1, but even if Tn eq 0,
//it is still possible to check signals duplicated on several boards for
//consistency.  Hence, the code here derives a signal and stores its
//value in one place.  Then outside the Tn ge 1 conditional, the value
//in that place is copied to all others where it appears.

	if Tn ge 1 do
	[
//**Simulation of stuff derived from values at Tn-2**
	  if Tn ge 2 do
	  [ let cBCWriteEnx,cMBWriteEnx = 0,not oldNextMacro
	    let ChkRbWadr,RbWadr = 17B,oldrstk
//Predict lc bits from table with bits aligned with muffler bits:
//	RbWriteEnx = 20040	(-1, -1, 0, -1, 0, 0, 0, 0)
//	TbWriteEnx =  2004	(-1, 0, 0, 0, -1, 0, -1, 0)
//	TbSelMd = 1002	(oldlc eq 2) % (oldlc eq 3)
//	RbSelMd = 10020	(oldlc & 2) eq 0
	    let clcstuff = table [
		32064B; 30060B; 1002B; 21042B; 12024B; 10020B; 2004B; 0
		] !oldlc
	    switchon oldFFfunc rshift 3 into
	    [
case 4B to 5B:		RbWadr = oldff & 17B; endcase
case 22B to 23B:	RbWadr<<nib2 = oldff xor 17B
			ChkRbWadr = 377B; endcase
case 30B to 33B:	cMBWriteEnx = 0
default:		endcase
	    ]
	    switchon oldFFfunc into
	      [
case 75B:	clcstuff = clcstuff % 1002B; endcase
case 76B:	cBCWriteEnx = -1; endcase
case 105B:
case 107B:
case 250B to 253B:
case 37B:	cMBWriteEnx = 0
default:	endcase
	    ]

	    Correct!dRTSB = (Correct!dRTSB & 144711B)+clcstuff
	    Correct>>P1.BCWriteEnx = cBCWriteEnx
	    Correct>>P1.MBWriteEnx = cMBWriteEnx
	    Correct>>P0.IOBoutSaved = OldDMuxTab>>P0.IOBout
	    Correct>>P1.RbWadr = (RbWadr & ChkRbWadr)+
		(DMuxTab>>P1.RbWadr & not ChkRbWadr)
	    Correct>>P0.CkMdParityx =
		((not oldgMD) % HoldDly) & ((not gMDI) % Hold)
	  ]

//**Beginning of simulation for signals clocked at T1**

	  let cT1Shiftx = T1asel ne 7
	  let cT1AmuxMd,cT1AmuxIFU,cT1AmuxSC = 0,0,0
	  let cT1AmuxQ,cT1AmuxT,cT1AmuxEnx = 0,0,not cT1Shiftx
	  let cT1MarMuxEn = 0
	  switchon T1asel into
	  [
case 5:		cT1AmuxIFU = -1; endcase
case 6:		cT1AmuxT = -1; endcase
case 2 to 3:	switchon (T1FFok ? T1ff rshift 6,3) into
		[ case 0: cT1AmuxMd = -1; endcase
		  case 1: cT1AmuxIFU = -1; endcase
		  case 2: cT1AmuxQ = -1; endcase
		  case 3: cT1AmuxT = -1; endcase
		]
case 0 to 1:	cT1MarMuxEn = -1
case 4:
case 7:		endcase
	  ]

	  let T1NextMacrox = not T1DTab>>P1.NextMacro
	  let cT1IOBout,cT1IOBinx = 0,-1
	  let cT1ShcWriteEnx,cT1TIOAWriteEnx = -1,-1
	  let cT1LdHoldSimx = -1
	  let cT1QshiftR = T1BExt & (T1bsel eq 3)
	  let cT1QshiftL = cT1QshiftR
	  let cT1ShiftBitsEnx = 4000B
	  let cT1Pmux,cT1MBMux = 0,0
	  let cT1RBaseWriteEnx = T1NextMacrox
	  let cT1BmuxEnx = 0
	  let T1F2 = T1FFfunc & 17B

//ALU simulation could be completed at Tn eq 0 except for the effects
//of ALU shifts and Carry20 (**muffle Carry20?**).
	  let lshiftmask,rshiftmask,alushiftbit = -1,-1,0
	  let aluCorrect,aluOverflow,aluCarryOut = nil,nil,nil
	  let aluArithmetic =
		SimALU(lv aluOverflow,lv aluCarryOut,lv aluCorrect,0)

	  if T1FFok do
	  [ switchon T1FFfunc rshift 3 into
	    [
case 0B to 1B:	cT1AmuxSC = -1
case 2B:	if T1FFfunc < 24B then cT1AmuxEnx = 0; endcase
case 12B:	cT1MarMuxEn = -1; endcase
case 16B to 17B:
		cT1BmuxEnx = 2004B; endcase
case 20B to 21B:
		cT1RBaseWriteEnx = 0; endcase
case 24B:	cT1TIOAWriteEnx = 0; endcase
case 27B:	cT1ShiftBitsEnx = 0
case 26B:	cT1Pmux = table [
		  0000B; 0000B; 2004B; 2004B
		  0401B; 0401B; 3006B; 3407B
		  1403B; 1403B; 1403B; 1403B
		  1002B; 1002B; 1002B; 1002B ] !T1F2
		endcase
case 30B to 33B:
		cT1MBMux = 1
default:	endcase
	    ]
	    switchon T1FFfunc into
	    [
case 21B:	cT1AmuxT = -1; endcase
case 22B:	cT1AmuxMd = -1; endcase
case 23B:	cT1AmuxQ = -1; endcase
case 26B:	SimALU(lv aluOverflow,lv aluCarryOut,lv aluCorrect,#20)
		endcase
case 36B:	cT1IOBout = 4010B; endcase
case 37B:	cT1MBMux = 2; endcase
case 73B:	cT1QshiftR = -1
case 150B:	cT1QshiftL = -1; endcase
case 151B:	cT1QshiftR = -1; endcase
case 106B to 107B:
		cT1RBaseWriteEnx = 0; endcase
case 152B:	cT1TIOAWriteEnx = 0; endcase
case 154B:	cT1LdHoldSimx = 0; endcase
case 155B to 157B:
		cT1ShcWriteEnx = 0; endcase
case 32B to 33B:
		cT1IOBinx,cT1Pmux = 0,2405B
case 271B:	alushiftbit = aluCorrect & 1; endcase	//rcy
case 72B:	cT1ShiftBitsEnx,cT1Pmux = 0,1403B	//multiply
		cT1QshiftR = -1
case 272B:	test aluArithmetic			//brsh
		ifso alushiftbit = aluCarryOut
		ifnot rshiftmask = 77777B; endcase
case 273B:						//arsh
case 275B:	alushiftbit = aluCorrect rshift 15	//lcy
		endcase
case 276B to 277B:
		cT1QshiftL = -1				//divide, cdivide
		lshiftmask = 177776B; endcase
case 250B to 253B:
		cT1MBMux = 3; endcase
default:	endcase
	    ]
	  ]

//Pmux encodings are:
//	0 ALU
//	1 0's mask Cnt, or Pointers
//	2 left shift
//	3 right shift
//	4 ALUFM
//	5 Input
//	6 TIOA&StkP
//	7 Shc
	  let Pmux = DMuxTab>>P0.Pmux
//If not a shift or if Pmux odd, can predict shmv without knowing ShC
	  let cSHMV = (Pmux & 1) ne 0
	  if cSHMV % (T1asel ne 7) do Correct!dSHMV = cSHMV
	  let CheckALU = -1
	  let shmv = DMuxTab!dSHMV
	  let alul1 = aluCorrect lshift 1
	  let alur1 = aluCorrect rshift 1
	  switchon Pmux into
	  [
case 0:		aluCorrect = aluCorrect & not shmv
//Can't check all the bits if MD shift is in progress.
		if (Tn < 2) % ((oldaluf ge 10B) & (oldasel eq 7B)) then
			CheckALU = not shmv
		endcase
//This simulates the hardware even when shmv is incorrect and for
//any kind of shift
case 2:		aluCorrect = ((alul1 & not shmv)+(alur1 & shmv)) %
			alushiftbit
		CheckALU = lshiftmask; endcase
case 3:		aluCorrect = alur1+(alushiftbit lshift 15)
		CheckALU = rshiftmask; endcase
default:	CheckALU = 0; endcase
	  ]
	  CheckALU = SimALU1(CheckALU)
	  Correct!dALUCON = (Correct!dALUCON & not CheckALU)+
		(CheckALU & SimALU1(aluCorrect))

//SimIfu computes MAR' when Tn eq 2 or the actual value of MAR' for Tn ne 2
	  test cT1MarMuxEn
	  ifso if cT1Shiftx then Correct!dMAR = not DMuxTab!dALUA
	  ifnot Correct!dMAR = cIfuMARvalx

	  let cT1Amux = (20040B & (cT1AmuxSC % cT1AmuxQ % cT1AmuxMd))+
	    (10020B & (cT1AmuxT % cT1AmuxQ %
		(cT1AmuxIFU & ((T1bsel & 3) ne 2))))
	  if (cT1Amux eq 20040B) & cT1AmuxSC then
		Correct!dALUA = (Correct!dALUA & not cT1Shiftx) % T1F2
	  let cT1Bmux = table [ 0; 401B; 1002B; 1403B; 0; 0; 0; 0 ] ! T1bsel
	  if T1bsel ge 4 do
	  [ let T1alub = (T1bsel & 1) ne 0 ? 177400B+T1ff,T1ff
	    test cT1Shiftx
	    ifso Correct!dALUB = T1bsel < 6 ? T1alub,LCycle(T1alub,10B)
	    ifnot cT1Bmux = 1403B
	  ]
//**Violate structures to save space here
	  Correct!dABCON = cT1Amux+cT1IOBout+cT1Bmux+cT1BmuxEnx+
		((((cT1Amux & 40B) ne 0) % not cT1MarMuxEn) & 100200B)+
		(cT1AmuxEnx & 40100B)

//ALUFWriteEn' filled in later
	  Correct!dQPDCON = ((not cT1QshiftL) & 100200B)+
	    ((not cT1QshiftR) & 40100B)+
	    (((cT1Pmux & 1) eq 0)&(((T1aluf & 4) eq 0)%cT1Shiftx)&20040B)+
	    ((cT1Shiftx % ((T1aluf & 2) eq 0)) & 10020B)+
	    cT1Pmux+cT1ShiftBitsEnx

	  Correct>>P0.IOBinx = cT1IOBinx
	  Correct>>P0.ShcWriteEnx = cT1ShcWriteEnx
	  Correct>>P0.LdHoldSimx = cT1LdHoldSimx
	  Correct>>P1.TIOAWriteEnx = cT1TIOAWriteEnx
	  Correct>>P1.MBMux = cT1MBMux
	  Correct>>P1.RBaseWriteEnx = cT1RBaseWriteEnx
	  Correct>>P1.StkPSaveEnx = T1NextMacrox % Hold
	  Correct>>P1.RBaseBypassx =
		not (cSelRBaseWadrx & (T1NextMacrox % Hold))
	]

//**Simulation of unclocked signals**

	let cShiftx,cAmuxIFU,cAmuxMd = -1,0,0
	switchon asel into
	[
case 5:		cAmuxIFU = -1; endcase
case 7:		cShiftx = 0
case 0:
case 1:
case 6:
case 4:		endcase
case 2:
case 3:		if FFok then switchon ff rshift 6 into
		[ case 0: cAmuxMd = -1; endcase
		  case 1: cAmuxIFU = -1
		  case 2 to 3: endcase
		]
		endcase
	]
	let cRisIFdata,cTisIFdata = 0,0
	if (bsel & 1) eq 0 then cRisIFdata = cAmuxIFU
	if (bsel & 3) ne 2 then cTisIFdata = cAmuxIFU

	let cLoadCntx,cTIOABypass = -1,0
	let cALUFWriteEnx,cReSchedWrEnx,cLdTaskSimx = -1,-1,-1
	let cStkSel = block & (not DMuxTab>>P0.EMUx)
	let cStkPWriteEnx = not cStkSel
	let cStkPMux1 = 0
	let cBumpRSTK,cBumpRBase = 0,0
	let cBExt = 0
	switchon FFfunc rshift 3 into
	[
case 4B to 5B:		cBumpRSTK = -1; endcase
case 16B to 17B:	cBExt = -1; endcase
case 22B to 23B:	cBumpRBase = -1; endcase
case 24B:		cTIOABypass = -1; endcase
case 25B:		if FFfunc ge 254B then endcase
case 30B to 33B:	cMBBypass = -1; endcase
case 34B to 35B:	cLoadCntx = 0
default:		endcase
	]
	let cgMDI = ((not cShiftx) & (aluf ge 10B)) %
		((bsel eq 0) & not cBExt) % cAmuxMd
	switchon FFfunc into
	[
case 22B:		cAmuxMd,cgMDI = -1,-1; endcase
case 34B:		cRisIFdata = -1; endcase
case 35B:		cTisIFdata = -1; endcase
case 37B:
case 105B:
case 107B:		cMBBypass = -1; endcase
case 132B to 133B:	cReSchedWrEnx = 0; endcase
case 145B:		cStkPMux1 = 1
case 144B:		cStkPWriteEnx = 0; endcase
case 146B:		cLoadCntx = 0; endcase
case 152B:		cTIOABypass = -1; endcase
case 154B:		cLdTaskSimx = 0; endcase
case 262B:		cALUFWriteEnx = 0
default:		endcase
	]

	Correct>>P1.FFokxb = not FFok
	Correct>>P1.RisIFdata = cRisIFdata
	Correct>>P1.TisIFdata = cTisIFdata
	Correct>>P1.NextDatax = (not cRisIFdata) & (not cTisIFdata)
	Correct>>P1.FFmem = (ff rshift 6) % (not FFok)
	Correct>>P1.gMDI = cgMDI
	Correct>>P1.gMD = table [ 0; 0; 1; 1; 1; 1; 0; 0 ] !lc
	Correct>>P1.BgExt = cBExt
	Correct!dPJUNK = MaskPut(Correct+dPJUNK,066377B)

	Correct>>C.bFFokxc = not FFok
	let cFAx = FFok ?
		table [ 7B; 13B; 15B; 16B ] !(FFfunc rshift 6),17B
	Correct>>C.FAeq01x = cFAx rshift 2

	Correct>>P0.FAx = cFAx
	Correct>>P0.Shiftx = cShiftx
	Correct>>P0.FFshiftx = cShiftx % (bsel < 4B)
	Correct>>P0.StkSela = cStkSel
	Correct>>P1.BumpRBase = cBumpRBase
	Correct>>P1.BumpRSTK = cBumpRSTK
	Correct>>P1.StkPMux1 = cStkPMux1
	Correct>>P1.StkPWriteEnx = cStkPWriteEnx
	Correct>>P0.LoadCntx = cLoadCntx
	Correct>>P0.ALUFWriteEnx = cALUFWriteEnx
	Correct>>P0.LdTaskSimx = cLdTaskSimx
	Correct>>P1.ReSchedWrEnx = cReSchedWrEnx
	Correct>>P1.TIOABypass = cTIOABypass & NoSwitchOrHold
	Correct>>P1.MBBypass = cMBBypass & NoSwitchOrHold
	if DMuxTab>>P0.DecCntx eq 1 then Correct>>P0.PropCntx = 1

	test DMuxTab>>P0.BmuxEnx ne 0
	ifso Correct!dALUB = not DMuxTab!dBMUX	//Ext bmux to int
	ifnot Correct!dBMUX = DMuxTab!dALUB	//Int bmux to ext

	if Tn ne 1 do
	[ let TbBypass = (not DMuxTab>>P0.LasteqCurrx) & (not HoldDly) &
		(not DMuxTab>>P1.TbWriteEnx) & (not cTisIFdata)
	  Correct!dRTSB = (TbBypass & 1) ne 0 ?
		Correct!dRTSB % 401B,Correct!dRTSB & 177376B
	]

	if HaveMemC do
	[ let T2StartMap =
		SimMemory(MemIfuTn,Correct,Tneven,DMuxTab>>P1.FFmem,
		asel,gMD,gMDI,T2RepeatCur,SWx,OldDMuxTab>>P1.FFmem,
		oldasel,oldgMD,oldgMDI,oldSWx,DMuxTab>>P0.gMDSaved ne 0,
		T1FFfunc,HoldReq,Hold,oldHold)
	  Correct>>C.bHoldA = Hold
	  Correct>>P0.Holda = Hold
	  SimMemX(MemIfuTn,Correct,T2DTab,T2StartMap,T1FFfunc)
	]

//Copy values computed for ProcL into equivalent bits for ProcH
	MaskPut(Correct+dPRFA,377B)
	MaskPut(Correct+dSCCON,110777B)

	let NWrong = 0
	for I = 0 to 177B do
	[ let Bad = (DMuxTab!I xor Correct!I) & DChecked!I
	  DWrong!I = Bad
	  while Bad ne 0 do	//Count 1's in Bad
	  [ NWrong = NWrong+1
	    Bad = Bad - (Bad & -Bad)
	  ]
	]
//d1simifu needs this to check for IFUM write in progress.
	oldoldFFfunc = oldFFfunc
	resultis NWrong
]


and MaskPut(Vec,Mask) be
[	rv Vec = ((rv Vec) & Mask)+(((rv Vec) lshift 8) & not Mask)
]


//Fill in Pdata00, 04, 08, and 12 of ALUCON for the selected table
and SimALU1(val) =
	(val & 100000B)+
	((val & 4000B) lshift 3)+
	((val & 200B) rshift 1)+
	((val & 10B) lshift 2)