1 /* tty_tb.c 4.9 83/08/13 */ 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/ioctl.h" 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" 17 #include "../h/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 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; 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 */ 93 tbread(tp, uio) 94 register struct tty *tp; 95 struct uio *uio; 96 { 97 register int i; 98 register s; 99 struct tbpos *tbpos; 100 101 if ((tp->t_state&TS_CARR_ON)==0) 102 return (EIO); 103 tbpos = &(((struct tb *) (tp->T_LINEP))->tbpos); 104 return (uiomove(tbpos, sizeof *tbpos, UIO_READ, uio)); 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 */ 115 int LASTTABC; 116 117 tbinput(c, tp) 118 register int c; 119 register struct tty *tp; 120 { 121 register struct tb *tbp = (struct tb *) tp->T_LINEP; 122 123 if (tp->t_line == TABLDISC) { 124 if ((c&0200) || (tp->t_inbuf == MTABCHAR)) { 125 tp->t_cp = tbp->cbuf; 126 tp->t_inbuf = 0; 127 } 128 *tp->t_cp++ = c&0177; 129 if (++tp->t_inbuf == MTABCHAR) 130 tbdecode(tbp->cbuf, &tbp->tbpos); 131 } else if (tp->t_line == NTABLDISC) { 132 if ((c&0200) || (tp->t_inbuf == MNTABCHAR)) { 133 tp->t_cp = tbp->cbuf; 134 tp->t_inbuf = 0; 135 } 136 *tp->t_cp++ = c&0177; 137 if (++tp->t_inbuf == MNTABCHAR) 138 tbndecode(tbp->cbuf, &tbp->tbpos); 139 } 140 } 141 142 /* 143 * Decode tablet coordinates from ascii to binary. 144 * (gtco 6 character format) 145 */ 146 tbndecode(cp, tbpos) 147 register char *cp; 148 register struct tbpos *tbpos; 149 { 150 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++; 159 } 160 161 /* 162 * Decode tablet coordinates from ascii to binary. 163 * (hitachi 5 character format) 164 */ 165 tbdecode(cp, tbpos) 166 register char *cp; 167 register struct tbpos *tbpos; 168 { 169 register int status; 170 register char byte; 171 172 byte = *cp++; 173 status = (byte&0100) ? 0100000 : 0; 174 byte &= ~0100; 175 if (byte > 036) 176 status |= 1<<((byte-040)/2); 177 tbpos->xpos = (*cp++)<<7; 178 tbpos->xpos |= (*cp++); 179 if (tbpos->xpos < 256) /* tablet wraps around at 256 */ 180 status &= 077777; /* make it out of proximity */ 181 tbpos->ypos = (*cp++)<<7; 182 tbpos->ypos |= (*cp++); 183 tbpos->status = status; 184 tbpos->scount++; 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*/ 194 tbioctl(tp, cmd, data, flag) 195 struct tty *tp; 196 caddr_t data; 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 213