/* * (C) 1983 UniSoft Corp. of Berkeley CA * * UniPlus Source Code. This program is proprietary * with Unisoft Corporation and is not to be reproduced * or used in any manner except as authorized in * writing by Unisoft. */int cksum;#ifdef	DEBUGint	debug = 0;#endifint	errno;main(){	register int ch;	register int lastchar = 0;	puts("\r\nSTANDALONE DOWNLOAD MONITOR\r\n");	putremote('\n');	for (;;) {		if ((ch = getlocal()) > 0)	/* poll console */			putremote(ch);		if ((ch = getremote()) > 0) {	/* poll remote */			putlocal(ch);			if (ch == 'S' && (lastchar == '\n' || lastchar == '\r'))				download();			lastchar = ch;		}	}}/* download a file */download(){	register char *addr;	register int count;	register int ch;	register int i;	register char *laddr = (char *)0;	for (;;) {		cksum = 0;		switch(i = wgetremote()) {			case '0':	/* name of input file */				while (wgetremote() != '\n') ;				break;			case '1':	/* data to be loaded */			case '2':				i = ((char)i == '1')? 2 : 3;				count = getnum(1) - i - 1;				addr = (char *) getnum(i);				if (laddr && laddr != addr) {					error("missing record");					return;				}				laddr = addr + count;				data(addr, count);				getbyte();				if ((cksum & 0xFF) != 0xFF) {					error("cksum");					return;				}				putlocal('.');	/* dot for record complete */				break;			case '8':	/* program execution */			case '9':				i = (i == '8')? 3 : 2;				count = getnum(1);				addr = (char *) getnum(i);				while (wgetremote() != '\n') ;				puts("\nTYPE RETURN TO START AT ");				puthex(addr);				bpoint();				while (wgetlocal() != '\r') ;				puts("\n\r");				((int (*)())addr)();	/* call program */				/* should never return */			default:				error("rec#");				return;		}		while ((ch = wgetremote()) == '\n' || ch == '\r') ;		if (ch != 'S') {			error("no S");			return;		}	}}/* put out a 6-digit hex number */puthex(v)register int v;{	puth1(v>>20);	puth1(v>>16);	puth1(v>>12);	puth1(v>>8);	puth1(v>>4);	puth1(v);}puth1(v)register int v;{	v &= 0xF;	if (v < 10)		wputlocal(v+'0');	else		wputlocal(v-10+'A');}/* get a number that is nb bytes (2*nb hex digits) long */getnum(nb)register int nb;{	register int v;	v = 0;	do {		v = (v << 8) | getbyte();	} while (--nb);	return(v);}/* get and load data */data(addr, count)register char *addr;register int count;{	if (count <= 0)		return;	do {		*addr++ = getbyte();	} while (--count);}/* get one byte (2 hex digits) */getbyte(){	register int hi, low;	hi = wgetremote();	if (hi >= '0' && hi <= '9')		hi -= '0';	else if (hi >= 'A' && hi <= 'F')		hi -= 'A' - 10;	else		error("#");	low = wgetremote();	if (low >= '0' && low <= '9')		low -= '0';	else if (low >= 'A' && low <= 'F')		low -= 'A' - 10;	else		error("#");	low |= hi << 4;	cksum += low;	return(low);}/* errors */error(s)char *s;{	puts("\r\nERROR ");	puts(s);	puts("\r\n");	return;}/* put a string on local terminal */puts(s)register char *s;{	while (*s)		wputlocal(*s++);}bpoint(){}