09500 /* 09501 * KL/DL-11 driver 09502 */ 09503 #include "../h/param.h" 09504 #include "../h/conf.h" 09505 #include "../h/dir.h" 09506 #include "../h/user.h" 09507 #include "../h/tty.h" 09508 #include "../h/systm.h" 09509 09510 /* base address */ 09511 #define KLADDR ((struct device *)0177560) /* console */ 09512 #define KLBASE ((struct device *)0176500) /* kl and dl11-a */ 09513 #define DLBASE ((struct device *)0175610) /* dl-e */ 09514 #define NKL11 1 09515 #define NDL11 0 09516 #define DSRDY 02 09517 #define RDRENB 01 09518 #define DLDELAY 4 /* Extra delay for DL's (double buff) */ 09519 09520 #define NL1 000400 09521 #define NL2 001000 09522 #define CR2 020000 09523 #define FF1 040000 09524 #define TAB1 002000 09525 09526 struct tty kl11[NKL11+NDL11]; 09527 int klstart(); 09528 int ttrstrt(); 09529 char partab[]; 09530 09531 struct device { 09532 int rcsr; 09533 int rbuf; 09534 int tcsr; 09535 int tbuf; 09536 }; 09537 09538 klopen(dev, flag) 09539 dev_t dev; 09540 { 09541 register struct device *addr; 09542 register struct tty *tp; 09543 register d; 09544 09545 d = minor(dev); 09546 if(d >= NKL11+NDL11) { 09547 u.u_error = ENXIO; 09548 return; 09549 } 09550 tp = &kl11[d]; 09551 /* 09552 * set up minor 0 to address KLADDR 09553 * set up minor 1 thru NKL11-1 to address from KLBASE 09554 * set up minor NKL11 on to address from DLBASE 09555 */ 09556 if(d == 0) 09557 addr = KLADDR; 09558 else if(d < NKL11) 09559 addr = KLBASE + (d-1); 09560 else 09561 addr = DLBASE + (d-NKL11); 09562 tp->t_addr = (caddr_t)addr; 09563 tp->t_oproc = klstart; 09564 if ((tp->t_state&ISOPEN) == 0) { 09565 tp->t_state = ISOPEN|CARR_ON; 09566 tp->t_flags = EVENP|LCASE|ECHO|XTABS|CRMOD|CR2; 09567 ttychars(tp); 09568 } 09569 addr->rcsr |= IENABLE|DSRDY|RDRENB; 09570 addr->tcsr |= IENABLE; 09571 ttyopen(dev, tp); 09572 } 09573 09574 klclose(dev, flag) 09575 dev_t dev; 09576 int flag; 09577 { 09578 register struct tty *tp; 09579 09580 tp = &kl11[minor(dev)]; 09581 ttyclose(tp); 09582 } 09583 09584 klread(dev) 09585 dev_t dev; 09586 { 09587 ttread(&kl11[minor(dev)]); 09588 } 09589 09590 klwrite(dev) 09591 dev_t dev; 09592 { 09593 ttwrite(&kl11[minor(dev)]); 09594 } 09595 09596 klxint(dev) 09597 dev_t dev; 09598 { 09599 register struct tty *tp; 09600 09601 tp = &kl11[minor(dev)]; 09602 ttstart(tp); 09603 if (tp->t_state&ASLEEP && tp->t_outq.c_cc<=TTLOWAT) 09604 if (tp->t_chan) 09605 mcstart(tp->t_chan, (caddr_t)&tp->t_outq); 09606 else 09607 wakeup((caddr_t)&tp->t_outq); 09608 } 09609 09610 klrint(dev) 09611 dev_t dev; 09612 { 09613 register int c; 09614 register struct device *addr; 09615 register struct tty *tp; 09616 09617 tp = &kl11[minor(dev)]; 09618 addr = (struct device *)tp->t_addr; 09619 c = addr->rbuf; 09620 addr->rcsr |= RDRENB; 09621 ttyinput(c, tp); 09622 } 09623 09624 klioctl(dev, cmd, addr, flag) 09625 caddr_t addr; 09626 dev_t dev; 09627 { 09628 if (ttioccom(cmd, &kl11[minor(dev)], addr, dev)==0) 09629 u.u_error = ENOTTY; 09630 } 09631 09632 klstart(tp) 09633 register struct tty *tp; 09634 { 09635 register c; 09636 register struct device *addr; 09637 09638 addr = (struct device *)tp->t_addr; 09639 if((addr->tcsr&DONE) == 0) 09640 return; 09641 if ((c=getc(&tp->t_outq)) >= 0) { 09642 if (tp->t_flags&RAW) 09643 addr->tbuf = c; 09644 else if (c<=0177) 09645 addr->tbuf = c | (partab[c]&0200); 09646 else { 09647 timeout(ttrstrt, (caddr_t)tp, (c&0177) + DLDELAY); 09648 tp->t_state |= TIMEOUT; 09649 } 09650 } 09651 } 09652 09653 char *msgbufp = msgbuf; /* Next saved printf character */ 09654 /* 09655 * Print a character on console. 09656 * Attempts to save and restore device 09657 * status. 09658 * If the switches are 0, all 09659 * printing is inhibited. 09660 * 09661 * Whether or not printing is inhibited, 09662 * the last MSGBUFS characters 09663 * are saved in msgbuf for inspection later. 09664 */ 09665 putchar(c) 09666 register c; 09667 { 09668 register s, timo; 09669 09670 if (c != '\0' && c != '\r' && c != 0177) { 09671 *msgbufp++ = c; 09672 if(msgbufp >= &msgbuf[MSGBUFS]) 09673 msgbufp = msgbuf; 09674 } 09675 /* 09676 * If last char was a break or null, don't print 09677 */ 09678 if ((KLADDR->rbuf&0177) == 0) 09679 return; 09680 timo = 30000; 09681 /* 09682 * Try waiting for the console tty to come ready, 09683 * otherwise give up after a reasonable time. 09684 */ 09685 while((KLADDR->tcsr&0200) == 0) 09686 if(--timo == 0) 09687 break; 09688 if(c == 0) 09689 return; 09690 s = KLADDR->tcsr; 09691 KLADDR->tcsr = 0; 09692 KLADDR->tbuf = c; 09693 if(c == '\n') { 09694 putchar('\r'); 09695 putchar(0177); 09696 putchar(0177); 09697 } 09698 putchar(0); 09699 KLADDR->tcsr = s; 09700 } 09701 09702 09703 09704 09705 09706 09707 09708 09709 09710 09711 09712 09713 09714 09715 09716 09717 09718 09719 09720 09721 09722 09723 09724 09725 09726 09727 09728 09729 09730 09731 09732 09733 09734 09735 09736 09737 09738 09739 09740 09741 09742 09743 09744 09745 09746 09747 09748 09749