1*41480Smckusick /* 2*41480Smckusick * Copyright (c) 1988 University of Utah. 3*41480Smckusick * Copyright (c) 1990 The Regents of the University of California. 4*41480Smckusick * All rights reserved. 5*41480Smckusick * 6*41480Smckusick * This code is derived from software contributed to Berkeley by 7*41480Smckusick * the Systems Programming Group of the University of Utah Computer 8*41480Smckusick * Science Department. 9*41480Smckusick * 10*41480Smckusick * %sccs.include.redist.c% 11*41480Smckusick * 12*41480Smckusick * from: Utah $Hdr: ite.c 1.22 89/08/17$ 13*41480Smckusick * 14*41480Smckusick * @(#)ite.c 7.1 (Berkeley) 05/08/90 15*41480Smckusick */ 16*41480Smckusick 17*41480Smckusick /* 18*41480Smckusick * Bit-mapped display terminal emulator machine independent code. 19*41480Smckusick * This is a very rudimentary. Much more can be abstracted out of 20*41480Smckusick * the hardware dependent routines. 21*41480Smckusick */ 22*41480Smckusick #include "ite.h" 23*41480Smckusick #if NITE > 0 24*41480Smckusick 25*41480Smckusick #include "grf.h" 26*41480Smckusick 27*41480Smckusick #undef NITE 28*41480Smckusick #define NITE NGRF 29*41480Smckusick 30*41480Smckusick #include "param.h" 31*41480Smckusick #include "conf.h" 32*41480Smckusick #include "user.h" 33*41480Smckusick #include "proc.h" 34*41480Smckusick #include "ioctl.h" 35*41480Smckusick #include "tty.h" 36*41480Smckusick #include "systm.h" 37*41480Smckusick #include "uio.h" 38*41480Smckusick #include "malloc.h" 39*41480Smckusick 40*41480Smckusick #include "itevar.h" 41*41480Smckusick #include "iteioctl.h" 42*41480Smckusick #include "kbdmap.h" 43*41480Smckusick 44*41480Smckusick #include "machine/cpu.h" 45*41480Smckusick 46*41480Smckusick #define set_attr(ip, attr) ((ip)->attribute |= (attr)) 47*41480Smckusick #define clr_attr(ip, attr) ((ip)->attribute &= ~(attr)) 48*41480Smckusick 49*41480Smckusick extern int nodev(); 50*41480Smckusick 51*41480Smckusick int topcat_scroll(), topcat_init(), topcat_deinit(); 52*41480Smckusick int topcat_clear(), topcat_putc(), topcat_cursor(); 53*41480Smckusick int gatorbox_scroll(), gatorbox_init(), gatorbox_deinit(); 54*41480Smckusick int gatorbox_clear(), gatorbox_putc(), gatorbox_cursor(); 55*41480Smckusick int rbox_scroll(), rbox_init(), rbox_deinit(); 56*41480Smckusick int rbox_clear(), rbox_putc(), rbox_cursor(); 57*41480Smckusick int dvbox_scroll(), dvbox_init(), dvbox_deinit(); 58*41480Smckusick int dvbox_clear(), dvbox_putc(), dvbox_cursor(); 59*41480Smckusick 60*41480Smckusick struct itesw itesw[] = 61*41480Smckusick { 62*41480Smckusick topcat_init, topcat_deinit, topcat_clear, 63*41480Smckusick topcat_putc, topcat_cursor, topcat_scroll, 64*41480Smckusick 65*41480Smckusick gatorbox_init, gatorbox_deinit, gatorbox_clear, 66*41480Smckusick gatorbox_putc, gatorbox_cursor, gatorbox_scroll, 67*41480Smckusick 68*41480Smckusick rbox_init, rbox_deinit, rbox_clear, 69*41480Smckusick rbox_putc, rbox_cursor, rbox_scroll, 70*41480Smckusick 71*41480Smckusick dvbox_init, dvbox_deinit, dvbox_clear, 72*41480Smckusick dvbox_putc, dvbox_cursor, dvbox_scroll, 73*41480Smckusick }; 74*41480Smckusick 75*41480Smckusick /* 76*41480Smckusick * # of chars are output in a single itestart() call. 77*41480Smckusick * If this is too big, user processes will be blocked out for 78*41480Smckusick * long periods of time while we are emptying the queue in itestart(). 79*41480Smckusick * If it is too small, console output will be very ragged. 80*41480Smckusick */ 81*41480Smckusick int iteburst = 64; 82*41480Smckusick 83*41480Smckusick int nite = NITE; 84*41480Smckusick struct tty *kbd_tty = NULL; 85*41480Smckusick struct tty ite_tty[NITE]; 86*41480Smckusick struct ite_softc ite_softc[NITE]; 87*41480Smckusick 88*41480Smckusick int itestart(); 89*41480Smckusick extern int ttrstrt(); 90*41480Smckusick extern struct tty *constty; 91*41480Smckusick 92*41480Smckusick /* 93*41480Smckusick * Primary attribute buffer to be used by the first bitmapped console 94*41480Smckusick * found. Secondary displays alloc the attribute buffer as needed. 95*41480Smckusick * Size is based on a 68x128 display, which is currently our largest. 96*41480Smckusick */ 97*41480Smckusick u_char console_attributes[0x2200]; 98*41480Smckusick 99*41480Smckusick /* 100*41480Smckusick * Perform functions necessary to setup device as a terminal emulator. 101*41480Smckusick */ 102*41480Smckusick iteon(dev, flag) 103*41480Smckusick dev_t dev; 104*41480Smckusick { 105*41480Smckusick int unit = UNIT(dev); 106*41480Smckusick struct tty *tp = &ite_tty[unit]; 107*41480Smckusick struct ite_softc *ip = &ite_softc[unit]; 108*41480Smckusick 109*41480Smckusick if (unit < 0 || unit >= NITE || (ip->flags&ITE_ALIVE) == 0) 110*41480Smckusick return(ENXIO); 111*41480Smckusick /* force ite active, overriding graphics mode */ 112*41480Smckusick if (flag & 1) { 113*41480Smckusick ip->flags |= ITE_ACTIVE; 114*41480Smckusick ip->flags &= ~(ITE_INGRF|ITE_INITED); 115*41480Smckusick } 116*41480Smckusick /* leave graphics mode */ 117*41480Smckusick if (flag & 2) { 118*41480Smckusick ip->flags &= ~ITE_INGRF; 119*41480Smckusick if ((ip->flags & ITE_ACTIVE) == 0) 120*41480Smckusick return(0); 121*41480Smckusick } 122*41480Smckusick ip->flags |= ITE_ACTIVE; 123*41480Smckusick if (ip->flags & ITE_INGRF) 124*41480Smckusick return(0); 125*41480Smckusick if (kbd_tty == NULL || kbd_tty == tp) { 126*41480Smckusick kbd_tty = tp; 127*41480Smckusick kbdenable(); 128*41480Smckusick } 129*41480Smckusick iteinit(dev); 130*41480Smckusick return(0); 131*41480Smckusick } 132*41480Smckusick 133*41480Smckusick iteinit(dev) 134*41480Smckusick dev_t dev; 135*41480Smckusick { 136*41480Smckusick int unit = UNIT(dev); 137*41480Smckusick struct ite_softc *ip = &ite_softc[unit]; 138*41480Smckusick 139*41480Smckusick if (ip->flags & ITE_INITED) 140*41480Smckusick return; 141*41480Smckusick 142*41480Smckusick ip->curx = 0; 143*41480Smckusick ip->cury = 0; 144*41480Smckusick ip->cursorx = 0; 145*41480Smckusick ip->cursory = 0; 146*41480Smckusick 147*41480Smckusick (*itesw[ip->type].ite_init)(ip); 148*41480Smckusick (*itesw[ip->type].ite_cursor)(ip, DRAW_CURSOR); 149*41480Smckusick 150*41480Smckusick ip->attribute = 0; 151*41480Smckusick if (ip->attrbuf == NULL) 152*41480Smckusick ip->attrbuf = (u_char *) 153*41480Smckusick malloc(ip->rows * ip->cols, M_DEVBUF, M_WAITOK); 154*41480Smckusick bzero(ip->attrbuf, (ip->rows * ip->cols)); 155*41480Smckusick 156*41480Smckusick ip->imode = 0; 157*41480Smckusick ip->flags |= ITE_INITED; 158*41480Smckusick } 159*41480Smckusick 160*41480Smckusick /* 161*41480Smckusick * "Shut down" device as terminal emulator. 162*41480Smckusick * Note that we do not deinit the console device unless forced. 163*41480Smckusick * Deinit'ing the console every time leads to a very active 164*41480Smckusick * screen when processing /etc/rc. 165*41480Smckusick */ 166*41480Smckusick iteoff(dev, flag) 167*41480Smckusick dev_t dev; 168*41480Smckusick { 169*41480Smckusick register struct ite_softc *ip = &ite_softc[UNIT(dev)]; 170*41480Smckusick 171*41480Smckusick if (flag & 2) 172*41480Smckusick ip->flags |= ITE_INGRF; 173*41480Smckusick if ((ip->flags & ITE_ACTIVE) == 0) 174*41480Smckusick return; 175*41480Smckusick if ((flag & 1) || 176*41480Smckusick (ip->flags & (ITE_INGRF|ITE_ISCONS|ITE_INITED)) == ITE_INITED) 177*41480Smckusick (*itesw[ip->type].ite_deinit)(ip); 178*41480Smckusick if ((flag & 2) == 0) 179*41480Smckusick ip->flags &= ~ITE_ACTIVE; 180*41480Smckusick } 181*41480Smckusick 182*41480Smckusick /*ARGSUSED*/ 183*41480Smckusick iteopen(dev, flag) 184*41480Smckusick dev_t dev; 185*41480Smckusick { 186*41480Smckusick int unit = UNIT(dev); 187*41480Smckusick register struct tty *tp = &ite_tty[unit]; 188*41480Smckusick register struct ite_softc *ip = &ite_softc[unit]; 189*41480Smckusick register int error; 190*41480Smckusick int first = 0; 191*41480Smckusick 192*41480Smckusick if (tp->t_state&TS_XCLUDE && u.u_uid != 0) 193*41480Smckusick return (EBUSY); 194*41480Smckusick if ((ip->flags & ITE_ACTIVE) == 0) { 195*41480Smckusick error = iteon(dev, 0); 196*41480Smckusick if (error) 197*41480Smckusick return (error); 198*41480Smckusick first = 1; 199*41480Smckusick } 200*41480Smckusick tp->t_oproc = itestart; 201*41480Smckusick tp->t_param = NULL; 202*41480Smckusick tp->t_dev = dev; 203*41480Smckusick if ((tp->t_state&TS_ISOPEN) == 0) { 204*41480Smckusick ttychars(tp); 205*41480Smckusick tp->t_iflag = TTYDEF_IFLAG; 206*41480Smckusick tp->t_oflag = TTYDEF_OFLAG; 207*41480Smckusick tp->t_cflag = CS8|CREAD; 208*41480Smckusick tp->t_lflag = TTYDEF_LFLAG; 209*41480Smckusick tp->t_ispeed = tp->t_ospeed = TTYDEF_SPEED; 210*41480Smckusick tp->t_state = TS_ISOPEN|TS_CARR_ON; 211*41480Smckusick ttsetwater(tp); 212*41480Smckusick } 213*41480Smckusick error = (*linesw[tp->t_line].l_open)(dev, tp); 214*41480Smckusick if (error == 0) { 215*41480Smckusick tp->t_winsize.ws_row = ip->rows; 216*41480Smckusick tp->t_winsize.ws_col = ip->cols; 217*41480Smckusick } else if (first) 218*41480Smckusick iteoff(dev, 0); 219*41480Smckusick return (error); 220*41480Smckusick } 221*41480Smckusick 222*41480Smckusick /*ARGSUSED*/ 223*41480Smckusick iteclose(dev, flag) 224*41480Smckusick dev_t dev; 225*41480Smckusick { 226*41480Smckusick register struct tty *tp = &ite_tty[UNIT(dev)]; 227*41480Smckusick 228*41480Smckusick (*linesw[tp->t_line].l_close)(tp); 229*41480Smckusick ttyclose(tp); 230*41480Smckusick iteoff(dev, 0); 231*41480Smckusick return(0); 232*41480Smckusick } 233*41480Smckusick 234*41480Smckusick iteread(dev, uio, flag) 235*41480Smckusick dev_t dev; 236*41480Smckusick struct uio *uio; 237*41480Smckusick { 238*41480Smckusick register struct tty *tp = &ite_tty[UNIT(dev)]; 239*41480Smckusick 240*41480Smckusick return ((*linesw[tp->t_line].l_read)(tp, uio, flag)); 241*41480Smckusick } 242*41480Smckusick 243*41480Smckusick itewrite(dev, uio, flag) 244*41480Smckusick dev_t dev; 245*41480Smckusick struct uio *uio; 246*41480Smckusick { 247*41480Smckusick int unit = UNIT(dev); 248*41480Smckusick register struct tty *tp = &ite_tty[unit]; 249*41480Smckusick 250*41480Smckusick if ((ite_softc[unit].flags & ITE_ISCONS) && constty && 251*41480Smckusick (constty->t_state&(TS_CARR_ON|TS_ISOPEN))==(TS_CARR_ON|TS_ISOPEN)) 252*41480Smckusick tp = constty; 253*41480Smckusick return ((*linesw[tp->t_line].l_write)(tp, uio, flag)); 254*41480Smckusick } 255*41480Smckusick 256*41480Smckusick iteioctl(dev, cmd, addr, flag) 257*41480Smckusick dev_t dev; 258*41480Smckusick caddr_t addr; 259*41480Smckusick { 260*41480Smckusick register struct tty *tp = &ite_tty[UNIT(dev)]; 261*41480Smckusick int error; 262*41480Smckusick 263*41480Smckusick error = (*linesw[tp->t_line].l_ioctl)(tp, cmd, addr, flag); 264*41480Smckusick if (error >= 0) 265*41480Smckusick return (error); 266*41480Smckusick error = ttioctl(tp, cmd, addr, flag); 267*41480Smckusick if (error >= 0) 268*41480Smckusick return (error); 269*41480Smckusick return (ENOTTY); 270*41480Smckusick } 271*41480Smckusick 272*41480Smckusick itestart(tp) 273*41480Smckusick register struct tty *tp; 274*41480Smckusick { 275*41480Smckusick register int cc, s; 276*41480Smckusick int hiwat = 0; 277*41480Smckusick 278*41480Smckusick s = spltty(); 279*41480Smckusick if (tp->t_state & (TS_TIMEOUT|TS_BUSY|TS_TTSTOP)) { 280*41480Smckusick splx(s); 281*41480Smckusick return; 282*41480Smckusick } 283*41480Smckusick tp->t_state |= TS_BUSY; 284*41480Smckusick cc = tp->t_outq.c_cc; 285*41480Smckusick if (cc <= tp->t_lowat) { 286*41480Smckusick if (tp->t_state & TS_ASLEEP) { 287*41480Smckusick tp->t_state &= ~TS_ASLEEP; 288*41480Smckusick wakeup(&tp->t_outq); 289*41480Smckusick } 290*41480Smckusick if (tp->t_wsel) { 291*41480Smckusick selwakeup(tp->t_wsel, tp->t_state & TS_WCOLL); 292*41480Smckusick tp->t_wsel = 0; 293*41480Smckusick tp->t_state &= ~TS_WCOLL; 294*41480Smckusick } 295*41480Smckusick } 296*41480Smckusick /* 297*41480Smckusick * Limit the amount of output we do in one burst 298*41480Smckusick * to prevent hogging the CPU. 299*41480Smckusick */ 300*41480Smckusick if (cc > iteburst) { 301*41480Smckusick hiwat++; 302*41480Smckusick cc = iteburst; 303*41480Smckusick } 304*41480Smckusick while (--cc >= 0) { 305*41480Smckusick register int c; 306*41480Smckusick 307*41480Smckusick c = getc(&tp->t_outq); 308*41480Smckusick /* 309*41480Smckusick * iteputchar() may take a long time and we don't want to 310*41480Smckusick * block all interrupts for long periods of time. Since 311*41480Smckusick * there is no need to stay at high priority while outputing 312*41480Smckusick * the character (since we don't have to worry about 313*41480Smckusick * interrupts), we don't. We just need to make sure that 314*41480Smckusick * we don't reenter iteputchar, which is guarenteed by the 315*41480Smckusick * earlier setting of TS_BUSY. 316*41480Smckusick */ 317*41480Smckusick splx(s); 318*41480Smckusick iteputchar(c, tp->t_dev); 319*41480Smckusick spltty(); 320*41480Smckusick } 321*41480Smckusick if (hiwat) { 322*41480Smckusick tp->t_state |= TS_TIMEOUT; 323*41480Smckusick timeout(ttrstrt, tp, 1); 324*41480Smckusick } 325*41480Smckusick tp->t_state &= ~TS_BUSY; 326*41480Smckusick splx(s); 327*41480Smckusick } 328*41480Smckusick 329*41480Smckusick itefilter(stat, c) 330*41480Smckusick register char stat, c; 331*41480Smckusick { 332*41480Smckusick static int capsmode = 0; 333*41480Smckusick static int metamode = 0; 334*41480Smckusick register char code, *str; 335*41480Smckusick 336*41480Smckusick if (kbd_tty == NULL) 337*41480Smckusick return; 338*41480Smckusick 339*41480Smckusick switch (c & 0xFF) { 340*41480Smckusick case KBD_CAPSLOCK: 341*41480Smckusick capsmode = !capsmode; 342*41480Smckusick return; 343*41480Smckusick 344*41480Smckusick case KBD_EXT_LEFT_DOWN: 345*41480Smckusick case KBD_EXT_RIGHT_DOWN: 346*41480Smckusick metamode = 1; 347*41480Smckusick return; 348*41480Smckusick 349*41480Smckusick case KBD_EXT_LEFT_UP: 350*41480Smckusick case KBD_EXT_RIGHT_UP: 351*41480Smckusick metamode = 0; 352*41480Smckusick return; 353*41480Smckusick } 354*41480Smckusick 355*41480Smckusick c &= KBD_CHARMASK; 356*41480Smckusick switch ((stat>>KBD_SSHIFT) & KBD_SMASK) { 357*41480Smckusick 358*41480Smckusick case KBD_KEY: 359*41480Smckusick if (!capsmode) { 360*41480Smckusick code = kbd_keymap[c]; 361*41480Smckusick break; 362*41480Smckusick } 363*41480Smckusick /* fall into... */ 364*41480Smckusick 365*41480Smckusick case KBD_SHIFT: 366*41480Smckusick code = kbd_shiftmap[c]; 367*41480Smckusick break; 368*41480Smckusick 369*41480Smckusick case KBD_CTRL: 370*41480Smckusick code = kbd_ctrlmap[c]; 371*41480Smckusick break; 372*41480Smckusick 373*41480Smckusick case KBD_CTRLSHIFT: 374*41480Smckusick code = kbd_ctrlshiftmap[c]; 375*41480Smckusick break; 376*41480Smckusick } 377*41480Smckusick 378*41480Smckusick if (code == NULL && (str = kbd_stringmap[c]) != NULL) { 379*41480Smckusick while (*str) 380*41480Smckusick (*linesw[kbd_tty->t_line].l_rint)(*str++, kbd_tty); 381*41480Smckusick } else { 382*41480Smckusick if (metamode) 383*41480Smckusick code |= 0x80; 384*41480Smckusick (*linesw[kbd_tty->t_line].l_rint)(code, kbd_tty); 385*41480Smckusick } 386*41480Smckusick } 387*41480Smckusick 388*41480Smckusick iteputchar(c, dev) 389*41480Smckusick register int c; 390*41480Smckusick dev_t dev; 391*41480Smckusick { 392*41480Smckusick int unit = UNIT(dev); 393*41480Smckusick register struct ite_softc *ip = &ite_softc[unit]; 394*41480Smckusick register struct itesw *sp = &itesw[ip->type]; 395*41480Smckusick register int n; 396*41480Smckusick 397*41480Smckusick if ((ip->flags & (ITE_ACTIVE|ITE_INGRF)) != ITE_ACTIVE) 398*41480Smckusick return; 399*41480Smckusick 400*41480Smckusick if (ip->escape) { 401*41480Smckusick doesc: 402*41480Smckusick switch (ip->escape) { 403*41480Smckusick 404*41480Smckusick case '&': /* Next can be a,d, or s */ 405*41480Smckusick if (ip->fpd++) { 406*41480Smckusick ip->escape = c; 407*41480Smckusick ip->fpd = 0; 408*41480Smckusick } 409*41480Smckusick return; 410*41480Smckusick 411*41480Smckusick case 'a': /* cursor change */ 412*41480Smckusick switch (c) { 413*41480Smckusick 414*41480Smckusick case 'Y': /* Only y coord. */ 415*41480Smckusick ip->cury = MIN(ip->pos, ip->rows-1); 416*41480Smckusick ip->pos = 0; 417*41480Smckusick ip->escape = 0; 418*41480Smckusick (*sp->ite_cursor)(ip, MOVE_CURSOR); 419*41480Smckusick clr_attr(ip, ATTR_INV); 420*41480Smckusick break; 421*41480Smckusick 422*41480Smckusick case 'y': /* y coord first */ 423*41480Smckusick ip->cury = MIN(ip->pos, ip->rows-1); 424*41480Smckusick ip->pos = 0; 425*41480Smckusick ip->fpd = 0; 426*41480Smckusick break; 427*41480Smckusick 428*41480Smckusick case 'C': /* x coord */ 429*41480Smckusick ip->curx = MIN(ip->pos, ip->cols-1); 430*41480Smckusick ip->pos = 0; 431*41480Smckusick ip->escape = 0; 432*41480Smckusick (*sp->ite_cursor)(ip, MOVE_CURSOR); 433*41480Smckusick clr_attr(ip, ATTR_INV); 434*41480Smckusick break; 435*41480Smckusick 436*41480Smckusick default: /* Possibly a 3 digit number. */ 437*41480Smckusick if (c >= '0' && c <= '9' && ip->fpd < 3) { 438*41480Smckusick ip->pos = ip->pos * 10 + (c - '0'); 439*41480Smckusick ip->fpd++; 440*41480Smckusick } else { 441*41480Smckusick ip->pos = 0; 442*41480Smckusick ip->escape = 0; 443*41480Smckusick } 444*41480Smckusick break; 445*41480Smckusick } 446*41480Smckusick return; 447*41480Smckusick 448*41480Smckusick case 'd': /* attribute change */ 449*41480Smckusick switch (c) { 450*41480Smckusick 451*41480Smckusick case 'B': 452*41480Smckusick set_attr(ip, ATTR_INV); 453*41480Smckusick break; 454*41480Smckusick case 'D': 455*41480Smckusick /* XXX: we don't do anything for underline */ 456*41480Smckusick set_attr(ip, ATTR_UL); 457*41480Smckusick break; 458*41480Smckusick case '@': 459*41480Smckusick clr_attr(ip, ATTR_ALL); 460*41480Smckusick break; 461*41480Smckusick } 462*41480Smckusick ip->escape = 0; 463*41480Smckusick return; 464*41480Smckusick 465*41480Smckusick case 's': /* keypad control */ 466*41480Smckusick switch (ip->fpd) { 467*41480Smckusick 468*41480Smckusick case 0: 469*41480Smckusick ip->hold = c; 470*41480Smckusick ip->fpd++; 471*41480Smckusick return; 472*41480Smckusick 473*41480Smckusick case 1: 474*41480Smckusick if (c == 'A') { 475*41480Smckusick switch (ip->hold) { 476*41480Smckusick 477*41480Smckusick case '0': 478*41480Smckusick clr_attr(ip, ATTR_KPAD); 479*41480Smckusick break; 480*41480Smckusick case '1': 481*41480Smckusick set_attr(ip, ATTR_KPAD); 482*41480Smckusick break; 483*41480Smckusick } 484*41480Smckusick } 485*41480Smckusick ip->hold = 0; 486*41480Smckusick } 487*41480Smckusick ip->escape = 0; 488*41480Smckusick return; 489*41480Smckusick 490*41480Smckusick case 'i': /* back tab */ 491*41480Smckusick if (ip->curx > TABSIZE) { 492*41480Smckusick n = ip->curx - (ip->curx & (TABSIZE - 1)); 493*41480Smckusick ip->curx -= n; 494*41480Smckusick } else 495*41480Smckusick ip->curx = 0; 496*41480Smckusick (*sp->ite_cursor)(ip, MOVE_CURSOR); 497*41480Smckusick ip->escape = 0; 498*41480Smckusick return; 499*41480Smckusick 500*41480Smckusick case '3': /* clear all tabs */ 501*41480Smckusick goto ignore; 502*41480Smckusick 503*41480Smckusick case 'K': /* clear_eol */ 504*41480Smckusick ite_clrtoeol(ip, sp, ip->cury, ip->curx); 505*41480Smckusick ip->escape = 0; 506*41480Smckusick return; 507*41480Smckusick 508*41480Smckusick case 'J': /* clear_eos */ 509*41480Smckusick ite_clrtoeos(ip, sp); 510*41480Smckusick ip->escape = 0; 511*41480Smckusick return; 512*41480Smckusick 513*41480Smckusick case 'B': /* cursor down 1 line */ 514*41480Smckusick if (++ip->cury == ip->rows) { 515*41480Smckusick --ip->cury; 516*41480Smckusick (*sp->ite_scroll)(ip, 1, 0, 1, SCROLL_UP); 517*41480Smckusick ite_clrtoeol(ip, sp, ip->cury, 0); 518*41480Smckusick } 519*41480Smckusick else 520*41480Smckusick (*sp->ite_cursor)(ip, MOVE_CURSOR); 521*41480Smckusick clr_attr(ip, ATTR_INV); 522*41480Smckusick ip->escape = 0; 523*41480Smckusick return; 524*41480Smckusick 525*41480Smckusick case 'C': /* cursor forward 1 char */ 526*41480Smckusick ip->escape = 0; 527*41480Smckusick itecheckwrap(ip, sp); 528*41480Smckusick return; 529*41480Smckusick 530*41480Smckusick case 'A': /* cursor up 1 line */ 531*41480Smckusick if (ip->cury > 0) { 532*41480Smckusick ip->cury--; 533*41480Smckusick (*sp->ite_cursor)(ip, MOVE_CURSOR); 534*41480Smckusick } 535*41480Smckusick ip->escape = 0; 536*41480Smckusick clr_attr(ip, ATTR_INV); 537*41480Smckusick return; 538*41480Smckusick 539*41480Smckusick case 'P': /* delete character */ 540*41480Smckusick ite_dchar(ip, sp); 541*41480Smckusick ip->escape = 0; 542*41480Smckusick return; 543*41480Smckusick 544*41480Smckusick case 'M': /* delete line */ 545*41480Smckusick ite_dline(ip, sp); 546*41480Smckusick ip->escape = 0; 547*41480Smckusick return; 548*41480Smckusick 549*41480Smckusick case 'Q': /* enter insert mode */ 550*41480Smckusick ip->imode = 1; 551*41480Smckusick ip->escape = 0; 552*41480Smckusick return; 553*41480Smckusick 554*41480Smckusick case 'R': /* exit insert mode */ 555*41480Smckusick ip->imode = 0; 556*41480Smckusick ip->escape = 0; 557*41480Smckusick return; 558*41480Smckusick 559*41480Smckusick case 'L': /* insert blank line */ 560*41480Smckusick ite_iline(ip, sp); 561*41480Smckusick ip->escape = 0; 562*41480Smckusick return; 563*41480Smckusick 564*41480Smckusick case 'h': /* home key */ 565*41480Smckusick ip->cury = ip->curx = 0; 566*41480Smckusick (*sp->ite_cursor)(ip, MOVE_CURSOR); 567*41480Smckusick ip->escape = 0; 568*41480Smckusick return; 569*41480Smckusick 570*41480Smckusick case 'D': /* left arrow key */ 571*41480Smckusick if (ip->curx > 0) { 572*41480Smckusick ip->curx--; 573*41480Smckusick (*sp->ite_cursor)(ip, MOVE_CURSOR); 574*41480Smckusick } 575*41480Smckusick ip->escape = 0; 576*41480Smckusick return; 577*41480Smckusick 578*41480Smckusick case '1': /* set tab in all rows */ 579*41480Smckusick goto ignore; 580*41480Smckusick 581*41480Smckusick case ESC: 582*41480Smckusick if ((ip->escape = c) == ESC) 583*41480Smckusick break; 584*41480Smckusick ip->fpd = 0; 585*41480Smckusick goto doesc; 586*41480Smckusick 587*41480Smckusick default: 588*41480Smckusick ignore: 589*41480Smckusick ip->escape = 0; 590*41480Smckusick return; 591*41480Smckusick 592*41480Smckusick } 593*41480Smckusick } 594*41480Smckusick 595*41480Smckusick switch (c &= 0x7F) { 596*41480Smckusick 597*41480Smckusick case '\n': 598*41480Smckusick 599*41480Smckusick if (++ip->cury == ip->rows) { 600*41480Smckusick --ip->cury; 601*41480Smckusick (*sp->ite_scroll)(ip, 1, 0, 1, SCROLL_UP); 602*41480Smckusick ite_clrtoeol(ip, sp, ip->cury, 0); 603*41480Smckusick } 604*41480Smckusick else 605*41480Smckusick (*sp->ite_cursor)(ip, MOVE_CURSOR); 606*41480Smckusick clr_attr(ip, ATTR_INV); 607*41480Smckusick break; 608*41480Smckusick 609*41480Smckusick case '\r': 610*41480Smckusick if (ip->curx) { 611*41480Smckusick ip->curx = 0; 612*41480Smckusick (*sp->ite_cursor)(ip, MOVE_CURSOR); 613*41480Smckusick } 614*41480Smckusick break; 615*41480Smckusick 616*41480Smckusick case '\b': 617*41480Smckusick if (--ip->curx < 0) 618*41480Smckusick ip->curx = 0; 619*41480Smckusick else 620*41480Smckusick (*sp->ite_cursor)(ip, MOVE_CURSOR); 621*41480Smckusick break; 622*41480Smckusick 623*41480Smckusick case '\t': 624*41480Smckusick if (ip->curx < TABEND(unit)) { 625*41480Smckusick n = TABSIZE - (ip->curx & (TABSIZE - 1)); 626*41480Smckusick ip->curx += n; 627*41480Smckusick (*sp->ite_cursor)(ip, MOVE_CURSOR); 628*41480Smckusick } else 629*41480Smckusick itecheckwrap(ip, sp); 630*41480Smckusick break; 631*41480Smckusick 632*41480Smckusick case CTRL('G'): 633*41480Smckusick if (&ite_tty[unit] == kbd_tty) 634*41480Smckusick kbdbell(); 635*41480Smckusick break; 636*41480Smckusick 637*41480Smckusick case ESC: 638*41480Smckusick ip->escape = ESC; 639*41480Smckusick break; 640*41480Smckusick 641*41480Smckusick default: 642*41480Smckusick if (c < ' ' || c == DEL) 643*41480Smckusick break; 644*41480Smckusick if (ip->imode) 645*41480Smckusick ite_ichar(ip, sp); 646*41480Smckusick if ((ip->attribute & ATTR_INV) || attrtest(ip, ATTR_INV)) { 647*41480Smckusick attrset(ip, ATTR_INV); 648*41480Smckusick (*sp->ite_putc)(ip, c, ip->cury, ip->curx, ATTR_INV); 649*41480Smckusick } 650*41480Smckusick else 651*41480Smckusick (*sp->ite_putc)(ip, c, ip->cury, ip->curx, ATTR_NOR); 652*41480Smckusick (*sp->ite_cursor)(ip, DRAW_CURSOR); 653*41480Smckusick itecheckwrap(ip, sp); 654*41480Smckusick break; 655*41480Smckusick } 656*41480Smckusick } 657*41480Smckusick 658*41480Smckusick itecheckwrap(ip, sp) 659*41480Smckusick register struct ite_softc *ip; 660*41480Smckusick register struct itesw *sp; 661*41480Smckusick { 662*41480Smckusick if (++ip->curx == ip->cols) { 663*41480Smckusick ip->curx = 0; 664*41480Smckusick clr_attr(ip, ATTR_INV); 665*41480Smckusick if (++ip->cury == ip->rows) { 666*41480Smckusick --ip->cury; 667*41480Smckusick (*sp->ite_scroll)(ip, 1, 0, 1, SCROLL_UP); 668*41480Smckusick ite_clrtoeol(ip, sp, ip->cury, 0); 669*41480Smckusick return; 670*41480Smckusick } 671*41480Smckusick } 672*41480Smckusick (*sp->ite_cursor)(ip, MOVE_CURSOR); 673*41480Smckusick } 674*41480Smckusick 675*41480Smckusick ite_dchar(ip, sp) 676*41480Smckusick register struct ite_softc *ip; 677*41480Smckusick register struct itesw *sp; 678*41480Smckusick { 679*41480Smckusick (*sp->ite_scroll)(ip, ip->cury, ip->curx + 1, 1, SCROLL_LEFT); 680*41480Smckusick attrmov(ip, ip->cury, ip->curx + 1, ip->cury, ip->curx, 681*41480Smckusick 1, ip->cols - ip->curx - 1); 682*41480Smckusick attrclr(ip, ip->cury, ip->cols - 1, 1, 1); 683*41480Smckusick (*sp->ite_putc)(ip, ' ', ip->cury, ip->cols - 1, ATTR_NOR); 684*41480Smckusick (*sp->ite_cursor)(ip, DRAW_CURSOR); 685*41480Smckusick } 686*41480Smckusick 687*41480Smckusick ite_ichar(ip, sp) 688*41480Smckusick register struct ite_softc *ip; 689*41480Smckusick register struct itesw *sp; 690*41480Smckusick { 691*41480Smckusick (*sp->ite_scroll)(ip, ip->cury, ip->curx, 1, SCROLL_RIGHT); 692*41480Smckusick attrmov(ip, ip->cury, ip->curx, ip->cury, ip->curx + 1, 693*41480Smckusick 1, ip->cols - ip->curx - 1); 694*41480Smckusick attrclr(ip, ip->cury, ip->curx, 1, 1); 695*41480Smckusick (*sp->ite_putc)(ip, ' ', ip->cury, ip->curx, ATTR_NOR); 696*41480Smckusick (*sp->ite_cursor)(ip, DRAW_CURSOR); 697*41480Smckusick } 698*41480Smckusick 699*41480Smckusick ite_dline(ip, sp) 700*41480Smckusick register struct ite_softc *ip; 701*41480Smckusick register struct itesw *sp; 702*41480Smckusick { 703*41480Smckusick (*sp->ite_scroll)(ip, ip->cury + 1, 0, 1, SCROLL_UP); 704*41480Smckusick attrmov(ip, ip->cury + 1, 0, ip->cury, 0, 705*41480Smckusick ip->rows - ip->cury - 1, ip->cols); 706*41480Smckusick ite_clrtoeol(ip, sp, ip->rows - 1, 0); 707*41480Smckusick } 708*41480Smckusick 709*41480Smckusick ite_iline(ip, sp) 710*41480Smckusick register struct ite_softc *ip; 711*41480Smckusick register struct itesw *sp; 712*41480Smckusick { 713*41480Smckusick (*sp->ite_scroll)(ip, ip->cury, 0, 1, SCROLL_DOWN); 714*41480Smckusick attrmov(ip, ip->cury, 0, ip->cury + 1, 0, 715*41480Smckusick ip->rows - ip->cury - 1, ip->cols); 716*41480Smckusick ite_clrtoeol(ip, sp, ip->cury, 0); 717*41480Smckusick } 718*41480Smckusick 719*41480Smckusick ite_clrtoeol(ip, sp, y, x) 720*41480Smckusick register struct ite_softc *ip; 721*41480Smckusick register struct itesw *sp; 722*41480Smckusick register int y, x; 723*41480Smckusick { 724*41480Smckusick (*sp->ite_clear)(ip, y, x, 1, ip->cols - x); 725*41480Smckusick attrclr(ip, y, x, 1, ip->cols - x); 726*41480Smckusick (*sp->ite_cursor)(ip, DRAW_CURSOR); 727*41480Smckusick } 728*41480Smckusick 729*41480Smckusick ite_clrtoeos(ip, sp) 730*41480Smckusick register struct ite_softc *ip; 731*41480Smckusick register struct itesw *sp; 732*41480Smckusick { 733*41480Smckusick (*sp->ite_clear)(ip, ip->cury, 0, ip->rows - ip->cury, ip->cols); 734*41480Smckusick attrclr(ip, ip->cury, 0, ip->rows - ip->cury, ip->cols); 735*41480Smckusick (*sp->ite_cursor)(ip, DRAW_CURSOR); 736*41480Smckusick } 737*41480Smckusick 738*41480Smckusick /* 739*41480Smckusick * Console functions 740*41480Smckusick */ 741*41480Smckusick #include "machine/cons.h" 742*41480Smckusick #include "grfioctl.h" 743*41480Smckusick #include "grfvar.h" 744*41480Smckusick 745*41480Smckusick #ifdef DEBUG 746*41480Smckusick /* 747*41480Smckusick * Minimum ITE number at which to start looking for a console. 748*41480Smckusick * Setting to 0 will do normal search, 1 will skip first ITE device, 749*41480Smckusick * NITE will skip ITEs and use serial port. 750*41480Smckusick */ 751*41480Smckusick int whichconsole = 0; 752*41480Smckusick #endif 753*41480Smckusick 754*41480Smckusick itecnprobe(cp) 755*41480Smckusick struct consdev *cp; 756*41480Smckusick { 757*41480Smckusick register struct ite_softc *ip; 758*41480Smckusick int i, maj, unit, pri; 759*41480Smckusick extern int iteopen(); 760*41480Smckusick 761*41480Smckusick /* locate the major number */ 762*41480Smckusick for (maj = 0; maj < nchrdev; maj++) 763*41480Smckusick if (cdevsw[maj].d_open == iteopen) 764*41480Smckusick break; 765*41480Smckusick 766*41480Smckusick /* urk! */ 767*41480Smckusick grfconfig(); 768*41480Smckusick 769*41480Smckusick /* check all the individual displays and find the best */ 770*41480Smckusick unit = -1; 771*41480Smckusick pri = CN_DEAD; 772*41480Smckusick for (i = 0; i < NITE; i++) { 773*41480Smckusick struct grf_softc *gp = &grf_softc[i]; 774*41480Smckusick 775*41480Smckusick ip = &ite_softc[i]; 776*41480Smckusick if ((gp->g_flags & GF_ALIVE) == 0) 777*41480Smckusick continue; 778*41480Smckusick ip->flags = (ITE_ALIVE|ITE_CONSOLE); 779*41480Smckusick 780*41480Smckusick /* XXX - we need to do something about mapping these */ 781*41480Smckusick switch (gp->g_type) { 782*41480Smckusick 783*41480Smckusick case GT_TOPCAT: 784*41480Smckusick case GT_LRCATSEYE: 785*41480Smckusick case GT_HRCCATSEYE: 786*41480Smckusick case GT_HRMCATSEYE: 787*41480Smckusick ip->type = ITE_TOPCAT; 788*41480Smckusick break; 789*41480Smckusick case GT_GATORBOX: 790*41480Smckusick ip->type = ITE_GATORBOX; 791*41480Smckusick break; 792*41480Smckusick case GT_RENAISSANCE: 793*41480Smckusick ip->type = ITE_RENAISSANCE; 794*41480Smckusick break; 795*41480Smckusick case GT_DAVINCI: 796*41480Smckusick ip->type = ITE_DAVINCI; 797*41480Smckusick break; 798*41480Smckusick } 799*41480Smckusick #ifdef DEBUG 800*41480Smckusick if (i < whichconsole) 801*41480Smckusick continue; 802*41480Smckusick #endif 803*41480Smckusick if ((int)gp->g_display.gd_regaddr == GRFIADDR) { 804*41480Smckusick pri = CN_INTERNAL; 805*41480Smckusick unit = i; 806*41480Smckusick } else if (unit < 0) { 807*41480Smckusick pri = CN_NORMAL; 808*41480Smckusick unit = i; 809*41480Smckusick } 810*41480Smckusick } 811*41480Smckusick 812*41480Smckusick /* initialize required fields */ 813*41480Smckusick cp->cn_dev = makedev(maj, unit); 814*41480Smckusick cp->cn_tp = &ite_tty[unit]; 815*41480Smckusick cp->cn_pri = pri; 816*41480Smckusick } 817*41480Smckusick 818*41480Smckusick itecninit(cp) 819*41480Smckusick struct consdev *cp; 820*41480Smckusick { 821*41480Smckusick int unit = UNIT(cp->cn_dev); 822*41480Smckusick struct ite_softc *ip = &ite_softc[unit]; 823*41480Smckusick 824*41480Smckusick ip->attrbuf = console_attributes; 825*41480Smckusick iteinit(cp->cn_dev); 826*41480Smckusick ip->flags |= (ITE_ACTIVE|ITE_ISCONS); 827*41480Smckusick kbd_tty = &ite_tty[unit]; 828*41480Smckusick } 829*41480Smckusick 830*41480Smckusick /*ARGSUSED*/ 831*41480Smckusick itecngetc(dev) 832*41480Smckusick dev_t dev; 833*41480Smckusick { 834*41480Smckusick register int c; 835*41480Smckusick int stat; 836*41480Smckusick 837*41480Smckusick c = kbdgetc(&stat); 838*41480Smckusick switch ((stat >> KBD_SSHIFT) & KBD_SMASK) { 839*41480Smckusick case KBD_SHIFT: 840*41480Smckusick c = kbd_shiftmap[c & KBD_CHARMASK]; 841*41480Smckusick break; 842*41480Smckusick case KBD_CTRL: 843*41480Smckusick c = kbd_ctrlmap[c & KBD_CHARMASK]; 844*41480Smckusick break; 845*41480Smckusick case KBD_KEY: 846*41480Smckusick c = kbd_keymap[c & KBD_CHARMASK]; 847*41480Smckusick break; 848*41480Smckusick default: 849*41480Smckusick c = 0; 850*41480Smckusick break; 851*41480Smckusick } 852*41480Smckusick return(c); 853*41480Smckusick } 854*41480Smckusick 855*41480Smckusick itecnputc(dev, c) 856*41480Smckusick dev_t dev; 857*41480Smckusick int c; 858*41480Smckusick { 859*41480Smckusick static int paniced = 0; 860*41480Smckusick struct ite_softc *ip = &ite_softc[UNIT(dev)]; 861*41480Smckusick extern char *panicstr; 862*41480Smckusick 863*41480Smckusick if (panicstr && !paniced && 864*41480Smckusick (ip->flags & (ITE_ACTIVE|ITE_INGRF)) != ITE_ACTIVE) { 865*41480Smckusick (void) iteon(dev, 3); 866*41480Smckusick paniced = 1; 867*41480Smckusick } 868*41480Smckusick iteputchar(c, dev); 869*41480Smckusick } 870*41480Smckusick #endif 871