📄 pccons.c
字号:
/*- * Copyright (c) 1990, 1993 * The Regents of the University of California. All rights reserved. * * This code is derived from software contributed to Berkeley by * William Jolitz and Don Ahn. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by the University of * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * * @(#)pccons.c 8.1 (Berkeley) 6/11/93 *//* * code to work keyboard & display for PC-style console */#include <sys/param.h>#include <sys/conf.h>#include <sys/ioctl.h>#include <sys/proc.h>#include <sys/user.h>#include <sys/tty.h>#include <sys/uio.h>#include <sys/callout.h>#include <sys/systm.h>#include <sys/kernel.h>#include <sys/syslog.h>#include <i386/isa/isa_device.h>#include <i386/isa/icu.h>#include <i386/i386/cons.h>struct tty pccons;struct pcconsoftc { char cs_flags;#define CSF_ACTIVE 0x1 /* timeout active */#define CSF_POLLING 0x2 /* polling for input */ char cs_lastc; /* last char sent */ int cs_timo; /* timeouts since interrupt */ u_long cs_wedgecnt; /* times restarted */} pcconsoftc;int pcprobe(), pcattach();struct isa_driver pcdriver = { pcprobe, pcattach, "pc",};#define COL 80#define ROW 25#define CHR 2#define MONO_BASE 0x3B4#define MONO_BUF 0xfe0B0000#define CGA_BASE 0x3D4#define CGA_BUF 0xfe0B8000#define IOPHYSMEM 0xA0000u_char color = 0xe ;static unsigned int addr_6845 = MONO_BASE;u_short *Crtat = (u_short *)MONO_BUF;static openf;/* * We check the console periodically to make sure * that it hasn't wedged. Unfortunately, if an XOFF * is typed on the console, that can't be distinguished * from more catastrophic failure. */#define CN_TIMERVAL (hz) /* frequency at which to check cons */#define CN_TIMO (2*60) /* intervals to allow for output char */int pcstart();int pcparam();int ttrstrt();char partab[];/* * Wait for CP to accept last CP command sent * before setting up next command. */#define waitforlast(timo) { \ if (pclast) { \ (timo) = 10000; \ do \ uncache((char *)&pclast->cp_unit); \ while ((pclast->cp_unit&CPTAKE) == 0 && --(timo)); \ } \}u_char inb();pcprobe(dev)struct isa_device *dev;{ u_char c; int again = 0; /* Enable interrupts and keyboard controller */ while (inb(0x64)&2); outb(0x64,0x60); while (inb(0x64)&2); outb(0x60,0x4D); /* Start keyboard stuff RESET */ while (inb(0x64)&2); /* wait input ready */ outb(0x60,0xFF); /* RESET */ while((c=inb(0x60))!=0xFA) { if ((c == 0xFE) || (c == 0xFF)) { if(!again)printf("KEYBOARD disconnected: RECONNECT \n"); while (inb(0x64)&2); /* wait input ready */ outb(0x60,0xFF); /* RESET */ again = 1; } } /* pick up keyboard reset return code */ while((c=inb(0x60))!=0xAA); return 1;}pcattach(dev)struct isa_device *dev;{ u_short *cp = Crtat + (CGA_BUF-MONO_BUF)/CHR; u_short was; /* Crtat initialized to point to MONO buffer */ /* if not present change to CGA_BUF offset */ /* ONLY ADD the difference since locore.s adds */ /* in the remapped offset at the right time */ was = *Crtat; *Crtat = (u_short) 0xA55A; if (*Crtat != 0xA55A) printf("<mono>"); else printf("<color>"); *Crtat = was; cursor();}/* ARGSUSED */#ifdef __STDC__pcopen(dev_t dev, int flag, int mode, struct proc *p)#elsepcopen(dev, flag, mode, p) dev_t dev; int flag, mode; struct proc *p;#endif{ register struct tty *tp; tp = &pccons; tp->t_oproc = pcstart; tp->t_param = pcparam; tp->t_dev = dev; openf++; if ((tp->t_state & TS_ISOPEN) == 0) { tp->t_state |= TS_WOPEN; ttychars(tp); tp->t_iflag = TTYDEF_IFLAG; tp->t_oflag = TTYDEF_OFLAG; tp->t_cflag = TTYDEF_CFLAG; tp->t_lflag = TTYDEF_LFLAG; tp->t_ispeed = tp->t_ospeed = TTYDEF_SPEED; pcparam(tp, &tp->t_termios); ttsetwater(tp); } else if (tp->t_state&TS_XCLUDE && p->p_ucred->cr_uid != 0) return (EBUSY); tp->t_state |= TS_CARR_ON; return ((*linesw[tp->t_line].l_open)(dev, tp));}pcclose(dev, flag, mode, p) dev_t dev; int flag, mode; struct proc *p;{ (*linesw[pccons.t_line].l_close)(&pccons, flag); ttyclose(&pccons); return(0);}/*ARGSUSED*/pcread(dev, uio, flag) dev_t dev; struct uio *uio;{ return ((*linesw[pccons.t_line].l_read)(&pccons, uio, flag));}/*ARGSUSED*/pcwrite(dev, uio, flag) dev_t dev; struct uio *uio;{ return ((*linesw[pccons.t_line].l_write)(&pccons, uio, flag));}/* * Got a console receive interrupt - * the console processor wants to give us a character. * Catch the character, and see who it goes to. */pcrint(dev, irq, cpl) dev_t dev;{ int c; c = sgetc(1); if (c&0x100) return; if (pcconsoftc.cs_flags&CSF_POLLING) return;#ifdef KDB if (kdbrintr(c, &pccons)) return;#endif if (openf) /* 386bsd */ (*linesw[pccons.t_line].l_rint)(c&0xff, &pccons);}pcioctl(dev, cmd, data, flag, p) dev_t dev; int cmd, flag; caddr_t data; struct proc *p;{ register struct tty *tp = &pccons; register error; error = (*linesw[tp->t_line].l_ioctl)(tp, cmd, data, flag, p); if (error >= 0) return (error); error = ttioctl(tp, cmd, data, flag); if (error >= 0) return (error); return (ENOTTY);}int pcconsintr = 1;/* * Got a console transmission interrupt - * the console processor wants another character. */pcxint(dev) dev_t dev;{ register struct tty *tp; register int unit; if (!pcconsintr) return; pccons.t_state &= ~TS_BUSY; pcconsoftc.cs_timo = 0; if (pccons.t_line) (*linesw[pccons.t_line].l_start)(&pccons); else pcstart(&pccons);}pcstart(tp) register struct tty *tp;{ register c, s; s = spltty(); if (tp->t_state & (TS_TIMEOUT|TS_BUSY|TS_TTSTOP)) goto out; do { if (tp->t_outq.c_cc <= tp->t_lowat) { if (tp->t_state&TS_ASLEEP) { tp->t_state &= ~TS_ASLEEP; wakeup((caddr_t)&tp->t_outq); } selwakeup(&tp->t_wsel); } if (tp->t_outq.c_cc == 0) goto out; c = getc(&tp->t_outq); splx(s); sput(c, 0x7); s = spltty(); } while(1);out: splx(s);}pccnprobe(cp) struct consdev *cp;{ int maj; extern int pcopen(); /* locate the major number */ for (maj = 0; maj < nchrdev; maj++) if (cdevsw[maj].d_open == pcopen) break; /* initialize required fields */ cp->cn_dev = makedev(maj, 0); cp->cn_tp = &pccons; cp->cn_pri = CN_INTERNAL;}/* ARGSUSED */pccninit(cp) struct consdev *cp;{ /* * For now, don't screw with it. */ /* crtat = 0; */}static __color;/* ARGSUSED */pccnputc(dev, c) dev_t dev; char c;{ int clr = __color; if (clr == 0) clr = 0x30; else clr |= 0x60; if (c == '\n') sput('\r', clr); sput(c, clr);}/* * Print a character on console. */pcputchar(c, tp) char c; register struct tty *tp;{ sput(c,0x2); if (c=='\n') getchar();}/* ARGSUSED */pccngetc(dev) dev_t dev;{ register int c, s; s = spltty(); /* block pcrint while we poll */ c = sgetc(0); if (c == '\r') c = '\n'; splx(s); return (c);}pcgetchar(tp) register struct tty *tp;{ int c; c = sgetc(0); return (c&0xff);}/* * Set line parameters */pcparam(tp, t) register struct tty *tp; register struct termios *t;{ register int cflag = t->c_cflag; /* and copy to tty */ tp->t_ispeed = t->c_ispeed; tp->t_ospeed = t->c_ospeed; tp->t_cflag = cflag; return(0);}#ifdef KDB/* * Turn input polling on/off (used by debugger). */pcpoll(onoff) int onoff;{}#endifextern int hz;static beeping;sysbeepstop(){ /* disable counter 2 */ outb(0x61,inb(0x61)&0xFC); beeping = 0;}sysbeep(){ /* enable counter 2 */ outb(0x61,inb(0x61)|3); /* set command for counter 2, 2 byte write */ outb(0x43,0xB6); /* send 0x637 for 750 HZ */ outb(0x42,0x37);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -