Research V4 development
[unix-history] / sys / dmr / dc.c
#
/*
* DC-11 driver
*/
#include "/sys/nsys/param.h"
#include "/sys/nsys/conf.h"
#include "/sys/nsys/user.h"
#include "/sys/nsys/tty.h"
#include "/sys/nsys/proc.h"
/* base address */
#define DCADDR 0174000
/* Control bits */
#define CDLEAD 01
#define CARRIER 04
#define SPEED1 010
#define STOP1 0400
#define RQSEND 01
#define PARITY 040
#define ERROR 0100000
#define CTRANS 040000
#define RINGIND 020000
struct tty dc11[NDC11];
struct dcregs {
int dcrcsr;
int dcrbuf;
int dctcsr;
int dctbuf;
};
struct {
char lbyte;
char hbyte;
};
int dcrstab[] {
0, /* 0 baud */
0, /* 75 baud */
0, /* 110 baud */
01101, /* 134.5 baud: 7b/ch, speed 0 */
0111, /* 150 baud: 8b/ch, speed 1 */
0121, /* 300 baud: 8b/ch, speed 2 */
0, /* 600 baud */
0131, /* 1200 baud */
0, /* 1800 baud */
0, /* 2400 baud */
0, /* 4800 baud */
0, /* 9600 baud */
0, /* X0 */
0, /* X1 */
0, /* X2 */
0 /* X3 */
};
int dctstab[] {
0, /* 0 baud */
0, /* 75 baud */
0, /* 110 baud */
0501, /* 134.5 baud: stop 1 */
0511, /* 150 baud */
0521, /* 300 baud */
0, /* 600 baud */
0531, /* 1200 baud */
0, /* 1800 baud */
0, /* 2400 baud */
0, /* 4800 baud */
0, /* 9600 baud */
0, /* X0 */
0, /* X1 */
0, /* X2 */
0 /* X3 */
};
dcopen(dev, flag)
{
struct tty *tp;
register struct tty *rtp;
int *addr;
if (dev.d_minor >= NDC11) {
u.u_error = ENXIO;
return;
}
rtp = tp = &dc11[dev.d_minor];
rtp->t_addr = addr = DCADDR + dev.d_minor*8;
rtp->t_state =| WOPEN;
addr->dcrcsr =| IENABLE|CDLEAD;
if ((rtp->t_state&ISOPEN) == 0) {
rtp->t_quit = 034; /* FS */
rtp->t_intrup = 0177; /* DEL */
addr->dcrcsr = IENABLE|CDLEAD|SPEED1;
addr->dctcsr = IENABLE|SPEED1|STOP1|RQSEND;
rtp->t_state = ISOPEN | WOPEN;
rtp->t_flags = ODDP|EVENP|ECHO;
}
while (((addr->dcrcsr) & CARRIER) == 0)
sleep(&tp->t_rawq, TTIPRI);
tp->t_state =& ~WOPEN;
if (u.u_procp->p_ttyp == 0)
u.u_procp->p_ttyp = tp;
}
dcclose(dev)
{
register struct tty *tp;
(tp = &dc11[dev.d_minor])->t_state = 0;
wflushtty(tp);
}
dcread(dev)
{
register struct tty *tp;
tp = &dc11[dev.d_minor];
if ((tp->t_addr->dcrcsr&CARRIER) != 0)
ttread(tp);
}
dcwrite(dev)
{
register struct tty *tp;
tp = &dc11[dev.d_minor];
if ((tp->t_addr->dcrcsr & CARRIER) != 0)
ttwrite(tp);
}
dcxint(dev)
{
struct tty *tp;
ttstart(tp = &dc11[dev.d_minor]);
if (tp->t_outq.c_cc <= TTLOWAT)
wakeup(&tp->t_outq);
}
dcrint(dev)
{
struct tty *tp;
register struct tty *rtp;
register int c, csr;
tp = rtp = &dc11[dev.d_minor];
c = rtp->t_addr->dcrbuf;
if (((csr = rtp->t_addr->dcrcsr) & CARRIER) == 0) {
if ((rtp->t_state&WOPEN) == 0) {
rtp->t_addr->dcrcsr =& ~CDLEAD;
signal(rtp, SIGHUP);
flushtty(tp);
}
return;
}
if (csr&ERROR || (rtp->t_state&ISOPEN)==0) {
wakeup(rtp);
return;
}
csr =& PARITY;
if (csr&&(rtp->t_flags&ODDP) || !csr&&(rtp->t_flags&EVENP))
ttyinput(c, rtp);
}
dcsgtty(dev, v)
int *v;
{
register struct tty *tp;
struct tty *atp;
register r;
tp = &dc11[dev.d_minor];
if (v) {
v[0] = tp->t_speeds;
v[1] = 0;
v[2] = tp->t_flags;
return;
}
atp = tp;
wflushtty(tp);
tp = atp;
tp->t_speeds = u.u_arg[0];
tp->t_flags = u.u_arg[2];
if (r = dcrstab[tp->t_speeds.lbyte&017])
tp->t_addr->dcrcsr = r;
if (r = dctstab[tp->t_speeds.hbyte&017])
tp->t_addr->dctcsr = r;
}