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