1*17542Skarels /* tty_subr.c 6.7 84/12/20 */ 21892Swnj 317097Sbloom #include "param.h" 417097Sbloom #include "systm.h" 517097Sbloom #include "conf.h" 617097Sbloom #include "buf.h" 717097Sbloom #include "tty.h" 817097Sbloom #include "clist.h" 932Sbill 101890Swnj char cwaiting; 111890Swnj 1232Sbill /* 1332Sbill * Character list get/put 1432Sbill */ 1532Sbill getc(p) 1612754Ssam register struct clist *p; 1732Sbill { 1832Sbill register struct cblock *bp; 1932Sbill register int c, s; 2032Sbill 21*17542Skarels s = spltty(); 2232Sbill if (p->c_cc <= 0) { 2332Sbill c = -1; 2432Sbill p->c_cc = 0; 2532Sbill p->c_cf = p->c_cl = NULL; 2632Sbill } else { 2732Sbill c = *p->c_cf++ & 0377; 2832Sbill if (--p->c_cc<=0) { 2932Sbill bp = (struct cblock *)(p->c_cf-1); 3032Sbill bp = (struct cblock *) ((int)bp & ~CROUND); 3132Sbill p->c_cf = NULL; 3232Sbill p->c_cl = NULL; 3332Sbill bp->c_next = cfreelist; 3432Sbill cfreelist = bp; 351890Swnj cfreecount += CBSIZE; 361890Swnj if (cwaiting) { 371890Swnj wakeup(&cwaiting); 381890Swnj cwaiting = 0; 391890Swnj } 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; 461890Swnj cfreecount += CBSIZE; 471890Swnj if (cwaiting) { 481890Swnj wakeup(&cwaiting); 491890Swnj cwaiting = 0; 501890Swnj } 5132Sbill } 5232Sbill } 5332Sbill splx(s); 5432Sbill return(c); 5532Sbill } 5632Sbill 5732Sbill /* 5832Sbill * copy clist to buffer. 5932Sbill * return number of bytes moved. 6032Sbill */ 6132Sbill q_to_b(q, cp, cc) 629761Ssam register struct clist *q; 639761Ssam register char *cp; 6432Sbill { 6532Sbill register struct cblock *bp; 6632Sbill register int s; 67*17542Skarels register nc; 6832Sbill char *acp; 6932Sbill 7032Sbill if (cc <= 0) 7132Sbill return(0); 72*17542Skarels s = spltty(); 7332Sbill if (q->c_cc <= 0) { 7432Sbill q->c_cc = 0; 7532Sbill q->c_cf = q->c_cl = NULL; 761890Swnj splx(s); 7732Sbill return(0); 7832Sbill } 7932Sbill acp = cp; 8032Sbill 81*17542Skarels while (cc) { 82*17542Skarels nc = sizeof(struct cblock) - ((int)q->c_cf & CROUND); 83*17542Skarels nc = MIN(nc, cc); 84*17542Skarels nc = MIN(nc, q->c_cc); 85*17542Skarels (void) bcopy(q->c_cf, cp, (unsigned)nc); 86*17542Skarels q->c_cf += nc; 87*17542Skarels q->c_cc -= nc; 88*17542Skarels cc -= nc; 89*17542Skarels cp += nc; 90*17542Skarels if (q->c_cc <= 0) { 91*17542Skarels bp = (struct cblock *)(q->c_cf - 1); 9232Sbill bp = (struct cblock *)((int)bp & ~CROUND); 9332Sbill q->c_cf = q->c_cl = NULL; 9432Sbill bp->c_next = cfreelist; 9532Sbill cfreelist = bp; 961890Swnj cfreecount += CBSIZE; 971890Swnj if (cwaiting) { 981890Swnj wakeup(&cwaiting); 991890Swnj cwaiting = 0; 1001890Swnj } 10132Sbill break; 10232Sbill } 10332Sbill if (((int)q->c_cf & CROUND) == 0) { 10432Sbill bp = (struct cblock *)(q->c_cf); 10532Sbill bp--; 10632Sbill q->c_cf = bp->c_next->c_info; 10732Sbill bp->c_next = cfreelist; 10832Sbill cfreelist = bp; 1091890Swnj cfreecount += CBSIZE; 1101890Swnj if (cwaiting) { 1111890Swnj wakeup(&cwaiting); 1121890Swnj cwaiting = 0; 1131890Swnj } 11432Sbill } 11532Sbill } 11632Sbill splx(s); 11732Sbill return(cp-acp); 11832Sbill } 11932Sbill 12032Sbill /* 12132Sbill * Return count of contiguous characters 12232Sbill * in clist starting at q->c_cf. 12332Sbill * Stop counting if flag&character is non-null. 12432Sbill */ 12532Sbill ndqb(q, flag) 1269761Ssam register struct clist *q; 12732Sbill { 1289761Ssam register cc; 1299761Ssam int s; 13032Sbill 131*17542Skarels s = spltty(); 13232Sbill if (q->c_cc <= 0) { 13332Sbill cc = -q->c_cc; 13432Sbill goto out; 13532Sbill } 13632Sbill cc = ((int)q->c_cf + CBSIZE) & ~CROUND; 13732Sbill cc -= (int)q->c_cf; 13832Sbill if (q->c_cc < cc) 13932Sbill cc = q->c_cc; 14032Sbill if (flag) { 14132Sbill register char *p, *end; 14232Sbill 14332Sbill p = q->c_cf; 14432Sbill end = p; 14532Sbill end += cc; 14632Sbill while (p < end) { 14732Sbill if (*p & flag) { 1481890Swnj cc = (int)p; 1491890Swnj cc -= (int)q->c_cf; 15032Sbill break; 15132Sbill } 15232Sbill p++; 15332Sbill } 15432Sbill } 15532Sbill out: 15632Sbill splx(s); 15732Sbill return(cc); 15832Sbill } 15932Sbill 1601890Swnj 1611890Swnj 16232Sbill /* 1631890Swnj * Flush cc bytes from q. 16432Sbill */ 16532Sbill ndflush(q, cc) 16612754Ssam register struct clist *q; 16712754Ssam register cc; 16832Sbill { 16912754Ssam register struct cblock *bp; 17012754Ssam char *end; 17112754Ssam int rem, s; 17232Sbill 173*17542Skarels s = spltty(); 17410749Seric if (q->c_cc <= 0) { 17532Sbill goto out; 17632Sbill } 1771890Swnj while (cc>0 && q->c_cc) { 1781890Swnj bp = (struct cblock *)((int)q->c_cf & ~CROUND); 1791890Swnj if ((int)bp == (((int)q->c_cl-1) & ~CROUND)) { 1801890Swnj end = q->c_cl; 1811890Swnj } else { 1821890Swnj end = (char *)((int)bp + sizeof (struct cblock)); 1831890Swnj } 1841890Swnj rem = end - q->c_cf; 1851890Swnj if (cc >= rem) { 1861890Swnj cc -= rem; 1871890Swnj q->c_cc -= rem; 18832Sbill q->c_cf = bp->c_next->c_info; 1891890Swnj bp->c_next = cfreelist; 1901890Swnj cfreelist = bp; 1911890Swnj cfreecount += CBSIZE; 1921890Swnj if (cwaiting) { 1931890Swnj wakeup(&cwaiting); 1941890Swnj cwaiting = 0; 1951890Swnj } 19632Sbill } else { 1971890Swnj q->c_cc -= cc; 1981890Swnj q->c_cf += cc; 1991890Swnj if (q->c_cc <= 0) { 2001890Swnj bp->c_next = cfreelist; 2011890Swnj cfreelist = bp; 2021890Swnj cfreecount += CBSIZE; 2031890Swnj if (cwaiting) { 2041890Swnj wakeup(&cwaiting); 2051890Swnj cwaiting = 0; 2061890Swnj } 2071890Swnj } 2081890Swnj break; 20932Sbill } 2101890Swnj } 2111890Swnj if (q->c_cc <= 0) { 21232Sbill q->c_cf = q->c_cl = NULL; 2131890Swnj q->c_cc = 0; 21432Sbill } 21532Sbill out: 21632Sbill splx(s); 21732Sbill } 218172Sbill 2191890Swnj 22032Sbill putc(c, p) 22112754Ssam register struct clist *p; 22232Sbill { 22332Sbill register struct cblock *bp; 22432Sbill register char *cp; 22532Sbill register s; 22632Sbill 227*17542Skarels s = spltty(); 22832Sbill if ((cp = p->c_cl) == NULL || p->c_cc < 0 ) { 22932Sbill if ((bp = cfreelist) == NULL) { 23032Sbill splx(s); 23132Sbill return(-1); 23232Sbill } 23332Sbill cfreelist = bp->c_next; 2341890Swnj cfreecount -= CBSIZE; 23532Sbill bp->c_next = NULL; 23632Sbill p->c_cf = cp = bp->c_info; 23732Sbill } else if (((int)cp & CROUND) == 0) { 23832Sbill bp = (struct cblock *)cp - 1; 23932Sbill if ((bp->c_next = cfreelist) == NULL) { 24032Sbill splx(s); 24132Sbill return(-1); 24232Sbill } 24332Sbill bp = bp->c_next; 24432Sbill cfreelist = bp->c_next; 2451890Swnj cfreecount -= CBSIZE; 24632Sbill bp->c_next = NULL; 24732Sbill cp = bp->c_info; 24832Sbill } 24932Sbill *cp++ = c; 25032Sbill p->c_cc++; 25132Sbill p->c_cl = cp; 25232Sbill splx(s); 25332Sbill return(0); 25432Sbill } 25532Sbill 2561890Swnj 2571890Swnj 25832Sbill /* 25932Sbill * copy buffer to clist. 26032Sbill * return number of bytes not transfered. 26132Sbill */ 26232Sbill b_to_q(cp, cc, q) 26312754Ssam register char *cp; 26412754Ssam struct clist *q; 26512754Ssam register int cc; 26632Sbill { 26732Sbill register char *cq; 26832Sbill register struct cblock *bp; 269*17542Skarels register s, nc; 270*17542Skarels int acc; 27132Sbill 27232Sbill if (cc <= 0) 273*17542Skarels return(0); 274*17542Skarels acc = cc; 275*17542Skarels s = spltty(); 276*17542Skarels if ((cq = q->c_cl) == NULL || q->c_cc < 0) { 277*17542Skarels if ((bp = cfreelist) == NULL) 278*17542Skarels goto out; 279*17542Skarels cfreelist = bp->c_next; 280*17542Skarels cfreecount -= CBSIZE; 281*17542Skarels bp->c_next = NULL; 282*17542Skarels q->c_cf = cq = bp->c_info; 283*17542Skarels } 284*17542Skarels 285*17542Skarels while (cc) { 28632Sbill if (((int)cq & CROUND) == 0) { 287*17542Skarels bp = (struct cblock *) cq - 1; 288*17542Skarels if ((bp->c_next = cfreelist) == NULL) 289*17542Skarels goto out; 29032Sbill bp = bp->c_next; 29132Sbill cfreelist = bp->c_next; 2921890Swnj cfreecount -= CBSIZE; 29332Sbill bp->c_next = NULL; 294*17542Skarels cq = bp->c_info; 29532Sbill } 296*17542Skarels nc = MIN(cc, sizeof(struct cblock) - ((int)cq & CROUND)); 297*17542Skarels (void) bcopy(cp, cq, (unsigned)nc); 298*17542Skarels cp += nc; 299*17542Skarels cq += nc; 300*17542Skarels cc -= nc; 30132Sbill } 302*17542Skarels out: 303*17542Skarels q->c_cl = cq; 304*17542Skarels q->c_cc += acc - cc; 305*17542Skarels splx(s); 30617368Ssam return (cc); 30732Sbill } 30832Sbill 30932Sbill /* 310172Sbill * Given a non-NULL pointter into the list (like c_cf which 311172Sbill * always points to a real character if non-NULL) return the pointer 312172Sbill * to the next character in the list or return NULL if no more chars. 313172Sbill * 314172Sbill * Callers must not allow getc's to happen between nextc's so that the 315172Sbill * pointer becomes invalid. Note that interrupts are NOT masked. 316172Sbill */ 317172Sbill char * 318172Sbill nextc(p, cp) 31912754Ssam register struct clist *p; 32012754Ssam register char *cp; 321172Sbill { 322172Sbill 323172Sbill if (p->c_cc && ++cp != p->c_cl) { 324172Sbill if (((int)cp & CROUND) == 0) 325172Sbill return (((struct cblock *)cp)[-1].c_next->c_info); 326172Sbill return (cp); 327172Sbill } 328172Sbill return (0); 329172Sbill } 330172Sbill 331172Sbill /* 332172Sbill * Remove the last character in the list and return it. 333172Sbill */ 334172Sbill unputc(p) 33512754Ssam register struct clist *p; 336172Sbill { 337172Sbill register struct cblock *bp; 338172Sbill register int c, s; 339172Sbill struct cblock *obp; 340172Sbill 341*17542Skarels s = spltty(); 342172Sbill if (p->c_cc <= 0) 343172Sbill c = -1; 344172Sbill else { 345172Sbill c = *--p->c_cl; 346172Sbill if (--p->c_cc <= 0) { 347172Sbill bp = (struct cblock *)p->c_cl; 348172Sbill bp = (struct cblock *)((int)bp & ~CROUND); 349172Sbill p->c_cl = p->c_cf = NULL; 350172Sbill bp->c_next = cfreelist; 351172Sbill cfreelist = bp; 3521890Swnj cfreecount += CBSIZE; 353172Sbill } else if (((int)p->c_cl & CROUND) == sizeof(bp->c_next)) { 354172Sbill p->c_cl = (char *)((int)p->c_cl & ~CROUND); 355172Sbill bp = (struct cblock *)p->c_cf; 356172Sbill bp = (struct cblock *)((int)bp & ~CROUND); 357172Sbill while (bp->c_next != (struct cblock *)p->c_cl) 358172Sbill bp = bp->c_next; 359172Sbill obp = bp; 360172Sbill p->c_cl = (char *)(bp + 1); 361172Sbill bp = bp->c_next; 362172Sbill bp->c_next = cfreelist; 363172Sbill cfreelist = bp; 3641890Swnj cfreecount += CBSIZE; 365172Sbill obp->c_next = NULL; 366172Sbill } 367172Sbill } 368172Sbill splx(s); 369172Sbill return (c); 370172Sbill } 371172Sbill 372172Sbill /* 373172Sbill * Put the chars in the from que 374172Sbill * on the end of the to que. 375172Sbill */ 376172Sbill catq(from, to) 37712754Ssam struct clist *from, *to; 378172Sbill { 379*17542Skarels char bbuf[CBSIZE*4]; 380*17542Skarels register s, c; 381172Sbill 382*17542Skarels s = spltty(); 383*17542Skarels if (to->c_cc == 0) { 384*17542Skarels *to = *from; 385*17542Skarels from->c_cc = 0; 386*17542Skarels from->c_cf = NULL; 387*17542Skarels from->c_cl = NULL; 388*17542Skarels splx(s); 389*17542Skarels return; 390*17542Skarels } 391*17542Skarels splx(s); 392*17542Skarels while (from->c_cc > 0) { 393*17542Skarels c = q_to_b(from, bbuf, sizeof bbuf); 394*17542Skarels (void) b_to_q(bbuf, c, to); 395*17542Skarels } 396172Sbill } 397172Sbill 398*17542Skarels #ifdef unneeded 399172Sbill /* 4009761Ssam * Integer (short) get/put 40132Sbill * using clists 40232Sbill */ 403*17542Skarels typedef u_short word_t; 4049761Ssam 40532Sbill getw(p) 4068955Sroot register struct clist *p; 40732Sbill { 408*17542Skarels register int s, c; 409*17542Skarels register struct cblock *bp; 41032Sbill 411*17542Skarels if (p->c_cc <= 1) 412*17542Skarels return(-1); 413*17542Skarels if (p->c_cc & 01) { 414*17542Skarels c = getc(p); 415*17542Skarels return(c | (getc(p)<<8)); 416*17542Skarels } 417*17542Skarels s = spltty(); 418*17542Skarels c = *((word_t *)p->c_cf); 419*17542Skarels p->c_cf += sizeof(word_t); 420*17542Skarels p->c_cc -= sizeof(word_t); 421*17542Skarels if (p->c_cc <= 0) { 422*17542Skarels bp = (struct cblock *)(p->c_cf-1); 423*17542Skarels bp = (struct cblock *) ((int)bp & ~CROUND); 424*17542Skarels p->c_cf = NULL; 425*17542Skarels p->c_cl = NULL; 426*17542Skarels bp->c_next = cfreelist; 427*17542Skarels cfreelist = bp; 428*17542Skarels cfreecount += CBSIZE; 429*17542Skarels if (cwaiting) { 430*17542Skarels wakeup(&cwaiting); 431*17542Skarels cwaiting = 0; 432*17542Skarels } 433*17542Skarels } else if (((int)p->c_cf & CROUND) == 0) { 434*17542Skarels bp = (struct cblock *)(p->c_cf); 435*17542Skarels bp--; 436*17542Skarels p->c_cf = bp->c_next->c_info; 437*17542Skarels bp->c_next = cfreelist; 438*17542Skarels cfreelist = bp; 439*17542Skarels cfreecount += CBSIZE; 440*17542Skarels if (cwaiting) { 441*17542Skarels wakeup(&cwaiting); 442*17542Skarels cwaiting = 0; 443*17542Skarels } 444*17542Skarels } 445*17542Skarels splx(s); 446*17542Skarels return (c); 44732Sbill } 44832Sbill 44932Sbill putw(c, p) 4508955Sroot register struct clist *p; 451*17542Skarels word_t c; 45232Sbill { 45332Sbill register s; 454*17542Skarels register struct cblock *bp; 455*17542Skarels register char *cp; 45632Sbill 457*17542Skarels s = spltty(); 45832Sbill if (cfreelist==NULL) { 45932Sbill splx(s); 46032Sbill return(-1); 46132Sbill } 462*17542Skarels if (p->c_cc & 01) { 463*17542Skarels (void) putc(c, p); 464*17542Skarels (void) putc(c>>8, p); 465*17542Skarels } else { 466*17542Skarels if ((cp = p->c_cl) == NULL || p->c_cc < 0 ) { 467*17542Skarels if ((bp = cfreelist) == NULL) { 468*17542Skarels splx(s); 469*17542Skarels return (-1); 470*17542Skarels } 471*17542Skarels cfreelist = bp->c_next; 472*17542Skarels cfreecount -= CBSIZE; 473*17542Skarels bp->c_next = NULL; 474*17542Skarels p->c_cf = cp = bp->c_info; 475*17542Skarels } else if (((int)cp & CROUND) == 0) { 476*17542Skarels bp = (struct cblock *)cp - 1; 477*17542Skarels if ((bp->c_next = cfreelist) == NULL) { 478*17542Skarels splx(s); 479*17542Skarels return (-1); 480*17542Skarels } 481*17542Skarels bp = bp->c_next; 482*17542Skarels cfreelist = bp->c_next; 483*17542Skarels cfreecount -= CBSIZE; 484*17542Skarels bp->c_next = NULL; 485*17542Skarels cp = bp->c_info; 486*17542Skarels } 487*17542Skarels *(word_t *)cp = c; 488*17542Skarels p->c_cl = cp + sizeof(word_t); 489*17542Skarels p->c_cc += sizeof(word_t); 490*17542Skarels } 49132Sbill splx(s); 4929761Ssam return (0); 49332Sbill } 494*17542Skarels #endif unneeded 495