1*130Sbill /* tty_subr.c 3.2 10/14/12 */ 232Sbill 332Sbill #include "../h/param.h" 432Sbill #include "../h/tty.h" 532Sbill #include "../h/systm.h" 632Sbill #include "../h/conf.h" 732Sbill #include "../h/buf.h" 832Sbill 932Sbill struct cblock { 1032Sbill struct cblock *c_next; 1132Sbill char c_info[CBSIZE]; 1232Sbill }; 1332Sbill 1432Sbill struct cblock cfree[NCLIST]; 1532Sbill struct cblock *cfreelist; 1632Sbill 1732Sbill /* 1832Sbill * Character list get/put 1932Sbill */ 2032Sbill getc(p) 2132Sbill register struct clist *p; 2232Sbill { 2332Sbill register struct cblock *bp; 2432Sbill register int c, s; 2532Sbill 2632Sbill s = spl6(); 2732Sbill if (p->c_cc <= 0) { 2832Sbill c = -1; 2932Sbill p->c_cc = 0; 3032Sbill p->c_cf = p->c_cl = NULL; 3132Sbill } else { 3232Sbill c = *p->c_cf++ & 0377; 3332Sbill if (--p->c_cc<=0) { 3432Sbill bp = (struct cblock *)(p->c_cf-1); 3532Sbill bp = (struct cblock *) ((int)bp & ~CROUND); 3632Sbill p->c_cf = NULL; 3732Sbill p->c_cl = NULL; 3832Sbill bp->c_next = cfreelist; 3932Sbill cfreelist = bp; 4032Sbill } else if (((int)p->c_cf & CROUND) == 0){ 4132Sbill bp = (struct cblock *)(p->c_cf); 4232Sbill bp--; 4332Sbill p->c_cf = bp->c_next->c_info; 4432Sbill bp->c_next = cfreelist; 4532Sbill cfreelist = bp; 4632Sbill } 4732Sbill } 4832Sbill splx(s); 4932Sbill return(c); 5032Sbill } 5132Sbill 5232Sbill /* 5332Sbill * copy clist to buffer. 5432Sbill * return number of bytes moved. 5532Sbill */ 5632Sbill q_to_b(q, cp, cc) 5732Sbill register struct clist *q; 5832Sbill register char *cp; 5932Sbill { 6032Sbill register struct cblock *bp; 6132Sbill register int s; 6232Sbill char *acp; 6332Sbill 6432Sbill if (cc <= 0) 6532Sbill return(0); 6632Sbill s = spl6(); 6732Sbill if (q->c_cc <= 0) { 6832Sbill q->c_cc = 0; 6932Sbill q->c_cf = q->c_cl = NULL; 7032Sbill return(0); 7132Sbill } 7232Sbill acp = cp; 7332Sbill cc++; 7432Sbill 7532Sbill while (--cc) { 7632Sbill *cp++ = *q->c_cf++; 7732Sbill if (--q->c_cc <= 0) { 7832Sbill bp = (struct cblock *)(q->c_cf-1); 7932Sbill bp = (struct cblock *)((int)bp & ~CROUND); 8032Sbill q->c_cf = q->c_cl = NULL; 8132Sbill bp->c_next = cfreelist; 8232Sbill cfreelist = bp; 8332Sbill break; 8432Sbill } 8532Sbill if (((int)q->c_cf & CROUND) == 0) { 8632Sbill bp = (struct cblock *)(q->c_cf); 8732Sbill bp--; 8832Sbill q->c_cf = bp->c_next->c_info; 8932Sbill bp->c_next = cfreelist; 9032Sbill cfreelist = bp; 9132Sbill } 9232Sbill } 9332Sbill splx(s); 9432Sbill return(cp-acp); 9532Sbill } 9632Sbill 9732Sbill 9832Sbill /* 9932Sbill * Return count of contiguous characters 10032Sbill * in clist starting at q->c_cf. 10132Sbill * Stop counting if flag&character is non-null. 10232Sbill */ 10332Sbill ndqb(q, flag) 10432Sbill register struct clist *q; 10532Sbill { 10632Sbill register cc; 10732Sbill int s; 10832Sbill 10932Sbill s = spl6(); 11032Sbill if (q->c_cc <= 0) { 11132Sbill cc = -q->c_cc; 11232Sbill goto out; 11332Sbill } 11432Sbill cc = ((int)q->c_cf + CBSIZE) & ~CROUND; 11532Sbill cc -= (int)q->c_cf; 11632Sbill if (q->c_cc < cc) 11732Sbill cc = q->c_cc; 11832Sbill if (flag) { 11932Sbill register char *p, *end; 12032Sbill 12132Sbill p = q->c_cf; 12232Sbill end = p; 12332Sbill end += cc; 12432Sbill while (p < end) { 12532Sbill if (*p & flag) { 12632Sbill cc = (int)p - (int)q->c_cf; 12732Sbill break; 12832Sbill } 12932Sbill p++; 13032Sbill } 13132Sbill } 13232Sbill out: 13332Sbill splx(s); 13432Sbill return(cc); 13532Sbill } 13632Sbill 13732Sbill 13832Sbill 13932Sbill /* 14032Sbill * Update clist to show that cc characters 14132Sbill * were removed. It is assumed that cc < CBSIZE. 14232Sbill */ 14332Sbill ndflush(q, cc) 14432Sbill register struct clist *q; 14532Sbill register cc; 14632Sbill { 14732Sbill register s; 14832Sbill 14932Sbill if (cc == 0) 15032Sbill return; 15132Sbill s = spl6(); 15232Sbill if (q->c_cc < 0) { 15332Sbill if (q->c_cf != NULL) { 15432Sbill q->c_cc += cc; 15532Sbill q->c_cf += cc; 15632Sbill goto out; 15732Sbill } 15832Sbill q->c_cc = 0; 15932Sbill goto out; 16032Sbill } 16132Sbill if (q->c_cc == 0) { 16232Sbill goto out; 16332Sbill } 16432Sbill q->c_cc -= cc; 16532Sbill q->c_cf += cc; 16632Sbill if (((int)q->c_cf & CROUND) == 0) { 16732Sbill register struct cblock *bp; 16832Sbill 16932Sbill bp = (struct cblock *)(q->c_cf) -1; 17032Sbill if (bp->c_next) { 17132Sbill q->c_cf = bp->c_next->c_info; 17232Sbill } else { 17332Sbill q->c_cf = q->c_cl = NULL; 17432Sbill } 17532Sbill bp->c_next = cfreelist; 17632Sbill cfreelist = bp; 17732Sbill } else 17832Sbill if (q->c_cc == 0) { 17932Sbill register struct cblock *bp; 18032Sbill q->c_cf = (char *)((int)q->c_cf & ~CROUND); 18132Sbill bp = (struct cblock *)(q->c_cf); 18232Sbill bp->c_next = cfreelist; 18332Sbill cfreelist = bp; 18432Sbill q->c_cf = q->c_cl = NULL; 18532Sbill } 18632Sbill out: 18732Sbill splx(s); 18832Sbill } 18932Sbill putc(c, p) 19032Sbill register struct clist *p; 19132Sbill { 19232Sbill register struct cblock *bp; 19332Sbill register char *cp; 19432Sbill register s; 19532Sbill 19632Sbill s = spl6(); 19732Sbill if ((cp = p->c_cl) == NULL || p->c_cc < 0 ) { 19832Sbill if ((bp = cfreelist) == NULL) { 19932Sbill splx(s); 20032Sbill return(-1); 20132Sbill } 20232Sbill cfreelist = bp->c_next; 20332Sbill bp->c_next = NULL; 20432Sbill p->c_cf = cp = bp->c_info; 20532Sbill } else if (((int)cp & CROUND) == 0) { 20632Sbill bp = (struct cblock *)cp - 1; 20732Sbill if ((bp->c_next = cfreelist) == NULL) { 20832Sbill splx(s); 20932Sbill return(-1); 21032Sbill } 21132Sbill bp = bp->c_next; 21232Sbill cfreelist = bp->c_next; 21332Sbill bp->c_next = NULL; 21432Sbill cp = bp->c_info; 21532Sbill } 21632Sbill *cp++ = c; 21732Sbill p->c_cc++; 21832Sbill p->c_cl = cp; 21932Sbill splx(s); 22032Sbill return(0); 22132Sbill } 22232Sbill 22332Sbill 22432Sbill 22532Sbill /* 22632Sbill * copy buffer to clist. 22732Sbill * return number of bytes not transfered. 22832Sbill */ 22932Sbill b_to_q(cp, cc, q) 23032Sbill register char *cp; 23132Sbill struct clist *q; 23232Sbill register int cc; 23332Sbill { 23432Sbill register char *cq; 23532Sbill register struct cblock *bp; 23632Sbill register s, acc; 23732Sbill 23832Sbill if (cc <= 0) 23932Sbill return(0); 24032Sbill acc = cc; 24132Sbill s = spl6(); 24232Sbill if ((cq = q->c_cl) == NULL || q->c_cc < 0) { 24332Sbill if ((bp = cfreelist) == NULL) 24432Sbill goto out; 24532Sbill cfreelist = bp->c_next; 24632Sbill bp->c_next = NULL; 24732Sbill q->c_cf = cq = bp->c_info; 24832Sbill } 24932Sbill 25032Sbill while (cc) { 25132Sbill if (((int)cq & CROUND) == 0) { 25232Sbill bp = (struct cblock *) cq - 1; 25332Sbill if ((bp->c_next = cfreelist) == NULL) 25432Sbill goto out; 25532Sbill bp = bp->c_next; 25632Sbill cfreelist = bp->c_next; 25732Sbill bp->c_next = NULL; 25832Sbill cq = bp->c_info; 25932Sbill } 26032Sbill *cq++ = *cp++; 26132Sbill cc--; 26232Sbill } 26332Sbill out: 26432Sbill q->c_cl = cq; 26532Sbill q->c_cc += acc-cc; 26632Sbill splx(s); 26732Sbill return(cc); 26832Sbill } 26932Sbill 27032Sbill /* 27132Sbill * Initialize clist by freeing all character blocks, then count 27232Sbill * number of character devices. (Once-only routine) 27332Sbill */ 27432Sbill cinit() 27532Sbill { 27632Sbill register int ccp; 27732Sbill register struct cblock *cp; 27832Sbill register struct cdevsw *cdp; 27932Sbill 28032Sbill ccp = (int)cfree; 28132Sbill ccp = (ccp+CROUND) & ~CROUND; 28232Sbill for(cp=(struct cblock *)ccp; cp <= &cfree[NCLIST-1]; cp++) { 28332Sbill cp->c_next = cfreelist; 28432Sbill cfreelist = cp; 28532Sbill } 28632Sbill ccp = 0; 28732Sbill for(cdp = cdevsw; cdp->d_open; cdp++) 28832Sbill ccp++; 28932Sbill nchrdev = ccp; 29032Sbill } 29132Sbill 29232Sbill /* 29332Sbill * integer (2-byte) get/put 29432Sbill * using clists 29532Sbill */ 29632Sbill /* 29732Sbill getw(p) 29832Sbill register struct clist *p; 29932Sbill { 30032Sbill register int s; 30132Sbill 30232Sbill if (p->c_cc <= 1) 30332Sbill return(-1); 30432Sbill s = getc(p); 30532Sbill return(s | (getc(p)<<8)); 30632Sbill } 30732Sbill */ 30832Sbill 30932Sbill putw(c, p) 31032Sbill register struct clist *p; 31132Sbill { 31232Sbill register s; 31332Sbill 31432Sbill s = spl6(); 31532Sbill if (cfreelist==NULL) { 31632Sbill splx(s); 31732Sbill return(-1); 31832Sbill } 319*130Sbill (void) putc(c, p); 320*130Sbill (void) putc(c>>8, p); 32132Sbill splx(s); 32232Sbill return(0); 32332Sbill } 324