summaryrefslogtreecommitdiffstats
path: root/sys/i386/isa/pcvt
diff options
context:
space:
mode:
authorpeter <peter@FreeBSD.org>1999-01-01 08:23:23 +0000
committerpeter <peter@FreeBSD.org>1999-01-01 08:23:23 +0000
commite6cf3a438fea379bc695c779b175c508ca097243 (patch)
tree97ebf948b34be84395e40d16a1024cb7e7fd4d76 /sys/i386/isa/pcvt
parentd713c6aca4942e88e9afb66a012c176a3b3c93dd (diff)
downloadFreeBSD-src-e6cf3a438fea379bc695c779b175c508ca097243.zip
FreeBSD-src-e6cf3a438fea379bc695c779b175c508ca097243.tar.gz
Part 3 of the pcvt/voxware revival.
Reviewed by: core
Diffstat (limited to 'sys/i386/isa/pcvt')
-rw-r--r--sys/i386/isa/pcvt/pcvt_conf.h477
-rw-r--r--sys/i386/isa/pcvt/pcvt_drv.c1641
-rw-r--r--sys/i386/isa/pcvt/pcvt_ext.c2835
-rw-r--r--sys/i386/isa/pcvt/pcvt_hdr.h1418
-rw-r--r--sys/i386/isa/pcvt/pcvt_kbd.c3321
-rw-r--r--sys/i386/isa/pcvt/pcvt_kbd.h567
-rw-r--r--sys/i386/isa/pcvt/pcvt_out.c2182
-rw-r--r--sys/i386/isa/pcvt/pcvt_sup.c2216
-rw-r--r--sys/i386/isa/pcvt/pcvt_tbl.h475
-rw-r--r--sys/i386/isa/pcvt/pcvt_vtf.c2187
10 files changed, 17319 insertions, 0 deletions
diff --git a/sys/i386/isa/pcvt/pcvt_conf.h b/sys/i386/isa/pcvt/pcvt_conf.h
new file mode 100644
index 0000000..52387e6
--- /dev/null
+++ b/sys/i386/isa/pcvt/pcvt_conf.h
@@ -0,0 +1,477 @@
+/*
+ * 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.20, Last Edit-Date: [Sun Apr 2 18:57:45 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
+ *
+ *---------------------------------------------------------------------------*/
+
+/*---------------------------------------------------------------------------
+ *
+ * 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 0.8 : NetBSD0_8 defined in <sys/param.h>
+ * NetBSD 0.9 : NetBSD0_9 defined in <sys/param.h>
+ * 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):
+ *
+ *---------------------------------------------------------------------------*/
+
+#ifdef NetBSD0_8
+#define PCVT_NETBSD 8
+#endif
+
+#ifdef NetBSD0_9
+#define PCVT_NETBSD 9
+#endif
+
+#ifdef NetBSD1_0
+#if NetBSD1_0 > 1
+#define PCVT_NETBSD 199
+#else
+#define PCVT_NETBSD 100
+#endif
+#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 = 9 for NetBSD 0.9
+ * PCVT_NETBSD = 99 for PRE-1.0 NetBSD-current
+ * PCVT_NETBSD = 100 for NetBSD 1.0
+ * PCVT_NETBSD = 199 for PRE-2.0 NetBSD-current
+ *
+ *
+ *======================================================================*
+ * F r e e B S D *
+ *======================================================================*
+ *
+ * options "PCVT_FREEBSD=xxx" enables support for FreeBSD
+ *
+ * select:
+ * PCVT_FREEBSD = 102 for 1.0 release (actually 1.0.2)
+ * PCVT_FREEBSD = 110 for FreeBSD 1.1-Release
+ * PCVT_FREEBSD = 115 for FreeBSD 1.1.5.1-Release
+ * PCVT_FREEBSD = 200 for FreeBSD 2.0-Release
+ * PCVT_FREEBSD = 210 for FreeBSD 2.1-Release
+ *
+ */
+
+/* -------------------------------------------------------------------- */
+/* ---------------- 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 its 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_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
+
+#ifdef XSERVER
+
+#if !defined PCVT_USL_VT_COMPAT /* ---------- DEFAULT: ON ------------- */
+# define PCVT_USL_VT_COMPAT 1 /* this option enables multiple virtual */
+#elif PCVT_USL_VT_COMPAT != 0 /* screen support for XFree86. If set */
+# undef PCVT_USL_VT_COMPAT /* to off, support for a "classic" */
+# define PCVT_USL_VT_COMPAT 1 /* single screen only X server is */
+#endif /* compiled in. If enabled, most of the */
+ /* ioctl's from SYSV/USL are supported */
+ /* to run multiple X servers and/or */
+ /* character terminal sessions. */
+
+#endif /* XSERVER */
+
+/*---------------------------------------------------------------------------*
+ * 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/i386/isa/pcvt/pcvt_drv.c b/sys/i386/isa/pcvt/pcvt_drv.c
new file mode 100644
index 0000000..99217c0
--- /dev/null
+++ b/sys/i386/isa/pcvt/pcvt_drv.c
@@ -0,0 +1,1641 @@
+/*
+ * 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.20, Last Edit-Date: [Sun Apr 2 19:09:19 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
+ *
+ *---------------------------------------------------------------------------*/
+
+#include "vt.h"
+#if NVT > 0
+
+#include "opt_devfs.h"
+
+#define EXTERN /* allocate mem */
+
+#include <i386/isa/pcvt/pcvt_hdr.h> /* global include */
+#ifdef DEVFS
+#include <sys/devfsext.h>
+#if !defined(MAXCONS)
+#define MAXCONS 16
+#endif
+static void *pcvt_devfs_token[MAXCONS];
+#endif /*DEVFS*/
+
+#if PCVT_FREEBSD >= 200
+#include <machine/stdarg.h>
+#else
+#include "machine/stdarg.h"
+#endif
+
+extern int getchar __P((void));
+
+#if PCVT_NETBSD
+ extern u_short *Crtat;
+#endif /* PCVT_NETBSD */
+
+static unsigned __debug = 0; /*0xffe */
+static __color;
+static nrow;
+
+static void vgapelinit(void); /* read initial VGA DAC palette */
+
+#if defined XSERVER && !PCVT_USL_VT_COMPAT
+static int pcvt_xmode_set(int on, struct proc *p); /* initialize for X mode */
+#endif /* XSERVER && !PCVT_USL_VT_COMPAT */
+
+static d_open_t pcopen;
+static d_close_t pcclose;
+static d_read_t pcread;
+static d_write_t pcwrite;
+static d_ioctl_t pcioctl;
+static d_devtotty_t pcdevtotty;
+static d_mmap_t pcmmap;
+
+#define CDEV_MAJOR 12
+static struct cdevsw pc_cdevsw = {
+ pcopen, pcclose, pcread, pcwrite,
+ pcioctl, nullstop, noreset, pcdevtotty,
+ ttpoll, pcmmap, nostrategy, "vt",
+ NULL, -1, nodump, nopsize,
+ D_TTY,
+};
+
+#if PCVT_FREEBSD > 205
+struct tty *
+pcdevtotty(Dev_t dev)
+{
+ return get_pccons(dev);
+}
+
+#endif /* PCVT_FREEBSD > 205 */
+
+#if PCVT_NETBSD > 100 /* NetBSD-current Feb 20 1995 */
+int
+pcprobe(struct device *parent, void *match, void *aux)
+#else
+#if PCVT_NETBSD > 9
+int
+pcprobe(struct device *parent, struct device *self, void *aux)
+#else
+int
+pcprobe(struct isa_device *dev)
+#endif /* PCVT_NETBSD > 9 */
+#endif /* PCVT_NETBSD > 100 */
+{
+#ifdef _I386_ISA_KBDIO_H_
+ kbdc = kbdc_open(IO_KBD);
+
+ if(kbdc == NULL)
+ {
+ reset_keyboard = 0;
+ return 1;
+ }
+
+ reset_keyboard = 1; /* it's now safe to do kbd reset */
+#endif /* _I386_ISA_KBDIO_H_ */
+
+ kbd_code_init();
+
+#if PCVT_NETBSD > 9
+ ((struct isa_attach_args *)aux)->ia_iosize = 16;
+ return 1;
+#else
+#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;
+ static struct intrhand vthand;
+#else
+int
+pcattach(struct isa_device *dev)
+{
+#endif /* PCVT_NETBSD > 9 */
+
+#ifdef DEVFS
+ int vt;
+#endif /*DEVFS*/
+ 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
+ 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 */
+
+ }
+
+#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 = pc_tty[0];
+#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
+ {
+ dev_t dev = makedev(CDEV_MAJOR, 0);
+
+ cdevsw_add(&dev, &pc_cdevsw, NULL);
+ }
+
+#ifdef DEVFS
+ for(vt = 0; vt < MAXCONS; vt++) {
+ pcvt_devfs_token[vt] =
+ devfs_add_devswf(&pc_cdevsw, vt,
+ DV_CHR, 0, 0, 0600, "ttyv%r", vt );
+ }
+#endif DEVFS
+#endif /* PCVT_FREEBSD > 205 */
+
+#if PCVT_NETBSD > 9
+
+ vthand.ih_fun = pcrint;
+ vthand.ih_arg = 0;
+ vthand.ih_level = IPL_TTY;
+
+#if (PCVT_NETBSD > 100) && defined(IST_EDGE)
+ intr_establish(ia->ia_irq, IST_EDGE, &vthand);
+#else /* PCVT_NETBSD > 100 */
+ intr_establish(ia->ia_irq, &vthand);
+#endif /* PCVT_NETBSD > 100 */
+
+#else /* PCVT_NETBSD > 9 */
+
+ dev->id_ointr = pcrint;
+
+ 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(pc_tty[i]);
+}
+
+#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)
+ {
+
+#ifdef TS_WOPEN /* not (FreeBSD-1.1.5 or FreeBSD some time after 2.0.5) */
+ tp->t_state |= TS_WOPEN;
+#endif
+
+ 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);
+ (*linesw[tp->t_line].l_modem)(tp, 1); /* fake connection */
+ winsz = 1; /* set winsize later */
+ }
+ else if (tp->t_state & TS_XCLUDE && p->p_ucred->cr_uid != 0)
+ return (EBUSY);
+
+#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)
+ {
+
+ /*
+ * 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);
+ }
+
+ 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_USL_VT_COMPAT
+#if PCVT_EMU_MOUSE
+
+ if(i == totalscreens)
+ return (0);
+
+#endif /* PCVT_EMU_MOUSE */
+
+ reset_usl_modes(vsx);
+
+#endif /* PCVT_USL_VT_COMPAT */
+
+ 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));
+}
+
+int
+pcioctl(Dev_t dev, u_long 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 PCVT_USL_VT_COMPAT
+
+ 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 */ ;
+ }
+
+#else /* PCVT_USL_VT_COMPAT */
+
+ switch(cmd)
+ {
+ case CONSOLE_X_MODE_ON:
+ return pcvt_xmode_set(1, p);
+
+ case CONSOLE_X_MODE_OFF:
+ return pcvt_xmode_set(0, p);
+
+ 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 /* PCVT_USL_VT_COMPAT */
+#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
+
+#if PCVT_NETBSD > 9 || PCVT_FREEBSD >= 200
+ if((error = (*linesw[tp->t_line].l_ioctl)(tp, cmd, data, flag, p))
+ != ENOIOCTL)
+ 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)) != ENOIOCTL)
+ return (error);
+#endif /* PCVT_NETBSD > 9 */
+
+ return (ENOTTY);
+}
+
+int
+pcmmap(Dev_t dev, vm_offset_t offset, int nprot)
+{
+ if (offset > 0x20000 - PAGE_SIZE)
+ return -1;
+ return i386_btop((0xa0000 + offset));
+}
+
+/*---------------------------------------------------------------------------*
+ *
+ * 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];
+static 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
+
+
+void
+pcrint(int unit)
+{
+
+#if PCVT_KBD_FIFO
+ u_char dt;
+ u_char ret = -1;
+
+# if PCVT_SLOW_INTERRUPT
+ int s;
+# endif
+
+# ifdef _I386_ISA_KBDIO_H_
+ int c;
+# endif
+
+#else /* !PCVT_KBD_FIFO */
+ u_char *cp;
+#endif /* PCVT_KBD_FIFO */
+
+ /*
+ * in case the keyboard was not plugged in while booting, kbdc
+ * was set to NULL at that time. When a keyboard IRQ occurs and
+ * kbdc is NULL, the keyboard was probably reconnected to the
+ * keyboard controller and we have to initialize the keyboard.
+ */
+
+ if(kbdc == NULL)
+ {
+ kbdc = kbdc_open(IO_KBD);
+ if(kbdc == NULL)
+ {
+ reset_keyboard = 0;
+ return;
+ }
+ reset_keyboard = 1;
+ kbd_code_init();
+ }
+
+#if PCVT_SCREENSAVER
+ pcvt_scrnsv_reset();
+#endif /* PCVT_SCREENSAVER */
+
+#if PCVT_KBD_FIFO
+ if (kbd_polling)
+ {
+ sgetc(1);
+ return;
+ }
+
+# ifndef _I386_ISA_KBDIO_H_
+ 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 */
+# else
+ while ((c = read_kbd_data_no_wait(kbdc)) != -1)
+ {
+ ret = 1; /* got something */
+ dt = c;
+# endif /* _I386_ISA_KBDIO_H_ */
+
+ 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(pcvt_timeout, NULL, hz / 100); /* fire off */
+ PCVT_ENABLE_INTR ();
+ }
+ }
+
+#else /* !PCVT_KBD_FIFO */
+
+ if((cp = sgetc(1)) == 0)
+ return;
+
+ if (kbd_polling)
+ return;
+
+ if(!(vs[current_video_screen].openf)) /* XXX was vs[minor(dev)] */
+ return;
+
+#if PCVT_NULLCHARS
+ if(*cp == '\0')
+ {
+ /* pass a NULL character */
+ (*linesw[pcconsp->t_line].l_rint)('\0', pcconsp);
+ return;
+ }
+#endif /* PCVT_NULLCHARS */
+
+ while (*cp)
+ (*linesw[pcconsp->t_line].l_rint)(*cp++ & 0xff, pcconsp);
+
+#endif /* PCVT_KBD_FIFO */
+}
+
+
+#if PCVT_NETBSD || PCVT_FREEBSD >= 200
+
+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);
+
+ rbp = &tp->t_outq;
+
+ /*
+ * Call q_to_b() at spltty() to ensure that the queue is empty when
+ * the loop terminates.
+ */
+
+ s = spltty();
+
+ while (len = q_to_b(rbp, buf, PCVT_PCBURST))
+ {
+ /*
+ * We need to do this outside spl since it could be fairly
+ * expensive and we don't want our serial ports to overflow.
+ */
+ splx(s);
+ sput(&buf[0], 0, len, minor(tp->t_dev));
+ s = spltty();
+ }
+
+ tp->t_state &= ~TS_BUSY;
+
+#ifndef TS_ASLEEP /* FreeBSD some time after 2.0.5 */
+ ttwwakeup(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_FREEBSD > 205
+void
+#else
+int
+#endif
+pccnprobe(struct consdev *cp)
+{
+ struct isa_device *dvp;
+
+#ifdef _I386_ISA_KBDIO_H_
+ kbdc = kbdc_open(IO_KBD);
+ /*
+ * Don't reset the keyboard via `kbdio' just yet.
+ * The system clock has not been calibrated...
+ */
+ reset_keyboard = 0;
+#if PCVT_SCANSET == 2
+ /*
+ * Turn off scancode translation early so that UserConfig
+ * and DDB can read the keyboard.
+ */
+ empty_both_buffers(kbdc, 10);
+ set_controller_command_byte(kbdc, KBD_TRANSLATION, 0);
+#endif /* PCVT_SCANSET == 2 */
+#endif /* _I386_ISA_KBDIO_H_ */
+
+ /*
+ * Take control if we are the highest priority enabled display device.
+ */
+ dvp = find_display();
+ if (dvp == NULL || dvp->id_driver != &vtdriver) {
+ cp->cn_pri = CN_DEAD;
+ return;
+ }
+
+ /* initialize required fields */
+
+ cp->cn_dev = makedev(CDEV_MAJOR, 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_FREEBSD <= 205
+ return 1;
+#endif
+}
+
+#if PCVT_FREEBSD > 205
+void
+#else
+int
+#endif
+pccninit(struct consdev *cp)
+{
+ pcvt_is_console = 1;
+#if PCVT_FREEBSD <= 205
+ return 0;
+#endif
+}
+
+#if PCVT_FREEBSD > 205
+void
+#else
+int
+#endif
+pccnputc(Dev_t dev, U_char c)
+{
+
+#if PCVT_SW0CNOUTP
+
+ if(current_video_screen != 0)
+ {
+
+#if !PCVT_USL_VT_COMPAT
+ vgapage(0);
+#else
+ switch_screen(0, 0);
+#endif /* !PCVT_USL_VT_COMPAT */
+
+ }
+
+#endif /* PCVT_SW0CNOUTP */
+
+ if (c == '\n')
+ sput("\r", 1, 1, 0);
+
+ sput((char *) &c, 1, 1, 0);
+
+ async_update(UPDATE_KERN);
+
+#if PCVT_FREEBSD <= 205
+ return 0;
+#endif
+}
+
+int
+pccngetc(Dev_t dev)
+{
+ register int s;
+ static u_char *cp, cbuf[4]; /* Temp buf for multi-char key sequence. */
+ register u_char c;
+
+#ifdef XSERVER
+
+#if !PCVT_USL_VT_COMPAT
+ if (pcvt_xmode)
+ return 0;
+#else /* !PCVT_USL_VT_COMPAT */
+ if (pcvt_kbd_raw)
+ return 0;
+#endif /* !PCVT_USL_VT_COMPAT */
+
+#endif /* XSERVER */
+
+ if (cp && *cp)
+ /*
+ * We still have a pending key sequence, e.g.
+ * from an arrow key. Deliver this one first.
+ */
+ return (*cp++);
+
+ s = spltty(); /* block pcrint while we poll */
+ kbd_polling = 1;
+ cp = sgetc(0);
+ kbd_polling = 0;
+ splx(s);
+ c = *cp++;
+ if (c && *cp) {
+ /* Preserve the multi-char sequence for the next call. */
+ bcopy(cp, cbuf, 3); /* take care for a trailing '\0' */
+ cp = cbuf;
+ } else
+ cp = 0;
+
+#if ! (PCVT_FREEBSD >= 201)
+ /* this belongs to cons.c */
+ if (c == '\r')
+ c = '\n';
+#endif /* ! (PCVT_FREEBSD >= 201) */
+
+ return c;
+}
+
+#if PCVT_FREEBSD >= 200
+int
+pccncheckc(Dev_t dev)
+{
+ char *cp;
+ int x = spltty();
+ kbd_polling = 1;
+ cp = sgetc(1);
+ kbd_polling = 0;
+ splx(x);
+ return (cp == NULL ? -1 : *cp);
+}
+#endif /* PCVT_FREEBSD >= 200 */
+
+#if PCVT_NETBSD >= 100
+void
+pccnpollc(Dev_t dev, int on)
+{
+ 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();
+ pcrint();
+ 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);
+ }
+}
+
+#define DPAUSE 1
+
+void
+dprintf(unsigned flgs, const char *fmt, ...)
+{
+ va_list ap;
+
+ if((flgs&__debug) > DPAUSE)
+ {
+ __color = ffs(flgs&__debug)+1;
+ va_start(ap,fmt);
+ vprintf(fmt, ap);
+ va_end(ap);
+
+ if (flgs & DPAUSE || nrow%24 == 23)
+ {
+ int x;
+ x = splhigh();
+ if(nrow%24 == 23)
+ nrow = 0;
+ (void)sgetc(0);
+ splx(x);
+ }
+ }
+ __color = 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));
+}
+
+#if defined XSERVER && !PCVT_USL_VT_COMPAT
+/*----------------------------------------------------------------------*
+ * initialize for X mode
+ * i.e.: grant current process (the X server) all IO privileges,
+ * and mark in static variable so other hooks can test for it,
+ * save all loaded fonts and screen pages to pageable buffers;
+ * if parameter `on' is false, the same procedure is done reverse.
+ *----------------------------------------------------------------------*/
+static int
+pcvt_xmode_set(int on, struct proc *p)
+{
+ static unsigned char *saved_fonts[NVGAFONTS];
+
+#if PCVT_SCREENSAVER
+ static unsigned saved_scrnsv_tmo = 0;
+#endif /* PCVT_SCREENSAVER */
+
+#if (PCVT_NETBSD > 9) || (PCVT_FREEBSD > 102)
+ struct trapframe *fp;
+#else
+ struct syscframe *fp;
+#endif /* PCVT_NETBSD > 9 */
+
+ int error, i;
+
+ /* X will only run on VGA and Hercules adaptors */
+
+ if(adaptor_type != VGA_ADAPTOR && adaptor_type != MDA_ADAPTOR)
+ return (EINVAL);
+
+#if PCVT_NETBSD > 9
+ fp = (struct trapframe *)p->p_regs;
+#else
+ fp = (struct syscframe *)p->p_regs;
+#endif /* PCVT_NETBSD > 9 */
+
+ if(on)
+ {
+ /*
+ * Test whether the calling process has super-user privileges
+ * and we're in insecure mode.
+ * This prevents us from granting the potential security hole
+ * `IO priv' to insufficiently privileged processes.
+ */
+ error = suser(p->p_ucred, &p->p_acflag);
+ if (error != 0)
+ return (error);
+ if (securelevel > 0)
+ return (EPERM);
+
+ if(pcvt_xmode)
+ return 0;
+
+ pcvt_xmode = pcvt_kbd_raw = 1;
+
+ for(i = 0; i < totalfonts; i++)
+ {
+ if(vgacs[i].loaded)
+ {
+ saved_fonts[i] = (unsigned char *)
+ malloc(32 * 256, M_DEVBUF, M_WAITOK);
+ if(saved_fonts[i] == 0)
+ {
+ printf(
+ "pcvt_xmode_set: no font buffer available\n");
+ return (EAGAIN);
+ }
+ else
+ {
+ vga_move_charset(i, saved_fonts[i], 1);
+ }
+ }
+ else
+ {
+ saved_fonts[i] = 0;
+ }
+ }
+
+#if PCVT_SCREENSAVER
+ if(saved_scrnsv_tmo = scrnsv_timeout)
+ pcvt_set_scrnsv_tmo(0); /* turn it off */
+#endif /* PCVT_SCREENSAVER */
+
+ async_update(UPDATE_STOP); /* turn off */
+
+ /* disable text output and save screen contents */
+ /* video board memory -> kernel memory */
+
+ bcopy(vsp->Crtat, vsp->Memory,
+ vsp->screen_rowsize * vsp->maxcol * CHR);
+
+ vsp->Crtat = vsp->Memory; /* operate in memory now */
+
+#ifndef _I386_ISA_KBDIO_H_
+
+#if PCVT_SCANSET == 2
+ /* put keyboard to return ancient PC scan codes */
+ kbc_8042cmd(CONTR_WRITE);
+#if PCVT_USEKBDSEC /* security enabled */
+ outb(CONTROLLER_DATA,
+ (COMMAND_SYSFLG|COMMAND_IRQEN|COMMAND_PCSCAN));
+#else /* security disabled */
+ outb(CONTROLLER_DATA,
+ (COMMAND_INHOVR|COMMAND_SYSFLG|COMMAND_IRQEN|COMMAND_PCSCAN));
+#endif /* PCVT_USEKBDSEC */
+#endif /* PCVT_SCANSET == 2 */
+
+#else /* _I386_ISA_KBDIO_H_ */
+
+#if PCVT_SCANSET == 2
+ /* put keyboard to return ancient PC scan codes */
+ set_controller_command_byte(kbdc,
+ KBD_TRANSLATION, KBD_TRANSLATION);
+#endif /* PCVT_SCANSET == 2 */
+
+#endif /* !_I386_ISA_KBDIO_H_ */
+
+#if PCVT_NETBSD > 9
+ fp->tf_eflags |= PSL_IOPL;
+#else
+ fp->sf_eflags |= PSL_IOPL;
+#endif /* PCVT_NETBSD > 9 */
+
+ }
+ else
+ {
+ if(!pcvt_xmode) /* verify if in X */
+ return 0;
+
+ pcvt_xmode = pcvt_kbd_raw = 0;
+
+ for(i = 0; i < totalfonts; i++)
+ {
+ if(saved_fonts[i])
+ {
+ vga_move_charset(i, saved_fonts[i], 0);
+ free(saved_fonts[i], M_DEVBUF);
+ saved_fonts[i] = 0;
+ }
+ }
+
+#if PCVT_NETBSD > 9
+ fp->tf_eflags &= ~PSL_IOPL;
+#else
+ fp->sf_eflags &= ~PSL_IOPL;
+#endif /* PCVT_NETBSD > 9 */
+
+#if PCVT_SCREENSAVER
+ if(saved_scrnsv_tmo)
+ pcvt_set_scrnsv_tmo(saved_scrnsv_tmo);
+#endif /* PCVT_SCREENSAVER */
+
+#ifndef _I386_ISA_KBDIO_H_
+
+#if PCVT_SCANSET == 2
+ kbc_8042cmd(CONTR_WRITE);
+#if PCVT_USEKBDSEC /* security enabled */
+ outb(CONTROLLER_DATA,
+ (COMMAND_SYSFLG|COMMAND_IRQEN));
+#else /* security disabled */
+ outb(CONTROLLER_DATA,
+ (COMMAND_INHOVR|COMMAND_SYSFLG|COMMAND_IRQEN));
+#endif /* PCVT_USEKBDSEC */
+#endif /* PCVT_SCANSET == 2 */
+
+#else /* _I386_ISA_KBDIO_H_ */
+
+#if PCVT_SCANSET == 2
+ set_controller_command_byte(kbdc, KBD_TRANSLATION, 0);
+#endif /* PCVT_SCANSET == 2 */
+
+#endif /* !_I386_ISA_KBDIO_H_ */
+
+ 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);
+ }
+
+ /* restore screen and re-enable text output */
+ /* kernel memory -> video board memory */
+
+ bcopy(vsp->Memory, Crtat,
+ vsp->screen_rowsize * vsp->maxcol * CHR);
+
+ vsp->Crtat = Crtat; /* operate on-screen now */
+
+ /* set crtc screen memory start address */
+
+ outb(addr_6845, CRTC_STARTADRH);
+ outb(addr_6845+1, (vsp->Crtat - Crtat) >> 8);
+ outb(addr_6845, CRTC_STARTADRL);
+ outb(addr_6845+1, (vsp->Crtat - Crtat));
+
+ async_update(UPDATE_START);
+ }
+ return 0;
+}
+#endif /* XSERVER && !PCVT_USL_VT_COMPAT */
+
+#endif /* NVT > 0 */
+
+/*-------------------------- E O F -------------------------------------*/
diff --git a/sys/i386/isa/pcvt/pcvt_ext.c b/sys/i386/isa/pcvt/pcvt_ext.c
new file mode 100644
index 0000000..acf066a
--- /dev/null
+++ b/sys/i386/isa/pcvt/pcvt_ext.c
@@ -0,0 +1,2835 @@
+/*
+ * 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.20, Last Edit-Date: [Thu Apr 6 10:07:45 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
+ *
+ *---------------------------------------------------------------------------*/
+
+#include "vt.h"
+#if NVT > 0
+
+#include <i386/isa/pcvt/pcvt_hdr.h> /* global include */
+
+#define ISSIGVALID(sig) ((sig) > 0 && (sig) < NSIG)
+
+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;
+ can_do_132col = 1;
+ switch ((byte & 0xfc) >> 2) {
+ case 0x22:
+ switch (byte & 3) {
+ case 0:
+ return VGA_CL_GD5402;
+ case 1:
+ return VGA_CL_GD5402r1;
+ case 2:
+ return VGA_CL_GD5420;
+ case 3:
+ return VGA_CL_GD5420r1;
+ }
+ break;
+ case 0x23:
+ return VGA_CL_GD5422;
+ case 0x25:
+ return VGA_CL_GD5424;
+ case 0x24:
+ return VGA_CL_GD5426;
+ case 0x26:
+ return VGA_CL_GD5428;
+ }
+ }
+
+ 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",
+ "unkown s3",
+ "cl-gd5402",
+ "cl-gd5402r1",
+ "cl-gd5420",
+ "cl-gd5420r1",
+ "cl-gd5422",
+ "cl-gd5424",
+ "cl-gd5426",
+ "cl-gd5428"
+ };
+ 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:
+ 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);
+}
+
+#if PCVT_USL_VT_COMPAT
+/*---------------------------------------------------------------------------*
+ * 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 */
+#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);
+ }
+ }
+}
+
+/*---------------------------------------------------------------------------*
+ * 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 (pcvt_kbd_raw && vsp == vsx) {
+#if PCVT_SCANSET > 1
+ kbd_emulate_pc(0);
+#endif /* PCVT_SCANSET > 1 */
+ pcvt_kbd_raw = 0;
+ }
+
+ /* Clear process controlled mode */
+ set_auto_mode (vsx);
+}
+
+/*---------------------------------------------------------------------------*
+ * switch to virtual screen n (0 ... PCVT_NSCREENS-1), VT_USL version
+ * (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;
+}
+
+/*---------------------------------------------------------------------------*
+ * ioctl handling for VT_USL mode
+ *---------------------------------------------------------------------------*/
+int
+usl_vt_ioctl(Dev_t dev, int cmd, caddr_t data, int flag, struct proc *p)
+{
+ int i, j, error, opri;
+ struct vt_mode newmode;
+
+ switch(cmd)
+ {
+
+ case VT_SETMODE:
+ newmode = *(struct vt_mode *)data;
+
+ opri = spltty();
+
+ if (newmode.mode != VT_PROCESS) {
+ struct video_state *vsx = &vs[minor(dev)];
+ 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 */
+ }
+
+ if (!ISSIGVALID(newmode.relsig) || !ISSIGVALID(newmode.acqsig)
+ || !ISSIGVALID(newmode.frsig))
+ {
+ splx(opri);
+ return EINVAL;
+ }
+
+ 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)
+ i = minor(dev);
+
+ {
+ 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 */
+ /* and insecure */
+ {
+
+#if PCVT_NETBSD > 9 || PCVT_FREEBSD >= 200
+ struct trapframe *fp = 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
+
+ error = suser(p->p_ucred, &p->p_acflag);
+ if (error != 0)
+ return (error);
+ if (securelevel > 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 = 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:
+ {
+ struct video_state *vsx = &vs[minor(dev)];
+ 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 KDSKBMODE:
+ switch(*(int *)data)
+ {
+ case K_RAW:
+
+#if PCVT_SCANSET > 1
+ /* put keyboard to return ancient PC scan codes */
+ kbd_emulate_pc(1);
+#endif /* PCVT_SCANSET > 1 */
+
+ pcvt_kbd_raw = 1;
+ shift_down = meta_down = altgr_down = ctrl_down = 0;
+ return 0;
+
+ case K_XLATE:
+
+#if PCVT_SCANSET > 1
+ kbd_emulate_pc(0);
+#endif /* PCVT_SCANSET > 1 */
+
+ pcvt_kbd_raw = 0;
+ 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 /* PCVT_USL_VT_COMPAT */
+
+#endif /* NVT > 0 */
+
+/* ------------------------- E O F ------------------------------------------*/
+
diff --git a/sys/i386/isa/pcvt/pcvt_hdr.h b/sys/i386/isa/pcvt/pcvt_hdr.h
new file mode 100644
index 0000000..11adc9c
--- /dev/null
+++ b/sys/i386/isa/pcvt/pcvt_hdr.h
@@ -0,0 +1,1418 @@
+/*
+ * 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.20, Last Edit-Date: [Fri Apr 7 10:16:58 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
+ *
+ *---------------------------------------------------------------------------*/
+
+#define PCVT_REL "3.20-b24" /* driver attach announcement */
+ /* see also: pcvt_ioctl.h */
+
+#include "opt_pcvt.h"
+#if defined(__FreeBSD__) && !defined(PCVT_FREEBSD)
+# define PCVT_FREEBSD 210
+#endif
+
+#if PCVT_FREEBSD >= 200
+
+#include <sys/param.h>
+#include <sys/conf.h>
+#include <sys/proc.h>
+#include <sys/signalvar.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>
+#if PCVT_FREEBSD > 210
+#include <machine/random.h>
+#endif /* PCVT_FREEBSD > 210 */
+#else /* ! PCVT_FREEBSD >= 200 */
+
+#include "param.h"
+#include "conf.h"
+#include "ioctl.h"
+#include "proc.h"
+#include "signalvar.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 <i386/isa/pcvt/pcvt_conf.h>
+#include <i386/isa/kbdio.h>
+
+#if PCVT_NETBSD > 9
+#include "device.h"
+#endif
+
+#if PCVT_NETBSD > 9
+#include "i386/isa/isavar.h"
+#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
+#include "i386/isa/isareg.h"
+#elif PCVT_FREEBSD >= 200
+#include <i386/isa/isa.h>
+#else
+#include "i386/isa/isa.h"
+#endif
+
+#if PCVT_NETBSD > 9
+#include "dev/cons.h"
+#elif PCVT_FREEBSD >= 200
+#include <machine/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_NETBSD > 9
+#include <i386/isa/pcvt/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
+#else /* PCVT_FREEBSD >= 200 */
+#include "machine/pc/display.h"
+#endif /* PCVT_FREEBSD >= 200 */
+
+/* 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 */
+#if !PCVT_NULLCHARS
+#undef PCVT_NULLCHARS
+#define PCVT_NULLCHARS 1
+#endif
+
+/* PCVT_BACKUP_FONTS is mandatory for PCVT_USL_VT_COMPAT */
+#if PCVT_USL_VT_COMPAT && !PCVT_BACKUP_FONTS
+#undef PCVT_BACKUP_FONTS
+#define PCVT_BACKUP_FONTS 1
+#endif
+
+#else /* XSERVER */
+
+#if PCVT_USL_VT_COMPAT
+#warning "Option PCVT_USL_VT_COMPAT meaningless without XSERVER"
+#undef PCVT_USL_VT_COMPAT
+#define PCVT_USL_VT_COMPAT 0
+#endif
+
+#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] */
+#undef PCVT_USL_VT_COMPAT
+#define PCVT_USL_VT_COMPAT 0 /* does not work, workaround ... */
+#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
+ *---------------------------------------------------------------------------*/
+
+#ifndef _I386_ISA_KBDIO_H_
+
+#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 */
+
+#endif /* _I386_ISA_KBDIO_H_ */
+
+/* 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"
+ *---------------------------------------------------------------------------*/
+
+#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 */
+
+/*---------------------------------------------------------------------------*
+ * 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_SCA 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 ((void *)0) /* do cursor update and requeue */
+#define UPDATE_STOP ((void *)1) /* suspend cursor updates */
+#define UPDATE_KERN ((void *)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
+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
+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 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 */
+
+#if PCVT_USL_VT_COMPAT /* SysV compatibility :-( */
+
+ struct vt_mode smode;
+ struct proc *proc;
+ pid_t pid;
+ unsigned 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 */
+ /* becoming active */
+#endif /* PCVT_USL_VT_COMPAT */
+
+} video_state;
+
+EXTERN video_state vs[PCVT_NSCREENS]; /* parameters for screens */
+
+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
+
+int pcprobe ();
+void pcattach ();
+
+struct cfdriver vtcd = {
+ NULL, "vt", pcprobe, pcattach, DV_TTY, sizeof(struct device)
+};
+
+#else
+
+int pcprobe ( struct isa_device *dev );
+int pcattach ( struct isa_device *dev );
+
+struct isa_driver vtdriver = { /* driver routines */
+ pcprobe, pcattach, "vt", 1,
+};
+
+#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
+/* XXX Crtat is shared with syscons. */
+u_short *Crtat; /* 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() */
+#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 */
+
+#if PCVT_USL_VT_COMPAT
+int vt_switch_pending = 0; /* if > 0, a vt switch is */
+#endif /* PCVT_USL_VT_COMPAT */ /* pending; contains the # */
+ /* 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 */
+#ifdef _I386_ISA_KBDIO_H_
+u_char reset_keyboard = 0; /* OK to reset keyboard */
+KBDC kbdc = NULL; /* keyboard controller */
+#endif /* _I386_ISA_KBDIO_H_ */
+
+#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 */
+
+#ifdef XSERVER
+unsigned scrnsv_timeout = 0; /* initially off */
+#if !PCVT_USL_VT_COMPAT
+u_char pcvt_xmode = 0; /* display is grafx */
+#endif /* PCVT_USL_VT_COMPAT */
+u_char pcvt_kbd_raw = 0; /* keyboard sends scans */
+#endif /* XSERVER */
+
+#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 */
+
+#if PCVT_USL_VT_COMPAT
+extern int vt_switch_pending;
+#endif /* PCVT_USL_VT_COMPAT */
+
+extern u_int addr_6845;
+extern u_short *Crtat;
+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;
+#ifdef _I386_ISA_KBDIO_H_
+extern u_char reset_keyboard;
+extern KBDC kbdc;
+#endif /* _I386_ISA_KBDIO_H_ */
+
+#if PCVT_SHOWKEYS
+extern u_char keyboard_show;
+#endif /* PCVT_SHOWKEYS */
+
+extern u_char cursor_pos_valid;
+
+extern u_char critical_scroll;
+extern int switch_page;
+
+#if PCVT_SCREENSAVER
+extern u_char reset_screen_saver;
+extern 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[];
+
+#ifdef XSERVER
+extern unsigned scrnsv_timeout;
+extern u_char pcvt_xmode;
+extern u_char pcvt_kbd_raw;
+#endif /* XSERVER */
+
+#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
+
+#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 pcparam ( struct tty *tp, struct termios *t );
+
+/*
+ * In FreeBSD > 2.0.6, driver console functions are declared in machine/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
+
+ointhand2_t pcrint;
+void pcstart ( struct tty *tp );
+void pcstop ( struct tty *tp, int flag );
+
+# if PCVT_FREEBSD < 200
+void consinit ( void );
+# endif
+
+#if PCVT_USL_VT_COMPAT
+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);
+#else
+void vgapage ( int n );
+#endif /* PCVT_USL_VT_COMPAT */
+
+#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 && defined(XSERVER)
+void pcvt_set_scrnsv_tmo ( int );
+#endif /* PCVT_SCREENSAVER && defined(XSERVER) */
+
+void vga_move_charset ( unsigned n, unsigned char *b, int save_it);
+
+void async_update ( void *arg );
+void clr_parms ( struct video_state *svsp );
+void cons_highlight ( void );
+void cons_normal ( void );
+void dprintf ( unsigned flgs, const char *fmt, ... );
+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 );
+#ifndef _I386_ISA_KBDIO_H_
+int kbd_cmd ( int val );
+int kbd_response ( void );
+#endif /* _I386_ISA_KBDIO_H_ */
+void kbd_code_init ( void );
+void kbd_code_init1 ( void );
+
+#if PCVT_SCANSET > 1
+void kbd_emulate_pc(int do_emulation);
+#endif
+
+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_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() \
+ { (void)inb(0x84); } \
+ { (void)inb(0x84); } \
+ { (void)inb(0x84); } \
+ { (void)inb(0x84); } \
+ { (void)inb(0x84); } \
+ { (void)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/i386/isa/pcvt/pcvt_kbd.c b/sys/i386/isa/pcvt/pcvt_kbd.c
new file mode 100644
index 0000000..2113ee0
--- /dev/null
+++ b/sys/i386/isa/pcvt/pcvt_kbd.c
@@ -0,0 +1,3321 @@
+/*
+ * 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.20, Last Edit-Date: [Sun Apr 2 18:59:04 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()
+ *
+ *---------------------------------------------------------------------------*/
+
+#include "vt.h"
+#include "opt_ddb.h"
+
+#if NVT > 0
+
+#include <i386/isa/pcvt/pcvt_hdr.h> /* global include */
+
+#define LEDSTATE_UPDATE_PENDING (1 << 3)
+
+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 );
+#ifndef _I386_ISA_KBDIO_H_
+static int kbc_8042cmd ( int val );
+#else
+static int set_keyboard_param( int command, int data );
+#endif /* !_I386_ISA_KBDIO_H_ */
+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 = LEDSTATE_UPDATE_PENDING; /* 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 <i386/isa/pcvt/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 || defined(_I386_ISA_KBDIO_H_)
+
+/*---------------------------------------------------------------------------*
+ * 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 may have had something to do with spltty() previously not being
+ * called before the kbd_cmd() calls in update_led().
+ *
+ * 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 struct callout_handle lost_intr_ch =
+ CALLOUT_HANDLE_INITIALIZER(&lost_intr_ch);
+
+static void
+check_for_lost_intr (void *arg)
+{
+#ifndef _I386_ISA_KBDIO_H_
+ lost_intr_timeout_queued = 0;
+ if (inb(CONTROLLER_CTRL) & STATUS_OUTPBF)
+ {
+ int opri = spltty ();
+ pcrint ();
+ splx (opri);
+ }
+#else
+ int opri;
+
+ lost_intr_timeout_queued = 0;
+ if (kbdc_lock(kbdc, TRUE)) {
+ opri = spltty ();
+ kbdc_lock(kbdc, FALSE);
+ if (kbdc_data_ready(kbdc))
+ pcrint (0);
+ splx (opri);
+ }
+ lost_intr_ch = timeout(check_for_lost_intr, (void *)NULL, hz);
+ lost_intr_timeout_queued = 1;
+#endif /* !_I386_ISA_KBDIO_H_ */
+}
+
+#endif /* PCVT_UPDLED_LOSES_INTR || defined(_I386_ISA_KBDIO_H_) */
+
+/*---------------------------------------------------------------------------*
+ * update keyboard led's
+ *---------------------------------------------------------------------------*/
+void
+update_led(void)
+{
+#if !PCVT_NO_LED_UPDATE
+
+ /* Don't update LED's unless necessary. */
+
+ int opri, new_ledstate;
+
+ opri = spltty();
+ new_ledstate = (vsp->scroll_lock) |
+ (vsp->num_lock * 2) |
+ (vsp->caps_lock * 4);
+
+ if (new_ledstate != ledstate)
+ {
+#ifndef _I386_ISA_KBDIO_H_
+ int response1, response2;
+
+ ledstate = LEDSTATE_UPDATE_PENDING;
+
+ if(kbd_cmd(KEYB_C_LEDS) != 0)
+ {
+ printf("Keyboard LED command timeout\n");
+ splx(opri);
+ return;
+ }
+
+ /*
+ * For some keyboards or keyboard controllers, it is an
+ * error to issue a command without waiting long enough
+ * for an ACK for the previous command. The keyboard
+ * gets confused, and responds with KEYB_R_RESEND, but
+ * we ignore that. Wait for the ACK here. The busy
+ * waiting doesn't matter much, since we lose anyway by
+ * busy waiting to send the command.
+ *
+ * XXX actually wait for any response, since we can't
+ * handle normal scancodes here.
+ *
+ * XXX all this should be interrupt driven. Issue only
+ * one command at a time wait for a ACK before proceeding.
+ * Retry after a timeout or on receipt of a KEYB_R_RESEND.
+ * KEYB_R_RESENDs seem to be guaranteed by working
+ * keyboard controllers with broken (or disconnected)
+ * keyboards. There is another code for keyboard
+ * reconnects. The keyboard hardware is very simple and
+ * well designed :-).
+ */
+ response1 = kbd_response();
+
+ if(kbd_cmd(new_ledstate) != 0) {
+ printf("Keyboard LED data timeout\n");
+ splx(opri);
+ return;
+ }
+ response2 = kbd_response();
+
+ if (response1 == KEYB_R_ACK && response2 == KEYB_R_ACK)
+ ledstate = new_ledstate;
+ else
+ printf(
+ "Keyboard LED command not ACKed (responses %#x %#x)\n",
+ response1, response2);
+#else /* _I386_ISA_KBDIO_H_ */
+
+ if (kbdc == NULL) {
+ ledstate = new_ledstate;
+ splx(opri);
+ } else {
+ ledstate = LEDSTATE_UPDATE_PENDING;
+ splx(opri);
+ if (set_keyboard_param(KBDC_SET_LEDS, new_ledstate) == 0)
+ ledstate = new_ledstate;
+ }
+
+#endif /* !_I386_ISA_KBDIO_H_ */
+
+#if PCVT_UPDLED_LOSES_INTR
+ if (lost_intr_timeout_queued)
+ untimeout(check_for_lost_intr, NULL, lost_intr_ch);
+
+ lost_intr_ch = timeout(check_for_lost_intr, NULL, hz);
+ lost_intr_timeout_queued = 1;
+#endif /* PCVT_UPDLED_LOSES_INTR */
+
+ }
+
+#ifndef _I386_ISA_KBDIO_H_
+ splx(opri);
+#endif
+
+#endif /* !PCVT_NO_LED_UPDATE */
+}
+
+/*---------------------------------------------------------------------------*
+ * set typematic rate
+ *---------------------------------------------------------------------------*/
+static void
+settpmrate(int rate)
+{
+#ifndef _I386_ISA_KBDIO_H_
+ 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");
+#else
+ tpmrate = rate & 0x7f;
+ if (set_keyboard_param(KBDC_SET_TYPEMATIC, tpmrate) != 0)
+ printf("pcvt: failed to set keyboard TYPEMATIC.\n");
+#endif /* !_I386_ISA_KBDIO_H_ */
+}
+
+#ifndef _I386_ISA_KBDIO_H_
+/*---------------------------------------------------------------------------*
+ * 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;
+}
+#else
+static int
+set_keyboard_param(int command, int data)
+{
+ int s;
+#if 0
+ int c;
+#endif
+
+ if (kbdc == NULL)
+ return 1;
+
+ /* prevent the timeout routine from polling the keyboard */
+ if (!kbdc_lock(kbdc, TRUE))
+ return 1;
+
+ /* disable the keyboard and mouse interrupt */
+ s = spltty();
+#if 0
+ c = get_controller_command_byte(kbdc);
+ if ((c == -1)
+ || !set_controller_command_byte(kbdc,
+ kbdc_get_device_mask(kbdc),
+ KBD_DISABLE_KBD_PORT | KBD_DISABLE_KBD_INT
+ | KBD_DISABLE_AUX_PORT | KBD_DISABLE_AUX_INT)) {
+ /* CONTROLLER ERROR */
+ kbdc_lock(kbdc, FALSE);
+ splx(s);
+ return 1;
+ }
+ /*
+ * Now that the keyboard controller is told not to generate
+ * the keyboard and mouse interrupts, call `splx()' to allow
+ * the other tty interrupts. The clock interrupt may also occur,
+ * but the timeout routine (`scrn_timer()') will be blocked
+ * by the lock flag set via `kbdc_lock()'
+ */
+ splx(s);
+#endif
+
+ if (send_kbd_command_and_data(kbdc, command, data) != KBD_ACK)
+ send_kbd_command(kbdc, KBDC_ENABLE_KBD);
+
+#if 0
+ /* restore the interrupts */
+ if (!set_controller_command_byte(kbdc,
+ kbdc_get_device_mask(kbdc),
+ c & (KBD_KBD_CONTROL_BITS | KBD_AUX_CONTROL_BITS))) {
+ /* CONTROLLER ERROR */
+ }
+#else
+ splx(s);
+#endif
+ kbdc_lock(kbdc, FALSE);
+
+ return 0;
+}
+#endif /* !_I386_ISA_KBDIO_H_ */
+
+#if PCVT_SCANSET > 1
+/*---------------------------------------------------------------------------*
+ * switch PC scan code emulation mode
+ *---------------------------------------------------------------------------*/
+void
+kbd_emulate_pc(int do_emulation)
+{
+#ifndef _I386_ISA_KBDIO_H_
+ int cmd, timeo = 10000;
+
+ cmd = COMMAND_SYSFLG|COMMAND_IRQEN; /* common base cmd */
+
+#if !PCVT_USEKBDSEC
+ cmd |= COMMAND_INHOVR;
+#endif
+
+ if(do_emulation)
+ cmd |= COMMAND_PCSCAN;
+
+ kbc_8042cmd(CONTR_WRITE);
+ while (inb(CONTROLLER_CTRL) & STATUS_INPBF)
+ if (--timeo == 0)
+ break;
+ outb(CONTROLLER_DATA, cmd);
+#else
+ set_controller_command_byte(kbdc, KBD_TRANSLATION,
+ (do_emulation) ? KBD_TRANSLATION : 0);
+#endif /* !_I386_ISA_KBDIO_H_ */
+}
+
+#endif /* PCVT_SCANSET > 1 */
+
+
+#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)
+{
+#ifndef _I386_ISA_KBDIO_H_
+ int again = 0;
+ int once = 0;
+ int response, opri;
+
+ /* 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. Versions
+ * between 1992 and Oct 1996 didn't have the delay and sometimes
+ * left a KEYB_R_RESEND.
+ */
+ while (1) {
+ if (inb(CONTROLLER_CTRL) & STATUS_OUTPBF)
+ kbd_response();
+ else {
+ DELAY(10000);
+ if (!(inb(CONTROLLER_CTRL) & STATUS_OUTPBF))
+ break;
+ }
+ }
+
+ /* Start keyboard reset */
+
+ opri = spltty ();
+
+ if (kbd_cmd(KEYB_C_RESET) != 0)
+ {
+ printf("pcvt: doreset() - timeout for keyboard reset command\n");
+ outb(CONTROLLER_DATA, KEYB_C_RESET); /* force */
+ }
+
+ /* 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;
+ }
+ else 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 (response == KEYB_R_RESEND)
+ {
+ 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");
+ outb(CONTROLLER_DATA, KEYB_C_RESET); /* force */
+ }
+ }
+ }
+
+ /* Wait for the second response to reset */
+
+ while ((response = kbd_response()) != KEYB_R_SELFOK)
+ {
+ if (response < 0)
+ {
+ printf("pcvt: doreset() - response != OK and resonse < 0\n");
+ /*
+ * If KEYB_R_SELFOK never arrives, the loop will
+ * finish here unless the keyboard babbles or
+ * STATUS_OUTPBF gets stuck.
+ */
+ break;
+ }
+ }
+
+ splx (opri);
+
+#if PCVT_KEYBDID
+
+ 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_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 */
+
+#else /* _I386_ISA_KBDIO_H_ */
+ int c;
+ int m;
+ int s;
+
+ if (!reset_keyboard) /* no, we are not ready to reset */
+ return;
+
+ if (lost_intr_timeout_queued) {
+ untimeout(check_for_lost_intr, (void *)NULL, lost_intr_ch);
+ lost_intr_timeout_queued = 0;
+ }
+
+ if (kbdc == NULL)
+ kbdc = kbdc_open(IO_KBD);
+
+ if (!kbdc_lock(kbdc, TRUE)) /* strange, somebody got there first */
+ return;
+
+ /* remove any noise */
+ empty_both_buffers(kbdc, 10);
+
+ s = spltty();
+
+ /* save the current controller command byte */
+ m = kbdc_get_device_mask(kbdc) & ~KBD_KBD_CONTROL_BITS;
+ c = get_controller_command_byte(kbdc);
+ if (c == -1) {
+ /* CONTROLLER ERROR */
+ kbdc_set_device_mask(kbdc, m);
+ kbdc_lock(kbdc, FALSE);
+ kbdc = NULL;
+ splx(s);
+ printf("pcvt: unable to get the command byte.\n");
+ return;
+ }
+
+#if PCVT_USEKBDSEC /* security enabled */
+
+# if PCVT_SCANSET == 2
+# define KBDINITCMD 0
+# else /* PCVT_SCANSET != 2 */
+# define KBDINITCMD KBD_TRANSLATION
+# endif /* PCVT_SCANSET == 2 */
+
+#else /* ! PCVT_USEKBDSEC */ /* security disabled */
+
+# if PCVT_SCANSET == 2
+# define KBDINITCMD KBD_OVERRIDE_KBD_LOCK
+# else /* PCVT_SCANSET != 2 */
+# define KBDINITCMD KBD_TRANSLATION | KBD_OVERRIDE_KBD_LOCK
+# endif /* PCVT_SCANSET == 2 */
+
+#endif /* PCVT_USEKBDSEC */
+
+ /* disable the keyboard interrupt and the aux port and interrupt */
+ if (!set_controller_command_byte(kbdc,
+ KBD_KBD_CONTROL_BITS | KBD_TRANSLATION | KBD_OVERRIDE_KBD_LOCK,
+ KBD_ENABLE_KBD_PORT | KBD_DISABLE_KBD_INT | KBDINITCMD)) {
+ /* CONTROLLER ERROR: there is very little we can do... */
+ kbdc_set_device_mask(kbdc, m);
+ kbdc_lock(kbdc, FALSE);
+ kbdc = NULL;
+ splx(s);
+ printf("pcvt: unable to set the command byte.\n");
+ return;
+ }
+ splx(s);
+
+ /* reset keyboard hardware */
+ ledstate = LEDSTATE_UPDATE_PENDING;
+ if (!reset_kbd(kbdc)) {
+ /* KEYBOARD ERROR */
+ empty_both_buffers(kbdc, 10);
+ test_controller(kbdc);
+ test_kbd_port(kbdc);
+ /*
+ * We could disable the keyboard port and interrupt now...
+ * but, the keyboard may still exist.
+ */
+ printf("pcvt: failed to reset the keyboard.\n");
+ /* try to restore the original command byte */
+ set_controller_command_byte(kbdc, 0xff, c);
+ kbdc_set_device_mask(kbdc, m);
+ kbdc_lock(kbdc, FALSE);
+ kbdc = NULL;
+ return;
+ }
+
+#if PCVT_KEYBDID
+
+ keyboard_type = KB_UNKNOWN;
+ if (send_kbd_command(kbdc, KBDC_SEND_DEV_ID) == KBD_ACK) {
+ DELAY(10000); /* 10msec delay */
+ switch (read_kbd_data(kbdc)) {
+ case KEYB_R_MF2ID1:
+ switch (read_kbd_data(kbdc)) {
+ case KEYB_R_MF2ID2:
+ case KEYB_R_MF2ID2HP:
+ keyboard_type = KB_MFII;
+ break;
+ case -1:
+ default:
+ break;
+ }
+ break;
+ case -1:
+ keyboard_type = KB_AT;
+ /* fall through */
+ default:
+ /* XXX: should we read the second byte? */
+ empty_both_buffers(kbdc, 10); /* XXX */
+ break;
+ }
+ } else {
+ /*
+ * The send ID command failed. This error is considered
+ * benign, but may need recovery.
+ */
+ empty_both_buffers(kbdc, 10);
+ test_controller(kbdc);
+ test_kbd_port(kbdc);
+ }
+
+#else /* PCVT_KEYBDID */
+
+ keyboard_type = KB_MFII; /* force it .. */
+
+#endif /* PCVT_KEYBDID */
+
+ /* enable the keyboard port and intr. */
+ if (!set_controller_command_byte(kbdc,
+ KBD_KBD_CONTROL_BITS,
+ KBD_ENABLE_KBD_PORT | KBD_ENABLE_KBD_INT)) {
+ /* CONTROLLER ERROR
+ * This is serious; we are left with the disabled
+ * keyboard intr.
+ */
+ printf("pcvt: failed to enable the keyboard port and intr.\n");
+ kbdc_set_device_mask(kbdc, m);
+ kbdc_lock(kbdc, FALSE);
+ kbdc = NULL;
+ return;
+ }
+
+ kbdc_set_device_mask(kbdc, m | KBD_KBD_CONTROL_BITS);
+ kbdc_lock(kbdc, FALSE);
+
+ update_led();
+
+ lost_intr_ch = timeout(check_for_lost_intr, (void *)NULL, hz);
+ lost_intr_timeout_queued = 1;
+
+#endif /* !_I386_ISA_KBDIO_H_ */
+}
+
+/*---------------------------------------------------------------------------*
+ * 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)(void);
+
+ 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 */
+
+#ifdef _I386_ISA_KBDIO_H_
+ int c;
+#endif /* _I386_ISA_KBDIO_H_ */
+
+loop:
+
+#ifdef XSERVER
+
+#ifndef _I386_ISA_KBDIO_H_
+
+#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 (pcvt_kbd_count || (inb(CONTROLLER_CTRL) & STATUS_OUTPBF))
+ {
+ if (!pcvt_kbd_count) /* 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 */
+
+#else /* _I386_ISA_KBDIO_H_ */
+
+#if PCVT_KBD_FIFO
+ if (pcvt_kbd_count) {
+ 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
+#endif /* PCVT_KBD_FIFO */
+ if (!noblock) {
+ while ((c = read_kbd_data(kbdc)) == -1)
+ ;
+ dt = c;
+ } else {
+ if ((c = read_kbd_data_no_wait(kbdc)) == -1)
+ return NULL;
+ dt = c;
+ }
+
+ {
+
+#endif /* !_I386_ISA_KBDIO_H_ */
+
+ /*
+ * 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).
+ * XXX For now, only the default locking key definitions
+ * are recognized (i.e. if you have overloaded you "A" key
+ * as NUMLOCK, that wont effect X mode:-)
+ * Changing this would be nice, but would require modifi-
+ * cations to the X server. After having this, X will
+ * deal with the LEDs itself, so we are committed.
+ */
+ /*
+ * Iff PCVT_USL_VT_COMPAT is defined, the behaviour has
+ * been fixed. We need not care about any keys here, since
+ * there are ioctls that deal with the lock key / LED stuff.
+ */
+ if (pcvt_kbd_raw)
+ {
+ keybuf[0] = dt;
+
+#if PCVT_FREEBSD > 210
+ add_keyboard_randomness(dt);
+#endif /* PCVT_FREEBSD > 210 */
+
+#if !PCVT_USL_VT_COMPAT
+ if ((dt & 0x80) == 0)
+ /* key make */
+ switch(dt)
+ {
+ case 0x45:
+ /* XXX on which virt screen? */ vsp->num_lock ^= 1;
+ update_led();
+ break;
+
+ case 0x3a:
+ vsp->caps_lock ^= 1;
+ update_led();
+ break;
+
+ case 0x46:
+ vsp->scroll_lock ^= 1;
+ update_led();
+ break;
+ }
+#endif /* !PCVT_USL_VT_COMPAT */
+
+#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;
+ 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
+ */
+ getmicrotime(&now);
+ timevalsub(&now, &mouse.lastmove);
+ getmicrotime(&mouse.lastmove);
+ 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 */
+
+#ifndef _I386_ISA_KBDIO_H_
+
+# 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 (pcvt_kbd_count || (inb(CONTROLLER_CTRL) & STATUS_OUTPBF))
+ {
+ if (!noblock || kbd_polling) /* 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 */
+
+#else /* _I386_ISA_KBDIO_H_ */
+
+#if PCVT_KBD_FIFO
+ if (pcvt_kbd_count) {
+ 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
+#endif /* PCVT_KBD_FIFO */
+ if (!noblock) {
+ while ((c = read_kbd_data(kbdc)) == -1)
+ ;
+ dt = c;
+ } else {
+ if ((c = read_kbd_data_no_wait(kbdc)) == -1)
+ return NULL;
+ dt = c;
+ }
+
+#endif /* !_I386_ISA_KBDIO_H_ */
+
+#endif /* !XSERVER */
+
+#ifndef _I386_ISA_KBDIO_H_
+ else
+ {
+ if(noblock)
+ return NULL;
+ else
+ goto loop;
+ }
+#endif /* !_I386_ISA_KBDIO_H_ */
+
+#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_FREEBSD > 210
+ add_keyboard_randomness(dt);
+#endif /* PCVT_FREEBSD > 210 */
+
+#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))
+ shutdown_nice();
+#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 KBDGLEDS:
+ *(int *)data = ledstate;
+ break;
+
+ case KBDSLEDS:
+ update_led(); /* ??? */
+ 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 */
+
+#if PCVT_USL_VT_COMPAT
+/*---------------------------------------------------------------------------*
+ * 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;
+ }
+ }
+}
+
+#endif /* PCVT_USL_VT_COMPAT */
+
+/*---------------------------------------------------------------------------*
+ * 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/i386/isa/pcvt/pcvt_kbd.h b/sys/i386/isa/pcvt/pcvt_kbd.h
new file mode 100644
index 0000000..fa6d2e1
--- /dev/null
+++ b/sys/i386/isa/pcvt/pcvt_kbd.h
@@ -0,0 +1,567 @@
+/*
+ * 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.20, Last Edit-Date: [Sun Apr 2 18:59:08 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
+ *
+ *---------------------------------------------------------------------------*/
+
+/*---------------------------------------------------------------------------*
+ * 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)(void); /* 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 "8"},
+/* 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
+};
+
+#if PCVT_USL_VT_COMPAT
+
+#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
+};
+
+#endif /* PCVT_USL_VT_COMPAT */
+
diff --git a/sys/i386/isa/pcvt/pcvt_out.c b/sys/i386/isa/pcvt/pcvt_out.c
new file mode 100644
index 0000000..09cc75c
--- /dev/null
+++ b/sys/i386/isa/pcvt/pcvt_out.c
@@ -0,0 +1,2182 @@
+/*
+ * 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.20, Last Edit-Date: [Sun Apr 2 18:59:11 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()
+ *
+ *---------------------------------------------------------------------------*/
+
+#include "vt.h"
+#if NVT > 0
+
+#define PCVT_INCLUDE_VT_SELATTR /* get inline function from pcvt_hdr.h */
+
+#include <i386/isa/pcvt/pcvt_hdr.h> /* global include */
+#include <vm/vm.h>
+#include <vm/vm_param.h>
+#include <vm/pmap.h>
+
+extern u_short csd_ascii[]; /* pcvt_tbl.h */
+extern u_short csd_supplemental[];
+
+static void write_char (struct video_state *svsp, int attrib, int ch);
+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; /* XXX inefficient interface */
+{
+ 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(((ch <= 0x1f) || (ch == 0x7f)) && (svsp->transparent == 0))
+ {
+
+ /* always process control-chars in the range 0x00..0x1f, 0x7f !!! */
+
+ 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 */
+ case 0x7f: /* DEL */
+ break;
+ }
+ }
+ }
+ else
+ {
+
+ /* char range 0x20...0x73, 0x80...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_SCA;
+ 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_SCA:
+ switch(ch)
+ {
+ case 'q':
+ 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)
+{
+ u_short volatile *cp;
+ u_short was;
+ int nscr, charset;
+ int equipment;
+ u_short *SaveCrtat;
+ struct video_state *svsp;
+
+ Crtat = (u_short *)MONO_BUF; /* XXX assume static relocation works */
+ SaveCrtat = Crtat;
+ cp = Crtat + (CGA_BUF-MONO_BUF)/CHR;
+
+ do_initialization = 0; /* reset init necessary flag */
+
+ /* get the equipment byte from the RTC chip */
+
+ equipment = ((rtcin(RTC_EQUIPMENT)) >> 4) & 0x03;
+
+ switch(equipment)
+ {
+ case EQ_EGAVGA:
+
+ /* set memory start to CGA == B8000 */
+
+ 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;
+ }
+
+ if(vga_test()) /* EGA or VGA ? */
+ {
+ adaptor_type = VGA_ADAPTOR;
+ totalfonts = 8;
+
+ if(color == 0)
+ {
+ mda2egaorvga();
+ Crtat = SaveCrtat; /* mono start */
+ }
+
+ /* find out which chipset we are running on */
+ vga_type = vga_chipset();
+ }
+ else
+ {
+ adaptor_type = EGA_ADAPTOR;
+ totalfonts = 4;
+
+ if(color == 0)
+ {
+ mda2egaorvga();
+ Crtat = SaveCrtat; /* mono start */
+ }
+ }
+
+ /* decouple ega/vga charsets and intensity */
+ set_2ndcharset();
+
+ break;
+
+ case EQ_40COLOR: /* XXX should panic in 40 col mode ! */
+ case EQ_80COLOR:
+ Crtat = Crtat + (CGA_BUF-MONO_BUF)/CHR;
+ addr_6845 = CGA_BASE;
+ adaptor_type = CGA_ADAPTOR;
+ color = 1;
+ totalfonts = 0;
+ break;
+
+ case EQ_80MONO:
+ 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->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_start = 0;
+ 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);
+
+ /*
+ * Reject cursors that are more than one row off a
+ * 25-row screen. syscons sets the cursor offset
+ * to 0xffff. The scroll up fixup fails for this
+ * because the assignment to svsp->row overflows
+ * and perhaps for other reasons.
+ */
+ if (cursorat > 25 * svsp->maxcol)
+ cursorat = 25 * svsp->maxcol;
+
+ 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);
+ }
+
+#if PCVT_USL_VT_COMPAT
+ svsp->smode.mode = VT_AUTO;
+ svsp->smode.relsig = svsp->smode.acqsig =
+ svsp->smode.frsig = 0;
+ svsp->proc = 0;
+ svsp->pid = svsp->vt_status = 0;
+#endif /* PCVT_USL_VT_COMPAT */
+
+ }
+
+ 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();
+}
+
+/*---------------------------------------------------------------------------*
+ * 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 takes 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/i386/isa/pcvt/pcvt_sup.c b/sys/i386/isa/pcvt/pcvt_sup.c
new file mode 100644
index 0000000..de7f938
--- /dev/null
+++ b/sys/i386/isa/pcvt/pcvt_sup.c
@@ -0,0 +1,2216 @@
+/*
+ * 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.20, Last Edit-Date: [Thu Apr 6 10:49:44 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
+ *
+ *---------------------------------------------------------------------------*/
+
+#include "vt.h"
+#if NVT > 0
+
+#include <i386/isa/pcvt/pcvt_hdr.h> /* global include */
+
+#include <sys/resource.h>
+
+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 */
+
+static struct callout_handle async_update_ch =
+ CALLOUT_HANDLE_INITIALIZER(&async_update_ch);
+
+#if PCVT_SCREENSAVER
+static void scrnsv_timedout ( void *arg );
+static struct callout_handle scrnsv_timeout_ch =
+ CALLOUT_HANDLE_INITIALIZER(&scrnsv_timeout_ch);
+static u_short *savedscreen = (u_short *)0; /* ptr to screen contents */
+static size_t scrnsv_size = (size_t)-1; /* size of saved image */
+
+#ifndef XSERVER
+static unsigned scrnsv_timeout = 0; /* initially off */
+static void pcvt_set_scrnsv_tmo ( int timeout );/* else declared global */
+#endif /* XSERVER */
+
+#if PCVT_PRETTYSCRNS
+static u_short *scrnsv_current = (u_short *)0; /* attention char ptr */
+static struct callout_handle scrnsv_blink_ch =
+ CALLOUT_HANDLE_INITIALIZER(&scrnsv_blink_ch);
+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
+#if PCVT_USL_VT_COMPAT
+#define is_dev_grafx vs[minor(dev)].vt_status & VT_GRAFX
+#define is_current_grafx vsp->vt_status & VT_GRAFX
+#else /* old X interface */
+#define is_dev_grafx pcvt_xmode
+#define is_current_grafx pcvt_xmode
+#endif /* PCVT_USL_VT_COMPAT */
+#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 defined XSERVER && !PCVT_USL_VT_COMPAT
+ /* avoid screen switch if using old X mode */
+ if(is_dev_grafx)
+ return EAGAIN;
+#endif /* XSERVER && !PCVT_USL_VT_COMPAT */
+
+#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)
+{
+ snprintf(data->name, sizeof(data->name), "%s", 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_USL_VT_COMPAT
+ | CONF_USL_VT_COMPAT
+#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_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);
+ }
+
+#if !PCVT_USL_VT_COMPAT
+ vgapage(current_video_screen);
+#else
+ switch_screen(current_video_screen, 0, 0);
+#endif /* !PCVT_USL_VT_COMPAT */
+
+}
+
+/*---------------------------------------------------------------------------*
+ * 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;
+
+ if(data->current_screen == -1)
+ {
+ screen = minor(dev);
+ }
+ else
+ {
+ if(data->current_screen >= PCVT_NSCREENS)
+ return; /* XXXXXX */
+ screen = data->current_screen;
+ }
+
+ vgapage(screen);
+
+#if defined XSERVER && PCVT_USL_VT_COMPAT
+ {
+ int 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 */
+#endif /* defined XSERVER && PCVT_USL_VT_COMPAT */
+
+ 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 = do update; requeue
+ * UPDATE_STOP = suspend updates
+ * UPDATE_KERN = do update for kernel printfs
+ *
+ *---------------------------------------------------------------------------*/
+void
+async_update(void *arg)
+{
+ static int lastpos = 0;
+ static int counter = PCVT_UPDATESLOW;
+
+#ifdef XSERVER
+ /* need a method to suspend the updates */
+
+ if(arg == UPDATE_STOP)
+ {
+ untimeout(async_update, UPDATE_START, async_update_ch);
+ return;
+ }
+#endif /* XSERVER */
+
+ /* first check if update is possible */
+
+ if(chargen_access /* does no-one load characters? */
+#ifdef XSERVER /* is vt0 not in graphics mode? */
+#if !PCVT_USL_VT_COMPAT
+ || pcvt_xmode /* XXX necessary ????? */
+#endif /* PCVT_USL_VT_COMPAT */
+#endif /* XSERVER */
+ )
+ {
+ goto async_update_exit; /* 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)
+ {
+ async_update_ch = timeout(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 */
+
+
+#if !PCVT_USL_VT_COMPAT
+/*---------------------------------------------------------------------------*
+ * switch to virtual screen n (0 ... PCVT_NSCREENS-1)
+ *---------------------------------------------------------------------------*/
+void
+vgapage(int n)
+{
+
+#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 */
+
+ /* 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 */
+#else
+ pcconsp = pc_tty[n]; /* current tty */
+#endif
+
+ vsp = &vs[n]; /* current video state ptr */
+
+ /* 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);
+ }
+
+ update_led(); /* update led's */
+
+ update_hp(vsp); /* update fkey labels, if present */
+}
+#endif /* !PCVT_USL_VT_COMPAT */
+
+/*---------------------------------------------------------------------------*
+ * 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_second;
+ return res;
+}
+
+/*---------------------------------------------------------------------------*
+ * produce "nice" screensaving ....
+ *---------------------------------------------------------------------------*/
+static void
+scrnsv_blink(void * arg)
+{
+ 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);
+ scrnsv_blink_ch = timeout(scrnsv_blink, NULL, hz);
+}
+
+#endif /* PCVT_PRETTYSCRNS */
+
+/*---------------------------------------------------------------------------*
+ * set timeout time
+ *---------------------------------------------------------------------------*/
+#ifndef XSERVER
+static void
+pcvt_set_scrnsv_tmo(int timeout)
+#else
+void
+pcvt_set_scrnsv_tmo(int timeout)
+#endif /* XSERVER */
+{
+ int x = splhigh();
+
+ if(scrnsv_timeout)
+ untimeout(scrnsv_timedout, NULL, scrnsv_timeout_ch);
+
+ 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... */
+ scrnsv_timeout_ch = timeout(scrnsv_timedout, 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;
+ scrnsv_blink_ch = timeout(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_second)
+ {
+ last_schedule = time_second;
+ reschedule = 1;
+ untimeout(scrnsv_timedout, NULL, scrnsv_timeout_ch);
+ }
+ if(scrnsv_active)
+ {
+
+#if PCVT_PRETTYSCRNS
+ if(scrnsv_active > 1)
+ untimeout(scrnsv_blink, NULL, scrnsv_blink_ch);
+#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 */
+ scrnsv_timeout_ch = timeout(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/i386/isa/pcvt/pcvt_tbl.h b/sys/i386/isa/pcvt/pcvt_tbl.h
new file mode 100644
index 0000000..c515679
--- /dev/null
+++ b/sys/i386/isa/pcvt/pcvt_tbl.h
@@ -0,0 +1,475 @@
+/*
+ * 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.20, Last Edit-Date: [Sun Apr 2 18:59:19 1995]
+ *
+ */
+
+/*---------------------------------------------------------------------------*
+ *
+ * pcvt_tbl.h VT220 Driver Character Set Conversion Tables
+ * ------------------------------------------------------------
+ * -hm splitting off pccons_out.c
+ * -hm default tables for pure mda/hcg/cga
+ *
+ * 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 | CSH, 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/i386/isa/pcvt/pcvt_vtf.c b/sys/i386/isa/pcvt/pcvt_vtf.c
new file mode 100644
index 0000000..e3f7878
--- /dev/null
+++ b/sys/i386/isa/pcvt/pcvt_vtf.c
@@ -0,0 +1,2187 @@
+/*
+ * 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.20, Last Edit-Date: [Wed Apr 5 18:08:50 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 ...
+ *
+ *---------------------------------------------------------------------------*/
+
+#include "vt.h"
+#if NVT > 0
+
+#define PCVT_INCLUDE_VT_SELATTR /* get inline function from pcvt_hdr.h */
+
+#include <i386/isa/pcvt/pcvt_hdr.h> /* global include */
+#include <i386/isa/pcvt/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->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 */
+
+ 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 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 */
+ adaptor_type != MDA_ADAPTOR))) /* and not on MDA/Hercules */
+ {
+ u_short *Memory =
+
+#if PCVT_USL_VT_COMPAT
+ (vsp != svsp || (vsp->vt_status & VT_GRAFX)) ?
+#else
+ (vsp != svsp) ?
+#endif
+
+ 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 PCVT_USL_VT_COMPAT
+ if(vsp == svsp && !(vsp->vt_status & VT_GRAFX))
+#else
+ if(vsp == svsp)
+#endif
+
+ {
+ 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), PPAUSE, "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 */
+ adaptor_type != MDA_ADAPTOR))) /* and not on MDA/Hercules */
+ {
+ u_short *Memory =
+
+#if PCVT_USL_VT_COMPAT
+ (vsp != svsp || (vsp->vt_status & VT_GRAFX)) ?
+#else
+ (vsp != svsp) ?
+#endif
+ 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 PCVT_USL_VT_COMPAT
+ if(vsp == svsp && !(vsp->vt_status & VT_GRAFX))
+#else
+ if(vsp == svsp)
+#endif
+
+ {
+ 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), PPAUSE, "scrlck", 0);
+}
+
+/*---------------------------------------------------------------------------*
+ * switch charset pointers
+ *---------------------------------------------------------------------------*/
+static void
+swcsp(struct video_state *svsp, u_short *ctp)
+{
+ if(ctp == NULL)
+ return;
+
+ switch(svsp->state)
+ {
+ case STATE_BROPN: /* designate G0 */
+ svsp->G0 = ctp;
+ break;
+
+ case STATE_BRCLO: /* designate G1 */
+ case STATE_MINUS: /* designate G1 (96) */
+ svsp->G1 = ctp;
+ break;
+
+ case STATE_STAR: /* designate G2 */
+ case STATE_DOT: /* designate G2 (96) */
+ svsp->G2 = ctp;
+ break;
+
+ case STATE_PLUS: /* designate G3 */
+ case STATE_SLASH: /* designate G3 (96) */
+ 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 ------------------------------------------*/
+
OpenPOWER on IntegriCloud