## diffname port/devscc.c 1991/0601
## diff -e /dev/null /n/bootesdump/1991/0601/sys/src/9/port/devscc.c
0a
#include "u.h"
#include "lib.h"
#include "mem.h"
#include "dat.h"
#include "fns.h"
#include "io.h"
#include "errno.h"
#include "devtab.h"
/*
* Driver for the Z8530.
*/
enum
{
/* wr 0 */
ResExtPend= 2<<3,
ResTxPend= 5<<3,
ResErr= 6<<3,
/* wr 1 */
ExtIntEna= 1<<0,
TxIntEna= 1<<1,
RxIntDis= 0<<3,
RxIntFirstEna= 1<<3,
RxIntAllEna= 2<<3,
/* wr 3 */
RxEna= 1,
Rx5bits= 0<<6,
Rx7bits= 1<<6,
Rx6bits= 2<<6,
Rx8bits= 3<<6,
/* wr 4 */
SyncMode= 0<<2,
Rx1stop= 1<<2,
Rx1hstop= 2<<2,
Rx2stop= 3<<2,
X16= 1<<6,
/* wr 5 */
TxRTS= 1<<1,
TxEna= 1<<3,
TxBreak= 1<<4,
TxDTR= 1<<7,
Tx5bits= 0<<5,
Tx7bits= 1<<5,
Tx6bits= 2<<5,
Tx8bits= 3<<5,
/* wr 9 */
IntEna= 1<<3,
ResetB= 1<<6,
ResetA= 2<<6,
HardReset= 3<<6,
/* wr 11 */
TRxCOutBR= 2,
TxClockBR= 2<<3,
RxClockBR= 2<<5,
TRxCOI= 1<<2,
/* wr 14 */
BREna= 1,
BRSource= 2,
/* rr 0 */
RxReady= 1,
TxReady= 1<<2,
RxDCD= 1<<3,
RxCTS= 1<<5,
RxBreak= 1<<7,
/* rr 3 */
ExtPendB= 1,
TxPendB= 1<<1,
RxPendB= 1<<2,
ExtPendA= 1<<3,
TxPendA= 1<<4,
RxPendA= 1<<5,
};
typedef struct SCC SCC;
struct SCC
{
QLock;
ushort sticky[16]; /* sticky write register values */
uchar *ptr; /* command/pointer register in Z8530 */
uchar *data; /* data register in Z8530 */
int printing; /* true if printing */
/* console interface */
int nostream; /* can't use the stream interface */
IOQ *iq; /* input character queue */
IOQ *oq; /* output character queue */
/* stream interface */
Queue *wq; /* write queue */
Rendez r; /* kproc waiting for input */
Alarm *a; /* alarm for waking the kernel process */
int delay; /* between character input and waking kproc */
int kstarted; /* kproc started */
uchar delim[256]; /* characters that act as delimiters */
};
SCC scc[2];
void
onepointseven(void)
{
int i;
for(i = 0; i < 20; i++)
;
}
/*
* Access registers using the pointer in register 0.
* This is a bit stupid when accessing register 0.
*/
void
sccwrreg(SCC *sp, int addr, int value)
{
onepointseven();
*sp->ptr = addr;
wbflush();
onepointseven();
*sp->ptr = sp->sticky[addr] | value;
wbflush();
}
ushort
sccrdreg(SCC *sp, int addr)
{
onepointseven();
*sp->ptr = addr;
wbflush();
onepointseven();
return *sp->ptr;
}
/*
* set the baud rate by calculating and setting the baudrate
* generator constant. This will work with fairly non-standard
* baud rates.
*/
void
sccsetbaud(SCC *sp, int rate)
{
int brconst;
brconst = (SCCFREQ+16*rate-1)/(2*16*rate) - 2;
sccwrreg(sp, 12, brconst & 0xff);
sccwrreg(sp, 13, (brconst>>8) & 0xff);
}
/*
* toggle DTR
*/
void
sccdtr(SCC *sp, int n)
{
if(n)
sp->sticky[5] |= TxDTR;
else
sp->sticky[5] &=~TxDTR;
sccwrreg(sp, 5, 0);
}
/*
* toggle RTS
*/
void
sccrts(SCC *sp, int n)
{
if(n)
sp->sticky[5] |= TxRTS;
else
sp->sticky[5] &=~TxRTS;
sccwrreg(sp, 5, 0);
}
/*
* send break
*/
void
sccbreak(SCC *sp, int ms)
{
sp->sticky[1] &=~TxIntEna;
sccwrreg(sp, 1, 0);
sccwrreg(sp, 5, TxBreak|TxEna);
tsleep(&u->p->sleep, return0, 0, ms);
sccwrreg(sp, 5, 0);
if(sp->oq){
sp->sticky[1] |= TxIntEna;
sccwrreg(sp, 1, 0);
}
}
/*
* 9600 baud, 1 stop bit, 8 bit chars, no interrupts,
* transmit and receive enabled, interrupts disabled.
*/
void
sccsetup(void)
{
SCC *sp;
static int already;
if(already)
return;
already = 1;
/*
* get port addresses
*/
scc[0].ptr = &SCCADDR->ptra;
scc[0].data = &SCCADDR->dataa;
scc[1].ptr = &SCCADDR->ptrb;
scc[1].data = &SCCADDR->datab;
for(sp = scc; sp < &scc[2]; sp++){
memset(sp->sticky, 0, sizeof(sp->sticky));
/*
* turn on baud rate generator and set rate to 9600 baud.
* use 1 stop bit.
*/
sp->sticky[14] = BRSource;
sccwrreg(sp, 14, 0);
sccsetbaud(sp, 9600);
sp->sticky[4] = Rx1stop | X16;
sccwrreg(sp, 4, 0);
sp->sticky[11] = TxClockBR | RxClockBR | TRxCOutBR | TRxCOI;
sccwrreg(sp, 11, 0);
sp->sticky[14] = BREna | BRSource;
sccwrreg(sp, 14, 0);
/*
* enable I/O, 8 bits/character
*/
sp->sticky[3] = RxEna | Rx8bits;
sccwrreg(sp, 3, 0);
sp->sticky[5] = TxEna | Tx8bits;
sccwrreg(sp, 5, 0);
}
}
/*
* Queue n characters for output; if queue is full, we lose characters.
* Get the output going if it isn't already.
*/
void
sccputs(IOQ *cq, char *s, int n)
{
SCC *sp = cq->ptr;
int ch, x;
x = splhi();
lock(cq);
puts(cq, s, n);
if(sp->printing == 0){
ch = getc(cq);
/*kprint("<start %2.2ux>", ch);*/
if(ch >= 0){
sp->printing = 1;
while((*sp->ptr&TxReady)==0)
;
*sp->data = ch;
}
}
unlock(cq);
splx(x);
}
/*
* an scc interrupt (a damn lot of work for one character)
*/
void
sccintr0(SCC *sp, uchar x)
{
int ch;
IOQ *cq;
if(x & ExtPendB){
/*kprint("scc %d: %2.2ux\n", sp-scc, *sp->ptr);*/
sccwrreg(sp, 0, ResExtPend);
}
if(x & RxPendB){
cq = sp->iq;
while(*sp->ptr&RxReady){
onepointseven();
ch = *sp->data;
if(cq->putc)
(*cq->putc)(cq, ch);
else {
putc(cq, ch);
if(sp->delim[ch])
wakeup(&cq->r);
}
}
}
if(x & TxPendB){
cq = sp->oq;
lock(cq);
ch = getc(cq);
/*kprint("<%2.2ux>", ch);*/
onepointseven();
if(ch < 0){
/*kprint("<done>", ch);*/
sccwrreg(sp, 0, ResTxPend);
sp->printing = 0;
wakeup(&cq->r);
}else
*sp->data = ch;
unlock(cq);
}
}
void
sccintr(void)
{
uchar x;
x = sccrdreg(&scc[0], 3);
sccintr0(&scc[1], x);
sccintr0(&scc[0], x>>3);
}
/*
* turn on a port's interrupts. set DTR and RTS
*/
void
sccdevice(SCC *sp)
{
/*
* turn on both ports
*/
sccsetup();
/*
* set up i/o routines
*/
if(sp->oq){
sp->oq->puts = sccputs;
sp->oq->ptr = sp;
sp->sticky[1] |= TxIntEna | ExtIntEna;
}
if(sp->iq){
sp->iq->ptr = sp;
sp->sticky[1] |= RxIntAllEna | ExtIntEna;
}
/*
* turn on interrupts
*/
sccwrreg(sp, 1, 0);
sp->sticky[9] |= IntEna;
sccwrreg(sp, 9, 0);
/*
* turn on DTR and RTS
*/
sccdtr(sp, 1);
sccrts(sp, 1);
}
/*
* set up an scc port as something other than a stream
*/
void
sccspecial(int port, IOQ *oq, IOQ *iq, int baud)
{
SCC *sp = &scc[port];
sp->nostream = 1;
sp->oq = oq;
sp->iq = iq;
sccdevice(sp);
sccsetbaud(sp, baud);
}
static void scctimer(Alarm*);
static int sccputc(IOQ *, int);
static void sccstopen(Queue*, Stream*);
static void sccstclose(Queue*);
static void sccoput(Queue*, Block*);
static void scckproc(void *);
Qinfo sccinfo =
{
nullput,
sccoput,
sccstopen,
sccstclose,
"scc"
};
/*
* create a helper process per port
*/
static void
scctimer(Alarm *a)
{
SCC *sp = a->arg;
cancel(a);
sp->a = 0;
wakeup(&sp->iq->r);
}
static int
sccputc(IOQ *cq, int ch)
{
SCC *sp = cq->ptr; int r;
r = putc(cq, ch);
/*
* pass upstream within sp->delay milliseconds
*/
if(sp->a==0){
if(sp->delay == 0)
wakeup(&cq->r);
else
sp->a = alarm(sp->delay, scctimer, sp);
}
return r;
}
static void
sccstopen(Queue *q, Stream *s)
{
SCC *sp;
char name[NAMELEN];
kprint("sccstopen: q=0x%ux, inuse=%d, type=%d, dev=%d, id=%d\n",
q, s->inuse, s->type, s->dev, s->id);
sp = &scc[s->id];
qlock(sp);
sp->wq = WR(q);
WR(q)->ptr = sp;
RD(q)->ptr = sp;
sp->delay = 64;
sp->iq->putc = sccputc;
qunlock(sp);
/* start with all characters as delimiters */
memset(sp->delim, 1, sizeof(sp->delim));
if(sp->kstarted == 0){
sp->kstarted = 1;
sprint(name, "scc%d", s->id);
kproc(name, scckproc, sp);
}
}
static void
sccstclose(Queue *q)
{
SCC *sp = q->ptr;
qlock(sp);
kprint("sccstclose: q=0x%ux, id=%d\n", q, sp-scc);
sp->wq = 0;
sp->iq->putc = 0;
WR(q)->ptr = 0;
RD(q)->ptr = 0;
qunlock(sp);
}
static void
sccoput(Queue *q, Block *bp)
{
SCC *sp = q->ptr;
IOQ *cq;
int n, m;
if(sp == 0){
freeb(bp);
return;
}
cq = sp->oq;
if(waserror()){
freeb(bp);
nexterror();
}
if(bp->type == M_CTL){
while (cangetc(cq)) /* let output drain */
sleep(&cq->r, cangetc, cq);
n = strtoul((char *)(bp->rptr+1), 0, 0);
switch(*bp->rptr){
case 'B':
case 'b':
sccsetbaud(sp, n);
break;
case 'D':
case 'd':
sccdtr(sp, n);
break;
case 'K':
case 'k':
sccbreak(sp, n);
break;
case 'R':
case 'r':
sccrts(sp, n);
break;
case 'W':
case 'w':
if(n>=0 && n<1000)
sp->delay = n;
break;
}
}else while((m = BLEN(bp)) > 0){
while ((n = canputc(cq)) == 0){
kprint(" sccoput: sleeping\n");
sleep(&cq->r, canputc, cq);
}
if(n > m)
n = m;
(*cq->puts)(cq, bp->rptr, n);
bp->rptr += n;
}
freeb(bp);
poperror();
}
/*
* process to send bytes upstream for a port
*/
static void
scckproc(void *a)
{
SCC *sp = a;
IOQ *cq = sp->iq;
Block *bp;
int n;
loop:
while ((n = cangetc(cq)) == 0)
sleep(&cq->r, cangetc, cq);
/*kprint(" scckproc: %d\n", n);*/
qlock(sp);
if(sp->wq == 0){
cq->out = cq->in;
}else{
bp = allocb(n);
bp->flags |= S_DELIM;
bp->wptr += gets(cq, bp->wptr, n);
PUTNEXT(RD(sp->wq), bp);
}
qunlock(sp);
goto loop;
}
enum{
Qdir= 0,
Qtty0= STREAMQID(0, Sdataqid),
Qtty0ctl= STREAMQID(0, Sctlqid),
Qtty1= STREAMQID(1, Sdataqid),
Qtty1ctl= STREAMQID(1, Sctlqid),
};
Dirtab sccdir[]={
"tty0", {Qtty0}, 0, 0666,
"tty0ctl", {Qtty0ctl}, 0, 0666,
"tty1", {Qtty1}, 0, 0666,
"tty1ctl", {Qtty1ctl}, 0, 0666,
};
#define NSCC (sizeof sccdir/sizeof(Dirtab))
/*
* allocate the queues if no one else has
*/
void
sccreset(void)
{
SCC *sp;
for(sp = scc; sp < &scc[2]; sp++){
if(sp->nostream)
continue;
sp->iq = ialloc(sizeof(IOQ), 0);
initq(sp->iq);
sp->oq = ialloc(sizeof(IOQ), 0);
initq(sp->oq);
sccdevice(sp);
}
}
void
sccinit(void)
{
}
Chan*
sccattach(char *spec)
{
return devattach('t', spec);
}
Chan*
sccclone(Chan *c, Chan *nc)
{
return devclone(c, nc);
}
int
sccwalk(Chan *c, char *name)
{
return devwalk(c, name, sccdir, NSCC, devgen);
}
void
sccstat(Chan *c, char *dp)
{
switch(c->qid.path){
case Qtty0:
streamstat(c, dp, "tty0");
break;
case Qtty1:
streamstat(c, dp, "tty1");
break;
default:
devstat(c, dp, sccdir, NSCC, devgen);
break;
}
}
Chan*
sccopen(Chan *c, int omode)
{
SCC *sp;
switch(c->qid.path){
case Qtty0:
case Qtty0ctl:
sp = &scc[0];
break;
case Qtty1:
case Qtty1ctl:
sp = &scc[1];
break;
default:
sp = 0;
break;
}
if(sp && sp->nostream)
errors("in use");
if((c->qid.path & CHDIR) == 0)
streamopen(c, &sccinfo);
return devopen(c, omode, sccdir, NSCC, devgen);
}
void
scccreate(Chan *c, char *name, int omode, ulong perm)
{
error(Eperm);
}
void
sccclose(Chan *c)
{
if(c->stream)
streamclose(c);
}
long
sccread(Chan *c, void *buf, long n, ulong offset)
{
SCC *sp = &scc[0]; int s;
switch(c->qid.path&~CHDIR){
case Qdir:
return devdirread(c, buf, n, sccdir, NSCC, devgen);
case Qtty1ctl:
++sp;
/* fall through */
case Qtty0ctl:
if(offset)
return 0;
s = splhi();
*(uchar *)buf = *sp->ptr;
splx(s);
return 1;
}
return streamread(c, buf, n);
}
long
sccwrite(Chan *c, void *va, long n, ulong offset)
{
return streamwrite(c, va, n, 0);
}
void
sccremove(Chan *c)
{
error(Eperm);
}
void
sccwstat(Chan *c, char *dp)
{
error(Eperm);
}
.
## diffname port/devscc.c 1991/0604
## diff -e /n/bootesdump/1991/0601/sys/src/9/port/devscc.c /n/bootesdump/1991/0604/sys/src/9/port/devscc.c
334,338d
216,219c
scc[0].ptr = &dev->ptra;
scc[0].data = &dev->dataa;
scc[1].ptr = &dev->ptrb;
scc[1].data = &dev->datab;
.
211a
dev = addr;
.
205a
SCCdev *dev;
.
204c
sccsetup(void *addr)
.
200c
* default is 9600 baud, 1 stop bit, 8 bit chars, no interrupts,
.
## diffname port/devscc.c 1991/0606
## diff -e /n/bootesdump/1991/0604/sys/src/9/port/devscc.c /n/bootesdump/1991/0606/sys/src/9/port/devscc.c
583c
sccenable(sp);
.
374c
sccenable(sp);
.
334c
sccenable(SCC *sp)
.
299c
if(sp->delim[ch/8] & (1<<(ch&7)) )
.
104c
uchar delim[256/8]; /* characters that act as delimiters */
.
## diffname port/devscc.c 1991/0607
## diff -e /n/bootesdump/1991/0606/sys/src/9/port/devscc.c /n/bootesdump/1991/0607/sys/src/9/port/devscc.c
311d
308d
287d
## diffname port/devscc.c 1991/0727
## diff -e /n/bootesdump/1991/0607/sys/src/9/port/devscc.c /n/bootesdump/1991/0727/sys/src/9/port/devscc.c
372a
if(iq){
/*
* Stupid HACK to undo a stupid hack
*/
if(iq == &kbdq)
kbdq.putc = kbdcr2nl;
}
.
## diffname port/devscc.c 1991/1003
## diff -e /n/bootesdump/1991/0727/sys/src/9/port/devscc.c /n/bootesdump/1991/1003/sys/src/9/port/devscc.c
510,511c
/* obsolete */
.
447,449d
443,444d
402,430d
398,400d
383d
326a
void
sccclock(void)
{
SCC *sp;
IOQ *cq;
for(sp = scc; sp < &scc[2]; sp++){
cq = sp->iq;
if(sp->wq && cangetc(cq))
wakeup(&cq->r);
}
}
.
298,300d
296c
else
.
104d
102d
## diffname port/devscc.c 1991/1115
## diff -e /n/bootesdump/1991/1003/sys/src/9/port/devscc.c /n/bootesdump/1991/1115/sys/src/9/port/devscc.c
676a
USED(c, dp);
.
670a
USED(c);
.
651c
case Qeia0ctl:
.
648c
case Qeia1ctl:
.
629a
USED(c, name, omode, perm);
.
610,611c
case Qeia1:
case Qeia1ctl:
.
606,607c
case Qeia0:
case Qeia0ctl:
.
591,592c
case Qeia1:
streamstat(c, dp, "eia1");
.
588,589c
case Qeia0:
streamstat(c, dp, "eia0");
.
534,537c
"eia0", {Qeia0}, 0, 0666,
"eia0ctl", {Qeia0ctl}, 0, 0666,
"eia1", {Qeia1}, 0, 0666,
"eia1ctl", {Qeia1ctl}, 0, 0666,
.
527,530c
Qeia0= STREAMQID(0, Sdataqid),
Qeia0ctl= STREAMQID(0, Sctlqid),
Qeia1= STREAMQID(1, Sdataqid),
Qeia1ctl= STREAMQID(1, Sctlqid),
.
## diffname port/devscc.c 1991/1225
## diff -e /n/bootesdump/1991/1115/sys/src/9/port/devscc.c /n/bootesdump/1991/1225/sys/src/9/port/devscc.c
660c
errors("bad qid");
.
646,658c
if(c->qid.path == CHDIR)
return devdirread(c, buf, n, sccdir, 2*nscc, devgen);
switch(STREAMTYPE(c->qid.path)){
case Sdataqid:
return streamread(c, buf, n);
case Sctlqid:
sprint(b, "%d", STREAMID(c->qid.path));
return stringread(buf, n, b, offset);
.
644c
SCC *sp;
char b[8];
.
624c
}
return devopen(c, omode, sccdir, 2*nscc, devgen);
.
605,622c
if(c->qid.path != CHDIR){
sp = scc[STREAMID(c->qid.path)];
if(sp->nostream)
errors("in use");
.
595c
devstat(c, dp, sccdir, 2*nscc, devgen);
.
591,593d
587,589c
int i;
i = STREAMID(c->qid.path);
switch(STREAMTYPE(c->qid.path)){
case Sdataqid:
streamstat(c, dp, sccdir[2*i].name);
.
581c
return devwalk(c, name, sccdir, 2*nscc, devgen);
.
550c
sccdir = ialloc(2 * nscc * sizeof(Dirtab), 0);
dp = sccdir;
for(i = 0; i < nscc; i++){
/* 2 directory entries per port */
sprint(dp->name, "eia%d", i);
dp->qid.path = STREAMQID(i, Sdataqid);
dp->perm = 0666;
dp++;
sprint(dp->name, "eia%dctl", i);
dp->qid.path = STREAMQID(i, Sctlqid);
dp->perm = 0666;
dp++;
/* set up queues if a stream port */
sp = scc[i];
.
548a
int i;
Dirtab *dp;
.
543c
* create 2 directory entries for each 'sccsetup' ports.
* allocate the queues if no one else has.
.
533,541d
525,531c
Dirtab *sccdir;
.
464c
if(BLEN(bp)>4 && strncmp((char*)(bp->rptr+1), "reak", 4) == 0)
sccbreak(sp, 0);
else
sccsetbaud(sp, n);
.
433d
413c
sp = scc[s->id];
.
374c
SCC *sp = scc[port];
.
328c
for(i = 0; i < nscc; i++){
sp = scc[i];
.
326a
int i;
.
317,319c
for(i = 0; i < nscc; i += 2){
x = sccrdreg(scc[i], 3);
if(x & (ExtPendB|RxPendB|TxPendB))
sccintr0(scc[i+1], x);
x = x >> 3;
if(x & (ExtPendB|RxPendB|TxPendB))
sccintr0(scc[i], x);
}
.
315a
int i;
.
216,245c
sp = ialloc(sizeof(SCC), 0);
scc[nscc] = sp;
sp->ptr = &dev->ptra;
sp->data = &dev->dataa;
sp->freq = freq;
sccsetup0(sp);
sp = ialloc(sizeof(SCC), 0);
scc[nscc+1] = sp;
sp->ptr = &dev->ptrb;
sp->data = &dev->datab;
sp->freq = freq;
sccsetup0(sp);
nscc += 2;
.
214c
* allocate a structure, set port addresses, and setup the line
.
208,210d
206d
202c
sccsetup(void *addr, ulong freq)
.
200a
static void
sccsetup0(SCC *sp)
{
memset(sp->sticky, 0, sizeof(sp->sticky));
/*
* turn on baud rate generator and set rate to 9600 baud.
* use 1 stop bit.
*/
sp->sticky[14] = BRSource;
sccwrreg(sp, 14, 0);
sccsetbaud(sp, 9600);
sp->sticky[4] = Rx1stop | X16;
sccwrreg(sp, 4, 0);
sp->sticky[11] = TxClockBR | RxClockBR | TRxCOutBR | TRxCOI;
sccwrreg(sp, 11, 0);
sp->sticky[14] = BREna | BRSource;
sccwrreg(sp, 14, 0);
/*
* enable I/O, 8 bits/character
*/
sp->sticky[3] = RxEna | Rx8bits;
sccwrreg(sp, 3, 0);
sp->sticky[5] = TxEna | Tx8bits;
sccwrreg(sp, 5, 0);
}
.
185a
if(ms == 0)
ms = 100;
.
149a
brconst = (sp->freq+16*rate-1)/(2*16*rate) - 2;
.
148c
if(rate == 0)
errors("bad baud rate");
.
105a
int nscc;
SCC *scc[8]; /* up to 4 8530's */
.
104d
91a
ulong freq; /* clock frequency */
.
## diffname port/devscc.c 1992/0111
## diff -e /n/bootesdump/1991/1225/sys/src/9/port/devscc.c /n/bootesdump/1992/0111/sys/src/9/port/devscc.c
7c
#include "../port/error.h"
.
## diffname port/devscc.c 1992/0114
## diff -e /n/bootesdump/1992/0111/sys/src/9/port/devscc.c /n/bootesdump/1992/0114/sys/src/9/port/devscc.c
670c
error(Egreg);
.
634c
error(Einuse);
.
152c
error(Ebadctl);
.
## diffname port/devscc.c 1992/0129
## diff -e /n/bootesdump/1992/0114/sys/src/9/port/devscc.c /n/bootesdump/1992/0129/sys/src/9/port/devscc.c
504a
break;
case 'X':
case 'x':
sp->xonoff = n;
.
312a
if (sp->blocked) {
sccwrreg(sp, 0, ResTxPend);
sp->printing = 0;
return;
}
.
305a
if (ch == CTLS && sp->xonoff)
sp->blocked = 1;
else if (ch == CTLQ && sp->xonoff) {
sp->blocked = 0;
sccputs(sp->oq, "", 0);
}
.
275c
if(sp->printing == 0 && sp->blocked==0){
.
107a
#define CTLS 023
#define CTLQ 021
.
103a
/* idiot flow control */
int xonoff; /* true if we obey this tradition */
int blocked; /* abstinence */
.
## diffname port/devscc.c 1992/0321
## diff -e /n/bootesdump/1992/0129/sys/src/9/port/devscc.c /n/bootesdump/1992/0321/sys/src/9/port/devscc.c
2c
#include "../port/lib.h"
.
## diffname port/devscc.c 1992/0326
## diff -e /n/bootesdump/1992/0321/sys/src/9/port/devscc.c /n/bootesdump/1992/0326/sys/src/9/port/devscc.c
509a
break;
case 'P':
case 'p':
sccparity(sp, *(bp->rptr+1));
.
165a
void
sccparity(SCC *sp, char type)
{
int val;
switch(type){
case 'e':
val = ParEven;
break;
case 'o':
val = ParOdd;
break;
default:
val = ParOff;
break;
}
sp->sticky[4] = (sp->sticky[4] & ~ParMask) | val;
sccwrreg(sp, 4, 0);
}
.
35a
ParEven= 3<<0,
ParOdd= 1<<0,
ParOff= 0<<0,
ParMask= 3<<0,
.
## diffname port/devscc.c 1992/0519
## diff -e /n/bootesdump/1992/0326/sys/src/9/port/devscc.c /n/bootesdump/1992/0519/sys/src/9/port/devscc.c
454d
## diffname port/devscc.c 1992/0522
## diff -e /n/bootesdump/1992/0519/sys/src/9/port/devscc.c /n/bootesdump/1992/0522/sys/src/9/port/devscc.c
718a
return 0; /* not reached */
.
## diffname port/devscc.c 1992/0602
## diff -e /n/bootesdump/1992/0522/sys/src/9/port/devscc.c /n/bootesdump/1992/0602/sys/src/9/port/devscc.c
106d
## diffname port/devscc.c 1992/0617
## diff -e /n/bootesdump/1992/0602/sys/src/9/port/devscc.c /n/bootesdump/1992/0617/sys/src/9/port/devscc.c
532a
case 'L':
case 'l':
sccbits(sp, n);
break;
.
189a
* set bits/character, default 8
*/
void
sccbits(SCC *sp, int n)
{
int val;
int rbits, tbits;
switch(n){
case 5:
rbits = Rx5bits;
tbits = Tx5bits;
break;
case 6:
rbits = Rx6bits;
tbits = Tx6bits;
break;
case 7:
rbits = Rx7bits;
tbits = Tx7bits;
break;
case 8:
default:
rbits = Rx8bits;
tbits = Tx8bits;
break;
}
sp->sticky[3] = (sp->sticky[3]&~Rxbitmask) | rbits;
sccwrreg(sp, 3, 0);
sp->sticky[5] = (sp->sticky[5]&~Txbitmask) | tbits;
sccwrreg(sp, 5, 0);
}
/*
.
54a
Txbitmask= 3<<5,
.
33a
Rxbitmask= 3<<6,
.
## diffname port/devscc.c 1992/0620
## diff -e /n/bootesdump/1992/0617/sys/src/9/port/devscc.c /n/bootesdump/1992/0620/sys/src/9/port/devscc.c
650c
sccdir = xalloc(2 * nscc * sizeof(Dirtab));
.
318c
sp = xalloc(sizeof(SCC));
.
312c
sp = xalloc(sizeof(SCC));
.
300a
.
## diffname port/devscc.c 1992/0622
## diff -e /n/bootesdump/1992/0620/sys/src/9/port/devscc.c /n/bootesdump/1992/0622/sys/src/9/port/devscc.c
670c
sp->oq = xalloc(sizeof(IOQ));
.
668c
sp->iq = xalloc(sizeof(IOQ));
.
## diffname port/devscc.c 1992/0623
## diff -e /n/bootesdump/1992/0622/sys/src/9/port/devscc.c /n/bootesdump/1992/0623/sys/src/9/port/devscc.c
757c
return readstr(offset, buf, n, b);
.
## diffname port/devscc.c 1992/0711
## diff -e /n/bootesdump/1992/0623/sys/src/9/port/devscc.c /n/bootesdump/1992/0711/sys/src/9/port/devscc.c
765a
USED(offset);
.
746d
197d
## diffname port/devscc.c 1992/0722
## diff -e /n/bootesdump/1992/0711/sys/src/9/port/devscc.c /n/bootesdump/1992/0722/sys/src/9/port/devscc.c
488a
void
sccrawput(int port, int c)
{
SCC *sp = scc[port];
if(c == '\n') {
sccrawput(port, '\r');
delay(100);
}
while((*sp->ptr&TxReady)==0)
;
*sp->data = c;
}
.
## diffname port/devscc.c 1992/0826
## diff -e /n/bootesdump/1992/0722/sys/src/9/port/devscc.c /n/bootesdump/1992/0826/sys/src/9/port/devscc.c
721c
streamstat(c, dp, sccdir[2*i].name, sccdir[2*i].perm);
.
## diffname port/devscc.c 1992/0922
## diff -e /n/bootesdump/1992/0826/sys/src/9/port/devscc.c /n/bootesdump/1992/0922/sys/src/9/port/devscc.c
323c
sccsetup0(sp, brsource);
.
317c
sccsetup0(sp, brsource);
.
302c
sccsetup(void *addr, ulong freq, int brsource)
.
289c
sp->sticky[14] = BREna;
if(brsource)
sp->sticky[14] |= BRSource;
.
287c
sp->sticky[11] = TxClockBR | RxClockBR | TRxCOutBR /*| TRxCOI*/;
.
274c
sccsetup0(SCC *sp, int brsource)
.
## diffname port/devscc.c 1992/1020
## diff -e /n/bootesdump/1992/0922/sys/src/9/port/devscc.c /n/bootesdump/1992/1020/sys/src/9/port/devscc.c
738c
if(sp->special)
.
682c
if(sp->special)
.
545a
if(sp->special)
return;
.
476c
sp->special = 1;
.
101c
int special; /* can't use the stream interface */
.
## diffname port/devscc.c 1992/1021
## diff -e /n/bootesdump/1992/1020/sys/src/9/port/devscc.c /n/bootesdump/1992/1021/sys/src/9/port/devscc.c
480c
if(baud)
sccsetbaud(sp, baud);
.
372c
ch = *sp->data & sp->mask;
.
300a
sp->mask = 0xff;
.
213a
sp->mask = 0xff;
.
208a
sp->mask = 0x7f;
.
204a
sp->mask = 0x3f;
.
200a
sp->mask = 0x1f;
.
98a
uchar mask; /* bits/char */
.
## diffname port/devscc.c 1992/1104
## diff -e /n/bootesdump/1992/1021/sys/src/9/port/devscc.c /n/bootesdump/1992/1104/sys/src/9/port/devscc.c
287c
sp->sticky[14] = brsource ? BRSource : 0;
.
## diffname port/devscc.c 1992/1201
## diff -e /n/bootesdump/1992/1104/sys/src/9/port/devscc.c /n/bootesdump/1992/1201/sys/src/9/port/devscc.c
710c
return devattach(SCCTYPE, spec);
.
423a
return j;
.
422c
++j, sccintr0(scc[i], x);
.
419c
++j, sccintr0(scc[i+1], x);
.
416c
for(i = j = 0; i < nscc; i += 2){
.
414c
int i, j;
.
410c
int
.
127a
#endif
.
120a
#ifdef Zduart
#define SCCTYPE 'z'
#define onepointseven()
#else
#define SCCTYPE 't'
.
## diffname port/devscc.c 1993/0226
## diff -e /n/bootesdump/1992/1201/sys/src/9/port/devscc.c /n/bootesdump/1993/0226/sys/src/9/port/devscc.c
597a
break;
case 'C':
case 'c':
sccextclk(sp, n);
.
588c
if(*bp->rptr == '!') /* do it now! */
++bp->rptr;
else while(cangetc(cq)) /* else let output drain */
.
488a
/* let output drain */
if(sp->oq){
while(cangetc(sp->oq))
sleep(&sp->oq->r, cangetc, sp->oq);
tsleep(&sp->oq->r, cangetc, sp->oq, 50);
}
.
235a
* set/clear external clock mode; the indigo uses the CTS pin,
* so we disable external interrupts.
*/
void
sccextclk(SCC *sp, int n)
{
if(n){
sp->sticky[1] &= ~ExtIntEna;
sp->sticky[11] = TxClockTRxC | RxClockTRxC;
}else{
sp->sticky[1] |= ExtIntEna;
sp->sticky[11] = TxClockBR | RxClockBR | TRxCOutBR;
}
sccwrreg(sp, 1, 0);
sccwrreg(sp, 11, 0);
}
/*
.
66a
RxClockTRxC= 1<<5,
.
65a
TxClockTRxC= 1<<3,
.
## diffname port/devscc.c 1993/0501
## diff -e /n/bootesdump/1993/0226/sys/src/9/port/devscc.c /n/fornaxdump/1993/0501/sys/src/brazil/port/devscc.c
627,630d
615,617c
while (cangetc(cq)) /* let output drain */
.
509,515d
238,255d
68d
66d
## diffname port/devscc.c 1993/1124 # deleted
## diff -e /n/fornaxdump/1993/0501/sys/src/brazil/port/devscc.c /n/fornaxdump/1993/1124/sys/src/brazil/port/devscc.c
1,814d
|