Ausam/sys/dmr/dj.c
#
/*
** 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