V7/usr/sys/dev/vs.c
/*
* Screw Works interface via DC-11
*/
#include "../h/types.h"
#include "../h/tty.h"
#define VSADDR ((struct device *)0174140)
#define CDLEAD 01
#define B1200 030
#define STOP1 0400
#define CLSEND 02
#define RQSEND 01
#define GO 026
#define COUNT 120
struct device {
int vsrcsr;
int vsrbuf;
int vsxcsr;
int vsxbuf;
};
struct {
struct clist iq;
int vtime;
struct clist oq;
} vs;
vsopen(dev)
{
register c;
c = VSADDR->vsrcsr; /* touch register */
VSADDR->vsrcsr = IENABLE|B1200|CDLEAD;
VSADDR->vsxcsr = STOP1|IENABLE|B1200;
vschar(GO);
}
vsclose(dev)
{
vschar(GO);
VSADDR->vsrcsr &= ~IENABLE;
while (getc(&vs.iq) >= 0);
}
vswrite(dev)
{
register int count, c;
count = 0;
while ((c=cpass()) >= 0) {
if (--count <= 0) {
count = COUNT;
vschar(GO);
}
vschar(c);
}
vschar(GO);
}
vschar(c)
{
spl5();
while (vs.oq.c_cc > 120) {
vsxintr();
sleep((caddr_t)&vs.oq, TTIPRI);
}
putc(c, &vs.oq);
vsxintr();
spl0();
}
vstimo()
{
vs.vtime = 0;
vsxintr();
}
vsxintr()
{
static lchar;
register c;
register int *xcsr;
xcsr = &VSADDR->vsxcsr;
if (*xcsr&DONE) {
if (lchar==GO) {
*xcsr &= ~RQSEND;
lchar = -1;
if (vs.oq.c_cc==0) {
wakeup((caddr_t)&vs.oq);
return;
}
}
if ((*xcsr&CLSEND) == 0) {
*xcsr |= RQSEND;
if ((*xcsr&CLSEND) == 0) {
if (vs.vtime==0) {
vs.vtime++;
timeout(vstimo, (caddr_t)0, 60);
}
return;
}
}
if ((c = getc(&vs.oq)) >= 0)
VSADDR->vsxbuf = lchar = c;
else
*xcsr &= ~RQSEND;
if (vs.oq.c_cc <= 15)
wakeup((caddr_t)&vs.oq);
}
}
vsread(dev)
{
register int c;
spl5();
while ((c = getc(&vs.iq)) < 0)
sleep((caddr_t)&vs.iq, TTIPRI);
spl0();
passc("?0*#?546?213?879?"[c&017]);
}
vsrintr()
{
register int c;
c = VSADDR->vsrbuf; /* Register must be read (?) */
c = VSADDR->vsrbuf;
if (vs.iq.c_cc<=10)
putc(c, &vs.iq);
wakeup((caddr_t)&vs.iq);
}