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