V4/nsys/dmr/tc.c

Compare this file to the similar file:
Show the results in this format:

#
/*
 * TC-11 DECtape driver
 */

#include "/sys/nsys/param.h"
#include "/sys/nsys/conf.h"
#include "/sys/nsys/buf.h"
#include "/sys/nsys/user.h"

struct {
	char	lbyte;
	char	hbyte;
};

struct {
	int	tccsr;
	int	tccm;
	int	tcwc;
	int	tcba;
	int	tcdt;
};

#define	TCADDR	0177340
#define	NTCBLK	578
#define	JTC	2

#define	TAPERR	0100000
#define	TREV	04000
#define	READY	0200
#define	IENABLE	0100
#define	UPS	0200

#define	SAT	0
#define	RNUM	02
#define	RDATA	04
#define	SST	010
#define	WDATA	014
#define	GO	01

#define	SFORW	1
#define	SREV	2
#define	SIO	3

tcclose(dev)
{
	bflush(dev);
}

tcstrategy(abp)
struct buf *abp;
{
	register struct buf *bp;

	bp = abp;
	bp->av_forw = 0;
	spl6();
	if (devtab[JTC].d_actf==0)
		devtab[JTC].d_actf = bp;
	else
		devtab[JTC].d_actl->av_forw = bp;
	devtab[JTC].d_actl = bp;
	if (devtab[JTC].d_active==0)
		tcstart();
	spl0();
}

tcstart()
{
	register struct buf *bp;
	register int *tccmp, com;

	if ((bp = devtab[JTC].d_actf) == 0)
		return;
	tccmp = &TCADDR->tccm;
	if (((*tccmp).hbyte&07) != bp->b_dev.d_minor)
		(*tccmp).lbyte = SAT|GO;
	devtab[JTC].d_errcnt = 20;
	devtab[JTC].d_active = SFORW;
	com = (bp->b_dev.d_minor<<8) | IENABLE|RNUM|GO;
	if ((TCADDR->tccsr & UPS) == 0) {
		com =| TREV;
		devtab[JTC].d_active = SREV;
	}
	*tccmp = com;
}

tcintr()
{
	register struct buf *bp;
	struct buf *sbp;
	register int *tccmp;
	register int *tcdtp;

	tccmp = &TCADDR->tccm;
	bp = devtab[JTC].d_actf;
	if (*tccmp&TAPERR) {
		*tccmp =& ~TAPERR;
		if (--devtab[JTC].d_errcnt  <= 0) {
			bp->b_flags =| B_ERROR;
			goto done;
		}
		if (*tccmp&TREV) {
		setforw:
			devtab[JTC].d_active = SFORW;
			*tccmp =& ~TREV;
		} else {
		setback:
			devtab[JTC].d_active = SREV;
			*tccmp =| TREV;
		}
		(*tccmp).lbyte = IENABLE|RNUM|GO;
		return;
	}
	tcdtp = &TCADDR->tcdt;
	switch (devtab[JTC].d_active) {

	case SIO:
	done:
		devtab[JTC].d_active = 0;
		sbp = bp;
		if (devtab[JTC].d_actf = bp->av_forw)
			tcstart();
		else
			TCADDR->tccm.lbyte = SAT|GO;
		iodone(sbp);
		return;

	case SFORW:
		if (*tcdtp > bp->b_blkno)
			goto setback;
		if (*tcdtp < bp->b_blkno)
			goto setforw;
		*--tcdtp = bp->b_addr;		/* core address */
		*--tcdtp = bp->b_wcount;
		tccmp->lbyte = (bp->b_flags&B_XMEM) | IENABLE|GO
		    | (bp->b_flags&B_READ?RDATA:WDATA);
		devtab[JTC].d_active = SIO;
		return;

	case SREV:
		if (*tcdtp+3 > bp->b_blkno)
			goto setback;
		goto setforw;
	}
}