141053Swilliam /*- 241053Swilliam * Copyright (c) 1990 The Regents of the University of California. 341053Swilliam * All rights reserved. 441053Swilliam * 541053Swilliam * This code is derived from software contributed to Berkeley by 641053Swilliam * William Jolitz. 741053Swilliam * 843589Sdonahn * Added support for ibmpc term type and improved keyboard support. -Don Ahn 943589Sdonahn * 1041053Swilliam * %sccs.include.386.c% 1141053Swilliam * 12*45535Sbill * @(#)pccons.c 5.3 (Berkeley) 11/08/90 1341053Swilliam */ 1441053Swilliam 1541053Swilliam /* 1641053Swilliam * code to work keyboard & display for console 1741053Swilliam */ 1841053Swilliam #include "param.h" 1941053Swilliam #include "conf.h" 2041053Swilliam #include "dir.h" 2141053Swilliam #include "ioctl.h" 2241053Swilliam #include "user.h" 2341053Swilliam #include "proc.h" 2441053Swilliam #include "tty.h" 2541053Swilliam #include "uio.h" 26*45535Sbill #include "machine/isa/device.h" 2741053Swilliam #include "callout.h" 2841053Swilliam #include "systm.h" 2941053Swilliam #include "kernel.h" 3041053Swilliam #include "syslog.h" 3141053Swilliam #include "icu.h" 3241053Swilliam 3341053Swilliam struct tty cons; 3441053Swilliam 3541053Swilliam struct consoftc { 3641053Swilliam char cs_flags; 3741053Swilliam #define CSF_ACTIVE 0x1 /* timeout active */ 3841053Swilliam #define CSF_POLLING 0x2 /* polling for input */ 3941053Swilliam char cs_lastc; /* last char sent */ 4041053Swilliam int cs_timo; /* timeouts since interrupt */ 4141053Swilliam u_long cs_wedgecnt; /* times restarted */ 4241053Swilliam } consoftc; 4341053Swilliam 4443589Sdonahn int cnprobe(), cnattach(); 4543589Sdonahn 46*45535Sbill struct isa_driver cndriver = { 4743589Sdonahn cnprobe, cnattach, "cn", 4843589Sdonahn }; 4943589Sdonahn 50*45535Sbill #define COL 80 51*45535Sbill #define ROW 25 52*45535Sbill #define CHR 2 53*45535Sbill #define MONO_BASE 0x3B4 54*45535Sbill #define MONO_BUF 0xB0000 55*45535Sbill #define CGA_BASE 0x3D4 56*45535Sbill #define CGA_BUF 0xB8000 57*45535Sbill #define IOPHYSMEM 0xA0000 58*45535Sbill 59*45535Sbill u_char color = 0xe ; 60*45535Sbill static unsigned int addr_6845 = MONO_BASE; 61*45535Sbill u_short *Crtat = (u_short *)MONO_BUF; 62*45535Sbill 6341053Swilliam /* 6441053Swilliam * We check the console periodically to make sure 6541053Swilliam * that it hasn't wedged. Unfortunately, if an XOFF 6641053Swilliam * is typed on the console, that can't be distinguished 6741053Swilliam * from more catastrophic failure. 6841053Swilliam */ 6941053Swilliam #define CN_TIMERVAL (hz) /* frequency at which to check cons */ 7041053Swilliam #define CN_TIMO (2*60) /* intervals to allow for output char */ 7141053Swilliam 7241053Swilliam int cnstart(); 7341053Swilliam int ttrstrt(); 7441053Swilliam char partab[]; 7541053Swilliam 7641053Swilliam /* 7741053Swilliam * Wait for CP to accept last CP command sent 7841053Swilliam * before setting up next command. 7941053Swilliam */ 8041053Swilliam #define waitforlast(timo) { \ 8141053Swilliam if (cnlast) { \ 8241053Swilliam (timo) = 10000; \ 8341053Swilliam do \ 8441053Swilliam uncache((char *)&cnlast->cp_unit); \ 8541053Swilliam while ((cnlast->cp_unit&CPTAKE) == 0 && --(timo)); \ 8641053Swilliam } \ 8741053Swilliam } 8841053Swilliam 8941053Swilliam u_char inb(); 9041053Swilliam 9143589Sdonahn cnprobe(dev) 92*45535Sbill struct isa_device *dev; 9343589Sdonahn { 9443589Sdonahn u_char c; 9543589Sdonahn int again = 0; 9643589Sdonahn 9743589Sdonahn /* Enable interrupts and keyboard controller */ 9843589Sdonahn while (inb(0x64)&2); outb(0x64,0x60); 9943589Sdonahn while (inb(0x64)&2); outb(0x60,0x4D); 10043589Sdonahn 10143589Sdonahn /* Start keyboard stuff RESET */ 10243589Sdonahn while (inb(0x64)&2); /* wait input ready */ 10343589Sdonahn outb(0x60,0xFF); /* RESET */ 10443589Sdonahn while((c=inb(0x60))!=0xFA) { 10543589Sdonahn if ((c == 0xFE) || (c == 0xFF)) { 10643589Sdonahn if(!again)printf("KEYBOARD disconnected: RECONNECT \n"); 10743589Sdonahn while (inb(0x64)&2); /* wait input ready */ 10843589Sdonahn outb(0x60,0xFF); /* RESET */ 10943589Sdonahn again = 1; 11043589Sdonahn } 11143589Sdonahn } 11243589Sdonahn /* pick up keyboard reset return code */ 113*45535Sbill while((c=inb(0x60))!=0xAA)nulldev(); 11443589Sdonahn return 1; 11543589Sdonahn } 11643589Sdonahn 11743589Sdonahn cnattach(dev) 118*45535Sbill struct isa_device *dev; 11943589Sdonahn { 120*45535Sbill u_short *cp = Crtat + (CGA_BUF-MONO_BUF)/CHR; 121*45535Sbill u_short was; 122*45535Sbill 123*45535Sbill /* Crtat initialized to point to MONO buffer */ 124*45535Sbill /* if not present change to CGA_BUF offset */ 125*45535Sbill /* ONLY ADD the difference since locore.s adds */ 126*45535Sbill /* in the remapped offset at the right time */ 127*45535Sbill 128*45535Sbill was = *Crtat; 129*45535Sbill *Crtat = (u_short) 0xA55A; 130*45535Sbill if (*Crtat != 0xA55A) 131*45535Sbill printf("<mono>"); 132*45535Sbill else printf("<color>"); 133*45535Sbill *Crtat = was; 13443589Sdonahn } 13543589Sdonahn 13641053Swilliam /*ARGSUSED*/ 13741053Swilliam cnopen(dev, flag) 13841053Swilliam dev_t dev; 13941053Swilliam { 14041053Swilliam register struct tty *tp; 14141053Swilliam int unit = minor(dev); 14241053Swilliam 14341053Swilliam tp = &cons; 14441053Swilliam if (tp->t_state&TS_XCLUDE && u.u_uid != 0) 14541053Swilliam return (EBUSY); 14641053Swilliam tp->t_oproc = cnstart; 14741053Swilliam if ((tp->t_state&TS_ISOPEN) == 0) { 14841053Swilliam ttychars(tp); 14941053Swilliam tp->t_state = TS_ISOPEN|TS_CARR_ON; 15041053Swilliam tp->t_flags = EVENP|ECHO|XTABS|CRMOD; 15141053Swilliam splnone(); 15241053Swilliam } 15341053Swilliam return ((*linesw[tp->t_line].l_open)(dev, tp)); 15441053Swilliam } 15541053Swilliam 15641053Swilliam 15741053Swilliam cnclose(dev) 15841053Swilliam dev_t dev; 15941053Swilliam { 16041053Swilliam (*linesw[cons.t_line].l_close)(&cons); 16141053Swilliam ttyclose(&cons); 16241053Swilliam } 16341053Swilliam 16441053Swilliam /*ARGSUSED*/ 16541053Swilliam cnread(dev, uio) 16641053Swilliam dev_t dev; 16741053Swilliam struct uio *uio; 16841053Swilliam { 16941053Swilliam return ((*linesw[cons.t_line].l_read)(&cons, uio)); 17041053Swilliam } 17141053Swilliam 17241053Swilliam /*ARGSUSED*/ 17341053Swilliam cnwrite(dev, uio) 17441053Swilliam dev_t dev; 17541053Swilliam struct uio *uio; 17641053Swilliam { 17741053Swilliam return ((*linesw[cons.t_line].l_write)(&cons, uio)); 17841053Swilliam } 17941053Swilliam 18041053Swilliam /* 18141053Swilliam * Got a console receive interrupt - 18241053Swilliam * the console processor wants to give us a character. 18341053Swilliam * Catch the character, and see who it goes to. 18441053Swilliam */ 185*45535Sbill cnrint(dev, irq, cpl) 18641053Swilliam dev_t dev; 18741053Swilliam { 18841053Swilliam int c; 18941053Swilliam 19041053Swilliam c = sgetc(1); 191*45535Sbill if (c&0x100) return; 19241053Swilliam if (consoftc.cs_flags&CSF_POLLING) 19341053Swilliam return; 19441053Swilliam #ifdef KDB 19541053Swilliam if (kdbrintr(c, &cons)) 19641053Swilliam return; 19741053Swilliam #endif 19841053Swilliam (*linesw[cons.t_line].l_rint)(c&0xff, &cons); 19941053Swilliam } 20041053Swilliam 20141053Swilliam cnioctl(dev, cmd, addr, flag) 20241053Swilliam dev_t dev; 20341053Swilliam caddr_t addr; 20441053Swilliam { 20541053Swilliam register struct tty *tp = &cons; 20641053Swilliam register error; 20741053Swilliam 20841053Swilliam error = (*linesw[tp->t_line].l_ioctl)(tp, cmd, addr); 20941053Swilliam if (error >= 0) 21041053Swilliam return error; 21141053Swilliam if ((error = ttioctl(tp, cmd, addr, flag)) < 0) 21241053Swilliam error = ENOTTY; 21341053Swilliam else if (cmd == TIOCSETP || cmd == TIOCSETN) 21441053Swilliam cnparams(tp); 21541053Swilliam return (error); 21641053Swilliam } 21741053Swilliam 21841053Swilliam int consintr = 1; 21941053Swilliam /* 22041053Swilliam * Got a console transmission interrupt - 22141053Swilliam * the console processor wants another character. 22241053Swilliam */ 22341053Swilliam cnxint(dev) 22441053Swilliam dev_t dev; 22541053Swilliam { 22641053Swilliam register struct tty *tp; 22741053Swilliam register int unit; 22841053Swilliam 22941053Swilliam if (!consintr) 23041053Swilliam return; 23141053Swilliam cons.t_state &= ~TS_BUSY; 23241053Swilliam consoftc.cs_timo = 0; 23341053Swilliam if (cons.t_line) 23441053Swilliam (*linesw[cons.t_line].l_start)(&cons); 23541053Swilliam else 23641053Swilliam cnstart(&cons); 23741053Swilliam } 23841053Swilliam 23941053Swilliam cnstart(tp) 24041053Swilliam register struct tty *tp; 24141053Swilliam { 24241053Swilliam register c, s; 24341053Swilliam 24441053Swilliam s = spltty(); 24541053Swilliam if (tp->t_state & (TS_TIMEOUT|TS_BUSY|TS_TTSTOP)) 24641053Swilliam goto out; 24741053Swilliam if (tp->t_outq.c_cc <= TTLOWAT(tp)) { 24841053Swilliam if (tp->t_state&TS_ASLEEP) { 24941053Swilliam tp->t_state &= ~TS_ASLEEP; 25041053Swilliam wakeup((caddr_t)&tp->t_outq); 25141053Swilliam } 25241053Swilliam if (tp->t_wsel) { 25341053Swilliam selwakeup(tp->t_wsel, tp->t_state & TS_WCOLL); 25441053Swilliam tp->t_wsel = 0; 25541053Swilliam tp->t_state &= ~TS_WCOLL; 25641053Swilliam } 25741053Swilliam } 25841053Swilliam while (tp->t_outq.c_cc != 0) { 25941053Swilliam c = getc(&tp->t_outq) & 0xff; 26041053Swilliam if ((tp->t_flags & (RAW|LITOUT)) == 0) { 26141053Swilliam if (c > 0177) 26241053Swilliam { 26341053Swilliam timeout(ttrstrt, (caddr_t)tp, (c&0177)); 26441053Swilliam tp->t_state |= TS_TIMEOUT; 26541053Swilliam break; 26641053Swilliam } 26741053Swilliam c &= 0177; 26841053Swilliam } 26943589Sdonahn splx(s); 27043589Sdonahn sput(c,0x7); 27143589Sdonahn s = spltty(); 27241053Swilliam } 27341053Swilliam out: 27441053Swilliam splx(s); 27541053Swilliam } 27641053Swilliam 27741053Swilliam cnputc(c) 27841053Swilliam char c; 27941053Swilliam { 28041053Swilliam if (c == '\n') 28143589Sdonahn sput('\r',0x3); 28243589Sdonahn sput(c, 0x3); 28341053Swilliam } 28441053Swilliam 28541053Swilliam /* 28641053Swilliam * Print a character on console. 28741053Swilliam */ 28841053Swilliam cnputchar(c, tp) 28941053Swilliam char c; 29041053Swilliam register struct tty *tp; 29141053Swilliam { 29243589Sdonahn sput(c,0x2); 29341053Swilliam if (c=='\n') getchar(); 29441053Swilliam } 29541053Swilliam 29641053Swilliam 29741053Swilliam cngetc() 29841053Swilliam { 29941053Swilliam register int c, s; 30041053Swilliam 30141053Swilliam s = spltty(); /* block cnrint while we poll */ 30243589Sdonahn c = sgetc(0); 30343589Sdonahn if (c == '\r') c = '\n'; 30441053Swilliam splx(s); 30541053Swilliam return (c); 30641053Swilliam } 30741053Swilliam 30841053Swilliam cngetchar(tp) 30941053Swilliam register struct tty *tp; 31041053Swilliam { 31141053Swilliam int c; 31241053Swilliam 31341053Swilliam c = sgetc(0); 31441053Swilliam return (c&0xff); 31541053Swilliam } 31641053Swilliam 31741053Swilliam /* 31841053Swilliam * Set line parameters 31941053Swilliam */ 32041053Swilliam cnparams(tp) 32141053Swilliam register struct tty *tp; 32241053Swilliam { 32341053Swilliam } 32441053Swilliam 32541053Swilliam #ifdef KDB 32641053Swilliam /* 32741053Swilliam * Turn input polling on/off (used by debugger). 32841053Swilliam */ 32941053Swilliam cnpoll(onoff) 33041053Swilliam int onoff; 33141053Swilliam { 33241053Swilliam } 33341053Swilliam #endif 33441053Swilliam 33543589Sdonahn extern int hz; 33643589Sdonahn 33743589Sdonahn sysbeepstop() 33843589Sdonahn { 33943589Sdonahn /* disable counter 2 */ 34043589Sdonahn outb(0x61,inb(0x61)&0xFC); 34143589Sdonahn } 34243589Sdonahn 34343589Sdonahn sysbeep() 34443589Sdonahn { 34543589Sdonahn /* enable counter 2 */ 34643589Sdonahn outb(0x61,inb(0x61)|3); 34743589Sdonahn /* set command for counter 2, 2 byte write */ 34843589Sdonahn outb(0x43,0xB6); 34943589Sdonahn /* send 0x637 for 750 HZ */ 35043589Sdonahn outb(0x42,0x37); 35143589Sdonahn outb(0x42,0x06); 35243589Sdonahn timeout(sysbeepstop,0,hz/4); 35343589Sdonahn } 35443589Sdonahn 355*45535Sbill /* cursor() sets an offset (0-1999) into the 80x25 text area */ 35641053Swilliam 357*45535Sbill static u_short *crtat = 0; 358*45535Sbill char bg_at = 0x0f; 359*45535Sbill char so_at = 0x70; 36041053Swilliam 361*45535Sbill cursor() 362*45535Sbill { int pos = crtat - Crtat; 36341053Swilliam 36443589Sdonahn outb(addr_6845,14); 36543589Sdonahn outb(addr_6845+1,pos >> 8); 36643589Sdonahn outb(addr_6845,15); 36743589Sdonahn outb(addr_6845+1,pos&0xff); 36843589Sdonahn } 36943589Sdonahn 37043589Sdonahn /* sput has support for emulation of the 'ibmpc' termcap entry. */ 37143589Sdonahn /* This is a bare-bones implementation of a bare-bones entry */ 37243589Sdonahn /* One modification: Change li#24 to li#25 to reflect 25 lines */ 37343589Sdonahn 37443589Sdonahn sput(c, ca) 37543589Sdonahn u_char c, ca; 37643589Sdonahn { 37743589Sdonahn 37843589Sdonahn static int esc,ebrac,eparm,cx,cy,row,so; 37943589Sdonahn 38041053Swilliam if (crtat == 0) { 381*45535Sbill u_short *cp = Crtat + (CGA_BUF-MONO_BUF)/CHR, was; 382*45535Sbill unsigned cursorat; 38343589Sdonahn 38443589Sdonahn /* Crtat initialized to point to MONO buffer */ 38543589Sdonahn /* if not present change to CGA_BUF offset */ 38643589Sdonahn /* ONLY ADD the difference since locore.s adds */ 38743589Sdonahn /* in the remapped offset at the right time */ 38843589Sdonahn 389*45535Sbill was = *cp; 390*45535Sbill *cp = (u_short) 0xA55A; 391*45535Sbill if (*cp != 0xA55A) { 392*45535Sbill addr_6845 = MONO_BASE; 393*45535Sbill } else { 394*45535Sbill *cp = was; 395*45535Sbill addr_6845 = CGA_BASE; 39643589Sdonahn Crtat = Crtat + (CGA_BUF-MONO_BUF)/CHR; 397*45535Sbill } 398*45535Sbill /* Extract cursor location */ 399*45535Sbill outb(addr_6845,14); 400*45535Sbill cursorat = inb(addr_6845+1)<<8 ; 401*45535Sbill outb(addr_6845,15); 402*45535Sbill cursorat |= inb(addr_6845+1); 403*45535Sbill 404*45535Sbill crtat = Crtat + cursorat; 405*45535Sbill fillw((bg_at<<8)|' ', crtat, COL*ROW-cursorat); 40641053Swilliam } 40741053Swilliam switch(c) { 40843589Sdonahn case 0x1B: 40943589Sdonahn esc = 1; ebrac = 0; eparm = 0; 41043589Sdonahn break; 41141053Swilliam 41241053Swilliam case '\t': 41341053Swilliam do { 41441053Swilliam *crtat++ = (ca<<8)| ' '; row++ ; 41541053Swilliam } while (row %8); 41641053Swilliam break; 41741053Swilliam 41841053Swilliam case '\010': 41941053Swilliam crtat--; row--; 42043589Sdonahn if (row < 0) row += COL; /* non-destructive backspace */ 42141053Swilliam break; 42241053Swilliam 42341053Swilliam case '\r': 42443589Sdonahn crtat -= row ; row = 0; 42541053Swilliam break; 42641053Swilliam 42741053Swilliam case '\n': 42841053Swilliam crtat += COL ; 42941053Swilliam break; 43041053Swilliam 43141053Swilliam default: 43243589Sdonahn if (esc) { 43343589Sdonahn if (ebrac) { 43443589Sdonahn switch(c) { 43543589Sdonahn case 'm': /* no support for standout */ 43643589Sdonahn if (!cx) so = 0; 43743589Sdonahn else so = 1; 43843589Sdonahn esc = 0; ebrac = 0; eparm = 0; 43943589Sdonahn break; 44043589Sdonahn case 'A': /* back one row */ 44143589Sdonahn crtat -= COL; 44243589Sdonahn esc = 0; ebrac = 0; eparm = 0; 44343589Sdonahn break; 44443589Sdonahn case 'B': /* down one row */ 44543589Sdonahn crtat += COL; 44643589Sdonahn esc = 0; ebrac = 0; eparm = 0; 44743589Sdonahn break; 44843589Sdonahn case 'C': /* right cursor */ 44943589Sdonahn crtat++; row++; 45043589Sdonahn esc = 0; ebrac = 0; eparm = 0; 45143589Sdonahn break; 45243589Sdonahn case 'J': /* Clear to end of display */ 453*45535Sbill fillw((bg_at<<8)+' ', crtat, 454*45535Sbill Crtat+COL*ROW-crtat); 45543589Sdonahn esc = 0; ebrac = 0; eparm = 0; 45643589Sdonahn break; 45743589Sdonahn case 'K': /* Clear to EOL */ 458*45535Sbill fillw((bg_at<<8)+' ', crtat, COL-row); 45943589Sdonahn esc = 0; ebrac = 0; eparm = 0; 46043589Sdonahn break; 46143589Sdonahn case 'H': /* Cursor move */ 46243589Sdonahn if ((!cx)||(!cy)) { 46343589Sdonahn crtat = Crtat; 46443589Sdonahn row = 0; 46543589Sdonahn } else { 46643589Sdonahn crtat = Crtat+(cx-1)*COL+cy-1; 46743589Sdonahn row = cy-1; 46843589Sdonahn } 46943589Sdonahn esc = 0; ebrac = 0; eparm = 0; 47043589Sdonahn break; 47143589Sdonahn case ';': /* Switch params in cursor def */ 47243589Sdonahn eparm = 1; 47343589Sdonahn return; 47443589Sdonahn default: /* Only numbers valid here */ 47543589Sdonahn if ((c >= '0')&&(c <= '9')) { 47643589Sdonahn if (eparm) { 47743589Sdonahn cy *= 10; 47843589Sdonahn cy += c - '0'; 47943589Sdonahn } else { 48043589Sdonahn cx *= 10; 48143589Sdonahn cx += c - '0'; 48243589Sdonahn } 48343589Sdonahn } else { 48443589Sdonahn esc = 0; ebrac = 0; eparm = 0; 48543589Sdonahn } 48643589Sdonahn return; 48743589Sdonahn } 48843589Sdonahn break; 48943589Sdonahn } else if (c == 'c') { /* Clear screen & home */ 490*45535Sbill fillw((bg_at<<8)+' ', Crtat,COL*ROW); 49143589Sdonahn crtat = Crtat; row = 0; 49243589Sdonahn esc = 0; ebrac = 0; eparm = 0; 493*45535Sbill } else if (c == '[') { /* Start ESC [ sequence */ 49443589Sdonahn ebrac = 1; cx = 0; cy = 0; eparm = 0; 495*45535Sbill } else { /* Invalid, clear state */ 49643589Sdonahn esc = 0; ebrac = 0; eparm = 0; 49743589Sdonahn } 49843589Sdonahn } else { 49943589Sdonahn if (c == 7) { 50043589Sdonahn sysbeep(); 50143589Sdonahn } 50243589Sdonahn /* Print only printables */ 503*45535Sbill else /*if (c >= ' ') */ { 504*45535Sbill while(inb(0x3da)&1)nulldev(); 50543589Sdonahn if (so) { 506*45535Sbill *crtat++ = (so_at<<8)| c; row++ ; 50743589Sdonahn } else { 50843589Sdonahn *crtat++ = (ca<<8)| c; row++ ; 50943589Sdonahn } 51043589Sdonahn if (row >= COL) row = 0; 51143589Sdonahn break ; 51243589Sdonahn } 51341053Swilliam } 51441053Swilliam } 51543589Sdonahn if (crtat >= Crtat+COL*(ROW)) { /* scroll check */ 51643589Sdonahn bcopy(Crtat+COL,Crtat,COL*(ROW-1)*CHR); 517*45535Sbill fillw ((bg_at<<8)+' ', Crtat+COL*(ROW-1),COL) ; 51843589Sdonahn crtat -= COL ; 51943589Sdonahn } 52041053Swilliam } 52143589Sdonahn 52243589Sdonahn 52341053Swilliam #define L 0x0001 /* locking function */ 52441053Swilliam #define SHF 0x0002 /* keyboard shift */ 52541053Swilliam #define ALT 0x0004 /* alternate shift -- alternate chars */ 52641053Swilliam #define NUM 0x0008 /* numeric shift cursors vs. numeric */ 52741053Swilliam #define CTL 0x0010 /* control shift -- allows ctl function */ 52841053Swilliam #define CPS 0x0020 /* caps shift -- swaps case of letter */ 52941053Swilliam #define ASCII 0x0040 /* ascii code for this key */ 53041053Swilliam #define STP 0x0080 /* stop output */ 53141053Swilliam #define FUNC 0x0100 /* function key */ 53243589Sdonahn #define SCROLL 0x0200 /* scroll lock key */ 53341053Swilliam 534*45535Sbill unsigned __debug = 0; 53541053Swilliam u_short action[] = { 53641053Swilliam 0, ASCII, ASCII, ASCII, ASCII, ASCII, ASCII, ASCII, /* scan 0- 7 */ 53741053Swilliam ASCII, ASCII, ASCII, ASCII, ASCII, ASCII, ASCII, ASCII, /* scan 8-15 */ 53841053Swilliam ASCII, ASCII, ASCII, ASCII, ASCII, ASCII, ASCII, ASCII, /* scan 16-23 */ 53941053Swilliam ASCII, ASCII, ASCII, ASCII, ASCII, CTL, ASCII, ASCII, /* scan 24-31 */ 54041053Swilliam ASCII, ASCII, ASCII, ASCII, ASCII, ASCII, ASCII, ASCII, /* scan 32-39 */ 54141053Swilliam ASCII, ASCII, SHF , ASCII, ASCII, ASCII, ASCII, ASCII, /* scan 40-47 */ 54241053Swilliam ASCII, ASCII, ASCII, ASCII, ASCII, ASCII, SHF, ASCII, /* scan 48-55 */ 54343589Sdonahn ALT, ASCII, CPS , FUNC , FUNC , FUNC , FUNC , FUNC , /* scan 56-63 */ 54443589Sdonahn FUNC , FUNC , FUNC , FUNC , FUNC , NUM, STP, ASCII, /* scan 64-71 */ 54541053Swilliam ASCII, ASCII, ASCII, ASCII, ASCII, ASCII, ASCII, ASCII, /* scan 72-79 */ 54641053Swilliam ASCII, ASCII, ASCII, ASCII, 0, 0, 0, 0, /* scan 80-87 */ 54741053Swilliam 0,0,0,0,0,0,0,0, 54841053Swilliam 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 54941053Swilliam 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, } ; 55041053Swilliam 55141053Swilliam u_char unshift[] = { /* no shift */ 55241053Swilliam 0, 033 , '1' , '2' , '3' , '4' , '5' , '6' , /* scan 0- 7 */ 55341053Swilliam '7' , '8' , '9' , '0' , '-' , '=' , 0177 ,'\t' , /* scan 8-15 */ 55441053Swilliam 55541053Swilliam 'q' , 'w' , 'e' , 'r' , 't' , 'y' , 'u' , 'i' , /* scan 16-23 */ 55641053Swilliam 'o' , 'p' , '[' , ']' , '\r' , CTL , 'a' , 's' , /* scan 24-31 */ 55741053Swilliam 55841053Swilliam 'd' , 'f' , 'g' , 'h' , 'j' , 'k' , 'l' , ';' , /* scan 32-39 */ 55941053Swilliam '\'' , '`' , SHF , '\\' , 'z' , 'x' , 'c' , 'v' , /* scan 40-47 */ 56041053Swilliam 56141053Swilliam 'b' , 'n' , 'm' , ',' , '.' , '/' , SHF , '*', /* scan 48-55 */ 56243589Sdonahn ALT , ' ' , CPS, 1, 2, 3 , 4, 5, /* scan 56-63 */ 56341053Swilliam 56443589Sdonahn 6, 7, 8, 9, 10, NUM, STP, '7', /* scan 64-71 */ 56541053Swilliam '8', '9', '-', '4', '5', '6', '+', '1', /* scan 72-79 */ 56641053Swilliam 56741053Swilliam '2', '3', '0', '.', 0, 0, 0, 0, /* scan 80-87 */ 56841053Swilliam 0,0,0,0,0,0,0,0, 56941053Swilliam 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 57041053Swilliam 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, } ; 57141053Swilliam 57241053Swilliam u_char shift[] = { /* shift shift */ 57341053Swilliam 0, 033 , '!' , '@' , '#' , '$' , '%' , '^' , /* scan 0- 7 */ 57441053Swilliam '&' , '*' , '(' , ')' , '_' , '+' , 0177 ,'\t' , /* scan 8-15 */ 57541053Swilliam 'Q' , 'W' , 'E' , 'R' , 'T' , 'Y' , 'U' , 'I' , /* scan 16-23 */ 57641053Swilliam 'O' , 'P' , '{' , '}' , '\r' , CTL , 'A' , 'S' , /* scan 24-31 */ 57741053Swilliam 'D' , 'F' , 'G' , 'H' , 'J' , 'K' , 'L' , ':' , /* scan 32-39 */ 57841053Swilliam '"' , '~' , SHF , '|' , 'Z' , 'X' , 'C' , 'V' , /* scan 40-47 */ 57941053Swilliam 'B' , 'N' , 'M' , '<' , '>' , '?' , SHF , '*', /* scan 48-55 */ 58043589Sdonahn ALT , ' ' , CPS, 0, 0, ' ' , 0, 0, /* scan 56-63 */ 58143589Sdonahn 0, 0, 0, 0, 0, NUM, STP, '7', /* scan 64-71 */ 58241053Swilliam '8', '9', '-', '4', '5', '6', '+', '1', /* scan 72-79 */ 58341053Swilliam '2', '3', '0', '.', 0, 0, 0, 0, /* scan 80-87 */ 58441053Swilliam 0,0,0,0,0,0,0,0, 58541053Swilliam 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 58641053Swilliam 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, } ; 58741053Swilliam 58841053Swilliam u_char ctl[] = { /* CTL shift */ 58941053Swilliam 0, 033 , '!' , 000 , '#' , '$' , '%' , 036 , /* scan 0- 7 */ 59041053Swilliam '&' , '*' , '(' , ')' , 037 , '+' , 034 ,'\177', /* scan 8-15 */ 59141053Swilliam 021 , 027 , 005 , 022 , 024 , 031 , 025 , 011 , /* scan 16-23 */ 59241053Swilliam 017 , 020 , 033 , 035 , '\r' , CTL , 001 , 023 , /* scan 24-31 */ 59341053Swilliam 004 , 006 , 007 , 010 , 012 , 013 , 014 , ';' , /* scan 32-39 */ 59441053Swilliam '\'' , '`' , SHF , 034 , 032 , 030 , 003 , 026 , /* scan 40-47 */ 59541053Swilliam 002 , 016 , 015 , '<' , '>' , '?' , SHF , '*', /* scan 48-55 */ 59643589Sdonahn ALT , ' ' , CPS, 0, 0, ' ' , 0, 0, /* scan 56-63 */ 59743589Sdonahn CPS, 0, 0, 0, 0, 0, 0, 0, /* scan 64-71 */ 59841053Swilliam 0, 0, 0, 0, 0, 0, 0, 0, /* scan 72-79 */ 59941053Swilliam 0, 0, 0, 0, 0, 0, 0, 0, /* scan 80-87 */ 60043589Sdonahn 0, 0, 033, '7' , '4' , '1' , 0, NUM, /* scan 88-95 */ 60143589Sdonahn '8' , '5' , '2' , 0, STP, '9' , '6' , '3' , /*scan 96-103*/ 60241053Swilliam '.' , 0, '*' , '-' , '+' , 0, 0, 0, /*scan 104-111*/ 60341053Swilliam 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, } ; 60441053Swilliam 60541053Swilliam #ifdef notdef 60641053Swilliam struct key { 60741053Swilliam u_short action; /* how this key functions */ 60841053Swilliam char ascii[8]; /* ascii result character indexed by shifts */ 60941053Swilliam }; 61041053Swilliam #endif 61141053Swilliam 61243589Sdonahn u_char shfts, ctls, alts, caps, num, stp, scroll; 61341053Swilliam 61443589Sdonahn #define KBSTAT 0x64 /* kbd status port */ 61543589Sdonahn #define KBS_INP_BUF_FUL 0x02 /* kbd char ready */ 61643589Sdonahn #define KBDATA 0x60 /* kbd data port */ 61741053Swilliam #define KBSTATUSPORT 0x61 /* kbd status */ 61841053Swilliam 61943589Sdonahn update_led() 62043589Sdonahn { 62143589Sdonahn while (inb(0x64)&2); /* wait input ready */ 62243589Sdonahn outb(0x60,0xED); /* LED Command */ 62343589Sdonahn while (inb(0x64)&2); /* wait input ready */ 62443589Sdonahn outb(0x60,scroll | 2*num | 4*caps); 62543589Sdonahn } 62641053Swilliam 627*45535Sbill reset_cpu() { 628*45535Sbill while(1) { 629*45535Sbill while (inb(0x64)&2); /* wait input ready */ 630*45535Sbill outb(0x64,0xFE); /* Reset Command */ 631*45535Sbill DELAY(4000000); 632*45535Sbill while (inb(0x64)&2); /* wait input ready */ 633*45535Sbill outb(0x64,0xFF); /* Keyboard Reset Command */ 634*45535Sbill } 635*45535Sbill /* NOTREACHED */ 636*45535Sbill } 637*45535Sbill 63843589Sdonahn /* 63943589Sdonahn sgetc(noblock) : get a character from the keyboard. If noblock = 0 wait until 64043589Sdonahn a key is gotten. Otherwise return a 0x100 (256). 64143589Sdonahn */ 64243589Sdonahn int sgetc(noblock) 64343589Sdonahn { 64443589Sdonahn u_char dt; unsigned key; 64541053Swilliam loop: 64643589Sdonahn /* First see if there is something in the keyboard port */ 64743589Sdonahn if (inb(KBSTAT)&1) dt = inb(KBDATA); 64843589Sdonahn else { if (noblock) return (0x100); else goto loop; } 64941053Swilliam 65043589Sdonahn /* Check for cntl-alt-del */ 65143589Sdonahn if ((dt == 83)&&ctls&&alts) _exit(); 65241053Swilliam 65343589Sdonahn /* Check for make/break */ 65443589Sdonahn if (dt & 0x80) { 65543589Sdonahn /* break */ 65643589Sdonahn dt = dt & 0x7f ; 65743589Sdonahn switch (action[dt]) { 65843589Sdonahn case SHF: shfts = 0; break; 65943589Sdonahn case ALT: alts = 0; break; 66043589Sdonahn case CTL: ctls = 0; break; 66143589Sdonahn case FUNC: 66243589Sdonahn /* Toggle debug flags */ 66343589Sdonahn key = unshift[dt]; 66443589Sdonahn if(__debug & (1<<key)) __debug &= ~(1<<key) ; 66543589Sdonahn else __debug |= (1<<key) ; 66643589Sdonahn break; 66741053Swilliam } 66843589Sdonahn } else { 66943589Sdonahn /* make */ 67043589Sdonahn dt = dt & 0x7f ; 67143589Sdonahn switch (action[dt]) { 67243589Sdonahn /* LOCKING KEYS */ 67343589Sdonahn case NUM: num ^= 1; update_led(); break; 67443589Sdonahn case CPS: caps ^= 1; update_led(); break; 67543589Sdonahn case SCROLL: scroll ^= 1; update_led(); break; 67643589Sdonahn case STP: stp ^= 1; if(stp) goto loop; break; 67743589Sdonahn 67843589Sdonahn /* NON-LOCKING KEYS */ 67943589Sdonahn case SHF: shfts = 1; break; 68043589Sdonahn case ALT: alts = 1; break; 68143589Sdonahn case CTL: ctls = 1; break; 68243589Sdonahn case ASCII: 68343589Sdonahn if (shfts) dt = shift[dt]; 68443589Sdonahn else if (ctls) dt = ctl[dt]; 68543589Sdonahn else dt = unshift[dt]; 68643589Sdonahn if (caps && (dt >= 'a' && dt <= 'z')) dt -= 'a' - 'A'; 68743589Sdonahn return(dt); 68843589Sdonahn } 68941053Swilliam } 69043589Sdonahn if (noblock) return (0x100); else goto loop; 69141053Swilliam } 69241053Swilliam 69341053Swilliam pg(p,q,r,s,t,u,v,w,x,y,z) char *p; { 69441053Swilliam printf(p,q,r,s,t,u,v,w,x,y,z); 69541053Swilliam printf("\n"); 69641053Swilliam return(getchar()); 69741053Swilliam } 69841053Swilliam 69941053Swilliam /* special characters */ 70041053Swilliam #define bs 8 70141053Swilliam #define lf 10 70241053Swilliam #define cr 13 70341053Swilliam #define cntlc 3 70441053Swilliam #define del 0177 70541053Swilliam #define cntld 4 70641053Swilliam 70741053Swilliam getchar() 70841053Swilliam { 70941053Swilliam register char thechar; 71041053Swilliam register delay; 71141053Swilliam int x; 71241053Swilliam 71341053Swilliam consoftc.cs_flags |= CSF_POLLING; 71441053Swilliam x=splhigh(); 71543589Sdonahn sput('>',0x6); 716*45535Sbill /*while (1) {*/ 71741053Swilliam thechar = (char) sgetc(0); 71843589Sdonahn consoftc.cs_flags &= ~CSF_POLLING; 71943589Sdonahn splx(x); 72041053Swilliam switch (thechar) { 72141053Swilliam default: if (thechar >= ' ') 72243589Sdonahn sput(thechar,0x6); 72341053Swilliam return(thechar); 72441053Swilliam case cr: 72543589Sdonahn case lf: sput(cr,0x6); 72643589Sdonahn sput(lf,0x6); 72741053Swilliam return(lf); 72841053Swilliam case bs: 72941053Swilliam case del: 73043589Sdonahn sput(bs,0x6); 73143589Sdonahn sput(' ',0x6); 73243589Sdonahn sput(bs,0x6); 73341053Swilliam return(thechar); 73443589Sdonahn /*case cntlc: 73541053Swilliam sput('^',0xe) ; sput('C',0xe) ; sput('\r',0xe) ; sput('\n',0xe) ; 73643589Sdonahn _exit(-2) ; */ 73741053Swilliam case cntld: 73843589Sdonahn sput('^',0x6) ; sput('D',0x6) ; sput('\r',0x6) ; sput('\n',0x6) ; 73941053Swilliam return(0); 74041053Swilliam } 741*45535Sbill /*}*/ 74241053Swilliam } 743