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 * 849592Swilliam * Added support for ibmpc term type and improved keyboard support. -Don Ahn 949592Swilliam * 1049573Swilliam * %sccs.include.redist.c% 1143589Sdonahn * 12*49751Smarc * @(#)pccons.c 5.10 (Berkeley) 05/16/91 1341053Swilliam */ 1441053Swilliam 1541053Swilliam /* 1649592Swilliam * code to work keyboard & display for PC-style console 1741053Swilliam */ 1841053Swilliam #include "param.h" 1941053Swilliam #include "conf.h" 2041053Swilliam #include "ioctl.h" 2149573Swilliam #include "proc.h" 2241053Swilliam #include "user.h" 2341053Swilliam #include "tty.h" 2441053Swilliam #include "uio.h" 2549573Swilliam #include "i386/isa/isa_device.h" 2641053Swilliam #include "callout.h" 2741053Swilliam #include "systm.h" 2841053Swilliam #include "kernel.h" 2941053Swilliam #include "syslog.h" 3049573Swilliam #include "i386/isa/icu.h" 3149592Swilliam #include "i386/i386/cons.h" 3241053Swilliam 3349592Swilliam struct tty pccons; 3441053Swilliam 3549592Swilliam struct pcconsoftc { 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 */ 4249592Swilliam } pcconsoftc; 4341053Swilliam 4449592Swilliam int pcprobe(), pcattach(); 4543589Sdonahn 4649592Swilliam struct isa_driver pcdriver = { 4749592Swilliam pcprobe, pcattach, "pc", 4843589Sdonahn }; 4943589Sdonahn 5045535Sbill #define COL 80 5145535Sbill #define ROW 25 5245535Sbill #define CHR 2 5345535Sbill #define MONO_BASE 0x3B4 5449573Swilliam #define MONO_BUF 0xfe0B0000 5545535Sbill #define CGA_BASE 0x3D4 5649573Swilliam #define CGA_BUF 0xfe0B8000 5745535Sbill #define IOPHYSMEM 0xA0000 5845535Sbill 5945535Sbill u_char color = 0xe ; 6045535Sbill static unsigned int addr_6845 = MONO_BASE; 6145535Sbill u_short *Crtat = (u_short *)MONO_BUF; 6249573Swilliam static openf; 6345535Sbill 6449592Swilliam /* 6549592Swilliam * We check the console periodically to make sure 6649592Swilliam * that it hasn't wedged. Unfortunately, if an XOFF 6749592Swilliam * is typed on the console, that can't be distinguished 6849592Swilliam * from more catastrophic failure. 6949592Swilliam */ 7049592Swilliam #define CN_TIMERVAL (hz) /* frequency at which to check cons */ 7149592Swilliam #define CN_TIMO (2*60) /* intervals to allow for output char */ 7249592Swilliam 7349592Swilliam int pcstart(); 7449592Swilliam int pcparam(); 7541053Swilliam int ttrstrt(); 7641053Swilliam char partab[]; 7749592Swilliam 7849592Swilliam /* 7949592Swilliam * Wait for CP to accept last CP command sent 8049592Swilliam * before setting up next command. 8149592Swilliam */ 8249592Swilliam #define waitforlast(timo) { \ 8349592Swilliam if (pclast) { \ 8449592Swilliam (timo) = 10000; \ 8549592Swilliam do \ 8649592Swilliam uncache((char *)&pclast->cp_unit); \ 8749592Swilliam while ((pclast->cp_unit&CPTAKE) == 0 && --(timo)); \ 8849592Swilliam } \ 8949592Swilliam } 9049592Swilliam 9141053Swilliam u_char inb(); 9241053Swilliam 9349592Swilliam pcprobe(dev) 9445535Sbill struct isa_device *dev; 9543589Sdonahn { 9643589Sdonahn u_char c; 9743589Sdonahn int again = 0; 9843589Sdonahn 9943589Sdonahn /* Enable interrupts and keyboard controller */ 10043589Sdonahn while (inb(0x64)&2); outb(0x64,0x60); 10143589Sdonahn while (inb(0x64)&2); outb(0x60,0x4D); 10243589Sdonahn 10343589Sdonahn /* Start keyboard stuff RESET */ 10443589Sdonahn while (inb(0x64)&2); /* wait input ready */ 10543589Sdonahn outb(0x60,0xFF); /* RESET */ 10643589Sdonahn while((c=inb(0x60))!=0xFA) { 10743589Sdonahn if ((c == 0xFE) || (c == 0xFF)) { 10843589Sdonahn if(!again)printf("KEYBOARD disconnected: RECONNECT \n"); 10943589Sdonahn while (inb(0x64)&2); /* wait input ready */ 11043589Sdonahn outb(0x60,0xFF); /* RESET */ 11143589Sdonahn again = 1; 11243589Sdonahn } 11343589Sdonahn } 11443589Sdonahn /* pick up keyboard reset return code */ 11549573Swilliam while((c=inb(0x60))!=0xAA); 11643589Sdonahn return 1; 11743589Sdonahn } 11843589Sdonahn 11949592Swilliam pcattach(dev) 12045535Sbill struct isa_device *dev; 12143589Sdonahn { 12245535Sbill u_short *cp = Crtat + (CGA_BUF-MONO_BUF)/CHR; 12345535Sbill u_short was; 12445535Sbill 12545535Sbill /* Crtat initialized to point to MONO buffer */ 12645535Sbill /* if not present change to CGA_BUF offset */ 12745535Sbill /* ONLY ADD the difference since locore.s adds */ 12845535Sbill /* in the remapped offset at the right time */ 12945535Sbill 13045535Sbill was = *Crtat; 13145535Sbill *Crtat = (u_short) 0xA55A; 13245535Sbill if (*Crtat != 0xA55A) 13345535Sbill printf("<mono>"); 13445535Sbill else printf("<color>"); 13545535Sbill *Crtat = was; 13649573Swilliam cursor(); 13743589Sdonahn } 13843589Sdonahn 13949573Swilliam /* ARGSUSED */ 14049573Swilliam #ifdef __STDC__ 14149592Swilliam pcopen(dev_t dev, int flag, int mode, struct proc *p) 14249573Swilliam #else 14349592Swilliam pcopen(dev, flag, mode, p) 14441053Swilliam dev_t dev; 14549573Swilliam int flag, mode; 14649573Swilliam struct proc *p; 14749573Swilliam #endif 14841053Swilliam { 14941053Swilliam register struct tty *tp; 15041053Swilliam 15149592Swilliam tp = &pccons; 15249592Swilliam tp->t_oproc = pcstart; 15349592Swilliam tp->t_param = pcparam; 15449573Swilliam tp->t_dev = dev; 15549573Swilliam openf++; 15649573Swilliam if ((tp->t_state & TS_ISOPEN) == 0) { 15749573Swilliam tp->t_state |= TS_WOPEN; 15841053Swilliam ttychars(tp); 15949573Swilliam tp->t_iflag = TTYDEF_IFLAG; 16049573Swilliam tp->t_oflag = TTYDEF_OFLAG; 16149573Swilliam tp->t_cflag = TTYDEF_CFLAG; 16249573Swilliam tp->t_lflag = TTYDEF_LFLAG; 16349573Swilliam tp->t_ispeed = tp->t_ospeed = TTYDEF_SPEED; 16449592Swilliam pcparam(tp, &tp->t_termios); 16549573Swilliam ttsetwater(tp); 16649573Swilliam } else if (tp->t_state&TS_XCLUDE && p->p_ucred->cr_uid != 0) 16749573Swilliam return (EBUSY); 16849573Swilliam tp->t_state |= TS_CARR_ON; 16941053Swilliam return ((*linesw[tp->t_line].l_open)(dev, tp)); 17041053Swilliam } 17141053Swilliam 172*49751Smarc pcclose(dev, flag, mode, p) 17341053Swilliam dev_t dev; 174*49751Smarc int flag, mode; 175*49751Smarc struct proc *p; 17641053Swilliam { 177*49751Smarc (*linesw[pccons.t_line].l_close)(&pccons, flag); 17849592Swilliam ttyclose(&pccons); 17949573Swilliam return(0); 18041053Swilliam } 18141053Swilliam 18241053Swilliam /*ARGSUSED*/ 18349592Swilliam pcread(dev, uio, flag) 18441053Swilliam dev_t dev; 18541053Swilliam struct uio *uio; 18641053Swilliam { 18749592Swilliam return ((*linesw[pccons.t_line].l_read)(&pccons, uio, flag)); 18841053Swilliam } 18941053Swilliam 19041053Swilliam /*ARGSUSED*/ 19149592Swilliam pcwrite(dev, uio, flag) 19241053Swilliam dev_t dev; 19341053Swilliam struct uio *uio; 19441053Swilliam { 19549592Swilliam return ((*linesw[pccons.t_line].l_write)(&pccons, uio, flag)); 19641053Swilliam } 19741053Swilliam 19841053Swilliam /* 19941053Swilliam * Got a console receive interrupt - 20041053Swilliam * the console processor wants to give us a character. 20141053Swilliam * Catch the character, and see who it goes to. 20241053Swilliam */ 20349592Swilliam pcrint(dev, irq, cpl) 20441053Swilliam dev_t dev; 20541053Swilliam { 20641053Swilliam int c; 20741053Swilliam 20841053Swilliam c = sgetc(1); 20945535Sbill if (c&0x100) return; 21049592Swilliam if (pcconsoftc.cs_flags&CSF_POLLING) 21141053Swilliam return; 21241053Swilliam #ifdef KDB 21349592Swilliam if (kdbrintr(c, &pccons)) 21441053Swilliam return; 21541053Swilliam #endif 21649592Swilliam (*linesw[pccons.t_line].l_rint)(c&0xff, &pccons); 21741053Swilliam } 21841053Swilliam 21949592Swilliam pcioctl(dev, cmd, data, flag) 22041053Swilliam dev_t dev; 22149573Swilliam caddr_t data; 22241053Swilliam { 22349592Swilliam register struct tty *tp = &pccons; 22441053Swilliam register error; 22541053Swilliam 22649573Swilliam error = (*linesw[tp->t_line].l_ioctl)(tp, cmd, data, flag); 22741053Swilliam if (error >= 0) 22849573Swilliam return (error); 22949573Swilliam error = ttioctl(tp, cmd, data, flag); 23049573Swilliam if (error >= 0) 23149573Swilliam return (error); 23249573Swilliam return (ENOTTY); 23341053Swilliam } 23441053Swilliam 23549592Swilliam int pcconsintr = 1; 23641053Swilliam /* 23741053Swilliam * Got a console transmission interrupt - 23841053Swilliam * the console processor wants another character. 23941053Swilliam */ 24049592Swilliam pcxint(dev) 24141053Swilliam dev_t dev; 24241053Swilliam { 24341053Swilliam register struct tty *tp; 24441053Swilliam register int unit; 24541053Swilliam 24649592Swilliam if (!pcconsintr) 24741053Swilliam return; 24849592Swilliam pccons.t_state &= ~TS_BUSY; 24949592Swilliam pcconsoftc.cs_timo = 0; 25049592Swilliam if (pccons.t_line) 25149592Swilliam (*linesw[pccons.t_line].l_start)(&pccons); 25241053Swilliam else 25349592Swilliam pcstart(&pccons); 25441053Swilliam } 25541053Swilliam 25649592Swilliam pcstart(tp) 25741053Swilliam register struct tty *tp; 25841053Swilliam { 25941053Swilliam register c, s; 26041053Swilliam 26141053Swilliam s = spltty(); 26241053Swilliam if (tp->t_state & (TS_TIMEOUT|TS_BUSY|TS_TTSTOP)) 26341053Swilliam goto out; 26449573Swilliam do { 26549573Swilliam if (tp->t_outq.c_cc <= tp->t_lowat) { 26641053Swilliam if (tp->t_state&TS_ASLEEP) { 26741053Swilliam tp->t_state &= ~TS_ASLEEP; 26841053Swilliam wakeup((caddr_t)&tp->t_outq); 26941053Swilliam } 27041053Swilliam if (tp->t_wsel) { 27141053Swilliam selwakeup(tp->t_wsel, tp->t_state & TS_WCOLL); 27241053Swilliam tp->t_wsel = 0; 27341053Swilliam tp->t_state &= ~TS_WCOLL; 27441053Swilliam } 27541053Swilliam } 27649573Swilliam if (tp->t_outq.c_cc == 0) 27749573Swilliam goto out; 27849573Swilliam c = getc(&tp->t_outq); 27949573Swilliam splx(s); 28049573Swilliam sput(c,0x7); 28149573Swilliam s = spltty(); 28249573Swilliam } while(1); 28341053Swilliam out: 28441053Swilliam splx(s); 28541053Swilliam } 28641053Swilliam 28749592Swilliam pccnprobe(cp) 28849592Swilliam struct consdev *cp; 28949592Swilliam { 29049592Swilliam int maj; 29149592Swilliam extern int pcopen(); 29249592Swilliam 29349592Swilliam /* locate the major number */ 29449592Swilliam for (maj = 0; maj < nchrdev; maj++) 29549592Swilliam if (cdevsw[maj].d_open == pcopen) 29649592Swilliam break; 29749592Swilliam 29849592Swilliam /* initialize required fields */ 29949592Swilliam cp->cn_dev = makedev(maj, 0); 30049592Swilliam cp->cn_tp = &pccons; 30149592Swilliam cp->cn_pri = CN_INTERNAL; 30249592Swilliam } 30349592Swilliam 30449592Swilliam /* ARGSUSED */ 30549592Swilliam pccninit(cp) 30649592Swilliam struct consdev *cp; 30749592Swilliam { 30849592Swilliam /* 30949592Swilliam * For now, don't screw with it. 31049592Swilliam */ 31149592Swilliam /* crtat = 0; */ 31249592Swilliam } 31349592Swilliam 31449573Swilliam static __color; 31549573Swilliam 31649592Swilliam /* ARGSUSED */ 31749592Swilliam pccnputc(dev, c) 31849592Swilliam dev_t dev; 31941053Swilliam char c; 32049592Swilliam { 32149592Swilliam int clr = __color; 32249592Swilliam 32349592Swilliam if (clr == 0) 32449592Swilliam clr = 0x30; 32549592Swilliam else 32649592Swilliam clr |= 0x60; 32741053Swilliam if (c == '\n') 32849592Swilliam sput('\r', clr); 32949573Swilliam sput(c, clr); 33041053Swilliam } 33141053Swilliam 33241053Swilliam /* 33341053Swilliam * Print a character on console. 33441053Swilliam */ 33549592Swilliam pcputchar(c, tp) 33641053Swilliam char c; 33741053Swilliam register struct tty *tp; 33841053Swilliam { 33943589Sdonahn sput(c,0x2); 34041053Swilliam if (c=='\n') getchar(); 34141053Swilliam } 34241053Swilliam 34341053Swilliam 34449592Swilliam /* ARGSUSED */ 34549592Swilliam pccngetc(dev) 34649592Swilliam dev_t dev; 34741053Swilliam { 34841053Swilliam register int c, s; 34941053Swilliam 35049592Swilliam s = spltty(); /* block pcrint while we poll */ 35143589Sdonahn c = sgetc(0); 35243589Sdonahn if (c == '\r') c = '\n'; 35341053Swilliam splx(s); 35441053Swilliam return (c); 35541053Swilliam } 35641053Swilliam 35749592Swilliam pcgetchar(tp) 35841053Swilliam register struct tty *tp; 35941053Swilliam { 36041053Swilliam int c; 36141053Swilliam 36241053Swilliam c = sgetc(0); 36341053Swilliam return (c&0xff); 36441053Swilliam } 36541053Swilliam 36641053Swilliam /* 36741053Swilliam * Set line parameters 36841053Swilliam */ 36949592Swilliam pcparam(tp, t) 37041053Swilliam register struct tty *tp; 37149573Swilliam register struct termios *t; 37241053Swilliam { 37349573Swilliam register int cflag = t->c_cflag; 37449573Swilliam /* and copy to tty */ 37549573Swilliam tp->t_ispeed = t->c_ispeed; 37649573Swilliam tp->t_ospeed = t->c_ospeed; 37749573Swilliam tp->t_cflag = cflag; 37849573Swilliam 37949573Swilliam return(0); 38041053Swilliam } 38141053Swilliam 38241053Swilliam #ifdef KDB 38341053Swilliam /* 38441053Swilliam * Turn input polling on/off (used by debugger). 38541053Swilliam */ 38649592Swilliam pcpoll(onoff) 38741053Swilliam int onoff; 38841053Swilliam { 38941053Swilliam } 39041053Swilliam #endif 39141053Swilliam 39243589Sdonahn extern int hz; 39343589Sdonahn 39449573Swilliam static beeping; 39543589Sdonahn sysbeepstop() 39643589Sdonahn { 39743589Sdonahn /* disable counter 2 */ 39843589Sdonahn outb(0x61,inb(0x61)&0xFC); 39949573Swilliam beeping = 0; 40043589Sdonahn } 40143589Sdonahn 40243589Sdonahn sysbeep() 40343589Sdonahn { 40449573Swilliam 40543589Sdonahn /* enable counter 2 */ 40643589Sdonahn outb(0x61,inb(0x61)|3); 40743589Sdonahn /* set command for counter 2, 2 byte write */ 40843589Sdonahn outb(0x43,0xB6); 40943589Sdonahn /* send 0x637 for 750 HZ */ 41043589Sdonahn outb(0x42,0x37); 41143589Sdonahn outb(0x42,0x06); 41249573Swilliam if(!beeping)timeout(sysbeepstop,0,hz/4); 41349573Swilliam beeping = 1; 41443589Sdonahn } 41543589Sdonahn 41645535Sbill /* cursor() sets an offset (0-1999) into the 80x25 text area */ 41741053Swilliam 41845535Sbill static u_short *crtat = 0; 41945535Sbill char bg_at = 0x0f; 42045535Sbill char so_at = 0x70; 42141053Swilliam 42245535Sbill cursor() 42345535Sbill { int pos = crtat - Crtat; 42441053Swilliam 42543589Sdonahn outb(addr_6845,14); 42643589Sdonahn outb(addr_6845+1,pos >> 8); 42743589Sdonahn outb(addr_6845,15); 42843589Sdonahn outb(addr_6845+1,pos&0xff); 42949573Swilliam timeout(cursor,0,hz/10); 43043589Sdonahn } 43143589Sdonahn 43249573Swilliam u_char shfts, ctls, alts, caps, num, stp, scroll; 43349573Swilliam 43449573Swilliam /* 43549573Swilliam * Compensate for abysmally stupid frame buffer aribitration with macro 43649573Swilliam */ 43749573Swilliam #define wrtchar(c) { do *crtat = (c); while ((c) != *crtat); crtat++; row++; } 43849573Swilliam 43943589Sdonahn /* sput has support for emulation of the 'ibmpc' termcap entry. */ 44043589Sdonahn /* This is a bare-bones implementation of a bare-bones entry */ 44143589Sdonahn /* One modification: Change li#24 to li#25 to reflect 25 lines */ 44243589Sdonahn 44343589Sdonahn sput(c, ca) 44443589Sdonahn u_char c, ca; 44543589Sdonahn { 44643589Sdonahn 44743589Sdonahn static int esc,ebrac,eparm,cx,cy,row,so; 44843589Sdonahn 44941053Swilliam if (crtat == 0) { 45045535Sbill u_short *cp = Crtat + (CGA_BUF-MONO_BUF)/CHR, was; 45145535Sbill unsigned cursorat; 45243589Sdonahn 45343589Sdonahn /* Crtat initialized to point to MONO buffer */ 45443589Sdonahn /* if not present change to CGA_BUF offset */ 45543589Sdonahn /* ONLY ADD the difference since locore.s adds */ 45643589Sdonahn /* in the remapped offset at the right time */ 45743589Sdonahn 45845535Sbill was = *cp; 45945535Sbill *cp = (u_short) 0xA55A; 46045535Sbill if (*cp != 0xA55A) { 46145535Sbill addr_6845 = MONO_BASE; 46245535Sbill } else { 46345535Sbill *cp = was; 46445535Sbill addr_6845 = CGA_BASE; 46543589Sdonahn Crtat = Crtat + (CGA_BUF-MONO_BUF)/CHR; 46645535Sbill } 46745535Sbill /* Extract cursor location */ 46845535Sbill outb(addr_6845,14); 46945535Sbill cursorat = inb(addr_6845+1)<<8 ; 47045535Sbill outb(addr_6845,15); 47145535Sbill cursorat |= inb(addr_6845+1); 47245535Sbill 47345535Sbill crtat = Crtat + cursorat; 47445535Sbill fillw((bg_at<<8)|' ', crtat, COL*ROW-cursorat); 47541053Swilliam } 47641053Swilliam switch(c) { 47743589Sdonahn case 0x1B: 47843589Sdonahn esc = 1; ebrac = 0; eparm = 0; 47943589Sdonahn break; 48041053Swilliam 48141053Swilliam case '\t': 48241053Swilliam do { 48349573Swilliam wrtchar((ca<<8)| ' '); 48449573Swilliam } while (row % 8); 48541053Swilliam break; 48641053Swilliam 48741053Swilliam case '\010': 48841053Swilliam crtat--; row--; 48943589Sdonahn if (row < 0) row += COL; /* non-destructive backspace */ 49041053Swilliam break; 49141053Swilliam 49241053Swilliam case '\r': 49343589Sdonahn crtat -= row ; row = 0; 49441053Swilliam break; 49541053Swilliam 49641053Swilliam case '\n': 49741053Swilliam crtat += COL ; 49841053Swilliam break; 49941053Swilliam 50041053Swilliam default: 50143589Sdonahn if (esc) { 50243589Sdonahn if (ebrac) { 50343589Sdonahn switch(c) { 50443589Sdonahn case 'm': /* no support for standout */ 50543589Sdonahn if (!cx) so = 0; 50643589Sdonahn else so = 1; 50743589Sdonahn esc = 0; ebrac = 0; eparm = 0; 50843589Sdonahn break; 50943589Sdonahn case 'A': /* back one row */ 51043589Sdonahn crtat -= COL; 51143589Sdonahn esc = 0; ebrac = 0; eparm = 0; 51243589Sdonahn break; 51343589Sdonahn case 'B': /* down one row */ 51443589Sdonahn crtat += COL; 51543589Sdonahn esc = 0; ebrac = 0; eparm = 0; 51643589Sdonahn break; 51743589Sdonahn case 'C': /* right cursor */ 51843589Sdonahn crtat++; row++; 51943589Sdonahn esc = 0; ebrac = 0; eparm = 0; 52043589Sdonahn break; 52143589Sdonahn case 'J': /* Clear to end of display */ 52245535Sbill fillw((bg_at<<8)+' ', crtat, 52345535Sbill Crtat+COL*ROW-crtat); 52443589Sdonahn esc = 0; ebrac = 0; eparm = 0; 52543589Sdonahn break; 52643589Sdonahn case 'K': /* Clear to EOL */ 52749573Swilliam fillw((bg_at<<8)+' ', crtat, 52849573Swilliam COL-(crtat-Crtat)%COL); 52943589Sdonahn esc = 0; ebrac = 0; eparm = 0; 53043589Sdonahn break; 53143589Sdonahn case 'H': /* Cursor move */ 53243589Sdonahn if ((!cx)||(!cy)) { 53343589Sdonahn crtat = Crtat; 53443589Sdonahn row = 0; 53543589Sdonahn } else { 53643589Sdonahn crtat = Crtat+(cx-1)*COL+cy-1; 53743589Sdonahn row = cy-1; 53843589Sdonahn } 53943589Sdonahn esc = 0; ebrac = 0; eparm = 0; 54043589Sdonahn break; 54143589Sdonahn case ';': /* Switch params in cursor def */ 54243589Sdonahn eparm = 1; 54343589Sdonahn return; 54443589Sdonahn default: /* Only numbers valid here */ 54543589Sdonahn if ((c >= '0')&&(c <= '9')) { 54643589Sdonahn if (eparm) { 54743589Sdonahn cy *= 10; 54843589Sdonahn cy += c - '0'; 54943589Sdonahn } else { 55043589Sdonahn cx *= 10; 55143589Sdonahn cx += c - '0'; 55243589Sdonahn } 55343589Sdonahn } else { 55443589Sdonahn esc = 0; ebrac = 0; eparm = 0; 55543589Sdonahn } 55643589Sdonahn return; 55743589Sdonahn } 55843589Sdonahn break; 55943589Sdonahn } else if (c == 'c') { /* Clear screen & home */ 56045535Sbill fillw((bg_at<<8)+' ', Crtat,COL*ROW); 56143589Sdonahn crtat = Crtat; row = 0; 56243589Sdonahn esc = 0; ebrac = 0; eparm = 0; 56345535Sbill } else if (c == '[') { /* Start ESC [ sequence */ 56443589Sdonahn ebrac = 1; cx = 0; cy = 0; eparm = 0; 56545535Sbill } else { /* Invalid, clear state */ 56643589Sdonahn esc = 0; ebrac = 0; eparm = 0; 56743589Sdonahn } 56843589Sdonahn } else { 56949573Swilliam if (c == 7) 57043589Sdonahn sysbeep(); 57143589Sdonahn /* Print only printables */ 57245535Sbill else /*if (c >= ' ') */ { 57343589Sdonahn if (so) { 57449573Swilliam wrtchar((so_at<<8)| c); 57543589Sdonahn } else { 57649573Swilliam wrtchar((ca<<8)| c); 57743589Sdonahn } 57843589Sdonahn if (row >= COL) row = 0; 57943589Sdonahn break ; 58043589Sdonahn } 58141053Swilliam } 58241053Swilliam } 58343589Sdonahn if (crtat >= Crtat+COL*(ROW)) { /* scroll check */ 58449573Swilliam if (openf) do sgetc(1); while (scroll); 58543589Sdonahn bcopy(Crtat+COL,Crtat,COL*(ROW-1)*CHR); 58649573Swilliam fillw ((bg_at<<8) + ' ', Crtat+COL*(ROW-1),COL) ; 58743589Sdonahn crtat -= COL ; 58843589Sdonahn } 58941053Swilliam } 59043589Sdonahn 59141053Swilliam #define L 0x0001 /* locking function */ 59241053Swilliam #define SHF 0x0002 /* keyboard shift */ 59341053Swilliam #define ALT 0x0004 /* alternate shift -- alternate chars */ 59441053Swilliam #define NUM 0x0008 /* numeric shift cursors vs. numeric */ 59541053Swilliam #define CTL 0x0010 /* control shift -- allows ctl function */ 59641053Swilliam #define CPS 0x0020 /* caps shift -- swaps case of letter */ 59741053Swilliam #define ASCII 0x0040 /* ascii code for this key */ 59841053Swilliam #define STP 0x0080 /* stop output */ 59941053Swilliam #define FUNC 0x0100 /* function key */ 60043589Sdonahn #define SCROLL 0x0200 /* scroll lock key */ 60141053Swilliam 60249695Swilliam unsigned __debug = 0; /*0xffe */; 60341053Swilliam u_short action[] = { 60441053Swilliam 0, ASCII, ASCII, ASCII, ASCII, ASCII, ASCII, ASCII, /* scan 0- 7 */ 60541053Swilliam ASCII, ASCII, ASCII, ASCII, ASCII, ASCII, ASCII, ASCII, /* scan 8-15 */ 60641053Swilliam ASCII, ASCII, ASCII, ASCII, ASCII, ASCII, ASCII, ASCII, /* scan 16-23 */ 60741053Swilliam ASCII, ASCII, ASCII, ASCII, ASCII, CTL, ASCII, ASCII, /* scan 24-31 */ 60841053Swilliam ASCII, ASCII, ASCII, ASCII, ASCII, ASCII, ASCII, ASCII, /* scan 32-39 */ 60941053Swilliam ASCII, ASCII, SHF , ASCII, ASCII, ASCII, ASCII, ASCII, /* scan 40-47 */ 61041053Swilliam ASCII, ASCII, ASCII, ASCII, ASCII, ASCII, SHF, ASCII, /* scan 48-55 */ 61143589Sdonahn ALT, ASCII, CPS , FUNC , FUNC , FUNC , FUNC , FUNC , /* scan 56-63 */ 61249573Swilliam FUNC , FUNC , FUNC , FUNC , FUNC , NUM, SCROLL, ASCII, /* scan 64-71 */ 61341053Swilliam ASCII, ASCII, ASCII, ASCII, ASCII, ASCII, ASCII, ASCII, /* scan 72-79 */ 61441053Swilliam ASCII, ASCII, ASCII, ASCII, 0, 0, 0, 0, /* scan 80-87 */ 61541053Swilliam 0,0,0,0,0,0,0,0, 61641053Swilliam 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 61741053Swilliam 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, } ; 61841053Swilliam 61941053Swilliam u_char unshift[] = { /* no shift */ 62041053Swilliam 0, 033 , '1' , '2' , '3' , '4' , '5' , '6' , /* scan 0- 7 */ 62141053Swilliam '7' , '8' , '9' , '0' , '-' , '=' , 0177 ,'\t' , /* scan 8-15 */ 62241053Swilliam 62341053Swilliam 'q' , 'w' , 'e' , 'r' , 't' , 'y' , 'u' , 'i' , /* scan 16-23 */ 62441053Swilliam 'o' , 'p' , '[' , ']' , '\r' , CTL , 'a' , 's' , /* scan 24-31 */ 62541053Swilliam 62641053Swilliam 'd' , 'f' , 'g' , 'h' , 'j' , 'k' , 'l' , ';' , /* scan 32-39 */ 62741053Swilliam '\'' , '`' , SHF , '\\' , 'z' , 'x' , 'c' , 'v' , /* scan 40-47 */ 62841053Swilliam 62941053Swilliam 'b' , 'n' , 'm' , ',' , '.' , '/' , SHF , '*', /* scan 48-55 */ 63043589Sdonahn ALT , ' ' , CPS, 1, 2, 3 , 4, 5, /* scan 56-63 */ 63141053Swilliam 63243589Sdonahn 6, 7, 8, 9, 10, NUM, STP, '7', /* scan 64-71 */ 63341053Swilliam '8', '9', '-', '4', '5', '6', '+', '1', /* scan 72-79 */ 63441053Swilliam 63541053Swilliam '2', '3', '0', '.', 0, 0, 0, 0, /* scan 80-87 */ 63641053Swilliam 0,0,0,0,0,0,0,0, 63741053Swilliam 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 63841053Swilliam 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, } ; 63941053Swilliam 64041053Swilliam u_char shift[] = { /* shift shift */ 64141053Swilliam 0, 033 , '!' , '@' , '#' , '$' , '%' , '^' , /* scan 0- 7 */ 64241053Swilliam '&' , '*' , '(' , ')' , '_' , '+' , 0177 ,'\t' , /* scan 8-15 */ 64341053Swilliam 'Q' , 'W' , 'E' , 'R' , 'T' , 'Y' , 'U' , 'I' , /* scan 16-23 */ 64441053Swilliam 'O' , 'P' , '{' , '}' , '\r' , CTL , 'A' , 'S' , /* scan 24-31 */ 64541053Swilliam 'D' , 'F' , 'G' , 'H' , 'J' , 'K' , 'L' , ':' , /* scan 32-39 */ 64641053Swilliam '"' , '~' , SHF , '|' , 'Z' , 'X' , 'C' , 'V' , /* scan 40-47 */ 64741053Swilliam 'B' , 'N' , 'M' , '<' , '>' , '?' , SHF , '*', /* scan 48-55 */ 64843589Sdonahn ALT , ' ' , CPS, 0, 0, ' ' , 0, 0, /* scan 56-63 */ 64943589Sdonahn 0, 0, 0, 0, 0, NUM, STP, '7', /* scan 64-71 */ 65041053Swilliam '8', '9', '-', '4', '5', '6', '+', '1', /* scan 72-79 */ 65141053Swilliam '2', '3', '0', '.', 0, 0, 0, 0, /* scan 80-87 */ 65241053Swilliam 0,0,0,0,0,0,0,0, 65341053Swilliam 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 65441053Swilliam 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, } ; 65541053Swilliam 65641053Swilliam u_char ctl[] = { /* CTL shift */ 65741053Swilliam 0, 033 , '!' , 000 , '#' , '$' , '%' , 036 , /* scan 0- 7 */ 65841053Swilliam '&' , '*' , '(' , ')' , 037 , '+' , 034 ,'\177', /* scan 8-15 */ 65941053Swilliam 021 , 027 , 005 , 022 , 024 , 031 , 025 , 011 , /* scan 16-23 */ 66041053Swilliam 017 , 020 , 033 , 035 , '\r' , CTL , 001 , 023 , /* scan 24-31 */ 66141053Swilliam 004 , 006 , 007 , 010 , 012 , 013 , 014 , ';' , /* scan 32-39 */ 66241053Swilliam '\'' , '`' , SHF , 034 , 032 , 030 , 003 , 026 , /* scan 40-47 */ 66341053Swilliam 002 , 016 , 015 , '<' , '>' , '?' , SHF , '*', /* scan 48-55 */ 66443589Sdonahn ALT , ' ' , CPS, 0, 0, ' ' , 0, 0, /* scan 56-63 */ 66543589Sdonahn CPS, 0, 0, 0, 0, 0, 0, 0, /* scan 64-71 */ 66641053Swilliam 0, 0, 0, 0, 0, 0, 0, 0, /* scan 72-79 */ 66741053Swilliam 0, 0, 0, 0, 0, 0, 0, 0, /* scan 80-87 */ 66843589Sdonahn 0, 0, 033, '7' , '4' , '1' , 0, NUM, /* scan 88-95 */ 66943589Sdonahn '8' , '5' , '2' , 0, STP, '9' , '6' , '3' , /*scan 96-103*/ 67041053Swilliam '.' , 0, '*' , '-' , '+' , 0, 0, 0, /*scan 104-111*/ 67141053Swilliam 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, } ; 67241053Swilliam 67341053Swilliam #ifdef notdef 67441053Swilliam struct key { 67541053Swilliam u_short action; /* how this key functions */ 67641053Swilliam char ascii[8]; /* ascii result character indexed by shifts */ 67741053Swilliam }; 67841053Swilliam #endif 67941053Swilliam 68041053Swilliam 68143589Sdonahn #define KBSTAT 0x64 /* kbd status port */ 68243589Sdonahn #define KBS_INP_BUF_FUL 0x02 /* kbd char ready */ 68343589Sdonahn #define KBDATA 0x60 /* kbd data port */ 68441053Swilliam #define KBSTATUSPORT 0x61 /* kbd status */ 68541053Swilliam 68643589Sdonahn update_led() 68743589Sdonahn { 68843589Sdonahn while (inb(0x64)&2); /* wait input ready */ 68943589Sdonahn outb(0x60,0xED); /* LED Command */ 69043589Sdonahn while (inb(0x64)&2); /* wait input ready */ 69143589Sdonahn outb(0x60,scroll | 2*num | 4*caps); 69243589Sdonahn } 69341053Swilliam 69445535Sbill reset_cpu() { 69545535Sbill while(1) { 69645535Sbill while (inb(0x64)&2); /* wait input ready */ 69745535Sbill outb(0x64,0xFE); /* Reset Command */ 69845535Sbill DELAY(4000000); 69945535Sbill while (inb(0x64)&2); /* wait input ready */ 70045535Sbill outb(0x64,0xFF); /* Keyboard Reset Command */ 70145535Sbill } 70245535Sbill /* NOTREACHED */ 70345535Sbill } 70445535Sbill 70543589Sdonahn /* 70643589Sdonahn sgetc(noblock) : get a character from the keyboard. If noblock = 0 wait until 70743589Sdonahn a key is gotten. Otherwise return a 0x100 (256). 70843589Sdonahn */ 70943589Sdonahn int sgetc(noblock) 71043589Sdonahn { 71143589Sdonahn u_char dt; unsigned key; 71241053Swilliam loop: 71343589Sdonahn /* First see if there is something in the keyboard port */ 71443589Sdonahn if (inb(KBSTAT)&1) dt = inb(KBDATA); 71543589Sdonahn else { if (noblock) return (0x100); else goto loop; } 71641053Swilliam 71743589Sdonahn /* Check for cntl-alt-del */ 71843589Sdonahn if ((dt == 83)&&ctls&&alts) _exit(); 71941053Swilliam 72043589Sdonahn /* Check for make/break */ 72143589Sdonahn if (dt & 0x80) { 72243589Sdonahn /* break */ 72343589Sdonahn dt = dt & 0x7f ; 72443589Sdonahn switch (action[dt]) { 72543589Sdonahn case SHF: shfts = 0; break; 72643589Sdonahn case ALT: alts = 0; break; 72743589Sdonahn case CTL: ctls = 0; break; 72843589Sdonahn case FUNC: 72943589Sdonahn /* Toggle debug flags */ 73043589Sdonahn key = unshift[dt]; 73143589Sdonahn if(__debug & (1<<key)) __debug &= ~(1<<key) ; 73243589Sdonahn else __debug |= (1<<key) ; 73343589Sdonahn break; 73441053Swilliam } 73543589Sdonahn } else { 73643589Sdonahn /* make */ 73743589Sdonahn dt = dt & 0x7f ; 73843589Sdonahn switch (action[dt]) { 73943589Sdonahn /* LOCKING KEYS */ 74043589Sdonahn case NUM: num ^= 1; update_led(); break; 74143589Sdonahn case CPS: caps ^= 1; update_led(); break; 74243589Sdonahn case SCROLL: scroll ^= 1; update_led(); break; 74343589Sdonahn case STP: stp ^= 1; if(stp) goto loop; break; 74443589Sdonahn 74543589Sdonahn /* NON-LOCKING KEYS */ 74643589Sdonahn case SHF: shfts = 1; break; 74743589Sdonahn case ALT: alts = 1; break; 74843589Sdonahn case CTL: ctls = 1; break; 74943589Sdonahn case ASCII: 75043589Sdonahn if (shfts) dt = shift[dt]; 75143589Sdonahn else if (ctls) dt = ctl[dt]; 75243589Sdonahn else dt = unshift[dt]; 75343589Sdonahn if (caps && (dt >= 'a' && dt <= 'z')) dt -= 'a' - 'A'; 75443589Sdonahn return(dt); 75543589Sdonahn } 75641053Swilliam } 75743589Sdonahn if (noblock) return (0x100); else goto loop; 75841053Swilliam } 75941053Swilliam 76041053Swilliam pg(p,q,r,s,t,u,v,w,x,y,z) char *p; { 76141053Swilliam printf(p,q,r,s,t,u,v,w,x,y,z); 76241053Swilliam printf("\n"); 76341053Swilliam return(getchar()); 76441053Swilliam } 76541053Swilliam 76641053Swilliam /* special characters */ 76741053Swilliam #define bs 8 76841053Swilliam #define lf 10 76941053Swilliam #define cr 13 77041053Swilliam #define cntlc 3 77141053Swilliam #define del 0177 77241053Swilliam #define cntld 4 77341053Swilliam 77441053Swilliam getchar() 77541053Swilliam { 77641053Swilliam register char thechar; 77741053Swilliam register delay; 77841053Swilliam int x; 77941053Swilliam 78049592Swilliam pcconsoftc.cs_flags |= CSF_POLLING; 78141053Swilliam x=splhigh(); 78243589Sdonahn sput('>',0x6); 78345535Sbill /*while (1) {*/ 78441053Swilliam thechar = (char) sgetc(0); 78549592Swilliam pcconsoftc.cs_flags &= ~CSF_POLLING; 78643589Sdonahn splx(x); 78741053Swilliam switch (thechar) { 78841053Swilliam default: if (thechar >= ' ') 78943589Sdonahn sput(thechar,0x6); 79041053Swilliam return(thechar); 79141053Swilliam case cr: 79243589Sdonahn case lf: sput(cr,0x6); 79343589Sdonahn sput(lf,0x6); 79441053Swilliam return(lf); 79541053Swilliam case bs: 79641053Swilliam case del: 79743589Sdonahn sput(bs,0x6); 79843589Sdonahn sput(' ',0x6); 79943589Sdonahn sput(bs,0x6); 80041053Swilliam return(thechar); 80143589Sdonahn /*case cntlc: 80241053Swilliam sput('^',0xe) ; sput('C',0xe) ; sput('\r',0xe) ; sput('\n',0xe) ; 80343589Sdonahn _exit(-2) ; */ 80441053Swilliam case cntld: 80543589Sdonahn sput('^',0x6) ; sput('D',0x6) ; sput('\r',0x6) ; sput('\n',0x6) ; 80641053Swilliam return(0); 80741053Swilliam } 80845535Sbill /*}*/ 80941053Swilliam } 81049573Swilliam 81149573Swilliam #include "machine/dbg.h" 81249573Swilliam #include "machine/stdarg.h" 81349573Swilliam static nrow; 81449573Swilliam 81549573Swilliam void 81649573Swilliam #ifdef __STDC__ 81749573Swilliam dprintf(unsigned flgs, const char *fmt, ...) 81849573Swilliam #else 81949573Swilliam dprintf(flgs, fmt /*, va_alist */) 82049573Swilliam char *fmt; 82149573Swilliam unsigned flgs; 82249573Swilliam #endif 82349573Swilliam { extern unsigned __debug; 82449573Swilliam va_list ap; 82549573Swilliam 82649573Swilliam if((flgs&__debug) > DPAUSE) { 82749573Swilliam __color = ffs(flgs&__debug)+1; 82849573Swilliam va_start(ap,fmt); 82949573Swilliam kprintf(fmt, 1, (struct tty *)0, ap); 83049573Swilliam va_end(ap); 83149573Swilliam if (flgs&DPAUSE || nrow%24 == 23) { 83249573Swilliam int x; 83349573Swilliam x = splhigh(); 83449573Swilliam if (nrow%24 == 23) nrow = 0; 83549573Swilliam sgetc(0); 83649573Swilliam splx(x); 83749573Swilliam } 83849573Swilliam } 83949573Swilliam __color = 0; 84049573Swilliam } 84149573Swilliam 84249573Swilliam consinit() {} 843