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

📄 pk2.c

📁 unix v7是最后一个广泛发布的研究型UNIX版本
💻 C
字号:
#define	KERNEL	1#include "../h/pk.p"/* * input framing and block checking. * frame layout for most devices is: *	 *	S|K|X|Y|C|Z|  ... data ... | * *	where 	S	== initial synch byte *		K	== encoded frame size (indexes pksizes[]) *		X, Y	== block check bytes *		C	== control byte *		Z	== XOR of header (K^X^Y^C) *		data	== 0 or more data bytes * * device driver interfaces on input are: *	pkrint  - byte level *	pkrend  - dma or pseudo-dma transfer level *	pkdata - packet level */int pksizes[] ={	1, 32, 64, 128, 256, 512, 1024, 2048, 4096, 1};/* * Pseudo-dma byte collection. * This code can be put in the device driver * interrupt routine to eliminate the per byte * subroutine call. */pkrint(c, tp)register c;register struct tty *tp;{	if (q1.c_cc<0) {		if (q1.c_cf != NULL) {			tp->t_erase = 0;			*q1.c_cf++ = c;		}		if (++q1.c_cc)			return;		pkrend(tp);		return;	}}/* * End of input transfer. */pkrend(tp)register struct tty *tp;{register char *p;struct pack *pk;struct header *h;register x;char	cntl, hdcheck;unsigned short sum;int i,j,k;char **bp;	p = q1.c_cl;	x = (int)q1.c_cf - (int)p;	pk = (struct pack *)tp->t_linep;	h = (struct header * )&pk->p_ihbuf;	if (x == HDRSIZ) {		if (*p++ == SYN ) {			hdcheck = k = *p++;			sum = (unsigned)*p;			hdcheck ^= *p++;			sum |= (unsigned)*p << 8;			hdcheck ^= *p++;			hdcheck ^= cntl = *p++;			if (hdcheck != *p) {				goto bad;			}			if (k == 9) {				pkcntl(cntl, pk);				q1.c_cf = q1.c_cl;				q1.c_cc = -HDRSIZ;				goto istart1;			}			if (k && pksizes[k]==pk->p_rsize) {				pk->p_rpr = cntl&MOD8;				pksack(pk);				bp = pk->p_ipool;				if (bp) {					pk->p_ipool = (char **)*bp;					pk->p_io = bp;				} else {				}				q1.c_cf = (char *)bp;				q1.c_cc = -pk->p_rsize;				h->sum = sum;				h->cntl = cntl;				goto istart1;			}bad:			pkbadframe(pk);		}scan:		x = HDRSIZ;		j = 0;		p = (caddr_t)h;		for (i = 1; i < HDRSIZ; i++)			if (p[i] == SYN)				for(x=i; i<HDRSIZ; i++,j++)					p[j] = p[i];		q1.c_cc = -x;		q1.c_cf = (caddr_t)((int)p + j);		goto istart2;	}	if (x == pk->p_rsize) {		pkdata(h->cntl, h->sum, pk, q1.c_cl);		pk->p_io = NULL;		q1.c_cf = (char *)h;		q1.c_cc = -HDRSIZ;		goto istart1;	}	if (x == 0) {		q1.c_cf = (char *)h;		q1.c_cc = -HDRSIZ;		pkbadframe(pk);	} else {		pkbadframe(pk);		goto scan;	}istart1:	q1.c_cl = q1.c_cf;istart2:	if (tp->t_iproc != NULL)		(*tp->t_iproc)(tp);}/* * Put packet located at address bp * in an input slot for further processing. */pkdata(c, sum, pk, cp)char c;unsigned short sum;register struct pack *pk;char *cp;{register struct tty *tp;register x;char **bp;int t;	pk->p_state &= ~BADFRAME;	bp = (char **)cp;	tp = pk->p_ttyp;	if (pk->p_state&DRAINO || !(pk->p_state&LIVE)) {		pk->p_msg |= pk->p_rmsg;		pkoutput(pk);		goto drop;	}	t = next[pk->p_pr];	for(x=pk->p_pr; x!=t; x = (x-1)&7) {		if (pk->p_is[x] == 0)			goto slot;	}	/*	 * this can't happen	 */	printf("no slot\n");drop:	*bp = (char *)pk->p_ipool;	pk->p_ipool = bp;	return;slot:	pk->p_imap |= mask[x];	pk->p_is[x] = c;	pk->p_isum[x] = sum;	pk->p_ib[x] = cp;	if (tp->t_chan)		sdata(tp->t_chan); else		wakeup(&pk->p_pr);}/* * Start transmission on output device associated with pk. * For asynch devices (t_line==1) framing is * imposed.  For devices with framing and crc * in the driver (t_line==2) the transfer is * passed on to the driver. */pkxstart(pk, cntl, x)struct pack *pk;char cntl;register x;{struct tty *tp;register char *p;short checkword;char hdcheck;	p = (caddr_t)&pk->p_ohbuf;	tp = pk->p_ttyp;	if (tp->t_line==1) {		*p++ = SYN;		if (x < 0) {			*p = 9;			checkword = cntl;			q3.c_cl = NULL;		} else {			*p = pk->p_lpsize;			checkword = pk->p_osum[x] ^ (unsigned)cntl;			q3.c_cl = pk->p_ob[x];		}		checkword = CHECK - checkword;		hdcheck = *p++;		hdcheck ^= *p++ = checkword;		hdcheck ^= *p++ = checkword>>8;		q3.c_cc = -HDRSIZ;	} else {		q3.c_cc = -1;	}	hdcheck ^= *p++ = cntl;	*p = hdcheck;	q3.c_cf = (caddr_t)&pk->p_ohbuf;/*	pk->p_srxmit++;*/	(*tp->t_oproc)(tp);}/* * transmitter interrupt. */int	pkdelay	= 2;pkxint(tp)register struct tty *tp;{register struct pack *pk;register s;extern int pkoutput();	pk = (struct pack *)tp->t_linep;	s = spl6();	tp->t_state &= ~BUSY;	if (q3.c_cl == NULL) {			pkoutput(pk);	} else {		q3.c_cf = q3.c_cl;		q3.c_cl = NULL;		q3.c_cc = -pk->p_xsize;		(*tp->t_oproc)(tp);	}	splx(s);}

⌨️ 快捷键说明

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