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

📄 ht.c

📁 unix v7是最后一个广泛发布的研究型UNIX版本
💻 C
字号:
/* * TJU16 tape driver */#include "../h/param.h"#include "../h/systm.h"#include "../h/buf.h"#include "../h/conf.h"#include "../h/dir.h"#include "../h/file.h"#include "../h/user.h"struct	device{	int	htcs1;	int	htwc;	caddr_t	htba;	int	htfc;	int	htcs2;	int	htds;	int	hter;	int	htas;	int	htck;	int	htdb;	int	htmr;	int	htdt;	int	htsn;	int	httc;	int	htbae;	/* 11/70 bus extension */	int	htcs3;};struct	buf	httab;struct	buf	rhtbuf;struct	buf	chtbuf;#define	NUNIT	1#define	INF	1000000char	h_flags[NUNIT];char	h_openf[NUNIT];daddr_t	h_blkno[NUNIT];daddr_t	h_nxrec[NUNIT];#define	HTADDR	((struct device *)0172440)#define	GO	01#define	WCOM	060#define	RCOM	070#define	NOP	0#define	WEOF	026#define	SFORW	030#define	SREV	032#define	ERASE	024#define	REW	06#define	DCLR	010#define P800	01300		/* 800 + pdp11 mode */#define	P1600	02300		/* 1600 + pdp11 mode */#define	IENABLE	0100#define	RDY	0200#define	TM	04#define	DRY	0200#define EOT	02000#define CS	02000#define COR	0100000#define PES	040#define WRL	04000#define MOL	010000#define ERR	040000#define FCE	01000#define	TRE	040000#define HARD	064023	/* UNS|OPI|NEF|FMT|RMR|ILR|ILF */#define	CLR	040	/* controller clear (in cs2) */#define	NED	010000#define	SIO	1#define	SSFOR	2#define	SSREV	3#define SRETRY	4#define SCOM	5#define SOK	6#define H_WRITTEN 1htopen(dev, flag){	register unit, ds;	httab.b_flags |= B_TAPE;	unit = minor(dev) & 077;	if (unit >= NUNIT || h_openf[unit]) {		u.u_error = ENXIO;		return;	}	h_blkno[unit] = 0;	h_nxrec[unit] = INF;	h_flags[unit] = 0;	ds = hcommand(dev, NOP);	if ((ds&MOL)==0 || (flag && (ds&WRL)))		u.u_error = ENXIO;	if (u.u_error==0)		h_openf[unit]++;}htclose(dev, flag){	register int unit;	unit = minor(dev) & 077;	if (flag == FWRITE || ((flag&FWRITE) && (h_flags[unit]&H_WRITTEN))) {		hcommand(dev, WEOF);		hcommand(dev, WEOF);		hcommand(dev, SREV);	}	if ((minor(dev)&0200) == 0)		hcommand(dev, REW);	h_openf[unit] = 0;}hcommand(dev, com){	register struct buf *bp;	bp = &chtbuf;	spl5();	while(bp->b_flags&B_BUSY) {		bp->b_flags |= B_WANTED;		sleep((caddr_t)bp, PRIBIO);	}	spl0();	bp->b_dev = dev;	bp->b_resid = com;	bp->b_blkno = 0;	bp->b_flags = B_BUSY|B_READ;	htstrategy(bp);	iowait(bp);	if(bp->b_flags&B_WANTED)		wakeup((caddr_t)bp);	bp->b_flags = 0;	return(bp->b_resid);}htstrategy(bp)register struct buf *bp;{	register daddr_t *p;	if(bp != &chtbuf) {		p = &h_nxrec[minor(bp->b_dev)&077];		if(bp->b_blkno > *p) {			bp->b_flags |= B_ERROR;			bp->b_error = ENXIO;			iodone(bp);			return;		}		if(bp->b_blkno == *p && bp->b_flags&B_READ) {			clrbuf(bp);			bp->b_resid = bp->b_bcount;			iodone(bp);			return;		}		if ((bp->b_flags&B_READ)==0) {			*p = bp->b_blkno + 1;			h_flags[minor(bp->b_dev)&077] |= H_WRITTEN;		}	}	bp->av_forw = NULL;	spl5();	if (httab.b_actf == NULL)		httab.b_actf = bp;	else		httab.b_actl->av_forw = bp;	httab.b_actl = bp;	if (httab.b_active==0)		htstart();	spl0();}htstart(){	register struct buf *bp;	register unit, den;	daddr_t blkno;    loop:	if ((bp = httab.b_actf) == NULL)		return;	unit = minor(bp->b_dev) & 0177;	HTADDR->htcs2 = ((unit>>3)&07);	den = P1600 | (unit&07);	if(unit > 077)		den = P800 | (unit&07);	if((HTADDR->httc&03777) != den)		HTADDR->httc = den;	if (HTADDR->htcs2 & NED || (HTADDR->htds&MOL)==0)		goto abort;	unit &= 077;	blkno = h_blkno[unit];	if (bp == &chtbuf) {		if (bp->b_resid==NOP) {			bp->b_resid = HTADDR->htds;			goto next;		}		httab.b_active = SCOM;		HTADDR->htfc = 0;		HTADDR->htcs1 = bp->b_resid|IENABLE|GO;		return;	}	if (h_openf[unit] < 0 || bp->b_blkno > h_nxrec[unit])		goto abort;	if (blkno == bp->b_blkno) {		httab.b_active = SIO;		HTADDR->htba = bp->b_un.b_addr;		if(cputype == 70)			HTADDR->htbae = bp->b_xmem;		HTADDR->htfc = -bp->b_bcount;		HTADDR->htwc = -(bp->b_bcount>>1);		den = ((bp->b_xmem&3) << 8) | IENABLE | GO;		if(bp->b_flags & B_READ)			den |= RCOM;		else {			if(HTADDR->htds & EOT) {				bp->b_resid = bp->b_bcount;				goto next;			}			den |= WCOM;		}		HTADDR->htcs1 = den;	} else {		if (blkno < bp->b_blkno) {			httab.b_active = SSFOR;			HTADDR->htfc = blkno - bp->b_blkno;			HTADDR->htcs1 = SFORW|IENABLE|GO;		} else {			httab.b_active = SSREV;			HTADDR->htfc = bp->b_blkno - blkno;			HTADDR->htcs1 = SREV|IENABLE|GO;		}	}	return;    abort:	bp->b_flags |= B_ERROR;    next:	httab.b_actf = bp->av_forw;	iodone(bp);	goto loop;}htintr(){	register struct buf *bp;	register int unit, state;	int	err;	if ((bp = httab.b_actf)==NULL)		return;	unit = minor(bp->b_dev) & 077;	state = httab.b_active;	httab.b_active = 0;	if (HTADDR->htcs1&TRE) {		err = HTADDR->hter;		if (HTADDR->htcs2&077400 || (err&HARD))			state = 0;		if (bp == &rhtbuf)			err &= ~FCE;		if ((bp->b_flags&B_READ) && (HTADDR->htds&PES))			err &= ~(CS|COR);		if((HTADDR->htds&MOL) == 0) {			if(h_openf[unit])				h_openf[unit] = -1;		}		else if(HTADDR->htds&TM) {			HTADDR->htwc = -(bp->b_bcount>>1);			h_nxrec[unit] = bp->b_blkno;			state = SOK;		}		else if(state && err == 0)			state = SOK;		if(httab.b_errcnt > 4)			deverror(bp, HTADDR->hter, HTADDR->htcs2);		htinit();		if (state==SIO && ++httab.b_errcnt < 10) {			httab.b_active = SRETRY;			h_blkno[unit]++;			HTADDR->htfc = -1;			HTADDR->htcs1 = SREV|IENABLE|GO;			return;		}		if (state!=SOK) {			bp->b_flags |= B_ERROR;			state = SIO;		}	} else if (HTADDR->htcs1 < 0) {	/* SC */		if(HTADDR->htds & ERR)			htinit();	}	switch(state) {	case SIO:	case SOK:		h_blkno[unit]++;	case SCOM:		httab.b_errcnt = 0;		httab.b_actf = bp->av_forw;		iodone(bp);		bp->b_resid = (-HTADDR->htwc)<<1;		break;	case SRETRY:		if((bp->b_flags&B_READ)==0) {			httab.b_active = SSFOR;			HTADDR->htcs1 = ERASE|IENABLE|GO;			return;		}	case SSFOR:	case SSREV:		if(HTADDR->htds & TM) {			if(state == SSREV) {				h_nxrec[unit] = bp->b_blkno - HTADDR->htfc;				h_blkno[unit] = h_nxrec[unit];			} else {				h_nxrec[unit] = bp->b_blkno + HTADDR->htfc - 1;				h_blkno[unit] = h_nxrec[unit]+1;			}		} else			h_blkno[unit] = bp->b_blkno;		break;	default:		return;	}	htstart();}htinit(){	register ocs2;	register omttc;		omttc = HTADDR->httc & 03777;	/* preserve old slave select, dens, format */	ocs2 = HTADDR->htcs2 & 07;	/* preserve old unit */	HTADDR->htcs2 = CLR;	HTADDR->htcs2 = ocs2;	HTADDR->httc = omttc;	HTADDR->htcs1 = DCLR|GO;}htread(dev){	htphys(dev);	physio(htstrategy, &rhtbuf, dev, B_READ);}htwrite(dev){	htphys(dev);	physio(htstrategy, &rhtbuf, dev, B_WRITE);}htphys(dev){	register unit;	daddr_t a;	unit = minor(dev) & 077;	if(unit < NUNIT) {		a = u.u_offset >> 9;		h_blkno[unit] = a;		h_nxrec[unit] = a+1;	}}

⌨️ 快捷键说明

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