//**************************************************************************************
//ALU1.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 1: Check initial conditions and the Suspend flip-flop control

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

//Repeat the SpeakTest initialization sequence with WCompares monitoring the process.
//See SpeakTest (in ALU.TST) for all input edge-pin signals (not redundantly entered here)
//The "//WCompares" are optional breakpoints. To activate, delete the leading "//".  Restore to normal by re-inserting "//".

	{clkbus}=#27; //LT=1, LR=0, Abort'=1, LoadMIR=1, Cycle0=0
	{aluf}=3; //for prom f2 outputs = 1111 (page 16)
	{LoadAd'}=0; //for MC1XferWord←1, MC1XWdly←1
	{EdgeClockFeed'}=0
	//WCompare(1,0,1000)
	{EdgeClockFeed'}=1; //load MIR with MemInst=0, RMOD=1, RSEL=01 11 11 for R←NBR (i.e. open Cycle0 R bus sources), Suspend←0, AbortDly'←1, MC1XferWord←1, MC1XWdly←1
	WCompare({Suspend-a},0,1001)
	WCompare({MemInst-a},0,1002)

	{clkbus}=#24; //LT=1, LR=0, Abort'=1, LoadMIR=0, Cycle0=1
	WCompare({EnableR},0,1004) //check test-clip b6.6
	WCompare({R←NBR'},0,1005)
 	{ALUF.2}=0; //makes {aluf}=1 for ALUOUT←ALUA.IN
	{LoadAd'}=1; //de-activate
	{AdvancePipe'}=0; //for MC2XferWord←1, MC2XWdly←1

	{EdgeClockFeed'}=0
	//WCompare(1,0,1006)
	{EdgeClockFeed'}=1; //reset cycler/masker bypass flip-flop, H2←(F1F2=0) (i.e. H2'←#177777), ALUF()←1 for ALUOUT←(ALUA.IN=ALUA), MC2XferWord←1, MC2XWdly←1
	WCompare({H2},0,1007)
	WCompare({MC2XferWord},1,1008)

	{Cycle0Feed'}=1; //Cycle0=0
	{MASK}=#177777; //ALUA←0's
	WCompare({ALUA},0,1009)
	{EdgeClockFeed'}=0
	//WCompare(1,0,1010)
	{EdgeClockFeed'}=1; //Stkp←(ALUA=0), RSA,B←3,3(Stkp), TComing←1, TWPending←1, RComing←0, RWPending←0

	{Cycle0Feed'}=0; //Cycle0=1	
	{rbus}=#177777
	{EdgeClockFeed'}=0
	WCompare({clkH3P'},0,1011) //check test-clip d7.12
	//WCompare(1,0,1012)
	{EdgeClockFeed'}=1; //H1←(rbus=#177777), H3P←(ALUOUT=ALUA.IN=ALUA=0), RASAVE←RA←(Stkp=0), reset EnableMask (i.e. route ALUB←H2)

	{rbus}=###
	{Cycle0Feed'}=1; //Cycle0=0
	WCompare({rbus},0,1013) //rbus←H3P
	{SALUF←H2'}=0
	{EdgeClockFeed'}=0
	//WCompare(1,0,1014)
	{EdgeClockFeed'}=1; //SALUF←(H2[8:15]=0) (includes MA',MB), WA←(RASAVE=0), RSA,B←3,3(Stkp), SStkp←(Stkp=0)

	{Cycle0Feed'}=0; //Cycle0=1
	{SALUF←H2'}=1; //keep SALUF=0
	{MASK}=0; //ALUA←(H1=#177777)

//Additional check of the SpeakTest initialization sequence

	//Edge connector signals:
	WCompare({Suspend-a},0,1020)
	WCompare({R←NBR'},0,1021)
	WCompare({H2},0,1022)
	WCompare({ALUA},#177777,1023)
	WCompare({SRC/DEST=0'},1,1024)

	//Test connector signals (tester socket "B" to test-clips):
	WCompare({EnableR},0,1030)       //pin 1 to test-clip b6.6
	WCompare({clkH3P'},1,1031)       //pin 2 to test-clip d7.12
	WCompare({RWriteStrobe'},1,1032) //pin 3 to test-clip c7.11
	WCompare({TWriteStrobe'},1,1033) //pin 4 to test-clip c7.6
	WCompare({RA=WAa},1,1034)        //pin 5 to test-clip d10.12
	WCompare({RA=WAb},1,1035)        //pin 6 to test-clip d10.10

	//registers displayable on R bus:
	{Stkp←ALUA'}=1; //keep Stkp=0
	{mirbus}=#1547; //MemInst=0, RMOD=1, RSEL=00 00 11
	ClockMIR() //rbus←SStkp,Stkp'
	WCompare({rbus},#377,1040)

	{mirbus}=#1557; //MemInst=0, RMOD=1, RSEL=00 01 11
	ClockMIR() //rbus[8:15] ← not(MA',MB,SALUF[0:5])
	WCompare({rbus}&#377,#377,1041)

//Test the Suspend flip-flop (page 13) and the MemNeedsR gates (page 16)
	//Suspend/d = MemNeedsR = MC1NeedsR.MC1XferWord + MC2WillGetR.MC2XferWord

	//prom f2 (page 16) contols MC1XferWord; ALUF.2 contols prom f2:
		//ALUF.2=0 will mean prom address = 1100 1010 (ouput = 0011)
		//ALUF.2=1 will mean prom address = 1100 1110 (ouput = 1111)
		//hence, MC1XferWord will follow ALUF.2

	//{MemNeedsRbus: ALUF.2,MC1NeedsR,MC2WillGetR}

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

	//Verify condition of signals resulting from SpeakTest
	WCompare({MC2XferWord},1,1101)

	{Cycle0Feed'}=1; //keep H2=0 and H1=-1 for prom f2 address = 1100 1x10
	{LoadAd'}=0; //all clocks in loop will cause MC1XferWord←ALUA.2

	for i = 0 to 15 do
	[
		{MemNeedsRbus}=i
		EClock() //MC1XferWord←(ALUF.2=i[13])

		{ALUF.2} = i rshift 3
		ClockMC2() //MC2XferWord←(MC1XferWord=i[13])
		           //MC1XferWord←(ALUF.2=i[12])
		WCompare({MC2XferWord},(i rshift 2)&1,1103,i)

		//Status: (MC1XferWord,MC2XferWord,MC1NeedsR,MC2WillGetR)=i
		EClock() //Suspend←MemNeedsR
		WCompare({Suspend-a},t1sb!i,1105,i)
	]

	//Check that RUN=0 D.C. resets Suspend
	{RUN}=0
	WCompare({Suspend-a},0,1006) //DC reset
	{RUN}=1; //return to normal
	WCompare({Suspend-a},0,1007) //should remain reset
]

//**************************************************************************************
//Test 2: Check all outputs generated on page 19.
//        The test sends all possible values of the inputs
//        and calculates what the result should be.

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

	//{t2drive: MC1NeedsR,  Cycle0Feed',MemInst/d,RMOD/d,  RSEL.0/d',RSEL.1/d',RSEL.2/d,  RSEL.3/d,RSEL.4/d,RSEL.5/d}

	//{t2out: MemInst-a,  R←NBR',R←DBSB',R←PCXF',  R←SpareR',ReadErrors',ReadSyn',  EnCtrlAuxRa,EnCtrlAuxRb,RSEL-Parity}

	for i = 0 to #1777 do
	[
		{t2drive}=i

		//set values which are combinatorial functions of other inputs
		{RSEL4and5/d} = i<<w.b14 & i<<w.b15
		{RMOD/d'} = not i<<w.b9
		{MemInst/d'} = not i<<w.b8

		ClockMIR() //Load MIR, Suspend←MC1NeedsR
		WCompare({t2out},t2sb(i),2000,i)
	]
]


and t2sb(i) = valof
[
	let suspendprime = not i<<w.b6
	let d16enabled = (i<<w.b9 & i<<w.b14 & i<<w.b15) & i<<w.b10 & ((not i<<w.b8) & suspendprime & (not i<<w.b7))
	let rsel123 = ((i rshift 2) xor 4) & 7
	let sb = 0

	sb<<w.b6  = i<<w.b8 //MemInst-a
	sb<<w.b7  = (d16enabled & (rsel123 eq 7))? 0,1 //R←NBR'
	sb<<w.b8  = (d16enabled & (rsel123 eq 6))? 0,1 //R←DBSB'
	sb<<w.b9  = (d16enabled & (rsel123 eq 5))? 0,1 //R←PCXF'
	sb<<w.b10 = (d16enabled & (rsel123 eq 4))? 0,1 //R←SpareR'
	sb<<w.b11 = (d16enabled & (rsel123 eq 3))? 0,1 //ReadErrors'
	sb<<w.b12 = (d16enabled & (rsel123 eq 2))? 0,1 //ReadSyn'
	sb<<w.b13 = (not i<<w.b8) & suspendprime & i<<w.b14 & i<<w.b15 //EnCtrlAuxRa
	sb<<w.b14 = i<<w.b9 & (not i<<w.b10) & i<<w.b11 //EnCtrlAuxRb
	sb<<w.b15 = i<<w.b8 xor i<<w.b9 xor i<<w.b10 xor i<<w.b11 xor i<<w.b14 xor i<<w.b15 //c17 output

	resultis sb
]

//**************************************************************************************
//Test 3: Test EnableR when MC2WritingR' is inactive (high) (page 6)
//        MC2WritingR = MC2HasR.MC2AllowWrite.MC2XWdly = 00x for this test
//        (For MC2WritingR' active cases, see Test 4)

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

	//{t3drive: MemInst/d,RMOD/d',  MC1WriteR,MC1NeedsR,Cycle0Feed',  RSEL.0/d',RSEL.1/d',RSEL4and5/d}

	for i = 0 to #377 do
	[
		{t3drive}=i
		ClockMIR()
		WCompare({EnableR},t3sb(i),3000,i)
	]
]


and t3sb(i) = valof
[
	let suspendprime = not i<<w.b11
	let GoCycle0 = suspendprime & (not i<<w.b12)
	let EnAuxR = (not i<<w.b9) & i<<w.b15

	let EnableR = (GoCycle0 & (not i<<w.b13) & (not i<<w.b14)) % ((not i<<w.b10) & (not suspendprime)) % (GoCycle0 & (not EnAuxR)) % (i<<w.b8 & suspendprime)

	resultis EnableR & 1
]

//**************************************************************************************
//Test 4: Test the R and T Write Strobes and clkH3P' (pages 6,15)
//        Test EnableR (page 6) when MC2WritingR' is active
//        Test EnableRDlyd2 (page 18). (CheckRParity'=0)

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

	//{t4drive: RamClockFeed',Cycle0Feed',  MC1WriteR,MC1NeedsR,MemInst/d,  Abort',LR,LT}

//PART 1: Test the MC2WritingR' gate (page 16). (Input to RWrite and EnableR)
//        MC2WritingR = MC2HasR.MC2AllowWrite.MC2XWdly

	//ALUF.2 addresses prom f2 which contols MC1XferWord and MC1XWdly (page 16):
		//ALUF.2=0 will mean prom address = 1100 1010 (ouput = 0011)
		//ALUF.2=1 will mean prom address = 1100 1110 (ouput = 1111)
		//hence: MC1XferWord, MC2XferWord and MC2XWdly will follow ALUF.2

	//{t4MC2bus: MC2WillGetR,MC2AllowWrite,ALUF.2}

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

	{t4drive}=#125; //for: RamClock=1 (enable RWriteStrobe'), Cycle0=0 (keeps H1=-1, H2=0),
	            //MC1WriteR=0, MC1NeedsR=1 (for set Suspend), SRC/DEST=0' =1 (for f2 prom)

	{LoadAd'}=0; //all clocks to the end of TEST 4 will cause MC1XferWord←ALUF.2

	for i = 0 to 8 do //(MC2HasR,MC2AllowWrite,MC2XWdly)←i[13:15]
	[
		{t4MC2bus} = i
		EClock() //MC1XferWord←(ALUF.2=i[15]), MC1XWdly←(prom f2, pin 9 =1)

		{ALUF.2}=1
		ClockMC2() //MC2XferWord←(MC1XferWord=i[15])
		           //MC1XferWord←(ALUF.2=1) (for Suspend←1)
		WCompare({MC2XferWord},i&1,4040+i)

		ClockMC2() //MC2XWdly←(MC2XferWord=i[15]) (effective revision-J)
		           //h2.15 ff ←(MC1XWdly=1)
		               //(MC2XWdly WAS the h2.15 ff (=1) before revision-J) 
		           //MC2XferWord←(MC1XferWord=1) (don't care) 
		           //Suspend←1 (since MC1NeedsR=1 and MC1XferWord=1)
		           //MC2HasR←(MC2WillGetR=i[13])

		WCompare({RWriteStrobe'},t4sb!i,4060+i)
		WCompare({EnableR},t4sb!i,4080+i)

		EClock() //c16b ff ← EnableR' (Page 16)
		EClock() //EnableRDlyd2 ← (not c16b ff).(CheckRParity=1)
		WCompare({EnableRDlyd2},t4sb!i,4100+i)
	]


//PART 2: Test all cases in which MC2WritingR' remains high (inactive since inputs =000)

	let t4dval = table [
	  #105;#004;#106;#004;  #103;#047;#117;#014;  #104;#114;#107;#127;  #024;#104;#307 ]

	//internal signals: RComing',TComing',  (RComing+TComing),RWPending,TWPending
	// #25; #25; #16; #16;   #30; #30; #07; #33;   #33; #30; #30; #07;   #07; #07; #07

	//{t4out: Suspend-a,MemInst-a,  clkH3P',RWriteStrobe',TWriteStrobe'}

	let t4outval = table [
	   #06; #03; #05; #03;   #07; #05; #17; #17;   #04; #17; #07; #27;   #27; #04; #07 ]

	//Note: since ALUF.2=1, the prom f2 address = xxxx x1x0 for output = 1111,
	//and since LoadAd'=0, all clocks will cause MC1XferWord←1,
	//hence, Suspend←1 when MC1NeedsR=1

	{LoadMIR}=1; //for MemInst←MemInst/d when Cycle0=0
	{MC1NeedsR}=0
	EClock() //Suspend←0, MC1XferWord←1 (for Suspend control)

	for i = 0 to 14 do
	[
		{t4drive}=t4dval!i
		EClock() //load control flip-flops
		{EdgeClockFeed'}=0; //for observe clkH3P'
		WCompare({t4out},t4outval!i,4200+i,t4dval!i)
		{EdgeClockFeed'}=1; //return to normal
	]
]