//**************************************************************************************
//MEMA5.TST
//By B. Rosen and M. Thomson  						January 25, 1979
//Sub Test Program for D0 MEM Module
//**************************************************************************************
get "mema.d"

//Edge pin and test connector signal busses available to this sub-test:

//{CrctSyn: CrctSyn0,CrctSyn1,  CrctSyn2,CrctSyn3,CrctSyn4,  CrctSyn5,CrctSyn6,CrctSyn7}

//{Odata: Odata.00,  Odata.01,Odata.02,Odata.03,  Odata.04,Odata.05,Odata.06,  Odata.07,Odata.08,Odata.09,  Odata.10,Odata.11,Odata.12,  Odata.13,Odata.14,Odata.15}

//{StorDin: StorDin.00,  StorDin.01,StorDin.02,StorDin.03,  StorDin.04,StorDin.05,StorDin.06,  StorDin.07,StorDin.08,StorDin.09,  StorDin.10,StorDin.11,StorDin.12,  StorDin.13,StorDin.14,StorDin.15}

//{StorEcIn: StorEcIn.0,StorEcIn.1,  StorEcIn.2,StorEcIn.3,StorEcIn.4,  StorEcIn.5,StorEcIn.6,StorEcIn.7}

//**************************************************************************************
//Test 7: Test assorted logic indicated by sub-titles

let Test7() be
[
	SpeakTest(7) //set initial conditions (see notes at end of MEMA.TEST)

//Check the SXClock' logic (page 13) and the MemSetFault logic (page 20)

	for i = 0 to 3 do
	[
		{MC1SXport} = i<<w.b14
		{RamClockFeed'}=i; //RamClock←i[15]'
		WCompare({SXClock'},(#13 rshift i)&1,7000+i)

		{MC1SetFault} = i<<w.b14
		{MC2SetFault}=i
		WCompare({MemSetFault},(#16 rshift i)&1,7020+i)
	]

//Check the EnColAd' and clkOutputReg' logic (page 13)
//Check the Odata←Cdat' logic (page 20) and the GateALUParity logic (page 10)

	for i = 0 to 1 do
	[
		{PreRowAd'}=i
		{MC1ClkOutput}=i
		{preLoadOdata'}=i

		EClock() //EnColAd'←(PreRowAd'=i) (new rev. M logic)
		         //h5b ff←(MC1ClkOutput=i) (new rev. M logic)
		         //e2d ff←(preLoadOdata'=i)
		WCompare({EnColAd'},i,7050+i)
		WCompare({clkOutputReg'},i xor 1,7052+i) //inverted h5b ff output

		EClock() //Odata←Cdat' ←(e2d ff=i)
		WCompare({Odata←Cdat'},i,7054+i)

		EClock() //h2i ff←(Odata←Cdat'=i)
		EClock() //GateALUParity←(h2i ff=i)
		WCompare({GateALUParity},i,7056+i)
	]

	{preLoadOdata'}=0; //restore no normal

//Check the R←H3C' and R←H3U' logic (page 20)

	//{t7bus1: MC2NeedsR',  MC2XferWord,MC2WriteCdat,PStore12'}

	for i = 0 to 15 do
	[
		{t7bus1}=i; //MC2WillGetR←i[12]', others←i[13:15]
		EClock() //clkStartMC2': MC2PS12'←(PStore12'=i[15]) (pages 15,19)
		EClock() //set up R←H3C' and R←H3U' ff's
		WCompare({R←H3C'},(#177477 rshift i)&1,7060,i)
		WCompare({R←H3U'},(#177737 rshift i)&1,7061,i)
	]

//Check that AdvancePipe=0 inhibits clkStartMC2' (pages 14,19,20)

	{t7bus1}=4; //to normally disqualify R←H3U' set gate (a1b) (page 20)
	{MC1StartMC2}=0; //for AdvanvePipe←0 to inhibit clkStartMC2'
	EClock() //don't MC2PS12'←(PStore12'=0); MC2PS12' stays =1
	EClock() //R←H3U' ←0 since MC2PS12' stayed =1
	WCompare({R←H3U'},0,7062)

	{MC1StartMC2}=1; {MC2NeedsR'}=1; //restore no normal

//Check the H4SelIMux logic via StorOut.15' (pages 5,18)

	//IMux←Cdat=0 for IMux[0:15]←Idata[0:15]
	//Idata.15=0 for StorOut.15'←1 when H4SelIMux=1
	{R.15}=1;  //for StorOut.15'←0 when H4SelIMux=0

	//{t7bus2: MC2XferWord,PStore12',H4←IMux}

	for i = 0 to 7 do
	[
		{t7bus2} = i xor 4
		EClock() //MC2XferingWord'←(MC2XferWord'=i[13])
		EClock() //H4SelIMux=0 => H4.15←(R.15=1), hence StorOut.15'←0
		         //H4SelIMux=1 => H4.15←(IMux.15=Idata.15=0), hence StorOut.15'←1
		WCompare({StorOut.15'},(#250 rshift i)&1,7070,i)
	]

	{R.15}=###; //restore to normal

//Check the MC1Active' logic (page 16)

	//Existing conditions: MC2DisableMC1t'=1, LoadType'=0

	//{t7bus3: ALUF.0,ALUF.1,ALUF.2,  ALUF.3,preMC1Next.6,MC1StartMC2}

	for i = 0 to 6 do
	[
		{t7bus3} = #100 rshift i
		EClock() //clkMC1t': MC1Next[0:3]←ALUF[0:3]
		WCompare({MC1Active'},1 rshift i,7080+i)
	]
]

//**************************************************************************************
//Test 8: Test Error Check/Correct all the way through

and Test8() be
[
	SpeakTest(8) //set initial conditions (see notes at end of MEMA.TEST)

	Ws("*nTesting Error Check/Correct using random numbers...")
	Ws("*n")

	//Do 0, then -1, then 10 random quadwords

	let T = vec 4

	T!0,T!1,T!2,T!3 = 0,0,0,0
	DoChkTest(T)

	T!0,T!1,T!2,T!3 = -1,-1,-1,-1
	DoChkTest(T)

	for i = 0 to 9 do
	[
		T!0 = Random()
		T!1 = Random()
		T!2 = Random()
		T!3 = Random()
		DoChkTest(T)
	]
]


and DoChkTest(V) be
[
	//run quadword through without any errors, then with all single bit failures

	Ws("#")

	let inp = vec 32 //for FORMAT
	let str = vec 64 //for FORMAT
	let VV  = vec 4

	//this table represents the contributions to the syndrome bits for each of the 64 data bits

	let SynTab = table [
		#07;#206;#106;#307;  #46;#247;#147;#346;
		#26;#227;#127;#326;  #67;#266;#166;#367;
		#13;#212;#112;#313;  #52;#253;#153;#352;
		#32;#233;#133;#332;  #73;#272;#172;#373;
		#15;#214;#114;#315;  #54;#255;#155;#354;
		#34;#235;#135;#334;  #75;#274;#174;#375;
		#16;#217;#117;#316;  #57;#256;#156;#357;
		#37;#236;#136;#337;  #76;#277;#177;#376 ]

	let syndr = 0

	for i = 0 to 3 do

		for j = 0 to 15 do
		[
			let bitt = ((V!i) & (#100000 rshift j))
			if bitt then syndr = syndr xor SynTab!((i lshift 4)+j)
		]


	//Text ("inp") to be inserted in "FORMAT" preceding each "WCompt8" routine:
	FORMAT(inp,", Input=<B>,<B>,<B>,<B> syndr=<B>",V!0,V!1,V!2,V!3,syndr)

	{StorEcIn} = syndr
	{StorDin} = V!0

	{ChkPhase0'} = 0
	EClock() //Partial←(StorEcIn=Syndr), Udat←(StorDin=V!0)
	{ChkPhase0'} = 1

	{StorDin} = V!1
	EClock() //Buffer←(Udat=V!0), Udat←(StorDin=V!1)

	{StorDin} = V!2
	EClock() //Buffer←(Udat=V!1), Udat←(StorDin=V!2)

	{StorDin} = V!3
	EClock() //Buffer←(Udat=V!2), Udat←(StorDin=V!3)

	{LoadSyndrome} = 1
	EClock() //Buffer←(Udat=V!3), CrctSyn←ChkSyn
	{LoadSyndrome} = 0

	FORMAT(str,"without any errors<S>",inp)
	WCompt8("CrctSyn",{CrctSyn},0,str,8000)

	for i = 0 to 3 do
	[
		EClock() //Odata←Cdat
		FORMAT(str,"in word <B>,no errors<S>",i,inp)
		WCompt8("Odata",{Odata},V!i,str,8001)
	]

	for j = 0 to 63 do
	[
		for i = 0 to 3 do VV!i = V!i

		let wordInErr = j rshift 4
		VV!wordInErr = (V!wordInErr) xor (#100000 rshift (j&#17))

		{StorEcIn} = syndr
		{StorDin} = VV!0

		{ChkPhase0'} = 0
		EClock()
		{ChkPhase0'} = 1

		{StorDin} = VV!1
		EClock()

		{StorDin} = VV!2
		EClock()

		{StorDin} = VV!3
		EClock()

		{LoadSyndrome} = 1
		EClock()
		{LoadSyndrome} = 0

		if {CrctSyn} ne SynTab!j then
		[
			FORMAT(str,"with bit <B> wrong<S>",j,inp)
			WCompt8("CrctSyn",{CrctSyn},(SynTab!j),str,8002)
		]

		for i = 0 to 3 do
		[
			EClock() //Odata←Cdat

			if {Odata} ne V!i then
			[
				FORMAT(str,"word <B> with bit <B> wrong<S>",i,j,inp)
				WCompt8("Odata",{Odata},V!i,str,8003)
			]
		]
	]
]


//Special Wait-Comparison routine peculiar to this test
//	"ini" is the signal or bus name being compared to "sb"
//	"fin" is the text ("str") in the "FORMAT" preceding each "WCompt8"

and WCompt8(ini,was,sb,fin,testno) be
[
	if was eq sb then return

	Ws(FORMATN("*nTest <D>: <S> was <B>, should be <B> <S>",testno,ini,was,sb,fin))

	while Endofs(keys) do [  ]  
	Gets(keys)
	Ws("*nRunning...")
]