From: Tom London Date: Tue, 23 Jan 1979 10:56:12 +0000 (-0500) Subject: Bell 32V development X-Git-Tag: Bell-32V~290 X-Git-Url: https://git.subgeniuskitty.com/unix-history/.git/commitdiff_plain/19eb064932cf112b7ca99b3626fbf330bb7c2a2c Bell 32V development Work on file usr/src/slowsys/sys/dz.c Co-Authored-By: John Reiser Synthesized-from: 32v --- diff --git a/usr/src/slowsys/sys/dz.c b/usr/src/slowsys/sys/dz.c new file mode 100644 index 0000000000..9fd7462a5d --- /dev/null +++ b/usr/src/slowsys/sys/dz.c @@ -0,0 +1,319 @@ +/* +* DZ-11 Driver +*/ +# include "../h/param.h" +# include "../h/tty.h" +# include "../h/uba.h" +# include "../h/proc.h" +# include "../h/dir.h" +# include "../h/file.h" +# include "../h/inode.h" +# include "../h/user.h" +# include "../h/conf.h" + +# define DZADDR (UBA0_DEV + 0160100) +# define NDZ (1*8) + +# define BITS7 020 +# define BITS8 030 +# define TWOSB 040 +# define PENABLE 0100 +# define OPAR 0200 +# define MSE 040 /* Master Scan Enable */ +# define RIE 0100 /* Receiver Interrupt Enable */ +# define TIE 040000 /* Transmit interrupt enable */ +# define DZ_IEN (MSE+RIE+TIE) +# define PERROR 010000 +# define FRERROR 020000 +# define SSPEED 7 /* std speed = 300 baud */ + + +# define dzlpr dzrbuf +# define dzmsr dzbrk +# define ON 1 +# define OFF 0 + +struct tty dz_tty[NDZ] ; +int dz_cnt = { NDZ } ; +struct dzregs { + short dzcsr ; + short dzrbuf ; + char dztcr ; + char dzdtr ; + char dztbuf ; + char dzbrk ; + } ; +struct dzregs *dz_addr[] = { + (struct dzregs *)(DZADDR), + (struct dzregs *)(DZADDR+010), + (struct dzregs *)(DZADDR+020), + (struct dzregs *)(DZADDR+030) + } ; +char dz_timer ; +char dz_speeds[] = { + 0, 020 , 021 , 022 , 023 , 024 , 0, 025, + 026 , 027 , 030 , 032 , 034 , 036 , 0 , 0, + } ; + +dzopen(d,flag) +{ + register struct tty *tp ; + register dev ; + extern dzstart() , dzscan() ; + + dev = minor(d); + if (dev >= dz_cnt) { + u.u_error = ENXIO ; + return ; + } + if (dz_timer == 0) { + dz_timer++ ; + timeout(dzscan,0,60) ; + } + tp = &dz_tty[dev] ; + tp->t_addr = ((struct dzregs *)DZADDR) + (dev>>3); + tp->t_oproc = dzstart ; + tp->t_iproc = NULL; + tp->t_state |= WOPEN ; + if ((tp->t_state & ISOPEN) == 0) { + tp->t_erase = CERASE ; + tp->t_kill = CKILL ; + tp->t_ospeed = tp->t_ispeed = SSPEED ; + tp->t_flags = ODDP|EVENP|ECHO|HUPCLS ; + dzparam(dev) ; + } + else + if (tp->t_state&XCLUDE && u.u_uid != 0) { + u.u_error = EBUSY ; + return ; + } + dzmodem(dev,ON) ; + spl5() ; + while ((tp->t_state & CARR_ON) == 0) { + tp->t_state |= WOPEN ; + sleep(&tp->t_rawq,TTIPRI) ; + } + spl0() ; + (*linesw[tp->t_line].l_open)(d,tp); +} + +/* */ + +dzclose(d) +{ + register struct tty *tp ; + register dev ; + + dev = minor(d); + tp = &dz_tty[dev] ; + (*linesw[tp->t_line].l_close)(tp); + if (tp->t_flags & HUPCLS) + dzmodem(dev,OFF) ; + ttyclose(tp); +} + +/* */ + +dzread(d) +{ + register struct tty *tp; + + tp = &dz_tty[minor(d)]; + (*linesw[tp->t_line].l_read)(tp); +} + +/* */ + +dzwrite(d) +{ + register struct tty *tp; + + tp = &dz_tty[minor(d)]; + (*linesw[tp->t_line].l_write)(tp); +} + +/* */ + +dzrint(dev) +{ + register struct tty *tp ; + register int c ; + register struct dzregs *dzaddr ; + + dzaddr = dz_addr[dev] ; + while ((c = dzaddr->dzrbuf) < 0) { /* char present */ + tp = &dz_tty[((c>>8)&07)|(dev<<3)] ; + if (tp >= &dz_tty[dz_cnt]) continue ; + if ((tp->t_state & ISOPEN) == 0) { + wakeup(&tp->t_rawq) ; + continue ; + } + if (c & FRERROR) /* framing error = break */ + if (tp->t_flags & RAW) c = 0 ; /* null for getty */ + else c = 0177 ; /* DEL = interrupt */ + if (c & PERROR) /* parity error */ + if (((tp->t_flags & (EVENP|ODDP)) == EVENP) + || ((tp->t_flags & (EVENP|ODDP)) == ODDP)) + continue ; + (*linesw[tp->t_line].l_rint)(c,tp); + } +} + +/* */ + +dzioctl(dev,cmd,addr,flag) +caddr_t addr; +dev_t dev; +{ + register struct tty *tp; + + tp = &dz_tty[minor(dev)]; + if (ttioccomm(cmd,tp,addr,dev)) { + if (cmd==TIOCSETP || cmd==TIOCSETN) + dzparam(minor(dev)); + } else + u.u_error = ENOTTY; +} + +/* */ + +dzparam(dev) +{ + register struct tty *tp ; + register struct dzregs *dzaddr ; + register short lpr ; + + tp = &dz_tty[dev] ; + dzaddr = dz_addr[dev>>3] ; + dzaddr->dzcsr = DZ_IEN ; + if (tp->t_ispeed == 0) { /* hang up line */ + dzmodem(dev,OFF) ; + return ; + } + lpr = (dz_speeds[tp->t_ispeed]<<8) | (dev & 07) ; + if (tp->t_flags & RAW) lpr |= BITS8 ; + else lpr |= (BITS7|PENABLE) ; + if ((tp->t_flags & EVENP) == 0) lpr |= OPAR ; + if (tp->t_ispeed == 3) /* 110 baud */ + lpr |= TWOSB ; /* 2 stop bits */ + dzaddr->dzlpr = lpr ; +} + +/* */ + +dzxint(dev) +dev_t dev; +{ + register struct tty *tp ; + register struct dzregs *dzaddr ; + register unit ; + + dzaddr = dz_addr[dev] ; + while (dzaddr->dzcsr < 0) { /* Transmit Ready is on */ + unit = (dzaddr->dzcsr >> 8) & 07 ; + tp = &dz_tty[(dev<<3) | unit] ; + /* the following is an attempt to fix what appears + to be a DZ hardware bug which causes the system + to loop here. Transmitting the NUL should not + cause too many problems.... */ + if ((dzaddr->dztcr & (1<dztbuf = 0; + continue; + } + if (tp->t_state & BUSY) { + dzaddr->dztbuf = tp->t_char ; /* output the char */ + tp->t_state &= ~BUSY ; + if (tp->t_line) + (*linesw[tp->t_line].l_start)(tp); + else + dzstart(tp); + continue ; + } + unit = (1<dztcr &= (~unit) ; /* Transmit enable off */ + } +} + +/* */ + +dzstart(tp) +register struct tty *tp ; +{ + register unit , c ; + register struct dzregs *dzaddr ; + extern ttrstrt() ; + int sps ; + + unit = tp - dz_tty ; + dzaddr = dz_addr[unit>>3] ; + unit = 1<<(unit&07) ; + sps = spl5() ; + if (tp->t_state & (TIMEOUT|BUSY|TTSTOP)) { + splx(sps) ; + return ; + } + if ((c = getc(&tp->t_outq)) >= 0) { + if (c >= 0200 && (tp->t_flags&RAW) == 0) { + dzaddr->dztcr &= ~unit ; + tp->t_state |= TIMEOUT ; + timeout(ttrstrt,tp,(c&0177)+6) ; + } + else { + tp->t_char = c ; + tp->t_state |= BUSY ; + dzaddr->dztcr |= unit ; + } + if (tp->t_outq.c_cc <= TTLOWAT && tp->t_state&ASLEEP) { + tp->t_state &= ~ASLEEP ; + wakeup(&tp->t_outq) ; + } + } + splx(sps) ; +} + +/* */ + +dzmodem(dev,flag) +register int dev; +{ + register struct dzregs *dzaddr ; + register char bit ; + + dzaddr = dz_addr[dev>>3] ; + bit = 1<<(dev&07) ; + if (flag == OFF) dzaddr->dzdtr &= ~bit ; + else dzaddr->dzdtr |= bit ; +} + +/* */ + +dzscan() +{ + register i ; + register struct dzregs *dzaddr ; + register bit ; + register struct tty *tp ; + extern dzscan() ; + + for (i = 0 ; i < dz_cnt ; i++) { + dzaddr = dz_addr[i>>3] ; + tp = &dz_tty[i] ; + bit = 1<<(i&07) ; + if (dzaddr->dzmsr & bit) { /* carrier present */ + if ((tp->t_state & CARR_ON) == 0) { + wakeup(&tp->t_rawq) ; + tp->t_state |= CARR_ON ; + } + } + else { + if ((tp->t_state & CARR_ON)) { /* carrier lost */ + signal(tp->t_pgrp,SIGHUP) ; + dzaddr->dzdtr &= ~bit ; + flushtty(tp) ; + } + tp->t_state &= ~CARR_ON ; + } + } + timeout(dzscan,0,2*60) ; +}