📄 qv.c
字号:
/* * Copyright (c) 1988 * The Regents of the University of California. All rights reserved. * (c) UNIX System Laboratories, Inc. * All or some portions of this file are derived from material licensed * to the University of California by American Telephone and Telegraph * Co. or Unix System Laboratories, Inc. and are reproduced herein with * the permission of UNIX System Laboratories, Inc. * * 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. * * @(#)qv.c 7.2 (Berkeley) 1/21/94 *//* * derived from: @(#)qv.c 1.8 (ULTRIX) 8/21/85 *//************************************************************************ * * * Copyright (c) 1985 by * * Digital Equipment Corporation, Maynard, MA * * All rights reserved. * * * * This software is furnished under a license and may be used and * * copied only in accordance with the terms of such license and * * with the inclusion of the above copyright notice. This * * software or any other copies thereof may not be provided or * * otherwise made available to any other person. No title to and * * ownership of the software is hereby transferred. * * * * This software is derived from software received from the * * University of California, Berkeley, and from Bell * * Laboratories. Use, duplication, or disclosure is subject to * * restrictions under license agreements with University of * * California and with AT&T. * * * * The information in this software is subject to change without * * notice and should not be construed as a commitment by Digital * * Equipment Corporation. * * * * Digital assumes no responsibility for the use or reliability * * of its software on equipment which is not supplied by Digital. * * * ************************************************************************ * * This driver provides glass tty functionality to the qvss. It is a strange * device in that it supports three subchannels. The first being the asr, * the second being a channel that intercepts the chars headed for the screen * ( like a pseudo tty ) and the third being a source of mouse state changes. * NOTE: the second is conditional on #ifdef CONS_HACK in this version * of the driver, as it's a total crock. * * There may be one and only one qvss in the system. This restriction is based * on the inability to map more than one at a time. This restriction will * exist until the kernel has shared memory services. This driver therefore * support a single unit. No attempt was made to have it service more. * * (this belongs in sccs - not here) * * 02 Aug 85 -- rjl * Changed the names of the special setup routines so that the system * can have a qvss or a qdss system console. * * 03 Jul 85 -- rjl * Added a check for virtual mode in qvputc so that the driver * doesn't crash while in a dump which is done in physical mode. * * 10 Apr 85 -- jg * Well, our theory about keyboard handling was wrong; most of the * keyboard is in autorepeat, down mode. These changes are to make * the qvss work the same as the Vs100, which is not necessarily * completely correct, as some chord usage may fail. But since we * can't easily change the Vs100, we might as well propagate the * problem to another device. There are also changes for screen and * mouse accellaration. * * 27 Mar 85 -- rjl * MicroVAX-II systems have interval timers that interrupt at ipl4. * Everything else is higher and thus causes us to miss clock ticks. The * problem isn't severe except in the case of a device like this one that * generates lots of interrupts. We aren't willing to make this change to * all device drivers but it seems acceptable in this case. * * 3 Dec 84 -- jg * To continue the tradition of building a better mouse trap, this * driver has been extended to form Vs100 style event queues. If the * mouse device is open, the keyboard events are intercepted and put * into the shared memory queue. Unfortunately, we are ending up with * one of the longest Unix device drivers. Sigh.... * * 20 Nov 84 -- rjl * As a further complication this driver is required to function as the * virtual system console. This code runs before and during auto- * configuration and therefore is require to have a second path for setup. * It is futher constrained to have a character output routine that * is not dependant on the interrupt system. * */#include "qv.h"#if NQV > 0#include "../include/pte.h"#include "sys/param.h"#include "sys/conf.h"#include "sys/user.h"#include "qvioctl.h"#include "sys/tty.h"#include "sys/map.h"#include "sys/buf.h"#include "sys/vm.h"#include "sys/clist.h"#include "sys/file.h"#include "sys/uio.h"#include "sys/kernel.h"#include "sys/syslog.h"#include "../include/cpu.h"#include "../include/mtpr.h"#include "ubareg.h"#include "ubavar.h"#define CONS_HACKstruct uba_device *qvinfo[NQV];struct tty qv_tty[NQV*4];#define nNQV NQVint nqv = NQV*4;/* * Definition of the driver for the auto-configuration program. */int qvprobe(), qvattach(), qvkint(), qvvint();u_short qvstd[] = { 0 };struct uba_driver qvdriver = { qvprobe, 0, qvattach, 0, qvstd, "qv", qvinfo };extern char qvmem[][512*NBPG];extern struct pte QVmap[][512];/* * Local variables for the driver. Initialized for 15' screen * so that it can be used during the boot process. */#define QVWAITPRI (PZERO+1)#define QVSSMAJOR 40#define QVKEYBOARD 0 /* minor 0, keyboard/glass tty */#define QVPCONS 1 /* minor 1, console interceptor XXX */#define QVMOUSECHAN 2 /* minor 2, mouse */#define QVSPARE 3 /* unused */#define QVCHAN(unit) ((unit) & 03)/* * v_putc is the switch that is used to redirect the console cnputc to the * virtual console vputc. consops is used to redirect the console * device to the qvss console. */extern (*v_putc)();extern struct cdevsw *consops;/* * qv_def_scrn is used to select the appropriate tables. 0=15 inch 1=19 inch, * 2 = uVAXII. */int qv_def_scrn = 2;#define QVMAXEVQ 64 /* must be power of 2 */#define EVROUND(x) ((x) & (QVMAXEVQ - 1))/* * Screen parameters 15 & 19 inch monitors. These determine the max size in * pixel and character units for the display and cursor positions. * Notice that the mouse defaults to original square algorithm, but X * will change to its defaults once implemented. */struct qv_info *qv_scn;struct qv_info qv_scn_defaults[] = { {0, {0, 0}, 0, {0, 0}, 0, 0, 30, 80, 768, 480, 768-16, 480-16, 0, 0, 0, 0, 0, QVMAXEVQ, 0, 0, {0, 0}, {0, 0, 0, 0}, 2, 4}, {0, {0, 0}, 0, {0, 0}, 0, 0, 55, 120, 960, 864, 960-16, 864-16, 0, 0, 0, 0, 0, QVMAXEVQ, 0, 0, {0, 0}, {0, 0, 0, 0}, 2, 4}, {0, {0, 0}, 0, {0, 0}, 0, 0, 56, 120,1024, 864,1024-16, 864-16, 0, 0, 0, 0, 0, QVMAXEVQ, 0, 0, {0, 0}, {0, 0, 0, 0}, 2, 4}};/* * Screen controller initialization parameters. The definations and use * of these parameters can be found in the Motorola 68045 crtc specs. In * essence they set the display parameters for the chip. The first set is * for the 15" screen and the second is for the 19" seperate sync. There * is also a third set for a 19" composite sync monitor which we have not * tested and which is not supported. */static short qv_crt_parms[][16] = { { 31, 25, 27, 0142, 31, 13, 30, 31, 4, 15, 040, 0, 0, 0, 0, 0 },/* VR100*/ { 39, 30, 32, 0262, 55, 5, 54, 54, 4, 15, 040, 0, 0, 0, 0, 0 },/* VR260*/ { 39, 32, 33, 0264, 56, 5, 54, 54, 4, 15, 040, 0, 0, 0, 0, 0},};/* * Screen parameters */struct qv_info *qv_scn;int maxqvmem = 254*1024 - sizeof(struct qv_info) - QVMAXEVQ*sizeof(vsEvent); /* * Keyboard state */struct qv_keyboard { int shift; /* state variables */ int cntrl; int lock; char last; /* last character */} qv_keyboard;short divdefaults[15] = { LK_DOWN, /* 0 doesn't exist */ LK_AUTODOWN, LK_AUTODOWN, LK_AUTODOWN, LK_DOWN, LK_UPDOWN, LK_UPDOWN, LK_AUTODOWN, LK_AUTODOWN, LK_AUTODOWN, LK_AUTODOWN, LK_AUTODOWN, LK_AUTODOWN, LK_DOWN, LK_AUTODOWN };short kbdinitstring[] = { /* reset any random keyboard stuff */ LK_AR_ENABLE, /* we want autorepeat by default */ LK_CL_ENABLE, /* keyclick */ 0x84, /* keyclick volume */ LK_KBD_ENABLE, /* the keyboard itself */ LK_BELL_ENABLE, /* keyboard bell */ 0x84, /* bell volume */ LK_LED_DISABLE, /* keyboard leds */ LED_ALL };#define KBD_INIT_LENGTH sizeof(kbdinitstring)/sizeof(short)#define TOY ((time.tv_sec * 100) + (time.tv_usec / 10000))int qv_ipl_lo = 1; /* IPL low flag */int mouseon = 0; /* mouse channel is enabled when 1*/struct proc *qvrsel; /* process waiting for select */int qvstart(), qvputc(), ttrstrt();/* * Keyboard translation and font tables */extern u_short q_key[], q_shift_key[], q_cursor[];extern char *q_special[], q_font[];/* * See if the qvss will interrupt. *//*ARGSUSED*/qvprobe(reg, ctlr) caddr_t reg; int ctlr;{ register int br, cvec; /* these are ``value-result'' */ register struct qvdevice *qvaddr = (struct qvdevice *)reg; static int tvec, ovec;#ifdef lint br = 0; cvec = br; br = cvec; qvkint(0); qvvint(0);#endif /* * Allocate the next two vectors */ tvec = 0360; ovec = cvec; /* * Turn on the keyboard and vertical interrupt vectors. */ qvaddr->qv_intcsr = 0; /* init the interrupt controler */ qvaddr->qv_intcsr = 0x40; /* reset irr */ qvaddr->qv_intcsr = 0x80; /* specify individual vectors */ qvaddr->qv_intcsr = 0xc0; /* preset autoclear data */ qvaddr->qv_intdata = 0xff; /* all setup as autoclear */ qvaddr->qv_intcsr = 0xe0; /* preset vector address 1 */ qvaddr->qv_intdata = tvec; /* give it the keyboard vector */ qvaddr->qv_intcsr = 0x28; /* enable tx/rx interrupt */ qvaddr->qv_intcsr = 0xe1; /* preset vector address 2 */ qvaddr->qv_intdata = tvec+4; /* give it the vertical sysnc */ qvaddr->qv_intcsr = 0x29; /* enable */ qvaddr->qv_intcsr = 0xa1; /* arm the interrupt ctrl */ qvaddr->qv_uartcmd = 0x15; /* set mode pntr/enable rx/tx */ qvaddr->qv_uartmode = 0x17; /* noparity, 8-bit */ qvaddr->qv_uartmode = 0x07; /* 1 stop bit */ qvaddr->qv_uartstatus = 0x99; /* 4800 baud xmit/recv */ qvaddr->qv_uartintstatus = 2; /* enable recv interrupts */ qvaddr->qv_csr |= QV_INT_ENABLE | QV_CUR_MODE; DELAY(10000); qvaddr->qv_csr &= ~QV_INT_ENABLE; /* * If the qvss did interrupt it was the second vector not * the first so we have to return the first so that they * will be setup properly */ if( ovec == cvec ) { return 0; } else cvec -= 4; return (sizeof (struct qvdevice));}/* * Routine called to attach a qv. */qvattach(ui) struct uba_device *ui;{ /* * If not the console then we have to setup the screen */ if (v_putc != qvputc || ui->ui_unit != 0) (void)qv_setup((struct qvdevice *)ui->ui_addr, ui->ui_unit, 1); else qv_scn->qvaddr = (struct qvdevice *)ui->ui_addr;}/*ARGSUSED*/qvopen(dev, flag) dev_t dev;{ register struct tty *tp; register int unit, qv; register struct qvdevice *qvaddr; register struct uba_device *ui; register struct qv_info *qp = qv_scn; unit = minor(dev); qv = unit >> 2; if (unit >= nqv || (ui = qvinfo[qv])== 0 || ui->ui_alive == 0) return (ENXIO); if (QVCHAN(unit) == QVSPARE#ifndef CONS_HACK || QVCHAN(unit) == QVPCONS#endif ) return (ENODEV); tp = &qv_tty[unit]; if (tp->t_state&TS_XCLUDE && u.u_uid!=0) return (EBUSY); qvaddr = (struct qvdevice *)ui->ui_addr; qv_scn->qvaddr = qvaddr; tp->t_addr = (caddr_t)qvaddr; tp->t_oproc = qvstart; if ((tp->t_state&TS_ISOPEN) == 0) { ttychars(tp); tp->t_state = TS_ISOPEN|TS_CARR_ON; tp->t_ispeed = B9600; tp->t_ospeed = B9600; if( QVCHAN(unit) == QVKEYBOARD ) { /* make sure keyboard is always back to default */ qvkbdreset(); qvaddr->qv_csr |= QV_INT_ENABLE; tp->t_iflag = TTYDEF_IFLAG; tp->t_oflag = TTYDEF_OFLAG; tp->t_lflag = TTYDEF_LFLAG; tp->t_cflag = TTYDEF_CFLAG; } /* XXX ?why? else tp->t_flags = RAW; */ } /* * Process line discipline specific open if its not the * mouse channel. For the mouse we init the ring ptr's. */ if( QVCHAN(unit) != QVMOUSECHAN ) return ((*linesw[tp->t_line].l_open)(dev, tp)); else { mouseon = 1; /* set up event queue for later */ qp->ibuff = (vsEvent *)qp - QVMAXEVQ; qp->iqsize = QVMAXEVQ; qp->ihead = qp->itail = 0; return 0; }}/* * Close a QVSS line. *//*ARGSUSED*/qvclose(dev, flag, mode, p) dev_t dev; int flag, mode; struct proc *p;{ register struct tty *tp; register unit; register struct qvdevice *qvaddr; int error; unit = minor(dev); tp = &qv_tty[unit]; /* * If this is the keyboard unit (0) shutdown the * interface.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -