From e6cf3a438fea379bc695c779b175c508ca097243 Mon Sep 17 00:00:00 2001 From: peter Date: Fri, 1 Jan 1999 08:23:23 +0000 Subject: Part 3 of the pcvt/voxware revival. Reviewed by: core --- sys/i386/isa/pcvt/pcvt_conf.h | 477 ++++++ sys/i386/isa/pcvt/pcvt_drv.c | 1641 ++++++++++++++++++++ sys/i386/isa/pcvt/pcvt_ext.c | 2835 +++++++++++++++++++++++++++++++++++ sys/i386/isa/pcvt/pcvt_hdr.h | 1418 ++++++++++++++++++ sys/i386/isa/pcvt/pcvt_kbd.c | 3321 +++++++++++++++++++++++++++++++++++++++++ sys/i386/isa/pcvt/pcvt_kbd.h | 567 +++++++ sys/i386/isa/pcvt/pcvt_out.c | 2182 +++++++++++++++++++++++++++ sys/i386/isa/pcvt/pcvt_sup.c | 2216 +++++++++++++++++++++++++++ sys/i386/isa/pcvt/pcvt_tbl.h | 475 ++++++ sys/i386/isa/pcvt/pcvt_vtf.c | 2187 +++++++++++++++++++++++++++ 10 files changed, 17319 insertions(+) create mode 100644 sys/i386/isa/pcvt/pcvt_conf.h create mode 100644 sys/i386/isa/pcvt/pcvt_drv.c create mode 100644 sys/i386/isa/pcvt/pcvt_ext.c create mode 100644 sys/i386/isa/pcvt/pcvt_hdr.h create mode 100644 sys/i386/isa/pcvt/pcvt_kbd.c create mode 100644 sys/i386/isa/pcvt/pcvt_kbd.h create mode 100644 sys/i386/isa/pcvt/pcvt_out.c create mode 100644 sys/i386/isa/pcvt/pcvt_sup.c create mode 100644 sys/i386/isa/pcvt/pcvt_tbl.h create mode 100644 sys/i386/isa/pcvt/pcvt_vtf.c (limited to 'sys/i386/isa/pcvt') 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 + * NetBSD 0.9 : NetBSD0_9 defined in + * NetBSD 1.0 : NetBSD1_0 defined as 1 in + * NetBSD 1.0A: NetBSD1_0 defined as 2 in + * + * 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" 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 /* 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 /* global include */ +#ifdef DEVFS +#include +#if !defined(MAXCONS) +#define MAXCONS 16 +#endif +static void *pcvt_devfs_token[MAXCONS]; +#endif /*DEVFS*/ + +#if PCVT_FREEBSD >= 200 +#include +#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(" ", 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 + * -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 /* 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#if PCVT_FREEBSD > 210 +#include +#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 +#include + +#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 +#else +#include "i386/isa/isa_device.h" +#endif + +#if PCVT_FREEBSD >= 200 +#include +#else +#include "i386/isa/icu.h" +#endif + +#if PCVT_NETBSD > 100 +#include "i386/isa/isareg.h" +#elif PCVT_FREEBSD >= 200 +#include +#else +#include "i386/isa/isa.h" +#endif + +#if PCVT_NETBSD > 9 +#include "dev/cons.h" +#elif PCVT_FREEBSD >= 200 +#include +#else +#include "i386/i386/cons.h" +#endif + +#if PCVT_NETBSD <= 9 +#if PCVT_FREEBSD >= 200 +#include +#include +#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 +#elif PCVT_FREEBSD >= 200 +#include +#else +#include "machine/pcvt_ioctl.h" +#endif + +#if PCVT_FREEBSD >= 200 +#include +#if PCVT_FREEBSD > 200 +#include +#include +#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 " */ +#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 /* 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 /* 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 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: + * + */ + 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; ikeynum].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 /* global include */ +#include +#include +#include + +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 /* global include */ + +#include + +static void vid_cursor ( struct cursorshape *data ); +static void vgasetfontattr ( struct vgafontattr *data ); +static void vgagetfontattr ( struct vgafontattr *data ); +static void vgaloadchar ( struct vgaloadchar *data ); +static void vid_getscreen ( struct screeninfo *data, Dev_t dev ); +static void vid_setscreen ( struct screeninfo *data, Dev_t dev ); +static void setchargen ( void ); +static void setchargen3 ( void ); +static void resetchargen ( void ); +static void vgareadpel ( struct vgapel *data, Dev_t dev ); +static void vgawritepel ( struct vgapel *data, Dev_t dev ); +static void vgapcvtid ( struct pcvtid *data ); +static void vgapcvtinfo ( struct pcvtinfo *data ); + +#ifdef XSERVER +static unsigned char * compute_charset_base ( unsigned fontset ); +#endif /* XSERVER */ + +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_",define the according "HAVECS_" + * 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 /* global include */ +#include /* 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; itab_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 ------------------------------------------*/ + -- cgit v1.1