summaryrefslogtreecommitdiff
path: root/sys/arch/i386/isa
diff options
context:
space:
mode:
authorTheo de Raadt <deraadt@cvs.openbsd.org>1995-10-18 08:53:40 +0000
committerTheo de Raadt <deraadt@cvs.openbsd.org>1995-10-18 08:53:40 +0000
commitd6583bb2a13f329cf0332ef2570eb8bb8fc0e39c (patch)
treeece253b876159b39c620e62b6c9b1174642e070e /sys/arch/i386/isa
initial import of NetBSD tree
Diffstat (limited to 'sys/arch/i386/isa')
-rw-r--r--sys/arch/i386/isa/clock.c519
-rw-r--r--sys/arch/i386/isa/debug.h24
-rw-r--r--sys/arch/i386/isa/fd.c1189
-rw-r--r--sys/arch/i386/isa/fdreg.h66
-rw-r--r--sys/arch/i386/isa/icu.h83
-rw-r--r--sys/arch/i386/isa/icu.s175
-rw-r--r--sys/arch/i386/isa/isa_machdep.c374
-rw-r--r--sys/arch/i386/isa/isa_machdep.h137
-rw-r--r--sys/arch/i386/isa/kbdreg.h28
-rw-r--r--sys/arch/i386/isa/lms.c351
-rw-r--r--sys/arch/i386/isa/mms.c346
-rw-r--r--sys/arch/i386/isa/npx.c589
-rw-r--r--sys/arch/i386/isa/nvram.h86
-rw-r--r--sys/arch/i386/isa/pccons.c1662
-rw-r--r--sys/arch/i386/isa/pcvt/Doc/Acknowledgements121
-rw-r--r--sys/arch/i386/isa/pcvt/Doc/Bibliography193
-rw-r--r--sys/arch/i386/isa/pcvt/Doc/BugList57
-rw-r--r--sys/arch/i386/isa/pcvt/Doc/ChangeLog1040
-rw-r--r--sys/arch/i386/isa/pcvt/Doc/CharGen149
-rw-r--r--sys/arch/i386/isa/pcvt/Doc/Charsets99
-rw-r--r--sys/arch/i386/isa/pcvt/Doc/EscapeSequences268
-rw-r--r--sys/arch/i386/isa/pcvt/Doc/FAQ405
-rw-r--r--sys/arch/i386/isa/pcvt/Doc/INSTALL.FreeBSD-2.0160
-rw-r--r--sys/arch/i386/isa/pcvt/Doc/INSTALL.NetBSD-1.0115
-rw-r--r--sys/arch/i386/isa/pcvt/Doc/Keyboard-Layout.HP286
-rw-r--r--sys/arch/i386/isa/pcvt/Doc/Keyboard-Layout.VT231
-rw-r--r--sys/arch/i386/isa/pcvt/Doc/Manifest170
-rw-r--r--sys/arch/i386/isa/pcvt/Doc/TestedHardware80
-rw-r--r--sys/arch/i386/isa/pcvt/Doc/ToDo15
-rw-r--r--sys/arch/i386/isa/pcvt/Etc/MAKEDEV.pcvt16
-rw-r--r--sys/arch/i386/isa/pcvt/Etc/Termcap287
-rw-r--r--sys/arch/i386/isa/pcvt/Etc/Terminfo41
-rw-r--r--sys/arch/i386/isa/pcvt/Etc/pcvt.el19
-rw-r--r--sys/arch/i386/isa/pcvt/Etc/rc.local288
-rw-r--r--sys/arch/i386/isa/pcvt/Etc/ttys.pcvt.freebsd148
-rw-r--r--sys/arch/i386/isa/pcvt/Etc/ttys.pcvt.netbsd70
-rw-r--r--sys/arch/i386/isa/pcvt/Etc/uemacs.tar.Z.uu594
-rw-r--r--sys/arch/i386/isa/pcvt/Etc/xmodmap-german117
-rw-r--r--sys/arch/i386/isa/pcvt/README.FIRST298
-rw-r--r--sys/arch/i386/isa/pcvt/Util/Makefile9
-rw-r--r--sys/arch/i386/isa/pcvt/Util/Makefile.inc33
-rw-r--r--sys/arch/i386/isa/pcvt/Util/cursor/Makefile3
-rw-r--r--sys/arch/i386/isa/pcvt/Util/cursor/cursor.176
-rw-r--r--sys/arch/i386/isa/pcvt/Util/cursor/cursor.c157
-rw-r--r--sys/arch/i386/isa/pcvt/Util/demo/Makefile54
-rw-r--r--sys/arch/i386/isa/pcvt/Util/demo/README20
-rw-r--r--sys/arch/i386/isa/pcvt/Util/demo/chardemo.vt.gz.uu53
-rw-r--r--sys/arch/i386/isa/pcvt/Util/demo/colors.vt.gz.uu15
-rw-r--r--sys/arch/i386/isa/pcvt/Util/demo/cowscene.vt.gz.uu90
-rw-r--r--sys/arch/i386/isa/pcvt/Util/demo/outerlimit.vt.gz.uu193
-rw-r--r--sys/arch/i386/isa/pcvt/Util/demo/playvt.c111
-rw-r--r--sys/arch/i386/isa/pcvt/Util/demo/sgr.vt.gz.uu11
-rw-r--r--sys/arch/i386/isa/pcvt/Util/demo/twzone.vt.gz.uu350
-rw-r--r--sys/arch/i386/isa/pcvt/Util/demo/xmas.vt.gz.uu110
-rw-r--r--sys/arch/i386/isa/pcvt/Util/fed/Makefile6
-rw-r--r--sys/arch/i386/isa/pcvt/Util/fed/edit.c340
-rw-r--r--sys/arch/i386/isa/pcvt/Util/fed/fed.152
-rw-r--r--sys/arch/i386/isa/pcvt/Util/fed/fed.c168
-rw-r--r--sys/arch/i386/isa/pcvt/Util/fed/fed.h127
-rw-r--r--sys/arch/i386/isa/pcvt/Util/fed/misc.c353
-rw-r--r--sys/arch/i386/isa/pcvt/Util/fed/select.c334
-rw-r--r--sys/arch/i386/isa/pcvt/Util/fontedit/Makefile5
-rw-r--r--sys/arch/i386/isa/pcvt/Util/fontedit/README36
-rw-r--r--sys/arch/i386/isa/pcvt/Util/fontedit/fontedit.158
-rw-r--r--sys/arch/i386/isa/pcvt/Util/fontedit/fontedit.c925
-rw-r--r--sys/arch/i386/isa/pcvt/Util/fonts/COPYRIGHT37
-rw-r--r--sys/arch/i386/isa/pcvt/Util/fonts/Makefile54
-rw-r--r--sys/arch/i386/isa/pcvt/Util/fonts/vt220h.808.uu49
-rw-r--r--sys/arch/i386/isa/pcvt/Util/fonts/vt220h.810.uu60
-rw-r--r--sys/arch/i386/isa/pcvt/Util/fonts/vt220h.814.uu83
-rw-r--r--sys/arch/i386/isa/pcvt/Util/fonts/vt220h.816.uu95
-rw-r--r--sys/arch/i386/isa/pcvt/Util/fonts/vt220l.808.uu49
-rw-r--r--sys/arch/i386/isa/pcvt/Util/fonts/vt220l.810.uu60
-rw-r--r--sys/arch/i386/isa/pcvt/Util/fonts/vt220l.814.uu83
-rw-r--r--sys/arch/i386/isa/pcvt/Util/fonts/vt220l.816.uu95
-rw-r--r--sys/arch/i386/isa/pcvt/Util/ispcvt/Makefile6
-rw-r--r--sys/arch/i386/isa/pcvt/Util/ispcvt/ispcvt.891
-rw-r--r--sys/arch/i386/isa/pcvt/Util/ispcvt/ispcvt.c310
-rw-r--r--sys/arch/i386/isa/pcvt/Util/kbdio/Makefile22
-rw-r--r--sys/arch/i386/isa/pcvt/Util/kbdio/kbdio.8330
-rw-r--r--sys/arch/i386/isa/pcvt/Util/kbdio/kbdio.y344
-rw-r--r--sys/arch/i386/isa/pcvt/Util/kbdio/lex.l87
-rw-r--r--sys/arch/i386/isa/pcvt/Util/kcon/Makefile10
-rw-r--r--sys/arch/i386/isa/pcvt/Util/kcon/kcon.1122
-rw-r--r--sys/arch/i386/isa/pcvt/Util/kcon/kcon.c753
-rw-r--r--sys/arch/i386/isa/pcvt/Util/keycap/Makefile19
-rw-r--r--sys/arch/i386/isa/pcvt/Util/keycap/keycap.3121
-rw-r--r--sys/arch/i386/isa/pcvt/Util/keycap/keycap.5133
-rw-r--r--sys/arch/i386/isa/pcvt/Util/keycap/keycap.c377
-rw-r--r--sys/arch/i386/isa/pcvt/Util/keycap/keycap.h49
-rw-r--r--sys/arch/i386/isa/pcvt/Util/keycap/keycap.src613
-rw-r--r--sys/arch/i386/isa/pcvt/Util/loadfont/Makefile3
-rw-r--r--sys/arch/i386/isa/pcvt/Util/loadfont/loadfont.191
-rw-r--r--sys/arch/i386/isa/pcvt/Util/loadfont/loadfont.c392
-rw-r--r--sys/arch/i386/isa/pcvt/Util/mcon/Makefile3
-rw-r--r--sys/arch/i386/isa/pcvt/Util/mcon/mcon.1166
-rw-r--r--sys/arch/i386/isa/pcvt/Util/mcon/mcon.c192
-rw-r--r--sys/arch/i386/isa/pcvt/Util/pcvtdoc/Makefile4
-rw-r--r--sys/arch/i386/isa/pcvt/Util/pcvtdoc/pcvt.4906
-rw-r--r--sys/arch/i386/isa/pcvt/Util/scon/Makefile3
-rw-r--r--sys/arch/i386/isa/pcvt/Util/scon/scon.1214
-rw-r--r--sys/arch/i386/isa/pcvt/Util/scon/scon.c860
-rw-r--r--sys/arch/i386/isa/pcvt/Util/set2061/CAUTION28
-rw-r--r--sys/arch/i386/isa/pcvt/Util/set2061/ICD2061Aalt.c297
-rw-r--r--sys/arch/i386/isa/pcvt/Util/set2061/Makefile10
-rw-r--r--sys/arch/i386/isa/pcvt/Util/set2061/README22
-rw-r--r--sys/arch/i386/isa/pcvt/Util/set2061/compiler.h341
-rw-r--r--sys/arch/i386/isa/pcvt/Util/set2061/main.c112
-rw-r--r--sys/arch/i386/isa/pcvt/Util/userkeys/Makefile3
-rw-r--r--sys/arch/i386/isa/pcvt/Util/userkeys/vt220keys.1131
-rw-r--r--sys/arch/i386/isa/pcvt/Util/userkeys/vt220keys.c297
-rw-r--r--sys/arch/i386/isa/pcvt/Util/vgaio/CAUTION28
-rw-r--r--sys/arch/i386/isa/pcvt/Util/vgaio/Makefile18
-rw-r--r--sys/arch/i386/isa/pcvt/Util/vgaio/lex.l68
-rw-r--r--sys/arch/i386/isa/pcvt/Util/vgaio/vgaio.8156
-rw-r--r--sys/arch/i386/isa/pcvt/Util/vgaio/vgaio.h71
-rw-r--r--sys/arch/i386/isa/pcvt/Util/vgaio/vgaio.y263
-rw-r--r--sys/arch/i386/isa/pcvt/Util/vttest/Makefile5
-rw-r--r--sys/arch/i386/isa/pcvt/Util/vttest/README57
-rw-r--r--sys/arch/i386/isa/pcvt/Util/vttest/esc.c398
-rw-r--r--sys/arch/i386/isa/pcvt/Util/vttest/header.h43
-rw-r--r--sys/arch/i386/isa/pcvt/Util/vttest/main.c2016
-rw-r--r--sys/arch/i386/isa/pcvt/Util/vttest/vttest.113
-rw-r--r--sys/arch/i386/isa/pcvt/pcvt_conf.h475
-rw-r--r--sys/arch/i386/isa/pcvt/pcvt_drv.c1336
-rw-r--r--sys/arch/i386/isa/pcvt/pcvt_ext.c2903
-rw-r--r--sys/arch/i386/isa/pcvt/pcvt_hdr.h1462
-rw-r--r--sys/arch/i386/isa/pcvt/pcvt_ioctl.h589
-rw-r--r--sys/arch/i386/isa/pcvt/pcvt_kbd.c2932
-rw-r--r--sys/arch/i386/isa/pcvt/pcvt_kbd.h566
-rw-r--r--sys/arch/i386/isa/pcvt/pcvt_out.c2304
-rw-r--r--sys/arch/i386/isa/pcvt/pcvt_sup.c2083
-rw-r--r--sys/arch/i386/isa/pcvt/pcvt_tbl.h476
-rw-r--r--sys/arch/i386/isa/pcvt/pcvt_vtf.c2237
-rw-r--r--sys/arch/i386/isa/pms.c451
-rw-r--r--sys/arch/i386/isa/spkr.c514
-rw-r--r--sys/arch/i386/isa/spkrreg.h11
-rw-r--r--sys/arch/i386/isa/timerreg.h100
-rw-r--r--sys/arch/i386/isa/vector.s365
139 files changed, 44652 insertions, 0 deletions
diff --git a/sys/arch/i386/isa/clock.c b/sys/arch/i386/isa/clock.c
new file mode 100644
index 00000000000..ff2f768d41c
--- /dev/null
+++ b/sys/arch/i386/isa/clock.c
@@ -0,0 +1,519 @@
+/* $NetBSD: clock.c,v 1.34 1995/08/13 04:06:29 mycroft Exp $ */
+
+/*-
+ * Copyright (c) 1993, 1994 Charles Hannum.
+ * Copyright (c) 1990 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.
+ *
+ * @(#)clock.c 7.2 (Berkeley) 5/12/91
+ */
+/*
+ * Mach Operating System
+ * Copyright (c) 1991,1990,1989 Carnegie Mellon University
+ * All Rights Reserved.
+ *
+ * Permission to use, copy, modify and distribute this software and its
+ * documentation is hereby granted, provided that both the copyright
+ * notice and this permission notice appear in all copies of the
+ * software, derivative works or modified versions, and any portions
+ * thereof, and that both notices appear in supporting documentation.
+ *
+ * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
+ * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
+ * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
+ *
+ * Carnegie Mellon requests users of this software to return to
+ *
+ * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
+ * School of Computer Science
+ * Carnegie Mellon University
+ * Pittsburgh PA 15213-3890
+ *
+ * any improvements or extensions that they make and grant Carnegie Mellon
+ * the rights to redistribute these changes.
+ */
+/*
+ Copyright 1988, 1989 by Intel Corporation, Santa Clara, California.
+
+ All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and
+its documentation for any purpose and without fee is hereby
+granted, provided that the above copyright notice appears in all
+copies and that both the copyright notice and this permission notice
+appear in supporting documentation, and that the name of Intel
+not be used in advertising or publicity pertaining to distribution
+of the software without specific, written prior permission.
+
+INTEL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE
+INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS,
+IN NO EVENT SHALL INTEL BE LIABLE FOR ANY SPECIAL, INDIRECT, OR
+CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+LOSS OF USE, DATA OR PROFITS, WHETHER IN ACTION OF CONTRACT,
+NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
+WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+*/
+
+/*
+ * Primitive clock interrupt routines.
+ */
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/time.h>
+#include <sys/kernel.h>
+#include <sys/device.h>
+
+#include <machine/cpu.h>
+#include <machine/pio.h>
+#include <machine/cpufunc.h>
+
+#include <dev/isa/isareg.h>
+#include <dev/isa/isavar.h>
+#include <dev/ic/mc146818reg.h>
+#include <i386/isa/nvram.h>
+#include <i386/isa/timerreg.h>
+#include <i386/isa/spkrreg.h>
+
+void spinwait __P((int));
+
+#define SECMIN ((unsigned)60) /* seconds per minute */
+#define SECHOUR ((unsigned)(60*SECMIN)) /* seconds per hour */
+#define SECDAY ((unsigned)(24*SECHOUR)) /* seconds per day */
+#define SECYR ((unsigned)(365*SECDAY)) /* seconds per common year */
+
+__inline u_int
+mc146818_read(sc, reg)
+ void *sc; /* XXX use it? */
+ u_int reg;
+{
+
+ outb(IO_RTC, reg);
+ return (inb(IO_RTC+1));
+}
+
+__inline void
+mc146818_write(sc, reg, datum)
+ void *sc; /* XXX use it? */
+ u_int reg, datum;
+{
+
+ outb(IO_RTC, reg);
+ outb(IO_RTC+1, datum);
+}
+
+void
+startrtclock()
+{
+ int s;
+
+ findcpuspeed(); /* use the clock (while it's free)
+ to find the cpu speed */
+ /* initialize 8253 clock */
+ outb(TIMER_MODE, TIMER_SEL0|TIMER_RATEGEN|TIMER_16BIT);
+
+ /* Correct rounding will buy us a better precision in timekeeping */
+ outb(IO_TIMER1, TIMER_DIV(hz) % 256);
+ outb(IO_TIMER1, TIMER_DIV(hz) / 256);
+
+ /* Check diagnostic status */
+ if (s = mc146818_read(NULL, NVRAM_DIAG)) /* XXX softc */
+ printf("RTC BIOS diagnostic error %b\n", s, NVRAM_DIAG_BITS);
+}
+
+int
+clockintr(arg)
+ void *arg;
+{
+ struct clockframe *frame = arg; /* not strictly necessary */
+
+ hardclock(frame);
+ return -1;
+}
+
+int
+gettick()
+{
+ u_char lo, hi;
+
+ /* Don't want someone screwing with the counter while we're here. */
+ disable_intr();
+ /* Select counter 0 and latch it. */
+ outb(TIMER_MODE, TIMER_SEL0 | TIMER_LATCH);
+ lo = inb(TIMER_CNTR0);
+ hi = inb(TIMER_CNTR0);
+ enable_intr();
+ return ((hi << 8) | lo);
+}
+
+/*
+ * Wait "n" microseconds.
+ * Relies on timer 1 counting down from (TIMER_FREQ / hz) at TIMER_FREQ Hz.
+ * Note: timer had better have been programmed before this is first used!
+ * (Note that we use `rate generator' mode, which counts at 1:1; `square
+ * wave' mode counts at 2:1).
+ */
+void
+delay(n)
+ int n;
+{
+ int limit, tick, otick;
+
+ /*
+ * Read the counter first, so that the rest of the setup overhead is
+ * counted.
+ */
+ otick = gettick();
+
+#ifdef __GNUC__
+ /*
+ * Calculate ((n * TIMER_FREQ) / 1e6) using explicit assembler code so
+ * we can take advantage of the intermediate 64-bit quantity to prevent
+ * loss of significance.
+ */
+ n -= 5;
+ if (n < 0)
+ return;
+ {register int m;
+ __asm __volatile("mul %3"
+ : "=a" (n), "=d" (m)
+ : "0" (n), "r" (TIMER_FREQ));
+ __asm __volatile("div %3"
+ : "=a" (n)
+ : "0" (n), "d" (m), "r" (1000000)
+ : "%edx");}
+#else
+ /*
+ * Calculate ((n * TIMER_FREQ) / 1e6) without using floating point and
+ * without any avoidable overflows.
+ */
+ n -= 20;
+ {
+ int sec = n / 1000000,
+ usec = n % 1000000;
+ n = sec * TIMER_FREQ +
+ usec * (TIMER_FREQ / 1000000) +
+ usec * ((TIMER_FREQ % 1000000) / 1000) / 1000 +
+ usec * (TIMER_FREQ % 1000) / 1000000;
+ }
+#endif
+
+ limit = TIMER_FREQ / hz;
+
+ while (n > 0) {
+ tick = gettick();
+ if (tick > otick)
+ n -= limit - (tick - otick);
+ else
+ n -= otick - tick;
+ otick = tick;
+ }
+}
+
+static int beeping;
+
+void
+sysbeepstop(arg)
+ void *arg;
+{
+
+ /* disable counter 2 */
+ disable_intr();
+ outb(PITAUX_PORT, inb(PITAUX_PORT) & ~PIT_SPKR);
+ enable_intr();
+ beeping = 0;
+}
+
+void
+sysbeep(pitch, period)
+ int pitch, period;
+{
+ static int last_pitch;
+
+ if (beeping)
+ untimeout(sysbeepstop, 0);
+ if (pitch == 0 || period == 0) {
+ sysbeepstop(0);
+ last_pitch = 0;
+ return;
+ }
+ if (!beeping || last_pitch != pitch) {
+ disable_intr();
+ outb(TIMER_MODE, TIMER_SEL2 | TIMER_16BIT | TIMER_SQWAVE);
+ outb(TIMER_CNTR2, TIMER_DIV(pitch) % 256);
+ outb(TIMER_CNTR2, TIMER_DIV(pitch) / 256);
+ outb(PITAUX_PORT, inb(PITAUX_PORT) | PIT_SPKR); /* enable counter 2 */
+ enable_intr();
+ }
+ last_pitch = pitch;
+ beeping = 1;
+ timeout(sysbeepstop, 0, period);
+}
+
+unsigned int delaycount; /* calibrated loop variable (1 millisecond) */
+
+#define FIRST_GUESS 0x2000
+findcpuspeed()
+{
+ int i;
+ int remainder;
+
+ /* Put counter in count down mode */
+ outb(TIMER_MODE, TIMER_SEL0 | TIMER_16BIT | TIMER_RATEGEN);
+ outb(TIMER_CNTR0, 0xff);
+ outb(TIMER_CNTR0, 0xff);
+ for (i = FIRST_GUESS; i; i--)
+ ;
+ /* Read the value left in the counter */
+ remainder = gettick();
+ /*
+ * Formula for delaycount is:
+ * (loopcount * timer clock speed) / (counter ticks * 1000)
+ */
+ delaycount = (FIRST_GUESS * TIMER_DIV(1000)) / (0xffff-remainder);
+}
+
+void
+cpu_initclocks()
+{
+
+ /*
+ * XXX If you're doing strange things with multiple clocks, you might
+ * want to keep track of clock handlers.
+ */
+ (void)isa_intr_establish(0, ISA_IST_PULSE, ISA_IPL_CLOCK,
+ clockintr, 0);
+}
+
+void
+rtcinit()
+{
+ static int first_rtcopen_ever = 1;
+
+ if (!first_rtcopen_ever)
+ return;
+ first_rtcopen_ever = 0;
+
+ mc146818_write(NULL, MC_REGA, /* XXX softc */
+ MC_BASE_32_KHz | MC_RATE_1024_Hz);
+ mc146818_write(NULL, MC_REGB, MC_REGB_24HR); /* XXX softc */
+}
+
+int
+rtcget(regs)
+ mc_todregs *regs;
+{
+
+ rtcinit();
+ if (mc146818_read(NULL, MC_REGD) & MC_REGD_VRT == 0) /* XXX softc */
+ return (-1);
+ MC146818_GETTOD(NULL, regs); /* XXX softc */
+ return (0);
+}
+
+void
+rtcput(regs)
+ mc_todregs *regs;
+{
+
+ rtcinit();
+ MC146818_PUTTOD(NULL, regs); /* XXX softc */
+}
+
+static int month[12] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
+
+static int
+yeartoday(year)
+ int year;
+{
+
+ return ((year % 4) ? 365 : 366);
+}
+
+int
+hexdectodec(n)
+ char n;
+{
+
+ return (((n >> 4) & 0x0f) * 10 + (n & 0x0f));
+}
+
+char
+dectohexdec(n)
+ int n;
+{
+
+ return ((char)(((n / 10) << 4) & 0xf0) | ((n % 10) & 0x0f));
+}
+
+static int timeset;
+
+/*
+ * Initialize the time of day register, based on the time base which is, e.g.
+ * from a filesystem.
+ */
+void
+inittodr(base)
+ time_t base;
+{
+ mc_todregs rtclk;
+ time_t n;
+ int sec, min, hr, dom, mon, yr;
+ int i, days = 0;
+ int s;
+
+ /*
+ * We mostly ignore the suggested time and go for the RTC clock time
+ * stored in the CMOS RAM. If the time can't be obtained from the
+ * CMOS, or if the time obtained from the CMOS is 5 or more years
+ * less than the suggested time, we used the suggested time. (In
+ * the latter case, it's likely that the CMOS battery has died.)
+ */
+
+ if (base < 15*SECYR) { /* if before 1985, something's odd... */
+ printf("WARNING: preposterous time in file system\n");
+ /* read the system clock anyway */
+ base = 17*SECYR + 186*SECDAY + SECDAY/2;
+ }
+
+ s = splclock();
+ if (rtcget(&rtclk)) {
+ splx(s);
+ printf("WARNING: invalid time in clock chip\n");
+ goto fstime;
+ }
+ splx(s);
+
+ sec = hexdectodec(rtclk[MC_SEC]);
+ min = hexdectodec(rtclk[MC_MIN]);
+ hr = hexdectodec(rtclk[MC_HOUR]);
+ dom = hexdectodec(rtclk[MC_DOM]);
+ mon = hexdectodec(rtclk[MC_MONTH]);
+ yr = hexdectodec(rtclk[MC_YEAR]);
+ yr = (yr < 70) ? yr+100 : yr;
+
+ n = sec + 60 * min + 3600 * hr;
+ n += (dom - 1) * 3600 * 24;
+
+ if (yeartoday(yr) == 366)
+ month[1] = 29;
+ for (i = mon - 2; i >= 0; i--)
+ days += month[i];
+ month[1] = 28;
+ for (i = 70; i < yr; i++)
+ days += yeartoday(i);
+ n += days * 3600 * 24;
+
+ n += tz.tz_minuteswest * 60;
+ if (tz.tz_dsttime)
+ n -= 3600;
+
+ if (base < n - 5*SECYR)
+ printf("WARNING: file system time much less than clock time\n");
+ else if (base > n + 5*SECYR) {
+ printf("WARNING: clock time much less than file system time\n");
+ printf("WARNING: using file system time\n");
+ goto fstime;
+ }
+
+ timeset = 1;
+ time.tv_sec = n;
+ time.tv_usec = 0;
+ return;
+
+fstime:
+ timeset = 1;
+ time.tv_sec = base;
+ time.tv_usec = 0;
+ printf("WARNING: CHECK AND RESET THE DATE!\n");
+}
+
+/*
+ * Reset the clock.
+ */
+void
+resettodr()
+{
+ mc_todregs rtclk;
+ time_t n;
+ int diff, i, j;
+ int s;
+
+ /*
+ * We might have been called by boot() due to a crash early
+ * on. Don't reset the clock chip in this case.
+ */
+ if (!timeset)
+ return;
+
+ s = splclock();
+ if (rtcget(&rtclk))
+ bzero(&rtclk, sizeof(rtclk));
+ splx(s);
+
+ diff = tz.tz_minuteswest * 60;
+ if (tz.tz_dsttime)
+ diff -= 3600;
+ n = (time.tv_sec - diff) % (3600 * 24); /* hrs+mins+secs */
+ rtclk[MC_SEC] = dectohexdec(n % 60);
+ n /= 60;
+ rtclk[MC_MIN] = dectohexdec(n % 60);
+ rtclk[MC_HOUR] = dectohexdec(n / 60);
+
+ n = (time.tv_sec - diff) / (3600 * 24); /* days */
+ rtclk[MC_DOW] = (n + 4) % 7; /* 1/1/70 is Thursday */
+
+ for (j = 1970, i = yeartoday(j); n >= i; j++, i = yeartoday(j))
+ n -= i;
+
+ rtclk[MC_YEAR] = dectohexdec(j - 1900);
+
+ if (i == 366)
+ month[1] = 29;
+ for (i = 0; n >= month[i]; i++)
+ n -= month[i];
+ month[1] = 28;
+ rtclk[MC_MONTH] = dectohexdec(++i);
+
+ rtclk[MC_DOM] = dectohexdec(++n);
+
+ s = splclock();
+ rtcput(&rtclk);
+ splx(s);
+}
+
+void
+setstatclockrate(arg)
+ int arg;
+{
+}
diff --git a/sys/arch/i386/isa/debug.h b/sys/arch/i386/isa/debug.h
new file mode 100644
index 00000000000..be0eee9959a
--- /dev/null
+++ b/sys/arch/i386/isa/debug.h
@@ -0,0 +1,24 @@
+/* $NetBSD: debug.h,v 1.6 1994/10/27 04:17:06 cgd Exp $ */
+
+#ifdef INTR_DEBUG
+#define INTRLOCAL(label) label
+#else /* not INTR_DEBUG */
+#define INTRLOCAL(label) L/**/label
+#endif /* INTR_DEBUG */
+
+#define BDBTRAP(name) \
+ ss ; \
+ cmpb $0,_bdb_exists ; \
+ je 1f ; \
+ testb $SEL_RPL_MASK,4(%esp) ; \
+ jne 1f ; \
+ ss ; \
+bdb_/**/name/**/_ljmp: ; \
+ ljmp $0,$0 ; \
+1:
+
+ .data
+ .globl _bdb_exists
+_bdb_exists:
+ .long 0
+ .text
diff --git a/sys/arch/i386/isa/fd.c b/sys/arch/i386/isa/fd.c
new file mode 100644
index 00000000000..5a46d1b3147
--- /dev/null
+++ b/sys/arch/i386/isa/fd.c
@@ -0,0 +1,1189 @@
+/* $NetBSD: fd.c,v 1.79 1995/08/21 06:56:14 mycroft Exp $ */
+
+/*-
+ * Copyright (c) 1993, 1994, 1995 Charles Hannum.
+ * Copyright (c) 1990 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * 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.
+ *
+ * @(#)fd.c 7.4 (Berkeley) 5/25/91
+ */
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/kernel.h>
+#include <sys/conf.h>
+#include <sys/file.h>
+#include <sys/ioctl.h>
+#include <sys/device.h>
+#include <sys/disklabel.h>
+#include <sys/dkstat.h>
+#include <sys/disk.h>
+#include <sys/buf.h>
+#include <sys/uio.h>
+#include <sys/syslog.h>
+#include <sys/queue.h>
+
+#include <machine/cpu.h>
+#include <machine/pio.h>
+
+#include <dev/isa/isavar.h>
+#include <dev/isa/isadmavar.h>
+#include <i386/isa/fdreg.h>
+
+#include <dev/ic/mc146818reg.h> /* for NVRAM access */
+#include <i386/isa/nvram.h>
+
+#define FDUNIT(dev) (minor(dev) / 8)
+#define FDTYPE(dev) (minor(dev) % 8)
+
+#define b_cylin b_resid
+
+enum fdc_state {
+ DEVIDLE = 0,
+ MOTORWAIT,
+ DOSEEK,
+ SEEKWAIT,
+ SEEKTIMEDOUT,
+ SEEKCOMPLETE,
+ DOIO,
+ IOCOMPLETE,
+ IOTIMEDOUT,
+ DORESET,
+ RESETCOMPLETE,
+ RESETTIMEDOUT,
+ DORECAL,
+ RECALWAIT,
+ RECALTIMEDOUT,
+ RECALCOMPLETE,
+};
+
+/* software state, per controller */
+struct fdc_softc {
+ struct device sc_dev; /* boilerplate */
+ struct isadev sc_id;
+ void *sc_ih;
+
+ int sc_iobase;
+ int sc_drq;
+
+ struct fd_softc *sc_fd[4]; /* pointers to children */
+ TAILQ_HEAD(drivehead, fd_softc) sc_drives;
+ enum fdc_state sc_state;
+ int sc_errors; /* number of retries so far */
+ u_char sc_status[7]; /* copy of registers */
+};
+
+/* controller driver configuration */
+int fdcprobe __P((struct device *, void *, void *));
+#ifdef NEWCONFIG
+void fdcforceintr __P((void *));
+#endif
+void fdcattach __P((struct device *, struct device *, void *));
+
+struct cfdriver fdccd = {
+ NULL, "fdc", fdcprobe, fdcattach, DV_DULL, sizeof(struct fdc_softc)
+};
+
+/*
+ * Floppies come in various flavors, e.g., 1.2MB vs 1.44MB; here is how
+ * we tell them apart.
+ */
+struct fd_type {
+ int sectrac; /* sectors per track */
+ int heads; /* number of heads */
+ int seccyl; /* sectors per cylinder */
+ int secsize; /* size code for sectors */
+ int datalen; /* data len when secsize = 0 */
+ int steprate; /* step rate and head unload time */
+ int gap1; /* gap len between sectors */
+ int gap2; /* formatting gap */
+ int tracks; /* total num of tracks */
+ int size; /* size of disk in sectors */
+ int step; /* steps per cylinder */
+ int rate; /* transfer speed code */
+ char *name;
+};
+
+/* The order of entries in the following table is important -- BEWARE! */
+struct fd_type fd_types[] = {
+ { 18,2,36,2,0xff,0xcf,0x1b,0x6c,80,2880,1,FDC_500KBPS,"1.44MB" }, /* 1.44MB diskette */
+ { 15,2,30,2,0xff,0xdf,0x1b,0x54,80,2400,1,FDC_500KBPS, "1.2MB" }, /* 1.2 MB AT-diskettes */
+ { 9,2,18,2,0xff,0xdf,0x23,0x50,40, 720,2,FDC_300KBPS, "360KB/AT" }, /* 360kB in 1.2MB drive */
+ { 9,2,18,2,0xff,0xdf,0x2a,0x50,40, 720,1,FDC_250KBPS, "360KB/PC" }, /* 360kB PC diskettes */
+ { 9,2,18,2,0xff,0xdf,0x2a,0x50,80,1440,1,FDC_250KBPS, "720KB" }, /* 3.5" 720kB diskette */
+ { 9,2,18,2,0xff,0xdf,0x23,0x50,80,1440,1,FDC_300KBPS, "720KB/x" }, /* 720kB in 1.2MB drive */
+ { 9,2,18,2,0xff,0xdf,0x2a,0x50,40, 720,2,FDC_250KBPS, "360KB/x" }, /* 360kB in 720kB drive */
+};
+
+/* software state, per disk (with up to 4 disks per ctlr) */
+struct fd_softc {
+ struct device sc_dev;
+ struct dkdevice sc_dk;
+
+ struct fd_type *sc_deftype; /* default type descriptor */
+ struct fd_type *sc_type; /* current type descriptor */
+
+ daddr_t sc_blkno; /* starting block number */
+ int sc_bcount; /* byte count left */
+ int sc_skip; /* bytes already transferred */
+ int sc_nblks; /* number of blocks currently tranferring */
+ int sc_nbytes; /* number of bytes currently tranferring */
+
+ int sc_drive; /* physical unit number */
+ int sc_flags;
+#define FD_OPEN 0x01 /* it's open */
+#define FD_MOTOR 0x02 /* motor should be on */
+#define FD_MOTOR_WAIT 0x04 /* motor coming up */
+ int sc_cylin; /* where we think the head is */
+
+ TAILQ_ENTRY(fd_softc) sc_drivechain;
+ int sc_ops; /* I/O ops since last switch */
+ struct buf sc_q; /* head of buf chain */
+};
+
+/* floppy driver configuration */
+int fdprobe __P((struct device *, void *, void *));
+void fdattach __P((struct device *, struct device *, void *));
+
+struct cfdriver fdcd = {
+ NULL, "fd", fdprobe, fdattach, DV_DISK, sizeof(struct fd_softc)
+};
+
+void fdgetdisklabel __P((struct fd_softc *));
+int fd_get_parms __P((struct fd_softc *));
+void fdstrategy __P((struct buf *));
+void fdstart __P((struct fd_softc *));
+
+struct dkdriver fddkdriver = { fdstrategy };
+
+struct fd_type *fd_nvtotype __P((char *, int, int));
+void fd_set_motor __P((struct fdc_softc *fdc, int reset));
+void fd_motor_off __P((void *arg));
+void fd_motor_on __P((void *arg));
+int fdcresult __P((struct fdc_softc *fdc));
+int out_fdc __P((int iobase, u_char x));
+void fdcstart __P((struct fdc_softc *fdc));
+void fdcstatus __P((struct device *dv, int n, char *s));
+void fdctimeout __P((void *arg));
+void fdcpseudointr __P((void *arg));
+int fdcintr __P((void *));
+void fdcretry __P((struct fdc_softc *fdc));
+void fdfinish __P((struct fd_softc *fd, struct buf *bp));
+
+int
+fdcprobe(parent, match, aux)
+ struct device *parent;
+ void *match, *aux;
+{
+ register struct isa_attach_args *ia = aux;
+ int iobase = ia->ia_iobase;
+
+ /* reset */
+ outb(iobase + fdout, 0);
+ delay(100);
+ outb(iobase + fdout, FDO_FRST);
+
+ /* see if it can handle a command */
+ if (out_fdc(iobase, NE7CMD_SPECIFY) < 0)
+ return 0;
+ out_fdc(iobase, 0xdf);
+ out_fdc(iobase, 2);
+
+#ifdef NEWCONFIG
+ if (iobase == IOBASEUNK || ia->ia_drq == DRQUNK)
+ return 0;
+
+ if (ia->ia_irq == IRQUNK) {
+ ia->ia_irq = isa_discoverintr(fdcforceintr, aux);
+ if (ia->ia_irq == IRQNONE)
+ return 0;
+
+ /* reset it again */
+ outb(iobase + fdout, 0);
+ delay(100);
+ outb(iobase + fdout, FDO_FRST);
+ }
+#endif
+
+ ia->ia_iosize = FDC_NPORT;
+ ia->ia_msize = 0;
+ return 1;
+}
+
+#ifdef NEWCONFIG
+void
+fdcforceintr(aux)
+ void *aux;
+{
+ struct isa_attach_args *ia = aux;
+ int iobase = ia->ia_iobase;
+
+ /* the motor is off; this should generate an error with or
+ without a disk drive present */
+ out_fdc(iobase, NE7CMD_SEEK);
+ out_fdc(iobase, 0);
+ out_fdc(iobase, 0);
+}
+#endif
+
+/*
+ * Arguments passed between fdcattach and fdprobe.
+ */
+struct fdc_attach_args {
+ int fa_drive;
+ struct fd_type *fa_deftype;
+};
+
+/*
+ * Print the location of a disk drive (called just before attaching the
+ * the drive). If `fdc' is not NULL, the drive was found but was not
+ * in the system config file; print the drive name as well.
+ * Return QUIET (config_find ignores this if the device was configured) to
+ * avoid printing `fdN not configured' messages.
+ */
+int
+fdprint(aux, fdc)
+ void *aux;
+ char *fdc;
+{
+ register struct fdc_attach_args *fa = aux;
+
+ if (!fdc)
+ printf(" drive %d", fa->fa_drive);
+ return QUIET;
+}
+
+void
+fdcattach(parent, self, aux)
+ struct device *parent, *self;
+ void *aux;
+{
+ struct fdc_softc *fdc = (void *)self;
+ struct isa_attach_args *ia = aux;
+ struct fdc_attach_args fa;
+ int type;
+
+ fdc->sc_iobase = ia->ia_iobase;
+ fdc->sc_drq = ia->ia_drq;
+ fdc->sc_state = DEVIDLE;
+ TAILQ_INIT(&fdc->sc_drives);
+
+ printf("\n");
+
+#ifdef NEWCONFIG
+ at_setup_dmachan(fdc->sc_drq, FDC_MAXIOSIZE);
+ isa_establish(&fdc->sc_id, &fdc->sc_dev);
+#endif
+ fdc->sc_ih = isa_intr_establish(ia->ia_irq, ISA_IST_EDGE, ISA_IPL_BIO,
+ fdcintr, fdc);
+
+ /*
+ * The NVRAM info only tells us about the first two disks on the
+ * `primary' floppy controller.
+ */
+ if (fdc->sc_dev.dv_unit == 0)
+ type = mc146818_read(NULL, NVRAM_DISKETTE); /* XXX softc */
+ else
+ type = -1;
+
+ /* physical limit: four drives per controller. */
+ for (fa.fa_drive = 0; fa.fa_drive < 4; fa.fa_drive++) {
+ if (type >= 0 && fa.fa_drive < 2)
+ fa.fa_deftype = fd_nvtotype(fdc->sc_dev.dv_xname,
+ type, fa.fa_drive);
+ else
+ fa.fa_deftype = NULL; /* unknown */
+ (void)config_found(self, (void *)&fa, fdprint);
+ }
+}
+
+int
+fdprobe(parent, match, aux)
+ struct device *parent;
+ void *match, *aux;
+{
+ struct fdc_softc *fdc = (void *)parent;
+ struct cfdata *cf = match;
+ struct fdc_attach_args *fa = aux;
+ int drive = fa->fa_drive;
+ int iobase = fdc->sc_iobase;
+ int n;
+
+ if (cf->cf_loc[0] != -1 && cf->cf_loc[0] != drive)
+ return 0;
+ /*
+ * XXX
+ * This is to work around some odd interactions between this driver
+ * and SMC Ethernet cards.
+ */
+ if (cf->cf_loc[0] == -1 && drive >= 2)
+ return 0;
+
+ /* select drive and turn on motor */
+ outb(iobase + fdout, drive | FDO_FRST | FDO_MOEN(drive));
+ /* wait for motor to spin up */
+ delay(250000);
+ out_fdc(iobase, NE7CMD_RECAL);
+ out_fdc(iobase, drive);
+ /* wait for recalibrate */
+ delay(2000000);
+ out_fdc(iobase, NE7CMD_SENSEI);
+ n = fdcresult(fdc);
+#ifdef FD_DEBUG
+ {
+ int i;
+ printf("fdprobe: status");
+ for (i = 0; i < n; i++)
+ printf(" %x", fdc->sc_status[i]);
+ printf("\n");
+ }
+#endif
+ if (n != 2 || (fdc->sc_status[0] & 0xf8) != 0x20)
+ return 0;
+ /* turn off motor */
+ outb(iobase + fdout, FDO_FRST);
+
+ return 1;
+}
+
+/*
+ * Controller is working, and drive responded. Attach it.
+ */
+void
+fdattach(parent, self, aux)
+ struct device *parent, *self;
+ void *aux;
+{
+ struct fdc_softc *fdc = (void *)parent;
+ struct fd_softc *fd = (void *)self;
+ struct fdc_attach_args *fa = aux;
+ struct fd_type *type = fa->fa_deftype;
+ int drive = fa->fa_drive;
+
+ /* XXX Allow `flags' to override device type? */
+
+ if (type)
+ printf(": %s %d cyl, %d head, %d sec\n", type->name,
+ type->tracks, type->heads, type->sectrac);
+ else
+ printf(": density unknown\n");
+
+ fd->sc_cylin = -1;
+ fd->sc_drive = drive;
+ fd->sc_deftype = type;
+ fdc->sc_fd[drive] = fd;
+ fd->sc_dk.dk_driver = &fddkdriver;
+#ifdef NEWCONFIG
+ /* XXX Need to do some more fiddling with sc_dk. */
+ dk_establish(&fd->sc_dk, &fd->sc_dev);
+#endif
+}
+
+/*
+ * Translate nvram type into internal data structure. Return NULL for
+ * none/unknown/unusable.
+ */
+struct fd_type *
+fd_nvtotype(fdc, nvraminfo, drive)
+ char *fdc;
+ int nvraminfo, drive;
+{
+ int type;
+
+ type = (drive == 0 ? nvraminfo : nvraminfo << 4) & 0xf0;
+ switch (type) {
+ case NVRAM_DISKETTE_NONE:
+ return NULL;
+ case NVRAM_DISKETTE_12M:
+ return &fd_types[1];
+ case NVRAM_DISKETTE_TYPE5:
+ case NVRAM_DISKETTE_TYPE6:
+ /* XXX We really ought to handle 2.88MB format. */
+ case NVRAM_DISKETTE_144M:
+ return &fd_types[0];
+ case NVRAM_DISKETTE_360K:
+ return &fd_types[3];
+ case NVRAM_DISKETTE_720K:
+ return &fd_types[4];
+ default:
+ printf("%s: drive %d: unknown device type 0x%x\n",
+ fdc, drive, type);
+ return NULL;
+ }
+}
+
+inline struct fd_type *
+fd_dev_to_type(fd, dev)
+ struct fd_softc *fd;
+ dev_t dev;
+{
+ int type = FDTYPE(dev);
+
+ if (type > (sizeof(fd_types) / sizeof(fd_types[0])))
+ return NULL;
+ return type ? &fd_types[type - 1] : fd->sc_deftype;
+}
+
+void
+fdstrategy(bp)
+ register struct buf *bp; /* IO operation to perform */
+{
+ struct fd_softc *fd;
+ int unit = FDUNIT(bp->b_dev);
+ int sz;
+ int s;
+
+ /* Valid unit, controller, and request? */
+ if (unit >= fdcd.cd_ndevs ||
+ (fd = fdcd.cd_devs[unit]) == 0 ||
+ bp->b_blkno < 0 ||
+ (bp->b_bcount % FDC_BSIZE) != 0) {
+ bp->b_error = EINVAL;
+ goto bad;
+ }
+
+ /* If it's a null transfer, return immediately. */
+ if (bp->b_bcount == 0)
+ goto done;
+
+ sz = howmany(bp->b_bcount, FDC_BSIZE);
+
+ if (bp->b_blkno + sz > fd->sc_type->size) {
+ sz = fd->sc_type->size - bp->b_blkno;
+ if (sz == 0) {
+ /* If exactly at end of disk, return EOF. */
+ bp->b_resid = bp->b_bcount;
+ goto done;
+ }
+ if (sz < 0) {
+ /* If past end of disk, return EINVAL. */
+ bp->b_error = EINVAL;
+ goto bad;
+ }
+ /* Otherwise, truncate request. */
+ bp->b_bcount = sz << DEV_BSHIFT;
+ }
+
+ bp->b_cylin = bp->b_blkno / (FDC_BSIZE / DEV_BSIZE) / fd->sc_type->seccyl;
+
+#ifdef FD_DEBUG
+ printf("fdstrategy: b_blkno %d b_bcount %d blkno %d cylin %d sz %d\n",
+ bp->b_blkno, bp->b_bcount, fd->sc_blkno, bp->b_cylin, sz);
+#endif
+
+ /* Queue transfer on drive, activate drive and controller if idle. */
+ s = splbio();
+ disksort(&fd->sc_q, bp);
+ untimeout(fd_motor_off, fd); /* a good idea */
+ if (!fd->sc_q.b_active)
+ fdstart(fd);
+#ifdef DIAGNOSTIC
+ else {
+ struct fdc_softc *fdc = (void *)fd->sc_dev.dv_parent;
+ if (fdc->sc_state == DEVIDLE) {
+ printf("fdstrategy: controller inactive\n");
+ fdcstart(fdc);
+ }
+ }
+#endif
+ splx(s);
+ return;
+
+bad:
+ bp->b_flags |= B_ERROR;
+done:
+ /* Toss transfer; we're done early. */
+ biodone(bp);
+}
+
+void
+fdstart(fd)
+ struct fd_softc *fd;
+{
+ struct fdc_softc *fdc = (void *)fd->sc_dev.dv_parent;
+ int active = fdc->sc_drives.tqh_first != 0;
+
+ /* Link into controller queue. */
+ fd->sc_q.b_active = 1;
+ TAILQ_INSERT_TAIL(&fdc->sc_drives, fd, sc_drivechain);
+
+ /* If controller not already active, start it. */
+ if (!active)
+ fdcstart(fdc);
+}
+
+void
+fdfinish(fd, bp)
+ struct fd_softc *fd;
+ struct buf *bp;
+{
+ struct fdc_softc *fdc = (void *)fd->sc_dev.dv_parent;
+
+ /*
+ * Move this drive to the end of the queue to give others a `fair'
+ * chance. We only force a switch if N operations are completed while
+ * another drive is waiting to be serviced, since there is a long motor
+ * startup delay whenever we switch.
+ */
+ if (fd->sc_drivechain.tqe_next && ++fd->sc_ops >= 8) {
+ fd->sc_ops = 0;
+ TAILQ_REMOVE(&fdc->sc_drives, fd, sc_drivechain);
+ if (bp->b_actf) {
+ TAILQ_INSERT_TAIL(&fdc->sc_drives, fd, sc_drivechain);
+ } else
+ fd->sc_q.b_active = 0;
+ }
+ bp->b_resid = fd->sc_bcount;
+ fd->sc_skip = 0;
+ fd->sc_q.b_actf = bp->b_actf;
+ biodone(bp);
+ /* turn off motor 5s from now */
+ timeout(fd_motor_off, fd, 5 * hz);
+ fdc->sc_state = DEVIDLE;
+}
+
+int
+fdread(dev, uio)
+ dev_t dev;
+ struct uio *uio;
+{
+
+ return (physio(fdstrategy, NULL, dev, B_READ, minphys, uio));
+}
+
+int
+fdwrite(dev, uio)
+ dev_t dev;
+ struct uio *uio;
+{
+
+ return (physio(fdstrategy, NULL, dev, B_WRITE, minphys, uio));
+}
+
+void
+fd_set_motor(fdc, reset)
+ struct fdc_softc *fdc;
+ int reset;
+{
+ struct fd_softc *fd;
+ u_char status;
+ int n;
+
+ if (fd = fdc->sc_drives.tqh_first)
+ status = fd->sc_drive;
+ else
+ status = 0;
+ if (!reset)
+ status |= FDO_FRST | FDO_FDMAEN;
+ for (n = 0; n < 4; n++)
+ if ((fd = fdc->sc_fd[n]) && (fd->sc_flags & FD_MOTOR))
+ status |= FDO_MOEN(n);
+ outb(fdc->sc_iobase + fdout, status);
+}
+
+void
+fd_motor_off(arg)
+ void *arg;
+{
+ struct fd_softc *fd = arg;
+ int s;
+
+ s = splbio();
+ fd->sc_flags &= ~(FD_MOTOR | FD_MOTOR_WAIT);
+ fd_set_motor((struct fdc_softc *)fd->sc_dev.dv_parent, 0);
+ splx(s);
+}
+
+void
+fd_motor_on(arg)
+ void *arg;
+{
+ struct fd_softc *fd = arg;
+ struct fdc_softc *fdc = (void *)fd->sc_dev.dv_parent;
+ int s;
+
+ s = splbio();
+ fd->sc_flags &= ~FD_MOTOR_WAIT;
+ if ((fdc->sc_drives.tqh_first == fd) && (fdc->sc_state == MOTORWAIT))
+ (void) fdcintr(fdc);
+ splx(s);
+}
+
+int
+fdcresult(fdc)
+ struct fdc_softc *fdc;
+{
+ int iobase = fdc->sc_iobase;
+ u_char i;
+ int j = 100000,
+ n = 0;
+
+ for (; j; j--) {
+ i = inb(iobase + fdsts) & (NE7_DIO | NE7_RQM | NE7_CB);
+ if (i == NE7_RQM)
+ return n;
+ if (i == (NE7_DIO | NE7_RQM | NE7_CB)) {
+ if (n >= sizeof(fdc->sc_status)) {
+ log(LOG_ERR, "fdcresult: overrun\n");
+ return -1;
+ }
+ fdc->sc_status[n++] = inb(iobase + fddata);
+ }
+ }
+ log(LOG_ERR, "fdcresult: timeout\n");
+ return -1;
+}
+
+int
+out_fdc(iobase, x)
+ int iobase;
+ u_char x;
+{
+ int i = 100000;
+
+ while ((inb(iobase + fdsts) & NE7_DIO) && i-- > 0);
+ if (i <= 0)
+ return -1;
+ while ((inb(iobase + fdsts) & NE7_RQM) == 0 && i-- > 0);
+ if (i <= 0)
+ return -1;
+ outb(iobase + fddata, x);
+ return 0;
+}
+
+int
+Fdopen(dev, flags)
+ dev_t dev;
+ int flags;
+{
+ int unit;
+ struct fd_softc *fd;
+ struct fd_type *type;
+
+ unit = FDUNIT(dev);
+ if (unit >= fdcd.cd_ndevs)
+ return ENXIO;
+ fd = fdcd.cd_devs[unit];
+ if (fd == 0)
+ return ENXIO;
+ type = fd_dev_to_type(fd, dev);
+ if (type == NULL)
+ return ENXIO;
+
+ if ((fd->sc_flags & FD_OPEN) != 0 &&
+ fd->sc_type != type)
+ return EBUSY;
+
+ fd->sc_type = type;
+ fd->sc_cylin = -1;
+ fd->sc_flags |= FD_OPEN;
+
+ return 0;
+}
+
+int
+fdclose(dev, flags)
+ dev_t dev;
+ int flags;
+{
+ struct fd_softc *fd = fdcd.cd_devs[FDUNIT(dev)];
+
+ fd->sc_flags &= ~FD_OPEN;
+ return 0;
+}
+
+void
+fdcstart(fdc)
+ struct fdc_softc *fdc;
+{
+
+#ifdef DIAGNOSTIC
+ /* only got here if controller's drive queue was inactive; should
+ be in idle state */
+ if (fdc->sc_state != DEVIDLE) {
+ printf("fdcstart: not idle\n");
+ return;
+ }
+#endif
+ (void) fdcintr(fdc);
+}
+
+void
+fdcstatus(dv, n, s)
+ struct device *dv;
+ int n;
+ char *s;
+{
+ struct fdc_softc *fdc = (void *)dv->dv_parent;
+ int iobase = fdc->sc_iobase;
+
+ if (n == 0) {
+ out_fdc(fdc->sc_iobase, NE7CMD_SENSEI);
+ (void) fdcresult(fdc);
+ n = 2;
+ }
+
+ printf("%s: %s", dv->dv_xname, s);
+
+ switch (n) {
+ case 0:
+ printf("\n");
+ break;
+ case 2:
+ printf(" (st0 %b cyl %d)\n",
+ fdc->sc_status[0], NE7_ST0BITS,
+ fdc->sc_status[1]);
+ break;
+ case 7:
+ printf(" (st0 %b st1 %b st2 %b cyl %d head %d sec %d)\n",
+ fdc->sc_status[0], NE7_ST0BITS,
+ fdc->sc_status[1], NE7_ST1BITS,
+ fdc->sc_status[2], NE7_ST2BITS,
+ fdc->sc_status[3], fdc->sc_status[4], fdc->sc_status[5]);
+ break;
+#ifdef DIAGNOSTIC
+ default:
+ printf("\nfdcstatus: weird size");
+ break;
+#endif
+ }
+}
+
+void
+fdctimeout(arg)
+ void *arg;
+{
+ struct fdc_softc *fdc = arg;
+ struct fd_softc *fd = fdc->sc_drives.tqh_first;
+ int s;
+
+ s = splbio();
+ fdcstatus(&fd->sc_dev, 0, "timeout");
+
+ if (fd->sc_q.b_actf)
+ fdc->sc_state++;
+ else
+ fdc->sc_state = DEVIDLE;
+
+ (void) fdcintr(fdc);
+ splx(s);
+}
+
+void
+fdcpseudointr(arg)
+ void *arg;
+{
+ int s;
+
+ /* Just ensure it has the right spl. */
+ s = splbio();
+ (void) fdcintr(arg);
+ splx(s);
+}
+
+int
+fdcintr(arg)
+ void *arg;
+{
+ struct fdc_softc *fdc = arg;
+#define st0 fdc->sc_status[0]
+#define cyl fdc->sc_status[1]
+ struct fd_softc *fd;
+ struct buf *bp;
+ int iobase = fdc->sc_iobase;
+ int read, head, trac, sec, i, s, nblks;
+ struct fd_type *type;
+
+loop:
+ /* Is there a drive for the controller to do a transfer with? */
+ fd = fdc->sc_drives.tqh_first;
+ if (fd == NULL) {
+ fdc->sc_state = DEVIDLE;
+ return 1;
+ }
+
+ /* Is there a transfer to this drive? If not, deactivate drive. */
+ bp = fd->sc_q.b_actf;
+ if (bp == NULL) {
+ fd->sc_ops = 0;
+ TAILQ_REMOVE(&fdc->sc_drives, fd, sc_drivechain);
+ fd->sc_q.b_active = 0;
+ goto loop;
+ }
+
+ switch (fdc->sc_state) {
+ case DEVIDLE:
+ fdc->sc_errors = 0;
+ fd->sc_skip = 0;
+ fd->sc_bcount = bp->b_bcount;
+ fd->sc_blkno = bp->b_blkno / (FDC_BSIZE / DEV_BSIZE);
+ untimeout(fd_motor_off, fd);
+ if ((fd->sc_flags & FD_MOTOR_WAIT) != 0) {
+ fdc->sc_state = MOTORWAIT;
+ return 1;
+ }
+ if ((fd->sc_flags & FD_MOTOR) == 0) {
+ /* Turn on the motor, being careful about pairing. */
+ struct fd_softc *ofd = fdc->sc_fd[fd->sc_drive ^ 1];
+ if (ofd && ofd->sc_flags & FD_MOTOR) {
+ untimeout(fd_motor_off, ofd);
+ ofd->sc_flags &= ~(FD_MOTOR | FD_MOTOR_WAIT);
+ }
+ fd->sc_flags |= FD_MOTOR | FD_MOTOR_WAIT;
+ fd_set_motor(fdc, 0);
+ fdc->sc_state = MOTORWAIT;
+ /* Allow .25s for motor to stabilize. */
+ timeout(fd_motor_on, fd, hz / 4);
+ return 1;
+ }
+ /* Make sure the right drive is selected. */
+ fd_set_motor(fdc, 0);
+
+ /* fall through */
+ case DOSEEK:
+ doseek:
+ if (fd->sc_cylin == bp->b_cylin)
+ goto doio;
+
+ out_fdc(iobase, NE7CMD_SPECIFY);/* specify command */
+ out_fdc(iobase, fd->sc_type->steprate);
+ out_fdc(iobase, 6); /* XXX head load time == 6ms */
+
+ out_fdc(iobase, NE7CMD_SEEK); /* seek function */
+ out_fdc(iobase, fd->sc_drive); /* drive number */
+ out_fdc(iobase, bp->b_cylin * fd->sc_type->step);
+
+ fd->sc_cylin = -1;
+ fdc->sc_state = SEEKWAIT;
+ timeout(fdctimeout, fdc, 4 * hz);
+ return 1;
+
+ case DOIO:
+ doio:
+ type = fd->sc_type;
+ sec = fd->sc_blkno % type->seccyl;
+ nblks = type->seccyl - sec;
+ nblks = min(nblks, fd->sc_bcount / FDC_BSIZE);
+ nblks = min(nblks, FDC_MAXIOSIZE / FDC_BSIZE);
+ fd->sc_nblks = nblks;
+ fd->sc_nbytes = nblks * FDC_BSIZE;
+ head = sec / type->sectrac;
+ sec -= head * type->sectrac;
+#ifdef DIAGNOSTIC
+ {int block;
+ block = (fd->sc_cylin * type->heads + head) * type->sectrac + sec;
+ if (block != fd->sc_blkno) {
+ printf("fdcintr: block %d != blkno %d\n", block, fd->sc_blkno);
+#ifdef DDB
+ Debugger();
+#endif
+ }}
+#endif
+ read = bp->b_flags & B_READ;
+#ifdef NEWCONFIG
+ at_dma(read, bp->b_data + fd->sc_skip, fd->sc_nbytes,
+ fdc->sc_drq);
+#else
+ isa_dmastart(read, bp->b_data + fd->sc_skip, fd->sc_nbytes,
+ fdc->sc_drq);
+#endif
+ outb(iobase + fdctl, type->rate);
+#ifdef FD_DEBUG
+ printf("fdcintr: %s drive %d track %d head %d sec %d nblks %d\n",
+ read ? "read" : "write", fd->sc_drive, fd->sc_cylin, head,
+ sec, nblks);
+#endif
+ if (read)
+ out_fdc(iobase, NE7CMD_READ); /* READ */
+ else
+ out_fdc(iobase, NE7CMD_WRITE); /* WRITE */
+ out_fdc(iobase, (head << 2) | fd->sc_drive);
+ out_fdc(iobase, fd->sc_cylin); /* track */
+ out_fdc(iobase, head);
+ out_fdc(iobase, sec + 1); /* sector +1 */
+ out_fdc(iobase, type->secsize); /* sector size */
+ out_fdc(iobase, type->sectrac); /* sectors/track */
+ out_fdc(iobase, type->gap1); /* gap1 size */
+ out_fdc(iobase, type->datalen); /* data length */
+ fdc->sc_state = IOCOMPLETE;
+ /* allow 2 seconds for operation */
+ timeout(fdctimeout, fdc, 2 * hz);
+ return 1; /* will return later */
+
+ case SEEKWAIT:
+ untimeout(fdctimeout, fdc);
+ fdc->sc_state = SEEKCOMPLETE;
+ /* allow 1/50 second for heads to settle */
+ timeout(fdcpseudointr, fdc, hz / 50);
+ return 1;
+
+ case SEEKCOMPLETE:
+ /* Make sure seek really happened. */
+ out_fdc(iobase, NE7CMD_SENSEI);
+ if (fdcresult(fdc) != 2 || (st0 & 0xf8) != 0x20 ||
+ cyl != bp->b_cylin * fd->sc_type->step) {
+#ifdef FD_DEBUG
+ fdcstatus(&fd->sc_dev, 2, "seek failed");
+#endif
+ fdcretry(fdc);
+ goto loop;
+ }
+ fd->sc_cylin = bp->b_cylin;
+ goto doio;
+
+ case IOTIMEDOUT:
+#ifdef NEWCONFIG
+ at_dma_abort(fdc->sc_drq);
+#else
+ isa_dmaabort(fdc->sc_drq);
+#endif
+ case SEEKTIMEDOUT:
+ case RECALTIMEDOUT:
+ case RESETTIMEDOUT:
+ fdcretry(fdc);
+ goto loop;
+
+ case IOCOMPLETE: /* IO DONE, post-analyze */
+ untimeout(fdctimeout, fdc);
+ if (fdcresult(fdc) != 7 || (st0 & 0xf8) != 0) {
+#ifdef NEWCONFIG
+ at_dma_abort(fdc->sc_drq);
+#else
+ isa_dmaabort(fdc->sc_drq);
+#endif
+#ifdef FD_DEBUG
+ fdcstatus(&fd->sc_dev, 7, bp->b_flags & B_READ ?
+ "read failed" : "write failed");
+ printf("blkno %d nblks %d\n",
+ fd->sc_blkno, fd->sc_nblks);
+#endif
+ fdcretry(fdc);
+ goto loop;
+ }
+#ifdef NEWCONFIG
+ at_dma_terminate(fdc->sc_drq);
+#else
+ read = bp->b_flags & B_READ;
+ isa_dmadone(read, bp->b_data + fd->sc_skip, fd->sc_nbytes,
+ fdc->sc_drq);
+#endif
+ if (fdc->sc_errors) {
+ diskerr(bp, "fd", "soft error", LOG_PRINTF,
+ fd->sc_skip / FDC_BSIZE, (struct disklabel *)NULL);
+ printf("\n");
+ fdc->sc_errors = 0;
+ }
+ fd->sc_blkno += fd->sc_nblks;
+ fd->sc_skip += fd->sc_nbytes;
+ fd->sc_bcount -= fd->sc_nbytes;
+ if (fd->sc_bcount > 0) {
+ bp->b_cylin = fd->sc_blkno / fd->sc_type->seccyl;
+ goto doseek;
+ }
+ fdfinish(fd, bp);
+ goto loop;
+
+ case DORESET:
+ /* try a reset, keep motor on */
+ fd_set_motor(fdc, 1);
+ delay(100);
+ fd_set_motor(fdc, 0);
+ fdc->sc_state = RESETCOMPLETE;
+ timeout(fdctimeout, fdc, hz / 2);
+ return 1; /* will return later */
+
+ case RESETCOMPLETE:
+ untimeout(fdctimeout, fdc);
+ /* clear the controller output buffer */
+ for (i = 0; i < 4; i++) {
+ out_fdc(iobase, NE7CMD_SENSEI);
+ (void) fdcresult(fdc);
+ }
+
+ /* fall through */
+ case DORECAL:
+ out_fdc(iobase, NE7CMD_RECAL); /* recalibrate function */
+ out_fdc(iobase, fd->sc_drive);
+ fdc->sc_state = RECALWAIT;
+ timeout(fdctimeout, fdc, 5 * hz);
+ return 1; /* will return later */
+
+ case RECALWAIT:
+ untimeout(fdctimeout, fdc);
+ fdc->sc_state = RECALCOMPLETE;
+ /* allow 1/30 second for heads to settle */
+ timeout(fdcpseudointr, fdc, hz / 30);
+ return 1; /* will return later */
+
+ case RECALCOMPLETE:
+ out_fdc(iobase, NE7CMD_SENSEI);
+ if (fdcresult(fdc) != 2 || (st0 & 0xf8) != 0x20 || cyl != 0) {
+#ifdef FD_DEBUG
+ fdcstatus(&fd->sc_dev, 2, "recalibrate failed");
+#endif
+ fdcretry(fdc);
+ goto loop;
+ }
+ fd->sc_cylin = 0;
+ goto doseek;
+
+ case MOTORWAIT:
+ if (fd->sc_flags & FD_MOTOR_WAIT)
+ return 1; /* time's not up yet */
+ goto doseek;
+
+ default:
+ fdcstatus(&fd->sc_dev, 0, "stray interrupt");
+ return 1;
+ }
+#ifdef DIAGNOSTIC
+ panic("fdcintr: impossible");
+#endif
+#undef st0
+#undef cyl
+}
+
+void
+fdcretry(fdc)
+ struct fdc_softc *fdc;
+{
+ struct fd_softc *fd;
+ struct buf *bp;
+
+ fd = fdc->sc_drives.tqh_first;
+ bp = fd->sc_q.b_actf;
+
+ switch (fdc->sc_errors) {
+ case 0:
+ /* try again */
+ fdc->sc_state = SEEKCOMPLETE;
+ break;
+
+ case 1: case 2: case 3:
+ /* didn't work; try recalibrating */
+ fdc->sc_state = DORECAL;
+ break;
+
+ case 4:
+ /* still no go; reset the bastard */
+ fdc->sc_state = DORESET;
+ break;
+
+ default:
+ diskerr(bp, "fd", "hard error", LOG_PRINTF,
+ fd->sc_skip / FDC_BSIZE, (struct disklabel *)NULL);
+ printf(" (st0 %b st1 %b st2 %b cyl %d head %d sec %d)\n",
+ fdc->sc_status[0], NE7_ST0BITS,
+ fdc->sc_status[1], NE7_ST1BITS,
+ fdc->sc_status[2], NE7_ST2BITS,
+ fdc->sc_status[3], fdc->sc_status[4], fdc->sc_status[5]);
+
+ bp->b_flags |= B_ERROR;
+ bp->b_error = EIO;
+ fdfinish(fd, bp);
+ }
+ fdc->sc_errors++;
+}
+
+int
+fdsize(dev)
+ dev_t dev;
+{
+
+ /* Swapping to floppies would not make sense. */
+ return -1;
+}
+
+int
+fddump(dev, blkno, va, size)
+ dev_t dev;
+ daddr_t blkno;
+ caddr_t va;
+ size_t size;
+{
+
+ /* Not implemented. */
+ return ENXIO;
+}
+
+int
+fdioctl(dev, cmd, addr, flag)
+ dev_t dev;
+ u_long cmd;
+ caddr_t addr;
+ int flag;
+{
+ struct fd_softc *fd = fdcd.cd_devs[FDUNIT(dev)];
+ struct disklabel buffer;
+ int error;
+
+ switch (cmd) {
+ case DIOCGDINFO:
+ bzero(&buffer, sizeof(buffer));
+
+ buffer.d_secpercyl = fd->sc_type->seccyl;
+ buffer.d_type = DTYPE_FLOPPY;
+ buffer.d_secsize = FDC_BSIZE;
+
+ if (readdisklabel(dev, fdstrategy, &buffer, NULL) != NULL)
+ return EINVAL;
+
+ *(struct disklabel *)addr = buffer;
+ return 0;
+
+ case DIOCWLABEL:
+ if ((flag & FWRITE) == 0)
+ return EBADF;
+ /* XXX do something */
+ return 0;
+
+ case DIOCWDINFO:
+ if ((flag & FWRITE) == 0)
+ return EBADF;
+
+ error = setdisklabel(&buffer, (struct disklabel *)addr, 0, NULL);
+ if (error)
+ return error;
+
+ error = writedisklabel(dev, fdstrategy, &buffer, NULL);
+ return error;
+
+ default:
+ return ENOTTY;
+ }
+
+#ifdef DIAGNOSTIC
+ panic("fdioctl: impossible");
+#endif
+}
diff --git a/sys/arch/i386/isa/fdreg.h b/sys/arch/i386/isa/fdreg.h
new file mode 100644
index 00000000000..a1c8388912d
--- /dev/null
+++ b/sys/arch/i386/isa/fdreg.h
@@ -0,0 +1,66 @@
+/* $NetBSD: fdreg.h,v 1.8 1995/06/28 04:30:57 cgd Exp $ */
+
+/*-
+ * Copyright (c) 1991 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * 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.
+ *
+ * @(#)fdreg.h 7.1 (Berkeley) 5/9/91
+ */
+
+/*
+ * AT floppy controller registers and bitfields
+ */
+
+/* uses NEC765 controller */
+#include <dev/ic/nec765reg.h>
+
+/* registers */
+#define fdout 2 /* Digital Output Register (W) */
+#define FDO_FDSEL 0x03 /* floppy device select */
+#define FDO_FRST 0x04 /* floppy controller reset */
+#define FDO_FDMAEN 0x08 /* enable floppy DMA and Interrupt */
+#define FDO_MOEN(n) ((1 << n) * 0x10) /* motor enable */
+
+#define fdsts 4 /* NEC 765 Main Status Register (R) */
+#define fddata 5 /* NEC 765 Data Register (R/W) */
+
+#define fdctl 7 /* Control Register (W) */
+#define FDC_500KBPS 0x00 /* 500KBPS MFM drive transfer rate */
+#define FDC_300KBPS 0x01 /* 300KBPS MFM drive transfer rate */
+#define FDC_250KBPS 0x02 /* 250KBPS MFM drive transfer rate */
+#define FDC_125KBPS 0x03 /* 125KBPS FM drive transfer rate */
+
+#define fdin 7 /* Digital Input Register (R) */
+#define FDI_DCHG 0x80 /* diskette has been changed */
+
+#define FDC_BSIZE 512
+#define FDC_NPORT 8
+#define FDC_MAXIOSIZE NBPG /* XXX should be MAXBSIZE */
diff --git a/sys/arch/i386/isa/icu.h b/sys/arch/i386/isa/icu.h
new file mode 100644
index 00000000000..d9a7e144d28
--- /dev/null
+++ b/sys/arch/i386/isa/icu.h
@@ -0,0 +1,83 @@
+/* $NetBSD: icu.h,v 1.17 1994/11/04 19:13:49 mycroft Exp $ */
+
+/*-
+ * Copyright (c) 1990 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * William Jolitz.
+ *
+ * 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.
+ *
+ * @(#)icu.h 5.6 (Berkeley) 5/9/91
+ */
+
+/*
+ * AT/386 Interrupt Control constants
+ * W. Jolitz 8/89
+ */
+
+#ifndef _I386_ISA_ICU_H_
+#define _I386_ISA_ICU_H_
+
+#ifndef LOCORE
+
+/*
+ * Interrupt "level" mechanism variables, masks, and macros
+ */
+extern unsigned imen; /* interrupt mask enable */
+
+#define INTRUNMASK(msk,s) (msk &= ~(s))
+#define INTREN(s) (INTRUNMASK(imen, s), SET_ICUS())
+#define INTRMASK(msk,s) (msk |= (s))
+#define INTRDIS(s) (INTRMASK(imen, s), SET_ICUS())
+#if 0
+#define SET_ICUS() (outb(IO_ICU1 + 1, imen), outb(IU_ICU2 + 1, imen >> 8))
+#else
+/*
+ * XXX - IO_ICU* are defined in isa.h, not icu.h, and nothing much bothers to
+ * include isa.h, while too many things include icu.h.
+ */
+#define SET_ICUS() (outb(0x21, imen), outb(0xa1, imen >> 8))
+#endif
+
+#endif /* !LOCORE */
+
+/*
+ * Interrupt enable bits -- in order of priority
+ */
+#define IRQ_SLAVE 2
+
+/*
+ * Interrupt Control offset into Interrupt descriptor table (IDT)
+ */
+#define ICU_OFFSET 32 /* 0-31 are processor exceptions */
+#define ICU_LEN 16 /* 32-47 are ISA interrupts */
+
+#endif /* !_I386_ISA_ICU_H_ */
diff --git a/sys/arch/i386/isa/icu.s b/sys/arch/i386/isa/icu.s
new file mode 100644
index 00000000000..1f5de650230
--- /dev/null
+++ b/sys/arch/i386/isa/icu.s
@@ -0,0 +1,175 @@
+/* $NetBSD: icu.s,v 1.43 1995/10/11 04:20:31 mycroft Exp $ */
+
+/*-
+ * Copyright (c) 1993, 1994, 1995 Charles M. Hannum. All rights reserved.
+ *
+ * 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 Charles M. Hannum.
+ * 4. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ */
+
+#include <net/netisr.h>
+
+ .data
+ .globl _imen,_cpl,_ipending,_astpending,_netisr
+_imen:
+ .long 0xffff # interrupt mask enable (all off)
+
+ .text
+
+#if defined(PROF) || defined(GPROF)
+ .globl _splhigh, _splx
+
+ ALIGN_TEXT
+_splhigh:
+ movl $-1,%eax
+ xchgl %eax,_cpl
+ ret
+
+ ALIGN_TEXT
+_splx:
+ movl 4(%esp),%eax
+ movl %eax,_cpl
+ testl %eax,%eax
+ jnz _Xspllower
+ ret
+#endif /* PROF || GPROF */
+
+/*
+ * Process pending interrupts.
+ *
+ * Important registers:
+ * ebx - cpl
+ * esi - address to resume loop at
+ * edi - scratch for Xsoftnet
+ */
+ENTRY(spllower)
+IDTVEC(spllower)
+ pushl %ebx
+ pushl %esi
+ pushl %edi
+ movl _cpl,%ebx # save priority
+ movl $1f,%esi # address to resume loop at
+1: movl %ebx,%eax
+ notl %eax
+ andl _ipending,%eax
+ jz 2f
+ bsfl %eax,%eax
+ btrl %eax,_ipending
+ jnc 1b
+ jmp *_Xrecurse(,%eax,4)
+2: popl %edi
+ popl %esi
+ popl %ebx
+ ret
+
+/*
+ * Handle return from interrupt after device handler finishes.
+ *
+ * Important registers:
+ * ebx - cpl to restore
+ * esi - address to resume loop at
+ * edi - scratch for Xsoftnet
+ */
+IDTVEC(doreti)
+ popl %ebx # get previous priority
+ movl %ebx,_cpl
+ movl $1f,%esi # address to resume loop at
+1: movl %ebx,%eax
+ notl %eax
+ andl _ipending,%eax
+ jz 2f
+ bsfl %eax,%eax # slow, but not worth optimizing
+ btrl %eax,_ipending
+ jnc 1b # some intr cleared the in-memory bit
+ jmp *_Xresume(,%eax,4)
+2: /* Check for ASTs on exit to user mode. */
+ cli
+ cmpb $0,_astpending
+ je 3f
+ testb $SEL_RPL,TF_CS(%esp)
+#ifdef VM86
+ jnz 4f
+ testl $PSL_VM,TF_EFLAGS(%esp)
+#endif
+ jz 3f
+4: movb $0,_astpending
+ sti
+ /* Pushed T_ASTFLT into tf_trapno on entry. */
+ call _trap
+3: INTRFASTEXIT
+
+
+/*
+ * Soft interrupt handlers
+ */
+
+IDTVEC(softtty)
+ /* XXXX nothing for now */
+ jmp %esi
+
+#define DONET(s, c) \
+ .globl c ;\
+ testl $(1 << s),%edi ;\
+ jz 1f ;\
+ call c ;\
+1:
+
+IDTVEC(softnet)
+ leal SIR_NETMASK(%ebx),%eax
+ movl %eax,_cpl
+ xorl %edi,%edi
+ xchgl _netisr,%edi
+#ifdef INET
+#include "ether.h"
+#if NETHER > 0
+ DONET(NETISR_ARP, _arpintr)
+#endif
+ DONET(NETISR_IP, _ipintr)
+#endif
+#ifdef IMP
+ DONET(NETISR_IMP, _impintr)
+#endif
+#ifdef NS
+ DONET(NETISR_NS, _nsintr)
+#endif
+#ifdef ISO
+ DONET(NETISR_ISO, _clnlintr)
+#endif
+#ifdef CCITT
+ DONET(NETISR_CCITT, _ccittintr)
+#endif
+#include "ppp.h"
+#if NPPP > 0
+ DONET(NETISR_PPP, _pppintr)
+#endif
+ movl %ebx,_cpl
+ jmp %esi
+
+IDTVEC(softclock)
+ leal SIR_CLOCKMASK(%ebx),%eax
+ movl %eax,_cpl
+ call _softclock
+ movl %ebx,_cpl
+ jmp %esi
diff --git a/sys/arch/i386/isa/isa_machdep.c b/sys/arch/i386/isa/isa_machdep.c
new file mode 100644
index 00000000000..5b7da9965be
--- /dev/null
+++ b/sys/arch/i386/isa/isa_machdep.c
@@ -0,0 +1,374 @@
+/* $NetBSD: isa_machdep.c,v 1.8 1995/10/09 06:34:47 mycroft Exp $ */
+
+/*-
+ * Copyright (c) 1993, 1994 Charles Hannum.
+ * Copyright (c) 1991 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * William Jolitz.
+ *
+ * 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.
+ *
+ * @(#)isa.c 7.2 (Berkeley) 5/13/91
+ */
+
+#include <sys/param.h>
+#include <sys/syslog.h>
+#include <sys/device.h>
+#include <sys/malloc.h>
+
+#include <machine/pio.h>
+#include <machine/cpufunc.h>
+
+#include <dev/isa/isareg.h>
+#include <dev/isa/isavar.h>
+#include <i386/isa/isa_machdep.h>
+#include <i386/isa/icu.h>
+
+#define IDTVEC(name) __CONCAT(X,name)
+/* default interrupt vector table entries */
+typedef (*vector)();
+extern vector IDTVEC(intr)[], IDTVEC(fast)[];
+extern struct gate_descriptor idt[];
+
+int isamatch __P((struct device *, void *, void *));
+void isaattach __P((struct device *, struct device *, void *));
+
+struct cfdriver isacd = {
+ NULL, "isa", isamatch, isaattach, DV_DULL, sizeof(struct isa_softc), 1
+};
+
+int
+isamatch(parent, match, aux)
+ struct device *parent;
+ void *match, *aux;
+{
+
+ return (1);
+}
+
+void
+isaattach(parent, self, aux)
+ struct device *parent, *self;
+ void *aux;
+{
+ struct isa_softc *sc = (struct isa_softc *)self;
+
+ printf("\n");
+
+ TAILQ_INIT(&sc->sc_subdevs);
+ config_scan(isascan, self);
+}
+
+/*
+ * Fill in default interrupt table (in case of spuruious interrupt
+ * during configuration of kernel, setup interrupt control unit
+ */
+void
+isa_defaultirq()
+{
+ int i;
+
+ /* icu vectors */
+ for (i = 0; i < ICU_LEN; i++)
+ setgate(&idt[ICU_OFFSET + i], IDTVEC(intr)[i], 0, SDT_SYS386IGT,
+ SEL_KPL);
+
+ /* initialize 8259's */
+ outb(IO_ICU1, 0x11); /* reset; program device, four bytes */
+ outb(IO_ICU1+1, ICU_OFFSET); /* starting at this vector index */
+ outb(IO_ICU1+1, 1 << IRQ_SLAVE); /* slave on line 2 */
+#ifdef AUTO_EOI_1
+ outb(IO_ICU1+1, 2 | 1); /* auto EOI, 8086 mode */
+#else
+ outb(IO_ICU1+1, 1); /* 8086 mode */
+#endif
+ outb(IO_ICU1+1, 0xff); /* leave interrupts masked */
+ outb(IO_ICU1, 0x68); /* special mask mode (if available) */
+ outb(IO_ICU1, 0x0a); /* Read IRR by default. */
+#ifdef REORDER_IRQ
+ outb(IO_ICU1, 0xc0 | (3 - 1)); /* pri order 3-7, 0-2 (com2 first) */
+#endif
+
+ outb(IO_ICU2, 0x11); /* reset; program device, four bytes */
+ outb(IO_ICU2+1, ICU_OFFSET+8); /* staring at this vector index */
+ outb(IO_ICU2+1, IRQ_SLAVE);
+#ifdef AUTO_EOI_2
+ outb(IO_ICU2+1, 2 | 1); /* auto EOI, 8086 mode */
+#else
+ outb(IO_ICU2+1, 1); /* 8086 mode */
+#endif
+ outb(IO_ICU2+1, 0xff); /* leave interrupts masked */
+ outb(IO_ICU2, 0x68); /* special mask mode (if available) */
+ outb(IO_ICU2, 0x0a); /* Read IRR by default. */
+}
+
+/*
+ * Handle a NMI, possibly a machine check.
+ * return true to panic system, false to ignore.
+ */
+int
+isa_nmi()
+{
+
+ log(LOG_CRIT, "NMI port 61 %x, port 70 %x\n", inb(0x61), inb(0x70));
+ return(0);
+}
+
+/*
+ * Caught a stray interrupt, notify
+ */
+void
+isa_strayintr(irq)
+ int irq;
+{
+ static u_long strays;
+
+ /*
+ * Stray interrupts on irq 7 occur when an interrupt line is raised
+ * and then lowered before the CPU acknowledges it. This generally
+ * means either the device is screwed or something is cli'ing too
+ * long and it's timing out.
+ */
+ if (++strays <= 5)
+ log(LOG_ERR, "stray interrupt %d%s\n", irq,
+ strays >= 5 ? "; stopped logging" : "");
+}
+
+int fastvec;
+int intrtype[ICU_LEN], intrmask[ICU_LEN], intrlevel[ICU_LEN];
+struct intrhand *intrhand[ICU_LEN];
+
+/*
+ * Recalculate the interrupt masks from scratch.
+ * We could code special registry and deregistry versions of this function that
+ * would be faster, but the code would be nastier, and we don't expect this to
+ * happen very much anyway.
+ */
+void
+intr_calculatemasks()
+{
+ int irq, level;
+ struct intrhand *q;
+
+ /* First, figure out which levels each IRQ uses. */
+ for (irq = 0; irq < ICU_LEN; irq++) {
+ register int levels = 0;
+ for (q = intrhand[irq]; q; q = q->ih_next)
+ if (q->ih_level != IPL_NONE)
+ levels |= 1 << q->ih_level;
+ intrlevel[irq] = levels;
+ }
+
+ /* Then figure out which IRQs use each level. */
+ for (level = 0; level < 5; level++) {
+ register int irqs = 0;
+ for (irq = 0; irq < ICU_LEN; irq++)
+ if (intrlevel[irq] & (1 << level))
+ irqs |= 1 << irq;
+ imask[level] = irqs | SIR_ALLMASK;
+ }
+
+#include "sl.h"
+#include "ppp.h"
+#if NSL > 0 || NPPP > 0
+ /* In the presence of SLIP or PPP, imp > tty. */
+ imask[IPL_IMP] |= imask[IPL_TTY];
+#endif
+
+ /*
+ * There are network and disk drivers that use free() at interrupt
+ * time, so imp > (net | bio).
+ */
+ imask[IPL_IMP] |= imask[IPL_NET] | imask[IPL_BIO];
+
+ /* And eventually calculate the complete masks. */
+ for (irq = 0; irq < ICU_LEN; irq++) {
+ register int irqs = 1 << irq;
+ for (q = intrhand[irq]; q; q = q->ih_next)
+ if (q->ih_level != IPL_NONE)
+ irqs |= imask[q->ih_level];
+ intrmask[irq] = irqs | SIR_ALLMASK;
+ }
+
+ /* Lastly, determine which IRQs are actually in use. */
+ {
+ register int irqs = 0;
+ for (irq = 0; irq < ICU_LEN; irq++)
+ if (intrhand[irq])
+ irqs |= 1 << irq;
+ if (irqs >= 0x100) /* any IRQs >= 8 in use */
+ irqs |= 1 << IRQ_SLAVE;
+ imen = ~irqs;
+ SET_ICUS();
+ }
+}
+
+int
+fakeintr(arg)
+ void *arg;
+{
+
+ return 0;
+}
+
+/*
+ * Set up an interrupt handler to start being called.
+ * XXX PRONE TO RACE CONDITIONS, UGLY, 'INTERESTING' INSERTION ALGORITHM.
+ */
+void *
+isa_intr_establish(irq, type, level, ih_fun, ih_arg)
+ int irq;
+ isa_intrtype type;
+ isa_intrlevel level;
+ int (*ih_fun) __P((void *));
+ void *ih_arg;
+{
+ int mask;
+ struct intrhand **p, *q, *ih;
+ static struct intrhand fakehand = {fakeintr};
+ extern int cold;
+
+ /* no point in sleeping unless someone can free memory. */
+ ih = malloc(sizeof *ih, M_DEVBUF, cold ? M_NOWAIT : M_WAITOK);
+ if (ih == NULL)
+ panic("isa_intr_establish: can't malloc handler info");
+
+ mask = 1 << irq;
+
+ if (irq < 0 || irq > ICU_LEN || type == ISA_IST_NONE)
+ panic("intr_establish: bogus irq or type");
+ if (fastvec & mask)
+ panic("intr_establish: irq is already fast vector");
+
+ switch (intrtype[irq]) {
+ case ISA_IST_EDGE:
+ case ISA_IST_LEVEL:
+ if (type == intrtype[irq])
+ break;
+ case ISA_IST_PULSE:
+ if (type != ISA_IST_NONE)
+ panic("intr_establish: can't share %s with %s",
+ isa_intr_typename(intrtype[irq]),
+ isa_intr_typename(type));
+ break;
+ }
+
+ /*
+ * Figure out where to put the handler.
+ * This is O(N^2), but we want to preserve the order, and N is
+ * generally small.
+ */
+ for (p = &intrhand[irq]; (q = *p) != NULL; p = &q->ih_next)
+ ;
+
+ /*
+ * Actually install a fake handler momentarily, since we might be doing
+ * this with interrupts enabled and don't want the real routine called
+ * until masking is set up.
+ */
+ switch (level) {
+ case ISA_IPL_NONE:
+ fakehand.ih_level = IPL_NONE;
+ break;
+
+ case ISA_IPL_BIO:
+ fakehand.ih_level = IPL_BIO;
+ break;
+
+ case ISA_IPL_NET:
+ fakehand.ih_level = IPL_NET;
+ break;
+
+ case ISA_IPL_TTY:
+ fakehand.ih_level = IPL_TTY;
+ break;
+
+ case ISA_IPL_CLOCK:
+ fakehand.ih_level = IPL_CLOCK;
+ break;
+
+ default:
+ panic("isa_intr_establish: bad interrupt level %d", level);
+ }
+ *p = &fakehand;
+
+ intr_calculatemasks();
+
+ /*
+ * Poke the real handler in now.
+ */
+ ih->ih_fun = ih_fun;
+ ih->ih_arg = ih_arg;
+ ih->ih_count = 0;
+ ih->ih_next = NULL;
+ ih->ih_level = fakehand.ih_level;
+ ih->ih_irq = irq;
+ *p = ih;
+
+ return (ih);
+}
+
+/*
+ * Deregister an interrupt handler.
+ */
+void
+isa_intr_disestablish(arg)
+ void *arg;
+{
+ struct intrhand *ih = arg;
+ int irq, mask;
+ struct intrhand **p, *q;
+
+ irq = ih->ih_irq;
+ mask = 1 << irq;
+
+ if (irq < 0 || irq > ICU_LEN)
+ panic("intr_disestablish: bogus irq");
+ if (fastvec & mask)
+ fastvec &= ~mask;
+
+ /*
+ * Remove the handler from the chain.
+ * This is O(n^2), too.
+ */
+ for (p = &intrhand[irq]; (q = *p) != NULL && q != ih; p = &q->ih_next)
+ ;
+ if (q)
+ *p = q->ih_next;
+ else
+ panic("intr_disestablish: handler not registered");
+ free(ih, M_DEVBUF);
+
+ intr_calculatemasks();
+
+ if (intrhand[irq] == NULL)
+ intrtype[irq] = ISA_IST_NONE;
+}
diff --git a/sys/arch/i386/isa/isa_machdep.h b/sys/arch/i386/isa/isa_machdep.h
new file mode 100644
index 00000000000..a118e7fc17a
--- /dev/null
+++ b/sys/arch/i386/isa/isa_machdep.h
@@ -0,0 +1,137 @@
+/* $NetBSD: isa_machdep.h,v 1.4 1995/05/04 19:39:46 cgd Exp $ */
+
+/*-
+ * Copyright (c) 1990 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * William Jolitz.
+ *
+ * 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.
+ *
+ * @(#)isa.h 5.7 (Berkeley) 5/9/91
+ */
+
+/*
+ * XXX THIS FILE IS A MESS. copyright: berkeley's probably.
+ * contents from isavar.h and isareg.h, mostly the latter.
+ * perhaps charles's?
+ *
+ * copyright from berkeley's isa.h which is now dev/isa/isareg.h.
+ */
+
+
+/*
+ * XXX Various seemingly PC-specific constants, some of which may be
+ * unnecessary anyway.
+ */
+
+/*
+ * RAM Physical Address Space (ignoring the above mentioned "hole")
+ */
+#define RAM_BEGIN 0x0000000 /* Start of RAM Memory */
+#define RAM_END 0x1000000 /* End of RAM Memory */
+#define RAM_SIZE (RAM_END - RAM_BEGIN)
+
+/*
+ * Oddball Physical Memory Addresses
+ */
+#define COMPAQ_RAMRELOC 0x80c00000 /* Compaq RAM relocation/diag */
+#define COMPAQ_RAMSETUP 0x80c00002 /* Compaq RAM setup */
+#define WEITEK_FPU 0xC0000000 /* WTL 2167 */
+#define CYRIX_EMC 0xC0000000 /* Cyrix EMC */
+
+/*
+ * stuff that used to be in pccons.c
+ */
+#define MONO_BASE 0x3B4
+#define MONO_BUF 0xB0000
+#define CGA_BASE 0x3D4
+#define CGA_BUF 0xB8000
+#define IOPHYSMEM 0xA0000
+
+
+/*
+ * Interrupt handler chains. isa_intr_establish() inserts a handler into
+ * the list. The handler is called with its (single) argument.
+ */
+
+struct intrhand {
+ int (*ih_fun)();
+ void *ih_arg;
+ u_long ih_count;
+ struct intrhand *ih_next;
+ int ih_level;
+ int ih_irq;
+};
+
+
+/*
+ * ISA DMA bounce buffers.
+ * XXX should be made partially machine- and bus-mapping-independent.
+ *
+ * DMA_BOUNCE is the number of pages of low-addressed physical memory
+ * to acquire for ISA bounce buffers.
+ *
+ * isaphysmem is the location of those bounce buffers. (They are currently
+ * assumed to be contiguous.
+ */
+
+#ifndef DMA_BOUNCE
+#define DMA_BOUNCE 8 /* one buffer per channel */
+#endif
+
+extern vm_offset_t isaphysmem;
+
+
+/*
+ * Variables and macros to deal with the ISA I/O hole.
+ * XXX These should be converted to machine- and bus-mapping-independent
+ * function definitions, invoked through the softc.
+ */
+
+extern u_long atdevbase; /* kernel virtual address of "hole" */
+
+/*
+ * Given a kernel virtual address for some location
+ * in the "hole" I/O space, return a physical address.
+ */
+#define ISA_PHYSADDR(v) ((void *) ((u_long)(v) - atdevbase + IOM_BEGIN))
+
+/*
+ * Given a physical address in the "hole",
+ * return a kernel virtual address.
+ */
+#define ISA_HOLE_VADDR(p) ((void *) ((u_long)(p) - IOM_BEGIN + atdevbase))
+
+
+/*
+ * Miscellanous functions.
+ */
+void sysbeep __P((int, int)); /* beep with the system speaker */
diff --git a/sys/arch/i386/isa/kbdreg.h b/sys/arch/i386/isa/kbdreg.h
new file mode 100644
index 00000000000..cfdcf230550
--- /dev/null
+++ b/sys/arch/i386/isa/kbdreg.h
@@ -0,0 +1,28 @@
+/* $NetBSD: kbdreg.h,v 1.7 1995/06/28 04:30:59 cgd Exp $ */
+
+/*
+ * Keyboard definitions
+ */
+
+#include <dev/ic/i8042reg.h>
+
+/* keyboard commands */
+#define KBC_RESET 0xFF /* reset the keyboard */
+#define KBC_RESEND 0xFE /* request the keyboard resend the last byte */
+#define KBC_SETDEFAULT 0xF6 /* resets keyboard to its power-on defaults */
+#define KBC_DISABLE 0xF5 /* as per KBC_SETDEFAULT, but also disable key scanning */
+#define KBC_ENABLE 0xF4 /* enable key scanning */
+#define KBC_TYPEMATIC 0xF3 /* set typematic rate and delay */
+#define KBC_SETTABLE 0xF0 /* set scancode translation table */
+#define KBC_MODEIND 0xED /* set mode indicators (i.e. LEDs) */
+#define KBC_ECHO 0xEE /* request an echo from the keyboard */
+
+/* keyboard responses */
+#define KBR_EXTENDED 0xE0 /* extended key sequence */
+#define KBR_RESEND 0xFE /* needs resend of command */
+#define KBR_ACK 0xFA /* received a valid command */
+#define KBR_OVERRUN 0x00 /* flooded */
+#define KBR_FAILURE 0xFD /* diagnosic failure */
+#define KBR_BREAK 0xF0 /* break code prefix - sent on key release */
+#define KBR_RSTDONE 0xAA /* reset complete */
+#define KBR_ECHO 0xEE /* echo response */
diff --git a/sys/arch/i386/isa/lms.c b/sys/arch/i386/isa/lms.c
new file mode 100644
index 00000000000..2d79f0d6984
--- /dev/null
+++ b/sys/arch/i386/isa/lms.c
@@ -0,0 +1,351 @@
+/* $NetBSD: lms.c,v 1.20 1995/10/05 22:06:47 mycroft Exp $ */
+
+/*-
+ * Copyright (c) 1993, 1994 Charles Hannum.
+ * Copyright (c) 1992, 1993 Erik Forsberg.
+ * All rights reserved.
+ *
+ * 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY ``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 I 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.
+ */
+
+#include <sys/param.h>
+#include <sys/kernel.h>
+#include <sys/systm.h>
+#include <sys/buf.h>
+#include <sys/malloc.h>
+#include <sys/ioctl.h>
+#include <sys/tty.h>
+#include <sys/file.h>
+#include <sys/select.h>
+#include <sys/proc.h>
+#include <sys/vnode.h>
+#include <sys/device.h>
+
+#include <machine/cpu.h>
+#include <machine/pio.h>
+#include <machine/mouse.h>
+
+#include <dev/isa/isavar.h>
+
+#define LMS_DATA 0 /* offset for data port, read-only */
+#define LMS_SIGN 1 /* offset for signature port, read-write */
+#define LMS_INTR 2 /* offset for interrupt port, read-only */
+#define LMS_CNTRL 2 /* offset for control port, write-only */
+#define LMS_CONFIG 3 /* for configuration port, read-write */
+#define LMS_NPORTS 4
+
+#define LMS_CHUNK 128 /* chunk size for read */
+#define LMS_BSIZE 1020 /* buffer size */
+
+struct lms_softc { /* driver status information */
+ struct device sc_dev;
+ void *sc_ih;
+
+ struct clist sc_q;
+ struct selinfo sc_rsel;
+ int sc_iobase; /* I/O port base */
+ u_char sc_state; /* mouse driver state */
+#define LMS_OPEN 0x01 /* device is open */
+#define LMS_ASLP 0x02 /* waiting for mouse data */
+ u_char sc_status; /* mouse button status */
+ int sc_x, sc_y; /* accumulated motion in the X,Y axis */
+};
+
+int lmsprobe __P((struct device *, void *, void *));
+void lmsattach __P((struct device *, struct device *, void *));
+int lmsintr __P((void *));
+
+struct cfdriver lmscd = {
+ NULL, "lms", lmsprobe, lmsattach, DV_TTY, sizeof(struct lms_softc)
+};
+
+#define LMSUNIT(dev) (minor(dev))
+
+int
+lmsprobe(parent, match, aux)
+ struct device *parent;
+ void *match, *aux;
+{
+ struct isa_attach_args *ia = aux;
+ int iobase = ia->ia_iobase;
+
+ /* Configure and check for port present. */
+ outb(iobase + LMS_CONFIG, 0x91);
+ delay(10);
+ outb(iobase + LMS_SIGN, 0x0c);
+ delay(10);
+ if (inb(iobase + LMS_SIGN) != 0x0c)
+ return 0;
+ outb(iobase + LMS_SIGN, 0x50);
+ delay(10);
+ if (inb(iobase + LMS_SIGN) != 0x50)
+ return 0;
+
+ /* Disable interrupts. */
+ outb(iobase + LMS_CNTRL, 0x10);
+
+ ia->ia_iosize = LMS_NPORTS;
+ ia->ia_msize = 0;
+ return 1;
+}
+
+void
+lmsattach(parent, self, aux)
+ struct device *parent, *self;
+ void *aux;
+{
+ struct lms_softc *sc = (void *)self;
+ struct isa_attach_args *ia = aux;
+ int iobase = ia->ia_iobase;
+
+ printf("\n");
+
+ /* Other initialization was done by lmsprobe. */
+ sc->sc_iobase = iobase;
+ sc->sc_state = 0;
+
+ sc->sc_ih = isa_intr_establish(ia->ia_irq, ISA_IST_PULSE, ISA_IPL_TTY,
+ lmsintr, sc);
+}
+
+int
+lmsopen(dev, flag)
+ dev_t dev;
+ int flag;
+{
+ int unit = LMSUNIT(dev);
+ struct lms_softc *sc;
+
+ if (unit >= lmscd.cd_ndevs)
+ return ENXIO;
+ sc = lmscd.cd_devs[unit];
+ if (!sc)
+ return ENXIO;
+
+ if (sc->sc_state & LMS_OPEN)
+ return EBUSY;
+
+ if (clalloc(&sc->sc_q, LMS_BSIZE, 0) == -1)
+ return ENOMEM;
+
+ sc->sc_state |= LMS_OPEN;
+ sc->sc_status = 0;
+ sc->sc_x = sc->sc_y = 0;
+
+ /* Enable interrupts. */
+ outb(sc->sc_iobase + LMS_CNTRL, 0);
+
+ return 0;
+}
+
+int
+lmsclose(dev, flag)
+ dev_t dev;
+ int flag;
+{
+ struct lms_softc *sc = lmscd.cd_devs[LMSUNIT(dev)];
+
+ /* Disable interrupts. */
+ outb(sc->sc_iobase + LMS_CNTRL, 0x10);
+
+ sc->sc_state &= ~LMS_OPEN;
+
+ clfree(&sc->sc_q);
+
+ return 0;
+}
+
+int
+lmsread(dev, uio, flag)
+ dev_t dev;
+ struct uio *uio;
+ int flag;
+{
+ struct lms_softc *sc = lmscd.cd_devs[LMSUNIT(dev)];
+ int s;
+ int error;
+ size_t length;
+ u_char buffer[LMS_CHUNK];
+
+ /* Block until mouse activity occured. */
+
+ s = spltty();
+ while (sc->sc_q.c_cc == 0) {
+ if (flag & IO_NDELAY) {
+ splx(s);
+ return EWOULDBLOCK;
+ }
+ sc->sc_state |= LMS_ASLP;
+ if (error = tsleep((caddr_t)sc, PZERO | PCATCH, "lmsrea", 0)) {
+ sc->sc_state &= ~LMS_ASLP;
+ splx(s);
+ return error;
+ }
+ }
+ splx(s);
+
+ /* Transfer as many chunks as possible. */
+
+ while (sc->sc_q.c_cc > 0 && uio->uio_resid > 0) {
+ length = min(sc->sc_q.c_cc, uio->uio_resid);
+ if (length > sizeof(buffer))
+ length = sizeof(buffer);
+
+ /* Remove a small chunk from the input queue. */
+ (void) q_to_b(&sc->sc_q, buffer, length);
+
+ /* Copy the data to the user process. */
+ if (error = uiomove(buffer, length, uio))
+ break;
+ }
+
+ return error;
+}
+
+int
+lmsioctl(dev, cmd, addr, flag)
+ dev_t dev;
+ u_long cmd;
+ caddr_t addr;
+ int flag;
+{
+ struct lms_softc *sc = lmscd.cd_devs[LMSUNIT(dev)];
+ struct mouseinfo info;
+ int s;
+ int error;
+
+ switch (cmd) {
+ case MOUSEIOCREAD:
+ s = spltty();
+
+ info.status = sc->sc_status;
+ if (sc->sc_x || sc->sc_y)
+ info.status |= MOVEMENT;
+
+ if (sc->sc_x > 127)
+ info.xmotion = 127;
+ else if (sc->sc_x < -127)
+ /* Bounding at -127 avoids a bug in XFree86. */
+ info.xmotion = -127;
+ else
+ info.xmotion = sc->sc_x;
+
+ if (sc->sc_y > 127)
+ info.ymotion = 127;
+ else if (sc->sc_y < -127)
+ info.ymotion = -127;
+ else
+ info.ymotion = sc->sc_y;
+
+ /* Reset historical information. */
+ sc->sc_x = sc->sc_y = 0;
+ sc->sc_status &= ~BUTCHNGMASK;
+ ndflush(&sc->sc_q, sc->sc_q.c_cc);
+
+ splx(s);
+ error = copyout(&info, addr, sizeof(struct mouseinfo));
+ break;
+
+ default:
+ error = EINVAL;
+ break;
+ }
+
+ return error;
+}
+
+int
+lmsintr(arg)
+ void *arg;
+{
+ struct lms_softc *sc = arg;
+ int iobase = sc->sc_iobase;
+ u_char hi, lo, buttons, changed;
+ char dx, dy;
+ u_char buffer[5];
+
+ if ((sc->sc_state & LMS_OPEN) == 0)
+ /* Interrupts are not expected. */
+ return 0;
+
+ outb(iobase + LMS_CNTRL, 0xab);
+ hi = inb(iobase + LMS_DATA);
+ outb(iobase + LMS_CNTRL, 0x90);
+ lo = inb(iobase + LMS_DATA);
+ dx = ((hi & 0x0f) << 4) | (lo & 0x0f);
+ /* Bounding at -127 avoids a bug in XFree86. */
+ dx = (dx == -128) ? -127 : dx;
+
+ outb(iobase + LMS_CNTRL, 0xf0);
+ hi = inb(iobase + LMS_DATA);
+ outb(iobase + LMS_CNTRL, 0xd0);
+ lo = inb(iobase + LMS_DATA);
+ dy = ((hi & 0x0f) << 4) | (lo & 0x0f);
+ dy = (dy == -128) ? 127 : -dy;
+
+ outb(iobase + LMS_CNTRL, 0);
+
+ buttons = (~hi >> 5) & 0x07;
+ changed = ((buttons ^ sc->sc_status) & 0x07) << 3;
+ sc->sc_status = buttons | (sc->sc_status & ~BUTSTATMASK) | changed;
+
+ if (dx || dy || changed) {
+ /* Update accumulated movements. */
+ sc->sc_x += dx;
+ sc->sc_y += dy;
+
+ /* Add this event to the queue. */
+ buffer[0] = 0x80 | (buttons ^ BUTSTATMASK);
+ buffer[1] = dx;
+ buffer[2] = dy;
+ buffer[3] = buffer[4] = 0;
+ (void) b_to_q(buffer, sizeof buffer, &sc->sc_q);
+
+ if (sc->sc_state & LMS_ASLP) {
+ sc->sc_state &= ~LMS_ASLP;
+ wakeup((caddr_t)sc);
+ }
+ selwakeup(&sc->sc_rsel);
+ }
+
+ return -1;
+}
+
+int
+lmsselect(dev, rw, p)
+ dev_t dev;
+ int rw;
+ struct proc *p;
+{
+ struct lms_softc *sc = lmscd.cd_devs[LMSUNIT(dev)];
+ int s;
+ int ret;
+
+ if (rw == FWRITE)
+ return 0;
+
+ s = spltty();
+ if (!sc->sc_q.c_cc) {
+ selrecord(p, &sc->sc_rsel);
+ ret = 0;
+ } else
+ ret = 1;
+ splx(s);
+
+ return ret;
+}
diff --git a/sys/arch/i386/isa/mms.c b/sys/arch/i386/isa/mms.c
new file mode 100644
index 00000000000..9081d199a82
--- /dev/null
+++ b/sys/arch/i386/isa/mms.c
@@ -0,0 +1,346 @@
+/* $NetBSD: mms.c,v 1.19 1995/10/05 22:06:51 mycroft Exp $ */
+
+/*-
+ * Copyright (c) 1993, 1994 Charles Hannum.
+ * Copyright (c) 1992, 1993 Erik Forsberg.
+ * All rights reserved.
+ *
+ * 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY ``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 I 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.
+ */
+
+#include <sys/param.h>
+#include <sys/kernel.h>
+#include <sys/systm.h>
+#include <sys/buf.h>
+#include <sys/malloc.h>
+#include <sys/ioctl.h>
+#include <sys/tty.h>
+#include <sys/file.h>
+#include <sys/select.h>
+#include <sys/proc.h>
+#include <sys/vnode.h>
+#include <sys/device.h>
+
+#include <machine/cpu.h>
+#include <machine/pio.h>
+#include <machine/mouse.h>
+
+#include <dev/isa/isavar.h>
+
+#define MMS_ADDR 0 /* offset for register select */
+#define MMS_DATA 1 /* offset for InPort data */
+#define MMS_IDENT 2 /* offset for identification register */
+#define MMS_NPORTS 4
+
+#define MMS_CHUNK 128 /* chunk size for read */
+#define MMS_BSIZE 1020 /* buffer size */
+
+struct mms_softc { /* driver status information */
+ struct device sc_dev;
+ void *sc_ih;
+
+ struct clist sc_q;
+ struct selinfo sc_rsel;
+ int sc_iobase; /* I/O port base */
+ u_char sc_state; /* mouse driver state */
+#define MMS_OPEN 0x01 /* device is open */
+#define MMS_ASLP 0x02 /* waiting for mouse data */
+ u_char sc_status; /* mouse button status */
+ int sc_x, sc_y; /* accumulated motion in the X,Y axis */
+};
+
+int mmsprobe __P((struct device *, void *, void *));
+void mmsattach __P((struct device *, struct device *, void *));
+int mmsintr __P((void *));
+
+struct cfdriver mmscd = {
+ NULL, "mms", mmsprobe, mmsattach, DV_TTY, sizeof(struct mms_softc)
+};
+
+#define MMSUNIT(dev) (minor(dev))
+
+int
+mmsprobe(parent, match, aux)
+ struct device *parent;
+ void *match, *aux;
+{
+ struct isa_attach_args *ia = aux;
+ int iobase = ia->ia_iobase;
+
+ /* Read identification register to see if present */
+ if (inb(iobase + MMS_IDENT) != 0xde)
+ return 0;
+
+ /* Seems it was there; reset. */
+ outb(iobase + MMS_ADDR, 0x87);
+
+ ia->ia_iosize = MMS_NPORTS;
+ ia->ia_msize = 0;
+ return 1;
+}
+
+void
+mmsattach(parent, self, aux)
+ struct device *parent, *self;
+ void *aux;
+{
+ struct mms_softc *sc = (void *)self;
+ struct isa_attach_args *ia = aux;
+ int iobase = ia->ia_iobase;
+
+ printf("\n");
+
+ /* Other initialization was done by mmsprobe. */
+ sc->sc_iobase = iobase;
+ sc->sc_state = 0;
+
+ sc->sc_ih = isa_intr_establish(ia->ia_irq, ISA_IST_PULSE, ISA_IPL_TTY,
+ mmsintr, sc);
+}
+
+int
+mmsopen(dev, flag)
+ dev_t dev;
+ int flag;
+{
+ int unit = MMSUNIT(dev);
+ struct mms_softc *sc;
+
+ if (unit >= mmscd.cd_ndevs)
+ return ENXIO;
+ sc = mmscd.cd_devs[unit];
+ if (!sc)
+ return ENXIO;
+
+ if (sc->sc_state & MMS_OPEN)
+ return EBUSY;
+
+ if (clalloc(&sc->sc_q, MMS_BSIZE, 0) == -1)
+ return ENOMEM;
+
+ sc->sc_state |= MMS_OPEN;
+ sc->sc_status = 0;
+ sc->sc_x = sc->sc_y = 0;
+
+ /* Enable interrupts. */
+ outb(sc->sc_iobase + MMS_ADDR, 0x07);
+ outb(sc->sc_iobase + MMS_DATA, 0x09);
+
+ return 0;
+}
+
+int
+mmsclose(dev, flag)
+ dev_t dev;
+ int flag;
+{
+ struct mms_softc *sc = mmscd.cd_devs[MMSUNIT(dev)];
+
+ /* Disable interrupts. */
+ outb(sc->sc_iobase + MMS_ADDR, 0x87);
+
+ sc->sc_state &= ~MMS_OPEN;
+
+ clfree(&sc->sc_q);
+
+ return 0;
+}
+
+int
+mmsread(dev, uio, flag)
+ dev_t dev;
+ struct uio *uio;
+ int flag;
+{
+ struct mms_softc *sc = mmscd.cd_devs[MMSUNIT(dev)];
+ int s;
+ int error;
+ size_t length;
+ u_char buffer[MMS_CHUNK];
+
+ /* Block until mouse activity occured. */
+
+ s = spltty();
+ while (sc->sc_q.c_cc == 0) {
+ if (flag & IO_NDELAY) {
+ splx(s);
+ return EWOULDBLOCK;
+ }
+ sc->sc_state |= MMS_ASLP;
+ if (error = tsleep((caddr_t)sc, PZERO | PCATCH, "mmsrea", 0)) {
+ sc->sc_state &= ~MMS_ASLP;
+ splx(s);
+ return error;
+ }
+ }
+ splx(s);
+
+ /* Transfer as many chunks as possible. */
+
+ while (sc->sc_q.c_cc > 0 && uio->uio_resid > 0) {
+ length = min(sc->sc_q.c_cc, uio->uio_resid);
+ if (length > sizeof(buffer))
+ length = sizeof(buffer);
+
+ /* Remove a small chunk from the input queue. */
+ (void) q_to_b(&sc->sc_q, buffer, length);
+
+ /* Copy the data to the user process. */
+ if (error = uiomove(buffer, length, uio))
+ break;
+ }
+
+ return error;
+}
+
+int
+mmsioctl(dev, cmd, addr, flag)
+ dev_t dev;
+ u_long cmd;
+ caddr_t addr;
+ int flag;
+{
+ struct mms_softc *sc = mmscd.cd_devs[MMSUNIT(dev)];
+ struct mouseinfo info;
+ int s;
+ int error;
+
+ switch (cmd) {
+ case MOUSEIOCREAD:
+ s = spltty();
+
+ info.status = sc->sc_status;
+ if (sc->sc_x || sc->sc_y)
+ info.status |= MOVEMENT;
+
+ if (sc->sc_x > 127)
+ info.xmotion = 127;
+ else if (sc->sc_x < -127)
+ /* Bounding at -127 avoids a bug in XFree86. */
+ info.xmotion = -127;
+ else
+ info.xmotion = sc->sc_x;
+
+ if (sc->sc_y > 127)
+ info.ymotion = 127;
+ else if (sc->sc_y < -127)
+ info.ymotion = -127;
+ else
+ info.ymotion = sc->sc_y;
+
+ /* Reset historical information. */
+ sc->sc_x = sc->sc_y = 0;
+ sc->sc_status &= ~BUTCHNGMASK;
+ ndflush(&sc->sc_q, sc->sc_q.c_cc);
+
+ splx(s);
+ error = copyout(&info, addr, sizeof(struct mouseinfo));
+ break;
+
+ default:
+ error = EINVAL;
+ break;
+ }
+
+ return error;
+}
+
+int
+mmsintr(arg)
+ void *arg;
+{
+ struct mms_softc *sc = arg;
+ int iobase = sc->sc_iobase;
+ u_char buttons, changed, status;
+ char dx, dy;
+ u_char buffer[5];
+
+ if ((sc->sc_state & MMS_OPEN) == 0)
+ /* Interrupts are not expected. */
+ return 0;
+
+ /* Freeze InPort registers (disabling interrupts). */
+ outb(iobase + MMS_ADDR, 0x07);
+ outb(iobase + MMS_DATA, 0x29);
+
+ outb(iobase + MMS_ADDR, 0x00);
+ status = inb(iobase + MMS_DATA);
+
+ if (status & 0x40) {
+ outb(iobase + MMS_ADDR, 1);
+ dx = inb(iobase + MMS_DATA);
+ dx = (dx == -128) ? -127 : dx;
+ outb(iobase + MMS_ADDR, 2);
+ dy = inb(iobase + MMS_DATA);
+ dy = (dy == -128) ? 127 : -dy;
+ } else
+ dx = dy = 0;
+
+ /* Unfreeze InPort registers (reenabling interrupts). */
+ outb(iobase + MMS_ADDR, 0x07);
+ outb(iobase + MMS_DATA, 0x09);
+
+ buttons = status & BUTSTATMASK;
+ changed = status & BUTCHNGMASK;
+ sc->sc_status = buttons | (sc->sc_status & ~BUTSTATMASK) | changed;
+
+ if (dx || dy || changed) {
+ /* Update accumulated movements. */
+ sc->sc_x += dx;
+ sc->sc_y += dy;
+
+ /* Add this event to the queue. */
+ buffer[0] = 0x80 | (buttons ^ BUTSTATMASK);
+ buffer[1] = dx;
+ buffer[2] = dy;
+ buffer[3] = buffer[4] = 0;
+ (void) b_to_q(buffer, sizeof buffer, &sc->sc_q);
+
+ if (sc->sc_state & MMS_ASLP) {
+ sc->sc_state &= ~MMS_ASLP;
+ wakeup((caddr_t)sc);
+ }
+ selwakeup(&sc->sc_rsel);
+ }
+
+ return -1;
+}
+
+int
+mmsselect(dev, rw, p)
+ dev_t dev;
+ int rw;
+ struct proc *p;
+{
+ struct mms_softc *sc = mmscd.cd_devs[MMSUNIT(dev)];
+ int s;
+ int ret;
+
+ if (rw == FWRITE)
+ return 0;
+
+ s = spltty();
+ if (!sc->sc_q.c_cc) {
+ selrecord(p, &sc->sc_rsel);
+ ret = 0;
+ } else
+ ret = 1;
+ splx(s);
+
+ return ret;
+}
diff --git a/sys/arch/i386/isa/npx.c b/sys/arch/i386/isa/npx.c
new file mode 100644
index 00000000000..ab6f116b8bd
--- /dev/null
+++ b/sys/arch/i386/isa/npx.c
@@ -0,0 +1,589 @@
+/* $NetBSD: npx.c,v 1.51 1995/10/10 04:46:09 mycroft Exp $ */
+
+#if 0
+#define iprintf(x) printf x
+#else
+#define iprintf(x)
+#endif
+
+/*-
+ * Copyright (c) 1994, 1995 Charles M. Hannum. All rights reserved.
+ * Copyright (c) 1990 William Jolitz.
+ * Copyright (c) 1991 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * 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.
+ *
+ * @(#)npx.c 7.2 (Berkeley) 5/12/91
+ */
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/conf.h>
+#include <sys/file.h>
+#include <sys/proc.h>
+#include <sys/user.h>
+#include <sys/ioctl.h>
+#include <sys/device.h>
+
+#include <machine/cpu.h>
+#include <machine/pio.h>
+#include <machine/cpufunc.h>
+#include <machine/pcb.h>
+#include <machine/trap.h>
+#include <machine/specialreg.h>
+
+#include <i386/isa/icu.h>
+#include <dev/isa/isavar.h>
+#include <dev/isa/isareg.h>
+
+/*
+ * 387 and 287 Numeric Coprocessor Extension (NPX) Driver.
+ *
+ * We do lazy initialization and switching using the TS bit in cr0 and the
+ * MDP_USEDFPU bit in mdproc.
+ *
+ * DNA exceptions are handled like this:
+ *
+ * 1) If there is no NPX, return and go to the emulator.
+ * 2) If someone else has used the NPX, save its state into that process's PCB.
+ * 3a) If MDP_USEDFPU is not set, set it and initialize the NPX.
+ * 3b) Otherwise, reload the process's previous NPX state.
+ *
+ * When a process is created or exec()s, its saved cr0 image has the TS bit
+ * set and the MDP_USEDFPU bit clear. The MDP_USEDFPU bit is set when the
+ * process first gets a DNA and the NPX is initialized. The TS bit is turned
+ * off when the NPX is used, and turned on again later when the process's NPX
+ * state is saved.
+ */
+
+#define fldcw(addr) __asm("fldcw %0" : : "m" (*addr))
+#define fnclex() __asm("fnclex")
+#define fninit() __asm("fninit")
+#define fnsave(addr) __asm("fnsave %0" : "=m" (*addr))
+#define fnstcw(addr) __asm("fnstcw %0" : "=m" (*addr))
+#define fnstsw(addr) __asm("fnstsw %0" : "=m" (*addr))
+#define fp_divide_by_0() __asm("fldz; fld1; fdiv %st,%st(1); fwait")
+#define frstor(addr) __asm("frstor %0" : : "m" (*addr))
+#define fwait() __asm("fwait")
+#define read_eflags() ({register u_long ef; \
+ __asm("pushfl; popl %0" : "=r" (ef)); \
+ ef;})
+#define write_eflags(x) ({register u_long ef = (x); \
+ __asm("pushl %0; popfl" : : "r" (ef));})
+#define clts() __asm("clts")
+#define stts() lcr0(rcr0() | CR0_TS)
+
+int npxdna __P((struct proc *));
+void npxexit __P((void));
+int npxintr __P((void *));
+static int npxprobe1 __P((struct isa_attach_args *));
+void npxsave __P((void));
+static void npxsave1 __P((void));
+
+struct npx_softc {
+ struct device sc_dev;
+ void *sc_ih;
+};
+
+int npxprobe __P((struct device *, void *, void *));
+void npxattach __P((struct device *, struct device *, void *));
+
+struct cfdriver npxcd = {
+ NULL, "npx", npxprobe, npxattach, DV_DULL, sizeof(struct npx_softc)
+};
+
+enum npx_type {
+ NPX_NONE = 0,
+ NPX_INTERRUPT,
+ NPX_EXCEPTION,
+ NPX_BROKEN,
+};
+
+struct proc *npxproc;
+
+static enum npx_type npx_type;
+static int npx_nointr;
+static volatile u_int npx_intrs_while_probing;
+static volatile u_int npx_traps_while_probing;
+
+/*
+ * Special interrupt handlers. Someday intr0-intr15 will be used to count
+ * interrupts. We'll still need a special exception 16 handler. The busy
+ * latch stuff in probintr() can be moved to npxprobe().
+ */
+void probeintr __P((void));
+asm ("
+ .text
+_probeintr:
+ ss
+ incl _npx_intrs_while_probing
+ pushl %eax
+ movb $0x20,%al # EOI (asm in strings loses cpp features)
+ outb %al,$0xa0 # IO_ICU2
+ outb %al,$0x20 # IO_ICU1
+ movb $0,%al
+ outb %al,$0xf0 # clear BUSY# latch
+ popl %eax
+ iret
+");
+
+void probetrap __P((void));
+asm ("
+ .text
+_probetrap:
+ ss
+ incl _npx_traps_while_probing
+ fnclex
+ iret
+");
+
+static inline int
+npxprobe1(ia)
+ struct isa_attach_args *ia;
+{
+ int control;
+ int status;
+
+ ia->ia_iosize = 16;
+ ia->ia_msize = 0;
+
+ /*
+ * Finish resetting the coprocessor, if any. If there is an error
+ * pending, then we may get a bogus IRQ13, but probeintr() will handle
+ * it OK. Bogus halts have never been observed, but we enabled
+ * IRQ13 and cleared the BUSY# latch early to handle them anyway.
+ */
+ fninit();
+ delay(1000); /* wait for any IRQ13 (fwait might hang) */
+
+ /*
+ * Check for a status of mostly zero.
+ */
+ status = 0x5a5a;
+ fnstsw(&status);
+ if ((status & 0xb8ff) == 0) {
+ /*
+ * Good, now check for a proper control word.
+ */
+ control = 0x5a5a;
+ fnstcw(&control);
+ if ((control & 0x1f3f) == 0x033f) {
+ /*
+ * We have an npx, now divide by 0 to see if exception
+ * 16 works.
+ */
+ control &= ~(1 << 2); /* enable divide by 0 trap */
+ fldcw(&control);
+ npx_traps_while_probing = npx_intrs_while_probing = 0;
+ fp_divide_by_0();
+ if (npx_traps_while_probing != 0) {
+ /*
+ * Good, exception 16 works.
+ */
+ npx_type = NPX_EXCEPTION;
+ ia->ia_irq = IRQUNK; /* zap the interrupt */
+ } else if (npx_intrs_while_probing != 0) {
+ /*
+ * Bad, we are stuck with IRQ13.
+ */
+ npx_type = NPX_INTERRUPT;
+ } else {
+ /*
+ * Worse, even IRQ13 is broken. Use emulator.
+ */
+ npx_type = NPX_BROKEN;
+ ia->ia_irq = IRQUNK;
+ }
+ return 1;
+ }
+ }
+ /*
+ * Probe failed. There is no usable FPU.
+ */
+ npx_type = NPX_NONE;
+ return 0;
+}
+
+/*
+ * Probe routine. Initialize cr0 to give correct behaviour for [f]wait
+ * whether the device exists or not (XXX should be elsewhere). Set flags
+ * to tell npxattach() what to do. Modify device struct if npx doesn't
+ * need to use interrupts. Return 1 if device exists.
+ */
+int
+npxprobe(parent, match, aux)
+ struct device *parent;
+ void *match, *aux;
+{
+ struct isa_attach_args *ia = aux;
+ int irq;
+ int result;
+ u_long save_eflags;
+ unsigned save_imen;
+ struct gate_descriptor save_idt_npxintr;
+ struct gate_descriptor save_idt_npxtrap;
+
+ /*
+ * This routine is now just a wrapper for npxprobe1(), to install
+ * special npx interrupt and trap handlers, to enable npx interrupts
+ * and to disable other interrupts. Someday isa_configure() will
+ * install suitable handlers and run with interrupts enabled so we
+ * won't need to do so much here.
+ */
+ irq = NRSVIDT + ia->ia_irq;
+ save_eflags = read_eflags();
+ disable_intr();
+ save_idt_npxintr = idt[irq];
+ save_idt_npxtrap = idt[16];
+ setgate(&idt[irq], probeintr, 0, SDT_SYS386IGT, SEL_KPL);
+ setgate(&idt[16], probetrap, 0, SDT_SYS386TGT, SEL_KPL);
+ save_imen = imen;
+ imen = ~((1 << IRQ_SLAVE) | (1 << ia->ia_irq));
+ SET_ICUS();
+
+ /*
+ * Partially reset the coprocessor, if any. Some BIOS's don't reset
+ * it after a warm boot.
+ */
+ outb(0xf1, 0); /* full reset on some systems, NOP on others */
+ delay(1000);
+ outb(0xf0, 0); /* clear BUSY# latch */
+
+ /*
+ * We set CR0 in locore to trap all ESC and WAIT instructions.
+ * We have to turn off the CR0_EM bit temporarily while probing.
+ */
+ lcr0(rcr0() & ~(CR0_EM|CR0_TS));
+ enable_intr();
+ result = npxprobe1(ia);
+ disable_intr();
+ lcr0(rcr0() | (CR0_EM|CR0_TS));
+
+ imen = save_imen;
+ SET_ICUS();
+ idt[irq] = save_idt_npxintr;
+ idt[16] = save_idt_npxtrap;
+ write_eflags(save_eflags);
+ return (result);
+}
+
+int npx586bug1 __P((int, int));
+asm ("
+ .text
+_npx586bug1:
+ fildl 4(%esp) # x
+ fildl 8(%esp) # y
+ fld %st(1)
+ fdiv %st(1),%st # x/y
+ fmulp %st,%st(1) # (x/y)*y
+ fsubrp %st,%st(1) # x-(x/y)*y
+ pushl $0
+ fistpl (%esp)
+ popl %eax
+ ret
+");
+
+/*
+ * Attach routine - announce which it is, and wire into system
+ */
+void
+npxattach(parent, self, aux)
+ struct device *parent, *self;
+ void *aux;
+{
+ struct npx_softc *sc = (void *)self;
+ struct isa_attach_args *ia = aux;
+
+ switch (npx_type) {
+ case NPX_INTERRUPT:
+ printf("\n");
+ lcr0(rcr0() & ~CR0_NE);
+ sc->sc_ih = isa_intr_establish(ia->ia_irq, ISA_IST_EDGE,
+ ISA_IPL_NONE, npxintr, 0);
+ break;
+ case NPX_EXCEPTION:
+ printf(": using exception 16\n");
+ break;
+ case NPX_BROKEN:
+ printf(": error reporting broken; not using\n");
+ npx_type = NPX_NONE;
+ return;
+ }
+
+ lcr0(rcr0() & ~(CR0_EM|CR0_TS));
+ fninit();
+ if (npx586bug1(4195835, 3145727) != 0)
+ printf("WARNING: Pentium FDIV bug detected!\n");
+ lcr0(rcr0() | (CR0_TS));
+}
+
+/*
+ * Record the FPU state and reinitialize it all except for the control word.
+ * Then generate a SIGFPE.
+ *
+ * Reinitializing the state allows naive SIGFPE handlers to longjmp without
+ * doing any fixups.
+ *
+ * XXX there is currently no way to pass the full error state to signal
+ * handlers, and if this is a nested interrupt there is no way to pass even
+ * a status code! So there is no way to have a non-naive SIGFPE handler. At
+ * best a handler could do an fninit followed by an fldcw of a static value.
+ * fnclex would be of little use because it would leave junk on the FPU stack.
+ * Returning from the handler would be even less safe than usual because
+ * IRQ13 exception handling makes exceptions even less precise than usual.
+ */
+int
+npxintr(arg)
+ void *arg;
+{
+ register struct proc *p = npxproc;
+ register struct save87 *addr;
+ struct intrframe *frame = arg;
+ int code;
+
+ cnt.v_trap++;
+ iprintf(("Intr"));
+
+ if (p == 0 || npx_type == NPX_NONE) {
+ /* XXX no %p in stand/printf.c. Cast to quiet gcc -Wall. */
+ printf("npxintr: p = %lx, curproc = %lx, npx_type = %d\n",
+ (u_long) p, (u_long) curproc, npx_type);
+ panic("npxintr from nowhere");
+ }
+ /*
+ * Clear the interrupt latch.
+ */
+ outb(0xf0, 0);
+ /*
+ * If we're saving, ignore the interrupt. The FPU will happily
+ * generate another one when we restore the state later.
+ */
+ if (npx_nointr != 0)
+ return (1);
+ /*
+ * Find the address of npxproc's savefpu. This is not necessarily
+ * the one in curpcb.
+ */
+ addr = &p->p_addr->u_pcb.pcb_savefpu;
+ /*
+ * Save state. This does an implied fninit. It had better not halt
+ * the cpu or we'll hang.
+ */
+ fnsave(addr);
+ fwait();
+ /*
+ * Restore control word (was clobbered by fnsave).
+ */
+ fldcw(&addr->sv_env.en_cw);
+ fwait();
+ /*
+ * Remember the exception status word and tag word. The current
+ * (almost fninit'ed) fpu state is in the fpu and the exception
+ * state just saved will soon be junk. However, the implied fninit
+ * doesn't change the error pointers or register contents, and we
+ * preserved the control word and will copy the status and tag
+ * words, so the complete exception state can be recovered.
+ */
+ addr->sv_ex_sw = addr->sv_env.en_sw;
+ addr->sv_ex_tw = addr->sv_env.en_tw;
+
+ /*
+ * Pass exception to process. If it's the current process, try to do
+ * it immediately.
+ */
+ if (p == curproc && USERMODE(frame->if_cs, frame->if_eflags)) {
+ /*
+ * Interrupt is essentially a trap, so we can afford to call
+ * the SIGFPE handler (if any) as soon as the interrupt
+ * returns.
+ *
+ * XXX little or nothing is gained from this, and plenty is
+ * lost - the interrupt frame has to contain the trap frame
+ * (this is otherwise only necessary for the rescheduling trap
+ * in doreti, and the frame for that could easily be set up
+ * just before it is used).
+ */
+ p->p_md.md_regs = (struct trapframe *)&frame->if_es;
+#ifdef notyet
+ /*
+ * Encode the appropriate code for detailed information on
+ * this exception.
+ */
+ code = XXX_ENCODE(addr->sv_ex_sw);
+#else
+ code = 0; /* XXX */
+#endif
+ trapsignal(p, SIGFPE, code);
+ } else {
+ /*
+ * Nested interrupt. These losers occur when:
+ * o an IRQ13 is bogusly generated at a bogus time, e.g.:
+ * o immediately after an fnsave or frstor of an
+ * error state.
+ * o a couple of 386 instructions after
+ * "fstpl _memvar" causes a stack overflow.
+ * These are especially nasty when combined with a
+ * trace trap.
+ * o an IRQ13 occurs at the same time as another higher-
+ * priority interrupt.
+ *
+ * Treat them like a true async interrupt.
+ */
+ psignal(p, SIGFPE);
+ }
+
+ return (1);
+}
+
+/*
+ * Wrapper for fnsave instruction to handle h/w bugs. If there is an error
+ * pending, then fnsave generates a bogus IRQ13 on some systems. Force any
+ * IRQ13 to be handled immediately, and then ignore it.
+ *
+ * This routine is always called at spl0. If it might called with the NPX
+ * interrupt masked, it would be necessary to forcibly unmask the NPX interrupt
+ * so that it could succeed.
+ */
+static inline void
+npxsave1()
+{
+ register struct pcb *pcb;
+
+ npx_nointr = 1;
+ pcb = &npxproc->p_addr->u_pcb;
+ fnsave(&pcb->pcb_savefpu);
+ pcb->pcb_cr0 |= CR0_TS;
+ fwait();
+ npx_nointr = 0;
+}
+
+/*
+ * Implement device not available (DNA) exception
+ *
+ * If the we were the last process to use the FPU, we can simply return.
+ * Otherwise, we save the previous state, if necessary, and restore our last
+ * saved state.
+ */
+int
+npxdna(p)
+ struct proc *p;
+{
+ static u_short control = __INITIAL_NPXCW__;
+
+ if (npx_type == NPX_NONE) {
+ iprintf(("Emul"));
+ return (0);
+ }
+
+#ifdef DIAGNOSTIC
+ if (cpl != 0 || npx_nointr != 0)
+ panic("npxdna: masked");
+#endif
+
+ p->p_addr->u_pcb.pcb_cr0 &= ~CR0_TS;
+ clts();
+
+ if ((p->p_md.md_flags & MDP_USEDFPU) == 0) {
+ p->p_md.md_flags |= MDP_USEDFPU;
+ iprintf(("Init"));
+ if (npxproc != 0 && npxproc != p)
+ npxsave1();
+ else {
+ npx_nointr = 1;
+ fninit();
+ fwait();
+ npx_nointr = 0;
+ }
+ npxproc = p;
+ fldcw(&control);
+ } else {
+ if (npxproc != 0) {
+#ifdef DIAGNOSTIC
+ if (npxproc == p)
+ panic("npxdna: same process");
+#endif
+ iprintf(("Save"));
+ npxsave1();
+ }
+ npxproc = p;
+ /*
+ * The following frstor may cause an IRQ13 when the state being
+ * restored has a pending error. The error will appear to have
+ * been triggered by the current (npx) user instruction even
+ * when that instruction is a no-wait instruction that should
+ * not trigger an error (e.g., fnclex). On at least one 486
+ * system all of the no-wait instructions are broken the same
+ * as frstor, so our treatment does not amplify the breakage.
+ * On at least one 386/Cyrix 387 system, fnclex works correctly
+ * while frstor and fnsave are broken, so our treatment breaks
+ * fnclex if it is the first FPU instruction after a context
+ * switch.
+ */
+ frstor(&p->p_addr->u_pcb.pcb_savefpu);
+ }
+
+ return (1);
+}
+
+/*
+ * Drop the current FPU state on the floor.
+ */
+void
+npxdrop()
+{
+
+ stts();
+ npxproc->p_addr->u_pcb.pcb_cr0 |= CR0_TS;
+ npxproc = 0;
+}
+
+/*
+ * Save npxproc's FPU state.
+ *
+ * The FNSAVE instruction clears the FPU state. Rather than reloading the FPU
+ * immediately, we clear npxproc and turn on CR0_TS to force a DNA and a reload
+ * of the FPU state the next time we try to use it. This routine is only
+ * called when forking or core dump, so this algorithm at worst forces us to
+ * trap once per fork(), and at best saves us a reload once per fork().
+ */
+void
+npxsave()
+{
+
+#ifdef DIAGNOSTIC
+ if (cpl != 0 || npx_nointr != 0)
+ panic("npxsave: masked");
+#endif
+ iprintf(("Fork"));
+ clts();
+ npxsave1();
+ stts();
+ npxproc = 0;
+}
diff --git a/sys/arch/i386/isa/nvram.h b/sys/arch/i386/isa/nvram.h
new file mode 100644
index 00000000000..31c24afdf53
--- /dev/null
+++ b/sys/arch/i386/isa/nvram.h
@@ -0,0 +1,86 @@
+/* $NetBSD: nvram.h,v 1.5 1995/05/05 22:08:43 mycroft Exp $ */
+
+/*-
+ * 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.
+ *
+ * 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.
+ *
+ * @(#)rtc.h 8.1 (Berkeley) 6/11/93
+ */
+
+/*
+ * The following information is found in the non-volatile RAM in the
+ * MC146818A (or DS1287A or other compatible) RTC on AT-compatible PCs.
+ */
+
+/* NVRAM byte 0: bios diagnostic */
+#define NVRAM_DIAG (MC_NVRAM_START + 0) /* RTC offset 0xe */
+
+#define NVRAM_DIAG_BITS "\020\010clock_battery\007ROM_cksum\006config_unit\005memory_size\004fixed_disk\003invalid_time"
+
+/* NVRAM byte 1: reset code */
+#define NVRAM_RESET (MC_NVRAM_START + 1) /* RTC offset 0xf */
+
+#define NVRAM_RESET_RST 0x00 /* normal reset */
+#define NVRAM_RESET_LOAD 0x04 /* load system */
+
+/* NVRAM byte 2: diskette drive type in upper/lower nibble */
+#define NVRAM_DISKETTE (MC_NVRAM_START + 2) /* RTC offset 0x10 */
+
+#define NVRAM_DISKETTE_NONE 0 /* none present */
+#define NVRAM_DISKETTE_360K 0x10 /* 360K */
+#define NVRAM_DISKETTE_12M 0x20 /* 1.2M */
+#define NVRAM_DISKETTE_720K 0x30 /* 720K */
+#define NVRAM_DISKETTE_144M 0x40 /* 1.44M */
+#define NVRAM_DISKETTE_TYPE5 0x50 /* 2.88M, presumably */
+#define NVRAM_DISKETTE_TYPE6 0x60 /* 2.88M */
+
+/* NVRAM byte 6: equipment type */
+#define NVRAM_EQUIPMENT (MC_NVRAM_START + 6)
+
+#define NVRAM_EQUIPMENT_EGAVGA 0x00 /* EGA or VGA */
+#define NVRAM_EQUIPMENT_COLOR40 0x10 /* 40 column color */
+#define NVRAM_EQUIPMENT_COLOR80 0x20 /* 80 column color */
+#define NVRAM_EQUIPMENT_MONO80 0x30 /* 80 column mono */
+#define NVRAM_EQUIPMENT_MONITOR 0x30 /* mask for monitor type */
+
+/* NVRAM bytes 7 & 8: base memory size */
+#define NVRAM_BASELO (MC_NVRAM_START + 7) /* low byte; RTC off. 0x15 */
+#define NVRAM_BASEHI (MC_NVRAM_START + 8) /* high byte; RTC off. 0x16 */
+
+/* NVRAM bytes 9 & 10: extended memory size */
+#define NVRAM_EXTLO (MC_NVRAM_START + 9) /* low byte; RTC off. 0x17 */
+#define NVRAM_EXTHI (MC_NVRAM_START + 10) /* high byte; RTC off. 0x18 */
+
+/* NVRAM byte 36: current century. (please increment in Dec99!) */
+#define NVRAM_CENTURY (MC_NVRAM_START + 36) /* RTC offset 0x32 */
diff --git a/sys/arch/i386/isa/pccons.c b/sys/arch/i386/isa/pccons.c
new file mode 100644
index 00000000000..7ffe1503080
--- /dev/null
+++ b/sys/arch/i386/isa/pccons.c
@@ -0,0 +1,1662 @@
+/* $NetBSD: pccons.c,v 1.90 1995/10/11 04:20:33 mycroft Exp $ */
+
+/*-
+ * Copyright (c) 1993, 1994, 1995 Charles Hannum. All rights reserved.
+ * Copyright (c) 1990 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 5.11 (Berkeley) 5/21/91
+ */
+
+/*
+ * 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/select.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 <sys/device.h>
+
+#include <dev/cons.h>
+
+#include <machine/cpu.h>
+#include <machine/pio.h>
+#include <machine/pc/display.h>
+#include <machine/pccons.h>
+
+#include <dev/isa/isareg.h>
+#include <dev/isa/isavar.h>
+#include <i386/isa/isa_machdep.h>
+#include <i386/isa/kbdreg.h>
+
+#define XFREE86_BUG_COMPAT
+
+#ifndef BEEP_FREQ
+#define BEEP_FREQ 1500
+#endif
+#ifndef BEEP_TIME
+#define BEEP_TIME (hz/5)
+#endif
+
+#define PCBURST 128
+
+static u_short *Crtat; /* pointer to backing store */
+static u_short *crtat; /* pointer to current char */
+static volatile u_char ack, nak; /* Don't ask. */
+static u_char async, kernel, polling; /* Really, you don't want to know. */
+static u_char lock_state = 0x00, /* all off */
+ old_lock_state = 0xff,
+ typematic_rate = 0xff, /* don't update until set by user */
+ old_typematic_rate = 0xff;
+static u_short cursor_shape = 0xffff, /* don't update until set by user */
+ old_cursor_shape = 0xffff;
+int pc_xmode = 0;
+
+#define PCUNIT(x) (minor(x))
+
+static struct video_state {
+ int cx, cy; /* escape parameters */
+ int row, col; /* current cursor position */
+ int nrow, ncol, nchr; /* current screen geometry */
+ u_char state; /* parser state */
+#define VSS_ESCAPE 1
+#define VSS_EBRACE 2
+#define VSS_EPARAM 3
+ char so; /* in standout mode? */
+ char color; /* color or mono display */
+ char at; /* normal attributes */
+ char so_at; /* standout attributes */
+} vs;
+
+struct pc_softc {
+ struct device sc_dev;
+ void *sc_ih;
+ struct tty *sc_tty;
+};
+
+int pcprobe __P((struct device *, void *, void *));
+void pcattach __P((struct device *, struct device *, void *));
+int pcintr __P((void *));
+
+struct cfdriver pccd = {
+ NULL, "pc", pcprobe, pcattach, DV_TTY, sizeof(struct pc_softc)
+};
+
+#define COL 80
+#define ROW 25
+#define CHR 2
+
+/*
+ * DANGER WIL ROBINSON -- the values of SCROLL, NUM, CAPS, and ALT are
+ * important.
+ */
+#define SCROLL 0x0001 /* stop output */
+#define NUM 0x0002 /* numeric shift cursors vs. numeric */
+#define CAPS 0x0004 /* caps shift -- swaps case of letter */
+#define SHIFT 0x0008 /* keyboard shift */
+#define CTL 0x0010 /* control shift -- allows ctl function */
+#define ASCII 0x0020 /* ascii code for this key */
+#define ALT 0x0080 /* alternate shift -- alternate chars */
+#define FUNC 0x0100 /* function key */
+#define KP 0x0200 /* Keypad keys */
+#define NONE 0x0400 /* no function */
+
+static unsigned int addr_6845 = MONO_BASE;
+
+char *sget __P((void));
+void sput __P((u_char *, int));
+
+void pcstart();
+int pcparam();
+char partab[];
+
+extern pcopen(dev_t, int, int, struct proc *);
+
+#define KBD_DELAY \
+ { u_char x = inb(0x84); } \
+ { u_char x = inb(0x84); } \
+ { u_char x = inb(0x84); } \
+ { u_char x = inb(0x84); }
+
+static inline int
+kbd_wait_output()
+{
+ u_int i;
+
+ for (i = 100000; i; i--)
+ if ((inb(KBSTATP) & KBS_IBF) == 0) {
+ KBD_DELAY;
+ return 1;
+ }
+ return 0;
+}
+
+static inline int
+kbd_wait_input()
+{
+ u_int i;
+
+ for (i = 100000; i; i--)
+ if ((inb(KBSTATP) & KBS_DIB) != 0) {
+ KBD_DELAY;
+ return 1;
+ }
+ return 0;
+}
+
+static inline void
+kbd_flush_input()
+{
+ u_int i;
+
+ for (i = 10; i; i--) {
+ if ((inb(KBSTATP) & KBS_DIB) == 0)
+ return;
+ KBD_DELAY;
+ (void) inb(KBDATAP);
+ }
+}
+
+#if 1
+/*
+ * Get the current command byte.
+ */
+static u_char
+kbc_get8042cmd()
+{
+
+ if (!kbd_wait_output())
+ return -1;
+ outb(KBCMDP, K_RDCMDBYTE);
+ if (!kbd_wait_input())
+ return -1;
+ return inb(KBDATAP);
+}
+#endif
+
+/*
+ * Pass command byte to keyboard controller (8042).
+ */
+static int
+kbc_put8042cmd(val)
+ u_char val;
+{
+
+ if (!kbd_wait_output())
+ return 0;
+ outb(KBCMDP, K_LDCMDBYTE);
+ if (!kbd_wait_output())
+ return 0;
+ outb(KBOUTP, val);
+ return 1;
+}
+
+/*
+ * Pass command to keyboard itself
+ */
+int
+kbd_cmd(val, polling)
+ u_char val;
+ u_char polling;
+{
+ u_int retries = 3;
+ register u_int i;
+
+ do {
+ if (!kbd_wait_output())
+ return 0;
+ ack = nak = 0;
+ outb(KBOUTP, val);
+ if (polling)
+ for (i = 100000; i; i--) {
+ if (inb(KBSTATP) & KBS_DIB) {
+ register u_char c;
+
+ KBD_DELAY;
+ c = inb(KBDATAP);
+ if (c == KBR_ACK || c == KBR_ECHO) {
+ ack = 1;
+ return 1;
+ }
+ if (c == KBR_RESEND) {
+ nak = 1;
+ break;
+ }
+#ifdef DIAGNOSTIC
+ printf("kbd_cmd: input char %x lost\n", c);
+#endif
+ }
+ }
+ else
+ for (i = 100000; i; i--) {
+ (void) inb(KBSTATP);
+ if (ack)
+ return 1;
+ if (nak)
+ break;
+ }
+ if (!nak)
+ return 0;
+ } while (--retries);
+ return 0;
+}
+
+void
+set_cursor_shape()
+{
+ register int iobase = addr_6845;
+
+ outb(iobase, 10);
+ outb(iobase+1, cursor_shape >> 8);
+ outb(iobase, 11);
+ outb(iobase+1, cursor_shape);
+ old_cursor_shape = cursor_shape;
+}
+
+void
+get_cursor_shape()
+{
+ register int iobase = addr_6845;
+
+ outb(iobase, 10);
+ cursor_shape = inb(iobase+1) << 8;
+ outb(iobase, 11);
+ cursor_shape |= inb(iobase+1);
+
+ /*
+ * real 6845's, as found on, MDA, Hercules or CGA cards, do
+ * not support reading the cursor shape registers. the 6845
+ * tri-states it's data bus. This is _normally_ read by the
+ * cpu as either 0x00 or 0xff.. in which case we just use
+ * a line cursor.
+ */
+ if (cursor_shape == 0x0000 || cursor_shape == 0xffff)
+ cursor_shape = 0x0b10;
+ else
+ cursor_shape &= 0x1f1f;
+}
+
+void
+do_async_update(poll)
+ u_char poll;
+{
+ int pos;
+ static int old_pos = -1;
+
+ async = 0;
+
+ if (lock_state != old_lock_state) {
+ old_lock_state = lock_state;
+ if (!kbd_cmd(KBC_MODEIND, poll) ||
+ !kbd_cmd(lock_state, poll)) {
+ printf("pc: timeout updating leds\n");
+ (void) kbd_cmd(KBC_ENABLE, poll);
+ }
+ }
+ if (typematic_rate != old_typematic_rate) {
+ old_typematic_rate = typematic_rate;
+ if (!kbd_cmd(KBC_TYPEMATIC, poll) ||
+ !kbd_cmd(typematic_rate, poll)) {
+ printf("pc: timeout updating typematic rate\n");
+ (void) kbd_cmd(KBC_ENABLE, poll);
+ }
+ }
+
+ if (pc_xmode > 0)
+ return;
+
+ pos = crtat - Crtat;
+ if (pos != old_pos) {
+ register int iobase = addr_6845;
+ outb(iobase, 14);
+ outb(iobase+1, pos >> 8);
+ outb(iobase, 15);
+ outb(iobase+1, pos);
+ old_pos = pos;
+ }
+ if (cursor_shape != old_cursor_shape)
+ set_cursor_shape();
+}
+
+void
+async_update()
+{
+
+ if (kernel || polling) {
+ if (async)
+ untimeout(do_async_update, NULL);
+ do_async_update(1);
+ } else {
+ if (async)
+ return;
+ async = 1;
+ timeout(do_async_update, NULL, 1);
+ }
+}
+
+/*
+ * these are both bad jokes
+ */
+int
+pcprobe(parent, match, aux)
+ struct device *parent;
+ void *match, *aux;
+{
+ struct isa_attach_args *ia = aux;
+ u_int i;
+
+ /* Enable interrupts and keyboard, etc. */
+ if (!kbc_put8042cmd(CMDBYTE)) {
+ printf("pcprobe: command error\n");
+ return 0;
+ }
+
+#if 1
+ /* Flush any garbage. */
+ kbd_flush_input();
+ /* Reset the keyboard. */
+ if (!kbd_cmd(KBC_RESET, 1)) {
+ printf("pcprobe: reset error %d\n", 1);
+ goto lose;
+ }
+ for (i = 600000; i; i--)
+ if ((inb(KBSTATP) & KBS_DIB) != 0) {
+ KBD_DELAY;
+ break;
+ }
+ if (i == 0 || inb(KBDATAP) != KBR_RSTDONE) {
+ printf("pcprobe: reset error %d\n", 2);
+ goto lose;
+ }
+ /*
+ * Some keyboards seem to leave a second ack byte after the reset.
+ * This is kind of stupid, but we account for them anyway by just
+ * flushing the buffer.
+ */
+ kbd_flush_input();
+ /* Just to be sure. */
+ if (!kbd_cmd(KBC_ENABLE, 1)) {
+ printf("pcprobe: reset error %d\n", 3);
+ goto lose;
+ }
+
+ /*
+ * Some keyboard/8042 combinations do not seem to work if the keyboard
+ * is set to table 1; in fact, it would appear that some keyboards just
+ * ignore the command altogether. So by default, we use the AT scan
+ * codes and have the 8042 translate them. Unfortunately, this is
+ * known to not work on some PS/2 machines. We try desparately to deal
+ * with this by checking the (lack of a) translate bit in the 8042 and
+ * attempting to set the keyboard to XT mode. If this all fails, well,
+ * tough luck.
+ *
+ * XXX It would perhaps be a better choice to just use AT scan codes
+ * and not bother with this.
+ */
+ if (kbc_get8042cmd() & KC8_TRANS) {
+ /* The 8042 is translating for us; use AT codes. */
+ if (!kbd_cmd(KBC_SETTABLE, 1) || !kbd_cmd(2, 1)) {
+ printf("pcprobe: reset error %d\n", 4);
+ goto lose;
+ }
+ } else {
+ /* Stupid 8042; set keyboard to XT codes. */
+ if (!kbd_cmd(KBC_SETTABLE, 1) || !kbd_cmd(1, 1)) {
+ printf("pcprobe: reset error %d\n", 5);
+ goto lose;
+ }
+ }
+
+lose:
+ /*
+ * Technically, we should probably fail the probe. But we'll be nice
+ * and allow keyboard-less machines to boot with the console.
+ */
+#endif
+
+ ia->ia_iosize = 16;
+ ia->ia_msize = 0;
+ return 1;
+}
+
+void
+pcattach(parent, self, aux)
+ struct device *parent, *self;
+ void *aux;
+{
+ struct pc_softc *sc = (void *)self;
+ struct isa_attach_args *ia = aux;
+
+ printf(": %s\n", vs.color ? "color" : "mono");
+ do_async_update(1);
+
+ sc->sc_ih = isa_intr_establish(ia->ia_irq, ISA_IST_EDGE, ISA_IPL_TTY,
+ pcintr, sc);
+}
+
+int
+pcopen(dev, flag, mode, p)
+ dev_t dev;
+ int flag, mode;
+ struct proc *p;
+{
+ struct pc_softc *sc;
+ int unit = PCUNIT(dev);
+ struct tty *tp;
+
+ if (unit >= pccd.cd_ndevs)
+ return ENXIO;
+ sc = pccd.cd_devs[unit];
+ if (sc == 0)
+ return ENXIO;
+
+ if (!sc->sc_tty)
+ tp = sc->sc_tty = ttymalloc();
+ else
+ tp = sc->sc_tty;
+
+ tp->t_oproc = pcstart;
+ tp->t_param = pcparam;
+ tp->t_dev = dev;
+ 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));
+}
+
+int
+pcclose(dev, flag, mode, p)
+ dev_t dev;
+ int flag, mode;
+ struct proc *p;
+{
+ struct pc_softc *sc = pccd.cd_devs[PCUNIT(dev)];
+ struct tty *tp = sc->sc_tty;
+
+ (*linesw[tp->t_line].l_close)(tp, flag);
+ ttyclose(tp);
+#ifdef notyet /* XXX */
+ ttyfree(tp);
+#endif
+ return(0);
+}
+
+int
+pcread(dev, uio, flag)
+ dev_t dev;
+ struct uio *uio;
+ int flag;
+{
+ struct pc_softc *sc = pccd.cd_devs[PCUNIT(dev)];
+ struct tty *tp = sc->sc_tty;
+
+ return ((*linesw[tp->t_line].l_read)(tp, uio, flag));
+}
+
+int
+pcwrite(dev, uio, flag)
+ dev_t dev;
+ struct uio *uio;
+ int flag;
+{
+ struct pc_softc *sc = pccd.cd_devs[PCUNIT(dev)];
+ struct tty *tp = sc->sc_tty;
+
+ return ((*linesw[tp->t_line].l_write)(tp, uio, flag));
+}
+
+struct tty *
+pctty(dev)
+ dev_t dev;
+{
+ struct pc_softc *sc = pccd.cd_devs[PCUNIT(dev)];
+ struct tty *tp = sc->sc_tty;
+
+ return (tp);
+}
+
+/*
+ * Got a console receive interrupt -
+ * the console processor wants to give us a character.
+ * Catch the character, and see who it goes to.
+ */
+int
+pcintr(arg)
+ void *arg;
+{
+ struct pc_softc *sc = arg;
+ register struct tty *tp = sc->sc_tty;
+ u_char *cp;
+
+ if ((inb(KBSTATP) & KBS_DIB) == 0)
+ return 0;
+ if (polling)
+ return 1;
+ do {
+ cp = sget();
+ if (!tp || (tp->t_state & TS_ISOPEN) == 0)
+ return 1;
+ if (cp)
+ do
+ (*linesw[tp->t_line].l_rint)(*cp++, tp);
+ while (*cp);
+ } while (inb(KBSTATP) & KBS_DIB);
+ return 1;
+}
+
+int
+pcioctl(dev, cmd, data, flag, p)
+ dev_t dev;
+ u_long cmd;
+ caddr_t data;
+ int flag;
+ struct proc *p;
+{
+ struct pc_softc *sc = pccd.cd_devs[PCUNIT(dev)];
+ struct tty *tp = sc->sc_tty;
+ int error;
+
+ error = (*linesw[tp->t_line].l_ioctl)(tp, cmd, data, flag, p);
+ if (error >= 0)
+ return error;
+ error = ttioctl(tp, cmd, data, flag, p);
+ if (error >= 0)
+ return error;
+
+ switch (cmd) {
+ case CONSOLE_X_MODE_ON:
+ pc_xmode_on();
+ return 0;
+ case CONSOLE_X_MODE_OFF:
+ pc_xmode_off();
+ return 0;
+ case CONSOLE_X_BELL:
+ /*
+ * If set, data is a pointer to a length 2 array of
+ * integers. data[0] is the pitch in Hz and data[1]
+ * is the duration in msec.
+ */
+ if (data)
+ sysbeep(((int*)data)[0],
+ (((int*)data)[1] * hz) / 1000);
+ else
+ sysbeep(BEEP_FREQ, BEEP_TIME);
+ return 0;
+ case CONSOLE_SET_TYPEMATIC_RATE: {
+ u_char rate;
+
+ if (!data)
+ return EINVAL;
+ rate = *((u_char *)data);
+ /*
+ * Check that it isn't too big (which would cause it to be
+ * confused with a command).
+ */
+ if (rate & 0x80)
+ return EINVAL;
+ typematic_rate = rate;
+ async_update();
+ return 0;
+ }
+ default:
+ return ENOTTY;
+ }
+
+#ifdef DIAGNOSTIC
+ panic("pcioctl: impossible");
+#endif
+}
+
+void
+pcstart(tp)
+ struct tty *tp;
+{
+ struct clist *cl;
+ int s, len, n;
+ u_char buf[PCBURST];
+
+ s = spltty();
+ if (tp->t_state & (TS_TIMEOUT | TS_BUSY | TS_TTSTOP))
+ goto out;
+ tp->t_state |= TS_BUSY;
+ splx(s);
+ /*
+ * We need to do this outside spl since it could be fairly
+ * expensive and we don't want our serial ports to overflow.
+ */
+ cl = &tp->t_outq;
+ len = q_to_b(cl, buf, PCBURST);
+ sput(buf, len);
+ s = spltty();
+ tp->t_state &= ~TS_BUSY;
+ if (cl->c_cc) {
+ tp->t_state |= TS_TIMEOUT;
+ timeout(ttrstrt, tp, 1);
+ }
+ if (cl->c_cc <= tp->t_lowat) {
+ if (tp->t_state & TS_ASLEEP) {
+ tp->t_state &= ~TS_ASLEEP;
+ wakeup(cl);
+ }
+ selwakeup(&tp->t_wsel);
+ }
+out:
+ splx(s);
+}
+
+void
+pcstop(tp, flag)
+ struct tty *tp;
+ int flag;
+{
+
+}
+
+void
+pccnprobe(cp)
+ struct consdev *cp;
+{
+ int maj;
+
+ /* 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_pri = CN_INTERNAL;
+}
+
+/* ARGSUSED */
+void
+pccninit(cp)
+ struct consdev *cp;
+{
+
+ /*
+ * For now, don't screw with it.
+ */
+ /* crtat = 0; */
+}
+
+/* ARGSUSED */
+void
+pccnputc(dev, c)
+ dev_t dev;
+ char c;
+{
+ u_char oldkernel = kernel;
+
+ kernel = 1;
+ if (c == '\n')
+ sput("\r\n", 2);
+ else
+ sput(&c, 1);
+ kernel = oldkernel;
+}
+
+/* ARGSUSED */
+pccngetc(dev)
+ dev_t dev;
+{
+ register char *cp;
+
+ if (pc_xmode > 0)
+ return 0;
+
+ do {
+ /* wait for byte */
+ while ((inb(KBSTATP) & KBS_DIB) == 0);
+ /* see if it's worthwhile */
+ cp = sget();
+ } while (!cp);
+ if (*cp == '\r')
+ return '\n';
+ return *cp;
+}
+
+void
+pccnpollc(dev, on)
+ dev_t dev;
+ int on;
+{
+
+ polling = on;
+ if (!on) {
+ int unit;
+ struct pc_softc *sc;
+ int s;
+
+ /*
+ * If disabling polling on a device that's been configured,
+ * make sure there are no bytes left in the FIFO, holding up
+ * the interrupt line. Otherwise we won't get any further
+ * interrupts.
+ */
+ unit = PCUNIT(dev);
+ if (pccd.cd_ndevs > unit) {
+ sc = pccd.cd_devs[unit];
+ if (sc != 0) {
+ s = spltty();
+ pcintr(sc);
+ splx(s);
+ }
+ }
+ }
+}
+
+/*
+ * Set line parameters.
+ */
+int
+pcparam(tp, t)
+ struct tty *tp;
+ struct termios *t;
+{
+
+ tp->t_ispeed = t->c_ispeed;
+ tp->t_ospeed = t->c_ospeed;
+ tp->t_cflag = t->c_cflag;
+ return 0;
+}
+
+#define wrtchar(c, at) do {\
+ char *cp = (char *)crtat; *cp++ = (c); *cp = (at); crtat++; vs.col++; \
+} while (0)
+
+/* translate ANSI color codes to standard pc ones */
+static char fgansitopc[] = {
+ FG_BLACK, FG_RED, FG_GREEN, FG_BROWN, FG_BLUE,
+ FG_MAGENTA, FG_CYAN, FG_LIGHTGREY
+};
+
+static char bgansitopc[] = {
+ BG_BLACK, BG_RED, BG_GREEN, BG_BROWN, BG_BLUE,
+ BG_MAGENTA, BG_CYAN, BG_LIGHTGREY
+};
+
+/*
+ * `pc3' termcap emulation.
+ */
+void
+sput(cp, n)
+ u_char *cp;
+ int n;
+{
+ u_char c, scroll = 0;
+
+ if (pc_xmode > 0)
+ return;
+
+ if (crtat == 0) {
+ u_short volatile *cp;
+ u_short was;
+ unsigned cursorat;
+
+ cp = ISA_HOLE_VADDR(CGA_BUF);
+ was = *cp;
+ *cp = (u_short) 0xA55A;
+ if (*cp != 0xA55A) {
+ cp = ISA_HOLE_VADDR(MONO_BUF);
+ addr_6845 = MONO_BASE;
+ vs.color = 0;
+ } else {
+ *cp = was;
+ addr_6845 = CGA_BASE;
+ vs.color = 1;
+ }
+
+ /* Extract cursor location */
+ outb(addr_6845, 14);
+ cursorat = inb(addr_6845+1) << 8;
+ outb(addr_6845, 15);
+ cursorat |= inb(addr_6845+1);
+
+#ifdef FAT_CURSOR
+ cursor_shape = 0x0012;
+#endif
+
+ Crtat = (u_short *)cp;
+ crtat = (u_short *)(cp + cursorat);
+
+ vs.ncol = COL;
+ vs.nrow = ROW;
+ vs.nchr = COL * ROW;
+ vs.at = FG_LIGHTGREY | BG_BLACK;
+
+ if (vs.color == 0)
+ vs.so_at = FG_BLACK | BG_LIGHTGREY;
+ else
+ vs.so_at = FG_YELLOW | BG_BLACK;
+
+ fillw((vs.at << 8) | ' ', crtat, vs.nchr - cursorat);
+ }
+
+ while (n--) {
+ if (!(c = *cp++))
+ continue;
+
+ switch (c) {
+ case 0x1B:
+ if (vs.state >= VSS_ESCAPE) {
+ wrtchar(c, vs.so_at);
+ vs.state = 0;
+ goto maybe_scroll;
+ } else
+ vs.state = VSS_ESCAPE;
+ break;
+
+ case '\t': {
+ int inccol = 8 - (vs.col & 7);
+ crtat += inccol;
+ vs.col += inccol;
+ }
+ maybe_scroll:
+ if (vs.col >= COL) {
+ vs.col -= COL;
+ scroll = 1;
+ }
+ break;
+
+ case '\010':
+ if (crtat <= Crtat)
+ break;
+ --crtat;
+ if (--vs.col < 0)
+ vs.col += COL; /* non-destructive backspace */
+ break;
+
+ case '\r':
+ crtat -= vs.col;
+ vs.col = 0;
+ break;
+
+ case '\n':
+ crtat += vs.ncol;
+ scroll = 1;
+ break;
+
+ default:
+ bypass:
+ switch (vs.state) {
+ case 0:
+ if (c == '\a')
+ sysbeep(BEEP_FREQ, BEEP_TIME);
+ else {
+ /*
+ * If we're outputting multiple printed
+ * characters, just blast them to the
+ * screen until we reach the end of the
+ * buffer or a control character. This
+ * saves time by short-circuiting the
+ * switch.
+ * If we reach the end of the line, we
+ * break to do a scroll check.
+ */
+ for (;;) {
+ if (vs.so)
+ wrtchar(c, vs.so_at);
+ else
+ wrtchar(c, vs.at);
+ if (vs.col >= vs.ncol) {
+ vs.col = 0;
+ scroll = 1;
+ break;
+ }
+ if (!n || (c = *cp) < ' ')
+ break;
+ n--, cp++;
+ }
+ }
+ break;
+ case VSS_ESCAPE:
+ if (c == '[') { /* Start ESC [ sequence */
+ vs.cx = vs.cy = 0;
+ vs.state = VSS_EBRACE;
+ } else if (c == 'c') { /* Clear screen & home */
+ fillw((vs.at << 8) | ' ', Crtat,
+ vs.nchr);
+ crtat = Crtat;
+ vs.col = 0;
+ vs.state = 0;
+ } else { /* Invalid, clear state */
+ wrtchar(c, vs.so_at);
+ vs.state = 0;
+ goto maybe_scroll;
+ }
+ break;
+ default: /* VSS_EBRACE or VSS_EPARAM */
+ switch (c) {
+ int pos;
+ case 'm':
+ if (!vs.cx)
+ vs.so = 0;
+ else
+ vs.so = 1;
+ vs.state = 0;
+ break;
+ case 'A': { /* back cx rows */
+ int cx = vs.cx;
+ if (cx <= 0)
+ cx = 1;
+ else
+ cx %= vs.nrow;
+ pos = crtat - Crtat;
+ pos -= vs.ncol * cx;
+ if (pos < 0)
+ pos += vs.nchr;
+ crtat = Crtat + pos;
+ vs.state = 0;
+ break;
+ }
+ case 'B': { /* down cx rows */
+ int cx = vs.cx;
+ if (cx <= 0)
+ cx = 1;
+ else
+ cx %= vs.nrow;
+ pos = crtat - Crtat;
+ pos += vs.ncol * cx;
+ if (pos >= vs.nchr)
+ pos -= vs.nchr;
+ crtat = Crtat + pos;
+ vs.state = 0;
+ break;
+ }
+ case 'C': { /* right cursor */
+ int cx = vs.cx,
+ col = vs.col;
+ if (cx <= 0)
+ cx = 1;
+ else
+ cx %= vs.ncol;
+ pos = crtat - Crtat;
+ pos += cx;
+ col += cx;
+ if (col >= vs.ncol) {
+ pos -= vs.ncol;
+ col -= vs.ncol;
+ }
+ vs.col = col;
+ crtat = Crtat + pos;
+ vs.state = 0;
+ break;
+ }
+ case 'D': { /* left cursor */
+ int cx = vs.cx,
+ col = vs.col;
+ if (cx <= 0)
+ cx = 1;
+ else
+ cx %= vs.ncol;
+ pos = crtat - Crtat;
+ pos -= cx;
+ col -= cx;
+ if (col < 0) {
+ pos += vs.ncol;
+ col += vs.ncol;
+ }
+ vs.col = col;
+ crtat = Crtat + pos;
+ vs.state = 0;
+ break;
+ }
+ case 'J': /* Clear ... */
+ switch (vs.cx) {
+ case 0:
+ /* ... to end of display */
+ fillw((vs.at << 8) | ' ', crtat,
+ Crtat + vs.nchr - crtat);
+ break;
+ case 1:
+ /* ... to next location */
+ fillw((vs.at << 8) | ' ', Crtat,
+ crtat - Crtat + 1);
+ break;
+ case 2:
+ /* ... whole display */
+ fillw((vs.at << 8) | ' ', Crtat,
+ vs.nchr);
+ break;
+ }
+ vs.state = 0;
+ break;
+ case 'K': /* Clear line ... */
+ switch (vs.cx) {
+ case 0:
+ /* ... current to EOL */
+ fillw((vs.at << 8) | ' ', crtat,
+ vs.ncol - vs.col);
+ break;
+ case 1:
+ /* ... beginning to next */
+ fillw((vs.at << 8) | ' ',
+ crtat - vs.col,
+ vs.col + 1);
+ break;
+ case 2:
+ /* ... entire line */
+ fillw((vs.at << 8) | ' ',
+ crtat - vs.col, vs.ncol);
+ break;
+ }
+ vs.state = 0;
+ break;
+ case 'f': /* in system V consoles */
+ case 'H': { /* Cursor move */
+ int cx = vs.cx,
+ cy = vs.cy;
+ if (!cx || !cy) {
+ crtat = Crtat;
+ vs.col = 0;
+ } else {
+ if (cx > vs.nrow)
+ cx = vs.nrow;
+ if (cy > vs.ncol)
+ cy = vs.ncol;
+ crtat = Crtat +
+ (cx - 1) * vs.ncol + cy - 1;
+ vs.col = cy - 1;
+ }
+ vs.state = 0;
+ break;
+ }
+ case 'M': { /* delete cx rows */
+ u_short *crtAt = crtat - vs.col;
+ int cx = vs.cx,
+ row = (crtAt - Crtat) / vs.ncol,
+ nrow = vs.nrow - row;
+ if (cx <= 0)
+ cx = 1;
+ else if (cx > nrow)
+ cx = nrow;
+ if (cx < nrow)
+ bcopy(crtAt + vs.ncol * cx,
+ crtAt, vs.ncol * (nrow -
+ cx) * CHR);
+ fillw((vs.at << 8) | ' ',
+ crtAt + vs.ncol * (nrow - cx),
+ vs.ncol * cx);
+ vs.state = 0;
+ break;
+ }
+ case 'S': { /* scroll up cx lines */
+ int cx = vs.cx;
+ if (cx <= 0)
+ cx = 1;
+ else if (cx > vs.nrow)
+ cx = vs.nrow;
+ if (cx < vs.nrow)
+ bcopy(Crtat + vs.ncol * cx,
+ Crtat, vs.ncol * (vs.nrow -
+ cx) * CHR);
+ fillw((vs.at << 8) | ' ',
+ Crtat + vs.ncol * (vs.nrow - cx),
+ vs.ncol * cx);
+ /* crtat -= vs.ncol * cx; /* XXX */
+ vs.state = 0;
+ break;
+ }
+ case 'L': { /* insert cx rows */
+ u_short *crtAt = crtat - vs.col;
+ int cx = vs.cx,
+ row = (crtAt - Crtat) / vs.ncol,
+ nrow = vs.nrow - row;
+ if (cx <= 0)
+ cx = 1;
+ else if (cx > nrow)
+ cx = nrow;
+ if (cx < nrow)
+ bcopy(crtAt,
+ crtAt + vs.ncol * cx,
+ vs.ncol * (nrow - cx) *
+ CHR);
+ fillw((vs.at << 8) | ' ', crtAt,
+ vs.ncol * cx);
+ vs.state = 0;
+ break;
+ }
+ case 'T': { /* scroll down cx lines */
+ int cx = vs.cx;
+ if (cx <= 0)
+ cx = 1;
+ else if (cx > vs.nrow)
+ cx = vs.nrow;
+ if (cx < vs.nrow)
+ bcopy(Crtat,
+ Crtat + vs.ncol * cx,
+ vs.ncol * (vs.nrow - cx) *
+ CHR);
+ fillw((vs.at << 8) | ' ', Crtat,
+ vs.ncol * cx);
+ /* crtat += vs.ncol * cx; /* XXX */
+ vs.state = 0;
+ break;
+ }
+ case ';': /* Switch params in cursor def */
+ vs.state = VSS_EPARAM;
+ break;
+ case 'r':
+ vs.so_at = (vs.cx & FG_MASK) |
+ ((vs.cy << 4) & BG_MASK);
+ vs.state = 0;
+ break;
+ case 'x': /* set attributes */
+ switch (vs.cx) {
+ case 0:
+ vs.at = FG_LIGHTGREY | BG_BLACK;
+ break;
+ case 1:
+ /* ansi background */
+ if (!vs.color)
+ break;
+ vs.at &= FG_MASK;
+ vs.at |= bgansitopc[vs.cy & 7];
+ break;
+ case 2:
+ /* ansi foreground */
+ if (!vs.color)
+ break;
+ vs.at &= BG_MASK;
+ vs.at |= fgansitopc[vs.cy & 7];
+ break;
+ case 3:
+ /* pc text attribute */
+ if (vs.state >= VSS_EPARAM)
+ vs.at = vs.cy;
+ break;
+ }
+ vs.state = 0;
+ break;
+
+ default: /* Only numbers valid here */
+ if ((c >= '0') && (c <= '9')) {
+ if (vs.state >= VSS_EPARAM) {
+ vs.cy *= 10;
+ vs.cy += c - '0';
+ } else {
+ vs.cx *= 10;
+ vs.cx += c - '0';
+ }
+ } else
+ vs.state = 0;
+ break;
+ }
+ break;
+ }
+ }
+ if (scroll) {
+ scroll = 0;
+ /* scroll check */
+ if (crtat >= Crtat + vs.nchr) {
+ if (!kernel) {
+ int s = spltty();
+ if (lock_state & SCROLL)
+ tsleep((caddr_t)&lock_state,
+ PUSER, "pcputc", 0);
+ splx(s);
+ }
+ bcopy(Crtat + vs.ncol, Crtat,
+ (vs.nchr - vs.ncol) * CHR);
+ fillw((vs.at << 8) | ' ',
+ Crtat + vs.nchr - vs.ncol, vs.ncol);
+ crtat -= vs.ncol;
+ }
+ }
+ }
+ async_update();
+}
+
+#define CODE_SIZE 4 /* Use a max of 4 for now... */
+typedef struct {
+ u_short type;
+ char unshift[CODE_SIZE];
+ char shift[CODE_SIZE];
+ char ctl[CODE_SIZE];
+} Scan_def;
+
+static Scan_def scan_codes[] = {
+ NONE, "", "", "", /* 0 unused */
+ ASCII, "\033", "\033", "\033", /* 1 ESCape */
+ ASCII, "1", "!", "!", /* 2 1 */
+ ASCII, "2", "@", "\000", /* 3 2 */
+ ASCII, "3", "#", "#", /* 4 3 */
+ ASCII, "4", "$", "$", /* 5 4 */
+ ASCII, "5", "%", "%", /* 6 5 */
+ ASCII, "6", "^", "\036", /* 7 6 */
+ ASCII, "7", "&", "&", /* 8 7 */
+ ASCII, "8", "*", "\010", /* 9 8 */
+ ASCII, "9", "(", "(", /* 10 9 */
+ ASCII, "0", ")", ")", /* 11 0 */
+ ASCII, "-", "_", "\037", /* 12 - */
+ ASCII, "=", "+", "+", /* 13 = */
+ ASCII, "\177", "\177", "\010", /* 14 backspace */
+ ASCII, "\t", "\177\t", "\t", /* 15 tab */
+ ASCII, "q", "Q", "\021", /* 16 q */
+ ASCII, "w", "W", "\027", /* 17 w */
+ ASCII, "e", "E", "\005", /* 18 e */
+ ASCII, "r", "R", "\022", /* 19 r */
+ ASCII, "t", "T", "\024", /* 20 t */
+ ASCII, "y", "Y", "\031", /* 21 y */
+ ASCII, "u", "U", "\025", /* 22 u */
+ ASCII, "i", "I", "\011", /* 23 i */
+ ASCII, "o", "O", "\017", /* 24 o */
+ ASCII, "p", "P", "\020", /* 25 p */
+ ASCII, "[", "{", "\033", /* 26 [ */
+ ASCII, "]", "}", "\035", /* 27 ] */
+ ASCII, "\r", "\r", "\n", /* 28 return */
+ CTL, "", "", "", /* 29 control */
+ ASCII, "a", "A", "\001", /* 30 a */
+ ASCII, "s", "S", "\023", /* 31 s */
+ ASCII, "d", "D", "\004", /* 32 d */
+ ASCII, "f", "F", "\006", /* 33 f */
+ ASCII, "g", "G", "\007", /* 34 g */
+ ASCII, "h", "H", "\010", /* 35 h */
+ ASCII, "j", "J", "\n", /* 36 j */
+ ASCII, "k", "K", "\013", /* 37 k */
+ ASCII, "l", "L", "\014", /* 38 l */
+ ASCII, ";", ":", ";", /* 39 ; */
+ ASCII, "'", "\"", "'", /* 40 ' */
+ ASCII, "`", "~", "`", /* 41 ` */
+ SHIFT, "", "", "", /* 42 shift */
+ ASCII, "\\", "|", "\034", /* 43 \ */
+ ASCII, "z", "Z", "\032", /* 44 z */
+ ASCII, "x", "X", "\030", /* 45 x */
+ ASCII, "c", "C", "\003", /* 46 c */
+ ASCII, "v", "V", "\026", /* 47 v */
+ ASCII, "b", "B", "\002", /* 48 b */
+ ASCII, "n", "N", "\016", /* 49 n */
+ ASCII, "m", "M", "\r", /* 50 m */
+ ASCII, ",", "<", "<", /* 51 , */
+ ASCII, ".", ">", ">", /* 52 . */
+ ASCII, "/", "?", "\037", /* 53 / */
+ SHIFT, "", "", "", /* 54 shift */
+ KP, "*", "*", "*", /* 55 kp * */
+ ALT, "", "", "", /* 56 alt */
+ ASCII, " ", " ", "\000", /* 57 space */
+ CAPS, "", "", "", /* 58 caps */
+ FUNC, "\033[M", "\033[Y", "\033[k", /* 59 f1 */
+ FUNC, "\033[N", "\033[Z", "\033[l", /* 60 f2 */
+ FUNC, "\033[O", "\033[a", "\033[m", /* 61 f3 */
+ FUNC, "\033[P", "\033[b", "\033[n", /* 62 f4 */
+ FUNC, "\033[Q", "\033[c", "\033[o", /* 63 f5 */
+ FUNC, "\033[R", "\033[d", "\033[p", /* 64 f6 */
+ FUNC, "\033[S", "\033[e", "\033[q", /* 65 f7 */
+ FUNC, "\033[T", "\033[f", "\033[r", /* 66 f8 */
+ FUNC, "\033[U", "\033[g", "\033[s", /* 67 f9 */
+ FUNC, "\033[V", "\033[h", "\033[t", /* 68 f10 */
+ NUM, "", "", "", /* 69 num lock */
+ SCROLL, "", "", "", /* 70 scroll lock */
+ KP, "7", "\033[H", "7", /* 71 kp 7 */
+ KP, "8", "\033[A", "8", /* 72 kp 8 */
+ KP, "9", "\033[I", "9", /* 73 kp 9 */
+ KP, "-", "-", "-", /* 74 kp - */
+ KP, "4", "\033[D", "4", /* 75 kp 4 */
+ KP, "5", "\033[E", "5", /* 76 kp 5 */
+ KP, "6", "\033[C", "6", /* 77 kp 6 */
+ KP, "+", "+", "+", /* 78 kp + */
+ KP, "1", "\033[F", "1", /* 79 kp 1 */
+ KP, "2", "\033[B", "2", /* 80 kp 2 */
+ KP, "3", "\033[G", "3", /* 81 kp 3 */
+ KP, "0", "\033[L", "0", /* 82 kp 0 */
+ KP, ".", "\177", ".", /* 83 kp . */
+ NONE, "", "", "", /* 84 0 */
+ NONE, "100", "", "", /* 85 0 */
+ NONE, "101", "", "", /* 86 0 */
+ FUNC, "\033[W", "\033[i", "\033[u", /* 87 f11 */
+ FUNC, "\033[X", "\033[j", "\033[v", /* 88 f12 */
+ NONE, "102", "", "", /* 89 0 */
+ NONE, "103", "", "", /* 90 0 */
+ NONE, "", "", "", /* 91 0 */
+ NONE, "", "", "", /* 92 0 */
+ NONE, "", "", "", /* 93 0 */
+ NONE, "", "", "", /* 94 0 */
+ NONE, "", "", "", /* 95 0 */
+ NONE, "", "", "", /* 96 0 */
+ NONE, "", "", "", /* 97 0 */
+ NONE, "", "", "", /* 98 0 */
+ NONE, "", "", "", /* 99 0 */
+ NONE, "", "", "", /* 100 */
+ NONE, "", "", "", /* 101 */
+ NONE, "", "", "", /* 102 */
+ NONE, "", "", "", /* 103 */
+ NONE, "", "", "", /* 104 */
+ NONE, "", "", "", /* 105 */
+ NONE, "", "", "", /* 106 */
+ NONE, "", "", "", /* 107 */
+ NONE, "", "", "", /* 108 */
+ NONE, "", "", "", /* 109 */
+ NONE, "", "", "", /* 110 */
+ NONE, "", "", "", /* 111 */
+ NONE, "", "", "", /* 112 */
+ NONE, "", "", "", /* 113 */
+ NONE, "", "", "", /* 114 */
+ NONE, "", "", "", /* 115 */
+ NONE, "", "", "", /* 116 */
+ NONE, "", "", "", /* 117 */
+ NONE, "", "", "", /* 118 */
+ NONE, "", "", "", /* 119 */
+ NONE, "", "", "", /* 120 */
+ NONE, "", "", "", /* 121 */
+ NONE, "", "", "", /* 122 */
+ NONE, "", "", "", /* 123 */
+ NONE, "", "", "", /* 124 */
+ NONE, "", "", "", /* 125 */
+ NONE, "", "", "", /* 126 */
+ NONE, "", "", "", /* 127 */
+};
+
+/*
+ * Get characters from the keyboard. If none are present, return NULL.
+ */
+char *
+sget()
+{
+ u_char dt;
+ static u_char extended = 0, shift_state = 0;
+ static u_char capchar[2];
+
+top:
+ KBD_DELAY;
+ dt = inb(KBDATAP);
+
+ switch (dt) {
+ case KBR_ACK:
+ ack = 1;
+ goto loop;
+ case KBR_RESEND:
+ nak = 1;
+ goto loop;
+ }
+
+ if (pc_xmode > 0) {
+#if defined(DDB) && defined(XSERVER_DDB)
+ /* F12 enters the debugger while in X mode */
+ if (dt == 88)
+ Debugger();
+#endif
+ capchar[0] = dt;
+ capchar[1] = 0;
+ /*
+ * Check for locking keys.
+ *
+ * XXX Setting the LEDs this way is a bit bogus. What if the
+ * keyboard has been remapped in X?
+ */
+ switch (scan_codes[dt & 0x7f].type) {
+ case NUM:
+ if (dt & 0x80) {
+ shift_state &= ~NUM;
+ break;
+ }
+ if (shift_state & NUM)
+ break;
+ shift_state |= NUM;
+ lock_state ^= NUM;
+ async_update();
+ break;
+ case CAPS:
+ if (dt & 0x80) {
+ shift_state &= ~CAPS;
+ break;
+ }
+ if (shift_state & CAPS)
+ break;
+ shift_state |= CAPS;
+ lock_state ^= CAPS;
+ async_update();
+ break;
+ case SCROLL:
+ if (dt & 0x80) {
+ shift_state &= ~SCROLL;
+ break;
+ }
+ if (shift_state & SCROLL)
+ break;
+ shift_state |= SCROLL;
+ lock_state ^= SCROLL;
+ if ((lock_state & SCROLL) == 0)
+ wakeup((caddr_t)&lock_state);
+ async_update();
+ break;
+ }
+ return capchar;
+ }
+
+ switch (dt) {
+ case KBR_EXTENDED:
+ extended = 1;
+ goto loop;
+ }
+
+#ifdef DDB
+ /*
+ * Check for cntl-alt-esc.
+ */
+ if ((dt == 1) && (shift_state & (CTL | ALT)) == (CTL | ALT)) {
+ Debugger();
+ dt |= 0x80; /* discard esc (ddb discarded ctl-alt) */
+ }
+#endif
+
+ /*
+ * Check for make/break.
+ */
+ if (dt & 0x80) {
+ /*
+ * break
+ */
+ dt &= 0x7f;
+ switch (scan_codes[dt].type) {
+ case NUM:
+ shift_state &= ~NUM;
+ break;
+ case CAPS:
+ shift_state &= ~CAPS;
+ break;
+ case SCROLL:
+ shift_state &= ~SCROLL;
+ break;
+ case SHIFT:
+ shift_state &= ~SHIFT;
+ break;
+ case ALT:
+ shift_state &= ~ALT;
+ break;
+ case CTL:
+ shift_state &= ~CTL;
+ break;
+ }
+ } else {
+ /*
+ * make
+ */
+ switch (scan_codes[dt].type) {
+ /*
+ * locking keys
+ */
+ case NUM:
+ if (shift_state & NUM)
+ break;
+ shift_state |= NUM;
+ lock_state ^= NUM;
+ async_update();
+ break;
+ case CAPS:
+ if (shift_state & CAPS)
+ break;
+ shift_state |= CAPS;
+ lock_state ^= CAPS;
+ async_update();
+ break;
+ case SCROLL:
+ if (shift_state & SCROLL)
+ break;
+ shift_state |= SCROLL;
+ lock_state ^= SCROLL;
+ if ((lock_state & SCROLL) == 0)
+ wakeup((caddr_t)&lock_state);
+ async_update();
+ break;
+ /*
+ * non-locking keys
+ */
+ case SHIFT:
+ shift_state |= SHIFT;
+ break;
+ case ALT:
+ shift_state |= ALT;
+ break;
+ case CTL:
+ shift_state |= CTL;
+ break;
+ case ASCII:
+ /* control has highest priority */
+ if (shift_state & CTL)
+ capchar[0] = scan_codes[dt].ctl[0];
+ else if (shift_state & SHIFT)
+ capchar[0] = scan_codes[dt].shift[0];
+ else
+ capchar[0] = scan_codes[dt].unshift[0];
+ if ((lock_state & CAPS) && capchar[0] >= 'a' &&
+ capchar[0] <= 'z') {
+ capchar[0] -= ('a' - 'A');
+ }
+ capchar[0] |= (shift_state & ALT);
+ extended = 0;
+ return capchar;
+ case NONE:
+ break;
+ case FUNC: {
+ char *more_chars;
+ if (shift_state & SHIFT)
+ more_chars = scan_codes[dt].shift;
+ else if (shift_state & CTL)
+ more_chars = scan_codes[dt].ctl;
+ else
+ more_chars = scan_codes[dt].unshift;
+ extended = 0;
+ return more_chars;
+ }
+ case KP: {
+ char *more_chars;
+ if (shift_state & (SHIFT | CTL) ||
+ (lock_state & NUM) == 0 || extended)
+ more_chars = scan_codes[dt].shift;
+ else
+ more_chars = scan_codes[dt].unshift;
+ extended = 0;
+ return more_chars;
+ }
+ }
+ }
+
+ extended = 0;
+loop:
+ if ((inb(KBSTATP) & KBS_DIB) == 0)
+ return 0;
+ goto top;
+}
+
+int
+pcmmap(dev, offset, nprot)
+ dev_t dev;
+ int offset;
+ int nprot;
+{
+
+ if (offset > 0x20000)
+ return -1;
+ return i386_btop(0xa0000 + offset);
+}
+
+pc_xmode_on()
+{
+ struct trapframe *fp;
+
+ if (pc_xmode)
+ return;
+ pc_xmode = 1;
+
+#ifdef XFREE86_BUG_COMPAT
+ /* If still unchanged, get current shape. */
+ if (cursor_shape == 0xffff)
+ get_cursor_shape();
+#endif
+
+#ifdef COMPAT_10
+ /* This is done by i386_iopl(3) now. */
+ fp = curproc->p_md.md_regs;
+ fp->tf_eflags |= PSL_IOPL;
+#endif
+}
+
+pc_xmode_off()
+{
+ struct trapframe *fp;
+
+ if (pc_xmode == 0)
+ return;
+ pc_xmode = 0;
+
+#ifdef XFREE86_BUG_COMPAT
+ /* XXX It would be hard to justify why the X server doesn't do this. */
+ set_cursor_shape();
+#endif
+ async_update();
+
+ fp = curproc->p_md.md_regs;
+ fp->tf_eflags &= ~PSL_IOPL;
+}
diff --git a/sys/arch/i386/isa/pcvt/Doc/Acknowledgements b/sys/arch/i386/isa/pcvt/Doc/Acknowledgements
new file mode 100644
index 00000000000..237c8ba01c0
--- /dev/null
+++ b/sys/arch/i386/isa/pcvt/Doc/Acknowledgements
@@ -0,0 +1,121 @@
+Thank You, (in the order of appearance)
+
+
+ Lynne and Bill Jolitz
+
+ for your work on 386BSD and making all this possible !
+
+
+ Holger Veit (veit@du9ds3.uni-duisburg.de)
+
+ for the permission to use a modified version of his keyboard
+ driver and utilities for keyboard remapping / multinational
+ keyboard support.
+
+
+ Per Lindberg
+
+ for the extremely helpful vt100 terminal testprogram found
+ in the directory vttest.
+
+
+ John Birchfield
+
+ for the ncsa telnet package, which contains a vt100 emulation
+ and which was very helpful in studying some concepts.
+
+
+ Ralf Friedl (friedl@informatik.uni-kl.de)
+
+ for making his implementation of multi-sceens for the net-2
+ distribution available. i looked at this and took some ideas
+ and lines from his code.
+
+
+ Bruce Evans (bde@runx.oz.au)
+
+ for contributing some bugfixes and a complete termcap entry
+
+
+ Brian H. Dunford-Shore (brian@morpheus.wustl.edu)
+
+ for contributing most of the EGA/VGA screen switching code
+ and being a fast, reliable and responsive co-author. This
+ driver would not be what it is without Brian, Thank You !
+
+
+ Frank da Cruz (fdc@columbia.edu)
+
+ for my famous datacomm program and for giving the permission
+ to redistribute files from the msdos kermit distribution
+ located in the directory support/demo.
+
+
+ Joerg Wunsch (joerg_wunsch@uriah.sax.de)
+
+ for contributing precise bugreports and -fixes, the 8x10
+ EGA/VGA fonts and the color palette ioctls and for being
+ a very responsive contributor of various ideas.
+ Joerg wrote pcvt's interface to XFree86 1.2 and 1.3 and
+ the SYSV/syscons - like interface to XFree86 2.0.
+ There would be no support for X without Joerg's work!
+ Thank you very much Joerg, i enjoy it !!! :-)
+
+
+ Scott Turner (scotty@gagetalker.com)
+
+ for contributing code to change the winsize structure, many
+ discussions on the keyboard code and fine-tuning the driver
+
+
+ Gordon L. Burditt (gordon@sneaky.lonestar.org)
+
+ for the nicest and most complete bugreports i ever got
+
+
+ Theo Deraadt (deraadt@fsa.ca)
+
+ for pushing me forward. There would be no 3.00 release
+ if Theo didn't asked for features ... ;-)
+
+
+ Onno van der Linden (c/o frank@fwi.uva.nl)
+
+ for writing the 132 column support for the Cirrus
+ chipsets although he had no time to do it ... :-)
+
+
+ Wolfram Solfrank, Ingo Koenig
+
+ for putting some data onto tape (and handling and shipping
+ in the case of Wolfgang) to provide me with some latest
+ sources because i still have no ip-connectivity ....
+
+
+ Michael Havemester (tik@abqhh.hanse.de)
+
+ for giving me a chance to stay up to date with NetBSD-
+ current, for programming the initial version of the fast
+ scrolling code and for the keyboard fifo code!
+
+
+ Charles Hannum (mycroft@gnu.ai.mit.edu)
+
+ for getting bored by a slow-scrolling video driver and
+ for leaving me some bugs to fix ;-)
+
+
+ The NetBSD and FreeBSD teams
+
+ for giving me something to play, work and learn with !
+ There would be nothing to write a driver for without you !!!
+
+
+ J.T. Conklin
+
+ for forwarding the pcvt-related NetBSD PR's to me !
+
+
+ John Kohl
+
+ for producing patches for NetBSD-current !
diff --git a/sys/arch/i386/isa/pcvt/Doc/Bibliography b/sys/arch/i386/isa/pcvt/Doc/Bibliography
new file mode 100644
index 00000000000..2f60910b7fd
--- /dev/null
+++ b/sys/arch/i386/isa/pcvt/Doc/Bibliography
@@ -0,0 +1,193 @@
+
+VGA BOOKS
+---------
+
+ Richard Wilton, "Programmers Guide to PC & PS/2 Video Systems",
+ Microsoft Press 1987
+
+
+ Richard F. Ferraro, "Programmers Guide to the EGA and VGA Cards",
+ Second Edition, Addison-Wesley 1990
+
+
+ Richard F. Ferraro, "Programmers Guide to the EGA and VGA Cards",
+ Third Edition, Addison-Wesley 1994
+
+
+ Matthias Uphoff, "Die Programmierung der EGA/VGA Grafikkarte",
+ Addison Wesley 1992
+
+
+ Bradley Dyck Kliewer, "EGA/VGA A Programmers Reference Guide",
+ McGraw Hill, 2nd Edition 1990
+
+
+UNIX AND UNIX DEVICE DRIVERS
+----------------------------
+
+ Bell Telephone Laboratories, Inc. "UNIX Programmer's Manual, Seventh
+ Edition, Volume 2". Revised and Expanded Version.
+ Holt, Rinehart and Winston 1983
+
+
+ George Pajari, "Writing Unix Device Drivers"
+ Addison Wesley 1992
+
+
+ Janet I. Egan and Thomas J. Teixeira, "Writing a UNIX Device Driver"
+ John Wiley & Sons 1988
+
+
+ Janet I. Egan and Thomas J. Teixeira, "Writing a UNIX Device Driver"
+ Second Edition. John Wiley & Sons 1992
+
+
+ Leffler, McKusick, Karels, Quarterman, "The Design and Implementation
+ of the 4.3BSD UNIX Operating System"
+ Addison Wesley 1988, corrected Reprint 1989
+
+
+ Leffler, McKusick, "The Design and Implementation of the 4.3BSD UNIX
+ Operating System, Answer Book"
+ Addison Wesley 1991
+
+
+ Maurice J. Bach, "The Design of the UNIX Operating System"
+ Prentice-Hall 1986
+
+
+ Sun Microsystems Inc., "Writing Device Drivers"
+ Part No. 800-3851-10, Revision A of 27 March 1990
+
+
+ Hewlett-Packard Company, "HP-UX Driver Development Guide",
+ Part No. 98577-90013, First Edition 07/91
+
+
+ W. Richard Stevens, "Advanced Programming in the UNIX Environment",
+ Addison Wesley 1992
+
+
+ Phillip M. Adams, Clovis L. Tondo, "Writing Unix Device Drivers in C",
+ Prentice Hall 1993
+
+
+ Berny Goodheart, James Cox, "The Magic Garden Explained",
+ Prentice Hall 1994
+
+
+ Peter Kettle, Steve Statler, "Writing Device Drivers for SCO Unix"
+ Addison Wesley 1993
+
+
+ Tim Burke, Mark A. Parenti, Al Wojtas, "Writing Device Drivers,
+ Tutorial and Reference", Digital Press 1995
+
+
+TERMINAL MANUALS
+----------------
+
+ Digital Equipment, VT100 Users Manual, 2nd ed. 1979
+ Digital Equipment, VT132 Users Manual
+ Digital Equipment, VT220 Programmers Reference Manual, 2nd ed. 1984
+ Digital Equipment Corporation
+
+
+ Hewlett Packard, 700/92 Technical Reference Manual (ANSI Operation)
+ Hewlett Packard, 2392a Users Manual (ANSI Operation)
+ Hewlett-Packard Company
+
+
+ Walker Richer & Quinn, Inc., "Reflection 2 and Reflection 4 Technical
+ Reference Manual", Version 4.2
+ Walker, Richer & Quinn, Seattle, August 1992
+
+
+IBM PC HARDWARE/FIRMWARE
+------------------------
+
+ Frank van Gilluwe, "The Undocumented PC",
+ Addison Wesley, First Edition May 1994
+
+
+ IBM Corporation, "Technical Reference Personal Computer AT",
+ Part No. 6280070, Form No. S229-9611-00, First Edition 1985
+
+
+ Phoenix Technologies Ltd., "System BIOS for IBM PC/XT/AT Computers
+ and Compatibles", Addison Wesley, Fourth Printing June 1990
+
+
+ Phoenix Technologies Ltd., "System BIOS for IBM PCs, Compatibles,
+ and EISA Computers", Second Edition
+ Addison Wesley, First Printing May 1991
+
+
+ American Megatrends, Inc., "Hi-Flex ISA and EISA AMIBIOS Technical
+ Reference", American Megatrends, Inc. 1992 (9/25/92)
+
+
+ Thom Hogan, "The Programmers PC Sourcebook", 2nd Edition
+ Microsoft Press, 1991
+
+
+TERMCAP/TERMINFO
+----------------
+
+ John Strang, Linda Mui and Tim O'Reilly, "Termcap and Terminfo",
+ O'Reilly & Associates, Inc. , April 1991
+
+
+ Richard M. Stallman, "Termcap - The Termcap Library and Data Base",
+ Free Software Foundation, Second Edition November 1988
+
+
+
+DATABOOKS/DATASHEETS
+--------------------
+
+ Intel Corporation, "Microsystem Components Handbook Volume II",
+ Intel Corporation, 1984
+
+
+ Intel Corporation, "Peripheral Design Handbook",
+ Intel Corporation, 1980
+
+
+ Tseng Labs, Inc. "ET4000 Graphics Controller Data Book", 1990
+
+
+ Western Digital Corporation, "WD90C11, WD90C11A (PVGA1C) Enhanced
+ VGA Controller", Western Digital 9/18/91
+
+
+ Western Digital Corporation, "WD90C00 Enhanced VGA Controller",
+ Western Digital 1/14/91
+
+
+ Western Digital Corporation, "WD90C00 Interface Guide",
+ Western Digital 1/10/91
+
+
+ Western Digital Corporation, "VGA Register Based Programmers Manual",
+ Western Digital 1/30/91
+
+
+ Western Digital Corporation, "VGA BIOS Programmers Manual",
+ Western Digital 1/10/91
+
+
+ Cirrus Logic, "True Color VGA Family - CL-GD542X", Technical Ref.
+ Manual, Cirrus Logic, Inc. April 1993
+
+
+ S3 Inc, "86C801/86C805 GUI Accelerators"
+ S3 Incorporated, September 1992
+
+
+ S3 Inc, "86C928 GUI Accelerator"
+ S3 Incorporated, July 1993
+
+
+ Trident Microsystems Inc., "TVGA9000i Technical Reference Manual",
+ Trident Microsystems, Inc. (c) 1992, March 1993, Rev 1
diff --git a/sys/arch/i386/isa/pcvt/Doc/BugList b/sys/arch/i386/isa/pcvt/Doc/BugList
new file mode 100644
index 00000000000..27a574807cf
--- /dev/null
+++ b/sys/arch/i386/isa/pcvt/Doc/BugList
@@ -0,0 +1,57 @@
+
+List of known bugs Last Edit-Date: [Tue Sep 5 17:52:05 1995]
+================================================================================
+
+
+Description: Fixed/done by/date
+------------------------------------------- --------------------------------
+Util/keycap/man5/keycap.5 does STILL not
+build correctly when doing a make obj.
+Will there ever be a solution ... :-)
+------------------------------------------- --------------------------------
+NetBSD PR #404: Meta-Control-Space broken
+with PCVT_META_ESC and PCVT_NULLCHARS set
+Meta-Control-Space should (theoretically)
+send ESC NUL if PCVT_NULLCHARS and
+PCVT_META_ESC are defined; in reality, it
+just sends ESC. Because of the grody
+encoding hack used by sgets() to implement
+PCVT_NULLCHARS (if the first character is
+a null, send it), there isn't a trivial
+one-line fix.
+How-To-Repeat: in a kernel with
+PCVT_NULLCHARS and PCVT_META_ESC, type a
+M-C-SPC to emacs.
+------------------------------------------- --------------------------------
+when auto switching to vt0 is enabled by
+PCVT_SW0CNOUTP and the screen is switched
+from an X-vt to screen 0, the video mem
+is irrecoverably destroyed - no data loss
+------------------------------------------- --------------------------------
+Altgr+Shift+key is not separately They way the keyboard mapping
+mappable. is done is subject to a sub-
+ stantial rewrite in a future
+ release
+------------------------------------------- --------------------------------
+132 column mode not working with #9 GXE
+(S3-based) (sorry, i don't have one -hm)
+(see discussion of 132 column mode in the
+ NotesAndHints file!)
+------------------------------------------- --------------------------------
+WD90Cxx chip detection fails to detect
+chips other than C00,C10 and C11. C30
+chips are detected as C11s ....
+------------------------------------------- --------------------------------
+On one keyboard, if a "Lock" key is pressed
+the leds do not get updated and the key-
+board hangs.
+------------------------------------------- --------------------------------
+HP function key labels code needs to set
+the user defined fkey string somehow!
+------------------------------------------- --------------------------------
+Video 7 1024i not fully supported yet, has
+sometimes problems with some chars to displ
+------------------------------------------- --------------------------------
+The HP-Escape sequences need to be FULLY 28.12.93, -hm did a bit to supp-
+implemented port elm. Needs MORE work !
+------------------------------------------- --------------------------------
diff --git a/sys/arch/i386/isa/pcvt/Doc/ChangeLog b/sys/arch/i386/isa/pcvt/Doc/ChangeLog
new file mode 100644
index 00000000000..75f673162dd
--- /dev/null
+++ b/sys/arch/i386/isa/pcvt/Doc/ChangeLog
@@ -0,0 +1,1040 @@
+ChangeLog last edit-date: [Tue Oct 3 12:32:18 1995]
+================================================================================
+
+Release 3.32 October 1995
+--------------------------------------------------------------------------------
+
+- renamed Doc/NotesAndHints to Doc/FAQ
+
+- TS_ASLEEP not available in FreeBSD 2.1 (FreeBSD 2.1.0 SNAP 950928)
+
+- patch from John Kohl adding missing kbd_setmode() in switch_screen()
+
+- implemented KDGKBMODE ioctl
+
+- removed support for KBDGLEDS and KBDSLEDS private ioctls
+
+- changed/updated pcvt termcap entry in Doc/Termcap
+
+- patch from Thomas Gellekum: GL and GR did not get updated after
+ loading a new charset into G0..G3, fixed in pcvt_vtf.c
+
+- patch from Charles Hannum to further cleanup the saved keyboard state
+ per screen patch.
+
+- patch from Frank van der Linden to support a saved keyboard state per
+ screen instead of one global saved flag.
+
+- the support for NetBSD <= 0.9 and FreeBSD <= 1.1.5.1 has been dropped since
+ i don't run this OS versions anymore. Not all the code supporting
+ this versions has been removed but it will disappear without further
+ notice.
+
+- removing support for the old pccons-like handling of the Xserver, the
+ former option PCVT_USL_VT_COMPAT has been removed since it is
+ now the only supported way of running X with pcvt.
+
+- patch from Martin Husemann for 132 cols switch support for Cirrus GD6225
+
+- patch from Martin Husemann to support Cirrus GD6225 VGA chipsets (Notebooks)
+
+- patch from Thomas Gellekum to introduce VT220 C1 control support
+
+- patch from Thomas Gellekum, this fixes a problem in the scrollregion code,
+ only reproducable under VMS: in some cases svsp->abs_write was set
+ to 1 when the scrollregion was set which caused check_scroll() to
+ fail.
+
+- patch from Ulf Kieber (uk1@irz301.inf.tu-dresden.de) to pcvt_conf.h to
+ better support changing the kernel message foreground and background
+ color at compile time, on monochrome diplays kernel messages are
+ underlined by default, so one can't distinguish between 'p' and 'q'
+ on some displays.
+
+- hint from Patrick Hausen to put 'pcvt' in the kcon manual page header
+
+- patch from Joerg to loadfont to support variable scanline values
+
+- patch from Joerg to make the mouse emulator work again (pcvt_drv.c)
+
+
+Release 3.30 July 1995
+--------------------------------------------------------------------------------
+
+- new Makefile for pcvt fonteditor Util/fed
+
+- patch from Joerg, removing all trailing whitespace chars
+
+- added missing ECHO definition in Util/Makefile.inc.NetBSD-current
+ (reported by Matthieu Herrb)
+
+- patch from John Kohl and Douglas Crosher for NetBSD-current regarding a
+ changed name of an include file
+
+Changes 3.10 -> 3.20 June 1995
+--------------------------------------------------------------------------------
+
+- updating Etc/rc.local to support path variables for pcvt utilities
+
+- fixing some code for compile with -Wall (unused variables/ add brackets)
+
+- patch to make pcvt work on NetBSD-current and a patch to fix a FreeBSD
+ bug; both from John Kohl, also a minor change from him:
+
+ I changed the auto-detect code to set PCVT_NETBSD to 102 if on
+ -current; I figure people can use "options PCVT_NETBSD=101" in
+ their config file if they need to.
+
+- keyboard code bugfix from Jukka A. Ukkonen (ukkonen@csc.fi):
+
+ I noticed that the doreset() function in pcvt was too hasty
+ in expecting SELFOK answers from certain keyboards. At least
+ Alps Membrane seems to first respond with an ACK as expected
+ but then it takes a short moment for itself.
+ During that time the only response to any attempts to fetch
+ the status value is -1. If one didn't allow for a few negative
+ replies being received before the SELFOK, one would get the
+ SELFOK only when expecting the answer to KBD ID query and
+ right after that there would be a request to re-issue the
+ KBD ID query.
+
+ My patch may not be the best possible solution, but it hits
+ the point quite nicely. With this patch attached e.g. Alps
+ Membrane will be correctly recognized as an MF-II keyboard.
+
+- adding NetBSD-current patches from John Kohl
+
+- added ${DESTDIR} to some Makefiles (patch from Joerg)
+
+- added support for Cirrus Logic CL-GD5430 VGA chipset 132 columns mode
+
+- new Util/Makefile.inc for FreeBSD 2.0.5-RELEASE
+
+- merging in changes from FreeBSD 2.0.5-RELEASE
+
+- (internal) release beta 25 ---------------------------------------------------
+
+- added ECHO to Makefile.inc.*BSD
+
+- added some (!) ${DESTDIR}'s to utilities Makefiles in Util
+
+- patch from Michael Havemester for NetBSD current later than April 21 1995,
+ for integration into NetBSD later than this date one has to define
+ a version value greater than 101, i.e. "options PCVT_NETBSD=102"
+
+- patch from joerg:
+ - if pcvt is acting as the systems console avoid panics going to
+ the debugger while we are in process mode.
+ - before using svsp->vs_tty and svsp->vs_tty->t_pgrp check that
+ vs_tty and t_pgrp are really set, other wise one can get panics
+ while booting with -c in FreeBSD
+
+- added -f to all gunzip's in Util/demo
+
+- added destination directory to ispcvt Makefile
+
+- moved pcvt.4 and Makefile from Doc to Util/pcvtdoc
+
+- Util Makefile cleanup
+
+- Util Makefile patch from Bruce Evans
+
+- Util Makefile patch from Joerg
+
+- updated example rc.local in directory Etc to run on a serial console
+
+- release beta 24 --------------------------------------------------------------
+
+- bugfix from Thomas Eberhardt: the force 24 lines enable function key
+ label was not updated when changing force 24 lines mode with
+ 'scon -f on|off', this is now fixed.
+
+- bugfix from John Kohl fixing divide by zero problem in pcvt_ext.c when
+ ringing the bell and pitch is 0: this avoids an integer divide
+ trap in supervisor mode.
+
+- changed the default behaviour of keyboard controller delay from using
+ delay()/DELAY() to using dummy reads to port 0x84 because i got
+ keyboard hangs in X.
+
+- bugfix: in pcvt_ext.c, MDA state restore when leaving X was lost, should
+ function now again.
+
+- renamed PCVT_XSERVER to XSERVER in ispcvt.c
+
+- bugfix in pcvt_vtf.c: renamed PCVT_USL_COMPAT to PCVT_USL_VT_COMPAT
+
+- added '-d <device>' option to ispcvt and loadfont
+
+- removed PCVT_NEEDPG
+
+- almost completely removed support for 386BSD 0.1 with patchkit 0.2.4
+
+- applied a patch from Joerg providing missing FreeBSD 2.1 functionality and
+ a some minor bugfixes and checks.
+
+- provide a single place PCVT_KBD_DELAY in pcvt_hdr.h. made it configurable
+ via PCVT_PORTIO_DELAY to use either 6 dummy reads from port 0x84
+ or the delay/DELAY function of the operating system. Changed ispcvt
+ to report status of compile time switch.
+
+- release beta 23 --------------------------------------------------------------
+
+- removed some files for 386BSD as there is virtually noone outside
+ using it anymore
+
+- make pcvt_ioctl.h accept "KERNEL" or "_KERNEL" for NetBSD-current
+
+- configuration fix: patch from Rafal Boni for pcvt_vtf.c, he writes:
+ This patch lets one compile pcvt on a system that is lacking XSERVER
+ and UCONSOLE [or either?] in the config file. I found this while
+ trying to build a minimal floppy-based test kernel. The problem is
+ that roll_up and roll_down assume that PCVT_USL_COMPAT is
+ unconditionally set, and hence muck with parts of the video structure
+ that are only there if PCVT_USL_COMPAT is set.
+ (generalized the patch a bit so that fastscroll functionality is
+ not lost in case of PCVT_USL_COMPAT not being defined. -hm)
+
+- bugfix: pcvt_ext.c switch_screen() - when switching to a 25 line charset
+ pure VT emulation screen which has force 24 lines set, then we have
+ to clear the last line on screen (bugreport from Joerg).
+
+- added define PCVT_NONRESP_KEYB_TRY for how many times to try to detect
+ a non-connected keyboard. This was previously set to 100 and
+ Joerg reports a 5+ minutes delay for a 386 booting without keyboard.
+ Set to 25 now in the definition. Also made shure the messages in
+ the corresponding loop display only once. [doreset() in pcvt_kbd.c]
+
+- updated kbdio utility to include the 7 us delay and added a 'what' command
+ detect type of MCA motherboard keyboard controller according to
+ Frank van Gilluwe, "The Undocumented PC", Addison Wesley, pp 273
+
+- "Gateway 2000" problem: after some discussion on the NetBSD port-i386
+ mailing list about hanging keyboards, Martin Husemann sent in a
+ patch where each inb(CONTROLLER_DATA) is now preceeded by a
+ delay(6). This fixed his keyboard problem, the same was reported
+ from Roland McGrath for his Gateway 2000 keyboard/machine.
+
+- patch from John Kohl for usl_vt_ioctl() in file pcvt_ext.c, he writes:
+ This is probably a long standing bug. tsleep() returns ERESTART
+ if it's interrupted. ERESTART is -1, which means that the
+ VT_WAITACTIVE call returns from usl_vt_ioctl() with -1,
+ meaning "not one of my ioctl's".
+
+- patch from Matthieu Herrb for NetBSD-current (post 1.0) support
+
+- patch from Joerg for FreeBSD pre-2.1 support
+
+- added file ToDo in directory Doc
+
+- fix for Util/Makefile.inc.NetBSD-c from Onno
+
+- removing unnecessary Trident support code from pcvt_out.c
+
+- fix from Onno for IST_EDGE in NetBSD-current
+
+- patch from Thomas Eberhardt to fix the bell frequency and duration setting
+ for NetBSD
+
+- some fixes from Onno van der Linden for NetBSD
+
+- added patch for NetBSD-current from Rafal Boni and Lon Willett
+
+- added another mega patch from Lon Willett fixing several bugs:
+
+ 1 -- Misc porting changes to deal with NetBSD-current, including
+ a new Util/Makefile.inc.NetBSD-current.
+
+ 2 -- The Control_R scancodes were being mapped to the Control_L
+ pcvt keynum.
+
+ 3 -- FASTSCROLL/graphics-mode problem: there was a problem where
+ switching from a graphics screen to a text screen would corrupt
+ the text screen's content if it had been scrolling using the
+ FASTSCROLL code. (The problem is the bcopy() from kernel to
+ video memory was using the vs[i].Memory pointer as the source,
+ instead of the vs[i].Crtat pointer). This is fixed in the beta
+ 21 release by just disabling the fast scroll code for screens
+ which aren't active.
+
+ The patch I'm sending you re-enables the fast scroll code on
+ inactive (i.e. in kernel memory) screens, saving a few cpu
+ cycles.
+
+ 4 -- This is a big one: running multiple X servers was not
+ really working. The USL handshaking code was a mess (not very
+ well designed to begin with, but there's not much that can be
+ done about that). I did manage to get it fairly functional, but
+ there's a lot of changes.
+
+- changing example rc.local to take care of good old EGA's
+
+- fixing support for EGA boards in vt_coldinit()
+
+- removing vt100 font files from Util/fonts, updated Manifest
+
+- fixing an obviously longstanding bug in roll_up() / roll_down() which was
+ triggered by Joergs "Crtat" cleanup mega patch.
+
+- removing PCVT_FAKE_SYSCONS10
+
+- removing duplicate names in termcap entries
+
+- fixing vt_coldinit: setting variable "color" for mda/hercules and cga
+ initializing cursor position
+
+- fixing roll_up() and roll_down() for mda/hercules: mda's have ALWAYS
+ just one page of memory, original hercules boards too so they
+ can NEVER use the fastscroll option. SOME hercules are somehow
+ enhanced in that they support 2 pages. pcvt now just supports
+ one page hercules/mda!
+
+- made cleanups to 8x14 high and 8x8 high fonts: adjust the 5 scanline
+ characters to adjust with the corner characters from the low fonts
+
+- applying patch from Joerg which fixes some bugs:
+
+ writing to a tty containing an X server resulted in some stange
+ behaviour depending on the opsys and opsys version used
+
+ the init code preserving the screen contents and cursor shape
+ can only be done on boards allowing the reading of
+ several crtc registers
+
+- removed bcopyb declaration from pcvt_hdr.h for FreeBSD 2.1
+
+- another patch from Lon Willett (willett@math.utah.edu), he writes:
+
+ 1 -- Very minor: One of my previous changes didn't get merged
+ into "pcvt_out.c"; the caclulation of ws_row doesn't account for
+ "force24" at one spot. It's easier to just set it from
+ screen_rows anyway, unless there's something that I didn't
+ understand happening here.
+
+ 2 -- Debugging stuff: I don't know if you care to add it, but I
+ found it useful, so I left it in. I rearranged the
+ PCVT_SHOWKEYS code a little, and added a few lines to show
+ keyboard commands and responses, with special delimiters.
+ [file: pcvt_kbd.c]
+
+ 3 -- "kcon" utility enhancement: I added a "-R" switch to kcon
+ to do a KBDRESET ioctl. [file: Util/kcon/kcon.c]
+
+ 4 -- KBDRESET-ioctl bug: the code was trying to read kbd
+ responses without an spltty(), so naturally it would fail, since
+ pcrint() was grabbing the ACKs. [file: pcvt_kbd.c]
+
+ 5 -- update_led() makes kbd hang: the problem here is that
+ update_led() makes the keyboard generate two KEYB_R_ACK
+ responses, and one of the interrupts sometimes gets lost when
+ there is a lot of other I/O happening. See the comment in the
+ code. My fix seems to work for me, but you may want to handle
+ it some other way. It would probably be quite reasonable to
+ check for lost interrupts periodically anyway, whether
+ update_led() has been called or not. [file: pcvt_kbd.c]
+
+ (NOTE: item 5 has been disabled because it causes older
+ FreeBSD's to panic because of the timer queue not being
+ initialized at the time called. -hm)
+
+- partly rewrote doreset() in pcvt_kbd.c to enable boot procedure to proceed
+ if no (PC) keyboard is found. The current behaviour and implementation
+ is subject to change.
+
+- patch from Thomas Gellekum to Util/keycap/keycap.src
+
+- minor modification to main.c in Util/set2061
+
+- patch from Onno and John Kohl to make pcvt beta 16 work on NetBSD current:
+ 1. pcvt_conf.h
+ _real_ 1.0 ===> NetBSD1_0 == 1
+ current 1.0 (1.0A) ===> NetBSD1_0 == 2
+ 2. pcvt_hdr.h
+ Put pcvt_conf.h before _all_ the #ifdef PCVT_*. This way
+ the #ifdef NetBSDx_y stuff can do its work.
+
+- size of PCVT_BURST was still reported as 1 for FreeBSD 2.0, fixed
+
+- made some adjustments for FreeBSD 2.0 in Util/vgaio
+
+- Another patch from Joerg for FreeBSD 2.0
+
+- included vgaio, kbdio and set2061 into the outer Makefile, this programs
+ are build and cleaned but don't install anything.
+ All program's in the Util dir should now cleanly make <anything> ...
+
+- enable 132 column support for Trident TVGA8900CL, some NetBSDisms
+
+- addend patch from Joerg for pcvt-320b7 to fix FreeBSD 2.0's ttymalloc's
+ encapsulation into #if's. Also new keycap.src entry.
+
+- fixed keyboard status/LED not updated on soft reset emulator
+
+- on 23rd of December i had some spare time, so i added some demos to the
+ Util/demo directory as well a a time-killer program (playvt) to view
+ some of the VT animations and a christmas animation i got from Joerg.
+
+- added a new utility set2061 to program the clock generator on my S3 based
+ ELSA Winner VGA board. This eventually lets me use 132 columns on this
+ board, because i'm now able to program the clock to generate 40MHz
+ on clock output #2.
+
+- debugged winsize patch on FreeBSD 1.1, line discipline open init's the
+ queues, winsize initialization must happen after line disc. open!
+
+- got a bunch of NetBSD PR's from J.T. Conklin:
+
+ PR #214: PCVT treats ctrl-shift exactly like shift for most characters.
+ (fixed by Lon Willet's Mega Patch described below -hm)
+
+ PR #399: If you define PCVT_META_ESC when builting PCVT, Meta-Return
+ sends 0x8d instead of ESC RET.
+ (fixed by applying the patch from Bill Sommerfeld. -hm)
+
+ PR #400: pcvt sometimes gets confused about window size
+ (fixed by applying the patch from Bill Sommerfeld. -hm)
+
+ PR #404: Meta-Control-Space broken with PCVT_META_ESC and PCVT_NULLCHARS
+ (put into "BugList" file, no solution yet .. -hm)
+
+ PR #488: pcvt can loose keyboard control if you start an xserver from
+ an xterm
+ (already fixed by a patch from John Kohl, see below -hm)
+
+ PR #580: NetBSD i386/pcvt bugs/enhancements; fixes included
+ (already integrated the patch from Lon Willet, see below -hm)
+
+- on coldinit, if FAT_CURSOR is defined, the old large blockcursor is used
+
+- enhanced the vgaio output in an attempt to make 132 column mode work
+ for my S3 board ....
+
+- applied patch from Thomas Gellekum: install instructions for FreeBSD 2.0,
+ patch to fontedit to compile under FreeBSD 2.0, an addition to
+ keycap.src and a fix for kbdio
+
+- changed installation instructions to reflect recent changes, removed
+ instructions for FreeBSD 1.0 and added instructions for FreeBSD 2.0
+
+- upgraded all utilities version strings to 3.20
+
+- new example of rc.local
+
+- changing timeout()/untimeout() function parameter type to TIMEOUT_FUNC_T
+ definition in pcvt_hdr.h
+
+- changed install instructions to reference Etc dir instead of Doc dir for
+ several files which were moved from Doc to Etc.
+
+- new parameter -d for the cursor utility, updated cursor manpage
+
+- applying a patch from Lon Willett, willett@math.utah.edu which fixes
+ several bugs and provides some enhancements. Lon writes:
+
+ 1 -- The displayed cursor is not updated during kernel I/O,
+ because async_update() doesn't get called. This is merely ugly
+ while the system startup messages are being displayed, but it is
+ positively annoying when using the kernel debugger.
+
+ 2 -- CONTROL-SHIFT-<KEY> is taken to be the same as SHIFT-<KEY>.
+ It should be interpretted as CONTROL-<KEY>, or even have its own
+ binding. One of the lines below fixes it in the former way.
+ This is especially bad (i.e. clearly buggy) when I type
+ CONTROL-SHIFT-<6/^> to get a "Control-^", and instead get a "^".
+
+ 3 -- The "special" region at the bottom of the screen, i.e. the
+ function-key-labels/status-line in HPVT mode, and the blank line
+ in FORCE24LINES mode, do not get properly cleared/updated.
+
+ 4 -- When switching screen sizes/modes, the FORCE24LINES setting
+ is not always handled.
+
+ 5 -- The PCVT_VT220KEYB functions are missing some features.
+ The control key settings are bug fixes; they apply only if
+ system function key labels are on, and match the labels. The
+ shift key definitions are enhancements.
+
+ The new keys (previously undefined) are:
+
+ Control-F1 -- toggle 80/132 columns
+ Control-F2 -- soft reset emulator
+ Control-F3 -- toggle force 24 lines mode
+ Control-F4 -- toggle keyboard debugging
+
+ Shift-F1 -- select screen 4
+ Shift-F2 -- select screen 5
+ Shift-F3 -- select screen 6
+ Shift-F4 -- select screen 7
+ Shift-F5 -- select (current screen - 1)
+
+ 6 -- [Enhancement] The initial startup screen is cleared, and
+ the screen gets cleared when changing modes/sizes. I don't like
+ this. I want a chance to see bootstrap loader messages, and I
+ also want the command "scon -d/dev/ttyv0 -H -s28" in my
+ rc.local, but then I lose various messages from daemons, etc
+ (which aren't always logged to syslog). So I have fixed the
+ code so that it tries to preserve the contents of the screen
+ when starting up, and when changing modes/sizes.
+
+ 7 -- [Enhancement?] I added code to preserve the initial cursor
+ shape at startup. This isn't really necessary, since the
+ "cursor" command can be used to set it to your preference; but
+ it seems like this is the preferable policy to use for the
+ default.
+
+- applying patches from Onno van der Linden and Martin Husemann: adding
+ support for post 1.0 NetBSD-current and adding PCVT_NO_LED_UPDATE
+
+- patch from Joerg Wunsch: support for FreeBSD 2.0 and better support
+ for serial console coexistence
+
+- bugreport from Michael Havemester regarding PCVT_NOFASTSCROLL: it was
+ not enabled in pcvt_vtf.c, fixed.
+
+- renamed pcvt_disable_intr and pcvt_enable_intr to PCVT_DISABLE_INTR and
+ PCVT_ENABLE_INTR (Joerg)
+
+- attempt to automatically compile time configure in pcvt_conf.h, how
+ does FreeBSD do this ? should work for NetBSD (from Onno v.d. Linden)
+
+- split off pcvt_kbd.h from pcvt_kbd.c, file > 100k
+
+- split off pcvt_config.h from pcvt_hdr.h. All compile time configurations
+ should be put into pcvt_config.h now.
+
+- moved version definitions to begin of file in pcvt_ioctl.h and pcvt_hdr.h
+
+- fixing NetBSD #ifdef in pcvt_drv.c
+
+- fixed bug in scon. when doing "scon -c <num>" the destination screen was
+ cleared, this is fixed now by properly setting "force_24lines"
+
+- added kbdio utility from Joerg into Util directory
+
+- changed font dir from /usr/share/misc/vgafonts to /usr/share/misc/pcvtfonts
+
+- Fix for Gateway 2000 keyboard problems from Brian Moore
+
+- Starting to implement more keymoard mapping layers in pcvt_kbd.c. This
+ section is a building site, enclosed in NOT_YET_DEF ifdef's
+
+- VT_SETMODE ioctl patch from John Kohl <jtk@kolvir.blrc.ma.us>, see text
+ from John in the source file pcvt_ext.c
+
+- patch from Joerg for kbd_emulate_pc(), intro of timeout
+
+- fixed bug in soft/hard reset and real system fkey labels
+
+- added patch from Joerg for FreeBSD 1.1.5.1R
+
+- fixed both SR and SF entries in termcap database file
+
+- removed SR entry in termcap database file (bugreport from John Perry)
+
+- bugfix in cirrus 132 column switching got from Onno/Charles
+
+- french keycap database entry from Matthieu Herrb
+
+- cleanup patch from Joerg for Util/demo/Makefile und Util/fonts/Makefile
+
+
+Changes 3.00 -> 3.10 June 1994
+--------------------------------------------------------------------------------
+
+- patch from Joerg correcting my assumed timeout/untimeout FreeBSD casts
+
+- adjusted some #if's while validating NetBSD 0.9 and NetBSD-current
+
+- rolled in Joerg's changes for a pre-1.1.5 (?) FreeBSD-current
+
+- Util/fonts: install only the necessary fontfiles, vt100 not used anymore
+
+- updated and commented Etc/rc.local and updated to more recent /etc/ttys files
+
+- updated all installation instructions and changed their names
+
+- documenting more PCVT_ options in pcvt_hdr.h
+
+- adding CONF_ options to driver config ioctl and upgrading ispcvt
+
+- commenting the source, housekeeping, step up to 3.10 beta 2
+
+- casting timeout()/untimeout() for FreeBSD 1.1R :-(
+
+- unprotecting vgapage() routine with #if !PCVT_KBD_FIFO
+
+- adding Michael Havemester's keyboard fifo diffs to source tree
+
+- pcvt_drv.c: made declaration of Crtat global for this file for NetBSD
+
+- changing Util/fonts/Makefile and Util/demo/Makefile to run in all
+ supported environments
+
+- moving inline from pcvt_vtf.h into pcvt_hdr.h, i still feel that this is
+ not the best solution, but i got annoyed by the 10 line pcvt_vtf.h
+
+- bugfix, in hpmode, clear last 4 lines when 28 column mode and force
+ 24 lines are true
+
+- applying patch from Thomas Gellekum <thomas@ghpc8.ihf.rwth-aachen.de>:
+ - discard escape sequences ESC space F and ESC space G
+ - discard escape sequences DECELR = enable locator report
+ and DECSLE = select type of locator event
+ - disable scrolling when writing outside the scrolling region
+ at an absolute position.
+
+ [ pcvt now seems to be "VAX resistant" :-) ]
+
+- optional switch to screen 0 can be done on kernel/console output
+
+- fixed kernel output cursor positioning
+
+- removed PCVT_FORCE8BIT
+
+- pcvt_ext.c, changed screen switching bcopyb's to bcopy's
+
+- new patch from Onno to support all BIOS versions of the Cirrus chipset.
+
+- pcvt_x_hook() has to care about fkey labels now
+
+- updated Doc/NotesAndHints and Doc/BugList
+
+- applied patch from Onno van der Linden for updated Cirrus chipset support
+
+- updated Doc/Bibliography
+
+- removed paranoid delay()/DELAY() from vga_test()
+
+- added prototype ttrstrt() into pcvt_drv.c for NetBSD 0.9
+
+- made INSTALLATION.NetBSD and INSTALLATION.NetBSD.bundled from mycrofts base
+
+- Charles Hannum took Michael Havemesters speedup modifications, made some
+ further enhancements and after adding support for pcvt, put it into
+ the NetBSD-current tree. THANK YOU, Charles !
+ The NetBSD version of May 20th '94 was taken as the base for 3.10.
+
+
+Changes 2.20 -> 3.00 March 1994
+--------------------------------------------------------------------------------
+
+- Release 3.00
+
+- last minute patch from Joerg (pcvt_hdr.h, BugList, NotesAndHints)
+
+- included speedup patch from Michael Havemester as Etc/LAST-MINUTE
+
+- updated Doc/pcvt.4
+
+- removed bug in Util/ispcvt/Makefile which caused ispcvt to be installed
+ into /usr/sbin and /usr/local/bin
+
+- split ioctl VGAPCVTID into two: intro of ioctl VGAPCVTINFO for compile
+ time options only.
+ VGAPCVTID is now frozen for identification purposes (XFree86 3.0)
+ updated Util/ispcvt for the above mentioned changes
+
+- issued patch to upgrade beta14 to beta16
+
+- bugfix: when scrolling up (bcopy) is interrupted by a keystroke requesting
+ a change of the current screen, the "new" screen is scrolled up. Fixed
+ in pcvt_kbd.c and pcvt_out.c (check_scroll)
+
+- fixed bug "Jumping through vt's with ALT-F12 does jump over vt0"
+
+- PCVT_PCBURST intro, update of ioctl and Util/ispcvt
+
+- NetBSD speedup patch from Michael Havemester (factor 6-10)
+
+- issued patch to upgrade beta14 to beta15 (never officially announced)
+
+- added patch for ttioctl parameters NetBSD-current 12 Feb 94 from Michael
+ Havemester in pcvt_drv.c
+
+- INSTALLATION.xxx(x)BSD upgraded to reflect changes in Util and NetBSD-current
+
+- struct pcvtid changed to hold the value of PCVT_xxx(x)BSD, ispcvt upgraded
+
+- applied patch from Szabolcs Szigeti for 132 column operation for Trident
+ TVGA 8900B and TVGA8900C based boards
+
+- PCVT_NETBSD can/must now be 1 or 09 for Release 0.9 and > 09 for current
+
+- applied patches from John Brezak and Szabolcs Szigeti for recent
+ NetBSD-current changes (syscframe -> trapframe)
+
+- in Util, removed Makefile.inc. Make Makefile.inc.FreeBSD and
+ Makefile.inc.NetBSD and added a check to the toplevel and every
+ other Makefile in this part of the tree. sigh ...
+
+- patch from Joerg for pcvt.4 Makefile and Debugger in FreeBSD
+
+- issued pcvt-beta14, code freeze for 3.00 release, just bugfixes now
+
+- INSTALLATION.FreeBSD and a small cleanup patch from Joerg
+
+- large patch from Joerg to get pcvt FreeBSD-current compliant
+
+- permission/owner cleanup, files:664, dirs:775, user:root, group:wheel
+
+- got rid of the verbose error message when installing in Util/fonts
+
+- new make-method in Util/kcon to workaround make portability problems
+
+- NetBSD-current detection workaroundaroundaround for NEW_AVERRUNNABLE in
+ pcvt_header.h
+
+- MONO_BUF and COLOR_BUF now ifndef'ed
+
+- fixed typo in pcvt_kbd.h in cfkey11() and cfkey12()
+
+- machine/pio.h must be included in pcvt_hdr.h for recent NetBSD-current
+
+- protected every tsleep call with an "if(curproc)" otherwise there is
+ chance to panic the system (Joerg has an idea why ...)
+
+- more fixes from Joerg: keyboard scansets fixed, X server is now aware
+ of redefined keys (ioctl implemented)
+
+- patch from Heiko Rupp, configuration with XSERVER not defined didn't compile
+
+- new version of vgaio from Joerg installed
+
+- large keyboard cleanup patch from Joerg merged in
+
+- bugfixes from Joerg: fix crash on not-open vt, remove pcxint, add option
+ PCVT_INHIBIT_NUMLOCK (for notebook owners :-), support for EGA/VGA
+ fonts with up to 32 scanlines.
+
+- included vgaio, a program to read/write vga register values from Joerg.
+
+- included mcon, the keyboard mouse emulator control program from Joerg.
+
+- applied averrunnable patch to satisfy the most recent NetBSD-current.
+
+- fixing cursor not updated bug if usl/vt server is running on vt0
+
+- polished some chars in Util/fonts/vt220l.810, fixed all permissions in
+ the uuencoded fontfiles.
+
+- debugged the EGA/VGA curses based font editor 'fed' in Util/fed. It seems
+ it's working ok now now.
+
+- updated copyright header files
+
+- synchronize asynchronous cursor position update with having a valid
+ (new) cursor (row) position from sputc(). (Otherwise a cursor
+ would appear temporarily in the first position of the first
+ function key label in the HP mode)
+
+- updated screeninfo ioctl and scon to report the monitor type
+
+- added file Doc/Notes for random notes and hints for pcvt-users.
+
+- enhanced the pcvtid-ioctl and the ispcvt(8) utility to print out the
+ values of all "PCVT_XXXXXX" compile time options.
+
+- included work from Joerg to convert all ifdef's to if's, to be able
+ to compile various configurations of pcvt without changing
+ options in the header file.
+
+- included (currently untested !) patch for a keyboard mouse emulator
+ from Joerg. (he got problems after he bought a notebook with
+ just one serial port, which he wanted to use for slip ...)
+
+- screensaver reset is now also done asynchronously to get more speed. the
+ function average() was renamed to async_update().
+
+- cursor position update and cursor position display in HP mode is now done
+ asynchronously in function average() in pcvt_sup.c. the function
+ update_cursor does no longer exist. this gave about 10..30% increase
+ in speed depending on the data cat'ed (termcap, kernel, 1Mb nulls)
+
+- HP function key emulation processing debugged, this has to be rewritten
+ to use a stack and a new parser. elm -K now works a bit more, the
+ display is not garbled anymore, but fkey strings do not work.
+
+- pcvt_vtf.c split off from pcvt_out.c, file got > 100k. Checked all
+ forward declarations in header and source files
+
+- 132 column support for Cirrus Logic CL-GD542X chipsets written by
+ Onno van der Linden, c/o vdlinden@fwi.uva.nl
+
+- keyboard scancode display (#define PCVT_SHOWKEYS)
+
+- printscreen keycode fix form Onno van der Linden
+
+- Util/Makefile.inc added .depend dependency for make depend
+
+- pcvt_ioctl.h is now installed into /usr/include/machine.
+
+- keyboard scancode 1 is now used by default, perhaps it cures some problems
+
+- support for keyboard scancodes sets 1 and 2 (compile time selectable via
+ PCVT_SCANSET), patch from Onno van der Linden, c/o vdlinden@fwi.uva.nl
+
+- Util/fontedit.c updated to "#if defined (__386BSD__) || defined (__NetBSD__)"
+ (suggested by Mark Weaver, Mark_Weaver@brown.edu)
+
+- 132 column support for S3 86c928 chipsets
+
+- split off pcvt_ext.c from pcvt_sup.c, it was more than 100k ....
+
+- intro of Doc/Manifest and Doc/TestedHardware, removed README.X-PATCH because
+ it was now really outdated
+
+- superprobe compatibility patches from Joerg
+
+- intro of file Doc/BugList
+
+- another powerpatch from Joerg:
+ - some vgaioctl's are now available if in X mode (i.e. to scon to
+ another screen from within an xterm)
+ - removed bug in keyboardhandling, numlock'ed numkeys did send an
+ additional null (0x00) char, this has been fixed now.
+ - SysRq key made functional
+
+- made force 24 lines (see below) the default configuration to have a well
+ behaving vt220 emulator at startup.
+
+- every vt now has a separate caps-lock, num-lock and scroll-lock flag and
+ a separate handling of these lock-keys.
+
+- made sleeping in case of scroll lock working from an earlier patch from Joerg.
+
+- large patch from Joerg:
+ - Doc/pcvt.4 updated to reflect recent changes
+ - struct winsize set ok when switching between HP/VT
+ - struct winsize pixels reflect real values now
+ - ioctl for switching between 80 and 132 cols
+ - 132 columns for generic VGA's
+ - updated scon to provide access to ioctl 80/132 col switching
+
+- removed pcconcoftc and kbdsoftc structures from header files, removed
+ pcconsintr variable and introduced kbd polling synchronization
+ variable kbd_polling.
+
+- merging Joerg's patch to support 132 columns on Tseng Labs ET3000
+
+- moved Util/uemacs/* --> Etc/uemacs.tar.Z.uu
+
+- added patches from Joerg for new Makefiles in Util
+
+- added keyboard security define's to the new X server code
+
+- adding bugfixes from Joerg Wunsch for "old" (= non vt switching) X server
+
+- Control-Alt-Functionkey(1...12) switches now virtual screens/terminals to
+ behave consistently with xfree 2.0, also the pages are now checked
+ against the real no. of terminals available ALL the time ...
+
+- pcvt_hdr.h: changed "int pcstart();" to "void pcstart();" to avoid warning
+ message when compiling under NetBSD-current
+
+- Doc dir split into Doc and Etc, Support renamed to Util
+
+- adding NetBSD-current support for new X server support (syscframe changed
+ to trapframe in NetBSD-current as of 11/11/93)
+
+- adding Joergs changes for XFree86 2.0 multiple X server and/or terminal
+ session support
+
+- adding entries from patchkit 0.2.4 codrv keymap to Support/keycap/keycap.src
+
+- Keyboard security introduced into the XSERVER dependent part in pcvt_drv.c
+
+- renamed device files from /dev/ttycXX to /dev/ttyvXX
+
+- added file Doc/pcvt.el from Joerg Wunsch to distribution
+
+- added HP-mode function key map from Gordon L. Burditt to description
+ in Doc/Keyboard.HP
+
+- fixed bug in scon which prevents it from showing the correct status of
+ 132 column support of chipset
+
+- 132 column mode for Trident TVGA9000 works now, after 2 1/5 months of
+ calling everybody i eventually got a tech ref manual from Trident ....
+
+- it is now possible to "force" pcvt into a 24 line mode when operating
+ in pure VT mode with 25 lines or in HP mode with 28 lines. This
+ is sometimes necessary when running software which assumes it runs
+ on a "real" VT220 which has just 24 lines.
+
+- updated scon to support the 24 lines force mode (scon -f [ on | off ])
+
+- soft reset fkey now positions cursor into left upper corner, update_cursor()
+ made global function
+
+- updated scon (-l) to print out additional info about the vga chipset,
+ family and 132 column support if VGA detected.
+
+- added additional fields to screeninfo structure in pcvt_ioctl.h to be
+ able to return information about current vga chipset.
+
+- moved VGA type/family definitions from pcvt_hdr.h to pcvt_ioctl.h
+
+- Terminfo and Termcap updated to support 132 columns
+
+- fixed bug in kcon which outputs garbage for remapped keys in kcon -l.
+ (reported by Gordon L. Burditt, gordon@sneaky.lonestar.org)
+
+- modified Makefile for Support/ispcvt to copy it for installation instead
+ of moving it ..
+
+- renamed /usr/share/misc/keycap -> /usr/share/misc/keycap.pcvt to
+ avoid nameclash with same file for codrv (Gordon Burditt)
+
+- security bit no longer ignored when initializing keyboard (see #define
+ PCVT_USEKBDSEC in pcvt_hdr.h, suggested by Terry Lambert)
+
+- cpufunc.h include made only for NetBSD (Gordon Burditt)
+
+- switch statement in pcvt_drv.c removed for 386BSD (Gordon Burditt)
+
+- Trident cursor size bug removed
+
+- keyboard initialization for ddb
+
+- added support for cursor on/of switching, screensaver and DECTCEM
+
+- removed explicit Hercules support, MDA = Hercules in this context now
+
+- patchkit from Joerg Wunsch (kbd-overlay malloc, scroll_sleep, clip fix)
+
+- ispcvt now installed into /usr/sbin
+
+- removed PCVT_NETBSD08 and PCVT_NETBSDCU, intro of PCVT_NETBSD
+
+- implemented 132 column operation for wd90c11 chipsets
+
+- PCVT_PREPATCH022 renamed to PCVT_NEEDPG
+
+- INSTALLATION.NetBSD written
+
+- DEVICE in kcon makefile changed from /dev/console to /dev/ttyc0
+
+- new keyboard code in pcvt_kbd.c from NetBSD current
+
+- new /etc/rc.local script in INSTALLATION
+
+- implemented 132 column operation for et4000 chipsets
+
+- detection of super vga chipsets as a prerequisite for 132 col mode
+
+- switched to memory mapped virtual screen operation, configurable no. of
+ virtual screens, virtual screens now also on MDA and Hercules boards
+
+
+Changes 2.10 -> 2.20 June 1993
+--------------------------------------------------------------------------------
+
+- added new option -a to scon to get the video adaptor in scripts
+
+- support for NetBSD-current, define PCVT_NETBSDCU to enable it
+
+- Support for NetBSD 0.8, define PCVT_NETBSD08 in pcvt_hdr.h to enable it.
+
+- Change Support/Makefile to use <bsd.subdir.mk> instead of <bsd.prog.mk>
+
+- Font editor for the EGA/VGA font-files added to support the design of new
+ fonts. One will need Zeyd M. Ben-Halim's ncurses library to compile it, see
+ file README.FIRST for information where to get it
+
+- Doc/INSTALLATION upgraded
+
+- Terminfo entry added to support Zeyd M. Ben-Halim's ncurses port
+
+- ispcvt is now installed in /sbin to have it at boottime if /usr is not
+ yet mounted.
+
+- applied a patch which prevents CAPS LOCK, SHIFT LOCK, and SCROLL LOCK
+ from being repeated (causing i.e a flashing CAPS LOCK led while
+ holding CAPS LOCK key down).
+ (diff from Gordon L. Burditt, gordon@sneaky.lonestar.org)
+
+- merging patches to support the pccons-model of X11 server support
+ (diff from Joerg Wunsch, joerg_wunsch@uriah.sax.de)
+
+- file pcvt_drv.c routine pg() enclosed in "#ifdef PCVT_PREPATCH022" to solve
+ multiple defined symbols beginning with patchkit 0.2.2
+ (reported by Marko Karppinen, dreamer@purkki.apu.fi)
+
+- added british keycap entry into keycap source file
+ (from Andy Duplain, duplain@rtf.bt.co.uk)
+
+
+Changes 2.00 -> 2.10 March 1993
+--------------------------------------------------------------------------------
+
+- detecting the presence of video boards has been changed to ask the
+ BIOS "equipment byte" in the RTC-CMOS ram what's installed. this caused
+ many discussions but solved also many problems ....
+
+- driver name changed from "pc" to "vt" for multiple driver coexistence
+ (diff from Joerg Wunsch, joerg_wunsch@uriah.sax.de)
+
+- new devicenames recommended for showup in utils like "ps"
+ (many people suggested that ..)
+
+- new location for manual pcvt.0
+ (diff from Joerg Wunsch, joerg_wunsch@uriah.sax.de)
+
+- new demo file "sgr.vt" to show available graphic renditions
+
+- intro of Doc/ChangeLog (this file)
+
+- fixed bug in Support/keycap/Makefile
+ (diff from Gordon L. Burditt, gordon@sneaky.lonestar.org)
+
+- make vttest (main.c) compile after applying patchkit-beta2
+
+- screensaver fixed by Joerg Wunsch
+
+- screensaver now compiled in by default
+
+- made recognition of CONTROL-ALT-DELETE an optional #ifdef'ed feature
+
+- added sgr-conversion table for MDA adaptors
+
+- fixed sgr-conversion table for VGA monochrome environments
+
+- added support for using the kernel debugger
+ (diff from Bruce Evans, bde@runx.oz.au)
+
+- fixed several bugs regarding monochrome environments in pcvt_sup.c
+
+- fixed bug in scon preventing one from piping output though more
+ (reported by Gordon L. Burditt, gordon@sneaky.lonestar.org)
+
+- display current screen number in HP-mode in the bottom right of screen
+
+- changed names of all #define-able compile time options to start with
+ "PCVT_" for easy identification and installation into the kernel config file
+
+- applied another pcvt_kbd.c patchkit from Bruce Evans, bde@runx.oz.au. he
+ writes:
+
+ These fixes are mainly related to ddb. sgetc has a weird interface that
+ has caused some bugs, and it was too easy for ddb to reenter itself.
+
+ 1. Don't use char for keypad2num, char might be unsigned. Space is not
+ important since the array is small.
+
+ 2. Don't use u_short for n.
+
+ 3. Change some 0's to NULLs.
+
+ 4. sgetc must not return NULL for the !noblock case. Only callers with
+ noblock set check for the null pointer. When the kernel follows a
+ null pointer, I think page 0 is sometimes mapped in so nothing bad
+ happens. The kernel panics if the page is not mapped in.
+
+ 5. Reentrancy fix. The debugger really ought to check for reentrancy
+ itself, but the driver still needs to return early after the
+ debugger returns, so that it doesn't return a junk ESC from
+ ctrl-alt-ESC.
+
+ 6. xlatkey2ascii may return NULL too.
+
+--------------------------------------------------------------------------------
diff --git a/sys/arch/i386/isa/pcvt/Doc/CharGen b/sys/arch/i386/isa/pcvt/Doc/CharGen
new file mode 100644
index 00000000000..c047bfacca0
--- /dev/null
+++ b/sys/arch/i386/isa/pcvt/Doc/CharGen
@@ -0,0 +1,149 @@
+Character Generator description (before it gets lost ..)
+--------------------------------------------------------------------------------
+
+The lower character generator is the default IBM character set II.
+
+The description of the higher character generator follows below. The
+character names are taken from the "Postscript Language Reference
+Manual", 2nd Edition, Fourth printing July 1991, pp 596.
+
+NOTE: The hex values here are NOT the values the character is identified
+ by in the emulator. The "physical" (vt220 character) to "logical"
+ (this table, character generator) conversion is done in the character
+ output routine by using the tables from file pcvt_tbl.h.
+
+The order of the characters is not regular and was largely influenced by
+the status of my brain while pixel-placing characters ....
+
+HEX What
+--- -------------------------------------------------
+00 Control code display for
+. control characters in the
+1f range 0x00 - 0x1f
+
+20 Control code display for
+. control characters in the
+3f range 0x80 - 0x9f
+
+HEX What
+--- -------------------------------------------------
+40 rho
+41 psi
+42 partialdiff
+43 lambda
+44 iota
+45 eta
+46 epsilon
+47 chi
+48 logicaland
+49 logicalor
+4a union
+4b propersuperset
+4c propersubset
+4d gamma
+4e Xi
+4f Psi
+
+HEX What
+--- -------------------------------------------------
+50 Pi
+51 arrowdblright
+52 arrowdblboth
+53 Lambda
+54 Theta
+55 congruent
+56 gradient
+57 Delta
+58 proportional
+59 therefore
+5a integral
+5b fraction
+5c (inverted fraction ????)
+5d angle
+5e (inverted angle ????)
+5f braceleftmid
+
+HEX What
+--- -------------------------------------------------
+60 bracerightmid
+61 bracelefttp
+62 braceleftbt
+63 bracerighttp
+64 bracerightbt
+65 radical
+66 omega
+67 (Yen ??)
+68 xi
+69 yacute
+6a thorn
+6b eth
+6c Thorn
+6d Yacute
+6e multiply
+6f Eth
+
+HEX What
+--- -------------------------------------------------
+70 threequarters
+71 Cedillasmall
+72 Acutesmall
+73 emdash
+74 registered
+75 endash
+76 logicalnot
+77 dieresis
+78 notequal
+79 scan 9
+7a scan 7
+7b scan 5
+7c scan 3
+7d scan 1
+7e upsilon
+7f emptyset
+
+HEX What
+--- -------------------------------------------------
+80 oe
+81 Otilde
+82 atilde
+83 Ydieresis
+84 Ucircumflex
+85 Uacute
+86 Ugrave
+87 Oslash
+88 OE
+89 Otilde
+8a Ocircumflex
+8b Oacute
+8c Ograve
+8d Idieresis
+8e Icircumflex
+8f Iacute
+
+HEX What
+--- -------------------------------------------------
+90 Igrave
+91 Edieresis
+92 Ecircumflex
+93 Egrave
+94 Atilde
+95 Acircumflex
+96 Aacute
+97 Agrave
+98 onesuperior
+99 (small black rectangle)
+9a zeta
+9b threesuperior
+9c copyright
+9d currency
+9e kappa
+9f (inverted question mark)
+
+HEX What
+--- -------------------------------------------------
+a0 the remaining positions
+. are used for the vt220
+ff downloadable characterset
+
+-------------------------------------------------------------------------------
+ (phoooo ..)
diff --git a/sys/arch/i386/isa/pcvt/Doc/Charsets b/sys/arch/i386/isa/pcvt/Doc/Charsets
new file mode 100644
index 00000000000..b30dd8a44a8
--- /dev/null
+++ b/sys/arch/i386/isa/pcvt/Doc/Charsets
@@ -0,0 +1,99 @@
+
+I. Character Set Selection on VT220 Terminals
+==================================================
+
+
+name C0 GL C1 GR
+ +---+ +-------------------+ +---+ +-------------------+
+ |00h| | | |80h| | |
+range | | | | 20h .. 7fh | | | | | a0h .. ffh |
+ |1fh| | | |9fh| | |
+ +---+ +-------------------+ +---+ +-------------------+
+length 32 96 32 96
+
+ /\
+SECOND /||\ "lock"- or "single"-shift one set of G0, G1, G2 or
+STEP || G3 into one of the "displayable" charactersets GL
+ || or GR. (escape) sequences are: SI, SO, ESC ~, ESC n,
+ || ESC }, ESC o, ESC |, ESC N and ESC O.
+
+ +----+ +----+ +----+ +----+
+name | G0 | | G1 | | G2 | | G3 |
+length |(96)| |(96)| |(96)| |(96)|
+ +----+ +----+ +----+ +----+
+
+ /\
+ /||\ designate a hard or a soft character set as
+ || one of G0, G1, G2 or G3, used escape sequences
+FIRST || are, ESC ( X, ESC ) X, ESC * X and ESC + X - where X is
+STEP || B for ascii, < for supplemental, 0 for special, A for
+ || british, 4 for dutch, C and 5 for finnish etc. etc. ...
+ ||
+
+ +-----+ +------------+ +--------+ +-----------+ +------------+
+name |ascii| |supplemental| |special | | national | |downloadable|
+ | | | graphics | |graphics| |replacement| |characterset|
+length | (96)| | (96)| | (96)| | (96)| | (96)|
+ +-----+ +------------+ +--------+ +-----------+ +------------+
+
+ \-------\ /----------/ norway/danish
+ | dutch
+ together, this is also finnish
+ referred to as the french
+ multinational character french canada
+ set (power on default german
+ on a dec vt220) italian
+ spanish
+ swedish
+ swiss
+
+
+II. Emulating Character Set Selection
+=========================================
+
+MDA/HCG/CGA:
+
+ just a partial emulation is done, because these boards don't allow
+ downloadable charactersets. some characters simply don't display
+ because they are not in the characterset roms on the video board.
+
+ if you want to change the mapping, have a look at the default tables
+ in pcvt_tbl.h.
+
+EGA/VGA:
+
+ these cards have provisions for downloadable charactersets and so
+ many vt220/vt320 charactersets are fully supported:
+
+ - US Ascii
+ - DEC Supplemental
+ - DEC Special Graphic
+ - DEC Technical
+ - ISO Latin-1
+ - Downloadable
+
+ when the emulator is started, it behaves initially similar to
+ the MDA/CGA/HCG method described above.
+
+ when a second (special) characterset for a given screen resolution
+ is loaded via the "loadfont" utility, the emulator detects this fact
+ and uses from then on extended tables to access the second charset
+ as an upper half 512 characterset in terms of ega/vga speak.
+
+ from this time on, vt220 downloadable fonts are usable.
+
+ the organization of this extended characterset is as follows:
+
+ 0x00 ... 0x1f C0 display function fonts
+ 0x20 ... 0x3f C1 display function fonts
+ 0x40 ... 0x9f fonts for DEC Supplemental, DEC Special
+ Graphic, DEC Technical and ISO Latin-1
+ 0xa0 ... 0xff VT220 Downloadable Font
+
+ the mapping between vt220 charactersets and the charactersets inside
+ the ega/vga is done by tables found in the file pcvt_tbl.h.
+
+ there is a MSDOS fonteditor called "EVAFONT" available on the
+ SIMTEL-20 archive, which i used to edit the character sets in the
+ distribution.
+
diff --git a/sys/arch/i386/isa/pcvt/Doc/EscapeSequences b/sys/arch/i386/isa/pcvt/Doc/EscapeSequences
new file mode 100644
index 00000000000..8e0e2c77e6d
--- /dev/null
+++ b/sys/arch/i386/isa/pcvt/Doc/EscapeSequences
@@ -0,0 +1,268 @@
+ Control Codes and Escape Sequences supported by pcvt
+===============================================================================
+
+CONTROL CODES
+-------------------------------------------------------------------------------
+
+ NUL (0x00) ignored
+ SOH (0x01) ignored
+ STX (0x02) ignored
+ ETX (0x03) ignored
+ EOT (0x04) ignored
+ ENQ (0x05) ignored
+ ACK (0x06) ignored
+
+ BEL (0x07) beep
+
+ BS (0x08) move one character position to the left
+ until at left margin
+
+ HT (0x09) move to next tab stop
+
+ LF (0x0a) move to next line, same column
+ VT (0x0b) move to next line, same column
+ FF (0x0c) move to next line, same column
+
+ CR (0x0d) move to left margin on current column
+
+ SO (0x0e) invoke character set G1 into GL
+ SI (0x0f) invoke character set G0 into GL
+
+ DLE (0x10) ignored
+ DC1 (0x11) ignored
+ DC2 (0x12) ignored
+ DC3 (0x13) ignored
+ DC4 (0x14) ignored
+ NAK (0x15) ignored
+ SYN (0x16) ignored
+ ETB (0x17) ignored
+
+ CAN (0x18) abort current escape sequence
+
+ EM (0x19) ignored
+
+ SUB (0x1a) abort current escape sequence
+
+ ESC (0x1b) start of escape sequence
+
+ FS (0x1c) ignored
+ GS (0x1d) ignored
+ RS (0x1e) ignored
+ US (0x1f) ignored
+
+ VT220 control codes in the range 0x80 .. 0x9f are completely ignored,
+ but displayed as C1 display controls.
+
+
+ESCAPE SEQUENCES DIGITAL EQUIPMENT
+-------------------------------------------------------------------------------
+
+(ni) = not implemented yet, all hooks available inside emulator!
+<p> = numeric parameter
+
+ ESC space F select 7-bit c1 control transmission (ni)
+ ESC space G select 8-bit c1 control transmission (ni)
+
+ ESC # 3 double height top half (ni)
+ ESC # 4 double height bottom half (ni)
+ ESC # 5 single width single height (ni)
+ ESC # 6 double width single height (ni)
+
+ ESC # 8 fill screen with 'E's
+
+ ESC 7 save cursor
+
+ ESC 8 restore cursor
+
+ ESC = keypad application mode
+
+ ESC > keypad numeric mode
+
+ ESC D index
+
+ ESC E next line
+
+ ESC H set tab at cur col
+
+ ESC M reverse index
+
+ ESC N single shift G2
+
+ ESC O single shift G3
+
+ ESC Z who are you
+
+ ESC d Only available if PCVT_SETCOLOR was defined when
+ compiling the kernel, allows to set custom color table
+ for more info, see pcvt_out.c ...
+
+ ESC c power up reset
+
+ ESC n Lock Shift G2 -> GL
+
+ ESC o Lock Shift G3 -> GL
+
+ ESC } Lock Shift G2 -> GR
+
+ ESC | Lock Shift G3 -> GR
+
+ ESC ~ Lock Shift G1 -> GR
+
+ ESC [ ? <p> h set dec private modes
+ ESC [ ? <p> l reset dec private modes
+ 1 CKM - cursor key mode
+ 6 OM - origin mode
+ 7 AWM - auto wrap mode
+
+ ESC [ <p> ' z DECELR - Enable Locator Report (ni)
+
+ ESC [ <p> ' { DECSLE - Select type of locator events (ni)
+
+ ESC [ ? n Terminal Reports
+
+ ESC [ ? K selective erase in line
+
+ ESC [ ? J selective erase in display
+
+ ESC [ <p> @ insert char(s)
+
+ ESC [ <p> A cursor up
+
+ ESC [ <p> B cursor down
+
+ ESC [ <p> C cursor forward
+
+ ESC [ <p> D cursor backward
+
+ ESC [ <p> H cursor direct cursor addressing
+
+ ESC [ <p> J erase screen
+
+ ESC [ <p> K erase line
+
+ ESC [ <p> L insert line
+
+ ESC [ <p> M delete line
+
+ ESC [ <p> P delete char
+
+ ESC [ <p> S scroll up
+
+ ESC [ <p> T scroll down
+
+ ESC [ <p> X erase character
+
+ ESC [ <p> c device attributes
+
+ ESC [ <p> f direct cursor addressing
+
+ ESC [ <p> g clear tabs
+
+ ESC [ <p> h set mode
+ ESC [ <p> l reset mode
+ 4 IRM - insert replacement mode
+ 20 LNM - line feed / newline mode
+
+ ESC [ <p> i media copy (ni)
+
+ ESC [ <p> m select graphic rendition
+ 0 reset to normal attributes
+ 1 bold
+ 4 underline
+ 5 blinking
+ 7 reverse
+ 22 bold off
+ 24 underline off
+ 25 blinking off
+ 27 reverse off
+ 30-37 foreground colors (on color display)
+ 40-47 background colors (on color display)
+
+ ESC [ <p> n device status report
+
+ ESC [ <p> r set scrolling region
+
+ ESC [ <p> x request / report terminal parameters
+
+ ESC [ <p> y invoke selftests (ni)
+
+
+ ESC [ x request/report parameters
+ ESC [ y invoke seftest(s)
+
+ ESC [ " q SCA
+ ESC [ ! p SCA
+
+ ESC ( <p> designate G0
+ ESC ) <p> designate G1
+ ESC * <p> designate G2
+ ESC + <p> designate G3
+ ESC - <p> designate G1 (96)
+ ESC . <p> designate G2 (96)
+ ESC / <p> designate G3 (96)
+ A British or ISO-Latin-1
+ B USASCII
+ C Finnish
+ 5 Finnish
+ E Norwegian/Danish
+ 6 Norwegian/Danish
+ H Swedish
+ 7 Swedish
+ K German
+ Q French Canadien
+ R French
+ Y Italian
+ Z Spanish
+ 0 special graphics
+ 1 alternate ROM
+ 2 alt ROM, spec graphics
+ 3 HP Roman 8, upper 128 chars*/
+ 4 Dutch
+ < DEC Supplemental
+ = Swiss
+ > DEC Technical
+
+
+ESCAPE SEQUENCES HEWLETT-PACKARD
+-------------------------------------------------------------------------------
+
+ESC&f<attr>a<key>k<llen>d<slen>L<label><string> set function key label
+
+ attr = attribute, 0 - normal (not implemented)
+ 1 - local only (not implemented)
+ 2 - transmit only (not implemented)
+
+ key = function key number, range 1 .. 8
+
+ llen = label string length
+
+ slen = string string length
+
+ label = label data (up to 16 chars per label)
+
+ string = string to send data (up to 80 chars per label)
+ (not implemented)
+
+EXAMPLE:
+========
+
+ ESC&f0a1k16d1LFUNCTION KEY 0
+
+ sets function key label 1 to "FUNCTION KEY ".
+ should program fkey 1 to emit "0" on keypress
+
+
+ESC&j<parm> function key operations
+
+ parm = '@' remove the function key labels from screen
+
+ parm = 'A' display the modes set of function key labels
+
+ parm = 'B' enable & display user function key labels
+
+ parm = 'C' clear message & restore the current key labels
+
+ parm = 'R' enable usr/sys and menu and label modes
+
+ parm = 'S' disable usr/sys and menu and label modes
+
diff --git a/sys/arch/i386/isa/pcvt/Doc/FAQ b/sys/arch/i386/isa/pcvt/Doc/FAQ
new file mode 100644
index 00000000000..b45c4297aec
--- /dev/null
+++ b/sys/arch/i386/isa/pcvt/Doc/FAQ
@@ -0,0 +1,405 @@
+FAQ's, Notes and Hints Last Edit-Date: [Tue Oct 3 11:05:55 1995]
+--------------------------------------------------------------------------------
+
+How to start the X server at boot time in a dedicated virtual screen
+================================================================================
+
+> I'm trying to keep an xdm session open on screen 4 at all times so I
+> don't have to keep starting X whenever I login. However, I don't want
+> the xdm login screen to be the default since I usually prefer
+> character mode screens.
+>
+> I'm using the pcvt console driver and in rc.local I'm doing this:
+>
+> /usr/sbin/scon -c 3 # go to screen 4
+> /usr/X11R6/bin/xdm -daemon # fire up xdm
+> sleep 10 # give xdm some time to start
+> /usr/sbin/scon -c 0 # come back to preferred login screen
+>
+> When I reboot, I see xdm start, come up with the graphical login, then
+> switch back to screen 1. However, if I hit CTRL+ALT+F4, the xdm
+> screen is gone and I'm met with just a blank (character mode) screen.
+
+Hmm - I'm doing this all the time with 2.0.5 on the 8th virtual screen.
+
+Did you disable the getty for the corresponding screen in /etc/ttys ?
+
+You need a configuration for xdm in /usr/X11R6/lib/X11/xdm/Xservers similar
+to this (from my system):
+
+ :0 local /usr/X11R6/bin/X vt8
+
+My (part of) rc.local looks like this for starting xdm at boot time on
+screen 8:
+
+[....]
+
+# path for xdm (X11R6)
+XDMP=/usr/X11R6/bin
+# path for xdm (X11R5)
+#XDMP=/usr/X386/bin
+
+# set to YES to start xdm on screen 8
+xdm_start=YES
+#xdm_start=NO
+
+[....]
+
+#--------------------------------------------------
+# if desired, start xdm on screen 8
+#--------------------------------------------------
+
+ if [ X${xdm_start} = X"YES" -a -x $XDMP/xdm ]
+ then
+ $SCONP/scon -d /dev/ttyv7
+ $XDMP/xdm
+ sleep 10
+ $SCONP/scon -d /dev/ttyv0
+ fi
+
+
+pcvt (german) keyboard remapping not adopted by X server
+================================================================================
+
+1) make shure your xterm is able to display national (8-bit) characters,
+ i.e. issue something like "stty cs8 -parenb -istrip".
+
+2) and more important, in the XFree86 3.x configuration file XF86Config,
+ you have to enable the AltGr - Key by uncommenting the line:
+
+ RightAlt ModeShift
+
+ in the Keyboard Section.
+
+
+Keyboard not working with pcvt
+================================================================================
+
+From Leo Bicknell (bicknell@ufp.org):
+
+ I have two systems I am trying to use your PCVT driver on
+ running NetBSD 1.0. One is a plain vanilla PC, but it has a
+ Northgate Omnikey Ultra programmable keyboard, the other is a IBM
+ Thinkpad 755c laptop. Both exhibit the same behavior. Under scan
+ set 1 they both are completely broken. Virtual consoles don't work
+ at all, in fact on the laptop none of the keys work properly.
+
+After using PCVT_SCANSET=2 both keyboards are running (-hm).
+
+
+Can't get pcvt working on a ThinkPad
+===============================================================================
+
+Anyway, back to the keyboard. The problem is that by default the
+ThinkPad uses PS/2 scan code mode.
+
+You can fix this by using an option and building a kernel, as shown
+below.
+
+] Just for the record, in case someone else is asking for this: Al's
+] confirmation that pcvt w/ PCVT_SCANSET=2 works for the ThinkPad:
+]
+] As Al Elia wrote:
+] | Date: Mon, 28 Nov 1994 18:24:42 GMT
+] | From: Al Elia <aelia%aelia.student.harvard.edu@sax.sax.de>
+] | Message-Id: <199411281824.SAA01554@aelia.student.harvard.edu>
+] | To: joerg_wunsch@bonnie.tcd-dresden.de
+] | Subject: Re: Anyone got FreeBSD 1.1.5.1 running on a ThinkPad?
+] |
+] | PCVT_SCANSET=2 worked...I had put in PCVT_SCAN_SET=2 (Doh!)
+] |
+] | --Al Elia
+] | <aelia@aelia.student.harvard,edu>
+
+ (Terry Lambert quoting Joerg Wunsch quoting Al Elia)
+
+Scancode 2 is also reported to work for a Thinkpad 755c (-hm)
+
+
+If one of the "lock" keys is pressed, LEDs do not get updated, keyboard hangs
+===============================================================================
+
+This entry used to be a long time in the BugList file, and i could never
+reproduce the problem. Today i got an explanation in german from someone
+owning such a keyboard, i'll try to translate:
+
+"This are old keyboards manufactured (~1985/1986) which manage their LED
+ setting only internally.
+ It is not possible to set the LEDs from the (main-) processor, if you
+ try, the keyboard processor hangs and the PC has to be reset by switching
+ power on and off, hard- and/or softreset does not work in this case.
+ Workaround: recompile pcvt with the LED update removed"
+
+In other words, define PCVT_NO_LED_UPDATE if you have such a beast!
+
+
+Cursor not visible anymore in 40 and 50 lines mode
+===============================================================================
+
+You have programmed an underline cursor in i.e. 28 line mode by doing
+"cursor -s 10 -e 12". Then you switch to 40 line mode using "scon -s 40".
+At this point the cursor is no longer visible because the 40 line font
+is only 10 pixels high and the cursor size is programmed with a value
+expressing its size from the top down and NOT from the bottom up!
+If anyone has a good idea how to solve this problem, please tell me!
+The only solution i see so far is having some sort of "generic" cursor
+sizes/descriptions (i.e. underline, rectangle, block) which are
+recalculated in case of a switch to another line size.
+
+
+386BSD port
+===============================================================================
+
+I don't have access to a 386BSD 0.1 machine anymore so the 386BSD pcvt is
+considered unsupported and will disappear in the future.
+
+386BSD support was dropped with release 3.20.
+
+
+Keyboard hangs after first update of keyboard LED's
+===============================================================================
+
+Define PCVT_NO_LED_UPDATE and recompile pcvt. (Or, get yourself a better
+keyboard. Some keyboards just don't work the documented way, this fact is
+"normally" masked by the manufacturers BIOS but unhides when one accesses
+the hardware directly.)
+
+
+Garbled screen when running vi
+===============================================================================
+
+When the terminal speed in the tty structure is set to low speeds (i.e. 1200
+Baud), pcvt shows a strange behaviour in some environments due to the changed
+screen update sequences from vi.
+
+Please check your shell startup files, /etc/ttys and /etc/gettytab and change
+the baudrate (i.e. by using stty(1)) to a higher value, i.e. 19200 Baud.
+
+Since i'm not a vi specialist, i never managed to find out wheter to blame
+vi or pcvt.
+
+
+Stty influences on the driver
+===============================================================================
+
+There used to be an entry in the BugList:
+
+ (printf with 9 x tab) printf "\n\t\t\t\t\t\t\t\t\tGotcha" works ok,
+ while one tab more: printf "\n\t\t\t\t\t\t\t\t\t\tGotcha" doesn't
+ work (it doesn't print Gotcha at column 80, but at column 131).
+
+This was solved some time ago:
+
+ On another note: if I use stty xtabs, the 'printf "\t\t\t\t\t\t\t"
+ bug goes away. With stty xtabs the tab handling is done in the kernel.
+
+(See also below: "Vttest shows strange results")
+
+
+After running some graphics application, the cursor is stuck on the
+bottom line, though everything else appears well
+===============================================================================
+
+Though this might initially appear to be a driver problem, it's rather
+an application program's bogosity. The cursor update is done asynchron-
+ously (to gain output speed), but this cursor update is inhibited while
+an application has put a virtual terminal into ``graphics mode'' (i.e.,
+the application program tells the driver that it's now responsible for
+anything and all on this vty). This is notably the case while X11 is
+running.
+
+If the application fails to properly shut down itself, the terminal
+might be left in an undefined state. The driver stand no chance there,
+even if it could detect this bad status, since it doesn't know enough
+about each piece of hardware to deal with. One possibility is that
+the X server has been shot up and didn't get it to do its cleanups.
+Another case (which i've often noticed on my slow notebook) is, killing
+the Xserver is too slow for the (unfortunately hard-coded) 10-second
+timeout from xinit, so it's being aborted ridiculously. (``X server
+slow to shut down, sending KILL signal.'') This way, the state of
+damage might range from ``almost okay, but cursor is stuck'' up to
+a totally unusable machine (moon bitmap from xphoon still displayed,
+no keyboard responses, only network is working and can be used to
+shut down cleanly).
+If the state of damage is only minimal, you might try to run the pure
+X server on that vty again, and exit it with Ctrl-Alt-BkSpc. This might
+be a workaround.
+
+
+Vttest shows strange results
+===============================================================================
+
+Verify your stty "oxtabs" settings, it has to be "oxtabs", NOT "-oxtabs".
+Get yourself an original DEC terminal to verify vttest's output, i have
+until now not seen any (!) VTxxx clone, which does it right !!!
+
+
+VT220-like Keyboard Layout
+===============================================================================
+
+I have to say, i don't use it and i don't like it, so it's mostly unsupported
+and untested. Patches welcome!
+
+
+132-column mode
+===============================================================================
+
+There are known difficulties running pcvt in 132 column mode in conjunction
+with X. Switching to 132 column mode does not only depend on a given chipset,
+but on the board/manufacturers method of clock generation also. Even if your
+chipset is detected, there may be still a problem with your board and it's
+method of generating clocks. You may run in severe difficulties if your
+board has a programmable clock generator and you run X and you switch from
+132 col mode into X and back.
+
+I have currently no idea how to solve this, other than having a similar
+scheme as XFree86 applied to pcvt: Letting the user probe his board by using
+SuperProbe and recompiling pcvt according to the result.
+
+I stumbled a bit deeper into this with my ELSA Winner 1000, which is equipped
+with a ICD2061 clock synthesizer chip. For 132 column mode to work properly,
+clock generator 2 must deliver 40 MHz to the S3 VGA chip, but this value has
+to be programmed or initialized. If this VGA board has ever been switched
+into 132 colums, i.e. in my case from a DOS program, it will continue to do
+so until X runs or the machine is power cycled. If that occurs, the clock
+generator 2 does contain nothing or garbage (in case of power cycling) or it
+does contain the value for the current resolution in X in case of having been
+in the X Server screen recently.
+
+The X Server reprograms the clock generator each time the server is entered,
+so the only thing to do is to reprogram the clock generator too when pcvt is
+entered. Until now i found no way of identifying the clock oscillator chip
+used, so an automatic clock switching seems to be a problem.
+
+
+NetBSD 0.9 and Xfree86 2.0
+===============================================================================
+
+To get the X server up and running on 0.9, you have to compile pcvt with
+PCVT_USL_VT_COMPAT disabled, otherwise X (and SuperProbe) will hang the
+video driver (not the whole machine !). This bug is reproducible but not
+found yet ...
+This does not apply to NetBSD-current, 386BSD and FreeBSD.
+
+
+X server ioctl compatibility:
+===============================================================================
+
+The compatibility X-Mode ioctl commands CONSOLE_X_MODE_ON and
+CONSOLE_X_MODE_OFF should not be used intermixed with the USL VT style
+commands on another virtual terminal. NB, that this situation could happen
+if you run an XFree86 2.0 server on one virtual terminal and attempt to
+run SuperProbe version 1.0 (as delivered with the XFree86 2.0 release)
+on another vty. SuperProbe is still using the old commands in order to
+gain IO privileges.
+Since the old commands cannot care for things like terminal switching,
+serious corruption could result from this, which need not to be detected
+immediately (i.e., apparently SuperProbe ran well). Known problems are
+font corruptions after the X server has been shut down later, or palette
+flickers in 1-second intervals due to an erroneously re-enabled screen
+saver.
+
+Once that SuperProbe has been fixed in its release to use the USL VT style
+commands, any support for the old CONSOLE_X_MODE_XXX commands will be
+eliminated.
+
+(Recent comment: SuperProbe 1.3 has been fixed. It will be delivered with
+XFree86 2.1.)
+
+
+How to set the foreground intensity to high on VGA mono screens:
+===============================================================================
+
+try to issue the command: "scon -p8,60,60,60", EXPERIMENT !!!
+
+
+How to change the color palette on VGA cards:
+===============================================================================
+
+try out the following commands:
+
+ /usr/local/bin/scon -d/dev/ttyv0 -pblack:0,0,0 -pblue:20,20,40
+ /usr/local/bin/scon -d/dev/ttyv0 -pbrown:55,55,15 -plightgray:0,42,0
+ /usr/local/bin/scon -d/dev/ttyv1 -pblack:42,42,42 -pblue:60,60,60
+ /usr/local/bin/scon -d/dev/ttyv1 -pbrown:60,60,30 -plightgray:30,10,0
+ /usr/local/bin/scon -d/dev/ttyv2 -pblack:42,42,42 -pblue:63,63,63
+ /usr/local/bin/scon -d/dev/ttyv2 -pbrown:60,60,20 -plightgray:0,22,0
+ /usr/local/bin/scon -d/dev/ttyv3 -pblack:38,38,38 -pblue:63,63,63
+ /usr/local/bin/scon -d/dev/ttyv3 -pbrown:60,40,0 -plightgray:0,0,20
+
+ ("scon -p default" resets the colors ...)
+
+
+I have the screensaver compiled in, but can't see any effect
+===============================================================================
+
+Don't forget to turn it on with the scon utility. E.g.,
+
+ scon -t 120
+
+sets the timeout to 2 minutes.
+
+
+Your Notebook uses the NumLock state to switch half of the keyboard into a
+numeric keypad
+===============================================================================
+
+Sigh, each time you leave "vi", your NumLock LED is on again and you
+get a "6" instead of "o"? Try to compile pcvt with:
+
+ options "PCVT_INHIBIT_NUMLOCK"
+
+this prevents applications from turning NumLock on/off (except the
+Xserver - but you want this).
+
+
+Your notebook significantly loses contrast when using pcvt
+===============================================================================
+
+Pcvt turns off the "high intensity" attribute bit internally (to enable
+the use of a 512-characters charset). Some notebooks hard-code the out-
+put intensity versus the character attribute though (i know it for a
+Cirrus Logic CL-GD610/620 chipset).
+
+As a quick & dirty workaround, you can reverse what pcvt did to the
+Attribute Controller. Do not hack pcvt_sup.c, instead patch your
+VGA registers during rc.local with the help of the vgaio utility:
+
+ echo "ar12=0f" | vgaio > /dev/null
+
+For the CL-GD610/620, i'm remapping some attribute registers and
+get a simple gray scale emulation with this (i.e., i DO NOT use
+the hack above):
+
+ eagle_id=`echo 'cr1f?' | vgaio | cut -dx -f2`
+ echo "sr 6 = $eagle_id" | vgaio > /dev/null # enable extended regs
+ echo "sr d5 = 40" | vgaio > /dev/null # not inverse, enable
+ # color emulation
+ echo "ar0=0;ar1=9;ar2=12;ar3=1b;ar4=24;ar5=2d;ar6=36;ar7=3f"|vgaio>/dev/null
+ echo "ar8=0;ar9=9;ara=12;arb=1b;arc=24;ard=2d;are=36;arf=3f"|vgaio>/dev/null
+
+NOTE THAT THIS IS ONLY FROM EXPERIMENTS! There's no warranty that something
+like this wouldn't damage your screen/VGA!
+
+(If you have chipset documentation, you're lucky...)
+
+
+How to set the "LINES"-Environment variable for sh/csh:
+===============================================================================
+
+(Note: this is mostly obsoleted now since the driver properly generates
+SIGWINCH'es to notify applications about a changed screen size.)
+
+ first for the csh:
+
+ alias linesw scon -s \!^ \; setenv LINES \!^
+
+ now for the bash/ash/sh/bash users:
+
+ linesw()
+ {
+ scon -s $1
+ LINES=$1; export LINES
+ }
+
+/* EOF */
diff --git a/sys/arch/i386/isa/pcvt/Doc/INSTALL.FreeBSD-2.0 b/sys/arch/i386/isa/pcvt/Doc/INSTALL.FreeBSD-2.0
new file mode 100644
index 00000000000..b955f878540
--- /dev/null
+++ b/sys/arch/i386/isa/pcvt/Doc/INSTALL.FreeBSD-2.0
@@ -0,0 +1,160 @@
+Note: As of FreeBSD 2.0.5 pcvt is integrated into the FreeBSD source tree and
+ the item #1 no longer applies!
+
+
+How to install the pcvt driver on a FreeBSD 2.0 machine (pcvt rel. 3.20)
+-------------------------------------------------------------------------------
+ last edit-date: [Fri Jun 30 20:35:28 1995]
+
+(1) Copy the driver distribution files into appropriate directories:
+
+ (1a) make a fresh directory
+
+ mkdir /usr/src/sys/i386/isa/pcvt
+ cd /usr/src/sys/i386/isa/pcvt
+
+ (1b) copy the pcvt distribution (or unshar it) into this newly
+ created directory (/usr/src/sys/i386/isa/pcvt)
+
+ (1c) copy the ioctl-header file into its destination directory
+
+ cp pcvt_ioctl.h /usr/include/machine
+
+(2) You have the choice of two keyboard layouts regarding the placement of
+ the vt220 function keys and the HELP and DO keys.
+
+ Both configurations are documented in the files Keyboard.HP and Keyboard.VT
+ respectively.
+
+ Decide which one to use and set the "#define" of PCVT_VT220KEYB to
+ compile the one you choosed.(see also pcvt_conf.h and pcvt_kbd.c)
+ Note: the preferable way to do all option hacking is to add "options"
+ lines to the kernel's config file. See the pcvt(4) man page (in this
+ directory).
+
+(3) There are several other configuration "#define"-able options located at
+ the beginning of pcvt_conf.h. "user"-settable options all start with
+ "PCVT_".
+ Please (!!!) read the comments for them in the header file !
+
+(4) Add a line
+
+ option "PCVT_FREEBSD=200"
+
+ into your kernel config file. The quotes are important. The number
+ should represent the version of your kernel, "200" stands for "2.00",
+ which is the official version number for FreeBSD 2.0 (Release).
+
+(5) Edit your kernel configuration file and comment the following line out
+ by placing a "#" in front of it:
+
+ device sc0 at isa? port "IO_KBD" tty irq 1 vector scintr
+
+ add a new config-line just below it:
+
+ device vt0 at isa? port "IO_KBD" tty irq 1 vector pcrint
+
+ The lines in my config file look like this:
+
+ #device sc0 at isa? port "IO_KBD" tty irq 1 vector scintr
+ device vt0 at isa? port "IO_KBD" tty irq 1 vector pcrint
+
+ You can use now either the pccons driver or the pcvt driver (or possibly
+ other console drivers too!) by simply un-commenting ONE of them.
+
+ YOU CANNOT USE/UNCOMMENT MORE THAN __ONE__ CONSOLE DRIVER !!!
+
+(6) Configure a new kernel using config(8).
+
+(7) Run "make depend" for the new kernel !!!!
+
+(8) Compile the new kernel
+
+(9) Test the new kernel and check whether it still works with your
+ keyboard and your videoboard. Testing could be done best by entering
+ the kernel name (e.g. /kernel.pcvt) at the boot prompt, append a
+ "-s" flag to prevent it from booting multi-user! The multi-user
+ boot phase requires the kernel to be named "/kernel".
+
+ If the kernel works, rename the old kernel (you don't need it any
+ more?), link the new one to "/kernel", and reboot up to multi-user.
+
+(10) Change into the distribution subdirectory "Util".
+ Copy Makefile.inc.FreeBSD to Makefile.inc and edit Makefile.inc
+ to suit your needs, especially have a look at "MANDIR" and "BINDIR".
+ Then execute "make". This makes all the utilities in their directories.
+ when you are satisfied with the results, execute "make install". This
+ installs all programs in all subdirs in "BINDIR" and all manual pages
+ in "MANDIR", all fonts in "FONTDIR" and the keycap database in "CAPDIR".
+ NB: unless you've got this distribution along with a FreeBSD distrib-
+ ution (where it is pre-installed:-), you WILL have to edit Makefile.inc
+ in order to get the man pages installed in source form.
+
+ Change into the distribution subdirectory "Doc" and edit Makefile
+ to suit your needs. Then execute "make" to prepare the manpage for
+ the driver.
+
+(11) If necessary, edit /usr/share/misc/keycap to match your keyboard.
+ Keycap uses special codes which are documented in Util/kcon/keycap.3
+ and Util/kcon/keycap.5. Also have a look at Util/kcon/kcon.1.
+
+(12) There are example termcap entries for the various screen resolutions
+ in the file "Etc/Termcap". Integrate them into your termcap file if
+ you don't have a "normal" vt220 entry or want to use pcvt's extensions.
+ Don't forget to run cap_mkdb after changing your termcap file !
+
+ NOTE: pcvt works with an unmodified VT220 termcap entry !
+ (it was written to do that .... ;-)
+
+(13) To use the virtual terminals, one must "mknod" this devices, they have
+ major number 12 and minor numbers 0 to n. The MAKEDEV script in the
+ /dev directory is suitable for this task, just change into the /dev
+ directory and execute 'sh ./MAKEDEV vty8' to make devicefiles for 8
+ virtual terminals.
+
+ If you want to use the mouse emulator, see the comments in pcvt(4).
+
+(14) edit /etc/ttys to enable login on the virtual consoles, mine looks like
+ this:
+
+ ttyv0 "/usr/libexec/getty Pc" pcvt25h on secure
+ ttyv1 "/usr/libexec/getty Pc" pcvt25h on secure
+ ttyv2 "/usr/libexec/getty Pc" pcvt25h on secure
+ ttyv3 "/usr/libexec/getty Pc" pcvt25h on secure
+ ttyv4 "/usr/libexec/getty Pc" pcvt25h on secure
+ ttyv5 "/usr/libexec/getty Pc" pcvt25h on secure
+ ttyv6 "/usr/libexec/getty Pc" pcvt25h on secure
+ ttyv7 "/usr/libexec/getty Pc" pcvt25h on secure
+
+
+(15) Edit /etc/rc.local to download fonts and establish emulation modes, mine
+ looks like the example provided in Etc/rc.local
+
+
+(16) For FreeBSD 2.0 there is a patch to cons.c necessary, if you don't
+ apply this patch, you don't have a console device; Joerg Wunsch
+ provided this patch:
+
+*** cons.c.orig Mon Oct 31 18:20:14 1994
+--- cons.c Tue Dec 13 16:16:52 1994
+***************
+*** 67,73 ****
+ #endif
+
+ struct consdev constab[] = {
+! #if NSC > 0
+ { pccnprobe, pccninit, pccngetc, pccncheckc, pccnputc },
+ #endif
+ #if NSIO > 0
+--- 67,73 ----
+ #endif
+
+ struct consdev constab[] = {
+! #if NSC > 0 || NVT > 0
+ { pccnprobe, pccninit, pccngetc, pccncheckc, pccnputc },
+ #endif
+ #if NSIO > 0
+
+
+
+good luck !
diff --git a/sys/arch/i386/isa/pcvt/Doc/INSTALL.NetBSD-1.0 b/sys/arch/i386/isa/pcvt/Doc/INSTALL.NetBSD-1.0
new file mode 100644
index 00000000000..81854eeec53
--- /dev/null
+++ b/sys/arch/i386/isa/pcvt/Doc/INSTALL.NetBSD-1.0
@@ -0,0 +1,115 @@
+How to install the pcvt driver on a NetBSD 1.0 machine (pcvt rel. 3.20)
+--------------------------------------------------------------------------------
+ last edit-date: [Thu Jan 5 16:11:17 1995]
+
+
+(1) you have the choice of two keyboard layouts regarding the placement of
+ the vt220 function keys and the HELP and DO keys.
+
+ both configurations are documented in the files Keyboard.HP and Keyboard.VT
+ respectively.
+
+ decide which one to use and set the "#define" of PCVT_VT220KEYB to
+ compile the one you choosed. (see also pcvt_hdr.h and pcvt_kbd.c)
+
+(2) add a line ''option PCVT_NETBSD="100"'' into your kernel config file.
+
+(3) there are several other configuration "#define"-able options located at
+ the beginning of pcvt_conf.h. "user"-settable options all start with
+ "PCVT_". Please (!!!) read the comments for them in the header file !
+
+(4) edit your kernel configuration file and comment the following line out
+ by placing a "#" in front of it:
+
+ device pc0 at isa? port "IO_KBD" tty irq 1
+
+ add a new config-line just below it:
+
+ device vt0 at isa? port "IO_KBD" tty irq 1
+
+ the lines in my config file look like this:
+
+ #device pc0 at isa? port "IO_KBD" tty irq 1
+ device vt0 at isa? port "IO_KBD" tty irq 1
+
+ you can use now either the pccons driver or the pcvt driver (or possibly
+ other console drivers too!) by simply un-commenting ONE of them.
+
+ YOU CANNOT USE/UNCOMMENT MORE THAN __ONE__ CONSOLE DRIVER !!!
+
+(5) configure a new kernel using config(8).
+
+(6) run "make depend" for the new kernel !!!!
+
+ (if you upgrade from a previous version of pcvt, or get unresolved
+ symbols during step 11, it may be necessary to run a "make clean"
+ prior to running "make depend" !!)
+
+(7) compile the new kernel
+
+(8) test the new kernel (i.e. on a floppy) and check whether it still works
+ with your keyboard and your videoboard.
+
+ if the kernel works, install it on your harddisk and reboot.
+
+(9) change into the distribution subdirectory "Util".
+ Edit Makefile.inc to suit your needs, especially have a look at "MANDIR"
+ and "BINDIR". Execute "make depend" and then "make".
+ this makes all the utilities in their directories. when you are satisfied
+ with the results, execute "make install". this installs all programs in
+ all subdirs in "BINDIR" and all manual pages in "MANDIR", all fonts in
+ "FONTDIR" and the keycap database in "CAPDIR".
+
+ change into the distribution subdirectory "Doc" and edit Makefile
+ to suit your needs. then execute "make" to prepare the manpage for
+ the driver.
+
+(10) if necessary, edit /usr/share/misc/keycap to match your keyboard.
+ keycap uses special codes which are documented in Util/kcon/keycap.3
+ and Util/kcon/keycap.5. also have a look at Util/kcon/kcon.1.
+
+(11) there are example termcap entries for the various screen resolutions
+ in the file "Etc/Termcap". integrate them into your termcap file if
+ you don't have a "normal" vt220 entry or want to use pcvt's extensions.
+
+ NOTE: pcvt works with an unmodified VT220 termcap entry !
+ (it was written to do that .... ;-)
+
+ Don't forget to make a new compiled termcap database using cap_mkdb !
+
+(12) to use the virtual terminals, one must "mknod" this devices, they have
+ major number 12 and minor numbers 0 to n:
+
+ mknod /dev/ttyv0 c 12 0
+ mknod /dev/ttyv1 c 12 1
+ mknod /dev/ttyv2 c 12 2
+ mknod /dev/ttyv3 c 12 3
+ ...
+ mknod /dev/ttyv<n> c 12 <n>
+
+ There is a shell-script available (Etc/MAKEDEV.pcvt) for this purpose.
+
+(13) edit /etc/ttys to enable login on the virtual consoles, mine looks like
+ this:
+
+ ttyv0 "/usr/libexec/getty console" pcvt25h on secure
+ ttyv1 "/usr/libexec/getty console" pcvt25h on secure
+ ttyv2 "/usr/libexec/getty console" pcvt25h on secure
+ ttyv3 "/usr/libexec/getty console" pcvt25h on secure
+
+
+(14) because the driver is (mostly) 8-bit clean, the entry to be used with it
+ in /etc/gettytab has to contain a ":np:" (no parity) entry, the "default"
+ entry has a ":ap:" (any parity), if you want to use this entry, you have
+ to change the ":ap:" to ":np:"!
+ my default entry looks like this:
+
+ default:\
+ :np:fd#1000:im=\r\n NetBSD (%h) (%t)\r\n\r\n:sp#9600:
+
+
+(15) edit /etc/rc.local to download fonts and establish emulation modes, mine
+ looks like the example provided in Etc/rc.local
+
+
+good luck !
diff --git a/sys/arch/i386/isa/pcvt/Doc/Keyboard-Layout.HP b/sys/arch/i386/isa/pcvt/Doc/Keyboard-Layout.HP
new file mode 100644
index 00000000000..06ad5b7d3c4
--- /dev/null
+++ b/sys/arch/i386/isa/pcvt/Doc/Keyboard-Layout.HP
@@ -0,0 +1,286 @@
+================================================================================
+# #
+# Function key mapping for the "more HP" - like layout #
+# #
+================================================================================
+
+
+I. Function Key Map
+========================
+
+
+PC | F1 | F2 | F3 | F4 | F5 | F6 | F7 | F8 | F9 | F10 | F11 | F12 |
+Key
+ _________________________________________________________________________
+UNSHF| 132 | Soft| | | | 7/8 | Dspl| Auto| SCRN| SCRN| SCRN| SCRN|
+SYS | Cols|Reset| | | Beep| Bit | Func| Wrap| 0 | 1 | 2 | 3 |
+LABEL|_____|_____|_____|_____|_____|_____|_____|_____|_____|_____|_____|_____|
+UNSHF| | | | | | | | | SCRN| SCRN| SCRN| SCRN|
+USER | F6 | F7 | F8 | F9 | F10 | F11 | F12 | F13 | 0 | 1 | 2 | 3 |
+LABEL|_____|_____|_____|_____|_____|_____|_____|_____|_____|_____|_____|_____|
+ | | | | | | | | | Fkey| U/S |VT/HP| Next|
+ALT | F14 | HELP| DO | F17 | F18 | F19 | F20 | F21 |Label|Label| Mode| SCRN|
+ |_____|_____|_____|_____|_____|_____|_____|_____|_____|_____|_____|_____|
+ | User| User| User| User| User| User| User| User| | | | |
+SHIFT| F6 | F7 | F8 | F9 | F10 | F11 | F12 | F13 | | | | |
+ |_____|_____|_____|_____|_____|_____|_____|_____|_____|_____|_____|_____|
+ALT- | User| User| User| User| User| User| User| User| | | | |
+SHIFT| F14 | F15 | F16 | F17 | F18 | F19 | F20 | F21 | | | | |
+ |_____|_____|_____|_____|_____|_____|_____|_____|_____|_____|_____|_____|
+CTRL-| SCRN| SCRN| SCRN| SCRN| SCRN| SCRN| SCRN| SCRN| SCRN| SCRN| SCRN| SCRN|
+ALT | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 |
+ |_____|_____|_____|_____|_____|_____|_____|_____|_____|_____|_____|_____|
+
+PC | F1 | F2 | F3 | F4 | F5 | F6 | F7 | F8 | F9 | F10 | F11 | F12 |
+Key
+
+
+
+II. Special Keys Used To Change The General Runtime Functionality
+=====================================================================
+
+
+ To be consistent with XFfree86 2.0 Virtual Screen switching, it is
+ now also possible to switch screens by using:
+
+ CTRL - ALT - Fx , where x can be 1 ... No of screens compiled,
+ see the definition of PCVT_NSCREENS !
+
+
+ Virtual Screen/Terminal switching
+ ---------------------------------
+
+ F9 or CTRL-ALT-F1 switches to screen 0
+ F10 or CTRL-ALT-F2 switches to screen 1
+ F11 or CTRL-ALT-F3 switches to screen 2
+ F12 or CTRL-ALT-F4 switches to screen 3
+ CTRL-ALT-F5 switches to screen 4
+ CTRL-ALT-F6 switches to screen 5
+ CTRL-ALT-F7 switches to screen 6
+ CTRL-ALT-F8 switches to screen 7
+ CTRL-ALT-F9 switches to screen 8
+ CTRL-ALT-F10 switches to screen 9
+ CTRL-ALT-F11 switches to screen 10
+ CTRL-ALT-F12 switches to screen 11
+
+ (see also ALT-F12 below)
+
+
+ ALT-F9 Function key labels ON / OFF
+ ------------------------------------
+
+ this key is only operational, when in HP/VT mode, see F11
+
+ ALT-F9 toggles between function key labels displayed or not.
+
+ ON: screen has either 25-3 = 22, 28-3 = 25 or 50-3 = 47 lines
+ 2 lines fkey labels displayed
+ row/col display enabled
+ 1 line status/load avg line
+
+ OFF: screen has either 25-3 = 22, 28-3 = 25 or 50-3 = 47 lines
+ no function key labels displayed
+ no row/col display
+ no status/load avg line
+
+ applicable escape sequences:
+
+ switch OFF:
+ ESC & j @ remove labels from screen
+
+ switch ON:
+ ESC & j A display system fkey labels
+ ESC & j B display user fkey labels
+ ESC & j C display current fkey labels
+
+
+ ALT-F10 User / System Function key labels
+ -----------------------------------------
+
+ this key is only operational, when in HP/VT mode, see ALT-F11
+
+ ALT-F10 toggles between the display of user or system
+ function key labels
+
+ this key is only active if labels are toggled on via
+ the ALT-F9 function key
+
+ screen has either 25-3 = 22, 28-3 = 25 or 50-3 = 47 lines
+ 2 lines fkey labels displayed
+ row/col display enabled
+ 1 line status/load avg line
+
+
+ applicable escape sequences: (see above)
+
+ ESC & j A display system fkey labels
+ ESC & j B display user fkey labels
+ ESC & j C display current fkey labels
+
+
+ ALT-F11 Toggle between pure VT and HP-VT Emulation
+ --------------------------------------------------
+
+ This key switches between pure vt100/vt220 mode and
+ vt100/vt220 with hp-fkey-labels mode of operation.
+ this is not dependent of any screen resolution the
+ virtual consoles are in.
+
+ initially, after power on, all virtual screens are in
+ the pure vt-mode:
+
+ - the emulator does not execute any hp escape sequences
+ - the function key label lines are switched off
+ - no load average or status line is displayed
+ - no row / column counter is displayed
+ - no window number is displayed
+ - the full screen 25x80, 28x80 or 50x80 is usable
+ - ALT-F9 and ALT-F10 have no function
+
+ when toggled to the vt/hp mix of operation, the following
+ changes take place:
+
+ - the emulator executes the supported hp-esc sequences
+ - the function key labels are displayable depending
+ on the state of ALT-F9/F10
+ - the load average is displayed
+ - the row / column counters are displayed
+ - the window number is displayed in the lower right corner
+ - in any screen resolution, the last 3 lines are lost,
+ so one has a 22x80, 25x80 and 47x80 resolution
+ - F9 and F10 are operational.
+
+ when switching modes by means of ALT-F11, the following
+ changes to the current environment, the emulator may
+ be in, apply:
+
+ - the screen is cleared
+ - the cursor moves to the home position
+ - the scrolling region is reset to default
+
+ (this functionality is available via an ioctl)
+
+ ALT-F12 Cycle current screen
+ ----------------------------
+
+ This key cycles through the display of the video
+ screens. on startup, screen 0 is displayed; with every
+ keypress of F12, the next screen is displayed, wrapping
+ from the maximum screen number back to screen 0.
+
+ (this functionality is available via an ioctl)
+
+
+III. Special Keys used to change the Runtime Functionality of a Page
+=======================================================================
+
+ when in mixed HP/VT mode, one has two types of function key labels
+ on screen, user function keys and system function keys.
+
+ this functionality is NOT available in pure VT220 mode !
+
+ the user function keys emit the below mentioned VT220 function-
+ key sequences. the labels can be reprogrammed by use of escape
+ sequences.
+
+ in system function key mode, several pre-programmed functions inside
+ the emulator can be toggled, currently implemented are:
+
+ - F1, if a chipset is detected for which 132 operation is supported,
+ F1 toggles between 80 columns and 132 columns.
+ - F2, does a soft reset of the emulator code
+ - F3, -/-
+ - F4, -/-
+ - F5, toggle the audible beep generation
+ - F6, toggle 7/8 bit char width
+ - F7, toggle display functions. this means that control codes
+ in the range 0x00 to 0x1f are not EXECUTED by the emulator
+ any longer, but displayed on the screen
+ - F8, toggle automatic cursor wraparound at end of line
+
+ these functions operate just for the selected screen
+
+
+IV. Keyboard VT220 compatibility
+====================================
+
+ The following keys behave different as probably expected.
+
+ They were mapped to provide more VT220 compatibility.
+
+ To have F1-F8 emit something in HP-mode, you have to switch
+ to user function key labels by using ALT-F10 (see ALT-F10 above) !
+
+ PC Keyboard VT220 Keyboard
+ ------------- --------------------------------------------------
+ F1 F6 (ESC [ 17 ~)
+ F2 F7 (ESC [ 18 ~)
+ F3 F8 (ESC [ 19 ~)
+ F4 F9 (ESC [ 20 ~)
+ F5 F10 (ESC [ 21 ~)
+ F6 F11 (ESC [ 23 ~)
+ F7 F12 (ESC [ 24 ~)
+ F8 F13 (ESC [ 25 ~)
+ ALT-F1 F14 (ESC [ 26 ~)
+ ALT-F2 HELP (ESC [ 28 ~)
+ ALT-F3 DO (ESC [ 29 ~)
+ ALT-F4 F17 (ESC [ 31 ~)
+ ALT-F5 F18 (ESC [ 32 ~)
+ ALT-F6 F19 (ESC [ 33 ~)
+ ALT-F7 F20 (ESC [ 34 ~)
+ ALT-F8 F21 (ESC [ 35 ~) (i know !!!!)
+
+ SHIFT-F1 ... SHIFT-F8
+ User Defined Keys for F6 - F13
+
+ ALT-SHIFT-F1 ... ALT-SHIFT-F8
+ User Defined Keys for F14 - F20
+
+ Insert Insert Here (ESC [ 2 ~)
+
+ Delete Remove (ESC [ 3 ~)
+
+ Home Find (ESC [ 1 ~)
+
+ End Select (ESC [ 4 ~)
+
+ PgUp Prev Screen (ESC [ 5 ~)
+
+ PgDn Next Screen (ESC [ 6 ~)
+
+ PrtSc (ignored)
+
+ Pause (ignored)
+
+ Break (ignored)
+
+ Cursor Keys dependent upon state of cursor key mode either
+ ESC [ A ... ESC [ D or ESC O A ... ESC O D
+
+ NumLock toggles Numeric Keypad for Keypad Numeric Mode
+ and Keypad Application Mode
+
+ ALT-Keypad-0 can be used to generate any keycode in the
+ ALT-Keypad-1 rage 0-255.
+ ALT-Keypad-2 this was modeled with the behaviour of a
+ ALT-Keypad-3 popular boot loader in mind
+ ALT-Keypad-4
+ ALT-Keypad-5
+ ALT-Keypad-6
+ ALT-Keypad-7
+ ALT-Keypad-8
+ ALT-Keypad-9
+
+ Numeric Keypad dependent upon state of keypad numeric/application
+ mode either 0 ... 9 or ESC O p ... ESC O y
+
+ ALT-NumLock emits PF1 sequence (ESC O P)
+
+ ALT-Keypad-/ emits PF2 sequence (ESC O Q)
+
+ ALT-Keypad-* emits PF3 sequence (ESC O R)
+
+ ALT-Keypad-- emits PF4 sequence (ESC O S)
+
+
+/* EOF */
diff --git a/sys/arch/i386/isa/pcvt/Doc/Keyboard-Layout.VT b/sys/arch/i386/isa/pcvt/Doc/Keyboard-Layout.VT
new file mode 100644
index 00000000000..4353ec7900b
--- /dev/null
+++ b/sys/arch/i386/isa/pcvt/Doc/Keyboard-Layout.VT
@@ -0,0 +1,231 @@
+================================================================================
+# #
+# Function key mapping for the "more VT220" - like layout #
+# #
+================================================================================
+
+
+I. Special Keys Used To Change The General Runtime Functionality
+=====================================================================
+
+
+ CTRL-F9 Function key labels ON / OFF
+ ------------------------------------
+
+ this key is only operational, when in HP/VT mode, see CTRL-F11
+
+ CTRL-F9 toggles between function key labels displayed or not.
+
+ ON: screen has either 25-3 = 22, 28-3 = 25 or 50-3 = 47 lines
+ 2 lines fkey labels displayed
+ row/col display enabled
+ 1 line status/load avg line
+
+ OFF: screen has either 25-3 = 22, 28-3 = 25 or 50-3 = 47 lines
+ no function key labels displayed
+ no row/col display
+ no status/load avg line
+
+ applicable escape sequences:
+
+ switch OFF:
+ ESC & j @ remove labels from screen
+
+ switch ON:
+ ESC & j A display system fkey labels
+ ESC & j B display user fkey labels
+ ESC & j C display current fkey labels
+
+
+ CTRL-F10 User / System Function key labels
+ -------------------------------------------------
+
+ this key is only operational, when in HP/VT mode, see CTRL-F11
+
+ CTRL-F10 toggles between the display of user or system
+ function key labels
+
+ this key is only active if labels are toggled on via
+ the CTRL-F9 function key
+
+ screen has either 25-3 = 22, 28-3 = 25 or 50-3 = 47 lines
+ 2 lines fkey labels displayed
+ row/col display enabled
+ 1 line status/load avg line
+
+
+ applicable escape sequences: (see above)
+
+ ESC & j A display system fkey labels
+ ESC & j B display user fkey labels
+ ESC & j C display current fkey labels
+
+
+ CTRL-F11 Toggle between pure VT and HP-VT Emulation
+ ----------------------------------------------------------
+
+ This key switches between pure vt100/vt220 mode and
+ vt100/vt220 with hp-fkey-labels mode of operation.
+ this is not dependent of any screen resolution the
+ virtual consoles are in.
+
+ initially, after power on, all virtual screens are in
+ the pure vt-mode:
+
+ - the emulator does not execute any hp escape sequences
+ - the function key label lines are switched off
+ - no load average or status line is displayed
+ - no row / column counter is displayed
+ - the full screen 25x80, 28x80 or 50x80 is usable
+ - CTRL-F9 and CTRL-F10 have no function
+
+ when toggled to the vt/hp mix of operation, the following
+ changes take place:
+
+ - the emulator executes the supported hp-esc sequences
+ - the function key labels are displayable depending
+ on the state of CTRL-F9/CTRL-F10
+ - the load average is displayed
+ - the row / column counters are displayed
+ - in any screen resolution, the last 3 lines are lost,
+ so one has a 22x80, 25x80 and 47x80 resolution
+ - CTRL-F9 and CTRL-F10 are operational.
+
+ when switching modes by means of CTRL-F11, the following
+ changes to the current environment, the emulator may
+ be in, apply:
+
+ - the screen is cleared
+ - the cursor moves to the home position
+ - the scrolling region is reset to default
+
+ (this functionality is available via an ioctl)
+
+ F5 Cycle current page
+ --------------------------
+
+ This key cycles through the display of the video
+ pages. on startup, page 0 is displayed; with every
+ keypress of F5, the next page is displayed, wrapping
+ from the maximum page number back to page 0.
+
+ F1 switches to page 0
+ F2 switches to page 1
+ F3 switches to page 2
+ F4 switches to page 3
+
+ Shift-F1 -- select screen 4
+ Shift-F2 -- select screen 5
+ Shift-F3 -- select screen 6
+ Shift-F4 -- select screen 7
+ Shift-F5 -- select (current screen - 1)
+
+ (this functionality is available via an ioctl)
+
+
+II. Special Keys used to change the Runtime Functionality of a Page
+=======================================================================
+
+ when in mixed HP/VT mode, one has two types of function key labels
+ on screen, user function keys and system function keys. they are
+ accessed by using the CTRL key while pressing a function key.
+
+ the function key labels are NOT available in pure VT220 mode--although
+ the function keys are still active
+
+ the user function keys and their labels can be reprogrammed by use of
+ escape sequences.
+
+ in system function key mode, several pre-programmed functions inside
+ the emulator can be toggled, currently implemented are:
+
+ - CTRL-F1, toggle 80/132 columns
+ - CTRL-F2, soft reset emulator
+ - CTRL-F3, toggle force 24 lines mode
+ - CTRL-F4, toggle keyboard debugging (if compiled in)
+ - CTRL-F5, toggle the audible beep generation
+ - CTRL-F6, toggle 7/8 bit char width
+ - CTRL-F7, toggle display functions. this means that control codes
+ in the range 0x00 to 0x1f are not EXECUTED by the emulator
+ any longer, but displayed on the screen
+ - CTRL-F8, toggle automatic cursor wraparound at end of line
+
+ these functions operate just for the selected page
+
+
+III. Keyboard VT220 compatibility
+====================================
+
+ The following keys behave different as probably expected.
+
+ They were mapped to provide more VT220 compatibility.
+
+
+ PC Keyboard VT220 Keyboard
+ ------------- --------------------------------------------------
+ F6 - F12 emit the sequences for VT220 F6 - F12 keys
+ (ESC [ 17 ~ .... ESC [ 24 ~)
+
+ ALT F1 - F10 emit the sequences for VT220 F11 - F14, HELP, DO,
+ F17 - F20 keys
+ (ESC [ 23 ~ .... ESC [ 34 ~)
+
+ SHIFT F6 - F12 emit the User Definable Key sequences for VT220
+ F6 - F12 keys or
+ (ESC [ 17 ~ .... ESC [ 24 ~) for cleared sequences
+
+ ALTSHIFT F1-F10 emit the User Definable Key sequences for VT220
+ F11 - F14, HELP, DO, F17 - F20 keys or
+ (ESC [ 23 ~ .... ESC [ 34 ~) for cleared sequences
+
+ Insert Insert Here (ESC [ 2 ~)
+
+ Delete Remove (ESC [ 3 ~)
+
+ Home Find (ESC [ 1 ~)
+
+ End Select (ESC [ 4 ~)
+
+ PgUp Prev Screen (ESC [ 5 ~)
+
+ PgDn Next Screen (ESC [ 6 ~)
+
+ PrtSc (ignored)
+
+ Pause (ignored)
+
+ Break (ignored)
+
+ Cursor Keys dependent upon state of cursor key mode either
+ ESC [ A ... ESC [ D or ESC O A ... ESC O D
+
+ NumLock toggles Numeric Keypad for Keypad Numeric Mode
+ and Keypad Application Mode
+
+ ALT-Keypad-0 can be used to generate any keycode in the
+ ALT-Keypad-1 rage 0-255.
+ ALT-Keypad-2 this was modeled with the behaviour of a
+ ALT-Keypad-3 popular boot loader in mind
+ ALT-Keypad-4
+ ALT-Keypad-5
+ ALT-Keypad-6
+ ALT-Keypad-7
+ ALT-Keypad-8
+ ALT-Keypad-9
+
+ Numeric Keypad dependent upon state of keypad numeric/application
+ mode either 0 ... 9 or ESC O p ... ESC O y
+
+ ALT-NumLock emits PF1 sequence (ESC O P)
+
+ ALT-Keypad-/ emits PF2 sequence (ESC O Q)
+
+ ALT-Keypad-* emits PF3 sequence (ESC O R)
+
+ ALT-Keypad-- emits PF4 sequence (ESC O S)
+
+ ALT-F11 emits PF1 sequence (ESC O P)
+
+ ALT-F12 emits PF2 sequence (ESC O Q)
+
+/* EOF */
diff --git a/sys/arch/i386/isa/pcvt/Doc/Manifest b/sys/arch/i386/isa/pcvt/Doc/Manifest
new file mode 100644
index 00000000000..af22c8edea7
--- /dev/null
+++ b/sys/arch/i386/isa/pcvt/Doc/Manifest
@@ -0,0 +1,170 @@
+
+FILES AND DIRECTORIES - Base Directory [pcvt Release 3.31]
+--------------------------------------------------------------------------------
+
+Doc Documentation, see below
+Etc Additional things, see below
+README.FIRST guess what
+Util Additional utilities and support, see below
+
+Driversource Description
+------------ --------------------------------------------------------
+pcvt_conf.h Driver, compile-time configuration file
+pcvt_drv.c Driver, os-interface
+pcvt_ext.c Driver, USL-VT Xserver ioctl's and 132 column support
+pcvt_hdr.h Driver, global include file
+pcvt_ioctl.h Driver, ioctl's available for the driver
+pcvt_kbd.c Driver, keyboard handling
+pcvt_kbd.h Driver, keyboard handling header file
+pcvt_out.c Driver, VT220 emulator state machine and misc
+pcvt_sup.c Driver, support code for ega's/vga's
+pcvt_tbl.h Driver, character set to vga charset mapping tables
+pcvt_vtf.c Driver, VT220 emulator support functions
+
+FILES AND DIRECTORIES - Doc
+--------------------------------------------------------------------------------
+
+Acknowledgements Everyone and everything who/what helped
+Bibliography Useful Books and documentation
+BugList Things to do
+ChangeLog Driver development history
+CharGen Description of the character set files
+Charsets VT220 and mda/cga/hcs/ega/vga charactersets
+EscapeSequences List of supported control codes & escape sequences
+INSTALL.FreeBSD-2.0 Install instructions for FreeBSD Release 2.0
+INSTALL.NetBSD-1.0 Install instructions for NetBSD Release 1.0
+Keyboard-Layout.HP Special keys and emulated VT220 keys, one style
+Keyboard-Layout.VT Special keys and emulated VT220 keys, other style
+Manifest This file
+FAQ FAQ's, notes and hints to get pcvt up and running
+TestedHardware A list of tested Hardware, this is just what we got ...
+ToDo A list of things to do
+
+
+FILES AND DIRECTORIES - Etc
+--------------------------------------------------------------------------------
+
+MAKEDEV.pcvt A shell script to mknod the device files
+Termcap A termcap entry for the emulator, this IS in fact
+ a series of VT220 termcap entries which
+ are extended by 24/25/40/50 lines, 80/132
+ columns and HP-function key labels
+Terminfo A terminfo entry for the emulator, this IS in
+ fact a VT220 terminfo entry !
+pcvt.el GNU emacs configuration
+rc.local sample script for driver initialization
+ttys.pcvt.netbsd sample /etc/ttys.pcvt for NetBSD
+ttys.pcvt.freebsd sample /etc/ttys.pcvt for FreeBSD
+uemacs.tar.Z.uu an example of how to use the function key labels.
+ It consists of some files from/for MicroEmacs 3.11a:
+ - dot-emacsrc, to be moved to /usr/local/.emacsrc,
+ startup file for micro emacs, contains setup of
+ the function key labels
+ - emacs.hlp, interactive uemacs help system
+ - unix.c-3.11a the source for the terminal handling
+xmodmap-german X-server german keyboard mapping sample
+
+
+FILES AND DIRECTORIES - Util
+--------------------------------------------------------------------------------
+
+Makefile main makefile for all systems
+Makefile.inc.FreeBSD1 Makefile.inc for FreeBSD 1.x
+Makefile.inc.FreeBSD2 Makefile.inc for FreeBSD 2.0.5 and higher
+Makefile.inc.NetBSD Makefile.inc for NetBSD 1.0 and lower
+Makefile.inc.NetBSD-current Makefile.inc for NetBSD post 1.0
+
+
+directory description
+--------- ---------------------------------------------------------------
+
+cursor Very simple program to set the cursor shape.
+
+demo Files demonstrating pcvts capabilities:
+ - chardemo.vt and colors.vt: These two files are from the
+ MSDOS-Kermit distribution from the Columbia University.
+ They can be "cat"-ed to the terminal screen and display
+ all supported VT220 charactersets and all possible colors
+ respectively.
+ - sgr.vt: A demonstration of the various display enhancement
+ combinations for the DECSGR escape sequence.
+ - some other VT animations i collected over the time and a
+ program to play them on pcvt with adjustable delay.
+
+fed A simple, System V (n)curses based font-editor for the EGA/VGA
+ fonts in the below mentioned font - directory.
+
+fontedit A program to edit VT220 downloadable character sets.
+
+fonts Contains uuencoded binary fontfiles following the naming rule:
+
+ vt220<X>.<YYY>.uu
+
+ <X> can be 'l' or 'h', where 'l' stands for a standard
+ IBM II charset and is to be loaded first for the
+ base characterset to support a desired resolution,
+ and 'h' is the extended characterset needed for proper
+ VT220 emulation and is to be loaded as the second set
+ in addition to the above mentioned base characterset.
+
+ <YYY> is the identifier for the character cell size, currently
+ we have:
+ 808 = 8x8 - 50 lines on VGA, 43 lines on EGA
+ 810 = 8x10 - 40 lines on VGA
+ 814 = 8x14 - 28 lines on VGA, 25 lines on EGA
+ 816 = 8x16 - 25 lines on VGA
+
+ Files distributed:
+
+ vt220l.808.uu, vt220h.808.uu
+ vt220l.810.uu, vt220h.810.uu
+ vt220l.814.uu, vt220h.814.uu
+ vt220l.816.uu, vt220h.816.uu
+
+ispcvt A short program usable in shell scripts to verify that the
+ current running kernel has pcvt compiled in and that the
+ the utility version and the driver version are the same,
+ also used to display all compile-time options.
+
+kbdio Keyboard controller debugging utility
+
+kcon Program to control various aspects of the keyboard such as
+ key remapping for national keyboards etc.
+
+keycap A library for accessing the keycap database
+
+loadfont Program to download charactersets into EGA/VGA character
+ generator memory.
+
+mcon A program to control the mouse emulation via the keyboard
+
+pcvtdoc Makefile and manual page for the driver and ioctl's
+
+scon Program to control various aspects of terminal emulation,
+ such as: emulation mode, screen switching etc.
+
+set2061 A program to set the programmable clock generator on my S3-
+ based ELSA Winner 1000 VGA board.
+ ---------------------- CAUTION ------------------------------
+ Because you are able to change the timings without check
+ or warning, this program may permanently damage your monitor.
+ If you don't know what you are doing, DO NOT USE IT !!!!!!!!!
+ -------------------------------------------------------------
+
+userkeys A program to edit the VT220 programmable function keys.
+
+vgaio A program to read and write VGA registers.
+ ---------------------- CAUTION ------------------------------
+ Because you are able to change the timings without check
+ or warning, this program may permanently damage your monitor.
+ If you don't know what you are doing, DO NOT USE IT !!!!!!!!!
+ -------------------------------------------------------------
+
+
+vttest A VT100 compatibility tester. This is a test tool for
+ VT100 emulation writers and terminal buyers.
+
+
+
+
+
diff --git a/sys/arch/i386/isa/pcvt/Doc/TestedHardware b/sys/arch/i386/isa/pcvt/Doc/TestedHardware
new file mode 100644
index 00000000000..3a1bc01dc87
--- /dev/null
+++ b/sys/arch/i386/isa/pcvt/Doc/TestedHardware
@@ -0,0 +1,80 @@
+Tested Hardware List last edit-date: [Sat Jun 24 14:50:46 1995]
+
+This is by no means a complete list of hardware pcvt runs on, it is just
+compiled from reports people sent in and from hardware owned/loaned !
+
+
+TESTED VIDEO BOARDS (80 column operation)
+--------------------------------------------------------------------------------
+
+Manufacturer Chipset Monitor Notes
+------------------------------ -------------- ---------------------- --------
+2theMax (?) ET4000 VGA Color
+Video7 Inc. VEGA VGA VGA Color/Mono (2)
+Diamond Stealth VRAM S3 NEC 3FGx
+Trident TVGA 8800CS NEC 3D
+Trident TVGA 9000B VGA Color/Mono (2)
+Data General C&T P82C604 VGA Color
+NoName Hercules W86855AF Mono
+Tandon Monochrome (Hercules) TD3088A Tandon Mono
+Kyocera ML III25 (Mainboard) WD90C00 JVC VGA Color (1)
+Kyocera ML III25 (Mainboard) WD90C00 Nokia CED1 VGA Mono (1)
+Kyocera ML IIII33 (Mainboard) WD90C11 Nokia CED1 VGA Mono (1)
+NoName VGA TVGA9000B JVC VGA Color (1,2)
+Tseng Labs ET3000AX JVC VGA Color (2)
+Video7 Inc. VEGA VGA VGA Mono (2)
+Video7 Inc. 1024i VGA Mono (2)
+ELSA GmbH S3 928 VGA Mono/Color
+IBM EGA 6845 Monochrome (2,3)
+IBM EGA 6845 Tandon EGA Color (2,3)
+Trident TVGA 8900CL VGA Mono (2)
+
+Notes:
+(1) - slight display distortion when switching between screens
+(2) - remarkable display distortion and/or loss of sync while loading fonts
+(3) - snow while scrolling with HP function key labels turned on
+
+TESTED VIDEO BOARDS (132 column operation)
+--------------------------------------------------------------------------------
+
+Manufacturer Chipset Monitor Notes
+------------------------------ -------------- ---------------------- --------
+2theMax (?) ET4000 VGA Color
+2theMax (?) ET4000 Tandon VGA Mono
+Kyocera ML III33 (Mainboard) WD90C11 Tandon VGA Mono (1,2)
+Kyocera ML IIII33 (Mainboard) WD90C11 Tandon VGA Mono (1,2)
+Kyocera ML IIII33 (Mainboard) WD90C11 VGA Color (1,2)
+Trident (?) TVGA9000B VGA Mono (1,3)
+Tseng Labs (?) ET3000 NEC 3D
+ELSA GmbH S3 928 VGA Mono/Color
+Trident TVGA 8900CL VGA Mono
+HP Vectra VE 5/75 Motherbd CL-GD5430 MAG
+
+Notes:
+(1) - slight display distortion when switching between screens
+(2) - all fonts must be loaded in ascending order prior to switching to 132 cols
+(3) - remarkable display distortion and/or loss of sync while loading fonts
+
+
+TESTED KEYBOARDS
+--------------------------------------------------------------------------------
+
+Manufacturer Type Layout
+------------------------------ ---------------------- ------------------------
+Cherry MF II US
+Cherry/Tandon MF II German
+Hewlett-Packard MF II US
+Hewlett-Packard MF II German
+Tatung AT German
+Kyocera MF II German
+
+There is absolutely NO support for the ancient PC-keyboards (they had 83 keys).
+
+There is only limited support for AT-keyboards (they have 84 keys, and a
+separate numeric keypad, they don't have F9-F12 keys) because the emulator
+needs F9-F12 for control functions, and due to the current design of the
+keyboard driver there is no (full) support for national keyboards because
+of the lack of a ALTGR key.
+
+MF-keyboards are fully supported, 101- and 102-key versions.
+
diff --git a/sys/arch/i386/isa/pcvt/Doc/ToDo b/sys/arch/i386/isa/pcvt/Doc/ToDo
new file mode 100644
index 00000000000..91bf5fd1d7d
--- /dev/null
+++ b/sys/arch/i386/isa/pcvt/Doc/ToDo
@@ -0,0 +1,15 @@
+
+Things to do Last Edit-Date: [Tue Sep 5 18:47:12 1995]
+================================================================================
+
+- implement secondary DA request: ESC [ > c and/or ESC [ > 0 c
+
+- implement user settable primary DA response and secondary DA response
+
+- retrying for a non-connected keyboard in doreset() must be made cpu and
+ speed independent. in case of a not connected keyboard, a fast machine
+ runs doreset() fast and a slow machine runs doreset() slow - bad !!
+
+- remove support for FreeBSD < 1.1.5.1 and NetBSD <= 0.9
+
+- rewrite the whole thing ....
diff --git a/sys/arch/i386/isa/pcvt/Etc/MAKEDEV.pcvt b/sys/arch/i386/isa/pcvt/Etc/MAKEDEV.pcvt
new file mode 100644
index 00000000000..a16dffc99d1
--- /dev/null
+++ b/sys/arch/i386/isa/pcvt/Etc/MAKEDEV.pcvt
@@ -0,0 +1,16 @@
+#!/bin/sh -
+#
+
+PATH=/sbin:/bin/:/usr/bin:/usr/sbin:
+umask 77
+for i
+do
+case $i in
+
+ttyv*)
+ unit=`expr $i : 'ttyv\(.*\)'`
+ rm -f /dev/ttyv$unit
+ mknod /dev/ttyv$unit c 12 $unit
+ ;;
+esac
+done
diff --git a/sys/arch/i386/isa/pcvt/Etc/Termcap b/sys/arch/i386/isa/pcvt/Etc/Termcap
new file mode 100644
index 00000000000..aa50c9f1283
--- /dev/null
+++ b/sys/arch/i386/isa/pcvt/Etc/Termcap
@@ -0,0 +1,287 @@
+#---------------------------------------------------------------------------
+#
+# pcvt termcap database entry (release 3.31)
+#
+# last edit-date: [Fri Sep 15 20:29:10 1995]
+#
+# -hm new entries for SR and SF
+# -hm removing duplicate entries
+# -hm changed: ae, as, do added: ac, nw, ta deleted: pb
+#
+#---------------------------------------------------------------------------
+
+#---------------------------------------------------------------------------
+# NetBSD/FreeBSD vt220 terminal emulator console (pc keyboard & monitor)
+# termcap entries for pure VT220-Emulation and 25, 28, 35, 40, 43 and
+# 50 lines entries
+# 80 columns
+#---------------------------------------------------------------------------
+pcvt25|dec vt220 with 25 lines:\
+ :li#25:\
+ :co#80:\
+ :is=\E>\E[?3l\E[?4l\E[?5l\E[?7h\E[?8h\E[1;25r\E[25;1H:\
+ :tc=pcvtXX:
+
+pcvt28|dec vt220 with 28 lines:\
+ :li#28:\
+ :co#80:\
+ :is=\E>\E[?3l\E[?4l\E[?5l\E[?7h\E[?8h\E[1;28r\E[28;1H:\
+ :tc=pcvtXX:
+
+pcvt35|dec vt220 with 35 lines:\
+ :li#35:\
+ :co#80:\
+ :is=\E>\E[?3l\E[?4l\E[?5l\E[?7h\E[?8h\E[1;35r\E[35;1H:\
+ :tc=pcvtXX:
+
+pcvt40|dec vt220 with 40 lines:\
+ :li#40:\
+ :co#80:\
+ :is=\E>\E[?3l\E[?4l\E[?5l\E[?7h\E[?8h\E[1;40r\E[40;1H:\
+ :tc=pcvtXX:
+
+pcvt43|dec vt220 with 43 lines:\
+ :li#43:\
+ :co#80:\
+ :is=\E>\E[?3l\E[?4l\E[?5l\E[?7h\E[?8h\E[1;43r\E[43;1H:\
+ :tc=pcvtXX:
+
+pcvt50|dec vt220 with 50 lines:\
+ :li#50:\
+ :co#80:\
+ :is=\E>\E[?3l\E[?4l\E[?5l\E[?7h\E[?8h\E[1;50r\E[50;1H:\
+ :tc=pcvtXX:
+
+#---------------------------------------------------------------------------
+# NetBSD/FreeBSD vt220 terminal emulator console (pc keyboard & monitor)
+# termcap entries for pure VT220-Emulation and 25, 28, 35, 40, 43 and
+# 50 lines entries
+# 132 columns
+#---------------------------------------------------------------------------
+pcvt25w|dec vt220 with 25 lines and 132 cols:\
+ :li#25:\
+ :co#132:\
+ :is=\E>\E[?3l\E[?4l\E[?5l\E[?7h\E[?8h\E[1;25r\E[25;1H:\
+ :tc=pcvtXX:
+
+pcvt28w|dec vt220 with 28 lines and 132 cols:\
+ :li#28:\
+ :co#132:\
+ :is=\E>\E[?3l\E[?4l\E[?5l\E[?7h\E[?8h\E[1;28r\E[28;1H:\
+ :tc=pcvtXX:
+
+pcvt35w|dec vt220 with 35 lines and 132 cols:\
+ :li#35:\
+ :co#132:\
+ :is=\E>\E[?3l\E[?4l\E[?5l\E[?7h\E[?8h\E[1;35r\E[35;1H:\
+ :tc=pcvtXX:
+
+pcvt40w|dec vt220 with 40 lines and 132 cols:\
+ :li#40:\
+ :co#132:\
+ :is=\E>\E[?3l\E[?4l\E[?5l\E[?7h\E[?8h\E[1;40r\E[40;1H:\
+ :tc=pcvtXX:
+
+pcvt43w|dec vt220 with 43 lines and 132 cols:\
+ :li#43:\
+ :co#132:\
+ :is=\E>\E[?3l\E[?4l\E[?5l\E[?7h\E[?8h\E[1;43r\E[43;1H:\
+ :tc=pcvtXX:
+
+pcvt50w|dec vt220 with 50 lines and 132 cols:\
+ :li#50:\
+ :co#132:\
+ :is=\E>\E[?3l\E[?4l\E[?5l\E[?7h\E[?8h\E[1;50r\E[50;1H:\
+ :tc=pcvtXX:
+
+#---------------------------------------------------------------------------
+# NetBSD/FreeBSD vt220 terminal emulator console (pc keyboard & monitor)
+# termcap entries for HP-Emulation and 25, 28, 35, 40, 43 and 50
+# lines entries. note that the HP-Emulation uses the bottom 3 lines
+# for status and function key labels, so we get always 3 lines less.
+# "Xs" is a nonstandard, private flag indicating HP-like fkey labels
+# 80 column entries
+#---------------------------------------------------------------------------
+pcvt22h|dec vt220 with HP-fkey labels and 22 lines:\
+ :li#22:\
+ :co#80:\
+ :Xs:\
+ :is=\E>\E[?3l\E[?4l\E[?5l\E[?7h\E[?8h\E[1;22r\E[22;1H:\
+ :tc=pcvtXX:
+
+pcvt25h|dec vt220 with HP-fkey labels and 25 lines:\
+ :li#25:\
+ :co#80:\
+ :Xs:\
+ :is=\E>\E[?3l\E[?4l\E[?5l\E[?7h\E[?8h\E[1;25r\E[25;1H:\
+ :tc=pcvtXX:
+
+pcvt32h|dec vt220 with HP-fkey labels and 32 lines:\
+ :li#32:\
+ :co#80:\
+ :Xs:\
+ :is=\E>\E[?3l\E[?4l\E[?5l\E[?7h\E[?8h\E[1;32r\E[32;1H:\
+ :tc=pcvtXX:
+
+pcvt37h|dec vt220 with HP-fkey labels and 37 lines:\
+ :li#37:\
+ :co#80:\
+ :Xs:\
+ :is=\E>\E[?3l\E[?4l\E[?5l\E[?7h\E[?8h\E[1;37r\E[37;1H:\
+ :tc=pcvtXX:
+
+pcvt40h|dec vt220 with HP-fkey labels and 40 lines:\
+ :li#40:\
+ :co#80:\
+ :Xs:\
+ :is=\E>\E[?3l\E[?4l\E[?5l\E[?7h\E[?8h\E[1;40r\E[40;1H:\
+ :tc=pcvtXX:
+
+pcvt47h|dec vt220 with HP-fkey labels and 47 lines:\
+ :li#47:\
+ :co#80:\
+ :Xs:\
+ :is=\E>\E[?3l\E[?4l\E[?5l\E[?7h\E[?8h\E[1;47r\E[47;1H:\
+ :tc=pcvtXX:
+
+#---------------------------------------------------------------------------
+# NetBSD/FreeBSD vt220 terminal emulator console (pc keyboard & monitor)
+# termcap entries for HP-Emulation and 25, 28, 35, 40, 43 and 50
+# lines entries. note that the HP-Emulation uses the bottom 3 lines
+# for status and function key labels, so we get always 3 lines less.
+# "Xs" is a nonstandard, private flag indicating HP-like fkey labels
+# 132 column entries
+#---------------------------------------------------------------------------
+pcvt22hw|dec vt220 with HP-fkey labels, 22 lines and 132 cols:\
+ :li#22:\
+ :co#132:\
+ :Xs:\
+ :is=\E>\E[?3l\E[?4l\E[?5l\E[?7h\E[?8h\E[1;22r\E[22;1H:\
+ :tc=pcvtXX:
+
+pcvt25hw|dec vt220 with HP-fkey labels, 25 lines and 132 cols:\
+ :li#25:\
+ :co#132:\
+ :Xs:\
+ :is=\E>\E[?3l\E[?4l\E[?5l\E[?7h\E[?8h\E[1;25r\E[25;1H:\
+ :tc=pcvtXX:
+
+pcvt32hw|dec vt220 with HP-fkey labels, 32 lines and 132 cols:\
+ :li#32:\
+ :co#132:\
+ :Xs:\
+ :is=\E>\E[?3l\E[?4l\E[?5l\E[?7h\E[?8h\E[1;32r\E[32;1H:\
+ :tc=pcvtXX:
+
+pcvt37hw|dec vt220 with HP-fkey labels, 37 lines and 132 cols:\
+ :li#37:\
+ :co#132:\
+ :Xs:\
+ :is=\E>\E[?3l\E[?4l\E[?5l\E[?7h\E[?8h\E[1;37r\E[37;1H:\
+ :tc=pcvtXX:
+
+pcvt40hw|dec vt220 with HP-fkey labels, 40 lines and 132 cols:\
+ :li#40:\
+ :co#132:\
+ :Xs:\
+ :is=\E>\E[?3l\E[?4l\E[?5l\E[?7h\E[?8h\E[1;40r\E[40;1H:\
+ :tc=pcvtXX:
+
+pcvt47hw|dec vt220 with HP-fkey labels, 47 lines and 132 cols:\
+ :li#47:\
+ :co#132:\
+ :Xs:\
+ :is=\E>\E[?3l\E[?4l\E[?5l\E[?7h\E[?8h\E[1;47r\E[47;1H:\
+ :tc=pcvtXX:
+
+#---------------------------------------------------------------------------
+# main entry, without "is" and "li" capabilities
+#
+# NOTE: because the 386BSD "vi"/"elvis" seems to have a bug if
+# both "ic" and "im" are specified (an original VT220
+# shows the same buggy behaviour!), "ic" has been taken
+# out of this entry. for reference, it should be "ic=\E[@".
+#
+#---------------------------------------------------------------------------
+pcvtXX|pcvt vt200 emulator (DEC VT220):\
+ :AL=\E[%dL:\
+ :DC=\E[%dP:\
+ :DL=\E[%dM:\
+ :DO=\E[%dB:\
+ :IC=\E[%d@:\
+ :LE=\E[%dD:\
+ :RI=\E[%dC:\
+ :SF=\E[%dS:\
+ :SR=\E[%dT:\
+ :UP=\E[%dA:\
+ :ac=llmmkkjjuuttvvwwqqxxnnoosspprr\140\140aaffgg~~..--++\054\054hhII00yyzz:\
+ :ae=\E(B:\
+ :al=\E[L:\
+ :am:\
+ :as=\E(0:\
+ :bl=^G:\
+ :bs:\
+ :cb=\E[1K:\
+ :cd=\E[J:\
+ :ce=\E[K:\
+ :cl=\E[H\E[J:\
+ :cm=\E[%i%d;%dH:\
+ :cr=^M:\
+ :cs=\E[%i%d;%dr:\
+ :ct=\E[3g:\
+ :dc=\E[P:\
+ :dl=\E[M:\
+ :do=\E[B:\
+ :ei=\E[4l:\
+ :ho=\E[H:\
+ :im=\E[4h:\
+ :it#8:\
+ :k1=\E[17~:\
+ :k2=\E[18~:\
+ :k3=\E[19~:\
+ :k4=\E[20~:\
+ :k5=\E[21~:\
+ :k6=\E[23~:\
+ :k7=\E[24~:\
+ :k8=\E[25~:\
+ :kD=\E[3~:\
+ :kH=\E[4~:\
+ :kI=\E[2~:\
+ :kN=\E[6~:\
+ :kP=\E[5~:\
+ :kb=\177:\
+ :kd=\EOB:\
+ :ke=\E[?1l\E>:\
+ :kh=\E[1~:\
+ :kl=\EOD:\
+ :km:\
+ :kr=\EOC:\
+ :ks=\E[?1h\E=:\
+ :ku=\EOA:\
+ :le=^H:\
+ :mb=\E[5m:\
+ :md=\E[1m:\
+ :me=\E[m:\
+ :mi:\
+ :mr=\E[7m:\
+ :ms:\
+ :nd=\E[C:\
+ :nw=\EE:\
+ :pt:\
+ :rc=\E8:\
+ :rf=/usr/share/tabset/vt100:\
+ :rs=\Ec\E>\E[?3l\E[?4l\E[?5l\E[?7h\E[?8h:\
+ :sc=\E7:\
+ :se=\E[27m:\
+ :sf=\ED:\
+ :so=\E[7m:\
+ :sr=\EM:\
+ :st=\EH:\
+ :ta=^I:\
+ :ue=\E[24m:\
+ :up=\E[A:\
+ :us=\E[4m:\
+ :vt#3:\
+ :xn:
+
+#---------------------------- E O F -------------------------------------------
diff --git a/sys/arch/i386/isa/pcvt/Etc/Terminfo b/sys/arch/i386/isa/pcvt/Etc/Terminfo
new file mode 100644
index 00000000000..072f885aacb
--- /dev/null
+++ b/sys/arch/i386/isa/pcvt/Etc/Terminfo
@@ -0,0 +1,41 @@
+pcvt25h|pcvt vt220 emulator video driver 80 cols,
+ lines#25, cols#80,
+ am, bel=^G, blink=^[[5m, bold=^[[1m, clear=^[[H^[[J,
+ cr=^M, csr=^[[%i%p1%d;%p2%dr, cub1=^H, cub=^[[%p1%dD, cud1=^J,
+ cud=^[[%p1%dB, cuf1=^[[C, cuf=^[[%p1%dC, cup=^[[%i%p1%d;%p2%dH,
+ cuu1=^[[A, cuu=^[[%p1%dA, dch1=^[[P, dch=^[[%p1%dP, dl1=^[[M,
+ dl=^[[%p1%dM, ed=^[[J, el=^[[K, home=^[[H, ht=^I, hts=^[H,
+ ich1=^[[@, ich=^[[%p1%d@, il1=^[[L, il=^[[%p1%dL, ind=^[D,
+ indn=^[%p1%dD, is1=^[>^[[?3l^[[?4l^[[?5l^[[?7h^[[?8h^[[1;25r^[[25;1H,
+ it#8, kbs=^?, kcub1=^[OD, kcud1=^[OB, kcuf1=^[OC, kcuu1=^[OA,
+ kdch1=^[[3~, kf1=^[[17~, kf2=^[[18~, kf3=^[[19~, kf4=^[[20~,
+ kf5=^[[21~, kf6=^[[23~, kf7=^[[24~, kf8=^[[25~, khome=^[[1~,
+ kich1=^[[2~, kll=^[[4~, km, knp=^[[6~, kpp=^[[5~,
+ mir, msgr, nel=^M^J, pb#16000000, rc=^[8, rev=^[[7m,
+ rf=/usr/share/tabset/vt100, ri=^[M, rin=^[%p1%dM, rmacs=^O,
+ rmir=^[[4l, rmkx=^[[?1l^[>, rmso=^[[27m, rmul=^[[24m,
+ rs1=^[c^[>^[[?3l^[[?4l^[[?5l^[[?7h^[[?8h, sc=^[7, sgr0=^[[m,
+ smacs=^N, smir=^[[4h, smkx=^[[?1h^[=, smso=^[[7m, smul=^[[4m,
+ tbc=^[[3g, vt#3, xenl, colors#8, pairs#64, setf=\E[%p1%{30}%+%dm,
+ setb=\E[%p1%{40}%+%dm,
+
+pcvt25hw|pcvt vt220 emulator video driver 132 cols,
+ lines#25, cols#132,
+ am, bel=^G, blink=^[[5m, bold=^[[1m, clear=^[[H^[[J,
+ cr=^M, csr=^[[%i%p1%d;%p2%dr, cub1=^H, cub=^[[%p1%dD, cud1=^J,
+ cud=^[[%p1%dB, cuf1=^[[C, cuf=^[[%p1%dC, cup=^[[%i%p1%d;%p2%dH,
+ cuu1=^[[A, cuu=^[[%p1%dA, dch1=^[[P, dch=^[[%p1%dP, dl1=^[[M,
+ dl=^[[%p1%dM, ed=^[[J, el=^[[K, home=^[[H, ht=^I, hts=^[H,
+ ich1=^[[@, ich=^[[%p1%d@, il1=^[[L, il=^[[%p1%dL, ind=^[D,
+ indn=^[%p1%dD, is1=^[>^[[?3l^[[?4l^[[?5l^[[?7h^[[?8h^[[1;25r^[[25;1H,
+ it#8, kbs=^?, kcub1=^[OD, kcud1=^[OB, kcuf1=^[OC, kcuu1=^[OA,
+ kdch1=^[[3~, kf1=^[[17~, kf2=^[[18~, kf3=^[[19~, kf4=^[[20~,
+ kf5=^[[21~, kf6=^[[23~, kf7=^[[24~, kf8=^[[25~, khome=^[[1~,
+ kich1=^[[2~, kll=^[[4~, km, knp=^[[6~, kpp=^[[5~,
+ mir, msgr, nel=^M^J, pb#16000000, rc=^[8, rev=^[[7m,
+ rf=/usr/share/tabset/vt100, ri=^[M, rin=^[%p1%dM, rmacs=^O,
+ rmir=^[[4l, rmkx=^[[?1l^[>, rmso=^[[27m, rmul=^[[24m,
+ rs1=^[c^[>^[[?3l^[[?4l^[[?5l^[[?7h^[[?8h, sc=^[7, sgr0=^[[m,
+ smacs=^N, smir=^[[4h, smkx=^[[?1h^[=, smso=^[[7m, smul=^[[4m,
+ tbc=^[[3g, vt#3, xenl, colors#8, pairs#64, setf=\E[%p1%{30}%+%dm,
+ setb=\E[%p1%{40}%+%dm,
diff --git a/sys/arch/i386/isa/pcvt/Etc/pcvt.el b/sys/arch/i386/isa/pcvt/Etc/pcvt.el
new file mode 100644
index 00000000000..bd6484f9dfb
--- /dev/null
+++ b/sys/arch/i386/isa/pcvt/Etc/pcvt.el
@@ -0,0 +1,19 @@
+;; pcvt25.el, by J"org Wunsch <joerg_wunsch@uriah.sax.de>
+;;
+;; pcvt is a good VT emulator
+
+(load "term/vt220")
+
+;; ...but i don't like `find' and `select' on `home' and `end' keys
+(global-set-key [find] 'beginning-of-line)
+(global-set-key [select] 'end-of-line)
+
+;; and the f1 thru f8 keys are designated as f6 thru f13
+(define-key function-key-map "\e[17~" [f1])
+(define-key function-key-map "\e[18~" [f2])
+(define-key function-key-map "\e[19~" [f3])
+(define-key function-key-map "\e[20~" [f4])
+(define-key function-key-map "\e[21~" [f5])
+(define-key function-key-map "\e[23~" [f6])
+(define-key function-key-map "\e[24~" [f7])
+(define-key function-key-map "\e[25~" [f8])
diff --git a/sys/arch/i386/isa/pcvt/Etc/rc.local b/sys/arch/i386/isa/pcvt/Etc/rc.local
new file mode 100644
index 00000000000..79be0bfec03
--- /dev/null
+++ b/sys/arch/i386/isa/pcvt/Etc/rc.local
@@ -0,0 +1,288 @@
+#---------------------------------------------------------------------------
+#
+# sample rc.local used for pcvt driver boot time initialization
+# -------------------------------------------------------------
+#
+# last edit-date: [Sun Jul 2 10:33:53 1995]
+#
+#---------------------------------------------------------------------------
+#
+# NOTE:
+# assumptions: - 8 screens configured
+# - /dev/ttyv0 ... /dev/ttyv7 exist
+#
+#---------------------------------------------------------------------------
+
+# path for pcvt utility programs: kcon, scon, loadfont, ispcvt and cursor
+# FreeBSD 2.0.5 and later
+#KCONP=/usr/sbin
+#SCONP=/usr/sbin
+#LDFNP=/usr/sbin
+#ISPCP=/usr/sbin
+#CURSP=/usr/sbin
+
+# path for pcvt utility programs: kcon, scon, loadfont, ispcvt and cursor
+# FreeBSD 2.0 and earlier and all NetBSD releases
+KCONP=/usr/local/bin
+SCONP=/usr/local/bin
+LDFNP=/usr/local/bin
+ISPCP=/usr/sbin
+CURSP=/usr/local/bin
+
+# path for pcvt's EGA/VGA download fonts
+FONTP=/usr/share/misc/pcvtfonts
+
+# path for xdm (X11R6)
+XDMP=/usr/X11R6/bin
+# path for xdm (X11R5)
+#XDMP=/usr/X386/bin
+
+# set to YES to start xdm on screen 8
+#xdm_start=YES
+xdm_start=NO
+
+# set to YES to set up for german keyboard layout
+#set_keybd=YES
+set_keybd=NO
+
+# set to YES to set up keyboard delay & rate
+set_keydr=YES
+#set_keydr=NO
+# if set to YES, this are the (very fast) settings
+set_keydr_rate=0
+set_keydr_delay=0
+
+# set to YES to construct a new /etc/motd file
+#construct_motd=YES
+construct_motd=NO
+
+# set to YES to set up cursor start and end scanline
+set_cursor=YES
+#set_cursor=NO
+# if YES set up a block cursor
+set_cur_start=0
+set_cur_end=15
+
+#-----------------------------------------------------
+# construct /etc/motd file
+#-----------------------------------------------------
+
+if [ X${construct_motd} = X"YES" ]
+then
+ if [ -f /netbsd ]
+ then
+ if [ ! -f /etc/motd ]; then
+ install -c -o root -g wheel -m 664 /dev/null /etc/motd
+ fi
+ T=/tmp/_motd
+ rm -f $T
+ sysctl -n kern.version | sed 1q > $T
+ echo "" >> $T
+ sed '1,/^$/d' < /etc/motd >> $T
+ cmp -s $T /etc/motd || cp $T /etc/motd
+ rm -f $T
+ echo 'runtime link editor directory cache'
+ ldconfig
+ else
+ T=/tmp/_motd
+ rm -f $T
+ uname -a > $T
+ echo "" >> $T
+ sed '1,/^$/d' < /etc/motd >> $T
+ cp $T /etc/motd
+ chmod 644 /etc/motd
+ rm -f $T
+
+ fi
+fi
+
+#-----------------------------------------------------
+# local daemons
+#-----------------------------------------------------
+
+echo -n 'starting local daemons:'
+
+# Kerberos runs ONLY on the Kerberos server machine
+if [ X${kerberos_server} = X"YES" ]; then
+ echo -n ' kerberos'; kerberos >> /var/log/kerberos.log &
+fi
+
+echo '.'
+
+#-----------------------------------------------------
+# check for correct driver and driver version matching
+#-----------------------------------------------------
+
+if [ -x $ISPCP/ispcvt ]
+then
+ if $ISPCP/ispcvt -d /dev/ttyv0
+ then
+
+#--------------------------------------------------
+# loading fonts into vga
+#--------------------------------------------------
+ echo 'console driver type: pcvt'
+ if [ -x $LDFNP/loadfont -a -x $SCONP/scon ]
+ then
+ adaptor=`$SCONP/scon -d /dev/ttyv0 -a`
+ if [ $adaptor = VGA ]
+ then
+ echo 'loading 25 lines base font into character set 0'
+ $LDFNP/loadfont -d /dev/ttyv0 -c0 -f $FONTP/vt220l.816
+ echo 'loading 25 lines extension font into character set 1'
+ $LDFNP/loadfont -d /dev/ttyv0 -c1 -f $FONTP/vt220h.816
+ echo 'loading 28 lines base font into character set 2'
+ $LDFNP/loadfont -d /dev/ttyv0 -c2 -f $FONTP/vt220l.814
+ echo 'loading 28 lines extension font into character set 3'
+ $LDFNP/loadfont -d /dev/ttyv0 -c3 -f $FONTP/vt220h.814
+ echo 'loading 40 lines base font into character set 4'
+ $LDFNP/loadfont -d /dev/ttyv0 -c4 -f $FONTP/vt220l.810
+ echo 'loading 40 lines extension font into character set 5'
+ $LDFNP/loadfont -d /dev/ttyv0 -c5 -f $FONTP/vt220h.810
+ echo 'loading 50 lines base font into character set 6'
+ $LDFNP/loadfont -d /dev/ttyv0 -c6 -f $FONTP/vt220l.808
+ echo 'loading 50 lines extension font into character set 7'
+ $LDFNP/loadfont -d /dev/ttyv0 -c7 -f $FONTP/vt220h.808
+ elif [ $adaptor = EGA ]
+ then
+ echo 'loading 25 lines base font into character set 0'
+ $LDFNP/loadfont -d /dev/ttyv0 -c0 -f $FONTP/vt220l.814
+ echo 'loading 25 lines extension font into character set 1'
+ $LDFNP/loadfont -d /dev/ttyv0 -c1 -f $FONTP/vt220h.814
+ echo 'loading 35 lines base font into character set 2'
+ $LDFNP/loadfont -d /dev/ttyv0 -c2 -f $FONTP/vt220l.810
+ echo 'loading 35 lines extension font into character set 3'
+ $LDFNP/loadfont -d /dev/ttyv0 -c3 -f $FONTP/vt220h.810
+
+# echo 'loading 43 lines base font into character set 2'
+# $LDFNP/loadfont -d /dev/ttyv0 -c2 -f $FONTP/vt220l.808
+# echo 'loading 43 lines extension font into character set 3'
+# $LDFNP/loadfont -d /dev/ttyv0 -c3 -f $FONTP/vt220h.808
+
+ fi
+ fi
+
+#--------------------------------------------------
+# setting screen sizes and emulation
+#--------------------------------------------------
+ if [ -x $SCONP/scon ]
+ then
+ if [ $adaptor = VGA ]
+ then
+ size=-s28
+ echo 'switching to 28 lines and VT/HP-emulation'
+ elif [ $adaptor = EGA ]
+ then
+ size=-s25
+ echo 'switching to 25 lines and VT/HP-emulation'
+ else
+ size=
+ echo 'switching to VT/HP-emulation'
+ fi
+
+# get monitor type (mono/color)
+
+ monitor=`$SCONP/scon -d /dev/ttyv0 -m`
+
+# for all screens do
+
+ for device in /dev/ttyv*
+ do
+
+# setup HP mode
+
+ $SCONP/scon -d$device $size -H
+
+# setup cursor size
+
+ if [ X${set_cursor} = X"YES" -a -x $CURSP/cursor ]
+ then
+ $CURSP/cursor -d$device -s$set_cur_start -e$set_cur_end
+ fi
+
+# if monochrome monitor, set color palette to use a higher intensity
+
+ if [ $monitor = MONO ]
+ then
+ if [ $adaptor = VGA ]
+ then
+ $SCONP/scon -d$device -p8,60,60,60
+ fi
+ fi
+ done
+
+# switch to screen 0
+
+ $SCONP/scon -d /dev/ttyv0
+
+# set screensaver timeout to one minute
+
+ $SCONP/scon -d /dev/ttyv0 -t360
+ fi
+
+#------------------------------------------------------
+# if desired, setup keyboard for german keyboard layout
+#------------------------------------------------------
+
+ if [ X${set_keybd} = X"YES" -a -x $KCONP/kcon ]
+ then
+ echo 'switching to german keyboard layout'
+ $KCONP/kcon -m de
+ fi
+
+#------------------------------------------------------
+# if desired, setup rate and delay keyboard values
+#------------------------------------------------------
+
+ if [ X${set_keydr} = X"YES" -a -x $KCONP/kcon ]
+ then
+ echo setting keyboard typematic rate = $set_keydr_rate and delay = $set_keydr_delay
+ $KCONP/kcon -r $set_keydr_rate -d $set_keydr_delay
+ fi
+
+#--------------------------------------------------
+# if desired, start xdm on screen 8
+#--------------------------------------------------
+
+ if [ X${xdm_start} = X"YES" -a -x $XDMP/xdm ]
+ then
+ $SCONP/scon -d /dev/ttyv7
+ $XDMP/xdm
+ sleep 5
+ $SCONP/scon -d /dev/ttyv0
+ fi
+
+#--------------------------------------------------
+# cp /etc/ttys corresponding to console driver
+#--------------------------------------------------
+
+ if [ -f /etc/ttys.pcvt ]
+ then
+ echo 'copying /etc/ttys.pcvt -> /etc/ttys'
+ cp /etc/ttys.pcvt /etc/ttys
+ fi
+
+ else
+ echo 'console driver type: not pcvt or pcvt utility/driver mismatch:'
+ echo '--------------------------------------------------------------'
+ $ISPCP/ispcvt -v -d /dev/ttyv0
+ echo '--------------------------------------------------------------'
+ if [ -f /etc/ttys.pccons ]
+ then
+ echo 'copying /etc/ttys.pccons -> /etc/ttys'
+ cp /etc/ttys.pccons /etc/ttys
+ fi
+ fi
+else
+ echo 'console driver type: not pcvt'
+ if [ -f /etc/ttys.pccons ]
+ then
+ echo 'copying /etc/ttys.pccons -> /etc/ttys'
+ cp /etc/ttys.pccons /etc/ttys
+ fi
+fi
+
+echo
+
+# EOF ----------------------------------------------------------------------
+
diff --git a/sys/arch/i386/isa/pcvt/Etc/ttys.pcvt.freebsd b/sys/arch/i386/isa/pcvt/Etc/ttys.pcvt.freebsd
new file mode 100644
index 00000000000..65fa74d9c68
--- /dev/null
+++ b/sys/arch/i386/isa/pcvt/Etc/ttys.pcvt.freebsd
@@ -0,0 +1,148 @@
+#---------------------------------------------------------------------------
+#
+# @(#)ttys 5.1 (Berkeley) 4/17/89
+#
+# example /etc/ttys for pcvt 3.31
+# -------------------------------
+#
+# FreeBSD 2.0.5-Release with entries for pcvt
+#
+# last edit-date: [Tue Sep 5 18:49:47 1995]
+#
+#---------------------------------------------------------------------------
+#
+# name getty type status comments
+#
+# This entry needed for asking password when init goes to single-user mode
+# If you want to be asked for password, change "secure" to "insecure" here
+console none unknown off secure
+#
+ttyv0 "/usr/libexec/getty Pc" pcvt25h on secure
+ttyv1 "/usr/libexec/getty Pc" pcvt25h on secure
+ttyv2 "/usr/libexec/getty Pc" pcvt25h on secure
+ttyv3 "/usr/libexec/getty Pc" pcvt25h on secure
+ttyv4 "/usr/libexec/getty Pc" pcvt25h on secure
+ttyv5 "/usr/libexec/getty Pc" pcvt25h on secure
+ttyv6 "/usr/libexec/getty Pc" pcvt25h off secure # syslog
+ttyv7 "/usr/libexec/getty Pc" pcvt25h off secure # X11
+# Serial terminals
+ttyd1 "/usr/libexec/getty std.19200" unknown on # Modem
+# Pseudo terminals
+ttyp0 none network
+ttyp1 none network
+ttyp2 none network
+ttyp3 none network
+ttyp4 none network
+ttyp5 none network
+ttyp6 none network
+ttyp7 none network
+ttyp8 none network
+ttyp9 none network
+ttypa none network
+ttypb none network
+ttypc none network
+ttypd none network
+ttype none network
+ttypf none network
+ttypg none network
+ttyph none network
+ttypi none network
+ttypj none network
+ttypk none network
+ttypl none network
+ttypm none network
+ttypn none network
+ttypo none network
+ttypp none network
+ttypq none network
+ttypr none network
+ttyps none network
+ttypt none network
+ttypu none network
+ttypv none network
+
+
+
+
+#
+# name getty type status comments
+#----- ----------------------------- ------- ---------- --------------
+#
+# This entry needed for asking password when init goes to single-user mode
+# If you want to be asked for password, change "secure" to "insecure" here
+#
+console none unknown off secure
+#
+# syscons
+#
+#ttyv0 "/usr/libexec/getty Pc" cons25 on secure
+## Virtual terminals
+#ttyv1 "/usr/libexec/getty Pc" cons25 on secure
+#ttyv2 "/usr/libexec/getty Pc" cons25 on secure
+#ttyv3 "/usr/libexec/getty Pc" cons25 off secure
+#
+# pcvt
+#
+ttyv0 "/usr/libexec/getty Pc" pcvt25h on secure
+ttyv1 "/usr/libexec/getty Pc" pcvt25h on secure
+ttyv2 "/usr/libexec/getty Pc" pcvt25h on secure
+ttyv3 "/usr/libexec/getty Pc" pcvt25h on secure
+ttyv4 "/usr/libexec/getty Pc" pcvt25h on secure
+ttyv5 "/usr/libexec/getty Pc" pcvt25h on secure
+ttyv6 "/usr/libexec/getty Pc" pcvt25h off secure # syslog msgs
+ttyv7 "/usr/libexec/getty Pc" pcvt25h off secure # used for X11
+#
+# Modem dialin/dialout port
+#
+ttyd1 "/usr/libexec/getty D19200" unknown on # T2500
+#
+# Hardwired ports
+#
+#tty00 "/usr/libexec/getty std.9600" unknown off secure # -N/C-
+#tty02 "/usr/libexec/getty std.9600" unknown off secure # DCF77
+#tty03 "/usr/libexec/getty std.9600" unknown off secure # Mouse
+#
+# Orig Hardwired terminals
+#
+#tty00 "/usr/libexec/getty std.9600" unknown off secure
+#tty01 "/usr/libexec/getty std.9600" unknown off secure
+#
+# Orig Dialin terminals
+#
+#ttyd2 "/usr/libexec/getty std.9600" unknown off secure
+#ttyd3 "/usr/libexec/getty std.9600" unknown off secure
+#
+# Pseudo terminals
+#
+ttyp0 none network
+ttyp1 none network
+ttyp2 none network
+ttyp3 none network
+ttyp4 none network
+ttyp5 none network
+ttyp6 none network
+ttyp7 none network
+ttyp8 none network
+ttyp9 none network
+ttypa none network
+ttypb none network
+ttypc none network
+ttypd none network
+ttype none network
+ttypf none network
+ttyq0 none network
+ttyq1 none network
+ttyq2 none network
+ttyq3 none network
+ttyq4 none network
+ttyq5 none network
+ttyq6 none network
+ttyq7 none network
+ttyq8 none network
+ttyq9 none network
+ttyqa none network
+ttyqb none network
+ttyqc none network
+ttyqd none network
+ttyqe none network
+ttyqf none network
diff --git a/sys/arch/i386/isa/pcvt/Etc/ttys.pcvt.netbsd b/sys/arch/i386/isa/pcvt/Etc/ttys.pcvt.netbsd
new file mode 100644
index 00000000000..12524af0ec5
--- /dev/null
+++ b/sys/arch/i386/isa/pcvt/Etc/ttys.pcvt.netbsd
@@ -0,0 +1,70 @@
+#---------------------------------------------------------------------------
+#
+# sample /etc/ttys file for pcvt driver and pcvt25h terminal emulation
+#
+# last edit-date: [Sun Feb 26 12:30:09 1995]
+#
+#---------------------------------------------------------------------------
+#
+# from: @(#)ttys 5.1 (Berkeley) 4/17/89
+# ttys,v 1.4.2.1 1993/08/20 07:58:39 cgd Exp
+#
+# name getty type status comments
+#
+console "/usr/libexec/getty Pcvt" pcvt25h off secure
+#
+# the following lines are for the pcvt driver
+#
+ttyv0 "/usr/libexec/getty Pcvt" pcvt25h on secure
+ttyv1 "/usr/libexec/getty Pcvt" pcvt25h on secure
+ttyv2 "/usr/libexec/getty Pcvt" pcvt25h on secure
+ttyv3 "/usr/libexec/getty Pcvt" pcvt25h on secure
+ttyv4 "/usr/libexec/getty Pcvt" pcvt25h on secure
+ttyv5 "/usr/libexec/getty Pcvt" pcvt25h on secure
+ttyv6 "/usr/libexec/getty Pcvt" pcvt25h off secure # X11 :1
+ttyv7 "/usr/libexec/getty Pcvt" pcvt25h off secure # X11 :0
+#
+# Hardwired lines are marked off, by default, so getty(8)
+# is quiet when they don't exist.
+#
+tty00 "/usr/libexec/getty std.9600" unknown off
+tty01 "/usr/libexec/getty std.9600" unknown off
+tty02 "/usr/libexec/getty std.9600" unknown off
+tty03 "/usr/libexec/getty std.9600" unknown off
+tty04 "/usr/libexec/getty std.9600" unknown off
+tty05 "/usr/libexec/getty std.9600" unknown off
+tty06 "/usr/libexec/getty std.9600" unknown off
+tty07 "/usr/libexec/getty std.9600" unknown off
+#
+ttyp0 none network
+ttyp1 none network
+ttyp2 none network
+ttyp3 none network
+ttyp4 none network
+ttyp5 none network
+ttyp6 none network
+ttyp7 none network
+ttyp8 none network
+ttyp9 none network
+ttypa none network
+ttypb none network
+ttypc none network
+ttypd none network
+ttype none network
+ttypf none network
+ttyq0 none network
+ttyq1 none network
+ttyq2 none network
+ttyq3 none network
+ttyq4 none network
+ttyq5 none network
+ttyq6 none network
+ttyq7 none network
+ttyq8 none network
+ttyq9 none network
+ttyqa none network
+ttyqb none network
+ttyqc none network
+ttyqd none network
+ttyqe none network
+ttyqf none network
diff --git a/sys/arch/i386/isa/pcvt/Etc/uemacs.tar.Z.uu b/sys/arch/i386/isa/pcvt/Etc/uemacs.tar.Z.uu
new file mode 100644
index 00000000000..25fba079135
--- /dev/null
+++ b/sys/arch/i386/isa/pcvt/Etc/uemacs.tar.Z.uu
@@ -0,0 +1,594 @@
+begin 666 uemacs.tar.Z
+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
+C`9^`4,`HH!1P"D@%K`):`:^`6,`LH!9P"\@%[`)Z`;^`8`$D
+`
+end
diff --git a/sys/arch/i386/isa/pcvt/Etc/xmodmap-german b/sys/arch/i386/isa/pcvt/Etc/xmodmap-german
new file mode 100644
index 00000000000..61bd100dbde
--- /dev/null
+++ b/sys/arch/i386/isa/pcvt/Etc/xmodmap-german
@@ -0,0 +1,117 @@
+! German keyboard with a programmer-like mapping,
+! J"org Wunsch <joerg_wunsch@uriah.sax.de>
+!
+! (``programmer-like'' stands for having brackets and braces on diaeresis
+! keys, whereas the ModeShifted keys result in umlauts)
+!
+! Note: the modifier keys are commented out, since they are remapped
+! within Xconfig to match internationalization requirements
+!
+keycode 8 =
+keycode 9 = Escape
+keycode 10 = 1 exclam
+keycode 11 = 2 quotedbl twosuperior
+keycode 12 = 3 paragraph threesuperior
+keycode 13 = 4 dollar
+keycode 14 = 5 percent
+keycode 15 = 6 ampersand
+keycode 16 = 7 slash braceleft
+keycode 17 = 8 parenleft bracketleft
+keycode 18 = 9 parenright bracketright
+keycode 19 = 0 equal braceright
+keycode 20 = ssharp question backslash
+keycode 21 = apostrophe grave
+keycode 22 = Delete
+keycode 23 = Tab
+keycode 24 = q Q at
+keycode 25 = W
+keycode 26 = E
+keycode 27 = R
+keycode 28 = T
+keycode 29 = Z
+keycode 30 = U
+keycode 31 = I
+keycode 32 = O
+keycode 33 = P
+keycode 34 = bracketright braceright udiaeresis Udiaeresis
+keycode 35 = plus asterisk asciitilde
+keycode 36 = Return
+! keycode 37 = Control_L
+keycode 38 = A
+keycode 39 = S
+keycode 40 = D
+keycode 41 = F
+keycode 42 = G
+keycode 43 = H
+keycode 44 = J
+keycode 45 = K
+keycode 46 = L
+keycode 47 = backslash bar odiaeresis Odiaeresis
+keycode 48 = bracketleft braceleft adiaeresis Adiaeresis
+keycode 49 = asciicircum degree
+! keycode 50 = Shift_L
+keycode 51 = numbersign apostrophe
+keycode 52 = Y
+keycode 53 = X
+keycode 54 = C
+keycode 55 = V
+keycode 56 = B
+keycode 57 = N
+keycode 58 = m M mu
+keycode 59 = comma semicolon
+keycode 60 = period colon
+keycode 61 = minus underscore
+! keycode 62 = Shift_R
+keycode 63 = KP_Multiply
+! keycode 64 = Alt_L Meta_L
+keycode 65 = space
+! keycode 66 = Caps_Lock
+keycode 67 = F1
+keycode 68 = F2
+keycode 69 = F3
+keycode 70 = F4
+keycode 71 = F5
+keycode 72 = F6
+keycode 73 = F7
+keycode 74 = F8
+keycode 75 = F9
+keycode 76 = F10
+! keycode 77 = Num_Lock
+keycode 78 = Multi_key
+keycode 79 = KP_7
+keycode 80 = KP_8
+keycode 81 = KP_9
+keycode 82 = KP_Subtract
+keycode 83 = KP_4
+keycode 84 = KP_5
+keycode 85 = KP_6
+keycode 86 = KP_Add
+keycode 87 = KP_1
+keycode 88 = KP_2
+keycode 89 = KP_3
+keycode 90 = KP_0
+keycode 91 = KP_Decimal
+keycode 92 = X386Sys_Req
+keycode 93 =
+keycode 94 = less greater bar
+keycode 95 = F11
+keycode 96 = F12
+keycode 97 = Home
+keycode 98 = Up
+keycode 99 = Prior
+keycode 100 = Left
+keycode 101 = Begin
+keycode 102 = Right
+keycode 103 = End
+keycode 104 = Down
+keycode 105 = Next
+keycode 106 = Insert
+keycode 107 = Delete
+keycode 108 = KP_Enter
+! keycode 109 = Control_R
+keycode 110 = Pause
+keycode 111 = Print
+keycode 112 = KP_Divide
+! keycode 113 = Alt_R Meta_R
+keycode 114 = Break
+
diff --git a/sys/arch/i386/isa/pcvt/README.FIRST b/sys/arch/i386/isa/pcvt/README.FIRST
new file mode 100644
index 00000000000..c1e675a5828
--- /dev/null
+++ b/sys/arch/i386/isa/pcvt/README.FIRST
@@ -0,0 +1,298 @@
+================================================================================
+| |
+| P C V T - VT220 Terminal Emulation Driver |
+| ------------------------------------------- |
+| |
+| Release 3.32 October 1995 |
+| ------------------------------------ |
+| |
+| for NetBSD/i386 1.x |
+| and FreeBSD 2.x |
+| |
+| (c) Copyright 1992,1993,1994,1995 by |
+| |
+| Hellmuth Michaelis |
+| Eggerstedtstrasse 28 |
+| 22765 Hamburg |
+| Europe |
+| |
+| For the contributors copyrights which apply to parts of the source |
+| see the header sections of the respective source files. |
+| |
+================================================================================
+
+Written by: Hellmuth Michaelis (hm@hcs.de)
+
+The major contributors to pcvt are Brian and Joerg, pcvt would not be what it
+is without the help, the support and the code from Joerg:
+
+ Brian Dunford-Shore (brian@athe.wustl.edu)
+
+ wrote parts of the EGA/VGA hardware handling and
+ some of the more ugly aspects of the VT220.
+
+ Joerg Wunsch (joerg_wunsch@uriah.heep.sax.de)
+
+ added ALL support for XFree86, the screensaver sub-
+ system and support for FreeBSD (and much more ...).
+
+
+I have to thank the following people for their help, for beta-testing, bugfixes,
+code, keymaps, suggestions, hints, patience and too much more to mention:
+
+ Scott Turner (scotty@gagetalker.com)
+ Peter Galbavy (peter@wonderland.org)
+ Michael Havemester (tik@abqhh.hanse.de)
+ Gordon L. Burditt (gordon@sneaky.lonestar.org)
+ Bruce Evans (bde@runx.oz.au)
+ Heiko W. Rupp (hwr@pilhuhn.ka.sub.org)
+ Carsten Lutz (clu@malihh.hanse.de)
+ Christian Rohrmueller (internal@doitcr.doit.sub.org)
+ Andy Duplain (duplain@rtf.bt.co.uk)
+ Marko Karppinen (dreamer@purkki.apu.fi)
+ Onno van der Linden (c/o frank@fwi.uva.nl)
+ Dave Nelson (dcn@ignatz.acs.depaul.edu)
+ Mark Weaver (Mark_Weaver@brown.edu)
+ John Brezak (brezak@apollo.hp.com)
+ Jan-Oliver Neumann (jan@encap.hanse.de)
+ Kim Andersen (kim@dde.dk)
+ Michael Graff (explorer@iastate.edu)
+ Randy Terbush (randyt@cse.unl.edu)
+ Benjamin Lewis (blewis@vet.vet.purdue.edu)
+ Daniel Harris (daniel@reubio.apana.org.au)
+ Alistair G. Crooks (agc@uts.amdahl.com)
+ Szabolcs Szigeti (pink@bagira.fsz.bme.hu)
+ Charles Hannum (mycroft@gnu.ai.mit.edu)
+ Thomas Gellekum (thomas@ghpc8.ihf.rwth-aachen.de)
+ Matthieu Herrb (matthieu@laas.fr)
+ John A. Perry (perry@jpunix.com)
+ John Kohl (jtk@kolvir.blrc.ma.us)
+ Brian Moore (ziff@eecs.umich.edu)
+ Martin Husemann (martin@euterpe.owl.de)
+ Lon Willett (willett@math.utah.edu)
+ Mark Willey (mwilley@mipos2.intel.com)
+ Bill Sommerfeld (sommerfeld@orchard.medford.ma.us)
+ Rafal Boni (r-boni@uiuc.edu)
+ Thomas Eberhardt (thomas@mathematik.uni-bremen.de)
+ Jukka A. Ukkonen (ukkonen@csc.fi)
+ Frank van der Linden (frank@fwi.uva.nl)
+
+
+History (see also Doc/ChangeLog)
+--------------------------------------------------------------------------------
+
+Release Changes/Features
+------------- ----------------------------------------------------------------
+1.00 (08/92) Released as "pccons_vga" to alt.sources, VT100 emulation
+
+2.00 (01/93) VT220 emulation, many bugfixes and enhancements
+
+2.10 (03/93) Fixed bugs, monochrome environments, configuration changes
+
+2.20 (10/93) never released (experimental internal release)
+
+3.00 (03/94) Support for XFree86 >= 1.2, support for XFree86 2.0's
+ syscons/USL model for multiple X servers and/or terminal
+ sessions from Joerg Wunsch (Thank You, Joerg !!!), fixed
+ bugs, (n)curses-based EGA/VGA font editor, memory mapped
+ screens, full MDA/CGA virtual screen support, 132 columns
+ on some super VGA chipsets, support for NetBSD >= 0.9,
+ support for FreeBSD >= 1.0 and much more ....
+ (posted to comp.sources.misc, Volume 41, Issue 140-152)
+
+3.10 never released (experimental internal release)
+
+3.20 never released (several beta testing cycles in '94/'95)
+ Fast forward/backward scrolling from Michael Havemester,
+ further optimization by Charles Hannum. Keyboard queueing
+ for silo overflow minimization also from Michael.
+ Many bugfixes, cleanups and enhancements.
+ Support for NetBSD 1.0 and FreeBSD 2.0.
+
+3.30 (07/95) Public release after almost a year of beta cycles.
+ Support for NetBSD-current as of 06/30/95 and FreeBSD 2.0.5.
+
+3.32 (10/95) Minor bugfixes for release 3.30, C1 controls support, removed
+ support for old single virtual screen Xserver (pccons-like),
+ NetBSD < 1.0 and FreeBSD < 2.0 no longer supported.
+
+
+Features
+--------------------------------------------------------------------------------
+
+The 'pcvt' VT220 emulator driver has:
+
+ - Almost full DEC VT220 (VT100/VT102) Terminal functionality
+ - full multiple virtual screen / multiple X-server support
+ for XFree86 >= 2.0 using the USL-VT/syscons model
+ - Full Support for MDA, CGA, EGA and VGA display adaptors
+ - configurable number of virtual screens on any video board
+ - completely independent virtual terminals for any video board
+ - (24), 25, 28, 40, or 50 lines for each virtual screen on VGA's
+ - (24), 25, 35, or 43 lines for each virtual screen on EGA's
+ - Fully remappable keyboard to support national keyboards
+ - All VT220 character sets plus ISO Latin-1 and DEC Technical supported
+ - VT220 downloadable character set supported when run on EGA/VGA
+ - VT220 user defined keys for each virtual terminal
+ - Optional function key label support a 'la Hewlett-Packard
+ - Display function codes (0x00-0x1f/0x90-0xaf) functionality
+ - Optional screen-saving feature
+ - 132 column operation on several VGA chipsets:
+ o Tseng Labs ET3000 and ET4000
+ o Western Digital WD90C11
+ o Trident TVGA9000, TVGA8900B, TVGA8900C, TVGA8900CL
+ o Video 7 1024i
+ o S3 80C928 (board dependent)
+ o Cirrus Logic GD542x, GD5430, GD6225 (board dependent)
+
+What it cannot:
+
+ - No double wide/high characters
+ - No softscroll
+ - No inverse background
+ - No VT220 printer output support
+ - No VT52 support at all
+ - Only limited AT-keyboard (84 keys) support
+ - Help you to make money ....
+
+
+The entire pcvt package consists of:
+
+ - the VT220 emulating driver itself
+ - complete documentation for installation and operation
+ - termcap/terminfo, pcvt.el, rc.local, /etc/ttys, xmodmap examples
+ - cursor: utility to set the cursor size and shape
+ - fed: curses-based EGA/VGA character set editor
+ - fontedit: utility to edit the vt220 downloadable character set
+ - ispcvt: utility to display the drivers compile time configuration
+ - kcon: utility to setup national keyboard layouts and remap keys
+ - keycap: keyboard mapping database library similar to termcap
+ - loadfont: utility to load up to 4/8 fonts into an EGA/VGA board
+ - mcon: utility to control/configure a keyboard based mouse emulator
+ - scon: utility to runtime configure the video part of pcvt
+ - userkeys: utility to set the VT220 user programmable function keys
+ - vttest: VT100 compatibility torture test program
+ - some color- characterset- and attribute demos
+ - vga and keyboard register-level debugging utilities
+
+
+Tested Operating Systems
+--------------------------------------------------------------------------------
+
+ NetBSD 1.0 pcvt release 3.32 tested
+
+ NetBSD-current (post 1.0) reported to run (June 30 1995)
+
+ FreeBSD 2.0.5R pcvt release 3.32 tested
+
+ FreeBSD-stable (pre 2.1) pcvt release 3.32 tested (SNAP-950928)
+
+
+
+Installation / Upgrade
+--------------------------------------------------------------------------------
+
+ R E A D (!!!) THE INSTRUCTIONS IN THE Doc/INSTALL.xxxBSD FILES CAREFULLY !
+ ==========================================================================
+
+ Again: PLEASE R E A D T H E M !!!!! (Thank You! ;-)
+ ========================================
+
+ If you read them, you should have NO problems installing pcvt on your
+ system, if you don't read them, you'll probably run into problems ...
+
+ If you run into any difficulties, please read the file Doc/FAQ !
+
+NOTE 1:
+-------
+ It is highly recommended in order to configure the driver into the system,
+ that you remove (and/or backup) your previous kernel compile directory and
+ do a fresh "config" with the new pcvt configuration. This has to be done
+ because the chain "config/make depend/make" obviously does not resolve ALL
+ dependencies!
+
+NOTE 2:
+-------
+ You MUST copy or link the Util/Makefile.inc.X for your flavour of xxx(x)BSD
+ to Util/Makefile.inc . This is because FreeBSD handles manual pages
+ in a differnet way than NetBSD. Also you have to edit Doc/Makefile
+ to make this changes for the pcvt(4) manpage.
+
+NOTE 3:
+-------
+ The driver now (from 2.10 on) DEPENDS on the BIOS video display setting
+ stored in the RTC CMOS Ram - verify your configuration setting!
+
+NOTE 4:
+-------
+ If you are using the pcvt termcap entry from Etc/Termcap, please reinstall
+ this into /usr/share/misc/termcap if you are upgrading, the entry had bugs
+ in release 3.10 and all earlier releases (release 3.32 added a few entries
+ to properly support the alternate charcterset!).
+
+ After doing that, you may need to generate a new termcap database for newer
+ FreeBSD (2.0 and up) and NetBSD (1.0 and up) Releases:
+ cd to /usr/share/misc and execute 'cap_mkdb termcap'.
+
+NOTE 5:
+-------
+ The default keyboard layout is documented in Doc/Keyboard.HP unless you
+ compiled with PCVT_VT220KEY which is described in Doc/Keyboard.VT. Please
+ note that PCVT_VT220KEYB is not much supported, because i don't use it.
+
+NOTE 6:
+-------
+ When upgrading from a previous version of the driver, you can remove now
+ the directory /usr/share/misc/vgafonts. It was moved in release 3.20 to
+ /usr/share/misc/pcvtfonts.
+
+NOTE 7:
+-------
+ In case you don't like pcvt's white on red kernel messages, have a look at
+ the end of pcvt_conf.h, this is the place to change them.
+
+FreeBSD upgrade to 2.0.5R
+-------------------------
+ The locations of the support binaries and libs have changed, be sure to
+ remove all old binaries from /usr/local/bin, man pages from /usr/local/man
+ and libs from /usr/local/lib. The new Makefile now places binaries into
+ /usr/sbin, libs into /usr/lib and manual pages into /usr/share/man.
+
+
+WYSIWYG - What You Share Is What You Get
+--------------------------------------------------------------------------------
+
+PLEASE, if you fix bugs, add features, hack this driver to work on your
+hardware or simply don't get it up and running, get in contact with me!
+
+ Help us to avoid reinventing the wheel over and over again!
+ -----------------------------------------------------------
+
+The code is far from being perfect, YOU are very welcome to enhance it !
+Please mail bug reports/fixes, suggestions, enhancements & diffs to
+
+ hm@hcs.de or
+ hm@altona.hamburg.com
+
+I will support this driver as my time permits it, feel free to contact me!
+
+Have fun!
+
+Hellmuth
+
+
+@home
+-----
+e-mail: hm@altona.hamburg.com
+ tel: +49 / 40 / 384298
+s-mail: Eggerstedtstr. 28, 22765 Hamburg, Europe
+
+
+@work
+-----
+e-mail: hm@hcs.de
+ tel: +49 / 40 / 559795-70
+ tel: +49 / 40 / 55903-170
+ fax: +49 / 40 / 5591486
+s-mail: HCS Hanseatischer Computerservice GmbH, Oldesloer Str. 97-99,
+ 22457 Hamburg, Europe
diff --git a/sys/arch/i386/isa/pcvt/Util/Makefile b/sys/arch/i386/isa/pcvt/Util/Makefile
new file mode 100644
index 00000000000..fc23821669c
--- /dev/null
+++ b/sys/arch/i386/isa/pcvt/Util/Makefile
@@ -0,0 +1,9 @@
+SUBDIR= keycap cursor fontedit fonts kcon loadfont scon \
+ userkeys vttest ispcvt mcon pcvtdoc
+
+.if make(clean) || make(cleandir) || make(obj)
+SUBDIR+= vgaio kbdio set2061
+SUBDIR+= demo
+.endif
+
+.include <bsd.subdir.mk>
diff --git a/sys/arch/i386/isa/pcvt/Util/Makefile.inc b/sys/arch/i386/isa/pcvt/Util/Makefile.inc
new file mode 100644
index 00000000000..70eb3a03513
--- /dev/null
+++ b/sys/arch/i386/isa/pcvt/Util/Makefile.inc
@@ -0,0 +1,33 @@
+# $NetBSD: Makefile.inc,v 1.3 1995/10/07 21:51:42 jtc Exp $
+
+ECHO ?= echo
+
+BINDIR = /usr/local/bin
+FONTDIR = /usr/share/misc/pcvtfonts
+LIBDIR = /usr/local/lib
+LIBMODE = 644
+
+# for pcvt_ioctl.h
+
+INCDIR = /usr/include/machine
+INCOWN = bin
+INCGRP = bin
+INCMODE = 444
+
+${INCDIR}/pcvt_ioctl.h: ${.CURDIR}/../../pcvt_ioctl.h
+ install ${COPY} -o ${INCOWN} -g ${INCGRP} -m ${INCMODE} \
+ ${.CURDIR}/../../pcvt_ioctl.h ${INCDIR}
+
+.depend: ${INCDIR}/pcvt_ioctl.h
+
+MAN3EXT = 3
+MAN4EXT = 4
+MAN5EXT = 5
+MAN8EXT = 8
+MANDIR = /usr/local/man/cat
+
+MAN = ${MAN1} ${MAN3} ${MAN4} ${MAN5} ${MAN8}
+
+.if empty(MAN) && defined(PROG)
+MAN+= ${PROG}.1
+.endif
diff --git a/sys/arch/i386/isa/pcvt/Util/cursor/Makefile b/sys/arch/i386/isa/pcvt/Util/cursor/Makefile
new file mode 100644
index 00000000000..b5afd6cec23
--- /dev/null
+++ b/sys/arch/i386/isa/pcvt/Util/cursor/Makefile
@@ -0,0 +1,3 @@
+PROG= cursor
+
+.include <bsd.prog.mk>
diff --git a/sys/arch/i386/isa/pcvt/Util/cursor/cursor.1 b/sys/arch/i386/isa/pcvt/Util/cursor/cursor.1
new file mode 100644
index 00000000000..077448cfc48
--- /dev/null
+++ b/sys/arch/i386/isa/pcvt/Util/cursor/cursor.1
@@ -0,0 +1,76 @@
+.\" Copyright (c) 1992, 1995 Hellmuth Michaelis
+.\"
+.\" All rights reserved.
+.\"
+.\" 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 Hellmuth Michaelis
+.\" 4. The name authors may not be used to endorse or promote products
+.\" derived from this software without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``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 AUTHORS 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.
+.\"
+.\" @(#)cursor.1, 3.30, Last Edit-Date: [Fri Jun 30 20:06:58 1995]
+.\"
+.Dd December 19, 1994
+.Dt CURSOR 1
+.Sh NAME
+.Nm cursor
+.Nd set cursor shape for the pcvt VT220 video driver
+.Sh SYNOPSIS
+.Nm cursor
+.Op Fl d Ar device
+.Op Fl n Ar screenno
+.Op Fl s Ar lineno
+.Op Fl e Ar lineno
+.Sh DESCRIPTION
+The
+.Nm cursor
+utility allows the user to set the cursor shape in a given virtual screen
+of the above mentioned driver.
+.Pp
+The options are as follows:
+.Bl -tag -width Ds
+.It Fl d
+Specifies a device for which the cursor shape is set.
+.It Fl n
+Sets the virtual screen number to apply the following parameters to. Not
+specifying this parameter implies the current virtual screen or the screen
+referenced by the -d parameter.
+.It Fl s
+Specifies the starting (top) scanline the cursor should have.
+.It Fl e
+Specifies the last (bottom) scanline the cursor should have.
+.El
+.Pp
+Be aware of the fact that the parameters need to be adjusted for the current
+size of the characterfont in use, on EGA and VGA boards sizes of 8, 14 and
+16 scanlines are currently supported.
+.Sh EXAMPLES
+The command
+.Dq Li cursor -s3 -e10
+sets the cursor on the current virtual screen to a rectangular shape on a
+14 line VGA screen.
+.Sh BUGS
+No known bugs
+.Sh SEE ALSO
+.Xr loadfont 1 ,
+.Xr scon 1 ,
+.Xr pcvt 4
diff --git a/sys/arch/i386/isa/pcvt/Util/cursor/cursor.c b/sys/arch/i386/isa/pcvt/Util/cursor/cursor.c
new file mode 100644
index 00000000000..f2a7b91b864
--- /dev/null
+++ b/sys/arch/i386/isa/pcvt/Util/cursor/cursor.c
@@ -0,0 +1,157 @@
+/*
+ * Copyright (c) 1992, 1995 Hellmuth Michaelis
+ *
+ * Copyright (c) 1992, 1994 Brian Dunford-Shore
+ *
+ * All rights reserved.
+ *
+ * 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
+ * Hellmuth Michaelis and Brian Dunford-Shore
+ * 4. The name authors may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``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 AUTHORS 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.
+ *
+ */
+
+static char *id =
+ "@(#)cursor.c, 3.30, Last Edit-Date: [Fri Jun 30 20:07:13 1995]";
+
+/*---------------------------------------------------------------------------*
+ *
+ * history:
+ *
+ * -hm adding option -d <device>
+ *
+ *---------------------------------------------------------------------------*/
+
+#include <stdio.h>
+#include <fcntl.h>
+#include <sys/stat.h>
+#include <machine/pcvt_ioctl.h>
+
+#define DEFAULTFD 0
+
+main(argc,argv)
+int argc;
+char *argv[];
+{
+ extern int optind;
+ extern int opterr;
+ extern char *optarg;
+
+ struct cursorshape cursorshape;
+ int fd;
+ int c;
+ int screen = -1;
+ int start = -1;
+ int end = -1;
+ int dflag = -1;
+ char *device;
+
+ while( (c = getopt(argc, argv, "d:n:s:e:")) != EOF)
+ {
+ switch(c)
+ {
+ case 'd':
+ device = optarg;
+ dflag = 1;
+ break;
+
+ case 'n':
+ screen = atoi(optarg);
+ break;
+
+ case 's':
+ start = atoi(optarg);
+ break;
+
+ case 'e':
+ end = atoi(optarg);
+ break;
+
+ case '?':
+ default:
+ usage();
+ break;
+ }
+ }
+
+ if(start == -1 || end == -1)
+ usage();
+
+ if(dflag == -1)
+ {
+ fd = DEFAULTFD;
+ }
+ else
+ {
+ if((fd = open(device, O_RDWR)) == -1)
+ {
+ char buffer[80];
+ strcpy(buffer,"ERROR opening ");
+ strcat(buffer,device);
+ perror(buffer);
+ exit(1);
+ }
+ }
+
+ if(screen == -1)
+ {
+ struct stat stat;
+
+ if((fstat(fd, &stat)) == -1)
+ {
+ char buffer[80];
+ strcpy(buffer,"ERROR opening ");
+ strcat(buffer,device);
+ perror(buffer);
+ exit(1);
+ }
+
+ screen = minor(stat.st_rdev);
+ }
+
+ cursorshape.start = start;
+ cursorshape.end = end;
+ cursorshape.screen_no = screen;
+
+ if(ioctl(fd, VGACURSOR, &cursorshape) == -1)
+ {
+ perror("cursor - ioctl VGACURSOR failed, error");
+ exit(1);
+ }
+ else
+ exit(0);
+}
+
+usage()
+{
+ fprintf(stderr,"\ncursor - set cursor shape for pcvt video driver\n");
+ fprintf(stderr,"usage: cursor -d [device] -n [no] -s [line] -e [line]\n");
+ fprintf(stderr," -d <device> device to use (/dev/ttyvX), default current\n");
+ fprintf(stderr," -n <no> screen no if specified, else current screen\n");
+ fprintf(stderr," -s <line> start scan line (topmost scan line)\n");
+ fprintf(stderr," -e <line> ending scan line (bottom scan line)\n\n");
+ exit(1);
+}
+
diff --git a/sys/arch/i386/isa/pcvt/Util/demo/Makefile b/sys/arch/i386/isa/pcvt/Util/demo/Makefile
new file mode 100644
index 00000000000..79f7397e6dd
--- /dev/null
+++ b/sys/arch/i386/isa/pcvt/Util/demo/Makefile
@@ -0,0 +1,54 @@
+PROG= playvt
+SRCS= playvt.c
+DEMOS= chardemo.vt colors.vt sgr.vt
+DEMOS+= outerlimit.vt twzone.vt cowscene.vt xmas.vt
+NOMAN=
+
+all: $(DEMOS) $(PROG)
+
+install: ${DEMOS}
+ @${ECHO} "to look at the demos, execute:"
+ @${ECHO} " \"cat <filename>.vt\""
+ @${ECHO} "if it is an animation an it runs too fast, try out:"
+ @${ECHO} " \"playvt -f <filename>.vt -d<some-delay-val>\""
+
+.include <bsd.prog.mk>
+
+CLEANFILES+= ${DEMOS}
+
+# this seems to be the lowest common denominator
+
+chardemo.vt: ${.CURDIR}/$@.gz.uu
+ uudecode ${.CURDIR}/$@.gz.uu
+ gunzip -f $@.gz
+ rm -f $@.gz
+
+colors.vt: ${.CURDIR}/$@.gz.uu
+ uudecode ${.CURDIR}/$@.gz.uu
+ gunzip -f $@.gz
+ rm -f $@.gz
+
+sgr.vt: ${.CURDIR}/$@.gz.uu
+ uudecode ${.CURDIR}/$@.gz.uu
+ gunzip -f $@.gz
+ rm -f $@.gz
+
+cowscene.vt: ${.CURDIR}/$@.gz.uu
+ uudecode ${.CURDIR}/$@.gz.uu
+ gunzip -f $@.gz
+ rm -f $@.gz
+
+xmas.vt: ${.CURDIR}/$@.gz.uu
+ uudecode ${.CURDIR}/$@.gz.uu
+ gunzip -f $@.gz
+ rm -f $@.gz
+
+outerlimit.vt: ${.CURDIR}/$@.gz.uu
+ uudecode ${.CURDIR}/$@.gz.uu
+ gunzip -f $@.gz
+ rm -f $@.gz
+
+twzone.vt: ${.CURDIR}/$@.gz.uu
+ uudecode ${.CURDIR}/$@.gz.uu
+ gunzip -f $@.gz
+ rm -f $@.gz
diff --git a/sys/arch/i386/isa/pcvt/Util/demo/README b/sys/arch/i386/isa/pcvt/Util/demo/README
new file mode 100644
index 00000000000..5e33f540ad8
--- /dev/null
+++ b/sys/arch/i386/isa/pcvt/Util/demo/README
@@ -0,0 +1,20 @@
+- The files "chardemo.vt" and "colors.vt" are taken from the MSDOS Kermit
+ distribution and are redistributed with permission from Frank da Cruz.
+
+- cat chardemo.vt - displays all available character sets
+
+- cat colors.vt - displays all available back/foreground color combinations
+
+- cat sgr.vt - displays all possible graphic renditions
+
+- all other files are some VT100 animations collected over the time from
+ unkown sources, play them with playvt.
+
+- Playvt is a program to play an animation file on pcvt: because pcvt is
+ _much_ faster than an original VT100/VT220, it adds a programmable delay
+ for each character so one can enjoy smooth-running animations! :-)
+ There is no manpage available for playvt, just try to run playvt -? which
+ should give sufficient information. You have to empirically find out which
+ delay value fit's your needs!
+
+have fun!
diff --git a/sys/arch/i386/isa/pcvt/Util/demo/chardemo.vt.gz.uu b/sys/arch/i386/isa/pcvt/Util/demo/chardemo.vt.gz.uu
new file mode 100644
index 00000000000..efcd4c7f1ef
--- /dev/null
+++ b/sys/arch/i386/isa/pcvt/Util/demo/chardemo.vt.gz.uu
@@ -0,0 +1,53 @@
+begin 664 chardemo.vt.gz
+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
+64(2@"$$1?CT_'&^W^B\8)0@*\AL``,4&
+`
+end
diff --git a/sys/arch/i386/isa/pcvt/Util/demo/colors.vt.gz.uu b/sys/arch/i386/isa/pcvt/Util/demo/colors.vt.gz.uu
new file mode 100644
index 00000000000..1d5d0daee45
--- /dev/null
+++ b/sys/arch/i386/isa/pcvt/Util/demo/colors.vt.gz.uu
@@ -0,0 +1,15 @@
+begin 664 colors.vt.gz
+M'XL("):V^BX"`V-O;&]R<RYV=`#MU+UNG$`4!>!^I7T"FGD`Q^+^S)TB2N-8
+M;B(GA=UMM;*1C;(8":\E/W[,G(.SX0E2+,WE(#%\@N$T._.O7H;MYO;NR_6O
+MN_2CFX;^F.RR3??=^S'=CH]=^CX>QNGU(ME[^I9NQJE[FL:WE\>+Y/.%J_W#
+M;US8;K:;A*/963LO_'&+MVF^TP5#,0S#,3)&8)24MIMEA63MLEP[I#EYBRB,
+M@JB,BFB,ANB,CI@9,V(PQN=3:RRG#*D,(4/`$#($#"%#P!`R!`PA0\`0,@0,
+M(4/`$#*DOH_T<YR&_>'4H]6C]"@\2H_"H_0H/$J/PJ/T*#Q*C\*C]"@\2H_"
+M\W<;G)JLFHPF@\EH,IB,)H/):#*8C":#R6@RF(PF@\EHLM6G\LIP,AP,)\/!
+M<#(<#"?#P7`R'`PGP\%P,AP,)\-7C%P9F8P,1B8C@Y')R&!D,C(8F8P,1B8C
+M@Y')R&!D,O**$9419`0804:`$60$&$%&@!%D!!A!1H`19`0804:L&*4R"AD%
+MC$)&`:.04<`H9!0P"AD%C$)&`:.04<`H9)1_&/?/_6M:_BZ<UHV]3\MV&MX.
+MQW[YJ`]S\Z7EW1[ZEVY9Z++YK,YF)\.YKU9]=37U3\_'<U^=^^K<5_]57S6[
+-]J.M_@#AP6KE^0D``&Y9
+`
+end
diff --git a/sys/arch/i386/isa/pcvt/Util/demo/cowscene.vt.gz.uu b/sys/arch/i386/isa/pcvt/Util/demo/cowscene.vt.gz.uu
new file mode 100644
index 00000000000..7a5a4dbb724
--- /dev/null
+++ b/sys/arch/i386/isa/pcvt/Util/demo/cowscene.vt.gz.uu
@@ -0,0 +1,90 @@
+begin 644 cowscene.vt.gz
+M'XL(".BA?2H"`V-O=W-C96YE+G9T`.U=P8[CQA$]&MA?F`N!R6%6B"QU=9.4
+ML`?;"1((1GP*XLL(&!C916QDXPT<(-Z#H&\/V5U-=C<?BV4@<)RD%XA":JA^
+M[W635:\DLOSP3%\^/']&[?N'Y_X-N1]>/3R;XQMS>3UNF+A!PT8S;MAQPV^Y
+M::N-?^R&C=WVOX>GXU]_?/_P])OM0R.;EXG.AXG/`1&*?*8/)I^</WJ=/WN;
+M/WR;Y=R;.,!3,L)3,L0^'2,9Y'!-1IF':=)QFFR@=*0F'6I_2Q@UZ6#Y:,5P
+MV7CY@/N479,/68Q9#IJ/6@R;,RT'+D=>#%V,G0U^W>>L[\OA%^,O`?;YBN<0
+MMUNAX(Y`EB@9S&&!TRR`FD.IIL%0`"L#:Y9H!P#7+)0U:X`(,8<$F`T`W35`
+M90[;)Q#*?R5;2+?@BP@CQLT.3M3,F=$)H1-")X1.")T\>C%AA-`M0K<(W2)T
+MB]`MTFX1ND/H#J$[A.X0ND/:'4)O$7J+T%N$WB+T%FEO$7J'T#N$WB'T#J%W
+M2'N'T'N$WB/T'J'W"+U'VGN$?D+H)X1^0N@GA'Y"VD\(_8S0SPC]C-#/"/V,
+MM)\1NCG"<'.$\>8(`\X11IPCF@`>M^2`0QZ.>3CHX:B'PQZ,>P8&/@,CGX&A
+MS\#89V#P,S#Z&1C^#(Q_!@9``R.@@2'0P!AH8!`T,`H:&`8-C(,&!D(#(Z&!
+MH=#`6&A@,#0P&AH8#@V,AP8&1`,CHH$AT<"8:&!0-#`J&A@6#8R+!@9&`R.C
+M@:'1P-AH8'`T,#H:&!X-C(\&!D@#(Z2!(=+`&&E@D#0P2AH8)@V,DP3C),$X
+M23!.$HR3=$0<:!DG3T/=>OFB^>V''Q^>SV^HN]P"K^[R]?B9P<V-K^1?K7]U
+M_K7UKYU_[?WKR;^>_>L0D/W_A4\/82F,%08P8003AC!A#!,&,6$4$X:A,`PQ
+MB<""[*4RJ\Q^)F;^^O`7(E\?3;P^FCJCE5F]/FK^J,PJLYH_*K/*K.:/RJPR
+MJ_FC,JO,*K/*K#+[.9@-=-SE$'[H;L>-\QMK+U]]^/#IIW5**[/*S%\@3;Q`
+M&KY`IGMCZI169O4"J1FD,JO,:@:IS"JSFD$JL\JL9I#*K#*KS"JSRNS_FYE[
+M8_O+U^%9J-[_0D]C]OJB>?_-]V__]MWW[ZK)J\PJLW"=-/$Z:>)U4CR+66>V
+M,JO72<TGE5EE5O-)95:9U7Q2F55FOY1\<AP_C)Y*AIT3"'9.(-@Y@0QLV8([
+MQN"6,;AG#&X:@[O&$'PR&G9.(-@Y@6#G!(*=$PAV3B`+YP%V3B#8.8%@YP2"
+MG1,(=DX@!^<!=DX@V#F!8.<$@IT3"'9.H!;.`^R<0+!S`L'."00[)Q#LG$`=
+MG`?8.8%@YP2"G1,(=DX@V#F!>C@/R\X)OKW&PZ/]W<>_O__P]KOO_S(^.#.\
+MWX7W7?G^R!EV6B#8:8%@IP6"G1;H!.<M[[3PZI/0%JF[7&^'\6F&(1K]X>'Y
+MJX?GS]IO.2*UE^LP]H%;+;G+-<WC]HTSEP,W5QJ.W.UVAU<Q;EW#1LSXCL*1
+MSH^R&]B%8X<@3/Y8$X\=`K*]E'S>O_(_RIWF=G-'?WSS]/GGL674J([GA<:]
+M89:8]\!F%[:ZR^X6-MWQ,K$]7@XA\-(Y;/D9W(4>#,6LG%(63.GCQT@IYT`!
+MEV9<&J=L4F["W\W\=S-.5/R[&SM"Q+6_-4U<\%M"D6?_Z%N[#8R'_]WO/-'#
+MXAR:G3]?=E<PH7TJY91*.6=*CBF3?F;23TQZ9F)#QHISW?#F\/$KFLN!P#DE
+M<$X)G-.I')\]B[#=!-L%V%+7R?.=ELCO3$ODI:1+=-C')1KF*2[1_N#IN="3
+M(\;.B4([46B7%+X-J"8]5_T><S!^CSF<PD[$<#.&FS#<O,Y39ID6V7(?P/T5
+M+?$(36F/1K_'1/Q5&8F<PTXD,IR:_&!32-97WO'Y,=#Q)[!_T\R+'1!B:S=_
+M6K^*%_5$@\(>T[!^+SG9;,9CHM#$YBG#Z3P##.%I6LJ\M5XX"X=K^Y!,4,1F
+M)C9CXC(F)C*9@'G;]XM)2/27^3)\?`Q@CX_\L8Q`$Z^2XR4CRJN6,&)^+N/7
+M9OQHXA=:E(ZS[1N+YHGHW=L&)J+Y_6K7*[-:?-4O\RJSRNS?<9UP_FG+=-S!
+M][WW2/M:S]UOK].5QXUOKR\O+[]NLI;*8]T3&]Z^A'^WJ=?M4_,ZCO^K"'";
+M$9X!Q`K&`B1!26'N,TX"U$"D-:@E5@J6HC4SW$N&MP*XB@@@,\P4].7>)).9
+MPMX`[@T"WP#R;04ZPWY))#<Y>H/@&XS?(`(OJPQR"HG^_Q2%;!H*$F\QBS4:
+MF(=`I&"234?)Y<,:F54V*W0D/B6A?'(6E%8XO9-(K;$2:2UX%5-5,OO]&K4_
+MR]Q6R<GLEO3*B2L)-JL,O]NBN,YQ@R1@N9C&DN<_UHG^<YNI0!5R?2V374[J
+M@J[`]P<-88DQGMZ"<TD9S'!)^AN)]3L=;9$W)/ZTR1Q-=\G]*Y'\'[7L9?KX
+M7%D(X.\1"A%P`4H9>UE'HQ>RH63E'%IJV0$E>$%*+7_:$O-3U&S)63NU%H*@
+MGI6U603+;4D_2=.F*+Q*I:P]"E&+A;H)PFZ;RFX*:;=-;;=M<:6Z?:JN>5E?
+M-DE?LRVPT2ALMB4V&HV%R"%@3")I(7):0Y)$TK9(THBD;9&T+9(6(L>@.(FT
+MZRMI)9%V6Z35B+3;(NVV2%N*'#7.(MWZ2CI)I-L6Z30BW;9(MRW2%2*]QEED
+MN[Z2K22RW1;9:D2VVR+;;9%M+C)HG+Q(M[Z0G:2QV];8:31VVQJ[;8U=II$E
+M3AK[=8V]I+'?UMAK-/;;&OMMC7VJ,4H<WTA_P[F//[>LB)Y.WO]2T9-F+WJ/
+M1)_65_HDB3YMBSYI1)^V19^V19]FT;/F8+Z!YO/Z0I\ES>=MS6>-YO.VYO.V
+MYG.B>=<L-.>2Q_]&SZH9/(IVZ:CP2T>583HJ'--189F.L_)9^&-47@@W@G#9
+M)VJ,HLXI:JRBQBL"L]@\1N&%;A+LL6@=C<([&I5Y-`KW:!3VT2S]XR!['W07
+MLJVPW**9-`HW:51VTBC\I%$82K-PE*/J(+M0[83%%MVE4=A+H_*71F$PC<)A
+MFM)B>M%>=2&Z%99:=)M&83>-RF\:A>$T"L?I_W-5^T1T<"C>JF2:.V&A1?=I
+M%/;3J/RG41A0HW"@XS'[1#.;LE%S)EGPHD;T949AS(S*F1F%-3,*;S8<$XK[
+M(#G:4+^7*#X)BRR:,J-P949ERXS"EQF%,1N."96^UQ@%>\6)X+.PQ*(C,PI+
+M9E2>S"A,F5&XLN&8W12^)KUCCK[/-^+1<7V%271CI'!CI')CI'!CI'!CE+BQ
+M6>^C7^^HUW:7>_-+ONW!4VSNOWB*=1;K+-99_)^8Q4]\(A"J4Q*K4U)4IZ2J
+M3DE1G9*B.B54G8;OAJ>\)Q2E)/^>H?E!0_>+AN8G#<UO&K0F=U(KU*(DUJ*D
+MJ$5)58N2HA8E12U*%JF]#WO!PI%0@9)8@9*B`B55!4J*"I04%2@YH/4^?3=.
+M0MU)8MU)BKJ35'4G*>I.4M2=U"ZEWN>?`4@H-TDL-TE1;I*JW"1%N4F*<I.Z
+MA=31D4]2A3*3Q#*3%&4FJ<I,4I29I"@SJ2^E^MICDBK4ER36EZ2H+TE57Y*B
+MOB1%?4FG0FJHLB:I0F5)8F5)BLJ25)4E*2I+4E26=,ZE!J635"O4E%:L*:VB
+MIK2JFM(J:DJKJ"GM,9/*2F>I@FNRHFNR"M=D5:[)*ER35;@FF[FFJ'26*C@F
+M*SHFJW!,5N68K,(Q685CLJECFI3.4@6[9.7[0#0W@NCN!-'<"J*Y%R2Q2[/2
+M6:K@EJSHEJS"+5F56[(*MV05;LEF;BDJG:4*;LF*;LDJW))5N26K<$M6X99L
+MZI8FI;-4P2U9T2U9A5NR*K=D%6[)*MR23=S2K'26*K@E*[HEJW!+5N66K,(M
+M685;LHE;.BQO/;:"6[*B6[(*MV15;LDJW))5N"5[6JM9IR?R5U=5=$M6X9:L
+MRBU9A5NR"K=DSZ)4)[@E)[HEIW!+3N66G,(M.85;\CT,[NM2!;?D1+?D%&[)
+MJ=R24[@EIW!+XS%W854%M^1$M^04;LFIW))3N"6G<$O#,7?I!!;<DA/=DE.X
+M):=R2T[AEIS"+86>!^M2!;?DY'MG-3?/ZNZ>=9>G3:GC,5M2!S1?B:](%=R2
+M$]V24[@EIW)+PU$OFU+;R\=-J>TE5.(K4@6WY$2WY!1NR:G<TG#4MM1.(;6[
+M'*1K57!+3G1+3N&6G,HM#4>]WI0Z'K,EM9?SJN"6G.B6G,(M.<DM-9-4R2VQ
+M4LDLL5#9*SG!*SG1*SF%5W*"5V*1@D]BC8)+8HFR1VH%C]2*'JE5>*1VW2--
+M1UF$4ZYENVZ1^';^HRQ3\$>MZ(]:A3]J5_T1"S1;Z]BN^B*69V1Y@B=J14_4
+M*CQ1N^:)$@D6X2Q6<<T2L<BU7]N"1L$,M:(9:E?,4)-J7#-#+,YNKN"*!V)I
+M%DL+R@3OTV+OP\*<0IA3+9[;7CS\/5%L2]@ZJ#`(%!Q/"QT/ZX-^AW5!G\-J
+MX'=!+`-^!\0:6J@AJA#,3`O,S$M4@:P,B^A4B]-M+P[ZNH=%=<+"(-/"BH!G
+M83W]NIY>OHKZS:L(?)?#,GI!!C(D+&/I$UC%THJPAJ7_8/9X*!?^D)-FSB>!
+M\]);,.-%TF?""TL1)WWA(^)T+T:*L[QP#?$B7IB%\#3<PB3PHW!EXN:'X$IG
+MP`^^E6:`'W5#@[CP=@G9^K?7IK0KDCR?`EV1?9EDGM?CPWE%)F>*8`07WEU,
+M85=DZL"LR,],C/#T92F9>64IF%D1GK@LR3(I$F8MRZO,+$UWS"I-HDPJS9G,
+MJ?R@"V\5=/)L&&BD29!9.#P_2=9C(DF.8QX.STV2PYB*D+:Z)&TQHSFQ,)<Y
+M0S&5.2TQD_PC+KR149BS3H"=\PRCQOC/F%,^8<@IB3!B>K@+NRG<E`\"VI0"
+M&*S/P6*P9ZP8X!FJSZ%B]&:D&+(#4`S2C'/*<3@<,PS_D5'"'F-PL&4(CK`!
+M@4,J`YQS@!`^>?SS-*+-#W1A=QH_!,3PZ&B(@ORPZ'$:P?`.CQUV^&G/:=N%
+M;1ZV]U$LC.J#%H>J<8?SD]^,3Y;&M^V\Z>;-UF_.P\5NI\=I;QJQF7JRIGLV
+>.?"2C#BW34UWQQ.;K+_C\C-JOWWU+THZ&OFDJ0``
+`
+end
diff --git a/sys/arch/i386/isa/pcvt/Util/demo/outerlimit.vt.gz.uu b/sys/arch/i386/isa/pcvt/Util/demo/outerlimit.vt.gz.uu
new file mode 100644
index 00000000000..a2b6d1a2e50
--- /dev/null
+++ b/sys/arch/i386/isa/pcvt/Util/demo/outerlimit.vt.gz.uu
@@ -0,0 +1,193 @@
+begin 644 outerlimit.vt.gz
+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
+#^0``
+`
+end
diff --git a/sys/arch/i386/isa/pcvt/Util/demo/playvt.c b/sys/arch/i386/isa/pcvt/Util/demo/playvt.c
new file mode 100644
index 00000000000..d0a391ff6b4
--- /dev/null
+++ b/sys/arch/i386/isa/pcvt/Util/demo/playvt.c
@@ -0,0 +1,111 @@
+/*
+ * Copyright (c) 1995 Hellmuth Michaelis
+ *
+ * All rights reserved.
+ *
+ * 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 Hellmuth Michaelis
+ * 4. The name authors may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ */
+
+static char *id =
+ "@(#)playvt.c, 1.00, Last Edit-Date: [Sun Jan 1 18:32:22 1995]";
+
+/*---------------------------------------------------------------------------*
+ *
+ * history:
+ *
+ * -hm want to see my xmas greeting ... :-)
+ *
+ *---------------------------------------------------------------------------*/
+
+#include <stdio.h>
+#include <unistd.h>
+
+main(argc,argv)
+int argc;
+char *argv[];
+{
+ extern int optind;
+ extern int opterr;
+ extern char *optarg;
+
+ int c;
+ FILE *fp = stdin;
+ volatile int i;
+ int delay = 0;
+ int fflag = -1;
+ char *filename;
+
+ while( (c = getopt(argc, argv, "d:f:")) != EOF)
+ {
+ switch(c)
+ {
+ case 'd':
+ delay = atoi(optarg);
+ break;
+
+ case 'f':
+ filename = optarg;
+ fflag = 1;
+ break;
+
+ case '?':
+ default:
+ usage();
+ break;
+ }
+ }
+
+ if(fflag == 1)
+ {
+ if((fp = fopen(filename, "r")) == NULL)
+ {
+ char buffer[80];
+ strcpy(buffer,"ERROR opening file ");
+ strcat(buffer,filename);
+ perror(buffer);
+ exit(1);
+ }
+ }
+
+ while((c = getc(fp)) != EOF)
+ {
+ putchar(c);
+ for(i = delay; i > 0; i--)
+ ;
+ }
+}
+
+
+usage()
+{
+ fprintf(stderr,"\nplayvt - play a VT animation with programmable delay\n");
+ fprintf(stderr,"usage: playvt -f [filename] -d [delay]\n");
+ fprintf(stderr," -f <filename> file containing the animation\n");
+ fprintf(stderr," -d <delay> delay between characters\n");
+ exit(1);
+}
+
diff --git a/sys/arch/i386/isa/pcvt/Util/demo/sgr.vt.gz.uu b/sys/arch/i386/isa/pcvt/Util/demo/sgr.vt.gz.uu
new file mode 100644
index 00000000000..099c3a49672
--- /dev/null
+++ b/sys/arch/i386/isa/pcvt/Util/demo/sgr.vt.gz.uu
@@ -0,0 +1,11 @@
+begin 664 sgr.vt.gz
+M'XL("):V^BX"`W-G<BYV=`"%44U/@T`0/2]_H9<Y:AH;MMT5#?&`L*D8^Q&H
+MIYYJNU0BA0:HO]]AV18L&"=D=LE[,^\]&*Q-VXP&ZU=CL#8/)!1OPEW!-'"6
+M+[X+@9A[_LI?S,$3L\4\7`6.>KOQA!M.`W@"$;JP+&Q\1B/L<+@U#"**[>8H
+M"0ED<4K*.-W#/M\</^,MY#+=Q66<I0:Y4T7TV5NU)Y3`0UV)DR3@E&4>?YQ*
+M64`610V'(H<BAP(\9\FN`1@"#($QP'NZDWD2I[)!.:(<T0F.(?*%=AO00M!"
+MD`$$\EOF16N0VM7BJA->2PY[UE.;*Q9*W&M65X;:EB*AE*5)'3FF%E6=/+2"
+M]&QC:EO5R6.;V5G)%;'JA)J7],.^I#J%DJ?T*FUO(J8S*1]T?#W2(\+U1&UH
+F\OMC=0<L[<K2KMCY%_UKC%^LU5+\KSQGT6K:P/H!L`MLDRX#``#2
+`
+end
diff --git a/sys/arch/i386/isa/pcvt/Util/demo/twzone.vt.gz.uu b/sys/arch/i386/isa/pcvt/Util/demo/twzone.vt.gz.uu
new file mode 100644
index 00000000000..df05d50b2ce
--- /dev/null
+++ b/sys/arch/i386/isa/pcvt/Util/demo/twzone.vt.gz.uu
@@ -0,0 +1,350 @@
+begin 644 twzone.vt.gz
+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
+0]]ZO?G=^^'_[0&'EA?,``'E+
+`
+end
diff --git a/sys/arch/i386/isa/pcvt/Util/demo/xmas.vt.gz.uu b/sys/arch/i386/isa/pcvt/Util/demo/xmas.vt.gz.uu
new file mode 100644
index 00000000000..ca2ba3ada79
--- /dev/null
+++ b/sys/arch/i386/isa/pcvt/Util/demo/xmas.vt.gz.uu
@@ -0,0 +1,110 @@
+begin 644 xmas.vt.gz
+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
+LK:O,4Y_?D[\>]SORP^WQS>WV]N?PK-K59<Q^3M6?Q'9Q/?LG-?=D49*R``"?
+`
+end
diff --git a/sys/arch/i386/isa/pcvt/Util/fed/Makefile b/sys/arch/i386/isa/pcvt/Util/fed/Makefile
new file mode 100644
index 00000000000..9e4503a7b13
--- /dev/null
+++ b/sys/arch/i386/isa/pcvt/Util/fed/Makefile
@@ -0,0 +1,6 @@
+PROG= fed
+SRCS= fed.c select.c edit.c misc.c
+LDADD= -lncurses
+BINDIR= /usr/local/bin
+
+.include <bsd.prog.mk>
diff --git a/sys/arch/i386/isa/pcvt/Util/fed/edit.c b/sys/arch/i386/isa/pcvt/Util/fed/edit.c
new file mode 100644
index 00000000000..c15a90ceb6d
--- /dev/null
+++ b/sys/arch/i386/isa/pcvt/Util/fed/edit.c
@@ -0,0 +1,340 @@
+/*
+ * Copyright (c) 1992, 1993, 1994 by Hellmuth Michaelis
+ *
+ * All rights reserved.
+ *
+ * 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 Hellmuth Michaelis.
+ * 4. The name of the developer may not be used to endorse or promote
+ * products derived from this software without specific prior written
+ * permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE DEVELOPER ``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 DEVELOPERS 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.
+ *
+ * edit.c, 3.00, last edit-date: [Sun Jan 2 20:08:27 1994]
+ */
+
+/*---------------------------------------------------------------------------
+ *
+ * edit.c font editor edit character
+ * ------------------------------------------
+ *
+ * written by Hellmuth Michaelis, hm@hcshh.hcs.de
+ *
+ * -hm first public release
+ * -hm some debugging & cleanup
+ *
+ *---------------------------------------------------------------------------*/
+
+#include "fed.h"
+
+#define UP 0
+#define DOWN 1
+
+static int pen;
+
+/*---------------------------------------------------------------------------*
+ * fill edit mode command window
+ *---------------------------------------------------------------------------*/
+void edit_mode(void)
+{
+ mvwprintw(cmd_win,1,1,"(W)hite ");
+ mvwprintw(cmd_win,2,1,"(Black ");
+ mvwprintw(cmd_win,3,1,"(I)nvert ");
+ mvwprintw(cmd_win,4,1,"(R)ow BLACK ");
+ mvwprintw(cmd_win,5,1,"(r)ow WHITE ");
+ mvwprintw(cmd_win,6,1,"(C)ol BLACK ");
+ mvwprintw(cmd_win,7,1,"(c)ol WHITE ");
+ mvwprintw(cmd_win,8,1,"(Q)uit/Save ");
+
+ mvwprintw(cmd_win,9 ,1,"e(X)it/undo ");
+ mvwprintw(cmd_win,10,1,"Pen (U)p ");
+ mvwprintw(cmd_win,11,1,"Pen (D)own ");
+ mvwprintw(cmd_win,12,1," ");
+ mvwprintw(cmd_win,13,1,"(^P)rev Line");
+ mvwprintw(cmd_win,14,1,"(^N)ext Line");
+ mvwprintw(cmd_win,15,1,"(^F)orwd Col");
+ mvwprintw(cmd_win,16,1,"(^B)ack Col");
+ wrefresh(cmd_win);
+}
+
+/*---------------------------------------------------------------------------*
+ * edit mode command loop
+ *---------------------------------------------------------------------------*/
+int edit(void)
+{
+ int c, r;
+ char l;
+ unsigned int k_ch;
+
+ c = r = 0;
+
+ pen = UP;
+
+ for(;;)
+ {
+ if(pen == DOWN)
+ dis_cmd(" Edit Mode, the Pen is DOWN");
+ else
+ dis_cmd(" Edit Mode, the Pen is UP");
+
+ l = ((mvwinch(ch_win,(r+1),(c+1))) & A_CHARTEXT);
+ wattron(ch_win,A_REVERSE);
+ mvwprintw(ch_win,(r+1),(c+1),"%c",l);
+ wattroff(ch_win,A_REVERSE);
+ wmove(ch_win,(r+1),(c+1));
+ wrefresh(ch_win);
+
+ k_ch = wgetch(ch_win);
+
+ switch(k_ch)
+ {
+ case K_LEFT:
+ case KEY_LEFT:
+ if(c > 0)
+ {
+ normal_ch(r,c);
+ c--;
+ }
+ break;
+
+ case K_DOWN:
+ case KEY_DOWN:
+ if(r < (ch_height-1))
+ {
+ normal_ch(r,c);
+ r++;
+ }
+ break;
+
+ case K_UP:
+ case KEY_UP:
+ if(r > 0)
+ {
+ normal_ch(r,c);
+ r--;
+ }
+ break;
+
+ case K_RIGHT:
+ case KEY_RIGHT:
+ if(c < (ch_width-1))
+ {
+ normal_ch(r,c);
+ c++;
+ }
+ break;
+
+ case KEY_HOME:
+ normal_ch(r,c);
+ c = r = 0;
+ break;
+
+ case KEY_LL:
+ normal_ch(r,c);
+ c = ch_width-1;
+ r = ch_height-1;
+ break;
+
+ case 0x0c:
+ wrefresh(curscr);
+ break;
+
+ case '\n':
+ case '\r':
+ case ' ' :
+ chg_pt(r,c);
+ break;
+
+ case 'q':
+ pen = UP;
+ normal_ch(r,c);
+ wrefresh(ch_win);
+ return(1);
+ break;
+
+ case 'x':
+ pen = UP;
+ normal_ch(r,c);
+ wrefresh(ch_win);
+ return(0);
+ break;
+
+ case 'w':
+ case 'W':
+ setchr(WHITE);
+ break;
+
+ case 'b':
+ case 'B':
+ setchr(BLACK);
+ break;
+
+ case 'i':
+ case 'I':
+ invert();
+ break;
+
+ case 'r':
+ setrow(WHITE);
+ break;
+
+ case 'R':
+ setrow(BLACK);
+ break;
+
+ case 'c':
+ setcol(WHITE);
+ break;
+
+ case 'C':
+ setcol(BLACK);
+ break;
+
+ case 'u':
+ case 'U':
+ pen = UP;
+ break;
+
+ case 'd':
+ case 'D':
+ pen = DOWN;
+ break;
+
+ default:
+ beep();
+ break;
+
+ }
+ }
+}
+
+/*---------------------------------------------------------------------------*
+ *
+ *---------------------------------------------------------------------------*/
+void normal_ch(int r, int c)
+{
+ char l = ((mvwinch(ch_win,(r+1),(c+1))) & A_CHARTEXT);
+ wattroff(ch_win,A_REVERSE);
+ if(pen == DOWN)
+ mvwprintw(ch_win,(r+1),(c+1),"*");
+ else
+ mvwprintw(ch_win,(r+1),(c+1),"%c",l);
+ wmove(ch_win,(r+1),(c+1));
+}
+
+/*---------------------------------------------------------------------------*
+ *
+ *---------------------------------------------------------------------------*/
+void chg_pt(int r, int c)
+{
+ char l;
+ l = ((mvwinch(ch_win,(r+1),(c+1))) & A_CHARTEXT);
+ if(l == WHITE)
+ l = BLACK;
+ else
+ l = WHITE;
+ mvwprintw(ch_win,(r+1),(c+1),"%c",l);
+ wmove(ch_win,(r+1),(c+1));
+}
+
+/*---------------------------------------------------------------------------*
+ * invert current character
+ *---------------------------------------------------------------------------*/
+void invert(void)
+{
+ int r,c;
+
+ r = 1;
+
+ while(r <= ch_height)
+ {
+ c = 1;
+ while(c <= ch_width)
+ {
+ if(WHITE == mvwinch(ch_win, r, c))
+ mvwaddch(ch_win, r, c, BLACK);
+ else
+ mvwaddch(ch_win, r, c, WHITE);
+ c++;
+ }
+ r++;
+ }
+}
+
+/*---------------------------------------------------------------------------*
+ * fill current character black/white
+ *---------------------------------------------------------------------------*/
+void setchr(char type)
+{
+ int r,c;
+
+ r = 1;
+
+ while(r <= ch_height)
+ {
+ c = 1;
+ while(c <= ch_width)
+ {
+ mvwaddch(ch_win, r, c, type);
+ c++;
+ }
+ r++;
+ }
+}
+
+/*---------------------------------------------------------------------------*
+ * set current row to black/white
+ *---------------------------------------------------------------------------*/
+void setrow(char type)
+{
+ int r,c;
+
+ getyx(ch_win,r,c);
+
+ c = 1;
+
+ while(c <= ch_width)
+ {
+ mvwaddch(ch_win, r, c, type);
+ c++;
+ }
+}
+
+/*---------------------------------------------------------------------------*
+ * set current column to black/white
+ *---------------------------------------------------------------------------*/
+void setcol(char type)
+{
+ int r,c;
+
+ getyx(ch_win,r,c);
+
+ r = 1;
+
+ while(r <= ch_height)
+ {
+ mvwaddch(ch_win, r, c, type);
+ r++;
+ }
+}
+
+/*---------------------------------- E O F ----------------------------------*/
diff --git a/sys/arch/i386/isa/pcvt/Util/fed/fed.1 b/sys/arch/i386/isa/pcvt/Util/fed/fed.1
new file mode 100644
index 00000000000..4b49671f336
--- /dev/null
+++ b/sys/arch/i386/isa/pcvt/Util/fed/fed.1
@@ -0,0 +1,52 @@
+.\" Copyright (c) 1992, 1995 Hellmuth Michaelis
+.\"
+.\" All rights reserved.
+.\"
+.\" 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 Hellmuth Michaelis
+.\" 4. The name authors may not be used to endorse or promote products
+.\" derived from this software without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``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 AUTHORS 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.
+.\"
+.\" @(#)fed.1, 3.30, Last Edit-Date: [Wed Jul 5 19:25:39 1995]
+.\"
+.Dd July 3, 1995
+.Dt FED 1
+.Sh NAME
+.Nm fed
+.Nd font editor for pcvt's EGA/VGA download fonts
+.Sh SYNOPSIS
+.Nm fed
+.Op filename
+.Sh DESCRIPTION
+The
+.Nm fed
+utility allows a user to edit or create EGA/VGA download fontfiles to be
+used by the
+.Nm pcvt
+device driver.
+.Pp
+.Sh BUGS
+No known bugs
+.Sh SEE ALSO
+.Xr pcvt 4
+.Xr loadfont 1
diff --git a/sys/arch/i386/isa/pcvt/Util/fed/fed.c b/sys/arch/i386/isa/pcvt/Util/fed/fed.c
new file mode 100644
index 00000000000..aa577ab9897
--- /dev/null
+++ b/sys/arch/i386/isa/pcvt/Util/fed/fed.c
@@ -0,0 +1,168 @@
+/*
+ * Copyright (c) 1992, 1993, 1994 by Hellmuth Michaelis
+ *
+ * All rights reserved.
+ *
+ * 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 Hellmuth Michaelis.
+ * 4. The name of the developer may not be used to endorse or promote
+ * products derived from this software without specific prior written
+ * permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE DEVELOPER ``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 DEVELOPERS 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.
+ *
+ * fed.c, 3.00, last edit-date: [Sun Jan 2 20:08:45 1994]
+ */
+
+/*---------------------------------------------------------------------------
+ *
+ * fed.c font editor main file
+ * -------------------------------------
+ *
+ * written by Hellmuth Michaelis, hm@hcshh.hcs.de
+ *
+ * -hm first public release
+ * -hm activating font save
+ *
+ *---------------------------------------------------------------------------*/
+
+#define FED
+
+#include "fed.h"
+
+void main(int argc, char *argv[])
+{
+ int i;
+ int row, col;
+ int ret;
+
+ if(argc != 2)
+ {
+ fprintf(stderr,"EGA/VGA Fonteditor, Rel 1.00\n");
+ fprintf(stderr,"usage: %s <fontfilename>\n",argv[0]);
+ exit(1);
+ }
+
+ readfont(argv[1]); /* read fontfile into memory */
+
+ initscr();
+ cbreak();
+ noecho();
+ nonl();
+ keypad(stdscr,TRUE);
+ idlok(stdscr, TRUE);
+
+ move(0,0);
+ standout();
+ addstr(" Interactive EGA/VGA Fonteditor - (c) 1993, 1994 Hellmuth Michaelis ");
+ standend();
+
+/* character horizontal ruler */
+
+ move(WINROW-1, CHCOL + ((WIDTH16 - ch_width)/2) + 1);
+ if(ch_width == WIDTH16)
+ addstr("1234567890123456");
+ else
+ addstr("12345678");
+
+/* charcater vertical ruler */
+
+ for(i=1; i < ch_height+1; i++)
+ mvprintw((WINROW+i), (CHCOL + ((WIDTH16 - ch_width)/2) - 2), "%2d", i);
+
+
+/* select horizontal ruler */
+
+ move(WINROW-1,SETCOL+2);
+ addstr("0 1 2 3 4 5 6 7 8 9 A B C D E F ");
+
+/* select vertical ruler */
+
+ for(i=0; i<10; i++)
+ mvaddch((WINROW+i+1),(SETCOL-1),(i+'0'));
+ for(i=0; i<6; i++)
+ mvaddch((WINROW+10+i+1),(SETCOL-1),(i+'A'));
+
+/* label available commands window */
+
+ move(WINROW-1,CMDCOL+1);
+ addstr("Commands");
+
+ refresh();
+
+/* command window */
+
+ cmd_win = newwin(((WSIZE)+(2*WBORDER)),(CMDSIZE+(2*WBORDER)),
+ WINROW,CMDCOL);
+ keypad(cmd_win,TRUE);
+ idlok(cmd_win, TRUE);
+ box(cmd_win,'|','-');
+
+ sel_mode();
+
+/* character font window */
+
+ ch_win = newwin((ch_height+(2*WBORDER)),(ch_width+(2*WBORDER)),
+ WINROW, CHCOL+((WIDTH16 - ch_width)/2));
+ keypad(ch_win,TRUE);
+ idlok(ch_win, TRUE);
+
+ box(ch_win,'|','-');
+ wrefresh(ch_win);
+
+/* character select window */
+
+ set_win = newwin((WSIZE+(2*WBORDER)),((WSIZE*2)+(2*WBORDER)),
+ WINROW,SETCOL); /* whole character set */
+ keypad(set_win,TRUE);
+ idlok(set_win, TRUE);
+
+ box(set_win,'|','-');
+
+ row = 0;
+ col = 0;
+
+ for(i=0; i<256; i++)
+ {
+ mvwprintw(set_win,row+1,col+1,"%02.2X",i);
+ if(++row > 15)
+ {
+ row = 0;
+ col += 2;
+ }
+ }
+ wmove(set_win,1,1);
+ wrefresh(set_win);
+
+/* start */
+
+ clr_cmd();
+
+ curchar = 0;
+
+ if((ret = selectc()) == 1)
+ {
+ writefont();
+ }
+ endwin();
+}
+
+/*---------------------------------- E O F ----------------------------------*/
diff --git a/sys/arch/i386/isa/pcvt/Util/fed/fed.h b/sys/arch/i386/isa/pcvt/Util/fed/fed.h
new file mode 100644
index 00000000000..27a32c35526
--- /dev/null
+++ b/sys/arch/i386/isa/pcvt/Util/fed/fed.h
@@ -0,0 +1,127 @@
+/*
+ * Copyright (c) 1992, 1993, 1994 by Hellmuth Michaelis
+ *
+ * All rights reserved.
+ *
+ * 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 Hellmuth Michaelis.
+ * 4. The name of the developer may not be used to endorse or promote
+ * products derived from this software without specific prior written
+ * permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE DEVELOPER ``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 DEVELOPERS 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.
+ *
+ * fed.h, 3.00, last edit-date: [Sun Jan 2 20:10:31 1994]
+ */
+
+#include <ncurses.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#ifdef FED
+
+int ch_height;
+int ch_width;
+
+int curchar;
+
+WINDOW *ch_win;
+WINDOW *set_win;
+WINDOW *cmd_win;
+
+#else
+
+extern int ch_height; /* current fontfile character dimensions */
+extern int ch_width;
+
+extern int curchar; /* character being edited */
+
+extern WINDOW *ch_win; /* windows */
+extern WINDOW *set_win;
+extern WINDOW *cmd_win;
+
+#endif
+
+#define FONTCHARS 256 /* no of chars in a fontfile */
+
+#define WHITE ('.')
+#define BLACK ('*')
+
+#define K_UP 0x10 /* ^P */
+#define K_DOWN 0x0e /* ^N */
+#define K_RIGHT 0x06 /* ^F */
+#define K_LEFT 0x02 /* ^B */
+
+#define WINROW 3
+#define CMDCOL 3
+#define CHCOL 20
+#define SETCOL 41
+#define WSIZE 16
+#define CMDSIZE 12
+#define WBORDER 1
+
+/* fonts */
+
+#define WIDTH8 8 /* 8 bits wide font */
+#define WIDTH16 16 /* 16 bits wide font */
+
+#define FONT8X8 2048 /* filesize for 8x8 font */
+#define HEIGHT8X8 8 /* 8 scan lines char cell height */
+
+#define FONT8X10 2560 /* filesize for 8x10 font */
+#define HEIGHT8X10 10 /* 10 scan lines char cell height */
+
+#define FONT8X14 3584 /* filesize for 8x14 font */
+#define HEIGHT8X14 14 /* 14 scan lines char cell height */
+#define WIDTH8X14 8 /* 8 bits wide font */
+
+#define FONT8X16 4096 /* filesize for 8x16 font */
+#define HEIGHT8X16 16 /* 16 scan lines char cell height */
+
+#define FONT16X16 8192 /* filesize for 16x16 font */
+#define HEIGHT16X16 16 /* 16 scan lines char cell height */
+
+
+void edit_mode ( void );
+int edit ( void );
+void normal_ch ( int r, int c );
+void chg_pt ( int r, int c );
+void invert ( void );
+void setchr ( char type );
+void setrow ( char type );
+void setcol ( char type );
+void main ( int argc, char *argv[] );
+void readfont ( char *filename );
+void dis_cmd ( char *strg );
+void clr_cmd ( void );
+void save_ch ( void );
+void move_ch ( int src, int dest );
+void xchg_ch ( int src, int dest );
+void display ( int no );
+void sel_mode ( void );
+int selectc ( void );
+void normal_set ( int r, int c );
+int sel_dest ( void );
+void normal_uset ( int r, int c );
+void writefont( void );
+
+/* ------------------------------ EOF ----------------------------------- */
diff --git a/sys/arch/i386/isa/pcvt/Util/fed/misc.c b/sys/arch/i386/isa/pcvt/Util/fed/misc.c
new file mode 100644
index 00000000000..a0dff32703a
--- /dev/null
+++ b/sys/arch/i386/isa/pcvt/Util/fed/misc.c
@@ -0,0 +1,353 @@
+/*
+ * Copyright (c) 1992, 1993, 1994 by Hellmuth Michaelis
+ *
+ * All rights reserved.
+ *
+ * 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 Hellmuth Michaelis.
+ * 4. The name of the developer may not be used to endorse or promote
+ * products derived from this software without specific prior written
+ * permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE DEVELOPER ``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 DEVELOPERS 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.
+ *
+ * misc.c, 3.00, last edit-date: [Sun Jan 2 20:09:21 1994]
+ */
+
+/*---------------------------------------------------------------------------
+ *
+ * misc.c font editor misc routines
+ * -----------------------------------------
+ *
+ * written by Hellmuth Michaelis, hm@hcshh.hcs.de
+ *
+ * -hm first public release
+ * -hm writefont routine
+ *
+ *---------------------------------------------------------------------------*/
+
+#include "fed.h"
+
+#include <stdlib.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+
+static unsigned char *fonttab; /* ptr to font in core memory */
+
+static char *bitmask[] = {
+ "....", /* 0 */
+ "...*", /* 1 */
+ "..*.", /* 2 */
+ "..**", /* 3 */
+ ".*..", /* 4 */
+ ".*.*", /* 5 */
+ ".**.", /* 6 */
+ ".***", /* 7 */
+ "*...", /* 8 */
+ "*..*", /* 9 */
+ "*.*.", /* A */
+ "*.**", /* B */
+ "**..", /* C */
+ "**.*", /* D */
+ "***.", /* E */
+ "****", /* F */
+ NULL };
+
+static char lfilename[1024]; /* current filename */
+static unsigned int lfilesize; /* current filename's size */
+
+/*---------------------------------------------------------------------------*
+ * read fontfile into memory
+ *---------------------------------------------------------------------------*/
+void readfont(char *filename)
+{
+ FILE *in;
+ struct stat sbuf, *sbp;
+ int ret;
+ char buffer[1024];
+
+ sbp = &sbuf;
+
+ if((in = fopen(filename, "r")) == NULL)
+ {
+ sprintf(buffer, "cannot open file %s for reading", filename);
+ perror(buffer);
+ exit(1);
+ }
+
+ if((fstat(fileno(in), sbp)) != 0)
+ {
+ sprintf(buffer, "cannot fstat file %s", filename);
+ perror(buffer);
+ exit(1);
+ }
+
+ switch(sbp->st_size)
+ {
+ case FONT8X8:
+ ch_height = HEIGHT8X8;
+ ch_width = WIDTH8;
+ break;
+
+ case FONT8X10:
+ ch_height = HEIGHT8X10;
+ ch_width = WIDTH8;
+ break;
+
+ case FONT8X14:
+ ch_height = HEIGHT8X14;
+ ch_width = WIDTH8;
+ break;
+
+ case FONT8X16:
+ ch_height = HEIGHT8X16;
+ ch_width = WIDTH8;
+ break;
+
+ case FONT16X16:
+ ch_height = HEIGHT16X16;
+ ch_width = WIDTH16;
+ break;
+
+ default:
+ fprintf(stderr,"error, file %s is no valid font file, size=%d\n",filename,sbp->st_size);
+ exit(1);
+ }
+
+ if((fonttab = (unsigned char *)malloc((size_t)sbp->st_size)) == NULL)
+ {
+ fprintf(stderr,"error, malloc failed\n");
+ exit(1);
+ }
+
+ strcpy(lfilename, filename); /* save for write */
+ lfilesize = sbp->st_size; /* save for write */
+
+ if((ret = fread(fonttab, sizeof(*fonttab), sbp->st_size, in)) != sbp->st_size)
+ {
+ sprintf(buffer,"error reading file %s, size = %d, ret = %d\n",filename,sbp->st_size, ret);
+ perror(buffer);
+ exit(1);
+ }
+}
+
+/*---------------------------------------------------------------------------*
+ * write fontfile to disk
+ *---------------------------------------------------------------------------*/
+void writefont()
+{
+ FILE *in, *out;
+ int ret;
+ char buffer[1024];
+
+ if((in = fopen(lfilename, "r")) != NULL)
+ {
+ int c;
+ char wfn[1024];
+
+ strcpy(wfn, lfilename);
+ strcat(wfn, ".BAK");
+ if((out = fopen(wfn, "w")) == NULL)
+ {
+ sprintf(buffer, "cannot open file %s for writing", wfn);
+ perror(buffer);
+ exit(1);
+ }
+
+ while(( c = fgetc(in) ) != EOF )
+ fputc(c, out);
+
+ fclose(out);
+ fclose(in);
+ }
+
+ if((out = fopen(lfilename, "w")) == NULL)
+ {
+ sprintf(buffer, "cannot open file %s for writing", lfilename);
+ perror(buffer);
+ exit(1);
+ }
+
+ if((ret = fwrite(fonttab, sizeof(*fonttab), lfilesize, out)) != lfilesize)
+ {
+ sprintf(buffer,"error writing file %s, size=%d, ret=%d\n",lfilename,lfilesize, ret);
+ perror(buffer);
+ exit(1);
+ }
+}
+
+/*---------------------------------------------------------------------------*
+ * display a string
+ *---------------------------------------------------------------------------*/
+void dis_cmd(char *strg)
+{
+ move(22,0);
+ clrtoeol();
+ mvaddstr(22,0,strg);
+ refresh();
+}
+
+/*---------------------------------------------------------------------------*
+ * clear a command string
+ *---------------------------------------------------------------------------*/
+void clr_cmd(void)
+{
+ move(22,0);
+ clrtoeol();
+ refresh();
+}
+
+/*---------------------------------------------------------------------------*
+ * move char from src to dest
+ *---------------------------------------------------------------------------*/
+void move_ch(int src, int dst)
+{
+ unsigned char *s, *d;
+ int offset = 0;
+
+ if(ch_width == WIDTH16)
+ offset = 2;
+ else
+ offset = 1;
+
+ s = &(fonttab[ch_height * offset * src]);
+ d = &(fonttab[ch_height * offset * dst]);
+
+ bcopy(s, d, (ch_height*offset)); /* src -> dst */
+}
+
+/*---------------------------------------------------------------------------*
+ * exchange char's src and dest
+ *---------------------------------------------------------------------------*/
+void xchg_ch(int src, int dst)
+{
+ unsigned char *s, *d;
+ unsigned char buf[32];
+ int offset = 0;
+
+ if(ch_width == WIDTH16)
+ offset = 2;
+ else
+ offset = 1;
+
+ s = &(fonttab[ch_height * offset * src]);
+ d = &(fonttab[ch_height * offset * dst]);
+
+ bcopy(s, buf, (ch_height*offset)); /* src -> tmp */
+ bcopy(d, s, (ch_height*offset)); /* dst -> src */
+ bcopy(buf, d, (ch_height*offset)); /* tmp -> dst */
+}
+
+/*---------------------------------------------------------------------------*
+ * display the current selected character
+ *---------------------------------------------------------------------------*/
+void display(int no)
+{
+ unsigned char *fontchar;
+ char line[32];
+ int ln_no;
+ unsigned char hibyte;
+ unsigned char lobyte;
+ int offset;
+ int r;
+
+ offset = 0;
+ r = 1;
+ lobyte = 0;
+
+ if(ch_width == WIDTH16)
+ fontchar = &(fonttab[ch_height * 2 * no]);
+ else
+ fontchar = &(fonttab[ch_height * no]);
+
+ for (ln_no = 0; ln_no < ch_height; ln_no++)
+ {
+ hibyte = *(fontchar + (offset++));
+
+ if(ch_width == WIDTH16)
+ {
+ lobyte = *(fontchar + offset++);
+ }
+
+ strcpy(line,bitmask[(int)((hibyte >> 4) & 0x0f)]);
+ strcat(line,bitmask[(int)(hibyte & 0x0f)]);
+
+ if(ch_width == WIDTH16)
+ {
+ strcat(line,bitmask[(int)((lobyte >> 4) & 0x0f)]);
+ strcat(line,bitmask[(int)(lobyte & 0x0f)]);
+ mvwprintw(ch_win, r, 1, "%16.16s", line);
+ }
+ else
+ {
+ mvwprintw(ch_win, r, 1, "%8.8s", line);
+ }
+ r++;
+ }
+ wmove(ch_win, 1, 1);
+ wrefresh(ch_win);
+}
+
+/*---------------------------------------------------------------------------*
+ * save character
+ *---------------------------------------------------------------------------*/
+void save_ch(void)
+{
+ unsigned char *s;
+ int offset = 0;
+ int r, c;
+ unsigned short byte;
+ unsigned short shift;
+
+ if(ch_width == WIDTH16)
+ offset = 2;
+ else
+ offset = 1;
+
+ s = &(fonttab[ch_height * offset * curchar]);
+
+ r = 1;
+
+ while(r <= ch_height)
+ {
+ c = 1;
+ byte = 0;
+ if(offset == 2)
+ shift = 0x8000;
+ else
+ shift = 0x80;
+
+ while(c <= ch_width)
+ {
+ if(mvwinch(ch_win, r, c) == BLACK)
+ byte |= shift;
+ shift = (shift >> 1);
+ c++;
+ }
+ *s++ = byte;
+ r++;
+ }
+}
+
+/*---------------------------------- E O F ----------------------------------*/
+
+
diff --git a/sys/arch/i386/isa/pcvt/Util/fed/select.c b/sys/arch/i386/isa/pcvt/Util/fed/select.c
new file mode 100644
index 00000000000..6b9d3858cf7
--- /dev/null
+++ b/sys/arch/i386/isa/pcvt/Util/fed/select.c
@@ -0,0 +1,334 @@
+/*
+ * Copyright (c) 1992, 1993, 1994 by Hellmuth Michaelis
+ *
+ * All rights reserved.
+ *
+ * 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 Hellmuth Michaelis.
+ * 4. The name of the developer may not be used to endorse or promote
+ * products derived from this software without specific prior written
+ * permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE DEVELOPER ``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 DEVELOPERS 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.
+ *
+ * select.c, 3.00, last edit-date: [Sun Jan 2 20:09:36 1994]
+ */
+
+/*---------------------------------------------------------------------------
+ *
+ * select.c font editor select character
+ * ----------------------------------------------------
+ *
+ * written by Hellmuth Michaelis, hm@hcshh.hcs.de
+ *
+ * -hm first public release
+ * -hm debugging
+ *
+ *---------------------------------------------------------------------------*/
+
+#include "fed.h"
+
+int sc, sr, scurchar;
+
+int edit();
+
+void sel_mode(void)
+{
+ mvwprintw(cmd_win,1,1,"(E)dit ");
+ mvwprintw(cmd_win,2,1,"(M)ove ");
+ mvwprintw(cmd_win,3,1,"exchan(G)e ");
+ mvwprintw(cmd_win,4,1,"(Q)uit/Save ");
+ mvwprintw(cmd_win,5,1,"e(X)it/Undo ");
+ mvwprintw(cmd_win,6,1," ");
+ mvwprintw(cmd_win,7,1," ");
+ mvwprintw(cmd_win,8,1," ");
+
+ mvwprintw(cmd_win,9 ,1," ");
+ mvwprintw(cmd_win,10,1," ");
+ mvwprintw(cmd_win,11,1," ");
+ mvwprintw(cmd_win,12,1," ");
+ mvwprintw(cmd_win,13,1,"(^P)rev Line");
+ mvwprintw(cmd_win,14,1,"(^N)ext Line");
+ mvwprintw(cmd_win,15,1,"(^F)orwd Col");
+ mvwprintw(cmd_win,16,1,"(^B)ack Col");
+ wrefresh(cmd_win);
+}
+
+int selectc()
+{
+ int c, r;
+ int ret;
+ char h, l;
+ unsigned int k_ch;
+
+ c = (curchar / 16);
+ r = (curchar % 16);
+
+ for(;;)
+ {
+ dis_cmd(" Select Character");
+
+ sel_mode();
+
+ curchar = r + (c*16);
+
+ display(curchar);
+
+ h = ((mvwinch(set_win,(r+1),((c*2)+1))) & A_CHARTEXT);
+ l = ((mvwinch(set_win,(r+1),((c*2)+2))) & A_CHARTEXT);
+ wattron(set_win,A_REVERSE);
+ mvwprintw(set_win,(r+1),((c*2)+1),"%c%c",h,l);
+ wattroff(set_win,A_REVERSE);
+ wmove(set_win,(r+1),((c*2)+1));
+ wrefresh(set_win);
+
+ k_ch = wgetch(set_win);
+
+ switch(k_ch)
+ {
+ case K_LEFT:
+ case KEY_LEFT:
+ if(c > 0)
+ {
+ normal_set(r,c);
+ c--;
+ }
+ break;
+
+ case K_DOWN:
+ case KEY_DOWN:
+ if(r < 15)
+ {
+ normal_set(r,c);
+ r++;
+ }
+ break;
+
+ case K_UP:
+ case KEY_UP:
+ if(r > 0)
+ {
+ normal_set(r,c);
+ r--;
+ }
+ break;
+
+ case K_RIGHT:
+ case KEY_RIGHT:
+ if(c < 15)
+ {
+ normal_set(r,c);
+ c++;
+ }
+ break;
+
+ case 'e':
+ case 'E':
+ edit_mode();
+ dis_cmd(" Edit Character");
+ display(curchar);
+ ret = edit();
+ if(ret == 1)
+ save_ch();
+ break;
+
+ case 'g':
+ case 'G':
+ dis_cmd(" Exchange: select Destination, then press RETURN or any other Key to ABORT");
+ sr = r;
+ sc = c;
+ scurchar = curchar;
+ if((curchar = sel_dest()) == -1)
+ { /* failsafe */
+ r = sr;
+ c = sc;
+ curchar = scurchar;
+ }
+ else
+ { /* valid return */
+ normal_set(r,c);
+ c = (curchar / 16);
+ r = (curchar % 16);
+ xchg_ch(scurchar,curchar);
+ }
+ break;
+
+ case 'm':
+ case 'M':
+ dis_cmd(" Move: select Destination, then press RETURN or any other Key to ABORT");
+ sr = r;
+ sc = c;
+ scurchar = curchar;
+ if((curchar = sel_dest()) == -1)
+ { /* failsafe */
+ r = sr;
+ c = sc;
+ curchar = scurchar;
+ }
+ else
+ { /* valid return */
+ normal_set(r,c);
+ c = (curchar / 16);
+ r = (curchar % 16);
+ move_ch(scurchar,curchar);
+ }
+ break;
+
+ case 'q':
+ case 'Q':
+ normal_set(r,c);
+ wrefresh(set_win);
+ return(1);
+ break;
+
+ case 'x':
+ case 'X':
+ normal_set(r,c);
+ wrefresh(set_win);
+ return(0);
+ break;
+
+ case 0x0c:
+ wrefresh(curscr);
+ break;
+
+ default:
+ beep();
+ break;
+
+ }
+ }
+}
+
+void normal_set(int r, int c)
+{
+ char h, l;
+
+ h = ((mvwinch(set_win,(r+1),((c*2)+1))) & A_CHARTEXT);
+ l = ((mvwinch(set_win,(r+1),((c*2)+2))) & A_CHARTEXT);
+ wattroff(set_win,A_REVERSE);
+ mvwprintw(set_win,(r+1),((c*2)+1),"%c%c",h,l);
+ wmove(set_win,(r+1),((c*2)+1));
+}
+
+int sel_dest(void)
+{
+ int c, r;
+ char h, l;
+ unsigned int k_ch;
+
+ c = (curchar / 16);
+ r = (curchar % 16);
+
+ for(;;)
+ {
+
+ curchar = r + (c*16);
+
+ display(curchar);
+
+ h = ((mvwinch(set_win,(r+1),((c*2)+1))) & A_CHARTEXT);
+ l = ((mvwinch(set_win,(r+1),((c*2)+2))) & A_CHARTEXT);
+ wattron(set_win,A_UNDERLINE);
+ mvwprintw(set_win,(r+1),((c*2)+1),"%c%c",h,l);
+ wattroff(set_win,A_UNDERLINE);
+ wmove(set_win,(r+1),((c*2)+1));
+ wrefresh(set_win);
+
+ k_ch = wgetch(set_win);
+
+ switch(k_ch)
+ {
+ case K_LEFT:
+ case KEY_LEFT:
+ if(c > 0)
+ {
+ normal_uset(r,c);
+ c--;
+ }
+ break;
+
+ case K_DOWN:
+ case KEY_DOWN:
+ if(r < 15)
+ {
+ normal_uset(r,c);
+ r++;
+ }
+ break;
+
+ case K_UP:
+ case KEY_UP:
+ if(r > 0)
+ {
+ normal_uset(r,c);
+ r--;
+ }
+ break;
+
+ case K_RIGHT:
+ case KEY_RIGHT:
+ if(c < 15)
+ {
+ normal_uset(r,c);
+ c++;
+ }
+ break;
+
+ case '\r':
+ case '\n':
+ normal_uset(r,c);
+ return(r + (c*16));
+
+ case 0x0c:
+ wrefresh(curscr);
+ break;
+
+ default:
+ normal_uset(r,c);
+ return(-1);
+ }
+ }
+}
+
+void normal_uset(int r, int c)
+{
+ char h, l;
+
+ h = ((mvwinch(set_win,(r+1),((c*2)+1))) & A_CHARTEXT);
+ l = ((mvwinch(set_win,(r+1),((c*2)+2))) & A_CHARTEXT);
+
+ wattroff(set_win,A_UNDERLINE);
+ mvwprintw(set_win,(r+1),((c*2)+1),"%c%c",h,l);
+ wmove(set_win,(r+1),((c*2)+1));
+
+ if((r==sr) && (c==sc))
+ {
+ wattron(set_win,A_REVERSE);
+ mvwprintw(set_win,(r+1),((c*2)+1),"%c%c",h,l);
+ wattroff(set_win,A_REVERSE);
+ wmove(set_win,(r+1),((c*2)+1));
+ }
+}
+
+
+
+/*---------------------------------- E O F ----------------------------------*/
diff --git a/sys/arch/i386/isa/pcvt/Util/fontedit/Makefile b/sys/arch/i386/isa/pcvt/Util/fontedit/Makefile
new file mode 100644
index 00000000000..be63fb8212d
--- /dev/null
+++ b/sys/arch/i386/isa/pcvt/Util/fontedit/Makefile
@@ -0,0 +1,5 @@
+PROG= fontedit
+CLEANFILES+= core.fontedit fontedit.core
+
+.include <bsd.prog.mk>
+
diff --git a/sys/arch/i386/isa/pcvt/Util/fontedit/README b/sys/arch/i386/isa/pcvt/Util/fontedit/README
new file mode 100644
index 00000000000..1854129b63d
--- /dev/null
+++ b/sys/arch/i386/isa/pcvt/Util/fontedit/README
@@ -0,0 +1,36 @@
+When I first saw this posted to rn, I tried to compile this on a machine
+running BSD UNIX. Much to my dissapointment, It said "unable to find
+/usr/include/termio.h" and thus it sat for a couple months. I was able to
+compile it on a 3b5, but I didn't have a vt220 hooked up to it. I was doing
+some unrelated work with ioctl calls and finally realized that it would not be
+too hard to convert it from System V to BSD. It also looked kind of strange
+with the cursor on, so I turned this off. To implement this, compile with
+the "-DCURFIX" flag in the Makefile.
+I am working on a new version that uses curses and that would enable you to
+change the file that your are working on without leaving the program.
+I thought I'd post it as it is now, since it has a lot of uses right away.
+Imagine changing your favorite game to have objects that look like what they
+are instead of the regular characters. Also, I think people should post their
+own character sets, if they come up with some neat stuff.
+ Please send any comments or suggestions to:
+
+ UUCP : ..!harvard!bu-cs!bucsb!eap
+ ARPANET: eap@bucsb.bu.edu
+ CSNET : eap%bucsb@bu-cs
+
+ Have fun,
+
+ - Eric Pearce
+ Boston University
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/sys/arch/i386/isa/pcvt/Util/fontedit/fontedit.1 b/sys/arch/i386/isa/pcvt/Util/fontedit/fontedit.1
new file mode 100644
index 00000000000..8b55edb46a6
--- /dev/null
+++ b/sys/arch/i386/isa/pcvt/Util/fontedit/fontedit.1
@@ -0,0 +1,58 @@
+.TH FONTEDIT 1 LOCAL
+.SH NAME
+fontedit \- Edit fonts.
+.SH SYNOPSIS
+.B fontedit file
+.SH DESCRIPTION
+.I Fontedit
+is used to edit the down line reloadable character set (DRCS) of a VT220
+terminal. The editor has two display areas, one for displaying the
+entry currently being manipulated, and one for displaying the complete
+DRCS. Commands to the editor take the form of function keys.
+.PP
+.I Fontedit
+takes one command line parameter, a file name. This file is
+used to save the character set. If the file exists when \fIfontedit\fP
+is invoked, it is read in to initialize the DRCS. The file is written
+to when \fIfontedit\fP exits.
+.PP
+Commands to fontedit take the form of function keys. The current
+definitions are:
+.IP \fBHELP\fP
+Display a help screen.
+.IP \fBF6\fP
+Turn the pixel under the cursor on.
+.IP \fBF7\fP
+Turn the pixel under the cursor off.
+.IP \fBF13\fP
+Clear the display area.
+.IP \fBFind\fP
+Save the current font in the font table. Update the DRCS display.
+.IP \fBSelect\fP
+Extract the entry selected by the cursor in the DRCS display.
+.IP \fBPrev\fP
+Move the cursor to the previous entry in the DRCS display.
+.IP \fBNext\fP
+Move the cursor to the next entry in the DRCS display.
+.IP \fBInsert\fP
+Insert a blank line at the current cursor position. The bottom row is lost.
+.IP \fBRemove\fP
+Remove the row at the current cursor position. All rows below the
+current one are shifted up.
+.IP \fBCursors\fP
+Move the cursor in the main display area.
+.PP
+If the screen gets garbled, press <control-L>.
+.PP
+To exit \fIfontedit\fP, press <control-D>. The DRCS will be saved in
+\fIfile\fP. To exit without saving the DRCS, hit interrupt (usually
+DEL).
+.SH DIAGNOSTICS
+.I Fontedit
+will issue a warning when the entry being worked on is not saved, and
+some potentially destructive command, like \fBSelect\fP is used. To
+override the warning message, immediately reissue the command.
+.SH AUTHOR
+Greg Franks.
+
+
diff --git a/sys/arch/i386/isa/pcvt/Util/fontedit/fontedit.c b/sys/arch/i386/isa/pcvt/Util/fontedit/fontedit.c
new file mode 100644
index 00000000000..36a3232f097
--- /dev/null
+++ b/sys/arch/i386/isa/pcvt/Util/fontedit/fontedit.c
@@ -0,0 +1,925 @@
+/*
+ * fontedit
+ * Fonteditor for VT220
+ *
+ * BUGS:
+ * o Cursor motion is less than optimal (but who cares at 9600),
+ *
+ * COMPILE:
+ * cc -O fontedit.c -o fontedit
+ * (use Makefile)
+ *
+ * Copyright (c) 1987 by Greg Franks.
+ *
+ * Permission is granted to do anything you want with this program
+ * except claim that you wrote it.
+ *
+ *
+ * REVISION HISTORY:
+ *
+ * Nov 21, 1987 - Fixed man page to say "Fontedit" instead of "Top"
+ * Nov 22, 1987 - Added BSD Compatible ioctl, turned cursor on/off
+ * - eap@bucsf.bu.edu
+ */
+
+void clear_screen();
+#include <stdio.h>
+#ifdef SYSV
+#include <sys/termio.h>
+#endif SYSV
+#ifdef BSD
+#include <sys/ioctl.h>
+#endif BSD
+#if defined (__NetBSD__) || defined (__FreeBSD__)
+#include <sys/termios.h>
+#include <sys/ioctl.h>
+#endif /* __NetBSD__ || __FreeBSD__ */
+#include <signal.h>
+
+#ifdef CURFIX
+#define CURSORON "\033[?25h"
+#define CURSOROFF "\033[?25l"
+#endif CURFIX
+
+#define MAX_ROWS 10
+#define MAX_COLS 8
+
+typedef enum { false, true } bool;
+
+#define KEY_FIND 0x0100
+#define KEY_INSERT 0x0101
+#define KEY_REMOVE 0x0102
+#define KEY_SELECT 0x0103
+#define KEY_PREV 0x0104
+#define KEY_NEXT 0x0105
+#define KEY_F6 0X0106
+#define KEY_F7 0x0107
+#define KEY_F8 0x0108
+#define KEY_F9 0x0109
+#define KEY_F10 0x010a
+#define KEY_F11 0x010b
+#define KEY_F12 0x010c
+#define KEY_F13 0x010d
+#define KEY_F14 0x010e
+#define KEY_HELP 0x010f
+#define KEY_DO 0x0110
+#define KEY_F17 0x0111
+#define KEY_F18 0x0112
+#define KEY_F19 0x0113
+#define KEY_F20 0x0114
+#define KEY_UP 0x0115
+#define KEY_DOWN 0x0116
+#define KEY_RIGHT 0x0117
+#define KEY_LEFT 0x0118
+
+/*
+ * Position of main drawing screen.
+ */
+
+#define ROW_OFFSET 3
+#define COL_OFFSET 10
+
+/*
+ * Position of the DRCS table.
+ */
+
+#define TABLE_ROW 4
+#define TABLE_COL 50
+
+/*
+ *
+ */
+
+#define ERROR_ROW 20
+#define ERROR_COL 40
+
+bool display_table[MAX_ROWS][MAX_COLS];
+
+#define TOTAL_ENTRIES (128 - 32)
+#define SIXELS_PER_CHAR 16
+
+char font_table[TOTAL_ENTRIES][SIXELS_PER_CHAR];
+unsigned int current_entry;
+
+#ifdef SYSV
+struct termio old_stty, new_stty;
+#endif SYSV
+#ifdef BSD
+struct sgttyb old_stty, new_stty;
+#endif BSD
+#if defined (__NetBSD__) || defined (__FreeBSD__)
+struct termios old_stty, new_stty;
+#endif /* __NetBSD__ || __FreeBSD__ */
+FILE * font_file = (FILE *)0;
+
+
+/*
+ * Interrupt
+ * Exit gracefully.
+ */
+
+interrupt()
+{
+ void clear_screen();
+#ifdef CURFIX
+ printf("%s\n",CURSORON);
+#endif CURFIX
+#ifdef SYSV
+ ioctl( 0, TCSETA, &old_stty );
+#endif SYSV
+#ifdef BSD
+ ioctl( 0, TIOCSETP, &old_stty );
+#endif BSD
+#if defined (__NetBSD__) || defined (__FreeBSD__)
+ ioctl( 0, TIOCSETA, &old_stty );
+#endif /* __NetBSD__ || __FreeBSD__ */
+ clear_screen();
+ exit( 0 );
+}
+
+
+/*
+ * Main
+ * Grab input/output file and call main command processor.
+ */
+
+main( argc, argv )
+int argc;
+char *argv[];
+{
+ void command(), init_restore(), clear_screen();
+ void save_table(), get_table(), extract_entry();
+
+ if ( argc != 2 ) {
+ fprintf( stderr, "usage: fontedit filename\n" );
+ exit( 1 );
+ }
+
+ printf( "Press HELP for help\n" );
+ printf( "\033P1;1;2{ @\033\\" ); /* Clear font buffer */
+ fflush( stdout );
+ sleep( 1 ); /* Let terminal catch up */
+ /* otherwise we get frogs */
+
+ if ( ( font_file = fopen( argv[1], "r" ) ) == (FILE *)0 ) {
+ if ( ( font_file = fopen( argv[1], "w" ) ) == (FILE *)0 ) {
+ fprintf( stderr, "Cannot create file %s \n", argv[1] );
+ exit( 1 );
+ }
+ }
+ fclose( font_file );
+
+ if ( ( font_file = fopen( argv[1], "r" ) ) != (FILE *)0 ) {
+ get_table( font_file );
+ fclose( font_file );
+ }
+
+ if ( ( font_file = fopen( argv[1], "r+" ) ) == (FILE *)0 ) {
+ fprintf( stderr, "Cannot open %s for writing\n", argv[1] );
+ exit( 1 );
+ }
+#ifdef CURFIX
+ printf("%s\n",CURSOROFF);
+#endif CURFIX
+#ifdef SYSV
+ ioctl( 0, TCGETA, &old_stty );
+#endif SYSV
+#ifdef BSD
+ ioctl( 0, TIOCGETP, &old_stty );
+#endif BSD
+#if defined (__NetBSD__) || defined (__FreeBSD__)
+ ioctl( 0, TIOCGETA, &old_stty );
+#endif /* __NetBSD__ || __FreeBSD__ */
+ signal( SIGINT, (void *) interrupt );
+ new_stty = old_stty;
+#ifdef SYSV
+ new_stty.c_lflag &= ~ICANON;
+ new_stty.c_cc[VMIN] = 1;
+ ioctl( 0, TCSETA, &new_stty );
+#endif SYSV
+#if defined (__NetBSD__) || defined (__FreeBSD__)
+ new_stty.c_lflag &= ~ICANON;
+ new_stty.c_lflag &= ~ECHO;
+ new_stty.c_cc[VMIN] = 1;
+ ioctl( 0, TIOCSETA, &new_stty );
+#endif /* __NetBSD__ || __FreeBSD__ */
+#ifdef BSD
+ new_stty.sg_flags |= CBREAK;
+ new_stty.sg_flags &= ~ECHO;
+ ioctl( 0, TIOCSETP, &new_stty );
+#endif BSD
+ current_entry = 1;
+ extract_entry( current_entry );
+ init_restore();
+ command();
+#ifdef SYSV
+ ioctl( 0, TCSETA, &old_stty );
+#endif SYSV
+#ifdef BSD
+ ioctl( 0, TIOCSETP, &old_stty );
+#endif BSD
+#if defined (__NetBSD__) || defined (__FreeBSD__)
+ ioctl( 0, TIOCSETA, &old_stty );
+#endif /* __NetBSD__ || __FreeBSD__ */
+ clear_screen();
+
+ /* Overwrite the old file. */
+
+ fseek( font_file, 0L, 0 );
+ save_table( font_file );
+ fclose( font_file );
+#ifdef CURFIX
+ printf("%s\n",CURSORON);
+#endif CURFIX
+}
+
+
+
+/*
+ * Command
+ * Process a function key.
+ *
+ * The user cannot fill in slots 0 or 95 (space and del respecitively).
+ */
+
+void
+command()
+{
+ register int c;
+ register int row, col;
+ register int i, j;
+ bool change, error, override;
+
+ void build_entry(), extract_entry(), send_entry(), print_entry();
+ void highlight(), draw_current(), init_restore(), help();
+ void warning();
+
+ change = false;
+ error = false;
+ override = false;
+ row = 0; col = 0;
+ highlight( row, col, true );
+
+ for ( ;; ) {
+ c = get_key();
+ highlight( row, col, false ); /* turn cursor off */
+
+ if ( error ) {
+ move ( ERROR_ROW, ERROR_COL );
+ printf( "\033[K" ); /* Clear error message */
+ move ( ERROR_ROW+1, ERROR_COL );
+ printf( "\033[K" ); /* Clear error message */
+ error = false;
+ } else {
+ override = false;
+ }
+
+ switch ( c ) {
+
+ case KEY_FIND: /* update DRCS */
+ if ( !change && !override ) {
+ warning( "No changes to save" );
+ override = true;
+ error = true;
+ } else {
+ build_entry( current_entry );
+ send_entry( current_entry );
+ print_entry( current_entry, true );
+ change = false;
+ }
+ break;
+
+ case KEY_F6: /* Turn on pixel */
+ change = true;
+ display_table[row][col] = true;
+ highlight( row, col, false );
+ col = ( col + 1 ) % MAX_COLS;
+ if ( col == 0 )
+ row = ( row + 1 ) % MAX_ROWS;
+ break;
+
+ case KEY_F7: /* Turn off pixel */
+ change = true;
+ display_table[row][col] = false;
+ highlight( row, col, false );
+ col = ( col + 1 ) % MAX_COLS;
+ if ( col == 0 )
+ row = ( row + 1 ) % MAX_ROWS;
+ break;
+
+ case KEY_INSERT: /* Insert a blank row */
+ change = true;
+ for ( j = 0; j < MAX_COLS; ++j ) {
+ for ( i = MAX_ROWS - 1; i > row; --i ) {
+ display_table[i][j] = display_table[i-1][j];
+ }
+ display_table[row][j] = false;
+ }
+ draw_current();
+ break;
+
+ case KEY_REMOVE: /* Remove a row */
+ change = true;
+ for ( j = 0; j < MAX_COLS; ++j ) {
+ for ( i = row; i < MAX_ROWS - 1; ++i ) {
+ display_table[i][j] = display_table[i+1][j];
+ }
+ display_table[MAX_ROWS-1][j] = false;
+ }
+ draw_current();
+ break;
+
+ case KEY_F13: /* Clear buffer */
+ if ( change && !override ) {
+ warning( "Changes not saved" );
+ error = true;
+ override = true;
+ } else {
+ for ( j = 0; j < MAX_COLS; ++j ) {
+ for ( i = 0; i < MAX_ROWS; ++i ) {
+ display_table[i][j] = false;
+ }
+ }
+ draw_current();
+ }
+ break;
+
+ case KEY_SELECT: /* Select font from DRCS */
+ if ( change && !override ) {
+ warning( "Changes not saved" );
+ error = true;
+ override = true;
+ } else {
+ extract_entry( current_entry );
+ draw_current();
+ }
+ break;
+
+ case KEY_PREV: /* Move to prev entry in DRCS */
+ if ( change && !override ) {
+ warning( "Changes not saved" );
+ override = true;
+ error = true;
+ } else {
+ print_entry( current_entry, false );
+ current_entry = current_entry - 1;
+ if ( current_entry == 0 )
+ current_entry = TOTAL_ENTRIES - 2;
+ print_entry( current_entry, true );
+ }
+ break;
+
+ case KEY_NEXT: /* Move to next entry in DRCS */
+ if ( change && !override ) {
+ warning( "Changes not saved" );
+ override = true;
+ error = true;
+ } else {
+ print_entry( current_entry, false );
+ current_entry = current_entry + 1;
+ if ( current_entry == TOTAL_ENTRIES - 1 )
+ current_entry = 1;
+ print_entry( current_entry, true );
+ }
+ break;
+
+ case KEY_UP: /* UP one row. */
+ if ( row == 0 )
+ row = MAX_ROWS;
+ row = row - 1;
+ break;
+
+ case KEY_DOWN: /* Guess. */
+ row = ( row + 1 ) % MAX_ROWS;
+ break;
+
+ case KEY_RIGHT:
+ col = ( col + 1 ) % MAX_COLS;
+ break;
+
+ case KEY_LEFT:
+ if ( col == 0 )
+ col = MAX_COLS;
+ col = col - 1;
+ break;
+
+ case KEY_HELP: /* Display helpful info */
+ clear_screen();
+ help();
+ c = getchar();
+ init_restore();
+ break;
+
+ case '\004': /* All done! */
+ return;
+
+ case '\f': /* Redraw display */
+ init_restore();
+ break;
+
+ default: /* user is a klutzy typist */
+ move ( ERROR_ROW, ERROR_COL );
+ printf( "Unknown key: " );
+ if ( c < 0x20 ) {
+ printf( "^%c", c );
+ } else if ( c < 0x0100 ) {
+ printf( "%c", c );
+ } else {
+ printf( "0x%04x", c );
+ }
+ fflush( stdout );
+ error = true;
+ }
+
+ highlight( row, col, true ); /* turn cursor on */
+ }
+}
+
+
+
+char *key_table[] = {
+ "\033[1~", /* Find */
+ "\033[2~", /* Insert */
+ "\033[3~", /* Remove */
+ "\033[4~", /* Select */
+ "\033[5~", /* Prev */
+ "\033[6~", /* Next */
+ "\033[17~",
+ "\033[18~",
+ "\033[19~",
+ "\033[20~",
+ "\033[21~",
+ "\033[23~",
+ "\033[24~",
+ "\033[25~",
+ "\033[26~",
+ "\033[28~",
+ "\033[29~",
+ "\033[31~",
+ "\033[32~",
+ "\033[33~",
+ "\033[34~",
+ "\033[A",
+ "\033[B",
+ "\033[C",
+ "\033[D",
+ (char *)0 };
+
+/*
+ * get_key
+ * Convert VT220 escape sequence into something more reasonable.
+ */
+
+int
+get_key()
+{
+ register char *p;
+ char s[10];
+ register int i, j;
+
+ p = s;
+ for ( i = 0; i < 10; ++i ) {
+ *p = getchar();
+ if ( i == 0 && *p != '\033' )
+ return( (int)*p ); /* Not an escape sequence */
+ if ( *p != '\033' && *p < 0x0020 )
+ return( (int)*p ); /* Control character */
+ *++p = '\0'; /* Null terminate */
+ for ( j = 0; key_table[j]; ++j ) {
+ if ( strcmp( s, key_table[j] ) == 0 ) {
+ return( j | 0x0100 );
+ }
+ }
+ }
+ return( -1 );
+}
+
+
+
+/*
+ * pad
+ * Emit nulls so that the terminal can catch up.
+ */
+
+pad()
+{
+ int i;
+
+ for ( i = 0; i < 20; ++i )
+ putchar( '\000' );
+ fflush( stdout );
+}
+
+
+
+/*
+ * init_restore
+ * refresh the main display table.
+ */
+
+void
+init_restore()
+{
+ register int row, col;
+ register int i;
+
+ void draw_current(), clear_screen(), print_entry();
+
+ clear_screen();
+
+ for ( col = 0; col < MAX_COLS; ++col ) {
+ move( ROW_OFFSET - 2, col * 3 + COL_OFFSET + 1 );
+ printf( "%d", col );
+ }
+ move( ROW_OFFSET - 1, COL_OFFSET );
+ printf( "+--+--+--+--+--+--+--+--+" );
+ move( ROW_OFFSET + MAX_ROWS * 2, COL_OFFSET );
+ printf( "+--+--+--+--+--+--+--+--+" );
+
+ for ( row = 0; row < MAX_ROWS; ++row ) {
+ if ( row != 0 && row != 7 ) {
+ move( row * 2 + ROW_OFFSET, COL_OFFSET - 2 );
+ printf( "%d|", row );
+ move( row * 2 + ROW_OFFSET + 1, COL_OFFSET - 1 );
+ printf( "|" );
+ move( row * 2 + ROW_OFFSET, COL_OFFSET + MAX_COLS * 3 );
+ printf( "|" );
+ move( row * 2 + ROW_OFFSET + 1, COL_OFFSET + MAX_COLS * 3 );
+ printf( "|" );
+ } else {
+ move( row * 2 + ROW_OFFSET, COL_OFFSET - 2 );
+ printf( "%d*", row );
+ move( row * 2 + ROW_OFFSET + 1, COL_OFFSET - 1 );
+ printf( "*" );
+ move( row * 2 + ROW_OFFSET, COL_OFFSET + MAX_COLS * 3 );
+ printf( "*" );
+ move( row * 2 + ROW_OFFSET + 1, COL_OFFSET + MAX_COLS * 3 );
+ printf( "*" );
+ }
+ }
+ draw_current();
+
+ move( TABLE_ROW - 1, TABLE_COL - 1 );
+ printf( "+-+-+-+-+-+-+-+-+-+-+-+-+" );
+ move( TABLE_ROW + 8 * 2 - 1, TABLE_COL - 1 );
+ printf( "+-+-+-+-+-+-+-+-+-+-+-+-+" );
+ for ( i = 0; i < 8; ++i ) {
+ move ( TABLE_ROW + i * 2, TABLE_COL - 1 );
+ printf( "|" );
+ move ( TABLE_ROW + i * 2 + 1, TABLE_COL - 1 );
+ printf( "+" );
+ move ( TABLE_ROW + i * 2, TABLE_COL + 12 * 2 - 1);
+ printf( "|" );
+ move ( TABLE_ROW + i * 2 + 1, TABLE_COL +12 * 2 - 1);
+ printf( "+" );
+ }
+ for ( i = 0; i < TOTAL_ENTRIES; ++i )
+ print_entry( i, (i == current_entry) ? true : false );
+}
+
+
+
+/*
+ * draw_current
+ * Draw the complete current entry.
+ */
+
+void
+draw_current()
+{
+ register int row, col;
+
+ printf( "\033)0" ); /* Special graphics in G1 */
+ printf( "\016" ); /* Lock in G1 (SO) */
+
+ for ( row = 0; row < MAX_ROWS; ++row ) {
+ for ( col = 0; col < MAX_COLS; ++col ) {
+ if ( display_table[row][col] ) {
+ move( row * 2 + ROW_OFFSET, col * 3 + COL_OFFSET );
+ printf( "\141\141\141" );
+ move( row * 2 + ROW_OFFSET + 1, col * 3 + COL_OFFSET );
+ printf( "\141\141\141" );
+ } else {
+ move( row * 2 + ROW_OFFSET, col * 3 + COL_OFFSET );
+ printf( " " ); /* erase splat */
+ move( row * 2 + ROW_OFFSET + 1, col * 3 + COL_OFFSET );
+ printf( " " ); /* erase splat */
+ }
+ }
+ pad();
+ }
+ printf( "\017" ); /* Lock in G0 (SI) */
+ fflush( stdout );
+}
+
+
+
+/*
+ * highlight
+ * Draw the cursor in the main display area.
+ */
+
+void
+highlight( row, col, on )
+unsigned int row, col;
+bool on;
+{
+
+ printf( "\033)0" ); /* Special graphics in G1 */
+ printf( "\016" ); /* Lock in G1 (SO) */
+ if ( on ) {
+ printf( "\033[7m" ); /* Reverse video cursor */
+ }
+
+ if ( display_table[row][col] ) {
+ move( row * 2 + ROW_OFFSET, col * 3 + COL_OFFSET );
+ printf( "\141\141\141" );
+ move( row * 2 + ROW_OFFSET + 1, col * 3 + COL_OFFSET );
+ printf( "\141\141\141" );
+ } else {
+ move( row * 2 + ROW_OFFSET, col * 3 + COL_OFFSET );
+ printf( " " ); /* erase splat */
+ move( row * 2 + ROW_OFFSET + 1, col * 3 + COL_OFFSET );
+ printf( " " ); /* erase splat */
+ }
+ pad();
+ printf( "\017" ); /* Lock in G0 (SI) */
+ printf( "\033[0m" ); /* normal video */
+ printf( "\b" ); /* Back up one spot */
+ fflush( stdout );
+}
+
+
+
+/*
+ * Clear_screen
+ */
+
+void
+clear_screen()
+{
+ printf( "\033[H\033[J" ); /* Clear screen. */
+ fflush( stdout );
+}
+
+
+
+/*
+ * move
+ */
+
+move( y, x )
+int y, x;
+{
+ printf( "\033[%d;%df", y, x );
+}
+
+
+
+/*
+ * Build_entry
+ * Convert the bit pattern used in the main display area into something
+ * that the vt220 can digest - namely sixels...
+ */
+
+void
+build_entry( entry_no )
+unsigned int entry_no;
+{
+ register int row, col;
+ register unsigned int mask;
+
+ for ( col = 0; col < 8; ++col ) {
+
+ /* Top set of sixels */
+
+ mask = 0;
+ for ( row = 5; row >= 0; --row ) {
+ mask = mask << 1;
+ if ( display_table[row][col] )
+ mask |= 1;
+ }
+ font_table[entry_no][col] = mask + 077;
+
+ /* Bottom set of sixels */
+
+ mask = 0;
+ for ( row = 9; row >= 6; --row ) {
+ mask = mask << 1;
+ if ( display_table[row][col] )
+ mask |= 1;
+ }
+ font_table[entry_no][col+8] = mask + 077;
+ }
+
+}
+
+
+
+/*
+ * Extract_engry
+ * convert sixel representation into an array of bits.
+ */
+
+void
+extract_entry( entry_no )
+unsigned int entry_no;
+{
+ register int row, col;
+ register unsigned int mask;
+
+ for ( col = 0; col < 8; ++col ) {
+
+ /* Top set of sixels */
+
+ mask = font_table[entry_no][col];
+ if ( mask >= 077 )
+ mask -= 077;
+ else
+ mask = 0; /* Bogus entry */
+
+ for ( row = 0; row <= 5; ++row ) {
+ display_table[row][col] = (bool)(mask & 0x0001);
+ mask = mask >> 1;
+ }
+
+ /* Bottom set of sixels */
+
+ mask = font_table[entry_no][col+8];
+ if ( mask >= 077 )
+ mask -= 077;
+ else
+ mask = 0;
+
+ for ( row = 6; row <= 9; ++row ) {
+ display_table[row][col] = (bool)(mask & 0x0001);
+ mask = mask >> 1;
+ }
+ }
+
+}
+
+
+
+/*
+ * Send_entry
+ * Emit the stuff used by the VT220 to load a character into the
+ * DRCS. We could, of course, send more than one entry at a time...
+ */
+
+void
+send_entry( entry_no )
+int entry_no;
+{
+ register char *fp = font_table[entry_no];
+
+ printf( "\033P1;%d;1;0;0;0{ @%c%c%c%c%c%c%c%c/%c%c%c%c%c%c%c%c\033\\",
+ entry_no,
+ fp[ 0], fp[ 1], fp[ 2], fp[ 3], fp[ 4], fp[ 5], fp[ 6], fp[ 7],
+ fp[ 8], fp[ 9], fp[10], fp[11], fp[12], fp[13], fp[14], fp[15] );
+}
+
+
+
+/*
+ * Print_entry
+ * The terminal normally has G0 in GL. We don't want to change
+ * this, nor do we want to use GR. Sooooo send out the necessary
+ * magic for shifting in G2 temporarily for the character that we
+ * want to display.
+ */
+
+void
+print_entry( entry_no, highlight )
+register unsigned int entry_no;
+bool highlight;
+{
+
+ register int y, x;
+
+ y = entry_no & 0x07;
+ x = entry_no >> 3 & 0x1f;
+ entry_no += 32; /* Map up to G set */
+
+ move( y * 2 + TABLE_ROW, x * 2 + TABLE_COL );
+
+ if ( highlight )
+ printf( "\033[7m" );
+
+ printf( "\033* @" ); /* select DRCS into G2 */
+ printf( "\033N" ); /* select single shift */
+ printf( "%c", entry_no ); /* Draw the character */
+
+ if ( highlight )
+ printf( "\033[0m" );
+}
+
+
+
+/*
+ * Save_table
+ * Save a font table
+ */
+
+void
+save_table( font_file )
+FILE *font_file;
+{
+ register char *fp;
+ register int i;
+
+ for ( i = 0; i < TOTAL_ENTRIES; ++i ) {
+ fp = font_table[i];
+ fprintf( font_file, "\033P1;%d;1;0;0;0{ @%c%c%c%c%c%c%c%c/%c%c%c%c%c%c%c%c\033\\\n",
+ i,
+ fp[ 0], fp[ 1], fp[ 2], fp[ 3], fp[ 4], fp[ 5], fp[ 6], fp[ 7],
+ fp[ 8], fp[ 9], fp[10], fp[11], fp[12], fp[13], fp[14], fp[15] );
+ }
+}
+
+
+
+/*
+ * Get_table
+ * Extract font table entries from a file
+ */
+
+void
+get_table( font_file )
+FILE *font_file;
+{
+ char s[256];
+ register char *p;
+ char *fp;
+ int i;
+ register int j;
+
+ while( fgets( s, 255, font_file ) ) {
+ if ( strncmp( s, "\033P1;", 4 ) != 0 )
+ continue; /* Bogus line */
+ p = &s[4];
+ if ( sscanf( p, "%d", &i ) != 1 )
+ continue; /* Illegal entry number */
+
+ if ( i <= 0 || TOTAL_ENTRIES <= i )
+ continue; /* Bogues entry */
+
+ fp = font_table[i];
+
+ while ( *p && *p != '@' )
+ ++p; /* Skip to font definition */
+ if ( ! *p++ )
+ continue; /* Skip @ */
+
+ for ( j = 0; *p && *p != '\033' && j < 16; ++j, ++p ) {
+ if ( *p == '/' ) {
+ j = 8;
+ ++p;
+ }
+ fp[j] = *p;
+ }
+ send_entry( i );
+ }
+}
+
+
+
+/*
+ * Help
+ * Print out help information.
+ */
+
+void
+help()
+{
+ printf( "Font editor\n\n" );
+ printf( "F6 - Pixel on\n" );
+ printf( "F7 - Pixel off\n" );
+ printf( "F13 - Clear display area\n" );
+ printf( "HELP - This screen\n" );
+ printf( "FIND - Update font table\n" );
+ printf( "INSERT - Insert a blank row\n" );
+ printf( "REMOVE - Remove a row\n" );
+ printf( "SELECT - Select current font table entry\n" );
+ printf( "PREV - Move to previous font table entry\n" );
+ printf( "NEXT - Move to next font table entry\n" );
+ printf( "^D - Exit\n" );
+ printf( "\n\n\n\nPress any key to continue\n" );
+}
+
+
+
+/*
+ * Warning
+ * Issue a warning to the regarding the current status.
+ */
+
+void
+warning( s )
+char *s;
+{
+ move( ERROR_ROW, ERROR_COL );
+ printf( "Warning: %s!\n", s );
+ move( ERROR_ROW+1, ERROR_COL );
+ printf( " Reissue command to override\n" );
+}
diff --git a/sys/arch/i386/isa/pcvt/Util/fonts/COPYRIGHT b/sys/arch/i386/isa/pcvt/Util/fonts/COPYRIGHT
new file mode 100644
index 00000000000..13205223548
--- /dev/null
+++ b/sys/arch/i386/isa/pcvt/Util/fonts/COPYRIGHT
@@ -0,0 +1,37 @@
+The font files:
+
+ vt220h.808.uu, vt220h.810.uu, vt220h.814.uu, vt220h.816.uu,
+ vt220l.808.uu, vt220l.810.uu, vt220l.814.uu and vt220l.816.uu
+
+in this directory are
+
+ Copyright (c) 1992, 1995 Hellmuth Michaelis and Joerg Wunsch
+
+ All rights reserved.
+
+ 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
+ Hellmuth Michaelis and Joerg Wunsch
+ 4. The name authors may not be used to endorse or promote products
+ derived from this software without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``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 AUTHORS 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.
+
diff --git a/sys/arch/i386/isa/pcvt/Util/fonts/Makefile b/sys/arch/i386/isa/pcvt/Util/fonts/Makefile
new file mode 100644
index 00000000000..88de1773adf
--- /dev/null
+++ b/sys/arch/i386/isa/pcvt/Util/fonts/Makefile
@@ -0,0 +1,54 @@
+FONTS = vt220l.814 vt220h.814 vt220l.808 vt220h.808 \
+ vt220l.816 vt220h.816 vt220l.810 vt220h.810
+
+LIBMODE = 644
+LIBOWN = bin
+LIBGRP = bin
+CLEANFILES= ${FONTS}
+
+all: $(FONTS)
+
+install: ${FONTS}
+ @if [ ! -d ${DESTDIR}${FONTDIR} ]; then mkdir ${DESTDIR}${FONTDIR};fi
+ @for i in ${FONTS}; do \
+ ${ECHO} "installing font $$i into ${DESTDIR}${FONTDIR}"; \
+ install -c -m ${LIBMODE} -o ${LIBOWN} -g ${LIBGRP} \
+ $$i ${DESTDIR}${FONTDIR}; \
+ done
+
+clean:
+ rm -f ${CLEANFILES}
+
+.include <bsd.prog.mk>
+
+# this seems to be the lowest common denominator
+
+vt100pc.814: ${.CURDIR}/vt100pc.814.uu
+ uudecode ${.CURDIR}/$@.uu
+
+vt100sg.814: ${.CURDIR}/vt100sg.814.uu
+ uudecode ${.CURDIR}/$@.uu
+
+vt220l.814: ${.CURDIR}/vt220l.814.uu
+ uudecode ${.CURDIR}/$@.uu
+
+vt220h.814: ${.CURDIR}/vt220h.814.uu
+ uudecode ${.CURDIR}/$@.uu
+
+vt220l.808: ${.CURDIR}/vt220l.808.uu
+ uudecode ${.CURDIR}/$@.uu
+
+vt220h.808: ${.CURDIR}/vt220h.808.uu
+ uudecode ${.CURDIR}/$@.uu
+
+vt220l.816: ${.CURDIR}/vt220l.816.uu
+ uudecode ${.CURDIR}/$@.uu
+
+vt220h.816: ${.CURDIR}/vt220h.816.uu
+ uudecode ${.CURDIR}/$@.uu
+
+vt220l.810: ${.CURDIR}/vt220l.810.uu
+ uudecode ${.CURDIR}/$@.uu
+
+vt220h.810: ${.CURDIR}/vt220h.810.uu
+ uudecode ${.CURDIR}/$@.uu
diff --git a/sys/arch/i386/isa/pcvt/Util/fonts/vt220h.808.uu b/sys/arch/i386/isa/pcvt/Util/fonts/vt220h.808.uu
new file mode 100644
index 00000000000..c9585dc1a39
--- /dev/null
+++ b/sys/arch/i386/isa/pcvt/Util/fonts/vt220h.808.uu
@@ -0,0 +1,49 @@
+begin 644 vt220h.808
+M9%1,1"`@(#X\0#@$>"(^(CQ`.`1X-@@V?$!X0'PV"#9\0'A`?#X("'Q`>'P<
+M(BH<.$1\1"PP*"1X1'A$>"`@/GA$>$1^$`P\1$1\1#X("`A`0$!\/B`\($1$
+M*!`^"`@(?$!X0#X@/"`\0$`\/"(\)CQ`.`1X'"(</$`X!'@<"!QX1$1X("`@
+M/GA$1'@$#`0.>$1X'"(,$#YX1'@<`@P"''A$1'@,$CX"9%1,(B0X)"(\0#@$
+M>"(<"'Q`>'P\(CP^/$`\(C(J)B)\0'A`?"(V*CQ`.`1X(B(<?$!X0'P>(!Y\
+M0'A`'B`>/#Q`3#P>(!X\>$1X3!X@'CQ$1#@>(!P"/'"(<(AP#!(,<(APB'`,
+M!`YPB'"(?"0(/'"(<(QB#@(<<(APC'@2/@)PB'"><!P"''"(<(YP/"(<<(AP
+MCG($"`APB'"<<APB''"(<)QR#@(<<(APB'P2'A)PB'"<<AP2''"(<(AP#A`.
+M<(APB'`<$AQPB'"><!P0'G"(<)YP'!`0<(AX"'`,$@QPB'@(<`P$#G"(>`A\
+M)`@\<(AX#&(.`AQPB'@,>!(^`G"(>!YP'`(<<(AX#G`\(AQPB'@><@0("'"(
+M>!QR'"(<<(AX''(.`AQPB'@(?!(>$G"(>!QR'!(<<(AX"'`.$`YPB'@(<!P2
+M''"(>!YP'!`><(AX'G`<$!```'S&QOS`P````,945'P8`'S&!G[&?```8+`8
+M+$V&`````!@X&!H,````_+8V-@0``'SD<.1\````PJ08*L8``$1$*"@0$```
+M$!`H*$1$``#&QL;&QGP```#\!@8&_````'[`P,!^````PD(D&"08`/Z"*#BJ
+M_@``QE14?!@\`````/YL;.X````$_@'^!````"1^@7XD````$!`H1.X`.$2"
+MJKJJ1#@``-QV`/X``/Z"Q,1H:#``&"PL1$:&_@`````VS,PV```8&`!F9@``
+M`!PT,#`PL.`!`@0($"!`@(!`(!`(!`(!`0($"!`@0/\``#\0"`0"`1@8,&`P
+M&!@8&!@,!@P8&!@```X8&!@8&!@8&!@8&`X```!P&!@8&!@8&!@8&!AP```"
+M`@(B$@H&``#NQM;6?```9F8\&'X8`%@D&"0X8`QX`!@`QL9^#'@`P,#XS/C`
+MP%`@4`P\9CP`\&!X;'A@\``.`&9F/!@\````1"@0*$0`_&9F]F9F_`#P$'(6
+M_CINP@``````&`QX&#!@````````````_@```'R"NJJRJH)\`````'@`````
+M``!X"`@``,;&``````````($?AA^($````````#_````````_P```````/\`
+M``````#_````````_P````````#N9F8L&````GS.UN9\@```?-;<T'P``/X`
+M?,;&?`#^`'@,?,QV`,P`S$AX,'@`.&P`QL;&?``<`,;&QL9\`'``QL;&QGP`
+M`CILUM9LN(``?LS.S,Q^`/XX;,;&;#@`.,8X;,9L.``.`#ALQFPX`'``.&S&
+M;#@`9@`\&!@8/``8)``\&!@\``X`/!@8&#P`<``\&!@8/`#&`/YB>&+^`#A$
+M_F)X8OX`<`#^8GAB_@#^`#ALQO[&`#AL$&S&_L8`#@`X;,;^Q@!P`#ALQO[&
+M```<#!X`````````&!@````('CIB>#P$&'@,.`QX````?(*:HJ*:@GP`P]L\
+M9CS;PP``S%1@4$P``'S&8#``,```?,9@,``P``!\QF`P`#```'S&8#``,```
+M?,9@,``P``!\QF`P`#```'S&8#``,```?,9@,``P``!\QF`P`#```'S&8#``
+M,```?,9@,``P``!\QF`P`#```'S&8#``,```?,9@,``P``!\QF`P`#```'S&
+M8#``,```?,9@,``P``!\QF`P`#```'S&8#``,```?,9@,``P``!\QF`P`#``
+M`'S&8#``,```?,9@,``P``!\QF`P`#```'S&8#``,```?,9@,``P``!\QF`P
+M`#```'S&8#``,```?,9@,``P``!\QF`P`#```'S&8#``,```?,9@,``P``!\
+MQF`P`#```'S&8#``,```?,9@,``P``!\QF`P`#```'S&8#``,```?,9@,``P
+M``!\QF`P`#```'S&8#``,```?,9@,``P``!\QF`P`#```'S&8#``,```?,9@
+M,``P``!\QF`P`#```'S&8#``,```?,9@,``P``!\QF`P`#```'S&8#``,```
+M?,9@,``P``!\QF`P`#```'S&8#``,```?,9@,``P``!\QF`P`#```'S&8#``
+M,```?,9@,``P``!\QF`P`#```'S&8#``,```?,9@,``P``!\QF`P`#```'S&
+M8#``,```?,9@,``P``!\QF`P`#```'S&8#``,```?,9@,``P``!\QF`P`#``
+M`'S&8#``,```?,9@,``P``!\QF`P`#```'S&8#``,```?,9@,``P``!\QF`P
+M`#```'S&8#``,```?,9@,``P``!\QF`P`#```'S&8#``,```?,9@,``P``!\
+MQF`P`#```'S&8#``,```?,9@,``P``!\QF`P`#```'S&8#``,```?,9@,``P
+M``!\QF`P`#```'S&8#``,```?,9@,``P``!\QF`P`#```'S&8#``,```?,9@
+M,``P``!\QF`P`#```'S&8#``,```?,9@,``P``!\QF`P`#```'S&8#``,```
+7?,9@,``P``!\QF`P`#```'S&8#``,`!@
+`
+end
diff --git a/sys/arch/i386/isa/pcvt/Util/fonts/vt220h.810.uu b/sys/arch/i386/isa/pcvt/Util/fonts/vt220h.810.uu
new file mode 100644
index 00000000000..04689b1585b
--- /dev/null
+++ b/sys/arch/i386/isa/pcvt/Util/fonts/vt220h.810.uu
@@ -0,0 +1,60 @@
+begin 644 vt220h.810
+M1&143$0@("`@/CQ`.`1X(B(^(B(\0#@$>"(4"!0B?$!X0'PB%`@4(GQ`>$!\
+M/@@("`A\0'A`?!PB(BH<.$1\1$0D*#`H)'A$>$1X("`@(#YX1'A$>!X@'`(\
+M1$1\1$0^"`@("$!`0$!\/B`\("!$1$0H$#X("`@(?$!X0$`^(#P@(#Q`0$`\
+M/"(\)"(\0#@$>!PB(B(</$`X!'@<"`@(''A$1$1X("`@(#YX1$1$>`0,!`0.
+M>$1$1'@<(@P0/GA$1$1X'`(,`AQX1$1$>`0($CX"1&143$0B)#@D(CQ`.`1X
+M(A0("`A\0'A`?#PB/"(\/$!`0#PB,BHF(GQ`>$!\(C8J(B(\0#@$>"(B(B(<
+M?$!X0'P>("`@'GQ`>$!`'B`<`CP\0$Q$/!X@'`(\>$1X2$0>(!P"/$1$1$0X
+M'B`<`CQPB'"(<`P2$A(,<(APB'`$#`0$#G"(<(AP'"(,$#YPB'"(<!P"#`(<
+M<(APB'`$"!(^`G"(<(AP'A`<`AQPB'"(<!P@/"(<<(APB'`^`@0("'"(<(AP
+M'"(<(AQPB'"(<!PB'@(<<(APB'`,$AX2$G"(<(AP'!(<$AQPB'"(<`X0$!`.
+M<(APB'`<$A(2''"(<(AP'A`<$!YPB'"(<!X0'!`0<(AX"'`,$A(2#'"(>`AP
+M!`P$!`YPB'@(<!PB#!`^<(AX"'`<`@P"''"(>`AP!`@2/@)PB'@(<!X0'`(<
+M<(AX"'`<(!PB''"(>`AP/@($"`APB'@(<!PB'"(<<(AX"'`<(AX"''"(>`AP
+M#!(>$A)PB'@(<!P2'!(<<(AX"'`.$!`0#G"(>`AP'!(2$AQPB'@(<!X0'!`>
+M<(AX"'`>$!P0$```?,;&QOS`P,````#&5%14?!@8`'S&!@9^QL9\``!@L#`8
+M&"Q-A@`````8.!@8&!H,````_+8V-C8&!`````!\Y'#D?`````#"I!@8*L8`
+M``""@D1$*"@0$```$!`H*$1$@H(``,;&QL;&QGP`````_`8&!@;\`````'[`
+MP,#`?@```,)")!@8)!@```#^@B@X*(+^``#&5%14?#@0.````/YL;&QL;.X`
+M````!/X!_@0``````"1^@7XD`````!`0*"A$1.X``#A$@JJZJH)$.````-QV
+M`/X``````/Z"Q,1H:#```!@8+"Q$1H;^```````V2$@V`````!@8``!F9@``
+M`!PT,#`P,+#@```!`@0($"!`@```@$`@$`@$`@$```$"!`@0($#_`````#\0
+M"`0"`0`8&!@P8#`8&!@8&!@8#`8,&!@8&```#A@8&!@8&!@8&!@8&!@8&`X`
+M``!P&!@8&!@8&!@8&!@8&!@8<`````("`B(2"@8``````.[&UM9\``!F9CP8
+M&'X8&`!8)!@8)#A@>`1X`!@P`,;&QGX,>`#`P/C,S/C`P```4"!0&`P\9F8\
+M`/!@>&QX8&#P``8,`&9F/!@8/`````!$*!`H1````/QF9O9F9F;\`/`0<!;N
+M&C9JSH(`````````&`QX&#!@````````````````_@``````?(*ZJKJRJH)\
+M``````!X``````````!X"`@```#&Q@````````````($?@@0?B!`````````
+M`````/\`````````_P````````#_`````````/\`````````_P``````````
+M````[FYF9BP8```"?,[6UN9\@`````!\UM;<T'P``';<`'S&QL9\`';<`'@,
+M?,S,=@#,`,S,2'@P,'@`.&P`QL;&QL9\``P8`,;&QL;&?``P&`#&QL;&QGP`
+M`CILSM;F;+B```!^S,S.S,S,?@!VS#ALQL;&;#@`.,8X;,;&QFPX``X`.&S&
+MQL9L.`!P`#ALQL;&;#@`9@`\&!@8&!@\`!@D`#P8&!@8/``,&``\&!@8&#P`
+M,!@`/!@8&!@\`,8`_F9B>&!B_@`X;`#^8GA@8OX`,!@`_F)X8&+^`';<`!`X
+M;,;^Q@`X;``0.&S&_L8`#!@`$#ALQO[&`&`P`!`X;,;^Q@``#!P,#!X`````
+M`````!@8```````('CID8'@\!!@`>`PX#'@``````'R"FJ*BHIJ"?`##VSQF
+M9CS;PP``````S%1@4$P``'S&QF`P,``P``!\QL9@,#``,```?,;&8#`P`#``
+M`'S&QF`P,``P``!\QL9@,#``,```?,;&8#`P`#```'S&QF`P,``P``!\QL9@
+M,#``,```?,;&8#`P`#```'S&QF`P,``P``!\QL9@,#``,```?,;&8#`P`#``
+M`'S&QF`P,``P``!\QL9@,#``,```?,;&8#`P`#```'S&QF`P,``P``!\QL9@
+M,#``,```?,;&8#`P`#```'S&QF`P,``P``!\QL9@,#``,```?,;&8#`P`#``
+M`'S&QF`P,``P``!\QL9@,#``,```?,;&8#`P`#```'S&QF`P,``P``!\QL9@
+M,#``,```?,;&8#`P`#```'S&QF`P,``P``!\QL9@,#``,```?,;&8#`P`#``
+M`'S&QF`P,``P``!\QL9@,#``,```?,;&8#`P`#```'S&QF`P,``P``!\QL9@
+M,#``,```?,;&8#`P`#```'S&QF`P,``P``!\QL9@,#``,```?,;&8#`P`#``
+M`'S&QF`P,``P``!\QL9@,#``,```?,;&8#`P`#```'S&QF`P,``P``!\QL9@
+M,#``,```?,;&8#`P`#```'S&QF`P,``P``!\QL9@,#``,```?,;&8#`P`#``
+M`'S&QF`P,``P``!\QL9@,#``,```?,;&8#`P`#```'S&QF`P,``P``!\QL9@
+M,#``,```?,;&8#`P`#```'S&QF`P,``P``!\QL9@,#``,```?,;&8#`P`#``
+M`'S&QF`P,``P``!\QL9@,#``,```?,;&8#`P`#```'S&QF`P,``P``!\QL9@
+M,#``,```?,;&8#`P`#```'S&QF`P,``P``!\QL9@,#``,```?,;&8#`P`#``
+M`'S&QF`P,``P``!\QL9@,#``,```?,;&8#`P`#```'S&QF`P,``P``!\QL9@
+M,#``,```?,;&8#`P`#```'S&QF`P,``P``!\QL9@,#``,```?,;&8#`P`#``
+M`'S&QF`P,``P``!\QL9@,#``,```?,;&8#`P`#```'S&QF`P,``P``!\QL9@
+M,#``,```?,;&8#`P`#```'S&QF`P,``P``!\QL9@,#``,```?,;&8#`P`#``
+M`'S&QF`P,``P``!\QL9@,#``,```?,;&8#`P`#```'S&QF`P,``P``!\QL9@
+M,#``,```?,;&8#`P`#```'S&QF`P,``P``!\QL9@,#``,```?,;&8#`P`#``
+H`'S&QF`P,``P``!\QL9@,#``,```?,;&8#`P`#```'S&QF`P,``P`#`P
+`
+end
diff --git a/sys/arch/i386/isa/pcvt/Util/fonts/vt220h.814.uu b/sys/arch/i386/isa/pcvt/Util/fonts/vt220h.814.uu
new file mode 100644
index 00000000000..9d49552c3bb
--- /dev/null
+++ b/sys/arch/i386/isa/pcvt/Util/fonts/vt220h.814.uu
@@ -0,0 +1,83 @@
+begin 644 vt220h.814
+M`$1D5$Q$`"`@("`^````/$`X!'@`(B(^(B(````\0#@$>``B%`@4(@```'Q`
+M>$!\`"(4"!0B````?$!X0'P`/@@("`@```!\0'A`?``<(B(J'`(``#A$?$1$
+M`"0H,"@D````>$1X1'@`("`@(#X```!X1'A$>``>(!P"/````$1$?$1$`#X(
+M"`@(````0$!`0'P`/B`\("````!$1$0H$``^"`@("````'Q`>$!``#X@/"`@
+M````/$!`0#P`/"(\)"(````\0#@$>``<(B(B'````#Q`.`1X`!P("`@<````
+M>$1$1'@`("`@(#X```!X1$1$>``$#`0$#@```'A$1$1X`!PB#!`^````>$1$
+M1'@`'`(,`AP```!X1$1$>``$"!(^`@```$1D5$Q$`"(D."0B````/$`X!'@`
+M(A0("`@```!\0'A`?``\(CPB/````#Q`0$`\`"(R*B8B````?$!X0'P`(C8J
+M(B(````\0#@$>``B(B(B'````'Q`>$!\`!X@("`>````?$!X0$``'B`<`CP`
+M```\0$Q$/``>(!P"/````'A$>$A$`!X@'`(\````1$1$1#@`'B`<`CP```!P
+MB'"(<``,$A(2#````'"(<(AP``0,!`0.````<(APB'``'"(,$#X```!PB'"(
+M<``<`@P"'````'"(<(AP``0($CX"````<(APB'``'A`<`AP```!PB'"(<``<
+M(#PB'````'"(<(AP`#X"!`@(````<(APB'``'"(<(AP```!PB'"(<``<(AX"
+M'````'"(<(AP``P2'A(2````<(APB'``'!(<$AP```!PB'"(<``.$!`0#@``
+M`'"(<(AP`!P2$A(<````<(APB'``'A`<$!X```!PB'"(<``>$!P0$````'"(
+M>`AP``P2$A(,````<(AX"'``!`P$!`X```!PB'@(<``<(@P0/@```'"(>`AP
+M`!P"#`(<````<(AX"'``!`@2/@(```!PB'@(<``>$!P"'````'"(>`AP`!P@
+M'"(<````<(AX"'``/@($"`@```!PB'@(<``<(APB'````'"(>`AP`!PB'@(<
+M````<(AX"'``#!(>$A(```!PB'@(<``<$AP2'````'"(>`AP``X0$!`.````
+M<(AX"'``'!(2$AP```!PB'@(<``>$!P0'@```'"(>`AP`!X0'!`0````````
+M`'S&QL;&_,#`P``````8V]O;V]M^&!@8````?,8&!G[&QGP``````,#`8#`8
+M'#9C00`````````P<#`P,#08``````````#<9F9F9F8&!@8``````'S&\,#&
+M?`````````#BMAP8.&S&````````@L;&;&PX.!`````````0.#AL;,;&@@``
+M`````,;&QL;&QL9\`````````/P&!@8&_```````````?L#`P,!^````````
+M``#&9CP8/&8\``````#^Q@!L?&P`QOX``````#P8V]O;VWX8/```````_FQL
+M;&QL;&SN````````"`S^`_X,"``````````D9G[#?F8D```````````0$"@H
+M1$3N```````\9L/G_^?#9CP``````````-QV`/X``````````/[&QLQL:#@P
+M````````&#@L;$3&QOX``````````&[8V&X````````````8&```9F8`````
+M```<-#`P,#`PL.`````````!`@0($"!`@````````(!`(!`(!`(!````````
+M``$"!`@0('\````````````_$`@$`@$``!@8&!@8,&`P&!@8&!@8&!@8&!@,
+M!@P8&!@8&!@```X8&!@8&!@8&!@8&!@8&!@8&!@8&!@.``````!P&!@8&!@8
+M&!@8&!@8&!@8&!@8&!@8<````````@("`B(2"@8"``````````!LQM;6UFP`
+M`````,S,>#`P_#`P,```````X'S@P'C`P&`X#'@```P8,`#&QL;&?@8,>```
+M`,#`^,S,^,#`P`````#8<.`P&`P^9F8\``````#P8'AL>&!@8/`````,&`#,
+MS,QX,#`P>`````````!$*!`H1`````````#\9F9F]F9F9OP```#P$'`6_!@P
+M9LZ:/@8&```````````````8#'@`&#!@``````````````````````#^````
+M````````?(*ZJKJRJH)\````````````>````````````````'@("```````
+M`,;&`````````````````````@9^"!!^8$```````````````````/\`````
+M`````````/\``````````````/\``````````````/\``````````````/\`
+M``````````````````#N;F9F;#@````````&?,[>]N9\P```````````?-;6
+MW-!^``````!VW`!\QL;&QGP``````';<`'@,?,S,=@```,S,`,S,2'@P,#!X
+M````.&S&`,;&QL;&QGP````&#!@`QL;&QL;&?````&`P&`#&QL;&QL9\````
+M```&/FS.UM;F;/C``````'[,S,S.S,S,?@```';<`#ALQL;&QFPX````.&S&
+M.&S&QL;&;#@````,&``X;,;&QL9L.````&`P`#ALQL;&QFPX````9F8`/!@8
+M&!@8&#P````\9@`\&!@8&!@8/`````P8`#P8&!@8&!@\````,!@`/!@8&!@8
+M&#P```#&Q@#^9F)X8&)F_@```#ALQ@#^9F!X8&;^````,!@,`/YF8'A@9OX`
+M``!VW``0.&S&QO[&Q@```#ALQA`X;,;&_L;&````#!@`$#ALQL;^QL8````P
+M&``0.&S&QO[&Q@`````,'`P,'@`````````````````8&````````````.`\
+M8,#`P,!@.`QX```\!AP&/`````````````!\@IJBHJ*:@GP```````##VSQF
+M9CS;PP``````````YFQX;&9F``````!\QL9@,#``,#```````'S&QF`P,``P
+M,```````?,;&8#`P`#`P``````!\QL9@,#``,#```````'S&QF`P,``P,```
+M````?,;&8#`P`#`P``````!\QL9@,#``,#```````'S&QF`P,``P,```````
+M?,;&8#`P`#`P``````!\QL9@,#``,#```````'S&QF`P,``P,```````?,;&
+M8#`P`#`P``````!\QL9@,#``,#```````'S&QF`P,``P,```````?,;&8#`P
+M`#`P``````!\QL9@,#``,#```````'S&QF`P,``P,```````?,;&8#`P`#`P
+M``````!\QL9@,#``,#```````'S&QF`P,``P,```````?,;&8#`P`#`P````
+M``!\QL9@,#``,#```````'S&QF`P,``P,```````?,;&8#`P`#`P``````!\
+MQL9@,#``,#```````'S&QF`P,``P,```````?,;&8#`P`#`P``````!\QL9@
+M,#``,#```````'S&QF`P,``P,```````?,;&8#`P`#`P``````!\QL9@,#``
+M,#```````'S&QF`P,``P,```````?,;&8#`P`#`P``````!\QL9@,#``,#``
+M`````'S&QF`P,``P,```````?,;&8#`P`#`P``````!\QL9@,#``,#``````
+M`'S&QF`P,``P,```````?,;&8#`P`#`P``````!\QL9@,#``,#```````'S&
+MQF`P,``P,```````?,;&8#`P`#`P``````!\QL9@,#``,#```````'S&QF`P
+M,``P,```````?,;&8#`P`#`P``````!\QL9@,#``,#```````'S&QF`P,``P
+M,```````?,;&8#`P`#`P``````!\QL9@,#``,#```````'S&QF`P,``P,```
+M````?,;&8#`P`#`P``````!\QL9@,#``,#```````'S&QF`P,``P,```````
+M?,;&8#`P`#`P``````!\QL9@,#``,#```````'S&QF`P,``P,```````?,;&
+M8#`P`#`P``````!\QL9@,#``,#```````'S&QF`P,``P,```````?,;&8#`P
+M`#`P``````!\QL9@,#``,#```````'S&QF`P,``P,```````?,;&8#`P`#`P
+M``````!\QL9@,#``,#```````'S&QF`P,``P,```````?,;&8#`P`#`P````
+M``!\QL9@,#``,#```````'S&QF`P,``P,```````?,;&8#`P`#`P``````!\
+MQL9@,#``,#```````'S&QF`P,``P,```````?,;&8#`P`#`P``````!\QL9@
+M,#``,#```````'S&QF`P,``P,```````?,;&8#`P`#`P``````!\QL9@,#``
+M,#```````'S&QF`P,``P,```````?,;&8#`P`#`P``````!\QL9@,#``,#``
+M`````'S&QF`P,``P,```````?,;&8#`P`#`P``````!\QL9@,#``,#``````
+M`'S&QF`P,``P,```````?,;&8#`P`#`P``````!\QL9@,#``,#```````'S&
+MQF`P,``P,```````?,;&8#`P`#`P``````!\QL9@,#``,#```````'S&QF`P
+M,``P,```````?,;&8#`P`#`P``````!\QL9@,#``,#```````'S&QF`P,``P
+M,```````?,;&8#`P`#`P``````!\QL9@,#``,#```````'S&QF`P,``P,```
+=````?,;&8#`P`#`P``````!\QL9@,#``,#``````
+`
+end
diff --git a/sys/arch/i386/isa/pcvt/Util/fonts/vt220h.816.uu b/sys/arch/i386/isa/pcvt/Util/fonts/vt220h.816.uu
new file mode 100644
index 00000000000..401db375c16
--- /dev/null
+++ b/sys/arch/i386/isa/pcvt/Util/fonts/vt220h.816.uu
@@ -0,0 +1,95 @@
+begin 644 vt220h.816
+M``!$9%1,1``@("`@/@``````/$`X!'@`(B(^(B(``````#Q`.`1X`"(4"!0B
+M``````!\0'A`?``B%`@4(@``````?$!X0'P`/@@("`@``````'Q`>$!\`!PB
+M(BH<`@`````X1'Q$1``D*#`H)```````>$1X1'@`("`@(#X``````'A$>$1X
+M`!X@'`(\``````!$1'Q$1``^"`@("```````0$!`0'P`/B`\("```````$1$
+M1"@0`#X("`@(``````!\0'A`0``^(#P@(```````/$!`0#P`/"(\)"(`````
+M`#Q`.`1X`!PB(B(<```````\0#@$>``<"`@('```````>$1$1'@`("`@(#X`
+M`````'A$1$1X``0,!`0.``````!X1$1$>``<(@P0/@``````>$1$1'@`'`(,
+M`AP``````'A$1$1X``0($CX"``````!$9%1,1``B)#@D(@``````/$`X!'@`
+M(A0("`@``````'Q`>$!\`#PB/"(\```````\0$!`/``B,BHF(@``````?$!X
+M0'P`(C8J(B(``````#Q`.`1X`"(B(B(<``````!\0'A`?``>("`@'@``````
+M?$!X0$``'B`<`CP``````#Q`3$0\`!X@'`(\``````!X1'A(1``>(!P"/```
+M````1$1$1#@`'B`<`CP`````<(APB'``#!(2$@P``````'"(<(AP``0,!`0.
+M``````!PB'"(<``<(@P0/@``````<(APB'``'`(,`AP``````'"(<(AP``0(
+M$CX"``````!PB'"(<``>$!P"'```````<(APB'``'"`\(AP``````'"(<(AP
+M`#X"!`@(``````!PB'"(<``<(APB'```````<(APB'``'"(>`AP``````'"(
+M<(AP``P2'A(2``````!PB'"(<``<$AP2'```````<(APB'``#A`0$`X`````
+M`'"(<(AP`!P2$A(<``````!PB'"(<``>$!P0'@``````<(APB'``'A`<$!``
+M`````'"(>`AP``P2$A(,``````!PB'@(<``$#`0$#@``````<(AX"'``'"(,
+M$#X``````'"(>`AP`!P"#`(<``````!PB'@(<``$"!(^`@``````<(AX"'``
+M'A`<`AP``````'"(>`AP`!P@/"(<``````!PB'@(<``^`@0("```````<(AX
+M"'``'"(<(AP``````'"(>`AP`!PB'@(<``````!PB'@(<``,$AX2$@``````
+M<(AX"'``'!(<$AP``````'"(>`AP``X0$!`.``````!PB'@(<``<$A(2'```
+M````<(AX"'``'A`<$!X``````'"(>`AP`!X0'!`0`````````````#YC8V-C
+M?F!@8&```````!C;V]O;VWX8&!@8`````'S&!@9^QL9\`````````,#`8#`8
+M'#9C00```````````#!P,#`P-!@`````````````W&9F9F9F!@8&!@``````
+M``!\Y'#D?````````````.:V'!@X;,8```````````""QD1L*#@0````````
+M````$#@H;$3&@@````````#&QL;&QL;&QGP``````````/P&!@8&_```````
+M``````!^P,#`P'X``````````````,9F/!@\9CP```````#^Q@!L?'QL`,;^
+M```````\&-O;V]O;?A@8/````````/YL;&QL;&QL;.X```````````@,_@/^
+M#`@````````````D9G[#?F8D````````````$!`X*&Q$1.X````````X1(*J
+MNKJJ@D0X````````````W'8`_@``````````````_H+$Q&AH,#``````````
+M`!@8+"Q$1H;^````````````=HB(=@``````````````&!@``&9F````````
+M```,'A@8&!@8&'@P```````````!`@0($"!`@```````````@$`@$`@$`@$`
+M```````````!`@0($"!_```````````````_$`@$`@$````8&!@8&!@P8#`8
+M&!@8&!@8&!@8&!@8#`8,&!@8&!@8&```#A@8&!@8&!@8&!@8&!@8&!@8&!@8
+M&!@8&`X```````!P&!@8&!@8&!@8&!@8&!@8&!@8&!@8&!@8<``````````"
+M`@("(A(*!@(``````````````&S&UM9L````````9F9F/!@8?A@8&```````
+M<#YP8#Q@8#`<!CP`````````#!@P`,;&QL9^!@QX````P,#XS,S,^,#`P```
+M`````+!@X+`8##YF9CP```````#P8'QF9GQ@8&#P``````P8`,S,S'@P,#`P
+M>```````````1"@0*$0```````````#\9F9F]F9F9F;\`````.`0<!#F#!@P
+M9LJ2/@(``````````````````!@,>```&#!@````````````````````````
+M``#^`````````````'R"NJJJLJJJ@GP``````````````'@`````````````
+M`````'@("`````````#&Q@```````````````````````@9^"!!^8$``````
+M````````````````_P````````````````#_`````````````````/\`````
+M````````````_P````````````````#_````````````````````````YF9B
+M8C08```````````&?,[>]N9\P`````````````!\UM;<T'X`````````=MP`
+M?,;&QL9\`````````';<`'@,?,S,=@````#,S`#,S,QX,#`P,'@`````.&S&
+M`,;&QL;&QL9\``````8,&`#&QL;&QL;&?`````!@,!@`QL;&QL;&QGP`````
+M```&/FS.WO;F;/C`````````?MC8V-[>V-C8?@````!VW``X;,;&QL;&;#@`
+M````.&S&.&S&QL;&QFPX``````P8`#ALQL;&QL9L.`````!@,``X;,;&QL;&
+M;#@`````9F8`/!@8&!@8&!@\`````!@\9@`\&!@8&!@8/``````&#!@`/!@8
+M&!@8&#P`````8#`8`#P8&!@8&!@\`````,;&`/YB8&!\8&!B_@`````X;,8`
+M_F)@?&!@8OX`````8#`8`/YB8'Q@8&+^`````';<`!`X;,;&_L;&Q@`````X
+M;,80.&S&QO[&QL8`````&#!@$#ALQL;^QL;&`````#`8#!`X;,;&_L;&Q@``
+M````"!@("!P`````````````````````&!@`````````````X#Q@P,#`8#@,
+M>```````.`08!#@```````````````!\@IJBHJ*BFH)\``````````##VSQF
+M9CS;PP``````````````YFYX;&8```````!\QL9@,#`P`#`P````````````
+M`````````````````'S&QF`P,#``,#````````!\QL9@,#`P`#`P````````
+M?,;&8#`P,``P,````````'S&QF`P,#``,#````````!\QL9@,#`P`#`P````
+M````?,;&8#`P,``P,````````'S&QF`P,#``,#````````!\QL9@,#`P`#`P
+M````````?,;&8#`P,``P,````````'S&QF`P,#``,#````````!\QL9@,#`P
+M`#`P````````?,;&8#`P,``P,````````'S&QF`P,#``,#````````!\QL9@
+M,#`P`#`P````````?,;&8#`P,``P,````````'S&QF`P,#``,#````````!\
+MQL9@,#`P`#`P````````?,;&8#`P,``P,````````'S&QF`P,#``,#``````
+M``!\QL9@,#`P`#`P````````?,;&8#`P,``P,````````'S&QF`P,#``,#``
+M``````!\QL9@,#`P`#`P````````?,;&8#`P,``P,````````'S&QF`P,#``
+M,#````````!\QL9@,#`P`#`P````````?,;&8#`P,``P,````````'S&QF`P
+M,#``,#````````!\QL9@,#`P`#`P````````?,;&8#`P,``P,````````'S&
+MQF`P,#``,#````````!\QL9@,#`P`#`P````````?,;&8#`P,``P,```````
+M`'S&QF`P,#``,#````````!\QL9@,#`P`#`P````````?,;&8#`P,``P,```
+M`````'S&QF`P,#``,#````````!\QL9@,#`P`#`P````````?,;&8#`P,``P
+M,````````'S&QF`P,#``,#````````!\QL9@,#`P`#`P````````?,;&8#`P
+M,``P,````````'S&QF`P,#``,#````````!\QL9@,#`P`#`P````````?,;&
+M8#`P,``P,````````'S&QF`P,#``,#````````!\QL9@,#`P`#`P````````
+M?,;&8#`P,``P,````````'S&QF`P,#``,#````````!\QL9@,#`P`#`P````
+M````?,;&8#`P,``P,````````'S&QF`P,#``,#````````!\QL9@,#`P`#`P
+M````````?,;&8#`P,``P,````````'S&QF`P,#``,#````````!\QL9@,#`P
+M`#`P````````?,;&8#`P,``P,````````'S&QF`P,#``,#````````!\QL9@
+M,#`P`#`P````````?,;&8#`P,``P,````````'S&QF`P,#``,#````````!\
+MQL9@,#`P`#`P````````?,;&8#`P,``P,````````'S&QF`P,#``,#``````
+M``!\QL9@,#`P`#`P````````?,;&8#`P,``P,````````'S&QF`P,#``,#``
+M``````!\QL9@,#`P`#`P````````?,;&8#`P,``P,````````'S&QF`P,#``
+M,#````````!\QL9@,#`P`#`P````````?,;&8#`P,``P,````````'S&QF`P
+M,#``,#````````!\QL9@,#`P`#`P````````?,;&8#`P,``P,````````'S&
+MQF`P,#``,#````````!\QL9@,#`P`#`P````````?,;&8#`P,``P,```````
+M`'S&QF`P,#``,#````````!\QL9@,#`P`#`P````````?,;&8#`P,``P,```
+M`````'S&QF`P,#``,#````````!\QL9@,#`P`#`P````````?,;&8#`P,``P
+M,````````'S&QF`P,#``,#````````!\QL9@,#`P`#`P````````?,;&8#`P
+M,``P,````````'S&QF`P,#``,#````````!\QL9@,#`P`#`P````````?,;&
+M8#`P,``P,````````'S&QF`P,#``,#````````!\QL9@,#`P`#`P````````
+M?,;&8#`P,``P,````````'S&QF`P,#``,#``````````````````````````
+!`,;&
+`
+end
diff --git a/sys/arch/i386/isa/pcvt/Util/fonts/vt220l.808.uu b/sys/arch/i386/isa/pcvt/Util/fonts/vt220l.808.uu
new file mode 100644
index 00000000000..02ad9444c47
--- /dev/null
+++ b/sys/arch/i386/isa/pcvt/Util/fonts/vt220l.808.uu
@@ -0,0 +1,49 @@
+begin 644 vt220l.808
+M``````````!^@:6!O9F!?G[_V__#Y_]^;/[^_GPX$``0.'S^?#@0`#A\./[^
+MUA`X$#A\_OY\$#@``!@\/!@``/__Y\/#Y___/&;#P\/#9CS_PYF]O9G#_Q\'
+M#7G-S,QX/&9F9CP8?A@X/#8R-'#PX']C?V-C9^;`&-L\Y^<\VQB`X/C^^."`
+M``(./OX^#@(`&#Q^&!A^/!AF9F9F9@!F`'_;VWL;&QL`?L/\9F8_PWX``'Y^
+M?@```!@\?AA^/!C_&#Q^&!@8&``8&!@8?CP8```8#/X,&````#!@_F`P````
+M`&!@8'X````D9O]F)````!`X?/[^````_OY\.!``````````````&#P\&!@`
+M&`!L;&P``````&QL_FS^;&P`,'S`?`;\,```QLP8,&;&`#AL.';<SGL`8&#`
+M```````8,&!@8#`8`#`8#`P,&#```&PX_CAL````,##\,#``````````,#!@
+M````_````````````!@8``8,&#!@P(``?,[>]N;&?``P<+`P,##\`'C,##A@
+MP/P`>,P,.`S,>``</&S,_@P>`/S`^`P,S'@`>,S`^,S,>`#\S`P8,#`P`'C,
+MS'C,S'@`>,S,?`S,>```,#```#`P```P,```,#!@&#!@P&`P&````'X``'X`
+M`#`8#`8,&#``/&8&#!@`&`!\QM[>WL!^`#!XS,S\S,P`_&9F?&9F_``\9L#`
+MP&8\`/AL9F9F;/@`_F)H>&AB_@#^8FAX:&#P`#QFP,#.9CX`S,S,_,S,S`!X
+M,#`P,#!X`!X,#`S,S'@`YFQX<'ALY@#P8&!@8F;^`,;N_M;&QL8`QN;VWL[&
+MQ@`X;,;&QFPX`/QF9GQ@8/``>,S,S-QX'`#\9F9\;&;F`'C,P'@,S'@`_+0P
+M,#`P>`#,S,S,S,QX`,S,S,S,>#``QL;&UO[^Q@#&QFPX.&S&`,S,S'@P,'@`
+M_,R8,&3,_`!X8&!@8&!X`,!@,!@,!@(`>!@8&!@8>``0.&S&````````````
+M``#_,#`8`````````'@,?,QV`.!@8'QF9OP```!XS,#,>``<#`Q\S,Q^````
+M>,S\P'@`.&Q@^&!@\````';,S'P,^.!@;'9F9N8`,`!P,#`P>``,`!P,#,S,
+M>.!@9FQX;.8`<#`P,#`P>````,S^_M;&````^,S,S,P```!XS,S,>````-QF
+M9GQ@\```=LS,?`P>``#<=F!@\````'S`?`;\`!`P?#`P-AP```#,S,S,=@``
+M`,;&QGPX````QM;^_FP```#&;#ALQ@```,S,S'P,^```_)@P9/P`'#`PX#`P
+M'``8&!@`&!@8`.`P,!PP,.``=MP````````0.&QLQL;^`'C,P,QX&`QX`,P`
+MS,S,?@`<`'C,_,!X`'[#/`8^9C\`S`!X#'S,?@#@`'@,?,Q^`#`P>`Q\S'X`
+M``!XP,!X##A^PSQF?F`\`,P`>,S\P'@`X`!XS/S`>`#,`'`P,#!X`'S&.!@8
+M&#P`X`!P,#`P>`#&.&S&_L;&`#`P`'C,_,P`'`#\8'A@_````'\,?\Q_`#YL
+MS/[,S,X`>,P`>,S,>```S`!XS,QX``#@`'C,S'@`>,P`S,S,?@``X`#,S,Q^
+M``#,`,S,?`SXPQ@\9F8\&`#,`,S,S,QX`!@8?L#`?A@8.&QD\&#F_`#,S'C\
+M,/PP,/C,S/K&S\;'#AL8/!@8V'`<`'@,?,Q^`#@`<#`P,'@``!P`>,S,>```
+M'`#,S,Q^``#X`/C,S,P`_`#,[/S<S``\;&P^`'X``#AL;#@`?```,``P8,#,
+M>`````#\P,```````/P,#```P\;,WC-FS`_#QLS;-V_/`Q@8`!@8&!@``#-F
+MS&8S````S&8S9LP``"*((H@BB"*(5:I5JE6J5:K;=]ONVW?;[A@8&!@8&!@8
+M&!@8&/@8&!@8&/@8^!@8&#8V-C;V-C8V`````/XV-C8``/@8^!@8&#8V]@;V
+M-C8V-C8V-C8V-C8``/X&]C8V-C8V]@;^````-C8V-OX````8&/@8^```````
+M``#X&!@8&!@8&!\````8&!@8_P````````#_&!@8&!@8&!\8&!@`````_P``
+M`!@8&!C_&!@8&!@?&!\8&!@V-C8V-S8V-C8V-S`_```````_,#<V-C8V-O<`
+M_P``````_P#W-C8V-C8W,#<V-C8``/\`_P```#8V]P#W-C8V&!C_`/\````V
+M-C8V_P``````_P#_&!@8`````/\V-C8V-C8V/P```!@8'Q@?```````?&!\8
+M&!@`````/S8V-C8V-C;_-C8V&!C_&/\8&!@8&!@8^``````````?&!@8____
+M______\`````______#P\/#P\/#P#P\/#P\/#P______````````=MS(W'8`
+M`'C,^,SXP,``_,S`P,#```#^;&QL;&P`_,Q@,&#,_````'[8V-AP``!F9F9F
+M?&#``';<&!@8&`#\,'C,S'@P_#ALQO[&;#@`.&S&QFQL[@`<,!A\S,QX````
+M?MO;?@``!@Q^V]M^8,`\8,#\P&`\`'C,S,S,S,P``/P`_`#\```P,/PP,`#\
+M`&`P&#!@`/P`&#!@,!@`_``.&QL8&!@8&!@8&!@8V-AP,#``_``P,```=MP`
+M=MP``#AL;#@`````````&!@`````````&`````\,#`SL;#P<>&QL;&P```!P
+7&#!@>```````/#P\/```````````````
+`
+end
diff --git a/sys/arch/i386/isa/pcvt/Util/fonts/vt220l.810.uu b/sys/arch/i386/isa/pcvt/Util/fonts/vt220l.810.uu
new file mode 100644
index 00000000000..7cba2cb91aa
--- /dev/null
+++ b/sys/arch/i386/isa/pcvt/Util/fonts/vt220l.810.uu
@@ -0,0 +1,60 @@
+begin 644 vt220l.810
+M`````````````'Z!I:6!@;V9@7Y^_]O;___#Y_]^;/[^?'PX.!`0````$#A\
+M_GPX$``X?'PX?/[^?#A\$!`X.'S^_GPX?````!@\/!@```#____GP\/G____
+M```\9D)"9CP``/__PYF]O9G#__\`#P</?<S,S'@``#QF9F8\&'X8`#\S/S`P
+M,'#PX`!_8W]C8V-GYL```-M^/.?G/'[;````@.#X_OC@@`````(./OX^#@(`
+M&!@\?A@8?CP8&&9F9F9F9@!F9@!_V]O;>QL;&QL`/&8P;,9L&,QX````````
+M?GY^?@`8&#Q^&!A^/!C_&!@\/'X8&!@8&!@8&!@8?CP\&!@`````&`S^#!@`
+M`````#!@_F`P``````#`P,#`_@``````)&;_9B0``!@8/#Q^?O__``#__WY^
+M/#P8&```````````````,'AX>#`P`#`P`&QL;"@```````!L;/YL;&S^;&P`
+M&'[8V'PV-OPP`,;,#!@X,&!FQ@`X;&PX,';<S'8`X.!@8,````````P8,#`P
+M,#`8#`!@,!@8&!@8,&````#&;#C^.&S&`````#`P_#`P````````<'`P,&``
+M``````#^```````````````P,```#`P8&#`P8&``?,;.WM;VYL9\`#!P,#`P
+M,#`P_`!\QL8&##A@QOX`?,;&!CP&QL9\``P,'#QLS/X,'@#^P,#\!@8&QGP`
+M'#!@P/S&QL9\`/[&!@P,&!@8&`!\QL;&?,;&QGP`?,;&QGX&#!AP`````#`P
+M```P,````#`P```P,&`````8,&#`8#`8``````#\``#\`````&`P&`P8,&``
+M?,;&!@P8&``8`'S&SMK6WL#&?``X?,;&QO[&QL8`_&9F9GQF9F;\`#QFP,#`
+MP,!F/`#X;&9F9F9F;/@`_F)@:'AH8&+^`/YB8&AX:&!@\``\9L#`P,[&9CP`
+MQL;&QO[&QL;&`#P8&!@8&!@8/``>#`P,#`S,S'@`YF9L;'AL;&;F`/!@8&!@
+M8&)F_@#&[O[^UL;&QL8`QN;F]M[.SL;&`#ALQL;&QL9L.`#\9F9F?&!@8/``
+M?,;&QL;&SGP.`/QF9F9X;&QFY@!\QL!@.`P&QGP`?EH8&!@8&!@\`,;&QL;&
+MQL;&?`!F9F9F9F9F/!@`QL;&QL;6_N[&`,;&;#@0.&S&Q@#,S,S,>#`P,'@`
+M_L:,&#!@PL;^`!X8&!@8&!@8'@``8&`P,!@8#`P`\#`P,#`P,##P`!`X;,8`
+M``````````````````#_,#`8`````````````'@,?,S,=@#@8&!\9F9F9MP`
+M````?,;`P,9\`!P,#'S,S,S,=@````!\QO[`P'P`.&Q@\&!@8&#P`````';,
+MS'P,S'C@8&!L=F9F9N8`,#``<#`P,#!X``P,``P,#`S,S'C@8&!F;'AX;.8`
+M<#`P,#`P,#!X`````,S^_M;6U@````#<YL;&QL8`````?,;&QL9\`````-QF
+M9F9\8/````!VS,S,?`P>````W'9F8&#P`````'S&<!S&?``@8&#\8&!@;#@`
+M````S,S,S,QV`````,;&QL9L.`````#&UM;^_FP`````QFPX.&S&`````,;&
+MQGX&!OP```#^C!@P8OX`#A@8&'`8&!@.`!@8&!@`&!@8&`#@,#`P'#`P,.``
+M=MP``````````````!`X;,;&_@!\QL#`P,9\#`8\`,P`S,S,S,QV```.`'S&
+M_L#`?``\9@`\!CYF9C\``,P`>`Q\S,QV``!P`'@,?,S,=@`P,`!X#'S,S'8`
+M````?L#`P'X&/#QF`#QF?F!@/`#,``!\QO[`P'P``'``?,;^P,!\``#,`'`P
+M,#`P>``X;``X&!@8&#P``.``<#`P,#!X`,8`.&S&_L;&Q@`P,`!XS/S,S,P`
+M'`#\8&!X8&#\`````'X;?MC8?P`^;,S,_LS,S,X`.&P`?,;&QL9\``#&`'S&
+MQL;&?```<`!\QL;&QGP`>,P`S,S,S,QV``!P`,S,S,S,=@``Q@#&QL9^!@;\
+MQCALQL;&QFPX`,8`QL;&QL;&?``8&'[`P,#`?A@8.&QD8/A@8.;\`,S,>##\
+M,/PP,`#XS,S,^L;/QL<`#AL8&#P8&!C8<``<`'@,?,S,=@``.`!P,#`P,'@`
+M`!P`?,;&QL9\```<`,S,S,S,=@!P_AP`W.;&QL8`_@#&YO;^WL[&`#QL;&P^
+M`'X````X;&QL.`!\````,``P,&#`QL9\``````#^P,``````````_@8&````
+MP\;,V#Y[PP8,#\/&S-DS9\T/`P,8&``8&#P\/!@`````,V;,9C,``````,QF
+M,V;,```BB"*((H@BB"*(5:I5JE6J5:I5JMMWV^[;=]ONVW<8&!@8&!@8&!@8
+M&!@8&!CX&!@8&!@8&/@8^!@8&!@V-C8V-O8V-C8V``````#^-C8V-@```/@8
+M^!@8&!@V-C;V!O8V-C8V-C8V-C8V-C8V-@```/X&]C8V-C8V-C;V!OX`````
+M-C8V-C;^`````!@8&/@8^````````````/@8&!@8&!@8&!@?`````!@8&!@8
+M_P```````````/\8&!@8&!@8&!@?&!@8&```````_P`````8&!@8&/\8&!@8
+M&!@8'Q@?&!@8&#8V-C8V-S8V-C8V-C8W,#\`````````/S`W-C8V-C8V-O<`
+M_P````````#_`/<V-C8V-C8V-S`W-C8V-@```/\`_P`````V-C;W`/<V-C8V
+M&!@8_P#_`````#8V-C8V_P````````#_`/\8&!@8``````#_-C8V-C8V-C8V
+M/P`````8&!@?&!\`````````'Q@?&!@8&```````/S8V-C8V-C8V-O\V-C8V
+M&!@8_QC_&!@8&!@8&!@8^````````````!\8&!@8_____________P``````
+M_______P\/#P\/#P\/#P#P\/#P\/#P\/#_______``````````!VW-C,W'8`
+M`'S&QMS&QMS`P/YF9&!@8&!@\`#^;&QL;&QL;.X`_L9@,!@P8,;^`````'_,
+MS,S,>`````!F9F9V;&#`````=MP8&!@8`#P8?MO;VWX8/``X;,;&_L;&;#@`
+M.&S&QL9L;&SN`!PR,!A\S,S,>`````!VV]O;;@```P9\S]O;\SY@P```'#!@
+M?&`P'````'S&QL;&QL8`````_@#^`/X`````,##\,#``_`!@,!@,&#!@`/X`
+M#!@P8#`8#`#^``X;&Q@8&!@8&!@8&!@8&!@8V-AP```P,`#\`#`P`````';<
+M`';<```X;&QL.````````````!@8````````````&``````/#`P,[&QL-#P<
+H>&QL;&QL`````'#8&'#`^``````````\/#P\`````````````````&QL
+`
+end
diff --git a/sys/arch/i386/isa/pcvt/Util/fonts/vt220l.814.uu b/sys/arch/i386/isa/pcvt/Util/fonts/vt220l.814.uu
new file mode 100644
index 00000000000..7d918bbe1c4
--- /dev/null
+++ b/sys/arch/i386/isa/pcvt/Util/fonts/vt220l.814.uu
@@ -0,0 +1,83 @@
+begin 644 vt220l.814
+M`````````````````````'Z!I8&!O9F!?@``````?O_;___#Y_]^````````
+M;/[^_OY\.!`````````0.'S^?#@0````````&#P\Y^?G&!@\```````8/'[_
+M_WX8&#P``````````!@\/!@``````/______Y\/#Y_______`````#QF0D)F
+M/`````#_____PYF]O9G#_____P``'@X:,GC,S,QX```````\9F9F/!A^&!@`
+M`````#\S/S`P,'#PX```````?V-_8V-C9^?FP``````8&-L\YSS;&!@`````
+M`(#`X/C^^.#`@````````@8./OX^#@8"```````8/'X8&!A^/!@``````&9F
+M9F9F9@!F9@``````?]O;VWL;&QL;`````'S&8#ALQL9L.`S&?```````````
+M`/[^_@``````&#Q^&!@8?CP8?@`````8/'X8&!@8&!@``````!@8&!@8&'X\
+M&``````````8#/X,&````````````#!@_F`P`````````````,#`P/X`````
+M```````H;/YL*```````````$#@X?'S^_@````````#^_GQ\.#@0````````
+M```````````````````8/#P\&!@`&!@`````9F9F)```````````````;&S^
+M;&QL_FQL````&!A\QL+`?`:&QGP8&```````PL8,&#!FQ@``````.&QL.';<
+MS,QV`````#`P,&````````````````P8,#`P,#`8#```````,!@,#`P,#!@P
+M`````````&8\_SQF````````````&!A^&!@`````````````````&!@8,```
+M````````_@`````````````````````8&````````@8,&#!@P(````````!\
+MQL[>]N;&QGP``````!@X>!@8&!@8?@``````?,8&#!@P8,;^``````!\Q@8&
+M/`8&QGP```````P</&S,_@P,'@``````_L#`P/P&!L9\```````X8,#`_,;&
+MQGP``````/[&!@P8,#`P,```````?,;&QGS&QL9\``````!\QL;&?@8&#'@`
+M```````8&````!@8`````````!@8````&!@P```````&#!@P8#`8#`8`````
+M`````'X``'X`````````8#`8#`8,&#!@``````!\QL8,&!@`&!@``````'S&
+MQM[>WMS`?```````$#ALQL;^QL;&``````#\9F9F?&9F9OP``````#QFPL#`
+MP,)F/```````^&QF9F9F9FSX``````#^9F)H>&AB9OX``````/YF8FAX:&!@
+M\```````/&;"P,#>QF8Z``````#&QL;&_L;&QL8``````#P8&!@8&!@8/```
+M````'@P,#`P,S,QX``````#F9FQL>&QL9N8``````/!@8&!@8&)F_@``````
+MQN[^_M;&QL;&``````#&YO;^WL[&QL8``````#ALQL;&QL9L.```````_&9F
+M9GQ@8&#P``````!\QL;&QM;>?`P.`````/QF9F9\;&9FY@``````?,;&8#@,
+MQL9\``````!^?EH8&!@8&#P``````,;&QL;&QL;&?```````QL;&QL;&;#@0
+M``````#&QL;&UM;^?&P``````,;&;#@X.&S&Q@``````9F9F9CP8&!@\````
+M``#^QHP8,&#"QOX``````#PP,#`P,#`P/```````@,#@<#@<#@8"```````\
+M#`P,#`P,##P````0.&S&`````````````````````````````/\`,#`8````
+M`````````````````'@,?,S,=@``````X&!@>&QF9F9\``````````!\QL#`
+MQGP``````!P,##QLS,S,=@``````````?,;^P,9\```````X;&1@\&!@8/``
+M`````````';,S,Q\#,QX````X&!@;'9F9F;F```````8&``X&!@8&#P`````
+M``8&``X&!@8&9F8\````X&!@9FQX;&;F```````X&!@8&!@8&#P`````````
+M`.S^UM;6Q@``````````W&9F9F9F``````````!\QL;&QGP``````````-QF
+M9F9\8&#P````````=LS,S'P,#!X```````#<=F9@8/```````````'S&<!S&
+M?```````$#`P_#`P,#8<``````````#,S,S,S'8``````````,;&QFPX$```
+M````````QL;6UOYL``````````#&;#@X;,8``````````,;&QL9^!@SX````
+M````_LP8,&;^```````.&!@8<!@8&`X``````!@8&!@`&!@8&```````<!@8
+M&`X8&!AP``````!VW```````````````````$#ALQL;^````````/&;"P,#"
+M9CP,!GP```#,S`#,S,S,S'8`````#!@P`'S&_L#&?``````0.&P`>`Q\S,QV
+M``````#,S`!X#'S,S'8`````8#`8`'@,?,S,=@`````X;#@`>`Q\S,QV````
+M`````#QF8&8\#`8\````$#AL`'S&_L#&?```````S,P`?,;^P,9\`````&`P
+M&`!\QO[`QGP``````&9F`#@8&!@8/``````8/&8`.!@8&!@\`````&`P&``X
+M&!@8&#P`````QL80.&S&QO[&Q@```#AL.``X;,;&_L;&````&#!@`/YF8'Q@
+M9OX`````````S'8V?MC8;@``````/FS,S/[,S,S.`````!`X;`!\QL;&QGP`
+M`````,;&`'S&QL;&?`````!@,!@`?,;&QL9\`````#!XS`#,S,S,S'8`````
+M8#`8`,S,S,S,=@``````QL8`QL;&QGX&#'@`QL8`.&S&QL;&;#@```#&Q@#&
+MQL;&QL;&?``````8&#QF8&!F/!@8`````#AL9&#P8&!@YOP``````&9F/!A^
+M&'X8&`````#XS,SXQ,S>S,S&``````X;&!@8?A@8&!C8<```&#!@`'@,?,S,
+M=@`````,&#``.!@8&!@\`````!@P8`!\QL;&QGP`````&#!@`,S,S,S,=@``
+M````=MP`W&9F9F9F````=MP`QN;V_M[.QL8`````/&QL/@!^```````````X
+M;&PX`'P````````````P,``P,&#&QGP```````````#^P,#`````````````
+M`/X&!@8``````,#`QLS8,&#<A@P8/@``P,#&S-@P9LZ>/@8&````&!@`&!@\
+M/#P8`````````#9LV&PV````````````V&PV;-@``````!%$$4011!%$$401
+M1!%$5:I5JE6J5:I5JE6J5:K==]UWW7?==]UWW7?==Q@8&!@8&!@8&!@8&!@8
+M&!@8&!@8&/@8&!@8&!@8&!@8&/@8^!@8&!@8&#8V-C8V-C;V-C8V-C8V````
+M`````/XV-C8V-C8``````/@8^!@8&!@8&#8V-C8V]@;V-C8V-C8V-C8V-C8V
+M-C8V-C8V-C8``````/X&]C8V-C8V-C8V-C8V]@;^````````-C8V-C8V-OX`
+M```````8&!@8&/@8^`````````````````#X&!@8&!@8&!@8&!@8&!\`````
+M```8&!@8&!@8_P````````````````#_&!@8&!@8&!@8&!@8&!\8&!@8&!@`
+M````````_P```````!@8&!@8&!C_&!@8&!@8&!@8&!@?&!\8&!@8&!@V-C8V
+M-C8V-S8V-C8V-C8V-C8V-S`_```````````````_,#<V-C8V-C8V-C8V-O<`
+M_P``````````````_P#W-C8V-C8V-C8V-C8W,#<V-C8V-C8``````/\`_P``
+M`````#8V-C8V]P#W-C8V-C8V&!@8&!C_`/\````````V-C8V-C8V_P``````
+M````````_P#_&!@8&!@8`````````/\V-C8V-C8V-C8V-C8V/P```````!@8
+M&!@8'Q@?```````````````?&!\8&!@8&!@`````````/S8V-C8V-C8V-C8V
+M-C;_-C8V-C8V&!@8&!C_&/\8&!@8&!@8&!@8&!@8^``````````````````?
+M&!@8&!@8__________________\`````````__________#P\/#P\/#P\/#P
+M\/#P#P\/#P\/#P\/#P\/#P__________````````````````=MS8V-QV````
+M`````'S&_,;&_,#`0````/[&QL#`P,#`P`````````#^;&QL;&QL``````#^
+MQF`P&#!@QOX``````````'[8V-C8<`````````!F9F9F?&!@P````````';<
+M&!@8&!@``````'X8/&9F9CP8?@``````.&S&QO[&QFPX```````X;,;&QFQL
+M;.X``````!XP&`P^9F9F/```````````?MO;?@`````````#!G[;V_-^8,``
+M`````!XP8&!^8&`P'@```````'S&QL;&QL;&````````_@``_@``_@``````
+M```8&'X8&```_P``````,!@,!@P8,`!^```````,&#!@,!@,`'X```````X;
+M&Q@8&!@8&!@8&!@8&!@8&!@8V-AP````````&!@`?@`8&```````````=MP`
+M=MP````````X;&PX````````````````````&!@`````````````````&```
+M```````/#`P,#`SL;#P<`````-AL;&QL;```````````<-@P8,CX````````
+=``````!\?'Q\?'P`````````````````````````
+`
+end
diff --git a/sys/arch/i386/isa/pcvt/Util/fonts/vt220l.816.uu b/sys/arch/i386/isa/pcvt/Util/fonts/vt220l.816.uu
new file mode 100644
index 00000000000..62393e14b72
--- /dev/null
+++ b/sys/arch/i386/isa/pcvt/Util/fonts/vt220l.816.uu
@@ -0,0 +1,95 @@
+begin 644 vt220l.816
+M````````````````````````?H&E@8&]F8&!?@```````'[_V___P^?__WX`
+M`````````&S^_O[^?#@0```````````0.'S^?#@0```````````8/#SGY^<8
+M&#P`````````&#Q^__]^&!@\`````````````!@\/!@```````#________G
+MP\/G________```````\9D)"9CP``````/______PYF]O9G#______\``!X.
+M&C)XS,S,S'@````````\9F9F9CP8?A@8````````/S,_,#`P,'#PX```````
+M`']C?V-C8V-GY^;`````````&!C;/.<\VQ@8``````"`P.#P^/[X\.#`@```
+M`````@8.'C[^/AX.!@(````````8/'X8&!A^/!@`````````9F9F9F9F9@!F
+M9@```````'_;V]M[&QL;&QL``````'S&8#ALQL9L.`S&?```````````````
+M_O[^_@```````!@\?A@8&'X\&'X````````8/'X8&!@8&!@8````````&!@8
+M&!@8&'X\&````````````!@,_@P8```````````````P8/Y@,```````````
+M`````,#`P/X``````````````"AL_FPH`````````````!`X.'Q\_OX`````
+M``````#^_GQ\.#@0```````````````````````````````8/#P\&!@8`!@8
+M``````!F9F8D``````````````````!L;/YL;&S^;&P``````!@8?,;"P'P&
+MAL9\&!@```````#"Q@P8,&#&A@```````#AL;#AVW,S,S'8``````#`P,&``
+M````````````````#!@P,#`P,#`8#````````#`8#`P,#`P,&#``````````
+M``!F//\\9@``````````````&!A^&!@````````````````````8&!@P````
+M`````````'X````````````````````````8&````````````@8,&#!@P(``
+M``````!\QL;.WO;FQL9\````````&#AX&!@8&!@8?@```````'S&!@P8,&#`
+MQOX```````!\Q@8&/`8&!L9\````````#!P\;,S^#`P,'@```````/[`P,#\
+M!@8&QGP````````X8,#`_,;&QL9\````````_L8&!@P8,#`P,````````'S&
+MQL9\QL;&QGP```````!\QL;&?@8&!@QX```````````8&````!@8````````
+M````&!@````8&#``````````!@P8,&`P&`P&````````````?@``?@``````
+M``````!@,!@,!@P8,&````````!\QL8,&!@8`!@8````````?,;&QM[>WMS`
+M?````````!`X;,;&_L;&QL8```````#\9F9F?&9F9F;\````````/&;"P,#`
+MP,)F/````````/AL9F9F9F9F;/@```````#^9F)H>&A@8F;^````````_F9B
+M:'AH8&!@\````````#QFPL#`WL;&9CH```````#&QL;&_L;&QL;&````````
+M/!@8&!@8&!@8/````````!X,#`P,#,S,S'@```````#F9F9L>'AL9F;F````
+M````\&!@8&!@8&)F_@```````,;N_O[6QL;&QL8```````#&YO;^WL[&QL;&
+M````````?,;&QL;&QL;&?````````/QF9F9\8&!@8/````````!\QL;&QL;&
+MUMY\#`X`````_&9F9GQL9F9FY@```````'S&QF`X#`;&QGP```````!^?EH8
+M&!@8&!@\````````QL;&QL;&QL;&?````````,;&QL;&QL9L.!````````#&
+MQL;&UM;6_NYL````````QL9L?#@X?&S&Q@```````&9F9F8\&!@8&#P`````
+M``#^QH8,&#!@PL;^````````/#`P,#`P,#`P/`````````"`P.!P.!P.!@(`
+M```````\#`P,#`P,#`P\`````!`X;,8`````````````````````````````
+M````_P``,#`8````````````````````````>`Q\S,S,=@```````.!@8'AL
+M9F9F9GP```````````!\QL#`P,9\````````'`P,/&S,S,S,=@``````````
+M`'S&_L#`QGP````````X;&1@\&!@8&#P````````````=LS,S,S,?`S,>```
+M`.!@8&QV9F9F9N8````````8&``X&!@8&!@\````````!@8`#@8&!@8&!F9F
+M/````.!@8&9L>'AL9N8````````X&!@8&!@8&!@\````````````[/[6UM;6
+MQ@```````````-QF9F9F9F8```````````!\QL;&QL9\````````````W&9F
+M9F9F?&!@\````````';,S,S,S'P,#!X```````#<=F9@8&#P````````````
+M?,9@.`S&?````````!`P,/PP,#`P-AP```````````#,S,S,S,QV````````
+M````QL;&QFPX$````````````,;&UM;6_FP```````````#&;#@X.&S&````
+M````````QL;&QL;&?@8,^````````/[,&#!@QOX````````.&!@8<!@8&!@.
+M````````&!@8&``8&!@8&````````'`8&!@.&!@8&'````````!VW```````
+M```````````````0.&S&QL;^`````````#QFPL#`P,)F/`P&?`````#,``#,
+MS,S,S,QV```````,&#``?,;^P,#&?```````$#AL`'@,?,S,S'8```````#,
+M``!X#'S,S,QV``````!@,!@`>`Q\S,S,=@``````.&PX`'@,?,S,S'8`````
+M`````#QF8&!F/`P&/``````0.&P`?,;^P,#&?````````,8``'S&_L#`QGP`
+M`````&`P&`!\QO[`P,9\````````9@``.!@8&!@8/```````&#QF`#@8&!@8
+M&#P``````&`P&``X&!@8&!@\``````#&`!`X;,;&_L;&Q@`````X;#@`.&S&
+MQO[&QL8`````&#!@`/YF8'Q@8&;^``````````!L_K(R?MC8;@```````#YL
+MS,S^S,S,S,X``````!`X;`!\QL;&QL9\````````Q@``?,;&QL;&?```````
+M8#`8`'S&QL;&QGP``````#!XS`#,S,S,S,QV``````!@,!@`S,S,S,S,=@``
+M````QL8``,;&QL;&QGX&#'@`QL8`?,;&QL;&QL9\`````,;&`,;&QL;&QL;&
+M?```````&!@\9F!@8&8\&!@``````#AL9&#P8&!@8.;\````````9F8\&'X8
+M?A@8&```````^,S,^,3,WLS,S,8```````X;&!@8?A@8&!@8V'`````8,&``
+M>`Q\S,S,=@``````#!@P`#@8&!@8&#P``````!@P8`!\QL;&QL9\```````8
+M,&``S,S,S,S,=@```````';<`-QF9F9F9F8`````=MP`QN;V_M[.QL;&````
+M```\;&P^`'X`````````````.&QL.`!\```````````````P,``P,&#`QL9\
+M`````````````/[`P,#```````````````#^!@8&!@```````,#`PL;,&#!@
+MW(8,&#X```#`P,+&S!@P9LZ>/@8&`````!@8`!@8&#P\/!@````````````V
+M;-AL-@``````````````V&PV;-@````````11!%$$4011!%$$4011!%$5:I5
+MJE6J5:I5JE6J5:I5JMUWW7?==]UWW7?==]UWW7<8&!@8&!@8&!@8&!@8&!@8
+M&!@8&!@8&/@8&!@8&!@8&!@8&!@8^!CX&!@8&!@8&!@V-C8V-C8V]C8V-C8V
+M-C8V`````````/XV-C8V-C8V-@``````^!CX&!@8&!@8&!@V-C8V-O8&]C8V
+M-C8V-C8V-C8V-C8V-C8V-C8V-C8V-@``````_@;V-C8V-C8V-C8V-C8V-O8&
+M_@``````````-C8V-C8V-OX``````````!@8&!@8^!CX````````````````
+M````^!@8&!@8&!@8&!@8&!@8&!\``````````!@8&!@8&!C_````````````
+M````````_Q@8&!@8&!@8&!@8&!@8&!\8&!@8&!@8&`````````#_````````
+M```8&!@8&!@8_Q@8&!@8&!@8&!@8&!@?&!\8&!@8&!@8&#8V-C8V-C8W-C8V
+M-C8V-C8V-C8V-C<P/P`````````````````_,#<V-C8V-C8V-C8V-C8V]P#_
+M`````````````````/\`]S8V-C8V-C8V-C8V-C8W,#<V-C8V-C8V-@``````
+M_P#_```````````V-C8V-O<`]S8V-C8V-C8V&!@8&!C_`/\``````````#8V
+M-C8V-C;_`````````````````/\`_Q@8&!@8&!@8`````````/\V-C8V-C8V
+M-C8V-C8V-C8_```````````8&!@8&!\8'P`````````````````?&!\8&!@8
+M&!@8&``````````_-C8V-C8V-C8V-C8V-C8V_S8V-C8V-C8V&!@8&!C_&/\8
+M&!@8&!@8&!@8&!@8&!CX````````````````````'Q@8&!@8&!@8________
+M_____________P````````#____________P\/#P\/#P\/#P\/#P\/#P#P\/
+M#P\/#P\/#P\/#P\/#_________\``````````````````';<V-C8W'8`````
+M``!XS,S,V,S&QL;,````````_L;&P,#`P,#`P```````````_FQL;&QL;&P`
+M````````_L9@,!@P8,;^````````````?MC8V-C8<```````````9F9F9F9\
+M8&#``````````';<&!@8&!@8`````````'X8/&9F9CP8?@`````````X;,;&
+M_L;&;#@````````X;,;&QFQL;&SN````````'C`8##YF9F9F/```````````
+M`'[;V]M^`````````````P9^V]OS?F#`````````'C!@8'Y@8&`P'@``````
+M``!\QL;&QL;&QL8``````````/X``/X``/X````````````8&'X8&```_P``
+M```````P&`P&#!@P`'X`````````#!@P8#`8#`!^````````#AL;&Q@8&!@8
+M&!@8&!@8&!@8&!@8&-C8V'```````````!@8`'X`&!@`````````````=MP`
+M=MP`````````.&QL.````````````````````````!@8````````````````
+M````&```````````#PP,#`P,[&QL/!P``````-AL;&QL;`````````````!P
+MV#!@R/@`````````````````?'Q\?'Q\?```````````````````````````
+!`#!@
+`
+end
diff --git a/sys/arch/i386/isa/pcvt/Util/ispcvt/Makefile b/sys/arch/i386/isa/pcvt/Util/ispcvt/Makefile
new file mode 100644
index 00000000000..5c17c22a4b7
--- /dev/null
+++ b/sys/arch/i386/isa/pcvt/Util/ispcvt/Makefile
@@ -0,0 +1,6 @@
+PROG= ispcvt
+MAN8= ispcvt.${MAN8EXT}
+
+.include <bsd.prog.mk>
+
+BINDIR= ${DESTDIR}/usr/sbin
diff --git a/sys/arch/i386/isa/pcvt/Util/ispcvt/ispcvt.8 b/sys/arch/i386/isa/pcvt/Util/ispcvt/ispcvt.8
new file mode 100644
index 00000000000..ef7459c5412
--- /dev/null
+++ b/sys/arch/i386/isa/pcvt/Util/ispcvt/ispcvt.8
@@ -0,0 +1,91 @@
+.\" Copyright (c) 1992, 1995 Hellmuth Michaelis
+.\"
+.\" All rights reserved.
+.\"
+.\" 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 Hellmuth Michaelis
+.\" 4. The name authors may not be used to endorse or promote products
+.\" derived from this software without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``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 AUTHORS 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.
+.\"
+.\" @(#)ispcvt.1, 3.30, Last Edit-Date: [Mon Jul 3 11:25:37 1995]
+.\"
+.Dd April 4, 1995
+.Dt ISPCVT 1
+.Sh NAME
+.Nm ispcvt
+.Nd verify if current video driver is pcvt driver
+.Sh SYNOPSIS
+.Nm ispcvt
+.Op Fl c
+.Op Fl d Ar device
+.Op Fl v
+.Sh DESCRIPTION
+The
+.Nm ispcvt
+utility allows the user to check whether the current video driver compiled
+into the kernel is a pcvt driver. The major and minor release numbers of
+the driver are also checked.
+Furthermore
+.Nm ispcvt
+is also able to print out the values of all the
+.Dq Ar PCVT_XXXXXX
+compile time options, the driver in the current running kernel was
+compiled with.
+.Pp
+The options are as follows:
+.Bl -tag -width Ds
+.It Fl d
+Specifies a device for which the check is done.
+.It Fl v
+Specifies being verbose. On success the name and revision is reported, on
+failure which comparison failed.
+.It Fl c
+This options prints out the values of all
+.Dq Ar PCVT_XXXXXX
+#defines which were given to the compiler at the time the currently running
+kernel was compiled. Specifying
+.Fl v
+with the
+.Fl c
+option gives a verbose listing of the compile-time options.
+.Sh RETURN VALUE
+.Bl -tag -width Ds
+.Pp
+.It Sy 0
+driver is pcvt and major and minor numbers match
+.It Sy 1
+open or ioctl system call failed
+.It Sy 2
+driver name mismatch
+.It Sy 3
+name matched, release major number mismatch
+.It Sy 4
+name & major number matched, release minor number mismatch
+.It Sy 5
+usage error
+.El
+.Pp
+.Sh BUGS
+No known bugs
+.Sh SEE ALSO
+.Xr pcvt 4
diff --git a/sys/arch/i386/isa/pcvt/Util/ispcvt/ispcvt.c b/sys/arch/i386/isa/pcvt/Util/ispcvt/ispcvt.c
new file mode 100644
index 00000000000..cac5b485a16
--- /dev/null
+++ b/sys/arch/i386/isa/pcvt/Util/ispcvt/ispcvt.c
@@ -0,0 +1,310 @@
+/*
+ * Copyright (c) 1992, 1995 Hellmuth Michaelis
+ *
+ * All rights reserved.
+ *
+ * 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 Hellmuth Michaelis
+ * 4. The name authors may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ */
+
+static char *id =
+ "@(#)ispcvt.c, 3.31, Last Edit-Date: [Tue Sep 5 16:31:24 1995]";
+
+/*---------------------------------------------------------------------------*
+ *
+ * history:
+ *
+ * -hm upgraded to report pcvt compile time configuration
+ * -hm PCVT_INHIBIT_NUMLOCK patch from Joerg
+ * -hm PCVT_META_ESC patch from Joerg
+ * -hm PCVT_PCBURST
+ * -hm new ioctl VGAPCVTINFO
+ * -hm new CONF_ values for 3.10
+ * -hm new CONF_ values for 3.20
+ * -hm removed PCVT_FAKE_SYSCONS10
+ * -hm added PCVT_PORTIO_DELAY
+ * -hm removed PCVT_386BSD
+ * -hm add -d option to specify a device
+ * -hm PCVT_XSERVER -> XSERVER
+ * -hm PCVT_MDAFASTSCROLL
+ * -hm removed PCVT_USL_VT_COMPAT
+ *
+ *---------------------------------------------------------------------------*/
+
+#include <stdio.h>
+#include <fcntl.h>
+#include <machine/pcvt_ioctl.h>
+
+#define DEFAULTFD 0
+
+main(argc,argv)
+int argc;
+char *argv[];
+{
+ extern int optind;
+ extern int opterr;
+ extern char *optarg;
+
+ struct pcvtid pcvtid;
+ struct pcvtinfo pcvtinfo;
+ int c;
+ char *p;
+ int verbose = 0;
+ int config = 0;
+ int dflag = 0;
+ int fd;
+ char *device;
+
+ while( (c = getopt(argc, argv, "vcd:")) != EOF)
+ {
+ switch(c)
+ {
+ case 'v':
+ verbose = 1;
+ break;
+
+ case 'c':
+ config = 1;
+ break;
+
+ case 'd':
+ device = optarg;
+ dflag = 1;
+ break;
+
+ case '?':
+ default:
+ usage();
+ break;
+ }
+ }
+
+ if(dflag)
+ {
+ if((fd = open(device, O_RDWR)) == -1)
+ {
+ if(verbose)
+ {
+ char buffer[80];
+ strcpy(buffer,"ERROR opening ");
+ strcat(buffer,device);
+ perror(buffer);
+ }
+ exit(1);
+ }
+ }
+ else
+ {
+ fd = DEFAULTFD;
+ }
+
+ if(ioctl(fd, VGAPCVTID, &pcvtid) == -1)
+ {
+ if(verbose)
+ perror("ispcvt - ioctl VGAPCVTID failed, error");
+ exit(1);
+ }
+
+ if(!strcmp(pcvtid.name, PCVTIDNAME))
+ {
+ if(pcvtid.rmajor == PCVTIDMAJOR)
+ {
+ if(pcvtid.rminor != PCVTIDMINOR)
+ {
+ if(verbose)
+ fprintf(stderr,"ispcvt - minor revision: expected %d, got %d\n", PCVTIDMINOR, pcvtid.rminor);
+ exit(4); /* minor revision mismatch */
+ }
+ }
+ else
+ {
+ if(verbose)
+ fprintf(stderr,"ispcvt - major revision: expected %d, got %d\n", PCVTIDMAJOR, pcvtid.rmajor);
+ exit(3); /* major revision mismatch */
+ }
+ }
+ else
+ {
+ if(verbose)
+ fprintf(stderr,"ispcvt - name check: expected %s, got %s\n", PCVTIDNAME, pcvtid.name);
+ exit(2); /* name mismatch */
+ }
+
+ if(verbose)
+ {
+ fprintf(stderr,"\nispcvt: kernel and utils match, driver name [%s], release [%1.1d.%02.2d]\n\n",pcvtid.name,pcvtid.rmajor,pcvtid.rminor);
+ }
+
+ if(config == 0)
+ exit(0);
+
+ if(ioctl(fd, VGAPCVTINFO, &pcvtinfo) == -1)
+ {
+ if(verbose)
+ perror("ispcvt - ioctl VGAPCVTINFO failed, error");
+ exit(1);
+ }
+
+ if(verbose)
+ {
+ switch(pcvtinfo.opsys)
+ {
+ case CONF_NETBSD:
+ p = "PCVT_NETBSD";
+ break;
+
+ case CONF_FREEBSD:
+ p = "PCVT_FREEBSD";
+ break;
+
+ default:
+ case CONF_UNKNOWNOPSYS:
+ p = "UNKNOWN";
+ break;
+
+ }
+ fprintf(stderr,"Operating System = %s\t", p);
+ fprintf(stderr,"OS Release Id = %u\n", pcvtinfo.opsysrel);
+ fprintf(stderr,"PCVT_NSCREENS = %u\t\t", pcvtinfo.nscreens);
+ fprintf(stderr,"PCVT_UPDATEFAST = %u\n", pcvtinfo.updatefast);
+ fprintf(stderr,"PCVT_UPDATESLOW = %u\t\t", pcvtinfo.updateslow);
+ fprintf(stderr,"PCVT_SYSBEEPF = %u\n", pcvtinfo.sysbeepf);
+ fprintf(stderr,"PCVT_PCBURST = %u\t\t", pcvtinfo.pcburst);
+ fprintf(stderr,"PCVT_KBD_FIFO_SZ = %u\n\n", pcvtinfo.kbd_fifo_sz);
+
+ /* config booleans */
+
+ fprintf(stderr,"PCVT_132GENERIC = %s",
+ (pcvtinfo.compile_opts & CONF_132GENERIC) ? "ON" : "OFF");
+ next();
+ fprintf(stderr,"PCVT_24LINESDEF = %s",
+ (pcvtinfo.compile_opts & CONF_24LINESDEF) ? "ON" : "OFF");
+ next();
+ fprintf(stderr,"PCVT_BACKUP_FONTS = %s",
+ (pcvtinfo.compile_opts & CONF_BACKUP_FONTS) ? "ON" : "OFF");
+ next();
+ fprintf(stderr,"PCVT_CTRL_ALT_DEL = %s",
+ (pcvtinfo.compile_opts & CONF_CTRL_ALT_DEL) ? "ON" : "OFF");
+ next();
+ fprintf(stderr,"PCVT_EMU_MOUSE = %s",
+ (pcvtinfo.compile_opts & CONF_EMU_MOUSE) ? "ON" : "OFF");
+ next();
+ fprintf(stderr,"PCVT_INHIBIT_NUMLOCK = %s",
+ (pcvtinfo.compile_opts & CONF_INHIBIT_NUMLOCK) ? "ON" : "OFF");
+ next();
+ fprintf(stderr,"PCVT_KEYBDID = %s",
+ (pcvtinfo.compile_opts & CONF_KEYBDID) ? "ON" : "OFF");
+ next();
+ fprintf(stderr,"PCVT_KBD_FIFO = %s",
+ (pcvtinfo.compile_opts & CONF_KBD_FIFO) ? "ON" : "OFF");
+ next();
+ fprintf(stderr,"PCVT_MDAFASTSCROLL = %s",
+ (pcvtinfo.compile_opts & CONF_MDAFASTSCROLL) ? "ON" : "OFF");
+ next();
+ fprintf(stderr,"PCVT_META_ESC = %s",
+ (pcvtinfo.compile_opts & CONF_META_ESC) ? "ON" : "OFF");
+ next();
+ fprintf(stderr,"PCVT_NOFASTSCROLL = %s",
+ (pcvtinfo.compile_opts & CONF_NOFASTSCROLL) ? "ON" : "OFF");
+ next();
+ fprintf(stderr,"PCVT_NO_LED_UPDATE = %s",
+ (pcvtinfo.compile_opts & CONF_NO_LED_UPDATE) ? "ON" : "OFF");
+ next();
+ fprintf(stderr,"PCVT_NULLCHARS = %s",
+ (pcvtinfo.compile_opts & CONF_NULLCHARS) ? "ON" : "OFF");
+ next();
+ fprintf(stderr,"PCVT_PALFLICKER = %s",
+ (pcvtinfo.compile_opts & CONF_PALFLICKER) ? "ON" : "OFF");
+ next();
+ fprintf(stderr,"PCVT_PORTIO_DELAY = %s",
+ (pcvtinfo.compile_opts & CONF_PORTIO_DELAY) ? "ON" : "OFF");
+ next();
+ fprintf(stderr,"PCVT_PRETTYSCRNS = %s",
+ (pcvtinfo.compile_opts & CONF_PRETTYSCRNS) ? "ON" : "OFF");
+ next();
+ fprintf(stderr,"PCVT_SCREENSAVER = %s",
+ (pcvtinfo.compile_opts & CONF_SCREENSAVER) ? "ON" : "OFF");
+ next();
+ fprintf(stderr,"PCVT_SETCOLOR = %s",
+ (pcvtinfo.compile_opts & CONF_SETCOLOR) ? "ON" : "OFF");
+ next();
+ fprintf(stderr,"PCVT_SHOWKEYS = %s",
+ (pcvtinfo.compile_opts & CONF_SHOWKEYS) ? "ON" : "OFF");
+ next();
+ fprintf(stderr,"PCVT_SIGWINCH = %s",
+ (pcvtinfo.compile_opts & CONF_SIGWINCH) ? "ON" : "OFF");
+ next();
+ fprintf(stderr,"PCVT_SLOW_INTERRUPT = %s",
+ (pcvtinfo.compile_opts & CONF_SLOW_INTERRUPT) ? "ON" : "OFF");
+ next();
+ fprintf(stderr,"PCVT_SW0CNOUTP = %s",
+ (pcvtinfo.compile_opts & CONF_SW0CNOUTP) ? "ON" : "OFF");
+ next();
+ fprintf(stderr,"PCVT_USEKBDSEC = %s",
+ (pcvtinfo.compile_opts & CONF_USEKBDSEC) ? "ON" : "OFF");
+ next();
+ fprintf(stderr,"PCVT_VT220KEYB = %s",
+ ((u_int)pcvtinfo.compile_opts & (u_int)CONF_VT220KEYB) ? "ON" : "OFF");
+ next();
+ fprintf(stderr,"PCVT_WAITRETRACE = %s",
+ (pcvtinfo.compile_opts & CONF_WAITRETRACE) ? "ON" : "OFF");
+ next();
+ fprintf(stderr,"XSERVER = %s",
+ (pcvtinfo.compile_opts & CONF_XSERVER) ? "ON" : "OFF");
+
+ fprintf(stderr,"\n\n");
+ }
+ else /* !verbose */
+ {
+ fprintf(stderr,"BSD Version = %u\n", pcvtinfo.opsys);
+ fprintf(stderr,"PCVT_NSCREENS = %u\n", pcvtinfo.nscreens);
+ fprintf(stderr,"PCVT_UPDATEFAST = %u\n", pcvtinfo.updatefast);
+ fprintf(stderr,"PCVT_UPDATESLOW = %u\n", pcvtinfo.updateslow);
+ fprintf(stderr,"PCVT_SYSBEEPF = %u\n", pcvtinfo.sysbeepf);
+ fprintf(stderr,"Compile options = 0x%08X\n", pcvtinfo.compile_opts);
+ }
+}
+
+usage()
+{
+ fprintf(stderr,"\nispcvt - verify current video driver is the pcvt-driver\n");
+ fprintf(stderr," usage: ispcvt [-v] [-c] [-d device]\n");
+ fprintf(stderr,"options: -v be verbose\n");
+ fprintf(stderr," -c print compile time configuration\n");
+ fprintf(stderr," -d <name> use devicefile <name> for verification\n\n");
+ exit(5);
+}
+
+next()
+{
+ static int i = 0;
+
+ fprintf(stderr, "%s", (i == 0) ? "\t\t" : "\n");
+
+ i = ~i;
+}
+
+/* EOF */
diff --git a/sys/arch/i386/isa/pcvt/Util/kbdio/Makefile b/sys/arch/i386/isa/pcvt/Util/kbdio/Makefile
new file mode 100644
index 00000000000..daebe80d967
--- /dev/null
+++ b/sys/arch/i386/isa/pcvt/Util/kbdio/Makefile
@@ -0,0 +1,22 @@
+PROG= kbdio
+SRCS= kbdio.y lex.l
+
+#YACC= bison
+#YFLAGS+= -yd # Bison only
+
+YFLAGS+= -v # verbose
+LFLAGS+= -I
+
+LDADD= -lm -ly -ll
+
+NOMAN=
+NOSHARED= no shared linkage
+
+CFLAGS+= -I ${.CURDIR}/obj -I ${.CURDIR} #-g
+
+CLEANFILES+= y.tab.h
+CLEANFILES+= y.output # comment file from bison
+
+.include <bsd.prog.mk>
+
+lex.o: y.tab.h lex.l
diff --git a/sys/arch/i386/isa/pcvt/Util/kbdio/kbdio.8 b/sys/arch/i386/isa/pcvt/Util/kbdio/kbdio.8
new file mode 100644
index 00000000000..b6048bb0a21
--- /dev/null
+++ b/sys/arch/i386/isa/pcvt/Util/kbdio/kbdio.8
@@ -0,0 +1,330 @@
+.\"
+.\" Copyright (c) 1995 Joerg Wunsch
+.\"
+.\" All rights reserved.
+.\"
+.\" This program is free software.
+.\"
+.\" 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 Joerg Wunsch
+.\" 4. The name of the developer may not be used to endorse or promote
+.\" products derived from this software without specific prior written
+.\" permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``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 DEVELOPERS 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.
+.\"
+.\" $Header: /cvs/OpenBSD/src/sys/arch/i386/isa/pcvt/Util/kbdio/Attic/kbdio.8,v 1.1 1995/10/18 08:50:45 deraadt Exp $
+.\"
+.Dd April 15, 1995
+.Dt KBDIO 8
+.Sh NAME
+.Nm kbdio
+.Nd perform input/output on a PC keyboard/keyboard controller
+.Sh SYNOPSIS
+.Nm kbdio
+.Op Fl d
+.Op Fl f Ar devname
+.Sh DESCRIPTION
+.Ss Purpose
+.Nm Kbdio
+is used to perform input/output on a PC keyboard or the
+.Pq motherboard
+keyboard controller.
+.Nm Kbdio
+cares for proper handshaking and necessary IO-ready conditions. It
+allows the interpretion of some registers in symbolic form, as well as
+to specify symbolic operands for the keyboard command byte. Simple
+arithmetic expressions can be formed to set or reset some bits, which
+is mostly applicable to the keyboard command byte, too.
+
+.Ss Options
+.Bl -tag -width 10n -offset indent -compact
+.It Fl d
+Turn on the grammar parser debugger.
+
+.It Fl f Ar devname
+Operate on device
+.Ar devname
+instead of the default
+.Pa /dev/console .
+.El
+
+.Ss Command language
+The command language of
+.Nm
+constitutes of some very simple tokens and rules. Commands are executed
+line by line as they are entered. Each line may contain any number of
+semicolon-separated statements.
+
+The list of acceptable statements includes:
+.Bl -tag -width "TYPEMATIC" -indent offset -compact
+
+.It Li \&?
+.It Li help
+Give help on the general syntax.
+
+.It Li help expr
+Help on expression syntax.
+
+.It Li status \&?
+Report keyboard controller status.
+
+.It Li what \&?
+Determine
+.Tn MCA
+type 1 or type 2 keyboard controller.
+
+.It Li data \&?
+Fetch keyboard controller data port.
+
+.It Li led \&= Ar number
+Set keyboard LEDs.
+.Ar Number
+is a logical combination of
+.Bl -hang -width "4" -compact
+.It 1
+scroll lock LED
+.It 2
+num lock LED
+.It 4
+caps lock LED.
+.El
+
+.It Li echo
+Send keyboard
+.Li ECHO
+command.
+
+.It Li scan \&= Ar number
+Turn keyboard to generate scan codes according to code set
+.Ar number .
+Only supported on
+.Tn PS/2
+style keyboards.
+
+.It Li scan \&?
+Report code set keyboard is currently operating in.
+
+.It Li \&id \&?
+Ask keyboard to report its identification bytes
+
+.It Xo
+.Li typematic \&= Ar number1 Li \&, Ar number2
+.Xc
+Set keyboard typematic delay and repeat rate to
+.Ar number1
+milliseconds and
+.Ar number2
+repeats per second, respectively.
+
+.It Li enable
+Enable keyboard.
+
+.It Li defaults
+Return customizable parameters to defaults.
+
+.It Li all typematic
+Set all keys to
+.Em typematic
+behaviour. This command as well as the following ones are only
+supported on
+.Tn PS/2
+style keyboards and only while operating in scan code set 3.
+
+.It Li all make release
+Turn all keys in generating
+.Em make
+and
+.Em release
+events only.
+
+.It Li all make only
+Turn all keys in generating
+.Em make
+codes only.
+
+.It Li all typematic make release
+Set all keys to generate
+.Em make
+and
+.Em release
+events, as well as perform
+.Em typematic
+behaviour. This is usually the default.
+
+.It Ar number Li typematic
+Set key
+.Ar number
+to
+.Em typematic
+behaviour.
+
+.It Ar number Li make release
+Turn a single key
+.Ar number
+to generate
+.Em make
+and
+.Em release
+events only.
+
+.It Ar number Li make only
+Set key
+.Ar number
+to return
+.Em make
+events only.
+
+.It Li resend
+Ask the keyboard to retransmit its last character.
+
+.It Li reset
+Perform a keyboard
+.Li RESET
+command.
+
+.It Li cmd \&?
+Get the keyboard command byte and interpret it symbolically.
+
+.It Li cmd \&= Ar expr
+Set the keyboard command byte to
+.Ar expr .
+See the next subsection for expression syntax.
+.El
+
+Returned data will be printed hexadecimal, but any queued keyboard
+control responses will be printed first.
+
+.Ss Expression syntax
+Expressions can either consist of a number, possibly followed
+by a
+.Sq +
+or
+.Sq \-
+sign and bit values in numeric or symbolic form.
+Symbolic bit values are
+.Pq with their meaning in the keyboard command byte :
+
+.Bl -tag -width "ovrinh" -offset indent -compact
+
+.It Li scconv
+value
+.Li 0x40 ,
+enable PC scan code conversion at
+.Em controller
+level, as opposed to the different keyboard scan code sets;
+
+.It Li ignpar
+value
+.Li 0x20 ,
+ignore keyboard parity;
+
+.It Li clklow
+value
+.Li 0x10 ,
+hold keyboard clock line low
+.Pq disables keyboard ;
+
+.It Li ovrinh
+value
+.Li 0x08 ,
+override keyboard inhibit function -- ignore the keyboard lockout switch,
+intented to allow the keyboard self-test;
+
+.It Li test
+value
+.Li 0x04 ,
+controller self-test okay;
+
+.It Li irq
+value
+.Li 0x01 ,
+enable generation of
+.Li IRQ1
+if output buffer is full.
+.El
+
+The operators
+.Sq +
+and
+.Sq \-
+perform simple bit-set or bit-clear functionality, respectively. This
+is roughly comparable with the operators
+.Sq \&|
+and
+.Sq \&&~
+in
+.Em C .
+
+Expressions are evaluated left to right and cannot be bracketed.
+The special keyword
+.Li cmd
+is substituted by a read of the current keyboard command byte.
+
+.Ss Access control
+The caller must have uid 0 in order to gain the required access to
+the IO registers.
+
+.Sh EXAMPLES
+
+.Dl led=3
+
+Turn on num lock and scroll lock LEDs.
+
+.Dl "cmd = cmd - irq; id?; cmd = cmd + irq"
+
+Temporarily suspend keyboard interrupt generation, and ask the
+keyboard to return its identification bytes.
+
+.Sh FILES
+.Pa /dev/console
+is used as the default device to enable access to the IO registers.
+
+.Sh HISTORY
+This program is considered
+.Dq hackware .
+It has been developed in order to simplify the process of developing other
+software that needs to handle the PC keyboard, and to give a very basic
+aid in debugging keyboard-related problems.
+
+.Sh AUTHOR
+The program has been contributed by
+.if n Joerg Wunsch,
+.if t J\(:org Wunsch,
+Dresden
+.Aq joerg_wunsch@uriah.heep.sax.de .
+
+.Sh BUGS
+No useful diagnostics are printed in case of a syntax error.
+
+Remember, to use this program, your kernel has to be compiled with XSERVER
+being defined.
+
+Use of this program might cause grievous harm to your system's sanity,
+not only that it might hang your keyboard and/or keyboard controller
+indefinitely, it might also hard-reset your system when accidentally
+accessing the hardware reset facility of the keyboard controller
+.Po
+which does not actually belong there, but used to be
+.Pc .
+
+It is highly recommended to use this program only when logged into the
+machine across a network or on a serial line.
diff --git a/sys/arch/i386/isa/pcvt/Util/kbdio/kbdio.y b/sys/arch/i386/isa/pcvt/Util/kbdio/kbdio.y
new file mode 100644
index 00000000000..02097f039e2
--- /dev/null
+++ b/sys/arch/i386/isa/pcvt/Util/kbdio/kbdio.y
@@ -0,0 +1,344 @@
+/* Hello emacs, this should be edited in -*- Fundamental -*- mode */
+%{
+/*
+ * Copyright (c) 1994,1995 Joerg Wunsch
+ *
+ * All rights reserved.
+ *
+ * This program is free software.
+ *
+ * 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 Joerg Wunsch
+ * 4. The name of the developer may not be used to endorse or promote
+ * products derived from this software without specific prior written
+ * permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``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 DEVELOPERS 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.
+ */
+
+#ident "$Header: /cvs/OpenBSD/src/sys/arch/i386/isa/pcvt/Util/kbdio/Attic/kbdio.y,v 1.1 1995/10/18 08:50:45 deraadt Exp $"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <math.h>
+#include <sys/fcntl.h>
+#include <machine/cpufunc.h>
+#include <machine/pcvt_ioctl.h>
+
+#ifdef __NetBSD__
+#include <machine/pio.h>
+#endif
+
+#define KBD_DELAY \
+ { u_char x = inb(0x84); } \
+ { u_char x = inb(0x84); } \
+ { u_char x = inb(0x84); } \
+ { u_char x = inb(0x84); } \
+ { u_char x = inb(0x84); } \
+ { u_char x = inb(0x84); }
+
+#define YYDEBUG 1
+
+void yyerror(const char *msg);
+
+static void help(int), status(void), data(int), kbd(int), cmdbyte(int),
+ kbc(int), whatMCA(void);
+static int kbget(void);
+%}
+
+%union {
+ int num;
+}
+
+%token NEWLINE
+%token ALL CMD DATA DEFAULTS ECHOC ENABLE EXPR HELP ID LED
+%token MAKE ONLY RELEASE RESEND RESET SCAN STATUS TYPEMATIC
+%token WHAT
+%token <num> NUM
+
+%type <num> expr opr
+
+%%
+
+interpret: lines ;
+
+lines: line
+ | lines line
+ ;
+
+line: statements NEWLINE
+ | NEWLINE
+ | error NEWLINE { fprintf(stderr, "bing!\n"); }
+ ;
+
+statements: statement
+ | statements ';' statement
+ ;
+
+statement: '?' { help(0); }
+ | HELP { help(0); }
+ | HELP EXPR { help(1); }
+ | STATUS '?' { status(); }
+ | WHAT '?' { whatMCA(); }
+ | DATA '?' { data(kbget()); }
+ | LED '=' NUM { kbd(0xed); kbd($3); }
+ | ECHOC { kbd(0xee); kbget(); }
+ | SCAN '=' NUM { kbd(0xf0); kbd($3);
+ if($3 == 0) data(kbget()); }
+ | SCAN '?' { kbd(0xf0); kbd(0); data(kbget()); }
+ | ID '?' { kbd(0xf2); data(kbget());
+ data(kbget()); }
+ | TYPEMATIC '=' NUM ',' NUM
+ { kbd(0xf3);
+ if($3 > 1000) $3 = 1000;
+ if($5 > 30) $5 = 30;
+ if($5 < 2) $5 = 2;
+ kbd(
+ (int)
+ (8.0 * log(30.0 / (double)$5)
+ / log(2))
+ | ((($3 / 250) - 1) * 32)
+ );
+ }
+ | ENABLE { kbd(0xf4); }
+ | DEFAULTS { kbd(0xf6); }
+ | ALL TYPEMATIC { kbd(0xf7); }
+ | ALL MAKE RELEASE { kbd(0xf8); }
+ | ALL MAKE ONLY { kbd(0xf9); }
+ | ALL TYPEMATIC MAKE RELEASE
+ { kbd(0xfa); }
+ | NUM TYPEMATIC { kbd(0xfb); kbd($1); }
+ | NUM MAKE RELEASE { kbd(0xfc); kbd($1); }
+ | NUM MAKE ONLY { kbd(0xfd); kbd($1); }
+ | RESEND { kbd(0xfe); }
+ | RESET { kbd(0xff); }
+ | CMD '?' { kbc(0x20); cmdbyte(kbget()); }
+ | CMD '=' expr { kbc(0x60); kbd($3); }
+ | /* lambda */
+ ;
+
+expr: opr { $$ = $1; }
+ | expr '+' opr { $$ = $1 | $3; }
+ | expr '-' opr { $$ = $1 & ~($3); }
+ ;
+
+opr: NUM { $$ = $1; }
+ | CMD { kbc(0x20); $$ = kbget(); }
+ ;
+
+%%
+
+static void
+help(int topic) {
+ switch(topic) {
+ case 0:
+ printf(
+ "Input consists of lines, containing one or more semicolon-separated\n"
+ "statements. Numbers are implicitly hexadecimal, append a dot for\n"
+ "decimal numbers. Valid statements include:\n"
+ "help [expr]; give help [to expression syntax]\n"
+ "status ? interpret kbd ctrl status byte\n"
+ "what ? check for MCA type 1 or 2 motherboard controller\n"
+ "data ? get one byte of data\n"
+ "led = NUM set kbd LEDs\n"
+ "echo send kbd ECHO command\n"
+ "scan = NUM; scan ? set scan code set; return current set\n"
+ "id ? get two id bytes\n"
+ "typematic=delay,rate set typematic delay(ms)&rate(1/s)\n"
+ "enable; defaults enable kbd; back to defaults\n"
+ "all typematic make all keys typematic\n"
+ "all make release make all keys sending make/release\n"
+ "all make only make all keys sending make only\n"
+ "all typematic make release make all keys typematic & make/release\n"
+ "NUM typematic make specific key typematic\n"
+ "NUM make release make specific key sending make/release\n"
+ "NUM make only make specific key sending make only\n"
+ "resend; reset resend last byte from kbd; reset kbd\n"
+ "cmd ? fetch kbd ctrl command byte\n"
+ "cmd = expr set kbd ctrl command byte\n");
+ break;
+
+ case 1:
+ printf(
+ "Expressions can either consist of a number, possibly followed\n"
+ "by a + or - sign and bit values in numeric or symbolic form.\n"
+ "Symbolic bit values are:\n"
+ "scconv ignpar clklow ovrinh test irq\n"
+ "\n");
+ break;
+
+ case 2:
+ fprintf(stderr, "usage: kbdio [-d] [-f devname]\n");
+ break;
+ }
+}
+
+static void
+status(void) {
+ int c = inb(0x64);
+ if(c&0x80) printf("parity error | ");
+ if(c&0x40) printf("rx timeout | ");
+ if(c&0x20) printf("tx timeout | ");
+ if(c&0x10) printf("kbd released ");
+ else printf("kbd locked ");
+ if(c&0x08) printf("| cmd last sent ");
+ else printf("| data last sent ");
+ if(c&0x04) printf("| power-on ");
+ else printf("| test ok ");
+ if(c&0x02) printf("| ctrl write busy ");
+ else printf("| ctrl write ok ");
+ if(c&0x01) printf("| ctrl read ok\n");
+ else printf("| ctrl read empty\n");
+}
+
+/* see: Frank van Gilluwe, "The Undocumented PC", Addison Wesley 1994, pp 273*/
+
+static void
+whatMCA(void) {
+ int new, sav;
+ kbc(0x20); /* get command byte */
+ sav = kbget(); /* sav = command byte */
+ kbc(0x60); /* set command byte */
+ kbd(sav | 0x40); /* set keyboard xlate bit */
+ kbc(0x20); /* get keyboard command */
+ new = kbget(); /* new = command byte */
+ kbc(0x60); /* set command byte */
+ kbd(sav); /* restore command byte */
+ if(new & 0x40)
+ printf("Hmm - looks like MCA type 1 motherboard controller\n");
+ else
+ printf("Hmm - looks like MCA type 2 motherboard controller\n");
+}
+
+static void
+kbd(int d) {
+ int i = 100000;
+ while(i && (inb(0x64) & 2)) i--;
+ if(i == 0) { printf("kbd write: timed out\n"); return; }
+ outb(0x60, d);
+}
+
+static void
+kbc(int d) {
+ int i = 100000;
+ while(i && (inb(0x64) & 2)) i--;
+ if(i == 0) { printf("ctrl write: timed out\n"); return; }
+ outb(0x64, d);
+}
+
+static int
+kbget(void) {
+ int i, c;
+ for(;;) {
+ i = 10000;
+ while(i && (inb(0x64) & 1) == 0) i--;
+ if(i == 0) { printf("data read: timed out\n"); return -1; }
+ KBD_DELAY
+ c = (unsigned char)inb(0x60);
+ switch(c) {
+ case 0: case 0xff:
+ printf("got kbd overrun\n"); break;
+ case 0xaa:
+ printf("got self-test OK\n"); break;
+ case 0xee:
+ printf("got ECHO byte\n"); break;
+ case 0xfa:
+ printf("got ACK\n"); break;
+ case 0xfc:
+ printf("got self-test FAIL\n"); break;
+ case 0xfd:
+ printf("got internal failure\n"); break;
+ case 0xfe:
+ printf("got RESEND request\n"); break;
+ default:
+ goto done;
+ }
+ }
+done:
+ return c;
+}
+
+static void
+cmdbyte(int d) {
+ if(d&0x40) printf("scan conv ");
+ else printf("pass thru ");
+ if(d&0x20) printf("| ign parity ");
+ else printf("| check parity ");
+ if(d&0x10) printf("| kbd clk low ");
+ else printf("| enable kbd ");
+ if(d&0x08) printf("| override kbd inh ");
+ if(d&0x04) printf("| test ok ");
+ else printf("| power-on ");
+ if(d&0x01) printf("| irq 1 enable\n");
+ else printf("| no irq\n");
+}
+
+static void
+data(int d) {
+ if(d < 0) return;
+ printf("data: 0x%02x\n", d);
+}
+
+void yyerror(const char *msg) {
+ fprintf(stderr, "yyerror: %s\n", msg);
+}
+
+int main(int argc, char **argv) {
+ int fd, c;
+ const char *devname = "/dev/console";
+
+ while((c = getopt(argc, argv, "df:")) != EOF)
+ switch(c) {
+ case 'd':
+ yydebug = 1;
+ break;
+
+ case 'f':
+ devname = optarg;
+ break;
+
+ case '?':
+ default:
+ help(2);
+ return 2;
+ }
+ argc -= optind;
+ argv += optind;
+ if(argc > 0) {
+ help(2);
+ return 2;
+ }
+
+ if((fd = open(devname, O_RDONLY)) < 0) {
+ perror("open(kbd)");
+ return 1;
+ }
+
+ if(ioctl(fd, KDENABIO, 0) < 0) {
+ perror("ioctl(KDENABIO)");
+ return 1;
+ }
+ yyparse();
+
+ (void)ioctl(fd, KDDISABIO, 0);
+ return 0;
+}
+
diff --git a/sys/arch/i386/isa/pcvt/Util/kbdio/lex.l b/sys/arch/i386/isa/pcvt/Util/kbdio/lex.l
new file mode 100644
index 00000000000..d8225eede23
--- /dev/null
+++ b/sys/arch/i386/isa/pcvt/Util/kbdio/lex.l
@@ -0,0 +1,87 @@
+%{
+/*
+ * Copyright (c) 1994,1995 Joerg Wunsch
+ *
+ * All rights reserved.
+ *
+ * This program is free software.
+ *
+ * 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 Joerg Wunsch
+ * 4. The name of the developer may not be used to endorse or promote
+ * products derived from this software without specific prior written
+ * permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``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 DEVELOPERS 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.
+ */
+
+#ident "$Header: /cvs/OpenBSD/src/sys/arch/i386/isa/pcvt/Util/kbdio/Attic/lex.l,v 1.1 1995/10/18 08:50:45 deraadt Exp $"
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "y.tab.h"
+
+extern YYSTYPE yylval;
+
+%}
+
+D [0-9a-fA-F]
+
+%%
+
+all { return ALL; }
+cmd { return CMD; }
+data { return DATA; }
+defaults { return DEFAULTS; }
+echo { return ECHOC; }
+enable { return ENABLE; }
+expr { return EXPR; }
+help { return HELP; }
+id { return ID; }
+led { return LED; }
+make { return MAKE; }
+only { return ONLY; }
+release { return RELEASE; }
+resend { return RESEND; }
+reset { return RESET; }
+scan { return SCAN; }
+status { return STATUS; }
+typematic { return TYPEMATIC; }
+what { return WHAT; }
+
+ /* numeric values */
+clklow { yylval.num = 0x10; return NUM; }
+ignpar { yylval.num = 0x20; return NUM; }
+irq { yylval.num = 0x01; return NUM; }
+ovrinh { yylval.num = 0x08; return NUM; }
+scconv { yylval.num = 0x40; return NUM; }
+test { yylval.num = 0x04; return NUM; }
+
+{D}({D}*)\. { sscanf(yytext, "%d", &yylval.num); return NUM; }
+
+{D}({D}*) { sscanf(yytext, "%x", &yylval.num); return NUM; }
+
+[ \t] { /* ignore */ }
+
+\n { return NEWLINE; }
+
+. { return yytext[0]; }
diff --git a/sys/arch/i386/isa/pcvt/Util/kcon/Makefile b/sys/arch/i386/isa/pcvt/Util/kcon/Makefile
new file mode 100644
index 00000000000..4826870f5b9
--- /dev/null
+++ b/sys/arch/i386/isa/pcvt/Util/kcon/Makefile
@@ -0,0 +1,10 @@
+PROG= kcon
+DEVICE= /dev/ttyv0
+CFLAGS+= -I${.CURDIR}/../keycap -DKEYB_DEVICE=\"${DEVICE}\"
+
+# the -Lfoo could be omitted if libkeycap.a were installed before
+# making those programs here
+
+LDADD = -L${.CURDIR}/../keycap -L${.CURDIR}/../keycap/obj -lkeycap
+
+.include <bsd.prog.mk>
diff --git a/sys/arch/i386/isa/pcvt/Util/kcon/kcon.1 b/sys/arch/i386/isa/pcvt/Util/kcon/kcon.1
new file mode 100644
index 00000000000..8c7d4f2d381
--- /dev/null
+++ b/sys/arch/i386/isa/pcvt/Util/kcon/kcon.1
@@ -0,0 +1,122 @@
+.\" Copyright (c) 1992, 1995 Hellmuth Michaelis
+.\"
+.\" All rights reserved.
+.\"
+.\" 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 Hellmuth Michaelis
+.\" 4. The name authors may not be used to endorse or promote products
+.\" derived from this software without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``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 AUTHORS 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.
+.\"
+.\" @(#)kcon.1, 3.31, Last Edit-Date: [Thu Aug 24 10:46:12 1995]
+.\"
+.Dd August 24, 1995
+.Dt KCON 1
+.Sh NAME
+.Nm kcon
+.Nd keyboard control and remapping for the pcvt driver
+.Sh SYNOPSIS
+.Nm kcon
+.Op Fl d Ar delay
+.Op Fl l
+.Op Fl m Ar map
+.Op Fl o
+.Op Fl p
+.Op Fl R
+.Op Fl r Ar rate
+.Op Fl s
+.Op Fl t Ns Ar +/-
+.Op Fl x
+.Sh DESCRIPTION
+.Nm kcon
+is used for controlling all aspects of keyboard configuration for the 'pcvt'
+video driver.
+.Pp
+The available options are:
+.Bl -tag -width flag
+.It Fl d Ar delay
+Specifies the delay after which the last key entered will be repeated by the
+Keyboard. Valid values are 0..3 corresponding to delays of 250, 500, 750 and
+1000 milliseconds.
+.It Fl l
+Displays the current keyboard map in use by the driver.
+.It Fl m Ar map
+Specifies the map entry to be searched in the keyboard capabilities database
+.Nm keycap.
+The database is searched for the entry and if found, the mapping
+is loaded and is used in the driver from then on.
+.It Fl o
+Switches display of control codes to octal in the listing of the current map.
+To be used in conjunction with the
+.Fl l
+option.
+.It Fl p
+Uses 'pure' output when listing - the Escape character is displayed in either
+octal or hexadecimal and not as 'ESC'. To be used in conjunction with the
+.Fl l
+option.
+.It Fl r Ar rate
+Specifies the character repetition rate. Valid argument values are 0...31
+corresponding to rates of 30 characters/second ... 2 characters/second.
+.It Fl R
+Reset the Keyboard.
+.It Fl s
+Displays the current settings of the rate and delay values.
+.It Fl t Ar +/-
+Specify this option to enable (
+.Ar +
+) or disable (
+.Ar -
+) the repetition of keys.
+.It Fl x
+Switches display of control codes to hexadecimal in the listing of the current map.
+To be used in conjunction with the
+.Fl l
+option. This is the default behaviour.
+.Sh FILES
+.Bl -tag -width /usr/share/misc/keycap -compact
+.It Pa /usr/share/misc/keycap
+Keyboard capabilities data base file if nothing else was chosen during installation.
+.It Pa /dev/console
+Keyboard raw device.
+.Sh SEE ALSO
+.Xr keycap 3 ,
+.Xr keycap 5
+.Sh BUGS
+.Nm kcon
+detects several inconsistencies in the keycap database. In case of errors
+.Nm kcon
+exits with an error message. If this happens, the keyboard may remain in
+an undefined state. To recover from such situation, execute
+.Nm kcon -m default
+.Sh EXAMPLES
+The command
+.Dq Li kcon -m gb
+loads the entry 'gb' from the keycap file into the keyboard to switch to
+a british keyboard behaviour.
+
+The command
+.Dq Li kcon -r 0 -d 0
+switches the keyboard to emit characters at a rate of 30 characters per second
+after a key has been held down for 250 milliseconds.
+
+
diff --git a/sys/arch/i386/isa/pcvt/Util/kcon/kcon.c b/sys/arch/i386/isa/pcvt/Util/kcon/kcon.c
new file mode 100644
index 00000000000..663faa9b4ca
--- /dev/null
+++ b/sys/arch/i386/isa/pcvt/Util/kcon/kcon.c
@@ -0,0 +1,753 @@
+/*
+ * Copyright (c) 1992, 1995 Hellmuth Michaelis
+ *
+ * Copyright (c) 1992, 1993 Holger Veit.
+ *
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to 386BSD by
+ * Holger Veit
+ *
+ * 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
+ * Hellmuth Michaelis and Holger Veit
+ * 4. The name authors may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``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 AUTHORS 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.
+ *
+ */
+
+static char *id =
+ "@(#)kcon.c, 3.30, Last Edit-Date: [Fri Jun 30 20:11:42 1995]";
+
+/*---------------------------------------------------------------------------*
+ *
+ * kcon.c Keyboard control and remapping
+ * ----------------------------------------------
+ *
+ * based on "keymap" which was written by
+ * Holger Veit (veit@du9ds3.uni-duisburg.de)
+ *
+ * -hm a first rewrite
+ * -hm rewrite for pcvt 2.0 distribution
+ * -hm adding show current typematic values
+ * -hm hex/octal/esc output choices
+ * -hm remapping debugging
+ * -hm garbage output for remapped keys bugfix
+ * -hm patch from Lon Willet, adding -R
+ *
+ *---------------------------------------------------------------------------*/
+
+#include <stdio.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/ioctl.h>
+#include <machine/pcvt_ioctl.h>
+
+#include "keycap.h"
+
+int Rf = 0;
+int df = 0;
+int lf = 0;
+int mf = 0;
+int of = 0;
+int pf = 0;
+int rf = 0;
+int tf = 0;
+int xf = 0;
+int sf = 0;
+
+/*---------------------------------------------------------------------------*
+ * main entry
+ *---------------------------------------------------------------------------*/
+main(argc, argv)
+int argc;
+char *argv[];
+{
+ extern char *optarg;
+ extern int optind;
+
+ int c = 0;
+
+ int errf = 0;
+
+ int rate = -1;
+ int delay = -1;
+ char *map;
+ int kbfd;
+
+ while((c = getopt(argc, argv, "Rd:lm:opr:st:x")) != EOF)
+ {
+ switch(c)
+ {
+ case 'R':
+ Rf = 1;
+ break;
+
+ case 'd':
+ df = 1;
+ delay = atoi(optarg);
+ break;
+
+ case 'l':
+ lf = 1;
+ break;
+
+ case 'm':
+ mf = 1;
+ map = optarg;
+ break;
+
+ case 'o':
+ if(xf)
+ errf = 1;
+ else
+ of = 1;
+ break;
+
+ case 'p':
+ pf = 1;
+ break;
+
+ case 'r':
+ rf = 1;
+ rate = atoi(optarg);
+ break;
+
+ case 's':
+ sf = 1;
+ break;
+
+ case 't':
+ if(*optarg == '+')
+ tf = 1;
+ else if(*optarg == '-')
+ tf = -1;
+ else
+ errf = 1;
+ break;
+
+ case 'x':
+ if(of)
+ errf = 1;
+ else
+ xf = 1;
+ break;
+
+ default:
+ usage();
+ }
+ }
+
+ if((Rf == 0 && df == 0 && lf == 0 && tf == 0 && sf == 0 &&
+ rf == 0 && mf == 0 ) || errf)
+ {
+ usage();
+ }
+
+ if((kbfd = open(KEYB_DEVICE, 0)) < 0)
+ {
+ perror("kcon: keyboard open failiure");
+ exit(1);
+ }
+
+ if(sf)
+ {
+ showtypeamatic(kbfd);
+ exit(0);
+ }
+
+ if(lf)
+ {
+ listcurrent(kbfd);
+ exit(0);
+ }
+
+ if (Rf)
+ {
+ if (ioctl(kbfd, KBDRESET, 0) < 0) {
+ perror ("kcon: ioctl KBDRESET failed");
+ exit (1);
+ }
+ }
+
+ if(tf)
+ {
+ setrepeat(kbfd, tf);
+ }
+
+ if(df || rf)
+ {
+ if(delay > 3)
+ {
+ fprintf(stderr,"Delay value (%d) out of range, possible values are 0..3!\n",delay);
+ exit(1);
+ }
+ if(rate > 31)
+ {
+ fprintf(stderr,"Rate value (%d) out of range, possible values are 0..31!\n",rate);
+ exit(1);
+ }
+ settypeam(kbfd, delay, rate);
+ }
+
+ if(mf)
+ {
+ remapkeys(kbfd, map);
+ }
+
+ close(kbfd);
+ exit(0);
+}
+
+/*---------------------------------------------------------------------------*
+ * display usage info & exit
+ *---------------------------------------------------------------------------*/
+usage()
+{
+ fprintf(stderr, "\nkcon: keyboard control and remapping utility for pcvt video driver\n");
+ fprintf(stderr, "usage: [-R] [-d delay] [-l] [-m map] [-o] [-p] [-r rate] [-t +/-] [-x]\n");
+ fprintf(stderr, " -R full reset of keyboard\n");
+ fprintf(stderr, " -d delay until a key is repeated (range: 0...3 => 250...1000ms)\n");
+ fprintf(stderr, " -l produce listing of current keyboard mapping\n");
+ fprintf(stderr, " -m set keyboard remapping from a keycap entry\n");
+ fprintf(stderr, " -o set octal output for listing\n");
+ fprintf(stderr, " -p pure, don't display escape as 'ESC' for listing\n");
+ fprintf(stderr, " -r chars/second repeat value (range: 0...31 => 30...2 chars/sec)\n");
+ fprintf(stderr, " -s show, display the current keyboard typematic values\n");
+ fprintf(stderr, " -t switch repeat on(+) or off(-)\n");
+ fprintf(stderr, " -x set hexadecimal output for listing\n\n");
+ exit(1);
+}
+
+/*---------------------------------------------------------------------------*
+ * convert control char in string to printable values
+ *---------------------------------------------------------------------------*/
+char *showcntrl(s)
+u_char *s;
+{
+ static char res_str[80];
+ static char conv_buf[80];
+ int i;
+
+ res_str[0] = '\0';
+
+ for(i = 0; s[i]; i++)
+ {
+ if(((s[i] > 0x20) && (s[i] <= 0x7e)) || ((s[i] >= 0xa0) && (s[i] <= 0xff)))
+ {
+ conv_buf[0] = s[i];
+ conv_buf[1] = '\0';
+ }
+ else if((s[i] == 0x1b) && (pf == 0))
+ {
+ strcpy(conv_buf,"ESC ");
+ }
+ else if(of)
+ {
+ sprintf(conv_buf,"\\%03.3o ", s[i]);
+ }
+ else
+ {
+ sprintf(conv_buf,"0x%02.2X ", s[i]);
+ }
+ strcat(res_str, conv_buf);
+ }
+ return(res_str);
+}
+
+/*---------------------------------------------------------------------------*
+ * list the current keyboard mapping
+ *---------------------------------------------------------------------------*/
+listcurrent(kbfd)
+int kbfd;
+{
+ static char *keytypetab[] = {
+ "NONE ",
+ "SHIFT ",
+ "ALT/META ",
+ "NUMLOCK ",
+ "CONTROL ",
+ "CAPSLOCK ",
+ "ASCII ",
+ "SCROLL ",
+ "FUNCTION ",
+ "KEYPAD ",
+ "BREAK ",
+ "ALTGR ",
+ "SHIFTLOCK",
+ "CURSOR ",
+ "RETURN "
+ };
+
+ struct kbd_ovlkey keyboardmap[KBDMAXKEYS];
+ struct kbd_ovlkey *kbmapp;
+ int keytype;
+ int altgr_defined;
+ int i;
+
+ altgr_defined = 0;
+ kbmapp = keyboardmap;
+
+ for (i = 0; i < KBDMAXKEYS; i++)
+ {
+ kbmapp->keynum = i;
+
+ if(ioctl(kbfd, KBDGCKEY, kbmapp) < 0)
+ {
+ perror("kcon: ioctl KBDGCKEY failed");
+ exit(1);
+ }
+
+ if((kbmapp->type & KBD_MASK) == KBD_ALTGR)
+ altgr_defined = i;
+
+ kbmapp++;
+ }
+
+ if(altgr_defined)
+ {
+ printf("S Key KeyType Normal Shift Control Altgr \n");
+ printf("- --- --------- --------------- --------------- --------------- ---------------\n");
+ }
+ else
+ {
+ printf("S Key KeyType Normal Shift Control \n");
+ printf("- --- --------- --------------- --------------- ---------------\n");
+ }
+
+ kbmapp = &keyboardmap[1];
+
+ for(i = 1; i < KBDMAXKEYS; i++)
+ {
+ keytype = kbmapp->type;
+
+ if(keytype)
+ {
+ if(keytype & KBD_OVERLOAD)
+ printf("! %3.3d %9.9s ", i, keytypetab[keytype & KBD_MASK]);
+ else
+ printf("- %3.3d %9.9s ", i, keytypetab[keytype & KBD_MASK]);
+
+ switch(keytype & KBD_MASK)
+ {
+
+ case KBD_NUM:
+ case KBD_ASCII:
+ case KBD_FUNC:
+ case KBD_KP:
+ case KBD_CURSOR:
+ case KBD_RETURN: /* ??? */
+
+ if(kbmapp->subu == KBD_SUBT_STR)
+ printf("%-15s ",showcntrl(kbmapp->unshift));
+ else
+ printf("Function() ");
+
+ if(kbmapp->subs == KBD_SUBT_STR)
+ printf("%-15s ",showcntrl(kbmapp->shift));
+ else
+ printf("Function() ");
+
+ if(kbmapp->subc == KBD_SUBT_STR)
+ printf("%-15s ",showcntrl(kbmapp->ctrl));
+ else
+ printf("Function() ");
+
+ if(altgr_defined)
+ {
+ if(kbmapp->suba == KBD_SUBT_STR)
+ printf("%-15s ",showcntrl(kbmapp->altgr));
+ else
+ printf("Function() ");
+ }
+ break;
+ }
+ putchar('\n');
+ }
+ kbmapp++;
+ }
+}
+
+/*---------------------------------------------------------------------------*
+ * show delay and rate values for keyboard
+ *---------------------------------------------------------------------------*/
+showtypeamatic(kbfd)
+int kbfd;
+{
+ static char *delaytab[] = {
+ "250",
+ "500",
+ "750",
+ "1000"
+ };
+
+ static char *ratetab[] = {
+ "30.0",
+ "26.7",
+ "24.0",
+ "21.8",
+ "20.0",
+ "18.5",
+ "17.1",
+ "16.0",
+ "15.0",
+ "13.3",
+ "12.0",
+ "10.9",
+ "10.0",
+ "9.2",
+ "8.6",
+ "8.0",
+ "7.5",
+ "6.7",
+ "6.0",
+ "5.5",
+ "5.0",
+ "4.6",
+ "4.3",
+ "4.0",
+ "3.7",
+ "3.3",
+ "3.0",
+ "2.7",
+ "2.5",
+ "2.3",
+ "2.1",
+ "2.0"
+ };
+
+ int cur_typemat_val;
+ int delay, rate;
+
+ if((ioctl(kbfd, KBDGTPMAT, &cur_typemat_val)) < 0)
+ {
+ perror("kcon: ioctl KBDGTPMAT failed");
+ exit(1);
+ }
+
+ delay = ((cur_typemat_val & 0x60) >> 5);
+ rate = cur_typemat_val & 0x1f;
+
+ printf("\nDisplaying the current keyboard typematic values:\n\n");
+ printf("The delay-until-repeat time is [ %s ] milliseconds\n",delaytab[delay]);
+ printf("The repeat-rate is [ %s ] characters per second\n\n",ratetab[rate]);
+}
+
+/*---------------------------------------------------------------------------*
+ * set repeat feature on/off
+ *---------------------------------------------------------------------------*/
+setrepeat(kbfd, tf)
+int kbfd;
+int tf;
+{
+ int srepsw_val;
+
+ if(tf == 1)
+ srepsw_val = KBD_REPEATON;
+ else
+ srepsw_val = KBD_REPEATOFF;
+
+ if(ioctl(kbfd, KBDSREPSW, &srepsw_val) < 0)
+ {
+ perror("kcon: ioctl KBDREPSW failed");
+ exit(1);
+ }
+}
+
+/*---------------------------------------------------------------------------*
+ * set delay and rate values for keyboard
+ *---------------------------------------------------------------------------*/
+settypeam(kbfd, delay, rate)
+int kbfd;
+int delay;
+int rate;
+{
+ int cur_typemat_val;
+ int new_typemat_val;
+
+ if((ioctl(kbfd, KBDGTPMAT, &cur_typemat_val)) < 0)
+ {
+ perror("kcon: ioctl KBDGTPMAT failed");
+ exit(1);
+ }
+
+ if(delay == -1)
+ delay = (cur_typemat_val & 0x60);
+ else
+ delay = ((delay << 5) & 0x60);
+
+ if(rate == -1)
+ rate = (cur_typemat_val & 0x1f);
+ else
+ rate &= 0x1f;
+
+ new_typemat_val = delay | rate;
+
+ if((ioctl(kbfd, KBDSTPMAT, &new_typemat_val)) < 0)
+ {
+ perror("kcon: ioctl KBDSTPMAT failed");
+ exit(1);
+ }
+}
+
+/*---------------------------------------------------------------------------*
+ * remap keyboard from keycap entry
+ *---------------------------------------------------------------------------*/
+remapkeys(kbfd, map)
+int kbfd;
+char *map;
+{
+ char cap_entry[1024];
+ int ret;
+ char keyflag[128];
+ int i;
+
+ /* try to find the entry */
+
+ ret = kgetent(cap_entry, map);
+
+ if(ret == -1)
+ {
+ fprintf(stderr, "kcon: keycap database not found or not accessible!\n");
+ exit(1);
+ }
+ else if(ret == 0)
+ {
+ fprintf(stderr, "kcon: keycap entry [%s] not found in database!\n", map);
+ exit(1);
+ }
+
+ /* set default mapping */
+
+ if((ioctl(kbfd, KBDDEFAULT)) < 0)
+ {
+ perror("kcon: ioctl KBDDEFAULT failed");
+ exit(1);
+ }
+
+ /* DE flag present? */
+
+ if(kgetflag("de"))
+ return;
+
+ for(i = 0; i < KBDMAXKEYS; i++)
+ keyflag[i] = 0;
+
+ set_lock(keyflag, kbfd);
+
+ set_shift(keyflag, kbfd);
+
+ set_char(keyflag, kbfd);
+}
+
+/*---------------------------------------------------------------------------*
+ * care for lock keys
+ *---------------------------------------------------------------------------*/
+set_lock(keyflag, kbfd)
+char keyflag[];
+int kbfd;
+{
+ int i, j;
+ char cap[16];
+ struct kbd_ovlkey entry;
+
+ struct {
+ char *ch;
+ u_short typ;
+ } lock[] =
+ {
+ "ca", KBD_CAPS,
+ "sh", KBD_SHFTLOCK,
+ "nl", KBD_NUMLOCK,
+ "sc", KBD_SCROLL
+ };
+
+
+ for(i = 0; i < 4; i++)
+ {
+ int n;
+
+ sprintf(cap, "%s", lock[i].ch);
+
+ n = kgetnum(cap);
+
+ if(n > 0)
+ {
+ if (keyflag[n])
+ {
+ fprintf(stderr,"kcon: duplicate key definition for key [%d]!\n",n);
+ exit(1);
+ }
+ keyflag[n] = 1;
+
+ entry.keynum = n;
+ entry.type = lock[i].typ;
+
+ if((ioctl(kbfd, KBDSCKEY, &entry)) < 0)
+ {
+ perror("kcon: ioctl KBDSCKEY failed");
+ exit(1);
+ }
+ }
+ }
+}
+
+/*---------------------------------------------------------------------------*
+ * care for shifting keys
+ *---------------------------------------------------------------------------*/
+set_shift(keyflag, kbfd)
+char keyflag[];
+int kbfd;
+{
+ int i, j;
+ char cap[16];
+ struct kbd_ovlkey entry;
+
+ struct {
+ char ch;
+ u_short typ;
+ } shift[] =
+ {
+ 'm', KBD_META,
+ 'l', KBD_ALTGR,
+ 'h', KBD_SHIFT,
+ 't', KBD_CTL
+ };
+
+ for(i = 0; i < 4; i++)
+ {
+ for(j = 1; j < 10; j++)
+ {
+ int n;
+
+ sprintf(cap, "%c%d", shift[i].ch,j);
+
+ n = kgetnum(cap);
+
+ if (n >= 0)
+ {
+ if (keyflag[n])
+ {
+ fprintf(stderr,"kcon: duplicate key definition for key [%d]!\n",n);
+ exit(1);
+ }
+ keyflag[n] = 1;
+
+ entry.keynum = n;
+ entry.type = shift[i].typ;
+ if((ioctl(kbfd, KBDSCKEY, &entry)) < 0)
+ {
+ perror("kcon: ioctl KBDSCKEY failed");
+ exit(1);
+ }
+ }
+ }
+ }
+}
+
+/*---------------------------------------------------------------------------*
+ * care for normal keys
+ *---------------------------------------------------------------------------*/
+set_char(keyflag, kbfd)
+char keyflag[];
+int kbfd;
+{
+ int i, j;
+ char cap[16];
+ int setflag;
+ char *addr_str;
+ char *new_str;
+ struct kbd_ovlkey entry;
+
+ struct {
+ char *addr;
+ char ch;
+ } standard[] = {
+ 0, 'D',
+ &entry.unshift[0], 'K',
+ &entry.shift[0], 'S',
+ &entry.ctrl[0], 'C',
+ &entry.altgr[0], 'A'
+ };
+
+ for(i = 1; i < KBDMAXKEYS; i++)
+ {
+ setflag = 0;
+
+ entry.keynum = i;
+
+ if((ioctl(kbfd, KBDGOKEY, &entry)) < 0)
+ {
+ perror("kcon: ioctl KBDGOKEY failed");
+ exit(1);
+ }
+
+ entry.type = KBD_ASCII;
+
+ for(j = 0; j < 5; j++)
+ {
+ sprintf(cap, "%c%d", standard[j].ch,i);
+
+ if((j == 0) && (kgetflag(cap)))
+ {
+ /* delete a key */
+
+ entry.type = KBD_NONE;
+ setflag = 1;
+ goto setit;
+
+ }
+ else
+ {
+ addr_str = standard[j].addr;
+ if(new_str = kgetstr(cap, &addr_str))
+ {
+ if(strlen(new_str) > KBDMAXOVLKEYSIZE)
+ {
+ fprintf(stderr, "kcon: database entry string [%s] longer than max [%d]!\n",new_str,KBDMAXOVLKEYSIZE);
+ exit(1);
+ }
+ setflag = 1;
+ }
+ }
+ }
+
+setit: if (setflag)
+ {
+ if (keyflag[i])
+ {
+ fprintf(stderr,"kcon: duplicate key definition for key [%d]!\n",i);
+ exit(1);
+ }
+ keyflag[i] = 1;
+
+ if((ioctl(kbfd, KBDSCKEY, &entry)) < 0)
+ {
+ perror("kcon: ioctl KBDSCKEY failed");
+ exit(1);
+ }
+ }
+ }
+}
+
+/*------------------- EOF ------------------------------------------------*/
diff --git a/sys/arch/i386/isa/pcvt/Util/keycap/Makefile b/sys/arch/i386/isa/pcvt/Util/keycap/Makefile
new file mode 100644
index 00000000000..940b272bc06
--- /dev/null
+++ b/sys/arch/i386/isa/pcvt/Util/keycap/Makefile
@@ -0,0 +1,19 @@
+LIB = keycap
+CAPDIR = $(DESTDIR)/usr/share/misc
+CAPPATH = $(CAPDIR)/keycap.pcvt
+KEYCAPSRC= keycap.src
+CFLAGS += -DKEYCAP_PATH=\"$(CAPPATH)\"
+SRCS = keycap.c
+MAN3 = keycap.${MAN3EXT}
+MAN5 = keycap.${MAN5EXT}
+#CLEANFILES+= keycap.0 keycap.0
+
+beforeinstall:
+ @if [ ! -d ${DESTDIR}${LIBDIR} ]; then mkdir ${DESTDIR}${LIBDIR};fi
+ @${ECHO} "Saving old keycap database"
+ -mv -f ${DESTDIR}${CAPPATH} ${DESTDIR}${CAPPATH}.BAK
+ install -c -m ${LIBMODE} -o ${LIBOWN} -g ${LIBGRP} \
+ ${.CURDIR}/${KEYCAPSRC} ${DESTDIR}${CAPPATH}
+
+
+.include <bsd.lib.mk>
diff --git a/sys/arch/i386/isa/pcvt/Util/keycap/keycap.3 b/sys/arch/i386/isa/pcvt/Util/keycap/keycap.3
new file mode 100644
index 00000000000..7eb59dcb230
--- /dev/null
+++ b/sys/arch/i386/isa/pcvt/Util/keycap/keycap.3
@@ -0,0 +1,121 @@
+.\"
+.\" Copyright (c) 1992,1993,1994 Hellmuth Michaelis
+.\"
+.\" Copyright (c) 1990 The Regents of the University of California.
+.\"
+.\" All rights reserved.
+.\"
+.\" 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.
+.\"
+.\" @(#)keycap.3, 3.00, Last Edit-Date: [Sun Jan 2 13:46:43 1994]
+.\"
+.Dd January 3, 1993
+.Dt KEYCAP 3
+.Sh NAME
+.Nm kgetent ,
+.Nm kgetnum ,
+.Nm kgetflag ,
+.Nm kgetstr
+.Nd routines for accessing the keycap database
+.Sh SYNOPSIS
+.Fn kgetent "char *bp" "char *name"
+.Fn kgetnum "char *id"
+.Fn kgetflag "char *id"
+.Ft char *
+.Fn kgetstr "char *id" "char *area"
+.Sh DESCRIPTION
+These functions extract and use capabilities from a keyboard capability data
+base, usually
+.Pa /usr/share/misc/keycap ,
+the format of which is described in
+.Xr keycap 5 .
+.Pp
+The
+.Fn kgetent
+function
+extracts the entry for keyboard mapping
+.Fa name
+into the buffer at
+.Fa bp .
+The
+.Fa bp
+argument
+should be a character buffer of size
+1024 and must be retained through all subsequent calls to
+.Fn kgetnum ,
+.Fn kgetflag ,
+and
+.Fn kgetstr .
+The
+.Fn kgetent
+function
+returns \-1 if none of the
+.Nm keycap
+data base files could be opened,
+0 if the map name given does not have an entry,
+and 1 if all goes well.
+.Pp
+The
+.Fn kgetnum
+function
+gets the numeric value of capability
+.Fa id ,
+returning \-1 if is not given for the map.
+.Pp
+The
+.Fn kgetflag
+function
+returns 1 if the specified capability is present in
+the map's entry, 0 if it is not.
+.Pp
+The
+.Fn kgetstr
+function
+returns the string value of the capability
+.Fa id ,
+places it in the buffer at
+.Fa area ,
+and advances the
+.Fa area
+pointer.
+The
+.Fn kgetstr
+function
+returns
+.Dv NULL
+if the capability was not found.
+.Pp
+.Sh FILES
+.Bl -tag -width /usr/share/misc/keycap -compact
+.It Pa /usr/share/misc/keycap
+Keyboard capabilities database (if nothing else chosen during installation).
+.El
+.Sh SEE ALSO
+.Xr kcon 1 ,
+.Xr keycap 5
diff --git a/sys/arch/i386/isa/pcvt/Util/keycap/keycap.5 b/sys/arch/i386/isa/pcvt/Util/keycap/keycap.5
new file mode 100644
index 00000000000..8a11f59a507
--- /dev/null
+++ b/sys/arch/i386/isa/pcvt/Util/keycap/keycap.5
@@ -0,0 +1,133 @@
+.\"
+.\" Copyright (c) 1992,1993,1994 Hellmuth Michaelis
+.\"
+.\" Copyright (c) 1990 The Regents of the University of California.
+.\"
+.\" All rights reserved.
+.\"
+.\" 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.
+.\"
+.\" @(#)keycap.5, 3.00, Last Edit-Date: [Sun Jan 2 13:45:59 1994]
+.\"
+.Dd January 3, 1993
+.Dt KEYCAP 5
+.Sh NAME
+.Nm keycap
+.Nd keyboard mapping data base
+.Sh SYNOPSIS
+.Nm keycap
+.Sh DESCRIPTION
+The
+.Nm keycap
+file
+is a data base describing keyboard mappings, used by
+.Xr kcon 1 .
+.Pp
+Entries in
+.Nm keycap
+consist of a number of `:'-separated fields.
+The first entry for each mapping gives the names that are known for the
+mapping, separated by `|' characters.
+All names but the first and last
+should be in lower case and contain no blanks;
+the last name may well contain
+upper case and blanks for readability.
+.Sh CAPABILITIES
+.Pp
+.Bl -column indent indent
+.Sy Name Type Description
+.It "de bool Resets Keyboard mapping to compiled-in default"
+.It "D<n> bool Disables key <n> completely"
+
+.It "m<n> num specify key numbers for ALT keys
+.It "l<n> num specify key numbers for ALTGR keys
+.It "h<n> num specify key numbers for SHIFT keys
+.It "t<n> num specify key numbers for CONTROL keys
+.It "ca<n> num specify key number for the CAPS LOCK key
+.It "sh<n> num specify key number for the SHIFT LOCK key
+.It "nl<n> num specify key number for the NUM LOCK key
+.It "sc<n> num specify key number for the SCROLL LOCK key
+
+.It "K<n> str bind a string to a unshifted (normal) key
+.It "S<n> str bind a string to a shifted key
+.It "C<n> str bind a string to a control key
+.It "A<n> str bind a string to a altgr key
+
+.It "tc str Entry of similar map \- must be last."
+.El
+
+Parameter <n> describing the key number can have values from 1 to 128.
+
+A string parameter may have up to 15 characters.
+
+.Pp
+.Ss A Sample Entry
+The following entry, which describes a test entry, is among the very
+easy entries in the
+.Nm keycap
+file as of this writing.
+.Pp
+.Bd -literal
+tt\||test\||Test entry which swaps y and z:\e
+ :K22=z:S22=Z:C22=\e032:\e
+ :K46=y:S46=Y:C46=\e031:
+
+.Ed
+.Pp
+Entries may continue onto multiple lines by giving a \e as the last
+character of a line. Comments may be included on lines beginning with
+.Dq # .
+.Sh FILES
+.Bl -tag -width /usr/share/misc/keycap -compact
+.It Pa /usr/share/misc/keycap
+File containing keyboard mapping descriptions.
+.El
+.Sh SEE ALSO
+.Xr kcon 1 ,
+.Xr keycap 3 ,
+.Sh EXAMPLES
+The entry
+.Dq Li l1#60
+sets the keynumber for the ALTGR key to 60.
+
+The entry
+.Dq Li K100=hugo
+binds the string 'hugo' to the key number 100.
+
+The entry
+.Dq Li K100=^D
+binds the control character EOT (0x04) to the key number 100.
+
+The entry
+.Dq Li K100=\e000
+binds the control character NUL (0x00) to the key number 100.
+
+
+
+
diff --git a/sys/arch/i386/isa/pcvt/Util/keycap/keycap.c b/sys/arch/i386/isa/pcvt/Util/keycap/keycap.c
new file mode 100644
index 00000000000..f70e987b0f6
--- /dev/null
+++ b/sys/arch/i386/isa/pcvt/Util/keycap/keycap.c
@@ -0,0 +1,377 @@
+/*-
+ * Copyright (c) 1992, 1993 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Holger Veit
+ *
+ * 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.
+ *
+ */
+
+static char *id =
+ "@(#)keycap.c, 3.20, Last Edit-Date: [Tue Dec 20 14:51:50 1994]";
+
+/*---------------------------------------------------------------------------*
+ *
+ * keycap.c Keyboard capabilities database handling
+ * -------------------------------------------------------
+ *
+ * converted from printcap by Holger Veit (veit@du9ds3.uni-duisburg.de)
+ *
+ * BUG: Should use a "last" pointer in tbuf, so that searching
+ * for capabilities alphabetically would not be a n**2/2
+ * process when large numbers of capabilities are given.
+ *
+ * Note: If we add a last pointer now we will screw up the
+ * tc capability. We really should compile termcap.
+ *
+ * modified by Hellmuth Michaelis (hm@hcshh.hcs.de) to fit into the
+ * vt220 driver pcvt 2.0 distribution
+ *
+ * -hm header conversion & cosmetic changes for pcvt 2.0 distribution
+ * -hm debugging remapping
+ * -hm cleaning up from termcap ....
+ * -hm split off header file keycap.h
+ *
+ *---------------------------------------------------------------------------*/
+
+#include <stdio.h>
+#include <ctype.h>
+
+#include "keycap.h"
+
+#define KEYCAP_BUFSIZ 1024
+
+#define MAXHOP 32 /* max number of tc= indirections */
+
+char *getenv();
+
+static FILE *pfp = NULL; /* keycap data base file pointer */
+static char *tbuf;
+static int hopcount; /* detect infinite loops in keycap, init 0 */
+
+static int knchktc();
+static int knamatch();
+static char *kdecode();
+
+/*---------------------------------------------------------------------------*
+ * match a name
+ *---------------------------------------------------------------------------*/
+static char *nmatch(id,cstr)
+char *id,*cstr;
+{
+ register n = strlen(id);
+ register char *c = cstr+n;
+
+ if (strncmp(id,cstr,n)==0 &&
+ (*c==':' || *c=='|' || *c=='=' || *c=='#') || *c=='@')
+ return c;
+ return 0;
+}
+
+/*---------------------------------------------------------------------------*
+ * Get an entry for keyboard name in buffer bp from the keycap file.
+ * Parse is very rudimentary, we just notice escaped newlines.
+ *---------------------------------------------------------------------------*/
+kgetent(bp, name)
+char *bp, *name;
+{
+ register char *cp;
+ register int c;
+ register int i = 0, cnt = 0;
+ char ibuf[KEYCAP_BUFSIZ];
+ char *cp2;
+ int tf;
+
+ tbuf = bp;
+ tf = 0;
+
+ tf = open(KEYCAP_PATH, 0);
+
+ if (tf < 0)
+ return (-1);
+ for (;;) {
+ cp = bp;
+ for (;;) {
+ if (i == cnt) {
+ cnt = read(tf, ibuf, KEYCAP_BUFSIZ);
+ if (cnt <= 0) {
+ close(tf);
+ return (0);
+ }
+ i = 0;
+ }
+ c = ibuf[i++];
+ if (c == '\n') {
+ if (cp > bp && cp[-1] == '\\'){
+ cp--;
+ continue;
+ }
+ break;
+ }
+ if (cp >= bp+KEYCAP_BUFSIZ) {
+ write(2,"Keycap entry too long\n", 23);
+ break;
+ } else
+ *cp++ = c;
+ }
+ *cp = 0;
+
+ /*
+ * The real work for the match.
+ */
+ if (knamatch(name)) {
+ close(tf);
+ return(knchktc());
+ }
+ }
+}
+
+/*---------------------------------------------------------------------------*
+ * knchktc: check the last entry, see if it's tc=xxx. If so, recursively
+ * find xxx and append that entry (minus the names) to take the place of
+ * the tc=xxx entry. Note that this works because of the left to right scan.
+ *---------------------------------------------------------------------------*/
+static int knchktc()
+{
+ register char *p, *q;
+ char tcname[16]; /* name of similar keyboard */
+ char tcbuf[KEYCAP_BUFSIZ];
+ char *holdtbuf = tbuf;
+ int l;
+
+ p = tbuf + strlen(tbuf) - 2; /* before the last colon */
+ while (*--p != ':')
+ if (p<tbuf) {
+ write(2, "Bad keycap entry\n", 18);
+ return (0);
+ }
+ p++;
+ /* p now points to beginning of last field */
+ if (p[0] != 't' || p[1] != 'c')
+ return(1);
+ strcpy(tcname,p+3);
+ q = tcname;
+ while (q && *q != ':')
+ q++;
+ *q = 0;
+ if (++hopcount > MAXHOP) {
+ write(2, "Infinite tc= loop\n", 18);
+ return (0);
+ }
+ if (kgetent(tcbuf, tcname) != 1)
+ return(0);
+ for (q=tcbuf; *q != ':'; q++)
+ ;
+ l = p - holdtbuf + strlen(q);
+ if (l > KEYCAP_BUFSIZ) {
+ write(2, "Keycap entry too long\n", 23);
+ q[KEYCAP_BUFSIZ - (p-tbuf)] = 0;
+ }
+ strcpy(p, q+1);
+ tbuf = holdtbuf;
+ return(1);
+}
+
+/*---------------------------------------------------------------------------*
+ * knamatch deals with name matching. The first field of the keycap entry
+ * is a sequence of names separated by |'s, so we compare against each such
+ * name. The normal : terminator after the last name (before the first field)
+ * stops us.
+ *---------------------------------------------------------------------------*/
+static int knamatch(np)
+char *np;
+{
+ register char *Np, *Bp;
+
+ Bp = tbuf;
+ if (*Bp == '#' || *Bp == 0)
+ return(0);
+ for (;;) {
+ for (Np = np; *Np && *Bp == *Np; Bp++, Np++)
+ continue;
+ if (*Np == 0 && (*Bp == '|' || *Bp == ':' || *Bp == 0))
+ return (1);
+ while (*Bp && *Bp != ':' && *Bp != '|')
+ Bp++;
+ if (*Bp == 0 || *Bp == ':')
+ return (0);
+ Bp++;
+ }
+}
+
+/*---------------------------------------------------------------------------*
+ * Skip to the next field. Notice that this is very dumb, not knowing about
+ * \: escapes or any such. If necessary, :'s can be put into the keycap file
+ * in octal.
+ *---------------------------------------------------------------------------*/
+static char *kskip(bp)
+char *bp;
+{
+ while (*bp && *bp != ':')
+ bp++;
+ if (*bp == ':')
+ bp++;
+ return (bp);
+}
+
+/*---------------------------------------------------------------------------*
+ * Return the (numeric) option id. Numeric options look like 'li#80' i.e.
+ * the option string is separated from the numeric value by a # character.
+ * If the option is not found we return -1. Note that we handle octal
+ * numbers beginning with 0.
+ *---------------------------------------------------------------------------*/
+int kgetnum(id)
+char *id;
+{
+ register int i, base;
+ register char *bp = tbuf,*xp;
+
+ for (;;) {
+ bp = kskip(bp);
+ if (*bp == 0)
+ return (-1);
+ if ((xp=nmatch(id,bp)) == 0)
+ continue;
+ bp = xp; /* we have an entry */
+ if (*bp == '@')
+ return(-1);
+ if (*bp != '#')
+ continue;
+ bp++;
+ base = 10;
+ if (*bp == '0')
+ base = 8;
+ i = 0;
+ while (isdigit(*bp))
+ i *= base, i += *bp++ - '0';
+ return (i);
+ }
+}
+
+/*---------------------------------------------------------------------------*
+ * Handle a flag option. Flag options are given "naked", i.e. followed by
+ * a : or the end of the buffer. Return 1 if we find the option, or 0 if
+ * it is not given.
+ *---------------------------------------------------------------------------*/
+int kgetflag(id)
+char *id;
+{
+ register char *bp = tbuf,*xp;
+
+ for (;;) {
+ bp = kskip(bp);
+ if (!*bp)
+ return (0);
+ if ((xp=nmatch(id,bp)) != 0) {
+ bp = xp;
+ if (!*bp || *bp == ':')
+ return (1);
+ else if (*bp == '@')
+ return(0);
+ }
+ }
+}
+
+/*---------------------------------------------------------------------------*
+ * Get a string valued option. These are given as 'cl=^Z'. Much decoding
+ * is done on the strings, and the strings are placed in area, which is a
+ * ref parameter which is updated. No checking on area overflow.
+ *---------------------------------------------------------------------------*/
+char *kgetstr(id, area)
+char *id;
+char **area;
+{
+ register char *bp = tbuf,*xp;
+
+ for (;;) {
+ bp = kskip(bp);
+ if (!*bp)
+ return (0);
+ if ((xp = nmatch(id,bp)) == 0)
+ continue;
+ bp = xp;
+ if (*bp == '@')
+ return(0);
+ if (*bp != '=')
+ continue;
+ bp++;
+ return (kdecode(bp, area));
+ }
+}
+
+/*---------------------------------------------------------------------------*
+ * kdecode does the grung work to decode the string capability escapes.
+ *---------------------------------------------------------------------------*/
+static char *kdecode(str, area)
+char *str;
+char **area;
+{
+ register char *cp;
+ register int c;
+ register char *dp;
+ int i;
+
+ cp = *area;
+ while ((c = *str++) && c != ':') {
+ switch (c) {
+
+ case '^':
+ c = *str++ & 037;
+ break;
+
+ case '\\':
+ dp = "E\033^^\\\\::n\nr\rt\tb\bf\f";
+ c = *str++;
+nextc:
+ if (*dp++ == c) {
+ c = *dp++;
+ break;
+ }
+ dp++;
+ if (*dp)
+ goto nextc;
+ if (isdigit(c)) {
+ c -= '0', i = 2;
+ do
+ c <<= 3, c |= *str++ - '0';
+ while (--i && isdigit(*str));
+ }
+ break;
+ }
+ *cp++ = c;
+ }
+ *cp++ = 0;
+ str = *area;
+ *area = cp;
+ return (str);
+}
+
+/*-------------------------------- EOF --------------------------------------*/
diff --git a/sys/arch/i386/isa/pcvt/Util/keycap/keycap.h b/sys/arch/i386/isa/pcvt/Util/keycap/keycap.h
new file mode 100644
index 00000000000..1dc4c3e1e6e
--- /dev/null
+++ b/sys/arch/i386/isa/pcvt/Util/keycap/keycap.h
@@ -0,0 +1,49 @@
+/*-
+ * Copyright (c) 1992, 1993 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Holger Veit
+ *
+ * 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.
+ *
+ * @(#)keycap.h, 3.20, Last Edit-Date: [Tue Dec 20 14:52:11 1994]
+ */
+
+#ifndef _KEYCAP_H_
+#define _KEYCAP_H_
+
+int kgetent( char*, char* );
+int kgetnum( char* );
+int kgetflag( char* );
+char *kgetstr( char*, char** );
+
+#endif /* _KEYCAP_H_ */
+
+/*-------------------------------- EOF -------------------------------------*/
diff --git a/sys/arch/i386/isa/pcvt/Util/keycap/keycap.src b/sys/arch/i386/isa/pcvt/Util/keycap/keycap.src
new file mode 100644
index 00000000000..af50d728c69
--- /dev/null
+++ b/sys/arch/i386/isa/pcvt/Util/keycap/keycap.src
@@ -0,0 +1,613 @@
+# Copyright (c) 1992, 1993, 1994 Hellmuth Michaelis, Joerg Wunsch and
+# Holger Veit.
+#
+# All rights reserved.
+#
+# 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 Hellmuth Michaelis,
+# Joerg Wunsch and Holger Veit.
+# 4. The names of the Authors may not be used to endorse or promote
+# products derived from this software without specific prior written
+# permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE AUTHORS 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.
+#
+# @(#)keycap.src, 3.20, Last Edit-Date: [Wed Mar 8 20:53:01 1995]
+#
+#---------------------------------------------------------------------------
+#
+# keyboard mappings for vt220 emulator pcvt 3.00
+# ----------------------------------------------
+#
+# DEC MCS and/or ISO-Latin-1 Characterset used
+#
+# MF II Keyboards fully supported
+# AT Keyboards lack a ALTGR Key, so they cannot be handled by
+# the current driver implementation .... sorry
+#
+# If you design a new entry for national keyboards, please
+# send it to hm@hcshh.hcs.de, thank you !
+#
+# Many entries are taken from the 386BSD patchkit 0.2.4 codrv
+#
+#---------------------------------------------------------------------------
+#
+# -hm patch from Thomas Gellekum
+# -hm renamed finnish "f8" entry to "f1"
+#
+#---------------------------------------------------------------------------
+
+df|default|default entry:\
+ :de:
+
+tt|test|Test entry which swaps y and z:\
+ :K22=z:S22=Z:C22=\032:\
+ :K46=y:S46=Y:C46=\031:
+
+# from codrv, untested
+be|belgium|Belgian mapping:\
+ :K1=\262:S1=\263:\
+ :K2=&:S2=1:A2=|:\
+ :K3=\351:S3=2:A3=@:\
+ :K4=":S4=3:A4=#:\
+ :K5=':S5=4:\
+ :K6=(:S6=5:\
+ :K7=\247:S7=6:A7=\136:\
+ :K8=\350:S8=7:\
+ :K9=!:S9=8:\
+ :K10=\347:S10=9:A10={:\
+ :K11=\340:S11=0:A11=}:\
+ :K12=):S12=\260:\
+ :K13=-:S13=_:\
+ :K17=a:S17=A:C17=^A:\
+ :K18=z:S18=Z:C18=^z:\
+ :K27=\136:S27=\250:A27=[:p1#27:\
+ :K28=$:S28=*:A28=]:\
+ :K31=q:S31=Q:C31=^q:\
+ :K40=m:S40=M:C40=^m:\
+ :K41=\371:S41=%:A41=':p2#41:\
+ :K42=\265:S42=\243:A42=\264:p3#42:\
+ :K45=<:S45=>:A45=\\:\
+ :K46=w:S46=W:C46=^w:\
+ :K52=,:S52=\077:\
+ :K53=;:S53=.:\
+ :K54=\072:S54=/:\
+ :K55==:S55=+:A55=~:\
+ :l1#62:a0:
+
+# from codrv, untested
+ca|canadafr|Canadian French mapping:\
+ :K1=#:S1=|:A1=\\:\
+ :A2=\261:S3=":A3=@:S4=/:A4=\243:A5=\242:\
+ :A6=\244:S7=\077:A7=\254:S8=&:A8=\246:S9=*:A9=\262:\
+ :S10=(:A10=\263:S11=):A11=\274:\
+ :K12=-:S12=_:A12=\275:\
+ :K13==:S13=+:A13=\276:\
+ :A25=\247:A26=\266:\
+ :K27=\136:S27=\136:A27=[:\
+ :K28=\270:S28=\250:A28=]:p1#28:\
+ :A40=~:K41=`:S41=`:A41={:\
+ :K42=<:S42=>:A42=}:\
+ :K45=\253:S45=\273:A45=\260:\
+ :A49=\253:A50=\273:A51=\260:\
+ :A52=\265:K53=,:S53=,:A53=-:\
+ :K54=\351:S54=\311:A54=':\
+ :l1#62:a0:
+
+# from codrv, untested
+c1|swissde|Swiss German mapping:\
+ :K1=\247:S1=\260:p1#1:\
+ :S2=+:A2=|:S3=":A3=@:S4=*:A4=#:S5=\347:S7=&:A7=\254:\
+ :S8=/:A8=\246:S9=(:A9=\242:S10=):S11==:\
+ :K12=`:S12=\077:A12=':p2#12:\
+ :K13=^:S13=\\:A13=~:p3#13:\
+ :K22=z:S22=Z:C22=\032:\
+ :S27=\350:K27=\374:A27=[:\
+ :K28=\250:S28=!:A28=]:\
+ :S40=\351:K40=\366:\
+ :S41=\340:K41=\344:A41={:\
+ :K42=$:S42=\243:A42=}:\
+ :K45=<:S45=>:A45=\\:\
+ :K46=y:S46=Y:C46=\031:
+ :S53=;:S54=\072:K55=-:S55=_:\
+ :l1#62:a0:
+
+# from codrv, untested
+c2|swissfr|Swiss French mapping:\
+ :K27=\350:S27=\374:A27=[:\
+ :K40=\351:S40=\366:\
+ :K41=\340:S41=\344:A41={:\
+ :tc=swissde:
+
+# more programmer-like than an original German kbd, you needn't
+# have gum-fingers to get `{}' and the like:-)
+# maps: ae -> [, oe -> \, ue -> ], Ae -> {, Oe -> |, Ue -> }
+# umlaute are available as AltGr- and Control-Mappings
+# also maps Pause -> ^Z
+#
+# (from Joerg Wunsch)
+#
+# l1/m1 bindings: left Alt is AltGr
+# Emacs functions:
+# C79/C89: ctrl-{leftarrow,rightarrow} {backward,forward} word
+# A79/A89: {backward,forward} sexp
+# C83/C84: ctrl-{uparrow,downarrow} {backward,forward} window
+#
+de-prog|germany-prog|programmer's mapping for german keyboard:\
+ :K27=]:S27=}:A27=\374:C27=\334:\
+ :K40=\\:S40=|:A40=\366:C40=\326:\
+ :K41=[:S41={:A41=\344:C41=\304:\
+ :K126=\032:C126=\003:\
+ :tc=de:
+# :l1#60:l2#62:\
+# :C79=^[B:K79=^[[D:S79=^[OD:A79=^[^B:\
+# :C89=^[F:K89=^[[C:S89=^[OC:A89=^[^F:\
+# :C83=^U-1^XO:K83=^[[A:S84=^[OA:\
+# :C84=^XO:K84=^[[B:S84=^[OB:\
+
+de|germany|German mapping for MF II-Keyboard:\
+ :K1=\136:S1=\260:\
+ :S3=\042:S4=\247:S7=&:S8=/:S9=(:S10=):S11=\075:\
+ :A3=\262:A4=\263:A8={:A9=[:A10=]:A11=}:A12=\134:\
+ :K12=\337:S12=?:C12=\034:\
+ :K13=':S13=`:\
+ :A17=\100:\
+ :K22=z:S22=Z:C22=\032:\
+ :K27=\374:S27=\334:\
+ :K28=+:S28=*:A28=\176:\
+ :K29=\043:S29=':A29=\174:\
+ :K40=\366:S40=\326:\
+ :K41=\344:S41=\304:\
+ :A45=\174:\
+ :K46=y:S46=Y:C46=\031:\
+ :A52=\265:\
+ :S53=;:S54=\072:\
+ :K55=-:S55=_:\
+ :l1#62:
+
+de-at|germany-at|German mapping for AT-Keyboard:\
+ :K1=<:S1=>:\
+ :S3=\042:\
+ :S4=\247:\
+ :S7=&:\
+ :S8=/:\
+ :S9=(:\
+ :S10=):\
+ :S11=\075:\
+ :K12=\337:S12=?:C12=\034:\
+ :K13=':S13=`:\
+ :K14=#:S14=\136:\
+ :K22=z:S22=Z:C22=\032:\
+ :K27=\374:S27=\334:\
+ :K28=+:S28=*:\
+ :K29=\043:S29=':\
+ :K40=\366:S40=\326:\
+ :K41=\344:S41=\304:\
+ :K46=y:S46=Y:C46=\031:\
+ :S53=;:S54=\072:\
+ :K55=-:S55=_:\
+
+# from codrv, untested
+# Includes improvements by Thomas Hiller (hiller@fzi.de)
+# and Andreas Israel (ai@hrz.tu-chemnitz.de)
+de-hi|germany-hiller|yet another German mapping:\
+ :K1=\136:S1=\260:C1=|:\
+ :S3=\042:S4=#:S7=&:S8=/:S9=(:S10=):S11=\075:\
+ :A8={:A9=[:A10=]:A11=}:A17=@:A28=~:\
+ :K12=\337:S12=\077:C12=\036:A12=\\:\
+ :K13=':S13=`:C13=\134:p1#13:\
+ :K22=z:S22=Z:C22=\032:\
+ :K27=\374:S27=\334:C27=\035:\
+ :K28=+:S28=*:C28=\000:\
+ :K29=<:S29=>:C29=\134:\
+ :K40=\366:S40=\326:C40=\034:\
+ :K41=\344:S41=\304:C41=\033:\
+ :K46=y:S46=Y:C46=\031:\
+ :S53=;:S54=\072:\
+ :K55=-:S55=_:\
+ :l1#62:a0:
+
+# from codrv, untested
+# Contribution by Thomas Hiller (hiller@fzi.de)
+# "K42 may not work on 102 keys kbds, K29 seems to work"
+d1|de-102|german with mf2:\
+ :K29=#:\
+ :K42=#:\
+ :K45=<:S45=>:A45=|:\
+ :tc=germany:
+
+# from codrv, untested
+hv|holgi|Holgi's special MF1 keyboard mapping:\
+ :K1=<:S1=>:C1=|:\
+ :K29=#:S29=\136:A29=\\:C29=~:\
+ :tc=germany:
+
+# from codrv, untested
+# Contributed by Andreas Israel (ai@hrz.tu-chemnitz.de)
+de-ai|nixmf2|ct22|nix|nix7|German Nixdorf MF2:\
+ :A28=~:\
+ :K29=#:S29=':\
+ :K45=<:S45=>:A45=|:\
+ :tc=germany:
+
+# from codrv, untested
+dk|denmark|Danish mapping:\
+ :K1=\275:S1=\247:\
+ :S3=":A3=@:\
+ :A4=\243:\
+ :S5=\244:A5=$:\
+ :S7=&:S8=/:A8={:S9=(:A9=[:S10=):A10=]:S11==:A11=}:\
+ :K12=+:S12=\077:\
+ :K13=':S13=`:A13=|:p1#13:\
+ :K27=\345:S27=\305:\
+ :K28=\250:S28=\136:A28=~:p2#28:\
+ :K40=\346:S40=\306:\
+ :K41=\370:S41=\330:\
+ :K42=:S42=*:\
+ :K45=<:S45=>:A45=\\:\
+ :S53=;:S54=\072:\
+ :K55=-:S55=_:\
+ :l1#62:a0:
+
+# from codrv, untested
+# Finnish keyboard map with 7-bit versions of the national
+# chars. The Latin1 chars are available with Alt-7, Alt-8, etc
+# (where normally you would have the 7-bit ones).
+# Makes C/C++ programming more comfortable, since the 7-bit chars
+# (|\{[}]) are needed much more often than the Latin1 chars.
+# -- Petri.Wessman@hut.fi
+fi|finland|finland7b|finland-ascii|Finnish ASCII mapping:\
+ :l1#60:l2#62:\
+ :A8=\344:A9=\304:A10=\305:A11=\345:A12=\326:A13=\366:\
+ :K40=|:S40=\\:K41={:S41=[:K27=}:S27=]:\
+ :S1=\275:K1=\247:\
+ :S3=":A3=@:\
+ :A4=\243:\
+ :S5=$:A5=$:\
+ :S7=&:S8=/:S9=(:S10=):S11==:\
+ :K12=+:S12=\077:\
+ :K13=':S13=`:\
+ :K28=~:S28=\136:A28=~:\
+ :K29=':S29=*:\
+ :K45=<:S45=>:A45=|:\
+ :S53=;:S54=\072:\
+ :K55=-:S55=_:\
+ :a0:
+
+# from codrv, untested
+# Finnish keyboard map with the Latin1 national chars in
+# their "right" place. --Petri.Wessman@hut.fi
+f1|finland8b|finland-latin1|Finnish Latin1 mapping:\
+ :A8={:A9=[:A10=]:A11=}:A12=\\:\
+ :K40=\366:S40=\326:K41=\344:S41=\304:K27=\345:S27=\305:\
+ :tc=finland:
+
+
+# French keyboard mapping
+# From Matthieu Herrb <matthieu@laas.fr>
+# For 102 keys keyboards, produces 8 bits characters
+# with ISO Latin-1 encoding
+f8|france-iso-8859-1|French ISO 8859-1 102 keys keyboard:\
+ :l1#62:\
+ :K1=\262:S1=:\
+ :K2=&:S2=1:\
+ :K3=\351:S3=2:C3=\211:A3=~:\
+ :K4=":S4=3:A4=#:\
+ :K5=':S5=4:A5={:\
+ :K6=(:S6=5:A6=[:\
+ :K7=-:S7=6:C7=\036:A7=|:\
+ :K8=\350:S8=7:C8=\210:A8=`:\
+ :K9=_:S9=8:C9=\037:A9=\\:\
+ :K10=\347:S10=9:C10=\207:A10=\136:\
+ :K11=\340:S11=0:C11=\340:A11=@:\
+ :K12=):S12=\260:A12=]:\
+ :A13=}:\
+ :K17=a:S17=A:C17=\001:\
+ :K18=z:S18=Z:C18=\032:\
+ :D27:\
+ :K28=$:S28=\243:\
+ :K29=*:S29=\265:\
+ :K31=q:S31=Q:C31=\021:\
+ :K40=m:S40=M:C40=\015;\
+ :K41=\371:C41=\231:S41=%:\
+ :K42=*:S42=\265:\
+ :K46=w:S46=W:C46=\027:\
+ :K52=,:S52=?:\
+ :K53=;:S53=.:\
+ :K54=\072:S54=/:C54=\037\
+ :K55=!:S55=\266:
+
+# fr|france|French mapping:\
+# :de:
+#
+# from codrv, untested
+# f1|france120|French 120 mapping:\
+# :tc=belgium:
+#
+#
+# from codrv, untested
+#f2|france189|French 189 mapping:\
+# :S1=:A1=':p3#1:\
+# :A2=:A3=~:A5={:A6=[:A7=|:A8=`:\
+# :S9=_:A9=\\:A10=\136:A11=@:A12=]:A13=}:\
+# :A27=:A28=\244:A41=:A42=:\
+# :A45=:!:S45=\247:\
+# :tc=belgium:
+
+# From: Andy Duplain, duplain@rtf.bt.co.uk
+gb|greatbritain|British mapping for MF-2 keyboard:\
+ :S1=|:S3=":C3=2:C12=-:S41=@:K42=#:S42=~:C42=#:K45=\\:S45=|:C45=\\:
+
+# from codrv, untested
+# This entry has been corrected by Mike Trim (mtrim@crucible.demon.co.uk)
+# (hv's comment: For the keys # and ~ you might also check the following
+# line
+# :K42=#:S42=~:\
+# Also I think I was wrong with the ALTGR key. If you need one, add this:
+# :l1#62:
+g1|greatbritain166|British 166 mapping:\
+ :K1=`:S1=\254:A1=|:\
+ :S3=":S4=\243:\
+ :K41=':S41=@:\
+ :K29=#:S29=~:\
+ :K45=\\:S45=|:
+
+# from codrv, untested
+g2|greatbritain168|British 168 mapping:\
+ :K1=\\:S1=|:\
+ :S3=":S4=\243:S7=&:S8=:S9=(:S10=):A10=\261:\
+ :S11=#:A11=\260:S12=:K13=\254:S13=-:\
+ :K27=@:S27=`:\
+ :K28=[:S28={:A28=~:\
+ :K40=;:S40=+:\
+ :K41=\072:S41=*:A41=\136:\
+ :K42=]:S42=}:\
+ :K45=|:S45=_:\
+ :A52=\265:\
+ :l1#62:a0:
+
+# from codrv, untested
+is:iceland:Island mapping:\
+ :K1=\260:S1=\250:p1#1:\
+ :S2=":S7=&:S8=/:A8={:S9=(:A9=[:S10=):A10=]:S11==:A11=}:\
+ :K12=\\:S12=\326:\
+ :K13=':S13=`:A13=|:\
+ :A17=@:K27=\360:S27=\320:\
+ :K28=':S28=\077:A28=~:\
+ :K40=\346:S40=\306:\
+ :K41=':S41=':A41=\136:p2#41:\
+ :K42=+:S42=*:A42=`:p3#42:\
+ :K45=<:S45=>:A45=|:\
+ :S53=;:S54=\072:\
+ :K54=\376:S54=\336:\
+ :K104=,:104=,:\
+ :l1#62:a0:
+
+# from codrv, untested
+i1|italy141|Italian 141 mapping:\
+ :K1=\\:S1=|:\
+ :S3=":S4=\243:S7=&:S8=/:S9=(:S10=):S11==:\
+ :K12=':S12=\077:\
+ :K13=\354:S13=\136:\
+ :K27=\350:S27=\351:\A27=[:\
+ :K28=+:S28=*:A28=]:\
+ :K40=\362:S40=\347:A40=@:\
+ :K41=\340:S41=\260:A41=#:\
+ :K42=\371:S42=\247:\
+ :K45=<:S45=>:\
+ :S53=;:S54=\072:\
+ :K55=-:S55=_:\
+ :l1#62:a0:
+
+# from codrv, untested
+i2|italy142|Italian 142 mapping:\
+ :A8={:A9=[:A10=]:A11=}:\
+ :A17=@:A27=:A28=~:A40=:A41=:\
+ :tc=italy141:a0:
+
+# from codrv, untested
+nl|netherlands|Dutch mapping:\
+ :K1=@:S1=\247:A1=\254:\
+ :A2=\271:S3=":A3=\262:S4=#:A4=\263:A5=\274:A6=\275:S7=&:\
+ :A7=\276:S8=_:A8=\243:S9=(:A9={:S10=):A10=}:S11=':\
+ :K12=/:S12=\077:A12=\\:\
+ :K13=\260:S13=~:A13=\270:p1#13:\
+ :K20=\266:K27=\250:S27=^:p2#27:\
+ :K28=*:S28=|:\
+ :K40=+:S40=\261:\
+ :K41=':S41=`:\
+ :K42=<:S42=>:\
+ :K45=[:S45=]:A45=|:\
+ :S53=;:S54=\072:K55=-:S55=_:\
+ :K104=,:S104=,:\
+ :l1#62:a0:
+
+# from codrv, untested
+no|norway|Norwegian mapping:\
+ :K1=|:\
+ :K13=\\:S13=`:A13=':p1#13:\
+ :K41=\346:S41=\306:\
+ :K40=\370:S40=\330:\
+ :A45=:\
+ :tc=denmark:
+
+# from codrv, untested
+pt|portugal|Portugesian mapping:\
+ :K1=\\:S1=|:\
+ :S3=":A3=@:A4=\243:A5=\247:S7=&:S8=/:A8={:S9=(:A9=[:\
+ :S10=):A10=]:S11=}:A11==:\
+ :K12=':S12=\077:\
+ :K13=\253:S13=\273:\
+ :K40=\347:S40=\307:\
+ :K41=\272:S41=\252:\
+ :K42=~:S42=^:p1#42:\
+ :K45=<:S45=>:\
+ :S53=;:S54=\072:K55=-:S55=_:\
+ :l1#62:a0:
+
+# from codrv, untested
+es|spain|Spainish mapping:\
+ :K1=\272:S1=\252:A1=\\:\
+ :A2=|:S3=":A3=@:S4=:A4=#:S7=&:A7=\254:S8=/:S9=(:S10=):S11==:\
+ :K12=':S12=\077:p1#12:\
+ :K13=\277:S13=\241:\
+ :K27=`:S27=^:A27=[:p2#27:\
+ :K28=+:S28=*:A28=]:\
+ :K40=\361:S41=\321:\
+ :K41=/:S41=\250:A41={:p3#41:\
+ :K42=\347:S42=\307:A42=}:\
+ :K45=<:S45=>:\
+ :S53=;:S54=\072:\
+ :K55=-:S55=_:\
+ :K104=,:S104=,:\
+ :l1#62:a0:
+
+# from codrv, untested
+# Contributed by Mats O Jansson, moj@stacken.kth.se
+# "Here is my map, rather large, but i want ALTGR normaly to be dead.
+# Only seven bit national characters have been placed where national characters
+# is on the keyboard."
+# We can help this man, just use the 'a0' capability -hv-
+s1|sweden1|Swedish mapping:\
+ :l1#62:a0:\
+ :D1:\
+ :K12=+:K13=':K29=':\
+ :S2=!:S3=":S4=#:S5=$:S6=%:S7=&:S8=/:\
+ :S9=(:S10=):S11=\075:S12=\077:S13=`:S29=*:\
+ :C2=:C3=\000:C4=\033:C5=\034:C6=\035:C7=:C8=:C9=:\
+ :C10=:C11=:C12=:C13=:C29=:\
+ :A3=\100:A5=$:A8={:\
+ :A9=[:A10=]:A11=}:A12=\134:\
+ :K27=]:K28=:\
+ :S27=}:S28=\136:\
+ :C27=\035:C28=:\
+ :A28=\176:\
+ :K40=\134:K41=[:\
+ :S40=|:S41={:\
+ :C40=\034:C41=\033:\
+ :K45=<:K53=,:K54=.:K55=-:\
+ :S45=>:S53=;:S54=\072:S55=_:\
+ :C45=\034:C53=:C54=:C55=:\
+ :A45=|:\
+ :C61=\000:
+
+# from codrv, untested
+# Contributed by Mats O Jansson, moj@stacken.kth.se
+# "Here is my map, rather large, but i want ALTGR normaly to be dead.
+# Only seven bit national characters have been placed where national
+# characters is on the keyboard."
+# We can help this man, just use the 'a0' capability -hv-
+# Corrected by Paul Pries, 5322@msg.abc.se (Some national shifts were
+# wrong).
+sa|sweden1a|Swedish 7bit mapping ISO 646:\
+ :l1#62:a0:\
+ :D1:\
+ :K12=+:K13=':K29=':\
+ :S2=!:S3=":S4=#:S5=$:S6=%:S7=&:S8=/:\
+ :S9=(:S10=):S11=\075:S12=\077:S13=`:S29=*:\
+ :C2=:C3=\000:C4=\033:C5=\034:C6=\035:C7=:C8=:C9=:\
+ :C10=:C11=:C12=:C13=:C29=:\
+ :A3=\100:A5=$:A8={:\
+ :A9=[:A10=]:A11=}:A12=\134:\
+ :K27=}:K28=:\
+ :S27=]:S28=\136:\
+ :C27=\035:C28=:\
+ :A28=\176:\
+ :S40=\134:S41=[:\
+ :K40=|:K41={:\
+ :C40=\034:C41=\033:\
+ :K45=<:K53=,:K54=.:K55=-:\
+ :S45=>:S53=;:S54=\072:S55=_:\
+ :C45=\034:C53=:C54=:C55=:\
+ :A45=|:\
+ :C61=\000:
+
+# from codrv, untested
+# Swedish keyboard map with national characters.
+# Paul Pries, 5322@msg.abc.se
+s2|sweden2|Swedish 8bit mapping ISO 8859-1:\
+ :l1#62:\
+ :K1=\247:S1=:\
+ :K12=+:K13=':K29=':\
+ :S2=!:S3=":S4=#:S5=$:S6=%:S7=&:S8=/:\
+ :S9=(:S10=):S11=\075:S12=\077:S13=`:S29=*:\
+ :C2=:C3=\000:C4=\033:C5=\034:C6=\035:C7=:C8=:C9=:\
+ :C10=:C11=:C12=:C13=:C29=:\
+ :A3=\100:A4=\234:A5=$:A8={:\
+ :A9=[:A10=]:A11=}:A12=\134:\
+ :K27=\206:K28=:\
+ :S27=\217:S28=\136:\
+ :C27=\035:C28=:\
+ :A28=\176:\
+ :S40=\231:S41=\216:\
+ :K40=\224:K41=\204:\
+ :C40=\034:C41=\033:\
+ :K45=<:K53=,:K54=.:K55=-:\
+ :S45=>:S53=;:S54=\072:S55=_:\
+ :C45=\034:C53=:C54=:C55=:\
+ :A45=|:\
+ :C61=\000:
+
+#
+# tg: my idiosyncratic mappings (thomas@ghpc8.ihf.rwth-aachen.de)
+#
+# the six function keys above the cursor keys are arranged
+# identical to a real VT220:
+#
+# find insert remove
+# select up down
+#
+# since i don't have a use for the numbers on the keypad,
+# i map NumLock, /, *, - to PF1-PF4;
+# + is mapped to SS3 l, shifted + is mapped to SS3 m
+#
+# they convinced me finally to add some support for german umlauts.
+# so, i stole the mapping from jörg wunsch's de-prog entry.
+#
+# tg
+#
+
+tg:\
+ :l1#62:\
+ :A12=\337:\
+ :A27=\374:C27=\334:\
+ :A40=\366:C40=\326:\
+ :A41=\344:C41=\304:\
+ :K126=\032:C126=\003:\
+ :K75=[1~:S75=[1~:C75=[1~:\
+ :K76=[4~:S76=[4~:C76=[4~:\
+ :K80=[2~:S80=[2~:C80=[2~:\
+ :K81=[5~:S81=[5~:C81=[5~:\
+ :K85=[3~:S85=[3~:C85=[3~:\
+ :K86=[6~:S86=[6~:C86=[6~:\
+ :K90=OP:S90=OP:C90=OP:\
+ :K95=OQ:S95=OQ:C95=OQ:\
+ :K100=OR:S100=OR:C100=OR:\
+ :K104=On:S104=On:C104=On:\
+ :K105=OS:S105=OS:C105=OS:\
+ :K106=Ol:S106=Om:\
+ :K108=OM:S108=OM:C108=OM:
+
+us|usa|United States mapping:\
+ :de:
+
+# EOF
diff --git a/sys/arch/i386/isa/pcvt/Util/loadfont/Makefile b/sys/arch/i386/isa/pcvt/Util/loadfont/Makefile
new file mode 100644
index 00000000000..c0f454fdc04
--- /dev/null
+++ b/sys/arch/i386/isa/pcvt/Util/loadfont/Makefile
@@ -0,0 +1,3 @@
+PROG= loadfont
+
+.include <bsd.prog.mk>
diff --git a/sys/arch/i386/isa/pcvt/Util/loadfont/loadfont.1 b/sys/arch/i386/isa/pcvt/Util/loadfont/loadfont.1
new file mode 100644
index 00000000000..913802c429b
--- /dev/null
+++ b/sys/arch/i386/isa/pcvt/Util/loadfont/loadfont.1
@@ -0,0 +1,91 @@
+.\" Copyright (c) 1992, 1995 Hellmuth Michaelis
+.\"
+.\" All rights reserved.
+.\"
+.\" 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 Hellmuth Michaelis
+.\" 4. The name authors may not be used to endorse or promote products
+.\" derived from this software without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``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 AUTHORS 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.
+.\"
+.\" @(#)loadfont.1, 3.31, Last Edit-Date: [Thu Aug 24 10:44:42 1995]
+.\"
+.Dd August 24, 1995
+.Dt LOADFONT 1
+.Sh NAME
+.Nm loadfont
+.Nd EGA/VGA fontloader for pcvt video driver.
+.Sh SYNOPSIS
+.Nm loadfont
+.Op Fl c Ar charsetno
+.Op Fl d Ar devicefile
+.Op Fl f Ar fontfilename
+.Op Fl i
+.Op Fl s Ar scanlines
+.Sh DESCRIPTION
+The
+.Nm loadfont
+utility is used to load fonts needed for proper operation of the pcvt
+VT220 driver on EGA and VGA boards into the font ram of this boards.
+.Pp
+The options are as follows:
+.Bl -tag -width Ds
+.It Fl c
+Specifies the slot, the font is to load into. EGA boards have four
+slots and VGA boards have eight slots available for downloading fonts.
+.It Fl d
+Specifies the devicefile to use.
+.It Fl f
+Specifies the file which contains the font to be downloaded.
+.It Fl i
+Gives information what type(s) of font do currently reside in which slot.
+This is also the default behaviour if no options are specified on the commandline.
+.It Fl s
+Specifies the number of scanlines of the display.
+.El
+.Pp
+This utility is used only on EGA and VGA boards, as MDA, HCG and CGA boards
+do not have downloadable charactersets available.
+.Sh FILES
+The following fontfiles are available in the pcvt distribution:
+
+.nf
+/usr/share/misc/pcvtfonts/vt220l.808: 8x8 IBM II font
+/usr/share/misc/pcvtfonts/vt220h.808: 8x8 Extension font
+/usr/share/misc/pcvtfonts/vt220l.810: 8x10 IBM II font
+/usr/share/misc/pcvtfonts/vt220h.810: 8x10 Extension font
+/usr/share/misc/pcvtfonts/vt220l.814: 8x14 IBM II font
+/usr/share/misc/pcvtfonts/vt220h.814: 8x14 Extension font
+/usr/share/misc/pcvtfonts/vt220l.816: 8x16 IBM II font
+/usr/share/misc/pcvtfonts/vt220h.816: 8x16 Extension font
+.fi
+.Sh EXAMPLES
+The command
+.Dq Li loadfont -c0 -f/usr/share/misc/pcvtfonts/vt220l.816
+loads a 8x16 font containing the standard IBM characterset II into font slot
+0 on a VGA or EGA board.
+.Sh BUGS
+No known bugs
+.Sh SEE ALSO
+.Xr cursor 1 ,
+.Xr scon 1 ,
+.Xr pcvt 8
diff --git a/sys/arch/i386/isa/pcvt/Util/loadfont/loadfont.c b/sys/arch/i386/isa/pcvt/Util/loadfont/loadfont.c
new file mode 100644
index 00000000000..3d66fd8e932
--- /dev/null
+++ b/sys/arch/i386/isa/pcvt/Util/loadfont/loadfont.c
@@ -0,0 +1,392 @@
+/*
+ * Copyright (c) 1992, 1995 Hellmuth Michaelis
+ *
+ * Copyright (c) 1992, 1994 Brian Dunford-Shore
+ *
+ * All rights reserved.
+ *
+ * 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
+ * Hellmuth Michaelis and Brian Dunford-Shore
+ * 4. The name authors may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``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 AUTHORS 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.
+ *
+ */
+
+static char *id =
+ "@(#)loadfont.c, 3.31, Last Edit-Date: [Thu Aug 24 10:40:50 1995]";
+
+/*---------------------------------------------------------------------------*
+ *
+ * load a font into vga character font memory
+ *
+ * -hm removing explicit HGC support (same as MDA ..)
+ * -hm new pcvt_ioctl.h SIZ_xxROWS
+ * -hm add -d option
+ * -hm patch from Joerg, -s scanlines option
+ *
+ *---------------------------------------------------------------------------*/
+
+#include <stdio.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <machine/pcvt_ioctl.h>
+
+struct screeninfo screeninfo;
+
+#define DEFAULTFD 0
+int fd;
+
+static int roundrows(int scrrow);
+static int codetosize(int code);
+static void setfont(int charset, int fontloaded, int charscan,
+ int scrscan, int scrrow);
+static void loadfont(int fontset, int charscanlines,
+ unsigned char *font_table);
+static void printvgafontattr(int charset);
+static void printheader(void);
+static void usage(void);
+
+main(int argc, char **argv)
+{
+ extern int optind;
+ extern int opterr;
+ extern char *optarg;
+
+ FILE *in;
+ struct stat sbuf, *sbp;
+ unsigned char *fonttab;
+ int ret;
+ int chr_height;
+ int scr_scan;
+ int scr_rows;
+ int scan_lines = -1;
+ int c;
+ int chr_set = -1;
+ char *filename;
+ int fflag = -1;
+ int info = -1;
+ int dflag = 0;
+ char *device;
+
+ while( (c = getopt(argc, argv, "c:d:f:is:")) != EOF)
+ {
+ switch(c)
+ {
+ case 'c':
+ chr_set = atoi(optarg);
+ break;
+
+ case 'd':
+ device = optarg;
+ dflag = 1;
+ break;
+
+ case 'f':
+ filename = optarg;
+ fflag = 1;
+ break;
+
+ case 'i':
+ info = 1;
+ break;
+
+ case 's':
+ scan_lines = atoi(optarg);
+ if(scan_lines == 0)
+ usage();
+ break;
+
+ case '?':
+ default:
+ usage();
+ break;
+ }
+ }
+
+ if(chr_set == -1 || fflag == -1)
+ info = 1;
+
+ if(dflag)
+ {
+ if((fd = open(device, O_RDWR)) == -1)
+ {
+ char buffer[80];
+ strcpy(buffer,"ERROR opening ");
+ strcat(buffer,device);
+ perror(buffer);
+ exit(1);
+ }
+ }
+ else
+ {
+ fd = DEFAULTFD;
+ }
+
+ if(ioctl(fd, VGAGETSCREEN, &screeninfo) == -1)
+ {
+ perror("ioctl VGAGETSCREEN failed");
+ exit(1);
+ }
+
+ if(info == 1)
+ {
+ int i;
+
+ switch(screeninfo.adaptor_type)
+ {
+ case UNKNOWN_ADAPTOR:
+ case MDA_ADAPTOR:
+ case CGA_ADAPTOR:
+ fprintf(stderr,
+ "Adaptor does not support Downloadable Fonts!\n");
+ break;
+ case EGA_ADAPTOR:
+ printheader();
+ for(i = 0;i < 4;i++)
+ {
+ printvgafontattr(i);
+ }
+ break;
+ case VGA_ADAPTOR:
+ printheader();
+ for(i = 0;i < 8;i++)
+ {
+ printvgafontattr(i);
+ }
+ }
+ printf("\n");
+ exit(0);
+ }
+
+ switch(screeninfo.adaptor_type)
+ {
+ case UNKNOWN_ADAPTOR:
+ case MDA_ADAPTOR:
+ case CGA_ADAPTOR:
+ fprintf(stderr,
+ "Adaptor does not support "
+ "Downloadable Fonts!\n");
+ exit(1);
+
+ case EGA_ADAPTOR:
+ if(scan_lines == -1) scan_lines = 350;
+ else if(scan_lines != 350) {
+ fprintf(stderr,
+ "EGA adaptors can only operate with "
+ "350 scan lines.\n");
+ exit(1);
+ }
+ break;
+
+ case VGA_ADAPTOR:
+ if(scan_lines == -1) scan_lines = 400;
+ else if(scan_lines != 400 && scan_lines != 480) {
+ fprintf(stderr,
+ "VGA adaptors can only operate with "
+ "400/480 scan lines.\n");
+ exit(1);
+ }
+ break;
+ }
+
+ if(chr_set < 0 || chr_set > 7)
+ usage();
+
+ sbp = &sbuf;
+
+ if((in = fopen(filename, "r")) == NULL)
+ {
+ char buffer[80];
+ sprintf(buffer, "cannot open file %s for reading", filename);
+ perror(buffer);
+ exit(1);
+ }
+
+ if((fstat(fileno(in), sbp)) != 0)
+ {
+ char buffer[80];
+ sprintf(buffer, "cannot fstat file %s", filename);
+ perror(buffer);
+ exit(1);
+ }
+
+ chr_height = sbp->st_size / 256; /* 256 chars per font */
+
+ if(chr_height * 256 != sbp->st_size ||
+ chr_height < 8 || chr_height > 20) {
+ fprintf(stderr,
+ "File is no valid font file, size = %d.\n",
+ sbp->st_size);
+ exit(1);
+ }
+
+ scr_rows = codetosize(roundrows(scan_lines / chr_height));
+ scr_scan = scr_rows * chr_height - 256 - 1;
+
+ if((fonttab = (unsigned char *)malloc((size_t)sbp->st_size)) == NULL)
+ {
+ fprintf(stderr,"error, malloc failed\n");
+ exit(1);
+ }
+
+ if((ret = fread(fonttab, sizeof(*fonttab), sbp->st_size, in)) !=
+ sbp->st_size)
+ {
+ fprintf(stderr,
+ "error reading file %s, size = %d, read = %d, "
+ "errno %d\n",
+ argv[1], sbp->st_size, ret, errno);
+ exit(1);
+ }
+
+ loadfont(chr_set, chr_height, fonttab);
+ setfont(chr_set, 1, chr_height - 1, scr_scan, scr_rows);
+
+ exit(0);
+}
+
+static int
+roundrows(int scrrow)
+{
+ if(scrrow >= 50) return SIZ_50ROWS;
+ else if(scrrow >= 43) return SIZ_43ROWS;
+ else if(scrrow >= 40) return SIZ_40ROWS;
+ else if(scrrow >= 35) return SIZ_35ROWS;
+ else if(scrrow >= 28) return SIZ_28ROWS;
+ else return SIZ_25ROWS;
+}
+
+static int
+codetosize(int code)
+{
+ static int sizetab[] = { 25, 28, 35, 40, 43, 50 };
+ if(code < 0 || code >= sizeof sizetab / sizeof(int))
+ return -1;
+ return sizetab[code];
+}
+
+static void
+setfont(int charset, int fontloaded, int charscan, int scrscan, int scrrow)
+{
+ struct vgafontattr vfattr;
+
+ vfattr.character_set = charset;
+ vfattr.font_loaded = fontloaded;
+ vfattr.character_scanlines = charscan;
+ vfattr.screen_scanlines = scrscan;
+ vfattr.screen_size = scrrow;
+
+ if(ioctl(fd, VGASETFONTATTR, &vfattr) == -1)
+ {
+ perror("loadfont - ioctl VGASETFONTATTR failed, error");
+ exit(1);
+ }
+}
+
+static void
+loadfont(int fontset, int charscanlines, unsigned char *font_table)
+{
+ int i, j;
+ struct vgaloadchar vlc;
+
+ vlc.character_set = fontset;
+ vlc.character_scanlines = charscanlines;
+
+ for(i = 0; i < 256; i++)
+ {
+ vlc.character = i;
+ for (j = 0; j < charscanlines; j++)
+ {
+ vlc.char_table[j] = font_table[j];
+ }
+ font_table += charscanlines;
+ if(ioctl(fd, VGALOADCHAR, &vlc) == -1)
+ {
+ perror("loadfont - ioctl VGALOADCHAR failed, error");
+ exit(1);
+ }
+ }
+}
+
+static void
+printvgafontattr(int charset)
+{
+ struct vgafontattr vfattr;
+
+ vfattr.character_set = charset;
+
+ if(ioctl(fd, VGAGETFONTATTR, &vfattr) == -1)
+ {
+ perror("loadfont - ioctl VGAGETFONTATTR failed, error");
+ exit(1);
+ }
+ printf(" %d ",charset);
+ if(vfattr.font_loaded)
+ {
+
+ printf("Loaded ");
+ printf(" %2.2d ", codetosize(vfattr.screen_size));
+ printf(" %2.2d ",
+ (((int)vfattr.character_scanlines) & 0x1f) + 1);
+ printf(" %3.3d",
+ ((int)vfattr.screen_scanlines+0x101));
+ }
+ else
+ {
+ printf("Empty");
+ }
+ printf("\n");
+}
+
+static void
+printheader(void)
+{
+ printf("\nEGA/VGA Charactersets Status Info:\n\n");
+ printf("Set Status Lines CharScanLines ScreenScanLines\n");
+ printf("--- ------ ----- ------------- ---------------\n");
+}
+
+static void
+usage(void)
+{
+ fprintf(stderr,
+ "\nloadfont - "
+ "load a font into EGA/VGA font ram for the pcvt video driver\n");
+ fprintf(stderr,
+ "usage: loadfont -c <charset> -d <device> -f <filename>"
+ " -i -s <scan_lines>\n");
+ fprintf(stderr,
+ " -c <charset> characterset to load (EGA 0..3, VGA 0..7)\n");
+ fprintf(stderr,
+ " -d <device> specify device\n");
+ fprintf(stderr,
+ " -f <filename> filename containing binary font data\n");
+ fprintf(stderr,
+ " -i print status and types of loaded fonts\n");
+ fprintf(stderr,
+ " -s <scan_lines> number of scan lines on screen\n");
+ exit(2);
+}
diff --git a/sys/arch/i386/isa/pcvt/Util/mcon/Makefile b/sys/arch/i386/isa/pcvt/Util/mcon/Makefile
new file mode 100644
index 00000000000..1a3b934661e
--- /dev/null
+++ b/sys/arch/i386/isa/pcvt/Util/mcon/Makefile
@@ -0,0 +1,3 @@
+PROG= mcon
+
+.include <bsd.prog.mk>
diff --git a/sys/arch/i386/isa/pcvt/Util/mcon/mcon.1 b/sys/arch/i386/isa/pcvt/Util/mcon/mcon.1
new file mode 100644
index 00000000000..088399c2359
--- /dev/null
+++ b/sys/arch/i386/isa/pcvt/Util/mcon/mcon.1
@@ -0,0 +1,166 @@
+.\" Copyright (c) 1994, 1995 Joerg Wunsch
+.\"
+.\" All rights reserved.
+.\"
+.\" 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 Joerg Wunsch
+.\" 4. The name authors may not be used to endorse or promote products
+.\" derived from this software without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``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 AUTHORS 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.
+.\"
+.\" @(#)mcon.1, 3.30, Last Edit-Date: [Fri Jun 30 20:14:42 1995]
+.\"
+.Dd January 3, 1994
+.Dt MCON 1
+.Sh NAME
+.Nm mcon
+.Nd controls pcvt mouse emulator
+.Sh SYNOPSIS
+.Nm mcon
+.Op Fl l Ar left-button-key
+.Op Fl m Ar mid-button-key
+.Op Fl r Ar right-button-key
+.Op Fl a Ar accel-time
+.Op Fl s Ar 0 | false | \&no
+.Op Fl s Ar 1 | true | yes
+.Ar device
+.Sh DESCRIPTION
+The
+.Nm mcon
+utility controls the configurable parameters for the mouse emulator of
+.Xr pcvt 4 .
+.br
+.Em NB :
+The mouse emulator is not configured in by default; the system's config
+file needs to specify an option line
+
+.Em options Dq PCVT_EMU_MOUSE
+
+in order to get its functionality.
+.Pp
+Either way, the
+.Nm
+program must be called with an argument
+.Ar device
+that specifies the device node used for the mouse emulation. This is
+usually the first device node of the
+.Xr pcvt 4
+driver not being used as a virtual terminal device. E.\ g., if you
+have configured eight virtual terminals
+.Pq the default value ,
+named
+.Pa /dev/ttyv0
+through
+.Pa /dev/ttyv7 ,
+the mouse emulator would allocate
+.Pa /dev/ttyv8 .
+
+If
+.Nm
+is called without any option, it will print the actual values of the
+configurable parameters.
+
+If called with an option, the program attempts to set up the new value.
+.Pp
+The options are as follows:
+.Bl -tag -width Ds
+.It Fl l Ar left-button-key
+.It Fl m Ar mid-button-key
+.It Fl r Ar right-button-key
+Maps the named
+.Ar button key
+to emulate either the left, middle, or right mouse button.
+.Ar Button key
+is the usual name for that key. Normal ASCII keys are denoted by the
+character they're labeled with, function keys are named
+.Em f1
+through
+.Em f10 .
+Note that the AT function keys
+.Em f11
+and
+.Em f12
+are
+.Em extended
+keys that cannot be mapped to be used with the mouse emulator since
+it only allows basic PC-scancode keys to be used.
+
+.It Fl a Ar accel-time
+Set the time limit for the internal accelerator to
+.Ar accel-time
+milliseconds. Key events occurring after a longer time than this limit
+will move the mouse cursor in single steps. Key events arriving more
+frequently will move the cursor accelerated by a factor of 6. Note that
+despite of
+.Em milliseconds
+being the unit of choice here, the time resolution is restricted by the
+timer tick distance of the underlying operating system, usually to a
+granularity of 10 milliseconds.
+
+.It Fl s Ar 0 | false | \&no
+.It Fl s Ar 1 | true | yes
+The first form disables, the second form enables the
+.Em sticky
+behaviour of the mouse buttons. Sticky mouse keys behave much like
+toggle-buttons: on first press, they become active, on second press,
+they're deactivated. Pressing another button will deactivate any
+other sticky button anyway.
+
+Sticky buttons might be more convenient since you don't need 20 fingers
+at all; on the other hand, they make it virtually impossible to initiate
+double or triple mouse clicks.
+.El
+.Sh EXAMPLES
+The following example would install the default behaviour of the
+mouse emulator:
+
+.Nm mcon
+.Fl l Ar f1
+.Fl m Ar f2
+.Fl r Ar f3
+.Fl a Ar 250
+.Fl s Ar \&no
+.Pa /dev/ttyv8
+.Sh BUGS
+The key names used to map the button-emulating keys to scan codes
+.Pq and vica verse
+are based on the American keyboard layout. This would usually not
+cause any trouble since the
+.Dq button-of-choice
+is certainly some function key that should be equal for any national
+keyboard layout.
+.Pp
+The mouse emulator is a rude hack at all; its only purpose is to provide
+a device to move the pointer within an X-windowing environment.
+.Sh SEE ALSO
+.Xr pcvt 4 ,
+.Xr X 1x .
+.Sh HISTORY
+The
+.Nm
+utility appeared in
+.Xr pcvt 4 ,
+release 3.00.
+.Sh AUTHOR
+The mouse emulator has been contributed by
+.if n Joerg Wunsch.
+.if t J\(:org Wunsch.
diff --git a/sys/arch/i386/isa/pcvt/Util/mcon/mcon.c b/sys/arch/i386/isa/pcvt/Util/mcon/mcon.c
new file mode 100644
index 00000000000..a4d65060117
--- /dev/null
+++ b/sys/arch/i386/isa/pcvt/Util/mcon/mcon.c
@@ -0,0 +1,192 @@
+/*
+ * Copyright (c) 1994, 1995 Joerg Wunsch
+ *
+ * All rights reserved.
+ *
+ * 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 Joerg Wunsch
+ * 4. The name authors may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``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 AUTHORS 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.
+ *
+ *
+ * @(#)mcon.c, 3.30, Last Edit-Date: [Fri Jun 30 20:15:02 1995]
+ */
+
+/*---------------------------------------------------------------------------*
+ *
+ * history:
+ *
+ * -jw initial version; includes a basic mapping between PeeCee
+ * scan codes and key names
+ * -hm changed sys/pcvt_ioctl.h -> machine/pcvt_ioctl.h
+ *
+ *---------------------------------------------------------------------------*/
+
+/*
+ * Utility program to wire the mouse emulator control ioctl to the
+ * user level. Allows setting of any configurable parameter, or
+ * display the current configuration.
+ */
+
+#include <machine/pcvt_ioctl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/fcntl.h>
+
+static const char *keynames[] = {
+ "", "esc", "1", "2", "3", "4", "5", "6", "7", "8", "9", "0",
+ "-", "+", "bksp", "tab", "q", "w", "e", "r", "t", "y", "u",
+ "i", "o", "p", "[", "]", "enter", "ctrl", "a", "s", "d", "f",
+ "g", "h", "j", "k", "l", ";", "\"", "`", "lshift", "\\",
+ "z", "x", "c", "v", "b", "n", "m", ",", ".", "/", "rshift",
+ "prtscr", "alt", "space", "caps", "f1", "f2", "f3", "f4",
+ "f5", "f6", "f7", "f8", "f9", "f10", "numlock", "scrolllock",
+ "kp7", "kp8", "kp9", "kp-", "kp4", "kp5", "kp6", "kp+",
+ "kp1", "kp2", "kp3", "kp0", "kp."
+};
+
+
+const char *scantoname(int scan) {
+ if(scan >= sizeof keynames / sizeof(const char *))
+ return "???";
+ else
+ return keynames[scan];
+}
+
+int nametoscan(const char *name) {
+ int i;
+ for(i = 0; i < sizeof keynames / sizeof(const char *); i++)
+ if(strcmp(keynames[i], name) == 0)
+ return i;
+ return -1;
+}
+
+
+int main(int argc, char **argv) {
+ int c, errs = 0, fd, do_set = 0;
+ int left = 0, mid = 0, right = 0, accel = 0, sticky = -1;
+ struct mousedefs mdef;
+
+ while((c = getopt(argc, argv, "l:m:r:a:s:")) != EOF)
+ switch(c) {
+ case 'l':
+ left = nametoscan(optarg);
+ do_set = 1;
+ if(left == -1) goto keynameerr;
+ break;
+
+ case 'm':
+ mid = nametoscan(optarg);
+ do_set = 1;
+ if(mid == -1) goto keynameerr;
+ break;
+
+ case 'r':
+ right = nametoscan(optarg);
+ do_set = 1;
+ if(right == -1) goto keynameerr;
+ break;
+
+ keynameerr:
+ {
+ fprintf(stderr, "unknown key name: %s\n",
+ optarg);
+ errs++;
+ }
+ break;
+
+ case 'a':
+ accel = 1000 * strtol(optarg, 0, 10);
+ do_set = 1;
+ break;
+
+ case 's':
+ if(strcmp(optarg, "0") == 0
+ || strcmp(optarg, "false") == 0
+ || strcmp(optarg, "no") == 0)
+ sticky = 0;
+ else if(strcmp(optarg, "1") == 0
+ || strcmp(optarg, "true") == 0
+ || strcmp(optarg, "yes") == 0)
+ sticky = 1;
+ else {
+ fprintf(stderr, "invalid argument to -s: %s\n",
+ optarg);
+ errs++;
+ }
+ do_set = 1;
+ break;
+
+ default:
+ errs++;
+ }
+
+ argc -= optind;
+ argv += optind;
+
+ if(errs || argc != 1) {
+ fprintf(stderr, "usage: "
+ "mouse [-l key][-m key][-r key][-a acctime][-s 0|1] "
+ "mousedev\n");
+ return 2;
+ }
+
+ if((fd = open(argv[0], O_RDONLY)) < 0) {
+ perror("open(mousedev)");
+ return 2;
+ }
+ if(ioctl(fd, KBDMOUSEGET, &mdef) < 0) {
+ perror("ioctl(KBDMOUSEGET)");
+ return 1;
+ }
+
+ if(!do_set) {
+ printf("Current mouse emulator definitions:\n"
+ "left button: %s\n"
+ "middle button: %s\n"
+ "right button: %s\n"
+ "acceleration limit: %d msec\n"
+ "sticky buttons: %s\n",
+ scantoname(mdef.leftbutton),
+ scantoname(mdef.middlebutton),
+ scantoname(mdef.rightbutton),
+ mdef.acceltime / 1000,
+ mdef.stickybuttons? "yes": "no");
+ return 0;
+ }
+
+ if(left) mdef.leftbutton = left & 0x7f;
+ if(mid) mdef.middlebutton = mid & 0x7f;
+ if(right) mdef.rightbutton = right & 0x7f;
+
+ if(accel) mdef.acceltime = accel;
+ if(sticky != -1) mdef.stickybuttons = sticky;
+
+ if(ioctl(fd, KBDMOUSESET, &mdef) < 0) {
+ perror("ioctl(KBDMOUSESET)");
+ return 1;
+ }
+
+ return 0;
+}
diff --git a/sys/arch/i386/isa/pcvt/Util/pcvtdoc/Makefile b/sys/arch/i386/isa/pcvt/Util/pcvtdoc/Makefile
new file mode 100644
index 00000000000..ee011f04930
--- /dev/null
+++ b/sys/arch/i386/isa/pcvt/Util/pcvtdoc/Makefile
@@ -0,0 +1,4 @@
+MAN4= pcvt.${MAN4EXT}
+MANSUBDIR= /i386
+
+.include <bsd.prog.mk>
diff --git a/sys/arch/i386/isa/pcvt/Util/pcvtdoc/pcvt.4 b/sys/arch/i386/isa/pcvt/Util/pcvtdoc/pcvt.4
new file mode 100644
index 00000000000..d3bef826d6c
--- /dev/null
+++ b/sys/arch/i386/isa/pcvt/Util/pcvtdoc/pcvt.4
@@ -0,0 +1,906 @@
+.\"
+.\" Copyright (c) 1992, 1995 Hellmuth Michaelis, Brian Dunford-Shore,
+.\" Joerg Wunsch and Holger Veit.
+.\"
+.\" All rights reserved.
+.\"
+.\" 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 Hellmuth Michaelis,
+.\" Brian Dunford-Shore, Joerg Wunsch and Holger Veit.
+.\" 4. The name authors may not be used to endorse or promote products
+.\" derived from this software without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``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 AUTHORS 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.
+.\"
+.\" @(#)pcvt.4, 3.30, Last Edit-Date: [Fri Jun 30 20:15:30 1995]
+.\"
+.\" Man page pcvt(4) created after pcvt_ioctl.h on 13-Jan-93
+.\" by Joerg Wunsch
+.\"
+.\" updated for rel 2.10 (-hm)
+.\" updated for rel 2.20 (-hm)
+.\" updated for rel 3.00 (-jw)
+.\" updated for final rel 3.00 (-hm)
+.\" removed references to 386BSD (-hm)
+.\"
+.Dd February 27, 1994
+.Dt PCVT 4
+.Sh NAME
+.Nm pcvt
+.Nd PC console virtual screen system
+.Sh SYNOPSIS
+options
+.Do
+.Em PCVT_FREEBSD = version
+|
+.Em PCVT_NETBSD = version
+.Dc
+.br
+.Op options Dq Em PCVT_NSCREENS = number
+.br
+.Op options Dq Em PCVT_XXXX
+.Po
+see
+.Sx Configuration
+below
+.Pc
+.Pp
+device
+.Em vt0
+at
+.Em isa?
+port
+.Dq Em IO_KBD
+.Em tty
+irq
+.Em 1
+vector
+.Em pcrint
+.Sh DESCRIPTION
+.Ss Overview
+The
+.Nm pcvt
+driver provides a virtual screen system with several additional
+features not available in
+.Xr pc 4
+standard console device driver. Besides the ability of handling
+multiple virtual screens,
+the probably most important is an emulation of a wide range
+of DEC VT-220
+.if t \(tm
+.if n (TM)
+functionality. See
+.Sx Features
+for a detailed description.
+
+.Ss Features
+.Bl -bullet
+.It
+Almost full DEC VT220
+.if t \(tm
+.if n (TM)
+functionality
+.Po
+moving towards VT320
+.if t \(tm
+.if n (TM)
+.Pc
+.It
+Completely independent virtual terminals for MDA/HGC/CGA/EGA and VGA
+.It
+25, 28, 35, 40, 43 or 50x80 screen resolution for each virtual screen
+.It
+Fully remappable keyboard to support national keyboards
+.It
+All VT220 character sets plus ISO Latin-1 and DEC technical supported
+.It
+VT220 downloadable character set supported when run on EGA/VGA
+.It
+VT220 user defined keys for each virtual terminal
+.It
+Optional function key label support
+.if t \('a
+.if n 'a
+la Hewlett-Packard
+.It
+Display function codes functionality
+.It
+Support for MDA, CGA, EGA and VGA display adaptors
+.It
+Support for 132 column operation on VGA chipsets
+.It
+X Window Support for XFree86 >= 1.2 using the pccons model, or
+for XFree86 >= 2.0 using the syscons model
+.Po
+requires
+.Em PCVT_USL_VT_COMPAT
+to be configured
+.Pc
+.El
+
+What it cannot:
+.Bl -bullet
+.It
+No double wide/high characters
+.It
+No softscroll
+.It
+No inverse background
+.It
+No VT220 printer output support
+.It
+No VT52 support at all
+.It
+No 8-bit controls
+.It
+Only limited AT-keyboard
+.Pq 84 keys
+support
+.Pq yet
+.It
+Help you to make money...
+.El
+
+.Ss Configuration
+The
+.Nm pcvt
+console driver is currently available for the Intel-based BSD operating
+systems
+.Em NetBSD/i386 Pq release 0.9 or higher,
+and
+.Em FreeBSD Pq release 1.0-GAMMA or higher .
+In order to get the appropriate system support, one of the options
+.Em PCVT_NETBSD ,
+or
+.Em PCVT_FREEBSD
+must be defined in the system's config file
+.Pq see Xr config 8 .
+In addition, for the
+.Em FreeBSD
+and
+.Em NetBSD
+operating systems, it is necessary to set this option to the operating
+system's version number.
+For
+.Em FreeBSD
+this version number must be expressed as a 3-digit number.
+E.\& g., if you are running the 1.0 release
+.Pq which is actually version 1.0.2 ,
+you should define
+
+.Em PCVT_FREEBSD = 102
+
+For
+.Em NetBSD
+this version number must be expressed as 9 if you are running NetBSD 0.9
+and anything greater than 9 for NetBSD-current (pre 1.0). It is recommended
+to use (as with FreeBSD) 100 for NetBSD 1.0 and 999 for NetBSD-current.
+E.\& g., if you are running the NetBSD 1.0 release, you should define
+
+.Em PCVT_NETBSD = 100
+
+The
+.Nm pcvt
+driver has been designed to be highly configurable in order to satisfy
+everyone's needs. The preferred way for those configurations is to
+provide appropriate
+.Em options
+lines within the config file, possibly overriding the built-in default
+values. Therefore it is possible to compile several distinct kernels
+with different driver behaviour on a single machine.
+
+The following list gives a short overview of the available configuration
+options. Refer to the file
+.Pa i386/isa/pcvt/pcvt_hdr.h
+in the kernel source tree for detailed documentation.
+
+Note: the following conventions apply to all the Boolean options.
+If an option is given with no value, a value of 1
+.Pq activated
+is substituted. If an option value is given as 0, this options is
+deactivated. Any other value is substituted by 1, too. If an option
+is omitted, a built-in default is assumed.
+
+.Bl -tag -width indent -compact
+
+.It Em PCVT_NSCREENS
+Defines the number of virtual screens.
+.br
+Default: 8
+
+.It Em PCVT_VT220KEYB
+If activated, a keyboard layout resembling a DEC VT200 (TM) is generated.
+If deactivated, a mixture between VT220 and HP is used. See the files
+.Pa Keyboard.VT
+and
+.Pa Keyboard.HP
+in the
+.Nm pcvt
+documentation directory for a full description.
+.br
+Default: off
+
+.It Em PCVT_SCREENSAVER
+Enables the builtin screensaver feature.
+.br
+Default: on
+
+.It Em PCVT_PRETTYSCRNS
+If enabled, a blinking-star screensaver is used. If disabled, the screen
+is simply blanked
+.Pq which might be useful for energy-saving monitors .
+.br
+Default: on
+
+.It Em PCVT_CTRL_ALT_DEL
+If enabled, the key combination
+.Aq Em Ctrl
+.Aq Em Alt
+.Aq Em Del
+invokes a CPU reset.
+.br
+Default: off
+
+.It Em PCVT_USEKBDSEC
+Do NOT override a security lock for the keyboard.
+.br
+Default: on
+
+.It Em PCVT_24LINESDEF
+If enabled, the 25-line modi
+.Po
+VT emulation with 25 lines, and HP emulation with 28 lines
+.Pc
+default to 24 lines only to provide a better compatibility to the
+original DEV VT220 (TM). Thus it should be possible to use the
+terminal information for those terminals without further changes.
+Note that this is a startup option; it is possible to toggle between
+the 24- and 25-lines' display by the
+.Xr scon 1
+utility.
+.br
+Default: off
+
+.It Em PCVT_EMU_MOUSE
+Emulate a three-button mouse via the keypad. Useful for notebooks when
+running XFree86. See
+.Sx Mouse emulation
+below.
+.br
+Default: off
+
+.It Em PCVT_META_ESC
+If enabled, a sequence composed of
+.Aq Em esc ,
+followed by the normal key code is emitted if a key is pressed with the
+.Aq Em Alt
+key modifier. If disabled, then normal key code with the value
+.Em 0x80
+added is sent.
+.br
+Default: off
+
+.El
+
+Note that there are further options available which are mainly used for
+debugging purposes or as a workaround for hardware problems. They are
+found in
+.Pa i386/isa/pcvt/pcvt_hdr.h
+along with their documentation.
+
+.Ss Internal Functions
+The functionality described below may be accessed via
+.Xr ioctl 2
+system calls with a file descriptor opened on a device node
+related to the
+.Nm pcvt
+driver.
+To make use of them, a program should contain the following line:
+
+
+.Dl #include <machine/pcvt_ioctl.h>
+
+Any parameter definitions cited below can be found in that file.
+
+
+.Em Keyboard related functions
+
+Three functions are related to basic keyboard hardware:
+
+.Bl -tag -width 20n -offset indent -compact
+.It KBDRESET
+reset keyboard, set defaults;
+.It KBDGTPMAT
+get current typematic value, parameter is a pointer to int where
+the values is stored to;
+.It KBDSTPMAT
+set current typematic value, similar to above command.
+.El
+
+Symbolic values are available for the appropriate constants.
+To specify the initial typematic delay time, they are
+KBD_TPD250 for 250 ms through
+KBD_TPD1000 for 1000 ms, in steps of 250 ms. The typematic repeat
+rates are
+KBD_TPM300, specifying 30.0 characters per second through
+KBD_TPM20 for 2.0 characters per second. The intermediate values
+are: 30.0, 26.7, 24.0, 21.8, 20.0, 18.5, 17.1, 16.0, 15.0, 13.3,
+12.0, 10.9, 10.0, 9.2, 8.6, 8.0, 7.5, 6.7, 6.0, 5.5, 5.0, 4.6, 4.3,
+4.0, 3.7, 3.3, 3.0, 2.7, 2.5, 2.3, 2.1, 2.0 characters per second.
+
+
+.Bl -tag -width 20n -offset indent -compact
+.It KBDGREPSW
+get key repetition switch, and
+.It KBDSREPSW
+set key repetition switch
+.El
+
+again take a pointer to int as argument. They manipulate the
+drivers internal keyboard repetition flag, possible values are:
+KBD_REPEATOFF or KBD_REPEATON.
+
+
+.Bl -tag -width 20n -offset indent -compact
+.It KBDGLEDS
+get LED state, and
+.It KBDSLEDS
+set LED state manipulate the keyboard indicators, but do not influence
+the drivers idea of lock key state.
+.El
+
+The int where the argument points to
+may have the values
+KBD_SCROLLLOCK, KBD_NUMLOCK, KBD_CAPSLOCK, which may be used in any
+conjunction.
+
+.Bl -tag -width 20n -offset indent -compact
+.It KBDGLOCK
+gets state of SCROLL,NUM,CAPS, and
+.It KBDSLOCK
+sets state of SCROLL,NUM,CAPS + LEDs
+.El
+
+should be used in a same manner to get/set the drivers internal
+LED flags.
+
+
+.Em Keyboard remapping
+
+One important feature of the
+.Nm pcvt
+driver is its ability to overload the built in key definition.
+
+.Bl -tag -width 20n -offset indent -compact
+.It KBDGCKEY
+get current key values,
+.It KBDSCKEY
+set new key assignment values, and
+.It KBDGOKEY
+get original key assignment values
+.El
+
+arrange those functions. The take a pointer to a
+.Em struct kbd_ovlkey
+as argument as described below. In addition,
+
+.Bl -tag -width 20n -offset indent -compact
+.It KBDRMKEY
+removes a key assignment, taking a pointer to an int as argument which
+contains the affected key number;
+.It KBDDEFAULT
+removes all key assignments.
+.El
+.Bd -literal
+struct kbd_ovlkey /* complete definition of a key */
+{
+ u_short keynum; /* the key itself */
+ u_short type; /* type of key, see below */
+ u_char subu; /* subtype, ignored on write */
+ char unshift[KBDMAXOVLKEYSIZE+1]; /* emitted string, unshifted */
+ u_char subs; /* subtype, ignored on write */
+ char shift[KBDMAXOVLKEYSIZE+1]; /* emitted string, shifted */
+ u_char subc; /* subtype, ignored on write */
+ char ctrl[KBDMAXOVLKEYSIZE+1]; /* emitted string, control */
+ u_char suba; /* subtype, ignored on write */
+ char altgr[KBDMAXOVLKEYSIZE+1]; /* emitted string, altgr */
+};
+.Ed
+
+The appropriate values for the
+.Em type
+field are:
+
+.Bl -tag -width 20n -offset indent -compact
+.It KBD_NONE
+no function, key is disabled,
+.It KBD_SHIFT
+keyboard shift,
+.It KBD_META
+alternate shift, sets bit8 to ASCII code,
+.It KBD_NUM
+numeric shift, keypad numeric / application mode,
+.It KBD_CTL
+control code generation,
+.It KBD_CAPS
+caps shift - swaps case of letter,
+.It KBD_ASCII
+ASCII code generating key,
+.It KBD_SCROLL
+stop output,
+.It KBD_FUNC
+function key,
+.It KBD_KP
+keypad keys,
+.It KBD_BREAK
+ignored,
+.It KBD_ALTGR
+AltGr translation feature,
+.It KBD_SHFTLOCK
+shift lock,
+.It KBD_CURSOR
+cursor keys, and
+.It KBD_RETURN
+.Dq Return
+or
+.Dq Enter
+keys.
+.El
+
+The
+.Em subtype
+field contains one of the values
+
+.Bl -tag -width 20n -offset indent -compact
+.It KBD_SUBT_STR
+key is bound to a string, or
+.It KBD_SUBT_FNC
+key is bound to a function.
+.El
+
+.Em Mouse emulation
+
+The mouse emulator
+.Pq if configured in
+fakes a three-button mouse using the Mouse Systems protocol. The first
+.Nm pcvt
+device node not used by a virtual screen is the mouse device. I.\& e.,
+for the default value of 8 virtual screens,
+.Pa /dev/ttyv0
+through
+.Pa /dev/ttyv7
+would refer to the virtual screens, and
+.Pa /dev/ttyv8
+were the mouse emulator device. The mouse emulation is turned on by
+pressing the
+.Aq Em NumLock
+key. The pointer is moved by the numerical keypad keys, into the
+obvious directions. The pointer is initially moved in single steps,
+and is accelerated after an adjustable time
+.Pq default: 500 ms
+by about 6 times. The mouse buttons are emulated by three normal
+keys, by default the function keys
+.Aq Em \&F1 ,
+.Aq Em \&F2 ,
+and
+.Aq Em \&F3 .
+There are two selectable flavors available: normal and
+.Dq sticky
+buttons. Normal buttons behave as expected.
+.Dq Sticky
+buttons are notified as button-press on the first keypress. They
+.Dq stick
+until the key is pressed again
+.Pq or another button-emulating key instead .
+Button presses and releases are notified to the user by a simple
+.Dq pling ,
+or
+.Dq plong ,
+respectively, generated from the PC's built-in speaker.
+
+The following commands control the emulation.
+
+.Bl -tag -width 20n -offset indent -compact
+.It KBDMOUSEGET
+get the current definitions, and
+.It KBDMOUSESET
+set new definitions.
+.El
+
+Both accept a
+.Li struct mousedefs *
+as the third argument to the ioctl call:
+.Bd -literal
+struct mousedefs {
+ int leftbutton; /* (PC) scan code for "left button" key */
+ int middlebutton; /* (PC) scan code for "mid button" key */
+ int rightbutton; /* (PC) scan code for "right button" key */
+ int stickybuttons; /* if true, the buttons are "sticky" */
+ int acceltime; /* timeout in microseconds to start pointer */
+ /* movement acceleration */
+ /* defaults to: scan(F1), scan(F2), scan(F3), false, 500000 */
+};
+.Ed
+
+
+.Em Downloadable character set interface
+
+EGA and VGA video adaptors provide the capability of downloadable
+software fonts. Since the
+.Sq native character set
+of any IBM-compatible PC video board does not allow the full interpretation
+of DEC multinational character set or ISO Latin-1
+.Pq ISO 8859-1 ,
+this might be very useful for a U**X environment.
+
+.Bl -tag -width 20n -offset indent -compact
+.It VGASETFONTATTR
+set font attr, and
+.It VGAGETFONTATTR
+get font attr
+.El
+
+are used to manipulate the drivers information about a downloaded
+font. The take a pointer to a
+.Em struct vgafontattr
+as argument:
+.Bd -literal
+struct vgafontattr {
+ int character_set; /* VGA character set */
+ int font_loaded; /* Mark font loaded or unloaded */
+ int screen_size; /* Character rows per screen */
+ int character_scanlines; /* Scanlines per character - 1 */
+ int screen_scanlines; /* Scanlines per screen - 1 byte */
+};
+.Ed
+
+Each character of each font is to be downloaded with
+
+.Bl -tag -width 20n -offset indent -compact
+.It VGALOADCHAR
+load vga char,
+.El
+
+taking a pointer to
+.Em struct vgaloadchar
+as its argument:
+.Bd -literal
+struct vgaloadchar {
+ int character_set; /* VGA character set to load into */
+ int character; /* Character to load */
+ int character_scanlines; /* Scanlines per character */
+ u_char char_table[32]; /* VGA character shape table */
+};
+.Ed
+
+The field
+.Em character_set
+takes the values
+CH_SET0, CH_SET1, CH_SET2, CH_SET3 on EGA's or VGA's. Since VGA's
+might have up to eight simultaneously loaded fonts, they can take
+CH_SET4, CH_SET5, CH_SET6, or CH_SET7, too.
+
+Note that there's a dependence between the font size
+and a possible screen height
+.Pq in character rows ,
+depending on the video adaptor used:
+.Bd -literal
+Screen size (rows) on: EGA VGA
+Font size
+
+8 x 8 43 50
+8 x 10 35 40
+8 x 14 25 28
+8 x 16 not 25
+ applicable
+.Ed
+
+
+.Em General screen manipulation commands
+
+.Bl -tag -width 20n -offset indent -compact
+.It VGACURSOR
+sets cursor shape,
+.El
+
+taking a pointer to the following structure as argument:
+.Bd -literal
+struct cursorshape {
+ int screen_no; /* screen number for which to set, */
+ /* or -1 to set on current active screen */
+ int start; /* top scanline, range 0... Character Height - 1 */
+ int end; /* end scanline, range 0... Character Height - 1 */
+};
+.Ed
+
+.Bl -tag -width 20n -offset indent -compact
+.It VGASETSCREEN
+set screen info, and
+.It VGAGETSCREEN
+get screen info,
+.El
+
+provide an interface to some general driver internal variables
+which might modify the behaviour of the screens,
+or which might simply be used to force the driver to switch
+to one certain screen. Their argument is a pointer to the structure:
+.Bd -literal
+struct screeninfo {
+ int adaptor_type; /* type of video adaptor installed */
+ /* read only, ignored on write (yet!) */
+ int totalfonts; /* no of downloadable fonts */
+ /* read only, ignored on write */
+ int totalscreens; /* no of virtual screens */
+ /* read only, ignored on write */
+ int screen_no; /* screen number, this was got from */
+ /* on write, if -1, apply pure_vt_mode */
+ /* and/or screen_size to current screen*/
+ /* else to screen_no supplied */
+ int current_screen; /* screen number, which is displayed. */
+ /* on write, if -1, make this screen */
+ /* the current screen, else set current*/
+ /* displayed screen to parameter */
+ int pure_vt_mode; /* flag, pure VT mode or HP/VT mode */
+ /* on write, if -1, no change */
+ int screen_size; /* screen size */
+ /* on write, if -1, no change */
+ int force_24lines; /* force 24 lines if 25 lines VT mode */
+ /* or 28 lines HP mode to get pure */
+ /* VT220 screen size */
+ /* on write, if -1, no change */
+ int vga_family; /* if adaptor_type = VGA, this reflects*/
+ /* the chipset family after a read */
+ /* nothing happenes on write ... */
+ int vga_type; /* if adaptor_type = VGA, this reflects*/
+ /* the chipset after a read */
+ /* nothing happenes on write ... */
+ int vga_132; /* set to 1 if driver has support for */
+ /* 132 column operation for chipset */
+ /* currently ignored on write */
+};
+.Ed
+
+Its field
+.Em pure_vt_mode
+may take the values M_HPVT for a mixed VTxxx and HP Mode, with function
+key labels and a status line, or M_PUREVT for only VTxxx sequences
+recognized, with no labels.
+
+.Bl -tag -width 20n -offset indent -compact
+.It VGASETCOLMS
+sets the number of columns for the current screen,
+.El
+
+its parameter is a pointer to an integer containing either a value of 80,
+or a value of 132. Note that setting the number of columns to 132 is
+only supported on VGA adaptors. Any unsupported numbers cause the ioctl
+to fail with
+.Em errno
+.Pq see Xr intro 2
+being set to
+.Em EINVAL .
+
+.Em VGA color palette interface
+
+Only on VGA adaptors, there's a color palette register at the output.
+It is responsible for the red, green and blue output voltage provided
+for each of the 256 internal color codes, each lying in the range of
+0 through 63 (with 63 representing the brightest value for a base color).
+Thus, these adaptors map each color code to a color of a
+.Dq palette
+out of 262144 colors. The commands
+
+.Bl -tag -width 20n -offset indent -compact
+.It VGAREADPEL
+read VGA palette entry, and
+.It VGAWRITEPEL
+write VGA palette entry
+.El
+
+establish an interface to these palette registers. Their argument is
+a pointer to:
+.Bd -literal
+struct vgapel {
+ unsigned idx; /* index into palette, 0 .. 255 valid */
+ unsigned r, g, b; /* RGB values, masked by VGA_PMASK (63) */
+};
+.Ed
+
+
+.Em Driver identification
+
+.Bl -tag -width 20n -offset indent -compact
+.It VGAPCVTID
+returns information if the current compiled in driver is pcvt and it's
+major and minor revision numbers. the call is taking a pointer to the
+following structure as argument:
+.El
+
+.Bd -literal
+struct pcvtid {
+#define PCVTIDNAMELN 16 /* driver id - string length */
+ char name[PCVTIDNAMELN]; /* driver name, == PCVTIDSTR */
+#define PCVTIDNAME "pcvt" /* driver id - string */
+ int rmajor; /* revision number, major */
+#define PCVTIDMAJOR 3
+ int rminor; /* revision number, minor */
+#define PCVTIDMINOR 00
+};
+.Ed
+
+
+.Bl -tag -width 20n -offset indent -compact
+.It VGAPCVTINFO
+returns information if the current compiled in driver is pcvt and it's
+compile time options. the call is taking a pointer to the following
+structure as argument:
+.El
+
+.Bd -literal
+struct pcvtinfo {
+ u_int opsys; /* PCVT_xxx(x)BSD */
+#define CONF_UNKNOWNOPSYS 0
+#define CONF_386BSD 1 /* unsupported !!! */
+#define CONF_NETBSD 2
+#define CONF_FREEBSD 3
+ u_int opsysrel; /* Release for NetBSD/FreeBSD */
+ u_int nscreens; /* PCVT_NSCREENS */
+ u_int scanset; /* PCVT_SCANSET */
+ u_int updatefast; /* PCVT_UPDATEFAST */
+ u_int updateslow; /* PCVT_UPDATESLOW */
+ u_int sysbeepf; /* PCVT_SYSBEEPF */
+
+/* config booleans */
+
+ u_long compile_opts; /* PCVT_xxxxxxxxxxxxxxx */
+};
+.Ed
+
+
+.Em Screen saver
+
+Depending on the configuration of a
+.Nm pcvt
+driver, their might be a simple screen saver available. It is controlled
+by the command
+
+.Bl -tag -width 20n -offset indent -compact
+.It VGASCREENSAVER
+set timeout for screen saver in seconds; 0 turns it off,
+.El
+
+taking a pointer to an integer as argument. Despite of its command name,
+this is available on
+.Em any
+kind of adaptor if configured in by the
+.Xr config 8
+option
+.Dq PCVT_SCREENSAVER
+
+.Em Compatibility commands for USL-style VT's
+
+Release 3.00 of this
+.Nm pcvt
+driver supports a subset of the USL-style commands used to control
+the virtual terminal interface. This feature is mainly intended to
+allow
+.Em XFree86 ,
+release 2.0 or higher, to switch between virtual screens even when
+running an X server. They are ugly with respect to the implied semantics
+.Pq i.\& e., they break Berkeley semantics
+and are therefore not recommended for common use. See the file
+.Pa i386/include/pcvt_ioctl.h
+for their documentation.
+
+.Sh FILES
+.Bl -tag -width /usr/include/machine/pcvt_ioctl.h
+.It Pa /usr/include/machine/pcvt_ioctl.h
+Definitions for
+.Xr ioctl 2
+function calls
+.It Pa /dev/ttyv?
+.It Pa /dev/console
+Device nodes to access the
+.Nm pcvt
+driver
+.It Pa i386/isa/pcvt/pcvt_hdr.h
+.Pq relative to the kernel source tree
+Documents the various compile-time options to tailor
+.Nm pcvt .
+.Sh HISTORY
+The
+.Nm pcvt
+driver has been developed for and contributed to 386BSD release 0.1. Since
+release 3.00 explicit support is provided for NetBSD 0.9. It is expected
+that no further development on pcvt is done for 386BSD 0.1 after release 3.00,
+in fact, 386BSD support was dropped with release 3.20.
+.Sh AUTHORS
+.Bl -tag -width 30n -offset indent
+.It Written by :
+Hellmuth Michaelis
+.Pq hm@hcshh.hcs.de
+.It With much help from :
+Brian Dunford-Shore
+.Pq brian@morpheus.wustl.edu
+.br
+.if n Joerg Wunsch
+.if t J\(:org Wunsch
+.Pq joerg_wunsch@uriah.sax.de
+.br
+.It This driver is based on several people's previous
+.It work, notably by :
+William Jolitz' and Don Ahn's
+.Xr pc 4
+implementation
+.Pq ljolitz@cardio.ucsf.edu
+.br
+Holger Veit
+.Pq veit@du9ds3.uni-duisburg.de, now veit@first.gmd.de
+.Sh SEE ALSO
+.Xr pc 4 ,
+.Xr config 8 ,
+.Xr intro 2 ,
+.Xr ioctl 2 .
+.Sh BUGS
+Certainly existent. See the file
+.Pa BugList
+in the Documentation directory for an up-to-date list.
+
+.Ss Tested Video Boards
+.Bd -literal
+Manufacturer Chipset Monitor
+
+2theMax (?) ET4000 VGA Color
+Video7 Inc. Video 7 VGA Color
+Diamond Stealth VRAM S3 NEC 3FGx
+Trident TVGA 8800CS NEC 3D
+Data General C&T P82C604 VGA Color
+NoName Hercules W86855AF Mono
+Kyocera (Mainboard) WD90C11 Sony Color
+unknown ET3000 NEC 3D
+.Ed
+
+.Ss Tested Keyboards
+.Bd -literal
+Manufacturer Type Layout
+
+Cherry MF II US
+Cherry/Tandon MF II German
+Hewlett-Packard MF II US
+Hewlett-Packard MF II German
+Tatung AT German
+.Ed
+
+There is absolutely NO support for the ancient PC-keyboards
+.Pq they had 83 keys .
+
+There is only limited support for AT-keyboards
+.Bo
+they have 84 keys, and a separate numeric keypad,
+they don't have F11/F12 keys
+.Bc
+because the emulator needs F9 through F12 for control functions, and due to
+the current design of the keyboard driver there is no
+.Pq full
+support for national keyboards because
+of the lack of an ALtGr key.
+
+MF-keyboards are fully supported, 101- and 102-key versions.
diff --git a/sys/arch/i386/isa/pcvt/Util/scon/Makefile b/sys/arch/i386/isa/pcvt/Util/scon/Makefile
new file mode 100644
index 00000000000..6fdb94eb650
--- /dev/null
+++ b/sys/arch/i386/isa/pcvt/Util/scon/Makefile
@@ -0,0 +1,3 @@
+PROG= scon
+
+.include <bsd.prog.mk>
diff --git a/sys/arch/i386/isa/pcvt/Util/scon/scon.1 b/sys/arch/i386/isa/pcvt/Util/scon/scon.1
new file mode 100644
index 00000000000..d99802b2975
--- /dev/null
+++ b/sys/arch/i386/isa/pcvt/Util/scon/scon.1
@@ -0,0 +1,214 @@
+.\" Copyright (c) 1992, 1995 Hellmuth Michaelis and Joerg Wunsch
+.\"
+.\" All rights reserved.
+.\"
+.\" 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
+.\" Hellmuth Michaelis and Joerg Wunsch
+.\" 4. The name authors may not be used to endorse or promote products
+.\" derived from this software without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``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 AUTHORS 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.
+.\"
+.\" @(#)scon.1, 3.30, Last Edit-Date: [Mon Jul 3 11:25:13 1995]
+.\"
+.Dd December 31, 1993
+.Dt SCON 1
+.Sh NAME
+.Nm scon
+.Nd controls screen modes for pcvt video driver
+.Sh SYNOPSIS
+.Nm scon
+.Op Fl a
+.Op Fl c Ar screenno
+.Op Fl d Ar device
+.Op Fl f Ar on|off
+.Op Fl h
+.Op Fl H
+.Op Fl l
+.Op Fl m
+.Op Fl v
+.Op Fl V
+.Op Fl s Ar lines
+.br
+.Nm scon
+.Op Fl v
+.Op Fl d Ar device
+.Fl p Ar entry,red,green,blue
+.br
+.Nm scon
+.Op Fl v
+.Op Fl d Ar device
+.Fl p Ar default
+.br
+.Nm scon
+.Op Fl v
+.Op Fl d Ar device
+.Fl p Ar list
+.Nm scon
+.Op Fl v
+.Fl t Ar timeout
+.Nm scon
+.Op Fl v
+.Fl 1 | Fl 8
+.Sh DESCRIPTION
+The
+.Nm scon
+utility controls several aspects of the runtime behaviour of the pcvt vt220
+driver.
+.Pp
+The options are as follows:
+.Bl -tag -width Ds
+.It Fl a
+Returns a string describing the video adaptor found by pcvt, the string
+returned could be MDA, HGC, CGA, EGA, VGA or UNKNOWN.
+.It Fl c
+Specify the screen number the current (displayed) screen should be switched
+to.
+.It Fl d
+Specify the device filename (i.e. /dev/ttyv2) further operations specified on
+the command line should be applied to.
+.It Fl f
+Some programs which silently assume 24 lines when they run on a VT220 show
+incorrect behaviour when the terminal has really 25 lines. To support full
+VT220 behaviour, it is possible to force pcvt to select only 24 lines when
+it is running in 25-lines pure VT mode and/or in 28-lines HP-mode. The
+.Fl f
+option requires one additional parameter, the string 'on' or 'off' to switch
+this mode for a virtual screen on or off respectively. This mode has no effect
+if any other vertical resolutions are selected than the two above mentioned.
+.It Fl h
+Prints a usage/help text.
+.It Fl l
+Lists the current configuration of runtime changeable options and fixed
+parameters (such as the type of the adaptor, and in case of a VGA adaptor,
+the Manufacturer, Chipset and 132 column support) of the output portion
+of the pcvt driver.
+.It Fl m
+Returns a string describing the connected display monitor type found by pcvt,
+the string returned can be MONO, COLOR or UNKNOWN.
+.It Fl v
+Specify verbose operation of the program.
+.It Fl V
+Switch the specified/current screen into a pure VT220 mode without recognizing
+any HP escape sequences and without displaying function key labels.
+.It Fl H
+Switch the specified/current screen into a mixed HP/VT220 mode. That is, that
+in addition to the full VT220 emulation, the HP function key labels and the
+escape sequences for handling the labels are available to the user.
+.It Fl s
+Specify the number of character lines on the screen. Possible parameters are
+25, 28, 35, 40, 43 or 50. To use all this screen sizes, the fonts required
+for proper operation of a desired size have to be downloaded to the EGA/VGA
+font ram. This option is available only for EGA and VGA boards.
+.It Fl p
+Modify VGA palette
+.Pq DAC .
+The
+.Fl p
+is mutually exclusive with
+.Fl s ,
+.Fl H ,
+and
+.Fl V .
+Naturally, option
+.Fl p
+is available only for VGA boards. Three flavors are available.
+
+If used with argument
+.Dq Ar default ,
+this flag will restore the default palette
+.Po
+as installed by VGA ROM BIOS after hardware reset
+.Pc .
+
+If used with argument
+.Dq Ar list ,
+the current VGA DAC palette entries are listed. Each entry contains
+the table index, values for red, green, and blue, and if there's a
+known name for this entry, the color name. Trailing empty table
+slots (RGB values all zero) are omitted.
+
+Otherwise, four comma-separated arguments are expected. The first
+denotes the number of palette entry to be modified. This may be either
+a number between 0 and 255, or the usual name of an associated color
+.Pq case-insensitive .
+The following values for red, green and blue are restricted to 0 through 63
+due to VGA DAC conventions.
+Note that the first delimiter within such an argument may be a colon
+.Dq \&:
+instead of a comma
+.Dq \&,
+for better readability, but this violates common command argument
+conventions.
+Multiple
+.Fl p
+options may be specified if unambiguous.
+.It Fl t
+Specifying
+.Fl t
+will activate the screen saver. The behaviour depends on
+.Ar timeout :
+if
+.Ar timeout
+is given as 0, the screen saver is turned off. Otherwise,
+.Ar timeout
+is taken as a number of seconds to wait until activating the
+screen saver.
+NOTE: the
+.Fl t
+option is only available if screen saver support has been compiled into
+the driver !
+.It Fl 1
+Sets 132 columns mode
+.Pq only available on VGA adaptors .
+.It Fl 8
+Sets 80 columns mode.
+.El
+.Pp
+When switching between HP and VT mode, when switching the force 24 lines
+mode on and off, or when switching between 80 and 132 columns operation,
+the screen is cleared, the scrolling
+region is reset and the cursor is placed in the home position.
+.Sh EXAMPLES
+The command
+.Dq Li scon Fl H s Ar 28
+places the current screen into HP mode and sets the screen size to 28x80.
+
+Invoking
+.Do
+.Li scon Fl p
+.Ar lightgray,0,15,0
+.Fl p
+.Ar 0:45,45,45
+.Dc
+will result in green on gray output for normal text.
+Note that normal text color is light gray, and not white as one might expect.
+.Sh BUGS
+the
+.Fl c
+and
+.Fl d
+options collide somehow, this will change in a future release.
+.Sh SEE ALSO
+.Xr loadfont 1 ,
+.Xr cursor 1 ,
+.Xr pcvt 4
diff --git a/sys/arch/i386/isa/pcvt/Util/scon/scon.c b/sys/arch/i386/isa/pcvt/Util/scon/scon.c
new file mode 100644
index 00000000000..0c512ab4cd3
--- /dev/null
+++ b/sys/arch/i386/isa/pcvt/Util/scon/scon.c
@@ -0,0 +1,860 @@
+/*
+ * Copyright (c) 1992, 1995 Hellmuth Michaelis and Joerg Wunsch
+ *
+ * All rights reserved.
+ *
+ * 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
+ * Hellmuth Michaelis and Joerg Wunsch
+ * 4. The name authors may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``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 AUTHORS 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.
+ *
+ */
+
+static char *id =
+ "@(#)scon.c, 3.30, Last Edit-Date: [Wed Aug 30 13:57:10 1995]";
+
+/*---------------------------------------------------------------------------*
+ *
+ * history:
+ *
+ * -hm moving fd for default device from 1 -> 0 for such things
+ * as "scon -p list | more" to be possible
+ * (reported by Gordon L. Burditt, gordon@sneaky.lonestar.org)
+ * -hm adding option "a" for just returning the type of video adaptor
+ * -hm removing explicit HGC support, same as MDA ...
+ * -hm vga type/family/132col support info on -l
+ * -hm force 24 lines in DEC 25 lines mode and HP 28 lines mode
+ * -hm fixed bug with 132 column mode display status display
+ * -jw added 132/80 col mode switching
+ * -hm removed -h flag, use -? now ... ;-)
+ * -hm S3 chipsets ..
+ * -hm Cirrus chipsets support from Onno van der Linden
+ * -hm -m option, display monitor type
+ * -hm bugfix, scon -c <screen-num> cleared dest screen, fixed
+ * -hm patch to support Cirrus CL-GD62x5 from Martin
+ *
+ *---------------------------------------------------------------------------*/
+
+#include <stdio.h>
+#include <fcntl.h>
+#include <machine/pcvt_ioctl.h>
+
+#define DEFAULTFD 0
+
+int aflag = -1;
+int lflag = -1;
+int mflag = -1;
+int current = -1;
+int pflag = -1;
+int hflag = -1;
+int res = -1;
+char *device;
+int dflag = -1;
+int vflag = 0;
+int Pflag = 0;
+int tflag = 0;
+int fflag = -1;
+int colms = 0;
+char *onoff;
+
+unsigned timeout;
+struct screeninfo screeninfo;
+
+#define NVGAPEL 256
+
+struct rgb {
+ unsigned r, g, b;
+ int dothis;
+};
+
+static struct rgb palette[NVGAPEL] = {
+ { 0x00, 0x00, 0x00, 0}, /* 0 - black */
+ { 0x00, 0x00, 0x2a, 0}, /* 1 - blue */
+ { 0x00, 0x2a, 0x00, 0}, /* 2 - green */
+ { 0x00, 0x2a, 0x2a, 0}, /* 3 - cyan */
+ { 0x2a, 0x00, 0x00, 0}, /* 4 - red */
+ { 0x2a, 0x00, 0x2a, 0}, /* 5 - magenta */
+ { 0x2a, 0x2a, 0x00, 0}, /* 6 */
+ { 0x2a, 0x2a, 0x2a, 0}, /* 7 - lightgray */
+ { 0x00, 0x00, 0x15, 0}, /* 8 */
+ { 0x00, 0x00, 0x3f, 0}, /* 9 */
+ { 0x00, 0x2a, 0x15, 0}, /* 10 */
+ { 0x00, 0x2a, 0x3f, 0}, /* 11 */
+ { 0x2a, 0x00, 0x15, 0}, /* 12 */
+ { 0x2a, 0x00, 0x3f, 0}, /* 13 */
+ { 0x2a, 0x2a, 0x15, 0}, /* 14 */
+ { 0x2a, 0x2a, 0x3f, 0}, /* 15 */
+ { 0x00, 0x15, 0x00, 0}, /* 16 */
+ { 0x00, 0x15, 0x2a, 0}, /* 17 */
+ { 0x00, 0x3f, 0x00, 0}, /* 18 */
+ { 0x00, 0x3f, 0x2a, 0}, /* 19 */
+ { 0x2a, 0x15, 0x00, 0}, /* 20 - brown */
+ { 0x2a, 0x15, 0x2a, 0}, /* 21 */
+ { 0x2a, 0x3f, 0x00, 0}, /* 22 */
+ { 0x2a, 0x3f, 0x2a, 0}, /* 23 */
+ { 0x00, 0x15, 0x15, 0}, /* 24 */
+ { 0x00, 0x15, 0x3f, 0}, /* 25 */
+ { 0x00, 0x3f, 0x15, 0}, /* 26 */
+ { 0x00, 0x3f, 0x3f, 0}, /* 27 */
+ { 0x2a, 0x15, 0x15, 0}, /* 28 */
+ { 0x2a, 0x15, 0x3f, 0}, /* 29 */
+ { 0x2a, 0x3f, 0x15, 0}, /* 30 */
+ { 0x2a, 0x3f, 0x3f, 0}, /* 31 */
+ { 0x15, 0x00, 0x00, 0}, /* 32 */
+ { 0x15, 0x00, 0x2a, 0}, /* 33 */
+ { 0x15, 0x2a, 0x00, 0}, /* 34 */
+ { 0x15, 0x2a, 0x2a, 0}, /* 35 */
+ { 0x3f, 0x00, 0x00, 0}, /* 36 */
+ { 0x3f, 0x00, 0x2a, 0}, /* 37 */
+ { 0x3f, 0x2a, 0x00, 0}, /* 38 */
+ { 0x3f, 0x2a, 0x2a, 0}, /* 39 */
+ { 0x15, 0x00, 0x15, 0}, /* 40 */
+ { 0x15, 0x00, 0x3f, 0}, /* 41 */
+ { 0x15, 0x2a, 0x15, 0}, /* 42 */
+ { 0x15, 0x2a, 0x3f, 0}, /* 43 */
+ { 0x3f, 0x00, 0x15, 0}, /* 44 */
+ { 0x3f, 0x00, 0x3f, 0}, /* 45 */
+ { 0x3f, 0x2a, 0x15, 0}, /* 46 */
+ { 0x3f, 0x2a, 0x3f, 0}, /* 47 */
+ { 0x15, 0x15, 0x00, 0}, /* 48 */
+ { 0x15, 0x15, 0x2a, 0}, /* 49 */
+ { 0x15, 0x3f, 0x00, 0}, /* 50 */
+ { 0x15, 0x3f, 0x2a, 0}, /* 51 */
+ { 0x3f, 0x15, 0x00, 0}, /* 52 */
+ { 0x3f, 0x15, 0x2a, 0}, /* 53 */
+ { 0x3f, 0x3f, 0x00, 0}, /* 54 */
+ { 0x3f, 0x3f, 0x2a, 0}, /* 55 */
+ { 0x15, 0x15, 0x15, 0}, /* 56 - darkgray */
+ { 0x15, 0x15, 0x3f, 0}, /* 57 - lightblue */
+ { 0x15, 0x3f, 0x15, 0}, /* 58 - lightgreen */
+ { 0x15, 0x3f, 0x3f, 0}, /* 59 - lightcyan */
+ { 0x3f, 0x15, 0x15, 0}, /* 60 - lightred */
+ { 0x3f, 0x15, 0x3f, 0}, /* 61 - lightmagenta */
+ { 0x3f, 0x3f, 0x15, 0}, /* 62 - yellow */
+ { 0x3f, 0x3f, 0x3f, 0}, /* 63 - white */
+ { 0x00, 0x00, 0x00, 0} /* 64 ... - empty */
+};
+
+static struct colname {
+ const char *name;
+ unsigned idx;
+} colnames[] = {
+ {"black", 0},
+ {"blue", 1},
+ {"green", 2},
+ {"cyan", 3},
+ {"red", 4},
+ {"magenta", 5},
+ {"brown", 20},
+ {"lightgray", 7},
+ {"lightgrey", 7},
+ {"darkgray", 56},
+ {"darkgrey", 56},
+ {"lightblue", 57},
+ {"lightgreen", 58},
+ {"lightcyan", 59},
+ {"lightred", 60},
+ {"lightmagenta", 61},
+ {"yellow", 62},
+ {"white", 63},
+ /* must be terminator: */ {(const char *)NULL, 0}
+};
+
+
+static void parsepopt(char *arg, unsigned *idx,
+ unsigned *r, unsigned *g, unsigned *b);
+static void printpalette(int fd);
+
+main(argc,argv)
+int argc;
+char *argv[];
+{
+ extern int optind;
+ extern int opterr;
+ extern char *optarg;
+
+ int c;
+ int fd;
+
+ while( (c = getopt(argc, argv, "ac:d:f:HVlms:t:vp:18")) != EOF)
+ {
+ switch(c)
+ {
+ case 'a':
+ aflag = 1;
+ break;
+
+ case 'l':
+ lflag = 1;
+ break;
+
+ case 'm':
+ mflag = 1;
+ break;
+
+ case 'c':
+ current = atoi(optarg);
+ break;
+
+ case 'd':
+ device = optarg;
+ dflag = 1;
+ break;
+
+ case 'f':
+ onoff = optarg;
+ fflag = 1;
+ break;
+
+ case 'V':
+ pflag = 1;
+ break;
+
+ case 'H':
+ hflag = 1;
+ break;
+
+ case 's':
+ if (!strncmp(optarg, "25", 2))
+ res = SIZ_25ROWS;
+ else if(!strncmp(optarg, "28", 2))
+ res = SIZ_28ROWS;
+ else if(!strncmp(optarg, "35", 2))
+ res = SIZ_35ROWS;
+ else if(!strncmp(optarg, "40", 2))
+ res = SIZ_40ROWS;
+ else if(!strncmp(optarg, "43", 2))
+ res = SIZ_43ROWS;
+ else if(!strncmp(optarg, "50", 2))
+ res = SIZ_50ROWS;
+ break;
+
+ case 'v':
+ vflag++;
+ break;
+
+ case 'p':
+ if(!strcmp(optarg, "list"))
+ {
+ if(Pflag)
+ {
+ fprintf(stderr,
+ "-p list is mutual exclusive "
+ "with other -p options\n");
+ return 2;
+ }
+ Pflag = 3;
+ }
+ else if(!strcmp(optarg, "default"))
+ {
+ if(Pflag)
+ {
+ fprintf(stderr,
+ "multiple -p default not "
+ "allowed\n");
+ return 2;
+ }
+ Pflag = 2;
+ } else {
+ unsigned idx, r, g, b;
+
+ if(Pflag > 1)
+ {
+ fprintf(stderr,
+ "-p default and -p i,r,g,b "
+ "ambiguous\n");
+ return 2;
+ }
+ Pflag = 1;
+ parsepopt(optarg, &idx, &r, &g, &b);
+ if(idx >= NVGAPEL)
+ {
+ fprintf(stderr,
+ "index %u in -p option "
+ "out of range\n", idx);
+ return 2;
+ }
+ palette[idx].r = r;
+ palette[idx].g = g;
+ palette[idx].b = b;
+ palette[idx].dothis = 1;
+ }
+ break;
+
+ case 't':
+ tflag++;
+ timeout = atoi(optarg);
+ break;
+
+ case '1':
+ colms = 132;
+ break;
+
+ case '8':
+ colms = 80;
+ break;
+
+ case '?':
+ default:
+ usage();
+ break;
+ }
+ }
+
+ if((pflag == 1) && (hflag == 1))
+ usage();
+
+ if(dflag == -1 && lflag == -1 && current == -1 && pflag == -1 &&
+ hflag == -1 && res == -1 && Pflag == 0 && tflag == 0 && fflag == -1
+ && colms == 0 && mflag == -1)
+ {
+ lflag = 1;
+ }
+
+ if(dflag == -1)
+ {
+ if(vflag)
+ printf("using current device\n");
+ fd = DEFAULTFD; /* -hm, Feb 12 1993 */
+ }
+ else
+ {
+ if((fd = open(device, O_RDWR)) == -1)
+ {
+ char buffer[80];
+ strcpy(buffer,"ERROR opening ");
+ strcat(buffer,device);
+ perror(buffer);
+ exit(1);
+ }
+ if(vflag)
+ printf("using device %s\n",device);
+ }
+
+ if(aflag == 1) /* return adaptor type */
+ {
+ printadaptor(fd);
+ exit(0);
+ }
+
+ if(mflag == 1) /* return monitor type */
+ {
+ printmonitor(fd);
+ exit(0);
+ }
+
+ if(lflag == 1) /* list information */
+ {
+ if(vflag)
+ printf("processing option -l, listing screen info\n");
+ printinfo(fd);
+ exit(0);
+ }
+
+ if(tflag) /* set screen saver timeout */
+ {
+ if(vflag)
+ {
+ printf(
+ "processing option -t, setting screen saver timeout: "
+ );
+ if(timeout)
+ printf("new timeout = %d s\n", timeout);
+ else
+ printf("turned off\n");
+ }
+
+ if(ioctl(fd, VGASCREENSAVER, &timeout) < 0)
+ {
+ perror("ioctl(VGASCREENSAVER)");
+ fprintf(stderr, "Check the driver, the screensaver is probably not compiled in!\n");
+ exit(2);
+ }
+ goto success;
+ }
+
+ if(colms)
+ {
+ if(vflag)
+ printf("Setting number of columns to %d\n", colms);
+ if(ioctl(fd, VGASETCOLMS, &colms) < 0)
+ {
+ perror("ioctl(VGASETCOLMS)");
+ exit(2);
+ }
+ goto success;
+ }
+
+ if(Pflag == 3)
+ {
+ /* listing VGA palette */
+ if(vflag)
+ printf("processing option -p list, "
+ "listing VGA palette\n");
+
+ printpalette(fd);
+ goto success;
+ }
+
+ if(Pflag)
+ {
+ unsigned int idx;
+
+ /* setting VGA palette */
+ if(vflag)
+ printf("processing option -p, setting VGA palette%s\n",
+ Pflag == 2? " to default": "");
+
+ for(idx = 0; idx < NVGAPEL; idx++)
+ if(Pflag == 2 || palette[idx].dothis)
+ {
+ struct vgapel p;
+ p.idx = idx;
+ p.r = palette[idx].r;
+ p.g = palette[idx].g;
+ p.b = palette[idx].b;
+ if(ioctl(fd, VGAWRITEPEL, (caddr_t)&p) < 0)
+ {
+ perror("ioctl(fd, VGAWRITEPEL)");
+ return 2;
+ }
+ }
+ goto success;
+ }
+
+ screeninfo.screen_no = -1; /* We are using fd */
+ screeninfo.current_screen = current;
+ screeninfo.pure_vt_mode = -1;
+ screeninfo.screen_size = res;
+ screeninfo.force_24lines = -1;
+
+ if(current != -1) /* set current screen */
+ {
+ if(vflag)
+ printf("processing option -c, setting current screen to %d\n",current);
+
+ if(ioctl(1, VGASETSCREEN, &screeninfo) == -1)
+ {
+ perror("ioctl VGASETSCREEN failed");
+ exit(1);
+ }
+ exit(0);
+ }
+
+ if(pflag == 1)
+ {
+ if(vflag)
+ printf("processing option -V, setting emulation to pure VT220\n");
+ screeninfo.pure_vt_mode = M_PUREVT;
+ }
+ else if(hflag == 1)
+ {
+ if(vflag)
+ printf("processing option -H, setting emulation to VT220 + HP Labels\n");
+ screeninfo.pure_vt_mode = M_HPVT;
+ }
+ else
+ {
+ if(vflag)
+ printf("no change in terminal emulation\n");
+ }
+
+ if(vflag)
+ {
+ if(res == -1)
+ printf("no change in screen resolution\n");
+ else if(res == SIZ_25ROWS)
+ printf("change screen resolution to 25 lines\n");
+ else if(res == SIZ_28ROWS)
+ printf("change screen resolution to 28 lines\n");
+ else if(res == SIZ_35ROWS)
+ printf("change screen resolution to 35 lines\n");
+ else if(res == SIZ_40ROWS)
+ printf("change screen resolution to 40 lines\n");
+ else if(res == SIZ_43ROWS)
+ printf("change screen resolution to 43 lines\n");
+ else if(res == SIZ_50ROWS)
+ printf("change screen resolution to 50 lines\n");
+ }
+
+ if(fflag == 1) /* force 24 lines on/off */
+ {
+ if(!strcmp(onoff, "on"))
+ {
+ fflag = 1;
+ }
+ else if(!strcmp(onoff, "off"))
+ {
+ fflag = 0;
+ }
+ else
+ {
+ fprintf(stderr,"you must specify 'on' or 'off' with -f option!\n");
+ exit(1);
+ }
+ }
+ screeninfo.force_24lines = fflag;
+
+ if(ioctl(fd, VGASETSCREEN, &screeninfo) == -1)
+ {
+ perror("ioctl VGASETSCREEN failed");
+ exit(1);
+ }
+success:
+ if(vflag)
+ printf("successful execution of ioctl VGASETSCREEN!\n");
+ exit(0);
+}
+
+usage()
+{
+ fprintf(stderr,"\nscon - screen control utility for the pcvt video driver\n");
+ fprintf(stderr,"usage: scon -a -l -m -v -c [n] -d [dev] -f [on|off] -V -H -s [n]\n");
+ fprintf(stderr,"usage: scon -p [default | list | i,r,g,b] | -t [sec] | -1 | -8\n");
+ fprintf(stderr," -a list video adaptor type (MDA,CGA,EGA or VGA)\n");
+ fprintf(stderr," -c <screen no> switch current virtual screen to <screen no>\n");
+ fprintf(stderr," -d <device> set parameters(-V|-H|-s) for virtual device\n");
+ fprintf(stderr," -f <on|off> force 24 lines in VT 25 lines and HP 28 lines mode\n");
+ fprintf(stderr," -H set VT220/HP emulation mode for a virtual screen\n");
+ fprintf(stderr," -l list current parameters for a virtual screen\n");
+ fprintf(stderr," -m report monitor type (MONO/COLOR)\n");
+ fprintf(stderr," -p default set default VGA palette\n");
+ fprintf(stderr," -p list list current VGA palette\n");
+ fprintf(stderr," -p <i,r,g,b> set VGA palette entry i to r/g/b\n");
+ fprintf(stderr," -p <name,r,g,b> set VGA palette entry for color name to r/g/b\n");
+ fprintf(stderr," -s <lines> set 25, 28, 35, 40, 43 or 50 lines for a virtual screen\n");
+ fprintf(stderr," -t <timeout> set screen saver timeout [seconds]\n");
+ fprintf(stderr," -1 set 132 columns mode\n");
+ fprintf(stderr," -8 set 80 columns mode\n");
+ fprintf(stderr," -v verbose mode\n");
+ fprintf(stderr," -V set pure VT220 emulation for a virtual screen\n");
+ fprintf(stderr," -? display help (this message)\n\n");
+ exit(1);
+}
+
+printadaptor(fd)
+int fd;
+{
+ if(ioctl(fd, VGAGETSCREEN, &screeninfo) == -1)
+ {
+ perror("ioctl VGAGETSCREEN failed");
+ exit(1);
+ }
+ switch(screeninfo.adaptor_type)
+ {
+ default:
+ case UNKNOWN_ADAPTOR:
+ printf("UNKNOWN\n");
+ break;
+
+ case MDA_ADAPTOR:
+ printf("MDA\n");
+ break;
+
+ case CGA_ADAPTOR:
+ printf("CGA\n");
+ break;
+
+ case EGA_ADAPTOR:
+ printf("EGA\n");
+ break;
+
+ case VGA_ADAPTOR:
+ printf("VGA\n");
+ break;
+ }
+}
+
+printmonitor(fd)
+int fd;
+{
+ if(ioctl(fd, VGAGETSCREEN, &screeninfo) == -1)
+ {
+ perror("ioctl VGAGETSCREEN failed");
+ exit(1);
+ }
+ switch(screeninfo.monitor_type)
+ {
+ default:
+ printf("UNKNOWN\n");
+ break;
+
+ case MONITOR_MONO:
+ printf("MONO\n");
+ break;
+
+ case MONITOR_COLOR:
+ printf("COLOR\n");
+ break;
+ }
+}
+
+char *vga_type(int number)
+{
+ static char *vga_tab[] = {
+ "Generic VGA",
+ "ET4000",
+ "ET3000",
+ "PVGA1A",
+ "WD90C00",
+ "WD90C10",
+ "WD90C11",
+ "VIDEO 7 VEGA",
+ "VIDEO 7 FAST",
+ "VIDEO 7 VER5",
+ "VIDEO 7 1024I",
+ "Unknown VIDEO 7",
+ "TVGA 8800BR",
+ "TVGA 8800CS",
+ "TVGA 8900B",
+ "TVGA 8900C",
+ "TVGA 8900CL",
+ "TVGA 9000",
+ "TVGA 9100",
+ "TVGA 9200",
+ "Unknown TRIDENT",
+ "S3 80C911",
+ "S3 80C924",
+ "S3 80C801/80C805",
+ "S3 80C928",
+ "Unknown S3",
+ "CL-GD5402",
+ "CL-GD5402r1",
+ "CL-GD5420",
+ "CL-GD5420r1",
+ "CL-GD5422",
+ "CL-GD5424",
+ "CL-GD5426",
+ "CL-GD5428",
+ "CL-GD5430",
+ "CL-GD62x5",
+ "Unknown Cirrus",
+
+ };
+ return(vga_tab[number]);
+}
+
+char *vga_family(int number)
+{
+ static char *vga_tab[] = {
+ "Generic VGA",
+ "Tseng Labs",
+ "Western Digital",
+ "Video Seven",
+ "Trident",
+ "S3 Incorporated",
+ "Cirrus Logic",
+ };
+ return(vga_tab[number]);
+}
+
+printinfo(fd)
+int fd;
+{
+ if(ioctl(fd, VGAGETSCREEN, &screeninfo) == -1)
+ {
+ perror("ioctl VGAGETSCREEN failed");
+ exit(1);
+ }
+
+ printf( "\nVideo Adaptor Type = ");
+
+ switch(screeninfo.adaptor_type)
+ {
+ default:
+ case UNKNOWN_ADAPTOR:
+ printf("UNKNOWN Video Adaptor\n");
+ break;
+
+ case MDA_ADAPTOR:
+ printf("MDA - Monochrome Display Adaptor\n");
+ break;
+
+ case CGA_ADAPTOR:
+ printf("CGA - Color Graphics Adaptor\n");
+ break;
+
+ case EGA_ADAPTOR:
+ printf("EGA - Enhanced Graphics Adaptor\n");
+ break;
+
+ case VGA_ADAPTOR:
+ printf("VGA - Video Graphics Adaptor/Array\n");
+ printf(" VGA Chipset Manufacturer = %s\n",
+ vga_family(screeninfo.vga_family));
+ printf(" VGA Chipset Type = %s\n",
+ vga_type(screeninfo.vga_type));
+ printf(" Support for 132 Column Mode = %s\n",
+ screeninfo.vga_132 ? "Yes" : "No");
+ break;
+ }
+
+ printf( "Display Monitor Type = ");
+
+ switch(screeninfo.monitor_type)
+ {
+ default:
+ printf("UNKNOWN Monitor Type\n");
+ break;
+
+ case MONITOR_MONO:
+ printf("Monochrome Monitor\n");
+ break;
+
+ case MONITOR_COLOR:
+ printf("Color Monitor\n");
+ break;
+ }
+
+ printf( "Number of Downloadable Fonts = %d\n",screeninfo.totalfonts);
+ printf( "Number of Virtual Screens = %d\n",screeninfo.totalscreens);
+ printf( "Info Request Screen Number = %d\n",screeninfo.screen_no);
+ printf( "Current Displayed Screen = %d\n",screeninfo.current_screen);
+
+ if(screeninfo.pure_vt_mode == M_PUREVT)
+ printf( "Terminal Emulation Mode = VT220\n");
+ else
+ printf( "Terminal Emulation Mode = VT220 with HP Features\n");
+
+ printf( "Lines = ");
+
+ switch(screeninfo.screen_size)
+ {
+ case SIZ_25ROWS:
+ printf( "25\n");
+ break;
+
+ case SIZ_28ROWS:
+ printf( "28\n");
+ break;
+
+ case SIZ_35ROWS:
+ printf( "35\n");
+ break;
+
+ case SIZ_40ROWS:
+ printf( "40\n");
+ break;
+
+ case SIZ_43ROWS:
+ printf( "43\n");
+ break;
+
+ case SIZ_50ROWS:
+ printf( "50\n");
+ break;
+
+ default:
+ printf( "UNKNOWN\n");
+ break;
+ }
+ printf( "Force 24 Lines = %s",
+ screeninfo.force_24lines ? "Yes" : "No");
+
+ printf("\n\n");
+}
+
+static const char *findname(unsigned idx)
+{
+ /* try to find a name for palette entry idx */
+ /* if multiple names exist, returns first matching */
+ register struct colname *cnp;
+
+ for(cnp = colnames; cnp->name; cnp++)
+ if(cnp->idx == idx)
+ return cnp->name;
+
+ /* not found */
+ return (const char *)NULL;
+}
+
+static void printpalette(int fd)
+{
+ register unsigned idx, last;
+
+ for(idx = 0; idx < NVGAPEL; idx++)
+ {
+ struct vgapel p;
+ p.idx = idx;
+ if(ioctl(fd, VGAREADPEL, &p) < 0)
+ {
+ perror("ioctl(VGAREADPEL)");
+ exit(2);
+ }
+ palette[idx].r = p.r;
+ palette[idx].g = p.g;
+ palette[idx].b = p.b;
+ }
+
+ /* find last non-empty entry */
+ for(last = NVGAPEL - 1; last; last--)
+ if(palette[last].r || palette[last].g || palette[last].b)
+ break;
+
+ if(last != NVGAPEL - 1)
+ last++;
+
+ /* now, everything's collected. print out table */
+ printf("VGA palette status\n");
+ printf("index red green blue name\n");
+ for(idx = 0; idx < last; idx++)
+ {
+ const char *cp;
+ printf("%5d %5d %5d %5d",
+ idx, palette[idx].r, palette[idx].g, palette[idx].b);
+ if(cp = findname(idx))
+ printf(" %s\n", cp);
+ else
+ putchar('\n');
+ }
+ putchar('\n');
+}
+
+
+static void parsepopt(char *arg, unsigned *idx,
+ unsigned *r, unsigned *g, unsigned *b)
+{
+ char firstarg[21];
+ register unsigned i;
+
+ if(sscanf(arg, "%20[a-zA-Z0-9]%*[,:]%u,%u,%u", firstarg, r, g, b) < 4
+ || strlen(firstarg) == 0) {
+ fprintf(stderr, "too few args in -p i,r,g,b\n");
+ exit(2);
+ }
+
+ if(firstarg[0] >= '0' && firstarg[0] <= '9') {
+ *idx = strtoul(firstarg, NULL, 10);
+ return;
+ }
+
+ for(i = 0; colnames[i].name; i++)
+ if(strcasecmp(colnames[i].name, firstarg) == 0) {
+ *idx = colnames[i].idx;
+ return;
+ }
+ fprintf(stderr, "arg ``%s'' in -p option not recognized\n",
+ firstarg);
+ exit(2);
+}
diff --git a/sys/arch/i386/isa/pcvt/Util/set2061/CAUTION b/sys/arch/i386/isa/pcvt/Util/set2061/CAUTION
new file mode 100644
index 00000000000..e1eba06aaa4
--- /dev/null
+++ b/sys/arch/i386/isa/pcvt/Util/set2061/CAUTION
@@ -0,0 +1,28 @@
+CAUTION CAUTION CAUTION CAUTION CAUTION CAUTION CAUTION CAUTION CAUTION CAUTION
+CAUTION CAUTION CAUTION CAUTION CAUTION CAUTION CAUTION CAUTION CAUTION CAUTION
+CAUTION CAUTION CAUTION CAUTION CAUTION CAUTION CAUTION CAUTION CAUTION CAUTION
+
+ THE USE OF THIS PROGRAM MAY DESTROY YOUR MONITOR !!!
+ ====================================================
+
+ IF YOU DON'T KNOW WHAT YOU ARE DOING, STAY AWAY FROM IT !!!
+ ===========================================================
+
+ THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+
+CAUTION CAUTION CAUTION CAUTION CAUTION CAUTION CAUTION CAUTION CAUTION CAUTION
+CAUTION CAUTION CAUTION CAUTION CAUTION CAUTION CAUTION CAUTION CAUTION CAUTION
+CAUTION CAUTION CAUTION CAUTION CAUTION CAUTION CAUTION CAUTION CAUTION CAUTION
+
diff --git a/sys/arch/i386/isa/pcvt/Util/set2061/ICD2061Aalt.c b/sys/arch/i386/isa/pcvt/Util/set2061/ICD2061Aalt.c
new file mode 100644
index 00000000000..248476ad728
--- /dev/null
+++ b/sys/arch/i386/isa/pcvt/Util/set2061/ICD2061Aalt.c
@@ -0,0 +1,297 @@
+/*
+ * This code is derived from code available from the STB bulletin board
+ */
+
+/* $XFree86: mit/server/ddx/x386/common_hw/ICD2061Aalt.c,v 2.6 1994/04/15 05:10:30 dawes Exp $ */
+
+#ifndef KERNEL
+#include "compiler.h"
+#else
+#define GCCUSESGAS
+#define PCVT_STANDALONE 1
+#endif
+
+#define SEQREG 0x03C4
+#define MISCREG 0x03C2
+#define MISCREAD 0x03CC
+
+double fref = 14.31818 * 2.0;
+char ascclk[] = "VIDEO CLOCK ?";
+
+unsigned short clknum;
+unsigned short vlbus_flag;
+unsigned short card;
+unsigned short crtcaddr;
+unsigned short clockreg;
+
+static double range[15] = {50.0, 51.0, 53.2, 58.5, 60.7, 64.4, 66.8, 73.5,
+ 75.6, 80.9, 83.2, 91.5, 100.0, 120.0, 120.0};
+
+#ifdef __STDC__
+static double genratio(unsigned int *p, unsigned int *q, double tgt);
+static double f(unsigned int p, unsigned int q, double basefreq);
+#if 0
+static void prtbinary(unsigned int size, unsigned int val);
+#endif
+static void wait_vb();
+static void wrt_clk_bit(unsigned int value);
+static void init_clock(unsigned long setup, unsigned short crtcport);
+#else
+static double genratio();
+static double f();
+#if 0
+static void prtbinary();
+#endif
+static void wait_vb();
+static void wrt_clk_bit();
+static void init_clock();
+#endif
+
+void AltICD2061SetClock(frequency, select)
+register long frequency; /* in Hz */
+int select;
+{
+ unsigned int m, mval, ival;
+ int i;
+ long dwv;
+ double realval;
+ double freq, fvco;
+ double dev, devx;
+ double delta, deltax;
+ unsigned int p, q;
+ unsigned int bestp, bestq;
+ unsigned char tmp;
+
+ crtcaddr=(inb(0x3CC) & 0x01) ? 0x3D4 : 0x3B4;
+
+
+ outb(crtcaddr, 0x11); /* Unlock CRTC registers */
+ tmp = inb(crtcaddr + 1);
+ outb(crtcaddr + 1, tmp & ~0x80);
+
+ outw(crtcaddr, 0x4838); /* Unlock S3 register set */
+ outw(crtcaddr, 0xA039);
+
+ clknum = select;
+
+ freq = ((double)frequency)/1000000.0;
+ if (freq > range[14])
+ freq =range[14];
+ else if (freq <= 6.99)
+ freq = 7.0;
+
+/*
+ * Calculate values to load into ICD 2061A clock chip to set frequency
+ */
+ delta = 999.0;
+ dev = 999.0;
+ ival = 99;
+ mval = 99;
+
+ fvco = freq / 2;
+ for (m = 0; m < 8; m++) {
+ fvco *= 2.0;
+ for (i = 14; i >= 0; i--)
+ if (fvco >= range[i])
+ break;
+ if (i < 0)
+ continue;
+ if (i == 14)
+ break;
+ devx = (fvco - (range[i] + range[i+1])/2)/fvco;
+ if (devx < 0)
+ devx = -devx;
+ deltax = genratio(&p, &q, fvco);
+ if (delta < deltax)
+ continue;
+ if (deltax < delta || devx < dev) {
+ bestp = p;
+ bestq = q;
+ delta = deltax;
+ dev = devx;
+ ival = i;
+ mval = m;
+ }
+ }
+ fvco = fref;
+ for (m=0; m<mval; m++)
+ fvco /= 2.0;
+ realval = f(bestp, bestq, fvco);
+ dwv = ((((((long)ival << 7) | bestp) << 3) | mval) << 7) | bestq;
+
+/*
+ * Write ICD 2061A clock chip
+ */
+ init_clock(((unsigned long)dwv) | (((long)clknum) << 21), crtcaddr);
+
+ wait_vb();
+ wait_vb();
+ wait_vb();
+ wait_vb();
+ wait_vb();
+ wait_vb();
+ wait_vb(); /* 0.10 second delay... */
+}
+
+static double f(p, q, base)
+ unsigned int p;
+ unsigned int q;
+ double base;
+ {
+ return(base * (p + 3)/(q + 2));
+ }
+
+static double genratio(p, q, tgt)
+ unsigned int *p;
+ unsigned int *q;
+ double tgt;
+ {
+ int k, m;
+ double test, mindiff;
+ unsigned int mmax;
+
+ mindiff = 999999999.0;
+ for (k = 13; k < 69; k++) { /* q={15..71}:Constraint 2 on page 14 */
+ m = 50.0*k/fref - 3;
+ if (m < 0)
+ m = 0;
+ mmax = 120*k/fref - 3; /* m..mmax is constraint 3 on page 14 */
+ if (mmax > 128)
+ mmax = 128;
+ while (m < mmax) {
+ test = f(m, k, fref) - tgt;
+ if (test < 0) test = -test;
+ if (mindiff > test) {
+ mindiff = test;
+ *p = m;
+ *q = k;
+ }
+ m++;
+ }
+ }
+ return (mindiff);
+ }
+
+#if 0
+static void prtbinary(size, val)
+ unsigned int size;
+ unsigned int val;
+ {
+ unsigned int mask;
+ int k;
+
+ mask = 1;
+
+ for (k=size; --k > 0 || mask <= val/2;)
+ mask <<= 1;
+
+ while (mask) {
+ fputc((mask&val)? '1': '0' , stderr);
+ mask >>= 1;
+ }
+ }
+#endif
+
+static void wait_vb()
+ {
+ while ((inb(crtcaddr+6) & 0x08) == 0)
+ ;
+ while (inb(crtcaddr+6) & 0x08)
+ ;
+ }
+
+
+#ifdef __STDC__
+static void init_clock(unsigned long setup, unsigned short crtcport)
+#else
+static void init_clock(setup, crtcport)
+ unsigned long setup;
+ unsigned short crtcport;
+#endif
+ {
+ unsigned char nclk[2], clk[2];
+ unsigned short restore42;
+ unsigned short oldclk;
+ unsigned short bitval;
+ int i;
+ unsigned char c;
+
+#ifndef PCVT_STANDALONE
+ (void)xf86DisableInterrupts();
+#endif
+
+ oldclk = inb(0x3CC);
+
+ outb(crtcport, 0x42);
+ restore42 = inb(crtcport+1);
+
+ outw(0x3C4, 0x0100);
+
+ outb(0x3C4, 1);
+ c = inb(0x3C5);
+ outb(0x3C5, 0x20 | c);
+
+ outb(crtcport, 0x42);
+ outb(crtcport+1, 0x03);
+
+ outw(0x3C4, 0x0300);
+
+ nclk[0] = oldclk & 0xF3;
+ nclk[1] = nclk[0] | 0x08;
+ clk[0] = nclk[0] | 0x04;
+ clk[1] = nclk[0] | 0x0C;
+
+ outb(crtcport, 0x42);
+ i = inw(crtcport);
+
+ outw(0x3C4, 0x0100);
+
+ wrt_clk_bit(oldclk | 0x08);
+ wrt_clk_bit(oldclk | 0x0C);
+ for (i=0; i<5; i++) {
+ wrt_clk_bit(nclk[1]);
+ wrt_clk_bit(clk[1]);
+ }
+ wrt_clk_bit(nclk[1]);
+ wrt_clk_bit(nclk[0]);
+ wrt_clk_bit(clk[0]);
+ wrt_clk_bit(nclk[0]);
+ wrt_clk_bit(clk[0]);
+ for (i=0; i<24; i++) {
+ bitval = setup & 0x01;
+ setup >>= 1;
+ wrt_clk_bit(clk[1-bitval]);
+ wrt_clk_bit(nclk[1-bitval]);
+ wrt_clk_bit(nclk[bitval]);
+ wrt_clk_bit(clk[bitval]);
+ }
+ wrt_clk_bit(clk[1]);
+ wrt_clk_bit(nclk[1]);
+ wrt_clk_bit(clk[1]);
+
+ outb(0x3C4, 1);
+ c = inb(0x3C5);
+ outb(0x3C5, 0xDF & c);
+
+ outb(crtcport, 0x42);
+ outb(crtcport+1, restore42);
+
+ outb(0x3C2, oldclk);
+
+ outw(0x3C4, 0x0300);
+
+#ifndef PCVT_STANDALONE
+ xf86EnableInterrupts();
+#endif
+
+ }
+
+static void wrt_clk_bit(value)
+ unsigned int value;
+ {
+ int j;
+
+ outb(0x3C2, value);
+ for (j=2; --j; )
+ inb(0x200);
+ }
diff --git a/sys/arch/i386/isa/pcvt/Util/set2061/Makefile b/sys/arch/i386/isa/pcvt/Util/set2061/Makefile
new file mode 100644
index 00000000000..3a1c92aa560
--- /dev/null
+++ b/sys/arch/i386/isa/pcvt/Util/set2061/Makefile
@@ -0,0 +1,10 @@
+PROG= set2061
+SRCS= main.c ICD2061Aalt.c
+CFLAGS+= -DGCCUSESGAS -DPCVT_STANDALONE
+NOMAN=
+
+all: $(PROG)
+
+.include <bsd.prog.mk>
+
+$(PROG): compiler.h
diff --git a/sys/arch/i386/isa/pcvt/Util/set2061/README b/sys/arch/i386/isa/pcvt/Util/set2061/README
new file mode 100644
index 00000000000..fd5ec868935
--- /dev/null
+++ b/sys/arch/i386/isa/pcvt/Util/set2061/README
@@ -0,0 +1,22 @@
+CAUTION CAUTION CAUTION CAUTION CAUTION CAUTION CAUTION CAUTION CAUTION CAUTION
+
+ THE USE OF THIS PROGRAM MAY DESTROY YOUR MONITOR !!!
+ ====================================================
+
+ IF YOU DON'T KNOW WHAT YOU ARE DOING, STAY AWAY FROM IT !!!
+ ===========================================================
+
+Read the file "CAUTION" before proceeding !!!
+
+The files:
+
+ ICD2061Aalt.c and
+ compiler.h
+
+come from the Xfree86 2.1 distribution and have been slightly modified to
+fit into a non-XFree environment.
+
+I use it to program the clock generator ICD2061a on my S3 928 based ELSA
+Winner VGA board to 40MHz for clock generator #2: set2061 -n2 -f40000000.
+
+This enables me to use 132 columns mode on this VGA board.
diff --git a/sys/arch/i386/isa/pcvt/Util/set2061/compiler.h b/sys/arch/i386/isa/pcvt/Util/set2061/compiler.h
new file mode 100644
index 00000000000..c05dbf52665
--- /dev/null
+++ b/sys/arch/i386/isa/pcvt/Util/set2061/compiler.h
@@ -0,0 +1,341 @@
+/* $XFree86: mit/server/ddx/x386/common/compiler.h,v 2.3 1993/10/03 14:55:28 dawes Exp $ */
+/*
+ * Copyright 1990,91 by Thomas Roell, Dinkelscherben, Germany.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of Thomas Roell not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Thomas Roell makes no representations
+ * about the suitability of this software for any purpose. It is provided
+ * "as is" without express or implied warranty.
+ *
+ * THOMAS ROELL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL THOMAS ROELL BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ *
+ * $Header: /cvs/OpenBSD/src/sys/arch/i386/isa/pcvt/Util/set2061/Attic/compiler.h,v 1.1 1995/10/18 08:50:48 deraadt Exp $
+ */
+
+
+#ifndef _COMPILER_H
+#define _COMPILER_H
+
+#ifndef __STDC__
+# ifdef signed
+# undef signed
+# endif
+# ifdef volatile
+# undef volatile
+# endif
+# ifdef const
+# undef const
+# endif
+# define signed /**/
+# ifdef __GNUC__
+# define volatile __volatile__
+# define const __const__
+# else
+# define const /**/
+# endif /* __GNUC__ */
+#endif /* !__STDC__ */
+
+#ifdef NO_INLINE
+
+extern void outb();
+extern void outw();
+extern unsigned int inb();
+extern unsigned int inw();
+#if NeedFunctionPrototypes
+extern unsigned char rdinx(unsigned short, unsigned char);
+extern void wrinx(unsigned short, unsigned char, unsigned char);
+extern void modinx(unsigned short, unsigned char, unsigned char, unsigned char);
+extern int testrg(unsigned short, unsigned char);
+extern int textinx2(unsigned short, unsigned char, unsigned char);
+extern int textinx(unsigned short, unsigned char);
+#else /* NeedFunctionProtoypes */
+extern unsigned char rdinx();
+extern void wrinx();
+extern void modinx();
+extern int testrg();
+extern int textinx2();
+extern int textinx();
+#endif /* NeedFunctionProtoypes */
+
+#else /* NO_INLINE */
+
+#ifdef __GNUC__
+
+#ifndef FAKEIT
+#ifdef GCCUSESGAS
+
+/*
+ * If gcc uses gas rather than the native assembler, the syntax of these
+ * inlines has to be different. DHD
+ */
+
+static __inline__ void
+outb(port, val)
+short port;
+char val;
+{
+ __asm__ __volatile__("outb %0,%1" : :"a" (val), "d" (port));
+}
+
+
+static __inline__ void
+outw(port, val)
+short port;
+short val;
+{
+ __asm__ __volatile__("outw %0,%1" : :"a" (val), "d" (port));
+}
+
+static __inline__ unsigned int
+inb(port)
+short port;
+{
+ unsigned char ret;
+ __asm__ __volatile__("inb %1,%0" :
+ "=a" (ret) :
+ "d" (port));
+ return ret;
+}
+
+static __inline__ unsigned int
+inw(port)
+short port;
+{
+ unsigned short ret;
+ __asm__ __volatile__("inw %1,%0" :
+ "=a" (ret) :
+ "d" (port));
+ return ret;
+}
+
+#else /* GCCUSESGAS */
+
+static __inline__ void
+outb(port, val)
+ short port;
+ char val;
+{
+ __asm__ __volatile__("out%B0 (%1)" : :"a" (val), "d" (port));
+}
+
+static __inline__ void
+outw(port, val)
+ short port;
+ short val;
+{
+ __asm__ __volatile__("out%W0 (%1)" : :"a" (val), "d" (port));
+}
+
+static __inline__ unsigned int
+inb(port)
+ short port;
+{
+ unsigned char ret;
+ __asm__ __volatile__("in%B0 (%1)" :
+ "=a" (ret) :
+ "d" (port));
+ return ret;
+}
+
+static __inline__ unsigned int
+inw(port)
+ short port;
+{
+ unsigned short ret;
+ __asm__ __volatile__("in%W0 (%1)" :
+ "=a" (ret) :
+ "d" (port));
+ return ret;
+}
+
+#endif /* GCCUSESGAS */
+
+#else /* FAKEIT */
+
+static __inline__ void
+outb(port, val)
+ short port;
+ char val;
+{
+}
+
+static __inline__ void
+outw(port, val)
+ short port;
+ short val;
+{
+}
+
+static __inline__ unsigned int
+inb(port)
+ short port;
+{
+ return 0;
+}
+
+static __inline__ unsigned int
+inw(port)
+ short port;
+{
+ return 0;
+}
+
+#endif /* FAKEIT */
+
+#else /* __GNUC__ */
+#if !defined(AMOEBA) && !defined(_MINIX)
+# if defined(__STDC__) && (__STDC__ == 1)
+# define asm __asm
+# endif
+# ifdef SVR4
+# include <sys/types.h>
+# ifndef __USLC__
+# define __USLC__
+# endif
+# endif
+# include <sys/inline.h>
+#endif
+#endif
+
+/*
+ *-----------------------------------------------------------------------
+ * Port manipulation convenience functions
+ *-----------------------------------------------------------------------
+ */
+
+#ifndef __GNUC__
+#define __inline__ /**/
+#endif
+
+/*
+ * rdinx - read the indexed byte port 'port', index 'ind', and return its value
+ */
+static __inline__ unsigned char
+#ifdef __STDC__
+rdinx(unsigned short port, unsigned char ind)
+#else
+rdinx(port, ind)
+unsigned short port;
+unsigned char ind;
+#endif
+{
+ if (port == 0x3C0) /* reset attribute flip-flop */
+ (void) inb(0x3DA);
+ outb(port, ind);
+ return(inb(port+1));
+}
+
+/*
+ * wrinx - write 'val' to port 'port', index 'ind'
+ */
+static __inline__ void
+#ifdef __STDC__
+wrinx(unsigned short port, unsigned char ind, unsigned char val)
+#else
+wrinx(port, ind, val)
+unsigned short port;
+unsigned char ind, val;
+#endif
+{
+ outb(port, ind);
+ outb(port+1, val);
+}
+
+/*
+ * modinx - in register 'port', index 'ind', set the bits in 'mask' as in 'new';
+ * the other bits are unchanged.
+ */
+static __inline__ void
+#ifdef __STDC__
+modinx(unsigned short port, unsigned char ind,
+ unsigned char mask, unsigned char new)
+#else
+modinx(port, ind, mask, new)
+unsigned short port;
+unsigned char ind, mask, new;
+#endif
+{
+ unsigned char tmp;
+
+ tmp = (rdinx(port, ind) & ~mask) | (new & mask);
+ wrinx(port, ind, tmp);
+}
+
+/*
+ * tstrg - returns true iff the bits in 'mask' of register 'port' are
+ * readable & writable.
+ */
+
+static __inline__ int
+#ifdef __STDC__
+testrg(unsigned short port, unsigned char mask)
+#else
+tstrg(port, mask)
+unsigned short port;
+unsigned char mask;
+#endif
+{
+ unsigned char old, new1, new2;
+
+ old = inb(port);
+ outb(port, old & ~mask);
+ new1 = inb(port) & mask;
+ outb(port, old | mask);
+ new2 = inb(port) & mask;
+ outb(port, old);
+ return((new1 == 0) && (new2 == mask));
+}
+
+/*
+ * testinx2 - returns true iff the bits in 'mask' of register 'port', index
+ * 'ind' are readable & writable.
+ */
+static __inline__ int
+#ifdef __STDC__
+testinx2(unsigned short port, unsigned char ind, unsigned char mask)
+#else
+testinx2(port, ind, mask)
+unsigned short port;
+unsigned char ind, mask;
+#endif
+{
+ unsigned char old, new1, new2;
+
+ old = rdinx(port, ind);
+ wrinx(port, ind, old & ~mask);
+ new1 = rdinx(port, ind) & mask;
+ wrinx(port, ind, old | mask);
+ new2 = rdinx(port, ind) & mask;
+ wrinx(port, ind, old);
+ return((new1 == 0) && (new2 == mask));
+}
+
+/*
+ * testinx - returns true iff all bits of register 'port', index 'ind' are
+ * readable & writable.
+ */
+static __inline__ int
+#ifdef __STDC__
+testinx(unsigned short port, unsigned char ind)
+#else
+testinx(port, ind, mask)
+unsigned short port;
+unsigned char ind;
+#endif
+{
+ return(testinx2(port, ind, 0xFF));
+}
+
+#endif /* NO_INLINE */
+#endif /* _COMPILER_H */
diff --git a/sys/arch/i386/isa/pcvt/Util/set2061/main.c b/sys/arch/i386/isa/pcvt/Util/set2061/main.c
new file mode 100644
index 00000000000..03a482d3e3f
--- /dev/null
+++ b/sys/arch/i386/isa/pcvt/Util/set2061/main.c
@@ -0,0 +1,112 @@
+/*
+ * Copyright (c) 1994 Hellmuth Michaelis
+ *
+ * All rights reserved.
+ *
+ * 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
+ * Hellmuth Michaelis
+ * 4. The name authors may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``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 AUTHORS 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.
+ *
+ */
+
+static char *id =
+ "@(#)set2061.c, 1.00, Last Edit-Date: [Sun Jan 15 19:52:05 1995]";
+
+/*---------------------------------------------------------------------------*
+ *
+ * history:
+ *
+ * -hm start using 132 columns on my Elsa Winner
+ *
+ *---------------------------------------------------------------------------*/
+
+#include <stdio.h>
+#include <fcntl.h>
+#include <machine/pcvt_ioctl.h>
+
+#define DEFAULTFD 0
+
+void AltICD2061SetClock(long frequency, int select);
+
+main(argc,argv)
+int argc;
+char *argv[];
+{
+ extern int optind;
+ extern int opterr;
+ extern char *optarg;
+
+ int fd;
+ int c;
+ long freq = -1;
+ int no = -1;
+
+ while( (c = getopt(argc, argv, "f:n:")) != EOF)
+ {
+ switch(c)
+ {
+ case 'f':
+ freq = atoi(optarg);
+ break;
+
+ case 'n':
+ no = atoi(optarg);
+ break;
+
+ case '?':
+ default:
+ usage();
+ break;
+ }
+ }
+
+ if(freq == -1 || no == -1)
+ usage();
+
+ if((fd = open("/dev/console", O_RDONLY)) < 0)
+ fd = DEFAULTFD;
+
+ if(ioctl(fd, KDENABIO, 0) < 0)
+ {
+ perror("ioctl(KDENABIO)");
+ return 1;
+ }
+
+ AltICD2061SetClock(freq, no);
+
+ (void)ioctl(fd, KDDISABIO, 0);
+
+ exit(0);
+}
+
+usage()
+{
+ fprintf(stderr,"\nset2061 - program the ICD2061 video clock chip\n");
+ fprintf(stderr,"usage: set2061 -f <freq> -n <no>\n");
+ fprintf(stderr," -f <freq> frequency in Hz\n");
+ fprintf(stderr," -n <no> clock generator number\n");
+ exit(1);
+}
+
diff --git a/sys/arch/i386/isa/pcvt/Util/userkeys/Makefile b/sys/arch/i386/isa/pcvt/Util/userkeys/Makefile
new file mode 100644
index 00000000000..2e0e1118b7e
--- /dev/null
+++ b/sys/arch/i386/isa/pcvt/Util/userkeys/Makefile
@@ -0,0 +1,3 @@
+PROG= vt220keys
+
+.include <bsd.prog.mk>
diff --git a/sys/arch/i386/isa/pcvt/Util/userkeys/vt220keys.1 b/sys/arch/i386/isa/pcvt/Util/userkeys/vt220keys.1
new file mode 100644
index 00000000000..cff95bf2b22
--- /dev/null
+++ b/sys/arch/i386/isa/pcvt/Util/userkeys/vt220keys.1
@@ -0,0 +1,131 @@
+.TH VT220 1
+.UC 4
+.SH NAME
+vt220 \- define SHIFTED function keys on VT220 terminal
+.SH SYNTAX
+.B vt220
+[
+.B \-cil
+]
+[ keyname keystring ] ...
+.SH DESCRIPTION
+.I Vt220
+sets up a "vt220 terminal" in vt200 mode to allow user
+definition of the SHIFTED function keys. Each
+\f2keyname\f1 specified on the command line will be loaded with
+the corresponding \f2keystring\f1.
+A \f2keyname\f1 is one of the following "words":
+F6 F7 F8 F9 F10 F11 ESC F12 BS F13 LF F14 HELP DO F17 F18 F19 F20.
+\f2Keystrings\f1
+must be quoted if spaces, tabs, or shell metacharacters are included.
+.PP
+.B Vt220
+expects to receive some combination of option flags and/or
+argument pair(s), otherwised an usage message
+is printed.
+.PP
+The options are:
+.TP
+.B \-c
+Clears all SHIFTED function key definitions before setting them to user
+defined strings.
+.TP
+.B \-i
+Read the initialization file
+.I $HOME/.vt220rc
+for SHIFTED function key definitions. This is done before any
+argument pair specified on the command line is processed.
+Each line in the file must consist of two fields (separated by spaces
+or tabs) where the first field is the
+\f2keyname\f1 and the second field is the \f2keystring\f1.
+The second field extends to the end of the line, thus a
+\f2keystring\f1
+may include spaces or tabs. A newline (return) may be specified
+within the string by using the C Language notation for newline (\\n).
+.TP
+.B \-l
+Locks the function keys from further definition.
+Locking occurs after processing the initialization file (if the "i"
+option is specified) and any argument
+pairs.
+The only way
+to unlock is by turning the power off.
+.SH EXAMPLES
+vt220 -ci
+.br
+vt220 F6 'nroff -ms '
+.br
+vt220 -i F20 'cc -O -c '
+.br
+vt220 -l HELP man
+.SH "OTHER FEATURES"
+Pressing the function keys without using the shift key, generates
+a string of characters. With
+\f2csh\f1(1) this string can be aliased to some command. For example:
+.br
+ alias ^[[17~ "ls -CR | more"
+.br
+where ^[[17~ is what is generated by pressing the F6 key. Therefore
+F6 can perform two commands, depending if pressed with/without the SHIFT
+key.
+.PP
+.B Vt220
+can be called from your .login or .profile file. Typically an user
+will create a initialization file and include a line like
+.br
+ vt220 -ci
+.br
+OR
+.br
+ vt220 -cil
+.br
+in the above mentioned files. This way the SHIFTED function keys
+will be set to your favorite commands when logging in.
+.SH CAVEATS
+If the SHIFTED function keys are unlocked, redefinition of a SHIFTED
+function key will rewrite the old string.
+.PP
+There are 256 bytes available for the SHIFTED function keys. Space is
+supplied on a first-come/first-serve basis. After the 256 bytes are
+used, you can't define any more keys unless space is cleared. This
+can be done by redefining a key to contain a string of fewer bytes.
+.PP
+All key definitions are stored in volatile RAM, and are lost when
+terminal power is lost.
+.PP
+The ESC key (unshifted) no longer generates the proper escape character. This
+is of particular importance since many editors require use of the
+ESC key. Here are some available alternatives:
+.sp
+.in +.5i
+The escape character can be generated by typing ^[ (control-[).
+.sp
+Use
+.B vt220
+as follows (note ^[ is control-[)
+.br
+.in +.5i
+vt220 ESC '^['
+.in
+.br
+This will require you
+to press the SHIFT key and ESC to generate the escape sequence.
+.sp
+Some editors, allow other character(s) to be substituted for the
+escape character. For example with
+.B emacs
+include this line in your .emacs_pro:
+.br
+ (bind-to-key "ESC-prefix" "\\033[23~")
+.br
+Thus when the ESC key is pressed, emacs will allow the characters
+generated (^[[23~) to perform the same function as the escape
+character.
+.in
+.SH FILES
+$HOME/.vt220rc \- initialization file
+.SH "SEE ALSO"
+VT220 Programmer Reference Manual
+.br
+VT220 Programmer Pocket Guide
+
diff --git a/sys/arch/i386/isa/pcvt/Util/userkeys/vt220keys.c b/sys/arch/i386/isa/pcvt/Util/userkeys/vt220keys.c
new file mode 100644
index 00000000000..dfde51a2691
--- /dev/null
+++ b/sys/arch/i386/isa/pcvt/Util/userkeys/vt220keys.c
@@ -0,0 +1,297 @@
+/*
+ * Trivial program to load VT220 Function keys with strings,
+ * note that the values only get sent when the key is shifted
+ * (shoulda been an option to flip the shift set like the Z19!)
+ *
+ * Typing no args gives help, basically pairs of keyname/value
+ * strings.
+ *
+ * Author, Author: Barry Shein, Boston University
+ *
+ * HISTORY
+ {1} 30-Oct-85 Kenneth J. Lester (ken) at ektools
+
+ Added the necessary code to read an initialization file. This
+ should make it easier to used this program. Also added code
+ that will set-up the terminal in vt200 (this saves the user the
+ trouble of checking if the set-up is in vt200).
+
+ Restructed the main function to use getopt, for argument
+ processing.
+
+ Alterated usage function to include new "i" option (init file)
+
+
+ -hm minor modifications for pcvt 2.0 release
+
+*/
+
+#include <stdio.h>
+#include <ctype.h>
+
+/*
+ * The default toupper() macro is stupid, will toupper anything
+ */
+
+#ifdef toupper
+#undef toupper
+#endif
+#define toupper(c) (islower(c) ? ((c)-' ') : c)
+
+#define VT200_7BIT 1
+#define ESC 033
+#define INITFILE ".vt220rc"
+
+struct keynames {
+ char *name ;
+ char *string ;
+} keys[] = {
+ "F6", "17",
+ "F7", "18",
+ "F8", "19",
+ "F9", "20",
+ "F10", "21",
+ "F11", "23",
+ "ESC", "23",
+ "F12", "24",
+ "BS", "24",
+ "F13", "25",
+ "LF", "25",
+ "F14", "26",
+ "HELP", "28",
+ "DO", "29",
+ "F17", "31",
+ "F18", "32",
+ "F19", "33",
+ "F20", "34",
+ NULL, NULL
+};
+
+char prog[BUFSIZ];
+
+main(argc,argv)
+ int argc;
+ char *argv[];
+{
+ /* these are defined in the getopt routine */
+ extern char *optarg; /* argument give to an option */
+ extern int optind; /* argv index after option processing */
+
+ int option; /* option character returned by getopt */
+ int initf = 0; /* read initialization file */
+ int lockf = 0; /* lock keys after loading strings */
+ int clearf = 0; /* clear all keys before loading strings */
+ char *strcpy();
+
+ (void) strcpy(prog, *argv); /* store program name */
+
+ if(argc == 1) usage(); /* program requires options */
+
+ /* get options */
+ while ((option = getopt(argc, argv, "cli")) != EOF)
+ switch(option)
+ {
+ case 'c' :
+ clearf++;
+ break;
+ case 'l' :
+ lockf++;
+ break;
+ case 'i' :
+ initf++;
+ break;
+ case '?' :
+ usage();
+ }
+
+ if (VT200_7BIT)
+ printf("\033[62;1\"p"); /* vt200 7 bits */
+ else
+ printf("\033[62;2\"p"); /* vt200 8 bits */
+
+ if(clearf) clearkeys();
+
+ if (initf) getinit();
+
+ /* process {key, key string} pairs. Note optind is index to argv
+ for first pair. By adding 1 to optind insures that a pair exists
+ i.e. the last key has a key string. */
+
+ while(optind + 1 < argc)
+ {
+ dokey(argv[optind], argv[optind+1]);
+ optind += 2;
+ }
+
+ if(lockf) lockkeys();
+
+ exit(0);
+}
+
+/****************************************************************************/
+
+/*
+ * Load the VT220 SHIFT-FNKEY value, the basic pattern is
+ * "\EP1;1|"+KEYNAME+"/"+VAL_AS_HEX+"\E\\"
+ * that is, literally what is in quotes (w/o quotes) then the
+ * name of the key from the keytable above (a numeric string)
+ * then a slash, then the string value as hex pairs then ESC-BACKSLASH
+ *
+ * Note: you can gang together key defns with semicolons but that
+ * would complicate things, especially error handling, so do it all
+ * for each pair, who cares, really.
+ */
+
+dokey(nm,val) char *nm, *val;
+{
+ register char *scr;
+ register struct keynames *kp;
+
+ for(scr = nm; *scr = toupper(*scr); scr++)
+ ;
+ for(kp = keys; kp->name != NULL; kp++)
+ if(strcmp(nm,kp->name) == 0) {
+ printf("%cP1;1|%s/",ESC,kp->string);
+ while(*val) printf("%02x",*val++);
+ printf("%c\\",ESC);
+ fflush(stdout);
+ return;
+ }
+ fprintf(stderr,"Bad key name: %s\n",nm);
+ usage(); /* bad key name, give up */
+}
+
+/****************************************************************************/
+
+clearkeys()
+{
+ printf("%cP0;1|%c\\",ESC,ESC);
+ fflush(stdout);
+}
+
+/****************************************************************************/
+
+lockkeys()
+{
+ printf("%cP1;0|%c\\",ESC,ESC);
+ fflush(stdout);
+}
+
+/****************************************************************************/
+
+usage()
+{
+ int i;
+
+ fprintf(stderr,"Usage: %s [-cil] [keyname string keyname string...]\n\n",prog);
+ fprintf(stderr,"The following options are available\n");
+ fprintf(stderr,"\t-c\tclears keys first\n");
+ fprintf(stderr,"\t-l\t[sets then] locks further setting\n");
+ fprintf(stderr,"\t-i\tfirst read initialization file $HOME/%s\n",INITFILE);
+ fprintf(stderr,"(note that the only way to unlock is via Set-Up)\n\n");
+ fprintf(stderr,"Keyname is one of:\n\t");
+ for(i=0; keys[i].name != NULL; i++)
+ fprintf(stderr,"%s ",keys[i].name);
+ fprintf(stderr,"\nKeyname is SHIFTED function key that sends the string\n\n");
+ fprintf(stderr,"Strings may need quoting to protect from shell\n");
+ fprintf(stderr,"You must specify an option or key,string pairs\n\n");
+ exit(1);
+}
+
+/****************************************************************************/
+
+/* This routine process the INITFILE. This file expects lines in the format
+
+ <ws> keyname ws string
+
+ Where ws is white space (spaces or tabs) and <ws> is optional white space.
+ The string may include spaces or tabs and need not be quoted. If the
+ string has the sequence of "\n" then a newline character is included in
+ the string.
+
+ examples:
+
+ F6 ls -lg\n
+ F7 uulog -s
+
+*/
+
+#include <sys/types.h>
+#include <sys/stat.h>
+
+getinit()
+{
+ char *home; /* user's home directory */
+ char path[BUFSIZ]; /* full path name of init file */
+ char buf[BUFSIZ]; /* buffer to hold 1 line from init file */
+ char key[BUFSIZ]; /* buffer, to hold specified fcn key */
+ char keystr[BUFSIZ]; /* string associated with fcn key */
+ char *ptr; /* pointer to transverse buf */
+ int i, j; /* array indices */
+ int statflag; /* whether init file is regular & readable */
+ struct stat statbuf; /* stat of the init file */
+ FILE *fp; /* file pointer to init file */
+
+ /* system calls and subroutines */
+ FILE *fopen();
+ char *strcpy();
+ char *strcat();
+ char *fgets();
+ char *getenv();
+
+ /* construct full path name for init file */
+ home = getenv("HOME");
+ (void) strcpy(path, home);
+ (void) strcat(path,"/");
+ (void) strcat(path,INITFILE);
+
+ /* check status if init file */
+ if (stat(path, &statbuf) != -1)
+ {
+ statflag = statbuf.st_mode & S_IFREG && statbuf.st_mode & S_IREAD;
+ if (!statflag || (fp = fopen(path, "r")) == NULL)
+ {
+ fprintf(stderr, "couldn't open initalization file: %s\n", path);
+ exit(1);
+ }
+
+ /* process lines from init file */
+ while (fgets(buf, BUFSIZ, fp) != NULL)
+ {
+ /* variable initializations */
+ i = 0; j = 0;
+ key[0] = '\0'; keystr[0] = '\0';
+ ptr = buf;
+
+ while (*ptr == ' ' || *ptr == '\t') ptr++; /*skip whitespace*/
+
+ if (*ptr == '\n') break; /* we hit an emtpy line */
+
+ while (!isspace(*ptr) && *ptr != '\0') /* get keyname */
+ key[i++] = *ptr++;
+ key[i] = '\0'; /* place EOS in buffer */
+
+ while (*ptr == ' ' || *ptr == '\t') ptr++; /*skip whitespace*/
+
+ while (*ptr != '\n' && *ptr != '\0') /* get string */
+ {
+ /* check if string is to include newline i.e. \n */
+ if (*ptr == '\\' && *(ptr+1) == 'n')
+ {
+ keystr[j] = '\012';
+ ptr++;
+ }
+ else
+ keystr[j] = *ptr;
+ j++; ptr++;
+ }
+ keystr[j] = '\0'; /* place EOS in buffer */
+ dokey(key, keystr); /* load key with string */
+ }
+ }
+ else
+ {
+ fprintf(stderr, "init file %s not found\n\n", path);
+ usage();
+ }
+}
diff --git a/sys/arch/i386/isa/pcvt/Util/vgaio/CAUTION b/sys/arch/i386/isa/pcvt/Util/vgaio/CAUTION
new file mode 100644
index 00000000000..e1eba06aaa4
--- /dev/null
+++ b/sys/arch/i386/isa/pcvt/Util/vgaio/CAUTION
@@ -0,0 +1,28 @@
+CAUTION CAUTION CAUTION CAUTION CAUTION CAUTION CAUTION CAUTION CAUTION CAUTION
+CAUTION CAUTION CAUTION CAUTION CAUTION CAUTION CAUTION CAUTION CAUTION CAUTION
+CAUTION CAUTION CAUTION CAUTION CAUTION CAUTION CAUTION CAUTION CAUTION CAUTION
+
+ THE USE OF THIS PROGRAM MAY DESTROY YOUR MONITOR !!!
+ ====================================================
+
+ IF YOU DON'T KNOW WHAT YOU ARE DOING, STAY AWAY FROM IT !!!
+ ===========================================================
+
+ THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+
+CAUTION CAUTION CAUTION CAUTION CAUTION CAUTION CAUTION CAUTION CAUTION CAUTION
+CAUTION CAUTION CAUTION CAUTION CAUTION CAUTION CAUTION CAUTION CAUTION CAUTION
+CAUTION CAUTION CAUTION CAUTION CAUTION CAUTION CAUTION CAUTION CAUTION CAUTION
+
diff --git a/sys/arch/i386/isa/pcvt/Util/vgaio/Makefile b/sys/arch/i386/isa/pcvt/Util/vgaio/Makefile
new file mode 100644
index 00000000000..253d5ec18e1
--- /dev/null
+++ b/sys/arch/i386/isa/pcvt/Util/vgaio/Makefile
@@ -0,0 +1,18 @@
+PROG= vgaio
+MAN8= vgaio.${MAN8EXT}
+
+SRCS= vgaio.y lex.l
+YACC= yacc
+
+#YFLAGS+= -yd # Bison
+#YFLAGS+= -v # verbose
+
+LFLAGS+= -I
+LDADD= -lm -ly -ll
+
+CFLAGS+= -I ${.CURDIR}/obj -I ${.CURDIR} -g
+
+CLEANFILES+= y.tab.h
+CLEANFILES+= y.output # comment file from bison
+
+.include <bsd.prog.mk>
diff --git a/sys/arch/i386/isa/pcvt/Util/vgaio/lex.l b/sys/arch/i386/isa/pcvt/Util/vgaio/lex.l
new file mode 100644
index 00000000000..2df1889b0ca
--- /dev/null
+++ b/sys/arch/i386/isa/pcvt/Util/vgaio/lex.l
@@ -0,0 +1,68 @@
+%{
+/*
+ * Copyright (c) 1994,1995 Joerg Wunsch
+ *
+ * All rights reserved.
+ *
+ * This program is free software.
+ *
+ * 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 Joerg Wunsch
+ * 4. The name of the developer may not be used to endorse or promote
+ * products derived from this software without specific prior written
+ * permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``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 DEVELOPERS 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.
+ */
+
+#ident "$Header: /cvs/OpenBSD/src/sys/arch/i386/isa/pcvt/Util/vgaio/Attic/lex.l,v 1.1 1995/10/18 08:50:49 deraadt Exp $"
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "vgaio.h"
+#include "y.tab.h"
+
+extern YYSTYPE yylval;
+
+%}
+
+D [0-9a-fA-F]
+
+%%
+
+cr|CR { return CR; }
+
+ar|AR { return AR; }
+
+gr|GR { return GR; }
+
+sr|SR { return SR; }
+
+mi|MI { return MI; }
+
+{D}({D}*) { sscanf(yytext, "%x", &yylval.num); return NUM; }
+
+[ \t] { /* ignore */ }
+
+\n { return NEWLINE; }
+
+. { return yytext[0]; }
diff --git a/sys/arch/i386/isa/pcvt/Util/vgaio/vgaio.8 b/sys/arch/i386/isa/pcvt/Util/vgaio/vgaio.8
new file mode 100644
index 00000000000..8275232cbc8
--- /dev/null
+++ b/sys/arch/i386/isa/pcvt/Util/vgaio/vgaio.8
@@ -0,0 +1,156 @@
+.\"
+.\" Copyright (c) 1994,1995 Joerg Wunsch
+.\"
+.\" All rights reserved.
+.\"
+.\" This program is free software.
+.\"
+.\" 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 Joerg Wunsch
+.\" 4. The name of the developer may not be used to endorse or promote
+.\" products derived from this software without specific prior written
+.\" permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``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 DEVELOPERS 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.
+.\"
+.\" $Header: /cvs/OpenBSD/src/sys/arch/i386/isa/pcvt/Util/vgaio/Attic/vgaio.8,v 1.1 1995/10/18 08:50:49 deraadt Exp $
+.\"
+.Dd December 31, 1994
+.Dt VGAIO 8
+.Sh NAME
+.Nm vgaio
+.Nd perform input/output on a Video Graphics Array
+.Sh SYNOPSIS
+.Nm vgaio
+.Op Fl d
+.Op Fl f Ar devname
+.Sh DESCRIPTION
+.Ss Purpose
+.Nm Vgaio
+is used to perform register-level input/output on a Video Graphics Array.
+Since some of the sequences required to access those registers are very
+silly,
+.Nm vgaio
+cares of all the things necessary and allows the user to access the
+registers of several register groups with their symbolic names.
+
+.Ss Options
+.Bl -tag -width 10n -offset indent -compact
+.It Fl d
+Turn on the grammar parser debugger.
+
+.It Fl f Ar devname
+Operate on device
+.Ar devname
+instead of the default
+.Pa /dev/console .
+
+.El
+.Ss Command language
+The command language of
+.Nm
+constitutes of some very simple tokens and rules. Commands are executed
+line by line as they are entered. Each line may contain any number of
+semicolon-separated input/output commands.
+
+Symbolic register names look like:
+
+.D1 Ao Em reggroup Ac Ao Em regnumber Ac
+
+with
+.Aq Em regnumber
+being any hexadecimal number
+.Pq without a leading Em 0x ,
+and
+.Aq Em reggroup
+one of the strings
+.Dq Em ar ,
+.Dq Em cr ,
+.Dq Em gr ,
+.Dq Em mi ,
+or
+.Dq Em sr ,
+standing for the
+.Em Attribute controller ,
+.Em CRT controller ,
+.Em Graphics controller ,
+.Em Miscellaneous Output Register ,
+or
+.Em Timing sequencer ,
+respectively.
+
+An input instruction has the form
+
+.D1 Ao Em regname Ac ?
+
+and will cause
+.Nm
+to output a line like
+
+.Bd -ragged -offset indent
+.Ao Em regname Ac \& = 0x Ns
+.Aq Em number
+.Ed
+
+An output instruction looks like
+
+.Bd -ragged -offset indent
+.Ao Em regname Ac =
+.Aq Em number
+.Ed
+
+Spaces or Tabs between the
+.Aq Em reggroup ,
+the
+.Aq Em regnumber ,
+or any of the other tokens are ignored. They are not required anyway.
+
+The
+.Dq Em mi
+register does not require an argument
+.Aq Em regnumber ;
+it's actually being ignored.
+
+
+.Ss Access control
+The caller must have uid 0 in order to gain the required access to
+the IO registers.
+
+.Sh FILES
+.Pa /dev/console
+is used as the default device to enable access to the IO registers.
+
+.Sh HISTORY
+This program is considered
+.Dq hackware .
+It has been developed in order to simplify the process of developing other
+software that needs to program the Video Graphics Array.
+
+Remember, to use this program, your kernel has to be compiled with XSERVER
+being defined.
+
+.Sh AUTHOR
+The program has been contributed by
+.if n Joerg Wunsch,
+.if t J\(:org Wunsch,
+Dresden
+.Aq joerg_wunsch@uriah.heep.sax.de .
+
diff --git a/sys/arch/i386/isa/pcvt/Util/vgaio/vgaio.h b/sys/arch/i386/isa/pcvt/Util/vgaio/vgaio.h
new file mode 100644
index 00000000000..b2d09999282
--- /dev/null
+++ b/sys/arch/i386/isa/pcvt/Util/vgaio/vgaio.h
@@ -0,0 +1,71 @@
+/*
+ * Copyright (c) 1994 Joerg Wunsch
+ *
+ * All rights reserved.
+ *
+ * This program is free software.
+ *
+ * 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 Joerg Wunsch
+ * 4. The name of the developer may not be used to endorse or promote
+ * products derived from this software without specific prior written
+ * permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``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 DEVELOPERS 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.
+ */
+
+/*
+ * $Header
+ * The author may be reached unter <joerg_wunsch@uriah.sax.de>
+ *
+ * $Log: vgaio.h,v $
+ * Revision 1.1 1995/10/18 08:50:49 deraadt
+ * Initial revision
+ *
+ * Revision 1.3 1995/10/07 21:46:02 jtc
+ * Overlay our pcvt with pcvt 3.32 sources. All of our fixes have been
+ * incorporated into the master sources, so it is unnecessary to resolve
+ * all the conflicts that would occur if we let CVS "merge" the versions.
+ *
+ * Revision 1.2 1995/03/05 22:46:27 joerg
+ * Upgrade to beta 3.20/b22
+ *
+ * Revision 1.1 1994/03/29 02:47:25 mycroft
+ * pcvt 3.0, with some performance enhancements by Joerg Wunsch and me.
+ *
+ * Revision 1.2 1994/01/08 17:42:58 j
+ * cleanup
+ * made multiple commands per line work
+ * wrote man page
+ *
+ *
+ */
+
+/* common structure to hold the definition for a VGA register */
+
+#ifndef VGAIO_H
+#define VGAIO_H
+
+struct reg {
+ int group, num;
+};
+
+#endif /* VGAIO_H */
diff --git a/sys/arch/i386/isa/pcvt/Util/vgaio/vgaio.y b/sys/arch/i386/isa/pcvt/Util/vgaio/vgaio.y
new file mode 100644
index 00000000000..5bf47bebfa8
--- /dev/null
+++ b/sys/arch/i386/isa/pcvt/Util/vgaio/vgaio.y
@@ -0,0 +1,263 @@
+/* Hello emacs, this should be edited in -*- Fundamental -*- mode */
+%{
+/*
+ * Copyright (c) 1994,1995 Joerg Wunsch
+ *
+ * All rights reserved.
+ *
+ * This program is free software.
+ *
+ * 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 Joerg Wunsch
+ * 4. The name of the developer may not be used to endorse or promote
+ * products derived from this software without specific prior written
+ * permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``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 DEVELOPERS 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.
+ */
+
+#ident "$Header: /cvs/OpenBSD/src/sys/arch/i386/isa/pcvt/Util/vgaio/Attic/vgaio.y,v 1.1 1995/10/18 08:50:49 deraadt Exp $"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/fcntl.h>
+#include <machine/cpufunc.h>
+#include <machine/pcvt_ioctl.h>
+
+#ifdef __NetBSD__
+#include <machine/pio.h>
+#endif
+
+#include "vgaio.h"
+
+void setreg(struct reg r, int val);
+void getreg(struct reg r);
+void yyerror(const char *msg);
+
+#define YYDEBUG 1
+
+unsigned short vgabase;
+
+%}
+
+%union {
+ int num;
+ struct reg reg;
+}
+
+%token MI GR CR SR AR NEWLINE
+%token <num> NUM
+
+%type <num> reggroup
+%type <reg> register
+
+%%
+
+interpret: lines ;
+
+lines: line
+ | lines line
+ ;
+
+line: statements NEWLINE
+ | NEWLINE
+ | error NEWLINE { fprintf(stderr, "bing!\n"); }
+ ;
+
+statements: statement
+ | statements ';' statement
+ ;
+
+statement: register '?' { getreg($1); }
+ | register '=' NUM { setreg($1, $3); }
+ | /* lambda */
+ ;
+
+register: reggroup NUM { $$.num = $2; $$.group = $1; }
+ /* useful for the MI register: */
+ | reggroup { $$.num = 0; $$.group = $1; }
+ ;
+
+reggroup: GR { $$ = GR; }
+ | CR { $$ = CR; }
+ | SR { $$ = SR; }
+ | AR { $$ = AR; }
+ | MI { $$ = MI; }
+ ;
+
+%%
+
+static struct {
+ int id;
+ const char *name;
+} regnames[] = {
+ {GR, "gr"}, {CR, "cr"}, {SR, "sr"}, {AR, "ar"}, {MI, "mi"},
+ {0, 0}
+};
+
+const char *getname(struct reg r) {
+ int idx;
+ for(idx = 0; regnames[idx].id; idx++)
+ if(regnames[idx].id == r.group)
+ return regnames[idx].name;
+ return "??";
+}
+
+/* return ptr to string of 1s and 0s for value */
+char *
+bin_str(unsigned long val, int length) {
+ static char buffer[80];
+ int i = 0;
+
+ if (length > 32)
+ length = 32;
+
+ val = val << (32 - length);
+
+ while (length--)
+ {
+ if (val & 0x80000000)
+ buffer[i++] = '1';
+ else
+ buffer[i++] = '0';
+ if ((length % 4) == 0 && length)
+ buffer[i++] = '.';
+ val = val << 1;
+ }
+ return (buffer);
+}
+
+void getreg(struct reg r) {
+ int val; /* FreeBSD gcc ONLY accepts an int */
+
+ switch(r.group) {
+ case GR:
+ outb(0x3ce, r.num);
+ val = inb(0x3cf);
+ break;
+
+ case AR:
+ r.num &= 0x1f;
+ (void)inb(vgabase + 0x0a);
+ outb(0x3c0, r.num + 0x20);
+ val = inb(0x3c1);
+ break;
+
+ case CR:
+ outb(vgabase + 4, r.num);
+ val = inb(vgabase + 5);
+ break;
+
+ case SR:
+ outb(0x3c4, r.num);
+ val = inb(0x3c5);
+ break;
+
+ case MI:
+ val = inb(0x3cc);
+ break;
+ }
+
+ printf("%s%02x = 0x%02x = %sB\n",
+ getname(r), r.num, val, bin_str(val, 8));
+}
+
+void setreg(struct reg r, int val) {
+ switch(r.group) {
+ case GR:
+ outb(0x3ce, r.num);
+ outb(0x3cf, val);
+ break;
+
+ case AR:
+ r.num &= 0x1f;
+ (void)inb(vgabase + 0x0a);
+ outb(0x3c0, r.num);
+ outb(0x3c0, val);
+ outb(0x3c0, r.num + 0x20);
+ break;
+
+ case CR:
+ outb(vgabase + 4, r.num);
+ outb(vgabase + 5, val);
+ break;
+
+ case SR:
+ outb(0x3c4, r.num);
+ outb(0x3c5, val);
+ break;
+
+ case MI:
+ outb(0x3c2, val);
+ break;
+ }
+
+ printf("%s%02x set to 0x%02x = %sB now\n",
+ getname(r), r.num, val, bin_str(val, 8));
+}
+
+void yyerror(const char *msg) {
+ fprintf(stderr, "yyerror: %s\n", msg);
+}
+
+void usage(void) {
+ fprintf(stderr, "usage: vgaio [-d] [-f devname]\n");
+ exit(2);
+}
+
+int main(int argc, char **argv) {
+ int fd, c;
+ const char *devname = "/dev/console";
+
+ while((c = getopt(argc, argv, "df:")) != EOF)
+ switch(c) {
+ case 'd':
+ yydebug = 1;
+ break;
+
+ case 'f':
+ devname = optarg;
+ break;
+
+ case '?':
+ default:
+ usage();
+ }
+ argc -= optind;
+ argv += optind;
+ if(argc > 0)
+ usage();
+
+ if((fd = open(devname, O_RDONLY)) < 0) {
+ perror("open(vga)");
+ return 1;
+ }
+
+ if(ioctl(fd, KDENABIO, 0) < 0) {
+ perror("ioctl(KDENABIO)");
+ return 1;
+ }
+ vgabase = (inb(0x3cc) & 1)? 0x3d0: 0x3b0;
+ yyparse();
+
+ (void)ioctl(fd, KDDISABIO, 0);
+ return 0;
+}
diff --git a/sys/arch/i386/isa/pcvt/Util/vttest/Makefile b/sys/arch/i386/isa/pcvt/Util/vttest/Makefile
new file mode 100644
index 00000000000..c45d720e0c3
--- /dev/null
+++ b/sys/arch/i386/isa/pcvt/Util/vttest/Makefile
@@ -0,0 +1,5 @@
+PROG= vttest
+CFLAGS+= -traditional -DUSEMYSTTY
+SRCS= main.c esc.c
+
+.include <bsd.prog.mk>
diff --git a/sys/arch/i386/isa/pcvt/Util/vttest/README b/sys/arch/i386/isa/pcvt/Util/vttest/README
new file mode 100644
index 00000000000..589d08f2c1f
--- /dev/null
+++ b/sys/arch/i386/isa/pcvt/Util/vttest/README
@@ -0,0 +1,57 @@
+NOTES FROM THE MOD.SOURCES MODERATOR:
+I split the source up into the three separate pieces it now is.
+In doing this, I put lines like "int reading;" in a header file
+that both C modules include. If your Unix requires one of these
+to be "extern int reading;" then you will have some editing to do.
+Also note that this program uses FIONREAD, which must be implemented
+differently in SystemV, etc., and check out the setjmp() call...
+ /Rich $alz
+Oh, yeah: I also wrote the Makefile and manpage, such as they are.
+-------------------------------------------------------------------
+
+This is a program to test the compatibility (or to demonstrate the
+non-compatibility) of so-called "VT100-compatible" terminals. In
+conformance of the good old hacker traditions, the only documentation
+of this program is the source code itself. To understand it, you also
+need a copy of the original VT100 manual from DEC.
+
+Comments and bug reports: Since this is a release (via USENET) to the
+whole world, a lot of people are going to have opinions and fresh
+ideas about it. (What -- bugs in MY program? Aww...) I can't deal
+with everyone sending me a hacked version, but if you have found a
+serious bug, or ported it to VMS, do tell me. I can't promise any new
+version release, though. From this version on (1.7b) VTTEST will have
+to live its own life without its father holding its hand.
+
+My adress is:
+
+Network-mail adress: (mcvax,seismo)!enea!suadb!lindberg
+
+Real-world-mail address: Per Lindberg
+ QZ, Stockholm University Computing Center
+ Box 27322
+ S - 102 54 Stockholm
+ SWEDEN
+
+The original version of this program is written for the Sargasso C
+compiler for the DECsystem-10. Many thanks to all sales persons with
+quote VT100-compatible unquote terminals, who prompted me to write
+this program, and also to:
+
+-- Bo Kleve, LIDAC, Linkoping University, Sweden
+ for the portation to DECSYSTEM-20 with the Sargasso C compiler
+
+-- Johan Widen, TTDS, Royal Institute of Technology, Stockholm, Sweden
+ for the portation to various UNIX systems (incl. System III and Xenix)
+
+-- Russ Herman, AES Data Inc., Missisauga, Ont. Canada
+ for fixes and code for the VT102 test
+
+Thanx also to JMR "Gremlin" at KTH, and Goran Wallberg at QZ
+for suggestions, bug fixes, etc.
+
+This program does not have support for all the different variations
+of VT100, like VT125, VT131 nor the new VT200 series. Feel free to
+add that yourself. Happy Hacking!
+
+ /TMP
diff --git a/sys/arch/i386/isa/pcvt/Util/vttest/esc.c b/sys/arch/i386/isa/pcvt/Util/vttest/esc.c
new file mode 100644
index 00000000000..520946b5054
--- /dev/null
+++ b/sys/arch/i386/isa/pcvt/Util/vttest/esc.c
@@ -0,0 +1,398 @@
+#include "header.h"
+
+println(s) char *s; {
+ printf("%s\n", s);
+}
+
+esc(s) char *s; {
+ printf("%c%s", 27, s);
+}
+
+esc2(s1, s2) char s1, s2; {
+ printf("%c%s%s", 27, s1, s2);
+}
+
+brcstr(ps, c) char *ps, c; {
+ printf("%c[%s%c", 27, ps, c);
+}
+
+brc(pn,c) int pn; char c; {
+ printf("%c[%d%c", 27, pn, c);
+}
+
+brc2(pn1, pn2 ,c) int pn1, pn2; char c; {
+ printf("%c[%d;%d%c", 27, pn1, pn2, c);
+}
+
+cub(pn) int pn; { /* Cursor Backward */
+ brc(pn,'D');
+}
+cud(pn) int pn; { /* Cursor Down */
+ brc(pn,'B');
+}
+cuf(pn) int pn; { /* Cursor Forward */
+ brc(pn,'C');
+}
+cup(pn1, pn2) int pn1, pn2; { /* Cursor Position */
+ brc2(pn1, pn2, 'H');
+}
+cuu(pn) int pn; { /* Cursor Up */
+ brc(pn,'A');
+}
+da() { /* Device Attributes */
+ brc(0,'c');
+}
+decaln() { /* Screen Alignment Display */
+ esc("#8");
+}
+decdhl(lower) int lower; { /* Double Height Line (also double width) */
+ if (lower) esc("#4");
+ else esc("#3");
+}
+decdwl() { /* Double Wide Line */
+ esc("#6");
+}
+deckpam() { /* Keypad Application Mode */
+ esc("=");
+}
+deckpnm() { /* Keypad Numeric Mode */
+ esc(">");
+}
+decll(ps) char *ps; { /* Load LEDs */
+ brcstr(ps, 'q');
+}
+decrc() { /* Restore Cursor */
+ esc("8");
+}
+decreqtparm(pn) int pn; { /* Request Terminal Parameters */
+ brc(pn,'x');
+}
+decsc() { /* Save Cursor */
+ esc("7");
+}
+decstbm(pn1, pn2) int pn1, pn2; { /* Set Top and Bottom Margins */
+ if (pn1 || pn2) brc2(pn1, pn2, 'r');
+ else esc("[r");
+ /* Good for >24-line terminals */
+}
+decswl() { /* Single With Line */
+ esc("#5");
+}
+dectst(pn) int pn; { /* Invoke Confidence Test */
+ brc2(2, pn, 'y');
+}
+dsr(pn) int pn; { /* Device Status Report */
+ brc(pn, 'n');
+}
+ed(pn) int pn; { /* Erase in Display */
+ brc(pn, 'J');
+}
+el(pn) int pn; { /* Erase in Line */
+ brc(pn,'K');
+}
+hts() { /* Horizontal Tabulation Set */
+ esc("H");
+}
+hvp(pn1, pn2) int pn1, pn2; { /* Horizontal and Vertical Position */
+ brc2(pn1, pn2, 'f');
+}
+ind() { /* Index */
+ esc("D");
+}
+nel() { /* Next Line */
+ esc("E");
+}
+ri() { /* Reverse Index */
+ esc("M");
+}
+ris() { /* Reset to Initial State */
+ esc("c");
+}
+rm(ps) char *ps; { /* Reset Mode */
+ brcstr(ps, 'l');
+}
+scs(g,c) int g; char c; { /* Select character Set */
+ printf("%c%c%c%c%c%c%c", 27, g ? ')' : '(', c,
+ 27, g ? '(' : ')', 'B',
+ g ? 14 : 15);
+}
+sgr(ps) char *ps; { /* Select Graphic Rendition */
+ brcstr(ps, 'm');
+}
+sm(ps) char *ps; { /* Set Mode */
+ brcstr(ps, 'h');
+}
+tbc(pn) int pn; { /* Tabulation Clear */
+ brc(pn, 'g');
+}
+
+vt52cup(l,c) int l,c; {
+ printf("%cY%c%c", 27, l + 31, c + 31);
+}
+
+char inchar() {
+
+ /*
+ * Wait until a character is typed on the terminal
+ * then read it, without waiting for CR.
+ */
+
+#ifdef UNIX
+ int lval, waittime, getpid(); static int val; char ch;
+
+ fflush(stdout);
+ lval = val;
+ brkrd = 0;
+ reading = 1;
+ read(0,&ch,1);
+ reading = 0;
+ if (brkrd)
+ val = 0177;
+ else
+ val = ch;
+ if ((val==0177) && (val==lval))
+ kill(getpid(), (int) SIGTERM);
+#endif
+#ifdef SARG10
+ int val, waittime;
+
+ waittime = 0;
+ while(!uuo(051,2,&val)) { /* TTCALL 2, (INCHRS) */
+ zleep(100); /* Wait 0.1 seconds */
+ if ((waittime += ttymode) > 600) /* Time-out, in case */
+ return('\177'); /* of hung in ttybin(1) */
+ }
+#endif
+#ifdef SARG20 /* try to fix a time-out function */
+ int val, waittime;
+
+ waittime = 0;
+ while(jsys(SIBE,2,_PRIIN) == 0) { /* Is input empty? */
+ zleep(100);
+ if ((waittime += ttymode) > 600)
+ return('\177');
+ }
+ ejsys(BIN,_PRIIN);
+ val = jsac[2];
+#endif
+ return(val);
+}
+
+char *instr() {
+
+ /*
+ * Get an unfinished string from the terminal:
+ * wait until a character is typed on the terminal,
+ * then read it, and all other available characters.
+ * Return a pointer to that string.
+ */
+
+
+ int i, val, crflag; long l1; char ch;
+ static char result[80];
+
+ i = 0;
+ result[i++] = inchar();
+/* Wait 0.1 seconds (1 second in vanilla UNIX) */
+#ifdef SARG10
+ if (trmop(01031,0) < 5) zleep(500); /* wait longer if low speed */
+ else zleep(100);
+#else
+ zleep(100);
+#endif
+#ifdef UNIX
+ fflush(stdout);
+#ifdef XENIX
+ while(rdchk(0)) {
+ read(0,result+i,1);
+ if (i++ == 78) break;
+ }
+#else
+#ifdef SIII
+ while(read(2,result+i,1) == 1)
+ if (i++ == 78) break;
+#else
+ while(ioctl(0,FIONREAD,&l1), l1 > 0L) {
+ while(l1-- > 0L) {
+ read(0,result+i,1);
+ if (i++ == 78) goto out1;
+ }
+ }
+out1:
+#endif
+#endif
+#endif
+#ifdef SARG10
+ while(uuo(051,2,&val)) { /* TTCALL 2, (INCHRS) */
+ if (!(val == '\012' && crflag)) /* TOPS-10 adds LF to CR */
+ result[i++] = val;
+ crflag = val == '\015';
+ if (i == 79) break;
+ zleep(50); /* Wait 0.05 seconds */
+ }
+#endif
+#ifdef SARG20
+ while(jsys(SIBE,2,_PRIIN) != 0) { /* read input until buffer is empty */
+ ejsys(BIN,_PRIIN);
+ result[i++] = jsac[2];
+ if (i == 79) break;
+ zleep(50); /* Wait 0.05 seconds */
+ }
+#endif
+ result[i] = '\0';
+ return(result);
+}
+
+ttybin(bin) int bin; {
+#ifdef SARG10
+ #define OPEN 050
+ #define IO_MOD 0000017
+ #define _IOPIM 2
+ #define _IOASC 0
+ #define _TOPAG 01021
+ #define _TOSET 01000
+
+ int v;
+ static int arglst[] = {
+ _IOPIM,
+ `TTY`,
+ 0
+ };
+ arglst[0] = bin ? _IOPIM : _IOASC;
+ v = uuo(OPEN, 1, &arglst[0]);
+ if (!v) { printf("OPEN failed"); exit(); }
+ trmop(_TOPAG + _TOSET, bin ? 0 : 1);
+ ttymode = bin;
+#endif
+#ifdef SARG20
+ /* TTYBIN will set the line in BINARY/ASCII mode
+ * BINARY mode is needed to send control characters
+ * Bit 28 must be 0 (we don't flip it).
+ * Bit 29 is used for the mode change.
+ */
+
+ #define _TTASC 0000100
+ #define _MOXOF 0000043
+
+ int v;
+
+ ejsys(RFMOD,_CTTRM);
+ v = ejsys(SFMOD,_CTTRM, bin ? (~_TTASC & jsac[2]) : (_TTASC | jsac[2]));
+ if (v) { printf("SFMOD failed"); exit(); }
+ v = ejsys(MTOPR,_CTTRM,_MOXOF,0);
+ if (v) { printf("MTOPR failed"); exit(); }
+#endif
+}
+
+#ifdef SARG20
+/*
+ * SUPERBIN turns off/on all input character interrupts
+ * This affects ^C, ^O, ^T
+ * Beware where and how you use it !!!!!!!
+ */
+
+superbin(bin) int bin; {
+ int v;
+
+ v = ejsys(STIW,(0//-5), bin ? 0 : -1);
+ if (v) { printf("STIW superbinary setting failed"); exit(); }
+ ttymode = bin;
+}
+
+/*
+ * PAGE affects the ^S/^Q handshake.
+ * Set bit 34 to turn it on. Clear it for off.
+ */
+
+page(bin) int bin; {
+ int v;
+
+ #define TT_PGM 0000002
+
+ ejsys(RFMOD,_CTTRM); /* Get the current terminal status */
+ v = ejsys(STPAR,_CTTRM, bin ? (TT_PGM | jsac[2]) : (~TT_PGM & jsac[2]));
+ if (v) { printf("STPAR failed"); exit(); }
+}
+#endif
+
+trmop(fc,arg) int fc, arg; {
+#ifdef SARG10
+ int retvalp;
+ int arglst[3];
+
+ /* TRMOP is a TOPS-10 monitor call that does things to the terminal. */
+
+ /* Find out TTY nbr (PA1050 barfs if TRMOP get -1 instead of udx) */
+ /* A TRMNO monitor call returns the udx (Universal Device Index) */
+
+ arglst[0] = fc; /* function code */
+ arglst[1] = calli(0115, -1); /* udx, TRMNO. UUO */
+ arglst[2] = arg; /* Optional argument */
+
+ if (calli(0116, 3 // &arglst[0], &retvalp)) /* TRMOP. UUO */
+ return (retvalp);
+ else {
+ printf("?Error return in TRMOP.");
+ exit();
+ }
+#endif
+}
+
+inputline(s) char *s; {
+ scanf("%s",s);
+#ifdef SARG10
+ readnl();
+#endif
+#ifdef SARG20
+ readnl();
+#endif
+}
+
+inflush() {
+
+ /*
+ * Flush input buffer, make sure no pending input character
+ */
+
+ int val;
+
+#ifdef UNIX
+#ifdef XENIX
+ while(rdchk(0)) read(0,&val,1);
+#else
+#ifdef SIII
+ while(read(2,&val,1));
+#else
+ long l1;
+ ioctl (0, FIONREAD, &l1);
+ while(l1-- > 0L) read(0,&val,1);
+#endif
+#endif
+#endif
+#ifdef SARG10
+ while(uuo(051,2,&val)) /* TTCALL 2, (INCHRS) */
+ ;
+#endif
+#ifdef SARG20
+ ejsys(CFIBF,_PRIIN); /* Clear input buffer */
+#endif
+}
+
+zleep(t) int t; {
+
+/*
+ * Sleep and do nothing (don't waste CPU) for t milliseconds
+ */
+
+#ifdef SARG10
+ calli(072,t); /* (HIBER) t milliseconds */
+#endif
+#ifdef SARG20
+ ejsys(DISMS,t); /* DISMISS for t milliseconds */
+#endif
+#ifdef UNIX
+ t = t / 1000;
+ if (t == 0) t = 1;
+ sleep(t); /* UNIX can only sleep whole seconds */
+#endif
+}
diff --git a/sys/arch/i386/isa/pcvt/Util/vttest/header.h b/sys/arch/i386/isa/pcvt/Util/vttest/header.h
new file mode 100644
index 00000000000..c4dcf906e83
--- /dev/null
+++ b/sys/arch/i386/isa/pcvt/Util/vttest/header.h
@@ -0,0 +1,43 @@
+#define VERSION "1.7b 1985-04-19"
+
+/* Choose one of these */
+
+/* #define XENIX /* XENIX implies UNIX */
+/* #define SIII /* SIII implies UNIX, (NDELAY a la System III) */
+#define UNIX /* UNIX */
+/* #define VMS /* VMS not done yet -- send me your version!!!! */
+/* #define SARG20 /* Sargasso C for TOPS-20 */
+/* #define SARG10 /* Sargasso C for TOPS-10 */
+
+/* These #ifdef:s are implementation dependent stuff for the Sargasso C */
+/* Unix C barfs on directives like "#strings", so we keep them */
+/* indented. Then unix c can't find them, but Sargasso C *can*. */
+/* Admittedly kludgey, but it works...) */
+#ifdef SARG10
+ #define _UNIXCON /* Make UNIX-flavored I/O on TOPS */
+ #strings low /* put strings in lowseg mem so we can modify them. */
+#endif
+#ifdef SARG20
+ #define _UNIXCON /* Make UNIX-flavored I/O on TOPS */
+ #strings low /* put strings in lowseg mem so we can modify them. */
+ #include <TOPS20.HDR>
+#endif
+
+#include <stdio.h>
+
+
+#ifdef UNIX
+#include <ctype.h>
+#include <sgtty.h>
+#include <signal.h>
+#include <setjmp.h>
+jmp_buf intrenv;
+struct sgttyb sgttyOrg, sgttyNew;
+char stdioBuf[BUFSIZ];
+int brkrd, reading;
+extern onterm(), onbrk();
+#ifdef SIII
+#include <fcntl.h>
+#endif
+#endif
+int ttymode;
diff --git a/sys/arch/i386/isa/pcvt/Util/vttest/main.c b/sys/arch/i386/isa/pcvt/Util/vttest/main.c
new file mode 100644
index 00000000000..cb67f745abc
--- /dev/null
+++ b/sys/arch/i386/isa/pcvt/Util/vttest/main.c
@@ -0,0 +1,2016 @@
+/*
+ VTTEST.C
+
+ Written Novemeber 1983 - July 1984 by Per Lindberg,
+ Stockholm University Computer Center (QZ), Sweden.
+
+ THE MAD PROGRAMMER STRIKES AGAIN!
+
+ This software is (c) 1984 by QZ
+ Non-commercial use and copying allowed.
+
+If you are developing a commercial product, and use this program to do
+it, and that product is successful, please send a sum of money of your
+choice to the address below.
+
+*/
+
+#include "header.h"
+
+char inchar(), *instr(), *lookup();
+
+struct table {
+ int key;
+ char *msg;
+} paritytable[] = {
+ { 1, "NONE" },
+ { 4, "ODD" },
+ { 5, "EVEN" },
+ { -1, "" }
+},nbitstable[] = {
+ { 1, "8" },
+ { 2, "7" },
+ { -1,"" }
+},speedtable[] = {
+ { 0, "50" },
+ { 8, "75" },
+ { 16, "110" },
+ { 24, "132.5"},
+ { 32, "150" },
+ { 40, "200" },
+ { 48, "300" },
+ { 56, "600" },
+ { 64, "1200" },
+ { 72, "1800" },
+ { 80, "2000" },
+ { 88, "2400" },
+ { 96, "3600" },
+ { 104, "4800" },
+ { 112, "9600" },
+ { 120, "19200" },
+ { -1, "" }
+};
+
+#ifdef USEMYSTTY
+#ifndef stty
+int stty(fd,ptr)
+int fd;
+struct sgttyb *ptr;
+{
+ return(ioctl(fd, TIOCSETP, ptr));
+}
+#endif
+#ifndef gtty
+int gtty(fd,ptr)
+int fd;
+struct sgttyb *ptr;
+{
+ return(ioctl(fd, TIOCGETP, ptr));
+}
+#endif
+#endif
+
+main() {
+
+ int menuchoice;
+
+ static char *mainmenu[] = {
+ "Exit",
+ "Test of cursor movements",
+ "Test of screen features",
+ "Test of character sets",
+ "Test of double-sized characters",
+ "Test of keyboard",
+ "Test of terminal reports",
+ "Test of VT52 mode",
+ "Test of VT102 features (Insert/Delete Char/Line)",
+ "Test of known bugs",
+ "Test of reset and self-test",
+ ""
+ };
+
+#ifdef UNIX
+ initterminal(setjmp(intrenv));
+ signal(SIGINT, onbrk);
+ signal(SIGTERM, onterm);
+ reading = 0;
+#else
+ initterminal(0);
+#endif
+ do {
+#ifdef SARG20
+ ttybin(1); /* set line to binary mode again. It's reset somehow!! */
+#endif
+ ed(2);
+ cup(5,10); printf("VT100 test program, version %s", VERSION);
+ cup(7,10); println("Choose test type:");
+ menuchoice = menu(mainmenu);
+ switch (menuchoice) {
+ case 1: tst_movements(); break;
+ case 2: tst_screen(); break;
+ case 3: tst_characters(); break;
+ case 4: tst_doublesize(); break;
+ case 5: tst_keyboard(); break;
+ case 6: tst_reports(); break;
+ case 7: tst_vt52(); break;
+ case 8: tst_insdel(); break;
+ case 9: tst_bugs(); break;
+ case 10: tst_rst(); break;
+ }
+ } while (menuchoice);
+ bye();
+}
+
+tst_movements() {
+
+ /* Test of:
+ CUF (Cursor Forward)
+ CUB (Cursor Backward)
+ CUD (Cursor Down) IND (Index) NEL (Next Line)
+ CUU (Cursor Up) RI (Reverse Index)
+ CUP (Cursor Position) HVP (Horizontal and Vertical Position)
+ ED (Erase in Display)
+ EL (Erase in Line)
+ DECALN (Screen Alignment Display)
+ <CR> <BS>
+ Cursor control characters inside CSI sequences
+ */
+
+ int i, row, col, pass, width, hlfxtra;
+ char c, *ctext = "This is a correct sentence";
+
+ for (pass = 0; pass <= 1; pass++) {
+ if (pass == 0) { rm("?3"); width = 80; hlfxtra = 0; }
+ else { sm("?3"); width = 132; hlfxtra = 26; }
+
+ decaln();
+ cup( 9,10+hlfxtra); ed(1);
+ cup(18,60+hlfxtra); ed(0); el(1);
+ cup( 9,71+hlfxtra); el(0);
+ for (row = 10; row <= 16; row++) {
+ cup(row, 10+hlfxtra); el(1);
+ cup(row, 71+hlfxtra); el(0);
+ }
+ cup(17,30); el(2);
+ for (col = 1; col <= width; col++) {
+ hvp(24, col); printf("*");
+ hvp( 1, col); printf("*");
+ }
+ cup(2,2);
+ for (row = 2; row <= 23; row++) {
+ printf("+");
+ cub(1);
+ ind();
+ }
+ cup(23,width-1);
+ for (row = 23; row >=2; row--) {
+ printf("+");
+ cub(1); ri();
+ }
+ cup(2,1);
+ for (row = 2; row <= 23; row++) {
+ printf("*");
+ cup(row, width);
+ printf("*");
+ cub(10);
+ if(row < 10)
+ nel();
+ else
+ printf("\n");
+ }
+ cup(2,10);
+ cub(42+hlfxtra); cuf(2);
+ for (col = 3; col <= width-2; col++) {
+ printf("+");
+ cuf(0); cub(2); cuf(1);
+ }
+ cup(23,70+hlfxtra);
+ cuf(42+hlfxtra); cub(2);
+ for (col = width-2; col >= 3; col--) {
+ printf("+");
+ cub(1); cuf(1); cub(0); printf("%c", 8);
+ }
+ cup( 1, 1); cuu(10); cuu(1); cuu(0);
+ cup(24,width); cud(10); cud(1); cud(0);
+
+ cup(10,12+hlfxtra);
+ for (row = 10; row <= 15; row++) {
+ for (col = 12+hlfxtra; col <= 69+hlfxtra; col++) printf(" ");
+ cud(1); cub(58);
+ }
+ cuu(5); cuf(1);
+ printf("The screen should be cleared, and have an unbroken bor-");
+ cup(12,13+hlfxtra);
+ printf("der of *'s and +'s around the edge, and exactly in the");
+ cup(13,13+hlfxtra);
+ printf("middle there should be a frame of E's around this text");
+ cup(14,13+hlfxtra);
+ printf("with one (1) free position around it. ");
+ holdit();
+ }
+ rm("?3");
+
+ ed(2);
+ cup(1,1);
+ println("Test of cursor-control characters inside ESC sequences.");
+ println("Below should be two identical lines:");
+ println("");
+ println("A B C D E F G H I J K L M N O P Q R S");
+ for (i = 1; i < 20; i++) {
+ printf("%c", 64 + i);
+ brcstr("2\010", 'C'); /* Two forward, one backspace */
+ }
+ println("");
+ println("");
+ holdit();
+
+ ed(2);
+ cup(1,1);
+ println("Test of leading zeros in ESC sequences.");
+ printf("Two lines below you should see the sentence \"%s\".",ctext);
+ for (col = 1; *ctext; col++)
+ printf("\033[00000000004;00000000%dH%c",col,*ctext++);
+ cup(20,1);
+ holdit();
+}
+
+tst_screen() {
+
+ /* Test of:
+ - DECSTBM (Set Top and Bottom Margins)
+ - TBC (Tabulation Clear)
+ - HTS (Horizontal Tabulation Set)
+ - SM RM (Set/Reset mode): - 80/132 chars
+ - Origin: Realtive/absolute
+ - Scroll: Smooth/jump
+ - Wraparound
+ - SGR (Select Graphic Rendition)
+ - SM RM (Set/Reset Mode) - Inverse
+ - DECSC (Save Cursor)
+ - DECRC (Restore Cursor)
+ */
+
+ int i, j, cset, row, col, down, soft, background;
+
+ static char *tststr = "*qx`";
+ static char *attr[5] = { ";0", ";1", ";4", ";5", ";7" };
+
+ cup(1,1);
+ sm("?7"); /* Wrap Around ON */
+ for (col = 1; col <= 160; col++) printf("*");
+ rm("?7"); /* Wrap Around OFF */
+ cup(3,1);
+ for (col = 1; col <= 160; col++) printf("*");
+ sm("?7"); /* Wrap Around ON */
+ cup(5,1);
+ println("This should be three identical lines of *'s completely filling");
+ println("the top of the screen without any empty lines between.");
+ println("(Test of WRAP AROUND mode setting.)");
+ holdit();
+
+ ed(2);
+ tbc(3);
+ cup(1,1);
+ for (col = 1; col <= 78; col += 3) {
+ cuf(3); hts();
+ }
+ cup(1,4);
+ for (col = 4; col <= 78; col += 6) {
+ tbc(0); cuf(6);
+ }
+ cup(1,7); tbc(1); tbc(2); /* no-op */
+ cup(1,1); for (col = 1; col <= 78; col += 6) printf("\t*");
+ cup(2,2); for (col = 2; col <= 78; col += 6) printf(" *");
+ cup(4,1);
+ println("Test of TAB setting/resetting. These two lines");
+ printf("should look the same. ");
+ holdit();
+ for (background = 0; background <= 1; background++) {
+ if (background) rm("?5");
+ else sm("?5");
+ sm("?3"); /* 132 cols */
+ ed(2); /* VT100 clears screen on SM3/RM3, but not obviously, so... */
+ cup(1,1); tbc(3);
+ for (col = 1; col <= 132; col += 8) {
+ cuf(8); hts();
+ }
+ cup(1,1); for (col = 1; col <= 130; col += 10) printf("1234567890");
+ printf("12");
+ for (row = 3; row <= 20; row++) {
+ cup(row,row);
+ printf("This is 132 column mode, %s background.",
+ background ? "dark" : "light");
+ }
+ holdit();
+ rm("?3"); /* 80 cols */
+ ed(2); /* VT100 clears screen on SM3/RM3, but not obviously, so... */
+ cup(1,1); for (col = 1; col <= 80; col += 10) printf("1234567890");
+ for (row = 3; row <= 20; row++) {
+ cup(row,row);
+ printf("This is 80 column mode, %s background.",
+ background ? "dark" : "light");
+ }
+ holdit();
+ }
+
+ ed(2);
+ sm("?6"); /* Origin mode (relative) */
+ for (soft = -1; soft <= 0; soft++) {
+ if (soft) sm("?4");
+ else rm("?4");
+ for (row = 12; row >= 1; row -= 11) {
+ decstbm(row, 24-row+1);
+ ed(2);
+ for (down = 0; down >= -1; down--) {
+ if (down) cuu(24);
+ else cud(24);
+ for (i = 1; i <= 30; i++) {
+ printf("%s scroll %s region %d Line %d\n",
+ soft ? "Soft" : "Jump",
+ down ? "down" : "up",
+ 2*(13-row), i);
+ if (down) { ri(); ri(); }
+ }
+ }
+ holdit();
+ }
+ }
+ ed(2);
+ decstbm(23,24);
+ printf(
+ "\nOrigin mode test. This line should be at the bottom of the screen.");
+ cup(1,1);
+ printf("%s",
+ "This line should be the one above the bottom of the screeen. ");
+ holdit();
+ ed(2);
+ rm("?6"); /* Origin mode (absolute) */
+ cup(24,1);
+ printf(
+ "Origin mode test. This line should be at the bottom of the screen.");
+ cup(1,1);
+ printf("%s", "This line should be at the top if the screen. ");
+ holdit();
+ decstbm(1,24);
+
+ ed(2);
+ cup( 1,20); printf("Graphic rendition test pattern:");
+ cup( 4, 1); sgr("0"); printf("vanilla");
+ cup( 4,40); sgr("0;1"); printf("bold");
+ cup( 6, 6); sgr(";4"); printf("underline");
+ cup( 6,45);sgr(";1");sgr("4");printf("bold underline");
+ cup( 8, 1); sgr("0;5"); printf("blink");
+ cup( 8,40); sgr("0;5;1"); printf("bold blink");
+ cup(10, 6); sgr("0;4;5"); printf("underline blink");
+ cup(10,45); sgr("0;1;4;5"); printf("bold underline blink");
+ cup(12, 1); sgr("1;4;5;0;7"); printf("negative");
+ cup(12,40); sgr("0;1;7"); printf("bold negative");
+ cup(14, 6); sgr("0;4;7"); printf("underline negative");
+ cup(14,45); sgr("0;1;4;7"); printf("bold underline negative");
+ cup(16, 1); sgr("1;4;;5;7"); printf("blink negative");
+ cup(16,40); sgr("0;1;5;7"); printf("bold blink negative");
+ cup(18, 6); sgr("0;4;5;7"); printf("underline blink negative");
+ cup(18,45); sgr("0;1;4;5;7"); printf("bold underline blink negative");
+ sgr("");
+
+ rm("?5"); /* Inverse video off */
+ cup(23,1); el(0); printf("Dark background. "); holdit();
+ sm("?5"); /* Inverse video */
+ cup(23,1); el(0); printf("Light background. "); holdit();
+ rm("?5");
+ ed(2);
+ cup(8,12); printf("normal");
+ cup(8,24); printf("bold");
+ cup(8,36); printf("underscored");
+ cup(8,48); printf("blinking");
+ cup(8,60); printf("reversed");
+ cup(10,1); printf("stars:");
+ cup(12,1); printf("line:");
+ cup(14,1); printf("x'es:");
+ cup(16,1); printf("diamonds:");
+ for (cset = 0; cset <= 3; cset++) {
+ for (i = 0; i <= 4; i++) {
+ cup(10 + 2 * cset, 12 + 12 * i);
+ sgr(attr[i]);
+ if (cset == 0 || cset == 2) scs(0,'B');
+ else scs(0,'0');
+ for (j = 0; j <= 4; j++) {
+ printf("%c", tststr[cset]);
+ }
+ decsc();
+ cup(cset + 1, i + 1); sgr(""); scs(0,'B'); printf("A");
+ decrc();
+ for (j = 0; j <= 4; j++) {
+ printf("%c", tststr[cset]);
+ }
+ }
+ }
+ sgr("0"); scs(0,'B'); cup(21,1);
+ println("Test of the SAVE/RESTORE CURSOR feature. There should");
+ println("be ten characters of each flavour, and a rectangle");
+ println("of 5 x 4 A's filling the top left of the screen.");
+ holdit();
+}
+
+tst_characters() {
+ /* Test of:
+ SCS (Select character Set)
+ */
+
+ int i, j, g, cset;
+ char chcode[5], *setmsg[5];
+
+ chcode[0] = 'A';
+ chcode[1] = 'B';
+ chcode[2] = '0';
+ chcode[3] = '1';
+ chcode[4] = '2';
+ setmsg[0] = "UK / national";
+ setmsg[1] = "US ASCII";
+ setmsg[2] = "Special graphics and line drawing";
+ setmsg[3] = "Alternate character ROM standard characters";
+ setmsg[4] = "Alternate character ROM special graphics";
+
+ cup(1,10); printf("Selected as G0 (with SI)");
+ cup(1,48); printf("Selected as G1 (with SO)");
+ for (cset = 0; cset <= 4; cset++) {
+ scs(1,'B');
+ cup(3 + 4 * cset, 1);
+ sgr("1");
+ printf("Character set %c (%s)",chcode[cset], setmsg[cset]);
+ sgr("0");
+ for (g = 0; g <= 1; g++) {
+ scs(g,chcode[cset]);
+ for (i = 1; i <= 3; i++) {
+ cup(3 + 4 * cset + i, 10 + 38 * g);
+ for (j = 0; j <= 31; j++) {
+ printf("%c", i * 32 + j);
+ }
+ }
+ }
+ }
+ scs(1,'B');
+ cup(24,1); printf("These are the installed character sets. ");
+ holdit();
+}
+
+tst_doublesize() {
+ /* Test of:
+ DECSWL (Single Width Line)
+ DECDWL (Double Width Line)
+ DECDHL (Double Height Line) (also implicit double width)
+ */
+
+ int col, i, w, w1;
+
+ /* Print the test pattern in both 80 and 132 character width */
+
+ for(w = 0; w <= 1; w++) {
+ w1 = 13 * w;
+
+ ed(2);
+ cup(1, 1);
+ if (w) { sm("?3"); printf("132 column mode"); }
+ else { rm("?3"); printf(" 80 column mode"); }
+
+ cup( 5, 3 + 2 * w1);
+ printf("v------- left margin");
+
+ cup( 7, 3 + 2 * w1);
+ printf("This is a normal-sized line");
+ decdhl(0); decdhl(1); decdwl(); decswl();
+
+ cup( 9, 2 + w1);
+ printf("This is a Double-width line");
+ decswl(); decdhl(0); decdhl(1); decdwl();
+
+ cup(11, 2 + w1);
+ decdwl(); decswl(); decdhl(1); decdhl(0);
+ printf("This is a Double-width-and-height line");
+ cup(12, 2 + w1);
+ decdwl(); decswl(); decdhl(0); decdhl(1);
+ printf("This is a Double-width-and-height line");
+
+ cup(14, 2 + w1);
+ decdwl(); decswl(); decdhl(1); decdhl(0); el(2);
+ printf("This is another such line");
+ cup(15, 2 + w1);
+ decdwl(); decswl(); decdhl(0); decdhl(1);
+ printf("This is another such line");
+
+ cup(17, 3 + 2 * w1);
+ printf("^------- left margin");
+
+ cup(21, 1);
+ printf("This is not a double-width line");
+ for (i = 0; i <= 1; i++) {
+ cup(21,6);
+ if (i) { printf("**is**"); decdwl(); }
+ else { printf("is not"); decswl(); }
+ cup(23,1); holdit();
+ }
+ }
+ /* Set vanilla tabs for next test */
+ cup(1,1); tbc(3); for (col = 1; col <= 132; col += 8) { cuf(8); hts(); }
+ rm("?3");
+ ed(2);
+ scs(0,'0');
+
+ cup( 8,1); decdhl(0); printf("lqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqk");
+ cup( 9,1); decdhl(1); printf("lqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqk");
+ cup(10,1); decdhl(0); printf("x%c%c%c%c%cx",9,9,9,9,9);
+ cup(11,1); decdhl(1); printf("x%c%c%c%c%cx",9,9,9,9,9);
+ cup(12,1); decdhl(0); printf("x%c%c%c%c%cx",9,9,9,9,9);
+ cup(13,1); decdhl(1); printf("x%c%c%c%c%cx",9,9,9,9,9);
+ cup(14,1); decdhl(0); printf("x x");
+ cup(15,1); decdhl(1); printf("x x");
+ cup(16,1); decdhl(0); printf("mqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqj");
+ cup(17,1); decdhl(1); printf("mqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqj");
+ scs(0,'B'); sgr("1;5");
+ cup(12,3);
+ printf("* The mad programmer strikes again * ");
+ cup(13,3); printf("%c",9); cub(6);
+ printf("* The mad programmer strikes again *");
+ sgr("0");
+ cup(22,1);
+ println("Another test pattern... a frame with blinking bold text,");
+ printf("all in double-height double-width size. ");
+ holdit();
+
+ decstbm(8,24); /* Absolute origin mode, so cursor is set at (1,1) */
+ cup(8,1);
+ for (i = 1; i <= 12; i++)
+ ri();
+ decstbm(0,0); /* No scroll region */
+ cup(1,1);
+ printf("%s", "Exactly half of the box should remain. ");
+ holdit();
+}
+
+tst_keyboard() {
+
+/* Test of:
+ - DECLL (Load LEDs)
+ - Keyboard return messages
+ - SM RM (Set/Reset Mode) - Cursor Keys
+ - Auto repeat
+ - DECKPAM (Keypad Application Mode)
+ - DECKPNM (Keypad Numeric Mode)
+
+The standard VT100 keayboard layout:
+
+ UP DN LE RI
+
+ESC 1! 2@ 3# 4$ 5% 6^ 7& 8* 9( 0) -_ =+ `~ BS
+
+TAB* qQ wW eE rR tT yY uU iI oO pP [{ ]} DEL
+
+** ** aA sS dD fF gG hH jJ kK lL ;: ," RETN \|
+
+** **** zZ xX cC vV bB nN mM ,< .> /? **** LF
+
+ ****************SPACE BAR****************
+
+ PF1 PF2 PF3 PF4
+
+ *7* *8* *9* *-*
+
+ *4* *5* *6* *,*
+
+ *1* *2* *3*
+
+ ***0*** *.* ENT
+*/
+
+ char *ledmsg[6], *ledseq[6];
+
+ int i, j, okflag;
+ int kblayout;
+ int ckeymode;
+ int fkeymode;
+ char kbdc;
+ char *kbds = " ";
+ char *curkeystr, *fnkeystr, *abmstr;
+ char arptstring[500];
+
+ static struct key {
+ char c;
+ int row;
+ int col;
+ char *symbol;
+ } keytab [] = {
+ { 27, 1, 0, "ESC" },
+ { '1', 1, 6, "1" }, { '!', 1, 7, "!" },
+ { '2', 1, 11, "2" }, { '@', 1, 12, "@" },
+ { '3', 1, 16, "3" }, { '#', 1, 17, "#" },
+ { '4', 1, 21, "4" }, { '$', 1, 22, "$" },
+ { '5', 1, 26, "5" }, { '%', 1, 27, "%" },
+ { '6', 1, 31, "6" }, { '^', 1, 32, "^" },
+ { '7', 1, 36, "7" }, { '&', 1, 37, "&" },
+ { '8', 1, 41, "8" }, { '*', 1, 42, "*" },
+ { '9', 1, 46, "9" }, { '(', 1, 47, "(" },
+ { '0', 1, 51, "0" }, { ')', 1, 52, ")" },
+ { '-', 1, 56, "-" }, { '_', 1, 57, "_" },
+ { '=', 1, 61, "=" }, { '+', 1, 62, "+" },
+ { '`', 1, 66, "`" }, { '~', 1, 67, "~" },
+ { 8, 1, 70, "BS" },
+ { 9, 2, 0, " TAB " },
+ { 'q', 2, 8, "q" }, { 'Q', 2, 9, "Q" },
+ { 'w', 2, 13, "w" }, { 'W', 2, 14, "W" },
+ { 'e', 2, 18, "e" }, { 'E', 2, 19, "E" },
+ { 'r', 2, 23, "r" }, { 'R', 2, 24, "R" },
+ { 't', 2, 28, "t" }, { 'T', 2, 29, "T" },
+ { 'y', 2, 33, "y" }, { 'Y', 2, 34, "Y" },
+ { 'u', 2, 38, "u" }, { 'U', 2, 39, "U" },
+ { 'i', 2, 43, "i" }, { 'I', 2, 44, "I" },
+ { 'o', 2, 48, "o" }, { 'O', 2, 49, "O" },
+ { 'p', 2, 53, "p" }, { 'P', 2, 54, "P" },
+ { '[', 2, 58, "[" }, { '{', 2, 59, "{" },
+ { ']', 2, 63, "]" }, { '}', 2, 64, "}" },
+ { 127, 2, 71, "DEL" },
+ { 'a', 3, 10, "a" }, { 'A', 3, 11, "A" },
+ { 's', 3, 15, "s" }, { 'S', 3, 16, "S" },
+ { 'd', 3, 20, "d" }, { 'D', 3, 21, "D" },
+ { 'f', 3, 25, "f" }, { 'F', 3, 26, "F" },
+ { 'g', 3, 30, "g" }, { 'G', 3, 31, "G" },
+ { 'h', 3, 35, "h" }, { 'H', 3, 36, "H" },
+ { 'j', 3, 40, "j" }, { 'J', 3, 41, "J" },
+ { 'k', 3, 45, "k" }, { 'K', 3, 46, "K" },
+ { 'l', 3, 50, "l" }, { 'L', 3, 51, "L" },
+ { ';', 3, 55, ";" }, { ':', 3, 56, ":" },
+ {'\'', 3, 60, "'" }, { '"', 3, 61,"\"" },
+ { 13, 3, 65, "RETN"},
+ {'\\', 3, 71,"\\" }, { '|', 3, 72, "|" },
+ { 'z', 4, 12, "z" }, { 'Z', 4, 13, "Z" },
+ { 'x', 4, 17, "x" }, { 'X', 4, 18, "X" },
+ { 'c', 4, 22, "c" }, { 'C', 4, 23, "C" },
+ { 'v', 4, 27, "v" }, { 'V', 4, 28, "V" },
+ { 'b', 4, 32, "b" }, { 'B', 4, 33, "B" },
+ { 'n', 4, 37, "n" }, { 'N', 4, 38, "N" },
+ { 'm', 4, 42, "m" }, { 'M', 4, 43, "M" },
+ { ',', 4, 47, "," }, { '<', 4, 48, "<" },
+ { '.', 4, 52, "." }, { '>', 4, 53, ">" },
+ { '/', 4, 57, "/" }, { '?', 4, 58, "?" },
+ { 10, 4, 69, "LF" },
+ { ' ', 5, 13, " SPACE BAR "},
+ {'\0', 0, 0, "" }
+ };
+
+ static struct natkey {
+ char natc;
+ int natrow;
+ int natcol;
+ char *natsymbol;
+ } natkeytab [][29] = {
+ {
+ { '"', 1, 12, "\""},
+ { '&', 1, 32, "&" },
+ { '/', 1, 37, "/" },
+ { '(', 1, 42, "(" },
+ { ')', 1, 47, ")" },
+ { '=', 1, 52, "=" },
+ { '+', 1, 56, "+" }, { '?', 1, 57, "?" },
+ { '`', 1, 61, "`" }, { '@', 1, 62, "@" },
+ { '<', 1, 66, "<" }, { '>', 1, 67, ">" },
+ { '}', 2, 58, "}" }, { ']', 2, 59, "]" },
+ { '^', 2, 63, "^" }, { '~', 2, 64, "~" },
+ { '|', 3, 55, "|" }, {'\\', 3, 56,"\\" },
+ { '{', 3, 60, "{" }, { '[', 3, 61, "[" },
+ {'\'', 3, 71, "'" }, { '*', 3, 72, "*" },
+ { ',', 4, 47, "," }, { ';', 4, 48, ";" },
+ { '.', 4, 52, "." }, { ':', 4, 53, ":" },
+ { '-', 4, 57, "-" }, { '_', 4, 58, "_" },
+ {'\0', 0, 0, "" }
+ },
+ {
+ { '"', 1, 12, "\""},
+ { '&', 1, 32, "&" },
+ { '/', 1, 37, "/" },
+ { '(', 1, 42, "(" },
+ { ')', 1, 47, ")" },
+ { '=', 1, 52, "=" },
+ { '+', 1, 56, "+" }, { '?', 1, 57, "?" },
+ { '`', 1, 61, "`" }, { '@', 1, 62, "@" },
+ { '<', 1, 66, "<" }, { '>', 1, 67, ">" },
+ { '}', 2, 58, "}" }, { ']', 2, 59, "]" },
+ { '~', 2, 63, "~" }, { '^', 2, 64, "^" },
+ { '|', 3, 55, "|" }, {'\\', 3, 56,"\\" },
+ { '{', 3, 60, "{" }, { '[', 3, 61, "[" },
+ {'\'', 3, 71, "'" }, { '*', 3, 72, "*" },
+ { ',', 4, 47, "," }, { ';', 4, 48, ";" },
+ { '.', 4, 52, "." }, { ':', 4, 53, ":" },
+ { '-', 4, 57, "-" }, { '_', 4, 58, "_" },
+ {'\0', 0, 0, "" }
+ }
+ };
+
+ static struct curkey {
+ char *curkeymsg[3];
+ int curkeyrow;
+ int curkeycol;
+ char *curkeysymbol;
+ char *curkeyname;
+ } curkeytab [] = {
+
+ /* A Reset, A Set, VT52 */
+
+ {{"\033[A","\033OA","\033A"}, 0, 56, "UP", "Up arrow" },
+ {{"\033[B","\033OB","\033B"}, 0, 61, "DN", "Down arrow" },
+ {{"\033[D","\033OD","\033D"}, 0, 66, "LT", "Left arrow" },
+ {{"\033[C","\033OC","\033C"}, 0, 71, "RT", "Right arrow"},
+ {{"", "", "" }, 0, 0, "", "" }
+ };
+
+ static struct fnkey {
+ char *fnkeymsg[4];
+ int fnkeyrow;
+ int fnkeycol;
+ char *fnkeysymbol;
+ char *fnkeyname;
+ } fnkeytab [] = {
+
+ /* ANSI-num,ANSI-app,VT52-nu,VT52-ap, r, c, symb name */
+
+ {{"\033OP","\033OP","\033P","\033P" }, 6, 59, "PF1", "PF1" },
+ {{"\033OQ","\033OQ","\033Q","\033Q" }, 6, 63, "PF2", "PF2" },
+ {{"\033OR","\033OR","\033R","\033R" }, 6, 67, "PF3", "PF3" },
+ {{"\033OS","\033OS","\033S","\033S" }, 6, 71, "PF4", "PF4" },
+ {{"7", "\033Ow","7", "\033?w"}, 7, 59, " 7 ", "Numeric 7" },
+ {{"8", "\033Ox","8", "\033?x"}, 7, 63, " 8 ", "Numeric 8" },
+ {{"9", "\033Oy","9", "\033?y"}, 7, 67, " 9 ", "Numeric 9" },
+ {{"-", "\033Om","-", "\033?m"}, 7, 71, " - ", "Minus" },
+ {{"4", "\033Ot","4", "\033?t"}, 8, 59, " 4 ", "Numeric 4" },
+ {{"5", "\033Ou","5", "\033?u"}, 8, 63, " 5 ", "Numeric 5" },
+ {{"6", "\033Ov","6", "\033?v"}, 8, 67, " 6 ", "Numeric 6" },
+ {{",", "\033Ol",",", "\033?l"}, 8, 71, " , ", "Comma" },
+ {{"1", "\033Oq","1", "\033?q"}, 9, 59, " 1 ", "Numeric 1" },
+ {{"2", "\033Or","2", "\033?r"}, 9, 63, " 2 ", "Numeric 2" },
+ {{"3", "\033Os","3", "\033?s"}, 9, 67, " 3 ", "Numeric 3" },
+ {{"0", "\033Op","0", "\033?p"},10, 59," O ","Numeric 0"},
+ {{".", "\033On",".", "\033?n"},10, 67, " . ", "Point" },
+ {{"\015", "\033OM","\015", "\033?M"},10, 71, "ENT", "ENTER" },
+ {{"","","",""}, 0, 0, "", "" }
+ };
+
+ static struct ckey {
+ int ccount;
+ char *csymbol;
+ } ckeytab [] = {
+ { 0, "NUL (CTRL-@ or CTRL-Space)" },
+ { 0, "SOH (CTRL-A)" },
+ { 0, "STX (CTRL-B)" },
+ { 0, "ETX (CTRL-C)" },
+ { 0, "EOT (CTRL-D)" },
+ { 0, "ENQ (CTRL-E)" },
+ { 0, "ACK (CTRL-F)" },
+ { 0, "BEL (CTRL-G)" },
+ { 0, "BS (CTRL-H) (BACK SPACE)" },
+ { 0, "HT (CTRL-I) (TAB)" },
+ { 0, "LF (CTRL-J) (LINE FEED)" },
+ { 0, "VT (CTRL-K)" },
+ { 0, "FF (CTRL-L)" },
+ { 0, "CR (CTRL-M) (RETURN)" },
+ { 0, "SO (CTRL-N)" },
+ { 0, "SI (CTRL-O)" },
+ { 0, "DLE (CTRL-P)" },
+ { 0, "DC1 (CTRL-Q) (X-On)" },
+ { 0, "DC2 (CTRL-R)" },
+ { 0, "DC3 (CTRL-S) (X-Off)" },
+ { 0, "DC4 (CTRL-T)" },
+ { 0, "NAK (CTRL-U)" },
+ { 0, "SYN (CTRL-V)" },
+ { 0, "ETB (CTRL-W)" },
+ { 0, "CAN (CTRL-X)" },
+ { 0, "EM (CTRL-Y)" },
+ { 0, "SUB (CTRL-Z)" },
+ { 0, "ESC (CTRL-[) (ESCAPE)" },
+ { 0, "FS (CTRL-\\ or CTRL-? or CTRL-_)" },
+ { 0, "GS (CTRL-])" },
+ { 0, "RS (CTRL-^ or CTRL-~ or CTRL-`)" },
+ { 0, "US (CTRL-_ or CTRL-?)" }
+ };
+
+ static char *keyboardmenu[] = {
+ "Standard American ASCII layout",
+ "Swedish national layout D47",
+ "Swedish national layout E47",
+ /* add new keyboard layouts here */
+ ""
+ };
+
+ static char *curkeymodes[3] = {
+ "ANSI / Cursor key mode RESET",
+ "ANSI / Cursor key mode SET",
+ "VT52 Mode"
+ };
+
+ static char *fnkeymodes[4] = {
+ "ANSI Numeric mode",
+ "ANSI Application mode",
+ "VT52 Numeric mode",
+ "VT52 Application mode"
+ };
+
+ ledmsg[0] = "L1 L2 L3 L4"; ledseq[0] = "1;2;3;4";
+ ledmsg[1] = " L2 L3 L4"; ledseq[1] = "1;0;4;3;2";
+ ledmsg[2] = " L2 L3"; ledseq[2] = "1;4;;2;3";
+ ledmsg[3] = "L1 L2"; ledseq[3] = ";;2;1";
+ ledmsg[4] = "L1"; ledseq[4] = "1";
+ ledmsg[5] = ""; ledseq[5] = "";
+
+#ifdef UNIX
+ fflush(stdout);
+#endif
+ ed(2);
+ cup(10,1);
+ println("These LEDs (\"lamps\") on the keyboard should be on:");
+ for (i = 0; i <= 5; i++) {
+ cup(10,52); el(0); printf("%s", ledmsg[i]);
+ decll("0");
+ decll(ledseq[i]);
+ cup(12,1); holdit();
+ }
+
+ ed(2);
+ cup(10,1);
+ println("Test of the AUTO REPEAT feature");
+ println("");
+ println("Hold down an alphanumeric key for a while, then push RETURN.");
+ printf("%s", "Auto Repeat OFF: ");
+ rm("?8");
+ inputline(arptstring);
+ if (strlen(arptstring) == 0) println("No characters read!??");
+ else if (strlen(arptstring) == 1) println("OK.");
+ else println("Too many characters read.");
+ println("");
+ println("Hold down an alphanumeric key for a while, then push RETURN.");
+ printf("%s", "Auto Repeat ON: ");
+ sm("?8");
+ inputline(arptstring);
+ if (strlen(arptstring) == 0) println("No characters read!??");
+ else if (strlen(arptstring) == 1) println("Not enough characters read.");
+ else println("OK.");
+ println("");
+ holdit();
+
+ ed(2);
+ cup(5,10);
+ println("Choose keyboard layout:");
+ kblayout = menu(keyboardmenu);
+ if (kblayout) {
+ kblayout--;
+ for (j = 0; natkeytab[kblayout][j].natc != '\0'; j++) {
+ for (i = 0; keytab[i].c != '\0'; i++) {
+ if (keytab[i].row == natkeytab[kblayout][j].natrow &&
+ keytab[i].col == natkeytab[kblayout][j].natcol) {
+ keytab[i].c = natkeytab[kblayout][j].natc;
+ keytab[i].symbol = natkeytab[kblayout][j].natsymbol;
+ break;
+ }
+ }
+ }
+ }
+
+ ed(2);
+ for (i = 0; keytab[i].c != '\0'; i++) {
+ cup(1 + 2 * keytab[i].row, 1 + keytab[i].col);
+ sgr("7");
+ printf("%s", keytab[i].symbol);
+ sgr("");
+ }
+ cup(22,1);
+#ifdef UNIX
+ sgttyNew.sg_flags &= ~CRMOD;
+ sgttyNew.sg_flags &= ~ECHO;
+ stty(0, &sgttyNew);
+#endif
+ inflush();
+ printf("Press each key, both shifted and unshifted. Finish with RETURN:");
+ do { /* while (kbdc != 13) */
+ cup(23,1); kbdc = inchar();
+ cup(23,1); el(0);
+ sprintf(kbds, "%c", kbdc);
+ chrprint(kbds);
+ for (i = 0; keytab[i].c != '\0'; i++) {
+ if (keytab[i].c == kbdc) {
+ cup(1 + 2 * keytab[i].row, 1 + keytab[i].col);
+ printf("%s", keytab[i].symbol);
+ break;
+ }
+ }
+ } while (kbdc != 13);
+#ifdef SARG10
+ inchar(); /* Local hack: Read LF that TOPS-10 adds to CR */
+#endif
+ cup(23,1); el(0);
+
+ for (ckeymode = 0; ckeymode <= 2; ckeymode++) {
+ if (ckeymode) sm("?1");
+ else rm("?1");
+ for (i = 0; curkeytab[i].curkeysymbol[0] != '\0'; i++) {
+ cup(1 + 2 * curkeytab[i].curkeyrow, 1 + curkeytab[i].curkeycol);
+ sgr("7");
+ printf("%s", curkeytab[i].curkeysymbol);
+ sgr("");
+ }
+ cup(20,1); printf("<%s>%20s", curkeymodes[ckeymode], "");
+ cup(22,1); el(0);
+ cup(22,1); printf("%s", "Press each cursor key. Finish with TAB.");
+ for(;;) {
+ cup(23,1);
+ if (ckeymode == 2) rm("?2"); /* VT52 mode */
+ curkeystr = instr();
+ esc("<"); /* ANSI mode */
+ cup(23,1); el(0);
+ cup(23,1); chrprint(curkeystr);
+ if (!strcmp(curkeystr,"\t")) break;
+ for (i = 0; curkeytab[i].curkeysymbol[0] != '\0'; i++) {
+ if (!strcmp(curkeystr,curkeytab[i].curkeymsg[ckeymode])) {
+ sgr("7");
+ printf(" (%s key) ", curkeytab[i].curkeyname);
+ sgr("");
+ cup(1 + 2 * curkeytab[i].curkeyrow,
+ 1 + curkeytab[i].curkeycol);
+ printf("%s", curkeytab[i].curkeysymbol);
+ break;
+ }
+ }
+ if (i == sizeof(curkeytab) / sizeof(struct curkey) - 1) {
+ sgr("7");
+ printf("%s", " (Unknown cursor key) ");
+ sgr("");
+ }
+ }
+ }
+
+ for (fkeymode = 0; fkeymode <= 3; fkeymode++) {
+ for (i = 0; fnkeytab[i].fnkeysymbol[0] != '\0'; i++) {
+ cup(1 + 2 * fnkeytab[i].fnkeyrow, 1 + fnkeytab[i].fnkeycol);
+ sgr("7");
+ printf("%s", fnkeytab[i].fnkeysymbol);
+ sgr("");
+ }
+ cup(20,1); printf("<%s>%20s", fnkeymodes[fkeymode], "");
+ cup(22,1); el(0);
+ cup(22,1); printf("%s", "Press each function key. Finish with TAB.");
+ for(;;) {
+ cup(23,1);
+ if (fkeymode >= 2) rm("?2"); /* VT52 mode */
+ if (fkeymode % 2) deckpam(); /* Application mode */
+ else deckpnm(); /* Numeric mode */
+ fnkeystr = instr();
+ esc("<"); /* ANSI mode */
+ cup(23,1); el(0);
+ cup(23,1); chrprint(fnkeystr);
+ if (!strcmp(fnkeystr,"\t")) break;
+ for (i = 0; fnkeytab[i].fnkeysymbol[0] != '\0'; i++) {
+ if (!strcmp(fnkeystr,fnkeytab[i].fnkeymsg[fkeymode])) {
+ sgr("7");
+ printf(" (%s key) ", fnkeytab[i].fnkeyname);
+ sgr("");
+ cup(1 + 2 * fnkeytab[i].fnkeyrow, 1 + fnkeytab[i].fnkeycol);
+ printf("%s", fnkeytab[i].fnkeysymbol);
+ break;
+ }
+ }
+ if (i == sizeof(fnkeytab) / sizeof(struct fnkey) - 1) {
+ sgr("7");
+ printf("%s", " (Unknown function key) ");
+ sgr("");
+ }
+ }
+ }
+
+#ifdef UNIX
+ sgttyNew.sg_flags |= CRMOD;
+ stty(0, &sgttyNew);
+#endif
+ ed(2);
+ cup(5,1);
+ println("Finally, a check of the ANSWERBACK MESSAGE, which can be sent");
+ println("by pressing CTRL-BREAK. The answerback message can be loaded");
+ println("in SET-UP B by pressing SHIFT-A and typing e.g.");
+ println("");
+ println(" \" H e l l o , w o r l d Return \"");
+ println("");
+ println("(the double-quote characters included). Do that, and then try");
+ println("to send an answerback message with CTRL-BREAK. If it works,");
+ println("the answerback message should be displayed in reverse mode.");
+ println("Finish with a single RETURN.");
+
+#ifdef UNIX
+ sgttyNew.sg_flags &= ~CRMOD;
+ stty(0, &sgttyNew);
+#endif
+ do {
+ cup(17,1);
+ inflush();
+ abmstr = instr();
+ cup(17,1);
+ el(0);
+ chrprint(abmstr);
+ } while (strcmp(abmstr,"\r"));
+
+ ed(2);
+ for (i = 0; i < 32; i++) {
+ cup(1 + (i % 16), 1 + 40 * (i / 16));
+ sgr("7");
+ printf("%s", ckeytab[i].csymbol);
+ sgr("0");
+ }
+ cup(19,1);
+#ifdef UNIX
+ sgttyNew.sg_flags |= CRMOD;
+ stty(0, &sgttyNew);
+#endif
+ println(
+ "Push each CTRL-key TWICE. Note that you should be able to send *all*");
+ println(
+ "CTRL-codes twice, including CTRL-S (X-Off) and CTRL-Q (X-Off)!");
+ println(
+ "Finish with DEL (also called DELETE or RUB OUT), or wait 1 minute.");
+#ifdef UNIX
+#ifdef SIII
+ sgttyNew.sg_flags &= ~CBREAK;
+ stty(0, &sgttyNew);
+#endif
+ sgttyNew.sg_flags |= RAW;
+ stty(0, &sgttyNew);
+#endif
+ ttybin(1);
+#ifdef SARG20
+ page(0); /* Turn off all character processing at input */
+ superbin(1); /* Turn off ^C (among others). Keep your fingers crossed!! */
+#endif
+ do {
+ cup(23,1); kbdc = inchar();
+ cup(23,1); el(0);
+ if (kbdc < 32) printf(" %s", ckeytab[kbdc].csymbol);
+ else {
+ sprintf(kbds, "%c", kbdc);
+ chrprint(kbds);
+ printf("%s", " -- not a CTRL key");
+ }
+ if (kbdc < 32) ckeytab[kbdc].ccount++;
+ if (ckeytab[kbdc].ccount == 2) {
+ cup(1 + (kbdc % 16), 1 + 40 * (kbdc / 16));
+ printf("%s", ckeytab[kbdc].csymbol);
+ }
+ } while (kbdc != '\177');
+#ifdef UNIX
+ sgttyNew.sg_flags &= ~RAW;
+ sgttyNew.sg_flags |= ECHO;
+ stty(0, &sgttyNew);
+#ifdef SIII
+ sgttyNew.sg_flags |= CBREAK;
+ stty(0, &sgttyNew);
+#endif
+#endif
+ ttybin(0);
+#ifdef SARG20
+ superbin(0); /* Puuuh! We made it!? */
+ page(1); /* Back to normal input processing */
+ ttybin(1); /* This must be the mode for DEC20 */
+#endif
+ cup(24,1);
+ okflag = 1;
+ for (i = 0; i < 32; i++) if (ckeytab[i].ccount < 2) okflag = 0;
+ if (okflag) printf("%s", "OK. ");
+ else printf("%s", "You have not been able to send all CTRL keys! ");
+ holdit();
+}
+
+tst_reports() {
+ /* Test of:
+ <ENQ> (AnswerBack Message)
+ SM RM (Set/Reset Mode) - LineFeed / Newline
+ DSR (Device Status Report)
+ DA (Device Attributes)
+ DECREQTPARM (Request Terminal Parameters)
+ */
+
+ int parity, nbits, xspeed, rspeed, clkmul, flags;
+ int i, reportpos;
+ char *report, *report2;
+ static char *attributes[][2] = {
+ { "\033[?1;0c", "No options (vanilla VT100)" },
+ { "\033[?1;1c", "VT100 with STP" },
+ { "\033[?1;2c", "VT100 with AVO (could be a VT102)" },
+ { "\033[?1;3c", "VT100 with STP and AVO" },
+ { "\033[?1;4c", "VT100 with GPO" },
+ { "\033[?1;5c", "VT100 with STP and GPO" },
+ { "\033[?1;6c", "VT100 with AVO and GPO" },
+ { "\033[?1;7c", "VT100 with STP, AVO and GPO" },
+ { "\033[?1;11c", "VT100 with PP and AVO" },
+ { "\033[?1;15c", "VT100 with PP, GPO and AVO" },
+ { "\033[?4;2c", "VT132 with AVO" },
+ { "\033[?4;3c", "VT132 with AVO and STP" },
+ { "\033[?4;6c", "VT132 with GPO and AVO" },
+ { "\033[?4;7c", "VT132 with GPO, AVO, and STP" },
+ { "\033[?4;11c", "VT132 with PP and AVO" },
+ { "\033[?4;15c", "VT132 with PP, GPO and AVO" },
+ { "\033[?7c", "VT131" },
+ { "\033[?12;5c", "VT125" }, /* VT125 also has ROM version */
+ { "\033[?12;7c", "VT125 with AVO" }, /* number, so this won't work */
+ { "\033[?5;0c", "VK100 (GIGI)" },
+ { "\033[?5c", "VK100 (GIGI)" },
+ { "", "" }
+ };
+
+#ifdef UNIX
+ sgttyNew.sg_flags &= ~ECHO;
+ stty(0, &sgttyNew);
+#endif
+ cup(5,1);
+ println("This is a test of the ANSWERBACK MESSAGE. (To load the A.B.M.");
+ println("see the TEST KEYBOARD part of this program). Below here, the");
+ println("current answerback message in your terminal should be");
+ println("displayed. Finish this test with RETURN.");
+ cup(10,1);
+ inflush();
+ printf("%c", 5); /* ENQ */
+ report = instr();
+ cup(10,1);
+ chrprint(report);
+ cup(12,1);
+ holdit();
+
+ ed(2);
+ cup(1,1);
+ println("Test of LineFeed/NewLine mode.");
+ cup(3,1);
+ sm("20");
+#ifdef UNIX
+ sgttyNew.sg_flags &= ~CRMOD;
+ stty(0, &sgttyNew);
+#endif
+ printf("NewLine mode set. Push the RETURN key: ");
+ report = instr();
+ cup(4,1);
+ el(0);
+ chrprint(report);
+ if (!strcmp(report, "\015\012")) printf(" -- OK");
+ else printf(" -- Not expected");
+ cup(6,1);
+ rm("20");
+ printf("NewLine mode reset. Push the RETURN key: ");
+ report = instr();
+ cup(7,1);
+ el(0);
+ chrprint(report);
+ if (!strcmp(report, "\015")) printf(" -- OK");
+ else printf(" -- Not expected");
+ cup(9,1);
+#ifdef UNIX
+ sgttyNew.sg_flags |= CRMOD;
+ stty(0, &sgttyNew);
+#endif
+ holdit();
+
+ ed(2);
+ cup(1,1);
+ printf("Test of Device Status Report 5 (report terminal status).");
+ cup(2,1);
+ dsr(5);
+ report = instr();
+ cup(2,1);
+ el(0);
+ printf("Report is: ");
+ chrprint(report);
+ if (!strcmp(report,"\033[0n")) printf(" -- means \"TERMINAL OK\"");
+ else if (!strcmp(report,"\033[3n")) printf(" -- means \"TERMINAL OK\"");
+ else printf(" -- Unknown response!");
+
+ cup(4,1);
+ println("Test of Device Status Report 6 (report cursor position).");
+ cup(5,1);
+ dsr(6);
+ report = instr();
+ cup(5,1);
+ el(0);
+ printf("Report is: ");
+ chrprint(report);
+ if (!strcmp(report,"\033[5;1R")) printf(" -- OK");
+ else printf(" -- Unknown response!");
+
+ cup(7,1);
+ println("Test of Device Attributes report (what are you)");
+ cup(8,1);
+ da(0);
+ report = instr();
+ cup(8,1);
+ el(0);
+ printf("Report is: ");
+ chrprint(report);
+ for (i = 0; *attributes[i][0] != '\0'; i++) {
+ if (!strcmp(report,attributes[i][0])) break;
+ }
+ if (*attributes[i][0] == '\0')
+ printf(" -- Unknown response, refer to the manual");
+ else {
+ printf(" -- means %s", attributes[i][1]);
+ if (i) {
+ cup(9,1);
+ println("Legend: STP = Processor Option");
+ println(" AVO = Advanced Video Option");
+ println(" GPO = Graphics Processor Option");
+ println(" PP = Printer Port");
+ }
+ }
+
+ cup(14,1);
+ println("Test of the \"Request Terminal Parameters\" feature, argument 0.");
+ cup(15,1);
+ decreqtparm(0);
+ report = instr();
+ cup(15,1);
+ el(0);
+ printf("Report is: ");
+ chrprint(report);
+ if (strlen(report) < 16
+ || report[0] != '\033'
+ || report[1] != '['
+ || report[2] != '2'
+ || report[3] != ';')
+ println(" -- Bad format");
+ else {
+ reportpos = 4;
+ parity = scanto(report, &reportpos, ';');
+ nbits = scanto(report, &reportpos, ';');
+ xspeed = scanto(report, &reportpos, ';');
+ rspeed = scanto(report, &reportpos, ';');
+ clkmul = scanto(report, &reportpos, ';');
+ flags = scanto(report, &reportpos, 'x');
+ if (parity == 0 || nbits == 0 || clkmul == 0) println(" -- Bad format");
+ else println(" -- OK");
+ printf(
+ "This means: Parity %s, %s bits, xmitspeed %s, recvspeed %s.\n",
+ lookup(paritytable, parity),
+ lookup(nbitstable, nbits),
+ lookup(speedtable, xspeed),
+ lookup(speedtable, rspeed));
+ printf("(CLoCk MULtiplier = %d, STP option flags = %d)\n", clkmul, flags);
+ }
+
+ cup(19,1);
+ println("Test of the \"Request Terminal Parameters\" feature, argument 1.");
+ cup(20,1);
+ decreqtparm(1); /* Does the same as decreqtparm(0), reports "3" */
+ report2 = instr();
+ cup(20,1);
+ el(0);
+ printf("Report is: ");
+ chrprint(report2);
+ if (strlen(report2) < 3
+ || report2[2] != '3')
+ println(" -- Bad format");
+ else {
+ report2[2] = '2';
+ if (!strcmp(report,report2)) println(" -- OK");
+ else println(" -- Bad format");
+ }
+ cup(24,1);
+ holdit();
+#ifdef UNIX
+ sgttyNew.sg_flags |= ECHO;
+ stty(0, &sgttyNew);
+#endif
+}
+
+tst_vt52() {
+
+ static struct rtabl {
+ char *rcode;
+ char *rmsg;
+ } resptable[] = {
+ { "\033/K", " -- OK (means Standard VT52)" },
+ { "\033/Z", " -- OK (means VT100 emulating VT52)" },
+ { "", " -- Unknown response"}
+ };
+
+ int i,j;
+ char *response;
+
+ rm("?2"); /* Reset ANSI (VT100) mode, Set VT52 mode */
+ esc("H"); /* Cursor home */
+ esc("J"); /* Erase to end of screen */
+ esc("H"); /* Cursor home */
+ for (i = 0; i <= 23; i++) {
+ for (j = 0; j <= 9; j++)
+ printf("%s", "FooBar ");
+ println("Bletch");
+ }
+ esc("H"); /* Cursor home */
+ esc("J"); /* Erase to end of screen */
+
+ vt52cup(7,47);
+ printf("nothing more.");
+ for (i = 1; i <= 10; i++) printf("THIS SHOULD GO AWAY! ");
+ for (i = 1; i <= 5; i++) {
+ vt52cup(1,1);
+ printf("%s", "Back scroll (this should go away)");
+ esc("I"); /* Reverse LineFeed (with backscroll!) */
+ }
+ vt52cup(12,60);
+ esc("J"); /* Erase to end of screen */
+ for (i = 2; i <= 6; i++) {
+ vt52cup(i,1);
+ esc("K"); /* Erase to end of line */
+ }
+
+ for (i = 2; i <= 23; i++) {
+ vt52cup(i,70); printf("%s", "**Foobar");
+ }
+ vt52cup(23,10);
+ for (i = 23; i >= 2; i--) {
+ printf("%s", "*");
+ printf("%c", 8); /* BS */
+ esc("I"); /* Reverse LineFeed (LineStarve) */
+ }
+ vt52cup(1,70);
+ for (i = 70; i >= 10; i--) {
+ printf("%s", "*");
+ esc("D"); esc("D"); /* Cursor Left */
+ }
+ vt52cup(24,10);
+ for (i = 10; i <= 70; i++) {
+ printf("%s", "*");
+ printf("%c", 8); /* BS */
+ esc("C"); /* Cursor Right */
+ }
+ vt52cup(2,11);
+ for (i = 2; i <= 23; i++) {
+ printf("%s", "!");
+ printf("%c", 8); /* BS */
+ esc("B"); /* Cursor Down */
+ }
+ vt52cup(23,69);
+ for (i = 23; i >= 2; i--) {
+ printf("%s", "!");
+ printf("%c", 8); /* BS */
+ esc("A"); /* Cursor Up */
+ }
+ for (i = 2; i <= 23; i++) {
+ vt52cup(i,71);
+ esc("K"); /* Erase to end of line */
+ }
+
+ vt52cup(10,16);
+ printf("%s", "The screen should be cleared, and have a centered");
+ vt52cup(11,16);
+ printf("%s", "rectangle of \"*\"s with \"!\"s on the inside to the");
+ vt52cup(12,16);
+ printf("%s", "left and right. Only this, and");
+ vt52cup(13,16);
+ holdit();
+
+ esc("H"); /* Cursor home */
+ esc("J"); /* Erase to end of screen */
+ printf("%s", "This is the normal character set:");
+ for (j = 0; j <= 1; j++) {
+ vt52cup(3 + j, 16);
+ for (i = 0; i <= 47; i++)
+ printf("%c", 32 + i + 48 * j);
+ }
+ vt52cup(6,1);
+ printf("%s", "This is the special graphics character set:");
+ esc("F"); /* Select Special Graphics character set */
+ for (j = 0; j <= 1; j++) {
+ vt52cup(8 + j, 16);
+ for (i = 0; i <= 47; i++)
+ printf("%c", 32 + i + 48 * j);
+ }
+ esc("G"); /* Select ASCII character set */
+ vt52cup(12,1);
+ holdit();
+
+ esc("H"); /* Cursor home */
+ esc("J"); /* Erase to end of screen */
+ println("Test of terminal response to IDENTIFY command");
+ esc("Z"); /* Identify */
+ response = instr();
+ println("");
+ printf("Response was");
+ esc("<"); /* Enter ANSI mode (VT100 mode) */
+ chrprint(response);
+ for(i = 0; resptable[i].rcode[0] != '\0'; i++)
+ if (!strcmp(response, resptable[i].rcode))
+ break;
+ printf("%s", resptable[i].rmsg);
+ println("");
+ println("");
+ holdit();
+}
+
+tst_insdel() {
+
+ /* Test of:
+ SM/RM(4) (= IRM (Insertion/replacement mode))
+ ICH (Insert Character)
+ DCH (Delete character)
+ IL (Insert line)
+ DL (Delete line)
+ */
+
+ int i, row, col, sw, dblchr, scr132;
+
+ for(scr132 = 0; scr132 <= 1; scr132++) {
+ if (scr132) { sm("?3"); sw = 132; }
+ else { rm("?3"); sw = 80; }
+ ed(2);
+ cup(1,1);
+ for (row=1; row<=24; row++) {
+ cup(row,1);
+ for (col=1; col<=sw; col++)
+ printf("%c", 'A'-1+row);
+ }
+ cup(4,1);
+ printf("Screen accordion test (Insert & Delete Line). "); holdit();
+ ri(); el(2);
+ decstbm( 2,23);
+ sm("?6");
+ cup(1,1);
+ for (row=1; row<=24; row++) {
+ il(row);
+ dl(row);
+ }
+ rm("?6");
+ decstbm( 0, 0);
+ cup(2,1);
+ printf(
+ "Top line: A's, bottom line: X's, this line, nothing more. ");
+ holdit();
+ cup(2,1); ed(0);
+ cup(1,2);
+ printf("B");
+ cub(1);
+ sm("4");
+ for (col=2; col<=sw-1; col++)
+ printf("*");
+ rm("4");
+ cup(4,1);
+ printf("Test of 'Insert Mode'. The top line should be 'A*** ... ***B'. ");
+ holdit(); ri(); el(2);
+ cup(1,2);
+ dch(sw-2);
+ cup(4,1);
+ printf("Test of 'Delete Character'. The top line should be 'AB'. ");
+ holdit();
+
+ for(dblchr = 1; dblchr <= 2; dblchr++) {
+ ed(2);
+ for (row=1; row<=24; row++) {
+ cup(row,1);
+ if (dblchr == 2) decdwl();
+ for (col=1; col<=sw/dblchr; col++)
+ printf("%c", 'A'-1+row);
+ cup(row,sw/dblchr-row);
+ dch(row);
+ }
+ cup(4,1);
+ println("The right column should be staggered ");
+ printf("by one. ");
+ holdit();
+ }
+ ed(2);
+ cup(1,1);
+ println("If your terminal has the ANSI 'Insert Character' function");
+ println("(the VT102 does not), then you should see a line like this");
+ println(" A B C D E F G H I J K L M N O P Q R S T U V W X Y Z");
+ println("below:");
+ println("");
+ for (i = 'Z'; i >= 'A'; i--) {
+ printf("%c\010",i);
+ ich(2);
+ }
+ cup(10,1);
+ holdit();
+
+ if (sw == 132) rm("?3");
+ }
+}
+
+dch(pn) int pn; { brc(pn, 'P'); } /* Delete character */
+ich(pn) int pn; { brc(pn, '@'); } /* Insert character -- not in VT102 */
+dl(pn) int pn; { brc(pn, 'M'); } /* Delete line */
+il(pn) int pn; { brc(pn, 'L'); } /* Insert line */
+
+/* Test of some known VT100 bugs and misfeatures */
+
+tst_bugs() {
+
+ int i, menuchoice;
+
+ static char *menutable[] = {
+ "Exit to main menu",
+ "Bug A: Smooth scroll to jump scroll",
+ "Bug B: Scrolling region",
+ "Bug C: Wide to narrow screen",
+ "Bug D: Narrow to wide screen",
+ "Bug E: Cursor move from double- to single-wide line",
+ "Bug F: Column mode escape sequence",
+ "Wrap around with cursor addressing",
+ "Erase right half of double width lines",
+ "Funny scroll regions",
+ /* Add more here */
+ ""
+ };
+
+ static char *hmsg[] = {
+ "Test of known bugs in the DEC VT100 series. The numbering of some of",
+ "the bugs (A-F) refers to the article 'VT100 MAGIC' by Sami Tabih in",
+ "the 'Proceedings of the DEC Users Society' at St. Louis, Missouri, May",
+ "1983. To understand some of the tests, you have to look at the source",
+ "code or the article. Of course, a good VT100-compatible terminal",
+ "should not have these bugs (or have some means of disabling them)! If",
+ "a bug appears, you might want to RESET the terminal before continuing",
+ "the test. There is a test of the RESET function in the main menu.",
+ "" };
+
+ do {
+ ed(2); cup(1,1);
+ for (i = 0; *hmsg[i]; i++) println(hmsg[i]);
+ println("");
+ println(" Choose bug test number:");
+ menuchoice = menu(menutable);
+ switch (menuchoice) {
+ case 1: bug_a(); break;
+ case 2: bug_b(); break;
+ case 3: bug_c(); break;
+ case 4: bug_d(); break;
+ case 5: bug_e(); break;
+ case 6: bug_f(); break;
+ case 7: bug_w(); break;
+ case 8: bug_l(); break;
+ case 9: bug_s(); break;
+ }
+ } while (menuchoice);
+}
+
+/* Bug A: Smooth scroll to jump scroll */
+
+bug_a() {
+ int i;
+
+ cup (10, 1);
+ println("This is a test of the VT100 'Scroll while toggle softscroll'");
+ println("bug. The cursor may disappear, or move UP the screen, or");
+ println("multiple copies of some lines may appear.");
+ holdit();
+
+ /* Invoke the bug */
+
+ esc ("[24H"); /* Simplified cursor movement */
+ rm("?4"); for (i = 1; i <= 20; i++) printf("\n");
+ sm("?4"); for (i = 1; i <= 10; i++) printf("\n");
+ rm("?4"); for (i = 1; i <= 5; i++) printf("\n");
+
+ /* That should be enough to show the bug. But we'll try another way: */
+ sm ("?4"); /* Set soft scroll */
+ nel (); /* "NextLine", move down */
+ rm ("?4"); /* Reset soft scroll */
+ nel (); /* "NextLine", move down */
+ for (i = 1; i <= 10; i++) { /* Show the bug */
+ printf ("Softscroll bug test, line %d. ", i);
+ holdit();
+ }
+ println("That should have been enough to show the bug, if present.");
+ holdit();
+}
+
+/* Bug B: Scrolling region */
+
+bug_b() {
+ char c;
+
+ decaln();
+ cup( 1,1); el(0);
+ printf("Line 11 should be double-wide, line 12 should be cleared.");
+ cup( 2,1); el(0);
+ printf("Then, the letters A-P should be written at the beginning");
+ cup( 3,1); el(0);
+ printf("of lines 12-24, and the empty line and A-E are scrolled away.");
+ cup( 4,1); el(0);
+ printf("If the bug is present, some lines are confused, look at K-P.");
+ cup(11,1); decdwl();
+ decstbm(12,24);
+ cup(12,1); el(0); printf("Here we go... "); holdit();
+ cup(12,1); ri(); /* Bug comes here */
+ for (c = 'A'; c <= 'P'; c++) printf("%c\n",c); /* Bug shows here */
+ holdit();
+ decstbm(0,0); /* No scr. region */
+}
+
+/* Bug C: Wide to narrow screen */
+
+bug_c() {
+ sm("?3"); /* 132 column mode */
+ cup(1,81);
+ rm("?3"); /* 80 column mode */
+ cup(12,5);
+ printf("Except for this line, the screen should be blank. ");
+ holdit();
+}
+
+/* Bug D: Narrow to wide screen */
+
+bug_d() {
+ int i;
+ char result;
+ /* Make the bug appear */
+ do {
+ cup(14,1);
+
+ /* The original code in the article says
+ * PRINT ESC$; "[13;1H"; CHR$(10%);
+ * but I guess a cup(14,1); would do.
+ * (To output a pure LF might be tricky).
+ */
+
+ sm("?3"); /* Make the bug visible */
+ cup(1,9); decdwl();
+ println("You should see blinking text at the bottom line.");
+ cup(3,9); decdwl();
+ println("Enter 0 to exit, 1 to try to invoke the bug again.");
+ cup(24,9); decdwl(); sgr("1;5;7");
+ printf("If you can see this then the bug did not appear."); sgr("");
+ cup(4,9); decdwl();
+ result = inchar(); readnl();
+ rm("?3");
+ } while (result == '1');
+ sm("?4"); /* Syrup scroll */
+ cup(23,1);
+ for (i = 1; i <= 5; i++)
+ println("If the bug is present, this should make things much worse!");
+ holdit();
+ rm("?4"); /* Jump scroll */
+}
+
+/* Bug E: Cursor move from double- to single-wide line */
+
+bug_e() {
+ int i;
+ static char *rend[2] = { "\033[m", "\033[7m" };
+ sm("?3");
+ cup(1,1); decdwl();
+ println("This test should put an 'X' at line 3 column 100.");
+ for (i = 1; i <= 12; i++) printf("1234567890%s",rend[i & 1]);
+ cup(1,1); /* The bug appears when we jump from a dobule-wide line */
+ cup(3,100); /* to a single-wide line, column > 66. */
+ printf("X");
+ cup(4, 66); printf("! !");
+ cup(5,1);
+ printf("--------------------------- The 'X' should NOT be above here -");
+ printf("---+------------ but above here -----+");
+ cup(10,1); decdwl(); holdit();
+ rm("?3");
+}
+
+/* Bug F: Column mode escape sequence */
+
+bug_f() {
+ int i, row, col;
+
+ /*
+ * VT100 "toggle origin mode, forget rest" bug. If you try to set
+ * (or clear) parameters and one of them is the "origin mode"
+ * ("?6") parameter, parameters that appear after the "?6"
+ * remain unaffected. This is also true on CIT-101 terminals.
+ */
+ sm ("?5"); /* Set reverse mode */
+ sm ("?3"); /* Set 132 column mode */
+ println("Test VT100 'Toggle origin mode, forget rest' bug, part 1.");
+ println("The screen should be in reverse, 132 column mode.");
+ holdit();
+ ed (2);
+ rm ("?6;5;3"); /* Reset (origin, reverse, 132 col) */
+ println("Test VT100 'Toggle origin mode, forget rest' bug, part 2.\n");
+ println("The screen should be in non-reverse, 80 column mode.");
+ holdit();
+}
+
+ /* Bug W:
+ * The dreaded "wraparound" bug! You CUP to col 80, write a char,
+ * CUP to another line in col 80, write a char. And the brain-damaged
+ * terminal thinks that "Hokay, so he's written a char in col 80, so
+ * I stay in col 80 and wait for next character. Let's see now, here
+ * comes another character, and I'm still in col 80, so I must make
+ * a NewLine first." -- It doesn't clear that "still in col 80" flag
+ * on a CUP. Argh!
+ */
+
+bug_w() {
+ int row, col;
+
+ cup (16,1);
+ println(" This illustrates the \"wrap around bug\" which exists on a");
+ println(" standard VT100. At the top of the screen there should be");
+ println(" a row of +'s, and the rightmost column should be filled");
+ println(" with *'s. But if the bug is present, some of the *'s may");
+ println(" be placed in other places, e.g. in the leftmost column,");
+ println(" and the top line of +'s may be scrolled away.");
+
+ cup(1,1);
+ for (col = 1; col <= 79; col++)
+ printf ("+");
+ for (row = 1; row <= 24; row++) {
+ hvp (row, 80);
+ printf ("*");
+ }
+ cup(24,1);
+ holdit();
+}
+
+ /* Bug L:
+ * Check if the right half of double-width lines comes back
+ * when a line is first set to single-width, filled with stuff,
+ * set to double-width, and finally reset to single-width.
+ *
+ * A VT100 has this misfeature, and many others. Foo!
+ */
+
+bug_l() {
+ cup(15, 1);
+ printf("This-is-a-long-line-This-is-a-long-line-");
+ printf("This-is-a-long-line-This-is-a-long-line-");
+ cup(1, 1);
+ printf("This is a test of what happens to the right half of double-width");
+ println(" lines.");
+ printf("A common misfeature is that the right half does not come back");
+ println(" when a long");
+ printf("single-width line is set to double-width and then reset to");
+ println(" single-width.");
+
+ cup(5, 1);
+ println("Now the line below should contain 80 characters in single width.");
+ holdit();
+ cup(15, 1); decdwl();
+ cup(8, 1);
+ println("Now the line below should contain 40 characters in double width.");
+ holdit();
+ cup(15, 1); decswl();
+ cup(11, 1);
+ println("Now the line below should contain 80 characters in single width.");
+ holdit();
+
+ /* ...and in 132 column mode */
+
+ sm("?3");
+ ed(2);
+ cup(15, 1);
+ printf("This-is-a-long-line-This-is-a-long-line-");
+ printf("This-is-a-long-line-This-is-a-long-line-");
+ printf("This-is-a-long-line-This-is-a-long-line-");
+ printf("ending-here-");
+
+ cup(1, 1);
+ printf("This is the same test in 132 column mode.");
+
+ cup(5, 1);
+ println("Now the line below should contain 132 characters in single width.");
+ holdit();
+ cup(15, 1); decdwl();
+ cup(8, 1);
+ println("Now the line below should contain 66 characters in double width.");
+ holdit();
+ cup(15, 1); decswl();
+ cup(11, 1);
+ println("Now the line below should contain 132 characters in single width.");
+ holdit();
+ rm("?3");
+}
+
+bug_s() {
+ int i;
+ decstbm(20,10); /* 20-10=-10, < 2, so no scroll region. */
+ cup(1,1);
+ for (i=1; i<=20; i++)
+ printf("This is 20 lines of text (line %d), no scroll region.\n", i);
+ holdit();
+ ed(2);
+ decstbm(0,1); /* Should be interpreted as decstbm(1,1) = none */
+ cup(1,1);
+ for (i=1; i<=20; i++)
+ printf("This is 20 lines of text (line %d), no scroll region.\n", i);
+ holdit();
+ decstbm(0,0); /* No scroll region (just in case...) */
+}
+
+tst_rst() {
+
+ /*
+ * Test of
+ * - RIS (Reset to Initial State)
+ * - DECTST (invoke terminal test)
+ */
+
+ cup(10,1);
+ printf ("The terminal will now be RESET. ");
+ holdit();
+ ris();
+#ifdef UNIX
+ fflush(stdout);
+#endif
+ zleep(5000); /* Wait 5.0 seconds */
+ cup(10,1);
+ println("The terminal is now RESET. Next, the built-in confidence test");
+ printf("%s", "will be invoked. ");
+ holdit();
+ ed(2);
+ dectst(1);
+#ifdef UNIX
+ fflush(stdout);
+#endif
+ zleep(5000); /* Wait 5.0 seconds */
+ cup(10,1);
+ println("If the built-in confidence test found any errors, a code");
+ printf("%s", "is visible above. ");
+ holdit();
+}
+
+initterminal(pn) int pn; {
+
+#ifdef UNIX
+ if (pn==0) {
+ fflush(stdout);
+ gtty(0,&sgttyOrg);
+ gtty(0,&sgttyNew);
+ sgttyNew.sg_flags |= CBREAK;
+ }
+ else {
+ fflush(stdout);
+ inflush();
+ sleep(2);
+ sgttyNew.sg_flags = sgttyOrg.sg_flags | CBREAK;
+ }
+ stty(0,&sgttyNew);
+#ifdef SIII
+ close(2);
+ open("/dev/tty",O_RDWR|O_NDELAY);
+#endif
+#endif
+#ifdef SARG10
+ /* Set up neccesary TOPS-10 terminal parameters */
+
+ trmop(02041, `VT100`); /* tty type vt100 */
+ trmop(02002, 0); /* tty no tape */
+ trmop(02003, 0); /* tty lc */
+ trmop(02005, 1); /* tty tab */
+ trmop(02010, 1); /* tty no crlf */
+ trmop(02020, 0); /* tty no tape */
+ trmop(02021, 1); /* tty page */
+ trmop(02025, 0); /* tty blanks */
+ trmop(02026, 1); /* tty no alt */
+ trmop(02040, 1); /* tty defer */
+#endif
+#ifdef SARG20
+ ttybin(1); /* set line to binary mode */
+#endif
+ /* Set up my personal prejudices */
+
+ esc("<"); /* Enter ANSI mode (if in VT52 mode) */
+ rm("?1"); /* cursor keys normal */
+ rm("?3"); /* 80 col mode */
+ rm("?4"); /* Jump scroll */
+ rm("?5"); /* Normal screen */
+ rm("?6"); /* Absolute origin mode */
+ sm("?7"); /* Wrap around on */
+ rm("?8"); /* Auto repeat off */
+ decstbm(0,0); /* No scroll region */
+ sgr("0"); /* Normal character attributes */
+
+}
+
+bye () {
+ /* Force my personal prejudices upon the poor luser */
+
+ esc("<"); /* Enter ANSI mode (if in VT52 mode) */
+ rm("?1"); /* cursor keys normal */
+ rm("?3"); /* 80 col mode */
+ rm("?5"); /* Normal screen */
+ rm("?6"); /* Absolute origin mode */
+ sm("?7"); /* Wrap around on */
+ sm("?8"); /* Auto repeat on */
+ decstbm(0,0); /* No scroll region */
+ sgr("0"); /* Normal character attributes */
+
+ /* Say goodbye */
+
+ ed(2);
+ cup(12,30);
+ printf("That's all, folks!\n");
+ printf("\n\n\n");
+ inflush();
+#ifdef SARG20
+ ttybin(0); /* reset line to normal mode */
+#endif
+#ifdef UNIX
+ stty(0,&sgttyOrg);
+#endif
+ exit();
+}
+
+#ifdef UNIX
+onbrk() {
+ signal(SIGINT, onbrk);
+ if (reading)
+ brkrd = 1;
+ else
+ longjmp(intrenv, 1);
+}
+
+onterm() {
+ signal(SIGTERM, onterm);
+ longjmp(intrenv, 1);
+}
+#endif
+
+holdit() {
+ inflush();
+ printf("Push <RETURN>");
+ readnl();
+}
+
+readnl() {
+#ifdef UNIX
+ char ch;
+ fflush(stdout);
+ brkrd = 0;
+ reading = 1;
+ do { read(0,&ch,1); } while(ch != '\n' && !brkrd);
+ if (brkrd)
+ kill(getpid(), SIGTERM);
+ reading = 0;
+#endif
+#ifdef SARG10
+ while (getchar() != '\n')
+ ;
+#endif
+#ifdef SARG20
+ while (getchar() != '\n')
+ ;
+#endif
+}
+
+scanto(str, pos, toc) char *str; int *pos; char toc; {
+ char c;
+ int result = 0;
+
+ while (toc != (c = str[(*pos)++])) {
+ if (isdigit(c)) result = result * 10 + c - '0';
+ else break;
+ }
+ if (c == toc) return(result);
+ else return(0);
+}
+
+char *lookup(t, k) struct table t[]; int k; {
+
+ int i;
+ for (i = 0; t[i].key != -1; i++) {
+ if (t[i].key == k) return(t[i].msg);
+ }
+ return("BAD VALUE");
+}
+
+menu(table) char *table[]; {
+
+ int i, tablesize, choice;
+ char c;
+ char storage[80];
+ char *s = storage;
+ println("");
+ tablesize = 0;
+ for (i = 0; *table[i] != '\0'; i++) {
+ printf(" %d. %s\n", i, table[i]);
+ tablesize++;
+ }
+ tablesize--;
+
+ printf("\n Enter choice number (0 - %d): ", tablesize);
+ for(;;) {
+ inputline(s);
+ choice = 0;
+ while (c = *s++) choice = 10 * choice + c - '0';
+ if (choice >= 0 && choice <= tablesize) {
+ ed(2);
+ return (choice);
+ }
+ printf(" Bad choice, try again: ");
+ }
+}
+
+chrprint (s) char *s; {
+
+ int i;
+
+ printf(" ");
+ sgr("7");
+ printf(" ");
+ for (i = 0; s[i] != '\0'; i++) {
+ if (s[i] <= ' ' || s[i] == '\177')
+ printf("<%d> ", s[i]);
+ else printf("%c ", s[i]);
+ }
+ sgr("");
+}
diff --git a/sys/arch/i386/isa/pcvt/Util/vttest/vttest.1 b/sys/arch/i386/isa/pcvt/Util/vttest/vttest.1
new file mode 100644
index 00000000000..c4104925d01
--- /dev/null
+++ b/sys/arch/i386/isa/pcvt/Util/vttest/vttest.1
@@ -0,0 +1,13 @@
+.TH VTTEST 1 "LOCAL"
+.SH NAME
+vttest \- test VT100-type terminal
+.SH SYNOPSIS
+.B vttest
+.SH DESCRIPTION
+.I Vttest
+is a program designed to test the functionality of a VT100 terminal
+(or emulator thereof).
+It tests both display (escape sequence handling) and keyboard.
+.PP
+The program is menu\-driven and contains full on\-line operating
+instructions.
diff --git a/sys/arch/i386/isa/pcvt/pcvt_conf.h b/sys/arch/i386/isa/pcvt/pcvt_conf.h
new file mode 100644
index 00000000000..379475bf49f
--- /dev/null
+++ b/sys/arch/i386/isa/pcvt/pcvt_conf.h
@@ -0,0 +1,475 @@
+/*
+ * Copyright (c) 1992, 1995 Hellmuth Michaelis and Joerg Wunsch.
+ *
+ * Copyright (c) 1992, 1994 Brian Dunford-Shore.
+ *
+ * All rights reserved.
+ *
+ * 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
+ * Hellmuth Michaelis, Brian Dunford-Shore and Joerg Wunsch.
+ * 4. The name authors may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``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 AUTHORS 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.
+ *
+ *
+ * @(#)pcvt_conf.h, 3.32, Last Edit-Date: [Tue Oct 3 11:19:47 1995]
+ *
+ */
+
+/*---------------------------------------------------------------------------
+ *
+ * pcvt_conf.h VT220 driver global configuration file
+ * ------------------------------------------------------
+ * -hm introduced pcvt_conf.h
+ * -hm re-integrated selfconfiguration for NetBSD from Onno
+ * -hm patch from Onno for NetBSD-current
+ * -hm removed PCVT_FAKE_SYSCONS10
+ * -hm ---------------- Release 3.30 -----------------------
+ * -hm patch from Ulf Kieber to support changeable kernel msg colors
+ * -hm ---------------- Release 3.32 -----------------------
+ *
+ *---------------------------------------------------------------------------*/
+
+/*---------------------------------------------------------------------------
+ *
+ * from: Onno van der Linden c/o frank@fwi.uva.nl
+ *
+ * Here's an idea how to automatically detect the version of NetBSD pcvt is
+ * being compiled on:
+ *
+ * NetBSD 1.0 : NetBSD1_0 defined as 1 in <sys/param.h>
+ * NetBSD 1.0A: NetBSD1_0 defined as 2 in <sys/param.h>
+ *
+ * The NetBSDx_y defines are mutual exclusive.
+ *
+ * This leads to something like this in pcvt_hdr.h (#elif is possible too):
+ *
+ *---------------------------------------------------------------------------*/
+
+#ifndef PCVT_NETBSD /* let user force it if needed... */
+#ifdef NetBSD0_8
+#error "NetBSD version 0.8 no longer supported, sorry!"
+#endif
+
+#ifdef NetBSD0_9
+#error "NetBSD version 0.9 no longer supported, sorry!"
+#endif
+
+#ifdef NetBSD1_0
+#if NetBSD1_0 > 1
+#define PCVT_NETBSD 102
+#else
+#define PCVT_NETBSD 100
+#endif
+#endif
+#endif
+
+#ifdef NetBSD1_1
+#define PCVT_NETBSD 110
+#endif
+
+/*---------------------------------------------------------------------------
+ * Note that each of the options below should rather be overriden by the
+ * kernel config file instead of this .h file - this allows for different
+ * definitions in different kernels compiled at the same machine
+ *
+ * The convention is as follows:
+ *
+ * options "PCVT_FOO=1" - enables the option
+ * options "PCVT_FOO" - is a synonym for the above
+ * options "PCVT_FOO=0" - disables the option
+ *
+ * omitting an option defaults to what is shown below
+ *
+ * exceptions from this rule are i.e.:
+ *
+ * options "PCVT_NSCREENS=x"
+ * options "PCVT_SCANSET=x"
+ * options "PCVT_UPDATEFAST=x"
+ * options "PCVT_UPDATESLOW=x"
+ * options "PCVT_SYSBEEPF=x"
+ *
+ * which are always numeric!
+ *---------------------------------------------------------------------------*/
+
+/* -------------------------------------------------------------------- */
+/* -------------------- OPERATING SYSTEM ------------------------------ */
+/* -------------------------------------------------------------------- */
+
+/*
+ * one of the following options must be set in the kernel config file:
+ *
+ *======================================================================*
+ * N e t B S D *
+ *======================================================================*
+ *
+ * options "PCVT_NETBSD=xxx" enables support for NetBSD
+ *
+ * select:
+ * PCVT_NETBSD = 100 for NetBSD 1.0
+ * PCVT_NETBSD = 101 for NetBSD-current before Apr. 21 '95
+ * PCVT_NETBSD = 102 for NetBSD-current after Apr. 21 '95
+ *
+ *
+ *======================================================================*
+ * F r e e B S D *
+ *======================================================================*
+ *
+ * options "PCVT_FREEBSD=xxx" enables support for FreeBSD
+ *
+ * select:
+ * PCVT_FREEBSD = 200 for FreeBSD 2.0-Release
+ * PCVT_FREEBSD = 210 for FreeBSD 2.0.5-Release
+ * (yes, its 210 for 2.0.5 !!!)
+ * (aaand yes, its 210 for 2.1 !!!)
+ *
+ */
+
+/* -------------------------------------------------------------------- */
+/* ---------------- USER PREFERENCE DRIVER OPTIONS -------------------- */
+/* -------------------------------------------------------------------- */
+
+/*----------------------------------------------------------------------*/
+/* NOTE: if FAT_CURSOR is defined, a block cursor is used instead of */
+/* the cursor shape we got from the BIOS, see pcvt_out.c */
+/*----------------------------------------------------------------------*/
+
+#if !defined PCVT_NSCREENS /* ---------- DEFAULT: 8 -------------- */
+# define PCVT_NSCREENS 8 /* this option defines how many virtual */
+#endif /* screens you want to have in your */
+ /* system. each screen allocates memory,*/
+ /* so you can't have an unlimited num- */
+ /* ber...; the value is intented to be */
+ /* compile-time overridable by a config */
+ /* options "PCVT_NSCREENS=x" line */
+
+#if !defined PCVT_VT220KEYB /* ---------- DEFAULT: OFF ------------ */
+# define PCVT_VT220KEYB 0 /* this compiles a more vt220-like */
+#elif PCVT_VT220KEYB != 0 /* keyboardlayout as described in the */
+# undef PCVT_VT220KEYB /* file Keyboard.VT220. */
+# define PCVT_VT220KEYB 1 /* if undefined, a more HP-like */
+#endif /* keyboardlayout is compiled */
+ /* try to find out what YOU like ! */
+
+#if !defined PCVT_SCREENSAVER /* ---------- DEFAULT: ON ------------- */
+# define PCVT_SCREENSAVER 1 /* enable screen saver feature - this */
+#elif PCVT_SCREENSAVER != 0 /* just blanks the display screen. */
+# undef PCVT_SCREENSAVER /* see PCVT_PRETTYSCRNS below ... */
+# define PCVT_SCREENSAVER 1
+#endif
+
+#if !defined PCVT_PRETTYSCRNS /* ---------- DEFAULT: OFF ------------ */
+# define PCVT_PRETTYSCRNS 0 /* for the cost of some microseconds of */
+#elif PCVT_PRETTYSCRNS != 0 /* cpu time this adds a more "pretty" */
+# undef PCVT_PRETTYSCRNS /* version to the screensaver, an "*" */
+# define PCVT_PRETTYSCRNS 1 /* in random locations of the display. */
+#endif /* NOTE: this should not be defined if */
+ /* you have an energy-saving monitor */
+ /* which turns off the display if its */
+ /* black !!!!!! */
+
+#if !defined PCVT_CTRL_ALT_DEL /* ---------- DEFAULT: OFF ------------ */
+# define PCVT_CTRL_ALT_DEL 0 /* this enables the execution of a cpu */
+#elif PCVT_CTRL_ALT_DEL != 0 /* reset by pressing the CTRL, ALT and */
+# undef PCVT_CTRL_ALT_DEL /* DEL keys simultanously. Because this */
+# define PCVT_CTRL_ALT_DEL 1 /* is a feature of an ancient simple */
+#endif /* bootstrap loader, it does not belong */
+ /* into modern operating systems and */
+ /* was commented out by default ... */
+
+#if !defined PCVT_KBD_FIFO /* ---------- DEFAULT: ON ------------- */
+# define PCVT_KBD_FIFO 1 /* this enables Keyboad fifo so that we */
+#elif PCVT_KBD_FIFO != 0 /* are not any longer forced to switch */
+# undef PCVT_KBD_FIFO /* off tty interrupts while switching */
+# define PCVT_KBD_FIFO 1 /* virtual screens - AND loosing chars */
+#endif /* on the serial lines is gone :-) */
+
+#if PCVT_KBD_FIFO
+
+# if !defined PCVT_KBD_FIFO_SZ /* ---------- DEFAULT: 256 ------------ */
+# define PCVT_KBD_FIFO_SZ 256 /* this specifies the size of the above */
+# elif PCVT_KBD_FIFO_SZ < 16 /* mentioned keyboard buffer. buffer */
+# undef PCVT_KBD_FIFO_SZ /* overflows are logged via syslog, so */
+# define PCVT_KBD_FIFO_SZ 256 /* have a look at /var/log/messages */
+# endif
+
+#endif /* PCVT_KBD_FIFO */
+
+#if !defined PCVT_USEKBDSEC /* ---------- DEFAULT: ON ------------- */
+# define PCVT_USEKBDSEC 1 /* do not set the COMMAND_INHOVR bit */
+#elif PCVT_USEKBDSEC != 0 /* (1 = override security lock inhibit) */
+# undef PCVT_USEKBDSEC /* when initializing the keyboard, so */
+# define PCVT_USEKBDSEC 1 /* that security locking should work */
+#endif /* now. I guess this has to be done also*/
+ /* in the boot code to prevent single */
+ /* user startup .... */
+
+#if !defined PCVT_24LINESDEF /* ---------- DEFAULT: OFF ------------ */
+# define PCVT_24LINESDEF 0 /* use 24 lines in VT 25 lines mode and */
+#elif PCVT_24LINESDEF != 0 /* HP 28 lines mode by default to have */
+# undef PCVT_24LINESDEF /* the the better compatibility to the */
+# define PCVT_24LINESDEF 1 /* real VT220 - you can switch between */
+#endif /* the maximum possible screensizes in */
+ /* those two modes (25 lines) and true */
+ /* compatibility (24 lines) by using */
+ /* the scon utility at runtime */
+
+#if !defined PCVT_EMU_MOUSE /* ---------- DEFAULT: OFF ------------ */
+# define PCVT_EMU_MOUSE 0 /* emulate a mouse systems mouse via */
+#elif PCVT_EMU_MOUSE != 0 /* the keypad; this is experimental */
+# undef PCVT_EMU_MOUSE /* code intented to be used on note- */
+# define PCVT_EMU_MOUSE 1 /* books in conjunction with XFree86; */
+#endif /* look at the comments in pcvt_kbd.c */
+ /* if you are interested in testing it. */
+
+#if !defined PCVT_META_ESC /* ---------- DEFAULT: OFF ------------ */
+# define PCVT_META_ESC 0 /* if ON, send the sequence "ESC key" */
+#elif PCVT_META_ESC != 0 /* for a meta-shifted key; if OFF, */
+# undef PCVT_META_ESC /* send the normal key code with 0x80 */
+# define PCVT_META_ESC 1 /* added. */
+#endif
+
+#if !defined PCVT_SW0CNOUTP /* ---------- DEFAULT: OFF ------------ */
+# define PCVT_SW0CNOUTP 0 /* if ON, on console/kernel output the */
+#elif PCVT_SW0CNOUTP != 0 /* current screen is switched to screen */
+# undef PCVT_SW0CNOUTP /* 0 if not already at screen 0. */
+# define PCVT_SW0CNOUTP 1 /* CAUTION: CURRENTLY THIS CAUSES AN X- */
+#endif /* SESSION TO CLUTTER VIDEO MEMORY !!!! */
+
+/* -------------------------------------------------------------------- */
+/* -------------------- DRIVER DEBUGGING ------------------------------ */
+/* -------------------------------------------------------------------- */
+
+#if !defined PCVT_SHOWKEYS /* ---------- DEFAULT: OFF ------------ */
+# define PCVT_SHOWKEYS 0 /* this replaces the system load line */
+#elif PCVT_SHOWKEYS != 0 /* on the vt 0 in hp mode with a display*/
+# undef PCVT_SHOWKEYS /* of the most recent keyboard scan- */
+# define PCVT_SHOWKEYS 1 /* and status codes received from the */
+#endif /* keyboard controller chip. */
+ /* this is just for some hardcore */
+ /* keyboarders .... */
+
+/* -------------------------------------------------------------------- */
+/* -------------------- DRIVER OPTIONS -------------------------------- */
+/* -------------------------------------------------------------------- */
+/* it is unlikely that anybody wants to change anything below */
+
+#if !defined PCVT_NO_LED_UPDATE /* ---------- DEFAULT: OFF ------------ */
+# define PCVT_NO_LED_UPDATE 0 /* On some (Notebook?) keyboards it is */
+#elif PCVT_NO_LED_UPDATE != 0 /* not possible to update the LED's */
+# undef PCVT_NO_LED_UPDATE /* without hanging the keyboard after- */
+# define PCVT_NO_LED_UPDATE 1 /* wards. If you experience Problems */
+#endif /* like this, try to enable this option */
+
+#if !defined PCVT_PORTIO_DELAY /* ---------- DEFAULT: ON ------------- */
+# define PCVT_PORTIO_DELAY 1 /* Defining PCVT_PORTIO_DELAY lets pcvt */
+#elif PCVT_PORTIO_DELAY != 0 /* use multiple accesses to port 0x84 */
+# undef PCVT_PORTIO_DELAY /* to produce a delay of 7 us needed for*/
+# define PCVT_PORTIO_DELAY 1 /* accessing the keyboard controller, */
+#endif /* otherwise the system delay functions */
+ /* are used. */
+
+#if !defined PCVT_PCBURST /* ---------- DEFAULT: 256 ------------ */
+# define PCVT_PCBURST 256 /* NETBSD and FreeBSD >= 2.0 only: this */
+#endif /* is the number of output characters */
+ /* handled together as a burst in */
+ /* routine pcstart(), file pcvt_drv.c */
+
+#if !defined PCVT_SCANSET /* ---------- DEFAULT: 1 -------------- */
+# define PCVT_SCANSET 1 /* define the keyboard scancode set you */
+#endif /* want to use: */
+ /* 1 - code set 1 (supported) */
+ /* 2 - code set 2 (supported) */
+ /* 3 - code set 3 (UNsupported) */
+
+#if !defined PCVT_KEYBDID /* ---------- DEFAULT: ON ------------- */
+# define PCVT_KEYBDID 1 /* check type of keyboard connected. at */
+#elif PCVT_KEYBDID != 0 /* least HP-keyboards send an id other */
+# undef PCVT_KEYBDID /* than the industry standard, so it */
+# define PCVT_KEYBDID 1 /* CAN lead to problems. if you have */
+#endif /* problems with this, TELL ME PLEASE ! */
+
+#if !defined PCVT_SIGWINCH /* ---------- DEFAULT: ON ------------- */
+# define PCVT_SIGWINCH 1 /* this sends a SIGWINCH signal in case */
+#elif PCVT_SIGWINCH != 0 /* the window size is changed. to try, */
+# undef PCVT_SIGWINCH /* issue "scons -s<size>" while in elvis*/
+# define PCVT_SIGWINCH 1 /* and you'll see the effect. */
+#endif /* i'm not sure, whether this feature */
+ /* has to be in the driver or has to */
+ /* move as an ioctl call to scon .... */
+
+#if !defined PCVT_NULLCHARS /* ---------- DEFAULT: ON ------------- */
+# define PCVT_NULLCHARS 1 /* allow the keyboard to send null */
+#elif PCVT_NULLCHARS != 0 /* (0x00) characters to the calling */
+# undef PCVT_NULLCHARS /* program. this has the side effect */
+# define PCVT_NULLCHARS 1 /* that every undefined key also sends */
+#endif /* out nulls. take it as experimental */
+ /* code, this behaviour will change in */
+ /* a future release */
+
+#if !defined PCVT_BACKUP_FONTS /* ---------- DEFAULT: ON ------------- */
+# define PCVT_BACKUP_FONTS 1 /* fonts are always kept memory-backed; */
+#elif PCVT_BACKUP_FONTS != 0 /* otherwise copies are only made if */
+# undef PCVT_BACKUP_FONTS /* they are needed. */
+# define PCVT_BACKUP_FONTS 1
+#endif
+
+#ifndef PCVT_UPDATEFAST /* this is the rate at which the cursor */
+# define PCVT_UPDATEFAST (hz/10) /* gets updated with it's new position */
+#endif /* see: async_update() in pcvt_sup.c */
+
+#ifndef PCVT_UPDATESLOW /* this is the rate at which the cursor */
+# define PCVT_UPDATESLOW 3 /* position display and the system load */
+#endif /* (or the keyboard scancode display) */
+ /* is updated. the relation is: */
+ /* PCVT_UPDATEFAST/PCVT_UPDATESLOW */
+
+#ifndef PCVT_SYSBEEPF /* timer chip value to be used for the */
+# define PCVT_SYSBEEPF 1193182 /* sysbeep frequency value. */
+#endif /* this should really go somewhere else,*/
+ /* e.g. in isa.h; but it used to be in */
+ /* each driver, sometimes even with */
+ /* different values (:-) */
+
+#if !defined PCVT_SETCOLOR /* ---------- DEFAULT: OFF ------------ */
+# define PCVT_SETCOLOR 0 /* enable making colors settable. this */
+#elif PCVT_SETCOLOR != 0 /* introduces a new escape sequence */
+# undef PCVT_SETCOLOR /* <ESC d> which is (i think) not */
+# define PCVT_SETCOLOR 1 /* standardized, so this is an option */
+#endif /* (Birthday present for Bruce ! :-) */
+
+#if !defined PCVT_132GENERIC /* ---------- DEFAULT: OFF ------------ */
+# define PCVT_132GENERIC 0 /* if you #define this, you enable */
+#elif PCVT_132GENERIC != 0 /* EXPERIMENTAL (!!!!!!!!!!!!) */
+# undef PCVT_132GENERIC /* USE-AT-YOUR-OWN-RISK, */
+# define PCVT_132GENERIC 1 /* MAY-DAMAGE-YOUR-MONITOR */
+#endif /* code to switch generic VGA boards/ */
+ /* chipsets to 132 column mode. Since */
+ /* i could not verify this option, i */
+ /* prefer to NOT generally enable this, */
+ /* if you want to play, look at the */
+ /* hints and the code in pcvt_sup.c and */
+ /* get in contact with Joerg Wunsch, who*/
+ /* submitted this code. Be careful !!! */
+
+#if !defined PCVT_PALFLICKER /* ---------- DEFAULT: OFF ------------ */
+# define PCVT_PALFLICKER 0 /* this option turns off the screen */
+#elif PCVT_PALFLICKER != 0 /* during accesses to the VGA DAC */
+# undef PCVT_PALFLICKER /* registers. why: on one fo the tested */
+# define PCVT_PALFLICKER 1 /* pc's (WD-chipset), accesses to the */
+#endif /* vga dac registers caused distortions */
+ /* on the screen. Ferraro says, one has */
+ /* to blank the screen. the method used */
+ /* to accomplish this stopped the noise */
+ /* but introduced another flicker, so */
+ /* this is for you to experiment ..... */
+ /* - see also PCVT_WAITRETRACE below -- */
+
+#if !defined PCVT_WAITRETRACE /* ---------- DEFAULT: OFF ------------ */
+# define PCVT_WAITRETRACE 0 /* this option waits for being in a */
+#elif PCVT_WAITRETRACE != 0 /* retrace window prior to accessing */
+# undef PCVT_WAITRETRACE /* the VGA DAC registers. */
+# define PCVT_WAITRETRACE 1 /* this is the other method Ferraro */
+#endif /* mentioned in his book. this option */
+ /* did eleminate the flicker noticably */
+ /* but not completely. besides that, it */
+ /* is implemented as a busy-wait loop */
+ /* which is a no-no-no in environments */
+ /* like this - VERY BAD PRACTICE !!!!! */
+ /* the other method implementing it is */
+ /* using the vertical retrace irq, but */
+ /* we get short of irq-lines on pc's. */
+ /* this is for you to experiment ..... */
+ /* -- see also PCVT_PALFLICKER above -- */
+
+#if !defined PCVT_INHIBIT_NUMLOCK /* --------- DEFAULT: OFF ----------- */
+# define PCVT_INHIBIT_NUMLOCK 0 /* A notebook hack: since i am getting */
+#elif PCVT_INHIBIT_NUMLOCK != 0 /* tired of the numlock LED always */
+# undef PCVT_INHIBIT_NUMLOCK /* being turned on - which causes the */
+# define PCVT_INHIBIT_NUMLOCK 1 /* right half of my keyboard being */
+#endif /* interpreted as a numeric keypad and */
+ /* thus going unusable - i want to */
+ /* have a better control over it. If */
+ /* this option is enabled, only the */
+ /* numlock key itself and the related */
+ /* ioctls will modify the numlock */
+ /* LED. (The ioctl is needed for the */
+ /* ServerNumLock feature of XFree86.) */
+ /* The default state is changed to */
+ /* numlock off, and the escape */
+ /* sequences to switch between numeric */
+ /* and application mode keypad are */
+ /* silently ignored. */
+
+#if !defined PCVT_NOFASTSCROLL /* ---------- DEFAULT: OFF ------------ */
+# define PCVT_NOFASTSCROLL 0 /* If off, enables code for fast scroll.*/
+#elif PCVT_NOFASTSCROLL != 0 /* This is done by changing the CRTC */
+# undef PCVT_NOFASTSCROLL /* screen start address for scrolling */
+# define PCVT_NOFASTSCROLL 1 /* and using 2 times the screen size as */
+#endif /* buffer. The fastscroll code works */
+ /* ONLY for VGA/EGA/CGA because it uses */
+ /* the crtc for hardware scrolling and */
+ /* therefore needs more than the one */
+ /* page video memory MDA and most */
+ /* Hercules boards support. */
+ /* If you run pcvt ONLY on MDA/Hercules */
+ /* you should disable fastscroll to save*/
+ /* the time to decide which board you */
+ /* are running pcvt on at runtime. */
+ /* [see roll_up() and roll_down().] */
+
+#if !defined PCVT_MDAFASTSCROLL /* ---------- DEFAULT: OFF ------------ */
+# define PCVT_MDAFASTSCROLL 0 /* If on, enables code for fast scroll */
+#elif PCVT_MDAFASTSCROLL != 0 /* on MDA/Hercules (see notes for */
+# undef PCVT_MDAFASTSCROLL /* PCVT_NOFASTSCROLL). Works only on */
+# define PCVT_MDAFASTSCROLL 1 /* MDA/Hercules which do support more */
+#endif /* than one page of video memory. */
+
+#if !defined PCVT_SLOW_INTERRUPT/* ---------- DEFAULT: OFF ------------ */
+# define PCVT_SLOW_INTERRUPT 0 /* If off, protecting critical regions */
+#elif PCVT_SLOW_INTERRUPT != 0 /* in the keyboard fifo code is done by */
+# undef PCVT_SLOW_INTERRUPT /* disabling the processor irq's, if on */
+# define PCVT_SLOW_INTERRUPT 1 /* this is done by spl()/splx() calls. */
+#endif
+
+/*---------------------------------------------------------------------------*
+ * Kernel messages attribute definitions
+ * These define the foreground and background attributes used to
+ * emphasize messages from the kernel on color and mono displays.
+ *---------------------------------------------------------------------------*/
+
+#if !defined COLOR_KERNEL_FG /* color displays */
+#define COLOR_KERNEL_FG FG_LIGHTGREY /* kernel messages, foreground */
+#endif
+#if !defined COLOR_KERNEL_BG
+#define COLOR_KERNEL_BG BG_RED /* kernel messages, background */
+#endif
+
+#if !defined MONO_KERNEL_FG /* monochrome displays */
+#define MONO_KERNEL_FG FG_UNDERLINE /* kernel messages, foreground */
+#endif
+#if !defined MONO_KERNEL_BG
+#define MONO_KERNEL_BG BG_BLACK /* kernel messages, background */
+#endif
+
+/*---------------------------------- E O F ----------------------------------*/
diff --git a/sys/arch/i386/isa/pcvt/pcvt_drv.c b/sys/arch/i386/isa/pcvt/pcvt_drv.c
new file mode 100644
index 00000000000..ad0cc727d95
--- /dev/null
+++ b/sys/arch/i386/isa/pcvt/pcvt_drv.c
@@ -0,0 +1,1336 @@
+/*
+ * Copyright (c) 1992, 1995 Hellmuth Michaelis and Joerg Wunsch.
+ *
+ * Copyright (c) 1992, 1993 Brian Dunford-Shore and Scott Turner.
+ *
+ * Copyright (c) 1993 Charles Hannum.
+ *
+ * All rights reserved.
+ *
+ * Parts of this code regarding the NetBSD interface were written
+ * by Charles Hannum.
+ *
+ * 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
+ * Hellmuth Michaelis, Brian Dunford-Shore, Joerg Wunsch, Scott Turner
+ * and Charles Hannum.
+ * 4. The name authors may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``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 AUTHORS 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.
+ *
+ *
+ * @(#)pcvt_drv.c, 3.32, Last Edit-Date: [Tue Oct 3 11:19:47 1995]
+ *
+ */
+
+/*---------------------------------------------------------------------------*
+ *
+ * pcvt_drv.c VT220 Driver Main Module / OS - Interface
+ * ---------------------------------------------------------
+ * -hm ------------ Release 3.00 --------------
+ * -hm integrating NetBSD-current patches
+ * -hm adding ttrstrt() proto for NetBSD 0.9
+ * -hm kernel/console output cursor positioning fixed
+ * -hm kernel/console output switches optional to screen 0
+ * -hm FreeBSD 1.1 porting
+ * -hm the NetBSD 0.9 compiler detected a nondeclared var which was
+ * NOT detected by neither the NetBSD-current nor FreeBSD 1.x!
+ * -hm including Michael's keyboard fifo code
+ * -hm Joergs patch for FreeBSD tty-malloc code
+ * -hm adjustments for NetBSD-current
+ * -hm FreeBSD bugfix from Joerg re timeout/untimeout casts
+ * -jw including Thomas Gellekum's FreeBSD 1.1.5 patch
+ * -hm adjusting #if's for NetBSD-current
+ * -hm applying Joerg's patch for FreeBSD 2.0
+ * -hm patch from Onno & Martin for NetBSD-current (post 1.0)
+ * -hm some adjustments for NetBSD 1.0
+ * -hm NetBSD PR #400: screen size report for new session
+ * -hm patch from Rafael Boni/Lon Willett for NetBSD-current
+ * -hm bell patch from Thomas Eberhardt for NetBSD
+ * -hm multiple X server bugfixes from Lon Willett
+ * -hm patch from joerg - pcdevtotty for FreeBSD pre-2.1
+ * -hm delay patch from Martin Husemann after port-i386 ml-discussion
+ * -jw add some code to provide more FreeBSD pre-2.1 support
+ * -hm patches from Michael for NetBSD-current (Apr/21/95) support
+ * -hm merged in changes from FreeBSD 2.0.5-RELEASE
+ * -hm NetBSD-current patches from John Kohl
+ * -hm ---------------- Release 3.30 -----------------------
+ * -hm patch from Joerg in pcopen() to make mouse emulator work again
+ * -hm patch from Frank van der Linden for keyboard state per VT
+ * -hm no TS_ASLEEP anymore in FreeBSD 2.1.0 SNAP 950928
+ * -hm ---------------- Release 3.32 -----------------------
+ *
+ *---------------------------------------------------------------------------*/
+
+#include "vt.h"
+#if NVT > 0
+
+#define EXTERN /* allocate mem */
+
+#include "pcvt_hdr.h" /* global include */
+
+#ifdef NOTDEF
+unsigned __debug = 0; /*0xffe */;
+static __color;
+static nrow;
+#endif
+
+static void vgapelinit(void); /* read initial VGA DAC palette */
+
+#if PCVT_FREEBSD > 205
+static struct kern_devconf kdc_vt[];
+static inline void
+vt_registerdev(struct isa_device *id, const char *name);
+static char vt_description[];
+#define VT_DESCR_LEN 40
+#endif /* PCVT_FREEBSD > 205 */
+
+#if PCVT_NETBSD > 100 /* NetBSD-current Feb 20 1995 */
+int
+pcprobe(struct device *parent, void *match, void *aux)
+#else /* !PCVT_NETBSD > 100 */
+
+#if PCVT_NETBSD > 9
+int
+pcprobe(struct device *parent, struct device *self, void *aux)
+#else /* !PCVT_NETBSD > 9 */
+int
+pcprobe(struct isa_device *dev)
+#endif /* PCVT_NETBSD > 9 */
+
+#endif /* PCVT_NETBSD > 100 */
+{
+ kbd_code_init();
+
+#if PCVT_NETBSD > 9
+ ((struct isa_attach_args *)aux)->ia_iosize = 16;
+ return 1;
+#else /* !PCVT_NETBSD > 9 */
+
+#if PCVT_NETBSD || PCVT_FREEBSD
+ return (16);
+#else
+ return 1;
+#endif /* PCVT_NETBSD || PCVT_FREEBSD */
+
+#endif /* PCVT_NETBSD > 9 */
+
+}
+
+#if PCVT_NETBSD > 9
+void
+pcattach(struct device *parent, struct device *self, void *aux)
+{
+ struct isa_attach_args *ia = aux;
+
+#if PCVT_NETBSD > 101
+ struct vt_softc *sc = (void *) self;
+#else /* !PCVT_NETBSD > 101 */
+ static struct intrhand vthand;
+#endif /* PCVT_NETBSD > 101 */
+
+#else /* !PCVT_NETBSD > 9 */
+int
+pcattach(struct isa_device *dev)
+{
+#endif /* PCVT_NETBSD > 9 */
+
+ int i;
+
+ vt_coldmalloc(); /* allocate memory for screens */
+
+#if PCVT_NETBSD || PCVT_FREEBSD
+
+#if PCVT_NETBSD > 9
+ printf(": ");
+#else
+ printf("vt%d: ", dev->id_unit);
+#endif /* PCVT_NETBSD > 9 */
+
+ switch(adaptor_type)
+ {
+ case MDA_ADAPTOR:
+ printf("mda");
+ break;
+
+ case CGA_ADAPTOR:
+ printf("cga");
+ break;
+
+ case EGA_ADAPTOR:
+ printf("ega");
+ break;
+
+ case VGA_ADAPTOR:
+ printf("%s, ", (char *)vga_string(vga_type));
+ if(can_do_132col)
+ printf("80/132 col");
+ else
+ printf("80 col");
+ vgapelinit();
+ break;
+
+ default:
+ printf("unknown");
+ break;
+ }
+
+ if(color == 0)
+ printf(", mono");
+ else
+ printf(", color");
+
+ printf(", %d scr, ", totalscreens);
+
+ switch(keyboard_type)
+ {
+ case KB_AT:
+ printf("at-");
+ break;
+
+ case KB_MFII:
+ printf("mf2-");
+ break;
+
+ default:
+ printf("unknown ");
+ break;
+ }
+
+ printf("kbd, [R%s]\n", PCVT_REL);
+
+#if PCVT_NETBSD || (PCVT_FREEBSD > 110 && PCVT_FREEBSD < 200)
+
+ for(i = 0; i < totalscreens; i++)
+ {
+
+#if PCVT_NETBSD > 100
+ vs[i].vs_tty = ttymalloc();
+#else /* !PCVT_NETBSD > 100 */
+
+#if PCVT_NETBSD
+ pc_tty[i] = ttymalloc();
+ vs[i].vs_tty = pc_tty[i];
+#else /* !PCVT_NETBSD */
+ pccons[i] = ttymalloc(pccons[i]);
+ vs[i].vs_tty = pccons[i];
+#endif /* PCVT_NETBSD */
+
+#endif /* PCVT_NETBSD > 100 */
+
+ }
+
+#if PCVT_EMU_MOUSE
+#if PCVT_NETBSD
+ pc_tty[totalscreens] = ttymalloc(); /* the mouse emulator tty */
+#else /* !PCVT_NETBSD */
+ /* the mouse emulator tty */
+ pc_tty[totalscreens] = ttymalloc(pccons[totalscreens]);
+#endif /* PCVT_NETBSD */
+#endif /* PCVT_EMU_MOUSE */
+
+#if PCVT_NETBSD
+ pcconsp = vs[0].vs_tty;
+#else /* !PCVT_NETBSD */
+ pcconsp = pccons[0];
+#endif /* PCVT_NETBSD */
+
+#endif /* #if PCVT_NETBSD || (PCVT_FREEBSD > 110 && PCVT_FREEBSD < 200) */
+
+#else /* !PCVT_NETBSD && !PCVT_FREEBSD*/
+
+ switch(adaptor_type)
+ {
+ case MDA_ADAPTOR:
+ printf(" <mda");
+ break;
+
+ case CGA_ADAPTOR:
+ printf(" <cga");
+ break;
+
+ case EGA_ADAPTOR:
+ printf(" <ega");
+ break;
+
+ case VGA_ADAPTOR:
+ printf(" <%s,", (char *)vga_string(vga_type));
+ if(can_do_132col)
+ printf("80/132 col");
+ else
+ printf("80 col");
+ vgapelinit();
+ break;
+
+ default:
+ printf(" <unknown");
+ break;
+ }
+
+ if(color == 0)
+ printf(",mono");
+ else
+ printf(",color");
+
+ printf(",%d scr,", totalscreens);
+
+ switch(keyboard_type)
+ {
+ case KB_AT:
+ printf("at-");
+ break;
+
+ case KB_MFII:
+ printf("mf2-");
+ break;
+
+ default:
+ printf("unknown ");
+ break;
+ }
+
+ printf("kbd,[R%s]>", PCVT_REL);
+
+#endif /* PCVT_NETBSD || PCVT_FREEBSD */
+
+#if !PCVT_NETBSD && !(PCVT_FREEBSD > 110 && PCVT_FREEBSD < 200)
+ for(i = 0; i < totalscreens; i++)
+ vs[i].vs_tty = &pccons[i];
+#endif /* !PCVT_NETBSD && !(PCVT_FREEBSD > 110 && PCVT_FREEBSD < 200) */
+
+ async_update(UPDATE_START); /* start asynchronous updates */
+
+#if PCVT_FREEBSD > 205
+ /* mark the device busy now if we are the console */
+ kdc_vt[dev->id_unit].kdc_state =
+ pcvt_is_console? DC_IDLE: DC_BUSY;
+ vt_registerdev(dev, (char *)vga_string(vga_type));
+#endif /* PCVT_FREEBSD > 205 */
+
+#if PCVT_NETBSD > 9
+
+#if PCVT_NETBSD > 101
+ sc->sc_ih = isa_intr_establish(ia->ia_irq, ISA_IST_EDGE, ISA_IPL_TTY,
+ pcintr, (void *)0);
+#else /* PCVT_NETBSD > 100 */
+ vthand.ih_fun = pcrint;
+ vthand.ih_arg = 0;
+ vthand.ih_level = IPL_TTY;
+ intr_establish(ia->ia_irq, &vthand);
+#endif /* PCVT_NETBSD > 100 */
+
+#else /* PCVT_NETBSD > 9 */
+
+ return 1;
+
+#endif /* PCVT_NETBSD > 9 */
+
+}
+
+/* had a look at the friedl driver */
+
+#if !PCVT_NETBSD
+
+struct tty *
+get_pccons(Dev_t dev)
+{
+ register int i = minor(dev);
+
+#if PCVT_EMU_MOUSE
+ if(i == totalscreens)
+#if !(PCVT_FREEBSD > 110 && PCVT_FREEBSD < 200)
+ return(&pccons[i]);
+#else
+ return(pccons[i]);
+#endif /* !(PCVT_FREEBSD > 110 && PCVT_FREEBSD < 200) */
+#endif /* PCVT_EMU_MOUSE */
+
+ if(i >= PCVT_NSCREENS)
+ return(NULL);
+#if !(PCVT_FREEBSD > 110 && PCVT_FREEBSD < 200)
+ return(&pccons[i]);
+#else
+ return(pccons[i]);
+#endif
+}
+
+#else
+
+struct tty *
+get_pccons(Dev_t dev)
+{
+ register int i = minor(dev);
+
+#if PCVT_EMU_MOUSE
+ if(i == totalscreens)
+ return(pc_tty[i]);
+#endif /* PCVT_EMU_MOUSE */
+
+ if(i >= PCVT_NSCREENS)
+ return(NULL);
+
+ return(vs[i].vs_tty);
+}
+
+#endif /* !PCVT_NETBSD */
+
+/*---------------------------------------------------------------------------*
+ * /dev/ttyc0, /dev/ttyc1, etc.
+ *---------------------------------------------------------------------------*/
+int
+pcopen(Dev_t dev, int flag, int mode, struct proc *p)
+{
+ register struct tty *tp;
+ register struct video_state *vsx;
+ int s, retval;
+ int winsz = 0;
+ int i = minor(dev);
+
+#if PCVT_EMU_MOUSE
+ if(i == totalscreens)
+ vsx = 0;
+ else
+#endif /* PCVT_EMU_MOUSE */
+
+ vsx = &vs[i];
+
+ if((tp = get_pccons(dev)) == NULL)
+ return ENXIO;
+
+#if PCVT_EMU_MOUSE
+ if(i == totalscreens)
+ {
+ if(mouse.opened == 0)
+ mouse.buttons = mouse.extendedseen =
+ mouse.breakseen = mouse.lastmove.tv_sec = 0;
+ mouse.minor = i;
+ mouse.opened++;
+ }
+ else
+#endif /* PCVT_EMU_MOUSE */
+
+ vsx->openf++;
+
+ tp->t_oproc = pcstart;
+ tp->t_param = pcparam;
+ tp->t_dev = dev;
+
+ if ((tp->t_state & TS_ISOPEN) == 0)
+ {
+
+#if !(PCVT_FREEBSD > 114)
+ tp->t_state |= TS_WOPEN;
+#endif /* !(PCVT_FREEBSD > 114) */
+
+ 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;
+ tp->t_cflag |= CLOCAL; /* cannot be a modem (:-) */
+
+ if ((tp->t_state & TS_ISOPEN) == 0) /* is this a "cold" open ? */
+ winsz = 1; /* yes, set winsize later */
+
+#if PCVT_NETBSD || (PCVT_FREEBSD >= 200)
+ retval = ((*linesw[tp->t_line].l_open)(dev, tp));
+#else
+ retval = ((*linesw[tp->t_line].l_open)(dev, tp, flag));
+#endif /* PCVT_NETBSD || (PCVT_FREEBSD >= 200) */
+
+ if(winsz == 1
+#if PCVT_EMU_MOUSE
+ && vsx /* the mouse device has no vsx */
+#endif /* PCVT_EMU_MOUSE */
+ )
+ {
+
+ /*
+ * The line discipline has clobbered t_winsize if TS_ISOPEN
+ * was clear. (NetBSD PR #400 from Bill Sommerfeld)
+ * We have to do this after calling the open routine, because
+ * it does some other things in other/older *BSD releases -hm
+ */
+
+ s = spltty();
+
+ tp->t_winsize.ws_col = vsx->maxcol;
+ tp->t_winsize.ws_row = vsx->screen_rows;
+ tp->t_winsize.ws_xpixel = (vsx->maxcol == 80)? 720: 1056;
+ tp->t_winsize.ws_ypixel = 400;
+
+ splx(s);
+ }
+
+#if PCVT_FREEBSD > 205
+ if(retval == 0)
+ {
+ /* XXX currently, only one vt device is supported */
+ kdc_vt[0].kdc_state = DC_BUSY;
+ }
+#endif
+
+ return(retval);
+}
+
+int
+pcclose(Dev_t dev, int flag, int mode, struct proc *p)
+{
+ register struct tty *tp;
+ register struct video_state *vsx;
+ int i = minor(dev);
+
+#if PCVT_EMU_MOUSE
+ if(i == totalscreens)
+ vsx = 0;
+ else
+#endif /* PCVT_EMU_MOUSE */
+
+ vsx = &vs[i];
+
+ if((tp = get_pccons(dev)) == NULL)
+ return ENXIO;
+
+ (*linesw[tp->t_line].l_close)(tp, flag);
+ ttyclose(tp);
+
+#if PCVT_EMU_MOUSE
+ if(i == totalscreens)
+ mouse.opened = 0;
+ else
+#endif /* PCVT_EMU_MOUSE */
+
+ vsx->openf = 0;
+
+#if PCVT_EMU_MOUSE
+
+ if(i == totalscreens)
+ return (0);
+
+#endif /* PCVT_EMU_MOUSE */
+
+ reset_usl_modes(vsx);
+
+#if PCVT_FREEBSD > 205
+ if(!pcvt_is_console)
+ {
+ /* XXX currently, only one vt device is supported */
+ kdc_vt[0].kdc_state = DC_IDLE;
+ }
+#endif
+
+ return(0);
+}
+
+int
+pcread(Dev_t dev, struct uio *uio, int flag)
+{
+ register struct tty *tp;
+
+ if((tp = get_pccons(dev)) == NULL)
+ return ENXIO;
+
+ return ((*linesw[tp->t_line].l_read)(tp, uio, flag));
+}
+
+int
+pcwrite(Dev_t dev, struct uio *uio, int flag)
+{
+ register struct tty *tp;
+
+ if((tp = get_pccons(dev)) == NULL)
+ return ENXIO;
+
+ return ((*linesw[tp->t_line].l_write)(tp, uio, flag));
+}
+
+#if PCVT_NETBSD > 101
+struct tty *
+pctty(Dev_t dev)
+{
+ register struct tty *tp;
+
+ if((tp = get_pccons(dev)) == NULL)
+ return 0;
+
+ return tp;
+}
+#endif /* PCVT_NETBSD > 101 */
+
+int
+pcioctl(Dev_t dev, int cmd, caddr_t data, int flag, struct proc *p)
+{
+ register error;
+ register struct tty *tp;
+
+ if((tp = get_pccons(dev)) == NULL)
+ return(ENXIO);
+
+ /* note that some ioctl's are global, e.g. KBSTPMAT: There is
+ * only one keyboard and different repeat rates for instance between
+ * sessions are a suspicious wish. If you really need this make the
+ * appropriate variables arrays
+ */
+
+#if PCVT_EMU_MOUSE
+ if(minor(dev) == totalscreens)
+ {
+ if((error = mouse_ioctl(dev, cmd, data)) >= 0)
+ return error;
+ goto do_standard;
+ }
+#endif /* PCVT_EMU_MOUSE */
+
+#ifdef XSERVER
+
+ if((error = usl_vt_ioctl(dev, cmd, data, flag, p)) >= 0)
+ return error;
+
+ /*
+ * just for compatibility:
+ * XFree86 < 2.0 and SuperProbe still might use it
+ *
+ * NB: THIS IS A HACK! Do not use it unless you explicitly need.
+ * Especially, since the vty is not put into process-controlled
+ * mode (this would require the application to co-operate), any
+ * attempts to switch vtys while this kind of X mode is active
+ * may cause serious trouble.
+ */
+ switch(cmd)
+ {
+ case CONSOLE_X_MODE_ON:
+ {
+ int i;
+
+ if((error = usl_vt_ioctl(dev, KDENABIO, 0, flag, p)) > 0)
+ return error;
+
+ i = KD_GRAPHICS;
+ if((error = usl_vt_ioctl(dev, KDSETMODE, (caddr_t)&i, flag, p))
+ > 0)
+ return error;
+
+ i = K_RAW;
+ error = usl_vt_ioctl(dev, KDSKBMODE, (caddr_t)&i, flag, p);
+ return error;
+ }
+
+ case CONSOLE_X_MODE_OFF:
+ {
+ int i;
+
+ (void)usl_vt_ioctl(dev, KDDISABIO, 0, flag, p);
+
+ i = KD_TEXT;
+ (void)usl_vt_ioctl(dev, KDSETMODE, (caddr_t)&i, flag, p);
+
+ i = K_XLATE;
+ (void)usl_vt_ioctl(dev, KDSKBMODE, (caddr_t)&i, flag, p);
+ return 0;
+ }
+
+
+ case CONSOLE_X_BELL:
+
+ /*
+ * If `data' is non-null, the first int value denotes
+ * the pitch, the second a duration. Otherwise, behaves
+ * like BEL.
+ */
+
+ if (data)
+ {
+
+#if PCVT_NETBSD
+ sysbeep(((int *)data)[0],
+ ((int *)data)[1] * hz / 1000);
+#else /* PCVT_NETBSD */
+ sysbeep(PCVT_SYSBEEPF / ((int *)data)[0],
+ ((int *)data)[1] * hz / 3000);
+#endif /* PCVT_NETBSD */
+
+ }
+ else
+ {
+ sysbeep(PCVT_SYSBEEPF / 1493, hz / 4);
+ }
+ return (0);
+
+ default: /* fall through */ ;
+ }
+
+#endif /* XSERVER */
+
+ if((error = kbdioctl(dev,cmd,data,flag)) >= 0)
+ return error;
+
+ if((error = vgaioctl(dev,cmd,data,flag)) >= 0)
+ return error;
+
+#if PCVT_EMU_MOUSE
+do_standard:
+#endif /* PCVT_EMU_MOUSE */
+
+#if PCVT_NETBSD > 9 || PCVT_FREEBSD >= 200
+ if((error = (*linesw[tp->t_line].l_ioctl)(tp, cmd, data, flag, p)) >= 0)
+ return (error);
+#else
+ if((error = (*linesw[tp->t_line].l_ioctl)(tp, cmd, data, flag)) >= 0)
+ return(error);
+#endif /* PCVT_NETBSD > 9 || PCVT_FREEBSD >= 200 */
+
+#if PCVT_NETBSD > 9
+ if((error = ttioctl(tp, cmd, data, flag, p)) >= 0)
+ return (error);
+#else
+ if((error = ttioctl(tp, cmd, data, flag)) >= 0)
+ return (error);
+#endif /* PCVT_NETBSD > 9 */
+
+ return (ENOTTY);
+}
+
+int
+pcmmap(Dev_t dev, int offset, int nprot)
+{
+ if (offset > 0x20000)
+ return -1;
+ return i386_btop((0xa0000 + offset));
+}
+
+#if PCVT_FREEBSD > 205
+struct tty *
+pcdevtotty(Dev_t dev)
+{
+ return get_pccons(dev);
+}
+
+static char vt_descr[VT_DESCR_LEN] = "Graphics console: ";
+
+static struct kern_devconf kdc_vt[NVT] = {
+ 0, 0, 0, /* filled in by dev_attach */
+ "vt", 0, { MDDT_ISA, 0, "tty" },
+ isa_generic_externalize, 0, 0, ISA_EXTERNALLEN,
+ &kdc_isa0, /* parent */
+ 0, /* parentdata */
+ DC_UNCONFIGURED, /* until we know it better */
+ vt_descr
+};
+
+static inline void
+vt_registerdev(struct isa_device *id, const char *name)
+{
+ if(id->id_unit)
+ kdc_vt[id->id_unit] = kdc_vt[0];
+
+ kdc_vt[id->id_unit].kdc_unit = id->id_unit;
+ kdc_vt[id->id_unit].kdc_isa = id;
+
+ /* XXX only vt0 currently allowed */
+ strncpy(vt_descr + sizeof("Graphics console: ") - 1,
+ name,
+ VT_DESCR_LEN - sizeof("Graphics console: "));
+
+ dev_attach(&kdc_vt[id->id_unit]);
+}
+
+#endif /* PCVT_FREEBSD > 205 */
+
+/*---------------------------------------------------------------------------*
+ *
+ * handle a keyboard receive interrupt
+ *
+ * NOTE: the keyboard is multiplexed by means of "pcconsp"
+ * between virtual screens. pcconsp - switching is done in
+ * the vgapage() routine
+ *
+ *---------------------------------------------------------------------------*/
+
+#if PCVT_KBD_FIFO
+
+u_char pcvt_kbd_fifo[PCVT_KBD_FIFO_SZ];
+int pcvt_kbd_wptr = 0;
+int pcvt_kbd_rptr = 0;
+short pcvt_kbd_count= 0;
+static u_char pcvt_timeout_scheduled = 0;
+
+static void pcvt_timeout (void *arg)
+{
+ u_char *cp;
+
+#if PCVT_SLOW_INTERRUPT
+ int s;
+#endif
+
+ pcvt_timeout_scheduled = 0;
+
+#if PCVT_SCREENSAVER
+ pcvt_scrnsv_reset();
+#endif /* PCVT_SCREENSAVER */
+
+ while (pcvt_kbd_count)
+ {
+ if (((cp = sgetc(1)) != 0) &&
+ (vs[current_video_screen].openf))
+ {
+
+#if PCVT_NULLCHARS
+ if(*cp == '\0')
+ {
+ /* pass a NULL character */
+ (*linesw[pcconsp->t_line].l_rint)('\0', pcconsp);
+ }
+/* XXX */ else
+#endif /* PCVT_NULLCHARS */
+
+ while (*cp)
+ (*linesw[pcconsp->t_line].l_rint)(*cp++ & 0xff, pcconsp);
+ }
+
+ PCVT_DISABLE_INTR ();
+
+ if (!pcvt_kbd_count)
+ pcvt_timeout_scheduled = 0;
+
+ PCVT_ENABLE_INTR ();
+ }
+
+ return;
+}
+#endif
+
+#if PCVT_NETBSD > 101
+int
+pcintr(void *arg)
+#else
+int
+pcrint(void)
+#endif
+{
+
+#if PCVT_KBD_FIFO
+ u_char dt;
+ u_char ret = -1;
+
+# if PCVT_SLOW_INTERRUPT
+ int s;
+# endif
+
+#else /* !PCVT_KBD_FIFO */
+ u_char *cp;
+#endif /* PCVT_KBD_FIFO */
+
+#if PCVT_SCREENSAVER
+ pcvt_scrnsv_reset();
+#endif /* PCVT_SCREENSAVER */
+
+#if PCVT_KBD_FIFO
+ if (kbd_polling)
+ {
+ if(sgetc(1) == 0)
+ return -1;
+ else
+ return 1;
+ }
+
+ while (inb(CONTROLLER_CTRL) & STATUS_OUTPBF) /* check 8042 buffer */
+ {
+ ret = 1; /* got something */
+
+ PCVT_KBD_DELAY(); /* 7 us delay */
+
+ dt = inb(CONTROLLER_DATA); /* get it 8042 data */
+
+ if (pcvt_kbd_count >= PCVT_KBD_FIFO_SZ) /* fifo overflow ? */
+ {
+ log (LOG_WARNING, "pcvt: keyboard buffer overflow\n");
+ }
+ else
+ {
+ pcvt_kbd_fifo[pcvt_kbd_wptr++] = dt; /* data -> fifo */
+
+ PCVT_DISABLE_INTR (); /* XXX necessary ? */
+ pcvt_kbd_count++; /* update fifo count */
+ PCVT_ENABLE_INTR ();
+
+ if (pcvt_kbd_wptr >= PCVT_KBD_FIFO_SZ)
+ pcvt_kbd_wptr = 0; /* wraparound pointer */
+ }
+ }
+
+ if (ret == 1) /* got data from keyboard ? */
+ {
+ if (!pcvt_timeout_scheduled) /* if not already active .. */
+ {
+ PCVT_DISABLE_INTR ();
+ pcvt_timeout_scheduled = 1; /* flag active */
+ timeout((TIMEOUT_FUNC_T)pcvt_timeout, (caddr_t) 0, 1); /* fire off */
+ PCVT_ENABLE_INTR ();
+ }
+ }
+ return (ret);
+
+#else /* !PCVT_KBD_FIFO */
+
+ if((cp = sgetc(1)) == 0)
+ return -1;
+
+ if (kbd_polling)
+ return 1;
+
+ if(!(vs[current_video_screen].openf)) /* XXX was vs[minor(dev)] */
+ return 1;
+
+#if PCVT_NULLCHARS
+ if(*cp == '\0')
+ {
+ /* pass a NULL character */
+ (*linesw[pcconsp->t_line].l_rint)('\0', pcconsp);
+ return 1;
+ }
+#endif /* PCVT_NULLCHARS */
+
+ while (*cp)
+ (*linesw[pcconsp->t_line].l_rint)(*cp++ & 0xff, pcconsp);
+ return 1;
+
+#endif /* PCVT_KBD_FIFO */
+}
+
+
+#if PCVT_NETBSD || PCVT_FREEBSD >= 200
+
+#if PCVT_NETBSD == 9
+extern void ttrstrt();
+#endif /* PCVT_NETBSD == 9 */
+
+void
+pcstart(register struct tty *tp)
+{
+ register struct clist *rbp;
+ int s, len;
+ u_char buf[PCVT_PCBURST];
+
+ s = spltty();
+
+ if (tp->t_state & (TS_TIMEOUT|TS_BUSY|TS_TTSTOP))
+ goto out;
+
+ tp->t_state |= TS_BUSY;
+
+ splx(s);
+
+ async_update(UPDATE_KERN);
+
+ /*
+ * We need to do this outside spl since it could be fairly
+ * expensive and we don't want our serial ports to overflow.
+ */
+
+ rbp = &tp->t_outq;
+
+ while (len = q_to_b(rbp, buf, PCVT_PCBURST))
+ sput(&buf[0], 0, len, minor(tp->t_dev));
+
+ s = spltty();
+
+ tp->t_state &= ~TS_BUSY;
+
+ if (rbp->c_cc)
+ {
+ tp->t_state |= TS_TIMEOUT;
+ timeout(ttrstrt, tp, 1);
+ }
+
+#if PCVT_FREEBSD >= 210 && !defined(TS_ASLEEP)
+ ttwakeup(tp);
+#else
+ if (rbp->c_cc <= tp->t_lowat)
+ {
+ if (tp->t_state&TS_ASLEEP)
+ {
+ tp->t_state &= ~TS_ASLEEP;
+ wakeup((caddr_t)rbp);
+ }
+ selwakeup(&tp->t_wsel);
+ }
+#endif
+
+out:
+ splx(s);
+}
+
+void
+pcstop(struct tty *tp, int flag)
+{
+}
+
+#else /* PCVT_NETBSD || PCVT_FREEBSD >= 200 */
+
+void
+pcstart(struct tty *tp)
+{
+ int s;
+ unsigned char c;
+
+ s = spltty();
+
+ if (tp->t_state & (TS_TIMEOUT|TS_BUSY|TS_TTSTOP))
+ {
+ goto out;
+ }
+
+ for(;;)
+ {
+
+#if !(PCVT_FREEBSD > 114)
+
+#if !(PCVT_FREEBSD > 111)
+ if (RB_LEN(&tp->t_out) <= tp->t_lowat)
+#else
+ if (RB_LEN(tp->t_out) <= tp->t_lowat)
+#endif
+ {
+ if (tp->t_state&TS_ASLEEP)
+ {
+ tp->t_state &= ~TS_ASLEEP;
+#if !(PCVT_FREEBSD > 111)
+ wakeup((caddr_t)&tp->t_out);
+#else
+ wakeup((caddr_t)tp->t_out);
+#endif
+ }
+
+ if (tp->t_wsel)
+ {
+ selwakeup(tp->t_wsel, tp->t_state & TS_WCOLL);
+ tp->t_wsel = 0;
+ tp->t_state &= ~TS_WCOLL;
+ }
+ }
+
+#else /* PCVT_FREEBSD > 114 */
+ if (tp->t_state & (TS_SO_OCOMPLETE | TS_SO_OLOWAT)
+ || tp->t_wsel) {
+ ttwwakeup(tp);
+ }
+#endif /* !PCVT_FREEBSD > 114 */
+
+#if !(PCVT_FREEBSD > 111)
+ if (RB_LEN(&tp->t_out) == 0)
+#else
+ if (RB_LEN(tp->t_out) == 0)
+#endif
+ {
+ goto out;
+ }
+
+#if !(PCVT_FREEBSD > 111)
+ c = getc(&tp->t_out);
+#else
+ c = getc(tp->t_out);
+#endif
+
+ tp->t_state |= TS_BUSY; /* patch from Frank Maclachlan */
+ splx(s);
+ sput(&c, 0, 1, minor(tp->t_dev));
+ spltty();
+ tp->t_state &= ~TS_BUSY; /* patch from Frank Maclachlan */
+ }
+out:
+ splx(s);
+}
+
+#endif /* PCVT_NETBSD || PCVT_FREEBSD >= 200 */
+
+/*---------------------------------------------------------------------------*
+ * /dev/console
+ *---------------------------------------------------------------------------*/
+
+#if !PCVT_NETBSD /* has moved to cons.c in netbsd-current */
+void
+consinit() /* init for kernel messages during boot */
+{
+}
+#endif /* PCVT_NETBSD */
+
+#if (PCVT_NETBSD > 101 || PCVT_FREEBSD > 205)
+void
+pccnprobe(struct consdev *cp)
+#else
+int
+pccnprobe(struct consdev *cp)
+#endif
+{
+ int maj;
+
+ /* locate the major number */
+
+ for (maj = 0; maj < nchrdev; maj++)
+ {
+ if ((u_int)cdevsw[maj].d_open == (u_int)pcopen)
+ break;
+ }
+
+ if (maj == nchrdev)
+ {
+ /* we are not in cdevsw[], give up */
+ panic("pcvt is not in cdevsw[]");
+ }
+
+ /* initialize required fields */
+
+ cp->cn_dev = makedev(maj, 0);
+ cp->cn_pri = CN_INTERNAL;
+
+#if !PCVT_NETBSD
+
+#if !(PCVT_FREEBSD > 110 && PCVT_FREEBSD < 200)
+ cp->cn_tp = &pccons[0];
+#else
+ cp->cn_tp = pccons[0];
+#endif /* !(PCVT_FREEBSD > 110 && PCVT_FREEBSD < 200) */
+
+#endif /* !PCVT_NETBSD */
+
+#if ((PCVT_NETBSD && (PCVT_NETBSD <= 101)) || \
+ (PCVT_FREEBSD && (PCVT_FREEBSD <= 205)))
+ return 1;
+#endif
+}
+
+#if (PCVT_NETBSD > 101 || PCVT_FREEBSD > 205)
+void
+pccninit(struct consdev *cp)
+#else
+int
+pccninit(struct consdev *cp)
+#endif
+{
+ pcvt_is_console = 1;
+
+#if ((PCVT_NETBSD && (PCVT_NETBSD <= 101)) || \
+ (PCVT_FREEBSD && (PCVT_FREEBSD <= 205)))
+ return 0;
+#endif
+}
+
+#if (PCVT_NETBSD > 101 || PCVT_FREEBSD > 205)
+void
+pccnputc(Dev_t dev, U_char c)
+#else
+int
+pccnputc(Dev_t dev, U_char c)
+#endif
+{
+
+#if PCVT_SW0CNOUTP
+
+ if(current_video_screen != 0)
+ {
+ switch_screen(0, 0);
+ }
+
+#endif /* PCVT_SW0CNOUTP */
+
+ if (c == '\n')
+ sput("\r", 1, 1, 0);
+
+ sput((char *) &c, 1, 1, 0);
+
+ async_update(UPDATE_KERN);
+
+#if ((PCVT_NETBSD && (PCVT_NETBSD <= 101)) || \
+ (PCVT_FREEBSD && (PCVT_FREEBSD <= 205)))
+ return 0;
+#endif
+}
+
+int
+pccngetc(Dev_t dev)
+{
+ register int s;
+ register u_char *cp;
+
+#ifdef XSERVER
+ if (vs[minor(dev)].kbd_state == K_RAW)
+ return 0;
+#endif /* XSERVER */
+
+ s = spltty(); /* block pcrint while we poll */
+ cp = sgetc(0);
+ splx(s);
+ async_update(UPDATE_KERN);
+
+#if ! (PCVT_FREEBSD >= 201)
+ /* this belongs to cons.c */
+ if (*cp == '\r')
+ return('\n');
+#endif /* ! (PCVT_FREEBSD >= 201) */
+
+ return (*cp);
+}
+
+#if PCVT_FREEBSD >= 200
+int
+pccncheckc(Dev_t dev)
+{
+ return (sgetc(1) != 0); /* did someone press the "Any" key? */
+}
+#endif /* PCVT_FREEBSD >= 200 */
+
+#if PCVT_NETBSD >= 100
+void
+pccnpollc(Dev_t dev, int on)
+{
+#if PCVT_NETBSD > 101
+ struct vt_softc *sc = vtcd.cd_devs[0]; /* XXX */
+#endif
+
+ kbd_polling = on;
+ if (!on) {
+ register int s;
+
+ /*
+ * If disabling polling, make sure there are no bytes left in
+ * the FIFO, holding up the interrupt line. Otherwise we
+ * won't get any further interrupts.
+ */
+ s = spltty();
+
+#if PCVT_NETBSD > 101
+ pcintr(sc);
+#else
+ pcrint();
+#endif
+
+ splx(s);
+ }
+}
+#endif /* PCVT_NETBSD >= 100 */
+
+/*---------------------------------------------------------------------------*
+ * Set line parameters
+ *---------------------------------------------------------------------------*/
+int
+pcparam(struct tty *tp, 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);
+}
+
+/* special characters */
+#define bs 8
+#define lf 10
+#define cr 13
+#define cntlc 3
+#define del 0177
+#define cntld 4
+
+int
+getchar(void)
+{
+ u_char thechar;
+ int x;
+
+ kbd_polling = 1;
+
+ x = splhigh();
+
+ sput(">", 1, 1, 0);
+
+ async_update(UPDATE_KERN);
+
+ thechar = *(sgetc(0));
+
+ kbd_polling = 0;
+
+ splx(x);
+
+ switch (thechar)
+ {
+ default:
+ if (thechar >= ' ')
+ sput(&thechar, 1, 1, 0);
+ return(thechar);
+
+ case cr:
+ case lf:
+ sput("\r\n", 1, 2, 0);
+ return(lf);
+
+ case bs:
+ case del:
+ sput("\b \b", 1, 3, 0);
+ return(thechar);
+
+ case cntlc:
+ sput("^C\r\n", 1, 4, 0) ;
+ cpu_reset();
+
+ case cntld:
+ sput("^D\r\n", 1, 4, 0) ;
+ return(0);
+ }
+}
+
+/*----------------------------------------------------------------------*
+ * read initial VGA palette (as stored by VGA ROM BIOS) into
+ * palette save area
+ *----------------------------------------------------------------------*/
+void
+vgapelinit(void)
+{
+ register unsigned idx;
+ register struct rgb *val;
+
+ /* first, read all and store to first screen's save buffer */
+ for(idx = 0, val = vs[0].palette; idx < NVGAPEL; idx++, val++)
+ vgapaletteio(idx, val, 0 /* read it */);
+
+ /* now, duplicate for remaining screens */
+ for(idx = 1; idx < PCVT_NSCREENS; idx++)
+ bcopy(vs[0].palette, vs[idx].palette,
+ NVGAPEL * sizeof(struct rgb));
+}
+
+#endif /* NVT > 0 */
+
+/*-------------------------- E O F -------------------------------------*/
diff --git a/sys/arch/i386/isa/pcvt/pcvt_ext.c b/sys/arch/i386/isa/pcvt/pcvt_ext.c
new file mode 100644
index 00000000000..9bbe8dd022b
--- /dev/null
+++ b/sys/arch/i386/isa/pcvt/pcvt_ext.c
@@ -0,0 +1,2903 @@
+/*
+ * Copyright (c) 1992, 1995 Hellmuth Michaelis and Joerg Wunsch.
+ *
+ * Copyright (C) 1992, 1993 Soeren Schmidt.
+ *
+ * All rights reserved.
+ *
+ * For the sake of compatibility, portions of this code regarding the
+ * X server interface are taken from Soeren Schmidt's syscons driver.
+ *
+ * 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
+ * Hellmuth Michaelis, Joerg Wunsch and Soeren Schmidt.
+ * 4. The name authors may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``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 AUTHORS 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.
+ *
+ *
+ * @(#)pcvt_ext.c, 3.32, Last Edit-Date: [Tue Oct 3 11:19:48 1995]
+ *
+ */
+
+/*---------------------------------------------------------------------------*
+ *
+ * pcvt_ext.c VT220 Driver Extended Support Routines
+ * ------------------------------------------------------
+ *
+ * -hm ------------ Release 3.00 --------------
+ * -hm integrating NetBSD-current patches
+ * -hm applied Onno van der Linden's patch for Cirrus BIOS upgrade
+ * -hm pcvt_x_hook has to care about fkey labels now
+ * -hm changed some bcopyb's to bcopy's
+ * -hm TS_INDEX -> TS_DATA for cirrus (mail from Onno/Charles)
+ * -jw removed kbc_8042(), and replaced by kbd_emulate_pc()
+ * -hm X server patch from John Kohl <jtk@kolvir.blrc.ma.us>
+ * -hm applying Joerg's patch for FreeBSD 2.0
+ * -hm enable 132 col support for Trident TVGA8900CL
+ * -hm applying patch from Joerg fixing Crtat bug
+ * -hm removed PCVT_FAKE_SYSCONS10
+ * -hm fastscroll/Crtat bugfix from Lon Willett
+ * -hm bell patch from Thomas Eberhardt for NetBSD
+ * -hm multiple X server bugfixes from Lon Willett
+ * -hm patch from John Kohl fixing tsleep bug in usl_vt_ioctl()
+ * -hm bugfix: clear 25th line when switching to a force 24 lines vt
+ * -jw add some forward declarations
+ * -hm fixing MDA re-init when leaving X
+ * -hm patch from John Kohl fixing potential divide by 0 problem
+ * -hm patch from Joerg: console unavailable flag handling
+ * -hm bugfix: unknown cirrus board enables 132 cols
+ * -hm fixing NetBSD PR1123, minor typo (reported by J.T. Conklin)
+ * -hm adding support for Cirrus 5430 chipset
+ * -hm adding NetBSD-current patches from John Kohl
+ * -hm ---------------- Release 3.30 -----------------------
+ * -hm patch to support Cirrus CL-GD62x5 from Martin
+ * -hm patch to support 132 cols for Cirrus CL-GD62x5 from Martin
+ * -hm patch from Frank van der Linden for keyboard state per VT
+ * -hm patch from Charles Hannum, bugfix of keyboard state switch
+ * -hm implemented KDGKBMODE keyboard ioctl
+ * -hm patch from John Kohl, missing kbd_setmode() in switch_screen()
+ * -hm ---------------- Release 3.32 -----------------------
+ *
+ *---------------------------------------------------------------------------*/
+
+#include "vt.h"
+#if NVT > 0
+
+#include "pcvt_hdr.h" /* global include */
+
+static int s3testwritable( void );
+static int et4000_col( int );
+static int wd90c11_col( int );
+static int tri9000_col( int );
+static int v7_1024i_col( int );
+static int s3_928_col( int );
+static int cl_gd542x_col( int );
+
+/* storage to save video timing values of 80 columns text mode */
+static union {
+ u_char generic[11];
+ u_char et4000[11];
+ u_char wd90c11[12];
+ u_char tri9000[13];
+ u_char v7_1024i[17];
+ u_char s3_928[32];
+ u_char cirrus[13];
+}
+savearea;
+
+static int regsaved = 0; /* registers are saved to savearea */
+
+/*---------------------------------------------------------------------------*
+ *
+ * Find out which video board we are running on, taken from:
+ * Richard Ferraro: Programmers Guide to the EGA and VGA Cards
+ * and from David E. Wexelblat's SuperProbe Version 1.0.
+ * When a board is found, for which 132 column switching is
+ * provided, the global variable "can_do_132col" is set to 1,
+ * also the global variable vga_family is set to what we found.
+ *
+ * ###############################################################
+ * ## THIS IS GETTING MORE AND MORE A LARGE SPAGHETTI HACK !!!! ##
+ * ###############################################################
+ *
+ *---------------------------------------------------------------------------*/
+u_char
+vga_chipset(void)
+{
+ u_char *ptr;
+ u_char byte, oldbyte, old1byte, newbyte;
+
+#if PCVT_132GENERIC
+ can_do_132col = 1; /* assumes everyone can do 132 col */
+#else
+ can_do_132col = 0; /* assumes noone can do 132 col */
+#endif /* PCVT_132GENERIC */
+
+ vga_family = VGA_F_NONE;
+
+/*---------------------------------------------------------------------------*
+ * check for Western Digital / Paradise chipsets
+ *---------------------------------------------------------------------------*/
+
+ ptr = (u_char *)Crtat;
+
+ if(color)
+ ptr += (0xc007d - 0xb8000);
+ else
+ ptr += (0xc007d - 0xb0000);
+
+ if((*ptr++ == 'V') && (*ptr++ == 'G') &&
+ (*ptr++ == 'A') && (*ptr++ == '='))
+ {
+ int wd90c10;
+
+ vga_family = VGA_F_WD;
+
+ outb(addr_6845, 0x2b);
+ oldbyte = inb(addr_6845+1);
+ outb(addr_6845+1, 0xaa);
+ newbyte = inb(addr_6845+1);
+ outb(addr_6845+1, oldbyte);
+ if(newbyte != 0xaa)
+ return(VGA_PVGA); /* PVGA1A chip */
+
+ outb(TS_INDEX, 0x12);
+ oldbyte = inb(TS_DATA);
+ outb(TS_DATA, oldbyte & 0xbf);
+ newbyte = inb(TS_DATA) & 0x40;
+ if(newbyte != 0)
+ return(VGA_WD90C00); /* WD90C00 chip */
+
+ outb(TS_DATA, oldbyte | 0x40);
+ newbyte = inb(TS_DATA) & 0x40;
+ if(newbyte == 0)
+ return(VGA_WD90C00); /* WD90C00 chip */
+
+ outb(TS_DATA, oldbyte);
+
+ wd90c10 = 0;
+ outb(TS_INDEX, 0x10);
+ oldbyte = inb(TS_DATA);
+
+ outb(TS_DATA, oldbyte & 0xfb);
+ newbyte = inb(TS_DATA) & 0x04;
+ if(newbyte != 0)
+ wd90c10 = 1;
+
+ outb(TS_DATA, oldbyte | 0x04);
+ newbyte = inb(TS_DATA) & 0x04;
+ if(newbyte == 0)
+ wd90c10 = 1;
+
+ outb(TS_DATA, oldbyte);
+
+ if(wd90c10)
+ return(VGA_WD90C10);
+ else
+ {
+ can_do_132col = 1;
+ return(VGA_WD90C11);
+ }
+ }
+
+/*---------------------------------------------------------------------------*
+ * check for Trident chipsets
+ *---------------------------------------------------------------------------*/
+
+ outb(TS_INDEX, 0x0b);
+ oldbyte = inb(TS_DATA);
+
+
+ outb(TS_INDEX, 0x0b);
+ outb(TS_DATA, 0x00);
+
+ byte = inb(TS_DATA); /* chipset type */
+
+
+ outb(TS_INDEX, 0x0e);
+ old1byte = inb(TS_DATA);
+
+ outb(TS_DATA, 0);
+ newbyte = inb(TS_DATA);
+
+ outb(TS_DATA, (old1byte ^ 0x02));
+
+ outb(TS_INDEX, 0x0b);
+ outb(TS_DATA, oldbyte);
+
+ if((newbyte & 0x0f) == 0x02)
+ {
+ /* is a trident chip */
+
+ vga_family = VGA_F_TRI;
+
+ switch(byte)
+ {
+ case 0x01:
+ return(VGA_TR8800BR);
+
+ case 0x02:
+ return(VGA_TR8800CS);
+
+ case 0x03:
+ can_do_132col = 1;
+ return(VGA_TR8900B);
+
+ case 0x04:
+ case 0x13:
+ /* Haven't tried, but should work */
+ can_do_132col = 1;
+ return(VGA_TR8900C);
+
+ case 0x23:
+ can_do_132col = 1;
+ return(VGA_TR9000);
+
+ case 0x33:
+ can_do_132col = 1;
+ return(VGA_TR8900CL);
+
+ case 0x83:
+ return(VGA_TR9200);
+
+ case 0x93:
+ return(VGA_TR9100);
+
+ default:
+ return(VGA_TRUNKNOWN);
+ }
+ }
+
+/*---------------------------------------------------------------------------*
+ * check for Tseng Labs ET3000/4000 chipsets
+ *---------------------------------------------------------------------------*/
+
+ outb(GN_HERCOMPAT, 0x06);
+ if(color)
+ outb(GN_DMCNTLC, 0xa0);
+ else
+ outb(GN_DMCNTLM, 0xa0);
+
+ /* read old value */
+
+ if(color)
+ inb(GN_INPSTAT1C);
+ else
+ inb(GN_INPSTAT1M);
+ outb(ATC_INDEX, ATC_MISC);
+ oldbyte = inb(ATC_DATAR);
+
+ /* write new value */
+
+ if(color)
+ inb(GN_INPSTAT1C);
+ else
+ inb(GN_INPSTAT1M);
+ outb(ATC_INDEX, ATC_MISC);
+ newbyte = oldbyte ^ 0x10;
+ outb(ATC_DATAW, newbyte);
+
+ /* read back new value */
+ if(color)
+ inb(GN_INPSTAT1C);
+ else
+ inb(GN_INPSTAT1M);
+ outb(ATC_INDEX, ATC_MISC);
+ byte = inb(ATC_DATAR);
+
+ /* write back old value */
+ if(color)
+ inb(GN_INPSTAT1C);
+ else
+ inb(GN_INPSTAT1M);
+ outb(ATC_INDEX, ATC_MISC);
+ outb(ATC_DATAW, oldbyte);
+
+ if(byte == newbyte) /* ET3000 or ET4000 */
+ {
+ vga_family = VGA_F_TSENG;
+
+ outb(addr_6845, CRTC_EXTSTART);
+ oldbyte = inb(addr_6845+1);
+ newbyte = oldbyte ^ 0x0f;
+ outb(addr_6845+1, newbyte);
+ byte = inb(addr_6845+1);
+ outb(addr_6845+1, oldbyte);
+
+ if(byte == newbyte)
+ {
+ can_do_132col = 1;
+ return(VGA_ET4000);
+ }
+ else
+ {
+ return(VGA_ET3000);
+ }
+ }
+
+/*---------------------------------------------------------------------------*
+ * check for Video7 VGA chipsets
+ *---------------------------------------------------------------------------*/
+
+ outb(TS_INDEX, TS_EXTCNTL); /* enable extensions */
+ outb(TS_DATA, 0xea);
+
+ outb(addr_6845, CRTC_STARTADRH);
+ oldbyte = inb(addr_6845+1);
+
+ outb(addr_6845+1, 0x55);
+ newbyte = inb(addr_6845+1);
+
+ outb(addr_6845, CRTC_V7ID); /* id register */
+ byte = inb(addr_6845+1); /* read id */
+
+ outb(addr_6845, CRTC_STARTADRH);
+ outb(addr_6845+1, oldbyte);
+
+ outb(TS_INDEX, TS_EXTCNTL); /* disable extensions */
+ outb(TS_DATA, 0xae);
+
+ if(byte == (0x55 ^ 0xea))
+ { /* is Video 7 */
+
+ vga_family = VGA_F_V7;
+
+ outb(TS_INDEX, TS_EXTCNTL); /* enable extensions */
+ outb(TS_DATA, 0xea);
+
+ outb(TS_INDEX, TS_V7CHIPREV);
+ byte = inb(TS_DATA);
+
+ outb(TS_INDEX, TS_EXTCNTL); /* disable extensions */
+ outb(TS_DATA, 0xae);
+
+ if(byte < 0xff && byte >= 0x80)
+ return(VGA_V7VEGA);
+ if(byte < 0x7f && byte >= 0x70)
+ return(VGA_V7FWVR);
+ if(byte < 0x5a && byte >= 0x50)
+ return(VGA_V7V5);
+ if(byte < 0x4a && byte > 0x40)
+ {
+ can_do_132col = 1;
+ return(VGA_V71024I);
+ }
+ return(VGA_V7UNKNOWN);
+ }
+
+/*---------------------------------------------------------------------------*
+ * check for S3 chipsets
+ *---------------------------------------------------------------------------*/
+
+ outb(addr_6845, 0x38); /* reg 1 lock register */
+ old1byte = inb(addr_6845+1); /* get old value */
+
+ outb(addr_6845, 0x38);
+ outb(addr_6845+1, 0x00); /* lock registers */
+
+ if(s3testwritable() == 0) /* check if locked */
+ {
+ outb(addr_6845, 0x38);
+ outb(addr_6845+1, 0x48); /* unlock registers */
+
+ if(s3testwritable() == 1 ) /* check if unlocked */
+ {
+ vga_family = VGA_F_S3; /* FAMILY S3 */
+
+ outb(addr_6845, 0x30); /* chip id/rev reg */
+ byte = inb(addr_6845+1);
+
+ switch(byte & 0xf0)
+ {
+ case 0x80:
+ switch(byte & 0x0f)
+ {
+ case 0x01:
+ outb(addr_6845, 0x38);
+ outb(addr_6845+1, old1byte);
+ return VGA_S3_911;
+
+ case 0x02:
+ outb(addr_6845, 0x38);
+ outb(addr_6845+1, old1byte);
+ return VGA_S3_924;
+
+ default:
+ outb(addr_6845, 0x38);
+ outb(addr_6845+1, old1byte);
+ return VGA_S3_UNKNOWN;
+ }
+ break;
+
+ case 0xA0:
+ outb(addr_6845, 0x38);
+ outb(addr_6845+1, old1byte);
+ return VGA_S3_80x;
+
+ case 0x90:
+ case 0xb0:
+ outb(addr_6845, 0x38);
+ outb(addr_6845+1, old1byte);
+ can_do_132col = 1;
+ return VGA_S3_928;
+
+ default:
+ outb(addr_6845, 0x38);
+ outb(addr_6845+1, old1byte);
+ return VGA_S3_UNKNOWN;
+ }
+ }
+ }
+
+/*---------------------------------------------------------------------------*
+ * check for Cirrus chipsets
+ *---------------------------------------------------------------------------*/
+
+ outb(TS_INDEX, 6);
+ oldbyte = inb(TS_DATA);
+
+ outb(TS_INDEX, 6);
+ outb(TS_DATA, 0x12);
+
+ outb(TS_INDEX, 6);
+ newbyte = inb(TS_DATA);
+
+ outb(addr_6845, 0x27);
+ byte = inb(addr_6845 + 1);
+
+ outb(TS_INDEX, 6);
+ outb(TS_DATA, oldbyte);
+
+ if (newbyte == 0x12)
+ {
+ vga_family = VGA_F_CIR;
+
+ switch ((byte & 0xfc) >> 2)
+ {
+ case 0x06:
+ can_do_132col = 1;
+ return VGA_CL_GD6225;
+
+ case 0x22:
+ switch (byte & 3)
+ {
+ case 0:
+ can_do_132col = 1;
+ return VGA_CL_GD5402;
+
+ case 1:
+ can_do_132col = 1;
+ return VGA_CL_GD5402r1;
+
+ case 2:
+ can_do_132col = 1;
+ return VGA_CL_GD5420;
+
+ case 3:
+ can_do_132col = 1;
+ return VGA_CL_GD5420r1;
+ }
+ break;
+ case 0x23:
+ can_do_132col = 1;
+ return VGA_CL_GD5422;
+
+ case 0x24:
+ can_do_132col = 1;
+ return VGA_CL_GD5426;
+
+ case 0x25:
+ can_do_132col = 1;
+ return VGA_CL_GD5424;
+
+ case 0x26:
+ can_do_132col = 1;
+ return VGA_CL_GD5428;
+
+ case 0x28:
+ can_do_132col = 1;
+ return VGA_CL_GD5430;
+
+ }
+ return(VGA_CL_UNKNOWN);
+ }
+ return(VGA_UNKNOWN);
+}
+
+/*---------------------------------------------------------------------------
+ * test if index 35 lower nibble is writable (taken from SuperProbe 1.0)
+ *---------------------------------------------------------------------------*/
+static int
+s3testwritable(void)
+{
+ u_char old, new1, new2;
+
+ outb(addr_6845, 0x35);
+ old = inb(addr_6845+1); /* save */
+
+ outb(addr_6845, 0x35);
+ outb(addr_6845+1, (old & 0xf0)); /* write 0 */
+
+ outb(addr_6845, 0x35);
+ new1 = (inb(addr_6845+1)) & 0x0f; /* must read 0 */
+
+ outb(addr_6845, 0x35);
+ outb(addr_6845+1, (old | 0x0f)); /* write 1 */
+
+ outb(addr_6845, 0x35);
+ new2 = (inb(addr_6845+1)) & 0x0f; /* must read 1 */
+
+ outb(addr_6845, 0x35);
+ outb(addr_6845+1, old); /* restore */
+
+ return((new1==0) && (new2==0x0f));
+}
+
+/*---------------------------------------------------------------------------*
+ * return ptr to string describing vga type
+ *---------------------------------------------------------------------------*/
+char *
+vga_string(int number)
+{
+ static char *vga_tab[] = {
+ "generic",
+ "et4000",
+ "et3000",
+ "pvga1a",
+ "wd90c00",
+ "wd90c10",
+ "wd90c11",
+ "v7 vega",
+ "v7 fast",
+ "v7 ver5",
+ "v7 1024i",
+ "unknown v7",
+ "tvga 8800br",
+ "tvga 8800cs",
+ "tvga 8900b",
+ "tvga 8900c",
+ "tvga 8900cl",
+ "tvga 9000",
+ "tvga 9100",
+ "tvga 9200",
+ "unknown trident",
+ "s3 911",
+ "s3 924",
+ "s3 801/805",
+ "s3 928",
+ "unknown s3",
+ "cl-gd5402",
+ "cl-gd5402r1",
+ "cl-gd5420",
+ "cl-gd5420r1",
+ "cl-gd5422",
+ "cl-gd5424",
+ "cl-gd5426",
+ "cl-gd5428",
+ "cl-gd5430",
+ "cl-gd62x5",
+ "unknown cirrus",
+ /* VGA_MAX_CHIPSET */
+ "vga_string: chipset name table ptr overflow!"
+ };
+
+ if(number > VGA_MAX_CHIPSET) /* failsafe */
+ number = VGA_MAX_CHIPSET;
+
+ return(vga_tab[number]);
+}
+
+/*---------------------------------------------------------------------------*
+ * toggle vga 80/132 column operation
+ *---------------------------------------------------------------------------*/
+int
+vga_col(struct video_state *svsp, int cols)
+{
+ int ret = 0;
+
+ if(adaptor_type != VGA_ADAPTOR)
+ return(0);
+
+ switch(vga_type)
+ {
+ case VGA_ET4000:
+ ret = et4000_col(cols);
+ break;
+
+ case VGA_WD90C11:
+ ret = wd90c11_col(cols);
+ break;
+
+ case VGA_TR8900B:
+ case VGA_TR8900C:
+ case VGA_TR8900CL:
+ case VGA_TR9000:
+ ret = tri9000_col(cols);
+ break;
+
+ case VGA_V71024I:
+ ret = v7_1024i_col(cols);
+ break;
+
+ case VGA_S3_928:
+ ret = s3_928_col(cols);
+ break;
+
+ case VGA_CL_GD5402:
+ case VGA_CL_GD5402r1:
+ case VGA_CL_GD5420:
+ case VGA_CL_GD5420r1:
+ case VGA_CL_GD5422:
+ case VGA_CL_GD5424:
+ case VGA_CL_GD5426:
+ case VGA_CL_GD5428:
+ case VGA_CL_GD5430:
+ case VGA_CL_GD6225:
+ ret = cl_gd542x_col(cols);
+ break;
+
+ default:
+
+#if PCVT_132GENERIC
+ ret = generic_col(cols);
+#endif /* PCVT_132GENERIC */
+
+ break;
+ }
+
+ if(ret == 0)
+ return(0); /* failed */
+
+ svsp->maxcol = cols;
+
+ return(1);
+}
+
+#if PCVT_132GENERIC
+/*---------------------------------------------------------------------------*
+ * toggle 80/132 column operation for "generic" SVGAs
+ * NB: this is supposed to work on any (S)VGA as long as the monitor
+ * is able to sync down to 21.5 kHz horizontally. The resulting
+ * vertical frequency is only 50 Hz, so if there is some better board
+ * specific algorithm, we avoid using this generic one.
+ * REPORT ANY FAILURES SO WE CAN IMPROVE THIS
+ *---------------------------------------------------------------------------*/
+
+#if PCVT_EXP_132COL
+/*
+ * Some improved (i.e. higher scan rates) figures for the horizontal
+ * timing. USE AT YOUR OWN RISK, THIS MIGHT DAMAGE YOUR MONITOR DUE
+ * TO A LOSS OF HORIZONTAL SYNC!
+ * The figures have been tested with an ET3000 board along with a
+ * NEC MultiSync 3D monitor. If you are playing here, consider
+ * testing with several screen pictures (dark background vs. light
+ * background, even enlightening the border color may impact the
+ * result - you can do this e.g. by "scon -p black,42,42,42")
+ * Remember that all horizontal timing values must be dividable
+ * by 8! (The scheme below is taken so that nifty kernel hackers
+ * are able to patch the figures at run-time.)
+ *
+ * The actual numbers result in 23 kHz line scan and 54 Hz vertical
+ * scan.
+ */
+#endif /* PCVT_EXP_132COL */
+
+int
+generic_col(int cols)
+{
+ u_char *sp;
+ u_char byte;
+
+#if !PCVT_EXP_132COL
+
+ /* stable figures for any multisync monitor that syncs down to 22 kHz*/
+ static volatile u_short htotal = 1312;
+ static volatile u_short displayend = 1056;
+ static volatile u_short blankstart = 1072;
+ static volatile u_short syncstart = 1112;
+ static volatile u_short syncend = 1280;
+
+#else /* PCVT_EXP_132COL */
+
+ /* reduced sync-pulse width and sync delays */
+ static volatile u_short htotal = 1232;
+ static volatile u_short displayend = 1056;
+ static volatile u_short blankstart = 1056;
+ static volatile u_short syncstart = 1104;
+ static volatile u_short syncend = 1168;
+
+#endif /* PCVT_EXP_132COL */
+
+ vga_screen_off();
+
+ /* enable access to first 7 CRTC registers */
+
+ outb(addr_6845, CRTC_VSYNCE);
+ byte = inb(addr_6845+1);
+ outb(addr_6845, CRTC_VSYNCE);
+ outb(addr_6845+1, byte & 0x7f);
+
+ if(cols == SCR_COL132) /* switch 80 -> 132 */
+ {
+ /* save state of board for 80 columns */
+
+ if(!regsaved)
+ {
+ regsaved = 1;
+
+ sp = savearea.generic;
+
+ outb(addr_6845, 0x00); /* Horizontal Total */
+ *sp++ = inb(addr_6845+1);
+ outb(addr_6845, 0x01); /* Horizontal Display End */
+ *sp++ = inb(addr_6845+1);
+ outb(addr_6845, 0x02); /* Horizontal Blank Start */
+ *sp++ = inb(addr_6845+1);
+ outb(addr_6845, 0x03); /* Horizontal Blank End */
+ *sp++ = inb(addr_6845+1);
+ outb(addr_6845, 0x04); /* Horizontal Retrace Start */
+ *sp++ = inb(addr_6845+1);
+ outb(addr_6845, 0x05); /* Horizontal Retrace End */
+ *sp++ = inb(addr_6845+1);
+
+ outb(addr_6845, 0x13); /* Row Offset Register */
+ *sp++ = inb(addr_6845+1);
+
+ outb(TS_INDEX, TS_MODE);/* Timing Sequencer */
+ *sp++ = inb(TS_DATA);
+
+ if(color)
+ inb(GN_INPSTAT1C);
+ else
+ inb(GN_INPSTAT1M);
+ /* ATC Mode control */
+ outb(ATC_INDEX, ATC_MODE | ATC_ACCESS);
+ *sp++ = inb(ATC_DATAR);
+
+ if(color)
+ inb(GN_INPSTAT1C);
+ else
+ inb(GN_INPSTAT1M);
+ /* ATC Horizontal Pixel Panning */
+ outb(ATC_INDEX, ATC_HORPIXPAN | ATC_ACCESS);
+ *sp++ = inb(ATC_DATAR);
+
+ *sp++ = inb(GN_MISCOUTR); /* Misc output register */
+ }
+
+ /* setup chipset for 132 column operation */
+
+
+ outb(addr_6845, 0x00); /* Horizontal Total */
+ outb(addr_6845+1, (htotal / 8) - 5);
+ outb(addr_6845, 0x01); /* Horizontal Display End */
+ outb(addr_6845+1, (displayend / 8) - 1);
+ outb(addr_6845, 0x02); /* Horizontal Blank Start */
+ outb(addr_6845+1, blankstart / 8);
+ outb(addr_6845, 0x03); /* Horizontal Blank End */
+ outb(addr_6845+1, ((syncend / 8) & 0x1f) | 0x80);
+ outb(addr_6845, 0x04); /* Horizontal Retrace Start */
+ outb(addr_6845+1, syncstart / 8);
+ outb(addr_6845, 0x05); /* Horizontal Retrace End */
+ outb(addr_6845+1,
+ (((syncend / 8) & 0x20) * 4)
+ | ((syncend / 8) & 0x1f));
+
+ outb(addr_6845, 0x13); /* Row Offset Register */
+ outb(addr_6845+1, 0x42);
+
+ outb(TS_INDEX, TS_MODE);/* Timing Sequencer */
+ outb(TS_DATA, 0x01); /* 8 dot char clock */
+
+ if(color)
+ inb(GN_INPSTAT1C);
+ else
+ inb(GN_INPSTAT1M);
+ outb(ATC_INDEX, ATC_MODE | ATC_ACCESS); /* ATC Mode control */
+ outb(ATC_DATAW, 0x08); /* Line graphics disable */
+
+ if(color)
+ inb(GN_INPSTAT1C);
+ else
+ inb(GN_INPSTAT1M);
+ outb(ATC_INDEX, ATC_HORPIXPAN | ATC_ACCESS); /* ATC Horizontal Pixel Panning */
+ outb(ATC_DATAW, 0x00);
+
+ /* Misc output register */
+ /* use the 28.322 MHz clock */
+ outb(GN_MISCOUTW, (inb(GN_MISCOUTR) & ~0x0c) | 4);
+ }
+ else /* switch 132 -> 80 */
+ {
+ if(!regsaved) /* failsafe */
+ {
+ /* disable access to first 7 CRTC registers */
+ outb(addr_6845, CRTC_VSYNCE);
+ outb(addr_6845+1, byte);
+ vga_screen_on();
+ return(0);
+ }
+
+ sp = savearea.generic;
+
+ outb(addr_6845, 0x00); /* Horizontal Total */
+ outb(addr_6845+1, *sp++);
+ outb(addr_6845, 0x01); /* Horizontal Display End */
+ outb(addr_6845+1, *sp++);
+ outb(addr_6845, 0x02); /* Horizontal Blank Start */
+ outb(addr_6845+1, *sp++);
+ outb(addr_6845, 0x03); /* Horizontal Blank End */
+ outb(addr_6845+1, *sp++);
+ outb(addr_6845, 0x04); /* Horizontal Retrace Start */
+ outb(addr_6845+1, *sp++);
+ outb(addr_6845, 0x05); /* Horizontal Retrace End */
+ outb(addr_6845+1, *sp++);
+
+ outb(addr_6845, 0x13); /* Row Offset Register */
+ outb(addr_6845+1, *sp++);
+
+ outb(TS_INDEX, TS_MODE);/* Timing Sequencer */
+ outb(TS_DATA, *sp++);
+
+ if(color)
+ inb(GN_INPSTAT1C);
+ else
+ inb(GN_INPSTAT1M);
+ /* ATC Mode control */
+ outb(ATC_INDEX, ATC_MODE | ATC_ACCESS);
+ outb(ATC_DATAW, *sp++);
+
+ if(color)
+ inb(GN_INPSTAT1C);
+ else
+ inb(GN_INPSTAT1M);
+ /* ATC Horizontal Pixel Panning */
+ outb(ATC_INDEX, ATC_HORPIXPAN | ATC_ACCESS);
+ outb(ATC_DATAW, *sp++);
+
+ outb(GN_MISCOUTW, *sp++); /* Misc output register */
+ }
+
+ /* disable access to first 7 CRTC registers */
+
+ outb(addr_6845, CRTC_VSYNCE);
+ outb(addr_6845+1, byte);
+
+ vga_screen_on();
+
+ return(1);
+}
+#endif /* PCVT_132GENERIC */
+
+/*---------------------------------------------------------------------------*
+ * toggle 80/132 column operation for ET4000 based boards
+ *---------------------------------------------------------------------------*/
+int
+et4000_col(int cols)
+{
+ u_char *sp;
+ u_char byte;
+
+ vga_screen_off();
+
+ /* enable access to first 7 CRTC registers */
+
+ outb(addr_6845, CRTC_VSYNCE);
+ byte = inb(addr_6845+1);
+ outb(addr_6845, CRTC_VSYNCE);
+ outb(addr_6845+1, byte & 0x7f);
+
+ if(cols == SCR_COL132) /* switch 80 -> 132 */
+ {
+ /* save state of board for 80 columns */
+
+ if(!regsaved)
+ {
+ regsaved = 1;
+
+ sp = savearea.et4000;
+
+ outb(addr_6845, 0x00); /* Horizontal Total */
+ *sp++ = inb(addr_6845+1);
+ outb(addr_6845, 0x01); /* Horizontal Display End */
+ *sp++ = inb(addr_6845+1);
+ outb(addr_6845, 0x02); /* Horizontal Blank Start */
+ *sp++ = inb(addr_6845+1);
+
+ outb(addr_6845, 0x04); /* Horizontal Retrace Start */
+ *sp++ = inb(addr_6845+1);
+ outb(addr_6845, 0x05); /* Horizontal Retrace End */
+ *sp++ = inb(addr_6845+1);
+
+ outb(addr_6845, 0x13); /* Row Offset Register */
+ *sp++ = inb(addr_6845+1);
+
+ outb(addr_6845, 0x34); /* 6845 Compatibility */
+ *sp++ = inb(addr_6845+1);
+
+ outb(TS_INDEX, TS_MODE);/* Timing Sequencer */
+ *sp++ = inb(TS_DATA);
+
+ if(color)
+ inb(GN_INPSTAT1C);
+ else
+ inb(GN_INPSTAT1M);
+ /* ATC Mode control */
+ outb(ATC_INDEX, ATC_MODE | ATC_ACCESS);
+ *sp++ = inb(ATC_DATAR);
+
+ if(color)
+ inb(GN_INPSTAT1C);
+ else
+ inb(GN_INPSTAT1M);
+ /* ATC Horizontal Pixel Panning */
+ outb(ATC_INDEX, ATC_HORPIXPAN | ATC_ACCESS);
+ *sp++ = inb(ATC_DATAR);
+
+ *sp++ = inb(GN_MISCOUTR); /* Misc output register */
+ }
+
+ /* setup chipset for 132 column operation */
+
+ outb(addr_6845, 0x00); /* Horizontal Total */
+ outb(addr_6845+1, 0x9f);
+ outb(addr_6845, 0x01); /* Horizontal Display End */
+ outb(addr_6845+1, 0x83);
+ outb(addr_6845, 0x02); /* Horizontal Blank Start */
+ outb(addr_6845+1, 0x84);
+
+ outb(addr_6845, 0x04); /* Horizontal Retrace Start */
+ outb(addr_6845+1, 0x8b);
+ outb(addr_6845, 0x05); /* Horizontal Retrace End */
+ outb(addr_6845+1, 0x80);
+
+ outb(addr_6845, 0x13); /* Row Offset Register */
+ outb(addr_6845+1, 0x42);
+
+ outb(addr_6845, 0x34); /* 6845 Compatibility */
+ outb(addr_6845+1, 0x0a);
+
+ outb(TS_INDEX, TS_MODE);/* Timing Sequencer */
+ outb(TS_DATA, 0x01); /* 8 dot char clock */
+
+ if(color)
+ inb(GN_INPSTAT1C);
+ else
+ inb(GN_INPSTAT1M);
+ outb(ATC_INDEX, ATC_MODE | ATC_ACCESS); /* ATC Mode control */
+ outb(ATC_DATAW, 0x08); /* Line graphics disable */
+
+ if(color)
+ inb(GN_INPSTAT1C);
+ else
+ inb(GN_INPSTAT1M);
+ outb(ATC_INDEX, ATC_HORPIXPAN | ATC_ACCESS); /* ATC Horizontal Pixel Panning */
+ outb(ATC_DATAW, 0x00);
+
+ /* Misc output register */
+
+ outb(GN_MISCOUTW, (inb(GN_MISCOUTR) & ~0x0c));
+ }
+ else /* switch 132 -> 80 */
+ {
+ if(!regsaved) /* failsafe */
+ {
+ /* disable access to first 7 CRTC registers */
+ outb(addr_6845, CRTC_VSYNCE);
+ outb(addr_6845+1, byte);
+ vga_screen_on();
+ return(0);
+ }
+
+ sp = savearea.et4000;
+
+ outb(addr_6845, 0x00); /* Horizontal Total */
+ outb(addr_6845+1, *sp++);
+
+ outb(addr_6845, 0x01); /* Horizontal Display End */
+ outb(addr_6845+1, *sp++);
+ outb(addr_6845, 0x02); /* Horizontal Blank Start */
+ outb(addr_6845+1, *sp++);
+
+
+ outb(addr_6845, 0x04); /* Horizontal Retrace Start */
+ outb(addr_6845+1, *sp++);
+ outb(addr_6845, 0x05); /* Horizontal Retrace End */
+ outb(addr_6845+1, *sp++);
+
+ outb(addr_6845, 0x13); /* Row Offset Register */
+ outb(addr_6845+1, *sp++);
+
+ outb(addr_6845, 0x34); /* 6845 Compatibility */
+ outb(addr_6845+1, *sp++);
+
+ outb(TS_INDEX, TS_MODE);/* Timing Sequencer */
+ outb(TS_DATA, *sp++);
+
+ if(color)
+ inb(GN_INPSTAT1C);
+ else
+ inb(GN_INPSTAT1M);
+ /* ATC Mode control */
+ outb(ATC_INDEX, ATC_MODE | ATC_ACCESS);
+ outb(ATC_DATAW, *sp++);
+
+ if(color)
+ inb(GN_INPSTAT1C);
+ else
+ inb(GN_INPSTAT1M);
+ /* ATC Horizontal Pixel Panning */
+ outb(ATC_INDEX, ATC_HORPIXPAN | ATC_ACCESS);
+ outb(ATC_DATAW, *sp++);
+
+ outb(GN_MISCOUTW, *sp++); /* Misc output register */
+ }
+
+ /* disable access to first 7 CRTC registers */
+
+ outb(addr_6845, CRTC_VSYNCE);
+ outb(addr_6845+1, byte);
+
+ vga_screen_on();
+
+ return(1);
+}
+
+/*---------------------------------------------------------------------------*
+ * toggle 80/132 column operation for WD/Paradise based boards
+ *
+ * when this card does 132 cols, the char map select register (TS_INDEX,
+ * TS_FONTSEL) function bits get REDEFINED. whoever did design this,
+ * please don't cross my way ever .......
+ *
+ *---------------------------------------------------------------------------*/
+int
+wd90c11_col(int cols)
+{
+
+#if !PCVT_BACKUP_FONTS
+ static unsigned char *sv_fontwd[NVGAFONTS];
+#endif /* !PCVT_BACKUP_FONTS */
+
+ u_char *sp;
+ u_char byte;
+ int i;
+
+ vga_screen_off();
+
+ /* enable access to first 7 CRTC registers */
+
+ outb(addr_6845, CRTC_VSYNCE);
+ byte = inb(addr_6845+1);
+ outb(addr_6845, CRTC_VSYNCE);
+ outb(addr_6845+1, byte & 0x7f);
+
+ /* enable access to WD/Paradise "control extensions" */
+
+ outb(GDC_INDEX, GDC_PR5GPLOCK);
+ outb(GDC_INDEX, 0x05);
+ outb(addr_6845, CRTC_PR10);
+ outb(addr_6845, 0x85);
+ outb(TS_INDEX, TS_UNLOCKSEQ);
+ outb(TS_DATA, 0x48);
+
+ if(cols == SCR_COL132) /* switch 80 -> 132 */
+ {
+ /* save state of board for 80 columns */
+
+ if(!regsaved)
+ {
+ regsaved = 1;
+
+ /* save current fonts */
+
+#if !PCVT_BACKUP_FONTS
+ for(i = 0; i < totalfonts; i++)
+ {
+ if(vgacs[i].loaded)
+ {
+ if((sv_fontwd[i] =
+ (u_char *)malloc(32 * 256,
+ M_DEVBUF,
+ M_WAITOK))
+ == NULL)
+ printf("pcvt: no font buffer\n");
+ else
+ vga_move_charset(i,
+ sv_fontwd[i],
+ 1);
+ }
+ else
+ {
+ sv_fontwd[i] = 0;
+ }
+ }
+
+#endif /* !PCVT_BACKUP_FONTS */
+
+ sp = savearea.wd90c11;
+
+ outb(addr_6845, 0x00); /* Horizontal Total */
+ *sp++ = inb(addr_6845+1);
+ outb(addr_6845, 0x01); /* Horizontal Display End */
+ *sp++ = inb(addr_6845+1);
+ outb(addr_6845, 0x02); /* Horizontal Blank Start */
+ *sp++ = inb(addr_6845+1);
+ outb(addr_6845, 0x03); /* Horizontal Blank End */
+ *sp++ = inb(addr_6845+1);
+ outb(addr_6845, 0x04); /* Horizontal Retrace Start */
+ *sp++ = inb(addr_6845+1);
+ outb(addr_6845, 0x05); /* Horizontal Retrace End */
+ *sp++ = inb(addr_6845+1);
+
+ outb(addr_6845, 0x13); /* Row Offset Register */
+ *sp++ = inb(addr_6845+1);
+
+ outb(addr_6845, 0x2e); /* misc 1 */
+ *sp++ = inb(addr_6845+1);
+ outb(addr_6845, 0x2f); /* misc 2 */
+ *sp++ = inb(addr_6845+1);
+
+ outb(TS_INDEX, 0x10);/* Timing Sequencer */
+ *sp++ = inb(TS_DATA);
+ outb(TS_INDEX, 0x12);/* Timing Sequencer */
+ *sp++ = inb(TS_DATA);
+
+ *sp++ = inb(GN_MISCOUTR); /* Misc output register */
+ }
+
+ /* setup chipset for 132 column operation */
+
+ outb(addr_6845, 0x00); /* Horizontal Total */
+ outb(addr_6845+1, 0x9c);
+ outb(addr_6845, 0x01); /* Horizontal Display End */
+ outb(addr_6845+1, 0x83);
+ outb(addr_6845, 0x02); /* Horizontal Blank Start */
+ outb(addr_6845+1, 0x84);
+ outb(addr_6845, 0x03); /* Horizontal Blank End */
+ outb(addr_6845+1, 0x9f);
+ outb(addr_6845, 0x04); /* Horizontal Retrace Start */
+ outb(addr_6845+1, 0x8a);
+ outb(addr_6845, 0x05); /* Horizontal Retrace End */
+ outb(addr_6845+1, 0x1c);
+
+ outb(addr_6845, 0x13); /* Row Offset Register */
+ outb(addr_6845+1, 0x42);
+
+ outb(addr_6845, 0x2e); /* misc 1 */
+ outb(addr_6845+1, 0x04);
+ outb(addr_6845, 0x2f); /* misc 2 */
+ outb(addr_6845+1, 0x00);
+
+ outb(TS_INDEX, 0x10);/* Timing Sequencer */
+ outb(TS_DATA, 0x21);
+ outb(TS_INDEX, 0x12);/* Timing Sequencer */
+ outb(TS_DATA, 0x14);
+
+ outb(GN_MISCOUTW, (inb(GN_MISCOUTR) | 0x08)); /* Misc output register */
+
+ vsp->wd132col = 1;
+ }
+ else /* switch 132 -> 80 */
+ {
+ if(!regsaved) /* failsafe */
+ {
+ /* disable access to first 7 CRTC registers */
+
+ outb(addr_6845, CRTC_VSYNCE);
+ outb(addr_6845+1, byte);
+
+ /* disable access to WD/Paradise "control extensions" */
+
+ outb(GDC_INDEX, GDC_PR5GPLOCK);
+ outb(GDC_INDEX, 0x00);
+ outb(addr_6845, CRTC_PR10);
+ outb(addr_6845, 0x00);
+ outb(TS_INDEX, TS_UNLOCKSEQ);
+ outb(TS_DATA, 0x00);
+
+ vga_screen_on();
+
+ return(0);
+ }
+
+ sp = savearea.wd90c11;
+
+ outb(addr_6845, 0x00); /* Horizontal Total */
+ outb(addr_6845+1, *sp++);
+ outb(addr_6845, 0x01); /* Horizontal Display End */
+ outb(addr_6845+1, *sp++);
+ outb(addr_6845, 0x02); /* Horizontal Blank Start */
+ outb(addr_6845+1, *sp++);
+ outb(addr_6845, 0x03); /* Horizontal Blank End */
+ outb(addr_6845+1, *sp++);
+ outb(addr_6845, 0x04); /* Horizontal Retrace Start */
+ outb(addr_6845+1, *sp++);
+ outb(addr_6845, 0x05); /* Horizontal Retrace End */
+ outb(addr_6845+1, *sp++);
+
+ outb(addr_6845, 0x13); /* Row Offset Register */
+ outb(addr_6845+1, *sp++);
+
+ outb(addr_6845, 0x2e); /* misc 1 */
+ outb(addr_6845+1, *sp++);
+ outb(addr_6845, 0x2f); /* misc 2 */
+ outb(addr_6845+1, *sp++);
+
+ outb(TS_INDEX, 0x10);/* Timing Sequencer */
+ outb(addr_6845+1, *sp++);
+ outb(TS_INDEX, 0x12);/* Timing Sequencer */
+ outb(addr_6845+1, *sp++);
+
+ outb(GN_MISCOUTW, *sp++); /* Misc output register */
+
+ vsp->wd132col = 0;
+ }
+
+ /* restore fonts */
+
+#if !PCVT_BACKUP_FONTS
+ for(i = 0; i < totalfonts; i++)
+ {
+ if(sv_fontwd[i])
+ vga_move_charset(i, sv_fontwd[i], 0);
+ }
+#else
+ for(i = 0; i < totalfonts; i++)
+ if(saved_charsets[i])
+ vga_move_charset(i, 0, 0);
+#endif /* !PCVT_BACKUP_FONTS */
+
+ select_vga_charset(vsp->vga_charset);
+
+ /* disable access to first 7 CRTC registers */
+
+ outb(addr_6845, CRTC_VSYNCE);
+ outb(addr_6845+1, byte);
+
+ /* disable access to WD/Paradise "control extensions" */
+
+ outb(GDC_INDEX, GDC_PR5GPLOCK);
+ outb(GDC_INDEX, 0x00);
+ outb(addr_6845, CRTC_PR10);
+ outb(addr_6845, 0x00);
+ outb(TS_INDEX, TS_UNLOCKSEQ);
+ outb(TS_DATA, 0x00);
+
+ vga_screen_on();
+
+ return(1);
+}
+
+/*---------------------------------------------------------------------------*
+ * toggle 80/132 column operation for TRIDENT 9000 based boards
+ *---------------------------------------------------------------------------*/
+int
+tri9000_col(int cols)
+{
+ u_char *sp;
+ u_char byte;
+
+ vga_screen_off();
+
+ /* sync reset is necessary to preserve memory contents ... */
+
+ outb(TS_INDEX, TS_SYNCRESET);
+ outb(TS_DATA, 0x01); /* synchronous reset */
+
+ /* disable protection of misc out and other regs */
+
+ outb(addr_6845, CRTC_MTEST);
+ byte = inb(addr_6845+1);
+ outb(addr_6845, CRTC_MTEST);
+ outb(addr_6845+1, byte & ~0x50);
+
+ /* enable access to first 7 CRTC registers */
+
+ outb(addr_6845, CRTC_VSYNCE);
+ byte = inb(addr_6845+1);
+ outb(addr_6845, CRTC_VSYNCE);
+ outb(addr_6845+1, byte & 0x7f);
+
+ if(cols == SCR_COL132) /* switch 80 -> 132 */
+ {
+ /* save state of board for 80 columns */
+
+ if(!regsaved)
+ {
+ regsaved = 1;
+
+ sp = savearea.tri9000;
+
+ outb(addr_6845, 0x00); /* Horizontal Total */
+ *sp++ = inb(addr_6845+1);
+ outb(addr_6845, 0x01); /* Horizontal Display End */
+ *sp++ = inb(addr_6845+1);
+ outb(addr_6845, 0x02); /* Horizontal Blank Start */
+ *sp++ = inb(addr_6845+1);
+ outb(addr_6845, 0x03); /* Horizontal Blank End */
+ *sp++ = inb(addr_6845+1);
+ outb(addr_6845, 0x04); /* Horizontal Retrace Start */
+ *sp++ = inb(addr_6845+1);
+ outb(addr_6845, 0x05); /* Horizontal Retrace End */
+ *sp++ = inb(addr_6845+1);
+
+ outb(addr_6845, 0x13);
+ *sp++ = inb(addr_6845+1);
+
+ outb(TS_INDEX, TS_MODE);/* Timing Sequencer */
+ *sp++ = inb(TS_DATA);
+
+ outb(TS_INDEX, TS_HWVERS);/* Hardware Version register */
+ outb(TS_DATA, 0x00); /* write ANYTHING switches to OLD */
+ outb(TS_INDEX, TS_MODEC2);
+ *sp++ = inb(TS_DATA);
+
+ outb(TS_INDEX, TS_HWVERS);/* Hardware Version register */
+ inb(TS_DATA); /* read switches to NEW */
+ outb(TS_INDEX, TS_MODEC2);
+ *sp++ = inb(TS_DATA);
+
+ if(color)
+ inb(GN_INPSTAT1C);
+ else
+ inb(GN_INPSTAT1M);
+ /* ATC Mode control */
+ outb(ATC_INDEX, ATC_MODE | ATC_ACCESS);
+ *sp++ = inb(ATC_DATAR);
+
+ if(color)
+ inb(GN_INPSTAT1C);
+ else
+ inb(GN_INPSTAT1M);
+ /* ATC Horizontal Pixel Panning */
+ outb(ATC_INDEX, ATC_HORPIXPAN | ATC_ACCESS);
+ *sp++ = inb(ATC_DATAR);
+
+ *sp++ = inb(GN_MISCOUTR); /* Misc output register */
+ }
+
+ /* setup chipset for 132 column operation */
+
+ outb(addr_6845, 0x00); /* Horizontal Total */
+ outb(addr_6845+1, 0x9b);
+ outb(addr_6845, 0x01); /* Horizontal Display End */
+ outb(addr_6845+1, 0x83);
+ outb(addr_6845, 0x02); /* Horizontal Blank Start */
+ outb(addr_6845+1, 0x84);
+ outb(addr_6845, 0x03); /* Horizontal Blank End */
+ outb(addr_6845+1, 0x1e);
+ outb(addr_6845, 0x04); /* Horizontal Retrace Start */
+ outb(addr_6845+1, 0x87);
+ outb(addr_6845, 0x05); /* Horizontal Retrace End */
+ outb(addr_6845+1, 0x1a);
+
+ outb(addr_6845, 0x13); /* Row Offset Register */
+ outb(addr_6845+1, 0x42);
+
+ outb(TS_INDEX, TS_MODE);/* Timing Sequencer */
+ outb(TS_DATA, 0x01); /* 8 dot char clock */
+
+ outb(TS_INDEX, TS_HWVERS);/* Hardware Version register */
+ outb(TS_DATA, 0x00); /* write ANYTHING switches to OLD */
+ outb(TS_INDEX, TS_MODEC2);
+ outb(TS_DATA, 0x00);
+
+ outb(TS_INDEX, TS_HWVERS);/* Hardware Version register */
+ inb(TS_DATA); /* read switches to NEW */
+ outb(TS_INDEX, TS_MODEC2);
+ outb(TS_DATA, 0x01);
+
+ if(color)
+ inb(GN_INPSTAT1C);
+ else
+ inb(GN_INPSTAT1M);
+ outb(ATC_INDEX, ATC_MODE | ATC_ACCESS); /* ATC Mode control */
+ outb(ATC_DATAW, 0x08); /* Line graphics disable */
+
+ if(color)
+ inb(GN_INPSTAT1C);
+ else
+ inb(GN_INPSTAT1M);
+ outb(ATC_INDEX, ATC_HORPIXPAN | ATC_ACCESS); /* ATC Horizontal Pixel Panning */
+ outb(ATC_DATAW, 0x00);
+
+ outb(GN_MISCOUTW, (inb(GN_MISCOUTR) | 0x0c)); /* Misc output register */
+ }
+ else /* switch 132 -> 80 */
+ {
+ if(!regsaved) /* failsafe */
+ {
+ /* disable access to first 7 CRTC registers */
+ outb(addr_6845, CRTC_VSYNCE);
+ outb(addr_6845+1, byte);
+
+ outb(TS_INDEX, TS_SYNCRESET);
+ outb(TS_DATA, 0x03); /* clear synchronous reset */
+
+ vga_screen_on();
+
+ return(0);
+ }
+
+ sp = savearea.tri9000;
+
+ outb(addr_6845, 0x00); /* Horizontal Total */
+ outb(addr_6845+1, *sp++);
+ outb(addr_6845, 0x01); /* Horizontal Display End */
+ outb(addr_6845+1, *sp++);
+ outb(addr_6845, 0x02); /* Horizontal Blank Start */
+ outb(addr_6845+1, *sp++);
+ outb(addr_6845, 0x03); /* Horizontal Blank End */
+ outb(addr_6845+1, *sp++);
+ outb(addr_6845, 0x04); /* Horizontal Retrace Start */
+ outb(addr_6845+1, *sp++);
+ outb(addr_6845, 0x05); /* Horizontal Retrace End */
+ outb(addr_6845+1, *sp++);
+
+ outb(addr_6845, 0x13); /* Row Offset Register */
+ outb(addr_6845+1, *sp++);
+
+ outb(TS_INDEX, TS_MODE);/* Timing Sequencer */
+ outb(TS_DATA, *sp++);
+
+ outb(TS_INDEX, TS_HWVERS);/* Hardware Version register */
+ outb(TS_DATA, 0x00); /* write ANYTHING switches to OLD */
+ outb(TS_INDEX, TS_MODEC2);/* Timing Sequencer */
+ outb(TS_DATA, *sp++);
+
+ outb(TS_INDEX, TS_HWVERS);/* Hardware Version register */
+ inb(TS_DATA); /* read switches to NEW */
+ outb(TS_INDEX, TS_MODEC2);/* Timing Sequencer */
+ outb(TS_DATA, *sp++);
+
+ if(color)
+ inb(GN_INPSTAT1C);
+ else
+ inb(GN_INPSTAT1M);
+ /* ATC Mode control */
+ outb(ATC_INDEX, ATC_MODE | ATC_ACCESS);
+ outb(ATC_DATAW, *sp++);
+
+ if(color)
+ inb(GN_INPSTAT1C);
+ else
+ inb(GN_INPSTAT1M);
+ /* ATC Horizontal Pixel Panning */
+ outb(ATC_INDEX, ATC_HORPIXPAN | ATC_ACCESS);
+ outb(ATC_DATAW, *sp++);
+
+ outb(GN_MISCOUTW, *sp++); /* Misc output register */
+ }
+
+ /* disable access to first 7 CRTC registers */
+
+ outb(addr_6845, CRTC_VSYNCE);
+ outb(addr_6845+1, byte);
+
+ outb(TS_INDEX, TS_SYNCRESET);
+ outb(TS_DATA, 0x03); /* clear synchronous reset */
+
+ vga_screen_on();
+
+ return(1);
+}
+
+/*---------------------------------------------------------------------------*
+ * toggle 80/132 column operation for Video7 VGA 1024i
+ *---------------------------------------------------------------------------*/
+int
+v7_1024i_col(int cols)
+{
+ u_char *sp;
+ u_char byte;
+ u_char save__byte;
+
+ vga_screen_off();
+
+ /* enable access to first 7 CRTC registers */
+
+ /* first, enable read access to vertical retrace start/end */
+ outb(addr_6845, CRTC_HBLANKE);
+ byte = inb(addr_6845+1);
+ outb(addr_6845, CRTC_HBLANKE);
+ outb(addr_6845+1, (byte | 0x80));
+
+ /* second, enable access to protected registers */
+ outb(addr_6845, CRTC_VSYNCE);
+ save__byte = byte = inb(addr_6845+1);
+ byte |= 0x20; /* no irq 2 */
+ byte &= 0x6f; /* wr enable, clr irq flag */
+ outb(addr_6845, CRTC_VSYNCE);
+ outb(addr_6845+1, byte);
+
+ outb(TS_INDEX, TS_EXTCNTL); /* enable extensions */
+ outb(TS_DATA, 0xea);
+
+
+ if(cols == SCR_COL132) /* switch 80 -> 132 */
+ {
+ /* save state of board for 80 columns */
+
+ if(!regsaved)
+ {
+ regsaved = 1;
+
+ sp = savearea.v7_1024i;
+
+ outb(addr_6845, 0x00); /* Horizontal Total */
+ *sp++ = inb(addr_6845+1);
+ outb(addr_6845, 0x01); /* Horizontal Display End */
+ *sp++ = inb(addr_6845+1);
+ outb(addr_6845, 0x02); /* Horizontal Blank Start */
+ *sp++ = inb(addr_6845+1);
+ outb(addr_6845, 0x03); /* Horizontal Blank End */
+ *sp++ = inb(addr_6845+1);
+ outb(addr_6845, 0x04); /* Horizontal Retrace Start */
+ *sp++ = inb(addr_6845+1);
+ outb(addr_6845, 0x05); /* Horizontal Retrace End */
+ *sp++ = inb(addr_6845+1);
+
+ outb(addr_6845, 0x13); /* Row Offset Register */
+ *sp++ = inb(addr_6845+1);
+
+ outb(TS_INDEX, TS_MODE);/* Timing Sequencer */
+ *sp++ = inb(TS_DATA);
+
+ if(color)
+ inb(GN_INPSTAT1C);
+ else
+ inb(GN_INPSTAT1M);
+ /* ATC Mode control */
+ outb(ATC_INDEX, ATC_MODE | ATC_ACCESS);
+ *sp++ = inb(ATC_DATAR);
+
+ if(color)
+ inb(GN_INPSTAT1C);
+ else
+ inb(GN_INPSTAT1M);
+ /* ATC Horizontal Pixel Panning */
+ outb(ATC_INDEX, ATC_HORPIXPAN | ATC_ACCESS);
+ *sp++ = inb(ATC_DATAR);
+
+ outb(TS_INDEX, 0x83);
+ *sp++ = inb(TS_DATA);
+
+ outb(TS_INDEX, 0xa4);
+ *sp++ = inb(TS_DATA);
+
+ outb(TS_INDEX, 0xe0);
+ *sp++ = inb(TS_DATA);
+
+ outb(TS_INDEX, 0xe4);
+ *sp++ = inb(TS_DATA);
+
+ outb(TS_INDEX, 0xf8);
+ *sp++ = inb(TS_DATA);
+
+ outb(TS_INDEX, 0xfd);
+ *sp++ = inb(TS_DATA);
+
+ *sp++ = inb(GN_MISCOUTR); /* Misc output register */
+ }
+
+ /* setup chipset for 132 column operation */
+
+ outb(addr_6845, 0x00); /* Horizontal Total */
+ outb(addr_6845+1, 0x9c);
+ outb(addr_6845, 0x01); /* Horizontal Display End */
+ outb(addr_6845+1, 0x83);
+ outb(addr_6845, 0x02); /* Horizontal Blank Start */
+ outb(addr_6845+1, 0x86);
+ outb(addr_6845, 0x03); /* Horizontal Blank End */
+ outb(addr_6845+1, 0x9e);
+ outb(addr_6845, 0x04); /* Horizontal Retrace Start */
+ outb(addr_6845+1, 0x89);
+ outb(addr_6845, 0x05); /* Horizontal Retrace End */
+ outb(addr_6845+1, 0x1c);
+
+ outb(addr_6845, 0x13); /* Row Offset Register */
+ outb(addr_6845+1, 0x42);
+
+ outb(TS_INDEX, TS_MODE);/* Timing Sequencer */
+ outb(TS_DATA, 0x01); /* 8 dot char clock */
+
+ if(color)
+ inb(GN_INPSTAT1C);
+ else
+ inb(GN_INPSTAT1M);
+ outb(ATC_INDEX, ATC_MODE | ATC_ACCESS); /* ATC Mode control */
+ outb(ATC_DATAW, 0x08); /* Line graphics disable */
+
+ if(color)
+ inb(GN_INPSTAT1C);
+ else
+ inb(GN_INPSTAT1M);
+ outb(ATC_INDEX, ATC_HORPIXPAN | ATC_ACCESS); /* ATC Horizontal Pixel Panning */
+ outb(ATC_DATAW, 0x00);
+
+ outb(TS_INDEX, TS_SYNCRESET);
+ outb(TS_DATA, 0x01); /* synchronous reset */
+
+ outb(TS_INDEX, 0x83);
+ outb(TS_DATA, 0xa0);
+
+ outb(TS_INDEX, 0xa4);
+ outb(TS_DATA, 0x1c);
+
+ outb(TS_INDEX, 0xe0);
+ outb(TS_DATA, 0x00);
+
+ outb(TS_INDEX, 0xe4);
+ outb(TS_DATA, 0xfe);
+
+ outb(TS_INDEX, 0xf8);
+ outb(TS_DATA, 0x1b);
+
+ outb(TS_INDEX, 0xfd);
+ outb(TS_DATA, 0x33);
+
+ byte = inb(GN_MISCOUTR);
+ byte |= 0x0c;
+ outb(GN_MISCOUTW, byte); /* Misc output register */
+
+ outb(TS_INDEX, TS_SYNCRESET);
+ outb(TS_DATA, 0x03); /* clear synchronous reset */
+ }
+ else /* switch 132 -> 80 */
+ {
+ if(!regsaved) /* failsafe */
+ {
+ outb(TS_INDEX, TS_EXTCNTL); /* disable extensions */
+ outb(TS_DATA, 0xae);
+
+ /* disable access to first 7 CRTC registers */
+ outb(addr_6845, CRTC_VSYNCE);
+ outb(addr_6845+1, byte);
+ vga_screen_on();
+ return(0);
+ }
+
+ sp = savearea.v7_1024i;
+
+ outb(addr_6845, 0x00); /* Horizontal Total */
+ outb(addr_6845+1, *sp++);
+ outb(addr_6845, 0x01); /* Horizontal Display End */
+ outb(addr_6845+1, *sp++);
+ outb(addr_6845, 0x02); /* Horizontal Blank Start */
+ outb(addr_6845+1, *sp++);
+ outb(addr_6845, 0x03); /* Horizontal Blank End */
+ outb(addr_6845+1, *sp++);
+ outb(addr_6845, 0x04); /* Horizontal Retrace Start */
+ outb(addr_6845+1, *sp++);
+ outb(addr_6845, 0x05); /* Horizontal Retrace End */
+ outb(addr_6845+1, *sp++);
+
+ outb(addr_6845, 0x13); /* Row Offset Register */
+ outb(addr_6845+1, *sp++);
+
+ outb(TS_INDEX, TS_MODE);/* Timing Sequencer */
+ outb(TS_DATA, *sp++);
+
+ if(color)
+ inb(GN_INPSTAT1C);
+ else
+ inb(GN_INPSTAT1M);
+ /* ATC Mode control */
+ outb(ATC_INDEX, ATC_MODE | ATC_ACCESS);
+ outb(ATC_DATAW, *sp++);
+
+ if(color)
+ inb(GN_INPSTAT1C);
+ else
+ inb(GN_INPSTAT1M);
+ /* ATC Horizontal Pixel Panning */
+ outb(ATC_INDEX, ATC_HORPIXPAN | ATC_ACCESS);
+ outb(ATC_DATAW, *sp++);
+
+ outb(TS_INDEX, TS_SYNCRESET);
+ outb(TS_DATA, 0x01); /* synchronous reset */
+
+ outb(TS_INDEX, 0x83);
+ outb(TS_DATA, *sp++);
+
+ outb(TS_INDEX, 0xa4);
+ outb(TS_DATA, *sp++);
+
+ outb(TS_INDEX, 0xe0);
+ outb(TS_DATA, *sp++);
+
+ outb(TS_INDEX, 0xe4);
+ outb(TS_DATA, *sp++);
+
+ outb(TS_INDEX, 0xf8);
+ outb(TS_DATA, *sp++);
+
+ outb(TS_INDEX, 0xfd);
+ outb(TS_DATA, *sp++);
+
+ outb(GN_MISCOUTW, *sp++); /* Misc output register */
+
+ outb(TS_INDEX, TS_SYNCRESET);
+ outb(TS_DATA, 0x03); /* clear synchronous reset */
+ }
+
+ outb(TS_INDEX, TS_EXTCNTL); /* disable extensions */
+ outb(TS_DATA, 0xae);
+
+ /* disable access to first 7 CRTC registers */
+
+ outb(addr_6845, CRTC_VSYNCE);
+ outb(addr_6845+1, save__byte);
+
+ vga_screen_on();
+
+ return(1);
+}
+
+/*---------------------------------------------------------------------------*
+ * toggle 80/132 column operation for S3 86C928 based boards
+ *---------------------------------------------------------------------------*/
+int
+s3_928_col(int cols)
+{
+ u_char *sp;
+ u_char byte;
+
+ vga_screen_off();
+
+ outb(addr_6845, 0x38);
+ outb(addr_6845+1, 0x48); /* unlock registers */
+ outb(addr_6845, 0x39);
+ outb(addr_6845+1, 0xa0); /* unlock registers */
+
+ /* enable access to first 7 CRTC registers */
+
+ outb(addr_6845, CRTC_VSYNCE);
+ byte = inb(addr_6845+1);
+ outb(addr_6845, CRTC_VSYNCE);
+ outb(addr_6845+1, byte & 0x7f);
+
+ if(cols == SCR_COL132) /* switch 80 -> 132 */
+ {
+ /* save state of board for 80 columns */
+
+ if(!regsaved)
+ {
+ regsaved = 1;
+
+ sp = savearea.s3_928;
+
+ outb(addr_6845, 0x00); /* Horizontal Total */
+ *sp++ = inb(addr_6845+1);
+ outb(addr_6845, 0x01); /* Horizontal Display End */
+ *sp++ = inb(addr_6845+1);
+ outb(addr_6845, 0x02); /* Horizontal Blank Start */
+ *sp++ = inb(addr_6845+1);
+ outb(addr_6845, 0x03); /* Horizontal Blank End */
+ *sp++ = inb(addr_6845+1);
+ outb(addr_6845, 0x04); /* Horizontal Retrace Start */
+ *sp++ = inb(addr_6845+1);
+ outb(addr_6845, 0x05); /* Horizontal Retrace End */
+ *sp++ = inb(addr_6845+1);
+
+ outb(addr_6845, 0x13); /* Row Offset Register */
+ *sp++ = inb(addr_6845+1);
+
+ outb(addr_6845, 0x34); /* Backward Compat 3 Reg */
+ *sp++ = inb(addr_6845+1);
+ outb(addr_6845, 0x3b); /* Data Xfer Exec Position */
+ *sp++ = inb(addr_6845+1);
+
+ outb(addr_6845, 0x42); /* (Clock) Mode Control */
+ *sp++ = inb(addr_6845+1);
+
+ outb(TS_INDEX, TS_MODE);/* Timing Sequencer */
+ *sp++ = inb(TS_DATA);
+
+ if(color)
+ inb(GN_INPSTAT1C);
+ else
+ inb(GN_INPSTAT1M);
+ /* ATC Mode control */
+ outb(ATC_INDEX, ATC_MODE | ATC_ACCESS);
+ *sp++ = inb(ATC_DATAR);
+
+ if(color)
+ inb(GN_INPSTAT1C);
+ else
+ inb(GN_INPSTAT1M);
+ /* ATC Horizontal Pixel Panning */
+ outb(ATC_INDEX, ATC_HORPIXPAN | ATC_ACCESS);
+ *sp++ = inb(ATC_DATAR);
+
+ *sp++ = inb(GN_MISCOUTR); /* Misc output register */
+ }
+
+ /* setup chipset for 132 column operation */
+
+ outb(addr_6845, 0x00); /* Horizontal Total */
+ outb(addr_6845+1, 0x9a);
+ outb(addr_6845, 0x01); /* Horizontal Display End */
+ outb(addr_6845+1, 0x83);
+ outb(addr_6845, 0x02); /* Horizontal Blank Start */
+ outb(addr_6845+1, 0x86);
+ outb(addr_6845, 0x03); /* Horizontal Blank End */
+ outb(addr_6845+1, 0x9d);
+ outb(addr_6845, 0x04); /* Horizontal Retrace Start */
+ outb(addr_6845+1, 0x87);
+ outb(addr_6845, 0x05); /* Horizontal Retrace End */
+ outb(addr_6845+1, 0x1b);
+
+ outb(addr_6845, 0x13); /* Row Offset Register */
+ outb(addr_6845+1, 0x42);
+
+ outb(addr_6845, 0x34);
+ outb(addr_6845+1, 0x10);/* enable data xfer pos control */
+ outb(addr_6845, 0x3b);
+ outb(addr_6845+1, 0x90);/* set data xfer pos value */
+
+ outb(addr_6845, 0x42); /* (Clock) Mode Control */
+ outb(addr_6845+1, 0x02);/* Select 40MHz Clock */
+
+ outb(TS_INDEX, TS_MODE);/* Timing Sequencer */
+ outb(TS_DATA, 0x01); /* 8 dot char clock */
+
+ if(color)
+ inb(GN_INPSTAT1C);
+ else
+ inb(GN_INPSTAT1M);
+ outb(ATC_INDEX, ATC_MODE | ATC_ACCESS); /* ATC Mode control */
+ outb(ATC_DATAW, 0x08); /* Line graphics disable */
+
+ if(color)
+ inb(GN_INPSTAT1C);
+ else
+ inb(GN_INPSTAT1M);
+ outb(ATC_INDEX, ATC_HORPIXPAN | ATC_ACCESS); /* ATC Horizontal Pixel Panning */
+ outb(ATC_DATAW, 0x00);
+
+ /* Misc output register */
+
+ outb(GN_MISCOUTW, (inb(GN_MISCOUTR) | 0x0c));
+ }
+ else /* switch 132 -> 80 */
+ {
+ if(!regsaved) /* failsafe */
+ {
+ /* disable access to first 7 CRTC registers */
+ outb(addr_6845, CRTC_VSYNCE);
+ outb(addr_6845+1, byte);
+
+ outb(addr_6845, 0x38);
+ outb(addr_6845+1, 0x00); /* lock registers */
+ outb(addr_6845, 0x39);
+ outb(addr_6845+1, 0x00); /* lock registers */
+
+ vga_screen_on();
+ return(0);
+ }
+
+ sp = savearea.s3_928;
+
+ outb(addr_6845, 0x00); /* Horizontal Total */
+ outb(addr_6845+1, *sp++);
+ outb(addr_6845, 0x01); /* Horizontal Display End */
+ outb(addr_6845+1, *sp++);
+ outb(addr_6845, 0x02); /* Horizontal Blank Start */
+ outb(addr_6845+1, *sp++);
+ outb(addr_6845, 0x03); /* Horizontal Blank End */
+ outb(addr_6845+1, *sp++);
+ outb(addr_6845, 0x04); /* Horizontal Retrace Start */
+ outb(addr_6845+1, *sp++);
+ outb(addr_6845, 0x05); /* Horizontal Retrace End */
+ outb(addr_6845+1, *sp++);
+
+ outb(addr_6845, 0x13); /* Row Offset Register */
+ outb(addr_6845+1, *sp++);
+
+ outb(addr_6845, 0x34);
+ outb(addr_6845+1, *sp++);
+ outb(addr_6845, 0x3b);
+ outb(addr_6845+1, *sp++);
+
+ outb(addr_6845, 0x42); /* Mode control */
+ outb(addr_6845+1, *sp++);
+
+ outb(TS_INDEX, TS_MODE);/* Timing Sequencer */
+ outb(TS_DATA, *sp++);
+
+ if(color)
+ inb(GN_INPSTAT1C);
+ else
+ inb(GN_INPSTAT1M);
+ /* ATC Mode control */
+ outb(ATC_INDEX, ATC_MODE | ATC_ACCESS);
+ outb(ATC_DATAW, *sp++);
+
+ if(color)
+ inb(GN_INPSTAT1C);
+ else
+ inb(GN_INPSTAT1M);
+ /* ATC Horizontal Pixel Panning */
+ outb(ATC_INDEX, ATC_HORPIXPAN | ATC_ACCESS);
+ outb(ATC_DATAW, *sp++);
+
+ outb(GN_MISCOUTW, *sp++); /* Misc output register */
+ }
+
+ /* disable access to first 7 CRTC registers */
+
+ outb(addr_6845, CRTC_VSYNCE);
+ outb(addr_6845+1, byte);
+
+ outb(addr_6845, 0x38);
+ outb(addr_6845+1, 0x00); /* lock registers */
+ outb(addr_6845, 0x39);
+ outb(addr_6845+1, 0x00); /* lock registers */
+
+ vga_screen_on();
+
+ return(1);
+}
+
+/*---------------------------------------------------------------------------*
+ * toggle 80/132 column operation for Cirrus Logic 542x based boards
+ *---------------------------------------------------------------------------*/
+int
+cl_gd542x_col(int cols)
+{
+ u_char *sp;
+ u_char byte;
+
+ vga_screen_off();
+
+ /* enable access to first 7 CRTC registers */
+
+ outb(addr_6845, CRTC_VSYNCE);
+ byte = inb(addr_6845+1);
+ outb(addr_6845, CRTC_VSYNCE);
+ outb(addr_6845+1, byte & 0x7f);
+
+ /* enable access to cirrus extension registers */
+ outb(TS_INDEX, 6);
+ outb(TS_DATA, 0x12);
+
+ if(cols == SCR_COL132) /* switch 80 -> 132 */
+ {
+ /* save state of board for 80 columns */
+
+ if(!regsaved)
+ {
+ regsaved = 1;
+
+ sp = savearea.cirrus;
+
+ outb(addr_6845, 0x00); /* Horizontal Total */
+ *sp++ = inb(addr_6845+1);
+ outb(addr_6845, 0x01); /* Horizontal Display End */
+ *sp++ = inb(addr_6845+1);
+ outb(addr_6845, 0x02); /* Horizontal Blank Start */
+ *sp++ = inb(addr_6845+1);
+ outb(addr_6845, 0x03); /* Horizontal Blank End */
+ *sp++ = inb(addr_6845+1);
+ outb(addr_6845, 0x04); /* Horizontal Retrace Start */
+ *sp++ = inb(addr_6845+1);
+ outb(addr_6845, 0x05); /* Horizontal Retrace End */
+ *sp++ = inb(addr_6845+1);
+
+ outb(addr_6845, 0x13); /* Row Offset Register */
+ *sp++ = inb(addr_6845+1);
+
+ outb(TS_INDEX, TS_MODE);/* Timing Sequencer */
+ *sp++ = inb(TS_DATA);
+
+
+ if(color)
+ inb(GN_INPSTAT1C);
+ else
+ inb(GN_INPSTAT1M);
+ /* ATC Mode control */
+ outb(ATC_INDEX, ATC_MODE | ATC_ACCESS);
+ *sp++ = inb(ATC_DATAR);
+
+ if(color)
+ inb(GN_INPSTAT1C);
+ else
+ inb(GN_INPSTAT1M);
+ /* ATC Horizontal Pixel Panning */
+ outb(ATC_INDEX, ATC_HORPIXPAN | ATC_ACCESS);
+ *sp++ = inb(ATC_DATAR);
+
+ /* VCLK2 Numerator Register */
+ outb(TS_INDEX, 0xd);
+ *sp++ = inb(TS_DATA);
+
+ /* VCLK2 Denominator and Post-Scalar Value Register */
+ outb(TS_INDEX, 0x1d);
+ *sp++ = inb(TS_DATA);
+
+ /* Misc output register */
+ *sp++ = inb(GN_MISCOUTR);
+ }
+
+ /* setup chipset for 132 column operation */
+
+ outb(addr_6845, 0x00); /* Horizontal Total */
+ outb(addr_6845+1, 0x9f);
+ outb(addr_6845, 0x01); /* Horizontal Display End */
+ outb(addr_6845+1, 0x83);
+ outb(addr_6845, 0x02); /* Horizontal Blank Start */
+ outb(addr_6845+1, 0x84);
+ outb(addr_6845, 0x03); /* Horizontal Blank End */
+ outb(addr_6845+1, 0x82);
+ outb(addr_6845, 0x04); /* Horizontal Retrace Start */
+ outb(addr_6845+1, 0x8a);
+ outb(addr_6845, 0x05); /* Horizontal Retrace End */
+ outb(addr_6845+1, 0x9e);
+
+ outb(addr_6845, 0x13); /* Row Offset Register */
+ outb(addr_6845+1, 0x42);
+
+ /* set VCLK2 to 41.164 MHz ..... */
+ outb(TS_INDEX, 0xd); /* VCLK2 Numerator Register */
+ outb(TS_DATA, 0x45);
+
+ outb(TS_INDEX, 0x1d); /* VCLK2 Denominator and */
+ outb(TS_DATA, 0x30); /* Post-Scalar Value Register */
+
+ /* and use it. */
+ outb(GN_MISCOUTW, (inb(GN_MISCOUTR) & ~0x0c) | (2 << 2));
+
+ outb(TS_INDEX, TS_MODE);/* Timing Sequencer */
+ outb(TS_DATA, 0x01); /* 8 dot char clock */
+
+ if(color)
+ inb(GN_INPSTAT1C);
+ else
+ inb(GN_INPSTAT1M);
+ outb(ATC_INDEX, ATC_MODE | ATC_ACCESS); /* ATC Mode control */
+ outb(ATC_DATAW, 0x08); /* Line graphics disable */
+
+ if(color)
+ inb(GN_INPSTAT1C);
+ else
+ inb(GN_INPSTAT1M);
+ outb(ATC_INDEX, ATC_HORPIXPAN | ATC_ACCESS); /* ATC Horizontal Pixel Panning */
+ outb(ATC_DATAW, 0x00);
+ }
+ else /* switch 132 -> 80 */
+ {
+ if(!regsaved) /* failsafe */
+ {
+ /* disable access to first 7 CRTC registers */
+ outb(addr_6845, CRTC_VSYNCE);
+ outb(addr_6845+1, byte);
+
+ /* disable access to cirrus extension registers */
+ outb(TS_INDEX, 6);
+ outb(TS_DATA, 0);
+
+ vga_screen_on();
+ return(0);
+ }
+
+ sp = savearea.cirrus;
+
+ outb(addr_6845, 0x00); /* Horizontal Total */
+ outb(addr_6845+1, *sp++);
+ outb(addr_6845, 0x01); /* Horizontal Display End */
+ outb(addr_6845+1, *sp++);
+ outb(addr_6845, 0x02); /* Horizontal Blank Start */
+ outb(addr_6845+1, *sp++);
+ outb(addr_6845, 0x03); /* Horizontal Blank End */
+ outb(addr_6845+1, *sp++);
+ outb(addr_6845, 0x04); /* Horizontal Retrace Start */
+ outb(addr_6845+1, *sp++);
+ outb(addr_6845, 0x05); /* Horizontal Retrace End */
+ outb(addr_6845+1, *sp++);
+
+ outb(addr_6845, 0x13); /* Row Offset Register */
+ outb(addr_6845+1, *sp++);
+
+ outb(TS_INDEX, TS_MODE);/* Timing Sequencer */
+ outb(TS_DATA, *sp++);
+
+ if(color)
+ inb(GN_INPSTAT1C);
+ else
+ inb(GN_INPSTAT1M);
+ /* ATC Mode control */
+ outb(ATC_INDEX, ATC_MODE | ATC_ACCESS);
+ outb(ATC_DATAW, *sp++);
+
+ if(color)
+ inb(GN_INPSTAT1C);
+ else
+ inb(GN_INPSTAT1M);
+ /* ATC Horizontal Pixel Panning */
+ outb(ATC_INDEX, ATC_HORPIXPAN | ATC_ACCESS);
+ outb(ATC_DATAW, *sp++);
+
+ /* VCLK2 Numerator Register */
+ outb(TS_INDEX, 0xd);
+ outb(TS_DATA, *sp++);
+
+ /* VCLK2 Denominator and Post-Scalar Value Register */
+ outb(TS_INDEX, 0x1d);
+ outb(TS_DATA, *sp++);
+
+ outb(GN_MISCOUTW, *sp++); /* Misc output register */
+ }
+
+ /* disable access to cirrus extension registers */
+ outb(TS_INDEX, 6);
+ outb(TS_DATA, 0);
+
+ /* disable access to first 7 CRTC registers */
+
+ outb(addr_6845, CRTC_VSYNCE);
+ outb(addr_6845+1, byte);
+
+ vga_screen_on();
+
+ return(1);
+}
+
+/*---------------------------------------------------------------------------*
+ * switch screen from text mode to X-mode and vice versa
+ *---------------------------------------------------------------------------*/
+void
+switch_screen(int n, int oldgrafx, int newgrafx)
+{
+
+#if PCVT_SCREENSAVER
+ static unsigned saved_scrnsv_tmo = 0;
+#endif /* PCVT_SCREENSAVER */
+
+#if !PCVT_KBD_FIFO
+ int x;
+#endif /* !PCVT_KBD_FIFO */
+
+ int cols = vsp->maxcol; /* get current col val */
+
+ if(n < 0 || n >= totalscreens)
+ return;
+
+#if !PCVT_KBD_FIFO
+ x = spltty(); /* protect us */
+#endif /* !PCVT_KBD_FIFO */
+
+ if(!oldgrafx && newgrafx)
+ {
+ /* switch from text to graphics */
+
+#if PCVT_SCREENSAVER
+ if((saved_scrnsv_tmo = scrnsv_timeout))
+ pcvt_set_scrnsv_tmo(0); /* screensaver off */
+#endif /* PCVT_SCREENSAVER */
+
+ async_update(UPDATE_STOP); /* status display off */
+ }
+
+ if(!oldgrafx)
+ {
+ /* switch from text mode */
+
+ /* video board memory -> kernel memory */
+ bcopy(vsp->Crtat, vsp->Memory,
+ vsp->screen_rows * vsp->maxcol * CHR);
+
+ vsp->Crtat = vsp->Memory; /* operate in memory now */
+ }
+
+ /* update global screen pointers/variables */
+ current_video_screen = n; /* current screen no */
+
+#if !PCVT_NETBSD && !(PCVT_FREEBSD > 110 && PCVT_FREEBSD < 200)
+ pcconsp = &pccons[n]; /* current tty */
+#elif PCVT_FREEBSD > 110 && PCVT_FREEBSD < 200
+ pcconsp = pccons[n]; /* current tty */
+#elif PCVT_NETBSD > 100
+ pcconsp = vs[n].vs_tty; /* current tty */
+#else
+ pcconsp = pc_tty[n]; /* current tty */
+#endif
+
+ vsp = &vs[n]; /* current video state ptr */
+
+ if(oldgrafx && !newgrafx)
+ {
+ /* switch from graphics to text mode */
+ unsigned i;
+
+ /* restore fonts */
+ for(i = 0; i < totalfonts; i++)
+ if(saved_charsets[i])
+ vga_move_charset(i, 0, 0);
+
+#if PCVT_SCREENSAVER
+ /* activate screen saver */
+ if(saved_scrnsv_tmo)
+ pcvt_set_scrnsv_tmo(saved_scrnsv_tmo);
+#endif /* PCVT_SCREENSAVER */
+
+ /* re-initialize lost MDA information */
+ if(adaptor_type == MDA_ADAPTOR)
+ {
+ /*
+ * Due to the fact that HGC registers are write-only,
+ * the Xserver can only make guesses about the state
+ * the HGC adaptor has been before turning on X mode.
+ * Thus, the display must be re-enabled now, and the
+ * cursor shape and location restored.
+ */
+ outb(GN_DMCNTLM, 0x28); /* enable display, text mode */
+ outb(addr_6845, CRTC_CURSORH); /* select high register */
+ outb(addr_6845+1,
+ ((vsp->Crtat + vsp->cur_offset) - Crtat) >> 8);
+ outb(addr_6845, CRTC_CURSORL); /* select low register */
+ outb(addr_6845+1,
+ ((vsp->Crtat + vsp->cur_offset) - Crtat));
+
+ outb(addr_6845, CRTC_CURSTART); /* select high register */
+ outb(addr_6845+1, vsp->cursor_start);
+ outb(addr_6845, CRTC_CUREND); /* select low register */
+ outb(addr_6845+1, vsp->cursor_end);
+ }
+
+ /* make status display happy */
+ async_update(UPDATE_START);
+ }
+
+ if(!newgrafx)
+ {
+ /* to text mode */
+
+ /* kernel memory -> video board memory */
+ bcopy(vsp->Crtat, Crtat,
+ vsp->screen_rows * vsp->maxcol * CHR);
+
+ vsp->Crtat = Crtat; /* operate on screen now */
+
+ outb(addr_6845, CRTC_STARTADRH);
+ outb(addr_6845+1, 0);
+ outb(addr_6845, CRTC_STARTADRL);
+ outb(addr_6845+1, 0);
+ }
+
+#if !PCVT_KBD_FIFO
+ splx(x);
+#endif /* !PCVT_KBD_FIFO */
+
+ select_vga_charset(vsp->vga_charset);
+
+ if(vsp->maxcol != cols)
+ vga_col(vsp, vsp->maxcol); /* select 80/132 columns */
+
+ outb(addr_6845, CRTC_CURSORH); /* select high register */
+ outb(addr_6845+1, vsp->cur_offset >> 8);
+ outb(addr_6845, CRTC_CURSORL); /* select low register */
+ outb(addr_6845+1, vsp->cur_offset);
+
+ if(vsp->cursor_on)
+ {
+ outb(addr_6845, CRTC_CURSTART); /* select high register */
+ outb(addr_6845+1, vsp->cursor_start);
+ outb(addr_6845, CRTC_CUREND); /* select low register */
+ outb(addr_6845+1, vsp->cursor_end);
+ }
+ else
+ {
+ sw_cursor(0);
+ }
+
+ if(adaptor_type == VGA_ADAPTOR)
+ {
+ unsigned i;
+
+ /* switch VGA DAC palette entries */
+ for(i = 0; i < NVGAPEL; i++)
+ vgapaletteio(i, &vsp->palette[i], 1);
+ }
+
+ if(!newgrafx)
+ {
+ update_led(); /* update led's */
+ update_hp(vsp); /* update fkey labels, if present */
+
+ /* if we switch to a vt with force 24 lines mode and */
+ /* pure VT emulation and 25 rows charset, then we have */
+ /* to clear the last line on display ... */
+
+ if(vsp->force24 && (vsp->vt_pure_mode == M_PUREVT) &&
+ (vgacs[vsp->vga_charset].screen_size == SIZ_25ROWS))
+ {
+ fillw(' ', vsp->Crtat + vsp->screen_rows * vsp->maxcol,
+ vsp->maxcol);
+ }
+ }
+ kbd_setmode(vsp->kbd_state);
+}
+
+/*---------------------------------------------------------------------------*
+ * Change specified vt to VT_AUTO mode
+ * xxx Maybe this should also reset VT_GRAFX mode; since switching and
+ * graphics modes are not going to work without VT_PROCESS mode.
+ *---------------------------------------------------------------------------*/
+static void
+set_auto_mode (struct video_state *vsx)
+{
+ unsigned ostatus = vsx->vt_status;
+ vsx->smode.mode = VT_AUTO;
+ vsx->proc = NULL;
+ vsx->pid = 0;
+ vsx->vt_status &= ~(VT_WAIT_REL|VT_WAIT_ACK);
+ if (ostatus & VT_WAIT_ACK) {
+#if 0
+ assert (!(ostatus&VT_WAIT_REL));
+ assert (vsp == vsx &&
+ vt_switch_pending == current_video_screen + 1);
+ vt_switch_pending = 0;
+#else
+ if (vsp == vsx &&
+ vt_switch_pending == current_video_screen + 1)
+ vt_switch_pending = 0;
+#endif
+ }
+ if (ostatus&VT_WAIT_REL) {
+ int new_screen = vt_switch_pending - 1;
+#if 0
+ assert(vsp == vsx && vt_switch_pending);
+ vt_switch_pending = 0;
+ vgapage (new_screen);
+#else
+ if (vsp == vsx && vt_switch_pending) {
+ vt_switch_pending = 0;
+ vgapage (new_screen);
+ }
+#endif
+ }
+}
+
+/*---------------------------------------------------------------------------*
+ * Exported function; to be called when a vt is closed down.
+ *
+ * Ideally, we would like to be able to recover from an X server crash;
+ * but in reality, if the server crashes hard while in control of the
+ * vga board, then you're not likely to be able to use pcvt ttys
+ * without rebooting.
+ *---------------------------------------------------------------------------*/
+void
+reset_usl_modes (struct video_state *vsx)
+{
+ /* Clear graphics mode */
+ if (vsx->vt_status & VT_GRAFX)
+ {
+ vsx->vt_status &= ~VT_GRAFX;
+ if (vsp == vsx)
+ switch_screen(current_video_screen, 1, 0);
+ }
+
+ /* Take kbd out of raw mode */
+ if(vsx->kbd_state == K_RAW)
+ {
+ if(vsx == vsp)
+ kbd_setmode(K_XLATE);
+ vsx->kbd_state = K_XLATE;
+ }
+
+ /* Clear process controlled mode */
+ set_auto_mode (vsx);
+}
+
+/*---------------------------------------------------------------------------*
+ * switch to virtual screen n (0 ... PCVT_NSCREENS-1)
+ * (the name vgapage() stands for historical reasons)
+ *---------------------------------------------------------------------------*/
+int
+vgapage(int new_screen)
+{
+ int x;
+
+ if(new_screen < 0 || new_screen >= totalscreens)
+ return EINVAL;
+
+ /* fallback to VT_AUTO if controlling processes died */
+ if(vsp->proc && vsp->proc != pfind(vsp->pid))
+ set_auto_mode(vsp);
+ if(vs[new_screen].proc
+ && vs[new_screen].proc != pfind(vs[new_screen].pid))
+ set_auto_mode(&vs[new_screen]);
+
+ if (!vt_switch_pending && new_screen == current_video_screen)
+ return 0;
+
+ if(vt_switch_pending && vt_switch_pending != new_screen + 1) {
+ /* Try resignaling uncooperative X-window servers */
+ if (vsp->smode.mode == VT_PROCESS) {
+ if (vsp->vt_status & VT_WAIT_REL) {
+ if(vsp->smode.relsig)
+ psignal(vsp->proc, vsp->smode.relsig);
+ } else if (vsp->vt_status & VT_WAIT_ACK) {
+ if(vsp->smode.acqsig)
+ psignal(vsp->proc, vsp->smode.acqsig);
+ }
+ }
+ return EAGAIN;
+ }
+
+ vt_switch_pending = new_screen + 1;
+
+ if(vsp->smode.mode == VT_PROCESS)
+ {
+ /* we cannot switch immediately here */
+ vsp->vt_status |= VT_WAIT_REL;
+ if(vsp->smode.relsig)
+ psignal(vsp->proc, vsp->smode.relsig);
+ }
+ else
+ {
+ struct video_state *old_vsp = vsp;
+
+ switch_screen(new_screen,
+ vsp->vt_status & VT_GRAFX,
+ vs[new_screen].vt_status & VT_GRAFX);
+
+ x = spltty();
+ if(old_vsp->vt_status & VT_WAIT_ACT)
+ {
+ old_vsp->vt_status &= ~VT_WAIT_ACT;
+ wakeup((caddr_t)&old_vsp->smode);
+ }
+ if(vsp->vt_status & VT_WAIT_ACT)
+ {
+ vsp->vt_status &= ~VT_WAIT_ACT;
+ wakeup((caddr_t)&vsp->smode);
+ }
+ splx(x);
+
+ if(vsp->smode.mode == VT_PROCESS)
+ {
+ /* if _new_ vt is under process control... */
+ vsp->vt_status |= VT_WAIT_ACK;
+ if(vsp->smode.acqsig)
+ psignal(vsp->proc, vsp->smode.acqsig);
+ }
+ else
+ {
+ /* we are committed */
+ vt_switch_pending = 0;
+
+#if PCVT_FREEBSD > 206
+ /*
+ * XXX: If pcvt is acting as the systems console,
+ * avoid panics going to the debugger while we are in
+ * process mode.
+ */
+ if(pcvt_is_console)
+ cons_unavail = 0;
+#endif
+ }
+ }
+ return 0;
+}
+
+/*---------------------------------------------------------------------------*
+ * VT_USL ioctl handling
+ *---------------------------------------------------------------------------*/
+int
+usl_vt_ioctl(Dev_t dev, int cmd, caddr_t data, int flag, struct proc *p)
+{
+ int i, j, error, opri, mode;
+ struct vt_mode newmode;
+ struct video_state *vsx = &vs[minor(dev)];
+
+ switch(cmd)
+ {
+
+ case VT_SETMODE:
+ newmode = *(struct vt_mode *)data;
+
+ opri = spltty();
+
+ if (newmode.mode != VT_PROCESS)
+ {
+ if (vsx->smode.mode == VT_PROCESS)
+ {
+ if (vsx->proc != p)
+ {
+ splx(opri);
+ return EPERM;
+ }
+ set_auto_mode(vsx);
+ }
+ splx(opri);
+ return 0;
+ }
+
+ /*
+ * NB: XFree86-3.1.1 does the following:
+ * VT_ACTIVATE (vtnum)
+ * VT_WAITACTIVE (vtnum)
+ * VT_SETMODE (VT_PROCESS)
+ * So it is possible that the screen was switched
+ * between the WAITACTIVE and the SETMODE (here). This
+ * can actually happen quite frequently, and it was
+ * leading to dire consequences. Now it is detected by
+ * requiring that minor(dev) match current_video_screen.
+ * An alternative would be to operate on vs[minor(dev)]
+ * instead of *vsp, but that would leave the server
+ * confused, because it would believe that its vt was
+ * currently activated.
+ */
+ if (minor(dev) != current_video_screen)
+ {
+ splx(opri);
+ return EPERM;
+ }
+
+ /* Check for server died */
+
+ if(vsp->proc && vsp->proc != pfind(vsp->pid))
+ set_auto_mode(vsp);
+
+ /* Check for server already running */
+
+ if (vsp->smode.mode == VT_PROCESS && vsp->proc != p)
+ {
+ splx(opri);
+ return EBUSY; /* already in use on this VT */
+ }
+
+ vsp->smode = newmode;
+ vsp->proc = p;
+ vsp->pid = p->p_pid;
+
+#if PCVT_FREEBSD > 206
+ /*
+ * XXX: If pcvt is acting as the systems console,
+ * avoid panics going to the debugger while we are in
+ * process mode.
+ */
+ if(pcvt_is_console)
+ cons_unavail = (newmode.mode == VT_PROCESS);
+#endif
+
+ splx(opri);
+ return 0;
+
+ case VT_GETMODE:
+ *(struct vt_mode *)data = vsp->smode;
+ return 0;
+
+ case VT_RELDISP:
+ if (minor(dev) != current_video_screen)
+ return EPERM;
+ if (vsp->smode.mode != VT_PROCESS)
+ return EINVAL;
+ if (vsp->proc != p)
+ return EPERM;
+ switch(*(int *)data)
+ {
+ case VT_FALSE:
+ /* process refuses to release screen; abort */
+ if(vt_switch_pending
+ && (vsp->vt_status & VT_WAIT_REL))
+ {
+ vsp->vt_status &= ~VT_WAIT_REL;
+ vt_switch_pending = 0;
+ return 0;
+ }
+ break;
+
+ case VT_TRUE:
+ /* process releases its VT */
+ if(vt_switch_pending
+ && (vsp->vt_status & VT_WAIT_REL))
+ {
+ int new_screen = vt_switch_pending - 1;
+ struct video_state *old_vsp = vsp;
+
+ vsp->vt_status &= ~VT_WAIT_REL;
+
+ switch_screen(new_screen,
+ vsp->vt_status & VT_GRAFX,
+ vs[new_screen].vt_status
+ & VT_GRAFX);
+
+ opri = spltty();
+ if(old_vsp->vt_status & VT_WAIT_ACT)
+ {
+ old_vsp->vt_status &= ~VT_WAIT_ACT;
+ wakeup((caddr_t)&old_vsp->smode);
+ }
+ if(vsp->vt_status & VT_WAIT_ACT)
+ {
+ vsp->vt_status &= ~VT_WAIT_ACT;
+ wakeup((caddr_t)&vsp->smode);
+ }
+ splx(opri);
+
+ if(vsp->smode.mode == VT_PROCESS)
+ {
+ /*
+ * if the new vt is also in process
+ * mode, we have to wait until its
+ * controlling process acknowledged
+ * the switch
+ */
+ vsp->vt_status
+ |= VT_WAIT_ACK;
+ if(vsp->smode.acqsig)
+ psignal(vsp->proc,
+ vsp->smode.acqsig);
+ }
+ else
+ {
+ /* we are committed */
+ vt_switch_pending = 0;
+
+#if PCVT_FREEBSD > 206
+ /* XXX */
+ if(pcvt_is_console)
+ cons_unavail = 0;
+#endif
+ }
+ return 0;
+ }
+ break;
+
+ case VT_ACKACQ:
+ /* new vts controlling process acknowledged */
+ if(vsp->vt_status & VT_WAIT_ACK)
+ {
+ vt_switch_pending = 0;
+ vsp->vt_status &= ~VT_WAIT_ACK;
+
+#if PCVT_FREEBSD > 206
+ /* XXX */
+ if(pcvt_is_console)
+ cons_unavail = 1;
+#endif
+ return 0;
+ }
+ break;
+ }
+ return EINVAL; /* end case VT_RELDISP */
+
+
+ case VT_OPENQRY:
+ /* return free vt */
+ for(i = 0; i < PCVT_NSCREENS; i++)
+ {
+ if(!vs[i].openf)
+ {
+ *(int *)data = i + 1;
+ return 0;
+ }
+ }
+ return EAGAIN;
+
+ case VT_GETACTIVE:
+ *(int *)data = current_video_screen + 1;
+ return 0;
+
+ case VT_ACTIVATE:
+ return vgapage(*(int *)data - 1);
+
+ case VT_WAITACTIVE:
+ /* sleep until vt switch happened */
+ i = *(int *)data - 1;
+
+ if(i != -1 && (i < 0 || i >= PCVT_NSCREENS))
+ return EINVAL;
+
+ if(i != -1 && current_video_screen == i)
+ return 0;
+
+ if(i == -1)
+ {
+ /* xxx Is this what it is supposed to do? */
+ int x = spltty();
+ i = current_video_screen;
+ error = 0;
+ while (current_video_screen == i &&
+ (error == 0 || error == ERESTART))
+ {
+ vs[i].vt_status |= VT_WAIT_ACT;
+ error = tsleep((caddr_t)&vs[i].smode,
+ PZERO | PCATCH, "waitvt", 0);
+ }
+ splx(x);
+ }
+ else
+ {
+ int x = spltty();
+ error = 0;
+ while (current_video_screen != i &&
+ (error == 0 || error == ERESTART))
+ {
+ vs[i].vt_status |= VT_WAIT_ACT;
+ error = tsleep((caddr_t)&vs[i].smode,
+ PZERO | PCATCH, "waitvt", 0);
+ }
+ splx(x);
+ }
+ return error;
+
+ case KDENABIO:
+ /* grant the process IO access; only allowed if euid == 0 */
+ {
+
+#if PCVT_NETBSD > 9 || PCVT_FREEBSD >= 200
+ struct trapframe *fp = (struct trapframe *)p->p_md.md_regs;
+#elif PCVT_NETBSD || (PCVT_FREEBSD && PCVT_FREEBSD > 102)
+ struct trapframe *fp = (struct trapframe *)p->p_regs;
+#else
+ struct syscframe *fp = (struct syscframe *)p->p_regs;
+#endif
+
+ if(suser(p->p_ucred, &p->p_acflag) != 0)
+ return (EPERM);
+
+#if PCVT_NETBSD || (PCVT_FREEBSD && PCVT_FREEBSD > 102)
+ fp->tf_eflags |= PSL_IOPL;
+#else
+ fp->sf_eflags |= PSL_IOPL;
+#endif
+
+ return 0;
+ }
+
+ case KDDISABIO:
+ /* abandon IO access permission */
+ {
+
+#if PCVT_NETBSD > 9 || PCVT_FREEBSD >= 200
+ struct trapframe *fp = (struct trapframe *)p->p_md.md_regs;
+ fp->tf_eflags &= ~PSL_IOPL;
+#elif PCVT_NETBSD || (PCVT_FREEBSD && PCVT_FREEBSD > 102)
+ struct trapframe *fp = (struct trapframe *)p->p_regs;
+ fp->tf_eflags &= ~PSL_IOPL;
+#else
+ struct syscframe *fp = (struct syscframe *)p->p_regs;
+ fp->sf_eflags &= ~PSL_IOPL;
+#endif
+
+ return 0;
+ }
+
+ case KDSETMODE:
+ {
+ int haschanged = 0;
+
+ if(adaptor_type != VGA_ADAPTOR
+ && adaptor_type != MDA_ADAPTOR)
+ /* X will only run on those adaptors */
+ return (EINVAL);
+
+ /* set text/graphics mode of current vt */
+ switch(*(int *)data)
+ {
+ case KD_TEXT:
+ haschanged = (vsx->vt_status & VT_GRAFX) != 0;
+ vsx->vt_status &= ~VT_GRAFX;
+ if(haschanged && vsx == vsp)
+ switch_screen(current_video_screen, 1, 0);
+ return 0;
+
+ case KD_GRAPHICS:
+ /* xxx It might be a good idea to require that
+ the vt be in process controlled mode here,
+ and that the calling process is the owner */
+ haschanged = (vsx->vt_status & VT_GRAFX) == 0;
+ vsx->vt_status |= VT_GRAFX;
+ if(haschanged && vsx == vsp)
+ switch_screen(current_video_screen, 0, 1);
+ return 0;
+
+ }
+ return EINVAL; /* end case KDSETMODE */
+ }
+
+ case KDSETRAD:
+ /* set keyboard repeat and delay */
+ return kbdioctl(dev, KBDSTPMAT, data, flag);
+
+ case KDGKBMODE:
+ *(int *)data = vsx->kbd_state;
+ return 0;
+
+ case KDSKBMODE:
+ mode = *(int *)data;
+ switch(mode)
+ {
+ case K_RAW:
+ case K_XLATE:
+ if(vsx->kbd_state != mode)
+ {
+ if(vsx == vsp)
+ kbd_setmode(mode);
+ vsx->kbd_state = mode;
+ }
+ return 0;
+ }
+ return EINVAL; /* end KDSKBMODE */
+
+ case KDMKTONE:
+ /* ring the speaker */
+ if(data)
+ {
+ int duration = *(int *)data >> 16;
+ int pitch = *(int *)data & 0xffff;
+
+#if PCVT_NETBSD
+ if(pitch != 0)
+ {
+ sysbeep(PCVT_SYSBEEPF / pitch,
+ duration * hz / 1000);
+ }
+#else /* PCVT_NETBSD */
+ sysbeep(pitch, duration * hz / 3000);
+#endif /* PCVT_NETBSD */
+
+ }
+ else
+ {
+ sysbeep(PCVT_SYSBEEPF / 1493, hz / 4);
+ }
+ return 0;
+
+ case KDSETLED:
+ /* set kbd LED status */
+ /* unfortunately, the LED definitions between pcvt and */
+ /* USL differ some way :-( */
+ i = *(int *)data;
+ j = (i & LED_CAP? KBD_CAPSLOCK: 0)
+ + (i & LED_NUM? KBD_NUMLOCK: 0)
+ + (i & LED_SCR? KBD_SCROLLLOCK: 0);
+ return kbdioctl(dev, KBDSLOCK, (caddr_t)&j, flag);
+
+ case KDGETLED:
+ /* get kbd LED status */
+ if((error = kbdioctl(dev, KBDGLOCK, (caddr_t)&j, flag)))
+ return error;
+ i = (j & KBD_CAPSLOCK? LED_CAP: 0)
+ + (j & KBD_NUMLOCK? LED_NUM: 0)
+ + (j & KBD_SCROLLLOCK? LED_SCR: 0);
+ *(int *)data = i;
+ return 0;
+
+ case GIO_KEYMAP:
+ get_usl_keymap((keymap_t *)data);
+ return 0;
+ } /* end case cmd */
+
+ return -1; /* inappropriate usl_vt_compat ioctl */
+}
+
+#endif /* NVT > 0 */
+
+/* ------------------------- E O F ------------------------------------------*/
+
diff --git a/sys/arch/i386/isa/pcvt/pcvt_hdr.h b/sys/arch/i386/isa/pcvt/pcvt_hdr.h
new file mode 100644
index 00000000000..86ec7c8e03b
--- /dev/null
+++ b/sys/arch/i386/isa/pcvt/pcvt_hdr.h
@@ -0,0 +1,1462 @@
+/*
+ * Copyright (c) 1992, 1995 Hellmuth Michaelis and Joerg Wunsch.
+ *
+ * Copyright (c) 1992, 1993 Brian Dunford-Shore.
+ *
+ * All rights reserved.
+ *
+ * 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
+ * Hellmuth Michaelis, Brian Dunford-Shore and Joerg Wunsch.
+ * 4. The name authors may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``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 AUTHORS 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.
+ *
+ *
+ * @(#)pcvt_hdr.h, 3.32, Last Edit-Date: [Tue Oct 3 11:19:48 1995]
+ *
+ */
+
+/*---------------------------------------------------------------------------
+ *
+ * pcvt_hdr.h VT220 Driver Global Include File
+ * ------------------------------------------------
+ * -hm ------------ Release 3.00 --------------
+ * -hm integrating NetBSD-current patches
+ * -hm integrating patches from Thomas Gellekum
+ * -hm moving vt_selattr() inline into this file
+ * -hm Michael's keyboard fifo diffs
+ * -hm documenting some #ifdef's ...
+ * -hm Joerg's patches for FreeBSD's ttymalloc
+ * -jw introduced kbd_emulate_pc() if scanset > 1
+ * -hm moved user configurable items to pcvt_conf.h
+ * -hm applying Joerg's patches for FreeBSD 2.0
+ * -hm patch from Onno & Martin for NetBSD-current (post 1.0)
+ * -hm some adjustments for NetBSD 1.0
+ * -hm patch from Joerg fixing FreeBSD 2.0 support
+ * -hm patch from Onno/John for NetBSD-current
+ * -hm applying patch from Joerg fixing Crtat bug
+ * -hm removed PCVT_FAKE_SYSCONS10
+ * -hm added pcstop (patch from Onno)
+ * -hm multiple X server bugfixes from Lon Willett
+ * -hm patch from Joerg for FreeBSD pre-2.1
+ * -jw adding more support for FreeBSD pre-2.1
+ * -hm patches from Michael for NetBSD-current (Apr/21/95) support
+ * -hm several NetBSD-current patches from John Kohl
+ * -hm ---------------- Release 3.30 -----------------------
+ * -hm patch from Thomas Gellekum to support C1 controls
+ * -hm patch from Frank van der Linden for keyboard state per VT
+ * -hm ---------------- Release 3.32 -----------------------
+ *
+ *---------------------------------------------------------------------------*/
+
+#define PCVT_REL "3.32" /* driver attach announcement */
+ /* see also: pcvt_ioctl.h */
+
+#if PCVT_FREEBSD >= 200
+
+#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 <sys/malloc.h>
+#include <sys/time.h>
+
+#else /* ! PCVT_FREEBSD >= 200 */
+
+#include "param.h"
+#include "conf.h"
+#include "ioctl.h"
+#include "proc.h"
+#include "user.h"
+#include "tty.h"
+#include "uio.h"
+#include "callout.h"
+#include "systm.h"
+#include "kernel.h"
+#include "syslog.h"
+#include "malloc.h"
+#include "time.h"
+
+#endif /* PCVT_FREEBSD >= 200 */
+
+#include "pcvt_conf.h"
+
+#if PCVT_NETBSD > 9
+#include "device.h"
+#endif
+
+#if PCVT_NETBSD > 9
+#if PCVT_NETBSD > 101
+#include "i386/isa/isa_machdep.h"
+#include "dev/isa/isavar.h"
+#else
+#include "i386/isa/isavar.h"
+#endif
+
+#include "i386/cpufunc.h"
+#elif PCVT_FREEBSD >= 200
+#include <i386/isa/isa_device.h>
+#else
+#include "i386/isa/isa_device.h"
+#endif
+
+#if PCVT_FREEBSD >= 200
+#include <i386/isa/icu.h>
+#else
+#include "i386/isa/icu.h"
+#endif
+
+#if PCVT_NETBSD > 100
+#if PCVT_NETBSD > 101
+#include "dev/isa/isareg.h"
+#else
+#include "i386/isa/isareg.h"
+#endif
+#elif PCVT_FREEBSD >= 200
+#include <i386/isa/isa.h>
+#else
+#include "i386/isa/isa.h"
+#endif
+
+#if PCVT_NETBSD > 9
+#include "dev/cons.h"
+#if PCVT_NETBSD > 100
+#include "dev/ic/mc146818reg.h"
+#include "i386/isa/nvram.h"
+#endif
+#elif PCVT_FREEBSD >= 200
+#include <i386/i386/cons.h>
+#else
+#include "i386/i386/cons.h"
+#endif
+
+#if PCVT_NETBSD <= 9
+#if PCVT_FREEBSD >= 200
+#include <machine/psl.h>
+#include <machine/frame.h>
+#else /* ! PCVT_FREEBSD >= 200 */
+#include "machine/psl.h"
+#include "machine/frame.h"
+#endif /* PCVT_FREEBSD >= 200 */
+#endif /* PCVT_NETBSD <= 9 */
+
+#if PCVT_FREEBSD >= 200
+#include <machine/stdarg.h>
+#else
+#include "machine/stdarg.h"
+#endif
+
+#if PCVT_NETBSD > 9
+#include "pcvt_ioctl.h"
+#elif PCVT_FREEBSD >= 200
+#include <machine/pcvt_ioctl.h>
+#else
+#include "machine/pcvt_ioctl.h"
+#endif
+
+#if PCVT_FREEBSD >= 200
+#include <machine/pc/display.h>
+#if PCVT_FREEBSD > 200
+#include <machine/clock.h>
+#include <machine/md_var.h>
+#endif
+#include <vm/vm_kern.h>
+#else /* PCVT_FREEBSD >= 200 */
+#include "machine/pc/display.h"
+#include "vm/vm_kern.h"
+#endif /* PCVT_FREEBSD >= 200 */
+
+#if PCVT_FREEBSD > 205
+#include <sys/devconf.h>
+#endif
+
+/* setup irq disable function to use */
+
+#if !(PCVT_SLOW_INTERRUPT) && (PCVT_NETBSD > 9)
+# define PCVT_DISABLE_INTR() disable_intr()
+# define PCVT_ENABLE_INTR() enable_intr()
+# undef PCVT_SLOW_INTERRUPT
+#else
+# define PCVT_DISABLE_INTR() s = spltty()
+# define PCVT_ENABLE_INTR() splx(s)
+# undef PCVT_SLOW_INTERRUPT
+# define PCVT_SLOW_INTERRUPT 1
+#endif
+
+/* perform option consistency checks */
+
+#if defined PCVT_FREEBSD && PCVT_FREEBSD == 1
+# undef PCVT_FREEBSD
+# define PCVT_FREEBSD 102 /* assume 1.0 release */
+#endif
+
+#if defined PCVT_NETBSD && PCVT_NETBSD == 1
+#undef PCVT_NETBSD
+#define PCVT_NETBSD 9 /* assume 0.9 release for now */
+#endif
+
+#if PCVT_FREEBSD + PCVT_NETBSD == 0
+# error "pcvt_hdr.h: You MUST define one of PCVT_{NET,FREE}BSD \
+in the config file"
+#elif (PCVT_FREEBSD && PCVT_NETBSD)
+# error "pcvt_hdr.h: You CAN only define *one* of PCVT_{NET,FREE}BSD \
+in the config file"
+#endif
+
+#ifdef XSERVER
+
+/* PCVT_NULLCHARS is mandatory for X server */
+#undef PCVT_NULLCHARS
+#define PCVT_NULLCHARS 1
+
+/* PCVT_BACKUP_FONTS is mandatory for XSERVER */
+#undef PCVT_BACKUP_FONTS
+#define PCVT_BACKUP_FONTS 1
+
+#endif /* XSERVER */
+
+/* PCVT_SCREENSAVER is mandatory for PCVT_PRETTYSCRNS */
+#if PCVT_PRETTYSCRNS && !PCVT_SCREENSAVER
+#undef PCVT_SCREENSAVER
+#define PCVT_SCREENSAVER 1
+#endif
+
+/* get the inline inb/outb back again ... */
+
+#if PCVT_NETBSD
+#if PCVT_NETBSD == 9
+#include "machine/cpufunc.h" /* NetBSD 0.9 [...and earlier -currents] */
+#else
+#include "machine/pio.h" /* recent NetBSD -currents */
+#define NEW_AVERUNNABLE /* averunnable changes for younger currents */
+#endif /* PCVT_NETBSD == 9 */
+#endif /* PCVT_NETBSD */
+
+#if PCVT_FREEBSD >= 200
+#define NEW_AVERUNNABLE /* new averunnable changes for FreeBSD 2.0 */
+#endif
+
+#if PCVT_SCANSET !=1 && PCVT_SCANSET !=2
+#error "Supported keyboard scancode sets are 1 and 2 only (for now)!!!"
+#endif
+
+/*---------------------------------------------------------------------------*
+ * Keyboard and Keyboard Controller
+ *---------------------------------------------------------------------------*/
+
+#define CONTROLLER_CTRL 0x64 /* W - command, R - status */
+#define CONTROLLER_DATA 0x60 /* R/W - data */
+
+/* commands to control the CONTROLLER (8042) on the mainboard */
+
+#define CONTR_READ 0x20 /* read command byte from controller */
+#define CONTR_WRITE 0x60 /* write command to controller, see below */
+#define CONTR_SELFTEST 0xaa /* controller selftest, returns 0x55 when ok */
+#define CONTR_IFTEST 0xab /* interface selftest */
+#define CONTR_KBDISABL 0xad /* disable keyboard */
+#define CONTR_KBENABL 0xae /* enable keyboard */
+
+/* command byte for writing to CONTROLLER (8042) via CONTR_WRITE */
+
+#define COMMAND_RES7 0x80 /* bit 7, reserved, always write a ZERO ! */
+#define COMMAND_PCSCAN 0x40 /* bit 6, 1 = convert to pc scan codes */
+#define COMMAND_RES5 0x20 /* bit 5, perhaps (!) use 9bit frame
+ * instead of 11 */
+#define COMMAND_DISABL 0x10 /* bit 4, 1 = disable keyboard */
+#define COMMAND_INHOVR 0x08 /* bit 3, 1 = override security lock inhibit */
+#define COMMAND_SYSFLG 0x04 /* bit 2, value stored as "system flag" */
+#define COMMAND_RES2 0x02 /* bit 1, reserved, always write a ZERO ! */
+#define COMMAND_IRQEN 0x01 /* bit 0, 1 = enable output buffer full
+ * interrupt */
+
+/* status from CONTROLLER (8042) on the mainboard */
+
+#define STATUS_PARITY 0x80 /* bit 7, 1 = parity error on last byte */
+#define STATUS_RXTIMO 0x40 /* bit 6, 1 = receive timeout error occured */
+#define STATUS_TXTIMO 0x20 /* bit 5, 1 = transmit timeout error occured */
+#define STATUS_ENABLE 0x10 /* bit 4, 1 = keyboard unlocked */
+#define STATUS_WHAT 0x08 /* bit 3, 1 = wrote cmd to 0x64, 0 = wrote
+ * data to 0x60 */
+#define STATUS_SYSFLG 0x04 /* bit 2, value stored as "system flag" */
+#define STATUS_INPBF 0x02 /* bit 1, 1 = input buffer full (to 8042) */
+#define STATUS_OUTPBF 0x01 /* bit 0, 1 = output buffer full (from 8042) */
+
+/* commands to the KEYBOARD (via the 8042 controller on mainboard..) */
+
+#define KEYB_C_RESET 0xff /* reset keyboard to power-on status */
+#define KEYB_C_RESEND 0xfe /* resend last byte in case of error */
+#define KEYB_C_TYPEM 0xf3 /* set keyboard typematic rate/delay */
+#define KEYB_C_ID 0xf2 /* return keyboard id */
+#define KEYB_C_ECHO 0xee /* diagnostic, echo 0xee */
+#define KEYB_C_LEDS 0xed /* set/reset numlock,capslock & scroll lock */
+
+/* responses from the KEYBOARD (via the 8042 controller on mainboard..) */
+
+#define KEYB_R_OVERRUN0 0x00 /* keyboard buffer overflow */
+#define KEYB_R_SELFOK 0xaa /* keyboard selftest ok after KEYB_C_RESET */
+#define KEYB_R_EXT0 0xe0 /* keyboard extended scancode prefix 1 */
+#define KEYB_R_EXT1 0xe1 /* keyboard extended scancode prefix 2 */
+#define KEYB_R_ECHO 0xee /* keyboard response to KEYB_C_ECHO */
+#define KEYB_R_BREAKPFX 0xf0 /* break code prefix for set 2 and 3 */
+#define KEYB_R_ACK 0xfa /* acknowledge after a command has rx'd */
+#define KEYB_R_SELFBAD 0xfc /*keyboard selftest FAILED after KEYB_C_RESET*/
+#define KEYB_R_DIAGBAD 0xfd /* keyboard self diagnostic failure */
+#define KEYB_R_RESEND 0xfe /* keyboard wants command resent or illegal
+ * command rx'd */
+#define KEYB_R_OVERRUN1 0xff /* keyboard buffer overflow */
+
+#define KEYB_R_MF2ID1 0xab /* MF II Keyboard id-byte #1 */
+#define KEYB_R_MF2ID2 0x41 /* MF II Keyboard id-byte #2 */
+#define KEYB_R_MF2ID2HP 0x83 /* MF II Keyboard id-byte #2 from HP keybd's */
+
+/* internal Keyboard Type */
+
+#define KB_UNKNOWN 0 /* unknown keyboard type */
+#define KB_AT 1 /* AT (84 keys) Keyboard */
+#define KB_MFII 2 /* MF II (101/102 keys) Keyboard */
+
+/*---------------------------------------------------------------------------*
+ * CMOS ram access to get the "Equipment Byte"
+ *---------------------------------------------------------------------------*/
+
+#if PCVT_NETBSD > 100
+#define EQ_EGAVGA NVRAM_EQUIPMENT_EGAVGA
+#define EQ_40COLOR NVRAM_EQUIPMENT_COLOR40
+#define EQ_80COLOR NVRAM_EQUIPMENT_COLOR80
+#define EQ_80MONO NVRAM_EQUIPMENT_MONO80
+#else
+#define RTC_EQUIPMENT 0x14 /* equipment byte in cmos ram */
+#define EQ_EGAVGA 0 /* reserved (= ega/vga) */
+#define EQ_40COLOR 1 /* display = 40 col color */
+#define EQ_80COLOR 2 /* display = 80 col color */
+#define EQ_80MONO 3 /* display = 80 col mono */
+#endif
+
+/*---------------------------------------------------------------------------*
+ * VT220 -> internal color conversion table fields
+ *---------------------------------------------------------------------------*/
+
+#define VT_NORMAL 0x00 /* no attributes at all */
+#define VT_BOLD 0x01 /* bold attribute */
+#define VT_UNDER 0x02 /* underline attribute */
+#define VT_BLINK 0x04 /* blink attribute */
+#define VT_INVERSE 0x08 /* inverse attribute */
+
+/*---------------------------------------------------------------------------*
+ * VGA GENERAL/EXTERNAL Registers (3BA or 3DA and 3CA, 3C2, 3CC)
+ *---------------------------------------------------------------------------*/
+
+#define GN_MISCOUTR 0x3CC /* misc output register read */
+#define GN_MISCOUTW 0x3C2 /* misc output register write */
+#define GN_INPSTAT0 0x3C2 /* input status 0, r/o */
+#define GN_INPSTAT1M 0x3BA /* input status 1, r/o, mono */
+#define GN_INPSTAT1C 0x3DA /* input status 1, r/o, color */
+#define GN_FEATR 0x3CA /* feature control, read */
+#define GN_FEATWM 0x3BA /* feature control, write, mono */
+#define GN_FEATWC 0x3DA /* feature control, write, color */
+#define GN_VSUBSYS 0x3C3 /* video subsystem register r/w */
+#define GN_DMCNTLM 0x3B8 /* display mode control, r/w, mono */
+#define GN_DMCNTLC 0x3D8 /* display mode control, r/w, color */
+#define GN_COLORSEL 0x3D9 /* color select register, w/o */
+#define GN_HERCOMPAT 0x3BF /* Hercules compatibility reg, w/o */
+
+/*---------------------------------------------------------------------------*
+ * VGA CRTC Registers (3B4 and 3B5 or 3D4 and 3D5)
+ *---------------------------------------------------------------------------*/
+
+#define MONO_BASE 0x3B4 /* crtc index register address mono */
+#define CGA_BASE 0x3D4 /* crtc index register address color */
+
+#define CRTC_ADDR 0x00 /* index register */
+
+#define CRTC_HTOTAL 0x00 /* horizontal total */
+#define CRTC_HDISPLE 0x01 /* horizontal display end */
+#define CRTC_HBLANKS 0x02 /* horizontal blank start */
+#define CRTC_HBLANKE 0x03 /* horizontal blank end */
+#define CRTC_HSYNCS 0x04 /* horizontal sync start */
+#define CRTC_HSYNCE 0x05 /* horizontal sync end */
+#define CRTC_VTOTAL 0x06 /* vertical total */
+#define CRTC_OVERFLL 0x07 /* overflow low */
+#define CRTC_IROWADDR 0x08 /* inital row address */
+#define CRTC_MAXROW 0x09 /* maximum row address */
+#define CRTC_CURSTART 0x0A /* cursor start row address */
+#define CURSOR_ON_BIT 0x20 /* cursor on/off on mda/cga/vga */
+#define CRTC_CUREND 0x0B /* cursor end row address */
+#define CRTC_STARTADRH 0x0C /* linear start address mid */
+#define CRTC_STARTADRL 0x0D /* linear start address low */
+#define CRTC_CURSORH 0x0E /* cursor address mid */
+#define CRTC_CURSORL 0x0F /* cursor address low */
+#define CRTC_VSYNCS 0x10 /* vertical sync start */
+#define CRTC_VSYNCE 0x11 /* vertical sync end */
+#define CRTC_VDE 0x12 /* vertical display end */
+#define CRTC_OFFSET 0x13 /* row offset */
+#define CRTC_ULOC 0x14 /* underline row address */
+#define CRTC_VBSTART 0x15 /* vertical blank start */
+#define CRTC_VBEND 0x16 /* vertical blank end */
+#define CRTC_MODE 0x17 /* CRTC mode register */
+#define CRTC_SPLITL 0x18 /* split screen start low */
+
+/* start of ET4000 extensions */
+
+#define CRTC_RASCAS 0x32 /* ras/cas configuration */
+#define CRTC_EXTSTART 0x33 /* extended start address */
+#define CRTC_COMPAT6845 0x34 /* 6845 comatibility control */
+#define CRTC_OVFLHIGH 0x35 /* overflow high */
+#define CRTC_SYSCONF1 0x36 /* video system configuration 1 */
+#define CRTC_SYSCONF2 0x36 /* video system configuration 2 */
+
+/* start of WD/Paradise extensions */
+
+#define CRTC_PR10 0x29 /* r/w unlocking */
+#define CRTC_PR11 0x2A /* ega switches */
+#define CRTC_PR12 0x2B /* scratch pad */
+#define CRTC_PR13 0x2C /* interlace h/2 start */
+#define CRTC_PR14 0x2D /* interlace h/2 end */
+#define CRTC_PR15 0x2E /* misc control #1 */
+#define CRTC_PR16 0x2F /* misc control #2 */
+#define CRTC_PR17 0x30 /* misc control #3 */
+ /* 0x31 .. 0x3f reserved */
+/* Video 7 */
+
+#define CRTC_V7ID 0x1f /* identification register */
+
+/* Trident */
+
+#define CRTC_MTEST 0x1e /* module test register */
+#define CRTC_SOFTPROG 0x1f /* software programming */
+#define CRTC_LATCHRDB 0x22 /* latch read back register */
+#define CRTC_ATTRSRDB 0x24 /* attribute state read back register*/
+#define CRTC_ATTRIRDB 0x26 /* attribute index read back register*/
+#define CRTC_HOSTAR 0x27 /* high order start address register */
+
+/*---------------------------------------------------------------------------*
+ * VGA TIMING & SEQUENCER Registers (3C4 and 3C5)
+ *---------------------------------------------------------------------------*/
+
+#define TS_INDEX 0x3C4 /* index register */
+#define TS_DATA 0x3C5 /* data register */
+
+#define TS_SYNCRESET 0x00 /* synchronous reset */
+#define TS_MODE 0x01 /* ts mode register */
+#define TS_WRPLMASK 0x02 /* write plane mask */
+#define TS_FONTSEL 0x03 /* font select register */
+#define TS_MEMMODE 0x04 /* memory mode register */
+
+/* ET4000 only */
+
+#define TS_RESERVED 0x05 /* undef, reserved */
+#define TS_STATECNTL 0x06 /* state control register */
+#define TS_AUXMODE 0x07 /* auxiliary mode control */
+
+/* WD/Paradise only */
+
+#define TS_UNLOCKSEQ 0x06 /* PR20 - unlock sequencer register */
+#define TS_DISCFSTAT 0x07 /* PR21 - display config status */
+#define TS_MEMFIFOCTL 0x10 /* PR30 - memory i/f & fifo control */
+#define TS_SYSIFCNTL 0x11 /* PR31 - system interface control */
+#define TS_MISC4 0x12 /* PR32 - misc control #4 */
+
+/* Video 7 */
+
+#define TS_EXTCNTL 0x06 /* extensions control */
+#define TS_CLRVDISP 0x30 /* clear vertical display 0x30-0x3f */
+#define TS_V7CHIPREV 0x8e /* chipset revision 0x8e-0x8f */
+#define TS_SWBANK 0xe8 /* single/write bank register, rev 5+*/
+#define TS_RDBANK 0xe8 /* read bank register, rev 4+ */
+#define TS_MISCCNTL 0xe8 /* misc control register, rev 4+ */
+#define TS_SWSTROBE 0xea /* switch strobe */
+#define TS_MWRCNTL 0xf3 /* masked write control */
+#define TS_MWRMVRAM 0xf4 /* masked write mask VRAM only */
+#define TS_BANKSEL 0xf6 /* bank select */
+#define TS_SWREADB 0xf7 /* switch readback */
+#define TS_PAGESEL 0xf9 /* page select */
+#define TS_COMPAT 0xfc /* compatibility control */
+#define TS_16BITCTL 0xff /* 16 bit interface control */
+
+/* Trident */
+
+#define TS_HWVERS 0x0b /* hardware version, switch old/new! */
+#define TS_CONFPORT1 0x0c /* config port 1 and 2 - caution! */
+#define TS_MODEC2 0x0d /* old/new mode control 2 - caution! */
+#define TS_MODEC1 0x0e /* old/new mode control 1 - caution! */
+#define TS_PUPM2 0x0f /* power up mode 2 */
+
+/*---------------------------------------------------------------------------*
+ * VGA GRAPHICS DATA CONTROLLER Registers (3CE, 3CF and 3CD)
+ *---------------------------------------------------------------------------*/
+
+#define GDC_SEGSEL 0x3CD /* segment select register */
+#define GDC_INDEX 0x3CE /* index register */
+#define GDC_DATA 0x3CF /* data register */
+
+#define GDC_SETRES 0x00 /* set / reset bits */
+#define GDC_ENSETRES 0x01 /* enable set / reset */
+#define GDC_COLORCOMP 0x02 /* color compare register */
+#define GDC_ROTFUNC 0x03 /* data rotate / function select */
+#define GDC_RDPLANESEL 0x04 /* read plane select */
+#define GDC_MODE 0x05 /* gdc mode register */
+#define GDC_MISC 0x06 /* gdc misc register */
+#define GDC_COLORCARE 0x07 /* color care register */
+#define GDC_BITMASK 0x08 /* bit mask register */
+
+/* WD/Paradise only */
+
+#define GDC_BANKSWA 0x09 /* PR0A - bank switch a */
+#define GDC_BANKSWB 0x0a /* PR0B - bank switch b */
+#define GDC_MEMSIZE 0x0b /* PR1 memory size */
+#define GDC_VIDEOSEL 0x0c /* PR2 video configuration */
+#define GDC_CRTCNTL 0x0d /* PR3 crt address control */
+#define GDC_VIDEOCNTL 0x0e /* PR4 video control */
+#define GDC_PR5GPLOCK 0x0f /* PR5 gp status and lock */
+
+/* Video 7 */
+
+#define GDC_DATALATCH 0x22 /* gdc data latch */
+
+/*---------------------------------------------------------------------------*
+ * VGA ATTRIBUTE CONTROLLER Registers (3C0 and 3C1)
+ *---------------------------------------------------------------------------*/
+
+#define ATC_INDEX 0x3C0 /* index register AND */
+#define ATC_DATAW 0x3C0 /* data write !!! */
+#define ATC_DATAR 0x3C1 /* data read */
+
+#define ATC_ACCESS 0x20 /* access bit in ATC index register */
+
+#define ATC_PALETTE0 0x00 /* color palette register 0 */
+#define ATC_PALETTE1 0x01 /* color palette register 1 */
+#define ATC_PALETTE2 0x02 /* color palette register 2 */
+#define ATC_PALETTE3 0x03 /* color palette register 3 */
+#define ATC_PALETTE4 0x04 /* color palette register 4 */
+#define ATC_PALETTE5 0x05 /* color palette register 5 */
+#define ATC_PALETTE6 0x06 /* color palette register 6 */
+#define ATC_PALETTE7 0x07 /* color palette register 7 */
+#define ATC_PALETTE8 0x08 /* color palette register 8 */
+#define ATC_PALETTE9 0x09 /* color palette register 9 */
+#define ATC_PALETTEA 0x0A /* color palette register 10 */
+#define ATC_PALETTEB 0x0B /* color palette register 11 */
+#define ATC_PALETTEC 0x0C /* color palette register 12 */
+#define ATC_PALETTED 0x0D /* color palette register 13 */
+#define ATC_PALETTEE 0x0E /* color palette register 14 */
+#define ATC_PALETTEF 0x0F /* color palette register 15 */
+#define ATC_MODE 0x10 /* atc mode register */
+#define ATC_OVERSCAN 0x11 /* overscan register */
+#define ATC_COLPLEN 0x12 /* color plane enable register */
+#define ATC_HORPIXPAN 0x13 /* horizontal pixel panning */
+#define ATC_COLRESET 0x14 /* color reset */
+#define ATC_MISC 0x16 /* misc register (ET3000/ET4000) */
+
+/*---------------------------------------------------------------------------*
+ * VGA palette handling (output DAC palette)
+ *---------------------------------------------------------------------------*/
+
+#define VGA_DAC 0x3C6 /* vga dac address */
+#define VGA_PMSK 0x3F /* palette mask, 64 distinct values */
+#define NVGAPEL 256 /* number of palette entries */
+
+/*---------------------------------------------------------------------------*
+ * function key labels
+ *---------------------------------------------------------------------------*/
+
+#define LABEL_LEN 9 /* length of one label */
+#define LABEL_MID 8 /* mid-part (row/col) */
+
+#define LABEL_ROWH ((4*LABEL_LEN)+1)
+#define LABEL_ROWL ((4*LABEL_LEN)+2)
+#define LABEL_COLU ((4*LABEL_LEN)+4)
+#define LABEL_COLH ((4*LABEL_LEN)+5)
+#define LABEL_COLL ((4*LABEL_LEN)+6)
+
+/* tab setting */
+
+#define MAXTAB 132 /* no of possible tab stops */
+
+/* escape detection state machine */
+
+#define STATE_INIT 0 /* normal */
+#define STATE_ESC 1 /* got ESC */
+#define STATE_BLANK 2 /* got ESC space*/
+#define STATE_HASH 3 /* got ESC # */
+#define STATE_BROPN 4 /* got ESC ( */
+#define STATE_BRCLO 5 /* got ESC ) */
+#define STATE_CSI 6 /* got ESC [ */
+#define STATE_CSIQM 7 /* got ESC [ ? */
+#define STATE_AMPSND 8 /* got ESC & */
+#define STATE_STAR 9 /* got ESC * */
+#define STATE_PLUS 10 /* got ESC + */
+#define STATE_DCS 11 /* got ESC P */
+#define STATE_DQUOTE 12 /* got ESC <Ps> " */
+#define STATE_STR 13 /* got ESC ! */
+#define STATE_MINUS 14 /* got ESC - */
+#define STATE_DOT 15 /* got ESC . */
+#define STATE_SLASH 16 /* got ESC / */
+
+/* for storing escape sequence parameters */
+
+#define MAXPARMS 10 /* maximum no of parms */
+
+/* terminal responses */
+
+#define DA_VT220 "\033[?62;1;2;6;7;8;9c"
+
+/* sub-states for Device Control String processing */
+
+#define DCS_INIT 0 /* got ESC P ... */
+#define DCS_AND_UDK 1 /* got ESC P ... | */
+#define DCS_UDK_DEF 2 /* got ESC P ... | fnckey / */
+#define DCS_UDK_ESC 3 /* got ESC P ... | fnckey / ... ESC */
+#define DCS_DLD_DSCS 4 /* got ESC P ... { */
+#define DCS_DLD_DEF 5 /* got ESC P ... { dscs */
+#define DCS_DLD_ESC 6 /* got ESC P ... { dscs ... / ... ESC */
+
+/* vt220 user defined keys and vt220 downloadable charset */
+
+#define MAXUDKDEF 300 /* max 256 char + 1 '\0' + space.. */
+#define MAXUDKEYS 18 /* plus holes .. */
+#define DSCS_LENGTH 3 /* descriptor length */
+#define MAXSIXEL 8 /* sixels forever ! */
+
+/* sub-states for HP-terminal emulator */
+
+#define SHP_INIT 0
+
+/* esc & f family */
+
+#define SHP_AND_F 1
+#define SHP_AND_Fa 2
+#define SHP_AND_Fak 3
+#define SHP_AND_Fak1 4
+#define SHP_AND_Fakd 5
+#define SHP_AND_FakdL 6
+#define SHP_AND_FakdLl 7
+#define SHP_AND_FakdLls 8
+
+/* esc & j family */
+
+#define SHP_AND_J 9
+#define SHP_AND_JL 10
+
+/* esc & every-thing-else */
+
+#define SHP_AND_ETE 11
+
+/* additionals for function key labels */
+
+#define MAX_LABEL 16
+#define MAX_STRING 80
+#define MAX_STATUS 160
+
+/* MAX values for screen sizes for possible video adaptors */
+
+#define MAXROW_MDACGA 25 /* MDA/CGA can do 25 x 80 max */
+#define MAXCOL_MDACGA 80
+
+#define MAXROW_EGA 43 /* EGA can do 43 x 80 max */
+#define MAXCOL_EGA 80
+
+#define MAXROW_VGA 50 /* VGA can do 50 x 80 max */
+#define MAXCOL_VGA 80
+#define MAXCOL_SVGA 132 /* Super VGA can do 50 x 132 max */
+
+/* switch 80/132 columns */
+
+#define SCR_COL80 80 /* in 80 col mode */
+#define SCR_COL132 132 /* in 132 col mode */
+
+#define MAXDECSCA (((MAXCOL_SVGA * MAXROW_VGA) \
+ / (8 * sizeof(unsigned int)) ) + 1 )
+
+/* screen memory start, monochrome */
+
+#ifndef MONO_BUF
+# if PCVT_FREEBSD && (PCVT_FREEBSD > 102)
+# define MONO_BUF (KERNBASE+0xB0000)
+# else
+# define MONO_BUF 0xfe0B0000 /* NetBSD-current: isa.h */
+# endif
+#endif
+
+/* screen memory start, color */
+
+#ifndef CGA_BUF
+# if PCVT_FREEBSD && (PCVT_FREEBSD > 102)
+# define CGA_BUF (KERNBASE+0xB8000)
+# else
+# define CGA_BUF 0xfe0B8000 /* NetBSD-current: isa.h */
+# endif
+#endif
+
+#define CHR 2 /* bytes per word in screen mem */
+
+#define NVGAFONTS 8 /* number of vga fonts loadable */
+
+#define MAXKEYNUM 127 /* max no of keys in table */
+
+/* charset tables */
+
+#define CSL 0x0000 /* ega/vga charset, lower half of 512 */
+#define CSH 0x0800 /* ega/vga charset, upper half of 512 */
+#define CSSIZE 96 /* (physical) size of a character set */
+
+/* charset designations */
+
+#define D_G0 0 /* designated as G0 */
+#define D_G1 1 /* designated as G1 */
+#define D_G2 2 /* designated as G2 */
+#define D_G3 3 /* designated as G3 */
+#define D_G1_96 4 /* designated as G1 for 96-char charsets */
+#define D_G2_96 5 /* designated as G2 for 96-char charsets */
+#define D_G3_96 6 /* designated as G3 for 96-char charsets */
+
+/* which fkey-labels */
+
+#define SYS_FKL 0 /* in hp mode, sys-fkls are active */
+#define USR_FKL 1 /* in hp mode, user-fkls are active */
+
+/* arguments to async_update() */
+
+#define UPDATE_START 0 /* do cursor update and requeue */
+#define UPDATE_STOP 1 /* suspend cursor updates */
+#define UPDATE_KERN 2 /* do cursor updates for kernel output */
+
+/* variables */
+
+#ifdef EXTERN
+#define WAS_EXTERN
+#else
+#define EXTERN extern
+#endif
+
+EXTERN u_char *more_chars; /* response buffer via kbd */
+EXTERN int char_count; /* response char count */
+EXTERN u_char color; /* color or mono display */
+
+EXTERN u_short kern_attr; /* kernel messages char attributes */
+EXTERN u_short user_attr; /* character attributes */
+
+#if !PCVT_EMU_MOUSE
+
+#if PCVT_NETBSD > 100
+/* nothing */
+#elif PCVT_NETBSD
+EXTERN struct tty *pc_tty[PCVT_NSCREENS];
+#elif !(PCVT_FREEBSD > 110 && PCVT_FREEBSD < 200)
+EXTERN struct tty pccons[PCVT_NSCREENS];
+#else
+EXTERN struct tty *pccons[PCVT_NSCREENS];
+#endif /* PCVT_NETBSD */
+
+#else /* PCVT_EMU_MOUSE */
+
+#if PCVT_NETBSD > 100
+/* nothing */
+#elif PCVT_NETBSD
+EXTERN struct tty *pc_tty[PCVT_NSCREENS + 1];
+#elif !(PCVT_FREEBSD > 110 && PCVT_FREEBSD < 200)
+EXTERN struct tty pccons[PCVT_NSCREENS + 1];
+#else
+EXTERN struct tty *pccons[PCVT_NSCREENS + 1];
+#endif
+
+#endif /* PCVT_EMU_MOUSE */
+
+struct sixels {
+ u_char lower[MAXSIXEL]; /* lower half of char */
+ u_char upper[MAXSIXEL]; /* upper half of char */
+};
+
+struct udkentry {
+ u_char first[MAXUDKEYS]; /* index to first char */
+ u_char length[MAXUDKEYS]; /* length of this entry */
+};
+
+/* VGA palette handling */
+struct rgb {
+ u_char r, g, b; /* red/green/blue, valid 0..VGA_PMSK */
+};
+
+typedef struct video_state {
+ u_short *Crtat; /* video page start addr */
+ u_short *Memory; /* malloc'ed memory start address */
+ struct tty *vs_tty; /* pointer to this screen's tty */
+ u_char maxcol; /* 80 or 132 cols on screen */
+ u_char row, col; /* current cursor position */
+ u_short c_attr; /* current character attributes */
+ u_char vtsgr; /* current sgr configuration */
+ u_short cur_offset; /* current cursor position offset */
+ u_char bell_on; /* flag, bell enabled */
+ u_char sevenbit; /* flag, data path 7 bits wide */
+ u_char dis_fnc; /* flag, display functions enable */
+ u_char transparent; /* flag, mk path tmp trnsprnt for ctls*/
+ u_char C1_ctls; /* flag, process C1 ctls */
+ u_char scrr_beg; /* scrolling region, begin */
+ u_char scrr_len; /* scrolling region, length */
+ u_char scrr_end; /* scrolling region, end */
+ u_char screen_rows; /* screen size, length - status lines */
+ u_char screen_rowsize; /* screen size, length */
+ u_char vga_charset; /* VGA character set value */
+ u_char lastchar; /* flag, vt100 behaviour of last char */
+ u_char lastrow; /* save row, --------- " ----------- */
+ u_char *report_chars; /* ptr, status reports from terminal */
+ u_char report_count; /* count, ----------- " ------------ */
+ u_char state; /* escape sequence state machine */
+ u_char m_awm; /* flag, vt100 mode, auto wrap */
+ u_char m_om; /* flag, vt100 mode, origin mode */
+ u_char sc_flag; /* flag, vt100 mode,saved parms valid */
+ u_char sc_row; /* saved row */
+ u_char sc_col; /* saved col */
+ u_short sc_cur_offset; /* saved cursor addr offset */
+ u_short sc_attr; /* saved attributes */
+ u_char sc_vtsgr; /* saved sgr configuration */
+ u_char sc_awm; /* saved auto wrap mode */
+ u_char sc_om; /* saved origin mode */
+ u_short *sc_G0; /* save G0 ptr */
+ u_short *sc_G1; /* save G1 ptr */
+ u_short *sc_G2; /* save G2 ptr */
+ u_short *sc_G3; /* save G3 ptr */
+ u_short *sc_GL; /* save GL ptr */
+ u_short *sc_GR; /* save GR ptr */
+ u_char sc_sel; /* selective erase state */
+ u_char ufkl[8][17]; /* user fkey-labels */
+ u_char sfkl[8][17]; /* system fkey-labels */
+ u_char labels_on; /* display fkey labels etc. on/off */
+ u_char which_fkl; /* which fkey labels are active */
+ char tab_stops[MAXTAB]; /* table of active tab stops */
+ u_char parmi; /* parameter index */
+ u_char parms[MAXPARMS]; /* parameter array */
+ u_char hp_state; /* hp escape sequence state machine */
+ u_char attribute; /* attribute normal, tx only, local */
+ u_char key; /* fkey label no */
+ u_char l_len; /* buffer length's */
+ u_char s_len;
+ u_char m_len;
+ u_char i; /* help (got short of names ...) */
+ u_char l_buf[MAX_LABEL+1]; /* buffers */
+ u_char s_buf[MAX_STRING+1];
+ u_char m_buf[MAX_STATUS+1];
+ u_char openf; /* we are opened ! */
+ u_char vt_pure_mode; /* no fkey labels, row/col, status */
+ u_char cursor_start; /* Start of cursor */
+ u_char cursor_end; /* End of cursor */
+ u_char cursor_on; /* cursor switched on */
+ u_char ckm; /* true = cursor key normal mode */
+ u_char irm; /* true = insert mode */
+ u_char lnm; /* Line Feed/New Line Mode */
+ u_char dcs_state; /* dcs escape sequence state machine */
+ u_char udk_def[MAXUDKDEF]; /* new definitions for vt220 FKeys */
+ u_char udk_defi; /* index for FKey definitions */
+ u_char udk_deflow; /* low or high nibble in sequence */
+ u_char udk_fnckey; /* function key to assign to */
+ u_char dld_dscs[DSCS_LENGTH]; /* designate soft character set id */
+ u_char dld_dscsi; /* index for dscs */
+ u_char dld_sixel_lower; /* upper/lower sixels of character */
+ u_char dld_sixelli; /* index for lower sixels */
+ u_char dld_sixelui; /* index for upper sixels */
+ struct sixels sixel; /* structure for storing char sixels */
+ u_char selchar; /* true = selective attribute on */
+ u_int decsca[MAXDECSCA]; /* Select Character Attrib bit array */
+ u_short *GL; /* ptr to current GL conversion table*/
+ u_short *GR; /* ptr to current GR conversion table*/
+ u_short *G0; /* ptr to current G0 conversion table*/
+ u_short *G1; /* ptr to current G1 conversion table*/
+ u_char force24; /* force 24 lines in DEC 25 and HP 28*/
+ u_short *G2; /* ptr to current G2 conversion table*/
+ u_short *G3; /* ptr to current G3 conversion table*/
+ u_char dld_id[DSCS_LENGTH+1]; /* soft character set id */
+ u_char which[DSCS_LENGTH+1]; /* which set to designate */
+ u_char whichi; /* index into which .. */
+ u_char ss; /* flag, single shift G2 / G3 -> GL */
+ u_short *Gs; /* ptr to cur. G2/G3 conversion table*/
+ u_char udkbuf[MAXUDKDEF]; /* buffer for user defined keys */
+ struct udkentry ukt; /* index & length for each udk */
+ u_char udkff; /* index into buffer first free entry*/
+ struct rgb palette[NVGAPEL]; /* saved VGA DAC palette */
+ u_char wd132col; /* we are on a wd vga and in 132 col */
+ u_char scroll_lock; /* scroll lock active */
+ u_char caps_lock; /* caps lock active */
+ u_char shift_lock; /* shiftlock flag (virtual ..) */
+ u_char num_lock; /* num lock, true = keypad num mode */
+ u_char abs_write; /* write outside of scroll region */
+ struct vt_mode smode; /* screen mode */
+ struct proc *proc; /* current process */
+ pid_t pid; /* current process id */
+ unsigned vt_status; /* state of the vt */
+ /* becoming active */
+ int kbd_state; /* keyboard raw or translated */
+} video_state;
+
+EXTERN video_state vs[PCVT_NSCREENS]; /* parameters for screens */
+
+/* possible states for video_state.vt_status: */
+
+#define VT_WAIT_REL 1 /* wait till process released vt */
+#define VT_WAIT_ACK 2 /* wait till process ack vt acquire */
+#define VT_GRAFX 4 /* vt runs graphics mode */
+#define VT_WAIT_ACT 8 /* a process is sleeping on this vt */
+
+/* struct describing one slot in the font ram */
+
+struct vga_char_state {
+ int loaded; /* Whether a font is loaded here */
+ int secondloaded; /* an extension characterset was loaded, */
+ /* the number is found here */
+ u_char char_scanlines; /* Scanlines per character */
+ u_char scr_scanlines; /* Low byte of scanlines per screen */
+ int screen_size; /* Screen size in SIZ_YYROWS */
+};
+
+EXTERN struct vga_char_state vgacs[NVGAFONTS]; /* Character set states */
+
+#if PCVT_EMU_MOUSE
+struct mousestat {
+ struct timeval lastmove; /* last time the pointer moved */
+ u_char opened; /* someone would like to use a mouse */
+ u_char minor; /* minor device number */
+ u_char buttons; /* current "buttons" pressed */
+ u_char extendedseen; /* 0xe0 has been seen, do not use next key */
+ u_char breakseen; /* key break has been seen for a sticky btn */
+};
+#endif /* PCVT_EMU_MOUSE */
+
+#ifdef WAS_EXTERN
+
+#if PCVT_NETBSD > 9
+
+#if PCVT_NETBSD > 101
+struct vt_softc {
+ struct device sc_dev;
+ void *sc_ih;
+};
+#endif /* PCVT_NETBSD > 101 */
+
+int pcprobe ();
+void pcattach ();
+
+#if PCVT_NETBSD > 101
+struct cfdriver vtcd = {
+ NULL, "vt", pcprobe, pcattach, DV_TTY, sizeof(struct vt_softc)
+};
+#else /* !PCVT_NETBSD > 101 */
+struct cfdriver vtcd = {
+ NULL, "vt", pcprobe, pcattach, DV_TTY, sizeof(struct device)
+};
+#endif /* PCVT_NETBSD > 101 */
+
+#else /* !PCVT_NETBSD > 9 */
+
+int pcprobe ( struct isa_device *dev );
+int pcattach ( struct isa_device *dev );
+
+struct isa_driver vtdriver = { /* driver routines */
+ pcprobe, pcattach, "vt",
+};
+
+#endif /* PCVT_NETBSD > 9 */
+
+u_char fgansitopc[] = { /* foreground ANSI color -> pc */
+ FG_BLACK, FG_RED, FG_GREEN, FG_BROWN, FG_BLUE,
+ FG_MAGENTA, FG_CYAN, FG_LIGHTGREY
+};
+
+u_char bgansitopc[] = { /* background ANSI color -> pc */
+ BG_BLACK, BG_RED, BG_GREEN, BG_BROWN, BG_BLUE,
+ BG_MAGENTA, BG_CYAN, BG_LIGHTGREY
+};
+
+#if !PCVT_NETBSD
+u_short *Crtat = (u_short *)MONO_BUF; /* screen start address */
+#if !(PCVT_FREEBSD > 110 && PCVT_FREEBSD < 200)
+struct tty *pcconsp = &pccons[0]; /* ptr to current device */
+#else /* PCVT_FREEBSD > 110 */
+struct tty *pcconsp;
+#endif /* !(PCVT_FREEBSD > 110) */
+#else
+struct tty *pcconsp; /* ptr to current device, see pcattach() */
+
+#if PCVT_NETBSD > 101
+u_short *Crtat; /* screen start address */
+#endif /* PCVT_NETBSD > 101 */
+
+#endif /* PCVT_NETBSD */
+
+#if PCVT_EMU_MOUSE
+struct mousestat mouse = {0};
+struct mousedefs mousedef = {0x3b, 0x3c, 0x3d, 0, 250000};
+#endif /* PCVT_EMU_MOUSE */ /* F1, F2, F3, false, 0.25 sec */
+
+video_state *vsp = &vs[0]; /* ptr to current screen parms */
+
+int vt_switch_pending = 0; /* if > 0, a vt switch is */
+ /* of the old vt + 1 */
+u_int addr_6845 = MONO_BASE; /* crtc base addr */
+u_char do_initialization = 1; /* we have to init ourselves */
+u_char pcvt_is_console = 0; /* until we know it */
+u_char shift_down = 0; /* shift key down flag */
+u_char ctrl_down = 0; /* ctrl key down flag */
+u_char meta_down = 0; /* alt key down flag */
+u_char altgr_down = 0; /* altgr key down flag */
+u_char kbrepflag = 1; /* key repeat flag */
+u_char totalscreens = 1; /* screens available */
+u_char current_video_screen = 0; /* displayed screen no */
+u_char adaptor_type = UNKNOWN_ADAPTOR;/* adaptor type */
+u_char vga_type = VGA_UNKNOWN; /* vga chipset */
+u_char can_do_132col = 0; /* vga chipset can 132 cols */
+u_char vga_family = 0; /* vga manufacturer */
+u_char totalfonts = 0; /* fonts available */
+u_char chargen_access = 0; /* synchronize access */
+u_char keyboard_type = KB_UNKNOWN; /* type of keyboard */
+u_char keyboard_is_initialized = 0; /* for ddb sanity */
+u_char kbd_polling = 0; /* keyboard is being polled */
+
+#if PCVT_SHOWKEYS
+u_char keyboard_show = 0; /* normal display */
+#endif /* PCVT_SHOWKEYS */
+
+u_char cursor_pos_valid = 0; /* sput left a valid position*/
+
+u_char critical_scroll = 0; /* inside scrolling up */
+int switch_page = -1; /* which page to switch to */
+
+#if PCVT_SCREENSAVER
+u_char reset_screen_saver = 1; /* reset the saver next time */
+u_char scrnsv_active = 0; /* active flag */
+#endif /* PCVT_SCREENSAVER */
+
+#if XSERVER || PCVT_SCREENSAVER
+unsigned scrnsv_timeout = 0; /* initially off */
+#endif /* XSERVER || PCVT_SCREENSAVER */
+
+#if PCVT_BACKUP_FONTS
+u_char *saved_charsets[NVGAFONTS] = {0}; /* backup copy of fonts */
+#endif /* PCVT_BACKUP_FONTS */
+
+/*---------------------------------------------------------------------------
+
+ VT220 attributes -> internal emulator attributes conversion tables
+
+ be careful when designing color combinations, because on
+ EGA and VGA displays, bit 3 of the attribute byte is used
+ for characterset switching, and is no longer available for
+ foreground intensity (bold)!
+
+---------------------------------------------------------------------------*/
+
+/* color displays */
+
+u_char sgr_tab_color[16] = {
+/*00*/ (BG_BLACK | FG_LIGHTGREY), /* normal */
+/*01*/ (BG_BLUE | FG_LIGHTGREY), /* bold */
+/*02*/ (BG_BROWN | FG_LIGHTGREY), /* underline */
+/*03*/ (BG_MAGENTA | FG_LIGHTGREY), /* bold+underline */
+/*04*/ (BG_BLACK | FG_LIGHTGREY | FG_BLINK), /* blink */
+/*05*/ (BG_BLUE | FG_LIGHTGREY | FG_BLINK), /* bold+blink */
+/*06*/ (BG_BROWN | FG_LIGHTGREY | FG_BLINK), /* underline+blink */
+/*07*/ (BG_MAGENTA | FG_LIGHTGREY | FG_BLINK), /* bold+underline+blink */
+/*08*/ (BG_LIGHTGREY | FG_BLACK), /* invers */
+/*09*/ (BG_LIGHTGREY | FG_BLUE), /* bold+invers */
+/*10*/ (BG_LIGHTGREY | FG_BROWN), /* underline+invers */
+/*11*/ (BG_LIGHTGREY | FG_MAGENTA), /* bold+underline+invers*/
+/*12*/ (BG_LIGHTGREY | FG_BLACK | FG_BLINK), /* blink+invers */
+/*13*/ (BG_LIGHTGREY | FG_BLUE | FG_BLINK), /* bold+blink+invers */
+/*14*/ (BG_LIGHTGREY | FG_BROWN | FG_BLINK), /* underline+blink+invers*/
+/*15*/ (BG_LIGHTGREY | FG_MAGENTA | FG_BLINK) /*bold+underl+blink+invers*/
+};
+
+/* monochrome displays (VGA version, no intensity) */
+
+u_char sgr_tab_mono[16] = {
+/*00*/ (BG_BLACK | FG_LIGHTGREY), /* normal */
+/*01*/ (BG_BLACK | FG_UNDERLINE), /* bold */
+/*02*/ (BG_BLACK | FG_UNDERLINE), /* underline */
+/*03*/ (BG_BLACK | FG_UNDERLINE), /* bold+underline */
+/*04*/ (BG_BLACK | FG_LIGHTGREY | FG_BLINK), /* blink */
+/*05*/ (BG_BLACK | FG_UNDERLINE | FG_BLINK), /* bold+blink */
+/*06*/ (BG_BLACK | FG_UNDERLINE | FG_BLINK), /* underline+blink */
+/*07*/ (BG_BLACK | FG_UNDERLINE | FG_BLINK), /* bold+underline+blink */
+/*08*/ (BG_LIGHTGREY | FG_BLACK), /* invers */
+/*09*/ (BG_LIGHTGREY | FG_BLACK), /* bold+invers */
+/*10*/ (BG_LIGHTGREY | FG_BLACK), /* underline+invers */
+/*11*/ (BG_LIGHTGREY | FG_BLACK), /* bold+underline+invers*/
+/*12*/ (BG_LIGHTGREY | FG_BLACK | FG_BLINK), /* blink+invers */
+/*13*/ (BG_LIGHTGREY | FG_BLACK | FG_BLINK), /* bold+blink+invers */
+/*14*/ (BG_LIGHTGREY | FG_BLACK | FG_BLINK), /* underline+blink+invers*/
+/*15*/ (BG_LIGHTGREY | FG_BLACK | FG_BLINK) /*bold+underl+blink+invers*/
+};
+
+/* monochrome displays (MDA version, with intensity) */
+
+u_char sgr_tab_imono[16] = {
+/*00*/ (BG_BLACK | FG_LIGHTGREY), /* normal */
+/*01*/ (BG_BLACK | FG_LIGHTGREY | FG_INTENSE), /* bold */
+/*02*/ (BG_BLACK | FG_UNDERLINE), /* underline */
+/*03*/ (BG_BLACK | FG_UNDERLINE | FG_INTENSE), /* bold+underline */
+/*04*/ (BG_BLACK | FG_LIGHTGREY | FG_BLINK), /* blink */
+/*05*/ (BG_BLACK | FG_LIGHTGREY | FG_INTENSE | FG_BLINK), /* bold+blink */
+/*06*/ (BG_BLACK | FG_UNDERLINE | FG_BLINK), /* underline+blink */
+/*07*/ (BG_BLACK | FG_UNDERLINE | FG_BLINK | FG_INTENSE), /* bold+underline+blink */
+/*08*/ (BG_LIGHTGREY | FG_BLACK), /* invers */
+/*09*/ (BG_LIGHTGREY | FG_BLACK | FG_INTENSE), /* bold+invers */
+/*10*/ (BG_LIGHTGREY | FG_BLACK), /* underline+invers */
+/*11*/ (BG_LIGHTGREY | FG_BLACK | FG_INTENSE), /* bold+underline+invers*/
+/*12*/ (BG_LIGHTGREY | FG_BLACK | FG_BLINK), /* blink+invers */
+/*13*/ (BG_LIGHTGREY | FG_BLACK | FG_BLINK | FG_INTENSE),/* bold+blink+invers*/
+/*14*/ (BG_LIGHTGREY | FG_BLACK | FG_BLINK), /* underline+blink+invers*/
+/*15*/ (BG_LIGHTGREY | FG_BLACK | FG_BLINK | FG_INTENSE) /* bold+underl+blink+invers */
+};
+
+#else /* WAS_EXTERN */
+
+extern u_char vga_type;
+extern struct tty *pcconsp;
+extern video_state *vsp;
+
+#if PCVT_EMU_MOUSE
+extern struct mousestat mouse;
+extern struct mousedefs mousedef;
+#endif /* PCVT_EMU_MOUSE */
+
+extern int vt_switch_pending;
+extern u_int addr_6845;
+extern u_short *Crtat;
+extern struct isa_driver vtdriver;
+extern u_char do_initialization;
+extern u_char pcvt_is_console;
+extern u_char bgansitopc[];
+extern u_char fgansitopc[];
+extern u_char shift_down;
+extern u_char ctrl_down;
+extern u_char meta_down;
+extern u_char altgr_down;
+extern u_char kbrepflag;
+extern u_char adaptor_type;
+extern u_char current_video_screen;
+extern u_char totalfonts;
+extern u_char totalscreens;
+extern u_char chargen_access;
+extern u_char keyboard_type;
+extern u_char can_do_132col;
+extern u_char vga_family;
+extern u_char keyboard_is_initialized;
+extern u_char kbd_polling;
+
+#if PCVT_SHOWKEYS
+extern u_char keyboard_show;
+#endif /* PCVT_SHOWKEYS */
+
+u_char cursor_pos_valid;
+
+u_char critical_scroll;
+int switch_page;
+
+#if PCVT_SCREENSAVER
+u_char reset_screen_saver;
+u_char scrnsv_active;
+#endif /* PCVT_SCREENSAVER */
+
+extern u_char sgr_tab_color[];
+extern u_char sgr_tab_mono[];
+extern u_char sgr_tab_imono[];
+
+#if defined(XSERVER) || PCVT_SCREENSAVER
+extern unsigned scrnsv_timeout;
+#endif /* XSERVER || PCVT_SCREENSAVER */
+
+#if PCVT_BACKUP_FONTS
+extern u_char *saved_charsets[NVGAFONTS];
+#endif /* PCVT_BACKUP_FONTS */
+
+#endif /* WAS_EXTERN */
+
+/*
+ * FreeBSD > 1.0.2 cleaned up the kernel definitions (with the aim of
+ * getting ANSI-clean). Since there has been a mixed usage of types like
+ * "dev_t" (actually some short) in prototyped and non-prototyped fasion,
+ * each of those types is declared as "int" within function prototypes
+ * (which is what the compiler would actually promote it to).
+ *
+ * The macros below are used to clarify which type a parameter ought to
+ * be, regardless of its actual promotion to "int".
+ */
+
+
+#define Dev_t int
+#define U_short int
+#define U_char int
+
+/*
+ * In FreeBSD >= 2.0, dev_t has type `unsigned long', so promoting it
+ * doesn't cause any problems in prototypes.
+ */
+
+#if PCVT_FREEBSD >= 200
+#undef Dev_t
+#define Dev_t dev_t
+#endif
+
+/* in FreeBSD > 102 arguments for timeout()/untimeout() are a special type */
+
+#if PCVT_FREEBSD > 102
+#define TIMEOUT_FUNC_T timeout_func_t
+#else
+#define TIMEOUT_FUNC_T void *
+#endif
+
+#if !PCVT_FREEBSD || (PCVT_FREEBSD < 210)
+extern void bcopyb(void *from, void *to, u_int length);
+#endif
+
+#if !PCVT_FREEBSD || (PCVT_FREEBSD < 200)
+extern void fillw(U_short value, void *addr, u_int length);
+#endif
+
+int pcopen ( Dev_t dev, int flag, int mode, struct proc *p );
+int pcclose ( Dev_t dev, int flag, int mode, struct proc *p );
+int pcread ( Dev_t dev, struct uio *uio, int flag );
+int pcwrite ( Dev_t dev, struct uio *uio, int flag );
+int pcioctl ( Dev_t dev, int cmd, caddr_t data, int flag, struct proc *p );
+int pcmmap ( Dev_t dev, int offset, int nprot );
+#if PCVT_FREEBSD > 205
+struct tty *pcdevtotty ( Dev_t dev );
+#endif /* PCVT_FREEBSD > 205 */
+
+#if PCVT_NETBSD
+#if PCVT_NETBSD > 101
+struct tty *
+ pctty ( Dev_t dev );
+int pcintr ( void *arg);
+void pccnprobe ( struct consdev *cp );
+void pccninit ( struct consdev *cp );
+void pccnputc ( Dev_t dev, U_char c );
+#else
+int pcrint ( void );
+int pccnprobe ( struct consdev *cp );
+int pccninit ( struct consdev *cp );
+int pccnputc ( Dev_t dev, U_char c );
+#endif
+int pccngetc ( Dev_t dev );
+#endif /* PCVT_NETBSD */
+
+int pcparam ( struct tty *tp, struct termios *t );
+void pcstart ( struct tty *tp );
+void pcstop ( struct tty *tp, int flag );
+
+#if PCVT_FREEBSD
+/*
+ * In FreeBSD > 2.0.6, driver console functions are declared in i386/cons.h
+ * and some return void, so don't declare them here.
+ */
+#if PCVT_FREEBSD <= 205
+int pccnprobe ( struct consdev *cp );
+int pccninit ( struct consdev *cp );
+int pccngetc ( Dev_t dev );
+int pccncheckc ( Dev_t dev );
+int pccnputc ( Dev_t dev, U_char c );
+#endif
+
+# if PCVT_FREEBSD < 200
+void consinit ( void );
+# endif
+#endif /* PCVT_FREEBSD */
+
+void switch_screen ( int n, int oldgrafx, int newgrafx );
+int usl_vt_ioctl (Dev_t dev,int cmd,caddr_t data,int flag,struct proc *);
+int vt_activate ( int newscreen );
+int vgapage ( int n );
+void get_usl_keymap( keymap_t *map );
+void reset_usl_modes (struct video_state *vsx);
+
+#if PCVT_EMU_MOUSE
+int mouse_ioctl ( Dev_t dev, int cmd, caddr_t data );
+#endif /* PCVT_EMU_MOUSE */
+
+#if PCVT_SCREENSAVER
+void pcvt_scrnsv_reset ( void );
+#endif /* PCVT_SCREENSAVER */
+
+#if PCVT_SCREENSAVER
+void pcvt_set_scrnsv_tmo ( int );
+#endif /* PCVT_SCREENSAVER */
+
+#ifdef XSERVER
+void vga_move_charset ( unsigned n, unsigned char *b, int save_it);
+#endif /* XSERVER */
+
+void async_update ( int arg );
+void clr_parms ( struct video_state *svsp );
+void cons_highlight ( void );
+void cons_normal ( void );
+int egavga_test ( void );
+void fkl_off ( struct video_state *svsp );
+void fkl_on ( struct video_state *svsp );
+struct tty *get_pccons ( Dev_t dev );
+void init_sfkl ( struct video_state *svsp );
+void init_ufkl ( struct video_state *svsp );
+int kbd_cmd ( int val );
+void kbd_code_init ( void );
+void kbd_code_init1 ( void );
+void kbd_setmode(int mode);
+int kbdioctl ( Dev_t dev, int cmd, caddr_t data, int flag );
+void loadchar ( int fontset, int character, int char_scanlines,
+ u_char *char_table );
+void mda2egaorvga ( void );
+void roll_up ( struct video_state *svsp, int n );
+void select_vga_charset ( int vga_charset );
+void set_2ndcharset ( void );
+void set_charset ( struct video_state *svsp, int curvgacs );
+void set_emulation_mode ( struct video_state *svsp, int mode );
+void set_screen_size ( struct video_state *svsp, int size );
+u_char *sgetc ( int noblock );
+void sixel_vga ( struct sixels *charsixel, u_char *charvga );
+void sput ( u_char *s, U_char attrib, int len, int page );
+void sw_cursor ( int onoff );
+void sw_sfkl ( struct video_state *svsp );
+void sw_ufkl ( struct video_state *svsp );
+void swritefkl ( int num, u_char *string, struct video_state *svsp );
+void toggl_awm ( struct video_state *svsp );
+void toggl_bell ( struct video_state *svsp );
+void toggl_columns ( struct video_state *svsp );
+void toggl_dspf ( struct video_state *svsp );
+void toggl_sevenbit ( struct video_state *svsp );
+void update_hp ( struct video_state *svsp );
+void update_led ( void );
+void vga10_vga10 ( u_char *invga, u_char *outvga );
+void vga10_vga14 ( u_char *invga, u_char *outvga );
+void vga10_vga16 ( u_char *invga, u_char *outvga );
+void vga10_vga8 ( u_char *invga, u_char *outvga );
+u_char vga_chipset ( void );
+int vga_col ( struct video_state *svsp, int cols );
+void vga_screen_off ( void );
+void vga_screen_on ( void );
+char *vga_string ( int number );
+int vga_test ( void );
+int vgaioctl ( Dev_t dev, int cmd, caddr_t data, int flag );
+void vgapaletteio ( unsigned idx, struct rgb *val, int writeit );
+void vt_aln ( struct video_state *svsp );
+void vt_clearudk ( struct video_state *svsp );
+void vt_clreol ( struct video_state *svsp );
+void vt_clreos ( struct video_state *svsp );
+void vt_clrtab ( struct video_state *svsp );
+int vt_col ( struct video_state *svsp, int cols );
+void vt_coldmalloc ( void );
+void vt_cub ( struct video_state *svsp );
+void vt_cud ( struct video_state *svsp );
+void vt_cuf ( struct video_state *svsp );
+void vt_curadr ( struct video_state *svsp );
+void vt_cuu ( struct video_state *svsp );
+void vt_da ( struct video_state *svsp );
+void vt_dch ( struct video_state *svsp );
+void vt_dcsentry ( U_char ch, struct video_state *svsp );
+void vt_designate ( struct video_state *svsp);
+void vt_dl ( struct video_state *svsp );
+void vt_dld ( struct video_state *svsp );
+void vt_dsr ( struct video_state *svsp );
+void vt_ech ( struct video_state *svsp );
+void vt_ic ( struct video_state *svsp );
+void vt_il ( struct video_state *svsp );
+void vt_ind ( struct video_state *svsp );
+void vt_initsel ( struct video_state *svsp );
+void vt_keyappl ( struct video_state *svsp );
+void vt_keynum ( struct video_state *svsp );
+void vt_mc ( struct video_state *svsp );
+void vt_nel ( struct video_state *svsp );
+void vt_rc ( struct video_state *svsp );
+void vt_reqtparm ( struct video_state *svsp );
+void vt_reset_ansi ( struct video_state *svsp );
+void vt_reset_dec_priv_qm ( struct video_state *svsp );
+void vt_ri ( struct video_state *svsp );
+void vt_ris ( struct video_state *svsp );
+void vt_sc ( struct video_state *svsp );
+void vt_scl ( struct video_state *svsp );
+void vt_sca ( struct video_state *svsp );
+void vt_sd ( struct video_state *svsp );
+void vt_sed ( struct video_state *svsp );
+void vt_sel ( struct video_state *svsp );
+void vt_set_ansi ( struct video_state *svsp );
+void vt_set_dec_priv_qm ( struct video_state *svsp );
+void vt_sgr ( struct video_state *svsp );
+void vt_stbm ( struct video_state *svsp );
+void vt_str ( struct video_state *svsp );
+void vt_su ( struct video_state *svsp );
+void vt_tst ( struct video_state *svsp );
+void vt_udk ( struct video_state *svsp );
+void toggl_24l ( struct video_state *svsp );
+
+#ifdef PCVT_INCLUDE_VT_SELATTR
+
+#define INT_BITS (sizeof(unsigned int) * 8)
+#define INT_INDEX(n) ((n) / INT_BITS)
+#define BIT_INDEX(n) ((n) % INT_BITS)
+
+/*---------------------------------------------------------------------------*
+ * set selective attribute if appropriate
+ *---------------------------------------------------------------------------*/
+static __inline void vt_selattr(struct video_state *svsp)
+{
+ int i;
+
+ i = (svsp->Crtat + svsp->cur_offset) - svsp->Crtat;
+
+ if(svsp->selchar)
+ svsp->decsca[INT_INDEX(i)] |= (1 << BIT_INDEX(i));
+ else
+ svsp->decsca[INT_INDEX(i)] &= ~(1 << BIT_INDEX(i));
+}
+
+#endif /* PCVT_INCLUDE_VT_SELATTR */
+
+
+/*---------------------------------------------------------------------------*
+ * produce 7 us delay accessing the keyboard controller
+ *---------------------------------------------------------------------------*/
+
+#if PCVT_PORTIO_DELAY
+ /* use multiple dummy accesses to port */
+ /* 0x84 to produce keyboard controller */
+ /* access delays */
+#define PCVT_KBD_DELAY() \
+ { u_char x = inb(0x84); } \
+ { u_char x = inb(0x84); } \
+ { u_char x = inb(0x84); } \
+ { u_char x = inb(0x84); } \
+ { u_char x = inb(0x84); } \
+ { u_char x = inb(0x84); }
+
+#else /* PCVT_PORTIO_DELAY */
+ /* use system supplied delay function for */
+ /* producing delays for accesssing the */
+ /* keyboard controller */
+#if PCVT_NETBSD > 9
+#define PCVT_KBD_DELAY() delay(7)
+#elif PCVT_FREEBSD || (PCVT_NETBSD <= 9)
+#define PCVT_KBD_DELAY() DELAY(7)
+#endif
+#endif /* PCVT_PORTIO_DELAY */
+
+/*---------------------------------- E O F ----------------------------------*/
diff --git a/sys/arch/i386/isa/pcvt/pcvt_ioctl.h b/sys/arch/i386/isa/pcvt/pcvt_ioctl.h
new file mode 100644
index 00000000000..bcef870bed9
--- /dev/null
+++ b/sys/arch/i386/isa/pcvt/pcvt_ioctl.h
@@ -0,0 +1,589 @@
+/*
+ * Copyright (c) 1992, 1995 Hellmuth Michaelis and Joerg Wunsch.
+ *
+ * Copyright (c) 1992, 1993 Brian Dunford-Shore and Holger Veit.
+ *
+ * Copyright (C) 1992, 1993 Soeren Schmidt.
+ *
+ * All rights reserved.
+ *
+ * For the sake of compatibility, portions of this code regarding the
+ * X server interface are taken from Soeren Schmidt's syscons driver.
+ *
+ * This code is derived from software contributed to 386BSD by
+ * Holger Veit.
+ *
+ * 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
+ * Hellmuth Michaelis, Brian Dunford-Shore, Joerg Wunsch, Holger Veit
+ * and Soeren Schmidt.
+ * 4. The name authors may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``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 AUTHORS 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.
+ *
+ *
+ * @(#)ioctl_pcvt.h, 3.32, Last Edit-Date: [Tue Oct 3 11:19:48 1995]
+ *
+ */
+
+/*---------------------------------------------------------------------------
+ *
+ * pcvt_ioctl.h ioctl's for the VT220 video driver 'pcvt'
+ * ---------------------------------------------------------
+ * -hm ------------ Release 3.00 --------------
+ * -hm some new PCVT_xxx (and CONF_xxx) values
+ * -hm version definitions moved to begin of file
+ * -hm removed PCVT_FAKE_SYSCONS10
+ * -hm accept KERNEL or _KERNEL
+ * -hm changed _IOCTL_PCVT_H_ to _MACHINE_PCVT_IOCTL_H_ (bde)
+ * -hm added PCVT_MDAFASTSCROLL
+ * -hm ---------------- Release 3.30 -----------------------
+ * -hm patch to support Cirrus CL-GD62x5 from Martin
+ * -hm removed KBDGLEDS and KBDSLEDS ioctls
+ * -hm ---------------- Release 3.32 -----------------------
+ *
+ *---------------------------------------------------------------------------*/
+
+#ifndef _MACHINE_PCVT_IOCTL_H_
+#define _MACHINE_PCVT_IOCTL_H_
+
+/* pcvt version information for VGAPCVTID ioctl */
+
+#define PCVTIDNAME "pcvt" /* driver id - string */
+#define PCVTIDMAJOR 3 /* driver id - major release */
+#define PCVTIDMINOR 32 /* driver id - minor release */
+
+#if defined(KERNEL) || defined(_KERNEL)
+#include "ioctl.h"
+#else
+#include <sys/ioctl.h>
+#include <sys/types.h>
+#endif
+
+/*---------------------------------------------------------------------------*
+ * IOCTLs for MF II and AT Keyboards
+ *---------------------------------------------------------------------------*/
+
+#define KBDRESET _IO('K', 1) /* reset keyboard / set defaults */
+#define KBDGTPMAT _IOR('K', 2, int) /* get current typematic value */
+#define KBDSTPMAT _IOW('K', 3, int) /* set current typematic value */
+
+/* Typematic Delay Values */
+
+#define KBD_TPD250 0x00 /* 250 ms */
+#define KBD_TPD500 0x20 /* 500 ms */
+#define KBD_TPD750 0x40 /* 750 ms */
+#define KBD_TPD1000 0x60 /* 1000 ms */
+
+/* Typematic Repeat Rate */
+
+#define KBD_TPM300 0x00 /* 30.0 char/second */
+#define KBD_TPM267 0x01 /* 26.7 char/second */
+#define KBD_TPM240 0x02 /* 24.0 char/second */
+#define KBD_TPM218 0x03 /* 21.8 char/second */
+#define KBD_TPM200 0x04 /* 20.0 char/second */
+#define KBD_TPM185 0x05 /* 18.5 char/second */
+#define KBD_TPM171 0x06 /* 17.1 char/second */
+#define KBD_TPM160 0x07 /* 16.0 char/second */
+#define KBD_TPM150 0x08 /* 15.0 char/second */
+#define KBD_TPM133 0x09 /* 13.3 char/second */
+#define KBD_TPM120 0x0A /* 12.0 char/second */
+#define KBD_TPM109 0x0B /* 10.9 char/second */
+#define KBD_TPM100 0x0C /* 10.0 char/second */
+#define KBD_TPM92 0x0D /* 9.2 char/second */
+#define KBD_TPM86 0x0E /* 8.6 char/second */
+#define KBD_TPM80 0x0F /* 8.0 char/second */
+#define KBD_TPM75 0x10 /* 7.5 char/second */
+#define KBD_TPM67 0x11 /* 6.7 char/second */
+#define KBD_TPM60 0x12 /* 6.0 char/second */
+#define KBD_TPM55 0x13 /* 5.5 char/second */
+#define KBD_TPM50 0x14 /* 5.0 char/second */
+#define KBD_TPM46 0x15 /* 4.6 char/second */
+#define KBD_TPM43 0x16 /* 4.3 char/second */
+#define KBD_TPM40 0x17 /* 4.0 char/second */
+#define KBD_TPM37 0x18 /* 3.7 char/second */
+#define KBD_TPM33 0x19 /* 3.3 char/second */
+#define KBD_TPM30 0x1A /* 3.0 char/second */
+#define KBD_TPM27 0x1B /* 2.7 char/second */
+#define KBD_TPM25 0x1C /* 2.5 char/second */
+#define KBD_TPM23 0x1D /* 2.3 char/second */
+#define KBD_TPM21 0x1E /* 2.1 char/second */
+#define KBD_TPM20 0x1F /* 2.0 char/second */
+
+#define KBDGREPSW _IOR('K', 4, int) /* get key repetition switch */
+#define KBDSREPSW _IOW('K', 5, int) /* set key repetition switch */
+#define KBD_REPEATOFF 0
+#define KBD_REPEATON 1
+
+#define KBDGLOCK _IOR('K', 8, int) /* gets SCROLL,NUM,CAPS state */
+#define KBDSLOCK _IOW('K', 9, int) /* sets SCROLL,NUM,CAPS state */
+ /* _and_ sets keyboard LEDs! */
+#define KBD_SCROLLLOCK 0x0001 /* the driver's idea of */
+#define KBD_NUMLOCK 0x0002 /* lock key state */
+#define KBD_CAPSLOCK 0x0004 /* for kbdioctl() */
+
+#define KBDMAXOVLKEYSIZE 15 /* + zero byte */
+
+struct kbd_ovlkey /* complete definition of a key */
+{
+ u_short keynum; /* the key itself */
+ u_short type; /* type of key, see below */
+ u_char subu; /* subtype, ignored on write */
+ char unshift[KBDMAXOVLKEYSIZE+1]; /* emitted string, unshifted */
+ u_char subs; /* subtype, ignored on write */
+ char shift[KBDMAXOVLKEYSIZE+1]; /* emitted string, shifted */
+ u_char subc; /* subtype, ignored on write */
+ char ctrl[KBDMAXOVLKEYSIZE+1]; /* emitted string, control */
+ u_char suba; /* subtype, ignored on write */
+ char altgr[KBDMAXOVLKEYSIZE+1]; /* emitted string, altgr */
+};
+
+/* Max value for keynum field */
+
+#define KBDMAXKEYS 128 /* Max No. of Keys */
+
+/* Values for type field */
+
+#define KBD_NONE 0 /* no function, key is disabled */
+#define KBD_SHIFT 1 /* keyboard shift */
+#define KBD_META 2 /* alternate shift, sets bit8 to ASCII code */
+#define KBD_NUM 3 /* numeric shift, keypad num / appl */
+#define KBD_CTL 4 /* control code generation */
+#define KBD_CAPS 5 /* caps shift - swaps case of letter */
+#define KBD_ASCII 6 /* ascii code generating key */
+#define KBD_SCROLL 7 /* stop output */
+#define KBD_FUNC 8 /* function key */
+#define KBD_KP 9 /* keypad keys */
+#define KBD_BREAK 10 /* ignored */
+#define KBD_ALTGR 11 /* AltGr Translation feature */
+#define KBD_SHFTLOCK 12 /* shiftlock */
+#define KBD_CURSOR 13 /* cursor keys */
+#define KBD_RETURN 14 /* RETURN/ENTER keys */
+
+/* Values for subtype field */
+
+#define KBD_SUBT_STR 0 /* key is bound to a string */
+#define KBD_SUBT_FNC 1 /* key is bound to a function */
+
+
+#define KBD_OVERLOAD 0x8000 /* Key is overloaded, ignored in ioctl */
+#define KBD_MASK (~KBD_OVERLOAD) /* mask for type */
+
+#define KBDGCKEY _IOWR('K',16, struct kbd_ovlkey) /* get current key values */
+#define KBDSCKEY _IOW('K',17, struct kbd_ovlkey) /* set new key assignment values*/
+#define KBDGOKEY _IOWR('K',18, struct kbd_ovlkey) /* get original key assignment values*/
+
+#define KBDRMKEY _IOW('K',19, int) /* remove a key assignment */
+#define KBDDEFAULT _IO('K',20) /* remove all key assignments */
+
+/* mouse emulator definitions */
+
+struct mousedefs {
+ int leftbutton; /* (PC) scan code for "left button" key */
+ int middlebutton; /* (PC) scan code for "mid button" key */
+ int rightbutton; /* (PC) scan code for "right button" key */
+ int stickybuttons; /* if true, the buttons are "sticky" */
+ int acceltime; /* timeout in microseconds to start pointer */
+ /* movement acceleration */
+ /* defaults to: scan(F1), scan(F2), scan(F3), false, 500000 */
+};
+
+#define KBDMOUSEGET _IOR('K', 25, struct mousedefs) /* read defs */
+#define KBDMOUSESET _IOW('K', 26, struct mousedefs) /* set defs */
+
+/*---------------------------------------------------------------------------*
+ * IOCTLs for Video Adapter
+ *---------------------------------------------------------------------------*/
+
+/* Definition of PC Video Adaptor Types */
+
+#define UNKNOWN_ADAPTOR 0 /* Unidentified adaptor ... */
+#define MDA_ADAPTOR 1 /* Monochrome Display Adaptor/Hercules Graphics Card */
+#define CGA_ADAPTOR 2 /* Color Graphics Adaptor */
+#define EGA_ADAPTOR 3 /* Enhanced Graphics Adaptor */
+#define VGA_ADAPTOR 4 /* Video Graphics Adaptor/Array */
+
+/* Deifinitions of Monitor types */
+
+#define MONITOR_MONO 0 /* Monochrome Monitor */
+#define MONITOR_COLOR 1 /* Color Monitor */
+
+/* Types of VGA chips detectable by current driver version */
+
+#define VGA_F_NONE 0 /* FAMILY NOT KNOWN */
+#define VGA_UNKNOWN 0 /* default, no 132 columns */
+
+#define VGA_F_TSENG 1 /* FAMILY TSENG */
+#define VGA_ET4000 1 /* Tseng Labs ET4000 */
+#define VGA_ET3000 2 /* Tseng Labs ET3000 */
+
+#define VGA_F_WD 2 /* FAMILY WD */
+#define VGA_PVGA 3 /* Western Digital Paradise VGA */
+#define VGA_WD90C00 4 /* Western Digital WD90C00 */
+#define VGA_WD90C10 5 /* Western Digital WD90C10 */
+#define VGA_WD90C11 6 /* Western Digital WD90C11 */
+
+#define VGA_F_V7 3 /* FAMILY VIDEO 7 */
+#define VGA_V7VEGA 7 /* Video 7 VEGA VGA */
+#define VGA_V7FWVR 8 /* Video 7 FASTWRITE/VRAM */
+#define VGA_V7V5 9 /* Video 7 Version 5 */
+#define VGA_V71024I 10 /* Video 7 1024i */
+#define VGA_V7UNKNOWN 11 /* Video 7 unknown board .. */
+
+#define VGA_F_TRI 4 /* FAMILY TRIDENT */
+#define VGA_TR8800BR 12 /* Trident TVGA 8800BR */
+#define VGA_TR8800CS 13 /* Trident TVGA 8800CS */
+#define VGA_TR8900B 14 /* Trident TVGA 8900B */
+#define VGA_TR8900C 15 /* Trident TVGA 8900C */
+#define VGA_TR8900CL 16 /* Trident TVGA 8900CL */
+#define VGA_TR9000 17 /* Trident TVGA 9000 */
+#define VGA_TR9100 18 /* Trident TVGA 9100 */
+#define VGA_TR9200 19 /* Trident TVGA 9200 */
+#define VGA_TRUNKNOWN 20 /* Trident unknown */
+
+#define VGA_F_S3 5 /* FAMILY S3 */
+#define VGA_S3_911 21 /* S3 911 */
+#define VGA_S3_924 22 /* S3 924 */
+#define VGA_S3_80x 23 /* S3 801/805 */
+#define VGA_S3_928 24 /* S3 928 */
+#define VGA_S3_UNKNOWN 25 /* unknown S3 chipset */
+
+#define VGA_F_CIR 6 /* FAMILY CIRRUS */
+#define VGA_CL_GD5402 26 /* Cirrus CL-GD5402 */
+#define VGA_CL_GD5402r1 27 /* Cirrus CL-GD5402r1 */
+#define VGA_CL_GD5420 28 /* Cirrus CL-GD5420 */
+#define VGA_CL_GD5420r1 29 /* Cirrus CL-GD5420r1 */
+#define VGA_CL_GD5422 30 /* Cirrus CL-GD5422 */
+#define VGA_CL_GD5424 31 /* Cirrus CL-GD5424 */
+#define VGA_CL_GD5426 32 /* Cirrus CL-GD5426 */
+#define VGA_CL_GD5428 33 /* Cirrus CL-GD5428 */
+#define VGA_CL_GD5430 34 /* Cirrus CL-GD543x */
+#define VGA_CL_GD6225 35 /* Cirrus CL-GD62x5 */
+#define VGA_CL_UNKNOWN 36 /* Unknown Cirrus CL */
+
+#define VGA_MAX_CHIPSET 37 /* max no of chips */
+
+/*****************************************************************************/
+/* NOTE: update the 'scon' utility when adding support for more chipsets !!! */
+/*****************************************************************************/
+
+/* Definitions of Vertical Screen Sizes for EGA/VGA Adaptors */
+
+#define SIZ_25ROWS 0 /* VGA: 25 lines, 8x16 font */
+ /* EGA: 25 lines, 8x14 font */
+#define SIZ_28ROWS 1 /* VGA: 28 lines, 8x14 font */
+#define SIZ_35ROWS 2 /* EGA: 35 lines, 8x10 font */
+#define SIZ_40ROWS 3 /* VGA: 40 lines, 8x10 font */
+#define SIZ_43ROWS 4 /* EGA: 43 lines, 8x8 font */
+#define SIZ_50ROWS 5 /* VGA: 50 lines, 8x8 font */
+
+/* Definitions of Font Sizes for EGA/VGA Adaptors */
+
+#define FNT_8x16 0 /* 8x16 Pixel Font, only VGA */
+#define FNT_8x14 1 /* 8x14 Pixel Font, EGA/VGA */
+#define FNT_8x10 2 /* 8x10 Pixel Font, EGA/VGA */
+#define FNT_8x8 3 /* 8x8 Pixel Font, EGA/VGA */
+
+/* Definitions of Character Set (Font) Numbers */
+
+#define CH_SET0 0 /* Character Set (Font) 0, EGA/VGA */
+#define CH_SET1 1 /* Character Set (Font) 1, EGA/VGA */
+#define CH_SET2 2 /* Character Set (Font) 2, EGA/VGA */
+#define CH_SET3 3 /* Character Set (Font) 3, EGA/VGA */
+#define CH_SETMAX_EGA 3 /* EGA has 4 Character Sets / Fonts */
+#define CH_SET4 4 /* Character Set (Font) 4, VGA */
+#define CH_SET5 5 /* Character Set (Font) 5, VGA */
+#define CH_SET6 6 /* Character Set (Font) 6, VGA */
+#define CH_SET7 7 /* Character Set (Font) 7, VGA */
+#define CH_SETMAX_VGA 7 /* VGA has 8 Character Sets / Fonts */
+
+/* Definitions of Terminal Emulation Modes */
+
+#define M_HPVT 0 /* VTxxx and HP Mode, Labels & Status Line on */
+#define M_PUREVT 1 /* only VTxxx Sequences recognized, no Labels */
+
+/*---*/
+
+#define VGACURSOR _IOW('V',100, struct cursorshape) /* set cursor shape */
+
+struct cursorshape {
+ int screen_no; /* screen number for which to set, */
+ /* or -1 to set on current active screen */
+ int start; /* top scanline, range 0... Character Height - 1 */
+ int end; /* end scanline, range 0... Character Height - 1 */
+};
+
+#define VGALOADCHAR _IOW('V',101, struct vgaloadchar) /* load vga char */
+
+struct vgaloadchar {
+ int character_set; /* VGA character set to load into */
+ int character; /* Character to load */
+ int character_scanlines; /* Scanlines per character */
+ u_char char_table[32]; /* VGA character shape table */
+};
+
+#define VGASETFONTATTR _IOW('V',102, struct vgafontattr) /* set font attr */
+#define VGAGETFONTATTR _IOWR('V',103, struct vgafontattr) /* get font attr */
+
+struct vgafontattr {
+ int character_set; /* VGA character set */
+ int font_loaded; /* Mark font loaded or unloaded */
+ int screen_size; /* Character rows per screen */
+ int character_scanlines; /* Scanlines per character - 1 */
+ int screen_scanlines; /* Scanlines per screen - 1 byte */
+};
+
+#define VGASETSCREEN _IOW('V',104, struct screeninfo) /* set screen info */
+#define VGAGETSCREEN _IOWR('V',105, struct screeninfo) /* get screen info */
+
+struct screeninfo {
+ int adaptor_type; /* type of video adaptor installed */
+ /* read only, ignored on write */
+ int monitor_type; /* type of monitor (mono/color)installed*/
+ /* read only, ignored on write */
+ int totalfonts; /* no of downloadable fonts */
+ /* read only, ignored on write */
+ int totalscreens; /* no of virtual screens */
+ /* read only, ignored on write */
+ int screen_no; /* screen number, this was got from */
+ /* on write, if -1, apply pure_vt_mode */
+ /* and/or screen_size to current screen */
+ /* else to screen_no supplied */
+ int current_screen; /* screen number, which is displayed. */
+ /* on write, if -1, make this screen */
+ /* the current screen, else set current */
+ /* displayed screen to parameter */
+ int pure_vt_mode; /* flag, pure VT mode or HP/VT mode */
+ /* on write, if -1, no change */
+ int screen_size; /* screen size */
+ /* on write, if -1, no change */
+ int force_24lines; /* force 24 lines if 25 lines VT mode */
+ /* or 28 lines HP mode to get pure */
+ /* VT220 screen size */
+ /* on write, if -1, no change */
+ int vga_family; /* if adaptor_type = VGA, this reflects */
+ /* the chipset family after a read */
+ /* nothing happenes on write ... */
+ int vga_type; /* if adaptor_type = VGA, this reflects */
+ /* the chipset after a read */
+ /* nothing happenes on write ... */
+ int vga_132; /* set to 1 if driver has support for */
+ /* 132 column operation for chipset */
+ /* currently ignored on write */
+};
+
+#define VGAREADPEL _IOWR('V', 110, struct vgapel) /*r VGA palette entry */
+#define VGAWRITEPEL _IOW('V', 111, struct vgapel) /*w VGA palette entry */
+
+struct vgapel {
+ unsigned idx; /* index into palette, 0 .. 255 valid */
+ unsigned r, g, b; /* RGB values, masked by VGA_PMASK (63) */
+};
+
+/* NOTE: The next ioctl is only valid if option PCVT_SCREENSAVER is configured*/
+/* this is *not* restricted to VGA's, but won't introduce new garbage... */
+
+#define VGASCREENSAVER _IOW('V', 112, int) /* set timeout for screen */
+ /* saver in seconds; 0 turns */
+ /* it off */
+
+#define VGAPCVTID _IOWR('V',113, struct pcvtid) /* get driver id */
+
+struct pcvtid { /* THIS STRUCTURE IS NOW FROZEN !!! */
+#define PCVTIDNAMELN 16 /* driver id - string length */
+ char name[PCVTIDNAMELN]; /* driver name, == PCVTIDSTR */
+ int rmajor; /* revision number, major */
+ int rminor; /* revision number, minor */
+}; /* END OF COLD PART ... */
+
+#define VGAPCVTINFO _IOWR('V',114, struct pcvtinfo) /* get driver info */
+
+struct pcvtinfo { /* compile time option values */
+ u_int opsys; /* PCVT_xxx(x)BSD */
+#define CONF_UNKNOWNOPSYS 0
+#define CONF_386BSD 1 /* unsupported */
+#define CONF_NETBSD 2
+#define CONF_FREEBSD 3
+ u_int opsysrel; /* Release */
+ u_int nscreens; /* PCVT_NSCREENS */
+ u_int scanset; /* PCVT_SCANSET */
+ u_int updatefast; /* PCVT_UPDATEFAST */
+ u_int updateslow; /* PCVT_UPDATESLOW */
+ u_int sysbeepf; /* PCVT_SYSBEEPF */
+ u_int pcburst; /* PCVT_PCBURST */
+ u_int kbd_fifo_sz; /* PCVT_KBD_FIFO_SZ */
+
+/* config booleans */
+
+ u_long compile_opts; /* PCVT_xxxxxxxxxxxxxxx */
+
+#define CONF_VT220KEYB 0x00000001
+#define CONF_SCREENSAVER 0x00000002
+#define CONF_PRETTYSCRNS 0x00000004
+#define CONF_CTRL_ALT_DEL 0x00000008
+#define CONF_USEKBDSEC 0x00000010
+#define CONF_24LINESDEF 0x00000020
+#define CONF_EMU_MOUSE 0x00000040
+#define CONF_SHOWKEYS 0x00000080
+#define CONF_KEYBDID 0x00000100
+#define CONF_SIGWINCH 0x00000200
+#define CONF_NULLCHARS 0x00000400
+#define CONF_BACKUP_FONTS 0x00000800
+#define CONF_SW0CNOUTP 0x00001000
+#define CONF_MDAFASTSCROLL 0x00002000
+#define CONF_SETCOLOR 0x00004000
+#define CONF_132GENERIC 0x00008000
+#define CONF_PALFLICKER 0x00010000
+#define CONF_WAITRETRACE 0x00020000
+#define CONF_XSERVER 0x00040000
+/* #define CONF_USL_VT_COMPAT 0x00080000 */
+#define CONF_PORTIO_DELAY 0x00100000
+#define CONF_INHIBIT_NUMLOCK 0x00200000
+#define CONF_META_ESC 0x00400000
+#define CONF_NOFASTSCROLL 0x00800000
+#define CONF_SLOW_INTERRUPT 0x01000000
+#define CONF_KBD_FIFO 0x02000000
+#define CONF_NO_LED_UPDATE 0x04000000
+};
+
+#define VGASETCOLMS _IOW('V', 115, int) /* set number of columns (80/132)*/
+
+/*
+ * only useful if compiled with ``XSERVER'' defined, but always here:
+ * WARNING: DO NOT CHANGE THESE DEFINITIONS, the X server relies on
+ * it since it's defining its own values and doesn't know nothing about
+ * this header file.
+ */
+
+#define CONSOLE_X_MODE_ON _IO('t', 121) /* turn off pcvt, grant IOPL for X */
+
+#define CONSOLE_X_MODE_OFF _IO('t', 122) /* back to pcvt */
+
+#define CONSOLE_X_BELL _IOW('t', 123, int[2]) /* set bell behaviour */
+
+/*
+ * start of USL VT compatibility stuff
+ * these definitions must match those ones used by syscons
+ *
+ * Note that some of the ioctl command definitions below break the Berkeley
+ * style. They accept a parameter of type "int" (instead of Berkeley style
+ * "int *") in order to pass a single integer to the ioctl. These macros
+ * below are marked with a dummy "int" comment. Dont blame anyone else
+ * than USL for that braindeadness. It is done here to be a bit source-
+ * level compatible to SysV. (N.B., within the ioctl, the argument is
+ * dereferenced by "int *" anyway. The translation is done by the upper-
+ * level ioctl stuff.)
+ */
+
+/*
+ * NB: Some of the definitions below apparently override the definitions
+ * in the KBD section above. But, due to BSDs encoding of the IO direction
+ * and transfer size, the resulting ioctl cmds differ, so we can take them
+ * here.
+ */
+
+#define KDGKBMODE _IOR('K', 6, int) /* get keyboard mode */
+#define KDSKBMODE _IO('K', 7 /*, int */) /* set keyboard mode */
+#define K_RAW 0 /* kbd switched to raw mode */
+#define K_XLATE 1 /* kbd switched to "normal" mode */
+
+#define KDMKTONE _IO('K', 8 /*, int */)
+
+/* #define KDGETMODE _IOR('K', 9, int) */ /* not yet implemented */
+
+#define KDSETMODE _IO('K', 10 /*, int */)
+#define KD_TEXT 0 /* set text mode restore fonts */
+#define KD_GRAPHICS 1 /* set graphics mode */
+
+/* we cannot see any sense to support KD_TEXT0 or KD_TEXT1 */
+
+#define KDENABIO _IO('K', 60) /* only allowed if euid == 0 */
+#define KDDISABIO _IO('K', 61)
+
+#define KDGETLED _IOR('K', 65, int)
+#define KDSETLED _IO('K', 66 /*, int */)
+#define LED_CAP 1
+#define LED_NUM 2
+#define LED_SCR 4
+
+#define KDSETRAD _IO('K', 67 /*, int */)
+
+/*
+ * Note that since our idea of key mapping is much different from the
+ * SysV style, we _only_ support mapping layers base (0), shifted (1),
+ * alt (4), and alt-shift (5), and only for the basic keys (without
+ * any function keys). This is what XFree86 2.0+ needs to establish
+ * the default X keysym mapping.
+ */
+#define GIO_KEYMAP _IOR('k', 6, keymap_t)
+
+#define VT_OPENQRY _IOR('v', 1, int)
+#define VT_SETMODE _IOW('v', 2, vtmode_t)
+#define VT_GETMODE _IOR('v', 3, vtmode_t)
+
+#define VT_RELDISP _IO('v', 4 /*, int */)
+
+/* acceptable values for the VT_RELDISP command */
+
+#define VT_FALSE 0 /* release of VT refused */
+#define VT_TRUE 1 /* VT released */
+#define VT_ACKACQ 2 /* acknowledging VT acquiration */
+
+
+#define VT_ACTIVATE _IO('v', 5 /*, int */)
+#define VT_WAITACTIVE _IO('v', 6 /*, int */)
+#define VT_GETACTIVE _IOR('v', 7, int)
+
+struct vt_mode {
+ char mode;
+
+#define VT_AUTO 0 /* switching controlled by drvr */
+#define VT_PROCESS 1 /* switching controlled by prog */
+
+ char waitv; /* not implemented yet SOS */
+ short relsig;
+ short acqsig;
+ short frsig; /* not implemented yet SOS */
+};
+
+typedef struct vt_mode vtmode_t;
+
+#define NUM_KEYS 256
+#define NUM_STATES 8
+
+struct keymap {
+ u_short n_keys;
+ struct key_t {
+ u_char map[NUM_STATES];
+ u_char spcl;
+ u_char flgs;
+ } key[NUM_KEYS];
+};
+
+typedef struct keymap keymap_t;
+
+/* end of USL VT compatibility stuff */
+
+#endif /* ! _MACHINE_PCVT_IOCTL_H_ */
diff --git a/sys/arch/i386/isa/pcvt/pcvt_kbd.c b/sys/arch/i386/isa/pcvt/pcvt_kbd.c
new file mode 100644
index 00000000000..c7925fd407e
--- /dev/null
+++ b/sys/arch/i386/isa/pcvt/pcvt_kbd.c
@@ -0,0 +1,2932 @@
+/*
+ * Copyright (c) 1992, 1995 Hellmuth Michaelis and Joerg Wunsch.
+ *
+ * Copyright (c) 1992, 1993 Brian Dunford-Shore and Holger Veit.
+ *
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * William Jolitz and Don Ahn.
+ *
+ * This code is derived from software contributed to 386BSD by
+ * Holger Veit.
+ *
+ * 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 Hellmuth Michaelis,
+ * Brian Dunford-Shore and Joerg Wunsch.
+ * 4. The name authors may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``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 AUTHORS 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.
+ *
+ *
+ * @(#)pcvt_kbd.c, 3.32, Last Edit-Date: [Tue Oct 3 11:19:48 1995]
+ *
+ */
+
+/*---------------------------------------------------------------------------*
+ *
+ * pcvt_kbd.c VT220 Driver Keyboard Interface Code
+ * ----------------------------------------------------
+ * -hm ------------ Release 3.00 --------------
+ * -hm integrating NetBSD-current patches
+ * -jw introduced kbd_emulate_pc() if scanset > 1
+ * -hm patch from joerg for timeout in kbd_emulate_pc()
+ * -hm starting to implement alt-shift/ctrl key mappings
+ * -hm Gateway 2000 Keyboard fix from Brian Moore
+ * -hm some #if adjusting for NetBSD 0.9
+ * -hm split off pcvt_kbd.h
+ * -hm applying Joerg's patches for FreeBSD 2.0
+ * -hm patch from Martin, PCVT_NO_LED_UPDATE
+ * -hm PCVT_VT220KEYB patches from Lon Willet
+ * -hm PR #399, patch from Bill Sommerfeld: Return with PCVT_META_ESC
+ * -hm allow keyboard-less kernel boot for serial consoles and such ..
+ * -hm patch from Lon Willett for led-update and showkey()
+ * -hm patch from Lon Willett to fix mapping of Control-R scancode
+ * -hm delay patch from Martin Husemann after port-i386 ml-discussion
+ * -hm added PCVT_NONRESP_KEYB_TRY definition to doreset()
+ * -hm keyboard code bugfix from Jukka A. Ukkonen (ukkonen@csc.fi)
+ * -hm ---------------- Release 3.30 -----------------------
+ * -hm patch from Frank van der Linden for keyboard state per VT
+ * -hm removed KBDGLEDS and KBDSLEDS ioctls
+ * -hm ---------------- Release 3.32 -----------------------
+ *
+ *---------------------------------------------------------------------------*/
+
+#include "vt.h"
+#if NVT > 0
+
+#include "pcvt_hdr.h" /* global include */
+
+static void fkey1(void), fkey2(void), fkey3(void), fkey4(void);
+static void fkey5(void), fkey6(void), fkey7(void), fkey8(void);
+static void fkey9(void), fkey10(void), fkey11(void), fkey12(void);
+
+static void sfkey1(void), sfkey2(void), sfkey3(void), sfkey4(void);
+static void sfkey5(void), sfkey6(void), sfkey7(void), sfkey8(void);
+static void sfkey9(void), sfkey10(void), sfkey11(void), sfkey12(void);
+
+static void cfkey1(void), cfkey2(void), cfkey3(void), cfkey4(void);
+static void cfkey5(void), cfkey6(void), cfkey7(void), cfkey8(void);
+static void cfkey9(void), cfkey10(void), cfkey11(void), cfkey12(void);
+
+static void doreset ( void );
+static void ovlinit ( int force );
+static void settpmrate ( int rate );
+static void setlockkeys ( int snc );
+static int kbc_8042cmd ( int val );
+static int getokeydef ( unsigned key, struct kbd_ovlkey *thisdef );
+static int getckeydef ( unsigned key, struct kbd_ovlkey *thisdef );
+static int rmkeydef ( int key );
+static int setkeydef ( struct kbd_ovlkey *data );
+static u_char * xlatkey2ascii( U_short key );
+
+static int ledstate = 0; /* keyboard led's */
+static int tpmrate = KBD_TPD500|KBD_TPM100;
+static u_char altkpflag = 0;
+static u_short altkpval = 0;
+
+#if PCVT_SHOWKEYS
+u_char rawkeybuf[80];
+#endif
+
+#include "pcvt_kbd.h" /* tables etc */
+
+#if PCVT_SHOWKEYS
+/*---------------------------------------------------------------------------*
+ * keyboard debugging: put kbd communication char into some buffer
+ *---------------------------------------------------------------------------*/
+static void showkey (char delim, u_char val)
+{
+ int rki;
+
+ for(rki = 3; rki < 80; rki++) /* shift left buffer */
+ rawkeybuf[rki-3] = rawkeybuf[rki];
+
+ rawkeybuf[77] = delim; /* delimiter */
+
+ rki = (val & 0xf0) >> 4; /* ms nibble */
+
+ if(rki <= 9)
+ rki = rki + '0';
+ else
+ rki = rki - 10 + 'A';
+
+ rawkeybuf[78] = rki;
+
+ rki = val & 0x0f; /* ls nibble */
+
+ if(rki <= 9)
+ rki = rki + '0';
+ else
+ rki = rki - 10 + 'A';
+
+ rawkeybuf[79] = rki;
+}
+#endif /* PCVT_SHOWKEYS */
+
+/*---------------------------------------------------------------------------*
+ * function to switch to another virtual screen
+ *---------------------------------------------------------------------------*/
+static void
+do_vgapage(int page)
+{
+ if(critical_scroll) /* executing critical region ? */
+ switch_page = page; /* yes, auto switch later */
+ else
+ vgapage(page); /* no, switch now */
+}
+
+
+/*
+ * This code from Lon Willett enclosed in #if PCVT_UPDLED_LOSES_INTR is
+ * abled because it crashes FreeBSD 1.1.5.1 at boot time.
+ * The cause is obviously that the timeout queue is not yet initialized
+ * timeout is called from here the first time.
+ * Anyway it is a pointer in the right direction so it is included for
+ * reference here.
+ */
+
+#define PCVT_UPDLED_LOSES_INTR 0 /* disabled for now */
+
+#if PCVT_UPDLED_LOSES_INTR
+
+/*---------------------------------------------------------------------------*
+ * check for lost keyboard interrupts
+ *---------------------------------------------------------------------------*/
+
+/*
+ * The two commands to change the LEDs generate two KEYB_R_ACK responses
+ * from the keyboard, which aren't explicitly checked for (maybe they
+ * should be?). However, when a lot of other I/O is happening, one of
+ * the interrupts sometimes gets lost (I'm not sure of the details of
+ * how and why and what hardware this happens with).
+ *
+ * This is a real problem, because normally the keyboard is only polled
+ * by pcrint(), and no more interrupts will be generated until the ACK
+ * has been read. So the keyboard is hung. This code polls a little
+ * while after changing the LEDs to make sure that this hasn't happened.
+ *
+ * XXX Quite possibly we should poll the kbd on a regular basis anyway,
+ * in the interest of robustness. It may be possible that interrupts
+ * get lost other times as well.
+ */
+
+static int lost_intr_timeout_queued = 0;
+
+static void
+check_for_lost_intr (void *arg)
+{
+ lost_intr_timeout_queued = 0;
+ if (inb(CONTROLLER_CTRL) & STATUS_OUTPBF)
+ {
+ int opri = spltty ();
+ (void) pcrint ();
+ splx (opri);
+ }
+}
+
+#endif /* PCVT_UPDLED_LOSES_INTR */
+
+/*---------------------------------------------------------------------------*
+ * update keyboard led's
+ *---------------------------------------------------------------------------*/
+void
+update_led(void)
+{
+
+#if !PCVT_NO_LED_UPDATE
+
+ /* Don't update LED's unless necessary. */
+
+ int new_ledstate = ((vsp->scroll_lock) |
+ (vsp->num_lock * 2) |
+ (vsp->caps_lock * 4));
+
+ if (new_ledstate != ledstate)
+ {
+ if(kbd_cmd(KEYB_C_LEDS) != 0)
+ {
+ printf("Keyboard LED command timeout\n");
+ return;
+ }
+
+ if(kbd_cmd(new_ledstate) != 0) {
+ printf("Keyboard LED data timeout\n");
+ return;
+ }
+
+ ledstate = new_ledstate;
+
+#if PCVT_UPDLED_LOSES_INTR
+ if (lost_intr_timeout_queued)
+ untimeout (check_for_lost_intr, (void *)NULL);
+
+ timeout (check_for_lost_intr, (void *)NULL, hz);
+ lost_intr_timeout_queued = 1;
+#endif /* PCVT_UPDLED_LOSES_INTR */
+
+ }
+#endif /* !PCVT_NO_LED_UPDATE */
+}
+
+/*---------------------------------------------------------------------------*
+ * set typematic rate
+ *---------------------------------------------------------------------------*/
+static void
+settpmrate(int rate)
+{
+ tpmrate = rate & 0x7f;
+ if(kbd_cmd(KEYB_C_TYPEM) != 0)
+ printf("Keyboard TYPEMATIC command timeout\n");
+ else if(kbd_cmd(tpmrate) != 0)
+ printf("Keyboard TYPEMATIC data timeout\n");
+}
+
+/*---------------------------------------------------------------------------*
+ * Pass command to keyboard controller (8042)
+ *---------------------------------------------------------------------------*/
+static int
+kbc_8042cmd(int val)
+{
+ unsigned timeo;
+
+ timeo = 100000; /* > 100 msec */
+ while (inb(CONTROLLER_CTRL) & STATUS_INPBF)
+ if (--timeo == 0)
+ return (-1);
+ outb(CONTROLLER_CTRL, val);
+ return (0);
+}
+
+/*---------------------------------------------------------------------------*
+ * Pass command to keyboard itself
+ *---------------------------------------------------------------------------*/
+int
+kbd_cmd(int val)
+{
+ unsigned timeo;
+
+ timeo = 100000; /* > 100 msec */
+ while (inb(CONTROLLER_CTRL) & STATUS_INPBF)
+ if (--timeo == 0)
+ return (-1);
+ outb(CONTROLLER_DATA, val);
+
+#if PCVT_SHOWKEYS
+ showkey ('>', val);
+#endif /* PCVT_SHOWKEYS */
+
+ return (0);
+}
+
+/*---------------------------------------------------------------------------*
+ * Read response from keyboard
+ * NB: make sure to call spltty() before kbd_cmd(), kbd_response().
+ *---------------------------------------------------------------------------*/
+int
+kbd_response(void)
+{
+ u_char ch;
+ unsigned timeo;
+
+ timeo = 500000; /* > 500 msec (KEYB_R_SELFOK requires 87) */
+ while (!(inb(CONTROLLER_CTRL) & STATUS_OUTPBF))
+ if (--timeo == 0)
+ return (-1);
+
+ PCVT_KBD_DELAY(); /* 7 us delay */
+ ch = inb(CONTROLLER_DATA);
+
+#if PCVT_SHOWKEYS
+ showkey ('<', ch);
+#endif /* PCVT_SHOWKEYS */
+
+ return ch;
+}
+
+/*---------------------------------------------------------------------------*
+ * switch to/from PC scan code emulation mode
+ *---------------------------------------------------------------------------*/
+void
+kbd_setmode(int mode)
+{
+#if PCVT_SCANSET > 1 /* switch only if we are running */
+ /* keyboard scancode 2 */
+
+ int cmd, timeo = 10000;
+
+#if PCVT_USEKBDSEC
+ cmd = COMMAND_SYSFLG | COMMAND_IRQEN;
+#else
+ cmd = COMMAND_INHOVR | COMMAND_SYSFLG | COMMAND_IRQEN;
+#endif
+
+ if(mode == K_RAW) /* switch to scancode 1 ? */
+ cmd |= COMMAND_PCSCAN; /* yes, setup command */
+
+ kbc_8042cmd(CONTR_WRITE);
+
+ while (inb(CONTROLLER_CTRL) & STATUS_INPBF)
+ {
+ if (--timeo == 0)
+ break;
+ }
+
+ outb(CONTROLLER_DATA, cmd);
+
+#endif /* PCVT_SCANSET > 1 */
+
+ if(mode == K_RAW)
+ shift_down = meta_down = altgr_down = ctrl_down = 0;
+}
+
+
+#ifndef PCVT_NONRESP_KEYB_TRY
+#define PCVT_NONRESP_KEYB_TRY 25 /* no of times to try to detect */
+#endif /* a nonresponding keyboard */
+
+/*---------------------------------------------------------------------------*
+ * try to force keyboard into a known state ..
+ *---------------------------------------------------------------------------*/
+static
+void doreset(void)
+{
+ int again = 0;
+ int once = 0;
+ int response, opri;
+ unsigned int wait_retries, seen_negative_response;
+
+ /* Enable interrupts and keyboard, etc. */
+ if(kbc_8042cmd(CONTR_WRITE) != 0)
+ printf("pcvt: doreset() - timeout controller write command\n");
+
+#if PCVT_USEKBDSEC /* security enabled */
+
+# if PCVT_SCANSET == 2
+# define KBDINITCMD COMMAND_SYSFLG|COMMAND_IRQEN
+# else /* PCVT_SCANSET != 2 */
+# define KBDINITCMD COMMAND_PCSCAN|COMMAND_SYSFLG|COMMAND_IRQEN
+# endif /* PCVT_SCANSET == 2 */
+
+#else /* ! PCVT_USEKBDSEC */ /* security disabled */
+
+# if PCVT_SCANSET == 2
+# define KBDINITCMD COMMAND_INHOVR|COMMAND_SYSFLG|COMMAND_IRQEN
+# else /* PCVT_SCANSET != 2 */
+# define KBDINITCMD COMMAND_PCSCAN|COMMAND_INHOVR|COMMAND_SYSFLG\
+ |COMMAND_IRQEN
+# endif /* PCVT_SCANSET == 2 */
+
+#endif /* PCVT_USEKBDSEC */
+
+ if(kbd_cmd(KBDINITCMD) != 0)
+ printf("pcvt: doreset() - timeout writing keyboard init command\n");
+
+ /*
+ * Discard any stale keyboard activity. The 0.1 boot code isn't
+ * very careful and sometimes leaves a KEYB_R_RESEND.
+ */
+ while(inb(CONTROLLER_CTRL) & STATUS_OUTPBF)
+ kbd_response();
+
+ /* Start keyboard reset */
+
+ opri = spltty();
+
+ if(kbd_cmd(KEYB_C_RESET) != 0)
+ printf("pcvt: doreset() - timeout for keyboard reset command\n");
+
+ /* Wait for the first response to reset and handle retries */
+
+ while((response = kbd_response()) != KEYB_R_ACK)
+ {
+ if(response < 0)
+ {
+ if(!again) /* print message only once ! */
+ printf("pcvt: doreset() - response != ack and response < 0 [one time only msg]\n");
+ response = KEYB_R_RESEND;
+ }
+ if(response == KEYB_R_RESEND)
+ {
+ if(!again) /* print message only once ! */
+ printf("pcvt: doreset() - got KEYB_R_RESEND response ... [one time only msg]\n");
+
+ if(++again > PCVT_NONRESP_KEYB_TRY)
+ {
+ printf("pcvt: doreset() - Caution - no PC keyboard detected!\n");
+ keyboard_type = KB_UNKNOWN;
+ splx(opri);
+ return;
+ }
+
+ if((kbd_cmd(KEYB_C_RESET) != 0) && (once == 0))
+ {
+ once++; /* print message only once ! */
+ printf("pcvt: doreset() - timeout for loop keyboard reset command [one time only msg]\n");
+ }
+ }
+ }
+
+ /* Wait for the second response to reset */
+
+ wait_retries = seen_negative_response = 0;
+
+ while((response = kbd_response()) != KEYB_R_SELFOK)
+ {
+ /*
+ * Let's be a little more tolerant here...
+ * Receiving a -1 could indicate that the keyboard
+ * is not ready to answer just yet.
+ * Such cases have been noticed with e.g. Alps Membrane.
+ */
+
+ if(response < 0)
+ seen_negative_response = 1;
+
+ if(seen_negative_response && (wait_retries >= 10))
+ {
+ printf("pcvt: doreset() - response != OK and response < 0\n");
+
+ /*
+ * If KEYB_R_SELFOK never arrives, the loop will
+ * finish here unless the keyboard babbles or
+ * STATUS_OUTPBF gets stuck.
+ */
+ break;
+ }
+ wait_retries++;
+ }
+
+ splx(opri);
+
+#if PCVT_KEYBDID
+
+query_kbd_id:
+
+ opri = spltty();
+
+ if(kbd_cmd(KEYB_C_ID) != 0)
+ {
+ printf("pcvt: doreset() - timeout for keyboard ID command\n");
+ keyboard_type = KB_UNKNOWN;
+ }
+ else
+ {
+
+r_entry:
+ if((response = kbd_response()) == KEYB_R_MF2ID1)
+ {
+ if((response = kbd_response()) == KEYB_R_MF2ID2)
+ {
+ keyboard_type = KB_MFII;
+ }
+ else if(response == KEYB_R_RESEND)
+ {
+ /*
+ * Let's give other priority levels
+ * a chance instead of blocking at
+ * tty level.
+ */
+ splx(opri);
+ goto query_kbd_id;
+ }
+ else if(response == KEYB_R_MF2ID2HP)
+ {
+ keyboard_type = KB_MFII;
+ }
+ else
+ {
+ printf("\npcvt: doreset() - kbdid, response 2 = [%d]\n",
+ response);
+ keyboard_type = KB_UNKNOWN;
+ }
+ }
+ else if(response == KEYB_R_ACK)
+ {
+ goto r_entry;
+ }
+ else if(response == -1)
+ {
+ keyboard_type = KB_AT;
+ }
+ else
+ {
+ printf("\npcvt: doreset() - kbdid, response 1 = [%d]\n", response);
+ }
+ }
+
+ splx(opri);
+
+#else /* PCVT_KEYBDID */
+
+ keyboard_type = KB_MFII; /* force it .. */
+
+#endif /* PCVT_KEYBDID */
+
+}
+
+/*---------------------------------------------------------------------------*
+ * init keyboard code
+ *---------------------------------------------------------------------------*/
+void
+kbd_code_init(void)
+{
+ doreset();
+ ovlinit(0);
+ keyboard_is_initialized = 1;
+}
+
+/*---------------------------------------------------------------------------*
+ * init keyboard code, this initializes the keyboard subsystem
+ * just "a bit" so the very very first ddb session is able to
+ * get proper keystrokes - in other words, it's a hack ....
+ *---------------------------------------------------------------------------*/
+void
+kbd_code_init1(void)
+{
+ doreset();
+ keyboard_is_initialized = 1;
+}
+
+/*---------------------------------------------------------------------------*
+ * init keyboard overlay table
+ *---------------------------------------------------------------------------*/
+static
+void ovlinit(int force)
+{
+ register i;
+
+ if(force || ovlinitflag==0)
+ {
+ if(ovlinitflag == 0 &&
+ (ovltbl = (Ovl_tbl *)malloc(sizeof(Ovl_tbl) * OVLTBL_SIZE,
+ M_DEVBUF, M_WAITOK)) == NULL)
+ panic("pcvt_kbd: malloc of Ovl_tbl failed");
+
+ for(i=0; i<OVLTBL_SIZE; i++)
+ {
+ ovltbl[i].keynum =
+ ovltbl[i].type = 0;
+ ovltbl[i].unshift[0] =
+ ovltbl[i].shift[0] =
+ ovltbl[i].ctrl[0] =
+ ovltbl[i].altgr[0] = 0;
+ ovltbl[i].subu =
+ ovltbl[i].subs =
+ ovltbl[i].subc =
+ ovltbl[i].suba = KBD_SUBT_STR; /* just strings .. */
+ }
+ for(i=0; i<=MAXKEYNUM; i++)
+ key2ascii[i].type &= KBD_MASK;
+ ovlinitflag = 1;
+ }
+}
+
+/*---------------------------------------------------------------------------*
+ * get original key definition
+ *---------------------------------------------------------------------------*/
+static int
+getokeydef(unsigned key, Ovl_tbl *thisdef)
+{
+ if(key == 0 || key > MAXKEYNUM)
+ return EINVAL;
+
+ thisdef->keynum = key;
+ thisdef->type = key2ascii[key].type;
+
+ if(key2ascii[key].unshift.subtype == STR)
+ {
+ bcopy((u_char *)(key2ascii[key].unshift.what.string),
+ thisdef->unshift, CODE_SIZE);
+ thisdef->subu = KBD_SUBT_STR;
+ }
+ else
+ {
+ bcopy("", thisdef->unshift, CODE_SIZE);
+ thisdef->subu = KBD_SUBT_FNC;
+ }
+
+ if(key2ascii[key].shift.subtype == STR)
+ {
+ bcopy((u_char *)(key2ascii[key].shift.what.string),
+ thisdef->shift, CODE_SIZE);
+ thisdef->subs = KBD_SUBT_STR;
+ }
+ else
+ {
+ bcopy("",thisdef->shift,CODE_SIZE);
+ thisdef->subs = KBD_SUBT_FNC;
+ }
+
+ if(key2ascii[key].ctrl.subtype == STR)
+ {
+ bcopy((u_char *)(key2ascii[key].ctrl.what.string),
+ thisdef->ctrl, CODE_SIZE);
+ thisdef->subc = KBD_SUBT_STR;
+ }
+ else
+ {
+ bcopy("",thisdef->ctrl,CODE_SIZE);
+ thisdef->subc = KBD_SUBT_FNC;
+ }
+
+ /* deliver at least anything for ALTGR settings ... */
+
+ if(key2ascii[key].unshift.subtype == STR)
+ {
+ bcopy((u_char *)(key2ascii[key].unshift.what.string),
+ thisdef->altgr, CODE_SIZE);
+ thisdef->suba = KBD_SUBT_STR;
+ }
+ else
+ {
+ bcopy("",thisdef->altgr, CODE_SIZE);
+ thisdef->suba = KBD_SUBT_FNC;
+ }
+ return 0;
+}
+
+/*---------------------------------------------------------------------------*
+ * get current key definition
+ *---------------------------------------------------------------------------*/
+static int
+getckeydef(unsigned key, Ovl_tbl *thisdef)
+{
+ u_short type = key2ascii[key].type;
+
+ if(key>MAXKEYNUM)
+ return EINVAL;
+
+ if(type & KBD_OVERLOAD)
+ *thisdef = ovltbl[key2ascii[key].ovlindex];
+ else
+ getokeydef(key,thisdef);
+
+ return 0;
+}
+
+/*---------------------------------------------------------------------------*
+ * translate keynumber and returns ptr to associated ascii string
+ * if key is bound to a function, executes it, and ret empty ptr
+ *---------------------------------------------------------------------------*/
+static u_char *
+xlatkey2ascii(U_short key)
+{
+ static u_char capchar[2] = {0, 0};
+#if PCVT_META_ESC
+ static u_char metachar[3] = {0x1b, 0, 0};
+#else
+ static u_char metachar[2] = {0, 0};
+#endif
+ static Ovl_tbl thisdef;
+ int n;
+ void (*fnc)();
+
+ if(key==0) /* ignore the NON-KEY */
+ return 0;
+
+ getckeydef(key&0x7F, &thisdef); /* get the current ASCII value */
+
+ thisdef.type &= KBD_MASK;
+
+ if(key&0x80) /* special handling of ALT-KEYPAD */
+ {
+ /* is the ALT Key released? */
+ if(thisdef.type==KBD_META || thisdef.type==KBD_ALTGR)
+ {
+ if(altkpflag) /* have we been in altkp mode? */
+ {
+ capchar[0] = altkpval;
+ altkpflag = 0;
+ altkpval = 0;
+ return capchar;
+ }
+ }
+ return 0;
+ }
+
+ switch(thisdef.type) /* convert the keys */
+ {
+ case KBD_BREAK:
+ case KBD_ASCII:
+ case KBD_FUNC:
+ fnc = NULL;
+ more_chars = NULL;
+
+ if(altgr_down)
+ {
+ more_chars = (u_char *)thisdef.altgr;
+ }
+ else if(!ctrl_down && (shift_down || vsp->shift_lock))
+ {
+ if(key2ascii[key].shift.subtype == STR)
+ more_chars = (u_char *)thisdef.shift;
+ else
+ fnc = key2ascii[key].shift.what.func;
+ }
+
+ else if(ctrl_down)
+ {
+ if(key2ascii[key].ctrl.subtype == STR)
+ more_chars = (u_char *)thisdef.ctrl;
+ else
+ fnc = key2ascii[key].ctrl.what.func;
+ }
+
+ else
+ {
+ if(key2ascii[key].unshift.subtype == STR)
+ more_chars = (u_char *)thisdef.unshift;
+ else
+ fnc = key2ascii[key].unshift.what.func;
+ }
+
+ if(fnc)
+ (*fnc)(); /* execute function */
+
+ if((more_chars != NULL) && (more_chars[1] == 0))
+ {
+ if(vsp->caps_lock && more_chars[0] >= 'a'
+ && more_chars[0] <= 'z')
+ {
+ capchar[0] = *more_chars - ('a'-'A');
+ more_chars = capchar;
+ }
+ if(meta_down)
+ {
+#if PCVT_META_ESC
+ metachar[1] = *more_chars;
+#else
+ metachar[0] = *more_chars | 0x80;
+#endif
+ more_chars = metachar;
+ }
+ }
+ return(more_chars);
+
+ case KBD_KP:
+ fnc = NULL;
+ more_chars = NULL;
+
+ if(meta_down)
+ {
+ switch(key)
+ {
+ case 95: /* / */
+ altkpflag = 0;
+ more_chars =
+ (u_char *)"\033OQ";
+ return(more_chars);
+
+ case 100: /* * */
+ altkpflag = 0;
+ more_chars =
+ (u_char *)"\033OR";
+ return(more_chars);
+
+ case 105: /* - */
+ altkpflag = 0;
+ more_chars =
+ (u_char *)"\033OS";
+ return(more_chars);
+ }
+ }
+
+ if(meta_down || altgr_down)
+ {
+ if((n = keypad2num[key-91]) >= 0)
+ {
+ if(!altkpflag)
+ {
+ /* start ALT-KP mode */
+ altkpflag = 1;
+ altkpval = 0;
+ }
+ altkpval *= 10;
+ altkpval += n;
+ }
+ else
+ altkpflag = 0;
+ return 0;
+ }
+
+ if(!(vsp->num_lock))
+ {
+ if(key2ascii[key].shift.subtype == STR)
+ more_chars = (u_char *)thisdef.shift;
+ else
+ fnc = key2ascii[key].shift.what.func;
+ }
+ else
+ {
+ if(key2ascii[key].unshift.subtype == STR)
+ more_chars = (u_char *)thisdef.unshift;
+ else
+ fnc = key2ascii[key].unshift.what.func;
+ }
+
+ if(fnc)
+ (*fnc)(); /* execute function */
+ return(more_chars);
+
+ case KBD_CURSOR:
+ fnc = NULL;
+ more_chars = NULL;
+
+ if(vsp->ckm)
+ {
+ if(key2ascii[key].shift.subtype == STR)
+ more_chars = (u_char *)thisdef.shift;
+ else
+ fnc = key2ascii[key].shift.what.func;
+ }
+ else
+ {
+ if(key2ascii[key].unshift.subtype == STR)
+ more_chars = (u_char *)thisdef.unshift;
+ else
+ fnc = key2ascii[key].unshift.what.func;
+ }
+
+ if(fnc)
+ (*fnc)(); /* execute function */
+ return(more_chars);
+
+ case KBD_NUM: /* special kp-num handling */
+ more_chars = NULL;
+
+ if(meta_down)
+ {
+ more_chars = (u_char *)"\033OP"; /* PF1 */
+ }
+ else
+ {
+ vsp->num_lock ^= 1;
+ update_led();
+ }
+ return(more_chars);
+
+ case KBD_RETURN:
+ more_chars = NULL;
+
+ if(!(vsp->num_lock))
+ {
+ more_chars = (u_char *)thisdef.shift;
+ }
+ else
+ {
+ more_chars = (u_char *)thisdef.unshift;
+ }
+ if(vsp->lnm && (*more_chars == '\r'))
+ {
+ more_chars = (u_char *)"\r\n"; /* CR LF */
+ }
+ if(meta_down)
+ {
+#if PCVT_META_ESC
+ metachar[1] = *more_chars;
+#else
+ metachar[0] = *more_chars | 0x80;
+#endif
+ more_chars = metachar;
+ }
+ return(more_chars);
+
+ case KBD_META: /* these keys are */
+ case KBD_ALTGR: /* handled directly */
+ case KBD_SCROLL: /* by the keyboard */
+ case KBD_CAPS: /* handler - they are */
+ case KBD_SHFTLOCK: /* ignored here */
+ case KBD_CTL:
+ case KBD_NONE:
+ default:
+ return 0;
+ }
+}
+
+/*---------------------------------------------------------------------------*
+ * get keystrokes from the keyboard.
+ * if noblock = 0, wait until a key is pressed.
+ * else return NULL if no characters present.
+ *---------------------------------------------------------------------------*/
+
+#if PCVT_KBD_FIFO
+extern u_char pcvt_kbd_fifo[];
+extern int pcvt_kbd_rptr;
+extern short pcvt_kbd_count;
+#endif
+
+u_char *
+sgetc(int noblock)
+{
+ u_char *cp;
+ u_char dt;
+ u_char key;
+ u_short type;
+
+#if PCVT_KBD_FIFO && PCVT_SLOW_INTERRUPT
+ int s;
+#endif
+
+ static u_char kbd_lastkey = 0; /* last keystroke */
+
+ static struct
+ {
+ u_char extended: 1; /* extended prefix seen */
+ u_char ext1: 1; /* extended prefix 1 seen */
+ u_char breakseen: 1; /* break code seen */
+ u_char vshift: 1; /* virtual shift pending */
+ u_char vcontrol: 1; /* virtual control pending */
+ u_char sysrq: 1; /* sysrq pressed */
+ } kbd_status = {0};
+
+#ifdef XSERVER
+ static char keybuf[2] = {0}; /* the second 0 is a delimiter! */
+#endif /* XSERVER */
+
+loop:
+
+#ifdef XSERVER
+
+#if PCVT_KBD_FIFO
+
+ /* see if there is data from the keyboard available either from */
+ /* the keyboard fifo or from the 8042 keyboard controller */
+
+ if ((( noblock) && (pcvt_kbd_count)) ||
+ ((!noblock) && (inb(CONTROLLER_CTRL) & STATUS_OUTPBF)))
+ {
+ if (!noblock) /* source = 8042 */
+ {
+ PCVT_KBD_DELAY(); /* 7 us delay */
+ dt = inb(CONTROLLER_DATA); /* get from obuf */
+ }
+ else /* source = keyboard fifo */
+ {
+ dt = pcvt_kbd_fifo[pcvt_kbd_rptr++];
+ PCVT_DISABLE_INTR();
+ pcvt_kbd_count--;
+ PCVT_ENABLE_INTR();
+ if (pcvt_kbd_rptr >= PCVT_KBD_FIFO_SZ)
+ pcvt_kbd_rptr = 0;
+ }
+
+#else /* !PCVT_KB_FIFO */
+
+ /* see if there is data from the keyboard available from the 8042 */
+
+ if (inb(CONTROLLER_CTRL) & STATUS_OUTPBF)
+ {
+ PCVT_KBD_DELAY(); /* 7 us delay */
+ dt = inb(CONTROLLER_DATA); /* yes, get data */
+
+#endif /* !PCVT_KBD_FIFO */
+
+ /*
+ * If x mode is active, only care for locking keys, then
+ * return the scan code instead of any key translation.
+ * Additionally, this prevents us from any attempts to
+ * execute pcvt internal functions caused by keys (such
+ * as screen flipping).
+ */
+
+ if (vsp->kbd_state == K_RAW)
+ {
+ keybuf[0] = dt;
+
+#if PCVT_EMU_MOUSE
+ /*
+ * The (mouse systems) mouse emulator. The mouse
+ * device allocates the first device node that is
+ * not used by a virtual terminal. (E.g., you have
+ * eight vtys, /dev/ttyv0 thru /dev/ttyv7, so the
+ * mouse emulator were /dev/ttyv8.)
+ * Currently the emulator only works if the keyboard
+ * is in raw (PC scan code) mode. This is the typic-
+ * al case when running the X server.
+ * It is activated if the num locks LED is active
+ * for the current vty, and if the mouse device
+ * has been opened by at least one process. It
+ * grabs the numerical keypad events (but only
+ * the "non-extended", so the separate arrow keys
+ * continue to work), and three keys for the "mouse
+ * buttons", preferrably F1 thru F3. Any of the
+ * eight directions (N, NE, E, SE, S, SW, W, NW)
+ * is supported, and frequent key presses (less
+ * than e.g. half a second between key presses)
+ * cause the emulator to accelerate the pointer
+ * movement by 6, while single presses result in
+ * single moves, so each point can be reached.
+ */
+ /*
+ * NB: the following code is spagghetti.
+ * Only eat it with lotta tomato ketchup and
+ * Parmesan cheese:-)
+ */
+ /*
+ * look whether we will have to steal the keys
+ * and cook them into mouse events
+ */
+ if(vsp->num_lock && mouse.opened)
+ {
+ int button, accel, i;
+ enum mouse_dir
+ {
+ MOUSE_NW, MOUSE_N, MOUSE_NE,
+ MOUSE_W, MOUSE_0, MOUSE_E,
+ MOUSE_SW, MOUSE_S, MOUSE_SE
+ }
+ move;
+ struct timeval now;
+ /* from sys/kern/kern_time.c */
+ extern void timevalsub
+ (struct timeval *, struct timeval *);
+ dev_t dummy = makedev(0, mouse.minor);
+ struct tty *mousetty = get_pccons(dummy);
+ /*
+ * strings to send for each mouse event,
+ * indexed by the movement direction and
+ * the "accelerator" value (TRUE for frequent
+ * key presses); note that the first byte
+ * of each string is actually overwritten
+ * by the current button value before sending
+ * the string
+ */
+ static u_char mousestrings[2][MOUSE_SE+1][5] =
+ {
+ {
+ /* first, the non-accelerated strings*/
+ {0x87, -1, 1, 0, 0}, /* NW */
+ {0x87, 0, 1, 0, 0}, /* N */
+ {0x87, 1, 1, 0, 0}, /* NE */
+ {0x87, -1, 0, 0, 0}, /* W */
+ {0x87, 0, 0, 0, 0}, /* 0 */
+ {0x87, 1, 0, 0, 0}, /* E */
+ {0x87, -1, -1, 0, 0}, /* SW */
+ {0x87, 0, -1, 0, 0}, /* S */
+ {0x87, 1, -1, 0, 0} /* SE */
+ },
+ {
+ /* now, 6 steps at once */
+ {0x87, -4, 4, 0, 0}, /* NW */
+ {0x87, 0, 6, 0, 0}, /* N */
+ {0x87, 4, 4, 0, 0}, /* NE */
+ {0x87, -6, 0, 0, 0}, /* W */
+ {0x87, 0, 0, 0, 0}, /* 0 */
+ {0x87, 6, 0, 0, 0}, /* E */
+ {0x87, -4, -4, 0, 0}, /* SW */
+ {0x87, 0, -6, 0, 0}, /* S */
+ {0x87, 4, -4, 0, 0} /* SE */
+ }
+ };
+
+ if(dt == 0xe0)
+ {
+ /* ignore extended scan codes */
+ mouse.extendedseen = 1;
+ goto no_mouse_event;
+ }
+ if(mouse.extendedseen)
+ {
+ mouse.extendedseen = 0;
+ goto no_mouse_event;
+ }
+ mouse.extendedseen = 0;
+
+ /*
+ * Note that we cannot use a switch here
+ * since we want to have the keycodes in
+ * a variable
+ */
+ if((dt & 0x7f) == mousedef.leftbutton) {
+ button = 4;
+ goto do_button;
+ }
+ else if((dt & 0x7f) == mousedef.middlebutton) {
+ button = 2;
+ goto do_button;
+ }
+ else if((dt & 0x7f) == mousedef.rightbutton) {
+ button = 1;
+ do_button:
+
+ /*
+ * i would really like to give
+ * some acustical support
+ * (pling/plong); i am not sure
+ * whether it is safe to call
+ * sysbeep from within an intr
+ * service, since it calls
+ * timeout in turn which mani-
+ * pulates the spl mask - jw
+ */
+
+# define PLING sysbeep(PCVT_SYSBEEPF / 1500, 2)
+# define PLONG sysbeep(PCVT_SYSBEEPF / 1200, 2)
+
+ if(mousedef.stickybuttons)
+ {
+ if(dt & 0x80) {
+ mouse.breakseen = 1;
+ return (u_char *)0;
+ }
+ else if(mouse.buttons == button
+ && !mouse.breakseen) {
+ /* ignore repeats */
+ return (u_char *)0;
+ }
+ else
+ mouse.breakseen = 0;
+ if(mouse.buttons == button) {
+ /* release it */
+ mouse.buttons = 0;
+ PLONG;
+ } else {
+ /*
+ * eventually, release
+ * any other button,
+ * and stick this one
+ */
+ mouse.buttons = button;
+ PLING;
+ }
+ }
+ else
+ {
+ if(dt & 0x80) {
+ mouse.buttons &=
+ ~button;
+ PLONG;
+ }
+ else if((mouse.buttons
+ & button) == 0) {
+ mouse.buttons |=
+ button;
+ PLING;
+ }
+ /*else: ignore same btn press*/
+ }
+ move = MOUSE_0;
+ accel = 0;
+ }
+# undef PLING
+# undef PLONG
+ else switch(dt & 0x7f)
+ {
+ /* the arrow keys - KP 1 thru KP 9 */
+ case 0x47: move = MOUSE_NW; goto do_move;
+ case 0x48: move = MOUSE_N; goto do_move;
+ case 0x49: move = MOUSE_NE; goto do_move;
+ case 0x4b: move = MOUSE_W; goto do_move;
+ case 0x4c: move = MOUSE_0; goto do_move;
+ case 0x4d: move = MOUSE_E; goto do_move;
+ case 0x4f: move = MOUSE_SW; goto do_move;
+ case 0x50: move = MOUSE_S; goto do_move;
+ case 0x51: move = MOUSE_SE;
+ do_move:
+ if(dt & 0x80)
+ /*
+ * arrow key break events are
+ * of no importance for us
+ */
+ return (u_char *)0;
+ /*
+ * see whether the last move did
+ * happen "recently", i.e. before
+ * less than half a second
+ */
+ now = time;
+ timevalsub(&now, &mouse.lastmove);
+ mouse.lastmove = time;
+ accel = (now.tv_sec == 0
+ && now.tv_usec
+ < mousedef.acceltime);
+ break;
+
+ default: /* not a mouse-emulating key */
+ goto no_mouse_event;
+ }
+ mousestrings[accel][move][0] =
+ 0x80 + (~mouse.buttons & 7);
+ /* finally, send the string */
+ for(i = 0; i < 5; i++)
+ (*linesw[mousetty->t_line].l_rint)
+ (mousestrings[accel][move][i],
+ mousetty);
+ return (u_char *)0; /* not a kbd event */
+ }
+no_mouse_event:
+
+#endif /* PCVT_EMU_MOUSE */
+
+ return ((u_char *)keybuf);
+ }
+ }
+
+#else /* !XSERVER */
+
+# if PCVT_KBD_FIFO
+
+ /* see if there is data from the keyboard available either from */
+ /* the keyboard fifo or from the 8042 keyboard controller */
+
+ if ((( noblock) && (pcvt_kbd_count)) ||
+ ((!noblock) && (inb(CONTROLLER_CTRL) & STATUS_OUTPBF)))
+ {
+ if (!noblock) /* source = 8042 */
+ {
+ PCVT_KBD_DELAY(); /* 7 us delay */
+ dt = inb(CONTROLLER_DATA);
+ }
+ else /* source = keyboard fifo */
+ {
+ dt = pcvt_kbd_fifo[pcvt_kbd_rptr++]; /* yes, get it ! */
+ PCVT_DISABLE_INTR();
+ pcvt_kbd_count--;
+ PCVT_ENABLE_INTR();
+ if (pcvt_kbd_rptr >= PCVT_KBD_FIFO_SZ)
+ pcvt_kbd_rptr = 0;
+ }
+ }
+
+#else /* !PCVT_KBD_FIFO */
+
+ /* see if there is data from the keyboard available from the 8042 */
+
+ if(inb(CONTROLLER_CTRL) & STATUS_OUTPBF)
+ {
+ PCVT_KBD_DELAY(); /* 7 us delay */
+ dt = inb(CONTROLLER_DATA); /* yes, get data ! */
+ }
+
+#endif /* !PCVT_KBD_FIFO */
+
+#endif /* !XSERVER */
+
+ else
+ {
+ if(noblock)
+ return NULL;
+ else
+ goto loop;
+ }
+
+#if PCVT_SHOWKEYS
+ showkey (' ', dt);
+#endif /* PCVT_SHOWKEYS */
+
+ /* lets look what we got */
+ switch(dt)
+ {
+ case KEYB_R_OVERRUN0: /* keyboard buffer overflow */
+
+#if PCVT_SCANSET == 2
+ case KEYB_R_SELFOK: /* keyboard selftest ok */
+#endif /* PCVT_SCANSET == 2 */
+
+ case KEYB_R_ECHO: /* keyboard response to KEYB_C_ECHO */
+ case KEYB_R_ACK: /* acknowledge after command has rx'd*/
+ case KEYB_R_SELFBAD: /* keyboard selftest FAILED */
+ case KEYB_R_DIAGBAD: /* keyboard self diagnostic failure */
+ case KEYB_R_RESEND: /* keyboard wants us to resend cmnd */
+ case KEYB_R_OVERRUN1: /* keyboard buffer overflow */
+ break;
+
+ case KEYB_R_EXT1: /* keyboard extended scancode pfx 2 */
+ kbd_status.ext1 = 1;
+ /* FALLTHROUGH */
+ case KEYB_R_EXT0: /* keyboard extended scancode pfx 1 */
+ kbd_status.extended = 1;
+ break;
+
+#if PCVT_SCANSET == 2
+ case KEYB_R_BREAKPFX: /* break code prefix for set 2 and 3 */
+ kbd_status.breakseen = 1;
+ break;
+#endif /* PCVT_SCANSET == 2 */
+
+ default:
+ goto regular; /* regular key */
+ }
+
+ if(noblock)
+ return NULL;
+ else
+ goto loop;
+
+ /* got a normal scan key */
+regular:
+
+#if PCVT_SCANSET == 1
+ kbd_status.breakseen = dt & 0x80 ? 1 : 0;
+ dt &= 0x7f;
+#endif /* PCVT_SCANSET == 1 */
+
+ /* make a keycode from scan code */
+ if(dt >= sizeof scantokey / sizeof(u_char))
+ key = 0;
+ else
+ key = kbd_status.extended ? extscantokey[dt] : scantokey[dt];
+
+ if(kbd_status.ext1 && key == 64)
+ /* virtual control key */
+ key = 129;
+
+ kbd_status.extended = kbd_status.ext1 = 0;
+
+#if PCVT_CTRL_ALT_DEL /* Check for cntl-alt-del */
+ if((key == 76) && ctrl_down && (meta_down||altgr_down))
+ cpu_reset();
+#endif /* PCVT_CTRL_ALT_DEL */
+
+#if !(PCVT_NETBSD || PCVT_FREEBSD >= 200)
+#include "ddb.h"
+#endif /* !(PCVT_NETBSD || PCVT_FREEBSD >= 200) */
+
+#if NDDB > 0 || defined(DDB) /* Check for cntl-alt-esc */
+
+ if((key == 110) && ctrl_down && (meta_down || altgr_down))
+ {
+ static u_char in_Debugger;
+
+ if(!in_Debugger)
+ {
+ in_Debugger = 1;
+#if PCVT_FREEBSD
+ /* the string is actually not used... */
+ Debugger("kbd");
+#else
+ Debugger();
+#endif
+ in_Debugger = 0;
+ if(noblock)
+ return NULL;
+ else
+ goto loop;
+ }
+ }
+#endif /* NDDB > 0 || defined(DDB) */
+
+ /* look for keys with special handling */
+ if(key == 128)
+ {
+ /*
+ * virtual shift; sent around PrtScr, and around the arrow
+ * keys if the NumLck LED is on
+ */
+ kbd_status.vshift = !kbd_status.breakseen;
+ key = 0; /* no key */
+ }
+ else if(key == 129)
+ {
+ /*
+ * virtual control - the most ugly thingie at all
+ * the Pause key sends:
+ * <virtual control make> <numlock make> <virtual control
+ * break> <numlock break>
+ */
+ if(!kbd_status.breakseen)
+ kbd_status.vcontrol = 1;
+ /* else: let the numlock hook clear this */
+ key = 0; /* no key */
+ }
+ else if(key == 90)
+ {
+ /* NumLock, look whether this is rather a Pause */
+ if(kbd_status.vcontrol)
+ key = 126;
+ /*
+ * if this is the final break code of a Pause key,
+ * clear the virtual control status, too
+ */
+ if(kbd_status.vcontrol && kbd_status.breakseen)
+ kbd_status.vcontrol = 0;
+ }
+ else if(key == 127)
+ {
+ /*
+ * a SysRq; some keyboards are brain-dead enough to
+ * repeat the SysRq key make code by sending PrtScr
+ * make codes; other keyboards do not repeat SysRq
+ * at all. We keep track of the SysRq state here.
+ */
+ kbd_status.sysrq = !kbd_status.breakseen;
+ }
+ else if(key == 124)
+ {
+ /*
+ * PrtScr; look whether this is really PrtScr or rather
+ * a silly repeat of a SysRq key
+ */
+ if(kbd_status.sysrq)
+ /* ignore the garbage */
+ key = 0;
+ }
+
+ /* in NOREPEAT MODE ignore the key if it was the same as before */
+
+ if(!kbrepflag && key == kbd_lastkey && !kbd_status.breakseen)
+ {
+ if(noblock)
+ return NULL;
+ else
+ goto loop;
+ }
+
+ type = key2ascii[key].type;
+
+ if(type & KBD_OVERLOAD)
+ type = ovltbl[key2ascii[key].ovlindex].type;
+
+ type &= KBD_MASK;
+
+ switch(type)
+ {
+ case KBD_SHFTLOCK:
+ if(!kbd_status.breakseen && key != kbd_lastkey)
+ {
+ vsp->shift_lock ^= 1;
+ }
+ break;
+
+ case KBD_CAPS:
+ if(!kbd_status.breakseen && key != kbd_lastkey)
+ {
+ vsp->caps_lock ^= 1;
+ update_led();
+ }
+ break;
+
+ case KBD_SCROLL:
+ if(!kbd_status.breakseen && key != kbd_lastkey)
+ {
+ vsp->scroll_lock ^= 1;
+ update_led();
+
+ if(!(vsp->scroll_lock))
+ {
+ /* someone may be sleeping */
+ wakeup((caddr_t)&(vsp->scroll_lock));
+ }
+ }
+ break;
+
+ case KBD_SHIFT:
+ shift_down = kbd_status.breakseen ? 0 : 1;
+ break;
+
+ case KBD_META:
+ meta_down = kbd_status.breakseen ? 0 : 0x80;
+ break;
+
+ case KBD_ALTGR:
+ altgr_down = kbd_status.breakseen ? 0 : 1;
+ break;
+
+ case KBD_CTL:
+ ctrl_down = kbd_status.breakseen ? 0 : 1;
+ break;
+
+ case KBD_NONE:
+ default:
+ break; /* deliver a key */
+ }
+
+ if(kbd_status.breakseen)
+ {
+ key |= 0x80;
+ kbd_status.breakseen = 0;
+ kbd_lastkey = 0; /* -hv- I know this is a bug with */
+ } /* N-Key-Rollover, but I ignore that */
+ else /* because avoidance is too complicated */
+ kbd_lastkey = key;
+
+ cp = xlatkey2ascii(key); /* have a key */
+
+ if(cp == NULL && !noblock)
+ goto loop;
+
+ return cp;
+}
+
+/*---------------------------------------------------------------------------*
+ * reflect status of locking keys & set led's
+ *---------------------------------------------------------------------------*/
+static void
+setlockkeys(int snc)
+{
+ vsp->scroll_lock = snc & 1;
+ vsp->num_lock = (snc & 2) ? 1 : 0;
+ vsp->caps_lock = (snc & 4) ? 1 : 0;
+ update_led();
+}
+
+/*---------------------------------------------------------------------------*
+ * remove a key definition
+ *---------------------------------------------------------------------------*/
+static int
+rmkeydef(int key)
+{
+ register Ovl_tbl *ref;
+
+ if(key==0 || key > MAXKEYNUM)
+ return EINVAL;
+
+ if(key2ascii[key].type & KBD_OVERLOAD)
+ {
+ ref = &ovltbl[key2ascii[key].ovlindex];
+ ref->keynum = 0;
+ ref->type = 0;
+ ref->unshift[0] =
+ ref->shift[0] =
+ ref->ctrl[0] =
+ ref->altgr[0] = 0;
+ key2ascii[key].type &= KBD_MASK;
+ }
+ return 0;
+}
+
+/*---------------------------------------------------------------------------*
+ * overlay a key
+ *---------------------------------------------------------------------------*/
+static int
+setkeydef(Ovl_tbl *data)
+{
+ register i;
+
+ if( data->keynum > MAXKEYNUM ||
+ (data->type & KBD_MASK) == KBD_BREAK ||
+ (data->type & KBD_MASK) > KBD_SHFTLOCK)
+ return EINVAL;
+
+ data->unshift[KBDMAXOVLKEYSIZE] =
+ data->shift[KBDMAXOVLKEYSIZE] =
+ data->ctrl[KBDMAXOVLKEYSIZE] =
+ data->altgr[KBDMAXOVLKEYSIZE] = 0;
+
+ data->subu =
+ data->subs =
+ data->subc =
+ data->suba = KBD_SUBT_STR; /* just strings .. */
+
+ data->type |= KBD_OVERLOAD; /* mark overloaded */
+
+ /* if key already overloaded, use that slot else find free slot */
+
+ if(key2ascii[data->keynum].type & KBD_OVERLOAD)
+ {
+ i = key2ascii[data->keynum].ovlindex;
+ }
+ else
+ {
+ for(i=0; i<OVLTBL_SIZE; i++)
+ if(ovltbl[i].keynum==0)
+ break;
+
+ if(i==OVLTBL_SIZE)
+ return ENOSPC; /* no space, abuse of ENOSPC(!) */
+ }
+
+ ovltbl[i] = *data; /* copy new data string */
+
+ key2ascii[data->keynum].type |= KBD_OVERLOAD; /* mark key */
+ key2ascii[data->keynum].ovlindex = i;
+
+ return 0;
+}
+
+/*---------------------------------------------------------------------------*
+ * keyboard ioctl's entry
+ *---------------------------------------------------------------------------*/
+int
+kbdioctl(Dev_t dev, int cmd, caddr_t data, int flag)
+{
+ int key;
+
+ switch(cmd)
+ {
+ case KBDRESET:
+ doreset();
+ ovlinit(1);
+ settpmrate(KBD_TPD500|KBD_TPM100);
+ setlockkeys(0);
+ break;
+
+ case KBDGTPMAT:
+ *(int *)data = tpmrate;
+ break;
+
+ case KBDSTPMAT:
+ settpmrate(*(int *)data);
+ break;
+
+ case KBDGREPSW:
+ *(int *)data = kbrepflag;
+ break;
+
+ case KBDSREPSW:
+ kbrepflag = (*(int *)data) & 1;
+ break;
+
+ case KBDGLOCK:
+ *(int *)data = ( (vsp->scroll_lock) |
+ (vsp->num_lock * 2) |
+ (vsp->caps_lock * 4));
+ break;
+
+ case KBDSLOCK:
+ setlockkeys(*(int *)data);
+ break;
+
+ case KBDGCKEY:
+ key = ((Ovl_tbl *)data)->keynum;
+ return getckeydef(key,(Ovl_tbl *)data);
+
+ case KBDSCKEY:
+ key = ((Ovl_tbl *)data)->keynum;
+ return setkeydef((Ovl_tbl *)data);
+
+ case KBDGOKEY:
+ key = ((Ovl_tbl *)data)->keynum;
+ return getokeydef(key,(Ovl_tbl *)data);
+
+ case KBDRMKEY:
+ key = *(int *)data;
+ return rmkeydef(key);
+
+ case KBDDEFAULT:
+ ovlinit(1);
+ break;
+
+ default:
+ /* proceed with vga ioctls */
+ return -1;
+ }
+ return 0;
+}
+
+#if PCVT_EMU_MOUSE
+/*--------------------------------------------------------------------------*
+ * mouse emulator ioctl
+ *--------------------------------------------------------------------------*/
+int
+mouse_ioctl(Dev_t dev, int cmd, caddr_t data)
+{
+ struct mousedefs *def = (struct mousedefs *)data;
+
+ switch(cmd)
+ {
+ case KBDMOUSEGET:
+ *def = mousedef;
+ break;
+
+ case KBDMOUSESET:
+ mousedef = *def;
+ break;
+
+ default:
+ return -1;
+ }
+ return 0;
+}
+#endif /* PCVT_EMU_MOUSE */
+
+/*---------------------------------------------------------------------------*
+ * convert ISO-8859 style keycode into IBM 437
+ *---------------------------------------------------------------------------*/
+static inline u_char
+iso2ibm(u_char c)
+{
+ if(c < 0x80)
+ return c;
+ return iso2ibm437[c - 0x80];
+}
+
+/*---------------------------------------------------------------------------*
+ * build up a USL style keyboard map
+ *---------------------------------------------------------------------------*/
+void
+get_usl_keymap(keymap_t *map)
+{
+ int i;
+
+ bzero((caddr_t)map, sizeof(keymap_t));
+
+ map->n_keys = 0x59; /* that many keys we know about */
+
+ for(i = 1; i < N_KEYNUMS; i++)
+ {
+ Ovl_tbl kdef;
+ u_char c;
+ int j;
+ int idx = key2scan1[i];
+
+ if(idx == 0 || idx >= map->n_keys)
+ continue;
+
+ getckeydef(i, &kdef);
+ kdef.type &= KBD_MASK;
+ switch(kdef.type)
+ {
+ case KBD_ASCII:
+ case KBD_RETURN:
+ map->key[idx].map[0] = iso2ibm(kdef.unshift[0]);
+ map->key[idx].map[1] = iso2ibm(kdef.shift[0]);
+ map->key[idx].map[2] = map->key[idx].map[3] =
+ iso2ibm(kdef.ctrl[0]);
+ map->key[idx].map[4] = map->key[idx].map[5] =
+ iso2ibm(c = kdef.altgr[0]);
+ /*
+ * XXX this is a hack
+ * since we currently do not map strings to AltGr +
+ * shift, we attempt to use the unshifted AltGr
+ * definition here and try to toggle the case
+ * this should at least work for ISO8859 letters,
+ * but also for (e.g.) russian KOI-8 style
+ */
+ if((c & 0x7f) >= 0x40)
+ map->key[idx].map[5] = iso2ibm(c ^ 0x20);
+ break;
+
+ case KBD_FUNC:
+ /* we are only interested in F1 thru F12 here */
+ if(i >= 112 && i <= 123) {
+ map->key[idx].map[0] = i - 112 + 27;
+ map->key[idx].spcl = 0x80;
+ }
+ break;
+
+ case KBD_SHIFT:
+ c = i == 44? 2 /* lSh */: 3 /* rSh */; goto special;
+
+ case KBD_CAPS:
+ c = 4; goto special;
+
+ case KBD_NUM:
+ c = 5; goto special;
+
+ case KBD_SCROLL:
+ c = 6; goto special;
+
+ case KBD_META:
+ c = 7; goto special;
+
+ case KBD_CTL:
+ c = 9; goto special;
+ special:
+ for(j = 0; j < NUM_STATES; j++)
+ map->key[idx].map[j] = c;
+ map->key[idx].spcl = 0xff;
+ break;
+
+ default:
+ break;
+ }
+ }
+}
+
+/*---------------------------------------------------------------------------*
+ * switch keypad to numeric mode
+ *---------------------------------------------------------------------------*/
+void
+vt_keynum(struct video_state *svsp)
+{
+ svsp->num_lock = 1;
+ update_led();
+}
+
+/*---------------------------------------------------------------------------*
+ * switch keypad to application mode
+ *---------------------------------------------------------------------------*/
+void
+vt_keyappl(struct video_state *svsp)
+{
+ svsp->num_lock = 0;
+ update_led();
+}
+
+#if !PCVT_VT220KEYB /* !PCVT_VT220KEYB, HP-like Keyboard layout */
+
+/*---------------------------------------------------------------------------*
+ * function bound to function key 1
+ *---------------------------------------------------------------------------*/
+static void
+fkey1(void)
+{
+ if(!meta_down)
+ {
+ if((vsp->vt_pure_mode == M_HPVT)
+ && (vsp->which_fkl == SYS_FKL))
+ toggl_columns(vsp);
+ else
+ more_chars = (u_char *)"\033[17~"; /* F6 */
+ }
+ else
+ {
+ if(vsp->vt_pure_mode == M_PUREVT
+ || (vsp->which_fkl == USR_FKL))
+ more_chars = (u_char *)"\033[26~"; /* F14 */
+ }
+}
+
+/*---------------------------------------------------------------------------*
+ * function bound to function key 2
+ *---------------------------------------------------------------------------*/
+static void
+fkey2(void)
+{
+ if(!meta_down)
+ {
+ if((vsp->vt_pure_mode == M_HPVT)
+ && (vsp->which_fkl == SYS_FKL))
+ vt_ris(vsp);
+ else
+ more_chars = (u_char *)"\033[18~"; /* F7 */
+ }
+ else
+ {
+ if(vsp->vt_pure_mode == M_PUREVT
+ || (vsp->which_fkl == USR_FKL))
+ more_chars = (u_char *)"\033[28~"; /* HELP */
+ }
+}
+
+/*---------------------------------------------------------------------------*
+ * function bound to function key 3
+ *---------------------------------------------------------------------------*/
+static void
+fkey3(void)
+{
+ if(!meta_down)
+ {
+ if((vsp->vt_pure_mode == M_HPVT)
+ && (vsp->which_fkl == SYS_FKL))
+ toggl_24l(vsp);
+ else
+ more_chars = (u_char *)"\033[19~"; /* F8 */
+ }
+ else
+ {
+ if(vsp->vt_pure_mode == M_PUREVT
+ || (vsp->which_fkl == USR_FKL))
+ more_chars = (u_char *)"\033[29~"; /* DO */
+ }
+}
+
+/*---------------------------------------------------------------------------*
+ * function bound to function key 4
+ *---------------------------------------------------------------------------*/
+static void
+fkey4(void)
+{
+ if(!meta_down)
+ {
+
+#if PCVT_SHOWKEYS
+ if((vsp->vt_pure_mode == M_HPVT)
+ && (vsp->which_fkl == SYS_FKL))
+ toggl_kbddbg(vsp);
+ else
+ more_chars = (u_char *)"\033[20~"; /* F9 */
+#else
+ if(vsp->vt_pure_mode == M_PUREVT
+ || (vsp->which_fkl == USR_FKL))
+ more_chars = (u_char *)"\033[20~"; /* F9 */
+#endif /* PCVT_SHOWKEYS */
+
+ }
+ else
+ {
+ if(vsp->vt_pure_mode == M_PUREVT
+ || (vsp->which_fkl == USR_FKL))
+ more_chars = (u_char *)"\033[31~"; /* F17 */
+ }
+}
+
+/*---------------------------------------------------------------------------*
+ * function bound to function key 5
+ *---------------------------------------------------------------------------*/
+static void
+fkey5(void)
+{
+ if(!meta_down)
+ {
+ if((vsp->vt_pure_mode == M_HPVT)
+ && (vsp->which_fkl == SYS_FKL))
+ toggl_bell(vsp);
+ else
+ more_chars = (u_char *)"\033[21~"; /* F10 */
+ }
+ else
+ {
+ if(vsp->vt_pure_mode == M_PUREVT
+ || (vsp->which_fkl == USR_FKL))
+ more_chars = (u_char *)"\033[32~"; /* F18 */
+ }
+}
+
+/*---------------------------------------------------------------------------*
+ * function bound to function key 6
+ *---------------------------------------------------------------------------*/
+static void
+fkey6(void)
+{
+ if(!meta_down)
+ {
+ if((vsp->vt_pure_mode == M_HPVT)
+ && (vsp->which_fkl == SYS_FKL))
+ toggl_sevenbit(vsp);
+ else
+ more_chars = (u_char *)"\033[23~"; /* F11 */
+ }
+ else
+ {
+ if(vsp->vt_pure_mode == M_PUREVT
+ || (vsp->which_fkl == USR_FKL))
+ more_chars = (u_char *)"\033[33~"; /* F19 */
+ }
+}
+
+/*---------------------------------------------------------------------------*
+ * function bound to function key 7
+ *---------------------------------------------------------------------------*/
+static void
+fkey7(void)
+{
+ if(!meta_down)
+ {
+ if((vsp->vt_pure_mode == M_HPVT)
+ && (vsp->which_fkl == SYS_FKL))
+ toggl_dspf(vsp);
+ else
+ more_chars = (u_char *)"\033[24~"; /* F12 */
+ }
+ else
+ {
+ if(vsp->vt_pure_mode == M_PUREVT
+ || (vsp->which_fkl == USR_FKL))
+ more_chars = (u_char *)"\033[34~"; /* F20 */
+ }
+}
+
+/*---------------------------------------------------------------------------*
+ * function bound to function key 8
+ *---------------------------------------------------------------------------*/
+static void
+fkey8(void)
+{
+ if(!meta_down)
+ {
+ if((vsp->vt_pure_mode == M_HPVT)
+ && (vsp->which_fkl == SYS_FKL))
+ toggl_awm(vsp);
+ else
+ more_chars = (u_char *)"\033[25~"; /* F13 */
+ }
+ else
+ {
+ if(vsp->vt_pure_mode == M_PUREVT
+ || (vsp->which_fkl == USR_FKL))
+ more_chars = (u_char *)"\033[35~"; /* F21 ??!! */
+ }
+}
+
+/*---------------------------------------------------------------------------*
+ * function bound to function key 9
+ *---------------------------------------------------------------------------*/
+static void
+fkey9(void)
+{
+ if(meta_down)
+ {
+ if(vsp->vt_pure_mode == M_PUREVT)
+ return;
+
+ if(vsp->labels_on) /* toggle label display on/off */
+ fkl_off(vsp);
+ else
+ fkl_on(vsp);
+ }
+ else
+ {
+ do_vgapage(0);
+ }
+}
+
+/*---------------------------------------------------------------------------*
+ * function bound to function key 10
+ *---------------------------------------------------------------------------*/
+static void
+fkey10(void)
+{
+ if(meta_down)
+ {
+ if(vsp->vt_pure_mode != M_PUREVT && vsp->labels_on)
+ {
+ if(vsp->which_fkl == USR_FKL)
+ sw_sfkl(vsp);
+ else if(vsp->which_fkl == SYS_FKL)
+ sw_ufkl(vsp);
+ }
+ }
+ else
+ {
+ do_vgapage(1);
+ }
+}
+
+/*---------------------------------------------------------------------------*
+ * function bound to function key 11
+ *---------------------------------------------------------------------------*/
+static void
+fkey11(void)
+{
+ if(meta_down)
+ {
+ if(vsp->vt_pure_mode == M_PUREVT)
+ set_emulation_mode(vsp, M_HPVT);
+ else if(vsp->vt_pure_mode == M_HPVT)
+ set_emulation_mode(vsp, M_PUREVT);
+ }
+ else
+ {
+ do_vgapage(2);
+ }
+}
+
+/*---------------------------------------------------------------------------*
+ * function bound to function key 12
+ *---------------------------------------------------------------------------*/
+static void
+fkey12(void)
+{
+ if(meta_down)
+ {
+ if(current_video_screen + 1 > totalscreens-1)
+ do_vgapage(0);
+ else
+ do_vgapage(current_video_screen + 1);
+ }
+ else
+ {
+ do_vgapage(3);
+ }
+}
+
+/*---------------------------------------------------------------------------*
+ * function bound to SHIFTED function key 1
+ *---------------------------------------------------------------------------*/
+static void
+sfkey1(void)
+{
+ if(!meta_down)
+ {
+ if(vsp->ukt.length[0]) /* entry available ? */
+ more_chars = (u_char *)
+ &(vsp->udkbuf[vsp->ukt.first[0]]);
+ }
+ else
+ {
+ if(vsp->ukt.length[9]) /* entry available ? */
+ more_chars = (u_char *)
+ &(vsp->udkbuf[vsp->ukt.first[9]]);
+ }
+}
+
+/*---------------------------------------------------------------------------*
+ * function bound to SHIFTED function key 2
+ *---------------------------------------------------------------------------*/
+static void
+sfkey2(void)
+{
+ if(!meta_down)
+ {
+ if(vsp->ukt.length[1]) /* entry available ? */
+ more_chars = (u_char *)
+ &(vsp->udkbuf[vsp->ukt.first[1]]);
+ }
+ else
+ {
+ if(vsp->ukt.length[11]) /* entry available ? */
+ more_chars = (u_char *)
+ &(vsp->udkbuf[vsp->ukt.first[11]]);
+ }
+}
+
+/*---------------------------------------------------------------------------*
+ * function bound to SHIFTED function key 3
+ *---------------------------------------------------------------------------*/
+static void
+sfkey3(void)
+{
+ if(!meta_down)
+ {
+ if(vsp->ukt.length[2]) /* entry available ? */
+ more_chars = (u_char *)
+ &(vsp->udkbuf[vsp->ukt.first[2]]);
+ }
+ else
+ {
+ if(vsp->ukt.length[12]) /* entry available ? */
+ more_chars = (u_char *)
+ &(vsp->udkbuf[vsp->ukt.first[12]]);
+ }
+}
+
+/*---------------------------------------------------------------------------*
+ * function bound to SHIFTED function key 4
+ *---------------------------------------------------------------------------*/
+static void
+sfkey4(void)
+{
+ if(!meta_down)
+ {
+ if(vsp->ukt.length[3]) /* entry available ? */
+ more_chars = (u_char *)
+ &(vsp->udkbuf[vsp->ukt.first[3]]);
+ }
+ else
+ {
+ if(vsp->ukt.length[13]) /* entry available ? */
+ more_chars = (u_char *)
+ &(vsp->udkbuf[vsp->ukt.first[13]]);
+ }
+}
+
+/*---------------------------------------------------------------------------*
+ * function bound to SHIFTED function key 5
+ *---------------------------------------------------------------------------*/
+static void
+sfkey5(void)
+{
+ if(!meta_down)
+ {
+ if(vsp->ukt.length[4]) /* entry available ? */
+ more_chars = (u_char *)
+ &(vsp->udkbuf[vsp->ukt.first[4]]);
+ }
+ else
+ {
+ if(vsp->ukt.length[14]) /* entry available ? */
+ more_chars = (u_char *)
+ &(vsp->udkbuf[vsp->ukt.first[14]]);
+ }
+}
+
+/*---------------------------------------------------------------------------*
+ * function bound to SHIFTED function key 6
+ *---------------------------------------------------------------------------*/
+static void
+sfkey6(void)
+{
+ if(!meta_down)
+ {
+ if(vsp->ukt.length[6]) /* entry available ? */
+ more_chars = (u_char *)
+ &(vsp->udkbuf[vsp->ukt.first[6]]);
+ }
+ else
+ {
+ if(vsp->ukt.length[15]) /* entry available ? */
+ more_chars = (u_char *)
+ &(vsp->udkbuf[vsp->ukt.first[15]]);
+ }
+}
+
+/*---------------------------------------------------------------------------*
+ * function bound to SHIFTED function key 7
+ *---------------------------------------------------------------------------*/
+static void
+sfkey7(void)
+{
+ if(!meta_down)
+ {
+ if(vsp->ukt.length[7]) /* entry available ? */
+ more_chars = (u_char *)
+ &(vsp->udkbuf[vsp->ukt.first[7]]);
+ }
+ else
+ {
+ if(vsp->ukt.length[16]) /* entry available ? */
+ more_chars = (u_char *)
+ &(vsp->udkbuf[vsp->ukt.first[16]]);
+ }
+}
+
+/*---------------------------------------------------------------------------*
+ * function bound to SHIFTED function key 8
+ *---------------------------------------------------------------------------*/
+static void
+sfkey8(void)
+{
+ if(!meta_down)
+ {
+ if(vsp->ukt.length[8]) /* entry available ? */
+ more_chars = (u_char *)
+ &(vsp->udkbuf[vsp->ukt.first[8]]);
+ }
+ else
+ {
+ if(vsp->ukt.length[17]) /* entry available ? */
+ more_chars = (u_char *)
+ &(vsp->udkbuf[vsp->ukt.first[17]]);
+ }
+}
+/*---------------------------------------------------------------------------*
+ * function bound to SHIFTED function key 9
+ *---------------------------------------------------------------------------*/
+static void
+sfkey9(void)
+{
+}
+
+/*---------------------------------------------------------------------------*
+ * function bound to SHIFTED function key 10
+ *---------------------------------------------------------------------------*/
+static void
+sfkey10(void)
+{
+}
+
+/*---------------------------------------------------------------------------*
+ * function bound to SHIFTED function key 11
+ *---------------------------------------------------------------------------*/
+static void
+sfkey11(void)
+{
+}
+
+/*---------------------------------------------------------------------------*
+ * function bound to SHIFTED function key 12
+ *---------------------------------------------------------------------------*/
+static void
+sfkey12(void)
+{
+}
+
+/*---------------------------------------------------------------------------*
+ * function bound to control function key 1
+ *---------------------------------------------------------------------------*/
+static void
+cfkey1(void)
+{
+ if(meta_down)
+ do_vgapage(0);
+}
+
+/*---------------------------------------------------------------------------*
+ * function bound to control function key 2
+ *---------------------------------------------------------------------------*/
+static void
+cfkey2(void)
+{
+ if(meta_down)
+ do_vgapage(1);
+}
+
+/*---------------------------------------------------------------------------*
+ * function bound to control function key 3
+ *---------------------------------------------------------------------------*/
+static void
+cfkey3(void)
+{
+ if(meta_down)
+ do_vgapage(2);
+}
+
+/*---------------------------------------------------------------------------*
+ * function bound to control function key 4
+ *---------------------------------------------------------------------------*/
+static void
+cfkey4(void)
+{
+ if(meta_down)
+ do_vgapage(3);
+}
+
+/*---------------------------------------------------------------------------*
+ * function bound to control function key 5
+ *---------------------------------------------------------------------------*/
+static void
+cfkey5(void)
+{
+ if(meta_down)
+ do_vgapage(4);
+}
+
+/*---------------------------------------------------------------------------*
+ * function bound to control function key 6
+ *---------------------------------------------------------------------------*/
+static void
+cfkey6(void)
+{
+ if(meta_down)
+ do_vgapage(5);
+}
+
+/*---------------------------------------------------------------------------*
+ * function bound to control function key 7
+ *---------------------------------------------------------------------------*/
+static void
+cfkey7(void)
+{
+ if(meta_down)
+ do_vgapage(6);
+}
+
+/*---------------------------------------------------------------------------*
+ * function bound to control function key 8
+ *---------------------------------------------------------------------------*/
+static void
+cfkey8(void)
+{
+ if(meta_down)
+ do_vgapage(7);
+}
+
+/*---------------------------------------------------------------------------*
+ * function bound to control function key 9
+ *---------------------------------------------------------------------------*/
+static void
+cfkey9(void)
+{
+ if(meta_down)
+ do_vgapage(8);
+}
+
+/*---------------------------------------------------------------------------*
+ * function bound to control function key 10
+ *---------------------------------------------------------------------------*/
+static void
+cfkey10(void)
+{
+ if(meta_down)
+ do_vgapage(9);
+}
+
+/*---------------------------------------------------------------------------*
+ * function bound to control function key 11
+ *---------------------------------------------------------------------------*/
+static void
+cfkey11(void)
+{
+ if(meta_down)
+ do_vgapage(10);
+}
+
+/*---------------------------------------------------------------------------*
+ * function bound to control function key 12
+ *---------------------------------------------------------------------------*/
+static void
+cfkey12(void)
+{
+ if(meta_down)
+ do_vgapage(11);
+}
+
+#else /* PCVT_VT220 - VT220-like Keyboard layout */
+
+/*---------------------------------------------------------------------------*
+ * function bound to function key 1
+ *---------------------------------------------------------------------------*/
+static void
+fkey1(void)
+{
+ if(meta_down)
+ more_chars = (u_char *)"\033[23~"; /* F11 */
+ else
+ do_vgapage(0);
+}
+
+/*---------------------------------------------------------------------------*
+ * function bound to function key 2
+ *---------------------------------------------------------------------------*/
+static void
+fkey2(void)
+{
+ if(meta_down)
+ more_chars = (u_char *)"\033[24~"; /* F12 */
+ else
+ do_vgapage(1);
+}
+
+/*---------------------------------------------------------------------------*
+ * function bound to function key 3
+ *---------------------------------------------------------------------------*/
+static void
+fkey3(void)
+{
+ if(meta_down)
+ more_chars = (u_char *)"\033[25~"; /* F13 */
+ else
+ do_vgapage(2);
+}
+
+/*---------------------------------------------------------------------------*
+ * function bound to function key 4
+ *---------------------------------------------------------------------------*/
+static void
+fkey4(void)
+{
+ if(meta_down)
+ more_chars = (u_char *)"\033[26~"; /* F14 */
+ else
+ do_vgapage(3);
+}
+
+/*---------------------------------------------------------------------------*
+ * function bound to function key 5
+ *---------------------------------------------------------------------------*/
+static void
+fkey5(void)
+{
+ if(meta_down)
+ more_chars = (u_char *)"\033[28~"; /* Help */
+ else
+ {
+ if((current_video_screen + 1) > totalscreens-1)
+ do_vgapage(0);
+ else
+ do_vgapage(current_video_screen + 1);
+ }
+}
+
+/*---------------------------------------------------------------------------*
+ * function bound to function key 6
+ *---------------------------------------------------------------------------*/
+static void
+fkey6(void)
+{
+ if(meta_down)
+ more_chars = (u_char *)"\033[29~"; /* DO */
+ else
+ more_chars = (u_char *)"\033[17~"; /* F6 */
+}
+
+/*---------------------------------------------------------------------------*
+ * function bound to function key 7
+ *---------------------------------------------------------------------------*/
+static void
+fkey7(void)
+{
+ if(meta_down)
+ more_chars = (u_char *)"\033[31~"; /* F17 */
+ else
+ more_chars = (u_char *)"\033[18~"; /* F7 */
+}
+
+/*---------------------------------------------------------------------------*
+ * function bound to function key 8
+ *---------------------------------------------------------------------------*/
+static void
+fkey8(void)
+{
+ if(meta_down)
+ more_chars = (u_char *)"\033[32~"; /* F18 */
+ else
+ more_chars = (u_char *)"\033[19~"; /* F8 */
+}
+
+/*---------------------------------------------------------------------------*
+ * function bound to function key 9
+ *---------------------------------------------------------------------------*/
+static void
+fkey9(void)
+{
+ if(meta_down)
+ more_chars = (u_char *)"\033[33~"; /* F19 */
+ else
+ more_chars = (u_char *)"\033[20~"; /* F9 */
+}
+
+/*---------------------------------------------------------------------------*
+ * function bound to function key 10
+ *---------------------------------------------------------------------------*/
+static void
+fkey10(void)
+{
+ if(meta_down)
+ more_chars = (u_char *)"\033[34~"; /* F20 */
+ else
+ more_chars = (u_char *)"\033[21~"; /* F10 */
+}
+
+/*---------------------------------------------------------------------------*
+ * function bound to function key 11
+ *---------------------------------------------------------------------------*/
+static void
+fkey11(void)
+{
+ if(meta_down)
+ more_chars = (u_char *)"\0x8FP"; /* PF1 */
+ else
+ more_chars = (u_char *)"\033[23~"; /* F11 */
+}
+
+/*---------------------------------------------------------------------------*
+ * function bound to function key 12
+ *---------------------------------------------------------------------------*/
+static void
+fkey12(void)
+{
+ if(meta_down)
+ more_chars = (u_char *)"\0x8FQ"; /* PF2 */
+ else
+ more_chars = (u_char *)"\033[24~"; /* F12 */
+}
+
+/*---------------------------------------------------------------------------*
+ * function bound to SHIFTED function key 1
+ *---------------------------------------------------------------------------*/
+static void
+sfkey1(void)
+{
+ if(meta_down)
+ {
+ if(vsp->ukt.length[6]) /* entry available ? */
+ more_chars = (u_char *)
+ &(vsp->udkbuf[vsp->ukt.first[6]]);
+ else
+ more_chars = (u_char *)"\033[23~"; /* F11 */
+ }
+ else
+ {
+ do_vgapage(4);
+ }
+}
+
+/*---------------------------------------------------------------------------*
+ * function bound to SHIFTED function key 2
+ *---------------------------------------------------------------------------*/
+static void
+sfkey2(void)
+{
+ if(meta_down)
+ {
+ if(vsp->ukt.length[7]) /* entry available ? */
+ more_chars = (u_char *)
+ &(vsp->udkbuf[vsp->ukt.first[7]]);
+ else
+ more_chars = (u_char *)"\033[24~"; /* F12 */
+ }
+ else
+ {
+ do_vgapage(5);
+ }
+}
+
+/*---------------------------------------------------------------------------*
+ * function bound to SHIFTED function key 3
+ *---------------------------------------------------------------------------*/
+static void
+sfkey3(void)
+{
+ if(meta_down)
+ {
+ if(vsp->ukt.length[8]) /* entry available ? */
+ more_chars = (u_char *)
+ &(vsp->udkbuf[vsp->ukt.first[8]]);
+ else
+ more_chars = (u_char *)"\033[25~"; /* F13 */
+ }
+ else
+ {
+ do_vgapage(6);
+ }
+}
+
+/*---------------------------------------------------------------------------*
+ * function bound to SHIFTED function key 4
+ *---------------------------------------------------------------------------*/
+static void
+sfkey4(void)
+{
+ if(meta_down)
+ {
+ if(vsp->ukt.length[9]) /* entry available ? */
+ more_chars = (u_char *)
+ &(vsp->udkbuf[vsp->ukt.first[9]]);
+ else
+ more_chars = (u_char *)"\033[26~"; /* F14 */
+ }
+ else
+ {
+ do_vgapage(7);
+ }
+}
+
+/*---------------------------------------------------------------------------*
+ * function bound to SHIFTED function key 5
+ *---------------------------------------------------------------------------*/
+static void
+sfkey5(void)
+{
+ if(meta_down)
+ {
+ if(vsp->ukt.length[11]) /* entry available ? */
+ more_chars = (u_char *)
+ &(vsp->udkbuf[vsp->ukt.first[11]]);
+ else
+ more_chars = (u_char *)"\033[28~"; /* Help */
+ }
+ else
+ {
+ if(current_video_screen <= 0)
+ do_vgapage(totalscreens-1);
+ else
+ do_vgapage(current_video_screen - 1);
+ }
+}
+
+/*---------------------------------------------------------------------------*
+ * function bound to SHIFTED function key 6
+ *---------------------------------------------------------------------------*/
+static void
+sfkey6(void)
+{
+ if(!meta_down)
+ {
+ if(vsp->ukt.length[0]) /* entry available ? */
+ more_chars = (u_char *)
+ &(vsp->udkbuf[vsp->ukt.first[0]]);
+ else
+ more_chars = (u_char *)"\033[17~"; /* F6 */
+ }
+ else if(vsp->ukt.length[12]) /* entry available ? */
+ more_chars = (u_char *)
+ &(vsp->udkbuf[vsp->ukt.first[12]]);
+ else
+ more_chars = (u_char *)"\033[29~"; /* DO */
+}
+
+/*---------------------------------------------------------------------------*
+ * function bound to SHIFTED function key 7
+ *---------------------------------------------------------------------------*/
+static void
+sfkey7(void)
+{
+ if(!meta_down)
+ {
+ if(vsp->ukt.length[1]) /* entry available ? */
+ more_chars = (u_char *)
+ &(vsp->udkbuf[vsp->ukt.first[1]]);
+ else
+ more_chars = (u_char *)"\033[18~"; /* F7 */
+ }
+ else if(vsp->ukt.length[14]) /* entry available ? */
+ more_chars = (u_char *)
+ &(vsp->udkbuf[vsp->ukt.first[14]]);
+ else
+ more_chars = (u_char *)"\033[31~"; /* F17 */
+}
+
+/*---------------------------------------------------------------------------*
+ * function bound to SHIFTED function key 8
+ *---------------------------------------------------------------------------*/
+static void
+sfkey8(void)
+{
+ if(!meta_down)
+ {
+ if(vsp->ukt.length[2]) /* entry available ? */
+ more_chars = (u_char *)
+ &(vsp->udkbuf[vsp->ukt.first[2]]);
+ else
+ more_chars = (u_char *)"\033[19~"; /* F8 */
+ }
+ else if(vsp->ukt.length[14]) /* entry available ? */
+ more_chars = (u_char *)
+ &(vsp->udkbuf[vsp->ukt.first[15]]);
+ else
+ more_chars = (u_char *)"\033[32~"; /* F18 */
+}
+
+/*---------------------------------------------------------------------------*
+ * function bound to SHIFTED function key 9
+ *---------------------------------------------------------------------------*/
+static void
+sfkey9(void)
+{
+ if(!meta_down)
+ {
+ if(vsp->ukt.length[3]) /* entry available ? */
+ more_chars = (u_char *)
+ &(vsp->udkbuf[vsp->ukt.first[3]]);
+ else
+ more_chars = (u_char *)"\033[20~"; /* F9 */
+ }
+ else if(vsp->ukt.length[16]) /* entry available ? */
+ more_chars = (u_char *)
+ &(vsp->udkbuf[vsp->ukt.first[16]]);
+ else
+ more_chars = (u_char *)"\033[33~"; /* F19 */
+}
+
+/*---------------------------------------------------------------------------*
+ * function bound to SHIFTED function key 10
+ *---------------------------------------------------------------------------*/
+static void
+sfkey10(void)
+{
+ if(!meta_down)
+ {
+ if(vsp->ukt.length[4]) /* entry available ? */
+ more_chars = (u_char *)
+ &(vsp->udkbuf[vsp->ukt.first[4]]);
+ else
+ more_chars = (u_char *)"\033[21~"; /* F10 */
+ }
+ else if(vsp->ukt.length[17]) /* entry available ? */
+ more_chars = (u_char *)
+ &(vsp->udkbuf[vsp->ukt.first[17]]);
+ else
+ more_chars = (u_char *)"\033[34~"; /* F20 */
+}
+
+/*---------------------------------------------------------------------------*
+ * function bound to SHIFTED function key 11
+ *---------------------------------------------------------------------------*/
+static void
+sfkey11(void)
+{
+ if(!meta_down)
+ {
+ if(vsp->ukt.length[6]) /* entry available ? */
+ more_chars = (u_char *)
+ &(vsp->udkbuf[vsp->ukt.first[6]]);
+ else
+ more_chars = (u_char *)"\033[23~"; /* F11 */
+ }
+}
+
+/*---------------------------------------------------------------------------*
+ * function bound to SHIFTED function key 12
+ *---------------------------------------------------------------------------*/
+static void
+sfkey12(void)
+{
+ if(!meta_down)
+ {
+ if(vsp->ukt.length[7]) /* entry available ? */
+ more_chars = (u_char *)
+ &(vsp->udkbuf[vsp->ukt.first[7]]);
+ else
+ more_chars = (u_char *)"\033[24~"; /* F12 */
+ }
+}
+
+/*---------------------------------------------------------------------------*
+ * function bound to control function key 1
+ *---------------------------------------------------------------------------*/
+static void
+cfkey1(void)
+{
+ if(vsp->which_fkl == SYS_FKL)
+ toggl_columns(vsp);
+}
+
+/*---------------------------------------------------------------------------*
+ * function bound to control function key 2
+ *---------------------------------------------------------------------------*/
+static void
+cfkey2(void)
+{
+ if(vsp->which_fkl == SYS_FKL)
+ vt_ris(vsp);
+}
+
+/*---------------------------------------------------------------------------*
+ * function bound to control function key 3
+ *---------------------------------------------------------------------------*/
+static void
+cfkey3(void)
+{
+ if(vsp->which_fkl == SYS_FKL)
+ toggl_24l(vsp);
+}
+
+/*---------------------------------------------------------------------------*
+ * function bound to control function key 4
+ *---------------------------------------------------------------------------*/
+static void
+cfkey4(void)
+{
+
+#if PCVT_SHOWKEYS
+ if(vsp->which_fkl == SYS_FKL)
+ toggl_kbddbg(vsp);
+#endif /* PCVT_SHOWKEYS */
+
+}
+
+/*---------------------------------------------------------------------------*
+ * function bound to control function key 5
+ *---------------------------------------------------------------------------*/
+static void
+cfkey5(void)
+{
+ if(vsp->which_fkl == SYS_FKL)
+ toggl_bell(vsp);
+}
+
+/*---------------------------------------------------------------------------*
+ * function bound to control function key 6
+ *---------------------------------------------------------------------------*/
+static void
+cfkey6(void)
+{
+ if(vsp->which_fkl == SYS_FKL)
+ toggl_sevenbit(vsp);
+}
+
+/*---------------------------------------------------------------------------*
+ * function bound to control function key 7
+ *---------------------------------------------------------------------------*/
+static void
+cfkey7(void)
+{
+ if(vsp->which_fkl == SYS_FKL)
+ toggl_dspf(vsp);
+}
+
+/*---------------------------------------------------------------------------*
+ * function bound to control function key 8
+ *---------------------------------------------------------------------------*/
+static void
+cfkey8(void)
+{
+ if(vsp->which_fkl == SYS_FKL)
+ toggl_awm(vsp);
+}
+
+/*---------------------------------------------------------------------------*
+ * function bound to control function key 9
+ *---------------------------------------------------------------------------*/
+static void
+cfkey9(void)
+{
+ if(vsp->labels_on) /* toggle label display on/off */
+ fkl_off(vsp);
+ else
+ fkl_on(vsp);
+}
+
+/*---------------------------------------------------------------------------*
+ * function bound to control function key 10
+ *---------------------------------------------------------------------------*/
+static void
+cfkey10(void)
+{
+ if(vsp->labels_on) /* toggle user/system fkey labels */
+ {
+ if(vsp->which_fkl == USR_FKL)
+ sw_sfkl(vsp);
+ else if(vsp->which_fkl == SYS_FKL)
+ sw_ufkl(vsp);
+ }
+}
+
+/*---------------------------------------------------------------------------*
+ * function bound to control function key 11
+ *---------------------------------------------------------------------------*/
+static void
+cfkey11(void)
+{
+ if(vsp->vt_pure_mode == M_PUREVT)
+ set_emulation_mode(vsp, M_HPVT);
+ else if(vsp->vt_pure_mode == M_HPVT)
+ set_emulation_mode(vsp, M_PUREVT);
+}
+
+/*---------------------------------------------------------------------------*
+ * function bound to control function key 12
+ *---------------------------------------------------------------------------*/
+static void
+cfkey12(void)
+{
+}
+
+#endif /* PCVT_VT220KEYB */
+
+#endif /* NVT > 0 */
+
+/* ------------------------------- EOF -------------------------------------*/
diff --git a/sys/arch/i386/isa/pcvt/pcvt_kbd.h b/sys/arch/i386/isa/pcvt/pcvt_kbd.h
new file mode 100644
index 00000000000..2af508d6042
--- /dev/null
+++ b/sys/arch/i386/isa/pcvt/pcvt_kbd.h
@@ -0,0 +1,566 @@
+/*
+ * Copyright (c) 1992, 1995 Hellmuth Michaelis and Joerg Wunsch.
+ *
+ * Copyright (c) 1992, 1993 Brian Dunford-Shore and Holger Veit.
+ *
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * William Jolitz and Don Ahn.
+ *
+ * This code is derived from software contributed to 386BSD by
+ * Holger Veit.
+ *
+ * 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 Hellmuth Michaelis,
+ * Brian Dunford-Shore and Joerg Wunsch.
+ * 4. The name authors may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``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 AUTHORS 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.
+ *
+ *
+ * @(#)pcvt_kbd.h, 3.32, Last Edit-Date: [Tue Oct 3 11:19:48 1995]
+ *
+ */
+
+/*---------------------------------------------------------------------------*
+ *
+ * pcvt_kbd.h VT220 Driver Keyboard Interface Header
+ * ------------------------------------------------------
+ * -hm split off from pcvt_kbd.c
+ * -hm patch from Lon Willett to fix mapping of Control-R scancode
+ * -hm ---------------- Release 3.30 -----------------------
+ * -hm ---------------- Release 3.32 -----------------------
+ *
+ *---------------------------------------------------------------------------*/
+
+/*---------------------------------------------------------------------------*
+ * this is one sub-entry for the table. the type can be either
+ * "pointer to a string" or "pointer to a function"
+ *---------------------------------------------------------------------------*/
+typedef struct
+{
+ u_char subtype; /* subtype, string or function */
+#ifdef PCVT_ALT_ENH
+ u_short str_leng; /* if string, stringlength */
+#endif
+ union what
+ {
+ u_char *string; /* ptr to string, null terminated */
+ void (*func)(); /* ptr to function */
+ } what;
+} entry;
+
+/*---------------------------------------------------------------------------*
+ * this is the "outer" table
+ *---------------------------------------------------------------------------*/
+typedef struct
+{
+ u_short type; /* type of key */
+ u_short ovlindex; /* -hv- index into overload table */
+ entry unshift; /* normal default codes/funcs */
+ entry shift; /* shifted default codes/funcs */
+ entry ctrl; /* control default codes/funcs */
+#ifdef PCVT_ALT_ENH
+ entry alt; /* normal default codes/funcs */
+ entry alt_shift; /* shifted default codes/funcs */
+ entry alt_ctrl; /* control default codes/funcs */
+ entry alt_ctrl_shift; /* normal default codes/funcs */
+#endif
+} Keycap_def;
+
+#define IDX0 0 /* default indexvalue into ovl table */
+
+#define STR KBD_SUBT_STR /* subtype = ptr to string */
+#define FNC KBD_SUBT_FNC /* subtype = ptr to function */
+
+#define CODE_SIZE 5
+
+/*---------------------------------------------------------------------------*
+ * the overlaytable table is a static fixed size scratchpad where all the
+ * overloaded definitions are stored.
+ * an entry consists of a short (holding the new type attribute) and
+ * four entries for a new keydefinition.
+ *---------------------------------------------------------------------------*/
+
+#define OVLTBL_SIZE 64 /* 64 keys can be overloaded */
+
+#define Ovl_tbl struct kbd_ovlkey
+
+static Ovl_tbl *ovltbl; /* the table itself */
+
+static ovlinitflag = 0; /* the init flag for the table */
+
+/*
+ * key codes >= 128 denote "virtual" shift/control
+ * They are resolved before any keymapping is handled
+ */
+
+#if PCVT_SCANSET == 2
+static u_char scantokey[] = {
+/* -0- -1- -2- -3- -4- -5- -6- -7- This layout is valid for US only */
+/*00*/ 0,120, 0,116,114,112,113,123, /* ?? F9 ?? F5 F3 F1 F2 F12 */
+/*08*/ 0,121,119,117,115, 16, 1, 0, /* ?? F10 F8 F6 F4 TAB ` ?? */
+/*10*/ 0, 60, 44, 0, 58, 17, 2, 0, /* ?? ALl SHl ?? CTl Q 1 ?? */
+/*18*/ 0, 0, 46, 32, 31, 18, 3, 0, /* ?? Z S A W 2 ?? ?? */
+/*20*/ 0, 48, 47, 33, 19, 5, 4, 0, /* ?? C X D E 4 3 ?? */
+/*28*/ 0, 61, 49, 34, 21, 20, 6, 0, /* ?? SP V F T R 5 ?? */
+/*30*/ 0, 51, 50, 36, 35, 22, 7, 0, /* ?? N B H G Y 6 ?? */
+/*38*/ 0, 0, 52, 37, 23, 8, 9, 0, /* ?? ?? M J U 7 8 ?? */
+/*40*/ 0, 53, 38, 24, 25, 11, 10, 0, /* ?? , K I O 0 9 ?? */
+/*48*/ 0, 54, 55, 39, 40, 26, 12, 0, /* ?? . / L ; P - ?? */
+/*50*/ 0, 0, 41, 0, 27, 13, 0, 0, /* ?? ?? " ?? [ = ?? ?? */
+/*58*/ 30, 57, 43, 28, 0, 29, 0, 0, /* CAP SHr ENT ] ?? \ ?? ?? */
+/*60*/ 0, 45, 0, 0, 0, 0, 15, 0, /* ?? NL1 ?? ?? ?? ?? BS ?? */
+/*68*/ 0, 93, 0, 92, 91, 0, 0, 0, /* ?? KP1 ?? KP4 KP7 ?? ?? ?? */
+/*70*/ 99,104, 98, 97,102, 96,110, 90, /* KP0 KP. KP2 KP5 KP6 KP8 ESC NUM */
+/*78*/ 122,106,103,105,100,101,125, 0, /* F11 KP+ KP3 KP- KP* KP9 LOC ?? */
+/*80*/ 0, 0, 0,118,127 /* ?? ?? ?? F7 SyRQ */
+};
+
+static u_char extscantokey[] = {
+/* -0- -1- -2- -3- -4- -5- -6- -7- This layout is valid for US only */
+/*00*/ 0,120, 0,116,114,112,113,123, /* ?? F9 ?? F5 F3 F1 F2 F12 */
+/*08*/ 0,121,119,117,115, 16, 1, 0, /* ?? F10 F8 F6 F4 TAB ` ?? */
+/*10*/ 0, 62,128, 0, 64, 17, 2, 0, /* ?? ALr vSh ?? CTr Q 1 ?? */
+/*18*/ 0, 0, 46, 32, 31, 18, 3, 0, /* ?? Z S A W 2 ?? ?? */
+/*20*/ 0, 48, 47, 33, 19, 5, 4, 0, /* ?? C X D E 4 3 ?? */
+/*28*/ 0, 61, 49, 34, 21, 20, 6, 0, /* ?? SP V F T R 5 ?? */
+/*30*/ 0, 51, 50, 36, 35, 22, 7, 0, /* ?? N B H G Y 6 ?? */
+/*38*/ 0, 0, 52, 37, 23, 8, 9, 0, /* ?? ?? M J U 7 8 ?? */
+/*40*/ 0, 53, 38, 24, 25, 11, 10, 0, /* ?? , K I O 0 9 ?? */
+/*48*/ 0, 54, 95, 39, 40, 26, 12, 0, /* ?? . KP/ L ; P - ?? */
+/*50*/ 0, 0, 41, 0, 27, 13, 0, 0, /* ?? ?? " ?? [ = ?? ?? */
+/*58*/ 30, 57,108, 28, 0, 29, 0, 0, /* CAP SHr KPE ] ?? \ ?? ?? */
+/*60*/ 0, 45, 0, 0, 0, 0, 15, 0, /* ?? NL1 ?? ?? ?? ?? BS ?? */
+/*68*/ 0, 81, 0, 79, 80, 0, 0, 0, /* ?? END ?? LA HOM ?? ?? ?? */
+/*70*/ 75, 76, 84, 97, 89, 83,110, 90, /* INS DEL DA KP5 RA UA ESC NUM */
+/*78*/ 122,106, 86,105,124, 85,126, 0, /* F11 KP+ PD KP- PSc PU Brk ?? */
+/*80*/ 0, 0, 0,118,127 /* ?? ?? ?? F7 SysRq */
+};
+
+#else /* PCVT_SCANSET != 2 */
+
+static u_char scantokey[] = {
+/* -0- -1- -2- -3- -4- -5- -6- -7- This layout is valid for US only */
+/*00*/ 0,110, 2, 3, 4, 5, 6, 7, /* ?? ESC 1 2 3 4 5 6 */
+/*08*/ 8, 9, 10, 11, 12, 13, 15, 16, /* 7 8 9 0 - = BS TAB */
+/*10*/ 17, 18, 19, 20, 21, 22, 23, 24, /* Q W E R T Y U I */
+/*18*/ 25, 26, 27, 28, 43, 58, 31, 32, /* O P [ ] ENT CTl A S */
+/*20*/ 33, 34, 35, 36, 37, 38, 39, 40, /* D F G H J K L ; */
+/*28*/ 41, 1, 44, 29, 46, 47, 48, 49, /* ' ` SHl \ Z X C V */
+/*30*/ 50, 51, 52, 53, 54, 55, 57,100, /* B N M , . / SHr KP* */
+/*38*/ 60, 61, 30,112,113,114,115,116, /* ALl SP CAP F1 F2 F3 F4 F5 */
+/*40*/ 117,118,119,120,121, 90,125, 91, /* F6 F7 F8 F9 F10 NUM LOC KP7 */
+/*48*/ 96,101,105, 92, 97,102,106, 93, /* KP8 KP9 KP- KP4 KP5 KP6 KP+ KP1 */
+/*50*/ 98,103, 99,104,127, 0, 45,122, /* KP2 KP3 KP0 KP. SyRq?? NL1 F11 */
+/*58*/ 123 /* F12 */
+};
+
+static u_char extscantokey[] = {
+/* -0- -1- -2- -3- -4- -5- -6- -7- This layout is valid for US only */
+/*00*/ 0,110, 2, 3, 4, 5, 6, 7, /* ?? ESC 1 2 3 4 5 6 */
+/*08*/ 8, 9, 10, 11, 12, 13, 15, 16, /* 7 8 9 0 - = BS TAB */
+/*10*/ 17, 18, 19, 20, 21, 22, 23, 24, /* Q W E R T Y U I */
+/*18*/ 25, 26, 27, 28,108, 64, 31, 32, /* O P [ ] KPE CTr A S */
+/*20*/ 33, 34, 35, 36, 37, 38, 39, 40, /* D F G H J K L ; */
+/*28*/ 41, 1,128, 29, 46, 47, 48, 49, /* ' ` vSh \ Z X C V */
+/*30*/ 50, 51, 52, 53, 54, 95, 57,124, /* B N M , . KP/ SHr KP* */
+/*38*/ 62, 61, 30,112,113,114,115,116, /* ALr SP CAP F1 F2 F3 F4 F5 */
+/*40*/ 117,118,119,120,121, 90,126, 80, /* F6 F7 F8 F9 F10 NUM Brk HOM */
+/*48*/ 83, 85,105, 79, 97, 89,106, 81, /* UA PU KP- LA KP5 RA KP+ END */
+/*50*/ 84, 86, 75, 76, 0, 0, 45,122, /* DA PD INS DEL ?? ?? NL1 F11 */
+/*58*/ 123, /* F12 */
+};
+#endif /* PCVT_SCANSET == 2 */
+
+static Keycap_def key2ascii[] =
+{
+
+#ifdef PCVT_ALT_ENH
+
+#define C (u_char *)
+#define U (u_short)
+#define V (void *)
+#define S STR
+#define F FNC
+#define I IDX0
+
+#define DFAULT {S, 0, C ""}
+
+/* DONT EVER OVERLOAD KEY 0, THIS IS A KEY THAT MUSTN'T EXIST */
+
+/* type index unshift shift ctrl alt alt_shift alt_ctrl alt_ctrl_shift */
+/* -------------------------------------------------------------------------------------------------------------------------------------------------- */
+/* 0*/ KBD_NONE, I, DFAULT, DFAULT, DFAULT, DFAULT, DFAULT, DFAULT, DFAULT,
+/* 1*/ KBD_ASCII, I, {S,1,C "`"}, {S,1,C "~"}, {S,1,C "`"}, DFAULT, DFAULT, DFAULT, DFAULT,
+/* 2*/ KBD_ASCII, I, {S,1,C "1"}, {S,1,C "!"}, {S,1,C "1"}, DFAULT, DFAULT, DFAULT, DFAULT,
+/* 3*/ KBD_ASCII, I, {S,1,C "2"}, {S,1,C "@"}, {S,1,C "\000"}, DFAULT, DFAULT, DFAULT, DFAULT,
+/* 4*/ KBD_ASCII, I, {S,1,C "3"}, {S,1,C "#"}, {S,1,C "3"}, DFAULT, DFAULT, DFAULT, DFAULT,
+/* 5*/ KBD_ASCII, I, {S,1,C "4"}, {S,1,C "$"}, {S,1,C "4"}, DFAULT, DFAULT, DFAULT, DFAULT,
+/* 6*/ KBD_ASCII, I, {S,1,C "5"}, {S,1,C "%"}, {S,1,C "5"}, DFAULT, DFAULT, DFAULT, DFAULT,
+/* 7*/ KBD_ASCII, I, {S,1,C "6"}, {S,1,C "^"}, {S,1,C "\036"}, DFAULT, DFAULT, DFAULT, DFAULT,
+/* 8*/ KBD_ASCII, I, {S,1,C "7"}, {S,1,C "&"}, {S,1,C "7"}, DFAULT, DFAULT, DFAULT, DFAULT,
+/* 9*/ KBD_ASCII, I, {S,1,C "8"}, {S,1,C "*"}, {S,1,C "9"}, DFAULT, DFAULT, DFAULT, DFAULT,
+/* 10*/ KBD_ASCII, I, {S,1,C "9"}, {S,1,C "("}, {S,1,C "9"}, DFAULT, DFAULT, DFAULT, DFAULT,
+/* 11*/ KBD_ASCII, I, {S,1,C "0"}, {S,1,C ")"}, {S,1,C "0"}, DFAULT, DFAULT, DFAULT, DFAULT,
+/* 12*/ KBD_ASCII, I, {S,1,C "-"}, {S,1,C "_"}, {S,1,C "\037"}, DFAULT, DFAULT, DFAULT, DFAULT,
+/* 13*/ KBD_ASCII, I, {S,1,C "="}, {S,1,C "+"}, {S,1,C "="}, DFAULT, DFAULT, DFAULT, DFAULT,
+/* 14*/ KBD_NONE, I, DFAULT, DFAULT, DFAULT, DFAULT, DFAULT, DFAULT, DFAULT,
+/* 15*/ KBD_ASCII, I, {S,1,C "\177"}, {S,1,C "\010"}, {S,1,C "\177"}, DFAULT, DFAULT, DFAULT, DFAULT,
+/* 16*/ KBD_ASCII, I, {S,1,C "\t"}, {S,1,C "\t"}, {S,1,C "\t"}, DFAULT, DFAULT, DFAULT, DFAULT,
+/* 17*/ KBD_ASCII, I, {S,1,C "q"}, {S,1,C "Q"}, {S,1,C "\021"}, DFAULT, DFAULT, DFAULT, DFAULT,
+/* 18*/ KBD_ASCII, I, {S,1,C "w"}, {S,1,C "W"}, {S,1,C "\027"}, DFAULT, DFAULT, DFAULT, DFAULT,
+/* 19*/ KBD_ASCII, I, {S,1,C "e"}, {S,1,C "E"}, {S,1,C "\005"}, DFAULT, DFAULT, DFAULT, DFAULT,
+/* 20*/ KBD_ASCII, I, {S,1,C "r"}, {S,1,C "R"}, {S,1,C "\022"}, DFAULT, DFAULT, DFAULT, DFAULT,
+/* 21*/ KBD_ASCII, I, {S,1,C "t"}, {S,1,C "T"}, {S,1,C "\024"}, DFAULT, DFAULT, DFAULT, DFAULT,
+/* 22*/ KBD_ASCII, I, {S,1,C "y"}, {S,1,C "Y"}, {S,1,C "\031"}, DFAULT, DFAULT, DFAULT, DFAULT,
+/* 23*/ KBD_ASCII, I, {S,1,C "u"}, {S,1,C "U"}, {S,1,C "\025"}, DFAULT, DFAULT, DFAULT, DFAULT,
+/* 24*/ KBD_ASCII, I, {S,1,C "i"}, {S,1,C "I"}, {S,1,C "\011"}, DFAULT, DFAULT, DFAULT, DFAULT,
+/* 25*/ KBD_ASCII, I, {S,1,C "o"}, {S,1,C "O"}, {S,1,C "\017"}, DFAULT, DFAULT, DFAULT, DFAULT,
+/* 26*/ KBD_ASCII, I, {S,1,C "p"}, {S,1,C "P"}, {S,1,C "\020"}, DFAULT, DFAULT, DFAULT, DFAULT,
+/* 27*/ KBD_ASCII, I, {S,1,C "["}, {S,1,C "{"}, {S,1,C "\033"}, DFAULT, DFAULT, DFAULT, DFAULT,
+/* 28*/ KBD_ASCII, I, {S,1,C "]"}, {S,1,C "}"}, {S,1,C "\035"}, DFAULT, DFAULT, DFAULT, DFAULT,
+/* 29*/ KBD_ASCII, I, {S,1,C "\\"}, {S,1,C "|"}, {S,1,C "\034"}, DFAULT, DFAULT, DFAULT, DFAULT,
+/* 30*/ KBD_CAPS, I, DFAULT, DFAULT, DFAULT, DFAULT, DFAULT, DFAULT, DFAULT,
+/* 31*/ KBD_ASCII, I, {S,1,C "a"}, {S,1,C "A"}, {S,1,C "\001"}, DFAULT, DFAULT, DFAULT, DFAULT,
+/* 32*/ KBD_ASCII, I, {S,1,C "s"}, {S,1,C "S"}, {S,1,C "\023"}, DFAULT, DFAULT, DFAULT, DFAULT,
+/* 33*/ KBD_ASCII, I, {S,1,C "d"}, {S,1,C "D"}, {S,1,C "\004"}, DFAULT, DFAULT, DFAULT, DFAULT,
+/* 34*/ KBD_ASCII, I, {S,1,C "f"}, {S,1,C "F"}, {S,1,C "\006"}, DFAULT, DFAULT, DFAULT, DFAULT,
+/* 35*/ KBD_ASCII, I, {S,1,C "g"}, {S,1,C "G"}, {S,1,C "\007"}, DFAULT, DFAULT, DFAULT, DFAULT,
+/* 36*/ KBD_ASCII, I, {S,1,C "h"}, {S,1,C "H"}, {S,1,C "\010"}, DFAULT, DFAULT, DFAULT, DFAULT,
+/* 37*/ KBD_ASCII, I, {S,1,C "j"}, {S,1,C "J"}, {S,1,C "\n"}, DFAULT, DFAULT, DFAULT, DFAULT,
+/* 38*/ KBD_ASCII, I, {S,1,C "k"}, {S,1,C "K"}, {S,1,C "\013"}, DFAULT, DFAULT, DFAULT, DFAULT,
+/* 39*/ KBD_ASCII, I, {S,1,C "l"}, {S,1,C "L"}, {S,1,C "\014"}, DFAULT, DFAULT, DFAULT, DFAULT,
+/* 40*/ KBD_ASCII, I, {S,1,C ";"}, {S,1,C ":"}, {S,1,C ";"}, DFAULT, DFAULT, DFAULT, DFAULT,
+/* 41*/ KBD_ASCII, I, {S,1,C "'"}, {S,1,C "\""}, {S,1,C "'"}, DFAULT, DFAULT, DFAULT, DFAULT,
+/* 42*/ KBD_ASCII, I, {S,1,C "\\"}, {S,1,C "|"}, {S,1,C "\034"}, DFAULT, DFAULT, DFAULT, DFAULT,
+/* 43*/ KBD_RETURN,I, {S,1,C "\r"}, {S,1,C "\r"}, {S,1,C "\r"}, DFAULT, DFAULT, DFAULT, DFAULT,
+/* 44*/ KBD_SHIFT, I, DFAULT, DFAULT, DFAULT, DFAULT, DFAULT, DFAULT, DFAULT,
+/* 45*/ KBD_ASCII, I, {S,1,C "<"}, {S,1,C ">"}, DFAULT, DFAULT, DFAULT, DFAULT, DFAULT,
+/* 46*/ KBD_ASCII, I, {S,1,C "z"}, {S,1,C "Z"}, {S,1,C "\032"}, DFAULT, DFAULT, DFAULT, DFAULT,
+/* 47*/ KBD_ASCII, I, {S,1,C "x"}, {S,1,C "X"}, {S,1,C "\030"}, DFAULT, DFAULT, DFAULT, DFAULT,
+/* 48*/ KBD_ASCII, I, {S,1,C "c"}, {S,1,C "C"}, {S,1,C "\003"}, DFAULT, DFAULT, DFAULT, DFAULT,
+/* 49*/ KBD_ASCII, I, {S,1,C "v"}, {S,1,C "V"}, {S,1,C "\026"}, DFAULT, DFAULT, DFAULT, DFAULT,
+/* 50*/ KBD_ASCII, I, {S,1,C "b"}, {S,1,C "B"}, {S,1,C "\002"}, DFAULT, DFAULT, DFAULT, DFAULT,
+/* 51*/ KBD_ASCII, I, {S,1,C "n"}, {S,1,C "N"}, {S,1,C "\016"}, DFAULT, DFAULT, DFAULT, DFAULT,
+/* 52*/ KBD_ASCII, I, {S,1,C "m"}, {S,1,C "M"}, {S,1,C "\r"}, DFAULT, DFAULT, DFAULT, DFAULT,
+/* 53*/ KBD_ASCII, I, {S,1,C ","}, {S,1,C "<"}, {S,1,C ","}, DFAULT, DFAULT, DFAULT, DFAULT,
+/* 54*/ KBD_ASCII, I, {S,1,C "."}, {S,1,C ">"}, {S,1,C "."}, DFAULT, DFAULT, DFAULT, DFAULT,
+/* 55*/ KBD_ASCII, I, {S,1,C "/"}, {S,1,C "?"}, {S,1,C "/"}, DFAULT, DFAULT, DFAULT, DFAULT,
+/* 56*/ KBD_NONE, I, DFAULT, DFAULT, DFAULT, DFAULT, DFAULT, DFAULT, DFAULT,
+/* 57*/ KBD_SHIFT, I, DFAULT, DFAULT, DFAULT, DFAULT, DFAULT, DFAULT, DFAULT,
+/* 58*/ KBD_CTL, I, DFAULT, DFAULT, DFAULT, DFAULT, DFAULT, DFAULT, DFAULT,
+/* 59*/ KBD_ASCII, I, DFAULT, DFAULT, DFAULT, DFAULT, DFAULT, DFAULT, DFAULT,
+/* 60*/ KBD_META, I, DFAULT, DFAULT, DFAULT, DFAULT, DFAULT, DFAULT, DFAULT,
+#if !PCVT_NULLCHARS
+/* 61*/ KBD_ASCII, I, DFAULT, DFAULT, DFAULT, DFAULT, DFAULT, DFAULT, DFAULT,
+#else
+/* 61*/ KBD_ASCII, I, DFAULT, DFAULT, {S,1,C "\000"}, DFAULT, DFAULT, DFAULT, DFAULT,
+#endif /* PCVT_NULLCHARS */
+/* 62*/ KBD_META, I, DFAULT, DFAULT, DFAULT, DFAULT, DFAULT, DFAULT, DFAULT,
+/* 63*/ KBD_ASCII, I, DFAULT, DFAULT, DFAULT, DFAULT, DFAULT, DFAULT, DFAULT,
+/* 64*/ KBD_CTL, I, DFAULT, DFAULT, DFAULT, DFAULT, DFAULT, DFAULT, DFAULT,
+/* 65*/ KBD_NONE, I, DFAULT, DFAULT, DFAULT, DFAULT, DFAULT, DFAULT, DFAULT,
+/* 66*/ KBD_NONE, I, DFAULT, DFAULT, DFAULT, DFAULT, DFAULT, DFAULT, DFAULT,
+/* 67*/ KBD_NONE, I, DFAULT, DFAULT, DFAULT, DFAULT, DFAULT, DFAULT, DFAULT,
+/* 68*/ KBD_NONE, I, DFAULT, DFAULT, DFAULT, DFAULT, DFAULT, DFAULT, DFAULT,
+/* 69*/ KBD_NONE, I, DFAULT, DFAULT, DFAULT, DFAULT, DFAULT, DFAULT, DFAULT,
+/* 70*/ KBD_NONE, I, DFAULT, DFAULT, DFAULT, DFAULT, DFAULT, DFAULT, DFAULT,
+/* 71*/ KBD_NONE, I, DFAULT, DFAULT, DFAULT, DFAULT, DFAULT, DFAULT, DFAULT,
+/* 72*/ KBD_NONE, I, DFAULT, DFAULT, DFAULT, DFAULT, DFAULT, DFAULT, DFAULT,
+/* 73*/ KBD_NONE, I, DFAULT, DFAULT, DFAULT, DFAULT, DFAULT, DFAULT, DFAULT,
+/* 74*/ KBD_NONE, I, DFAULT, DFAULT, DFAULT, DFAULT, DFAULT, DFAULT, DFAULT,
+/* 75*/ KBD_FUNC, I, {S,4,C "\033[2~"}, {S,4,C "\033[2~"}, {S,4,C "\033[2~"}, DFAULT, DFAULT, DFAULT, DFAULT,
+/* 76*/ KBD_FUNC, I, {S,4,C "\033[3~"}, {S,4,C "\033[3~"}, {S,4,C "\033[3~"}, DFAULT, DFAULT, DFAULT, DFAULT,
+/* 77*/ KBD_NONE, I, DFAULT, DFAULT, DFAULT, DFAULT, DFAULT, DFAULT, DFAULT,
+/* 78*/ KBD_NONE, I, DFAULT, DFAULT, DFAULT, DFAULT, DFAULT, DFAULT, DFAULT,
+/* 79*/ KBD_CURSOR,I, {S,4,C "\033[D"}, {S,4,C "\033OD"}, {S,4,C "\033[D"}, DFAULT, DFAULT, DFAULT, DFAULT,
+/* 80*/ KBD_FUNC, I, {S,4,C "\033[1~"}, {S,4,C "\033[1~"}, {S,4,C "\033[1~"}, DFAULT, DFAULT, DFAULT, DFAULT,
+/* 81*/ KBD_FUNC, I, {S,4,C "\033[4~"}, {S,4,C "\033[4~"}, {S,4,C "\033[4~"}, DFAULT, DFAULT, DFAULT, DFAULT,
+/* 82*/ KBD_NONE, I, DFAULT, DFAULT, DFAULT, DFAULT, DFAULT, DFAULT, DFAULT,
+/* 83*/ KBD_CURSOR,I, {S,4,C "\033[A"}, {S,4,C "\033OA"}, {S,4,C "\033[A"}, DFAULT, DFAULT, DFAULT, DFAULT,
+/* 84*/ KBD_CURSOR,I, {S,4,C "\033[B"}, {S,4,C "\033OB"}, {S,4,C "\033[B"}, DFAULT, DFAULT, DFAULT, DFAULT,
+/* 85*/ KBD_FUNC, I, {S,4,C "\033[5~"}, {S,4,C "\033[5~"}, {S,4,C "\033[5~"}, DFAULT, DFAULT, DFAULT, DFAULT,
+/* 86*/ KBD_FUNC, I, {S,4,C "\033[6~"}, {S,4,C "\033[6~"}, {S,4,C "\033[6~"}, DFAULT, DFAULT, DFAULT, DFAULT,
+/* 87*/ KBD_NONE, I, DFAULT, DFAULT, DFAULT, DFAULT, DFAULT, DFAULT, DFAULT,
+/* 88*/ KBD_NONE, I, DFAULT, DFAULT, DFAULT, DFAULT, DFAULT, DFAULT, DFAULT,
+/* 89*/ KBD_CURSOR,I, {S,3,C "\033[C"}, {S,3,C "\033OC"}, {S,3,C "\033[C"}, DFAULT, DFAULT, DFAULT, DFAULT,
+/* 90*/ KBD_NUM, I, DFAULT, DFAULT, DFAULT, DFAULT, DFAULT, DFAULT, DFAULT,
+/* 91*/ KBD_KP, I, {S,1,C "7"}, {S,2,C "\033Ow"}, {S,1,C "7"}, DFAULT, DFAULT, DFAULT, DFAULT,
+/* 92*/ KBD_KP, I, {S,1,C "4"}, {S,2,C "\033Ot"}, {S,1,C "4"}, DFAULT, DFAULT, DFAULT, DFAULT,
+/* 93*/ KBD_KP, I, {S,1,C "1"}, {S,2,C "\033Oq"}, {S,1,C "1"}, DFAULT, DFAULT, DFAULT, DFAULT,
+/* 94*/ KBD_NONE, I, DFAULT, DFAULT, DFAULT, DFAULT, DFAULT, DFAULT, DFAULT,
+/* 95*/ KBD_KP, I, {S,1,C "/"}, {S,1,C "/"}, {S,1,C "/"}, DFAULT, DFAULT, DFAULT, DFAULT,
+/* 96*/ KBD_KP, I, {S,1,C "8"}, {S,2,C "\033Ox"}, {S,1,C "8"}, DFAULT, DFAULT, DFAULT, DFAULT,
+/* 97*/ KBD_KP, I, {S,1,C "5"}, {S,2,C "\033Ou"}, {S,1,C "5"}, DFAULT, DFAULT, DFAULT, DFAULT,
+/* 98*/ KBD_KP, I, {S,1,C "2"}, {S,2,C "\033Or"}, {S,1,C "2"}, DFAULT, DFAULT, DFAULT, DFAULT,
+/* 99*/ KBD_KP, I, {S,1,C "0"}, {S,2,C "\033Op"}, {S,1,C "0"}, DFAULT, DFAULT, DFAULT, DFAULT,
+/*100*/ KBD_KP, I, {S,1,C "*"}, {S,1,C "*"}, {S,1,C "*"}, DFAULT, DFAULT, DFAULT, DFAULT,
+/*101*/ KBD_KP, I, {S,1,C "9"}, {S,2,C "\033Oy"}, {S,1,C "9"}, DFAULT, DFAULT, DFAULT, DFAULT,
+/*102*/ KBD_KP, I, {S,1,C "6"}, {S,2,C "\033Ov"}, {S,1,C "6"}, DFAULT, DFAULT, DFAULT, DFAULT,
+/*103*/ KBD_KP, I, {S,1,C "3"}, {S,2,C "\033Os"}, {S,1,C "3"}, DFAULT, DFAULT, DFAULT, DFAULT,
+/*104*/ KBD_KP, I, {S,1,C "."}, {S,2,C "\033On"}, {S,1,C "."}, DFAULT, DFAULT, DFAULT, DFAULT,
+/*105*/ KBD_KP, I, {S,1,C "-"}, {S,2,C "\033Om"}, {S,1,C "-"}, DFAULT, DFAULT, DFAULT, DFAULT,
+/*106*/ KBD_KP, I, {S,1,C "+"}, {S,1,C "+"}, {S,1,C "+"}, DFAULT, DFAULT, DFAULT, DFAULT,
+/*107*/ KBD_NONE, I, DFAULT, DFAULT, DFAULT, DFAULT, DFAULT, DFAULT, DFAULT,
+/*108*/ KBD_RETURN,I, {S,1,C "\r"}, {S,2,C "\033OM"}, {S,1,C "\r"}, DFAULT, DFAULT, DFAULT, DFAULT,
+/*109*/ KBD_NONE, I, DFAULT, DFAULT, DFAULT, DFAULT, DFAULT, DFAULT, DFAULT,
+/*110*/ KBD_ASCII, I, {S,1,C "\033"}, {S,2,C "\033"}, {S,1,C "\033"}, DFAULT, DFAULT, DFAULT, DFAULT,
+/*111*/ KBD_NONE, I, DFAULT, DFAULT, DFAULT, DFAULT, DFAULT, DFAULT, DFAULT,
+/*112*/ KBD_FUNC, I, {F,0,V fkey1}, {F,0,V sfkey1}, {F,0,V cfkey1}, DFAULT, DFAULT, DFAULT, DFAULT,
+/*113*/ KBD_FUNC, I, {F,0,V fkey2}, {F,0,V sfkey2}, {F,0,V cfkey2}, DFAULT, DFAULT, DFAULT, DFAULT,
+/*114*/ KBD_FUNC, I, {F,0,V fkey3}, {F,0,V sfkey3}, {F,0,V cfkey3}, DFAULT, DFAULT, DFAULT, DFAULT,
+/*115*/ KBD_FUNC, I, {F,0,V fkey4}, {F,0,V sfkey4}, {F,0,V cfkey4}, DFAULT, DFAULT, DFAULT, DFAULT,
+/*116*/ KBD_FUNC, I, {F,0,V fkey5}, {F,0,V sfkey5}, {F,0,V cfkey5}, DFAULT, DFAULT, DFAULT, DFAULT,
+/*117*/ KBD_FUNC, I, {F,0,V fkey6}, {F,0,V sfkey6}, {F,0,V cfkey6}, DFAULT, DFAULT, DFAULT, DFAULT,
+/*118*/ KBD_FUNC, I, {F,0,V fkey7}, {F,0,V sfkey7}, {F,0,V cfkey7}, DFAULT, DFAULT, DFAULT, DFAULT,
+/*119*/ KBD_FUNC, I, {F,0,V fkey8}, {F,0,V sfkey8}, {F,0,V cfkey8}, DFAULT, DFAULT, DFAULT, DFAULT,
+/*120*/ KBD_FUNC, I, {F,0,V fkey9}, {F,0,V sfkey9}, {F,0,V cfkey9}, DFAULT, DFAULT, DFAULT, DFAULT,
+/*121*/ KBD_FUNC, I, {F,0,V fkey10}, {F,0,V sfkey10}, {F,0,V cfkey10}, DFAULT, DFAULT, DFAULT, DFAULT,
+/*122*/ KBD_FUNC, I, {F,0,V fkey11}, {F,0,V sfkey11}, {F,0,V cfkey11}, DFAULT, DFAULT, DFAULT, DFAULT,
+/*123*/ KBD_FUNC, I, {F,0,V fkey12}, {F,0,V sfkey12}, {F,0,V cfkey12}, DFAULT, DFAULT, DFAULT, DFAULT,
+/*124*/ KBD_KP, I, DFAULT, DFAULT, DFAULT, DFAULT, DFAULT, DFAULT, DFAULT,
+/*125*/ KBD_SCROLL,I, DFAULT, DFAULT, DFAULT, DFAULT, DFAULT, DFAULT, DFAULT,
+/*126*/ KBD_BREAK, I, DFAULT, DFAULT, DFAULT, DFAULT, DFAULT, DFAULT, DFAULT,
+/*127*/ KBD_FUNC, I, DFAULT, DFAULT, DFAULT, DFAULT, DFAULT, DFAULT, DFAULT,
+
+#undef C
+#undef U
+#undef V
+#undef S
+#undef F
+#undef I
+#undef DFLT
+};
+
+#else /* PCVT_ALT_ENH */
+
+/* define some shorthands to make the table (almost) fit into 80 columns */
+#define C (u_char *)
+#define V (void *)
+#define S STR
+#define F FNC
+#define I IDX0
+
+/* DONT EVER OVERLOAD KEY 0, THIS IS A KEY THAT MUSTN'T EXIST */
+
+/* type index unshift shift ctrl */
+/* ---------------------------------------------------------- */
+/* 0*/ KBD_NONE, I, {S,C "df"}, {S,C ""}, {S,C ""},
+/* 1*/ KBD_ASCII, I, {S,C "`"}, {S,C "~"}, {S,C "`"},
+/* 2*/ KBD_ASCII, I, {S,C "1"}, {S,C "!"}, {S,C "1"},
+/* 3*/ KBD_ASCII, I, {S,C "2"}, {S,C "@"}, {S,C "\000"},
+/* 4*/ KBD_ASCII, I, {S,C "3"}, {S,C "#"}, {S,C "3"},
+/* 5*/ KBD_ASCII, I, {S,C "4"}, {S,C "$"}, {S,C "4"},
+/* 6*/ KBD_ASCII, I, {S,C "5"}, {S,C "%"}, {S,C "5"},
+/* 7*/ KBD_ASCII, I, {S,C "6"}, {S,C "^"}, {S,C "\036"},
+/* 8*/ KBD_ASCII, I, {S,C "7"}, {S,C "&"}, {S,C "7"},
+/* 9*/ KBD_ASCII, I, {S,C "8"}, {S,C "*"}, {S,C "9"},
+/* 10*/ KBD_ASCII, I, {S,C "9"}, {S,C "("}, {S,C "9"},
+/* 11*/ KBD_ASCII, I, {S,C "0"}, {S,C ")"}, {S,C "0"},
+/* 12*/ KBD_ASCII, I, {S,C "-"}, {S,C "_"}, {S,C "\037"},
+/* 13*/ KBD_ASCII, I, {S,C "="}, {S,C "+"}, {S,C "="},
+/* 14*/ KBD_NONE, I, {S,C ""}, {S,C ""}, {S,C ""},
+/* 15*/ KBD_ASCII, I, {S,C "\177"}, {S,C "\010"}, {S,C "\177"}, /* BS */
+/* 16*/ KBD_ASCII, I, {S,C "\t"}, {S,C "\t"}, {S,C "\t"}, /* TAB */
+/* 17*/ KBD_ASCII, I, {S,C "q"}, {S,C "Q"}, {S,C "\021"},
+/* 18*/ KBD_ASCII, I, {S,C "w"}, {S,C "W"}, {S,C "\027"},
+/* 19*/ KBD_ASCII, I, {S,C "e"}, {S,C "E"}, {S,C "\005"},
+/* 20*/ KBD_ASCII, I, {S,C "r"}, {S,C "R"}, {S,C "\022"},
+/* 21*/ KBD_ASCII, I, {S,C "t"}, {S,C "T"}, {S,C "\024"},
+/* 22*/ KBD_ASCII, I, {S,C "y"}, {S,C "Y"}, {S,C "\031"},
+/* 23*/ KBD_ASCII, I, {S,C "u"}, {S,C "U"}, {S,C "\025"},
+/* 24*/ KBD_ASCII, I, {S,C "i"}, {S,C "I"}, {S,C "\011"},
+/* 25*/ KBD_ASCII, I, {S,C "o"}, {S,C "O"}, {S,C "\017"},
+/* 26*/ KBD_ASCII, I, {S,C "p"}, {S,C "P"}, {S,C "\020"},
+/* 27*/ KBD_ASCII, I, {S,C "["}, {S,C "{"}, {S,C "\033"},
+/* 28*/ KBD_ASCII, I, {S,C "]"}, {S,C "}"}, {S,C "\035"},
+/* 29*/ KBD_ASCII, I, {S,C "\\"}, {S,C "|"}, {S,C "\034"},
+/* 30*/ KBD_CAPS, I, {S,C ""}, {S,C ""}, {S,C ""},
+/* 31*/ KBD_ASCII, I, {S,C "a"}, {S,C "A"}, {S,C "\001"},
+/* 32*/ KBD_ASCII, I, {S,C "s"}, {S,C "S"}, {S,C "\023"},
+/* 33*/ KBD_ASCII, I, {S,C "d"}, {S,C "D"}, {S,C "\004"},
+/* 34*/ KBD_ASCII, I, {S,C "f"}, {S,C "F"}, {S,C "\006"},
+/* 35*/ KBD_ASCII, I, {S,C "g"}, {S,C "G"}, {S,C "\007"},
+/* 36*/ KBD_ASCII, I, {S,C "h"}, {S,C "H"}, {S,C "\010"},
+/* 37*/ KBD_ASCII, I, {S,C "j"}, {S,C "J"}, {S,C "\n"},
+/* 38*/ KBD_ASCII, I, {S,C "k"}, {S,C "K"}, {S,C "\013"},
+/* 39*/ KBD_ASCII, I, {S,C "l"}, {S,C "L"}, {S,C "\014"},
+/* 40*/ KBD_ASCII, I, {S,C ";"}, {S,C ":"}, {S,C ";"},
+/* 41*/ KBD_ASCII, I, {S,C "'"}, {S,C "\""}, {S,C "'"},
+/* 42*/ KBD_ASCII, I, {S,C "\\"}, {S,C "|"}, {S,C "\034"}, /* special */
+/* 43*/ KBD_RETURN,I, {S,C "\r"}, {S,C "\r"}, {S,C "\r"}, /* RETURN */
+/* 44*/ KBD_SHIFT, I, {S,C ""}, {S,C ""}, {S,C ""}, /* SHIFT left */
+/* 45*/ KBD_ASCII, I, {S,C "<"}, {S,C ">"}, {S,C ""},
+/* 46*/ KBD_ASCII, I, {S,C "z"}, {S,C "Z"}, {S,C "\032"},
+/* 47*/ KBD_ASCII, I, {S,C "x"}, {S,C "X"}, {S,C "\030"},
+/* 48*/ KBD_ASCII, I, {S,C "c"}, {S,C "C"}, {S,C "\003"},
+/* 49*/ KBD_ASCII, I, {S,C "v"}, {S,C "V"}, {S,C "\026"},
+/* 50*/ KBD_ASCII, I, {S,C "b"}, {S,C "B"}, {S,C "\002"},
+/* 51*/ KBD_ASCII, I, {S,C "n"}, {S,C "N"}, {S,C "\016"},
+/* 52*/ KBD_ASCII, I, {S,C "m"}, {S,C "M"}, {S,C "\r"},
+/* 53*/ KBD_ASCII, I, {S,C ","}, {S,C "<"}, {S,C ","},
+/* 54*/ KBD_ASCII, I, {S,C "."}, {S,C ">"}, {S,C "."},
+/* 55*/ KBD_ASCII, I, {S,C "/"}, {S,C "?"}, {S,C "/"},
+/* 56*/ KBD_NONE, I, {S,C ""}, {S,C ""}, {S,C ""},
+/* 57*/ KBD_SHIFT, I, {S,C ""}, {S,C ""}, {S,C ""}, /* SHIFT right */
+/* 58*/ KBD_CTL, I, {S,C ""}, {S,C ""}, {S,C ""}, /* CTL left */
+/* 59*/ KBD_ASCII, I, {S,C ""}, {S,C ""}, {S,C ""},
+/* 60*/ KBD_META, I, {S,C ""}, {S,C ""}, {S,C ""}, /* ALT left */
+#if !PCVT_NULLCHARS
+/* 61*/ KBD_ASCII, I, {S,C " "}, {S,C " "}, {S,C " "}, /* SPACE */
+#else
+/* 61*/ KBD_ASCII, I, {S,C " "}, {S,C " "}, {S,C "\000"}, /* SPACE */
+#endif /* PCVT_NULLCHARS */
+/* 62*/ KBD_META, I, {S,C ""}, {S,C ""}, {S,C ""}, /* ALT right */
+/* 63*/ KBD_ASCII, I, {S,C ""}, {S,C ""}, {S,C ""},
+/* 64*/ KBD_CTL, I, {S,C ""}, {S,C ""}, {S,C ""}, /* CTL right */
+/* 65*/ KBD_NONE, I, {S,C ""}, {S,C ""}, {S,C ""},
+/* 66*/ KBD_NONE, I, {S,C ""}, {S,C ""}, {S,C ""},
+/* 67*/ KBD_NONE, I, {S,C ""}, {S,C ""}, {S,C ""},
+/* 68*/ KBD_NONE, I, {S,C ""}, {S,C ""}, {S,C ""},
+/* 69*/ KBD_NONE, I, {S,C ""}, {S,C ""}, {S,C ""},
+/* 70*/ KBD_NONE, I, {S,C ""}, {S,C ""}, {S,C ""},
+/* 71*/ KBD_NONE, I, {S,C ""}, {S,C ""}, {S,C ""},
+/* 72*/ KBD_NONE, I, {S,C ""}, {S,C ""}, {S,C ""},
+/* 73*/ KBD_NONE, I, {S,C ""}, {S,C ""}, {S,C ""},
+/* 74*/ KBD_NONE, I, {S,C ""}, {S,C ""}, {S,C ""},
+/* 75*/ KBD_FUNC, I, {S,C "\033[2~"},{S,C "\033[2~"},{S,C "\033[2~"},/* INS */
+/* 76*/ KBD_FUNC, I, {S,C "\033[3~"},{S,C "\033[3~"},{S,C "\033[3~"},/* DEL */
+/* 77*/ KBD_NONE, I, {S,C ""}, {S,C ""}, {S,C ""},
+/* 78*/ KBD_NONE, I, {S,C ""}, {S,C ""}, {S,C ""},
+/* 79*/ KBD_CURSOR,I, {S,C "\033[D"},{S,C "\033OD"},{S,C "\033[D"}, /* CU <- */
+/* 80*/ KBD_FUNC, I, {S,C "\033[1~"},{S,C "\033[1~"},{S,C "\033[1~"},/* HOME = FIND*/
+/* 81*/ KBD_FUNC, I, {S,C "\033[4~"},{S,C "\033[4~"},{S,C "\033[4~"},/* END = SELECT */
+/* 82*/ KBD_NONE, I, {S,C ""}, {S,C ""}, {S,C ""},
+/* 83*/ KBD_CURSOR,I, {S,C "\033[A"},{S,C "\033OA"},{S,C "\033[A"}, /* CU ^ */
+/* 84*/ KBD_CURSOR,I, {S,C "\033[B"},{S,C "\033OB"},{S,C "\033[B"}, /* CU v */
+/* 85*/ KBD_FUNC, I, {S,C "\033[5~"},{S,C "\033[5~"},{S,C "\033[5~"},/*PG UP*/
+/* 86*/ KBD_FUNC, I, {S,C "\033[6~"},{S,C "\033[6~"},{S,C "\033[6~"},/*PG DN*/
+/* 87*/ KBD_NONE, I, {S,C ""}, {S,C ""}, {S,C ""},
+/* 88*/ KBD_NONE, I, {S,C ""}, {S,C ""}, {S,C ""},
+/* 89*/ KBD_CURSOR,I, {S,C "\033[C"},{S,C "\033OC"},{S,C "\033[C"}, /* CU -> */
+/* 90*/ KBD_NUM, I, {S,C ""}, {S,C ""}, {S,C ""},
+/* 91*/ KBD_KP, I, {S,C "7"}, {S,C "\033Ow"},{S,C "7"},
+/* 92*/ KBD_KP, I, {S,C "4"}, {S,C "\033Ot"},{S,C "4"},
+/* 93*/ KBD_KP, I, {S,C "1"}, {S,C "\033Oq"},{S,C "1"},
+/* 94*/ KBD_NONE, I, {S,C ""}, {S,C ""}, {S,C ""},
+/* 95*/ KBD_KP, I, {S,C "/"}, {S,C "/"}, {S,C "/"},
+/* 96*/ KBD_KP, I, {S,C "8"}, {S,C "\033Ox"},{S,C "8"},
+/* 97*/ KBD_KP, I, {S,C "5"}, {S,C "\033Ou"},{S,C "5"},
+/* 98*/ KBD_KP, I, {S,C "2"}, {S,C "\033Or"},{S,C "2"},
+/* 99*/ KBD_KP, I, {S,C "0"}, {S,C "\033Op"},{S,C "0"},
+/*100*/ KBD_KP, I, {S,C "*"}, {S,C "*"}, {S,C "*"},
+/*101*/ KBD_KP, I, {S,C "9"}, {S,C "\033Oy"},{S,C "9"},
+/*102*/ KBD_KP, I, {S,C "6"}, {S,C "\033Ov"},{S,C "6"},
+/*103*/ KBD_KP, I, {S,C "3"}, {S,C "\033Os"},{S,C "3"},
+/*104*/ KBD_KP, I, {S,C "."}, {S,C "\033On"},{S,C "."},
+/*105*/ KBD_KP, I, {S,C "-"}, {S,C "\033Om"},{S,C "-"},
+/*106*/ KBD_KP, I, {S,C "+"}, {S,C "+"}, {S,C "+"},
+/*107*/ KBD_NONE, I, {S,C ""}, {S,C ""}, {S,C ""},
+/*108*/ KBD_RETURN,I, {S,C "\r"}, {S,C "\033OM"},{S,C "\r"}, /* KP ENTER */
+/*109*/ KBD_NONE, I, {S,C ""}, {S,C ""}, {S,C ""},
+/*110*/ KBD_ASCII, I, {S,C "\033"}, {S,C "\033"}, {S,C "\033"},
+/*111*/ KBD_NONE, I, {S,C ""}, {S,C ""}, {S,C ""},
+/*112*/ KBD_FUNC, I, {F,V fkey1}, {F,V sfkey1}, {F,V cfkey1}, /* F1 */
+/*113*/ KBD_FUNC, I, {F,V fkey2}, {F,V sfkey2}, {F,V cfkey2}, /* F2 */
+/*114*/ KBD_FUNC, I, {F,V fkey3}, {F,V sfkey3}, {F,V cfkey3}, /* F3 */
+/*115*/ KBD_FUNC, I, {F,V fkey4}, {F,V sfkey4}, {F,V cfkey4}, /* F4 */
+/*116*/ KBD_FUNC, I, {F,V fkey5}, {F,V sfkey5}, {F,V cfkey5}, /* F5 */
+/*117*/ KBD_FUNC, I, {F,V fkey6}, {F,V sfkey6}, {F,V cfkey6}, /* F6 */
+/*118*/ KBD_FUNC, I, {F,V fkey7}, {F,V sfkey7}, {F,V cfkey7}, /* F7 */
+/*119*/ KBD_FUNC, I, {F,V fkey8}, {F,V sfkey8}, {F,V cfkey8}, /* F8 */
+/*120*/ KBD_FUNC, I, {F,V fkey9}, {F,V sfkey9}, {F,V cfkey9}, /* F9 */
+/*121*/ KBD_FUNC, I, {F,V fkey10}, {F,V sfkey10}, {F,V cfkey10}, /* F10 */
+/*122*/ KBD_FUNC, I, {F,V fkey11}, {F,V sfkey11}, {F,V cfkey11}, /* F11 */
+/*123*/ KBD_FUNC, I, {F,V fkey12}, {F,V sfkey12}, {F,V cfkey12}, /* F12 */
+/*124*/ KBD_KP, I, {S,C ""}, {S,C ""}, {S,C ""},
+/*125*/ KBD_SCROLL,I, {S,C ""}, {S,C ""}, {S,C ""},
+/*126*/ KBD_BREAK, I, {S,C ""}, {S,C ""}, {S,C ""},
+/*127*/ KBD_FUNC, I, {S,C ""}, {S,C ""}, {S,C ""}, /* SysRq */
+
+#undef C
+#undef V
+#undef S
+#undef F
+#undef I
+};
+
+#endif /* PCVT_ALT_ENH */
+
+static short keypad2num[] = {
+ 7, 4, 1, -1, -1, 8, 5, 2, 0, -1, 9, 6, 3, -1, -1, -1, -1
+};
+
+#define N_KEYNUMS 128
+
+/*
+ * this is the reverse mapping from keynumbers to scanset 1 codes
+ * it is used to emulate the SysV-style GIO_KEYMAP ioctl cmd
+ */
+
+static u_char key2scan1[N_KEYNUMS] = {
+ 0,0x29,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09, /* 0 */
+ 0x0a,0x0b,0x0c,0x0d, 0,0x0e,0x0f,0x10,0x11,0x12, /* 10 */
+ 0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x2b, /* 20 */
+ 0x3a,0x1e,0x1f,0x20,0x21,0x22,0x23,0x24,0x25,0x26, /* 30 */
+ 0x27,0x28, 0,0x1c,0x2a,0x56,0x2c,0x2d,0x2e,0x2f, /* 40 */
+ 0x30,0x31,0x32,0x33,0x34,0x35,0x56,0x36,0x1d, 0, /* 50 */
+ 0x38,0x39, 0, 0, 0, 0, 0, 0, 0, 0, /* 60 */
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 70 */
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 80 */
+ 0x45,0x47,0x4b,0x4f, 0, 0,0x48,0x4c,0x50,0x52, /* 90 */
+ 0x37,0x49,0x4d,0x51,0x53,0x4a,0x4e, 0, 0, 0, /* 100 */
+ 0x01, 0,0x3b,0x3c,0x3d,0x3e,0x3f,0x40,0x41,0x42, /* 110 */
+ 0x43,0x44,0x57,0x58, 0,0x46, 0,0x54 /* 120 */
+};
+
+/*
+ * SysV is brain-dead enough to stick on the IBM code page 437. So we
+ * have to translate our keymapping into IBM 437 (possibly losing keys),
+ * in order to have the X server convert it back into ISO8859.1
+ */
+
+/* NB: this table only contains the mapping for codes >= 128 */
+
+static u_char iso2ibm437[] =
+{
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0xff, 0xad, 0x9b, 0x9c, 0, 0x9d, 0, 0x40,
+ 0x6f, 0x63, 0x61, 0xae, 0, 0, 0, 0,
+ 0xf8, 0xf1, 0xfd, 0x33, 0, 0xe6, 0, 0xfa,
+ 0, 0x31, 0x6f, 0xaf, 0xac, 0xab, 0, 0xa8,
+ 0x41, 0x41, 0x41, 0x41, 0x8e, 0x8f, 0x92, 0x80,
+ 0x45, 0x90, 0x45, 0x45, 0x49, 0x49, 0x49, 0x49,
+ 0x81, 0xa5, 0x4f, 0x4f, 0x4f, 0x4f, 0x99, 0x4f,
+ 0x4f, 0x55, 0x55, 0x55, 0x9a, 0x59, 0, 0xe1,
+ 0x85, 0xa0, 0x83, 0x61, 0x84, 0x86, 0x91, 0x87,
+ 0x8a, 0x82, 0x88, 0x89, 0x8d, 0xa1, 0x8c, 0x8b,
+ 0, 0xa4, 0x95, 0xa2, 0x93, 0x6f, 0x94, 0x6f,
+ 0x6f, 0x97, 0xa3, 0x96, 0x81, 0x98, 0, 0
+};
+
+/* EOF */
diff --git a/sys/arch/i386/isa/pcvt/pcvt_out.c b/sys/arch/i386/isa/pcvt/pcvt_out.c
new file mode 100644
index 00000000000..9a463527a72
--- /dev/null
+++ b/sys/arch/i386/isa/pcvt/pcvt_out.c
@@ -0,0 +1,2304 @@
+/*
+ * Copyright (c) 1992, 1995 Hellmuth Michaelis and Joerg Wunsch.
+ *
+ * Copyright (c) 1992, 1993 Brian Dunford-Shore.
+ *
+ * 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 Hellmuth Michaelis,
+ * Brian Dunford-Shore and Joerg Wunsch.
+ * 4. The name authors may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``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 AUTHORS 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.
+ *
+ *
+ * @(#)pcvt_out.c, 3.32, Last Edit-Date: [Tue Oct 3 11:19:49 1995]
+ *
+ */
+
+/*---------------------------------------------------------------------------*
+ *
+ * pcvt_out.c VT220 Terminal Emulator
+ * ---------------------------------------
+ * -hm ------------ Release 3.00 --------------
+ * -hm integrating NetBSD-current patches
+ * -hm integrating patch from Thomas Gellekum
+ * -hm bugfix: clear last line when hpmode 28lines and force 24
+ * -hm right fkey labels after soft/hard reset
+ * -hm patch from Joerg for comconsole operation
+ * -hm patch from Lon Willet to preserve the initial cursor shape
+ * -hm if FAT_CURSOR is defined, you get the old cursor type back ..
+ * -hm patch from Lon Willett regarding winsize settings
+ * -hm applying patch from Joerg fixing Crtat bug, non VGA startup bug
+ * -hm setting variable color for CGA and MDA/HGC in coldinit
+ * -hm fixing bug initializing cursor position on startup
+ * -hm fixing support for EGA boards in vt_coldinit()
+ * -hm bugfix from Joerg: check for svsp->vs_tty before using it
+ * -hm patches from Michael for NetBSD-current (Apr/21/95) support
+ * -hm ---------------- Release 3.30 -----------------------
+ * -hm patch from Thomas Gellekum to support C1 controls
+ * -hm patch from Frank van der Linden for keyboard state per VT
+ * -hm ---------------- Release 3.32 -----------------------
+ *
+ *---------------------------------------------------------------------------*/
+
+#include "vt.h"
+#if NVT > 0
+
+#define PCVT_INCLUDE_VT_SELATTR /* get inline function from pcvt_hdr.h */
+
+#include "pcvt_hdr.h" /* global include */
+
+static void check_scroll ( struct video_state *svsp );
+static void hp_entry ( U_char ch, struct video_state *svsp );
+static void vt_coldinit ( void );
+static void wrfkl ( int num, u_char *string, struct video_state *svsp );
+static void writefkl ( int num, u_char *string, struct video_state *svsp );
+
+
+/*---------------------------------------------------------------------------*
+ * do character set transformation and write to display memory (inline)
+ *---------------------------------------------------------------------------*/
+
+#define video (svsp->Crtat + svsp->cur_offset)
+
+static __inline void write_char (svsp, attrib, ch)
+struct video_state *svsp;
+u_short attrib, ch;
+{
+ if ((ch >= 0x20) && (ch <= 0x7f)) /* use GL if ch >= 0x20 */
+ {
+ if(!svsp->ss) /* single shift G2/G3 -> GL ? */
+ {
+ *video = attrib | svsp->GL[ch-0x20];
+ }
+ else
+ {
+ *video = attrib | svsp->Gs[ch-0x20];
+ svsp->ss = 0;
+ }
+ }
+ else
+ {
+ svsp->ss = 0;
+
+ if(ch >= 0x80) /* display controls C1 */
+ {
+ if(ch >= 0xA0) /* use GR if ch >= 0xA0 */
+ {
+ *video = attrib | svsp->GR[ch-0xA0];
+ }
+ else
+ {
+ if(vgacs[svsp->vga_charset].secondloaded)
+ {
+ *video = attrib | ((ch-0x60) | CSH);
+ }
+ else /* use normal ibm charset for
+ control display */
+ {
+ *video = attrib | ch;
+ }
+ }
+ }
+ else /* display controls C0 */
+ {
+ if(vgacs[svsp->vga_charset].secondloaded)
+ {
+ *video = attrib | (ch | CSH);
+ }
+ else /* use normal ibm charset for control display*/
+ {
+ *video = attrib | ch;
+ }
+ }
+ }
+}
+
+/*---------------------------------------------------------------------------*
+ * emulator main entry
+ *---------------------------------------------------------------------------*/
+void
+sput (u_char *s, U_char kernel, int len, int page)
+{
+ register struct video_state *svsp;
+ u_short attrib;
+ u_short ch;
+
+ if(page >= PCVT_NSCREENS) /* failsafe */
+ page = 0;
+
+ svsp = &vs[page]; /* pointer to current screen state */
+
+ if(do_initialization) /* first time called ? */
+ vt_coldinit(); /* yes, we have to init ourselves */
+
+ if(svsp == vsp) /* on current displayed page ? */
+ {
+ cursor_pos_valid = 0; /* do not update cursor */
+
+#if PCVT_SCREENSAVER
+ if(scrnsv_active) /* screen blanked ? */
+ pcvt_scrnsv_reset(); /* unblank NOW ! */
+ else
+ reset_screen_saver = 1; /* do it asynchronously */
+#endif /* PCVT_SCREENSAVER */
+
+ }
+
+ attrib = kernel ? kern_attr : svsp->c_attr;
+
+ while (len-- > 0)
+ if (ch = (*(s++)))
+ {
+ if(svsp->sevenbit)
+ ch &= 0x7f;
+
+ if((svsp->transparent == 0)
+ && ((ch <= 0x1f)
+ || (svsp->C1_ctls && (ch > 0x7f) && (ch < 0xa0))))
+ {
+
+ /* always process control-chars in the range 0x00..0x1f !!! */
+
+ /* also process the C1 control chars a VT220 recognizes and
+ * ignore the others.
+ */
+ if(svsp->dis_fnc)
+ {
+ if(svsp->lastchar && svsp->m_awm
+ && (svsp->lastrow == svsp->row))
+ {
+ svsp->cur_offset++;
+ svsp->col = 0;
+ svsp->lastchar = 0;
+ check_scroll(svsp);
+ }
+
+ if(svsp->irm)
+ bcopy((svsp->Crtat + svsp->cur_offset),
+ (svsp->Crtat + svsp->cur_offset) + 1,
+ (((svsp->maxcol)-1) - svsp->col)*CHR);
+
+ write_char(svsp, attrib, ch);
+
+ vt_selattr(svsp);
+
+ if(svsp->col >= ((svsp->maxcol)-1)
+ && ch != 0x0a && ch != 0x0b && ch != 0x0c)
+ {
+ svsp->lastchar = 1;
+ svsp->lastrow = svsp->row;
+ }
+ else if(ch == 0x0a || ch == 0x0b || ch == 0x0c)
+ {
+ svsp->cur_offset -= svsp->col;
+ svsp->cur_offset += svsp->maxcol;
+ svsp->col = 0;
+ svsp->lastchar = 0;
+ check_scroll(svsp); /* check scroll up */
+ }
+ else
+ {
+ svsp->cur_offset++;
+ svsp->col++;
+ svsp->lastchar = 0;
+ }
+ }
+ else
+ {
+ switch(ch)
+ {
+ case 0x00: /* NUL */
+ case 0x01: /* SOH */
+ case 0x02: /* STX */
+ case 0x03: /* ETX */
+ case 0x04: /* EOT */
+ case 0x05: /* ENQ */
+ case 0x06: /* ACK */
+ break;
+
+ case 0x07: /* BEL */
+ if(svsp->bell_on)
+ sysbeep(PCVT_SYSBEEPF/1500, hz/4);
+ break;
+
+ case 0x08: /* BS */
+ if(svsp->col > 0)
+ {
+ svsp->cur_offset--;
+ svsp->col--;
+ }
+ break;
+
+ case 0x09: /* TAB */
+ while(svsp->col < ((svsp->maxcol)-1))
+ {
+ svsp->cur_offset++;
+ if(svsp->
+ tab_stops[++svsp->col])
+ break;
+ }
+ break;
+
+ case 0x0a: /* LF */
+ case 0x0b: /* VT */
+ case 0x0c: /* FF */
+ if(svsp->lnm)
+ {
+ svsp->cur_offset -= svsp->col;
+ svsp->cur_offset +=
+ svsp->maxcol;
+ svsp->col = 0;
+ }
+ else
+ {
+ svsp->cur_offset +=
+ svsp->maxcol;
+ }
+ check_scroll(svsp);
+ break;
+
+ case 0x0d: /* CR */
+ svsp->cur_offset -= svsp->col;
+ svsp->col = 0;
+ break;
+
+ case 0x0e: /* SO */
+ svsp->GL = svsp->G1;
+ break;
+
+ case 0x0f: /* SI */
+ svsp->GL = svsp->G0;
+ break;
+
+ case 0x10: /* DLE */
+ case 0x11: /* DC1/XON */
+ case 0x12: /* DC2 */
+ case 0x13: /* DC3/XOFF */
+ case 0x14: /* DC4 */
+ case 0x15: /* NAK */
+ case 0x16: /* SYN */
+ case 0x17: /* ETB */
+ break;
+
+ case 0x18: /* CAN */
+ svsp->state = STATE_INIT;
+ clr_parms(svsp);
+ break;
+
+ case 0x19: /* EM */
+ break;
+
+ case 0x1a: /* SUB */
+ svsp->state = STATE_INIT;
+ clr_parms(svsp);
+ break;
+
+ case 0x1b: /* ESC */
+ svsp->state = STATE_ESC;
+ clr_parms(svsp);
+ break;
+
+ case 0x1c: /* FS */
+ case 0x1d: /* GS */
+ case 0x1e: /* RS */
+ case 0x1f: /* US */
+ break;
+
+ case 0x80: /* */
+ case 0x81: /* */
+ case 0x82: /* */
+ case 0x83: /* */
+ break;
+
+ case 0x84: /* IND */
+ vt_ind(svsp);
+ break;
+
+ case 0x85: /* NEL */
+ vt_nel(svsp);
+ break;
+
+ case 0x86: /* SSA */
+ case 0x87: /* ESA */
+ break;
+
+ case 0x88: /* HTS */
+ svsp->tab_stops[svsp->col] = 1;
+ break;
+
+ case 0x89: /* HTJ */
+ case 0x8a: /* VTS */
+ case 0x8b: /* PLD */
+ case 0x8c: /* PLU */
+ break;
+
+ case 0x8d: /* RI */
+ vt_ri(svsp);
+ break;
+
+ case 0x8e: /* SS2 */
+ svsp->Gs = svsp->G2;
+ svsp->ss = 1;
+ break;
+
+ case 0x8f: /* SS3 */
+ svsp->Gs = svsp->G3;
+ svsp->ss = 1;
+ break;
+
+ case 0x90: /* DCS */
+ svsp->dcs_state = DCS_INIT;
+ svsp->state = STATE_DCS;
+ break;
+
+ case 0x91: /* PU1 */
+ case 0x92: /* PU2 */
+ case 0x93: /* STS */
+ case 0x94: /* CCH */
+ case 0x95: /* MW */
+ case 0x96: /* SPA */
+ case 0x97: /* EPA */
+ case 0x98: /* */
+ case 0x99: /* */
+ case 0x9a: /* */
+ break;
+
+ case 0x9b: /* CSI */
+ clr_parms(svsp);
+ svsp->state = STATE_CSI;
+ break;
+
+ case 0x9c: /* ST */
+ svsp->state = STATE_INIT;
+ break;
+
+ case 0x9d: /* OSC */
+ case 0x9e: /* PM */
+ case 0x9f: /* APC */
+ /* only in VT320's */
+ break;
+ }
+ }
+ }
+ else
+ {
+
+ /* char range 0x20...0xff processing depends on current state */
+
+ switch(svsp->state)
+ {
+ case STATE_INIT:
+ if(svsp->lastchar && svsp->m_awm &&
+ (svsp->lastrow == svsp->row))
+ {
+ svsp->cur_offset++;
+ svsp->col = 0;
+ svsp->lastchar = 0;
+ check_scroll(svsp);
+ }
+
+ if(svsp->irm)
+ bcopy ((svsp->Crtat
+ + svsp->cur_offset),
+ (svsp->Crtat
+ + svsp->cur_offset) + 1,
+ (((svsp->maxcol)-1)
+ - svsp->col) * CHR);
+
+ write_char(svsp, attrib, ch);
+
+ vt_selattr(svsp);
+
+ if(svsp->col >= ((svsp->maxcol)-1))
+ {
+ svsp->lastchar = 1;
+ svsp->lastrow = svsp->row;
+ }
+ else
+ {
+ svsp->lastchar = 0;
+ svsp->cur_offset++;
+ svsp->col++;
+ }
+ break;
+
+ case STATE_ESC:
+ switch(ch)
+ {
+ case ' ': /* ESC sp family */
+ svsp->state = STATE_BLANK;
+ break;
+
+ case '#': /* ESC # family */
+ svsp->state = STATE_HASH;
+ break;
+
+ case '&': /* ESC & family (HP) */
+ if(svsp->vt_pure_mode ==
+ M_HPVT)
+ {
+ svsp->state =
+ STATE_AMPSND;
+ svsp->hp_state =
+ SHP_INIT;
+ }
+ else
+ svsp->state =
+ STATE_INIT;
+ break;
+
+ case '(': /* ESC ( family */
+ svsp->state = STATE_BROPN;
+ break;
+
+ case ')': /* ESC ) family */
+ svsp->state = STATE_BRCLO;
+ break;
+
+ case '*': /* ESC * family */
+ svsp->state = STATE_STAR;
+ break;
+
+ case '+': /* ESC + family */
+ svsp->state = STATE_PLUS;
+ break;
+
+ case '-': /* ESC - family */
+ svsp->state = STATE_MINUS;
+ break;
+
+ case '.': /* ESC . family */
+ svsp->state = STATE_DOT;
+ break;
+
+ case '/': /* ESC / family */
+ svsp->state = STATE_SLASH;
+ break;
+
+ case '7': /* SAVE CURSOR */
+ vt_sc(svsp);
+ svsp->state = STATE_INIT;
+ break;
+
+ case '8': /* RESTORE CURSOR */
+ vt_rc(svsp);
+ if (!kernel)
+ attrib = svsp->c_attr;
+ svsp->state = STATE_INIT;
+ break;
+
+ case '=': /* keypad application mode */
+#if !PCVT_INHIBIT_NUMLOCK
+ vt_keyappl(svsp);
+#endif
+ svsp->state = STATE_INIT;
+ break;
+
+ case '>': /* keypad numeric mode */
+#if !PCVT_INHIBIT_NUMLOCK
+ vt_keynum(svsp);
+#endif
+ svsp->state = STATE_INIT;
+ break;
+
+ case 'D': /* INDEX */
+ vt_ind(svsp);
+ svsp->state = STATE_INIT;
+ break;
+
+ case 'E': /* NEXT LINE */
+ vt_nel(svsp);
+ svsp->state = STATE_INIT;
+ break;
+
+ case 'H': /* set TAB at current col */
+ svsp->tab_stops[svsp->col] = 1;
+ svsp->state = STATE_INIT;
+ break;
+
+ case 'M': /* REVERSE INDEX */
+ vt_ri(svsp);
+ svsp->state = STATE_INIT;
+ break;
+
+ case 'N': /* SINGLE SHIFT G2 */
+ svsp->Gs = svsp->G2;
+ svsp->ss = 1;
+ svsp->state = STATE_INIT;
+ break;
+
+ case 'O': /* SINGLE SHIFT G3 */
+ svsp->Gs = svsp->G3;
+ svsp->ss = 1;
+ svsp->state = STATE_INIT;
+ break;
+
+ case 'P': /* DCS detected */
+ svsp->dcs_state = DCS_INIT;
+ svsp->state = STATE_DCS;
+ break;
+
+ case 'Z': /* What are you = ESC [ c */
+ vt_da(svsp);
+ svsp->state = STATE_INIT;
+ break;
+
+ case '[': /* CSI detected */
+ clr_parms(svsp);
+ svsp->state = STATE_CSI;
+ break;
+
+ case '\\': /* String Terminator */
+ svsp->state = STATE_INIT;
+ break;
+
+ case 'c': /* hard reset */
+ vt_ris(svsp);
+ if (!kernel)
+ attrib = svsp->c_attr;
+ svsp->state = STATE_INIT;
+ break;
+
+#if PCVT_SETCOLOR
+ case 'd': /* set color sgr */
+ if(color)
+ {
+ /* set shiftwidth=4 */
+ sgr_tab_color
+ [svsp->
+ vtsgr] =
+ svsp->c_attr
+ >> 8;
+ user_attr =
+ sgr_tab_color
+ [0] << 8;
+ }
+ svsp->state = STATE_INIT;
+ break;
+#endif /* PCVT_SETCOLOR */
+ case 'n': /* Lock Shift G2 -> GL */
+ svsp->GL = svsp->G2;
+ svsp->state = STATE_INIT;
+ break;
+
+ case 'o': /* Lock Shift G3 -> GL */
+ svsp->GL = svsp->G3;
+ svsp->state = STATE_INIT;
+ break;
+
+ case '}': /* Lock Shift G2 -> GR */
+ svsp->GR = svsp->G2;
+ svsp->state = STATE_INIT;
+ break;
+
+ case '|': /* Lock Shift G3 -> GR */
+ svsp->GR = svsp->G3;
+ svsp->state = STATE_INIT;
+ break;
+
+ case '~': /* Lock Shift G1 -> GR */
+ svsp->GR = svsp->G1;
+ svsp->state = STATE_INIT;
+ break;
+
+ default:
+ svsp->state = STATE_INIT;
+ break;
+ }
+ break;
+
+ case STATE_BLANK: /* ESC space [FG], which are */
+ svsp->state = STATE_INIT; /* currently ignored*/
+ break;
+
+ case STATE_HASH:
+ switch(ch)
+ {
+ case '3': /* double height top half */
+ case '4': /*double height bottom half*/
+ case '5': /*single width sngle height*/
+ case '6': /*double width sngle height*/
+ svsp->state = STATE_INIT;
+ break;
+
+ case '8': /* fill sceen with 'E's */
+ vt_aln(svsp);
+ svsp->state = STATE_INIT;
+ break;
+
+ default: /* anything else */
+ svsp->state = STATE_INIT;
+ break;
+ }
+ break;
+
+ case STATE_BROPN: /* designate G0 */
+ case STATE_BRCLO: /* designate G1 */
+ case STATE_STAR: /* designate G2 */
+ case STATE_PLUS: /* designate G3 */
+ case STATE_MINUS: /* designate G1 (96) */
+ case STATE_DOT: /* designate G2 (96) */
+ case STATE_SLASH: /* designate G3 (96) */
+ svsp->which[svsp->whichi++] = ch;
+ if(ch >= 0x20 && ch <= 0x2f
+ && svsp->whichi <= 2)
+ break;
+ else if(ch >=0x30 && ch <= 0x7e)
+ {
+ svsp->which[svsp->whichi] = '\0';
+ vt_designate(svsp);
+ }
+ svsp->whichi = 0;
+ svsp->state = STATE_INIT;
+ break;
+
+ case STATE_CSIQM: /* DEC private modes */
+ switch(ch)
+ {
+ case '0':
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ case '8':
+ case '9': /* parameters */
+ svsp->parms[svsp->parmi] *= 10;
+ svsp->parms[svsp->parmi] +=
+ (ch -'0');
+ break;
+
+ case ';': /* next parameter */
+ svsp->parmi =
+ (svsp->parmi+1 < MAXPARMS) ?
+ svsp->parmi+1 : svsp->parmi;
+ break;
+
+ case 'h': /* set mode */
+ vt_set_dec_priv_qm(svsp);
+ svsp->state = STATE_INIT;
+ break;
+
+ case 'l': /* reset mode */
+ vt_reset_dec_priv_qm(svsp);
+ svsp->state = STATE_INIT;
+ break;
+
+ case 'n': /* Reports */
+ vt_dsr(svsp);
+ svsp->state = STATE_INIT;
+ break;
+
+ case 'K': /* selective erase in line */
+ vt_sel(svsp);
+ svsp->state = STATE_INIT;
+ break;
+
+ case 'J':/*selective erase in display*/
+ vt_sed(svsp);
+ svsp->state = STATE_INIT;
+ break;
+
+ default:
+ svsp->state = STATE_INIT;
+ break;
+
+ }
+ break;
+
+ case STATE_CSI:
+ switch(ch)
+ {
+ case '0':
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ case '8':
+ case '9': /* parameters */
+ svsp->parms[svsp->parmi] *= 10;
+ svsp->parms[svsp->parmi] +=
+ (ch -'0');
+ break;
+
+ case ';': /* next parameter */
+ svsp->parmi =
+ (svsp->parmi+1 < MAXPARMS) ?
+ svsp->parmi+1 : svsp->parmi;
+ break;
+
+ case '?': /* ESC [ ? family */
+ svsp->state = STATE_CSIQM;
+ break;
+
+ case '@': /* insert char */
+ vt_ic(svsp);
+ svsp->state = STATE_INIT;
+ break;
+
+ case '"': /* select char attribute */
+ svsp->state = STATE_DQUOTE;
+ break;
+
+ case '\'': /* for DECELR/DECSLE */
+/* XXX */ /* another state needed -hm */
+ break;
+
+ case '!': /* soft terminal reset */
+ svsp->state = STATE_STR;
+ break;
+
+ case 'A': /* cursor up */
+ vt_cuu(svsp);
+ svsp->state = STATE_INIT;
+ break;
+
+ case 'B': /* cursor down */
+ vt_cud(svsp);
+ svsp->state = STATE_INIT;
+ break;
+
+ case 'C': /* cursor forward */
+ vt_cuf(svsp);
+ svsp->state = STATE_INIT;
+ break;
+
+ case 'D': /* cursor backward */
+ vt_cub(svsp);
+ svsp->state = STATE_INIT;
+ break;
+
+ case 'H': /* direct cursor addressing*/
+ vt_curadr(svsp);
+ svsp->state = STATE_INIT;
+ break;
+
+ case 'J': /* erase screen */
+ vt_clreos(svsp);
+ svsp->state = STATE_INIT;
+ break;
+
+ case 'K': /* erase line */
+ vt_clreol(svsp);
+ svsp->state = STATE_INIT;
+ break;
+
+ case 'L': /* insert line */
+ vt_il(svsp);
+ svsp->state = STATE_INIT;
+ break;
+
+ case 'M': /* delete line */
+ vt_dl(svsp);
+ svsp->state = STATE_INIT;
+ break;
+
+ case 'P': /* delete character */
+ vt_dch(svsp);
+ svsp->state = STATE_INIT;
+ break;
+
+ case 'S': /* scroll up */
+ vt_su(svsp);
+ svsp->state = STATE_INIT;
+ break;
+
+ case 'T': /* scroll down */
+ vt_sd(svsp);
+ svsp->state = STATE_INIT;
+ break;
+
+ case 'X': /* erase character */
+ vt_ech(svsp);
+ svsp->state = STATE_INIT;
+ break;
+
+ case 'c': /* device attributes */
+ vt_da(svsp);
+ svsp->state = STATE_INIT;
+ break;
+
+ case 'f': /* direct cursor addressing*/
+ vt_curadr(svsp);
+ svsp->state = STATE_INIT;
+ break;
+
+ case 'g': /* clear tabs */
+ vt_clrtab(svsp);
+ svsp->state = STATE_INIT;
+ break;
+
+ case 'h': /* set mode(s) */
+ vt_set_ansi(svsp);
+ svsp->state = STATE_INIT;
+ break;
+
+ case 'i': /* media copy */
+ vt_mc(svsp);
+ svsp->state = STATE_INIT;
+ break;
+
+ case 'l': /* reset mode(s) */
+ vt_reset_ansi(svsp);
+ svsp->state = STATE_INIT;
+ break;
+
+ case 'm': /* select graphic rendition*/
+ vt_sgr(svsp);
+ if (!kernel)
+ attrib = svsp->c_attr;
+ svsp->state = STATE_INIT;
+ break;
+
+ case 'n': /* reports */
+ vt_dsr(svsp);
+ svsp->state = STATE_INIT;
+ break;
+
+ case 'r': /* set scrolling region */
+ vt_stbm(svsp);
+ svsp->state = STATE_INIT;
+ break;
+
+ case 'x': /*request/report parameters*/
+ vt_reqtparm(svsp);
+ svsp->state = STATE_INIT;
+ break;
+
+ case 'y': /* invoke selftest(s) */
+ vt_tst(svsp);
+ svsp->state = STATE_INIT;
+ break;
+
+ case 'z': /* DECELR, ignored */
+ case '{': /* DECSLE, ignored */
+ svsp->state = STATE_INIT;
+ break;
+
+ default:
+ svsp->state = STATE_INIT;
+ break;
+ }
+ break;
+
+ case STATE_AMPSND:
+ hp_entry(ch,svsp);
+ break;
+
+ case STATE_DCS:
+ vt_dcsentry(ch,svsp);
+ break;
+
+ case STATE_DQUOTE:
+ switch(ch)
+ {
+ case 'p': /* compatibility level */
+ vt_scl(svsp);
+ svsp->state = STATE_INIT;
+ break;
+
+ case 'q': /* select char attributes */
+ vt_sca(svsp);
+ svsp->state = STATE_INIT;
+ break;
+
+ default:
+ svsp->state = STATE_INIT;
+ break;
+ }
+ break;
+
+ case STATE_STR:
+ switch(ch)
+ {
+ case 'p': /* soft terminal reset */
+ vt_str(svsp);
+ if (!kernel)
+ attrib = svsp->c_attr;
+ svsp->state = STATE_INIT;
+ break;
+
+ default:
+ svsp->state = STATE_INIT;
+ break;
+ }
+ break;
+
+ default: /* failsafe */
+ svsp->state = STATE_INIT;
+ break;
+
+ }
+ }
+
+ svsp->row = svsp->cur_offset / svsp->maxcol; /* current row update */
+
+ /* take care of last character on line behaviour */
+
+ if(svsp->lastchar && (svsp->col < ((svsp->maxcol)-1)))
+ svsp->lastchar = 0;
+ }
+
+ if(svsp == vsp) /* on current displayed page ? */
+ cursor_pos_valid = 1; /* position is valid now */
+}
+
+/*---------------------------------------------------------------------------*
+ * this is the absolute cold initialization of the emulator
+ *---------------------------------------------------------------------------*/
+static void
+vt_coldinit(void)
+{
+ extern u_short csd_ascii[]; /* pcvt_tbl.h */
+ extern u_short csd_supplemental[];
+
+#if PCVT_NETBSD <= 101
+ u_short volatile *cp = Crtat + (CGA_BUF-MONO_BUF)/CHR;
+#endif
+
+ u_short was;
+ int nscr, charset;
+ int equipment;
+
+#if PCVT_NETBSD <= 101
+ u_short *SaveCrtat = Crtat;
+#endif
+
+ struct video_state *svsp;
+
+ do_initialization = 0; /* reset init necessary flag */
+
+ /* get the equipment byte from the RTC chip */
+
+#if PCVT_NETBSD > 101
+ equipment = mc146818_read(NULL, NVRAM_EQUIPMENT);
+ switch(equipment & NVRAM_EQUIPMENT_MONITOR)
+#else
+ equipment = ((rtcin(RTC_EQUIPMENT)) >> 4) & 0x03;
+ switch(equipment)
+#endif
+ {
+ default:
+ panic("vt_coldinit: impossible equipment");
+
+ case EQ_EGAVGA:
+ /* set memory start to CGA == B8000 */
+
+#if PCVT_NETBSD > 101
+ Crtat = ISA_HOLE_VADDR(CGA_BUF);
+
+ /* find out, what monitor is connected */
+
+ was = *Crtat;
+ *Crtat = (u_short) 0xA55A;
+ if (*Crtat != 0xA55A)
+ {
+ Crtat = ISA_HOLE_VADDR(MONO_BUF);
+ addr_6845 = MONO_BASE;
+ color = 0;
+ }
+ else
+ {
+ *Crtat = was;
+ addr_6845 = CGA_BASE;
+ color = 1;
+ }
+
+#else /* ! PCVT_NETBSD > 101 */
+
+ Crtat = Crtat + (CGA_BUF-MONO_BUF)/CHR;
+
+ /* find out, what monitor is connected */
+
+ was = *cp;
+ *cp = (u_short) 0xA55A;
+ if (*cp != 0xA55A)
+ {
+ addr_6845 = MONO_BASE;
+ color = 0;
+ }
+ else
+ {
+ *cp = was;
+ addr_6845 = CGA_BASE;
+ color = 1;
+ }
+
+#endif /* PCVT_NETBSD > 101 */
+
+ if(vga_test()) /* EGA or VGA ? */
+ {
+ adaptor_type = VGA_ADAPTOR;
+ totalfonts = 8;
+
+ if(color == 0)
+ {
+ mda2egaorvga();
+#if PCVT_NETBSD <= 101
+ Crtat = SaveCrtat; /* mono start */
+#endif
+ }
+
+ /* find out which chipset we are running on */
+ vga_type = vga_chipset();
+ }
+ else
+ {
+ adaptor_type = EGA_ADAPTOR;
+ totalfonts = 4;
+
+ if(color == 0)
+ {
+ mda2egaorvga();
+#if PCVT_NETBSD <= 101
+ Crtat = SaveCrtat; /* mono start */
+#endif
+ }
+ }
+
+ /* decouple ega/vga charsets and intensity */
+ set_2ndcharset();
+
+ break;
+
+ case EQ_40COLOR: /* XXX should panic in 40 col mode ! */
+ case EQ_80COLOR:
+
+#if PCVT_NETBSD > 101
+ Crtat = ISA_HOLE_VADDR (CGA_BUF);
+#else
+ Crtat = Crtat + (CGA_BUF-MONO_BUF)/CHR;
+#endif
+
+ addr_6845 = CGA_BASE;
+ adaptor_type = CGA_ADAPTOR;
+ color = 1;
+ totalfonts = 0;
+ break;
+
+ case EQ_80MONO:
+
+#if PCVT_NETBSD > 101
+ Crtat = ISA_HOLE_VADDR (MONO_BUF);
+#endif
+
+ addr_6845 = MONO_BASE;
+ adaptor_type = MDA_ADAPTOR;
+ color = 0;
+ totalfonts = 0;
+ break;
+ }
+
+ /* establish default colors */
+
+ if(color)
+ {
+ kern_attr = (COLOR_KERNEL_FG | COLOR_KERNEL_BG) << 8;
+ user_attr = sgr_tab_color[0] << 8;
+ }
+ else
+ {
+ kern_attr = (MONO_KERNEL_FG | MONO_KERNEL_BG) << 8;
+ if(adaptor_type == MDA_ADAPTOR)
+ user_attr = sgr_tab_imono[0] << 8;
+ else
+ user_attr = sgr_tab_mono[0] << 8;
+ }
+
+ totalscreens = 1; /* for now until malloced */
+
+ for(nscr = 0, svsp = vs; nscr < PCVT_NSCREENS; nscr++, svsp++)
+ {
+ svsp->Crtat = Crtat; /* all same until malloc'ed */
+ svsp->Memory = Crtat; /* until malloc'ed */
+ svsp->cur_offset = 0; /* cursor offset */
+ svsp->c_attr = user_attr; /* non-kernel attributes */
+ svsp->bell_on = 1; /* enable bell */
+ svsp->sevenbit = 0; /* set to 8-bit path */
+ svsp->dis_fnc = 0; /* disable display functions */
+ svsp->transparent = 0; /* disable internal tranparency */
+ svsp->C1_ctls = 0; /* process only C0 ctls */
+ svsp->lastchar = 0; /* VTxxx behaviour of last */
+ /* char on line */
+ svsp->report_chars = NULL; /* VTxxx reports init */
+ svsp->report_count = 0; /* VTxxx reports init */
+ svsp->state = STATE_INIT; /* main state machine init */
+ svsp->m_awm = 1; /* enable auto wrap mode */
+ svsp->m_om = 0; /* origin mode = absolute */
+ svsp->sc_flag = 0; /* init saved cursor flag */
+ svsp->which_fkl = SYS_FKL; /* display system fkey-labels */
+ svsp->labels_on = 1; /* if in HP-mode, display */
+ /* fkey-labels */
+ svsp->attribute = 0; /* HP mode init */
+ svsp->key = 0; /* HP mode init */
+ svsp->l_len = 0; /* HP mode init */
+ svsp->s_len = 0; /* HP mode init */
+ svsp->m_len = 0; /* HP mode init */
+ svsp->i = 0; /* HP mode init */
+ svsp->vt_pure_mode = M_PUREVT; /* initial mode: pure VT220*/
+ svsp->vga_charset = CH_SET0; /* use bios default charset */
+
+#if PCVT_24LINESDEF /* true compatibility */
+ svsp->screen_rows = 24; /* default 24 rows on screen */
+#else /* full screen */
+ svsp->screen_rows = 25; /* default 25 rows on screen */
+#endif /* PCVT_24LINESDEF */
+
+ svsp->screen_rowsize = 25; /* default 25 rows on screen */
+ svsp->scrr_beg = 0; /* scrolling region begin row*/
+ svsp->scrr_len = svsp->screen_rows; /* scrolling region length*/
+ svsp->scrr_end = svsp->scrr_len - 1;/* scrolling region end */
+
+ if(nscr == 0)
+ {
+ if(adaptor_type == VGA_ADAPTOR)
+ {
+ /* only VGA can read cursor shape registers ! */
+ /* Preserve initial cursor shape */
+ outb(addr_6845,CRTC_CURSTART);
+ svsp->cursor_start = inb(addr_6845+1);
+ outb(addr_6845,CRTC_CUREND);
+ svsp->cursor_end = inb(addr_6845+1);
+ }
+ else
+ {
+ /* MDA,HGC,CGA,EGA registers are write-only */
+ svsp->cursor_start = 0;
+ svsp->cursor_end = 15;
+ }
+ }
+ else
+ {
+ svsp->cursor_start = vs[0].cursor_start;
+ svsp->cursor_end = vs[0].cursor_end;
+ }
+
+#ifdef FAT_CURSOR
+ svsp->cursor_end = 15; /* cursor lower scanline */
+#endif
+
+ svsp->cursor_on = 1; /* cursor is on */
+ svsp->ckm = 1; /* normal cursor key mode */
+ svsp->irm = 0; /* replace mode */
+ svsp->lnm = 0; /* CR only */
+ svsp->selchar = 0; /* selective attribute off */
+ svsp->G0 = csd_ascii; /* G0 = ascii */
+ svsp->G1 = csd_ascii; /* G1 = ascii */
+ svsp->G2 = csd_supplemental; /* G2 = supplemental */
+ svsp->G3 = csd_supplemental; /* G3 = supplemental */
+ svsp->GL = svsp->G0; /* GL = G0 */
+ svsp->GR = svsp->G2; /* GR = G2 */
+ svsp->whichi = 0; /* char set designate init */
+ svsp->which[0] = '\0'; /* char set designate init */
+ svsp->hp_state = SHP_INIT; /* init HP mode state machine*/
+ svsp->dcs_state = DCS_INIT; /* init DCS mode state machine*/
+ svsp->ss = 0; /* init single shift 2/3 */
+ svsp->Gs = NULL; /* Gs single shift 2/3 */
+ svsp->maxcol = SCR_COL80; /* 80 columns now (MUST!!!) */
+ svsp->wd132col = 0; /* help good old WD .. */
+ svsp->scroll_lock = 0; /* scrollock off */
+
+#if PCVT_INHIBIT_NUMLOCK
+ svsp->num_lock = 0; /* numlock off */
+#else
+ svsp->num_lock = 1; /* numlock on */
+#endif
+
+ svsp->caps_lock = 0; /* capslock off */
+ svsp->shift_lock = 0; /* shiftlock off */
+
+#if PCVT_24LINESDEF /* true compatibility */
+ svsp->force24 = 1; /* force 24 lines */
+#else /* maximum screen size */
+ svsp->force24 = 0; /* no 24 lines force yet */
+#endif /* PCVT_24LINESDEF */
+
+ vt_clearudk(svsp); /* clear vt220 udk's */
+
+ vt_str(svsp); /* init emulator */
+
+ if(nscr == 0)
+ {
+ /*
+ * Preserve data on the startup screen that
+ * precedes the cursor position. Leave the
+ * cursor where it was found.
+ */
+ unsigned cursorat;
+ int filllen;
+
+ /* CRTC regs 0x0e and 0x0f are r/w everywhere */
+
+ outb(addr_6845, CRTC_CURSORH);
+ cursorat = inb(addr_6845+1) << 8;
+ outb(addr_6845, CRTC_CURSORL);
+ cursorat |= inb(addr_6845+1);
+
+ svsp->cur_offset = cursorat;
+ svsp->row = cursorat / svsp->maxcol;
+ svsp->col = cursorat % svsp->maxcol;
+
+ if (svsp->row >= svsp->screen_rows)
+ {
+
+ /*
+ * Scroll up; this should only happen when
+ * PCVT_24LINESDEF is set
+ */
+ int nscroll =
+ svsp->row + 1
+ - svsp->screen_rows;
+ bcopy (svsp->Crtat
+ + nscroll*svsp->maxcol,
+ svsp->Crtat,
+ svsp->screen_rows
+ * svsp->maxcol * CHR);
+ svsp->row -= nscroll;
+ svsp->cur_offset -=
+ nscroll * svsp->maxcol;
+ }
+
+ filllen = (svsp->maxcol * svsp->screen_rowsize)
+ - svsp->cur_offset;
+
+ if (filllen > 0)
+ fillw(user_attr | ' ',
+ svsp->Crtat+svsp->cur_offset,
+ filllen);
+ }
+ svsp->smode.mode = VT_AUTO;
+ svsp->smode.relsig = svsp->smode.acqsig =
+ svsp->smode.frsig = 0;
+ svsp->proc = 0;
+ svsp->kbd_state = K_XLATE;
+ svsp->pid = svsp->vt_status = 0;
+ }
+
+ for(charset = 0;charset < NVGAFONTS;charset++)
+ {
+ vgacs[charset].loaded = 0; /* not populated yet */
+ vgacs[charset].secondloaded = 0; /* not populated yet */
+
+ switch(adaptor_type)
+ {
+ case VGA_ADAPTOR:
+
+ /*
+ * for a VGA, do not assume any
+ * constant - instead, read the actual
+ * values. This avoid problems with
+ * LCD displays that apparently happen
+ * to use font matrices up to 19
+ * scan lines and 475 scan lines
+ * total in order to make use of the
+ * whole screen area
+ */
+
+ outb(addr_6845, CRTC_VDE);
+ vgacs[charset].scr_scanlines =
+ inb(addr_6845 + 1);
+ outb(addr_6845, CRTC_MAXROW);
+ vgacs[charset].char_scanlines =
+ inb(addr_6845 + 1);
+ break;
+
+ case EGA_ADAPTOR:
+ /* 0x5D for 25 lines */
+ vgacs[charset].scr_scanlines = 0x5D;
+ /* 0x4D for 25 lines */
+ vgacs[charset].char_scanlines = 0x4D;
+ break;
+
+ case CGA_ADAPTOR:
+ case MDA_ADAPTOR:
+ default:
+ /* These shouldn't be used for CGA/MDA */
+ vgacs[charset].scr_scanlines = 0;
+ vgacs[charset].char_scanlines = 0;
+ break;
+ }
+ vgacs[charset].screen_size = SIZ_25ROWS; /* set screen size */
+ }
+
+ vgacs[0].loaded = 1; /* The BIOS loaded this at boot */
+
+ /* set cursor for first screen */
+
+ outb(addr_6845,CRTC_CURSTART); /* cursor start reg */
+ outb(addr_6845+1,vs[0].cursor_start);
+ outb(addr_6845,CRTC_CUREND); /* cursor end reg */
+ outb(addr_6845+1,vs[0].cursor_end);
+
+ /* this is to satisfy ddb */
+
+ if(!keyboard_is_initialized)
+ kbd_code_init1();
+
+ /* update keyboard led's */
+
+ update_led();
+}
+
+/*---------------------------------------------------------------------------*
+ * get kernel memory for virtual screens
+ *
+ * CAUTION: depends on "can_do_132col" being set properly, or
+ * depends on vga_type() being run before calling this !!!
+ *
+ *---------------------------------------------------------------------------*/
+void
+vt_coldmalloc(void)
+{
+ int nscr;
+ int screen_max_size;
+
+ /* we need to initialize in case we are not the console */
+
+ if(do_initialization)
+ vt_coldinit();
+
+ switch(adaptor_type)
+ {
+ default:
+ case MDA_ADAPTOR:
+ case CGA_ADAPTOR:
+ screen_max_size = MAXROW_MDACGA * MAXCOL_MDACGA * CHR;
+ break;
+
+ case EGA_ADAPTOR:
+ screen_max_size = MAXROW_EGA * MAXCOL_EGA * CHR;
+ break;
+
+ case VGA_ADAPTOR:
+ if(can_do_132col)
+ screen_max_size =
+ MAXROW_VGA * MAXCOL_SVGA * CHR;
+ else
+ screen_max_size =
+ MAXROW_VGA * MAXCOL_VGA * CHR;
+ }
+
+ for(nscr = 0; nscr < PCVT_NSCREENS; nscr++)
+ {
+ if((vs[nscr].Memory =
+ (u_short *)malloc(screen_max_size * 2, M_DEVBUF, M_WAITOK))
+ == NULL)
+ {
+ printf("pcvt: screen memory malloc failed, "
+ "NSCREEN=%d, nscr=%d\n",
+ PCVT_NSCREENS, nscr);
+ break;
+ }
+ if(nscr != 0)
+ {
+ vs[nscr].Crtat = vs[nscr].Memory;
+ fillw(user_attr | ' ',
+ vs[nscr].Crtat,
+ vs[nscr].maxcol * vs[nscr].screen_rowsize);
+ totalscreens++;
+ }
+ }
+}
+
+/*---------------------------------------------------------------------------*
+ * check if we must scroll up screen
+ *---------------------------------------------------------------------------*/
+static void
+check_scroll(struct video_state *svsp)
+{
+ if(!svsp->abs_write)
+ {
+ /* we write within scroll region */
+
+ if(svsp->cur_offset >= ((svsp->scrr_end + 1) * svsp->maxcol))
+ {
+ /* the following piece of code has to be protected */
+ /* from trying to switch to another virtual screen */
+ /* while being in there ... */
+
+ critical_scroll = 1; /* flag protect ON */
+
+ roll_up(svsp, 1); /* rolling up .. */
+
+ svsp->cur_offset -= svsp->maxcol;/* update position */
+
+ if(switch_page != -1) /* someone wanted to switch ? */
+ {
+ vgapage(switch_page); /* yes, then switch ! */
+ switch_page = -1; /* reset switch flag */
+ }
+
+ critical_scroll = 0; /* flag protect OFF */
+ }
+ }
+ else
+ {
+ /* clip, if outside of screen */
+
+ if (svsp->cur_offset >= svsp->screen_rows * svsp->maxcol)
+ svsp->cur_offset -= svsp->maxcol;
+ }
+}
+
+/*---------------------------------------------------------------------------*
+ * write to one user function key label
+ *---------------------------------------------------------------------------*/
+static void
+writefkl(int num, u_char *string, struct video_state *svsp)
+{
+ if((num < 0) || (num > 7)) /* range ok ? */
+ return;
+
+ strncpy(svsp->ufkl[num], string, 16); /* save string in static array */
+
+ if(svsp->which_fkl == USR_FKL)
+ wrfkl(num,string,svsp);
+}
+
+/*---------------------------------------------------------------------------*
+ * write to one system function key label
+ *---------------------------------------------------------------------------*/
+void
+swritefkl(int num, u_char *string, struct video_state *svsp)
+{
+ if((num < 0) || (num > 7)) /* range ok ? */
+ return;
+
+ strncpy(svsp->sfkl[num], string, 16); /* save string in static array */
+
+ if(svsp->which_fkl == SYS_FKL)
+ wrfkl(num,string,svsp);
+}
+
+/*---------------------------------------------------------------------------*
+ * write function key label onto screen
+ *---------------------------------------------------------------------------*/
+static void
+wrfkl(int num, u_char *string, struct video_state *svsp)
+{
+ register u_short *p;
+ register u_short *p1;
+ register int cnt = 0;
+
+ if(!svsp->labels_on || (svsp->vt_pure_mode == M_PUREVT))
+ return;
+
+ p = (svsp->Crtat
+ + (svsp->screen_rows * svsp->maxcol)); /* screen_rows+1 line */
+
+ if(svsp->maxcol == SCR_COL80)
+ {
+ if(num < 4) /* labels 1 .. 4 */
+ p += (num * LABEL_LEN);
+ else /* labels 5 .. 8 */
+ p += ((num * LABEL_LEN) + LABEL_MID + 1);
+ }
+ else
+ {
+ if(num < 4) /* labels 1 .. 4 */
+ p += (num * (LABEL_LEN + 6));
+ else /* labels 5 .. 8 */
+ p += ((num * (LABEL_LEN + 6)) + LABEL_MID + 11);
+
+ }
+ p1 = p + svsp->maxcol; /* second label line */
+
+ while((*string != '\0') && (cnt < 8))
+ {
+ *p = ((0x70 << 8) + (*string & 0xff));
+ p++;
+ string++;
+ cnt++;
+ }
+ while(cnt < 8)
+ {
+ *p = ((0x70 << 8) + ' ');
+ p++;
+ cnt++;
+ }
+
+ while((*string != '\0') && (cnt < 16))
+ {
+ *p1 = ((0x70 << 8) + (*string & 0xff));
+ p1++;
+ string++;
+ cnt++;
+ }
+ while(cnt < 16)
+ {
+ *p1 = ((0x70 << 8) + ' ');
+ p1++;
+ cnt++;
+ }
+}
+
+/*---------------------------------------------------------------------------*
+ * remove (=blank) function key labels, row/col and status line
+ *---------------------------------------------------------------------------*/
+void
+fkl_off(struct video_state *svsp)
+{
+ register u_short *p;
+ register int num;
+ register int size;
+
+ svsp->labels_on = 0;
+
+ if((vgacs[svsp->vga_charset].screen_size==SIZ_28ROWS) && svsp->force24)
+ size = 4;
+ else
+ size = 3;
+
+ p = (svsp->Crtat + (svsp->screen_rows * svsp->maxcol));
+
+ for(num = 0; num < (size * svsp->maxcol); num++)
+ *p++ = ' ';
+}
+
+/*---------------------------------------------------------------------------*
+ * (re-) display function key labels, row/col and status line
+ *---------------------------------------------------------------------------*/
+void
+fkl_on(struct video_state *svsp)
+{
+ svsp->labels_on = 1;
+
+ if(svsp->which_fkl == SYS_FKL)
+ sw_sfkl(svsp);
+ else if(svsp->which_fkl == USR_FKL)
+ sw_ufkl(svsp);
+}
+
+/*---------------------------------------------------------------------------*
+ * set emulation mode, switch between pure VTxxx mode and HP/VTxxx mode
+ *---------------------------------------------------------------------------*/
+void
+set_emulation_mode(struct video_state *svsp, int mode)
+{
+ if(svsp->vt_pure_mode == mode)
+ return;
+
+ clr_parms(svsp); /* escape parameter init */
+ svsp->state = STATE_INIT; /* initial state */
+ svsp->scrr_beg = 0; /* start of scrolling region */
+ svsp->sc_flag = 0; /* invalidate saved cursor position */
+ svsp->transparent = 0; /* disable control code processing */
+
+ if(mode == M_HPVT) /* vt-pure -> hp/vt-mode */
+ {
+ svsp->screen_rows = svsp->screen_rowsize - 3;
+ if (svsp->force24 && svsp->screen_rows == 25)
+ svsp->screen_rows = 24;
+
+ if (svsp->row >= svsp->screen_rows) {
+ /* Scroll up */
+ int nscroll = svsp->row + 1 - svsp->screen_rows;
+ bcopy (svsp->Crtat + nscroll * svsp->maxcol,
+ svsp->Crtat,
+ svsp->screen_rows * svsp->maxcol * CHR);
+ svsp->row -= nscroll;
+ svsp->cur_offset -= nscroll * svsp->maxcol;
+ }
+
+ svsp->vt_pure_mode = M_HPVT;
+
+ if (svsp->vs_tty)
+ svsp->vs_tty->t_winsize.ws_row = svsp->screen_rows;
+
+ svsp->scrr_len = svsp->screen_rows;
+ svsp->scrr_end = svsp->scrr_len - 1;
+
+ update_hp(svsp);
+ }
+ else if(mode == M_PUREVT) /* hp/vt-mode -> vt-pure */
+ {
+ fillw(user_attr | ' ',
+ svsp->Crtat + svsp->screen_rows * svsp->maxcol,
+ (svsp->screen_rowsize - svsp->screen_rows)
+ * svsp->maxcol);
+
+ svsp->vt_pure_mode = M_PUREVT;
+
+ svsp->screen_rows = svsp->screen_rowsize;
+ if (svsp->force24 && svsp->screen_rows == 25)
+ svsp->screen_rows = 24;
+
+ if (svsp->vs_tty)
+ svsp->vs_tty->t_winsize.ws_row = svsp->screen_rows;
+
+ svsp->scrr_len = svsp->screen_rows;
+ svsp->scrr_end = svsp->scrr_len - 1;
+ }
+
+#if PCVT_SIGWINCH
+ if (svsp->vs_tty && svsp->vs_tty->t_pgrp)
+ pgsignal(svsp->vs_tty->t_pgrp, SIGWINCH, 1);
+#endif /* PCVT_SIGWINCH */
+
+}
+
+/*---------------------------------------------------------------------------*
+ * initialize user function key labels
+ *---------------------------------------------------------------------------*/
+void
+init_ufkl(struct video_state *svsp)
+{
+ writefkl(0,(u_char *)" f1",svsp); /* init fkey labels */
+ writefkl(1,(u_char *)" f2",svsp);
+ writefkl(2,(u_char *)" f3",svsp);
+ writefkl(3,(u_char *)" f4",svsp);
+ writefkl(4,(u_char *)" f5",svsp);
+ writefkl(5,(u_char *)" f6",svsp);
+ writefkl(6,(u_char *)" f7",svsp);
+ writefkl(7,(u_char *)" f8",svsp);
+}
+
+/*---------------------------------------------------------------------------*
+ * initialize system user function key labels
+ *---------------------------------------------------------------------------*/
+void
+init_sfkl(struct video_state *svsp)
+{
+ /* 1234567812345678 */
+ if(can_do_132col)
+ /* 1234567812345678 */
+ swritefkl(0,(u_char *)"132 COLUMNS ",svsp);
+ else
+ swritefkl(0,(u_char *)" ",svsp);
+
+ /* 1234567812345678 */
+ swritefkl(1,(u_char *)"SOFT-RSTTERMINAL",svsp);
+
+ if(svsp->force24)
+ swritefkl(2,(u_char *)"FORCE24 ENABLE *",svsp);
+ else
+ swritefkl(2,(u_char *)"FORCE24 ENABLE ",svsp);
+
+#if PCVT_SHOWKEYS /* 1234567812345678 */
+ if(svsp == &vs[0])
+ swritefkl(3,(u_char *)"KEYBSCANDISPLAY ",svsp);
+ else
+ swritefkl(3,(u_char *)" ",svsp);
+#else
+ swritefkl(3,(u_char *)" ",svsp);
+#endif /* PCVT_SHOWKEYS */
+
+ /* 1234567812345678 */
+ if(svsp->bell_on)
+ swritefkl(4,(u_char *)"BELL ENABLE *",svsp);
+ else
+ swritefkl(4,(u_char *)"BELL ENABLE ",svsp);
+
+ if(svsp->sevenbit)
+ swritefkl(5,(u_char *)"8-BIT ENABLE ",svsp);
+ else
+ swritefkl(5,(u_char *)"8-BIT ENABLE *",svsp);
+
+ swritefkl(6,(u_char *)"DISPLAY FUNCTNS ",svsp);
+
+ swritefkl(7,(u_char *)"AUTOWRAPENABLE *",svsp);
+ /* 1234567812345678 */
+}
+
+/*---------------------------------------------------------------------------*
+ * switch display to user function key labels
+ *---------------------------------------------------------------------------*/
+void
+sw_ufkl(struct video_state *svsp)
+{
+ int i;
+ svsp->which_fkl = USR_FKL;
+ for(i = 0; i < 8; i++)
+ wrfkl(i,svsp->ufkl[i],svsp);
+}
+
+/*---------------------------------------------------------------------------*
+ * switch display to system function key labels
+ *---------------------------------------------------------------------------*/
+void
+sw_sfkl(struct video_state *svsp)
+{
+ int i;
+ svsp->which_fkl = SYS_FKL;
+ for(i = 0; i < 8; i++)
+ wrfkl(i,svsp->sfkl[i],svsp);
+}
+
+/*---------------------------------------------------------------------------*
+ * toggle force 24 lines
+ *---------------------------------------------------------------------------*/
+void
+toggl_24l(struct video_state *svsp)
+{
+ if(svsp->which_fkl == SYS_FKL)
+ {
+ if(svsp->force24)
+ {
+ svsp->force24 = 0;
+ swritefkl(2,(u_char *)"FORCE24 ENABLE ",svsp);
+ }
+ else
+ {
+ svsp->force24 = 1;
+ swritefkl(2,(u_char *)"FORCE24 ENABLE *",svsp);
+ }
+ set_screen_size(svsp, vgacs[(svsp->vga_charset)].screen_size);
+ }
+}
+
+#if PCVT_SHOWKEYS
+/*---------------------------------------------------------------------------*
+ * toggle keyboard scancode display
+ *---------------------------------------------------------------------------*/
+void
+toggl_kbddbg(struct video_state *svsp)
+{
+ if((svsp->which_fkl == SYS_FKL) && (svsp == &vs[0]))
+ {
+ if(keyboard_show)
+ {
+ keyboard_show = 0;
+ swritefkl(3,(u_char *)"KEYBSCANDISPLAY ",svsp);
+ }
+ else
+ {
+ keyboard_show = 1;
+ swritefkl(3,(u_char *)"KEYBSCANDISPLAY*",svsp);
+ }
+ }
+}
+#endif /* PCVT_SHOWKEYS */
+
+/*---------------------------------------------------------------------------*
+ * toggle display functions
+ *---------------------------------------------------------------------------*/
+void
+toggl_dspf(struct video_state *svsp)
+{
+ if(svsp->which_fkl == SYS_FKL)
+ {
+ if(svsp->dis_fnc)
+ {
+ svsp->dis_fnc = 0;
+ swritefkl(6,(u_char *)"DISPLAY FUNCTNS ",svsp);
+ }
+ else
+ {
+ svsp->dis_fnc = 1;
+ swritefkl(6,(u_char *)"DISPLAY FUNCTNS*",svsp);
+ }
+ }
+}
+
+/*---------------------------------------------------------------------------*
+ * auto wrap on/off
+ *---------------------------------------------------------------------------*/
+void
+toggl_awm(struct video_state *svsp)
+{
+ if(svsp->which_fkl == SYS_FKL)
+ {
+ if(svsp->m_awm)
+ {
+ svsp->m_awm = 0;
+ swritefkl(7,(u_char *)"AUTOWRAPENABLE ",svsp);
+ }
+ else
+ {
+ svsp->m_awm = 1;
+ swritefkl(7,(u_char *)"AUTOWRAPENABLE *",svsp);
+ }
+ }
+}
+
+/*---------------------------------------------------------------------------*
+ * bell on/off
+ *---------------------------------------------------------------------------*/
+void
+toggl_bell(struct video_state *svsp)
+{
+ if(svsp->which_fkl == SYS_FKL)
+ {
+ if(svsp->bell_on)
+ {
+ svsp->bell_on = 0;
+ swritefkl(4,(u_char *)"BELL ENABLE ",svsp);
+ }
+ else
+ {
+ svsp->bell_on = 1;
+ swritefkl(4,(u_char *)"BELL ENABLE *",svsp);
+ }
+ }
+}
+
+/*---------------------------------------------------------------------------*
+ * 7/8 bit usage
+ *---------------------------------------------------------------------------*/
+void
+toggl_sevenbit(struct video_state *svsp)
+{
+ if(svsp->which_fkl == SYS_FKL)
+ {
+ if(svsp->sevenbit)
+ {
+ svsp->sevenbit = 0;
+ swritefkl(5,(u_char *)"8-BIT ENABLE *",svsp);
+ }
+ else
+ {
+ svsp->sevenbit = 1;
+ swritefkl(5,(u_char *)"8-BIT ENABLE ",svsp);
+ }
+ }
+}
+
+/*---------------------------------------------------------------------------*
+ * 80 / 132 columns
+ *---------------------------------------------------------------------------*/
+void
+toggl_columns(struct video_state *svsp)
+{
+ if(svsp->which_fkl == SYS_FKL)
+ {
+ if(svsp->maxcol == SCR_COL132)
+ {
+ if(vt_col(svsp, SCR_COL80))
+ svsp->maxcol = 80;
+ }
+ else
+ {
+ if(vt_col(svsp, SCR_COL132))
+ svsp->maxcol = 132;
+ }
+ }
+}
+
+/*---------------------------------------------------------------------------*
+ * toggle vga 80/132 column operation
+ *---------------------------------------------------------------------------*/
+int
+vt_col(struct video_state *svsp, int cols)
+{
+ if(vga_col(svsp, cols) == 0)
+ return(0);
+
+ if(cols == SCR_COL80)
+ swritefkl(0,(u_char *)"132 COLUMNS ",svsp);
+ else
+ swritefkl(0,(u_char *)"132 COLUMNS*",svsp);
+
+ fillw(user_attr | ' ',
+ svsp->Crtat,
+ svsp->maxcol * svsp->screen_rowsize);
+
+ clr_parms(svsp); /* escape parameter init */
+ svsp->state = STATE_INIT; /* initial state */
+ svsp->col = 0; /* init row */
+ svsp->row = 0; /* init col */
+ svsp->cur_offset = 0; /* cursor offset init */
+ svsp->sc_flag = 0; /* invalidate saved cursor position */
+ svsp->scrr_beg = 0; /* reset scrolling region */
+ svsp->scrr_len = svsp->screen_rows; /*reset scrolling region legnth */
+ svsp->scrr_end = svsp->scrr_len - 1;
+ svsp->transparent = 0; /* disable control code processing */
+ svsp->selchar = 0; /* selective attr off */
+ vt_initsel(svsp); /* re-init sel attr */
+
+ update_hp(svsp); /* update labels, row/col, page ind */
+
+ /* Update winsize struct to reflect screen size */
+
+ if(svsp->vs_tty)
+ {
+ svsp->vs_tty->t_winsize.ws_row = svsp->screen_rows;
+ svsp->vs_tty->t_winsize.ws_col = svsp->maxcol;
+ svsp->vs_tty->t_winsize.ws_xpixel =
+ (cols == SCR_COL80)? 720: 1056;
+ svsp->vs_tty->t_winsize.ws_ypixel = 400;
+
+#if PCVT_SIGWINCH
+ if(svsp->vs_tty->t_pgrp)
+ pgsignal(svsp->vs_tty->t_pgrp, SIGWINCH, 1);
+#endif /* PCVT_SIGWINCH */
+
+ }
+ return(1);
+}
+
+/*---------------------------------------------------------------------------*
+ * update HP stuff on screen
+ *---------------------------------------------------------------------------*/
+void
+update_hp(struct video_state *svsp)
+{
+ if(svsp->vt_pure_mode != M_HPVT)
+ return;
+
+ fillw (user_attr | ' ',
+ svsp->Crtat + svsp->screen_rows * svsp->maxcol,
+ (svsp->screen_rowsize - svsp->screen_rows) * svsp->maxcol);
+
+ if (!svsp->labels_on)
+ return;
+
+ /* update fkey labels */
+
+ fkl_off(svsp);
+ fkl_on(svsp);
+
+ if(vsp == svsp)
+ {
+ /* update current displayed screen indicator */
+
+ *((svsp->Crtat + ((svsp->screen_rows + 2) * svsp->maxcol))
+ + svsp->maxcol - 3) = user_attr | '[';
+ *((svsp->Crtat + ((svsp->screen_rows + 2) * svsp->maxcol))
+ + svsp->maxcol - 2) = user_attr | (current_video_screen + '0');
+ *((svsp->Crtat + ((svsp->screen_rows + 2) * svsp->maxcol))
+ + svsp->maxcol - 1) = user_attr | ']';
+ }
+}
+
+/*---------------------------------------------------------------------------*
+ * initialize ANSI escape sequence parameter buffers
+ *---------------------------------------------------------------------------*/
+void
+clr_parms(struct video_state *svsp)
+{
+ register int i;
+ for(i=0; i < MAXPARMS; i++)
+ svsp->parms[i] = 0;
+ svsp->parmi = 0;
+}
+
+
+/*---------------------------------------------------------------------------*
+ *
+ * partial HP 2392 ANSI mode Emulator
+ * ==================================
+ *
+ * this part tooks over the emulation of some escape sequences
+ * needed to handle the function key labels
+ *
+ * They are modeled after the corresponding escape sequences
+ * introduced with the HP2392 terminals from Hewlett-Packard.
+ *
+ * see:
+ * "HP2392A, Display Terminal Reference Manual",
+ * HP Manual Part Number 02390-90001
+ * and:
+ * Reference Manual Supplement
+ * "2392A Display Terminal Option 049, ANSI Operation"
+ * HP Manual Part Number 02390-90023EN
+ *
+ *---------------------------------------------------------------------------*/
+
+static void
+hp_entry(U_char ch, struct video_state *svsp)
+{
+ switch(svsp->hp_state)
+ {
+ case SHP_INIT:
+ switch(ch)
+ {
+ case 'f':
+ svsp->hp_state = SHP_AND_F;
+ svsp->attribute = 0;
+ svsp->key = 0;
+ svsp->l_len = 0;
+ svsp->s_len = 0;
+ svsp->i = 0;
+ break;
+
+ case 'j':
+ svsp->m_len = 0;
+ svsp->hp_state = SHP_AND_J;
+ break;
+
+ case 's':
+ svsp->hp_state = SHP_AND_ETE;
+ break;
+
+ default:
+ svsp->hp_state = SHP_INIT;
+ svsp->state = STATE_INIT;
+ break;
+ }
+ break;
+
+ case SHP_AND_F:
+ if((ch >= '0') && (ch <= '8'))
+ {
+ svsp->attribute = ch;
+ svsp->hp_state = SHP_AND_Fa;
+ }
+ else
+ {
+ svsp->hp_state = SHP_INIT;
+ svsp->state = STATE_INIT;
+ }
+ break;
+
+ case SHP_AND_Fa:
+ if(ch == 'a')
+ svsp->hp_state = SHP_AND_Fak;
+ else if(ch == 'k')
+ {
+ svsp->key = svsp->attribute;
+ svsp->hp_state = SHP_AND_Fakd;
+ }
+ else
+ {
+ svsp->hp_state = SHP_INIT;
+ svsp->state = STATE_INIT;
+ }
+ break;
+
+ case SHP_AND_Fak:
+ if((ch >= '1') && (ch <= '8'))
+ {
+ svsp->key = ch;
+ svsp->hp_state = SHP_AND_Fak1;
+ }
+ else
+ {
+ svsp->hp_state = SHP_INIT;
+ svsp->state = STATE_INIT;
+ }
+ break;
+
+ case SHP_AND_Fak1:
+ if(ch == 'k')
+ svsp->hp_state = SHP_AND_Fakd;
+ else
+ {
+ svsp->hp_state = SHP_INIT;
+ svsp->state = STATE_INIT;
+ }
+ break;
+
+ case SHP_AND_Fakd:
+ if(svsp->l_len > 16)
+ {
+ svsp->hp_state = SHP_INIT;
+ svsp->state = STATE_INIT;
+ }
+ else if(ch >= '0' && ch <= '9')
+ {
+ svsp->l_len *= 10;
+ svsp->l_len += (ch -'0');
+ }
+ else if(ch == 'd')
+ svsp->hp_state = SHP_AND_FakdL;
+ else
+ {
+ svsp->hp_state = SHP_INIT;
+ svsp->state = STATE_INIT;
+ }
+ break;
+
+ case SHP_AND_FakdL:
+ if(svsp->s_len > 80)
+ {
+ svsp->hp_state = SHP_INIT;
+ svsp->state = STATE_INIT;
+ }
+ else if(ch >= '0' && ch <= '9')
+ {
+ svsp->s_len *= 10;
+ svsp->s_len += (ch -'0');
+ }
+ else if(ch == 'L')
+ {
+ svsp->hp_state = SHP_AND_FakdLl;
+ svsp->transparent = 1;
+ }
+ else
+ {
+ svsp->hp_state = SHP_INIT;
+ svsp->state = STATE_INIT;
+ }
+ break;
+
+ case SHP_AND_FakdLl:
+ svsp->l_buf[svsp->i] = ch;
+ if(svsp->i >= svsp->l_len-1)
+ {
+ svsp->hp_state = SHP_AND_FakdLls;
+ svsp->i = 0;
+ if(svsp->s_len == 0)
+ {
+ svsp->state = STATE_INIT;
+ svsp->hp_state = SHP_INIT;
+ svsp->transparent = 0;
+ svsp->i = 0;
+ svsp->l_buf[svsp->l_len] = '\0';
+ svsp->s_buf[svsp->s_len] = '\0';
+ writefkl((svsp->key - '0' -1),
+ svsp->l_buf, svsp);
+ }
+ }
+ else
+ svsp->i++;
+ break;
+
+ case SHP_AND_FakdLls:
+ svsp->s_buf[svsp->i] = ch;
+ if(svsp->i >= svsp->s_len-1)
+ {
+ svsp->state = STATE_INIT;
+ svsp->hp_state = SHP_INIT;
+ svsp->transparent = 0;
+ svsp->i = 0;
+ svsp->l_buf[svsp->l_len] = '\0';
+ svsp->s_buf[svsp->s_len] = '\0';
+ writefkl((svsp->key - '0' -1), svsp->l_buf,
+ svsp);
+ }
+ else
+ svsp->i++;
+ break;
+
+ case SHP_AND_J:
+ switch(ch)
+ {
+ case '@': /* enable user keys, remove */
+ /* all labels & status from */
+ /* screen */
+ svsp->hp_state = SHP_INIT;
+ svsp->state = STATE_INIT;
+ fkl_off(svsp);
+ break;
+
+ case 'A': /* enable & display "modes" */
+ svsp->hp_state = SHP_INIT;
+ svsp->state = STATE_INIT;
+ fkl_on(svsp);
+ sw_sfkl(svsp);
+ break;
+
+ case 'B': /* enable & display "user" */
+ svsp->hp_state = SHP_INIT;
+ svsp->state = STATE_INIT;
+ fkl_on(svsp);
+ sw_ufkl(svsp);
+ break;
+
+ case 'C': /* remove (clear) status line*/
+ /* and restore current labels*/
+ svsp->hp_state = SHP_INIT;
+ svsp->state = STATE_INIT;
+ fkl_on(svsp);
+ break;
+
+ case 'R': /* enable usr/menu keys */
+ /* and fkey label modes */
+ svsp->hp_state = SHP_INIT;
+ svsp->state = STATE_INIT;
+ break;
+
+ case 'S': /* disable usr/menu keys */
+ /* and fkey label modes */
+ svsp->hp_state = SHP_INIT;
+ svsp->state = STATE_INIT;
+ break;
+
+ case '0':
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ case '8':
+ case '9': /* parameters for esc & j xx L mm */
+ svsp->m_len *= 10;
+ svsp->m_len += (ch -'0');
+ break;
+
+ case 'L':
+ svsp->hp_state = SHP_AND_JL;
+ svsp->i = 0;
+ svsp->transparent = 1;
+ break;
+
+ default:
+ svsp->hp_state = SHP_INIT;
+ svsp->state = STATE_INIT;
+ break;
+
+ }
+ break;
+
+
+ case SHP_AND_JL:
+ svsp->m_buf[svsp->i] = ch;
+ if(svsp->i >= svsp->m_len-1)
+ {
+ svsp->state = STATE_INIT;
+ svsp->hp_state = SHP_INIT;
+ svsp->transparent = 0;
+ svsp->i = 0;
+ svsp->m_buf[svsp->m_len] = '\0';
+ /* display status line */
+ /* needs to be implemented */
+ /* see 2392 man, 3-14 */
+
+ }
+ else
+ svsp->i++;
+ break;
+
+ case SHP_AND_ETE: /* eat chars until uppercase */
+ if(ch >= '@' && ch <= 'Z')
+ {
+ svsp->hp_state = SHP_INIT;
+ svsp->state = STATE_INIT;
+ svsp->transparent = 0;
+ }
+ break;
+
+ default:
+ svsp->hp_state = SHP_INIT;
+ svsp->state = STATE_INIT;
+ svsp->transparent = 0;
+ break;
+ }
+}
+
+#endif /* NVT > 0 */
+
+/* ------------------------- E O F ------------------------------------------*/
+
diff --git a/sys/arch/i386/isa/pcvt/pcvt_sup.c b/sys/arch/i386/isa/pcvt/pcvt_sup.c
new file mode 100644
index 00000000000..af96e7b3cc1
--- /dev/null
+++ b/sys/arch/i386/isa/pcvt/pcvt_sup.c
@@ -0,0 +1,2083 @@
+/*
+ * Copyright (c) 1992, 1995 Hellmuth Michaelis and Joerg Wunsch.
+ *
+ * Copyright (c) 1992, 1993 Brian Dunford-Shore and Scott Turner.
+ *
+ * Copyright (C) 1992, 1993 Soeren Schmidt.
+ *
+ * All rights reserved.
+ *
+ * For the sake of compatibility, portions of this code regarding the
+ * X server interface are taken from Soeren Schmidt's syscons driver.
+ *
+ * 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 Hellmuth Michaelis,
+ * Brian Dunford-Shore, Joerg Wunsch, Scott Turner and Soeren Schmidt.
+ * 4. The name authors may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``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 AUTHORS 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.
+ *
+ *
+ * @(#)pcvt_sup.c, 3.32, Last Edit-Date: [Tue Oct 3 11:19:49 1995]
+ *
+ */
+
+/*---------------------------------------------------------------------------*
+ *
+ * pcvt_sup.c VT220 Driver Support Routines
+ * ---------------------------------------------
+ * -hm ------------ Release 3.00 --------------
+ * -hm integrating NetBSD-current patches
+ * -hm removed paranoid delay()/DELAY() from vga_test()
+ * -hm removing vgapage() protection if PCVT_KBD_FIFO
+ * -hm some new CONF_ - values
+ * -hm Joerg's patches for FreeBSD ttymalloc
+ * -hm applying Joerg's patches for FreeBSD 2.0
+ * -hm applying Lon Willet's patches for NetBSD
+ * -hm NetBSD PR #400: patch to short-circuit TIOCSWINSZ
+ * -hm getting PCVT_BURST reported correctly for FreeBSD 2.0
+ * -hm applying patch from Joerg fixing Crtat bug
+ * -hm moving ega/vga coldinit support code to mda2egaorvga()
+ * -hm patch from Thomas Eberhardt fixing force 24 lines fkey update
+ * -hm bugfix from Joerg: check for svsp->vs_tty before using it
+ * -hm added support for CONF_MDAFASTSCROLL
+ * -hm ---------------- Release 3.30 -----------------------
+ * -hm patch from Frank van der Linden for keyboard state per VT
+ * -hm ---------------- Release 3.32 -----------------------
+ *
+ *---------------------------------------------------------------------------*/
+
+#include "vt.h"
+#if NVT > 0
+
+#include "pcvt_hdr.h" /* global include */
+
+static void vid_cursor ( struct cursorshape *data );
+static void vgasetfontattr ( struct vgafontattr *data );
+static void vgagetfontattr ( struct vgafontattr *data );
+static void vgaloadchar ( struct vgaloadchar *data );
+static void vid_getscreen ( struct screeninfo *data, Dev_t dev );
+static void vid_setscreen ( struct screeninfo *data, Dev_t dev );
+static void setchargen ( void );
+static void setchargen3 ( void );
+static void resetchargen ( void );
+static void vgareadpel ( struct vgapel *data, Dev_t dev );
+static void vgawritepel ( struct vgapel *data, Dev_t dev );
+static void vgapcvtid ( struct pcvtid *data );
+static void vgapcvtinfo ( struct pcvtinfo *data );
+
+#ifdef XSERVER
+static unsigned char * compute_charset_base ( unsigned fontset );
+#endif /* XSERVER */
+
+#if PCVT_SCREENSAVER
+static void scrnsv_timedout ( void *arg );
+static u_short *savedscreen = (u_short *)0; /* ptr to screen contents */
+static size_t scrnsv_size = (size_t)-1; /* size of saved image */
+
+#if PCVT_PRETTYSCRNS
+static u_short *scrnsv_current = (u_short *)0; /* attention char ptr */
+static void scrnsv_blink ( void );
+static u_short getrand ( void );
+#endif /* PCVT_PRETTYSCRNS */
+
+#endif /* PCVT_SCREENSAVER */
+
+
+/*---------------------------------------------------------------------------*
+ * execute vga ioctls
+ *---------------------------------------------------------------------------*/
+int
+vgaioctl(Dev_t dev, int cmd, caddr_t data, int flag)
+{
+ if(minor(dev) >= PCVT_NSCREENS)
+ return -1;
+
+/*
+ * Some of the commands are not applicable if the vt in question, or the
+ * current vt is in graphics mode (i.e., the X server acts on it); they
+ * will cause an EAGAIN (resource temporarily unavailable) to be returned.
+ */
+
+#ifdef XSERVER
+#define is_dev_grafx vs[minor(dev)].vt_status & VT_GRAFX
+#define is_current_grafx vsp->vt_status & VT_GRAFX
+#else /* !XSERVER */
+#define is_dev_grafx 0 /* not applicable */
+#define is_current_grafx 0
+#endif /* XSERVER */
+
+ switch(cmd)
+ {
+ case VGACURSOR:
+ if(is_current_grafx)
+ return EAGAIN;
+ vid_cursor((struct cursorshape *)data);
+ break;
+
+ case VGALOADCHAR:
+ if((adaptor_type != VGA_ADAPTOR) &&
+ (adaptor_type != EGA_ADAPTOR))
+ return -1;
+ if(is_current_grafx)
+ return EAGAIN;
+ vgaloadchar((struct vgaloadchar *)data);
+ break;
+
+ case VGASETFONTATTR:
+ if((adaptor_type != VGA_ADAPTOR) &&
+ (adaptor_type != EGA_ADAPTOR))
+ return -1;
+
+#if PCVT_SCREENSAVER
+ pcvt_scrnsv_reset();
+#endif /* PCVT_SCREENSAVER */
+
+ vgasetfontattr((struct vgafontattr *)data);
+ break;
+
+ case VGAGETFONTATTR:
+ if((adaptor_type != VGA_ADAPTOR) &&
+ (adaptor_type != EGA_ADAPTOR))
+ return -1;
+ vgagetfontattr((struct vgafontattr *)data);
+ break;
+
+ case VGASETSCREEN:
+
+#if PCVT_SCREENSAVER
+ pcvt_scrnsv_reset();
+#endif /* PCVT_SCREENSAVER */
+
+ vid_setscreen((struct screeninfo *)data, dev);
+ break;
+
+ case VGAGETSCREEN:
+ vid_getscreen((struct screeninfo *)data, dev);
+ break;
+
+ case VGAREADPEL:
+ if(adaptor_type != VGA_ADAPTOR)
+ return -1;
+ if(is_dev_grafx)
+ return EAGAIN;
+ vgareadpel((struct vgapel *)data, dev);
+ break;
+
+ case VGAWRITEPEL:
+ if(adaptor_type != VGA_ADAPTOR)
+ return -1;
+ if(is_dev_grafx)
+ return EAGAIN;
+ vgawritepel((struct vgapel *)data, dev);
+ break;
+
+#if PCVT_SCREENSAVER
+ case VGASCREENSAVER:
+ if(is_current_grafx)
+ return EAGAIN;
+ pcvt_set_scrnsv_tmo(*(int *)data);
+ pcvt_scrnsv_reset();
+ break;
+#endif /* PCVT_SCREENSAVER */
+
+ case VGAPCVTID:
+ vgapcvtid((struct pcvtid *)data);
+ break;
+
+ case VGAPCVTINFO:
+ vgapcvtinfo((struct pcvtinfo *)data);
+ break;
+
+ case VGASETCOLMS:
+ if(is_dev_grafx)
+ return EAGAIN;
+ if(*(int *)data == 80)
+ (void)vt_col(&vs[minor(dev)], SCR_COL80);
+ else if(*(int *)data == 132)
+ {
+ if(vt_col(&vs[minor(dev)], SCR_COL132) == 0)
+ return EINVAL; /* not a VGA */
+ }
+ else
+ return EINVAL;
+ break;
+
+ case TIOCSWINSZ:
+ /* do nothing here */
+ break;
+
+ default:
+ return -1;
+ }
+ return 0;
+
+#undef is_dev_grafx
+#undef is_current_grafx
+}
+
+/*---------------------------------------------------------------------------*
+ * video ioctl - return driver id
+ *---------------------------------------------------------------------------*/
+static void
+vgapcvtid(struct pcvtid *data)
+{
+ strcpy(data->name, PCVTIDNAME);
+ data->rmajor = PCVTIDMAJOR;
+ data->rminor = PCVTIDMINOR;
+}
+
+/*---------------------------------------------------------------------------*
+ * video ioctl - return driver compile time options data
+ *---------------------------------------------------------------------------*/
+static void
+vgapcvtinfo(struct pcvtinfo *data)
+{
+#if PCVT_NETBSD
+ data->opsys = CONF_NETBSD;
+ data->opsysrel = PCVT_NETBSD;
+#elif PCVT_FREEBSD
+ data->opsys = CONF_FREEBSD;
+ data->opsysrel = PCVT_FREEBSD;
+#else
+ data->opsys = CONF_UNKNOWNOPSYS;
+ data->opsysrel = 0;
+#endif
+
+ data->nscreens = PCVT_NSCREENS;
+ data->scanset = PCVT_SCANSET;
+ data->updatefast= PCVT_UPDATEFAST;
+ data->updateslow= PCVT_UPDATESLOW;
+ data->sysbeepf = PCVT_SYSBEEPF;
+
+#if PCVT_NETBSD || PCVT_FREEBSD >= 200
+ data->pcburst = PCVT_PCBURST;
+#else
+ data->pcburst = 1;
+#endif
+
+#if PCVT_KBD_FIFO
+ data->kbd_fifo_sz = PCVT_KBD_FIFO_SZ;
+#else
+ data->kbd_fifo_sz = 0;
+#endif
+
+ data->compile_opts = (0
+
+#if PCVT_VT220KEYB
+ | CONF_VT220KEYB
+#endif
+#if PCVT_SCREENSAVER
+ | CONF_SCREENSAVER
+#endif
+#if PCVT_PRETTYSCRNS
+ | CONF_PRETTYSCRNS
+#endif
+#if PCVT_CTRL_ALT_DEL
+ | CONF_CTRL_ALT_DEL
+#endif
+#if PCVT_USEKBDSEC
+ | CONF_USEKBDSEC
+#endif
+#if PCVT_24LINESDEF
+ | CONF_24LINESDEF
+#endif
+#if PCVT_EMU_MOUSE
+ | CONF_EMU_MOUSE
+#endif
+#if PCVT_SHOWKEYS
+ | CONF_SHOWKEYS
+#endif
+#if PCVT_KEYBDID
+ | CONF_KEYBDID
+#endif
+#if PCVT_SIGWINCH
+ | CONF_SIGWINCH
+#endif
+#if PCVT_NULLCHARS
+ | CONF_NULLCHARS
+#endif
+#if PCVT_BACKUP_FONTS
+ | CONF_BACKUP_FONTS
+#endif
+#if PCVT_SW0CNOUTP /* was FORCE8BIT */
+ | CONF_SW0CNOUTP
+#endif
+#if PCVT_SETCOLOR
+ | CONF_SETCOLOR
+#endif
+#if PCVT_132GENERIC
+ | CONF_132GENERIC
+#endif
+#if PCVT_PALFLICKER
+ | CONF_PALFLICKER
+#endif
+#if PCVT_WAITRETRACE
+ | CONF_WAITRETRACE
+#endif
+#ifdef XSERVER
+ | CONF_XSERVER
+#endif
+#if PCVT_PORTIO_DELAY
+ | CONF_PORTIO_DELAY
+#endif
+#if PCVT_INHIBIT_NUMLOCK
+ | CONF_INHIBIT_NUMLOCK
+#endif
+#if PCVT_META_ESC
+ | CONF_META_ESC
+#endif
+#if PCVT_KBD_FIFO
+ | CONF_KBD_FIFO
+#endif
+#if PCVT_NOFASTSCROLL
+ | CONF_NOFASTSCROLL
+#endif
+#if PCVT_MDAFASTSCROLL
+ | CONF_MDAFASTSCROLL
+#endif
+#if PCVT_SLOW_INTERRUPT
+ | CONF_SLOW_INTERRUPT
+#endif
+#if PCVT_NO_LED_UPDATE
+ | CONF_NO_LED_UPDATE
+#endif
+ );
+}
+
+/*---------------------------------------------------------------------------*
+ * video ioctl - set cursor appearence
+ *---------------------------------------------------------------------------*/
+static void
+vid_cursor(struct cursorshape *data)
+{
+ int screen;
+ int start;
+ int end;
+ int line_height;
+ int character_set;
+
+ /* for which virtual screen, -1 for current */
+ screen = data->screen_no;
+
+ if(screen == -1) /* current ? */
+ screen = current_video_screen;
+ else if(screen > totalscreens - 1)
+ screen = totalscreens - 1;
+ else if(screen < 0)
+ screen = 0;
+
+ if(adaptor_type == VGA_ADAPTOR || adaptor_type == EGA_ADAPTOR)
+ {
+ character_set = vs[screen].vga_charset;
+ character_set = (character_set < 0) ? 0 :
+ ((character_set < totalfonts) ?
+ character_set :
+ totalfonts-1);
+
+ line_height = vgacs[character_set].char_scanlines & 0x1F;
+ }
+ else if(adaptor_type == MDA_ADAPTOR)
+ {
+ line_height = 14;
+ }
+ else
+ {
+ line_height = 8; /* CGA */
+ }
+
+ start = (data->start < 0) ? 0 :
+ ((data->start > line_height) ? line_height : data->start);
+
+ if((vga_family == VGA_F_TRI) && (start == 0))
+ start = 1;
+
+ end = (data->end < 0) ? 0 :
+ ((data->end > line_height) ? line_height : data->end);
+
+ vs[screen].cursor_start = start;
+ vs[screen].cursor_end = end;
+
+ if(screen == current_video_screen)
+ {
+ outb(addr_6845,CRTC_CURSTART); /* cursor start reg */
+ outb(addr_6845+1, start);
+ outb(addr_6845,CRTC_CUREND); /* cursor end reg */
+ outb(addr_6845+1, end);
+ }
+}
+
+/*---------------------------------------------------------------------------*
+ * ega/vga ioctl - set font attributes
+ *---------------------------------------------------------------------------*/
+static void
+vgasetfontattr(struct vgafontattr *data)
+{
+ register int i;
+ int vga_character_set;
+ int lines_per_character;
+ int totscanlines;
+ int size;
+
+ vga_character_set = data->character_set;
+ vga_character_set = (vga_character_set < 0) ? 0 :
+ ((vga_character_set < totalfonts) ?
+ vga_character_set : totalfonts-1);
+
+ vgacs[vga_character_set].loaded = data->font_loaded;
+
+ /* Limit Characters to 32 scanlines doubled */
+ vgacs[vga_character_set].char_scanlines =
+ (data->character_scanlines & 0x1F)
+ | 0x40; /* always set bit 9 of line cmp reg */
+
+ if(adaptor_type == EGA_ADAPTOR)
+ /* ...and screen height to scan 350 lines */
+ vgacs[vga_character_set].scr_scanlines =
+ (data->screen_scanlines > 0x5d) ?
+ 0x5d : data->screen_scanlines;
+ else
+ /* ...and screen height to scan 480 lines */
+ vgacs[vga_character_set].scr_scanlines =
+ (data->screen_scanlines > 0xdF) ?
+ 0xdF : data->screen_scanlines;
+
+ lines_per_character =
+ (int)(0x1F & vgacs[vga_character_set].char_scanlines)+1;
+
+ totscanlines = 0x101 + (int)vgacs[vga_character_set].scr_scanlines;
+
+ size = data->screen_size;
+
+ if(adaptor_type == EGA_ADAPTOR)
+ {
+ switch(size)
+ {
+ case SIZ_25ROWS: /* This case is always OK */
+ break;
+
+ case SIZ_35ROWS:
+ if(totscanlines/lines_per_character >= 35)
+ size = SIZ_35ROWS;
+ else
+ size = SIZ_25ROWS;
+ break;
+
+ case SIZ_43ROWS:
+ default:
+ if(totscanlines/lines_per_character >= 43)
+ size = SIZ_43ROWS;
+ else if(totscanlines/lines_per_character >= 35)
+ size = SIZ_35ROWS;
+ else
+ size = SIZ_25ROWS;
+ break;
+ }
+ }
+ else
+ {
+ switch(size)
+ {
+ case SIZ_25ROWS: /* This case is always OK */
+ break;
+
+ case SIZ_28ROWS:
+ if(totscanlines/lines_per_character >= 28)
+ size = SIZ_28ROWS;
+ else
+ size = SIZ_25ROWS;
+ break;
+
+ case SIZ_40ROWS:
+ if(totscanlines/lines_per_character >= 40)
+ size = SIZ_40ROWS;
+ else if(totscanlines/lines_per_character >= 28)
+ size = SIZ_28ROWS;
+ else
+ size = SIZ_25ROWS;
+ break;
+
+ case SIZ_50ROWS:
+ default:
+ if(totscanlines/lines_per_character >= 50)
+ size = SIZ_50ROWS;
+ else if(totscanlines/lines_per_character >= 40)
+ size = SIZ_40ROWS;
+ else if(totscanlines/lines_per_character >= 28)
+ size = SIZ_28ROWS;
+ else
+ size = SIZ_25ROWS;
+ break;
+ }
+ }
+
+ vgacs[vga_character_set].screen_size = size;
+
+ for (i = 0;i < PCVT_NSCREENS;i++)
+ {
+ if(vga_character_set == vs[i].vga_charset)
+ set_charset(&(vs[i]),vga_character_set);
+ }
+ switch_screen(current_video_screen, 0, 0);
+}
+
+/*---------------------------------------------------------------------------*
+ * ega/vga ioctl - get font attributes
+ *---------------------------------------------------------------------------*/
+static void
+vgagetfontattr(struct vgafontattr *data)
+{
+ int vga_character_set;
+
+ vga_character_set = data->character_set;
+ vga_character_set = (vga_character_set < 0) ? 0 :
+ ((vga_character_set < (int)totalfonts) ?
+ vga_character_set :
+ (int)(totalfonts-1));
+
+ data->character_set = (int)vga_character_set;
+
+ data->font_loaded = (int)vgacs[vga_character_set].loaded;
+
+ data->character_scanlines =
+ (int)vgacs[vga_character_set].char_scanlines
+ & 0x1f; /* do not display the overflow bits */
+
+ data->screen_scanlines = (int)vgacs[vga_character_set].scr_scanlines;
+
+ data->screen_size = (int)vgacs[vga_character_set].screen_size;
+}
+
+/*---------------------------------------------------------------------------*
+ * ega/vga ioctl - load a character shape into character set
+ *---------------------------------------------------------------------------*/
+static void
+vgaloadchar(struct vgaloadchar *data)
+{
+ int vga_character_set;
+ int character;
+ int lines_per_character;
+
+ vga_character_set = data->character_set;
+ vga_character_set = (vga_character_set < 0) ? 0 :
+ ((vga_character_set < (int)totalfonts) ?
+ vga_character_set : (int)(totalfonts-1));
+
+ character = (data->character < 0) ? 0 :
+ ((data->character > 255) ? 255 : data->character);
+
+ lines_per_character = (int)data->character_scanlines;
+ lines_per_character = (lines_per_character < 0) ? 0 :
+ ((lines_per_character > 32) ? 32 : lines_per_character);
+
+ loadchar(vga_character_set,character,lines_per_character,
+ data->char_table);
+}
+
+/*---------------------------------------------------------------------------*
+ * video ioctl - get screen information
+ *---------------------------------------------------------------------------*/
+static void
+vid_getscreen(struct screeninfo *data, Dev_t dev)
+{
+ int device = minor(dev);
+ data->adaptor_type = adaptor_type; /* video adapter installed */
+ data->monitor_type = color; /* monitor type installed */
+ data->totalfonts = totalfonts; /* no of downloadble fonts */
+ data->totalscreens = totalscreens; /* no of virtual screens */
+ data->screen_no = device; /* this screen number */
+ data->current_screen = current_video_screen; /* displayed screen no */
+ /* screen size */
+ data->screen_size = vgacs[(vs[device].vga_charset)].screen_size;
+ /* pure VT mode or HP/VT mode */
+ data->pure_vt_mode = vs[device].vt_pure_mode;
+ data->vga_family = vga_family; /* manufacturer, family */
+ data->vga_type = vga_type; /* detected chipset type */
+ data->vga_132 = can_do_132col; /* 132 column support */
+ data->force_24lines = vs[device].force24; /* force 24 lines */
+}
+
+/*---------------------------------------------------------------------------*
+ * video ioctl - set screen information
+ *---------------------------------------------------------------------------*/
+static void
+vid_setscreen(struct screeninfo *data, Dev_t dev)
+{
+ int screen, x, waitfor;
+
+ if(data->current_screen == -1)
+ {
+ screen = minor(dev);
+ }
+ else
+ {
+ if(data->current_screen >= PCVT_NSCREENS)
+ return; /* XXXXXX */
+ screen = data->current_screen;
+ }
+
+ vgapage(screen);
+
+ x = spltty();
+
+ waitfor = screen + 1;
+
+ /* if the vt is yet to be released by a process, wait here */
+
+ if(vs[screen].vt_status & VT_WAIT_REL)
+ (void)usl_vt_ioctl(dev, VT_WAITACTIVE, (caddr_t)&waitfor, 0, 0);
+
+ splx(x);
+
+ /* make sure the switch really happened */
+
+ if(screen != current_video_screen)
+ return; /* XXX should say "EAGAIN" here */
+
+ if((data->screen_size != -1) || (data->force_24lines != -1))
+ {
+ if(data->screen_size == -1)
+ data->screen_size =
+ vgacs[(vs[screen].vga_charset)].screen_size;
+
+ if(data->force_24lines != -1)
+ {
+ vs[screen].force24 = data->force_24lines;
+
+ if(vs[screen].force24)
+ {
+ swritefkl(2,(u_char *)"FORCE24 ENABLE *",
+ &vs[screen]);
+ }
+ else
+ {
+ swritefkl(2,(u_char *)"FORCE24 ENABLE ",
+ &vs[screen]);
+ }
+ }
+
+ if((data->screen_size == SIZ_25ROWS) ||
+ (data->screen_size == SIZ_28ROWS) ||
+ (data->screen_size == SIZ_35ROWS) ||
+ (data->screen_size == SIZ_40ROWS) ||
+ (data->screen_size == SIZ_43ROWS) ||
+ (data->screen_size == SIZ_50ROWS))
+ {
+ if(data->screen_no == -1)
+ set_screen_size(vsp, data->screen_size);
+ else
+ set_screen_size(&vs[minor(dev)],
+ data->screen_size);
+ }
+ }
+
+ if(data->pure_vt_mode != -1)
+ {
+ if((data->pure_vt_mode == M_HPVT) ||
+ (data->pure_vt_mode == M_PUREVT))
+ {
+ if(data->screen_no == -1)
+ set_emulation_mode(vsp, data->pure_vt_mode);
+ else
+ set_emulation_mode(&vs[minor(dev)],
+ data->pure_vt_mode);
+ }
+ }
+}
+
+/*---------------------------------------------------------------------------*
+ * set screen size/resolution for a virtual screen
+ *---------------------------------------------------------------------------*/
+void
+set_screen_size(struct video_state *svsp, int size)
+{
+ int i;
+
+ for(i = 0; i < totalfonts; i++)
+ {
+ if(vgacs[i].screen_size == size)
+ {
+ set_charset(svsp, i);
+ clr_parms(svsp); /* escape parameter init */
+ svsp->state = STATE_INIT; /* initial state */
+ svsp->scrr_beg = 0; /* start of scrolling region */
+ svsp->sc_flag = 0; /* invalidate saved cursor
+ * position */
+ svsp->transparent = 0; /* disable control code
+ * processing */
+
+ /* Update tty to reflect screen size */
+
+ if (svsp->vs_tty)
+ {
+ svsp->vs_tty->t_winsize.ws_col = svsp->maxcol;
+ svsp->vs_tty->t_winsize.ws_xpixel =
+ (svsp->maxcol == 80)? 720: 1056;
+ svsp->vs_tty->t_winsize.ws_ypixel = 400;
+ svsp->vs_tty->t_winsize.ws_row =
+ svsp->screen_rows;
+ }
+
+ /* screen_rows already calculated in set_charset() */
+ if(svsp->vt_pure_mode == M_HPVT && svsp->labels_on)
+ {
+ if(svsp->which_fkl == SYS_FKL)
+ sw_sfkl(svsp);
+ else if(svsp->which_fkl == USR_FKL)
+ sw_ufkl(svsp);
+ }
+
+ svsp->scrr_len = svsp->screen_rows;
+ svsp->scrr_end = svsp->scrr_len - 1;
+
+#if PCVT_SIGWINCH
+ if (svsp->vs_tty && svsp->vs_tty->t_pgrp)
+ pgsignal(svsp->vs_tty->t_pgrp, SIGWINCH, 1);
+#endif /* PCVT_SIGWINCH */
+
+ break;
+ }
+ }
+}
+
+/*---------------------------------------------------------------------------*
+ * VGA ioctl - read DAC palette entry
+ *---------------------------------------------------------------------------*/
+static void
+vgareadpel(struct vgapel *data, Dev_t dev)
+{
+ register unsigned vpage = minor(dev);
+ register unsigned idx = data->idx;
+
+ if(idx >= NVGAPEL)
+ return; /* no such entry */
+
+ /* do not read VGA palette directly, use saved values */
+ data->r = vs[vpage].palette[idx].r;
+ data->g = vs[vpage].palette[idx].g;
+ data->b = vs[vpage].palette[idx].b;
+}
+
+/*---------------------------------------------------------------------------*
+ * VGA ioctl - write DAC palette entry
+ *---------------------------------------------------------------------------*/
+static void
+vgawritepel(struct vgapel *data, Dev_t dev)
+{
+ register unsigned vpage = minor(dev);
+ register unsigned idx = data->idx;
+
+ if(idx >= NVGAPEL)
+ return; /* no such entry */
+
+ /* first, update saved values for this video screen */
+ vs[vpage].palette[idx].r = data->r;
+ vs[vpage].palette[idx].g = data->g;
+ vs[vpage].palette[idx].b = data->b;
+
+ /* if this happens on active screen, update VGA DAC, too */
+ if(vpage == current_video_screen)
+ vgapaletteio(idx, &vs[vpage].palette[idx], 1);
+}
+
+/*---------------------------------------------------------------------------*
+ * VGA physical IO - read/write one palette entry
+ *---------------------------------------------------------------------------*/
+void
+vgapaletteio(unsigned idx, struct rgb *val, int writeit)
+{
+
+#if PCVT_PALFLICKER
+ vga_screen_off();
+#endif /* PCVT_PALFLICKER */
+
+ if(writeit)
+ {
+ outb(VGA_DAC + 2, idx);
+
+#if PCVT_WAITRETRACE
+ wait_retrace();
+#endif /* PCVT_WAITRETRACE */
+
+ outb(VGA_DAC + 3, val->r & VGA_PMSK);
+
+#if PCVT_WAITRETRACE
+ wait_retrace();
+#endif /* PCVT_WAITRETRACE */
+
+ outb(VGA_DAC + 3, val->g & VGA_PMSK);
+
+#if PCVT_WAITRETRACE
+ wait_retrace();
+#endif /* PCVT_WAITRETRACE */
+
+ outb(VGA_DAC + 3, val->b & VGA_PMSK);
+ }
+ else /* read it */
+ {
+ outb(VGA_DAC + 1, idx);
+
+#if PCVT_WAITRETRACE
+ wait_retrace();
+#endif /* PCVT_WAITRETRACE */
+
+ val->r = inb(VGA_DAC + 3) & VGA_PMSK;
+
+#if PCVT_WAITRETRACE
+ wait_retrace();
+#endif /* PCVT_WAITRETRACE */
+
+ val->g = inb(VGA_DAC + 3) & VGA_PMSK;
+
+#if PCVT_WAITRETRACE
+ wait_retrace();
+#endif /* PCVT_WAITRETRACE */
+
+ val->b = inb(VGA_DAC + 3) & VGA_PMSK;
+ }
+
+#if PCVT_PALFLICKER
+ vga_screen_on();
+#endif /* PCVT_PALFLICKER */
+
+}
+
+/*---------------------------------------------------------------------------*
+ *
+ * update asynchronous: cursor, cursor pos displ, sys load, keyb scan
+ *
+ * arg is:
+ * UPDATE_START = 0 = do update; requeue
+ * UPDATE_STOP = 1 = suspend updates
+ * UPDATE_KERN = 2 = do update for kernel printfs
+ *
+ *---------------------------------------------------------------------------*/
+void
+async_update(int arg)
+{
+ static int lastpos = 0;
+ static int counter = PCVT_UPDATESLOW;
+
+#ifdef XSERVER
+ /* need a method to suspend the updates */
+
+ if(arg == UPDATE_STOP)
+ {
+ untimeout((TIMEOUT_FUNC_T)async_update, UPDATE_START);
+ return;
+ }
+#endif /* XSERVER */
+
+ /* first check if update is possible */
+
+ if(chargen_access) /* does someone load characters? */
+ goto async_update_exit; /* yes, do not update anything */
+
+#if PCVT_SCREENSAVER
+ if(reset_screen_saver && (counter == PCVT_UPDATESLOW))
+ {
+ pcvt_scrnsv_reset(); /* yes, do it */
+ reset_screen_saver = 0; /* re-init */
+ }
+ else if(scrnsv_active) /* is the screen not blanked? */
+ {
+ goto async_update_exit; /* do not update anything */
+ }
+#endif /* PCVT_SCREENSAVER */
+
+ /*-------------------------------------------------------------------*/
+ /* this takes place on EVERY virtual screen (if not in X mode etc...)*/
+ /*-------------------------------------------------------------------*/
+
+ if ( cursor_pos_valid &&
+ (lastpos != (vsp->Crtat + vsp->cur_offset - Crtat)))
+ {
+ lastpos = vsp->Crtat + vsp->cur_offset - Crtat;
+ outb(addr_6845, CRTC_CURSORH); /* high register */
+ outb(addr_6845+1, ((lastpos) >> 8));
+ outb(addr_6845, CRTC_CURSORL); /* low register */
+ outb(addr_6845+1, (lastpos));
+ }
+
+ if (arg == UPDATE_KERN) /* Magic arg: for kernel printfs */
+ return;
+
+ if(--counter) /* below is possible update */
+ goto async_update_exit; /* just now and then ..... */
+ counter = PCVT_UPDATESLOW; /* caution, see screensaver above !! */
+
+ /*-------------------------------------------------------------------*/
+ /* this takes place ONLY on screen 0 if in HP mode, labels on, !X */
+ /*-------------------------------------------------------------------*/
+
+ /* additional processing for HP necessary ? */
+
+ if((vs[0].vt_pure_mode == M_HPVT) && (vs[0].labels_on))
+ {
+ static volatile u_char buffer[] =
+ "System Load: 1min: 0.00 5min: 0.00 15min: 0.00";
+ register int tmp, i;
+#if PCVT_SHOWKEYS
+ extern u_char rawkeybuf[80];
+
+ if(keyboard_show)
+ {
+ for(i = 0; i < 80; i++)
+ {
+ *((vs[0].Crtat+((vs[0].screen_rows+2)
+ * vs[0].maxcol))+i) =
+ user_attr | rawkeybuf[i];
+ }
+ }
+ else
+ {
+#endif /* PCVT_SHOWKEYS */
+
+ /* display load averages in last line (taken from tty.c) */
+ i = 18;
+#ifdef NEW_AVERUNNABLE
+ tmp = (averunnable.ldavg[0] * 100 + FSCALE / 2)
+ >> FSHIFT;
+#else
+ tmp = (averunnable[0] * 100 + FSCALE / 2) >> FSHIFT;
+#endif
+
+ buffer[i++] =
+ ((((tmp/100)/10) == 0) ?
+ ' ' :
+ ((tmp/100)/10) + '0');
+ buffer[i++] = ((tmp/100)%10) + '0';
+ buffer[i++] = '.';
+ buffer[i++] = ((tmp%100)/10) + '0';
+ buffer[i++] = ((tmp%100)%10) + '0';
+ i += 6;
+#ifdef NEW_AVERUNNABLE
+ tmp = (averunnable.ldavg[1] * 100 + FSCALE / 2)
+ >> FSHIFT;
+#else
+ tmp = (averunnable[1] * 100 + FSCALE / 2) >> FSHIFT;
+#endif
+ buffer[i++] = ((((tmp/100)/10) == 0) ?
+ ' ' :
+ ((tmp/100)/10) + '0');
+ buffer[i++] = ((tmp/100)%10) + '0';
+ buffer[i++] = '.';
+ buffer[i++] = ((tmp%100)/10) + '0';
+ buffer[i++] = ((tmp%100)%10) + '0';
+ i += 7;
+#ifdef NEW_AVERUNNABLE
+ tmp = (averunnable.ldavg[2] * 100 + FSCALE / 2)
+ >> FSHIFT;
+#else
+ tmp = (averunnable[2] * 100 + FSCALE / 2) >> FSHIFT;
+#endif
+ buffer[i++] = ((((tmp/100)/10) == 0) ?
+ ' ' :
+ ((tmp/100)/10) + '0');
+ buffer[i++] = ((tmp/100)%10) + '0';
+ buffer[i++] = '.';
+ buffer[i++] = ((tmp%100)/10) + '0';
+ buffer[i++] = ((tmp%100)%10) + '0';
+ buffer[i] = '\0';
+
+ for(i = 0; buffer[i]; i++)
+ {
+ *((vs[0].Crtat +
+ ((vs[0].screen_rows + 2) * vs[0].maxcol)
+ ) + i
+ ) = user_attr | buffer[i];
+ }
+
+#if PCVT_SHOWKEYS
+ for(; i < 77; i++)
+ {
+ *((vs[0].Crtat +
+ ((vs[0].screen_rows + 2) * vs[0].maxcol)
+ ) + i
+ ) = user_attr | ' ';
+ }
+
+ }
+#endif /* PCVT_SHOWKEYS */
+ }
+
+ /*-------------------------------------------------------------------*/
+ /* this takes place on EVERY screen which is in HP mode, labels on,!X*/
+ /*-------------------------------------------------------------------*/
+
+ if((vsp->vt_pure_mode == M_HPVT) && (vsp->labels_on))
+ {
+ register int col = vsp->col+1;
+ register u_short *p = vsp->Crtat +
+ (vsp->screen_rows * vsp->maxcol);
+
+ /* update column display between labels */
+
+ if(vsp->maxcol == SCR_COL132)
+ {
+ p += (SCR_COL132 - SCR_COL80)/2;
+
+ if(col >= 100)
+ {
+ *(p + LABEL_COLU) = user_attr | '1';
+ col -= 100;
+ }
+ else
+ {
+ *(p + LABEL_COLU) = user_attr | '0';
+ }
+ }
+ *(p + LABEL_COLH) = user_attr | ((col/10) + '0');
+ *(p + LABEL_COLL) = user_attr | ((col%10) + '0');
+
+ /* update row display between labels */
+
+ *(p + LABEL_ROWH) = (user_attr | (((vsp->row+1)/10) + '0'));
+ *(p + LABEL_ROWL) = (user_attr | (((vsp->row+1)%10) + '0'));
+ }
+
+async_update_exit:
+
+ if(arg == UPDATE_START)
+ {
+ timeout((TIMEOUT_FUNC_T)async_update, UPDATE_START, PCVT_UPDATEFAST);
+ }
+}
+
+/*---------------------------------------------------------------------------*
+ * set character set for virtual screen
+ *---------------------------------------------------------------------------*/
+void
+set_charset(struct video_state *svsp, int curvgacs)
+{
+ static int sizetab[] = { 25, 28, 35, 40, 43, 50 };
+ int oldsize, oldrows, newsize, newrows;
+
+ if((curvgacs < 0) || (curvgacs > (NVGAFONTS-1)))
+ return;
+
+ svsp->vga_charset = curvgacs;
+
+ select_vga_charset(curvgacs);
+
+ oldsize = svsp->screen_rowsize;
+ oldrows = svsp->screen_rows;
+ newsize = sizetab[(vgacs[curvgacs].screen_size)];
+ newrows = newsize;
+ if (svsp->vt_pure_mode == M_HPVT)
+ newrows -= 3;
+ if (newrows == 25 && svsp->force24)
+ newrows = 24;
+ if (newrows < oldrows) {
+ int nscroll = svsp->row + 1 - newrows;
+
+ if (svsp->row >= oldrows) /* Sanity check */
+ nscroll = oldrows - newrows;
+ if (nscroll > 0) {
+ /* Scroll up */
+ bcopy (svsp->Crtat + nscroll * svsp->maxcol,
+ svsp->Crtat,
+ newrows * svsp->maxcol * CHR);
+ svsp->row -= nscroll;
+ svsp->cur_offset -= nscroll * svsp->maxcol;
+ }
+ if (newrows < newsize)
+ fillw(user_attr | ' ',
+ svsp->Crtat + newrows * svsp->maxcol,
+ (newsize - newrows) * svsp->maxcol);
+ } else if (oldrows < newsize)
+ fillw(user_attr | ' ',
+ svsp->Crtat + oldrows * svsp->maxcol,
+ (newsize - oldrows) * svsp->maxcol);
+
+ svsp->screen_rowsize = newsize;
+ svsp->screen_rows = newrows;
+
+ /* Clip scrolling region */
+ if(svsp->scrr_end > svsp->screen_rows - 1)
+ svsp->scrr_end = svsp->screen_rows - 1;
+ svsp->scrr_len = svsp->scrr_end - svsp->scrr_beg + 1;
+
+ /* Clip cursor pos */
+
+ if(svsp->cur_offset > (svsp->scrr_len * svsp->maxcol))
+ svsp->cur_offset = (svsp->scrr_len * svsp->maxcol) + svsp->col;
+}
+
+/*---------------------------------------------------------------------------*
+ * select a vga character set
+ *---------------------------------------------------------------------------*/
+void
+select_vga_charset(int vga_charset)
+{
+ int first, second;
+ int fflag = 0;
+ int sflag = 0;
+ u_char cmap = 0;
+
+ static u_char cmaptaba[] =
+ {0x00, 0x01, 0x02, 0x03, 0x10, 0x11, 0x12, 0x13};
+
+ static u_char cmaptabb[] =
+ {0x00, 0x04, 0x08, 0x0c, 0x20, 0x24, 0x28, 0x2c};
+
+ if((adaptor_type != EGA_ADAPTOR) && (adaptor_type != VGA_ADAPTOR))
+ return;
+
+ if((vga_charset < 0) || (vga_charset >= totalfonts))
+ return;
+
+ if(!vgacs[vga_charset].loaded)
+ return;
+
+ /*--------------------------------------------------------------
+ find the the first and second charset of a given resolution.
+ the first is used for lower 256 and the second (if any) is
+ used for the upper 256 entries of a complete 512 entry ega/
+ vga charset.
+ --------------------------------------------------------------*/
+
+ for(first = 0; first < totalfonts; first++)
+ {
+ if(!vgacs[first].loaded)
+ continue;
+ if(vgacs[first].screen_size != vgacs[vga_charset].screen_size)
+ continue;
+ if(vgacs[first].char_scanlines !=
+ vgacs[vga_charset].char_scanlines)
+ continue;
+ if(vgacs[first].scr_scanlines !=
+ vgacs[vga_charset].scr_scanlines)
+ continue;
+ fflag = 1;
+ break;
+ }
+
+ if(fflag != 1)
+ return;
+
+ for(second = first+1; second < totalfonts; second++)
+ {
+ if(!vgacs[second].loaded)
+ continue;
+ if(vgacs[second].screen_size != vgacs[vga_charset].screen_size)
+ continue;
+ if(vgacs[second].char_scanlines !=
+ vgacs[vga_charset].char_scanlines)
+ continue;
+ if(vgacs[second].scr_scanlines !=
+ vgacs[vga_charset].scr_scanlines)
+ continue;
+ sflag = 1;
+ break;
+ }
+
+ cmap = cmaptaba[first];
+ if(sflag)
+ {
+ cmap |= cmaptabb[second];
+ vgacs[first].secondloaded = second;
+ }
+ else
+ {
+ vgacs[first].secondloaded = 0; /*cs 0 can never become a 2nd!*/
+ }
+
+ if(vsp->wd132col)
+ {
+ cmap = (vga_charset & 0x07);
+ cmap |= 0x10;
+ }
+
+ outb(TS_INDEX, TS_FONTSEL); /* character map select register */
+ outb(TS_DATA, cmap); /* new char map */
+
+ outb(addr_6845, CRTC_MAXROW); /* max scan line reg */
+ outb(addr_6845+1,
+ vgacs[first].char_scanlines); /* scanlines/char */
+
+ outb(addr_6845, CRTC_VDE); /* vert display enable end */
+ outb(addr_6845+1,
+ vgacs[first].scr_scanlines); /* low byte of scr scanlines */
+
+ if((color == 0) && (adaptor_type == VGA_ADAPTOR))
+ {
+ outb(addr_6845, CRTC_ULOC); /* underline location reg */
+ outb(addr_6845+1, (vgacs[first].char_scanlines & 0x1F));
+ }
+}
+
+/*---------------------------------------------------------------------------*
+ * switch vga-card to load a character set
+ *---------------------------------------------------------------------------*/
+static void
+setchargen(void)
+{
+ chargen_access = 1; /* flag we are accessing the chargen ram */
+
+ /* program sequencer to access character generator */
+
+ outb(TS_INDEX, TS_SYNCRESET);
+ outb(TS_DATA, 0x01); /* synchronous reset */
+
+ outb(TS_INDEX, TS_WRPLMASK);
+ outb(TS_DATA, 0x04); /* write to map 2 */
+
+ outb(TS_INDEX, TS_MEMMODE);
+ outb(TS_DATA, 0x07); /* sequential addressing */
+
+ outb(TS_INDEX, TS_SYNCRESET);
+ outb(TS_DATA, 0x03); /* clear synchronous reset */
+
+ /* program graphics controller to access character generator */
+
+ outb(GDC_INDEX, GDC_RDPLANESEL);
+ outb(GDC_DATA, 0x02); /* select map 2 for cpu reads */
+
+ outb(GDC_INDEX, GDC_MODE);
+ outb(GDC_DATA, 0x00); /* disable odd-even addressing */
+
+ outb(GDC_INDEX, GDC_MISC);
+ outb(GDC_DATA, 0x00); /* map starts at 0xA000 */
+}
+
+/*---------------------------------------------------------------------------*
+ * switch vga-card to load a character set to plane 3
+ *---------------------------------------------------------------------------*/
+static void
+setchargen3(void)
+{
+ chargen_access = 1; /* flag we are accessing the chargen ram */
+
+ /* program sequencer to access character generator */
+
+ outb(TS_INDEX, TS_SYNCRESET);
+ outb(TS_DATA, 0x01); /* synchronous reset */
+
+ outb(TS_INDEX, TS_WRPLMASK);
+ outb(TS_DATA, 0x08); /* write to map 3 */
+
+ outb(TS_INDEX, TS_MEMMODE);
+ outb(TS_DATA, 0x07); /* sequential addressing */
+
+ outb(TS_INDEX, TS_SYNCRESET);
+ outb(TS_DATA, 0x03); /* clear synchronous reset */
+
+ /* program graphics controller to access character generator */
+
+ outb(GDC_INDEX, GDC_RDPLANESEL);
+ outb(GDC_DATA, 0x03); /* select map 3 for cpu reads */
+
+ outb(GDC_INDEX, GDC_MODE);
+ outb(GDC_DATA, 0x00); /* disable odd-even addressing */
+
+ outb(GDC_INDEX, GDC_MISC);
+ outb(GDC_DATA, 0x00); /* map starts at 0xA000 */
+}
+
+/*---------------------------------------------------------------------------*
+ * switch back vga-card to normal operation
+ *---------------------------------------------------------------------------*/
+static void
+resetchargen(void)
+{
+ /* program sequencer to access video ram */
+
+ outb(TS_INDEX, TS_SYNCRESET);
+ outb(TS_DATA, 0x01); /* synchronous reset */
+
+ outb(TS_INDEX, TS_WRPLMASK);
+ outb(TS_DATA, 0x03); /* write to map 0 & 1 */
+
+ outb(TS_INDEX, TS_MEMMODE);
+ outb(TS_DATA, 0x03); /* odd-even addressing */
+
+ outb(TS_INDEX, TS_SYNCRESET);
+ outb(TS_DATA, 0x03); /* clear synchronous reset */
+
+ /* program graphics controller to access character generator */
+
+ outb(GDC_INDEX, GDC_RDPLANESEL);
+ outb(GDC_DATA, 0x00); /* select map 0 for cpu reads */
+
+ outb(GDC_INDEX, GDC_MODE);
+ outb(GDC_DATA, 0x10); /* enable odd-even addressing */
+
+ outb(GDC_INDEX, GDC_MISC);
+ if(color)
+ outb(GDC_DATA, 0x0e); /* map starts at 0xb800 */
+ else
+ outb(GDC_DATA, 0x0a); /* map starts at 0xb000 */
+
+ chargen_access = 0; /* flag we are NOT accessing the chargen ram */
+}
+
+#if PCVT_WAITRETRACE
+/*---------------------------------------------------------------------------*
+ * wait for being in a retrace time window
+ * NOTE: this is __VERY__ bad programming practice in this environment !!
+ *---------------------------------------------------------------------------*/
+
+static void
+wait_retrace(void)
+{
+ if(color)
+ {
+ while(!(inb(GN_INPSTAT1C) & 0x01))
+ ;
+ }
+ else
+ {
+ while(!(inb(GN_INPSTAT1M) & 0x01))
+ ;
+ }
+}
+
+#endif /* PCVT_WAITRETRACE */
+
+/*---------------------------------------------------------------------------*
+ * switch screen off (VGA only)
+ *---------------------------------------------------------------------------*/
+void
+vga_screen_off(void)
+{
+ unsigned char old;
+
+ outb(TS_INDEX, TS_SYNCRESET);
+ outb(TS_DATA, 0x01); /* synchronous reset */
+
+ outb(TS_INDEX, TS_MODE); /* clocking mode reg */
+ old = inb(TS_DATA); /* get current value */
+
+ outb(TS_INDEX, TS_MODE); /* clocking mode reg */
+ outb(TS_DATA, (old | 0x20)); /* screen off bit on */
+
+ outb(TS_INDEX, TS_SYNCRESET);
+ outb(TS_DATA, 0x03); /* clear synchronous reset */
+}
+
+/*---------------------------------------------------------------------------*
+ * switch screen back on (VGA only)
+ *---------------------------------------------------------------------------*/
+void
+vga_screen_on(void)
+{
+ unsigned char old;
+
+ outb(TS_INDEX, TS_SYNCRESET);
+ outb(TS_DATA, 0x01); /* synchronous reset */
+
+ outb(TS_INDEX, TS_MODE); /* clocking mode reg */
+ old = inb(TS_DATA); /* get current value */
+
+ outb(TS_INDEX, TS_MODE); /* clocking mode reg */
+ outb(TS_DATA, (old & ~0x20)); /* screen off bit off */
+
+ outb(TS_INDEX, TS_SYNCRESET);
+ outb(TS_DATA, 0x03); /* clear synchronous reset */
+}
+
+/*---------------------------------------------------------------------------*
+ * compute character set base address (in kernel map)
+ *---------------------------------------------------------------------------*/
+static unsigned char *
+compute_charset_base(unsigned fontset)
+{
+ unsigned char *d = (unsigned char *)Crtat;
+
+ static int charset_offset[8] = { 0x0000, 0x4000, 0x8000, 0xC000,
+ 0x2000, 0x6000, 0xA000, 0xE000 };
+
+ static int charsetw_offset[8] = { 0x0000, 0x2000, 0x4000, 0x6000,
+ 0x8000, 0xA000, 0xC000, 0xE000 };
+
+ switch(adaptor_type)
+ {
+ case EGA_ADAPTOR:
+ fontset = (fontset > 3) ? 3 : fontset;
+ break;
+
+ case VGA_ADAPTOR:
+ fontset = (fontset > 7) ? 7 : fontset;
+ break;
+
+ default:
+ return 0;
+ }
+
+ if(color)
+ d -= (0xB8000 - 0xA0000); /* Point to 0xA0000 */
+ else
+ d -= (0xB0000 - 0xA0000); /* Point to 0xA0000 */
+
+ if(vsp->wd132col)
+ d += charsetw_offset[fontset]; /* Load into Character set n */
+ else
+ d += charset_offset[fontset]; /* Load into Character set n */
+
+ return d;
+}
+
+/*---------------------------------------------------------------------------*
+ * load a char into ega/vga character generator ram
+ *---------------------------------------------------------------------------*/
+void
+loadchar(int fontset, int character, int char_scanlines, u_char *char_table)
+{
+ unsigned char *d;
+
+#if PCVT_BACKUP_FONTS
+ unsigned char *bak;
+#endif /* PCVT_BACKUP_FONTS */
+
+ int j, k;
+
+ if((d = compute_charset_base(fontset)) == 0)
+ return;
+
+ d += (character * 32); /* 32 bytes per character */
+
+ if(vsp->wd132col &&
+ (fontset == 1||fontset == 3||fontset == 5||fontset == 7))
+ setchargen3(); /* access chargen ram */
+ else
+ setchargen(); /* access chargen ram */
+
+ for(j = k = 0; j < char_scanlines; j++) /* x bit high characters */
+ {
+ *d = char_table[k];
+ d++;
+ k++;
+ }
+ for(; j < 32; j++) /* Up to 32 bytes per character image*/
+ {
+ *d = 0x00;
+ d++;
+ }
+
+ resetchargen(); /* access video ram */
+
+#if PCVT_BACKUP_FONTS
+ if(saved_charsets[fontset] == 0)
+ saved_charsets[fontset] =
+ (u_char *)malloc(32 * 256, M_DEVBUF, M_WAITOK);
+
+ if((bak = saved_charsets[fontset]))
+ {
+ /* make a backup copy of this char */
+ bak += (character * 32);
+ bzero(bak, 32);
+ bcopy(char_table, bak, char_scanlines);
+ }
+#ifdef DIAGNOSTIC
+ else
+ panic("pcvt loadchar: no backup buffer");
+#endif /* DIAGNOSTIC */
+
+#endif /* PCVT_BACKUP_FONTS */
+
+}
+
+/*---------------------------------------------------------------------------*
+ * save/restore character set n to addr b
+ *---------------------------------------------------------------------------*/
+#if !PCVT_BACKUP_FONTS
+
+void
+vga_move_charset(unsigned n, unsigned char *b, int save_it)
+{
+ unsigned char *d = compute_charset_base(n);
+
+#ifdef DIAGNOSTIC
+ if(d == 0)
+ panic("vga_move_charset: wrong adaptor");
+#endif
+
+ if(vsp->wd132col && (n == 1||n == 3||n == 5||n == 7))
+ {
+ setchargen3();
+ d -= 0x2000;
+ }
+ else
+ {
+ setchargen();
+ }
+
+ /* PLEASE, leave the following alone using bcopyb, as several */
+ /* chipsets have problems if their memory is accessed with 32 */
+ /* or 16 bits wide, don't change this to using bcopy for speed! */
+
+ if(save_it)
+ bcopyb(d, b, 256 /* chars */ * 32 /* bytes per char */);
+ else
+ bcopyb(b, d, 256 /* chars */ * 32 /* bytes per char */);
+
+ resetchargen();
+}
+
+#else /* PCVT_BACKUP_FONTS */
+
+/* since there are always backed up copies, we do not save anything here */
+/* parameter "b" is totally ignored */
+
+void
+vga_move_charset(unsigned n, unsigned char *b, int save_it)
+{
+ unsigned char *d = compute_charset_base(n);
+
+ if(save_it)
+ return;
+
+ if(saved_charsets[n] == 0)
+#ifdef DIAGNOSTIC
+ panic("pcvt: restoring unbuffered charset");
+#else
+ return;
+#endif
+
+#ifdef DIAGNOSTIC
+ if(d == 0)
+ panic("vga_move_charset: wrong adaptor");
+#endif
+
+ if(vsp->wd132col && (n == 1||n == 3||n == 5||n == 7))
+ {
+ setchargen3();
+ d -= 0x2000;
+ }
+ else
+ {
+ setchargen();
+ }
+
+ /* PLEASE, leave the following alone using bcopyb, as several */
+ /* chipsets have problems if their memory is accessed with 32 */
+ /* or 16 bits wide, don't change this to using bcopy for speed! */
+
+ bcopyb(saved_charsets[n], d,
+ 256 /* chars */ * 32 /* bytes per char */);
+
+ resetchargen();
+}
+
+#endif /* PCVT_BACKUP_FONTS */
+
+/*---------------------------------------------------------------------------*
+ * test if it is a vga
+ *---------------------------------------------------------------------------*/
+int
+vga_test(void)
+{
+ u_char old, new, check;
+
+ outb(addr_6845,CRTC_CURSTART); /* cursor start reg */
+ old = inb(addr_6845+1); /* get current value */
+
+ new = old | CURSOR_ON_BIT; /* set cursor on by setting bit 5 on */
+
+ outb(addr_6845,CRTC_CURSTART); /* cursor start reg */
+ outb(addr_6845+1,new); /* cursor should be on now */
+
+ outb(addr_6845,CRTC_CURSTART); /* cursor start reg */
+ check = inb(addr_6845+1); /* get current value */
+
+ if(check != new)
+ {
+ outb(addr_6845,CRTC_CURSTART); /* cursor start reg */
+ outb(addr_6845+1,old); /* failsafe */
+ return(0); /* must be ega */
+ }
+
+ new = old & ~CURSOR_ON_BIT; /* turn cursor off by clearing bit 5 */
+
+ outb(addr_6845,CRTC_CURSTART); /* cursor start reg */
+ outb(addr_6845+1,new); /* cursor should be off now */
+
+ outb(addr_6845,CRTC_CURSTART); /* cursor start reg */
+ check = inb(addr_6845+1); /* get current value */
+
+ if(check != new)
+ {
+ outb(addr_6845,CRTC_CURSTART); /* cursor start reg */
+ outb(addr_6845+1,old); /* failsafe */
+ return(0); /* must be ega */
+ }
+
+ outb(addr_6845,CRTC_CURSTART); /* cursor start reg */
+ outb(addr_6845+1,old); /* failsafe */
+
+ return(1); /* vga */
+}
+
+/*---------------------------------------------------------------------------*
+ * convert upper/lower sixel font array to vga font array
+ *---------------------------------------------------------------------------*/
+void
+sixel_vga(struct sixels *sixelp, u_char *vgachar)
+{
+ register int i, j;
+ register int shift;
+ register u_char mask;
+
+ for(j = 0; j < 16; j++)
+ vgachar[j] = 0;
+
+ mask = 0x01;
+ for(j = 0; j < 6; j++)
+ {
+ for(i = 0, shift = 7; i < 8; i++, shift--)
+ vgachar[j] |= ((((sixelp->upper[i]) & mask) >> j)
+ << shift);
+ mask <<= 1;
+ }
+
+ mask = 0x01;
+ for(j = 0; j < 4; j++)
+ {
+ for(i = 0, shift = 7; i < 8; i++, shift--)
+ vgachar[j+6] |= ((((sixelp->lower[i]) & mask) >>j)
+ << shift);
+ mask <<= 1;
+ }
+}
+
+/*---------------------------------------------------------------------------*
+ * Expand 8x10 EGA/VGA characters to 8x16 EGA/VGA characters
+ *---------------------------------------------------------------------------*/
+void
+vga10_vga16(u_char *invga, u_char *outvga)
+{
+ register int i,j;
+
+ /*
+ * Keep the top and bottom scanlines the same and double every scan
+ * line in between.
+ */
+
+ outvga[0] = invga[0];
+ outvga[1] = invga[1];
+ outvga[14] = invga[8];
+ outvga[15] = invga[9];
+
+ for(i = j = 2;i < 8 && j < 14;i++,j += 2)
+ {
+ outvga[j] = invga[i];
+ outvga[j+1] = invga[i];
+ }
+}
+
+/*---------------------------------------------------------------------------*
+ * Expand 8x10 EGA/VGA characters to 8x14 EGA/VGA characters
+ *---------------------------------------------------------------------------*/
+void
+vga10_vga14(u_char *invga, u_char *outvga)
+{
+ register int i;
+
+ /*
+ * Double the top two and bottom two scanlines and copy everything
+ * in between.
+ */
+
+ outvga[0] = invga[0];
+ outvga[1] = invga[0];
+ outvga[2] = invga[1];
+ outvga[3] = invga[1];
+ outvga[10] = invga[8];
+ outvga[11] = invga[8];
+ outvga[12] = invga[9];
+ outvga[13] = invga[9];
+
+ for(i = 2;i < 8;i++)
+ outvga[i+2] = invga[i];
+}
+
+/*---------------------------------------------------------------------------*
+ * Expand 8x10 EGA/VGA characters to 8x10 EGA/VGA characters
+ *---------------------------------------------------------------------------*/
+void
+vga10_vga10(u_char *invga, u_char *outvga)
+{
+ register int i;
+
+ for(i = 0;i < 10;i++)
+ outvga[i] = invga[i];
+}
+
+/*---------------------------------------------------------------------------*
+ * Contract 8x10 EGA/VGA characters to 8x8 EGA/VGA characters
+ *---------------------------------------------------------------------------*/
+void
+vga10_vga8(u_char *invga, u_char *outvga)
+{
+ /* Skip scanlines 3 and 7 */
+
+ outvga[0] = invga[0];
+ outvga[1] = invga[1];
+ outvga[2] = invga[2];
+ outvga[3] = invga[4];
+ outvga[4] = invga[5];
+ outvga[5] = invga[6];
+ outvga[6] = invga[8];
+ outvga[7] = invga[9];
+}
+
+/*---------------------------------------------------------------------------*
+ * force a vga card to behave like an ega for debugging
+ *---------------------------------------------------------------------------*/
+#if FORCE_EGA
+void
+force_ega(void)
+{
+ unsigned char vgareg;
+
+ if(adaptor_type == VGA_ADAPTOR)
+ {
+ adaptor_type = EGA_ADAPTOR;
+ totalfonts = 4;
+ vgareg = inb(GN_MISCOUTR); /* Miscellaneous Output Register */
+ vgareg |= 128; /* Set 350 scanline mode */
+ vgareg &= ~64;
+ outb(GN_MISCOUTW,vgareg);
+ }
+}
+#endif /* FORCE_EGA */
+
+/*---------------------------------------------------------------------------*
+ * disconnect attribute bit 3 from generating intensity
+ * (and use it for a second character set !)
+ *---------------------------------------------------------------------------*/
+void
+set_2ndcharset(void)
+{
+ if(color) /* prepare to access index register! */
+ inb(GN_INPSTAT1C);
+ else
+ inb(GN_INPSTAT1M);
+
+ /* select color plane enable reg, caution: set ATC access bit ! */
+
+ outb(ATC_INDEX, (ATC_COLPLEN | ATC_ACCESS));
+ outb(ATC_DATAW, 0x07); /* disable plane 3 */
+}
+
+#if PCVT_SCREENSAVER
+#if PCVT_PRETTYSCRNS
+
+/*---------------------------------------------------------------------------*
+ * produce some kinda random number, had a look into the system library...
+ *---------------------------------------------------------------------------*/
+static u_short
+getrand(void)
+{
+#if !PCVT_FREEBSD
+ extern struct timeval time; /* time-of-day register */
+#endif
+ static unsigned long seed = 1;
+ register u_short res = (u_short)seed;
+ seed = seed * 1103515245L + time.tv_sec;
+ return res;
+}
+
+/*---------------------------------------------------------------------------*
+ * produce "nice" screensaving ....
+ *---------------------------------------------------------------------------*/
+static void
+scrnsv_blink(void)
+{
+ static struct rgb blink_rgb[8] =
+ {
+ {63, 63, 63}, /* white */
+ {0, 63, 42}, /* pale green */
+ {63, 63, 0}, /* yellow */
+ {63, 21, 63}, /* violet */
+ {42, 63, 0}, /* yellow-green */
+ {63, 42, 0}, /* amber */
+ {63, 42, 42}, /* rose */
+ {21, 42, 42} /* cyan */
+ };
+ register u_short r = getrand();
+ unsigned pos = (r % (scrnsv_size / 2));
+
+ *scrnsv_current = /* (0 << 8) + */ ' ';
+ scrnsv_current = vsp->Crtat + pos;
+ *scrnsv_current = (7 /* LIGHTGRAY */ << 8) + '*';
+ if(adaptor_type == VGA_ADAPTOR)
+ vgapaletteio(7 /* LIGHTGRAY */, &blink_rgb[(r >> 4) & 7], 1);
+ timeout((TIMEOUT_FUNC_T)scrnsv_blink, NULL, hz);
+}
+
+#endif /* PCVT_PRETTYSCRNS */
+
+/*---------------------------------------------------------------------------*
+ * set timeout time
+ *---------------------------------------------------------------------------*/
+void
+pcvt_set_scrnsv_tmo(int timeout)
+{
+ int x = splhigh();
+
+ if(scrnsv_timeout)
+ untimeout((TIMEOUT_FUNC_T)scrnsv_timedout, NULL);
+
+ scrnsv_timeout = timeout;
+ pcvt_scrnsv_reset(); /* sanity */
+ splx(x);
+ if(timeout == 0 && savedscreen)
+ {
+ /* release buffer when screen saver turned off */
+ free(savedscreen, M_TEMP);
+ savedscreen = (u_short *)0;
+ }
+}
+
+/*---------------------------------------------------------------------------*
+ * we were timed out
+ *---------------------------------------------------------------------------*/
+static void
+scrnsv_timedout(void *arg)
+{
+ /* this function is called by timeout() */
+ /* raise priority to avoid conflicts with kbd intr */
+ int x = spltty();
+
+ /*
+ * due to some undefined problems with video adaptor RAM
+ * access timing, the following has been splitted into
+ * two pieces called subsequently with a time difference
+ * of 100 millisec
+ */
+
+ if(++scrnsv_active == 1)
+ {
+ register size_t s;
+ /*
+ * first, allocate a buffer
+ * do only if none allocated yet or another size required
+ * this reduces malloc() overhead by avoiding successive
+ * calls to malloc() and free() if they would have requested
+ * the same buffer
+ *
+ * XXX This is inherited from old days where no buffering
+ * happened at all. Meanwhile we should use the standard
+ * screen buffer instead. Any volunteers? :-) [At least,
+ * this code proved to work...]
+ */
+
+ s = sizeof(u_short) * vsp->screen_rowsize * vsp->maxcol;
+
+ if(savedscreen == (u_short *)0 || s != scrnsv_size)
+ {
+ /* really need to allocate */
+ if(savedscreen)
+ free(savedscreen, M_TEMP);
+ scrnsv_size = s;
+ if((savedscreen =
+ (u_short *)malloc(s, M_TEMP, M_NOWAIT))
+ == (u_short *)0)
+ {
+ /*
+ * didn't get the buffer memory,
+ * turn off screen saver
+ */
+ scrnsv_timeout = scrnsv_active = 0;
+ splx(x);
+ return;
+ }
+ }
+ /* save current screen */
+ bcopy(vsp->Crtat, savedscreen, scrnsv_size);
+
+ /* on VGA's, make sure palette is set to blank screen */
+ if(adaptor_type == VGA_ADAPTOR)
+ {
+ struct rgb black = {0, 0, 0};
+ vgapaletteio(0 /* BLACK */, &black, 1);
+ }
+ /* prepare for next time... */
+ timeout((TIMEOUT_FUNC_T)scrnsv_timedout /* me! */,
+ NULL, hz / 10);
+ }
+ else
+ {
+ /* second call, now blank the screen */
+ /* fill screen with blanks */
+ fillw(/* (BLACK<<8) + */ ' ', vsp->Crtat, scrnsv_size / 2);
+
+#if PCVT_PRETTYSCRNS
+ scrnsv_current = vsp->Crtat;
+ timeout((TIMEOUT_FUNC_T)scrnsv_blink, NULL, hz);
+#endif /* PCVT_PRETTYSCRNS */
+
+ sw_cursor(0); /* cursor off on mda/cga */
+ }
+ splx(x);
+}
+
+/*---------------------------------------------------------------------------*
+ * interface to screensaver "subsystem"
+ *---------------------------------------------------------------------------*/
+void
+pcvt_scrnsv_reset(void)
+{
+ /*
+ * to save lotta time with superfluous timeout()/untimeout() calls
+ * when having massive output operations, we remember the last
+ * second of kernel timer we've rescheduled scrnsv_timedout()
+ */
+ static long last_schedule = 0L;
+ register int x = splhigh();
+ int reschedule = 0;
+
+ if((scrnsv_active == 1 || scrnsv_timeout) &&
+ last_schedule != time.tv_sec)
+ {
+ last_schedule = time.tv_sec;
+ reschedule = 1;
+ untimeout((TIMEOUT_FUNC_T)scrnsv_timedout, NULL);
+ }
+ if(scrnsv_active)
+ {
+
+#if PCVT_PRETTYSCRNS
+ if(scrnsv_active > 1)
+ untimeout((TIMEOUT_FUNC_T)scrnsv_blink, NULL);
+#endif /* PCVT_PRETTYSCRNS */
+
+ bcopy(savedscreen, vsp->Crtat, scrnsv_size);
+ if(adaptor_type == VGA_ADAPTOR)
+ {
+ /* back up VGA palette info */
+ vgapaletteio(0 /* BLACK */, &vsp->palette[0], 1);
+
+#if PCVT_PRETTYSCRNS
+ vgapaletteio(7 /* LIGHTGRAY */, &vsp->palette[7], 1);
+#endif /* PCVT_PRETTYSCRNS */
+
+ }
+ scrnsv_active = 0;
+
+ if(vsp->cursor_on)
+ sw_cursor(1); /* cursor on */
+ }
+
+ if(reschedule)
+ {
+ /* mark next timeout */
+ timeout((TIMEOUT_FUNC_T)scrnsv_timedout, NULL,
+ scrnsv_timeout * hz);
+ }
+ splx(x);
+}
+
+#endif /* PCVT_SCREENSAVER */
+
+/*---------------------------------------------------------------------------*
+ * switch cursor on/off
+ *---------------------------------------------------------------------------*/
+void
+sw_cursor(int onoff)
+{
+ if(adaptor_type == EGA_ADAPTOR)
+ {
+ int start, end;
+ if(onoff)
+ {
+ start = vsp->cursor_start;
+ end = vsp->cursor_end;
+ }
+ else
+ {
+ int cs = vs[current_video_screen].vga_charset;
+
+ cs = (cs < 0) ? 0 : ((cs < totalfonts) ?
+ cs : totalfonts-1);
+
+ start = (vgacs[cs].char_scanlines & 0x1F) + 1;
+ end = 0;
+ }
+ outb(addr_6845,CRTC_CURSTART); /* cursor start reg */
+ outb(addr_6845+1, start);
+ outb(addr_6845,CRTC_CUREND); /* cursor end reg */
+ outb(addr_6845+1, end);
+ }
+ else /* mda, cga, vga */
+ {
+ outb(addr_6845,CRTC_CURSTART); /* cursor start reg */
+ if(onoff)
+ outb(addr_6845+1, vsp->cursor_start);
+ else
+ outb(addr_6845+1, CURSOR_ON_BIT);
+ }
+}
+
+/*---------------------------------------------------------------------------*
+ * cold init support, if a mono monitor is attached to a
+ * vga or ega, it comes up with a mda emulation. switch
+ * board to generic ega/vga mode in this case.
+ *---------------------------------------------------------------------------*/
+void
+mda2egaorvga(void)
+{
+ /*
+ * program sequencer to access
+ * video ram
+ */
+
+ /* synchronous reset */
+ outb(TS_INDEX, TS_SYNCRESET);
+ outb(TS_DATA, 0x01);
+
+ /* write to map 0 & 1 */
+ outb(TS_INDEX, TS_WRPLMASK);
+ outb(TS_DATA, 0x03);
+
+ /* odd-even addressing */
+ outb(TS_INDEX, TS_MEMMODE);
+ outb(TS_DATA, 0x03);
+
+ /* clear synchronous reset */
+ outb(TS_INDEX, TS_SYNCRESET);
+ outb(TS_DATA, 0x03);
+
+ /*
+ * program graphics controller
+ * to access character
+ * generator
+ */
+
+ /* select map 0 for cpu reads */
+ outb(GDC_INDEX, GDC_RDPLANESEL);
+ outb(GDC_DATA, 0x00);
+
+ /* enable odd-even addressing */
+ outb(GDC_INDEX, GDC_MODE);
+ outb(GDC_DATA, 0x10);
+
+ /* map starts at 0xb000 */
+ outb(GDC_INDEX, GDC_MISC);
+ outb(GDC_DATA, 0x0a);
+}
+
+#endif /* NVT > 0 */
+
+/* ------------------------- E O F ------------------------------------------*/
diff --git a/sys/arch/i386/isa/pcvt/pcvt_tbl.h b/sys/arch/i386/isa/pcvt/pcvt_tbl.h
new file mode 100644
index 00000000000..3635c19bab3
--- /dev/null
+++ b/sys/arch/i386/isa/pcvt/pcvt_tbl.h
@@ -0,0 +1,476 @@
+/*
+ * Copyright (c) 1992, 1995 Hellmuth Michaelis.
+ *
+ * All rights reserved.
+ *
+ * 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 Hellmuth Michaelis
+ * 4. The name authors may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``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 AUTHORS 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.
+ *
+ *
+ * @(#)pcvt_tbl.h, 3.32, Last Edit-Date: [Tue Oct 3 11:19:49 1995]
+ *
+ */
+
+/*---------------------------------------------------------------------------*
+ *
+ * pcvt_tbl.h VT220 Driver Character Set Conversion Tables
+ * ------------------------------------------------------------
+ * -hm splitting off pccons_out.c
+ * -hm default tables for pure mda/hcg/cga
+ * -hm ---------------- Release 3.32 -----------------------
+ *
+ * in pcvt_out.c, hooks are provided for the following charactersets:
+ *
+ * HAVECS_BRITISH
+ * HAVECS_ASCII
+ * HAVECS_FINNISH
+ * HAVECS_NORWEGIANDANISH
+ * HAVECS_SWEDISH
+ * HAVECS_GERMAN
+ * HAVECS_FRENCHCANADA
+ * HAVECS_FRENCH
+ * HAVECS_ITALIAN
+ * HAVECS_SPANISH
+ * HAVECS_SPECIAL
+ * HAVECS_ALTERNATEROM1
+ * HAVECS_ALTERNATEROM2
+ * HAVECS_ROMAN8
+ * HAVECS_DUTCH
+ * HAVECS_SUPPLEMENTAL
+ * HAVECS_SWISS
+ * HAVECS_TECHNICAL
+ * HAVECS_ISOLATIN
+ *
+ * to add support for a new charcterset, you have to provide the
+ * table named "cs_<charset>",define the according "HAVECS_<CHARSET>"
+ * and recompile everything. ref: pcvt_out.c, vt_designate()
+ *
+ *---------------------------------------------------------------------------*/
+
+/*===========================================================================*
+ * DEFAULT TABLES FOR MDA/HCG/CGA
+ *===========================================================================*/
+
+/*---------------------------------------------------------------------------*
+ * ASCII Characterset
+ *---------------------------------------------------------------------------*/
+#define HAVECSD_ASCII
+u_short csd_ascii[CSSIZE] = {
+/* 20 */ 0x20 | CSL, 0x21 | CSL, 0x22 | CSL, 0x23 | CSL,
+/* 24 */ 0x24 | CSL, 0x25 | CSL, 0x26 | CSL, 0x27 | CSL,
+/* 28 */ 0x28 | CSL, 0x29 | CSL, 0x2A | CSL, 0x2B | CSL,
+/* 2C */ 0x2C | CSL, 0x2D | CSL, 0x2E | CSL, 0x2F | CSL,
+
+/* 30 */ 0x30 | CSL, 0x31 | CSL, 0x32 | CSL, 0x33 | CSL,
+/* 34 */ 0x34 | CSL, 0x35 | CSL, 0x36 | CSL, 0x37 | CSL,
+/* 38 */ 0x38 | CSL, 0x39 | CSL, 0x3A | CSL, 0x3B | CSL,
+/* 3C */ 0x3C | CSL, 0x3D | CSL, 0x3E | CSL, 0x3F | CSL,
+
+/* 40 */ 0x40 | CSL, 0x41 | CSL, 0x42 | CSL, 0x43 | CSL,
+/* 44 */ 0x44 | CSL, 0x45 | CSL, 0x46 | CSL, 0x47 | CSL,
+/* 48 */ 0x48 | CSL, 0x49 | CSL, 0x4A | CSL, 0x4B | CSL,
+/* 4C */ 0x4C | CSL, 0x4D | CSL, 0x4E | CSL, 0x4F | CSL,
+
+/* 50 */ 0x50 | CSL, 0x51 | CSL, 0x52 | CSL, 0x53 | CSL,
+/* 54 */ 0x54 | CSL, 0x55 | CSL, 0x56 | CSL, 0x57 | CSL,
+/* 58 */ 0x58 | CSL, 0x59 | CSL, 0x5A | CSL, 0x5B | CSL,
+/* 5C */ 0x5C | CSL, 0x5D | CSL, 0x5E | CSL, 0x5F | CSL,
+
+/* 60 */ 0x60 | CSL, 0x61 | CSL, 0x62 | CSL, 0x63 | CSL,
+/* 64 */ 0x64 | CSL, 0x65 | CSL, 0x66 | CSL, 0x67 | CSL,
+/* 68 */ 0x68 | CSL, 0x69 | CSL, 0x6A | CSL, 0x6B | CSL,
+/* 6C */ 0x6C | CSL, 0x6D | CSL, 0x6E | CSL, 0x6F | CSL,
+
+/* 70 */ 0x70 | CSL, 0x71 | CSL, 0x72 | CSL, 0x73 | CSL,
+/* 74 */ 0x74 | CSL, 0x75 | CSL, 0x76 | CSL, 0x77 | CSL,
+/* 78 */ 0x78 | CSL, 0x79 | CSL, 0x7A | CSL, 0x7B | CSL,
+/* 7C */ 0x7C | CSL, 0x7D | CSL, 0x7E | CSL, 0x7F | CSL,
+};
+
+/*---------------------------------------------------------------------------*
+ * DEC Supplemental Graphic Characterset
+ *---------------------------------------------------------------------------*/
+#define HAVECSD_SUPPLEMENTAL
+u_short csd_supplemental[CSSIZE] = {
+/* 20 */ 0x20 | CSL, 0xAD | CSL, 0x9B | CSL, 0x9C | CSL,
+/* 24 */ 0x20 | CSL, 0x9D | CSL, 0x20 | CSL, 0x20 | CSL,
+/* 28 */ 0x20 | CSL, 0x20 | CSL, 0xA6 | CSL, 0xAE | CSL,
+/* 2C */ 0x20 | CSL, 0x20 | CSL, 0x20 | CSL, 0x20 | CSL,
+
+/* 30 */ 0xF8 | CSL, 0xF1 | CSL, 0xFD | CSL, 0x20 | CSL,
+/* 34 */ 0x20 | CSL, 0xE6 | CSL, 0x20 | CSL, 0x20 | CSL,
+/* 38 */ 0x20 | CSL, 0x20 | CSL, 0xA7 | CSL, 0xAF | CSL,
+/* 3C */ 0xAC | CSL, 0xAB | CSL, 0x20 | CSL, 0xA8 | CSL,
+
+/* 40 */ 0x20 | CSL, 0x20 | CSL, 0x20 | CSL, 0x20 | CSL,
+/* 44 */ 0x8E | CSL, 0x8F | CSL, 0x92 | CSL, 0x80 | CSL,
+/* 48 */ 0x20 | CSL, 0x90 | CSL, 0x20 | CSL, 0x20 | CSL,
+/* 4C */ 0x8D | CSL, 0xA1 | CSL, 0x8C | CSL, 0x8B | CSL,
+
+/* 50 */ 0x20 | CSL, 0xA5 | CSL, 0x20 | CSL, 0x20 | CSL,
+/* 54 */ 0x20 | CSL, 0x20 | CSL, 0x99 | CSL, 0x20 | CSL,
+/* 58 */ 0x20 | CSL, 0x20 | CSL, 0x20 | CSL, 0x20 | CSL,
+/* 5C */ 0x9A | CSL, 0x20 | CSL, 0x20 | CSL, 0xE1 | CSL,
+
+/* 60 */ 0x85 | CSL, 0xA0 | CSL, 0x83 | CSL, 0x20 | CSL,
+/* 64 */ 0x84 | CSL, 0x86 | CSL, 0x91 | CSL, 0x87 | CSL,
+/* 68 */ 0x8A | CSL, 0x82 | CSL, 0x88 | CSL, 0x89 | CSL,
+/* 6C */ 0x8D | CSL, 0xA1 | CSL, 0x8C | CSL, 0x8B | CSL,
+
+/* 70 */ 0x20 | CSL, 0xA4 | CSL, 0x95 | CSL, 0xA2 | CSL,
+/* 74 */ 0x93 | CSL, 0x20 | CSL, 0x94 | CSL, 0x20 | CSL,
+/* 78 */ 0x20 | CSL, 0x97 | CSL, 0xA3 | CSL, 0x96 | CSL,
+/* 7C */ 0x81 | CSL, 0x98 | CSL, 0x20 | CSL, 0x20 | CSL
+};
+
+/*---------------------------------------------------------------------------*
+ * DEC Special Graphic Characterset
+ *---------------------------------------------------------------------------*/
+#define HAVECSD_SPECIAL
+u_short csd_special[CSSIZE] = {
+/* 20 */ 0x20 | CSL, 0x21 | CSL, 0x22 | CSL, 0x23 | CSL,
+/* 24 */ 0x24 | CSL, 0x25 | CSL, 0x26 | CSL, 0x27 | CSL,
+/* 28 */ 0x28 | CSL, 0x29 | CSL, 0x2A | CSL, 0x2B | CSL,
+/* 2C */ 0x2C | CSL, 0x2D | CSL, 0x2E | CSL, 0x2F | CSL,
+
+/* 30 */ 0x30 | CSL, 0x31 | CSL, 0x32 | CSL, 0x33 | CSL,
+/* 34 */ 0x34 | CSL, 0x35 | CSL, 0x36 | CSL, 0x37 | CSL,
+/* 38 */ 0x38 | CSL, 0x39 | CSL, 0x3A | CSL, 0x3B | CSL,
+/* 3C */ 0x3C | CSL, 0x3D | CSL, 0x3E | CSL, 0x3F | CSL,
+
+/* 40 */ 0x40 | CSL, 0x41 | CSL, 0x42 | CSL, 0x43 | CSL,
+/* 44 */ 0x44 | CSL, 0x45 | CSL, 0x46 | CSL, 0x47 | CSL,
+/* 48 */ 0x48 | CSL, 0x49 | CSL, 0x4A | CSL, 0x4B | CSL,
+/* 4C */ 0x4C | CSL, 0x4D | CSL, 0x4E | CSL, 0x4F | CSL,
+
+/* 50 */ 0x50 | CSL, 0x51 | CSL, 0x52 | CSL, 0x53 | CSL,
+/* 54 */ 0x54 | CSL, 0x55 | CSL, 0x56 | CSL, 0x57 | CSL,
+/* 58 */ 0x58 | CSL, 0x59 | CSL, 0x5A | CSL, 0x5B | CSL,
+/* 5C */ 0x5C | CSL, 0x5D | CSL, 0x5E | CSL, 0x20 | CSL,
+
+/* 60 */ 0x20 | CSL, 0xB0 | CSL, 0x20 | CSL, 0x20 | CSL,
+/* 64 */ 0x20 | CSL, 0x20 | CSL, 0xF8 | CSL, 0xF1 | CSL,
+/* 68 */ 0x20 | CSL, 0x20 | CSL, 0xD9 | CSL, 0xBF | CSL,
+/* 6C */ 0xDA | CSL, 0xC0 | CSL, 0xC5 | CSL, 0x20 | CSL,
+
+/* 70 */ 0x20 | CSL, 0xC4 | CSL, 0x20 | CSL, 0x20 | CSL,
+/* 74 */ 0xC3 | CSL, 0xB4 | CSL, 0xC1 | CSL, 0xC2 | CSL,
+/* 78 */ 0xB3 | CSL, 0xF3 | CSL, 0xF2 | CSL, 0xE3 | CSL,
+/* 7C */ 0x20 | CSL, 0x9C | CSL, 0x20 | CSL, 0x20 | CSL
+};
+
+/*---------------------------------------------------------------------------*
+ * DEC Technical Characterset
+ *---------------------------------------------------------------------------*/
+#define HAVECSD_TECHNICAL
+u_short csd_technical[CSSIZE] = {
+/* 20 */ 0xFE | CSH, 0xFB | CSL, 0xDA | CSL, 0xC4 | CSL,
+/* 24 */ 0xF4 | CSL, 0xF5 | CSL, 0xB3 | CSL, 0xDA | CSL,
+/* 28 */ 0xC0 | CSL, 0xBF | CSL, 0xD9 | CSL, 0x20 | CSL,
+/* 2C */ 0x20 | CSL, 0x20 | CSL, 0x20 | CSL, 0x20 | CSL,
+
+/* 30 */ 0x20 | CSL, 0x20 | CSL, 0x20 | CSL, 0x20 | CSL,
+/* 34 */ 0x20 | CSL, 0xAA | CSL, 0xA9 | CSL, 0x3E | CSL,
+/* 38 */ 0x20 | CSL, 0x20 | CSL, 0x20 | CSL, 0x20 | CSL,
+/* 3C */ 0xF3 | CSL, 0x20 | CSL, 0xF2 | CSL, 0x20 | CSL,
+
+/* 40 */ 0x20 | CSL, 0x20 | CSL, 0xEC | CSL, 0xF6 | CSL,
+/* 44 */ 0x20 | CSL, 0x20 | CSL, 0xE8 | CSL, 0xE2 | CSL,
+/* 48 */ 0x20 | CSL, 0xF7 | CSL, 0xE9 | CSL, 0x78 | CSL,
+/* 4C */ 0x20 | CSL, 0x20 | CSL, 0x20 | CSL, 0xF0 | CSL,
+
+/* 50 */ 0x20 | CSL, 0x20 | CSL, 0x20 | CSL, 0xE4 | CSL,
+/* 54 */ 0x20 | CSL, 0x20 | CSL, 0xFB | CSL, 0xEA | CSL,
+/* 58 */ 0x20 | CSL, 0x20 | CSL, 0x20 | CSL, 0x20 | CSL,
+/* 5C */ 0xEF | CSL, 0x20 | CSL, 0x20 | CSL, 0x20 | CSL,
+
+/* 60 */ 0xAA | CSL, 0xE0 | CSL, 0xE1 | CSL, 0x20 | CSL,
+/* 64 */ 0xEB | CSL, 0x20 | CSL, 0xED | CSL, 0x59 | CSL,
+/* 68 */ 0x20 | CSL, 0x20 | CSL, 0xE9 | CSL, 0x20 | CSL,
+/* 6C */ 0x20 | CSL, 0x20 | CSL, 0x20 | CSL, 0x20 | CSL,
+
+/* 70 */ 0xE3 | CSL, 0x20 | CSL, 0x20 | CSL, 0xE5 | CSL,
+/* 74 */ 0xE7 | CSL, 0x20 | CSL, 0x9F | CSL, 0x20 | CSL,
+/* 78 */ 0x20 | CSL, 0x20 | CSL, 0x20 | CSL, 0x20 | CSL,
+/* 7C */ 0x20 | CSL, 0x20 | CSL, 0x20 | CSL, 0x20 | CSL
+};
+
+/*---------------------------------------------------------------------------*
+ * ISO Latin-1 Characterset
+ *---------------------------------------------------------------------------*/
+#define HAVECSD_ISOLATIN
+u_short csd_isolatin[CSSIZE] = {
+/* 20 */ 0x20 | CSL, 0xAD | CSL, 0x9B | CSL, 0x9C | CSL,
+/* 24 */ 0x20 | CSL, 0x9D | CSL, 0x7C | CSL, 0x20 | CSL,
+/* 28 */ 0x22 | CSL, 0x20 | CSL, 0xA6 | CSL, 0xAE | CSL,
+/* 2C */ 0xAA | CSL, 0x2D | CSL, 0x20 | CSL, 0x2D | CSL,
+
+/* 30 */ 0xF8 | CSL, 0xF1 | CSL, 0xFD | CSL, 0x20 | CSL,
+/* 34 */ 0x27 | CSL, 0xE6 | CSL, 0x20 | CSL, 0x20 | CSL,
+/* 38 */ 0x20 | CSL, 0x20 | CSL, 0xA7 | CSL, 0xAF | CSL,
+/* 3C */ 0xAC | CSL, 0xAB | CSL, 0x20 | CSL, 0xA8 | CSL,
+
+/* 40 */ 0x20 | CSL, 0x20 | CSL, 0x20 | CSL, 0x20 | CSL,
+/* 44 */ 0x8E | CSL, 0x8F | CSL, 0x92 | CSL, 0x80 | CSL,
+/* 48 */ 0x20 | CSL, 0x90 | CSL, 0x20 | CSL, 0x20 | CSL,
+/* 4C */ 0x8D | CSL, 0xA1 | CSL, 0x8C | CSL, 0x8B | CSL,
+
+/* 50 */ 0x20 | CSL, 0xA5 | CSL, 0x20 | CSL, 0x20 | CSL,
+/* 54 */ 0x20 | CSL, 0x20 | CSL, 0x99 | CSL, 0x78 | CSL,
+/* 58 */ 0x20 | CSL, 0x20 | CSL, 0x20 | CSL, 0x20 | CSL,
+/* 5C */ 0x9A | CSL, 0x20 | CSL, 0x20 | CSL, 0xE1 | CSL,
+
+/* 60 */ 0x85 | CSL, 0xA0 | CSL, 0x83 | CSL, 0x20 | CSL,
+/* 64 */ 0x84 | CSL, 0x86 | CSL, 0x91 | CSL, 0x87 | CSL,
+/* 68 */ 0x8A | CSL, 0x82 | CSL, 0x88 | CSL, 0x89 | CSL,
+/* 6C */ 0x8D | CSL, 0xA1 | CSL, 0x8C | CSL, 0x8B | CSL,
+
+/* 70 */ 0x20 | CSL, 0xA4 | CSL, 0x95 | CSL, 0xA2 | CSL,
+/* 74 */ 0x93 | CSL, 0x20 | CSL, 0x94 | CSL, 0xF6 | CSL,
+/* 78 */ 0x20 | CSL, 0x97 | CSL, 0xA3 | CSL, 0x96 | CSL,
+/* 7C */ 0x81 | CSL, 0x20 | CSL, 0x20 | CSL, 0x98 | CSL
+};
+
+/*===========================================================================*
+ * EXTENDED TABLES FOR EGA/VGA
+ *===========================================================================*/
+
+/*---------------------------------------------------------------------------*
+ * ASCII Characterset
+ *---------------------------------------------------------------------------*/
+#define HAVECSE_ASCII
+u_short cse_ascii[CSSIZE] = {
+/* 20 */ 0x20 | CSL, 0x21 | CSL, 0x22 | CSL, 0x23 | CSL,
+/* 24 */ 0x24 | CSL, 0x25 | CSL, 0x26 | CSL, 0x27 | CSL,
+/* 28 */ 0x28 | CSL, 0x29 | CSL, 0x2A | CSL, 0x2B | CSL,
+/* 2C */ 0x2C | CSL, 0x2D | CSL, 0x2E | CSL, 0x2F | CSL,
+
+/* 30 */ 0x30 | CSL, 0x31 | CSL, 0x32 | CSL, 0x33 | CSL,
+/* 34 */ 0x34 | CSL, 0x35 | CSL, 0x36 | CSL, 0x37 | CSL,
+/* 38 */ 0x38 | CSL, 0x39 | CSL, 0x3A | CSL, 0x3B | CSL,
+/* 3C */ 0x3C | CSL, 0x3D | CSL, 0x3E | CSL, 0x3F | CSL,
+
+/* 40 */ 0x40 | CSL, 0x41 | CSL, 0x42 | CSL, 0x43 | CSL,
+/* 44 */ 0x44 | CSL, 0x45 | CSL, 0x46 | CSL, 0x47 | CSL,
+/* 48 */ 0x48 | CSL, 0x49 | CSL, 0x4A | CSL, 0x4B | CSL,
+/* 4C */ 0x4C | CSL, 0x4D | CSL, 0x4E | CSL, 0x4F | CSL,
+
+/* 50 */ 0x50 | CSL, 0x51 | CSL, 0x52 | CSL, 0x53 | CSL,
+/* 54 */ 0x54 | CSL, 0x55 | CSL, 0x56 | CSL, 0x57 | CSL,
+/* 58 */ 0x58 | CSL, 0x59 | CSL, 0x5A | CSL, 0x5B | CSL,
+/* 5C */ 0x5C | CSL, 0x5D | CSL, 0x5E | CSL, 0x5F | CSL,
+
+/* 60 */ 0x60 | CSL, 0x61 | CSL, 0x62 | CSL, 0x63 | CSL,
+/* 64 */ 0x64 | CSL, 0x65 | CSL, 0x66 | CSL, 0x67 | CSL,
+/* 68 */ 0x68 | CSL, 0x69 | CSL, 0x6A | CSL, 0x6B | CSL,
+/* 6C */ 0x6C | CSL, 0x6D | CSL, 0x6E | CSL, 0x6F | CSL,
+
+/* 70 */ 0x70 | CSL, 0x71 | CSL, 0x72 | CSL, 0x73 | CSL,
+/* 74 */ 0x74 | CSL, 0x75 | CSL, 0x76 | CSL, 0x77 | CSL,
+/* 78 */ 0x78 | CSL, 0x79 | CSL, 0x7A | CSL, 0x7B | CSL,
+/* 7C */ 0x7C | CSL, 0x7D | CSL, 0x7E | CSL, 0xB0 | CSL,
+};
+
+/*---------------------------------------------------------------------------*
+ * DEC Supplemental Graphic Characterset
+ *---------------------------------------------------------------------------*/
+#define HAVECSE_SUPPLEMENTAL
+u_short cse_supplemental[CSSIZE] = {
+/* 20 */ 0x20 | CSL, 0xAD | CSL, 0x9B | CSL, 0x9C | CSL,
+/* 24 */ 0x9F | CSH, 0x67 | CSH, 0x9F | CSH, 0x15 | CSL,
+/* 28 */ 0x9D | CSH, 0x9C | CSH, 0xA6 | CSL, 0xAE | CSL,
+/* 2C */ 0x9F | CSH, 0x9F | CSH, 0x9F | CSH, 0x9F | CSH,
+
+/* 30 */ 0xF8 | CSL, 0xF1 | CSL, 0xFD | CSL, 0x9B | CSH,
+/* 34 */ 0x9F | CSH, 0xE6 | CSL, 0x14 | CSL, 0x99 | CSH,
+/* 38 */ 0x9F | CSH, 0x98 | CSH, 0xA7 | CSL, 0xAF | CSL,
+/* 3C */ 0xAC | CSL, 0xAB | CSL, 0x9F | CSH, 0xA8 | CSL,
+
+/* 40 */ 0x97 | CSH, 0x96 | CSH, 0x95 | CSH, 0x94 | CSH,
+/* 44 */ 0x8E | CSL, 0x8F | CSL, 0x92 | CSL, 0x80 | CSL,
+/* 48 */ 0x93 | CSH, 0x90 | CSL, 0x92 | CSH, 0x91 | CSH,
+/* 4C */ 0x90 | CSH, 0x8F | CSH, 0x8E | CSH, 0x8D | CSH,
+
+/* 50 */ 0x9F | CSH, 0xA5 | CSL, 0x8C | CSH, 0x8B | CSH,
+/* 54 */ 0x8A | CSH, 0x89 | CSH, 0x99 | CSL, 0x88 | CSH,
+/* 58 */ 0x87 | CSH, 0x86 | CSH, 0x85 | CSH, 0x84 | CSH,
+/* 5C */ 0x9A | CSL, 0x83 | CSH, 0x9F | CSH, 0xE1 | CSL,
+
+/* 60 */ 0x85 | CSL, 0xA0 | CSL, 0x83 | CSL, 0x82 | CSH,
+/* 64 */ 0x84 | CSL, 0x86 | CSL, 0x91 | CSL, 0x87 | CSL,
+/* 68 */ 0x8A | CSL, 0x82 | CSL, 0x88 | CSL, 0x89 | CSL,
+/* 6C */ 0x8D | CSL, 0xA1 | CSL, 0x8C | CSL, 0x8B | CSL,
+
+/* 70 */ 0x9F | CSH, 0xA4 | CSL, 0x95 | CSL, 0xA2 | CSL,
+/* 74 */ 0x93 | CSL, 0x81 | CSH, 0x94 | CSL, 0x80 | CSH,
+/* 78 */ 0x7F | CSH, 0x97 | CSL, 0xA3 | CSL, 0x96 | CSL,
+/* 7C */ 0x81 | CSL, 0x98 | CSL, 0x9F | CSH, 0x20 | CSL
+};
+
+/*---------------------------------------------------------------------------*
+ * DEC Special Graphic Characterset
+ *---------------------------------------------------------------------------*/
+#define HAVECSE_SPECIAL
+u_short cse_special[CSSIZE] = {
+/* 20 */ 0x20 | CSL, 0x21 | CSL, 0x22 | CSL, 0x23 | CSL,
+/* 24 */ 0x24 | CSL, 0x25 | CSL, 0x26 | CSL, 0x27 | CSL,
+/* 28 */ 0x28 | CSL, 0x29 | CSL, 0x2A | CSL, 0x2B | CSL,
+/* 2C */ 0x2C | CSL, 0x2D | CSL, 0x2E | CSL, 0x2F | CSL,
+
+/* 30 */ 0x30 | CSL, 0x31 | CSL, 0x32 | CSL, 0x33 | CSL,
+/* 34 */ 0x34 | CSL, 0x35 | CSL, 0x36 | CSL, 0x37 | CSL,
+/* 38 */ 0x38 | CSL, 0x39 | CSL, 0x3A | CSL, 0x3B | CSL,
+/* 3C */ 0x3C | CSL, 0x3D | CSL, 0x3E | CSL, 0x3F | CSL,
+
+/* 40 */ 0x40 | CSL, 0x41 | CSL, 0x42 | CSL, 0x43 | CSL,
+/* 44 */ 0x44 | CSL, 0x45 | CSL, 0x46 | CSL, 0x47 | CSL,
+/* 48 */ 0x48 | CSL, 0x49 | CSL, 0x4A | CSL, 0x4B | CSL,
+/* 4C */ 0x4C | CSL, 0x4D | CSL, 0x4E | CSL, 0x4F | CSL,
+
+/* 50 */ 0x50 | CSL, 0x51 | CSL, 0x52 | CSL, 0x53 | CSL,
+/* 54 */ 0x54 | CSL, 0x55 | CSL, 0x56 | CSL, 0x57 | CSL,
+/* 58 */ 0x58 | CSL, 0x59 | CSL, 0x5A | CSL, 0x5B | CSL,
+/* 5C */ 0x5C | CSL, 0x5D | CSL, 0x5E | CSL, 0x20 | CSL,
+
+/* 60 */ 0x04 | CSL, 0xB0 | CSL, 0x09 | CSH, 0x0C | CSH,
+/* 64 */ 0x0D | CSH, 0x0A | CSH, 0xF8 | CSL, 0xF1 | CSL,
+/* 68 */ 0x00 | CSH, 0x0B | CSH, 0xD9 | CSL, 0xBF | CSL,
+/* 6C */ 0xDA | CSL, 0xC0 | CSL, 0xC5 | CSL, 0x7D | CSH,
+
+/* 70 */ 0x7C | CSH, 0x7B | CSH, 0x7A | CSH, 0x79 | CSH,
+/* 74 */ 0xC3 | CSL, 0xB4 | CSL, 0xC1 | CSL, 0xC2 | CSL,
+/* 78 */ 0xB3 | CSL, 0xF3 | CSL, 0xF2 | CSL, 0xE3 | CSL,
+/* 7C */ 0x78 | CSH, 0x9C | CSL, 0x99 | CSH, 0x20 | CSL
+};
+
+/*---------------------------------------------------------------------------*
+ * DEC Technical Characterset
+ *---------------------------------------------------------------------------*/
+#define HAVECSE_TECHNICAL
+u_short cse_technical[CSSIZE] = {
+/* 20 */ 0x20 | CSL, 0x65 | CSH, 0xDA | CSL, 0xC4 | CSL,
+/* 24 */ 0xF4 | CSL, 0xF5 | CSL, 0xB3 | CSL, 0xDA | CSL,
+/* 28 */ 0xC0 | CSL, 0xBF | CSL, 0xD9 | CSL, 0x61 | CSH,
+/* 2C */ 0x62 | CSH, 0x63 | CSH, 0x64 | CSH, 0x5F | CSH,
+
+/* 30 */ 0x60 | CSH, 0x5E | CSH, 0x5D | CSH, 0x5C | CSH,
+/* 34 */ 0x5B | CSH, 0xAA | CSL, 0xA9 | CSL, 0x3E | CSL,
+/* 38 */ 0x9F | CSH, 0x9F | CSH, 0x9F | CSH, 0x9F | CSH,
+/* 3C */ 0xF3 | CSL, 0x78 | CSH, 0xF2 | CSL, 0x5A | CSH,
+
+/* 40 */ 0x59 | CSH, 0x58 | CSH, 0xEC | CSL, 0xF6 | CSL,
+/* 44 */ 0x57 | CSH, 0x56 | CSH, 0xE8 | CSL, 0xE2 | CSL,
+/* 48 */ 0x77 | CSH, 0x55 | CSH, 0x54 | CSH, 0x6E | CSH,
+/* 4C */ 0x53 | CSH, 0x52 | CSH, 0x51 | CSH, 0xF0 | CSL,
+
+/* 50 */ 0x50 | CSH, 0x4F | CSH, 0x9F | CSH, 0xE4 | CSL,
+/* 54 */ 0x9F | CSH, 0x9F | CSH, 0xFB | CSL, 0xEA | CSL,
+/* 58 */ 0x4E | CSH, 0x4D | CSH, 0x4C | CSH, 0x4B | CSH,
+/* 5C */ 0xEF | CSL, 0x4A | CSH, 0x49 | CSH, 0x48 | CSH,
+
+/* 60 */ 0xAA | CSL, 0xE0 | CSL, 0xE1 | CSL, 0x47 | CSH,
+/* 64 */ 0xEB | CSL, 0x46 | CSH, 0xED | CSL, 0x59 | CSL,
+/* 68 */ 0x45 | CSH, 0x44 | CSH, 0xE9 | CSL, 0x9E | CSH,
+/* 6C */ 0x43 | CSH, 0x9F | CSH, 0x76 | CSL, 0x42 | CSH,
+
+/* 70 */ 0xE3 | CSL, 0x41 | CSH, 0x40 | CSH, 0xE5 | CSL,
+/* 74 */ 0xE7 | CSL, 0x9F | CSH, 0x9F | CSL, 0x66 | CSH,
+/* 78 */ 0x68 | CSH, 0x7E | CSH, 0x9A | CSH, 0x1B | CSL,
+/* 7C */ 0x18 | CSL, 0x1A | CSL, 0x19 | CSL, 0x20 | CSL
+};
+
+/*---------------------------------------------------------------------------*
+ * ISO Latin-1 Characterset
+ *---------------------------------------------------------------------------*/
+#define HAVECSE_ISOLATIN
+u_short cse_isolatin[CSSIZE] = {
+/* 20 */ 0x20 | CSL, 0xAD | CSL, 0x9B | CSL, 0x9C | CSL,
+/* 24 */ 0x9D | CSH, 0x9D | CSL, 0x7C | CSL, 0x15 | CSL,
+/* 28 */ 0x77 | CSH, 0x9C | CSH, 0xA6 | CSL, 0xAE | CSL,
+/* 2C */ 0x76 | CSH, 0x75 | CSH, 0x74 | CSH, 0x73 | CSH,
+
+/* 30 */ 0xF8 | CSL, 0xF1 | CSL, 0xFD | CSL, 0x9B | CSH,
+/* 34 */ 0x72 | CSH, 0xE6 | CSL, 0x14 | CSL, 0x99 | CSH,
+/* 38 */ 0x71 | CSH, 0x98 | CSH, 0xA7 | CSL, 0xAF | CSL,
+/* 3C */ 0xAC | CSL, 0xAB | CSL, 0x70 | CSH, 0xA8 | CSL,
+
+/* 40 */ 0x97 | CSH, 0x96 | CSH, 0x95 | CSH, 0x94 | CSH,
+/* 44 */ 0x8E | CSL, 0x8F | CSL, 0x92 | CSL, 0x80 | CSL,
+/* 48 */ 0x93 | CSH, 0x90 | CSL, 0x92 | CSH, 0x91 | CSH,
+/* 4C */ 0x90 | CSH, 0x8F | CSH, 0x8E | CSH, 0x8D | CSH,
+
+/* 50 */ 0x6F | CSH, 0xA5 | CSL, 0x8C | CSH, 0x8B | CSH,
+/* 54 */ 0x8A | CSH, 0x89 | CSH, 0x99 | CSL, 0x6E | CSH,
+/* 58 */ 0x87 | CSH, 0x86 | CSH, 0x85 | CSH, 0x84 | CSH,
+/* 5C */ 0x9A | CSL, 0x6D | CSH, 0x6C | CSH, 0xE1 | CSL,
+
+/* 60 */ 0x85 | CSL, 0xA0 | CSL, 0x83 | CSL, 0x82 | CSH,
+/* 64 */ 0x84 | CSL, 0x86 | CSL, 0x91 | CSL, 0x87 | CSL,
+/* 68 */ 0x8A | CSL, 0x82 | CSL, 0x88 | CSL, 0x89 | CSL,
+/* 6C */ 0x8D | CSL, 0xA1 | CSL, 0x8C | CSL, 0x8B | CSL,
+
+/* 70 */ 0x6B | CSH, 0xA4 | CSL, 0x95 | CSL, 0xA2 | CSL,
+/* 74 */ 0x93 | CSL, 0x81 | CSH, 0x94 | CSL, 0xF6 | CSL,
+/* 78 */ 0x7F | CSH, 0x97 | CSL, 0xA3 | CSL, 0x96 | CSL,
+/* 7C */ 0x81 | CSL, 0x69 | CSL, 0x6A | CSH, 0x98 | CSL
+};
+
+/*---------------------------------------------------------------------------*
+ * Downloadable Characterset
+ *---------------------------------------------------------------------------*/
+#define HAVECSE_DOWNLOADABLE
+u_short cse_downloadable[CSSIZE] = {
+/* 20 */ 0xA0 | CSH, 0xA1 | CSH, 0xA2 | CSH, 0xA3 | CSH,
+/* 24 */ 0xA4 | CSH, 0xA5 | CSH, 0xA6 | CSH, 0xA7 | CSH,
+/* 28 */ 0xA8 | CSH, 0xA9 | CSH, 0xAA | CSH, 0xAB | CSH,
+/* 2C */ 0xAC | CSH, 0xAD | CSH, 0xAE | CSH, 0xAF | CSH,
+
+/* 30 */ 0xB0 | CSH, 0xB1 | CSH, 0xB2 | CSH, 0xB3 | CSH,
+/* 34 */ 0xB4 | CSH, 0xB5 | CSH, 0xB6 | CSH, 0xB7 | CSH,
+/* 38 */ 0xB8 | CSH, 0xB9 | CSH, 0xBA | CSH, 0xBB | CSH,
+/* 3C */ 0xBC | CSH, 0xBD | CSH, 0xBE | CSH, 0xBF | CSH,
+
+/* 40 */ 0xC0 | CSH, 0xC1 | CSH, 0xC2 | CSH, 0xC3 | CSH,
+/* 44 */ 0xC4 | CSH, 0xC5 | CSH, 0xC6 | CSH, 0xC7 | CSH,
+/* 48 */ 0xC8 | CSH, 0xC9 | CSH, 0xCA | CSH, 0xCB | CSH,
+/* 4C */ 0xCC | CSH, 0xCD | CSH, 0xCE | CSH, 0xCF | CSH,
+
+/* 50 */ 0xD0 | CSH, 0xD1 | CSH, 0xD2 | CSH, 0xD3 | CSH,
+/* 54 */ 0xD4 | CSH, 0xD5 | CSH, 0xD6 | CSH, 0xD7 | CSH,
+/* 58 */ 0xD8 | CSH, 0xD9 | CSH, 0xDA | CSH, 0xDB | CSH,
+/* 5C */ 0xDC | CSH, 0xDD | CSH, 0xDE | CSH, 0xDF | CSH,
+
+/* 60 */ 0xE0 | CSH, 0xE1 | CSH, 0xE2 | CSH, 0xE3 | CSH,
+/* 64 */ 0xE4 | CSH, 0xE5 | CSH, 0xE6 | CSH, 0xE7 | CSH,
+/* 68 */ 0xE8 | CSH, 0xE9 | CSH, 0xEA | CSH, 0xEB | CSH,
+/* 6C */ 0xEC | CSH, 0xED | CSH, 0xEE | CSH, 0xEF | CSH,
+
+/* 70 */ 0xF0 | CSH, 0xF1 | CSH, 0xF2 | CSH, 0xF3 | CSH,
+/* 74 */ 0xF4 | CSH, 0xF5 | CSH, 0xF6 | CSH, 0xF7 | CSH,
+/* 78 */ 0xF8 | CSH, 0xF9 | CSH, 0xFA | CSH, 0xFB | CSH,
+/* 7C */ 0xFC | CSH, 0xFD | CSH, 0xFE | CSH, 0xFF | CSH,
+};
+
+/* ------------------------- E O F ------------------------------------------*/
diff --git a/sys/arch/i386/isa/pcvt/pcvt_vtf.c b/sys/arch/i386/isa/pcvt/pcvt_vtf.c
new file mode 100644
index 00000000000..25c8c18240f
--- /dev/null
+++ b/sys/arch/i386/isa/pcvt/pcvt_vtf.c
@@ -0,0 +1,2237 @@
+/*
+ * Copyright (c) 1992, 1995 Hellmuth Michaelis and Joerg Wunsch.
+ *
+ * Copyright (c) 1992, 1993 Brian Dunford-Shore.
+ *
+ * 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 Hellmuth Michaelis,
+ * Brian Dunford-Shore and Joerg Wunsch.
+ * 4. The name authors may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``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 AUTHORS 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.
+ *
+ *
+ * @(#)pcvt_vtf.c, 3.32, Last Edit-Date: [Tue Oct 3 11:19:49 1995]
+ *
+ */
+
+/*---------------------------------------------------------------------------*
+ *
+ * pcvt_vtf.c VT220 Terminal Emulator Functions
+ * -------------------------------------------------
+ * -hm ------------ Release 3.00 --------------
+ * -hm integrating NetBSD-current patches
+ * -hm integrating patch from Thomas Gellekum
+ * -hm fixed bug fkey labels not properly (re)set after ris
+ * -hm Michael Havemester fixed NOFASTSCROLL define bug
+ * -hm set caps/scroll/num_lock in vt_str() and made led_update()
+ * -hm applying patch from Joerg fixing Crtat bug
+ * -hm fixing NOFASTSCROLL operation for MDA/Hercules
+ * -jw/hm fixing bug in roll_up() and roll_down()
+ * -hm fastscroll/Crtat bugfix from Lon Willett
+ * -hm patch for non-XSERVER/UCONSOLE compiles from Rafal Boni
+ * -hm bugfix: PCVT_USL_COMPAT renamed to PCVT_USL_VT_COMPAT ...
+ * -hm ---------------- Release 3.30 -----------------------
+ * -hm patch from Thomas Gellekum fixes scroll region bug in vt_stbm()
+ * -hm patch from Thomas Gellekum to support C1 controls
+ * -hm patch from Thomas Gellekum re updating GL and GR
+ * -hm ---------------- Release 3.32 -----------------------
+ *
+ *---------------------------------------------------------------------------*/
+
+#include "vt.h"
+#if NVT > 0
+
+#define PCVT_INCLUDE_VT_SELATTR /* get inline function from pcvt_hdr.h */
+
+#include "pcvt_hdr.h" /* global include */
+#include "pcvt_tbl.h" /* character set conversion tables */
+
+static void clear_dld ( struct video_state *svsp );
+static void init_dld ( struct video_state *svsp );
+static void init_udk ( struct video_state *svsp );
+static void respond ( struct video_state *svsp );
+static void roll_down ( struct video_state *svsp, int n );
+static void selective_erase ( struct video_state *svsp, u_short *pcrtat,
+ int length );
+static void swcsp ( struct video_state *svsp, u_short *ctp );
+
+/*---------------------------------------------------------------------------*
+ * DECSTBM - set top and bottom margins
+ *---------------------------------------------------------------------------*/
+void
+vt_stbm(struct video_state *svsp)
+{
+ /* both 0 => scrolling region = entire screen */
+
+ if((svsp->parms[0] == 0) && (svsp->parms[1] == 0))
+ {
+ svsp->cur_offset = 0;
+ svsp->scrr_beg = 0;
+ svsp->scrr_len = svsp->screen_rows;
+ svsp->scrr_end = svsp->scrr_len - 1;
+ svsp->col = 0;
+ return;
+ }
+
+ if(svsp->parms[1] <= svsp->parms[0])
+ return;
+
+ /* range parm 1 */
+
+ if(svsp->parms[0] < 1)
+ svsp->parms[0] = 1;
+ else if(svsp->parms[0] > svsp->screen_rows-1)
+ svsp->parms[0] = svsp->screen_rows-1;
+
+ /* range parm 2 */
+
+ if(svsp->parms[1] < 2)
+ svsp->parms[1] = 2;
+ else if(svsp->parms[1] > svsp->screen_rows)
+ svsp->parms[1] = svsp->screen_rows;
+
+ svsp->scrr_beg = svsp->parms[0]-1; /* begin of scrolling region */
+ svsp->scrr_len = svsp->parms[1] - svsp->parms[0] + 1; /* no of lines */
+ svsp->scrr_end = svsp->parms[1]-1;
+
+ /* cursor to first pos */
+ if(svsp->m_om)
+ svsp->cur_offset = svsp->scrr_beg * svsp->maxcol;
+ else
+ svsp->cur_offset = 0;
+
+ svsp->abs_write = 0;
+ svsp->col = 0;
+}
+
+/*---------------------------------------------------------------------------*
+ * SGR - set graphic rendition
+ *---------------------------------------------------------------------------*/
+void
+vt_sgr(struct video_state *svsp)
+{
+ register int i = 0;
+ u_short setcolor = 0;
+ char colortouched = 0;
+
+ do
+ {
+ switch(svsp->parms[i++])
+ {
+ case 0: /* reset to normal attributes */
+ svsp->vtsgr = VT_NORMAL;
+ break;
+
+ case 1: /* bold */
+ svsp->vtsgr |= VT_BOLD;
+ break;
+
+ case 4: /* underline */
+ svsp->vtsgr |= VT_UNDER;
+ break;
+
+ case 5: /* blinking */
+ svsp->vtsgr |= VT_BLINK;
+ break;
+
+ case 7: /* reverse */
+ svsp->vtsgr |= VT_INVERSE;
+ break;
+
+ case 22: /* not bold */
+ svsp->vtsgr &= ~VT_BOLD;
+ break;
+
+ case 24: /* not underlined */
+ svsp->vtsgr &= ~VT_UNDER;
+ break;
+
+ case 25: /* not blinking */
+ svsp->vtsgr &= ~VT_BLINK;
+ break;
+
+ case 27: /* not reverse */
+ svsp->vtsgr &= ~VT_INVERSE;
+ break;
+
+ case 30: /* foreground colors */
+ case 31:
+ case 32:
+ case 33:
+ case 34:
+ case 35:
+ case 36:
+ case 37:
+ if(color)
+ {
+ colortouched = 1;
+ setcolor |= ((fgansitopc[(svsp->parms[i-1]-30) & 7]) << 8);
+ }
+ break;
+
+ case 40: /* background colors */
+ case 41:
+ case 42:
+ case 43:
+ case 44:
+ case 45:
+ case 46:
+ case 47:
+ if(color)
+ {
+ colortouched = 1;
+ setcolor |= ((bgansitopc[(svsp->parms[i-1]-40) & 7]) << 8);
+ }
+ break;
+ }
+ }
+ while(i <= svsp->parmi);
+ if(color)
+ {
+ if(colortouched)
+ svsp->c_attr = setcolor;
+ else
+ svsp->c_attr = ((sgr_tab_color[svsp->vtsgr]) << 8);
+ }
+ else
+ {
+ if(adaptor_type == MDA_ADAPTOR)
+ svsp->c_attr = ((sgr_tab_imono[svsp->vtsgr]) << 8);
+ else
+ svsp->c_attr = ((sgr_tab_mono[svsp->vtsgr]) << 8);
+ }
+}
+
+/*---------------------------------------------------------------------------*
+ * CUU - cursor up
+ *---------------------------------------------------------------------------*/
+void
+vt_cuu(struct video_state *svsp)
+{
+ register int p = svsp->parms[0];
+
+ if (p <= 0) /* parameter min */
+ p = 1;
+
+ p = min(p, svsp->row - svsp->scrr_beg);
+
+ if (p <= 0)
+ return;
+
+ svsp->cur_offset -= (svsp->maxcol * p);
+}
+
+/*---------------------------------------------------------------------------*
+ * CUD - cursor down
+ *---------------------------------------------------------------------------*/
+void
+vt_cud(struct video_state *svsp)
+{
+ register int p = svsp->parms[0];
+
+ if (p <= 0)
+ p = 1;
+
+ p = min(p, svsp->scrr_end - svsp->row);
+
+ if (p <= 0)
+ return;
+
+ svsp->cur_offset += (svsp->maxcol * p);
+}
+
+/*---------------------------------------------------------------------------*
+ * CUF - cursor forward
+ *---------------------------------------------------------------------------*/
+void
+vt_cuf(struct video_state *svsp)
+{
+ register int p = svsp->parms[0];
+
+ if(svsp->col == ((svsp->maxcol)-1)) /* already at right margin */
+ return;
+
+ if(p <= 0) /* parameter min = 1 */
+ p = 1;
+ else if(p > ((svsp->maxcol)-1)) /* parameter max = 79 */
+ p = ((svsp->maxcol)-1);
+
+ if((svsp->col + p) > ((svsp->maxcol)-1))/* not more than right margin */
+ p = ((svsp->maxcol)-1) - svsp->col;
+
+ svsp->cur_offset += p;
+ svsp->col += p;
+}
+
+/*---------------------------------------------------------------------------*
+ * CUB - cursor backward
+ *---------------------------------------------------------------------------*/
+void
+vt_cub(struct video_state *svsp)
+{
+ register int p = svsp->parms[0];
+
+ if(svsp->col == 0) /* already at left margin ? */
+ return;
+
+ if(p <= 0) /* parameter min = 1 */
+ p = 1;
+ else if(p > ((svsp->maxcol)-1)) /* parameter max = 79 */
+ p = ((svsp->maxcol)-1);
+
+ if((svsp->col - p) <= 0) /* not more than left margin */
+ p = svsp->col;
+
+ svsp->cur_offset -= p;
+ svsp->col -= p;
+}
+
+/*---------------------------------------------------------------------------*
+ * ED - erase in display
+ *---------------------------------------------------------------------------*/
+void
+vt_clreos(struct video_state *svsp)
+{
+ switch(svsp->parms[0])
+ {
+ case 0:
+ fillw(user_attr | ' ', svsp->Crtat + svsp->cur_offset,
+ svsp->Crtat +
+ (svsp->maxcol * svsp->screen_rows) -
+ (svsp->Crtat + svsp->cur_offset));
+ break;
+
+ case 1:
+ fillw(user_attr | ' ', svsp->Crtat,
+ svsp->Crtat + svsp->cur_offset -
+ svsp->Crtat + 1 );
+ break;
+
+ case 2:
+ fillw(user_attr | ' ', svsp->Crtat,
+ svsp->maxcol * svsp->screen_rows);
+ break;
+ }
+}
+
+/*---------------------------------------------------------------------------*
+ * EL - erase in line
+ *---------------------------------------------------------------------------*/
+void
+vt_clreol(struct video_state *svsp)
+{
+ switch(svsp->parms[0])
+ {
+ case 0:
+ fillw(user_attr | ' ',
+ svsp->Crtat + svsp->cur_offset,
+ svsp->maxcol-svsp->col);
+ break;
+
+ case 1:
+ fillw(user_attr | ' ',
+ svsp->Crtat + svsp->cur_offset - svsp->col,
+ svsp->col + 1);
+ break;
+
+ case 2:
+ fillw(user_attr | ' ',
+ svsp->Crtat + svsp->cur_offset - svsp->col,
+ svsp->maxcol);
+ break;
+ }
+}
+
+/*---------------------------------------------------------------------------*
+ * CUP - cursor position / HVP - horizontal & vertical position
+ *---------------------------------------------------------------------------*/
+void
+vt_curadr(struct video_state *svsp)
+{
+ if(svsp->m_om) /* relative to scrolling region */
+ {
+ if((svsp->parms[0] == 0) && (svsp->parms[1] == 0))
+ {
+ svsp->cur_offset = svsp->scrr_beg * svsp->maxcol;
+ svsp->col = 0;
+ svsp->abs_write = 0;
+ return;
+ }
+
+ if(svsp->parms[0] <= 0)
+ svsp->parms[0] = 1;
+ else if(svsp->parms[0] > svsp->scrr_len)
+ svsp->parms[0] = svsp->scrr_len;
+
+ if(svsp->parms[1] <= 0 )
+ svsp->parms[1] = 1;
+ if(svsp->parms[1] > svsp->maxcol)
+ svsp->parms[1] = svsp->maxcol;
+
+ svsp->cur_offset = (svsp->scrr_beg * svsp->maxcol) +
+ ((svsp->parms[0] - 1) * svsp->maxcol) +
+ svsp->parms[1] - 1;
+ svsp->col = svsp->parms[1] - 1;
+ svsp->abs_write = 0;
+ }
+ else /* relative to screen start */
+ {
+ if((svsp->parms[0] == 0) && (svsp->parms[1] == 0))
+ {
+ svsp->cur_offset = 0;
+ svsp->col = 0;
+ svsp->abs_write = 0;
+ return;
+ }
+
+ if(svsp->parms[0] <= 0)
+ svsp->parms[0] = 1;
+ else if(svsp->parms[0] > svsp->screen_rows)
+ svsp->parms[0] = svsp->screen_rows;
+
+ if(svsp->parms[1] <= 0 )
+ svsp->parms[1] = 1;
+ if(svsp->parms[1] > svsp->maxcol) /* col */
+ svsp->parms[1] = svsp->maxcol;
+
+ svsp->cur_offset = (((svsp->parms[0]-1)*svsp->maxcol) +
+ (svsp->parms[1]-1));
+ svsp->col = svsp->parms[1]-1;
+
+ if (svsp->cur_offset >=
+ ((svsp->scrr_beg + svsp->scrr_len + 1) * svsp->maxcol))
+
+ svsp->abs_write = 1;
+ else
+ svsp->abs_write = 0;
+ }
+}
+
+/*---------------------------------------------------------------------------*
+ * RIS - reset to initial state (hard emulator runtime reset)
+ *---------------------------------------------------------------------------*/
+void
+vt_ris(struct video_state *svsp)
+{
+ fillw(user_attr | ' ', svsp->Crtat, svsp->maxcol * svsp->screen_rows);
+ svsp->cur_offset = 0; /* cursor upper left corner */
+ svsp->col = 0;
+ svsp->row = 0;
+ svsp->lnm = 0; /* CR only */
+ clear_dld(svsp); /* clear download charset */
+ vt_clearudk(svsp); /* clear user defined keys */
+ svsp->selchar = 0; /* selective attribute off */
+ vt_str(svsp); /* and soft terminal reset */
+}
+
+/*---------------------------------------------------------------------------*
+ * DECSTR - soft terminal reset (SOFT emulator runtime reset)
+ *---------------------------------------------------------------------------*/
+void
+vt_str(struct video_state *svsp)
+{
+ int i;
+
+ clr_parms(svsp); /* escape parameter init */
+ svsp->state = STATE_INIT; /* initial state */
+
+ svsp->dis_fnc = 0; /* display functions reset */
+
+ svsp->sc_flag = 0; /* save cursor position */
+ svsp->transparent = 0; /* enable control code processing */
+ svsp->C1_ctls = 0; /* but only for C0 codes */
+ svsp->sevenbit = 0; /* data path 8 bits wide */
+
+ for(i = 0; i < MAXTAB; i++) /* setup tabstops */
+ {
+ if(!(i % 8))
+ svsp->tab_stops[i] = 1;
+ else
+ svsp->tab_stops[i] = 0;
+ }
+
+ svsp->irm = 0; /* replace mode */
+ svsp->m_om = 0; /* origin mode */
+ svsp->m_awm = 1; /* auto wrap mode */
+
+#if PCVT_INHIBIT_NUMLOCK
+ svsp->num_lock = 0; /* keypad application mode */
+#else
+ svsp->num_lock = 1; /* keypad numeric mode */
+#endif
+
+ svsp->scroll_lock = 0; /* reset keyboard modes */
+ svsp->caps_lock = 0;
+
+ svsp->ckm = 1; /* cursor key mode = "normal" ... */
+ svsp->scrr_beg = 0; /* start of scrolling region */
+ svsp->scrr_len = svsp->screen_rows; /* no. of lines in scrolling region */
+ svsp->abs_write = 0; /* scrr is complete screen */
+ svsp->scrr_end = svsp->scrr_len - 1;
+
+ if(adaptor_type == EGA_ADAPTOR || adaptor_type == VGA_ADAPTOR)
+ {
+ svsp->G0 = cse_ascii; /* G0 = ascii */
+ svsp->G1 = cse_ascii; /* G1 = ascii */
+ svsp->G2 = cse_supplemental; /* G2 = supplemental */
+ svsp->G3 = cse_supplemental; /* G3 = supplemental */
+ svsp->GL = svsp->G0; /* GL = G0 */
+ svsp->GR = svsp->G2; /* GR = G2 */
+ }
+ else
+ {
+ svsp->G0 = csd_ascii; /* G0 = ascii */
+ svsp->G1 = csd_ascii; /* G1 = ascii */
+ svsp->G2 = csd_supplemental; /* G2 = supplemental */
+ svsp->G3 = csd_supplemental; /* G3 = supplemental */
+ svsp->GL = svsp->G0; /* GL = G0 */
+ svsp->GR = svsp->G2; /* GR = G2 */
+ }
+
+ svsp->vtsgr = VT_NORMAL; /* no attributes */
+ svsp->c_attr = user_attr; /* reset sgr to normal */
+
+ svsp->selchar = 0; /* selective attribute off */
+ vt_initsel(svsp);
+
+ init_ufkl(svsp); /* init user fkey labels */
+ init_sfkl(svsp); /* init system fkey labels */
+
+ update_led(); /* update keyboard LED's */
+}
+
+/*---------------------------------------------------------------------------*
+ * RI - reverse index, move cursor up
+ *---------------------------------------------------------------------------*/
+void
+vt_ri(struct video_state *svsp)
+{
+ if(svsp->cur_offset >= ((svsp->scrr_beg * svsp->maxcol) + svsp->maxcol))
+ svsp->cur_offset -= svsp->maxcol;
+ else
+ roll_down(svsp, 1);
+}
+
+/*---------------------------------------------------------------------------*
+ * IND - index, move cursor down
+ *---------------------------------------------------------------------------*/
+void
+vt_ind(struct video_state *svsp)
+{
+ if(svsp->cur_offset < (svsp->scrr_end * svsp->maxcol))
+ svsp->cur_offset += svsp->maxcol;
+ else
+ roll_up(svsp, 1);
+}
+
+/*---------------------------------------------------------------------------*
+ * NEL - next line, first pos of next line
+ *---------------------------------------------------------------------------*/
+void
+vt_nel(struct video_state *svsp)
+{
+ if(svsp->cur_offset < (svsp->scrr_end * svsp->maxcol))
+ {
+ svsp->cur_offset += (svsp->maxcol-svsp->col);
+ svsp->col = 0;
+ }
+ else
+ {
+ roll_up(svsp, 1);
+ svsp->cur_offset -= svsp->col;
+ svsp->col = 0;
+ }
+}
+
+/*---------------------------------------------------------------------------*
+ * set dec private modes, esc [ ? x h
+ *---------------------------------------------------------------------------*/
+void
+vt_set_dec_priv_qm(struct video_state *svsp)
+{
+ switch(svsp->parms[0])
+ {
+ case 0: /* error, ignored */
+ case 1: /* CKM - cursor key mode */
+ svsp->ckm = 1;
+ break;
+
+ case 2: /* ANM - ansi/vt52 mode */
+ break;
+
+ case 3: /* COLM - column mode */
+ vt_col(svsp, SCR_COL132);
+ break;
+
+ case 4: /* SCLM - scrolling mode */
+ case 5: /* SCNM - screen mode */
+ break;
+
+ case 6: /* OM - origin mode */
+ svsp->m_om = 1;
+ break;
+
+ case 7: /* AWM - auto wrap mode */
+ svsp->m_awm = 1;
+ swritefkl(7,(u_char *)"AUTOWRAPENABLE *",svsp);
+ break;
+
+ case 8: /* ARM - auto repeat mode */
+ kbrepflag = 1;
+ break;
+
+ case 9: /* INLM - interlace mode */
+ case 10: /* EDM - edit mode */
+ case 11: /* LTM - line transmit mode */
+ case 12: /* */
+ case 13: /* SCFDM - space compression / field delimiting */
+ case 14: /* TEM - transmit execution mode */
+ case 15: /* */
+ case 16: /* EKEM - edit key execution mode */
+ break;
+
+ case 25: /* TCEM - text cursor enable mode */
+ if(vsp == svsp)
+ sw_cursor(1); /* cursor on */
+ svsp->cursor_on = 1;
+ break;
+
+ case 42: /* NRCM - 7bit NRC characters */
+ break;
+ }
+}
+
+/*---------------------------------------------------------------------------*
+ * reset dec private modes, esc [ ? x l
+ *---------------------------------------------------------------------------*/
+void
+vt_reset_dec_priv_qm(struct video_state *svsp)
+{
+ switch(svsp->parms[0])
+ {
+ case 0: /* error, ignored */
+ case 1: /* CKM - cursor key mode */
+ svsp->ckm = 0;
+ break;
+
+ case 2: /* ANM - ansi/vt52 mode */
+ break;
+
+ case 3: /* COLM - column mode */
+ vt_col(svsp, SCR_COL80);
+ break;
+
+ case 4: /* SCLM - scrolling mode */
+ case 5: /* SCNM - screen mode */
+ break;
+
+ case 6: /* OM - origin mode */
+ svsp->m_om = 0;
+ break;
+
+ case 7: /* AWM - auto wrap mode */
+ svsp->m_awm = 0;
+ swritefkl(7,(u_char *)"AUTOWRAPENABLE ",svsp);
+ break;
+
+ case 8: /* ARM - auto repeat mode */
+ kbrepflag = 0;
+ break;
+
+ case 9: /* INLM - interlace mode */
+ case 10: /* EDM - edit mode */
+ case 11: /* LTM - line transmit mode */
+ case 12: /* */
+ case 13: /* SCFDM - space compression / field delimiting */
+ case 14: /* TEM - transmit execution mode */
+ case 15: /* */
+ case 16: /* EKEM - edit key execution mode */
+ break;
+
+ case 25: /* TCEM - text cursor enable mode */
+ if(vsp == svsp)
+ sw_cursor(0); /* cursor off */
+ svsp->cursor_on = 0;
+ break;
+
+ case 42: /* NRCM - 7bit NRC characters */
+ break;
+ }
+}
+
+/*---------------------------------------------------------------------------*
+ * set ansi modes, esc [ x
+ *---------------------------------------------------------------------------*/
+void
+vt_set_ansi(struct video_state *svsp)
+{
+ switch(svsp->parms[0])
+ {
+ case 0: /* error, ignored */
+ case 1: /* GATM - guarded area transfer mode */
+ case 2: /* KAM - keyboard action mode */
+ case 3: /* CRM - Control Representation mode */
+ break;
+
+ case 4: /* IRM - insert replacement mode */
+ svsp->irm = 1; /* Insert mode */
+ break;
+
+ case 5: /* SRTM - status report transfer mode */
+ case 6: /* ERM - erasue mode */
+ case 7: /* VEM - vertical editing mode */
+ case 10: /* HEM - horizontal editing mode */
+ case 11: /* PUM - position unit mode */
+ case 12: /* SRM - send-receive mode */
+ case 13: /* FEAM - format effector action mode */
+ case 14: /* FETM - format effector transfer mode */
+ case 15: /* MATM - multiple area transfer mode */
+ case 16: /* TTM - transfer termination */
+ case 17: /* SATM - selected area transfer mode */
+ case 18: /* TSM - tabulation stop mode */
+ case 19: /* EBM - editing boundary mode */
+ break;
+
+ case 20: /* LNM - line feed / newline mode */
+ svsp->lnm = 1;
+ break;
+ }
+}
+
+/*---------------------------------------------------------------------------*
+ * reset ansi modes, esc [ x
+ *---------------------------------------------------------------------------*/
+void
+vt_reset_ansi(struct video_state *svsp)
+{
+ switch(svsp->parms[0])
+ {
+ case 0: /* error, ignored */
+ case 1: /* GATM - guarded area transfer mode */
+ case 2: /* KAM - keyboard action mode */
+ case 3: /* CRM - Control Representation mode */
+ break;
+
+ case 4: /* IRM - insert replacement mode */
+ svsp->irm = 0; /* Replace mode */
+ break;
+
+ case 5: /* SRTM - status report transfer mode */
+ case 6: /* ERM - erasue mode */
+ case 7: /* VEM - vertical editing mode */
+ case 10: /* HEM - horizontal editing mode */
+ case 11: /* PUM - position unit mode */
+ case 12: /* SRM - send-receive mode */
+ case 13: /* FEAM - format effector action mode */
+ case 14: /* FETM - format effector transfer mode */
+ case 15: /* MATM - multiple area transfer mode */
+ case 16: /* TTM - transfer termination */
+ case 17: /* SATM - selected area transfer mode */
+ case 18: /* TSM - tabulation stop mode */
+ case 19: /* EBM - editing boundary mode */
+ break;
+
+ case 20: /* LNM - line feed / newline mode */
+ svsp->lnm = 0;
+ break;
+ }
+}
+
+/*---------------------------------------------------------------------------*
+ * clear tab stop(s)
+ *---------------------------------------------------------------------------*/
+void
+vt_clrtab(struct video_state *svsp)
+{
+ int i;
+
+ if(svsp->parms[0] == 0)
+ svsp->tab_stops[svsp->col] = 0;
+ else if(svsp->parms[0] == 3)
+ {
+ for(i=0; i<MAXTAB; i++)
+ svsp->tab_stops[i] = 0;
+ }
+}
+
+/*---------------------------------------------------------------------------*
+ * DECSC - save cursor & attributes
+ *---------------------------------------------------------------------------*/
+void
+vt_sc(struct video_state *svsp)
+{
+ svsp->sc_flag = 1;
+ svsp->sc_row = svsp->row;
+ svsp->sc_col = svsp->col;
+ svsp->sc_cur_offset = svsp->cur_offset;
+ svsp->sc_attr = svsp->c_attr;
+ svsp->sc_awm = svsp->m_awm;
+ svsp->sc_om = svsp->m_om;
+ svsp->sc_G0 = svsp->G0;
+ svsp->sc_G1 = svsp->G1;
+ svsp->sc_G2 = svsp->G2;
+ svsp->sc_G3 = svsp->G3;
+ svsp->sc_GL = svsp->GL;
+ svsp->sc_GR = svsp->GR;
+ svsp->sc_sel = svsp->selchar;
+ svsp->sc_vtsgr = svsp->vtsgr;
+}
+
+/*---------------------------------------------------------------------------*
+ * DECRC - restore cursor & attributes
+ *---------------------------------------------------------------------------*/
+void
+vt_rc(struct video_state *svsp)
+{
+ if(svsp->sc_flag == 1)
+ {
+ svsp->sc_flag = 0;
+ svsp->row = svsp->sc_row;
+ svsp->col = svsp->sc_col;
+ svsp->cur_offset = svsp->sc_cur_offset;
+ svsp->c_attr = svsp->sc_attr;
+ svsp->m_awm = svsp->sc_awm;
+ svsp->m_om = svsp->sc_om;
+ svsp->G0 = svsp->sc_G0;
+ svsp->G1 = svsp->sc_G1;
+ svsp->G2 = svsp->sc_G2;
+ svsp->G3 = svsp->sc_G3;
+ svsp->GL = svsp->sc_GL;
+ svsp->GR = svsp->sc_GR;
+ svsp->selchar = svsp->sc_sel;
+ svsp->vtsgr = svsp->sc_vtsgr;
+ }
+}
+
+/*---------------------------------------------------------------------------*
+ * designate a character set as G0, G1, G2 or G3 for 94/96 char sets
+ *---------------------------------------------------------------------------*/
+void
+vt_designate(struct video_state *svsp)
+{
+ u_short *ctp = NULL;
+ u_char ch;
+
+ if(svsp->whichi == 1)
+ ch = svsp->which[0];
+ else
+ {
+ int i;
+
+ if(svsp->dld_id[0] == '\0')
+ return;
+
+ if(!(((adaptor_type == EGA_ADAPTOR) ||
+ (adaptor_type == VGA_ADAPTOR)) &&
+ (vgacs[svsp->vga_charset].secondloaded)))
+ {
+ return;
+ }
+
+ for(i = (svsp->whichi)-1; i >= 0; i--)
+ {
+ if(svsp->which[i] != svsp->dld_id[i])
+ return;
+ }
+#ifdef HAVECSE_DOWNLOADABLE
+ ctp = cse_downloadable;
+ swcsp(svsp, ctp);
+#endif
+ return;
+ }
+
+ if(((adaptor_type == EGA_ADAPTOR) || (adaptor_type == VGA_ADAPTOR)) &&
+ (vgacs[svsp->vga_charset].secondloaded))
+ {
+ if((ch == svsp->dld_id[0]) && (svsp->dld_id[1] == '\0'))
+ {
+#ifdef HAVECSE_DOWNLOADABLE
+ ctp = cse_downloadable;
+ swcsp(svsp, ctp);
+#endif
+ return;
+ }
+
+ switch(ch)
+ {
+ case 'A': /* British or ISO-Latin-1 */
+ switch(svsp->state)
+ {
+ case STATE_BROPN: /* designate G0 */
+ case STATE_BRCLO: /* designate G1 */
+ case STATE_STAR: /* designate G2 */
+ case STATE_PLUS: /* designate G3 */
+#ifdef HAVECSE_BRITISH
+ ctp = cse_british;
+#endif
+ break;
+
+ case STATE_MINUS: /* designate G1 (96)*/
+ case STATE_DOT: /* designate G2 (96)*/
+ case STATE_SLASH: /* designate G3 (96)*/
+#ifdef HAVECSE_ISOLATIN
+ ctp = cse_isolatin;
+#endif
+ break;
+ }
+ break;
+
+ case 'B': /* USASCII */
+#ifdef HAVECSE_ASCII
+ ctp = cse_ascii;
+#endif
+ break;
+
+ case 'C': /* Finnish */
+ case '5': /* Finnish */
+#ifdef HAVECSE_FINNISH
+ ctp = cse_finnish;
+#endif
+ break;
+
+ case 'E': /* Norwegian/Danish */
+ case '6': /* Norwegian/Danish */
+#ifdef HAVECSE_NORWEGIANDANISH
+ ctp = cse_norwegiandanish;
+#endif
+ break;
+
+ case 'H': /* Swedish */
+ case '7': /* Swedish */
+#ifdef HAVECSE_SWEDISH
+ ctp = cse_swedish;
+#endif
+ break;
+
+ case 'K': /* German */
+#ifdef HAVECSE_GERMAN
+ ctp = cse_german;
+#endif
+ break;
+
+ case 'Q': /* French Canadien */
+#ifdef HAVECSE_FRENCHCANADA
+ ctp = cse_frenchcanada;
+#endif
+ break;
+
+ case 'R': /* French */
+#ifdef HAVECSE_FRENCH
+ ctp = cse_french;
+#endif
+ break;
+
+ case 'Y': /* Italian */
+#ifdef HAVECSE_ITALIAN
+ ctp = cse_italian;
+#endif
+ break;
+
+ case 'Z': /* Spanish */
+#ifdef HAVECSE_SPANISH
+ ctp = cse_spanish;
+#endif
+ break;
+
+ case '0': /* special graphics */
+#ifdef HAVECSE_SPECIAL
+ ctp = cse_special;
+#endif
+ break;
+
+ case '1': /* alternate ROM */
+#ifdef HAVECSE_ALTERNATEROM1
+ ctp = cse_alternaterom1;
+#endif
+ break;
+
+ case '2': /* alt ROM, spec graphics */
+#ifdef HAVECSE_ALTERNATEROM2
+ ctp = cse_alternaterom2;
+#endif
+ break;
+
+ case '3': /* HP Roman 8, upper 128 chars*/
+#ifdef HAVECSE_ROMAN8
+ ctp = cse_roman8;
+#endif
+ break;
+
+ case '4': /* Dutch */
+#ifdef HAVECSE_DUTCH
+ ctp = cse_dutch;
+#endif
+ break;
+
+ case '<': /* DEC Supplemental */
+#ifdef HAVECSE_SUPPLEMENTAL
+ ctp = cse_supplemental;
+#endif
+ break;
+
+ case '=': /* Swiss */
+#ifdef HAVECSE_SWISS
+ ctp = cse_swiss;
+#endif
+ break;
+
+ case '>': /* DEC Technical */
+#ifdef HAVECSE_TECHNICAL
+ ctp = cse_technical;
+#endif
+ break;
+
+ default:
+ break;
+ }
+ }
+ else
+ {
+ switch(ch)
+ {
+ case 'A': /* British or ISO-Latin-1 */
+ switch(svsp->state)
+ {
+ case STATE_BROPN: /* designate G0 */
+ case STATE_BRCLO: /* designate G1 */
+ case STATE_STAR: /* designate G2 */
+ case STATE_PLUS: /* designate G3 */
+#ifdef HAVECSD_BRITISH
+ ctp = csd_british;
+#endif
+ break;
+
+ case STATE_MINUS: /* designate G1 (96)*/
+ case STATE_DOT: /* designate G2 (96)*/
+ case STATE_SLASH: /* designate G3 (96)*/
+#ifdef HAVECSD_ISOLATIN
+ ctp = csd_isolatin;
+#endif
+ break;
+ }
+ break;
+
+ case 'B': /* USASCII */
+#ifdef HAVECSD_ASCII
+ ctp = csd_ascii;
+#endif
+ break;
+
+ case 'C': /* Finnish */
+ case '5': /* Finnish */
+#ifdef HAVECSD_FINNISH
+ ctp = csd_finnish;
+#endif
+ break;
+
+ case 'E': /* Norwegian/Danish */
+ case '6': /* Norwegian/Danish */
+#ifdef HAVECSD_NORWEGIANDANISH
+ ctp = csd_norwegiandanish;
+#endif
+ break;
+
+ case 'H': /* Swedish */
+ case '7': /* Swedish */
+#ifdef HAVECSD_SWEDISH
+ ctp = csd_swedish;
+#endif
+ break;
+
+ case 'K': /* German */
+#ifdef HAVECSD_GERMAN
+ ctp = csd_german;
+#endif
+ break;
+
+ case 'Q': /* French Canadien */
+#ifdef HAVECSD_FRENCHCANADA
+ ctp = csd_frenchcanada;
+#endif
+ break;
+
+ case 'R': /* French */
+#ifdef HAVECSD_FRENCH
+ ctp = csd_french;
+#endif
+ break;
+
+ case 'Y': /* Italian */
+#ifdef HAVECSD_ITALIAN
+ ctp = csd_italian;
+#endif
+ break;
+
+ case 'Z': /* Spanish */
+#ifdef HAVECSD_SPANISH
+ ctp = csd_spanish;
+#endif
+ break;
+
+ case '0': /* special graphics */
+#ifdef HAVECSD_SPECIAL
+ ctp = csd_special;
+#endif
+ break;
+
+ case '1': /* alternate ROM */
+#ifdef HAVECSD_ALTERNATEROM1
+ ctp = csd_alternaterom1;
+#endif
+ break;
+
+ case '2': /* alt ROM, spec graphics */
+#ifdef HAVECSD_ALTERNATEROM2
+ ctp = csd_alternaterom2;
+#endif
+ break;
+
+ case '3': /* HP Roman 8, upper 128 chars*/
+#ifdef HAVECSD_ROMAN8
+ ctp = csd_roman8;
+#endif
+ break;
+
+ case '4': /* Dutch */
+#ifdef HAVECSD_DUTCH
+ ctp = csd_dutch;
+#endif
+ break;
+
+ case '<': /* DEC Supplemental */
+#ifdef HAVECSD_SUPPLEMENTAL
+ ctp = csd_supplemental;
+#endif
+ break;
+
+ case '=': /* Swiss */
+#ifdef HAVECSD_SWISS
+ ctp = csd_swiss;
+#endif
+ break;
+
+ case '>': /* DEC Technical */
+#ifdef HAVECSD_TECHNICAL
+ ctp = csd_technical;
+#endif
+ break;
+
+ default:
+ break;
+ }
+ }
+ swcsp(svsp, ctp);
+}
+
+/*---------------------------------------------------------------------------*
+ * device attributes
+ *---------------------------------------------------------------------------*/
+void
+vt_da(struct video_state *svsp)
+{
+ static u_char *response = (u_char *)DA_VT220;
+
+ svsp->report_chars = response;
+ svsp->report_count = 18;
+ respond(svsp);
+}
+
+/*---------------------------------------------------------------------------*
+ * screen alignment display
+ *---------------------------------------------------------------------------*/
+void
+vt_aln(struct video_state *svsp)
+{
+ register int i;
+
+ svsp->cur_offset = 0;
+ svsp->col = 0;
+
+ for(i=0; i < (svsp->screen_rows*svsp->maxcol); i++)
+ {
+ *(svsp->Crtat + svsp->cur_offset) = user_attr | 'E';
+ vt_selattr(svsp);
+ svsp->cur_offset++;
+ svsp->col++;
+ }
+
+ svsp->cur_offset = 0; /* reset everything ! */
+ svsp->col = 0;
+ svsp->row = 0;
+}
+
+/*---------------------------------------------------------------------------*
+ * request terminal parameters
+ *---------------------------------------------------------------------------*/
+void
+vt_reqtparm(struct video_state *svsp)
+{
+ static u_char *answr = (u_char *)"\033[3;1;1;120;120;1;0x";
+
+ svsp->report_chars = answr;
+ svsp->report_count = 20;
+ respond(svsp);
+}
+
+/*---------------------------------------------------------------------------*
+ * invoke selftest
+ *---------------------------------------------------------------------------*/
+void
+vt_tst(struct video_state *svsp)
+{
+ clear_dld(svsp);
+}
+
+/*---------------------------------------------------------------------------*
+ * device status reports
+ *---------------------------------------------------------------------------*/
+void
+vt_dsr(struct video_state *svsp)
+{
+ static u_char *answr = (u_char *)"\033[0n";
+ static u_char *panswr = (u_char *)"\033[?13n"; /* Printer Unattached */
+ static u_char *udkanswr = (u_char *)"\033[?21n"; /* UDK Locked */
+ static u_char *langanswr = (u_char *)"\033[?27;1n"; /* North American*/
+ static u_char buffer[16];
+ int i = 0;
+
+ switch(svsp->parms[0])
+ {
+ case 5: /* return status */
+ svsp->report_chars = answr;
+ svsp->report_count = 4;
+ respond(svsp);
+ break;
+
+ case 6: /* return cursor position */
+ buffer[i++] = 0x1b;
+ buffer[i++] = '[';
+ if((svsp->row+1) > 10)
+ buffer[i++] = ((svsp->row+1) / 10) + '0';
+ buffer[i++] = ((svsp->row+1) % 10) + '0';
+ buffer[i++] = ';';
+ if((svsp->col+1) > 10)
+ buffer[i++] = ((svsp->col+1) / 10) + '0';
+ buffer[i++] = ((svsp->col+1) % 10) + '0';
+ buffer[i++] = 'R';
+ buffer[i++] = '\0';
+
+ svsp->report_chars = buffer;
+ svsp->report_count = i;
+ respond(svsp);
+ break;
+
+ case 15: /* return printer status */
+ svsp->report_chars = panswr;
+ svsp->report_count = 6;
+ respond(svsp);
+ break;
+
+ case 25: /* return udk status */
+ svsp->report_chars = udkanswr;
+ svsp->report_count = 6;
+ respond(svsp);
+ break;
+
+ case 26: /* return language status */
+ svsp->report_chars = langanswr;
+ svsp->report_count = 8;
+ respond(svsp);
+ break;
+
+ default: /* nothing else valid */
+ break;
+ }
+}
+
+/*---------------------------------------------------------------------------*
+ * IL - insert line
+ *---------------------------------------------------------------------------*/
+void
+vt_il(struct video_state *svsp)
+{
+ register int p = svsp->parms[0];
+
+ if((svsp->row >= svsp->scrr_beg) && (svsp->row <= svsp->scrr_end))
+ {
+ if(p <= 0)
+ p = 1;
+ else if(p > svsp->scrr_end - svsp->row)
+ p = svsp->scrr_end - svsp->row;
+
+ svsp->cur_offset -= svsp->col;
+ svsp->col = 0;
+ if(svsp->row == svsp->scrr_beg)
+ roll_down(svsp, p);
+ else
+ {
+ bcopy(svsp->Crtat + svsp->cur_offset,
+ svsp->Crtat + svsp->cur_offset + (p * svsp->maxcol),
+ svsp->maxcol * (svsp->scrr_end-svsp->row+1-p) * CHR );
+
+ fillw(user_attr | ' ',
+ svsp->Crtat + svsp->cur_offset,
+ p * svsp->maxcol);
+ }
+ }
+}
+
+/*---------------------------------------------------------------------------*
+ * ICH - insert character
+ *---------------------------------------------------------------------------*/
+void
+vt_ic(struct video_state *svsp)
+{
+ register int p = svsp->parms[0];
+
+ if(p <= 0)
+ p = 1;
+ else if(p > svsp->maxcol-svsp->col)
+ p = svsp->maxcol-svsp->col;
+
+ while(p--)
+ {
+ bcopy((svsp->Crtat + svsp->cur_offset),
+ (svsp->Crtat + svsp->cur_offset) + 1,
+ (((svsp->maxcol)-1)-svsp->col) * CHR);
+
+ *(svsp->Crtat + svsp->cur_offset) = user_attr | ' ';
+ vt_selattr(svsp);
+ }
+}
+
+/*---------------------------------------------------------------------------*
+ * DL - delete line
+ *---------------------------------------------------------------------------*/
+void
+vt_dl(struct video_state *svsp)
+{
+ register int p = svsp->parms[0];
+
+ if((svsp->row >= svsp->scrr_beg) && (svsp->row <= svsp->scrr_end))
+ {
+ if(p <= 0)
+ p = 1;
+ else if(p > svsp->scrr_end - svsp->row)
+ p = svsp->scrr_end - svsp->row;
+
+ svsp->cur_offset -= svsp->col;
+ svsp->col = 0;
+
+ if(svsp->row == svsp->scrr_beg)
+ roll_up(svsp, p);
+ else
+ {
+ bcopy(svsp->Crtat + svsp->cur_offset + (p * svsp->maxcol),
+ svsp->Crtat + svsp->cur_offset,
+ svsp->maxcol * (svsp->scrr_end-svsp->row+1-p) * CHR );
+
+ fillw(user_attr | ' ',
+ svsp->Crtat + ((svsp->scrr_end-p+1) * svsp->maxcol),
+ p * svsp->maxcol);
+ }
+ }
+}
+
+/*---------------------------------------------------------------------------*
+ * DCH - delete character
+ *---------------------------------------------------------------------------*/
+void
+vt_dch(struct video_state *svsp)
+{
+ register int p = svsp->parms[0];
+
+ if(p <= 0)
+ p = 1;
+ else if(p > svsp->maxcol-svsp->col)
+ p = svsp->maxcol-svsp->col;
+
+ while(p--)
+ {
+ bcopy((svsp->Crtat + svsp->cur_offset)+1,
+ (svsp->Crtat + svsp->cur_offset),
+ (((svsp->maxcol)-1) - svsp->col)* CHR );
+
+ *((svsp->Crtat + svsp->cur_offset) +
+ ((svsp->maxcol)-1)-svsp->col) = user_attr | ' ';
+ }
+}
+
+/*---------------------------------------------------------------------------*
+ * scroll up
+ *---------------------------------------------------------------------------*/
+void
+vt_su(struct video_state *svsp)
+{
+ register int p = svsp->parms[0];
+
+ if(p <= 0)
+ p = 1;
+ else if(p > svsp->screen_rows-1)
+ p = svsp->screen_rows-1;
+
+ roll_up(svsp, p);
+}
+
+/*---------------------------------------------------------------------------*
+ * scroll down
+ *---------------------------------------------------------------------------*/
+void
+vt_sd(struct video_state *svsp)
+{
+ register int p = svsp->parms[0];
+
+ if(p <= 0)
+ p = 1;
+ else if(p > svsp->screen_rows-1)
+ p = svsp->screen_rows-1;
+
+ roll_down(svsp, p);
+}
+
+/*---------------------------------------------------------------------------*
+ * ECH - erase character
+ *---------------------------------------------------------------------------*/
+void
+vt_ech(struct video_state *svsp)
+{
+ register int p = svsp->parms[0];
+
+ if(p <= 0)
+ p = 1;
+ else if(p > svsp->maxcol-svsp->col)
+ p = svsp->maxcol-svsp->col;
+
+ fillw(user_attr | ' ', (svsp->Crtat + svsp->cur_offset), p);
+}
+
+/*---------------------------------------------------------------------------*
+ * media copy (NO PRINTER AVAILABLE IN KERNEL ...)
+ *---------------------------------------------------------------------------*/
+void
+vt_mc(struct video_state *svsp)
+{
+}
+
+/*---------------------------------------------------------------------------*
+ * Device Control String State Machine Entry for:
+ *
+ * DECUDK - user-defined keys and
+ * DECDLD - downloadable charset
+ *
+ *---------------------------------------------------------------------------*/
+void
+vt_dcsentry(U_char ch, struct video_state *svsp)
+{
+ switch(svsp->dcs_state)
+ {
+ case DCS_INIT:
+ switch(ch)
+ {
+ case '0':
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ case '8':
+ case '9': /* parameters */
+ svsp->parms[svsp->parmi] *= 10;
+ svsp->parms[svsp->parmi] += (ch -'0');
+ break;
+
+ case ';': /* next parameter */
+ svsp->parmi =
+ (svsp->parmi+1 < MAXPARMS) ?
+ svsp->parmi+1 : svsp->parmi;
+ break;
+
+ case '|': /* DECUDK */
+ svsp->transparent = 1;
+ init_udk(svsp);
+ svsp->dcs_state = DCS_AND_UDK;
+ break;
+
+ case '{': /* DECDLD */
+ svsp->transparent = 1;
+ init_dld(svsp);
+ svsp->dcs_state = DCS_DLD_DSCS;
+ break;
+
+ default: /* failsafe */
+ svsp->transparent = 0;
+ svsp->state = STATE_INIT;
+ svsp->dcs_state = DCS_INIT;
+ break;
+ }
+ break;
+
+ case DCS_AND_UDK: /* DCS ... | */
+ switch(ch)
+ {
+ case '0':
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ case '8':
+ case '9': /* fkey number */
+ svsp->udk_fnckey *= 10;
+ svsp->udk_fnckey += (ch -'0');
+ break;
+
+ case '/': /* Key */
+ svsp->dcs_state = DCS_UDK_DEF;
+ break;
+
+ case 0x1b: /* ESC */
+ svsp->dcs_state = DCS_UDK_ESC;
+ break;
+
+ default:
+ svsp->transparent = 0;
+ svsp->state = STATE_INIT;
+ svsp->dcs_state = DCS_INIT;
+ break;
+ }
+ break;
+
+ case DCS_UDK_DEF: /* DCS ... | fnckey / */
+ switch(ch)
+ {
+ case '0':
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ case '8':
+ case '9':
+ if(svsp->udk_deflow) /* low nibble */
+ {
+ svsp->udk_def[svsp->udk_defi] |= (ch -'0');
+ svsp->udk_deflow = 0;
+ svsp->udk_defi = (svsp->udk_defi+1 >= MAXUDKDEF) ?
+ svsp->udk_defi : svsp->udk_defi+1;
+ }
+ else /* high nibble */
+ {
+ svsp->udk_def[svsp->udk_defi] = ((ch -'0') << 4);
+ svsp->udk_deflow = 1;
+ }
+ break;
+
+ case 'a':
+ case 'b':
+ case 'c':
+ case 'd':
+ case 'e':
+ case 'f':
+ if(svsp->udk_deflow) /* low nibble */
+ {
+ svsp->udk_def[svsp->udk_defi] |= (ch - 'a' + 10);
+ svsp->udk_deflow = 0;
+ svsp->udk_defi = (svsp->udk_defi+1 >= MAXUDKDEF) ?
+ svsp->udk_defi : svsp->udk_defi+1;
+ }
+ else /* high nibble */
+ {
+ svsp->udk_def[svsp->udk_defi] = ((ch - 'a' + 10) << 4);
+ svsp->udk_deflow = 1;
+ }
+ break;
+
+
+
+ case 'A':
+ case 'B':
+ case 'C':
+ case 'D':
+ case 'E':
+ case 'F':
+ if(svsp->udk_deflow) /* low nibble */
+ {
+ svsp->udk_def[svsp->udk_defi] |= (ch - 'A' + 10);
+ svsp->udk_deflow = 0;
+ svsp->udk_defi = (svsp->udk_defi+1 >= MAXUDKDEF) ?
+ svsp->udk_defi : svsp->udk_defi+1;
+ }
+ else /* high nibble */
+ {
+ svsp->udk_def[svsp->udk_defi] = ((ch - 'A' + 10) << 4);
+ svsp->udk_deflow = 1;
+ }
+ break;
+
+ case ';': /* next function key */
+ vt_udk(svsp);
+ svsp->dcs_state = DCS_AND_UDK;
+ break;
+
+ case 0x1b: /* ESC */
+ svsp->dcs_state = DCS_UDK_ESC;
+ break;
+
+ default:
+ svsp->transparent = 0;
+ svsp->state = STATE_INIT;
+ svsp->dcs_state = DCS_INIT;
+ break;
+ }
+ break;
+
+ case DCS_UDK_ESC: /* DCS ... | fkey/def ... ESC */
+ switch(ch)
+ {
+ case '\\': /* ST */
+ vt_udk(svsp);
+ svsp->transparent = 0;
+ svsp->state = STATE_INIT;
+ svsp->dcs_state = DCS_INIT;
+ break;
+
+ default:
+ svsp->transparent = 0;
+ svsp->state = STATE_INIT;
+ svsp->dcs_state = DCS_INIT;
+ break;
+ }
+ break;
+
+
+ case DCS_DLD_DSCS: /* got DCS ... { */
+ if(ch >= ' ' && ch <= '/') /* intermediates ... */
+ {
+ svsp->dld_dscs[svsp->dld_dscsi] = ch;
+ svsp->dld_id[svsp->dld_dscsi] = ch;
+ if(svsp->dld_dscsi >= DSCS_LENGTH)
+ {
+ svsp->transparent = 0;
+ svsp->state = STATE_INIT;
+ svsp->dcs_state = DCS_INIT;
+ svsp->dld_id[0] = '\0';
+ }
+ else
+ {
+ svsp->dld_dscsi++;
+ }
+ }
+ else if(ch >= '0' && ch <= '~') /* final .... */
+ {
+ svsp->dld_dscs[svsp->dld_dscsi] = ch;
+ svsp->dld_id[svsp->dld_dscsi++] = ch;
+ svsp->dld_id[svsp->dld_dscsi] = '\0';
+ svsp->dcs_state = DCS_DLD_DEF;
+ }
+ else
+ {
+ svsp->transparent = 0;
+ svsp->state = STATE_INIT;
+ svsp->dcs_state = DCS_INIT;
+ svsp->dld_id[0] = '\0';
+ }
+ break;
+
+ case DCS_DLD_DEF: /* DCS ... { dscs */
+ switch(ch)
+ {
+ case 0x1b: /* ESC */
+ svsp->dcs_state = DCS_DLD_ESC;
+ break;
+
+ case '/': /* sixel upper / lower divider */
+ svsp->dld_sixel_lower = 1;
+ break;
+
+ case ';': /* character divider */
+ vt_dld(svsp);
+ svsp->parms[1]++; /* next char */
+ break;
+
+ default:
+ if (svsp->dld_sixel_lower)
+ {
+ if(ch >= '?' && ch <= '~')
+ svsp->sixel.lower[svsp->dld_sixelli] = ch - '?';
+ svsp->dld_sixelli =
+ (svsp->dld_sixelli+1 < MAXSIXEL) ?
+ svsp->dld_sixelli+1 : svsp->dld_sixelli;
+ }
+ else
+ {
+ if(ch >= '?' && ch <= '~')
+ svsp->sixel.upper[svsp->dld_sixelui] = ch - '?';
+ svsp->dld_sixelui =
+ (svsp->dld_sixelui+1 < MAXSIXEL) ?
+ svsp->dld_sixelui+1 : svsp->dld_sixelui;
+ }
+ break;
+ }
+ break;
+
+ case DCS_DLD_ESC: /* DCS ... { dscs ... / ... ESC */
+ switch(ch)
+ {
+ case '\\': /* String Terminator ST */
+ vt_dld(svsp);
+ svsp->transparent = 0;
+ svsp->state = STATE_INIT;
+ svsp->dcs_state = DCS_INIT;
+ break;
+
+ default:
+ svsp->transparent = 0;
+ svsp->state = STATE_INIT;
+ svsp->dcs_state = DCS_INIT;
+ svsp->dld_id[0] = '\0';
+ break;
+ }
+ break;
+
+ default:
+ svsp->transparent = 0;
+ svsp->state = STATE_INIT;
+ svsp->dcs_state = DCS_INIT;
+ break;
+ }
+}
+
+/*---------------------------------------------------------------------------*
+ * User Defineable Keys
+ *---------------------------------------------------------------------------*/
+void
+vt_udk(struct video_state *svsp)
+{
+ int key, start, max, i;
+ int usedff = 0;
+
+ if(svsp->parms[0] != 1) /* clear all ? */
+ {
+ vt_clearudk(svsp);
+ svsp->parms[0] = 1;
+ }
+
+ if(svsp->udk_fnckey < 17 || svsp->udk_fnckey > 34)
+ {
+ init_udk(svsp);
+ return;
+ }
+
+ key = svsp->udk_fnckey - 17; /* index into table */
+
+ if(svsp->ukt.length[key] == 0) /* never used ? */
+ {
+ if(svsp->udkff < MAXUDKDEF-2) /* space available ? */
+ {
+ start = svsp->udkff; /* next sequential */
+ max = MAXUDKDEF - svsp->udkff; /* space available */
+ svsp->ukt.first[key] = start; /* start entry */
+ usedff = 1; /* flag to update later */
+ }
+ else /* no space */
+ {
+ init_udk(svsp);
+ return;
+ }
+ }
+ else /* in use, redefine */
+ {
+ start = svsp->ukt.first[key]; /* start entry */
+ max = svsp->ukt.length[key]; /* space available */
+ }
+
+ if(max < 2) /* hmmm .. */
+ {
+ init_udk(svsp);
+ return;
+ }
+
+ max--; /* adjust for tailing '\0' */
+
+ for(i = 0; i < max && i < svsp->udk_defi; i++)
+ svsp->udkbuf[start++] = svsp->udk_def[i];
+
+ svsp->udkbuf[start] = '\0'; /* make it a string, see pcvt_kbd.c */
+ svsp->ukt.length[key] = i+1; /* count for tailing '\0' */
+ if(usedff)
+ svsp->udkff += (i+2); /* new start location */
+
+ init_udk(svsp);
+}
+
+/*---------------------------------------------------------------------------*
+ * clear all User Defineable Keys
+ *---------------------------------------------------------------------------*/
+void
+vt_clearudk(struct video_state *svsp)
+{
+ register int i;
+
+ for(i = 0; i < MAXUDKEYS; i++)
+ {
+ svsp->ukt.first[i] = 0;
+ svsp->ukt.length[i] = 0;
+ }
+ svsp->udkff = 0;
+}
+
+/*---------------------------------------------------------------------------*
+ * Down line LoaDable Fonts
+ *---------------------------------------------------------------------------*/
+void
+vt_dld(struct video_state *svsp)
+{
+ unsigned char vgacharset;
+ unsigned char vgachar[16];
+ unsigned char vgacharb[16];
+
+ if(vgacs[svsp->vga_charset].secondloaded)
+ vgacharset = vgacs[svsp->vga_charset].secondloaded;
+ else
+ return;
+
+ svsp->parms[1] = (svsp->parms[1] < 1) ? 1 :
+ ((svsp->parms[1] > 0x7E) ? 0x7E : svsp->parms[1]);
+
+ if(svsp->parms[2] != 1) /* Erase all characters ? */
+ {
+ clear_dld(svsp);
+ svsp->parms[2] = 1; /* Only erase all characters once per sequence */
+ }
+
+ sixel_vga(&(svsp->sixel),vgachar);
+
+ switch(vgacs[vgacharset].char_scanlines & 0x1F)
+ {
+ case 7:
+ vga10_vga8(vgachar,vgacharb);
+ break;
+
+ case 9:
+ default:
+ vga10_vga10(vgachar,vgacharb);
+ break;
+
+ case 13:
+ vga10_vga14(vgachar,vgacharb);
+ break;
+
+ case 15:
+ vga10_vga16(vgachar,vgacharb);
+ break;
+ }
+
+ loadchar(vgacharset, svsp->parms[1] + 0xA0, 16, vgacharb);
+
+ init_dld(svsp);
+}
+
+/*---------------------------------------------------------------------------*
+ * select compatibility level
+ *---------------------------------------------------------------------------*/
+void
+vt_scl(struct video_state *svsp)
+{
+ /* poor man's scl. normally this also enables/disables the editing
+ * keypad and the available character sets. we only enable/disable
+ * support for C1 control codes.
+ */
+
+ register int p0, p1;
+
+ p0 = svsp->parms[0];
+ p1 = svsp->parms[1];
+
+ vt_str(svsp);
+
+ switch(p0)
+ {
+ case 61:
+ svsp->sevenbit = 1;
+ break;
+ case 62:
+ /* case 63: vt320 */
+ default:
+ if(p1 != 1)
+ svsp->C1_ctls = 1;
+ break;
+ }
+}
+
+/*---------------------------------------------------------------------------*
+ * select character attributes
+ *---------------------------------------------------------------------------*/
+void
+vt_sca(struct video_state *svsp)
+{
+ switch(svsp->parms[0])
+ {
+ case 1:
+ svsp->selchar = 1;
+ break;
+ case 0:
+ case 2:
+ default:
+ svsp->selchar = 0;
+ break;
+ }
+}
+
+/*---------------------------------------------------------------------------*
+ * initalize selective attribute bit array
+ *---------------------------------------------------------------------------*/
+void
+vt_initsel(struct video_state *svsp)
+{
+ register int i;
+
+ for(i = 0;i < MAXDECSCA;i++)
+ svsp->decsca[i] = 0;
+}
+
+/*---------------------------------------------------------------------------*
+ * DECSEL - selective erase in line
+ *---------------------------------------------------------------------------*/
+void
+vt_sel(struct video_state *svsp)
+{
+ switch(svsp->parms[0])
+ {
+ case 0:
+ selective_erase(svsp, (svsp->Crtat + svsp->cur_offset),
+ svsp->maxcol-svsp->col);
+ break;
+
+ case 1:
+ selective_erase(svsp, (svsp->Crtat + svsp->cur_offset)-
+ svsp->col, svsp->col + 1);
+ break;
+
+ case 2:
+ selective_erase(svsp, (svsp->Crtat + svsp->cur_offset)-
+ svsp->col, svsp->maxcol);
+ break;
+ }
+}
+
+/*---------------------------------------------------------------------------*
+ * DECSED - selective erase in display
+ *---------------------------------------------------------------------------*/
+void
+vt_sed(struct video_state *svsp)
+{
+ switch(svsp->parms[0])
+ {
+ case 0:
+ selective_erase(svsp, (svsp->Crtat + svsp->cur_offset),
+ svsp->Crtat + (svsp->maxcol * svsp->screen_rows) -
+ (svsp->Crtat + svsp->cur_offset));
+ break;
+
+ case 1:
+ selective_erase(svsp, svsp->Crtat,
+ (svsp->Crtat + svsp->cur_offset) - svsp->Crtat + 1 );
+ break;
+
+ case 2:
+ selective_erase(svsp, svsp->Crtat,
+ svsp->maxcol * svsp->screen_rows);
+ break;
+ }
+}
+
+/*---------------------------------------------------------------------------*
+ * scroll screen n lines up
+ *---------------------------------------------------------------------------*/
+void
+roll_up(struct video_state *svsp, int n)
+{
+
+#if (PCVT_NOFASTSCROLL==0)
+
+ if(svsp->scrr_beg == 0 && /* if scroll region is whole screen */
+ svsp->scrr_len == svsp->screen_rows &&
+ (svsp != vsp || /* and either running in memory */
+ (svsp->screen_rows == svsp->screen_rowsize /* or no fkeys */
+
+#if (PCVT_MDAFASTSCROLL==0)
+ && adaptor_type != MDA_ADAPTOR /* and not on MDA/Hercules */
+#endif
+
+ )))
+
+ {
+ u_short *Memory =
+ (vsp != svsp || (vsp->vt_status & VT_GRAFX)) ?
+ svsp->Memory : Crtat;
+
+ if(svsp->Crtat > (Memory + (svsp->screen_rows - n) *
+ svsp->maxcol))
+ {
+ bcopy(svsp->Crtat + svsp->maxcol * n, Memory,
+ svsp->maxcol * (svsp->screen_rows - n) * CHR);
+
+ svsp->Crtat = Memory;
+ }
+ else
+ {
+ svsp->Crtat += n * svsp->maxcol;
+ }
+
+ if(vsp == svsp && !(vsp->vt_status & VT_GRAFX))
+ {
+ outb(addr_6845, CRTC_STARTADRH);
+ outb(addr_6845+1, (svsp->Crtat - Crtat) >> 8);
+ outb(addr_6845, CRTC_STARTADRL);
+ outb(addr_6845+1, (svsp->Crtat - Crtat));
+ }
+ }
+ else
+#endif
+ {
+ bcopy( svsp->Crtat + ((svsp->scrr_beg + n) * svsp->maxcol),
+ svsp->Crtat + (svsp->scrr_beg * svsp->maxcol),
+ svsp->maxcol * (svsp->scrr_len - n) * CHR );
+ }
+
+ fillw( user_attr | ' ',
+ svsp->Crtat + ((svsp->scrr_end - n + 1) * svsp->maxcol),
+ n * svsp->maxcol);
+
+/*XXX*/ if(svsp->scroll_lock && svsp->openf && curproc)
+ tsleep((caddr_t)&(svsp->scroll_lock), PUSER, "scrlck", 0);
+}
+
+/*---------------------------------------------------------------------------*
+ * scroll screen n lines down
+ *---------------------------------------------------------------------------*/
+static void
+roll_down(struct video_state *svsp, int n)
+{
+
+#if (PCVT_NOFASTSCROLL==0)
+
+ if(svsp->scrr_beg == 0 && /* if scroll region is whole screen */
+ svsp->scrr_len == svsp->screen_rows &&
+ (svsp != vsp || /* and either running in memory */
+ (svsp->screen_rows == svsp->screen_rowsize /* or no fkeys */
+
+#if (PCVT_MDAFASTSCROLL==0)
+ && adaptor_type != MDA_ADAPTOR /* and not on MDA/Hercules */
+#endif
+
+ )))
+
+ {
+ u_short *Memory =
+ (vsp != svsp || (vsp->vt_status & VT_GRAFX)) ?
+ svsp->Memory : Crtat;
+
+ if (svsp->Crtat < (Memory + n * svsp->maxcol))
+ {
+ bcopy(svsp->Crtat,
+ Memory + svsp->maxcol * (svsp->screen_rows + n),
+ svsp->maxcol * (svsp->screen_rows - n) * CHR);
+
+ svsp->Crtat = Memory + svsp->maxcol * svsp->screen_rows;
+ }
+ else
+ {
+ svsp->Crtat -= n * svsp->maxcol;
+ }
+
+ if(vsp == svsp && !(vsp->vt_status & VT_GRAFX))
+ {
+ outb(addr_6845, CRTC_STARTADRH);
+ outb(addr_6845+1, (svsp->Crtat - Crtat) >> 8);
+ outb(addr_6845, CRTC_STARTADRL);
+ outb(addr_6845+1, (svsp->Crtat - Crtat));
+ }
+ }
+ else
+#endif
+ {
+ bcopy( svsp->Crtat + (svsp->scrr_beg * svsp->maxcol),
+ svsp->Crtat + ((svsp->scrr_beg + n) * svsp->maxcol),
+ svsp->maxcol * (svsp->scrr_len - n) * CHR );
+ }
+
+ fillw( user_attr | ' ',
+ svsp->Crtat + (svsp->scrr_beg * svsp->maxcol),
+ n * svsp->maxcol);
+
+/*XXX*/ if(svsp->scroll_lock && svsp->openf && curproc)
+ tsleep((caddr_t)&(svsp->scroll_lock), PUSER, "scrlck", 0);
+}
+
+/*---------------------------------------------------------------------------*
+ * switch charset pointers
+ *---------------------------------------------------------------------------*/
+static void
+swcsp(struct video_state *svsp, u_short *ctp)
+{
+ if(ctp == NULL)
+ return;
+
+ /* update GL or GR if the designated charset is currently displayed */
+
+ switch(svsp->state)
+ {
+ case STATE_BROPN: /* designate G0 */
+ if (svsp->GL == svsp->G0)
+ svsp->GL = ctp;
+ if (svsp->GR == svsp->G0)
+ svsp->GR = ctp;
+ svsp->G0 = ctp;
+ break;
+
+ case STATE_BRCLO: /* designate G1 */
+ case STATE_MINUS: /* designate G1 (96) */
+ if (svsp->GL == svsp->G1)
+ svsp->GL = ctp;
+ if (svsp->GR == svsp->G1)
+ svsp->GR = ctp;
+ svsp->G1 = ctp;
+ break;
+
+ case STATE_STAR: /* designate G2 */
+ case STATE_DOT: /* designate G2 (96) */
+ if (svsp->GL == svsp->G2)
+ svsp->GL = ctp;
+ if (svsp->GR == svsp->G2)
+ svsp->GR = ctp;
+ svsp->G2 = ctp;
+ break;
+
+ case STATE_PLUS: /* designate G3 */
+ case STATE_SLASH: /* designate G3 (96) */
+ if (svsp->GL == svsp->G3)
+ svsp->GL = ctp;
+ if (svsp->GR == svsp->G3)
+ svsp->GR = ctp;
+ svsp->G3 = ctp;
+ break;
+ }
+}
+
+/*---------------------------------------------------------------------------*
+ * process terminal responses
+ *---------------------------------------------------------------------------*/
+static void
+respond(struct video_state *svsp)
+{
+ if(!(svsp->openf)) /* are we opened ? */
+ return;
+
+ while (*svsp->report_chars && svsp->report_count > 0)
+ {
+ (*linesw[svsp->vs_tty->t_line].l_rint)
+ (*svsp->report_chars++ & 0xff, svsp->vs_tty);
+ svsp->report_count--;
+ }
+}
+
+/*---------------------------------------------------------------------------*
+ * Initialization for User Defineable Keys
+ *---------------------------------------------------------------------------*/
+static void
+init_udk(struct video_state *svsp)
+{
+ svsp->udk_defi = 0;
+ svsp->udk_deflow = 0;
+ svsp->udk_fnckey = 0;
+}
+
+/*---------------------------------------------------------------------------*
+ * Clear loaded downloadable (DLD) character set
+ *---------------------------------------------------------------------------*/
+static void
+clear_dld(struct video_state *svsp)
+{
+ register int i;
+ unsigned char vgacharset;
+ unsigned char vgachar[16];
+
+ if(vgacs[svsp->vga_charset].secondloaded)
+ vgacharset = vgacs[svsp->vga_charset].secondloaded;
+ else
+ return;
+
+ for(i=0;i < 16;i++) /* A zeroed character, vt220 has inverted '?' */
+ vgachar[i] = 0x00;
+
+ for(i=1;i <= 94;i++) /* Load (erase) all characters */
+ loadchar(vgacharset, i + 0xA0, 16, vgachar);
+}
+
+/*---------------------------------------------------------------------------*
+ * Initialization for Down line LoaDable Fonts
+ *---------------------------------------------------------------------------*/
+static void
+init_dld(struct video_state *svsp)
+{
+ register int i;
+
+ svsp->dld_dscsi = 0;
+ svsp->dld_sixel_lower = 0;
+ svsp->dld_sixelli = 0;
+ svsp->dld_sixelui = 0;
+
+ for(i = 0;i < MAXSIXEL;i++)
+ svsp->sixel.lower[i] = svsp->sixel.upper[i] = 0;
+}
+
+/*---------------------------------------------------------------------------*
+ * selective erase a region
+ *---------------------------------------------------------------------------*/
+static void
+selective_erase(struct video_state *svsp, u_short *pcrtat, int length)
+{
+ register int i, j;
+
+ for(j = pcrtat - svsp->Crtat, i = 0;i < length;i++,pcrtat++)
+ {
+ if(!(svsp->decsca[INT_INDEX(j+i)] & (1 << BIT_INDEX(j+i))))
+ {
+ *pcrtat &= 0xFF00; /* Keep the video character attributes */
+ *pcrtat += ' '; /* Erase the character */
+ }
+ }
+}
+
+#endif /* NVT > 0 */
+
+/* ------------------------- E O F ------------------------------------------*/
+
diff --git a/sys/arch/i386/isa/pms.c b/sys/arch/i386/isa/pms.c
new file mode 100644
index 00000000000..8098b473968
--- /dev/null
+++ b/sys/arch/i386/isa/pms.c
@@ -0,0 +1,451 @@
+/* $NetBSD: pms.c,v 1.23 1995/10/05 22:06:54 mycroft Exp $ */
+
+/*-
+ * Copyright (c) 1994 Charles Hannum.
+ * Copyright (c) 1992, 1993 Erik Forsberg.
+ * All rights reserved.
+ *
+ * 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY ``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 I 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.
+ */
+
+/*
+ * XXXX
+ * This is a hack. This driver should really be combined with the
+ * keyboard driver, since they go through the same buffer and use the
+ * same I/O ports. Frobbing the mouse and keyboard at the same time
+ * may result in dropped characters and/or corrupted mouse events.
+ */
+
+#include "pms.h"
+#if NPMS > 1
+#error Only one PS/2 style mouse may be configured into your system.
+#endif
+
+#include <sys/param.h>
+#include <sys/kernel.h>
+#include <sys/systm.h>
+#include <sys/buf.h>
+#include <sys/malloc.h>
+#include <sys/ioctl.h>
+#include <sys/tty.h>
+#include <sys/file.h>
+#include <sys/select.h>
+#include <sys/proc.h>
+#include <sys/vnode.h>
+#include <sys/device.h>
+
+#include <machine/cpu.h>
+#include <machine/pio.h>
+#include <machine/mouse.h>
+
+#include <dev/isa/isavar.h>
+
+#define PMS_DATA 0x60 /* offset for data port, read-write */
+#define PMS_CNTRL 0x64 /* offset for control port, write-only */
+#define PMS_STATUS 0x64 /* offset for status port, read-only */
+#define PMS_NPORTS 8
+
+/* status bits */
+#define PMS_OBUF_FULL 0x01
+#define PMS_IBUF_FULL 0x02
+
+/* controller commands */
+#define PMS_INT_ENABLE 0x47 /* enable controller interrupts */
+#define PMS_INT_DISABLE 0x65 /* disable controller interrupts */
+#define PMS_AUX_ENABLE 0xa8 /* enable auxiliary port */
+#define PMS_AUX_DISABLE 0xa7 /* disable auxiliary port */
+#define PMS_AUX_TEST 0xa9 /* test auxiliary port */
+
+#define PMS_8042_CMD 0x65
+
+/* mouse commands */
+#define PMS_SET_SCALE11 0xe6 /* set scaling 1:1 */
+#define PMS_SET_SCALE21 0xe7 /* set scaling 2:1 */
+#define PMS_SET_RES 0xe8 /* set resolution */
+#define PMS_GET_SCALE 0xe9 /* get scaling factor */
+#define PMS_SET_STREAM 0xea /* set streaming mode */
+#define PMS_SET_SAMPLE 0xf3 /* set sampling rate */
+#define PMS_DEV_ENABLE 0xf4 /* mouse on */
+#define PMS_DEV_DISABLE 0xf5 /* mouse off */
+#define PMS_RESET 0xff /* reset */
+
+#define PMS_CHUNK 128 /* chunk size for read */
+#define PMS_BSIZE 1020 /* buffer size */
+
+struct pms_softc { /* driver status information */
+ struct device sc_dev;
+ void *sc_ih;
+
+ struct clist sc_q;
+ struct selinfo sc_rsel;
+ u_char sc_state; /* mouse driver state */
+#define PMS_OPEN 0x01 /* device is open */
+#define PMS_ASLP 0x02 /* waiting for mouse data */
+ u_char sc_status; /* mouse button status */
+ int sc_x, sc_y; /* accumulated motion in the X,Y axis */
+};
+
+int pmsprobe __P((struct device *, void *, void *));
+void pmsattach __P((struct device *, struct device *, void *));
+int pmsintr __P((void *));
+
+struct cfdriver pmscd = {
+ NULL, "pms", pmsprobe, pmsattach, DV_TTY, sizeof(struct pms_softc)
+};
+
+#define PMSUNIT(dev) (minor(dev))
+
+static inline void
+pms_flush()
+{
+ u_char c;
+
+ while (c = inb(PMS_STATUS) & 0x03)
+ if ((c & PMS_OBUF_FULL) == PMS_OBUF_FULL) {
+ /* XXX - delay is needed to prevent some keyboards from
+ wedging when the system boots */
+ delay(6);
+ (void) inb(PMS_DATA);
+ }
+}
+
+static inline void
+pms_dev_cmd(value)
+ u_char value;
+{
+
+ pms_flush();
+ outb(PMS_CNTRL, 0xd4);
+ pms_flush();
+ outb(PMS_DATA, value);
+}
+
+static inline void
+pms_aux_cmd(value)
+ u_char value;
+{
+
+ pms_flush();
+ outb(PMS_CNTRL, value);
+}
+
+static inline void
+pms_pit_cmd(value)
+ u_char value;
+{
+
+ pms_flush();
+ outb(PMS_CNTRL, 0x60);
+ pms_flush();
+ outb(PMS_DATA, value);
+}
+
+int
+pmsprobe(parent, match, aux)
+ struct device *parent;
+ void *match, *aux;
+{
+ struct isa_attach_args *ia = aux;
+ u_char x;
+
+ if (ia->ia_iobase != 0x60)
+ return 0;
+
+ pms_dev_cmd(PMS_RESET);
+ pms_aux_cmd(PMS_AUX_TEST);
+ delay(1000);
+ x = inb(PMS_DATA);
+ pms_pit_cmd(PMS_INT_DISABLE);
+ if (x & 0x04)
+ return 0;
+
+ ia->ia_iosize = PMS_NPORTS;
+ ia->ia_msize = 0;
+ return 1;
+}
+
+void
+pmsattach(parent, self, aux)
+ struct device *parent, *self;
+ void *aux;
+{
+ struct pms_softc *sc = (void *)self;
+ struct isa_attach_args *ia = aux;
+
+ printf("\n");
+
+ /* Other initialization was done by pmsprobe. */
+ sc->sc_state = 0;
+
+ sc->sc_ih = isa_intr_establish(ia->ia_irq, ISA_IST_EDGE, ISA_IPL_TTY,
+ pmsintr, sc);
+}
+
+int
+pmsopen(dev, flag)
+ dev_t dev;
+ int flag;
+{
+ int unit = PMSUNIT(dev);
+ struct pms_softc *sc;
+
+ if (unit >= pmscd.cd_ndevs)
+ return ENXIO;
+ sc = pmscd.cd_devs[unit];
+ if (!sc)
+ return ENXIO;
+
+ if (sc->sc_state & PMS_OPEN)
+ return EBUSY;
+
+ if (clalloc(&sc->sc_q, PMS_BSIZE, 0) == -1)
+ return ENOMEM;
+
+ sc->sc_state |= PMS_OPEN;
+ sc->sc_status = 0;
+ sc->sc_x = sc->sc_y = 0;
+
+ /* Enable interrupts. */
+ pms_dev_cmd(PMS_DEV_ENABLE);
+ pms_aux_cmd(PMS_AUX_ENABLE);
+#if 0
+ pms_dev_cmd(PMS_SET_RES);
+ pms_dev_cmd(3); /* 8 counts/mm */
+ pms_dev_cmd(PMS_SET_SCALE21);
+ pms_dev_cmd(PMS_SET_SAMPLE);
+ pms_dev_cmd(100); /* 100 samples/sec */
+ pms_dev_cmd(PMS_SET_STREAM);
+#endif
+ pms_pit_cmd(PMS_INT_ENABLE);
+
+ return 0;
+}
+
+int
+pmsclose(dev, flag)
+ dev_t dev;
+ int flag;
+{
+ struct pms_softc *sc = pmscd.cd_devs[PMSUNIT(dev)];
+
+ /* Disable interrupts. */
+ pms_dev_cmd(PMS_DEV_DISABLE);
+ pms_pit_cmd(PMS_INT_DISABLE);
+ pms_aux_cmd(PMS_AUX_DISABLE);
+
+ sc->sc_state &= ~PMS_OPEN;
+
+ clfree(&sc->sc_q);
+
+ return 0;
+}
+
+int
+pmsread(dev, uio, flag)
+ dev_t dev;
+ struct uio *uio;
+ int flag;
+{
+ struct pms_softc *sc = pmscd.cd_devs[PMSUNIT(dev)];
+ int s;
+ int error;
+ size_t length;
+ u_char buffer[PMS_CHUNK];
+
+ /* Block until mouse activity occured. */
+
+ s = spltty();
+ while (sc->sc_q.c_cc == 0) {
+ if (flag & IO_NDELAY) {
+ splx(s);
+ return EWOULDBLOCK;
+ }
+ sc->sc_state |= PMS_ASLP;
+ if (error = tsleep((caddr_t)sc, PZERO | PCATCH, "pmsrea", 0)) {
+ sc->sc_state &= ~PMS_ASLP;
+ splx(s);
+ return error;
+ }
+ }
+ splx(s);
+
+ /* Transfer as many chunks as possible. */
+
+ while (sc->sc_q.c_cc > 0 && uio->uio_resid > 0) {
+ length = min(sc->sc_q.c_cc, uio->uio_resid);
+ if (length > sizeof(buffer))
+ length = sizeof(buffer);
+
+ /* Remove a small chunk from the input queue. */
+ (void) q_to_b(&sc->sc_q, buffer, length);
+
+ /* Copy the data to the user process. */
+ if (error = uiomove(buffer, length, uio))
+ break;
+ }
+
+ return error;
+}
+
+int
+pmsioctl(dev, cmd, addr, flag)
+ dev_t dev;
+ u_long cmd;
+ caddr_t addr;
+ int flag;
+{
+ struct pms_softc *sc = pmscd.cd_devs[PMSUNIT(dev)];
+ struct mouseinfo info;
+ int s;
+ int error;
+
+ switch (cmd) {
+ case MOUSEIOCREAD:
+ s = spltty();
+
+ info.status = sc->sc_status;
+ if (sc->sc_x || sc->sc_y)
+ info.status |= MOVEMENT;
+
+ if (sc->sc_x > 127)
+ info.xmotion = 127;
+ else if (sc->sc_x < -127)
+ /* Bounding at -127 avoids a bug in XFree86. */
+ info.xmotion = -127;
+ else
+ info.xmotion = sc->sc_x;
+
+ if (sc->sc_y > 127)
+ info.ymotion = 127;
+ else if (sc->sc_y < -127)
+ info.ymotion = -127;
+ else
+ info.ymotion = sc->sc_y;
+
+ /* Reset historical information. */
+ sc->sc_x = sc->sc_y = 0;
+ sc->sc_status &= ~BUTCHNGMASK;
+ ndflush(&sc->sc_q, sc->sc_q.c_cc);
+
+ splx(s);
+ error = copyout(&info, addr, sizeof(struct mouseinfo));
+ break;
+
+ default:
+ error = EINVAL;
+ break;
+ }
+
+ return error;
+}
+
+/* Masks for the first byte of a packet */
+#define PS2LBUTMASK 0x01
+#define PS2RBUTMASK 0x02
+#define PS2MBUTMASK 0x04
+
+int
+pmsintr(arg)
+ void *arg;
+{
+ struct pms_softc *sc = arg;
+ static int state = 0;
+ static u_char buttons;
+ u_char changed;
+ static char dx, dy;
+ u_char buffer[5];
+
+ if ((sc->sc_state & PMS_OPEN) == 0) {
+ /* Interrupts are not expected. Discard the byte. */
+ pms_flush();
+ return 0;
+ }
+
+ switch (state) {
+
+ case 0:
+ buttons = inb(PMS_DATA);
+ if ((buttons & 0xc0) == 0)
+ ++state;
+ break;
+
+ case 1:
+ dx = inb(PMS_DATA);
+ /* Bounding at -127 avoids a bug in XFree86. */
+ dx = (dx == -128) ? -127 : dx;
+ ++state;
+ break;
+
+ case 2:
+ dy = inb(PMS_DATA);
+ dy = (dy == -128) ? -127 : dy;
+ state = 0;
+
+ buttons = ((buttons & PS2LBUTMASK) << 2) |
+ ((buttons & (PS2RBUTMASK | PS2MBUTMASK)) >> 1);
+ changed = ((buttons ^ sc->sc_status) & BUTSTATMASK) << 3;
+ sc->sc_status = buttons | (sc->sc_status & ~BUTSTATMASK) | changed;
+
+ if (dx || dy || changed) {
+ /* Update accumulated movements. */
+ sc->sc_x += dx;
+ sc->sc_y += dy;
+
+ /* Add this event to the queue. */
+ buffer[0] = 0x80 | (buttons ^ BUTSTATMASK);
+ buffer[1] = dx;
+ buffer[2] = dy;
+ buffer[3] = buffer[4] = 0;
+ (void) b_to_q(buffer, sizeof buffer, &sc->sc_q);
+
+ if (sc->sc_state & PMS_ASLP) {
+ sc->sc_state &= ~PMS_ASLP;
+ wakeup((caddr_t)sc);
+ }
+ selwakeup(&sc->sc_rsel);
+ }
+
+ break;
+ }
+
+ return -1;
+}
+
+int
+pmsselect(dev, rw, p)
+ dev_t dev;
+ int rw;
+ struct proc *p;
+{
+ struct pms_softc *sc = pmscd.cd_devs[PMSUNIT(dev)];
+ int s;
+ int ret;
+
+ if (rw == FWRITE)
+ return 0;
+
+ s = spltty();
+ if (!sc->sc_q.c_cc) {
+ selrecord(p, &sc->sc_rsel);
+ ret = 0;
+ } else
+ ret = 1;
+ splx(s);
+
+ return ret;
+}
diff --git a/sys/arch/i386/isa/spkr.c b/sys/arch/i386/isa/spkr.c
new file mode 100644
index 00000000000..b2694ca1f37
--- /dev/null
+++ b/sys/arch/i386/isa/spkr.c
@@ -0,0 +1,514 @@
+/* $NetBSD: spkr.c,v 1.17 1994/10/30 21:44:18 cgd Exp $ */
+
+/*
+ * spkr.c -- device driver for console speaker on 80386
+ *
+ * v1.1 by Eric S. Raymond (esr@snark.thyrsus.com) Feb 1990
+ * modified for 386bsd by Andrew A. Chernov <ache@astral.msk.su>
+ * 386bsd only clean version, all SYSV stuff removed
+ * use hz value from param.c
+ */
+
+#include "speaker.h"
+#if NSPEAKER > 0
+
+#include <sys/param.h>
+#include <sys/kernel.h>
+#include <sys/errno.h>
+#include <sys/buf.h>
+#include <sys/uio.h>
+
+#include <machine/cpu.h>
+#include <machine/pio.h>
+#include <machine/spkr.h>
+
+#include <i386/isa/isareg.h>
+#include <i386/isa/timerreg.h>
+#include <i386/isa/spkrreg.h>
+
+/**************** MACHINE DEPENDENT PART STARTS HERE *************************
+ *
+ * This section defines a function tone() which causes a tone of given
+ * frequency and duration from the 80x86's console speaker.
+ * Another function endtone() is defined to force sound off, and there is
+ * also a rest() entry point to do pauses.
+ *
+ * Audible sound is generated using the Programmable Interval Timer (PIT) and
+ * Programmable Peripheral Interface (PPI) attached to the 80x86's speaker. The
+ * PPI controls whether sound is passed through at all; the PIT's channel 2 is
+ * used to generate clicks (a square wave) of whatever frequency is desired.
+ */
+
+/*
+ * Magic numbers for timer control.
+ */
+#define PIT_MODE (TIMER_SEL2|TIMER_16BIT|TIMER_SQWAVE)
+
+void
+speakerattach()
+{
+}
+
+static int endtone()
+/* turn off the speaker, ending current tone */
+{
+ wakeup((caddr_t)endtone);
+ outb(PITAUX_PORT, inb(PITAUX_PORT) & ~PIT_SPKR);
+}
+
+static void tone(hz, ticks)
+/* emit tone of frequency hz for given number of ticks */
+unsigned int hz, ticks;
+{
+ unsigned int divisor = TIMER_DIV(hz);
+ int sps;
+
+#ifdef DEBUG
+ printf("tone: hz=%d ticks=%d\n", hz, ticks);
+#endif /* DEBUG */
+
+ /* set timer to generate clicks at given frequency in Hertz */
+ sps = spltty();
+ outb(TIMER_MODE, PIT_MODE); /* prepare timer */
+ outb(TIMER_CNTR2, (unsigned char) divisor); /* send lo byte */
+ outb(TIMER_CNTR2, (divisor >> 8)); /* send hi byte */
+ splx(sps);
+
+ /* turn the speaker on */
+ outb(PITAUX_PORT, inb(PITAUX_PORT) | PIT_SPKR);
+
+ /*
+ * Set timeout to endtone function, then give up the timeslice.
+ * This is so other processes can execute while the tone is being
+ * emitted.
+ */
+ timeout((caddr_t)endtone, (caddr_t)NULL, ticks);
+ sleep((caddr_t)endtone, PZERO - 1);
+}
+
+static int endrest()
+/* end a rest */
+{
+ wakeup((caddr_t)endrest);
+}
+
+static void rest(ticks)
+/* rest for given number of ticks */
+int ticks;
+{
+ /*
+ * Set timeout to endrest function, then give up the timeslice.
+ * This is so other processes can execute while the rest is being
+ * waited out.
+ */
+#ifdef DEBUG
+ printf("rest: %d\n", ticks);
+#endif /* DEBUG */
+ timeout((caddr_t)endrest, (caddr_t)NULL, ticks);
+ sleep((caddr_t)endrest, PZERO - 1);
+}
+
+/**************** PLAY STRING INTERPRETER BEGINS HERE **********************
+ *
+ * Play string interpretation is modelled on IBM BASIC 2.0's PLAY statement;
+ * M[LNS] are missing and the ~ synonym and octave-tracking facility is added.
+ * Requires tone(), rest(), and endtone(). String play is not interruptible
+ * except possibly at physical block boundaries.
+ */
+
+typedef int bool;
+#define TRUE 1
+#define FALSE 0
+
+#define toupper(c) ((c) - ' ' * (((c) >= 'a') && ((c) <= 'z')))
+#define isdigit(c) (((c) >= '0') && ((c) <= '9'))
+#define dtoi(c) ((c) - '0')
+
+static int octave; /* currently selected octave */
+static int whole; /* whole-note time at current tempo, in ticks */
+static int value; /* whole divisor for note time, quarter note = 1 */
+static int fill; /* controls spacing of notes */
+static bool octtrack; /* octave-tracking on? */
+static bool octprefix; /* override current octave-tracking state? */
+
+/*
+ * Magic number avoidance...
+ */
+#define SECS_PER_MIN 60 /* seconds per minute */
+#define WHOLE_NOTE 4 /* quarter notes per whole note */
+#define MIN_VALUE 64 /* the most we can divide a note by */
+#define DFLT_VALUE 4 /* default value (quarter-note) */
+#define FILLTIME 8 /* for articulation, break note in parts */
+#define STACCATO 6 /* 6/8 = 3/4 of note is filled */
+#define NORMAL 7 /* 7/8ths of note interval is filled */
+#define LEGATO 8 /* all of note interval is filled */
+#define DFLT_OCTAVE 4 /* default octave */
+#define MIN_TEMPO 32 /* minimum tempo */
+#define DFLT_TEMPO 120 /* default tempo */
+#define MAX_TEMPO 255 /* max tempo */
+#define NUM_MULT 3 /* numerator of dot multiplier */
+#define DENOM_MULT 2 /* denominator of dot multiplier */
+
+/* letter to half-tone: A B C D E F G */
+static int notetab[8] = {9, 11, 0, 2, 4, 5, 7};
+
+/*
+ * This is the American Standard A440 Equal-Tempered scale with frequencies
+ * rounded to nearest integer. Thank Goddess for the good ol' CRC Handbook...
+ * our octave 0 is standard octave 2.
+ */
+#define OCTAVE_NOTES 12 /* semitones per octave */
+static int pitchtab[] =
+{
+/* C C# D D# E F F# G G# A A# B*/
+/* 0 */ 65, 69, 73, 78, 82, 87, 93, 98, 103, 110, 117, 123,
+/* 1 */ 131, 139, 147, 156, 165, 175, 185, 196, 208, 220, 233, 247,
+/* 2 */ 262, 277, 294, 311, 330, 349, 370, 392, 415, 440, 466, 494,
+/* 3 */ 523, 554, 587, 622, 659, 698, 740, 784, 831, 880, 932, 988,
+/* 4 */ 1047, 1109, 1175, 1245, 1319, 1397, 1480, 1568, 1661, 1760, 1865, 1975,
+/* 5 */ 2093, 2217, 2349, 2489, 2637, 2794, 2960, 3136, 3322, 3520, 3729, 3951,
+/* 6 */ 4186, 4435, 4698, 4978, 5274, 5588, 5920, 6272, 6644, 7040, 7459, 7902,
+};
+
+static void playinit()
+{
+ octave = DFLT_OCTAVE;
+ whole = (hz * SECS_PER_MIN * WHOLE_NOTE) / DFLT_TEMPO;
+ fill = NORMAL;
+ value = DFLT_VALUE;
+ octtrack = FALSE;
+ octprefix = TRUE; /* act as though there was an initial O(n) */
+}
+
+static void playtone(pitch, value, sustain)
+/* play tone of proper duration for current rhythm signature */
+int pitch, value, sustain;
+{
+ register int sound, silence, snum = 1, sdenom = 1;
+
+ /* this weirdness avoids floating-point arithmetic */
+ for (; sustain; sustain--)
+ {
+ snum *= NUM_MULT;
+ sdenom *= DENOM_MULT;
+ }
+
+ if (pitch == -1)
+ rest(whole * snum / (value * sdenom));
+ else
+ {
+ sound = (whole * snum) / (value * sdenom)
+ - (whole * (FILLTIME - fill)) / (value * FILLTIME);
+ silence = whole * (FILLTIME-fill) * snum / (FILLTIME * value * sdenom);
+
+#ifdef DEBUG
+ printf("playtone: pitch %d for %d ticks, rest for %d ticks\n",
+ pitch, sound, silence);
+#endif /* DEBUG */
+
+ tone(pitchtab[pitch], sound);
+ if (fill != LEGATO)
+ rest(silence);
+ }
+}
+
+static int abs(n)
+int n;
+{
+ if (n < 0)
+ return(-n);
+ else
+ return(n);
+}
+
+static void playstring(cp, slen)
+/* interpret and play an item from a notation string */
+char *cp;
+size_t slen;
+{
+ int pitch, lastpitch = OCTAVE_NOTES * DFLT_OCTAVE;
+
+#define GETNUM(cp, v) for(v=0; isdigit(cp[1]) && slen > 0; ) \
+ {v = v * 10 + (*++cp - '0'); slen--;}
+ for (; slen--; cp++)
+ {
+ int sustain, timeval, tempo;
+ register char c = toupper(*cp);
+
+#ifdef DEBUG
+ printf("playstring: %c (%x)\n", c, c);
+#endif /* DEBUG */
+
+ switch (c)
+ {
+ case 'A': case 'B': case 'C': case 'D': case 'E': case 'F': case 'G':
+
+ /* compute pitch */
+ pitch = notetab[c - 'A'] + octave * OCTAVE_NOTES;
+
+ /* this may be followed by an accidental sign */
+ if (cp[1] == '#' || cp[1] == '+')
+ {
+ ++pitch;
+ ++cp;
+ slen--;
+ }
+ else if (cp[1] == '-')
+ {
+ --pitch;
+ ++cp;
+ slen--;
+ }
+
+ /*
+ * If octave-tracking mode is on, and there has been no octave-
+ * setting prefix, find the version of the current letter note
+ * closest to the last regardless of octave.
+ */
+ if (octtrack && !octprefix)
+ {
+ if (abs(pitch-lastpitch) > abs(pitch+OCTAVE_NOTES-lastpitch))
+ {
+ ++octave;
+ pitch += OCTAVE_NOTES;
+ }
+
+ if (abs(pitch-lastpitch) > abs((pitch-OCTAVE_NOTES)-lastpitch))
+ {
+ --octave;
+ pitch -= OCTAVE_NOTES;
+ }
+ }
+ octprefix = FALSE;
+ lastpitch = pitch;
+
+ /* ...which may in turn be followed by an override time value */
+ GETNUM(cp, timeval);
+ if (timeval <= 0 || timeval > MIN_VALUE)
+ timeval = value;
+
+ /* ...and/or sustain dots */
+ for (sustain = 0; cp[1] == '.'; cp++)
+ {
+ slen--;
+ sustain++;
+ }
+
+ /* time to emit the actual tone */
+ playtone(pitch, timeval, sustain);
+ break;
+
+ case 'O':
+ if (cp[1] == 'N' || cp[1] == 'n')
+ {
+ octprefix = octtrack = FALSE;
+ ++cp;
+ slen--;
+ }
+ else if (cp[1] == 'L' || cp[1] == 'l')
+ {
+ octtrack = TRUE;
+ ++cp;
+ slen--;
+ }
+ else
+ {
+ GETNUM(cp, octave);
+ if (octave >= sizeof(pitchtab) / OCTAVE_NOTES)
+ octave = DFLT_OCTAVE;
+ octprefix = TRUE;
+ }
+ break;
+
+ case '>':
+ if (octave < sizeof(pitchtab) / OCTAVE_NOTES - 1)
+ octave++;
+ octprefix = TRUE;
+ break;
+
+ case '<':
+ if (octave > 0)
+ octave--;
+ octprefix = TRUE;
+ break;
+
+ case 'N':
+ GETNUM(cp, pitch);
+ for (sustain = 0; cp[1] == '.'; cp++)
+ {
+ slen--;
+ sustain++;
+ }
+ playtone(pitch - 1, value, sustain);
+ break;
+
+ case 'L':
+ GETNUM(cp, value);
+ if (value <= 0 || value > MIN_VALUE)
+ value = DFLT_VALUE;
+ break;
+
+ case 'P':
+ case '~':
+ /* this may be followed by an override time value */
+ GETNUM(cp, timeval);
+ if (timeval <= 0 || timeval > MIN_VALUE)
+ timeval = value;
+ for (sustain = 0; cp[1] == '.'; cp++)
+ {
+ slen--;
+ sustain++;
+ }
+ playtone(-1, timeval, sustain);
+ break;
+
+ case 'T':
+ GETNUM(cp, tempo);
+ if (tempo < MIN_TEMPO || tempo > MAX_TEMPO)
+ tempo = DFLT_TEMPO;
+ whole = (hz * SECS_PER_MIN * WHOLE_NOTE) / tempo;
+ break;
+
+ case 'M':
+ if (cp[1] == 'N' || cp[1] == 'n')
+ {
+ fill = NORMAL;
+ ++cp;
+ slen--;
+ }
+ else if (cp[1] == 'L' || cp[1] == 'l')
+ {
+ fill = LEGATO;
+ ++cp;
+ slen--;
+ }
+ else if (cp[1] == 'S' || cp[1] == 's')
+ {
+ fill = STACCATO;
+ ++cp;
+ slen--;
+ }
+ break;
+ }
+ }
+}
+
+/******************* UNIX DRIVER HOOKS BEGIN HERE **************************
+ *
+ * This section implements driver hooks to run playstring() and the tone(),
+ * endtone(), and rest() functions defined above.
+ */
+
+static int spkr_active; /* exclusion flag */
+static struct buf *spkr_inbuf; /* incoming buf */
+
+int spkropen(dev)
+dev_t dev;
+{
+#ifdef DEBUG
+ printf("spkropen: entering with dev = %x\n", dev);
+#endif /* DEBUG */
+
+ if (minor(dev) != 0)
+ return(ENXIO);
+ else if (spkr_active)
+ return(EBUSY);
+ else
+ {
+ playinit();
+ spkr_inbuf = geteblk(DEV_BSIZE);
+ spkr_active = 1;
+ }
+ return(0);
+}
+
+int spkrwrite(dev, uio)
+dev_t dev;
+struct uio *uio;
+{
+ register unsigned n;
+ char *cp;
+ int error;
+#ifdef DEBUG
+ printf("spkrwrite: entering with dev = %x, count = %d\n",
+ dev, uio->uio_resid);
+#endif /* DEBUG */
+
+ if (minor(dev) != 0)
+ return(ENXIO);
+ else
+ {
+ n = min(DEV_BSIZE, uio->uio_resid);
+ cp = spkr_inbuf->b_data;
+ error = uiomove(cp, n, uio);
+ if (!error)
+ playstring(cp, n);
+ return(error);
+ }
+}
+
+int spkrclose(dev)
+dev_t dev;
+{
+#ifdef DEBUG
+ printf("spkrclose: entering with dev = %x\n", dev);
+#endif /* DEBUG */
+
+ if (minor(dev) != 0)
+ return(ENXIO);
+ else
+ {
+ endtone();
+ brelse(spkr_inbuf);
+ spkr_active = 0;
+ }
+ return(0);
+}
+
+int spkrioctl(dev, cmd, data, flag, p)
+dev_t dev;
+u_long cmd;
+caddr_t data;
+int flag;
+struct proc *p;
+{
+#ifdef DEBUG
+ printf("spkrioctl: entering with dev = %x, cmd = %lx\n", dev, cmd);
+#endif /* DEBUG */
+
+ if (minor(dev) != 0)
+ return(ENXIO);
+ else if (cmd == SPKRTONE)
+ {
+ tone_t *tp = (tone_t *)data;
+
+ if (tp->frequency == 0)
+ rest(tp->duration);
+ else
+ tone(tp->frequency, tp->duration);
+ }
+ else if (cmd == SPKRTUNE)
+ {
+ tone_t *tp = (tone_t *)(*(caddr_t *)data);
+ tone_t ttp;
+ int error;
+
+ for (; ; tp++) {
+ error = copyin(tp, &ttp, sizeof(tone_t));
+ if (error)
+ return(error);
+ if (ttp.duration == 0)
+ break;
+ if (ttp.frequency == 0)
+ rest(ttp.duration);
+ else
+ tone(ttp.frequency, ttp.duration);
+ }
+ }
+ else
+ return(EINVAL);
+ return(0);
+}
+
+#endif /* NSPEAKER > 0 */
+/* spkr.c ends here */
diff --git a/sys/arch/i386/isa/spkrreg.h b/sys/arch/i386/isa/spkrreg.h
new file mode 100644
index 00000000000..af1df50e2ad
--- /dev/null
+++ b/sys/arch/i386/isa/spkrreg.h
@@ -0,0 +1,11 @@
+/* $NetBSD: spkrreg.h,v 1.2 1994/10/27 04:18:16 cgd Exp $ */
+
+/*
+ * PIT port addresses and speaker control values
+ */
+
+#define PITAUX_PORT 0x61 /* port of Programmable Peripheral Interface */
+#define PIT_ENABLETMR2 0x01 /* Enable timer/counter 2 */
+#define PIT_SPKRDATA 0x02 /* Direct to speaker */
+
+#define PIT_SPKR (PIT_ENABLETMR2|PIT_SPKRDATA)
diff --git a/sys/arch/i386/isa/timerreg.h b/sys/arch/i386/isa/timerreg.h
new file mode 100644
index 00000000000..996834cadca
--- /dev/null
+++ b/sys/arch/i386/isa/timerreg.h
@@ -0,0 +1,100 @@
+/* $NetBSD: timerreg.h,v 1.4 1994/10/27 04:18:17 cgd Exp $ */
+
+/*-
+ * Copyright (c) 1993 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * 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.
+ */
+
+/*
+ * Register definitions for the Intel 8253 Programmable Interval Timer.
+ *
+ * This chip has three independent 16-bit down counters that can be
+ * read on the fly. There are three mode registers and three countdown
+ * registers. The countdown registers are addressed directly, via the
+ * first three I/O ports. The three mode registers are accessed via
+ * the fourth I/O port, with two bits in the mode byte indicating the
+ * register. (Why are hardware interfaces always so braindead?).
+ *
+ * To write a value into the countdown register, the mode register
+ * is first programmed with a command indicating the which byte of
+ * the two byte register is to be modified. The three possibilities
+ * are load msb (TMR_MR_MSB), load lsb (TMR_MR_LSB), or load lsb then
+ * msb (TMR_MR_BOTH).
+ *
+ * To read the current value ("on the fly") from the countdown register,
+ * you write a "latch" command into the mode register, then read the stable
+ * value from the corresponding I/O port. For example, you write
+ * TMR_MR_LATCH into the corresponding mode register. Presumably,
+ * after doing this, a write operation to the I/O port would result
+ * in undefined behavior (but hopefully not fry the chip).
+ * Reading in this manner has no side effects.
+ *
+ * The outputs of the three timers are connected as follows:
+ *
+ * timer 0 -> irq 0
+ * timer 1 -> dma chan 0 (for dram refresh)
+ * timer 2 -> speaker (via keyboard controller)
+ *
+ * Timer 0 is used to call hardclock.
+ * Timer 2 is used to generate console beeps.
+ */
+
+/*
+ * Frequency of all three count-down timers; (TIMER_FREQ/freq) is the
+ * appropriate count to generate a frequency of freq hz.
+ */
+#ifndef TIMER_FREQ
+#define TIMER_FREQ 1193182
+#endif
+#define TIMER_DIV(x) ((TIMER_FREQ+(x)/2)/(x))
+
+/*
+ * Macros for specifying values to be written into a mode register.
+ */
+#define TIMER_CNTR0 (IO_TIMER1 + 0) /* timer 0 counter port */
+#define TIMER_CNTR1 (IO_TIMER1 + 1) /* timer 1 counter port */
+#define TIMER_CNTR2 (IO_TIMER1 + 2) /* timer 2 counter port */
+#define TIMER_MODE (IO_TIMER1 + 3) /* timer mode port */
+#define TIMER_SEL0 0x00 /* select counter 0 */
+#define TIMER_SEL1 0x40 /* select counter 1 */
+#define TIMER_SEL2 0x80 /* select counter 2 */
+#define TIMER_INTTC 0x00 /* mode 0, intr on terminal cnt */
+#define TIMER_ONESHOT 0x02 /* mode 1, one shot */
+#define TIMER_RATEGEN 0x04 /* mode 2, rate generator */
+#define TIMER_SQWAVE 0x06 /* mode 3, square wave */
+#define TIMER_SWSTROBE 0x08 /* mode 4, s/w triggered strobe */
+#define TIMER_HWSTROBE 0x0a /* mode 5, h/w triggered strobe */
+#define TIMER_LATCH 0x00 /* latch counter for reading */
+#define TIMER_LSB 0x10 /* r/w counter LSB */
+#define TIMER_MSB 0x20 /* r/w counter MSB */
+#define TIMER_16BIT 0x30 /* r/w counter 16 bits, LSB first */
+#define TIMER_BCD 0x01 /* count in BCD */
+
diff --git a/sys/arch/i386/isa/vector.s b/sys/arch/i386/isa/vector.s
new file mode 100644
index 00000000000..0558ebbde2b
--- /dev/null
+++ b/sys/arch/i386/isa/vector.s
@@ -0,0 +1,365 @@
+/* $NetBSD: vector.s,v 1.29 1995/05/08 18:00:20 mycroft Exp $ */
+
+/*
+ * Copyright (c) 1993, 1994, 1995 Charles M. Hannum. All rights reserved.
+ *
+ * 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 Charles M. Hannum.
+ * 4. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ */
+
+#include <i386/isa/icu.h>
+#include <dev/isa/isareg.h>
+
+#define ICU_HARDWARE_MASK
+
+/*
+ * These macros are fairly self explanatory. If ICU_SPECIAL_MASK_MODE is
+ * defined, we try to take advantage of the ICU's `special mask mode' by only
+ * EOIing the interrupts on return. This avoids the requirement of masking and
+ * unmasking. We can't do this without special mask mode, because the ICU
+ * would also hold interrupts that it thinks are of lower priority.
+ *
+ * Many machines do not support special mask mode, so by default we don't try
+ * to use it.
+ */
+
+#define IRQ_BIT(irq_num) (1 << ((irq_num) % 8))
+#define IRQ_BYTE(irq_num) ((irq_num) / 8)
+
+#ifdef ICU_SPECIAL_MASK_MODE
+
+#define ENABLE_ICU1(irq_num)
+#define ENABLE_ICU1_AND_2(irqnum) \
+ movb $(0x60|IRQ_SLAVE),%al /* specific EOI for IRQ2 */ ;\
+ outb %al,$IO_ICU1
+#define MASK(irq_num, icu)
+#define UNMASK(irq_num, icu) \
+ movb $(0x60|(irq_num%8)),%al /* specific EOI */ ;\
+ outb %al,$icu
+
+#else /* ICU_SPECIAL_MASK_MODE */
+
+#ifndef AUTO_EOI_1
+#define ENABLE_ICU1(irq_num) \
+ movb $(0x60|(irq_num%8)),%al /* specific EOI */ ;\
+ outb %al,$IO_ICU1
+#else
+#define ENABLE_ICU1(irq_num)
+#endif
+
+#ifndef AUTO_EOI_2
+#define ENABLE_ICU1_AND_2(irq_num) \
+ movb $(0x60|(irq_num%8)),%al /* specific EOI */ ;\
+ outb %al,$IO_ICU2 /* do the second ICU first */ ;\
+ movb $(0x60|IRQ_SLAVE),%al /* specific EOI for IRQ2 */ ;\
+ outb %al,$IO_ICU1
+#else
+#define ENABLE_ICU1_AND_2(irq_num)
+#endif
+
+#ifdef ICU_HARDWARE_MASK
+
+#define MASK(irq_num, icu) \
+ movb _imen + IRQ_BYTE(irq_num),%al ;\
+ orb $IRQ_BIT(irq_num),%al ;\
+ movb %al,_imen + IRQ_BYTE(irq_num) ;\
+ FASTER_NOP ;\
+ outb %al,$(icu+1)
+#define UNMASK(irq_num, icu) \
+ cli ;\
+ movb _imen + IRQ_BYTE(irq_num),%al ;\
+ andb $~IRQ_BIT(irq_num),%al ;\
+ movb %al,_imen + IRQ_BYTE(irq_num) ;\
+ FASTER_NOP ;\
+ outb %al,$(icu+1) ;\
+ sti
+
+#else /* ICU_HARDWARE_MASK */
+
+#define MASK(irq_num, icu)
+#define UNMASK(irq_num, icu)
+
+#endif /* ICU_HARDWARE_MASK */
+
+#endif /* ICU_SPECIAL_MASK_MODE */
+
+/*
+ * Macros for interrupt entry, call to handler, and exit.
+ *
+ * XXX
+ * The interrupt frame is set up to look like a trap frame. This may be a
+ * waste. The only handler which needs a frame is the clock handler, and it
+ * only needs a few bits. doreti() needs a trap frame for handling ASTs, but
+ * it could easily convert the frame on demand.
+ *
+ * The direct costs of setting up a trap frame are two pushl's (error code and
+ * trap number), an addl to get rid of these, and pushing and popping the
+ * callee-saved registers %esi, %edi, %ebx, and %ebp twice.
+ *
+ * If the interrupt frame is made more flexible, INTR can push %eax first and
+ * decide the ipending case with less overhead, e.g., by avoiding loading the
+ * segment registers.
+ *
+ * XXX
+ * Should we do a cld on every system entry to avoid the requirement for
+ * scattered cld's?
+ */
+
+ .globl _isa_strayintr
+
+/*
+ * Fast vectors.
+ *
+ * Like a normal vector, but run with all interrupts off. The handler is
+ * expected to be as fast as possible, and is expected to not change the
+ * interrupt flag. We pass an argument in like normal vectors, but we assume
+ * that a pointer to the frame is never required. There can be only one
+ * handler on a fast vector.
+ *
+ * XXX
+ * Note that we assume fast vectors don't do anything that would cause an AST
+ * or softintr; if so, it will be deferred until the next clock tick (or
+ * possibly sooner).
+ */
+#define FAST(irq_num, icu, enable_icus) \
+IDTVEC(fast/**/irq_num) ;\
+ pushl %eax /* save call-used registers */ ;\
+ pushl %ecx ;\
+ pushl %edx ;\
+ pushl %ds ;\
+ pushl %es ;\
+ movl $GSEL(GDATA_SEL, SEL_KPL),%eax ;\
+ movl %ax,%ds ;\
+ movl %ax,%es ;\
+ /* have to do this here because %eax is lost on call */ ;\
+ movl _intrhand + (irq_num) * 4,%eax ;\
+ incl IH_COUNT(%eax) ;\
+ pushl IH_ARG(%eax) ;\
+ call IH_FUN(%eax) ;\
+ enable_icus(irq_num) ;\
+ addl $4,%esp ;\
+ incl _cnt+V_INTR /* statistical info */ ;\
+ popl %es ;\
+ popl %ds ;\
+ popl %edx ;\
+ popl %ecx ;\
+ popl %eax ;\
+ iret
+
+FAST(0, IO_ICU1, ENABLE_ICU1)
+FAST(1, IO_ICU1, ENABLE_ICU1)
+FAST(2, IO_ICU1, ENABLE_ICU1)
+FAST(3, IO_ICU1, ENABLE_ICU1)
+FAST(4, IO_ICU1, ENABLE_ICU1)
+FAST(5, IO_ICU1, ENABLE_ICU1)
+FAST(6, IO_ICU1, ENABLE_ICU1)
+FAST(7, IO_ICU1, ENABLE_ICU1)
+FAST(8, IO_ICU2, ENABLE_ICU1_AND_2)
+FAST(9, IO_ICU2, ENABLE_ICU1_AND_2)
+FAST(10, IO_ICU2, ENABLE_ICU1_AND_2)
+FAST(11, IO_ICU2, ENABLE_ICU1_AND_2)
+FAST(12, IO_ICU2, ENABLE_ICU1_AND_2)
+FAST(13, IO_ICU2, ENABLE_ICU1_AND_2)
+FAST(14, IO_ICU2, ENABLE_ICU1_AND_2)
+FAST(15, IO_ICU2, ENABLE_ICU1_AND_2)
+
+/*
+ * Normal vectors.
+ *
+ * We cdr down the intrhand chain, calling each handler with its appropriate
+ * argument (0 meaning a pointer to the frame, for clock interrupts).
+ *
+ * The handler returns one of three values:
+ * 0 - This interrupt wasn't for me.
+ * 1 - This interrupt was for me.
+ * -1 - This interrupt might have been for me, but I don't know.
+ * If there are no handlers, or they all return 0, we flags it as a `stray'
+ * interrupt. On a system with level-triggered interrupts, we could terminate
+ * immediately when one of them returns 1; but this is a PC.
+ *
+ * On exit, we jump to doreti, to process soft interrupts and ASTs.
+ */
+#define INTR(irq_num, icu, enable_icus) \
+IDTVEC(intr/**/irq_num) ;\
+ pushl $0 /* dummy error code */ ;\
+ pushl $T_ASTFLT /* trap # for doing ASTs */ ;\
+ INTRENTRY ;\
+ MAKE_FRAME ;\
+ MASK(irq_num, icu) /* mask it in hardware */ ;\
+ enable_icus(irq_num) /* and allow other intrs */ ;\
+ testb $IRQ_BIT(irq_num),_cpl + IRQ_BYTE(irq_num) ;\
+ jnz _Xhold/**/irq_num /* currently masked; hold it */ ;\
+_Xresume/**/irq_num/**/: ;\
+ movl _cpl,%eax /* cpl to restore on exit */ ;\
+ pushl %eax ;\
+ orl _intrmask + (irq_num) * 4,%eax ;\
+ movl %eax,_cpl /* add in this intr's mask */ ;\
+ sti /* safe to take intrs now */ ;\
+ movl _intrhand + (irq_num) * 4,%ebx /* head of chain */ ;\
+ testl %ebx,%ebx ;\
+ jz _Xstray/**/irq_num /* no handlears; we're stray */ ;\
+ STRAY_INITIALIZE /* nobody claimed it yet */ ;\
+7: movl IH_ARG(%ebx),%eax /* get handler arg */ ;\
+ testl %eax,%eax ;\
+ jnz 4f ;\
+ movl %esp,%eax /* 0 means frame pointer */ ;\
+4: pushl %eax ;\
+ call IH_FUN(%ebx) /* call it */ ;\
+ addl $4,%esp /* toss the arg */ ;\
+ STRAY_INTEGRATE /* maybe he claimed it */ ;\
+ incl IH_COUNT(%ebx) /* count the intrs */ ;\
+ movl IH_NEXT(%ebx),%ebx /* next handler in chain */ ;\
+ testl %ebx,%ebx ;\
+ jnz 7b ;\
+ STRAY_TEST /* see if it's a stray */ ;\
+5: UNMASK(irq_num, icu) /* unmask it in hardware */ ;\
+ INTREXIT /* lower spl and do ASTs */ ;\
+IDTVEC(stray/**/irq_num) ;\
+ pushl $irq_num ;\
+ call _isa_strayintr ;\
+ addl $4,%esp ;\
+ jmp 5b ;\
+IDTVEC(hold/**/irq_num) ;\
+ orb $IRQ_BIT(irq_num),_ipending + IRQ_BYTE(irq_num) ;\
+ INTRFASTEXIT
+
+#if defined(DEBUG) && defined(notdef)
+#define STRAY_INITIALIZE \
+ xorl %esi,%esi
+#define STRAY_INTEGRATE \
+ orl %eax,%esi
+#define STRAY_TEST \
+ testl %esi,%esi ;\
+ jz _Xstray/**/irq_num
+#else /* !DEBUG */
+#define STRAY_INITIALIZE
+#define STRAY_INTEGRATE
+#define STRAY_TEST
+#endif /* DEBUG */
+
+#ifdef DDB
+#define MAKE_FRAME \
+ leal -8(%esp),%ebp
+#else /* !DDB */
+#define MAKE_FRAME
+#endif /* DDB */
+
+INTR(0, IO_ICU1, ENABLE_ICU1)
+INTR(1, IO_ICU1, ENABLE_ICU1)
+INTR(2, IO_ICU1, ENABLE_ICU1)
+INTR(3, IO_ICU1, ENABLE_ICU1)
+INTR(4, IO_ICU1, ENABLE_ICU1)
+INTR(5, IO_ICU1, ENABLE_ICU1)
+INTR(6, IO_ICU1, ENABLE_ICU1)
+INTR(7, IO_ICU1, ENABLE_ICU1)
+INTR(8, IO_ICU2, ENABLE_ICU1_AND_2)
+INTR(9, IO_ICU2, ENABLE_ICU1_AND_2)
+INTR(10, IO_ICU2, ENABLE_ICU1_AND_2)
+INTR(11, IO_ICU2, ENABLE_ICU1_AND_2)
+INTR(12, IO_ICU2, ENABLE_ICU1_AND_2)
+INTR(13, IO_ICU2, ENABLE_ICU1_AND_2)
+INTR(14, IO_ICU2, ENABLE_ICU1_AND_2)
+INTR(15, IO_ICU2, ENABLE_ICU1_AND_2)
+
+/*
+ * Recursive interrupts.
+ *
+ * This is a somewhat nasty hack to deal with resuming interrupts from splx().
+ * We can't just jump to the resume point, because some handlers require an
+ * interrupt frame. Instead, we just recursively interrupt.
+ *
+ * On entry, %esi contains a pointer to where we need to return. This is a
+ * bit faster than a call/ret/jmp to continue the loop.
+ *
+ * XXX
+ * It might be a little faster to build the interrupt frame manually and jump
+ * to the resume point. The code would be larger, though.
+ */
+#define RECURSE(irq_num) \
+IDTVEC(recurse/**/irq_num) ;\
+ int $(ICU_OFFSET + irq_num) ;\
+ jmp %esi
+
+RECURSE(0)
+RECURSE(1)
+RECURSE(2)
+RECURSE(3)
+RECURSE(4)
+RECURSE(5)
+RECURSE(6)
+RECURSE(7)
+RECURSE(8)
+RECURSE(9)
+RECURSE(10)
+RECURSE(11)
+RECURSE(12)
+RECURSE(13)
+RECURSE(14)
+RECURSE(15)
+
+/*
+ * These tables are used by the ISA configuration code.
+ */
+/* interrupt service routine entry points */
+IDTVEC(intr)
+ .long _Xintr0, _Xintr1, _Xintr2, _Xintr3, _Xintr4, _Xintr5, _Xintr6
+ .long _Xintr7, _Xintr8, _Xintr9, _Xintr10, _Xintr11, _Xintr12
+ .long _Xintr13, _Xintr14, _Xintr15
+/* fast interrupt routine entry points */
+IDTVEC(fast)
+ .long _Xfast0, _Xfast1, _Xfast2, _Xfast3, _Xfast4, _Xfast5, _Xfast6
+ .long _Xfast7, _Xfast8, _Xfast9, _Xfast10, _Xfast11, _Xfast12
+ .long _Xfast13, _Xfast14, _Xfast15
+
+/*
+ * These tables are used by doreti() and spllower().
+ */
+/* resume points for suspended interrupts */
+IDTVEC(resume)
+ .long _Xresume0, _Xresume1, _Xresume2, _Xresume3, _Xresume4
+ .long _Xresume5, _Xresume6, _Xresume7, _Xresume8, _Xresume9
+ .long _Xresume10, _Xresume11, _Xresume12, _Xresume13, _Xresume14
+ .long _Xresume15
+ /* for soft interrupts */
+ .long 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+ .long _Xsofttty, _Xsoftnet, _Xsoftclock
+/* fake interrupts to resume from splx() */
+IDTVEC(recurse)
+ .long _Xrecurse0, _Xrecurse1, _Xrecurse2, _Xrecurse3, _Xrecurse4
+ .long _Xrecurse5, _Xrecurse6, _Xrecurse7, _Xrecurse8, _Xrecurse9
+ .long _Xrecurse10, _Xrecurse11, _Xrecurse12, _Xrecurse13, _Xrecurse14
+ .long _Xrecurse15
+ /* for soft interrupts */
+ .long 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+ .long _Xsofttty, _Xsoftnet, _Xsoftclock
+
+/* Some bogus data, to keep vmstat happy, for now. */
+ .globl _intrnames, _eintrnames, _intrcnt, _eintrcnt
+_intrnames:
+ .long 0
+_eintrnames:
+_intrcnt:
+ .long 0
+_eintrcnt: