
/*		kdsio.c
	
	keyboard and display functions for kiwi diagnostics
*/

#include "kiwi.h"
#include "diag.h"
#include "diagdat.h"

/* ---------------------------------------------------------------- */
/* 	atoh (ascii to hex) ignores leading blanks */
/* 	then converts the ascii hex digits pointed to by p */
/* 	to a hex number and returns that unsigned number */

unsigned atoh(p)
register char *p;
{
	char c, s;
	unsigned int count;

	--p;
	while (*++p  == ' ');
	count =0;
	while(1) {
		c = *p++;
		if(c>= '0' && c<='9')
			s=c-'0';
		else if (c>='A' && c <= 'F')
			s=c-('A'-10);
		else 
			return count;
		count<<=4;			/* ie count*=16 */
		count += s;
	}
}


/* ---------------------------------------------------------------- */
/* checks for validity of a hex, number.  An assumption made here is
   that any argument to this funtion will be null terminated, and
   there will not be tabs, spaces, carriage returns or linefeeds at end.
   Because of nature of fuction gets, this is true so far. */


isnumeric(p)
register char *p;
{

	while(*p++ == ' ');
	p--;
	if(!((*p <= 'F' && *p >= 'A') || (*p <= '9' && *p >= '0')))
		return FALSE;
	while(1) {
		++p;
		if(!((*p <= 'F' && *p >= 'A') || (*p <= '9' && *p >= '0')))
			return (!*p);
	}
}
	

/* ---------------------------------------------------------------- */
putchar(p)
char p;
{

	if(p == 0x0a)
		putc(0x0d);
	putc(p);
}

/* ---------------------------------------------------------------- */
putc(c)
char c;
{

	while(!(PORTB->control & 0x04));
	PORTB->data = c;
}


/* ---------------------------------------------------------------- */
char getchar()
{
	while (!(PORTB->control & SIO_BUSY));
	return (PORTB->data & PARITY);
}

/* ---------------------------------------------------------------- */
kbhit()		/* mnemonic for KeyBoard HIT */
{
	char	getchar();

	if (PORTB->control & SIO_BUSY) {
		getchar();
		xprintf("\b \b");
		return(TRUE);
	}
	else
		return (FALSE);
}

/* ---------------------------------------------------------------- */
/* xprintf takes %4x %s and %c arguments */
/* The '4' in %x will zero fill, providing 4 digits */


union stack {
	unsigned int xx;
	char *str;
};

xprintf(s,x)
register char *s;
unsigned int x;
{
	register union stack *p;
	char count= (char) 0;

	p = (union stack *)(&x);
	while(1) {
		while(*s != '%') {
			if(! *s)
				return;
			putchar(*s++);
		}
		count=1;
		if(* ++s >= '1' && *s <= '8')
			count= (*s++  - '0');
		switch(* s++) {
			case 's': while(*(p->str))
					putchar(*p->str++);
				  break;
			
			case 'x': number(p->xx,count);
				  break;

			case 'c': putchar(p->xx);
				  break;
		} /* end of switch */
		p++;
	} /* end of the while */
}

/* ---------------------------------------------------------------- */
number(x,count)
unsigned x, count;
{
	char c;

	c= (x & 0x0f);
	if(count)
		count--;
	if((x >>= 4))		/* ie if x not yet zero */
		number(x,count);
	else
		while (count--)
			putchar('0');
	putchar((c > 9) ? (c+'A'-10) : c+ '0');
}
/* ---------------------------------------------------------------- */

/* routine reads user input, and edits.  Command line is changed into
	series of null terminated strings.  Tallied and pointed to
	by structure argp.  */

gets(s)
register char *s;
{
	register char c, *p;
	register int count=0;
	register char inword = 0;
	char getchar();

	argp.argcount=0;
	p=s;
	repeat {
		switch(c=getchar()) {
		case CTRLX:	/* ^X, delete line */
			p=s;
			++count;
			while(--count)
				xprintf("\010 \010");
			break;
		case BS:	/* back space delete character */
			if(count) {
				count--;
				xprintf("\010 \010");
				p--;
			}
			break;
		case CR:	/* carriage return, end of input */
			*p=0x00;
			while(1) {
				if(*s == ' ') {
					if(inword) {
						*s=0x00;
						inword=0;
					}
				}
				else if(*s == 0x00)
					break;
				else if(!inword) {
					argp.argv[argp.argcount++] = s;
					inword++;
				}
				s++;
			}
			return count;
		default:	/* non special character */
			putchar(c);
			if(++count>MAXLN+1) {
				*p++ = 0x00;
				return ERROR;
			}
			*p++ = ((c>='a' && c<='z') ? c-=0x20 : c);
		}	/* end of switch statement */
	}		/* end of repeat loop */
}
/*  */                                                                                                                                                                                                                                                