
/************************************************************************
*									*
*			"d86mn.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 into smaller files...............J.Middleton	*
*	29-04-86....modified lbx/mbus select,new burn mode.J.Middleton	*
*	05-05-86....fix lbx buffer address set.............J.Middleton	*
*									*
*************************************************************************
*/
#include "diag.h"
#include "diagdat.h"
#include "kiwi.h"
#include "rabits.h"
#include "msgs.h"

extern verio(), mctst(), ratst(), cstst(), pictst(), tst8x(), ivTst() ;
extern ramTst(), offTst(), parTst(), vramTst(), udcTst(), chainTst();
extern loadop(), inSel(), reqIn(), dmaRead(), dmaWrite();
extern dspTst(),  inout(), lpbkTst(), lbxRd(), lbxWr(), manTst();
extern ibmlp();

extern unsigned char buffx[];
extern unsigned char buffy[];
extern unsigned char *buff86;
extern unsigned char *buffoff;

extern unsigned long len86;	/* word count */
extern char odd86;
extern unsigned long lenoff;	/* word count */
extern char oddoff;
extern unsigned long rlen;
extern unsigned long wrlen;


unsigned char	allTests, burnIn, menuSwitch;
struct kiwidev verreg;
struct kiwidev *vreg;

/* main calls initialization routines, does the initial prompting and
	inputs a command line for parse() to use
*/

main()
{
	unsigned aok;

	lbxSw = OFF;
	allTests = FALSE;

	/*  initialize CPU related stuff  */
	hk68init();

	xprintf("%s - %s  REV %s", header, $DATE, $VERSION );


	/* get the KIWI I/O address, check for 32 bit alignment */
	aok = FALSE;
	do {
		xprintf("%s %6x ):", praddr, DEFADR);
		gets(buffer);
		if (argp.argcount != 0) {
			if (isnumeric(argp.argv[0]))   {
				baseadr = atoh(argp.argv[0]);
				xprintf ("converted address = %6x", baseadr);
				if (baseadr & 0x0000001f)
					xprintf(E0);
				else 
					aok = TRUE;
			}
			else 
				xprintf(E4);
		}
		else {
			baseadr = DEFADR;	/* default address  */
			aok = TRUE;
			xprintf("\nDefault address selected.");
		}
	} while (aok == FALSE);
		

	/* set up KIWI register struct and valid register struct */
	kiwi1 = (struct kiwidev *) baseadr;
	vreg = & verreg;

	level = 1;		/* diagnostic level */
	timg =  0;	/* clear offline tag images */
	kiwi1->otag = timg;

	display(0);

	menuSwitch = ON;

	/* command line input loop */
	repeat {
		if (menuSwitch) {
			xprintf("             %s - %s  REV %s", header, $DATE, $VERSION );
			xprintf(menu1);		/* print test menu */
			xprintf(menu2);		/* print test menu */
		}
		xprintf(prompt);		/* prompt */
		gets(buffer);			/* input command line */
		if(parse(buffer) == ERROR)
			eMsg(E1);
	}
}

/*------------------------------------------------------------------*/
help()
{
	xprintf("\nSorry, no help at this time.");
}
/*------------------------------------------------------------------*/
lbSwitch()
{
	xprintf("\nRemove E3, install E4 - hit <cr> to continue");
	gets(buffer);
	lbxSw = ON;

	buff86 = buffx;
	buffoff = buffy;
	buff86 += LBXBASE;
	buffoff += LBXBASE;
	rlen = LB_RLEN;
	wrlen = LB_WRLEN;
	lenoff = LB_RLEN/2;
	len86 = LB_RLEN/2;
}

/*------------------------------------------------------------------*/
mbSwitch()
{
	xprintf("\nInstall E3 - hit <cr> to continue");
	gets(buffer);
	lbxSw = OFF;

	rlen = MB_RLEN;
	wrlen = MB_WRLEN;
	lenoff = MB_RLEN/2;
	len86 = MB_RLEN/2;
	buff86 = buffx;
	buffoff = buffy;
}
/*------------------------------------------------------------------*/
burnUm()
{
	long pass;
	int burnCnt;

	pass = 0;

/* get count and set up burnCnt */
	if (argp.argcount != 2) 
		burnCnt = 1;
	else if (!isnumeric(argp.argv[1]))
		return ERROR;
	else burnCnt = atoh(argp.argv[1]);	
	if (burnCnt == 0)		/* do at least one iteration */
		burnCnt++;
/* set loop count to 1 */
	argp.argv[1] = "1";

	menuSwitch = OFF;

	while (burnCnt--) {

		if (allTests == TRUE) {
			if (dspTst() == FAIL)
				break;
			}
			
		if (verio() == FAIL)
			break;
		if (kbhit() == TRUE)
			break;

		if (mctst() == FAIL)
			break;
		if (kbhit() == TRUE)
			break;

		if (ratst() == FAIL)
			break;
		if (kbhit() == TRUE)
			break;

		if (cstst() == FAIL)
			break;
		if (kbhit() == TRUE)
			break;

		if (pictst() == FAIL)
			break;
		if (kbhit() == TRUE)
			break;

		if (tst8x() == FAIL)
			break;
		if (kbhit() == TRUE)
			break;

		if (ivTst() == FAIL)
			break;
		if (kbhit() == TRUE)
			break;

		if (ramTst() == FAIL)
			break;
		if (kbhit() == TRUE)
			break;

		if (offTst() == FAIL)
			break;
		if (kbhit() == TRUE)
			break;

		if (parTst() == FAIL)
			break;
		if (kbhit() == TRUE)
			break;

		if (vramTst() == FAIL)
			break;
		if (kbhit() == TRUE)
			break;

		if (udcTst() == FAIL)
			break;
		if (kbhit() == TRUE)
			break;

		if (chainTst() == FAIL)
			break;
		if (kbhit() == TRUE)
			break;

		if (loadop() == FAIL)
			break;
		if (kbhit() == TRUE)
			break;

		if (inSel() == FAIL)
			break;
		if (kbhit() == TRUE)
			break;

		if (reqIn() == FAIL)
			break;
		if (kbhit() == TRUE)
			break;

		if (dmaRead() == FAIL)
			break;
		if (kbhit() == TRUE)
			break;

		if (dmaWrite() == FAIL)
			break;
		if (kbhit() == TRUE)
			break;

		if (allTests == TRUE) {
			if (lbxSw == ON) 
				mbSwitch();
			else
				lbSwitch();

			if (dmaRead() == FAIL)
				break;
			if (kbhit() == TRUE)
				break;

			if (dmaWrite() == FAIL)
				break;
			if (kbhit() == TRUE)
				break;

			}
			

		xprintf("\nPASS %6x ", pass++);

	}
	if (burnCnt != 0)
		xprintf("\nPASS %6x ", pass++);		/* print last pass */
}
/*------------------------------------------------------------------*/

/*	parse does preliminary parsing of the command line */
/*	it is passed the pointer into the buffer and passes */
/*	it to routines it calls. */

parse(p)
register char *p;
{
	int	no_op(),f;
	char chold;


	switch((chold = *p)) {
	case 'A':
		if (*++p == 'R')
			return reform(p, vramTst);
	case 'B':		/* burn in mode */
		if (*++p == 'L') {
			burnIn = TRUE;
			allTests = FALSE;
			return reform(p, burnUm);
			}
		if (*p == 'A') {
			burnIn = TRUE;
			allTests = TRUE;
			return reform(p, burnUm);
			}
	case 'C':
		if (*++p == 'S')
			return reform(p, cstst);
		if (*p == 'L')
			return reform(p, ibmlp);
		if (*p == 'T')
			return reform(p, chainTst);
	case 'D':
		if (*++p == 'C')
			return reform(p, udcTst);
		if (*p == 'I')
			return reform(p, dspTst);
		if (*p == 'R')
			return reform(p, dmaRead);
		if (*p == 'T')
			return reform(p, inout);
		if (*p == 'W')
			return reform(p, dmaWrite);
	case 'E':		/* exit */
		hbugWarm();
	case 'I':
		if (*++p == 'T')
			return reform(p, pictst);
		if (*p == 'V')
			return reform(p, ivTst);
		if (*p == 'R')
			return reform(p, ramTst);
		if (*p == 'S')
			return reform(p, inSel);
	case 'L':
		if (*++p == 'M')
			return reform(p, loadop);
		if (*p == 'P')
			return reform(p, lpbkTst);
		if (*p == 'B')
			return reform(p, lbSwitch);
	case 'M':
		if (*++p == 'C')
			return reform(p, mctst);
		if (*p == 'B')
			return reform(p, mbSwitch);
		if (!*p)
			menuSwitch = !menuSwitch;
			return;
	case 'O':
		if (*++p == 'R')
			return reform(p, offTst);
	case 'P':
		if (*++p == 'T')
			return reform(p, parTst);
	case 'R':	
		if (*++p == 'A')
			return reform(p, ratst);
		if (*p == 'I')
			return reform(p, reqIn);
		if (!*p)		/* gets maps a space to a NULL */
			main();
	case 'V':
		if (*++p == 'I')
			return reform(p, verio);
		if ((typemem = (*p == 'R')) || *p == 'W')
			return reform(p, manTst);
		else
			return ERROR;
	case '8':
		if (*++p == 'X')
			return reform(p, tst8x);
	case '?':
		return reform(p, help);
	default:
		return ERROR;
	}		/* end of major switch statement */
}

/*------------------------------------------------------------------*/

/* reform gives a program ability to have an option space after the commands
   by reformating the argv and argcount of struct argp ****/

reform(p,f)
char	*p; /* pointer into command string, at last letter of command op */
int	(*f)();
{
	int	i;

	if (! (*++p == SPACE || *p == NULL)) {
		i = argp.argcount++;		/* increase # of args */
		do			/* remap vectors */
			argp.argv[i] = argp.argv[i-1];
		while(--i);
		argp.argv[1] = p;
	}
	return (f());		/* call fuction */
}

no_op()			/* dummy, for reform calls */
{
	return TRUE;
}


	
/*------------------------------------------------------------------*/
getCnt()
{
	if (argp.argcount != 2) 
		lpCnt = 1;
	else if (!isnumeric(argp.argv[1]))
		return ERROR;
	else lpCnt = atoh(argp.argv[1]);	
	if (lpCnt == 0)		/* do at least one iteration */
		lpCnt++;
}
/*------------------------------------------------------------------*/
