/* console input output*/

char *__dwwht =  "$Header: dw.c,v 1.4 86/12/04 10:21:43 tom Exp $";

/* Some defines for the Console Subsystem */
#define	RXCS	0x20	/* console receiver control/status register */
#define	RXDB	0x21	/* console receiver data buffer */
#define	TXCS	0x22	/* console transmitter control/status register */
#define	TXDB	0x23	/* console transmitter data buffer */

#define	RXCS_IE		0x00000040	/* receiver interrupt enable */
#define	RXCS_DONE	0x00000080	/* receiver done */

#define	RXDB_DATA	0x000000ff	/* received character */
#define	RXDB_ID		0x00000f00	/* channel id */
#define	RXDB_ERR	0x80000000	/* receiver error */

#define	TXCS_IE		0x00000040	/* transmitter interrupt enable */
#define	TXCS_RDY	0x00000080	/* transmitter ready for next char */
#define	TXDB_DATA	0x000000ff	/* transmitter byte */
#define	TXDB_ID		0x00000f00	/* channel id */


/*VARARGS1*/
printf(fmt, x1)
	char *fmt;
	unsigned x1;
{
	prf(fmt, &x1);
}

prf(fmt, adx)
	register char *fmt;
	register unsigned int *adx;
{
	register int b, c, i;
	char *s;
	int any;

loop:
	while ((c = *fmt++) != '%') {
		if(c == '\0')
			return;
		putchar(c);
	}

again:
	c = *fmt++;
	/* THIS CODE IS VAX DEPENDENT IN HANDLING %l? AND %c */
	switch (c) {

	case 'l':
		goto again;
	case 'x': case 'X':
		b = 16;
		goto number;
	case 'd': case 'D':
	case 'u':		/* what a joke */
		b = 10;
		goto number;
	case 'o': case 'O':
		b = 8;
number:
		printn((unsigned long)*adx, b);
		break;
	case 'c':
		b = *adx;
		for (i = 24; i >= 0; i -= 8)
			if (c = (b >> i) & 0x7f)
				putchar(c);
		break;
	case 'b':
		b = *adx++;
		s = (char *)*adx;
		printn((unsigned long)b, *s++);
		any = 0;
		if (b) {
			putchar('<');
			while (i = *s++) {
				if (b & (1 << (i-1))) {
					if (any)
						putchar(',');
					any = 1;
					for (; (c = *s) > 32; s++)
						putchar(c);
				} else
					for (; *s > 32; s++)
						;
			}
			putchar('>');
		}
		break;

	case 's':
		s = (char *)*adx;
		while (c = *s++)
			putchar(c);
		break;
	}
	adx++;
	goto loop;

}

/*
 * Printn prints a number n in base b.
 * We don't use recursion to avoid deep kernel stacks.
 */
printn(n, b)
	unsigned long n;
{
	char prbuf[11];
	register char *cp;

	if (b == 10 && (int)n < 0) {
		putchar('-');
		n = (unsigned)(-(int)n);
	}
	cp = prbuf;
	do {
		*cp++ = "0123456789abcdef"[n%b];
		n /= b;
	} while (n);
	do
		putchar(*--cp);
	while (cp > prbuf);
}


/* putchar for level 1 bootloader */
putchar(c)
	register c;
{
	register s, tout;

	tout = 40000;

	while((mfpr(TXCS)&TXCS_RDY) == 0) /* busy wait for console ready */
		if(--tout == 0)
			break;
	if(c == 0)		/* ignore nulls */
		return;

	s = mfpr(TXCS);	/* save status */
	mtpr(TXCS,0);
	mtpr(TXDB, c&0xff);	/* poke that char! */
	if(c == '\n')
		putchar('\r');
	putchar(0);		/* cheap recursive ready-wait */
	mtpr(TXCS, s);	/* try to restore status */
}

getchar()
{
	register c;

	while((mfpr(RXCS)&RXCS_DONE) == 0)
		;		/* wait for DONE */
	c = mfpr(RXDB)&0177;	/* get the char */
	if (c=='\r')
		c = '\n';	/* map from CR-> NL */
	putchar(c);		/* echo */
	return(c);
}



#ifdef NEVER
gets(buf)
	char *buf;
{
	register char *lp;
	register c;

	lp = buf;
	for (;;) {
		c = getchar() & 0177;
	store:
		switch(c) {
		case '\n':
		case '\r':
			c = '\n';
			*lp++ = '\0';
			return;
		case '\b':
		case '#':
			lp--;
			if (lp < buf)
				lp = buf;
			continue;
		case '@':
		case 'u'&037:
			lp = buf;
			putchar('\n');
			continue;
		default:
			*lp++ = c;
		}
	}
}
#endif /* NEVER */
