USG_PG3/usr/source/io1/kl.c
#
/*
*/
/*
* KL/DL-11 driver
*/
#include "../head/param.h"
#include "../head/conf.h"
#include "../head/user.h"
#include "../head/userx.h"
#include "../head/tty.h"
/* base address */
#define KLADDR 0177560 /* console */
#define KLBASE 0176500 /* kl and dl11-a */
#define DLBASE 0175610 /* dl-e */
#define KLTYPE 0
#define DLTYPE 01 /* dl-e */
#define NKL11 1
#define NDL11 0
#define RDRENB 01
#define IENABLE 0100 /* interrupt enable */
#define DTR 02 /* data teminal ready */
#define MENABLE 040 /* modem enable */
int nkl11 NKL11+NDL11;
struct tty kl11[NKL11+NDL11];
struct klregs {
int klrcsr;
int klrbuf;
int kltcsr;
int kltbuf;
}
klopen(dev, flag)
{
register char *addr;
register struct tty *tp;
if(dev.d_minor >= NKL11+NDL11) {
u.u_error = ENXIO;
return;
}
tp = &kl11[dev.d_minor];
/*
* set up minor 0 to address KLADDR
* set up minor 1 thru NKL11-1 to address from KLBASE
* set up minor NKL11 on to address from DLBASE
*/
addr = KLADDR + 8*dev.d_minor;
tp->t_dtype = KLTYPE;
if(dev.d_minor)
addr =+ KLBASE-KLADDR-8;
if(dev.d_minor >= NKL11) {
addr =+ DLBASE-KLBASE-8*NKL11+8;
tp->t_dtype = DLTYPE;
}
tp->t_addr = addr;
tp->t_dev = dev;
if (flag) {
addr->klrcsr =| IENABLE|RDRENB;
addr->kltcsr =| IENABLE;
(*linesw[tp->t_discp].l_open)(dev, tp);
}
}
klclose(dev, flag)
{
register struct tty *tp;
tp = &kl11[dev.d_minor];
(*linesw[tp->t_discp].l_close)(dev, tp);
}
klread(dev)
{
register struct tty *tp;
tp = &kl11[dev.d_minor];
(*linesw[tp->t_discp].l_read)(tp);
}
klwrite(dev)
{
register struct tty *tp;
tp = &kl11[dev.d_minor];
(*linesw[tp->t_discp].l_write)(tp);
}
klsgtty(dev, flag)
{
register struct tty *tp;
tp = &kl11[dev.d_minor];
ttioctl(dev, tp, flag);
}
klxint(dev)
{
register struct tty *tp;
tp = &kl11[dev.d_minor];
ttstart(tp);
}
klrint(dev)
{
register int c, *addr;
register struct tty *tp;
int rcsr, status, action;
tp = &kl11[dev.d_minor];
addr = tp->t_addr;
while ((rcsr = addr->klrcsr)<0 || rcsr&DONE) {
if(rcsr < 0) {
/*
* DL modem transition
*/
status = (rcsr>>10)&(CARRIER|SR)|(rcsr>>12)&CTS;
action = (*linesw[tp->t_discp].l_mt)(tp, status);
if(action > 0)
dlmctl(dev, action);
continue;
}
c = addr->klrbuf & (OVERRUN|FRERROR|PERROR|0377);
addr->klrcsr =| RDRENB;
(*linesw[tp->t_discp].l_rcvd)(c, tp);
}
}
klmctl(dev, action)
{
if(action == FSTATUS)
return(CARRIER|CTS);
}
dlmctl(dev, action)
{
struct tty *tp;
register int sps, *addr;
int rcsr, status;
tp = &kl11[dev.d_minor];
addr = tp->t_addr;
status = 0;
sps = PS->integ;
spl5();
switch(action&03) {
case FSTATUS:
rcsr = addr->klrcsr;
status = (rcsr>>10)&(CARRIER|SR)|(rcsr>>12)&CTS;
break;
case DISABLE:
addr->klrcsr =& ~(ST|RQS|DTR|MENABLE);
break;
case HUP:
addr->klrcsr =& ~DTR;
break;
case TURNON:
/*
* Enable modem and set data terminal ready. Set primary and
* secondary carrier according to bits 2 and 3 of "action"
*/
action =& (RQS|ST);
addr->klrcsr = addr->klrcsr & ~(RQS|ST) | (action|DTR|MENABLE);
}
PS->integ = sps;
return(status);
}