1 /* tty_tb.c 6.3 84/08/29 */ 2 3 #include "tb.h" 4 #if NTB > 0 5 6 #include "param.h" 7 #include "systm.h" 8 #include "dir.h" 9 #include "user.h" 10 #include "ioctl.h" 11 #include "tty.h" 12 #include "proc.h" 13 #include "inode.h" 14 #include "file.h" 15 #include "conf.h" 16 #include "buf.h" 17 #include "uio.h" 18 19 /* 20 * Line discipline for RS232 tablets. 21 * Supplies binary coordinate data. 22 * 23 * MAKE TABLET TYPE AN ioctl TO AVOID HAVING ONE DISCIPLINE PER TABLET TYPE. 24 */ 25 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]; 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) 49 dev_t dev; 50 register struct tty *tp; 51 { 52 register struct tb *tbp; 53 54 if (tp->t_line == TABLDISC || tp->t_line == NTABLDISC) 55 return (ENODEV); 56 ttywflush(tp); 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; 64 tp->t_inbuf = 0; 65 tbp->tbpos.xpos = tbp->tbpos.ypos = 0; 66 tbp->tbpos.status = tbp->tbpos.scount = 0; 67 tp->T_LINEP = (caddr_t) tbp; 68 return (0); 69 } 70 71 /* 72 * Break down... called when discipline changed or from device 73 * close routine. 74 */ 75 tbclose(tp) 76 register struct tty *tp; 77 { 78 register int s = spl5(); 79 80 ((struct tb *) tp->T_LINEP)->used = 0; 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; 85 tp->t_line = 0; /* paranoid: avoid races */ 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 */ 94 tbread(tp, uio) 95 register struct tty *tp; 96 struct uio *uio; 97 { 98 struct tbpos *tbpos; 99 100 if ((tp->t_state&TS_CARR_ON)==0) 101 return (EIO); 102 tbpos = &(((struct tb *) (tp->T_LINEP))->tbpos); 103 return (uiomove(tbpos, sizeof *tbpos, UIO_READ, uio)); 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 */ 114 int LASTTABC; 115 116 tbinput(c, tp) 117 register int c; 118 register struct tty *tp; 119 { 120 register struct tb *tbp = (struct tb *) tp->T_LINEP; 121 122 if (tp->t_line == TABLDISC) { 123 if ((c&0200) || (tp->t_inbuf == MTABCHAR)) { 124 tp->t_cp = tbp->cbuf; 125 tp->t_inbuf = 0; 126 } 127 *tp->t_cp++ = c&0177; 128 if (++tp->t_inbuf == MTABCHAR) 129 tbdecode(tbp->cbuf, &tbp->tbpos); 130 } else if (tp->t_line == NTABLDISC) { 131 if ((c&0200) || (tp->t_inbuf == MNTABCHAR)) { 132 tp->t_cp = tbp->cbuf; 133 tp->t_inbuf = 0; 134 } 135 *tp->t_cp++ = c&0177; 136 if (++tp->t_inbuf == MNTABCHAR) 137 tbndecode(tbp->cbuf, &tbp->tbpos); 138 } 139 } 140 141 /* 142 * Decode tablet coordinates from ascii to binary. 143 * (gtco 6 character format) 144 */ 145 tbndecode(cp, tbpos) 146 register char *cp; 147 register struct tbpos *tbpos; 148 { 149 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++; 158 } 159 160 /* 161 * Decode tablet coordinates from ascii to binary. 162 * (hitachi 5 character format) 163 */ 164 tbdecode(cp, tbpos) 165 register char *cp; 166 register struct tbpos *tbpos; 167 { 168 register int status; 169 register char byte; 170 171 byte = *cp++; 172 status = (byte&0100) ? 0100000 : 0; 173 byte &= ~0100; 174 if (byte > 036) 175 status |= 1<<((byte-040)/2); 176 tbpos->xpos = (*cp++)<<7; 177 tbpos->xpos |= (*cp++); 178 if (tbpos->xpos < 256) /* tablet wraps around at 256 */ 179 status &= 077777; /* make it out of proximity */ 180 tbpos->ypos = (*cp++)<<7; 181 tbpos->ypos |= (*cp++); 182 tbpos->status = status; 183 tbpos->scount++; 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*/ 193 tbioctl(tp, cmd, data, flag) 194 struct tty *tp; 195 caddr_t data; 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 212