AUSAM/sys/dmr/dj.c

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

#
/*
 **   	copyright 1975.    ian.  inc
 *
 *
 **	also that dj11 parity checking is screwed if terminal attached
 **	does not generate parity. SO IT AIN'T SUPPORTED !!
 */
 
/*
 *	dj-11 driver
 */
#include "../defines.h"
#include "../param.h"
#include "../conf.h"
#include "../user.h"
#include "../tty.h"
#include "../proc.h"
 
#define DJSCANRATE	2	/* define this if dj11 is strapped
				   to interrrupt when input silo
				   has more than 5,9,17, .. ,31 chars in it.
				   2 is best any more and eching becomes chunky */
#define	NDJ11	1		/* one only dj11s */
#define	NLINES	(NDJ11*16)	/* number of terminals connected */
#define SSPEED	12		/* standard speed 4800 bd */

/* device register equates */

#define	DJTIE		0040000		/* xmit interupt enable */
#define	DJTSE		0000400		/* xmit scanner enable */
#define	DJTR		0100000		/* transmitter ready */
#define	DJRIE		0000100		/* receive interupt enable */
#define	DJRE		0000001		/* receive enable */
#define	DJOVERUN	0040000		/* overrun error */
#define	DJFRAME		0020000		/* framing error */
#define	DJPARITY	0010000		/* parity error */

struct djregs {
	int djcsr;
	int djrbuf;
	int djtcr;
	int djtbuf;
};
 
struct dj {
	struct djregs *djaddr;	/* address of registers for this dj11 */
	unsigned openl;		/* flags for open lines */
	unsigned sopen;		/* If bit 'n' set then line 'n' is an exclusive use.
				That is only one open allowed (e.g. LA180)	*/
	} dj[NDJ11] {
		0160010, 0000000, 0000210,
};

unsigned djoverrun;	/* Total count of overrun errors.
	  		   Don't init - want bss for big unix systems 
			   so can put in root segment */

unsigned djscanning;	/* True when scanning in operation.
			Equal to total number of open lines.
			When true scan open lines every DJSCANRATE ticks. */


struct  tty dj11[NLINES];
 
djopen(dev, flag)
{
	register struct dj *djp = &dj[dev.d_minor>>4];
	register struct tty *tp = &dj11[dev.d_minor];
	register t_bit = (1 << (dev.d_minor&017));
	extern djstart(),djrint();
 
	if(dev.d_minor >= NLINES)
	{
		u.u_error = ENXIO;
		return;
	}
 
	if ((tp->t_state&ISOPEN) == 0)
	{
		if( djp->openl == 0 )
			djp->djaddr->djcsr =  DJTIE|DJTSE|DJRE|DJRIE;
		djp->openl =| t_bit;
#ifdef	DJSCANRATE
		if( djscanning==0 )
			timeout( &djrint, -1, DJSCANRATE );
#endif
		djscanning++;
		tp->t_addr = djstart;   /* special start routine */
		tp->t_dev = dev;
		tp->t_speeds = SSPEED|(SSPEED<<8);
		tp->t_state = SSTART|ISOPEN|CARR_ON;
		tp->t_flags = ODDP|EVENP|XTABS|RAW;
		tp->t_erase = CERASE;
		tp->t_kill = CKILL;
	}
	else if( djp->sopen & t_bit )
	{
		u.u_error = EOPENFAIL;
		return;
	}

	if (u.u_procp->p_ttyp == 0)
		u.u_procp->p_ttyp = tp;
}
 
djclose(dev)
{
	register struct dj *djp = &dj[dev.d_minor>>4];
	register struct tty *tp = &dj11[dev.d_minor];
	register t_bit = (1 << (dev.d_minor&017));
 
	wflushtty( tp );
	tp->t_state = SSTART;
	djp->openl =& ~t_bit;
	if( djp->openl == 0 )
		djp->djaddr->djcsr = 0;
	djscanning--;
}
 
djread(dev)
{
	ttread(&dj11[dev.d_minor]);
}
 
djwrite(dev)
{
	ttwrite(&dj11[dev.d_minor]);
}
 
 
djstart(atp)
struct tty *atp;
{
	register line;

	line = atp - dj11;
	/* enable transmit for this line */
	dj[ line>>4 ].djaddr->djtcr =| 1 << (line&017) ;
}
 
djxint()
{
	register int c;
	register struct tty *tp ;
	register struct dj *djp;
	int line,djn;
	extern ttrstrt();
 
  for( djp=dj , djn=0 ; djp<&dj[NDJ11] ; djp++ , djn=+16 ) {
	while (djp->djaddr->djcsr&DJTR) {	/* loop till trans. happy */
	  tp = &dj11[djn+(line=(djp->djaddr->djtbuf)>>8)];	/* get tty structure address + line no. */
	  if( !(tp->t_state&TIMEOUT) )
	    if((c = getc(&tp->t_outq)) >= 0)  {
		if( tp->t_flags == RAW ) {
			djp->djaddr->djtbuf = c;
			continue;
		}
		if( c<=0177 ) {
			djp->djaddr->djtbuf = c + (partab[c]&0200);
			continue;
		} else {
			timeout( &ttrstrt, tp, c&0177 );
			tp->t_state =| TIMEOUT;
		}
	    }
	  djp->djaddr->djtcr =& ~(1<<line); /*stop*/
 
	  if (tp->t_outq.c_cc <= TTLOWAT && tp->t_state & ASLEEP )  {
		tp->t_state =& ~ASLEEP;
		wakeup(&tp->t_outq);
	  }
	}
  }
}
 
djrint( dev )
{
	register int c;
	register struct tty *tp;
	register djn;
	extern djrint();
 
  for( djn=0 ; djn<NDJ11 ; djn++ ) {
	while( (c = dj[djn].djaddr->djrbuf) < 0)	/* char present in silo */
	{
		tp = &dj11[(djn<<4)+((c>>8) & 017)]; /* line number */
		if( c & DJOVERUN )
			djoverrun++;
		if( c & DJFRAME )		/* break */
			if(tp->t_flags & RAW)
				c = 0;	/* null for getty */
			else
				continue; /* ignore framing errors if not raw */
		ttyinput(c, tp);
	}
  }
#ifdef	DJSCANRATE
	if( (dev == -1) && (djscanning) ) timeout( &djrint, -1, DJSCANRATE );
#endif
}
 
djsgtty(dev, v)
int *v;
{
	ttystty(&dj11[dev.d_minor], v);
}
#ifdef	POWER_FAIL

djpowf()
{
	register line;
	register struct djregs *dja;
	register struct tty *tp;
	int djn;

	tp = &dj11[0];
	for( djn = 0 ; djn < NDJ11 ; djn++ ) {
		dja = dj[djn].djaddr;
		for( line = 0 ; line < 16 ; line++, tp++ )
			if( tp->t_state & ISOPEN ) {
				dja->djcsr = DJTIE|DJTSE|DJRE|DJRIE;
				dja->djtcr =| 1 << line;
			}
	}
}
#endif	POWER_FAIL