141053Swilliam /*-
2*63364Sbostic * Copyright (c) 1990, 1993
3*63364Sbostic * The Regents of the University of California. All rights reserved.
441053Swilliam *
541053Swilliam * This code is derived from software contributed to Berkeley by
649828Sbostic * William Jolitz and Don Ahn.
741053Swilliam *
849573Swilliam * %sccs.include.redist.c%
943589Sdonahn *
10*63364Sbostic * @(#)pccons.c 8.1 (Berkeley) 06/11/93
1141053Swilliam */
1241053Swilliam
1341053Swilliam /*
1449592Swilliam * code to work keyboard & display for PC-style console
1541053Swilliam */
1656513Sbostic #include <sys/param.h>
1756513Sbostic #include <sys/conf.h>
1856513Sbostic #include <sys/ioctl.h>
1956513Sbostic #include <sys/proc.h>
2056513Sbostic #include <sys/user.h>
2156513Sbostic #include <sys/tty.h>
2256513Sbostic #include <sys/uio.h>
2356513Sbostic #include <sys/callout.h>
2456513Sbostic #include <sys/systm.h>
2556513Sbostic #include <sys/kernel.h>
2656513Sbostic #include <sys/syslog.h>
2741053Swilliam
2856513Sbostic #include <i386/isa/isa_device.h>
2956513Sbostic #include <i386/isa/icu.h>
3056513Sbostic #include <i386/i386/cons.h>
3156513Sbostic
3249592Swilliam struct tty pccons;
3341053Swilliam
3449592Swilliam struct pcconsoftc {
3541053Swilliam char cs_flags;
3641053Swilliam #define CSF_ACTIVE 0x1 /* timeout active */
3741053Swilliam #define CSF_POLLING 0x2 /* polling for input */
3841053Swilliam char cs_lastc; /* last char sent */
3941053Swilliam int cs_timo; /* timeouts since interrupt */
4041053Swilliam u_long cs_wedgecnt; /* times restarted */
4149592Swilliam } pcconsoftc;
4241053Swilliam
4349592Swilliam int pcprobe(), pcattach();
4443589Sdonahn
4549592Swilliam struct isa_driver pcdriver = {
4649592Swilliam pcprobe, pcattach, "pc",
4743589Sdonahn };
4843589Sdonahn
4945535Sbill #define COL 80
5045535Sbill #define ROW 25
5145535Sbill #define CHR 2
5245535Sbill #define MONO_BASE 0x3B4
5349573Swilliam #define MONO_BUF 0xfe0B0000
5445535Sbill #define CGA_BASE 0x3D4
5549573Swilliam #define CGA_BUF 0xfe0B8000
5645535Sbill #define IOPHYSMEM 0xA0000
5745535Sbill
5845535Sbill u_char color = 0xe ;
5945535Sbill static unsigned int addr_6845 = MONO_BASE;
6045535Sbill u_short *Crtat = (u_short *)MONO_BUF;
6149573Swilliam static openf;
6245535Sbill
6349592Swilliam /*
6449592Swilliam * We check the console periodically to make sure
6549592Swilliam * that it hasn't wedged. Unfortunately, if an XOFF
6649592Swilliam * is typed on the console, that can't be distinguished
6749592Swilliam * from more catastrophic failure.
6849592Swilliam */
6949592Swilliam #define CN_TIMERVAL (hz) /* frequency at which to check cons */
7049592Swilliam #define CN_TIMO (2*60) /* intervals to allow for output char */
7149592Swilliam
7249592Swilliam int pcstart();
7349592Swilliam int pcparam();
7441053Swilliam int ttrstrt();
7541053Swilliam char partab[];
7649592Swilliam
7749592Swilliam /*
7849592Swilliam * Wait for CP to accept last CP command sent
7949592Swilliam * before setting up next command.
8049592Swilliam */
8149592Swilliam #define waitforlast(timo) { \
8249592Swilliam if (pclast) { \
8349592Swilliam (timo) = 10000; \
8449592Swilliam do \
8549592Swilliam uncache((char *)&pclast->cp_unit); \
8649592Swilliam while ((pclast->cp_unit&CPTAKE) == 0 && --(timo)); \
8749592Swilliam } \
8849592Swilliam }
8949592Swilliam
9041053Swilliam u_char inb();
9141053Swilliam
9249592Swilliam pcprobe(dev)
9345535Sbill struct isa_device *dev;
9443589Sdonahn {
9543589Sdonahn u_char c;
9643589Sdonahn int again = 0;
9743589Sdonahn
9843589Sdonahn /* Enable interrupts and keyboard controller */
9943589Sdonahn while (inb(0x64)&2); outb(0x64,0x60);
10043589Sdonahn while (inb(0x64)&2); outb(0x60,0x4D);
10143589Sdonahn
10243589Sdonahn /* Start keyboard stuff RESET */
10343589Sdonahn while (inb(0x64)&2); /* wait input ready */
10443589Sdonahn outb(0x60,0xFF); /* RESET */
10543589Sdonahn while((c=inb(0x60))!=0xFA) {
10643589Sdonahn if ((c == 0xFE) || (c == 0xFF)) {
10743589Sdonahn if(!again)printf("KEYBOARD disconnected: RECONNECT \n");
10843589Sdonahn while (inb(0x64)&2); /* wait input ready */
10943589Sdonahn outb(0x60,0xFF); /* RESET */
11043589Sdonahn again = 1;
11143589Sdonahn }
11243589Sdonahn }
11343589Sdonahn /* pick up keyboard reset return code */
11449573Swilliam while((c=inb(0x60))!=0xAA);
11543589Sdonahn return 1;
11643589Sdonahn }
11743589Sdonahn
11849592Swilliam pcattach(dev)
11945535Sbill struct isa_device *dev;
12043589Sdonahn {
12145535Sbill u_short *cp = Crtat + (CGA_BUF-MONO_BUF)/CHR;
12245535Sbill u_short was;
12345535Sbill
12445535Sbill /* Crtat initialized to point to MONO buffer */
12545535Sbill /* if not present change to CGA_BUF offset */
12645535Sbill /* ONLY ADD the difference since locore.s adds */
12745535Sbill /* in the remapped offset at the right time */
12845535Sbill
12945535Sbill was = *Crtat;
13045535Sbill *Crtat = (u_short) 0xA55A;
13145535Sbill if (*Crtat != 0xA55A)
13245535Sbill printf("<mono>");
13345535Sbill else printf("<color>");
13445535Sbill *Crtat = was;
13549573Swilliam cursor();
13643589Sdonahn }
13743589Sdonahn
13849573Swilliam /* ARGSUSED */
13949573Swilliam #ifdef __STDC__
pcopen(dev_t dev,int flag,int mode,struct proc * p)14049592Swilliam pcopen(dev_t dev, int flag, int mode, struct proc *p)
14149573Swilliam #else
14249592Swilliam pcopen(dev, flag, mode, p)
14341053Swilliam dev_t dev;
14449573Swilliam int flag, mode;
14549573Swilliam struct proc *p;
14649573Swilliam #endif
14741053Swilliam {
14841053Swilliam register struct tty *tp;
14941053Swilliam
15049592Swilliam tp = &pccons;
15149592Swilliam tp->t_oproc = pcstart;
15249592Swilliam tp->t_param = pcparam;
15349573Swilliam tp->t_dev = dev;
15449573Swilliam openf++;
15549573Swilliam if ((tp->t_state & TS_ISOPEN) == 0) {
15649573Swilliam tp->t_state |= TS_WOPEN;
15741053Swilliam ttychars(tp);
15849573Swilliam tp->t_iflag = TTYDEF_IFLAG;
15949573Swilliam tp->t_oflag = TTYDEF_OFLAG;
16049573Swilliam tp->t_cflag = TTYDEF_CFLAG;
16149573Swilliam tp->t_lflag = TTYDEF_LFLAG;
16249573Swilliam tp->t_ispeed = tp->t_ospeed = TTYDEF_SPEED;
16349592Swilliam pcparam(tp, &tp->t_termios);
16449573Swilliam ttsetwater(tp);
16549573Swilliam } else if (tp->t_state&TS_XCLUDE && p->p_ucred->cr_uid != 0)
16649573Swilliam return (EBUSY);
16749573Swilliam tp->t_state |= TS_CARR_ON;
16841053Swilliam return ((*linesw[tp->t_line].l_open)(dev, tp));
16941053Swilliam }
17041053Swilliam
pcclose(dev,flag,mode,p)17149751Smarc pcclose(dev, flag, mode, p)
17241053Swilliam dev_t dev;
17349751Smarc int flag, mode;
17449751Smarc struct proc *p;
17541053Swilliam {
17649751Smarc (*linesw[pccons.t_line].l_close)(&pccons, flag);
17749592Swilliam ttyclose(&pccons);
17849573Swilliam return(0);
17941053Swilliam }
18041053Swilliam
18141053Swilliam /*ARGSUSED*/
pcread(dev,uio,flag)18249592Swilliam pcread(dev, uio, flag)
18341053Swilliam dev_t dev;
18441053Swilliam struct uio *uio;
18541053Swilliam {
18649592Swilliam return ((*linesw[pccons.t_line].l_read)(&pccons, uio, flag));
18741053Swilliam }
18841053Swilliam
18941053Swilliam /*ARGSUSED*/
pcwrite(dev,uio,flag)19049592Swilliam pcwrite(dev, uio, flag)
19141053Swilliam dev_t dev;
19241053Swilliam struct uio *uio;
19341053Swilliam {
19449592Swilliam return ((*linesw[pccons.t_line].l_write)(&pccons, uio, flag));
19541053Swilliam }
19641053Swilliam
19741053Swilliam /*
19841053Swilliam * Got a console receive interrupt -
19941053Swilliam * the console processor wants to give us a character.
20041053Swilliam * Catch the character, and see who it goes to.
20141053Swilliam */
pcrint(dev,irq,cpl)20249592Swilliam pcrint(dev, irq, cpl)
20341053Swilliam dev_t dev;
20441053Swilliam {
20541053Swilliam int c;
20641053Swilliam
20741053Swilliam c = sgetc(1);
20845535Sbill if (c&0x100) return;
20949592Swilliam if (pcconsoftc.cs_flags&CSF_POLLING)
21041053Swilliam return;
21141053Swilliam #ifdef KDB
21249592Swilliam if (kdbrintr(c, &pccons))
21341053Swilliam return;
21441053Swilliam #endif
21553643Sbostic if (openf) /* 386bsd */
21653643Sbostic (*linesw[pccons.t_line].l_rint)(c&0xff, &pccons);
21741053Swilliam }
21841053Swilliam
pcioctl(dev,cmd,data,flag,p)21952691Ssklower pcioctl(dev, cmd, data, flag, p)
22041053Swilliam dev_t dev;
22152691Ssklower int cmd, flag;
22249573Swilliam caddr_t data;
22352691Ssklower struct proc *p;
22441053Swilliam {
22549592Swilliam register struct tty *tp = &pccons;
22641053Swilliam register error;
22741053Swilliam
22852691Ssklower error = (*linesw[tp->t_line].l_ioctl)(tp, cmd, data, flag, p);
22941053Swilliam if (error >= 0)
23049573Swilliam return (error);
23149573Swilliam error = ttioctl(tp, cmd, data, flag);
23249573Swilliam if (error >= 0)
23349573Swilliam return (error);
23449573Swilliam return (ENOTTY);
23541053Swilliam }
23641053Swilliam
23749592Swilliam int pcconsintr = 1;
23841053Swilliam /*
23941053Swilliam * Got a console transmission interrupt -
24041053Swilliam * the console processor wants another character.
24141053Swilliam */
pcxint(dev)24249592Swilliam pcxint(dev)
24341053Swilliam dev_t dev;
24441053Swilliam {
24541053Swilliam register struct tty *tp;
24641053Swilliam register int unit;
24741053Swilliam
24849592Swilliam if (!pcconsintr)
24941053Swilliam return;
25049592Swilliam pccons.t_state &= ~TS_BUSY;
25149592Swilliam pcconsoftc.cs_timo = 0;
25249592Swilliam if (pccons.t_line)
25349592Swilliam (*linesw[pccons.t_line].l_start)(&pccons);
25441053Swilliam else
25549592Swilliam pcstart(&pccons);
25641053Swilliam }
25741053Swilliam
pcstart(tp)25849592Swilliam pcstart(tp)
25941053Swilliam register struct tty *tp;
26041053Swilliam {
26141053Swilliam register c, s;
26241053Swilliam
26341053Swilliam s = spltty();
26441053Swilliam if (tp->t_state & (TS_TIMEOUT|TS_BUSY|TS_TTSTOP))
26541053Swilliam goto out;
26649573Swilliam do {
26752659Storek if (tp->t_outq.c_cc <= tp->t_lowat) {
26852659Storek if (tp->t_state&TS_ASLEEP) {
26952659Storek tp->t_state &= ~TS_ASLEEP;
27052659Storek wakeup((caddr_t)&tp->t_outq);
27152659Storek }
27252659Storek selwakeup(&tp->t_wsel);
27341053Swilliam }
27452659Storek if (tp->t_outq.c_cc == 0)
27552659Storek goto out;
27652659Storek c = getc(&tp->t_outq);
27752659Storek splx(s);
27852659Storek sput(c, 0x7);
27952659Storek s = spltty();
28049573Swilliam } while(1);
28141053Swilliam out:
28241053Swilliam splx(s);
28341053Swilliam }
28441053Swilliam
28549592Swilliam pccnprobe(cp)
28649592Swilliam struct consdev *cp;
28749592Swilliam {
28849592Swilliam int maj;
28949592Swilliam extern int pcopen();
29049592Swilliam
29149592Swilliam /* locate the major number */
29249592Swilliam for (maj = 0; maj < nchrdev; maj++)
29349592Swilliam if (cdevsw[maj].d_open == pcopen)
29449592Swilliam break;
29549592Swilliam
29649592Swilliam /* initialize required fields */
29749592Swilliam cp->cn_dev = makedev(maj, 0);
29849592Swilliam cp->cn_tp = &pccons;
29949592Swilliam cp->cn_pri = CN_INTERNAL;
30049592Swilliam }
30149592Swilliam
30249592Swilliam /* ARGSUSED */
30349592Swilliam pccninit(cp)
30449592Swilliam struct consdev *cp;
30549592Swilliam {
30649592Swilliam /*
30749592Swilliam * For now, don't screw with it.
30849592Swilliam */
30949592Swilliam /* crtat = 0; */
31049592Swilliam }
31149592Swilliam
31249573Swilliam static __color;
31349573Swilliam
31449592Swilliam /* ARGSUSED */
pccnputc(dev,c)31549592Swilliam pccnputc(dev, c)
31649592Swilliam dev_t dev;
31741053Swilliam char c;
31849592Swilliam {
31949592Swilliam int clr = __color;
32049592Swilliam
32149592Swilliam if (clr == 0)
32249592Swilliam clr = 0x30;
32349592Swilliam else
32449592Swilliam clr |= 0x60;
32541053Swilliam if (c == '\n')
32649592Swilliam sput('\r', clr);
32749573Swilliam sput(c, clr);
32841053Swilliam }
32941053Swilliam
33041053Swilliam /*
33141053Swilliam * Print a character on console.
33241053Swilliam */
pcputchar(c,tp)33349592Swilliam pcputchar(c, tp)
33441053Swilliam char c;
33541053Swilliam register struct tty *tp;
33641053Swilliam {
33743589Sdonahn sput(c,0x2);
33841053Swilliam if (c=='\n') getchar();
33941053Swilliam }
34041053Swilliam
34141053Swilliam
34249592Swilliam /* ARGSUSED */
pccngetc(dev)34349592Swilliam pccngetc(dev)
34449592Swilliam dev_t dev;
34541053Swilliam {
34641053Swilliam register int c, s;
34741053Swilliam
34849592Swilliam s = spltty(); /* block pcrint while we poll */
34943589Sdonahn c = sgetc(0);
35043589Sdonahn if (c == '\r') c = '\n';
35141053Swilliam splx(s);
35241053Swilliam return (c);
35341053Swilliam }
35441053Swilliam
pcgetchar(tp)35549592Swilliam pcgetchar(tp)
35641053Swilliam register struct tty *tp;
35741053Swilliam {
35841053Swilliam int c;
35941053Swilliam
36041053Swilliam c = sgetc(0);
36141053Swilliam return (c&0xff);
36241053Swilliam }
36341053Swilliam
36441053Swilliam /*
36541053Swilliam * Set line parameters
36641053Swilliam */
pcparam(tp,t)36749592Swilliam pcparam(tp, t)
36841053Swilliam register struct tty *tp;
36949573Swilliam register struct termios *t;
37041053Swilliam {
37149573Swilliam register int cflag = t->c_cflag;
37249573Swilliam /* and copy to tty */
37349573Swilliam tp->t_ispeed = t->c_ispeed;
37449573Swilliam tp->t_ospeed = t->c_ospeed;
37549573Swilliam tp->t_cflag = cflag;
37649573Swilliam
37749573Swilliam return(0);
37841053Swilliam }
37941053Swilliam
38041053Swilliam #ifdef KDB
38141053Swilliam /*
38241053Swilliam * Turn input polling on/off (used by debugger).
38341053Swilliam */
pcpoll(onoff)38449592Swilliam pcpoll(onoff)
38541053Swilliam int onoff;
38641053Swilliam {
38741053Swilliam }
38841053Swilliam #endif
38941053Swilliam
39043589Sdonahn extern int hz;
39143589Sdonahn
39249573Swilliam static beeping;
sysbeepstop()39343589Sdonahn sysbeepstop()
39443589Sdonahn {
39543589Sdonahn /* disable counter 2 */
39643589Sdonahn outb(0x61,inb(0x61)&0xFC);
39749573Swilliam beeping = 0;
39843589Sdonahn }
39943589Sdonahn
sysbeep()40043589Sdonahn sysbeep()
40143589Sdonahn {
40249573Swilliam
40343589Sdonahn /* enable counter 2 */
40443589Sdonahn outb(0x61,inb(0x61)|3);
40543589Sdonahn /* set command for counter 2, 2 byte write */
40643589Sdonahn outb(0x43,0xB6);
40743589Sdonahn /* send 0x637 for 750 HZ */
40843589Sdonahn outb(0x42,0x37);
40943589Sdonahn outb(0x42,0x06);
41049573Swilliam if(!beeping)timeout(sysbeepstop,0,hz/4);
41149573Swilliam beeping = 1;
41243589Sdonahn }
41343589Sdonahn
41445535Sbill /* cursor() sets an offset (0-1999) into the 80x25 text area */
41541053Swilliam
41645535Sbill static u_short *crtat = 0;
41745535Sbill char bg_at = 0x0f;
41845535Sbill char so_at = 0x70;
41941053Swilliam
cursor()42045535Sbill cursor()
42145535Sbill { int pos = crtat - Crtat;
42241053Swilliam
42343589Sdonahn outb(addr_6845,14);
42443589Sdonahn outb(addr_6845+1,pos >> 8);
42543589Sdonahn outb(addr_6845,15);
42643589Sdonahn outb(addr_6845+1,pos&0xff);
42749573Swilliam timeout(cursor,0,hz/10);
42843589Sdonahn }
42943589Sdonahn
43049573Swilliam u_char shfts, ctls, alts, caps, num, stp, scroll;
43149573Swilliam
43249573Swilliam /*
43349573Swilliam * Compensate for abysmally stupid frame buffer aribitration with macro
43449573Swilliam */
43549573Swilliam #define wrtchar(c) { do *crtat = (c); while ((c) != *crtat); crtat++; row++; }
43649573Swilliam
43743589Sdonahn /* sput has support for emulation of the 'ibmpc' termcap entry. */
43843589Sdonahn /* This is a bare-bones implementation of a bare-bones entry */
43943589Sdonahn /* One modification: Change li#24 to li#25 to reflect 25 lines */
44043589Sdonahn
sput(c,ca)44143589Sdonahn sput(c, ca)
44243589Sdonahn u_char c, ca;
44343589Sdonahn {
44443589Sdonahn
44543589Sdonahn static int esc,ebrac,eparm,cx,cy,row,so;
44643589Sdonahn
44741053Swilliam if (crtat == 0) {
44845535Sbill u_short *cp = Crtat + (CGA_BUF-MONO_BUF)/CHR, was;
44945535Sbill unsigned cursorat;
45043589Sdonahn
45143589Sdonahn /* Crtat initialized to point to MONO buffer */
45243589Sdonahn /* if not present change to CGA_BUF offset */
45343589Sdonahn /* ONLY ADD the difference since locore.s adds */
45443589Sdonahn /* in the remapped offset at the right time */
45543589Sdonahn
45645535Sbill was = *cp;
45745535Sbill *cp = (u_short) 0xA55A;
45845535Sbill if (*cp != 0xA55A) {
45945535Sbill addr_6845 = MONO_BASE;
46045535Sbill } else {
46145535Sbill *cp = was;
46245535Sbill addr_6845 = CGA_BASE;
46343589Sdonahn Crtat = Crtat + (CGA_BUF-MONO_BUF)/CHR;
46445535Sbill }
46545535Sbill /* Extract cursor location */
46645535Sbill outb(addr_6845,14);
46745535Sbill cursorat = inb(addr_6845+1)<<8 ;
46845535Sbill outb(addr_6845,15);
46945535Sbill cursorat |= inb(addr_6845+1);
47045535Sbill
47145535Sbill crtat = Crtat + cursorat;
47245535Sbill fillw((bg_at<<8)|' ', crtat, COL*ROW-cursorat);
47341053Swilliam }
47441053Swilliam switch(c) {
47543589Sdonahn case 0x1B:
47643589Sdonahn esc = 1; ebrac = 0; eparm = 0;
47743589Sdonahn break;
47841053Swilliam
47941053Swilliam case '\t':
48041053Swilliam do {
48149573Swilliam wrtchar((ca<<8)| ' ');
48249573Swilliam } while (row % 8);
48341053Swilliam break;
48441053Swilliam
48541053Swilliam case '\010':
48641053Swilliam crtat--; row--;
48743589Sdonahn if (row < 0) row += COL; /* non-destructive backspace */
48841053Swilliam break;
48941053Swilliam
49041053Swilliam case '\r':
49143589Sdonahn crtat -= row ; row = 0;
49241053Swilliam break;
49341053Swilliam
49441053Swilliam case '\n':
49541053Swilliam crtat += COL ;
49641053Swilliam break;
49741053Swilliam
49841053Swilliam default:
49943589Sdonahn if (esc) {
50043589Sdonahn if (ebrac) {
50143589Sdonahn switch(c) {
50243589Sdonahn case 'm': /* no support for standout */
50343589Sdonahn if (!cx) so = 0;
50443589Sdonahn else so = 1;
50543589Sdonahn esc = 0; ebrac = 0; eparm = 0;
50643589Sdonahn break;
50743589Sdonahn case 'A': /* back one row */
50843589Sdonahn crtat -= COL;
50943589Sdonahn esc = 0; ebrac = 0; eparm = 0;
51043589Sdonahn break;
51143589Sdonahn case 'B': /* down one row */
51243589Sdonahn crtat += COL;
51343589Sdonahn esc = 0; ebrac = 0; eparm = 0;
51443589Sdonahn break;
51543589Sdonahn case 'C': /* right cursor */
51643589Sdonahn crtat++; row++;
51743589Sdonahn esc = 0; ebrac = 0; eparm = 0;
51843589Sdonahn break;
51943589Sdonahn case 'J': /* Clear to end of display */
52045535Sbill fillw((bg_at<<8)+' ', crtat,
52145535Sbill Crtat+COL*ROW-crtat);
52243589Sdonahn esc = 0; ebrac = 0; eparm = 0;
52343589Sdonahn break;
52443589Sdonahn case 'K': /* Clear to EOL */
52549573Swilliam fillw((bg_at<<8)+' ', crtat,
52649573Swilliam COL-(crtat-Crtat)%COL);
52743589Sdonahn esc = 0; ebrac = 0; eparm = 0;
52843589Sdonahn break;
52943589Sdonahn case 'H': /* Cursor move */
53043589Sdonahn if ((!cx)||(!cy)) {
53143589Sdonahn crtat = Crtat;
53243589Sdonahn row = 0;
53343589Sdonahn } else {
53443589Sdonahn crtat = Crtat+(cx-1)*COL+cy-1;
53543589Sdonahn row = cy-1;
53643589Sdonahn }
53743589Sdonahn esc = 0; ebrac = 0; eparm = 0;
53843589Sdonahn break;
53943589Sdonahn case ';': /* Switch params in cursor def */
54043589Sdonahn eparm = 1;
54143589Sdonahn return;
54243589Sdonahn default: /* Only numbers valid here */
54343589Sdonahn if ((c >= '0')&&(c <= '9')) {
54443589Sdonahn if (eparm) {
54543589Sdonahn cy *= 10;
54643589Sdonahn cy += c - '0';
54743589Sdonahn } else {
54843589Sdonahn cx *= 10;
54943589Sdonahn cx += c - '0';
55043589Sdonahn }
55143589Sdonahn } else {
55243589Sdonahn esc = 0; ebrac = 0; eparm = 0;
55343589Sdonahn }
55443589Sdonahn return;
55543589Sdonahn }
55643589Sdonahn break;
55743589Sdonahn } else if (c == 'c') { /* Clear screen & home */
55845535Sbill fillw((bg_at<<8)+' ', Crtat,COL*ROW);
55943589Sdonahn crtat = Crtat; row = 0;
56043589Sdonahn esc = 0; ebrac = 0; eparm = 0;
56145535Sbill } else if (c == '[') { /* Start ESC [ sequence */
56243589Sdonahn ebrac = 1; cx = 0; cy = 0; eparm = 0;
56345535Sbill } else { /* Invalid, clear state */
56443589Sdonahn esc = 0; ebrac = 0; eparm = 0;
56543589Sdonahn }
56643589Sdonahn } else {
56749573Swilliam if (c == 7)
56843589Sdonahn sysbeep();
56943589Sdonahn /* Print only printables */
57045535Sbill else /*if (c >= ' ') */ {
57143589Sdonahn if (so) {
57249573Swilliam wrtchar((so_at<<8)| c);
57343589Sdonahn } else {
57449573Swilliam wrtchar((ca<<8)| c);
57543589Sdonahn }
57643589Sdonahn if (row >= COL) row = 0;
57743589Sdonahn break ;
57843589Sdonahn }
57941053Swilliam }
58041053Swilliam }
58143589Sdonahn if (crtat >= Crtat+COL*(ROW)) { /* scroll check */
58249573Swilliam if (openf) do sgetc(1); while (scroll);
58343589Sdonahn bcopy(Crtat+COL,Crtat,COL*(ROW-1)*CHR);
58449573Swilliam fillw ((bg_at<<8) + ' ', Crtat+COL*(ROW-1),COL) ;
58543589Sdonahn crtat -= COL ;
58643589Sdonahn }
58741053Swilliam }
58843589Sdonahn
58941053Swilliam #define L 0x0001 /* locking function */
59041053Swilliam #define SHF 0x0002 /* keyboard shift */
59141053Swilliam #define ALT 0x0004 /* alternate shift -- alternate chars */
59241053Swilliam #define NUM 0x0008 /* numeric shift cursors vs. numeric */
59341053Swilliam #define CTL 0x0010 /* control shift -- allows ctl function */
59441053Swilliam #define CPS 0x0020 /* caps shift -- swaps case of letter */
59541053Swilliam #define ASCII 0x0040 /* ascii code for this key */
59641053Swilliam #define STP 0x0080 /* stop output */
59741053Swilliam #define FUNC 0x0100 /* function key */
59843589Sdonahn #define SCROLL 0x0200 /* scroll lock key */
59941053Swilliam
60049695Swilliam unsigned __debug = 0; /*0xffe */;
60141053Swilliam u_short action[] = {
60241053Swilliam 0, ASCII, ASCII, ASCII, ASCII, ASCII, ASCII, ASCII, /* scan 0- 7 */
60341053Swilliam ASCII, ASCII, ASCII, ASCII, ASCII, ASCII, ASCII, ASCII, /* scan 8-15 */
60441053Swilliam ASCII, ASCII, ASCII, ASCII, ASCII, ASCII, ASCII, ASCII, /* scan 16-23 */
60541053Swilliam ASCII, ASCII, ASCII, ASCII, ASCII, CTL, ASCII, ASCII, /* scan 24-31 */
60641053Swilliam ASCII, ASCII, ASCII, ASCII, ASCII, ASCII, ASCII, ASCII, /* scan 32-39 */
60741053Swilliam ASCII, ASCII, SHF , ASCII, ASCII, ASCII, ASCII, ASCII, /* scan 40-47 */
60841053Swilliam ASCII, ASCII, ASCII, ASCII, ASCII, ASCII, SHF, ASCII, /* scan 48-55 */
60943589Sdonahn ALT, ASCII, CPS , FUNC , FUNC , FUNC , FUNC , FUNC , /* scan 56-63 */
61049573Swilliam FUNC , FUNC , FUNC , FUNC , FUNC , NUM, SCROLL, ASCII, /* scan 64-71 */
61141053Swilliam ASCII, ASCII, ASCII, ASCII, ASCII, ASCII, ASCII, ASCII, /* scan 72-79 */
61241053Swilliam ASCII, ASCII, ASCII, ASCII, 0, 0, 0, 0, /* scan 80-87 */
61341053Swilliam 0,0,0,0,0,0,0,0,
61441053Swilliam 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,
61541053Swilliam 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, } ;
61641053Swilliam
61741053Swilliam u_char unshift[] = { /* no shift */
61841053Swilliam 0, 033 , '1' , '2' , '3' , '4' , '5' , '6' , /* scan 0- 7 */
61941053Swilliam '7' , '8' , '9' , '0' , '-' , '=' , 0177 ,'\t' , /* scan 8-15 */
62041053Swilliam
62141053Swilliam 'q' , 'w' , 'e' , 'r' , 't' , 'y' , 'u' , 'i' , /* scan 16-23 */
62241053Swilliam 'o' , 'p' , '[' , ']' , '\r' , CTL , 'a' , 's' , /* scan 24-31 */
62341053Swilliam
62441053Swilliam 'd' , 'f' , 'g' , 'h' , 'j' , 'k' , 'l' , ';' , /* scan 32-39 */
62541053Swilliam '\'' , '`' , SHF , '\\' , 'z' , 'x' , 'c' , 'v' , /* scan 40-47 */
62641053Swilliam
62741053Swilliam 'b' , 'n' , 'm' , ',' , '.' , '/' , SHF , '*', /* scan 48-55 */
62843589Sdonahn ALT , ' ' , CPS, 1, 2, 3 , 4, 5, /* scan 56-63 */
62941053Swilliam
63043589Sdonahn 6, 7, 8, 9, 10, NUM, STP, '7', /* scan 64-71 */
63141053Swilliam '8', '9', '-', '4', '5', '6', '+', '1', /* scan 72-79 */
63241053Swilliam
63341053Swilliam '2', '3', '0', '.', 0, 0, 0, 0, /* scan 80-87 */
63441053Swilliam 0,0,0,0,0,0,0,0,
63541053Swilliam 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,
63641053Swilliam 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, } ;
63741053Swilliam
63841053Swilliam u_char shift[] = { /* shift shift */
63941053Swilliam 0, 033 , '!' , '@' , '#' , '$' , '%' , '^' , /* scan 0- 7 */
64041053Swilliam '&' , '*' , '(' , ')' , '_' , '+' , 0177 ,'\t' , /* scan 8-15 */
64141053Swilliam 'Q' , 'W' , 'E' , 'R' , 'T' , 'Y' , 'U' , 'I' , /* scan 16-23 */
64241053Swilliam 'O' , 'P' , '{' , '}' , '\r' , CTL , 'A' , 'S' , /* scan 24-31 */
64341053Swilliam 'D' , 'F' , 'G' , 'H' , 'J' , 'K' , 'L' , ':' , /* scan 32-39 */
64441053Swilliam '"' , '~' , SHF , '|' , 'Z' , 'X' , 'C' , 'V' , /* scan 40-47 */
64541053Swilliam 'B' , 'N' , 'M' , '<' , '>' , '?' , SHF , '*', /* scan 48-55 */
64643589Sdonahn ALT , ' ' , CPS, 0, 0, ' ' , 0, 0, /* scan 56-63 */
64743589Sdonahn 0, 0, 0, 0, 0, NUM, STP, '7', /* scan 64-71 */
64841053Swilliam '8', '9', '-', '4', '5', '6', '+', '1', /* scan 72-79 */
64941053Swilliam '2', '3', '0', '.', 0, 0, 0, 0, /* scan 80-87 */
65041053Swilliam 0,0,0,0,0,0,0,0,
65141053Swilliam 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,
65241053Swilliam 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, } ;
65341053Swilliam
65441053Swilliam u_char ctl[] = { /* CTL shift */
65541053Swilliam 0, 033 , '!' , 000 , '#' , '$' , '%' , 036 , /* scan 0- 7 */
65641053Swilliam '&' , '*' , '(' , ')' , 037 , '+' , 034 ,'\177', /* scan 8-15 */
65741053Swilliam 021 , 027 , 005 , 022 , 024 , 031 , 025 , 011 , /* scan 16-23 */
65841053Swilliam 017 , 020 , 033 , 035 , '\r' , CTL , 001 , 023 , /* scan 24-31 */
65941053Swilliam 004 , 006 , 007 , 010 , 012 , 013 , 014 , ';' , /* scan 32-39 */
66041053Swilliam '\'' , '`' , SHF , 034 , 032 , 030 , 003 , 026 , /* scan 40-47 */
66141053Swilliam 002 , 016 , 015 , '<' , '>' , '?' , SHF , '*', /* scan 48-55 */
66243589Sdonahn ALT , ' ' , CPS, 0, 0, ' ' , 0, 0, /* scan 56-63 */
66343589Sdonahn CPS, 0, 0, 0, 0, 0, 0, 0, /* scan 64-71 */
66441053Swilliam 0, 0, 0, 0, 0, 0, 0, 0, /* scan 72-79 */
66541053Swilliam 0, 0, 0, 0, 0, 0, 0, 0, /* scan 80-87 */
66643589Sdonahn 0, 0, 033, '7' , '4' , '1' , 0, NUM, /* scan 88-95 */
66743589Sdonahn '8' , '5' , '2' , 0, STP, '9' , '6' , '3' , /*scan 96-103*/
66841053Swilliam '.' , 0, '*' , '-' , '+' , 0, 0, 0, /*scan 104-111*/
66941053Swilliam 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, } ;
67041053Swilliam
67141053Swilliam #ifdef notdef
67241053Swilliam struct key {
67341053Swilliam u_short action; /* how this key functions */
67441053Swilliam char ascii[8]; /* ascii result character indexed by shifts */
67541053Swilliam };
67641053Swilliam #endif
67741053Swilliam
67841053Swilliam
67943589Sdonahn #define KBSTAT 0x64 /* kbd status port */
68043589Sdonahn #define KBS_INP_BUF_FUL 0x02 /* kbd char ready */
68143589Sdonahn #define KBDATA 0x60 /* kbd data port */
68241053Swilliam #define KBSTATUSPORT 0x61 /* kbd status */
68341053Swilliam
update_led()68443589Sdonahn update_led()
68543589Sdonahn {
68643589Sdonahn while (inb(0x64)&2); /* wait input ready */
68743589Sdonahn outb(0x60,0xED); /* LED Command */
68843589Sdonahn while (inb(0x64)&2); /* wait input ready */
68943589Sdonahn outb(0x60,scroll | 2*num | 4*caps);
69043589Sdonahn }
69141053Swilliam
reset_cpu()69245535Sbill reset_cpu() {
69345535Sbill while(1) {
69445535Sbill while (inb(0x64)&2); /* wait input ready */
69545535Sbill outb(0x64,0xFE); /* Reset Command */
69645535Sbill DELAY(4000000);
69745535Sbill while (inb(0x64)&2); /* wait input ready */
69845535Sbill outb(0x64,0xFF); /* Keyboard Reset Command */
69945535Sbill }
70045535Sbill /* NOTREACHED */
70145535Sbill }
70245535Sbill
70343589Sdonahn /*
70443589Sdonahn sgetc(noblock) : get a character from the keyboard. If noblock = 0 wait until
70543589Sdonahn a key is gotten. Otherwise return a 0x100 (256).
70643589Sdonahn */
sgetc(noblock)70743589Sdonahn int sgetc(noblock)
70843589Sdonahn {
70943589Sdonahn u_char dt; unsigned key;
71041053Swilliam loop:
71143589Sdonahn /* First see if there is something in the keyboard port */
71243589Sdonahn if (inb(KBSTAT)&1) dt = inb(KBDATA);
71343589Sdonahn else { if (noblock) return (0x100); else goto loop; }
71441053Swilliam
71543589Sdonahn /* Check for cntl-alt-del */
71643589Sdonahn if ((dt == 83)&&ctls&&alts) _exit();
71741053Swilliam
71843589Sdonahn /* Check for make/break */
71943589Sdonahn if (dt & 0x80) {
72043589Sdonahn /* break */
72143589Sdonahn dt = dt & 0x7f ;
72243589Sdonahn switch (action[dt]) {
72343589Sdonahn case SHF: shfts = 0; break;
72443589Sdonahn case ALT: alts = 0; break;
72543589Sdonahn case CTL: ctls = 0; break;
72643589Sdonahn case FUNC:
72743589Sdonahn /* Toggle debug flags */
72843589Sdonahn key = unshift[dt];
72943589Sdonahn if(__debug & (1<<key)) __debug &= ~(1<<key) ;
73043589Sdonahn else __debug |= (1<<key) ;
73143589Sdonahn break;
73241053Swilliam }
73343589Sdonahn } else {
73443589Sdonahn /* make */
73543589Sdonahn dt = dt & 0x7f ;
73643589Sdonahn switch (action[dt]) {
73743589Sdonahn /* LOCKING KEYS */
73843589Sdonahn case NUM: num ^= 1; update_led(); break;
73943589Sdonahn case CPS: caps ^= 1; update_led(); break;
74043589Sdonahn case SCROLL: scroll ^= 1; update_led(); break;
74143589Sdonahn case STP: stp ^= 1; if(stp) goto loop; break;
74243589Sdonahn
74343589Sdonahn /* NON-LOCKING KEYS */
74443589Sdonahn case SHF: shfts = 1; break;
74543589Sdonahn case ALT: alts = 1; break;
74643589Sdonahn case CTL: ctls = 1; break;
74743589Sdonahn case ASCII:
74843589Sdonahn if (shfts) dt = shift[dt];
74943589Sdonahn else if (ctls) dt = ctl[dt];
75043589Sdonahn else dt = unshift[dt];
75143589Sdonahn if (caps && (dt >= 'a' && dt <= 'z')) dt -= 'a' - 'A';
75243589Sdonahn return(dt);
75343589Sdonahn }
75441053Swilliam }
75543589Sdonahn if (noblock) return (0x100); else goto loop;
75641053Swilliam }
75741053Swilliam
pg(p,q,r,s,t,u,v,w,x,y,z)75841053Swilliam pg(p,q,r,s,t,u,v,w,x,y,z) char *p; {
75941053Swilliam printf(p,q,r,s,t,u,v,w,x,y,z);
76041053Swilliam printf("\n");
76141053Swilliam return(getchar());
76241053Swilliam }
76341053Swilliam
76441053Swilliam /* special characters */
76541053Swilliam #define bs 8
76641053Swilliam #define lf 10
76741053Swilliam #define cr 13
76841053Swilliam #define cntlc 3
76941053Swilliam #define del 0177
77041053Swilliam #define cntld 4
77141053Swilliam
getchar()77241053Swilliam getchar()
77341053Swilliam {
77441053Swilliam register char thechar;
77541053Swilliam register delay;
77641053Swilliam int x;
77741053Swilliam
77849592Swilliam pcconsoftc.cs_flags |= CSF_POLLING;
77941053Swilliam x=splhigh();
78043589Sdonahn sput('>',0x6);
78145535Sbill /*while (1) {*/
78241053Swilliam thechar = (char) sgetc(0);
78349592Swilliam pcconsoftc.cs_flags &= ~CSF_POLLING;
78443589Sdonahn splx(x);
78541053Swilliam switch (thechar) {
78641053Swilliam default: if (thechar >= ' ')
78743589Sdonahn sput(thechar,0x6);
78841053Swilliam return(thechar);
78941053Swilliam case cr:
79043589Sdonahn case lf: sput(cr,0x6);
79143589Sdonahn sput(lf,0x6);
79241053Swilliam return(lf);
79341053Swilliam case bs:
79441053Swilliam case del:
79543589Sdonahn sput(bs,0x6);
79643589Sdonahn sput(' ',0x6);
79743589Sdonahn sput(bs,0x6);
79841053Swilliam return(thechar);
79943589Sdonahn /*case cntlc:
80041053Swilliam sput('^',0xe) ; sput('C',0xe) ; sput('\r',0xe) ; sput('\n',0xe) ;
80143589Sdonahn _exit(-2) ; */
80241053Swilliam case cntld:
80343589Sdonahn sput('^',0x6) ; sput('D',0x6) ; sput('\r',0x6) ; sput('\n',0x6) ;
80441053Swilliam return(0);
80541053Swilliam }
80645535Sbill /*}*/
80741053Swilliam }
80849573Swilliam
80956513Sbostic #include <machine/dbg.h>
81056513Sbostic #include <machine/stdarg.h>
81149573Swilliam static nrow;
81249573Swilliam
81349573Swilliam void
81449573Swilliam #ifdef __STDC__
dprintf(unsigned flgs,const char * fmt,...)81549573Swilliam dprintf(unsigned flgs, const char *fmt, ...)
81649573Swilliam #else
81749573Swilliam dprintf(flgs, fmt /*, va_alist */)
81849573Swilliam char *fmt;
81949573Swilliam unsigned flgs;
82049573Swilliam #endif
82149573Swilliam { extern unsigned __debug;
82249573Swilliam va_list ap;
82349573Swilliam
82449573Swilliam if((flgs&__debug) > DPAUSE) {
82549573Swilliam __color = ffs(flgs&__debug)+1;
82649573Swilliam va_start(ap,fmt);
82749573Swilliam kprintf(fmt, 1, (struct tty *)0, ap);
82849573Swilliam va_end(ap);
82949573Swilliam if (flgs&DPAUSE || nrow%24 == 23) {
83049573Swilliam int x;
83149573Swilliam x = splhigh();
83249573Swilliam if (nrow%24 == 23) nrow = 0;
83349573Swilliam sgetc(0);
83449573Swilliam splx(x);
83549573Swilliam }
83649573Swilliam }
83749573Swilliam __color = 0;
83849573Swilliam }
83949573Swilliam
consinit()84049573Swilliam consinit() {}
841