//**************************************************************************************
//ALU5.TST
//By F. Itami and M. Thomson  							January 29, 1979
//Sub Test Program for D0 ALU Module
//**************************************************************************************
get "alu.d"

//Edge pin signal busses used by ALU module:

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

//{aluf: ALUF.0,  ALUF.1,ALUF.2,ALUF.3}

//{clkbus: LT,LR,  Abort',LoadMIR,Cycle0Feed'}

//{CTask: CTask.0,  CTask.1,CTask.2,CTask.3}

//{F1F2: F1.0,F1.1,  F1.2,F1.3,F2.0,  F2.1,F2.2,F2.3}

//{H2: H2.08,H2.09,  H2.10,H2.11,H2.12,  H2.13,H2.14,H2.15}

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

//{MC1SA: BSEL.0,BSEL.1,  F1.0,F1.1,F1.2,  F1.3,LR,LT}

//{mcbus: MC1WriteR,  MC2AllowWrite,MC1NeedsR,MC2WillGetR}

//{mirbus: MemInst/d,MemInst/d',  RMOD/d,RMOD/d',RSEL.0/d',  RSEL.1/d',RSEL.2/d,RSEL.3/d,  RSEL.4/d,RSEL4and5/d,RSEL.5/d}

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

//{TA: TA.0,  TA.1,TA.2,TA.3}

//**************************************************************************************
//Test 14: Check the Stkp counting logic controlled by the b13 prom (page 11,12)

let Test14() be
[
	SpeakTest(14) //set initial conditions (see notes at end of ALU.TST)

	let t14aval = table [ 0;0;0;0;0;0;0;1; 0;0;0;1;0;0;0;0; 0;0;0;0;0;0;0;1; 0;0;0;1;0;0;0;0 ]

	let t14bval = table [ 2;2;2;2;3;5;5;6; 5;3;3;2;2;2;2;2; 2;2;2;2;2;2;2;2; 2;2;2;2;2;2;2;2 ]

	{MASK}=#375
	{mirbus}=#1547; //MemInst=0, RMOD=1, RSEL=00 00 11
	ClockMIR() //rbus←SStkp,,Stkp', Stkp←(ALUA=2)
	{Stkp←ALUA'}=1; //switch to count logic

	for i = 0 to 31 do
	[
		{aluf}=i; //ALUF[0:3]←i[12:15]
		{LT} = i rshift 4; //SRC/DEST=0' ← i[11]

		{MemInst/d}=1
		ClockMIR() //(Stkp←Stkp+0), set MemInst (enable b13 prom)
		WCompare({IOInst},t14aval!i,14000,i)

		{MemInst/d}=0
		ClockMIR() //Stkp←Stkp+count, reset MemInst
		           //rbus←SStkp,Stkp', WA←(RASAVE=0) since signal WA←preStkp =0

		WCompare((not {rbus})&#377,t14bval!i,14001,i)
		WCompare({RA=WAa},0,14102,i) //unequal since WA stays =0
	]
] 

//**************************************************************************************
//Test 15: Test the Memory Address Registers (StorA, etc.) (page 17)

and Test15() be
[
	SpeakTest(15) //set initial conditions (see notes at end of ALU.TST)

//{StorAbus: StorA0,  StorA1,StorA2,StorA3,  StorA4,StorA5,StorA6}
//{StorXbus: StorA6,MOBounds,  StorA0,StorA1,StorA2,  StorA3,StorA4,StorA5}

//NOTE: THE FOLLOWING FLIP-FLOPS TRIGGER ON THE LEADING EDGE OF EdgeClock:
//      EnMapRow', the c18c,c18d flip-flops, and the b15,b16 counter

//Test the b19 gates, the f18,h18 flip-flops and the b18 gates

	for i = 0 to 7 do
	[
		let a = 1 lshift i
		let data = ((not a) lshift 8) % a //left and right bytes are complements
		{rbus}=data

		{aluf}=9; //for ALUOUT="R+B" (ALUA+#000000+0: END CARRY =0)
		EClock() //H1←data, ALUF()←"R+B", c18c ff ←1
		ClockAd() //load f18,h18 from high byte, EnMapRow'←0
		WCompare({StorAbus},a&#177,15000+i) //b19 gates: ALUOUT[1:7]'=a[9:15]

		EClock() //EnMapRow'←1, c18c ff ←0
		//test: StorA6=ALUOUT.00'=a[8], MOBounds=R.01=a[9]', StorA[0:5]=R[2:7]'=a[10:15]
		WCompare({StorXbus},a xor #100,15010+i) //b18 gates, MOBounds

		{aluf}=12; //for ALUOUT="R-B" (ALUA+#177777+1: END CARRY =1)
		EClock() //H1←data, ALUF()←"R-B", c18c ff ←1
		ClockAd() //load f18,h18 from low byte, EnMapRow'←0

		EClock() //EnMapRow'←1, c18c ff ←0
		//test: StorA6=ALUOUT.00'=a[8], MOBounds=R.09=a[9], StorA[0:5]=R[10:15]'=a[10:15]'
		WCompare({StorXbus},a xor #77,15020+i) //b18 gates, MOBounds
	]

//Test that every bit of the column counter can be loaded
	{Refresh'}=0; //for counter msb ← ALUOUT.07'

	for i = 0 to 6 do
	[
		let a = 4 lshift i
		{rbus}=a
		{EnColAd'}=1; //for c18d ff ←1 (inactive state)
		ClockAd() //EnMapRow'←0, c18c ff ←1, c18d ff ←1, H1←a
		EClock()  //EnMapRow'←1, c18c ff ←0
		          //counter←(ALUOUT[7:13]=a[7:13]) xor #100
		{EnColAd'}=0; //for c18d ff ←0
		EClock()  //c18d ff ←0 for StorA[0:6]←counter', Enable counting 
		          //c18c ff ←1
		WCompare({StorAbus},(a rshift 2) xor #77,15100+i) //b17 gates
	]

//Now test the column counter increment function (counter=0 from above loop)

	for i = 1 to 128 do
	[
		EClock() //increment counter
		WCompare((not {StorAbus})&#177,i&#177,15200,i) //b17 gates
	]

//Now check that with Refresh'=1, the msb of the column counter gets 1 even if ALUOUT.07=1

	{Refresh'}=1; //counter msb ←1
	{EnColAd'}=1; //for c18d ff ←1 (inactive state)

	{rbus}=#400; //for ALUOUT.07=a[7]=1 (would clear counter msb if Refresh'=0)
	ClockAd() //EnMapRow'←0, c18d ff ←1, H1←#400
	EClock()  //EnMapRow'←1, c18c ff ←0, counter←#100
	{EnColAd'}=0; //for c18d ff ←0
	EClock()  //c18d ff ←0 for StorA[0:6]←counter' 
	          //c18c ff ←1
	WCompare({StorAbus},#77,15300)

]

//**************************************************************************************
//Test 16: Check SRC/DEST=0' logic on bottom of page 16
//         Test the MC1Ad:RA and MC2Ad:RA comparators (page 20)

let Test16() be
[
	SpeakTest(16) //set initial conditions (see notes at end of ALU.TST)

//{MC1/MC2Comp: MC1Compa,  MC1Compb,MC2Compa,MC2Compb}
//{MC1/MC2Compb: MC1Compb,MC2Compb}
//{MCQ/DWRef': MC1QWRef',  MC1DQWRef',MC2QWRef',MC2DQWRef'}

//Set up initial conditions

	{Cycle0Feed'}=1; //keep H1=#177777; all clocks are ClockCycle1
	{MemInst/d}=1
	ClockMIR() //MemInst←1 to enable b13 prom (page 11)
	{MemInst/d}=0; //for RSA,B←3,3 (RA←Stkp) for remainder of test
	               //(MemInst remains =1 since there will be no more ClockMIR's)

//Check SRC/DEST=0' logic on bottom of page 16
	
	WCompare({SRC/DEST=0'},1,16000)  //from SpeakTest
	{LT}=0
	WCompare({SRC/DEST=0'},0,16001)

	for i = 1 to 255 do
	[
		{MC1SA}=i
		WCompare({SRC/DEST=0'},1,16002,i)
	]

//Test the MC1Ad:RA and MC2Ad:RA comparators (page 20)

	ClockAd()  //MC1Ad←(MC1SA=#377), Stkp←(ALUA=#177777)
	ClockMC2() //MC2Ad←(MC1Ad=#377), MC2CAd[4:7]←(MC1Ad[4:7]=#17)
	WCompare({MC1/MC2Comp},#17,16400) //#377=#377

	for i = 0 to 3 do  //single "0" in field of 1's (in each hex digit)
	[
		{MASK}=#210 rshift i
		EClock() //Stkp←not(#210 rshift i)
		WCompare({MC1/MC2Comp},0,16410+i)
	]

	{MASK}=#177777
	EClock() //Stkp←(ALUA=0)

	{MC1SA}=0; //MC1Ad←Stkp since SRC/DEST=0
	ClockAd()  //MC1Ad←(Stkp=0)
	ClockMC2() //MC2Ad←(MC1Ad=0), MC2CAd[4:7]←(MC1Ad[4:7]=0)
	WCompare({MC1/MC2Comp},#17,16420) //0's=0's

	for i = 0 to 3 do  //single "1" in field of 0's (in each hex digit)
	[
		{MASK}=#7567 rshift i
		EClock() //Stkp←(#210 rshift i)
		WCompare({MC1/MC2Comp},0,16430+i)
	]

	//Check the {MCQ/DWRef'} input edgepins (MC1Ad=MC2Ad=0 from above)

	{MASK}=#374
	EClock() //Stkp←(ALUA=3)
	WCompare({MC1/MC2Compb},0,16440) //3's#0's

	{MCQ/DWRef'}=0; //override bits[6:7] compare
	WCompare({MC1/MC2Compb},3,16441) //3's appear = 0's
	{MCQ/DWRef'}=#17; //restore to normal

	//Check the equality cases not tested above
	//Check the MC1Ad[0:3]←CTask[0:3] path

	for i = 1 to 15 do //avoid SRC/DEST=0 case
	[
		let a = (i lshift 4) %i
		{MASK} = not a
		{CTask}=i; //for MC1Ad[0:3]
		{MC1SA}=i; //for MC1Ad[4:7]
		ClockAd()  //MC1Ad←a, Stkp←a
		ClockMC2() //MC2Ad←a, MC2CAd[4:7]←(MC1Ad[4:7]=i)
		WCompare({MC1/MC2Comp},#17,16500,i)
	]


//************************
//SPECIAL TEST FOR CHECKING StorA bus INTERFERENCE WITH Cycle0Feed', etc.
//(Delete when testers modified)
//STATUS: H1=-1, H2=0, Cycle0=0, MemInst=1

//WILL PROBABLY FAIL 16808 due to transients from the StorA bus interfering with Cycle0Feed', producing a false ClockCycle0 directly after the LEADING edge of ClockMC2.  This results in clocking H1←(rbus=R) and H2←(T=-1),  destroying their contents (of -1 and 0 respectively).

	{CTask}=0; //resume MC1SA control of MC1Ad[0:3]
	{MC1SA}=1; //for F1F2=0, but SRC/DEST#0 (LT=1)

	//raise the 9 to #77777 for SCOPING **********
	for j = 0 to 9 do
	[

	for i = 6 to 10 do
	[
		{MASK} = not (i lshift 4)

		{CTask}=i; //USE CTask.0 (a18.01) FOR POSITIVE SCOPE SYNC. and OBSERVE Cycle0Feed', Cycle0, clkCycle0'a.  THE INTERFERENCE SHOULD BE SEEN DURING ClockMC2 WHEN H2.12 (and others) GETS ILLEGALLY RESET BY A clkCycle0'a THAT SHOULDN'T EXIST.

		ClockAd()  //MC1Ad[0:3]←i, Stkp[0:3]←i
		ClockMC2() //MC2Ad[0:3]←i, TROUBLE IS HERE WHEN i=8

		{MASK}=0; //TO LOOK AT ALL OF H1 on ALUA

		//PUT "//" IN FRONT OF WCompare FOR SCOPING **********
		WCompare({ALUA},-1,16800+i) //if not -1, contains contents of R file (address from Stkp = i lshift 4). (H1=#73567 when failure is on test 16808; #73567 = hex 7777, which was stored in R (RA=hex 80) by TEST 7.)

		WCompare({H2},0,16820+i) //always fails when above fails

		{MASK} = not (i lshift 4); //it won't fail without this nonsense entry!!

		//restore H1←-1, H2←0's
		ClockMIR() //MemInst←0
		{Cycle0Feed'}=0
		{rbus}=-1
		EClock() //H1←-1, H2←0's
		{rbus}=###
		{Cycle0Feed'}=1
		{MemInst/d}=1
		ClockMIR() //MemInst←1
		{MemInst/d}=0
		EClock() //RSA,B←3,3(RA←Stkp) for rbus←R

		//excite StorA bus, restoring to prior values
		let a = i-1
		{MASK} = not (a lshift 4)
		{CTask}=a
		ClockAd()  //MC1Ad[0:3]←a, Stkp[0:3]←a
		ClockMC2() //MC2Ad[0:3]←a
		//WCompare({ALUA},a lshift 4,16840+i) //never fails
	]

	]
]