
/************************************************************************
*									*
*			"d86l1.c"  (was "d8600a.c")			*
*									*
*			Diagnostic code for the KIWI (8600)		*
*									*
*	12-05-84....original, based on diag1.c.......J.Middleton	*
*	12-27-84....added offline tag test...........J.Middleton	*
*	01-02-85....added udc static test............J.Middleton	*
*	01-11-85....added operational ucode load.....J.Middleton	*
*	01-25-85....added manual IV read/write.......J.Middleton	*
*	02-13-85....initial selection test...........J.Middleton	*
*	03-13-85....valid addr, parity , offline tst.J.Middleton	*
*	04-11-85....mods to initial selection tests..J.Middleton	*
*	04-30-85....add request in, reset tests......J.Middleton	*
*	05-10-85....dma read test....................J.Middleton	*
*	07-11-85....added dma tests..................J.Middleton	*
*	09-18-85....change for parity clock hw fix.........J.Middleton	*
*	10-22-85....fixes to dmawr, added var buff adr.....J.Middleton	*
*	12-13-85....added loopback cable test..............J.Middleton  *
*	02-17-86....lbx dma tests..........................J.Middleton	*
*	04-03-86....swap ucode & mdiag buffers.............J.Middleton	*
*	04-04-86....split up to smaller files..............J.Middleton	*
*									*
*************************************************************************
*/
#include "diag.h"
#include "kiwi.h"
#include "rabits.h"

short	tstWord, actWord, csAdEr;
short	tstLoc;

extern cssize;

/*------------------------------------------------------------------*/
/* Register Array Test - tests the register array by calling 
   a second routine which does the real testing.  ratst is just
   the shell of the loop and handles the errors.
*/
ratst()
{
	if (level != 1) {
		xprintf("\n\07WARNING - 8x305 is operational.");
	}

	display(0);
	getCnt();
	while (lpCnt--) {	
		currTst(E30);

		if (verRa() != 0) 
			raErr();	/* process reg array error */
		if (ratstpat(0xaaaa) == ERROR) {
			rweMsg(E30, tstWord, actWord);
			return FAIL;
		}
		else if (ratstpat(0x5555) == ERROR) {
			rweMsg(E30, tstWord, actWord);
			return FAIL;
		}
		else 
			passTst;
	}
	return PASS;
}

/*------------------------------------------------------------------*/
/* Master Control Register test - tests the master control register
   by calling mcregtst(), where the actual bit by bit testing takes 
   place */
mctst()
{
	display(0);
	level = 1;		/* this test forces to level 1 */
	getCnt();

	while (lpCnt--) {	
		currTst(E31);

		if (verMc() != 0) {
			if (vreg->mc == 0x80) {
				vErrMsg(E31, E11, E15);
				return FAIL;
			}

			if (vreg->mc == 0x81) {
				vErrMsg(E31, E11, E16);
				return FAIL;
			}
		}

		if (mcregtst() == ERROR) {
			rbeMsg(E31, tstByte, actByte);
			return FAIL;
		}

		else
			passTst;
	}
	return PASS;
}
/*------------------------------------------------------------------*/
/* Control Store Test - the Master Control Register is used in this test */ 
   
cstst()
{
	display(0);
	getCnt();

	while (lpCnt--) {	

		currTst(E38);

		if (verDld() != 0) {
			dldErr();
			return FAIL;
		}

		if (loadtst(0) == ERROR)  {
			ldErr();
			return FAIL;
		}
	
		else 
			passTst;
	}
	xprintf("\nControl store size: %1x K words.", cssize);
	return PASS;
}

/*------------------------------------------------------------------*/
ldErr()
{
	xprintf("\n\07ERROR at addr %4x.  Test val %4x, actual val %4x", csAdEr, actWord, tstWord);
}
/*------------------------------------------------------------------*/
/* Programmable Interrupt Controller test */
pictst()
{
	display(0);
	getCnt();

	while (lpCnt--) {	
		currTst(E36);

		if (verPic() != 0) {
			picErr();
			return FAIL;
		}

		if (!tst8259() == ERROR)  {
			rbeMsg(E31, tstByte, actByte);
			return FAIL;
		}

		passTst; 
	}
	return PASS;
}
/*------------------------------------------------------------------*/
/* test the hex display on the front panel */
dspTst()
{	
	unsigned char value;

	currTst(E47);

	value = 0;
	display(value);
	xprintf("\nVerify display shows a hex %2x", value);
	gets(buffer);

	value = 1;
	while (value != 0) {
		display(value);
		xprintf("\nVerify display shows a hex %2x", value);
		gets(buffer);
		value += value;
	}

	value = 0xff;
	display(value);
	xprintf("\nVerify display shows a hex %2x", value);
	gets(buffer);
	passTst;
}
/*------------------------------------------------------------------*/
/*	See if the KIWI I/O registers all respond.  Tests 
	XACK generation, address decode FPLA's.			*/

verio()
{
	unsigned char	i;
	unsigned char v;

	display(0);
	level = 1;		/* forces to level 1 */
	getCnt();

	while (lpCnt--) {	
		currTst(E37);
		v = TRUE;

	/*  Zero the valid register structure */
		i = 7;
		while (i > 0)
			vreg->ra.w[i--] = 0;
		vreg->mc = 0;
		vreg->dsp = 0;
		vreg->obus = 0;
		vreg->otag = 0;
		vreg->dwld.w = 0;
		vreg->pic1 = 0;
		vreg->pic2 = 0;

		display(0xf0);
		if (verRa() != 0) {
			raErr();	/* process reg array error */
			v = FALSE;
			}

		display(0x10);
		if (verMc() != 0) {
			if (vreg->mc == 0x80)
				vErrMsg(E31, E11, E15);
			if (vreg->mc == 0x81)
				vErrMsg(E31, E11, E16);
			v = FALSE;
			}

		display(0x11);
		if (verDsp() != 0) {
			if (vreg->dsp == 0x80)
				vErrMsg(E32, E11, E15);
			if (vreg->dsp == 0x81)
				vErrMsg(E32, E11, E16);
			v = FALSE;
			}

		display(0x12);
		if (verObus() != 0) {
			if (vreg->obus == 0x80)
				vErrMsg(E33, E11, E15);
			if (vreg->obus == 0x81)
				vErrMsg(E33, E11, E16);
			v = FALSE;
			}

		display(0x14);
		timg = 0;		/* this test clears the output tags */
		if (verOtag() != 0) {
			if (vreg->otag == 0x80)
				vErrMsg(E34, E11, E15);
			if (vreg->otag == 0x81)
				vErrMsg(E34, E11, E16);
			v = FALSE;
			}

		display(0x16);
		if (verDld() != 0) {
			dldErr();
			v = FALSE;
			}

		display(0x1a);
		if (verPic() != 0) {
			picErr();
			v = FALSE;
			}
		if (v == TRUE)
			passTst;
		else
			return FAIL;
	} 
	return PASS;
}
/*------------------------------------------------------------------*/
/* process an interrupt controller error */
picErr()
{
	if (vreg->pic1 == 0x80)
		vErrMsg(E36, E11, E15);
	if (vreg->pic1 == 0x81)
		vErrMsg(E36, E11, E16);
	if (vreg->pic2 == 0x80)
		vErrMsg(E36, E11, E15);
	if (vreg->pic2 == 0x81)
		vErrMsg(E36, E11, E16);
}
/*------------------------------------------------------------------*/
/* process a download register error */
dldErr()
{
	if (vreg->dwld.b[0] == 0x80)
		vErrMsg(E35, E11, E15);
	if (vreg->dwld.b[0] == 0x81)
		vErrMsg(E35, E11, E16);
	if (vreg->dwld.b[1] == 0x80)
		vErrMsg(E35, E11, E15);
	if (vreg->dwld.b[1] == 0x81)
		vErrMsg(E35, E11, E16);
	if (vreg->dwld.b[0] == 0x82)
		vErrMsg(E35, E11, E15);
	if (vreg->dwld.b[0] == 0x83)
		vErrMsg(E35, E11, E16);
}
/*------------------------------------------------------------------*/
/* process an register array error */

raErr()
{
	unsigned char i;

	i = 0;
	while (i < 16) {
		if (vreg->ra.b[i] == 80) {
			vErrMsg(E30, E11, E15);
			xprintf("%2x", i);
			}
		if (vreg->ra.b[i] == 81) {
			vErrMsg(E30, E11, E16);
			xprintf("%2x", i);
			}
		if (vreg->ra.b[i] == 82) {
			vErrMsg(E30, E12, E15);
			xprintf("%2x", i);
			}
		if (vreg->ra.b[i] == 83) {
			vErrMsg(E30, E12, E16);
			xprintf("%2x", i);
			}
		i++;
		if (vreg->ra.b[i] == 80) {
			vErrMsg(E30, E11, E15);
			xprintf("%2x", i);
			}
		if (vreg->ra.b[i] == 81) {
			vErrMsg(E30, E11, E16);
			xprintf("%2x", i);
			}
	i++;
	}
}
/*------------------------------------------------------------------*/

/*  Test the KIWI Register Array by writing the value 'pattern' 
	and then testing.  Return a TRUE if test is ok.  
	Return a FALSE if test fails.				*/

ratstpat(pattern)
short	pattern;
{
	unsigned char	i, j;

	/* zero the register array */
	i = 7;
	while (i > 0)
		kiwi1->ra.w[i--] = 0;

	/* write  and test the pattern */
	i = 7;
	while (i > 0) {
		kiwi1->ra.w[i] = pattern;
		j = 7;
		while (j > 0) {
			if ( (i != j) & (kiwi1->ra.w[j] != 0)) {
				display(tstLoc);
				tstLoc = j;
				return ERROR;
				}
			if ((i == j) & (kiwi1->ra.w[j] != pattern)) {
				display(tstLoc);
				tstLoc = j;
				return ERROR;
				}
			j--;
		}
		kiwi1->ra.w[i--] = 0;
	}
	return PASS;
}


/*------------------------------------------------------------------*/

/* Do a preliminary test of the KIWI master control Register 
	tests only the upper 4 bits for now			*/

mcregtst()
{

	tstByte = 0;
	kiwi1->mc = 0;		/* clear master control register */
	actByte = kiwi1->mc & 0xF0;
	if (actByte != 0) 
		return ERROR;

	tstByte = run;
	kiwi1->mc |= run;
	actByte = kiwi1->mc & 0xF0;
	if (actByte != run) 
		return ERROR;

	tstByte = dl;
	kiwi1->mc = 0;		/* clear master control register */
	kiwi1->mc |= dl;
	actByte = kiwi1->mc & 0xF0;
	if (actByte != dl) 
		return ERROR;

	tstByte = rwe;
	kiwi1->mc = 0;		/* clear master control register */
	kiwi1->mc |= rwe;
	actByte = (kiwi1->mc & 0xF0);
	if (actByte != rwe) 
		return ERROR;

	tstByte = step;
	kiwi1->mc = 0;		/* clear master control register */
	kiwi1->mc |= step;
	actByte = (kiwi1->mc & 0xF0);
	if (actByte != step) 
		return ERROR;

	tstByte = 0;
	kiwi1->mc = 0;		/* clear master control register */
	actByte = kiwi1->mc & 0xF0;
	if (actByte != 0) 
		return ERROR;
	
	return PASS;
}

/*------------------------------------------------------------------*/

/*	Test the control store of and the function of the 
	download circuit.  */

loadtst(start)
short	start;
{
	short	count, value;

	/* zero the first 1k of ram */
	kiwi1->mc = 0;		/* clear master control register */
	kiwi1->mc |= run | dl | rwe;	/* set up for download */
	count = 1024 - 1;
	while (count) {
		kiwi1->dwld.w = 0;	/* download data */
		count--;
		kiwi1->mc |= step;
	};
	kiwi1->mc |= step;		/* point to 0 or 1025th word */
	kiwi1->dwld.w = 0xffff;
	kiwi1->mc = 0;			/* point back to 0 */
	if (kiwi1->dwld.w == 0) 
		cssize = 4096;
	else 
		cssize = 1024;

	count = cssize;
	kiwi1->mc = 0;		/* clear master control register */
	kiwi1->mc |= run | dl | rwe;	/* set up for download */

	value = start;
	while (count > 0) {
		kiwi1->dwld.w = value++;	/* download data */
		count--;
		kiwi1->mc |= step;
	};

	count = cssize;
	kiwi1->mc = 0;		/* clear master control register */
	kiwi1->mc |= run | dl | rwe;	/* set up for download */

	value = start;
	display(0);
	while (count > 0) {
		if (kiwi1->dwld.w != value++) {	/* test download data */
			actWord = kiwi1->dwld.w;
			tstWord = --value;
			csAdEr  = (cssize - count);
			return ERROR;
		}
		else {
			count--;
			kiwi1->mc |= step;
			display(count);
		};
	};

	kiwi1->mc = 0;		/* clear master control register */
	return PASS;
}


/*------------------------------------------------------------------*/

tst8259()
{
	unsigned char	error;

	error = 0;
	/* first initialize the PIC */

	/* icw1 */
	display(1);
	kiwi1->pic1 = 0x13;	/* edge trig, intvl=8, single, icw4 */
	/* icw2 */
	kiwi1->pic2 = 0x00;	/* 5 bit int vector, bit0-2 don't care */
	/* icw4 */
	kiwi1->pic2 = 0x0d;	/* 8086 set */

	kiwi1->pic2 = 0xaa;
	if (kiwi1->pic2 != 0xaa) 
		error = 1;
	kiwi1->pic2 = 0x55;
	if (kiwi1->pic2 != 0x55) 
		error = 1;
	kiwi1->pic2 = 0xff;			/* set mask */

	display(2);
	kiwi1->pic1 = 0x0b;			/* set read of IS */
	if (kiwi1->pic1 != 0x00) 
		error = 1;
	kiwi1->pic1 = 0x0a;			/* set read of IR */
	if (kiwi1->pic1 != 0x00) 
		error = 1;

	if (error) 
		return(FALSE);
	else 
		return(TRUE);

}


/*------------------------------------------------------------------*/
/* 	use BUG to generate interrupt on Multibus	*/
pictst2(irqlevel)
unsigned char	irqlevel;
{
	unsigned char	error;

	kiwi1->ra.b[4] = 0xbf;
	kiwi1->ra.b[3] = 0x07;
	kiwi1->ra.b[2] = 0x02;		/* force irq low */

	kiwi1->ra.b[4] = 0xff;
	kiwi1->ra.b[3] = 0x07;
	kiwi1->ra.b[2] = 0x02;		/* force irq high */

	/* 	test pic registers for an IR0 */
	kiwi1->pic2 = 0;	/* clear mask */
	kiwi1->pic1 = 0x0a;
	if (kiwi1->pic1 != 0x01) 
		error = 1;
	kiwi1->pic1 = 0x0c;
	if (kiwi1->pic1 != 0x80) 
		error = 1;

	/* 	see if interrupt on multibus  */
	irqlevel = irqLev();

	/* 	clean up IRQ  */
	kiwi1->ra.b[4] = 0xbf;
	kiwi1->ra.b[3] = 0x07;
	kiwi1->ra.b[2] = 0x02;		/* force irq low */
	kiwi1->pic2 = 0xff;	/* set mask */

	if (error) 
		return(FALSE);
	else 
		return(TRUE);

}


/*------------------------------------------------------------------*/
          