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

📄 nindy.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 3 页
字号:
		}		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	*/intninDownload( 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		*/	int wret;	/* Value returned by wait			*/	char buf[200];	if ( old_nindy ){		return OninDownload( fn, quiet );	}	/* 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.	 */	ninReset();	putpkt((unsigned char *) "D", 1 );	/* 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	 * lose all the transmission parameters we've set up.	 */	success = 0;#if defined(USG) && !defined(HAVE_VFORK)	pid = fork ();#else	pid = vfork ();#endif	if ( pid == -1 ){		perror( "Can't fork process:" );	} else if ( pid == 0 ){		/* CHILD */		dup2( nindy_fd, 0 );	/* Redirect stdin */		dup2( nindy_fd, 1 );	/* Redirect stout */		if ( quiet ){			execl( p, p, "-q", fn, (char*)0 );		} else {			execl( p, p, fn, (char*)0 );		}		/* Don't get here unless execl fails */		sprintf( buf, "Can't exec %s", p );		perror( buf );	} else {			/* PARENT */		do {			wret = wait(&w);		} while ( wret != pid && wret != -1 );		if ( wret == -1 ){			perror( "Wait failed" );		} else if (WIFEXITED(w) && (WEXITSTATUS(w) == 0)){			success = 1;		}	}	return success;}/****************************************************************************** * ninGdbExit: *	Ask NINDY to leave GDB mode and print a NINDY prompt. ******************************************************************************/ninGdbExit(){	if ( old_nindy ){		OninGdbExit();		return;	}        putpkt((unsigned char *) "E", 1 );}/****************************************************************************** * ninGo: *	Ask NINDY to start or continue execution of an application program *	in it's memory at the current ip. ******************************************************************************/ninGo( step_flag )    int step_flag;	/* 1 => run in single-step mode */{	if ( old_nindy ){		OninGo( step_flag );		return;	}	putpkt((unsigned char *) (step_flag ? "s" : "c"), 1 );}/****************************************************************************** * ninMemGet: *	Read a string of bytes from NINDY's address space (960 memory). ******************************************************************************/ninMemGet(ninaddr, hostaddr, len)     long ninaddr;	/* Source address, in the 960 memory space	*/     unsigned char *hostaddr;	/* Destination address, in our memory space */     int len;		/* Number of bytes to read			*/{	unsigned char buf[BUFSIZE+20];	int cnt;		/* Number of bytes in next transfer	*/	if ( old_nindy ){		OninMemGet(ninaddr, hostaddr, len);		return;	}	for ( ; len > 0; len -= BUFSIZE ){		cnt = len > BUFSIZE ? BUFSIZE : len;		buf[0] = 'm';		put_int( &buf[1], ninaddr );		buf[5] = cnt & 0xff;		buf[6] = (cnt>>8) & 0xff;		send( buf, 7, hostaddr );		ninaddr += cnt;		hostaddr += cnt;	}}/****************************************************************************** * ninMemPut: *	Write a string of bytes into NINDY's address space (960 memory). ******************************************************************************/ninMemPut( ninaddr, hostaddr, len )     long ninaddr;	/* Destination address, in NINDY memory space	*/     unsigned char *hostaddr;	/* Source address, in our memory space	*/     int len;		/* Number of bytes to write			*/{	unsigned char buf[BUFSIZE+20];	int cnt;		/* Number of bytes in next transfer	*/	if ( old_nindy ){		OninMemPut( ninaddr, hostaddr, len );		return;	}	for ( ; len > 0; len -= BUFSIZE ){		cnt = len > BUFSIZE ? BUFSIZE : len;		buf[0] = 'M';		put_int( &buf[1], ninaddr );		bcopy( hostaddr, buf+5, cnt );		send( buf, cnt+5, NULL );		ninaddr += cnt;		hostaddr += cnt;	}}/****************************************************************************** * ninRegGet: *	Retrieve the contents of a 960 register, and return them as a long *	in host byte order. * *	THIS ROUTINE CAN ONLY BE USED TO READ THE LOCAL, GLOBAL, AND *	ip/ac/pc/tc REGISTERS. * ******************************************************************************/longninRegGet( regname )    char *regname;	/* Register name recognized by NINDY, subject to the			 * above limitations.			 */{	unsigned char outbuf[10];	unsigned char inbuf[20];	if ( old_nindy ){		return OninRegGet( regname );	}	sprintf( outbuf, "u%s:", regname );	send( outbuf, strlen(outbuf), inbuf );	return get_int(inbuf);}/****************************************************************************** * ninRegPut: *	Set the contents of a 960 register. * *	THIS ROUTINE CAN ONLY BE USED TO SET THE LOCAL, GLOBAL, AND *	ip/ac/pc/tc REGISTERS. * ******************************************************************************/ninRegPut( regname, val )    char *regname;	/* Register name recognized by NINDY, subject to the			 * above limitations.			 */    long val;		/* New contents of register, in host byte-order	*/{	unsigned char buf[20];	int len;	if ( old_nindy ){		OninRegPut( regname, val );		return;	}	sprintf( buf, "U%s:", regname );	len = strlen(buf);	put_int( &buf[len], val );	send( buf, len+4, NULL );}/****************************************************************************** * ninRegsGet: *	Get a dump of the contents of the entire 960 register set.  The *	individual registers appear in the dump in the following order: * *		pfp  sp   rip  r3   r4   r5   r6   r7  *		r8   r9   r10  r11  r12  r13  r14  r15  *		g0   g1   g2   g3   g4   g5   g6   g7  *		g8   g9   g10  g11  g12  g13  g14  fp  *		pc   ac   ip   tc   fp0  fp1  fp2  fp3 * *	Each individual register comprises exactly 4 bytes, except for *	fp0-fp3, which are 8 bytes.  All register values are in 960 *	(little-endian) byte order. * ******************************************************************************/ninRegsGet( regp )    unsigned char *regp;		/* Where to place the register dump */{	if ( old_nindy ){		OninRegsGet( regp );		return;	}	send( (unsigned char *) "r", 1, regp );}/****************************************************************************** * ninRegsPut: *	Initialize the entire 960 register set to a specified set of values. *	The format of the register value data should be the same as that *	returned by ninRegsGet. * * WARNING: *	All register values must be in 960 (little-endian) byte order. * ******************************************************************************/ninRegsPut( regp )    char *regp;		/* Pointer to desired values of registers */{	unsigned char buf[REGISTER_BYTES+10];	if ( old_nindy ){		OninRegsPut( regp );		return;	}	buf[0] = 'R';	bcopy( regp, buf+1, REGISTER_BYTES );	send( buf, REGISTER_BYTES+1, NULL );}/****************************************************************************** * ninReset: *      Ask NINDY to perform a soft reset; wait for the reset to complete. * ******************************************************************************/ninReset(){	unsigned char ack;	if ( old_nindy ){		OninReset();		return;	}	while (1){		putpkt((unsigned char *) "X", 1 );		while (1){			if ( !rdnin(&ack,1,5) ){				/* Timed out */				break;		/* Resend */			}			if ( ack == '+' ){				return;			}		}	}}/****************************************************************************** * ninSrq: *	Assume NINDY has stopped execution of the 960 application program in *	order to process a host service request (srq).  Ask NINDY for the *	srq arguments, perform the requested service, and send an "srq *	complete" message so NINDY will return control to the application. * ******************************************************************************/ninSrq(){	unsigned char buf[BUFSIZE];	int retcode;	unsigned char srqnum;	int i;	int offset;	int arg[MAX_SRQ_ARGS];	if ( old_nindy ){		OninSrq();		return;	}	/* Get srq number and arguments	 */	send((unsigned char *) "!", 1, buf );	srqnum = buf[0];	for  ( i=0, offset=1; i < MAX_SRQ_ARGS; i++, offset+=4 ){		arg[i] = get_int(&buf[offset]);	}	/* Process Srq	 */	switch( srqnum ){	case BS_CLOSE:		/* args: file descriptor */		if ( arg[0] > 2 ){			retcode = close( arg[0] );		} else {			retcode = 0;		}		break;	case BS_CREAT:		/* args: filename, mode */		ninStrGet( arg[0], buf );		retcode = creat(buf,arg[1]);		break;	case BS_OPEN:		/* args: filename, flags, mode */		ninStrGet( arg[0], buf );		retcode = open(buf,arg[1],arg[2]);		break;	case BS_READ:		/* args: file descriptor, buffer, count */		retcode = read(arg[0],buf,arg[2]);		if ( retcode > 0 ){			ninMemPut( arg[1], buf, retcode );		}		break;	case BS_SEEK:		/* args: file descriptor, offset, whence */		retcode = lseek(arg[0],arg[1],arg[2]);		break;	case BS_WRITE:		/* args: file descriptor, buffer, count */		ninMemGet( arg[1], buf, arg[2] );		retcode = write(arg[0],buf,arg[2]);		break;	default:		retcode = ERROR;		break;	}	/* Send request termination status to NINDY	 */	buf[0] = 'e';	put_int( &buf[1], retcode );	send( buf, 5, NULL );}/****************************************************************************** * ninStopWhy: *	Assume the application program has stopped (i.e., a DLE was received *	from NINDY).  Ask NINDY for status information describing the *	reason for the halt. * *	Returns a non-zero value if the user program has exited, 0 otherwise. *	Also returns the following information, through passed pointers: *           - why: an exit code if program the exited; otherwise the reason *			why the program halted (see stop.h for values). *	    - contents of register ip (little-endian byte order) *	    - contents of register sp (little-endian byte order) *	    - contents of register fp (little-endian byte order) ******************************************************************************/charninStopWhy( whyp, ipp, fpp, spp )    unsigned char *whyp; /* Return the 'why' code through this pointer	*/    long *ipp;	/* Return contents of register ip through this pointer	*/    long *fpp;	/* Return contents of register fp through this pointer	*/    long *spp;	/* Return contents of register sp through this pointer	*/{	unsigned char buf[30];	extern char OninStopWhy ();	if ( old_nindy ){		return OninStopWhy( whyp, ipp, fpp, spp );	}	send((unsigned char *) "?", 1, buf );	*whyp = buf[1];	bcopy (&buf[2],  (char *)ipp, sizeof (*ipp));	bcopy (&buf[6],  (char *)fpp, sizeof (*ipp));	bcopy (&buf[10], (char *)spp, sizeof (*ipp));	return buf[0];}/****************************************************************************** * ninStrGet: *	Read a '\0'-terminated string of data out of the 960 memory space. * ******************************************************************************/staticninStrGet( ninaddr, hostaddr )     unsigned long ninaddr;	/* Address of string in NINDY memory space */     unsigned char *hostaddr;	/* Address of the buffer to which string should				 *	be copied.				 */{	unsigned char cmd[5];	cmd[0] = '"';	put_int( &cmd[1], ninaddr );	send( cmd, 5, hostaddr );}/****************************************************************************** * ninVersion: *	Ask NINDY for version information about itself. *	The information is sent as an ascii string in the form "x.xx,<arch>", *	where, *		x.xx	is the version number *		<arch>	is the processor architecture: "KA", "KB", "MC", "CA" * * ******************************************************************************/intninVersion( p )     unsigned char *p;		/* Where to place version string */{	if ( old_nindy ){		return OninVersion( p );	}	send((unsigned char *) "v", 1, p );	return strlen(p);}

⌨️ 快捷键说明

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