AUSAM/sys/dmr/ta.c

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

#

/*
 *	copyright 1975 ace systems inc.
 */

/*
 *	ta-11 cassette driver
 */

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

int	taopenl[2];

int tabc,tabcz;  char *taba,tabaz;  int tactv;  int taerr;  taerrcnt;

/*	symbolic equates for ta-11 	*/

#define	taddr	0177500
struct	{
		int tacs;		/* ta-11 control and status register */
		int tadb; };		/* ta-11 data buffer register */

#define	taperr (1<<15)	/* 14->9,3->1, indicate type
			   valid only when ready is set */
#define	blkchk	(1<<14)	/* crc error for read and sfb 
			   sets error for read */
#define	xot	(1<<13)		/* eot or bot on selected tape
			   sets error for all but rewind */
#define	wlock	(1<<12)	/* selected tape is write protected
			   write or wfg must be set */
#define	fgap	(1<<11)	/* tape mark encounted during read,sfb,srf,sff
			   sets error only on read, sfb */
#define	timerr	(1<<10)	/* missed character
                             sets error only on read, write */
#define	offline	((1<<9)|(1<<15)) /* selected cassette unavailable */

#define	treq	(1<<7)	/* data available in tadb during read
			   data wanted in tadb during write */
#define	ready	(1<<5)	/* unit ready to accept commands */
#define	ilbs	(1<<4)	/* initate last byte sequence */
#define	wfg	((1<<6)|(0<<1)|1)	/* write file gap */
#define	write	((1<<6)|(1<<1)|1)	/* write */
#define	read	((1<<6)|(2<<1)|1)	/* read */
#define	srf	((1<<6)|(3<<1)|1)	/* space reverse file */
#define	srb	((1<<6)|(4<<1)|1)	/* space reverse block */
#define	sff	((1<<6)|(5<<1)|1)	/* space forward file */
#define	sfb	((1<<6)|(6<<1)|1)	/* space forward block */
#define	rewind	((1<<6)|(7<<1)|1)	/* rewind */









taopen(dev,flag)
{
	register lr;

	if( (lr=dev.d_minor)>1 )  u.u_error=ENXIO;
	else { taddr->tacs =| lr<<8 ; 
		if( taopenl[lr] || ((taddr->tacs&offline)==offline) )
				u.u_error=ENXIO;
			else
				taopenl[lr]=1;
	}
}
taclose(dev,flag)
{
	register lr;
	lr = dev.d_minor<<8;
	if (flag) tastart(lr,wfg);
	tastart(lr,rewind);
	taopenl[lr>>8]=0;
}
tastart( lr , cmd )
{
	register struct buf *bp;
	if(u.u_count>512)  { u.u_error=ENXIO; return; }
	while(tactv) sleep(&tactv,1);
	taddr->tacs =| lr ;
	if( (!(taddr->tacs&ready))||((taddr->tacs&offline)==offline))
			{ u.u_error = ENXIO; return; }
	switch(cmd) {
	  case read:	bp = getblk(NODEV);
			tabaz=taba=bp->b_addr;
			tabcz=tabc= u.u_count;
			break;
	  case write:	bp = getblk(NODEV);
			tabaz=taba=bp->b_addr;
			tabcz=tabc= u.u_count;
			iomove(bp,0,u.u_count,B_WRITE);
	  case wfg:
	  case rewind:
			break;
	}
	tactv = cmd;	taerr = 0;	taerrcnt = 5;
	taddr->tacs=  lr | cmd;
	while(tactv) sleep(&tactv,1);	/* wait for i/o to complete */
	if((taerr==2)&&(cmd==read)) return;
	switch(cmd) {
	  case read:	if(tabc==u.u_count) return;
	  		iomove(bp,0,u.u_count-tabc,B_READ);
	  case write:	brelse(bp);
	  case wfg:	break;
	  case rewind:	return;
	}
	if(taerr) u.u_error = ENXIO;
}

taintr()
{

	if(!(tactv)) return;

	if(taddr->tacs&treq)
	  { if (!tabc--) { taddr->tacs =| ilbs; tabc=0; }
		else if (tactv==read)
			*taba++ =taddr->tadb;
		   else taddr->tadb= *taba++;
		return;	}

	if(taddr->tacs&taperr) {
	  if(!taerr) {
/*************
	   	deverror(bp,taddr->tacs);
*************/
	   	taerr = 1;
		if((taerrcnt--)>0) switch(tactv) { 
		case read:	if(taddr->tacs&(xot|fgap)) {
					taerr++; goto rti;
				}
		case write:	if(taddr->tacs&timerr) {
				taddr->tacs = (taddr->tacs & 0177740)|srb;
				return; 
				}
		}
	  }
	}
	   else if(taerr) {
		taddr->tacs = (taddr->tacs & 0177740) | tactv;
		taerr = 0;	taerrcnt = 5;
		taba = tabaz;	tabc = tabcz;
		return;
	   }
rti:	tactv = 0;
	wakeup(&tactv);
}
/*
 *	 i/o interface for  cassette.
 *	essentially provided so users can read/write caps-11 format
 *	 tapes.
 */

taread(dev)
{
	tastart(dev.d_minor<<8,read);
}

tawrite(dev)
{
	tastart(dev.d_minor<<8 , (u.u_count==1) ? wfg : write);
}