1*41053Swilliam /*- 2*41053Swilliam * Copyright (c) 1990 The Regents of the University of California. 3*41053Swilliam * All rights reserved. 4*41053Swilliam * 5*41053Swilliam * This code is derived from software contributed to Berkeley by 6*41053Swilliam * William Jolitz. 7*41053Swilliam * 8*41053Swilliam * %sccs.include.386.c% 9*41053Swilliam * 10*41053Swilliam * @(#)pccons.c 5.1 (Berkeley) 04/24/90 11*41053Swilliam */ 12*41053Swilliam 13*41053Swilliam /* 14*41053Swilliam * code to work keyboard & display for console 15*41053Swilliam */ 16*41053Swilliam #include "param.h" 17*41053Swilliam #include "conf.h" 18*41053Swilliam #include "dir.h" 19*41053Swilliam #include "ioctl.h" 20*41053Swilliam #include "user.h" 21*41053Swilliam #include "proc.h" 22*41053Swilliam #include "tty.h" 23*41053Swilliam #include "uio.h" 24*41053Swilliam #include "callout.h" 25*41053Swilliam #include "systm.h" 26*41053Swilliam #include "kernel.h" 27*41053Swilliam #include "syslog.h" 28*41053Swilliam #include "icu.h" 29*41053Swilliam 30*41053Swilliam struct tty cons; 31*41053Swilliam 32*41053Swilliam struct consoftc { 33*41053Swilliam char cs_flags; 34*41053Swilliam #define CSF_ACTIVE 0x1 /* timeout active */ 35*41053Swilliam #define CSF_POLLING 0x2 /* polling for input */ 36*41053Swilliam char cs_lastc; /* last char sent */ 37*41053Swilliam int cs_timo; /* timeouts since interrupt */ 38*41053Swilliam u_long cs_wedgecnt; /* times restarted */ 39*41053Swilliam } consoftc; 40*41053Swilliam 41*41053Swilliam /* 42*41053Swilliam * We check the console periodically to make sure 43*41053Swilliam * that it hasn't wedged. Unfortunately, if an XOFF 44*41053Swilliam * is typed on the console, that can't be distinguished 45*41053Swilliam * from more catastrophic failure. 46*41053Swilliam */ 47*41053Swilliam #define CN_TIMERVAL (hz) /* frequency at which to check cons */ 48*41053Swilliam #define CN_TIMO (2*60) /* intervals to allow for output char */ 49*41053Swilliam 50*41053Swilliam int cnstart(); 51*41053Swilliam int ttrstrt(); 52*41053Swilliam char partab[]; 53*41053Swilliam 54*41053Swilliam /* 55*41053Swilliam * Wait for CP to accept last CP command sent 56*41053Swilliam * before setting up next command. 57*41053Swilliam */ 58*41053Swilliam #define waitforlast(timo) { \ 59*41053Swilliam if (cnlast) { \ 60*41053Swilliam (timo) = 10000; \ 61*41053Swilliam do \ 62*41053Swilliam uncache((char *)&cnlast->cp_unit); \ 63*41053Swilliam while ((cnlast->cp_unit&CPTAKE) == 0 && --(timo)); \ 64*41053Swilliam } \ 65*41053Swilliam } 66*41053Swilliam 67*41053Swilliam u_char inb(); 68*41053Swilliam 69*41053Swilliam /*ARGSUSED*/ 70*41053Swilliam cnopen(dev, flag) 71*41053Swilliam dev_t dev; 72*41053Swilliam { 73*41053Swilliam register struct tty *tp; 74*41053Swilliam int unit = minor(dev); 75*41053Swilliam 76*41053Swilliam tp = &cons; 77*41053Swilliam if (tp->t_state&TS_XCLUDE && u.u_uid != 0) 78*41053Swilliam return (EBUSY); 79*41053Swilliam tp->t_oproc = cnstart; 80*41053Swilliam if ((tp->t_state&TS_ISOPEN) == 0) { 81*41053Swilliam ttychars(tp); 82*41053Swilliam tp->t_state = TS_ISOPEN|TS_CARR_ON; 83*41053Swilliam tp->t_flags = EVENP|ECHO|XTABS|CRMOD; 84*41053Swilliam INTREN(IRQ1); 85*41053Swilliam splnone(); 86*41053Swilliam } 87*41053Swilliam return ((*linesw[tp->t_line].l_open)(dev, tp)); 88*41053Swilliam } 89*41053Swilliam 90*41053Swilliam 91*41053Swilliam cnclose(dev) 92*41053Swilliam dev_t dev; 93*41053Swilliam { 94*41053Swilliam (*linesw[cons.t_line].l_close)(&cons); 95*41053Swilliam ttyclose(&cons); 96*41053Swilliam INTRDIS(IRQ1); 97*41053Swilliam } 98*41053Swilliam 99*41053Swilliam /*ARGSUSED*/ 100*41053Swilliam cnread(dev, uio) 101*41053Swilliam dev_t dev; 102*41053Swilliam struct uio *uio; 103*41053Swilliam { 104*41053Swilliam return ((*linesw[cons.t_line].l_read)(&cons, uio)); 105*41053Swilliam } 106*41053Swilliam 107*41053Swilliam /*ARGSUSED*/ 108*41053Swilliam cnwrite(dev, uio) 109*41053Swilliam dev_t dev; 110*41053Swilliam struct uio *uio; 111*41053Swilliam { 112*41053Swilliam return ((*linesw[cons.t_line].l_write)(&cons, uio)); 113*41053Swilliam } 114*41053Swilliam 115*41053Swilliam /* 116*41053Swilliam * Got a console receive interrupt - 117*41053Swilliam * the console processor wants to give us a character. 118*41053Swilliam * Catch the character, and see who it goes to. 119*41053Swilliam */ 120*41053Swilliam cnrint(dev) 121*41053Swilliam dev_t dev; 122*41053Swilliam { 123*41053Swilliam int c; 124*41053Swilliam 125*41053Swilliam c = sgetc(1); 126*41053Swilliam if (c&0x100)return; 127*41053Swilliam if (consoftc.cs_flags&CSF_POLLING) 128*41053Swilliam return; 129*41053Swilliam #ifdef KDB 130*41053Swilliam if (kdbrintr(c, &cons)) 131*41053Swilliam return; 132*41053Swilliam #endif 133*41053Swilliam (*linesw[cons.t_line].l_rint)(c&0xff, &cons); 134*41053Swilliam } 135*41053Swilliam 136*41053Swilliam cnioctl(dev, cmd, addr, flag) 137*41053Swilliam dev_t dev; 138*41053Swilliam caddr_t addr; 139*41053Swilliam { 140*41053Swilliam register struct tty *tp = &cons; 141*41053Swilliam register error; 142*41053Swilliam 143*41053Swilliam error = (*linesw[tp->t_line].l_ioctl)(tp, cmd, addr); 144*41053Swilliam if (error >= 0) 145*41053Swilliam return error; 146*41053Swilliam if ((error = ttioctl(tp, cmd, addr, flag)) < 0) 147*41053Swilliam error = ENOTTY; 148*41053Swilliam else if (cmd == TIOCSETP || cmd == TIOCSETN) 149*41053Swilliam cnparams(tp); 150*41053Swilliam return (error); 151*41053Swilliam } 152*41053Swilliam 153*41053Swilliam int consintr = 1; 154*41053Swilliam /* 155*41053Swilliam * Got a console transmission interrupt - 156*41053Swilliam * the console processor wants another character. 157*41053Swilliam */ 158*41053Swilliam cnxint(dev) 159*41053Swilliam dev_t dev; 160*41053Swilliam { 161*41053Swilliam register struct tty *tp; 162*41053Swilliam register int unit; 163*41053Swilliam 164*41053Swilliam if (!consintr) 165*41053Swilliam return; 166*41053Swilliam cons.t_state &= ~TS_BUSY; 167*41053Swilliam consoftc.cs_timo = 0; 168*41053Swilliam if (cons.t_line) 169*41053Swilliam (*linesw[cons.t_line].l_start)(&cons); 170*41053Swilliam else 171*41053Swilliam cnstart(&cons); 172*41053Swilliam } 173*41053Swilliam 174*41053Swilliam cnstart(tp) 175*41053Swilliam register struct tty *tp; 176*41053Swilliam { 177*41053Swilliam register c, s; 178*41053Swilliam 179*41053Swilliam s = spltty(); 180*41053Swilliam if (tp->t_state & (TS_TIMEOUT|TS_BUSY|TS_TTSTOP)) 181*41053Swilliam goto out; 182*41053Swilliam if (tp->t_outq.c_cc <= TTLOWAT(tp)) { 183*41053Swilliam if (tp->t_state&TS_ASLEEP) { 184*41053Swilliam tp->t_state &= ~TS_ASLEEP; 185*41053Swilliam wakeup((caddr_t)&tp->t_outq); 186*41053Swilliam } 187*41053Swilliam if (tp->t_wsel) { 188*41053Swilliam selwakeup(tp->t_wsel, tp->t_state & TS_WCOLL); 189*41053Swilliam tp->t_wsel = 0; 190*41053Swilliam tp->t_state &= ~TS_WCOLL; 191*41053Swilliam } 192*41053Swilliam } 193*41053Swilliam while (tp->t_outq.c_cc != 0) { 194*41053Swilliam c = getc(&tp->t_outq) & 0xff; 195*41053Swilliam if ((tp->t_flags & (RAW|LITOUT)) == 0) { 196*41053Swilliam if (c > 0177) 197*41053Swilliam { 198*41053Swilliam timeout(ttrstrt, (caddr_t)tp, (c&0177)); 199*41053Swilliam tp->t_state |= TS_TIMEOUT; 200*41053Swilliam break; 201*41053Swilliam } 202*41053Swilliam c &= 0177; 203*41053Swilliam } 204*41053Swilliam sput(c,0xc); 205*41053Swilliam } 206*41053Swilliam out: 207*41053Swilliam splx(s); 208*41053Swilliam } 209*41053Swilliam 210*41053Swilliam cnputc(c) 211*41053Swilliam char c; 212*41053Swilliam { 213*41053Swilliam 214*41053Swilliam if (c == '\n') 215*41053Swilliam sput('\r',0xb); 216*41053Swilliam sput(c, 0xb); 217*41053Swilliam } 218*41053Swilliam 219*41053Swilliam /* 220*41053Swilliam * Print a character on console. 221*41053Swilliam */ 222*41053Swilliam cnputchar(c, tp) 223*41053Swilliam char c; 224*41053Swilliam register struct tty *tp; 225*41053Swilliam { 226*41053Swilliam sput(c,0xa); 227*41053Swilliam if (c=='\n') getchar(); 228*41053Swilliam } 229*41053Swilliam 230*41053Swilliam 231*41053Swilliam cngetc() 232*41053Swilliam { 233*41053Swilliam register int c, s; 234*41053Swilliam 235*41053Swilliam s = spltty(); /* block cnrint while we poll */ 236*41053Swilliam if (c == '\r') 237*41053Swilliam c = '\n'; 238*41053Swilliam splx(s); 239*41053Swilliam return (c); 240*41053Swilliam } 241*41053Swilliam 242*41053Swilliam cngetchar(tp) 243*41053Swilliam register struct tty *tp; 244*41053Swilliam { 245*41053Swilliam int c; 246*41053Swilliam 247*41053Swilliam c = sgetc(0); 248*41053Swilliam return (c&0xff); 249*41053Swilliam } 250*41053Swilliam 251*41053Swilliam /* 252*41053Swilliam * Set line parameters 253*41053Swilliam */ 254*41053Swilliam cnparams(tp) 255*41053Swilliam register struct tty *tp; 256*41053Swilliam { 257*41053Swilliam } 258*41053Swilliam 259*41053Swilliam #ifdef KDB 260*41053Swilliam /* 261*41053Swilliam * Turn input polling on/off (used by debugger). 262*41053Swilliam */ 263*41053Swilliam cnpoll(onoff) 264*41053Swilliam int onoff; 265*41053Swilliam { 266*41053Swilliam } 267*41053Swilliam #endif 268*41053Swilliam 269*41053Swilliam #define CRT_TXTADDR Crtat 270*41053Swilliam #define COL 80 271*41053Swilliam #define ROW 25 272*41053Swilliam #define CHR 2 273*41053Swilliam 274*41053Swilliam 275*41053Swilliam u_short *Crtat = ((u_short *)0xb8000); 276*41053Swilliam u_short *crtat ; 277*41053Swilliam u_char color = 0xe ; 278*41053Swilliam int row; 279*41053Swilliam 280*41053Swilliam sput(c, ca) u_char c, ca; { 281*41053Swilliam 282*41053Swilliam if(inb(0x64)&2 == 0)sgetc(1); 283*41053Swilliam if (crtat == 0) { 284*41053Swilliam INTREN(IRQ1); /* XXX */ 285*41053Swilliam crtat = CRT_TXTADDR; bzero (crtat,COL*ROW*CHR); 286*41053Swilliam } 287*41053Swilliam /*if (crtat >= (CRT_TXTADDR+COL*(ROW-1))) { 288*41053Swilliam crtat = CRT_TXTADDR+COL*(ROW-1); row = 0; 289*41053Swilliam }*/ 290*41053Swilliam if (crtat >= CRT_TXTADDR+COL*(ROW-1)) { /* scroll */ 291*41053Swilliam bcopy(CRT_TXTADDR+COL, CRT_TXTADDR,COL*(ROW-1)*CHR); 292*41053Swilliam bzero (CRT_TXTADDR+COL*(ROW-1),COL*CHR) ; 293*41053Swilliam crtat -= COL ; 294*41053Swilliam } 295*41053Swilliam switch(c) { 296*41053Swilliam 297*41053Swilliam case '\t': 298*41053Swilliam do { 299*41053Swilliam *crtat++ = (ca<<8)| ' '; row++ ; 300*41053Swilliam } while (row %8); 301*41053Swilliam break; 302*41053Swilliam 303*41053Swilliam case '\010': 304*41053Swilliam crtat--; row--; 305*41053Swilliam break; 306*41053Swilliam 307*41053Swilliam case '\r': 308*41053Swilliam /*bzero (crtat,(COL-row)*CHR) ;*/ crtat -= row ; row = 0; 309*41053Swilliam break; 310*41053Swilliam 311*41053Swilliam case '\n': 312*41053Swilliam if (crtat >= CRT_TXTADDR+COL*(ROW-1)) { /* scroll */ 313*41053Swilliam bcopy(CRT_TXTADDR+COL, CRT_TXTADDR,COL*(ROW-1)*CHR); 314*41053Swilliam bzero (CRT_TXTADDR+COL*(ROW-1),COL*CHR) ; 315*41053Swilliam crtat -= COL ; 316*41053Swilliam } 317*41053Swilliam crtat += COL ; 318*41053Swilliam break; 319*41053Swilliam 320*41053Swilliam default: 321*41053Swilliam *crtat++ = (ca<<8)| c; row++ ; 322*41053Swilliam if (row >= COL) { 323*41053Swilliam /*bzero (crtat,(COL-row)*CHR) ;*/ crtat -= row ; row = 0; 324*41053Swilliam if (crtat >= CRT_TXTADDR+COL*(ROW-1)) { /* scroll */ 325*41053Swilliam bcopy(CRT_TXTADDR+COL, CRT_TXTADDR,COL*(ROW-1)*CHR); 326*41053Swilliam bzero (CRT_TXTADDR+COL*(ROW-1),COL*CHR) ; 327*41053Swilliam crtat -= COL ; 328*41053Swilliam } 329*41053Swilliam crtat += COL ; 330*41053Swilliam } 331*41053Swilliam break ; 332*41053Swilliam } 333*41053Swilliam } 334*41053Swilliam #define L 0x0001 /* locking function */ 335*41053Swilliam #define SHF 0x0002 /* keyboard shift */ 336*41053Swilliam #define ALT 0x0004 /* alternate shift -- alternate chars */ 337*41053Swilliam #define NUM 0x0008 /* numeric shift cursors vs. numeric */ 338*41053Swilliam #define CTL 0x0010 /* control shift -- allows ctl function */ 339*41053Swilliam #define CPS 0x0020 /* caps shift -- swaps case of letter */ 340*41053Swilliam #define ASCII 0x0040 /* ascii code for this key */ 341*41053Swilliam #define STP 0x0080 /* stop output */ 342*41053Swilliam #define FUNC 0x0100 /* function key */ 343*41053Swilliam #define SYSREQ 0x0200 /* sys req key */ 344*41053Swilliam 345*41053Swilliam unsigned __debug ; 346*41053Swilliam u_short action[] = { 347*41053Swilliam 0, ASCII, ASCII, ASCII, ASCII, ASCII, ASCII, ASCII, /* scan 0- 7 */ 348*41053Swilliam ASCII, ASCII, ASCII, ASCII, ASCII, ASCII, ASCII, ASCII, /* scan 8-15 */ 349*41053Swilliam ASCII, ASCII, ASCII, ASCII, ASCII, ASCII, ASCII, ASCII, /* scan 16-23 */ 350*41053Swilliam ASCII, ASCII, ASCII, ASCII, ASCII, CTL, ASCII, ASCII, /* scan 24-31 */ 351*41053Swilliam ASCII, ASCII, ASCII, ASCII, ASCII, ASCII, ASCII, ASCII, /* scan 32-39 */ 352*41053Swilliam ASCII, ASCII, SHF , ASCII, ASCII, ASCII, ASCII, ASCII, /* scan 40-47 */ 353*41053Swilliam ASCII, ASCII, ASCII, ASCII, ASCII, ASCII, SHF, ASCII, /* scan 48-55 */ 354*41053Swilliam ALT, ASCII, CPS|L, FUNC , FUNC , FUNC , FUNC , FUNC , /* scan 56-63 */ 355*41053Swilliam FUNC , FUNC , FUNC , FUNC , FUNC , NUM|L, STP|L, ASCII, /* scan 64-71 */ 356*41053Swilliam ASCII, ASCII, ASCII, ASCII, ASCII, ASCII, ASCII, ASCII, /* scan 72-79 */ 357*41053Swilliam ASCII, ASCII, ASCII, ASCII, 0, 0, 0, 0, /* scan 80-87 */ 358*41053Swilliam 0,0,0,0,0,0,0,0, 359*41053Swilliam 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 360*41053Swilliam 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, } ; 361*41053Swilliam 362*41053Swilliam u_char unshift[] = { /* no shift */ 363*41053Swilliam 0, 033 , '1' , '2' , '3' , '4' , '5' , '6' , /* scan 0- 7 */ 364*41053Swilliam '7' , '8' , '9' , '0' , '-' , '=' , 0177 ,'\t' , /* scan 8-15 */ 365*41053Swilliam 366*41053Swilliam 'q' , 'w' , 'e' , 'r' , 't' , 'y' , 'u' , 'i' , /* scan 16-23 */ 367*41053Swilliam 'o' , 'p' , '[' , ']' , '\r' , CTL , 'a' , 's' , /* scan 24-31 */ 368*41053Swilliam 369*41053Swilliam 'd' , 'f' , 'g' , 'h' , 'j' , 'k' , 'l' , ';' , /* scan 32-39 */ 370*41053Swilliam '\'' , '`' , SHF , '\\' , 'z' , 'x' , 'c' , 'v' , /* scan 40-47 */ 371*41053Swilliam 372*41053Swilliam 'b' , 'n' , 'm' , ',' , '.' , '/' , SHF , '*', /* scan 48-55 */ 373*41053Swilliam ALT , ' ' , CPS|L, 1, 2, 3 , 4, 5, /* scan 56-63 */ 374*41053Swilliam 375*41053Swilliam 6, 7, 8, 9, 10, NUM|L, STP|L, '7', /* scan 64-71 */ 376*41053Swilliam '8', '9', '-', '4', '5', '6', '+', '1', /* scan 72-79 */ 377*41053Swilliam 378*41053Swilliam '2', '3', '0', '.', 0, 0, 0, 0, /* scan 80-87 */ 379*41053Swilliam 0,0,0,0,0,0,0,0, 380*41053Swilliam 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 381*41053Swilliam 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, } ; 382*41053Swilliam 383*41053Swilliam u_char shift[] = { /* shift shift */ 384*41053Swilliam 0, 033 , '!' , '@' , '#' , '$' , '%' , '^' , /* scan 0- 7 */ 385*41053Swilliam '&' , '*' , '(' , ')' , '_' , '+' , 0177 ,'\t' , /* scan 8-15 */ 386*41053Swilliam 'Q' , 'W' , 'E' , 'R' , 'T' , 'Y' , 'U' , 'I' , /* scan 16-23 */ 387*41053Swilliam 'O' , 'P' , '{' , '}' , '\r' , CTL , 'A' , 'S' , /* scan 24-31 */ 388*41053Swilliam 'D' , 'F' , 'G' , 'H' , 'J' , 'K' , 'L' , ':' , /* scan 32-39 */ 389*41053Swilliam '"' , '~' , SHF , '|' , 'Z' , 'X' , 'C' , 'V' , /* scan 40-47 */ 390*41053Swilliam 'B' , 'N' , 'M' , '<' , '>' , '?' , SHF , '*', /* scan 48-55 */ 391*41053Swilliam ALT , ' ' , CPS|L, 0, 0, ' ' , 0, 0, /* scan 56-63 */ 392*41053Swilliam 0, 0, 0, 0, 0, NUM|L, STP|L, '7', /* scan 64-71 */ 393*41053Swilliam '8', '9', '-', '4', '5', '6', '+', '1', /* scan 72-79 */ 394*41053Swilliam '2', '3', '0', '.', 0, 0, 0, 0, /* scan 80-87 */ 395*41053Swilliam 0,0,0,0,0,0,0,0, 396*41053Swilliam 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 397*41053Swilliam 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, } ; 398*41053Swilliam 399*41053Swilliam u_char ctl[] = { /* CTL shift */ 400*41053Swilliam 0, 033 , '!' , 000 , '#' , '$' , '%' , 036 , /* scan 0- 7 */ 401*41053Swilliam '&' , '*' , '(' , ')' , 037 , '+' , 034 ,'\177', /* scan 8-15 */ 402*41053Swilliam 021 , 027 , 005 , 022 , 024 , 031 , 025 , 011 , /* scan 16-23 */ 403*41053Swilliam 017 , 020 , 033 , 035 , '\r' , CTL , 001 , 023 , /* scan 24-31 */ 404*41053Swilliam 004 , 006 , 007 , 010 , 012 , 013 , 014 , ';' , /* scan 32-39 */ 405*41053Swilliam '\'' , '`' , SHF , 034 , 032 , 030 , 003 , 026 , /* scan 40-47 */ 406*41053Swilliam 002 , 016 , 015 , '<' , '>' , '?' , SHF , '*', /* scan 48-55 */ 407*41053Swilliam ALT , ' ' , CPS|L, 0, 0, ' ' , 0, 0, /* scan 56-63 */ 408*41053Swilliam CPS|L, 0, 0, 0, 0, 0, 0, 0, /* scan 64-71 */ 409*41053Swilliam 0, 0, 0, 0, 0, 0, 0, 0, /* scan 72-79 */ 410*41053Swilliam 0, 0, 0, 0, 0, 0, 0, 0, /* scan 80-87 */ 411*41053Swilliam 0, 0, 033, '7' , '4' , '1' , 0, NUM|L, /* scan 88-95 */ 412*41053Swilliam '8' , '5' , '2' , 0, STP|L, '9' , '6' , '3' , /*scan 96-103*/ 413*41053Swilliam '.' , 0, '*' , '-' , '+' , 0, 0, 0, /*scan 104-111*/ 414*41053Swilliam 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, } ; 415*41053Swilliam 416*41053Swilliam #ifdef notdef 417*41053Swilliam struct key { 418*41053Swilliam u_short action; /* how this key functions */ 419*41053Swilliam char ascii[8]; /* ascii result character indexed by shifts */ 420*41053Swilliam }; 421*41053Swilliam #endif 422*41053Swilliam 423*41053Swilliam u_char shfts, ctls, alts, caps, num, stp; 424*41053Swilliam 425*41053Swilliam #define KBSTATP 0x64 /* kbd status port */ 426*41053Swilliam #define KBS_INP_BUF_FUL 0x02 /* kbd char ready */ 427*41053Swilliam #define KBDATAP 0x60 /* kbd data port */ 428*41053Swilliam #define KBSTATUSPORT 0x61 /* kbd status */ 429*41053Swilliam 430*41053Swilliam u_char odt; 431*41053Swilliam 432*41053Swilliam int sgetc(on) { 433*41053Swilliam u_char dt, brk; 434*41053Swilliam u_short act; 435*41053Swilliam 436*41053Swilliam loop: 437*41053Swilliam do { 438*41053Swilliam while (inb(0x64)&2) ; 439*41053Swilliam dt = inb(0x60); 440*41053Swilliam } while (dt == odt); 441*41053Swilliam odt = dt; 442*41053Swilliam if(dt == 0x54) _exit(); 443*41053Swilliam brk = dt & 0x80 ; dt = dt & 0x7f ; 444*41053Swilliam 445*41053Swilliam act = action[dt]; 446*41053Swilliam if (act&SHF) { 447*41053Swilliam if(brk) shfts = 0; else shfts = 1; 448*41053Swilliam } 449*41053Swilliam if (act&ALT) { 450*41053Swilliam if(brk) alts = 0; else alts = 1; 451*41053Swilliam } 452*41053Swilliam if (act&NUM) { 453*41053Swilliam if (act&L) { 454*41053Swilliam if(!brk) num ^= 1; 455*41053Swilliam } else if(brk) num = 0; else num = 1; 456*41053Swilliam } 457*41053Swilliam if (act&CTL) { 458*41053Swilliam if(brk) ctls = 0; else ctls = 1; 459*41053Swilliam } 460*41053Swilliam if (act&CPS) { 461*41053Swilliam if (act&L) { 462*41053Swilliam if(!brk) caps ^= 1; 463*41053Swilliam } else if(brk) caps = 0; else caps = 1; 464*41053Swilliam } 465*41053Swilliam if (act&STP) { 466*41053Swilliam if (act&L) { 467*41053Swilliam if(!brk) stp ^= 1; 468*41053Swilliam } else if(brk) stp = 0; else stp = 1; 469*41053Swilliam } 470*41053Swilliam if ((act&FUNC) && brk) { 471*41053Swilliam unsigned key = unshift[dt] ; 472*41053Swilliam if(__debug & (1<<key)) 473*41053Swilliam __debug &= ~(1<<key) ; 474*41053Swilliam else 475*41053Swilliam __debug |= (1<<key) ; 476*41053Swilliam } 477*41053Swilliam if(stp) goto loop; 478*41053Swilliam if ((act&ASCII) && !brk) { 479*41053Swilliam u_char chr; 480*41053Swilliam 481*41053Swilliam if (shfts){ 482*41053Swilliam chr = shift[dt] ; } else { 483*41053Swilliam if (ctls) { 484*41053Swilliam chr = ctl[dt] ; } else { 485*41053Swilliam chr = unshift[dt] ; } } 486*41053Swilliam if (caps && (chr >= 'a' && chr <= 'z')) { 487*41053Swilliam chr -= 'a' - 'A' ; 488*41053Swilliam } 489*41053Swilliam return(chr); 490*41053Swilliam } 491*41053Swilliam if(on) return (0x100); else goto loop; 492*41053Swilliam } 493*41053Swilliam 494*41053Swilliam pg(p,q,r,s,t,u,v,w,x,y,z) char *p; { 495*41053Swilliam printf(p,q,r,s,t,u,v,w,x,y,z); 496*41053Swilliam printf("\n"); 497*41053Swilliam return(getchar()); 498*41053Swilliam } 499*41053Swilliam 500*41053Swilliam /* special characters */ 501*41053Swilliam #define bs 8 502*41053Swilliam #define lf 10 503*41053Swilliam #define cr 13 504*41053Swilliam #define cntlc 3 505*41053Swilliam #define del 0177 506*41053Swilliam #define cntld 4 507*41053Swilliam 508*41053Swilliam getchar() 509*41053Swilliam { 510*41053Swilliam register char thechar; 511*41053Swilliam register delay; 512*41053Swilliam int x; 513*41053Swilliam 514*41053Swilliam consoftc.cs_flags |= CSF_POLLING; 515*41053Swilliam x=splhigh(); 516*41053Swilliam sput('>',0xe); 517*41053Swilliam while (1) { 518*41053Swilliam thechar = (char) sgetc(0); 519*41053Swilliam consoftc.cs_flags &= ~CSF_POLLING; 520*41053Swilliam splx(x); 521*41053Swilliam switch (thechar) { 522*41053Swilliam default: if (thechar >= ' ') 523*41053Swilliam sput(thechar,0xe); 524*41053Swilliam return(thechar); 525*41053Swilliam case cr: 526*41053Swilliam case lf: sput(cr,0xe); 527*41053Swilliam sput(lf,0xe); 528*41053Swilliam return(lf); 529*41053Swilliam case bs: 530*41053Swilliam case del: 531*41053Swilliam sput(bs,0xe); 532*41053Swilliam sput(' ',0xe); 533*41053Swilliam sput(bs,0xe); 534*41053Swilliam return(thechar); 535*41053Swilliam case cntlc: 536*41053Swilliam sput('^',0xe) ; sput('C',0xe) ; sput('\r',0xe) ; sput('\n',0xe) ; 537*41053Swilliam _exit(-2) ; 538*41053Swilliam case cntld: 539*41053Swilliam sput('^',0xe) ; sput('D',0xe) ; sput('\r',0xe) ; sput('\n',0xe) ; 540*41053Swilliam return(0); 541*41053Swilliam } 542*41053Swilliam } 543*41053Swilliam } 544