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