reorganized; t_lstate and t_lflags no more; rewrite of ttyinput
[unix-history] / usr / src / sys / kern / tty_tb.c
CommitLineData
830bbc16 1/* tty_tb.c 4.6 82/10/17 */
4f9a21f0
SL
2
3#include "tb.h"
4#if NTB > 0
5
6#include "../h/param.h"
7#include "../h/systm.h"
8#include "../h/dir.h"
9#include "../h/user.h"
10#include "../h/tty.h"
11#include "../h/proc.h"
12#include "../h/inode.h"
13#include "../h/file.h"
14#include "../h/conf.h"
15#include "../h/buf.h"
740e4029 16#include "../h/uio.h"
4f9a21f0
SL
17
18/*
19 * Line discipline for RS232 tablets.
840510a3 20 * Supplies binary coordinate data.
4f9a21f0 21 *
840510a3
BJ
22 * FIX WAY IN WHICH OVERLAYING IS DONE
23 * MAKE TABLET TYPE AN ioctl TO AVOID HAVING ONE DISCIPLINE PER TABLET TYPE.
4f9a21f0
SL
24 */
25
26#define MTABCHAR 5
27#define MNTABCHAR 6
840510a3 28
4f9a21f0 29struct tbposition {
840510a3
BJ
30 int xpos;
31 int ypos;
32 short status;
33 short scount;
4f9a21f0
SL
34};
35
36/*
37 * Open as tablet discipline. Called when discipline changed
38 * with ioctl, and changes the interpretation of the information
39 * in the tty structure.
40 */
41/*ARGSUSED*/
42tbopen(dev, tp)
942f05a9
SL
43 dev_t dev;
44 register struct tty *tp;
4f9a21f0
SL
45{
46 register struct tbposition *tbp;
47
4f9a21f0 48 if (tp->t_line == TABLDISC || tp->t_line == NTABLDISC) {
830bbc16 49 return (EBUSY);
4f9a21f0
SL
50 wflushtty(tp);
51 tp->t_cp = (char *) &tp->t_un.T_CTLQ; /* overlay control queue */
52 tp->t_inbuf = 0;
53 tbp = (struct tbposition *) &tp->t_rocount;
54 tbp->xpos = tbp->ypos = tbp->status = tbp->scount = 0;
830bbc16 55 return (0);
4f9a21f0
SL
56}
57
58/*
59 * Break down... called when discipline changed or from device
60 * close routine.
61 */
62tbclose(tp)
830bbc16 63 register struct tty *tp;
4f9a21f0 64{
830bbc16 65 register int s = spl5();
4f9a21f0 66
4f9a21f0
SL
67 tp->t_cp = 0;
68 tp->t_inbuf = 0;
69 tp->t_rawq.c_cc = 0; /* clear queues -- paranoid */
70 tp->t_canq.c_cc = 0;
71 tp->t_un.T_CTLQ.c_cc = 0; /* clear overlaid queue status */
72 tp->t_un.T_CTLQ.c_cf = tp->t_un.T_CTLQ.c_cl = NULL;
73 tp->t_line = 0; /* paranoid: avoid races */
74 splx(s);
75}
76
77/*
78 * Read from a tablet line.
79 * Characters have been buffered in a buffer and
80 * decoded. The coordinates are now sluffed back to the user.
81 */
740e4029
BJ
82tbread(tp, uio)
83 register struct tty *tp;
84 struct uio *uio;
4f9a21f0
SL
85{
86 register int i;
87 register s;
88 struct tbposition tbposition;
89
90 if ((tp->t_state&TS_CARR_ON)==0)
840510a3
BJ
91 return (EIO);
92 return (iomove(&tp->t_rocount, sizeof tbposition, UIO_READ, uio));
4f9a21f0
SL
93}
94
95/*
96 * Low level character input routine.
97 * Stuff the character in the buffer, and decode the it
98 * if all the chars are there.
99 *
100 * This routine could be expanded in-line in the receiver
101 * interrupt routine of the dh-11 to make it run as fast as possible.
102 */
840510a3
BJ
103int LASTTABC;
104
4f9a21f0 105tbinput(c, tp)
840510a3
BJ
106 register int c;
107 register struct tty *tp;
4f9a21f0
SL
108{
109
840510a3
BJ
110 if (tp->t_line == TABLDISC) {
111 if ((c&0200) || (tp->t_inbuf == MTABCHAR)) {
4f9a21f0
SL
112 tp->t_cp = (char *) &tp->t_un.T_CTLQ;
113 tp->t_inbuf = 0;
114 }
115 *tp->t_cp++ = c&0177;
840510a3 116 if (++tp->t_inbuf == MTABCHAR)
4f9a21f0 117 tbdecode((char *) &tp->t_un.T_CTLQ,
840510a3
BJ
118 (struct tbposition *) &tp->t_rocount);
119 } else if (tp->t_line == NTABLDISC) {
120 if ((c&0200) || (tp->t_inbuf == MNTABCHAR)) {
4f9a21f0
SL
121 tp->t_cp = (char *) &tp->t_un.T_CTLQ;
122 tp->t_inbuf = 0;
123 }
124 *tp->t_cp++ = c&0177;
840510a3 125 if (++tp->t_inbuf == MNTABCHAR)
4f9a21f0
SL
126 tbndecode((char *) &tp->t_un.T_CTLQ,
127 (struct tbposition *) &tp->t_rocount);
128 }
129}
130
131/*
132 * Decode tablet coordinates from ascii to binary.
133 * (gtco 6 character format)
134 */
135tbndecode(cp, tbposition)
136 register char *cp;
137 register struct tbposition *tbposition;
138{
139
140 tbposition->status = *cp>>2; /* this needs to be decoded */
141 tbposition->xpos = ((*cp++)&03)<<14;
142 tbposition->xpos |= (*cp++)<<7;
143 tbposition->xpos |= (*cp++);
144 tbposition->ypos = ((*cp++)&03)<<14;
145 tbposition->ypos |= (*cp++)<<7;
146 tbposition->ypos |= (*cp++);
147 tbposition->scount++;
148}
149
150/*
151 * Decode tablet coordinates from ascii to binary.
152 * (hitachi 5 character format)
153 */
154tbdecode(cp, tbposition)
155 register char *cp;
156 register struct tbposition *tbposition;
157{
158 register int status;
159 register char byte;
160
161 byte = *cp++;
162 status = (byte&0100) ? 0100000 : 0;
163 byte &= ~0100;
840510a3 164 if (byte > 036)
4f9a21f0
SL
165 status |= 1<<((byte-040)/2);
166 tbposition->xpos = (*cp++)<<7;
167 tbposition->xpos |= (*cp++);
840510a3 168 if (tbposition->xpos < 256) /* tablet wraps around at 256 */
4f9a21f0
SL
169 status &= 077777; /* make it out of proximity */
170 tbposition->ypos = (*cp++)<<7;
171 tbposition->ypos |= (*cp++);
172 tbposition->status = status;
173 tbposition->scount++;
174}
175
176/*
177 * This routine is called whenever a ioctl is about to be performed
178 * and gets a chance to reject the ioctl. We reject all teletype
179 * oriented ioctl's except those which set the discipline, and
180 * those which get parameters (gtty and get special characters).
181 */
182/*ARGSUSED*/
942f05a9
SL
183tbioctl(tp, cmd, data, flag)
184 struct tty *tp;
185 caddr_t data;
4f9a21f0
SL
186{
187
188 if ((cmd>>8) != 't')
189 return (cmd);
190 switch (cmd) {
191
192 case TIOCSETD:
193 case TIOCGETD:
194 case TIOCGETP:
195 case TIOCGETC:
196 return (cmd);
197 }
198 u.u_error = ENOTTY;
199 return (0);
200}
201#endif