Commit | Line | Data |
---|---|---|
4b1939c8 | 1 | /* tty_tb.c 6.1 83/08/13 */ |
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 | ||
31 | struct 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*/ | |
48 | tbopen(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 | */ | |
75 | tbclose(tp) | |
830bbc16 | 76 | register struct tty *tp; |
4f9a21f0 | 77 | { |
830bbc16 | 78 | register int s = spl5(); |
4f9a21f0 | 79 | |
4f9a21f0 SL |
80 | tp->t_cp = 0; |
81 | tp->t_inbuf = 0; | |
82 | tp->t_rawq.c_cc = 0; /* clear queues -- paranoid */ | |
83 | tp->t_canq.c_cc = 0; | |
4f9a21f0 SL |
84 | tp->t_line = 0; /* paranoid: avoid races */ |
85 | splx(s); | |
86 | } | |
87 | ||
88 | /* | |
89 | * Read from a tablet line. | |
90 | * Characters have been buffered in a buffer and | |
91 | * decoded. The coordinates are now sluffed back to the user. | |
92 | */ | |
740e4029 BJ |
93 | tbread(tp, uio) |
94 | register struct tty *tp; | |
95 | struct uio *uio; | |
4f9a21f0 SL |
96 | { |
97 | register int i; | |
98 | register s; | |
13b9086b | 99 | struct tbpos *tbpos; |
4f9a21f0 SL |
100 | |
101 | if ((tp->t_state&TS_CARR_ON)==0) | |
840510a3 | 102 | return (EIO); |
13b9086b SL |
103 | tbpos = &(((struct tb *) (tp->T_LINEP))->tbpos); |
104 | return (uiomove(tbpos, sizeof *tbpos, UIO_READ, uio)); | |
4f9a21f0 SL |
105 | } |
106 | ||
107 | /* | |
108 | * Low level character input routine. | |
109 | * Stuff the character in the buffer, and decode the it | |
110 | * if all the chars are there. | |
111 | * | |
112 | * This routine could be expanded in-line in the receiver | |
113 | * interrupt routine of the dh-11 to make it run as fast as possible. | |
114 | */ | |
840510a3 BJ |
115 | int LASTTABC; |
116 | ||
4f9a21f0 | 117 | tbinput(c, tp) |
840510a3 BJ |
118 | register int c; |
119 | register struct tty *tp; | |
4f9a21f0 | 120 | { |
13b9086b | 121 | register struct tb *tbp = (struct tb *) tp->T_LINEP; |
4f9a21f0 | 122 | |
840510a3 BJ |
123 | if (tp->t_line == TABLDISC) { |
124 | if ((c&0200) || (tp->t_inbuf == MTABCHAR)) { | |
13b9086b | 125 | tp->t_cp = tbp->cbuf; |
4f9a21f0 SL |
126 | tp->t_inbuf = 0; |
127 | } | |
128 | *tp->t_cp++ = c&0177; | |
840510a3 | 129 | if (++tp->t_inbuf == MTABCHAR) |
13b9086b | 130 | tbdecode(tbp->cbuf, &tbp->tbpos); |
840510a3 BJ |
131 | } else if (tp->t_line == NTABLDISC) { |
132 | if ((c&0200) || (tp->t_inbuf == MNTABCHAR)) { | |
13b9086b | 133 | tp->t_cp = tbp->cbuf; |
4f9a21f0 SL |
134 | tp->t_inbuf = 0; |
135 | } | |
136 | *tp->t_cp++ = c&0177; | |
840510a3 | 137 | if (++tp->t_inbuf == MNTABCHAR) |
13b9086b | 138 | tbndecode(tbp->cbuf, &tbp->tbpos); |
4f9a21f0 SL |
139 | } |
140 | } | |
141 | ||
142 | /* | |
143 | * Decode tablet coordinates from ascii to binary. | |
144 | * (gtco 6 character format) | |
145 | */ | |
13b9086b | 146 | tbndecode(cp, tbpos) |
4f9a21f0 | 147 | register char *cp; |
13b9086b | 148 | register struct tbpos *tbpos; |
4f9a21f0 SL |
149 | { |
150 | ||
13b9086b SL |
151 | tbpos->status = *cp>>2; /* this needs to be decoded */ |
152 | tbpos->xpos = ((*cp++)&03)<<14; | |
153 | tbpos->xpos |= (*cp++)<<7; | |
154 | tbpos->xpos |= (*cp++); | |
155 | tbpos->ypos = ((*cp++)&03)<<14; | |
156 | tbpos->ypos |= (*cp++)<<7; | |
157 | tbpos->ypos |= (*cp++); | |
158 | tbpos->scount++; | |
4f9a21f0 SL |
159 | } |
160 | ||
161 | /* | |
162 | * Decode tablet coordinates from ascii to binary. | |
163 | * (hitachi 5 character format) | |
164 | */ | |
13b9086b | 165 | tbdecode(cp, tbpos) |
4f9a21f0 | 166 | register char *cp; |
13b9086b | 167 | register struct tbpos *tbpos; |
4f9a21f0 SL |
168 | { |
169 | register int status; | |
170 | register char byte; | |
171 | ||
172 | byte = *cp++; | |
173 | status = (byte&0100) ? 0100000 : 0; | |
174 | byte &= ~0100; | |
840510a3 | 175 | if (byte > 036) |
4f9a21f0 | 176 | status |= 1<<((byte-040)/2); |
13b9086b SL |
177 | tbpos->xpos = (*cp++)<<7; |
178 | tbpos->xpos |= (*cp++); | |
179 | if (tbpos->xpos < 256) /* tablet wraps around at 256 */ | |
4f9a21f0 | 180 | status &= 077777; /* make it out of proximity */ |
13b9086b SL |
181 | tbpos->ypos = (*cp++)<<7; |
182 | tbpos->ypos |= (*cp++); | |
183 | tbpos->status = status; | |
184 | tbpos->scount++; | |
4f9a21f0 SL |
185 | } |
186 | ||
187 | /* | |
188 | * This routine is called whenever a ioctl is about to be performed | |
189 | * and gets a chance to reject the ioctl. We reject all teletype | |
190 | * oriented ioctl's except those which set the discipline, and | |
191 | * those which get parameters (gtty and get special characters). | |
192 | */ | |
193 | /*ARGSUSED*/ | |
942f05a9 SL |
194 | tbioctl(tp, cmd, data, flag) |
195 | struct tty *tp; | |
196 | caddr_t data; | |
4f9a21f0 SL |
197 | { |
198 | ||
199 | if ((cmd>>8) != 't') | |
200 | return (cmd); | |
201 | switch (cmd) { | |
202 | ||
203 | case TIOCSETD: | |
204 | case TIOCGETD: | |
205 | case TIOCGETP: | |
206 | case TIOCGETC: | |
207 | return (cmd); | |
208 | } | |
209 | u.u_error = ENOTTY; | |
210 | return (0); | |
211 | } | |
212 | #endif |