// D1Prin4.bcpl -- DWrong print routine
//	Last edited: 4 May 1980

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

external [
// OS
	Puts

// MASM
	Wss; ResetsCSS; ResetsCS1

// MIOC
	Wns

// MCMD
	@WssCSS; WnsCSSD; WssCS1; CmdCommentStream; CmdCS1

// D1I0
	DWrong

// D1PRIN4ASM1
	DWPtab	//For DMux addresses 0 to 57B

// D1PRIN4ASM2
	DWPtab1	//For DMux addresses 60B to 144B

// D1PRIN4ASM3
	DWPtab2	//For DMux addresses 160B to 175B

// Defined here
	PrintDWrong; PrinDMww
]


// Subroutine to print bad bits in DWrong
let PrintDWrong() be
[	let ECSS,ECS1 = 1,0
	ResetsCSS(); ResetsCS1(); WssCSS("Errors:")
	for I = 0 to DMUXlen - 1 do
	[ let W = DWrong!I
	  if W ne 0 do
	  [ PrinDMww(I,W,lv ECSS,lv ECS1,true)
	  ]
	]
]

//DMux signal name strings are pointed to by self-relative pointers
//in DWPtab or DWPtab1 tables.  For isolated signals, the self-relative
//pointer in the table is to a string; for signal groups like
//"FOO.1", "FOO.2", ..., "FOO.n" the thing pointed at is another
//self-relative pointer back to "FOO.0".
//ECSS and ECS1 are counters of the number of names printed on
//each of the comment lines.
and PrinDMww(Addr,Val,lvECSS,lvECS1,PrintModule) be
[	let DAddr = Addr lshift 4
	let Tabl = DWPtab
//Above 175B there are only counters, which aren't printed this way.
	if Addr > 175B then return
	if Addr ge 60B then
	  test Addr le dRESON
	  ifso
	  [ Tabl = DWPtab1; Addr = Addr-60B
	  ]
	  ifnot
	  [ Tabl = DWPtab2; Addr = Addr-dTEMP
	  ]
//Note that Addr is negative for addresses 145B to 157B, currently unused.
	let X = Tabl+(Addr lshift 4)
	let Bit = 100000B
	for I = 0 to 17B do
	[ if (Val & Bit) ne 0 do
	  [ let P,S = X+I,nil
	    test (rv lvECSS) ge 6
	    ifso test (rv lvECS1) ge 6
	      ifso return
	      ifnot
	      [ S = CmdCS1; rv lvECS1 = (rv lvECS1)+1
	      ]
	    ifnot
	    [ S = CmdCommentStream; rv lvECSS = (rv lvECSS)+1
	    ]
	    Puts(S,$ )
	    test (Addr < 0) % (P!0 eq 0)	//Table entry 0 = no name
	    ifso
	    [ Wns(S,DAddr+I,0,8)
	    ]
	    ifnot test rv(P+P!0) ge 200B	//Point at a string?
	      ifso Wss(S,P+P!0)
	      ifnot
	      [ Wss(S,P+P!0+1); Wns(S,-P!0-(rv(P+P!0)),0,10)
	      ]
	    let Z,TermCh = DAddr+I,nil
//This is the code I would like, but it doesn't compile
//	    TermCh = selecton Z into
//	    [
//	case 0B to 117B:	$A	//ContA
//	case 120B to 177B:	$B	//ContB
//	case 200B to 237B:	$A
//	case 240B to 257B:	$B
//	case 260B to 377B:	$A
//	case 400B to 777B:	(I ge 10B ? $L,$H)
//	case 1000B to 1177B:	$C	//MemC
//	case 1200B to 1357B:	$D	//MemD
//	case 1360B to 1374B:	$C
//	case 1375B to 1777B:	$X	//MemX
//	case 2000B to 2117B:	$K	//Disk control
//	case 2120B to 2177B:	$E	//Ethernet
//	case 2200B to 2377B:	$Z	//Baseboard
//	case 2400B to 2777B:	$I	//IFU & junk io
//	case 3000B to 3377B:	$V	//Display control
//	case 3400B:		$B	//Temperature stuff
//	case 3401B:		$Z
//	case 3402B:		$H
//	case 3403B:		$L
//	case 3404B:		$I
//	case 3420B to 3457B:	$C	//AAD and MEMB
//	3460B to 3517B are BMUX and ESTAT from direct readouts
//	case 3540B to 3543B:	$B	//MIR stuff divided between A and B
//	case 3544B to 3547B:	$A
//	case 3550B to 3563B:	$B
//	case 3564B to 3567B:	$A
//	case 3570B to 3603B:	$B
//	case 3604B to 3610B:	$A
//	case 3620B to 3623B:	$B
//	case 3624B to 3637B:	$A
//	case 3640B to 3737B:	$B	//IMOUT
//	default:		0
//	    ]
//So this ugly code is used instead
	    TermCh = Z < 2000B ?
	      (Z < 1000B ?
		//0 to 777B
		(Z < 400B ?
		  ((Z < 120B) % (Z ge 260B) ? $A,
		    (((Z < 200B) % (Z > 237B)) ? $B,$A)
		  ),(I ge 10B ? $L,$H)
		),
		//1000B to 1777B
		(Z < 1200B ? $C,
		  (Z < 1360B ? $D,(Z < 1375B ? $C,$X))
		)
	      ),
	      //2000 up
	      (Z < 2400B ?
		//2000B to 2377B
		(Z < 2200B ? (Z < 2120B ? $K,$E),$Z),
		//2400B up
		(Z < 3400B ? (Z < 3000B ? $I,$V),
		  (Z < 3420B ? table [ $B; $Z; $H; $L; $I; 0; 0; 0;
				0; 0; 0; 0; 0; 0; 0; 0 ] ! (Z-3400B),
		    //3420 up
		    (Z < 3460B ? $C,
		      //3460 up
		      (Z < 3540B ? 0,
			//3540 up
			(Z < 3570B ?
			  //3540 to 3567
			  (Z < 3550B ?
			    (Z < 3544B ? $B,$A),
			    (Z < 3564B ? $B,$A)
			  ),
			  //3570 up
			  (Z < 3620B ?
			    (Z < 3604B ? $B,$A),
			    (Z < 3624B ? $B,(Z < 3640B ? $A,$B))
			  )
			)
		      )
		    )
		  )
		)
	      )
	    if (TermCh ne 0) & PrintModule do
	    [ Puts(S,$/); Puts(S,TermCh)
	    ]
	  ]
	  Bit = Bit rshift 1
	]
]