| 1 | /* pdp8_ttx.c: PDP-8 additional terminals simulator\r |
| 2 | \r |
| 3 | Copyright (c) 1993-2007, Robert M Supnik\r |
| 4 | \r |
| 5 | Permission is hereby granted, free of charge, to any person obtaining a\r |
| 6 | copy of this software and associated documentation files (the "Software"),\r |
| 7 | to deal in the Software without restriction, including without limitation\r |
| 8 | the rights to use, copy, modify, merge, publish, distribute, sublicense,\r |
| 9 | and/or sell copies of the Software, and to permit persons to whom the\r |
| 10 | Software is furnished to do so, subject to the following conditions:\r |
| 11 | \r |
| 12 | The above copyright notice and this permission notice shall be included in\r |
| 13 | all copies or substantial portions of the Software.\r |
| 14 | \r |
| 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r |
| 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r |
| 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\r |
| 18 | ROBERT M SUPNIK BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER\r |
| 19 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN\r |
| 20 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\r |
| 21 | \r |
| 22 | Except as contained in this notice, the name of Robert M Supnik shall not be\r |
| 23 | used in advertising or otherwise to promote the sale, use or other dealings\r |
| 24 | in this Software without prior written authorization from Robert M Supnik.\r |
| 25 | \r |
| 26 | ttix,ttox PT08/KL8JA terminal input/output\r |
| 27 | \r |
| 28 | 07-Jun-06 RMS Added UNIT_IDLE flag\r |
| 29 | 06-Jul-06 RMS Fixed bug in DETACH routine\r |
| 30 | 22-Nov-05 RMS Revised for new terminal processing routines\r |
| 31 | 29-Jun-05 RMS Added SET TTOXn DISCONNECT\r |
| 32 | Fixed bug in SET LOG/NOLOG\r |
| 33 | 21-Jun-05 RMS Fixed bug in SHOW CONN/STATS\r |
| 34 | 05-Jan-04 RMS Revised for tmxr library changes\r |
| 35 | 09-May-03 RMS Added network device flag\r |
| 36 | 25-Apr-03 RMS Revised for extended file support\r |
| 37 | 22-Dec-02 RMS Added break support\r |
| 38 | 02-Nov-02 RMS Added 7B/8B support\r |
| 39 | 04-Oct-02 RMS Added DIB, device number support\r |
| 40 | 22-Aug-02 RMS Updated for changes to sim_tmxr.c\r |
| 41 | 06-Jan-02 RMS Added device enable/disable support\r |
| 42 | 30-Dec-01 RMS Complete rebuild\r |
| 43 | 30-Nov-01 RMS Added extended SET/SHOW support\r |
| 44 | \r |
| 45 | This module implements four individual serial interfaces similar in function\r |
| 46 | to the console. These interfaces are mapped to Telnet based connections as\r |
| 47 | though they were the four lines of a terminal multiplexor. The connection\r |
| 48 | polling mechanism is superimposed onto the keyboard of the first interface.\r |
| 49 | */\r |
| 50 | \r |
| 51 | #include "pdp8_defs.h"\r |
| 52 | #include "sim_sock.h"\r |
| 53 | #include "sim_tmxr.h"\r |
| 54 | #include <ctype.h>\r |
| 55 | \r |
| 56 | #define TTX_LINES 4\r |
| 57 | #define TTX_MASK (TTX_LINES - 1)\r |
| 58 | \r |
| 59 | #define TTX_GETLN(x) (((x) >> 4) & TTX_MASK)\r |
| 60 | \r |
| 61 | extern int32 int_req, int_enable, dev_done, stop_inst;\r |
| 62 | \r |
| 63 | uint8 ttix_buf[TTX_LINES] = { 0 }; /* input buffers */\r |
| 64 | uint8 ttox_buf[TTX_LINES] = { 0 }; /* output buffers */\r |
| 65 | int32 ttx_tps = 100; /* polls per second */\r |
| 66 | TMLN ttx_ldsc[TTX_LINES] = { 0 }; /* line descriptors */\r |
| 67 | TMXR ttx_desc = { TTX_LINES, 0, 0, ttx_ldsc }; /* mux descriptor */\r |
| 68 | \r |
| 69 | DEVICE ttix_dev, ttox_dev;\r |
| 70 | int32 ttix (int32 IR, int32 AC);\r |
| 71 | int32 ttox (int32 IR, int32 AC);\r |
| 72 | t_stat ttix_svc (UNIT *uptr);\r |
| 73 | t_stat ttix_reset (DEVICE *dptr);\r |
| 74 | t_stat ttox_svc (UNIT *uptr);\r |
| 75 | t_stat ttox_reset (DEVICE *dptr);\r |
| 76 | t_stat ttx_attach (UNIT *uptr, char *cptr);\r |
| 77 | t_stat ttx_detach (UNIT *uptr);\r |
| 78 | t_stat ttx_summ (FILE *st, UNIT *uptr, int32 val, void *desc);\r |
| 79 | t_stat ttx_show (FILE *st, UNIT *uptr, int32 val, void *desc);\r |
| 80 | void ttx_enbdis (int32 dis);\r |
| 81 | \r |
| 82 | /* TTIx data structures\r |
| 83 | \r |
| 84 | ttix_dev TTIx device descriptor\r |
| 85 | ttix_unit TTIx unit descriptor\r |
| 86 | ttix_reg TTIx register list\r |
| 87 | ttix_mod TTIx modifiers list\r |
| 88 | */\r |
| 89 | \r |
| 90 | DIB ttix_dib = { DEV_KJ8, 8,\r |
| 91 | { &ttix, &ttox, &ttix, &ttox, &ttix, &ttox, &ttix, &ttox } };\r |
| 92 | \r |
| 93 | UNIT ttix_unit = { UDATA (&ttix_svc, UNIT_IDLE|UNIT_ATTABLE, 0), KBD_POLL_WAIT };\r |
| 94 | \r |
| 95 | REG ttix_reg[] = {\r |
| 96 | { BRDATA (BUF, ttix_buf, 8, 8, TTX_LINES) },\r |
| 97 | { GRDATA (DONE, dev_done, 8, TTX_LINES, INT_V_TTI1) },\r |
| 98 | { GRDATA (ENABLE, int_enable, 8, TTX_LINES, INT_V_TTI1) },\r |
| 99 | { GRDATA (INT, int_req, 8, TTX_LINES, INT_V_TTI1) },\r |
| 100 | { DRDATA (TIME, ttix_unit.wait, 24), REG_NZ + PV_LEFT },\r |
| 101 | { DRDATA (TPS, ttx_tps, 10), REG_NZ + PV_LEFT },\r |
| 102 | { ORDATA (DEVNUM, ttix_dib.dev, 6), REG_HRO },\r |
| 103 | { NULL }\r |
| 104 | };\r |
| 105 | \r |
| 106 | MTAB ttix_mod[] = {\r |
| 107 | { UNIT_ATT, UNIT_ATT, "summary", NULL, NULL, &ttx_summ },\r |
| 108 | { MTAB_XTD | MTAB_VDV, 1, NULL, "DISCONNECT",\r |
| 109 | &tmxr_dscln, NULL, &ttx_desc },\r |
| 110 | { MTAB_XTD | MTAB_VDV | MTAB_NMO, 1, "CONNECTIONS", NULL,\r |
| 111 | NULL, &ttx_show, NULL },\r |
| 112 | { MTAB_XTD | MTAB_VDV | MTAB_NMO, 0, "STATISTICS", NULL,\r |
| 113 | NULL, &ttx_show, NULL },\r |
| 114 | { MTAB_XTD|MTAB_VDV, 0, "DEVNO", "DEVNO",\r |
| 115 | &set_dev, &show_dev, NULL },\r |
| 116 | { 0 }\r |
| 117 | };\r |
| 118 | \r |
| 119 | DEVICE ttix_dev = {\r |
| 120 | "TTIX", &ttix_unit, ttix_reg, ttix_mod,\r |
| 121 | 1, 10, 31, 1, 8, 8,\r |
| 122 | &tmxr_ex, &tmxr_dep, &ttix_reset,\r |
| 123 | NULL, &ttx_attach, &ttx_detach,\r |
| 124 | &ttix_dib, DEV_NET | DEV_DISABLE\r |
| 125 | };\r |
| 126 | \r |
| 127 | /* TTOx data structures\r |
| 128 | \r |
| 129 | ttox_dev TTOx device descriptor\r |
| 130 | ttox_unit TTOx unit descriptor\r |
| 131 | ttox_reg TTOx register list\r |
| 132 | */\r |
| 133 | \r |
| 134 | UNIT ttox_unit[] = {\r |
| 135 | { UDATA (&ttox_svc, TT_MODE_UC, 0), SERIAL_OUT_WAIT },\r |
| 136 | { UDATA (&ttox_svc, TT_MODE_UC, 0), SERIAL_OUT_WAIT },\r |
| 137 | { UDATA (&ttox_svc, TT_MODE_UC, 0), SERIAL_OUT_WAIT },\r |
| 138 | { UDATA (&ttox_svc, TT_MODE_UC, 0), SERIAL_OUT_WAIT }\r |
| 139 | };\r |
| 140 | \r |
| 141 | REG ttox_reg[] = {\r |
| 142 | { BRDATA (BUF, ttox_buf, 8, 8, TTX_LINES) },\r |
| 143 | { GRDATA (DONE, dev_done, 8, TTX_LINES, INT_V_TTO1) },\r |
| 144 | { GRDATA (ENABLE, int_enable, 8, TTX_LINES, INT_V_TTO1) },\r |
| 145 | { GRDATA (INT, int_req, 8, TTX_LINES, INT_V_TTO1) },\r |
| 146 | { URDATA (TIME, ttox_unit[0].wait, 10, 24, 0,\r |
| 147 | TTX_LINES, PV_LEFT) },\r |
| 148 | { NULL }\r |
| 149 | };\r |
| 150 | \r |
| 151 | MTAB ttox_mod[] = {\r |
| 152 | { TT_MODE, TT_MODE_UC, "UC", "UC", NULL },\r |
| 153 | { TT_MODE, TT_MODE_7B, "7b", "7B", NULL },\r |
| 154 | { TT_MODE, TT_MODE_8B, "8b", "8B", NULL },\r |
| 155 | { TT_MODE, TT_MODE_7P, "7p", "7P", NULL },\r |
| 156 | { MTAB_XTD|MTAB_VUN, 0, NULL, "DISCONNECT",\r |
| 157 | &tmxr_dscln, NULL, &ttx_desc },\r |
| 158 | { MTAB_XTD|MTAB_VUN|MTAB_NC, 0, "LOG", "LOG",\r |
| 159 | &tmxr_set_log, &tmxr_show_log, &ttx_desc },\r |
| 160 | { MTAB_XTD|MTAB_VUN|MTAB_NC, 0, NULL, "NOLOG",\r |
| 161 | &tmxr_set_nolog, NULL, &ttx_desc },\r |
| 162 | { 0 }\r |
| 163 | };\r |
| 164 | \r |
| 165 | DEVICE ttox_dev = {\r |
| 166 | "TTOX", ttox_unit, ttox_reg, ttox_mod,\r |
| 167 | 4, 10, 31, 1, 8, 8,\r |
| 168 | NULL, NULL, &ttox_reset, \r |
| 169 | NULL, NULL, NULL,\r |
| 170 | NULL, DEV_DISABLE\r |
| 171 | };\r |
| 172 | \r |
| 173 | /* Terminal input: IOT routine */\r |
| 174 | \r |
| 175 | int32 ttix (int32 inst, int32 AC)\r |
| 176 | {\r |
| 177 | int32 pulse = inst & 07; /* IOT pulse */\r |
| 178 | int32 ln = TTX_GETLN (inst); /* line # */\r |
| 179 | int32 itti = (INT_TTI1 << ln); /* rx intr */\r |
| 180 | int32 itto = (INT_TTO1 << ln); /* tx intr */\r |
| 181 | \r |
| 182 | switch (pulse) { /* case IR<9:11> */\r |
| 183 | \r |
| 184 | case 0: /* KCF */\r |
| 185 | dev_done = dev_done & ~itti; /* clear flag */\r |
| 186 | int_req = int_req & ~itti;\r |
| 187 | break;\r |
| 188 | \r |
| 189 | case 1: /* KSF */\r |
| 190 | return (dev_done & itti)? IOT_SKP + AC: AC;\r |
| 191 | \r |
| 192 | case 2: /* KCC */\r |
| 193 | dev_done = dev_done & ~itti; /* clear flag */\r |
| 194 | int_req = int_req & ~itti;\r |
| 195 | return 0; /* clear AC */\r |
| 196 | \r |
| 197 | case 4: /* KRS */\r |
| 198 | return (AC | ttix_buf[ln]); /* return buf */\r |
| 199 | \r |
| 200 | case 5: /* KIE */\r |
| 201 | if (AC & 1) int_enable = int_enable | (itti + itto);\r |
| 202 | else int_enable = int_enable & ~(itti + itto);\r |
| 203 | int_req = INT_UPDATE; /* update intr */\r |
| 204 | break;\r |
| 205 | \r |
| 206 | case 6: /* KRB */\r |
| 207 | dev_done = dev_done & ~itti; /* clear flag */\r |
| 208 | int_req = int_req & ~itti;\r |
| 209 | return ttix_buf[ln]; /* return buf */\r |
| 210 | \r |
| 211 | default:\r |
| 212 | return (stop_inst << IOT_V_REASON) + AC;\r |
| 213 | } /* end switch */\r |
| 214 | \r |
| 215 | return AC;\r |
| 216 | }\r |
| 217 | \r |
| 218 | /* Unit service */\r |
| 219 | \r |
| 220 | t_stat ttix_svc (UNIT *uptr)\r |
| 221 | {\r |
| 222 | int32 ln, c, temp;\r |
| 223 | \r |
| 224 | if ((uptr->flags & UNIT_ATT) == 0) return SCPE_OK; /* attached? */\r |
| 225 | temp = sim_rtcn_calb (ttx_tps, TMR_TTX); /* calibrate */\r |
| 226 | sim_activate (uptr, temp); /* continue poll */\r |
| 227 | ln = tmxr_poll_conn (&ttx_desc); /* look for connect */\r |
| 228 | if (ln >= 0) ttx_ldsc[ln].rcve = 1; /* got one? rcv enb*/\r |
| 229 | tmxr_poll_rx (&ttx_desc); /* poll for input */\r |
| 230 | for (ln = 0; ln < TTX_LINES; ln++) { /* loop thru lines */\r |
| 231 | if (ttx_ldsc[ln].conn) { /* connected? */\r |
| 232 | if (temp = tmxr_getc_ln (&ttx_ldsc[ln])) { /* get char */\r |
| 233 | if (temp & SCPE_BREAK) c = 0; /* break? */\r |
| 234 | else c = sim_tt_inpcvt (temp, TT_GET_MODE (ttox_unit[ln].flags));\r |
| 235 | ttix_buf[ln] = c;\r |
| 236 | dev_done = dev_done | (INT_TTI1 << ln);\r |
| 237 | int_req = INT_UPDATE;\r |
| 238 | }\r |
| 239 | }\r |
| 240 | }\r |
| 241 | return SCPE_OK;\r |
| 242 | }\r |
| 243 | \r |
| 244 | /* Reset routine */\r |
| 245 | \r |
| 246 | t_stat ttix_reset (DEVICE *dptr)\r |
| 247 | {\r |
| 248 | int32 t, ln, itto;\r |
| 249 | \r |
| 250 | ttx_enbdis (dptr->flags & DEV_DIS); /* sync enables */\r |
| 251 | if (ttix_unit.flags & UNIT_ATT) { /* if attached, */\r |
| 252 | if (!sim_is_active (&ttix_unit)) {\r |
| 253 | t = sim_rtcn_init (ttix_unit.wait, TMR_TTX);\r |
| 254 | sim_activate (&ttix_unit, t); /* activate */\r |
| 255 | }\r |
| 256 | }\r |
| 257 | else sim_cancel (&ttix_unit); /* else stop */\r |
| 258 | for (ln = 0; ln < TTX_LINES; ln++) { /* for all lines */\r |
| 259 | ttix_buf[ln] = 0; /* clear buf, */\r |
| 260 | itto = (INT_TTI1 << ln); /* interrupt */\r |
| 261 | dev_done = dev_done & ~itto; /* clr done, int */\r |
| 262 | int_req = int_req & ~itto;\r |
| 263 | int_enable = int_enable | itto; /* set enable */\r |
| 264 | }\r |
| 265 | return SCPE_OK;\r |
| 266 | }\r |
| 267 | \r |
| 268 | /* Terminal output: IOT routine */\r |
| 269 | \r |
| 270 | int32 ttox (int32 inst, int32 AC)\r |
| 271 | {\r |
| 272 | int32 pulse = inst & 07; /* pulse */\r |
| 273 | int32 ln = TTX_GETLN (inst); /* line # */\r |
| 274 | int32 itti = (INT_TTI1 << ln); /* rx intr */\r |
| 275 | int32 itto = (INT_TTO1 << ln); /* tx intr */\r |
| 276 | \r |
| 277 | switch (pulse) { /* case IR<9:11> */\r |
| 278 | \r |
| 279 | case 0: /* TLF */\r |
| 280 | dev_done = dev_done | itto; /* set flag */\r |
| 281 | int_req = INT_UPDATE; /* update intr */\r |
| 282 | break;\r |
| 283 | \r |
| 284 | case 1: /* TSF */\r |
| 285 | return (dev_done & itto)? IOT_SKP + AC: AC;\r |
| 286 | \r |
| 287 | case 2: /* TCF */\r |
| 288 | dev_done = dev_done & ~itto; /* clear flag */\r |
| 289 | int_req = int_req & ~itto; /* clear intr */\r |
| 290 | break;\r |
| 291 | \r |
| 292 | case 5: /* SPI */\r |
| 293 | return (int_req & (itti | itto))? IOT_SKP + AC: AC;\r |
| 294 | \r |
| 295 | case 6: /* TLS */\r |
| 296 | dev_done = dev_done & ~itto; /* clear flag */\r |
| 297 | int_req = int_req & ~itto; /* clear int req */\r |
| 298 | case 4: /* TPC */\r |
| 299 | sim_activate (&ttox_unit[ln], ttox_unit[ln].wait); /* activate */\r |
| 300 | ttox_buf[ln] = AC & 0377; /* load buffer */\r |
| 301 | break;\r |
| 302 | \r |
| 303 | default:\r |
| 304 | return (stop_inst << IOT_V_REASON) + AC;\r |
| 305 | } /* end switch */\r |
| 306 | \r |
| 307 | return AC;\r |
| 308 | }\r |
| 309 | \r |
| 310 | /* Unit service */\r |
| 311 | \r |
| 312 | t_stat ttox_svc (UNIT *uptr)\r |
| 313 | {\r |
| 314 | int32 c, ln = uptr - ttox_unit; /* line # */\r |
| 315 | \r |
| 316 | if (ttx_ldsc[ln].conn) { /* connected? */\r |
| 317 | if (ttx_ldsc[ln].xmte) { /* tx enabled? */\r |
| 318 | TMLN *lp = &ttx_ldsc[ln]; /* get line */\r |
| 319 | c = sim_tt_outcvt (ttox_buf[ln], TT_GET_MODE (ttox_unit[ln].flags));\r |
| 320 | if (c >= 0) tmxr_putc_ln (lp, c); /* output char */\r |
| 321 | tmxr_poll_tx (&ttx_desc); /* poll xmt */\r |
| 322 | }\r |
| 323 | else {\r |
| 324 | tmxr_poll_tx (&ttx_desc); /* poll xmt */\r |
| 325 | sim_activate (uptr, ttox_unit[ln].wait); /* wait */\r |
| 326 | return SCPE_OK;\r |
| 327 | }\r |
| 328 | }\r |
| 329 | dev_done = dev_done | (INT_TTO1 << ln); /* set done */\r |
| 330 | int_req = INT_UPDATE; /* update intr */\r |
| 331 | return SCPE_OK;\r |
| 332 | }\r |
| 333 | \r |
| 334 | /* Reset routine */\r |
| 335 | \r |
| 336 | t_stat ttox_reset (DEVICE *dptr)\r |
| 337 | {\r |
| 338 | int32 ln, itto;\r |
| 339 | \r |
| 340 | ttx_enbdis (dptr->flags & DEV_DIS); /* sync enables */\r |
| 341 | for (ln = 0; ln < TTX_LINES; ln++) { /* for all lines */\r |
| 342 | ttox_buf[ln] = 0; /* clear buf */\r |
| 343 | itto = (INT_TTO1 << ln); /* interrupt */\r |
| 344 | dev_done = dev_done & ~itto; /* clr done, int */\r |
| 345 | int_req = int_req & ~itto;\r |
| 346 | int_enable = int_enable | itto; /* set enable */\r |
| 347 | sim_cancel (&ttox_unit[ln]); /* deactivate */\r |
| 348 | }\r |
| 349 | return SCPE_OK;\r |
| 350 | }\r |
| 351 | \r |
| 352 | /* Attach master unit */\r |
| 353 | \r |
| 354 | t_stat ttx_attach (UNIT *uptr, char *cptr)\r |
| 355 | {\r |
| 356 | int32 t;\r |
| 357 | t_stat r;\r |
| 358 | \r |
| 359 | r = tmxr_attach (&ttx_desc, uptr, cptr); /* attach */\r |
| 360 | if (r != SCPE_OK) return r; /* error */\r |
| 361 | t = sim_rtcn_init (ttix_unit.wait, TMR_TTX); /* init calib */\r |
| 362 | sim_activate (uptr, t); /* start poll */\r |
| 363 | return SCPE_OK;\r |
| 364 | }\r |
| 365 | \r |
| 366 | /* Detach master unit */\r |
| 367 | \r |
| 368 | t_stat ttx_detach (UNIT *uptr)\r |
| 369 | {\r |
| 370 | int32 i;\r |
| 371 | t_stat r;\r |
| 372 | \r |
| 373 | r = tmxr_detach (&ttx_desc, uptr); /* detach */\r |
| 374 | for (i = 0; i < TTX_LINES; i++) /* all lines, */\r |
| 375 | ttx_ldsc[i].rcve = 0; /* disable rcv */\r |
| 376 | sim_cancel (uptr); /* stop poll */\r |
| 377 | return r;\r |
| 378 | }\r |
| 379 | \r |
| 380 | /* Show summary processor */\r |
| 381 | \r |
| 382 | t_stat ttx_summ (FILE *st, UNIT *uptr, int32 val, void *desc)\r |
| 383 | {\r |
| 384 | int32 i, t;\r |
| 385 | \r |
| 386 | for (i = t = 0; i < TTX_LINES; i++) t = t + (ttx_ldsc[i].conn != 0);\r |
| 387 | if (t == 1) fprintf (st, "1 connection");\r |
| 388 | else fprintf (st, "%d connections", t);\r |
| 389 | return SCPE_OK;\r |
| 390 | }\r |
| 391 | \r |
| 392 | /* SHOW CONN/STAT processor */\r |
| 393 | \r |
| 394 | t_stat ttx_show (FILE *st, UNIT *uptr, int32 val, void *desc)\r |
| 395 | {\r |
| 396 | int32 i, t;\r |
| 397 | \r |
| 398 | for (i = t = 0; i < TTX_LINES; i++) t = t + (ttx_ldsc[i].conn != 0);\r |
| 399 | if (t) {\r |
| 400 | for (i = 0; i < TTX_LINES; i++) {\r |
| 401 | if (ttx_ldsc[i].conn) { \r |
| 402 | if (val) tmxr_fconns (st, &ttx_ldsc[i], i);\r |
| 403 | else tmxr_fstats (st, &ttx_ldsc[i], i);\r |
| 404 | }\r |
| 405 | }\r |
| 406 | }\r |
| 407 | else fprintf (st, "all disconnected\n");\r |
| 408 | return SCPE_OK;\r |
| 409 | }\r |
| 410 | \r |
| 411 | /* Enable/disable device */\r |
| 412 | \r |
| 413 | void ttx_enbdis (int32 dis)\r |
| 414 | {\r |
| 415 | if (dis) {\r |
| 416 | ttix_dev.flags = ttox_dev.flags | DEV_DIS;\r |
| 417 | ttox_dev.flags = ttox_dev.flags | DEV_DIS;\r |
| 418 | }\r |
| 419 | else {\r |
| 420 | ttix_dev.flags = ttix_dev.flags & ~DEV_DIS;\r |
| 421 | ttox_dev.flags = ttox_dev.flags & ~DEV_DIS;\r |
| 422 | }\r |
| 423 | return;\r |
| 424 | }\r |