xref: /original-bsd/sys/vax/vax/cons.c (revision 55330032)
1 /*	cons.c	4.3	12/17/80	*/
2 
3 /*
4  * Vax console driver and floppy interface
5  */
6 #include "../h/param.h"
7 #include "../h/conf.h"
8 #include "../h/dir.h"
9 #include "../h/user.h"
10 #include "../h/tty.h"
11 #include "../h/systm.h"
12 #include "../h/cons.h"
13 #include "../h/mtpr.h"
14 #include "../h/mx.h"
15 
16 /*
17  * When running dz's using only SAE (silo alarm) on input
18  * it is necessary to call dzrint() at clock interrupt time.
19  * This is unsafe unless spl5()s in tty code are changed to
20  * spl6()s to block clock interrupts.  Note that the dh driver
21  * currently in use works the same way as the dz, even though
22  * we could try to more intelligently manage its silo.
23  * Thus don't take this out if you have no dz's unless you
24  * change clock.c and dhtimer().
25  */
26 #define	spl5	spl6
27 
28 #define	NL1	000400
29 #define	NL2	001000
30 #define	CR2	020000
31 #define	FF1	040000
32 #define	TAB1	002000
33 
34 struct	tty cons;
35 int	cnstart();
36 int	ttrstrt();
37 char	partab[];
38 
39 /*ARGSUSED*/
40 cnopen(dev, flag)
41 dev_t dev;
42 {
43 	register struct tty *tp;
44 
45 	tp = &cons;
46 	tp->t_oproc = cnstart;
47 	tp->t_iproc = NULL;
48 	if ((tp->t_state&ISOPEN) == 0) {
49 		ttychars(tp);
50 		tp->t_state = ISOPEN|CARR_ON;
51 		tp->t_flags = EVENP|ECHO|XTABS|CRMOD;
52 	}
53 	if (tp->t_state&XCLUDE && u.u_uid != 0) {
54 		u.u_error = EBUSY;
55 		return;
56 	}
57 	mtpr(RXCS, mfpr(RXCS)|RXCS_IE);
58 	mtpr(TXCS, mfpr(TXCS)|TXCS_IE);
59 	(*linesw[tp->t_line].l_open)(dev, tp);
60 }
61 
62 /*ARGSUSED*/
63 cnclose(dev)
64 dev_t dev;
65 {
66 	register struct tty *tp;
67 
68 	tp = &cons;
69 	(*linesw[tp->t_line].l_close)(tp);
70 	ttyclose(tp);
71 }
72 
73 /*ARGSUSED*/
74 cnread(dev)
75 dev_t dev;
76 {
77 	register struct tty *tp;
78 
79 	tp = &cons;
80 	(*linesw[tp->t_line].l_read)(tp);
81 }
82 
83 /*ARGSUSED*/
84 cnwrite(dev)
85 dev_t dev;
86 {
87 	register struct tty *tp;
88 
89 	tp = &cons;
90 	(*linesw[tp->t_line].l_write)(tp);
91 }
92 
93 /*
94  * Got a level-20 receive interrupt -
95  * the LSI wants to give us a character.
96  * Catch the character, and see who it goes to.
97  */
98 /*ARGSUSED*/
99 cnrint(dev)
100 dev_t dev;
101 {
102 	register int c;
103 	register struct tty *tp;
104 
105 	c = mfpr(RXDB);
106 	if (c&RXDB_ID) {
107 #if VAX==780
108 		cnrfl(c);
109 #endif
110 		return;
111 	}
112 	tp = &cons;
113 	(*linesw[tp->t_line].l_rint)(c, tp);
114 }
115 
116 /*ARGSUSED*/
117 cnioctl(dev, cmd, addr, flag)
118 dev_t dev;
119 caddr_t addr;
120 {
121 	register struct tty *tp;
122 
123 	tp = &cons;
124 	cmd = (*linesw[tp->t_line].l_ioctl)(tp, cmd, addr);
125 	if (cmd == 0)
126 		return;
127 	if (ttioctl(tp, cmd, addr, flag) == 0)
128 		u.u_error = ENOTTY;
129 }
130 
131 #if VAX==750
132 int	consdone = 1;
133 #endif
134 /*
135  * Got a level-20 transmission interrupt -
136  * the LSI wants another character.  First,
137  * see if we can send something to the typewriter.
138  * If not, try the floppy.
139  */
140 /*ARGSUSED*/
141 cnxint(dev)
142 dev_t dev;
143 {
144 	register struct tty *tp;
145 
146 #if VAX==750
147 	consdone++;
148 #endif
149 	tp = &cons;
150 	tp->t_state &= ~BUSY;
151 	if (tp->t_line)
152 		(*linesw[tp->t_line].l_start)(tp);
153 	else
154 		cnstart(tp);
155 #if VAX==780
156 	if ((tp->t_state & BUSY) == 0)
157 		conxfl();
158 #endif
159 }
160 
161 cnstart(tp)
162 register struct tty *tp;
163 {
164 	register c;
165 	register s;
166 
167 	s = spl5();
168 	if (tp->t_state & (TIMEOUT|BUSY|TTSTOP))
169 		goto out;
170 	if (tp->t_state&ASLEEP && tp->t_outq.c_cc <= TTLOWAT(tp)) {
171 		tp->t_state &= ~ASLEEP;
172 		if (tp->t_chan)
173 			mcstart(tp->t_chan, (caddr_t)&tp->t_outq);
174 		else
175 			wakeup((caddr_t)&tp->t_outq);
176 	}
177 	if (tp->t_outq.c_cc == 0)
178 		goto out;
179 #if VAX==750
180 	if (consdone == 0)
181 		return;
182 #else
183 	if ((mfpr(TXCS)&TXCS_RDY) == 0)
184 		return;
185 #endif
186 	if ((c=getc(&tp->t_outq)) >= 0) {
187 #if VAX==750
188 		consdone = 0;
189 #endif
190 		if (tp->t_flags&RAW)
191 			mtpr(TXDB, c&0xff);
192 		else if (c<=0177)
193 			mtpr(TXDB, (c | (partab[c]&0200))&0xff);
194 		else {
195 			timeout(ttrstrt, (caddr_t)tp, (c&0177));
196 			tp->t_state |= TIMEOUT;
197 			goto out;
198 		}
199 	}
200 	tp->t_state |= BUSY;
201     out:
202 	splx(s);
203 }
204 
205 /*
206  * Print a character on console.
207  * Attempts to save and restore device
208  * status.
209  */
210 cnputc(c)
211 register c;
212 {
213 	register s, timo;
214 
215 	timo = 30000;
216 	/*
217 	 * Try waiting for the console tty to come ready,
218 	 * otherwise give up after a reasonable time.
219 	 */
220 	while((mfpr(TXCS)&TXCS_RDY) == 0)
221 		if(--timo == 0)
222 			break;
223 	if(c == 0)
224 		return;
225 	s = mfpr(TXCS);
226 	mtpr(TXCS, 0);
227 	mtpr(TXDB, c&0xff);
228 	if(c == '\n')
229 		cnputc('\r');
230 	cnputc(0);
231 	mtpr(TXCS, s);
232 }
233