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 * 8*49573Swilliam * %sccs.include.redist.c% 943589Sdonahn * 10*49573Swilliam * @(#)pccons.c 5.7 (Berkeley) 05/09/91 1141053Swilliam */ 1241053Swilliam 1341053Swilliam /* 1441053Swilliam * code to work keyboard & display for console 1541053Swilliam */ 1641053Swilliam #include "param.h" 1741053Swilliam #include "conf.h" 1841053Swilliam #include "ioctl.h" 19*49573Swilliam #include "proc.h" 2041053Swilliam #include "user.h" 2141053Swilliam #include "tty.h" 2241053Swilliam #include "uio.h" 23*49573Swilliam #include "i386/isa/isa_device.h" 2441053Swilliam #include "callout.h" 2541053Swilliam #include "systm.h" 2641053Swilliam #include "kernel.h" 2741053Swilliam #include "syslog.h" 28*49573Swilliam #include "i386/isa/icu.h" 2941053Swilliam 3041053Swilliam struct tty cons; 3141053Swilliam 3241053Swilliam struct consoftc { 3341053Swilliam char cs_flags; 3441053Swilliam #define CSF_ACTIVE 0x1 /* timeout active */ 3541053Swilliam #define CSF_POLLING 0x2 /* polling for input */ 3641053Swilliam char cs_lastc; /* last char sent */ 3741053Swilliam int cs_timo; /* timeouts since interrupt */ 3841053Swilliam u_long cs_wedgecnt; /* times restarted */ 3941053Swilliam } consoftc; 4041053Swilliam 4143589Sdonahn int cnprobe(), cnattach(); 4243589Sdonahn 4345535Sbill struct isa_driver cndriver = { 4443589Sdonahn cnprobe, cnattach, "cn", 4543589Sdonahn }; 4643589Sdonahn 4745535Sbill #define COL 80 4845535Sbill #define ROW 25 4945535Sbill #define CHR 2 5045535Sbill #define MONO_BASE 0x3B4 51*49573Swilliam #define MONO_BUF 0xfe0B0000 5245535Sbill #define CGA_BASE 0x3D4 53*49573Swilliam #define CGA_BUF 0xfe0B8000 5445535Sbill #define IOPHYSMEM 0xA0000 5545535Sbill 5645535Sbill u_char color = 0xe ; 5745535Sbill static unsigned int addr_6845 = MONO_BASE; 5845535Sbill u_short *Crtat = (u_short *)MONO_BUF; 59*49573Swilliam static openf; 6045535Sbill 6141053Swilliam int cnstart(); 62*49573Swilliam int cnparam(); 6341053Swilliam int ttrstrt(); 6441053Swilliam char partab[]; 6541053Swilliam u_char inb(); 6641053Swilliam 6743589Sdonahn cnprobe(dev) 6845535Sbill struct isa_device *dev; 6943589Sdonahn { 7043589Sdonahn u_char c; 7143589Sdonahn int again = 0; 7243589Sdonahn 7343589Sdonahn /* Enable interrupts and keyboard controller */ 7443589Sdonahn while (inb(0x64)&2); outb(0x64,0x60); 7543589Sdonahn while (inb(0x64)&2); outb(0x60,0x4D); 7643589Sdonahn 7743589Sdonahn /* Start keyboard stuff RESET */ 7843589Sdonahn while (inb(0x64)&2); /* wait input ready */ 7943589Sdonahn outb(0x60,0xFF); /* RESET */ 8043589Sdonahn while((c=inb(0x60))!=0xFA) { 8143589Sdonahn if ((c == 0xFE) || (c == 0xFF)) { 8243589Sdonahn if(!again)printf("KEYBOARD disconnected: RECONNECT \n"); 8343589Sdonahn while (inb(0x64)&2); /* wait input ready */ 8443589Sdonahn outb(0x60,0xFF); /* RESET */ 8543589Sdonahn again = 1; 8643589Sdonahn } 8743589Sdonahn } 8843589Sdonahn /* pick up keyboard reset return code */ 89*49573Swilliam while((c=inb(0x60))!=0xAA); 9043589Sdonahn return 1; 9143589Sdonahn } 9243589Sdonahn 9343589Sdonahn cnattach(dev) 9445535Sbill struct isa_device *dev; 9543589Sdonahn { 9645535Sbill u_short *cp = Crtat + (CGA_BUF-MONO_BUF)/CHR; 9745535Sbill u_short was; 9845535Sbill 9945535Sbill /* Crtat initialized to point to MONO buffer */ 10045535Sbill /* if not present change to CGA_BUF offset */ 10145535Sbill /* ONLY ADD the difference since locore.s adds */ 10245535Sbill /* in the remapped offset at the right time */ 10345535Sbill 10445535Sbill was = *Crtat; 10545535Sbill *Crtat = (u_short) 0xA55A; 10645535Sbill if (*Crtat != 0xA55A) 10745535Sbill printf("<mono>"); 10845535Sbill else printf("<color>"); 10945535Sbill *Crtat = was; 110*49573Swilliam cursor(); 11143589Sdonahn } 11243589Sdonahn 113*49573Swilliam /* ARGSUSED */ 114*49573Swilliam #ifdef __STDC__ 115*49573Swilliam cnopen(dev_t dev, int flag, int mode, struct proc *p) 116*49573Swilliam #else 117*49573Swilliam cnopen(dev, flag, mode, p) 11841053Swilliam dev_t dev; 119*49573Swilliam int flag, mode; 120*49573Swilliam struct proc *p; 121*49573Swilliam #endif 12241053Swilliam { 12341053Swilliam register struct tty *tp; 12441053Swilliam 12541053Swilliam tp = &cons; 12641053Swilliam tp->t_oproc = cnstart; 127*49573Swilliam tp->t_param = cnparam; 128*49573Swilliam tp->t_dev = dev; 129*49573Swilliam openf++; 130*49573Swilliam if ((tp->t_state & TS_ISOPEN) == 0) { 131*49573Swilliam tp->t_state |= TS_WOPEN; 13241053Swilliam ttychars(tp); 133*49573Swilliam tp->t_iflag = TTYDEF_IFLAG; 134*49573Swilliam tp->t_oflag = TTYDEF_OFLAG; 135*49573Swilliam tp->t_cflag = TTYDEF_CFLAG; 136*49573Swilliam tp->t_lflag = TTYDEF_LFLAG; 137*49573Swilliam tp->t_ispeed = tp->t_ospeed = TTYDEF_SPEED; 138*49573Swilliam cnparam(tp, &tp->t_termios); 139*49573Swilliam ttsetwater(tp); 140*49573Swilliam } else if (tp->t_state&TS_XCLUDE && p->p_ucred->cr_uid != 0) 141*49573Swilliam return (EBUSY); 142*49573Swilliam tp->t_state |= TS_CARR_ON; 14341053Swilliam return ((*linesw[tp->t_line].l_open)(dev, tp)); 14441053Swilliam } 14541053Swilliam 146*49573Swilliam cnclose(dev, flag) 14741053Swilliam dev_t dev; 14841053Swilliam { 14941053Swilliam (*linesw[cons.t_line].l_close)(&cons); 15041053Swilliam ttyclose(&cons); 151*49573Swilliam return(0); 15241053Swilliam } 15341053Swilliam 15441053Swilliam /*ARGSUSED*/ 155*49573Swilliam cnread(dev, uio, flag) 15641053Swilliam dev_t dev; 15741053Swilliam struct uio *uio; 15841053Swilliam { 159*49573Swilliam return ((*linesw[cons.t_line].l_read)(&cons, uio, flag)); 16041053Swilliam } 16141053Swilliam 16241053Swilliam /*ARGSUSED*/ 163*49573Swilliam cnwrite(dev, uio, flag) 16441053Swilliam dev_t dev; 16541053Swilliam struct uio *uio; 16641053Swilliam { 167*49573Swilliam return ((*linesw[cons.t_line].l_write)(&cons, uio, flag)); 16841053Swilliam } 16941053Swilliam 17041053Swilliam /* 17141053Swilliam * Got a console receive interrupt - 17241053Swilliam * the console processor wants to give us a character. 17341053Swilliam * Catch the character, and see who it goes to. 17441053Swilliam */ 17545535Sbill cnrint(dev, irq, cpl) 17641053Swilliam dev_t dev; 17741053Swilliam { 17841053Swilliam int c; 17941053Swilliam 18041053Swilliam c = sgetc(1); 18145535Sbill if (c&0x100) return; 18241053Swilliam if (consoftc.cs_flags&CSF_POLLING) 18341053Swilliam return; 18441053Swilliam #ifdef KDB 18541053Swilliam if (kdbrintr(c, &cons)) 18641053Swilliam return; 18741053Swilliam #endif 18841053Swilliam (*linesw[cons.t_line].l_rint)(c&0xff, &cons); 18941053Swilliam } 19041053Swilliam 191*49573Swilliam cnioctl(dev, cmd, data, flag) 19241053Swilliam dev_t dev; 193*49573Swilliam caddr_t data; 19441053Swilliam { 19541053Swilliam register struct tty *tp = &cons; 19641053Swilliam register error; 19741053Swilliam 198*49573Swilliam error = (*linesw[tp->t_line].l_ioctl)(tp, cmd, data, flag); 19941053Swilliam if (error >= 0) 200*49573Swilliam return (error); 201*49573Swilliam error = ttioctl(tp, cmd, data, flag); 202*49573Swilliam if (error >= 0) 203*49573Swilliam return (error); 204*49573Swilliam return (ENOTTY); 20541053Swilliam } 20641053Swilliam 207*49573Swilliam extern int consintr ; 20841053Swilliam /* 20941053Swilliam * Got a console transmission interrupt - 21041053Swilliam * the console processor wants another character. 21141053Swilliam */ 21241053Swilliam cnxint(dev) 21341053Swilliam dev_t dev; 21441053Swilliam { 21541053Swilliam register struct tty *tp; 21641053Swilliam register int unit; 21741053Swilliam 21841053Swilliam if (!consintr) 21941053Swilliam return; 22041053Swilliam cons.t_state &= ~TS_BUSY; 22141053Swilliam consoftc.cs_timo = 0; 22241053Swilliam if (cons.t_line) 22341053Swilliam (*linesw[cons.t_line].l_start)(&cons); 22441053Swilliam else 22541053Swilliam cnstart(&cons); 22641053Swilliam } 22741053Swilliam 22841053Swilliam cnstart(tp) 22941053Swilliam register struct tty *tp; 23041053Swilliam { 23141053Swilliam register c, s; 23241053Swilliam 23341053Swilliam s = spltty(); 23441053Swilliam if (tp->t_state & (TS_TIMEOUT|TS_BUSY|TS_TTSTOP)) 23541053Swilliam goto out; 236*49573Swilliam do { 237*49573Swilliam if (tp->t_outq.c_cc <= tp->t_lowat) { 23841053Swilliam if (tp->t_state&TS_ASLEEP) { 23941053Swilliam tp->t_state &= ~TS_ASLEEP; 24041053Swilliam wakeup((caddr_t)&tp->t_outq); 24141053Swilliam } 24241053Swilliam if (tp->t_wsel) { 24341053Swilliam selwakeup(tp->t_wsel, tp->t_state & TS_WCOLL); 24441053Swilliam tp->t_wsel = 0; 24541053Swilliam tp->t_state &= ~TS_WCOLL; 24641053Swilliam } 24741053Swilliam } 248*49573Swilliam if (tp->t_outq.c_cc == 0) 249*49573Swilliam goto out; 250*49573Swilliam c = getc(&tp->t_outq); 251*49573Swilliam splx(s); 252*49573Swilliam sput(c,0x7); 253*49573Swilliam s = spltty(); 254*49573Swilliam } while(1); 25541053Swilliam out: 25641053Swilliam splx(s); 25741053Swilliam } 25841053Swilliam 259*49573Swilliam static __color; 260*49573Swilliam 26141053Swilliam cnputc(c) 26241053Swilliam char c; 263*49573Swilliam { int clr; 264*49573Swilliam clr = __color; 265*49573Swilliam if (clr == 0) clr = 0x30; 266*49573Swilliam else clr |= 0x60; 26741053Swilliam if (c == '\n') 268*49573Swilliam sput('\r',clr); 269*49573Swilliam sput(c, clr); 27041053Swilliam } 27141053Swilliam 27241053Swilliam /* 27341053Swilliam * Print a character on console. 27441053Swilliam */ 27541053Swilliam cnputchar(c, tp) 27641053Swilliam char c; 27741053Swilliam register struct tty *tp; 27841053Swilliam { 27943589Sdonahn sput(c,0x2); 28041053Swilliam if (c=='\n') getchar(); 28141053Swilliam } 28241053Swilliam 28341053Swilliam 28441053Swilliam cngetc() 28541053Swilliam { 28641053Swilliam register int c, s; 28741053Swilliam 28841053Swilliam s = spltty(); /* block cnrint while we poll */ 28943589Sdonahn c = sgetc(0); 29043589Sdonahn if (c == '\r') c = '\n'; 29141053Swilliam splx(s); 29241053Swilliam return (c); 29341053Swilliam } 29441053Swilliam 29541053Swilliam cngetchar(tp) 29641053Swilliam register struct tty *tp; 29741053Swilliam { 29841053Swilliam int c; 29941053Swilliam 30041053Swilliam c = sgetc(0); 30141053Swilliam return (c&0xff); 30241053Swilliam } 30341053Swilliam 30441053Swilliam /* 30541053Swilliam * Set line parameters 30641053Swilliam */ 307*49573Swilliam cnparam(tp, t) 30841053Swilliam register struct tty *tp; 309*49573Swilliam register struct termios *t; 31041053Swilliam { 311*49573Swilliam register int cflag = t->c_cflag; 312*49573Swilliam /* and copy to tty */ 313*49573Swilliam tp->t_ispeed = t->c_ispeed; 314*49573Swilliam tp->t_ospeed = t->c_ospeed; 315*49573Swilliam tp->t_cflag = cflag; 316*49573Swilliam 317*49573Swilliam return(0); 31841053Swilliam } 31941053Swilliam 32041053Swilliam #ifdef KDB 32141053Swilliam /* 32241053Swilliam * Turn input polling on/off (used by debugger). 32341053Swilliam */ 32441053Swilliam cnpoll(onoff) 32541053Swilliam int onoff; 32641053Swilliam { 32741053Swilliam } 32841053Swilliam #endif 32941053Swilliam 33043589Sdonahn extern int hz; 33143589Sdonahn 332*49573Swilliam static beeping; 33343589Sdonahn sysbeepstop() 33443589Sdonahn { 33543589Sdonahn /* disable counter 2 */ 33643589Sdonahn outb(0x61,inb(0x61)&0xFC); 337*49573Swilliam beeping = 0; 33843589Sdonahn } 33943589Sdonahn 34043589Sdonahn sysbeep() 34143589Sdonahn { 342*49573Swilliam 34343589Sdonahn /* enable counter 2 */ 34443589Sdonahn outb(0x61,inb(0x61)|3); 34543589Sdonahn /* set command for counter 2, 2 byte write */ 34643589Sdonahn outb(0x43,0xB6); 34743589Sdonahn /* send 0x637 for 750 HZ */ 34843589Sdonahn outb(0x42,0x37); 34943589Sdonahn outb(0x42,0x06); 350*49573Swilliam if(!beeping)timeout(sysbeepstop,0,hz/4); 351*49573Swilliam beeping = 1; 35243589Sdonahn } 35343589Sdonahn 35445535Sbill /* cursor() sets an offset (0-1999) into the 80x25 text area */ 35541053Swilliam 35645535Sbill static u_short *crtat = 0; 35745535Sbill char bg_at = 0x0f; 35845535Sbill char so_at = 0x70; 35941053Swilliam 36045535Sbill cursor() 36145535Sbill { int pos = crtat - Crtat; 36241053Swilliam 36343589Sdonahn outb(addr_6845,14); 36443589Sdonahn outb(addr_6845+1,pos >> 8); 36543589Sdonahn outb(addr_6845,15); 36643589Sdonahn outb(addr_6845+1,pos&0xff); 367*49573Swilliam timeout(cursor,0,hz/10); 36843589Sdonahn } 36943589Sdonahn 370*49573Swilliam u_char shfts, ctls, alts, caps, num, stp, scroll; 371*49573Swilliam 372*49573Swilliam /* 373*49573Swilliam * Compensate for abysmally stupid frame buffer aribitration with macro 374*49573Swilliam */ 375*49573Swilliam #define wrtchar(c) { do *crtat = (c); while ((c) != *crtat); crtat++; row++; } 376*49573Swilliam 37743589Sdonahn /* sput has support for emulation of the 'ibmpc' termcap entry. */ 37843589Sdonahn /* This is a bare-bones implementation of a bare-bones entry */ 37943589Sdonahn /* One modification: Change li#24 to li#25 to reflect 25 lines */ 38043589Sdonahn 38143589Sdonahn sput(c, ca) 38243589Sdonahn u_char c, ca; 38343589Sdonahn { 38443589Sdonahn 38543589Sdonahn static int esc,ebrac,eparm,cx,cy,row,so; 38643589Sdonahn 38741053Swilliam if (crtat == 0) { 38845535Sbill u_short *cp = Crtat + (CGA_BUF-MONO_BUF)/CHR, was; 38945535Sbill unsigned cursorat; 39043589Sdonahn 39143589Sdonahn /* Crtat initialized to point to MONO buffer */ 39243589Sdonahn /* if not present change to CGA_BUF offset */ 39343589Sdonahn /* ONLY ADD the difference since locore.s adds */ 39443589Sdonahn /* in the remapped offset at the right time */ 39543589Sdonahn 39645535Sbill was = *cp; 39745535Sbill *cp = (u_short) 0xA55A; 39845535Sbill if (*cp != 0xA55A) { 39945535Sbill addr_6845 = MONO_BASE; 40045535Sbill } else { 40145535Sbill *cp = was; 40245535Sbill addr_6845 = CGA_BASE; 40343589Sdonahn Crtat = Crtat + (CGA_BUF-MONO_BUF)/CHR; 40445535Sbill } 40545535Sbill /* Extract cursor location */ 40645535Sbill outb(addr_6845,14); 40745535Sbill cursorat = inb(addr_6845+1)<<8 ; 40845535Sbill outb(addr_6845,15); 40945535Sbill cursorat |= inb(addr_6845+1); 41045535Sbill 41145535Sbill crtat = Crtat + cursorat; 41245535Sbill fillw((bg_at<<8)|' ', crtat, COL*ROW-cursorat); 41341053Swilliam } 41441053Swilliam switch(c) { 41543589Sdonahn case 0x1B: 41643589Sdonahn esc = 1; ebrac = 0; eparm = 0; 41743589Sdonahn break; 41841053Swilliam 41941053Swilliam case '\t': 42041053Swilliam do { 421*49573Swilliam wrtchar((ca<<8)| ' '); 422*49573Swilliam } while (row % 8); 42341053Swilliam break; 42441053Swilliam 42541053Swilliam case '\010': 42641053Swilliam crtat--; row--; 42743589Sdonahn if (row < 0) row += COL; /* non-destructive backspace */ 42841053Swilliam break; 42941053Swilliam 43041053Swilliam case '\r': 43143589Sdonahn crtat -= row ; row = 0; 43241053Swilliam break; 43341053Swilliam 43441053Swilliam case '\n': 43541053Swilliam crtat += COL ; 43641053Swilliam break; 43741053Swilliam 43841053Swilliam default: 43943589Sdonahn if (esc) { 44043589Sdonahn if (ebrac) { 44143589Sdonahn switch(c) { 44243589Sdonahn case 'm': /* no support for standout */ 44343589Sdonahn if (!cx) so = 0; 44443589Sdonahn else so = 1; 44543589Sdonahn esc = 0; ebrac = 0; eparm = 0; 44643589Sdonahn break; 44743589Sdonahn case 'A': /* back one row */ 44843589Sdonahn crtat -= COL; 44943589Sdonahn esc = 0; ebrac = 0; eparm = 0; 45043589Sdonahn break; 45143589Sdonahn case 'B': /* down one row */ 45243589Sdonahn crtat += COL; 45343589Sdonahn esc = 0; ebrac = 0; eparm = 0; 45443589Sdonahn break; 45543589Sdonahn case 'C': /* right cursor */ 45643589Sdonahn crtat++; row++; 45743589Sdonahn esc = 0; ebrac = 0; eparm = 0; 45843589Sdonahn break; 45943589Sdonahn case 'J': /* Clear to end of display */ 46045535Sbill fillw((bg_at<<8)+' ', crtat, 46145535Sbill Crtat+COL*ROW-crtat); 46243589Sdonahn esc = 0; ebrac = 0; eparm = 0; 46343589Sdonahn break; 46443589Sdonahn case 'K': /* Clear to EOL */ 465*49573Swilliam fillw((bg_at<<8)+' ', crtat, 466*49573Swilliam COL-(crtat-Crtat)%COL); 46743589Sdonahn esc = 0; ebrac = 0; eparm = 0; 46843589Sdonahn break; 46943589Sdonahn case 'H': /* Cursor move */ 47043589Sdonahn if ((!cx)||(!cy)) { 47143589Sdonahn crtat = Crtat; 47243589Sdonahn row = 0; 47343589Sdonahn } else { 47443589Sdonahn crtat = Crtat+(cx-1)*COL+cy-1; 47543589Sdonahn row = cy-1; 47643589Sdonahn } 47743589Sdonahn esc = 0; ebrac = 0; eparm = 0; 47843589Sdonahn break; 47943589Sdonahn case ';': /* Switch params in cursor def */ 48043589Sdonahn eparm = 1; 48143589Sdonahn return; 48243589Sdonahn default: /* Only numbers valid here */ 48343589Sdonahn if ((c >= '0')&&(c <= '9')) { 48443589Sdonahn if (eparm) { 48543589Sdonahn cy *= 10; 48643589Sdonahn cy += c - '0'; 48743589Sdonahn } else { 48843589Sdonahn cx *= 10; 48943589Sdonahn cx += c - '0'; 49043589Sdonahn } 49143589Sdonahn } else { 49243589Sdonahn esc = 0; ebrac = 0; eparm = 0; 49343589Sdonahn } 49443589Sdonahn return; 49543589Sdonahn } 49643589Sdonahn break; 49743589Sdonahn } else if (c == 'c') { /* Clear screen & home */ 49845535Sbill fillw((bg_at<<8)+' ', Crtat,COL*ROW); 49943589Sdonahn crtat = Crtat; row = 0; 50043589Sdonahn esc = 0; ebrac = 0; eparm = 0; 50145535Sbill } else if (c == '[') { /* Start ESC [ sequence */ 50243589Sdonahn ebrac = 1; cx = 0; cy = 0; eparm = 0; 50345535Sbill } else { /* Invalid, clear state */ 50443589Sdonahn esc = 0; ebrac = 0; eparm = 0; 50543589Sdonahn } 50643589Sdonahn } else { 507*49573Swilliam if (c == 7) 50843589Sdonahn sysbeep(); 50943589Sdonahn /* Print only printables */ 51045535Sbill else /*if (c >= ' ') */ { 51143589Sdonahn if (so) { 512*49573Swilliam wrtchar((so_at<<8)| c); 51343589Sdonahn } else { 514*49573Swilliam wrtchar((ca<<8)| c); 51543589Sdonahn } 51643589Sdonahn if (row >= COL) row = 0; 51743589Sdonahn break ; 51843589Sdonahn } 51941053Swilliam } 52041053Swilliam } 52143589Sdonahn if (crtat >= Crtat+COL*(ROW)) { /* scroll check */ 522*49573Swilliam if (openf) do sgetc(1); while (scroll); 52343589Sdonahn bcopy(Crtat+COL,Crtat,COL*(ROW-1)*CHR); 524*49573Swilliam fillw ((bg_at<<8) + ' ', Crtat+COL*(ROW-1),COL) ; 52543589Sdonahn crtat -= COL ; 52643589Sdonahn } 52741053Swilliam } 52843589Sdonahn 52941053Swilliam #define L 0x0001 /* locking function */ 53041053Swilliam #define SHF 0x0002 /* keyboard shift */ 53141053Swilliam #define ALT 0x0004 /* alternate shift -- alternate chars */ 53241053Swilliam #define NUM 0x0008 /* numeric shift cursors vs. numeric */ 53341053Swilliam #define CTL 0x0010 /* control shift -- allows ctl function */ 53441053Swilliam #define CPS 0x0020 /* caps shift -- swaps case of letter */ 53541053Swilliam #define ASCII 0x0040 /* ascii code for this key */ 53641053Swilliam #define STP 0x0080 /* stop output */ 53741053Swilliam #define FUNC 0x0100 /* function key */ 53843589Sdonahn #define SCROLL 0x0200 /* scroll lock key */ 53941053Swilliam 540*49573Swilliam unsigned __debug = 0xffe; 54141053Swilliam u_short action[] = { 54241053Swilliam 0, ASCII, ASCII, ASCII, ASCII, ASCII, ASCII, ASCII, /* scan 0- 7 */ 54341053Swilliam ASCII, ASCII, ASCII, ASCII, ASCII, ASCII, ASCII, ASCII, /* scan 8-15 */ 54441053Swilliam ASCII, ASCII, ASCII, ASCII, ASCII, ASCII, ASCII, ASCII, /* scan 16-23 */ 54541053Swilliam ASCII, ASCII, ASCII, ASCII, ASCII, CTL, ASCII, ASCII, /* scan 24-31 */ 54641053Swilliam ASCII, ASCII, ASCII, ASCII, ASCII, ASCII, ASCII, ASCII, /* scan 32-39 */ 54741053Swilliam ASCII, ASCII, SHF , ASCII, ASCII, ASCII, ASCII, ASCII, /* scan 40-47 */ 54841053Swilliam ASCII, ASCII, ASCII, ASCII, ASCII, ASCII, SHF, ASCII, /* scan 48-55 */ 54943589Sdonahn ALT, ASCII, CPS , FUNC , FUNC , FUNC , FUNC , FUNC , /* scan 56-63 */ 550*49573Swilliam FUNC , FUNC , FUNC , FUNC , FUNC , NUM, SCROLL, ASCII, /* scan 64-71 */ 55141053Swilliam ASCII, ASCII, ASCII, ASCII, ASCII, ASCII, ASCII, ASCII, /* scan 72-79 */ 55241053Swilliam ASCII, ASCII, ASCII, ASCII, 0, 0, 0, 0, /* scan 80-87 */ 55341053Swilliam 0,0,0,0,0,0,0,0, 55441053Swilliam 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 55541053Swilliam 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, } ; 55641053Swilliam 55741053Swilliam u_char unshift[] = { /* no shift */ 55841053Swilliam 0, 033 , '1' , '2' , '3' , '4' , '5' , '6' , /* scan 0- 7 */ 55941053Swilliam '7' , '8' , '9' , '0' , '-' , '=' , 0177 ,'\t' , /* scan 8-15 */ 56041053Swilliam 56141053Swilliam 'q' , 'w' , 'e' , 'r' , 't' , 'y' , 'u' , 'i' , /* scan 16-23 */ 56241053Swilliam 'o' , 'p' , '[' , ']' , '\r' , CTL , 'a' , 's' , /* scan 24-31 */ 56341053Swilliam 56441053Swilliam 'd' , 'f' , 'g' , 'h' , 'j' , 'k' , 'l' , ';' , /* scan 32-39 */ 56541053Swilliam '\'' , '`' , SHF , '\\' , 'z' , 'x' , 'c' , 'v' , /* scan 40-47 */ 56641053Swilliam 56741053Swilliam 'b' , 'n' , 'm' , ',' , '.' , '/' , SHF , '*', /* scan 48-55 */ 56843589Sdonahn ALT , ' ' , CPS, 1, 2, 3 , 4, 5, /* scan 56-63 */ 56941053Swilliam 57043589Sdonahn 6, 7, 8, 9, 10, NUM, STP, '7', /* scan 64-71 */ 57141053Swilliam '8', '9', '-', '4', '5', '6', '+', '1', /* scan 72-79 */ 57241053Swilliam 57341053Swilliam '2', '3', '0', '.', 0, 0, 0, 0, /* scan 80-87 */ 57441053Swilliam 0,0,0,0,0,0,0,0, 57541053Swilliam 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 57641053Swilliam 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, } ; 57741053Swilliam 57841053Swilliam u_char shift[] = { /* shift shift */ 57941053Swilliam 0, 033 , '!' , '@' , '#' , '$' , '%' , '^' , /* scan 0- 7 */ 58041053Swilliam '&' , '*' , '(' , ')' , '_' , '+' , 0177 ,'\t' , /* scan 8-15 */ 58141053Swilliam 'Q' , 'W' , 'E' , 'R' , 'T' , 'Y' , 'U' , 'I' , /* scan 16-23 */ 58241053Swilliam 'O' , 'P' , '{' , '}' , '\r' , CTL , 'A' , 'S' , /* scan 24-31 */ 58341053Swilliam 'D' , 'F' , 'G' , 'H' , 'J' , 'K' , 'L' , ':' , /* scan 32-39 */ 58441053Swilliam '"' , '~' , SHF , '|' , 'Z' , 'X' , 'C' , 'V' , /* scan 40-47 */ 58541053Swilliam 'B' , 'N' , 'M' , '<' , '>' , '?' , SHF , '*', /* scan 48-55 */ 58643589Sdonahn ALT , ' ' , CPS, 0, 0, ' ' , 0, 0, /* scan 56-63 */ 58743589Sdonahn 0, 0, 0, 0, 0, NUM, STP, '7', /* scan 64-71 */ 58841053Swilliam '8', '9', '-', '4', '5', '6', '+', '1', /* scan 72-79 */ 58941053Swilliam '2', '3', '0', '.', 0, 0, 0, 0, /* scan 80-87 */ 59041053Swilliam 0,0,0,0,0,0,0,0, 59141053Swilliam 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 59241053Swilliam 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, } ; 59341053Swilliam 59441053Swilliam u_char ctl[] = { /* CTL shift */ 59541053Swilliam 0, 033 , '!' , 000 , '#' , '$' , '%' , 036 , /* scan 0- 7 */ 59641053Swilliam '&' , '*' , '(' , ')' , 037 , '+' , 034 ,'\177', /* scan 8-15 */ 59741053Swilliam 021 , 027 , 005 , 022 , 024 , 031 , 025 , 011 , /* scan 16-23 */ 59841053Swilliam 017 , 020 , 033 , 035 , '\r' , CTL , 001 , 023 , /* scan 24-31 */ 59941053Swilliam 004 , 006 , 007 , 010 , 012 , 013 , 014 , ';' , /* scan 32-39 */ 60041053Swilliam '\'' , '`' , SHF , 034 , 032 , 030 , 003 , 026 , /* scan 40-47 */ 60141053Swilliam 002 , 016 , 015 , '<' , '>' , '?' , SHF , '*', /* scan 48-55 */ 60243589Sdonahn ALT , ' ' , CPS, 0, 0, ' ' , 0, 0, /* scan 56-63 */ 60343589Sdonahn CPS, 0, 0, 0, 0, 0, 0, 0, /* scan 64-71 */ 60441053Swilliam 0, 0, 0, 0, 0, 0, 0, 0, /* scan 72-79 */ 60541053Swilliam 0, 0, 0, 0, 0, 0, 0, 0, /* scan 80-87 */ 60643589Sdonahn 0, 0, 033, '7' , '4' , '1' , 0, NUM, /* scan 88-95 */ 60743589Sdonahn '8' , '5' , '2' , 0, STP, '9' , '6' , '3' , /*scan 96-103*/ 60841053Swilliam '.' , 0, '*' , '-' , '+' , 0, 0, 0, /*scan 104-111*/ 60941053Swilliam 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, } ; 61041053Swilliam 61141053Swilliam #ifdef notdef 61241053Swilliam struct key { 61341053Swilliam u_short action; /* how this key functions */ 61441053Swilliam char ascii[8]; /* ascii result character indexed by shifts */ 61541053Swilliam }; 61641053Swilliam #endif 61741053Swilliam 61841053Swilliam 61943589Sdonahn #define KBSTAT 0x64 /* kbd status port */ 62043589Sdonahn #define KBS_INP_BUF_FUL 0x02 /* kbd char ready */ 62143589Sdonahn #define KBDATA 0x60 /* kbd data port */ 62241053Swilliam #define KBSTATUSPORT 0x61 /* kbd status */ 62341053Swilliam 62443589Sdonahn update_led() 62543589Sdonahn { 62643589Sdonahn while (inb(0x64)&2); /* wait input ready */ 62743589Sdonahn outb(0x60,0xED); /* LED Command */ 62843589Sdonahn while (inb(0x64)&2); /* wait input ready */ 62943589Sdonahn outb(0x60,scroll | 2*num | 4*caps); 63043589Sdonahn } 63141053Swilliam 63245535Sbill reset_cpu() { 63345535Sbill while(1) { 63445535Sbill while (inb(0x64)&2); /* wait input ready */ 63545535Sbill outb(0x64,0xFE); /* Reset Command */ 63645535Sbill DELAY(4000000); 63745535Sbill while (inb(0x64)&2); /* wait input ready */ 63845535Sbill outb(0x64,0xFF); /* Keyboard Reset Command */ 63945535Sbill } 64045535Sbill /* NOTREACHED */ 64145535Sbill } 64245535Sbill 64343589Sdonahn /* 64443589Sdonahn sgetc(noblock) : get a character from the keyboard. If noblock = 0 wait until 64543589Sdonahn a key is gotten. Otherwise return a 0x100 (256). 64643589Sdonahn */ 64743589Sdonahn int sgetc(noblock) 64843589Sdonahn { 64943589Sdonahn u_char dt; unsigned key; 65041053Swilliam loop: 65143589Sdonahn /* First see if there is something in the keyboard port */ 65243589Sdonahn if (inb(KBSTAT)&1) dt = inb(KBDATA); 65343589Sdonahn else { if (noblock) return (0x100); else goto loop; } 65441053Swilliam 65543589Sdonahn /* Check for cntl-alt-del */ 65643589Sdonahn if ((dt == 83)&&ctls&&alts) _exit(); 65741053Swilliam 65843589Sdonahn /* Check for make/break */ 65943589Sdonahn if (dt & 0x80) { 66043589Sdonahn /* break */ 66143589Sdonahn dt = dt & 0x7f ; 66243589Sdonahn switch (action[dt]) { 66343589Sdonahn case SHF: shfts = 0; break; 66443589Sdonahn case ALT: alts = 0; break; 66543589Sdonahn case CTL: ctls = 0; break; 66643589Sdonahn case FUNC: 66743589Sdonahn /* Toggle debug flags */ 66843589Sdonahn key = unshift[dt]; 66943589Sdonahn if(__debug & (1<<key)) __debug &= ~(1<<key) ; 67043589Sdonahn else __debug |= (1<<key) ; 67143589Sdonahn break; 67241053Swilliam } 67343589Sdonahn } else { 67443589Sdonahn /* make */ 67543589Sdonahn dt = dt & 0x7f ; 67643589Sdonahn switch (action[dt]) { 67743589Sdonahn /* LOCKING KEYS */ 67843589Sdonahn case NUM: num ^= 1; update_led(); break; 67943589Sdonahn case CPS: caps ^= 1; update_led(); break; 68043589Sdonahn case SCROLL: scroll ^= 1; update_led(); break; 68143589Sdonahn case STP: stp ^= 1; if(stp) goto loop; break; 68243589Sdonahn 68343589Sdonahn /* NON-LOCKING KEYS */ 68443589Sdonahn case SHF: shfts = 1; break; 68543589Sdonahn case ALT: alts = 1; break; 68643589Sdonahn case CTL: ctls = 1; break; 68743589Sdonahn case ASCII: 68843589Sdonahn if (shfts) dt = shift[dt]; 68943589Sdonahn else if (ctls) dt = ctl[dt]; 69043589Sdonahn else dt = unshift[dt]; 69143589Sdonahn if (caps && (dt >= 'a' && dt <= 'z')) dt -= 'a' - 'A'; 69243589Sdonahn return(dt); 69343589Sdonahn } 69441053Swilliam } 69543589Sdonahn if (noblock) return (0x100); else goto loop; 69641053Swilliam } 69741053Swilliam 69841053Swilliam pg(p,q,r,s,t,u,v,w,x,y,z) char *p; { 69941053Swilliam printf(p,q,r,s,t,u,v,w,x,y,z); 70041053Swilliam printf("\n"); 70141053Swilliam return(getchar()); 70241053Swilliam } 70341053Swilliam 70441053Swilliam /* special characters */ 70541053Swilliam #define bs 8 70641053Swilliam #define lf 10 70741053Swilliam #define cr 13 70841053Swilliam #define cntlc 3 70941053Swilliam #define del 0177 71041053Swilliam #define cntld 4 71141053Swilliam 71241053Swilliam getchar() 71341053Swilliam { 71441053Swilliam register char thechar; 71541053Swilliam register delay; 71641053Swilliam int x; 71741053Swilliam 71841053Swilliam consoftc.cs_flags |= CSF_POLLING; 71941053Swilliam x=splhigh(); 72043589Sdonahn sput('>',0x6); 72145535Sbill /*while (1) {*/ 72241053Swilliam thechar = (char) sgetc(0); 72343589Sdonahn consoftc.cs_flags &= ~CSF_POLLING; 72443589Sdonahn splx(x); 72541053Swilliam switch (thechar) { 72641053Swilliam default: if (thechar >= ' ') 72743589Sdonahn sput(thechar,0x6); 72841053Swilliam return(thechar); 72941053Swilliam case cr: 73043589Sdonahn case lf: sput(cr,0x6); 73143589Sdonahn sput(lf,0x6); 73241053Swilliam return(lf); 73341053Swilliam case bs: 73441053Swilliam case del: 73543589Sdonahn sput(bs,0x6); 73643589Sdonahn sput(' ',0x6); 73743589Sdonahn sput(bs,0x6); 73841053Swilliam return(thechar); 73943589Sdonahn /*case cntlc: 74041053Swilliam sput('^',0xe) ; sput('C',0xe) ; sput('\r',0xe) ; sput('\n',0xe) ; 74143589Sdonahn _exit(-2) ; */ 74241053Swilliam case cntld: 74343589Sdonahn sput('^',0x6) ; sput('D',0x6) ; sput('\r',0x6) ; sput('\n',0x6) ; 74441053Swilliam return(0); 74541053Swilliam } 74645535Sbill /*}*/ 74741053Swilliam } 748*49573Swilliam 749*49573Swilliam #include "machine/dbg.h" 750*49573Swilliam #include "machine/stdarg.h" 751*49573Swilliam static nrow; 752*49573Swilliam 753*49573Swilliam void 754*49573Swilliam #ifdef __STDC__ 755*49573Swilliam dprintf(unsigned flgs, const char *fmt, ...) 756*49573Swilliam #else 757*49573Swilliam dprintf(flgs, fmt /*, va_alist */) 758*49573Swilliam char *fmt; 759*49573Swilliam unsigned flgs; 760*49573Swilliam #endif 761*49573Swilliam { extern unsigned __debug; 762*49573Swilliam va_list ap; 763*49573Swilliam 764*49573Swilliam if((flgs&__debug) > DPAUSE) { 765*49573Swilliam __color = ffs(flgs&__debug)+1; 766*49573Swilliam va_start(ap,fmt); 767*49573Swilliam kprintf(fmt, 1, (struct tty *)0, ap); 768*49573Swilliam va_end(ap); 769*49573Swilliam if (flgs&DPAUSE || nrow%24 == 23) { 770*49573Swilliam int x; 771*49573Swilliam x = splhigh(); 772*49573Swilliam if (nrow%24 == 23) nrow = 0; 773*49573Swilliam sgetc(0); 774*49573Swilliam splx(x); 775*49573Swilliam } 776*49573Swilliam } 777*49573Swilliam __color = 0; 778*49573Swilliam } 779*49573Swilliam 780*49573Swilliam consinit() {} 781