⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 onindy.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 3 页
字号:
    char *buf;		/* Message to be sent to NINDY; replaced by			 *	NINDY's response.			 */    int ack_required;	/* TRUE means NINDY's response MUST be either "X00" (no			 *	error) or an error code "Xnn".			 * FALSE means the it's OK as long as it doesn't			 *	begin with "Xnn".			 */{	int errnum;	static char *errmsg[] = {		"",						/* X00 */		"Buffer overflow",				/* X01 */		"Unknown command",				/* X02 */		"Wrong amount of data to load register(s)",	/* X03 */		"Missing command argument(s)",			/* X04 */		"Odd number of digits sent to load memory",	/* X05 */		"Unknown register name",			/* X06 */		"No such memory segment",			/* X07 */		"No breakpoint available",			/* X08 */		"Can't set requested baud rate",		/* X09 */	};#	define NUMERRS	( sizeof(errmsg) / sizeof(errmsg[0]) )	static char err0[] = "NINDY failed to acknowledge command: <%s>\r\n";	static char err1[] = "Unknown error response from NINDY: <%s>\r\n";	static char err2[] = "Error response %s from NINDY: %s\r\n";	putpkt (buf);	getpkt (buf);	if ( buf[0] != 'X' ){		if ( ack_required ){			fprintf( stderr, err0, buf );			abort();		}	} else if ( strcmp(buf,"X00") ){		sscanf( &buf[1], "%x", &errnum );		if ( errnum > NUMERRS ){			fprintf( stderr, err1, buf );		} else{			fprintf( stderr, err2, buf, errmsg[errnum] );		}		abort();	}}		/************************		 *                      *		 *  BAUD RATE ROUTINES  *		 *                      *		 ************************//* Table of baudrates known to be acceptable to NINDY.  Each baud rate * appears both as character string and as a Unix baud rate constant. */struct baudrate {	char *string;	int rate;};static struct baudrate baudtab[] = {	 "1200", B1200,	 "2400", B2400,	 "4800", B4800,	 "9600", B9600,	"19200", B19200,	"38400", B38400,	NULL,    0		/* End of table */}; /****************************************************************************** * parse_baudrate: *	Look up the passed baud rate in the baudrate table.  If found, change *	our internal record of the current baud rate, but don't do anything *	about the tty just now. * *	Return pointer to baudrate structure on success, NULL on failure. ******************************************************************************/staticstruct baudrate *parse_baudrate(s)    char *s;	/* Desired baud rate, as an ASCII (decimal) string */{	int i;	for ( i=0; baudtab[i].string != NULL; i++ ){		if ( !strcmp(baudtab[i].string,s) ){			return &baudtab[i];		}	}	return NULL;}/****************************************************************************** * try_baudrate: *	Try speaking to NINDY via the specified file descriptor at the *	specified baudrate.  Assume success it we can send an empty command *	with a bogus checksum and receive a NAK (response of '-') back within *	one second. * *	Return 1 on success, 0 on failure. ******************************************************************************/static int saw_alarm;static voidalarm_handler(){	saw_alarm = 1;}static inttry_baudrate( fd, brp )    int fd;    struct baudrate *brp;{	TTY_STRUCT tty;	char c;	int n;	void (*old_alarm)();    /* Save alarm signal handler here on entry */		/* Set specified baud rate and flush all pending input */	ioctl( fd, TIOCGETP, &tty );	TTY_REMOTE( tty, brp->rate );	ioctl( fd, TIOCSETP, &tty );	tty_flush( fd );	/* Send bogus command */	write( fd, "\020#00", 4 );	/* Wait until reponse comes back or one second passes */	old_alarm = signal( SIGALRM,alarm_handler );	saw_alarm = 0;	alarm(1);	do {		n = 1;		TTY_NBREAD(fd,n,&c);	} while ( n<=0 && !saw_alarm );	/* Turn off alarm */	alarm(0);	signal( SIGALRM,old_alarm );	/* Did we get a '-' back ? */	if ( (n > 0) && (c == '-') ){		return 1;	}	return 0;}/****************************************************************************** * autobaud: *	Get NINDY talking over the specified file descriptor at the specified *	baud rate.  First see if NINDY's already talking at 'baudrate'.  If *	not, run through all the legal baudrates in 'baudtab' until one works, *	and then tell NINDY to talk at 'baudrate' instead. ******************************************************************************/staticautobaud( fd, brp )    int fd;    struct baudrate *brp;{	int i;	TTY_STRUCT tty;	say("NINDY at wrong baud rate? Trying to autobaud...\n");	i = 0;	while ( 1 ){		say( "\r%s...   ", baudtab[i].string );		if ( try_baudrate(fd,&baudtab[i]) ){			break;		}		if ( baudtab[++i].string == NULL ){			/* End of table -- wraparound */			i = 0;			say("\nAutobaud failed. Trying again...\n");		}	}	/* Found NINDY's current baud rate;  now change it.	 */	say("Changing NINDY baudrate to %s\n", brp->string);	OninBaud( brp->string );	/* Change our baud rate back to rate to which we just set NINDY.	 */	ioctl( fd, TIOCGETP, &tty );	TTY_REMOTE( tty, brp->rate );	ioctl( fd, TIOCSETP, &tty );}		/**********************************		 *				  *		 *   NINDY INTERFACE ROUTINES	  *		 *                            	  *		 * ninConnect *MUST* be the first *		 * one of these routines called.  *		 **********************************//****************************************************************************** * ninBaud: *	Ask NINDY to change the baud rate on its serial port. *	Assumes we know the baud rate at which NINDY's currently talking. ******************************************************************************/OninBaud( baudrate )    char *baudrate;	/* Desired baud rate, as a string of ASCII decimal			 * digits.			 */{	char buf[100];		/* Message buffer	*/	char *p;		/* Pointer into buffer	*/	unsigned char csum;	/* Calculated checksum	*/	tty_flush( nindy_fd );	/* Can't use putpkt() because after the baudrate change	 * NINDY's ack/nak will look like gibberish.	 */	for ( p=baudrate, csum=020+'z'; *p; p++ ){		csum += *p;	}	sprintf( buf, "\020z%s#%02x", baudrate, csum );	write( nindy_fd, buf, strlen(buf) );}/****************************************************************************** * ninBptDel: *	Ask NINDY to delete the specified type of *hardware* breakpoint at *	the specified address.  If the 'addr' is -1, all breakpoints of *	the specified type are deleted. ******************************************************************************/OninBptDel( addr, data )    long addr;	/* Address in 960 memory	*/    int data;	/* '1' => data bkpt, '0' => instruction breakpoint */{	char buf[100];	if ( addr == -1 ){		sprintf( buf, "b%c", data ? '1' : '0' );	} else {		sprintf( buf, "b%c%x", data ? '1' : '0', addr );	}	return send( buf, FALSE );}/****************************************************************************** * ninBptSet: *	Ask NINDY to set the specified type of *hardware* breakpoint at *	the specified address. ******************************************************************************/OninBptSet( addr, data )    long addr;	/* Address in 960 memory	*/    int data;	/* '1' => data bkpt, '0' => instruction breakpoint */{	char buf[100];	sprintf( buf, "B%c%x", data ? '1' : '0', addr );	return send( buf, FALSE );}/****************************************************************************** * ninConnect: *	Open the specified tty.  Get communications working at the specified *	Flush any pending I/O on the tty. * *	Return the file descriptor, or -1 on failure. ******************************************************************************/intOninConnect( name, baudrate, brk, silent )    char *name;		/* "/dev/ttyXX" to be opened			*/    char *baudrate;/* baud rate: a string of ascii decimal digits (eg,"9600")*/    int brk;		/* 1 => send break to tty first thing after opening it*/    int silent;		/* 1 => stifle unnecessary messages when talking to 			 *	this tty.			 */{	int i;	char *p;	struct baudrate *brp;	/* We will try each of the following paths when trying to open the tty	 */	static char *prefix[] = { "", "/dev/", "/dev/tty", NULL };	quiet = silent;		/* Make global to this file */	for ( i=0; prefix[i] != NULL; i++ ){		p = malloc(strlen(prefix[i]) + strlen(name) + 1 );		strcpy( p, prefix[i] );		strcat( p, name );		nindy_fd = open(p,O_RDWR);		if ( nindy_fd >= 0 ){#ifdef TIOCEXCL			/* Exclusive use mode (hp9000 does not support it) */			ioctl(nindy_fd,TIOCEXCL,NULL);#endif			if ( brk ){				send_break( nindy_fd );			}			brp = parse_baudrate( baudrate );			if ( brp == NULL ){				say("Illegal baudrate %s ignored; using 9600\n",								baudrate);				brp = parse_baudrate( "9600" );			}			if ( !try_baudrate(nindy_fd,brp) ){				autobaud(nindy_fd,brp);			}			tty_flush( nindy_fd );			say( "Connected to %s\n", p );			free(p);			break;		}		free(p);	}	return nindy_fd;}/****************************************************************************** * ninDownload: *	Ask NINDY to start up it's COFF downloader. Invoke 'sx' to perform *	the XMODEM download from the host end. * *	Return 1 on success, 0 on failure. ******************************************************************************/#define XMODEM	"sx"	/* Name of xmodem transfer utility	*/intOninDownload( fn, quiet )    char *fn;		/* Stripped copy of object file			*/    int quiet;{	char *p;	/* Pointer to full pathname of sx utility	*/	int success;	/* Return value					*/	int pid;	/* Process ID of xmodem transfer utility	*/	WAITTYPE w;	/* xmodem transfer completion status		*/	char buf[200];	/* Make sure the xmodem utility is findable.  This must be done before	 * we start up the NINDY end of the download (NINDY will hang if we	 * don't complete the download).	 */	if ( ((p = exists("G960BIN",XMODEM,NULL,NULL,1)) == NULL)	&&   ((p = exists("G960BASE","bin",XMODEM, NULL,1)) == NULL)#ifdef HOST	&&   ((p = exists(DEFAULT_BASE,HOST,"bin",XMODEM,0)) == NULL)#endif								      ){		fprintf(stderr,"Can't find '%s' download utility\n",XMODEM);		fprintf(stderr,"Check env variables G960BIN and G960BASE\n");		return 0;	}	if ( !quiet ){		printf( "Downloading %s\n", fn );	}	/* Reset NINDY,  wait until "reset-complete" ack,	 * and start up the NINDY end of the download.	 */	OninReset();	putpkt( "D" );	/* Invoke x-modem transfer, a separate process.  DON'T	 * use system() to do this -- under system V Unix, the	 * redirection of stdin/stdout causes the nindy tty to

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -